[
  {
    "path": ".gitbook.yaml",
    "content": "root: ./docs/\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "# These are supported funding model platforms\n\ngithub: nick-thompson\npatreon: # Replace with a single Patreon username\nopen_collective: # Replace with a single Open Collective username\nko_fi: # Replace with a single Ko-fi username\ntidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel\ncommunity_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry\nliberapay: # Replace with a single Liberapay username\nissuehunt: # Replace with a single IssueHunt username\notechie: # Replace with a single Otechie username\ncustom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']\n"
  },
  {
    "path": ".github/workflows/cmake.yml",
    "content": "name: CMake\n\non: [push, pull_request]\n\nenv:\n  # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)\n  BUILD_TYPE: Release\n\njobs:\n  build:\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        os: [macos-latest, ubuntu-latest, windows-latest]\n\n    steps:\n      - uses: actions/checkout@v2\n        with:\n          submodules: true\n\n      - name: Fetch juce dependencies\n        if: matrix.os == 'ubuntu-latest'\n        run: sudo apt-get update && sudo apt-get install libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxext-dev libfreetype6-dev libasound2-dev\n\n      - name: Create Build Environment\n        # Some projects don't allow in-source building, so create a separate build directory\n        # We'll use this as our working directory for all subsequent commands\n        run: cmake -E make_directory ${{runner.workspace}}/build\n\n      - name: Configure CMake\n        # Use a bash shell so we can use the same syntax for environment variable\n        # access regardless of the host operating system\n        shell: bash\n        working-directory: ${{runner.workspace}}/build\n        # Note the current convention is to use the -S and -B options here to specify source\n        # and build directories, but this is only available with CMake 3.13 and higher.\n        # The CMake binaries on the Github Actions machines are (as of this writing) 3.12\n        run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE\n\n      - name: Build\n        working-directory: ${{runner.workspace}}/build\n        shell: bash\n        # Execute the build.  You can specify a specific target with \"--target <NAME>\"\n        run: cmake --build . --config $BUILD_TYPE\n"
  },
  {
    "path": ".github/workflows/lint.yml",
    "content": "name: Lint\n\non: [push, pull_request]\n\njobs:\n  run-linters:\n    name: Run linters\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v2\n      - uses: bahmutov/npm-install@v1\n      - name: Lint\n        run: npm run lint\n"
  },
  {
    "path": ".github/workflows/node.yml",
    "content": "name: Node.js\n\non: [push, pull_request]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n      - uses: actions/checkout@v2\n\n      - name: Setup Node.js\n        uses: actions/setup-node@v1\n        with:\n          node-version: \"12.x\"\n          registry-url: \"https://npm.pkg.github.com\"\n\n      - name: Install dependencies\n        working-directory: ${{runner.workspace}}/react-juce/packages/react-juce\n        run: npm ci\n\n      - name: Build react-juce\n        working-directory: ${{runner.workspace}}/react-juce/packages/react-juce\n        run: npm run build\n"
  },
  {
    "path": ".github/workflows/publish.yml",
    "content": "name: Publish Packages\n\non:\n  release:\n    types: [created]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n\n      - uses: actions/setup-node@v1\n        with:\n          node-version: \"12.x\"\n          registry-url: \"https://registry.npmjs.org\"\n\n      - name: Install dependencies\n        working-directory: ${{runner.workspace}}/react-juce/packages/react-juce\n        run: npm ci\n\n      - name: Build react-juce\n        working-directory: ${{runner.workspace}}/react-juce/packages/react-juce\n        run: npm run build\n\n      - name: Publish\n        working-directory: ${{runner.workspace}}/react-juce/packages/react-juce\n        run: npm publish\n        env:\n          NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}\n"
  },
  {
    "path": ".gitignore",
    "content": "# Compiled object files\n*.slo\n*.lo\n*.o\n*.obj\n*.tlog\n*.log\n\n.vscode/\n.cache/\n\nbuild\nexamples/TestRunner/Builds\nexamples/**/build\n\n# For VSCode users\n*.code-workspace\n\n# For JetBrains users\n.idea\n\n# For vim users\n*.swp\n\n._*\n*.mode1v3\n*.pbxuser\n*.perspectivev3\n*.user\n*.ncb\n*.suo\n*.ilk\n*.pch\n*.pdb\n*.dep\n*.idb\n*.manifest\n*.manifest.res\n*.o\n*.d\n*.sdf\n*.opensdf\n*.VC.db\n*.VC.opendb\nxcuserdata\nxcshareddata\n*.xccheckout\n*.xcscmblueprint\ncontents.xcworkspacedata\n.DS_Store\n.svn\n.deps\n.dirstamp\nprofile\nnode_modules\n**/MacOSX/build\n**/iOS/build\n**/IDEWorkspaceChecks.plist\n**/Linux/build\n**/LinuxMakefile/build\n**/VisualStudio2005/Debug\n**/VisualStudio2005/Release\n**/VisualStudio2008/Debug\n**/VisualStudio2008/Release\n**/VisualStudio2010/Debug\n**/VisualStudio2010/Release\n**/VisualStudio2012/Debug\n**/VisualStudio2012/Release\n**/VisualStudio2013/Win32\n**/VisualStudio2013/x64\n**/VisualStudio2015/Win32\n**/VisualStudio2015/x64\n**/VisualStudio2017/Win32\n**/VisualStudio2017/x64\n**/Builds/x64\n**/.vs\n**/CodeBlocks/bin\n**/CodeBlocks/obj\n**/CodeBlocks/*.depend\n**/CodeBlocks/*.layout\n**/Builds/Android/.gradle\n**/Builds/Android/.idea\n**/Builds/Android/build\n**/Builds/Android/**/*.iml\n**/Builds/Android/local.properties\n**/Builds/Android/app/build\n**/Builds/Android/app/.externalNativeBuild\n**/Builds/Android/lib/build\n**/Builds/Android/lib/.externalNativeBuild\n**/Builds/CLion/cmake-build-*\n**/Builds/CLion/.idea\n**/doxygen/doc\n**/doxygen/build\nextras/Projucer/JUCECompileEngine.dylib\n**/AAX_SDK_2p3p1/Libs/*.build\n**/AAX_SDK_2p3p1/Libs/AAXLibrary/WinBuild/**/int\n**/AAX_SDK_2p3p1/Libs/Debug\n**/AAX_SDK_2p3p1/Libs/Release\n**/AAX_SDK_2p3p1/Documentation\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"juce\"]\n\tpath = ext/juce\n\turl = ../../juce-framework/JUCE.git\n[submodule \"yoga\"]\n\tpath = react_juce/yoga\n\turl = ../../facebook/yoga.git\n[submodule \"react_juce/hermes\"]\n\tpath = react_juce/hermes\n\turl = ../../facebook/hermes.git\n"
  },
  {
    "path": ".prettierignore",
    "content": "react_juce\nbuild\ndist\next\njuce\n"
  },
  {
    "path": "CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(reactjuce VERSION 0.1.0)\n\n# Change this option to ON if you want to build the AudioPluginHost for example\n# (practical to debug the plugin processor directly from your IDE)\noption(JUCE_BUILD_EXTRAS \"Build JUCE Extras\" OFF)\n\n\n# Change this option to set the JS Interpreter/Engine you wish to run React-JUCE against.\nset(REACTJUCE_JS_LIBRARY DUKTAPE CACHE STRING \"The JS Engine to use: either HERMES or DUKTAPE\")\n\n\nadd_subdirectory(ext/juce)\n\n# Adding any custom modules you might have:\njuce_add_module(react_juce)\n\n# Setup the JS engine/interpreter to use.\nif (REACTJUCE_JS_LIBRARY STREQUAL \"HERMES\")\n    add_subdirectory(react_juce/hermes)\n\n    target_compile_definitions(\n        react_juce\n        INTERFACE\n        REACTJUCE_USE_HERMES=1\n    )\n\n    #TODO: We should be able to remove this include bloc once the following PR is merged\n    #      over at hermes upstream: https://github.com/facebook/hermes/pull/454\n    target_include_directories(\n        react_juce\n        INTERFACE\n        react_juce/hermes/API/\n        react_juce/hermes/public/\n    )\n\n    target_link_libraries(\n        react_juce\n        INTERFACE\n        hermesapi\n    )\nelseif (REACTJUCE_JS_LIBRARY STREQUAL \"QUICKJS\")\n    #TODO: Add QuickJS cmake settings/includes here.\nelseif (REACTJUCE_JS_LIBRARY STREQUAL \"DUKTAPE\")\n    target_compile_definitions(\n        react_juce\n        INTERFACE\n        REACTJUCE_USE_DUKTAPE=1\n    )\nendif()\n\n# If you want to create new projects, you can init them in the examples folder\n# and add them here with the add_subdirectory command\nadd_subdirectory(examples/GainPlugin)\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\nWe'd love to see you get involved with React-JUCE! Here are our current working guidelines, and we'll be updating and iterating on these as we go.\n\n- Have a question? Please open a Discussion topic, not an issue\n- Document every feature request, bugfix, or change with an issue\n- Issues that have been assigned to someone should be considered \"in progress\"\n- Issues with no assignee are free to claim. Please assign yourself if you want to tackle an issue to prevent duplicate efforts\n- If you don't see an issue for some work you're planning, open one so that we can mark an assignee and further avoid duplication\n- Priority will be established by way of labels\n- Timelines will be established by way of milestones\n\n# Style Guide\n\nFor javascript, typescript, markdown and yaml we enforce default [prettier](https://prettier.io/) formatting via a pipeline check. You can set up your IDE to format automatically, instantiate our formatting pre-commit hook by running `npm i && npx husky install` in the top-level directory, or ad-hoc by running `npm run beautify`.\n\nOn the C++ side, we don't yet have a coding style guideline, so please try to adhere to the style you see in the codebase. We will aim to get some tooling involved\nsoon to ameliorate that situation!\n\n## Thank you\n\n:pray: :heart: :rocket:\n"
  },
  {
    "path": "LICENSE.md",
    "content": "MIT License\n\nCopyright (c) [2019] [Nicholas Thompson]\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# React-JUCE\n\n> Write cross-platform native apps with React.js and JUCE\n\nReact-JUCE (formerly named Blueprint) is a hybrid JavaScript/C++ framework that enables a [React.js](https://reactjs.org/) frontend for a [JUCE](http://juce.com/) application or plugin. It provides an embedded, ES5 JavaScript engine via [Duktape](http://duktape.org/), native hooks for rendering the React component tree to `juce::Component` instances, and a flexbox layout engine via [Yoga](https://yogalayout.com/).\n\nFor more information, see the introductory blog post here: [Blueprint: A JUCE Rendering Backend for React.js](https://nickwritesablog.com/blueprint-a-juce-rendering-backend-for-react-js)\n\n## Status\n\n**Approaching Beta**. We hope to announce a beta release in the coming weeks, after which we will aim our focus at stability and completeness on the path\nto a 1.0 release.\n\n**Anticipated Breaking Changes**\n\n- We'll be renaming Blueprint to react-juce before beta (#34)\n- ~~Updating the examples and `npm init` template to point to npm instead of the local package~~\n- ~~`ReactApplicationRoot::evaluate` and `ReactApplicationRoot::evaluateFile` (#115)~~\n- ~~Refactoring the hot reloader and decoupling the EcmascriptEngine from ReactApplicationRoot (#65)~~\n\n## Resources\n\n- Documentation: [Docs & Getting Started](https://docs.react-juce.dev)\n- Discussions: [GitHub Discussions](https://github.com/nick-thompson/react-juce/discussions)\n- Community: [The Audio Programmer Discord Server](https://discord.gg/3H4wwVf49v)\n  - Join the `#blueprint` channel and say hi!\n\n## Maintainers\n\n- [@nick-thompson](https://github.com/nick-thompson)\n- [@joshmarler](https://github.com/JoshMarler)\n\n## Examples\n\nReact-JUCE is a young project, but already it provides the framework on which the entire user interface for [Creative Intent's Remnant](https://www.creativeintent.co/product/remnant) plugin is built.\n\n![Creative Intent Remnant: Screenshot](https://github.com/nick-thompson/react-juce/blob/master/RemnantScreenShot.jpg)\n\nBesides that, you can check out the example code in the `examples/` directory. See the \"Documentation\" section\nbelow for building and running the demo plugin. If you have a project written with React-JUCE that you want to share, get in touch! I would\nlove to showcase your work.\n\n## Contributing\n\nSee [CONTRIBUTING.md](https://github.com/nick-thompson/react-juce/blob/master/CONTRIBUTING.md)\n\n## License\n\nSee [LICENSE.md](https://github.com/nick-thompson/react-juce/blob/master/LICENSE.md)\n"
  },
  {
    "path": "docs/.nojekyll",
    "content": ""
  },
  {
    "path": "docs/README.md",
    "content": "# Introduction\n\nReact-JUCE is a hybrid JavaScript/C++ framework that enables a [React.js](https://reactjs.org/) frontend for a [JUCE](http://juce.com/) application or plugin. It provides an embedded, ECMAScript-compliant JavaScript engine via [Duktape](http://duktape.org/), native hooks for rendering the React component tree via `juce::Component` instances, and a flexbox layout engine via [Yoga](https://yogalayout.com/).\n\nFor more information, see the introductory blog post here: [React-JUCE: A JUCE Rendering Backend for React.js](https://nickwritesablog.com/blueprint-a-juce-rendering-backend-for-react-js)\n\n## Examples\n\nReact-JUCE is a young project, but already it provides the framework on which the entire user interface for [Creative Intent's Remnant](https://www.creativeintent.co/product/remnant) plugin is built.\n\n![Creative Intent Remnant: Screenshot](_media/RemnantScreenShot.jpg)\n\nBesides that, you can check out the example code in the `examples/` directory. See the \"Documentation\" section\nbelow for building and running the demo plugin. If you have a project written with React-JUCE that you want to share, get in touch! I would\nlove to showcase your work.\n\n## Contributing\n\nYes, please! I would be very happy to welcome your involvement. Take a look at the [open issues](https://github.com/nick-thompson/react-juce/issues)\nor the [project tracker](https://github.com/nick-thompson/react-juce/projects/1) to see if there's outstanding work that you might\nbe able to get started. Or feel free to propose an idea or offer feedback by [opening an issue](https://github.com/nick-thompson/react-juce/issues/new) as well.\n\nI don't have a formal style guide at the moment, so please try to match the present formatting in any code contributions.\n\n## License\n\nSee [LICENSE.md](https://github.com/nick-thompson/react-juce/blob/master/LICENSE.md)\n"
  },
  {
    "path": "docs/Resources.md",
    "content": "# Resources\n\n- [Introductory Blog Post](https://nickwritesablog.com/blueprint-a-juce-rendering-backend-for-react-js/)\n- [The Audio Programmer Podcast](http://img.youtube.com/vi/GOuFg773eCM/0.jpg)\n  - [![The Audio Programmer Podcast](http://img.youtube.com/vi/GOuFg773eCM/0.jpg)](https://www.youtube.com/watch?v=GOuFg773eCM)\n- [ADC 2019 Blueprint: rendering React.js to JUCE](https://www.youtube.com/watch?v=51pdMfGU-4g)\n  - [![ADC 2019 Blueprint: rendering React.js to JUCE](https://img.youtube.com/vi/51pdMfGU-4g/0.jpg)](https://www.youtube.com/watch?v=51pdMfGU-4g)\n"
  },
  {
    "path": "docs/SUMMARY.md",
    "content": "# Summary\n\n## Guides\n\n- [Getting Started](guides/Getting_Started.md)\n- [Running the Examples](guides/Running_the_Examples.md)\n- [Integrating Your Project](guides/Integrating_Your_Project.md)\n- [Debugging with Duktape](guides/Debugging_With_Duktape.md)\n- [Why Not React Native?](guides/Why_Not_React_Native.md)\n\n## Components\n\n- [View](components/View.md)\n- [Image](components/Image.md)\n- [Text](components/Text.md)\n- [Canvas](components/Canvas.md)\n- [Button](components/Button.md)\n- [Slider](components/Slider.md)\n- [ListView](components/ListView.md)\n- [ScrollView](components/ScrollView.md)\n- [Style Properties](components/Styles.md)\n- [Synthetic Events](components/Events.md)\n\n## Native\n\n- [Custom Native Components](native/Custom_Native_Components.md)\n- [JS/Native Interop](native/Interop.md)\n\n## Have a Question?\n\n- [GitHub Discussions](https://github.com/nick-thompson/react-juce/discussions)\n- [Discord Chatroom](https://discord.gg/3H4wwVf49v)\n- [Open an Issue](https://github.com/nick-thompson/react-juce/issues)\n"
  },
  {
    "path": "docs/components/Button.md",
    "content": "# Button\n\nA basic React component for rendering a button with web-like behavior and\nevent interactions.\n\n## Example\n\n```js\nimport React, { Component } from \"react\";\nimport { View, Button, Text } from \"react-juce\";\n\nfunction App(props) {\n  return (\n    <View {...styles.outer}>\n      <Button\n        {...styles.button}\n        onClick={(e) => console.log('Click')}\n        onMouseEnter={(e) => console.log('Mouse Enter!)}\n        onMouseLeave={(e) => console.log('Mouse Leave!)}>\n        <Text>Click me!</Text>\n      </Button>\n    </View>\n  );\n}\n\nconst styles = {\n  outer: {\n    width: \"100%\",\n    height: \"100%\",\n    backgroundColor: \"#17191f\",\n    justifyContent: \"center\",\n    alignItems: \"center\",\n  },\n  button: {\n    borderColor: \"#66cffd\",\n    padding: 20,\n  },\n};\n```\n\n## Props\n\n`Button` inherits support for all of the core `View` properties described in [View](View.md).\n\n#### onClick\n\nA callback property which will be invoked in response to a mouse click. The callback should\naccept a single [`SyntheticMouseEvent`](Events.md) argument.\n\n| Type     | Required | Supported                                                                                 |\n| -------- | -------- | ----------------------------------------------------------------------------------------- |\n| function | No       | Partial: [Standard](https://developer.mozilla.org/en-US/docs/Web/API/Element/click_event) |\n\n## Styles\n\n`Button` supports all of the default style properties described in [Style Properties](Styles.md).\n"
  },
  {
    "path": "docs/components/Canvas.md",
    "content": "# TODO\n"
  },
  {
    "path": "docs/components/Events.md",
    "content": "# TODO: Describe synthetic event support\n"
  },
  {
    "path": "docs/components/Image.md",
    "content": "# Image\n\nA React component for displaying different types of images, including network images,\nlocal image files, and image data URLs.\n\nThe example below demonstrates displaying a local image file, and a data url.\n\n## Example\n\n```js\nimport React, { Component } from \"react\";\nimport { View, Image } from \"react-juce\";\n\n// Using a bundling tool like Webpack or Rollup, we can configure this import\n// to read the image file from disk at the time of bundling, and embed the data\n// URL in our javascript bundle which can be imported just like this.\nimport logoDataUri from \"./logo.jpg\";\n\nfunction App(props) {\n  return (\n    <View {...styles.outer} onMouseDown={(e) => console.log(\"Mouse event!\", e)}>\n      <Image {...styles.image} source=\"file:///Users/nick/Documents/logo.jpg\" />\n      <Image {...styles.image} source={logoDataUri} />\n    </View>\n  );\n}\n\nconst styles = {\n  outer: {\n    width: \"100%\",\n    height: \"100%\",\n    backgroundColor: \"ff17191f\",\n    justifyContent: \"center\",\n    alignItems: \"center\",\n  },\n  image: {\n    width: \"25%\",\n    height: \"25%\",\n    padding: 20,\n  },\n};\n```\n\n## Props\n\n`Image` inherits support for all of the core `View` properties described in [View](View.md).\n\n#### source\n\nThe image source (either a remote URL ([#14](https://github.com/nick-thompson/react-juce/issues/14)), a local file resource, or a data uri).\n\n| Type   | Required | Supported                                                                  |\n| ------ | -------- | -------------------------------------------------------------------------- |\n| string | No       | Partial: [Standard](https://developer.mozilla.org/en-US/docs/Glossary/URL) |\n\n## Styles\n\n`Image` supports all of the default style properties described in [Style Properties](Styles.md).\n"
  },
  {
    "path": "docs/components/ListView.md",
    "content": "# TODO\n"
  },
  {
    "path": "docs/components/ScrollView.md",
    "content": "# TODO\n"
  },
  {
    "path": "docs/components/Slider.md",
    "content": "# Slider\n\nA basic React component for rendering a linear slider or rotary knob, common in\nmany audio applications.\n\n`Slider` is simply a composition of a single `View` component, a single `Canvas` component,\nand a set of default drawing operations to render common slider representations.\n\n## Example\n\n```js\nimport React, { Component } from \"react\";\nimport { View, Slider, Text } from \"react-juce\";\n\nfunction App(props) {\n  return (\n    <View {...styles.outer}>\n      <Slider\n        {...this.props}\n        value={props._value}\n        onDraw={Slider.drawRotary}\n        onMouseDown={props._onMouseDown}\n        onMouseUp={props._onMouseUp}\n        onChange={props._onSliderValueChange}\n      >\n        <Text>Cutoff Frequency</Text>\n      </Slider>\n    </View>\n  );\n}\n\nconst styles = {\n  outer: {\n    width: \"100%\",\n    height: \"100%\",\n    backgroundColor: \"#17191f\",\n    justifyContent: \"center\",\n    alignItems: \"center\",\n  },\n};\n```\n\n## Props\n\n`Slider` inherits support for all of the core `View` properties described in [View](View.md).\n\n#### sensitivity\n\nSets the sensitivity of a mouse drag interaction as it relates to changing the slider value.\nThe default value is `0.005`. Smaller numbers are less sensitive, larger numbers more sensitive.\n\n| Type   | Required | Supported    |\n| ------ | -------- | ------------ |\n| number | No       | Non-Standard |\n\n#### value\n\nSets the current value of the slider.\n\nSee React.js' notion of [controlled and uncontrolled components](https://reactjs.org/docs/forms.html#controlled-components). The `Slider`\nvalue property and `onChange` behavior follow this model.\n\n| Type   | Required | Supported    |\n| ------ | -------- | ------------ |\n| number | No       | Non-Standard |\n\n#### onDraw\n\nA callback property which will be invoked when its time to draw to the underlying `Canvas`.\nThis property is much like the `onDraw` property on the `Canvas` view itself, but with additional\narguments: (`context`, `width`, `height`, `value`).\n\nThese arguments are, respectively, the underlying canvas rendering context, the current width of the\nunderlying canvas object, the current height of the underlying canvas object, and the current slider value\non the range [0, 1].\n\nDefault drawing operations are provided as static members of the `Slider` class, which\ncan be passed directly as the `onDraw` property:\n\n- `Slider.drawLinearHorizontal`\n- `Slider.drawLinearVertical`\n- `Slider.drawRotary` (Default)\n\n| Type     | Required | Supported    |\n| -------- | -------- | ------------ |\n| function | No       | Non-Standard |\n\n#### onChange\n\nA callback property which will be invoked when the slider's value changes. The callback should\naccept a single argument: a number on the range [0, 1].\n\n| Type     | Required | Supported    |\n| -------- | -------- | ------------ |\n| function | No       | Non-Standard |\n\n#### mapDragGestureToValue\n\nA callback property which will be invoked to map a drag gesture to a new slider value. This\nallows for customization of the drag behavior, for example:\n\n- Behavior that maps drags \"up and to the right\" as increasing in value, and \"down and to the left\" as decreasing.\n- Behavior that maps only rightward drag as increasing in value and leftward drag as decreasing invalue.\n- Behavior that maps only upwards drag as increasing in value and downwards drag as decreasing invalue.\n\nThe callback should accept five arguments:\n`(mouseDownX, mouseDownY, sensitivity, valueAtDragStart, dragEvent)`. Respectively, these\narguments are the x and y position of the mouse at the time of the mouseDown event, the `sensitivity`\nof the slider as defined by the `sensitivity` prop above, the slider value at the time the drag started,\nand the current `SyntheticMouseEvent` for the drag operation.\n\nDefault mapping operations are provided as static members of the `Slider` class, which\ncan be passed directly as the `mapDragGestureToValue` property:\n\n- `Slider.linearHorizontalGestureMap`\n- `Slider.linearVerticalGestureMap`\n- `Slider.rotaryGestureMap` (Default)\n\n| Type     | Required | Supported    |\n| -------- | -------- | ------------ |\n| function | No       | Non-Standard |\n\n## Styles\n\n`Slider` supports all of the default style properties described in [Style Properties](Styles.md).\n"
  },
  {
    "path": "docs/components/Styles.md",
    "content": "# Style Properties\n\nStyle properties in React-JUCE generally aim to match the behavior and experience\nof writing CSS or writing a StyleSheet with React Native. It's important to note, however,\nthat these style properties _are not_ proper CSS, and that we have no notion of parsing CSS\nstylesheets. In React-JUCE, these properties are simple directives passed to the underlying `juce::Component`\nheirarchy that yield behavior that matches much of the CSS specificiation.\n\nAt present, these style properties are applied as a top-level prop to any given component, as you would with\nany other prop. In the future, we may adopt an API closer to that of React Native's StyleSheet.\n\n## Layout Props\n\n| Property           | Support | Spec                                                                             |\n| ------------------ | ------- | -------------------------------------------------------------------------------- |\n| flex               | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| flex-grow          | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| flex-shrink        | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| flex-basis         | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| flex-direction     | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| justify-content    | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| align-items        | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| align-content      | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| align-self         | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| flex-wrap          | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| position           | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| left               | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| top                | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| right              | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| bottom             | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| width              | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| height             | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| min-width          | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| min-height         | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| max-width          | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| max-height         | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| aspect-ratio       | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| direction          | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| overflow           | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| margin             | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| margin-left        | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| margin-top         | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| margin-right       | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| margin-bottom      | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| margin-start       | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| margin-end         | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| margin-horizontal  | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| margin-vertical    | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| padding            | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| padding-left       | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| padding-top        | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| padding-right      | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| padding-bottom     | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| padding-start      | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| padding-end        | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| padding-horizontal | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n| padding-vertical   | Yes     | [Flexbox](https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Flexbox) |\n\n## View Props\n\n| Property                   | Support                                                                  | Spec                                                                                                            |\n| -------------------------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- |\n| border-left-width          | Planned [(#143)](https://github.com/nick-thompson/react-juce/issues/143) | [MDN border-width](https://developer.mozilla.org/en-US/docs/Web/CSS/border-width)                               |\n| border-right-width         | Planned [(#143)](https://github.com/nick-thompson/react-juce/issues/143) | [MDN border-width](https://developer.mozilla.org/en-US/docs/Web/CSS/border-width)                               |\n| border-top-width           | Planned [(#143)](https://github.com/nick-thompson/react-juce/issues/143) | [MDN border-width](https://developer.mozilla.org/en-US/docs/Web/CSS/border-width)                               |\n| border-bottom-width        | Planned [(#143)](https://github.com/nick-thompson/react-juce/issues/143) | [MDN border-width](https://developer.mozilla.org/en-US/docs/Web/CSS/border-width)                               |\n| border-left-color          | Planned [(#143)](https://github.com/nick-thompson/react-juce/issues/143) | [MDN border-color](https://developer.mozilla.org/en-US/docs/Web/CSS/border-color)                               |\n| border-right-color         | Planned [(#143)](https://github.com/nick-thompson/react-juce/issues/143) | [MDN border-color](https://developer.mozilla.org/en-US/docs/Web/CSS/border-color)                               |\n| border-top-color           | Planned [(#143)](https://github.com/nick-thompson/react-juce/issues/143) | [MDN border-color](https://developer.mozilla.org/en-US/docs/Web/CSS/border-color)                               |\n| border-bottom-color        | Planned [(#143)](https://github.com/nick-thompson/react-juce/issues/143) | [MDN border-color](https://developer.mozilla.org/en-US/docs/Web/CSS/border-color)                               |\n| border-bottom-left-radius  | Planned [(#143)](https://github.com/nick-thompson/react-juce/issues/143) | [MDN border-radius](https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius)                             |\n| border-bottom-right-radius | Planned [(#143)](https://github.com/nick-thompson/react-juce/issues/143) | [MDN border-radius](https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius)                             |\n| border-top-left-radius     | Planned [(#143)](https://github.com/nick-thompson/react-juce/issues/143) | [MDN border-radius](https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius)                             |\n| border-top-right-radius    | Planned [(#143)](https://github.com/nick-thompson/react-juce/issues/143) | [MDN border-radius](https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius)                             |\n| border-width               | Planned [(#143)](https://github.com/nick-thompson/react-juce/issues/143) | [MDN border-width](https://developer.mozilla.org/en-US/docs/Web/CSS/border-width)                               |\n| border-color               | Planned [(#143)](https://github.com/nick-thompson/react-juce/issues/143) | [MDN border-color](https://developer.mozilla.org/en-US/docs/Web/CSS/border-color)                               |\n| border-radius              | Planned [(#143)](https://github.com/nick-thompson/react-juce/issues/143) | [MDN border-radius](https://developer.mozilla.org/en-US/docs/Web/CSS/border-radius)                             |\n| background-color           | Partial [(#84)](https://github.com/nick-thompson/react-juce/issues/84)   | [MDN background-color](https://developer.mozilla.org/en-US/docs/Web/CSS/background-color)                       |\n| opacity                    | Yes                                                                      | [juce::Component::setAlpha](https://docs.juce.com/master/classComponent.html#a1b9329a87c71ed01319071e0fedac128) |\n"
  },
  {
    "path": "docs/components/Text.md",
    "content": "# Text\n\nA React component for displaying text.\n\nUnlike React Native and React-DOM, `Text` does not yet support nesting ([#6](https://github.com/nick-thompson/react-juce/issues/6)), though\nit does happily support styling, and touch handling.\n\n## Example\n\n```js\nimport React, { Component } from \"react\";\nimport { View, Text } from \"react-juce\";\n\nfunction App(props) {\n  return (\n    <View {...styles.outer}>\n      <Text {...styles.labelText}>Hello, </Text>\n      <Text {...styles.nameText}>{props.name}</Text>\n    </View>\n  );\n}\n\nconst styles = {\n  outer: {\n    width: \"100%\",\n    height: \"100%\",\n    backgroundColor: \"#17191f\",\n    justifyContent: \"center\",\n    alignItems: \"center\",\n  },\n  labelText: {\n    color: \"#626262\",\n    fontSize: 16.0,\n    lineSpacing: 1.6,\n  },\n  nameText: {\n    color: \"#6262f8\",\n    fontSize: 16.0,\n    lineSpacing: 1.6,\n  },\n};\n```\n\n## Props\n\n`Text` inherits support for all of the core `View` properties described in [View](View.md).\n\n#### color\n\nThe color used to draw the text\n\n| Type   | Required | Supported                                                          |\n| ------ | -------- | ------------------------------------------------------------------ |\n| string | No       | [Standard](https://developer.mozilla.org/en-US/docs/Web/CSS/color) |\n\n#### fontSize\n\nThe font size used to draw the text\n\n| Type   | Required | Supported                                                             |\n| ------ | -------- | --------------------------------------------------------------------- |\n| string | No       | [Partial](https://developer.mozilla.org/en-US/docs/Web/CSS/font-size) |\n\n#### fontFamily\n\nThe font family name with which to draw the text\n\n| Type   | Required | Supported                                                               |\n| ------ | -------- | ----------------------------------------------------------------------- |\n| string | No       | [Partial](https://developer.mozilla.org/en-US/docs/Web/CSS/font-family) |\n\n#### fontStyle\n\nSets whether the text should be rendered bold, italics, or normal.\n\n| Type   | Required | Supported                                                              |\n| ------ | -------- | ---------------------------------------------------------------------- |\n| string | No       | [Partial](https://developer.mozilla.org/en-US/docs/Web/CSS/font-style) |\n\n#### justification\n\nSets the horizontal alignment of the text within the container.\n\nTODO: Rename this prop and match the text-align spec\n\n| Type   | Required | Supported                                                            |\n| ------ | -------- | -------------------------------------------------------------------- |\n| string | No       | [Non-Standard](https://docs.juce.com/master/classJustification.html) |\n\n#### kerningFactor\n\nSets the horizontal spacing between text characters.\n\nTODO: Rename this prop and match the letter-spacing spec\n\n| Type   | Required | Supported                                                                                     |\n| ------ | -------- | --------------------------------------------------------------------------------------------- |\n| string | No       | [Non-Standard](https://docs.juce.com/master/classFont.html#a996b7095b0956f62b71f24893e72a914) |\n\n#### lineSpacing\n\nSets the height of a line box, commonly used to apply vertical spacing between\nneighboring lines of text.\n\nTODO: Rename this prop and match the line-height spec\n\n| Type   | Required | Supported                                                                                                 |\n| ------ | -------- | --------------------------------------------------------------------------------------------------------- |\n| string | No       | [Non-Standard](https://docs.juce.com/master/classAttributedString.html#a0506d7b2000aaebd5873ea23eca6ae6a) |\n\n#### wordWrap\n\nSets the word-wrap behavior for when the text content overflows its content box.\n\n| Type   | Required | Supported                                                                                                 |\n| ------ | -------- | --------------------------------------------------------------------------------------------------------- |\n| string | No       | [Non-Standard](https://docs.juce.com/master/classAttributedString.html#ad752f270294ec5b2cef0c80863ee3a3c) |\n\n## Styles\n\n`Text` supports all of the default style properties described in [Style Properties](Styles.md).\n"
  },
  {
    "path": "docs/components/TextInput.md",
    "content": "TextInput component imitates web's `<input type=\"text\">`.\nhttps://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/text\nSo it supports props like `placeholder`, `maxlength`, `onInput`, etc...\n\nTextInput also supports React's controlled components model:\nhttps://reactjs.org/docs/uncontrolled-components.html.\nIf the user supplies a `value` prop,\nthen it never renders anything into that text editor other than\nthe string supplied by that `value` prop.\n\n## Example\n\n```js\nimport React, { Component } from \"react\";\n\nimport { Text, TextInput, View } from \"react-juce\";\n\nclass App extends Component {\n  constructor(props) {\n    super(props);\n    this._onInput = this._onInput.bind(this);\n\n    this.state = {\n      textValue: \"\",\n    };\n  }\n\n  _onInput(event) {\n    console.log(`onInput: ${event.value}`);\n    this.setState({ textValue: event.value });\n  }\n\n  render() {\n    return (\n      <View>\n        <TextInput\n          value={this.state.textValue}\n          placeholder=\"init message\"\n          onInput={this._onInput}\n          {...styles.text_input}\n        />\n      </View>\n    );\n  }\n}\n\nconst styles = {\n  text_input: {\n    backgroundColor: \"ff303030\",\n    color: \"ff66FDCF\",\n    fontSize: 15.0,\n    fontFamily: \"Menlo\",\n    fontStyle: Text.FontStyleFlags.bold,\n    \"placeholder-color\": \"ffAAAAAA\",\n    height: 30,\n    width: 200,\n  },\n};\n\nexport default App;\n```\n\n## Props\n\n**TODO**: Document props. See [the class](https://github.com/nick-thompson/react-juce/blob/master/packages/react-juce/src/components/TextInput.tsx#L11) for props in the meantime.\n"
  },
  {
    "path": "docs/components/View.md",
    "content": "# View\n\nThe most fundamental of the core React-JUCE components, `View` is a container that supports layout with flexbox, style, and some event handling.\n`View` maps directly to the underlying native `reactjuce::View` instance, which is effectively a simple `juce::Component`.\n\n`View` is designed to be nested inside other views and can have 0 to many children of any type.\n\n## Example\n\n```js\nimport React, { Component } from \"react\";\nimport { View } from \"react-juce\";\n\nfunction App(props) {\n  return (\n    <View {...styles.outer} onMouseDown={(e) => console.log(\"Mouse event!\", e)}>\n      <View {...styles.inner} />\n    </View>\n  );\n}\n\nconst styles = {\n  outer: {\n    width: \"100%\",\n    height: \"100%\",\n    backgroundColor: \"ff17191f\",\n    justifyContent: \"center\",\n    alignItems: \"center\",\n  },\n  inner: {\n    width: \"25%\",\n    height: \"25%\",\n    backgroundColor: \"ffa7191f\",\n  },\n};\n```\n\n## Props\n\n#### onMeasure\n\nA callback which will be invoked any time the `View`'s layout calculation changes.\nThe callback should accept a single argument, a [SyntheticEvent](Events.md) object holding\na `width` and `height` property reflecting the new size of the `View`.\n\n| Type     | Required | Supported         |\n| -------- | -------- | ----------------- |\n| function | No       | Yes: Non-Standard |\n\n#### onMouseDown\n\nA callback which will be invoked in response to a mouse button down event on the\nunderlying native component. The callback should accept a single argument, a [SyntheticMouseEvent](Events.md)\nobject similar in interface to [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent).\n\n| Type     | Required | Supported         |\n| -------- | -------- | ----------------- |\n| function | No       | Partial: Standard |\n\n#### onMouseUp\n\nA callback which will be invoked in response to a mouse button up event on the\nunderlying native component. The callback should accept a single argument, a [SyntheticMouseEvent](Events.md)\nobject similar in interface to [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent).\n\n| Type     | Required | Supported         |\n| -------- | -------- | ----------------- |\n| function | No       | Partial: Standard |\n\n#### onMouseEnter\n\nA callback which will be invoked in response to a mouse entering the local bounds of a native component.\nThe callback should accept a single argument, a `SyntheticMouseEvent`\nobject similar in interface to [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent).\n\n| Type     | Required | Supported         |\n| -------- | -------- | ----------------- |\n| function | No       | Partial: Standard |\n\n#### onMouseLeave\n\nA callback which will be invoked in response to a mouse leaving the local bounds of a native component.\nThe callback should accept a single argument, a `SyntheticMouseEvent`\nobject similar in interface to [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent).\n\n| Type     | Required | Supported         |\n| -------- | -------- | ----------------- |\n| function | No       | Partial: Standard |\n\n#### onMouseDoubleClick\n\nA callback which will be invoked in response to a mouse button double click on the\nunderlying native component. The callback should accept a single argument, a [SyntheticMouseEvent](Events.md)\nobject similar in interface to [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent).\n\n| Type     | Required | Supported         |\n| -------- | -------- | ----------------- |\n| function | No       | Partial: Standard |\n\n#### onKeyPress\n\nA callback which will be invoked in response to a key press event while the\nunderlying native component has focus. The callback should accept a single argument, a [SyntheticKeyboardEvent](Events.md)\nobject similar in interface to [KeyboardEvent](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent).\n\n| Type     | Required | Supported         |\n| -------- | -------- | ----------------- |\n| function | No       | Partial: Standard |\n\n## Styles\n\n`View` supports all of the default style properties described in [Style Properties](Styles.md).\n"
  },
  {
    "path": "docs/guides/Debugging_With_Duktape.md",
    "content": "# Debugger Support\n\n(Because console.log() isn't always enough)\n\nNote, there are known issues debugging on Windows. See [Known Issues](#known-issues)\n\nJS debugging support for React-JUCE/Duktape is available via [Visual Studio Code](https://code.visualstudio.com/) using the [Duktape Debugger](https://marketplace.visualstudio.com/items?itemName=HaroldBrenes.duk-debug) extension.\nCurrently this is the only debug client known to support the use of source maps with Duktape.\nIf you do become aware of other Duktape debug clients that may work well with React-JUCE, please open an issue with details for us to investigate.\n\nReact-JUCE provides an implementation of the Duktape debugging interface via `EcmascriptEngine::debuggerAttach` and `EcmascriptEngine::debuggerDetach`.\n\nIf you are using the `ReactApplicationRoot` class to host your React app/ui then you can enjoy a debugging experience similar to that of React Native.\n\nIn debug builds with `JUCE_DEBUG` defined, ensure your editor has focus and use the `CTRL-d/CMD-d` command to trigger a call to `EcmascriptEngine::debuggerAttach`.\nThis command blocks the UI and awaits connection from a debug client. You can then attach your debugger, continue execution and set breakpoints etc.\n\nTo configure the Duktape debugger extension for use with React-JUCE, you will need to do the following:\n\n- Download/Add the Duktape debugger extension.\n\n- Ensure you have compiled React-JUCE and your application/plugin in debug mode (with `JUCE_DEBUG` defined).\n\n- Add a launch configuration for debugging your UI.\n\nAn example launch configuration for use with the `GainPlugin` example project is provided below.\nNote that `localRoot` points to the root `workspaceFolder`. In this case we assume `workspaceFolder` to be `examples/GainPlugin/jsui`.\nThe `outDir` entry points to the build directory containing the compiled JS bundle you wish to debug.\nThis `outDir` directory should also contain the bundle's associated source map.\n\n```\n{\n  \"version\": \"0.2.0\",\n  \"configurations\": [\n      {\n          \"name\": \"JSUI Debug Attach\",\n          \"type\": \"duk\",\n          \"request\": \"attach\",\n          \"address\": \"localhost\",\n          \"port\": 9091,\n          \"localRoot\": \"${workspaceFolder}\",\n          \"sourceMaps\": true,\n          \"outDir\": \"${workspaceFolder}/build/js\",\n          \"stopOnEntry\": false,\n          \"debugLog\": false\n      }\n   ]\n}\n```\n\nTo ensure debugging works reliably, you need to ensure your source map has been generated by webpack using [devtool](https://webpack.js.org/configuration/devtool/).\nThe following option should be added to the `output` key in your webpack config:\n\n`devtoolModuleFilenameTemplate: 'webpack:///[absolute-resource-path]'`\n\nYou also need to ensure that your bundle is not minified, this can be achieved by building your JS bundle with `webpack --mode=development`.\nIn the case of the `GainPlugin` example this can be achieved by running `npm run start` in `GainPlugin/jsui`.\n\nThe `webpack.config.js` template provided by React-JUCE enables all of this for you. See: [Starting a new Project](New_Project.md) for a project\ntemplate setup which includes debugger support. Project template files are available under `react-juce/packages/react-juce/template`.\n\nExample `webpack.config.js`:\n\n```\nmodule.exports = {\n  entry: './src/index.js',\n  // This is the section you care about for debugging.\n  output: {\n    path: __dirname + '/build/js',\n    filename: 'main.js',\n    sourceMapFilename: \"[file].map\",\n    devtoolModuleFilenameTemplate: 'webpack:///[absolute-resource-path]'\n  },\n  devtool: \"source-map\",\n  module: {\n    rules: [\n      {\n        test: /\\.(js|jsx)$/,\n        exclude: /node_modules/,\n        use: ['babel-loader']\n      },\n      {\n        test: /\\.svg$/,\n        exclude: /node_modules/,\n        use: ['svg-inline-loader']\n      },\n      {\n        test: /\\.(png|jpeg|jpg|gif)$/,\n        use: [\n          {\n            loader: 'url-loader',\n            options: {\n              limit: true,\n              esModule: false\n            }\n          }\n        ]\n      }\n    ]\n  },\n}\n```\n\nTo test debugging support using the `GainPlugin` example do the following:\n\n- Open the `GainPlugin/jsui` directory in Visual Studio Code.\n\n- Add the `launch.json` configuration from above to your `.vscode` directory under `GainPlugin/jsui`.\n\n- Run `npm run start` in the `jsui` directory\n\n- Start the standalone plugin app in your IDE (i.e. Visual Studio/Xcode)\n\n- Give the `GainPlugin`'s UI/PluginEditor focus and hit `CTRL-d` (Win) / `CMD-d` (Mac)\n\n- Start the `JSUI Debug Attach` launch task from the VSCode debugger menu.\n\n- Set some breakpoints, profit!\n\n## Known Issues\n\n- Debugging support is currently experimental and issues may occur from time to time whilst we refine the experience.\n\n- At present there are some issues debugging duktape under Windows. The vscode-duktape-debug extension requires a patch to resolve source map entries, without this patch setting breakpoints in source files fails. To obtain a version of the extension with this patch you can fetch https://github.com/JoshMarler/vscode-duktape-debug/tree/topic/fix-windows-debug-blueprint. To use this version of the extension run `npm install` in the `vscode-duktape-debug` root followed by `npm run compile`. You can then copy the contents of `vscode-duktape-debug/dist` to your vscode extensions directory which is usually under `.vscode` in your home folder. Copy the contents of `vscode-duktape-debug/dist` to `.vscode/extensions/haroldbrenes.duk-debug-0.5.6`. There are issues attaching the debugger with breakpoints already set in vscode on Windows. You will need to attach the debugger and then set breakpoints once attached.\n\n## Acknowledgements\n\nThanks to [harold-b](https://github.com/harold-b/vscode-duktape-debug) for his excellent extension.\n"
  },
  {
    "path": "docs/guides/Getting_Started.md",
    "content": "# Getting Started\n\nThis guide assumes you have some familiarity with [React.js](https://reactjs.org/) and with [JUCE](https://juce.com/), and it is therefore recommended that you spend some time getting comfortable there, if you're not already, before embarking on this guide.\n\n## Dependencies\n\nTo get started with React-JUCE, you'll first need to install a few dependencies:\n\n- [Node.js](https://nodejs.org/en/) v8.11.0+\n- [npm](https://www.npmjs.com/) v5.6.0+\n- [JUCE](https://juce.com/) v5.4.2+ (Optional if you are only running the examples)\n- Xcode10.2+ (MacOS)\n- Visual Studio 2017+ (Windows)\n\nOnce you have the dependencies installed, we need to clone the React-JUCE repository\nitself. React-JUCE's git repository contains necessary submodules, so we'll need to\ncollect those as well, which we can do one of two ways:\n\n```bash\n$ git clone --recurse-submodules git@github.com:nick-thompson/react-juce.git\n```\n\nor\n\n```bash\n$ git clone git@github.com:nick-thompson/react-juce.git\n$ cd react-juce\n$ git submodule update --init --recursive\n```\n\nNote that the `git@github.com` prefix here indicates cloning via SSH. If you prefer\nto work with git via HTTPS you'll want to swap in `https://github.com/nick-thompson/react-juce.git`\nin the above commands.\n\nAt this point, we've got everything ready to get our project up and running. Let's\nmove on to the next step, [running the demo plugin](Running_the_Examples.md).\n"
  },
  {
    "path": "docs/guides/Integrating_Your_Project.md",
    "content": "# Starting a New Project\n\nThis step assumes you've already reviewed the [Getting Started](Getting_Started.md) guide. If not,\nplease start there!\n\nOk, so you're ready to add some React.js to your JUCE project. Whether that's a totally new project or a preexisting project, getting React-JUCE involved is the same. If you're starting your project from scratch, I recommend running through the [Getting started with the Projucer](https://docs.juce.com/master/tutorial_new_projucer_project.html) tutorial on the JUCE website, if you haven't already.\n\nNow before we write any code, we have to add React-JUCE to our JUCE project. Fortunately, JUCE makes this super\neasy with the JUCE module format, and React-JUCE abides by that format. Follow along with the [Manage JUCE modules](https://docs.juce.com/master/tutorial_manage_projucer_project.html#tutorial_manage_projucer_project_managing_modules) section of the Projucer tutorial, wherein you'll need to add the React-JUCE module by pointing the Projucer to its location on disk. The actual React-JUCE JUCE module is located in the `react_juce` subdirectory of the root of the React-JUCE project.\n\n## Template Generator\n\nNext, the first thing we want to do here is write some React.js, so let's start with a \"Hello World!\" of our own. React-JUCE's `react-juce` npm package carries a template generator that you can use to boostrap a React application for your project. For this step, let's assume your JUCE project directory is at `~/MyProject`, the source files are at `~/MyProject/Source`, and we want to put the React application source at `~/MyProject/Source/jsui` (note, you can put this wherever you want). Now, to use the template generator, we start again at the root of the React-JUCE git repository:\n\n```bash\n$ pwd\n/Users/nick/Dev/react-juce\n$ cd packages/react-juce\n$ npm run init -- ~/MyProject/Source/jsui\n```\n\nThe template generator will create the `jsui` directory as suggested in the example command above, fill it\nwith a basic \"Hello World!\" app, and install local dependencies like React.js and Webpack. Like the [[GainPlugin Example|running-the-example]], we now need to build our output bundle.\n\n```bash\n$ cd ~/MyProject/Source/jsui\n$ npm start\n```\n\nAt this point we've got our app bundle ready to roll, so let's turn over to the native side to mount this into\nour JUCE project.\n\n## Native Code\n\nBecause we've already added the React-JUCE module to our Projucer project, we can jump straight into the code on the native side. Part of the native React-JUCE API is a particularly important class called `reactjuce::ReactApplicationRoot`. This class is mostly just a `juce::Component`, and in that way you should think about using it the same way you might use a `juce::Slider` in your application.\n\nFor example, let's suppose that we have our `MainComponent` or our `AudioProcessorPluginEditor` at the top of our project:\n\n```cpp\nclass MainComponent   : public Component\n{\npublic:\n    //==============================================================================\n    MainComponent();\n    ~MainComponent();\n\n    //==============================================================================\n    void paint (Graphics&) override;\n    void resized() override;\n\nprivate:\n    //==============================================================================\n    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)\n};\n```\n\nAdding the `reactjuce::ReactApplicationRoot` is easy, and should be familiar if you've worked with `juce::Component`s before:\n\n```cpp\nclass MainComponent   : public Component\n{\npublic:\n    //==============================================================================\n    MainComponent()\n    {\n        addAndMakeVisible(appRoot);\n        setSize(400, 300);\n    }\n\n    ~MainComponent();\n\n    //==============================================================================\n    void paint (Graphics&) override;\n\n    void resized() override\n    {\n        appRoot.setBounds(getLocalBounds());\n    }\n\nprivate:\n    //==============================================================================\n    reactjuce::ReactApplicationRoot appRoot;\n\n    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)\n};\n```\n\nIt's important to note here that our `appRoot` will be the point at which our React application code from earlier\nwill \"take over,\" and it's also important to note that you can add this `appRoot` wherever you need it in your application. For example, if you want to write your entire interface in React, you should mount your `appRoot` at the top of your application in your `MainComponent` or your `AudioProcessorPluginEditor`. If instead you want only to write your preset switcher in React, you can build the rest of your interface as usual with JUCE, and add the `appRoot` wherever the preset switcher should go within the context of your interface.\n\nNow we're almost done here, but if you compile and run right now you won't see your \"Hello from React.js!\"– of course, we haven't told the `appRoot` where to find the JavaScript bundle we made! So, putting the last piece together here:\n\n```cpp\nclass MainComponent   : public Component\n{\npublic:\n    //==============================================================================\n    MainComponent()\n    {\n        // First thing we have to do is load our javascript bundle from the build\n        // directory so that we can evaluate it within our appRot.\n\n        // TODO: Replace this with the appropriate path to your javascript bundle!\n        File bundle = File(\"/path/to/your/jsui/build/js/main.js\");\n\n        addAndMakeVisible(appRoot);\n        appRoot.evaluate(bundle);\n\n        setSize(400, 300);\n    }\n\n    ~MainComponent();\n\n    //==============================================================================\n    void paint (Graphics&) override;\n\n    void resized() override\n    {\n        appRoot.setBounds(getLocalBounds());\n    }\n\nprivate:\n    //==============================================================================\n    reactjuce::ReactApplicationRoot appRoot;\n\n    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)\n};\n```\n\nThat's it! We've now integrated React-JUCE into our project, and now you can write freely in React.js and watch your application take shape.\n"
  },
  {
    "path": "docs/guides/Running_the_Examples.md",
    "content": "# Running the GainPlugin Example project\n\nThis step assumes you've already reviewed the [Getting Started](Getting_Started.md) guide. If not,\nplease start there!\n\n## GainPlugin\n\n![Gain Plugin example project user interface](../_media/gainplugin.jpg)\n\nReact-JUCE includes an extremely simple utility gain plugin to demonstrate the minimal\ncode required for integrating React-JUCE into a JUCE project. To get it running,\nwe only need two steps: compiling the JavaScript bundle, and then compiling and\nrunning the native code.\n\n### JavaScript Bundle\n\nAll React-JUCE projects have two components: we have the native code that knows how\nto mount the React application into our JUCE project and satisfy calls from React's\nreconciler, and then we have the React.js application code that we want to run in the\nnative environment. In order to ease this handoff, we're using a tool in this\nexample called [Webpack](https://webpack.js.org/) that can compile a complete JavaScript project into a single\nfile. That single file is then the only thing we need to execute in the native\nenvironment.\n\nTo get the GainPlugin up and running for the first time, we have to first perform\nthat compilation step. So, from the root of the `React-JUCE` git repository:\n\n```bash\n$ cd examples/GainPlugin/Source/jsui/\n```\n\nThe `jsui/` directory here is the top level directory of all the\nReact.js application code that we used to build the example interface.\nWe use a build step managed by npm to compile all of our application javascript\ninto a single file that can be easily loaded up in the native app:\n\n```bash\n$ npm install\n$ npm run build\n```\n\nAt this point, you'll see an output file in `examples/GainPlugin/Source/jsui/build/js/`. That file location is important, because that's where the native code looks for executing the output file.\n\n### Native\n\nNow that we have our JavaScript bundle, the last step is simple: just hit Build and\nRun from your IDE! When the JUCE PluginEditor gets initialized, it will find your\nJavaScript build and evaluate it within the embedded interpreter to draw the\nGainPlugin interface.\n\n## Hot Reloading\n\nThe GainPlugin example is preconfigured with hot reloading, so that as you edit\nthe React application code, your interface will redraw itself instantly. In order\nto take advantage of this, we need to recompile our JavaScript bundle on the\nfly as we're editing our code. Fortunately, Webpack makes that simple, so from\nwithin the `jsui/` directory:\n\n```bash\n$ npm start\n```\n\nThis will first build your JavaScript bundle, then wait and watch your source files\nfor changes. When it finds a change, it will pick that change up and incrementally\nrebuild your bundle. In turn, React-JUCE will pick up the change to the bundle file\nand redraw your interface.\n\nNow that you're up and running, take a minute to tweak the GainPlugin React\napplication to get a sense of the workflow! When you're done, let's move on to\nthe next step, [adding React-JUCE to your own project](New_Project.md).\n"
  },
  {
    "path": "docs/guides/Why_Not_React_Native.md",
    "content": "# Why Not React Native?\n\nThe React community first formed in 2013 when React was introduced as a framework for writing web applications. Shortly thereafter, the team announced React Native for rendering native iOS and Android mobile apps, and the React community grew accordingly. The community then introduced a project for rendering native Windows desktop apps from React, and since then several projects have spun off with similar goals. Why, then, do we need another one in React-JUCE?\n\nTo start, I think it's helpful to clarify the goals of these projects and the underlying philosophy that brings them together. Then, I think's helpful to recognize JUCE's utility and popularity in the audio application development space. Finally, once we've covered those points, I think the answer to our original question becomes quite clear, and shows why React-JUCE stands to make an impact in the audio application development space.\n\n## The React Philosophy\n\nWhen the React team introduced React Native in 2015, they made a point to clarify that React and React Native were different projects. With its introduction, they started sharing the idea \"Learn once, write anywhere,\" which we still see in their messaging today. What we see from that message is that their goal was never to be able to write a React web app and then push a button to ship that same app to native mobile. Rather, the goal was slightly higher level.\n\nAt the initial React.js announcement, the library focused totally on web applications. When React Native showed up, we saw the team split out the React DOM package. This step is very illuminating. After that, to talk about React in the context of a cross-platform web/mobile app, we have to consider three things: React, React DOM, and React Native. This distinction is helpful in that it shows React itself is only an abstract tool. It deals in abstract representations of a user interface, and the business logic around that user interface. But eventually this abstraction layer decays to real rendering primitives, and here we see what separates React DOM and React Native. React DOM provides a library of rendering primitives targeting the Web DOM. React Native provides a library of rendering primitives targeting native platform components in iOS and Android. (As a brief aside, this distinction in rendering primitives is exactly where React-JUCE fits into the picture as well, offering a library of rendering primitives that target JUCE.)\n\nThrough this lens, React Native's \"Learn once, write anywhere\" philosophy makes sense. Different rendering primitives on different platforms may have totally different semantics, and the idea of writing an application against one set of rendering primitives and then pushing a button to render against a new set of primitives just falls over in some cases. But the idea of _working in React_ never changes. With these tools, a single team can write a web application and then turn around and write a native iOS, Android or Windows desktop application with total familiarity. This isn't \"push a button, render anywhere,\" it's about lowering the barrier to entry to new platforms, unifying the development experience, and empowering developers to cross what have long been great divides in our industry.\n\n## The JUCE Ecosystem\n\nOur brief survey of the React landscape tells a compelling story when viewed from the perspective of a generic application developer. But what happens when we look from the perspective of an audio application developer?\n\nReact Native solves a very non-trivial problem in the way it bridges between iOS and Android. A React Native developer can write a single application and deploy it to two totally different platforms, while React Native takes care of answering all the prerequisite questions about how to get an application up and running on each respective platform, how to provision that top level window, and how to evaluate the application JavaScript bundle in an embedded interpreter.\n\nJUCE takes its place in the audio application development ecosystem answering very similar questions. Nearly all audio applications start with the same two requirements:\n\n- A window provisioned somewhere (either directly or perhaps by a host program) into which we can render our interface\n- An audio buffer from the driver on which we can operate our signal processing\n\nUnfortunately, in audio, and especially when we consider audio plugin development, this is a combinatorial problem which grows extremely quickly. To answer even the first bullet point above, we have a lot to consider.\n\n- How do I get to that top-level window when running as an AAX plugin on Windows?\n  - What rendering primitives do I use once I'm there? Windows Platform APIs?\n- How do I get to that top-level window when running as an AU plugin on MacOS?\n  - And what rendering primitives can I use here? CoreGraphics?\n- And what if I want to ship the same application as a standalone Linux application? Or even an embedded Linux application? How do I get to that top-level window against X11 there?\n\nI could keep that list running for a _long_ time. And that's just to address the first of the core requirements of an audio application; the same list runs back for getting access to the underlying audio callback in all of these scenarios.\n\nHere, I think it's fair to say that JUCE has solved a massively challenging problem very elegantly in abstracting over all of these combinations. To write an audio application with JUCE, developers need only start from the core questions about _what_ the application will do once it has access to that window and the underlying audio buffer, and JUCE will take care of extending that functionality across all of the combinations of target platform, windowing system, audio driver, and plugin host. This is why, in my opinion, JUCE has become such a widely adopted framework for audio application development.\n\n## React + JUCE = <3\n\nAgainst this backdrop, a compelling case for React-JUCE is already starting to reveal itself. But before going any further, I think it's worthwhile to say that React Native and React Native Windows _are_ great options.\n\nIf your goal is singular in focus, say, to ship an audio application on iOS, then starting at React Native is an excellent choice. React Native will solve the top level window question for you, and you may then have to solve the problem of \"How do I get to that audio buffer when running as a standalone on iOS,\" but that's a problem you'll only need to solve once. Or you might start at JUCE and figure out how to mount React Native into the window that JUCE provisions for you. Either way, in a scenario like this, your project will be neatly limited in the scope of the problems that you have to solve. I would happily recommend to people with a goal that has this type of focus to use React Native, or React Native Windows.\n\nBut this approach starts to break down when the project goal broadens. For example, maybe you want to ship your audio application as a standalone desktop app and a standalone iOS app. Now, if you start with React Native, you can find your answer to the question above for getting to the audio buffer just the same on iOS, but what happens when you want to ship to desktop? Well, maybe the audio buffer part is the same, and surely if you've integrated JUCE into your React Native project you can rely on JUCE for that part here too, but React Native doesn't render to desktop. So do you integrate a different framework for writing the desktop interface? Maybe you can integrate React Native Windows, but what about MacOS? Suddenly we're creeping back into the combinatorial problem we mentioned above, and we haven't even cracked this door open to include shipping the application as a cross-platform audio plugin, or potentially as a Linux application.\n\nHere is exactly the place where React-JUCE finds its home. With React-JUCE, we can leverage JUCE's elegant solution to this hugely combinatorial problem, while at the same time leveraging the capabilities that React has introduced to the world of app UI programming, with no extra overhead. Shipping an audio application with React as a standalone application across MacOS, Windows, Linux, and as a plugin across AAX, AU, VST3, LV2 is now as easy as it should be.\n\nAnd there's more still. It would be a shame to acknowledge the popularity of JUCE without addressing all of the many projects already shipped or actively underway with JUCE. React-JUCE is designed to be trivially integrated into any existing JUCE project: anywhere you can mount a `juce::Component`, whether that's in an existing project or a brand new project, you can mount React-JUCE, and start writing React.\n\nI started this project with the goal of fully embracing the \"Learn once, write anywhere\" message introduced by React and React Native. It's my hope now that in the same way React Native empowers React developers to approach mobile platforms, React-JUCE empowers developers to approach the audio application space.\n"
  },
  {
    "path": "docs/native/Custom_Native_Components.md",
    "content": "# TODO\n"
  },
  {
    "path": "docs/native/Interop.md",
    "content": "# JavaScript/Native Interop\n\nThere are generally two ways to cross the Native/JavaScript boundary:\n\n1. You can pass C++ values and functions into JavaScript, and JavaScript values and functions into C++ directly or via an event model\n2. Or, you can create a custom native View and render it in your React component tree\n\n## Value Passing\n\nTo pass C++ values and functions into your JS environment, see `EcmascriptEngine::registerNativeProperty`\nand `EcmascriptEngine::registerNativeMethod`. These methods will install the given values on either the `global`\nobject, or named object of your choosing.\n\nIn the other direction, you can pass values from JavaScript into C++ either via invoking the methods that\nwere installed via `EcmascriptEngine::registerNativeMethod` or by assigning a value to a named object accessible\nfrom the global object, and looking that value up or invoking it on the C++ side with `EcmascriptEngine::evaluateInline` or `EcmascriptEngine::invoke`.\n\n### Example\n\n```cpp\n// From C++\nengine->registerNativeProperty(\"world\", \"Hello!\");\nengine->registerNativeMethod(\"sayHello\", [this](juce::var::NativeFunctionArgs const& args) {\n    // Here, `args.arguments[0]` comes from JavaScript\n    std::cout << args.arguments[0].toStdString() << std::endl;\n});\n```\n\n```js\n// Then, from js\nconsole.log(\"Hello\", global.world);\nglobal.sayHello(\"World!\");\n```\n\nAnd similarly, in the other direction:\n\n```js\n// From js\nglobal.myFun = (x) => x * x;\nglobal.myValue = 17;\n```\n\n```cpp\n// From C++\nauto myValue = engine->evaluateInline(\"global.myValue\");\nauto result = engine->invoke(\"myFun\", (int) myValue);\n```\n\n## Custom Native View\n\nNow the other option is to define a totally custom native view, and register it with React.\nTo do this, you can make your own C++ class that inherits `reactjuce::View`, and override the necessary methods.\nBasically, a `reactjuce::View` is just a `juce::Component` with some extra goodies.\n\nFor greater detail, see [Custom Native Components](Custom_Native_Components.md), but for a brief example, see below.\n\n### Example\n\n```cpp\nclass MyCoolView : public reactjuce::View {\n  void paint(juce::Graphics& g) override {\n    // Do your own paint routine like usual.\n    // You can also treat this whole class instance like your normal juce::Components. Add children, `addAndMakeVisible`,\n   // `resized` and everything!\n  }\n}\n```\n\nNow once you've got your custom view implementation, you have to tell React about it so that you can use it. The end goal with this is to be able to write something like this:\n\n```js\nfunction MyReactApp(props) {\n  return (\n    <View>\n      <MyCoolView customProp=\"hi\" otherCustomProp=\"bye\" />\n    </View>\n  );\n}\n```\n\nWith this, you can write your juce::Components like normal, but use React to compose these things together into your full application.\nSo, how do we register your C++ class with React? All you need is `ReactApplicationRoot::registerViewType`:\n\n```cpp\nmAppRoot.registerViewType(\"MyCoolView\", []() {\n  // This lambda will be called when we need to construct one of your custom view instances. So, first, we make one:\n  auto view = std::make_unique<MyCoolView>();\n\n  // Then we need to construct a shadow view, which will govern the layout. 99% of the time, you can just use the\n  // default shadow view:\n  auto shadowView = std::make_unique<ShadowViewType>(view.get());\n\n  // Then just return these guys as a pair\n  return {std::move(view), std::move(shadowView)};\n});\n```\n\nThat's it, React can now understand your `MyCoolView`!\n\nNow there's one last cosmetic issue. In React, you can always make elements with `React.createElement(\"MyCoolView\", props, children);`,\nbut you rarely see that because people are used to using JSX and writing `<MyCoolView {...props}>`.\nIf you want to use JSX like that you have to make this little wrapper to abstract over the dynamic string argument:\n\n```js\nfunction MyCoolView(props) {\n  return React.createElement(\"MyCoolView\", props, props.children);\n}\n\n// Now I can use it elsewhere in JSX...\nfunction MyApp(props) {\n  return <MyCoolView {...props} />;\n}\n```\n"
  },
  {
    "path": "examples/GainPlugin/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.15)\nproject(GainPlugin VERSION 0.1.0)\n\n# `juce_add_plugin` adds a static library target with the name passed as the first argument.\n# This target is a normal CMake target, but has a lot of extra properties set\n# up by default. As well as this shared code static library, this function adds targets for each of\n# the formats specified by the FORMATS arguments. This function accepts many optional arguments.\n# Check the readme at `docs/CMake API.md` in the JUCE repo for the full list.\n\njuce_add_plugin(GainPlugin\n    # VERSION ...                               # Set this if the plugin version is different to the project version\n    # ICON_BIG ...                              # ICON_* arguments specify a path to an image file to use as an icon for the Standalone\n    # ICON_SMALL ...\n    # COMPANY_NAME ...                          # Specify the name of the plugin's author\n    # IS_SYNTH TRUE/FALSE                       # Is this a synth or an effect?\n    # NEEDS_MIDI_INPUT TRUE/FALSE               # Does the plugin need midi input?\n    # NEEDS_MIDI_OUTPUT TRUE/FALSE              # Does the plugin need midi output?\n    # IS_MIDI_EFFECT TRUE/FALSE                 # Is this plugin a MIDI effect?\n    # EDITOR_WANTS_KEYBOARD_FOCUS TRUE/FALSE    # Does the editor need keyboard focus?\n    # COPY_PLUGIN_AFTER_BUILD TRUE/FALSE        # Should the plugin be installed to a default location after building?\n    PLUGIN_MANUFACTURER_CODE Reju               # A four-character manufacturer id with at least one upper-case character\n    PLUGIN_CODE Dem0                            # A unique four-character plugin id with at least one upper-case character\n    FORMATS AU VST3 Standalone                  # The formats to build. Other valid formats are: AAX Unity VST AU AUv3\n    PRODUCT_NAME \"ReactJUCEGainPlugin\")         # The name of the final executable, which can differ from the target name\n\n# `juce_generate_juce_header` will create a JuceHeader.h for a given target, which will be generated\n# into your build tree. This should be included with `#include <JuceHeader.h>`. The include path for\n# this header will be automatically added to the target. The main function of the JuceHeader is to\n# include all your JUCE module headers; if you're happy to include module headers directly, you\n# probably don't need to call this.\njuce_generate_juce_header(GainPlugin)\n\n# `target_sources` adds source files to a target. We pass the target that needs the sources as the\n# first argument, then a visibility parameter for the sources (PRIVATE is normally best practice,\n# although it doesn't really affect executable targets). Finally, we supply a list of source files\n# that will be built into the target. This is a standard CMake command.\ntarget_sources(GainPlugin PRIVATE PluginProcessor.cpp)\n\n# Add an explicit include path here so that React-juce's EcmascriptEngine can find\n# the included Duktape source. You can optionally point this elsewhere if you'd like to\n# include a custom Duktape build.\ntarget_include_directories(GainPlugin PRIVATE react_juce/)\n\n# `target_compile_definitions` adds some preprocessor definitions to our target. In a Projucer\n# project, these might be passed in the 'Preprocessor Definitions' field. JUCE modules also make use\n# of compile definitions to switch certain features on/off, so if there's a particular feature you\n# need that's not on by default, check the module header for the correct flag to set here. These\n# definitions will be visible both to your code, and also the JUCE module code, so for new\n# definitions, pick unique names that are unlikely to collide! This is a standard CMake command.\ntarget_compile_definitions(GainPlugin\n    PRIVATE\n    GAINPLUGIN_SOURCE_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"\n    JUCE_WEB_BROWSER=0  # If you remove this, add `NEEDS_WEB_BROWSER TRUE` to the `juce_add_plugin` call\n    JUCE_USE_CURL=0     # If you remove this, add `NEEDS_CURL TRUE` to the `juce_add_plugin` call\n    JUCE_VST3_CAN_REPLACE_VST2=0)\n\n# `target_link_libraries` links libraries and JUCE modules to other libraries or executables. Here,\n# we're linking our executable target to the `juce::juce_audio_utils` module. Inter-module\n# dependencies are resolved automatically, so `juce_core`, `juce_events` and so on will also be\n# linked automatically. If we'd generated a binary data target above, we would need to link to it\n# here too. This is a standard CMake command.\ntarget_link_libraries(GainPlugin PRIVATE\n    juce::juce_recommended_config_flags\n    juce::juce_recommended_lto_flags\n    juce::juce_recommended_warning_flags\n    juce::juce_core\n    juce::juce_audio_basics\n    juce::juce_audio_devices\n    juce::juce_audio_processors\n    juce::juce_audio_utils\n    juce::juce_graphics\n    juce::juce_gui_basics\n    react_juce)\n"
  },
  {
    "path": "examples/GainPlugin/PluginProcessor.cpp",
    "content": "/*\n  ==============================================================================\n\n    This file was auto-generated!\n\n    It contains the basic framework code for a JUCE plugin processor.\n\n  ==============================================================================\n*/\n\n#include \"PluginProcessor.h\"\n\n\n//==============================================================================\n/** Helper function for generating the parameter layout. */\nAudioProcessorValueTreeState::ParameterLayout createParameterLayout()\n{\n    AudioProcessorValueTreeState::ParameterLayout params (\n        std::make_unique<AudioParameterFloat>(\n            \"MainGain\",\n            \"Gain\",\n            NormalisableRange<float>(0.0, 1.0),\n            0.8,\n            String(),\n            AudioProcessorParameter::genericParameter,\n            [](float value, int /* maxLength */) {\n                return String(Decibels::gainToDecibels(value), 1) + \"dB\";\n            },\n            nullptr\n        ),\n        std::make_unique<AudioParameterBool>(\n            \"MainMute\",\n            \"Mute\",\n            false\n       )\n    );\n\n    return params;\n}\n\n//==============================================================================\nGainPluginAudioProcessor::GainPluginAudioProcessor()\n     : AudioProcessor (BusesProperties()\n                       .withInput  (\"Input\",  AudioChannelSet::stereo(), true)\n                       .withOutput (\"Output\", AudioChannelSet::stereo(), true)),\n       params(*this, nullptr, JucePlugin_Name, createParameterLayout())\n{\n}\n\nGainPluginAudioProcessor::~GainPluginAudioProcessor()\n{\n    stopTimer();\n}\n\n//==============================================================================\nconst String GainPluginAudioProcessor::getName() const\n{\n    return JucePlugin_Name;\n}\n\nbool GainPluginAudioProcessor::acceptsMidi() const\n{\n   #if JucePlugin_WantsMidiInput\n    return true;\n   #else\n    return false;\n   #endif\n}\n\nbool GainPluginAudioProcessor::producesMidi() const\n{\n   #if JucePlugin_ProducesMidiOutput\n    return true;\n   #else\n    return false;\n   #endif\n}\n\nbool GainPluginAudioProcessor::isMidiEffect() const\n{\n   #if JucePlugin_IsMidiEffect\n    return true;\n   #else\n    return false;\n   #endif\n}\n\ndouble GainPluginAudioProcessor::getTailLengthSeconds() const\n{\n    return 0.0;\n}\n\nint GainPluginAudioProcessor::getNumPrograms()\n{\n    return 1;   // NB: some hosts don't cope very well if you tell them there are 0 programs,\n                // so this should be at least 1, even if you're not really implementing programs.\n}\n\nint GainPluginAudioProcessor::getCurrentProgram()\n{\n    return 0;\n}\n\nvoid GainPluginAudioProcessor::setCurrentProgram (int /* index */) {}\nconst String GainPluginAudioProcessor::getProgramName (int /* index */) { return {}; }\nvoid GainPluginAudioProcessor::changeProgramName (int /* index */, const String& /* newName */) {}\n\n//==============================================================================\nvoid GainPluginAudioProcessor::prepareToPlay (double sampleRate, int /* samplesPerBlock */)\n{\n    gain.reset(sampleRate, 0.02);\n}\n\nvoid GainPluginAudioProcessor::releaseResources()\n{\n    // When playback stops, you can use this as an opportunity to free up any\n    // spare memory, etc.\n}\n\n#ifndef JucePlugin_PreferredChannelConfigurations\nbool GainPluginAudioProcessor::isBusesLayoutSupported (const BusesLayout& layouts) const\n{\n  #if JucePlugin_IsMidiEffect\n    ignoreUnused (layouts);\n    return true;\n  #else\n    // This is the place where you check if the layout is supported.\n    // In this template code we only support mono or stereo.\n    if (layouts.getMainOutputChannelSet() != AudioChannelSet::mono()\n     && layouts.getMainOutputChannelSet() != AudioChannelSet::stereo())\n        return false;\n\n    // This checks if the input layout matches the output layout\n   #if ! JucePlugin_IsSynth\n    if (layouts.getMainOutputChannelSet() != layouts.getMainInputChannelSet())\n        return false;\n   #endif\n\n    return true;\n  #endif\n}\n#endif\n\nvoid GainPluginAudioProcessor::processBlock (AudioBuffer<float>& buffer, MidiBuffer& /* midiMessages */)\n{\n    ScopedNoDenormals noDenormals;\n    auto totalNumInputChannels  = getTotalNumInputChannels();\n    auto totalNumOutputChannels = getTotalNumOutputChannels();\n\n    // In case we have more outputs than inputs, this code clears any output\n    // channels that didn't contain input data, (because these aren't\n    // guaranteed to be empty - they may contain garbage).\n    // This is here to avoid people getting screaming feedback\n    // when they first compile a plugin, but obviously you don't need to keep\n    // this code if your algorithm always overwrites all the output channels.\n    for (auto i = totalNumInputChannels; i < totalNumOutputChannels; ++i)\n        buffer.clear (i, 0, buffer.getNumSamples());\n\n    // Our intense dsp processing\n    gain.setTargetValue(*params.getRawParameterValue(\"MainGain\"));\n    gain.applyGain(buffer, buffer.getNumSamples());\n\n    if (auto *muteParam  = dynamic_cast<AudioParameterBool*>(params.getParameter(\"MainMute\")))\n    {\n        bool muted = muteParam->get();\n        if (muted)\n            buffer.applyGain(0.0f);\n    }\n\n    // Read current block gain peak value\n    gainPeakValue = buffer.getMagnitude (0, buffer.getNumSamples());\n}\n\n//==============================================================================\nbool GainPluginAudioProcessor::hasEditor() const\n{\n    return true; // (change this to false if you choose to not supply an editor)\n}\n\nAudioProcessorEditor* GainPluginAudioProcessor::createEditor()\n{\n    // The GainPlugin example uses the GenericEditor, which is a default\n    // AudioProcessorEditor provided that will automatically bootstrap\n    // your React root, install some native method hooks for parameter interaction\n    // if you provide an AudioProcessorValueTreeState, and manage hot reloading\n    // of the source bundle. You can always start with the GenericEditor\n    // then switch to a custom editor when you need more explicit control.\n    File sourceDir = File(GAINPLUGIN_SOURCE_DIR);\n    File bundle = sourceDir.getChildFile(\"jsui/build/js/main.js\");\n\n    auto* editor = new reactjuce::GenericEditor(*this, bundle);\n\n    editor->setResizable(true, true);\n    editor->setResizeLimits(400, 240, 400 * 2, 240 * 2);\n    editor->getConstrainer()->setFixedAspectRatio(400.0 / 240.0);\n    editor->setSize (400, 240);\n\n    // Start timer to dispatch gainPeakValues event to update Meter values\n    startTimer(100);\n\n    return editor;\n}\n\nvoid GainPluginAudioProcessor::timerCallback()\n{\n    if (auto* editor = dynamic_cast<reactjuce::GenericEditor*>(getActiveEditor()))\n    {\n        // Dispatch gainPeakValues event used by Meter React component\n        editor->getReactAppRoot().dispatchEvent(\n            \"gainPeakValues\",\n            static_cast<float>(gainPeakValue),\n            static_cast<float>(gainPeakValue)\n        );\n    }\n}\n\n//==============================================================================\nvoid GainPluginAudioProcessor::getStateInformation (MemoryBlock& /* destData */)\n{\n    // You should use this method to store your parameters in the memory block.\n    // You could do that either as raw data, or use the XML or ValueTree classes\n    // as intermediaries to make it easy to save and load complex data.\n}\n\nvoid GainPluginAudioProcessor::setStateInformation (const void* /* data */, int /* sizeInBytes */)\n{\n    // You should use this method to restore your parameters from this memory block,\n    // whose contents will have been created by the getStateInformation() call.\n}\n\n//==============================================================================\n// This creates new instances of the plugin..\nAudioProcessor* JUCE_CALLTYPE createPluginFilter()\n{\n    return new GainPluginAudioProcessor();\n}\n"
  },
  {
    "path": "examples/GainPlugin/PluginProcessor.h",
    "content": "/*\r\n  ==============================================================================\r\n\r\n    This file was auto-generated!\r\n\r\n    It contains the basic framework code for a JUCE plugin processor.\r\n\r\n  ==============================================================================\r\n*/\r\n\r\n#pragma once\r\n\r\n#include \"../JuceLibraryCode/JuceHeader.h\"\r\n\r\n//==============================================================================\r\n/**\r\n*/\r\nclass GainPluginAudioProcessor  : public AudioProcessor, private Timer\r\n{\r\npublic:\r\n    //==============================================================================\r\n    GainPluginAudioProcessor();\r\n    ~GainPluginAudioProcessor() override;\r\n\r\n    //==============================================================================\r\n    void prepareToPlay (double sampleRate, int samplesPerBlock) override;\r\n    void releaseResources() override;\r\n\r\n   #ifndef JucePlugin_PreferredChannelConfigurations\r\n    bool isBusesLayoutSupported (const BusesLayout& layouts) const override;\r\n   #endif\r\n\r\n    void processBlock (AudioBuffer<float>&, MidiBuffer&) override;\r\n\r\n    //==============================================================================\r\n    AudioProcessorEditor* createEditor() override;\r\n    bool hasEditor() const override;\r\n\r\n    //==============================================================================\r\n    const String getName() const override;\r\n\r\n    bool acceptsMidi() const override;\r\n    bool producesMidi() const override;\r\n    bool isMidiEffect() const override;\r\n    double getTailLengthSeconds() const override;\r\n\r\n    //==============================================================================\r\n    int getNumPrograms() override;\r\n    int getCurrentProgram() override;\r\n    void setCurrentProgram (int index) override;\r\n    const String getProgramName (int index) override;\r\n    void changeProgramName (int index, const String& newName) override;\r\n\r\n    //==============================================================================\r\n    void getStateInformation (MemoryBlock& destData) override;\r\n    void setStateInformation (const void* data, int sizeInBytes) override;\r\n\r\n    //==============================================================================\r\n    AudioProcessorValueTreeState& getValueTreeState() { return params; }\r\n    \r\n    void timerCallback() override;\r\n\r\nprivate:\r\n    //==============================================================================\r\n    AudioProcessorValueTreeState params;\r\n    LinearSmoothedValue<float> gain;\r\n    std::atomic<float> gainPeakValue;\r\n\r\n    //==============================================================================\r\n    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GainPluginAudioProcessor)\r\n};\r\n"
  },
  {
    "path": "examples/GainPlugin/jsui/.gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# production\n/build\n\n# misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n"
  },
  {
    "path": "examples/GainPlugin/jsui/babel.config.js",
    "content": "module.exports = {\n  presets: [\n    [\n      \"@babel/preset-env\",\n      {\n        modules: \"umd\",\n      },\n    ],\n    \"@babel/preset-react\",\n  ],\n  plugins: [\n    \"@babel/plugin-proposal-class-properties\",\n    [\n      \"@babel/plugin-transform-runtime\",\n      {\n        absoluteRuntime: false,\n        corejs: 3,\n        version: \"7.11.2\",\n      },\n    ],\n  ],\n};\n"
  },
  {
    "path": "examples/GainPlugin/jsui/package.json",
    "content": "{\n  \"name\": \"ui\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"dependencies\": {\n    \"@babel/runtime-corejs3\": \"^7.11.2\",\n    \"file-loader\": \"6.1.0\",\n    \"react\": \"^16.13.1\",\n    \"react-juce\": \"^0.2.16\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.11.1\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.10.4\",\n    \"@babel/plugin-transform-runtime\": \"^7.11.0\",\n    \"@babel/preset-env\": \"^7.11.0\",\n    \"@babel/preset-react\": \"^7.10.4\",\n    \"babel-loader\": \"^8.0.4\",\n    \"svg-inline-loader\": \"^0.8.0\",\n    \"url-loader\": \"4.1.0\",\n    \"webpack\": \"^5.46.0\",\n    \"webpack-cli\": \"^4.7.2\"\n  },\n  \"scripts\": {\n    \"start\": \"webpack -w --mode=development\",\n    \"build\": \"webpack --mode=production\"\n  }\n}\n"
  },
  {
    "path": "examples/GainPlugin/jsui/src/AnimatedFlexBox.js",
    "content": "import React, { Component } from \"react\";\nimport { View, Text } from \"react-juce\";\n\nclass AnimatedFlexBoxExample extends Component {\n  render() {\n    return (\n      <View {...styles.container}>\n        <View {...styles.cell}>\n          <Text {...styles.text}>Look at me, cell #1!</Text>\n        </View>\n        <View {...styles.cell}>\n          <Text {...styles.text}>Look at me, cell #2!</Text>\n        </View>\n        <View {...styles.cell}>\n          <Text {...styles.text}>Look at me, cell #3!</Text>\n        </View>\n        <View {...styles.cell}>\n          <Text {...styles.text}>Look at me, cell #4!</Text>\n        </View>\n        <View {...styles.cell}>\n          <Text {...styles.text}>Look at me, cell #5!</Text>\n        </View>\n        <View {...styles.cell}>\n          <Text {...styles.text}>Look at me, cell #6!</Text>\n        </View>\n        <View {...styles.cell}>\n          <Text {...styles.text}>Look at me, cell #7!</Text>\n        </View>\n        <View {...styles.cell}>\n          <Text {...styles.text}>Look at me, cell #8!</Text>\n        </View>\n      </View>\n    );\n  }\n}\n\nconst styles = {\n  container: {\n    width: \"100%\",\n    height: \"100%\",\n    backgroundColor: \"#17191f\",\n    justifyContent: \"flex-start\",\n    alignContent: \"flex-start\",\n    flexWrap: \"wrap\",\n    layoutAnimated: {\n      duration: 200.0,\n      frameRate: 45,\n      easing: View.EasingFunctions.quadraticInOut,\n    },\n  },\n  cell: {\n    flex: 0.0,\n    width: 100.0,\n    height: 100.0,\n    justifyContent: \"space-around\",\n    alignItems: \"center\",\n    backgroundColor: \"#87898f\",\n    margin: 6.0,\n    padding: 6.0,\n  },\n  text: {\n    fontSize: 16.0,\n    lineSpacing: 1.6,\n    justification: Text.JustificationFlags.centred,\n  },\n};\n\nexport default AnimatedFlexBoxExample;\n"
  },
  {
    "path": "examples/GainPlugin/jsui/src/App.js",
    "content": "// import AnimatedFlexBoxExample from \"./AnimatedFlexBox\";\nimport Meter from \"./Meter\";\nimport Knob from \"./Knob\";\nimport ParameterToggleButton from \"./ParameterToggleButton\";\nimport React, { Component } from \"react\";\nimport { Canvas, Image, Text, View } from \"react-juce\";\n\nfunction animatedDraw(ctx) {\n  let now = Date.now() / 10;\n  let width = now % 100;\n  let red = Math.sqrt(width / 100) * 255;\n  let hex = Math.floor(red).toString(16);\n\n  ctx.fillStyle = `#${hex}ffaa`;\n  ctx.fillRect(0, 0, width, 2);\n}\n\n// Example of callback for image onLoad/onError\nfunction imageLoaded() {\n  console.log(\"Image is loaded!\");\n}\n\nfunction imageError(error) {\n  console.log(error.name);\n  console.log(error.message);\n}\n\nclass App extends Component {\n  constructor(props) {\n    super(props);\n    this._onMuteToggled = this._onMuteToggled.bind(this);\n\n    this.state = {\n      muted: false,\n    };\n  }\n\n  _onMuteToggled(toggled) {\n    this.setState({\n      muted: toggled,\n    });\n  }\n\n  render() {\n    // Uncomment here to watch the animated flex box example in action\n    // return (\n    //   <View {...styles.container}>\n    //     <AnimatedFlexBoxExample />\n    //   </View>\n    // );\n\n    const muteBackgroundColor = this.state.muted\n      ? \"#66FDCF\"\n      : \"hsla(162, 97%, 70%, 0)\";\n    const muteTextColor = this.state.muted\n      ? \"#17191f\"\n      : \"hsla(162, 97%, 70%, 1)\";\n\n    const logo_url =\n      \"https://raw.githubusercontent.com/nick-thompson/react-juce/master/examples/GainPlugin/jsui/src/logo.png\";\n    //const logo_png = require('./logo.png');\n    //const logo_svg = require('./logo.svg');\n\n    return (\n      <View {...styles.container}>\n        <View {...styles.content}>\n          <Image\n            source={logo_url}\n            onLoad={imageLoaded}\n            onError={imageError}\n            {...styles.logo}\n          />\n          <Knob paramId=\"MainGain\" />\n          <Meter {...styles.meter} />\n          <Canvas {...styles.canvas} animate={true} onDraw={animatedDraw} />\n          <ParameterToggleButton\n            paramId=\"MainMute\"\n            onToggled={this._onMuteToggled}\n            background-color={muteBackgroundColor}\n            {...styles.mute_button}\n          >\n            <Text color={muteTextColor} {...styles.mute_button_text}>\n              MUTE\n            </Text>\n          </ParameterToggleButton>\n        </View>\n      </View>\n    );\n  }\n}\n\nconst styles = {\n  container: {\n    width: \"100%\",\n    height: \"100%\",\n    backgroundColor:\n      \"linear-gradient(45deg, hsla(225, 15%, 11%, 0.3), #17191f 50%)\",\n    justifyContent: \"center\",\n    alignItems: \"center\",\n  },\n  content: {\n    flex: 1.0,\n    flexDirection: \"column\",\n    justifyContent: \"space-around\",\n    alignItems: \"center\",\n    padding: 24.0,\n    maxWidth: 600,\n    aspectRatio: 400.0 / 240.0,\n  },\n  logo: {\n    flex: 0.0,\n    width: \"80%\",\n    aspectRatio: 281.6 / 35.0,\n    placement: Image.PlacementFlags.centred,\n  },\n  meter: {\n    flex: 0.0,\n    width: 100.0,\n    height: 16.0,\n  },\n  canvas: {\n    flex: 0.0,\n    width: 100.0,\n    height: 2,\n    marginTop: 10,\n  },\n  mute_button: {\n    justifyContent: \"center\",\n    alignItems: \"center\",\n    borderRadius: 5.0,\n    borderWidth: 2.0,\n    borderColor: \"rgba(102, 253, 207, 1)\",\n    marginTop: 10,\n    minWidth: 30.0,\n    minHeight: 30.0,\n    width: \"20%\",\n    height: \"17.5%\",\n  },\n  mute_button_text: {\n    fontSize: 20.0,\n    lineSpacing: 1.6,\n    fontStyle: Text.FontStyleFlags.bold,\n  },\n};\n\nexport default App;\n"
  },
  {
    "path": "examples/GainPlugin/jsui/src/Knob.js",
    "content": "import React from \"react\";\nimport ParameterSlider from \"./ParameterSlider\";\nimport { Slider } from \"react-juce\";\nimport Label from \"./Label\";\nimport { useParameter } from \"./ParameterValueContext\";\nimport { View } from \"react-juce\";\n\nconst sliderFillColor = \"#66FDCF\";\nconst sliderTrackColor = \"#626262\";\nconst drawRotary = Slider.drawRotary(sliderTrackColor, sliderFillColor);\n\nconst Knob = ({ paramId }) => {\n  const { stringValue, currentValue } = useParameter(paramId);\n  return (\n    <View {...styles.container}>\n      <ParameterSlider\n        paramId={paramId}\n        value={currentValue}\n        onDraw={drawRotary}\n        mapDragGestureToValue={Slider.rotaryGestureMap}\n        {...styles.slider}\n      />\n      <Label value={stringValue} {...styles.label} />\n    </View>\n  );\n};\n\nconst styles = {\n  container: {\n    minWidth: 100.0,\n    minHeight: 100.0,\n    width: \"55%\",\n    height: \"55%\",\n    marginTop: 15,\n    marginBottom: 15,\n    justifyContent: \"center\",\n    alignItems: \"center\",\n  },\n  slider: {\n    width: \"100%\",\n    height: \"100%\",\n  },\n  label: {\n    width: \"100%\",\n    height: \"100%\",\n    flex: 1.0,\n    justifyContent: \"center\",\n    alignItems: \"center\",\n    interceptClickEvents: false,\n    position: \"absolute\",\n  },\n};\nexport default Knob;\n"
  },
  {
    "path": "examples/GainPlugin/jsui/src/Label.js",
    "content": "import React, { memo } from \"react\";\nimport { Text, View } from \"react-juce\";\n\nconst Label = ({ value, ...props }) => {\n  return (\n    <View {...props}>\n      <Text {...styles.labelText}>{value}</Text>\n    </View>\n  );\n};\n\nconst styles = {\n  labelText: {\n    color: \"#626262\",\n    fontSize: 16.0,\n    lineSpacing: 1.6,\n  },\n};\n\nexport default memo(Label);\n"
  },
  {
    "path": "examples/GainPlugin/jsui/src/Meter.js",
    "content": "import React, { Component } from \"react\";\nimport { EventBridge, Image, Text, View } from \"react-juce\";\n\nclass Meter extends Component {\n  constructor(props) {\n    super(props);\n\n    this._onMeasure = this._onMeasure.bind(this);\n    this._onMeterValues = this._onMeterValues.bind(this);\n\n    this.state = {\n      width: 0,\n      height: 0,\n      lcPeak: 0.0,\n      rcPeak: 0.0,\n    };\n  }\n\n  componentDidMount() {\n    EventBridge.addListener(\"gainPeakValues\", this._onMeterValues);\n  }\n\n  componentWillUnmount() {\n    EventBridge.removeListener(\"gainPeakValues\", this._onMeterValues);\n  }\n\n  _onMeterValues(lcPeak, rcPeak) {\n    this.setState({\n      lcPeak,\n      rcPeak,\n    });\n  }\n\n  _onMeasure(e) {\n    this.setState({\n      width: e.width,\n      height: e.height,\n    });\n  }\n\n  _renderVectorGraphics(lcPeak, rcPeak, width, height) {\n    // Similar to the audio side of this, this is a pretty rudimentary\n    // way of drawing a gain meter; we'd get a much nicer response by using\n    // a peak envelope follower with instant attack and a smooth release for\n    // each channel, but this is just a demo plugin.\n    return `\n      <svg\n        width=\"${width}\"\n        height=\"${height}\"\n        viewBox=\"0 0 ${width} ${height}\"\n        version=\"1.1\"\n        xmlns=\"http://www.w3.org/2000/svg\">\n        <rect\n          x=\"${0}\" y=\"${0}\"\n          width=\"${width}\" height=\"${height * 0.45}\"\n          fill=\"#626262\" />\n        <rect\n          x=\"${0}\" y=\"${0}\"\n          width=\"${width * Math.min(1.0, lcPeak)}\" height=\"${height * 0.45}\"\n          fill=\"#66FDCF\" />\n        <rect\n          x=\"${0}\" y=\"${height * 0.5}\"\n          width=\"${width}\" height=\"${height * 0.45}\"\n          fill=\"#626262\" />\n        <rect\n          x=\"${0}\" y=\"${height * 0.5}\"\n          width=\"${width * Math.min(1.0, rcPeak)}\" height=\"${height * 0.45}\"\n          fill=\"#66FDCF\" />\n      </svg>\n    `;\n  }\n\n  render() {\n    const { lcPeak, rcPeak, width, height } = this.state;\n\n    return (\n      <View {...this.props} onMeasure={this._onMeasure}>\n        <Image\n          {...styles.canvas}\n          source={this._renderVectorGraphics(lcPeak, rcPeak, width, height)}\n        />\n      </View>\n    );\n  }\n}\n\nconst styles = {\n  canvas: {\n    flex: 1.0,\n    height: \"100%\",\n    width: \"100%\",\n    position: \"absolute\",\n    left: 0.0,\n    top: 0.0,\n    interceptClickEvents: false,\n  },\n};\n\nexport default Meter;\n"
  },
  {
    "path": "examples/GainPlugin/jsui/src/ParameterSlider.js",
    "content": "import React, { memo, useCallback } from \"react\";\nimport { Slider } from \"react-juce\";\nimport {\n  beginParameterChangeGesture,\n  endParameterChangeGesture,\n  setParameterValueNotifyingHost,\n} from \"./nativeMethods\";\n\nconst ParameterSlider = ({ value, paramId, children, ...props }) => {\n  const onMouseDown = (e) => {\n    beginParameterChangeGesture(paramId);\n  };\n\n  const onMouseUp = (e) => {\n    endParameterChangeGesture(paramId);\n  };\n\n  const onSliderValueChange = (value) => {\n    setParameterValueNotifyingHost(paramId, value);\n  };\n\n  return (\n    <Slider\n      {...props}\n      value={value}\n      onMouseDown={onMouseDown}\n      onMouseUp={onMouseUp}\n      onChange={onSliderValueChange}\n    >\n      {children}\n    </Slider>\n  );\n};\n\n// TODO: PropTypes Validation\n// paramId should be required and has type of string\n// https://www.npmjs.com/package/prop-types\n\nexport default memo(ParameterSlider);\n"
  },
  {
    "path": "examples/GainPlugin/jsui/src/ParameterToggleButton.js",
    "content": "import ParameterValueStore from \"./ParameterValueStore\";\nimport React, { Component } from \"react\";\nimport { Button } from \"react-juce\";\nimport {\n  beginParameterChangeGesture,\n  endParameterChangeGesture,\n  setParameterValueNotifyingHost,\n} from \"./nativeMethods\";\n\nclass ParameterToggleButton extends Component {\n  constructor(props) {\n    super(props);\n\n    this._handleClick = this._handleClick.bind(this);\n    this._handleEnter = this._handleEnter.bind(this);\n    this._handleLeave = this._handleLeave.bind(this);\n    this._onParameterValueChange = this._onParameterValueChange.bind(this);\n\n    const paramState = ParameterValueStore.getParameterState(\n      this.props.paramId\n    );\n\n    const initialDefaultValue =\n      typeof paramState.defaultValue === \"number\"\n        ? paramState.defaultValue\n        : 0.0;\n\n    const initialValue =\n      typeof paramState.currentValue === \"number\"\n        ? paramState.currentValue\n        : 0.0;\n\n    this.defaultBorderColor = \"#66FDCF\";\n    this.hoverBorderColor = \"#66CFFD\";\n\n    this.state = {\n      defaultValue: initialDefaultValue,\n      value: initialValue,\n      borderColor: this.defaultBorderColor,\n    };\n\n    if (typeof this.props.onToggled === \"function\") {\n      this.props.onToggled(initialValue !== 0.0);\n    }\n  }\n\n  componentDidMount() {\n    ParameterValueStore.addListener(\n      ParameterValueStore.CHANGE_EVENT,\n      this._onParameterValueChange\n    );\n  }\n\n  componentWillUnmount() {\n    ParameterValueStore.removeListener(\n      ParameterValueStore.CHANGE_EVENT,\n      this._onParameterValueChange\n    );\n  }\n\n  _handleClick(e) {\n    const newValue = this.state.value === 0.0 ? 1.0 : 0.0;\n\n    this.setState({\n      value: newValue,\n    });\n\n    if (\n      typeof this.props.paramId === \"string\" &&\n      this.props.paramId.length > 0\n    ) {\n      setParameterValueNotifyingHost(this.props.paramId, newValue);\n    }\n\n    if (typeof this.props.onToggled === \"function\") {\n      this.props.onToggled(newValue !== 0.0);\n    }\n  }\n\n  _handleEnter(e) {\n    beginParameterChangeGesture(this.props.paramId);\n    this.setState({\n      borderColor: this.hoverBorderColor,\n    });\n  }\n\n  _handleLeave(e) {\n    endParameterChangeGesture(this.props.paramId);\n    this.setState({\n      borderColor: this.defaultBorderColor,\n    });\n  }\n\n  _onParameterValueChange(paramId) {\n    const shouldUpdate =\n      typeof this.props.paramId === \"string\" &&\n      this.props.paramId.length > 0 &&\n      this.props.paramId === paramId;\n\n    if (shouldUpdate) {\n      const state = ParameterValueStore.getParameterState(paramId);\n\n      const newDefaultValue = state.defaultValue;\n      const newValue = state.currentValue;\n\n      this.setState({\n        defaultValue: newDefaultValue,\n        value: newValue,\n      });\n\n      if (typeof this.props.onToggled === \"function\") {\n        this.props.onToggled(newValue !== 0.0);\n      }\n    }\n  }\n\n  render() {\n    const { parameterId, onToggled, ...other } = this.props;\n\n    return (\n      <Button\n        {...other}\n        borderColor={this.state.borderColor}\n        onClick={this._handleClick}\n        onMouseEnter={this._handleEnter}\n        onMouseLeave={this._handleLeave}\n      >\n        {this.props.children}\n      </Button>\n    );\n  }\n}\n\nexport default ParameterToggleButton;\n"
  },
  {
    "path": "examples/GainPlugin/jsui/src/ParameterValueContext.js",
    "content": "import React, {\n  createContext,\n  useContext,\n  useState,\n  useCallback,\n  useEffect,\n} from \"react\";\nimport { EventBridge } from \"react-juce\";\n\nexport const ParamIds = {\n  MainGain: \"MainGain\",\n  MainMute: \"MainMute\",\n};\n\nconst defaultValues = {\n  MainGain: {\n    defaultValue: 0.0,\n    currentValue: 0.0,\n    stringValue: \"loading\",\n  },\n  MainMute: {\n    defaultValue: false,\n    currentValue: false,\n    stringValue: \"loading\",\n  },\n};\n\nexport const ParameterValueContext = createContext(defaultValues);\n\nexport const useParameter = (paramId) => {\n  return useContext(ParameterValueContext)[paramId];\n};\n\nexport const ParameterValueProvider = ({ children }) => {\n  const [params, setParams] = useState(defaultValues);\n  const onParameterValueChange = useCallback(\n    (index, changedParamId, defaultValue, currentValue, stringValue) => {\n      if (!ParamIds[changedParamId]) return;\n      setParams((prevParams) => ({\n        ...prevParams,\n        [changedParamId]: {\n          index,\n          defaultValue,\n          currentValue,\n          stringValue,\n        },\n      }));\n    },\n    []\n  );\n  useEffect(() => {\n    EventBridge.addListener(\"parameterValueChange\", onParameterValueChange);\n    return () => {\n      EventBridge.removeListener(\n        \"parameterValueChange\",\n        onParameterValueChange\n      );\n    };\n  }, [onParameterValueChange]);\n\n  return (\n    <ParameterValueContext.Provider value={params}>\n      {children}\n    </ParameterValueContext.Provider>\n  );\n};\n"
  },
  {
    "path": "examples/GainPlugin/jsui/src/ParameterValueStore.js",
    "content": "import EventEmitter from \"events\";\nimport { EventBridge } from \"react-juce\";\n\n/** This is more or less a proxy to the EventBridge's parameter events that\n *  caches last known values and provides components a way to access the\n *  cache.\n */\nclass ParameterValueStore extends EventEmitter {\n  constructor() {\n    super();\n\n    this.CHANGE_EVENT = \"change\";\n\n    this.setMaxListeners(100);\n    this._onParameterValueChange = this._onParameterValueChange.bind(this);\n\n    EventBridge.addListener(\n      \"parameterValueChange\",\n      this._onParameterValueChange\n    );\n\n    this.state = {};\n  }\n\n  getParameterState(paramId) {\n    if (!this.state.hasOwnProperty(paramId)) {\n      return {};\n    }\n\n    return this.state[paramId];\n  }\n\n  _onParameterValueChange(\n    index,\n    paramId,\n    defaultValue,\n    currentValue,\n    stringValue\n  ) {\n    this.state[paramId] = {\n      parameterIndex: index,\n      parameterId: paramId,\n      defaultValue: defaultValue,\n      currentValue: currentValue,\n      stringValue: stringValue,\n    };\n\n    this.emit(this.CHANGE_EVENT, paramId);\n  }\n}\n\nconst __singletonInstance = new ParameterValueStore();\n\nexport default __singletonInstance;\n"
  },
  {
    "path": "examples/GainPlugin/jsui/src/index.js",
    "content": "import React from \"react\";\nimport ReactJUCE from \"react-juce\";\nimport App from \"./App\";\nimport { ParameterValueProvider } from \"./ParameterValueContext\";\n\nReactJUCE.render(\n  <ParameterValueProvider>\n    <App />\n  </ParameterValueProvider>,\n  ReactJUCE.getRootContainer()\n);\n"
  },
  {
    "path": "examples/GainPlugin/jsui/src/nativeMethods.js",
    "content": "export const beginParameterChangeGesture = (paramId) =>\n  global.beginParameterChangeGesture(paramId);\n\nexport const endParameterChangeGesture = (paramId) =>\n  global.endParameterChangeGesture(paramId);\n\nexport const setParameterValueNotifyingHost = (paramId, value) =>\n  global.setParameterValueNotifyingHost(paramId, value);\n"
  },
  {
    "path": "examples/GainPlugin/jsui/webpack.config.js",
    "content": "const webpack = require(\"webpack\");\n\nmodule.exports = {\n  entry: \"./src/index.js\",\n  output: {\n    path: __dirname + \"/build/js\",\n    filename: \"main.js\",\n    sourceMapFilename: \"[file].map\",\n    devtoolModuleFilenameTemplate: (info) =>\n      `webpack:///${info.absoluteResourcePath.replace(/\\\\/g, \"/\")}`,\n  },\n  // Required for duktape to ensure webpack chunk do not contain arrow functions\n  target: [\"web\", \"es5\"],\n  devtool: \"source-map\",\n  module: {\n    rules: [\n      {\n        test: /\\.(js|jsx)$/,\n        exclude: /node_modules/,\n        use: [\"babel-loader\"],\n      },\n      {\n        test: /\\.svg$/,\n        exclude: /node_modules/,\n        use: [\"svg-inline-loader\"],\n      },\n      {\n        test: /\\.(png|jpeg|jpg|gif)$/,\n        use: [\n          {\n            loader: \"url-loader\",\n            options: {\n              limit: true,\n              esModule: false,\n            },\n          },\n        ],\n      },\n    ],\n  },\n  plugins: [\n    new webpack.DefinePlugin({\n      \"process.env.NODE_DEBUG\": JSON.stringify(process.env.NODE_DEBUG),\n    }),\n  ],\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"blueprint\",\n  \"version\": \"0.1.0\",\n  \"description\": \"Write cross-platform native apps with React and JUCE\",\n  \"directories\": {\n    \"example\": \"examples\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/nick-thompson/react-juce.git\"\n  },\n  \"devDependencies\": {\n    \"husky\": \"^4.3.8\",\n    \"lint-staged\": \"^10.5.3\",\n    \"prettier\": \"2.2.1\"\n  },\n  \"scripts\": {\n    \"beautify\": \"prettier --write .\",\n    \"lint\": \"prettier --check .\"\n  },\n  \"husky\": {\n    \"hooks\": {\n      \"pre-commit\": \"lint-staged\"\n    }\n  },\n  \"lint-staged\": {\n    \"*.{ts,tsx,js,jsx,css,md,yml,yaml}\": \"prettier --write\"\n  }\n}\n"
  },
  {
    "path": "packages/react-juce/.gitignore",
    "content": "dist\n"
  },
  {
    "path": "packages/react-juce/babel.config.js",
    "content": "module.exports = {\n  presets: [\n    \"@babel/preset-env\",\n    \"@babel/preset-react\",\n    \"@babel/preset-typescript\",\n  ],\n  plugins: [\n    \"@babel/plugin-proposal-class-properties\",\n    \"@babel/plugin-proposal-object-rest-spread\",\n    [\n      \"@babel/plugin-transform-runtime\",\n      {\n        absoluteRuntime: false,\n        corejs: 3,\n        version: \"^7.11.2\",\n      },\n    ],\n  ],\n};\n"
  },
  {
    "path": "packages/react-juce/package.json",
    "content": "{\n  \"name\": \"react-juce\",\n  \"version\": \"0.2.16\",\n  \"description\": \"Write cross-platform native apps with React.js and JUCE.\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/nick-thompson/react-juce.git\"\n  },\n  \"main\": \"dist/index.js\",\n  \"types\": \"dist/index.d.ts\",\n  \"files\": [\n    \"dist/index.js\",\n    \"dist/index.d.ts\",\n    \"dist/lib\",\n    \"dist/components\",\n    \"dist/src\"\n  ],\n  \"author\": \"Nick Thompson\",\n  \"devDependencies\": {\n    \"@babel/cli\": \"^7.10.0\",\n    \"@babel/core\": \"^7.11.1\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.11.0\",\n    \"@babel/plugin-transform-runtime\": \"^7.11.0\",\n    \"@babel/preset-env\": \"^7.11.0\",\n    \"@babel/preset-react\": \"^7.10.4\",\n    \"@babel/preset-typescript\": \"^7.10.4\",\n    \"@types/core-js\": \"^2.5.4\",\n    \"@types/invariant\": \"^2.2.33\",\n    \"@types/node\": \"^14.6.4\",\n    \"@types/react\": \"^16.9.41\",\n    \"@types/react-reconciler\": \"^0.18.0\",\n    \"awesome-typescript-loader\": \"^5.2.1\",\n    \"chalk\": \"^2.4.2\",\n    \"fs-extra\": \"^8.1.0\",\n    \"typescript\": \"^3.9.6\",\n    \"webpack\": \"^5.46.0\",\n    \"webpack-cli\": \"^4.7.2\"\n  },\n  \"dependencies\": {\n    \"@babel/runtime-corejs3\": \"^7.11.2\",\n    \"camelcase\": \"^6.2.0\",\n    \"color-string\": \"^1.5.4\",\n    \"core-js\": \"2.6.0\",\n    \"invariant\": \"^2.2.4\",\n    \"known-css-properties\": \"^0.20.0\",\n    \"matrix-js\": \"^1.5.1\",\n    \"object-inspect\": \"^1.11.0\",\n    \"react-reconciler\": \"^0.25.1\"\n  },\n  \"peerDependencies\": {\n    \"react\": \"^16.13.1\"\n  },\n  \"scripts\": {\n    \"build\": \"webpack --mode=production\",\n    \"watch\": \"webpack --watch --mode=development\",\n    \"init\": \"node scripts/init.js\"\n  }\n}\n"
  },
  {
    "path": "packages/react-juce/scripts/init.js",
    "content": "#!/usr/bin/env node\n\nvar assert = require(\"assert\");\nvar chalk = require(\"chalk\");\nvar cp = require(\"child_process\");\nvar fs = require(\"fs-extra\");\nvar path = require(\"path\");\n\nvar args = process.argv.slice(2);\n\nassert(\n  typeof args[0] === \"string\" && args[0].length > 0,\n  \"Must provide a path to the directory in which to initialize the template.\"\n);\n\nvar targetDir = path.resolve(args[0]);\nvar packageDir = path.resolve(__dirname, \"..\");\nvar templateDir = path.resolve(packageDir, \"template\");\n\nconsole.log(\"Initializing a React-JUCE template in:\", chalk.green(targetDir));\nconsole.log(\"Directory tree will be created if it does not exist.\");\n\nfs.mkdirp(targetDir, function (err) {\n  if (err) {\n    console.error(chalk.red(err));\n    process.exit(1);\n  }\n\n  console.log(\"[*] Copying template files\");\n\n  fs.copy(templateDir, targetDir, function (err) {\n    if (err) {\n      console.error(chalk.red(err));\n      process.exit(1);\n    }\n\n    console.log(\"[*] Installing dependencies\");\n\n    cp.exec(\"npm install\", { cwd: targetDir }, function (err, stdout, stderr) {\n      if (err) {\n        console.error(chalk.red(err));\n        console.error(stderr);\n        process.exit(1);\n      }\n\n      console.log();\n      console.log(`\n${chalk.blue(\n  \"Success!\"\n)} Initialized a React-JUCE template in ${chalk.green(targetDir)}\n\nYou can now get started by typing:\n\n${chalk.blue(\"cd\")} ${args[0]}\n${chalk.blue(\"npm start\")}\n\nThen adding the reactjuce::ReactApplicationRoot component to your project.\n      `);\n    });\n  });\n});\n"
  },
  {
    "path": "packages/react-juce/src/components/Button.tsx",
    "content": "import React, { Component } from \"react\";\n\nimport { View } from \"./View\";\nimport { SyntheticMouseEvent } from \"../lib/SyntheticEvents\";\nimport { ViewInstance } from \"../lib/Backend\";\n\n//TODO: Once ViewProps work is complete we can probably\n//      remove this in favour of ViewProps.\nexport interface ButtonProps {\n  onClick: (e: SyntheticMouseEvent) => void;\n  onMouseDown?: (e: SyntheticMouseEvent) => void;\n  onMouseUp?: (e: SyntheticMouseEvent) => void;\n  onMouseEnter?: (e: SyntheticMouseEvent) => void;\n  onMouseLeave?: (e: SyntheticMouseEvent) => void;\n}\n\ntype ButtonState = {\n  down: boolean;\n};\n\n/**\n * A simple Button component which can be used as a building block\n * for more complex button types.\n *\n * @example\n *\n * <Button onClick={() => { console.log(\"clicked\"); }} {...styles.button}>\n *   <Text {...styles.text}>\n       Hello World\n *   </Text>\n * </Button>\n *\n * const styles = {\n *   text: {\n *     'font-size': 18.0,\n *     'line-spacing': 1.6,\n *     'color': 'ff626262'\n *   },\n *   button: {\n *     'justify-content': 'center',\n *     'align-items': 'center',\n *     'width': '100%',\n *     'height': '100%',\n *     'border-radius': 5.0,\n *     'border-width': 2.0,\n *     'border-color': 'ff626262'\n *   }\n * };\n *\n */\nexport class Button extends Component<ButtonProps, ButtonState> {\n  private _ref: React.RefObject<ViewInstance>;\n\n  constructor(props: ButtonProps) {\n    super(props);\n    this._ref = React.createRef();\n\n    this.state = {\n      down: false,\n    };\n  }\n\n  handleDown = (e: SyntheticMouseEvent): void => {\n    if (typeof this.props.onMouseDown === \"function\")\n      this.props.onMouseDown.call(null, e);\n\n    this.setState({\n      down: true,\n    });\n  };\n\n  handleUp = (e: SyntheticMouseEvent): void => {\n    if (typeof this.props.onMouseUp === \"function\")\n      this.props.onMouseUp.call(null, e);\n\n    this.setState({\n      down: false,\n    });\n\n    if (typeof this.props.onClick === \"function\") {\n      const instance = this._ref ? this._ref.current : null;\n\n      if (instance && instance.contains(e.relatedTarget)) {\n        this.props.onClick(e);\n      }\n    }\n  };\n\n  render = () => {\n    const { onMouseDown, onMouseUp, onClick, ...other } = this.props;\n    const opacity = this.state.down ? 0.8 : 1.0;\n\n    return (\n      <View\n        onMouseDown={this.handleDown}\n        onMouseUp={this.handleUp}\n        opacity={opacity}\n        viewRef={this._ref}\n        {...other}\n      >\n        {this.props.children}\n      </View>\n    );\n  };\n}\n"
  },
  {
    "path": "packages/react-juce/src/components/Canvas.ts",
    "content": "import React, { Component } from \"react\";\nimport Colors from \"../lib/MacroProperties/Colors\";\n\n// TODO: Need to explicitly bind this to members?\nexport class CanvasRenderingContext {\n  private _drawCommands: any[];\n\n  constructor() {\n    this._drawCommands = [];\n  }\n\n  reset() {\n    this._drawCommands = [];\n  }\n\n  getDrawCommands(): any[] {\n    return this._drawCommands;\n  }\n\n  //================================================================================\n  // Properties\n  // TODO: Support fillStyle/strokeStyle pattern.\n  // TODO: Support fillStyle/strokeStyle gradient.\n  set fillStyle(value: string) {\n    value = Colors.colorStringToAlphaHex(value);\n    this._drawCommands.push([\"setFillStyle\", value]);\n  }\n\n  set strokeStyle(value: string) {\n    value = Colors.colorStringToAlphaHex(value);\n    this._drawCommands.push([\"setStrokeStyle\", value]);\n  }\n\n  set lineWidth(value: number) {\n    this._drawCommands.push([\"setLineWidth\", value]);\n  }\n\n  set font(value: string) {\n    this._drawCommands.push([\"setFont\", value]);\n  }\n\n  set textAlign(value: string) {\n    this._drawCommands.push([\"setTextAlign\", value]);\n  }\n\n  //================================================================================\n  // Rect functions\n  fillRect(x: number, y: number, width: number, height: number): void {\n    this._drawCommands.push([\"fillRect\", x, y, width, height]);\n  }\n\n  strokeRect(x: number, y: number, width: number, height: number): void {\n    this._drawCommands.push([\"strokeRect\", x, y, width, height]);\n  }\n\n  strokeRoundedRect(\n    x: number,\n    y: number,\n    width: number,\n    height: number,\n    cornerSize: number\n  ): void {\n    this._drawCommands.push([\n      \"strokeRoundedRect\",\n      x,\n      y,\n      width,\n      height,\n      cornerSize,\n    ]);\n  }\n\n  fillRoundedRect(\n    x: number,\n    y: number,\n    width: number,\n    height: number,\n    cornerSize: number\n  ): void {\n    this._drawCommands.push([\n      \"fillRoundedRect\",\n      x,\n      y,\n      width,\n      height,\n      cornerSize,\n    ]);\n  }\n\n  clearRect(x: number, y: number, width: number, height: number): void {\n    this._drawCommands.push([\"clearRect\", x, y, width, height]);\n  }\n\n  //================================================================================\n  // Path functions\n  //\n  // TODO: Should we split things out into CanvasRenderingContextPath\n  //       so things like close()/stroke() are more obvious when looking at API.\n  //       If you look at the ts type definitions for CanvasRenderingContext2D\n  //       CanvasRenderingContext2D is composed of other objects like CanvasRenderingContextPath\n  //       which contains all path methods. What is the best way to do this in JS and share\n  //       a drawCommands instance?\n  beginPath(): void {\n    this._drawCommands.push([\"beginPath\"]);\n  }\n\n  lineTo(x: number, y: number): void {\n    this._drawCommands.push([\"lineTo\", x, y]);\n  }\n\n  moveTo(x: number, y: number): void {\n    this._drawCommands.push([\"moveTo\", x, y]);\n  }\n\n  arc(\n    x: number,\n    y: number,\n    radius: number,\n    startAngle: number,\n    endAngle: number\n  ): void {\n    //TODO: Add support for optional antiClockWise?: boolean arg\n    this._drawCommands.push([\"arc\", x, y, radius, startAngle, endAngle]);\n  }\n\n  quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): void {\n    this._drawCommands.push([\"quadraticCurveTo\", cpx, cpy, x, y]);\n  }\n\n  closePath(): void {\n    this._drawCommands.push([\"close\"]);\n  }\n\n  stroke(): void {\n    this._drawCommands.push([\"stroke\"]);\n  }\n\n  fill(): void {\n    this._drawCommands.push([\"fill\"]);\n  }\n\n  //================================================================================\n  // Transform functions\n  rotate(angle: number): void {\n    this._drawCommands.push([\"rotate\", angle]);\n  }\n\n  translate(x: number, y: number): void {\n    this._drawCommands.push([\"translate\", x, y]);\n  }\n\n  setTransform(\n    a: number,\n    b: number,\n    c: number,\n    d: number,\n    e: number,\n    f: number\n  ): void {\n    this._drawCommands.push([\"setTransform\", a, b, c, d, e, f]);\n  }\n\n  resetTransform(): void {\n    this._drawCommands.push([\"resetTransform\"]);\n  }\n\n  //================================================================================\n  // Image functions\n  //\n  //TODO: Add support for other drawImage overloads.\n  //      Currently only support SVG string. What is correct\n  //      type to use here?\n  drawImage(image: string, dx: number, dy: number): void {\n    this._drawCommands.push([\"drawImage\", image, dx, dy]);\n  }\n\n  //================================================================================\n  // Text functions\n  strokeText(text: string, x: number, y: number, maxWidth?: number): void {\n    if (maxWidth === undefined)\n      this._drawCommands.push([\"strokeText\", text, x, y]);\n    else this._drawCommands.push([\"strokeText\", text, x, y, maxWidth]);\n  }\n\n  fillText(text: string, x: number, y: number, maxWidth?: number): void {\n    if (maxWidth === undefined)\n      this._drawCommands.push([\"fillText\", text, x, y]);\n    else this._drawCommands.push([\"fillText\", text, x, y, maxWidth]);\n  }\n\n  //================================================================================\n}\n\nexport interface CanvasProps {\n  onDraw: (ctx: CanvasRenderingContext) => void;\n  onMeasure?: (e: any) => void;\n  stateful?: boolean;\n}\n\ninterface CanvasState {\n  width: number;\n  height: number;\n}\n\nexport class Canvas extends Component<CanvasProps, CanvasState> {\n  private _ctx: CanvasRenderingContext;\n\n  constructor(props: CanvasProps) {\n    super(props);\n\n    this._ctx = new CanvasRenderingContext();\n    this._onMeasure = this._onMeasure.bind(this);\n    this._onDraw = this._onDraw.bind(this);\n\n    this.state = {\n      width: 0,\n      height: 0,\n    };\n  }\n\n  _onMeasure(e: any) {\n    this.setState({\n      width: e.width,\n      height: e.height,\n    });\n\n    if (typeof this.props.onMeasure === \"function\") {\n      this.props.onMeasure(e);\n    }\n  }\n\n  _onDraw(): any[] {\n    if (typeof this.props.onDraw === \"function\") {\n      this._ctx.reset();\n\n      this.props.onDraw(this._ctx);\n      return this._ctx.getDrawCommands();\n    }\n\n    return [];\n  }\n\n  render() {\n    return React.createElement(\n      \"CanvasView\",\n      Object.assign({}, this.props, {\n        onDraw: () => {\n          return this._onDraw();\n        },\n        onMeasure: (e: any) => {\n          this._onMeasure(e);\n        },\n      }),\n      this.props.children\n    );\n  }\n}\n"
  },
  {
    "path": "packages/react-juce/src/components/Image.ts",
    "content": "import React from \"react\";\n\nexport function Image(props: any) {\n  return React.createElement(\"Image\", props, props.children);\n}\n\nImage.PlacementFlags = {\n  xLeft: 1,\n  xRight: 2,\n  xMid: 4,\n  yTop: 8,\n  yBottom: 16,\n  yMid: 32,\n  stretchToFit: 64,\n  fillDestination: 128,\n  onlyReduceInSize: 256,\n  onlyIncreaseInSize: 512,\n  doNotResize: 256 | 512,\n  centred: 4 + 32,\n};\n"
  },
  {
    "path": "packages/react-juce/src/components/ListView.tsx",
    "content": "import React, { Component, PropsWithChildren, ReactElement } from \"react\";\n\nimport { ViewInstance } from \"../lib/Backend\";\nimport { ScrollView, ScrollEvent } from \"./ScrollView\";\n\nimport invariant from \"invariant\";\n\ntype ListViewState = {\n  scrollTopPosition: number;\n  width: number;\n  height: number;\n};\n\ntype VirtualPositions = {\n  innerHeight: number;\n  startIndex: number;\n  endIndex: number;\n};\n\n/**\n * ScrollParams is passed to ListView's scrollToIndex\n * function.\n *\n * @property index - The index of the item in the ListView's data\n *                   source to scroll to.\n *\n * @property offset - A normalised value between 0.0 and 1.0 which\n *                    will offset the position of the ListView item\n *                    (specified by index) from the top of the ListView.\n *                    i.e. offset == 0.5 positions the item at index in\n *                    the center of the ListView.\n */\nexport interface ScrollParams {\n  index: number;\n  offset: number;\n}\n\n/**\n * Prop type for ListView.\n *\n * @property data       - Array of objects to use when populating ListView items\n *                        via the renderItem callback.\n *\n * @property renderItem - Callback to render a ListView item given an element\n *                        from the supplied data source.\n *\n * @property itemHeight - Fixed height in pixels for a single item in the\n *                        ListView.\n */\nexport interface ListViewProps {\n  data: any[];\n  renderItem: (any) => ReactElement;\n  itemHeight: number;\n}\n\n/**\n * A lightweight \"virtualised list\" implementation that allows for\n * the efficient rendering of a large number of objects within a\n * ScrollView. ListView supports the full set of ScrollViewProps\n * for styling etc.\n *\n * Note, at present ListView requires the user to specify a fixed\n * itemHeight property in order to calculate which items to render\n * within the list based on scroll position. This may change in\n * future versions.\n *\n * @example\n *\n * function getListViewItems() {\n *   let items = [];\n *\n *   for (let i = 0; i < 5000; ++i) {\n *     const name     = \"Item \" + i;\n *     const category = i % 2 ? \"A\" : \"B\";\n *\n *     items.push({id: i, name: name, category: category});\n *   }\n *\n *   return items;\n * }\n *\n * <ListView\n *   height=\"100%\"\n *   width=\"50%\"\n *   overflow=\"hidden\"\n *   scroll-on-drag={true}\n *   data={getListViewItems()}\n *   renderItem={(item, index, props) => <Item name={item.name} category={item.category} {...props}/>}\n *   itemHeight={50}\n * />\n *\n */\nexport class ListView extends Component<\n  PropsWithChildren<ListViewProps | any>,\n  ListViewState\n> {\n  private _ref: React.RefObject<ViewInstance>;\n\n  constructor(props: PropsWithChildren<ListViewProps | any>) {\n    super(props);\n    this._ref = React.createRef();\n\n    this._onMeasure = this._onMeasure.bind(this);\n    this._calculateVirtualPositions = this._calculateVirtualPositions.bind(\n      this\n    );\n    this._setScrollTopPosition = this._setScrollTopPosition.bind(this);\n    this.scrollToIndex = this.scrollToIndex.bind(this);\n\n    this.state = {\n      scrollTopPosition: 0,\n      width: 0,\n      height: 0,\n    };\n  }\n\n  _onMeasure(e: any): void {\n    this.setState({\n      width: e.width,\n      height: e.height,\n    });\n  }\n\n  _calculateVirtualPositions(): VirtualPositions {\n    const totalItems = this.props.data.length;\n    const innerHeight = this.props.itemHeight * totalItems;\n\n    invariant(\n      this.props.itemHeight > 0,\n      \"Zero or negative itemHeight passed to ListView\"\n    );\n\n    // Pad num rendered items by 1 so we always render the same number of items\n    // which allows us to use a fixed key value on each item in the list.\n    const numItems = Math.floor(this.state.height / this.props.itemHeight) + 1;\n\n    const startIndex = Math.floor(\n      this.state.scrollTopPosition / this.props.itemHeight\n    );\n\n    const endIndex = Math.min(totalItems - 1, startIndex + numItems);\n\n    return {\n      innerHeight: innerHeight,\n      startIndex: startIndex,\n      endIndex: endIndex,\n    };\n  }\n\n  _setScrollTopPosition(e: ScrollEvent): void {\n    this.setState({\n      scrollTopPosition: e.scrollTop,\n    });\n\n    if (typeof this.props.onScroll === \"function\") {\n      this.props.onScroll(e);\n    }\n  }\n\n  scrollToIndex(scrollParams: ScrollParams) {\n    invariant(\n      scrollParams.index >= 0 && scrollParams.index <= this.props.data.length,\n      \"scrollParams.index must be between 0 and props.data.length\"\n    );\n\n    invariant(\n      scrollParams.offset >= 0.0 && scrollParams.offset <= 1.0,\n      \"scrollParams.offset must be normalised between 0.0 and 1.0\"\n    );\n\n    const numItems = Math.floor(this.state.height / this.props.itemHeight);\n\n    const xPos = 0;\n    let yPos =\n      this.props.itemHeight * scrollParams.index -\n      this.props.itemHeight * numItems * scrollParams.offset;\n\n    const scrollViewInstance = this._ref ? this._ref.current : null;\n\n    if (scrollViewInstance) {\n      //@ts-ignore\n      scrollViewInstance.scrollToPosition(xPos, yPos);\n    }\n  }\n\n  render() {\n    const positions: VirtualPositions = this._calculateVirtualPositions();\n    const items: any = [];\n\n    // List items must have a key but we ensure the key remains fixed here\n    // so that we simply re-render the existing views/components rather than\n    // replacing them. This stops issues occuring when dynamically adding and removing\n    // components inside a juce::Viewport.\n    if (this.state.height > 0) {\n      for (let i = positions.startIndex; i <= positions.endIndex; ++i) {\n        items.push(\n          this.props.renderItem(this.props.data[i], i, {\n            position: \"absolute\",\n            top: this.props.itemHeight * i,\n            key: positions.endIndex - i,\n          })\n        );\n      }\n    }\n\n    return (\n      <ScrollView\n        {...this.props}\n        onMeasure={this._onMeasure}\n        onScroll={this._setScrollTopPosition}\n        viewRef={this._ref}\n      >\n        <ScrollView.ContentView\n          {...styles.scrollViewContent}\n          height={positions.innerHeight}\n        >\n          {items}\n        </ScrollView.ContentView>\n      </ScrollView>\n    );\n  }\n}\n\nconst styles = {\n  scrollViewContent: {\n    flexDirection: \"column\",\n    flex: 1.0,\n    flexShrink: 0.0,\n  },\n};\n"
  },
  {
    "path": "packages/react-juce/src/components/ScrollView.ts",
    "content": "import React, { PropsWithChildren } from \"react\";\n\nimport invariant from \"invariant\";\n\nfunction ScrollViewContentView(props: any) {\n  return React.createElement(\"ScrollViewContentView\", props, props.children);\n}\n\nfunction parseScrollbarColorProp(scrollbarColorProp: string) {\n  const values = scrollbarColorProp.split(\" \");\n\n  invariant(\n    values.length === 2,\n    'scrollbar-color should be a space separated string with two values: \"{thumbColor} {trackColor}\".'\n  );\n\n  return {\n    \"scrollbar-thumb-color\": values[0],\n    \"scrollbar-track-color\": values[1],\n  };\n}\n\nfunction parseScrollbarWidthProp(scrollBarWidthProp: string | number) {\n  invariant(\n    typeof scrollBarWidthProp === \"string\" ||\n      typeof scrollBarWidthProp === \"number\",\n    \"scrollbar-width should be a string or a number.\"\n  );\n\n  let props = {};\n\n  if (typeof scrollBarWidthProp === \"string\") {\n    switch (scrollBarWidthProp) {\n      // JUCE's look and feel V2 uses 18px as default scrollbar thickness.\n      case \"auto\":\n        props[\"scrollbar-width\"] = 18;\n        return props;\n      case \"thin\":\n        props[\"scrollbar-width\"] = 9;\n        return props;\n      case \"none\":\n        props[\"overflow-x\"] = \"hidden\";\n        props[\"overflow-y\"] = \"hidden\";\n        props[\"scroll-on-drag\"] = true;\n        return props;\n      default:\n        invariant(\n          false,\n          \"scrollbar-width as string should be one of 'auto', 'thin' or 'none'\"\n        );\n    }\n  }\n\n  props[\"scrollbar-width\"] = scrollBarWidthProp;\n\n  return props;\n}\n\nfunction parseOverflowProp(\n  overflowProp: string | undefined,\n  overflowXProp: string | undefined,\n  overflowYProp: string | undefined\n) {\n  let props = {};\n\n  props[\"overflow-x\"] = overflowXProp || overflowProp;\n  props[\"overflow-y\"] = overflowYProp || overflowProp;\n\n  return props;\n}\n\nexport interface ScrollEvent {\n  scrollTop: number;\n  scrollLeft: number;\n}\n\nexport interface ScrollViewProps {\n  overflow?: string;\n  \"overflow-x\"?: string;\n  \"overflow-y\"?: string;\n  \"scrollbar-color\"?: string;\n  \"scrollbar-width\"?: string | number;\n  \"scroll-on-drag\"?: boolean;\n  onScroll: (e: ScrollEvent) => void;\n}\n\n//TODO: Remove any once ViewProps typed\nexport function ScrollView(props: PropsWithChildren<ScrollViewProps | any>) {\n  const child = React.Children.only(props.children);\n\n  invariant(\n    child && child[\"type\"] === ScrollViewContentView,\n    \"ScrollView must have only one child, and that child must be a ScrollView.ContentView.\"\n  );\n\n  // Unpack non-native props\n  let {\n    overflow,\n    \"scrollbar-color\": scrollbarColor,\n    \"scrollbar-width\": scrollBarWidth,\n    ...other\n  } = props;\n\n  if (typeof scrollbarColor !== \"undefined\")\n    Object.assign(other, parseScrollbarColorProp(scrollbarColor));\n\n  if (typeof scrollBarWidth !== \"undefined\")\n    Object.assign(other, parseScrollbarWidthProp(scrollBarWidth));\n\n  if (typeof overflow !== \"undefined\")\n    Object.assign(\n      other,\n      parseOverflowProp(overflow, other[\"overflow-x\"], other[\"overflow-y\"])\n    );\n\n  return React.createElement(\"ScrollView\", other, child);\n}\n\nScrollView.ContentView = ScrollViewContentView;\n"
  },
  {
    "path": "packages/react-juce/src/components/Slider.tsx",
    "content": "import React, { Component, PropsWithChildren } from \"react\";\nimport invariant from \"invariant\";\n\nimport { Canvas, CanvasRenderingContext } from \"./Canvas\";\nimport { View } from \"./View\";\nimport { SyntheticMouseEvent } from \"../lib/SyntheticEvents\";\n\n// Some simple helpers for slider drag gesture -> value mapping\nconst _linearHorizontalGestureMap = (\n  mouseDownX: number,\n  mouseDownY: number,\n  sensitivity: number,\n  valueAtDragStart: number,\n  dragEvent: SyntheticMouseEvent\n): number => {\n  const dx = dragEvent.x - mouseDownX;\n  return Math.max(0.0, Math.min(1.0, valueAtDragStart + dx * sensitivity));\n};\n\nconst _linearVerticalGestureMap = (\n  mouseDownX: number,\n  mouseDownY: number,\n  sensitivity: number,\n  valueAtDragStart: number,\n  dragEvent: SyntheticMouseEvent\n): number => {\n  const dy = dragEvent.y - mouseDownY;\n  return Math.max(0.0, Math.min(1.0, valueAtDragStart - dy * sensitivity));\n};\n\nconst _rotaryGestureMap = (\n  mouseDownX: number,\n  mouseDownY: number,\n  sensitivity: number,\n  valueAtDragStart: number,\n  dragEvent: SyntheticMouseEvent\n): number => {\n  const dx = dragEvent.x - mouseDownX;\n  const dy = mouseDownY - dragEvent.y;\n  return Math.max(\n    0.0,\n    Math.min(1.0, valueAtDragStart + (dx + dy) * sensitivity)\n  );\n};\n\nconst _drawLinearHorizontalSlider = (trackColor: string, fillColor: string) => {\n  return (\n    ctx: CanvasRenderingContext,\n    width: number,\n    height: number,\n    value: number\n  ): void => {\n    const lineWidth = 2.0;\n\n    const x = 0 + lineWidth / 2;\n    const y = 0 + lineWidth / 2;\n\n    width = width - lineWidth;\n    height = height - lineWidth;\n\n    const fillWidth = value * width;\n\n    ctx.lineWidth = lineWidth;\n    ctx.strokeStyle = trackColor;\n    ctx.fillStyle = fillColor;\n\n    ctx.fillRect(x, y, fillWidth, height);\n    ctx.strokeRect(x, y, width, height);\n  };\n};\n\nconst _drawLinearVerticalSlider = (trackColor: string, fillColor: string) => {\n  return (\n    ctx: CanvasRenderingContext,\n    width: number,\n    height: number,\n    value: number\n  ): void => {\n    const lineWidth = 2.0;\n\n    const x = 0 + lineWidth / 2;\n    const y = 0 + lineWidth / 2;\n\n    width = width - lineWidth;\n    height = height - lineWidth;\n\n    const fillHeight = value * height;\n    const fillY = y + (height - fillHeight);\n\n    ctx.lineWidth = lineWidth;\n    ctx.strokeStyle = trackColor;\n    ctx.fillStyle = fillColor;\n\n    ctx.fillRect(x, fillY, width, fillHeight);\n    ctx.strokeRect(x, y, width, height);\n  };\n};\n\nfunction _drawArc(\n  ctx,\n  centerX,\n  centerY,\n  radius,\n  arcSize,\n  startAngle,\n  endAngle,\n  lineWidth\n) {\n  const deltaX = centerX;\n  const deltaY = centerY;\n\n  const rotateAngle = ((180 + 180 * (1 - arcSize)) * Math.PI) / 180;\n\n  ctx.lineWidth = lineWidth;\n\n  ctx.beginPath();\n  ctx.moveTo(centerX - lineWidth / 2, 0);\n  ctx.arc(\n    centerX - lineWidth / 2,\n    centerY - lineWidth / 2,\n    radius,\n    startAngle,\n    endAngle\n  );\n\n  ctx.translate(deltaX, deltaY);\n  ctx.rotate(rotateAngle);\n  ctx.translate(-deltaX, -deltaY);\n\n  ctx.stroke();\n  ctx.resetTransform();\n}\n\nconst _drawRotarySlider = (trackColor, fillColor) => {\n  return (ctx, width, height, value) => {\n    const lineWidth = 3;\n    const arcSize = 0.8;\n\n    const radius = Math.min(width, height) * 0.5 - lineWidth / 2;\n\n    const centerX = width / 2;\n    const centerY = height / 2;\n\n    const strokeStart = 0;\n    const strokeEnd = 2 * Math.PI * arcSize;\n\n    const fillStart = -(2.5 * Math.PI * arcSize);\n    const fillEnd = fillStart + value * (2 * Math.PI * arcSize);\n\n    ctx.strokeStyle = trackColor;\n    _drawArc(\n      ctx,\n      centerX,\n      centerY,\n      radius,\n      arcSize,\n      strokeStart,\n      strokeEnd,\n      lineWidth\n    );\n\n    ctx.strokeStyle = fillColor;\n    _drawArc(\n      ctx,\n      centerX,\n      centerY,\n      radius,\n      arcSize,\n      fillStart,\n      fillEnd,\n      lineWidth\n    );\n  };\n};\n\nexport interface SliderProps {\n  value?: number;\n  sensitivity?: number;\n  onChange?: (value: number) => void;\n  onDraw?: (\n    ctx: CanvasRenderingContext,\n    width: number,\n    height: number,\n    value: number\n  ) => void;\n  mapDragGestureToValue?: (\n    mouseDownX: number,\n    mouseDownY: number,\n    sensitivity: number,\n    valueAtDragStart: number,\n    dragEvent: SyntheticMouseEvent\n  ) => number;\n}\n\ntype SliderState = {\n  width: number;\n  height: number;\n  value: number;\n};\n\n/**\n * A generic slider component which can be used as a building block for more complex\n * sliders.\n *\n * Slider takes an onDraw function prop for rendering the Slider using a CanvasRenderingContext.\n * Slider also accepts a mapDragGestureToValue pop which allows customisation when converting mouse drag\n * positions/events to the Slider's normalised value reported via the onChange prop callback.\n *\n * Some default onDraw and mapDragGestureToValue implementations are provided:\n * @see Slider.drawLinearHorizontal\n * @see Slider.drawLinearVertical\n * @see Slider.drawRotary\n *\n * @see Slider.linearHorizontalGestureMap\n * @see Slider.linearVerticalGestureMap\n * @see Slider.rotaryGestureMap\n *\n * @example\n *\n * <Slider\n *  onChange={(value) => console.log(\"Slider value changed: \" + value)}\n *  onDraw={Slider.drawRotary('ff66FDCF', 'ff626262')}\n *  mapDragGestureToValue={Slider.rotaryGestureMap}\n * />\n *\n */\nexport class Slider extends Component<\n  PropsWithChildren<SliderProps | any>,\n  SliderState\n> {\n  static linearHorizontalGestureMap = _linearHorizontalGestureMap;\n  static linearVerticalGestureMap = _linearVerticalGestureMap;\n  static rotaryGestureMap = _rotaryGestureMap;\n\n  static drawLinearHorizontal = _drawLinearHorizontalSlider;\n  static drawLinearVertical = _drawLinearVerticalSlider;\n  static drawRotary = _drawRotarySlider;\n\n  private _valueAtDragStart = 0.0;\n  private _mouseDownX = 0;\n  private _mouseDownY = 0;\n\n  static defaultProps = {\n    sensitivity: 1 / 200,\n    onDraw: _drawRotarySlider(\"ff626262\", \"ff66FDCF\"),\n    mapDragGestureToValue: _rotaryGestureMap,\n  };\n\n  constructor(props: PropsWithChildren<SliderProps | any>) {\n    super(props);\n\n    this._onMeasure = this._onMeasure.bind(this);\n    this._onMouseDown = this._onMouseDown.bind(this);\n    this._onMouseDrag = this._onMouseDrag.bind(this);\n    this._onDraw = this._onDraw.bind(this);\n\n    this.state = {\n      width: 0,\n      height: 0,\n      value: 0.0,\n    };\n  }\n\n  _onMeasure(e: any) {\n    this.setState({\n      width: e.width,\n      height: e.height,\n    });\n  }\n\n  _onMouseDown(e: SyntheticMouseEvent) {\n    this._valueAtDragStart = this.props.hasOwnProperty(\"value\")\n      ? this.props.value\n      : this.state.value;\n\n    this._mouseDownX = e.x;\n    this._mouseDownY = e.y;\n\n    if (typeof this.props.onMouseDown === \"function\") {\n      this.props.onMouseDown(e);\n    }\n  }\n\n  _onMouseDrag(e: SyntheticMouseEvent) {\n    let value = 0.0;\n\n    if (typeof this.props.mapDragGestureToValue !== \"function\") {\n      invariant(false, \"Invalid gesture mapping function supplied.\");\n      return;\n    }\n\n    value = this.props.mapDragGestureToValue(\n      this._mouseDownX,\n      this._mouseDownY,\n      this.props.sensitivity,\n      this._valueAtDragStart,\n      e\n    );\n\n    if (!this.props.hasOwnProperty(\"value\")) {\n      this.setState({\n        value: value,\n      });\n    }\n\n    if (typeof this.props.onChange === \"function\") {\n      this.props.onChange(value);\n    }\n\n    if (typeof this.props.onMouseDrag === \"function\") {\n      this.props.onMouseDrag(e);\n    }\n  }\n\n  _onDraw(ctx: CanvasRenderingContext) {\n    const value = this.props.hasOwnProperty(\"value\")\n      ? this.props.value\n      : this.state.value;\n\n    if (typeof this.props.onDraw === \"function\") {\n      return this.props.onDraw(ctx, this.state.width, this.state.height, value);\n    }\n  }\n\n  render() {\n    return (\n      <View\n        {...this.props}\n        onMeasure={this._onMeasure}\n        onMouseDown={this._onMouseDown}\n        onMouseDrag={this._onMouseDrag}\n      >\n        <Canvas onDraw={this._onDraw} {...styles.canvas} />\n        {this.props.children}\n      </View>\n    );\n  }\n}\n\nconst styles = {\n  canvas: {\n    width: \"100%\",\n    height: \"100%\",\n    position: \"absolute\",\n    interceptClickEvents: false,\n  },\n};\n"
  },
  {
    "path": "packages/react-juce/src/components/Text.ts",
    "content": "import React from \"react\";\n\nexport function Text(props: any) {\n  return React.createElement(\"Text\", props, props.children);\n}\n\nText.WordWrap = {\n  none: 0,\n  byWord: 1,\n  byChar: 2,\n};\n\nText.FontStyleFlags = {\n  plain: 0,\n  bold: 1,\n  italic: 2,\n  underlined: 4,\n};\n\nText.JustificationFlags = {\n  left: 1,\n  right: 2,\n  horizontallyCentred: 4,\n  top: 8,\n  bottom: 16,\n  verticallyCentred: 32,\n  horizontallyJustified: 64,\n  centred: 36,\n  centredLeft: 33,\n  centredRight: 34,\n  centredTop: 12,\n  centredBottom: 20,\n  topLeft: 9,\n  topRight: 10,\n  bottomLeft: 17,\n  bottomRight: 18,\n};\n"
  },
  {
    "path": "packages/react-juce/src/components/TextInput.tsx",
    "content": "import React, { PropsWithChildren } from \"react\";\n\nexport interface InputEvent {\n  value: string;\n}\n\nexport interface ChangeEvent {\n  value: string;\n}\n\nexport interface TextInputProps {\n  value?: string;\n\n  color?: string;\n  fontSize?: number;\n  fontStyle?: number;\n  fontFamily?: string;\n  justification?: number;\n  \"kerning-factor\"?: number;\n\n  placeholder?: string;\n  \"placeholder-color\"?: string;\n  maxlength?: number;\n  readonly?: boolean;\n  \"outline-color\"?: string;\n  \"focused-outline-color\"?: string;\n  \"highlighted-text-color\"?: string;\n  \"highlight-color\"?: string;\n  \"caret-color\"?: string;\n\n  onChange?: (e: ChangeEvent) => void;\n  onInput?: (e: InputEvent) => void;\n}\n\nexport function TextInput(props: PropsWithChildren<TextInputProps | any>) {\n  return React.createElement(\"TextInput\", props, props.children);\n}\n"
  },
  {
    "path": "packages/react-juce/src/components/View.ts",
    "content": "import React from \"react\";\n\n// We'll need to wrap the default native components in stuff like this so that\n// you can use <View> in your JSX. Otherwise we need the dynamic friendliness\n// of the createElement call (note that the type is a string...);\nexport function View(props: any) {\n  return React.createElement(\"View\", props, props.children);\n}\n\nView.ClickEventFlags = {\n  disableClickEvents: 0,\n  allowClickEvents: 1,\n  allowClickEventsExcludingChildren: 2,\n  allowClickEventsOnlyOnChildren: 3,\n};\n\nView.EasingFunctions = {\n  linear: 0,\n  quadraticIn: 1,\n  quadraticOut: 2,\n  quadraticInOut: 3,\n};\n"
  },
  {
    "path": "packages/react-juce/src/index.tsx",
    "content": "/** Polyfill ES2015 data structures with core-js. */\nimport \"core-js/es6/set\";\nimport \"core-js/es6/map\";\n\nimport Backend from \"./lib/Backend\";\nimport Renderer, { TracedRenderer } from \"./lib/Renderer\";\n\nexport { default as EventBridge } from \"./lib/EventBridge\";\n\nexport * from \"./components/View\";\nexport * from \"./components/ScrollView\";\nexport * from \"./components/Canvas\";\nexport * from \"./components/Text\";\nexport * from \"./components/TextInput\";\nexport * from \"./components/Image\";\nexport * from \"./components/Button\";\nexport * from \"./components/Slider\";\nexport * from \"./components/ListView\";\nexport * from \"./lib/SyntheticEvents\";\n\nlet __renderStarted = false;\nlet __preferredRenderer = Renderer;\n\nexport default {\n  getRootContainer() {\n    return Backend.getRootContainer();\n  },\n\n  render(\n    element: any,\n    container: any,\n    callback?: () => void | null | undefined\n  ) {\n    console.log(\"Render started...\");\n\n    // Create a root Container if it doesnt exist\n    if (!container._rootContainer) {\n      //TODO: Double check passing false for final param \"hydrate correct\"\n      container._rootContainer = __preferredRenderer.createContainer(\n        container,\n        false,\n        false\n      );\n    }\n\n    // Update the root Container\n    return __preferredRenderer.updateContainer(\n      element,\n      container._rootContainer,\n      null,\n      // TODO: callback in __preferredRenderer.updateContainer is not optional.\n      // @ts-ignore\n      callback\n    );\n  },\n\n  enableMethodTrace() {\n    if (__renderStarted) {\n      throw new Error(\"Cannot enable method trace after initial render.\");\n    }\n\n    __preferredRenderer = TracedRenderer;\n  },\n};\n"
  },
  {
    "path": "packages/react-juce/src/lib/Backend.ts",
    "content": "import { all as allCssProps } from \"known-css-properties\";\nimport camelCase from \"camelcase\";\nimport NativeMethods from \"./NativeMethods\";\nimport SyntheticEvents, {\n  SyntheticMouseEvent,\n  SyntheticKeyboardEvent,\n} from \"./SyntheticEvents\";\nimport { macroPropertyGetters } from \"./MacroProperties\";\nimport Colors from \"./MacroProperties/Colors\";\n\n//TODO: Keep this union or introduce a common base class ViewInstanceBase?\nexport type Instance = ViewInstance | RawTextViewInstance;\n\nlet __rootViewInstance: ViewInstance | null = null;\nlet __viewRegistry: Map<string, Instance> = new Map<string, Instance>();\nlet __lastMouseDownViewId: string | null = null;\n\n// get any css properties not beginning with a \"-\",\n// and build a map from any camelCase versions to\n// the hyphenated version\nconst cssPropsMap = allCssProps\n  .filter((s) => !s.startsWith(\"-\") && s.includes(\"-\"))\n  .reduce((acc, v) => Object.assign(acc, { [camelCase(v)]: v }), {});\n\nexport class ViewInstance {\n  private _id: string;\n  private _type: string;\n  public _children: Instance[];\n  public _props: any = null;\n  public _parent: any = null;\n\n  constructor(id: string, type: string, props?: any, parent?: ViewInstance) {\n    this._id = id;\n    this._type = type;\n    this._children = [];\n    this._props = props;\n    this._parent = parent;\n\n    //TODO: This has been added to resolve a bug in\n    //      our Button component when calling contains()\n    //      on a viewRef. This is a result of wrapping our\n    //      viewRefs in a Proxy object which means this is\n    //      no longer bound to the original ViewInstance object\n    //      during the contains call. Ideally we would use Reflect.get()\n    //      here but Duktape does not fully support Reflect at the moment.\n    this.contains = this.contains.bind(this);\n  }\n\n  getViewId(): string {\n    return this._id;\n  }\n\n  getType(): string {\n    return this._type;\n  }\n\n  getChildIndex(childInstance: Instance): number {\n    for (let i = 0; i < this._children.length; ++i) {\n      if (this._children[i] === childInstance) {\n        return i;\n      }\n    }\n\n    return -1;\n  }\n\n  appendChild(childInstance: Instance): any {\n    childInstance._parent = this;\n\n    this._children.push(childInstance);\n\n    //@ts-ignore\n    return NativeMethods.insertChild(this._id, childInstance._id, -1);\n  }\n\n  insertChild(childInstance: Instance, index: number): any {\n    childInstance._parent = this;\n\n    this._children.splice(index, 0, childInstance);\n\n    //@ts-ignore\n    return NativeMethods.insertChild(this._id, childInstance._id, index);\n  }\n\n  removeChild(childInstance: Instance): any {\n    const index = this._children.indexOf(childInstance);\n\n    if (index >= 0) {\n      this._children.splice(index, 1);\n\n      __viewRegistry.delete(childInstance.getViewId());\n\n      //@ts-ignore\n      return NativeMethods.removeChild(this._id, childInstance._id);\n    }\n  }\n\n  setProperty(propKey: string, value: any): any {\n    // if the supplied propkey is a camelCase equivalent\n    // of a css prop, first convert it to kebab-case\n    propKey = cssPropsMap[propKey] || propKey;\n\n    // convert provided color string to alpha-hex code for JUCE\n    let nativeValue;\n    if (Colors.isColorProperty(propKey)) {\n      value = Colors.colorStringToAlphaHex(value);\n      if (value.startsWith(\"linear-gradient\")) {\n        nativeValue = Colors.convertLinearGradientStringToNativeObject(value);\n      }\n    }\n\n    this._props = Object.assign({}, this._props, {\n      [propKey]: value,\n    });\n\n    // Our React Ref equivalent. This is needed\n    // as it appears the 'ref' prop isn't passed through\n    // to our renderer's setProperty from the reconciler.\n    // We wrap the ViewInstance in a proxy object here to allow\n    // invocation of native ViewInstance methods via React refs.\n    // If a property is not present on the ViewInstance object\n    // we assume the caller is attempting to access/invoke a\n    // native View method.\n    if (propKey === \"viewRef\") {\n      value.current = new Proxy(this, {\n        get: function (target, prop, receiver) {\n          if (prop in target) {\n            return target[prop];\n          }\n\n          return function (...args) {\n            //@ts-ignore\n            return NativeMethods.invokeViewMethod(target._id, prop, ...args);\n          };\n        },\n      });\n\n      return;\n    }\n\n    if (macroPropertyGetters.hasOwnProperty(propKey)) {\n      //@ts-ignore\n      for (const [k, v] of macroPropertyGetters[propKey](value))\n        NativeMethods.setViewProperty(this._id, k, v);\n      return;\n    }\n    //@ts-ignore\n    return NativeMethods.setViewProperty(\n      this._id,\n      propKey,\n      nativeValue ? nativeValue : value\n    );\n  }\n\n  contains(node: Instance): boolean {\n    if (node === this) {\n      return true;\n    }\n\n    for (let i = 0; i < this._children.length; ++i) {\n      const child = this._children[i];\n\n      // A ViewInstance may hold RawTextViewInstances but a\n      // RawTextViewInstance contains no children.\n      if (child instanceof ViewInstance && child.contains(node)) return true;\n    }\n\n    return false;\n  }\n}\n\nexport class RawTextViewInstance {\n  private _id: string;\n  private _text: string;\n  public _parent: ViewInstance;\n\n  constructor(id: string, text: string, parent: ViewInstance) {\n    this._id = id;\n    this._text = text;\n    this._parent = parent;\n  }\n\n  getViewId(): string {\n    return this._id;\n  }\n\n  getText() {\n    return this._text;\n  }\n\n  setTextValue(text: string): any {\n    this._text = text;\n    //@ts-ignore\n    return NativeMethods.setRawTextValue(this._id, text);\n  }\n}\n\nfunction __getRootContainer(): ViewInstance {\n  if (__rootViewInstance !== null) return __rootViewInstance;\n\n  //@ts-ignore\n  const id = NativeMethods.getRootInstanceId();\n  __rootViewInstance = new ViewInstance(id, \"View\");\n\n  return __rootViewInstance;\n}\n\nfunction __hasFunctionProp(view: ViewInstance, prop: string) {\n  return (\n    view._props.hasOwnProperty(prop) && typeof view._props[prop] === \"function\"\n  );\n}\n\nfunction __callEventHandlerIfPresent(\n  view: Instance,\n  eventType: string,\n  event: any\n) {\n  if (view instanceof ViewInstance && __hasFunctionProp(view, eventType)) {\n    view._props[eventType](event);\n  }\n}\n\nfunction __bubbleEvent(view: Instance, eventType: string, event: any): void {\n  if (view && view !== __getRootContainer()) {\n    // Always call the event callback on the target before bubbling.\n    // Some events may not bubble or have bubble defined. i.e. onMeasure\n    __callEventHandlerIfPresent(view, eventType, event);\n\n    if (event.bubbles) __bubbleEvent(view._parent, eventType, event);\n  }\n}\n\n//@ts-ignore\nNativeMethods.dispatchViewEvent = function dispatchEvent(\n  viewId: string,\n  eventType: string,\n  event: any\n) {\n  if (__viewRegistry.hasOwnProperty(viewId)) {\n    const instance = __viewRegistry[viewId];\n\n    // Convert target/relatedTarget to concrete ViewInstance refs\n    if (event.target && __viewRegistry.hasOwnProperty(event.target)) {\n      event.target = __viewRegistry[event.target];\n    }\n\n    if (\n      event.relatedTarget &&\n      __viewRegistry.hasOwnProperty(event.relatedTarget)\n    ) {\n      event.relatedTarget = __viewRegistry[event.relatedTarget];\n    }\n\n    // Convert native event object into it's SyntheticEvent equivalent if required.\n    if (SyntheticEvents.isMouseEventHandler(eventType))\n      event = new SyntheticMouseEvent(event);\n    else if (SyntheticEvents.isKeyboardEventHandler(eventType))\n      event = new SyntheticKeyboardEvent(event);\n\n    // If mouseDown event we store the target viewId as the last view\n    // to recieve a mouseDown for \"onClick\" book-keeping.\n    if (eventType === \"onMouseDown\") {\n      __lastMouseDownViewId = viewId;\n      __bubbleEvent(instance, eventType, event);\n      return;\n    }\n\n    if (eventType === \"onMouseUp\") {\n      __bubbleEvent(instance, eventType, event);\n\n      if (__lastMouseDownViewId && viewId === __lastMouseDownViewId) {\n        __lastMouseDownViewId = null;\n        __bubbleEvent(instance, \"onClick\", event);\n      }\n      return;\n    }\n\n    __bubbleEvent(instance, eventType, event);\n  }\n};\n\nexport default {\n  getRootContainer(): ViewInstance {\n    return __getRootContainer();\n  },\n  createViewInstance(\n    viewType: string,\n    props: any,\n    parentInstance: ViewInstance\n  ): ViewInstance {\n    //@ts-ignore\n    const id = NativeMethods.createViewInstance(viewType);\n    const instance = new ViewInstance(id, viewType, props, parentInstance);\n\n    __viewRegistry[id] = instance;\n    return instance;\n  },\n  createTextViewInstance(text: string, parentInstance: ViewInstance) {\n    //@ts-ignore\n    const id = NativeMethods.createTextViewInstance(text);\n    const instance = new RawTextViewInstance(id, text, parentInstance);\n\n    __viewRegistry[id] = instance;\n    return instance;\n  },\n  resetAfterCommit() {\n    //@ts-ignore\n    return NativeMethods.resetAfterCommit();\n  },\n};\n"
  },
  {
    "path": "packages/react-juce/src/lib/EventBridge.ts",
    "content": "import EventEmitter from \"events\";\nimport NativeMethods from \"./NativeMethods\";\n\nconst EventBridge = new EventEmitter.EventEmitter();\nEventBridge.setMaxListeners(30);\n\n// An internal hook for the native side, from which we propagate events through\n// the EventEmitter interface.\n// @ts-ignore\nNativeMethods.dispatchEvent = function dispatchEvent(\n  eventType: string,\n  ...args: any\n): void {\n  EventBridge.emit(eventType, ...args);\n};\n\nexport default EventBridge;\n"
  },
  {
    "path": "packages/react-juce/src/lib/MacroProperties/Colors.ts",
    "content": "import ColorString from \"color-string\";\nimport ColorNames from \"color-name\";\n\nconst COLOR_PROPERTIES = [\"border-color\", \"background-color\", \"color\"];\n\nconst isColorProperty = (propKey: string): boolean => {\n  return COLOR_PROPERTIES.includes(propKey);\n};\n\nconst colorStringToAlphaHex = (colorString: string): string => {\n  //From Hex\n  if (colorString.startsWith(\"#\") && colorString.length === 7) {\n    return `ff${colorString}`.replace(\"#\", \"\");\n  }\n  //From RGB or RGBA\n  else if (colorString.startsWith(\"rgb\")) {\n    const rgbValues = colorString\n      .split(\"(\")[1]\n      .split(\")\")[0]\n      .replace(/ /g, \"\")\n      .split(\",\");\n    const alphaValue =\n      rgbValues.length === 4\n        ? //@ts-ignore\n          percentToHex(100 * rgbValues.pop())\n        : \"ff\";\n    const hex = rgbValues.map((color) => {\n      const hex = Number.parseInt(color).toString(16);\n      return hex.length == 1 ? \"0\" + hex : hex;\n    });\n    return alphaValue + hex.join(\"\");\n  }\n  //From HSL or HSLA\n  else if (colorString.startsWith(\"hsl\")) {\n    const hslValues = colorString\n      .split(\"(\")[1]\n      .split(\")\")[0]\n      .replace(/ |[%]/g, \"\")\n      .split(\",\");\n    const alphaValue =\n      hslValues.length === 4\n        ? //@ts-ignore\n          percentToHex(100 * hslValues.pop())\n        : \"ff\";\n    const hex = hslToHex(\n      Number.parseInt(hslValues[0]),\n      Number.parseInt(hslValues[1]),\n      Number.parseInt(hslValues[2])\n    );\n    return alphaValue + hex;\n  }\n  //From Linear Gradient\n  else if (colorString.startsWith(\"linear-gradient\")) {\n    const lgValues = colorString\n      .split(/\\((.+)/)[1]\n      .split(/\\)$/)[0]\n      .split(/,+(?![^\\(]*\\))/)\n      .map((item) => {\n        return item.split(\" \");\n      });\n    //concat any arrays that contain hsl or rba strings\n    lgValues.forEach((itemArr, idx) => {\n      if (itemArr.find((item) => item.includes(\"(\")) !== undefined) {\n        const itemArrClone = itemArr.slice();\n        const startIdx = itemArrClone.findIndex((item) => item.includes(\"(\"));\n        const endIdx = itemArrClone.findIndex((item) => item.includes(\")\"));\n        const colorHSLRGB = itemArrClone.slice(startIdx, endIdx + 1).join(\"\");\n        itemArr.splice(startIdx, endIdx + 1, colorHSLRGB);\n        lgValues[idx] = itemArr;\n      } else {\n        lgValues[idx] = itemArr;\n      }\n    });\n    //flatten array\n    const lgValuesCleaned: Array<String> = [].concat\n      // @ts-ignore\n      .apply([], lgValues)\n      .filter((item) => {\n        return item != \"\";\n      });\n    //converts any colorStrings in linear gradient to alpha-hex\n    let skipCurrentIdx = -1;\n    const lgValuesConverted = lgValuesCleaned\n      .map((value, idx) => {\n        if (skipCurrentIdx == idx) return;\n        // @ts-ignore\n        let convertedColorString = colorStringToAlphaHex(value);\n        //check if the next element is a percent and attach to current and remove it\n        const nextIdx = idx + 1;\n        if (\n          lgValuesCleaned[nextIdx] !== undefined &&\n          lgValuesCleaned[nextIdx].includes(\"%\") &&\n          !lgValuesCleaned[nextIdx].includes(\"(\")\n        ) {\n          convertedColorString += lgValuesCleaned[nextIdx];\n          skipCurrentIdx = nextIdx;\n        }\n        return convertedColorString;\n      })\n      .filter((item) => {\n        return item !== undefined;\n      });\n    return \"linear-gradient(\" + lgValuesConverted.join(\",\") + \")\";\n  }\n  //From Named Colours\n  else if (Object.keys(ColorNames).includes(colorString)) {\n    const rgbValues = ColorString.get.rgb(colorString);\n    const hex = ColorString.to.hex(rgbValues);\n    return colorStringToAlphaHex(hex);\n  } else {\n    return colorString;\n  }\n};\n\nconst convertLinearGradientStringToNativeObject = (\n  lgColorStringHex: string\n): object => {\n  const linearGradientNativeObject = {};\n  const lgValues = lgColorStringHex\n    .split(/\\((.+)/)[1]\n    .split(/\\)$/)[0]\n    .replace(/ /g, \"\")\n    .split(/,+(?![^\\(]*\\))/);\n  //Check for directional words\n  let angle: number = 0;\n  let rotation: string = lgValues[0];\n  if (rotation == \"toleft\") angle = 270;\n  if (rotation == \"toright\") angle = 90;\n  if (rotation == \"tobottom\") angle = 180;\n  if (rotation == \"totop\") angle = 0;\n\n  //These are not the exact match to CSS as boundary dimensions are required for calculation\n  if (rotation == \"totopleft\" || rotation == \"tolefttop\") angle = 295;\n  if (rotation == \"totopright\" || rotation == \"torighttop\") angle = 45;\n  if (rotation == \"tobottomright\" || rotation == \"torightbottom\") angle = 115;\n  if (rotation == \"tobottomleft\" || rotation == \"toleftbottom\") angle = 205;\n\n  //Check for Turns\n  if (rotation.includes(\"turn\")) {\n    rotation = rotation.replace(\"turn\", \"\");\n    const turns: number = parseFloat(rotation);\n    angle = 360 * turns;\n  }\n  //Check for Degrees\n  if (rotation.includes(\"deg\")) {\n    rotation = rotation.replace(\"deg\", \"\");\n    angle = parseInt(rotation);\n  }\n\n  linearGradientNativeObject[\"angle\"] = angle;\n  linearGradientNativeObject[\"colours\"] = [];\n  const colorPositions: Array<String> = lgValues.slice(1);\n\n  colorPositions.forEach((colorPos, idx) => {\n    const hexPosObj = { id: idx };\n    const hex = colorPos.slice(0, 8);\n    //check string is an alpha hex\n    const isValidAlphaHex =\n      // @ts-ignore\n      hex.match(\n        /^[0-9a-fA-F]{8}$|#[0-9a-fA-F]{6}$|#[0-9a-fA-F]{4}$|#[0-9a-fA-F]{3}$/\n      ).length > 0;\n    if (!isValidAlphaHex) return;\n    colorPos = colorPos.replace(hex, \"\");\n    if (colorPos.includes(\"%\")) {\n      colorPos = colorPos.replace(\"%\", \"\");\n      // @ts-ignore\n      let colorPercent = parseInt(colorPos) / 100;\n      //check if previous percent is greater or equal to the current\n      if (linearGradientNativeObject[\"colours\"].length > 0) {\n        const previousPos =\n          linearGradientNativeObject[\"colours\"][idx - 1][\"position\"];\n        if (previousPos >= colorPercent) colorPercent = previousPos + 0.001;\n      }\n      hexPosObj[\"position\"] = colorPercent;\n    } else {\n      if (idx == 0) {\n        hexPosObj[\"position\"] = 0.0;\n      } else if (idx == colorPositions.length - 1) {\n        hexPosObj[\"position\"] = 1.0;\n      }\n      //assign null and iterate over again later\n      else {\n        hexPosObj[\"position\"] = undefined;\n      }\n    }\n    hexPosObj[\"hex\"] = hex;\n    linearGradientNativeObject[\"colours\"].push(hexPosObj);\n  });\n  //Find half way between previous and next given percent if no percentage assigned\n  linearGradientNativeObject[\"colours\"].forEach((colorPos, idx) => {\n    if (colorPos[\"position\"] === undefined) {\n      //find next color with percentage\n      const colorsClone = JSON.parse(\n        JSON.stringify(linearGradientNativeObject[\"colours\"])\n      );\n      let currentArrayChunk = colorsClone.splice(idx);\n      const nextColorPercent = currentArrayChunk.find(\n        (colorPos) => colorPos[\"position\"] != undefined && colorPos[\"id\"] !== 0\n      );\n      const nextColorPercentIdx = currentArrayChunk.findIndex(\n        (colorPos) => colorPos[\"position\"] != undefined && colorPos[\"id\"] !== 0\n      );\n      currentArrayChunk = currentArrayChunk.splice(0, nextColorPercentIdx + 1);\n      const previousColorPercent = colorsClone[idx - 1];\n      const y = nextColorPercent[\"position\"];\n      const x = previousColorPercent[\"position\"];\n      const n = currentArrayChunk.length + 1;\n      //assign evenly distributed values to each undefined color in current array chunk\n      currentArrayChunk.forEach((colorPosChunk, idx) => {\n        idx += 1;\n        if (colorPosChunk[\"position\"] === undefined) {\n          const colorPosition = x + ((y - x) / (n - 1)) * idx;\n          const colorPosObj =\n            linearGradientNativeObject[\"colours\"][colorPosChunk[\"id\"]];\n          colorPosObj[\"position\"] = colorPosition;\n        }\n      });\n    }\n  });\n  return linearGradientNativeObject;\n};\n\nconst hslToHex = (h: number, s: number, l: number): string => {\n  l /= 100;\n  const a = (s * Math.min(l, 1 - l)) / 100;\n  const f = (n) => {\n    const k = (n + h / 30) % 12;\n    const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);\n    return Math.round(255 * color)\n      .toString(16)\n      .padStart(2, \"0\");\n  };\n  return `${f(0)}${f(8)}${f(4)}`;\n};\n\nconst percentToHex = (p: number): string => {\n  p = p > 100 ? 100 : p;\n  const intValue = Math.round((p / 100) * 255);\n  const hexValue = intValue.toString(16);\n  return hexValue.padStart(2, \"0\").toLowerCase();\n};\n\nexport default {\n  isColorProperty,\n  colorStringToAlphaHex,\n  convertLinearGradientStringToNativeObject,\n};\n"
  },
  {
    "path": "packages/react-juce/src/lib/MacroProperties/Transform.ts",
    "content": "import { TPropertyAssignment } from \"./types\";\nimport { getMacroCalls } from \"./util\";\nimport matrix from \"matrix-js\";\n\nconst rotateMultipliers = {\n  deg: Math.PI / 180.0,\n  grad: Math.PI / 200.0,\n  rad: 1,\n  turn: 2 * Math.PI,\n};\n\nconst angleUnitMatcher = new RegExp(\n  `(-?[0-9]*\\.?[0-9]+)(${Object.keys(rotateMultipliers).join(\"|\")}|)$`\n);\n\nconst toRadians = (arg: string) => {\n  // @ts-ignore\n  let [, angle, unit] = angleUnitMatcher.exec(arg);\n  let angleFloat = parseFloat(angle);\n  if (angleFloat === NaN) return NaN;\n  if (unit === \"\" && angleFloat !== 0) return NaN;\n  angleFloat *= rotateMultipliers[unit] || 1;\n  return angleFloat;\n};\n\nconst stringArgsToFloat = (...args: string[]) => args.map(parseFloat);\nconst stringArgsToRadians = (...args: string[]) => args.map(toRadians);\n\nconst identity = matrix([\n  [1, 0, 0, 0],\n  [0, 1, 0, 0],\n  [0, 0, 1, 0],\n  [0, 0, 0, 1],\n]);\n\nconst rotate3d = (x: number, y: number, z: number, theta: number) => {\n  const sinTheta = Math.sin(theta);\n  const cosTheta = Math.cos(theta);\n  const r = Math.sqrt(x ** 2 + y ** 2 + z ** 2);\n  if (r === 0) {\n    return identity;\n  }\n  const [u, v, w] = [x / r, y / r, z / r];\n\n  return matrix([\n    [\n      cosTheta + (1 - cosTheta) * u ** 2,\n      u * v * (1 - cosTheta) - w * sinTheta,\n      u * w * (1 - cosTheta) + v * sinTheta,\n      0,\n    ],\n    [\n      v * u * (1 - cosTheta) + w * sinTheta,\n      cosTheta + (1 - cosTheta) * v ** 2,\n      v * w * (1 - cosTheta) - u * sinTheta,\n      0,\n    ],\n    [\n      w * u * (1 - cosTheta) - v * sinTheta,\n      w * v * (1 - cosTheta) + u * sinTheta,\n      cosTheta + (1 - cosTheta) * w ** 2,\n      0,\n    ],\n    [0, 0, 0, 1],\n  ]);\n};\n\nconst rotateX = (theta: number) => rotate3d(1, 0, 0, theta);\nconst rotateY = (theta: number) => rotate3d(0, 1, 0, theta);\nconst rotateZ = (theta: number) => rotate3d(0, 0, 1, theta);\n\nconst scale3d = (sx = 1, sy = 1, sz = 1) =>\n  matrix([\n    [sx, 0, 0, 0],\n    [0, sy, 0, 0],\n    [0, 0, sz, 0],\n    [0, 0, 0, 1],\n  ]);\n\nconst scale = (sx = 1, sy = 1) => scale3d(sx, sy);\nconst scaleX = (sx = 1) => scale(sx);\nconst scaleY = (sy = 1) => scale(1, sy);\nconst scaleZ = (sz = 1) => scale3d(1, 1, sz);\n\nconst skew = (alpha = 0, beta = 0) => {\n  const tanAlpha = Math.tan(alpha) || 0;\n  const tanBeta = Math.tan(beta) || 0;\n  return matrix([\n    [1 + tanAlpha * tanBeta, tanAlpha, 0, 0],\n    [tanBeta, 1, 0, 0],\n    [0, 0, 1, 0],\n    [0, 0, 0, 1],\n  ]);\n};\n\nconst skewX = (theta: number) => skew(theta);\nconst skewY = (theta: number) => skew(0, theta);\n\nconst translate3d = (dx = 0, dy = 0, dz = 0) =>\n  matrix([\n    [1, 0, 0, dx],\n    [0, 1, 0, dy],\n    [0, 0, 1, dz],\n    [0, 0, 0, 1],\n  ]);\n\nconst translate = (dx = 0, dy = 0) => translate3d(dx, dy, 0);\nconst translateX = (dx = 0) => translate3d(dx);\nconst translateY = (dy = 0) => translate3d(0, dy);\nconst translateZ = (dz = 0) => translate3d(0, 0, dz);\n\nconst argsTransformMap = {\n  matrix: stringArgsToFloat,\n  matrix3d: stringArgsToFloat,\n  rotate: stringArgsToRadians,\n  rotate3d: (x, y, z, t) => [...stringArgsToFloat(x, y, z), toRadians(t)],\n  rotateX: stringArgsToRadians,\n  rotateY: stringArgsToRadians,\n  rotateZ: stringArgsToRadians,\n  scale: stringArgsToFloat,\n  scale3d: stringArgsToFloat,\n  scaleX: stringArgsToFloat,\n  scaleY: stringArgsToFloat,\n  scaleZ: stringArgsToFloat,\n  skew: stringArgsToRadians,\n  skewX: stringArgsToRadians,\n  skewY: stringArgsToRadians,\n  translate: stringArgsToFloat,\n  translate3d: stringArgsToFloat,\n  translateX: stringArgsToFloat,\n  translateY: stringArgsToFloat,\n  translateZ: stringArgsToFloat,\n};\n\nconst transformMatrixMap = {\n  none: identity,\n  matrix: (l11, l12, dx, l21, l22, dy) =>\n    matrix([\n      [l11, l12, 0, dx],\n      [l21, l22, 0, dy],\n      [0, 0, 1, 0],\n      [0, 0, 0, 1],\n    ]),\n  matrix3d: (\n    m11,\n    m12,\n    m13,\n    m14,\n    m21,\n    m22,\n    m23,\n    m24,\n    m31,\n    m32,\n    m33,\n    m34,\n    m41,\n    m42,\n    m43,\n    m44\n  ) =>\n    matrix([\n      [m11, m12, m13, m14],\n      [m21, m22, m23, m24],\n      [m31, m32, m33, m34],\n      [m41, m42, m43, m44],\n    ]),\n  // perspective: ()=>identity, // TODO\n  rotate: rotateZ,\n  rotateX,\n  rotateY,\n  rotateZ,\n  scale,\n  scale3d,\n  scaleX,\n  scaleY,\n  scaleZ,\n  skew,\n  skewX,\n  skewY,\n  translate,\n  translate3d,\n  translateX,\n  translateY,\n  translateZ,\n};\n\nconst matrixToArray = (m) => m().reduce((acc, v) => [...acc, ...v]);\n\nexport default function (value: string): TPropertyAssignment[] {\n  const calls = getMacroCalls(value);\n  // operations performed right to left\n  // i.e. transform: translateY(20) rotate(90deg)\n  // means rotate 90 degrees, then translate up 20\n  // so we reverse in-place the calls array which initially\n  // has the translation first followed by the rotate.\n  calls.reverse();\n  //@ts-ignore\n  const transformMatrix = calls.reduce((acc, { macro: f, args }) => {\n    if (!transformMatrixMap.hasOwnProperty(f)) {\n      return acc;\n    }\n    const argsTransform = argsTransformMap[f] || (() => args);\n    const transform = transformMatrixMap[f](...argsTransform(...args));\n    return matrix(transform.prod(acc));\n  }, identity);\n  return [[\"transform-matrix\", matrixToArray(transformMatrix)]];\n}\n"
  },
  {
    "path": "packages/react-juce/src/lib/MacroProperties/index.ts",
    "content": "import transformPropertiesGetter from \"./Transform\";\n\nexport const macroPropertyGetters = {\n  transform: transformPropertiesGetter,\n};\n"
  },
  {
    "path": "packages/react-juce/src/lib/MacroProperties/types.d.ts",
    "content": "export type TMacroCall = {\n  macro: string;\n  args: string[];\n};\n\nexport type TPropertyAssignment = [string, string | number];\n"
  },
  {
    "path": "packages/react-juce/src/lib/MacroProperties/util.ts",
    "content": "import { TMacroCall } from \"./types\";\n\n// don't try too hard, we don't need to support qouted strings containing commas etc.\nexport const splitArgs = (a: string) => {\n  const argArray = a.trim().split(/\\s*,\\s*/);\n  if (argArray.length === 1 && argArray[0] === \"\") return [];\n  return argArray;\n};\n\nexport const getMacroCalls = (s: string): TMacroCall[] => {\n  const macroMatcher = String.raw`([a-zA-Z0-9]+)\\(([^)]*)\\)`;\n  let r = new RegExp(macroMatcher, \"g\");\n  // the rest would be trivial with matchAll\n  // which duktape sadly lacks\n  const matches = s.match(r);\n  if (!matches) return [];\n  // unset \"g\" flag, otherwise r.exec returns null when multiple matches occurred\n  r = new RegExp(macroMatcher);\n  const macroCalls = [];\n  for (const match of matches) {\n    // @ts-ignore\n    const [, macro, args] = r.exec(match);\n    macroCalls.push({\n      // @ts-ignore\n      macro,\n      // @ts-ignore\n      args: splitArgs(args),\n    });\n  }\n  return macroCalls;\n};\n"
  },
  {
    "path": "packages/react-juce/src/lib/MethodTracer.ts",
    "content": "//@ts-nocheck\n\nvar inspect = require(\"object-inspect\");\n\n/** An object to be used as an ES6 Proxy handler to trace method calls and\n    undefined property accesses on the target object.\n */\nexport default {\n  get(target, propKey, receiver) {\n    const f = target[propKey];\n\n    if (typeof f === \"undefined\") {\n      console.log(\n        \"MethodTrace: Stubbing undefined property access for\",\n        propKey\n      );\n\n      return function _noop(...args) {\n        console.log(\n          \"MethodTrace Stub:\",\n          propKey,\n          ...args.map((arg) => {\n            return inspect(arg, { depth: 1 });\n          })\n        );\n      };\n    }\n\n    if (typeof f === \"function\") {\n      return function _traced(...args) {\n        console.log(\n          \"MethodTrace:\",\n          propKey,\n          ...args.map((arg) => {\n            return inspect(arg, { depth: 1 });\n          })\n        );\n\n        return f.apply(this, args);\n      };\n    }\n\n    return f;\n  },\n};\n"
  },
  {
    "path": "packages/react-juce/src/lib/NativeMethods.ts",
    "content": "let Native = global[\"__NativeBindings__\"] || {};\nlet DefaultExport = Native;\n\ndeclare var process: {\n  env: {\n    NODE_ENV: string;\n  };\n};\n\nif (process.env.NODE_ENV !== \"production\") {\n  // @ts-ignore\n  DefaultExport = new Proxy(Native, {\n    get: function (target, propKey, receiver) {\n      if (\n        target.hasOwnProperty(propKey) &&\n        typeof target[propKey] === \"function\"\n      ) {\n        return function __NativeMethodWrapper__(...args: any): any {\n          return target[propKey].call(null, ...args);\n        };\n      }\n\n      return function __NativeMethodWrapper__() {\n        console.warn(\n          `WARNING: Attempt to access undefined native method ${target}`\n        );\n      };\n    },\n  });\n}\n\nexport default DefaultExport;\n"
  },
  {
    "path": "packages/react-juce/src/lib/Renderer.ts",
    "content": "import MethodTracer from \"./MethodTracer\";\nimport ReactReconciler from \"react-reconciler\";\nimport Backend, { ViewInstance, RawTextViewInstance } from \"./Backend\";\n\nimport invariant from \"invariant\";\n\ntype HostContext = {\n  isInTextParent: boolean;\n};\n\n//TODO: This should really be types against ReactReconciler.HostConfig with the generics typed out.\nconst HostConfig = {\n  /** Time provider. */\n  now: Date.now,\n\n  /** Indicates to the reconciler that our DOM tree supports mutating operations\n   *  like appendChild, removeChild, etc.\n   */\n  supportsMutation: true,\n\n  /** Provides the context for rendering the root level element.\n   *\n   *  Really only using this and `getChildHostContext` for enforcing nesting\n   *  constraints, such as that raw text content must be a child of a <Text>\n   *  element.\n   */\n  getRootHostContext(rootContainerInstance: ViewInstance): HostContext {\n    return {\n      isInTextParent: false,\n    };\n  },\n\n  /** Provides the context for rendering a child element.\n   */\n  getChildHostContext(\n    parentHostContext: HostContext,\n    elementType: string,\n    rootContainerInstance: ViewInstance\n  ): HostContext {\n    const isInTextParent =\n      parentHostContext.isInTextParent || elementType === \"Text\";\n\n    return { isInTextParent };\n  },\n\n  prepareForCommit: (...args: any) => {},\n  resetAfterCommit: (...args: any) => {\n    Backend.resetAfterCommit();\n  },\n\n  /** Called to determine whether or not a new text value can be set on an\n   *  existing node, or if a new text node needs to be created.\n   *\n   *  This is essentially born from the fact in that in a Web DOM, there are certain\n   *  nodes, such as <textarea>, that support a `textContent` property. Setting the\n   *  node's `textContent` property is different from creating a TextNode and appending\n   *  it to the node's children array. This method signals which option to take.\n   *\n   *  In our case, we return `false` always because we have no nodes in the JUCE\n   *  backend that support this kind of behavior. All text nodes must be created as\n   *  RawTextViewInstances as children of a TextViewInstance.\n   */\n  shouldSetTextContent(elementType: string, props: any) {\n    return false;\n  },\n\n  /** Create a new DOM node. */\n  createInstance(\n    elementType: string,\n    props: any,\n    rootContainerInstance: ViewInstance,\n    hostContext: HostContext,\n    internalInstanceHandle: any\n  ): ViewInstance {\n    invariant(\n      !hostContext.isInTextParent,\n      \"Nesting elements inside of <Text> is currently not supported.\"\n    );\n\n    return Backend.createViewInstance(\n      elementType,\n      props,\n      rootContainerInstance\n    );\n  },\n\n  /** Create a new text node. */\n  createTextInstance(\n    text: string,\n    rootContainerInstance: ViewInstance,\n    hostContext: HostContext,\n    internalInstanceHandle: any\n  ): RawTextViewInstance {\n    invariant(\n      hostContext.isInTextParent,\n      \"Raw text strings must be rendered within a <Text> element.\"\n    );\n\n    return Backend.createTextViewInstance(text, rootContainerInstance);\n  },\n\n  /** Mount the child to its container. */\n  appendInitialChild(parentInstance: ViewInstance, child: ViewInstance): void {\n    parentInstance.appendChild(child);\n  },\n\n  /** For each newly constructed node, once we finish the assignment of children\n   *  this method will be called to finalize the node. We take this opportunity\n   *  to propagate relevant properties to the node.\n   */\n  finalizeInitialChildren(\n    instance: ViewInstance,\n    elementType: string,\n    props: any,\n    rootContainerInstance: ViewInstance\n  ): void {\n    Object.keys(props).forEach(function (propKey) {\n      if (propKey !== \"children\") {\n        instance.setProperty(propKey, props[propKey]);\n      }\n    });\n  },\n\n  /** During a state change, this method will be called to identify the set of\n   *  properties that need to be updated. This is more-or-less an opportunity\n   *  for us to diff our props before propagating.\n   */\n  prepareUpdate(\n    domElement: any,\n    elementType: string,\n    oldProps: any,\n    newProps: any,\n    rootContainerInstance: ViewInstance,\n    hostContext: HostContext\n  ) {\n    // The children prop will be handled separately via the tree update.\n    let { children: oldChildren, ...op } = oldProps;\n    let { children: newChildren, ...np } = newProps;\n\n    // We construct a new payload of property values that are either new or\n    // have changed for this element.\n    let payload: any = {};\n\n    for (let key in np) {\n      if (np.hasOwnProperty(key) && np[key] !== op[key]) {\n        payload[key] = np[key];\n      }\n    }\n\n    return payload;\n  },\n\n  /** Following from `prepareUpdate` above, this is our opportunity to apply\n   *  the update payload to a given instance.\n   */\n  commitUpdate(\n    instance: ViewInstance,\n    updatePayload: any,\n    elementType: string,\n    oldProps: any,\n    newProps: any,\n    internalInstanceHandle: any\n  ): void {\n    Object.keys(updatePayload).forEach(function (propKey: string): void {\n      instance.setProperty(propKey, updatePayload[propKey]);\n    });\n  },\n\n  /** Similar to the previous method, this is our opportunity to apply text\n   *  updates to a given instance.\n   */\n  commitTextUpdate(\n    instance: RawTextViewInstance,\n    oldText: string,\n    newText: string\n  ): void {\n    if (typeof newText === \"string\" && oldText !== newText) {\n      instance.setTextValue(newText);\n    }\n  },\n\n  /** TODO\n   */\n  commitMount(\n    instance: ViewInstance,\n    type: string,\n    newProps: any,\n    internalInstanceHandle: any\n  ): void {\n    // Noop\n  },\n\n  /** Append a child to a parent instance. */\n  appendChild(parentInstance: ViewInstance, child: ViewInstance): void {\n    parentInstance.appendChild(child);\n  },\n\n  /** Append a child to a parent container.\n   *  TODO: Not really sure how this is different from the above.\n   */\n  appendChildToContainer(\n    parentContainer: ViewInstance,\n    child: ViewInstance\n  ): void {\n    parentContainer.appendChild(child);\n  },\n\n  /** Inserts a child node into a parent's children array, just before the\n   *  second given child node.\n   */\n  insertBefore(\n    parentInstance: ViewInstance,\n    child: ViewInstance,\n    beforeChild: ViewInstance\n  ): void {\n    let index = parentInstance.getChildIndex(beforeChild);\n\n    if (index < 0)\n      throw new Error(\n        \"Failed to find child instance for insertBefore operation.\"\n      );\n\n    parentInstance.insertChild(child, index);\n  },\n\n  /** Remove a child from a parent instance. */\n  removeChild(parentInstance: ViewInstance, child: ViewInstance): void {\n    parentInstance.removeChild(child);\n  },\n\n  /** Remove a child from a parent container. */\n  removeChildFromContainer(\n    parentContainer: ViewInstance,\n    child: ViewInstance\n  ): void {\n    parentContainer.removeChild(child);\n  },\n};\n\n//TODO: Applied ts-ignore here as TS complains about missing functions on HostConfig\n//@ts-ignore\nexport default ReactReconciler(HostConfig);\nexport const TracedRenderer = ReactReconciler(\n  new Proxy(HostConfig, MethodTracer)\n);\n"
  },
  {
    "path": "packages/react-juce/src/lib/SyntheticEvents.ts",
    "content": "import { Instance } from \"./Backend\";\n\nexport class SyntheticEvent {\n  public bubbles: boolean;\n  public defaultPrevented: boolean;\n  public target: Instance;\n  private _internal: any;\n\n  constructor(props: any) {\n    this.bubbles = true;\n    this.defaultPrevented = false;\n\n    const { target, ...other } = props;\n    this.target = target;\n\n    this._internal = other;\n  }\n\n  stopPropagation(): void {\n    this.bubbles = false;\n  }\n\n  preventDefault(): void {\n    this.defaultPrevented = true;\n  }\n}\n\nexport class SyntheticMouseEvent extends SyntheticEvent {\n  public x: number;\n  public y: number;\n  public clientX: number;\n  public clientY: number;\n  public screenX: number;\n  public screenY: number;\n  public relatedTarget: Instance;\n\n  constructor(props: any) {\n    super(props);\n\n    this.x = this.clientX = props.x;\n    this.y = this.clientY = props.y;\n    this.screenX = props.screenX;\n    this.screenY = props.screenY;\n    this.relatedTarget = props.relatedTarget;\n  }\n}\n\nexport class SyntheticKeyboardEvent extends SyntheticEvent {\n  public keyCode: number;\n  public key: string;\n\n  constructor(props: any) {\n    super(props);\n\n    this.keyCode = props.keyCode;\n    this.key = props.key;\n  }\n}\n\nexport default {\n  isMouseEventHandler(key: string): boolean {\n    const k = key.toLowerCase();\n\n    return (\n      k === \"onmousedown\" ||\n      k == \"onmouseup\" ||\n      k == \"onmouseenter\" ||\n      k == \"onmouseleave\" ||\n      k == \"onmousedrag\" ||\n      k == \"onmouseclick\"\n    );\n  },\n\n  isKeyboardEventHandler(key: string): boolean {\n    const k = key.toLowerCase();\n\n    return k === \"onkeydown\" || k == \"onkeyup\" || k == \"onkeypress\";\n  },\n};\n"
  },
  {
    "path": "packages/react-juce/template/.gitignore",
    "content": "# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.\n\n# dependencies\n/node_modules\n/.pnp\n.pnp.js\n\n# testing\n/coverage\n\n# production\n/build\n\n# misc\n.DS_Store\n.env.local\n.env.development.local\n.env.test.local\n.env.production.local\n\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n"
  },
  {
    "path": "packages/react-juce/template/babel.config.js",
    "content": "module.exports = {\n  presets: [\n    [\n      \"@babel/preset-env\",\n      {\n        modules: \"umd\",\n      },\n    ],\n    \"@babel/preset-react\",\n  ],\n  plugins: [\n    \"@babel/plugin-proposal-class-properties\",\n    [\n      \"@babel/plugin-transform-runtime\",\n      {\n        absoluteRuntime: false,\n        corejs: 3,\n        version: \"7.11.2\",\n      },\n    ],\n  ],\n};\n"
  },
  {
    "path": "packages/react-juce/template/package.json",
    "content": "{\n  \"name\": \"ui\",\n  \"version\": \"0.1.0\",\n  \"private\": true,\n  \"dependencies\": {\n    \"@babel/runtime-corejs3\": \"^7.10.3\",\n    \"react-juce\": \"^0.2.10\",\n    \"react\": \"^16.6.3\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.2.0\",\n    \"@babel/plugin-proposal-class-properties\": \"^7.10.4\",\n    \"@babel/plugin-transform-runtime\": \"^7.10.3\",\n    \"@babel/preset-env\": \"^7.2.0\",\n    \"@babel/preset-react\": \"^7.0.0\",\n    \"babel-loader\": \"^8.0.4\",\n    \"svg-inline-loader\": \"^0.8.0\",\n    \"webpack\": \"^4.27.1\",\n    \"webpack-cli\": \"^3.1.2\"\n  },\n  \"scripts\": {\n    \"start\": \"webpack -w --mode=development\",\n    \"build\": \"webpack --mode=production\"\n  }\n}\n"
  },
  {
    "path": "packages/react-juce/template/src/App.js",
    "content": "import React, { Component } from \"react\";\nimport { View, Text } from \"react-juce\";\n\nclass App extends Component {\n  render() {\n    return (\n      <View {...styles.container}>\n        <View {...styles.content}>\n          <Text {...styles.text}>Hello from React.js!</Text>\n        </View>\n      </View>\n    );\n  }\n}\n\nconst styles = {\n  container: {\n    width: \"100%\",\n    height: \"100%\",\n    \"background-color\": \"ff17191f\",\n  },\n  content: {\n    flex: 1.0,\n    \"justify-content\": \"center\",\n    \"align-items\": \"center\",\n  },\n  text: {\n    \"font-size\": 18.0,\n    \"line-spacing\": 1.6,\n    color: \"ff626262\",\n  },\n};\n\nexport default App;\n"
  },
  {
    "path": "packages/react-juce/template/src/index.js",
    "content": "import React from \"react\";\nimport ReactJUCE from \"react-juce\";\nimport App from \"./App\";\n\nReactJUCE.render(<App />, ReactJUCE.getRootContainer());\n"
  },
  {
    "path": "packages/react-juce/template/webpack.config.js",
    "content": "module.exports = {\n  entry: \"./src/index.js\",\n  output: {\n    path: __dirname + \"/build/js\",\n    filename: \"main.js\",\n    sourceMapFilename: \"[file].map\",\n    devtoolModuleFilenameTemplate: (info) =>\n      `webpack:///${info.absoluteResourcePath.replace(/\\\\/g, \"/\")}`,\n  },\n  devtool: \"source-map\",\n  module: {\n    rules: [\n      {\n        test: /\\.(js|jsx)$/,\n        exclude: /node_modules/,\n        use: [\"babel-loader\"],\n      },\n      {\n        test: /\\.svg$/,\n        exclude: /node_modules/,\n        use: [\"svg-inline-loader\"],\n      },\n    ],\n  },\n};\n"
  },
  {
    "path": "packages/react-juce/tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"module\": \"commonjs\",\n    \"target\": \"es6\",\n    \"lib\": [\"es2015\", \"dom\"],\n    \"declaration\": true,\n    \"sourceMap\": true,\n    \"isolatedModules\": true,\n    \"esModuleInterop\": true,\n    \"allowJs\": true,\n    \"noImplicitAny\": false,\n    \"strict\": true,\n    \"strictNullChecks\": true,\n    \"skipLibCheck\": true,\n    \"jsx\": \"react\"\n  },\n  \"include\": [\"./src/**/*\"]\n}\n"
  },
  {
    "path": "packages/react-juce/webpack.config.js",
    "content": "const path = require(\"path\");\n\nmodule.exports = (env) => {\n  return {\n    entry: \"./src/index.tsx\",\n    output: {\n      path: path.resolve(__dirname, \"dist\"),\n      filename: \"index.js\",\n      libraryTarget: \"umd\",\n      globalObject: \"this\",\n      sourceMapFilename: \"[file].map\",\n      devtoolModuleFilenameTemplate: \"webpack:///[absolute-resource-path]\",\n    },\n    externals: {\n      react: {\n        root: \"React\",\n        commonjs2: \"react\",\n        commonjs: \"react\",\n        amd: \"react\",\n      },\n    },\n    target: [\"web\", \"es5\"],\n    devtool: \"source-map\",\n    resolve: {\n      extensions: [\".ts\", \".tsx\", \".js\"],\n    },\n    module: {\n      rules: [\n        {\n          test: /\\.tsx?$/,\n          exclude: path.resolve(__dirname, \"node_modules\"),\n          use: [\n            {\n              loader: \"awesome-typescript-loader\",\n              options: {\n                useBabel: true,\n                babelCore: \"@babel/core\",\n                declarationDir: path.resolve(__dirname, \"dist\"),\n              },\n            },\n          ],\n        },\n        {\n          test: /\\.js$/,\n          include: [\n            path.resolve(__dirname, \"node_modules\", \"matrix-js\"),\n            path.resolve(__dirname, \"node_modules\", \"camelcase\"),\n          ],\n          use: [\n            {\n              loader: \"awesome-typescript-loader\",\n              options: {\n                useBabel: true,\n                babelCore: \"@babel/core\",\n              },\n            },\n          ],\n        },\n        {\n          test: /\\.svg$/,\n          exclude: path.resolve(__dirname, \"node_modules\"),\n          use: [\"svg-inline-loader\"],\n        },\n      ],\n    },\n    watchOptions: {\n      ignored: [\n        path.resolve(__dirname, \"dist\"),\n        path.resolve(__dirname, \"node_modules\"),\n      ],\n    },\n  };\n};\n"
  },
  {
    "path": "react_juce/core/AppHarness.cpp",
    "content": "/*\n  ==============================================================================\n\n    AppHarness.cpp\n    Created: 21 Nov 2020 11:27:37am\n\n  ==============================================================================\n*/\n\n#include \"AppHarness.h\"\n\n\nnamespace reactjuce\n{\n\n    //==============================================================================\n    AppHarness::AppHarness(ReactApplicationRoot& _appRoot)\n        : appRoot(_appRoot)\n    {\n        JUCE_ASSERT_MESSAGE_THREAD\n        fileWatcher = std::make_unique<FileWatcher>([this]() { handleFilesChanged(); });\n    }\n\n    //==============================================================================\n    void AppHarness::watch (const juce::File& f)\n    {\n        if (fileWatcher)\n        {\n            sourceFileTypeMap[f.getFullPathName()] = false;\n            fileWatcher->watch(f);\n        }\n    }\n\n    void AppHarness::watch (const std::vector<juce::File>& fs)\n    {\n        if (fileWatcher)\n        {\n            for (const auto& f : fs)\n                watch(f);\n        }\n    }\n\n    void AppHarness::watchBytecode (const juce::File& f)\n    {\n        if (fileWatcher)\n        {\n            sourceFileTypeMap[f.getFullPathName()] = true;\n            fileWatcher->watch(f);\n        }\n    }\n\n    void AppHarness::watchBytecode (const std::vector<juce::File>& fs)\n    {\n        if (fileWatcher)\n        {\n            for (const auto& f : fs)\n                watchBytecode(f);\n        }\n    }\n\n    void AppHarness::start()\n    {\n        // Nothing to do if we haven't watched any files\n        if (fileWatcher == nullptr)\n            return;\n\n        // Run initial callbacks and file eval.\n        handleFilesChanged();\n\n        // Finally, kick off the file watch process\n        fileWatcher->start();\n    }\n\n    void AppHarness::stop()\n    {\n        if (fileWatcher)\n            fileWatcher->stop();\n    }\n\n    void AppHarness::once()\n    {\n        // Nothing to do if we haven't watched any files\n        if (fileWatcher == nullptr)\n            return;\n\n        // Run callback and eval step once.\n        handleFilesChanged();\n    }\n\n    void AppHarness::handleFilesChanged()\n    {\n        appRoot.reset();\n        appRoot.bindNativeRenderingHooks();\n\n        if (onBeforeAll) { onBeforeAll(); }\n\n        for (const auto& f : fileWatcher->getWatchedFiles())\n        {\n            if (onBeforeEach) { onBeforeEach(f); }\n\n            try\n            {\n                const bool isBytecode = sourceFileTypeMap[f.getFullPathName()];\n\n                if (isBytecode)\n                    appRoot.evaluateBytecode(f);\n                else\n                    appRoot.evaluate(f);\n            }\n            catch (const EcmascriptEngine::Error& err)\n            {\n                // We may fall in here in Release builds when ReactApplicationRoot hasn't\n                // caught the error for us to show the red screen. In this case, we call\n                // a user supplied error handler if we have one, else just break the loop\n                // and await the next file change event.\n                if (onEvalError)\n                {\n                    onEvalError(err);\n                    break;\n                }\n                else\n                {\n                    throw err;\n                }\n            }\n\n            if (onAfterEach) { onAfterEach(f); }\n        }\n\n        if (onAfterAll) { onAfterAll(); }\n    }\n\n}\n"
  },
  {
    "path": "react_juce/core/AppHarness.h",
    "content": "/*\n  ==============================================================================\n\n    AppHarness.h\n    Created: 21 Nov 2020 11:27:37am\n\n  ==============================================================================\n*/\n\n#pragma once\n\n#include \"EcmascriptEngine.h\"\n#include \"FileWatcher.h\"\n#include \"ReactApplicationRoot.h\"\n\n\nnamespace reactjuce\n{\n\n    /** The AppHarness is a simple class which composes over your ReactApplicationRoot\n     *  to provide file watching and hot reloading behavior for the bundle files your app evaluates.\n     *\n     *  To use, you should only need to make a AppHarness, set it to `watch()` any\n     *  of your files, and then call `start()` (called automatically in Debug builds).\n     *\n     *  For custom behavior, you can attach callbacks at each of the four reloading stages:\n     *    onBeforeAll – Invoked before evaluating any watched bundle\n     *    onBeforeEach – Invoked before evaluating each watched bundle\n     *    onAfterEach – Invoked after evaluating each watched bundle\n     *    onAfterAll – Invoked after evaluating all watched bundles\n     *    onEvalError – Invoked for an uncaught exception during bundle evaluation\n     */\n    class AppHarness\n    {\n    public:\n        //==============================================================================\n        explicit AppHarness(ReactApplicationRoot& _appRoot);\n\n        //==============================================================================\n        /** Add JS bundle file to be watched/managed by the AppHarness.  */\n        void watch (const juce::File& f);\n        void watch (const std::vector<juce::File>& fs);\n\n        void watchBytecode (const juce::File& f);\n        void watchBytecode (const std::vector<juce::File>& fs);\n\n        /** Run the initial evaluation step and then watch for file changes. */\n        void start();\n\n        /** Stop any running file watch. */\n        void stop();\n\n        /** Run the initial evaluation step exactly once.\n         *\n         *  It may be helpful to use AppHarness::start in DEBUG builds when you want\n         *  hot reloading for development, then switch in RELEASE builds to using\n         *  AppHarness::once to ignore file watching when you don't need it.\n         */\n        void once();\n\n        //==============================================================================\n        /**\n         * Called once, after a file change is detected, before any watched bundle is evaluated.\n         *\n         * Often this callback will be used to install custom native methods and properties\n         * that the code in the bundle will expect to find when it's evaluated.\n         *\n         * @code\n         *\n         *  MyEditor()\n         *     : engine(std::make_shared<EcmascriptEngine>())\n         *     , appRoot(engine)\n         *     , harness(appRoot)\n         * {\n         *     juce::File myAppBundle(\"/path/to/myAppBundle.js\");\n         *\n         *     harness.onBeforeAll = [=]() {\n         *         engine->registerNativeMethod(\n         *             \"myNativeMethod\",\n         *             [this](const juce::var::NativeFunctionArgs& args) {\n         *                 const juce::String& someParam = args.arguments[0].toString();\n         *                 myMethod(someParam);\n         *                 return juce::var::undefined();\n         *             }\n         *         );\n         *     };\n         *\n         *     harness.watch(myAppBundle);\n         *\n         *     // Not strictly required if JUCE_DEBUG set.\n         *     harness.start();\n         * }\n         *\n         * @endcode\n         **/\n        std::function<void(void)> onBeforeAll;\n\n        /**\n         * Called after `onBeforeAll` immediately before evaluating each of the watched bundles.\n         *\n         * This callback may be used to assign specific behavior that must be invoked\n         * before a watched bundle is evaluated, but in such a way that depends on\n         * which bundle is being evaluated and when.\n         *\n         * @code\n         *\n         *  MyEditor()\n         *     : engine(std::make_shared<EcmascriptEngine>())\n         *     , appRoot(engine)\n         *     , harness(appRoot)\n         * {\n         *     juce::File myAppBundle(\"/path/to/myAppBundle.js\");\n         *\n         *     harness.onBeforeEach = [=](const juce::File& bundle) {\n         *         if (bundle == myAppBundle) {\n         *             engine->registerNativeMethod(\n         *                 \"myNativeMethod\",\n         *                 [this](const juce::var::NativeFunctionArgs& args) {\n         *                     const juce::String& someParam = args.arguments[0].toString();\n         *                     myMethod(someParam);\n         *                     return juce::var::undefined();\n         *                 }\n         *             );\n         *         }\n         *     };\n         *\n         *     harness.watch(myAppBundle);\n         *\n         *     // Not strictly required if JUCE_DEBUG set.\n         *     harness.start();\n         * }\n         *\n         * @endcode\n         **/\n        std::function<void(const juce::File&)> onBeforeEach;\n\n        /**\n         * Called after `onBeforeEach` immediately after evaluating each of the watched bundles.\n         *\n         * This callback may be used to assign specific behavior that must be invoked\n         * after a watched bundle is evaluated, but in such a way that depends on\n         * which bundle hs been evaluated.\n         *\n         * @code\n         *\n         *  MyEditor()\n         *     : engine(std::make_shared<EcmascriptEngine>())\n         *     , appRoot(engine)\n         *     , harness(appRoot)\n         * {\n         *     juce::File myAppBundle(\"/path/to/myAppBundle.js\");\n         *\n         *     harness.onAfterEach = [=](const juce::File& bundle) {\n         *         if (bundle == myAppBundle) {\n         *             engine->invoke(\"MyBundlePlacedThisHere\", 42);\n         *         }\n         *     };\n         *\n         *     harness.watch(myAppBundle);\n         *\n         *     // Not strictly required if JUCE_DEBUG set.\n         *     harness.start();\n         * }\n         *\n         * @endcode\n         **/\n        std::function<void(const juce::File&)> onAfterEach;\n\n        /**\n         * Called once, after all the watched files have been evaluated and all the\n         * prior callbacks have been invoked.\n         *\n         * Often this callback will be used to dispatch events or values into an\n         * application that is expecting some initial state.\n         *\n         * @code\n         *\n         *  MyEditor()\n         *     : engine(std::make_shared<EcmascriptEngine>())\n         *     , appRoot(engine)\n         *     , harness(appRoot)\n         * {\n         *     juce::File myAppBundle(\"/path/to/myAppBundle.js\");\n         *\n         *     harness.onAfterAll = [=]() {\n         *         appRoot.dispatchEvent(\"InitialParameterState, getInitialParamState());\n         *     };\n         *\n         *     harness.watch(myAppBundle);\n         *\n         *     // Not strictly required if JUCE_DEBUG set.\n         *     harness.start();\n         * }\n         *\n         * @endcode\n         **/\n        std::function<void(void)> onAfterAll;\n\n        /**\n         * Called for any uncaught exception during bundle evaluation.\n         *\n         * @code\n         *\n         *  MyEditor()\n         *     : engine(std::make_shared<EcmascriptEngine>())\n         *     , appRoot(engine)\n         *     , harness(appRoot)\n         * {\n         *     juce::File myAppBundle(\"/path/to/myAppBundle.js\");\n         *\n         *     harness.onEvalError = [=](const EcmascriptEngine::Error& e) {\n         *         logError(e.what());\n         *     };\n         *\n         *     harness.watch(myAppBundle);\n         *     harness.start();\n         * }\n         *\n         * @endcode\n         **/\n        std::function<void(const EcmascriptEngine::Error&)> onEvalError;\n\n    private:\n        //==============================================================================\n        void handleFilesChanged();\n\n        //==============================================================================\n        ReactApplicationRoot&                  appRoot;\n        std::unique_ptr<FileWatcher>           fileWatcher;\n        std::unordered_map<juce::String, bool> sourceFileTypeMap;\n\n        //==============================================================================\n        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AppHarness)\n    };\n\n}\n"
  },
  {
    "path": "react_juce/core/CanvasView.cpp",
    "content": "/*\n  ==============================================================================\n\n    CanvasView.cpp\n    Created: 23 Jan 2021 21:45:00pm\n\n  ==============================================================================\n*/\n\n#include \"CanvasView.h\"\n\nnamespace reactjuce\n{\n    namespace\n    {\n        void setFillStyle(CanvasView::CanvasContext           &ctx,\n                          juce::Graphics                      &g,\n                          const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 1);\n            juce::ignoreUnused(g);\n\n            //TODO: Implement fillStyle pattern\n            //TODO: Implement fillStyle gradient\n\n            const auto colourHex = args.arguments[0].toString();\n            ctx.properties.fillStyle.setColour(juce::Colour::fromString(colourHex));\n        }\n\n        void setStrokeStyle(CanvasView::CanvasContext           &ctx,\n                            juce::Graphics                      &g,\n                            const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 1);\n            juce::ignoreUnused(g);\n\n            //TODO: Implement strokeStyle pattern\n            //TODO: Implement stokeStyle gradient\n\n            const auto colourHex = args.arguments[0].toString();\n            ctx.properties.strokeStyle.setColour(juce::Colour::fromString(colourHex));\n        }\n\n        void setLineWidth(CanvasView::CanvasContext           &ctx,\n                          juce::Graphics                      &g,\n                          const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 1);\n            juce::ignoreUnused(g);\n\n            const int lineWidth = args.arguments[0];\n            ctx.properties.lineWidth = lineWidth;\n        }\n\n        /**\n         * TODO: Should this be pushed out into some sort of generic helpers namespace for parsing\n         *       CSS like props?\n         *\n         *       i.e juce::Font parseCSSFontString(const juce::String &font);\n         *\n         *\n         * Currently supports space separated css-font like strings with the below  supported format/properties:\n         *\n         *  \"<font-style> <font-weight> <font-size> <font-family>\"\n         *\n         *  One of the following values may be supplied for each font property.\n         *\n         *  <font-style>:  italic, normal\n         *  <font-weight>: bold, normal\n         *  <font-size>:   font size in pixels, i.e. \"14px\"\n         *  <font-family>: font name representing an available font/typeface on the system, i.e. \"sans-serif\"\n         *\n         *  Note, font-size and font-family must be supplied in the string from JS but font-style and font-weight\n         *  are optional, though they must precede font-size and font-family and be ordered font-style, font-weight.\n         *  If no values are supplied for font-style and font-weight the juce::Font::plain flag will be used.\n         *\n         *  Example font strings from JS bundle:\n         *\n         *  'italic bold 14px sans-serif'\n         *  'bold 14px sans-serif'\n         *  'italic 14px sans-serif'\n         *  '14px sans-serif'\n         *\n         *  Note, multi-word/space-separated strings should be place in quotes:\n         *\n         *  'bold 14px \"DejaVu Serif\"'\n         * */\n        void setFont(CanvasView::CanvasContext          &ctx,\n                    juce::Graphics                      &g,\n                    const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 1);\n            juce::ignoreUnused(g);\n\n            auto fontString = args.arguments[0].toString();\n            auto values = juce::StringArray::fromTokens (fontString, juce::StringRef (\" \"), {});\n\n            jassert(values.size() >=2 && values.size() <= 4);\n\n            juce::Font::FontStyleFlags flags    = juce::Font::plain;\n            float                      fontSize = 0;\n            juce::String               typeface;\n\n            for (auto& value : values)\n            {\n                // Remove any quoted values likely used when specifying fonts\n                value = value.unquoted();\n\n                if (value == \"bold\")\n                {\n                    flags = static_cast<juce::Font::FontStyleFlags>(flags | juce::Font::bold);\n                }\n                else if (value == \"italic\")\n                {\n                    flags = static_cast<juce::Font::FontStyleFlags>(flags | juce::Font::italic);\n                }\n                else if (value.contains(\"px\"))\n                {\n                    fontSize = (float)value.getIntValue();\n                }\n                else if (value != \"normal\")\n                {\n                    typeface = value;\n                }\n            }\n\n            ctx.properties.font = juce::Font(typeface, fontSize, flags);\n        }\n\n        void setTextAlign(CanvasView::CanvasContext           &ctx,\n                          juce::Graphics                      &g,\n                          const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 1);\n            juce::ignoreUnused(g);\n\n            const juce::String textAlign = args.arguments[0].toString();\n\n            //TODO: Have \"start\" and \"end\" depend on a \"direction\" property.\n            //      Leaving with sensible defaults for now. No clear way\n            //      to provide/infer text direction from locale at the moment etc.\n            if (textAlign == \"left\")\n                ctx.properties.textAlign = juce::Justification::left;\n            else if (textAlign == \"right\")\n                ctx.properties.textAlign = juce::Justification::right;\n            else if (textAlign == \"center\")\n                ctx.properties.textAlign = juce::Justification::horizontallyCentred;\n            else if (textAlign == \"start\")\n                ctx.properties.textAlign = juce::Justification::left;\n            else if (textAlign == \"end\")\n                ctx.properties.textAlign = juce::Justification::right;\n        }\n\n        /** void rect(CanvasView::CanvasContext &ctx, juce::Graphics &g, const juce::var::NativeFunctionArgs &args) */\n        /** { */\n        /**     jassert(args.numArguments == 4); */\n\n        /**     const float x = args.arguments[0]; */\n        /**     const float y = args.arguments[1]; */\n        /**     const float width = args.arguments[2]; */\n        /**     const float height = args.arguments[3]; */\n\n        /**     // TODO: For some reason this operation closes the current path. */\n        /**     //       The API docs suggest addRectangle should be added as a new sub-path */\n        /**     //       leaving the previous path open. */\n        /**     //       Fix. */\n        /**     ctx.path.addRectangle(x, y, width, height); */\n        /** } */\n\n        void fillRect(CanvasView::CanvasContext           &ctx,\n                      juce::Graphics                      &g,\n                      const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 4);\n\n            const int x      = args.arguments[0];\n            const int y      = args.arguments[1];\n            const int width  = args.arguments[2];\n            const int height = args.arguments[3];\n\n            g.setFillType(ctx.properties.fillStyle);\n            g.fillRect(x, y, width, height);\n        }\n\n        void strokeRect(CanvasView::CanvasContext           &ctx,\n                        juce::Graphics                      &g,\n                        const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 4);\n\n            const int x = args.arguments[0];\n            const int y = args.arguments[1];\n            const int width = args.arguments[2];\n            const int height = args.arguments[3];\n\n            g.setColour(ctx.properties.strokeStyle.colour);\n            g.drawRect(x, y, width, height, ctx.properties.lineWidth);\n        }\n\n        void strokeRoundedRect(CanvasView::CanvasContext           &ctx,\n                               juce::Graphics                      &g,\n                               const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 5);\n\n            const float x = args.arguments[0];\n            const float y = args.arguments[1];\n            const float width = args.arguments[2];\n            const float height = args.arguments[3];\n            const float cornerSize = args.arguments[4];\n\n            g.setColour(ctx.properties.strokeStyle.colour);\n\n            g.drawRoundedRectangle(x,\n                                   y,\n                                   width,\n                                   height,\n                                   cornerSize,\n                                   (float)ctx.properties.lineWidth);\n        }\n\n        void fillRoundedRect(CanvasView::CanvasContext           &ctx,\n                             juce::Graphics                      &g,\n                             const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 5);\n\n            const float x = args.arguments[0];\n            const float y = args.arguments[1];\n            const float width = args.arguments[2];\n            const float height = args.arguments[3];\n            const float cornerSize = args.arguments[4];\n\n            g.setFillType(ctx.properties.fillStyle);\n            g.fillRoundedRectangle(x, y, width, height, cornerSize);\n        }\n\n        void clearRect(CanvasView::CanvasContext           &ctx,\n                       juce::Graphics                      &g,\n                       const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 4);\n            juce::ignoreUnused(ctx);\n\n            const int x = args.arguments[0];\n            const int y = args.arguments[1];\n            const int width = args.arguments[2];\n            const int height = args.arguments[3];\n\n            juce::Rectangle<int> area (x, y, width, height);\n\n            // Set fill color to transparent black\n            g.setColour({});\n            g.fillRect(area);\n        }\n\n        void beginPath(CanvasView::CanvasContext           &ctx,\n                       juce::Graphics                      &g,\n                       const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 0);\n            juce::ignoreUnused(args);\n            juce::ignoreUnused(g);\n\n            // Reset the current path on a call to beginPath on the context.\n            ctx.path = juce::Path();\n        }\n\n        void lineTo(CanvasView::CanvasContext           &ctx,\n                    juce::Graphics                      &g,\n                    const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 2);\n            juce::ignoreUnused(g);\n\n            const float x = args.arguments[0];\n            const float y = args.arguments[1];\n\n            ctx.path.lineTo(x, y);\n        }\n\n        void moveTo(CanvasView::CanvasContext           &ctx,\n                    juce::Graphics                      &g,\n                    const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 2);\n            juce::ignoreUnused(g);\n\n            const float x = args.arguments[0];\n            const float y = args.arguments[1];\n\n            ctx.path.startNewSubPath(x, y);\n        }\n\n        void arc(CanvasView::CanvasContext           &ctx,\n                 juce::Graphics                      &g,\n                 const juce::var::NativeFunctionArgs &args)\n        {\n            // CanvasRenderingContext2D.arc() uses default antiClockWise false arg\n            jassert(args.numArguments >= 5 && args.numArguments <= 6);\n            juce::ignoreUnused(g);\n\n            const float x             = args.arguments[0];\n            const float y             = args.arguments[1];\n            const float radius        = args.arguments[2];\n            const float startAngle    = args.arguments[3];\n            const float endAngle      = args.arguments[4];\n            //TODO; Handle antiClockWise\n            //bool        antiClockWise = args.arguments[5];\n\n            ctx.path.addCentredArc(x, y, radius, radius, 0.0f, startAngle, endAngle, false);\n        }\n\n        void quadraticCurveTo(CanvasView::CanvasContext           &ctx,\n                              juce::Graphics                      &g,\n                              const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 4);\n            juce::ignoreUnused(g);\n\n            const float controlPointX = args.arguments[0];\n            const float controlPointY = args.arguments[1];\n            const float endPointX     = args.arguments[2];\n            const float endPointY     = args.arguments[3];\n\n            ctx.path.quadraticTo(controlPointX, controlPointY, endPointX, endPointY);\n        }\n\n        void closePath(CanvasView::CanvasContext           &ctx,\n                       juce::Graphics                      &g,\n                       const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 0);\n            juce::ignoreUnused(args);\n            juce::ignoreUnused(g);\n\n            ctx.path.closeSubPath();\n        }\n\n        void stroke(CanvasView::CanvasContext           &ctx,\n                    juce::Graphics                      &g,\n                    const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 0);\n            juce::ignoreUnused(args);\n\n            g.setColour(ctx.properties.strokeStyle.colour);\n            g.strokePath(ctx.path, juce::PathStrokeType((float)ctx.properties.lineWidth));\n        }\n\n        void fill(CanvasView::CanvasContext           &ctx,\n                  juce::Graphics                      &g,\n                  const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 0);\n            juce::ignoreUnused(args);\n\n            g.setColour(ctx.properties.fillStyle.colour);\n            g.fillPath(ctx.path);\n        }\n\n        void rotate(CanvasView::CanvasContext           &ctx,\n                    juce::Graphics                      &g,\n                    const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 1);\n\n            const float angle = args.arguments[0];\n\n            auto transform = juce::AffineTransform::rotation(angle);\n            g.addTransform(transform);\n            ctx.transformStack.push_back(transform.inverted());\n        }\n\n        void translate(CanvasView::CanvasContext           &ctx,\n                       juce::Graphics                      &g,\n                       const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 2);\n\n            const float x = args.arguments[0];\n            const float y = args.arguments[1];\n\n            auto transform = juce::AffineTransform::translation(x, y);\n            g.addTransform(transform);\n            ctx.transformStack.push_back(transform.inverted());\n        }\n\n        void setTransform(CanvasView::CanvasContext           &ctx,\n                          juce::Graphics                      &g,\n                          const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 6);\n\n            const float mat00 = args.arguments[0];\n            const float mat01 = args.arguments[1];\n            const float mat02 = args.arguments[2];\n            const float mat10 = args.arguments[3];\n            const float mat11 = args.arguments[4];\n            const float mat12 = args.arguments[5];\n\n            auto transform = juce::AffineTransform(mat00, mat01, mat02, mat10, mat11, mat12);\n            g.addTransform(transform);\n            ctx.transformStack.push_back(transform.inverted());\n        }\n\n        void resetTransform(CanvasView::CanvasContext           &ctx,\n                            juce::Graphics                      &g,\n                            const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments == 0);\n            juce::ignoreUnused(args);\n\n            while (!ctx.transformStack.empty())\n            {\n                g.addTransform(ctx.transformStack.back());\n                ctx.transformStack.pop_back();\n            }\n\n            ctx.transformStack.clear();\n        }\n\n        void drawImage(CanvasView::CanvasContext           &ctx,\n                       juce::Graphics                      &g,\n                       const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments >= 3 && args.numArguments <= 5);\n            juce::ignoreUnused(ctx);\n\n            const juce::String svg  = args.arguments[0].toString();\n            const float        xPos = args.arguments[1];\n            const float        yPos = args.arguments[2];\n\n            //TODO: Add support for drawimage source width and source height to draw sub rect of an image.\n            //      ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);\n\n            std::unique_ptr<juce::XmlElement> svgElement(juce::XmlDocument::parse(svg));\n\n            if (!svgElement)\n            {\n                DBG(\"\\\"WARNING: Invalid SVG string supplied to `drawImage`.\\\"\");\n                return;\n            }\n\n            std::unique_ptr<juce::Drawable> svgDrawable(juce::Drawable::createFromSVG(*svgElement));\n\n            if (args.numArguments == 5)\n            {\n                const float destWidth  = args.arguments[3];\n                const float destHeight = args.arguments[4];\n                const auto  bounds     = juce::Rectangle<float>(xPos, yPos, destWidth, destHeight);\n\n                svgDrawable->setTransformToFit(bounds, juce::RectanglePlacement::stretchToFit);\n                svgDrawable->draw(g, 1.0f);\n            }\n            else\n            {\n                svgDrawable->drawAt(g, xPos, yPos, 1.0);\n            }\n        }\n\n        void strokeText(CanvasView::CanvasContext           &ctx,\n                        juce::Graphics                      &g,\n                        const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments >= 3 && args.numArguments <= 4);\n\n            const juce::String text = args.arguments[0].toString();\n            const float        xPos = args.arguments[1];\n            const float        yPos = args.arguments[2];\n\n            // Default maxLineWidth to full context width\n            float maxLineWidth = (float)ctx.width;\n\n            if (args.numArguments == 4)\n                maxLineWidth = args.arguments[3];\n\n            juce::Path textPath;\n            juce::GlyphArrangement glyphArrangement;\n\n            glyphArrangement.addJustifiedText(ctx.properties.font,\n                                              text,\n                                              xPos,\n                                              yPos,\n                                              maxLineWidth,\n                                              ctx.properties.textAlign);\n\n            glyphArrangement.createPath(textPath);\n\n            g.setColour(ctx.properties.strokeStyle.colour);\n            g.strokePath(textPath, juce::PathStrokeType((float)ctx.properties.lineWidth));\n        }\n\n        void fillText(CanvasView::CanvasContext           &ctx,\n                      juce::Graphics                      &g,\n                      const juce::var::NativeFunctionArgs &args)\n        {\n            jassert(args.numArguments >= 3 && args.numArguments <= 4);\n\n            const juce::String text = args.arguments[0].toString();\n            const float        xPos = args.arguments[1];\n            const float        yPos = args.arguments[2];\n\n            // Default maxLineWidth to full context width\n            float maxLineWidth = (float)ctx.width;\n\n            if (args.numArguments == 4)\n                maxLineWidth = args.arguments[3];\n\n            juce::Path textPath;\n            juce::GlyphArrangement glyphArrangement;\n\n            glyphArrangement.addJustifiedText(ctx.properties.font,\n                                              text,\n                                              xPos,\n                                              yPos,\n                                              maxLineWidth,\n                                              ctx.properties.textAlign);\n\n            glyphArrangement.createPath(textPath);\n\n            g.setFillType(ctx.properties.fillStyle);\n            g.fillPath(textPath);\n        }\n\n        using DrawCommand = std::function<void(CanvasView::CanvasContext&,\n                                               juce::Graphics&,\n                                               const juce::var::NativeFunctionArgs&)>;\n\n        std::unordered_map<juce::String, DrawCommand> DrawCommands\n        {\n            { \"setFillStyle\"      , setFillStyle      },\n            { \"setStrokeStyle\"    , setStrokeStyle    },\n            { \"setLineWidth\"      , setLineWidth      },\n            { \"setFont\"           , setFont           },\n            { \"setTextAlign\"      , setTextAlign      },\n            { \"fillRect\"          , fillRect          },\n            { \"strokeRect\"        , strokeRect        },\n            { \"strokeRoundedRect\" , strokeRoundedRect },\n            { \"fillRoundedRect\"   , fillRoundedRect   },\n            { \"clearRect\"         , clearRect         },\n            { \"beginPath\"         , beginPath         },\n            { \"lineTo\"            , lineTo            },\n            { \"moveTo\"            , moveTo            },\n            { \"arc\"               , arc               },\n            { \"quadraticCurveTo\"  , quadraticCurveTo  },\n            { \"closePath\"         , closePath         },\n            { \"stroke\"            , stroke            },\n            { \"fill\"              , fill              },\n            { \"rotate\"            , rotate            },\n            { \"translate\"         , translate         },\n            { \"setTransform\"      , setTransform      },\n            { \"resetTransform\"    , resetTransform    },\n            { \"drawImage\"         , drawImage         },\n            { \"strokeText\"        , strokeText        },\n            { \"fillText\"          , fillText          },\n        };\n    }\n\n    //==============================================================================\n    void CanvasView::processDrawCommands(CanvasContext  &ctx,\n                                        juce::Graphics  &g,\n                                        const juce::var &drawCommands)\n    {\n        jassert(drawCommands.isArray());\n\n        for (juce::var &command : *drawCommands.getArray())\n        {\n            jassert(command.isArray());\n            jassert(command.getArray()->size() >= 1);\n\n            const auto args = command.getArray();\n            const auto name = (*args)[0];\n\n            if (auto it = DrawCommands.find(name); it != DrawCommands.end())\n            {\n                it->second(ctx,\n                           g,\n                           juce::var::NativeFunctionArgs(juce::var(),\n                                                         args->getRawDataPointer() + 1,\n                                                         args->size() - 1));\n            }\n        }\n    }\n\n    //==============================================================================\n    CanvasView::CanvasView()\n        : canvasImage(juce::Image::ARGB, 1, 1, true)\n    {\n\n    }\n\n    CanvasView::~CanvasView()\n    {\n        if (isTimerRunning())\n            stopTimer();\n    }\n\n    //==============================================================================\n    void CanvasView::setProperty(const juce::Identifier& name, const juce::var& value)\n    {\n        View::setProperty(name, value);\n\n        if (name == animateProp)\n        {\n            bool shouldAnimate = value;\n\n            if (shouldAnimate && !isTimerRunning())\n                startTimerHz(45);\n\n            if (!shouldAnimate && isTimerRunning())\n                stopTimer();\n        }\n        \n        if (name == statefulProp && props[statefulProp])\n        {\n            resized();\n        }\n    }\n\n    //==============================================================================\n    void CanvasView::timerCallback()\n    {\n        repaint();\n    }\n\n    //==============================================================================\n    void CanvasView::paint (juce::Graphics& g)\n    {\n        View::paint(g);\n\n        CanvasContext ctx = { getLocalBounds().getWidth(), getLocalBounds().getHeight() };\n\n        if (props.contains(onDrawProp) && props[onDrawProp].isMethod())\n        {\n            const auto drawCommands = std::invoke( props[onDrawProp].getNativeFunction()\n                                                 , juce::var::NativeFunctionArgs(juce::var(), nullptr, 0u));\n\n            if (props.contains(statefulProp) && props[statefulProp])\n            {\n                juce::Graphics imageGraphics(canvasImage);\n                processDrawCommands(ctx, imageGraphics, drawCommands);\n                g.drawImageAt(canvasImage, 0, 0);\n            }\n            else\n            {\n                processDrawCommands(ctx, g, drawCommands);\n            }\n        }\n        else\n        {\n            DBG(\"You appear to have a Canvas element without an onDraw property in your js bundle.\");\n        }\n    }\n\n    void CanvasView::resized()\n    {\n        View::resized();\n\n        if (props.contains(statefulProp) && props[statefulProp])\n        {\n            //TODO: Fix image scalling for retina displays.\n            //      May require passing an optional scaleFactor\n            //      arg through to draw commands.\n            const auto bounds = getLocalBounds();\n            if (bounds.getWidth() > 0 && bounds.getHeight() > 0)\n            {\n                canvasImage = canvasImage.rescaled(bounds.getWidth(),\n                                                   bounds.getHeight(),\n                                                   juce::Graphics::highResamplingQuality);\n            }\n        }\n    }\n\n    //==============================================================================\n}\n\n"
  },
  {
    "path": "react_juce/core/CanvasView.h",
    "content": "/*\n  ==============================================================================\n\n    CanvasView.h\n    Created: 19 May 2020 9:02:25pm\n\n  ==============================================================================\n*/\n\n#pragma once\n\n#include\"View.h\"\n\n\nnamespace reactjuce\n{\n    //==============================================================================\n    /**\n     * The CanvasView class provide HTML canvas functionality to react-juce.\n     * JS CanvasRenderingContext calls are handled here and converted to JUCE graphics\n     * routines.\n     */\n    class CanvasView : public View, public juce::Timer\n    {\n    public:\n        //==============================================================================\n        static const inline juce::Identifier animateProp  = \"animate\";\n        static const inline juce::Identifier onDrawProp   = \"onDraw\";\n        static const inline juce::Identifier statefulProp = \"stateful\";\n\n        //==============================================================================\n        using FillStyle   = juce::FillType;\n        using StrokeStyle = juce::FillType;\n\n        struct CanvasContextProperties\n        {\n            FillStyle           fillStyle;\n            StrokeStyle         strokeStyle;\n            int                 lineWidth = 1;\n            juce::Font          font;\n            juce::Justification textAlign = juce::Justification::left;\n        };\n\n        struct CanvasContext\n        {\n            int                                width          = 1;\n            int                                height         = 1;\n            juce::Path                         path           = {};\n            CanvasContextProperties            properties     = {};\n            std::vector<juce::AffineTransform> transformStack = {};\n        };\n\n        //==============================================================================\n        static void processDrawCommands(CanvasContext   &ctx,\n                                        juce::Graphics  &g,\n                                        const juce::var &drawCommands);\n\n        //==============================================================================\n        CanvasView();\n        ~CanvasView() override;\n\n        //==============================================================================\n        void setProperty (const juce::Identifier& name, const juce::var& value) override;\n\n        //==============================================================================\n        void timerCallback() override;\n\n        //==============================================================================\n        void paint (juce::Graphics& g) override;\n        void resized() override;\n\n        //==============================================================================\n\n    private:\n        juce::Image canvasImage;\n\n        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CanvasView)\n    };\n\n}\n\n\n"
  },
  {
    "path": "react_juce/core/EcmascriptEngine.cpp",
    "content": "/*\n  ==============================================================================\n\n    EcmascriptEngine.cpp\n    Created: 24 Oct 2019 3:08:39pm\n\n  ==============================================================================\n*/\n\n#include \"EcmascriptEngine.h\"\n\n#if REACTJUCE_USE_HERMES\n    #include \"EcmascriptEngine_Hermes.cpp\"\n#elif REACTJUCE_USE_DUKTAPE\n    #include \"EcmascriptEngine_Duktape.cpp\"\n#endif\n\n\nnamespace reactjuce\n{\n\n    //==============================================================================\n    EcmascriptEngine::EcmascriptEngine()\n        : mPimpl(std::make_unique<Pimpl>())\n    {\n        /** If you hit this, you're probably trying to run a console application.\n\n            Please make use of juce::ScopedJuceInitialiser_GUI because this JS engine requires event loops.\n            Without the initialiser, the console app would always crash on exit,\n            and things will probably not get cleaned up.\n        */\n        jassert (juce::MessageManager::getInstanceWithoutCreating() != nullptr);\n    }\n\n    EcmascriptEngine::~EcmascriptEngine()\n    {\n    }\n\n    //==============================================================================\n    juce::var EcmascriptEngine::evaluateInline (const juce::String& code)\n    {\n        return mPimpl->evaluateInline(code);\n    }\n\n    juce::var EcmascriptEngine::evaluate (const juce::File& code)\n    {\n        return mPimpl->evaluate(code);\n    }\n\n    juce::var EcmascriptEngine::evaluateBytecode (const juce::File &code)\n    {\n        return mPimpl->evaluateBytecode(code);\n    }\n\n    //==============================================================================\n    void EcmascriptEngine::registerNativeMethod (const juce::String& name, juce::var::NativeFunction fn)\n    {\n        registerNativeProperty(name, juce::var(fn));\n    }\n\n    void EcmascriptEngine::registerNativeMethod (const juce::String& target, const juce::String& name, juce::var::NativeFunction fn)\n    {\n        registerNativeProperty(target, name, juce::var(fn));\n    }\n\n    //==============================================================================\n    void EcmascriptEngine::registerNativeProperty (const juce::String& name, const juce::var& value)\n    {\n        mPimpl->registerNativeProperty(name, value);\n    }\n\n    void EcmascriptEngine::registerNativeProperty (const juce::String& target, const juce::String& name, const juce::var& value)\n    {\n        mPimpl->registerNativeProperty(target, name, value);\n    }\n\n    //==============================================================================\n    juce::var EcmascriptEngine::invoke (const juce::String& name, const std::vector<juce::var>& vargs)\n    {\n        return mPimpl->invoke(name, vargs);\n    }\n\n    void EcmascriptEngine::reset()\n    {\n        mPimpl->reset();\n    }\n\n    //==============================================================================\n    void EcmascriptEngine::debuggerAttach()\n    {\n        mPimpl->debuggerAttach();\n    }\n\n    void EcmascriptEngine::debuggerDetach()\n    {\n        mPimpl->debuggerDetach();\n    }\n\n}\n"
  },
  {
    "path": "react_juce/core/EcmascriptEngine.h",
    "content": "/*\n  ==============================================================================\n\n    EcmascriptEngine.h\n    Created: 24 Oct 2019 3:08:39pm\n\n  ==============================================================================\n*/\n\n#pragma once\n\n#include <unordered_map>\n\n\nnamespace reactjuce\n{\n\n    //==============================================================================\n    /** The EcmascriptEngine provides a flexible ECMAScript 5 compliant JavaScript engine\n     *  with an interface implemented by Duktape, but which may be implemented by one of\n     *  many embedded engines in the future.\n     */\n    class EcmascriptEngine\n    {\n    public:\n        //==============================================================================\n        EcmascriptEngine();\n        ~EcmascriptEngine();\n\n        //==============================================================================\n        /** A helper struct for representing an error that occured within the Duktape\n         *  engine.\n         *\n         *  We provide the JavaScript stack trace in the `stack` member.\n         */\n        struct Error : public std::runtime_error {\n            Error(const juce::String& msg)\n                : std::runtime_error(msg.toStdString()) {}\n\n            Error(const juce::String& msg, const juce::String& _stack)\n                : std::runtime_error(msg.toStdString()), stack(_stack) {}\n\n            Error(const juce::String& msg, const juce::String& _stack, const juce::String& _context)\n                : std::runtime_error(msg.toStdString()), stack(_stack), context(_context) {}\n\n            juce::String stack;\n            juce::String context;\n        };\n\n        /** A helper struct for representing an error that occured within the Duktape\n         *  engine.\n         *\n         *  In the event this error is thrown, the engine is to be considered\n         *  unrecoverable, and it is up to the user to address how to proceed.\n         */\n        struct FatalError : public std::runtime_error {\n            FatalError(const juce::String& msg)\n                : std::runtime_error(msg.toStdString()) {}\n        };\n\n        //==============================================================================\n        /** Evaluates the given code in the interpreter, returning the result.\n         *\n         *  @returns juce::var result of the evaluation\n         *  @throws EcmascriptEngine::Error in the event of an evaluation error\n         */\n        juce::var evaluateInline (const juce::String& code);\n        juce::var evaluate (const juce::File& code);\n\n        /**\n         * An evaluate overload for engines which support loading precompiled\n         * JS bytecode.\n         * @param code The precompiled bytecode filed to evaluate.\n         * @return juce::var result of the evaluation\n         * @throws EcmascriptEngine::Error in the event of an evaluation error\n         *         or when called on an engine instance which does not support\n         *         loading of precompiled bytecode.\n         */\n        juce::var evaluateBytecode(const juce::File &code);\n\n        //==============================================================================\n        /** Registers a native method by the given name in the global namespace. */\n        void registerNativeMethod (const juce::String&, juce::var::NativeFunction fn);\n\n        /** Registers a native method by the given name on the target object.\n         *\n         *  The provided target name may be any expression that leaves the target\n         *  object on the top of the stack. For example:\n         *\n         *  ```\n         *  registerNativeMethod(\"global\", \"hello\", []() {\n         *      std::cout << \"World!\" << std::endl;\n         *      return juce::var();\n         *  });\n         *  ```\n         *\n         *  is equivalent to calling the previous `registerNativeMethod` overload\n         *  with just the \"hello\" and function arguments.\n         *\n         *  @throws EcmascriptEngine::Error in the event of an evaluation error\n         */\n        void registerNativeMethod (const juce::String&, const juce::String&, juce::var::NativeFunction fn);\n\n        //==============================================================================\n        /** Registers a native value by the given name in the global namespace. */\n        void registerNativeProperty (const juce::String&, const juce::var&);\n\n        /** Registers a native value by the given name on the target object.\n         *\n         *  The provided target name may be any expression that leaves the target\n         *  object on the top of the stack. For example, the following three\n         *  examples have equivalent behavior:\n         *\n         *  ```\n         *  registerNativeProperty(\"global\", \"hello\", \"world\");\n         *  registerNativeProperty(\"hello\", \"world\");\n         *  evaluate(\"global.hello = \\\"world\\\";\");\n         *  ```\n         *\n         *  @throws EcmascriptEngine::Error in the event of an evaluation error\n         */\n        void registerNativeProperty (const juce::String&, const juce::String&, const juce::var&);\n\n        //==============================================================================\n        /** Invokes a method, applying the given args, inside the interpreter.\n         *\n         *  This is similar in function to `Function.prototype.apply()`. The provided\n         *  method name may be any expression that leaves the target function on the\n         *  top of the stack. For example:\n         *\n         *  `invoke(\"global.dispatchViewEvent\", args);`\n         *\n         *  @returns juce::var result of the invocation\n         *  @throws EcmascriptEngine::Error in the event of an error\n         */\n        juce::var invoke (const juce::String& name, const std::vector<juce::var>& vargs);\n\n        /** Invokes a method with the given args inside the interpreter.\n         *\n         *  This is similar in function to `Function.prototype.call()`. The provided\n         *  method name may be any expression that leaves the target function on the\n         *  top of the stack. For example:\n         *\n         *  `invoke(\"global.dispatchViewEvent\", \"click\");`\n         *\n         *  @returns juce::var result of the invocation\n         *  @throws EcmascriptEngine::Error in the event of an error\n         */\n        template <typename... T>\n        juce::var invoke (const juce::String& name, T... args);\n\n        //==============================================================================\n        /** Resets the internal Duktape context, clearing the value stack and destroying native callbacks. */\n        void reset();\n\n        //==============================================================================\n        /** Pauses execution and waits for a debug client to attach and begin a debug session. */\n        void debuggerAttach();\n\n        /** Detaches the from the current debug session/attachment. */\n        void debuggerDetach();\n\n    private:\n        //==============================================================================\n        struct Pimpl;\n        std::unique_ptr<Pimpl> mPimpl;\n\n        //==============================================================================\n        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (EcmascriptEngine)\n    };\n\n    //==============================================================================\n    template <typename... T>\n    juce::var EcmascriptEngine::invoke (const juce::String& name, T... args)\n    {\n        // Pack the args and push them to the alternate `invoke` implementation\n        std::vector<juce::var> vargs { args... };\n        return invoke(name, vargs);\n    }\n\n}\n"
  },
  {
    "path": "react_juce/core/EcmascriptEngine_Duktape.cpp",
    "content": "/* We're careful to include the duktape source files before the module header\n * file because `duktape.c` sets certain preprocessor definitions that enable\n * necessary features in the duktape header. We need those defines to preempt\n * the loading of the duktape header. This also, therefore, is the place for\n * custom preprocessor definitions.\n *\n * We force Duktape to use a time provider on Windows that is compatible with\n * Windows 7 SP1. It looks like W7SP1 is quite happy with plugins built with\n * the 8.1 SDK, but the GetSystemTimePreciseAsFileTime() call used in here is\n * just not supported without the 8.1 dll available.\n */\n#if defined (_WIN32) || defined (_WIN64)\n#define DUK_USE_DATE_NOW_WINDOWS 1\n#endif\n\n/*\n * For whatever reason it is necessary to define this to resolve errors caused by both\n * duktape and juce including parts of the winsock2 API. There may be a better way to\n * resolve this.\n */\n#if defined (_WIN32) || defined (_WIN64)\n#define _WINSOCKAPI_\n#endif\n\n#if _MSC_VER\n#pragma warning(push)\n#elif __clang__\n#pragma clang diagnostic push\n #pragma clang diagnostic ignored \"-Wextra-semi\"\n #pragma clang diagnostic ignored \"-Wsign-conversion\"\n #pragma clang diagnostic ignored \"-Wswitch-enum\"\n #pragma clang diagnostic ignored \"-Wunused-parameter\"\n #pragma clang diagnostic ignored \"-Wused-but-marked-unused\"\n #pragma clang diagnostic ignored \"-Wformat-nonliteral\"\n #pragma clang diagnostic ignored \"-Wzero-as-null-pointer-constant\"\n #pragma clang diagnostic ignored \"-Wshadow\"\n #if __clang_major__ > 10\n  #pragma clang diagnostic ignored \"-Wc++98-compat-extra-semi\"\n  #pragma clang diagnostic ignored \"-Wimplicit-int-conversion\"\n  #pragma clang diagnostic ignored \"-Wshorten-64-to-32\"\n #else\n  #pragma clang diagnostic ignored \"-Wconversion\"\n #endif\n#elif __GNUC__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wzero-as-null-pointer-constant\"\n#pragma GCC diagnostic ignored \"-Wsign-conversion\"\n#pragma GCC diagnostic ignored \"-Wswitch-enum\"\n#pragma GCC diagnostic ignored \"-Wunused-parameter\"\n#endif\n\n// We rely on the JUCE_DEBUG macro in duk_config.h at the moment to determine\n// when we enable duktape debug features. This is a bit of a hack to make this\n// work. We should be able to do better and may do so once we enable custom duktape\n// configs.\n#include <juce_core/system/juce_TargetPlatform.h>\n\n#include <duktape/src-noline/duktape.c>\n#include <duktape/extras/console/duk_console.c>\n\n#if defined (_WIN32) || defined (_WIN64)\n#include <duktape/examples/debug-trans-socket/duk_trans_socket_windows.c>\n#else\n#include <duktape/examples/debug-trans-socket/duk_trans_socket_unix.c>\n#endif\n\n#include <duktape/src-noline/duktape.h>\n#include <duktape/extras/console/duk_console.h>\n#include <duktape/examples/debug-trans-socket/duk_trans_socket.h>\n\n#if _MSC_VER\n#elif __clang__\n#pragma clang diagnostic pop\n#elif __GNUC__\n#pragma GCC diagnostic pop\n#endif\n\nnamespace reactjuce\n{\n\n    namespace detail\n    {\n\n        static void fatalErrorHandler (void* udata, const char* msg)\n        {\n            (void) udata; // Ignored in this case, silence warning\n            throw EcmascriptEngine::FatalError(msg);\n        }\n\n        static juce::String getContextDump(duk_context* ctx)\n        {\n            duk_push_context_dump(ctx);\n            auto ret = juce::String(duk_to_string(ctx, -1));\n            duk_pop(ctx);\n            return ret;\n        }\n\n        static void safeCall(duk_context* ctx, const int numArgs)\n        {\n            if (duk_pcall(ctx, numArgs) != DUK_EXEC_SUCCESS)\n            {\n                const juce::String stack = duk_safe_to_stacktrace(ctx, -1);\n                const juce::String msg = duk_safe_to_string(ctx, -1);\n\n                throw EcmascriptEngine::Error(msg, stack, getContextDump(ctx));\n            }\n        }\n\n        static void safeEvalString(duk_context* ctx, const juce::String& s)\n        {\n            if (duk_peval_string(ctx, s.toRawUTF8()) != DUK_EXEC_SUCCESS)\n            {\n                const juce::String stack = duk_safe_to_stacktrace(ctx, -1);\n                const juce::String msg = duk_safe_to_string(ctx, -1);\n\n                throw EcmascriptEngine::Error(msg, stack, getContextDump(ctx));\n            }\n        }\n\n        static void safeCompileFile(duk_context* ctx, const juce::File& file)\n        {\n            auto name = file.getFileName();\n            auto body = file.loadFileAsString();\n\n            // Push the js filename to be compiled/evaluated\n            duk_push_string(ctx, name.toRawUTF8());\n\n            if (duk_pcompile_string_filename(ctx, DUK_COMPILE_EVAL, body.toRawUTF8()) != DUK_EXEC_SUCCESS)\n            {\n                const juce::String stack = duk_safe_to_stacktrace(ctx, -1);\n                const juce::String msg = duk_safe_to_string(ctx, -1);\n\n                throw EcmascriptEngine::Error(msg, stack, getContextDump(ctx));\n            }\n        }\n\n    }\n\n    //==============================================================================\n    struct EcmascriptEngine::Pimpl : private juce::Timer\n    {\n        Pimpl() { reset(); }\n\n        ~Pimpl() override\n        {\n            // NB: Explicitly stopping the timer so as to avoid any late calls to derefenrencing a (cleaned up) context.\n            stopTimer();\n        }\n\n        //==============================================================================\n        juce::var evaluateInline (const juce::String& code)\n        {\n            jassert(code.isNotEmpty());\n            auto* ctxRawPtr = dukContext.get();\n\n            try {\n                detail::safeEvalString(ctxRawPtr, code);\n            } catch (Error const& err) {\n                reset();\n                throw err;\n            }\n\n            auto result = readVarFromDukStack(dukContext, -1);\n            duk_pop(ctxRawPtr);\n\n            return result;\n        }\n\n        juce::var evaluate (const juce::File& code)\n        {\n            jassert(code.existsAsFile());\n            jassert(code.loadFileAsString().isNotEmpty());\n            auto* ctxRawPtr = dukContext.get();\n\n            try {\n                detail::safeCompileFile(ctxRawPtr, code);\n                detail::safeCall(ctxRawPtr, 0);\n            } catch (Error const& err) {\n                reset();\n                throw err;\n            }\n\n            // Collect the return value\n            auto result = readVarFromDukStack(dukContext, -1);\n            duk_pop(ctxRawPtr);\n\n            return result;\n        }\n\n        juce::var evaluateBytecode(const juce::File &code)\n        {\n            throw Error(\"Duktape engine does not currently support bytecode evaluation\");\n        }\n\n        //==============================================================================\n        void registerNativeProperty (const juce::String& name, const juce::var& value)\n        {\n            auto* ctxRawPtr = dukContext.get();\n\n            duk_push_global_object(ctxRawPtr);\n            pushVarToDukStack(dukContext, value, true);\n            duk_put_prop_string(ctxRawPtr, -2, name.toRawUTF8());\n            duk_pop(ctxRawPtr);\n        }\n\n        void registerNativeProperty (const juce::String& target, const juce::String& name, const juce::var& value)\n        {\n            auto* ctxRawPtr = dukContext.get();\n\n            try {\n                detail::safeEvalString(ctxRawPtr, target);\n            } catch (Error const& err) {\n                reset();\n                throw err;\n            }\n\n            // Then assign the property\n            pushVarToDukStack(dukContext, value, true);\n            duk_put_prop_string(ctxRawPtr, -2, name.toRawUTF8());\n            duk_pop(ctxRawPtr);\n        }\n\n        //==============================================================================\n        juce::var invoke (const juce::String& name, const std::vector<juce::var>& vargs)\n        {\n            auto* ctxRawPtr = dukContext.get();\n\n            try {\n                detail::safeEvalString(ctxRawPtr, name);\n\n                if (!duk_is_function(ctxRawPtr, -1)) {\n                    throw Error(\"Invocation failed, target is not a function.\");\n                }\n\n                // Push the args to the duktape stack\n                const auto nargs = static_cast<duk_idx_t>(vargs.size());\n                duk_require_stack_top(ctxRawPtr, nargs);\n\n                for (auto& p : vargs)\n                    pushVarToDukStack(dukContext, p);\n\n                // Invocation\n                detail::safeCall(ctxRawPtr, nargs);\n            } catch (Error const& err) {\n                reset();\n                throw err;\n            }\n\n            // Collect the return value\n            auto result = readVarFromDukStack(dukContext, -1);\n            duk_pop(ctxRawPtr);\n\n            return result;\n        }\n\n        struct TimeoutFunctionManager : private juce::MultiTimer\n        {\n            ~TimeoutFunctionManager() override {\n                for(const auto &[id, timer] : timeoutFunctions)\n                    stopTimer(id);\n            }\n\n            juce::var clearTimeout(const int id)\n            {\n                stopTimer(id);\n                const auto f = timeoutFunctions.find(id);\n                if(f != timeoutFunctions.cend())\n                    timeoutFunctions.erase(f);\n                return juce::var();\n            }\n\n            int newTimeout(const juce::var::NativeFunction f, const int timeoutMillis, const std::vector<juce::var>&& args, const bool repeats=false)\n            {\n                static int nextId = 0;\n                timeoutFunctions.emplace(nextId, TimeoutFunction(f, std::move(args), repeats));\n                startTimer(nextId, timeoutMillis);\n                return nextId++;\n            }\n\n            void timerCallback(int id) override\n            {\n                const auto f = timeoutFunctions.find(id);\n                if(f != timeoutFunctions.cend())\n                {\n                    const auto cb = f->second;\n                    std::invoke(cb.f, juce::var::NativeFunctionArgs(juce::var(), cb.args.data(), static_cast<int>(cb.args.size())));\n                    if(!cb.repeats)\n                    {\n                        stopTimer(id);\n                        timeoutFunctions.erase(f);\n                    }\n                }\n            }\n\n        private:\n            struct TimeoutFunction\n            {\n                TimeoutFunction(const juce::var::NativeFunction _f, const std::vector<juce::var> &&_args, const bool _repeats=false)\n                    : f(_f), args(std::move(_args)), repeats(_repeats) {}\n\n                const juce::var::NativeFunction f;\n                std::vector<juce::var> args;\n                const bool repeats;\n            };\n\n            std::map<int, TimeoutFunction> timeoutFunctions;\n        };\n\n        // IsSetter is true for setTimeout / setInterval\n        // and false for clearTimeout / clearInterval\n        template <bool IsSetter = false, bool Repeats = false, typename MethodType>\n        void registerNativeTimerFunction(const char* name, MethodType method)\n        {\n            registerNativeProperty(name, juce::var::NativeFunction([this, name, method] (const juce::var::NativeFunctionArgs& _args) -> juce::var {\n                if constexpr (IsSetter)\n                {\n                    if(_args.numArguments < 2 || !_args.arguments[0].isMethod() || !_args.arguments[1].isDouble())\n                        throw Error(juce::String(name) + \" requires a callback and time in milliseconds\");\n                    // build a vector holding all additional arguments\n                    std::vector<juce::var> args(_args.arguments + 2, _args.arguments + _args.numArguments);\n                    return (this->timeoutsManager.get()->*method)(_args.arguments[0].getNativeFunction(), _args.arguments[1], std::move(args), Repeats);\n                }\n                else\n                {\n                    if(_args.numArguments < 1 || !_args.arguments[0].isDouble())\n                        throw Error(juce::String(name) + \" requires an integer ID of the timer to clear\");\n                    return (this->timeoutsManager.get()->*method)(_args.arguments[0]);\n                }\n            }));\n        }\n\n        void registerTimerGlobals()\n        {\n            registerNativeTimerFunction<true>(\n                \"setTimeout\", &TimeoutFunctionManager::newTimeout\n            );\n            registerNativeTimerFunction<true, true>(\n                \"setInterval\", &TimeoutFunctionManager::newTimeout\n            );\n            registerNativeTimerFunction(\"clearTimeout\", &TimeoutFunctionManager::clearTimeout);\n            registerNativeTimerFunction(\"clearInterval\", &TimeoutFunctionManager::clearTimeout);\n        }\n\n        void reset()\n        {\n            // Clear out any timer callbacks\n            timeoutsManager = std::make_unique<TimeoutFunctionManager>();\n\n            // Allocate a new js heap\n            dukContext = std::shared_ptr<duk_context>(\n                duk_create_heap (nullptr, nullptr, nullptr, nullptr, detail::fatalErrorHandler),\n                duk_destroy_heap\n            );\n\n            // Add console.log support\n            auto* ctxRawPtr = dukContext.get();\n            duk_console_init(ctxRawPtr, DUK_CONSOLE_FLUSH);\n\n            // Install a pointer back to this EcmascriptEngine instance\n            duk_push_global_stash(ctxRawPtr);\n            duk_push_pointer(ctxRawPtr, (void *) this);\n            duk_put_prop_string(ctxRawPtr, -2, DUK_HIDDEN_SYMBOL(\"__EcmascriptEngineInstance__\"));\n            duk_pop(ctxRawPtr);\n\n            // Clear out any lambdas attached to the previous context instance\n            persistentReleasePool.clear();\n\n            // Register our various timeout-related native functions\n            registerTimerGlobals();\n        }\n\n        //==============================================================================\n        void debuggerAttach()\n        {\n            auto* ctxRawPtr = dukContext.get();\n\n            duk_trans_socket_init();\n            duk_trans_socket_waitconn();\n\n            duk_debugger_attach(ctxRawPtr,\n                                duk_trans_socket_read_cb,\n                                duk_trans_socket_write_cb,\n                                duk_trans_socket_peek_cb,\n                                duk_trans_socket_read_flush_cb,\n                                duk_trans_socket_write_flush_cb,\n                                nullptr,\n                                [](duk_context*, void* data)\n                                {\n                                    duk_trans_socket_finish();\n\n                                    auto engine = static_cast<EcmascriptEngine::Pimpl*>(data);\n                                    engine->stopTimer();\n                                },\n                                this);\n\n            // Start timer for duk_debugger_cooperate calls\n            startTimer(200);\n        }\n\n        void debuggerDetach()\n        {\n            if (auto* dc = dukContext.get())\n                duk_debugger_detach (dc);\n        }\n\n        //==============================================================================\n        void timerCallback() override\n        {\n            if (auto* dc = dukContext.get())\n                duk_debugger_cooperate (dc);\n        }\n\n        //==============================================================================\n        struct LambdaHelper {\n            LambdaHelper(juce::var::NativeFunction fn, uint32_t _id)\n                : callback(std::move(fn)), id(_id) {}\n\n            static duk_ret_t invokeFromDukContext(duk_context* ctx)\n            {\n                // First we have to retrieve the actual function pointer and our engine pointer\n                // See: https://duktape.org/guide.html#hidden-symbol-properties\n                duk_push_current_function(ctx);\n                duk_get_prop_string(ctx, -1, DUK_HIDDEN_SYMBOL(\"LambdaHelperPtr\"));\n\n                LambdaHelper* helper = static_cast<LambdaHelper*>(duk_get_pointer(ctx, -1));\n                duk_pop(ctx);\n\n                // Then the engine...\n                duk_get_prop_string(ctx, -1, DUK_HIDDEN_SYMBOL(\"EnginePtr\"));\n                auto* engine = static_cast<EcmascriptEngine::Pimpl*>(duk_get_pointer(ctx, -1));\n\n                // Pop back both the pointer and the \"current function\"\n                duk_pop_2(ctx);\n\n                // Now we can collect our args\n                std::vector<juce::var> args;\n                int nargs = duk_get_top(ctx);\n\n                for (int i = 0; i < nargs; ++i)\n                    args.push_back(engine->readVarFromDukStack(engine->dukContext, i));\n\n                juce::var result;\n\n                // Now we can invoke the user method with its arguments\n                try\n                {\n                    result = std::invoke(helper->callback, juce::var::NativeFunctionArgs(\n                        juce::var(),\n                        args.data(),\n                        static_cast<int>(args.size())\n                    ));\n                }\n                catch (Error& err)\n                {\n                    duk_push_error_object(ctx, DUK_ERR_TYPE_ERROR, err.what());\n                    return duk_throw(ctx);\n                }\n\n                // For an undefined result, return 0 to notify the duktape interpreter\n                if (result.isUndefined())\n                    return 0;\n\n                // Otherwise, push the result to the stack and tell duktape\n                engine->pushVarToDukStack(engine->dukContext, result);\n                return 1;\n            }\n\n            static duk_ret_t invokeFromDukContextLightFunc(duk_context* ctx)\n            {\n                // Retrieve the engine pointer\n                duk_push_global_stash(ctx);\n                duk_get_prop_string(ctx, -1, DUK_HIDDEN_SYMBOL(\"__EcmascriptEngineInstance__\"));\n\n                auto* engine = static_cast<EcmascriptEngine::Pimpl*>(duk_get_pointer(ctx, -1));\n                duk_pop_2(ctx);\n\n                // Retrieve the lambda helper\n                duk_push_current_function(ctx);\n                const auto magic = duk_get_magic(ctx, -1);\n                auto& helper = engine->temporaryReleasePool[static_cast<size_t> (magic + 128)];\n                duk_pop(ctx);\n\n                // Now we can collect our args\n                const auto nargs = duk_get_top(ctx);\n                std::vector<juce::var> args;\n                args.reserve(static_cast<size_t> (nargs));\n\n                for (int i = 0; i < nargs; ++i)\n                    args.push_back(engine->readVarFromDukStack(engine->dukContext, i));\n\n                // Now we can invoke the user method with its arguments\n                const auto result = std::invoke(helper->callback, juce::var::NativeFunctionArgs(\n                    juce::var(),\n                    args.data(),\n                    static_cast<int>(args.size())\n                ));\n\n                // For an undefined result, return 0 to notify the duktape interpreter\n                if (result.isUndefined())\n                    return 0;\n\n                // Otherwise, push the result to the stack and tell duktape\n                engine->pushVarToDukStack(engine->dukContext, result);\n                return 1;\n            }\n\n            static duk_ret_t callbackFinalizer (duk_context* ctx)\n            {\n                // First we have to retrieve the actual function pointer and our engine pointer\n                // See: https://duktape.org/guide.html#hidden-symbol-properties\n                // And: https://duktape.org/api.html#duk_set_finalizer\n                // In this case our function is at index 0.\n                duk_require_function(ctx, 0);\n                duk_get_prop_string(ctx, 0, DUK_HIDDEN_SYMBOL(\"LambdaHelperPtr\"));\n\n                LambdaHelper* helper = static_cast<LambdaHelper*>(duk_get_pointer(ctx, -1));\n                duk_pop(ctx);\n\n                // Then the engine...\n                duk_get_prop_string(ctx, 0, DUK_HIDDEN_SYMBOL(\"EnginePtr\"));\n                auto* engine = static_cast<EcmascriptEngine::Pimpl*>(duk_get_pointer(ctx, -1));\n\n                // Pop back both the pointer and the \"current function\"\n                duk_pop_2(ctx);\n\n                // Clean up our lambda helper\n                engine->removeLambdaHelper(helper);\n                return 0;\n            }\n\n            juce::var::NativeFunction callback;\n            uint32_t id;\n        };\n\n        //==============================================================================\n        /** Helper for cleaning up native function temporaries. */\n        void removeLambdaHelper (LambdaHelper* helper)\n        {\n            persistentReleasePool.erase(helper->id);\n        }\n\n        /** Helper for pushing a juce::var to the duktape stack. */\n        void pushVarToDukStack (std::shared_ptr<duk_context> ctx, const juce::var& v, bool persistNativeFunctions = false)\n        {\n            auto* ctxRawPtr = dukContext.get();\n\n            if (v.isVoid() || v.isUndefined())\n                return duk_push_undefined(ctxRawPtr);\n            if (v.isBool())\n                return duk_push_boolean(ctxRawPtr, (bool) v);\n            if (v.isInt() || v.isInt64())\n                return duk_push_int(ctxRawPtr, (int) v);\n            if (v.isDouble())\n                return duk_push_number(ctxRawPtr, (double) v);\n            if (v.isString())\n                return (void) duk_push_string(ctxRawPtr, v.toString().toRawUTF8());\n            if (v.isArray())\n            {\n                duk_idx_t arr_idx = duk_push_array(ctxRawPtr);\n                duk_uarridx_t i = 0;\n\n                for (auto& e : *(v.getArray()))\n                {\n                    pushVarToDukStack(ctx, e, persistNativeFunctions);\n                    duk_put_prop_index(ctxRawPtr, arr_idx, i++);\n                }\n\n                return;\n            }\n            if (v.isObject())\n            {\n                if (auto* o = v.getDynamicObject())\n                {\n                    duk_idx_t obj_idx = duk_push_object(ctxRawPtr);\n\n                    for (auto& e : o->getProperties())\n                    {\n                        pushVarToDukStack(ctx, e.value, persistNativeFunctions);\n                        duk_put_prop_string(ctxRawPtr, obj_idx, e.name.toString().toRawUTF8());\n                    }\n                }\n\n                return;\n            }\n            if (v.isMethod())\n            {\n                if (persistNativeFunctions)\n                {\n                    // For persisted native functions, we provide a helper layer storing and retrieving the\n                    // stash, and marshalling between the Duktape C interface and the NativeFunction interface\n                    duk_push_c_function(ctxRawPtr, LambdaHelper::invokeFromDukContext, DUK_VARARGS);\n\n                    // Now we assign the pointers as properties of the wrapper function\n                    auto helper = std::make_unique<LambdaHelper>(v.getNativeFunction(), nextHelperId++);\n                    duk_push_pointer(ctxRawPtr, (void *) helper.get());\n                    duk_put_prop_string(ctxRawPtr, -2, DUK_HIDDEN_SYMBOL(\"LambdaHelperPtr\"));\n                    duk_push_pointer(ctxRawPtr, (void *) this);\n                    duk_put_prop_string(ctxRawPtr, -2, DUK_HIDDEN_SYMBOL(\"EnginePtr\"));\n\n                    // Now we prepare the finalizer\n                    duk_push_c_function(ctxRawPtr, LambdaHelper::callbackFinalizer, 1);\n                    duk_push_pointer(ctxRawPtr, (void *) helper.get());\n                    duk_put_prop_string(ctxRawPtr, -2, DUK_HIDDEN_SYMBOL(\"LambdaHelperPtr\"));\n                    duk_push_pointer(ctxRawPtr, (void *) this);\n                    duk_put_prop_string(ctxRawPtr, -2, DUK_HIDDEN_SYMBOL(\"EnginePtr\"));\n                    duk_set_finalizer(ctxRawPtr, -2);\n\n                    // And hang on to it!\n                    persistentReleasePool[helper->id] = std::move(helper);\n                }\n                else\n                {\n                    // For temporary native functions, we use the stack-allocated lightfunc. In\n                    // this case we can't attach properties, so we can't rely on raw pointers to\n                    // the LambdaHelper and we can't rely on finalizers. So, all we do here is use\n                    // a small pool for temporary LambdaHelpers. Within this pool, we just allow insertions\n                    // to wrap around and clobber previous temporaries, effectively garbage collecting on\n                    // demand. The maximum number of temporary values before wrapping is 255, as dictated\n                    // by that we use the lightfunc's magic number to identify our native callback.\n                    auto helper = std::make_unique<LambdaHelper>(v.getNativeFunction(), nextHelperId++);\n                    auto magic = nextMagicInt++;\n\n                    duk_push_c_lightfunc(ctxRawPtr, LambdaHelper::invokeFromDukContextLightFunc, DUK_VARARGS, 15, magic);\n                    temporaryReleasePool[static_cast<size_t> (magic + 128)] = std::move(helper);\n\n                    if (nextMagicInt >= 127)\n                        nextMagicInt = -128;\n                }\n                return;\n            }\n\n            // If you hit this, you tried to push an unsupported var type to the duktape\n            // stack.\n            jassertfalse;\n        }\n\n        /** Helper for reading from the duktape stack to a juce::var instance. */\n        juce::var readVarFromDukStack (std::shared_ptr<duk_context> ctx, duk_idx_t idx)\n        {\n            auto* ctxRawPtr = dukContext.get();\n            juce::var value;\n\n            switch (duk_get_type(ctxRawPtr, idx))\n            {\n                case DUK_TYPE_NULL:\n                    // It looks like juce::var doesn't have an explicit null value,\n                    // so we're just using the default empty constructor value.\n                    break;\n                case DUK_TYPE_UNDEFINED:\n                    value = juce::var::undefined();\n                    break;\n                case DUK_TYPE_BOOLEAN:\n                    value = (bool) duk_get_boolean(ctxRawPtr, idx);\n                    break;\n                case DUK_TYPE_NUMBER:\n                    value = duk_get_number(ctxRawPtr, idx);\n                    break;\n                case DUK_TYPE_STRING:\n                    value = juce::String(juce::CharPointer_UTF8(duk_get_string(ctxRawPtr, idx)));\n                    break;\n                case DUK_TYPE_OBJECT:\n                case DUK_TYPE_LIGHTFUNC:\n                {\n                    if (duk_is_array(ctxRawPtr, idx))\n                    {\n                        duk_size_t len = duk_get_length(ctxRawPtr, idx);\n                        juce::Array<juce::var> els;\n\n                        for (duk_size_t i = 0; i < len; ++i)\n                        {\n                            duk_get_prop_index(ctxRawPtr, idx, static_cast<duk_uarridx_t>(i));\n                            els.add(readVarFromDukStack(ctx, -1));\n                            duk_pop(ctxRawPtr);\n                        }\n\n                        value = els;\n                        break;\n                    }\n\n                    if (duk_is_function(ctxRawPtr, idx) || duk_is_lightfunc(ctxRawPtr, idx))\n                    {\n                        struct CallbackHelper {\n                            CallbackHelper(std::weak_ptr<duk_context> _weakContext)\n                                : weakContext(_weakContext)\n                                , funcId(juce::String(\"__NativeCallback__\") + juce::Uuid().toString()) {}\n\n                            ~CallbackHelper() {\n                                if (auto spt = weakContext.lock()) {\n                                    duk_push_global_stash(spt.get());\n                                    duk_del_prop_string(spt.get(), -1, funcId.toRawUTF8());\n                                    duk_pop(spt.get());\n                                }\n                            }\n\n                            std::weak_ptr<duk_context> weakContext;\n                            juce::String funcId;\n                        };\n\n                        // With a function, we first push the function reference to\n                        // the Duktape global stash so we can read it later.\n                        auto helper = std::make_shared<CallbackHelper>(ctx);\n\n                        duk_push_global_stash(ctxRawPtr);\n                        duk_dup(ctxRawPtr, idx);\n                        duk_put_prop_string(ctxRawPtr, -2, helper->funcId.toRawUTF8());\n                        duk_pop(ctxRawPtr);\n\n                        // Next we create a var::NativeFunction that captures the function\n                        // id and knows how to invoke it\n                        value = juce::var::NativeFunction {\n                            [this, weakContext = std::weak_ptr<duk_context>(ctx), helper](const juce::var::NativeFunctionArgs& args) -> juce::var {\n                                auto sharedContext = weakContext.lock();\n\n                                // If our context disappeared, we return early\n                                if (!sharedContext)\n                                    return juce::var();\n\n                                auto* rawPtr = sharedContext.get();\n\n                                // Here when we're being invoked we retrieve the callback function from\n                                // the global stash and invoke it with the provided args.\n                                duk_push_global_stash(rawPtr);\n                                duk_get_prop_string(rawPtr, -1, helper->funcId.toRawUTF8());\n\n                                if (!(duk_is_lightfunc(rawPtr, -1) || duk_is_function(rawPtr, -1)))\n                                    throw Error(\"Global callback not found.\", \"\", detail::getContextDump(rawPtr));\n\n                                // Push the args to the duktape stack\n                                duk_require_stack_top(rawPtr, args.numArguments);\n\n                                for (int i = 0; i < args.numArguments; ++i)\n                                    pushVarToDukStack(sharedContext, args.arguments[i]);\n\n                                // Invocation\n                                try {\n                                    detail::safeCall(rawPtr, args.numArguments);\n                                } catch (Error const& err) {\n                                    reset();\n                                    throw err;\n                                }\n\n                                // Clean the result and the stash off the top of the stack\n                                juce::var result = readVarFromDukStack(sharedContext, -1);\n                                duk_pop_2(rawPtr);\n\n                                return result;\n                            }\n                        };\n\n                        break;\n                    }\n\n                    // If it's not a function or an array, it's a regular object.\n                    auto* obj = new juce::DynamicObject();\n\n                    // Generic object enumeration; `duk_enum` pushes an enumerator\n                    // object to the top of the stack\n                    duk_enum(ctxRawPtr, idx, DUK_ENUM_OWN_PROPERTIES_ONLY);\n\n                    while (duk_next(ctxRawPtr, -1, 1))\n                    {\n                        // For each found key/value pair, `duk_enum` pushes the\n                        // values to the top of the stack. So here the stack top\n                        // is [ ... enum key value]. Enum is at -3, key at -2,\n                        // value at -1 from the stack top.\n                        // Note here that all keys in an ECMAScript object are of\n                        // type string, even arrays, e.g. `myArr[0]` has an implicit\n                        // conversion from number to string. Thus here, while constructing\n                        // the DynamicObject, we take the `toString()` value for the key\n                        // always.\n                        obj->setProperty(duk_to_string(ctxRawPtr, -2), readVarFromDukStack(ctx, -1));\n\n                        // Clear the key/value pair from the stack\n                        duk_pop_2(ctxRawPtr);\n                    }\n\n                    // Pop the enumerator from the stack\n                    duk_pop(ctxRawPtr);\n\n                    value = juce::var(obj);\n                    break;\n                }\n                case DUK_TYPE_NONE:\n                default:\n                    jassertfalse;\n            }\n\n            return value;\n        }\n\n        //==============================================================================\n        uint32_t nextHelperId = 0;\n        int32_t nextMagicInt = 0;\n        std::unordered_map<uint32_t, std::unique_ptr<LambdaHelper>> persistentReleasePool;\n        std::array<std::unique_ptr<LambdaHelper>, 255> temporaryReleasePool;\n        std::unique_ptr<TimeoutFunctionManager> timeoutsManager;\n\n        // The duk_context must be listed after the release pools so that it is destructed\n        // before the pools. That way, as the duk_context is being freed and finalizing all\n        // of our lambda helpers, our pools still exist for those code paths.\n        std::shared_ptr<duk_context> dukContext;\n    };\n\n}\n"
  },
  {
    "path": "react_juce/core/EcmascriptEngine_Hermes.cpp",
    "content": "#include \"EcmascriptEngine.h\"\n\n#if _MSC_VER\n#pragma warning(push)\n#elif __clang__\n#pragma clang diagnostic push\n #pragma clang diagnostic ignored \"-Winconsistent-missing-destructor-override\"\n #pragma clang diagnostic ignored \"-Wextra-semi\"\n #pragma clang diagnostic ignored \"-Wgnu-zero-variadic-macro-arguments\"\n#elif __GNUC__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wpedantic\"\n#endif\n\n#include <hermes/hermes.h>\n\n#if _MSC_VER\n#elif __clang__\n#pragma clang diagnostic pop\n#elif __GNUC__\n#pragma GCC diagnostic pop\n#endif\n\nusing namespace facebook;\n\nnamespace reactjuce\n{\n    namespace\n    {\n        //==============================================================================\n        class JSIMemoryBuffer : public jsi::Buffer\n        {\n        public:\n            explicit JSIMemoryBuffer(std::unique_ptr<juce::MemoryBlock> mem)\n                : memBlock(std::move(mem))\n            { }\n\n            size_t size() const override\n            {\n                return memBlock->getSize();\n            }\n\n            const uint8_t *data() const override\n            {\n                return reinterpret_cast<const uint8_t*>(memBlock->getData());\n            }\n\n        private:\n            std::unique_ptr<juce::MemoryBlock> memBlock;\n        };\n\n        //==============================================================================\n        struct CopyableJSIMethodWrapper\n        {\n            explicit CopyableJSIMethodWrapper(jsi::Function f)\n                : fn(std::move(f))\n            { }\n\n            jsi::Function fn;\n        };\n\n        //==============================================================================\n        juce::var  jsiValueToVar(const jsi::Value &v, jsi::Runtime &runtime);\n        jsi::Value varToJSIValue(const juce::var &v, jsi::Runtime &runtime);\n\n        juce::var jsiArrayToVarArray(const jsi::Array &v, jsi::Runtime &runtime)\n        {\n            juce::Array<juce::var> varArray;\n\n            const size_t numItems = v.size(runtime);\n            for (size_t i = 0; i < numItems; ++i)\n            {\n                varArray.add(jsiValueToVar(v.getValueAtIndex(runtime, i), runtime));\n            }\n\n            return varArray;\n        }\n\n        juce::var::NativeFunction jsiMethodToVarMethod(jsi::Function v, jsi::Runtime &runtime)\n        {\n            auto fPtr = std::make_shared<CopyableJSIMethodWrapper>(std::move(v));\n\n            return [fPtr = fPtr, &rt = runtime] (const juce::var::NativeFunctionArgs &args)\n            {\n                std::vector<jsi::Value> jsiArgs;\n                for (int i = 0; i < args.numArguments; ++i)\n                {\n                    jsiArgs.emplace_back(varToJSIValue(args.arguments[i], rt));\n                }\n\n                const jsi::Value *jsiArgsPtr = jsiArgs.data();\n                return jsiValueToVar(fPtr->fn.call(rt, jsiArgsPtr, jsiArgs.size()), rt);\n            };\n        }\n\n        juce::var jsiObjectToVarObject(const jsi::Object &v, jsi::Runtime &runtime)\n        {\n            juce::DynamicObject::Ptr varObj = new juce::DynamicObject();\n\n            jsi::Array props = v.getPropertyNames(runtime);\n            for (size_t i = 0; i < props.size(runtime); ++i)\n            {\n                const juce::String propId = props.getValueAtIndex(runtime, i).asString(runtime).utf8(runtime);\n                jsi::Value property = v.getProperty(runtime, propId.toRawUTF8());\n                varObj->setProperty(propId, jsiValueToVar(property, runtime));\n            }\n\n            return varObj.get();\n        }\n\n        juce::var jsiValueToVar(const jsi::Value &v, jsi::Runtime &runtime)\n        {\n            if (v.isBool())\n                return v.getBool();\n\n            if (v.isNumber())\n                return v.getNumber();\n\n            if (v.isString())\n                return juce::String(v.getString(runtime).utf8(runtime));\n\n            if (v.isUndefined())\n                return juce::var::undefined();\n\n            if (v.isNull())\n                return juce::var();\n\n            if (v.isObject())\n            {\n                auto obj = v.getObject(runtime);\n\n                if (obj.isArray(runtime))\n                    return jsiArrayToVarArray(obj.getArray(runtime), runtime);\n\n                if (obj.isArrayBuffer(runtime))\n                {\n                    jsi::ArrayBuffer arrayBuffer = obj.getArrayBuffer(runtime);\n                    juce::MemoryBlock memBlock(static_cast<const void*>(arrayBuffer.data(runtime)),\n                                               arrayBuffer.size(runtime));\n\n                    return juce::var(memBlock);\n                }\n\n                if (obj.isFunction(runtime))\n                    return jsiMethodToVarMethod(obj.asFunction(runtime), runtime);\n\n                // If jsi object is not array or function type then treat as an object\n                return jsiObjectToVarObject(obj, runtime);\n            }\n\n            jassertfalse;\n            return {};\n        }\n\n        //==============================================================================\n        jsi::Object varObjectToJSIObject(juce::DynamicObject *v, jsi::Runtime &runtime)\n        {\n            jassert(v);\n\n            jsi::Object jsiObj(runtime);\n            for (auto &prop : v->getProperties())\n            {\n                jsiObj.setProperty(runtime, prop.name.getCharPointer(), varToJSIValue(prop.value, runtime));\n            }\n\n            return jsiObj;\n        }\n\n        jsi::Function varMethodToJSIMethod(juce::var::NativeFunction &v, jsi::Runtime &runtime)\n        {\n            return jsi::Function::createFromHostFunction(\n                runtime,\n                jsi::PropNameID::forAscii(runtime, \"\"),\n                0,\n                [v = v](jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count)\n                {\n                    std::vector<juce::var> varArgs;\n                    for (size_t i = 0; i < count; ++i)\n                    {\n                        varArgs.push_back(jsiValueToVar(args[i], rt));\n                    }\n\n                    juce::var::NativeFunctionArgs nfArgs(jsiValueToVar(thisVal, rt), varArgs.data(), static_cast<int>(count));\n                    return varToJSIValue(v(nfArgs), rt);\n                }\n            );\n        }\n\n        jsi::Array varArrayToJSIArray(const juce::Array<juce::var> *v, jsi::Runtime &runtime)\n        {\n            jassert(v);\n\n            const auto numItems = static_cast<size_t>(v->size());\n            jsi::Array jsiArray(runtime, numItems);\n\n            for (size_t i = 0; i < numItems; ++i)\n            {\n                jsiArray.setValueAtIndex(runtime, i, varToJSIValue(v->getReference(static_cast<int>(i)), runtime));\n            }\n\n            return jsiArray;\n        }\n\n        jsi::Value varToJSIValue(const juce::var &v, jsi::Runtime &runtime)\n        {\n            if (v.isBool())\n                return jsi::Value(static_cast<bool>(v));\n\n            if (v.isInt())\n                return jsi::Value(static_cast<int>(v));\n\n            if (v.isInt64())\n                return jsi::Value(static_cast<double>(v));\n\n            if (v.isDouble())\n                return jsi::Value(static_cast<double>(v));\n\n            if (v.isString())\n                return jsi::Value(runtime,  jsi::String::createFromAscii(runtime, v.toString().getCharPointer()));\n\n            if (v.isUndefined())\n                return jsi::Value::undefined();\n\n            if (v.isVoid())\n                return {};\n\n            if (v.isArray())\n                return varArrayToJSIArray(v.getArray(), runtime);\n\n            if (v.isMethod())\n            {\n                auto nf = v.getNativeFunction();\n                return varMethodToJSIMethod(nf, runtime);\n            }\n\n            if (v.isObject())\n                return varObjectToJSIObject(v.getDynamicObject(), runtime);\n\n            if (v.isBinaryData())\n            {\n                //TODO: Currently appears no way to create a jsi::ArrayBuffer from C++.\n                jassertfalse;\n                return {};\n            }\n\n            jassertfalse;\n            return {};\n        }\n\n        //==============================================================================\n    }\n\n    //==============================================================================\n    struct EcmascriptEngine::Pimpl\n    {\n        //==============================================================================\n        struct TimeoutFunctionManager : private juce::MultiTimer\n        {\n            explicit TimeoutFunctionManager(jsi::Runtime &rt)\n                : runtime(rt)\n            { }\n\n            ~TimeoutFunctionManager() override\n            {\n                clear();\n            }\n\n            void clear()\n            {\n                std::for_each(timeoutFunctions.cbegin(), timeoutFunctions.cend(), [this] (const auto &tf)\n                {\n                    stopTimer(tf.first);\n                });\n\n                timeoutFunctions.clear();\n            }\n\n            jsi::Value clearTimeout(const int id)\n            {\n                stopTimer(id);\n\n                if (const auto f = timeoutFunctions.find(id); f != timeoutFunctions.cend())\n                    timeoutFunctions.erase(f);\n\n                return jsi::Value();\n            }\n\n            jsi::Value newTimeout(jsi::Function f, const int timeoutMillis, std::vector<jsi::Value> args, const bool repeats=false)\n            {\n                static int nextId = 0;\n                timeoutFunctions.emplace(nextId, TimeoutFunction(std::move(f), std::move(args), repeats));\n                startTimer(nextId, timeoutMillis);\n\n                return nextId++;\n            }\n\n            void timerCallback(int id) override\n            {\n                if (const auto f = timeoutFunctions.find(id); f != timeoutFunctions.cend())\n                {\n                    TimeoutFunction &cb = f->second;\n\n                    const jsi::Value *argsPtr = cb.args.data();\n                    cb.f.call(runtime, argsPtr, cb.args.size());\n\n                    if (!cb.repeats)\n                    {\n                        stopTimer(id);\n                        timeoutFunctions.erase(f);\n                    }\n                }\n            }\n\n        private:\n            struct TimeoutFunction\n            {\n                TimeoutFunction(jsi::Function _f, std::vector<jsi::Value> _args, const bool _repeats=false)\n                    : f(std::move(_f))\n                    , args(std::move(_args))\n                    , repeats(_repeats)\n                { }\n\n                jsi::Function           f;\n                std::vector<jsi::Value> args;\n                const bool              repeats;\n            };\n\n            jsi::Runtime                   &runtime;\n            std::map<int, TimeoutFunction>  timeoutFunctions;\n        };\n\n        //==============================================================================\n        Pimpl()\n        {\n            reset();\n        }\n\n        ~Pimpl() = default;\n\n        //==============================================================================\n        juce::var evaluateInline(const juce::String &code)\n        {\n            try\n            {\n                auto jsiBuffer = std::make_shared<jsi::StringBuffer>(code.toStdString());\n                auto js        = runtime->prepareJavaScript(jsiBuffer, \"\");\n                auto result    = runtime->evaluatePreparedJavaScript(js);\n\n                return jsiValueToVar(result, *runtime);\n            }\n            catch (const jsi::JSIException &e)\n            {\n                throw Error(e.what());\n            }\n        }\n\n        juce::var evaluate(const juce::File &code)\n        {\n            try\n            {\n                auto jsiBuffer = std::make_shared<jsi::StringBuffer>(code.loadFileAsString().toStdString());\n                auto js        = runtime->prepareJavaScript(jsiBuffer, code.getFullPathName().toStdString());\n                auto result    = runtime->evaluatePreparedJavaScript(js);\n\n                return jsiValueToVar(result, *runtime);\n            }\n            catch (const jsi::JSIException &e)\n            {\n                throw Error(e.what());\n            }\n        }\n\n        juce::var evaluateBytecode(const juce::File &code)\n        {\n            try\n            {\n                auto memBlock = std::make_unique<juce::MemoryBlock>();\n                code.loadFileAsData(*memBlock);\n\n                auto jsiBuffer = std::make_shared<JSIMemoryBuffer>(std::move(memBlock));\n                auto js        = runtime->prepareJavaScript(jsiBuffer, code.getFullPathName().toStdString());\n                auto result    = runtime->evaluatePreparedJavaScript(js);\n\n                return jsiValueToVar(result, *runtime);\n            }\n            catch (const jsi::JSIException &e)\n            {\n                throw Error(e.what());\n            }\n        }\n\n        //==============================================================================\n        void registerNativeProperty(const juce::String &name, const juce::var &value)\n        {\n            try\n            {\n                runtime->global().setProperty(*runtime, name.toRawUTF8(), varToJSIValue(value, *runtime));\n            }\n            catch (const jsi::JSIException &e)\n            {\n                throw Error(e.what());\n            }\n        }\n\n        void registerNativeProperty(const juce::String &target, const juce::String &name, const juce::var &value)\n        {\n            try\n            {\n                auto obj = runtime->global().getPropertyAsObject(*runtime, target.toRawUTF8());\n                obj.setProperty(*runtime, name.toRawUTF8(), varToJSIValue(value, *runtime));\n            }\n            catch (const jsi::JSIException &e)\n            {\n                throw Error(e.what());\n            }\n        }\n\n        //==============================================================================\n        //TODO: We can probably improve on this by refining the invoke API\n        juce::var invoke(const juce::String &name, const std::vector<juce::var> &vargs)\n        {\n            try\n            {\n                juce::StringArray accessors;\n                accessors.addTokens(name.trim(), \".\", \"\");\n                accessors.removeEmptyStrings();\n\n                jsi::Value prop = runtime->global();\n\n                for (auto &p : accessors)\n                {\n                    if (prop.isObject())\n                    {\n                        jsi::Object obj = prop.getObject(*runtime);\n                        prop = obj.getProperty(*runtime, p.toRawUTF8());\n                    }\n                }\n\n                auto func = prop.getObject(*runtime).asFunction(*runtime);\n\n                std::vector<jsi::Value> jsiArgs;\n                for (auto &v : vargs)\n                {\n                    jsiArgs.push_back(varToJSIValue(v, *runtime));\n                }\n\n                const jsi::Value *argsPtr = jsiArgs.data();\n                jsi::Value result = func.call(*runtime, argsPtr, jsiArgs.size());\n\n                return jsiValueToVar(result, *runtime);\n            }\n            catch(const jsi::JSIException &e)\n            {\n                throw Error(e.what());\n            }\n        }\n\n        //==============================================================================\n        jsi::Function createSetTimerFunction(bool isInterval)\n        {\n            return jsi::Function::createFromHostFunction(\n                *runtime,\n                jsi::PropNameID::forAscii(*runtime, \"\"),\n                0,\n                [=] (jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count)\n                {\n                    juce::ignoreUnused(thisVal);\n\n                    jsi::Function fn      = args[0].asObject(rt).asFunction(rt);\n                    const auto    timeout = static_cast<int>(args[1].asNumber());\n\n                    std::vector<jsi::Value> timeoutArgs;\n                    if (count > 2)\n                    {\n                        for (size_t i = 2; i < count; ++i)\n                        {\n                            timeoutArgs.emplace_back(jsi::Value(rt, args[i]));\n                        }\n                    }\n\n                    return timeoutsManager->newTimeout(std::move(fn), timeout, std::move(timeoutArgs), isInterval);\n                }\n            );\n        }\n\n        jsi::Function createClearTimerFunction()\n        {\n            return jsi::Function::createFromHostFunction(\n                *runtime,\n                jsi::PropNameID::forAscii(*runtime, \"\"),\n                0,\n                [this] (jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count)\n                {\n                    juce::ignoreUnused(rt);\n                    juce::ignoreUnused(thisVal);\n                    juce::ignoreUnused(count);\n\n                    const auto timerId = static_cast<int>(args[0].asNumber());\n                    return timeoutsManager->clearTimeout(timerId);\n                }\n            );\n        }\n\n        //==============================================================================\n        void reset()\n        {\n            if (timeoutsManager)\n                timeoutsManager->clear();\n\n            runtime         = facebook::hermes::makeHermesRuntime();\n            timeoutsManager = std::make_unique<TimeoutFunctionManager>(*runtime);\n\n            // Quick and dirty console object provide. Could be improved upon.\n            jsi::Function logFunction =\n                jsi::Function::createFromHostFunction(\n                    *runtime,\n                    jsi::PropNameID::forAscii(*runtime, \"\"),\n                    0,\n                    [] (jsi::Runtime& rt, const jsi::Value& thisVal, const jsi::Value* args, size_t count)\n                    {\n                        juce::ignoreUnused(thisVal);\n                        juce::String logString;\n\n                        for (size_t i = 0; i < count; ++i)\n                        {\n                            auto s = args[i].toString(rt).utf8(rt);\n                            logString.append(s, s.size());\n                            logString.append(\" \", 1u);\n                        }\n\n                        juce::Logger::writeToLog(logString);\n                        return jsi::Value();\n                    }\n                );\n\n            auto console = jsi::Object(*runtime);\n            console.setProperty(*runtime, \"log\", logFunction);\n\n            runtime->global().setProperty(*runtime, \"console\"      , console);\n            runtime->global().setProperty(*runtime, \"setTimeout\"   , createSetTimerFunction(false));\n            runtime->global().setProperty(*runtime, \"setInterval\"  , createSetTimerFunction(true));\n            runtime->global().setProperty(*runtime, \"clearTimeout\" , createClearTimerFunction());\n            runtime->global().setProperty(*runtime, \"clearInterval\", createClearTimerFunction());\n        }\n\n        void debuggerAttach()\n        {\n            //TODO: Implement Hermed debug support\n            jassertfalse;\n        }\n\n        void debuggerDetach()\n        {\n            //TODO: Implement Hermed debug support\n            jassertfalse;\n        }\n\n        std::unique_ptr<TimeoutFunctionManager>          timeoutsManager;\n        std::unique_ptr<facebook::hermes::HermesRuntime> runtime;\n    };\n\n    //==============================================================================\n\n}\n"
  },
  {
    "path": "react_juce/core/FileWatcher.h",
    "content": "/*\n  ==============================================================================\n\n    FileWatcher.h\n    Created: 10 Oct 2020 3:08:39pm\n\n  ==============================================================================\n*/\n\n#pragma once\n\n\nnamespace reactjuce\n{\n\n    //==============================================================================\n    /** Helper class which watches files for changes and triggers a user supplied\n     *  callback in thte event of a file change.\n     */\n    class FileWatcher : private juce::Timer\n    {\n    public:\n        using FileChangedCallback = std::function<void(void)>;\n\n        explicit FileWatcher (FileChangedCallback && callback)\n            : onFileChanged(std::move(callback)) {}\n\n        void start() { startTimer(50); }\n        void stop() { stopTimer(); }\n\n        void watch (const juce::File& f)\n        {\n            JUCE_ASSERT_MESSAGE_THREAD\n\n            jassert(f.existsAsFile());\n\n            // If we're already watching that bundle, nothing to do\n            if (watchedFiles.count(f) > 0)\n                return;\n\n            watchedFiles.emplace(f, f.getLastModificationTime());\n        }\n\n        std::vector<juce::File> getWatchedFiles()\n        {\n            std::vector<juce::File> ret;\n\n            for (const auto& pair : watchedFiles)\n                ret.push_back(pair.first);\n\n            return ret;\n        }\n\n    private:\n        void timerCallback() override\n        {\n            bool shouldFireChangeEvent = false;\n\n            // First step here is to be careful for empty files. Some bundlers\n            // may delete the target file just before replacing it with their\n            // new compiled result, and if we happen to poll in between we'll\n            // get a messed up result.\n            for (auto it = watchedFiles.begin(); it != watchedFiles.end();)\n            {\n                auto& f = (*it).first;\n                bool const fileExists = f.existsAsFile() && (f.getSize() > 0);\n\n                if (fileExists)\n                {\n                    const auto lmt = f.getLastModificationTime();\n\n                    if (lmt > (*it).second)\n                    {\n                        shouldFireChangeEvent = true;\n                        watchedFiles[f] = lmt;\n                    }\n                }\n\n                it++;\n            }\n\n            // Now we fire once if any bundle has changed, which coalesces changes\n            // into a single event in response to which we should re-evaluate\n            // all watched files.\n            if (shouldFireChangeEvent)\n            {\n                onFileChanged();\n            }\n        }\n\n        // It's important here that we're using a std::map because we want the\n        // insertion order retained. In the event of a file change, we want to\n        // re-evaluate all bundles within the cleaned engine in the same order\n        // we started with.\n        std::map<juce::File, juce::Time>            watchedFiles;\n        FileChangedCallback                         onFileChanged;\n    };\n\n}\n"
  },
  {
    "path": "react_juce/core/GenericEditor.cpp",
    "content": "/*\n  ==============================================================================\n\n    GenericEditor.cpp\n    Created: 3 Nov 2019 4:47:39pm\n\n  ==============================================================================\n*/\n\n#include \"GenericEditor.h\"\n\n\nnamespace reactjuce\n{\n\n    //==============================================================================\n    GenericEditor::GenericEditor (juce::AudioProcessor& proc, const juce::File& bundle)\n        : juce::AudioProcessorEditor (proc)\n        , engine(std::make_shared<EcmascriptEngine>())\n        , appRoot(engine)\n        , harness(appRoot)\n    {\n        // Sanity check\n        jassert (bundle.existsAsFile());\n        bundleFile = bundle;\n\n        // Now we set up parameter listeners and register their current values.\n        auto& params = processor.getParameters();\n        paramReadouts.resize(static_cast<size_t>(params.size()));\n\n        for (auto& p : params)\n        {\n            // Store the parameter ID for easy lookup in gesture lambdas\n            if (auto paramWithID = dynamic_cast<juce::AudioProcessorParameterWithID*>(p)) {\n                parameters.emplace(paramWithID->paramID, p);\n            }\n\n            const auto index = static_cast<size_t>(p->getParameterIndex());\n            const auto value = p->getValue();\n\n            paramReadouts[index].value = value;\n            paramReadouts[index].dirty = true;\n\n            p->addListener(this);\n        }\n\n        // Set up the hot reloading callbacks\n        harness.onBeforeAll = [this]() { beforeBundleEvaluated(); };\n        harness.onAfterAll = [this]() { afterBundleEvaluated(); };\n\n        // Set up the file watching and kick off the initial render\n        harness.watch(bundleFile);\n\n#if JUCE_DEBUG\n        // We only want to watch for compile changes in debug mode.\n        harness.start();\n#else\n        harness.once();\n#endif\n\n        // Add ReactApplicationRoot as child component\n        addAndMakeVisible(appRoot);\n\n        // Set an arbitrary size, should be overridden from outside the constructor\n        setSize(400, 200);\n\n        // Lastly, start our timer for reporting meter and parameter values\n        startTimerHz(30);\n    }\n\n    GenericEditor::~GenericEditor()\n    {\n        for (auto& p : processor.getParameters())\n        {\n            p->removeListener(this);\n        }\n    }\n\n    //==============================================================================\n    void GenericEditor::parameterValueChanged (int parameterIndex, float newValue)\n    {\n        // This callback often runs on the realtime thread. To avoid any blocking\n        // or non-deterministic operations, we simply set some atomic values in our\n        // paramReadouts list. The timer running on the PluginEditor will check to\n        // propagate the updated values to the javascript interface.\n        paramReadouts[static_cast<size_t>(parameterIndex)].value = newValue;\n        paramReadouts[static_cast<size_t>(parameterIndex)].dirty = true;\n    }\n\n    void GenericEditor::parameterGestureChanged (int, bool)\n    {\n        // Our generic editor doesn't do anything with this information yet, but\n        // we'll happily take a pull request if you need something here :).\n    }\n\n    //==============================================================================\n    void GenericEditor::timerCallback()\n    {\n        // Iterate here to dispatch any updated parameter values\n        for (size_t i = 0; i < paramReadouts.size(); ++i)\n        {\n            auto& pr = paramReadouts[i];\n\n            if (pr.dirty)\n            {\n                const float value = pr.value.load();\n                pr.dirty = false;\n\n                const auto& p = processor.getParameters()[(int) i];\n                juce::String id = p->getName(100);\n\n                if (auto* x = dynamic_cast<juce::AudioProcessorParameterWithID*>(p))\n                    id = x->paramID;\n\n                float defaultValue = p->getDefaultValue();\n                juce::String stringValue = p->getText(value, 0);\n\n                appRoot.dispatchEvent(\n                    \"parameterValueChange\",\n                    static_cast<int>(i),\n                    id,\n                    defaultValue,\n                    value,\n                    stringValue\n                );\n            }\n        }\n    }\n\n    //==============================================================================\n    void GenericEditor::resized()\n    {\n        // Ensure our ReactApplicationRoot always fills the entire bounds\n        // of this editor.\n        appRoot.setBounds(getLocalBounds());\n    }\n\n    void GenericEditor::paint(juce::Graphics& g)\n    {\n        g.fillAll(juce::Colours::transparentWhite);\n    }\n\n    //==============================================================================\n    void GenericEditor::beforeBundleEvaluated()\n    {\n        engine->registerNativeMethod(\n            \"beginParameterChangeGesture\",\n            [this](const juce::var::NativeFunctionArgs& args) {\n                if (auto it = parameters.find (args.arguments[0].toString()); it != parameters.cend())\n                    it->second->beginChangeGesture();\n\n                return juce::var::undefined();\n            }\n        );\n\n        engine->registerNativeMethod(\n            \"setParameterValueNotifyingHost\",\n            [this](const juce::var::NativeFunctionArgs& args) {\n                if (auto it = parameters.find (args.arguments[0].toString()); it != parameters.cend())\n                    it->second->setValueNotifyingHost(args.arguments[1]);\n\n                return juce::var::undefined();\n            }\n        );\n\n        engine->registerNativeMethod(\n            \"endParameterChangeGesture\",\n            [this](const juce::var::NativeFunctionArgs& args) {\n                if (auto it = parameters.find (args.arguments[0].toString()); it != parameters.cend())\n                    it->second->endChangeGesture();\n\n                return juce::var::undefined();\n            }\n        );\n    }\n\n    void GenericEditor::afterBundleEvaluated()\n    {\n        // Push current parameter values into the bundle on load\n        for (auto& p : processor.getParameters())\n            parameterValueChanged(p->getParameterIndex(), p->getValue());\n    }\n\n}\n"
  },
  {
    "path": "react_juce/core/GenericEditor.h",
    "content": "/*\n  ==============================================================================\n\n    GenericEditor.h\n    Created: 3 Nov 2019 4:47:39pm\n\n  ==============================================================================\n*/\n\n#pragma once\n\n#include \"AppHarness.h\"\n#include \"ReactApplicationRoot.h\"\n\n\nnamespace reactjuce\n{\n\n    //==============================================================================\n    /** The Editor is a default AudioProcessorEditor with preinstalled functionality\n     *  for working with React.\n     *\n     *  It automatically manages a ReactApplicationRoot, registers some native methods\n     *  and properties for interfacing with the editor, and provides some helpful\n     *  development tools.\n     */\n    class GenericEditor\n        : public juce::AudioProcessorEditor\n        , public juce::AudioProcessorParameter::Listener\n        , public juce::Timer\n    {\n    public:\n        //==============================================================================\n        GenericEditor (juce::AudioProcessor&, const juce::File&);\n        ~GenericEditor() override;\n\n        //==============================================================================\n        /** Implement the AudioProcessorParameter::Listener interface. */\n        void parameterValueChanged (int parameterIndex, float newValue) override;\n        void parameterGestureChanged (int parameterIndex, bool gestureIsStarting) override;\n\n        //==============================================================================\n        /** Override the timer interface. */\n        void timerCallback() override;\n\n        //==============================================================================\n        /** Override the component interface. */\n        void resized() override;\n        void paint (juce::Graphics&) override;\n        \n        /** Public getter to access appRoot instance */\n        ReactApplicationRoot& getReactAppRoot() { return appRoot; }\n\n    private:\n        //==============================================================================\n        /** ReactApplicationRoot bundle eval callback functions */\n        void beforeBundleEvaluated();\n        void afterBundleEvaluated();\n\n        //==============================================================================\n        std::shared_ptr<EcmascriptEngine>     engine;\n        ReactApplicationRoot                  appRoot;\n        AppHarness                            harness;\n\n        juce::File                            bundleFile;\n\n        // We keep a map of the parameter IDs and their associated parameter pointers\n        // to have a quick lookup in beforeBundleEvaluated where lambdas are called\n        // with a param ID\n        std::map<juce::String, juce::AudioProcessorParameter*> parameters;\n\n        //==============================================================================\n        // The plugin editor holds an array of parameter value readouts which are\n        // propagated to the user interface. During parameter value changes on the\n        // realtime thread, we capture the values in this array of structs, then at\n        // 30Hz propagate the value changes via dispatching events to the jsui.\n        struct ParameterReadout {\n            std::atomic<float> value = 0.0;\n            std::atomic<bool> dirty = false;\n\n            ParameterReadout() = default;\n\n            ParameterReadout(const ParameterReadout& other) {\n                value = other.value.load();\n                dirty = other.dirty.load();\n            }\n        };\n\n        std::vector<ParameterReadout> paramReadouts;\n\n        //==============================================================================\n        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GenericEditor)\n    };\n\n}\n"
  },
  {
    "path": "react_juce/core/ImageView.cpp",
    "content": "/*\n  ==============================================================================\n\n    ImageView.cpp\n    Created: 13 Jan 2021 10:54pm\n\n  ==============================================================================\n*/\n\n#include \"ImageView.h\"\n#include \"Utils.h\"\n\nnamespace\n{\n    // juce::URL::isWellFormed is currently not a complete\n    // implementation, so we have this slightly more robust check\n    // for now.\n    bool isWellFormedURL(const juce::URL& url)\n    {\n        return url.isWellFormed() &&\n            url.getScheme().isNotEmpty() &&\n            !url.toString(false).startsWith(\"data\");\n    }\n\n}\n\nnamespace reactjuce\n{\n    //==============================================================================\n    void ImageView::setProperty(const juce::Identifier& name, const juce::var& value)\n    {\n        View::setProperty(name, value);\n\n        if (name == sourceProp)\n        {\n            const juce::String source = value.toString();\n            const int sourceHash      = juce::DefaultHashFunctions::generateHash(source, 1024);\n\n            // No need to recalculate the image if it's already in the ImageCache.\n            const juce::Image& cachedImage = juce::ImageCache::getFromHashCode(sourceHash);\n            if (cachedImage.isValid())\n                return setDrawableImage(cachedImage, sourceHash);\n\n            try\n            {\n                const juce::URL sourceURL = source;\n\n                // Web images are downloaded in a separate thread to avoid blocking.\n                if (isWellFormedURL(sourceURL) && sourceURL.isProbablyAWebsiteURL(sourceURL.toString(false)))\n                    return downloadImageAsync(source);\n\n                if (sourceURL.isLocalFile())\n                {\n                    const juce::File imageFile = sourceURL.getLocalFile();\n\n                    if (imageFile.getFileExtension() == \".svg\")\n                        return setDrawableSVG(imageFile);\n                    else\n                        return setDrawableImage(loadImageFromFile(imageFile), sourceHash);\n                }\n\n                if (source.startsWith(\"data:image/\")) // juce::URL does not currently handle Data URLs\n                    return setDrawableImage(loadImageFromDataURL(source), sourceHash);\n\n                // Last case left, raw Image data.\n                return setDrawableData(source);\n            }\n            catch (const std::exception& l)\n            {\n                // Every image format can throw an exception that we catch here\n                // to send an onError callback to the React component.\n                return sendOnErrorCallback(juce::String(l.what()));\n            }\n        }\n    }\n\n    //==============================================================================\n    void ImageView::paint(juce::Graphics& g)\n    {\n        View::paint(g);\n\n        if (drawable == nullptr) return;\n\n        const float opacity = props.getWithDefault(opacityProp, 1.0f);\n\n        // Without a specified placement, we just draw the drawable.\n        if (!props.contains(placementProp))\n            return drawable->draw(g, opacity);\n\n        // Otherwise we map placement strings to the appropriate flags\n        const int existingFlags = props[placementProp];\n        const juce::RectanglePlacement placement(existingFlags);\n\n        drawable->drawWithin(g, getLocalBounds().toFloat(), placement, opacity);\n    }\n\n    //==============================================================================\n    void ImageView::sendOnLoadCallback()\n    {\n        // Notify JS that image is loaded.\n        if (props.contains(onloadProp) && props[onloadProp].isMethod())\n            std::invoke(props[onloadProp].getNativeFunction(), juce::var::NativeFunctionArgs(juce::var(), {}, 0));\n    }\n\n    //==============================================================================\n    void ImageView::sendOnErrorCallback(const juce::String& message)\n    {\n        // Send an error callback to JS.\n        if (props.contains(onerrorProp) && props[onerrorProp].isMethod())\n        {\n            std::vector<juce::var> jsArgs{ {detail::makeErrorObject(\"ImageViewError\", message)} };\n            juce::var::NativeFunctionArgs nfArgs(juce::var(), jsArgs.data(), static_cast<int>(jsArgs.size()));\n            std::invoke(props[onerrorProp].getNativeFunction(), nfArgs);\n        }\n    }\n\n    //==============================================================================\n    void ImageView::setDrawableImage(const juce::Image& image, const int sourceHash)\n    {\n        // Add the freshly retrieved image to the cache.\n        juce::ImageCache::addImageToCache(image, sourceHash);\n\n        auto drawableImg = std::make_unique<juce::DrawableImage>();\n        drawableImg->setImage(image);\n        drawable = std::move(drawableImg);\n\n        repaint();\n        sendOnLoadCallback();\n    }\n\n    void ImageView::setDrawableSVG(const juce::File& svgFile)\n    {\n        if (!svgFile.existsAsFile())\n        {\n            const juce::String errorString = \"SVG file does not exist: \" + svgFile.getFullPathName();\n            throw std::logic_error(errorString.toStdString());\n        }\n\n        drawable = std::unique_ptr<juce::Drawable>(\n                juce::Drawable::createFromSVGFile(svgFile));\n\n        if (drawable == nullptr)\n        {\n            const juce::String errorString = \"Invalid SVG file: \" + svgFile.getFullPathName();\n            throw std::logic_error(errorString.toStdString());\n        }\n\n        repaint();\n        sendOnLoadCallback();\n    }\n\n    void ImageView::setDrawableData(const juce::String& source)\n    {\n        // If not a URL treat source prop as inline SVG/Image data\n        drawable = std::unique_ptr<juce::Drawable>(\n            juce::Drawable::createFromImageData(\n                source.toRawUTF8(),\n                source.getNumBytesAsUTF8()\n            )\n        );\n\n        if (drawable == nullptr)\n        {\n            const juce::String errorString = \"Unsupported image URL: \" + source;\n            throw std::logic_error(errorString.toStdString());\n        }\n\n        repaint();\n        sendOnLoadCallback();\n    }\n\n    //==============================================================================\n    void ImageView::parentHierarchyChanged()\n    {\n        if (shouldDownloadImage)\n        {\n            downloadImageAsync(props[sourceProp].toString());\n        }\n    }\n\n    //==============================================================================\n    void ImageView::downloadImageAsync(const juce::String& source)\n    {\n        if (auto* appRoot = findParentComponentOfClass<ReactApplicationRoot>())\n        {\n            appRoot->getThreadPool().addJob([this, source] ()\n            {\n                shouldDownloadImage = false;\n                juce::MemoryBlock mb;\n\n                // Did we reach the URL?\n                if (!juce::URL(source).readEntireBinaryStream(mb))\n                {\n                    juce::MessageManager::callAsync([this]() {\n                        sendOnErrorCallback(\"Could not reach URL\");\n                    });\n                    return;\n                }\n\n                auto image = juce::ImageFileFormat::loadFrom(mb.getData(), mb.getSize());\n                if (image.isValid())\n                {\n                    juce::MessageManager::callAsync([this, image, source]()\n                    {\n                        // At this point, there may be multiple downloads happening at the same time,\n                        // so we need to be sure the one that's just finished matches the current sourceProp.\n                        if (source == props[sourceProp].toString())\n                        {\n                            auto sourceHash = juce::DefaultHashFunctions::generateHash(source, 1024);\n                            setDrawableImage(image, sourceHash);\n                        }\n                    });\n                }\n                else\n                {\n                    // The URL was valid but was not pointing to a valid image.\n                    juce::MessageManager::callAsync([this]() {\n                        sendOnErrorCallback(\"The URL was not pointing to a valid image\");\n                    });\n                }\n            });\n        }\n        else\n        {\n            // It will be called later on parentHierarchyChanged.\n            shouldDownloadImage = true;\n        }\n    }\n\n    //==============================================================================\n    juce::Image ImageView::loadImageFromFile(const juce::File& imageFile) const\n    {\n        if (!imageFile.existsAsFile())\n        {\n            const juce::String errorString = \"Image file does not exist: \" + imageFile.getFullPathName();\n            throw std::logic_error(errorString.toStdString());\n        }\n\n        juce::Image image = juce::ImageFileFormat::loadFrom(imageFile);\n\n        if (image.isNull())\n        {\n            const juce::String errorString = \"Unable to load image file: \" + imageFile.getFullPathName();\n            throw std::logic_error(errorString.toStdString());\n        }\n\n        return image;\n    }\n\n    //==============================================================================\n    juce::Image ImageView::loadImageFromDataURL(const juce::String& source) const\n    {\n        // source is a data URL that describes image.\n        // the format is `data:[<mediatype>][;base64],<data>`\n        // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs\n        const int commaIndex = source.indexOf(\",\");\n        const int semiIndex = source.indexOf(\";\");\n\n        if (commaIndex == -1 || semiIndex == -1)\n        {\n            throw std::runtime_error(\"Image received an invalid data url.\");\n        }\n\n        const auto base64EncodedData = source.substring(commaIndex + 1);\n        juce::MemoryOutputStream outStream{};\n\n        if (!juce::Base64::convertFromBase64(outStream, base64EncodedData))\n        {\n            throw std::runtime_error(\"Image failed to convert data url.\");\n        }\n\n        juce::MemoryInputStream inputStream(outStream.getData(), outStream.getDataSize(), false);\n\n        const auto mimeType = source.substring(5, semiIndex);\n        auto fmt = prepareImageFormat(mimeType);\n\n        if (fmt == nullptr)\n        {\n            throw std::runtime_error(\"Unsupported format.\");\n        }\n\n        if (!fmt->canUnderstand(inputStream))\n        {\n            throw std::runtime_error(\"Cannot understand the image.\");\n        }\n\n        inputStream.setPosition(0);\n        return fmt->decodeImage(inputStream);\n    }\n\n    std::unique_ptr<juce::ImageFileFormat> ImageView::prepareImageFormat(const juce::String& mimeType) const\n    {\n        if (mimeType == \"image/png\")\n        {\n            return std::make_unique<juce::PNGImageFormat>();\n        }\n\n        if (mimeType == \"image/jpeg\")\n        {\n            return std::make_unique<juce::JPEGImageFormat>();\n        }\n\n        if (mimeType == \"image/gif\")\n        {\n            return std::make_unique<juce::GIFImageFormat>();\n        }\n        return nullptr;\n    }\n}\n"
  },
  {
    "path": "react_juce/core/ImageView.h",
    "content": "/*\n  ==============================================================================\n\n    ImageView.h\n    Created: 20 Apr 2019 5:25:25pm\n\n  ==============================================================================\n*/\n\n#pragma once\n\n#include \"View.h\"\n\n\nnamespace reactjuce\n{\n    //==============================================================================\n    /** The ImageView class is a core view for rendering images from React. */\n    class ImageView : public View\n    {\n    public:\n        //==============================================================================\n        static inline juce::Identifier sourceProp    = \"source\";\n        static inline juce::Identifier placementProp = \"placement\";\n        static inline juce::Identifier onloadProp    = \"onLoad\";\n        static inline juce::Identifier onerrorProp   = \"onError\";\n\n        //==============================================================================\n        ImageView() = default;\n\n        //==============================================================================\n        void setProperty(const juce::Identifier& name, const juce::var& value) override;\n        void paint(juce::Graphics& g) override;\n        void parentHierarchyChanged() override;\n        //==============================================================================\n    private:\n        //==============================================================================\n        void downloadImageAsync(const juce::String& source);\n        void sendOnLoadCallback();\n        void sendOnErrorCallback(const juce::String& message);\n        void setDrawableImage(const juce::Image& image, const int sourceHash);\n        void setDrawableSVG(const juce::File& svgFile);\n        void setDrawableData(const juce::String& source);\n        juce::Image loadImageFromFile(const juce::File& imageFile) const;\n        juce::Image loadImageFromDataURL(const juce::String& source) const;\n        std::unique_ptr<juce::ImageFileFormat> prepareImageFormat(const juce::String& mimeType) const;\n\n        //==============================================================================\n        std::unique_ptr<juce::Drawable> drawable;\n\n        // To manage the download thread\n        bool shouldDownloadImage{ false };\n\n        //==============================================================================\n        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ImageView)\n    };\n}\n"
  },
  {
    "path": "react_juce/core/RawTextView.h",
    "content": "/*\n  ==============================================================================\n\n    RawTextView.h\n    Created: 11 Apr 2019 11:27:27am\n\n  ==============================================================================\n*/\n\n#pragma once\n\n#include \"View.h\"\n\n\nnamespace reactjuce\n{\n\n    //==============================================================================\n    /** The RawTextView class is more or less a wrapper around a string that asserts\n        itself as a leaf node in the tree by refusing a resize and painting nothing.\n\n        It provides an interface for a parent TextView to draw a collection of\n        RawTextView children. For example,\n\n            `<Text>123 Avenue Avenue {'\\n'} City, St 12345</Text>`\n\n        creates three RawTextView children of a single TextView. But independently\n        these raw text strings can't know how to lay themselves out correctly.\n     */\n    class RawTextView : public View\n    {\n    public:\n        //==============================================================================\n        RawTextView(const juce::String& text) : _text(text) {}\n\n        //==============================================================================\n        void setProperty (const juce::Identifier&, const juce::var&) override\n        {\n            throw std::logic_error(\"A RawTextView can't receive properties.\");\n        }\n\n        //==============================================================================\n        void setText (const juce::String& text) {\n            _text = text;\n        }\n\n        juce::String getText()\n        {\n            return _text;\n        }\n\n    private:\n        //==============================================================================\n        juce::String _text;\n\n        //==============================================================================\n        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (RawTextView)\n    };\n\n}\n"
  },
  {
    "path": "react_juce/core/ReactApplicationRoot.cpp",
    "content": "/*\n  ==============================================================================\n\n    ReactApplicationRoot.cpp\n    Created: 9 Dec 2018 10:20:37am\n\n  ==============================================================================\n*/\n\n#include \"ReactApplicationRoot.h\"\n\n\nnamespace reactjuce\n{\n\n    ReactApplicationRoot::ReactApplicationRoot(std::shared_ptr<EcmascriptEngine> ee)\n        : viewManager(this)\n        , engine(ee)\n    {\n        JUCE_ASSERT_MESSAGE_THREAD\n        jassert(ee != nullptr);\n\n        bindNativeRenderingHooks();\n\n#if JUCE_DEBUG\n        // Enable keyboardFocus to support CTRL-D/CMD-D debug attachment.\n        setWantsKeyboardFocus(true);\n#endif\n    }\n\n    ReactApplicationRoot::ReactApplicationRoot()\n        : ReactApplicationRoot(std::make_shared<EcmascriptEngine>()) {}\n\n    //==============================================================================\n    juce::var ReactApplicationRoot::createViewInstance (const juce::String& viewType)\n    {\n        return juce::var(viewManager.createViewInstance(viewType));\n    }\n\n    juce::var ReactApplicationRoot::createTextViewInstance (const juce::String& textValue)\n    {\n        return juce::var(viewManager.createTextViewInstance(textValue));\n    }\n\n    juce::var ReactApplicationRoot::setViewProperty (const ViewId viewId, const juce::String& name, const juce::var& value)\n    {\n        viewManager.setViewProperty(viewId, name, value);\n        return juce::var::undefined();\n    }\n\n    juce::var ReactApplicationRoot::setRawTextValue (const ViewId viewId, const juce::String& value)\n    {\n        viewManager.setRawTextValue(viewId, value);\n        return juce::var::undefined();\n    }\n\n    juce::var ReactApplicationRoot::insertChild (const ViewId parentId, const ViewId childId, int index)\n    {\n        viewManager.insertChild(parentId, childId, index);\n        return juce::var::undefined();\n    }\n\n    juce::var ReactApplicationRoot::removeChild (const ViewId parentId, const ViewId childId)\n    {\n        viewManager.removeChild(parentId, childId);\n        return juce::var::undefined();\n    }\n\n    juce::var ReactApplicationRoot::getRootInstanceId()\n    {\n        return juce::var(getViewId());\n    }\n\n    juce::var ReactApplicationRoot::resetAfterCommit()\n    {\n        viewManager.performRootShadowTreeLayout();\n        return juce::var::undefined();\n    }\n\n    //==============================================================================\n    void ReactApplicationRoot::resized()\n    {\n        viewManager.performRootShadowTreeLayout();\n    }\n\n    void ReactApplicationRoot::paint(juce::Graphics& g)\n    {\n        if (errorText)\n        {\n            g.fillAll(juce::Colour(0xffe14c37));\n            errorText->draw(g, getLocalBounds().toFloat().reduced(10.f));\n        }\n        else\n        {\n            View::paint(g);\n        }\n    }\n\n#if JUCE_DEBUG\n    bool ReactApplicationRoot::keyPressed(const juce::KeyPress& key)\n    {\n        const auto startDebugCommand = juce::KeyPress('d', juce::ModifierKeys::commandModifier, 0);\n\n        if (key == startDebugCommand)\n            engine->debuggerAttach();\n\n        return true;\n    }\n#endif\n\n    //==============================================================================\n    juce::var ReactApplicationRoot::evaluate(const juce::File& bundle)\n    {\n        JUCE_ASSERT_MESSAGE_THREAD\n\n        try\n        {\n            return engine->evaluate(bundle);\n        }\n        catch (const EcmascriptEngine::Error& err)\n        {\n            handleRuntimeError(err);\n            return juce::var();\n        }\n    }\n\n    juce::var ReactApplicationRoot::evaluateBytecode(const juce::File &code)\n    {\n        JUCE_ASSERT_MESSAGE_THREAD\n\n        try\n        {\n            return engine->evaluateBytecode(code);\n        }\n        catch (const EcmascriptEngine::Error& err)\n        {\n            handleRuntimeError(err);\n            return juce::var();\n        }\n    }\n\n    //==============================================================================\n    void ReactApplicationRoot::registerViewType(const juce::String& typeId, ViewManager::ViewFactory f)\n    {\n        viewManager.registerViewType(typeId, f);\n    }\n\n    //==============================================================================\n    void ReactApplicationRoot::handleRuntimeError(const EcmascriptEngine::Error& err)\n    {\n#if ! JUCE_DEBUG\n        // In release builds, we don't catch errors and show the red screen,\n        // we allow the exception to raise up to the user to be handled properly\n        // for a production app.\n        throw err;\n#endif\n\n        JUCE_ASSERT_MESSAGE_THREAD\n\n        DBG(\"\");\n        DBG(\"==== Error in JavaScript runtime. Context: ====\");\n        DBG(err.context);\n        DBG(\"\");\n        DBG(err.what());\n\n        errorText = std::make_unique<juce::AttributedString>(err.what());\n        errorText->append(\"\\n\\n\");\n        errorText->append(err.stack);\n\n#if JUCE_WINDOWS\n        errorText->setFont(juce::Font(\"Lucida Console\", 18, juce::Font::FontStyleFlags::plain));\n#elif JUCE_MAC\n        errorText->setFont(juce::Font(\"Monaco\", 18, juce::Font::FontStyleFlags::plain));\n#else\n        errorText->setFont(18);\n#endif\n\n        // Lastly, kill the ViewManager to tear down existing views and prevent\n        // further view interaction\n        viewManager.clearViewTables();\n\n        repaint();\n    }\n\n    void ReactApplicationRoot::reset()\n    {\n        viewManager.clearViewTables();\n        engine->reset();\n        errorText = nullptr;\n    }\n\n    void ReactApplicationRoot::bindNativeRenderingHooks()\n    {\n        const auto ns = \"__NativeBindings__\";\n\n        engine->registerNativeProperty(ns, juce::JSON::parse(\"{}\"));\n\n        engine->registerNativeMethod(ns, \"invokeViewMethod\", [this](const juce::var::NativeFunctionArgs& args) -> juce::var\n        {\n            jassert(args.numArguments >= 2);\n            const ViewId       viewId = args.arguments[0];\n            const juce::String method = args.arguments[1];\n\n            const juce::var::NativeFunctionArgs methodArgs(args.thisObject, args.arguments + 2, args.numArguments - 2);\n            return viewManager.invokeViewMethod(viewId, method, methodArgs);\n        });\n\n        addMethodBinding<1>(ns, \"createViewInstance\", &ReactApplicationRoot::createViewInstance);\n        addMethodBinding<1>(ns, \"createTextViewInstance\", &ReactApplicationRoot::createTextViewInstance);\n        addMethodBinding<3>(ns, \"setViewProperty\", &ReactApplicationRoot::setViewProperty);\n        addMethodBinding<2>(ns, \"setRawTextValue\", &ReactApplicationRoot::setRawTextValue);\n        addMethodBinding<3>(ns, \"insertChild\", &ReactApplicationRoot::insertChild);\n        addMethodBinding<2>(ns, \"removeChild\", &ReactApplicationRoot::removeChild);\n        addMethodBinding<0>(ns, \"getRootInstanceId\", &ReactApplicationRoot::getRootInstanceId);\n        addMethodBinding<0>(ns, \"resetAfterCommit\", &ReactApplicationRoot::resetAfterCommit);\n    }\n\n    juce::ThreadPool&  ReactApplicationRoot::getThreadPool()\n    {\n        return threadPool;\n    }\n\n}\n"
  },
  {
    "path": "react_juce/core/ReactApplicationRoot.h",
    "content": "/*\n  ==============================================================================\n\n    ReactApplicationRoot.h\n    Created: 9 Dec 2018 10:20:37am\n\n  ==============================================================================\n*/\n\n#pragma once\n\n#include \"EcmascriptEngine.h\"\n#include \"FileWatcher.h\"\n#include \"View.h\"\n#include \"ViewManager.h\"\n\n\nnamespace reactjuce\n{\n\n    //==============================================================================\n    /** The ReactApplicationRoot class is the primary point of coordination between\n     *  the React.js reconciler and the native View heirarchy.\n     *\n     *  By default, ReactApplicationRoot implements a generic error handler which will\n     *  catch errors from JavaScript code and display an error screen with a stack trace\n     *  and error message. This generic error handler is enabled by default in Debug builds,\n     *  and in Release builds such errors will be thrown, with the intention that the end\n     *  user should catch and handle them appropriately.\n     *\n     *  ReactApplicationRoot also provides debug functionality similar to React Native.\n     *  Users can hit CTRL-D/CMD-D when the ReactApplicationRoot component has focus,\n     *  causing the application to suspend execution and await connection from a debug client.\n     *  See the documentation for details on setting up and connecting a debugger.\n     */\n    class ReactApplicationRoot : public View\n    {\n    public:\n        //==============================================================================\n        explicit ReactApplicationRoot(std::shared_ptr<EcmascriptEngine> ee);\n        ReactApplicationRoot();\n\n        //==============================================================================\n        /** The main rendering interface. */\n        juce::var createViewInstance (const juce::String& viewType);\n        juce::var createTextViewInstance (const juce::String& textValue);\n        juce::var setViewProperty (const ViewId viewId, const juce::String& name, const juce::var& value);\n        juce::var setRawTextValue (const ViewId viewId, const juce::String& value);\n        juce::var insertChild (const ViewId parentId, const ViewId childId, int index);\n        juce::var removeChild (const ViewId parentId, const ViewId childId);\n        juce::var getRootInstanceId();\n        juce::var resetAfterCommit();\n\n        //==============================================================================\n        /** Override the default resized behavior. */\n        void resized() override;\n\n        /** Override the default paint behavior. */\n        void paint(juce::Graphics& g) override;\n\n#if JUCE_DEBUG\n        /** In debug builds, we add a keypress handler to toggle debugging. */\n        bool keyPressed(const juce::KeyPress& key) override;\n#endif\n\n        //==============================================================================\n        /** Evaluates a javascript bundle file in the EcmascriptEngine.\n         *\n         * Provides default error handling to display the red screen with error\n         * message and stack trace.\n         */\n        juce::var evaluate(const juce::File& bundle);\n\n        /** Overload for evaluating precompiled bytecode file in engines which support this.\n         *\n         * Provides default error handling to display the red screen with error\n         * message and stack trace.\n         */\n        juce::var evaluateBytecode(const juce::File &code);\n\n        /** Install a custom view type into the view manager. */\n        void registerViewType(const juce::String& typeId, ViewManager::ViewFactory f);\n\n        /** Dispatches an event through the EventBridge. */\n        template <typename... T>\n        void dispatchEvent (const juce::String& eventType, T... args)\n        {\n            JUCE_ASSERT_MESSAGE_THREAD\n\n            // We early return here in the event that we're currently showing the red error\n            // screen. This prevents subsequent errors caused by dispatching events with an\n            // incorrect engine state from overwriting the first error message.\n            if (errorText)\n                return;\n\n            try {\n                engine->invoke(\"__NativeBindings__.dispatchEvent\", eventType, std::forward<T>(args)...);\n            } catch (const EcmascriptEngine::Error& err) {\n                handleRuntimeError(err);\n            }\n        }\n\n        /** Dispatches a view event through the internal event replayer. */\n        template <typename... T>\n        void dispatchViewEvent (T... args)\n        {\n            JUCE_ASSERT_MESSAGE_THREAD\n\n            // We early return here in the event that we're currently showing the red error\n            // screen. This prevents subsequent errors caused by dispatching events with an\n            // incorrect engine state from overwriting the first error message.\n            if (errorText)\n                return;\n\n            try {\n                engine->invoke(\"__NativeBindings__.dispatchViewEvent\", std::forward<T>(args)...);\n            } catch (const EcmascriptEngine::Error& err) {\n                handleRuntimeError(err);\n            }\n        }\n\n        //==============================================================================\n        /** Displays the red error screen for the given error. */\n        void handleRuntimeError(const EcmascriptEngine::Error& err);\n\n        /** Clears the internal EcmascriptEngine and view table. */\n        void reset();\n\n        /** Installs the rendering hooks needed by the React reconciler into the\n         *  EcmascriptEngine environment.\n         *\n         *  Should be called after every `reset` and before evaluating the bundle.\n         */\n        void bindNativeRenderingHooks();\n\n        /** Get a handle to the internal threadpool. */\n        juce::ThreadPool& getThreadPool();\n\n    private:\n        //==============================================================================\n        template <int NumParams, typename MethodType>\n        juce::var invokeFromNativeFunction (MethodType method, const juce::var::NativeFunctionArgs& args)\n        {\n            static_assert (NumParams <= 4);\n\n            if (args.numArguments != NumParams)\n                return juce::var::undefined();\n\n            if constexpr (NumParams == 0)    return (this->*method)();\n            if constexpr (NumParams == 1)    return (this->*method)(args.arguments[0]);\n            if constexpr (NumParams == 2)    return (this->*method)(args.arguments[0], args.arguments[1]);\n            if constexpr (NumParams == 3)    return (this->*method)(args.arguments[0], args.arguments[1], args.arguments[2]);\n            if constexpr (NumParams == 4)    return (this->*method)(args.arguments[0], args.arguments[1], args.arguments[2], args.arguments[3]);\n\n            return {};\n        }\n\n        template <int NumParams, typename MethodType>\n        void addMethodBinding (const char* ns, const char* name, MethodType method) {\n            engine->registerNativeMethod(\n                ns,\n                name,\n                [this, method] (const juce::var::NativeFunctionArgs& args) -> juce::var {\n                    return invokeFromNativeFunction<NumParams>(method, args);\n                }\n            );\n        }\n\n        //==============================================================================\n        ViewManager viewManager;\n\n        // This will be used by components to asynchronously download content from an web url.\n        juce::ThreadPool threadPool;\n\n        std::shared_ptr<EcmascriptEngine>       engine;\n        std::unique_ptr<juce::AttributedString> errorText;\n\n        //==============================================================================\n        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ReactApplicationRoot)\n    };\n}\n"
  },
  {
    "path": "react_juce/core/ScrollView.cpp",
    "content": "/*\n  ==============================================================================\n\n    ScrollView.cpp\n    Created: 10 Nov 2020 18:07pm\n\n  ==============================================================================\n*/\n\n#include \"ScrollView.h\"\n\n\nnamespace reactjuce\n{\n    namespace detail\n    {\n        juce::var makeScrollEventObject(float scrollTopPosition, float scrollLeftPosition)\n        {\n            juce::DynamicObject::Ptr obj = new juce::DynamicObject();\n            obj->setProperty(\"scrollTop\", scrollTopPosition);\n            obj->setProperty(\"scrollLeft\", scrollLeftPosition);\n            return obj.get();\n        }\n    }\n\n    //==============================================================================\n    ScrollView::ScrollView()\n    {\n        // Use a default scrollEvent rate of 30Hz.\n        // This is prop configurable\n        startTimerHz(30);\n\n        viewport.onAreaChanged([this](const juce::Rectangle<int>& area)\n        {\n            lastScrollEvent.event = detail::makeScrollEventObject(area.getY(), area.getX());\n            lastScrollEvent.dirty = true;\n        });\n\n        addAndMakeVisible(viewport);\n        viewport.setScrollBarsShown(true, true);\n\n        exportNativeMethods();\n    }\n\n    void ScrollView::setProperty (const juce::Identifier& name, const juce::var& value)\n    {\n        View::setProperty(name, value);\n\n        auto showX = viewport.isHorizontalScrollBarShown();\n        auto showY = viewport.isVerticalScrollBarShown();\n\n        auto overflowCheck = [](const juce::String& p, const juce::String &v)\n        {\n            if (juce::StringRef(\"scroll\") == v) { return true; }\n            if (juce::StringRef(\"hidden\") == v) { return false; }\n\n            const juce::String e = \"Invalid prop value. Prop '\" + p + \"' must be a string of 'hidden' or 'scroll'\";\n            throw std::invalid_argument(e.toStdString());\n        };\n\n        if (name == overflowYProp)\n        {\n            showY = overflowCheck(overflowYProp.toString(), value);\n        }\n\n        if (name == overflowXProp)\n        {\n            showX = overflowCheck(overflowXProp.toString(), value);\n        }\n\n        viewport.setScrollBarsShown(showY, showX);\n\n        if (name == scrollBarWidthProp)\n        {\n            if (!props[scrollBarWidthProp].isDouble())\n                throw std::invalid_argument(\"Invalid prop value. Prop \\'scollbar-width\\' must be a number.\");\n\n            const int thickness = props[scrollBarWidthProp];\n            viewport.setScrollBarThickness(thickness);\n        }\n\n        if (name == scrollbarThumbColorProp)\n        {\n            if (!props[scrollbarThumbColorProp].isString())\n                throw std::invalid_argument(\"Invalid prop value. Prop \\'scrollbar-thumb-color\\' must be a color string.\");\n\n            const auto thumbColor = juce::Colour::fromString(props[scrollbarThumbColorProp].toString());\n            viewport.getVerticalScrollBar().setColour(juce::ScrollBar::thumbColourId, thumbColor);\n            viewport.getHorizontalScrollBar().setColour(juce::ScrollBar::thumbColourId, thumbColor);\n        }\n\n        if (name == scrollbarTrackColorProp)\n        {\n            if (!props[scrollbarTrackColorProp].isString())\n                throw std::invalid_argument(\"Invalid prop value. Prop \\'scrollbar-track-color\\' must be a color string.\");\n\n            const auto trackColor = juce::Colour::fromString(props[scrollbarTrackColorProp].toString());\n            viewport.getVerticalScrollBar().setColour(juce::ScrollBar::trackColourId, trackColor);\n            viewport.getHorizontalScrollBar().setColour(juce::ScrollBar::trackColourId, trackColor);\n        }\n\n        if (name == scrollOnDragProp)\n        {\n            if (!props[scrollOnDragProp].isBool())\n                throw std::invalid_argument(\"Invalid prop value. Prop \\'scroll-on-drag\\' must be a bool.\");\n\n            const bool scrollOnDrag = props[scrollOnDragProp];\n            viewport.setScrollOnDragEnabled(scrollOnDrag);\n        }\n    }\n\n    void ScrollView::addChild (View* childView, int index)\n    {\n        juce::ignoreUnused (index);\n        jassert (viewport.getViewedComponent() == nullptr);\n        viewport.setViewedComponent(childView, false);\n    }\n\n    void ScrollView::resized()\n    {\n        const auto &bounds = getLocalBounds();\n        viewport.setBounds(bounds);\n        View::resized();\n    }\n\n    void ScrollView::timerCallback()\n    {\n        if (lastScrollEvent.dirty)\n        {\n            if (props.contains(onScrollProp) && props[onScrollProp].isMethod())\n            {\n                std::array<juce::var, 1> args { lastScrollEvent.event };\n                juce::var::NativeFunctionArgs nfArgs(juce::var(), args.data(), static_cast<int>(args.size()));\n\n                std::invoke(props[onScrollProp].getNativeFunction(), nfArgs);\n\n                // Update lastScrollEvent dirty flag so it isn't raised again\n                lastScrollEvent.dirty = false;\n            }\n        }\n    }\n\n    void ScrollView::exportNativeMethods()\n    {\n       exportMethod(\"scrollToPosition\", [this] (const juce::var::NativeFunctionArgs &args) -> juce::var\n       {\n           jassert(args.numArguments == 2);\n           const int xPos = args.arguments[0];\n           const int yPos = args.arguments[1];\n\n           viewport.setViewPosition(xPos, yPos);\n           return juce::var::undefined();\n       });\n    }\n}\n"
  },
  {
    "path": "react_juce/core/ScrollView.h",
    "content": "/*\n  ==============================================================================\n\n    ScrollView.h\n    Created: 20 Apr 2019 5:25:25pm\n\n  ==============================================================================\n*/\n\n#pragma once\n\n#include \"View.h\"\n\n\nnamespace reactjuce\n{\n\n    //==============================================================================\n    /** The ScrollView class is a core view for scrollable content.\n\n        This is basically a proxy component where the appendChild/removeChild\n        methods delegate to a single child juce::Viewport.\n     */\n    class ScrollView : public View\n                     , private juce::Timer\n    {\n        //==============================================================================\n        class ScrollViewViewport : public juce::Viewport\n        {\n            using OnAreaChangedCallback = std::function<void(const juce::Rectangle<int>&)>;\n        public:\n            ScrollViewViewport() = default;\n\n            void onAreaChanged(OnAreaChangedCallback callback)\n            {\n                onAreaChangedCallback = std::move(callback);\n            }\n\n            void visibleAreaChanged(const juce::Rectangle<int> &newArea) override\n            {\n                if (onAreaChangedCallback)\n                    onAreaChangedCallback(newArea);\n            }\n\n        private:\n             OnAreaChangedCallback onAreaChangedCallback;\n        };\n\n        //==============================================================================\n        struct ScrollEvent\n        {\n            juce::var event = juce::var();\n            bool      dirty = false;\n        };\n\n        //==============================================================================\n\n    public:\n        //==============================================================================\n        // Props following CSS Scrollbars spec with some omissions/additions.\n        // https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Scrollbars\n        static inline juce::Identifier overflowXProp           = \"overflow-x\";\n        static inline juce::Identifier overflowYProp           = \"overflow-y\";\n        static inline juce::Identifier scrollBarWidthProp      = \"scrollbar-width\";\n        static inline juce::Identifier scrollbarThumbColorProp = \"scrollbar-thumb-color\";\n        static inline juce::Identifier scrollbarTrackColorProp = \"scrollbar-track-color\";\n        static inline juce::Identifier scrollOnDragProp        = \"scroll-on-drag\";\n        static inline juce::Identifier onScrollProp            = \"onScroll\";\n\n        //==============================================================================\n        ScrollView();\n\n        //==============================================================================\n        void setProperty (const juce::Identifier& name, const juce::var& value) override;\n        void addChild (View* childView, int index = -1) override;\n\n        //==============================================================================\n        void resized() override;\n\n    private:\n        //==============================================================================\n        void timerCallback() override;\n        void exportNativeMethods();\n\n        //==============================================================================\n        ScrollViewViewport viewport;\n        ScrollEvent        lastScrollEvent;\n\n        //==============================================================================\n        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ScrollView)\n    };\n\n}\n"
  },
  {
    "path": "react_juce/core/ScrollViewContentShadowView.h",
    "content": "/*\n  ==============================================================================\n\n    ScrollViewContentShadowView.h\n    Created: 16 Jun 2019 10:38:37pm\n\n  ==============================================================================\n*/\n\n#pragma once\n\n#include \"ShadowView.h\"\n#include \"View.h\"\n\n\nnamespace reactjuce\n{\n\n    //==============================================================================\n    /** The ScrollViewContentShadowView extends a ShadowView to provide specialized\n     *  behavior for flushing layout bounds to the content element of a ScrolLView.\n     *\n     *  In particular, the default ShadowView behavior doesn't understand that\n     *  the child view of a ScrollView might be offset from the (0, 0) top left\n     *  position. Because of that, when flushing layout bounds it will set bounds\n     *  with a (0, 0) top left position, which the juce::Viewport understands as\n     *  a command to scroll back to (0, 0). So here we just make sure to preserve\n     *  any offset value when flushing new bounds.\n     */\n    class ScrollViewContentShadowView : public ShadowView\n    {\n    public:\n        //==============================================================================\n        explicit ScrollViewContentShadowView(View* _view)\n            : ShadowView(_view) {}\n\n        //==============================================================================\n        void flushViewLayout() override\n        {\n            View      *v      = getAssociatedView();\n            const auto pos    = v->getPosition().toFloat();\n            const auto bounds = getCachedLayoutBounds().withPosition(pos);\n\n            v->setFloatBounds(bounds);\n            v->setBounds(bounds.toNearestInt());\n\n            for (auto& child : getChildren())\n                child->flushViewLayout();\n        }\n\n    private:\n        //==============================================================================\n        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ScrollViewContentShadowView)\n    };\n\n}\n"
  },
  {
    "path": "react_juce/core/ShadowView.cpp",
    "content": "#include \"ShadowView.h\"\n\n//TODO: Eventually we may switch this out based on some preprocessor\n//      flag just as we're doing with EcmascriptEngine.\n#include \"ShadowView_Yoga.cpp\"\n\nnamespace reactjuce\n{\n    //==============================================================================\n    ShadowView::ShadowView(View* _view)\n        : shadowViewPimpl(std::make_unique<ShadowViewPimpl>(_view))\n    {\n    }\n\n    ShadowView::~ShadowView()\n    {\n    }\n\n    //==============================================================================\n    bool ShadowView::setProperty (const juce::String& name, const juce::var& newValue)\n    {\n        return shadowViewPimpl->setProperty(name, newValue);\n    }\n\n    //==============================================================================\n    void ShadowView::addChild (ShadowView* childView, int index)\n    {\n       shadowViewPimpl->addChild(childView, index);\n    }\n\n    void ShadowView::removeChild (ShadowView* childView)\n    {\n        shadowViewPimpl->removeChild(childView);\n    }\n\n    //==============================================================================\n    View* ShadowView::getAssociatedView()\n    {\n        return shadowViewPimpl->getAssociatedView();\n    }\n\n    //==============================================================================\n    juce::Rectangle<float> ShadowView::getCachedLayoutBounds()\n    {\n        return shadowViewPimpl->getCachedLayoutBounds();\n    }\n\n    void ShadowView::computeViewLayout(const float width, const float height)\n    {\n        shadowViewPimpl->computeViewLayout(width, height);\n    }\n\n    void ShadowView::flushViewLayout()\n    {\n        shadowViewPimpl->flushViewLayout();\n    }\n\n    void ShadowView::flushViewLayoutAnimated(double const durationMs,\n                                             int const frameRate,\n                                             BoundsAnimator::EasingType const et)\n    {\n        shadowViewPimpl->flushViewLayoutAnimated(durationMs, frameRate, et);\n    }\n\n    //==============================================================================\n    std::vector<ShadowView*>& ShadowView::getChildren()\n    {\n       return shadowViewPimpl->children;\n    }\n\n    //==============================================================================\n    ShadowView::ShadowViewPimpl& ShadowView::getShadowViewImpl() { return *shadowViewPimpl;  };\n\n    //==============================================================================\n\n}\n"
  },
  {
    "path": "react_juce/core/ShadowView.h",
    "content": "#pragma once\n\n#include \"View.h\"\n\n\nnamespace reactjuce\n{\n\n    //==============================================================================\n    struct BoundsAnimator : public juce::Timer\n    {\n        using StepCallback = std::function<void(juce::Rectangle<float>)>;\n\n        enum class EasingType\n        {\n            Linear,\n            QuadraticIn,\n            QuadraticOut,\n            QuadraticInOut,\n        };\n\n        juce::Rectangle<float> start;\n        juce::Rectangle<float> dest;\n        StepCallback callback;\n        double duration;\n        double startTime;\n        int frameRate = 45;\n        EasingType easingType = EasingType::Linear;\n\n        BoundsAnimator(double durationMs,\n                       int frameRateToUse,\n                       EasingType et,\n                       juce::Rectangle<float> startRect,\n                       juce::Rectangle<float> destRect,\n                       StepCallback cb)\n            : start(startRect)\n            , dest(destRect)\n            , callback(std::move (cb))\n            , duration(durationMs)\n            , frameRate(frameRateToUse)\n            , easingType(et)\n        {\n            startTime = juce::Time::getMillisecondCounterHiRes();\n            startTimerHz(45);\n        }\n\n        ~BoundsAnimator() override\n        {\n            stopTimer();\n        }\n\n        static constexpr float  lerp (float a, float b, double t)  { return a + (static_cast<float> (t) * (b - a)); }\n\n        void timerCallback() override\n        {\n            auto now = juce::Time::getMillisecondCounterHiRes();\n            double t = std::clamp((now - startTime) / duration, 0.0, 1.0);\n\n            // Super helpful cheat sheet: https://gist.github.com/gre/1650294\n            switch (easingType)\n            {\n                case EasingType::Linear:\n                    break;\n                case EasingType::QuadraticIn:\n                    t = t * t;\n                    break;\n                case EasingType::QuadraticOut:\n                    t = t * (2.0 - t);\n                    break;\n                case EasingType::QuadraticInOut:\n                    t = (t < 0.5) ? (2.0 * t * t) : (-1.0 + (4.0 - 2.0 * t) * t);\n                    break;\n                default:\n                    break;\n            }\n\n            if (t >= 0.9999)\n            {\n                callback(dest);\n                stopTimer();\n                return;\n            }\n\n            callback({\n                lerp(start.getX(), dest.getX(), t),\n                lerp(start.getY(), dest.getY(), t),\n                lerp(start.getWidth(), dest.getWidth(), t),\n                lerp(start.getHeight(), dest.getHeight(), t),\n            });\n        }\n    };\n\n    //==============================================================================\n    /** The ShadowView class decouples layout constraints from the actual View instances\n        so that our View tree and ShadowView tree might differ (i.e. in the case of raw\n        text nodes), and so that our View may remain more simple.\n     */\n    class ShadowView\n    {\n    public:\n        //==============================================================================\n        static const inline juce::Identifier debugProp          = \"debug\";\n        static const inline juce::Identifier durationProp       = \"duration\";\n        static const inline juce::Identifier easingProp         = \"easing\";\n        static const inline juce::Identifier frameRateProp      = \"frameRate\";\n        static const inline juce::Identifier layoutAnimatedProp = \"layoutAnimated\";\n\n        //==============================================================================\n        explicit ShadowView(View* _view);\n        virtual ~ShadowView();\n\n        //==============================================================================\n        /** Set a property on the shadow view. */\n        virtual bool setProperty (const juce::String& name, const juce::var& newValue);\n\n        /** Adds a child component behind the existing children. */\n        //TODO: Deal with default arg. Virtual functions shouldn't have them.\n        virtual void addChild (ShadowView* childView, int index = -1);\n\n        /** Removes a child component from the children array. */\n        virtual void removeChild (ShadowView* childView);\n\n        //==============================================================================\n        /** Returns a pointer to the View instance shadowed by this node. */\n        View* getAssociatedView();\n\n        //==============================================================================\n        /** Returns the layout bounds held by the internal yogaNode. */\n        juce::Rectangle<float> getCachedLayoutBounds();\n\n        /** Recursively computes the shadow tree layout. */\n        void computeViewLayout(float width, float height);\n\n        /** Recursive traversal of the shadow tree, flushing layout bounds to\n            the associated view components.\n         */\n        virtual void flushViewLayout();\n\n        /** Recursive traversal of the shadow tree, flushing layout bounds to the\n         *  associated view components smoothly over time. This recursive step allows\n         *  an animation of a component subtree by just marking the parent as animated.\n         */\n        virtual void flushViewLayoutAnimated(double durationMs, int frameRate, BoundsAnimator::EasingType et);\n\n    protected:\n        //==============================================================================\n        std::vector<ShadowView*>& getChildren();\n\n        class ShadowViewPimpl;\n        ShadowViewPimpl& getShadowViewImpl();\n\n    private:\n        //==============================================================================\n        std::unique_ptr<ShadowViewPimpl> shadowViewPimpl;\n        friend ShadowViewPimpl;\n\n        //==============================================================================\n        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ShadowView)\n    };\n\n}\n"
  },
  {
    "path": "react_juce/core/ShadowView_Yoga.cpp",
    "content": "#include \"ShadowView.h\"\n#include \"YogaImplInclude.cpp\"\n\n\n//==============================================================================\n#define BP_SPREAD_SETTER_PERCENT(setter) setter, setter##Percent\n#define BP_SPREAD_SETTER_AUTO(setter) BP_SPREAD_SETTER_PERCENT(setter), setter##Auto\n\n//==============================================================================\n\nnamespace reactjuce\n{\n    namespace\n    {\n        //==============================================================================\n        template <typename Setter, typename ...Args>\n        const auto getYogaNodeFloatSetter(Setter setter, Args... args) {\n            return [=](const juce::var& value, YGNodeRef node) {\n                if(value.isDouble()) {\n                    setter(node, args..., (float) value);\n                    return true;\n                }\n                return false;\n            };\n        }\n\n        template <typename Setter, typename SetterPercent, typename ...Args>\n        const auto getYogaNodeDimensionSetter(Setter setter, SetterPercent setterPercent, Args... args) {\n            return [=, floatSetter = getYogaNodeFloatSetter(setter, args...)](const juce::var& value, YGNodeRef node) {\n                if (floatSetter(value, node))\n                    return true;\n                if (value.isString() && value.toString().contains(\"%\"))\n                {\n                    juce::String strVal = value.toString().retainCharacters(\"-1234567890.\");\n                    setterPercent(node, args..., strVal.getFloatValue());\n                    return true;\n                }\n                setter(node, args..., YGUndefined);\n                return true;\n            };\n        }\n\n        template <typename Setter, typename SetterPercent, typename SetterAuto, typename ...Args>\n        const auto getYogaNodeDimensionAutoSetter(Setter setter, SetterPercent setterPercent, SetterAuto setterAuto, Args... args) {\n            return [=, nonAutoSetter = getYogaNodeDimensionSetter(setter, setterPercent, args...)](const juce::var& value, YGNodeRef node) {\n                if (value.isString() && value.toString() == \"auto\") {\n                    setterAuto(node, args...);\n                    return true;\n                }\n                return nonAutoSetter(value, node);\n            };\n        }\n\n        template <typename Setter, typename EnumMap>\n        const auto getYogaNodeEnumSetter(Setter setter, EnumMap &map) {\n            return [=](const juce::var& value, YGNodeRef node) {                       \\\n        const auto val = map.find(value);\n                if(val == map.end()) {\n                    // TODO catch further up to add the key at which we tried\n                    // to set this enum property to the message and rethrow\n                    throw std::invalid_argument(\"Invalid property: \" + value.toString().toStdString());\n                }\n                setter(node, val->second);\n                return true;\n            };\n        }\n\n        //==============================================================================\n        std::unordered_map<juce::String, YGDirection> ValidDirectionValues {\n            { YGDirectionToString(YGDirectionInherit), YGDirectionInherit },\n            { YGDirectionToString(YGDirectionLTR), YGDirectionLTR },\n            { YGDirectionToString(YGDirectionRTL), YGDirectionRTL },\n        };\n\n        std::unordered_map<juce::String, YGFlexDirection> ValidFlexDirectionValues {\n            { YGFlexDirectionToString(YGFlexDirectionColumn), YGFlexDirectionColumn },\n            { YGFlexDirectionToString(YGFlexDirectionColumnReverse), YGFlexDirectionColumnReverse },\n            { YGFlexDirectionToString(YGFlexDirectionRow), YGFlexDirectionRow },\n            { YGFlexDirectionToString(YGFlexDirectionRowReverse), YGFlexDirectionRowReverse },\n        };\n\n        std::unordered_map<juce::String, YGJustify> ValidJustifyValues {\n            { YGJustifyToString(YGJustifyFlexStart), YGJustifyFlexStart },\n            { YGJustifyToString(YGJustifyCenter), YGJustifyCenter },\n            { YGJustifyToString(YGJustifyFlexEnd), YGJustifyFlexEnd },\n            { YGJustifyToString(YGJustifySpaceBetween), YGJustifySpaceBetween },\n            { YGJustifyToString(YGJustifySpaceAround), YGJustifySpaceAround },\n        };\n\n        std::unordered_map<juce::String, YGAlign> ValidAlignValues {\n            { YGAlignToString(YGAlignAuto), YGAlignAuto },\n            { YGAlignToString(YGAlignFlexStart), YGAlignFlexStart },\n            { YGAlignToString(YGAlignCenter), YGAlignCenter },\n            { YGAlignToString(YGAlignFlexEnd), YGAlignFlexEnd },\n            { YGAlignToString(YGAlignStretch), YGAlignStretch },\n            { YGAlignToString(YGAlignBaseline), YGAlignBaseline },\n            { YGAlignToString(YGAlignSpaceBetween), YGAlignSpaceBetween },\n            { YGAlignToString(YGAlignSpaceAround), YGAlignSpaceAround },\n        };\n\n        std::unordered_map<juce::String, YGPositionType> ValidPositionTypeValues {\n            { YGPositionTypeToString(YGPositionTypeRelative), YGPositionTypeRelative },\n            { YGPositionTypeToString(YGPositionTypeAbsolute), YGPositionTypeAbsolute },\n        };\n\n        std::unordered_map<juce::String, YGWrap> ValidFlexWrapValues {\n            { YGWrapToString(YGWrapNoWrap), YGWrapNoWrap },\n            { YGWrapToString(YGWrapWrap), YGWrapWrap },\n            { YGWrapToString(YGWrapWrapReverse), YGWrapWrapReverse },\n        };\n\n        std::unordered_map<juce::String, YGOverflow> ValidOverflowValues {\n            { YGOverflowToString(YGOverflowVisible), YGOverflowVisible },\n            { YGOverflowToString(YGOverflowHidden), YGOverflowHidden },\n            { YGOverflowToString(YGOverflowScroll), YGOverflowScroll },\n        };\n\n        //==============================================================================\n        class PropertySetterMap {\n            using K = juce::String;\n            using V = juce::var;\n            using F = std::function<bool(const V&, YGNodeRef)>;\n            std::unordered_map<K, F> propertySetters;\n\n        public:\n            PropertySetterMap(std::initializer_list<std::pair<const K, F>> init): propertySetters(init) {}\n            bool call(const K& key, const V& v, YGNodeRef node) const {\n                const auto setter = propertySetters.find(key);\n                if(setter == propertySetters.end()) {\n                    return false;\n                }\n                return setter->second(v, node);\n            }\n        };\n\n        static const PropertySetterMap propertySetters{\n            {\"direction\", getYogaNodeEnumSetter(YGNodeStyleSetDirection, ValidDirectionValues)},\n            {\"flex-direction\", getYogaNodeEnumSetter(YGNodeStyleSetFlexDirection, ValidFlexDirectionValues)},\n            {\"justify-content\", getYogaNodeEnumSetter(YGNodeStyleSetJustifyContent, ValidJustifyValues)},\n            {\"align-items\", getYogaNodeEnumSetter(YGNodeStyleSetAlignItems, ValidAlignValues)},\n            {\"align-content\", getYogaNodeEnumSetter(YGNodeStyleSetAlignContent, ValidAlignValues)},\n            {\"align-self\", getYogaNodeEnumSetter(YGNodeStyleSetAlignSelf, ValidAlignValues)},\n            {\"position\", getYogaNodeEnumSetter(YGNodeStyleSetPositionType, ValidPositionTypeValues)},\n            {\"flex-wrap\", getYogaNodeEnumSetter(YGNodeStyleSetFlexWrap, ValidFlexWrapValues)},\n            {\"overflow\", getYogaNodeEnumSetter(YGNodeStyleSetOverflow, ValidOverflowValues)},\n            {\"flex\", getYogaNodeFloatSetter(YGNodeStyleSetFlex)},\n            {\"flex-grow\", getYogaNodeFloatSetter(YGNodeStyleSetFlexGrow)},\n            {\"flex-shrink\", getYogaNodeFloatSetter(YGNodeStyleSetFlexShrink)},\n            {\"flex-basis\", getYogaNodeDimensionAutoSetter(BP_SPREAD_SETTER_AUTO(YGNodeStyleSetFlexBasis))},\n            {\"width\", getYogaNodeDimensionAutoSetter(BP_SPREAD_SETTER_AUTO(YGNodeStyleSetWidth))},\n            {\"height\", getYogaNodeDimensionAutoSetter(BP_SPREAD_SETTER_AUTO(YGNodeStyleSetHeight))},\n            {\"min-width\", getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetMinWidth))},\n            {\"min-height\", getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetMinHeight))},\n            {\"max-width\", getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetMaxWidth))},\n            {\"max-height\", getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetMaxHeight))},\n            {\"aspect-ratio\", getYogaNodeFloatSetter(YGNodeStyleSetAspectRatio)},\n\n            {\"margin\", getYogaNodeDimensionAutoSetter(BP_SPREAD_SETTER_AUTO(YGNodeStyleSetMargin), YGEdgeAll)},\n            {juce::String(\"margin-\") + YGEdgeToString(YGEdgeLeft), getYogaNodeDimensionAutoSetter(BP_SPREAD_SETTER_AUTO(YGNodeStyleSetMargin), YGEdgeLeft)},\n            {juce::String(\"margin-\") + YGEdgeToString(YGEdgeTop), getYogaNodeDimensionAutoSetter(BP_SPREAD_SETTER_AUTO(YGNodeStyleSetMargin), YGEdgeTop)},\n            {juce::String(\"margin-\") + YGEdgeToString(YGEdgeRight), getYogaNodeDimensionAutoSetter(BP_SPREAD_SETTER_AUTO(YGNodeStyleSetMargin), YGEdgeRight)},\n            {juce::String(\"margin-\") + YGEdgeToString(YGEdgeBottom), getYogaNodeDimensionAutoSetter(BP_SPREAD_SETTER_AUTO(YGNodeStyleSetMargin), YGEdgeBottom)},\n            {juce::String(\"margin-\") + YGEdgeToString(YGEdgeStart), getYogaNodeDimensionAutoSetter(BP_SPREAD_SETTER_AUTO(YGNodeStyleSetMargin), YGEdgeStart)},\n            {juce::String(\"margin-\") + YGEdgeToString(YGEdgeEnd), getYogaNodeDimensionAutoSetter(BP_SPREAD_SETTER_AUTO(YGNodeStyleSetMargin), YGEdgeEnd)},\n            {juce::String(\"margin-\") + YGEdgeToString(YGEdgeHorizontal), getYogaNodeDimensionAutoSetter(BP_SPREAD_SETTER_AUTO(YGNodeStyleSetMargin), YGEdgeHorizontal)},\n            {juce::String(\"margin-\") + YGEdgeToString(YGEdgeVertical), getYogaNodeDimensionAutoSetter(BP_SPREAD_SETTER_AUTO(YGNodeStyleSetMargin), YGEdgeLeft)},\n            {juce::String(\"margin-\") + YGEdgeToString(YGEdgeAll), getYogaNodeDimensionAutoSetter(BP_SPREAD_SETTER_AUTO(YGNodeStyleSetMargin), YGEdgeAll)},\n\n            {\"padding\", getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetPadding), YGEdgeAll)},\n            {juce::String(\"padding-\") + YGEdgeToString(YGEdgeLeft), getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetPadding), YGEdgeLeft)},\n            {juce::String(\"padding-\") + YGEdgeToString(YGEdgeTop), getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetPadding), YGEdgeTop)},\n            {juce::String(\"padding-\") + YGEdgeToString(YGEdgeRight), getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetPadding), YGEdgeRight)},\n            {juce::String(\"padding-\") + YGEdgeToString(YGEdgeBottom), getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetPadding), YGEdgeBottom)},\n            {juce::String(\"padding-\") + YGEdgeToString(YGEdgeStart), getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetPadding), YGEdgeStart)},\n            {juce::String(\"padding-\") + YGEdgeToString(YGEdgeEnd), getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetPadding), YGEdgeEnd)},\n            {juce::String(\"padding-\") + YGEdgeToString(YGEdgeHorizontal), getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetPadding), YGEdgeHorizontal)},\n            {juce::String(\"padding-\") + YGEdgeToString(YGEdgeVertical), getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetPadding), YGEdgeLeft)},\n            {juce::String(\"margin-\") + YGEdgeToString(YGEdgeAll), getYogaNodeDimensionAutoSetter(BP_SPREAD_SETTER_AUTO(YGNodeStyleSetMargin), YGEdgeAll)},\n\n            {YGEdgeToString(YGEdgeLeft), getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetPosition), YGEdgeLeft)},\n            {YGEdgeToString(YGEdgeTop), getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetPosition), YGEdgeTop)},\n            {YGEdgeToString(YGEdgeRight), getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetPosition), YGEdgeRight)},\n            {YGEdgeToString(YGEdgeBottom), getYogaNodeDimensionSetter(BP_SPREAD_SETTER_PERCENT(YGNodeStyleSetPosition), YGEdgeBottom)},\n        };\n\n    }\n\n    //==============================================================================\n    class ShadowView::ShadowViewPimpl\n    {\n    public:\n        //==============================================================================\n        ShadowViewPimpl(View* v)\n            : view(v)\n        {\n            YGConfigSetUseWebDefaults(YGConfigGetDefault(), true);\n            yogaNode = YGNodeNew();\n        }\n\n        ~ShadowViewPimpl()\n        {\n            YGNodeFree(yogaNode);\n        }\n\n        //==============================================================================\n        bool setProperty (const juce::String& name, const juce::var& newValue)\n        {\n            props.set(name, newValue);\n            return propertySetters.call(name, newValue, yogaNode);\n        }\n\n        //==============================================================================\n        void addChild (ShadowView* childView, int index = -1)\n        {\n            if (index == -1)\n            {\n                YGNodeInsertChild(yogaNode, childView->getShadowViewImpl().yogaNode, YGNodeGetChildCount(yogaNode));\n                children.push_back(childView);\n            }\n            else\n            {\n                jassert (juce::isPositiveAndNotGreaterThan(index, YGNodeGetChildCount(yogaNode)));\n\n                YGNodeInsertChild(yogaNode, childView->getShadowViewImpl().yogaNode, static_cast<uint32_t> (index));\n                children.insert(children.begin() + index, childView);\n            }\n        }\n\n        void removeChild (ShadowView* childView)\n        {\n            auto it = std::find(children.begin(), children.end(), childView);\n\n            if (it != children.end())\n            {\n                YGNodeRemoveChild(yogaNode, childView->getShadowViewImpl().yogaNode);\n                children.erase(it);\n            }\n        }\n\n        //==============================================================================\n        View* getAssociatedView() { return view; }\n\n        //==============================================================================\n        juce::Rectangle<float> getCachedLayoutBounds()\n        {\n            return {\n                YGNodeLayoutGetLeft(yogaNode),\n                YGNodeLayoutGetTop(yogaNode),\n                YGNodeLayoutGetWidth(yogaNode),\n                YGNodeLayoutGetHeight(yogaNode)\n            };\n        }\n\n        void computeViewLayout(const float width, const float height)\n        {\n            // Compute the new layout values\n            YGNodeCalculateLayout(yogaNode, width, height, YGDirectionInherit);\n        }\n\n        void flushViewLayout()\n        {\n#ifdef DEBUG\n            if (props.contains(debugProp))\n                YGNodePrint(yogaNode, (YGPrintOptions) (YGPrintOptionsLayout\n                                                        | YGPrintOptionsStyle\n                                                        | YGPrintOptionsChildren));\n#endif\n\n            if (props.contains(layoutAnimatedProp))\n            {\n                if (props[layoutAnimatedProp].isBool() && props[layoutAnimatedProp])\n                {\n                    // Default parameters\n                    return flushViewLayoutAnimated(50.0, 45, BoundsAnimator::EasingType::Linear);\n                }\n\n                if (props[layoutAnimatedProp].isObject())\n                {\n                    double const durationMs = props[layoutAnimatedProp].getProperty(durationProp, 50.0);\n                    double const frameRate = props[layoutAnimatedProp].getProperty(frameRateProp, 45);\n                    int const et = props[layoutAnimatedProp].getProperty(easingProp, 0);\n\n                    return flushViewLayoutAnimated(durationMs, static_cast<int> (frameRate), static_cast<BoundsAnimator::EasingType>(et));\n                }\n            }\n\n            view->setFloatBounds(getCachedLayoutBounds());\n            view->setBounds(getCachedLayoutBounds().toNearestInt());\n\n            for (auto& child : children)\n                child->flushViewLayout();\n        }\n\n        void flushViewLayoutAnimated(double const durationMs, int const frameRate, BoundsAnimator::EasingType const et)\n        {\n            auto viewCurrentBounds = view->getBounds().toFloat();\n            auto viewDestinationBounds = getCachedLayoutBounds();\n\n            animator = std::make_unique<BoundsAnimator>(\n                durationMs,\n                frameRate,\n                et,\n                viewCurrentBounds,\n                viewDestinationBounds,\n                [safeView = juce::Component::SafePointer(view)](auto && stepBounds)\n                {\n                    if (auto* v = safeView.getComponent()) {\n                        v->setFloatBounds(stepBounds);\n                        v->setBounds(stepBounds.toNearestInt());\n                    }\n                }\n            );\n\n            for (auto& child : children)\n            {\n                child->flushViewLayoutAnimated(durationMs, frameRate, et);\n            }\n        }\n\n        //==============================================================================\n        YGNodeRef yogaNode;\n        View* view = nullptr;\n        juce::NamedValueSet props;\n\n        std::unique_ptr<BoundsAnimator> animator;\n        std::vector<ShadowView*> children;\n\n        //==============================================================================\n    };\n\n    //==============================================================================\n}\n"
  },
  {
    "path": "react_juce/core/TextInputView.cpp",
    "content": "/*\n==============================================================================\n\n  TextInputView.cpp\n  Created: 20 Jan 2021 10:30pm\n\n==============================================================================\n*/\n\n#include \"TextInputView.h\"\n#include \"TextView.h\"\n\nnamespace reactjuce\n{\n    namespace detail\n    {\n        static juce::var makeInputEventObject(const juce::String &value)\n        {\n            juce::DynamicObject::Ptr obj = new juce::DynamicObject();\n            obj->setProperty(\"value\", value);\n            return obj.get();\n        }\n\n        static juce::var makeChangeEventObject(const juce::String &value)\n        {\n            juce::DynamicObject::Ptr obj = new juce::DynamicObject();\n            obj->setProperty(\"value\", value);\n            return obj.get();\n        }\n    }\n\n    void TextInputView::TextInput::setControlledValue(const juce::String &value)\n    {\n        insertedAsControlledValue = true;\n        setText(value);\n    }\n\n    void TextInputView::TextInput::setMaxLength(int maxLen)\n    {\n        maxLength = maxLen;\n        setInputRestrictions(maxLen);\n    }\n\n    void TextInputView::TextInput::setPlaceholderText(const juce::String &text)\n    {\n        placeholderText = text;\n        setTextToShowWhenEmpty(placeholderText, placeholderColour);\n    }\n\n    void TextInputView::TextInput::setPlaceholderColour(const juce::Colour &colourToUse)\n    {\n        placeholderColour = colourToUse;\n        setTextToShowWhenEmpty(placeholderText, placeholderColour);\n    }\n\n    void TextInputView::TextInput::insertTextAtCaret(const juce::String &textToInsert)\n    {\n        const juce::String currentValue = getText();\n        juce::TextEditor::insertTextAtCaret(textToInsert);\n        const juce::String newValue = getText();\n        if (currentValue == newValue)\n        {\n            return;\n        }\n\n        // Invoke JavaScript's `input` event.\n        if (props.contains(TextInputView::onInputProp) && props[TextInputView::onInputProp].isMethod())\n        {\n            std::array<juce::var, 1> args{{detail::makeInputEventObject(newValue)}};\n            juce::var::NativeFunctionArgs nfArgs(juce::var(), args.data(), static_cast<int>(args.size()));\n            std::invoke(props[TextInputView::onInputProp].getNativeFunction(), nfArgs);\n        }\n\n        dirty = true;\n\n        if (controlled && !insertedAsControlledValue)\n        {\n            undo();\n        }\n        insertedAsControlledValue = false;\n    }\n\n    //==============================================================================\n\n    void TextInputView::TextInput::textEditorReturnKeyPressed(juce::TextEditor &)\n    {\n        invokeChangeEventIfNeeded();\n    }\n\n    void TextInputView::TextInput::textEditorFocusLost(juce::TextEditor &)\n    {\n        invokeChangeEventIfNeeded();\n    }\n\n    void TextInputView::TextInput::invokeChangeEventIfNeeded()\n    {\n        if (dirty)\n        {\n            // Invoke JavaScript's `change` event.\n            if (props.contains(TextInputView::onChangeProp) && props[TextInputView::onChangeProp].isMethod())\n            {\n                std::array<juce::var, 1> args{{detail::makeChangeEventObject(getText())}};\n                juce::var::NativeFunctionArgs nfArgs(juce::var(), args.data(), static_cast<int>(args.size()));\n                std::invoke(props[TextInputView::onChangeProp].getNativeFunction(), nfArgs);\n            }\n            dirty = false;\n        }\n    }\n\n    //==============================================================================\n\n    void TextInputView::setProperty(const juce::Identifier &name, const juce::var &value)\n    {\n        View::setProperty(name, value);\n        if (name == valueProp)\n        {\n            if (!value.isString())\n                throw std::invalid_argument(\"Invalid prop value. Prop \\'value\\' must be a string.\");\n\n            textInput.setControlled(true);\n            textInput.setControlledValue(value);\n        }\n\n        if (name == placeholderProp)\n        {\n            if (!value.isString())\n                throw std::invalid_argument(\"Invalid prop value. Prop \\'placeholder\\' must be a string.\");\n\n            textInput.setPlaceholderText(value);\n        }\n\n        if (name == placeholderColorProp)\n        {\n            if (!value.isString())\n                throw std::invalid_argument(\"Invalid prop value. Prop \\'placeholder-color\\' must be a color string.\");\n\n            const juce::String hexPlaceholderColor = value;\n            const juce::Colour placeholderColor = juce::Colour::fromString(hexPlaceholderColor);\n            textInput.setPlaceholderColour(placeholderColor);\n        }\n\n        if (name == maxlengthProp)\n        {\n            if (!value.isDouble())\n              throw std::invalid_argument(\"Invalid prop value. Prop \\'maxlength\\' must be a number.\");\n\n            textInput.setMaxLength(value);\n        }\n\n        if (name == readonly)\n        {\n            textInput.setReadOnly(value);\n        }\n\n        textInput.applyFontToAllText(getFont());\n\n        const juce::String hexColor = props.getWithDefault(colorProp, \"ff000000\");\n        const juce::Colour colour = juce::Colour::fromString(hexColor);\n        textInput.applyColourToAllText(colour);\n\n        const int just = props.getWithDefault(justificationProp, 1);\n        textInput.setJustification(just);\n\n        if (isTextEditorColorProp(name))\n            setTextEditorColorProp(name, value);\n    }\n\n    void TextInputView::resized()\n    {\n        View::resized();\n        textInput.setBounds(getLocalBounds());\n    }\n\n    juce::Font TextInputView::getFont() const\n    {\n        return TextView::getFont(props);\n    }\n\n    bool TextInputView::isTextEditorColorProp(const juce::Identifier &textEditorColorProp)\n    {\n        const auto it = textEditorColourIdsByProp.find(textEditorColorProp);\n        return it != textEditorColourIdsByProp.end();\n    }\n\n    void TextInputView::setTextEditorColorProp(const juce::Identifier &textEditorColorProp, const juce::var &value)\n    {\n        if (!value.isString())\n        {\n            const std::string propName = textEditorColorProp.toString().toStdString();\n            const std::string message = \"Invalid prop value. Prop \\'\" + propName + \"\\' must be a color string.\";\n            throw std::invalid_argument(message);\n        }\n\n        const juce::String hexColor = value;\n        const juce::Colour color = juce::Colour::fromString(hexColor);\n        textInput.setColour(textEditorColourIdsByProp.at(textEditorColorProp), color);\n    }\n\n    const std::map<juce::Identifier, int> TextInputView::textEditorColourIdsByProp = {\n        { backgroundColorProp,      juce::TextEditor::ColourIds::backgroundColourId },\n        { outlineColorProp,         juce::TextEditor::ColourIds::outlineColourId },\n        { focusedOutlineColorProp,  juce::TextEditor::ColourIds::focusedOutlineColourId },\n        { highlightedTextColorProp, juce::TextEditor::ColourIds::highlightedTextColourId },\n        { highlightColorProp,       juce::TextEditor::ColourIds::highlightColourId },\n        { caretColorProp,           juce::CaretComponent::ColourIds::caretColourId }\n    };\n}\n"
  },
  {
    "path": "react_juce/core/TextInputView.h",
    "content": "/*\n==============================================================================\n\n  TextInputView.h\n  Created: 20 Jan 2021 10:30pm\n\n==============================================================================\n*/\n\n#pragma once\n\n#include <climits>\n#include \"View.h\"\n\nnamespace reactjuce\n{\n    //==============================================================================\n    /** The TextInputView class is a core view for text editing. */\n    class TextInputView : public View\n    {\n        //==============================================================================\n        /** The TextInput class is an extended juce::TextEditor class for TextInputView\n         * class. There are some features added.\n         *\n         * - Invoke JavaScript's 'input' and 'change' event.\n         *\n         *   Note: React.js has only 'onChange' callback which has same behavior as\n         *   JavaScript's 'onInput' and does not have any callback corresponding to\n         *   original JavaScript's 'onChange'.\n         *   https://stackoverflow.com/questions/38256332/in-react-whats-the-difference-between-onchange-and-oninput\n         *\n         * - Support React's controlled component model.\n         *   https://reactjs.org/docs/uncontrolled-components.html\n         *   If field `controlled` is true,\n         *   only the string value given by `setControlledValue()`\n         *   is shown in the text editor.\n         *\n         * - Allow to set 'placeholder' text and 'placeholder-color' separately.\n         */\n        class TextInput : public juce::TextEditor\n                        , public juce::TextEditor::Listener\n        {\n        public:\n            //==============================================================================\n            explicit TextInput(const juce::NamedValueSet &_props)\n                : props(_props)\n                , controlled(false)\n                , insertedAsControlledValue(false)\n                , dirty(false)\n                , maxLength(INT_MAX)\n                , placeholderText()\n                , placeholderColour(juce::Colours::black) {}\n\n            void insertTextAtCaret(const juce::String &textToInsert) override;\n            void setControlled(bool _controlled) { controlled = _controlled; }\n            void setControlledValue(const juce::String &value);\n            void setMaxLength(int maxLen);\n            void setPlaceholderText(const juce::String &text);\n            void setPlaceholderColour(const juce::Colour &colourToUse);\n\n            //==============================================================================\n            void textEditorReturnKeyPressed(juce::TextEditor &) override;\n            void textEditorFocusLost(juce::TextEditor &) override;\n        private:\n            //==============================================================================\n            void invokeChangeEventIfNeeded();\n\n            //==============================================================================\n            const juce::NamedValueSet &props;\n            bool controlled;\n            bool insertedAsControlledValue;\n\n            bool dirty; // for `onChange`\n            int maxLength;\n            juce::String placeholderText;\n            juce::Colour placeholderColour;\n        };\n\n        //==============================================================================\n\n    public:\n        //==============================================================================\n        static inline juce::Identifier valueProp = \"value\";\n\n        static const inline juce::Identifier colorProp = \"color\";\n        static const inline juce::Identifier justificationProp = \"justification\";\n\n        static const inline juce::Identifier placeholderProp = \"placeholder\";\n        static const inline juce::Identifier placeholderColorProp = \"placeholder-color\";\n        static const inline juce::Identifier maxlengthProp = \"maxlength\";\n        static const inline juce::Identifier readonly = \"readonly\";\n\n        static const inline juce::Identifier outlineColorProp = \"outline-color\";\n        static const inline juce::Identifier focusedOutlineColorProp = \"focused-outline-color\";\n        static const inline juce::Identifier highlightedTextColorProp = \"highlighted-text-color\";\n        static const inline juce::Identifier highlightColorProp = \"highlight-color\";\n        static const inline juce::Identifier caretColorProp = \"caret-color\";\n\n        static const inline juce::Identifier onInputProp = \"onInput\";\n        static const inline juce::Identifier onChangeProp = \"onChange\";\n\n        //==============================================================================\n        TextInputView()\n            : textInput(props)\n        {\n            addAndMakeVisible(textInput);\n            textInput.addListener(&textInput);\n            textInput.setPopupMenuEnabled(false);\n        }\n        void setProperty(const juce::Identifier &name, const juce::var &value) override;\n        void resized() override;\n\n    private:\n        //==============================================================================\n        juce::Font getFont() const;\n        static bool isTextEditorColorProp(const juce::Identifier &textEditorColorProp);\n        void setTextEditorColorProp(const juce::Identifier &textEditorColorProp, const juce::var &value);\n\n        //==============================================================================\n        TextInput textInput;\n        static const std::map<juce::Identifier, int> textEditorColourIdsByProp;\n\n        //==============================================================================\n        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(TextInputView)\n    };\n\n}\n"
  },
  {
    "path": "react_juce/core/TextShadowView.cpp",
    "content": "#include \"TextShadowView.h\"\n\n//TODO: Eventually we may switch this out based on some preprocessor\n//      flag just as we're doing with EcmascriptEngine.\n#include \"TextShadowView_Yoga.cpp\"\n\n\nnamespace reactjuce\n{\n\n    //==============================================================================\n    TextShadowView::TextShadowView(View* _view)\n        : ShadowView(_view)\n    {\n        textShadowViewPimpl = std::make_unique<TextShadowViewPimpl>(*this);\n    }\n\n    //==============================================================================\n    bool TextShadowView::setProperty (const juce::String& name, const juce::var& value)\n    {\n        const bool layoutPropertyWasSet = ShadowView::setProperty(name, value);\n\n        // For certain text properties we want Yoga to know that we need\n        // to measure again. For example, changing the font size.\n        if (name.compare(\"font-size\") == 0)\n            markDirty();\n\n        return layoutPropertyWasSet;\n    }\n\n    //==============================================================================\n    void TextShadowView::addChild (ShadowView* childView, int index)\n    {\n        juce::ignoreUnused (index);\n        if (childView != nullptr)\n        {\n            throw std::logic_error(\"TextShadowView cannot take children.\");\n        }\n    }\n    //==============================================================================\n    void TextShadowView::markDirty()\n    {\n        textShadowViewPimpl->markDirty();\n    }\n\n    //==============================================================================\n}\n"
  },
  {
    "path": "react_juce/core/TextShadowView.h",
    "content": "#pragma once\n\n#include \"ShadowView.h\"\n#include \"View.h\"\n\n\nnamespace reactjuce\n{\n\n    /** The TextShadowView extends a ShadowView to provide specialized behavior\n     *  for measuring text content, as text layout is removed from the FlexBox\n     *  flow.\n     */\n    class TextShadowView : public ShadowView\n    {\n    public:\n        //==============================================================================\n        explicit TextShadowView(View* _view);\n\n        //==============================================================================\n        /** Set a property on the shadow view. */\n        bool setProperty (const juce::String& name, const juce::var& value) override;\n\n        /** Override the default ShadowView behavior to explicitly error. */\n        void addChild (ShadowView* childView, int index) override;\n\n        //==============================================================================\n        /** Sets a flag to indicate that this node needs to be measured at the next layout pass. */\n        void markDirty();\n\n        //==============================================================================\n\n    private:\n        //==============================================================================\n        class TextShadowViewPimpl;\n        std::unique_ptr<TextShadowViewPimpl> textShadowViewPimpl;\n\n        friend TextShadowViewPimpl;\n\n        //==============================================================================\n        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TextShadowView)\n    };\n\n}\n"
  },
  {
    "path": "react_juce/core/TextShadowView_Yoga.cpp",
    "content": "#include \"TextShadowView.h\"\n#include \"YogaImplInclude.cpp\"\n\nnamespace reactjuce\n{\n    //==============================================================================\n    /** We use this method to measure the size of a given string so that the\n     *  text container knows what size to take.\n     */\n    namespace\n    {\n        YGSize measureTextNode(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode)\n        {\n            juce::ignoreUnused(widthMode);\n            juce::ignoreUnused(height);\n            juce::ignoreUnused(heightMode);\n\n            auto context = reinterpret_cast<TextShadowView*>(YGNodeGetContext(node));\n            auto view = dynamic_cast<TextView*>(context->getAssociatedView());\n\n            jassert (view != nullptr);\n\n            // TODO: This is a bit of an oversimplification. We have a YGMeasureMode which\n            // is one of three things, \"undefined\", \"exact\", or \"at-most.\" Here we're kind of\n            // just ignoring that, and in cases like `white-space: nowrap;` we want to ignore it,\n            // but it would probably be good to get specific for each case.\n            // See https://github.com/facebook/yoga/pull/576/files\n            auto tl = view->getTextLayout(width);\n\n            return { tl.getWidth(), tl.getHeight() };\n        }\n    }\n    \n    //==============================================================================\n    class TextShadowView::TextShadowViewPimpl\n    {\n    public:\n        explicit TextShadowViewPimpl(TextShadowView &tv)\n            : textShadowView(tv)\n        {\n            YGNodeSetContext(textShadowView.getShadowViewImpl().yogaNode, &textShadowView);\n            YGNodeSetMeasureFunc(textShadowView.getShadowViewImpl().yogaNode, measureTextNode);\n        }\n\n        void markDirty()\n        {\n            YGNodeMarkDirty(textShadowView.getShadowViewImpl().yogaNode);\n        }\n\n    private:\n        TextShadowView &textShadowView;\n    };\n    //==============================================================================\n\n}\n"
  },
  {
    "path": "react_juce/core/TextView.h",
    "content": "/*\n  ==============================================================================\n\n    TextView.h\n    Created: 28 Nov 2018 3:27:27pm\n\n  ==============================================================================\n*/\n\n#pragma once\n\n#include \"View.h\"\n\n\nnamespace reactjuce\n{\n\n    //==============================================================================\n    /** The TextView class is a core container abstraction for declaring text components\n        within the layout system.\n     */\n    class TextView : public View\n    {\n    public:\n        //==============================================================================\n        static const inline juce::Identifier colorProp         = \"color\";\n\n        static const inline juce::Identifier fontSizeProp      = \"font-size\";\n        static const inline juce::Identifier fontStyleProp     = \"font-style\";\n        static const inline juce::Identifier fontFamilyProp    = \"font-family\";\n\n        static const inline juce::Identifier justificationProp = \"justification\";\n        static const inline juce::Identifier kerningFactorProp = \"kerning-factor\";\n        static const inline juce::Identifier lineSpacingProp   = \"line-spacing\";\n        static const inline juce::Identifier wordWrapProp      = \"word-wrap\";\n\n        //==============================================================================\n        TextView() = default;\n\n        //==============================================================================\n        /** Assembles a Font from properties. */\n        static juce::Font getFont(const juce::NamedValueSet &fontProps)\n        {\n            const float fontHeight = fontProps.getWithDefault(fontSizeProp, 12.0f);\n            const int textStyleFlags = fontProps.getWithDefault(fontStyleProp, 0);\n\n            juce::Font f (fontHeight);\n\n            if (fontProps.contains(fontFamilyProp))\n                f = juce::Font (fontProps[fontFamilyProp], fontHeight, textStyleFlags);\n\n            f.setExtraKerningFactor(fontProps.getWithDefault(kerningFactorProp, 0.0));\n            return f;\n        }\n\n        /** Assembles a Font from the current node properties. */\n        juce::Font getFont()\n        {\n            return getFont(props);\n        }\n\n        /** Constructs a TextLayout from all the children string values. */\n        juce::TextLayout getTextLayout (float maxWidth)\n        {\n            juce::String hexColor = props.getWithDefault(colorProp, \"ff000000\");\n            juce::Colour colour = juce::Colour::fromString(hexColor);\n            int just = props.getWithDefault(justificationProp, 1);\n            juce::String text;\n\n            // TODO: Right now a <Text> element maps 1:1 to a TextView instance,\n            // and all children must be RawTextView instances, which are basically\n            // just juce::String. A much more flexible alternative would be for a <Text>\n            // element to map to a TextView and any nested raw text nodes or <Text> elements\n            // map to a juce::AttributedString and carry their own properties. This allows\n            // bolding single words inline, for example, and setting line-height, etc.\n            for (auto& c : getChildren())\n                if (RawTextView* v = dynamic_cast<RawTextView*>(c))\n                    text += v->getText();\n\n            juce::AttributedString as (text);\n            juce::TextLayout tl;\n\n            as.setLineSpacing(props.getWithDefault(lineSpacingProp, 1.0f));\n            as.setFont(getFont());\n            as.setColour(colour);\n            as.setJustification(just);\n\n            if (props.contains(wordWrapProp))\n            {\n                int wwValue = props[wordWrapProp];\n\n                switch (wwValue)\n                {\n                    case 0:\n                        as.setWordWrap(juce::AttributedString::WordWrap::none);\n                        break;\n                    case 2:\n                        as.setWordWrap(juce::AttributedString::WordWrap::byChar);\n                        break;\n                    case 1:\n                    default:\n                        as.setWordWrap(juce::AttributedString::WordWrap::byWord);\n                        break;\n\n                }\n            }\n\n            tl.createLayout(as, maxWidth);\n            return tl;\n        }\n\n        //==============================================================================\n        void paint (juce::Graphics& g) override\n        {\n            auto floatBounds = getLocalBounds().toFloat();\n\n            View::paint(g);\n            getTextLayout(floatBounds.getWidth()).draw(g, floatBounds);\n        }\n\n    private:\n        //==============================================================================\n        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TextView)\n    };\n\n}\n"
  },
  {
    "path": "react_juce/core/Utils.cpp",
    "content": "/*\n  ==============================================================================\n\n    Utils.cpp\n    Created: 20 Jan 2021 10:44:27pm\n\n  ==============================================================================\n*/\n\n#include \"Utils.h\"\n\nnamespace reactjuce\n{\n    namespace detail\n    {\n        juce::var makeErrorObject(const juce::String& errorName, const juce::String& errorMessage)\n        {\n            juce::DynamicObject::Ptr o = new juce::DynamicObject();\n\n            o->setProperty(\"name\", errorName);\n            o->setProperty(\"message\", errorMessage);\n\n            return o.get();\n        }\n\n        std::variant<juce::Colour, juce::ColourGradient> makeColorVariant(const juce::var& colorVariant, const juce::Rectangle<int>& localBounds)\n        {\n            //If object we assume it's a linear gradient\n            if(colorVariant.isObject()) {\n                auto linearGradientObj = juce::JSON::parse(juce::JSON::toString(colorVariant));\n                int deg = linearGradientObj.getProperty(\"angle\", juce::var());\n                double radians = deg * (juce::MathConstants<double>::pi / 180.0);\n                auto colorStops = linearGradientObj.getProperty(\"colours\", juce::var()).getArray();\n                double maximumPercent = colorStops->getFirst().getProperty(\"position\", juce::var());\n                double minimumPercent = colorStops->getFirst().getProperty(\"position\", juce::var());\n                juce::DynamicObject::Ptr colorStopsObj = new juce::DynamicObject();\n                juce::Colour maxColor;\n                juce::Colour minColor;\n                for(auto& colorStop : *colorStops) {\n                    double currentPosition = colorStop.getProperty(\"position\", juce::var());\n                    juce::String currentHex = colorStop.getProperty(\"hex\", juce::var());\n                    juce::DynamicObject::Ptr colorStopObj = new juce::DynamicObject();\n                    colorStopObj->setProperty(\"hex\", currentHex);\n                    colorStopObj->setProperty(\"position\", currentPosition);\n                    colorStopObj->setProperty(\"type\", \"additional\");\n                    juce::String colorUUID = juce::Uuid().toString();\n                    colorStopsObj->setProperty(colorUUID, colorStopObj.get());\n                    if(currentPosition >= maximumPercent) {\n                        maximumPercent = currentPosition;\n                        for (auto& colors : colorStopsObj->getProperties())\n                        {\n                            juce::String colorID = colors.name.toString();\n                            auto* color = colorStopsObj->getProperty(colorID).getDynamicObject();\n                            if(color->getProperty(\"type\") == \"max\"){\n                                color->setProperty(\"type\", \"additional\");\n                            }\n                        }\n                        juce::String hexString = colorStopObj->getProperty(\"hex\");\n                        maxColor = juce::Colour::fromString(hexString);\n                        colorStopObj->setProperty(\"type\", \"max\");\n                    }\n                    if(currentPosition <= minimumPercent) {\n                        minimumPercent = currentPosition;\n                        for (auto& colors : colorStopsObj->getProperties())\n                        {\n                            juce::String colorID = colors.name.toString();\n                            auto* color = colorStopsObj->getProperty(colorID).getDynamicObject();\n                            if(color->getProperty(\"type\") == \"min\"){\n                                color->setProperty(\"type\", \"additional\");\n                            }\n                        }\n                        juce::String hexString = colorStopObj->getProperty(\"hex\");\n                        minColor = juce::Colour::fromString(hexString);\n                        colorStopObj->setProperty(\"type\", \"min\");\n                    }\n                }\n                double positiveExtensionPercent = maximumPercent - 1.0;\n                double negativeExtensionPercent = minimumPercent * -1;\n                juce::Rectangle <int> const b {localBounds};\n                int x1; int x2; int y1; int y2;\n                int width = b.getWidth();\n                int height = b.getHeight();\n                juce::Array<int> centerPoint{width/2, height/2};\n                auto getEdgePointsFromAngle = [](int width, int height, int deg){\n                    double twoPI = juce::MathConstants<double>::twoPi;\n                    double theta = (360 - (deg + 270))  * juce::MathConstants<double>::pi / 180;\n                    while (theta < -juce::MathConstants<double>::pi) {\n                        theta += twoPI;\n                    }\n                    while (theta > juce::MathConstants<double>::pi) {\n                        theta -= twoPI;\n                    }\n                    double rectAtan = atan2(height, width);\n                    double tanTheta = tan(theta);\n                    int region;\n                    if ((theta > -rectAtan) && (theta <= rectAtan)) {\n                        region = 1;\n                    } else if ((theta > rectAtan) && (theta <= (juce::MathConstants<double>::pi - rectAtan))) {\n                        region = 2;\n                    } else if ((theta > (juce::MathConstants<double>::pi - rectAtan)) || (theta <= -(juce::MathConstants<double>::pi - rectAtan))) {\n                        region = 3;\n                    } else {\n                        region = 4;\n                    }\n                    double xEdge = width / 2;\n                    double yEdge = height / 2;\n                    int xFactor = 1;\n                    int yFactor = 1;\n\n                    switch(region) {\n                        case 1: yFactor = -1; break;\n                        case 2: yFactor = -1; break;\n                        case 3: xFactor = -1; break;\n                        case 4: xFactor = -1; break;\n                    }\n\n                    if ((region == 1) || (region == 3)) {\n                        xEdge += xFactor * (width / 2.);\n                        yEdge += yFactor * (width / 2.) * tanTheta;\n                    }\n                    else {\n                        xEdge += xFactor * (height / (2. * tanTheta));\n                        yEdge += yFactor * (height /  2.);\n                    }\n                    juce::Array<int> edgePoints{xEdge, yEdge};\n                    return edgePoints;\n                };\n                //Calculate the gradient Line End point coordinates\n                juce::Array<int> edgePoint1 = getEdgePointsFromAngle(width, height, deg + 180);\n                x1 = edgePoint1[0]; y1 = edgePoint1[1];\n                juce::Array<int> edgePoint2 = getEdgePointsFromAngle(width, height, deg);\n                x2 = edgePoint2[0]; y2 = edgePoint2[1];\n                double gradientLineDistance = abs(b.getWidth() * sin(radians) + abs(b.getHeight() * cos(radians)));\n                double edgePoint1CenterDist = sqrt(pow((x1 - centerPoint[0]), 2) + pow((y1 - centerPoint[1]), 2));\n                double edgePoint2CenterDist = sqrt(pow((x2 - centerPoint[0]), 2) + pow((y2 - centerPoint[1]), 2));\n                double halfGradientDistance = gradientLineDistance/2;\n                double distanceRatio1 = halfGradientDistance/edgePoint1CenterDist;\n                double distanceRatio2 = halfGradientDistance/edgePoint2CenterDist;\n                x1 = ((1 - distanceRatio1) * centerPoint[0]) + (distanceRatio1 * x1);\n                y1 = ((1 - distanceRatio1) * centerPoint[1]) + (distanceRatio1 * y1);\n                x2 = ((1 - distanceRatio2) * centerPoint[0]) + (distanceRatio2 * x2);\n                y2 = ((1 - distanceRatio2) * centerPoint[1]) + (distanceRatio2 * y2);\n                //Gradient line Points\n                int glX1 = x1; int glX2 = x2; int glY1 = y1; int glY2 = y2;\n                //Offset the gradient line length with min max extension percent\n                x1 = ((1 - (negativeExtensionPercent * -1)) * glX1) + ((negativeExtensionPercent * -1) * glX2);\n                y1 = ((1 - (negativeExtensionPercent * -1)) * glY1) + ((negativeExtensionPercent * -1) * glY2);\n                x2 = ((1 - (positiveExtensionPercent * -1)) * glX2) + ((positiveExtensionPercent * -1) * glX1);\n                y2 = ((1 - (positiveExtensionPercent * -1)) * glY2) + ((positiveExtensionPercent * -1) * glY1);\n                juce::ColourGradient gradient = juce::ColourGradient (minColor, x1, y1, maxColor, x2, y2,false);\n                for (auto& colors : colorStopsObj->getProperties())\n                {\n                    juce::String colorID = colors.name.toString();\n                    auto* color = colorStopsObj->getProperty(colorID).getDynamicObject();\n                    //Calculate any offset from the original additional color percentage along gradient line\n                    if(color->getProperty(\"type\") == \"additional\"){\n                        juce::String hexString = color->getProperty(\"hex\");\n                        juce::Colour additionalColor = juce::Colour::fromString(hexString);\n                        double originalPercent = color->getProperty(\"position\");\n                        double gradientLineDistanceExtension = gradientLineDistance * (1 + (negativeExtensionPercent + positiveExtensionPercent));\n                        double offsetPercent = ((gradientLineDistance * originalPercent) + (gradientLineDistance * negativeExtensionPercent)) / gradientLineDistanceExtension;\n                        gradient.addColour(offsetPercent, additionalColor);\n                    }\n                }\n                return gradient;\n            }\n            //else we assume it's just one colour\n            else {\n                return juce::Colour::fromString(colorVariant.toString());;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "react_juce/core/Utils.h",
    "content": "/*\n  ==============================================================================\n\n    Utils.h\n    Created: 20 Jan 2021 10:44:27pm\n\n  ==============================================================================\n*/\n\n#pragma once\n\n#include <variant>\n\n\nnamespace reactjuce\n{\n    namespace detail\n    {\n        // Constructs a generic error object to pass through to JS\n        juce::var makeErrorObject(const juce::String& errorName, const juce::String& errorMessage);\n\n        // Constructs either a Color or ColorGradient\n        std::variant<juce::Colour, juce::ColourGradient> makeColorVariant(const juce::var& colorVariant, const juce::Rectangle<int>& localBounds);\n    }\n}\n"
  },
  {
    "path": "react_juce/core/View.cpp",
    "content": "/*\n  ==============================================================================\n\n    View.cpp\n    Created: 26 Nov 2018 3:38:37am\n\n  ==============================================================================\n*/\n\n#include \"View.h\"\n#include \"Utils.h\"\n\n#include <climits>\n\n\nnamespace reactjuce\n{\n\n    namespace detail\n    {\n        static juce::var getMouseEventRelatedTarget(const juce::MouseEvent& e, const View& view)\n        {\n            juce::Component *topParent              = view.getTopLevelComponent();\n            const juce::MouseEvent topRelativeEvent = e.getEventRelativeTo(topParent);\n\n            juce::Component *componentUnderMouse = topParent->getComponentAt(topRelativeEvent.x, topRelativeEvent.y);\n\n            if (auto v = dynamic_cast<View*>(componentUnderMouse))\n                return v->getViewId();\n\n            // return null relatedTarget if event occurred from a non-View component.\n            return {};\n        }\n\n        /** A little helper for DynamicObject construction. */\n        static juce::var makeViewEventObject (const juce::NamedValueSet& props, const View& view)\n        {\n            auto* o = new juce::DynamicObject();\n\n            for (auto& pair : props)\n                o->setProperty(pair.name, pair.value);\n\n            o->setProperty(\"target\", view.getViewId());\n\n            //TODO: Add timeStamp.\n\n            return juce::var(o);\n        }\n\n        /** Another little helper for DynamicObject construction. */\n        static juce::var makeViewEventObject (const juce::MouseEvent& me, const View &view)\n        {\n            // TODO: Get all of it!\n            return makeViewEventObject({\n                {\"x\", me.x},\n                {\"y\", me.y},\n                {\"screenX\", me.getScreenX()},\n                {\"screenY\", me.getScreenY()},\n                {\"relatedTarget\", getMouseEventRelatedTarget(me, view)}\n            }, view);\n        }\n\n        /** And another little helper for DynamicObject construction. */\n        static juce::var makeViewEventObject (const juce::KeyPress& ke, const View &view)\n        {\n            // TODO: Get all of it!\n            return makeViewEventObject({\n                {\"key\", juce::String(ke.getTextCharacter())},\n                {\"keyCode\", ke.getKeyCode()},\n            }, view);\n        }\n\n    }\n\n    //==============================================================================\n    ViewId View::getViewId() const\n    {\n        return juce::DefaultHashFunctions::generateHash(_viewId, INT_MAX);\n    }\n\n    juce::Identifier View::getRefId() const\n    {\n        return _refId;\n    }\n\n    void View::setProperty (const juce::Identifier& name, const juce::var& value)\n    {\n        props.set(name, value);\n\n        if (name == interceptClickEventsProp)\n        {\n            switch (static_cast<int> (value))\n            {\n                case 0:      setInterceptsMouseClicks (false, false);  break;\n                case 1:      setInterceptsMouseClicks (true,  true);   break;\n                case 2:      setInterceptsMouseClicks (true,  false);  break;\n                case 3:      setInterceptsMouseClicks (false, true);   break;\n\n                default:     setInterceptsMouseClicks (true,  true);   break;\n            }\n        }\n\n        if (name == onKeyPressProp)\n            setWantsKeyboardFocus(true);\n\n        if (name == opacityProp)\n            setAlpha(static_cast<float> (value));\n\n        if (name == refIdProp)\n            _refId = juce::Identifier(value.toString());\n    }\n\n    void View::addChild (View* childView, int index)\n    {\n        // Add the child view to our component heirarchy.\n        addAndMakeVisible(childView, index);\n    }\n\n    void View::setFloatBounds(juce::Rectangle<float> bounds)\n    {\n        cachedFloatBounds = bounds;\n\n        // Update transforms\n        if (props.contains(transformMatrixProp))\n        {\n            const juce::var& matrix = props[transformMatrixProp];\n            if(matrix.isArray() && matrix.getArray()->size() >= 16) {\n              const juce::Array<juce::var> &m = *matrix.getArray();\n\n              auto cxRelParent = cachedFloatBounds.getX() + cachedFloatBounds.getWidth() * 0.5f;\n              auto cyRelParent = cachedFloatBounds.getY() + cachedFloatBounds.getHeight() * 0.5f;\n\n              const auto translateToOrigin = juce::AffineTransform::translation(cxRelParent * -1.0f, cyRelParent * -1.0f);\n              // set 2d homogeneous matrix using 3d homogeneous matrix\n              const auto transform = juce::AffineTransform(\n                m[0], m[1], m[3],\n                m[4], m[5], m[7]\n              );\n              const auto translateFromOrigin = juce::AffineTransform::translation(cxRelParent, cyRelParent);\n\n              setTransform(translateToOrigin.followedBy(transform).followedBy(translateFromOrigin));\n            }\n        }\n    }\n\n    //==============================================================================\n    float View::getResolvedLengthProperty (const juce::String& name, float axisLength)\n    {\n        float ret = 0;\n\n        if (props.contains(name))\n        {\n            const auto& v = props[name];\n\n            if (v.isString() && v.toString().trim().endsWithChar('%'))\n            {\n                float pctVal = v.toString().retainCharacters(\"-1234567890.\").getFloatValue();\n                ret = axisLength * (pctVal / 100.0f);\n            }\n            else\n            {\n                ret = (float) v;\n            }\n        }\n\n        return ret;\n    }\n\n    void View::paint (juce::Graphics& g)\n    {\n        if (props.contains(borderPathProp))\n        {\n            juce::Path p = juce::Drawable::parseSVGPath(props[borderPathProp].toString());\n\n            if (props.contains(borderColorProp))\n            {\n                juce::StringRef colorString = props[borderColorProp].toString();\n                juce::Colour c = juce::Colour::fromString(colorString);\n                float borderWidth = props.getWithDefault(borderWidthProp, 1.0);\n\n                g.setColour(c);\n                g.strokePath(p, juce::PathStrokeType(borderWidth));\n            }\n\n            g.reduceClipRegion(p);\n        }\n        else if (props.contains(borderColorProp) && props.contains(borderWidthProp))\n        {\n            juce::Path border;\n            juce::StringRef colorString = props[borderColorProp].toString();\n            auto c = juce::Colour::fromString(colorString);\n            float borderWidth = props[borderWidthProp];\n\n            // Note this little bounds trick. When a Path is stroked, the line width extends\n            // outwards in both directions from the coordinate line. If the coordinate\n            // line is the exact bounding box then the component clipping makes the corners\n            // appear to have different radii on the interior and exterior of the box.\n            auto borderBounds = getLocalBounds().toFloat().reduced(borderWidth * 0.5f);\n            auto width  = borderBounds.getWidth();\n            auto height = borderBounds.getHeight();\n            auto minLength = juce::jmin(width, height);\n            float borderRadius = getResolvedLengthProperty(borderRadiusProp.toString(), minLength);\n\n            border.addRoundedRectangle(borderBounds, borderRadius);\n            g.setColour(c);\n            g.strokePath(border, juce::PathStrokeType(borderWidth));\n            g.reduceClipRegion(border);\n        }\n\n        if (props.contains(backgroundColorProp))\n        {\n            auto colorProp = props[backgroundColorProp];\n            auto colorVariant = detail::makeColorVariant(colorProp, getLocalBounds());\n            if(const auto color (std::get_if<juce::Colour>(&colorVariant)); color)\n            {\n                if (!color->isTransparent())\n                    g.fillAll(*color);\n            }\n            else if(const auto gradient (std::get_if<juce::ColourGradient>(&colorVariant)); gradient)\n            {\n                g.setGradientFill(*gradient);\n                g.fillAll();\n            }\n        }\n    }\n\n    //==============================================================================\n    void View::resized()\n    {\n        auto w = cachedFloatBounds.getWidth();\n        auto h = cachedFloatBounds.getHeight();\n\n        dispatchViewEvent(\"onMeasure\", detail::makeViewEventObject({\n            {\"width\", w},\n            {\"height\", h}\n        }, *this));\n    }\n\n    void View::mouseDown (const juce::MouseEvent& e)\n    {\n        dispatchViewEvent(\"onMouseDown\", detail::makeViewEventObject(e, *this));\n    }\n\n    void View::mouseUp (const juce::MouseEvent& e)\n    {\n        dispatchViewEvent(\"onMouseUp\", detail::makeViewEventObject(e, *this));\n    }\n\n    void View::mouseEnter (const juce::MouseEvent& e)\n    {\n        dispatchViewEvent(\"onMouseEnter\", detail::makeViewEventObject(e, *this));\n    }\n\n    void View::mouseExit (const juce::MouseEvent& e)\n    {\n        dispatchViewEvent(\"onMouseLeave\", detail::makeViewEventObject(e, *this));\n    }\n\n    void View::mouseDrag (const juce::MouseEvent& e)\n    {\n        // TODO: mouseDrag isn't a dom event... is it?\n        dispatchViewEvent(\"onMouseDrag\", detail::makeViewEventObject(e, *this));\n    }\n\n    void View::mouseDoubleClick (const juce::MouseEvent& e)\n    {\n        dispatchViewEvent(\"onMouseDoubleClick\", detail::makeViewEventObject(e, *this));\n    }\n\n    bool View::keyPressed (const juce::KeyPress& key)\n    {\n        dispatchViewEvent(\"onKeyPress\", detail::makeViewEventObject(key, *this));\n\n        // We always inform the underlying juce::Component that we've consumed the event,\n        // because we manually bubble a SyntheticEvent wrapper up the javascript view tree.\n        // However, because the React app may be only a subtree of the overall app architecture,\n        // we skip up to the ReactApplicationRoot parent and restart the keypress event propagation\n        // up there.\n        if (auto* parent = findParentComponentOfClass<ReactApplicationRoot>())\n            parent->keyPressed(key);\n\n        return true;\n    }\n\n    void View::dispatchViewEvent (const juce::String& eventType, const juce::var& e)\n    {\n        JUCE_ASSERT_MESSAGE_THREAD\n\n        if (auto *parent = findParentComponentOfClass<ReactApplicationRoot>())\n            parent->dispatchViewEvent(getViewId(), eventType, e);\n    }\n\n    void View::exportMethod(const juce::String &method, juce::var::NativeFunction fn)\n    {\n        JUCE_ASSERT_MESSAGE_THREAD\n        nativeMethods[method] = std::move(fn);\n    }\n\n    juce::var View::invokeMethod(const juce::String &method, const juce::var::NativeFunctionArgs &args)\n    {\n        JUCE_ASSERT_MESSAGE_THREAD\n        auto it = nativeMethods.find(method);\n\n        if (it != nativeMethods.end())\n            return it->second(args);\n\n        throw std::logic_error(\"Caller attempted to invoke a non-existent View method\");\n    }\n}\n"
  },
  {
    "path": "react_juce/core/View.h",
    "content": "/*\n  ==============================================================================\n\n    View.h\n    Created: 26 Nov 2018 3:38:37am\n\n  ==============================================================================\n*/\n\n#pragma once\n\n#include <map>\n\n\nnamespace reactjuce\n{\n\n    // Internally we use a juce::Uuid for uniquely identifying views, but we\n    // need that same identifier to make a transit through JavaScript land\n    // and still match afterwards. So we map our Uuids into a signed 32-bit integer\n    // type and leave Duktape to perform the appropriate cast through JavaScript's\n    // double-width \"Number\" type.\n    using ViewId = juce::int32;\n\n    //==============================================================================\n    /** The View class is the core component abstraction for React-JUCE's declarative\n        flex-based component composition.\n     */\n    class View : public juce::Component\n    {\n    public:\n        //==============================================================================\n        static const inline juce::Identifier interceptClickEventsProp = \"interceptClickEvents\";\n        static const inline juce::Identifier onKeyPressProp           = \"onKeyPress\";\n        static const inline juce::Identifier opacityProp              = \"opacity\";\n        static const inline juce::Identifier refIdProp                = \"refId\";\n        static const inline juce::Identifier transformMatrixProp      = \"transform-matrix\";\n\n        static const inline juce::Identifier backgroundColorProp      = \"background-color\";\n\n        static const inline juce::Identifier borderColorProp          = \"border-color\";\n        static const inline juce::Identifier borderPathProp           = \"border-path\";\n        static const inline juce::Identifier borderRadiusProp         = \"border-radius\";\n        static const inline juce::Identifier borderWidthProp          = \"border-width\";\n\n        //==============================================================================\n        View() = default;\n        ~View() override = default;\n\n        //==============================================================================\n        /** Returns this view's identifier. */\n        ViewId getViewId() const;\n\n        /** Returns this view's reference identifier, optionally set via React props. */\n        juce::Identifier getRefId() const;\n\n        /** Set a property on the native view. */\n        virtual void setProperty (const juce::Identifier&, const juce::var&);\n\n        /** Adds a child component behind the existing children. */\n        virtual void addChild (View* childView, int index = -1);\n\n        /** Updates the cached float layout bounds from the shadow tree. */\n        void setFloatBounds (juce::Rectangle<float> bounds);\n\n        //==============================================================================\n        /** Resolves a property to a specific point value or 0 if not present. */\n        float getResolvedLengthProperty (const juce::String& name, float axisLength);\n\n        /** Override the default Component method with default paint behaviors. */\n        void paint (juce::Graphics& g) override;\n\n        //==============================================================================\n        /** Dispatches a resized event to the React application. */\n        void resized() override;\n\n        /** Dispatches a mouseDown event to the React application. */\n        void mouseDown (const juce::MouseEvent& e) override;\n\n        /** Dispatches a mouseUp event to the React application. */\n        void mouseUp (const juce::MouseEvent& e) override;\n\n        /** Dispatches a mouseEnter event to the React application. */\n        void mouseEnter (const juce::MouseEvent& e) override;\n\n        /** Dispatches a mouseLeave event to the React application. */\n        void mouseExit (const juce::MouseEvent& e) override;\n\n        /** Dispatches a mouseDrag event to the React application. */\n        void mouseDrag (const juce::MouseEvent& e) override;\n\n        /** Dispatches a mouseDoubleClick event to the React application. */\n        void mouseDoubleClick (const juce::MouseEvent& e) override;\n\n        /** Dispatches a keyPress event to the React application. */\n        bool keyPressed (const juce::KeyPress& e) override;\n\n        //==============================================================================\n        /** Invokes, if exists, the respective view event handler. */\n        void dispatchViewEvent (const juce::String& eventType, const juce::var& e);\n\n        //==============================================================================\n        /** Invokes an \"exported\" native method on the View instance */\n        juce::var invokeMethod(const juce::String &method, const juce::var::NativeFunctionArgs &args);\n\n    protected:\n        //==============================================================================\n        /** Exports/Registers a method on this View instance so it may be called\n         *  directly from React. This is here to support calling ViewInstance functions\n         *  in React via component refs.\n         * */\n        void exportMethod(const juce::String &method, juce::var::NativeFunction fn);\n\n        //==============================================================================\n        juce::NamedValueSet props;\n        juce::Rectangle<float> cachedFloatBounds;\n\n    private:\n        //==============================================================================\n        juce::Uuid _viewId;\n        juce::Identifier _refId;\n\n        std::unordered_map<juce::String, juce::var::NativeFunction> nativeMethods;\n\n        //==============================================================================\n        JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (View)\n    };\n\n}\n"
  },
  {
    "path": "react_juce/core/ViewManager.cpp",
    "content": "/*\n  ==============================================================================\n\n    ViewManager.cpp\n    Created: 21 May 2020 15:32:00am\n\n  ==============================================================================\n*/\n\n#include \"ViewManager.h\"\n#include \"CanvasView.h\"\n#include \"ImageView.h\"\n#include \"ScrollView.h\"\n#include \"ScrollViewContentShadowView.h\"\n#include \"TextView.h\"\n#include \"TextInputView.h\"\n#include \"TextShadowView.h\"\n\n\nnamespace reactjuce\n{\n\n    namespace\n    {\n\n        /** A quick helper for registering view types. */\n        template <typename ViewType, typename ShadowViewType>\n        struct GenericViewFactory\n        {\n            ViewManager::ViewPair operator()() {\n                auto view = std::make_unique<ViewType>();\n                auto shadowView = std::make_unique<ShadowViewType>(view.get());\n\n                return {std::move(view), std::move(shadowView)};\n            }\n        };\n\n    }\n\n    ViewManager::ViewManager(View* rootView)\n        : rootId(rootView->getViewId())\n    {\n        shadowViewTable[rootId] = std::make_unique<ShadowView>(rootView);\n\n        // Register the default view types\n        registerViewType(\"View\", GenericViewFactory<View, ShadowView>());\n        registerViewType(\"Text\", GenericViewFactory<TextView, TextShadowView>());\n        registerViewType(\"TextInput\", GenericViewFactory<TextInputView, ShadowView>());\n        registerViewType(\"CanvasView\", GenericViewFactory<CanvasView, ShadowView>());\n        registerViewType(\"Image\", GenericViewFactory<ImageView, ShadowView>());\n        registerViewType(\"ScrollView\", GenericViewFactory<ScrollView, ShadowView>());\n        registerViewType(\"ScrollViewContentView\", GenericViewFactory<View, ScrollViewContentShadowView>());\n    }\n\n    void ViewManager::registerViewType(const juce::String &typeId, ViewFactory f)\n    {\n        // If you hit this jassert, you're trying to register a type which\n        // has already been registered!\n        jassert (viewFactories.find(typeId) == viewFactories.end());\n        viewFactories[typeId] = f;\n    }\n\n    ViewId ViewManager::createViewInstance(const juce::String& viewType)\n    {\n        // We can't create a view instance of a type that hasn't been registered.\n        jassert (viewFactories.find(viewType) != viewFactories.end());\n\n        auto [view, shadowView] = viewFactories[viewType]();\n        ViewId vid = view->getViewId();\n\n        viewTable[vid] = std::move(view);\n        shadowViewTable[vid] = std::move(shadowView);\n\n        return vid;\n    }\n\n    ViewId ViewManager::createTextViewInstance(const juce::String& value)\n    {\n        std::unique_ptr<View> view = std::make_unique<RawTextView>(value);\n        ViewId id = view->getViewId();\n\n        viewTable[id] = std::move(view);\n        return id;\n    }\n\n    void ViewManager::setViewProperty(ViewId viewId, const juce::String& name, const juce::var& value)\n    {\n        const auto& [view, shadow] = getViewHandle(viewId);\n\n        // ShadowView::setProperty returns true when a layout prop\n        // has been set.  Otherwise set on the view and repaint\n        if(!shadow->setProperty(name, value)) {\n          view->setProperty(name, value);\n          view->repaint();\n        }\n    }\n\n    void ViewManager::setRawTextValue(ViewId viewId, const juce::String& value)\n    {\n        View* view = getViewHandle(viewId).first;\n\n        if (auto* rawTextView = dynamic_cast<RawTextView*>(view))\n        {\n            // Update text\n            rawTextView->setText(value);\n\n            if (auto* parent = dynamic_cast<TextView*>(rawTextView->getParentComponent()))\n            {\n                // If we have a parent already, find the parent's shadow node and\n                // mark it dirty, then we'll issue a new layout call\n                ShadowView* parentShadowView = getViewHandle(parent->getViewId()).second;\n\n                if (auto* textShadowView = dynamic_cast<TextShadowView*>(parentShadowView))\n                {\n                    textShadowView->markDirty();\n                }\n\n                // Then we need to paint, but the RawTextView has no idea how to paint its text,\n                // we need to tell the parent to repaint its children.\n                parent->repaint();\n            }\n        }\n    }\n\n    void ViewManager::insertChild(ViewId parentId, ViewId childId, int index)\n    {\n        // We probably don't want to be doing this!\n        jassert(childId != rootId);\n\n        const auto& [parentView, parentShadowView] = getViewHandle(parentId);\n        const auto& [childView, childShadowView] = getViewHandle(childId);\n\n        if (dynamic_cast<TextView*>(parentView))\n        {\n            // If we're trying to append a child to a text view, it will be raw text\n            // with no accompanying shadow view, and we'll need to mark the parent\n            // TextShadowView dirty before the subsequent layout pass.\n            jassert (dynamic_cast<RawTextView*>(childView) != nullptr);\n            jassert (childShadowView == nullptr);\n\n            parentView->addChild(childView, index);\n            dynamic_cast<TextShadowView*>(parentShadowView)->markDirty();\n        }\n        else\n        {\n            parentView->addChild(childView, index);\n            parentShadowView->addChild(childShadowView, index);\n        }\n    }\n\n    void ViewManager::removeChild(ViewId parentId, ViewId childId)\n    {\n        // We probably don't want to be doing this!\n        jassert(childId != rootId);\n\n        const auto& [parentView, parentShadowView] = getViewHandle(parentId);\n        const auto& [childView, childShadowView] = getViewHandle(childId);\n\n        // TODO: Set a View::removeChild method and call into that here. Make\n        // that method virtual so that, e.g., the scroll view can override to\n        // remove the child from its viewport\n        parentView->removeChildComponent(childView);\n\n        // Here we have to clear the view table of all children of this view.\n        // React may clear a whole subtree from the interface by removing a\n        // single component at the root of the tree. Because the view table\n        // is a flat map of viewId to View, if we only remove that root view\n        // from the table we leave all of its children dangling, which confuses\n        // subsequent functionality like `getViewHandle` or `getViewByRefId`\n        std::vector<ViewId> childIds;\n        enumerateChildViewIds(childIds, childView);\n\n        for (auto& id : childIds)\n            viewTable.erase(id);\n\n        // We might be dealing with a text view, in which case we expect a null\n        // shadow view.\n        if (parentShadowView && childShadowView)\n        {\n            parentShadowView->removeChild(childShadowView);\n\n            // Then here, since we now know we have a child shadow view,\n            // we try also to remove its children from the shadowViewTable to\n            // prevent dangling children like in the viewTable above.\n            for (auto& id : childIds)\n                shadowViewTable.erase(id);\n        }\n    }\n\n    void ViewManager::enumerateChildViewIds (std::vector<ViewId>& ids, View* v)\n    {\n        for (auto* child : v->getChildren())\n        {\n            // Some view elements may mount a plain juce::Component, such as the\n            // ScrollView mounting a juce::Viewport which is a juce::Component but\n            // not a juce::View. Such elements aren't in our table and can be skipped\n            if (auto* childView = dynamic_cast<View*>(child))\n            {\n                enumerateChildViewIds(ids, childView);\n            }\n        }\n\n        ids.push_back(v->getViewId());\n    }\n\n    void ViewManager::performRootShadowTreeLayout()\n    {\n        ShadowView* root = shadowViewTable[rootId].get();\n        jassert(root);\n\n        juce::Rectangle<float> rootBounds = root->getAssociatedView()->getLocalBounds().toFloat();\n        const float width = rootBounds.getWidth();\n        const float height = rootBounds.getHeight();\n\n        root->computeViewLayout(width, height);\n        root->flushViewLayout();\n    }\n\n    void ViewManager::clearViewTables()\n    {\n        auto nh = shadowViewTable.extract(rootId);\n\n        viewTable.clear();\n        shadowViewTable.clear();\n\n        // Make a new root shadow view to reinitialize the view table\n        shadowViewTable[rootId] = std::make_unique<ShadowView>(nh.mapped()->getAssociatedView());\n    }\n\n    juce::var ViewManager::invokeViewMethod(ViewId viewId, const juce::String &method, const juce::var::NativeFunctionArgs &args)\n    {\n        if (View *view = getViewHandle(viewId).first)\n            return view->invokeMethod(method, args);\n\n        throw std::logic_error(\"Caller attempted to invoke method on non-existent View instance\");\n    }\n\n    std::pair<View*, ShadowView*> ViewManager::getViewHandle (ViewId viewId)\n    {\n        if (viewId == rootId)\n            return {shadowViewTable[viewId]->getAssociatedView(), shadowViewTable[viewId].get()};\n\n        if (viewTable.find(viewId) != viewTable.end())\n            return {viewTable[viewId].get(), shadowViewTable[viewId].get()};\n\n        // If we land here, you asked for a view that we don't have.\n        jassertfalse;\n        return {nullptr, nullptr};\n    }\n\n    View* ViewManager::getViewByRefId (const juce::Identifier& refId)\n    {\n        if (refId == getRootViewRefId())\n            return shadowViewTable[rootId]->getAssociatedView();\n\n        for (auto& pair : viewTable)\n        {\n            auto* view = pair.second.get();\n\n            if (refId == view->getRefId())\n                return view;\n        }\n\n        return nullptr;\n    }\n\n    juce::Identifier ViewManager::getRootViewRefId()\n    {\n       View* root = shadowViewTable[rootId]->getAssociatedView();\n       jassert(root);\n\n       return root->getRefId();\n    }\n}\n"
  },
  {
    "path": "react_juce/core/ViewManager.h",
    "content": "/*\n  ==============================================================================\n\n    ViewManager.h\n    Created: 21 May 2020 15:32:00am\n\n  ==============================================================================\n*/\n\n#pragma once\n\n#include <map>\n\n#include \"View.h\"\n#include \"ShadowView.h\"\n\n\nnamespace reactjuce\n{\n    /**\n     * ViewManager manages the set of Views held by a \"root\" View/ReactApplicationRoot instance.\n     *\n     * The ViewManager is responsible for adding/removing child Views to the root View's component\n     * tree and registering new view types.\n     *\n     * ViewManager also manages triggering the layout of all View nodes within the root View's\n     * tree, i.e. when a nodes is added/removed or has a property modified that requires a layout\n     * change (flexbox props etc).\n     * */\n    class ViewManager\n    {\n    public:\n        //==============================================================================\n        // We allow registering arbitrary view types with the React context by way of\n        // a \"ViewFactory\" here which is a user-defined function that produces a View\n        // and a corresponding ShadowView.\n        using ViewPair = std::pair<std::unique_ptr<View>, std::unique_ptr<ShadowView>>;\n        using ViewFactory = std::function<ViewPair()>;\n\n        //==============================================================================\n        explicit ViewManager(View* rootView);\n        ~ViewManager() = default;\n\n        /** Registers a new dynamic view type and its associated factory. */\n        void registerViewType(const juce::String& typeId, ViewFactory f);\n\n        /** Creates a new view instance and registers it with the view table. */\n        ViewId createViewInstance(const juce::String& viewType);\n\n        /** Creates a new text view instance and registers it with the view table. */\n        ViewId createTextViewInstance(const juce::String& value);\n\n        /** Calls View::setProperty on the requested View */\n        void setViewProperty(ViewId viewId, const juce::String& name, const juce::var& value);\n\n        /** Calls RawTextView::setText on the requested View. If the ViewId supplied is not the id of a RawTextView\n         *  this is a no-op.\n         * */\n        void setRawTextValue(ViewId viewId, const juce::String& value);\n\n        /** Inserts/Appends a child View to the given parent View\n         *  Callers may call without supplying index (or with index = 1)\n         *  to append to the end of the parents child view list rather than\n         *  inserting.\n         * */\n        void insertChild(ViewId parentId, ViewId childId, int index = -1);\n\n        /** Removes a child View from the given parent View */\n        void removeChild (ViewId parentId, ViewId childId);\n\n        /** Recursively computes the shadow tree layout on the root ShadowView, then traverses the tree\n            flushing new layout bounds to the associated view components.\n         */\n        void performRootShadowTreeLayout();\n\n        /** Empties the internal view tables, deallocating every view except the root in the ViewManager heirarchy. */\n        void clearViewTables();\n\n        /** Invokes an exported native method on the given View instance.\n         *  This method is used to allow JS code to invoke a native function on a ViewInstance using React refs.\n         **/\n        juce::var invokeViewMethod(ViewId viewId, const juce::String &method, const juce::var::NativeFunctionArgs &args);\n\n        //==============================================================================\n    private:\n        void enumerateChildViewIds (std::vector<ViewId>& ids, View* v);\n\n        /** Returns a pointer pair to the view associated to the given id. */\n        std::pair<View*, ShadowView*> getViewHandle (ViewId viewId);\n\n        /** Walks the view table, returning the first view with a `refId`\n         *  whose value equals the provided id.\n         */\n        View* getViewByRefId (const juce::Identifier& refId);\n\n        /** Helper function to return refId of the root view */\n        juce::Identifier getRootViewRefId();\n\n        ViewId                                        rootId;\n        std::map<ViewId, std::unique_ptr<View>>       viewTable;\n        std::map<ViewId, std::unique_ptr<ShadowView>> shadowViewTable;\n        std::map<juce::String, ViewFactory>           viewFactories;\n    };\n}\n"
  },
  {
    "path": "react_juce/core/YogaImplInclude.cpp",
    "content": "#pragma once\n\n// Disable compiler warnings for yoga\n#if _MSC_VER\n#pragma warning(push)\n  #pragma warning(disable : 4018) // signed/unsigned mismatch\n  #pragma warning(disable : 4127) // conditional expression is constant\n  #pragma warning(disable : 4244) // possible loss of data\n  #pragma warning(disable : 4505) // unreferenced local function\n  #pragma warning(disable : 4611) // object destruction is non-portable\n  #pragma warning(disable : 4702) // unreachable code\n  #pragma warning(disable : 4100 4244 4459)\n#elif __clang__\n#pragma clang diagnostic push\n #pragma clang diagnostic ignored \"-Wextra-semi\"\n #pragma clang diagnostic ignored \"-Wzero-as-null-pointer-constant\"\n #pragma clang diagnostic ignored \"-Wswitch-enum\"\n #pragma clang diagnostic ignored \"-Wshorten-64-to-32\"\n #pragma clang diagnostic ignored \"-Wshadow-field-in-constructor\"\n #pragma clang diagnostic ignored \"-Wsign-conversion\"\n #pragma clang diagnostic ignored \"-Wformat-nonliteral\"\n #if __clang_major__ > 10\n  #pragma clang diagnostic ignored \"-Wc++98-compat-extra-semi\"\n  #pragma clang diagnostic ignored \"-Wimplicit-int-conversion\"\n  #pragma clang diagnostic ignored \"-Wimplicit-float-conversion\"\n #else\n  #pragma clang diagnostic ignored \"-Wconversion\"\n #endif\n#elif __GNUC__\n#pragma GCC diagnostic push\n#pragma GCC diagnostic ignored \"-Wzero-as-null-pointer-constant\"\n#pragma GCC diagnostic ignored \"-Wsign-conversion\"\n#pragma GCC diagnostic ignored \"-Wswitch-enum\"\n#pragma GCC diagnostic ignored \"-Wunused-variable\"\n#pragma GCC diagnostic ignored \"-Wredundant-decls\"\n#pragma GCC diagnostic ignored \"-Wpedantic\"\n#endif\n\n#include \"yoga/yoga/log.cpp\"\n#include \"yoga/yoga/event/event.cpp\"\n#include \"yoga/yoga/Utils.cpp\"\n#include \"yoga/yoga/YGConfig.cpp\"\n#include \"yoga/yoga/YGEnums.cpp\"\n#include \"yoga/yoga/YGLayout.cpp\"\n#include \"yoga/yoga/YGNode.cpp\"\n#include \"yoga/yoga/YGNodePrint.cpp\"\n#include \"yoga/yoga/YGStyle.cpp\"\n#include \"yoga/yoga/YGValue.cpp\"\n#include \"yoga/yoga/Yoga.cpp\"\n\n#include \"yoga/yoga/YGMacros.h\"\n\n// This is a hacky workaround for an issue introduced in the YG_ENUM_BEGIN\n// macro in YGMacros.h. When compiled on VS2017 we fall to their definition\n// of YG_ENUM_BEGIN in YGMacros.h, which runs into something like a wrap-around overflow\n// with signed types, and ends up trying to index with a garbage value into\n// an array. We overwrite the YG_ENUM_BEGIN definition here with an unsigned\n// type and everything seems to work ok.\n// See: https://github.com/facebook/yoga/issues/891\n#ifndef NS_ENUM\n#undef YG_ENUM_BEGIN\n#define YG_ENUM_BEGIN(name) enum name: unsigned\n#endif\n\n#include \"yoga/yoga/log.h\"\n#include \"yoga/yoga/event/event.h\"\n#include \"yoga/yoga/YGConfig.h\"\n#include \"yoga/yoga/YGEnums.h\"\n#include \"yoga/yoga/YGFloatOptional.h\"\n#include \"yoga/yoga/YGLayout.h\"\n#include \"yoga/yoga/YGNodePrint.h\"\n#include \"yoga/yoga/YGStyle.h\"\n#include \"yoga/yoga/YGValue.h\"\n#include \"yoga/yoga/Yoga-internal.h\"\n#include \"yoga/yoga/Yoga.h\"\n\n// Enable compiler warnings\n#if _MSC_VER\n#pragma warning (pop)\n#elif __clang__\n#pragma clang diagnostic pop\n#elif __GNUC__\n#pragma GCC diagnostic pop\n#endif\n"
  },
  {
    "path": "react_juce/duktape/AUTHORS.rst",
    "content": "===============\nDuktape authors\n===============\n\nCopyright\n=========\n\nDuktape copyrights are held by its authors.  Each author has a copyright\nto their contribution, and agrees to irrevocably license the contribution\nunder the Duktape ``LICENSE.txt``.\n\nAuthors\n=======\n\nPlease include an e-mail address, a link to your GitHub profile, or something\nsimilar to allow your contribution to be identified accurately.\n\nThe following people have contributed code, website contents, or Wiki contents,\nand agreed to irrevocably license their contributions under the Duktape\n``LICENSE.txt`` (in order of appearance):\n\n* Sami Vaarala <sami.vaarala@iki.fi>\n* Niki Dobrev\n* Andreas Öman <andreas@lonelycoder.com>\n* László Langó <llango.u-szeged@partner.samsung.com>\n* Legimet <legimet.calc@gmail.com>\n* Karl Skomski <karl@skomski.com>\n* Bruce Pascoe <fatcerberus1@gmail.com>\n* René Hollander <rene@rene8888.at>\n* Julien Hamaide (https://github.com/crazyjul)\n* Sebastian Götte (https://github.com/jaseg)\n* Tomasz Magulski (https://github.com/magul)\n* \\D. Bohdan (https://github.com/dbohdan)\n* Ondřej Jirman (https://github.com/megous)\n* Saúl Ibarra Corretgé <saghul@gmail.com>\n* Jeremy HU <huxingyi@msn.com>\n* Ole André Vadla Ravnås (https://github.com/oleavr)\n* Harold Brenes (https://github.com/harold-b)\n* Oliver Crow (https://github.com/ocrow)\n* Jakub Chłapiński (https://github.com/jchlapinski)\n* Brett Vickers (https://github.com/beevik)\n* Dominik Okwieka (https://github.com/okitec)\n* Remko Tronçon (https://el-tramo.be)\n* Romero Malaquias (rbsm@ic.ufal.br)\n* Michael Drake <michael.drake@codethink.co.uk>\n* Steven Don (https://github.com/shdon)\n* Simon Stone (https://github.com/sstone1)\n* \\J. McC. (https://github.com/jmhmccr)\n* Jakub Nowakowski (https://github.com/jimvonmoon)\n* Tommy Nguyen (https://github.com/tn0502)\n* Fabrice Fontaine (https://github.com/ffontaine)\n* Christopher Hiller (https://github.com/boneskull)\n* Gonzalo Diethelm (https://github.com/gonzus)\n* Michal Kasperek (https://github.com/michalkas)\n* Andrew Janke (https://github.com/apjanke)\n* Steve Fan (https://github.com/stevefan1999)\n* Edward Betts (https://github.com/edwardbetts)\n* Ozhan Duz (https://github.com/webfolderio)\n* Akos Kiss (https://github.com/akosthekiss)\n* TheBrokenRail (https://github.com/TheBrokenRail)\n* Jesse Doyle (https://github.com/jessedoyle)\n* Gero Kuehn (https://github.com/dc6jgk)\n* James Swift (https://github.com/phraemer)\n* Luis de Bethencourt (https://github.com/luisbg)\n* Ian Whyman (https://github.com/v00d00)\n\nOther contributions\n===================\n\nThe following people have contributed something other than code (e.g. reported\nbugs, provided ideas, etc; roughly in order of appearance):\n\n* Greg Burns\n* Anthony Rabine\n* Carlos Costa\n* Aurélien Bouilland\n* Preet Desai (Pris Matic)\n* judofyr (http://www.reddit.com/user/judofyr)\n* Jason Woofenden\n* Michał Przybyś\n* Anthony Howe\n* Conrad Pankoff\n* Jim Schimpf\n* Rajaran Gaunker (https://github.com/zimbabao)\n* Andreas Öman\n* Doug Sanden\n* Josh Engebretson (https://github.com/JoshEngebretson)\n* Remo Eichenberger (https://github.com/remoe)\n* Mamod Mehyar (https://github.com/mamod)\n* David Demelier (https://github.com/markand)\n* Tim Caswell (https://github.com/creationix)\n* Mitchell Blank Jr (https://github.com/mitchblank)\n* https://github.com/yushli\n* Seo Sanghyeon (https://github.com/sanxiyn)\n* Han ChoongWoo (https://github.com/tunz)\n* Joshua Peek (https://github.com/josh)\n* Bruce E. Pascoe (https://github.com/fatcerberus)\n* https://github.com/Kelledin\n* https://github.com/sstruchtrup\n* Michael Drake (https://github.com/tlsa)\n* https://github.com/chris-y\n* Laurent Zubiaur (https://github.com/lzubiaur)\n* Neil Kolban (https://github.com/nkolban)\n* Wilhelm Wanecek (https://github.com/wanecek)\n* Andrew Janke (https://github.com/apjanke)\n* Unamer (https://github.com/unamer)\n* Karl Dahlke (eklhad@gmail.com)\n\nIf you are accidentally missing from this list, send me an e-mail\n(``sami.vaarala@iki.fi``) and I'll fix the omission.\n"
  },
  {
    "path": "react_juce/duktape/LICENSE.txt",
    "content": "===============\nDuktape license\n===============\n\n(http://opensource.org/licenses/MIT)\n\nCopyright (c) 2013-2019 by Duktape authors (see AUTHORS.rst)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "react_juce/duktape/Makefile.cmdline",
    "content": "#\n#  Example Makefile for building a program with embedded Duktape.\n#  The example program here is the Duktape command line tool.\n#\n\nDUKTAPE_SOURCES = src/duktape.c\n\nCMDLINE_SOURCES = \\\n\texamples/cmdline/duk_cmdline.c\n\nCC = gcc\nCCOPTS = -Os -pedantic -std=c99 -Wall -fstrict-aliasing -fomit-frame-pointer\nCCOPTS += -I./examples/cmdline -I./src   # duktape.h and duk_config.h must be in include path\nCCLIBS = -lm\n\n# Enable print() and alert() for command line using an optional extra module.\nCCOPTS += -DDUK_CMDLINE_PRINTALERT_SUPPORT -I./extras/print-alert\nCMDLINE_SOURCES += extras/print-alert/duk_print_alert.c\n\n# Enable console object (console.log() etc) for command line.\nCCOPTS += -DDUK_CMDLINE_CONSOLE_SUPPORT -I./extras/console\nCMDLINE_SOURCES += extras/console/duk_console.c\n\n# Enable Duktape.Logger for command line.\nCCOPTS += -DDUK_CMDLINE_LOGGING_SUPPORT -I./extras/logging\nCMDLINE_SOURCES += extras/logging/duk_logging.c\n\n# Enable Duktape 1.x module loading for command line.\nCCOPTS += -DDUK_CMDLINE_MODULE_SUPPORT -I./extras/module-duktape\nCMDLINE_SOURCES += extras/module-duktape/duk_module_duktape.c\n\n# If you want linenoise, you can enable these.  At the moment linenoise\n# will cause some harmless compilation warnings.\n#CCOPTS += -DDUK_CMDLINE_FANCY -I./linenoise\n#CMDLINE_SOURCES += linenoise/linenoise.c\n#duk: linenoise\n\n# Use the tools/configure.py utility to modify Duktape default configuration:\n# http://duktape.org/guide.html#compiling\n# http://wiki.duktape.org/Configuring.html\n\nduk: $(DUKTAPE_SOURCES) $(CMDLINE_SOURCES)\n\t$(CC) -o $@ $(DEFINES) $(CCOPTS) $(DUKTAPE_SOURCES) $(CMDLINE_SOURCES) $(CCLIBS)\n\nlinenoise/linenoise.c: linenoise\nlinenoise:\n\tgit clone https://github.com/antirez/linenoise.git\n"
  },
  {
    "path": "react_juce/duktape/Makefile.codepage",
    "content": "CC = gcc\n\ncodepage:\n\t$(CC) -o $@ -std=c99 -O2 -Wall -Wextra -Isrc/ \\\n\t\tsrc/duktape.c examples/codepage-conv/duk_codepage_conv.c \\\n\t\texamples/codepage-conv/test.c -lm\n"
  },
  {
    "path": "react_juce/duktape/Makefile.coffee",
    "content": "dummy:\n\tcoffee -c examples/coffee/globals.coffee\n\tcoffee -c examples/coffee/hello.coffee\n\tcoffee -c examples/coffee/mandel.coffee\n"
  },
  {
    "path": "react_juce/duktape/Makefile.dukdebug",
    "content": "#\n#  Duktape command line tool with debugger support.\n#\n\nDUKTAPE_SOURCES = prep/duktape.c\n\n# Windows (MinGW): use examples/debug-trans-socket/duk_trans_socket_windows.c\n# and link with -lws2_32.\nCMDLINE_SOURCES = \\\n\texamples/cmdline/duk_cmdline.c \\\n\texamples/debug-trans-socket/duk_trans_socket_unix.c\n\nCC = gcc\nCCOPTS = -Os -pedantic -std=c99 -Wall -fstrict-aliasing -fomit-frame-pointer\nCCOPTS += -I./prep -I./examples/cmdline -I./examples/debug-trans-socket\nCCOPTS += -DDUK_CMDLINE_DEBUGGER_SUPPORT     # enable --debugger in ./duk\nCCLIBS = -lm\n\n# Enable a few optional modules.\nCCOPTS += -DDUK_CMDLINE_PRINTALERT_SUPPORT -I./extras/print-alert\nCMDLINE_SOURCES += extras/print-alert/duk_print_alert.c\nCCOPTS += -DDUK_CMDLINE_CONSOLE_SUPPORT -I./extras/console\nCMDLINE_SOURCES += extras/console/duk_console.c\nCCOPTS += -DDUK_CMDLINE_LOGGING_SUPPORT -I./extras/logging\nCMDLINE_SOURCES += extras/logging/duk_logging.c\nCCOPTS += -DDUK_CMDLINE_MODULE_SUPPORT -I./extras/module-duktape\nCMDLINE_SOURCES += extras/module-duktape/duk_module_duktape.c\n\n# Use tools/configure.py to prepare Duktape config header and sources with\n# custom configuration.\nduk: $(CMDLINE_SOURCES)\n\t@rm -rf prep\n\tpython2 tools/configure.py \\\n\t\t--source-directory src-input \\\n\t\t--output-directory prep \\\n\t\t--config-metadata config \\\n\t\t-DDUK_USE_DEBUGGER_SUPPORT \\\n\t\t-DDUK_USE_INTERRUPT_COUNTER \\\n\t\t-DDUK_USE_DEBUGGER_DUMPHEAP \\\n\t\t-DDUK_USE_DEBUGGER_INSPECT\n\t$(CC) -o $@ $(DEFINES) $(CCOPTS) $(DUKTAPE_SOURCES) $(CMDLINE_SOURCES) $(CCLIBS)\n"
  },
  {
    "path": "react_juce/duktape/Makefile.eval",
    "content": "#\n#  Example Makefile for building the eval example\n#\n\nCC = gcc\n\neval:\n\t$(CC) -o $@ -std=c99 -O2 -Wall -Wextra -Isrc/ \\\n\t\tsrc/duktape.c examples/eval/eval.c -lm\n"
  },
  {
    "path": "react_juce/duktape/Makefile.eventloop",
    "content": "#\n#  Example Makefile for building the eventloop example\n#\n\nCC = gcc\n\nevloop:\n\t@echo \"NOTE: The eventloop is an example intended to be used on Linux\"\n\t@echo \"      or other common UNIX variants.  It is not fully portable.\"\n\t@echo \"\"\n\n\t$(CC) -o $@ -std=c99 -Wall -Wextra -O2 -Isrc \\\n\t\texamples/eventloop/main.c \\\n\t\texamples/eventloop/c_eventloop.c \\\n\t\texamples/eventloop/poll.c \\\n\t\texamples/eventloop/socket.c \\\n\t\texamples/eventloop/fileio.c \\\n\t\tsrc/duktape.c \\\n\t\t-lm\n\n\t@echo \"\"\n\t@echo \"NOTE: You must 'cd examples/eventloop' before you execute the\"\n\t@echo \"      eventloop binary: it relies on finding .js files in CWD\"\n"
  },
  {
    "path": "react_juce/duktape/Makefile.hello",
    "content": "#\n#  Example Makefile for building a program with embedded Duktape.\n#\n#  There are two source sets in the distribution: (1) combined sources where\n#  you only need duktape.c, duktape.h, and duk_config.h, and (2) separate\n#  sources where you have a bunch of source and header files.  Whichever\n#  you use, simply include the relevant sources into your C project.  This\n#  Makefile uses the combined source file.\n#\n\nDUKTAPE_SOURCES = src/duktape.c\n\n# Compiler options are quite flexible.  GCC versions have a significant impact\n# on the size of -Os code, e.g. gcc-4.6 is much worse than gcc-4.5.\n\nCC = gcc\nCCOPTS = -Os -pedantic -std=c99 -Wall -fstrict-aliasing -fomit-frame-pointer\nCCOPTS += -I./src  # for combined sources\nCCLIBS = -lm\nDEFINES =\n\n# If you want a 32-bit build on a 64-bit host\n#CCOPTS += -m32\n\n# Use the tools/configure.py utility to modify Duktape default configuration:\n# http://duktape.org/guide.html#compiling\n# http://wiki.duktape.org/Configuring.html\n\n# For debugging, use -O0 -g -ggdb, and don't add -fomit-frame-pointer\n\nhello: $(DUKTAPE_SOURCES) examples/hello/hello.c\n\t$(CC) -o $@ $(DEFINES) $(CCOPTS) $(DUKTAPE_SOURCES) examples/hello/hello.c $(CCLIBS)\n"
  },
  {
    "path": "react_juce/duktape/Makefile.jsoncbor",
    "content": "#\n#  Example Makefile for building the jsoncbor example\n#\n\nCC = gcc\n\njsoncbor:\n\t$(CC) -o $@ -std=c99 -Wall -Wextra -O2 -Isrc -Iextras/cbor \\\n\t\tsrc/duktape.c extras/cbor/duk_cbor.c extras/cbor/jsoncbor.c \\\n\t\t-lm\n"
  },
  {
    "path": "react_juce/duktape/Makefile.jxpretty",
    "content": "#\n#  Example Makefile for building the jxpretty example\n#\n\nCC = gcc\n\njxpretty:\n\t$(CC) -o $@ -std=c99 -Wall -Wextra -O2 -Isrc \\\n\t\tsrc/duktape.c examples/jxpretty/jxpretty.c \\\n\t\t-lm\n"
  },
  {
    "path": "react_juce/duktape/Makefile.sandbox",
    "content": "#\n#  Example Makefile for building the sandbox example\n#\n\nCC = gcc\n\nsandbox:\n\t$(CC) -o $@ -std=c99 -O2 -Wall -Wextra -Isrc/ \\\n\t\tsrc/duktape.c examples/sandbox/sandbox.c -lm\n"
  },
  {
    "path": "react_juce/duktape/Makefile.sharedlibrary",
    "content": "#\n#  Example of how to build and install locally as a shared library\n#\n#  Usage:\n#\n#    $ make -f Makefile.sharedlibrary\n#    $ sudo make -f Makefile.sharedlibrary install\n#    $ make -f Makefile.sharedlibrary duk  # --> example 'duk' linked to shared libduktape\n#\n#    $ ls -l duk\n#    -rwxrwxr-x 1 duktape duktape 19407 Nov 30 15:48 duk\n#\n#    $ ldd ./duk\n#            linux-vdso.so.1 =>  (0x00007ffd5ed3c000)\n#            libduktape.so.104 => /usr/local/lib/libduktape.so.104 (0x00007fb2f9753000)\n#            libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb2f944d000)\n#            libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb2f9088000)\n#            /lib64/ld-linux-x86-64.so.2 (0x00007fb2f9991000)\n#\n#  Based on: http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html\n\n# Soname version must be bumped whenever a binary compatibility change occurs\n# (and should not be bumped when the library is compatible).  A simple Duktape\n# convention is to set soname version to (100*MAJOR + MINOR), e.g. 104 for\n# Duktape 1.4.x, so that it gets automatically bumped for major and minor\n# releases (potentially binary incompatible), but not for patch releases.\nDUK_VERSION = 20400\nSONAME_VERSION = 204\nREAL_VERSION = $(SONAME_VERSION).$(DUK_VERSION)\n\n# Mac has an unusual .so naming convention\nifeq ($(OS),Windows_NT)\n    DETECTED_OS := Windows\nelse\n    DETECTED_OS := $(shell uname -s)\nendif\nifeq ($(DETECTED_OS),Darwin)\n    LD_SONAME_ARG=-install_name\n    SO_SONAME_SUFFIX=$(SONAME_VERSION).so\n    SO_REALNAME_SUFFIX=$(REAL_VERSION).so\nelse\n    LD_SONAME_ARG=-soname\n    SO_SONAME_SUFFIX=so.$(SONAME_VERSION)\n    SO_REALNAME_SUFFIX=so.$(REAL_VERSION)\nendif\n\n# Change to actual path for actual distribution packaging.\nINSTALL_PREFIX = /usr/local\n\n# The 'noline' variant may be more appropriate for some distributions; it\n# doesn't have #line directives in the combined source.\nDUKTAPE_SRCDIR = ./src\n#DUKTAPE_SRCDIR = ./src-noline\n\nCC = gcc\n\n.PHONY: all\nall: libduktape.$(SO_REALNAME_SUFFIX) libduktaped.$(SO_REALNAME_SUFFIX)\n\n# If the default duk_config.h is not suitable for the distribution, modify it\n# before compiling the shared library and copy the same, edited duk_config.h\n# to $INSTALL_PREFIX/include on installation.\n\nlibduktape.$(SO_REALNAME_SUFFIX):\n\t$(CC) -shared -fPIC -Wall -Wextra -Os -Wl,$(LD_SONAME_ARG),libduktape.$(SO_SONAME_SUFFIX) \\\n\t\t-o $@ $(DUKTAPE_SRCDIR)/duktape.c\n\nlibduktaped.$(SO_REALNAME_SUFFIX):\n\t$(CC) -shared -fPIC -g -Wall -Wextra -Os -Wl,$(LD_SONAME_ARG),libduktaped.$(SO_SONAME_SUFFIX) \\\n\t\t-o $@ $(DUKTAPE_SRCDIR)/duktape.c\n\n# Symlinks depend on platform conventions.\n.PHONY: install\ninstall: libduktape.$(SO_REALNAME_SUFFIX) libduktaped.$(SO_REALNAME_SUFFIX)\n\tmkdir -p $(INSTALL_PREFIX)/lib/\n\tcp $+ $(INSTALL_PREFIX)/lib/\n\trm -f $(INSTALL_PREFIX)/lib/libduktape.so $(INSTALL_PREFIX)/lib/libduktape.$(SO_SONAME_SUFFIX)\n\tln -s libduktape.$(SO_REALNAME_SUFFIX) $(INSTALL_PREFIX)/lib/libduktape.so\n\tln -s libduktape.$(SO_REALNAME_SUFFIX) $(INSTALL_PREFIX)/lib/libduktape.$(SO_SONAME_SUFFIX)\n\trm -f $(INSTALL_PREFIX)/lib/libduktaped.so $(INSTALL_PREFIX)/lib/libduktaped.$(SO_SONAME_SUFFIX)\n\tln -s libduktaped.$(SO_REALNAME_SUFFIX) $(INSTALL_PREFIX)/lib/libduktaped.so\n\tln -s libduktaped.$(SO_REALNAME_SUFFIX) $(INSTALL_PREFIX)/lib/libduktaped.$(SO_SONAME_SUFFIX)\n\tmkdir -p $(INSTALL_PREFIX)/include/\n\tcp $(DUKTAPE_SRCDIR)/duktape.h $(DUKTAPE_SRCDIR)/duk_config.h $(INSTALL_PREFIX)/include/\n\nCCOPTS = -I./examples/cmdline\nduk:\n\t$(CC) $(CCOPTS) -I$(INSTALL_PREFIX)/include -L$(INSTALL_PREFIX)/lib -Wall -Wextra -Os -o $@ ./examples/cmdline/duk_cmdline.c -lduktape -lm\n"
  },
  {
    "path": "react_juce/duktape/README.rst",
    "content": "=======\nDuktape\n=======\n\nDuktape is a small and portable ECMAScript E5/E5.1 implementation.  It is\nintended to be easily embeddable into C programs, with a C API similar in\nspirit to Lua's.\n\nDuktape supports the full E5/E5.1 feature set (with some semantics updated\nfrom ES2015+) including errors, Unicode strings, and regular expressions,\na subset of ECMAScript 2015 (E6) and ECMAScript 2016 (E7) features (e.g.\ncomputed property names, Proxy objects, exponentiation operator, Reflect),\nES2015 ArrayBuffer/TypedView, Node.js Buffer, performance.now(), and WHATWG\nEncoding API living standard.\n\nDuktape also provides a number of custom features such as error tracebacks,\nadditional data types for better C integration, combined reference counting\nand mark-and sweep garbage collector, object finalizers, co-operative\nthreads a.k.a. coroutines, tail calls, a built-in debugger protocol, function\nbytecode dump/load, and so on.  Bundled extra modules provide functionality\nsuch as CommonJS module loading and a logging framework.\n\nYou can browse Duktape programmer's API and other documentation at:\n\n* http://duktape.org/\n\nIn particular, you should read the getting started section:\n\n* http://duktape.org/guide.html#gettingstarted\n\nMore examples and how-to articles are in the Duktape Wiki:\n\n* http://wiki.duktape.org/\n\nTo build an example command line tool with interactive evaluation (REPL) and\nthe ability to run script files::\n\n  $ cd <dist_root>\n  $ make -f Makefile.cmdline\n  [...]\n\n  $ ./duk\n  ((o) Duktape\n  duk> print('Hello world!');\n  Hello world!\n  = undefined\n\n  $ ./duk mandel.js\n  [...]\n\nTo integrate Duktape into your program:\n\n* Use ``tools/configure.py`` to prepare Duktape source and header files\n  for build::\n\n      # Duktape options can be customized via command line options.\n      # In this example, enable \"fastint\" support and disable ES2015\n      # Proxy support\n\n      $ python2 tools/configure.py --output-directory duktape-src \\\n            -DDUK_USE_FASTINT -UDUK_USE_ES6_PROXY\n\n* The output directory (duktape-src) will then contain ``duktape.c``,\n  ``duktape.h``, and ``duk_config.h`` which you include in your build.\n\nFor more details, see:\n\n* http://duktape.org/guide.html#compiling\n\n* http://wiki.duktape.org/Configuring.html\n\nThis distributable contains:\n\n* Pre-configured Duktape header and source files using the Duktape default\n  configuration:\n\n  * ``src/``: main Duktape library in a \"single source file\" format (duktape.c,\n    duktape.h, and duk_config.h).\n\n  * ``src-noline/``: contains a variant of ``src/duktape.c`` with no ``#line``\n    directives which is preferable for some users.  See discussion in\n    https://github.com/svaarala/duktape/pull/363.\n\n  * ``src-separate/``: main Duktape library in multiple files format.\n\n* ``src-input/``: raw input source files used by ``configure.py`` which\n  recreates the combined/separate prepared sources with specific options.\n\n* ``tools/``: various Python tools, such as ``configure.py`` for preparing\n  a ``duk_config.h`` header and Duktape source files for compilation, see\n  http://wiki.duktape.org/Configuring.html.\n\n* ``config/``: configuration metadata for ``configure.py``.\n\n* ``examples/``: further examples for using Duktape.  Although Duktape\n  itself is widely portable, some of the examples are Linux only.\n  For instance the ``eventloop`` example illustrates how ``setTimeout()``\n  and other standard timer functions could be implemented on Unix/Linux.\n\n* ``extras/``: utilities and modules which don't comfortably fit into the\n  main Duktape library because of footprint or portability concerns.\n  Extras are maintained and bug fixed code, but don't have the same version\n  guarantees as the main Duktape library.\n\n* ``polyfills/``: a few replacement suggestions for non-standard Javascript\n  functions provided by other implementations.\n\n* ``debugger/``: a debugger with a web UI, see ``debugger/README.rst`` and\n  https://github.com/svaarala/duktape/blob/master/doc/debugger.rst for\n  details on Duktape debugger support.  Also contains a JSON debug proxy\n  (one written in Node.js and another in DukLuv) to make talking to the\n  debug target easier.\n\n* ``licenses/``: licensing information.\n\nYou can find release notes at:\n\n* https://github.com/svaarala/duktape/blob/master/RELEASES.rst\n  (summary of all versions)\n\n* https://github.com/svaarala/duktape/blob/master/doc/release-notes-v2-4.rst\n  (more detailed notes for this version)\n\nThis distributable contains Duktape version 2.4.0, created from git\ncommit d4f2cff1c592d70f58bab8e1bd85705174c02a58 (v2.4.0).\n\nDuktape is copyrighted by its authors (see ``AUTHORS.rst``) and licensed\nunder the MIT license (see ``LICENSE.txt``).  String hashing algorithms are\nbased on the algorithm from Lua (MIT license), djb2 hash, and Murmurhash2\n(MIT license).  Pseudorandom number generator algorithms are based on\nAdi Shamir's three-op algorithm, xoroshiro128+ (public domain), and SplitMix64\n(public domain).  Duktape module loader is based on the CommonJS module\nloading specification (without sharing any code), CommonJS is under the MIT\nlicense.\n\nHave fun!\n\nSami Vaarala (sami.vaarala@iki.fi)\n"
  },
  {
    "path": "react_juce/duktape/config/README.rst",
    "content": "=================\nDuktape genconfig\n=================\n\n``genconfig`` is a helper script for coming up with a ``duk_config.h`` for\ncompiling Duktape for your platform.\n\nTo support this:\n\n* It helps to create a ``duk_config.h`` for your platform/compiler\n  combination.  You can give a base configuration and then force certain\n  values manually based on a YAML configuration file.\n\n* It autogenerates documentation for config options based on option metadata\n  files written in YAML.\n\nNOTE: ``tools/configure.py`` is now the preferred tool for preparing a config\nheader (using genconfig.py) and Duktape source files (using other tools) for\nbuild.\n"
  },
  {
    "path": "react_juce/duktape/config/architectures/architecture_arm32.h.in",
    "content": "#define DUK_USE_ARCH_STRING \"arm32\"\n/* Byte order varies, so rely on autodetect. */\n#define DUK_USE_PACKED_TVAL\n"
  },
  {
    "path": "react_juce/duktape/config/architectures/architecture_arm64.h.in",
    "content": "#define DUK_USE_ARCH_STRING \"arm64\"\n/* Byte order varies, so rely on autodetect. */\n#undef DUK_USE_PACKED_TVAL\n"
  },
  {
    "path": "react_juce/duktape/config/architectures/architecture_emscripten.h.in",
    "content": "#define DUK_USE_ARCH_STRING \"emscripten\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#undef DUK_USE_PACKED_TVAL\n"
  },
  {
    "path": "react_juce/duktape/config/architectures/architecture_generic.h.in",
    "content": "/* These are necessary wild guesses. */\n#define DUK_USE_ARCH_STRING \"generic\"\n/* Rely on autodetection for byte order, alignment, and packed tval. */\n"
  },
  {
    "path": "react_juce/duktape/config/architectures/architecture_m68k.h.in",
    "content": "#define DUK_USE_ARCH_STRING \"m68k\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_PACKED_TVAL\n"
  },
  {
    "path": "react_juce/duktape/config/architectures/architecture_mips32.h.in",
    "content": "#define DUK_USE_ARCH_STRING \"mips32\"\n/* MIPS byte order varies so rely on autodetection. */\n#define DUK_USE_PACKED_TVAL\n"
  },
  {
    "path": "react_juce/duktape/config/architectures/architecture_mips64.h.in",
    "content": "#define DUK_USE_ARCH_STRING \"mips64\"\n/* MIPS byte order varies so rely on autodetection. */\n#undef DUK_USE_PACKED_TVAL\n"
  },
  {
    "path": "react_juce/duktape/config/architectures/architecture_powerpc32.h.in",
    "content": "#define DUK_USE_ARCH_STRING \"ppc32\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_PACKED_TVAL\n"
  },
  {
    "path": "react_juce/duktape/config/architectures/architecture_powerpc64.h.in",
    "content": "#define DUK_USE_ARCH_STRING \"ppc64\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#undef DUK_USE_PACKED_TVAL\n"
  },
  {
    "path": "react_juce/duktape/config/architectures/architecture_sparc32.h.in",
    "content": "#define DUK_USE_ARCH_STRING \"sparc32\"\n/* SPARC byte order varies so rely on autodetection. */\n#define DUK_USE_PACKED_TVAL\n"
  },
  {
    "path": "react_juce/duktape/config/architectures/architecture_sparc64.h.in",
    "content": "#define DUK_USE_ARCH_STRING \"sparc64\"\n/* SPARC byte order varies so rely on autodetection. */\n#undef DUK_USE_PACKED_TVAL\n"
  },
  {
    "path": "react_juce/duktape/config/architectures/architecture_superh.h.in",
    "content": "#define DUK_USE_ARCH_STRING \"sh\"\n/* Byte order varies, rely on autodetection. */\n#define DUK_USE_PACKED_TVAL\n"
  },
  {
    "path": "react_juce/duktape/config/architectures/architecture_x32.h.in",
    "content": "#define DUK_USE_ARCH_STRING \"x32\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#define DUK_USE_PACKED_TVAL\n"
  },
  {
    "path": "react_juce/duktape/config/architectures/architecture_x64.h.in",
    "content": "#define DUK_USE_ARCH_STRING \"x64\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#undef DUK_USE_PACKED_TVAL\n"
  },
  {
    "path": "react_juce/duktape/config/architectures/architecture_x86.h.in",
    "content": "#define DUK_USE_ARCH_STRING \"x86\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n\n#define DUK_USE_PACKED_TVAL\n\n/* FreeBSD, -m32, and clang prior to 5.0 has union aliasing issues which\n * break duk_tval copying.  Disable packed duk_tval automatically.\n */\n#if defined(DUK_F_FREEBSD) && defined(DUK_F_X86) && \\\n    defined(__clang__) && defined(__clang_major__) && (__clang_major__ < 5)\n#undef DUK_USE_PACKED_TVAL\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/architectures.yaml",
    "content": "# Architecture metadata.\n\nautodetect:\n  -\n    name: x86\n    check: DUK_F_X86\n    include: architecture_x86.h.in\n  -\n    name: x64\n    check: DUK_F_X64\n    include: architecture_x64.h.in\n  -\n    name: x32\n    check: DUK_F_X32\n    include: architecture_x32.h.in\n  -\n    name: ARM 32-bit\n    check: DUK_F_ARM32\n    include: architecture_arm32.h.in\n  -\n    name: ARM 64-bit\n    check: DUK_F_ARM64\n    include: architecture_arm64.h.in\n  -\n    name: MIPS 32-bit\n    check: DUK_F_MIPS32\n    include: architecture_mips32.h.in\n  -\n    name: MIPS 64-bit\n    check: DUK_F_MIPS64\n    include: architecture_mips64.h.in\n  -\n    name: PowerPC 32-bit\n    check: DUK_F_PPC32\n    include: architecture_powerpc32.h.in\n  -\n    name: PowerPC 64-bit\n    check: DUK_F_PPC64\n    include: architecture_powerpc64.h.in\n  -\n    name: SPARC 32-bit\n    check: DUK_F_SPARC32\n    include: architecture_sparc32.h.in\n  -\n    name: SPARC 64-bit\n    check: DUK_F_SPARC64\n    include: architecture_sparc64.h.in\n  -\n    name: SuperH\n    check: DUK_F_SUPERH\n    include: architecture_superh.h.in\n  -\n    name: Motorola 68k\n    check: DUK_F_M68K\n    include: architecture_m68k.h.in\n  -\n    name: Emscripten\n    check: DUK_F_EMSCRIPTEN\n    include: architecture_emscripten.h.in\n  -\n    name: Generic\n    check: null\n    include: architecture_generic.h.in\n"
  },
  {
    "path": "react_juce/duktape/config/compilers/compiler_bcc.h.in",
    "content": "#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"bcc++\"\n#else\n#define DUK_USE_COMPILER_STRING \"bcc\"\n#endif\n\n/* Most portable */\n#undef DUK_USE_VARIADIC_MACROS\n\n/* Most portable, wastes space */\n#undef DUK_USE_UNION_INITIALIZERS\n\n/* Most portable, wastes space */\n#define DUK_USE_FLEX_ONESIZE\n\n/* Most portable, potentially wastes space */\n#define DUK_USE_PACK_DUMMY_MEMBER\n\n/* BCC, assume we're on x86. */\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/compilers/compiler_clang.h.in",
    "content": "#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n/* C99 / C++11 and above: rely on va_copy() which is required. */\n#define DUK_VA_COPY(dest,src) va_copy(dest,src)\n#else\n/* Clang: assume we have __va_copy() in non-C99 mode. */\n#define DUK_VA_COPY(dest,src) __va_copy(dest,src)\n#endif\n\n#define DUK_NORETURN(decl)  decl __attribute__((noreturn))\n\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unreachable)\n#define DUK_UNREACHABLE()  do { __builtin_unreachable(); } while (0)\n#endif\n#endif\n\n#define DUK_USE_BRANCH_HINTS\n#define DUK_LIKELY(x)    __builtin_expect((x), 1)\n#define DUK_UNLIKELY(x)  __builtin_expect((x), 0)\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unpredictable)\n#define DUK_UNPREDICTABLE(x)  __builtin_unpredictable((x))\n#endif\n#endif\n\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_NOINLINE        __attribute__((noinline))\n#define DUK_INLINE          inline\n#define DUK_ALWAYS_INLINE   inline __attribute__((always_inline))\n#endif\n\n/* DUK_HOT */\n/* DUK_COLD */\n\n#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS)\n#snippet \"msvc_visibility.h.in\"\n#else\n#snippet \"gcc_clang_visibility.h.in\"\n#endif\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"clang\"\n#else\n#define DUK_USE_COMPILER_STRING \"clang\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#define DUK_USE_UNION_INITIALIZERS\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#undef DUK_USE_GCC_PRAGMAS\n#define DUK_USE_PACK_CLANG_ATTR\n\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_bswap64)\n#define DUK_BSWAP64(x) ((duk_uint64_t) __builtin_bswap64((duk_uint64_t) (x)))\n#endif\n#if __has_builtin(__builtin_bswap32)\n#define DUK_BSWAP32(x) ((duk_uint32_t) __builtin_bswap32((duk_uint32_t) (x)))\n#endif\n#if __has_builtin(__builtin_bswap16)\n#define DUK_BSWAP16(x) ((duk_uint16_t) __builtin_bswap16((duk_uint16_t) (x)))\n#endif\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/compilers/compiler_emscripten.h.in",
    "content": "#define DUK_NORETURN(decl)  decl __attribute__((noreturn))\n\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unreachable)\n#define DUK_UNREACHABLE()  do { __builtin_unreachable(); } while (0)\n#endif\n#endif\n\n#define DUK_USE_BRANCH_HINTS\n#define DUK_LIKELY(x)    __builtin_expect((x), 1)\n#define DUK_UNLIKELY(x)  __builtin_expect((x), 0)\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unpredictable)\n#define DUK_UNPREDICTABLE(x)  __builtin_unpredictable((x))\n#endif\n#endif\n\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_NOINLINE        __attribute__((noinline))\n#define DUK_INLINE          inline\n#define DUK_ALWAYS_INLINE   inline __attribute__((always_inline))\n#endif\n\n#snippet \"gcc_clang_visibility.h.in\"\n\n#define DUK_USE_COMPILER_STRING \"emscripten\"\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#define DUK_USE_UNION_INITIALIZERS\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#undef DUK_USE_GCC_PRAGMAS\n#define DUK_USE_PACK_CLANG_ATTR\n"
  },
  {
    "path": "react_juce/duktape/config/compilers/compiler_gcc.h.in",
    "content": "#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n/* C99 / C++11 and above: rely on va_copy() which is required. */\n#define DUK_VA_COPY(dest,src) va_copy(dest,src)\n#else\n/* GCC: assume we have __va_copy() in non-C99 mode. */\n#define DUK_VA_COPY(dest,src) __va_copy(dest,src)\n#endif\n\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 20500L) && (DUK_F_GCC_VERSION < 50000L)\n/* Since gcc-2.5.\n *\n * Disabled temporarily in GCC 5+ because of an unresolved noreturn-related\n * issue: https://github.com/svaarala/duktape/issues/2155.\n */\n#define DUK_NORETURN(decl)  decl __attribute__((noreturn))\n#endif\n\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L)\n/* Since gcc-4.5. */\n#define DUK_UNREACHABLE()  do { __builtin_unreachable(); } while (0)\n#endif\n\n#define DUK_USE_BRANCH_HINTS\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L)\n/* GCC: test not very accurate; enable only in relatively recent builds\n * because of bugs in gcc-4.4 (http://lists.debian.org/debian-gcc/2010/04/msg00000.html)\n */\n#define DUK_LIKELY(x)    __builtin_expect((x), 1)\n#define DUK_UNLIKELY(x)  __builtin_expect((x), 0)\n#endif\n/* XXX: equivalent of clang __builtin_unpredictable? */\n\n#if (defined(DUK_F_C99) || defined(DUK_F_CPP11)) && \\\n    defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 30101)\n#define DUK_NOINLINE        __attribute__((noinline))\n#define DUK_INLINE          inline\n#define DUK_ALWAYS_INLINE   inline __attribute__((always_inline))\n#endif\n\n#if (defined(DUK_F_C99) || defined(DUK_F_CPP11)) && \\\n    defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40300)\n#define DUK_HOT             __attribute__((hot))\n#define DUK_COLD            __attribute__((cold))\n#endif\n\n#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS)\n#snippet \"msvc_visibility.h.in\"\n#elif defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40000)\n#snippet \"gcc_clang_visibility.h.in\"\n#endif\n\n#if defined(DUK_F_MINGW)\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"mingw++\"\n#else\n#define DUK_USE_COMPILER_STRING \"mingw\"\n#endif\n#else\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"g++\"\n#else\n#define DUK_USE_COMPILER_STRING \"gcc\"\n#endif\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || (defined(DUK_F_CPP11) && defined(__GNUC__))\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#define DUK_USE_UNION_INITIALIZERS\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40600)\n#define DUK_USE_GCC_PRAGMAS\n#else\n#undef DUK_USE_GCC_PRAGMAS\n#endif\n\n#define DUK_USE_PACK_GCC_ATTR\n\n/* Availability varies based on platform (between GCC 4.4 and 4.8), and there\n * are apparently some bugs in GCC 4.x.  Check for GCC 5.0 before enabling\n * these to be safe.\n */\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 50000L)\n#define DUK_BSWAP64(x) ((duk_uint64_t) __builtin_bswap64((duk_uint64_t) (x)))\n#define DUK_BSWAP32(x) ((duk_uint32_t) __builtin_bswap32((duk_uint32_t) (x)))\n#define DUK_BSWAP16(x) ((duk_uint16_t) __builtin_bswap16((duk_uint16_t) (x)))\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/compilers/compiler_generic.h.in",
    "content": "#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"generic-c++\"\n#else\n#define DUK_USE_COMPILER_STRING \"generic\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n/* C++ doesn't have standard designated union initializers ({ .foo = 1 }). */\n#undef DUK_USE_UNION_INITIALIZERS\n#if defined(DUK_F_C99)\n#define DUK_USE_UNION_INITIALIZERS\n#endif\n\n/* Most portable, wastes space */\n#define DUK_USE_FLEX_ONESIZE\n\n/* Most portable, potentially wastes space */\n#define DUK_USE_PACK_DUMMY_MEMBER\n"
  },
  {
    "path": "react_juce/duktape/config/compilers/compiler_msvc.h.in",
    "content": "/* http://msdn.microsoft.com/en-us/library/aa235362(VS.60).aspx */\n#define DUK_NORETURN(decl)  __declspec(noreturn) decl\n\n/* XXX: DUK_UNREACHABLE for msvc? */\n\n#undef DUK_USE_BRANCH_HINTS\n\n/* XXX: DUK_LIKELY, DUK_UNLIKELY for msvc? */\n/* XXX: DUK_NOINLINE, DUK_INLINE, DUK_ALWAYS_INLINE for msvc? */\n\n#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS)\n#snippet \"msvc_visibility.h.in\"\n#endif\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"msvc++\"\n#else\n#define DUK_USE_COMPILER_STRING \"msvc\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99)\n#define DUK_USE_VARIADIC_MACROS\n#elif defined(_MSC_VER) && (_MSC_VER >= 1400)\n/* VS2005+ should have variadic macros even when they're not C99. */\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#undef DUK_USE_UNION_INITIALIZERS\n#if defined(_MSC_VER) && (_MSC_VER >= 1800)\n/* VS2013+ supports union initializers but there's a bug involving union-inside-struct:\n * https://connect.microsoft.com/VisualStudio/feedback/details/805981\n * The bug was fixed (at least) in VS2015 so check for VS2015 for now:\n * https://blogs.msdn.microsoft.com/vcblog/2015/07/01/c-compiler-front-end-fixes-in-vs2015/\n * Manually tested using VS2013, CL reports 18.00.31101, so enable for VS2013 too.\n */\n#define DUK_USE_UNION_INITIALIZERS\n#endif\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#undef DUK_USE_GCC_PRAGMAS\n\n#define DUK_USE_PACK_MSVC_PRAGMA\n\n/* These have been tested from VS2008 onwards; may work in older VS versions\n * too but not enabled by default.\n */\n#if defined(_MSC_VER) && (_MSC_VER >= 1500)\n#define DUK_NOINLINE        __declspec(noinline)\n#define DUK_INLINE          __inline\n#define DUK_ALWAYS_INLINE   __forceinline\n#endif\n\n#if defined(_MSC_VER) && (_MSC_VER >= 1900)\n#define DUK_SNPRINTF     snprintf\n#define DUK_VSNPRINTF    vsnprintf\n#else\n/* (v)snprintf() is missing before MSVC 2015.  Note that _(v)snprintf() does\n * NOT NUL terminate on truncation, but Duktape code never assumes that.\n * http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010\n */\n#define DUK_SNPRINTF     _snprintf\n#define DUK_VSNPRINTF    _vsnprintf\n#endif\n\n/* Avoid warning when doing DUK_UNREF(some_function). */\n#if defined(_MSC_VER) && (_MSC_VER < 1500)\n#pragma warning(disable: 4100 4101 4550 4551)\n#define DUK_UNREF(x)\n#else\n#define DUK_UNREF(x)  do { __pragma(warning(suppress:4100 4101 4550 4551)) (x); } while (0)\n#endif\n\n/* Older versions of MSVC don't support the LL/ULL suffix. */\n#define DUK_U64_CONSTANT(x) x##ui64\n#define DUK_I64_CONSTANT(x) x##i64\n"
  },
  {
    "path": "react_juce/duktape/config/compilers/compiler_tinyc.h.in",
    "content": "#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"tinyc++\"\n#else\n#define DUK_USE_COMPILER_STRING \"tinyc\"\n#endif\n\n/* http://bellard.org/tcc/tcc-doc.html#SEC7 */\n#define DUK_USE_VARIADIC_MACROS\n\n#define DUK_USE_UNION_INITIALIZERS\n\n/* Most portable, wastes space */\n#define DUK_USE_FLEX_ONESIZE\n\n/* Most portable, potentially wastes space */\n#define DUK_USE_PACK_DUMMY_MEMBER\n"
  },
  {
    "path": "react_juce/duktape/config/compilers/compiler_vbcc.h.in",
    "content": "#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"vbcc-c++\"\n#else\n#define DUK_USE_COMPILER_STRING \"vbcc\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n/* VBCC supports C99 so check only for C99 for union initializer support.\n * Designated union initializers would possibly work even without a C99 check.\n */\n#undef DUK_USE_UNION_INITIALIZERS\n#if defined(DUK_F_C99)\n#define DUK_USE_UNION_INITIALIZERS\n#endif\n\n#define DUK_USE_FLEX_ZEROSIZE\n#define DUK_USE_PACK_DUMMY_MEMBER\n"
  },
  {
    "path": "react_juce/duktape/config/compilers.yaml",
    "content": "# Compiler metadata.\n\nautodetect:\n  -\n    name: Clang\n    check: DUK_F_CLANG\n    include: compiler_clang.h.in\n  -\n    name: GCC\n    check: DUK_F_GCC\n    include: compiler_gcc.h.in\n  -\n    name: MSVC\n    check: DUK_F_MSVC\n    include: compiler_msvc.h.in\n  -\n    name: Emscripten\n    check: DUK_F_EMSCRIPTEN\n    include: compiler_emscripten.h.in\n  -\n    name: TinyC\n    check: DUK_F_TINYC\n    include: compiler_tinyc.h.in\n  -\n    name: VBCC\n    check: DUK_F_VBCC\n    include: compiler_vbcc.h.in\n  -\n    name: Bruce's C compiler\n    check: DUK_F_BCC\n    include: compiler_bcc.h.in\n  -\n    name: Generic\n    check: null\n    include: compiler_generic.h.in\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_32BIT_PTRS.yaml",
    "content": "define: DUK_USE_32BIT_PTRS\nintroduced: 1.0.0\nremoved: 1.4.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Pointers are 32-bit integer compatible.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_64BIT_OPS.yaml",
    "content": "define: DUK_USE_64BIT_OPS\nintroduced: 1.0.0\ndefault: true\ntags:\n  - portability\ndescription: >\n  Use 64-bit integer operations.  On some platforms 64-bit types may be\n  available but 64-bit operations don't work correctly e.g. in integer/float\n  casts.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ALIGN_4.yaml",
    "content": "define: DUK_USE_ALIGN_4\nintroduced: 1.0.0\nremoved: 1.3.0\nrelated:\n  - DUK_USE_ALIGN_BY\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use 4-byte alignment for 64-bit integers and IEEE doubles.\n  Replaced by DUK_USE_ALIGN_BY.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ALIGN_8.yaml",
    "content": "define: DUK_USE_ALIGN_8\nintroduced: 1.0.0\nremoved: 1.3.0\nrelated:\n  - DUK_USE_ALIGN_BY\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use 8-byte alignment for 64-bit integers and IEEE doubles.\n  Replaced by DUK_USE_ALIGN_BY.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ALIGN_BY.yaml",
    "content": "define: DUK_USE_ALIGN_BY\nintroduced: 1.3.0\ndefault: 8\ntags:\n  - portability\ndescription: >\n  Use N-byte alignment for 64-bit integers and IEEE doubles\n  (supported values are 1, 4, and 8).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ALLOW_UNDEFINED_BEHAVIOR.yaml",
    "content": "define: DUK_USE_ALLOW_UNDEFINED_BEHAVIOR\nintroduced: 2.3.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Allow technically undefined behavior such as out-of-range double-to-integer\n  casts, floating point division by zero, etc. which are likely to work on the\n  majority of platforms.  Default is to avoid such behaviors, at the cost of\n  some footprint and performance.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ARCH_STRING.yaml",
    "content": "define: DUK_USE_ARCH_STRING\nintroduced: 1.0.0\ndefault:\n  string: \"unknown\"\ntags:\n  - portability\ndescription: >\n  Human-readable architecture string used in e.g. Duktape.env and debugger\n  protocol (example: x64).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ARRAY_BUILTIN.yaml",
    "content": "define: DUK_USE_ARRAY_BUILTIN\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Provide an Array built-in.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ARRAY_FASTPATH.yaml",
    "content": "define: DUK_USE_ARRAY_FASTPATH\nintroduced: 2.0.0\ndefault: true\ntags:\n  - performance\n  - fastpath\n  - lowmemory\n  - compliance\ndescription: >\n  Enable fast path for Array.prototype operations like push(), pop(), etc.\n  The fast path handles dense Array instances which are more common than\n  sparse arrays or non-array objects (which Array.prototype operations must\n  also support).  The fast path assumes that Array.prototype doesn't contain\n  inherited index properties; such properties are very rarely used in\n  practical code.  If compliance is critical, disable the fast path.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ARRAY_PROP_FASTPATH.yaml",
    "content": "define: DUK_USE_ARRAY_PROP_FASTPATH\nintroduced: 2.0.0\ndefault: true\ntags:\n  - performance\n  - fastpath\n  - lowmemory\n  - compliance\ndescription: >\n  Enable a shallow fast path check for Array index property reads and writes.\n  The fast path assumes Array.prototype doesn't have numeric index properties\n  which would be inherited and affect read/write behavior.  This behavior is\n  non-compliant (but practical because such inherited properties are very\n  rare).  Disable this option to ensure strict compliance.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ASSERTIONS.yaml",
    "content": "define: DUK_USE_ASSERTIONS\nintroduced: 1.0.0\ndefault: false\ntags:\n  - development\n  - debug\ndescription: >\n  Enable internal assert checks.  These slow down execution considerably\n  so only use when debugging.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ATAN2_WORKAROUNDS.yaml",
    "content": "define: DUK_USE_ATAN2_WORKAROUNDS\nintroduced: 2.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Enable workarounds to common atan2() semantics issues.  At least Cygwin/MinGW\n  has such issues, see test-bug-mingw-math-issues.js.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_AUGMENT_ERROR_CREATE.yaml",
    "content": "define: DUK_USE_AUGMENT_ERROR_CREATE\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Augment an ECMAScript error object at creation with tracedata or\n  fileName/lineNumber, or Duktape.errCreate (if enabled).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_AUGMENT_ERROR_THROW.yaml",
    "content": "define: DUK_USE_AUGMENT_ERROR_THROW\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Augment an ECMAScript error object at throw time with Duktape.errThrow\n  (if enabled).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_AVOID_PLATFORM_FUNCPTRS.yaml",
    "content": "define: DUK_USE_AVOID_PLATFORM_FUNCPTRS\nintroduced: 1.0.0\ndefault: true\ntags:\n  - portability\ndescription: >\n  Don't assume that platform functions (e.g. math functions) are actual\n  functions.  This option is needed if platform functions may be defined\n  as macros.  This is certainly the case with some platform \"polyfills\"\n  which provide missing C99/C++11 functions through macros, and may be\n  the case with VS2013 (see GH-17).\n\n  This is now the default: the cost in footprint is negligible.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_BASE64_FASTPATH.yaml",
    "content": "define: DUK_USE_BASE64_FASTPATH\nintroduced: 1.4.0\ndefault: true\ntags:\n  - performance\n  - fastpath\n  - lowmemory\ndescription: >\n  Enable fast path for base64 encode/decode.  The fast path uses a lookup\n  table at a small cost in footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_BASE64_SUPPORT.yaml",
    "content": "define: DUK_USE_BASE64_SUPPORT\nintroduced: 2.3.0\ndefault: true\ntags:\n  - codec\ndescription: >\n  Enable base64 encoding/decoding support.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_BOOLEAN_BUILTIN.yaml",
    "content": "define: DUK_USE_BOOLEAN_BUILTIN\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Provide a Boolean built-in.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_BRANCH_HINTS.yaml",
    "content": "define: DUK_USE_BRANCH_HINTS\nintroduced: 1.0.0\ndefault: true\ntags:\n  - portability\ndescription: >\n  Use branch hints if the compiler supports them.\n\n# XXX: Unused now, DUK_LIKELY and DUK_UNLIKELY are used instead.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_BROWSER_LIKE.yaml",
    "content": "define: DUK_USE_BROWSER_LIKE\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Provide browser-like bindings: currently print() and alert().\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_BUFFEROBJECT_SUPPORT.yaml",
    "content": "define: DUK_USE_BUFFEROBJECT_SUPPORT\nintroduced: 1.3.0\ndefault: true\ntags:\n  - ecmascript2015\ndescription: >\n  Enable support for Khronos/ES6 typed arrays and Node.js Buffer objects.\n\n  When disabled, Duktape custom plain buffer type is present and functional\n  in the C API.  Plain buffers have virtual properties and you can read/write\n  buffer contents in ECMAScript code.  Plain buffers will still inherit from\n  ArrayBuffer.prototype, but none of the ECMAScript buffer related bindings\n  will work.  This includes all ArrayBuffer, typed array, and Node.js Buffer\n  methods.  Native bindings which produce plain buffer results (like\n  Duktape.dec()) will still work.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_BUFLEN16.yaml",
    "content": "define: DUK_USE_BUFLEN16\nintroduced: 1.1.0\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use a 16-bit buffer length field (for low memory environments).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_BUILTIN_INITJS.yaml",
    "content": "define: DUK_USE_BUILTIN_INITJS\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Use built-in .js init code when creating a new global context.\n  The .js init code (duk_initjs.js) provides some initialization\n  code that's nicer to implement in ECMAScript, and is also used\n  to provide some backwards compatibility bindings which are easy\n  to remove later.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_BYTECODE_DUMP_SUPPORT.yaml",
    "content": "define: DUK_USE_BYTECODE_DUMP_SUPPORT\nintroduced: 1.3.0\ndefault: true\ntags:\n  - api\ndescription: >\n  Enable support for API calls to dump/load function bytecode.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_BYTEORDER.yaml",
    "content": "define: DUK_USE_BYTEORDER\nintroduced: 1.4.0\ndefault: 0  # no reasonable automatic default\ntags:\n  - portability\ndescription: >\n  Byte order for platform: 1 = little endian, 2 = mixed (arm hybrid) endian,\n  3 = big endian.\n\n  ARM mixed endian means integers are little endian but IEEE doubles have\n  mixed endianness: big endian bytes 12345678 are ordered in memory as\n  43218765.\n\n  (This define should be produced by duk_config.h; currently Duktape internals\n  use automatically derived defines DUK_USE_{INTEGER,DOUBLE}_{LE,BE_ME}\n  instead of using this define directly.)\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_BYTEORDER_FORCED.yaml",
    "content": "define: DUK_USE_BYTEORDER_FORCED\nintroduced: 1.0.0\nremoved: 1.4.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Byte order was forced (instead of being autodetected).  This has no\n  functional impact but the forced status shows up in Duktape.env.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_CACHE_ACTIVATION.yaml",
    "content": "define: DUK_USE_CACHE_ACTIVATION\nintroduced: 2.2.0\ndefault: true\ntags:\n  - performance\ndescription: >\n  Cache duk_activation records.  When releasing a duk_activation, place it in\n  a free list for later reuse.  Mark-and-sweep frees the free list to keep\n  memory usage in check.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_CACHE_CATCHER.yaml",
    "content": "define: DUK_USE_CACHE_CATCHER\nintroduced: 2.2.0\ndefault: true\ntags:\n  - performance\ndescription: >\n  Cache duk_catcher records.  When releasing a duk_catcher, place it in\n  a free list for later reuse.  Mark-and-sweep frees the free list to keep\n  memory usage in check.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_CALLSTACK_LIMIT.yaml",
    "content": "define: DUK_USE_CALLSTACK_LIMIT\nintroduced: 2.2.0\ndefault: 10000\ntags:\n  - misc\ndescription: >\n  Maximum call stack size.  If call stack would grow beyond this value, reject\n  the call in progress.  This mainly protects against runaway recursion.  Note\n  in particular that this limit is unrelated to the native C stack size which\n  has a separate limit define.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_COMMONJS_MODULES.yaml",
    "content": "define: DUK_USE_COMMONJS_MODULES\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Enable support for CommonJS modules.  When enabled, the global require()\n  function provides a simple module loader facility which depends on the user\n  providing low level module searching functionality.  When disabled, the\n  global require() function is present but throws an error.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_COMPILER_RECLIMIT.yaml",
    "content": "define: DUK_USE_COMPILER_RECLIMIT\nintroduced: 1.3.0\ndefault: 2500\ntags:\n  - portability\n  - cstackdepth\ndescription: >\n  ECMAScript compiler native call stack recursion limit.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_COMPILER_STRING.yaml",
    "content": "define: DUK_USE_COMPILER_STRING\nintroduced: 1.0.0\ndefault:\n  string: \"unknown\"\ntags:\n  - portability\ndescription: >\n  Human-readable compiler string used in e.g. Duktape.env and debugger\n  protocol (example: gcc).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_COMPUTED_INFINITY.yaml",
    "content": "define: DUK_USE_COMPUTED_INFINITY\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  The DUK_DOUBLE_INFINITY is not a constant but refers to a global variable\n  with an IEEE double infinity value computed at run-time.  Some compilers\n  don't provide a constant for infinity, and may incorrectly evaluate\n  (1 / 0) when doing constant folding.\n\n  When enabled, define DUK_DOUBLE_INFINITY as duk_computed_infinity.\n\n# XXX: Remove computed infinity from Duktape itself and let user\n# provide it instead?\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_COMPUTED_NAN.yaml",
    "content": "define: DUK_USE_COMPUTED_NAN\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  The DUK_DOUBLE_NAN is not a constant but refers to a global variable with\n  an IEEE NaN value computed at run-time.  Some compilers don't provide a\n  constant for NaN, and may incorrectly evaluate (0 / 0) when doing\n  constant folding.\n\n  When enabled, define DUK_DOUBLE_NAN as duk_computed_nan.\n\n# XXX: Remove computed NaN from Duktape itself and let user provide\n# it instead?\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_COROUTINE_SUPPORT.yaml",
    "content": "define: DUK_USE_COROUTINE_SUPPORT\nintroduced: 2.0.0\ndefault: true\ntags:\n  - execution\ndescription: >\n  Enable support for Duktape coroutines, i.e. yield/resume.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_CPP_EXCEPTIONS.yaml",
    "content": "define: DUK_USE_CPP_EXCEPTIONS\nintroduced: 1.4.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use C++ exceptions instead of setjmp/longjmp for long control transfers.\n  This allows Duktape/C functions written in C++ to use automatic destructors\n  (RAII or scope-based resource management).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATAPTR16.yaml",
    "content": "define: DUK_USE_DATAPTR16\nintroduced: 1.1.0\nrelated:\n  - DUK_USE_DATAPTR_ENC16\n  - DUK_USE_DATAPTR_DEC16\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Enable \"compression\" of arbitrary data pointers into an unsigned 16-bit\n  value.  Use together with DUK_USE_DATAPTR_ENC16 and DUK_USE_DATAPTR_DEC16.\n\n  Pointers compressed are any void pointers in C code, not just the Duktape\n  heap.  Also NULL pointer must encode and decode correctly.\n\n  Currently it is required that NULL encodes to integer 0, and integer\n  0 decodes to NULL.  No other pointer can be encoded to 0.\n\n  NOTE: This feature option is currently unimplemented, i.e. Duktape won't\n  compress any data pointers at the moment.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATAPTR_DEC16.yaml",
    "content": "define: DUK_USE_DATAPTR_DEC16\nintroduced: 1.1.0\nrequires:\n  - DUK_USE_DATAPTR16\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use together with DUK_USE_DATAPTR16 for arbitrary data pointer compression.\n  DUK_USE_DATAPTR_DEC16(udata,x) is a macro with a userdata and duk_uint16_t\n  argument, and a void ptr return value.  The userdata argument is the heap\n  userdata value given at heap creation.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATAPTR_ENC16.yaml",
    "content": "define: DUK_USE_DATAPTR_ENC16\nintroduced: 1.1.0\nrequires:\n  - DUK_USE_DATAPTR16\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use together with DUK_USE_DATAPTR16 for arbitrary data pointer compression.\n  DUK_USE_DATAPTR_ENC16(udata,p) is a macro with a userdata and void ptr\n  argument, and a duk_uint16_t return value.  The userdata argument is the\n  heap userdata value given at heap creation.  Currently it is required that\n  NULL encodes to integer 0, and integer 0 decodes to NULL.  No other pointer\n  can be encoded to 0.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_BUILTIN.yaml",
    "content": "define: DUK_USE_DATE_BUILTIN\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Provide a Date built-in.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_FMT_STRFTIME.yaml",
    "content": "define: DUK_USE_DATE_FMT_STRFTIME\nintroduced: 1.0.0\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Use strftime() to format Date values in native, platform specific format\n  before falling back into ISO 8601.  When enabled, appropriate date/time\n  headers must be included.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_FORMAT_STRING.yaml",
    "content": "define: DUK_USE_DATE_FORMAT_STRING\nintroduced: 1.3.0\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Optional macro for formatting a date in a platform dependent manner,\n  see datetime.rst.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_GET_LOCAL_TZOFFSET.yaml",
    "content": "define: DUK_USE_DATE_GET_LOCAL_TZOFFSET\nintroduced: 1.3.0\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Mandatory macro for getting the local time offset for a given datetime,\n  see datetime.rst.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_GET_NOW.yaml",
    "content": "define: DUK_USE_DATE_GET_NOW\nintroduced: 1.3.0\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Mandatory macro for getting the current time, see datetime.rst.  The macro\n  is allowed (and recommended) to return millisecond fractions.  The fractions\n  are truncated by the Date built-in, but are available via duk_get_now() C\n  API call.\n\n  If the time provided experiences time jumps or doesn't advance in realtime\n  (which is useful in some time virtualization scenarios), consider defining\n  DUK_USE_GET_MONOTONIC_TIME.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_NOW_GETTIMEOFDAY.yaml",
    "content": "define: DUK_USE_DATE_NOW_GETTIMEOFDAY\nintroduced: 1.0.0\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Use gettimeofday() to get current datetime.  When enabled, appropriate\n  date/time headers must be included.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_NOW_TIME.yaml",
    "content": "define: DUK_USE_DATE_NOW_TIME\nintroduced: 1.0.0\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Use time() to get current datetime, with the limitation that datetime is\n  limited to one second resolution.  When enabled, appropriate date/time\n  headers must be included.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_NOW_WINDOWS.yaml",
    "content": "define: DUK_USE_DATE_NOW_WINDOWS\nintroduced: 1.0.0\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Use Win32 API calls to get current datetime.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_NOW_WINDOWS_SUBMS.yaml",
    "content": "define: DUK_USE_DATE_NOW_WINDOWS_SUBMS\nintroduced: 2.2.0\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Like DUK_USE_DATE_NOW_WINDOWS but use GetSystemTimePreciseAsFileTime(),\n  available since Windows 8, for sub-millisecond resolution.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_PARSE_STRING.yaml",
    "content": "define: DUK_USE_DATE_PARSE_STRING\nintroduced: 1.3.0\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Optional macro for parsing a date in a platform dependent manner,\n  see datetime.rst.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_PRS_GETDATE.yaml",
    "content": "define: DUK_USE_DATE_PRS_GETDATE\nintroduced: 1.3.0\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Use getdate_r() to parse a platform specific datetime string into ECMAScript\n  time.  getdate_r() depends on DATEMSK being set so this is not always very\n  convenient for an embedded interpreter.  When enabled, appropriate date/time\n  headers must be included.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_PRS_STRPTIME.yaml",
    "content": "define: DUK_USE_DATE_PRS_STRPTIME\nintroduced: 1.0.0\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Use strptime() to parse a platform specific datetime string into ECMAScript\n  time.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_TZO_GMTIME.yaml",
    "content": "define: DUK_USE_DATE_TZO_GMTIME\nintroduced: 1.0.0\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Use gmtime() to get local time offset at a certain time.\n  When enabled, appropriate date/time headers must be included.\n\n  Since gmtime() is not re-entrant, this is not thread safe.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_TZO_GMTIME_R.yaml",
    "content": "define: DUK_USE_DATE_TZO_GMTIME_R\nintroduced: 1.0.0\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Use gmtime_r() to get local time offset at a certain time.\n  When enabled, appropriate date/time headers must be included.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_TZO_GMTIME_S.yaml",
    "content": "define: DUK_USE_DATE_TZO_GMTIME_S\nintroduced: 2.0.0\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Use gmtime_s() to get local time offset at a certain time.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_TZO_WINDOWS.yaml",
    "content": "define: DUK_USE_DATE_TZO_WINDOWS\nintroduced: 1.0.0\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Use Win32 API calls to get local time offset at a certain time.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DATE_TZO_WINDOWS_NO_DST.yaml",
    "content": "define: DUK_USE_DATE_TZO_WINDOWS_NO_DST\nintroduced: 2.0.1\ndefault: false\ntags:\n  - date\n  - portability\ndescription: >\n  Use Win32 API calls to get local time offset at a certain time.\n  Does not take into account daylight savings time.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DDDPRINT.yaml",
    "content": "define: DUK_USE_DDDPRINT\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: false\ntags:\n  - debug\ndescription: >\n  Enable even more debug printouts.  Not recommended unless you have\n  grep handy.  Replaced by DUK_USE_DEBUG_LEVEL.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DDPRINT.yaml",
    "content": "define: DUK_USE_DDPRINT\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: false\ntags:\n  - debug\ndescription: >\n  Enable more debug printouts.  Replaced by DUK_USE_DEBUG_LEVEL.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DEBUG.yaml",
    "content": "define: DUK_USE_DEBUG\nintroduced: 1.0.0\ndefault: false\ntags:\n  - debug\ndescription: >\n  Enable debug code in Duktape internals.  Without this option other\n  debugging options (such as DUK_USE_DEBUG_LEVEL and DUK_USE_DEBUG_WRITE)\n  have no effect.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DEBUGGER_DUMPHEAP.yaml",
    "content": "define: DUK_USE_DEBUGGER_DUMPHEAP\nintroduced: 1.2.0\n# Option is ignored unless debugger support is enabled.\n#requires:\n#  - DUK_USE_DEBUGGER_SUPPORT\ndefault: false\ntags:\n  - debugger\ndescription: >\n  Support the DumpHeap command.  This is optional because the command is not\n  always needed.  The command also has a relatively large footprint (about\n  10% of debugger code); in absolute terms it's about 1kB of code footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DEBUGGER_FWD_LOGGING.yaml",
    "content": "define: DUK_USE_DEBUGGER_FWD_LOGGING\nintroduced: 1.2.0\nremoved: 2.0.0\n# Option is ignored unless debugger support is enabled.\n#requires:\n#  - DUK_USE_DEBUGGER_SUPPORT\ndefault: false\ntags:\n  - debugger\ndescription: >\n  Forward log writes using the built-in logging framework to the debug client.\n  Forwarding happens from the Duktape.Logger.prototype.info() etc calls before\n  the raw() function is called, so that logging is forwarded even if you\n  replace the backend.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DEBUGGER_FWD_PRINTALERT.yaml",
    "content": "define: DUK_USE_DEBUGGER_FWD_PRINTALERT\nintroduced: 1.2.0\nremoved: 2.0.0\n# Option is ignored unless debugger support is enabled.\n#requires:\n#  - DUK_USE_DEBUGGER_SUPPORT\ndefault: false\ntags:\n  - debugger\ndescription: >\n  Forward calls to the built-in print() and alert() function to the debug\n  client.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DEBUGGER_INSPECT.yaml",
    "content": "define: DUK_USE_DEBUGGER_INSPECT\nintroduced: 1.5.0\n# Option is ignored unless debugger support is enabled.\n#requires:\n#  - DUK_USE_DEBUGGER_SUPPORT\ndefault: false\ntags:\n  - debugger\ndescription: >\n  Support debugger heap object inspection commands GetHeapObjInfo,\n  GetObjPropDesc, GetObjPropDescRange.  These are optional because the\n  commands have a relatively high code footprint (about 3kB) and are not\n  always needed.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DEBUGGER_PAUSE_UNCAUGHT.yaml",
    "content": "define: DUK_USE_DEBUGGER_PAUSE_UNCAUGHT\nintroduced: 1.4.0\n# Option is ignored unless debugger support is enabled.\n#requires:\n#  - DUK_USE_DEBUGGER_SUPPORT\nrelated:\n  - DUK_USE_DEBUGGER_THROW_NOTIFY\ndefault: false\ntags:\n  - debugger\ndescription: >\n  Pause automatically when an error is about to be thrown and that error is\n  (most likely) not going to be caught.  An error is considered uncaught if\n  there is no active catch clause in the current thread or in the current\n  thread's resumer chain.  This is not 100% accurate because there may be a\n  finally clause which neutralizes the throw (e.g. converts it to a \"return\"\n  or a \"continue\").\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DEBUGGER_SUPPORT.yaml",
    "content": "define: DUK_USE_DEBUGGER_SUPPORT\nintroduced: 1.2.0\nrequires:\n  - DUK_USE_INTERRUPT_COUNTER\ndefault: false\ntags:\n  - debugger\ndescription: >\n  Enable support for Duktape debug protocol (see doc/debugger.rst) and the\n  debug API calls (duk_debugger_attach(), duk_debugger_detach(), etc).\n  This adds about 10kB of code footprint at the moment.\n\n  This option requires DUK_USE_INTERRUPT_COUNTER.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DEBUGGER_THROW_NOTIFY.yaml",
    "content": "define: DUK_USE_DEBUGGER_THROW_NOTIFY\nintroduced: 1.4.0\n# Option is ignored unless debugger support is enabled.\n#requires:\n#  - DUK_USE_DEBUGGER_SUPPORT\nrelated:\n  - DUK_USE_DEBUGGER_PAUSE_UNCAUGHT\ndefault: true\ntags:\n  - debugger\ndescription: >\n  Send a Throw notify when an error is about to be thrown.  The Throw notify\n  also indicates if an error is fatal (most likely not caught) which is very\n  useful in debugging.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DEBUGGER_TRANSPORT_TORTURE.yaml",
    "content": "define: DUK_USE_DEBUGGER_TRANSPORT_TORTURE\nintroduced: 1.2.0\n# Option is ignored unless debugger support is enabled.\n#requires:\n#  - DUK_USE_DEBUGGER_SUPPORT\ndefault: false\ntags:\n  - debugger\n  - development\n  - torture\ndescription: >\n  Development time option: force debugger transport torture.  Concretely this\n  now causes Duktape to read/write debug protocol data in 1-byte increments,\n  which stresses message parsing and transport code.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DEBUG_BUFSIZE.yaml",
    "content": "define: DUK_USE_DEBUG_BUFSIZE\nintroduced: 1.0.0\nrelated:  # not strictly required, value is defined even when DUK_USE_DEBUG not defined\n  - DUK_USE_DEBUG\ndefault: 65536\ntags:\n  - debug\ndescription: >\n  Debug code uses a static buffer as a formatting temporary to avoid side\n  effects in debug prints.  The static buffer is large by default, which\n  may be an issue in constrained environments.  You can set the buffer size\n  manually with this option, e.g. set DUK_USE_DEBUG_BUFSIZE to 2048.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DEBUG_LEVEL.yaml",
    "content": "define: DUK_USE_DEBUG_LEVEL\nintroduced: 2.0.0\ndefault: 0\ntags:\n  - debug\ndescription: >\n  Set debug print level when DUK_USE_DEBUG is enabled.  The level can be\n  0 (minimal), 1 (verbose), 2 (very verbose).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DEBUG_WRITE.yaml",
    "content": "define: DUK_USE_DEBUG_WRITE\nintroduced: 2.0.0\ndefault: false\ntags:\n  - debug\ndescription: >\n  Macro used for Duktape debug log writes (when DUK_USE_DEBUG is enabled).\n  There's no default provider to avoid a dependency on platform I/O calls.\n  The macro is called like a function with the following prototype:\n  \"void DUK_USE_DEBUG_WRITE(long level, const char *file, long line, const char *func, const char *msg)\".\n  The \"file\", \"func\", and \"msg\" arguments are non-NULL strings, though NULLs\n  should be handled as good practice (it's ultimately up to duk_config.h\n  whether NULL values are possible).\n\n  See http://wiki.duktape.org/HowtoDebugPrints.html for more information\n  and examples.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DEEP_C_STACK.yaml",
    "content": "define: DUK_USE_DEEP_C_STACK\nintroduced: 1.0.0\nremoved: 1.3.0\ndefault: true\ntags:\n  - portability\ndescription: >\n  Assume deep C stacks are not an issue on the target platform; on some\n  embedded platforms the native C stack is very limited (e.g. 32-64 kB)\n  and overrunning the stack leads to difficult-to-diagnose problems.\n\n  Removed in Duktape 1.3.0, replaced by explicit recursion limits.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DOUBLE_BE.yaml",
    "content": "define: DUK_USE_DOUBLE_BE\nintroduced: 1.0.0\nremoved: 1.4.0\ndefault: false\nconflicts:\n  - DUK_USE_DOUBLE_LE\n  - DUK_USE_DOUBLE_ME\ntags:\n  - portability\ndescription: >\n  IEEE double memory representation is big endian on the target platform.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DOUBLE_LE.yaml",
    "content": "define: DUK_USE_DOUBLE_LE\nintroduced: 1.0.0\nremoved: 1.4.0\ndefault: true\nconflicts:\n  - DUK_USE_DOUBLE_BE\n  - DUK_USE_DOUBLE_ME\ntags:\n  - portability\ndescription: >\n  IEEE double memory representation is little endian on the target platform.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DOUBLE_LINKED_HEAP.yaml",
    "content": "define: DUK_USE_DOUBLE_LINKED_HEAP\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Use a double-linked duk_heaphdr structure.  Required when reference\n  counting is enabled.\n\n# XXX: This must currently always match DUK_USE_REFERENCE_COUNTING\n# so remove as a separate option?\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DOUBLE_ME.yaml",
    "content": "define: DUK_USE_DOUBLE_ME\nintroduced: 1.0.0\nremoved: 1.4.0\ndefault: false\nconflicts:\n  - DUK_USE_DOUBLE_LE\n  - DUK_USE_DOUBLE_BE\ntags:\n  - portability\ndescription: >\n  IEEE double memory representation is mixed endian on the target platform.\n  In other words the logical bytes ABCDEFGH are represented in memory as\n  DCBAHGFE.  This endianness is used by some ARM platforms.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DPRINT.yaml",
    "content": "define: DUK_USE_DPRINT\nintroduced: 1.0.0\nremoved: 2.0.0\nrequires:\n  - DUK_USE_DEBUG\ndefault: false\ntags:\n  - debug\ndescription: >\n  Enable debug printouts.  Replaced by DUK_USE_DEBUG_LEVEL.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DPRINT_COLORS.yaml",
    "content": "define: DUK_USE_DPRINT_COLORS\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: false\ntags:\n  - debug\ndescription: >\n  Enable coloring of debug prints with ANSI escape codes\n  (http://en.wikipedia.org/wiki/ANSI_escape_code).  The behavior is not\n  sensitive to terminal settings.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DPRINT_RDTSC.yaml",
    "content": "define: DUK_USE_DPRINT_RDTSC\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: false\ntags:\n  - debug\ndescription: >\n  Print RDTSC cycle count in debug prints if available.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_DUKTAPE_BUILTIN.yaml",
    "content": "define: DUK_USE_DUKTAPE_BUILTIN\nintroduced: 2.0.0\ndefault: true\ntags:\n  - duktape\ndescription: >\n  Provide a Duktape built-in.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ENCODING_BUILTINS.yaml",
    "content": "define: DUK_USE_ENCODING_BUILTINS\nintroduced: 2.0.0\ndefault: true\ntags:\n  - encoding-api\ndescription: >\n  Provide TextEncoder and TextDecoder built-ins (the Encoding API) which allow\n  ECMAScript code to encode and decode text stored in a buffer.  Only UTF-8 is\n  currently supported for decoding.\n\n  DUK_USE_BUFFEROBJECT_SUPPORT is recommended but not required: If it is\n  disabled, TextEncoder will encode to a plain buffer instead of a Uint8Array.\n  TextDecoder always accepts plain buffers as input.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ERRCREATE.yaml",
    "content": "define: DUK_USE_ERRCREATE\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Call Duktape.errCreate() when augmenting an ECMAScript error object\n  being created.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ERRTHROW.yaml",
    "content": "define: DUK_USE_ERRTHROW\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Call Duktape.errThrow() when augmenting an ECMAScript error object\n  about to be thrown.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ES6.yaml",
    "content": "define: DUK_USE_ES6\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript2015\ndescription: >\n  Enable ES6 functionality not covered by other specific config options.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ES6_OBJECT_PROTO_PROPERTY.yaml",
    "content": "define: DUK_USE_ES6_OBJECT_PROTO_PROPERTY\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript2015\ndescription: >\n  Provide the non-standard (ES6) Object.prototype.__proto__ property.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ES6_OBJECT_SETPROTOTYPEOF.yaml",
    "content": "define: DUK_USE_ES6_OBJECT_SETPROTOTYPEOF\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript2015\ndescription: >\n  Provide the non-standard (ES6) Object.setPrototypeOf method.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ES6_PROXY.yaml",
    "content": "define: DUK_USE_ES6_PROXY\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript2015\ndescription: >\n  Provide the non-standard (ES6) Proxy object.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ES6_REGEXP_BRACES.yaml",
    "content": "define: DUK_USE_ES6_REGEXP_BRACES\nintroduced: 1.5.0\nremoved: 2.0.0\ndefault: true\ntags:\n  - ecmascript2015\ndescription: >\n  Replaced by DUK_USE_ES6_REGEXP_SYNTAX.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ES6_REGEXP_SYNTAX.yaml",
    "content": "define: DUK_USE_ES6_REGEXP_SYNTAX\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript2015\ndescription: >\n  Enable support for additional RegExp syntax from E6 Section B.1.4, such as:\n  (1) dollar escape, (2) unescaped curly braces ('{' and '}'), and (3)\n  unescaped right bracket (']').  This option does not enable all of the ES6\n  syntax because not all of the extra syntax is implemented; rather, the option\n  enables whatever ES6 extra syntax has been implemented so far.\n\n  This option is recommended because a lot of existing code depends on literal\n  regexp braces, and other non-ES5 constructs.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ES6_UNICODE_ESCAPE.yaml",
    "content": "define: DUK_USE_ES6_UNICODE_ESCAPE\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript2015\ndescription: >\n  Enable support for ES6 Unicode escape syntax (\"\\u{12345}\") in source code\n  and RegExps.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ES7.yaml",
    "content": "define: DUK_USE_ES7\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript2016\ndescription: >\n  Enable ES7 functionality not covered by other specific config options.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ES7_EXP_OPERATOR.yaml",
    "content": "define: DUK_USE_ES7_EXP_OPERATOR\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript2016\ndescription: >\n  Support the ES7 exponentiation operator (** and **=).  This is optional\n  because the operator pulls in pow() which may have a significant footprint\n  impact on bare metal platforms.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ES8.yaml",
    "content": "define: DUK_USE_ES8\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript2017\ndescription: >\n  Enable ES8 functionality not covered by other specific config options.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ES9.yaml",
    "content": "define: DUK_USE_ES9\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript2018\ndescription: >\n  Enable ES9 functionality not covered by other specific config options.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ESBC_LIMITS.yaml",
    "content": "define: DUK_USE_ESBC_LIMITS\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Impose byte and line number limits for compiled function bytecode.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ESBC_MAX_BYTES.yaml",
    "content": "define: DUK_USE_ESBC_MAX_BYTES\nintroduced: 1.0.0\nrequires:\n  - DUK_USE_ESBC_LIMITS\ndefault: 0x7fff0000\ntags:\n  - ecmascript\ndescription: >\n  Maximum byte count for compiled function bytecode.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ESBC_MAX_LINENUMBER.yaml",
    "content": "define: DUK_USE_ESBC_MAX_LINENUMBER\nintroduced: 1.0.0\nrequires:\n  - DUK_USE_ESBC_LIMITS\ndefault: 0x7fff0000\ntags:\n  - ecmascript\ndescription: >\n  Maximum line number for compiled function bytecode.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_EXAMPLE.yaml",
    "content": "#\n#  Each Duktape option is described as a YAML file named OPTION_NAME.yaml.\n#  YAML is used because it diffs well and has clean support for multiline\n#  inline strings.\n#\n\n# C #define name for the option.  Must match filename minus extension.\ndefine: DUK_USE_OBJSIZES16\n\n# Duktape version number where this option was first introduced.\nintroduced: 1.1.0\n\n# Optional Duktape version number where this option was deprecated,\n# i.e. the option is supported but no longer recommended.\n# XXX: automatic #error with some -DDUK_USE_NO_DEPRECATED flag?\n#deprecated: 1.2.0\n\n# Optional Duktape version number where this option was removed,\n# i.e. the option is no longer supported but we may want to issue\n# a clear #error for it.\n#removed: 1.3.0\n\n# Optional indication that config option is defined but currently\n# unused, so that it can be omitted from generated header.\n#unused: true\n\n# Optional list of options that must also be defined to use this option.\n#requires:\n#  - DUK_USE_FOO\n#  - DUK_USE_BAR\n\n# Optional list of options that this option conflicts with.\n#conflicts:\n#  - DUK_USE_BAZ\n\n# Optional list of options that are related from a user and documentation\n# perspective.\n#related:\n#  - DUK_USE_QUUX\n\n# Default value for option:\n# - false: undefined (#undef DUK_USE_EXAMPLE)\n# - true: defined with no value (#define DUK_USE_EXAMPLE)\n# - string: defined with string value (#define DUK_USE_EXAMPLE \"foo\")\n# - number: defined with number value (#define DUK_USE_EXAMPLE 123)\n# - verbatim: define verbatim line(s)\ndefault: false\n\n# Tags related to option (required).  If present, first tag is used as a\n# primary tag for grouping.  Use 'misc' if nothing else is appropriate.\ntags:\n  - lowmemory\n  - experimental\n\n# When set to true, genconfig.py will warn if no forced value is provided.\n# This should be used sparingly, for options which are really strongly\n# recommended so that configure.py output should warn about it.\n#warn_if_missing: true\n\n# Description for option, no newlines.  Line breaking for e.g. C header\n# is automatic.\ndescription: >\n  Use a 16-bit object entry and array part sizes (for low memory\n  environments).  Also automatically drops support for an object hash\n  part to further reduce memory usage; there are rarely large objects\n  in low memory environments simply because there's no memory to store\n  a lot of properties.\n\n  By default use \"description: >\" markup which works well for paragraphs\n  (replacing newlines with spaces) but includes a trailing newline which\n  is also a good default.\n\n# Marker to avoid processing this file.\nexample: true\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_EXEC_FUN_LOCAL.yaml",
    "content": "define: DUK_USE_EXEC_FUN_LOCAL\nintroduced: 1.4.0\ndefault: false\ntags:\n  - performance\n  - execution\ndescription: >\n  Use a local variable \"fun\" pointing to the current function in the bytecode\n  dispatch loop instead of looking up the current function through \"thr\" every\n  time it is needed.  On x64 performance is slightly better without a \"fun\"\n  local; on x86 performance is slightly better with one.\n\n  You should only tweak this if you're really interested in performance, and\n  should then do proper testing to see which value works better.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_EXEC_INDIRECT_BOUND_CHECK.yaml",
    "content": "define: DUK_USE_EXEC_INDIRECT_BOUND_CHECK\nintroduced: 1.0.0\ndefault: false\ntags:\n  - execution\n  - debug\ndescription: >\n  For opcodes with indirect indices, check final index against stack size.\n  Useful for diagnosing problems.  Normally this check is not necessary\n  because the compiler is trusted, and we don't bound check direct indices\n  either.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_EXEC_PREFER_SIZE.yaml",
    "content": "define: DUK_USE_EXEC_PREFER_SIZE\nintroduced: 2.0.0\ndefault: false\ntags:\n  - lowmemory\ndescription: >\n  Prefer size over performance in bytecode executor.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_EXEC_REGCONST_OPTIMIZE.yaml",
    "content": "define: DUK_USE_EXEC_REGCONST_OPTIMIZE\nintroduced: 2.0.0\ndefault: true\ntags:\n  - performance\n  - execution\ndescription: >\n  Use an internal optimization to access registers and constants in the\n  bytecode executor.  The optimization avoids unnecessary shifts when computing\n  addresses but assumes sizeof(duk_tval) is 8 or 16.  This is almost always the\n  case, but when it isn't, disable this option.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_EXEC_TIMEOUT_CHECK.yaml",
    "content": "define: DUK_USE_EXEC_TIMEOUT_CHECK\nintroduced: 1.2.0\nrequires:\n  - DUK_USE_INTERRUPT_COUNTER\ndefault: false\ntags:\n  - execution\n  - sandbox\n  - experimental\ndescription: >\n  NOTE: This mechanism is EXPERIMENTAL and the details may change\n  between releases.\n\n  Provide a hook to check for bytecode execution timeout.  The macro gets\n  a void ptr userdata argument (the userdata given to duk_heap_create())\n  and must evaluate to a duk_bool_t.  Duktape calls the macro as:\n  \"if (DUK_USE_EXEC_TIMEOUT_CHECK(udata)) { ... }\".\n\n  The macro is called occasionally by the Duktape bytecode executor (i.e.\n  when executing ECMAScript code), typically from a few times per second\n  to a hundred times per second, but the interval varies a great deal\n  depending on what kind of code is being executed.\n\n  To indicate an execution timeout, the macro must return a non-zero value.\n  When that happens, Duktape starts to bubble a ``RangeError`` outwards\n  until control has been returned to the original protected call made by\n  the application.  Until that happens, the exec timeout macro must always\n  return non-zero to indicate an execution timeout is still in progress.\n\n  This mechanism and its limitations is described in more detail in\n  doc/sandboxing.rst.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_EXPLICIT_NULL_INIT.yaml",
    "content": "define: DUK_USE_EXPLICIT_NULL_INIT\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  When zeroing structures, don't rely on memzero initializing pointers to\n  NULL.  Instead, write NULL values explicitly after zeroing.  This should\n  only be necessary when a NULL pointer is not represented by zero bytes in\n  memory.\n\n  # NOTE: Condition in Duktape 1.2 seems wrong, and is linked to packed tval.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_EXTSTR_FREE.yaml",
    "content": "define: DUK_USE_EXTSTR_FREE\nintroduced: 1.1.0\nrequires:\n  - DUK_USE_HSTRING_EXTDATA\ndefault: false\ntags:\n  - memory\n  - experimental\ndescription: >\n  Optional counterpart to DUK_USE_EXTSTR_INTERN_CHECK.  Invoked when an\n  external string is about to be freed by Duktape.\n\n  The argument \"ptr\" is a void ptr and points to the external string data.\n  Concretely, it is the (non-NULL) value returned by\n  DUK_USE_EXTSTR_INTERN_CHECK.  The \"udata\" argument is the heap userdata\n  which may be ignored if not needed.\n\n  Also enable DUK_USE_HSTRING_EXTDATA to use this feature.\n\n  NOTE: Right now there is no API to push external strings; external strings\n  come into being as a result of DUK_USE_EXTSTR_INTERN_CHECK() only.  If/when\n  this is changed, this hook will get called for every string, even if pushed\n  by the user using an API call; this may need to be rethought at that time.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_EXTSTR_INTERN_CHECK.yaml",
    "content": "define: DUK_USE_EXTSTR_INTERN_CHECK\nintroduced: 1.1.0\nrequires:\n  - DUK_USE_HSTRING_EXTDATA\ndefault: false\ntags:\n  - memory\n  - experimental\ndescription: >\n  Provide a hook for checking if data for a certain string can be used from\n  external memory (outside of Duktape heap, e.g. memory mapped flash).\n  The hook is called during string interning with the following semantics:\n\n  The string data with no NUL termination resides at \"ptr\" and has \"len\"\n  bytes.  The \"udata\" argument is the heap userdata which may be ignored\n  if not needed.  If the hook returns NULL, Duktape interns the string\n  normally, i.e. string data is allocated from Duktape heap.  Otherwise the\n  hook return value must point to a memory area which contains\n  \"len\" bytes from \"ptr\" followed by a NUL byte which is NOT PRESENT\n  in the input data.  Data behind the returned pointer may not change after\n  the hook returns.\n\n  The hook may be called several times for the same input string.  This\n  happens when a string is interned, garbage collected, and then interned\n  again.\n\n  The DUK_USE_EXTSTR_FREE() hook allows application code to detect when\n  an external string is about to be freed.\n\n  In most cases the hook should reject strings whose \"len\" is less than 4\n  because there is no RAM advantage in moving so short strings into external\n  memory.  The ordinary \"duk_hstring\" header followed by the data (and a\n  NUL byte) has the same size as \"duk_hstring_external\" header which hosts\n  a pointer instead of string data.\n\n  Also enable DUK_USE_HSTRING_EXTDATA to use this feature.\n\n  See doc/low-memory.rst for more discussion how to use this feature option\n  in practice.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FASTINT.yaml",
    "content": "define: DUK_USE_FASTINT\nrequires:\n  - DUK_USE_64BIT_OPS\nintroduced: 1.2.0\ndefault: false\ntags:\n  - performance\n  - fastpath\ndescription: >\n  Enable support for 48-bit signed \"fastint\" integer values.  Fastints are\n  transparent to user code (both C and ECMAScript) but may be faster than\n  IEEE doubles on some platforms, especially those using softints.  The\n  downside of fastints is increased code footprint and a small performance\n  penalty for some kinds of code.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FAST_REFCOUNT_DEFAULT.yaml",
    "content": "define: DUK_USE_FAST_REFCOUNT_DEFAULT\nintroduced: 1.2.0\ndefault: true\ntags:\n  - performance\n  - fastpath\n  - experimental\ndescription: >\n  When enabled, plain refcount macros (e.g. DUK_TVAL_INCREF) default to\n  fast variants (DUK_TVAL_INCREF_FAST) to improve performance.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FATAL_HANDLER.yaml",
    "content": "define: DUK_USE_FATAL_HANDLER\nintroduced: 2.0.0\ndefault: false\ntags:\n  - portability\nwarn_if_missing: true\ndescription: >\n  Provide a custom default fatal error handler to replace the built-in one\n  (which calls abort() without any error message).  The default fatal error\n  handler gets called when (1) a fatal error occurs and application code\n  didn't register a fatal error handler in heap creation or (2) a context-free\n  fatal error happens, concretely e.g. an assertion failure.\n\n  The handler is called like a C function with the prototype\n  \"void fatal_handler(void *udata, const char *msg)\".  The \"msg\" argument can\n  be NULL.  The \"udata\" argument matches the heap-related userdata but is\n  NULL for fatal errors unrelated to a heap/thread context (this is the case\n  for e.g. assertions).\n\n  A custom default fatal error handler is recommended for any environment\n  where recover from fatal errors is important.  A custom handler can take\n  appropriate action to recover, e.g. record the error and reboot the target\n  device.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FATAL_MAXLEN.yaml",
    "content": "define: DUK_USE_FATAL_MAXLEN\nintroduced: 2.2.0\ndefault: 128\ntags:\n  - portability\ndescription: >\n  Maximum length of fatal error message string when error is thrown by\n  Duktape internals, in particular for uncaught errors.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FILE_IO.yaml",
    "content": "define: DUK_USE_FILE_IO\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: true\ntags:\n  - io\ndescription: >\n  File I/O support.  This is now used in a few API calls to e.g. push\n  a string from file contents or eval a file.  For portability it must\n  be possible to disable I/O altogether.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FINALIZER_SUPPORT.yaml",
    "content": "define: DUK_USE_FINALIZER_SUPPORT\nintroduced: 2.0.0\ndefault: true\ntags:\n  - execution\ndescription: >\n  Enable support for object finalizers (Duktape specific).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FINALIZER_TORTURE.yaml",
    "content": "define: DUK_USE_FINALIZER_TORTURE\nintroduced: 2.1.0\ndefault: false\ntags:\n  - gc\n  - memory\n  - development\n  - torture\ndescription: >\n  Development time option: simulate a fake finalizer call every time when\n  finalizers might be executed (even if the actual finalize_list is empty).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FLEX_C99.yaml",
    "content": "define: DUK_USE_FLEX_C99\nintroduced: 1.0.0\ndefault: true\ntags:\n  - portability\ndescription: >\n  Use C99 flexible array member for defining variable size structures.\n\n# XXX: currently unused, remove or mark unused so doesn't get emitted?\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FLEX_ONESIZE.yaml",
    "content": "define: DUK_USE_FLEX_ONESIZE\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use a single element array to define variable size structures.  This is the\n  most portable alternative: zero-size arrays are not allowed by all compilers\n  and flexible array member (\"char arr[]\") is defined in C99.\n\n# XXX: currently unused, remove or mark unused so doesn't get emitted?\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FLEX_ZEROSIZE.yaml",
    "content": "define: DUK_USE_FLEX_ZEROSIZE\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use a zero element array to define variable size structures.  This is not\n  fully portable but works with some compilers and is preferred over using\n  a one element array.\n\n# XXX: currently unused, remove or mark unused so doesn't get emitted?\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FULL_TVAL.yaml",
    "content": "define: DUK_USE_FULL_TVAL\nintroduced: 1.0.0\nremoved: 1.2.0\ndefault: false\ntags:\n  - misc\ndescription: >\n  Initialize all bytes of a duk_tval when setting a value into one.\n\n  By default only needed fields are initialized which reduces code size and\n  improves performance slightly.  This should cause no functional issues but\n  may cause valgrind issues in rare cases, e.g. when debugger code dumps the\n  constant table of a function (which then reads uninitialized bits).\n\n  Removed in 1.2.0 because the option was never enabled and there was no\n  feature option to cause it to be used.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FUNCPTR16.yaml",
    "content": "define: DUK_USE_FUNCPTR16\nintroduced: 1.1.0\nrelated:\n  - DUK_USE_FUNCPTR_ENC16\n  - DUK_USE_FUNCPTR_DEC16\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Enable \"compression\" of arbitrary data pointers into an unsigned 16-bit\n  value.  Use together with DUK_USE_DATAPTR_ENC16 and DUK_USE_DATAPTR_DEC16.\n\n  Pointers compressed are any void pointers in C code, not just the Duktape\n  heap.  Also NULL pointer must encode and decode correctly.\n\n  Currently it is required that NULL encodes to integer 0, and integer\n  0 decodes to NULL.  No other pointer can be encoded to 0.\n\n  NOTE: This feature option is currently unimplemented, i.e. Duktape won't\n  compress any data pointers at the moment.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FUNCPTR_DEC16.yaml",
    "content": "define: DUK_USE_FUNCPTR_DEC16\nintroduced: 1.1.0\nrequires:\n  - DUK_USE_FUNCPTR16\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use together with DUK_USE_FUNCPTR16 for arbitrary data pointer compression.\n  DUK_USE_FUNCPTR_ENC16(udata,p) is a macro with a userdata and void ptr\n  argument, and a duk_uint16_t return value.  The userdata argument is the\n  heap userdata value given at heap creation.  Currently it is required that\n  NULL encodes to integer 0, and integer 0 decodes to NULL.  No other pointer\n  can be encoded to 0.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FUNCPTR_ENC16.yaml",
    "content": "define: DUK_USE_FUNCPTR_ENC16\nintroduced: 1.1.0\nrequires:\n  - DUK_USE_FUNCPTR16\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use together with DUK_USE_FUNCPTR16 for arbitrary data pointer compression.\n  DUK_USE_FUNCPTR_DEC16(udata,x) is a macro with a userdata and duk_uint16_t\n  argument, and a void ptr return value.  The userdata argument is the heap\n  userdata value given at heap creation.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FUNCTION_BUILTIN.yaml",
    "content": "define: DUK_USE_FUNCTION_BUILTIN\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Provide a Function built-in.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FUNC_FILENAME_PROPERTY.yaml",
    "content": "define: DUK_USE_FUNC_FILENAME_PROPERTY\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript\n  - compliance\ndescription: >\n  Add a non-standard \".fileName\" property to function instances.  Disabling\n  reduces footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_FUNC_NAME_PROPERTY.yaml",
    "content": "define: DUK_USE_FUNC_NAME_PROPERTY\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript\n  - compliance\ndescription: >\n  Add a \"name\" property to function instances.  This is part of ECMAScript\n  requirements, but low memory devices can sometimes opt to not include the\n  .name to reduce footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_GCC_PRAGMAS.yaml",
    "content": "define: DUK_USE_GCC_PRAGMAS\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use GCC-specific pragmas, e.g. \"#pragma GCC diagnostic\" to suppress\n  unnecessary warnings.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_GC_TORTURE.yaml",
    "content": "define: DUK_USE_GC_TORTURE\nintroduced: 1.0.0\ndefault: false\ntags:\n  - gc\n  - memory\n  - development\n  - torture\ndescription: >\n  Development time option: force full mark-and-sweep on every allocation and\n  in other chosen places to stress test memory management.\n\n  Using a low value (e.g. 3) for DUK_USE_MARK_AND_SWEEP_RECLIMIT is also\n  recommended.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_GET_MONOTONIC_TIME.yaml",
    "content": "define: DUK_USE_GET_MONOTONIC_TIME\nintroduced: 2.2.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Optional macro for getting monotonic time in milliseconds from an arbitrary\n  starting point (device startup, program startup, script startup, etc).\n  Fractional time values are allowed (and even recommended).  The time returned\n  must increase monotonically, and must not jump discontinuously even if system\n  date/time is reset.  The semantics are similar to POSIX clock_gettime()\n  CLOCK_MONOTONIC.\n\n  Monotonic time is used by Duktape for its internal needs, such as rate\n  limiting debugger transport peek callbacks.  It is also used to provide\n  performance.now().  If this option is not provided, Duktape falls back to\n  using DUK_USE_DATE_GET_NOW() which is usually fine.\n\n  If DUK_USE_DATE_GET_NOW() experiences time jumps or doesn't run in realtime\n  (which may be useful for some time virtualization cases) it's recommended\n  to provide this config option so that internals which need a reliable\n  realtime rate have a reliable time basis.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME.yaml",
    "content": "define: DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME\nintroduced: 2.2.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use clock_gettime(CLOCK_MONOTONIC, ...) for monotonic time on POSIX\n  platforms.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC.yaml",
    "content": "define: DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC\nintroduced: 2.2.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use QueryPerformanceCounter() for monotonic time on Windows.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_GET_RANDOM_DOUBLE.yaml",
    "content": "define: DUK_USE_GET_RANDOM_DOUBLE\nintroduced: 2.0.0\ndefault: false\ntags:\n  - portability\n  - performance\ndescription: >\n  Override the default internal random number generator which is used for\n  Math.random() and some other internal call sites (currently, for example,\n  Array.prototype.sort()).  The default random number generator has a very\n  low footprint but is not suitable for serious statistics algorithms or\n  cryptography.  Overriding the random number generator may thus be useful\n  in some environments.\n\n  The macro gets a heap userdata argument and must provide an IEEE double\n  in the range [0,1[.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_GLOBAL_BINDING.yaml",
    "content": "define: DUK_USE_GLOBAL_BINDING\nintroduced: 2.1.0\ndefault: false\ntags:\n  - ecmascript\n  - experimental\ndescription: >\n  Provide a 'global' binding (https://github.com/tc39/proposal-global).\n  Disabled by default because it's still a proposal and there may be\n  reasons it won't be widely implemented: https://github.com/tc39/proposal-global/issues/20.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_GLOBAL_BUILTIN.yaml",
    "content": "define: DUK_USE_GLOBAL_BUILTIN\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Provide miscellaneous global built-ins like encodeURIComponent(), escape(),\n  Infinity, etc.  This is a catch-all for globals not covered by other options\n  (like DUK_USE_ARRAY_BUILTIN).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS.yaml",
    "content": "define: DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS\nintroduced: 1.0.0\nremoved: 1.4.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Allow unaligned 32-bit unsigned integer access in hashbytes algorithm.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HEAPPTR16.yaml",
    "content": "define: DUK_USE_HEAPPTR16\nintroduced: 1.1.0\nconflicts:\n  - DUK_USE_DEBUG\nrelated:\n  - DUK_USE_HEAPPTR_ENC16\n  - DUK_USE_HEAPPTR_DEC16\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Enable \"compression\" of Duktape heap pointers into an unsigned 16-bit value.\n  Use together with DUK_USE_HEAPPTR_ENC16 and DUK_USE_HEAPPTR_DEC16.\n\n  Pointers compressed are those allocated from Duktape heap, using the user\n  provided allocation functions.  Also NULL pointer must encode and decode\n  correctly.\n\n  Currently it is required that NULL encodes to integer 0, and integer\n  0 decodes to NULL.  No other pointer can be encoded to 0.\n\n  This option reduces memory usage by several kilobytes, but has several\n  downsides.  It can only be applied when Duktape heap is limited in size,\n  for instance, with 4-byte aligned allocations a 256kB heap (minus one value\n  for NULL) can be supported.  Pointer encoding and decoding may be relatively\n  complicated as they need to correctly handle NULL pointers and\n  non-continuous memory maps used by some targets.  The macro may need to call\n  out to a helper function in practice, which is much slower than an inline\n  implementation.\n\n  Current limitation:  Duktape internal debug code enabled with e.g.\n  DUK_USE_DEBUG and DUK_USE_DEBUG_LEVEL=0 doesn't have enough plumbing to be\n  able to decode pointers.  Debug printing cannot currently be enabled when\n  pointer compression is active.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HEAPPTR_DEC16.yaml",
    "content": "define: DUK_USE_HEAPPTR_DEC16\nintroduced: 1.1.0\nrequires:\n  - DUK_USE_HEAPPTR16\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use together with DUK_USE_HEAPPTR16 for heap pointer compression.\n  DUK_USE_HEAPPTR_DEC16(udata,x) is a macro with a userdata and duk_uint16_t\n  argument, and a void ptr return value.  The userdata argument is the heap\n  userdata value given at heap creation.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HEAPPTR_ENC16.yaml",
    "content": "define: DUK_USE_HEAPPTR_ENC16\nintroduced: 1.1.0\nrequires:\n  - DUK_USE_HEAPPTR16\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use together with DUK_USE_HEAPPTR16 for heap pointer compression.\n  DUK_USE_HEAPPTR_ENC16(udata,p) is a macro with a userdata and void ptr\n  argument, and a duk_uint16_t return value.  The userdata argument is the\n  heap userdata value given at heap creation.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HEX_FASTPATH.yaml",
    "content": "define: DUK_USE_HEX_FASTPATH\nintroduced: 1.4.0\ndefault: true\ntags:\n  - performance\n  - fastpath\n  - lowmemory\ndescription: >\n  Enable fast path for hex encode/decode.  The fast path uses a lookup\n  table at a small cost in footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HEX_SUPPORT.yaml",
    "content": "define: DUK_USE_HEX_SUPPORT\nintroduced: 2.3.0\ndefault: true\ntags:\n  - codec\ndescription: >\n  Enable hex encoding/decoding support.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HOBJECT_ARRAY_ABANDON_LIMIT.yaml",
    "content": "define: DUK_USE_HOBJECT_ARRAY_ABANDON_LIMIT\nintroduced: 2.1.0\ndefault: 2\ntags:\n  - performance\n  - lowmemory\ndescription: >\n  Abandon array part if its density is below L.  The limit L is expressed as\n  a .3 fixed point point, e.g. 2 means 2/8 = 25%.\n\n  The default limit is quite low: one array entry with packed duk_tval is 8\n  bytes whereas one normal entry is 4+1+8 = 13 bytes without a hash entry,\n  and 17-21 bytes with a hash entry (load factor 0.5-1.0).  So the array part\n  shouldn't be abandoned very easily from a footprint point of view.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HOBJECT_ARRAY_FAST_RESIZE_LIMIT.yaml",
    "content": "define: DUK_USE_HOBJECT_ARRAY_FAST_RESIZE_LIMIT\nintroduced: 2.1.0\ndefault: 9\ntags:\n  - performance\n  - lowmemory\ndescription: >\n  Skip abandon check in object array part resize if new_size < L * old_size.\n  The limit L is expressed as a .3 fixed point value, e.g. 9 means 9/8 =\n  112.5% of current size.\n\n  This is rather technical and you should only change the parameter if you've\n  looked at the internals.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HOBJECT_ARRAY_MINGROW_ADD.yaml",
    "content": "define: DUK_USE_HOBJECT_ARRAY_MINGROW_ADD\nintroduced: 2.1.0\ndefault: 16\ntags:\n  - performance\ndescription: >\n  Technical internal parameter, see sources for details.  Only adjust if\n  you've looked at the internals.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HOBJECT_ARRAY_MINGROW_DIVISOR.yaml",
    "content": "define: DUK_USE_HOBJECT_ARRAY_MINGROW_DIVISOR\nintroduced: 2.1.0\ndefault: 8\ntags:\n  - performance\ndescription: >\n  Technical internal parameter, see sources for details.  Only adjust if\n  you've looked at the internals.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HOBJECT_ENTRY_MINGROW_ADD.yaml",
    "content": "define: DUK_USE_HOBJECT_ENTRY_MINGROW_DIVISOR\nintroduced: 2.1.0\ndefault: 8\ntags:\n  - performance\ndescription: >\n  Technical internal parameter, see sources for details.  Only adjust if\n  you've looked at the internals.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HOBJECT_ENTRY_MINGROW_DIVISOR.yaml",
    "content": "define: DUK_USE_HOBJECT_ENTRY_MINGROW_ADD\nintroduced: 2.1.0\ndefault: 16\ntags:\n  - performance\ndescription: >\n  Technical internal parameter, see sources for details.  Only adjust if\n  you've looked at the internals.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HOBJECT_HASH_PART.yaml",
    "content": "define: DUK_USE_HOBJECT_HASH_PART\nintroduced: 1.1.0\ndefault: true\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use a hash table for objects that have enough properties.  This should be\n  enabled unless the target is very low on memory.\n\n  If DUK_USE_OBJSIZES16 is defined, this option must not be defined.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HOBJECT_HASH_PROP_LIMIT.yaml",
    "content": "define: DUK_USE_HOBJECT_HASH_PROP_LIMIT\nintroduced: 2.1.0\ndefault: 8\ntags:\n  - performance\n  - lowmemory\ndescription: >\n  Minimum number of properties needed for a hash part to be included in the\n  object property table.  This limit is checked whenever an object is resized.\n\n  A hash part improves property lookup performance even for small objects,\n  starting from roughly 4 properties.  However, this ignores the cost of\n  setting up and managing the hash part, which is offset only if property\n  lookups made through the hash part can offset the setup cost.  A hash part\n  is worth it for heavily accessed small objects or large objects (even those\n  accessed quite infrequently).  The limit doesn't take into account property\n  access frequency, so it is necessarily a compromise.\n\n  A lower value improves performance (a value as low a 4-8 can be useful)\n  while a higher value conserves memory.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HOBJECT_LAYOUT_1.yaml",
    "content": "define: DUK_USE_HOBJECT_LAYOUT_1\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use layout variant 1 for object properties.  Layout 1 can be used when the\n  target has no alignment restrictions.  It is preferable to other layouts\n  because it produces smaller code and provides direct access to property\n  keys.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HOBJECT_LAYOUT_2.yaml",
    "content": "define: DUK_USE_HOBJECT_LAYOUT_2\nintroduced: 1.0.0\ndefault: true\ntags:\n  - portability\ndescription: >\n  Use layout variant 2 for object properties.  Layout 2 can be used on any\n  target (including targets with alignment restrictions).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HOBJECT_LAYOUT_3.yaml",
    "content": "define: DUK_USE_HOBJECT_LAYOUT_3\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use layout variant 3 for object properties.  Layout 3 can be used on any\n  target (including targets with alignment restrictions).  It's a bit more\n  packed than layout variant 2 but has a bit slower lookups.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HSTRING_ARRIDX.yaml",
    "content": "define: DUK_USE_HSTRING_ARRIDX\nintroduced: 2.0.0\ndefault: true\ntags:\n  - lowmemory\ndescription: >\n  When enabled, duk_hstring stores a precomputed array index (or \"not an array\n  index\") value related to the string.  This reduces code footprint and\n  improves performance a littl ebit.\n\n  When disabled, duk_hstring has a flag indicating whether it is an array\n  index or not, but the actual value is computed on-the-fly.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HSTRING_CLEN.yaml",
    "content": "define: DUK_USE_HSTRING_CLEN\nintroduced: 1.5.0\ndefault: true\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  When DUK_USE_STRLEN16 enabled, indicates whether the character length\n  (clen16) field should be actually present (default) or computed on-the-fly.\n\n  When clen is computed on-the-fly the duk_hstring structure will be 4 bytes\n  smaller (from 10 bytes + 2 bytes padding to 8 bytes) which may be useful for\n  very low memory targets.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HSTRING_EXTDATA.yaml",
    "content": "define: DUK_USE_HSTRING_EXTDATA\nintroduced: 1.1.0\ndefault: false\ntags:\n  - memory\ndescription: >\n  Enable support for external strings.  An external string requires a Duktape\n  heap allocation to store a minimal string header, with the actual string\n  data being held behind a pointer (similarly to how dynamic buffers work).\n\n  This option is needed to use DUK_USE_EXTSTR_INTERN_CHECK and/or\n  DUK_USE_EXTSTR_FREE.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HSTRING_LAZY_CLEN.yaml",
    "content": "define: DUK_USE_HSTRING_LAZY_CLEN\nintroduced: 2.2.0\ndefault: true\ntags:\n  - performance\ndescription: >\n  When enabled, duk_hstring charlen is computed only when accessed; because\n  the charlen of most strings is not accessed during their lifetime, this\n  reduces unnecessary charlen calculations.  When disabled, charlen is computed\n  during interning which has smaller code footprint at slightly slower charlen\n  handling.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_HTML_COMMENTS.yaml",
    "content": "define: DUK_USE_HTML_COMMENTS\nintroduced: 2.1.0\ndefault: true\ntags:\n  - ecmascript2015\ndescription: >\n  Enable ES2015 Annex B.1.3 HTML comment syntax.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_IDCHAR_FASTPATH.yaml",
    "content": "define: DUK_USE_IDCHAR_FASTPATH\nintroduced: 1.5.0\ndefault: true\ntags:\n  - performance\n  - fastpath\n  - lowmemory\ndescription: >\n  Enable fast path for identifier start/part tables, which affect lexing and\n  JSON performance slightly at a small cost in footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_INJECT_HEAP_ALLOC_ERROR.yaml",
    "content": "define: DUK_USE_INJECT_HEAP_ALLOC_ERROR\nintroduced: 2.1.0\ndefault: false\ntags:\n  - development\ndescription: >\n  Force heap allocation to fail, value indicates the desired error position.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_INTEGER_BE.yaml",
    "content": "define: DUK_USE_INTEGER_BE\nintroduced: 1.0.0\nremoved: 1.4.0\ndefault: false\nconflicts:\n  - DUK_USE_INTEGER_LE\n  - DUK_USE_INTEGER_ME\ntags:\n  - portability\ndescription: >\n  Integer memory representation is big endian on the target platform.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_INTEGER_LE.yaml",
    "content": "define: DUK_USE_INTEGER_LE\nintroduced: 1.0.0\nremoved: 1.4.0\ndefault: true\nconflicts:\n  - DUK_USE_INTEGER_BE\n  - DUK_USE_INTEGER_ME\ntags:\n  - portability\ndescription: >\n  Integer memory representation is little endian on the target platform.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_INTEGER_ME.yaml",
    "content": "define: DUK_USE_INTEGER_ME\nintroduced: 1.0.0\nremoved: 1.4.0\ndefault: false\nconflicts:\n  - DUK_USE_INTEGER_LE\n  - DUK_USE_INTEGER_BE\ntags:\n  - portability\ndescription: >\n  Integer memory representation is mixed endian on the target platform.\n\n  This option is unused (and unsupported) because no target platform currently\n  needs this.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_INTERRUPT_COUNTER.yaml",
    "content": "define: DUK_USE_INTERRUPT_COUNTER\nintroduced: 1.1.0\nrelated:\n  - DUK_USE_DEBUGGER_SUPPORT\ndefault: false\ntags:\n  - execution\n  - debugger\ndescription: >\n  Enable the internal bytecode executor periodic interrupt counter.\n  The mechanism is used to implement e.g. execution step limit, custom\n  profiling, and debugger interaction.  Enabling the interrupt counter\n  has a small impact on execution performance.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_INTERRUPT_DEBUG_FIXUP.yaml",
    "content": "define: DUK_USE_INTERRUPT_DEBUG_FIXUP\nintroduced: 1.4.0\ndefault: false\ntags:\n  - development\ndescription: >\n  For Duktape development only: enable \"interrupt fixup\" in call handling\n  so that heap->inst_count_exec and heap->inst_count_interrupt can be\n  manually checked to match.  Only useful when debugging and/or asserts\n  are enabled.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_JC.yaml",
    "content": "define: DUK_USE_JC\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Enable support for the JC custom JSON format.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_JSON_BUILTIN.yaml",
    "content": "define: DUK_USE_JSON_BUILTIN\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Provide a JSON built-in.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_JSON_DECNUMBER_FASTPATH.yaml",
    "content": "define: DUK_USE_JSON_DECNUMBER_FASTPATH\nintroduced: 1.3.0\ndefault: true\ntags:\n  - performance\n  - fastpath\n  - lowmemory\ndescription: >\n  Enable fast path for decoding numbers in JSON.parse().  The fast path uses\n  a lookup table at a small cost in footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_JSON_DECSTRING_FASTPATH.yaml",
    "content": "define: DUK_USE_JSON_DECSTRING_FASTPATH\nintroduced: 1.3.0\ndefault: true\ntags:\n  - performance\n  - fastpath\n  - lowmemory\ndescription: >\n  Enable fast path for string decoding in JSON.parse().  The fast path uses\n  a lookup table at a small cost in footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_JSON_DEC_RECLIMIT.yaml",
    "content": "define: DUK_USE_JSON_DEC_RECLIMIT\nintroduced: 1.3.0\ndefault: 1000\ntags:\n  - portability\n  - cstackdepth\ndescription: >\n  Maximum native stack recursion for JSON decoding.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_JSON_EATWHITE_FASTPATH.yaml",
    "content": "define: DUK_USE_JSON_EATWHITE_FASTPATH\nintroduced: 1.3.0\ndefault: true\ntags:\n  - performance\n  - fastpath\n  - lowmemory\ndescription: >\n  Enable fast path for eating whitespace in JSON.parse().  The fast path uses\n  a lookup table at a small cost in footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_JSON_ENC_RECLIMIT.yaml",
    "content": "define: DUK_USE_JSON_ENC_RECLIMIT\nintroduced: 1.3.0\ndefault: 1000\ntags:\n  - portability\n  - cstackdepth\ndescription: >\n  Maximum native stack recursion for JSON encoding.\n\n  Must be higher than the internal DUK_JSON_ENC_LOOPARRAY define when\n  DUK_USE_JSON_STRINGIFY_FASTPATH is enabled.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_JSON_QUOTESTRING_FASTPATH.yaml",
    "content": "define: DUK_USE_JSON_QUOTESTRING_FASTPATH\nintroduced: 1.3.0\ndefault: true\ntags:\n  - performance\n  - fastpath\n  - lowmemory\ndescription: >\n  Enable fast path for string quoting in JSON.stringify().  The fast path uses\n  a lookup table at a small cost in footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_JSON_STRINGIFY_FASTPATH.yaml",
    "content": "define: DUK_USE_JSON_STRINGIFY_FASTPATH\nintroduced: 1.3.0\ndefault: false\ntags:\n  - performance\n  - fastpath\n  - lowmemory\ndescription: >\n  Enable fast path for JSON.stringify() serialization.  The fast path is used\n  when there is no \"replacer\" argument.  Indent argument and JX/JC format is\n  supported since Duktape 1.4.0.  The fast path increases code footprint by\n  roughly 1.5 kB but is up to 4-5x faster than the slow path.\n\n  Current limitation: assumes \"long long\" type exists (and covers duk_int64_t\n  range) and that sprintf() format string \"%lld\" works for \"long long\".\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_JSON_SUPPORT.yaml",
    "content": "define: DUK_USE_JSON_SUPPORT\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Enable JSON functionality, affects both ECMAScript and C APIs.\n  Note that disabling DUK_USE_JSON_BUILTIN still leaves the C API intact\n  and pulls in the JSON encoding/decoding functionality; disable this\n  option to remove that too.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_JX.yaml",
    "content": "define: DUK_USE_JX\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Enable support for the JX custom JSON format.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_LEXER_SLIDING_WINDOW.yaml",
    "content": "define: DUK_USE_LEXER_SLIDING_WINDOW\nintroduced: 1.3.0\ndefault: true\ntags:\n  - lowmemory\ndescription: >\n  Use a sliding window approach for managing the lexer codepoint lookup window\n  (recommended).  If disabled, the lexer uses a slower algorithm which has a\n  slightly smaller code and RAM footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_LIGHTFUNC_BUILTINS.yaml",
    "content": "define: DUK_USE_LIGHTFUNC_BUILTINS\nintroduced: 1.1.0\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Force built-in functions to be lightweight functions.  This reduces\n  memory footprint by around 14 kB at the cost of some non-compliant\n  behavior.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_LITCACHE_SIZE.yaml",
    "content": "define: DUK_USE_LITCACHE_SIZE\nintroduced: 2.3.0\ndefault: 256\ntags:\n  - performance\n  - lowmemory\ndescription: >\n  Size of the literal cache, which maps C literal memory addresses into\n  pinned duk_hstring heap object addresses.  The cache is used when\n  application code calls one of the duk_xxx_literal() API call variants,\n  such as duk_push_literal() or duk_get_prop_literal(), to speed up the\n  string intern check for the literal.  In successful cases this caching\n  makes using duk_xxx_literal() almost as fast as using borrowed heap\n  pointers with duk_xxx_heapptr().\n\n  When this option is defined, duk_hstrings related to literals encountered\n  in duk_xxx_literal() API calls are automatically pinned between\n  mark-and-sweep rounds.  This accomplishes two things.  First, it avoids the\n  need for cache invalidation for the literal cache in normal operation between\n  mark-and-sweep rounds.  Second, it reduces string table traffic (i.e. freeing\n  and reallocating) for literals which are likely to occur again and again.\n  However, the downside is that some strings that may occur only temporarily\n  will remain pinned until the next mark-and-sweep round.  If this matter, you\n  can avoid it by simply using e.g. duk_xxx_string() when dealing with such\n  strings.\n\n  The literal cache size must be a power of two (2^N).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_MARKANDSWEEP_FINALIZER_TORTURE.yaml",
    "content": "define: DUK_USE_MARKANDSWEEP_FINALIZER_TORTURE\nintroduced: 1.3.0\nremoved: 2.1.0\nrelated:\n  - DUK_USE_GC_TORTURE\n  - DUK_USE_REFZERO_FINALIZER_TORTURE\ndefault: false\ntags:\n  - gc\n  - memory\n  - development\n  - torture\ndescription: >\n  Development time option: simulate a fake finalizer call during every\n  mark-and-sweep round.  This is useful to detect bugs caused by finalizer\n  side effects.  Most useful when combined with DUK_USE_GC_TORTURE so that\n  potential finalizer side effects are realized on every allocation.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_MARK_AND_SWEEP.yaml",
    "content": "define: DUK_USE_MARK_AND_SWEEP\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: true\ntags:\n  - gc\n  - memory\ndescription: >\n  Enable mark-and-sweep garbage collection (recommended).\n\n  When disabled, only reference counting is used for garbage collection.\n  This reduces code footprint and eliminates garbage collection pauses, but\n  objects participating in unreachable reference cycles won't be collected\n  until the Duktape heap is destroyed.  In particular, function instances\n  won't be collected because they're always in a reference cycle with their\n  default prototype object.  Unreachable objects are collected if you break\n  reference cycles manually (and are always freed when a heap is destroyed).\n\n  NOTE: Removed in Duktape 2.0.0 because mark-and-sweep is no longer optional.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_MARK_AND_SWEEP_RECLIMIT.yaml",
    "content": "define: DUK_USE_MARK_AND_SWEEP_RECLIMIT\nintroduced: 1.3.0\ndefault: 256\ntags:\n  - portability\n  - cstackdepth\ndescription: >\n  Mark-and-sweep C recursion depth for marking phase; if reached,\n  mark object as a TEMPROOT and use multi-pass marking (slower but\n  same result).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_MATH_BUILTIN.yaml",
    "content": "define: DUK_USE_MATH_BUILTIN\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Provide a Math built-in.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_MATH_FMAX.yaml",
    "content": "define: DUK_USE_MATH_FMAX\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: true\ntags:\n  - portability\ndescription: >\n  Assume platform function fmax() is available and works correctly.\n  Some platforms don't have fmax() (it is defined in C99) and on some\n  platforms (e.g. some uclibc environments) it may not be provided even\n  though the compilation environment is nominally C99.\n\n  Removed in Duktape 2.0.0: if the platform doesn't have fmax(), simply\n  define a replacement for DUK_FMAX().\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_MATH_FMIN.yaml",
    "content": "define: DUK_USE_MATH_FMIN\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: true\ntags:\n  - portability\ndescription: >\n  Assume platform function fmin() is available and works correctly.\n  Some platforms don't have fmin() (it is defined in C99) and on some\n  platforms (e.g. some uclibc environments) it may not be provided even\n  though the compilation environment is nominally C99.\n\n  Removed in Duktape 2.0.0: if the platform doesn't have fmin(), simply\n  define a replacement for DUK_FMIN().\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_MATH_ROUND.yaml",
    "content": "define: DUK_USE_MATH_ROUND\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: true\ntags:\n  - portability\ndescription: >\n  Assume platform function round() is available and works correctly.\n  Some platforms don't have round() (it is defined in C99) and on some\n  platforms (e.g. some uclibc environments) it may not be provided even\n  though the compilation environment is nominally C99.\n\n  Removed in Duktape 2.0.0: if the platform doesn't have round(), simply\n  define a replacement for DUK_ROUND().  Currently DUK_ROUND() isn't used\n  at all however.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_MS_STRINGTABLE_RESIZE.yaml",
    "content": "define: DUK_USE_MS_STRINGTABLE_RESIZE\nintroduced: 1.0.0\nremoved: 2.1.0\ndefault: true\ntags:\n  - gc\n  - memory\ndescription: >\n  Enable forced string intern table resize during mark-and-sweep garbage\n  collection.  This is the recommended behavior.\n\n  It may be useful to disable this option when reference counting is disabled,\n  as mark-and-sweep collections will be more frequent and thus more expensive.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_NATIVE_CALL_RECLIMIT.yaml",
    "content": "define: DUK_USE_NATIVE_CALL_RECLIMIT\nintroduced: 1.3.0\ndefault: 1000\ntags:\n  - portability\n  - cstackdepth\ndescription: >\n  Maximum duk_handle_call() / duk_handle_safe_call() C recursion limit.\n  Note that this does not limit bytecode executor internal call depth at\n  all (e.g. for ECMAScript-to-ECMAScript calls, thread yields/resumes, etc).\n  There is a separate callstack depth limit for threads which is independent\n  of this limit.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_NATIVE_STACK_CHECK.yaml",
    "content": "define: DUK_USE_NATIVE_STACK_CHECK\nintroduced: 2.4.0\ndefault: false\ntags:\n  - portability\n  - execution\ndescription: >\n  Provide a macro hook to check for available native stack space for the\n  currently executing native thread.  The macro must evaluate to zero if\n  there is enough stack space available and non-zero otherwise; a RangeError\n  will then be thrown.\n\n  The definition of \"enough space\" depends on the target platform and the\n  compiler because the size of native stack frames cannot be easily known\n  in advance.  As a relatively safe estimate, one can check for 8kB of\n  available stack.\n\n  Duktape doesn't call this macro for every internal native call.  The macro\n  is called in code paths that are involved in potentially unlimited\n  recursion (such as making Ecmascript/native function calls, invoking\n  getters and Proxy traps, and resolving Proxy chains) and code paths\n  requiring a lot of stack space temporarily.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER.yaml",
    "content": "define: DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER\nintroduced: 1.0.0\nremoved: 2.3.0\ndefault: true\ntags:\n  - ecmascript\n  - compliance\ndescription: >\n  In ES5.1 trailing gaps of an argument array don't count towards the result\n  length.  This is in essence a specification \"bug\" which was fixed in ES2015.\n  This option was removed in 2.3.0, and the remaining behavior matches ES2015.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_NONSTD_ARRAY_MAP_TRAILER.yaml",
    "content": "define: DUK_USE_NONSTD_ARRAY_MAP_TRAILER\nintroduced: 1.0.0\nremoved: 2.3.0\ndefault: true\ntags:\n  - ecmascript\n  - compliance\ndescription: >\n  This option was removed in 2.3.0 as it was unnecessary and in essence fixing\n  a Duktape bug.  ES5.0/ES5.1 already behave like ES2015 in that trailing gaps\n  in the input don't affect the result length.  The result array is created\n  with a length based on the input array in Step 6 of ES5.1 Section 15.4.4.19\n  and subsequent index writes don't affect the length.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT.yaml",
    "content": "define: DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\n  - compliance\ndescription: >\n  For better compatibility with existing code, enable non-standard\n  Array.prototype.splice() behavior when the second argument (deleteCount)\n  is not given: the splice operation is extended to the end of the array, see\n  https://github.com/svaarala/duktape/blob/master/tests/ecmascript/test-bi-array-proto-splice-no-delcount.js.\n\n  If this option is disabled, splice() will behave in a strictly conforming\n  fashion, treating a missing deleteCount the same as an undefined (or 0)\n  value.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_NONSTD_FUNC_CALLER_PROPERTY.yaml",
    "content": "define: DUK_USE_NONSTD_FUNC_CALLER_PROPERTY\nintroduced: 1.0.0\ndefault: false\ntags:\n  - ecmascript\n  - compliance\ndescription: >\n  Add a non-standard \"caller\" property to non-strict function instances\n  for better compatibility with existing code.  The semantics of this\n  property are not standardized and may vary between engines; Duktape tries\n  to behave close to V8 and Spidermonkey.  See\n  https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller\n  description of the property.  This feature disables tail call support.\n\n  This feature conflicts with several other features, so you should use it\n  only if it's absolutely necessary.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY.yaml",
    "content": "define: DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY\nintroduced: 1.0.0\ndefault: false\ntags:\n  - ecmascript\n  - compliance\ndescription: >\n  Add a non-standard \"source\" property to function instances.  This allows\n  function toString() to print out the actual function source.  The property\n  is disabled by default because it increases memory footprint.\n\n  NOTE: Unimplemented as of Duktape 1.3.0.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_NONSTD_FUNC_STMT.yaml",
    "content": "define: DUK_USE_NONSTD_FUNC_STMT\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\n  - compliance\ndescription: >\n  Enable support for function declarations outside program or function top\n  level (also known as \"function statements\").  Such declarations are\n  non-standard and the strictly compliant behavior is to treat them as a\n  SyntaxError.  When this option is enabled (recommended), Duktape behavior\n  is to treat them like ordinary function declarations (\"hoist\" them to\n  function top) with V8-like semantics.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_NONSTD_GETTER_KEY_ARGUMENT.yaml",
    "content": "define: DUK_USE_NONSTD_GETTER_KEY_ARGUMENT\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\n  - compliance\ndescription: >\n  Give getter calls the accessed property name as an additional non-standard\n  argument.  This allows a single getter function to be reused for multiple\n  properties more easily.  See\n  http://duktape.org/guide.html#propertyvirtualization.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_NONSTD_JSON_ESC_U2028_U2029.yaml",
    "content": "define: DUK_USE_NONSTD_JSON_ESC_U2028_U2029\nintroduced: 1.1.0\ndefault: true\ntags:\n  - ecmascript\n  - compliance\ndescription: >\n  When enabled, Duktape JSON.stringify() will escape U+2028 and U+2029 which\n  is non-compliant behavior.  This is recommended to make JSON.stringify()\n  output valid when embedded in a web page or parsed with eval().\n\n  When disabled, Duktape provides the compliant behavior, i.e. no escaping\n  for U+2028 and U+2029.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_NONSTD_REGEXP_DOLLAR_ESCAPE.yaml",
    "content": "define: DUK_USE_NONSTD_REGEXP_DOLLAR_ESCAPE\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: true\ntags:\n  - ecmascript\n  - compliance\ndescription: >\n  Replaced by DUK_USE_ES6_REGEXP_SYNTAX.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_NONSTD_SETTER_KEY_ARGUMENT.yaml",
    "content": "define: DUK_USE_NONSTD_SETTER_KEY_ARGUMENT\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\n  - compliance\ndescription: >\n  Give setter calls the accessed property name as an additional non-standard\n  argument.  This allows a single setter function to be reused for multiple\n  properties more easily.  See\n  http://duktape.org/guide.html#propertyvirtualization.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT.yaml",
    "content": "define: DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT\nintroduced: 1.2.0\ndefault: true\ntags:\n  - ecmascript\n  - compliance\ndescription: >\n  Allow 32-bit codepoints in String.fromCharCode().  This is non-compliant\n  (the E5.1 specification has a ToUint16() coercion for the codepoints) but\n  useful because Duktape supports non-BMP strings.\n\n  When disabled, Duktape provides the compliant behavior.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_NO_DOUBLE_ALIASING_SELFTEST.yaml",
    "content": "define: DUK_USE_NO_DOUBLE_ALIASING_SELFTEST\nintroduced: 1.0.0\nremoved: 1.4.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Disable double aliasing selftest (if self tests enabled).\n\n  Double aliasing testcase fails when Emscripten-generated code is run.\n  This is not fatal because it only affects packed duk_tval which we\n  avoid with Emscripten.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_NUMBER_BUILTIN.yaml",
    "content": "define: DUK_USE_NUMBER_BUILTIN\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Provide a Number built-in.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_OBJECT_BUILTIN.yaml",
    "content": "define: DUK_USE_OBJECT_BUILTIN\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Provide an Object built-in.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_OBJSIZES16.yaml",
    "content": "define: DUK_USE_OBJSIZES16\nintroduced: 1.1.0\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use a 16-bit object entry and array part sizes (for low memory\n  environments).  Also automatically drops support for an object hash part\n  to further reduce memory usage; there are rarely large objects in low\n  memory environments simply because there's no memory to store a lot of\n  properties.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_OCTAL_SUPPORT.yaml",
    "content": "define: DUK_USE_OCTAL_SUPPORT\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Enable optional octal number support (ECMAScript E5/E5.1\n  Annex B: http://www.ecma-international.org/ecma-262/5.1/#sec-B).\n  Recommended because existing code bases use octal numbers.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_OS_STRING.yaml",
    "content": "define: DUK_USE_OS_STRING\nintroduced: 1.0.0\ndefault:\n  string: \"unknown\"\ntags:\n  - portability\ndescription: >\n  Human-readable operating system string used in e.g. Duktape.env and debugger\n  protocol (example: linux).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PACKED_TVAL.yaml",
    "content": "define: DUK_USE_PACKED_TVAL\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use a packed 8-byte representation for duk_tval.  The packed representation\n  represents non-number values as special IEEE double NaN values, and is only\n  possible for platforms with 32-bit pointers.  When the packed representation\n  is not available, Duktape uses a 12-16 byte struct/union which is more\n  portable.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PACKED_TVAL_POSSIBLE.yaml",
    "content": "define: DUK_USE_PACKED_TVAL_POSSIBLE\nintroduced: 1.0.0\nremoved: 1.4.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Define when packed, 8-byte duk_tval representation is possible.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PACK_CLANG_ATTR.yaml",
    "content": "define: DUK_USE_PACK_CLANG_ATTR\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use clang-specific attribute to force struct packing.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PACK_DUMMY_MEMBER.yaml",
    "content": "define: DUK_USE_PACK_DUMMY_MEMBER\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use dummy struct member to force struct packing.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PACK_GCC_ATTR.yaml",
    "content": "define: DUK_USE_PACK_GCC_ATTR\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use gcc-specific attribute to force struct packing.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PACK_MSVC_PRAGMA.yaml",
    "content": "define: DUK_USE_PACK_MSVC_PRAGMA\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use msvc-specific attribute to force struct packing.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PANIC_ABORT.yaml",
    "content": "define: DUK_USE_PANIC_ABORT\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: true\ntags:\n  - portability\ndescription: >\n  Call abort() when the default panic handler is invoked.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PANIC_EXIT.yaml",
    "content": "define: DUK_USE_PANIC_EXIT\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Call exit() when the default panic handler is invoked.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PANIC_HANDLER.yaml",
    "content": "define: DUK_USE_PANIC_HANDLER\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Provide a custom panic handler.  A custom panic handler is recommended for\n  any environment where recovery from fatal errors is important.  A custom\n  handler can take appropriate action to recover, e.g. record the error and\n  reboot the target device.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PANIC_SEGFAULT.yaml",
    "content": "define: DUK_USE_PANIC_SEGFAULT\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Cause an intentional segfault when the default panic handler is invoked.\n  This is useful when debugging with valgrind because a segfault provides\n  a nice C traceback in valgrind.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PARANOID_DATE_COMPUTATION.yaml",
    "content": "define: DUK_USE_PARANOID_DATE_COMPUTATION\nintroduced: 1.0.0\ndefault: false  # XXX: make default detect C99/C++11?\ntags:\n  - portability\ndescription: >\n  There was a curious bug where test-bi-date-canceling.js would fail e.g.\n  on 64-bit Ubuntu, gcc-4.8.1, -m32, and no -std=c99.  Some date computations\n  using doubles would be optimized which then broke some corner case tests.\n  The problem goes away by adding 'volatile' to the datetime computations.\n  Not sure what the actual triggering conditions are, but using this on\n  non-C99 systems solves the known issues and has relatively little cost\n  on other platforms.\n\n  Recommended for non-C99 platforms.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PARANOID_ERRORS.yaml",
    "content": "define: DUK_USE_PARANOID_ERRORS\nintroduced: 1.4.0\ndefault: false\ntags:\n  - ecmascript\n  - sandbox\ndescription: >\n  When enabled, error messages won't involve summarization of keys or values.\n  Summaries may be an issue in some security sensitive environments because\n  error messages will include e.g. property keys.\n\n  The default is to summarize offending base value and key for property access\n  errors such as \"null.foo = 123;\", invalid calls such as \"undefined()\", etc.\n  Base values and keys are summarized using duk_push_string_tval_readable().\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PARANOID_MATH.yaml",
    "content": "define: DUK_USE_PARANOID_MATH\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Rely as little as possible on compiler behavior for NaN comparison,\n  signed zero handling, etc.  May be needed for (very) broken compilers.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PC2LINE.yaml",
    "content": "define: DUK_USE_PC2LINE\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Record a \"pc2line\" map into function instances which allows bytecode program\n  counter values to be mapped into line numbers e.g. in error tracebacks.\n\n  Without this map, exceptions won't have meaningful line numbers but function\n  instances will have a smaller footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PERFORMANCE_BUILTIN.yaml",
    "content": "define: DUK_USE_PERFORMANCE_BUILTIN\nintroduced: 2.2.0\ndefault: true\ntags:\n  - performance-api\ndescription: >\n  Provide a 'performance' global object based on https://www.w3.org/TR/hr-time/.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_POW_NETBSD_WORKAROUND.yaml",
    "content": "define: DUK_USE_POW_NETBSD_WORKAROUND\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  NetBSD 6.0 x86 (at least) has a few problems with pow() semantics,\n  see test-bug-netbsd-math-pow.js.  Use NetBSD specific workaround.\n\n  (This might be a wider problem; if so, generalize the define name.)\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_POW_WORKAROUNDS.yaml",
    "content": "define: DUK_USE_POW_WORKAROUNDS\nintroduced: 2.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Enable workarounds to common pow() semantics issues.  At least NetBSD\n  6.0 x86 and Cygwin/MinGW have such issues, see test-bug-netbsd-math-pow.js\n  and test-bug-mingw-math-issues.js.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PREFER_SIZE.yaml",
    "content": "define: DUK_USE_PREFER_SIZE\nintroduced: 1.2.0\ndefault: false\ntags:\n  - lowmemory\ndescription: >\n  Catch-all flag which can be used to choose between variant algorithms\n  where a speed-size tradeoff exists (e.g. lookup tables).  When it really\n  matters, specific use flags may be appropriate.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PROMISE_BUILTIN.yaml",
    "content": "define: DUK_USE_PROMISE_BUILTIN\nintroduced: 2.2.0\ndefault: false  # disabled until fully functional\ntags:\n  - ecmascript\ndescription: >\n  Enable Promise built-in.\n\n  At present entirely non-functional, and disabled by default.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS.yaml",
    "content": "define: DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS\nintroduced: 1.0.0\ndefault: true\ntags:\n  - portability\ndescription: >\n  Provide default allocation functions.\n\n  At the moment this option should be enabled.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_RDTSC.yaml",
    "content": "define: DUK_USE_RDTSC\nintroduced: 1.3.0\nremoved: 1.4.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Macro to provide an x86/x64 RDTSC timestamp for debug prints.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_REFCOUNT16.yaml",
    "content": "define: DUK_USE_REFCOUNT16\nintroduced: 1.1.0\ndefault: false\ntags:\n  - lowmemory\n  - experimental\n  - gc\ndescription: >\n  Use a 16-bit reference count field (for low memory environments).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_REFCOUNT32.yaml",
    "content": "define: DUK_USE_REFCOUNT32\nintroduced: 2.1.0\ndefault: true\ntags:\n  - gc\ndescription: >\n  Use a 32-bit reference count field.\n\n  While on some 64-bit systems it's theoretically possible to wrap a 32-bit\n  counter field, assuming a 16-byte duk_tval the Duktape heap would have to\n  be larger than 64GB for that to happen.  Because of this the default is to\n  use a 32-bit refcount field.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_REFERENCE_COUNTING.yaml",
    "content": "define: DUK_USE_REFERENCE_COUNTING\nintroduced: 1.0.0\ndefault: true\ntags:\n  - gc\ndescription: >\n  Use reference counting for garbage collection.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_REFLECT_BUILTIN.yaml",
    "content": "define: DUK_USE_REFLECT_BUILTIN\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript2015\ndescription: >\n  Provide a Reflect built-in.  The ES6 Reflect object provides a collection of\n  methods for examining and manipulating objects at runtime.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_REFZERO_FINALIZER_TORTURE.yaml",
    "content": "define: DUK_USE_REFZERO_FINALIZER_TORTURE\nintroduced: 1.3.0\nremoved: 2.1.0\nrelated:\n  - DUK_USE_MARKANDSWEEP_FINALIZER_TORTURE\ndefault: false\ntags:\n  - gc\n  - memory\n  - development\n  - torture\ndescription: >\n  Development time option: simulate a fake finalizer call for every object\n  going through refzero freeing.  This is useful to detect bugs caused by\n  finalizer side effects in e.g. call handling.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_REGEXP_CANON_BITMAP.yaml",
    "content": "define: DUK_USE_REGEXP_CANON_BITMAP\nintroduced: 2.2.0\ndefault: true\ntags:\n  - performance\n  - unicode\ndescription: >\n  Use a small lookup table (footprint impact is ~300-400 bytes) to speed up\n  case insensitive RegExp canonicalization.  The result is still much slower\n  than with DUK_USE_REGEXP_CANON_WORKAROUND but ~50x faster than without the\n  lookup.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_REGEXP_CANON_WORKAROUND.yaml",
    "content": "define: DUK_USE_REGEXP_CANON_WORKAROUND\nintroduced: 1.4.0\ndefault: false\ntags:\n  - performance\n  - unicode\n  - experimental\ndescription: >\n  Use a 128kB lookup table for RegExp codepoint canonicalization to improve\n  performance of case insensitive RegExp handling.\n\n  This is a temporary workaround until there's better support for faster\n  Unicode handling.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_REGEXP_COMPILER_RECLIMIT.yaml",
    "content": "define: DUK_USE_REGEXP_COMPILER_RECLIMIT\nintroduced: 1.3.0\ndefault: 10000\ntags:\n  - portability\n  - cstackdepth\ndescription: >\n  RegExp compiler native call stack recursion limit.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_REGEXP_EXECUTOR_RECLIMIT.yaml",
    "content": "define: DUK_USE_REGEXP_EXECUTOR_RECLIMIT\nintroduced: 1.3.0\ndefault: 10000\ntags:\n  - portability\n  - cstackdepth\ndescription: >\n  RegExp executor native call stack recursion limit.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_REGEXP_SUPPORT.yaml",
    "content": "define: DUK_USE_REGEXP_SUPPORT\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\n  - lowmemory\ndescription: >\n  Enable support for regular expressions (recommended).\n\n  When disabled, regexp literals are treated as a SyntaxError, RegExp\n  constructor and prototype functions throw an error,\n  String.prototype.replace() throws an error if given a regexp search value,\n  String.prototype.split() throws an error if given a regexp separator value,\n  String.prototype.search() and String.prototype.match() throw an error\n  unconditionally.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_REPL_FPCLASSIFY.yaml",
    "content": "define: DUK_USE_REPL_FPCLASSIFY\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Provide a built-in replacement for fpclassify(), duk_repl_fpclassify.\n\n  When enabled, define DUK_FPCLASSIFY as duk_repl_fpclassify.\n\n# XXX: the dependency between DUK_USE_REPL_FPCLASSIFY and DUK_FPCLASSIFY\n# is a bit awkward.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_REPL_ISFINITE.yaml",
    "content": "define: DUK_USE_REPL_ISFINITE\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Provide a built-in replacement for isfinite(), duk_repl_isfinite.\n\n  When enabled, define DUK_ISFINITE as duk_repl_isfinite.\n\n# XXX: the dependency between DUK_USE_REPL_ISFINITE and DUK_ISFINITE\n# is a bit awkward.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_REPL_ISINF.yaml",
    "content": "define: DUK_USE_REPL_ISINF\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Provide a built-in replacement for isinf(), duk_repl_isinf.\n\n  When enabled, define DUK_ISINF as duk_repl_isinf.\n\n# XXX: the dependency between DUK_USE_REPL_ISINF and DUK_ISINF\n# is a bit awkward.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_REPL_ISNAN.yaml",
    "content": "define: DUK_USE_REPL_ISNAN\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Provide a built-in replacement for isnan(), duk_repl_isnan.\n\n  When enabled, define DUK_ISNAN as duk_repl_isnan.\n\n# XXX: the dependency between DUK_USE_REPL_ISNAN and DUK_ISNAN\n# is a bit awkward.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_REPL_SIGNBIT.yaml",
    "content": "define: DUK_USE_REPL_SIGNBIT\nintroduced: 1.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Provide a built-in replacement for signbit(), duk_repl_signbit.\n\n  When enabled, define DUK_SIGNBIT as duk_repl_signbit.\n\n# XXX: the dependency between DUK_USE_REPL_SIGNBIT and DUK_SIGNBIT\n# is a bit awkward.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ROM_GLOBAL_CLONE.yaml",
    "content": "define: DUK_USE_ROM_GLOBAL_CLONE\nintroduced: 1.5.0\nrequires:\n  - DUK_USE_ROM_STRINGS\n  - DUK_USE_ROM_OBJECTS\nconflicts:\n  - DUK_USE_ROM_GLOBAL_INHERIT\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  When using ROM built-in objects, create a RAM-based global object by copying\n  the properties of the ROM-based global object into a fresh empty object.\n\n  Having a writable global object is usually expected; if the global object is\n  not writable, it's not possible to e.g. declare functions outside of CommonJS\n  modules.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ROM_GLOBAL_INHERIT.yaml",
    "content": "define: DUK_USE_ROM_GLOBAL_INHERIT\nintroduced: 1.5.0\nrequires:\n  - DUK_USE_ROM_STRINGS\n  - DUK_USE_ROM_OBJECTS\nconflicts:\n  - DUK_USE_ROM_GLOBAL_CLONE\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  When using ROM built-in objects, create a RAM-based global object by creating\n  a fresh empty object which inherits from the ROM-based global object.  This\n  provides all the standard bindings with a small RAM footprint cost, but still\n  allows the global object to be extended and existing bindings overwritten\n  (but not deleted).  The downside of this compared to cloning a global object\n  is that the inheritance is not fully transparent and the result is less\n  compliant.\n\n  Having a writable global object is usually expected; if the global object is\n  not writable, it's not possible to e.g. declare functions outside of CommonJS\n  modules.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ROM_OBJECTS.yaml",
    "content": "define: DUK_USE_ROM_OBJECTS\nintroduced: 1.5.0\nrequires:\n  - DUK_USE_ROM_STRINGS  # use both DUK_USE_ROM_STRINGS + DUK_USE_ROM_OBJECTS together for now\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Enable support for built-in objects compiled as constants and placed in a\n  read-only data section.  This reduces startup RAM usage considerably at the\n  cost of a larger code footprint and slower performance overall.  The built-in\n  objects will be immutable: the objects will be non-extensible.\n\n  ROM objects will always be non-extensible and properties are forced to be\n  non-configurable.  Other property attributes will have their usual values;\n  in particular, properties can be \"writable\" from a property attributes\n  standpoint, but an attempt to actually change the property value will fail\n  with a TypeError.  This may seem strange, but is necessary to allow a\n  property value to be overridden in a RAM object inheriting from a ROM object:\n  if the inherited ROM property was not writable, ECMAScript semantics would\n  prevent a new property from being established in the RAM object.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ROM_PTRCOMP_FIRST.yaml",
    "content": "define: DUK_USE_ROM_PTRCOMP_FIRST\nintroduced: 1.5.0\nrelated:\n  - DUK_USE_ROM_STRINGS\n  - DUK_USE_ROM_OBJECTS\ndefault: 0xf800\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  When using ROM pointer compression ROM pointers are compressed to the\n  integer range [DUK_USE_ROM_PTRCOMP_FIRST,0xffff].  The default value\n  allows for 2048 ROM pointers, which can point to objects and strings.\n\n  You may need to lower this value to support more pointers if there are\n  a lot of custom ROM strings/objects.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ROM_STRINGS.yaml",
    "content": "define: DUK_USE_ROM_STRINGS\nintroduced: 1.5.0\nrequires:\n  - DUK_USE_ROM_OBJECTS  # use both DUK_USE_ROM_STRINGS + DUK_USE_ROM_OBJECTS together for now\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Enable support for built-in (and optional user-supplied strings) which are\n  compiled as constants and placed in a read-only data section.  This reduces\n  startup RAM usage considerably at the cost of a larger code footprint and\n  slower string interning.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_SECTION_B.yaml",
    "content": "define: DUK_USE_SECTION_B\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Enable optional features in ECMAScript specification\n  Annex B: http://www.ecma-international.org/ecma-262/5.1/#sec-B.\n\n  When disabled, escape(), unescape(), and String.prototype.substr()\n  throw an error.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_SELF_TESTS.yaml",
    "content": "define: DUK_USE_SELF_TESTS\nintroduced: 1.0.0\ndefault: false\ntags:\n  - debug\ndescription: >\n  Perform run-time self tests when a Duktape heap is created.  Catches\n  platform/compiler problems which cannot be reliably detected during\n  compile time.  Not enabled by default because of the extra footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_SETJMP.yaml",
    "content": "define: DUK_USE_SETJMP\nintroduced: 1.1.0\nremoved: 1.5.0\ndefault: true\ntags:\n  - portability\ndescription: >\n  Use setjmp/longjmp for long control transfers.  This is the most portable\n  option for long control transfers.\n\n  The downside of setjmp/longjmp is that signal mask saving behavior is not\n  specified and varies between platforms.  Signal mask saving may have a\n  significant performance impact so you may want to force a specific provider\n  if performance matters for your application.  (This is the case for OSX,\n  for instance.)\n\n  Removed in Duktape 1.5.0: edit duk_config.h directly.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_SHEBANG_COMMENTS.yaml",
    "content": "define: DUK_USE_SHEBANG_COMMENTS\nintroduced: 2.1.0\ndefault: true\ntags:\n  - ecmascript2015\ndescription: >\n  Support parsing of a \"shebang\" comment ('#!...') on the first line of\n  source text.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_SHUFFLE_TORTURE.yaml",
    "content": "define: DUK_USE_SHUFFLE_TORTURE\nintroduced: 1.2.0\ndefault: false\ntags:\n  - gc\n  - memory\n  - development\n  - torture\ndescription: >\n  Development time option: force compiler to shuffle every possible opcode\n  to stress shuffle behavior which is otherwise difficult to test for\n  comprehensively.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_SIGSETJMP.yaml",
    "content": "define: DUK_USE_SIGSETJMP\nintroduced: 1.1.0\nremoved: 1.5.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use sigsetjmp/siglongjmp with savesigs == 0 for long control\n  transfers (i.e. signal mask not saved/restored).  See comments in\n  DUK_USE_SETJMP.\n\n  Removed in Duktape 1.5.0: edit duk_config.h directly.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_SOURCE_NONBMP.yaml",
    "content": "define: DUK_USE_SOURCE_NONBMP\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\n  - lowmemory\ndescription: >\n  Enable accurate Unicode support for non-BMP characters in source code.\n\n  When disabled non-BMP characters are always accepted as identifier\n  characters.  Disabling this option saves a little bit of code footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRHASH16.yaml",
    "content": "define: DUK_USE_STRHASH16\nintroduced: 1.1.0\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use a 16-bit string hash field (for low memory environments).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRHASH_DENSE.yaml",
    "content": "define: DUK_USE_STRHASH_DENSE\nintroduced: 1.4.0\ndefault: false\ntags:\n  - performance\n  - sandbox\ndescription: >\n  Use the slower but more dense string hash algorithm from Duktape 1.3.0 and\n  prior (based on Murmurhash2).  This may be useful if you're experiencing\n  collision issues with the default hash algorithm.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRHASH_SKIP_SHIFT.yaml",
    "content": "define: DUK_USE_STRHASH_SKIP_SHIFT\nintroduced: 1.4.0\ndefault: 5\ntags:\n  - performance\ndescription: >\n  Shift value to use for string hash skip offset when using the default\n  (fast) string hash.  The skip offset is calculated as:\n  ((length >> DUK_USE_STRHASH_SKIP_SHIFT) + 1).  A higher value will be\n  slower but sample the string more densely.\n\n  You should only change this if you run into issues with the default value.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRICT_DECL.yaml",
    "content": "define: DUK_USE_STRICT_DECL\nintroduced: 1.1.0\ndefault: true\ntags:\n  - ecmascript\n  - experimental\ndescription: >\n  Enable support for \"use strict\" declaration (recommended).\n\n  When disabled, ECMAScript code is always executed in non-strict mode.\n  Duktape/C functions remain strict.  This option is useful in some legacy\n  environments where \"use strict\" declarations are used in existing code\n  base but the Javascript engine didn't actually support strict mode.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRICT_UTF8_SOURCE.yaml",
    "content": "define: DUK_USE_STRICT_UTF8_SOURCE\nintroduced: 1.0.0\ndefault: false\ntags:\n  - ecmascript\ndescription: >\n  Enable strict UTF-8 parsing of source code.\n\n  When disabled, non-shortest encodings (normally invalid UTF-8) and surrogate\n  pair codepoints are accepted as valid source code characters.  Disabling\n  this option breaks compatibility with some test262 tests.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRING_BUILTIN.yaml",
    "content": "define: DUK_USE_STRING_BUILTIN\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Provide a String built-in.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRLEN16.yaml",
    "content": "define: DUK_USE_STRLEN16\nintroduced: 1.1.0\ndefault: false\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use a 16-bit string length field (for low memory environments).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRTAB_CHAIN.yaml",
    "content": "define: DUK_USE_STRTAB_CHAIN\nintroduced: 1.1.0\nremoved: 2.1.0\nrelated:\n  - DUK_USE_STRTAB_CHAIN_SIZE\ndefault: false\ntags:\n  - lowmemory\ndescription: >\n  Replace the default (open addressing, probing) string table structure with\n  one based on separate chaining.  There is a fixed-size top level hash table\n  (whose size is defined using DUK_USE_STRTAB_CHAIN_SIZE), with each entry in\n  the hash table being: (a) NULL, (b) a duk_hstring pointer, or (c) a pointer\n  to an array of duk_hstring pointers.  The pointer arrays are gappy (the gaps\n  are reused on new inserts) and are never shrunk at the moment.\n\n  This option is intended for low memory environments to make Duktape's memory\n  behavior match a typical pool-based allocator better as follows:\n\n  The top level fixed structure never changes size, so there is no hash table\n  resize, and thus no need for resize temporaries.  The default string table\n  algorithm needs resizing from time to time and doesn't resize in place, so\n  you effectively need twice the string table size temporarily during a resize.\n\n  The pointer arrays vary in size, but their size (typically 8 to 64 bytes,\n  depending on the load factor) matches that of many other allocations which\n  works well with a pooled allocator.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRTAB_CHAIN_SIZE.yaml",
    "content": "define: DUK_USE_STRTAB_CHAIN_SIZE\nintroduced: 1.1.0\nremoved: 2.1.0\nrequires:\n  - DUK_USE_STRTAB_CHAIN\ndefault: false\ntags:\n  - lowmemory\ndescription: >\n  Define stringtable size for DUK_USE_STRTAB_CHAIN.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRTAB_GROW_LIMIT.yaml",
    "content": "define: DUK_USE_STRTAB_GROW_LIMIT\nintroduced: 2.1.0\ndefault: 17  # 17/16 = 1.0625\ntags:\n  - performance\n  - lowmemory\ndescription: >\n  Grow top level strtable allocation when load factor reaches this value.\n  Expressed as a .4 fixed point; the load factor is computed as\n  floor((count / size) * 16.0), e.g. 32 means a load factor of 2.0.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRTAB_MAXSIZE.yaml",
    "content": "define: DUK_USE_STRTAB_MAXSIZE\nintroduced: 2.1.0\ndefault: 268435456\ntags:\n  - performance\n  - lowmemory\ndescription: >\n  Maximum size for Duktape heap string table, must be 2^N, and small enough\n  so that if the value is multiplied by sizeof(duk_hstring *) it won't overflow\n  duk_size_t.\n\n  To avoid resizing the strtable at all, set DUK_USE_STRTAB_MINSIZE and\n  DUK_USE_STRTAB_MAXSIZE to the same value.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRTAB_MINSIZE.yaml",
    "content": "define: DUK_USE_STRTAB_MINSIZE\nintroduced: 2.1.0\ndefault: 1024\ntags:\n  - performance\n  - lowmemory\ndescription: >\n  Minimum size for Duktape heap string table, must be 2^N, and should never\n  be lower than 64.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRTAB_PROBE.yaml",
    "content": "define: DUK_USE_STRTAB_PROBE\nintroduced: 1.1.0\nremoved: 2.1.0\ndefault: true\ntags:\n  - lowmemory\ndescription: >\n  Use the default open addressing (probing) based string table algorithm.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRTAB_PTRCOMP.yaml",
    "content": "define: DUK_USE_STRTAB_PTRCOMP\nintroduced: 2.1.0\ndefault: false\nrequires:\n  - DUK_USE_HEAPPTR16\ntags:\n  - performance\n  - lowmemory\ndescription: >\n  Pointer compress the top level heap->strtable[] string table.  On 32-bit\n  targets this saves 2 bytes per entry, e.g. for 256 entries 0.5kB.  However,\n  the additional pointer compression code increases footprint by 200-300\n  bytes.  The option also reduces performance a little bit, so this should\n  be enabled when RAM is much more constrained than ROM.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRTAB_RESIZE_CHECK_MASK.yaml",
    "content": "define: DUK_USE_STRTAB_RESIZE_CHECK_MASK\nintroduced: 2.1.0\ndefault: 255\ntags:\n  - performance\n  - lowmemory\ndescription: >\n  Somewhat technical: bit mask (must be 2^N-1) used against heap->st_count to\n  determine the interval between string table resize checks.  A resize check\n  is made when heap->st_count & DUK_USE_STRTAB_RESIZE_CHECK_MASK is zero.\n\n  A large value makes string table grow/shrink checks less frequent.  Usually\n  this has very little practical impact on memory performance.  There are\n  corner cases, such as dereferencing a large number of strings simultaneously,\n  where this parameter affects how many new strings need to be inserted before\n  the string table shrinks to a more appropriate size.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRTAB_SHRINK_LIMIT.yaml",
    "content": "define: DUK_USE_STRTAB_SHRINK_LIMIT\nintroduced: 2.1.0\ndefault: 6  # 6/16 = 0.375\ntags:\n  - performance\n  - lowmemory\ndescription: >\n  Shrink top level strtable allocation when load factor reaches this value.\n  Expressed as a .4 fixed point; the load factor is computed as\n  floor((count / size) * 16.0), e.g. 8 means a load factor of 0.5.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_STRTAB_TORTURE.yaml",
    "content": "define: DUK_USE_STRTAB_TORTURE\nintroduced: 2.1.0\ndefault: false\ntags:\n  - torture\ndescription: >\n  Resize string table (grow, shrink back) for every intern.  Ensures string\n  table chaining is correct, and resize side effects are exercised on every\n  resize.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_SYMBOL_BUILTIN.yaml",
    "content": "define: DUK_USE_SYMBOL_BUILTIN\nintroduced: 2.0.0\ndefault: true\ntags:\n  - ecmascript2015\ndescription: >\n  Provide ES6 Symbol built-ins.\n\n  Even with the built-ins disabled, symbols created by C code are still\n  supported.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_TAILCALL.yaml",
    "content": "define: DUK_USE_TAILCALL\nintroduced: 1.0.0\nconflicts:\n  - DUK_USE_NONSTD_FUNC_CALLER_PROPERTY\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Enable tail call support (recommended).\n\n  The non-standard function 'caller' property feature conflicts with\n  tailcalls quite severely so tailcalls must be disabled if the 'caller'\n  property is enabled.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_TARGET_INFO.yaml",
    "content": "define: DUK_USE_TARGET_INFO\nintroduced: 1.2.0\ndefault:\n  string: \"unknown\"\ntags:\n  - debugger\ndescription: >\n  Define a freeform human readable string to describe the target device (e.g.\n  \"Arduino Yun\").  This string will be sent as part of version/target info in\n  the debugger protocol and shows up in the debugger UI.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_TRACEBACKS.yaml",
    "content": "define: DUK_USE_TRACEBACKS\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Record traceback data into ECMAScript error objects.\n\n  When disabled, traceback data is not recorded, but fileName/lineNumber of\n  the error cause are still recorded as explicit properties.  Disabling this\n  option reduces footprint and makes error handling a bit faster, at the cost\n  of less informative ECMAScript errors.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_TRACEBACK_DEPTH.yaml",
    "content": "define: DUK_USE_TRACEBACK_DEPTH\nintroduced: 1.0.0\ndefault: 10\ntags:\n  - ecmascript\ndescription: >\n  Define traceback collection depth.  A large number causes tracedata to be\n  larger, taking more time to create and consuming more memory.  A small\n  number makes tracebacks less useful.\n\n  When tracebacks are disabled this option affects .fileName and .lineNumber\n  blaming.  Error augmentation code won't look deeper than this value to find\n  a function to blame for error .fileName / .lineNumber.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_UNALIGNED_ACCESSES_POSSIBLE.yaml",
    "content": "define: DUK_USE_UNALIGNED_ACCESSES_POSSIBLE\nintroduced: 1.0.0\nremoved: 1.4.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Target architecture unaligned memory accesses (e.g. 32-bit integer access\n  from an arbitrary address).\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_UNDERSCORE_SETJMP.yaml",
    "content": "define: DUK_USE_UNDERSCORE_SETJMP\nintroduced: 1.1.0\nremoved: 1.5.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Use _setjmp/_longjmp for long control transfers.  This ensures signal\n  mask is not saved which can be a lot faster if setjmp/longjmp saves the\n  signal mask (this varies between platforms).  See comments in\n  DUK_USE_SETJMP.\n\n  Removed in Duktape 1.5.0: edit duk_config.h directly.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_UNION_INITIALIZERS.yaml",
    "content": "define: DUK_USE_UNION_INITIALIZERS\nintroduced: 1.5.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Compiler supports C99-style designated union initializers, e.g.\n  { .foo = 123 }.\n\n  When disabled, Duktape sometimes needs to resort to less efficient struct\n  initializers for portability.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_USER_DECLARE.yaml",
    "content": "define: DUK_USE_USER_DECLARE\nintroduced: 1.0.0\nremoved: 2.4.0\ndefault:\n  verbatim: '#define DUK_USE_USER_DECLARE() /* no user declarations */'\ntags:\n  - portability\ndescription: >\n  Provide declarations or additional preprocessor include directives to be\n  used when compiling Duktape.  You may need this if you set\n  DUK_USE_PANIC_HANDLER to call your own panic handler function.  You can\n  also use this option to cause additional files to be included when compiling\n  Duktape.\n\n  NOTE: This is only needed if using the default autodetecting duk_config.h\n  header.  When providing DUK_USE_xxx flags directly, you should just provide\n  all the necessary declarations in duk_config.h directly.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_USER_INITJS.yaml",
    "content": "define: DUK_USE_USER_INITJS\nintroduced: 1.0.0\nremoved: 2.0.0\ndefault: false\ntags:\n  - portability\ndescription: >\n  Provide a string to evaluate when a thread with new built-ins (a new global\n  environment) is created.  This allows you to make minor modifications to the\n  global environment before any code is executed in it.  The value must be a\n  string, e.g.:: -DDUK_OPT_USER_INITJS='\"this.foo = 123\"'.\n\n  Errors in the initialization code result in a fatal error.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_VALSTACK_GROW_SHIFT.yaml",
    "content": "define: DUK_USE_VALSTACK_GROW_SHIFT\nintroduced: 2.2.0\ndefault: 2\ntags:\n  - performance\n  - lowmemory\ndescription: >\n  When growing the value stack, shift minimum size right by this amount to\n  come up with a slack which is allocated on top of the minimum required\n  size.  The slack increases memory usage a bit, but reduces value stack\n  reallocations when the minimum size grows.  A value of 2 means that a\n  25% slack is used.  Undefine to remove any slack, value stack is then\n  always grown by the minimum amount possible.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_VALSTACK_LIMIT.yaml",
    "content": "define: DUK_USE_VALSTACK_LIMIT\nintroduced: 2.2.0\ndefault: 1000000\ntags:\n  - misc\ndescription: >\n  Maximum value stack size.  If value stack is about to be grown beyond this\n  size (the check includes a possible spare so the check isn't exact) reject\n  the resize.  The limit must be low enough so that when multiplied by\n  sizeof(duk_tval), typically 8 or 16, the multiplication won't overflow\n  size_t.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT.yaml",
    "content": "define: DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT\nintroduced: 2.2.0\ndefault: 2\ntags:\n  - performance\n  - lowmemory\ndescription: >\n  When doing a value stack shrink check, skip shrinking if the difference\n  between the minimum reserve and allocated size is less than\n  (curr_size >> DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT) bytes.  A value of 2\n  means that the difference must be at least 25% for a shrink to happen.\n  If undefined, value stack is always shrunk to the minimum reserved size\n  with no slack.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT.yaml",
    "content": "define: DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT\nintroduced: 2.2.0\ndefault: 4\ntags:\n  - performance\n  - lowmemory\ndescription: >\n  When shrinking, leave (curr_size >> DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT)\n  bytes as a slack.  This shift count must be larger than\n  DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_VALSTACK_UNSAFE.yaml",
    "content": "define: DUK_USE_VALSTACK_UNSAFE\nintroduced: 1.2.0\ndefault: false\ntags:\n  - performance\n  - experimental\ndescription: >\n  Don't check allocated value stack size in operations like value stack\n  pushes.  Improves performance of API calls but causes unsafe memory\n  behavior (e.g. a segfault) when user code pushes beyond \"checked\" value\n  stack size.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_VARIADIC_MACROS.yaml",
    "content": "define: DUK_USE_VARIADIC_MACROS\nintroduced: 1.0.0\ndefault: true\ntags:\n  - portability\ndescription: >\n  Compiler supports C99-style variadic macros.  Highly recommended to enable\n  when possible.\n\n  When disabled, Duktape needs to resort to various hacks to work around\n  missing support for variadic macros.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_VERBOSE_ERRORS.yaml",
    "content": "define: DUK_USE_VERBOSE_ERRORS\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Provide error message strings and file/line information for errors generated\n  by Duktape.\n\n  When disabled, reduces footprint at the cost of much less informative\n  ECMAScript errors.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_VERBOSE_EXECUTOR_ERRORS.yaml",
    "content": "define: DUK_USE_VERBOSE_EXECUTOR_ERRORS\nintroduced: 1.0.0\ndefault: true\ntags:\n  - ecmascript\ndescription: >\n  Use verbose error messages in bytecode executor (recommended).\n\n  When disabled, reduces footprint slightly at the cost of more obscure\n  error messages.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_VOLUNTARY_GC.yaml",
    "content": "define: DUK_USE_VOLUNTARY_GC\nintroduced: 1.0.0\ndefault: true\ntags:\n  - gc\n  - memory\ndescription: >\n  Enable voluntary periodic mark-and-sweep collection.\n\n  When disabled, a mark-and-sweep collection is still triggered in an\n  out-of-memory condition (known as \"emergency GC\".  When disabling this\n  option it's recommended to use reference counting which collects all\n  non-cyclical garbage.  Application code should also request an explicit\n  garbage collection from time to time when appropriate.  When this option\n  is disabled, Duktape will have no garbage collection pauses in ordinary\n  use, which is useful for timing sensitive applications like games.\n"
  },
  {
    "path": "react_juce/duktape/config/config-options/DUK_USE_ZERO_BUFFER_DATA.yaml",
    "content": "define: DUK_USE_ZERO_BUFFER_DATA\nintroduced: 1.0.0\ndefault: true\ntags:\n  - memory\n  - ecmascript\ndescription: >\n  Zero data are of newly allocated buffer values (recommended).\n\n  When disabled, buffers are not zeroed and may contain arbitrary data.\n  Disabling this option only makes sense for performance reasons.\n"
  },
  {
    "path": "react_juce/duktape/config/examples/compliance.yaml",
    "content": "# Enable compliant behavior, defaults favor \"real world\" compatibility.\n\nDUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT: false\nDUK_USE_NONSTD_FUNC_CALLER_PROPERTY: false\nDUK_USE_NONSTD_FUNC_SOURCE_PROPERTY: false\nDUK_USE_NONSTD_FUNC_STMT: false\nDUK_USE_NONSTD_GETTER_KEY_ARGUMENT: false\nDUK_USE_NONSTD_JSON_ESC_U2028_U2029: false\nDUK_USE_NONSTD_SETTER_KEY_ARGUMENT: false\nDUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT: false\nDUK_USE_ES6_REGEXP_SYNTAX: false  # for ES5 compliance, disable ES6-only regexp extra syntax\n\n# These Array fast paths assume Array.prototype has no inherited index\n# properties which might affect reads/writes.  Such properties are very\n# rare so this assumption is usually a good one; for strict compliance,\n# disable the fast paths.\nDUK_USE_ARRAY_PROP_FASTPATH: false\nDUK_USE_ARRAY_FASTPATH: false\n"
  },
  {
    "path": "react_juce/duktape/config/examples/debugger_support.yaml",
    "content": "# Enable debugger support in general, also needs interrupt support.\nDUK_USE_INTERRUPT_COUNTER: true\nDUK_USE_DEBUGGER_SUPPORT: true\n\n# Basic set of Notifys.\nDUK_USE_DEBUGGER_THROW_NOTIFY: true\n\n# Automatically pause on an uncaught error about to be thrown.\nDUK_USE_DEBUGGER_PAUSE_UNCAUGHT: true\n\n# Enable DumpHeap command (experimental).\nDUK_USE_DEBUGGER_DUMPHEAP: true\n\n# Enable object inspection commands: GetHeapObjInfo, GetObjPropDesc,\n# GetObjPropDescRange.\nDUK_USE_DEBUGGER_INSPECT: true\n\n# Transport torture testing: enable when testing your transport\n# implementation.\nDUK_USE_DEBUGGER_TRANSPORT_TORTURE: false\n\n# NOTE: If you're using the Duktape command line utility for debugging\n# (duk --debugger ...), remember to enable debugger support for the command\n# line tool when compiling it: -DDUK_CMDLINE_DEBUGGER_SUPPORT.\n"
  },
  {
    "path": "react_juce/duktape/config/examples/disable_bufferobjects.yaml",
    "content": "# Disable support for typed arrays and Node.js Buffer.  Duktape will still\n# support plain buffers and Duktape.Buffer.\nDUK_USE_BUFFEROBJECT_SUPPORT: false\n"
  },
  {
    "path": "react_juce/duktape/config/examples/disable_es6.yaml",
    "content": "# Disable ES2015 features.\n\nDUK_USE_ES6_OBJECT_PROTO_PROPERTY: false\nDUK_USE_ES6_OBJECT_SETPROTOTYPEOFS: false\nDUK_USE_ES6_PROXY: false\n"
  },
  {
    "path": "react_juce/duktape/config/examples/enable_debug_print0.yaml",
    "content": "# Enable debug level 0.\nDUK_USE_DEBUG: true\nDUK_USE_DEBUG_LEVEL: 0\n"
  },
  {
    "path": "react_juce/duktape/config/examples/enable_debug_print1.yaml",
    "content": "# Enable debug level 1.\nDUK_USE_DEBUG: true\nDUK_USE_DEBUG_LEVEL: 1\n"
  },
  {
    "path": "react_juce/duktape/config/examples/enable_debug_print2.yaml",
    "content": "# Enable debug level 2.\nDUK_USE_DEBUG: true\nDUK_USE_DEBUG_LEVEL: 2\n"
  },
  {
    "path": "react_juce/duktape/config/examples/enable_fastint.yaml",
    "content": "# Enable fastint support.\n\nDUK_USE_FASTINT: true\n"
  },
  {
    "path": "react_juce/duktape/config/examples/low_memory.yaml",
    "content": "# Base configuration for low memory environments, see\n# doc/low-memory.rst:\n#\n#   - Strips verbose errors etc\n#   - Strips some ES2015 features like Proxy support (re-enable if needed)\n#   - Strips some Duktape custom feature like JX/JC; keeps e.g. RegExp\n#     and other standard parts\n#   - Strips some commonly unnecessary API calls like bytecode dump/load\n#   - Does not enable pointer compression or external strings: these\n#     need target specific support code\n#   - Does not enable ROM string/object support by default, enable manually\n#\n\n# Consider switching alignment to align-by-1 or align-by-4 for more compact\n# memory layout if the architecture supports it.\n#DUK_USE_ALIGN_BY: 1\n\n# With the vast majority of compilers some of the 'undefined behavior'\n# assumptions are fine, and produce smaller and faster code, so enable\n# by default for lowmem targets.  You may need to disable this for some\n# compilers.\nDUK_USE_ALLOW_UNDEFINED_BEHAVIOR: true\n\nDUK_USE_PREFER_SIZE: true\nDUK_USE_EXEC_PREFER_SIZE: true\nDUK_USE_FAST_REFCOUNT_DEFAULT: false\nDUK_USE_AUGMENT_ERROR_CREATE: false\nDUK_USE_AUGMENT_ERROR_THROW: false\nDUK_USE_TRACEBACKS: false\nDUK_USE_ERRCREATE: false\nDUK_USE_ERRTHROW: false\nDUK_USE_VERBOSE_ERRORS: false\nDUK_USE_PARANOID_ERRORS: true\nDUK_USE_FATAL_MAXLEN: 64\nDUK_USE_VERBOSE_EXECUTOR_ERRORS: false  # <100 bytes footprint\nDUK_USE_DEBUGGER_SUPPORT: false  # must be disabled if DUK_USE_PC2LINE is disabled\nDUK_USE_PC2LINE: false\nDUK_USE_LEXER_SLIDING_WINDOW: false\nDUK_USE_JSON_STRINGIFY_FASTPATH: false\nDUK_USE_JSON_QUOTESTRING_FASTPATH: false\nDUK_USE_JSON_DECSTRING_FASTPATH: false\nDUK_USE_JSON_DECNUMBER_FASTPATH: false\nDUK_USE_JSON_EATWHITE_FASTPATH: false\nDUK_USE_BASE64_FASTPATH: false\nDUK_USE_HEX_FASTPATH: false\nDUK_USE_IDCHAR_FASTPATH: false\nDUK_USE_ARRAY_PROP_FASTPATH: false\nDUK_USE_ARRAY_FASTPATH: false\nDUK_USE_BYTECODE_DUMP_SUPPORT: false\nDUK_USE_JX: false\nDUK_USE_JC: false\n#DUK_USE_REGEXP_SUPPORT: false\nDUK_USE_DEBUG_BUFSIZE: 2048\nDUK_USE_LIGHTFUNC_BUILTINS: true\n\n# Grow value stack without any slack, and shrink to minimum reserved size with\n# no slack.  Increases allocation traffic but avoids allocating space not\n# actually needed.\nDUK_USE_VALSTACK_GROW_SHIFT: false\nDUK_USE_VALSTACK_SHRINK_CHECK_SHIFT: false\nDUK_USE_VALSTACK_SHRINK_SLACK_SHIFT: false\n\n# Using the same minsize and maxsize drops code footprint by around 400 bytes\n# (string table resize code is omitted).  Enabling DUK_USE_STRTAB_PTRCOMP\n# saves some RAM (two bytes per strtab entry) at the cost of 200-300 bytes of\n# code footprint.\nDUK_USE_STRTAB_MINSIZE: 128\nDUK_USE_STRTAB_MAXSIZE: 128\nDUK_USE_STRTAB_SHRINK_LIMIT: 0         # doesn't matter if minsize==masize\nDUK_USE_STRTAB_GROW_LIMIT: 65536       # -\"\"-\nDUK_USE_STRTAB_RESIZE_CHECK_MASK: 255  # -\"\"-\n#DUK_USE_STRTAB_PTRCOMP: true  # sometimes useful with pointer compression\n\n# Disable literal pinning and litcache.\nDUK_USE_LITCACHE_SIZE: false\n\nDUK_USE_HSTRING_ARRIDX: false\nDUK_USE_HSTRING_LAZY_CLEN: false  # non-lazy charlen is smaller\n\n# Only add a hash table for quite large objects to conserve memory.  Even\n# lower memory targets usually drop hash part support entirely.\nDUK_USE_HOBJECT_HASH_PROP_LIMIT: 64\n\n# Disable freelist caching.\nDUK_USE_CACHE_ACTIVATION: false\nDUK_USE_CACHE_CATCHER: false\n\n# Consider using pointer compression, see doc/low-memory.rst.\n#DUK_USE_REFCOUNT16: true\n#DUK_USE_REFCOUNT32: false\n#DUK_USE_STRHASH16: true\n#DUK_USE_STRLEN16: true\n#DUK_USE_BUFLEN16: true\n#DUK_USE_OBJSIZES16: true\n#DUK_USE_HSTRING_CLEN: false\n#DUK_USE_HSTRING_LAZY_CLEN: false\n#DUK_USE_HOBJECT_HASH_PART: false\n#DUK_USE_HEAPPTR16\n#DUK_USE_HEAPPTR_DEC16\n#DUK_USE_HEAPPTR_ENC16\n\n# Consider using external strings, see doc/low_memory.rst.\n#DUK_USE_EXTERNAL_STRINGS: true\n#DUK_USE_EXTSTR_INTERN_CHECK\n#DUK_USE_EXTSTR_FREE\n\n# Consider removing Node.js Buffer and ES2015 typed array support if not\n# needed (about 10 kB code footprint difference on x64)\nDUK_USE_BUFFEROBJECT_SUPPORT: false\n\n# Consider to reduce code footprint at the expense of more erratic RAM usage\n#DUK_USE_REFERENCE_COUNTING: false\n#DUK_USE_DOUBLE_LINKED_HEAP: false\n\n# Consider to reduce code footprint at the expense of less safeguards against\n# bugs in calling C code.\nDUK_USE_VALSTACK_UNSAFE: true\n\n# Disable optimizations for case insensitive regexps.  If code involves\n# case insensitive regexps with large character classes, consider enabling\n# at least DUK_USE_REGEXP_CANON_BITMAP.\nDUK_USE_REGEXP_CANON_WORKAROUND: false  # very large footprint (~128kB)\nDUK_USE_REGEXP_CANON_BITMAP: false      # small footprint (~300-400 bytes)\n\n# Consider using ROM strings/objects to reduce footprint, see doc/low_memory.rst.\n# ROM strings/objects reduce startup RAM usage at the expense of code footprint\n# and some compliance.\n#DUK_USE_ROM_STRINGS: true\n#DUK_USE_ROM_OBJECTS: true\n#DUK_USE_ROM_GLOBAL_INHERIT: true  # select inherit or clone; inherit recommended\n#DUK_USE_ROM_GLOBAL_CLONE: false\n\n# Function footprint size reduction.\nDUK_USE_FUNC_NAME_PROPERTY: true  # compliance\nDUK_USE_FUNC_FILENAME_PROPERTY: false  # non-standard, can be removed\n\n# Consider these; disabled by default because they don't impact E5 compliance.\nDUK_USE_ES6: false\nDUK_USE_ES7: false\nDUK_USE_ES8: false\nDUK_USE_ES9: false\nDUK_USE_BASE64_SUPPORT: false\nDUK_USE_HEX_SUPPORT: false\nDUK_USE_COROUTINE_SUPPORT: false\nDUK_USE_SOURCE_NONBMP: false  # <300 bytes footprint\nDUK_USE_ES6_PROXY: false  # roughly 2kB footprint\nDUK_USE_ES7_EXP_OPERATOR: false  # pulls in pow()\nDUK_USE_ENCODING_BUILTINS: false\nDUK_USE_PERFORMANCE_BUILTIN: false\nDUK_USE_ES6_UNICODE_ESCAPE: false\nDUK_USE_HTML_COMMENTS: false\nDUK_USE_SHEBANG_COMMENTS: false\nDUK_USE_REFLECT_BUILTIN: false\nDUK_USE_SYMBOL_BUILTIN: false\n"
  },
  {
    "path": "react_juce/duktape/config/examples/low_memory_strip.yaml",
    "content": "# More stripping for low memory environments, removing e.g. RegExp support,\n# coroutine support, etc.\n\nDUK_USE_BUFFEROBJECT_SUPPORT: false\n\nDUK_USE_REGEXP_SUPPORT: false\n\nDUK_USE_REFERENCE_COUNTING: false\nDUK_USE_DOUBLE_LINKED_HEAP: false\n\n# Consider to reduce code footprint at the expense of less safeguards against\n# bugs in calling C code\nDUK_USE_VALSTACK_UNSAFE: true\n\n# Short term workaround with large footprint, disable.\nDUK_USE_REGEXP_CANON_WORKAROUND: false\n\n# Coroutine support has about 2kB footprint.\nDUK_USE_COROUTINE_SUPPORT: false\n\n# Finalizer support has about 0.8kB footprint.\nDUK_USE_FINALIZER_SUPPORT: false\n\n# ES2015 Proxy has about 2kB footprint.\nDUK_USE_ES6_PROXY: false\n\n# Don't support non-BMP characters in source code (UTF-8 otherwise OK).\nDUK_USE_SOURCE_NONBMP: false\n\n# Don't include even .name property for functions.\nDUK_USE_FUNC_NAME_PROPERTY: false\n\n# Remove built-in bindings.\nDUK_USE_MATH_BUILTIN: false\nDUK_USE_DATE_BUILTIN: false\nDUK_USE_ARRAY_BUILTIN: false\nDUK_USE_STRING_BUILTIN: false\nDUK_USE_BOOLEAN_BUILTIN: false\nDUK_USE_NUMBER_BUILTIN: false\nDUK_USE_FUNCTION_BUILTIN: false\nDUK_USE_OBJECT_BUILTIN: false\nDUK_USE_DUKTAPE_BUILTIN: false\nDUK_USE_JSON_BUILTIN: false\nDUK_USE_ENCODING_BUILTINS: false\nDUK_USE_REFLECT_BUILTIN: false\nDUK_USE_JSON_SUPPORT: false   # also disables JSON support for C API\nDUK_USE_GLOBAL_BUILTIN: false\n"
  },
  {
    "path": "react_juce/duktape/config/examples/performance_sensitive.yaml",
    "content": "# Base configuration for performance sensitive environments, see\n# doc/performance-sensitive.rst.\n\n# You should choose the fastest setjmp/longjmp for your platform.\n\n# With the vast majority of compilers some of the 'undefined behavior'\n# assumptions are fine, and produce smaller and faster code, so enable\n# by default for performance oriented targets.  You may need to disable\n# this for some compilers.\nDUK_USE_ALLOW_UNDEFINED_BEHAVIOR: true\n\nDUK_USE_PREFER_SIZE: false\nDUK_USE_PACKED_TVAL: false  # packed duk_tval slower in most cases\nDUK_USE_FASTINT: true\nDUK_USE_VALSTACK_UNSAFE: true\nDUK_USE_FAST_REFCOUNT_DEFAULT: true\n\nDUK_USE_JSON_STRINGIFY_FASTPATH: true  # not fully portable right now\nDUK_USE_JSON_QUOTESTRING_FASTPATH: true\nDUK_USE_JSON_DECSTRING_FASTPATH: true\nDUK_USE_JSON_DECNUMBER_FASTPATH: true\nDUK_USE_JSON_EATWHITE_FASTPATH: true\nDUK_USE_BASE64_FASTPATH: true\nDUK_USE_HEX_FASTPATH: true\nDUK_USE_IDCHAR_FASTPATH: true\nDUK_USE_ARRAY_PROP_FASTPATH: true\nDUK_USE_ARRAY_FASTPATH: true\nDUK_USE_INTERRUPT_COUNTER: false\n\nDUK_USE_DEBUGGER_SUPPORT: false\n\nDUK_USE_STRHASH_DENSE: false\nDUK_USE_STRHASH_SKIP_SHIFT: 5  # may be able to reduce\n#DUK_USE_EXEC_FUN_LOCAL: false  # test both values, marginal benefit\n\nDUK_USE_LITCACHE_SIZE: 1024\n\nDUK_USE_REGEXP_CANON_WORKAROUND: true  # high footprint impact (128kB), enabled until a better solution\n"
  },
  {
    "path": "react_juce/duktape/config/examples/rom_builtins.yaml",
    "content": "# Move built-in strings and objects to ROM (read-only data section) to reduce\n# RAM usage of Duktape heaps; all heaps will share the same built-in strings\n# and objects, except for the global object which is writable.  The downside\n# is that built-in objects (other than global object) will be read-only.\n\n# These should be used together.\nDUK_USE_ROM_STRINGS: true\nDUK_USE_ROM_OBJECTS: true\n\n# Provide a writable global object:\n#  - DUK_USE_ROM_GLOBAL_INHERIT: empty RAM global object inherits from ROM\n#    global object, uses very little RAM.\n#  - DUK_USE_ROM_GLOBAL_CLONE: ROM global object is cloned into RAM, more\n#    compliant but uses more RAM.\n#\n# If both are set to 'false', global object will be non-writable which\n# may surprise users.\nDUK_USE_ROM_GLOBAL_INHERIT: true\nDUK_USE_ROM_GLOBAL_CLONE: false\n"
  },
  {
    "path": "react_juce/duktape/config/examples/security_sensitive.yaml",
    "content": "# Base configuration for security sensitive environments.\n\n# Avoid summary of object/key for rejected property operations.  May be\n# relevant if keys contain potentially sensitive information.\nDUK_USE_PARANOID_ERRORS: true\n\n# Disable tracebacks, minimizes attacker knowledge of call chains.  Access\n# to the internal error _Tracedata property provides access to all functions\n# in the call chain (even when they're otherwise not visible to sandboxed\n# code).\nDUK_USE_TRACEBACKS: false\n\n# Dense string hashing may be useful against accidental string hash collisions.\n# This won't prevent an attacker from finding intentional collisions.\nDUK_USE_STRHASH_DENSE: true\n\n# TBD\n"
  },
  {
    "path": "react_juce/duktape/config/examples/shallow_c_stack.yaml",
    "content": "# Reduce recursion limits for shallow C stack targets.\n# These values are based on the (removed) DUK_USE_DEEP_C_STACK option.\n\nDUK_USE_NATIVE_CALL_RECLIMIT: 60\nDUK_USE_COMPILER_RECLIMIT: 50\nDUK_USE_REGEXP_COMPILER_RECLIMIT: 100\nDUK_USE_REGEXP_EXECUTOR_RECLIMIT: 100\nDUK_USE_JSON_ENC_RECLIMIT: 100\nDUK_USE_JSON_DEC_RECLIMIT: 100\nDUK_USE_MARK_AND_SWEEP_RECLIMIT: 32\n"
  },
  {
    "path": "react_juce/duktape/config/examples/timing_sensitive.yaml",
    "content": "# Base configuration for timing sensitive environments, see\n# doc/timing-sensitive.rst:\n\nDUK_USE_MARK_AND_SWEEP: true\nDUK_USE_REFERENCE_COUNTING: true\nDUK_USE_VOLUNTARY_GC: false\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_ASSERTIONS.yaml",
    "content": "define: DUK_OPT_ASSERTIONS\nintroduced: 1.0.0\ntags:\n  - development\n  - debug\ndescription: >\n  Enable internal assert checks.  These slow down execution considerably\n  so only use when debugging.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_BUFFEROBJECT_SUPPORT.yaml",
    "content": "define: DUK_OPT_BUFFEROBJECT_SUPPORT\nintroduced: 1.3.0\ntags:\n  - ecmascript6\ndescription: >\n  Enable support for Khronos/ES6 typed arrays and Node.js Buffer objects.\n  This adds about 8-9 kB of code footprint on x64.  When disabled, Duktape\n  custom plain buffers and Duktape.Buffer are still supported.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_BUFLEN16.yaml",
    "content": "define: DUK_OPT_BUFLEN16\nintroduced: 1.1.0\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use a 16-bit buffer length field (for low memory environments).\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DATAPTR16.yaml",
    "content": "define: DUK_OPT_DATAPTR16\nintroduced: 1.1.0\nrelated:\n  - DUK_OPT_DATAPTR_ENC16\n  - DUK_OPT_DATAPTR_DEC16\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Enable \"compression\" of arbitrary data pointers into an unsigned 16-bit\n  value.  Use together with DUK_OPT_DATAPTR_ENC16 and DUK_OPT_DATAPTR_DEC16.\n\n  Pointers compressed are any void pointers in C code, not just the Duktape\n  heap.  Also NULL pointer must encode and decode correctly.\n\n  Currently it is required that NULL encodes to integer 0, and integer\n  0 decodes to NULL.  No other pointer can be encoded to 0.\n\n  NOTE: This feature option is currently unimplemented, i.e. Duktape won't\n  compress any data pointers at the moment.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DATAPTR_DEC16.yaml",
    "content": "define: DUK_OPT_DATAPTR_DEC16\nintroduced: 1.1.0\nrequires:\n  - DUK_OPT_DATAPTR16\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use together with DUK_OPT_DATAPTR16 for arbitrary data pointer compression.\n  DUK_OPT_DATAPTR_DEC16(udata,x) is a macro with a userdata and duk_uint16_t\n  argument, and a void ptr return value.  The userdata argument is the heap\n  userdata value given at heap creation.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DATAPTR_ENC16.yaml",
    "content": "define: DUK_OPT_DATAPTR_ENC16\nintroduced: 1.1.0\nrequires:\n  - DUK_OPT_DATAPTR16\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use together with DUK_OPT_DATAPTR16 for arbitrary data pointer compression.\n  DUK_OPT_DATAPTR_ENC16(udata,p) is a macro with a userdata and void ptr\n  argument, and a duk_uint16_t return value.  The userdata argument is the\n  heap userdata value given at heap creation.  Currently it is required that\n  NULL encodes to integer 0, and integer 0 decodes to NULL.  No other pointer\n  can be encoded to 0.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DDDPRINT.yaml",
    "content": "define: DUK_OPT_DDDPRINT\nintroduced: 1.0.0\nrequires:\n  - DUK_OPT_DEBUG\ntags:\n  - debug\ndescription: >\n  Enable even more debug printouts.  Not recommended unless you have\n  grep handy.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DDPRINT.yaml",
    "content": "define: DUK_OPT_DDPRINT\nintroduced: 1.0.0\nrequires:\n  - DUK_OPT_DEBUG\ntags:\n  - debug\ndescription: >\n  Enable more debug printouts.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DEBUG.yaml",
    "content": "define: DUK_OPT_DEBUG\nintroduced: 1.0.0\ntags:\n  - debug\ndescription: >\n  Enable debug code in Duktape internals.  Without this option other\n  debugging options (such as DUK_OPT_DPRINT) have no effect.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DEBUGGER_DUMPHEAP.yaml",
    "content": "define: DUK_OPT_DEBUGGER_DUMPHEAP\nintroduced: 1.2.0\nrequires:\n  - DUK_OPT_DEBUGGER_SUPPORT\ntags:\n  - debugger\ndescription: >\n  Support the DumpHeap command.  This is optional because the command is not\n  always needed.  The command also has a relatively large footprint (about\n  10% of debugger code); in absolute terms it's about 1kB of code footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DEBUGGER_FWD_LOGGING.yaml",
    "content": "define: DUK_OPT_DEBUGGER_FWD_LOGGING\nintroduced: 1.2.0\nrequires:\n  - DUK_OPT_DEBUGGER_SUPPORT\ntags:\n  - debugger\ndescription: >\n  Forward log writes using the built-in logging framework to the debug client.\n  Forwarding happens from the Duktape.Logger.prototype.info() etc calls before\n  the raw() function is called, so that logging is forwarded even if you\n  replace the backend.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DEBUGGER_FWD_PRINTALERT.yaml",
    "content": "define: DUK_OPT_DEBUGGER_FWD_PRINTALERT\nintroduced: 1.2.0\nrequires:\n  - DUK_OPT_DEBUGGER_SUPPORT\ntags:\n  - debugger\ndescription: >\n  Forward calls to the built-in print() and alert() function to the debug\n  client.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DEBUGGER_SUPPORT.yaml",
    "content": "define: DUK_OPT_DEBUGGER_SUPPORT\nintroduced: 1.2.0\nrequires:\n  - DUK_OPT_INTERRUPT_COUNTER\ntags:\n  - debugger\ndescription: >\n  Enable support for Duktape debug protocol (see doc/debugger.rst) and the\n  debug API calls (duk_debugger_attach(), duk_debugger_detach(), etc).\n  This adds about 10kB of code footprint at the moment.\n\n  This option requires DUK_OPT_INTERRUPT_COUNTER.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DEBUGGER_TRANSPORT_TORTURE.yaml",
    "content": "define: DUK_OPT_DEBUGGER_TRANSPORT_TORTURE\nintroduced: 1.2.0\nrequires:\n  - DUK_OPT_DEBUGGER_SUPPORT\ntags:\n  - debugger\n  - development\ndescription: >\n  Development time option: force debugger transport torture.  Concretely this\n  now causes Duktape to read/write debug protocol data in 1-byte increments,\n  which stresses message parsing and transport code.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DEBUG_BUFSIZE.yaml",
    "content": "define: DUK_OPT_DEBUG_BUFSIZE\nintroduced: 1.0.0\nrequires:\n  - DUK_OPT_DEBUG\ntags:\n  - debug\ndescription: >\n  Debug code uses a static buffer as a formatting temporary to avoid side\n  effects in debug prints.  The static buffer is large by default, which\n  may be an issue in constrained environments.  You can set the buffer size\n  manually with this option.  Example: -DDUK_OPT_DEBUG_BUFSIZE=2048.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DECLARE.yaml",
    "content": "define: DUK_OPT_DECLARE\nintroduced: 1.0.0\ntags:\n  - portability\ndescription: >\n  Provide declarations or additional preprocessor include directives to be\n  used when compiling Duktape.  You may need this if you set\n  DUK_OPT_PANIC_HANDLER to call your own panic handler function.  You can\n  also use this option to cause additional files to be included when compiling\n  Duktape.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DEEP_C_STACK.yaml",
    "content": "define: DUK_OPT_DEEP_C_STACK\nintroduced: 1.0.0\nremoved: 1.3.0\ntags:\n  - memory\n  - portability\ndescription: >\n  By default Duktape imposes a sanity limit on the depth of the C stack\n  because it is often limited in embedded environments.  This option\n  forces Duktape to use a deep C stack which relaxes e.g. recursion limits.\n  Automatic feature detection enables deep C stacks on some platforms known\n  to have them (e.g. Linux, BSD, Windows).\n\n  Removed in Duktape 1.3.0, use explicit config options to control recursion\n  limits for shallow stack targets.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DLL_BUILD.yaml",
    "content": "define: DUK_OPT_DLL_BUILD\nintroduced: 1.0.0\ntags:\n  - portability\ndescription: >\n  Add this define to both Duktape and application build when Duktape is\n  compiled as a DLL.  This is especially critical on Windows: the option\n  makes Duktape use __declspec(dllexport) and __declspec(dllimport) for\n  public symbols.\n\n  While this is not currently needed for Unix platforms, it should always\n  be used if you build as a DLL.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DPRINT.yaml",
    "content": "define: DUK_OPT_DPRINT\nintroduced: 1.0.0\nrequires:\n  - DUK_OPT_DEBUG\ntags:\n  - debug\ndescription: >\n  Enable debug printouts.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DPRINT_COLORS.yaml",
    "content": "define: DUK_OPT_DPRINT_COLORS\nintroduced: 1.0.0\ntags:\n  - debug\ndescription: >\n  Enable coloring of debug prints with ANSI escape codes\n  (http://en.wikipedia.org/wiki/ANSI_escape_code).  The behavior is not\n  sensitive to terminal settings.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_DPRINT_RDTSC.yaml",
    "content": "define: DUK_OPT_DPRINT_RDTSC\nintroduced: 1.0.0\nremoved: 1.4.0\ntags:\n  - debug\ndescription: >\n  Print RDTSC cycle count in debug prints if available.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_EXAMPLE.yaml",
    "content": "#\n#  Each Duktape option is described as a YAML file named OPTION_NAME.yaml.\n#  YAML is used because it diffs well and has clean support for multiline\n#  inline strings.\n#\n#  Metadata for feature options (DUK_OPT_xxx) is sparse, it's needed for\n#  legacy support.\n#\n\n# C #define name for the option.  Must match filename minus extension.\ndefine: DUK_OPT_OBJSIZES16\n\n# Duktape version number where this option was first introduced.\nintroduced: 1.1.0\n#deprecated: 1.2.0\n#removed: 1.3.0\n\n# Optional indication that feature option is defined but currently\n# unused, so that it can be omitted from generated header.\n#unused: true\n\n# Optional list of options that must also be defined to use this option.\n#requires:\n#  - DUK_OPT_FOO\n#  - DUK_OPT_BAR\n\n# Optional list of options that this option conflicts with.\n#conflicts:\n#  - DUK_OPT_BAZ\n\n# Optional list of options that are related from a user and documentation\n# perspective.\n#related:\n#  - DUK_OPT_QUUX\n\n# Tags related to option (required).  If present, first tag is used as a\n# primary tag for grouping.  Use 'misc' if nothing else is appropriate.\ntags:\n  - lowmemory\n  - experimental\n\n# Description for option, no newlines.  Line breaking for e.g. C header\n# is automatic.\ndescription: >\n  Use a 16-bit object entry and array part sizes (for low memory\n  environments).  Also automatically drops support for an object hash\n  part to further reduce memory usage; there are rarely large objects\n  in low memory environments simply because there's no memory to store\n  a lot of properties.\n\n# Marker to avoid processing this file.\nexample: true\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_EXEC_TIMEOUT_CHECK.yaml",
    "content": "define: DUK_OPT_EXEC_TIMEOUT_CHECK\nintroduced: 1.2.0\nrequires:\n  - DUK_OPT_INTERRUPT_COUNTER\ntags:\n  - execution\n  - sandbox\n  - experimental\ndescription: >\n  NOTE: This mechanism is EXPERIMENTAL and the details may change\n  between releases.\n\n  Provide a hook to check for bytecode execution timeout.  The macro gets\n  a void ptr userdata argument (the userdata given to duk_heap_create())\n  and must evaluate to a duk_bool_t.  Duktape calls the macro as:\n  \"if (DUK_OPT_EXEC_TIMEOUT_CHECK(udata)) { ... }\".\n\n  The macro is called occasionally by the Duktape bytecode executor (i.e.\n  when executing ECMAScript code), typically from a few times per second\n  to a hundred times per second, but the interval varies a great deal\n  depending on what kind of code is being executed.\n\n  To indicate an execution timeout, the macro must return a non-zero value.\n  When that happens, Duktape starts to bubble a ``RangeError`` outwards\n  until control has been returned to the original protected call made by\n  the application.  Until that happens, the exec timeout macro must always\n  return non-zero to indicate an execution timeout is still in progress.\n\n  This mechanism and its limitations is described in more detail in\n  doc/sandboxing.rst.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_EXTERNAL_STRINGS.yaml",
    "content": "define: DUK_OPT_EXTERNAL_STRINGS\nintroduced: 1.1.0\ntags:\n  - memory\ndescription: >\n  Enable support for external strings.  An external string requires a Duktape\n  heap allocation to store a minimal string header, with the actual string\n  data being held behind a pointer (similarly to how dynamic buffers work).\n\n  This option is needed to use DUK_OPT_EXTSTR_INTERN_CHECK and/or\n  DUK_OPT_EXTSTR_FREE.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_EXTSTR_FREE.yaml",
    "content": "define: DUK_OPT_EXTSTR_FREE\nintroduced: 1.1.0\nrequires:\n  - DUK_OPT_EXTERNAL_STRINGS\ntags:\n  - memory\n  - experimental\ndescription: >\n  Optional counterpart to DUK_OPT_EXTSTR_INTERN_CHECK.  Invoked when an\n  external string is about to be freed by Duktape.\n\n  The argument \"ptr\" is a void ptr and points to the external string data.\n  Concretely, it is the (non-NULL) value returned by\n  DUK_OPT_EXTSTR_INTERN_CHECK.  The \"udata\" argument is the heap userdata\n  which may be ignored if not needed.\n\n  Also enable DUK_OPT_EXTERNAL_STRINGS to use this feature.\n\n  NOTE: Right now there is no API to push external strings; external strings\n  come into being as a result of DUK_OPT_EXTSTR_INTERN_CHECK() only.  If/when\n  this is changed, this hook will get called for every string, even if pushed\n  by the user using an API call; this may need to be rethought at that time.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_EXTSTR_INTERN_CHECK.yaml",
    "content": "define: DUK_OPT_EXTSTR_INTERN_CHECK\nintroduced: 1.1.0\nrequires:\n  - DUK_OPT_EXTERNAL_STRINGS\ntags:\n  - memory\n  - experimental\ndescription: >\n  Provide a hook for checking if data for a certain string can be used from\n  external memory (outside of Duktape heap, e.g. memory mapped flash).\n  The hook is called during string interning with the following semantics:\n\n  The string data with no NUL termination resides at \"ptr\" and has \"len\"\n  bytes.  The \"udata\" argument is the heap userdata which may be ignored\n  if not needed.  If the hook returns NULL, Duktape interns the string\n  normally, i.e. string data is allocated from Duktape heap.  Otherwise the\n  hook return value must point to a memory area which contains\n  \"len\" bytes from \"ptr\" followed by a NUL byte which is NOT PRESENT\n  in the input data.  Data behind the returned pointer may not change after\n  the hook returns.\n\n  The hook may be called several times for the same input string.  This\n  happens when a string is interned, garbage collected, and then interned\n  again.\n\n  The DUK_OPT_EXTSTR_FREE() hook allows application code to detect when\n  an external string is about to be freed.\n\n  In most cases the hook should reject strings whose \"len\" is less than 4\n  because there is no RAM advantage in moving so short strings into external\n  memory.  The ordinary \"duk_hstring\" header followed by the data (and a\n  NUL byte) has the same size as \"duk_hstring_external\" header which hosts\n  a pointer instead of string data.\n\n  Also enable DUK_OPT_EXTERNAL_STRINGS to use this feature.\n\n  See doc/low-memory.rst for more discussion how to use this feature option\n  in practice.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_FASTINT.yaml",
    "content": "define: DUK_OPT_FASTINT\nintroduced: 1.2.0\ntags:\n  - performance\ndescription: >\n  Enable support for 48-bit signed \"fastint\" integer values.  Fastints are\n  transparent to user code (both C and ECMAScript) but may be faster than\n  IEEE doubles on some platforms, especially those using softints.  The\n  downside of fastints is increased code footprint and a small performance\n  penalty for some kinds of code.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_FORCE_ALIGN.yaml",
    "content": "define: DUK_OPT_FORCE_ALIGN\nintroduced: 1.0.0\ntags:\n  - portability\ndescription: >\n  Use -DDUK_OPT_FORCE_ALIGN=4 or -DDUK_OPT_FORCE_ALIGN=8 to force a\n  specific struct/value alignment instead of relying on Duktape's\n  automatic detection.  This shouldn't normally be needed.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_FORCE_BYTEORDER.yaml",
    "content": "define: DUK_OPT_FORCE_BYTEORDER\nintroduced: 1.0.0\ntags:\n  - portability\ndescription: >\n  Use this to skip byte order detection and force a specific byte order:\n  1 for little endian, 2 for ARM \"mixed\" endian (integers little endian,\n  IEEE doubles mixed endian), 3 for big endian.  Byte order detection\n  relies on unstandardized platform specific header files, so this may be\n  required for custom platforms if compilation fails in endianness detection.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_FUNCPTR16.yaml",
    "content": "define: DUK_OPT_FUNCPTR16\nintroduced: 1.1.0\nrelated:\n  - DUK_OPT_FUNCPTR_ENC16\n  - DUK_OPT_FUNCPTR_DEC16\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Enable \"compression\" of arbitrary C function pointers into an unsigned 16-bit\n  value.  Use together with DUK_OPT_FUNCPTR_ENC16 and DUK_OPT_FUNCPTR_DEC16.\n\n  Pointers compressed are any C function pointers.  Also NULL pointer must\n  encode and decode correctly.\n\n  Currently it is required that NULL encodes to integer 0, and integer\n  0 decodes to NULL.  No other pointer can be encoded to 0.\n\n  NOTE: This feature option is currently unimplemented, i.e. Duktape won't\n  compress any function pointers at the moment.  It might not be necessary\n  to support a NULL function pointer (uncertain until taken into use).\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_FUNCPTR_DEC16.yaml",
    "content": "define: DUK_OPT_FUNCPTR_DEC16\nintroduced: 1.1.0\nrequires:\n  - DUK_OPT_FUNCPTR16\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use together with DUK_OPT_FUNCPTR16 for function pointer compression.\n  DUK_OPT_FUNCPTR_DEC16(udata,x) is a macro with a userdata and duk_uint16_t\n  argument, and a void ptr return value.  The userdata argument is the heap\n  userdata value given at heap creation.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_FUNCPTR_ENC16.yaml",
    "content": "define: DUK_OPT_FUNCPTR_ENC16\nintroduced: 1.1.0\nrequires:\n  - DUK_OPT_FUNCPTR16\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use together with DUK_OPT_FUNCPTR16 for function pointer compression.\n  DUK_OPT_FUNCPTR_ENC16(udata,p) is a macro with a userdata and void ptr\n  argument, and a duk_uint16_t return value.  The userdata arguments is the\n  heap userdata value given at heap creation.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_FUNC_NONSTD_CALLER_PROPERTY.yaml",
    "content": "define: DUK_OPT_FUNC_NONSTD_CALLER_PROPERTY\nintroduced: 1.0.0\nremoved: 1.0.0\nrelated:\n  - DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY\ntags:\n  - ecmascript\ndescription: >\n  Removed, use DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY instead.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_FUNC_NONSTD_SOURCE_PROPERTY.yaml",
    "content": "define: DUK_OPT_FUNC_NONSTD_SOURCE_PROPERTY\nintroduced: 1.0.0\nremoved: 1.0.0\nrelated:\n  - DUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY\ntags:\n  - ecmascript\ndescription: >\n  Removed, use DUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY instead.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_GC_TORTURE.yaml",
    "content": "define: DUK_OPT_GC_TORTURE\nintroduced: 1.0.0\ntags:\n  - gc\n  - memory\n  - development\ndescription: >\n  Development time option: force full mark-and-sweep on every allocation to\n  stress test memory management.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_HAVE_CUSTOM_H.yaml",
    "content": "define: DUK_OPT_HAVE_CUSTOM_H\nintroduced: 1.0.0\ndeprecated: 1.3.0\ntags:\n  - portability\ndescription: >\n  Normally you define DUK_OPT_xxx feature options and the autodetecting\n  duk_config.h (previously internal duk_features.h.in) header resolves\n  these with platform/compiler constraints to determine effective compilation\n  options for Duktape internals.  The effective options are provided as\n  DUK_USE_xxx defines which you normally never see.\n\n  If you define DUK_OPT_HAVE_CUSTOM_H, Duktape will include \"duk_custom.h\"\n  after determining the appropriate DUK_USE_xxx defines but before compiling\n  any code.  The duk_custom.h header, which you provide, can then tweak the\n  active DUK_USE_xxx defines freely.  See duk_config.h and genconfig option\n  metadata for the available defines.\n\n  This approach is useful when the DUK_OPT_xxx feature options don't\n  provide enough flexibility to tweak the build.  The downside is that you can\n  easily create inconsistent DUK_USE_xxx flags, the customization header\n  will be version specific, and you need to peek into Duktape internals to\n  know what defines to tweak.\n\n  NOTE: This option is deprecated.  The preferred method for customization\n  starting from Duktape 1.3.0 is to create/modify a \"duk_config.h\" header.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_HEAPPTR16.yaml",
    "content": "define: DUK_OPT_HEAPPTR16\nintroduced: 1.1.0\nconflicts:\n  - DUK_OPT_DEBUG\nrelated:\n  - DUK_OPT_HEAPPTR_ENC16\n  - DUK_OPT_HEAPPTR_DEC16\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Enable \"compression\" of Duktape heap pointers into an unsigned 16-bit value.\n  Use together with DUK_OPT_HEAPPTR_ENC16 and DUK_OPT_HEAPPTR_DEC16.\n\n  Pointers compressed are those allocated from Duktape heap, using the user\n  provided allocation functions.  Also NULL pointer must encode and decode\n  correctly.\n\n  Currently it is required that NULL encodes to integer 0, and integer\n  0 decodes to NULL.  No other pointer can be encoded to 0.\n\n  This option reduces memory usage by several kilobytes, but has several\n  downsides.  It can only be applied when Duktape heap is limited in size,\n  for instance, with 4-byte aligned allocations a 256kB heap (minus one value\n  for NULL) can be supported.  Pointer encoding and decoding may be relatively\n  complicated as they need to correctly handle NULL pointers and\n  non-continuous memory maps used by some targets.  The macro may need to call\n  out to a helper function in practice, which is much slower than an inline\n  implementation.\n\n  Current limitation:  Duktape internal debug code enabled with e.g.\n  DUK_OPT_DEBUG and DUK_OPT_DPRINT doesn't have enough plumbing to be able to\n  decode pointers.  Debug printing cannot currently be enabled when pointer\n  compression is active.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_HEAPPTR_DEC16.yaml",
    "content": "define: DUK_OPT_HEAPPTR_DEC16\nintroduced: 1.1.0\nrequires:\n  - DUK_OPT_HEAPPTR16\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use together with DUK_OPT_HEAPPTR16 for heap pointer compression.\n  DUK_OPT_HEAPPTR_DEC16(udata,x) is a macro with a userdata and duk_uint16_t\n  argument, and a void ptr return value.  The userdata argument is the heap\n  userdata value given at heap creation.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_HEAPPTR_ENC16.yaml",
    "content": "define: DUK_OPT_HEAPPTR_ENC16\nintroduced: 1.1.0\nrequires:\n  - DUK_OPT_HEAPPTR16\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use together with DUK_OPT_HEAPPTR16 for heap pointer compression.\n  DUK_OPT_HEAPPTR_ENC16(udata,p) is a macro with a userdata and void ptr\n  argument, and a duk_uint16_t return value.  The userdata argument is the\n  heap userdata value given at heap creation.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_INTERRUPT_COUNTER.yaml",
    "content": "define: DUK_OPT_INTERRUPT_COUNTER\nintroduced: 1.1.0\nrelated:\n  - DUK_OPT_DEBUGGER_SUPPORT\ntags:\n  - execution\n  - debugger\ndescription: >\n  Enable the internal bytecode executor periodic interrupt counter.\n  The mechanism is used to implement e.g. execution step limit, custom\n  profiling, and debugger interaction.  Enabling the interrupt counter\n  has a small impact on execution performance.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_JSON_STRINGIFY_FASTPATH.yaml",
    "content": "define: DUK_OPT_JSON_STRINGIFY_FASTPATH\nintroduced: 1.3.0\ntags:\n  - performance\n  - fastpath\n  - lowmemory\ndescription: >\n  Enable fast apth for JSON.stringify() serialization.  See\n  DUK_USE_JSON_STRINGIFY_FASTPATH for details.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_LIGHTFUNC_BUILTINS.yaml",
    "content": "define: DUK_OPT_LIGHTFUNC_BUILTINS\nintroduced: 1.1.0\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Force built-in functions to be lightweight functions.  This reduces\n  memory footprint by around 14 kB at the cost of some non-compliant\n  behavior.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY.yaml",
    "content": "define: DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Add a non-standard \"caller\" property to non-strict function instances\n  for better compatibility with existing code.  The semantics of this\n  property are not standardized and may vary between engines; Duktape tries\n  to behave close to V8 and Spidermonkey.  See\n  https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller\n  description of the property.  This feature disables tail call support.\n\n  This feature conflicts with several other features, so you should use it\n  only if it's absolutely necessary.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY.yaml",
    "content": "define: DUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Add a non-standard \"source\" property to function instances.  This allows\n  function toString() to print out the actual function source.  The property\n  is disabled by default because it increases memory footprint.\n\n  NOTE: Unimplemented as of Duktape 1.2.0.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_ARRAY_SPLICE_NONSTD_DELCOUNT.yaml",
    "content": "define: DUK_OPT_NO_ARRAY_SPLICE_NONSTD_DELCOUNT\nintroduced: 1.0.0\nremoved: 1.0.0\nrelated:\n  - DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT\ntags:\n  - ecmascript\ndescription: >\n  Removed, use DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT instead.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_AUGMENT_ERRORS.yaml",
    "content": "define: DUK_OPT_NO_AUGMENT_ERRORS\nintroduced: 1.0.0\nrelated:\n  - DUK_OPT_NO_TRACEBACKS\ntags:\n  - ecmascript\ndescription: >\n  Don't augment ECMAScript error objects with custom fields like fileName,\n  lineNumber, and traceback data.  Also disables Duktape.errCreate and\n  Duktape.errThrow error handler callbacks.  Implies DUK_OPT_NO_TRACEBACKS.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_BROWSER_LIKE.yaml",
    "content": "define: DUK_OPT_NO_BROWSER_LIKE\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Disable browser-like functions.  Makes print() and alert() throw an error.\n\n  This option is confusing when used with the Duktape command line tool, as\n  the command like tool will immediately panic on startup.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_BUFFEROBJECT_SUPPORT.yaml",
    "content": "define: DUK_OPT_NO_BUFFEROBJECT_SUPPORT\nintroduced: 1.3.0\ntags:\n  - ecmascript6\ndescription: >\n  Disable support for Khronos/ES6 typed arrays and Node.js Buffer objects\n  which reduces code footprint.  When disabled, Duktape custom plain buffers\n  and Duktape.Buffer are still supported.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_BYTECODE_DUMP_SUPPORT.yaml",
    "content": "define: DUK_OPT_NO_BYTECODE_DUMP_SUPPORT\nintroduced: 1.3.0\ntags:\n  - api\ndescription: >\n  Disable API calls to dump/load functions to bytecode (reduces code\n  footprint).\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_COMMONJS_MODULES.yaml",
    "content": "define: DUK_OPT_NO_COMMONJS_MODULES\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Disable support for CommonJS modules.  Causes require() to throw an error.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY.yaml",
    "content": "define: DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY\nintroduced: 1.0.0\ntags:\n  - ecmascript\n  - ecmascript6\ndescription: >\n  Disable the non-standard (ES6) Object.prototype.__proto__ property\n  which is enabled by default.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF.yaml",
    "content": "define: DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF\nintroduced: 1.0.0\ntags:\n  - ecmascript\n  - ecmascript6\ndescription: >\n  Disable the non-standard (ES6) Object.setPrototypeOf method which\n  is enabled by default.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_ES6_PROXY.yaml",
    "content": "define: DUK_OPT_NO_ES6_PROXY\nintroduced: 1.0.0\ntags:\n  - ecmascript\n  - ecmascript6\ndescription: >\n  Disable the non-standard (ES6) Proxy object which is enabled by\n  default.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_FILE_IO.yaml",
    "content": "define: DUK_OPT_NO_FILE_IO\nintroduced: 1.0.0\ntags:\n  - portability\ndescription: >\n  Disable use of ANSI C file I/O which might be a portability issue on some\n  platforms.  Causes duk_eval_file() to throw an error, makes built-in\n  print() and alert() no-ops, and suppresses writing of a panic\n  message to stderr on panic.  This option does not suppress debug\n  printing so don't enable debug printing if you wish to avoid I/O.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_FUNC_STMT.yaml",
    "content": "define: DUK_OPT_NO_FUNC_STMT\nintroduced: 1.0.0\nremoved: 1.0.0\nrelated:\n  - DUK_OPT_NO_NONSTD_FUNC_STMT\ntags:\n  - ecmascript\ndescription: >\n  Removed, use DUK_OPT_NO_NONSTD_FUNC_STMT instead.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_JC.yaml",
    "content": "define: DUK_OPT_NO_JC\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Disable support for the JC format.  Reduces code footprint.  An attempt\n  to encode or decode the format causes an error.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_JSONC.yaml",
    "content": "define: DUK_OPT_NO_JSONC\nintroduced: 1.0.0\nremoved: 1.0.0\nrelated:\n  - DUK_OPT_NO_JC\ntags:\n  - ecmascript\ndescription: >\n  Removed, use DUK_OPT_NO_JC instead.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_JSONX.yaml",
    "content": "define: DUK_OPT_NO_JSONX\nintroduced: 1.0.0\nremoved: 1.0.0\nrelated:\n  - DUK_OPT_NO_JX\ntags:\n  - ecmascript\ndescription: >\n  Removed, use DUK_OPT_NO_JX instead.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_JX.yaml",
    "content": "define: DUK_OPT_NO_JX\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Disable support for the JX format.  Reduces code footprint.  An attempt\n  to encode or decode the format causes an error.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_MARK_AND_SWEEP.yaml",
    "content": "define: DUK_OPT_NO_MARK_AND_SWEEP\nintroduced: 1.0.0\ntags:\n  - gc\n  - memory\ndescription: >\n  Disable mark-and-sweep and use only reference counting for garbage\n  collection.  This reduces code footprint and eliminates garbage collection\n  pauses, but objects participating in unreachable reference cycles won't be\n  collected until the Duktape heap is destroyed.  In particular, function\n  instances won't be collected because they're always in a reference cycle\n  with their default prototype object.  Unreachable objects are collected if\n  you break reference cycles manually (and are always freed when a heap is\n  destroyed).\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_MS_STRINGTABLE_RESIZE.yaml",
    "content": "define: DUK_OPT_NO_MS_STRINGTABLE_RESIZE\nintroduced: 1.0.0\ntags:\n  - gc\n  - memory\ndescription: >\n  Disable forced string intern table resize during mark-and-sweep garbage\n  collection.  This may be useful when reference counting is disabled, as\n  mark-and-sweep collections will be more frequent and thus more expensive.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_NONSTD_ACCESSOR_KEY_ARGUMENT.yaml",
    "content": "define: DUK_OPT_NO_NONSTD_ACCESSOR_KEY_ARGUMENT\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Don't give setter/getter calls the property name being accessed as\n  an additional, non-standard property.  See\n  http://duktape.org/guide.html#propertyvirtualization.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_NONSTD_ARRAY_CONCAT_TRAILER.yaml",
    "content": "define: DUK_OPT_NO_NONSTD_ARRAY_CONCAT_TRAILER\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  For better compatibility with existing code, Array.prototype.concat() has\n  non-standard behavior by default for trailing non-existent elements of\n  the concat result, see\n  https://github.com/svaarala/duktape/blob/master/ecmascript-testcases/test-bi-array-proto-concat-nonstd-trailing.js.\n\n  If this option is given, concat() will behave in a strictly conforming\n  fashion, ignoring non-existent trailing elements in the result length.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_NONSTD_ARRAY_MAP_TRAILER.yaml",
    "content": "define: DUK_OPT_NO_NONSTD_ARRAY_MAP_TRAILER\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  For better compatibility with existing code, Array.prototype.map() has\n  non-standard behavior by default for trailing non-existent elements of\n  the map result, see\n  https://github.com/svaarala/duktape/blob/master/ecmascript-testcases/test-bi-array-proto-map-nonstd-trailing.js.\n\n  If this option is given, map() will behave in a strictly conforming\n  fashion, ignoring non-existent trailing elements in the result length.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT.yaml",
    "content": "define: DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  For better compatibility with existing code, Array.prototype.splice() has\n  non-standard behavior by default when the second argument (deleteCount)\n  is not given: the splice operation is extended to the end of the array, see\n  https://github.com/svaarala/duktape/blob/master/ecmascript-testcases/test-bi-array-proto-splice-no-delcount.js.\n\n  If this option is given, splice() will behave in a strictly conforming\n  fashion, treating a missing deleteCount the same as an undefined (or 0)\n  value.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_NONSTD_FUNC_STMT.yaml",
    "content": "define: DUK_OPT_NO_NONSTD_FUNC_STMT\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Disable support for function declarations outside program or function top\n  level (also known as \"function statements\").  Such declarations are\n  non-standard and the strictly compliant behavior is to treat them as a\n  SyntaxError.  Default behavior is to treat them like ordinary function\n  declarations (\"hoist\" them to function top) with V8-like semantics.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_NONSTD_JSON_ESC_U2028_U2029.yaml",
    "content": "define: DUK_OPT_NO_NONSTD_JSON_ESC_U2028_U2029\nintroduced: 1.1.0\ntags:\n  - ecmascript\ndescription: >\n  By default Duktape JSON.stringify() will escape U+2028 and U+2029 which\n  is non-compliant behavior.  This is the default to make JSON.stringify()\n  output valid when embedded in a web page or parsed with eval().  This\n  feature option enables the compliant behavior, i.e. no escaping for U+2028\n  and U+2029.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_NONSTD_STRING_FROMCHARCODE_32BIT.yaml",
    "content": "define: DUK_OPT_NO_NONSTD_STRING_FROMCHARCODE_32BIT\nintroduced: 1.2.0\ntags:\n  - ecmascript\ndescription: >\n  By default Duktape String.fromCharCode() allows 32-bit codepoints which is\n  non-compliant (the E5.1 specification has a ToUint16() coercion for the\n  codepoints) but useful because Duktape supports non-BMP strings.  This\n  feature option restores the compliant behavior.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_OBJECT_ES6_PROTO_PROPERTY.yaml",
    "content": "define: DUK_OPT_NO_OBJECT_ES6_PROTO_PROPERTY\nintroduced: 1.0.0\nremoved: 1.0.0\nrelated:\n  - DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY\ntags:\n  - ecmascript\n  - ecmascript6\ndescription: >\n  Removed, use DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY instead.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_OBJECT_ES6_SETPROTOTYPEOF.yaml",
    "content": "define: DUK_OPT_NO_OBJECT_ES6_SETPROTOTYPEOF\nintroduced: 1.0.0\nremoved: 1.0.0\nrelated:\n  - DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF\ntags:\n  - ecmascript\n  - ecmascript6\ndescription: >\n  Removed, use DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF instead.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_OCTAL_SUPPORT.yaml",
    "content": "define: DUK_OPT_NO_OCTAL_SUPPORT\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Disable optional octal number support (ECMAScript E5/E5.1\n  Annex B: http://www.ecma-international.org/ecma-262/5.1/#sec-B).\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_PACKED_TVAL.yaml",
    "content": "define: DUK_OPT_NO_PACKED_TVAL\nintroduced: 1.0.0\ntags:\n  - memory\n  - portability\ndescription: >\n  Don't use the packed 8-byte internal value representation even if otherwise\n  possible.  The packed representation has more platform/compiler portability\n  issues than the unpacked one.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_PC2LINE.yaml",
    "content": "define: DUK_OPT_NO_PC2LINE\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Don't record a \"pc2line\" map into function instances.  Without this map,\n  exceptions won't have meaningful line numbers (virtual machine program\n  counter values cannot be translated to line numbers) but function instances\n  will have a smaller footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_REFERENCE_COUNTING.yaml",
    "content": "define: DUK_OPT_NO_REFERENCE_COUNTING\nintroduced: 1.0.0\ntags:\n  - gc\n  - memory\ndescription: >\n  Disable reference counting and use only mark-and-sweep for garbage\n  collection.  Although this reduces memory footprint of heap objects, the\n  downside is much more fluctuation in memory usage.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_REGEXP_SUPPORT.yaml",
    "content": "define: DUK_OPT_NO_REGEXP_SUPPORT\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Disable support for regular expressions.  Regexp literals are treated as\n  a SyntaxError, RegExp constructor and prototype functions throw an error,\n  String.prototype.replace() throws an error if given a regexp search value,\n  String.prototype.split() throws an error if given a regexp separator value,\n  String.prototype.search() and String.prototype.match() throw an error\n  unconditionally.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_SECTION_B.yaml",
    "content": "define: DUK_OPT_NO_SECTION_B\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Disable optional features in ECMAScript specification\n  Annex B: http://www.ecma-international.org/ecma-262/5.1/#sec-B.\n  Causes escape(), unescape(), and String.prototype.substr() to throw\n  an error.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_SOURCE_NONBMP.yaml",
    "content": "define: DUK_OPT_NO_SOURCE_NONBMP\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Disable accurate Unicode support for non-BMP characters in source code.\n  Non-BMP characters are then always accepted as identifier characters.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_STRICT_DECL.yaml",
    "content": "define: DUK_OPT_NO_STRICT_DECL\nintroduced: 1.1.0\ntags:\n  - ecmascript\n  - experimental\ndescription: >\n  Disable support for \"use strict\" declaration so that ECMAScript code is\n  always executed in non-strict mode.  Duktape/C functions remain strict.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_TRACEBACKS.yaml",
    "content": "define: DUK_OPT_NO_TRACEBACKS\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Don't record traceback data into ECMAScript error objects (but still record\n  fileName and lineNumber).  Reduces footprint and makes error handling a bit\n  faster, at the cost of less informative ECMAScript errors.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_VERBOSE_ERRORS.yaml",
    "content": "define: DUK_OPT_NO_VERBOSE_ERRORS\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Don't provide error message strings or filename/line information for errors\n  generated by Duktape.  Reduces footprint, at the cost of much less\n  informative ECMAScript errors.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_VOLUNTARY_GC.yaml",
    "content": "define: DUK_OPT_NO_VOLUNTARY_GC\nintroduced: 1.0.0\ntags:\n  - gc\n  - memory\ndescription: >\n  Disable voluntary periodic mark-and-sweep collection.  A mark-and-sweep\n  collection is still triggered in an out-of-memory condition.  This option\n  should usually be combined with reference counting, which collects all\n  non-cyclical garbage.  Application code should also request an explicit\n  garbage collection from time to time when appropriate.  When this option\n  is used, Duktape will have no garbage collection pauses in ordinary use,\n  which is useful for timing sensitive applications like games.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_NO_ZERO_BUFFER_DATA.yaml",
    "content": "define: DUK_OPT_NO_ZERO_BUFFER_DATA\nintroduced: 1.0.0\ntags:\n  - memory\n  - ecmascript\ndescription: >\n  By default Duktape zeroes data allocated for buffer values.  Define\n  this to disable the zeroing (perhaps for performance reasons).\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_OBJSIZES16.yaml",
    "content": "define: DUK_OPT_OBJSIZES16\nintroduced: 1.1.0\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use a 16-bit object entry and array part sizes (for low memory\n  environments).  Also automatically drops support for an object hash part\n  to further reduce memory usage; there are rarely large objects in low\n  memory environments simply because there's no memory to store a lot of\n  properties.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_PANIC_HANDLER.yaml",
    "content": "define: DUK_OPT_PANIC_HANDLER\nintroduced: 1.0.0\ntags:\n  - portability\ndescription: >\n  Provide a custom panic handler.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_REFCOUNT16.yaml",
    "content": "define: DUK_OPT_REFCOUNT16\nintroduced: 1.1.0\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use a 16-bit reference count field (for low memory environments).\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_SEGFAULT_ON_PANIC.yaml",
    "content": "define: DUK_OPT_SEGFAULT_ON_PANIC\nintroduced: 1.0.0\ntags:\n  - portability\ndescription: >\n  Cause the default panic handler to cause a segfault instead of using\n  abort() or exit().  This is useful when debugging with valgrind,\n  as a segfault provides a nice C traceback in valgrind.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_SELF_TESTS.yaml",
    "content": "define: DUK_OPT_SELF_TESTS\nintroduced: 1.0.0\ntags:\n  - debug\ndescription: >\n  Perform run-time self tests when a Duktape heap is created.  Catches\n  platform/compiler problems which cannot be reliably detected during\n  compile time.  Not enabled by default because of the extra footprint.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_SETJMP.yaml",
    "content": "define: DUK_OPT_SETJMP\nintroduced: 1.1.0\nremoved: 1.5.0\ntags:\n  - portability\ndescription: >\n  Force setjmp/longjmp for long control transfers.\n\n  The default long control transfer provider is setjmp/longjmp because it\n  is the most portable option.  When a better provider is known for a platform,\n  Duktape may default to that (e.g. _setjmp/_longjmp is the default for\n  OSX/iPhone, see GH-55).  With this feature option you can force Duktape to\n  explicitly use setjmp/longjmp even in these cases.\n\n  The downside of setjmp/longjmp is that signal mask saving behavior is not\n  specified and varies between platforms.  Signal mask saving may have a\n  significant performance impact so you may want to force a specific provider\n  if performance matters for your application.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_SHUFFLE_TORTURE.yaml",
    "content": "define: DUK_OPT_SHUFFLE_TORTURE\nintroduced: 1.2.0\ntags:\n  - gc\n  - memory\n  - development\ndescription: >\n  Development time option: force compiler to shuffle every possible opcode\n  to stress shuffle behavior which is otherwise difficult to test for\n  comprehensively.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_SIGSETJMP.yaml",
    "content": "define: DUK_OPT_SIGSETJMP\nintroduced: 1.1.0\nremoved: 1.5.0\ntags:\n  - portability\ndescription: >\n  Force sigsetjmp/siglongjmp with savesigs == 0 for long control\n  transfers (i.e. signal mask not saved/restored).  See comments in\n  DUK_OPT_SETJMP.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_STRHASH16.yaml",
    "content": "define: DUK_OPT_STRHASH16\nintroduced: 1.1.0\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use a 16-bit string hash field (for low memory environments).\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_STRICT_UTF8_SOURCE.yaml",
    "content": "define: DUK_OPT_STRICT_UTF8_SOURCE\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Enable strict UTF-8 parsing of source code.  When enabled, non-shortest\n  encodings (normally invalid UTF-8) and surrogate pair codepoints are\n  accepted as valid source code characters.  This option breaks compatibility\n  with some test262 tests.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_STRLEN16.yaml",
    "content": "define: DUK_OPT_STRLEN16\nintroduced: 1.1.0\ntags:\n  - lowmemory\n  - experimental\ndescription: >\n  Use a 16-bit string length field (for low memory environments).\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_STRTAB_CHAIN.yaml",
    "content": "define: DUK_OPT_STRTAB_CHAIN\nintroduced: 1.1.0\nrelated:\n  - DUK_OPT_STRTAB_CHAIN_SIZE\ntags:\n  - lowmemory\ndescription: >\n  Replace the default (open addressing, probing) string table structure with\n  one based on separate chaining.  There is a fixed-size top level hash table\n  (whose size is defined using DUK_OPT_STRTAB_CHAIN_SIZE), with each entry in\n  the hash table being: (a) NULL, (b) a duk_hstring pointer, or (c) a pointer\n  to an array of duk_hstring pointers.  The pointer arrays are gappy (the gaps\n  are reused on new inserts) and are never shrunk at the moment.\n\n  This option is intended for low memory environments to make Duktape's memory\n  behavior match a typical pool-based allocator better as follows:\n\n  The top level fixed structure never changes size, so there is no hash table\n  resize, and thus no need for resize temporaries.  The default string table\n  algorithm needs resizing from time to time and doesn't resize in place, so\n  you effectively need twice the string table size temporarily during a resize.\n\n  The pointer arrays vary in size, but their size (typically 8 to 64 bytes,\n  depending on the load factor) matches that of many other allocations which\n  works well with a pooled allocator.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_STRTAB_CHAIN_SIZE.yaml",
    "content": "define: DUK_OPT_STRTAB_CHAIN_SIZE\nintroduced: 1.1.0\nrequires:\n  - DUK_OPT_STRTAB_CHAIN\ntags:\n  - lowmemory\ndescription: >\n  Define stringtable size for DUK_OPT_STRTAB_CHAIN.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_TARGET_INFO.yaml",
    "content": "define: DUK_OPT_TARGET_INFO\nintroduced: 1.2.0\ntags:\n  - debugger\ndescription: >\n  Define a freeform human readable string to describe the target device (e.g.\n  \"Arduino Yun\").  This string will be sent as part of version/target info in\n  the debugger protocol and shows up in the debugger UI.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_TRACEBACK_DEPTH.yaml",
    "content": "define: DUK_OPT_TRACEBACK_DEPTH\nintroduced: 1.0.0\ntags:\n  - ecmascript\ndescription: >\n  Override default traceback collection depth.  The default is currently 10.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_UNDERSCORE_SETJMP.yaml",
    "content": "define: DUK_OPT_UNDERSCORE_SETJMP\nintroduced: 1.1.0\nremoved: 1.5.0\ntags:\n  - portability\ndescription: >\n  Force _setjmp/_longjmp for long control transfers.  This ensures signal\n  mask is not saved which can be a lot faster if setjmp/longjmp saves the\n  signal mask (this varies between platforms).  See comments in\n  DUK_OPT_SETJMP.\n"
  },
  {
    "path": "react_juce/duktape/config/feature-options/DUK_OPT_USER_INITJS.yaml",
    "content": "define: DUK_OPT_USER_INITJS\nintroduced: 1.0.0\ntags:\n  - portability\ndescription: >\n  Provide a string to evaluate when a thread with new built-ins (a new global\n  environment) is created.  This allows you to make minor modifications to the\n  global environment before any code is executed in it.  The value must be a\n  string, e.g.:: -DDUK_OPT_USER_INITJS='\"this.foo = 123\"'.\n\n  Errors in the initialization code result in a fatal error.\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/64bitops.h.in",
    "content": "/* Check whether we should use 64-bit integers or not.\n *\n * Quite incomplete now.  Use 64-bit types if detected (C99 or other detection)\n * unless they are known to be unreliable.  For instance, 64-bit types are\n * available on VBCC but seem to misbehave.\n */\n#if defined(DUK_F_HAVE_64BIT) && !defined(DUK_F_VBCC)\n#define DUK_USE_64BIT_OPS\n#else\n#undef DUK_USE_64BIT_OPS\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/alignment_fillin.h.in",
    "content": "/*\n *  Alignment requirement and support for unaligned accesses\n *\n *  Assume unaligned accesses are not supported unless specifically allowed\n *  in the target platform.  Some platforms may support unaligned accesses\n *  but alignment to 4 or 8 may still be desirable.  Note that unaligned\n *  accesses (and even pointers) relative to natural alignment (regardless\n *  of target alignment) are technically undefined behavior and thus\n *  compiler/architecture specific.\n */\n\n/* If not forced, use safe default for alignment. */\n#if !defined(DUK_USE_ALIGN_BY)\n#define DUK_USE_ALIGN_BY 8\n#endif\n\n/* Compiler specific hackery needed to force struct size to match alignment,\n * see e.g. duk_hbuffer.h.\n *\n * http://stackoverflow.com/questions/11130109/c-struct-size-alignment\n * http://stackoverflow.com/questions/10951039/specifying-64-bit-alignment\n */\n#if !(defined(DUK_USE_PACK_MSVC_PRAGMA) || defined(DUK_USE_PACK_GCC_ATTR) || \\\n      defined(DUK_USE_PACK_CLANG_ATTR) || defined(DUK_USE_PACK_DUMMY_MEMBER))\n#define DUK_USE_PACK_DUMMY_MEMBER\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/architecture_fillins.h.in",
    "content": ""
  },
  {
    "path": "react_juce/duktape/config/header-snippets/byteorder_derived.h.in",
    "content": "/*\n *  Convert DUK_USE_BYTEORDER, from whatever source, into currently used\n *  internal defines.  If detection failed, #error out.\n */\n\n#if defined(DUK_USE_BYTEORDER)\n#if (DUK_USE_BYTEORDER == 1)\n#define DUK_USE_INTEGER_LE\n#define DUK_USE_DOUBLE_LE\n#elif (DUK_USE_BYTEORDER == 2)\n#define DUK_USE_INTEGER_LE  /* integer endianness is little on purpose */\n#define DUK_USE_DOUBLE_ME\n#elif (DUK_USE_BYTEORDER == 3)\n#define DUK_USE_INTEGER_BE\n#define DUK_USE_DOUBLE_BE\n#else\n#error unsupported: byte order invalid\n#endif  /* byte order */\n#else\n#error unsupported: byte order detection failed\n#endif  /* defined(DUK_USE_BYTEORDER) */\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/byteorder_fillin.h.in",
    "content": "/*\n *  Byte order and double memory layout detection\n *\n *  Endianness detection is a major portability hassle because the macros\n *  and headers are not standardized.  There's even variance across UNIX\n *  platforms.  Even with \"standard\" headers, details like underscore count\n *  varies between platforms, e.g. both __BYTE_ORDER and _BYTE_ORDER are used\n *  (Crossbridge has a single underscore, for instance).\n *\n *  The checks below are structured with this in mind: several approaches are\n *  used, and at the end we check if any of them worked.  This allows generic\n *  approaches to be tried first, and platform/compiler specific hacks tried\n *  last.  As a last resort, the user can force a specific endianness, as it's\n *  not likely that automatic detection will work on the most exotic platforms.\n *\n *  Duktape supports little and big endian machines.  There's also support\n *  for a hybrid used by some ARM machines where integers are little endian\n *  but IEEE double values use a mixed order (12345678 -> 43218765).  This\n *  byte order for doubles is referred to as \"mixed endian\".\n */\n\n/* GCC and Clang provide endianness defines as built-in predefines, with\n * leading and trailing double underscores (e.g. __BYTE_ORDER__).  See\n * output of \"make gccpredefs\" and \"make clangpredefs\".  Clang doesn't\n * seem to provide __FLOAT_WORD_ORDER__; assume not mixed endian for clang.\n * http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html\n */\n#if !defined(DUK_USE_BYTEORDER) && defined(__BYTE_ORDER__)\n#if defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__)\n#define DUK_USE_BYTEORDER 1\n#elif defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__)\n#define DUK_USE_BYTEORDER 2\n#elif !defined(__FLOAT_WORD_ORDER__)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 1\n#else\n/* Byte order is little endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#elif defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__)\n#define DUK_USE_BYTEORDER 3\n#elif !defined(__FLOAT_WORD_ORDER__)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 3\n#else\n/* Byte order is big endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#else\n/* Cannot determine byte order; __ORDER_PDP_ENDIAN__ is related to 32-bit\n * integer ordering and is not relevant.\n */\n#endif  /* integer byte order */\n#endif  /* !defined(DUK_USE_BYTEORDER) && defined(__BYTE_ORDER__) */\n\n/* More or less standard endianness predefines provided by header files.\n * The ARM hybrid case is detected by assuming that __FLOAT_WORD_ORDER\n * will be big endian, see: http://lists.mysql.com/internals/443.\n * On some platforms some defines may be present with an empty value which\n * causes comparisons to fail: https://github.com/svaarala/duktape/issues/453.\n */\n#if !defined(DUK_USE_BYTEORDER)\n#if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN) || \\\n    defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN) || \\\n    defined(__LITTLE_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER) && defined(__LITTLE_ENDIAN) && (__FLOAT_WORD_ORDER == __LITTLE_ENDIAN) || \\\n    defined(_FLOAT_WORD_ORDER) && defined(_LITTLE_ENDIAN) && (_FLOAT_WORD_ORDER == _LITTLE_ENDIAN)\n#define DUK_USE_BYTEORDER 1\n#elif defined(__FLOAT_WORD_ORDER) && defined(__BIG_ENDIAN) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN) || \\\n      defined(_FLOAT_WORD_ORDER) && defined(_BIG_ENDIAN) && (_FLOAT_WORD_ORDER == _BIG_ENDIAN)\n#define DUK_USE_BYTEORDER 2\n#elif !defined(__FLOAT_WORD_ORDER) && !defined(_FLOAT_WORD_ORDER)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 1\n#else\n/* Byte order is little endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN) || \\\n      defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN) || \\\n      defined(__BIG_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER) && defined(__BIG_ENDIAN) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN) || \\\n    defined(_FLOAT_WORD_ORDER) && defined(_BIG_ENDIAN) && (_FLOAT_WORD_ORDER == _BIG_ENDIAN)\n#define DUK_USE_BYTEORDER 3\n#elif !defined(__FLOAT_WORD_ORDER) && !defined(_FLOAT_WORD_ORDER)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 3\n#else\n/* Byte order is big endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#else\n/* Cannot determine byte order. */\n#endif  /* integer byte order */\n#endif  /* !defined(DUK_USE_BYTEORDER) */\n\n/* QNX gcc cross compiler seems to define e.g. __LITTLEENDIAN__ or __BIGENDIAN__:\n *  $ /opt/qnx650/host/linux/x86/usr/bin/i486-pc-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian\n *  67:#define __LITTLEENDIAN__ 1\n *  $ /opt/qnx650/host/linux/x86/usr/bin/mips-unknown-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian\n *  81:#define __BIGENDIAN__ 1\n *  $ /opt/qnx650/host/linux/x86/usr/bin/arm-unknown-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian\n *  70:#define __LITTLEENDIAN__ 1\n */\n#if !defined(DUK_USE_BYTEORDER)\n#if defined(__LITTLEENDIAN__)\n#define DUK_USE_BYTEORDER 1\n#elif defined(__BIGENDIAN__)\n#define DUK_USE_BYTEORDER 3\n#endif\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/compiler_fillins.h.in",
    "content": "#if !defined(DUK_U64_CONSTANT)\n#define DUK_U64_CONSTANT(x) x##ULL\n#endif\n#if !defined(DUK_I64_CONSTANT)\n#define DUK_I64_CONSTANT(x) x##LL\n#endif\n\n#if !defined(DUK_VA_COPY)\n/* We need va_copy() which is defined in C99 / C++11, so an awkward\n * replacement is needed for pre-C99 / pre-C++11 environments.  This\n * will quite likely need portability hacks for some non-C99\n * environments.\n */\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n/* C99 / C++11 and above: rely on va_copy() which is required.\n * Omit parenthesis on macro right side on purpose to minimize differences\n * to direct use.\n */\n#define DUK_VA_COPY(dest,src) va_copy(dest,src)\n#else\n/* Pre-C99: va_list type is implementation dependent.  This replacement\n * assumes it is a plain value so that a simple assignment will work.\n * This is not the case on all platforms (it may be a single-array element,\n * for instance).\n */\n#define DUK_VA_COPY(dest,src) do { (dest) = (src); } while (0)\n#endif\n#endif\n\n#if !defined(DUK_MACRO_STRINGIFY)\n/* Macro hackery to convert e.g. __LINE__ to a string without formatting,\n * see: http://stackoverflow.com/questions/240353/convert-a-preprocessor-token-to-a-string\n */\n#define DUK_MACRO_STRINGIFY_HELPER(x)  #x\n#define DUK_MACRO_STRINGIFY(x)  DUK_MACRO_STRINGIFY_HELPER(x)\n#endif\n\n#if !defined(DUK_CAUSE_SEGFAULT)\n/* This can be used for testing; valgrind will then indicate the C call stack\n * leading to the call site.\n */\n#define DUK_CAUSE_SEGFAULT()  do { *((volatile duk_uint32_t *) NULL) = (duk_uint32_t) 0xdeadbeefUL; } while (0)\n#endif\n\n#if !defined(DUK_UNREF)\n/* Macro for suppressing warnings for potentially unreferenced variables.\n * The variables can be actually unreferenced or unreferenced in some\n * specific cases only; for instance, if a variable is only debug printed,\n * it is unreferenced when debug printing is disabled.  May cause warnings\n * for volatile arguments.\n */\n#define DUK_UNREF(x)  do { (void) (x); } while (0)\n#endif\n\n/* Fillin for DUK_NORETURN; DUK_WO_NORETURN() is used to insert dummy\n * dummy statements after noreturn calls to silence harmless compiler\n * warnings, e.g.:\n *\n *   DUK_ERROR_TYPE(thr, \"aiee\");\n *   DUK_WO_NORETURN(return 0;);\n *\n * Statements inside DUK_WO_NORETURN() must NEVER be actually reachable,\n * and they're only included to satisfy the compiler.\n */\n#if defined(DUK_NORETURN)\n#define DUK_WO_NORETURN(stmt) do { } while (0)\n#else\n#define DUK_NORETURN(decl)  decl\n#define DUK_WO_NORETURN(stmt) do { stmt } while (0)\n#endif\n\n#if !defined(DUK_UNREACHABLE)\n/* Don't know how to declare unreachable point, so don't do it; this\n * may cause some spurious compilation warnings (e.g. \"variable used\n * uninitialized\").\n */\n#define DUK_UNREACHABLE()  do { } while (0)\n#endif\n\n#if !defined(DUK_LOSE_CONST)\n/* Convert any input pointer into a \"void *\", losing a const qualifier.\n * This is not fully portable because casting through duk_uintptr_t may\n * not work on all architectures (e.g. those with long, segmented pointers).\n */\n#define DUK_LOSE_CONST(src) ((void *) (duk_uintptr_t) (src))\n#endif\n\n#if !defined(DUK_LIKELY)\n#define DUK_LIKELY(x)    (x)\n#endif\n#if !defined(DUK_UNLIKELY)\n#define DUK_UNLIKELY(x)  (x)\n#endif\n#if !defined(DUK_UNPREDICTABLE)\n#define DUK_UNPREDICTABLE(x)  (x)\n#endif\n\n#if !defined(DUK_NOINLINE)\n#define DUK_NOINLINE       /*nop*/\n#endif\n#if !defined(DUK_INLINE)\n#define DUK_INLINE         /*nop*/\n#endif\n#if !defined(DUK_ALWAYS_INLINE)\n#define DUK_ALWAYS_INLINE  /*nop*/\n#endif\n\n#if !defined(DUK_HOT)\n#define DUK_HOT            /*nop*/\n#endif\n#if !defined(DUK_COLD)\n#define DUK_COLD           /*nop*/\n#endif\n\n#if !defined(DUK_EXTERNAL_DECL)\n#define DUK_EXTERNAL_DECL  extern\n#endif\n#if !defined(DUK_EXTERNAL)\n#define DUK_EXTERNAL       /*empty*/\n#endif\n#if !defined(DUK_INTERNAL_DECL)\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL_DECL  static\n#else\n#define DUK_INTERNAL_DECL  extern\n#endif\n#endif\n#if !defined(DUK_INTERNAL)\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL       static\n#else\n#define DUK_INTERNAL       /*empty*/\n#endif\n#endif\n#if !defined(DUK_LOCAL_DECL)\n#define DUK_LOCAL_DECL     static\n#endif\n#if !defined(DUK_LOCAL)\n#define DUK_LOCAL          static\n#endif\n\n#if !defined(DUK_FILE_MACRO)\n#define DUK_FILE_MACRO  __FILE__\n#endif\n#if !defined(DUK_LINE_MACRO)\n#define DUK_LINE_MACRO  __LINE__\n#endif\n#if !defined(DUK_FUNC_MACRO)\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_FUNC_MACRO  __func__\n#elif defined(__FUNCTION__)\n#define DUK_FUNC_MACRO  __FUNCTION__\n#else\n#define DUK_FUNC_MACRO  \"unknown\"\n#endif\n#endif\n\n#if defined(DUK_F_HAVE_64BIT)\n#if !defined(DUK_BSWAP64)\n#define DUK_BSWAP64(x) \\\n\t((((duk_uint64_t) (x)) >> 56U) | \\\n\t ((((duk_uint64_t) (x)) >> 40U) & DUK_U64_CONSTANT(0xff00)) | \\\n\t ((((duk_uint64_t) (x)) >> 24U) & DUK_U64_CONSTANT(0xff0000)) | \\\n\t ((((duk_uint64_t) (x)) >> 8U) & DUK_U64_CONSTANT(0xff000000)) | \\\n\t ((((duk_uint64_t) (x)) << 8U) & DUK_U64_CONSTANT(0xff00000000)) | \\\n\t ((((duk_uint64_t) (x)) << 24U) & DUK_U64_CONSTANT(0xff0000000000)) | \\\n\t ((((duk_uint64_t) (x)) << 40U) & DUK_U64_CONSTANT(0xff000000000000)) | \\\n\t (((duk_uint64_t) (x)) << 56U))\n#endif\n#endif\n#if !defined(DUK_BSWAP32)\n#define DUK_BSWAP32(x) \\\n\t((((duk_uint32_t) (x)) >> 24U) | \\\n\t ((((duk_uint32_t) (x)) >> 8U) & 0xff00UL) | \\\n\t ((((duk_uint32_t) (x)) << 8U) & 0xff0000UL) | \\\n\t (((duk_uint32_t) (x)) << 24U))\n#endif\n#if !defined(DUK_BSWAP16)\n#define DUK_BSWAP16(x) \\\n\t((duk_uint16_t) (x) >> 8U) | \\\n\t((duk_uint16_t) (x) << 8U)\n#endif\n\n/* DUK_USE_VARIADIC_MACROS: required from compilers, so no fill-in. */\n/* DUK_USE_UNION_INITIALIZERS: required from compilers, so no fill-in. */\n\n#if !(defined(DUK_USE_FLEX_C99) || defined(DUK_USE_FLEX_ZEROSIZE) || defined(DUK_USE_FLEX_ONESIZE))\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE  /* Not standard but common enough */\n#endif\n#endif\n\n#if !(defined(DUK_USE_PACK_GCC_ATTR) || defined(DUK_USE_PACK_CLANG_ATTR) || \\\n      defined(DUK_USE_PACK_MSVC_PRAGMA) || defined(DUK_USE_PACK_DUMMY_MEMBER))\n#define DUK_USE_PACK_DUMMY_MEMBER\n#endif\n\n#if 0  /* not defined by default */\n#undef DUK_USE_GCC_PRAGMAS\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/cpp_exception_sanity.h.in",
    "content": "#if defined(DUK_USE_CPP_EXCEPTIONS) && !defined(__cplusplus)\n#error DUK_USE_CPP_EXCEPTIONS enabled but not compiling with a C++ compiler\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/date_provider.h.in",
    "content": "/*\n *  Date provider selection\n *\n *  User may define DUK_USE_DATE_GET_NOW() etc directly, in which case we'll\n *  rely on an external provider.  If this is not done, revert to previous\n *  behavior and use Unix/Windows built-in provider.\n */\n\n#if defined(DUK_COMPILING_DUKTAPE)\n\n#if defined(DUK_USE_DATE_GET_NOW)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_gettimeofday()\n#elif defined(DUK_USE_DATE_NOW_TIME)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_time()\n#elif defined(DUK_USE_DATE_NOW_WINDOWS)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_windows()\n#elif defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_windows_subms()\n#else\n#error no provider for DUK_USE_DATE_GET_NOW()\n#endif\n\n#if defined(DUK_USE_DATE_GET_LOCAL_TZOFFSET)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S) || defined(DUK_USE_DATE_TZO_GMTIME)\n#define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d)   duk_bi_date_get_local_tzoffset_gmtime((d))\n#elif defined(DUK_USE_DATE_TZO_WINDOWS)\n#define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d)   duk_bi_date_get_local_tzoffset_windows((d))\n#elif defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST)\n#define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d)   duk_bi_date_get_local_tzoffset_windows_no_dst((d))\n#else\n#error no provider for DUK_USE_DATE_GET_LOCAL_TZOFFSET()\n#endif\n\n#if defined(DUK_USE_DATE_PARSE_STRING)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_PRS_STRPTIME)\n#define DUK_USE_DATE_PARSE_STRING(ctx,str)   duk_bi_date_parse_string_strptime((ctx), (str))\n#elif defined(DUK_USE_DATE_PRS_GETDATE)\n#define DUK_USE_DATE_PARSE_STRING(ctx,str)   duk_bi_date_parse_string_getdate((ctx), (str))\n#else\n/* No provider for DUK_USE_DATE_PARSE_STRING(), fall back to ISO 8601 only. */\n#endif\n\n#if defined(DUK_USE_DATE_FORMAT_STRING)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_FMT_STRFTIME)\n#define DUK_USE_DATE_FORMAT_STRING(ctx,parts,tzoffset,flags) \\\n\tduk_bi_date_format_parts_strftime((ctx), (parts), (tzoffset), (flags))\n#else\n/* No provider for DUK_USE_DATE_FORMAT_STRING(), fall back to ISO 8601 only. */\n#endif\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME)\n/* External provider already defined. */\n#elif defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)\n#define DUK_USE_GET_MONOTONIC_TIME(ctx)  duk_bi_date_get_monotonic_time_clock_gettime()\n#elif defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC)\n#define DUK_USE_GET_MONOTONIC_TIME(ctx)  duk_bi_date_get_monotonic_time_windows_qpc()\n#else\n/* No provider for DUK_USE_GET_MONOTONIC_TIME(), fall back to DUK_USE_DATE_GET_NOW(). */\n#endif\n\n#endif  /* DUK_COMPILING_DUKTAPE */\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/gcc_clang_visibility.h.in",
    "content": "#define DUK_EXTERNAL_DECL  __attribute__ ((visibility(\"default\"))) extern\n#define DUK_EXTERNAL       __attribute__ ((visibility(\"default\")))\n#if defined(DUK_SINGLE_FILE)\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n/* Minimize warnings for unused internal functions with GCC >= 3.1.1 and\n * Clang.  Based on documentation it should suffice to have the attribute\n * in the declaration only, but in practice some warnings are generated unless\n * the attribute is also applied to the definition.\n */\n#define DUK_INTERNAL_DECL  static __attribute__ ((unused))\n#define DUK_INTERNAL       static __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#endif\n#else\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused)) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\")))\n#endif\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/inline_workaround.h.in",
    "content": "/* Workaround for GH-323: avoid inlining control when compiling from\n * multiple sources, as it causes compiler portability trouble.\n */\n#if !defined(DUK_SINGLE_FILE)\n#undef DUK_NOINLINE\n#undef DUK_INLINE\n#undef DUK_ALWAYS_INLINE\n#define DUK_NOINLINE       /*nop*/\n#define DUK_INLINE         /*nop*/\n#define DUK_ALWAYS_INLINE  /*nop*/\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/msvc_visibility.h.in",
    "content": "/* MSVC dllexport/dllimport: appropriate __declspec depends on whether we're\n * compiling Duktape or the application.\n */\n#if defined(DUK_COMPILING_DUKTAPE)\n#define DUK_EXTERNAL_DECL  extern __declspec(dllexport)\n#define DUK_EXTERNAL       __declspec(dllexport)\n#else\n#define DUK_EXTERNAL_DECL  extern __declspec(dllimport)\n#define DUK_EXTERNAL       should_not_happen\n#endif\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#else\n#define DUK_INTERNAL_DECL  extern\n#define DUK_INTERNAL       /*empty*/\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/object_layout.h.in",
    "content": "/* Object property allocation layout has implications for memory and code\n * footprint and generated code size/speed.  The best layout also depends\n * on whether the platform has alignment requirements or benefits from\n * having mostly aligned accesses.\n */\n#undef DUK_USE_HOBJECT_LAYOUT_1\n#undef DUK_USE_HOBJECT_LAYOUT_2\n#undef DUK_USE_HOBJECT_LAYOUT_3\n#if (DUK_USE_ALIGN_BY == 1)\n/* On platforms without any alignment issues, layout 1 is preferable\n * because it compiles to slightly less code and provides direct access\n * to property keys.\n */\n#define DUK_USE_HOBJECT_LAYOUT_1\n#else\n/* On other platforms use layout 2, which requires some padding but\n * is a bit more natural than layout 3 in ordering the entries.  Layout\n * 3 is currently not used.\n */\n#define DUK_USE_HOBJECT_LAYOUT_2\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/packed_tval_fillin.h.in",
    "content": "/*\n *  Check whether or not a packed duk_tval representation is possible.\n *  What's basically required is that pointers are 32-bit values\n *  (sizeof(void *) == 4).  Best effort check, not always accurate.\n *  If guess goes wrong, crashes may result; self tests also verify\n *  the guess.\n */\n\n/* Explicit marker needed; may be 'defined', 'undefined, 'or 'not provided'. */\n#if !defined(DUK_F_PACKED_TVAL_PROVIDED)\n#undef DUK_F_PACKED_TVAL_POSSIBLE\n\n/* Strict C99 case: DUK_UINTPTR_MAX (= UINTPTR_MAX) should be very reliable */\n#if !defined(DUK_F_PACKED_TVAL_POSSIBLE) && defined(DUK_UINTPTR_MAX)\n#if (DUK_UINTPTR_MAX <= 0xffffffffUL)\n#define DUK_F_PACKED_TVAL_POSSIBLE\n#endif\n#endif\n\n/* Non-C99 case, still relying on DUK_UINTPTR_MAX, as long as it is not a computed value */\n#if !defined(DUK_F_PACKED_TVAL_POSSIBLE) && defined(DUK_UINTPTR_MAX) && !defined(DUK_UINTPTR_MAX_COMPUTED)\n#if (DUK_UINTPTR_MAX <= 0xffffffffUL)\n#define DUK_F_PACKED_TVAL_POSSIBLE\n#endif\n#endif\n\n/* DUK_SIZE_MAX (= SIZE_MAX) is often reliable */\n#if !defined(DUK_F_PACKED_TVAL_POSSIBLE) && defined(DUK_SIZE_MAX) && !defined(DUK_SIZE_MAX_COMPUTED)\n#if (DUK_SIZE_MAX <= 0xffffffffUL)\n#define DUK_F_PACKED_TVAL_POSSIBLE\n#endif\n#endif\n\n#undef DUK_USE_PACKED_TVAL\n#if defined(DUK_F_PACKED_TVAL_POSSIBLE)\n#define DUK_USE_PACKED_TVAL\n#endif\n#undef DUK_F_PACKED_TVAL_POSSIBLE\n\n#endif  /* DUK_F_PACKED_TVAL_PROVIDED */\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/platform_conditionalincludes.h.in",
    "content": "#if defined(DUK_F_CPP) && defined(DUK_USE_CPP_EXCEPTIONS)\n#include <exception>  /* std::exception */\n#include <stdexcept>  /* std::runtime_error */\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/platform_cppextras.h.in",
    "content": "/* Workaround for older C++ compilers before including <inttypes.h>,\n * see e.g.: https://sourceware.org/bugzilla/show_bug.cgi?id=15366\n */\n#if defined(__cplusplus) && !defined(__STDC_LIMIT_MACROS)\n#define __STDC_LIMIT_MACROS\n#endif\n#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS)\n#define __STDC_CONSTANT_MACROS\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/platform_fillins.h.in",
    "content": "/* An abort()-like primitive is needed by the default fatal error handler. */\n#if !defined(DUK_ABORT)\n#define DUK_ABORT             abort\n#endif\n\n#if !defined(DUK_SETJMP)\n#define DUK_JMPBUF_TYPE       jmp_buf\n#define DUK_SETJMP(jb)        setjmp((jb))\n#define DUK_LONGJMP(jb)       longjmp((jb), 1)\n#endif\n\n#if 0\n/* sigsetjmp() alternative */\n#define DUK_JMPBUF_TYPE       sigjmp_buf\n#define DUK_SETJMP(jb)        sigsetjmp((jb))\n#define DUK_LONGJMP(jb)       siglongjmp((jb), 1)\n#endif\n\n/* Special naming to avoid conflict with e.g. DUK_FREE() in duk_heap.h\n * (which is unfortunately named).  May sometimes need replacement, e.g.\n * some compilers don't handle zero length or NULL correctly in realloc().\n */\n#if !defined(DUK_ANSI_MALLOC)\n#define DUK_ANSI_MALLOC      malloc\n#endif\n#if !defined(DUK_ANSI_REALLOC)\n#define DUK_ANSI_REALLOC     realloc\n#endif\n#if !defined(DUK_ANSI_CALLOC)\n#define DUK_ANSI_CALLOC      calloc\n#endif\n#if !defined(DUK_ANSI_FREE)\n#define DUK_ANSI_FREE        free\n#endif\n\n/* ANSI C (various versions) and some implementations require that the\n * pointer arguments to memset(), memcpy(), and memmove() be valid values\n * even when byte size is 0 (even a NULL pointer is considered invalid in\n * this context).  Zero-size operations as such are allowed, as long as their\n * pointer arguments point to a valid memory area.  The DUK_MEMSET(),\n * DUK_MEMCPY(), and DUK_MEMMOVE() macros require this same behavior, i.e.:\n * (1) pointers must be valid and non-NULL, (2) zero size must otherwise be\n * allowed.  If these are not fulfilled, a macro wrapper is needed.\n *\n *   http://stackoverflow.com/questions/5243012/is-it-guaranteed-to-be-safe-to-perform-memcpy0-0-0\n *   http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-October/011065.html\n *\n * Not sure what's the required behavior when a pointer points just past the\n * end of a buffer, which often happens in practice (e.g. zero size memmoves).\n * For example, if allocation size is 3, the following pointer would not\n * technically point to a valid memory byte:\n *\n *   <-- alloc -->\n *   | 0 | 1 | 2 | .....\n *                 ^-- p=3, points after last valid byte (2)\n */\n#if !defined(DUK_MEMCPY)\n#if defined(DUK_F_UCLIBC)\n/* Old uclibcs have a broken memcpy so use memmove instead (this is overly wide\n * now on purpose): http://lists.uclibc.org/pipermail/uclibc-cvs/2008-October/025511.html\n */\n#define DUK_MEMCPY       memmove\n#else\n#define DUK_MEMCPY       memcpy\n#endif\n#endif\n#if !defined(DUK_MEMMOVE)\n#define DUK_MEMMOVE      memmove\n#endif\n#if !defined(DUK_MEMCMP)\n#define DUK_MEMCMP       memcmp\n#endif\n#if !defined(DUK_MEMSET)\n#define DUK_MEMSET       memset\n#endif\n#if !defined(DUK_STRLEN)\n#define DUK_STRLEN       strlen\n#endif\n#if !defined(DUK_STRCMP)\n#define DUK_STRCMP       strcmp\n#endif\n#if !defined(DUK_STRNCMP)\n#define DUK_STRNCMP      strncmp\n#endif\n#if !defined(DUK_SPRINTF)\n#define DUK_SPRINTF      sprintf\n#endif\n#if !defined(DUK_SNPRINTF)\n/* snprintf() is technically not part of C89 but usually available. */\n#define DUK_SNPRINTF     snprintf\n#endif\n#if !defined(DUK_VSPRINTF)\n#define DUK_VSPRINTF     vsprintf\n#endif\n#if !defined(DUK_VSNPRINTF)\n/* vsnprintf() is technically not part of C89 but usually available. */\n#define DUK_VSNPRINTF    vsnprintf\n#endif\n#if !defined(DUK_SSCANF)\n#define DUK_SSCANF       sscanf\n#endif\n#if !defined(DUK_VSSCANF)\n#define DUK_VSSCANF      vsscanf\n#endif\n#if !defined(DUK_MEMZERO)\n#define DUK_MEMZERO(p,n) DUK_MEMSET((p), 0, (n))\n#endif\n\n#if !defined(DUK_DOUBLE_INFINITY)\n#undef DUK_USE_COMPUTED_INFINITY\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION < 40600)\n/* GCC older than 4.6: avoid overflow warnings related to using INFINITY */\n#define DUK_DOUBLE_INFINITY  (__builtin_inf())\n#elif defined(INFINITY)\n#define DUK_DOUBLE_INFINITY  ((double) INFINITY)\n#elif !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) && !defined(DUK_F_BCC) && \\\n      !defined(DUK_F_OLD_SOLARIS) && !defined(DUK_F_AIX)\n#define DUK_DOUBLE_INFINITY  (1.0 / 0.0)\n#else\n/* In VBCC (1.0 / 0.0) results in a warning and 0.0 instead of infinity.\n * Use a computed infinity (initialized when a heap is created at the\n * latest).\n */\n#define DUK_USE_COMPUTED_INFINITY\n#define DUK_DOUBLE_INFINITY  duk_computed_infinity\n#endif\n#endif\n\n#if !defined(DUK_DOUBLE_NAN)\n#undef DUK_USE_COMPUTED_NAN\n#if defined(NAN)\n#define DUK_DOUBLE_NAN       NAN\n#elif !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) && !defined(DUK_F_BCC) && \\\n      !defined(DUK_F_OLD_SOLARIS) && !defined(DUK_F_AIX)\n#define DUK_DOUBLE_NAN       (0.0 / 0.0)\n#else\n/* In VBCC (0.0 / 0.0) results in a warning and 0.0 instead of NaN.\n * In MSVC (VS2010 Express) (0.0 / 0.0) results in a compile error.\n * Use a computed NaN (initialized when a heap is created at the\n * latest).\n */\n#define DUK_USE_COMPUTED_NAN\n#define DUK_DOUBLE_NAN       duk_computed_nan\n#endif\n#endif\n\n/* Many platforms are missing fpclassify() and friends, so use replacements\n * if necessary.  The replacement constants (FP_NAN etc) can be anything but\n * match Linux constants now.\n */\n#undef DUK_USE_REPL_FPCLASSIFY\n#undef DUK_USE_REPL_SIGNBIT\n#undef DUK_USE_REPL_ISFINITE\n#undef DUK_USE_REPL_ISNAN\n#undef DUK_USE_REPL_ISINF\n\n/* Complex condition broken into separate parts. */\n#undef DUK_F_USE_REPL_ALL\n#if !(defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO) && \\\n      defined(FP_SUBNORMAL) && defined(FP_NORMAL))\n/* Missing some obvious constants. */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC)\n/* VBCC is missing the built-ins even in C99 mode (perhaps a header issue). */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_AMIGAOS) && defined(DUK_F_M68K)\n/* AmigaOS + M68K seems to have math issues even when using GCC cross\n * compilation.  Use replacements for all AmigaOS versions on M68K\n * regardless of compiler.\n */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_FREEBSD) && defined(DUK_F_CLANG)\n/* Placeholder fix for (detection is wider than necessary):\n * http://llvm.org/bugs/show_bug.cgi?id=17788\n */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_UCLIBC)\n/* At least some uclibc versions have broken floating point math.  For\n * example, fpclassify() can incorrectly classify certain NaN formats.\n * To be safe, use replacements.\n */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_AIX)\n/* Older versions may be missing isnan(), etc. */\n#define DUK_F_USE_REPL_ALL\n#endif\n\n#if defined(DUK_F_USE_REPL_ALL)\n#define DUK_USE_REPL_FPCLASSIFY\n#define DUK_USE_REPL_SIGNBIT\n#define DUK_USE_REPL_ISFINITE\n#define DUK_USE_REPL_ISNAN\n#define DUK_USE_REPL_ISINF\n#define DUK_FPCLASSIFY       duk_repl_fpclassify\n#define DUK_SIGNBIT          duk_repl_signbit\n#define DUK_ISFINITE         duk_repl_isfinite\n#define DUK_ISNAN            duk_repl_isnan\n#define DUK_ISINF            duk_repl_isinf\n#define DUK_FP_NAN           0\n#define DUK_FP_INFINITE      1\n#define DUK_FP_ZERO          2\n#define DUK_FP_SUBNORMAL     3\n#define DUK_FP_NORMAL        4\n#else\n#define DUK_FPCLASSIFY       fpclassify\n#define DUK_SIGNBIT          signbit\n#define DUK_ISFINITE         isfinite\n#define DUK_ISNAN            isnan\n#define DUK_ISINF            isinf\n#define DUK_FP_NAN           FP_NAN\n#define DUK_FP_INFINITE      FP_INFINITE\n#define DUK_FP_ZERO          FP_ZERO\n#define DUK_FP_SUBNORMAL     FP_SUBNORMAL\n#define DUK_FP_NORMAL        FP_NORMAL\n#endif\n\n#if defined(DUK_F_USE_REPL_ALL)\n#undef DUK_F_USE_REPL_ALL\n#endif\n\n/* These functions don't currently need replacement but are wrapped for\n * completeness.  Because these are used as function pointers, they need\n * to be defined as concrete C functions (not macros).\n */\n#if !defined(DUK_FABS)\n#define DUK_FABS             fabs\n#endif\n#if !defined(DUK_FLOOR)\n#define DUK_FLOOR            floor\n#endif\n#if !defined(DUK_CEIL)\n#define DUK_CEIL             ceil\n#endif\n#if !defined(DUK_FMOD)\n#define DUK_FMOD             fmod\n#endif\n#if !defined(DUK_POW)\n#define DUK_POW              pow\n#endif\n#if !defined(DUK_ACOS)\n#define DUK_ACOS             acos\n#endif\n#if !defined(DUK_ASIN)\n#define DUK_ASIN             asin\n#endif\n#if !defined(DUK_ATAN)\n#define DUK_ATAN             atan\n#endif\n#if !defined(DUK_ATAN2)\n#define DUK_ATAN2            atan2\n#endif\n#if !defined(DUK_SIN)\n#define DUK_SIN              sin\n#endif\n#if !defined(DUK_COS)\n#define DUK_COS              cos\n#endif\n#if !defined(DUK_TAN)\n#define DUK_TAN              tan\n#endif\n#if !defined(DUK_EXP)\n#define DUK_EXP              exp\n#endif\n#if !defined(DUK_LOG)\n#define DUK_LOG              log\n#endif\n#if !defined(DUK_SQRT)\n#define DUK_SQRT             sqrt\n#endif\n\n/* The functions below exist only in C99/C++11 or later and need a workaround\n * for platforms that don't include them.  MSVC isn't detected as C99, but\n * these functions also exist in MSVC 2013 and later so include a clause for\n * that too.  Android doesn't have log2; disable all of these for Android.\n */\n#if (defined(DUK_F_C99) || defined(DUK_F_CPP11) || (defined(_MSC_VER) && (_MSC_VER >= 1800))) && \\\n    !defined(DUK_F_ANDROID) && !defined(DUK_F_MINT)\n#if !defined(DUK_CBRT)\n#define DUK_CBRT             cbrt\n#endif\n#if !defined(DUK_LOG2)\n#define DUK_LOG2             log2\n#endif\n#if !defined(DUK_LOG10)\n#define DUK_LOG10            log10\n#endif\n#if !defined(DUK_TRUNC)\n#define DUK_TRUNC            trunc\n#endif\n#endif  /* DUK_F_C99 etc */\n\n/* NetBSD 6.0 x86 (at least) has a few problems with pow() semantics,\n * see test-bug-netbsd-math-pow.js.  MinGW has similar (but different)\n * issues, see test-bug-mingw-math-issues.js.  Enable pow() workarounds\n * for these targets.\n */\n#undef DUK_USE_POW_WORKAROUNDS\n#if defined(DUK_F_NETBSD) || defined(DUK_F_MINGW)\n#define DUK_USE_POW_WORKAROUNDS\n#endif\n\n/* Similar workarounds for atan2() semantics issues.  MinGW issues are\n * documented in test-bug-mingw-math-issues.js.\n */\n#undef DUK_USE_ATAN2_WORKAROUNDS\n#if defined(DUK_F_MINGW)\n#define DUK_USE_ATAN2_WORKAROUNDS\n#endif\n\n/* Rely as little as possible on compiler behavior for NaN comparison,\n * signed zero handling, etc.  Currently never activated but may be needed\n * for broken compilers.\n */\n#undef DUK_USE_PARANOID_MATH\n\n/* There was a curious bug where test-bi-date-canceling.js would fail e.g.\n * on 64-bit Ubuntu, gcc-4.8.1, -m32, and no -std=c99.  Some date computations\n * using doubles would be optimized which then broke some corner case tests.\n * The problem goes away by adding 'volatile' to the datetime computations.\n * Not sure what the actual triggering conditions are, but using this on\n * non-C99 systems solves the known issues and has relatively little cost\n * on other platforms.\n */\n#undef DUK_USE_PARANOID_DATE_COMPUTATION\n#if !defined(DUK_F_C99)\n#define DUK_USE_PARANOID_DATE_COMPUTATION\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/platform_sharedincludes.h.in",
    "content": "/* Shared includes: C89 */\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdarg.h>  /* varargs */\n#include <setjmp.h>\n#include <stddef.h>  /* e.g. ptrdiff_t */\n#include <math.h>\n#include <limits.h>\n\n/* date.h is omitted, and included per platform */\n\n/* Shared includes: stdint.h is C99 */\n#if defined(DUK_F_NO_STDINT_H)\n/* stdint.h not available */\n#else\n/* Technically C99 (C++11) but found in many systems.  On some systems\n * __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS must be defined before\n * including stdint.h (see above).\n */\n#include <stdint.h>\n#endif\n\n/* <exception> is only included if needed, based on DUK_USE_xxx flags. */\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/reject_fast_math.h.in",
    "content": "/* GCC/clang inaccurate math would break compliance and probably duk_tval,\n * so refuse to compile.  Relax this if -ffast-math is tested to work.\n */\n#if defined(__FAST_MATH__)\n#error __FAST_MATH__ defined, refusing to compile\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/types1.h.in",
    "content": "/*\n *  Wrapper typedefs and constants for integer types, also sanity check types.\n *\n *  C99 typedefs are quite good but not always available, and we want to avoid\n *  forcibly redefining the C99 typedefs.  So, there are Duktape wrappers for\n *  all C99 typedefs and Duktape code should only use these typedefs.  Type\n *  detection when C99 is not supported is best effort and may end up detecting\n *  some types incorrectly.\n *\n *  Pointer sizes are a portability problem: pointers to different types may\n *  have a different size and function pointers are very difficult to manage\n *  portably.\n *\n *  http://en.wikipedia.org/wiki/C_data_types#Fixed-width_integer_types\n *\n *  Note: there's an interesting corner case when trying to define minimum\n *  signed integer value constants which leads to the current workaround of\n *  defining e.g. -0x80000000 as (-0x7fffffffL - 1L).  See doc/code-issues.txt\n *  for a longer discussion.\n *\n *  Note: avoid typecasts and computations in macro integer constants as they\n *  can then no longer be used in macro relational expressions (such as\n *  #if DUK_SIZE_MAX < 0xffffffffUL).  There is internal code which relies on\n *  being able to compare DUK_SIZE_MAX against a limit.\n */\n\n/* XXX: add feature options to force basic types from outside? */\n\n#if !defined(INT_MAX)\n#error INT_MAX not defined\n#endif\n\n/* Check that architecture is two's complement, standard C allows e.g.\n * INT_MIN to be -2**31+1 (instead of -2**31).\n */\n#if defined(INT_MAX) && defined(INT_MIN)\n#if INT_MAX != -(INT_MIN + 1)\n#error platform does not seem complement of two\n#endif\n#else\n#error cannot check complement of two\n#endif\n\n/* Pointer size determination based on __WORDSIZE or architecture when\n * that's not available.\n */\n#if defined(DUK_F_X86) || defined(DUK_F_X32) || \\\n    defined(DUK_F_M68K) || defined(DUK_F_PPC32) || \\\n    defined(DUK_F_BCC) || \\\n    (defined(__WORDSIZE) && (__WORDSIZE == 32)) || \\\n    ((defined(DUK_F_OLD_SOLARIS) || defined(DUK_F_AIX) || \\\n      defined(DUK_F_HPUX)) && defined(_ILP32)) || \\\n    defined(DUK_F_ARM32)\n#define DUK_F_32BIT_PTRS\n#elif defined(DUK_F_X64) || \\\n      (defined(__WORDSIZE) && (__WORDSIZE == 64)) || \\\n   ((defined(DUK_F_OLD_SOLARIS) || defined(DUK_F_AIX) || \\\n     defined(DUK_F_HPUX)) && defined(_LP64)) || \\\n    defined(DUK_F_ARM64)\n#define DUK_F_64BIT_PTRS\n#else\n/* not sure, not needed with C99 anyway */\n#endif\n\n/* Intermediate define for 'have inttypes.h' */\n#undef DUK_F_HAVE_INTTYPES\n#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \\\n    !(defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC))\n/* vbcc + AmigaOS has C99 but no inttypes.h */\n#define DUK_F_HAVE_INTTYPES\n#elif defined(__cplusplus) && (__cplusplus >= 201103L)\n/* C++11 apparently ratified stdint.h */\n#define DUK_F_HAVE_INTTYPES\n#endif\n\n/* Basic integer typedefs and limits, preferably from inttypes.h, otherwise\n * through automatic detection.\n */\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/types2.h.in",
    "content": "/* A few types are assumed to always exist. */\ntypedef size_t duk_size_t;\ntypedef ptrdiff_t duk_ptrdiff_t;\n\n/* The best type for an \"all around int\" in Duktape internals is \"at least\n * 32 bit signed integer\" which is most convenient.  Same for unsigned type.\n * Prefer 'int' when large enough, as it is almost always a convenient type.\n */\n#if defined(UINT_MAX) && (UINT_MAX >= 0xffffffffUL)\ntypedef int duk_int_t;\ntypedef unsigned int duk_uint_t;\n#define DUK_INT_MIN           INT_MIN\n#define DUK_INT_MAX           INT_MAX\n#define DUK_UINT_MIN          0\n#define DUK_UINT_MAX          UINT_MAX\n#else\ntypedef duk_int_fast32_t duk_int_t;\ntypedef duk_uint_fast32_t duk_uint_t;\n#define DUK_INT_MIN           DUK_INT_FAST32_MIN\n#define DUK_INT_MAX           DUK_INT_FAST32_MAX\n#define DUK_UINT_MIN          DUK_UINT_FAST32_MIN\n#define DUK_UINT_MAX          DUK_UINT_FAST32_MAX\n#endif\n\n/* Same as 'duk_int_t' but guaranteed to be a 'fast' variant if this\n * distinction matters for the CPU.  These types are used mainly in the\n * executor where it might really matter.\n */\ntypedef duk_int_fast32_t duk_int_fast_t;\ntypedef duk_uint_fast32_t duk_uint_fast_t;\n#define DUK_INT_FAST_MIN      DUK_INT_FAST32_MIN\n#define DUK_INT_FAST_MAX      DUK_INT_FAST32_MAX\n#define DUK_UINT_FAST_MIN     DUK_UINT_FAST32_MIN\n#define DUK_UINT_FAST_MAX     DUK_UINT_FAST32_MAX\n\n/* Small integers (16 bits or more) can fall back to the 'int' type, but\n * have a typedef so they are marked \"small\" explicitly.\n */\ntypedef int duk_small_int_t;\ntypedef unsigned int duk_small_uint_t;\n#define DUK_SMALL_INT_MIN     INT_MIN\n#define DUK_SMALL_INT_MAX     INT_MAX\n#define DUK_SMALL_UINT_MIN    0\n#define DUK_SMALL_UINT_MAX    UINT_MAX\n\n/* Fast variants of small integers, again for really fast paths like the\n * executor.\n */\ntypedef duk_int_fast16_t duk_small_int_fast_t;\ntypedef duk_uint_fast16_t duk_small_uint_fast_t;\n#define DUK_SMALL_INT_FAST_MIN    DUK_INT_FAST16_MIN\n#define DUK_SMALL_INT_FAST_MAX    DUK_INT_FAST16_MAX\n#define DUK_SMALL_UINT_FAST_MIN   DUK_UINT_FAST16_MIN\n#define DUK_SMALL_UINT_FAST_MAX   DUK_UINT_FAST16_MAX\n\n/* Boolean values are represented with the platform 'unsigned int'. */\ntypedef duk_small_uint_t duk_bool_t;\n#define DUK_BOOL_MIN              DUK_SMALL_UINT_MIN\n#define DUK_BOOL_MAX              DUK_SMALL_UINT_MAX\n\n/* Index values must have at least 32-bit signed range. */\ntypedef duk_int_t duk_idx_t;\n#define DUK_IDX_MIN               DUK_INT_MIN\n#define DUK_IDX_MAX               DUK_INT_MAX\n\n/* Unsigned index variant. */\ntypedef duk_uint_t duk_uidx_t;\n#define DUK_UIDX_MIN              DUK_UINT_MIN\n#define DUK_UIDX_MAX              DUK_UINT_MAX\n\n/* Array index values, could be exact 32 bits.\n * Currently no need for signed duk_arridx_t.\n */\ntypedef duk_uint_t duk_uarridx_t;\n#define DUK_UARRIDX_MIN           DUK_UINT_MIN\n#define DUK_UARRIDX_MAX           DUK_UINT_MAX\n\n/* Duktape/C function return value, platform int is enough for now to\n * represent 0, 1, or negative error code.  Must be compatible with\n * assigning truth values (e.g. duk_ret_t rc = (foo == bar);).\n */\ntypedef duk_small_int_t duk_ret_t;\n#define DUK_RET_MIN               DUK_SMALL_INT_MIN\n#define DUK_RET_MAX               DUK_SMALL_INT_MAX\n\n/* Error codes are represented with platform int.  High bits are used\n * for flags and such, so 32 bits are needed.\n */\ntypedef duk_int_t duk_errcode_t;\n#define DUK_ERRCODE_MIN           DUK_INT_MIN\n#define DUK_ERRCODE_MAX           DUK_INT_MAX\n\n/* Codepoint type.  Must be 32 bits or more because it is used also for\n * internal codepoints.  The type is signed because negative codepoints\n * are used as internal markers (e.g. to mark EOF or missing argument).\n * (X)UTF-8/CESU-8 encode/decode take and return an unsigned variant to\n * ensure duk_uint32_t casts back and forth nicely.  Almost everything\n * else uses the signed one.\n */\ntypedef duk_int_t duk_codepoint_t;\ntypedef duk_uint_t duk_ucodepoint_t;\n#define DUK_CODEPOINT_MIN         DUK_INT_MIN\n#define DUK_CODEPOINT_MAX         DUK_INT_MAX\n#define DUK_UCODEPOINT_MIN        DUK_UINT_MIN\n#define DUK_UCODEPOINT_MAX        DUK_UINT_MAX\n\n/* IEEE float/double typedef. */\ntypedef float duk_float_t;\ntypedef double duk_double_t;\n\n/* We're generally assuming that we're working on a platform with a 32-bit\n * address space.  If DUK_SIZE_MAX is a typecast value (which is necessary\n * if SIZE_MAX is missing), the check must be avoided because the\n * preprocessor can't do a comparison.\n */\n#if !defined(DUK_SIZE_MAX)\n#error DUK_SIZE_MAX is undefined, probably missing SIZE_MAX\n#elif !defined(DUK_SIZE_MAX_COMPUTED)\n#if DUK_SIZE_MAX < 0xffffffffUL\n/* On some systems SIZE_MAX can be smaller than max unsigned 32-bit value\n * which seems incorrect if size_t is (at least) an unsigned 32-bit type.\n * However, it doesn't seem useful to error out compilation if this is the\n * case.\n */\n#endif\n#endif\n\n/* Type used in public API declarations and user code.  Typedef maps to\n * 'struct duk_hthread' like the 'duk_hthread' typedef which is used\n * exclusively in internals.\n */\ntypedef struct duk_hthread duk_context;\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/types_c99.h.in",
    "content": "#define DUK_F_HAVE_64BIT\n#include <inttypes.h>\n\ntypedef uint8_t duk_uint8_t;\ntypedef int8_t duk_int8_t;\ntypedef uint16_t duk_uint16_t;\ntypedef int16_t duk_int16_t;\ntypedef uint32_t duk_uint32_t;\ntypedef int32_t duk_int32_t;\ntypedef uint64_t duk_uint64_t;\ntypedef int64_t duk_int64_t;\ntypedef uint_least8_t duk_uint_least8_t;\ntypedef int_least8_t duk_int_least8_t;\ntypedef uint_least16_t duk_uint_least16_t;\ntypedef int_least16_t duk_int_least16_t;\ntypedef uint_least32_t duk_uint_least32_t;\ntypedef int_least32_t duk_int_least32_t;\ntypedef uint_least64_t duk_uint_least64_t;\ntypedef int_least64_t duk_int_least64_t;\ntypedef uint_fast8_t duk_uint_fast8_t;\ntypedef int_fast8_t duk_int_fast8_t;\ntypedef uint_fast16_t duk_uint_fast16_t;\ntypedef int_fast16_t duk_int_fast16_t;\ntypedef uint_fast32_t duk_uint_fast32_t;\ntypedef int_fast32_t duk_int_fast32_t;\ntypedef uint_fast64_t duk_uint_fast64_t;\ntypedef int_fast64_t duk_int_fast64_t;\ntypedef uintptr_t duk_uintptr_t;\ntypedef intptr_t duk_intptr_t;\ntypedef uintmax_t duk_uintmax_t;\ntypedef intmax_t duk_intmax_t;\n\n#define DUK_UINT8_MIN         0\n#define DUK_UINT8_MAX         UINT8_MAX\n#define DUK_INT8_MIN          INT8_MIN\n#define DUK_INT8_MAX          INT8_MAX\n#define DUK_UINT_LEAST8_MIN   0\n#define DUK_UINT_LEAST8_MAX   UINT_LEAST8_MAX\n#define DUK_INT_LEAST8_MIN    INT_LEAST8_MIN\n#define DUK_INT_LEAST8_MAX    INT_LEAST8_MAX\n#define DUK_UINT_FAST8_MIN    0\n#define DUK_UINT_FAST8_MAX    UINT_FAST8_MAX\n#define DUK_INT_FAST8_MIN     INT_FAST8_MIN\n#define DUK_INT_FAST8_MAX     INT_FAST8_MAX\n#define DUK_UINT16_MIN        0\n#define DUK_UINT16_MAX        UINT16_MAX\n#define DUK_INT16_MIN         INT16_MIN\n#define DUK_INT16_MAX         INT16_MAX\n#define DUK_UINT_LEAST16_MIN  0\n#define DUK_UINT_LEAST16_MAX  UINT_LEAST16_MAX\n#define DUK_INT_LEAST16_MIN   INT_LEAST16_MIN\n#define DUK_INT_LEAST16_MAX   INT_LEAST16_MAX\n#define DUK_UINT_FAST16_MIN   0\n#define DUK_UINT_FAST16_MAX   UINT_FAST16_MAX\n#define DUK_INT_FAST16_MIN    INT_FAST16_MIN\n#define DUK_INT_FAST16_MAX    INT_FAST16_MAX\n#define DUK_UINT32_MIN        0\n#define DUK_UINT32_MAX        UINT32_MAX\n#define DUK_INT32_MIN         INT32_MIN\n#define DUK_INT32_MAX         INT32_MAX\n#define DUK_UINT_LEAST32_MIN  0\n#define DUK_UINT_LEAST32_MAX  UINT_LEAST32_MAX\n#define DUK_INT_LEAST32_MIN   INT_LEAST32_MIN\n#define DUK_INT_LEAST32_MAX   INT_LEAST32_MAX\n#define DUK_UINT_FAST32_MIN   0\n#define DUK_UINT_FAST32_MAX   UINT_FAST32_MAX\n#define DUK_INT_FAST32_MIN    INT_FAST32_MIN\n#define DUK_INT_FAST32_MAX    INT_FAST32_MAX\n#define DUK_UINT64_MIN        0\n#define DUK_UINT64_MAX        UINT64_MAX\n#define DUK_INT64_MIN         INT64_MIN\n#define DUK_INT64_MAX         INT64_MAX\n#define DUK_UINT_LEAST64_MIN  0\n#define DUK_UINT_LEAST64_MAX  UINT_LEAST64_MAX\n#define DUK_INT_LEAST64_MIN   INT_LEAST64_MIN\n#define DUK_INT_LEAST64_MAX   INT_LEAST64_MAX\n#define DUK_UINT_FAST64_MIN   0\n#define DUK_UINT_FAST64_MAX   UINT_FAST64_MAX\n#define DUK_INT_FAST64_MIN    INT_FAST64_MIN\n#define DUK_INT_FAST64_MAX    INT_FAST64_MAX\n\n#define DUK_UINTPTR_MIN       0\n#define DUK_UINTPTR_MAX       UINTPTR_MAX\n#define DUK_INTPTR_MIN        INTPTR_MIN\n#define DUK_INTPTR_MAX        INTPTR_MAX\n\n#define DUK_UINTMAX_MIN       0\n#define DUK_UINTMAX_MAX       UINTMAX_MAX\n#define DUK_INTMAX_MIN        INTMAX_MIN\n#define DUK_INTMAX_MAX        INTMAX_MAX\n\n#define DUK_SIZE_MIN          0\n#define DUK_SIZE_MAX          SIZE_MAX\n#undef DUK_SIZE_MAX_COMPUTED\n"
  },
  {
    "path": "react_juce/duktape/config/header-snippets/types_legacy.h.in",
    "content": "/* When C99 types are not available, we use heuristic detection to get\n * the basic 8, 16, 32, and (possibly) 64 bit types.  The fast/least\n * types are then assumed to be exactly the same for now: these could\n * be improved per platform but C99 types are very often now available.\n * 64-bit types are not available on all platforms; this is OK at least\n * on 32-bit platforms.\n *\n * This detection code is necessarily a bit hacky and can provide typedefs\n * and defines that won't work correctly on some exotic platform.\n */\n\n#if (defined(CHAR_BIT) && (CHAR_BIT == 8)) || \\\n    (defined(UCHAR_MAX) && (UCHAR_MAX == 255))\ntypedef unsigned char duk_uint8_t;\ntypedef signed char duk_int8_t;\n#else\n#error cannot detect 8-bit type\n#endif\n\n#if defined(USHRT_MAX) && (USHRT_MAX == 65535UL)\ntypedef unsigned short duk_uint16_t;\ntypedef signed short duk_int16_t;\n#elif defined(UINT_MAX) && (UINT_MAX == 65535UL)\n/* On some platforms int is 16-bit but long is 32-bit (e.g. PureC) */\ntypedef unsigned int duk_uint16_t;\ntypedef signed int duk_int16_t;\n#else\n#error cannot detect 16-bit type\n#endif\n\n#if defined(UINT_MAX) && (UINT_MAX == 4294967295UL)\ntypedef unsigned int duk_uint32_t;\ntypedef signed int duk_int32_t;\n#elif defined(ULONG_MAX) && (ULONG_MAX == 4294967295UL)\n/* On some platforms int is 16-bit but long is 32-bit (e.g. PureC) */\ntypedef unsigned long duk_uint32_t;\ntypedef signed long duk_int32_t;\n#else\n#error cannot detect 32-bit type\n#endif\n\n/* 64-bit type detection is a bit tricky.\n *\n * ULLONG_MAX is a standard define.  __LONG_LONG_MAX__ and __ULONG_LONG_MAX__\n * are used by at least GCC (even if system headers don't provide ULLONG_MAX).\n * Some GCC variants may provide __LONG_LONG_MAX__ but not __ULONG_LONG_MAX__.\n *\n * ULL / LL constants are rejected / warned about by some compilers, even if\n * the compiler has a 64-bit type and the compiler/system headers provide an\n * unsupported constant (ULL/LL)!  Try to avoid using ULL / LL constants.\n * As a side effect we can only check that e.g. ULONG_MAX is larger than 32\n * bits but can't be sure it is exactly 64 bits.  Self tests will catch such\n * cases.\n */\n#undef DUK_F_HAVE_64BIT\n#if !defined(DUK_F_HAVE_64BIT) && defined(ULONG_MAX)\n#if (ULONG_MAX > 4294967295UL)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long duk_uint64_t;\ntypedef signed long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(ULLONG_MAX)\n#if (ULLONG_MAX > 4294967295UL)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long long duk_uint64_t;\ntypedef signed long long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(__ULONG_LONG_MAX__)\n#if (__ULONG_LONG_MAX__ > 4294967295UL)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long long duk_uint64_t;\ntypedef signed long long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(__LONG_LONG_MAX__)\n#if (__LONG_LONG_MAX__ > 2147483647L)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long long duk_uint64_t;\ntypedef signed long long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(DUK_F_MINGW)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long duk_uint64_t;\ntypedef signed long duk_int64_t;\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(DUK_F_MSVC)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned __int64 duk_uint64_t;\ntypedef signed __int64 duk_int64_t;\n#endif\n#if !defined(DUK_F_HAVE_64BIT)\n/* cannot detect 64-bit type, not always needed so don't error */\n#endif\n\ntypedef duk_uint8_t duk_uint_least8_t;\ntypedef duk_int8_t duk_int_least8_t;\ntypedef duk_uint16_t duk_uint_least16_t;\ntypedef duk_int16_t duk_int_least16_t;\ntypedef duk_uint32_t duk_uint_least32_t;\ntypedef duk_int32_t duk_int_least32_t;\ntypedef duk_uint8_t duk_uint_fast8_t;\ntypedef duk_int8_t duk_int_fast8_t;\ntypedef duk_uint16_t duk_uint_fast16_t;\ntypedef duk_int16_t duk_int_fast16_t;\ntypedef duk_uint32_t duk_uint_fast32_t;\ntypedef duk_int32_t duk_int_fast32_t;\n#if defined(DUK_F_HAVE_64BIT)\ntypedef duk_uint64_t duk_uint_least64_t;\ntypedef duk_int64_t duk_int_least64_t;\ntypedef duk_uint64_t duk_uint_fast64_t;\ntypedef duk_int64_t duk_int_fast64_t;\n#endif\n#if defined(DUK_F_HAVE_64BIT)\ntypedef duk_uint64_t duk_uintmax_t;\ntypedef duk_int64_t duk_intmax_t;\n#else\ntypedef duk_uint32_t duk_uintmax_t;\ntypedef duk_int32_t duk_intmax_t;\n#endif\n\n/* Note: the funny looking computations for signed minimum 16-bit, 32-bit, and\n * 64-bit values are intentional as the obvious forms (e.g. -0x80000000L) are\n * -not- portable.  See code-issues.txt for a detailed discussion.\n */\n#define DUK_UINT8_MIN         0UL\n#define DUK_UINT8_MAX         0xffUL\n#define DUK_INT8_MIN          (-0x80L)\n#define DUK_INT8_MAX          0x7fL\n#define DUK_UINT_LEAST8_MIN   0UL\n#define DUK_UINT_LEAST8_MAX   0xffUL\n#define DUK_INT_LEAST8_MIN    (-0x80L)\n#define DUK_INT_LEAST8_MAX    0x7fL\n#define DUK_UINT_FAST8_MIN    0UL\n#define DUK_UINT_FAST8_MAX    0xffUL\n#define DUK_INT_FAST8_MIN     (-0x80L)\n#define DUK_INT_FAST8_MAX     0x7fL\n#define DUK_UINT16_MIN        0UL\n#define DUK_UINT16_MAX        0xffffUL\n#define DUK_INT16_MIN         (-0x7fffL - 1L)\n#define DUK_INT16_MAX         0x7fffL\n#define DUK_UINT_LEAST16_MIN  0UL\n#define DUK_UINT_LEAST16_MAX  0xffffUL\n#define DUK_INT_LEAST16_MIN   (-0x7fffL - 1L)\n#define DUK_INT_LEAST16_MAX   0x7fffL\n#define DUK_UINT_FAST16_MIN   0UL\n#define DUK_UINT_FAST16_MAX   0xffffUL\n#define DUK_INT_FAST16_MIN    (-0x7fffL - 1L)\n#define DUK_INT_FAST16_MAX    0x7fffL\n#define DUK_UINT32_MIN        0UL\n#define DUK_UINT32_MAX        0xffffffffUL\n#define DUK_INT32_MIN         (-0x7fffffffL - 1L)\n#define DUK_INT32_MAX         0x7fffffffL\n#define DUK_UINT_LEAST32_MIN  0UL\n#define DUK_UINT_LEAST32_MAX  0xffffffffUL\n#define DUK_INT_LEAST32_MIN   (-0x7fffffffL - 1L)\n#define DUK_INT_LEAST32_MAX   0x7fffffffL\n#define DUK_UINT_FAST32_MIN   0UL\n#define DUK_UINT_FAST32_MAX   0xffffffffUL\n#define DUK_INT_FAST32_MIN    (-0x7fffffffL - 1L)\n#define DUK_INT_FAST32_MAX    0x7fffffffL\n\n/* 64-bit constants.  Since LL / ULL constants are not always available,\n * use computed values.  These values can't be used in preprocessor\n * comparisons; flag them as such.\n */\n#if defined(DUK_F_HAVE_64BIT)\n#define DUK_UINT64_MIN        ((duk_uint64_t) 0)\n#define DUK_UINT64_MAX        ((duk_uint64_t) -1)\n#define DUK_INT64_MIN         ((duk_int64_t) (~(DUK_UINT64_MAX >> 1)))\n#define DUK_INT64_MAX         ((duk_int64_t) (DUK_UINT64_MAX >> 1))\n#define DUK_UINT_LEAST64_MIN  DUK_UINT64_MIN\n#define DUK_UINT_LEAST64_MAX  DUK_UINT64_MAX\n#define DUK_INT_LEAST64_MIN   DUK_INT64_MIN\n#define DUK_INT_LEAST64_MAX   DUK_INT64_MAX\n#define DUK_UINT_FAST64_MIN   DUK_UINT64_MIN\n#define DUK_UINT_FAST64_MAX   DUK_UINT64_MAX\n#define DUK_INT_FAST64_MIN    DUK_INT64_MIN\n#define DUK_INT_FAST64_MAX    DUK_INT64_MAX\n#define DUK_UINT64_MIN_COMPUTED\n#define DUK_UINT64_MAX_COMPUTED\n#define DUK_INT64_MIN_COMPUTED\n#define DUK_INT64_MAX_COMPUTED\n#define DUK_UINT_LEAST64_MIN_COMPUTED\n#define DUK_UINT_LEAST64_MAX_COMPUTED\n#define DUK_INT_LEAST64_MIN_COMPUTED\n#define DUK_INT_LEAST64_MAX_COMPUTED\n#define DUK_UINT_FAST64_MIN_COMPUTED\n#define DUK_UINT_FAST64_MAX_COMPUTED\n#define DUK_INT_FAST64_MIN_COMPUTED\n#define DUK_INT_FAST64_MAX_COMPUTED\n#endif\n\n#if defined(DUK_F_HAVE_64BIT)\n#define DUK_UINTMAX_MIN       DUK_UINT64_MIN\n#define DUK_UINTMAX_MAX       DUK_UINT64_MAX\n#define DUK_INTMAX_MIN        DUK_INT64_MIN\n#define DUK_INTMAX_MAX        DUK_INT64_MAX\n#define DUK_UINTMAX_MIN_COMPUTED\n#define DUK_UINTMAX_MAX_COMPUTED\n#define DUK_INTMAX_MIN_COMPUTED\n#define DUK_INTMAX_MAX_COMPUTED\n#else\n#define DUK_UINTMAX_MIN       0UL\n#define DUK_UINTMAX_MAX       0xffffffffUL\n#define DUK_INTMAX_MIN        (-0x7fffffffL - 1L)\n#define DUK_INTMAX_MAX        0x7fffffffL\n#endif\n\n/* This detection is not very reliable. */\n#if defined(DUK_F_32BIT_PTRS)\ntypedef duk_int32_t duk_intptr_t;\ntypedef duk_uint32_t duk_uintptr_t;\n#define DUK_UINTPTR_MIN       DUK_UINT32_MIN\n#define DUK_UINTPTR_MAX       DUK_UINT32_MAX\n#define DUK_INTPTR_MIN        DUK_INT32_MIN\n#define DUK_INTPTR_MAX        DUK_INT32_MAX\n#elif defined(DUK_F_64BIT_PTRS) && defined(DUK_F_HAVE_64BIT)\ntypedef duk_int64_t duk_intptr_t;\ntypedef duk_uint64_t duk_uintptr_t;\n#define DUK_UINTPTR_MIN       DUK_UINT64_MIN\n#define DUK_UINTPTR_MAX       DUK_UINT64_MAX\n#define DUK_INTPTR_MIN        DUK_INT64_MIN\n#define DUK_INTPTR_MAX        DUK_INT64_MAX\n#define DUK_UINTPTR_MIN_COMPUTED\n#define DUK_UINTPTR_MAX_COMPUTED\n#define DUK_INTPTR_MIN_COMPUTED\n#define DUK_INTPTR_MAX_COMPUTED\n#else\n#error cannot determine intptr type\n#endif\n\n/* SIZE_MAX may be missing so use an approximate value for it. */\n#undef DUK_SIZE_MAX_COMPUTED\n#if !defined(SIZE_MAX)\n#define DUK_SIZE_MAX_COMPUTED\n#define SIZE_MAX              ((size_t) (-1))\n#endif\n#define DUK_SIZE_MIN          0\n#define DUK_SIZE_MAX          SIZE_MAX\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_AIX.h.in",
    "content": "/* AIX */\n#if defined(_AIX)\n/* defined(__xlc__) || defined(__IBMC__): works but too wide */\n#define DUK_F_AIX\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_AMIGAOS.h.in",
    "content": "/* AmigaOS.  Neither AMIGA nor __amigaos__ is defined on VBCC, so user must\n * define 'AMIGA' manually when using VBCC.\n */\n#if defined(AMIGA) || defined(__amigaos__)\n#define DUK_F_AMIGAOS\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_ANDROID.h.in",
    "content": "#if defined(ANDROID) || defined(__ANDROID__)\n#define DUK_F_ANDROID\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_APPLE.h.in",
    "content": "/* Apple OSX, iOS */\n#if defined(__APPLE__)\n#define DUK_F_APPLE\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_ARM.h.in",
    "content": "/* ARM */\n#if defined(__arm__) || defined(__thumb__) || defined(_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__)\n#define DUK_F_ARM\n#if defined(__LP64__) || defined(_LP64) || defined(__arm64) || defined(__arm64__) || defined(_M_ARM64) || defined(__aarch64__)\n#define DUK_F_ARM64\n#else\n#define DUK_F_ARM32\n#endif\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_BCC.h.in",
    "content": "/* BCC (Bruce's C compiler): this is a \"torture target\" for compilation */\n#if defined(__BCC__) || defined(__BCC_VERSION__)\n#define DUK_F_BCC\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_BSD.h.in",
    "content": "/* BSD variant */\n#if defined(DUK_F_FREEBSD) || defined(DUK_F_NETBSD) || defined(DUK_F_OPENBSD) || \\\n    defined(__bsdi__) || defined(__DragonFly__)\n#define DUK_F_BSD\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_C99.h.in",
    "content": "/* C99 or above */\n#undef DUK_F_C99\n#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)\n#define DUK_F_C99\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_CLANG.h.in",
    "content": "/* Clang */\n#if defined(__clang__)\n#define DUK_F_CLANG\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_CPP.h.in",
    "content": "/* C++ */\n#undef DUK_F_CPP\n#if defined(__cplusplus)\n#define DUK_F_CPP\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_CPP11.h.in",
    "content": "/* C++11 or above */\n#undef DUK_F_CPP11\n#if defined(__cplusplus) && (__cplusplus >= 201103L)\n#define DUK_F_CPP11\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_CYGWIN.h.in",
    "content": "/* Cygwin */\n#if defined(__CYGWIN__)\n#define DUK_F_CYGWIN\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_DURANGO.h.in",
    "content": "/* Durango (Xbox One) */\n#if defined(_DURANGO) || defined(_XBOX_ONE)\n#define DUK_F_DURANGO\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_EMSCRIPTEN.h.in",
    "content": "/* Emscripten (provided explicitly by user), improve if possible */\n#if defined(EMSCRIPTEN)\n#define DUK_F_EMSCRIPTEN\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_FLASHPLAYER.h.in",
    "content": "/* Flash player (e.g. Crossbridge) */\n#if defined(__FLASHPLAYER__)\n#define DUK_F_FLASHPLAYER\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_FREEBSD.h.in",
    "content": "/* FreeBSD */\n#if defined(__FreeBSD__) || defined(__FreeBSD)\n#define DUK_F_FREEBSD\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_GCC.h.in",
    "content": "/* GCC.  Clang also defines __GNUC__ so don't detect GCC if using Clang. */\n#if defined(__GNUC__) && !defined(__clang__) && !defined(DUK_F_CLANG)\n#define DUK_F_GCC\n#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)\n/* Convenience, e.g. gcc 4.5.1 == 40501; http://stackoverflow.com/questions/6031819/emulating-gccs-builtin-unreachable */\n#define DUK_F_GCC_VERSION  (__GNUC__ * 10000L + __GNUC_MINOR__ * 100L + __GNUC_PATCHLEVEL__)\n#else\n#error cannot figure out gcc version\n#endif\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_HPUX.h.in",
    "content": "/* HPUX */\n#if defined(__hpux)\n#define DUK_F_HPUX\n#if defined(__ia64)\n#define DUK_F_HPUX_ITANIUM\n#endif\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_LINUX.h.in",
    "content": "/* Linux */\n#if defined(__linux) || defined(__linux__) || defined(linux)\n#define DUK_F_LINUX\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_M68K.h.in",
    "content": "/* Motorola 68K.  Not defined by VBCC, so user must define one of these\n * manually when using VBCC.\n */\n#if defined(__m68k__) || defined(M68000) || defined(__MC68K__)\n#define DUK_F_M68K\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_MINGW.h.in",
    "content": "/* MinGW.  Also GCC flags (DUK_F_GCC) are enabled now. */\n#if defined(__MINGW32__) || defined(__MINGW64__)\n#define DUK_F_MINGW\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_MINT.h.in",
    "content": "/* Atari Mint */\n#if defined(__MINT__)\n#define DUK_F_MINT\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_MIPS.h.in",
    "content": "/* MIPS.  Related defines: __MIPSEB__, __MIPSEL__, __mips_isa_rev, __LP64__ */\n#if defined(__mips__) || defined(mips) || defined(_MIPS_ISA) || \\\n    defined(_R3000) || defined(_R4000) || defined(_R5900) || \\\n    defined(_MIPS_ISA_MIPS1) || defined(_MIPS_ISA_MIPS2) || \\\n    defined(_MIPS_ISA_MIPS3) || defined(_MIPS_ISA_MIPS4) || \\\n    defined(__mips) || defined(__MIPS__)\n#define DUK_F_MIPS\n#if defined(__LP64__) || defined(_LP64) || defined(__mips64) || \\\n    defined(__mips64__) || defined(__mips_n64)\n#define DUK_F_MIPS64\n#else\n#define DUK_F_MIPS32\n#endif\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_MSVC.h.in",
    "content": "/* MSVC */\n#if defined(_MSC_VER)\n/* MSVC preprocessor defines: http://msdn.microsoft.com/en-us/library/b0084kay.aspx\n * _MSC_FULL_VER includes the build number, but it has at least two formats, see e.g.\n * BOOST_MSVC_FULL_VER in http://www.boost.org/doc/libs/1_52_0/boost/config/compiler/visualc.hpp\n */\n#define DUK_F_MSVC\n#if defined(_MSC_FULL_VER)\n#if (_MSC_FULL_VER > 100000000)\n#define DUK_F_MSVC_FULL_VER _MSC_FULL_VER\n#else\n#define DUK_F_MSCV_FULL_VER (_MSC_FULL_VER * 10)\n#endif\n#endif\n#endif  /* _MSC_VER */\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_NETBSD.h.in",
    "content": "/* NetBSD */\n#if defined(__NetBSD__) || defined(__NetBSD)\n#define DUK_F_NETBSD\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_NO_STDINT_H.h.in",
    "content": "/* stdint.h not available */\n#if defined(DUK_F_WINDOWS) && defined(_MSC_VER)\n#if (_MSC_VER < 1700)\n/* VS2012+ has stdint.h, < VS2012 does not (but it's available for download). */\n#define DUK_F_NO_STDINT_H\n#endif\n#endif\n#if !defined(DUK_F_NO_STDINT_H) && (defined(DUK_F_TOS) || defined(DUK_F_BCC))\n#define DUK_F_NO_STDINT_H\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_OPENBSD.h.in",
    "content": "/* OpenBSD */\n#if defined(__OpenBSD__) || defined(__OpenBSD)\n#define DUK_F_OPENBSD\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_ORBIS.h.in",
    "content": "/* Orbis (PS4) variant */\n#if defined(DUK_F_FREEBSD) && defined(__ORBIS__)\n#define DUK_F_ORBIS\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_POSIX.h.in",
    "content": "/* POSIX */\n#if defined(__posix)\n#define DUK_F_POSIX\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_PPC.h.in",
    "content": "/* PowerPC */\n#if defined(__powerpc) || defined(__powerpc__) || defined(__PPC__)\n#define DUK_F_PPC\n#if defined(__PPC64__) || defined(__LP64__) || defined(_LP64)\n#define DUK_F_PPC64\n#else\n#define DUK_F_PPC32\n#endif\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_QNX.h.in",
    "content": "/* QNX */\n#if defined(__QNX__)\n#define DUK_F_QNX\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_SPARC.h.in",
    "content": "/* SPARC */\n#if defined(sparc) || defined(__sparc) || defined(__sparc__)\n#define DUK_F_SPARC\n#if defined(__LP64__) || defined(_LP64)\n#define DUK_F_SPARC64\n#else\n#define DUK_F_SPARC32\n#endif\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_SUN.h.in",
    "content": "/* illumos / Solaris */\n#if defined(__sun) && defined(__SVR4)\n#define DUK_F_SUN\n#if defined(__SUNPRO_C) && (__SUNPRO_C < 0x550)\n#define DUK_F_OLD_SOLARIS\n/* Defines _ILP32 / _LP64 required by DUK_F_X86/DUK_F_X64.  Platforms\n * are processed before architectures, so this happens before the\n * DUK_F_X86/DUK_F_X64 detection is emitted.\n */\n#include <sys/isa_defs.h>\n#endif\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_SUPERH.h.in",
    "content": "/* SuperH */\n#if defined(__sh__) || \\\n    defined(__sh1__) || defined(__SH1__) || \\\n    defined(__sh2__) || defined(__SH2__) || \\\n    defined(__sh3__) || defined(__SH3__) || \\\n    defined(__sh4__) || defined(__SH4__) || \\\n    defined(__sh5__) || defined(__SH5__)\n#define DUK_F_SUPERH\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_TINSPIRE.h.in",
    "content": "/* TI-Nspire (using Ndless) */\n#if defined(_TINSPIRE)\n#define DUK_F_TINSPIRE\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_TINYC.h.in",
    "content": "/* TinyC */\n#if defined(__TINYC__)\n/* http://bellard.org/tcc/tcc-doc.html#SEC9 */\n#define DUK_F_TINYC\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_TOS.h.in",
    "content": "/* Atari ST TOS.  __TOS__ defined by PureC.  No platform define in VBCC\n * apparently, so to use with VBCC user must define __TOS__ manually.\n  */\n#if defined(__TOS__)\n#define DUK_F_TOS\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_UCLIBC.h.in",
    "content": "/* uclibc */\n#if defined(__UCLIBC__)\n#define DUK_F_UCLIBC\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_ULL_CONSTS.h.in",
    "content": "/* ULL / LL preprocessor constants should be avoided because they're not\n * always available.  With suitable options, some compilers will support\n * 64-bit integer types but won't support ULL / LL preprocessor constants.\n * Assume C99/C++11 environments have these.  However, BCC is nominally\n * C99 but doesn't support these constants.\n */\n#if (defined(DUK_F_C99) || defined(DUK_F_CPP11)) && !defined(DUK_F_BCC)\n#define DUK_F_ULL_CONSTS\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_UNIX.h.in",
    "content": "/* Generic Unix (includes Cygwin) */\n#if defined(__unix) || defined(__unix__) || defined(unix) || \\\n    defined(DUK_F_LINUX) || defined(DUK_F_BSD)\n#define DUK_F_UNIX\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_VBCC.h.in",
    "content": "/* VBCC */\n#if defined(__VBCC__)\n#define DUK_F_VBCC\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_WINDOWS.h.in",
    "content": "/* Windows, both 32-bit and 64-bit */\n#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64) || \\\n    defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__)\n#define DUK_F_WINDOWS\n#if defined(_WIN64) || defined(WIN64)\n#define DUK_F_WIN64\n#else\n#define DUK_F_WIN32\n#endif\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/helper-snippets/DUK_F_X86.h.in",
    "content": "/* Intel x86 (32-bit), x64 (64-bit) or x32 (64-bit but 32-bit pointers),\n * define only one of DUK_F_X86, DUK_F_X64, DUK_F_X32.\n * https://sites.google.com/site/x32abi/\n *\n * With DUK_F_OLD_SOLARIS the <sys/isa_defs.h> header must be included\n * before this.\n */\n#if defined(__amd64__) || defined(__amd64) || \\\n    defined(__x86_64__) || defined(__x86_64) || \\\n    defined(_M_X64) || defined(_M_AMD64)\n#if defined(__ILP32__) || defined(_ILP32)\n#define DUK_F_X32\n#else\n#define DUK_F_X64\n#endif\n#elif defined(i386) || defined(__i386) || defined(__i386__) || \\\n      defined(__i486__) || defined(__i586__) || defined(__i686__) || \\\n      defined(__IA32__) || defined(_M_IX86) || defined(__X86__) || \\\n      defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__)\n#if defined(__LP64__) || defined(_LP64)\n/* This should not really happen, but would indicate x64. */\n#define DUK_F_X64\n#else\n#define DUK_F_X86\n#endif\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_aix.h.in",
    "content": "#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"aix\"\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_amigaos.h.in",
    "content": "#if defined(DUK_F_M68K)\n/* AmigaOS on M68k */\n#define DUK_USE_DATE_NOW_TIME\n#define DUK_USE_DATE_TZO_GMTIME\n/* no parsing (not an error) */\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n#elif defined(DUK_F_PPC)\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n#if !defined(UINTPTR_MAX)\n#define UINTPTR_MAX UINT_MAX\n#endif\n#else\n#error AmigaOS but not M68K/PPC, not supported now\n#endif\n\n#define DUK_USE_OS_STRING \"amigaos\"\n\n/* AmigaOS on M68K or PPC is always big endian. */\n#if !defined(DUK_USE_BYTEORDER) && (defined(DUK_F_M68K) || defined(DUK_F_PPC))\n#define DUK_USE_BYTEORDER 3\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_android.h.in",
    "content": "#if defined(DUK_COMPILING_DUKTAPE)\n#if !defined(_POSIX_C_SOURCE)\n#define _POSIX_C_SOURCE  200809L\n#endif\n#if !defined(_GNU_SOURCE)\n#define _GNU_SOURCE      /* e.g. getdate_r */\n#endif\n#if !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n#endif  /* DUK_COMPILING_DUKTAPE */\n\n#include <sys/types.h>\n#if defined(DUK_F_BCC)\n/* no endian.h or stdint.h */\n#else\n#include <endian.h>\n#include <stdint.h>\n#endif  /* DUK_F_BCC */\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#if 0  /* XXX: safe condition? */\n#define DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME\n#endif\n\n#define DUK_USE_OS_STRING \"android\"\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_apple.h.in",
    "content": "#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <TargetConditionals.h>\n#include <architecture/byte_order.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n/* http://stackoverflow.com/questions/5919996/how-to-detect-reliably-mac-os-x-ios-linux-windows-in-c-preprocessor */\n#if TARGET_IPHONE_SIMULATOR\n#define DUK_USE_OS_STRING \"iphone-sim\"\n#elif TARGET_OS_IPHONE\n#define DUK_USE_OS_STRING \"iphone\"\n#elif TARGET_OS_MAC\n#define DUK_USE_OS_STRING \"osx\"\n#else\n#define DUK_USE_OS_STRING \"osx-unknown\"\n#endif\n\n/* Use _setjmp() on Apple by default, see GH-55. */\n#define DUK_JMPBUF_TYPE       jmp_buf\n#define DUK_SETJMP(jb)        _setjmp((jb))\n#define DUK_LONGJMP(jb)       _longjmp((jb), 1)\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_cygwin.h.in",
    "content": "/* don't use strptime() for now */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_JMPBUF_TYPE       jmp_buf\n#define DUK_SETJMP(jb)        _setjmp((jb))\n#define DUK_LONGJMP(jb)       _longjmp((jb), 1)\n\n#define DUK_USE_OS_STRING \"windows\"\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_durango.h.in",
    "content": "/* Durango = XboxOne\n * Configuration is nearly identical to Windows, except for\n * DUK_USE_DATE_TZO_WINDOWS.\n */\n\n/* Initial fix: disable secure CRT related warnings when compiling Duktape\n * itself (must be defined before including Windows headers).  Don't define\n * for user code including duktape.h.\n */\n#if defined(DUK_COMPILING_DUKTAPE) && !defined(_CRT_SECURE_NO_WARNINGS)\n#define _CRT_SECURE_NO_WARNINGS\n#endif\n\n/* MSVC does not have sys/param.h */\n#define DUK_USE_DATE_NOW_WINDOWS\n#define DUK_USE_DATE_TZO_WINDOWS_NO_DST\n/* Note: PRS and FMT are intentionally left undefined for now.  This means\n * there is no platform specific date parsing/formatting but there is still\n * the ISO 8601 standard format.\n */\n#if defined(DUK_COMPILING_DUKTAPE)\n/* Only include when compiling Duktape to avoid polluting application build\n * with a lot of unnecessary defines.\n */\n#include <windows.h>\n#endif\n\n#define DUK_USE_OS_STRING \"durango\"\n\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_emscripten.h.in",
    "content": "#if defined(DUK_COMPILING_DUKTAPE)\n#if !defined(_POSIX_C_SOURCE)\n#define _POSIX_C_SOURCE  200809L\n#endif\n#if !defined(_GNU_SOURCE)\n#define _GNU_SOURCE      /* e.g. getdate_r */\n#endif\n#if !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n#endif  /* DUK_COMPILING_DUKTAPE */\n\n#include <sys/types.h>\n#if defined(DUK_F_BCC)\n/* no endian.h */\n#else\n#include <endian.h>\n#endif  /* DUK_F_BCC */\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n#include <stdint.h>\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#define DUK_USE_OS_STRING \"emscripten\"\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_flashplayer.h.in",
    "content": "#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"flashplayer\"\n\n#if !defined(DUK_USE_BYTEORDER) && defined(DUK_F_FLASHPLAYER)\n#define DUK_USE_BYTEORDER 1\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_generic.h.in",
    "content": "/* The most portable current time provider is time(), but it only has a\n * one second resolution.\n */\n#define DUK_USE_DATE_NOW_TIME\n\n/* The most portable way to figure out local time offset is gmtime(),\n * but it's not thread safe so use with caution.\n */\n#define DUK_USE_DATE_TZO_GMTIME\n\n/* Avoid custom date parsing and formatting for portability. */\n#undef DUK_USE_DATE_PRS_STRPTIME\n#undef DUK_USE_DATE_FMT_STRFTIME\n\n/* Rely on C89 headers only; time.h must be here. */\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"unknown\"\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_genericbsd.h.in",
    "content": "#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"bsd\"\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_genericunix.h.in",
    "content": "#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n#include <sys/time.h>\n#define DUK_USE_OS_STRING \"unknown\"\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_hpux.h.in",
    "content": "#define DUK_F_NO_STDINT_H\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"hpux\"\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_linux.h.in",
    "content": "#if defined(DUK_COMPILING_DUKTAPE)\n#if !defined(_POSIX_C_SOURCE)\n#define _POSIX_C_SOURCE  200809L\n#endif\n#if !defined(_GNU_SOURCE)\n#define _GNU_SOURCE      /* e.g. getdate_r */\n#endif\n#if !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n#endif  /* DUK_COMPILING_DUKTAPE */\n\n#include <sys/types.h>\n#if defined(DUK_F_BCC)\n/* no endian.h or stdint.h */\n#else\n#include <endian.h>\n#include <stdint.h>\n#endif  /* DUK_F_BCC */\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#if 0  /* XXX: safe condition? */\n#define DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME\n#endif\n\n#define DUK_USE_OS_STRING \"linux\"\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_openbsd.h.in",
    "content": "/* http://www.monkey.org/openbsd/archive/ports/0401/msg00089.html */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"openbsd\"\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_orbis.h.in",
    "content": "/* Orbis = PS4 */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_S\n/* no parsing (not an error) */\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <machine/endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"orbis\"\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_posix.h.in",
    "content": "#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"posix\"\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_qnx.h.in",
    "content": "#if defined(DUK_F_QNX) && defined(DUK_COMPILING_DUKTAPE)\n/* See: /opt/qnx650/target/qnx6/usr/include/sys/platform.h */\n#define _XOPEN_SOURCE    600\n#define _POSIX_C_SOURCE  200112L\n#endif\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"qnx\"\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_solaris.h.in",
    "content": "#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#include <sys/types.h>\n#if defined(DUK_F_OLD_SOLARIS)\n/* Old Solaris with no endian.h, stdint.h */\n#define DUK_F_NO_STDINT_H\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#else  /* DUK_F_OLD_SOLARIS */\n#include <ast/endian.h>\n#endif  /* DUK_F_OLD_SOLARIS */\n\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"solaris\"\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_tinspire.h.in",
    "content": "#if defined(DUK_COMPILING_DUKTAPE) && !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"tinspire\"\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_tos.h.in",
    "content": "#define DUK_USE_DATE_NOW_TIME\n#define DUK_USE_DATE_TZO_GMTIME\n/* no parsing (not an error) */\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"tos\"\n\n/* TOS on M68K is always big endian. */\n#if !defined(DUK_USE_BYTEORDER) && defined(DUK_F_M68K)\n#define DUK_USE_BYTEORDER 3\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/platforms/platform_windows.h.in",
    "content": "/* Windows version can't obviously be determined at compile time,\n * but _WIN32_WINNT indicates the minimum version targeted:\n * - https://msdn.microsoft.com/en-us/library/6sehtctf.aspx\n */\n\n/* Initial fix: disable secure CRT related warnings when compiling Duktape\n * itself (must be defined before including Windows headers).  Don't define\n * for user code including duktape.h.\n */\n#if defined(DUK_COMPILING_DUKTAPE) && !defined(_CRT_SECURE_NO_WARNINGS)\n#define _CRT_SECURE_NO_WARNINGS\n#endif\n\n/* Windows 32-bit and 64-bit are currently the same. */\n/* MSVC does not have sys/param.h */\n\n#if defined(DUK_COMPILING_DUKTAPE)\n/* Only include when compiling Duktape to avoid polluting application build\n * with a lot of unnecessary defines.\n */\n#include <windows.h>\n#endif\n\n/* GetSystemTimePreciseAsFileTime() available from Windows 8:\n * https://msdn.microsoft.com/en-us/library/windows/desktop/hh706895(v=vs.85).aspx\n */\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS) || defined(DUK_USE_DATE_NOW_WINDOWS)\n/* User forced provider. */\n#else\n#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)\n#define DUK_USE_DATE_NOW_WINDOWS_SUBMS\n#else\n#define DUK_USE_DATE_NOW_WINDOWS\n#endif\n#endif\n\n#define DUK_USE_DATE_TZO_WINDOWS\n\n/* Note: PRS and FMT are intentionally left undefined for now.  This means\n * there is no platform specific date parsing/formatting but there is still\n * the ISO 8601 standard format.\n */\n\n/* QueryPerformanceCounter() may go backwards in Windows XP, so enable for\n * Vista and later: https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx#qpc_support_in_windows_versions\n */\n#if !defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC) && \\\n    defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)\n#define DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC\n#endif\n\n#define DUK_USE_OS_STRING \"windows\"\n\n/* On Windows, assume we're little endian.  Even Itanium which has a\n * configurable endianness runs little endian in Windows.\n */\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n"
  },
  {
    "path": "react_juce/duktape/config/platforms.yaml",
    "content": "# Platform metadata.\n\nautodetect:\n  # Platforms for autodetect header.  Order matters because some defines\n  # overlap, so rules select for more specific define first.\n  -\n    name: Mac OSX, iPhone, Darwin\n    check: DUK_F_APPLE\n    include: platform_apple.h.in\n  -\n    name: Orbis\n    check: DUK_F_ORBIS\n    include: platform_orbis.h.in\n  -\n    name: OpenBSD\n    check: DUK_F_OPENBSD\n    include: platform_openbsd.h.in\n  -\n    name: Generic BSD\n    check: DUK_F_BSD\n    include: platform_genericbsd.h.in\n  -\n    name: Atari ST TOS\n    check: DUK_F_TOS\n    include: platform_tos.h.in\n  -\n    name: AmigaOS\n    check: DUK_F_AMIGAOS\n    include: platform_amigaos.h.in\n  -\n    name: Durango (XboxOne)\n    check: DUK_F_DURANGO\n    include: platform_durango.h.in\n  -\n    name: Windows\n    check: DUK_F_WINDOWS\n    include: platform_windows.h.in\n  -\n    name: Flashplayer (Crossbridge)\n    check: DUK_F_FLASHPLAYER\n    include: platform_flashplayer.h.in\n  -\n    name: QNX\n    check: DUK_F_QNX\n    include: platform_qnx.h.in\n  -\n    name: TI-Nspire\n    check: DUK_F_TINSPIRE\n    include: platform_tinspire.h.in\n  -\n    name: Emscripten\n    check: DUK_F_EMSCRIPTEN\n    include: platform_emscripten.h.in\n  -\n    name: Android\n    check: DUK_F_ANDROID\n    include: platform_android.h.in\n  -\n    name: Linux\n    check: DUK_F_LINUX\n    include: platform_linux.h.in\n  -\n    name: Solaris\n    check: DUK_F_SUN\n    include: platform_solaris.h.in\n  -\n    name: AIX\n    check: DUK_F_AIX\n    include: platform_aix.h.in\n  -\n    name: HPUX\n    check: DUK_F_HPUX\n    include: platform_hpux.h.in\n  -\n    name: Generic POSIX\n    check: DUK_F_POSIX\n    include: platform_posix.h.in\n  -\n    name: Cygwin\n    check: DUK_F_CYGWIN\n    include: platform_cygwin.h.in\n  -\n    name: Generic UNIX\n    check: DUK_F_UNIX\n    include: platform_genericunix.h.in\n  -\n    name: Generic fallback\n    check: null\n    include: platform_generic.h.in  # if nothing else\n"
  },
  {
    "path": "react_juce/duktape/config/tags.yaml",
    "content": "# Properties for each tag:\n#\n# - title: title to use in header files\n#\n\necmascript:\n  title: ECMAScript Edition 5 (ES5) options\n\necmascript2015:\n  title: ECMAScript 2015 (ES6) options\n\necmascript2016:\n  title: ECMAScript 2016 (ES7) options\n\necmascript2017:\n  title: ECMAScript 2017 (ES8) options\n\necmascript2018:\n  title: ECMAScript 2018 (ES9) options\n\nduktape:\n  title: Duktape specific options\n\ncompliance:\n  title: Compliance related options\n\ndebugger:\n  title: Debugger options\n\ndebug:\n  title: Debug options\n\nexecution:\n  title: Execution options\n\nsandbox:\n  title: Sandboxing options\n\nperformance:\n  title: Performance options\n\nportability:\n  title: Platform and portability options\n\nmemory:\n  title: Memory management options\n\nlowmemory:\n  title: Low memory options\n\ngc:\n  title: Garbage collection options\n\nmisc:\n  title: Miscellaneous options\n\nio:\n  title: I/O options\n\ndevelopment:\n  title: Developer-only options\n  description: >\n    Developer options which are not intended for end users and are not\n    part of semantic versioning guarantees (e.g. torture options).\n\nlegacy:\n  title: Backwards compatibility options\n  description: >\n    Options for providing backwards compatible behavior.\n\ndate:\n  title: Date handling options\n\nexperimental:\n  title: Experimental options\n\napi:\n  title: API options\n\nfastpath:\n  title: Fast path performance options\n\ncstackdepth:\n  title: C stack depth\n\ntorture:\n  title: Development time torture options\n  description: >\n    Development time options to stress test corner case handling by e.g.\n    causing a garbage collection on every allocation.\n\ncodec:\n  title: Codecs\n\nencoding-api:\n  title: WHATWG Encoding API\n\nperformance-api:\n  title: Performance API (High Resolution Time)\n"
  },
  {
    "path": "react_juce/duktape/debugger/Makefile",
    "content": "NODE:=$(shell { command -v nodejs || command -v node; } 2>/dev/null)\nDUKLUV:=$(shell command -v dukluv 2>/dev/null)\n\n# Try to get a useful default --source-dirs which works both in the Duktape\n# repo and in the distributable.  We don't want to add '..' because it would\n# scan a lot of undesired files in the Duktape repo (e.g. test262 testcases).\nifeq ($(wildcard ../tests/ecmascript/*.js),)\nSOURCEDIRS:=../\nelse\nSOURCEDIRS:=../tests/ecmascript\nendif\n\n.PHONY: all\nall: run\n\n.PHONY: run\nrun: node_modules static/socket.io-1.2.0.js static/jquery-1.11.1.min.js static/reset.css static/jquery-ui.min.js static/jquery-ui.min.css static/images\n\t\"$(NODE)\" duk_debug.js --source-dirs=$(SOURCEDIRS)\n\nrundebug: node_modules static/socket.io-1.2.0.js static/jquery-1.11.1.min.js static/reset.css static/jquery-ui.min.js static/jquery-ui.min.css static/images\n\t\"$(NODE)\" duk_debug.js --source-dirs=$(SOURCEDIRS) --verbose --log-messages /tmp/dukdebug-messages --dump-debug-pretty /tmp/dukdebug-pretty\n\n.PHONY: runproxynodejs\nrunproxynodejs: node_modules static/socket.io-1.2.0.js static/jquery-1.11.1.min.js static/reset.css static/jquery-ui.min.js static/jquery-ui.min.css static/images\n\t@echo \"Running Node.js based debug proxy\"\n\t\"$(NODE)\" duk_debug.js --json-proxy\n\n.PHONY: runproxydukluv\nrunproxydukluv: duk_debug_meta.json\n\t@echo \"Running Dukluv based debug proxy (you may need to edit DUKLUV in the Makefile)\"\n\t\"$(DUKLUV)\" duk_debug_proxy.js --log-level 2 --metadata duk_debug_meta.json --readable-numbers\n\n.PHONY: runproxy\nrunproxy: runproxydukluv\n\n.PHONY: clean\nclean:\n\t@rm -f static/socket.io-1.2.0.js\n\t@rm -f static/jquery-1.11.1.min.js\n\t@rm -f static/jquery.syntaxhighlighter.min.js\n\t@rm -f static/jquery.snippet.min.js\n\t@rm -f static/jquery.snippet.min.css\n\t@rm -f static/prefixfree.min.js\n\t@rm -f static/reset.css\n\t@rm -f static/jquery-ui.min.js\n\t@rm -f static/jquery-ui.min.css\n\t@rm -rf static/images\n\t@rm -f jquery-ui-1.11.2.zip\n\t@rm -rf jquery-ui-1.11.2\n\t@rm -rf node_modules\n\t@rm -f duk_debug_meta.json\n\nnode_modules:\n\tnpm install\n\nduk_debug_meta.json:\n\tpython2 ../tools/merge_debug_meta.py --output $@ \\\n\t\t--class-names duk_classnames.yaml \\\n\t\t--opcodes duk_opcodes.yaml \\\n\t\t--debug-commands duk_debugcommands.yaml \\\n\t\t--debug-errors duk_debugerrors.yaml\n\nstatic/socket.io-1.2.0.js:\n\twget -O $@ http://cdn.socket.io/socket.io-1.2.0.js\n\nstatic/jquery-1.11.1.min.js:\n\twget -O $@ http://code.jquery.com/jquery-1.11.1.min.js\n\n# http://balupton.github.io/jquery-syntaxhighlighter/demo/\nstatic/jquery.syntaxhighlighter.min.js:\n\twget -O $@ http://balupton.github.com/jquery-syntaxhighlighter/scripts/jquery.syntaxhighlighter.min.js\n\n# http://steamdev.com/snippet/\nstatic/jquery.snippet.min.js:\n\twget -O $@ http://steamdev.com/snippet/js/jquery.snippet.min.js\nstatic/jquery.snippet.min.css:\n\twget -O $@ http://steamdev.com/snippet/css/jquery.snippet.min.css\n\n# http://prismjs.com/\n# http://prismjs.com/plugins/line-highlight/\n#\n# XXX: prism download manually?\n\n# https://raw.github.com/LeaVerou/prefixfree/gh-pages/prefixfree.min.js\nstatic/prefixfree.min.js:\n\twget -O $@ https://raw.github.com/LeaVerou/prefixfree/gh-pages/prefixfree.min.js\n\n# http://meyerweb.com/eric/tools/css/reset/\nstatic/reset.css:\n\twget -O $@ http://meyerweb.com/eric/tools/css/reset/reset.css\n\njquery-ui-1.11.2.zip:\n\twget -O $@ http://jqueryui.com/resources/download/jquery-ui-1.11.2.zip\njquery-ui-1.11.2: jquery-ui-1.11.2.zip\n\tunzip $<\nstatic/jquery-ui.min.js: jquery-ui-1.11.2\n\tcp jquery-ui-1.11.2/jquery-ui.min.js $@\nstatic/jquery-ui.min.css: jquery-ui-1.11.2\n\tcp jquery-ui-1.11.2/jquery-ui.min.css $@\nstatic/images: jquery-ui-1.11.2\n\tcp -r jquery-ui-1.11.2/images static/\n"
  },
  {
    "path": "react_juce/duktape/debugger/README.rst",
    "content": "=========================================\nDuktape debug client and JSON debug proxy\n=========================================\n\nOverview\n========\n\nDebugger web UI which connects to the Duktape command line tool or any other\ntarget supporting the example TCP transport (``examples/debug-trans-socket``)\non Unix and Windows.\n\nAlso provides a JSON debug proxy with a JSON mapping for the Duktape debug\nprotocol.\n\nFor detailed documentation of the debugger internals, see `debugger.rst`__.\n\n__ https://github.com/svaarala/duktape/blob/master/doc/debugger.rst\n\nUsing the debugger web UI\n=========================\n\nSome prerequisites:\n\n* You'll need Node.js v0.10.x or newer.  Older Node.js versions don't support\n  the required packages.\n\nCompile Duktape command line tool with debugger support:\n\n* Enable ``DUK_USE_DEBUGGER_SUPPORT`` and ``DUK_USE_INTERRUPT_COUNTER`` for\n  ``tools/configure.py``.\n\n* Enable ``DUK_CMDLINE_DEBUGGER_SUPPORT`` on compiler command line for Duktape\n  command line utility.\n\nThe source distributable contains a Makefile to build a \"duk\" command with\ndebugger support::\n\n    $ cd <duktape dist directory>\n    $ make -f Makefile.dukdebug\n\nThe Duktape Git repo \"duk\" target has debugger support enabled by default::\n\n    $ make clean duk\n\nStart Duktape command line tool so that it waits for a debugger connection::\n\n    # For now we need to be in the directory containing the source files\n    # executed so that the 'fileName' properties of functions will match\n    # that on the debug client.\n\n    # Using source distributable\n    $ cd <duktape dist directory>\n    $ ./duk --debugger mandel.js\n\n    # Using Duktape Git repo\n    $ cd <duktape checkout>/tests/ecmascript/\n    $ ../../duk --debugger test-dev-mandel2-func.js\n\nStart the web UI::\n\n    # Must be in 'debugger' directory.\n\n    $ cd debugger/\n    $ make  # runs 'node duk_debug.js'\n\nOnce the required packages are installed, the NodeJS debug client will be\nup and running.  Open the following in your browser and start debugging:\n\n* http://localhost:9092/\n\nThe debug client automatically attaches to the debug target on startup.\nIf you start the debug target later, you'll need to click \"Attach\" in the\nweb UI.\n\nUsing the JSON debug proxy\n==========================\n\nThere are two JSON debug proxy implementations: one implemented in DukLuv\nand another in Node.js.\n\nDukLuv JSON proxy\n-----------------\n\nDukLuv (https://github.com/creationix/dukluv) is a small and portable event\nloop based on LibUV and Duktape with MIT license (like Duktape).  As such it's\neasy to embed in a custom debug client: you just include the DukLuv executable\nand the JSON proxy source file in your debug client.\n\nInstall DukLuv:\n\n* Ensure ``cmake`` is installed\n\n* ``git clone https://github.com/creationix/dukluv.git``\n\n* ``cd dukluv``\n\n* ``git submodule init; git submodule update``\n\n* ``make``\n\n* Binary should appear in:\n\n  - ``./build/dukluv`` on Linux\n\n  - ``.\\build\\Debug\\dukluv.exe`` on Windows\n\nRun the proxy::\n\n    # Using Makefile; autogenerates duk_debug_meta.json\n    # (You may need to edit DUKLUV in Makefile to point to your DukLuv)\n    $ make runproxydukluv\n\n    # Manually: see \"dukluv duk_debug_proxy.js --help\" for help\n    $ .../path/to/dukluv duk_debug_proxy.js\n\nStart Duktape command line (or whatever your target is)::\n\n    $ cd <duktape checkout>/tests/ecmascript/\n    $ ../../duk --debugger test-dev-mandel2-func.js\n\nNow connect to the proxy using e.g. telnet::\n\n    $ telnet localhost 9093\n\nThe proxy will then connect to the target and you can start issuing commands::\n\n    $ telnet localhost 9093\n    Trying 127.0.0.1...\n    Connected to localhost.\n    Escape character is '^]'.\n    {\"notify\":\"_TargetConnecting\",\"args\":[\"127.0.0.1\",9091]}\n    {\"notify\":\"_TargetConnected\",\"args\":[\"1 10499 v1.4.0-140-gc9a6c7c duk command built from Duktape repo\"]}\n    {\"notify\":\"Status\",\"command\":1,\"args\":[1,\"test-dev-mandel2-func.js\",\"global\",58,0]}\n    {\"request\":\"BasicInfo\"}\n    {\"reply\":true,\"args\":[10499,\"v1.4.0-140-gc9a6c7c\",\"duk command built from Duktape repo\",1]}\n    {\"request\":\"Eval\",\"args\":[\"print('Hello world!'); 123;\"]}\n    {\"notify\":\"Print\",\"command\":2,\"args\":[\"Hello world!\\n\"]}\n    {\"reply\":true,\"args\":[0,{\"type\":\"number\",\"data\":\"405ec00000000000\"}]}\n    [...]\n\nThe proxy log provides dumps both JSON and dvalue binary traffic which is\nquite useful in development::\n\n    $ make runproxydukluv\n    Running Dukluv based debug proxy\n    \"dukluv\" duk_debug_proxy.js --log-level 2 --metadata duk_debug_meta.json\n    2016-02-17T13:59:42.308Z INF Proxy: Read proxy metadata from duk_debug_meta.json\n    2016-02-17T13:59:42.325Z INF Proxy: Listening for incoming JSON debug connection on 0.0.0.0:9093, target is 127.0.0.1:9091\n    2016-02-17T13:59:47.994Z INF Proxy: JSON proxy client connected\n    2016-02-17T13:59:47.994Z INF Proxy: Connecting to debug target at 127.0.0.1:9091\n    2016-02-17T13:59:47.994Z INF Proxy: PROXY --> CLIENT: {\"notify\":\"_TargetConnecting\",\"args\":[\"127.0.0.1\",9091]}\n    2016-02-17T13:59:47.994Z INF Proxy: Connected to debug target at 127.0.0.1:9091\n    2016-02-17T13:59:48.003Z INF Proxy: PROXY --> CLIENT: {\"notify\":\"_TargetConnected\",\"args\":[\"1 10499 v1.4.0-140-gc9a6c7c duk command built from Duktape repo\"]}\n    2016-02-17T13:59:48.003Z INF Proxy: Target handshake: {\"line\":\"1 10499 v1.4.0-140-gc9a6c7c duk command built from Duktape repo\",\"protocolVersion\":1,\"text\":\"10499 v1.4.0-140-gc9a6c7c duk command built from Duktape repo\",\"dukVersion\":\"1\",\"dukGitDescribe\":\"10499\",\"targetString\":\"v1.4.0-140-gc9a6c7c\"}\n    2016-02-17T13:59:48.151Z INF Proxy: PROXY <-- TARGET: |04|\n    2016-02-17T13:59:48.152Z INF Proxy: PROXY <-- TARGET: |81|\n    2016-02-17T13:59:48.152Z INF Proxy: PROXY <-- TARGET: |81|\n    2016-02-17T13:59:48.160Z INF Proxy: PROXY <-- TARGET: |78746573742d6465762d6d616e64656c322d66756e632e6a73|\n    2016-02-17T13:59:48.161Z INF Proxy: PROXY <-- TARGET: |66676c6f62616c|\n    2016-02-17T13:59:48.165Z INF Proxy: PROXY <-- TARGET: |ba|\n    2016-02-17T13:59:48.165Z INF Proxy: PROXY <-- TARGET: |80|\n    2016-02-17T13:59:48.165Z INF Proxy: PROXY <-- TARGET: |00|\n    2016-02-17T13:59:48.165Z INF Proxy: PROXY --> CLIENT: {\"notify\":\"Status\",\"command\":1,\"args\":[1,\"test-dev-mandel2-func.js\",\"global\",58,0]}\n    2016-02-17T13:59:51.289Z INF Proxy: PROXY <-- CLIENT: {\"request\":\"BasicInfo\"}\n    2016-02-17T13:59:51.289Z INF Proxy: PROXY --> TARGET: |01|\n    2016-02-17T13:59:51.289Z INF Proxy: PROXY --> TARGET: |90|\n    2016-02-17T13:59:51.289Z INF Proxy: PROXY --> TARGET: |00|\n    2016-02-17T13:59:51.291Z INF Proxy: PROXY <-- TARGET: |02|\n    2016-02-17T13:59:51.291Z INF Proxy: PROXY <-- TARGET: |e903|\n    2016-02-17T13:59:51.292Z INF Proxy: PROXY <-- TARGET: |7376312e342e302d3134302d6763396136633763|\n    2016-02-17T13:59:51.293Z INF Proxy: PROXY <-- TARGET: |12002364756b20636f6d6d616e64206275696c742066726f6d2044756b74617065207265706f|\n    2016-02-17T13:59:51.293Z INF Proxy: PROXY <-- TARGET: |81|\n    2016-02-17T13:59:51.293Z INF Proxy: PROXY <-- TARGET: |00|\n    2016-02-17T13:59:51.293Z INF Proxy: PROXY --> CLIENT: {\"reply\":true,\"args\":[10499,\"v1.4.0-140-gc9a6c7c\",\"duk command built from Duktape repo\",1]}\n    2016-02-17T14:00:06.105Z INF Proxy: PROXY <-- CLIENT: {\"request\":\"Eval\",\"args\":[\"print('Hello world!'); 123;\"]}\n    2016-02-17T14:00:06.105Z INF Proxy: PROXY --> TARGET: |01|\n    2016-02-17T14:00:06.105Z INF Proxy: PROXY --> TARGET: |9e|\n    2016-02-17T14:00:06.105Z INF Proxy: PROXY --> TARGET: |7b7072696e74282748656c6c6f20776f726c642127293b203132333b|\n    2016-02-17T14:00:06.105Z INF Proxy: PROXY --> TARGET: |00|\n    2016-02-17T14:00:06.167Z INF Proxy: PROXY <-- TARGET: |04|\n    2016-02-17T14:00:06.167Z INF Proxy: PROXY <-- TARGET: |82|\n    2016-02-17T14:00:06.167Z INF Proxy: PROXY <-- TARGET: |6d48656c6c6f20776f726c64210a|\n    2016-02-17T14:00:06.168Z INF Proxy: PROXY <-- TARGET: |00|\n    2016-02-17T14:00:06.168Z INF Proxy: PROXY --> CLIENT: {\"notify\":\"Print\",\"command\":2,\"args\":[\"Hello world!\\n\"]}\n    2016-02-17T14:00:06.171Z INF Proxy: PROXY <-- TARGET: |02|\n    2016-02-17T14:00:06.171Z INF Proxy: PROXY <-- TARGET: |80|\n    2016-02-17T14:00:06.173Z INF Proxy: PROXY <-- TARGET: |1a405ec00000000000|\n    2016-02-17T14:00:06.173Z INF Proxy: PROXY <-- TARGET: |00|\n    2016-02-17T14:00:06.174Z INF Proxy: PROXY --> CLIENT: {\"reply\":true,\"args\":[0,{\"type\":\"number\",\"data\":\"405ec00000000000\"}]}\n    [...]\n\nNode.js JSON proxy\n------------------\n\nA Node.js-based JSON debug proxy is also provided by ``duk_debug.js``::\n\n    # Same prerequisites as for running the debug client\n    $ make runproxynodejs\n\nStart Duktape command line (or whatever your target is)::\n\n    $ cd <duktape checkout>/tests/ecmascript/\n    $ ../../duk --debugger test-dev-mandel2-func.js\n\nYou can then connect to localhost:9093 and interact with the proxy.\nHere's an example session using telnet and manually typed in commands\nThe ``-->`` (send) and ``<--`` (receiver) markers have been added for\nreadability and are not part of the stream::\n\n    $ telnet localhost 9093\n    Trying 127.0.0.1...\n    Connected to localhost.\n    Escape character is '^]'.\n    <-- {\"notify\":\"_TargetConnected\",\"args\":[\"1 10199 v1.1.0-275-gbd4d610-dirty duk command built from Duktape repo\"]}\n    <-- {\"notify\":\"Status\",\"command\":1,\"args\":[1,\"test-dev-mandel2-func.js\",\"global\",58,0]}\n    --> {\"request\":\"BasicInfo\"}\n    <-- {\"reply\":true,\"args\":[10199,\"v1.1.0-275-gbd4d610-dirty\",\"duk command built from Duktape repo\",1]}\n    --> {\"request\":\"Eval\", \"args\":[ \"print(Math.PI)\" ]}\n    <-- {\"notify\":\"Print\",\"command\":2,\"args\":[\"3.141592653589793\\n\"]}\n    <-- {\"reply\":true,\"args\":[0,{\"type\":\"undefined\"}]}\n    --> {\"request\":\"Resume\"}\n    <-- {\"reply\":true,\"args\":[]}\n    <-- {\"notify\":\"Status\",\"command\":1,\"args\":[0,\"test-dev-mandel2-func.js\",\"global\",58,0]}\n    <-- {\"notify\":\"Status\",\"command\":1,\"args\":[0,\"test-dev-mandel2-func.js\",\"global\",58,0]}\n    <-- {\"notify\":\"Print\",\"command\":2,\"args\":[\"................................................................................\\n\"]}\n    <-- {\"notify\":\"Print\",\"command\":2,\"args\":[\"................................................................................\\n\"]}\n    <-- {\"notify\":\"Print\",\"command\":2,\"args\":[\"................................................................................\\n\"]}\n    [...]\n    <-- {\"notify\":\"_Disconnecting\"}\n\nA telnet connection allows you to experiment with debug commands by simply\ncopy-pasting debug commands to the telnet session.  This is useful even if\nyou decide to implement the binary protocol directly.\n\nThe debug target used by the proxy can be configured with ``duk_debug.js``\ncommand line options.\n\nSource search path\n==================\n\nThe NodeJS debug client needs to be able to find source code files matching\ncode running on the target (\"duk\" command line).  **The filenames used on the\ntarget and on the debug client must match exactly**, because e.g. breakpoints\nare targeted based on the 'fileName' property of Function objects.\n\nThe search path can be set using the ``--source-dirs`` option given to\n``duk_debug.js``, with the default search paths including only\n``../tests/ecmascript/``.\n\nThe default search path means that if a function on the target has fileName\n``foo/bar.js`` it would be loaded from (relative to the duk_debug.js working\ndirectory, ``debugger/``)::\n\n    ../tests/ecmascript/foo/bar.js\n\nSimilarly, if the filesystem contained::\n\n    ../tests/ecmascript/baz/quux.js\n\nthe web UI dropdown would show ``baz/quux.js``.  If you selected that file\nand added a breakpoint, the breakpoint fileName sent to the debug target\nwould be ``baz/quux.js``.\n\n.. note:: There's much to improve in the search path.  For instance, it'd\n          be nice to add a certain path to search but exclude files based\n          on paths and patterns, etc.\n\nArchitecture\n============\n\n::\n\n    +-------------------+\n    | Web browser       |  [debug UI]\n    +-------------------+\n          |\n          | http (port 9092)\n          | socket.io\n          v\n    +-------------------+\n    | duk_debug.js      |  [debug client]\n    +-------------------+\n          |          /\\\n          |          ||\n          +----------||---- [example tcp transport] (port 9091)\n          |          ||     (application provides concrete transport)\n          |          ||\n          |          ||---- [debug protocol stream]\n          |          ||     (between debug client and Duktape)\n          |          ||\n    + - - | - - - - -|| - - +\n    :     v          ||     :\n    :  +-------------||-+   :  [target]\n    :  | application || |   :\n    :  +-------------||-+   :\n    :     ^          ||     :\n    :     |          ||     :   [debug API]\n    :     +----------||-------- debug transport callbacks\n    :     |          ||     :   (read, write, peek, read/write flush)\n    :     |          ||     :   implemented by application\n    :     |          \\/     :\n    :  +----------------+   :\n    :  | Duktape        |   :\n    :  +----------------+   :\n    + - - - - - - - - - - - +\n\nThe debug transport is application specific:\n\n* Duktape command line (\"duk\") and this debug client use an **example** TCP\n  transport as a concrete example.\n\n* It is entirely up to the application to come up with the most suitable\n  transport for its environment.  Different mechanisms will be needed for\n  Wi-Fi, serial, etc.\n\nThe debug protocol running inside the transport is transport independent:\n\n* The debug protocol is documented in ``doc/debugger.rst``.\n\n* This debug client provides further concrete examples and clarifications\n  on how the protocol can be used.\n\nUsing a custom transport\n========================\n\nQuite possibly your target device cannot use the example TCP transport and\nyou need to implement your own transport.  You'll need to implement your\ncustom transport both for the target device and for the debug client.\n\nTarget device\n-------------\n\nImplement the debug transport callbacks needed by ``duk_debugger_attach()``.\n\nSee ``doc/debugger.rst`` for details and ``examples/debug-trans-socket``\nfor example running code for a TCP transport.\n\nDebug client alternative 1: duk_debug.js + custom TCP proxy\n-----------------------------------------------------------\n\nIf you don't want to change ``duk_debug.js`` you can implement a TCP proxy\nwhich accepts a TCP connection from ``duk_debug.js`` and then uses your\ncustom transport to talk to the target::\n\n   +--------------+   TCP   +-------+   custom   +--------+\n   | duk_debug.js | ------> | proxy | ---------> | target |\n   +--------------+         +-------+            +--------+\n\nThis is a straightforward option and a proxy can be used with other debug\nclients too (perhaps custom scripts talking to the target etc).\n\nYou could also use netcat and implement your proxy so that it talks to\n``duk_debug.js`` using stdin/stdout.\n\nDebug client alternative 2: duk_debug.js + custom NodeJS stream\n---------------------------------------------------------------\n\nTo make ``duk_debug.js`` use a custom transport you need to:\n\n* Implement your own transport as NodeJS stream.  You can add it directly to\n  ``duk_debug.js`` but it's probably easiest to use a separate module so that\n  the diff to ``duk_debug.js`` stays minimal.\n\n* Change ``duk_debug.js`` to use the custom transport instead of a TCP\n  stream.  Search for \"CUSTOMTRANSPORT\" in ``duk_debug.js``.\n\nSee:\n\n* http://nodejs.org/api/stream.html\n\n* https://github.com/substack/stream-handbook\n\nDebug client alternative 3: custom debug client\n-----------------------------------------------\n\nYou can also implement your own debug client and debug UI with support for\nyour custom transport.\n\nYou'll also need to implement the client part of the Duktape debugger\nprotocol.  See ``doc/debugger.rst`` for the specification and ``duk_debug.js``\nfor example running code which should illustrate the protocol in more detail.\n\nThe JSON debug proxy allows you to implement a debug client without needing\nto implement the Duktape binary debug protocol.  The JSON protocol provides\na roughly 1:1 mapping to the binary protocol but with an easier syntax.\n"
  },
  {
    "path": "react_juce/duktape/debugger/duk_classnames.yaml",
    "content": "# Must match C header.\nclass_names:\n  - none\n  - Object\n  - Array\n  - Function\n  - Arguments\n  - Boolean\n  - Date\n  - Error\n  - JSON\n  - Math\n  - Number\n  - RegExp\n  - String\n  - global\n  - Symbol\n  - ObjEnv\n  - DecEnv\n  - Pointer\n  - Thread\n  - ArrayBuffer\n  - DataView\n  - Int8Array\n  - Uint8Array\n  - Uint8ClampedArray\n  - Int16Array\n  - Uint16Array\n  - Int32Array\n  - Uint32Array\n  - Float32Array\n  - Float64Array\n"
  },
  {
    "path": "react_juce/duktape/debugger/duk_debug.js",
    "content": "/*\n *  Minimal debug web console for Duktape command line tool\n *\n *  See debugger/README.rst.\n *\n *  The web UI socket.io communication can easily become a bottleneck and\n *  it's important to ensure that the web UI remains responsive.  Basic rate\n *  limiting mechanisms (token buckets, suppressing identical messages, etc)\n *  are used here now.  Ideally the web UI would pull data on its own terms\n *  which would provide natural rate limiting.\n *\n *  Promises are used to structure callback chains.\n *\n *  https://github.com/petkaantonov/bluebird\n *  https://github.com/petkaantonov/bluebird/blob/master/API.md\n *  https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns\n */\n\nvar Promise = require('bluebird');\nvar events = require('events');\nvar stream = require('stream');\nvar path = require('path');\nvar fs = require('fs');\nvar net = require('net');\nvar byline = require('byline');\nvar util = require('util');\nvar readline = require('readline');\nvar sprintf = require('sprintf').sprintf;\nvar utf8 = require('utf8');\nvar yaml = require('yamljs');\nvar recursiveReadSync = require('recursive-readdir-sync');\n\n// Command line options (defaults here, overwritten if necessary)\nvar optTargetHost = '127.0.0.1';\nvar optTargetPort = 9091;\nvar optHttpPort = 9092;\nvar optJsonProxyPort = 9093;\nvar optJsonProxy = false;\nvar optSourceSearchDirs = [ '../tests/ecmascript' ];\nvar optDumpDebugRead = null;\nvar optDumpDebugWrite = null;\nvar optDumpDebugPretty = null;\nvar optLogMessages = false;\n\n// Constants\nvar UI_MESSAGE_CLIPLEN = 128;\nvar LOCALS_CLIPLEN = 64;\nvar EVAL_CLIPLEN = 4096;\nvar GETVAR_CLIPLEN = 4096;\nvar SUPPORTED_DEBUG_PROTOCOL_VERSION = 2;\n\n// Commands initiated by Duktape\nvar CMD_STATUS = 0x01;\nvar CMD_UNUSED_2 = 0x02;  // Duktape 1.x: print notify\nvar CMD_UNUSED_3 = 0x03;  // Duktape 1.x: alert notify\nvar CMD_UNUSED_4 = 0x04;  // Duktape 1.x: log notify\nvar CMD_THROW = 0x05;\nvar CMD_DETACHING = 0x06;\n\n// Commands initiated by the debug client (= us)\nvar CMD_BASICINFO = 0x10;\nvar CMD_TRIGGERSTATUS = 0x11;\nvar CMD_PAUSE = 0x12;\nvar CMD_RESUME = 0x13;\nvar CMD_STEPINTO = 0x14;\nvar CMD_STEPOVER = 0x15;\nvar CMD_STEPOUT = 0x16;\nvar CMD_LISTBREAK = 0x17;\nvar CMD_ADDBREAK = 0x18;\nvar CMD_DELBREAK = 0x19;\nvar CMD_GETVAR = 0x1a;\nvar CMD_PUTVAR = 0x1b;\nvar CMD_GETCALLSTACK = 0x1c;\nvar CMD_GETLOCALS = 0x1d;\nvar CMD_EVAL = 0x1e;\nvar CMD_DETACH = 0x1f;\nvar CMD_DUMPHEAP = 0x20;\nvar CMD_GETBYTECODE = 0x21;\n\n// Errors\nvar ERR_UNKNOWN = 0x00;\nvar ERR_UNSUPPORTED = 0x01;\nvar ERR_TOOMANY = 0x02;\nvar ERR_NOTFOUND = 0x03;\n\n// Marker objects for special protocol values\nvar DVAL_EOM = { type: 'eom' };\nvar DVAL_REQ = { type: 'req' };\nvar DVAL_REP = { type: 'rep' };\nvar DVAL_ERR = { type: 'err' };\nvar DVAL_NFY = { type: 'nfy' };\n\n// String map for commands (debug dumping).  A single map works (instead of\n// separate maps for each direction) because command numbers don't currently\n// overlap.  So merge the YAML metadata.\nvar debugCommandMeta = yaml.load('duk_debugcommands.yaml');\nvar debugCommandNames = [];  // list of command names, merged client/target\ndebugCommandMeta.target_commands.forEach(function (k, i) {\n    debugCommandNames[i] = k;\n});\ndebugCommandMeta.client_commands.forEach(function (k, i) {  // override\n    debugCommandNames[i] = k;\n});\nvar debugCommandNumbers = {};  // map from (merged) command name to number\ndebugCommandNames.forEach(function (k, i) {\n    debugCommandNumbers[k] = i;\n});\n\n// Duktape heaphdr type constants, must match C headers\nvar DUK_HTYPE_STRING = 0;\nvar DUK_HTYPE_OBJECT = 1;\nvar DUK_HTYPE_BUFFER = 2;\n\n// Duktape internal class numbers, must match C headers\nvar dukClassNameMeta = yaml.load('duk_classnames.yaml');\nvar dukClassNames = dukClassNameMeta.class_names;\n\n// Bytecode opcode/extraop metadata\nvar dukOpcodes = yaml.load('duk_opcodes.yaml');\nif (dukOpcodes.opcodes.length != 256) {\n    throw new Error('opcode metadata length incorrect');\n}\n\n/*\n *  Miscellaneous helpers\n */\n\nvar nybbles = '0123456789abcdef';\n\n/* Convert a buffer into a string using Unicode codepoints U+0000...U+00FF.\n * This is the NodeJS 'binary' encoding, but since it's being deprecated,\n * reimplement it here.  We need to avoid parsing strings as e.g. UTF-8:\n * although Duktape strings are usually UTF-8/CESU-8 that's not always the\n * case, e.g. for internal strings.  Buffer values are also represented as\n * strings in the debug protocol, so we must deal accurately with arbitrary\n * byte arrays.\n */\nfunction bufferToDebugString(buf) {\n    var cp = [];\n    var i, n;\n\n/*\n    // This fails with \"RangeError: Maximum call stack size exceeded\" for some\n    // reason, so use a much slower variant.\n\n    for (i = 0, n = buf.length; i < n; i++) {\n        cp[i] = buf[i];\n    }\n\n    return String.fromCharCode.apply(String, cp);\n*/\n\n    for (i = 0, n = buf.length; i < n; i++) {\n        cp[i] = String.fromCharCode(buf[i]);\n    }\n\n    return cp.join('');\n}\n\n/* Write a string into a buffer interpreting codepoints U+0000...U+00FF\n * as bytes.  Drop higher bits.\n */\nfunction writeDebugStringToBuffer(str, buf, off) {\n    var i, n;\n\n    for (i = 0, n = str.length; i < n; i++) {\n        buf[off + i] = str.charCodeAt(i) & 0xff;  // truncate higher bits\n    }\n}\n\n/* Encode an ordinary Unicode string into a dvalue compatible format, i.e.\n * into a byte array represented as codepoints U+0000...U+00FF.  Concretely,\n * encode with UTF-8 and then represent the bytes with U+0000...U+00FF.\n */\nfunction stringToDebugString(str) {\n    return utf8.encode(str);\n}\n\n/* Pretty print a dvalue.  Useful for dumping etc. */\nfunction prettyDebugValue(x) {\n    if (typeof x === 'object' && x !== null) {\n        if (x.type === 'eom') {\n            return 'EOM';\n        } else if (x.type === 'req') {\n            return 'REQ';\n        } else if (x.type === 'rep') {\n            return 'REP';\n        } else if (x.type === 'err') {\n            return 'ERR';\n        } else if (x.type === 'nfy') {\n            return 'NFY';\n        }\n    }\n    return JSON.stringify(x);\n}\n\n/* Pretty print a number for UI usage.  Types and values should be easy to\n * read and typing should be obvious.  For numbers, support Infinity, NaN,\n * and signed zeroes properly.\n */\nfunction prettyUiNumber(x) {\n    if (x === 1 / 0) { return 'Infinity'; }\n    if (x === -1 / 0) { return '-Infinity'; }\n    if (Number.isNaN(x)) { return 'NaN'; }\n    if (x === 0 && 1 / x > 0) { return '0'; }\n    if (x === 0 && 1 / x < 0) { return '-0'; }\n    return x.toString();\n}\n\n/* Pretty print a dvalue string (bytes represented as U+0000...U+00FF)\n * for UI usage.  Try UTF-8 decoding to get a nice Unicode string (JSON\n * encoded) but if that fails, ensure that bytes are encoded transparently.\n * The result is a quoted string with a special quote marker for a \"raw\"\n * string when UTF-8 decoding fails.  Very long strings are optionally\n * clipped.\n */\nfunction prettyUiString(x, cliplen) {\n    var ret;\n\n    if (typeof x !== 'string') {\n        throw new Error('invalid input to prettyUiString: ' + typeof x);\n    }\n    try {\n        // Here utf8.decode() is better than decoding using NodeJS buffer\n        // operations because we want strict UTF-8 interpretation.\n        ret = JSON.stringify(utf8.decode(x));\n    } catch (e) {\n        // When we fall back to representing bytes, indicate that the string\n        // is \"raw\" with a 'r\"' prefix (a somewhat arbitrary convention).\n        // U+0022 = \", U+0027 = '\n        ret = 'r\"' + x.replace(/[\\u0022\\u0027\\u0000-\\u001f\\u0080-\\uffff]/g, function (match) {\n            var cp = match.charCodeAt(0);\n            return '\\\\x' + nybbles[(cp >> 4) & 0x0f] + nybbles[cp & 0x0f];\n        }) + '\"';\n    }\n\n    if (cliplen && ret.length > cliplen) {\n        ret = ret.substring(0, cliplen) + '...';  // trailing '\"' intentionally missing\n    }\n    return ret;\n}\n\n/* Pretty print a dvalue string (bytes represented as U+0000...U+00FF)\n * for UI usage without quotes.\n */\nfunction prettyUiStringUnquoted(x, cliplen) {\n    var ret;\n\n    if (typeof x !== 'string') {\n        throw new Error('invalid input to prettyUiStringUnquoted: ' + typeof x);\n    }\n\n    try {\n        // Here utf8.decode() is better than decoding using NodeJS buffer\n        // operations because we want strict UTF-8 interpretation.\n\n        // XXX: unprintable characters etc?  In some UI cases we'd want to\n        // e.g. escape newlines and in others not.\n        ret = utf8.decode(x);\n    } catch (e) {\n        // For the unquoted version we don't need to escape single or double\n        // quotes.\n        ret = x.replace(/[\\u0000-\\u001f\\u0080-\\uffff]/g, function (match) {\n            var cp = match.charCodeAt(0);\n            return '\\\\x' + nybbles[(cp >> 4) & 0x0f] + nybbles[cp & 0x0f];\n        });\n    }\n\n    if (cliplen && ret.length > cliplen) {\n        ret = ret.substring(0, cliplen) + '...';\n    }\n    return ret;\n}\n\n/* Pretty print a dvalue for UI usage.  Everything comes out as a ready-to-use\n * string.\n *\n * XXX: Currently the debug client formats all values for UI use.  A better\n * solution would be to pass values in typed form and let the UI format them,\n * so that styling etc. could take typing into account.\n */\nfunction prettyUiDebugValue(x, cliplen) {\n    if (typeof x === 'object' && x !== null) {\n        // Note: typeof null === 'object', so null special case explicitly\n        if (x.type === 'eom') {\n            return 'EOM';\n        } else if (x.type === 'req') {\n            return 'REQ';\n        } else if (x.type === 'rep') {\n            return 'REP';\n        } else if (x.type === 'err') {\n            return 'ERR';\n        } else if (x.type === 'nfy') {\n            return 'NFY';\n        } else if (x.type === 'unused') {\n            return 'unused';\n        } else if (x.type === 'undefined') {\n            return 'undefined';\n        } else if (x.type === 'buffer') {\n            return '|' + x.data + '|';\n        } else if (x.type === 'object') {\n            return '[object ' + (dukClassNames[x.class] || ('class ' + x.class)) + ' ' + x.pointer + ']';\n        } else if (x.type === 'pointer') {\n            return '<pointer ' + x.pointer + '>';\n        } else if (x.type === 'lightfunc') {\n            return '<lightfunc 0x' + x.flags.toString(16) + ' ' + x.pointer + '>';\n        } else if (x.type === 'number') {\n            // duk_tval number, any IEEE double\n            var tmp = new Buffer(x.data, 'hex');  // decode into hex\n            var val = tmp.readDoubleBE(0);        // big endian ieee double\n            return prettyUiNumber(val);\n        }\n    } else if (x === null) {\n        return 'null';\n    } else if (typeof x === 'boolean') {\n        return x ? 'true' : 'false';\n    } else if (typeof x === 'string') {\n        return prettyUiString(x, cliplen);\n    } else if (typeof x === 'number') {\n        // Debug protocol integer\n        return prettyUiNumber(x);\n    }\n\n    // We shouldn't come here, but if we do, JSON is a reasonable default.\n    return JSON.stringify(x);\n}\n\n/* Pretty print a debugger message given as an array of parsed dvalues.\n * Result should be a pure ASCII one-liner.\n */\nfunction prettyDebugMessage(msg) {\n    return msg.map(prettyDebugValue).join(' ');\n}\n\n/* Pretty print a debugger command. */\nfunction prettyDebugCommand(cmd) {\n    return debugCommandNames[cmd] || String(cmd);\n}\n\n/* Decode and normalize source file contents: UTF-8, tabs to 8,\n * CR LF to LF.\n */\nfunction decodeAndNormalizeSource(data) {\n    var tmp;\n    var lines, line, repl;\n    var i, n;\n    var j, m;\n\n    try {\n        tmp = data.toString('utf8');\n    } catch (e) {\n        console.log('Failed to UTF-8 decode source file, ignoring: ' + e);\n        tmp = String(data);\n    }\n\n    lines = tmp.split(/\\r?\\n/);\n    for (i = 0, n = lines.length; i < n; i++) {\n        line = lines[i];\n        if (/\\t/.test(line)) {\n            repl = '';\n            for (j = 0, m = line.length; j < m; j++) {\n                if (line.charAt(j) === '\\t') {\n                    repl += ' ';\n                    while ((repl.length % 8) != 0) {\n                        repl += ' ';\n                    }\n                } else {\n                    repl += line.charAt(j);\n                }\n            }\n            lines[i] = repl;\n        }\n    }\n\n    // XXX: normalize last newline (i.e. force a newline if contents don't\n    // end with a newline)?\n\n    return lines.join('\\n');\n}\n\n/* Token bucket rate limiter for a given callback.  Calling code calls\n * trigger() to request 'cb' to be called, and the rate limiter ensures\n * that 'cb' is not called too often.\n */\nfunction RateLimited(tokens, rate, cb) {\n    var _this = this;\n    this.maxTokens = tokens;\n    this.tokens = this.maxTokens;\n    this.rate = rate;\n    this.cb = cb;\n    this.delayedCb = false;\n\n    // Right now the implementation is setInterval-based, but could also be\n    // made timerless.  There are so few rate limited resources that this\n    // doesn't matter in practice.\n\n    this.tokenAdder = setInterval(function () {\n        if (_this.tokens < _this.maxTokens) {\n            _this.tokens++;\n        }\n        if (_this.delayedCb) {\n            _this.delayedCb = false;\n            _this.tokens--;\n            _this.cb();\n        }\n    }, this.rate);\n}\nRateLimited.prototype.trigger = function () {\n    if (this.tokens > 0) {\n        this.tokens--;\n        this.cb();\n    } else {\n        this.delayedCb = true;\n    }\n};\n\n/*\n *  Source file manager\n *\n *  Scan the list of search directories for ECMAScript source files and\n *  build an index of them.  Provides a mechanism to find a source file\n *  based on a raw 'fileName' property provided by the debug target, and\n *  to provide a file list for the web UI.\n *\n *  NOTE: it's tempting to do loose matching for filenames, but this does\n *  not work in practice.  Filenames must match 1:1 with the debug target\n *  so that e.g. breakpoints assigned based on filenames found from the\n *  search paths will match 1:1 on the debug target.  If this is not the\n *  case, breakpoints won't work as expected.\n */\n\nfunction SourceFileManager(directories) {\n    this.directories = directories;\n    this.extensions = { '.js': true, '.jsm': true };\n    this.fileMap = {};  // filename as seen by debug target -> file path\n    this.files = [];    // filenames as seen by debug target\n}\n\nSourceFileManager.prototype.scan = function () {\n    var _this = this;\n    var fileMap = {};   // relative path -> file path\n    var files;\n\n    this.directories.forEach(function (dir) {\n        console.log('Scanning source files: ' + dir);\n        try {\n            recursiveReadSync(dir).forEach(function (fn) {\n                // Example: dir     ../../tests\n                //          normFn  ../../tests/foo/bar.js\n                //          relFn   foo/bar.js\n                var normDir = path.normalize(dir);\n                var normFn = path.normalize(fn);\n                var relFn = path.relative(normDir, normFn);\n\n                if (fs.existsSync(normFn) && fs.lstatSync(normFn).isFile() &&\n                    _this.extensions[path.extname(normFn)]) {\n                    // We want the fileMap to contain the filename relative to\n                    // the search dir root.  First directory containing a\n                    // certail relFn wins.\n                    if (relFn in fileMap) {\n                        console.log('Found', relFn, 'multiple times, first match wins');\n                    } else {\n                        fileMap[relFn] = normFn;\n                    }\n                }\n            });\n        } catch (e) {\n            console.log('Failed to scan ' + dir + ': ' + e);\n        }\n    });\n\n    files = Object.keys(fileMap);\n    files.sort();\n    this.files = files;\n\n    this.fileMap = fileMap;\n\n    console.log('Found ' + files.length + ' source files in ' + this.directories.length + ' search directories');\n};\n\nSourceFileManager.prototype.getFiles = function () {\n    return this.files;\n};\n\nSourceFileManager.prototype.search = function (fileName) {\n    var _this = this;\n\n    // Loose matching is tempting but counterproductive: filenames must\n    // match 1:1 between the debug client and the debug target for e.g.\n    // breakpoints to work as expected.  Note that a breakpoint may be\n    // assigned by selecting a file from a dropdown populated by scanning\n    // the filesystem for available sources and there's no way of knowing\n    // if the debug target uses the exact same name.\n    //\n    // We intentionally allow any files from the search paths, not just\n    // those scanned to this.fileMap.\n\n    function tryLookup() {\n        var i, fn, data;\n\n        for (i = 0; i < _this.directories.length; i++) {\n            fn = path.join(_this.directories[i], fileName);\n            if (fs.existsSync(fn) && fs.lstatSync(fn).isFile()) {\n                data = fs.readFileSync(fn);             // Raw bytes\n                return decodeAndNormalizeSource(data);  // Unicode string\n            }\n        }\n        return null;\n    }\n\n    return tryLookup(fileName);\n};\n\n/*\n *  Debug protocol parser\n *\n *  The debug protocol parser is an EventEmitter which parses debug messages\n *  from an input stream and emits 'debug-message' events for completed\n *  messages ending in an EOM.  The parser also provides debug dumping, stream\n *  logging functionality, and statistics gathering functionality.\n *\n *  This parser is used to parse both incoming and outgoing messages.  For\n *  outgoing messages the only function is to validate and debug dump the\n *  messages we're about to send.  The downside of dumping at this low level\n *  is that we can't match request and reply/error messages here.\n *\n *  http://www.sitepoint.com/nodejs-events-and-eventemitter/\n */\n\nfunction DebugProtocolParser(inputStream,\n                             protocolVersion,\n                             rawDumpFileName,\n                             textDumpFileName,\n                             textDumpFilePrefix,\n                             hexDumpConsolePrefix,\n                             textDumpConsolePrefix) {\n    var _this = this;\n    this.inputStream = inputStream;\n    this.closed = false;       // stream is closed/broken, don't parse anymore\n    this.bytes = 0;\n    this.dvalues = 0;\n    this.messages = 0;\n    this.requests = 0;\n    this.prevBytes = 0;\n    this.bytesPerSec = 0;\n    this.statsTimer = null;\n    this.readableNumberValue = true;\n\n    events.EventEmitter.call(this);\n\n    var buf = new Buffer(0);    // accumulate data\n    var msg = [];               // accumulated message until EOM\n    var versionIdentification;\n\n    var statsInterval = 2000;\n    var statsIntervalSec = statsInterval / 1000;\n    this.statsTimer = setInterval(function () {\n        _this.bytesPerSec = (_this.bytes - _this.prevBytes) / statsIntervalSec;\n        _this.prevBytes = _this.bytes;\n        _this.emit('stats-update');\n    }, statsInterval);\n\n    function consume(n) {\n        var tmp = new Buffer(buf.length - n);\n        buf.copy(tmp, 0, n);\n        buf = tmp;\n    }\n\n    inputStream.on('data', function (data) {\n        var i, n, x, v, gotValue, len, t, tmpbuf, verstr;\n        var prettyMsg;\n\n        if (_this.closed || !_this.inputStream) {\n            console.log('Ignoring incoming data from closed input stream, len ' + data.length);\n            return;\n        }\n\n        _this.bytes += data.length;\n        if (rawDumpFileName) {\n            fs.appendFileSync(rawDumpFileName, data);\n        }\n        if (hexDumpConsolePrefix) {\n            console.log(hexDumpConsolePrefix + data.toString('hex'));\n        }\n\n        buf = Buffer.concat([ buf, data ]);\n\n        // Protocol version handling.  When dumping an output stream, the\n        // caller gives a non-null protocolVersion so we don't read one here.\n        if (protocolVersion == null) {\n            if (buf.length > 1024) {\n                _this.emit('transport-error', 'Parse error (version identification too long), dropping connection');\n                _this.close();\n                return;\n            }\n\n            for (i = 0, n = buf.length; i < n; i++) {\n                if (buf[i] == 0x0a) {\n                    tmpbuf = new Buffer(i);\n                    buf.copy(tmpbuf, 0, 0, i);\n                    consume(i + 1);\n                    verstr = tmpbuf.toString('utf-8');\n                    t = verstr.split(' ');\n                    protocolVersion = Number(t[0]);\n                    versionIdentification = verstr;\n\n                    _this.emit('protocol-version', {\n                        protocolVersion: protocolVersion,\n                        versionIdentification: versionIdentification\n                    });\n                    break;\n                }\n            }\n\n            if (protocolVersion == null) {\n                // Still waiting for version identification to complete.\n                return;\n            }\n        }\n\n        // Parse complete dvalues (quite inefficient now) by trial parsing.\n        // Consume a value only when it's fully present in 'buf'.\n        // See doc/debugger.rst for format description.\n\n        while (buf.length > 0) {\n            x = buf[0];\n            v = undefined;\n            gotValue = false;  // used to flag special values like undefined\n\n            if (x >= 0xc0) {\n                // 0xc0...0xff: integers 0-16383\n                if (buf.length >= 2) {\n                    v = ((x - 0xc0) << 8) + buf[1];\n                    consume(2);\n                }\n            } else if (x >= 0x80) {\n                // 0x80...0xbf: integers 0-63\n                v = x - 0x80;\n                consume(1);\n            } else if (x >= 0x60) {\n                // 0x60...0x7f: strings with length 0-31\n                len = x - 0x60;\n                if (buf.length >= 1 + len) {\n                    v = new Buffer(len);\n                    buf.copy(v, 0, 1, 1 + len);\n                    v = bufferToDebugString(v);\n                    consume(1 + len);\n                }\n            } else {\n                switch (x) {\n                case 0x00: v = DVAL_EOM; consume(1); break;\n                case 0x01: v = DVAL_REQ; consume(1); break;\n                case 0x02: v = DVAL_REP; consume(1); break;\n                case 0x03: v = DVAL_ERR; consume(1); break;\n                case 0x04: v = DVAL_NFY; consume(1); break;\n                case 0x10:  // 4-byte signed integer\n                    if (buf.length >= 5) {\n                        v = buf.readInt32BE(1);\n                        consume(5);\n                    }\n                    break;\n                case 0x11:  // 4-byte string\n                    if (buf.length >= 5) {\n                        len = buf.readUInt32BE(1);\n                        if (buf.length >= 5 + len) {\n                            v = new Buffer(len);\n                            buf.copy(v, 0, 5, 5 + len);\n                            v = bufferToDebugString(v);\n                            consume(5 + len);\n                        }\n                    }\n                    break;\n                case 0x12:  // 2-byte string\n                    if (buf.length >= 3) {\n                        len = buf.readUInt16BE(1);\n                        if (buf.length >= 3 + len) {\n                            v = new Buffer(len);\n                            buf.copy(v, 0, 3, 3 + len);\n                            v = bufferToDebugString(v);\n                            consume(3 + len);\n                        }\n                    }\n                    break;\n                case 0x13:  // 4-byte buffer\n                    if (buf.length >= 5) {\n                        len = buf.readUInt32BE(1);\n                        if (buf.length >= 5 + len) {\n                            v = new Buffer(len);\n                            buf.copy(v, 0, 5, 5 + len);\n                            v = { type: 'buffer', data: v.toString('hex') };\n                            consume(5 + len);\n                            // Value could be a Node.js buffer directly, but\n                            // we prefer all dvalues to be JSON compatible\n                        }\n                    }\n                    break;\n                case 0x14:  // 2-byte buffer\n                    if (buf.length >= 3) {\n                        len = buf.readUInt16BE(1);\n                        if (buf.length >= 3 + len) {\n                            v = new Buffer(len);\n                            buf.copy(v, 0, 3, 3 + len);\n                            v = { type: 'buffer', data: v.toString('hex') };\n                            consume(3 + len);\n                            // Value could be a Node.js buffer directly, but\n                            // we prefer all dvalues to be JSON compatible\n                        }\n                    }\n                    break;\n                case 0x15:  // unused/none\n                    v = { type: 'unused' };\n                    consume(1);\n                    break;\n                case 0x16:  // undefined\n                    v = { type: 'undefined' };\n                    gotValue = true;  // indicate 'v' is actually set\n                    consume(1);\n                    break;\n                case 0x17:  // null\n                    v = null;\n                    gotValue = true;  // indicate 'v' is actually set\n                    consume(1);\n                    break;\n                case 0x18:  // true\n                    v = true;\n                    consume(1);\n                    break;\n                case 0x19:  // false\n                    v = false;\n                    consume(1);\n                    break;\n                case 0x1a:  // number (IEEE double), big endian\n                    if (buf.length >= 9) {\n                        v = new Buffer(8);\n                        buf.copy(v, 0, 1, 9);\n                        v = { type: 'number', data: v.toString('hex') };\n\n                        if (_this.readableNumberValue) {\n                            // The value key should not be used programmatically,\n                            // it is just there to make the dumps more readable.\n                            v.value = buf.readDoubleBE(1);\n                        }\n                        consume(9);\n                    }\n                    break;\n                case 0x1b:  // object\n                    if (buf.length >= 3) {\n                        len = buf[2];\n                        if (buf.length >= 3 + len) {\n                            v = new Buffer(len);\n                            buf.copy(v, 0, 3, 3 + len);\n                            v = { type: 'object', 'class': buf[1], pointer: v.toString('hex') };\n                            consume(3 + len);\n                        }\n                    }\n                    break;\n                case 0x1c:  // pointer\n                    if (buf.length >= 2) {\n                        len = buf[1];\n                        if (buf.length >= 2 + len) {\n                            v = new Buffer(len);\n                            buf.copy(v, 0, 2, 2 + len);\n                            v = { type: 'pointer', pointer: v.toString('hex') };\n                            consume(2 + len);\n                        }\n                    }\n                    break;\n                case 0x1d:  // lightfunc\n                    if (buf.length >= 4) {\n                        len = buf[3];\n                        if (buf.length >= 4 + len) {\n                            v = new Buffer(len);\n                            buf.copy(v, 0, 4, 4 + len);\n                            v = { type: 'lightfunc', flags: buf.readUInt16BE(1), pointer: v.toString('hex') };\n                            consume(4 + len);\n                        }\n                    }\n                    break;\n                case 0x1e:  // heapptr\n                    if (buf.length >= 2) {\n                        len = buf[1];\n                        if (buf.length >= 2 + len) {\n                            v = new Buffer(len);\n                            buf.copy(v, 0, 2, 2 + len);\n                            v = { type: 'heapptr', pointer: v.toString('hex') };\n                            consume(2 + len);\n                        }\n                    }\n                    break;\n                default:\n                    _this.emit('transport-error', 'Parse error, dropping connection');\n                    _this.close();\n                }\n            }\n\n            if (typeof v === 'undefined' && !gotValue) {\n                break;\n            }\n            msg.push(v);\n            _this.dvalues++;\n\n            // Could emit a 'debug-value' event here, but that's not necessary\n            // because the receiver will just collect statistics which can also\n            // be done using the finished message.\n\n            if (v === DVAL_EOM) {\n                _this.messages++;\n\n                if (textDumpFileName || textDumpConsolePrefix) {\n                    prettyMsg = prettyDebugMessage(msg);\n                    if (textDumpFileName) {\n                        fs.appendFileSync(textDumpFileName, (textDumpFilePrefix || '') + prettyMsg + '\\n');\n                    }\n                    if (textDumpConsolePrefix) {\n                        console.log(textDumpConsolePrefix + prettyMsg);\n                    }\n                }\n\n                _this.emit('debug-message', msg);\n                msg = [];  // new object, old may be in circulation for a while\n            }\n        }\n    });\n\n    // Not all streams will emit this.\n    inputStream.on('error', function (err) {\n        _this.emit('transport-error', err);\n        _this.close();\n    });\n\n    // Not all streams will emit this.\n    inputStream.on('close', function () {\n        _this.close();\n    });\n}\nDebugProtocolParser.prototype = Object.create(events.EventEmitter.prototype);\n\nDebugProtocolParser.prototype.close = function () {\n    // Although the underlying transport may not have a close() or destroy()\n    // method or even a 'close' event, this method is always available and\n    // will generate a 'transport-close'.\n    //\n    // The caller is responsible for closing the underlying stream if that\n    // is necessary.\n\n    if (this.closed) { return; }\n\n    this.closed = true;\n    if (this.statsTimer) {\n        clearInterval(this.statsTimer);\n        this.statsTimer = null;\n    }\n    this.emit('transport-close');\n};\n\n/*\n *  Debugger output formatting\n */\n\nfunction formatDebugValue(v) {\n    var buf, dec, len;\n\n    // See doc/debugger.rst for format description.\n\n    if (typeof v === 'object' && v !== null) {\n        // Note: typeof null === 'object', so null special case explicitly\n        if (v.type === 'eom') {\n            return new Buffer([ 0x00 ]);\n        } else if (v.type === 'req') {\n            return new Buffer([ 0x01 ]);\n        } else if (v.type === 'rep') {\n            return new Buffer([ 0x02 ]);\n        } else if (v.type === 'err') {\n            return new Buffer([ 0x03 ]);\n        } else if (v.type === 'nfy') {\n            return new Buffer([ 0x04 ]);\n        } else if (v.type === 'unused') {\n            return new Buffer([ 0x15 ]);\n        } else if (v.type === 'undefined') {\n            return new Buffer([ 0x16 ]);\n        } else if (v.type === 'number') {\n            dec = new Buffer(v.data, 'hex');\n            len = dec.length;\n            if (len !== 8) {\n                throw new TypeError('value cannot be converted to dvalue: ' + JSON.stringify(v));\n            }\n            buf = new Buffer(1 + len);\n            buf[0] = 0x1a;\n            dec.copy(buf, 1);\n            return buf;\n        } else if (v.type === 'buffer') {\n            dec = new Buffer(v.data, 'hex');\n            len = dec.length;\n            if (len <= 0xffff) {\n                buf = new Buffer(3 + len);\n                buf[0] = 0x14;\n                buf[1] = (len >> 8) & 0xff;\n                buf[2] = (len >> 0) & 0xff;\n                dec.copy(buf, 3);\n                return buf;\n            } else {\n                buf = new Buffer(5 + len);\n                buf[0] = 0x13;\n                buf[1] = (len >> 24) & 0xff;\n                buf[2] = (len >> 16) & 0xff;\n                buf[3] = (len >> 8) & 0xff;\n                buf[4] = (len >> 0) & 0xff;\n                dec.copy(buf, 5);\n                return buf;\n            }\n        } else if (v.type === 'object') {\n            dec = new Buffer(v.pointer, 'hex');\n            len = dec.length;\n            buf = new Buffer(3 + len);\n            buf[0] = 0x1b;\n            buf[1] = v.class;\n            buf[2] = len;\n            dec.copy(buf, 3);\n            return buf;\n        } else if (v.type === 'pointer') {\n            dec = new Buffer(v.pointer, 'hex');\n            len = dec.length;\n            buf = new Buffer(2 + len);\n            buf[0] = 0x1c;\n            buf[1] = len;\n            dec.copy(buf, 2);\n            return buf;\n        } else if (v.type === 'lightfunc') {\n            dec = new Buffer(v.pointer, 'hex');\n            len = dec.length;\n            buf = new Buffer(4 + len);\n            buf[0] = 0x1d;\n            buf[1] = (v.flags >> 8) & 0xff;\n            buf[2] = v.flags & 0xff;\n            buf[3] = len;\n            dec.copy(buf, 4);\n            return buf;\n        } else if (v.type === 'heapptr') {\n            dec = new Buffer(v.pointer, 'hex');\n            len = dec.length;\n            buf = new Buffer(2 + len);\n            buf[0] = 0x1e;\n            buf[1] = len;\n            dec.copy(buf, 2);\n            return buf;\n        }\n    } else if (v === null) {\n        return new Buffer([ 0x17 ]);\n    } else if (typeof v === 'boolean') {\n        return new Buffer([ v ? 0x18 : 0x19 ]);\n    } else if (typeof v === 'number') {\n        if (Math.floor(v) === v &&     /* whole */\n            (v !== 0 || 1 / v > 0) &&  /* not negative zero */\n            v >= -0x80000000 && v <= 0x7fffffff) {\n            // Represented signed 32-bit integers as plain integers.\n            // Debugger code expects this for all fields that are not\n            // duk_tval representations (e.g. command numbers and such).\n            if (v >= 0x00 && v <= 0x3f) {\n                return new Buffer([ 0x80 + v ]);\n            } else if (v >= 0x0000 && v <= 0x3fff) {\n                return new Buffer([ 0xc0 + (v >> 8), v & 0xff ]);\n            } else if (v >= -0x80000000 && v <= 0x7fffffff) {\n                return new Buffer([ 0x10,\n                                    (v >> 24) & 0xff,\n                                    (v >> 16) & 0xff,\n                                    (v >> 8) & 0xff,\n                                    (v >> 0) & 0xff ]);\n            } else {\n                throw new Error('internal error when encoding integer to dvalue: ' + v);\n            }\n        } else {\n            // Represent non-integers as IEEE double dvalues\n            buf = new Buffer(1 + 8);\n            buf[0] = 0x1a;\n            buf.writeDoubleBE(v, 1);\n            return buf;\n        }\n    } else if (typeof v === 'string') {\n        if (v.length < 0 || v.length > 0xffffffff) {\n            // Not possible in practice.\n            throw new TypeError('cannot convert to dvalue, invalid string length: ' + v.length);\n        }\n        if (v.length <= 0x1f) {\n            buf = new Buffer(1 + v.length);\n            buf[0] = 0x60 + v.length;\n            writeDebugStringToBuffer(v, buf, 1);\n            return buf;\n        } else if (v.length <= 0xffff) {\n            buf = new Buffer(3 + v.length);\n            buf[0] = 0x12;\n            buf[1] = (v.length >> 8) & 0xff;\n            buf[2] = (v.length >> 0) & 0xff;\n            writeDebugStringToBuffer(v, buf, 3);\n            return buf;\n        } else {\n            buf = new Buffer(5 + v.length);\n            buf[0] = 0x11;\n            buf[1] = (v.length >> 24) & 0xff;\n            buf[2] = (v.length >> 16) & 0xff;\n            buf[3] = (v.length >> 8) & 0xff;\n            buf[4] = (v.length >> 0) & 0xff;\n            writeDebugStringToBuffer(v, buf, 5);\n            return buf;\n        }\n    }\n\n    // Shouldn't come here.\n    throw new TypeError('value cannot be converted to dvalue: ' + JSON.stringify(v));\n}\n\n/*\n *  Debugger implementation\n *\n *  A debugger instance communicates with the debug target and maintains\n *  persistent debug state so that the current state can be resent to the\n *  socket.io client (web UI) if it reconnects.  Whenever the debugger state\n *  is changed an event is generated.  The socket.io handler will listen to\n *  state change events and push the necessary updates to the web UI, often\n *  in a rate limited fashion or using a client pull to ensure the web UI\n *  is not overloaded.\n *\n *  The debugger instance assumes that if the debug protocol connection is\n *  re-established, it is always to the same target.  There is no separate\n *  abstraction for a debugger session.\n */\n\nfunction Debugger() {\n    events.EventEmitter.call(this);\n\n    this.web = null;                      // web UI singleton\n    this.targetStream = null;             // transport connection to target\n    this.outputPassThroughStream = null;  // dummy passthrough for message dumping\n    this.inputParser = null;              // parser for incoming debug messages\n    this.outputParser = null;             // parser for outgoing debug messages (stats, dumping)\n    this.protocolVersion = null;\n    this.dukVersion = null;\n    this.dukGitDescribe = null;\n    this.targetInfo = null;\n    this.attached = false;\n    this.handshook = false;\n    this.reqQueue = null;\n    this.stats = {                        // stats for current debug connection\n        rxBytes: 0, rxDvalues: 0, rxMessages: 0, rxBytesPerSec: 0,\n        txBytes: 0, txDvalues: 0, txMessages: 0, txBytesPerSec: 0\n    };\n    this.execStatus = {\n        attached: false,\n        state: 'detached',\n        fileName: '',\n        funcName: '',\n        line: 0,\n        pc: 0\n    };\n    this.breakpoints = [];\n    this.callstack = [];\n    this.locals = [];\n    this.messageLines = [];\n    this.messageScrollBack = 100;\n}\nDebugger.prototype = events.EventEmitter.prototype;\n\nDebugger.prototype.decodeBytecodeFromBuffer = function (buf, consts, funcs) {\n    var i, j, n, m, ins, pc;\n    var res = [];\n    var op, str, args, comments;\n\n    // XXX: add constants inline to preformatted output (e.g. for strings,\n    // add a short escaped snippet as a comment on the line after the\n    // compact argument list).\n\n    for (i = 0, n = buf.length; i < n; i += 4) {\n        pc = i / 4;\n\n        // shift forces unsigned\n        if (this.endianness === 'little') {\n            ins = buf.readInt32LE(i) >>> 0;\n        } else {\n            ins = buf.readInt32BE(i) >>> 0;\n        }\n\n        op = dukOpcodes.opcodes[ins & 0xff];\n\n        args = [];\n        comments = [];\n        if (op.args) {\n            for (j = 0, m = op.args.length; j < m; j++) {\n                var A = (ins >>> 8) & 0xff;\n                var B = (ins >>> 16) & 0xff;\n                var C = (ins >>> 24) & 0xff;\n                var BC = (ins >>> 16) & 0xffff;\n                var ABC = (ins >>> 8) & 0xffffff;\n                var Bconst = op & 0x01;\n                var Cconst = op & 0x02;\n\n                switch (op.args[j]) {\n                case 'A_R':   args.push('r' + A); break;\n                case 'A_RI':  args.push('r' + A + '(indirect)'); break;\n                case 'A_C':   args.push('c' + A); break;\n                case 'A_H':   args.push('0x' + A.toString(16)); break;\n                case 'A_I':   args.push(A.toString(10)); break;\n                case 'A_B':   args.push(A ? 'true' : 'false'); break;\n                case 'B_RC':  args.push((Bconst ? 'c' : 'r') + B); break;\n                case 'B_R':   args.push('r' + B); break;\n                case 'B_RI':  args.push('r' + B + '(indirect)'); break;\n                case 'B_C':   args.push('c' + B); break;\n                case 'B_H':   args.push('0x' + B.toString(16)); break;\n                case 'B_I':   args.push(B.toString(10)); break;\n                case 'C_RC':  args.push((Cconst ? 'c' : 'r') + C); break;\n                case 'C_R':   args.push('r' + C); break;\n                case 'C_RI':  args.push('r' + C + '(indirect)'); break;\n                case 'C_C':   args.push('c' + C); break;\n                case 'C_H':   args.push('0x' + C.toString(16)); break;\n                case 'C_I':   args.push(C.toString(10)); break;\n                case 'BC_R':  args.push('r' + BC); break;\n                case 'BC_C':  args.push('c' + BC); break;\n                case 'BC_H':  args.push('0x' + BC.toString(16)); break;\n                case 'BC_I':  args.push(BC.toString(10)); break;\n                case 'ABC_H': args.push(ABC.toString(16)); break;\n                case 'ABC_I': args.push(ABC.toString(10)); break;\n                case 'BC_LDINT': args.push(BC - (1 << 15)); break;\n                case 'BC_LDINTX': args.push(BC - 0); break;  // no bias in LDINTX\n                case 'ABC_JUMP': {\n                    var pc_add = ABC - (1 << 23) + 1;  // pc is preincremented before adding\n                    var pc_dst = pc + pc_add;\n                    args.push(pc_dst + ' (' + (pc_add >= 0 ? '+' : '') + pc_add + ')');\n                    break;\n                }\n                default:      args.push('?'); break;\n                }\n            }\n        }\n        if (op.flags) {\n            for (j = 0, m = op.flags.length; j < m; j++) {\n                if (ins & op.flags[j].mask) {\n                    comments.push(op.flags[j].name);\n                }\n            }\n        }\n\n        if (args.length > 0) {\n            str = sprintf('%05d %08x   %-12s %s', pc, ins, op.name, args.join(', '));\n        } else {\n            str = sprintf('%05d %08x   %-12s', pc, ins, op.name);\n        }\n        if (comments.length > 0) {\n            str = sprintf('%-44s ; %s', str, comments.join(', '));\n        }\n\n        res.push({\n            str: str,\n            ins: ins\n        });\n    }\n\n    return res;\n};\n\nDebugger.prototype.uiMessage = function (type, val) {\n    var msg;\n    if (typeof type === 'object') {\n        msg = type;\n    } else if (typeof type === 'string') {\n        msg = { type: type, message: val };\n    } else {\n        throw new TypeError('invalid ui message: ' + type);\n    }\n    this.messageLines.push(msg);\n    while (this.messageLines.length > this.messageScrollBack) {\n        this.messageLines.shift();\n    }\n    this.emit('ui-message-update');  // just trigger a sync, gets rate limited\n};\n\nDebugger.prototype.sendRequest = function (msg) {\n    var _this = this;\n    return new Promise(function (resolve, reject) {\n        var dvals = [];\n        var dval;\n        var data;\n        var i;\n\n        if (!_this.attached || !_this.handshook || !_this.reqQueue || !_this.targetStream) {\n            throw new Error('invalid state for sendRequest');\n        }\n\n        for (i = 0; i < msg.length; i++) {\n            try {\n                dval = formatDebugValue(msg[i]);\n            } catch (e) {\n                console.log('Failed to format dvalue, dropping connection: ' + e);\n                console.log(e.stack || e);\n                _this.targetStream.destroy();\n                throw new Error('failed to format dvalue');\n            }\n            dvals.push(dval);\n        }\n\n        data = Buffer.concat(dvals);\n\n        _this.targetStream.write(data);\n        _this.outputPassThroughStream.write(data);  // stats and dumping\n\n        if (optLogMessages) {\n            console.log('Request ' + prettyDebugCommand(msg[1]) + ': ' + prettyDebugMessage(msg));\n        }\n\n        if (!_this.reqQueue) {\n            throw new Error('no reqQueue');\n        }\n\n        _this.reqQueue.push({\n            reqMsg: msg,\n            reqCmd: msg[1],\n            resolveCb: resolve,\n            rejectCb: reject\n        });\n    });\n};\n\nDebugger.prototype.sendBasicInfoRequest = function () {\n    var _this = this;\n    return this.sendRequest([ DVAL_REQ, CMD_BASICINFO, DVAL_EOM ]).then(function (msg) {\n        _this.dukVersion = msg[1];\n        _this.dukGitDescribe = msg[2];\n        _this.targetInfo = msg[3];\n        _this.endianness = { 1: 'little', 2: 'mixed', 3: 'big' }[msg[4]] || 'unknown';\n        _this.emit('basic-info-update');\n        return msg;\n    });\n};\n\nDebugger.prototype.sendGetVarRequest = function (varname, level) {\n    var _this = this;\n    return this.sendRequest([ DVAL_REQ, CMD_GETVAR, (typeof level === 'number' ? level : -1), varname, DVAL_EOM ]).then(function (msg) {\n        return { found: msg[1] === 1, value: msg[2] };\n    });\n};\n\nDebugger.prototype.sendPutVarRequest = function (varname, varvalue, level) {\n    var _this = this;\n    return this.sendRequest([ DVAL_REQ, CMD_PUTVAR, (typeof level === 'number' ? level : -1), varname, varvalue, DVAL_EOM ]);\n};\n\nDebugger.prototype.sendInvalidCommandTestRequest = function () {\n    // Intentional invalid command\n    var _this = this;\n    return this.sendRequest([ DVAL_REQ, 0xdeadbeef, DVAL_EOM ]);\n};\n\nDebugger.prototype.sendStatusRequest = function () {\n    // Send a status request to trigger a status notify, result is ignored:\n    // target sends a status notify instead of a meaningful reply\n    var _this = this;\n    return this.sendRequest([ DVAL_REQ, CMD_TRIGGERSTATUS, DVAL_EOM ]);\n};\n\nDebugger.prototype.sendBreakpointListRequest = function () {\n    var _this = this;\n    return this.sendRequest([ DVAL_REQ, CMD_LISTBREAK, DVAL_EOM ]).then(function (msg) {\n        var i, n;\n        var breakpts = [];\n\n        for (i = 1, n = msg.length - 1; i < n; i += 2) {\n            breakpts.push({ fileName: msg[i], lineNumber: msg[i + 1] });\n        }\n\n        _this.breakpoints = breakpts;\n        _this.emit('breakpoints-update');\n        return msg;\n    });\n};\n\nDebugger.prototype.sendGetLocalsRequest = function (level) {\n    var _this = this;\n    return this.sendRequest([ DVAL_REQ, CMD_GETLOCALS, (typeof level === 'number' ? level : -1), DVAL_EOM ]).then(function (msg) {\n        var i;\n        var locals = [];\n\n        for (i = 1; i <= msg.length - 2; i += 2) {\n            // XXX: do pretty printing in debug client for now\n            locals.push({ key: msg[i], value: prettyUiDebugValue(msg[i + 1], LOCALS_CLIPLEN) });\n        }\n\n        _this.locals = locals;\n        _this.emit('locals-update');\n        return msg;\n    });\n};\n\nDebugger.prototype.sendGetCallStackRequest = function () {\n    var _this = this;\n    return this.sendRequest([ DVAL_REQ, CMD_GETCALLSTACK, DVAL_EOM ]).then(function (msg) {\n        var i;\n        var stack = [];\n\n        for (i = 1; i + 3 <= msg.length - 1; i += 4) {\n            stack.push({\n                fileName: msg[i],\n                funcName: msg[i + 1],\n                lineNumber: msg[i + 2],\n                pc: msg[i + 3]\n            });\n        }\n\n        _this.callstack = stack;\n        _this.emit('callstack-update');\n        return msg;\n    });\n};\n\nDebugger.prototype.sendStepIntoRequest = function () {\n    var _this = this;\n    return this.sendRequest([ DVAL_REQ, CMD_STEPINTO, DVAL_EOM ]);\n};\n\nDebugger.prototype.sendStepOverRequest = function () {\n    var _this = this;\n    return this.sendRequest([ DVAL_REQ, CMD_STEPOVER, DVAL_EOM ]);\n};\n\nDebugger.prototype.sendStepOutRequest = function () {\n    var _this = this;\n    return this.sendRequest([ DVAL_REQ, CMD_STEPOUT, DVAL_EOM ]);\n};\n\nDebugger.prototype.sendPauseRequest = function () {\n    var _this = this;\n    return this.sendRequest([ DVAL_REQ, CMD_PAUSE, DVAL_EOM ]);\n};\n\nDebugger.prototype.sendResumeRequest = function () {\n    var _this = this;\n    return this.sendRequest([ DVAL_REQ, CMD_RESUME, DVAL_EOM ]);\n};\n\nDebugger.prototype.sendEvalRequest = function (evalInput, level) {\n    var _this = this;\n    // Use explicit level if given.  If no level is given, use null if the call\n    // stack is empty, -1 otherwise.  This works well when we're paused and the\n    // callstack information is not liable to change before we do an Eval.\n    if (typeof level !== 'number') {\n        level = this.callstack && this.callstack.length > 0 ? -1 : null;\n    }\n    return this.sendRequest([ DVAL_REQ, CMD_EVAL, level, evalInput, DVAL_EOM ]).then(function (msg) {\n        return { error: msg[1] === 1 /*error*/, value: msg[2] };\n    });\n};\n\nDebugger.prototype.sendDetachRequest = function () {\n    var _this = this;\n    return this.sendRequest([ DVAL_REQ, CMD_DETACH, DVAL_EOM ]);\n};\n\nDebugger.prototype.sendDumpHeapRequest = function () {\n    var _this = this;\n\n    return this.sendRequest([ DVAL_REQ, CMD_DUMPHEAP, DVAL_EOM ]).then(function (msg) {\n        var res = {};\n        var objs = [];\n        var i, j, n, m, o, prop;\n\n        res.type = 'heapDump';\n        res.heapObjects = objs;\n\n        for (i = 1, n = msg.length - 1; i < n; /*nop*/) {\n            o = {};\n            o.ptr = msg[i++];\n            o.type = msg[i++];\n            o.flags = msg[i++] >>> 0;  /* unsigned */\n            o.refc = msg[i++];\n\n            if (o.type === DUK_HTYPE_STRING) {\n                o.blen = msg[i++];\n                o.clen = msg[i++];\n                o.hash = msg[i++] >>> 0;  /* unsigned */\n                o.data = msg[i++];\n            } else if (o.type === DUK_HTYPE_BUFFER) {\n                o.len = msg[i++];\n                o.data = msg[i++];\n            } else if (o.type === DUK_HTYPE_OBJECT) {\n                o['class'] = msg[i++];\n                o.proto = msg[i++];\n                o.esize = msg[i++];\n                o.enext = msg[i++];\n                o.asize = msg[i++];\n                o.hsize = msg[i++];\n                o.props = [];\n                for (j = 0, m = o.enext; j < m; j++) {\n                    prop = {};\n                    prop.flags = msg[i++];\n                    prop.key = msg[i++];\n                    prop.accessor = (msg[i++] == 1);\n                    if (prop.accessor) {\n                        prop.getter = msg[i++];\n                        prop.setter = msg[i++];\n                    } else {\n                        prop.value = msg[i++];\n                    }\n                    o.props.push(prop);\n                }\n                o.array = [];\n                for (j = 0, m = o.asize; j < m; j++) {\n                    prop = {};\n                    prop.value = msg[i++];\n                    o.array.push(prop);\n                }\n            } else {\n                console.log('invalid htype: ' + o.type + ', disconnect');\n                _this.disconnectDebugger();\n                throw new Error('invalid htype');\n                return;\n            }\n\n            objs.push(o);\n        }\n\n        return res;\n    });\n};\n\nDebugger.prototype.sendGetBytecodeRequest = function () {\n    var _this = this;\n\n    return this.sendRequest([ DVAL_REQ, CMD_GETBYTECODE, -1 /* level; could be other than -1 too */, DVAL_EOM ]).then(function (msg) {\n        var idx = 1;\n        var nconst;\n        var nfunc;\n        var val;\n        var buf;\n        var i, n;\n        var consts = [];\n        var funcs = [];\n        var bcode;\n        var preformatted;\n        var ret;\n        var idxPreformattedInstructions;\n\n        //console.log(JSON.stringify(msg));\n\n        nconst = msg[idx++];\n        for (i = 0; i < nconst; i++) {\n            val = msg[idx++];\n            consts.push(val);\n        }\n\n        nfunc = msg[idx++];\n        for (i = 0; i < nfunc; i++) {\n            val = msg[idx++];\n            funcs.push(val);\n        }\n        val = msg[idx++];\n\n        // Right now bytecode is a string containing a direct dump of the\n        // bytecode in target endianness.  Decode here so that the web UI\n        // doesn't need to.\n\n        buf = new Buffer(val.length);\n        writeDebugStringToBuffer(val, buf, 0);\n        bcode = _this.decodeBytecodeFromBuffer(buf, consts, funcs);\n\n        preformatted = [];\n        consts.forEach(function (v, i) {\n            preformatted.push('; c' + i + ' ' + JSON.stringify(v));\n        });\n        preformatted.push('');\n        idxPreformattedInstructions = preformatted.length;\n        bcode.forEach(function (v) {\n            preformatted.push(v.str);\n        });\n        preformatted = preformatted.join('\\n') + '\\n';\n\n        ret = {\n            constants: consts,\n            functions: funcs,\n            bytecode: bcode,\n            preformatted: preformatted,\n            idxPreformattedInstructions: idxPreformattedInstructions\n        };\n\n        return ret;\n    });\n};\n\nDebugger.prototype.changeBreakpoint = function (fileName, lineNumber, mode) {\n    var _this = this;\n\n    return this.sendRequest([ DVAL_REQ, CMD_LISTBREAK, DVAL_EOM ]).then(function (msg) {\n        var i, n;\n        var breakpts = [];\n        var deleted = false;\n\n        // Up-to-date list of breakpoints on target\n        for (i = 1, n = msg.length - 1; i < n; i += 2) {\n            breakpts.push({ fileName: msg[i], lineNumber: msg[i + 1] });\n        }\n\n        // Delete matching breakpoints in reverse order so that indices\n        // remain valid.  We do this for all operations so that duplicates\n        // are eliminated if present.\n        for (i = breakpts.length - 1; i >= 0; i--) {\n            var bp = breakpts[i];\n            if (mode === 'deleteall' || (bp.fileName === fileName && bp.lineNumber === lineNumber)) {\n                deleted = true;\n                _this.sendRequest([ DVAL_REQ, CMD_DELBREAK, i, DVAL_EOM ], function (msg) {\n                    // nop\n                }, function (err) {\n                    // nop\n                });\n            }\n        }\n\n        // Technically we should wait for each delbreak reply but because\n        // target processes the requests in order, it doesn't matter.\n        if ((mode === 'add') || (mode === 'toggle' && !deleted)) {\n            _this.sendRequest([ DVAL_REQ, CMD_ADDBREAK, fileName, lineNumber, DVAL_EOM ], function (msg) {\n                // nop\n            }, function (err) {\n                _this.uiMessage('debugger-info', 'Failed to add breakpoint: ' + err);\n            });\n        }\n\n        // Read final, effective breakpoints from the target\n        _this.sendBreakpointListRequest();\n    });\n};\n\nDebugger.prototype.disconnectDebugger = function () {\n    if (this.targetStream) {\n        // We require a destroy() method from the actual target stream\n        this.targetStream.destroy();\n        this.targetStream = null;\n    }\n    if (this.inputParser) {\n        this.inputParser.close();\n        this.inputParser = null;\n    }\n    if (this.outputPassThroughStream) {\n        // There is no close() or destroy() for a passthrough stream, so just\n        // close the outputParser which will cancel timers etc.\n    }\n    if (this.outputParser) {\n        this.outputParser.close();\n        this.outputParser = null;\n    }\n\n    this.attached = false;\n    this.handshook = false;\n    this.reqQueue = null;\n    this.execStatus = {\n        attached: false,\n        state: 'detached',\n        fileName: '',\n        funcName: '',\n        line: 0,\n        pc: 0\n    };\n};\n\nDebugger.prototype.connectDebugger = function () {\n    var _this = this;\n\n    this.disconnectDebugger();  // close previous target connection\n\n    // CUSTOMTRANSPORT: to use a custom transport, change this.targetStream to\n    // use your custom transport.\n\n    console.log('Connecting to ' + optTargetHost + ':' + optTargetPort + '...');\n    this.targetStream = new net.Socket();\n    this.targetStream.connect(optTargetPort, optTargetHost, function () {\n        console.log('Debug transport connected');\n        _this.attached = true;\n        _this.reqQueue = [];\n        _this.uiMessage('debugger-info', 'Debug transport connected');\n    });\n\n    this.inputParser = new DebugProtocolParser(\n        this.targetStream,\n        null,\n        optDumpDebugRead,\n        optDumpDebugPretty,\n        optDumpDebugPretty ? 'Recv: ' : null,\n        null,\n        null   // console logging is done at a higher level to match request/response\n    );\n\n    // Use a PassThrough stream to debug dump and get stats for output messages.\n    // Simply write outgoing data to both the targetStream and this passthrough\n    // separately.\n    this.outputPassThroughStream = stream.PassThrough();\n    this.outputParser = new DebugProtocolParser(\n        this.outputPassThroughStream,\n        1,\n        optDumpDebugWrite,\n        optDumpDebugPretty,\n        optDumpDebugPretty ? 'Send: ' : null,\n        null,\n        null   // console logging is done at a higher level to match request/response\n    );\n\n    this.inputParser.on('transport-close', function () {\n        _this.uiMessage('debugger-info', 'Debug transport closed');\n        _this.disconnectDebugger();\n        _this.emit('exec-status-update');\n        _this.emit('detached');\n    });\n\n    this.inputParser.on('transport-error', function (err) {\n        _this.uiMessage('debugger-info', 'Debug transport error: ' + err);\n        _this.disconnectDebugger();\n    });\n\n    this.inputParser.on('protocol-version', function (msg) {\n        var ver = msg.protocolVersion;\n        console.log('Debug version identification:', msg.versionIdentification);\n        _this.protocolVersion = ver;\n        _this.uiMessage('debugger-info', 'Debug version identification: ' + msg.versionIdentification);\n        if (ver !== SUPPORTED_DEBUG_PROTOCOL_VERSION) {\n            console.log('Unsupported debug protocol version (got ' + ver + ', support ' + SUPPORTED_DEBUG_PROTOCOL_VERSION + ')');\n            _this.uiMessage('debugger-info', 'Protocol version ' + ver + ' unsupported, dropping connection');\n            _this.targetStream.destroy();\n        } else {\n            _this.uiMessage('debugger-info', 'Debug protocol version: ' + ver);\n            _this.handshook = true;\n            _this.execStatus = {\n                attached: true,\n                state: 'attached',\n                fileName: '',\n                funcName: '',\n                line: 0,\n                pc: 0\n            };\n            _this.emit('exec-status-update');\n            _this.emit('attached');  // inform web UI\n\n            // Fetch basic info right away\n            _this.sendBasicInfoRequest();\n        }\n    });\n\n    this.inputParser.on('debug-message', function (msg) {\n        _this.processDebugMessage(msg);\n    });\n\n    this.inputParser.on('stats-update', function () {\n        _this.stats.rxBytes = this.bytes;\n        _this.stats.rxDvalues = this.dvalues;\n        _this.stats.rxMessages = this.messages;\n        _this.stats.rxBytesPerSec = this.bytesPerSec;\n        _this.emit('debug-stats-update');\n    });\n\n    this.outputParser.on('stats-update', function () {\n        _this.stats.txBytes = this.bytes;\n        _this.stats.txDvalues = this.dvalues;\n        _this.stats.txMessages = this.messages;\n        _this.stats.txBytesPerSec = this.bytesPerSec;\n        _this.emit('debug-stats-update');\n    });\n};\n\nDebugger.prototype.processDebugMessage = function (msg) {\n    var req;\n    var prevState, newState;\n    var err;\n\n    if (msg[0] === DVAL_REQ) {\n        // No actual requests sent by the target right now (just notifys).\n        console.log('Unsolicited reply message, dropping connection: ' + prettyDebugMessage(msg));\n    } else if (msg[0] === DVAL_REP) {\n        if (this.reqQueue.length <= 0) {\n            console.log('Unsolicited reply message, dropping connection: ' + prettyDebugMessage(msg));\n            this.targetStream.destroy();\n        }\n        req = this.reqQueue.shift();\n\n        if (optLogMessages) {\n            console.log('Reply for ' + prettyDebugCommand(req.reqCmd) + ': ' + prettyDebugMessage(msg));\n        }\n\n        if (req.resolveCb) {\n            req.resolveCb(msg);\n        } else {\n            // nop: no callback\n        }\n    } else if (msg[0] === DVAL_ERR) {\n        if (this.reqQueue.length <= 0) {\n            console.log('Unsolicited error message, dropping connection: ' + prettyDebugMessage(msg));\n            this.targetStream.destroy();\n        }\n        err = new Error(String(msg[2]) + ' (code ' + String(msg[1]) + ')');\n        err.errorCode = msg[1] || 0;\n        req = this.reqQueue.shift();\n\n        if (optLogMessages) {\n            console.log('Error for ' + prettyDebugCommand(req.reqCmd) + ': ' + prettyDebugMessage(msg));\n        }\n\n        if (req.rejectCb) {\n            req.rejectCb(err);\n        } else {\n            // nop: no callback\n        }\n    } else if (msg[0] === DVAL_NFY) {\n        if (optLogMessages) {\n            console.log('Notify ' + prettyDebugCommand(msg[1]) + ': ' + prettyDebugMessage(msg));\n        }\n\n        if (msg[1] === CMD_STATUS) {\n            prevState = this.execStatus.state;\n            newState = msg[2] === 0 ? 'running' : 'paused';\n            this.execStatus = {\n                attached: true,\n                state: newState,\n                fileName: msg[3],\n                funcName: msg[4],\n                line: msg[5],\n                pc: msg[6]\n            };\n\n            if (prevState !== newState && newState === 'paused') {\n                // update run state now that we're paused\n                this.sendBreakpointListRequest();\n                this.sendGetLocalsRequest();\n                this.sendGetCallStackRequest();\n            }\n\n            this.emit('exec-status-update');\n        } else if (msg[1] === CMD_THROW) {\n            this.uiMessage({ type: 'throw', fatal: msg[2], message: (msg[2] ? 'UNCAUGHT: ' : 'THROW: ') + prettyUiStringUnquoted(msg[3], UI_MESSAGE_CLIPLEN), fileName: msg[4], lineNumber: msg[5] });\n        } else if (msg[1] === CMD_DETACHING) {\n            this.uiMessage({ type: 'detaching', reason: msg[2], message: 'DETACH: ' + (msg.length >= 5 ? prettyUiStringUnquoted(msg[3]) : 'detaching') });\n        } else {\n            // Ignore unknown notify messages\n            console.log('Unknown notify, ignoring: ' + prettyDebugMessage(msg));\n\n            //this.targetStream.destroy();\n        }\n    } else {\n        console.log('Invalid initial dvalue, dropping connection: ' + prettyDebugMessage(msg));\n        this.targetStream.destroy();\n    }\n};\n\nDebugger.prototype.run = function () {\n    var _this = this;\n\n    // Initial debugger connection\n\n    this.connectDebugger();\n\n    // Poll various state items when running\n\n    var sendRound = 0;\n    var statusPending = false;\n    var bplistPending = false;\n    var localsPending = false;\n    var callStackPending = false;\n\n    setInterval(function () {\n        if (_this.execStatus.state !== 'running') {\n            return;\n        }\n\n        // Could also check for an empty request queue, but that's probably\n        // too strict?\n\n        // Pending flags are used to avoid requesting the same thing twice\n        // while a previous request is pending.  The flag-based approach is\n        // quite awkward.  Rework to use promises.\n\n        switch (sendRound) {\n        case 0:\n            if (!statusPending) {\n                statusPending = true;\n                _this.sendStatusRequest().finally(function () { statusPending = false; });\n            }\n            break;\n        case 1:\n            if (!bplistPending) {\n                bplistPending = true;\n                _this.sendBreakpointListRequest().finally(function () { bplistPending = false; });\n            }\n            break;\n        case 2:\n            if (!localsPending) {\n                localsPending = true;\n                _this.sendGetLocalsRequest().finally(function () { localsPending = false; });\n            }\n            break;\n        case 3:\n            if (!callStackPending) {\n                callStackPending = true;\n                _this.sendGetCallStackRequest().finally(function () { callStackPending = false; });\n            }\n            break;\n        }\n        sendRound = (sendRound + 1) % 4;\n    }, 500);\n};\n\n/*\n *  Express setup and socket.io\n */\n\nfunction DebugWebServer() {\n    this.dbg = null;       // debugger singleton\n    this.socket = null;    // current socket (or null)\n    this.keepaliveTimer = null;\n    this.uiMessageLimiter = null;\n    this.cachedJson = {};  // cache to avoid resending identical data\n    this.sourceFileManager = new SourceFileManager(optSourceSearchDirs);\n    this.sourceFileManager.scan();\n}\n\nDebugWebServer.prototype.handleSourcePost = function (req, res) {\n    var fileName = req.body && req.body.fileName;\n    var fileData;\n\n    console.log('Source request: ' + fileName);\n\n    if (typeof fileName !== 'string') {\n        res.status(500).send('invalid request');\n        return;\n    }\n    fileData = this.sourceFileManager.search(fileName, optSourceSearchDirs);\n    if (typeof fileData !== 'string') {\n        res.status(404).send('not found');\n        return;\n    }\n    res.status(200).send(fileData);  // UTF-8\n};\n\nDebugWebServer.prototype.handleSourceListPost = function (req, res) {\n    console.log('Source list request');\n\n    var files = this.sourceFileManager.getFiles();\n    res.header('Content-Type', 'application/json');\n    res.status(200).json(files);\n};\n\nDebugWebServer.prototype.handleHeapDumpGet = function (req, res) {\n    console.log('Heap dump get');\n\n    this.dbg.sendDumpHeapRequest().then(function (val) {\n        res.header('Content-Type', 'application/json');\n        //res.status(200).json(val);\n        res.status(200).send(JSON.stringify(val, null, 4));\n    }).catch(function (err) {\n        res.status(500).send('Failed to get heap dump: ' + (err.stack || err));\n    });\n};\n\nDebugWebServer.prototype.run = function () {\n    var _this = this;\n\n    var express = require('express');\n    var bodyParser = require('body-parser');\n    var app = express();\n    var http = require('http').Server(app);\n    var io = require('socket.io')(http);\n\n    app.use(bodyParser.json());\n    app.post('/source', this.handleSourcePost.bind(this));\n    app.post('/sourceList', this.handleSourceListPost.bind(this));\n    app.get('/heapDump.json', this.handleHeapDumpGet.bind(this));\n    app.use('/', express.static(__dirname + '/static'));\n\n    http.listen(optHttpPort, function () {\n        console.log('Listening on *:' + optHttpPort);\n    });\n\n    io.on('connection', this.handleNewSocketIoConnection.bind(this));\n\n    this.dbg.on('attached', function () {\n        console.log('Debugger attached');\n    });\n\n    this.dbg.on('detached', function () {\n        console.log('Debugger detached');\n    });\n\n    this.dbg.on('debug-stats-update', function () {\n        _this.debugStatsLimiter.trigger();\n    });\n\n    this.dbg.on('ui-message-update', function () {\n        // Explicit rate limiter because this is a source of a lot of traffic.\n        _this.uiMessageLimiter.trigger();\n    });\n\n    this.dbg.on('basic-info-update', function () {\n        _this.emitBasicInfo();\n    });\n\n    this.dbg.on('breakpoints-update', function () {\n        _this.emitBreakpoints();\n    });\n\n    this.dbg.on('exec-status-update', function () {\n        // Explicit rate limiter because this is a source of a lot of traffic.\n        _this.execStatusLimiter.trigger();\n    });\n\n    this.dbg.on('locals-update', function () {\n        _this.emitLocals();\n    });\n\n    this.dbg.on('callstack-update', function () {\n        _this.emitCallStack();\n    });\n\n    this.uiMessageLimiter = new RateLimited(10, 1000, this.uiMessageLimiterCallback.bind(this));\n    this.execStatusLimiter = new RateLimited(50, 500, this.execStatusLimiterCallback.bind(this));\n    this.debugStatsLimiter = new RateLimited(1, 2000, this.debugStatsLimiterCallback.bind(this));\n\n    this.keepaliveTimer = setInterval(this.emitKeepalive.bind(this), 30000);\n};\n\nDebugWebServer.prototype.handleNewSocketIoConnection = function (socket) {\n    var _this = this;\n\n    console.log('Socket.io connected');\n    if (this.socket) {\n        console.log('Closing previous socket.io socket');\n        this.socket.emit('replaced');\n    }\n    this.socket = socket;\n\n    this.emitKeepalive();\n\n    socket.on('disconnect', function () {\n        console.log('Socket.io disconnected');\n        if (_this.socket === socket) {\n             _this.socket = null;\n        }\n    });\n\n    socket.on('keepalive', function (msg) {\n        // nop\n    });\n\n    socket.on('attach', function (msg) {\n        if (_this.dbg.targetStream) {\n            console.log('Attach request when debugger already has a connection, ignoring');\n        } else {\n            _this.dbg.connectDebugger();\n        }\n    });\n\n    socket.on('detach', function (msg) {\n        // Try to detach cleanly, timeout if no response\n        Promise.any([\n            _this.dbg.sendDetachRequest(),\n            Promise.delay(3000)\n        ]).finally(function () {\n            _this.dbg.disconnectDebugger();\n        });\n    });\n\n    socket.on('stepinto', function (msg) {\n        _this.dbg.sendStepIntoRequest();\n    });\n\n    socket.on('stepover', function (msg) {\n        _this.dbg.sendStepOverRequest();\n    });\n\n    socket.on('stepout', function (msg) {\n        _this.dbg.sendStepOutRequest();\n    });\n\n    socket.on('pause', function (msg) {\n        _this.dbg.sendPauseRequest();\n    });\n\n    socket.on('resume', function (msg) {\n        _this.dbg.sendResumeRequest();\n    });\n\n    socket.on('eval', function (msg) {\n        // msg.input is a proper Unicode strings here, and needs to be\n        // converted into a protocol string (U+0000...U+00FF).\n        var input = stringToDebugString(msg.input);\n        _this.dbg.sendEvalRequest(input, msg.level).then(function (v) {\n            socket.emit('eval-result', { error: v.error, result: prettyUiDebugValue(v.value, EVAL_CLIPLEN) });\n        });\n\n        // An eval call quite possibly changes the local variables so always\n        // re-read locals afterwards.  We don't need to wait for Eval to\n        // complete here; the requests will pipeline automatically and be\n        // executed in order.\n\n        // XXX: move this to the web UI so that the UI can control what\n        // locals are listed (or perhaps show locals for all levels with\n        // an expandable tree view).\n        _this.dbg.sendGetLocalsRequest();\n    });\n\n    socket.on('getvar', function (msg) {\n        // msg.varname is a proper Unicode strings here, and needs to be\n        // converted into a protocol string (U+0000...U+00FF).\n        var varname = stringToDebugString(msg.varname);\n        _this.dbg.sendGetVarRequest(varname, msg.level)\n        .then(function (v) {\n            socket.emit('getvar-result', { found: v.found, result: prettyUiDebugValue(v.value, GETVAR_CLIPLEN) });\n        });\n    });\n\n    socket.on('putvar', function (msg) {\n        // msg.varname and msg.varvalue are proper Unicode strings here, they\n        // need to be converted into protocol strings (U+0000...U+00FF).\n        var varname = stringToDebugString(msg.varname);\n        var varvalue = msg.varvalue;\n\n        // varvalue is JSON parsed by the web UI for now, need special string\n        // encoding here.\n        if (typeof varvalue === 'string') {\n            varvalue = stringToDebugString(msg.varvalue);\n        }\n\n        _this.dbg.sendPutVarRequest(varname, varvalue, msg.level)\n        .then(function (v) {\n            console.log('putvar done');  // XXX: signal success to UI?\n        });\n\n        // A PutVar call quite possibly changes the local variables so always\n        // re-read locals afterwards.  We don't need to wait for PutVar to\n        // complete here; the requests will pipeline automatically and be\n        // executed in order.\n\n        // XXX: make the client do this?\n        _this.dbg.sendGetLocalsRequest();\n    });\n\n    socket.on('add-breakpoint', function (msg) {\n        _this.dbg.changeBreakpoint(msg.fileName, msg.lineNumber, 'add');\n    });\n\n    socket.on('delete-breakpoint', function (msg) {\n        _this.dbg.changeBreakpoint(msg.fileName, msg.lineNumber, 'delete');\n    });\n\n    socket.on('toggle-breakpoint', function (msg) {\n        _this.dbg.changeBreakpoint(msg.fileName, msg.lineNumber, 'toggle');\n    });\n\n    socket.on('delete-all-breakpoints', function (msg) {\n        _this.dbg.changeBreakpoint(null, null, 'deleteall');\n    });\n\n    socket.on('get-bytecode', function (msg) {\n        _this.dbg.sendGetBytecodeRequest().then(function (res) {\n            socket.emit('bytecode', res);\n        });\n    });\n\n    // Resend all debugger state for new client\n    this.cachedJson = {};  // clear client state cache\n    this.emitBasicInfo();\n    this.emitStats();\n    this.emitExecStatus();\n    this.emitUiMessages();\n    this.emitBreakpoints();\n    this.emitCallStack();\n    this.emitLocals();\n};\n\n// Check if 'msg' would encode to the same JSON which was previously sent\n// to the web client.  The caller then avoid resending unnecessary stuff.\nDebugWebServer.prototype.cachedJsonCheck = function (cacheKey, msg) {\n    var newJson = JSON.stringify(msg);\n    if (this.cachedJson[cacheKey] === newJson) {\n        return true;  // cached\n    }\n    this.cachedJson[cacheKey] = newJson;\n    return false;  // not cached, send (cache already updated)\n};\n\nDebugWebServer.prototype.uiMessageLimiterCallback = function () {\n    this.emitUiMessages();\n};\n\nDebugWebServer.prototype.execStatusLimiterCallback = function () {\n    this.emitExecStatus();\n};\n\nDebugWebServer.prototype.debugStatsLimiterCallback = function () {\n    this.emitStats();\n};\n\nDebugWebServer.prototype.emitKeepalive = function () {\n    if (!this.socket) { return; }\n\n    this.socket.emit('keepalive', { nodeVersion: process.version });\n};\n\nDebugWebServer.prototype.emitBasicInfo = function () {\n    if (!this.socket) { return; }\n\n    var newMsg = {\n        duk_version: this.dbg.dukVersion,\n        duk_git_describe: this.dbg.dukGitDescribe,\n        target_info: this.dbg.targetInfo,\n        endianness: this.dbg.endianness\n    };\n    if (this.cachedJsonCheck('basic-info', newMsg)) {\n        return;\n    }\n    this.socket.emit('basic-info', newMsg);\n};\n\nDebugWebServer.prototype.emitStats = function () {\n    if (!this.socket) { return; }\n\n    this.socket.emit('debug-stats', this.dbg.stats);\n};\n\nDebugWebServer.prototype.emitExecStatus = function () {\n    if (!this.socket) { return; }\n\n    var newMsg = this.dbg.execStatus;\n    if (this.cachedJsonCheck('exec-status', newMsg)) {\n        return;\n    }\n    this.socket.emit('exec-status', newMsg);\n};\n\nDebugWebServer.prototype.emitUiMessages = function () {\n    if (!this.socket) { return; }\n\n    var newMsg = this.dbg.messageLines;\n    if (this.cachedJsonCheck('output-lines', newMsg)) {\n        return;\n    }\n    this.socket.emit('output-lines', newMsg);\n};\n\nDebugWebServer.prototype.emitBreakpoints = function () {\n    if (!this.socket) { return; }\n\n    var newMsg = { breakpoints: this.dbg.breakpoints };\n    if (this.cachedJsonCheck('breakpoints', newMsg)) {\n        return;\n    }\n    this.socket.emit('breakpoints', newMsg);\n};\n\nDebugWebServer.prototype.emitCallStack = function () {\n    if (!this.socket) { return; }\n\n    var newMsg = { callstack: this.dbg.callstack };\n    if (this.cachedJsonCheck('callstack', newMsg)) {\n        return;\n    }\n    this.socket.emit('callstack', newMsg);\n};\n\nDebugWebServer.prototype.emitLocals = function () {\n    if (!this.socket) { return; }\n\n    var newMsg = { locals: this.dbg.locals };\n    if (this.cachedJsonCheck('locals', newMsg)) {\n        return;\n    }\n    this.socket.emit('locals', newMsg);\n};\n\n/*\n *  JSON debug proxy\n */\n\nfunction DebugProxy(serverPort) {\n    this.serverPort = serverPort;\n    this.server = null;\n    this.socket = null;\n    this.targetStream = null;\n    this.inputParser = null;\n\n    // preformatted dvalues\n    this.dval_eom = formatDebugValue(DVAL_EOM);\n    this.dval_req = formatDebugValue(DVAL_REQ);\n    this.dval_rep = formatDebugValue(DVAL_REP);\n    this.dval_nfy = formatDebugValue(DVAL_NFY);\n    this.dval_err = formatDebugValue(DVAL_ERR);\n}\n\nDebugProxy.prototype.determineCommandNumber = function (cmdName, cmdNumber) {\n    var ret;\n    if (typeof cmdName === 'string') {\n        ret = debugCommandNumbers[cmdName];\n    } else if (typeof cmdName === 'number') {\n        ret = cmdName;\n    }\n    ret = ret || cmdNumber;\n    if (typeof ret !== 'number') {\n        throw Error('cannot figure out command number for \"' + cmdName + '\" (' + cmdNumber + ')');\n    }\n    return ret;\n};\n\nDebugProxy.prototype.commandNumberToString = function (id) {\n    return debugCommandNames[id] || String(id);\n};\n\nDebugProxy.prototype.formatDvalues = function (args) {\n    if (!args) {\n        return [];\n    }\n    return args.map(function (v) {\n        return formatDebugValue(v);\n    });\n};\n\nDebugProxy.prototype.writeJson = function (val) {\n    this.socket.write(JSON.stringify(val) + '\\n');\n};\n\nDebugProxy.prototype.writeJsonSafe = function (val) {\n    try {\n        this.writeJson(val);\n    } catch (e) {\n        console.log('Failed to write JSON in writeJsonSafe, ignoring: ' + e);\n    }\n};\n\nDebugProxy.prototype.disconnectJsonClient = function () {\n    if (this.socket) {\n        this.socket.destroy();\n        this.socket = null;\n    }\n};\n\nDebugProxy.prototype.disconnectTarget = function () {\n    if (this.inputParser) {\n        this.inputParser.close();\n        this.inputParser = null;\n    }\n    if (this.targetStream) {\n        this.targetStream.destroy();\n        this.targetStream = null;\n    }\n};\n\nDebugProxy.prototype.run = function () {\n    var _this = this;\n\n    console.log('Waiting for client connections on port ' + this.serverPort);\n    this.server = net.createServer(function (socket) {\n        console.log('JSON proxy client connected');\n\n        _this.disconnectJsonClient();\n        _this.disconnectTarget();\n\n        // A byline-parser is simple and good enough for now (assume\n        // compact JSON with no newlines).\n        var socketByline = byline(socket);\n        _this.socket = socket;\n\n        socketByline.on('data', function (line) {\n            try {\n                // console.log('Received json proxy input line: ' + line.toString('utf8'));\n                var msg = JSON.parse(line.toString('utf8'));\n                var first_dval;\n                var args_dvalues = _this.formatDvalues(msg.args);\n                var last_dval = _this.dval_eom;\n                var cmd;\n\n                if (msg.request) {\n                    // \"request\" can be a string or \"true\"\n                    first_dval = _this.dval_req;\n                    cmd = _this.determineCommandNumber(msg.request, msg.command);\n                } else if (msg.reply) {\n                    first_dval = _this.dval_rep;\n                } else if (msg.notify) {\n                    // \"notify\" can be a string or \"true\"\n                    first_dval = _this.dval_nfy;\n                    cmd = _this.determineCommandNumber(msg.notify, msg.command);\n                } else if (msg.error) {\n                    first_dval = _this.dval_err;\n                } else {\n                    throw new Error('Invalid input JSON message: ' + JSON.stringify(msg));\n                }\n\n                _this.targetStream.write(first_dval);\n                if (cmd) {\n                    _this.targetStream.write(formatDebugValue(cmd));\n                }\n                args_dvalues.forEach(function (v) {\n                    _this.targetStream.write(v);\n                });\n                _this.targetStream.write(last_dval);\n            } catch (e) {\n                console.log(e);\n\n                _this.writeJsonSafe({\n                    notify: '_Error',\n                    args: [ 'Failed to handle input json message: ' + e ]\n                });\n\n                _this.disconnectJsonClient();\n                _this.disconnectTarget();\n            }\n        });\n\n        _this.connectToTarget();\n    }).listen(this.serverPort);\n};\n\nDebugProxy.prototype.connectToTarget = function () {\n    var _this = this;\n\n    console.log('Connecting to ' + optTargetHost + ':' + optTargetPort + '...');\n    this.targetStream = new net.Socket();\n    this.targetStream.connect(optTargetPort, optTargetHost, function () {\n        console.log('Debug transport connected');\n    });\n\n    this.inputParser = new DebugProtocolParser(\n        this.targetStream,\n        null,\n        optDumpDebugRead,\n        optDumpDebugPretty,\n        optDumpDebugPretty ? 'Recv: ' : null,\n        null,\n        null   // console logging is done at a higher level to match request/response\n    );\n\n    // Don't add a 'value' key to numbers.\n    this.inputParser.readableNumberValue = false;\n\n    this.inputParser.on('transport-close', function () {\n        console.log('Debug transport closed');\n\n        _this.writeJsonSafe({\n            notify: '_Disconnecting'\n        });\n\n        _this.disconnectJsonClient();\n        _this.disconnectTarget();\n    });\n\n    this.inputParser.on('transport-error', function (err) {\n        console.log('Debug transport error', err);\n\n        _this.writeJsonSafe({\n            notify: '_Error',\n            args: [ String(err) ]\n        });\n    });\n\n    this.inputParser.on('protocol-version', function (msg) {\n        var ver = msg.protocolVersion;\n        console.log('Debug version identification:', msg.versionIdentification);\n\n        _this.writeJson({\n            notify: '_TargetConnected',\n            args: [ msg.versionIdentification ]  // raw identification string\n        });\n\n        if (ver !== 1) {\n            console.log('Protocol version ' + ver + ' unsupported, dropping connection');\n        }\n    });\n\n    this.inputParser.on('debug-message', function (msg) {\n        var t;\n\n        //console.log(msg);\n\n        if (typeof msg[0] !== 'object' || msg[0] === null) {\n            throw new Error('unexpected initial dvalue: ' + msg[0]);\n        } else if (msg[0].type === 'eom') {\n            throw new Error('unexpected initial dvalue: ' + msg[0]);\n        } else if (msg[0].type === 'req') {\n            if (typeof msg[1] !== 'number') {\n                throw new Error('unexpected request command number: ' + msg[1]);\n            }\n            t = {\n                request: _this.commandNumberToString(msg[1]),\n                command: msg[1],\n                args: msg.slice(2, msg.length - 1)\n            };\n            _this.writeJson(t);\n        } else if (msg[0].type === 'rep') {\n            t = {\n                reply: true,\n                args: msg.slice(1, msg.length - 1)\n            };\n            _this.writeJson(t);\n        } else if (msg[0].type === 'err') {\n            t = {\n                error: true,\n                args: msg.slice(1, msg.length - 1)\n            };\n            _this.writeJson(t);\n        } else if (msg[0].type === 'nfy') {\n            if (typeof msg[1] !== 'number') {\n                throw new Error('unexpected notify command number: ' + msg[1]);\n            }\n            t = {\n                notify: _this.commandNumberToString(msg[1]),\n                command: msg[1],\n                args: msg.slice(2, msg.length - 1)\n            };\n            _this.writeJson(t);\n        } else {\n            throw new Error('unexpected initial dvalue: ' + msg[0]);\n        }\n    });\n\n    this.inputParser.on('stats-update', function () {\n    });\n};\n\n/*\n *  Command line parsing and initialization\n */\n\nfunction main() {\n    console.log('((o) Duktape debugger');\n\n    // Parse arguments.\n\n    var argv = require('minimist')(process.argv.slice(2));\n    //console.dir(argv);\n    if (argv['target-host']) {\n        optTargetHost = argv['target-host'];\n    }\n    if (argv['target-port']) {\n        optTargetPort = argv['target-port'];\n    }\n    if (argv['http-port']) {\n        optHttpPort = argv['http-port'];\n    }\n    if (argv['json-proxy-port']) {\n        optJsonProxyPort = argv['json-proxy-port'];\n    }\n    if (argv['json-proxy']) {\n        optJsonProxy = argv['json-proxy'];\n    }\n    if (argv['source-dirs']) {\n        optSourceSearchDirs = argv['source-dirs'].split(path.delimiter);\n    }\n    if (argv['dump-debug-read']) {\n        optDumpDebugRead = argv['dump-debug-read'];\n    }\n    if (argv['dump-debug-write']) {\n        optDumpDebugWrite = argv['dump-debug-write'];\n    }\n    if (argv['dump-debug-pretty']) {\n        optDumpDebugPretty = argv['dump-debug-pretty'];\n    }\n    if (argv['log-messages']) {\n        optLogMessages = true;\n    }\n\n    // Dump effective options.  Also provides a list of option names.\n\n    console.log('');\n    console.log('Effective options:');\n    console.log('  --target-host:       ' + optTargetHost);\n    console.log('  --target-port:       ' + optTargetPort);\n    console.log('  --http-port:         ' + optHttpPort);\n    console.log('  --json-proxy-port:   ' + optJsonProxyPort);\n    console.log('  --json-proxy:        ' + optJsonProxy);\n    console.log('  --source-dirs:       ' + optSourceSearchDirs.join(' '));\n    console.log('  --dump-debug-read:   ' + optDumpDebugRead);\n    console.log('  --dump-debug-write:  ' + optDumpDebugWrite);\n    console.log('  --dump-debug-pretty: ' + optDumpDebugPretty);\n    console.log('  --log-messages:      ' + optLogMessages);\n    console.log('');\n\n    // Create debugger and web UI singletons, tie them together and\n    // start them.\n\n    if (optJsonProxy) {\n        console.log('Starting in JSON proxy mode, JSON port: ' + optJsonProxyPort);\n\n        var prx = new DebugProxy(optJsonProxyPort);\n        prx.run();\n    } else {\n        var dbg = new Debugger();\n        var web = new DebugWebServer();\n        dbg.web = web;\n        web.dbg = dbg;\n        dbg.run();\n        web.run();\n    }\n}\n\nmain();\n"
  },
  {
    "path": "react_juce/duktape/debugger/duk_debug_meta.json",
    "content": "{\n    \"error_codes\": [\n        \"Unknown\", \n        \"UnsupportedCommand\", \n        \"TooMany\", \n        \"NotFound\", \n        \"ApplicationError\"\n    ], \n    \"opcodes\": [\n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_R\"\n            ], \n            \"name\": \"LDREG\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_R\"\n            ], \n            \"name\": \"STREG\"\n        }, \n        {\n            \"args\": [\n                \"ABC_JUMP\"\n            ], \n            \"name\": \"JUMP\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_C\"\n            ], \n            \"name\": \"LDCONST\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_LDINT\"\n            ], \n            \"name\": \"LDINT\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_LDINTX\"\n            ], \n            \"name\": \"LDINTX\"\n        }, \n        {\n            \"args\": [\n                \"BC_R\"\n            ], \n            \"name\": \"LDTHIS\"\n        }, \n        {\n            \"args\": [\n                \"BC_R\"\n            ], \n            \"name\": \"LDUNDEF\"\n        }, \n        {\n            \"args\": [\n                \"BC_R\"\n            ], \n            \"name\": \"LDNULL\"\n        }, \n        {\n            \"args\": [\n                \"BC_R\"\n            ], \n            \"name\": \"LDTRUE\"\n        }, \n        {\n            \"args\": [\n                \"BC_R\"\n            ], \n            \"name\": \"LDFALSE\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_C\"\n            ], \n            \"name\": \"GETVAR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_R\"\n            ], \n            \"name\": \"BNOT\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_R\"\n            ], \n            \"name\": \"LNOT\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_R\"\n            ], \n            \"name\": \"UNM\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_R\"\n            ], \n            \"name\": \"UNP\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"EQ_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"EQ_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"EQ_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"EQ_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"NEQ_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"NEQ_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"NEQ_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"NEQ_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"SEQ_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"SEQ_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"SEQ_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"SEQ_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"SNEQ_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"SNEQ_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"SNEQ_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"SNEQ_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"GT_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"GT_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"GT_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"GT_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"GE_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"GE_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"GE_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"GE_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"LT_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"LT_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"LT_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"LT_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"LE_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"LE_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"LE_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"LE_CC\"\n        }, \n        {\n            \"args\": [\n                \"BC_R\"\n            ], \n            \"name\": \"IFTRUE_R\"\n        }, \n        {\n            \"args\": [\n                \"BC_C\"\n            ], \n            \"name\": \"IFTRUE_C\"\n        }, \n        {\n            \"args\": [\n                \"BC_R\"\n            ], \n            \"name\": \"IFFALSE_R\"\n        }, \n        {\n            \"args\": [\n                \"BC_C\"\n            ], \n            \"name\": \"IFFALSE_C\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"ADD_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"ADD_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"ADD_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"ADD_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"SUB_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"SUB_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"SUB_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"SUB_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"MUL_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"MUL_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"MUL_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"MUL_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"DIV_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"DIV_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"DIV_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"DIV_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"MOD_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"MOD_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"MOD_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"MOD_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"EXP_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"EXP_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"EXP_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"EXP_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"BAND_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"BAND_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"BAND_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"BAND_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"BOR_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"BOR_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"BOR_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"BOR_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"BXOR_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"BXOR_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"BXOR_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"BXOR_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"BASL_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"BASL_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"BASL_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"BASL_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"BLSR_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"BLSR_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"BLSR_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"BLSR_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"BASR_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"BASR_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"BASR_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"BASR_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"INSTOF_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"INSTOF_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"INSTOF_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"INSTOF_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"IN_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"IN_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"IN_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"IN_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"GETPROP_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"GETPROP_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"GETPROP_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"GETPROP_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"PUTPROP_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"PUTPROP_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"PUTPROP_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"PUTPROP_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"DELPROP_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"DELPROP_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"DELPROP_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"DELPROP_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_R\"\n            ], \n            \"name\": \"PREINCR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_R\"\n            ], \n            \"name\": \"PREDECR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_R\"\n            ], \n            \"name\": \"POSTINCR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_R\"\n            ], \n            \"name\": \"POSTDECR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_C\"\n            ], \n            \"name\": \"PREINCV\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_C\"\n            ], \n            \"name\": \"PREDECV\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_C\"\n            ], \n            \"name\": \"POSTINCV\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_C\"\n            ], \n            \"name\": \"POSTDECV\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"PREINCP_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"PREINCP_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"PREINCP_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"PREINCP_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"PREDECP_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"PREDECP_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"PREDECP_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"PREDECP_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"POSTINCP_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"POSTINCP_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"POSTINCP_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"POSTINCP_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"POSTDECP_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"POSTDECP_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"POSTDECP_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"POSTDECP_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_H\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"flags\": [\n                {\n                    \"mask\": 256, \n                    \"name\": \"writable\"\n                }, \n                {\n                    \"mask\": 512, \n                    \"name\": \"enumerable\"\n                }, \n                {\n                    \"mask\": 1024, \n                    \"name\": \"configurable\"\n                }, \n                {\n                    \"mask\": 2048, \n                    \"name\": \"accessor\"\n                }, \n                {\n                    \"mask\": 4096, \n                    \"name\": \"func_decl\"\n                }\n            ], \n            \"name\": \"DECLVAR_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_H\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"flags\": [\n                {\n                    \"mask\": 256, \n                    \"name\": \"writable\"\n                }, \n                {\n                    \"mask\": 512, \n                    \"name\": \"enumerable\"\n                }, \n                {\n                    \"mask\": 1024, \n                    \"name\": \"configurable\"\n                }, \n                {\n                    \"mask\": 2048, \n                    \"name\": \"accessor\"\n                }, \n                {\n                    \"mask\": 4096, \n                    \"name\": \"func_decl\"\n                }\n            ], \n            \"name\": \"DECLVAR_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_H\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"flags\": [\n                {\n                    \"mask\": 256, \n                    \"name\": \"writable\"\n                }, \n                {\n                    \"mask\": 512, \n                    \"name\": \"enumerable\"\n                }, \n                {\n                    \"mask\": 1024, \n                    \"name\": \"configurable\"\n                }, \n                {\n                    \"mask\": 2048, \n                    \"name\": \"accessor\"\n                }, \n                {\n                    \"mask\": 4096, \n                    \"name\": \"func_decl\"\n                }\n            ], \n            \"name\": \"DECLVAR_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_H\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"flags\": [\n                {\n                    \"mask\": 256, \n                    \"name\": \"writable\"\n                }, \n                {\n                    \"mask\": 512, \n                    \"name\": \"enumerable\"\n                }, \n                {\n                    \"mask\": 1024, \n                    \"name\": \"configurable\"\n                }, \n                {\n                    \"mask\": 2048, \n                    \"name\": \"accessor\"\n                }, \n                {\n                    \"mask\": 4096, \n                    \"name\": \"func_decl\"\n                }\n            ], \n            \"name\": \"DECLVAR_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"REGEXP_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"REGEXP_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"REGEXP_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"REGEXP_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_I\"\n            ], \n            \"name\": \"CLOSURE\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_R\"\n            ], \n            \"name\": \"TYPEOF\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_C\"\n            ], \n            \"name\": \"TYPEOFID\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_C\"\n            ], \n            \"name\": \"PUTVAR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_C\"\n            ], \n            \"name\": \"DELVAR\"\n        }, \n        {\n            \"args\": [\n                \"BC_R\"\n            ], \n            \"name\": \"RETREG\"\n        }, \n        {\n            \"name\": \"RETUNDEF\"\n        }, \n        {\n            \"args\": [\n                \"BC_C\"\n            ], \n            \"name\": \"RETCONST\"\n        }, \n        {\n            \"args\": [\n                \"BC_C\"\n            ], \n            \"name\": \"RETCONSTN\"\n        }, \n        {\n            \"args\": [\n                \"BC_I\"\n            ], \n            \"name\": \"LABEL\"\n        }, \n        {\n            \"args\": [\n                \"BC_I\"\n            ], \n            \"name\": \"ENDLABEL\"\n        }, \n        {\n            \"args\": [\n                \"BC_I\"\n            ], \n            \"name\": \"BREAK\"\n        }, \n        {\n            \"args\": [\n                \"BC_I\"\n            ], \n            \"name\": \"CONTINUE\"\n        }, \n        {\n            \"args\": [\n                \"A_H\", \n                \"BC_R\"\n            ], \n            \"flags\": [\n                {\n                    \"mask\": 64, \n                    \"name\": \"have_catch\"\n                }, \n                {\n                    \"mask\": 128, \n                    \"name\": \"have_finally\"\n                }, \n                {\n                    \"mask\": 256, \n                    \"name\": \"catch_binding\"\n                }, \n                {\n                    \"mask\": 512, \n                    \"name\": \"with_binding\"\n                }\n            ], \n            \"name\": \"TRYCATCH\"\n        }, \n        {\n            \"name\": \"ENDTRY\"\n        }, \n        {\n            \"name\": \"ENDCATCH\"\n        }, \n        {\n            \"args\": [\n                \"ABC_R\"\n            ], \n            \"name\": \"ENDFIN\"\n        }, \n        {\n            \"args\": [\n                \"BC_R\"\n            ], \n            \"name\": \"THROW\"\n        }, \n        {\n            \"name\": \"INVLHS\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_R\"\n            ], \n            \"name\": \"CSREG\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\"\n            ], \n            \"name\": \"CSVAR_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\"\n            ], \n            \"name\": \"CSVAR_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\"\n            ], \n            \"name\": \"CSVAR_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\"\n            ], \n            \"name\": \"CSVAR_CC\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL0\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL1\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL2\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL3\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL4\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL5\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL6\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL7\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL8\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL9\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL10\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL11\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL12\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL13\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL14\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"CALL15\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"NEWOBJ\"\n        }, \n        {\n            \"args\": [\n                \"A_I\", \n                \"BC_R\"\n            ], \n            \"name\": \"NEWARR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_I\"\n            ], \n            \"name\": \"MPUTOBJ\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_RI\", \n                \"C_I\"\n            ], \n            \"name\": \"MPUTOBJI\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_R\"\n            ], \n            \"name\": \"INITSET\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"BC_R\"\n            ], \n            \"name\": \"INITGET\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_I\"\n            ], \n            \"name\": \"MPUTARR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_RI\", \n                \"C_I\"\n            ], \n            \"name\": \"MPUTARRI\"\n        }, \n        {\n            \"args\": [\n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"SETALEN\"\n        }, \n        {\n            \"args\": [\n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"INITENUM\"\n        }, \n        {\n            \"args\": [\n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"NEXTENUM\"\n        }, \n        {\n            \"args\": [\n                \"BC_R\"\n            ], \n            \"name\": \"NEWTARGET\"\n        }, \n        {\n            \"name\": \"DEBUGGER\"\n        }, \n        {\n            \"args\": [\n                \"ABC_I\"\n            ], \n            \"name\": \"NOP\"\n        }, \n        {\n            \"args\": [\n                \"ABC_I\"\n            ], \n            \"name\": \"INVALID\"\n        }, \n        {\n            \"name\": \"UNUSED207\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_R\"\n            ], \n            \"name\": \"GETPROPC_RR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_R\"\n            ], \n            \"name\": \"GETPROPC_CR\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_R\", \n                \"C_C\"\n            ], \n            \"name\": \"GETPROPC_RC\"\n        }, \n        {\n            \"args\": [\n                \"A_R\", \n                \"B_C\", \n                \"C_C\"\n            ], \n            \"name\": \"GETPROPC_CC\"\n        }, \n        {\n            \"name\": \"UNUSED212\"\n        }, \n        {\n            \"name\": \"UNUSED213\"\n        }, \n        {\n            \"name\": \"UNUSED214\"\n        }, \n        {\n            \"name\": \"UNUSED215\"\n        }, \n        {\n            \"name\": \"UNUSED216\"\n        }, \n        {\n            \"name\": \"UNUSED217\"\n        }, \n        {\n            \"name\": \"UNUSED218\"\n        }, \n        {\n            \"name\": \"UNUSED219\"\n        }, \n        {\n            \"name\": \"UNUSED220\"\n        }, \n        {\n            \"name\": \"UNUSED221\"\n        }, \n        {\n            \"name\": \"UNUSED222\"\n        }, \n        {\n            \"name\": \"UNUSED223\"\n        }, \n        {\n            \"name\": \"UNUSED224\"\n        }, \n        {\n            \"name\": \"UNUSED225\"\n        }, \n        {\n            \"name\": \"UNUSED226\"\n        }, \n        {\n            \"name\": \"UNUSED227\"\n        }, \n        {\n            \"name\": \"UNUSED228\"\n        }, \n        {\n            \"name\": \"UNUSED229\"\n        }, \n        {\n            \"name\": \"UNUSED230\"\n        }, \n        {\n            \"name\": \"UNUSED231\"\n        }, \n        {\n            \"name\": \"UNUSED232\"\n        }, \n        {\n            \"name\": \"UNUSED233\"\n        }, \n        {\n            \"name\": \"UNUSED234\"\n        }, \n        {\n            \"name\": \"UNUSED235\"\n        }, \n        {\n            \"name\": \"UNUSED236\"\n        }, \n        {\n            \"name\": \"UNUSED237\"\n        }, \n        {\n            \"name\": \"UNUSED238\"\n        }, \n        {\n            \"name\": \"UNUSED239\"\n        }, \n        {\n            \"name\": \"UNUSED240\"\n        }, \n        {\n            \"name\": \"UNUSED241\"\n        }, \n        {\n            \"name\": \"UNUSED242\"\n        }, \n        {\n            \"name\": \"UNUSED243\"\n        }, \n        {\n            \"name\": \"UNUSED244\"\n        }, \n        {\n            \"name\": \"UNUSED245\"\n        }, \n        {\n            \"name\": \"UNUSED246\"\n        }, \n        {\n            \"name\": \"UNUSED247\"\n        }, \n        {\n            \"name\": \"UNUSED248\"\n        }, \n        {\n            \"name\": \"UNUSED249\"\n        }, \n        {\n            \"name\": \"UNUSED250\"\n        }, \n        {\n            \"name\": \"UNUSED251\"\n        }, \n        {\n            \"name\": \"UNUSED252\"\n        }, \n        {\n            \"name\": \"UNUSED253\"\n        }, \n        {\n            \"name\": \"UNUSED254\"\n        }, \n        {\n            \"name\": \"UNUSED255\"\n        }\n    ], \n    \"client_commands\": [\n        \"Reserved_0\", \n        \"Status\", \n        \"Reserved_2\", \n        \"Reserved_3\", \n        \"Reserved_4\", \n        \"Throw\", \n        \"Detaching\", \n        \"AppNotify\"\n    ], \n    \"class_names\": [\n        \"none\", \n        \"Object\", \n        \"Array\", \n        \"Function\", \n        \"Arguments\", \n        \"Boolean\", \n        \"Date\", \n        \"Error\", \n        \"JSON\", \n        \"Math\", \n        \"Number\", \n        \"RegExp\", \n        \"String\", \n        \"global\", \n        \"Symbol\", \n        \"ObjEnv\", \n        \"DecEnv\", \n        \"Pointer\", \n        \"Thread\", \n        \"ArrayBuffer\", \n        \"DataView\", \n        \"Int8Array\", \n        \"Uint8Array\", \n        \"Uint8ClampedArray\", \n        \"Int16Array\", \n        \"Uint16Array\", \n        \"Int32Array\", \n        \"Uint32Array\", \n        \"Float32Array\", \n        \"Float64Array\"\n    ], \n    \"target_commands\": [\n        \"Reserved_0\", \n        \"Reserved_1\", \n        \"Reserved_2\", \n        \"Reserved_3\", \n        \"Reserved_4\", \n        \"Reserved_5\", \n        \"Reserved_6\", \n        \"Reserved_7\", \n        \"Reserved_8\", \n        \"Reserved_9\", \n        \"Reserved_10\", \n        \"Reserved_11\", \n        \"Reserved_12\", \n        \"Reserved_13\", \n        \"Reserved_14\", \n        \"Reserved_15\", \n        \"BasicInfo\", \n        \"TriggerStatus\", \n        \"Pause\", \n        \"Resume\", \n        \"StepInto\", \n        \"StepOver\", \n        \"StepOut\", \n        \"ListBreak\", \n        \"AddBreak\", \n        \"DelBreak\", \n        \"GetVar\", \n        \"PutVar\", \n        \"GetCallStack\", \n        \"GetLocals\", \n        \"Eval\", \n        \"Detach\", \n        \"DumpHeap\", \n        \"GetBytecode\", \n        \"AppRequest\", \n        \"GetHeapObjInfo\", \n        \"GetObjPropDesc\", \n        \"GetObjPropDescRange\"\n    ]\n}\n"
  },
  {
    "path": "react_juce/duktape/debugger/duk_debug_proxy.js",
    "content": "/*\n *  JSON debug proxy written in DukLuv\n *\n *  This single file JSON debug proxy implementation is an alternative to the\n *  Node.js-based proxy in duk_debug.js.  DukLuv is a much smaller dependency\n *  than Node.js so embedding DukLuv in a debug client is easier.\n */\n\n'use strict';\n\n// XXX: Code assumes uv.write() will write fully.  This is not necessarily\n// true; should add support for partial writes (or at least failing when\n// a partial write occurs).\n\nvar log = new Duktape.Logger('Proxy');  // default logger\n//log.l = 0;  // enable debug and trace logging\n\n/*\n *  Config\n */\n\nvar serverHost = '0.0.0.0';\nvar serverPort = 9093;\nvar targetHost = '127.0.0.1';\nvar targetPort = 9091;\nvar singleConnection = false;\nvar readableNumberValue = false;\nvar lenientJsonParse = false;\nvar jxParse = false;\nvar metadataFile = null;\nvar metadata = {};\nvar TORTURE = false;  // for manual testing of binary/json parsing robustness\n\n/*\n *  Duktape 1.x and 2.x buffer harmonization\n */\n\nvar allocPlain = (typeof Uint8Array.allocPlain === 'function' ?\n                  Uint8Array.allocPlain : Duktape.Buffer);\nvar plainOf = (typeof Uint8Array.plainOf === 'function' ?\n               Uint8Array.plainOf : Duktape.Buffer);\nvar bufferToString = (typeof String.fromBuffer === 'function' ?\n                      String.fromBuffer : String);\n\n/*\n *  Detect missing 'var' declarations\n */\n\n// Prevent new bindings on global object.  This detects missing 'var'\n// declarations, e.g. \"x = 123;\" in a function without declaring it.\nvar global = new Function('return this;')();\nlog.debug('Preventing extensions on global object');\nlog.debug('Global is extensible:', Object.isExtensible(global));\nObject.preventExtensions(global);\nlog.debug('Global is extensible:', Object.isExtensible(global));\n\n/*\n *  Misc helpers\n */\n\nfunction jxEncode(v) {\n    return Duktape.enc('jx', v);\n}\n\nfunction plainBufferCopy(typedarray) {\n    // This is still pretty awkward in Duktape 1.4.x.\n    // Argument may be a \"slice\" and we want a copy of the slice\n    // (not the full underlying buffer).\n\n    var u8 = new Uint8Array(typedarray.length);\n    u8.set(typedarray);  // make a copy, ensuring there's no slice offset\n    return plainOf(u8);  // get underlying plain buffer\n}\n\nfunction isObject(x) {\n    // Note that typeof null === 'object'.\n    return (typeof x === 'object' && x !== null);\n}\n\nfunction readFully(filename, cb) {\n    uv.fs_open(metadataFile, 'r', 0, function (handle, err) {\n        var fileOff = 0;\n        var data = new Uint8Array(256);\n        var dataOff = 0;\n\n        if (err) {\n            return cb(null, err);\n        }\n        function readCb(buf, err) {\n            var res;\n            var newData;\n\n            log.debug('Read callback:', buf.length, err);\n            if (err) {\n                uv.fs_close(handle);\n                return cb(null, err);\n            }\n            if (buf.length == 0) {\n                uv.fs_close(handle);\n                res = new Uint8Array(dataOff);\n                res.set(data.subarray(0, dataOff));\n                res = plainOf(res);  // plain buffer\n                log.debug('Read', res.length, 'bytes from', filename);\n                return cb(res, null);\n            }\n            while (data.length - dataOff < buf.length) {\n                log.debug('Resize file read buffer:', data.length, '->', data.length * 2);\n                newData = new Uint8Array(data.length * 2);\n                newData.set(data);\n                data = newData;\n            }\n            data.set(new Uint8Array(buf), dataOff);\n            dataOff += buf.length;\n            fileOff += buf.length;\n            uv.fs_read(handle, 4096, fileOff, readCb);\n        }\n        uv.fs_read(handle, 4096, fileOff, readCb);\n    });\n}\n\n/*\n *  JSON proxy server\n *\n *  Accepts an incoming JSON proxy client and connects to a debug target,\n *  tying the two connections together.  Supports both a single connection\n *  and a persistent mode.\n */\n\nfunction JsonProxyServer(host, port) {\n    this.name = 'JsonProxyServer';\n    this.handle = uv.new_tcp();\n    uv.tcp_bind(this.handle, host, port);\n    uv.listen(this.handle, 128, this.onConnection.bind(this));\n}\n\nJsonProxyServer.prototype.onConnection = function onConnection(err) {\n    if (err) {\n        log.error('JSON proxy onConnection error:', err);\n        return;\n    }\n    log.info('JSON proxy client connected');  // XXX: it'd be nice to log remote peer host:port\n\n    var jsonSock = new JsonConnHandler(this);\n    var targSock = new TargetConnHandler(this);\n    jsonSock.targetHandler = targSock;\n    targSock.jsonHandler = jsonSock;\n    uv.accept(this.handle, jsonSock.handle);\n\n    log.info('Connecting to debug target at', targetHost + ':' + targetPort);\n    jsonSock.writeJson({ notify: '_TargetConnecting', args: [ targetHost, targetPort ] });\n    uv.tcp_connect(targSock.handle, targetHost, targetPort, targSock.onConnect.bind(targSock));\n\n    if (singleConnection) {\n        log.info('Single connection mode, stop listening for more connections');\n        uv.shutdown(this.handle);\n        uv.read_stop(this.handle);  // unnecessary but just in case\n        uv.close(this.handle);\n        this.handle = null;\n    }\n};\n\nJsonProxyServer.prototype.onProxyClientDisconnected = function onProxyClientDisconnected() {\n    // When this is invoked the proxy connection and the target connection\n    // have both been closed.\n    if (singleConnection) {\n        log.info('Proxy connection finished (single connection mode: we should be exiting now)');\n    } else {\n        log.info('Proxy connection finished (persistent mode: wait for more connections)');\n    }\n};\n\n/*\n *  JSON connection handler\n */\n\nfunction JsonConnHandler(server) {\n    var i, n;\n\n    this.name = 'JsonConnHandler';\n    this.server = server;\n    this.handle = uv.new_tcp();\n    this.incoming = new Uint8Array(4096);\n    this.incomingOffset = 0;\n    this.targetHandler = null;\n\n    this.commandNumberLookup = {};\n    if (metadata && metadata.target_commands) {\n        for (i = 0, n = metadata.target_commands.length; i < n; i++) {\n            this.commandNumberLookup[metadata.target_commands[i]] = i;\n        }\n    }\n}\n\nJsonConnHandler.prototype.finish = function finish(msg) {\n    var args;\n\n    if (!this.handle) {\n        log.info('JsonConnHandler already disconnected, ignore finish()');\n        return;\n    }\n    log.info('JsonConnHandler finished:', msg);\n    try {\n        args = msg ? [ msg ] : void 0;\n        this.writeJson({ notify: '_Disconnecting', args: args });\n    } catch (e) {\n        log.info('Failed to write _Disconnecting notify, ignoring:', e);\n    }\n    uv.shutdown(this.handle);\n    uv.read_stop(this.handle);\n    uv.close(this.handle);\n    this.handle = null;\n\n    this.targetHandler.finish(msg);  // disconnect target too (if not already disconnected)\n\n    this.server.onProxyClientDisconnected();\n};\n\nJsonConnHandler.prototype.onRead = function onRead(err, data) {\n    var newIncoming;\n    var msg;\n    var errmsg;\n    var tmpBuf;\n\n    log.trace('Received data from JSON socket, err:', err, 'data length:', data ? data.length : 'null');\n\n    if (err) {\n        errmsg = 'Error reading data from JSON debug client: ' + err;\n        this.finish(errmsg);\n        return;\n    }\n    if (data) {\n        // Feed the data one byte at a time when torture testing.\n        if (TORTURE && data.length > 1) {\n            for (var i = 0; i < data.length; i++) {\n                tmpBuf = allocPlain(1);\n                tmpBuf[0] = data[i];\n                this.onRead(null, tmpBuf);\n            }\n            return;\n        }\n\n        // Receive data into 'incoming', resizing as necessary.\n        while (data.length > this.incoming.length - this.incomingOffset) {\n            newIncoming = new Uint8Array(this.incoming.length * 1.3 + 16);\n            newIncoming.set(this.incoming);\n            this.incoming = newIncoming;\n            log.debug('Resize incoming JSON buffer to ' + this.incoming.length);\n        }\n        this.incoming.set(new Uint8Array(data), this.incomingOffset);\n        this.incomingOffset += data.length;\n\n        // Trial parse JSON message(s).\n        while (true) {\n            msg = this.trialParseJsonMessage();\n            if (!msg) {\n                break;\n            }\n            try {\n                this.dispatchJsonMessage(msg);\n            } catch (e) {\n                errmsg = 'JSON message dispatch failed: ' + e;\n                this.writeJson({ notify: '_Error', args: [ errmsg ] });\n                if (lenientJsonParse) {\n                    log.warn('JSON message dispatch failed (lenient mode, ignoring):', e);\n                } else {\n                    log.warn('JSON message dispatch failed (dropping connection):', e);\n                    this.finish(errmsg);\n                }\n            }\n        }\n    } else {\n        this.finish('JSON proxy client disconnected');\n    }\n};\n\nJsonConnHandler.prototype.writeJson = function writeJson(msg) {\n    log.info('PROXY --> CLIENT:', JSON.stringify(msg));\n    if (this.handle) {\n        uv.write(this.handle, JSON.stringify(msg) + '\\n');\n    }\n};\n\nJsonConnHandler.prototype.handleDebugMessage = function handleDebugMessage(dvalues) {\n    var msg = {};\n    var idx = 0;\n    var cmd;\n\n    if (dvalues.length <= 0) {\n        throw new Error('invalid dvalues list: length <= 0');\n    }\n    var x = dvalues[idx++];\n    if (!isObject(x)) {\n        throw new Error('invalid initial dvalue: ' + Duktape.enc('jx', dvalues));\n    }\n    if (x.type === 'req') {\n        cmd = dvalues[idx++];\n        if (typeof cmd !== 'number') {\n            throw new Error('invalid command: ' + Duktape.enc('jx', cmd));\n        }\n        msg.request = this.determineCommandName(cmd) || true;\n        msg.command = cmd;\n    } else if (x.type === 'rep') {\n        msg.reply = true;\n    } else if (x.type === 'err') {\n        msg.error = true;\n    } else if (x.type === 'nfy') {\n        cmd = dvalues[idx++];\n        if (typeof cmd !== 'number') {\n            throw new Error('invalid command: ' + Duktape.enc('jx', cmd));\n        }\n        msg.notify = this.determineCommandName(cmd) || true;\n        msg.command = cmd;\n    } else {\n        throw new Error('invalid initial dvalue: ' + Duktape.enc('jx', dvalues));\n    }\n\n    for (; idx < dvalues.length - 1; idx++) {\n        if (!msg.args) {\n            msg.args = [];\n        }\n        msg.args.push(dvalues[idx]);\n    }\n\n    if (!isObject(dvalues[idx]) || dvalues[idx].type !== 'eom') {\n        throw new Error('invalid final dvalue: ' + Duktape.enc('jx', dvalues));\n    }\n\n    this.writeJson(msg);\n};\n\nJsonConnHandler.prototype.determineCommandName = function determineCommandName(cmd) {\n    if (!(metadata && metadata.client_commands)) {\n        return;\n    }\n    return metadata.client_commands[cmd];\n};\n\nJsonConnHandler.prototype.trialParseJsonMessage = function trialParseJsonMessage() {\n    var buf = this.incoming;\n    var avail = this.incomingOffset;\n    var i;\n    var msg, str, errmsg;\n\n    for (i = 0; i < avail; i++) {\n        if (buf[i] == 0x0a) {\n            str = bufferToString(plainBufferCopy(buf.subarray(0, i)));\n            try {\n                if (jxParse) {\n                    msg = Duktape.dec('jx', str);\n                } else {\n                    msg = JSON.parse(str);\n                }\n            } catch (e) {\n                // In lenient mode if JSON parse fails just send back an _Error\n                // and ignore the line (useful for initial development).\n                //\n                // In non-lenient mode drop the connection here; if the failed line\n                // was a request the client is expecting a reply/error message back\n                // (otherwise it may go out of sync) but we can't send a synthetic\n                // one (as we can't parse the request).\n                errmsg = 'JSON parse failed for: ' + jxEncode(str) + ': ' + e;\n                this.writeJson({ notify: '_Error', args: [ errmsg ] });\n                if (lenientJsonParse) {\n                    log.warn('JSON parse failed (lenient mode, ignoring):', e);\n                } else {\n                    log.warn('JSON parse failed (dropping connection):', e);\n                    this.finish(errmsg);\n                }\n            }\n\n            this.incoming.set(this.incoming.subarray(i + 1));\n            this.incomingOffset -= i + 1;\n            return msg;\n        }\n    }\n};\n\nJsonConnHandler.prototype.dispatchJsonMessage = function dispatchJsonMessage(msg) {\n    var cmd;\n    var dvalues = [];\n    var i, n;\n\n    log.info('PROXY <-- CLIENT:', JSON.stringify(msg));\n\n    // Parse message type, determine initial marker for binary message.\n    if (msg.request) {\n        cmd = this.determineCommandNumber(msg.request, msg.command);\n        dvalues.push(new Uint8Array([ 0x01 ]));\n        dvalues.push(this.encodeJsonDvalue(cmd));\n    } else if (msg.reply) {\n        dvalues.push(new Uint8Array([ 0x02 ]));\n    } else if (msg.notify) {\n        cmd = this.determineCommandNumber(msg.notify, msg.command);\n        dvalues.push(new Uint8Array([ 0x04 ]));\n        dvalues.push(this.encodeJsonDvalue(cmd));\n    } else if (msg.error) {\n        dvalues.push(new Uint8Array([ 0x03 ]));\n    } else {\n        throw new Error('invalid input JSON message: ' + jxEncode(msg));\n    }\n\n    // Encode arguments into dvalues.\n    for (i = 0, n = (msg.args ? msg.args.length : 0); i < n; i++) {\n        dvalues.push(this.encodeJsonDvalue(msg.args[i]));\n    }\n\n    // Add an EOM, and write out the dvalues to the debug target.\n    dvalues.push(new Uint8Array([ 0x00 ]));\n    for (i = 0, n = dvalues.length; i < n; i++) {\n        this.targetHandler.writeBinary(dvalues[i]);\n    }\n};\n\nJsonConnHandler.prototype.determineCommandNumber = function determineCommandNumber(name, val) {\n    var res;\n\n    if (typeof name === 'string') {\n        res = this.commandNumberLookup[name];\n        if (!res) {\n            log.info('Unknown command name: ' + name + ', command number: ' + val);\n        }\n    } else if (typeof name === 'number') {\n        res = name;\n    } else if (name !== true) {\n        throw new Error('invalid command name (must be string, number, or \"true\"): ' + name);\n    }\n    if (typeof res === 'undefined' && typeof val === 'undefined') {\n        throw new Error('cannot determine command number from name: ' + name);\n    }\n    if (typeof val !== 'number' && typeof val !== 'undefined') {\n        throw new Error('invalid command number: ' + val);\n    }\n    res = res || val;\n    return res;\n};\n\nJsonConnHandler.prototype.writeDebugStringToBuffer = function writeDebugStringToBuffer(v, buf, off) {\n    var i, n;\n\n    for (i = 0, n = v.length; i < n; i++) {\n        buf[off + i] = v.charCodeAt(i) & 0xff;  // truncate higher bits\n    }\n};\n\nJsonConnHandler.prototype.encodeJsonDvalue = function encodeJsonDvalue(v) {\n    var buf, dec, len, dv;\n\n    if (isObject(v)) {\n        if (v.type === 'eom') {\n            return new Uint8Array([ 0x00 ]);\n        } else if (v.type === 'req') {\n            return new Uint8Array([ 0x01 ]);\n        } else if (v.type === 'rep') {\n            return new Uint8Array([ 0x02 ]);\n        } else if (v.type === 'err') {\n            return new Uint8Array([ 0x03 ]);\n        } else if (v.type === 'nfy') {\n            return new Uint8Array([ 0x04 ]);\n        } else if (v.type === 'unused') {\n            return new Uint8Array([ 0x15 ]);\n        } else if (v.type === 'undefined') {\n            return new Uint8Array([ 0x16 ]);\n        } else if (v.type === 'number') {\n            dec = Duktape.dec('hex', v.data);\n            len = dec.length;\n            if (len !== 8) {\n                throw new TypeError('value cannot be converted to dvalue: ' + jxEncode(v));\n            }\n            buf = new Uint8Array(1 + len);\n            buf[0] = 0x1a;\n            buf.set(new Uint8Array(dec), 1);\n            return buf;\n        } else if (v.type === 'buffer') {\n            dec = Duktape.dec('hex', v.data);\n            len = dec.length;\n            if (len <= 0xffff) {\n                buf = new Uint8Array(3 + len);\n                buf[0] = 0x14;\n                buf[1] = (len >> 8) & 0xff;\n                buf[2] = (len >> 0) & 0xff;\n                buf.set(new Uint8Arrau(dec), 3);\n                return buf;\n            } else {\n                buf = new Uint8Array(5 + len);\n                buf[0] = 0x13;\n                buf[1] = (len >> 24) & 0xff;\n                buf[2] = (len >> 16) & 0xff;\n                buf[3] = (len >> 8) & 0xff;\n                buf[4] = (len >> 0) & 0xff;\n                buf.set(new Uint8Array(dec), 5);\n                return buf;\n            }\n        } else if (v.type === 'object') {\n            dec = Duktape.dec('hex', v.pointer);\n            len = dec.length;\n            buf = new Uint8Array(3 + len);\n            buf[0] = 0x1b;\n            buf[1] = v.class;\n            buf[2] = len;\n            buf.set(new Uint8Array(dec), 3);\n            return buf;\n        } else if (v.type === 'pointer') {\n            dec = Duktape.dec('hex', v.pointer);\n            len = dec.length;\n            buf = new Uint8Array(2 + len);\n            buf[0] = 0x1c;\n            buf[1] = len;\n            buf.set(new Uint8Array(dec), 2);\n            return buf;\n        } else if (v.type === 'lightfunc') {\n            dec = Duktape.dec('hex', v.pointer);\n            len = dec.length;\n            buf = new Uint8Array(4 + len);\n            buf[0] = 0x1d;\n            buf[1] = (v.flags >> 8) & 0xff;\n            buf[2] = v.flags & 0xff;\n            buf[3] = len;\n            buf.set(new Uint8Array(dec), 4);\n            return buf;\n        } else if (v.type === 'heapptr') {\n            dec = Duktape.dec('hex', v.pointer);\n            len = dec.length;\n            buf = new Uint8Array(2 + len);\n            buf[0] = 0x1e;\n            buf[1] = len;\n            buf.set(new Uint8Array(dec), 2);\n            return buf;\n        }\n    } else if (v === null) {\n        return new Uint8Array([ 0x17 ]);\n    } else if (typeof v === 'boolean') {\n        return new Uint8Array([ v ? 0x18 : 0x19 ]);\n    } else if (typeof v === 'number') {\n        if (Math.floor(v) === v &&     /* whole */\n            (v !== 0 || 1 / v > 0) &&  /* not negative zero */\n            v >= -0x80000000 && v <= 0x7fffffff) {\n            // Represented signed 32-bit integers as plain integers.\n            // Debugger code expects this for all fields that are not\n            // duk_tval representations (e.g. command numbers and such).\n            if (v >= 0x00 && v <= 0x3f) {\n                return new Uint8Array([ 0x80 + v ]);\n            } else if (v >= 0x0000 && v <= 0x3fff) {\n                return new Uint8Array([ 0xc0 + (v >> 8), v & 0xff ]);\n            } else if (v >= -0x80000000 && v <= 0x7fffffff) {\n                return new Uint8Array([ 0x10,\n                                    (v >> 24) & 0xff,\n                                    (v >> 16) & 0xff,\n                                    (v >> 8) & 0xff,\n                                    (v >> 0) & 0xff ]);\n            } else {\n                throw new Error('internal error when encoding integer to dvalue: ' + v);\n            }\n        } else {\n            // Represent non-integers as IEEE double dvalues.\n            buf = new Uint8Array(1 + 8);\n            buf[0] = 0x1a;\n            new DataView(buf).setFloat64(1, v, false);\n            return buf;\n        }\n    } else if (typeof v === 'string') {\n        if (v.length < 0 || v.length > 0xffffffff) {\n            // Not possible in practice.\n            throw new TypeError('cannot convert to dvalue, invalid string length: ' + v.length);\n        }\n        if (v.length <= 0x1f) {\n            buf = new Uint8Array(1 + v.length);\n            buf[0] = 0x60 + v.length;\n            this.writeDebugStringToBuffer(v, buf, 1);\n            return buf;\n        } else if (v.length <= 0xffff) {\n            buf = new Uint8Array(3 + v.length);\n            buf[0] = 0x12;\n            buf[1] = (v.length >> 8) & 0xff;\n            buf[2] = (v.length >> 0) & 0xff;\n            this.writeDebugStringToBuffer(v, buf, 3);\n            return buf;\n        } else {\n            buf = new Uint8Array(5 + v.length);\n            buf[0] = 0x11;\n            buf[1] = (v.length >> 24) & 0xff;\n            buf[2] = (v.length >> 16) & 0xff;\n            buf[3] = (v.length >> 8) & 0xff;\n            buf[4] = (v.length >> 0) & 0xff;\n            this.writeDebugStringToBuffer(v, buf, 5);\n            return buf;\n        }\n    }\n\n    throw new TypeError('value cannot be converted to dvalue: ' + jxEncode(v));\n};\n\n/*\n *  Target binary connection handler\n */\n\nfunction TargetConnHandler(server) {\n    this.name = 'TargetConnHandler';\n    this.server = server;\n    this.handle = uv.new_tcp();\n    this.jsonHandler = null;\n    this.incoming = new Uint8Array(4096);\n    this.incomingOffset = 0;\n    this.dvalues = [];\n}\n\nTargetConnHandler.prototype.finish = function finish(msg) {\n    if (!this.handle) {\n        log.info('TargetConnHandler already disconnected, ignore finish()');\n        return;\n    }\n    log.info('TargetConnHandler finished:', msg);\n\n    this.jsonHandler.writeJson({ notify: '_TargetDisconnected' });\n\n    // XXX: write a notify to target?\n\n    uv.shutdown(this.handle);\n    uv.read_stop(this.handle);\n    uv.close(this.handle);\n    this.handle = null;\n\n    this.jsonHandler.finish(msg);  // disconnect JSON client too (if not already disconnected)\n};\n\nTargetConnHandler.prototype.onConnect = function onConnect(err) {\n    var errmsg;\n\n    if (err) {\n        errmsg = 'Failed to connect to target: ' + err;\n        log.warn(errmsg);\n        this.jsonHandler.writeJson({ notify: '_Error', args: [ String(err) ] });\n        this.finish(errmsg);\n        return;\n    }\n\n    // Once we're connected to the target, start read both binary and JSON\n    // input.  We don't want to read JSON input before this so that we can\n    // always translate incoming messages to dvalues and write them out\n    // without queueing.  Any pending JSON messages will be queued by the\n    // OS instead.\n\n    log.info('Connected to debug target at', targetHost + ':' + targetPort);\n    uv.read_start(this.jsonHandler.handle, this.jsonHandler.onRead.bind(this.jsonHandler));\n    uv.read_start(this.handle, this.onRead.bind(this));\n};\n\nTargetConnHandler.prototype.writeBinary = function writeBinary(buf) {\n    var plain = plainBufferCopy(buf);\n    log.info('PROXY --> TARGET:', Duktape.enc('jx', plain));\n    if (this.handle) {\n        uv.write(this.handle, plain);\n    }\n};\n\nTargetConnHandler.prototype.onRead = function onRead(err, data) {\n    var res;\n    var errmsg;\n    var tmpBuf;\n    var newIncoming;\n\n    log.trace('Received data from target socket, err:', err, 'data length:', data ? data.length : 'null');\n\n    if (err) {\n        errmsg = 'Error reading data from debug target: ' + err;\n        this.finish(errmsg);\n        return;\n    }\n\n    if (data) {\n        // Feed the data one byte at a time when torture testing.\n        if (TORTURE && data.length > 1) {\n            for (var i = 0; i < data.length; i++) {\n                tmpBuf = allocPlain(1);\n                tmpBuf[0] = data[i];\n                this.onRead(null, tmpBuf);\n            }\n            return;\n        }\n\n        // Receive data into 'incoming', resizing as necessary.\n        while (data.length > this.incoming.length - this.incomingOffset) {\n            newIncoming = new Uint8Array(this.incoming.length * 1.3 + 16);\n            newIncoming.set(this.incoming);\n            this.incoming = newIncoming;\n            log.debug('Resize incoming binary buffer to ' + this.incoming.length);\n        }\n        this.incoming.set(new Uint8Array(data), this.incomingOffset);\n        this.incomingOffset += data.length;\n\n        // Trial parse handshake unless done.\n        if (!this.handshake) {\n            this.trialParseHandshake();\n        }\n\n        // Trial parse dvalue(s) and debug messages.\n        if (this.handshake) {\n            for (;;) {\n                res = this.trialParseDvalue();\n                if (!res) {\n                    break;\n                }\n                log.trace('Got dvalue:', Duktape.enc('jx', res.dvalue));\n                this.dvalues.push(res.dvalue);\n                if (isObject(res.dvalue) && res.dvalue.type === 'eom') {\n                    try {\n                        this.jsonHandler.handleDebugMessage(this.dvalues);\n                        this.dvalues = [];\n                    } catch (e) {\n                        errmsg = 'JSON message handling failed: ' + e;\n                        this.jsonHandler.writeJson({ notify: '_Error', args: [ errmsg ] });\n                        if (lenientJsonParse) {\n                            log.warn('JSON message handling failed (lenient mode, ignoring):', e);\n                        } else {\n                            log.warn('JSON message handling failed (dropping connection):', e);\n                            this.finish(errmsg);\n                        }\n                    }\n                }\n            }\n        }\n    } else {\n        log.info('Target disconnected');\n        this.finish('Target disconnected');\n    }\n};\n\nTargetConnHandler.prototype.trialParseHandshake = function trialParseHandshake() {\n    var buf = this.incoming;\n    var avail = this.incomingOffset;\n    var i;\n    var msg;\n    var m;\n    var protocolVersion;\n\n    for (i = 0; i < avail; i++) {\n        if (buf[i] == 0x0a) {\n            msg = bufferToString(plainBufferCopy(buf.subarray(0, i)));\n            this.incoming.set(this.incoming.subarray(i + 1));\n            this.incomingOffset -= i + 1;\n\n            // Generic handshake format: only relies on initial version field.\n            m = /^(\\d+) (.*)$/.exec(msg) || {};\n            protocolVersion = +m[1];\n            this.handshake = {\n                line: msg,\n                protocolVersion: protocolVersion,\n                text: m[2]\n            };\n\n            // More detailed v1 handshake line.\n            if (protocolVersion === 1) {\n                m = /^(\\d+) (\\d+) (.*?) (.*?) (.*)$/.exec(msg) || {};\n                this.handshake.dukVersion = m[1];\n                this.handshake.dukGitDescribe = m[2];\n                this.handshake.targetString = m[3];\n            }\n\n            this.jsonHandler.writeJson({ notify: '_TargetConnected', args: [ msg ] });\n\n            log.info('Target handshake: ' + JSON.stringify(this.handshake));\n            return;\n        }\n    }\n};\n\nTargetConnHandler.prototype.bufferToDebugString = function bufferToDebugString(buf) {\n    return String.fromCharCode.apply(null, buf);\n};\n\nTargetConnHandler.prototype.trialParseDvalue = function trialParseDvalue() {\n    var _this = this;\n    var buf = this.incoming;\n    var avail = this.incomingOffset;\n    var v;\n    var gotValue = false;  // explicit flag for e.g. v === undefined\n    var dv = new DataView(buf);\n    var tmp;\n    var x;\n    var len;\n\n    function consume(n) {\n        log.info('PROXY <-- TARGET:', Duktape.enc('jx', _this.incoming.subarray(0, n)));\n        _this.incoming.set(_this.incoming.subarray(n));\n        _this.incomingOffset -= n;\n    }\n\n    x = buf[0];\n    if (avail <= 0) {\n        ;\n    } else if (x >= 0xc0) {\n        // 0xc0...0xff: integers 0-16383\n        if (avail >= 2) {\n            v = ((x - 0xc0) << 8) + buf[1];\n            consume(2);\n        }\n    } else if (x >= 0x80) {\n        // 0x80...0xbf: integers 0-63\n        v = x - 0x80;\n        consume(1);\n    } else if (x >= 0x60) {\n        // 0x60...0x7f: strings with length 0-31\n        len = x - 0x60;\n        if (avail >= 1 + len) {\n            v = new Uint8Array(len);\n            v.set(buf.subarray(1, 1 + len));\n            v = this.bufferToDebugString(v);\n            consume(1 + len);\n        }\n    } else {\n        switch (x) {\n        case 0x00: consume(1); v = { type: 'eom' }; break;\n        case 0x01: consume(1); v = { type: 'req' }; break;\n        case 0x02: consume(1); v = { type: 'rep' }; break;\n        case 0x03: consume(1); v = { type: 'err' }; break;\n        case 0x04: consume(1); v = { type: 'nfy' }; break;\n        case 0x10:  // 4-byte signed integer\n            if (avail >= 5) {\n                v = dv.getInt32(1, false);\n                consume(5);\n            }\n            break;\n        case 0x11:  // 4-byte string\n            if (avail >= 5) {\n                len = dv.getUint32(1, false);\n                if (avail >= 5 + len) {\n                    v = new Uint8Array(len);\n                    v.set(buf.subarray(5, 5 + len));\n                    v = this.bufferToDebugString(v);\n                    consume(5 + len);\n                }\n            }\n            break;\n        case 0x12:  // 2-byte string\n            if (avail >= 3) {\n                len = dv.getUint16(1, false);\n                if (avail >= 3 + len) {\n                    v = new Uint8Array(len);\n                    v.set(buf.subarray(3, 3 + len));\n                    v = this.bufferToDebugString(v);\n                    consume(3 + len);\n                }\n            }\n            break;\n        case 0x13:  // 4-byte buffer\n            if (avail >= 5) {\n                len = dv.getUint32(1, false);\n                if (avail >= 5 + len) {\n                    v = new Uint8Array(len);\n                    v.set(buf.subarray(5, 5 + len));\n                    v = { type: 'buffer', data: Duktape.enc('hex', plainOf(v)) };\n                    consume(5 + len);\n                }\n            }\n            break;\n        case 0x14:  // 2-byte buffer\n            if (avail >= 3) {\n                len = dv.getUint16(1, false);\n                if (avail >= 3 + len) {\n                    v = new Uint8Array(len);\n                    v.set(buf.subarray(3, 3 + len));\n                    v = { type: 'buffer', data: Duktape.enc('hex', plainOf(v)) };\n                    consume(3 + len);\n                }\n            }\n            break;\n        case 0x15:  // unused/none\n            v = { type: 'unused' };\n            consume(1);\n            break;\n        case 0x16:  // undefined\n            v = { type: 'undefined' };\n            gotValue = true;  // indicate 'v' is actually set\n            consume(1);\n            break;\n        case 0x17:  // null\n            v = null;\n            gotValue = true;  // indicate 'v' is actually set\n            consume(1);\n            break;\n        case 0x18:  // true\n            v = true;\n            consume(1);\n            break;\n        case 0x19:  // false\n            v = false;\n            consume(1);\n            break;\n        case 0x1a:  // number (IEEE double), big endian\n            if (avail >= 9) {\n                tmp = new Uint8Array(8);\n                tmp.set(buf.subarray(1, 9));\n                v = { type: 'number', data: Duktape.enc('hex', plainOf(tmp)) };\n                if (readableNumberValue) {\n                    // The value key should not be used programmatically,\n                    // it is just there to make the dumps more readable.\n                    v.value = new DataView(tmp.buffer).getFloat64(0, false);\n                }\n                consume(9);\n            }\n            break;\n        case 0x1b:  // object\n            if (avail >= 3) {\n                len = buf[2];\n                if (avail >= 3 + len) {\n                    v = new Uint8Array(len);\n                    v.set(buf.subarray(3, 3 + len));\n                    v = { type: 'object', 'class': buf[1], pointer: Duktape.enc('hex', plainOf(v)) };\n                    consume(3 + len);\n                }\n            }\n            break;\n        case 0x1c:  // pointer\n            if (avail >= 2) {\n                len = buf[1];\n                if (avail >= 2 + len) {\n                    v = new Uint8Array(len);\n                    v.set(buf.subarray(2, 2 + len));\n                    v = { type: 'pointer', pointer: Duktape.enc('hex', plainOf(v)) };\n                    consume(2 + len);\n                }\n            }\n            break;\n        case 0x1d:  // lightfunc\n            if (avail >= 4) {\n                len = buf[3];\n                if (avail >= 4 + len) {\n                    v = new Uint8Array(len);\n                    v.set(buf.subarray(4, 4 + len));\n                    v = { type: 'lightfunc', flags: dv.getUint16(1, false), pointer: Duktape.enc('hex', plainOf(v)) };\n                    consume(4 + len);\n                }\n            }\n            break;\n        case 0x1e:  // heapptr\n            if (avail >= 2) {\n                len = buf[1];\n                if (avail >= 2 + len) {\n                    v = new Uint8Array(len);\n                    v.set(buf.subarray(2, 2 + len));\n                    v = { type: 'heapptr', pointer: Duktape.enc('hex', plainOf(v)) };\n                    consume(2 + len);\n                }\n            }\n            break;\n        default:\n            throw new Error('failed parse initial byte: ' + buf[0]);\n        }\n    }\n\n    if (typeof v !== 'undefined' || gotValue) {\n        return { dvalue: v };\n    }\n};\n\n/*\n *  Main\n */\n\nfunction main() {\n    var argv = typeof uv.argv === 'function' ? uv.argv() : [];\n    var i;\n    for (i = 2; i < argv.length; i++) {  // skip dukluv and script name\n        if (argv[i] == '--help') {\n            print('Usage: dukluv ' + argv[1] + ' [option]+');\n            print('');\n            print('    --server-host HOST    JSON proxy server listen address');\n            print('    --server-port PORT    JSON proxy server listen port');\n            print('    --target-host HOST    Debug target address');\n            print('    --target-port PORT    Debug target port');\n            print('    --metadata FILE       Proxy metadata file (usually named duk_debug_meta.json)');\n            print('    --log-level LEVEL     Set log level, default is 2; 0=trace, 1=debug, 2=info, 3=warn, etc');\n            print('    --single              Run a single proxy connection and exit (default: persist for multiple connections)');\n            print('    --readable-numbers    Add a non-programmatic \"value\" key for IEEE doubles help readability');\n            print('    --lenient             Ignore (with warning) invalid JSON without dropping connection');\n            print('    --jx-parse            Parse JSON proxy input with JX, useful when testing manually');\n            print('');\n            return;  // don't register any sockets/timers etc to exit\n        } else if (argv[i] == '--single') {\n            singleConnection = true;\n            continue;\n        } else if (argv[i] == '--readable-numbers') {\n            readableNumberValue = true;\n            continue;\n        } else if (argv[i] == '--lenient') {\n            lenientJsonParse = true;\n            continue;\n        } else if (argv[i] == '--jx-parse') {\n            jxParse = true;\n            continue;\n        }\n        if (i >= argv.length - 1) {\n            throw new Error('missing option value for ' + argv[i]);\n        }\n        if (argv[i] == '--server-host') {\n            serverHost = argv[i + 1];\n            i++;\n        } else if (argv[i] == '--server-port') {\n            serverPort = Math.floor(+argv[i + 1]);\n            i++;\n        } else if (argv[i] == '--target-host') {\n            targetHost = argv[i + 1];\n            i++;\n        } else if (argv[i] == '--target-port') {\n            targetPort = Math.floor(+argv[i + 1]);\n            i++;\n        } else if (argv[i] == '--metadata') {\n            metadataFile = argv[i + 1];\n            i++;\n        } else if (argv[i] == '--log-level') {\n            log.l = Math.floor(+argv[i + 1]);\n            i++;\n        } else {\n            throw new Error('invalid option ' + argv[i]);\n        }\n    }\n\n    function runServer() {\n        var serverSocket = new JsonProxyServer(serverHost, serverPort);\n        var connMode = singleConnection ? 'single connection mode' : 'persistent connection mode';\n        log.info('Listening for incoming JSON debug connection on ' + serverHost + ':' + serverPort +\n                 ', target is ' + targetHost + ':' + targetPort + ', ' + connMode);\n    }\n\n    if (metadataFile) {\n        log.info('Read proxy metadata from', metadataFile);\n        readFully(metadataFile, function (data, err) {\n            if (err) {\n                log.error('Failed to load metadata:', err);\n                throw err;\n            }\n            try {\n                metadata = JSON.parse(bufferToString(data));\n            } catch (e) {\n                log.error('Failed to parse JSON metadata from ' + metadataFile + ': ' + e);\n                throw e;\n            }\n            runServer();\n        });\n    } else {\n        runServer();\n    }\n}\n\nmain();\n"
  },
  {
    "path": "react_juce/duktape/debugger/duk_debugcommands.yaml",
    "content": "# Debug request/notify command names provided by the debug client.\n# These are concretely notify names now.\nclient_commands:\n  - Reserved_0\n  - Status\n  - Reserved_2  # Duktape 1.x: print notify\n  - Reserved_3  # Duktape 1.x: alert notify\n  - Reserved_4  # Duktape 1.x: log notify\n  - Throw\n  - Detaching\n  - AppNotify\n\n# Debug request/notify command names provided by the debug target (Duktape).\ntarget_commands:\n  - Reserved_0\n  - Reserved_1\n  - Reserved_2\n  - Reserved_3\n  - Reserved_4\n  - Reserved_5\n  - Reserved_6\n  - Reserved_7\n  - Reserved_8\n  - Reserved_9\n  - Reserved_10\n  - Reserved_11\n  - Reserved_12\n  - Reserved_13\n  - Reserved_14\n  - Reserved_15\n  - BasicInfo\n  - TriggerStatus\n  - Pause\n  - Resume\n  - StepInto\n  - StepOver\n  - StepOut\n  - ListBreak\n  - AddBreak\n  - DelBreak\n  - GetVar\n  - PutVar\n  - GetCallStack\n  - GetLocals\n  - Eval\n  - Detach\n  - DumpHeap\n  - GetBytecode\n  - AppRequest\n  - GetHeapObjInfo\n  - GetObjPropDesc\n  - GetObjPropDescRange\n"
  },
  {
    "path": "react_juce/duktape/debugger/duk_debugerrors.yaml",
    "content": "error_codes:\n  - Unknown\n  - UnsupportedCommand\n  - TooMany\n  - NotFound\n  - ApplicationError\n"
  },
  {
    "path": "react_juce/duktape/debugger/duk_opcodes.yaml",
    "content": "# Duktape opcode metadata for debugger.\n# - See duk_debug.js for the argument formats (A_R etc).\n# - Flag bits are for the whole instruction as a 32-bit integer,\n#   they are not field shifted\n#\n# NOTE: Use YAML comments only on comment-only lines (not trailing content):\n# Node.js 'yamljs' seems to refuse parsing trailing comments in some cases.\n\nopcodes:\n  - name: LDREG\n    args:\n      - A_R\n      - BC_R\n  - name: STREG\n    args:\n      - A_R\n      - BC_R\n  - name: JUMP\n    args:\n      - ABC_JUMP\n  - name: LDCONST\n    args:\n      - A_R\n      - BC_C\n  - name: LDINT\n    args:\n      - A_R\n      - BC_LDINT\n  - name: LDINTX\n    args:\n      - A_R\n      - BC_LDINTX\n  - name: LDTHIS\n    args:\n      - BC_R\n  - name: LDUNDEF\n    args:\n      - BC_R\n  - name: LDNULL\n    args:\n      - BC_R\n  - name: LDTRUE\n    args:\n      - BC_R\n  - name: LDFALSE\n    args:\n      - BC_R\n  - name: GETVAR\n    args:\n      - A_R\n      - BC_C\n  - name: BNOT\n    args:\n      - A_R\n      - BC_R\n  - name: LNOT\n    args:\n      - A_R\n      - BC_R\n  - name: UNM\n    args:\n      - A_R\n      - BC_R\n  - name: UNP\n    args:\n      - A_R\n      - BC_R\n  - name: EQ_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: EQ_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: EQ_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: EQ_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: NEQ_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: NEQ_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: NEQ_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: NEQ_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: SEQ_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: SEQ_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: SEQ_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: SEQ_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: SNEQ_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: SNEQ_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: SNEQ_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: SNEQ_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: GT_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: GT_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: GT_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: GT_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: GE_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: GE_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: GE_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: GE_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: LT_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: LT_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: LT_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: LT_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: LE_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: LE_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: LE_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: LE_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: IFTRUE_R\n    args:\n      - BC_R\n  - name: IFTRUE_C\n    args:\n      - BC_C\n  - name: IFFALSE_R\n    args:\n      - BC_R\n  - name: IFFALSE_C\n    args:\n      - BC_C\n  - name: ADD_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: ADD_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: ADD_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: ADD_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: SUB_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: SUB_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: SUB_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: SUB_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: MUL_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: MUL_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: MUL_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: MUL_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: DIV_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: DIV_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: DIV_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: DIV_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: MOD_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: MOD_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: MOD_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: MOD_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: EXP_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: EXP_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: EXP_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: EXP_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: BAND_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: BAND_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: BAND_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: BAND_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: BOR_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: BOR_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: BOR_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: BOR_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: BXOR_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: BXOR_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: BXOR_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: BXOR_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: BASL_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: BASL_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: BASL_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: BASL_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: BLSR_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: BLSR_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: BLSR_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: BLSR_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: BASR_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: BASR_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: BASR_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: BASR_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: INSTOF_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: INSTOF_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: INSTOF_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: INSTOF_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: IN_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: IN_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: IN_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: IN_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: GETPROP_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: GETPROP_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: GETPROP_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: GETPROP_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: PUTPROP_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: PUTPROP_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: PUTPROP_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: PUTPROP_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: DELPROP_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: DELPROP_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: DELPROP_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: DELPROP_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: PREINCR\n    args:\n      - A_R\n      - BC_R\n  - name: PREDECR\n    args:\n      - A_R\n      - BC_R\n  - name: POSTINCR\n    args:\n      - A_R\n      - BC_R\n  - name: POSTDECR\n    args:\n      - A_R\n      - BC_R\n  - name: PREINCV\n    args:\n      - A_R\n      - BC_C\n  - name: PREDECV\n    args:\n      - A_R\n      - BC_C\n  - name: POSTINCV\n    args:\n      - A_R\n      - BC_C\n  - name: POSTDECV\n    args:\n      - A_R\n      - BC_C\n  - name: PREINCP_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: PREINCP_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: PREINCP_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: PREINCP_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: PREDECP_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: PREDECP_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: PREDECP_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: PREDECP_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: POSTINCP_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: POSTINCP_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: POSTINCP_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: POSTINCP_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: POSTDECP_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: POSTDECP_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: POSTDECP_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: POSTDECP_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: DECLVAR_RR\n    args:\n      - A_H\n      - B_R\n      - C_R\n    flags:\n      - mask: 0x100\n        name: writable\n      - mask: 0x200\n        name: enumerable\n      - mask: 0x400\n        name: configurable\n      - mask: 0x800\n        name: accessor\n      - mask: 0x1000\n        name: func_decl\n  - name: DECLVAR_CR\n    args:\n      - A_H\n      - B_C\n      - C_R\n    flags:\n      - mask: 0x100\n        name: writable\n      - mask: 0x200\n        name: enumerable\n      - mask: 0x400\n        name: configurable\n      - mask: 0x800\n        name: accessor\n      - mask: 0x1000\n        name: func_decl\n  - name: DECLVAR_RC\n    args:\n      - A_H\n      - B_R\n      - C_C\n    flags:\n      - mask: 0x100\n        name: writable\n      - mask: 0x200\n        name: enumerable\n      - mask: 0x400\n        name: configurable\n      - mask: 0x800\n        name: accessor\n      - mask: 0x1000\n        name: func_decl\n  - name: DECLVAR_CC\n    args:\n      - A_H\n      - B_C\n      - C_C\n    flags:\n      - mask: 0x100\n        name: writable\n      - mask: 0x200\n        name: enumerable\n      - mask: 0x400\n        name: configurable\n      - mask: 0x800\n        name: accessor\n      - mask: 0x1000\n        name: func_decl\n  - name: REGEXP_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: REGEXP_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: REGEXP_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: REGEXP_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: CLOSURE\n    args:\n      - A_R\n      - BC_I\n  - name: TYPEOF\n    args:\n      - A_R\n      - BC_R\n  - name: TYPEOFID\n    args:\n      - A_R\n      - BC_C\n  - name: PUTVAR\n    args:\n      - A_R\n      - BC_C\n  - name: DELVAR\n    args:\n      - A_R\n      - BC_C\n  - name: RETREG\n    args:\n      - BC_R\n  - name: RETUNDEF\n  - name: RETCONST\n    args:\n      - BC_C\n  - name: RETCONSTN\n    args:\n      - BC_C\n  - name: LABEL\n    args:\n      - BC_I\n  - name: ENDLABEL\n    args:\n      - BC_I\n  - name: BREAK\n    args:\n      - BC_I\n  - name: CONTINUE\n    args:\n      - BC_I\n  - name: TRYCATCH\n    args:\n      - A_H\n      # base register for two consecutive regs (base_reg + 0, base_reg + 1) used for two things:\n      # - input: either 'with' target register or catch varname constant (base_reg + 0), depending on flags\n      # - output: when caught, catch value (base_reg + 0) and type (base_reg + 1)\n      - BC_R\n    flags:\n      - mask: 0x40\n        name: have_catch\n      - mask: 0x80\n        name: have_finally\n      - mask: 0x100\n        name: catch_binding\n      - mask: 0x200\n        name: with_binding\n  - name: ENDTRY\n  - name: ENDCATCH\n  - name: ENDFIN\n    args:\n      - ABC_R\n  - name: THROW\n    args:\n      - BC_R\n  - name: INVLHS\n  - name: CSREG\n    args:\n      - A_R\n      - BC_R\n  - name: CSVAR_RR\n    args:\n      - A_R\n      - B_R\n  - name: CSVAR_CR\n    args:\n      - A_R\n      - B_C\n  - name: CSVAR_RC\n    args:\n      - A_R\n      - B_R\n  - name: CSVAR_CC\n    args:\n      - A_R\n      - B_C\n  - name: CALL0\n    args:\n      - A_I\n      - BC_R\n  - name: CALL1\n    args:\n      - A_I\n      - BC_R\n  - name: CALL2\n    args:\n      - A_I\n      - BC_R\n  - name: CALL3\n    args:\n      - A_I\n      - BC_R\n  - name: CALL4\n    args:\n      - A_I\n      - BC_R\n  - name: CALL5\n    args:\n      - A_I\n      - BC_R\n  - name: CALL6\n    args:\n      - A_I\n      - BC_R\n  - name: CALL7\n    args:\n      - A_I\n      - BC_R\n  - name: CALL8\n    args:\n      - A_I\n      - BC_R\n  - name: CALL9\n    args:\n      - A_I\n      - BC_R\n  - name: CALL10\n    args:\n      - A_I\n      - BC_R\n  - name: CALL11\n    args:\n      - A_I\n      - BC_R\n  - name: CALL12\n    args:\n      - A_I\n      - BC_R\n  - name: CALL13\n    args:\n      - A_I\n      - BC_R\n  - name: CALL14\n    args:\n      - A_I\n      - BC_R\n  - name: CALL15\n    args:\n      - A_I\n      - BC_R\n  - name: NEWOBJ\n    args:\n      - A_I  # property count init size\n      - BC_R\n  - name: NEWARR\n    args:\n      - A_I  # array item count init size\n      - BC_R\n  - name: MPUTOBJ\n    args:\n      - A_R\n      - B_R\n      - C_I\n  - name: MPUTOBJI\n    args:\n      - A_R\n      - B_RI\n      - C_I\n  - name: INITSET\n    args:\n      - A_R\n      - BC_R\n  - name: INITGET\n    args:\n      - A_R\n      - BC_R\n  - name: MPUTARR\n    args:\n      - A_R\n      - B_R\n      - C_I\n  - name: MPUTARRI\n    args:\n      - A_R\n      - B_RI\n      - C_I\n  - name: SETALEN\n    args:\n      - B_R\n      - C_R\n  - name: INITENUM\n    args:\n      - B_R\n      - C_R\n  - name: NEXTENUM\n    args:\n      - B_R\n      - C_R\n  - name: NEWTARGET\n    args:\n      - BC_R\n  - name: DEBUGGER\n  - name: NOP\n    args:\n      - ABC_I\n  - name: INVALID\n    args:\n      - ABC_I\n  - name: UNUSED207\n  - name: GETPROPC_RR\n    args:\n      - A_R\n      - B_R\n      - C_R\n  - name: GETPROPC_CR\n    args:\n      - A_R\n      - B_C\n      - C_R\n  - name: GETPROPC_RC\n    args:\n      - A_R\n      - B_R\n      - C_C\n  - name: GETPROPC_CC\n    args:\n      - A_R\n      - B_C\n      - C_C\n  - name: UNUSED212\n  - name: UNUSED213\n  - name: UNUSED214\n  - name: UNUSED215\n  - name: UNUSED216\n  - name: UNUSED217\n  - name: UNUSED218\n  - name: UNUSED219\n  - name: UNUSED220\n  - name: UNUSED221\n  - name: UNUSED222\n  - name: UNUSED223\n  - name: UNUSED224\n  - name: UNUSED225\n  - name: UNUSED226\n  - name: UNUSED227\n  - name: UNUSED228\n  - name: UNUSED229\n  - name: UNUSED230\n  - name: UNUSED231\n  - name: UNUSED232\n  - name: UNUSED233\n  - name: UNUSED234\n  - name: UNUSED235\n  - name: UNUSED236\n  - name: UNUSED237\n  - name: UNUSED238\n  - name: UNUSED239\n  - name: UNUSED240\n  - name: UNUSED241\n  - name: UNUSED242\n  - name: UNUSED243\n  - name: UNUSED244\n  - name: UNUSED245\n  - name: UNUSED246\n  - name: UNUSED247\n  - name: UNUSED248\n  - name: UNUSED249\n  - name: UNUSED250\n  - name: UNUSED251\n  - name: UNUSED252\n  - name: UNUSED253\n  - name: UNUSED254\n  - name: UNUSED255\n"
  },
  {
    "path": "react_juce/duktape/debugger/package.json",
    "content": "{\n  \"name\": \"duk-debug\",\n  \"version\": \"0.1.0\",\n  \"description\": \"Duktape debugger\",\n  \"author\": {\n    \"name\": \"Sami Vaarala\",\n    \"email\": \"sami.vaarala@iki.fi\"\n  },\n  \"dependencies\": {\n    \"bluebird\": \"~2.6.4\",\n    \"body-parser\": \"~1.9.3\",\n    \"byline\": \"~4.2.1\",\n    \"events\": \"~1.0.2\",\n    \"express\": \"~4.10.1\",\n    \"http\": \"0.0.0\",\n    \"minimist\": \"~1.1.0\",\n    \"readline\": \"0.0.5\",\n    \"recursive-readdir-sync\": \"^1.0.6\",\n    \"socket.io\": \"~1.2.1\",\n    \"sprintf\": \"~0.1.5\",\n    \"stream\": \"0.0.2\",\n    \"utf8\": \"~2.0.0\",\n    \"util\": \"~0.10.3\",\n    \"yamljs\": \"~0.2.1\"\n  },\n  \"main\": \"duk_debug.js\"\n}\n"
  },
  {
    "path": "react_juce/duktape/debugger/static/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"utf-8\" />\n<link rel=\"stylesheet\" href=\"reset.css\" type=\"text/css\" />\n<link rel=\"stylesheet\" href=\"jquery-ui.min.css\" type=\"text/css\" />\n<link rel=\"stylesheet\" href=\"style.css\" type=\"text/css\" />\n<title>Duktape debugger</title>\n</head>\n<body>\n\n<div id=\"part-header\">\n((o) Duktape debugger\n</div>  <!-- #part-header -->\n\n<div id=\"part-middle\">\n\n<div id=\"left-area\">\n<a class=\"button\" href=\"#\" id=\"stepinto-button\">Step&#x00a0;into</a>\n<a class=\"button\" href=\"#\" id=\"stepover-button\">Step&#x00a0;over</a>\n<a class=\"button\" href=\"#\" id=\"stepout-button\">Step&#x00a0;out</a>\n<a class=\"button\" href=\"#\" id=\"resume-button\">Resume</a>\n<a class=\"button\" href=\"#\" id=\"pause-button\">Pause</a>\n<br />\n<br />\n<br />\n<br />\n<a class=\"button\" href=\"#\" id=\"attach-button\">Attach</a>\n<a class=\"button\" href=\"#\" id=\"detach-button\">Detach</a>\n<a class=\"button\" href=\"#\" id=\"about-button\">About</a>\n<a class=\"button\" id=\"heap-dump-download-button\" href=\"/heapDump.json\" target=\"_blank\">Dump&#x00a0;heap</a>\n<a class=\"button\" href=\"#\" id=\"show-bytecode-button\">Show bytecode</a>\n</div>  <!-- #left-area -->\n\n<div id=\"center-area\">\n<pre id=\"source-pre\" class=\"sourcecode\"><code id=\"source-code\" class=\"sourcecode\">\n// No source loaded\n</code></pre>\n<div>\n<select id=\"source-select\"></select><br />\n<!-- <span id=\"source-filename\">?</span> -->\n</div>\n<div id=\"exec-status\">\n<div id=\"exec-state\"><span id=\"current-state\">?</span></div>\n<div id=\"exec-other\"><span id=\"current-fileline\">?</span><br /><span id=\"current-funcpc\">?</span></div>\n</div>  <!-- #exec-status -->\n<div id=\"output\">\n<div style=\"color: #dddddd\">(output from script, print() and alert() calls)</div>\n</div>\n</div>  <!-- #center-area -->\n\n<div id=\"right-area\">\n<div id=\"callstack\">\n<div style=\"color: #dddddd\">(callstack)</div>\n</div>\n<div id=\"locals\">\n<div style=\"color: #dddddd\">(locals)</div>\n</div>\n<div id=\"breakpoints\">\n<div style=\"color: #dddddd\">(breakpoints)</div>\n</div>\n<div id=\"eval\">\n<input id=\"eval-input\" value=\"print('hello world'); 1+2\" /><button id=\"eval-button\">Eval</button><input id=\"eval-watch\" type=\"checkbox\" />&#xa0;watch (eval on pause)\n<div id=\"eval-output\"></div>\n<button id=\"putvar-button\">PutVar</button><button id=\"getvar-button\">GetVar</button><input id=\"varname-input\" value=\"varname\" /><input id=\"varvalue-input\" value=\"varvalue\" />\n<div id=\"var-output\"></div>\n</div>\n</div>  <!-- #right-area -->\n\n</div>  <!-- #part-middle -->\n\n<div id=\"part-footer\">\n<div>DUK_VERSION: <span id=\"duk-version\">?</span>, DUK_GIT_DESCRIBE: <span id=\"duk-git-describe\">?</span>, Target info: <span id=\"target-info\">?</span>, Endianness: <span id=\"endianness\">?</span><br />\nDebug protocol stats:\nrecv <span id=\"debug-rx-bytes\">?</span> (<span id=\"debug-rx-kbrate\">?</span> kB/s), <span id=\"debug-rx-dvalues\">?</span> dvalues, <span id=\"debug-rx-messages\">?</span> messages;\nsend <span id=\"debug-tx-bytes\">?</span> (<span id=\"debug-tx-kbrate\">?</span> kB/s), <span id=\"debug-tx-dvalues\">?</span> dvalues, <span id=\"debug-tx-messages\">?</span> messages\n</div>\n</div>  <!-- #part-footer -->\n\n<div id=\"about-dialog\" title=\"About Duktape debugger\">\n<p>Duktape debugger is a web UI for debugging ECMAScript on a target device.</p>\n<p>This web UI talks to a NodeJS debug server using <a href=\"http://socket.io/\" target=\"_blank\">socket.io</a>.\nThe debug server talks to the target device using the Duktape debug protocol\n(see <a href=\"https://github.com/svaarala/duktape/blob/master/doc/debugger.rst\" target=\"_blank\">debugger.rst</a>).</p>\n</div>  <!-- #about-dialog -->\n\n<div id=\"bytecode-dialog\" title=\"Bytecode for current function\">\n<pre id=\"bytecode-preformatted\"></pre>\n</div>\n\n<script src=\"jquery-1.11.1.min.js\" type=\"text/javascript\"></script>\n<script src=\"jquery-ui.min.js\" type=\"text/javascript\"></script>\n<script src=\"socket.io-1.2.0.js\" type=\"text/javascript\"></script>\n<script src=\"webui.js\" type=\"text/javascript\"></script>\n</body>\n</html>\n"
  },
  {
    "path": "react_juce/duktape/debugger/static/style.css",
    "content": "// http://stackoverflow.com/questions/71074/how-to-remove-firefoxs-dotted-outline-on-buttons-as-well-as-links/3844452#3844452\n:focus {\n\toutline: none;\n}\n::-moz-focus-inner {\n\tborder: 0;\n}\n\n@keyframes pulsate {\n\tfrom { opacity: 1; }\n\tto { opacity: 0.25; }\n}\n\n#part-header {\n\tbackground: #444444;\n\tcolor: #ffffff;\n\tfont: 24pt monospace;\n\tborder-bottom: 2px solid #cccccc;\n\tpadding: 20px 0px 20px 10px;\n}\n\n/* http://css-tricks.com/snippets/css/a-guide-to-flexbox/ */\n#part-middle {\n\tdisplay: flex;\n\tflex-direction: row;\n\tflex-wrap: nowrap;\n\tjustify-content: space-between;\n\talign-items: stretch;\n\talign-content: stretch;\n\n\tmin-height: 800px;\n\n\tborder-top: 1px solid #ffffff;\n\tpadding: 8px;\n\tmargin-top: 2px;\n}\n#left-area {\n\tflex: 0 0 11em;\n\tmargin-right: 20px;\n\tmargin-bottom: 10px;\n}\n#center-area {\n\tflex: 1 1 0;\n\tmargin-bottom: 10px;\n}\n#right-area {\n\tflex: 0 0 40em;\n\tmargin-left: 20px;\n\tmargin-bottom: 10px;\n}\n\n#part-footer {\n\tclear: both;\n\tborder-top: 2px solid #bbbbbb;\n\tbackground: #eeeeee;\n\tcolor: #555555;\n\ttext-align: center;\n\tpadding-top: 12px;\n\tpadding-bottom: 12px;\n\tline-height: 1.5;\n}\n\n#exec-status {\n\tmargin-top: 25px;\n\tmargin-bottom: 25px;\n}\n#exec-state {\n\tdisplay: inline-block;\n\tvertical-align: middle;\n}\n#exec-other {\n\tdisplay: inline-block;\n\tvertical-align: middle;\n\tfont-size: 125%;\n}\n#current-state {\n\tbackground: #228822;\n\tcolor: #ffffff;\n\tfont: 16pt;\n\tpadding: 6pt;\n\tborder: 5px solid #228822;\n\tborder-radius: 10px;\n\tfont-size: 200%;\n\tfont-weight: bold;\n\tmargin-right: 10px;\n}\n#current-state.notrunning {\n\tbackground: #882222;\n\tborder: 5px solid #882222;\n\tborder-radius: 10px;\n\tanimation: pulsate 0.7s cubic-bezier(0.75, 0, 0.75, 1) infinite alternate;\n}\n#exec-other:hover {\n\ttext-decoration: underline;\n\tcolor: #9999ff;\n}\n\n#left-area .button {\n\tdisplay: inline-block;\n\ttext-align: center;\n\twidth: 95%;\n\tmin-width: 6em;\n\tbackground: #226622;\n\tcolor: #ffffff;\n\tfont: 16pt sans-serif;\n\tfont-weight: bold;\n\ttext-decoration: none;\n\tmargin: 10px 0 0 0;\n\tpadding: 0.4em;\n\tborder: 2px solid #000000;\n\tborder-radius: 4px;\n}\n#left-area .button a {\n\tcolor: #ffffff;\n\ttext-decoration: none;\n}\n#left-area .button:hover {\n\tbackground: #55aa55;\n}\n#left-area .button:disabled {\n\tbackground: #555555;\n\tcolor: #888888;\n}\n#left-area .button:disabled a {\n\tbackground: #555555;\n\tcolor: #888888;\n}\n\n#pause-button.pending {\n\tbackground: #5555ff;\n\tanimation: pulsate 0.2s cubic-bezier(0.75, 0, 0.75, 1) infinite alternate;\n}\n\n#attach-button {\n}\n#attach-button.enabled {\n\tanimation: pulsate 0.7s cubic-bezier(0.75, 0, 0.75, 1) infinite alternate;\n}\n\n.duktape-exec-line {\n\toutline: 2px solid red;\n\tbackground: #550000;\n}\n.duktape-break-line {\n\toutline: 2px solid white;\n}\n\n#output {\n\tfont: 9pt monospace;\n\tcolor: #000000;\n\tborder: 2px solid #cccccc;\n\tborder-radius: 5px;\n\tpadding: 3px;\n\theight: 30ex;\n\toverflow: scroll;\n\toverflow-x: auto;\n\toverflow-y: scroll;\n\twhite-space: pre;\n}\n#output .alert {\n\tcolor: #ff0000;\n}\n/* Default color (should be overridden by level) */\n#output .log {\n\tcolor: #00ff00;\n}\n/* Trace */\n#output .loglevel0 {\n\tcolor: #cccccc;\n}\n/* Debug */\n#output .loglevel1 {\n\tcolor: #cccccc;\n}\n/* Info */\n#output .loglevel2 {\n\tcolor: #888888;\n\tfont-weight: bold;\n}\n/* Warn */\n#output .loglevel3 {\n\tcolor: #ff4444;\n\tfont-weight: bold;\n}\n/* Error */\n#output .loglevel4 {\n\tcolor: #ff0000;\n\tfont-weight: bold;\n}\n/* Fatal */\n#output .loglevel5 {\n\tbackground: #000000;\n\tcolor: #ff0000;\n\tfont-weight: bold;\n}\n#output .debugger-info {\n\tcolor: #880000;\n\tfont-weight: bold;\n\tfont-style: italic;\n}\n#output .debugger-debug {\n\tcolor: #888888;\n\tfont-weight: bold;\n\tfont-style: italic;\n}\n\n#callstack {\n\tfont: 9pt monospace;\n\tcolor: #000000;\n\tmargin-top: 10px;\n\tborder: 2px solid #cccccc;\n\tborder-radius: 5px;\n\tpadding: 3px;\n\theight: 14ex;\n\toverflow: scroll;\n\toverflow-x: auto;\n\toverflow-y: scroll;\n\twhite-space: pre;\n}\n#callstack div:nth-child(2n) {\n\tbackground: #eeeeee;\n}\n#callstack .func {\n}\n#callstack .rest {\n\tfloat: right;\n\tcolor: #6666ff;\n}\n#callstack .rest:hover {\n\ttext-decoration: underline;\n\tcolor: #9999ff;\n}\n\n#locals {\n\tfont: 9pt monospace;\n\tcolor: #000000;\n\tmargin-top: 10px;\n\tborder: 2px solid #cccccc;\n\tborder-radius: 5px;\n\tpadding: 10px;\n\theight: 30ex;\n\toverflow: scroll;\n\toverflow-x: auto;\n\toverflow-y: scroll;\n\twhite-space: pre;\n}\n#locals div:nth-child(2n) {\n\tbackground: #eeeeee;\n}\n#locals .key {\n}\n#locals .value {\n\tfloat: right;\n\tcolor: #888888;\n}\n\n#breakpoints {\n\tcolor: #000000;\n\tmargin-top: 10px;\n\tborder: 2px solid #cccccc;\n\tborder-radius: 5px;\n\tpadding: 3px;\n\theight: 15ex;\n\toverflow: scroll;\n\toverflow-x: auto;\n\toverflow-y: scroll;\n\twhite-space: pre;\n}\n#breakpoints div {\n\tmargin: 2px 0 2px 0;\n}\n#breakpoints div:nth-child(2n) {\n\tbackground: #eeeeee;\n}\n#breakpoints a {\n\tfont: 9pt monospace;\n\tcolor: #6666ff;\n}\n#breakpoints a:hover {\n\ttext-decoration: underline;\n\tcolor: #9999ff;\n}\n.breakpoint-line {\n\tclear: both;\n\tpadding-top: 2px;\n\tpadding-bottom: 2px;\n}\n#add-breakpoint-file {\n\tfont: 10pt monospace;\n\twidth: 10em;\n\tpadding: 5px;\n}\n#add-breakpoint-line {\n\tfont: 10pt monospace;\n\twidth: 3em;\n\tmargin-left: 3px;\n\tpadding: 5px;\n}\n#delete-all-breakpoints-button {\n\tfloat: right;\n\tfont: 10pt sans-serif;\n\tpadding: 5px;\n\tborder: 1px solid #888888;\n\tbackground: #ddffdd;\n\tcolor: #000000;\n}\n#delete-all-breakpoints-button:hover {\n\tbackground: #f8fff8;\n}\n#delete-all-breakpoints-button:disabled {\n\tbackground: #dddddd;\n\tcolor: #444444;\n}\n#add-breakpoint-button {\n\tfont: 10pt sans-serif;\n\tmargin-left: 10px;\n\tpadding: 5px;\n\tborder: 1px solid #888888;\n\tbackground: #ddffdd;\n\tcolor: #000000;\n}\n#add-breakpoint-button:hover {\n\tbackground: #f8fff8;\n}\n#add-breakpoint-button:disabled {\n\tbackground: #dddddd;\n\tcolor: #444444;\n}\n#breakpoint-hint {\n\tcolor: #aaaaaa;\n\tfont-style: italic;\n\tmargin-left: 10px;\n}\n.delete-breakpoint-button {\n\tfloat: right;\n\tdisplay: inline;\n\tfont: 9pt sans-serif;\n\tpadding: 3px;\n\tborder: none;\n\tbackground: none;\n\tcolor: #6666ff;\n}\n.delete-breakpoint-button {\n\tfont: 9pt sans-serif;\n}\n.delete-breakpoint-button:hover {\n\ttext-decoration: underline;\n\tcolor: #9999ff;\n}\n.delete-breakpoint-button:disabled {\n\tcolor: #888888;\n}\n\n#about-dialog p {\n\tmargin: 10px 0 10px 0;\n}\n\n#bytecode-dialog p {\n\tmargin: 10px 0 10px 0;\n}\n#bytecode-dialog pre {\n\tfont: 10pt monospace;\n\tcolor: #000000;\n}\n#bytecode-dialog div.highlight {\n\tbackground: #888888;\n\tcolor: #ffffff;\n}\n\n#eval {\n\tcolor: #000000;\n\tmargin-top: 10px;\n\tborder: 2px solid #cccccc;\n\tborder-radius: 5px;\n\tpadding: 3px;\n\theight: 30ex;\n\toverflow: scroll;\n\toverflow-x: auto;\n\toverflow-y: scroll;\n\twhite-space: pre;\n}\n#eval-input {\n\tdisplay: inline;\n\tfont: 10pt monospace;\n\twidth: 20em;\n\tpadding: 5px;\n}\n#eval-button {\n\tdisplay: inline;\n\tmargin-left: 10px;\n\tpadding: 5px;\n\tborder: 1px solid #888888;\n\tfont: 10pt sans-serif;\n\tbackground: #ddffdd;\n\tcolor: #000000;\n}\n#eval-button {\n}\n#eval-button:hover {\n\tbackground: #f8fff8;\n}\n#eval-button:disabled {\n\tbackground: #dddddd;\n\tcolor: #444444;\n}\n#eval-button.pending {\n\tbackground: #5555ff;\n\tanimation: pulsate 0.2s cubic-bezier(0.75, 0, 0.75, 1) infinite alternate;\n}\n#eval-watch {\n\tmargin-left: 20px;\n\tvertical-align: middle;\n}\n#eval-output {\n\tfont: 10pt monospace;\n\twhite-space: pre;\n\tpadding: 5px;\n\tborder: 1px solid #888888;\n\tmin-height: 4ex;\n\tmargin-top: 5px;\n}\n\n#varname-input {\n\tfont: 10pt monospace;\n\twidth: 10em;\n\tpadding: 5px;\n}\n#varvalue-input {\n\tmargin-left: 10px;\n\tfont: 10pt monospace;\n\twidth: 20em;\n\tpadding: 5px;\n}\n#getvar-button,\n#putvar-button {\n\tdisplay: inline;\n\tfloat: right;\n\tmargin-left: 10px;\n\tpadding: 5px;\n\tborder: 1px solid #888888;\n\tfont: 10pt sans-serif;\n\tbackground: #ddffdd;\n\tcolor: #000000;\n}\n#getvar-button:hover,\n#putvar-button:hover {\n\tbackground: #f8fff8;\n}\n#getvar-button:disabled,\n#putvar-button:disabled {\n\tbackground: #dddddd;\n\tcolor: #444444;\n}\n#var-output {\n\tfont: 10pt monospace;\n\twhite-space: pre;\n\tpadding: 5px;\n\tborder: 1px solid #888888;\n\tmin-height: 4ex;\n\tmargin-top: 5px;\n}\n\n#source-pre {\n\tmargin-top: 10px;\n\tborder: 2px solid #cccccc;\n\tborder-radius: 5px;\n\theight: 400px;\n\toverflow: scroll;\n\toverflow-x: auto;\n\toverflow-y: scroll;\n}\n#source-pre.running {\n\tbackground: #eeeeee;\n\tcolor: #888888;\n}\n#source-pre.running #source-code {\n\tbackground: #eeeeee;\n\tcolor: #888888;\n}\n#source-filename {\n\tfont-size: 125%;\n\tcolor: #888888;\n}\ncode.sourcecode {\n\tcounter-reset: source-line;\n}\ncode.sourcecode div {\n\tfont: 10pt monospace;\n\tpadding: 2px 5px 2px 5px;\n\twhite-space: pre;\n\tborder-bottom: 1px solid #eeeeee;\n}\ncode.sourcecode div:before {\n\tdisplay: inline-block;\n\tcontent: counter(source-line);\n\tcounter-increment: source-line;\n\twidth: 4em;\n\tcolor: #888888;\n\ttext-align: right;\n\tmargin-right: 20px;\n}\ncode.sourcecode div.breakpoint:before {\n\tmargin-right: 0px;\n\tborder-right: 20px solid #ff0000;\n}\ncode.sourcecode div.highlight {\n\tbackground: #aaaaaa;\n\tcolor: #000000;\n}\ncode.sourcecode div.execution {\n\tbackground: #000000;\n\tcolor: #ffffff;\n}\n\n#source-select {\n\tmargin-top: 5px;\n}\n"
  },
  {
    "path": "react_juce/duktape/debugger/static/webui.js",
    "content": "/*\n *  Duktape debugger web client\n *\n *  Talks to the NodeJS server using socket.io.\n *\n *  http://unixpapa.com/js/key.html\n */\n\n// Update interval for custom source highlighting.\nvar SOURCE_UPDATE_INTERVAL = 350;\n\n// Source view\nvar activeFileName = null;          // file that we want to be loaded in source view\nvar activeLine = null;              // scroll to line once file has been loaded\nvar activeHighlight = null;         // line that we want to highlight (if any)\nvar loadedFileName = null;          // currently loaded (shown) file\nvar loadedLineCount = 0;            // currently loaded file line count\nvar loadedFileExecuting = false;    // true if currFileName (loosely) matches loadedFileName\nvar loadedLinePending = null;       // if set, scroll loaded file to requested line\nvar highlightLine = null;           // highlight line\nvar sourceEditedLines = [];         // line numbers which have been modified\n                                    // (added classes etc, tracked for removing)\nvar sourceUpdateInterval = null;    // timer for updating source view\nvar sourceFetchXhr = null;          // current AJAX request for fetching a source file (if any)\nvar forceButtonUpdate = false;      // hack to reset button states\nvar bytecodeDialogOpen = false;     // bytecode dialog active\nvar bytecodeIdxHighlight = null;    // index of currently highlighted line (or null)\nvar bytecodeIdxInstr = 0;           // index to first line of bytecode instructions\n\n// Execution state\nvar prevState = null;               // previous execution state ('paused', 'running', etc)\nvar prevAttached = null;            // previous debugger attached state (true, false, null)\nvar currFileName = null;            // current filename being executed\nvar currFuncName = null;            // current function name being executed\nvar currLine = 0;                   // current line being executed\nvar currPc = 0;                     // current bytecode PC being executed\nvar currState = 0;                  // current execution state ('paused', 'running', 'detached', etc)\nvar currAttached = false;           // current debugger attached state (true or false)\nvar currLocals = [];                // current local variables\nvar currCallstack = [];             // current callstack (from top to bottom)\nvar currBreakpoints = [];           // current breakpoints\nvar startedRunning = 0;             // timestamp when last started running (if running)\n                                    // (used to grey out the source file if running for long enough)\n\n/*\n *  Helpers\n */\n\nfunction formatBytes(x) {\n    if (x < 1024) {\n        return String(x) + ' bytes';\n    } else if (x < 1024 * 1024) {\n        return (x / 1024).toPrecision(3) + ' kB';\n    } else {\n        return (x / (1024 * 1024)).toPrecision(3) + ' MB';\n    }\n}\n\n/*\n *  Source view periodic update handling\n */\n\nfunction doSourceUpdate() {\n    var elem;\n\n    // Remove previously added custom classes\n    sourceEditedLines.forEach(function (linenum) {\n        elem = $('#source-code div')[linenum - 1];\n        if (elem) {\n            elem.classList.remove('breakpoint');\n            elem.classList.remove('execution');\n            elem.classList.remove('highlight');\n        }\n    });\n    sourceEditedLines.length = 0;\n\n    // If we're executing the file shown, highlight current line\n    if (loadedFileExecuting) {\n        elem = $('#source-code div')[currLine - 1];\n        if (elem) {\n            sourceEditedLines.push(currLine);\n            elem.classList.add('execution');\n        }\n    }\n\n    // Add breakpoints\n    currBreakpoints.forEach(function (bp) {\n        if (bp.fileName === loadedFileName) {\n            elem = $('#source-code div')[bp.lineNumber - 1];\n            if (elem) {\n                sourceEditedLines.push(bp.lineNumber);\n                elem.classList.add('breakpoint');\n            }\n        }\n    });\n\n    if (highlightLine !== null) {\n        elem = $('#source-code div')[highlightLine - 1];\n        if (elem) {\n            sourceEditedLines.push(highlightLine);\n            elem.classList.add('highlight');\n        }\n    }\n\n    // Bytecode dialog highlight\n    if (loadedFileExecuting && bytecodeDialogOpen && bytecodeIdxHighlight !== bytecodeIdxInstr + currPc) {\n        if (typeof bytecodeIdxHighlight === 'number') {\n            $('#bytecode-preformatted div')[bytecodeIdxHighlight].classList.remove('highlight');\n        }\n        bytecodeIdxHighlight = bytecodeIdxInstr + currPc;\n        $('#bytecode-preformatted div')[bytecodeIdxHighlight].classList.add('highlight');\n    }\n\n    // If no-one requested us to scroll to a specific line, finish.\n    if (loadedLinePending == null) {\n        return;\n    }\n\n    var reqLine = loadedLinePending;\n    loadedLinePending = null;\n\n    // Scroll to requested line.  This is not very clean, so a better solution\n    // should be found:\n    // https://developer.mozilla.org/en-US/docs/Web/API/Element.scrollIntoView\n    // http://erraticdev.blogspot.fi/2011/02/jquery-scroll-into-view-plugin-with.html\n    // http://flesler.blogspot.fi/2007/10/jqueryscrollto.html\n    var tmpLine = Math.max(reqLine - 5, 0);\n    elem = $('#source-code div')[tmpLine];\n    if (elem) {\n        elem.scrollIntoView();\n    }\n}\n\n// Source is updated periodically.  Other code can also call doSourceUpdate()\n// directly if an immediate update is needed.\nsourceUpdateInterval = setInterval(doSourceUpdate, SOURCE_UPDATE_INTERVAL);\n\n/*\n *  UI update handling when exec-status update arrives\n */\n\nfunction doUiUpdate() {\n    var now = Date.now();\n\n    // Note: loadedFileName can be either from target or from server, but they\n    // must match exactly.  We could do a loose match here, but exact matches\n    // are needed for proper breakpoint handling anyway.\n    loadedFileExecuting = (loadedFileName === currFileName);\n\n    // If we just started running, store a timestamp so we can grey out the\n    // source view only if we execute long enough (i.e. we're not just\n    // stepping).\n    if (currState !== prevState && currState === 'running') {\n        startedRunning = now;\n    }\n\n    // If we just became paused, check for eval watch\n    if (currState !== prevState && currState === 'paused') {\n        if ($('#eval-watch').is(':checked')) {\n            submitEval();  // don't clear eval input\n        }\n    }\n\n    // Update current execution state\n    if (currFileName === '' && currLine === 0) {\n        $('#current-fileline').text('');\n    } else {\n        $('#current-fileline').text(String(currFileName) + ':' + String(currLine));\n    }\n    if (currFuncName === '' && currPc === 0) {\n        $('#current-funcpc').text('');\n    } else {\n        $('#current-funcpc').text(String(currFuncName) + '() pc ' + String(currPc));\n    }\n    $('#current-state').text(String(currState));\n\n    // Update buttons\n    if (currState !== prevState || currAttached !== prevAttached || forceButtonUpdate) {\n        $('#stepinto-button').prop('disabled', !currAttached || currState !== 'paused');\n        $('#stepover-button').prop('disabled', !currAttached || currState !== 'paused');\n        $('#stepout-button').prop('disabled', !currAttached || currState !== 'paused');\n        $('#resume-button').prop('disabled', !currAttached || currState !== 'paused');\n        $('#pause-button').prop('disabled', !currAttached || currState !== 'running');\n        $('#attach-button').prop('disabled', currAttached);\n        if (currAttached) {\n            $('#attach-button').removeClass('enabled');\n        } else {\n            $('#attach-button').addClass('enabled');\n        }\n        $('#detach-button').prop('disabled', !currAttached);\n        $('#eval-button').prop('disabled', !currAttached);\n        $('#add-breakpoint-button').prop('disabled', !currAttached);\n        $('#delete-all-breakpoints-button').prop('disabled', !currAttached);\n        $('.delete-breakpoint-button').prop('disabled', !currAttached);\n        $('#putvar-button').prop('disabled', !currAttached);\n        $('#getvar-button').prop('disabled', !currAttached);\n        $('#heap-dump-download-button').prop('disabled', !currAttached);\n    }\n    if (currState !== 'running' || forceButtonUpdate) {\n        // Remove pending highlight once we're no longer running.\n        $('#pause-button').removeClass('pending');\n        $('#eval-button').removeClass('pending');\n    }\n    forceButtonUpdate = false;\n\n    // Make source window grey when running for a longer time, use a small\n    // delay to avoid flashing grey when stepping.\n    if (currState === 'running' && now - startedRunning >= 500) {\n        $('#source-pre').removeClass('notrunning');\n        $('#current-state').removeClass('notrunning');\n    } else {\n        $('#source-pre').addClass('notrunning');\n        $('#current-state').addClass('notrunning');\n    }\n\n    // Force source view to match currFileName only when running or when\n    // just became paused (from running or detached).\n    var fetchSource = false;\n    if (typeof currFileName === 'string') {\n        if (currState === 'running' ||\n            (prevState !== 'paused' && currState === 'paused') ||\n            (currAttached !== prevAttached)) {\n            if (activeFileName !== currFileName) {\n                fetchSource = true;\n                activeFileName = currFileName;\n                activeLine = currLine;\n                activeHighlight = null;\n                requestSourceRefetch();\n            }\n        }\n    }\n\n    // Force line update (scrollTop) only when running or just became paused.\n    // Otherwise let user browse and scroll source files freely.\n    if (!fetchSource) {\n        if ((prevState !== 'paused' && currState === 'paused') ||\n            currState === 'running') {\n            loadedLinePending = currLine || 0;\n        }\n    }\n}\n\n/*\n *  Init socket.io and add handlers\n */\n\nvar socket = io();  // returns a Manager\n\nsetInterval(function () {\n    socket.emit('keepalive', {\n        userAgent: (navigator || {}).userAgent\n    });\n}, 30000);\n\nsocket.on('connect', function () {\n    $('#socketio-info').text('connected');\n    currState = 'connected';\n\n    fetchSourceList();\n});\nsocket.on('disconnect', function () {\n    $('#socketio-info').text('not connected');\n    currState = 'disconnected';\n});\nsocket.on('reconnecting', function () {\n    $('#socketio-info').text('reconnecting');\n    currState = 'reconnecting';\n});\nsocket.on('error', function (err) {\n    $('#socketio-info').text(err);\n});\n\nsocket.on('replaced', function () {\n    // XXX: how to minimize the chance we'll further communciate with the\n    // server or reconnect to it?  socket.reconnection()?\n\n    // We'd like to window.close() here but can't (not allowed from scripts).\n    // Alert is the next best thing.\n    alert('Debugger connection replaced by a new one, do you have multiple tabs open? If so, please close this tab.');\n});\n\nsocket.on('keepalive', function (msg) {\n    // Not really interesting in the UI\n    // $('#server-info').text(new Date() + ': ' + JSON.stringify(msg));\n});\n\nsocket.on('basic-info', function (msg) {\n    $('#duk-version').text(String(msg.duk_version));\n    $('#duk-git-describe').text(String(msg.duk_git_describe));\n    $('#target-info').text(String(msg.target_info));\n    $('#endianness').text(String(msg.endianness));\n});\n\nsocket.on('exec-status', function (msg) {\n    // Not 100% reliable if callstack has several functions of the same name\n    if (bytecodeDialogOpen && (currFileName != msg.fileName || currFuncName != msg.funcName)) {\n        socket.emit('get-bytecode', {});\n    }\n\n    currFileName = msg.fileName;\n    currFuncName = msg.funcName;\n    currLine = msg.line;\n    currPc = msg.pc;\n    currState = msg.state;\n    currAttached = msg.attached;\n\n    // Duktape now restricts execution status updates quite effectively so\n    // there's no need to rate limit UI updates now.\n\n    doUiUpdate();\n\n    prevState = currState;\n    prevAttached = currAttached;\n});\n\n// Update the \"console\" output based on lines sent by the server.  The server\n// rate limits these updates to keep the browser load under control.  Even\n// better would be for the client to pull this (and other stuff) on its own.\nsocket.on('output-lines', function (msg) {\n    var elem = $('#output');\n    var i, n, ent;\n\n    elem.empty();\n    for (i = 0, n = msg.length; i < n; i++) {\n        ent = msg[i];\n        if (ent.type === 'print') {\n            elem.append($('<div></div>').text(ent.message));\n        } else if (ent.type === 'alert') {\n            elem.append($('<div class=\"alert\"></div>').text(ent.message));\n        } else if (ent.type === 'log') {\n            elem.append($('<div class=\"log loglevel' + ent.level + '\"></div>').text(ent.message));\n        } else if (ent.type === 'debugger-info') {\n            elem.append($('<div class=\"debugger-info\"><div>').text(ent.message));\n        } else if (ent.type === 'debugger-debug') {\n            elem.append($('<div class=\"debugger-debug\"><div>').text(ent.message));\n        } else {\n            elem.append($('<div></div>').text(ent.message));\n        }\n    }\n\n    // http://stackoverflow.com/questions/14918787/jquery-scroll-to-bottom-of-div-even-after-it-updates\n    // Stop queued animations so that we always scroll quickly to bottom\n    $('#output').stop(true);\n    $('#output').animate({ scrollTop: $('#output')[0].scrollHeight}, 1000);\n});\n\nsocket.on('callstack', function (msg) {\n    var elem = $('#callstack');\n    var s1, s2, div;\n\n    currCallstack = msg.callstack;\n\n    elem.empty();\n    msg.callstack.forEach(function (e) {\n        s1 = $('<a class=\"rest\"></a>').text(e.fileName + ':' + e.lineNumber + ' (pc ' + e.pc + ')');  // float\n        s1.on('click', function () {\n            activeFileName = e.fileName;\n            activeLine = e.lineNumber || 1;\n            activeHighlight = activeLine;\n            requestSourceRefetch();\n        });\n        s2 = $('<span class=\"func\"></span>').text(e.funcName + '()');\n        div = $('<div></div>');\n        div.append(s1);\n        div.append(s2);\n        elem.append(div);\n    });\n});\n\nsocket.on('locals', function (msg) {\n    var elem = $('#locals');\n    var s1, s2, div;\n    var i, n, e;\n\n    currLocals = msg.locals;\n\n    elem.empty();\n    for (i = 0, n = msg.locals.length; i < n; i++) {\n        e = msg.locals[i];\n        s1 = $('<span class=\"value\"></span>').text(e.value);  // float\n        s2 = $('<span class=\"key\"></span>').text(e.key);\n        div = $('<div></div>');\n        div.append(s1);\n        div.append(s2);\n        elem.append(div);\n    }\n});\n\nsocket.on('debug-stats', function (msg) {\n    $('#debug-rx-bytes').text(formatBytes(msg.rxBytes));\n    $('#debug-rx-dvalues').text(msg.rxDvalues);\n    $('#debug-rx-messages').text(msg.rxMessages);\n    $('#debug-rx-kbrate').text((msg.rxBytesPerSec / 1024).toFixed(2));\n    $('#debug-tx-bytes').text(formatBytes(msg.txBytes));\n    $('#debug-tx-dvalues').text(msg.txDvalues);\n    $('#debug-tx-messages').text(msg.txMessages);\n    $('#debug-tx-kbrate').text((msg.txBytesPerSec / 1024).toFixed(2));\n});\n\nsocket.on('breakpoints', function (msg) {\n    var elem = $('#breakpoints');\n    var div;\n    var sub;\n\n    currBreakpoints = msg.breakpoints;\n\n    elem.empty();\n\n    // First line is special\n    div = $('<div></div>');\n    sub = $('<button id=\"delete-all-breakpoints-button\"></button>').text('Delete all breakpoints');\n    sub.on('click', function () {\n        socket.emit('delete-all-breakpoints');\n    });\n    div.append(sub);\n    sub = $('<input id=\"add-breakpoint-file\"></input>').val('file.js');\n    div.append(sub);\n    sub = $('<span></span>').text(':');\n    div.append(sub);\n    sub = $('<input id=\"add-breakpoint-line\"></input>').val('123');\n    div.append(sub);\n    sub = $('<button id=\"add-breakpoint-button\"></button>').text('Add breakpoint');\n    sub.on('click', function () {\n        socket.emit('add-breakpoint', {\n            fileName: $('#add-breakpoint-file').val(),\n            lineNumber: Number($('#add-breakpoint-line').val())\n        });\n    });\n    div.append(sub);\n    sub = $('<span id=\"breakpoint-hint\"></span>').text('or dblclick source');\n    div.append(sub);\n    elem.append(div);\n\n    // Active breakpoints follow\n    msg.breakpoints.forEach(function (bp) {\n        var div;\n        var sub;\n\n        div = $('<div class=\"breakpoint-line\"></div>');\n        sub = $('<button class=\"delete-breakpoint-button\"></button>').text('Delete');\n        sub.on('click', function () {\n            socket.emit('delete-breakpoint', {\n                fileName: bp.fileName,\n                lineNumber: bp.lineNumber\n            });\n        });\n        div.append(sub);\n        sub = $('<a></a>').text((bp.fileName || '?') + ':' + (bp.lineNumber || 0));\n        sub.on('click', function () {\n            activeFileName = bp.fileName || '';\n            activeLine = bp.lineNumber || 1;\n            activeHighlight = activeLine;\n            requestSourceRefetch();\n        });\n        div.append(sub);\n        elem.append(div);\n    });\n\n    forceButtonUpdate = true;\n    doUiUpdate();\n});\n\nsocket.on('eval-result', function (msg) {\n    $('#eval-output').text((msg.error ? 'ERROR: ' : '') + msg.result);\n\n    // Remove eval button \"pulsating\" glow when we get a result\n    $('#eval-button').removeClass('pending');\n});\n\nsocket.on('getvar-result', function (msg) {\n    $('#var-output').text(msg.found ? msg.result : 'NOTFOUND');\n});\n\nsocket.on('bytecode', function (msg) {\n    var elem, div;\n    var div;\n\n    elem = $('#bytecode-preformatted');\n    elem.empty();\n\n    msg.preformatted.split('\\n').forEach(function (line, idx) {\n        div = $('<div></div>');\n        div.text(line);\n        elem.append(div);\n    });\n\n    bytecodeIdxHighlight = null;\n    bytecodeIdxInstr = msg.idxPreformattedInstructions;\n});\n\n$('#stepinto-button').click(function () {\n    socket.emit('stepinto', {});\n});\n\n$('#stepover-button').click(function () {\n    socket.emit('stepover', {});\n});\n\n$('#stepout-button').click(function () {\n    socket.emit('stepout', {});\n});\n\n$('#pause-button').click(function () {\n    socket.emit('pause', {});\n\n    // Pause may take seconds to complete so indicate it is pending.\n    $('#pause-button').addClass('pending');\n});\n\n$('#resume-button').click(function () {\n    socket.emit('resume', {});\n});\n\n$('#attach-button').click(function () {\n    socket.emit('attach', {});\n});\n\n$('#detach-button').click(function () {\n    socket.emit('detach', {});\n});\n\n$('#about-button').click(function () {\n    $('#about-dialog').dialog('open');\n});\n\n$('#show-bytecode-button').click(function () {\n    bytecodeDialogOpen = true;\n    $('#bytecode-dialog').dialog('open');\n\n    elem = $('#bytecode-preformatted');\n    elem.empty().text('Loading bytecode...');\n\n    socket.emit('get-bytecode', {});\n});\n\nfunction submitEval() {\n    socket.emit('eval', { input: $('#eval-input').val() });\n\n    // Eval may take seconds to complete so indicate it is pending.\n    $('#eval-button').addClass('pending');\n}\n\n$('#eval-button').click(function () {\n    submitEval();\n    $('#eval-input').val('');\n});\n\n$('#getvar-button').click(function () {\n    socket.emit('getvar', { varname: $('#varname-input').val() });\n});\n\n$('#putvar-button').click(function () {\n    // The variable value is parsed as JSON right now, but it'd be better to\n    // also be able to parse buffer values etc.\n    var val = JSON.parse($('#varvalue-input').val());\n    socket.emit('putvar', { varname: $('#varname-input').val(), varvalue: val });\n});\n\n$('#source-code').dblclick(function (event) {\n    var target = event.target;\n    var elems = $('#source-code div');\n    var i, n;\n    var line = 0;\n\n    // XXX: any faster way; elems doesn't have e.g. indexOf()\n    for (i = 0, n = elems.length; i < n; i++) {\n        if (target === elems[i]) {\n            line = i + 1;\n        }\n    }\n\n    socket.emit('toggle-breakpoint', {\n        fileName: loadedFileName,\n        lineNumber: line\n    });\n});\n\nfunction setSourceText(data) {\n    var elem, div;\n\n    elem = $('#source-code');\n    elem.empty();\n    data.split('\\n').forEach(function (line) {\n        div = $('<div></div>');\n        div.text(line);\n        elem.append(div);\n    });\n\n    sourceEditedLines = [];\n}\n\nfunction setSourceSelect(fileName) {\n    var elem;\n    var i, n, t;\n\n    if (fileName == null) {\n        $('#source-select').val('__none__');\n        return;\n    }\n\n    elem = $('#source-select option');\n    for (i = 0, n = elem.length; i < n; i++) {\n        // Exact match is required.\n        t = $(elem[i]).val();\n        if (t === fileName) {\n            $('#source-select').val(t);\n            return;\n        }\n    }\n}\n\n/*\n *  AJAX request handling to fetch source files\n */\n\nfunction requestSourceRefetch() {\n    // If previous update is pending, abort and start a new one.\n    if (sourceFetchXhr) {\n        sourceFetchXhr.abort();\n        sourceFetchXhr = null;\n    }\n\n    // Make copies of the requested file/line so that we have the proper\n    // values in case they've changed.\n    var fileName = activeFileName;\n    var lineNumber = activeLine;\n\n    // AJAX request for the source.\n    sourceFetchXhr = $.ajax({\n        type: 'POST',\n        url: '/source',\n        data: JSON.stringify({ fileName: fileName }),\n        contentType: 'application/json',\n        success: function (data, status, jqxhr) {\n            var elem;\n\n            sourceFetchXhr = null;\n\n            loadedFileName = fileName;\n            loadedLineCount = data.split('\\n').length;  // XXX: ignore issue with last empty line for now\n            loadedFileExecuting = (loadedFileName === currFileName);\n            setSourceText(data);\n            setSourceSelect(fileName);\n            loadedLinePending = activeLine || 1;\n            highlightLine = activeHighlight;  // may be null\n            activeLine = null;\n            activeHighlight = null;\n            doSourceUpdate();\n\n            // XXX: hacky transition, make source change visible\n            $('#source-pre').fadeTo('fast', 0.25, function () {\n                $('#source-pre').fadeTo('fast', 1.0);\n            });\n        },\n        error: function (jqxhr, status, err) {\n            // Not worth alerting about because source fetch errors happen\n            // all the time, e.g. for dynamically evaluated code.\n\n            sourceFetchXhr = null;\n\n            // XXX: prevent retry of no-such-file by negative caching?\n            loadedFileName = fileName;\n            loadedLineCount = 1;\n            loadedFileExecuting = false;\n            setSourceText('// Cannot load source file: ' + fileName);\n            setSourceSelect(null);\n            loadedLinePending = 1;\n            activeLine = null;\n            activeHighlight = null;\n            doSourceUpdate();\n\n            // XXX: error transition here\n            $('#source-pre').fadeTo('fast', 0.25, function () {\n                $('#source-pre').fadeTo('fast', 1.0);\n            });\n        },\n        dataType: 'text'\n    });\n}\n\n/*\n *  AJAX request for fetching the source list\n */\n\nfunction fetchSourceList() {\n    $.ajax({\n        type: 'POST',\n        url: '/sourceList',\n        data: JSON.stringify({}),\n        contentType: 'application/json',\n        success: function (data, status, jqxhr) {\n            var elem = $('#source-select');\n\n            data = JSON.parse(data);\n\n            elem.empty();\n            var opt = $('<option></option>').attr({ 'value': '__none__' }).text('No source file selected');\n            elem.append(opt);\n            data.forEach(function (ent) {\n                var opt = $('<option></option>').attr({ 'value': ent }).text(ent);\n                elem.append(opt);\n            });\n            elem.change(function () {\n                activeFileName = elem.val();\n                activeLine = 1;\n                requestSourceRefetch();\n            });\n        },\n        error: function (jqxhr, status, err) {\n            // This is worth alerting about as the UI is somewhat unusable\n            // if we don't get a source list.\n\n            alert('Failed to load source list: ' + err);\n        },\n        dataType: 'text'\n    });\n}\n\n/*\n *  Initialization\n */\n\n$(document).ready(function () {\n    var showAbout = true;\n\n    // About dialog, shown automatically on first startup.\n    $('#about-dialog').dialog({\n        autoOpen: false,\n        hide: 'fade',  // puff\n        show: 'fade',  // slide, puff\n        width: 500,\n        height: 300\n    });\n\n    // Bytecode dialog\n    $('#bytecode-dialog').dialog({\n        autoOpen: false,\n        hide: 'fade',  // puff\n        show: 'fade',  // slide, puff\n        width: 700,\n        height: 600,\n        close: function () {\n            bytecodeDialogOpen = false;\n            bytecodeIdxHighlight = null;\n            bytecodeIdxInstr = 0;\n        }\n    });\n\n    // http://diveintohtml5.info/storage.html\n    if (typeof localStorage !== 'undefined') {\n        if (localStorage.getItem('about-shown')) {\n            showAbout = false;\n        } else {\n            localStorage.setItem('about-shown', 'yes');\n        }\n    }\n    if (showAbout) {\n        $('#about-dialog').dialog('open');\n    }\n\n    // onclick handler for exec status text\n    function loadCurrFunc() {\n        activeFileName = currFileName;\n        activeLine = currLine;\n        requestSourceRefetch();\n    }\n    $('#exec-other').on('click', loadCurrFunc);\n\n    // Enter handling for eval input\n    // https://forum.jquery.com/topic/bind-html-input-to-enter-key-keypress\n    $('#eval-input').keypress(function (event) {\n        if (event.keyCode == 13) {\n            submitEval();\n            $('#eval-input').val('');\n        }\n    });\n\n    // Eval watch handling\n    $('#eval-watch').change(function () {\n        // nop\n    });\n\n    // Function keys\n    $('body').keydown(function(e){\n        //alert(\"keydown: \"+e.which);\n        switch (e.which) {\n        case 116:  // F5: step into\n            socket.emit('stepinto', {});\n            e.preventDefault();\n            return;\n        case 117:  // F6: step over\n            socket.emit('stepover', {});\n            e.preventDefault();\n            return;\n        case 118:  // F7: step out (= step return)\n            socket.emit('stepout', {});\n            e.preventDefault();\n            return;\n        case 119:  // F8: resume\n            socket.emit('resume', {});\n            e.preventDefault();\n            return;\n        }\n    });\n\n    forceButtonUpdate = true;\n    doUiUpdate();\n});\n"
  },
  {
    "path": "react_juce/duktape/duk_dist_meta.json",
    "content": "{\n    \"comment\": \"Metadata for Duktape distributable\", \n    \"duk_version_string\": \"2.4.0\", \n    \"type\": \"duk_dist_meta\", \n    \"duk_version\": 20400, \n    \"git_branch\": \"master\", \n    \"git_commit\": \"d4f2cff1c592d70f58bab8e1bd85705174c02a58\", \n    \"git_describe\": \"v2.4.0\"\n}"
  },
  {
    "path": "react_juce/duktape/examples/README.rst",
    "content": "================\nDuktape examples\n================\n\nExamples for using Duktape.  These support user documentation and are\nintended as informative illustrations only.\n\nExamples are unmaintained and are not production quality code.  Bugs are\nnot necessarily fixed, unless the bug makes the example misleading as\ndocumentation.\n"
  },
  {
    "path": "react_juce/duktape/examples/alloc-hybrid/README.rst",
    "content": "=====================\nHybrid pool allocator\n=====================\n\nExample allocator that tries to satisfy memory allocations for small sizes\nfrom a set of fixed pools, but always falls back to malloc/realloc/free if\na larger size is requested or the pools have been exhausted.\n\nThis may be useful to reduce memory churn when the platform allocator does\nnot handle allocations for a lot of small memory areas efficiently.\n"
  },
  {
    "path": "react_juce/duktape/examples/alloc-hybrid/duk_alloc_hybrid.c",
    "content": "/*\n *  Example memory allocator with pool allocation for small sizes and\n *  fallback into malloc/realloc/free for larger sizes or when the pools\n *  are exhausted.\n *\n *  Useful to reduce memory churn or work around a platform allocator\n *  that doesn't handle a lot of small allocations efficiently.\n */\n\n#include \"duktape.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n#include \"duk_alloc_hybrid.h\"\n\n/* Define to enable some debug printfs. */\n/* #define DUK_ALLOC_HYBRID_DEBUG */\n\ntypedef struct {\n\tsize_t size;\n\tint count;\n} pool_size_spec;\n\nstatic pool_size_spec pool_sizes[] = {\n\t{ 32, 1024 },\n\t{ 48, 2048 },\n\t{ 64, 2048 },\n\t{ 128, 2048 },\n\t{ 256, 512 },\n\t{ 1024, 64 },\n\t{ 2048, 32 }\n};\n\n#define  NUM_POOLS  (sizeof(pool_sizes) / sizeof(pool_size_spec))\n\n/* This must fit into the smallest pool entry. */\nstruct pool_free_entry;\ntypedef struct pool_free_entry pool_free_entry;\nstruct pool_free_entry {\n\tpool_free_entry *next;\n};\n\ntypedef struct {\n\tpool_free_entry *free;\n\tchar *alloc_start;\n\tchar *alloc_end;\n\tsize_t size;\n\tint count;\n} pool_header;\n\ntypedef struct {\n\tpool_header headers[NUM_POOLS];\n\tsize_t pool_max_size;\n\tchar *alloc_start;\n\tchar *alloc_end;\n} pool_state;\n\n#define ADDR_IN_STATE_ALLOC(st,p) \\\n\t((char *) (p) >= (st)->alloc_start && (char *) (p) < (st)->alloc_end)\n#define ADDR_IN_HEADER_ALLOC(hdr,p) \\\n\t((char *) (p) >= (hdr)->alloc_start && (char *) (p) < (hdr)->alloc_end)\n\n#if defined(DUK_ALLOC_HYBRID_DEBUG)\nstatic void dump_pool_state(pool_state *st) {\n\tpool_free_entry *free;\n\tint free_len;\n\tint i;\n\n\tprintf(\"=== Pool state: st=%p\\n\", (void *) st);\n\tfor (i = 0; i < (int) NUM_POOLS; i++) {\n\t\tpool_header *hdr = st->headers + i;\n\n\t\tfor (free = hdr->free, free_len = 0; free != NULL; free = free->next) {\n\t\t\tfree_len++;\n\t\t}\n\n\t\tprintf(\"[%d]: size %ld, count %ld, used %ld, free list len %ld\\n\",\n\t\t       i, (long) hdr->size, (long) hdr->count,\n\t\t       (long) (hdr->count - free_len),\n\t\t       (long) free_len);\n\t}\n}\n#else\nstatic void dump_pool_state(pool_state *st) {\n\t(void) st;\n}\n#endif\n\nvoid *duk_alloc_hybrid_init(void) {\n\tpool_state *st;\n\tsize_t total_size, max_size;\n\tint i, j;\n\tchar *p;\n\n\tst = (pool_state *) malloc(sizeof(pool_state));\n\tif (!st) {\n\t\treturn NULL;\n\t}\n\tmemset((void *) st, 0, sizeof(pool_state));\n\tst->alloc_start = NULL;\n\tst->alloc_end = NULL;\n\n\tfor (i = 0, total_size = 0, max_size = 0; i < (int) NUM_POOLS; i++) {\n#if defined(DUK_ALLOC_HYBRID_DEBUG)\n\t\tprintf(\"Pool %d: size %ld, count %ld\\n\", i, (long) pool_sizes[i].size, (long) pool_sizes[i].count);\n#endif\n\t\ttotal_size += pool_sizes[i].size * (size_t) pool_sizes[i].count;\n\t\tif (pool_sizes[i].size > max_size) {\n\t\t\tmax_size = pool_sizes[i].size;\n\t\t}\n\t}\n#if defined(DUK_ALLOC_HYBRID_DEBUG)\n\tprintf(\"Total size %ld, max pool size %ld\\n\", (long) total_size, (long) max_size);\n#endif\n\n\tst->alloc_start = (char *) malloc(total_size);\n\tif (!st->alloc_start) {\n\t\tfree(st);\n\t\treturn NULL;\n\t}\n\tst->alloc_end = st->alloc_start + total_size;\n\tst->pool_max_size = max_size;\n\tmemset((void *) st->alloc_start, 0, total_size);\n\n\tfor (i = 0, p = st->alloc_start; i < (int) NUM_POOLS; i++) {\n\t\tpool_header *hdr = st->headers + i;\n\n\t\thdr->alloc_start = p;\n\t\thdr->alloc_end = p + pool_sizes[i].size * (size_t) pool_sizes[i].count;\n\t\thdr->free = (pool_free_entry *) (void *) p;\n\t\thdr->size = pool_sizes[i].size;\n\t\thdr->count = pool_sizes[i].count;\n\n\t\tfor (j = 0; j < pool_sizes[i].count; j++) {\n\t\t\tpool_free_entry *ent = (pool_free_entry *) (void *) p;\n\t\t\tif (j == pool_sizes[i].count - 1) {\n\t\t\t\tent->next = (pool_free_entry *) NULL;\n\t\t\t} else {\n\t\t\t\tent->next = (pool_free_entry *) (void *) (p + pool_sizes[i].size);\n\t\t\t}\n\t\t\tp += pool_sizes[i].size;\n\t\t}\n\t}\n\n\tdump_pool_state(st);\n\n\t/* Use 'st' as udata. */\n\treturn (void *) st;\n}\n\nvoid *duk_alloc_hybrid(void *udata, duk_size_t size) {\n\tpool_state *st = (pool_state *) udata;\n\tint i;\n\tvoid *new_ptr;\n\n#if 0\n\tdump_pool_state(st);\n#endif\n\n\tif (size == 0) {\n\t\treturn NULL;\n\t}\n\tif (size > st->pool_max_size) {\n#if defined(DUK_ALLOC_HYBRID_DEBUG)\n\t\tprintf(\"alloc fallback: %ld\\n\", (long) size);\n#endif\n\t\treturn malloc(size);\n\t}\n\n\tfor (i = 0; i < (int) NUM_POOLS; i++) {\n\t\tpool_header *hdr = st->headers + i;\n\t\tif (hdr->size < size) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (hdr->free) {\n#if 0\n\t\t\tprintf(\"alloc from pool: %ld -> pool size %ld\\n\", (long) size, (long) hdr->size);\n#endif\n\t\t\tnew_ptr = (void *) hdr->free;\n\t\t\thdr->free = hdr->free->next;\n\t\t\treturn new_ptr;\n\t\t} else {\n#if defined(DUK_ALLOC_HYBRID_DEBUG)\n\t\t\tprintf(\"alloc out of pool entries: %ld -> pool size %ld\\n\", (long) size, (long) hdr->size);\n#endif\n\t\t\tbreak;\n\t\t}\n\t}\n\n#if defined(DUK_ALLOC_HYBRID_DEBUG)\n\tprintf(\"alloc fallback (out of pool): %ld\\n\", (long) size);\n#endif\n\treturn malloc(size);\n}\n\nvoid *duk_realloc_hybrid(void *udata, void *ptr, duk_size_t size) {\n\tpool_state *st = (pool_state *) udata;\n\tvoid *new_ptr;\n\tint i;\n\n#if 0\n\tdump_pool_state(st);\n#endif\n\n\tif (ADDR_IN_STATE_ALLOC(st, ptr)) {\n\t\t/* 'ptr' cannot be NULL. */\n\t\tfor (i = 0; i < (int) NUM_POOLS; i++) {\n\t\t\tpool_header *hdr = st->headers + i;\n\t\t\tif (ADDR_IN_HEADER_ALLOC(hdr, ptr)) {\n\t\t\t\tif (size <= hdr->size) {\n\t\t\t\t\t/* Still fits, no shrink support. */\n#if 0\n\t\t\t\t\tprintf(\"realloc original from pool: still fits, size %ld, pool size %ld\\n\",\n\t\t\t\t\t       (long) size, (long) hdr->size);\n#endif\n\t\t\t\t\treturn ptr;\n\t\t\t\t}\n\n\t\t\t\tnew_ptr = duk_alloc_hybrid(udata, size);\n\t\t\t\tif (!new_ptr) {\n#if defined(DUK_ALLOC_HYBRID_DEBUG)\n\t\t\t\t\tprintf(\"realloc original from pool: needed larger size, failed to alloc\\n\");\n#endif\n\t\t\t\t\treturn NULL;\n\t\t\t\t}\n\t\t\t\tmemcpy(new_ptr, ptr, hdr->size);\n\n\t\t\t\t((pool_free_entry *) ptr)->next = hdr->free;\n\t\t\t\thdr->free = (pool_free_entry *) ptr;\n#if 0\n\t\t\t\tprintf(\"realloc original from pool: size %ld, pool size %ld\\n\", (long) size, (long) hdr->size);\n#endif\n\t\t\t\treturn new_ptr;\n\t\t\t}\n\t\t}\n#if defined(DUK_ALLOC_HYBRID_DEBUG)\n\t\tprintf(\"NEVER HERE\\n\");\n#endif\n\t\treturn NULL;\n\t} else if (ptr != NULL) {\n\t\tif (size == 0) {\n\t\t\tfree(ptr);\n\t\t\treturn NULL;\n\t\t} else {\n#if defined(DUK_ALLOC_HYBRID_DEBUG)\n\t\t\tprintf(\"realloc fallback: size %ld\\n\", (long) size);\n#endif\n\t\t\treturn realloc(ptr, size);\n\t\t}\n\t} else {\n#if 0\n\t\tprintf(\"realloc NULL ptr, call alloc: %ld\\n\", (long) size);\n#endif\n\t\treturn duk_alloc_hybrid(udata, size);\n\t}\n}\n\nvoid duk_free_hybrid(void *udata, void *ptr) {\n\tpool_state *st = (pool_state *) udata;\n\tint i;\n\n#if 0\n\tdump_pool_state(st);\n#endif\n\n\tif (!ADDR_IN_STATE_ALLOC(st, ptr)) {\n\t\tif (ptr == NULL) {\n\t\t\treturn;\n\t\t}\n#if 0\n\t\tprintf(\"free out of pool: %p\\n\", (void *) ptr);\n#endif\n\t\tfree(ptr);\n\t\treturn;\n\t}\n\n\tfor (i = 0; i < (int) NUM_POOLS; i++) {\n\t\tpool_header *hdr = st->headers + i;\n\t\tif (ADDR_IN_HEADER_ALLOC(hdr, ptr)) {\n\t\t\t((pool_free_entry *) ptr)->next = hdr->free;\n\t\t\thdr->free = (pool_free_entry *) ptr;\n#if 0\n\t\t\tprintf(\"free from pool: %p\\n\", ptr);\n#endif\n\t\t\treturn;\n\t\t}\n\t}\n\n#if defined(DUK_ALLOC_HYBRID_DEBUG)\n\tprintf(\"NEVER HERE\\n\");\n#endif\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/alloc-hybrid/duk_alloc_hybrid.h",
    "content": "#if !defined(DUK_ALLOC_HYBRID_H_INCLUDED)\n#define DUK_ALLOC_HYBRID_H_INCLUDED\n\n#include \"duktape.h\"\n\nvoid *duk_alloc_hybrid_init(void);\nvoid *duk_alloc_hybrid(void *udata, duk_size_t size);\nvoid *duk_realloc_hybrid(void *udata, void *ptr, duk_size_t size);\nvoid duk_free_hybrid(void *udata, void *ptr);\n\n#endif  /* DUK_ALLOC_HYBRID_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/examples/alloc-logging/README.rst",
    "content": "======================\nAllocator with logging\n======================\n\nExample allocator that writes all memory alloc/realloc/free calls into a\nlog file so that memory usage can replayed later.  This is useful to e.g.\noptimize pool sizes.\n"
  },
  {
    "path": "react_juce/duktape/examples/alloc-logging/duk_alloc_logging.c",
    "content": "/*\n *  Example memory allocator with machine parseable logging.\n *\n *  Also sizes for reallocs and frees are logged so that the memory\n *  behavior can be essentially replayed to accurately determine e.g.\n *  optimal pool sizes for a pooled allocator.\n *\n *  Allocation structure:\n *\n *    [ alloc_hdr | user area ]\n *\n *     ^           ^\n *     |           `--- pointer returned to Duktape\n *     `--- underlying malloc ptr\n */\n\n#include \"duktape.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n#include \"duk_alloc_logging.h\"\n\n#define  ALLOC_LOG_FILE  \"/tmp/duk-alloc-log.txt\"\n\ntypedef struct {\n\t/* The double value in the union is there to ensure alignment is\n\t * good for IEEE doubles too.  In many 32-bit environments 4 bytes\n\t * would be sufficiently aligned and the double value is unnecessary.\n\t */\n\tunion {\n\t\tsize_t sz;\n\t\tdouble d;\n\t} u;\n} alloc_hdr;\n\nstatic FILE *log_file = NULL;\n\nstatic void write_log(const char *fmt, ...) {\n\tva_list ap;\n\n\tif (!log_file) {\n\t\tlog_file = fopen(ALLOC_LOG_FILE, \"wb\");\n\t\tif (!log_file) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\tva_start(ap, fmt);\n\tvfprintf(log_file, fmt, ap);\n\tva_end(ap);\n}\n\nvoid *duk_alloc_logging(void *udata, duk_size_t size) {\n\talloc_hdr *hdr;\n\tvoid *ret;\n\n\t(void) udata;  /* Suppress warning. */\n\n\tif (size == 0) {\n\t\twrite_log(\"A NULL %ld\\n\", (long) size);\n\t\treturn NULL;\n\t}\n\n\thdr = (alloc_hdr *) malloc(size + sizeof(alloc_hdr));\n\tif (!hdr) {\n\t\twrite_log(\"A FAIL %ld\\n\", (long) size);\n\t\treturn NULL;\n\t}\n\thdr->u.sz = size;\n\tret = (void *) (hdr + 1);\n\twrite_log(\"A %p %ld\\n\", ret, (long) size);\n\treturn ret;\n}\n\nvoid *duk_realloc_logging(void *udata, void *ptr, duk_size_t size) {\n\talloc_hdr *hdr;\n\tsize_t old_size;\n\tvoid *t;\n\tvoid *ret;\n\n\t(void) udata;  /* Suppress warning. */\n\n\t/* Handle the ptr-NULL vs. size-zero cases explicitly to minimize\n\t * platform assumptions.  You can get away with much less in specific\n\t * well-behaving environments.\n\t */\n\n\tif (ptr) {\n\t\thdr = (alloc_hdr *) (void *) ((unsigned char *) ptr - sizeof(alloc_hdr));\n\t\told_size = hdr->u.sz;\n\n\t\tif (size == 0) {\n\t\t\twrite_log(\"R %p %ld NULL 0\\n\", ptr, (long) old_size);\n\t\t\tfree((void *) hdr);\n\t\t\treturn NULL;\n\t\t} else {\n\t\t\tt = realloc((void *) hdr, size + sizeof(alloc_hdr));\n\t\t\tif (!t) {\n\t\t\t\twrite_log(\"R %p %ld FAIL %ld\\n\", ptr, (long) old_size, (long) size);\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\thdr = (alloc_hdr *) t;\n\t\t\thdr->u.sz = size;\n\t\t\tret = (void *) (hdr + 1);\n\t\t\twrite_log(\"R %p %ld %p %ld\\n\", ptr, (long) old_size, ret, (long) size);\n\t\t\treturn ret;\n\t\t}\n\t} else {\n\t\tif (size == 0) {\n\t\t\twrite_log(\"R NULL 0 NULL 0\\n\");\n\t\t\treturn NULL;\n\t\t} else {\n\t\t\thdr = (alloc_hdr *) malloc(size + sizeof(alloc_hdr));\n\t\t\tif (!hdr) {\n\t\t\t\twrite_log(\"R NULL 0 FAIL %ld\\n\", (long) size);\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\thdr->u.sz = size;\n\t\t\tret = (void *) (hdr + 1);\n\t\t\twrite_log(\"R NULL 0 %p %ld\\n\", ret, (long) size);\n\t\t\treturn ret;\n\t\t}\n\t}\n}\n\nvoid duk_free_logging(void *udata, void *ptr) {\n\talloc_hdr *hdr;\n\n\t(void) udata;  /* Suppress warning. */\n\n\tif (!ptr) {\n\t\twrite_log(\"F NULL 0\\n\");\n\t\treturn;\n\t}\n\thdr = (alloc_hdr *) (void *) ((unsigned char *) ptr - sizeof(alloc_hdr));\n\twrite_log(\"F %p %ld\\n\", ptr, (long) hdr->u.sz);\n\tfree((void *) hdr);\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/alloc-logging/duk_alloc_logging.h",
    "content": "#if !defined(DUK_ALLOC_LOGGING_H_INCLUDED)\n#define DUK_ALLOC_LOGGING_H_INCLUDED\n\n#include \"duktape.h\"\n\nvoid *duk_alloc_logging(void *udata, duk_size_t size);\nvoid *duk_realloc_logging(void *udata, void *ptr, duk_size_t size);\nvoid duk_free_logging(void *udata, void *ptr);\n\n#endif  /* DUK_ALLOC_LOGGING_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/examples/alloc-logging/log2gnuplot.py",
    "content": "#!/usr/bin/env python2\n#\n#  Analyze allocator logs and write total-bytes-in-use after every\n#  operation to stdout.  The output can be gnuplotted as:\n#\n#  $ python log2gnuplot.py </tmp/duk-alloc-log.txt >/tmp/output.txt\n#  $ gnuplot\n#  > plot \"output.txt\" with lines\n#\n\nimport os\nimport sys\n\ndef main():\n    allocated = 0\n\n    for line in sys.stdin:\n        line = line.strip()\n        parts = line.split(' ')\n\n        # A ptr/NULL/FAIL size\n        # F ptr/NULL size\n        # R ptr/NULL oldsize ptr/NULL/FAIL newsize\n\n        # Note: duk-low doesn't log oldsize (uses -1 instead)\n\n        if parts[0] == 'A':\n            if parts[1] != 'NULL' and parts[1] != 'FAIL':\n                allocated += long(parts[2])\n        elif parts[0] == 'F':\n            allocated -= long(parts[2])\n        elif parts[0] == 'R':\n            allocated -= long(parts[2])\n            if parts[3] != 'NULL' and parts[3] != 'FAIL':\n                allocated += long(parts[4])\n        print(allocated)\n\n    print(allocated)\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/examples/alloc-torture/README.rst",
    "content": "==========================================\nAllocator with memory wiping and red zones\n==========================================\n\nExample allocator that wipes memory on free and checks that no out-of-bounds\nwrites have been made to bytes just before and after the allocated area.\n\nValgrind is a better tool for detecting these memory issues, but it's not\navailable for all targets so you can use something like this to detect\nmemory lifecycle or out-of-bounds issues.\n"
  },
  {
    "path": "react_juce/duktape/examples/alloc-torture/duk_alloc_torture.c",
    "content": "/*\n *  Example torture memory allocator with memory wiping and check for\n *  out-of-bounds writes.\n *\n *  Allocation structure:\n *\n *    [ alloc_hdr | red zone before | user area | red zone after ]\n *\n *     ^                             ^\n *     |                             `--- pointer returned to Duktape\n *     `--- underlying malloc ptr\n */\n\n#include \"duktape.h\"\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n#include \"duk_alloc_torture.h\"\n\n#define  RED_ZONE_SIZE  16\n#define  RED_ZONE_BYTE  0x5a\n#define  INIT_BYTE      0xa5\n#define  WIPE_BYTE      0x27\n\ntypedef struct {\n\t/* The double value in the union is there to ensure alignment is\n\t * good for IEEE doubles too.  In many 32-bit environments 4 bytes\n\t * would be sufficiently aligned and the double value is unnecessary.\n\t */\n\tunion {\n\t\tsize_t sz;\n\t\tdouble d;\n\t} u;\n} alloc_hdr;\n\nstatic void check_red_zone(alloc_hdr *hdr) {\n\tsize_t size;\n\tint i;\n\tint err;\n\tunsigned char *p;\n\tunsigned char *userptr;\n\n\tsize = hdr->u.sz;\n\tuserptr = (unsigned char *) hdr + sizeof(alloc_hdr) + RED_ZONE_SIZE;\n\n\terr = 0;\n\tp = (unsigned char *) hdr + sizeof(alloc_hdr);\n\tfor (i = 0; i < RED_ZONE_SIZE; i++) {\n\t\tif (p[i] != RED_ZONE_BYTE) {\n\t\t\terr = 1;\n\t\t}\n\t}\n\tif (err) {\n\t\tfprintf(stderr, \"RED ZONE CORRUPTED BEFORE ALLOC: hdr=%p ptr=%p size=%ld\\n\",\n\t\t        (void *) hdr, (void *) userptr, (long) size);\n\t\tfflush(stderr);\n\t}\n\n\terr = 0;\n\tp = (unsigned char *) hdr + sizeof(alloc_hdr) + RED_ZONE_SIZE + size;\n\tfor (i = 0; i < RED_ZONE_SIZE; i++) {\n\t\tif (p[i] != RED_ZONE_BYTE) {\n\t\t\terr = 1;\n\t\t}\n\t}\n\tif (err) {\n\t\tfprintf(stderr, \"RED ZONE CORRUPTED AFTER ALLOC: hdr=%p ptr=%p size=%ld\\n\",\n\t\t        (void *) hdr, (void *) userptr, (long) size);\n\t\tfflush(stderr);\n\t}\n}\n\nvoid *duk_alloc_torture(void *udata, duk_size_t size) {\n\tunsigned char *p;\n\n\t(void) udata;  /* Suppress warning. */\n\n\tif (size == 0) {\n\t\treturn NULL;\n\t}\n\n\tp = (unsigned char *) malloc(size + sizeof(alloc_hdr) + 2 * RED_ZONE_SIZE);\n\tif (!p) {\n\t\treturn NULL;\n\t}\n\n\t((alloc_hdr *) (void *) p)->u.sz = size;\n\tp += sizeof(alloc_hdr);\n\tmemset((void *) p, RED_ZONE_BYTE, RED_ZONE_SIZE);\n\tp += RED_ZONE_SIZE;\n\tmemset((void *) p, INIT_BYTE, size);\n\tp += size;\n\tmemset((void *) p, RED_ZONE_BYTE, RED_ZONE_SIZE);\n\tp -= size;\n\treturn (void *) p;\n}\n\nvoid *duk_realloc_torture(void *udata, void *ptr, duk_size_t size) {\n\tunsigned char *p, *old_p;\n\tsize_t old_size;\n\n\t(void) udata;  /* Suppress warning. */\n\n\t/* Handle the ptr-NULL vs. size-zero cases explicitly to minimize\n\t * platform assumptions.  You can get away with much less in specific\n\t * well-behaving environments.\n\t */\n\n\tif (ptr) {\n\t\told_p = (unsigned char *) ptr - sizeof(alloc_hdr) - RED_ZONE_SIZE;\n\t\told_size = ((alloc_hdr *) (void *) old_p)->u.sz;\n\t\tcheck_red_zone((alloc_hdr *) (void *) old_p);\n\n\t\tif (size == 0) {\n\t\t\tmemset((void *) old_p, WIPE_BYTE, old_size + sizeof(alloc_hdr) + 2 * RED_ZONE_SIZE);\n\t\t\tfree((void *) old_p);\n\t\t\treturn NULL;\n\t\t} else {\n\t\t\t/* Force address change on every realloc. */\n\t\t\tp = (unsigned char *) malloc(size + sizeof(alloc_hdr) + 2 * RED_ZONE_SIZE);\n\t\t\tif (!p) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\n\t\t\t((alloc_hdr *) (void *) p)->u.sz = size;\n\t\t\tp += sizeof(alloc_hdr);\n\t\t\tmemset((void *) p, RED_ZONE_BYTE, RED_ZONE_SIZE);\n\t\t\tp += RED_ZONE_SIZE;\n\t\t\tif (size > old_size) {\n\t\t\t\tmemcpy((void *) p, (void *) (old_p + sizeof(alloc_hdr) + RED_ZONE_SIZE), old_size);\n\t\t\t\tmemset((void *) (p + old_size), INIT_BYTE, size - old_size);\n\t\t\t} else {\n\t\t\t\tmemcpy((void *) p, (void *) (old_p + sizeof(alloc_hdr) + RED_ZONE_SIZE), size);\n\t\t\t}\n\t\t\tp += size;\n\t\t\tmemset((void *) p, RED_ZONE_BYTE, RED_ZONE_SIZE);\n\t\t\tp -= size;\n\n\t\t\tmemset((void *) old_p, WIPE_BYTE, old_size + sizeof(alloc_hdr) + 2 * RED_ZONE_SIZE);\n\t\t\tfree((void *) old_p);\n\n\t\t\treturn (void *) p;\n\t\t}\n\t} else {\n\t\tif (size == 0) {\n\t\t\treturn NULL;\n\t\t} else {\n\t\t\tp = (unsigned char *) malloc(size + sizeof(alloc_hdr) + 2 * RED_ZONE_SIZE);\n\t\t\tif (!p) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\n\t\t\t((alloc_hdr *) (void *) p)->u.sz = size;\n\t\t\tp += sizeof(alloc_hdr);\n\t\t\tmemset((void *) p, RED_ZONE_BYTE, RED_ZONE_SIZE);\n\t\t\tp += RED_ZONE_SIZE;\n\t\t\tmemset((void *) p, INIT_BYTE, size);\n\t\t\tp += size;\n\t\t\tmemset((void *) p, RED_ZONE_BYTE, RED_ZONE_SIZE);\n\t\t\tp -= size;\n\t\t\treturn (void *) p;\n\t\t}\n\t}\n}\n\nvoid duk_free_torture(void *udata, void *ptr) {\n\tunsigned char *p;\n\tsize_t old_size;\n\n\t(void) udata;  /* Suppress warning. */\n\n\tif (!ptr) {\n\t\treturn;\n\t}\n\n\tp = (unsigned char *) ptr - sizeof(alloc_hdr) - RED_ZONE_SIZE;\n\told_size = ((alloc_hdr *) (void *) p)->u.sz;\n\n\tcheck_red_zone((alloc_hdr *) (void *) p);\n\tmemset((void *) p, WIPE_BYTE, old_size + sizeof(alloc_hdr) + 2 * RED_ZONE_SIZE);\n\tfree((void *) p);\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/alloc-torture/duk_alloc_torture.h",
    "content": "#if !defined(DUK_ALLOC_TORTURE_H_INCLUDED)\n#define DUK_ALLOC_TORTURE_H_INCLUDED\n\n#include \"duktape.h\"\n\nvoid *duk_alloc_torture(void *udata, duk_size_t size);\nvoid *duk_realloc_torture(void *udata, void *ptr, duk_size_t size);\nvoid duk_free_torture(void *udata, void *ptr);\n\n#endif  /* DUK_ALLOC_TORTURE_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/examples/cmdline/README.rst",
    "content": "====================\nDuktape command line\n====================\n\nECMAScript command line execution tool, useful for running ECMAScript code\nfrom a file, stdin, or interactively.  Also used by automatic testing.\n"
  },
  {
    "path": "react_juce/duktape/examples/cmdline/duk_cmdline.c",
    "content": "/*\n *  Command line execution tool.  Useful for test cases and manual testing.\n *  Also demonstrates some basic integration techniques.\n *\n *  Optional features include:\n *\n *  - To enable print()/alert() bindings, define DUK_CMDLINE_PRINTALERT_SUPPORT\n *    and add extras/print-alert/duk_print_alert.c to compilation.\n *\n *  - To enable console.log() etc, define DUK_CMDLINE_CONSOLE_SUPPORT\n *    and add extras/console/duk_console.c to compilation.\n *\n *  - To enable Duktape.Logger, define DUK_CMDLINE_LOGGING_SUPPORT\n *    and add extras/logging/duk_logging.c to compilation.\n *\n *  - To enable CBOR, define DUK_CMDLINE_CBOR_SUPPORT and add\n *    extras/cbor/duk_cbor.c to compilation.\n *\n *  - To enable Duktape 1.x module loading support (require(),\n *    Duktape.modSearch() etc), define DUK_CMDLINE_MODULE_SUPPORT and add\n *    extras/module-duktape/duk_module_duktape.c to compilation.\n *\n *  - To enable linenoise and other fancy stuff, compile with -DDUK_CMDLINE_FANCY.\n *    It is not the default to maximize portability.  You can also compile in\n *    support for example allocators, grep for DUK_CMDLINE_*.\n */\n\n/* Helper define to enable a feature set; can also use separate defines. */\n#if defined(DUK_CMDLINE_FANCY)\n#define DUK_CMDLINE_LINENOISE\n#define DUK_CMDLINE_LINENOISE_COMPLETION  /* Enables completion and hints. */\n#define DUK_CMDLINE_RLIMIT\n#define DUK_CMDLINE_SIGNAL\n#endif\n\n#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || \\\n    defined(WIN64) || defined(_WIN64) || defined(__WIN64__)\n/* Suppress warnings about plain fopen() etc. */\n#define _CRT_SECURE_NO_WARNINGS\n#if defined(_MSC_VER) && (_MSC_VER < 1900)\n/* Workaround for snprintf() missing in older MSVC versions.\n * Note that _snprintf() may not NUL terminate the string, but\n * this difference does not matter here as a NUL terminator is\n * always explicitly added.\n */\n#define snprintf _snprintf\n#endif\n#endif\n\n#if defined(DUK_CMDLINE_PTHREAD_STACK_CHECK)\n#define _GNU_SOURCE\n#include <pthread.h>\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#if defined(DUK_CMDLINE_SIGNAL)\n#include <signal.h>\n#endif\n#if defined(DUK_CMDLINE_RLIMIT)\n#include <sys/resource.h>\n#endif\n#if defined(DUK_CMDLINE_LINENOISE)\n#include \"linenoise.h\"\n#include <stdint.h>  /* Assume C99/C++11 with linenoise. */\n#endif\n#if defined(DUK_CMDLINE_PRINTALERT_SUPPORT)\n#include \"duk_print_alert.h\"\n#endif\n#if defined(DUK_CMDLINE_CONSOLE_SUPPORT)\n#include \"duk_console.h\"\n#endif\n#if defined(DUK_CMDLINE_LOGGING_SUPPORT)\n#include \"duk_logging.h\"\n#endif\n#if defined(DUK_CMDLINE_MODULE_SUPPORT)\n#include \"duk_module_duktape.h\"\n#endif\n#if defined(DUK_CMDLINE_CBOR_SUPPORT)\n#include \"duk_cbor.h\"\n#endif\n#if defined(DUK_CMDLINE_FILEIO)\n#include <errno.h>\n#endif\n#if defined(EMSCRIPTEN)\n#include <emscripten.h>\n#endif\n#if defined(DUK_CMDLINE_ALLOC_LOGGING)\n#include \"duk_alloc_logging.h\"\n#endif\n#if defined(DUK_CMDLINE_ALLOC_TORTURE)\n#include \"duk_alloc_torture.h\"\n#endif\n#if defined(DUK_CMDLINE_ALLOC_HYBRID)\n#include \"duk_alloc_hybrid.h\"\n#endif\n#include \"duktape.h\"\n\n#include \"duk_cmdline.h\"\n\n#if defined(DUK_CMDLINE_LOWMEM)\n#include \"duk_alloc_pool.h\"\n#endif\n\n#if defined(DUK_CMDLINE_DEBUGGER_SUPPORT)\n#include \"duk_trans_socket.h\"\n#endif\n\n#define  MEM_LIMIT_NORMAL   (128*1024*1024)   /* 128 MB */\n#define  MEM_LIMIT_HIGH     (2047*1024*1024)  /* ~2 GB */\n#define  LINEBUF_SIZE       65536\n\nstatic int main_argc = 0;\nstatic char **main_argv = NULL;\nstatic int interactive_mode = 0;\nstatic int allow_bytecode = 0;\n#if defined(DUK_CMDLINE_DEBUGGER_SUPPORT)\nstatic int debugger_reattach = 0;\n#endif\n#if defined(DUK_CMDLINE_LINENOISE_COMPLETION)\nstatic int no_auto_complete = 0;\n#endif\n\nint duk_cmdline_stack_check(void);\n\n/*\n *  Misc helpers\n */\n\nstatic void print_greet_line(void) {\n\tprintf(\"((o) Duktape%s %d.%d.%d (%s)\\n\",\n#if defined(DUK_CMDLINE_LINENOISE)\n\t       \" [linenoise]\",\n#else\n\t       \"\",\n#endif\n\t       (int) (DUK_VERSION / 10000),\n\t       (int) ((DUK_VERSION / 100) % 100),\n\t       (int) (DUK_VERSION % 100),\n\t       DUK_GIT_DESCRIBE);\n}\n\n#if defined(DUK_CMDLINE_RLIMIT)\nstatic void set_resource_limits(rlim_t mem_limit_value) {\n\tint rc;\n\tstruct rlimit lim;\n\n\trc = getrlimit(RLIMIT_AS, &lim);\n\tif (rc != 0) {\n\t\tfprintf(stderr, \"Warning: cannot read RLIMIT_AS\\n\");\n\t\treturn;\n\t}\n\n\tif (lim.rlim_max < mem_limit_value) {\n\t\tfprintf(stderr, \"Warning: rlim_max < mem_limit_value (%d < %d)\\n\", (int) lim.rlim_max, (int) mem_limit_value);\n\t\treturn;\n\t}\n\n\tlim.rlim_cur = mem_limit_value;\n\tlim.rlim_max = mem_limit_value;\n\n\trc = setrlimit(RLIMIT_AS, &lim);\n\tif (rc != 0) {\n\t\tfprintf(stderr, \"Warning: setrlimit failed\\n\");\n\t\treturn;\n\t}\n\n#if 0\n\tfprintf(stderr, \"Set RLIMIT_AS to %d\\n\", (int) mem_limit_value);\n#endif\n}\n#endif  /* DUK_CMDLINE_RLIMIT */\n\n#if defined(DUK_CMDLINE_SIGNAL)\nstatic void my_sighandler(int x) {\n\tfprintf(stderr, \"Got signal %d\\n\", x);\n\tfflush(stderr);\n}\nstatic void set_sigint_handler(void) {\n\t(void) signal(SIGINT, my_sighandler);\n\t(void) signal(SIGPIPE, SIG_IGN);  /* avoid SIGPIPE killing process */\n}\n#endif  /* DUK_CMDLINE_SIGNAL */\n\nstatic void cmdline_fatal_handler(void *udata, const char *msg) {\n\t(void) udata;\n\tfprintf(stderr, \"*** FATAL ERROR: %s\\n\", msg ? msg : \"no message\");\n\tfprintf(stderr, \"Causing intentional segfault...\\n\");\n\tfflush(stderr);\n\t*((volatile unsigned int *) 0) = (unsigned int) 0xdeadbeefUL;\n\tabort();\n}\n\n/* Print error to stderr and pop error. */\nstatic void print_pop_error(duk_context *ctx, FILE *f) {\n\tfprintf(f, \"%s\\n\", duk_safe_to_stacktrace(ctx, -1));\n\tfflush(f);\n\tduk_pop(ctx);\n}\n\nstatic duk_ret_t wrapped_compile_execute(duk_context *ctx, void *udata) {\n\tconst char *src_data;\n\tduk_size_t src_len;\n\tduk_uint_t comp_flags;\n\n\t(void) udata;\n\n\t/* XXX: Here it'd be nice to get some stats for the compilation result\n\t * when a suitable command line is given (e.g. code size, constant\n\t * count, function count.  These are available internally but not through\n\t * the public API.\n\t */\n\n\t/* Use duk_compile_lstring_filename() variant which avoids interning\n\t * the source code.  This only really matters for low memory environments.\n\t */\n\n\t/* [ ... bytecode_filename src_data src_len filename ] */\n\n\tsrc_data = (const char *) duk_require_pointer(ctx, -3);\n\tsrc_len = (duk_size_t) duk_require_uint(ctx, -2);\n\n\tif (src_data != NULL && src_len >= 1 && src_data[0] == (char) 0xbf) {\n\t\t/* Bytecode. */\n\t\tif (allow_bytecode) {\n\t\t\tvoid *buf;\n\t\t\tbuf = duk_push_fixed_buffer(ctx, src_len);\n\t\t\tmemcpy(buf, (const void *) src_data, src_len);\n\t\t\tduk_load_function(ctx);\n\t\t} else {\n\t\t\t(void) duk_type_error(ctx, \"bytecode input rejected (use -b to allow bytecode inputs)\");\n\t\t}\n\t} else {\n\t\t/* Source code. */\n\t\tcomp_flags = DUK_COMPILE_SHEBANG;\n\t\tduk_compile_lstring_filename(ctx, comp_flags, src_data, src_len);\n\t}\n\n\t/* [ ... bytecode_filename src_data src_len function ] */\n\n\t/* Optional bytecode dump. */\n\tif (duk_is_string(ctx, -4)) {\n\t\tFILE *f;\n\t\tvoid *bc_ptr;\n\t\tduk_size_t bc_len;\n\t\tsize_t wrote;\n\t\tchar fnbuf[256];\n\t\tconst char *filename;\n\n\t\tduk_dup_top(ctx);\n\t\tduk_dump_function(ctx);\n\t\tbc_ptr = duk_require_buffer_data(ctx, -1, &bc_len);\n\t\tfilename = duk_require_string(ctx, -5);\n#if defined(EMSCRIPTEN)\n\t\tif (filename[0] == '/') {\n\t\t\tsnprintf(fnbuf, sizeof(fnbuf), \"%s\", filename);\n\t\t} else {\n\t\t\tsnprintf(fnbuf, sizeof(fnbuf), \"/working/%s\", filename);\n\t\t}\n#else\n\t\tsnprintf(fnbuf, sizeof(fnbuf), \"%s\", filename);\n#endif\n\t\tfnbuf[sizeof(fnbuf) - 1] = (char) 0;\n\n\t\tf = fopen(fnbuf, \"wb\");\n\t\tif (!f) {\n\t\t\t(void) duk_generic_error(ctx, \"failed to open bytecode output file\");\n\t\t}\n\t\twrote = fwrite(bc_ptr, 1, (size_t) bc_len, f);  /* XXX: handle partial writes */\n\t\t(void) fclose(f);\n\t\tif (wrote != bc_len) {\n\t\t\t(void) duk_generic_error(ctx, \"failed to write all bytecode\");\n\t\t}\n\n\t\treturn 0;  /* duk_safe_call() cleans up */\n\t}\n\n#if 0\n\t/* Manual test for bytecode dump/load cycle: dump and load before\n\t * execution.  Enable manually, then run \"make ecmatest\" for a\n\t * reasonably good coverage of different functions and programs.\n\t */\n\tduk_dump_function(ctx);\n\tduk_load_function(ctx);\n#endif\n\n#if defined(DUK_CMDLINE_LOWMEM)\n\tlowmem_start_exec_timeout();\n#endif\n\n\tduk_push_global_object(ctx);  /* 'this' binding */\n\tduk_call_method(ctx, 0);\n\n#if defined(DUK_CMDLINE_LOWMEM)\n\tlowmem_clear_exec_timeout();\n#endif\n\n\tif (interactive_mode) {\n\t\t/*\n\t\t *  In interactive mode, write to stdout so output won't\n\t\t *  interleave as easily.\n\t\t *\n\t\t *  NOTE: the ToString() coercion may fail in some cases;\n\t\t *  for instance, if you evaluate:\n\t\t *\n\t\t *    ( {valueOf: function() {return {}},\n\t\t *       toString: function() {return {}}});\n\t\t *\n\t\t *  The error is:\n\t\t *\n\t\t *    TypeError: coercion to primitive failed\n\t\t *            duk_api.c:1420\n\t\t *\n\t\t *  These are handled now by the caller which also has stack\n\t\t *  trace printing support.  User code can print out errors\n\t\t *  safely using duk_safe_to_string().\n\t\t */\n\n\t\tduk_push_global_stash(ctx);\n\t\tduk_get_prop_string(ctx, -1, \"dukFormat\");\n\t\tduk_dup(ctx, -3);\n\t\tduk_call(ctx, 1);  /* -> [ ... res stash formatted ] */\n\n\t\tfprintf(stdout, \"= %s\\n\", duk_to_string(ctx, -1));\n\t\tfflush(stdout);\n\t} else {\n\t\t/* In non-interactive mode, success results are not written at all.\n\t\t * It is important that the result value is not string coerced,\n\t\t * as the string coercion may cause an error in some cases.\n\t\t */\n\t}\n\n\treturn 0;  /* duk_safe_call() cleans up */\n}\n\n/*\n *  Minimal Linenoise completion support\n */\n\n#if defined(DUK_CMDLINE_LINENOISE_COMPLETION)\nstatic duk_context *completion_ctx;\n\nstatic const char *linenoise_completion_script =\n\t\"(function linenoiseCompletion(input, addCompletion) {\\n\"\n\t\"    // Find maximal trailing string which looks like a property\\n\"\n\t\"    // access.  Look up all the components (starting from the global\\n\"\n\t\"    // object now) except the last; treat the last component as a\\n\"\n\t\"    // partial name and use it as a filter for possible properties.\\n\"\n\t\"    var match, propseq, obj, i, partial, names, name, sanity;\\n\"\n\t\"\\n\"\n\t\"    if (!input) { return; }\\n\"\n\t\"    match = /^.*?((?:\\\\w+\\\\.)*\\\\w*)$/.exec(input);\\n\"\n\t\"    if (!match || !match[1]) { return; }\\n\"\n\t\"    var propseq = match[1].split('.');\\n\"\n\t\"\\n\"\n\t\"    obj = Function('return this')();\\n\"\n\t\"    for (i = 0; i < propseq.length - 1; i++) {\\n\"\n\t\"        if (obj === void 0 || obj === null) { return; }\\n\"\n\t\"        obj = obj[propseq[i]];\\n\"\n\t\"    }\\n\"\n\t\"    if (obj === void 0 || obj === null) { return; }\\n\"\n\t\"\\n\"\n\t\"    partial = propseq[propseq.length - 1];\\n\"\n\t\"    sanity = 1000;\\n\"\n\t\"    while (obj != null) {\\n\"\n\t\"        if (--sanity < 0) { throw new Error('sanity'); }\\n\"\n\t\"        names = Object.getOwnPropertyNames(Object(obj));\\n\"\n\t\"        for (i = 0; i < names.length; i++) {\\n\"\n\t\"            if (--sanity < 0) { throw new Error('sanity'); }\\n\"\n\t\"            name = names[i];\\n\"\n\t\"            if (Number(name) >= 0) { continue; }  // ignore array keys\\n\"\n\t\"            if (name.substring(0, partial.length) !== partial) { continue; }\\n\"\n\t\"            if (name === partial) { addCompletion(input + '.'); continue; }\\n\"\n\t\"            addCompletion(input + name.substring(partial.length));\\n\"\n\t\"        }\\n\"\n\t\"        obj = Object.getPrototypeOf(Object(obj));\\n\"\n\t\"    }\\n\"\n\t\"})\";\n\nstatic const char *linenoise_hints_script =\n\t\"(function linenoiseHints(input) {\\n\"\n\t\"    // Similar to completions but different handling for final results.\\n\"\n\t\"    var match, propseq, obj, i, partial, names, name, res, found, first, sanity;\\n\"\n\t\"\\n\"\n\t\"    if (!input) { return; }\\n\"\n\t\"    match = /^.*?((?:\\\\w+\\\\.)*\\\\w*)$/.exec(input);\\n\"\n\t\"    if (!match || !match[1]) { return; }\\n\"\n\t\"    var propseq = match[1].split('.');\\n\"\n\t\"\\n\"\n\t\"    obj = Function('return this')();\\n\"\n\t\"    for (i = 0; i < propseq.length - 1; i++) {\\n\"\n\t\"        if (obj === void 0 || obj === null) { return; }\\n\"\n\t\"        obj = obj[propseq[i]];\\n\"\n\t\"    }\\n\"\n\t\"    if (obj === void 0 || obj === null) { return; }\\n\"\n\t\"\\n\"\n\t\"    partial = propseq[propseq.length - 1];\\n\"\n\t\"    res = [];\\n\"\n\t\"    found = Object.create(null);  // keys already handled\\n\"\n\t\"    sanity = 1000;\\n\"\n\t\"    while (obj != null) {\\n\"\n\t\"        if (--sanity < 0) { throw new Error('sanity'); }\\n\"\n\t\"        names = Object.getOwnPropertyNames(Object(obj));\\n\"\n\t\"        first = true;\\n\"\n\t\"        for (i = 0; i < names.length; i++) {\\n\"\n\t\"            if (--sanity < 0) { throw new Error('sanity'); }\\n\"\n\t\"            name = names[i];\\n\"\n\t\"            if (Number(name) >= 0) { continue; }  // ignore array keys\\n\"\n\t\"            if (name.substring(0, partial.length) !== partial) { continue; }\\n\"\n\t\"            if (name === partial) { continue; }\\n\"\n\t\"            if (found[name]) { continue; }\\n\"\n\t\"            found[name] = true;\\n\"\n\t\"            res.push(res.length === 0 ? name.substring(partial.length) : (first ? ' || ' : ' | ') + name);\\n\"\n\t\"            first = false;\\n\"\n\t\"        }\\n\"\n\t\"        obj = Object.getPrototypeOf(Object(obj));\\n\"\n\t\"    }\\n\"\n\t\"    return { hints: res.join(''), color: 35, bold: 1 };\\n\"\n\t\"})\";\n\nstatic duk_ret_t linenoise_add_completion(duk_context *ctx) {\n\tlinenoiseCompletions *lc;\n\n\tduk_push_current_function(ctx);\n\tduk_get_prop_string(ctx, -1, \"lc\");\n\tlc = duk_require_pointer(ctx, -1);\n\n\tlinenoiseAddCompletion(lc, duk_require_string(ctx, 0));\n\treturn 0;\n}\n\nstatic char *linenoise_hints(const char *buf, int *color, int *bold) {\n\tduk_context *ctx;\n\tduk_int_t rc;\n\n\tctx = completion_ctx;\n\tif (!ctx) {\n\t\treturn NULL;\n\t}\n\n\tduk_push_global_stash(ctx);\n\tduk_get_prop_string(ctx, -1, \"linenoiseHints\");\n\tif (!buf) {\n\t\tduk_push_undefined(ctx);\n\t} else {\n\t\tduk_push_string(ctx, buf);\n\t}\n\n\trc = duk_pcall(ctx, 1 /*nargs*/);  /* [ stash func ] -> [ stash result ] */\n\tif (rc != 0) {\n\t\tconst char *res;\n\t\tres = strdup(duk_safe_to_string(ctx, -1));\n\t\t*color = 31;  /* red */\n\t\t*bold = 1;\n\t\tduk_pop_2(ctx);\n\t\treturn (char *) (uintptr_t) res;  /* uintptr_t cast to avoid const discard warning. */\n\t}\n\n\tif (duk_is_object(ctx, -1)) {\n\t\tconst char *tmp;\n\t\tconst char *res = NULL;\n\n\t\tduk_get_prop_string(ctx, -1, \"hints\");\n\t\ttmp = duk_get_string(ctx, -1);\n\t\tif (tmp) {\n\t\t\tres = strdup(tmp);\n\t\t}\n\t\tduk_pop(ctx);\n\n\t\tduk_get_prop_string(ctx, -1, \"color\");\n\t\t*color = duk_to_int(ctx, -1);\n\t\tduk_pop(ctx);\n\n\t\tduk_get_prop_string(ctx, -1, \"bold\");\n\t\t*bold = duk_to_int(ctx, -1);\n\t\tduk_pop(ctx);\n\n\t\tduk_pop_2(ctx);\n\t\treturn (char *) (uintptr_t) res;  /* uintptr_t cast to avoid const discard warning. */\n\t}\n\n\tduk_pop_2(ctx);\n\treturn NULL;\n}\n\nstatic void linenoise_freehints(void *ptr) {\n#if 0\n\tprintf(\"free hint: %p\\n\", (void *) ptr);\n#endif\n\tfree(ptr);\n}\n\nstatic void linenoise_completion(const char *buf, linenoiseCompletions *lc) {\n\tduk_context *ctx;\n\tduk_int_t rc;\n\n\tctx = completion_ctx;\n\tif (!ctx) {\n\t\treturn;\n\t}\n\n\tduk_push_global_stash(ctx);\n\tduk_get_prop_string(ctx, -1, \"linenoiseCompletion\");\n\n\tif (!buf) {\n\t\tduk_push_undefined(ctx);\n\t} else {\n\t\tduk_push_string(ctx, buf);\n\t}\n\tduk_push_c_function(ctx, linenoise_add_completion, 2 /*nargs*/);\n\tduk_push_pointer(ctx, (void *) lc);\n\tduk_put_prop_string(ctx, -2, \"lc\");\n\n\trc = duk_pcall(ctx, 2 /*nargs*/);  /* [ stash func callback ] -> [ stash result ] */\n\tif (rc != 0) {\n\t\tlinenoiseAddCompletion(lc, duk_safe_to_string(ctx, -1));\n\t}\n\tduk_pop_2(ctx);\n}\n#endif  /* DUK_CMDLINE_LINENOISE_COMPLETION */\n\n/*\n *  Execute from file handle etc\n */\n\nstatic int handle_fh(duk_context *ctx, FILE *f, const char *filename, const char *bytecode_filename) {\n\tchar *buf = NULL;\n\tsize_t bufsz;\n\tsize_t bufoff;\n\tsize_t got;\n\tint rc;\n\tint retval = -1;\n\n\tbuf = (char *) malloc(1024);\n\tif (!buf) {\n\t\tgoto error;\n\t}\n\tbufsz = 1024;\n\tbufoff = 0;\n\n\t/* Read until EOF, avoid fseek/stat because it won't work with stdin. */\n\tfor (;;) {\n\t\tsize_t avail;\n\n\t\tavail = bufsz - bufoff;\n\t\tif (avail < 1024) {\n\t\t\tsize_t newsz;\n\t\t\tchar *buf_new;\n#if 0\n\t\t\tfprintf(stderr, \"resizing read buffer: %ld -> %ld\\n\", (long) bufsz, (long) (bufsz * 2));\n#endif\n\t\t\tnewsz = bufsz + (bufsz >> 2) + 1024;  /* +25% and some extra */\n\t\t\tbuf_new = (char *) realloc(buf, newsz);\n\t\t\tif (!buf_new) {\n\t\t\t\tgoto error;\n\t\t\t}\n\t\t\tbuf = buf_new;\n\t\t\tbufsz = newsz;\n\t\t}\n\n\t\tavail = bufsz - bufoff;\n#if 0\n\t\tfprintf(stderr, \"reading input: buf=%p bufsz=%ld bufoff=%ld avail=%ld\\n\",\n\t\t        (void *) buf, (long) bufsz, (long) bufoff, (long) avail);\n#endif\n\n\t\tgot = fread((void *) (buf + bufoff), (size_t) 1, avail, f);\n#if 0\n\t\tfprintf(stderr, \"got=%ld\\n\", (long) got);\n#endif\n\t\tif (got == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tbufoff += got;\n\n\t\t/* Emscripten specific: stdin EOF doesn't work as expected.\n\t\t * Instead, when 'emduk' is executed using Node.js, a file\n\t\t * piped to stdin repeats (!).  Detect that repeat and cut off\n\t\t * the stdin read.  Ensure the loop repeats enough times to\n\t\t * avoid detecting spurious loops.\n\t\t *\n\t\t * This only seems to work for inputs up to 256 bytes long.\n\t\t */\n#if defined(EMSCRIPTEN)\n\t\tif (bufoff >= 16384) {\n\t\t\tsize_t i, j, nloops;\n\t\t\tint looped = 0;\n\n\t\t\tfor (i = 16; i < bufoff / 8; i++) {\n\t\t\t\tint ok;\n\n\t\t\t\tnloops = bufoff / i;\n\t\t\t\tok = 1;\n\t\t\t\tfor (j = 1; j < nloops; j++) {\n\t\t\t\t\tif (memcmp((void *) buf, (void *) (buf + i * j), i) != 0) {\n\t\t\t\t\t\tok = 0;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (ok) {\n\t\t\t\t\tfprintf(stderr, \"emscripten workaround: detect looping at index %ld, verified with %ld loops\\n\", (long) i, (long) (nloops - 1));\n\t\t\t\t\tbufoff = i;\n\t\t\t\t\tlooped = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (looped) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n\tduk_push_string(ctx, bytecode_filename);\n\tduk_push_pointer(ctx, (void *) buf);\n\tduk_push_uint(ctx, (duk_uint_t) bufoff);\n\tduk_push_string(ctx, filename);\n\n\tinteractive_mode = 0;  /* global */\n\n\trc = duk_safe_call(ctx, wrapped_compile_execute, NULL /*udata*/, 4 /*nargs*/, 1 /*nret*/);\n\n#if defined(DUK_CMDLINE_LOWMEM)\n\tlowmem_clear_exec_timeout();\n#endif\n\n\tfree(buf);\n\tbuf = NULL;\n\n\tif (rc != DUK_EXEC_SUCCESS) {\n\t\tprint_pop_error(ctx, stderr);\n\t\tgoto error;\n\t} else {\n\t\tduk_pop(ctx);\n\t\tretval = 0;\n\t}\n\t/* fall thru */\n\n cleanup:\n\tif (buf) {\n\t\tfree(buf);\n\t\tbuf = NULL;\n\t}\n\treturn retval;\n\n error:\n\tfprintf(stderr, \"error in executing file %s\\n\", filename);\n\tfflush(stderr);\n\tgoto cleanup;\n}\n\nstatic int handle_file(duk_context *ctx, const char *filename, const char *bytecode_filename) {\n\tFILE *f = NULL;\n\tint retval;\n\tchar fnbuf[256];\n\n\t/* Example of sending an application specific debugger notification. */\n\tduk_push_string(ctx, \"DebuggerHandleFile\");\n\tduk_push_string(ctx, filename);\n\tduk_debugger_notify(ctx, 2);\n\n#if defined(EMSCRIPTEN)\n\tif (filename[0] == '/') {\n\t\tsnprintf(fnbuf, sizeof(fnbuf), \"%s\", filename);\n\t} else {\n\t\tsnprintf(fnbuf, sizeof(fnbuf), \"/working/%s\", filename);\n\t}\n#else\n\tsnprintf(fnbuf, sizeof(fnbuf), \"%s\", filename);\n#endif\n\tfnbuf[sizeof(fnbuf) - 1] = (char) 0;\n\n\tf = fopen(fnbuf, \"rb\");\n\tif (!f) {\n\t\tfprintf(stderr, \"failed to open source file: %s\\n\", filename);\n\t\tfflush(stderr);\n\t\tgoto error;\n\t}\n\n\tretval = handle_fh(ctx, f, filename, bytecode_filename);\n\n\tfclose(f);\n\treturn retval;\n\n error:\n\treturn -1;\n}\n\nstatic int handle_eval(duk_context *ctx, char *code) {\n\tint rc;\n\tint retval = -1;\n\n\tduk_push_pointer(ctx, (void *) code);\n\tduk_push_uint(ctx, (duk_uint_t) strlen(code));\n\tduk_push_string(ctx, \"eval\");\n\n\tinteractive_mode = 0;  /* global */\n\n\trc = duk_safe_call(ctx, wrapped_compile_execute, NULL /*udata*/, 3 /*nargs*/, 1 /*nret*/);\n\n#if defined(DUK_CMDLINE_LOWMEM)\n\tlowmem_clear_exec_timeout();\n#endif\n\n\tif (rc != DUK_EXEC_SUCCESS) {\n\t\tprint_pop_error(ctx, stderr);\n\t} else {\n\t\tduk_pop(ctx);\n\t\tretval = 0;\n\t}\n\n\treturn retval;\n}\n\n#if defined(DUK_CMDLINE_LINENOISE)\nstatic int handle_interactive(duk_context *ctx) {\n\tconst char *prompt = \"duk> \";\n\tchar *buffer = NULL;\n\tint retval = 0;\n\tint rc;\n\n\tlinenoiseSetMultiLine(1);\n\tlinenoiseHistorySetMaxLen(64);\n#if defined(DUK_CMDLINE_LINENOISE_COMPLETION)\n\tif (!no_auto_complete) {\n\t\tlinenoiseSetCompletionCallback(linenoise_completion);\n\t\tlinenoiseSetHintsCallback(linenoise_hints);\n\t\tlinenoiseSetFreeHintsCallback(linenoise_freehints);\n\t\tduk_push_global_stash(ctx);\n\t\tduk_eval_string(ctx, linenoise_completion_script);\n\t\tduk_put_prop_string(ctx, -2, \"linenoiseCompletion\");\n\t\tduk_eval_string(ctx, linenoise_hints_script);\n\t\tduk_put_prop_string(ctx, -2, \"linenoiseHints\");\n\t\tduk_pop(ctx);\n\t}\n#endif\n\n\tfor (;;) {\n\t\tif (buffer) {\n\t\t\tlinenoiseFree(buffer);\n\t\t\tbuffer = NULL;\n\t\t}\n\n#if defined(DUK_CMDLINE_LINENOISE_COMPLETION)\n\t\tcompletion_ctx = ctx;\n#endif\n\t\tbuffer = linenoise(prompt);\n#if defined(DUK_CMDLINE_LINENOISE_COMPLETION)\n\t\tcompletion_ctx = NULL;\n#endif\n\n\t\tif (!buffer) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (buffer && buffer[0] != (char) 0) {\n\t\t\tlinenoiseHistoryAdd(buffer);\n\t\t}\n\n\t\tduk_push_pointer(ctx, (void *) buffer);\n\t\tduk_push_uint(ctx, (duk_uint_t) strlen(buffer));\n\t\tduk_push_string(ctx, \"input\");\n\n\t\tinteractive_mode = 1;  /* global */\n\n\t\trc = duk_safe_call(ctx, wrapped_compile_execute, NULL /*udata*/, 3 /*nargs*/, 1 /*nret*/);\n\n#if defined(DUK_CMDLINE_LOWMEM)\n\t\tlowmem_clear_exec_timeout();\n#endif\n\n\t\tif (buffer) {\n\t\t\tlinenoiseFree(buffer);\n\t\t\tbuffer = NULL;\n\t\t}\n\n\t\tif (rc != DUK_EXEC_SUCCESS) {\n\t\t\t/* in interactive mode, write to stdout */\n\t\t\tprint_pop_error(ctx, stdout);\n\t\t\tretval = -1;  /* an error 'taints' the execution */\n\t\t} else {\n\t\t\tduk_pop(ctx);\n\t\t}\n\t}\n\n\tif (buffer) {\n\t\tlinenoiseFree(buffer);\n\t\tbuffer = NULL;\n\t}\n\n\treturn retval;\n}\n#else  /* DUK_CMDLINE_LINENOISE */\nstatic int handle_interactive(duk_context *ctx) {\n\tconst char *prompt = \"duk> \";\n\tchar *buffer = NULL;\n\tint retval = 0;\n\tint rc;\n\tint got_eof = 0;\n\n\tbuffer = (char *) malloc(LINEBUF_SIZE);\n\tif (!buffer) {\n\t\tfprintf(stderr, \"failed to allocated a line buffer\\n\");\n\t\tfflush(stderr);\n\t\tretval = -1;\n\t\tgoto done;\n\t}\n\n\twhile (!got_eof) {\n\t\tsize_t idx = 0;\n\n\t\tfwrite(prompt, 1, strlen(prompt), stdout);\n\t\tfflush(stdout);\n\n\t\tfor (;;) {\n\t\t\tint c = fgetc(stdin);\n\t\t\tif (c == EOF) {\n\t\t\t\tgot_eof = 1;\n\t\t\t\tbreak;\n\t\t\t} else if (c == '\\n') {\n\t\t\t\tbreak;\n\t\t\t} else if (idx >= LINEBUF_SIZE) {\n\t\t\t\tfprintf(stderr, \"line too long\\n\");\n\t\t\t\tfflush(stderr);\n\t\t\t\tretval = -1;\n\t\t\t\tgoto done;\n\t\t\t} else {\n\t\t\t\tbuffer[idx++] = (char) c;\n\t\t\t}\n\t\t}\n\n\t\tduk_push_pointer(ctx, (void *) buffer);\n\t\tduk_push_uint(ctx, (duk_uint_t) idx);\n\t\tduk_push_string(ctx, \"input\");\n\n\t\tinteractive_mode = 1;  /* global */\n\n\t\trc = duk_safe_call(ctx, wrapped_compile_execute, NULL /*udata*/, 3 /*nargs*/, 1 /*nret*/);\n\n#if defined(DUK_CMDLINE_LOWMEM)\n\t\tlowmem_clear_exec_timeout();\n#endif\n\n\t\tif (rc != DUK_EXEC_SUCCESS) {\n\t\t\t/* in interactive mode, write to stdout */\n\t\t\tprint_pop_error(ctx, stdout);\n\t\t\tretval = -1;  /* an error 'taints' the execution */\n\t\t} else {\n\t\t\tduk_pop(ctx);\n\t\t}\n\t}\n\n done:\n\tif (buffer) {\n\t\tfree(buffer);\n\t\tbuffer = NULL;\n\t}\n\n\treturn retval;\n}\n#endif  /* DUK_CMDLINE_LINENOISE */\n\n/*\n *  Simple file read/write bindings\n */\n\n#if defined(DUK_CMDLINE_FILEIO)\nstatic duk_ret_t fileio_read_file(duk_context *ctx) {\n\tconst char *fn;\n\tchar *buf;\n\tsize_t len;\n\tsize_t off;\n\tint rc;\n\tFILE *f;\n\n\tfn = duk_require_string(ctx, 0);\n\tf = fopen(fn, \"rb\");\n\tif (!f) {\n\t\t(void) duk_type_error(ctx, \"cannot open file %s for reading, errno %ld: %s\",\n\t\t                      fn, (long) errno, strerror(errno));\n\t}\n\n\trc = fseek(f, 0, SEEK_END);\n\tif (rc < 0) {\n\t\t(void) fclose(f);\n\t\t(void) duk_type_error(ctx, \"fseek() failed for %s, errno %ld: %s\",\n\t\t                      fn, (long) errno, strerror(errno));\n\t}\n\tlen = (size_t) ftell(f);\n\trc = fseek(f, 0, SEEK_SET);\n\tif (rc < 0) {\n\t\t(void) fclose(f);\n\t\t(void) duk_type_error(ctx, \"fseek() failed for %s, errno %ld: %s\",\n\t\t                      fn, (long) errno, strerror(errno));\n\t}\n\n\tbuf = (char *) duk_push_fixed_buffer(ctx, (duk_size_t) len);\n\tfor (off = 0; off < len;) {\n\t\tsize_t got;\n\t\tgot = fread((void *) (buf + off), 1, len - off, f);\n\t\tif (ferror(f)) {\n\t\t\t(void) fclose(f);\n\t\t\t(void) duk_type_error(ctx, \"error while reading %s\", fn);\n\t\t}\n\t\tif (got == 0) {\n\t\t\tif (feof(f)) {\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t(void) fclose(f);\n\t\t\t\t(void) duk_type_error(ctx, \"error while reading %s\", fn);\n\t\t\t}\n\t\t}\n\t\toff += got;\n\t}\n\n\tif (f) {\n\t\t(void) fclose(f);\n\t}\n\n\treturn 1;\n}\n\nstatic duk_ret_t fileio_write_file(duk_context *ctx) {\n\tconst char *fn;\n\tconst char *buf;\n\tsize_t len;\n\tsize_t off;\n\tFILE *f;\n\n\tfn = duk_require_string(ctx, 0);\n\tf = fopen(fn, \"wb\");\n\tif (!f) {\n\t\t(void) duk_type_error(ctx, \"cannot open file %s for writing, errno %ld: %s\",\n\t\t          fn, (long) errno, strerror(errno));\n\t}\n\n\tlen = 0;\n\tbuf = (char *) duk_require_buffer_data(ctx, 1, &len);\n\tfor (off = 0; off < len;) {\n\t\tsize_t got;\n\t\tgot = fwrite((const void *) (buf + off), 1, len - off, f);\n\t\tif (ferror(f)) {\n\t\t\t(void) fclose(f);\n\t\t\t(void) duk_type_error(ctx, \"error while writing %s\", fn);\n\t\t}\n\t\tif (got == 0) {\n\t\t\t(void) fclose(f);\n\t\t\t(void) duk_type_error(ctx, \"error while writing %s\", fn);\n\t\t}\n\t\toff += got;\n\t}\n\n\tif (f) {\n\t\t(void) fclose(f);\n\t}\n\n\treturn 0;\n}\n#endif  /* DUK_CMDLINE_FILEIO */\n\n/*\n *  String.fromBufferRaw()\n */\n\nstatic duk_ret_t string_frombufferraw(duk_context *ctx) {\n\tduk_buffer_to_string(ctx, 0);\n\treturn 1;\n}\n\n/*\n *  Duktape heap lifecycle\n */\n\n#if defined(DUK_CMDLINE_DEBUGGER_SUPPORT)\nstatic duk_idx_t debugger_request(duk_context *ctx, void *udata, duk_idx_t nvalues) {\n\tconst char *cmd;\n\tint i;\n\n\t(void) udata;\n\n\tif (nvalues < 1) {\n\t\tduk_push_string(ctx, \"missing AppRequest argument(s)\");\n\t\treturn -1;\n\t}\n\n\tcmd = duk_get_string(ctx, -nvalues + 0);\n\n\tif (cmd && strcmp(cmd, \"CommandLine\") == 0) {\n\t\tif (!duk_check_stack(ctx, main_argc)) {\n\t\t\t/* Callback should avoid errors for now, so use\n\t\t\t * duk_check_stack() rather than duk_require_stack().\n\t\t\t */\n\t\t\tduk_push_string(ctx, \"failed to extend stack\");\n\t\t\treturn -1;\n\t\t}\n\t\tfor (i = 0; i < main_argc; i++) {\n\t\t\tduk_push_string(ctx, main_argv[i]);\n\t\t}\n\t\treturn main_argc;\n\t}\n\tduk_push_sprintf(ctx, \"command not supported\");\n\treturn -1;\n}\n\nstatic void debugger_detached(duk_context *ctx, void *udata) {\n\tfprintf(stderr, \"Debugger detached, udata: %p\\n\", (void *) udata);\n\tfflush(stderr);\n\n\t/* Ensure socket is closed even when detach is initiated by Duktape\n\t * rather than debug client.\n\t */\n\tduk_trans_socket_finish();\n\n\tif (debugger_reattach) {\n\t\t/* For automatic reattach testing. */\n\t\tduk_trans_socket_init();\n\t\tduk_trans_socket_waitconn();\n\t\tfprintf(stderr, \"Debugger reconnected, call duk_debugger_attach()\\n\");\n\t\tfflush(stderr);\n#if 0\n\t\t/* This is not necessary but should be harmless. */\n\t\tduk_debugger_detach(ctx);\n#endif\n\t\tduk_debugger_attach(ctx,\n\t\t                    duk_trans_socket_read_cb,\n\t\t                    duk_trans_socket_write_cb,\n\t\t                    duk_trans_socket_peek_cb,\n\t\t                    duk_trans_socket_read_flush_cb,\n\t\t                    duk_trans_socket_write_flush_cb,\n\t\t                    debugger_request,\n\t\t                    debugger_detached,\n\t\t                    NULL);\n\t}\n}\n#endif\n\n#define  ALLOC_DEFAULT  0\n#define  ALLOC_LOGGING  1\n#define  ALLOC_TORTURE  2\n#define  ALLOC_HYBRID   3\n#define  ALLOC_LOWMEM   4\n\nstatic duk_context *create_duktape_heap(int alloc_provider, int debugger, int lowmem_log) {\n\tduk_context *ctx;\n\n\t(void) lowmem_log;  /* suppress warning */\n\n\tctx = NULL;\n\tif (!ctx && alloc_provider == ALLOC_LOGGING) {\n#if defined(DUK_CMDLINE_ALLOC_LOGGING)\n\t\tctx = duk_create_heap(duk_alloc_logging,\n\t\t                      duk_realloc_logging,\n\t\t                      duk_free_logging,\n\t\t                      (void *) 0xdeadbeef,\n\t\t                      cmdline_fatal_handler);\n#else\n\t\tfprintf(stderr, \"Warning: option --alloc-logging ignored, no logging allocator support\\n\");\n\t\tfflush(stderr);\n#endif\n\t}\n\tif (!ctx && alloc_provider == ALLOC_TORTURE) {\n#if defined(DUK_CMDLINE_ALLOC_TORTURE)\n\t\tctx = duk_create_heap(duk_alloc_torture,\n\t\t                      duk_realloc_torture,\n\t\t                      duk_free_torture,\n\t\t                      (void *) 0xdeadbeef,\n\t\t                      cmdline_fatal_handler);\n#else\n\t\tfprintf(stderr, \"Warning: option --alloc-torture ignored, no torture allocator support\\n\");\n\t\tfflush(stderr);\n#endif\n\t}\n\tif (!ctx && alloc_provider == ALLOC_HYBRID) {\n#if defined(DUK_CMDLINE_ALLOC_HYBRID)\n\t\tvoid *udata = duk_alloc_hybrid_init();\n\t\tif (!udata) {\n\t\t\tfprintf(stderr, \"Failed to init hybrid allocator\\n\");\n\t\t\tfflush(stderr);\n\t\t} else {\n\t\t\tctx = duk_create_heap(duk_alloc_hybrid,\n\t\t\t                      duk_realloc_hybrid,\n\t\t\t                      duk_free_hybrid,\n\t\t\t                      udata,\n\t\t\t                      cmdline_fatal_handler);\n\t\t}\n#else\n\t\tfprintf(stderr, \"Warning: option --alloc-hybrid ignored, no hybrid allocator support\\n\");\n\t\tfflush(stderr);\n#endif\n\t}\n\tif (!ctx && alloc_provider == ALLOC_LOWMEM) {\n#if defined(DUK_CMDLINE_LOWMEM)\n\t\tlowmem_init();\n\n\t\tctx = duk_create_heap(\n\t\t\tlowmem_log ? lowmem_alloc_wrapped : duk_alloc_pool,\n\t\t\tlowmem_log ? lowmem_realloc_wrapped : duk_realloc_pool,\n\t\t\tlowmem_log ? lowmem_free_wrapped : duk_free_pool,\n\t\t\t(void *) lowmem_pool_ptr,\n\t\t\tcmdline_fatal_handler);\n#else\n\t\tfprintf(stderr, \"Warning: option --alloc-ajsheap ignored, no ajsheap allocator support\\n\");\n\t\tfflush(stderr);\n#endif\n\t}\n\tif (!ctx && alloc_provider == ALLOC_DEFAULT) {\n\t\tctx = duk_create_heap(NULL, NULL, NULL, NULL, cmdline_fatal_handler);\n\t}\n\n\tif (!ctx) {\n\t\tfprintf(stderr, \"Failed to create Duktape heap\\n\");\n\t\tfflush(stderr);\n\t\texit(1);\n\t}\n\n#if defined(DUK_CMDLINE_LOWMEM)\n\tif (alloc_provider == ALLOC_LOWMEM) {\n\t\tfprintf(stderr, \"*** pool dump after heap creation ***\\n\");\n\t\tlowmem_dump();\n\t}\n#endif\n\n#if defined(DUK_CMDLINE_LOWMEM)\n\tif (alloc_provider == ALLOC_LOWMEM) {\n\t\tlowmem_register(ctx);\n\t}\n#endif\n\n\t/* Register print() and alert() (removed in Duktape 2.x). */\n#if defined(DUK_CMDLINE_PRINTALERT_SUPPORT)\n\tduk_print_alert_init(ctx, 0 /*flags*/);\n#endif\n\n\t/* Register String.fromBufferRaw() which does a 1:1 buffer-to-string\n\t * coercion needed by testcases.  String.fromBufferRaw() is -not- a\n\t * default built-in!  For stripped builds the 'String' built-in\n\t * doesn't exist and we create it here; for ROM builds it may be\n\t * present but unwritable (which is ignored).\n\t */\n\tduk_eval_string(ctx,\n\t\t\"(function(v){\"\n\t\t    \"if (typeof String === 'undefined') { String = {}; }\"\n\t\t    \"Object.defineProperty(String, 'fromBufferRaw', {value:v, configurable:true});\"\n\t\t\"})\");\n\tduk_push_c_function(ctx, string_frombufferraw, 1 /*nargs*/);\n\t(void) duk_pcall(ctx, 1);\n\tduk_pop(ctx);\n\n\t/* Register console object. */\n#if defined(DUK_CMDLINE_CONSOLE_SUPPORT)\n\tduk_console_init(ctx, DUK_CONSOLE_FLUSH /*flags*/);\n#endif\n\n\t/* Register Duktape.Logger (removed in Duktape 2.x). */\n#if defined(DUK_CMDLINE_LOGGING_SUPPORT)\n\tduk_logging_init(ctx, 0 /*flags*/);\n#endif\n\n\t/* Register require() (removed in Duktape 2.x). */\n#if defined(DUK_CMDLINE_MODULE_SUPPORT)\n\tduk_module_duktape_init(ctx);\n#endif\n\n\t/* Register CBOR. */\n#if defined(DUK_CMDLINE_CBOR_SUPPORT)\n\tduk_cbor_init(ctx, 0 /*flags*/);\n#endif\n\n\t/* Trivial readFile/writeFile bindings for testing. */\n#if defined(DUK_CMDLINE_FILEIO)\n\tduk_push_c_function(ctx, fileio_read_file, 1 /*nargs*/);\n\tduk_put_global_string(ctx, \"readFile\");\n\tduk_push_c_function(ctx, fileio_write_file, 2 /*nargs*/);\n\tduk_put_global_string(ctx, \"writeFile\");\n#endif\n\n\t/* Stash a formatting function for evaluation results. */\n\tduk_push_global_stash(ctx);\n\tduk_eval_string(ctx,\n\t\t\"(function (E) {\"\n\t\t    \"return function format(v){\"\n\t\t        \"try{\"\n\t\t            \"return E('jx',v);\"\n\t\t        \"}catch(e){\"\n\t\t            \"return ''+v;\"\n\t\t        \"}\"\n\t\t    \"};\"\n\t\t\"})(Duktape.enc)\");\n\tduk_put_prop_string(ctx, -2, \"dukFormat\");\n\tduk_pop(ctx);\n\n\tif (debugger) {\n#if defined(DUK_CMDLINE_DEBUGGER_SUPPORT)\n\t\tfprintf(stderr, \"Debugger enabled, create socket and wait for connection\\n\");\n\t\tfflush(stderr);\n\t\tduk_trans_socket_init();\n\t\tduk_trans_socket_waitconn();\n\t\tfprintf(stderr, \"Debugger connected, call duk_debugger_attach() and then execute requested file(s)/eval\\n\");\n\t\tfflush(stderr);\n\t\tduk_debugger_attach(ctx,\n\t\t                    duk_trans_socket_read_cb,\n\t\t                    duk_trans_socket_write_cb,\n\t\t                    duk_trans_socket_peek_cb,\n\t\t                    duk_trans_socket_read_flush_cb,\n\t\t                    duk_trans_socket_write_flush_cb,\n\t\t                    debugger_request,\n\t\t                    debugger_detached,\n\t\t                    NULL);\n#else\n\t\tfprintf(stderr, \"Warning: option --debugger ignored, no debugger support\\n\");\n\t\tfflush(stderr);\n#endif\n\t}\n\n#if 0\n\t/* Manual test for duk_debugger_cooperate() */\n\t{\n\t\tfor (i = 0; i < 60; i++) {\n\t\t\tprintf(\"cooperate: %d\\n\", i);\n\t\t\tusleep(1000000);\n\t\t\tduk_debugger_cooperate(ctx);\n\t\t}\n\t}\n#endif\n\n\treturn ctx;\n}\n\nstatic void destroy_duktape_heap(duk_context *ctx, int alloc_provider) {\n\t(void) alloc_provider;\n\n#if defined(DUK_CMDLINE_LOWMEM)\n\tif (alloc_provider == ALLOC_LOWMEM) {\n\t\tfprintf(stderr, \"*** pool dump before duk_destroy_heap(), before forced gc ***\\n\");\n\t\tlowmem_dump();\n\n\t\tduk_gc(ctx, 0);\n\n\t\tfprintf(stderr, \"*** pool dump before duk_destroy_heap(), after forced gc ***\\n\");\n\t\tlowmem_dump();\n\t}\n#endif\n\n\tif (ctx) {\n\t\tduk_destroy_heap(ctx);\n\t}\n\n#if defined(DUK_CMDLINE_LOWMEM)\n\tif (alloc_provider == ALLOC_LOWMEM) {\n\t\tfprintf(stderr, \"*** pool dump after duk_destroy_heap() (should have zero allocs) ***\\n\");\n\t\tlowmem_dump();\n\t}\n\tlowmem_free();\n#endif\n}\n\n/*\n *  Main\n */\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx = NULL;\n\tint retval = 0;\n\tint have_files = 0;\n\tint have_eval = 0;\n\tint interactive = 0;\n\tint memlimit_high = 1;\n\tint alloc_provider = ALLOC_DEFAULT;\n\tint lowmem_log = 0;\n\tint debugger = 0;\n\tint recreate_heap = 0;\n\tint no_heap_destroy = 0;\n\tint verbose = 0;\n\tint run_stdin = 0;\n\tconst char *compile_filename = NULL;\n\tint i;\n\n\tmain_argc = argc;\n\tmain_argv = (char **) argv;\n\n#if defined(EMSCRIPTEN)\n\t/* Try to use NODEFS to provide access to local files.  Mount the\n\t * CWD as /working, and then prepend \"/working/\" to relative native\n\t * paths in file calls to get something that works reasonably for\n\t * relative paths.  Emscripten doesn't support replacing virtual\n\t * \"/\" with host \"/\" (the default MEMFS at \"/\" can't be unmounted)\n\t * but we can mount \"/tmp\" as host \"/tmp\" to allow testcase runs.\n\t *\n\t * https://kripken.github.io/emscripten-site/docs/api_reference/Filesystem-API.html#filesystem-api-nodefs\n\t * https://github.com/kripken/emscripten/blob/master/tests/fs/test_nodefs_rw.c\n\t */\n\tEM_ASM(\n\t\t/* At the moment it's not possible to replace the default MEMFS mounted at '/':\n\t\t * https://github.com/kripken/emscripten/issues/2040\n\t\t * https://github.com/kripken/emscripten/blob/incoming/src/library_fs.js#L1341-L1358\n\t\t */\n\t\t/*\n\t\ttry {\n\t\t\tFS.unmount(\"/\");\n\t\t} catch (e) {\n\t\t\tconsole.log(\"Failed to unmount default '/' MEMFS mount: \" + e);\n\t\t}\n\t\t*/\n\t\ttry {\n\t\t\tFS.mkdir(\"/working\");\n\t\t\tFS.mount(NODEFS, { root: \".\" }, \"/working\");\n\t\t} catch (e) {\n\t\t\tconsole.log(\"Failed to mount NODEFS /working: \" + e);\n\t\t}\n\t\t/* A virtual '/tmp' exists by default:\n\t\t * https://gist.github.com/evanw/e6be28094f34451bd5bd#file-temp-js-L3806-L3809\n\t\t */\n\t\t/*\n\t\ttry {\n\t\t\tFS.mkdir(\"/tmp\");\n\t\t} catch (e) {\n\t\t\tconsole.log(\"Failed to create virtual /tmp: \" + e);\n\t\t}\n\t\t*/\n\t\ttry {\n\t\t\tFS.mount(NODEFS, { root: \"/tmp\" }, \"/tmp\");\n\t\t} catch (e) {\n\t\t\tconsole.log(\"Failed to mount NODEFS /tmp: \" + e);\n\t\t}\n\t);\n#endif  /* EMSCRIPTEN */\n\n#if defined(DUK_CMDLINE_LOWMEM)\n\talloc_provider = ALLOC_LOWMEM;\n#endif\n\t(void) lowmem_log;\n\n\t/*\n\t *  Signal handling setup\n\t */\n\n#if defined(DUK_CMDLINE_SIGNAL)\n\tset_sigint_handler();\n\n\t/* This is useful at the global level; libraries should avoid SIGPIPE though */\n\t/*signal(SIGPIPE, SIG_IGN);*/\n#endif\n\n\t/*\n\t *  Parse options\n\t */\n\n\tfor (i = 1; i < argc; i++) {\n\t\tchar *arg = argv[i];\n\t\tif (!arg) {\n\t\t\tgoto usage;\n\t\t}\n\t\tif (strcmp(arg, \"--restrict-memory\") == 0) {\n\t\t\tmemlimit_high = 0;\n\t\t} else if (strcmp(arg, \"-i\") == 0) {\n\t\t\tinteractive = 1;\n\t\t} else if (strcmp(arg, \"-b\") == 0) {\n\t\t\tallow_bytecode = 1;\n\t\t} else if (strcmp(arg, \"-c\") == 0) {\n\t\t\tif (i == argc - 1) {\n\t\t\t\tgoto usage;\n\t\t\t}\n\t\t\ti++;\n\t\t\tcompile_filename = argv[i];\n\t\t} else if (strcmp(arg, \"-e\") == 0) {\n\t\t\thave_eval = 1;\n\t\t\tif (i == argc - 1) {\n\t\t\t\tgoto usage;\n\t\t\t}\n\t\t\ti++;  /* skip code */\n\t\t} else if (strcmp(arg, \"--alloc-default\") == 0) {\n\t\t\talloc_provider = ALLOC_DEFAULT;\n\t\t} else if (strcmp(arg, \"--alloc-logging\") == 0) {\n\t\t\talloc_provider = ALLOC_LOGGING;\n\t\t} else if (strcmp(arg, \"--alloc-torture\") == 0) {\n\t\t\talloc_provider = ALLOC_TORTURE;\n\t\t} else if (strcmp(arg, \"--alloc-hybrid\") == 0) {\n\t\t\talloc_provider = ALLOC_HYBRID;\n\t\t} else if (strcmp(arg, \"--alloc-lowmem\") == 0) {\n\t\t\talloc_provider = ALLOC_LOWMEM;\n\t\t} else if (strcmp(arg, \"--lowmem-log\") == 0) {\n\t\t\tlowmem_log = 1;\n\t\t} else if (strcmp(arg, \"--debugger\") == 0) {\n\t\t\tdebugger = 1;\n#if defined(DUK_CMDLINE_DEBUGGER_SUPPORT)\n\t\t} else if (strcmp(arg, \"--reattach\") == 0) {\n\t\t\tdebugger_reattach = 1;\n#endif\n\t\t} else if (strcmp(arg, \"--recreate-heap\") == 0) {\n\t\t\trecreate_heap = 1;\n\t\t} else if (strcmp(arg, \"--no-heap-destroy\") == 0) {\n\t\t\tno_heap_destroy = 1;\n\t\t} else if (strcmp(arg, \"--no-auto-complete\") == 0) {\n#if defined(DUK_CMDLINE_LINENOISE_COMPLETION)\n\t\t\tno_auto_complete = 1;\n#endif\n\t\t} else if (strcmp(arg, \"--verbose\") == 0) {\n\t\t\tverbose = 1;\n\t\t} else if (strcmp(arg, \"--run-stdin\") == 0) {\n\t\t\trun_stdin = 1;\n\t\t} else if (strlen(arg) >= 1 && arg[0] == '-') {\n\t\t\tgoto usage;\n\t\t} else {\n\t\t\thave_files = 1;\n\t\t}\n\t}\n\tif (!have_files && !have_eval && !run_stdin) {\n\t\tinteractive = 1;\n\t}\n\n\t/*\n\t *  Memory limit\n\t */\n\n#if defined(DUK_CMDLINE_RLIMIT)\n\tset_resource_limits(memlimit_high ? MEM_LIMIT_HIGH : MEM_LIMIT_NORMAL);\n#else\n\tif (memlimit_high == 0) {\n\t\tfprintf(stderr, \"Warning: option --restrict-memory ignored, no rlimit support\\n\");\n\t\tfflush(stderr);\n\t}\n#endif\n\n\t/*\n\t *  Create heap\n\t */\n\n\tctx = create_duktape_heap(alloc_provider, debugger, lowmem_log);\n\n\t/*\n\t *  Execute any argument file(s)\n\t */\n\n\tfor (i = 1; i < argc; i++) {\n\t\tchar *arg = argv[i];\n\t\tif (!arg) {\n\t\t\tcontinue;\n\t\t} else if (strlen(arg) == 2 && strcmp(arg, \"-e\") == 0) {\n\t\t\t/* Here we know the eval arg exists but check anyway */\n\t\t\tif (i == argc - 1) {\n\t\t\t\tretval = 1;\n\t\t\t\tgoto cleanup;\n\t\t\t}\n\t\t\tif (handle_eval(ctx, argv[i + 1]) != 0) {\n\t\t\t\tretval = 1;\n\t\t\t\tgoto cleanup;\n\t\t\t}\n\t\t\ti++;  /* skip code */\n\t\t\tcontinue;\n\t\t} else if (strlen(arg) == 2 && strcmp(arg, \"-c\") == 0) {\n\t\t\ti++;  /* skip filename */\n\t\t\tcontinue;\n\t\t} else if (strlen(arg) >= 1 && arg[0] == '-') {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (verbose) {\n\t\t\tfprintf(stderr, \"*** Executing file: %s\\n\", arg);\n\t\t\tfflush(stderr);\n\t\t}\n\n\t\tif (handle_file(ctx, arg, compile_filename) != 0) {\n\t\t\tretval = 1;\n\t\t\tgoto cleanup;\n\t\t}\n\n\t\tif (recreate_heap) {\n\t\t\tif (verbose) {\n\t\t\t\tfprintf(stderr, \"*** Recreating heap...\\n\");\n\t\t\t\tfflush(stderr);\n\t\t\t}\n\n\t\t\tdestroy_duktape_heap(ctx, alloc_provider);\n\t\t\tctx = create_duktape_heap(alloc_provider, debugger, lowmem_log);\n\t\t}\n\t}\n\n\tif (run_stdin) {\n\t\t/* Running stdin like a full file (reading all lines before\n\t\t * compiling) is useful with emduk:\n\t\t * cat test.js | ./emduk --run-stdin\n\t\t */\n\t\tif (handle_fh(ctx, stdin, \"stdin\", compile_filename) != 0) {\n\t\t\tretval = 1;\n\t\t\tgoto cleanup;\n\t\t}\n\n\t\tif (recreate_heap) {\n\t\t\tif (verbose) {\n\t\t\t\tfprintf(stderr, \"*** Recreating heap...\\n\");\n\t\t\t\tfflush(stderr);\n\t\t\t}\n\n\t\t\tdestroy_duktape_heap(ctx, alloc_provider);\n\t\t\tctx = create_duktape_heap(alloc_provider, debugger, lowmem_log);\n\t\t}\n\t}\n\n\t/*\n\t *  Enter interactive mode if options indicate it\n\t */\n\n\tif (interactive) {\n\t\tprint_greet_line();\n\t\tif (handle_interactive(ctx) != 0) {\n\t\t\tretval = 1;\n\t\t\tgoto cleanup;\n\t\t}\n\t}\n\n\t/*\n\t *  Cleanup and exit\n\t */\n\n cleanup:\n\tif (interactive) {\n\t\tfprintf(stderr, \"Cleaning up...\\n\");\n\t\tfflush(stderr);\n\t}\n\n\tif (ctx && no_heap_destroy) {\n\t\tduk_gc(ctx, 0);\n\t}\n\tif (ctx && !no_heap_destroy) {\n\t\tdestroy_duktape_heap(ctx, alloc_provider);\n\t}\n\tctx = NULL;\n\n\treturn retval;\n\n\t/*\n\t *  Usage\n\t */\n\n usage:\n\tfprintf(stderr, \"Usage: duk [options] [<filenames>]\\n\"\n\t                \"\\n\"\n\t                \"   -i                 enter interactive mode after executing argument file(s) / eval code\\n\"\n\t                \"   -e CODE            evaluate code\\n\"\n\t                \"   -c FILE            compile into bytecode and write to FILE (use with only one file argument)\\n\"\n\t                \"   -b                 allow bytecode input files (memory unsafe for invalid bytecode)\\n\"\n\t                \"   --run-stdin        treat stdin like a file, i.e. compile full input (not line by line)\\n\"\n\t                \"   --verbose          verbose messages to stderr\\n\"\n\t                \"   --restrict-memory  use lower memory limit (used by test runner)\\n\"\n\t                \"   --alloc-default    use Duktape default allocator\\n\"\n#if defined(DUK_CMDLINE_ALLOC_LOGGING)\n\t                \"   --alloc-logging    use logging allocator, write alloc log to /tmp/duk-alloc-log.txt\\n\"\n#endif\n#if defined(DUK_CMDLINE_ALLOC_TORTURE)\n\t                \"   --alloc-torture    use torture allocator\\n\"\n#endif\n#if defined(DUK_CMDLINE_ALLOC_HYBRID)\n\t                \"   --alloc-hybrid     use hybrid allocator\\n\"\n#endif\n#if defined(DUK_CMDLINE_LOWMEM)\n\t                \"   --alloc-lowmem     use pooled allocator (enabled by default for duk-low)\\n\"\n\t                \"   --lowmem-log       write alloc log to /tmp/lowmem-alloc-log.txt\\n\"\n#endif\n#if defined(DUK_CMDLINE_DEBUGGER_SUPPORT)\n\t                \"   --debugger         start example debugger\\n\"\n\t                \"   --reattach         automatically reattach debugger on detach\\n\"\n#endif\n\t                \"   --recreate-heap    recreate heap after every file\\n\"\n\t                \"   --no-heap-destroy  force GC, but don't destroy heap at end (leak testing)\\n\"\n#if defined(DUK_CMDLINE_LINENOISE_COMPLETION)\n\t                \"   --no-auto-complete disable linenoise auto completion\\n\"\n#else\n\t                \"   --no-auto-complete disable linenoise auto completion [ignored, not supported]\\n\"\n#endif\n\t                \"\\n\"\n\t                \"If <filename> is omitted, interactive mode is started automatically.\\n\"\n\t                \"\\n\"\n\t                \"Input files can be either ECMAScript source files or bytecode files\\n\"\n\t                \"(if -b is given).  Bytecode files are not validated prior to loading,\\n\"\n\t                \"so that incompatible or crafted files can cause memory unsafe behavior.\\n\"\n\t                \"See discussion in\\n\"\n\t                \"https://github.com/svaarala/duktape/blob/master/doc/bytecode.rst#memory-safety-and-bytecode-validation.\\n\");\n\tfflush(stderr);\n\texit(1);\n}\n\n/* Example of how a native stack check can be implemented in a platform\n * specific manner for DUK_USE_NATIVE_STACK_CHECK().  This example is for\n * (Linux) pthreads, and rejects further native recursion if less than\n * 16kB stack is left (conservative).\n */\n#if defined(DUK_CMDLINE_PTHREAD_STACK_CHECK)\nint duk_cmdline_stack_check(void) {\n\tpthread_attr_t attr;\n\tvoid *stackaddr;\n\tsize_t stacksize;\n\tchar *ptr;\n\tchar *ptr_base;\n\tptrdiff_t remain;\n\n\t(void) pthread_getattr_np(pthread_self(), &attr);\n\t(void) pthread_attr_getstack(&attr, &stackaddr, &stacksize);\n\tptr = (char *) &stacksize;  /* Rough estimate of current stack pointer. */\n\tptr_base = (char *) stackaddr;\n\tremain = ptr - ptr_base;\n\n\t/* HIGH ADDR   -----  stackaddr + stacksize\n\t *               |\n\t *               |  stack growth direction\n\t *               v -- ptr, approximate used size\n\t *\n\t * LOW ADDR    -----  ptr_base, end of stack (lowest address)\n\t */\n\n#if 0\n\tfprintf(stderr, \"STACK CHECK: stackaddr=%p, stacksize=%ld, ptr=%p, remain=%ld\\n\",\n\t        stackaddr, (long) stacksize, (void *) ptr, (long) remain);\n\tfflush(stderr);\n#endif\n\tif (remain < 16384) {\n\t\treturn 1;\n\t}\n\treturn 0;  /* 0: no error, != 0: throw RangeError */\n}\n#else\nint duk_cmdline_stack_check(void) {\n\treturn 0;\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/examples/cmdline/duk_cmdline.h",
    "content": "#if !defined(DUK_CMDLINE_H_INCLUDED)\n#define DUK_CMDLINE_H_INCLUDED\n\n/* Defined in duk_cmdline_lowmem.c. */\nextern void *lowmem_pool_ptr;\nvoid lowmem_init(void);\nvoid lowmem_free(void);\nvoid lowmem_dump(void);\nvoid lowmem_register(duk_context *ctx);\nvoid lowmem_start_exec_timeout(void);\nvoid lowmem_clear_exec_timeout(void);\nvoid *lowmem_alloc_wrapped(void *udata, duk_size_t size);\nvoid *lowmem_realloc_wrapped(void *udata, void *ptr, duk_size_t size);\nvoid lowmem_free_wrapped(void *udata, void *ptr);\n\n#endif  /* DUK_CMDLINE_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/examples/cmdline/duk_cmdline_lowmem.c",
    "content": "/*\n *  Examples for low memory techniques\n */\n\n#if defined(DUK_CMDLINE_LOWMEM)\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include \"duktape.h\"\n#include \"duk_cmdline.h\"\n#include \"duk_alloc_pool.h\"\n\n#if defined(DUK_USE_ROM_OBJECTS) && defined(DUK_USE_HEAPPTR16)\n/* Pointer compression with ROM strings/objects:\n *\n * For now, use DUK_USE_ROM_OBJECTS to signal the need for compressed ROM\n * pointers.  DUK_USE_ROM_PTRCOMP_FIRST is provided for the ROM pointer\n * compression range minimum to avoid duplication in user code.\n */\n#if 0  /* This extern declaration is provided by duktape.h, array provided by duktape.c. */\nextern const void * const duk_rom_compressed_pointers[];\n#endif\nstatic const void *duk__romptr_low = NULL;\nstatic const void *duk__romptr_high = NULL;\n#define DUK__ROMPTR_COMPRESSION\n#define DUK__ROMPTR_FIRST ((duk_uint_t) DUK_USE_ROM_PTRCOMP_FIRST)\n#endif\n\n#define LOWMEM_NUM_POOLS 28\n\n#define LOWMEM_HEAP_SIZE (255 * 1024)\n\nstatic const duk_pool_config lowmem_config[LOWMEM_NUM_POOLS] = {\n\t{ 8,      10 * 8,     0 },\n\t{ 12,     600 * 12,   0 },\n\t{ 16,     300 * 16,   0 },\n\t{ 20,     300 * 20,   0 },\n\t{ 24,     300 * 24,   0 },\n\t{ 28,     250 * 28,   0 },\n\t{ 32,     150 * 32,   0 },\n\t{ 40,     150 * 40,   0 },\n\t{ 48,     50 * 48,    0 },\n\t{ 52,     50 * 52,    0 },\n\t{ 56,     50 * 56,    0 },\n\t{ 60,     50 * 60,    0 },\n\t{ 64,     50 * 64,    0 },\n\t{ 96,     50 * 96,    0 },\n\t{ 196,    0,          196 },  /* duk_heap, with heap ptr compression, ROM strings+objects */\n\t{ 232,    0,          232 },  /* duk_hthread, with heap ptr compression, ROM strings+objects */\n\t{ 256,    16 * 256,   0 },\n\t{ 288,    1 * 288,    0 },\n\t{ 320,    1 * 320,    0 },\n\t{ 400,    0,          400 },  /* duk_hthread, with heap ptr compression, RAM strings+objects */\n\t{ 520,    0,          520 },  /* duk_heap, with heap ptr compression, RAM strings+objects */\n\t{ 512,    16 * 512,   0 },\n\t{ 768,    0,          768 },  /* initial value stack for packed duk_tval */\n\t{ 1024,   6 * 1024,   0 },\n\t{ 2048,   5 * 2048,   0 },\n\t{ 4096,   3 * 4096,   0 },\n\t{ 8192,   3 * 8192,   0 },\n\t{ 16384,  1 * 16384,  0 },\n};\n\nstatic duk_pool_state lowmem_state[LOWMEM_NUM_POOLS];\n\nstatic duk_pool_global lowmem_global;\n\nvoid *lowmem_pool_ptr = NULL;\n\nuint8_t *lowmem_ram = NULL;\n\nstatic void *duk__lose_const(const void *ptr) {\n\t/* Somewhat portable way of losing a const without warnings.\n\t * Another approach is to cast through intptr_t, but that\n\t * type is not always available.\n\t */\n\tunion {\n\t\tconst void *p;\n\t\tvoid *q;\n\t} u;\n\tu.p = ptr;\n\treturn u.q;\n}\n\nstatic void duk__safe_print_chars(const char *p, duk_size_t len, int until_nul) {\n\tduk_size_t i;\n\n\tfprintf(stderr, \"\\\"\");\n\tfor (i = 0; i < len; i++) {\n\t\tunsigned char x = (unsigned char) p[i];\n\t\tif (until_nul && x == 0U) {\n\t\t\tbreak;\n\t\t}\n\t\tif (x < 0x20 || x >= 0x7e || x == '\"' || x == '\\'' || x == '\\\\') {\n\t\t\tfprintf(stderr, \"\\\\x%02x\", (int) x);\n\t\t} else {\n\t\t\tfprintf(stderr, \"%c\", (char) x);\n\t\t}\n\t}\n\tfprintf(stderr, \"\\\"\");\n}\n\n\nvoid lowmem_init(void) {\n\tvoid *ptr;\n\n\tlowmem_ram = (uint8_t *) malloc(LOWMEM_HEAP_SIZE);\n\tif (lowmem_ram == NULL) {\n\t\tfprintf(stderr, \"Failed to allocate lowmem heap\\n\");\n\t\tfflush(stderr);\n\t\texit(1);\n\t}\n\n\tptr = duk_alloc_pool_init((char *) lowmem_ram,\n\t                          LOWMEM_HEAP_SIZE,\n\t                          lowmem_config,\n\t                          lowmem_state,\n\t                          LOWMEM_NUM_POOLS,\n\t                          &lowmem_global);\n\tif (ptr == NULL) {\n\t\tfree(lowmem_ram);\n\t\tlowmem_ram = NULL;\n\t\tfprintf(stderr, \"Failed to init lowmem pool\\n\");\n\t\tfflush(stderr);\n\t\texit(1);\n\t}\n\n\tlowmem_pool_ptr = ptr;\n\n#if defined(DUK__ROMPTR_COMPRESSION)\n\t/* Scan ROM pointer range for faster detection of \"is 'p' a ROM pointer\"\n\t * later on.\n\t */\n\tif (1) {\n\t\tconst void * const * ptrs = (const void * const *) duk_rom_compressed_pointers;\n\t\tduk__romptr_low = duk__romptr_high = (const void *) *ptrs;\n\t\twhile (*ptrs) {\n\t\t\tif (*ptrs > duk__romptr_high) {\n\t\t\t\tduk__romptr_high = (const void *) *ptrs;\n\t\t\t}\n\t\t\tif (*ptrs < duk__romptr_low) {\n\t\t\t\tduk__romptr_low = (const void *) *ptrs;\n\t\t\t}\n\t\t\tptrs++;\n\t\t}\n\t\tfprintf(stderr, \"romptrs: low=%p high=%p\\n\",\n\t\t        (const void *) duk__romptr_low, (const void *) duk__romptr_high);\n\t\tfflush(stderr);\n\t}\n#endif\n}\n\nvoid lowmem_free(void) {\n\tif (lowmem_ram != NULL) {\n\t\tfree(lowmem_ram);\n\t\tlowmem_ram = NULL;\n\t}\n\tlowmem_pool_ptr = NULL;\n}\n\nstatic duk_ret_t lowmem__dump_binding(duk_context *ctx) {\n\tlowmem_dump();\n\treturn 0;\n}\n\nvoid lowmem_dump(void) {\n\tint i;\n\tduk_pool_global_stats global_stats;\n\n\tfor (i = 0; i < LOWMEM_NUM_POOLS; i++) {\n\t\tduk_pool_state *s = &lowmem_state[i];\n\t\tduk_pool_stats stats;\n\n\t\tduk_alloc_pool_get_pool_stats(s, &stats);\n\n\t\tfprintf(stderr, \"  %2ld: %4ld %5ldB | free %4ld %5ldB | used %4ld %5ldB | waste %5ldB | hwm %4ld (%3ld%%)%s\\n\",\n\t\t        (long) i, (long) s->count, (long) s->size,\n\t\t        (long) stats.free_count, (long) stats.free_bytes,\n\t\t        (long) stats.used_count, (long) stats.used_bytes,\n\t\t        (long) stats.waste_bytes, (long) stats.hwm_used_count,\n\t\t        (long) ((double) stats.hwm_used_count / (double) s->count * 100.0),\n\t\t        (stats.hwm_used_count == s->count ? \" !\" : \"\"));\n\t}\n\n\t/* This causes another walk over the individual pools which is a bit\n\t * inelegant, but we want the highwater mark stats too.\n\t */\n\tduk_alloc_pool_get_global_stats(&lowmem_global, &global_stats);\n\n\tfprintf(stderr, \"  TOTAL: %ld bytes used, %ld bytes waste, %ld bytes free, %ld bytes total; highwater %ld used, %ld waste\\n\",\n\t        (long) global_stats.used_bytes, (long) global_stats.waste_bytes,\n\t        (long) global_stats.free_bytes, (long) (global_stats.used_bytes + global_stats.free_bytes),\n\t        (long) global_stats.hwm_used_bytes, (long) global_stats.hwm_waste_bytes);\n\tfflush(stderr);\n}\n\nvoid lowmem_register(duk_context *ctx) {\n\tduk_push_global_object(ctx);\n\tduk_push_string(ctx, \"dumpHeap\");\n\tduk_push_c_function(ctx, lowmem__dump_binding, 0);\n\tduk_def_prop(ctx, -3, DUK_DEFPROP_SET_WRITABLE |\n\t                      DUK_DEFPROP_CLEAR_ENUMERABLE |\n\t                      DUK_DEFPROP_SET_CONFIGURABLE |\n\t                      DUK_DEFPROP_HAVE_VALUE);\n\tduk_pop(ctx);\n}\n\n/*\n *  Wrapped alloc functions\n *\n *  Used to write an alloc log.\n */\n\nstatic FILE *lowmem_alloc_log = NULL;\n\nstatic void lowmem_write_alloc_log(const char *fmt, ...) {\n\tva_list ap;\n\tchar buf[256];\n\n\tva_start(ap, fmt);\n\tvsnprintf(buf, sizeof(buf), fmt, ap);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\tva_end(ap);\n\n\tif (lowmem_alloc_log == NULL) {\n\t\tlowmem_alloc_log = fopen(\"/tmp/lowmem-alloc-log.txt\", \"wb\");\n\t\tif (lowmem_alloc_log == NULL) {\n\t\t\tfprintf(stderr, \"WARNING: failed to write alloc log, ignoring\\n\");\n\t\t\tfflush(stderr);\n\t\t\treturn;\n\t\t}\n\t}\n\n\t(void) fwrite((const void *) buf, 1, strlen(buf), lowmem_alloc_log);\n\t(void) fflush(lowmem_alloc_log);\n}\n\nvoid *lowmem_alloc_wrapped(void *udata, duk_size_t size) {\n\tvoid *ret = duk_alloc_pool(udata, size);\n\tif (size > 0 && ret == NULL) {\n\t\tlowmem_write_alloc_log(\"A FAIL %ld\\n\", (long) size);\n\t} else if (ret == NULL) {\n\t\tlowmem_write_alloc_log(\"A NULL %ld\\n\", (long) size);\n\t} else {\n\t\tlowmem_write_alloc_log(\"A %p %ld\\n\", ret, (long) size);\n\t}\n\treturn ret;\n}\n\nvoid *lowmem_realloc_wrapped(void *udata, void *ptr, duk_size_t size) {\n\tvoid *ret = duk_realloc_pool(udata, ptr, size);\n\tif (size > 0 && ret == NULL) {\n\t\tif (ptr == NULL) {\n\t\t\tlowmem_write_alloc_log(\"R NULL -1 FAIL %ld\\n\", (long) size);\n\t\t} else {\n\t\t\tlowmem_write_alloc_log(\"R %p -1 FAIL %ld\\n\", ptr, (long) size);\n\t\t}\n\t} else if (ret == NULL) {\n\t\tif (ptr == NULL) {\n\t\t\tlowmem_write_alloc_log(\"R NULL -1 NULL %ld\\n\", (long) size);\n\t\t} else {\n\t\t\tlowmem_write_alloc_log(\"R %p -1 NULL %ld\\n\", ptr, (long) size);\n\t\t}\n\t} else {\n\t\tif (ptr == NULL) {\n\t\t\tlowmem_write_alloc_log(\"R NULL -1 %p %ld\\n\", ret, (long) size);\n\t\t} else {\n\t\t\tlowmem_write_alloc_log(\"R %p -1 %p %ld\\n\", ptr, ret, (long) size);\n\t\t}\n\t}\n\treturn ret;\n}\n\nvoid lowmem_free_wrapped(void *udata, void *ptr) {\n\tduk_free_pool(udata, ptr);\n\tif (ptr == NULL) {\n\t\t/* Ignore. */\n\t} else {\n\t\tlowmem_write_alloc_log(\"F %p -1\\n\", ptr);\n\t}\n}\n\n/*\n *  Example pointer compression functions.\n *\n *  'base' is chosen so that no non-NULL pointer results in a zero result\n *  which is reserved for NULL pointers.\n */\n\nduk_uint16_t lowmem_enc16(void *ud, void *p) {\n\tduk_uint32_t ret;\n\tchar *base = (char *) lowmem_ram - 4;\n\n#if defined(DUK__ROMPTR_COMPRESSION)\n\tif (p >= duk__romptr_low && p <= duk__romptr_high) {\n\t\t/* The if-condition should be the fastest possible check\n\t\t * for \"is 'p' in ROM?\".  If pointer is in ROM, we'd like\n\t\t * to compress it quickly.  Here we just scan a ~1K array\n\t\t * which is very bad for performance and for illustration\n\t\t * only.\n\t\t */\n\t\tconst void * const * ptrs = duk_rom_compressed_pointers;\n\t\twhile (*ptrs) {\n\t\t\tif (*ptrs == p) {\n\t\t\t\tret = (duk_uint32_t) DUK__ROMPTR_FIRST + (duk_uint32_t) (ptrs - duk_rom_compressed_pointers);\n#if 0\n\t\t\t\tfprintf(stderr, \"lowmem_enc16: rom pointer: %p -> 0x%04lx\\n\", (void *) p, (long) ret);\n\t\t\t\tfflush(stderr);\n#endif\n\t\t\t\treturn (duk_uint16_t) ret;\n\t\t\t}\n\t\t\tptrs++;\n\t\t}\n\n\t\t/* We should really never be here: Duktape should only be\n\t\t * compressing pointers which are in the ROM compressed\n\t\t * pointers list, which are known at 'make dist' time.\n\t\t * We go on, causing a pointer compression error.\n\t\t */\n\t\tfprintf(stderr, \"lowmem_enc16: rom pointer: %p could not be compressed, should never happen\\n\", (void *) p);\n\t\tfflush(stderr);\n\t}\n#endif\n\n\t/* Userdata is not needed in this case but would be useful if heap\n\t * pointer compression were used for multiple heaps.  The userdata\n\t * allows the callback to distinguish between heaps and their base\n\t * pointers.\n\t *\n\t * If not needed, the userdata can be left out during compilation\n\t * by simply ignoring the userdata argument of the pointer encode\n\t * and decode macros.  It is kept here so that any bugs in actually\n\t * providing the value inside Duktape are revealed during compilation.\n\t */\n\t(void) ud;\n#if 1\n\t/* Ensure that we always get the heap_udata given in heap creation.\n\t * (Useful for Duktape development, not needed for user programs.)\n\t */\n\tif (ud != (void *) lowmem_pool_ptr) {\n\t\tfprintf(stderr, \"invalid udata for lowmem_enc16: %p\\n\", ud);\n\t\tfflush(stderr);\n\t}\n#endif\n\n\tif (p == NULL) {\n\t\tret = 0;\n\t} else {\n\t\tret = (duk_uint32_t) (((char *) p - base) >> 2);\n\t}\n#if 0\n\tfprintf(stderr, \"lowmem_enc16: %p -> %u\\n\", p, (unsigned int) ret);\n#endif\n\tif (ret > 0xffffUL) {\n\t\tfprintf(stderr, \"Failed to compress pointer: %p (ret was %ld)\\n\", (void *) p, (long) ret);\n\t\tfflush(stderr);\n\t\tabort();\n\t}\n#if defined(DUK__ROMPTR_COMPRESSION)\n\tif (ret >= (duk_uint32_t) DUK__ROMPTR_FIRST) {\n\t\tfprintf(stderr, \"Failed to compress pointer, in 16-bit range but matches romptr range: %p (ret was %ld)\\n\", (void *) p, (long) ret);\n\t\tfflush(stderr);\n\t\tabort();\n\t}\n#endif\n\treturn (duk_uint16_t) ret;\n}\n\nvoid *lowmem_dec16(void *ud, duk_uint16_t x) {\n\tvoid *ret;\n\tchar *base = (char *) lowmem_ram - 4;\n\n#if defined(DUK__ROMPTR_COMPRESSION)\n\tif (x >= (duk_uint16_t) DUK__ROMPTR_FIRST) {\n\t\t/* This is a blind lookup, could check index validity.\n\t\t * Duktape should never decompress a pointer which would\n\t\t * be out-of-bounds here.\n\t\t */\n\t\tret = (void *) duk__lose_const(duk_rom_compressed_pointers[x - (duk_uint16_t) DUK__ROMPTR_FIRST]);\n#if 0\n\t\tfprintf(stderr, \"lowmem_dec16: rom pointer: 0x%04lx -> %p\\n\", (long) x, ret);\n\t\tfflush(stderr);\n#endif\n\t\treturn ret;\n\t}\n#endif\n\n\t/* See userdata discussion in lowmem_enc16(). */\n\t(void) ud;\n#if 1\n\t/* Ensure that we always get the heap_udata given in heap creation. */\n\tif (ud != (void *) lowmem_pool_ptr) {\n\t\tfprintf(stderr, \"invalid udata for lowmem_dec16: %p\\n\", ud);\n\t\tfflush(stderr);\n\t}\n#endif\n\n\tif (x == 0) {\n\t\tret = NULL;\n\t} else {\n\t\tret = (void *) (base + (((duk_uint32_t) x) << 2));\n\t}\n#if 0\n\tfprintf(stderr, \"lowmem_dec16: %u -> %p\\n\", (unsigned int) x, ret);\n#endif\n\treturn ret;\n}\n\n/*\n *  Simplified example of an external strings strategy where incoming strings\n *  are written sequentially into a fixed, memory mapped flash area.\n *\n *  The example first scans if the string is already in the flash (which may\n *  happen if the same string is interned multiple times), then adds it to\n *  flash if there is space.\n *\n *  This example is too slow to be used in a real world application: there\n *  should be e.g. a hash table to quickly check for strings that are already\n *  present in the string data (similarly to how string interning works in\n *  Duktape itself).\n */\n\nstatic uint8_t lowmem_strdata[65536];\nstatic size_t lowmem_strdata_used = 0;\n\nconst void *lowmem_extstr_check_1(const void *ptr, duk_size_t len) {\n\tuint8_t *p, *p_end;\n\tuint8_t initial;\n\tuint8_t *ret;\n\tsize_t left;\n\n\t(void) duk__safe_print_chars;  /* potentially unused */\n\n\tif (len <= 3) {\n\t\t/* It's not worth it to make very small strings external, as\n\t\t * they would take the same space anyway.  Also avoids zero\n\t\t * length degenerate case.\n\t\t */\n\t\treturn NULL;\n\t}\n\n\t/*\n\t *  Check if we already have the string.  Be careful to compare for\n\t *  NUL terminator too, it is NOT present in 'ptr'.  This algorithm\n\t *  is too simplistic and way too slow for actual use.\n\t */\n\n\tinitial = ((const uint8_t *) ptr)[0];\n\tfor (p = lowmem_strdata, p_end = p + lowmem_strdata_used; p != p_end; p++) {\n\t\tif (*p != initial) {\n\t\t\tcontinue;\n\t\t}\n\t\tleft = (size_t) (p_end - p);\n\t\tif (left >= len + 1 &&\n\t\t    memcmp(p, ptr, len) == 0 &&\n\t\t    p[len] == 0) {\n\t\t\tret = p;\n#if 0\n\t\t\tfprintf(stderr, \"lowmem_extstr_check_1: ptr=%p, len=%ld \",\n\t\t\t       (void *) ptr, (long) len);\n\t\t\tduk__safe_print_chars((const char *) ptr, len, 0 /*until_nul*/);\n\t\t\tfprintf(stderr, \" -> existing %p (used=%ld)\\n\",\n\t\t\t       (void *) ret, (long) lowmem_strdata_used);\n#endif\n\t\t\treturn ret;\n\t\t}\n\t}\n\n\t/*\n\t *  Not present yet, check if we have space.  Again, be careful to\n\t *  ensure there is space for a NUL following the input data.\n\t */\n\n\tif (lowmem_strdata_used + len + 1 > sizeof(lowmem_strdata)) {\n#if 0\n\t\tfprintf(stderr, \"lowmem_extstr_check_1: ptr=%p, len=%ld \", (void *) ptr, (long) len);\n\t\tduk__safe_print_chars((const char *) ptr, len, 0 /*until_nul*/);\n\t\tfprintf(stderr, \" -> no space (used=%ld)\\n\", (long) lowmem_strdata_used);\n#endif\n\t\treturn NULL;\n\t}\n\n\t/*\n\t *  There is space, add the string to our collection, being careful\n\t *  to append the NUL.\n\t */\n\n\tret = lowmem_strdata + lowmem_strdata_used;\n\tmemcpy(ret, ptr, len);\n\tret[len] = (uint8_t) 0;\n\tlowmem_strdata_used += len + 1;\n\n#if 0\n\tfprintf(stderr, \"lowmem_extstr_check_1: ptr=%p, len=%ld -> \", (void *) ptr, (long) len);\n\tduk__safe_print_chars((const char *) ptr, len, 0 /*until_nul*/);\n\tfprintf(stderr, \" -> %p (used=%ld)\\n\", (void *) ret, (long) lowmem_strdata_used);\n#endif\n\treturn (const void *) ret;\n}\n\nvoid lowmem_extstr_free_1(const void *ptr) {\n\t(void) ptr;\n#if 0\n\tfprintf(stderr, \"lowmem_extstr_free_1: freeing extstr %p -> \", ptr);\n\tduk__safe_print_chars((const char *) ptr, DUK_SIZE_MAX, 1 /*until_nul*/);\n\tfprintf(stderr, \"\\n\");\n#endif\n}\n\n/*\n *  Simplified example of an external strings strategy where a set of strings\n *  is gathered during application compile time and baked into the application\n *  binary.\n *\n *  Duktape built-in strings are available from duk_source_meta.json in a\n *  prepared source directory, see tools/duk_meta_to_strarray.py.  There\n *  may also be a lot of application specific strings, e.g. those used by\n *  application specific APIs.  These must be gathered through some other\n *  means, see e.g. tools/scan_strings.py.\n */\n\nstatic const char *strdata_duk_builtin_strings[] = {\n\t/*\n\t *  These strings are from tools/duk_meta_to_strarray.py\n\t */\n\n\t\"Logger\",\n\t\"Thread\",\n\t\"Pointer\",\n\t\"Buffer\",\n\t\"DecEnv\",\n\t\"ObjEnv\",\n\t\"\",\n\t\"global\",\n\t\"Arguments\",\n\t\"JSON\",\n\t\"Math\",\n\t\"Error\",\n\t\"RegExp\",\n\t\"Date\",\n\t\"Number\",\n\t\"Boolean\",\n\t\"String\",\n\t\"Array\",\n\t\"Function\",\n\t\"Object\",\n\t\"Null\",\n\t\"Undefined\",\n\t\"{_func:true}\",\n\t\"{\\x22\" \"_func\\x22\" \":true}\",\n\t\"{\\x22\" \"_ninf\\x22\" \":true}\",\n\t\"{\\x22\" \"_inf\\x22\" \":true}\",\n\t\"{\\x22\" \"_nan\\x22\" \":true}\",\n\t\"{\\x22\" \"_undef\\x22\" \":true}\",\n\t\"toLogString\",\n\t\"clog\",\n\t\"l\",\n\t\"n\",\n\t\"fatal\",\n\t\"error\",\n\t\"warn\",\n\t\"debug\",\n\t\"trace\",\n\t\"raw\",\n\t\"fmt\",\n\t\"current\",\n\t\"resume\",\n\t\"compact\",\n\t\"jc\",\n\t\"jx\",\n\t\"base64\",\n\t\"hex\",\n\t\"dec\",\n\t\"enc\",\n\t\"fin\",\n\t\"gc\",\n\t\"act\",\n\t\"info\",\n\t\"version\",\n\t\"env\",\n\t\"modLoaded\",\n\t\"modSearch\",\n\t\"errThrow\",\n\t\"errCreate\",\n\t\"compile\",\n\t\"\\x82\" \"Regbase\",\n\t\"\\x82\" \"Thread\",\n\t\"\\x82\" \"Handler\",\n\t\"\\x82\" \"Finalizer\",\n\t\"\\x82\" \"Callee\",\n\t\"\\x82\" \"Map\",\n\t\"\\x82\" \"Args\",\n\t\"\\x82\" \"This\",\n\t\"\\x82\" \"Pc2line\",\n\t\"\\x82\" \"Source\",\n\t\"\\x82\" \"Varenv\",\n\t\"\\x82\" \"Lexenv\",\n\t\"\\x82\" \"Varmap\",\n\t\"\\x82\" \"Formals\",\n\t\"\\x82\" \"Bytecode\",\n\t\"\\x82\" \"Next\",\n\t\"\\x82\" \"Target\",\n\t\"\\x82\" \"Value\",\n\t\"pointer\",\n\t\"buffer\",\n\t\"\\x82\" \"Tracedata\",\n\t\"lineNumber\",\n\t\"fileName\",\n\t\"pc\",\n\t\"stack\",\n\t\"ThrowTypeError\",\n\t\"Duktape\",\n\t\"id\",\n\t\"require\",\n\t\"__proto__\",\n\t\"setPrototypeOf\",\n\t\"ownKeys\",\n\t\"enumerate\",\n\t\"deleteProperty\",\n\t\"has\",\n\t\"Proxy\",\n\t\"callee\",\n\t\"Invalid Date\",\n\t\"[...]\",\n\t\"\\x0a\" \"\\x09\",\n\t\" \",\n\t\",\",\n\t\"-0\",\n\t\"+0\",\n\t\"0\",\n\t\"-Infinity\",\n\t\"+Infinity\",\n\t\"Infinity\",\n\t\"object\",\n\t\"string\",\n\t\"number\",\n\t\"boolean\",\n\t\"undefined\",\n\t\"stringify\",\n\t\"tan\",\n\t\"sqrt\",\n\t\"sin\",\n\t\"round\",\n\t\"random\",\n\t\"pow\",\n\t\"min\",\n\t\"max\",\n\t\"log\",\n\t\"floor\",\n\t\"exp\",\n\t\"cos\",\n\t\"ceil\",\n\t\"atan2\",\n\t\"atan\",\n\t\"asin\",\n\t\"acos\",\n\t\"abs\",\n\t\"SQRT2\",\n\t\"SQRT1_2\",\n\t\"PI\",\n\t\"LOG10E\",\n\t\"LOG2E\",\n\t\"LN2\",\n\t\"LN10\",\n\t\"E\",\n\t\"message\",\n\t\"name\",\n\t\"input\",\n\t\"index\",\n\t\"(?:)\",\n\t\"lastIndex\",\n\t\"multiline\",\n\t\"ignoreCase\",\n\t\"source\",\n\t\"test\",\n\t\"exec\",\n\t\"toGMTString\",\n\t\"setYear\",\n\t\"getYear\",\n\t\"toJSON\",\n\t\"toISOString\",\n\t\"toUTCString\",\n\t\"setUTCFullYear\",\n\t\"setFullYear\",\n\t\"setUTCMonth\",\n\t\"setMonth\",\n\t\"setUTCDate\",\n\t\"setDate\",\n\t\"setUTCHours\",\n\t\"setHours\",\n\t\"setUTCMinutes\",\n\t\"setMinutes\",\n\t\"setUTCSeconds\",\n\t\"setSeconds\",\n\t\"setUTCMilliseconds\",\n\t\"setMilliseconds\",\n\t\"setTime\",\n\t\"getTimezoneOffset\",\n\t\"getUTCMilliseconds\",\n\t\"getMilliseconds\",\n\t\"getUTCSeconds\",\n\t\"getSeconds\",\n\t\"getUTCMinutes\",\n\t\"getMinutes\",\n\t\"getUTCHours\",\n\t\"getHours\",\n\t\"getUTCDay\",\n\t\"getDay\",\n\t\"getUTCDate\",\n\t\"getDate\",\n\t\"getUTCMonth\",\n\t\"getMonth\",\n\t\"getUTCFullYear\",\n\t\"getFullYear\",\n\t\"getTime\",\n\t\"toLocaleTimeString\",\n\t\"toLocaleDateString\",\n\t\"toTimeString\",\n\t\"toDateString\",\n\t\"now\",\n\t\"UTC\",\n\t\"parse\",\n\t\"toPrecision\",\n\t\"toExponential\",\n\t\"toFixed\",\n\t\"POSITIVE_INFINITY\",\n\t\"NEGATIVE_INFINITY\",\n\t\"NaN\",\n\t\"MIN_VALUE\",\n\t\"MAX_VALUE\",\n\t\"substr\",\n\t\"trim\",\n\t\"toLocaleUpperCase\",\n\t\"toUpperCase\",\n\t\"toLocaleLowerCase\",\n\t\"toLowerCase\",\n\t\"substring\",\n\t\"split\",\n\t\"search\",\n\t\"replace\",\n\t\"match\",\n\t\"localeCompare\",\n\t\"charCodeAt\",\n\t\"charAt\",\n\t\"fromCharCode\",\n\t\"reduceRight\",\n\t\"reduce\",\n\t\"filter\",\n\t\"map\",\n\t\"forEach\",\n\t\"some\",\n\t\"every\",\n\t\"lastIndexOf\",\n\t\"indexOf\",\n\t\"unshift\",\n\t\"splice\",\n\t\"sort\",\n\t\"slice\",\n\t\"shift\",\n\t\"reverse\",\n\t\"push\",\n\t\"pop\",\n\t\"join\",\n\t\"concat\",\n\t\"isArray\",\n\t\"arguments\",\n\t\"caller\",\n\t\"bind\",\n\t\"call\",\n\t\"apply\",\n\t\"propertyIsEnumerable\",\n\t\"isPrototypeOf\",\n\t\"hasOwnProperty\",\n\t\"valueOf\",\n\t\"toLocaleString\",\n\t\"toString\",\n\t\"constructor\",\n\t\"set\",\n\t\"get\",\n\t\"enumerable\",\n\t\"configurable\",\n\t\"writable\",\n\t\"value\",\n\t\"keys\",\n\t\"isExtensible\",\n\t\"isFrozen\",\n\t\"isSealed\",\n\t\"preventExtensions\",\n\t\"freeze\",\n\t\"seal\",\n\t\"defineProperties\",\n\t\"defineProperty\",\n\t\"create\",\n\t\"getOwnPropertyNames\",\n\t\"getOwnPropertyDescriptor\",\n\t\"getPrototypeOf\",\n\t\"prototype\",\n\t\"length\",\n\t\"alert\",\n\t\"print\",\n\t\"unescape\",\n\t\"escape\",\n\t\"encodeURIComponent\",\n\t\"encodeURI\",\n\t\"decodeURIComponent\",\n\t\"decodeURI\",\n\t\"isFinite\",\n\t\"isNaN\",\n\t\"parseFloat\",\n\t\"parseInt\",\n\t\"eval\",\n\t\"URIError\",\n\t\"TypeError\",\n\t\"SyntaxError\",\n\t\"ReferenceError\",\n\t\"RangeError\",\n\t\"EvalError\",\n\t\"break\",\n\t\"case\",\n\t\"catch\",\n\t\"continue\",\n\t\"debugger\",\n\t\"default\",\n\t\"delete\",\n\t\"do\",\n\t\"else\",\n\t\"finally\",\n\t\"for\",\n\t\"function\",\n\t\"if\",\n\t\"in\",\n\t\"instanceof\",\n\t\"new\",\n\t\"return\",\n\t\"switch\",\n\t\"this\",\n\t\"throw\",\n\t\"try\",\n\t\"typeof\",\n\t\"var\",\n\t\"void\",\n\t\"while\",\n\t\"with\",\n\t\"class\",\n\t\"const\",\n\t\"enum\",\n\t\"export\",\n\t\"extends\",\n\t\"import\",\n\t\"super\",\n\t\"null\",\n\t\"true\",\n\t\"false\",\n\t\"implements\",\n\t\"interface\",\n\t\"let\",\n\t\"package\",\n\t\"private\",\n\t\"protected\",\n\t\"public\",\n\t\"static\",\n\t\"yield\",\n\n\t/*\n\t *  These strings are manually added, and would be gathered in some\n\t *  application specific manner.\n\t */\n\n\t\"foo\",\n\t\"bar\",\n\t\"quux\",\n\t\"enableFrob\",\n\t\"disableFrob\"\n\t/* ... */\n};\n\nconst void *lowmem_extstr_check_2(const void *ptr, duk_size_t len) {\n\tint i, n;\n\n\t(void) duk__safe_print_chars;  /* potentially unused */\n\n\t/* Linear scan.  An actual implementation would need some acceleration\n\t * structure, e.g. select a sublist based on first character.\n\t *\n\t * NOTE: input string (behind 'ptr' with 'len' bytes) DOES NOT have a\n\t * trailing NUL character.  Any strings returned from this function\n\t * MUST have a trailing NUL character.\n\t */\n\n\tn = (int) (sizeof(strdata_duk_builtin_strings) / sizeof(const char *));\n\tfor (i = 0; i < n; i++) {\n\t\tconst char *str;\n\n\t\tstr = strdata_duk_builtin_strings[i];\n\t\tif (strlen(str) == len && memcmp(ptr, (const void *) str, len) == 0) {\n#if 0\n\t\t\tfprintf(stderr, \"lowmem_extstr_check_2: ptr=%p, len=%ld \",\n\t\t\t       (void *) ptr, (long) len);\n\t\t\tduk__safe_print_chars((const char *) ptr, len, 0 /*until_nul*/);\n\t\t\tfprintf(stderr, \" -> constant string index %ld\\n\", (long) i);\n#endif\n\t\t\treturn (void *) duk__lose_const(strdata_duk_builtin_strings[i]);\n\t\t}\n\t}\n\n#if 0\n\tfprintf(stderr, \"lowmem_extstr_check_2: ptr=%p, len=%ld \",\n\t       (void *) ptr, (long) len);\n\tduk__safe_print_chars((const char *) ptr, len, 0 /*until_nul*/);\n\tfprintf(stderr, \" -> not found\\n\");\n#endif\n\treturn NULL;\n}\n\nvoid lowmem_extstr_free_2(const void *ptr) {\n\t(void) ptr;\n#if 0\n\tfprintf(stderr, \"lowmem_extstr_free_2: freeing extstr %p -> \", ptr);\n\tduk__safe_print_chars((const char *) ptr, DUK_SIZE_MAX, 1 /*until_nul*/);\n\tfprintf(stderr, \"\\n\");\n#endif\n}\n\n/*\n *  External strings strategy intended for valgrind testing: external strings\n *  are allocated using malloc()/free() so that valgrind can be used to ensure\n *  that strings are e.g. freed exactly once.\n */\n\nconst void *lowmem_extstr_check_3(const void *ptr, duk_size_t len) {\n\tduk_uint8_t *ret;\n\n\t(void) duk__safe_print_chars;  /* potentially unused */\n\n\tret = malloc((size_t) len + 1);\n\tif (ret == NULL) {\n#if 0\n\t\tfprintf(stderr, \"lowmem_extstr_check_3: ptr=%p, len=%ld \",\n\t\t       (void *) ptr, (long) len);\n\t\tduk__safe_print_chars((const char *) ptr, len, 0 /*until_nul*/);\n\t\tfprintf(stderr, \" -> malloc failed, return NULL\\n\");\n#endif\n\t\treturn (const void *) NULL;\n\t}\n\n\tif (len > 0) {\n\t\tmemcpy((void *) ret, ptr, (size_t) len);\n\t}\n\tret[len] = (duk_uint8_t) 0;\n\n#if 0\n\tfprintf(stderr, \"lowmem_extstr_check_3: ptr=%p, len=%ld \",\n\t       (void *) ptr, (long) len);\n\tduk__safe_print_chars((const char *) ptr, len, 0 /*until_nul*/);\n\tfprintf(stderr, \" -> %p\\n\", (void *) ret);\n#endif\n\treturn (const void *) ret;\n}\n\nvoid lowmem_extstr_free_3(const void *ptr) {\n\t(void) ptr;\n#if 0\n\tfprintf(stderr, \"lowmem_extstr_free_3: freeing extstr %p -> \", ptr);\n\tduk__safe_print_chars((const char *) ptr, DUK_SIZE_MAX, 1 /*until_nul*/);\n\tfprintf(stderr, \"\\n\");\n#endif\n\tfree((void *) duk__lose_const(ptr));\n}\n\n/*\n *  Execution timeout example\n */\n\n#define  AJSHEAP_EXEC_TIMEOUT  5  /* seconds */\n\nstatic time_t curr_pcall_start = 0;\nstatic long exec_timeout_check_counter = 0;\n\nvoid lowmem_start_exec_timeout(void) {\n\tcurr_pcall_start = time(NULL);\n}\n\nvoid lowmem_clear_exec_timeout(void) {\n\tcurr_pcall_start = 0;\n}\n\nduk_bool_t lowmem_exec_timeout_check(void *udata) {\n\ttime_t now = time(NULL);\n\ttime_t diff = now - curr_pcall_start;\n\n\t(void) udata;  /* not needed */\n\n\texec_timeout_check_counter++;\n#if 0\n\tfprintf(stderr, \"exec timeout check %ld: now=%ld, start=%ld, diff=%ld\\n\",\n\t       (long) exec_timeout_check_counter, (long) now, (long) curr_pcall_start, (long) diff);\n\tfflush(stderr);\n#endif\n\n\tif (curr_pcall_start == 0) {\n\t\t/* protected call not yet running */\n\t\treturn 0;\n\t}\n\tif (diff > AJSHEAP_EXEC_TIMEOUT) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\n#else  /* DUK_CMDLINE_LOWMEM */\n\nint duk_lowmem_dummy = 0;  /* to avoid empty source file */\n\n#endif  /* DUK_CMDLINE_LOWMEM */\n"
  },
  {
    "path": "react_juce/duktape/examples/codepage-conv/README.rst",
    "content": "Codepage conversion example\n===========================\n\nExample of how to convert an 8-bit input string (e.g. ISO-8859-1 or Windows\ncodepage 1252) into CESU-8 without using an external library like iconv.\n\nThis is useful e.g. when compiling non-UTF-8 source code which cannot be\nconverted to UTF-8 (CESU-8) at build time.\n"
  },
  {
    "path": "react_juce/duktape/examples/codepage-conv/duk_codepage_conv.c",
    "content": "/*\n *  Convert an 8-bit input string (e.g. ISO-8859-1) into CESU-8.\n *  Calling code supplies the \"code page\" as a 256-entry array of\n *  codepoints for the conversion.\n *\n *  This is useful when input data is in non-UTF-8 format and must\n *  be converted at runtime, e.g. when compiling non-UTF-8 source\n *  code.  Another alternative is to use e.g. iconv.\n */\n\n#include \"duktape.h\"\n\n/* Decode an 8-bit string using 'codepage' into Unicode codepoints and\n * re-encode into CESU-8.  Codepage argument must point to a 256-entry\n * table.  Only supports BMP (codepoints U+0000 to U+FFFF).\n */\nvoid duk_decode_string_codepage(duk_context *ctx, const char *str, size_t len, unsigned int *codepage) {\n\tunsigned char *tmp;\n\tsize_t tmplen, i;\n\tunsigned char *p;\n\tunsigned int cp;\n\n\ttmplen = 3 * len;  /* max expansion is 1 input byte -> 3 output bytes */\n\tif (tmplen / 3 != len) {\n\t\t/* Temporary buffer length wraps. */\n\t\t(void) duk_error(ctx, DUK_ERR_RANGE_ERROR, \"input string too long\");\n\t\treturn;\n\t}\n\n\ttmp = (unsigned char *) duk_push_fixed_buffer(ctx, tmplen);\n\n\tfor (i = 0, p = tmp; i < len; i++) {\n\t\tcp = codepage[((unsigned char *) str)[i]] & 0xffffUL;\n\t\tif (cp < 0x80UL) {\n\t\t\t*p++ = (unsigned char) cp;\n\t\t} else if (cp < 0x800UL) {\n\t\t\t*p++ = (unsigned char) (0xc0 + ((cp >> 6) & 0x1f));\n\t\t\t*p++ = (unsigned char) (0x80 + (cp & 0x3f));\n\t\t} else {\n\t\t\t/* In CESU-8 all codepoints in [0x0000,0xFFFF] are\n\t\t\t * allowed, including surrogates.\n\t\t\t */\n\t\t\t*p++ = (unsigned char) (0xe0 + ((cp >> 12) & 0x0f));\n\t\t\t*p++ = (unsigned char) (0x80 + ((cp >> 6) & 0x3f));\n\t\t\t*p++ = (unsigned char) (0x80 + (cp & 0x3f));\n\t\t}\n\t}\n\n\tduk_push_lstring(ctx, (const char *) tmp, (duk_size_t) (p - tmp));\n\n\t/* [ ... tmp res ] */\n\n\tduk_remove(ctx, -2);\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/codepage-conv/duk_codepage_conv.h",
    "content": "#if !defined(DUK_CODEPAGE_CONV_H_INCLUDED)\n#define DUK_CODEPAGE_CONV_H_INCLUDED\n\n#include \"duktape.h\"\n\nvoid duk_decode_string_codepage(duk_context *ctx, const char *str, size_t len, unsigned int *codepage);\n\n#endif  /* DUK_CODEPAGE_CONV_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/examples/codepage-conv/test.c",
    "content": "#include \"duktape.h\"\n#include \"duk_codepage_conv.h\"\n\n/* http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT */\nunsigned int cp1252[256] = {\n\t(unsigned int) 0x0000,\n\t(unsigned int) 0x0001,\n\t(unsigned int) 0x0002,\n\t(unsigned int) 0x0003,\n\t(unsigned int) 0x0004,\n\t(unsigned int) 0x0005,\n\t(unsigned int) 0x0006,\n\t(unsigned int) 0x0007,\n\t(unsigned int) 0x0008,\n\t(unsigned int) 0x0009,\n\t(unsigned int) 0x000A,\n\t(unsigned int) 0x000B,\n\t(unsigned int) 0x000C,\n\t(unsigned int) 0x000D,\n\t(unsigned int) 0x000E,\n\t(unsigned int) 0x000F,\n\t(unsigned int) 0x0010,\n\t(unsigned int) 0x0011,\n\t(unsigned int) 0x0012,\n\t(unsigned int) 0x0013,\n\t(unsigned int) 0x0014,\n\t(unsigned int) 0x0015,\n\t(unsigned int) 0x0016,\n\t(unsigned int) 0x0017,\n\t(unsigned int) 0x0018,\n\t(unsigned int) 0x0019,\n\t(unsigned int) 0x001A,\n\t(unsigned int) 0x001B,\n\t(unsigned int) 0x001C,\n\t(unsigned int) 0x001D,\n\t(unsigned int) 0x001E,\n\t(unsigned int) 0x001F,\n\t(unsigned int) 0x0020,\n\t(unsigned int) 0x0021,\n\t(unsigned int) 0x0022,\n\t(unsigned int) 0x0023,\n\t(unsigned int) 0x0024,\n\t(unsigned int) 0x0025,\n\t(unsigned int) 0x0026,\n\t(unsigned int) 0x0027,\n\t(unsigned int) 0x0028,\n\t(unsigned int) 0x0029,\n\t(unsigned int) 0x002A,\n\t(unsigned int) 0x002B,\n\t(unsigned int) 0x002C,\n\t(unsigned int) 0x002D,\n\t(unsigned int) 0x002E,\n\t(unsigned int) 0x002F,\n\t(unsigned int) 0x0030,\n\t(unsigned int) 0x0031,\n\t(unsigned int) 0x0032,\n\t(unsigned int) 0x0033,\n\t(unsigned int) 0x0034,\n\t(unsigned int) 0x0035,\n\t(unsigned int) 0x0036,\n\t(unsigned int) 0x0037,\n\t(unsigned int) 0x0038,\n\t(unsigned int) 0x0039,\n\t(unsigned int) 0x003A,\n\t(unsigned int) 0x003B,\n\t(unsigned int) 0x003C,\n\t(unsigned int) 0x003D,\n\t(unsigned int) 0x003E,\n\t(unsigned int) 0x003F,\n\t(unsigned int) 0x0040,\n\t(unsigned int) 0x0041,\n\t(unsigned int) 0x0042,\n\t(unsigned int) 0x0043,\n\t(unsigned int) 0x0044,\n\t(unsigned int) 0x0045,\n\t(unsigned int) 0x0046,\n\t(unsigned int) 0x0047,\n\t(unsigned int) 0x0048,\n\t(unsigned int) 0x0049,\n\t(unsigned int) 0x004A,\n\t(unsigned int) 0x004B,\n\t(unsigned int) 0x004C,\n\t(unsigned int) 0x004D,\n\t(unsigned int) 0x004E,\n\t(unsigned int) 0x004F,\n\t(unsigned int) 0x0050,\n\t(unsigned int) 0x0051,\n\t(unsigned int) 0x0052,\n\t(unsigned int) 0x0053,\n\t(unsigned int) 0x0054,\n\t(unsigned int) 0x0055,\n\t(unsigned int) 0x0056,\n\t(unsigned int) 0x0057,\n\t(unsigned int) 0x0058,\n\t(unsigned int) 0x0059,\n\t(unsigned int) 0x005A,\n\t(unsigned int) 0x005B,\n\t(unsigned int) 0x005C,\n\t(unsigned int) 0x005D,\n\t(unsigned int) 0x005E,\n\t(unsigned int) 0x005F,\n\t(unsigned int) 0x0060,\n\t(unsigned int) 0x0061,\n\t(unsigned int) 0x0062,\n\t(unsigned int) 0x0063,\n\t(unsigned int) 0x0064,\n\t(unsigned int) 0x0065,\n\t(unsigned int) 0x0066,\n\t(unsigned int) 0x0067,\n\t(unsigned int) 0x0068,\n\t(unsigned int) 0x0069,\n\t(unsigned int) 0x006A,\n\t(unsigned int) 0x006B,\n\t(unsigned int) 0x006C,\n\t(unsigned int) 0x006D,\n\t(unsigned int) 0x006E,\n\t(unsigned int) 0x006F,\n\t(unsigned int) 0x0070,\n\t(unsigned int) 0x0071,\n\t(unsigned int) 0x0072,\n\t(unsigned int) 0x0073,\n\t(unsigned int) 0x0074,\n\t(unsigned int) 0x0075,\n\t(unsigned int) 0x0076,\n\t(unsigned int) 0x0077,\n\t(unsigned int) 0x0078,\n\t(unsigned int) 0x0079,\n\t(unsigned int) 0x007A,\n\t(unsigned int) 0x007B,\n\t(unsigned int) 0x007C,\n\t(unsigned int) 0x007D,\n\t(unsigned int) 0x007E,\n\t(unsigned int) 0x007F,\n\t(unsigned int) 0x20AC,\n\t(unsigned int) 0xFFFD,  /* undefined */\n\t(unsigned int) 0x201A,\n\t(unsigned int) 0x0192,\n\t(unsigned int) 0x201E,\n\t(unsigned int) 0x2026,\n\t(unsigned int) 0x2020,\n\t(unsigned int) 0x2021,\n\t(unsigned int) 0x02C6,\n\t(unsigned int) 0x2030,\n\t(unsigned int) 0x0160,\n\t(unsigned int) 0x2039,\n\t(unsigned int) 0x0152,\n\t(unsigned int) 0xFFFD,  /* undefined */\n\t(unsigned int) 0x017D,\n\t(unsigned int) 0xFFFD,  /* undefined */\n\t(unsigned int) 0xFFFD,  /* undefined */\n\t(unsigned int) 0x2018,\n\t(unsigned int) 0x2019,\n\t(unsigned int) 0x201C,\n\t(unsigned int) 0x201D,\n\t(unsigned int) 0x2022,\n\t(unsigned int) 0x2013,\n\t(unsigned int) 0x2014,\n\t(unsigned int) 0x02DC,\n\t(unsigned int) 0x2122,\n\t(unsigned int) 0x0161,\n\t(unsigned int) 0x203A,\n\t(unsigned int) 0x0153,\n\t(unsigned int) 0xFFFD,  /* undefined */\n\t(unsigned int) 0x017E,\n\t(unsigned int) 0x0178,\n\t(unsigned int) 0x00A0,\n\t(unsigned int) 0x00A1,\n\t(unsigned int) 0x00A2,\n\t(unsigned int) 0x00A3,\n\t(unsigned int) 0x00A4,\n\t(unsigned int) 0x00A5,\n\t(unsigned int) 0x00A6,\n\t(unsigned int) 0x00A7,\n\t(unsigned int) 0x00A8,\n\t(unsigned int) 0x00A9,\n\t(unsigned int) 0x00AA,\n\t(unsigned int) 0x00AB,\n\t(unsigned int) 0x00AC,\n\t(unsigned int) 0x00AD,\n\t(unsigned int) 0x00AE,\n\t(unsigned int) 0x00AF,\n\t(unsigned int) 0x00B0,\n\t(unsigned int) 0x00B1,\n\t(unsigned int) 0x00B2,\n\t(unsigned int) 0x00B3,\n\t(unsigned int) 0x00B4,\n\t(unsigned int) 0x00B5,\n\t(unsigned int) 0x00B6,\n\t(unsigned int) 0x00B7,\n\t(unsigned int) 0x00B8,\n\t(unsigned int) 0x00B9,\n\t(unsigned int) 0x00BA,\n\t(unsigned int) 0x00BB,\n\t(unsigned int) 0x00BC,\n\t(unsigned int) 0x00BD,\n\t(unsigned int) 0x00BE,\n\t(unsigned int) 0x00BF,\n\t(unsigned int) 0x00C0,\n\t(unsigned int) 0x00C1,\n\t(unsigned int) 0x00C2,\n\t(unsigned int) 0x00C3,\n\t(unsigned int) 0x00C4,\n\t(unsigned int) 0x00C5,\n\t(unsigned int) 0x00C6,\n\t(unsigned int) 0x00C7,\n\t(unsigned int) 0x00C8,\n\t(unsigned int) 0x00C9,\n\t(unsigned int) 0x00CA,\n\t(unsigned int) 0x00CB,\n\t(unsigned int) 0x00CC,\n\t(unsigned int) 0x00CD,\n\t(unsigned int) 0x00CE,\n\t(unsigned int) 0x00CF,\n\t(unsigned int) 0x00D0,\n\t(unsigned int) 0x00D1,\n\t(unsigned int) 0x00D2,\n\t(unsigned int) 0x00D3,\n\t(unsigned int) 0x00D4,\n\t(unsigned int) 0x00D5,\n\t(unsigned int) 0x00D6,\n\t(unsigned int) 0x00D7,\n\t(unsigned int) 0x00D8,\n\t(unsigned int) 0x00D9,\n\t(unsigned int) 0x00DA,\n\t(unsigned int) 0x00DB,\n\t(unsigned int) 0x00DC,\n\t(unsigned int) 0x00DD,\n\t(unsigned int) 0x00DE,\n\t(unsigned int) 0x00DF,\n\t(unsigned int) 0x00E0,\n\t(unsigned int) 0x00E1,\n\t(unsigned int) 0x00E2,\n\t(unsigned int) 0x00E3,\n\t(unsigned int) 0x00E4,\n\t(unsigned int) 0x00E5,\n\t(unsigned int) 0x00E6,\n\t(unsigned int) 0x00E7,\n\t(unsigned int) 0x00E8,\n\t(unsigned int) 0x00E9,\n\t(unsigned int) 0x00EA,\n\t(unsigned int) 0x00EB,\n\t(unsigned int) 0x00EC,\n\t(unsigned int) 0x00ED,\n\t(unsigned int) 0x00EE,\n\t(unsigned int) 0x00EF,\n\t(unsigned int) 0x00F0,\n\t(unsigned int) 0x00F1,\n\t(unsigned int) 0x00F2,\n\t(unsigned int) 0x00F3,\n\t(unsigned int) 0x00F4,\n\t(unsigned int) 0x00F5,\n\t(unsigned int) 0x00F6,\n\t(unsigned int) 0x00F7,\n\t(unsigned int) 0x00F8,\n\t(unsigned int) 0x00F9,\n\t(unsigned int) 0x00FA,\n\t(unsigned int) 0x00FB,\n\t(unsigned int) 0x00FC,\n\t(unsigned int) 0x00FD,\n\t(unsigned int) 0x00FE,\n\t(unsigned int) 0x00FF\n};\n\n/* Exercise all 3 byte lengths: any ASCII character is 1 byte, 0xFC maps to\n * U+00FC which is 2 bytes, and 0x80 maps to U+20AC which is 3 bytes.\n */\nstatic const char *example_source = \"print('Hello w\\xfcrld - \\x80');\";\n\nstatic duk_ret_t duk__print(duk_context *ctx) {\n\tduk_push_string(ctx, \" \");\n\tduk_insert(ctx, 0);\n\tduk_join(ctx, duk_get_top(ctx) - 1);\n\tprintf(\"%s\\n\", duk_safe_to_string(ctx, -1));\n\treturn 0;\n}\n\n/* Example: compile and run test source encoded in Windows codepage 1252. */\nint main(int argc, char *argv[]) {\n\tduk_context *ctx;\n\n\t(void) argc; (void) argv;\n\n\tctx = duk_create_heap_default();\n\tif (!ctx) {\n\t\tprintf(\"Failed to create Duktape heap.\\n\");\n\t\treturn 1;\n\t}\n\n\t/* Minimal print() provider. */\n\tduk_push_c_function(ctx, duk__print, DUK_VARARGS);\n\tduk_put_global_string(ctx, \"print\");\n\n\tduk_decode_string_codepage(ctx, example_source, strlen(example_source), cp1252);\n\tduk_eval_noresult(ctx);\n\n\tduk_destroy_heap(ctx);\n\treturn 0;\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/coffee/README.rst",
    "content": "=====================\nCoffeescript examples\n=====================\n\nA few tests to see how CoffeeScript works with Duktape.  Just convert the\nCoffeescript files to Javascript with the ``Makefile.coffee`` in the\ndistributable, or manually::\n\n  $ coffee -c hello.coffee\n  $ cat hello.js\n"
  },
  {
    "path": "react_juce/duktape/examples/coffee/globals.coffee",
    "content": "\nprint '*** All globals'\nprint(name) for name in Object.getOwnPropertyNames(this)\n\nprint '*** Globals with a short name (<= 8 chars)'\nprint(name) for name in Object.getOwnPropertyNames(this) when name.length <= 8\n\n"
  },
  {
    "path": "react_juce/duktape/examples/coffee/hello.coffee",
    "content": "print 'Hello world!'\nprint 'version: ' + Duktape.version\n"
  },
  {
    "path": "react_juce/duktape/examples/coffee/mandel.coffee",
    "content": "mandel = (x0, y0, x1, y1, w, h, maxiter) ->\n  [dx, dy] = [(x1 - x0) / w, (y1 - y0) / h]\n  res = []\n\n  y = y0\n  for yc in [0..h-1]\n    x = x0\n    for xc in [0..w-1]\n      [xx, yy] = [x, y]\n      c = '*'\n      for i in [0..maxiter-1]\n        # (xx+i*yy)^2 + (x+i*y) = xx^2 + i*2*xx*yy - yy^2 + x + i*y\n        # = (xx^2 - yy^2 + x) + i*(2*xx*yy + y)\n        [xx2, yy2] = [xx*xx, yy*yy]\n        if xx2 + yy2 >= 4.0\n          c = '.'\n          break\n        [xx, yy] = [xx2 - yy2 + x, 2*xx*yy + y]\n      res.push(c)\n      x += dx\n    res.push('\\n')\n    y += dy\n\n  print(res.join(''))\n  return\n\nmandel(-2, 2, 2, -2, 200, 100, 1000)\n\n"
  },
  {
    "path": "react_juce/duktape/examples/cpp-exceptions/README.rst",
    "content": "=========================================\nC++ exceptions for long control transfers\n=========================================\n\nNormally Duktape uses ``setjmp()`` / ``longjmp()`` or their variants for\ninternal long control transfers.  One downside of these functions is that\nC++ automatic destructors (scope-based resource management, SBRM, a special\ncase of RAII) in Duktape/C functions won't be executed which is awkward for\nC++ programmers.\n\nWhen ``DUK_USE_CPP_EXCEPTIONS`` is defined, and both Duktape and application\ncode is compiled using a C++ compiler, Duktape uses C++ ``try-catch`` and\n``throw`` for internal long control transfers.  This allows automatic\ndestructors to run as expected.  The config option is not enabled by default\nbecause C++ exceptions are sometimes disabled even when a C++ compiler is\nused (e.g. for performance reasons).\n\nThe ``cpp_exceptions.cpp`` example illustrates how C++ exceptions can be\nused in Duktape/C functions at the moment:\n\n* Duktape uses C++ try/catch/throw internally; this is not visible to user\n  code directly.\n\n* Automatic destructors (scope-based resource management) work as expected.\n\n* C++ exceptions can be used in Duktape/C functions normally, but user\n  exceptions must be caught before they reach Duktape.  If this is not\n  done, such exceptions are caught by Duktape and converted to API errors\n  (in other words, they won't propagate \"through\" Duktape at the moment).\n"
  },
  {
    "path": "react_juce/duktape/examples/cpp-exceptions/cpp_exceptions.cpp",
    "content": "/*\n *  Example of how to use DUK_USE_CPP_EXCEPTIONS to support automatic\n *  variables (e.g. destructor calls) in Duktape/C functions.\n *\n *  Configure and compile with -DDUK_USE_CPP_EXCEPTIONS:\n *\n *    $ python2 tools/configure.py \\\n *          --source-directory src-input \\\n *          --output-directory /tmp/output \\\n *          --config-metadata config \\\n *          -DDUK_USE_CPP_EXCEPTIONS\n *\n *    $ g++ -otest -I/tmp/output \\\n *          /tmp/output/duktape.c cpp_exceptions.cpp -lm\n *\n *  When executed you should see something like:\n *\n *    $ ./test\n *    my_class instance created\n *    my_class instance destroyed      <== destructor gets called\n *    --> rc=1 (SyntaxError: parse error (line 1))\n *    [...]\n *\n *  Duktape uses a custom exception class (duk_internal_exception) which\n *  doesn't inherit from any base class, so that catching any base classes\n *  in user code won't accidentally catch exceptions thrown by Duktape.\n */\n\n#if !defined(__cplusplus)\n#error compile using a c++ compiler\n#endif\n\n#include <stdio.h>\n#include <exception>\n#include \"duktape.h\"\n\n#if defined(__cplusplus) && (__cplusplus >= 201103L)\n#define NOEXCEPT noexcept\n#else\n#define NOEXCEPT throw()\n#endif\n\n/*\n *  Example class with a destructor\n */\n\nclass my_class {\n public:\n\tmy_class();\n\t~my_class();\n};\n\nmy_class::my_class() {\n\tprintf(\"my_class instance created\\n\");\n}\n\nmy_class::~my_class() {\n\tprintf(\"my_class instance destroyed\\n\");\n}\n\n/*\n *  SyntaxError caused by eval exits Duktape/C function but destructors\n *  are executed.\n */\n\nduk_ret_t test1(duk_context *ctx) {\n\tmy_class myclass;\n\n\tduk_eval_string(ctx, \"aiee=\");\n\n\treturn 0;\n}\nduk_ret_t test1_safecall(duk_context *ctx, void *udata) {\n\t(void) udata;\n\treturn test1(ctx);\n}\n\n/*\n *  You can use C++ exceptions inside Duktape/C functions for your own\n *  purposes but you should catch them before they propagate to Duktape.\n */\n\nduk_ret_t test2(duk_context *ctx) {\n\tmy_class myclass;\n\n\ttry {\n\t\tthrow 123;\n\t} catch (int myvalue) {\n\t\tprintf(\"Caught: %d\\n\", myvalue);\n\t}\n\n\treturn 0;\n}\nduk_ret_t test2_safecall(duk_context *ctx, void *udata) {\n\t(void) udata;\n\treturn test2(ctx);\n}\n\n/*\n *  If you let your own C++ exceptions propagate out of a Duktape/C function\n *  it will be caught by Duktape and considered a programming error.  Duktape\n *  will catch the exception and convert it to a Duktape error.\n *\n *  This may be allowed in a later version once all the implications have been\n *  worked out.\n */\n\nduk_ret_t test3(duk_context *ctx) {\n\tmy_class myclass;\n\n\tthrow 123;  /* ERROR: exception propagated to Duktape */\n\n\treturn 0;\n}\nduk_ret_t test3_safecall(duk_context *ctx, void *udata) {\n\t(void) udata;\n\treturn test3(ctx);\n}\n\n/*\n *  Same as above, but if the exception inherits from std::exception, it's\n *  \"what()\" will be included in the error message.\n */\n\nclass my_exception : public std::exception {\n\tvirtual const char *what() const NOEXCEPT {\n\t\treturn \"my_exception\";\n\t}\n};\n\nduk_ret_t test4(duk_context *ctx) {\n\tmy_class myclass;\n\tmy_exception myexc;\n\n\tthrow myexc;  /* ERROR: exception propagated to Duktape */\n\n\treturn 0;\n}\nduk_ret_t test4_safecall(duk_context *ctx, void *udata) {\n\t(void) udata;\n\treturn test4(ctx);\n}\n\n/*\n *  Same as above, but if the exception inherits from std::exception with\n *  a NULL what().  Duktape will describe the error as 'unknown' if so.\n */\n\nclass my_exception2 : public std::exception {\n\tvirtual const char *what() const NOEXCEPT {\n\t\treturn NULL;\n\t}\n};\n\nduk_ret_t test5(duk_context *ctx) {\n\tmy_class myclass;\n\tmy_exception2 myexc;\n\n\tthrow myexc;  /* ERROR: exception propagated to Duktape */\n\n\treturn 0;\n}\nduk_ret_t test5_safecall(duk_context *ctx, void *udata) {\n\t(void) udata;\n\treturn test5(ctx);\n}\n\nstatic duk_ret_t duk__print(duk_context *ctx) {\n\tduk_push_string(ctx, \" \");\n\tduk_insert(ctx, 0);\n\tduk_join(ctx, duk_get_top(ctx) - 1);\n\tprintf(\"%s\\n\", duk_safe_to_string(ctx, -1));\n\treturn 0;\n}\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx = duk_create_heap_default();\n\tduk_int_t rc;\n\n\t(void) argc; (void) argv;  /* suppress warning */\n\n\t/* Minimal print() provider. */\n\tduk_push_c_function(ctx, duk__print, DUK_VARARGS);\n\tduk_put_global_string(ctx, \"print\");\n\n\tprintf(\"*** test1 - duk_pcall()\\n\");\n\tduk_push_c_function(ctx, test1, 0);\n\trc = duk_pcall(ctx, 0);\n\tprintf(\"--> rc=%ld (%s)\\n\", (long) rc, duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\tprintf(\"\\n\");\n\n\tprintf(\"*** test1 - duk_safe_call()\\n\");\n\trc = duk_safe_call(ctx, test1_safecall, NULL, 0, 1);\n\tprintf(\"--> rc=%ld (%s)\\n\", (long) rc, duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\tprintf(\"\\n\");\n\n\tprintf(\"*** test1 - ecmascript try-catch\\n\");\n\tduk_push_c_function(ctx, test1, 0);\n\tduk_put_global_string(ctx, \"test1\");\n\tduk_eval_string_noresult(ctx,\n\t\t\"try {\\n\"\n\t\t\"    test1();\\n\"\n\t\t\"} catch (e) {\\n\"\n\t\t\"    print(e.stack || e);\\n\"\n\t\t\"}\\n\");\n\tprintf(\"\\n\");\n\n\tprintf(\"*** test2 - duk_pcall()\\n\");\n\tduk_push_c_function(ctx, test2, 0);\n\trc = duk_pcall(ctx, 0);\n\tprintf(\"--> rc=%ld (%s)\\n\", (long) rc, duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\tprintf(\"\\n\");\n\n\tprintf(\"*** test2 - duk_safe_call()\\n\");\n\trc = duk_safe_call(ctx, test2_safecall, NULL, 0, 1);\n\tprintf(\"--> rc=%ld (%s)\\n\", (long) rc, duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\tprintf(\"\\n\");\n\n\tprintf(\"*** test2 - ecmascript try-catch\\n\");\n\tduk_push_c_function(ctx, test2, 0);\n\tduk_put_global_string(ctx, \"test2\");\n\tduk_eval_string_noresult(ctx,\n\t\t\"try {\\n\"\n\t\t\"    test2();\\n\"\n\t\t\"} catch (e) {\\n\"\n\t\t\"    print(e.stack || e);\\n\"\n\t\t\"}\\n\");\n\tprintf(\"\\n\");\n\n\tprintf(\"*** test3 - duk_pcall()\\n\");\n\tduk_push_c_function(ctx, test3, 0);\n\trc = duk_pcall(ctx, 0);\n\tprintf(\"--> rc=%ld (%s)\\n\", (long) rc, duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\tprintf(\"\\n\");\n\n\tprintf(\"*** test3 - duk_safe_call()\\n\");\n\trc = duk_safe_call(ctx, test3_safecall, NULL, 0, 1);\n\tprintf(\"--> rc=%ld (%s)\\n\", (long) rc, duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\tprintf(\"\\n\");\n\n\tprintf(\"*** test3 - ecmascript try-catch\\n\");\n\tduk_push_c_function(ctx, test3, 0);\n\tduk_put_global_string(ctx, \"test3\");\n\tduk_eval_string_noresult(ctx,\n\t\t\"try {\\n\"\n\t\t\"    test3();\\n\"\n\t\t\"} catch (e) {\\n\"\n\t\t\"    print(e.stack || e);\\n\"\n\t\t\"}\\n\");\n\tprintf(\"\\n\");\n\n\tprintf(\"*** test4 - duk_pcall()\\n\");\n\tduk_push_c_function(ctx, test4, 0);\n\trc = duk_pcall(ctx, 0);\n\tprintf(\"--> rc=%ld (%s)\\n\", (long) rc, duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\tprintf(\"\\n\");\n\n\tprintf(\"*** test4 - duk_safe_call()\\n\");\n\trc = duk_safe_call(ctx, test4_safecall, NULL, 0, 1);\n\tprintf(\"--> rc=%ld (%s)\\n\", (long) rc, duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\tprintf(\"\\n\");\n\n\tprintf(\"*** test4 - ecmascript try-catch\\n\");\n\tduk_push_c_function(ctx, test4, 0);\n\tduk_put_global_string(ctx, \"test4\");\n\tduk_eval_string_noresult(ctx,\n\t\t\"try {\\n\"\n\t\t\"    test4();\\n\"\n\t\t\"} catch (e) {\\n\"\n\t\t\"    print(e.stack || e);\\n\"\n\t\t\"}\\n\");\n\tprintf(\"\\n\");\n\n\tprintf(\"*** test5 - duk_pcall()\\n\");\n\tduk_push_c_function(ctx, test5, 0);\n\trc = duk_pcall(ctx, 0);\n\tprintf(\"--> rc=%ld (%s)\\n\", (long) rc, duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\tprintf(\"\\n\");\n\n\tprintf(\"*** test5 - duk_safe_call()\\n\");\n\trc = duk_safe_call(ctx, test5_safecall, NULL, 0, 1);\n\tprintf(\"--> rc=%ld (%s)\\n\", (long) rc, duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\tprintf(\"\\n\");\n\n\tprintf(\"*** test5 - ecmascript try-catch\\n\");\n\tduk_push_c_function(ctx, test5, 0);\n\tduk_put_global_string(ctx, \"test5\");\n\tduk_eval_string_noresult(ctx,\n\t\t\"try {\\n\"\n\t\t\"    test5();\\n\"\n\t\t\"} catch (e) {\\n\"\n\t\t\"    print(e.stack || e);\\n\"\n\t\t\"}\\n\");\n\tprintf(\"\\n\");\n\n\tprintf(\"*** done\\n\");\n\n\tduk_destroy_heap(ctx);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/debug-trans-dvalue/Makefile",
    "content": "DUKTAPE_OPTS=\nDUKTAPE_OPTS+=-DDUK_USE_ASSERTIONS\nDUKTAPE_OPTS+=-DDUK_USE_DEBUGGER_SUPPORT -DDUK_USE_INTERRUPT_COUNTER\nDUKTAPE_OPTS+=-DDUK_USE_DEBUGGER_DUMPHEAP\n#DUKTAPE_OPTS+=-DDUK_USE_DEBUGGER_TRANSPORT_TORTURE\nTRANS_OPTS=\n#TRANS_OPTS+=-DDEBUG_PRINTS\n\ntest: test.c duk_trans_dvalue.c duk_trans_dvalue.h\n\trm -rf ./prep\n\tpython2 ../../tools/configure.py \\\n\t\t--output-directory ./prep \\\n\t\t$(DUKTAPE_OPTS)\n\tgcc -O0 -g -ggdb -Wall -Wextra -std=c99 -o test -I./prep -I. \\\n\t\t$(TRANS_OPTS) \\\n\t\t./prep/duktape.c duk_trans_dvalue.c test.c -lm\n"
  },
  {
    "path": "react_juce/duktape/examples/debug-trans-dvalue/README.rst",
    "content": "===========================================================\nDebug transport with local debug protocol encoding/decoding\n===========================================================\n\nThis example implements a debug transport which decodes/encodes the Duktape\ndebug protocol locally into a more easy to use C interface, which is useful\nfor debug clients implemented locally on the target.  The example also\ndemonstrates how to trial parse dvalues in C.\n"
  },
  {
    "path": "react_juce/duktape/examples/debug-trans-dvalue/duk_trans_dvalue.c",
    "content": "/*\n *  Example debug transport with a local debug message encoder/decoder.\n *\n *  Provides a \"received dvalue\" callback for a fully parsed dvalue (user\n *  code frees dvalue) and a \"cooperate\" callback for e.g. UI integration.\n *  There are a few other callbacks.  See test.c for usage examples.\n *\n *  This transport implementation is not multithreaded which means that:\n *\n *    - Callbacks to \"received dvalue\" callback come from the Duktape thread,\n *      either during normal execution or from duk_debugger_cooperate().\n *\n *    - Calls into duk_trans_dvalue_send() must be made from the callbacks\n *      provided (e.g. \"received dvalue\" or \"cooperate\") which use the active\n *      Duktape thread.\n *\n *    - The only exception to this is when Duktape is idle: you can then call\n *      duk_trans_dvalue_send() from any thread (only one thread at a time).\n *      When you next call into Duktape or call duk_debugger_cooperate(), the\n *      queued data will be read and processed by Duktape.\n *\n *  There are functions for creating and freeing values; internally they use\n *  malloc() and free() for memory management.  Duktape heap alloc functions\n *  are not used to minimize disturbances to the Duktape heap under debugging.\n *\n *  Doesn't depend on C99 types; assumes \"int\" is at least 32 bits, and makes\n *  a few assumptions about format specifiers.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"duktape.h\"\n#include \"duk_trans_dvalue.h\"\n\n/* Define to enable debug prints to stderr. */\n#if 0\n#define DEBUG_PRINTS\n#endif\n\n/* Define to enable error prints to stderr. */\n#if 1\n#define ERROR_PRINTS\n#endif\n\n/*\n *  Dvalue handling\n */\n\nduk_dvalue *duk_dvalue_alloc(void) {\n\tduk_dvalue *dv = (duk_dvalue *) malloc(sizeof(duk_dvalue));\n\tif (dv) {\n\t\tmemset((void *) dv, 0, sizeof(duk_dvalue));\n\t\tdv->buf = NULL;\n\t}\n\treturn dv;\n}\n\nvoid duk_dvalue_free(duk_dvalue *dv) {\n\tif (dv) {\n\t\tfree(dv->buf);  /* tolerates NULL */\n\t\tdv->buf = NULL;\n\t\tfree(dv);\n\t}\n}\n\nstatic void duk__dvalue_bufesc(duk_dvalue *dv, char *buf, size_t maxbytes, int stresc) {\n\tsize_t i, limit;\n\n\t*buf = (char) 0;\n\tlimit = dv->len > maxbytes ? maxbytes : dv->len;\n\tfor (i = 0; i < limit; i++) {\n\t\tunsigned char c = dv->buf[i];\n\t\tif (stresc) {\n\t\t\tif (c >= 0x20 && c <= 0x7e && c != (char) '\"' && c != (char) '\\'') {\n\t\t\t\tsprintf(buf, \"%c\", c);\n\t\t\t\tbuf++;\n\t\t\t} else {\n\t\t\t\tsprintf(buf, \"\\\\x%02x\", (unsigned int) c);\n\t\t\t\tbuf += 4;\n\t\t\t}\n\t\t} else {\n\t\t\tsprintf(buf, \"%02x\", (unsigned int) c);\n\t\t\tbuf += 2;\n\t\t}\n\t}\n\tif (dv->len > maxbytes) {\n\t\tsprintf(buf, \"...\");\n\t\tbuf += 3;\n\t}\n}\n\n/* Caller must provide a buffer at least DUK_DVALUE_TOSTRING_BUFLEN in size. */\nvoid duk_dvalue_to_string(duk_dvalue *dv, char *buf) {\n\tchar hexbuf[32 * 4 + 4];  /* 32 hex encoded or \\xXX escaped bytes, possible \"...\", NUL */\n\n\tif (!dv) {\n\t\tsprintf(buf, \"NULL\");\n\t\treturn;\n\t}\n\n\tswitch (dv->tag) {\n\tcase DUK_DVALUE_EOM:\n\t\tsprintf(buf, \"EOM\");\n\t\tbreak;\n\tcase DUK_DVALUE_REQ:\n\t\tsprintf(buf, \"REQ\");\n\t\tbreak;\n\tcase DUK_DVALUE_REP:\n\t\tsprintf(buf, \"REP\");\n\t\tbreak;\n\tcase DUK_DVALUE_ERR:\n\t\tsprintf(buf, \"ERR\");\n\t\tbreak;\n\tcase DUK_DVALUE_NFY:\n\t\tsprintf(buf, \"NFY\");\n\t\tbreak;\n\tcase DUK_DVALUE_INTEGER:\n\t\tsprintf(buf, \"%d\", dv->i);\n\t\tbreak;\n\tcase DUK_DVALUE_STRING:\n\t\tduk__dvalue_bufesc(dv, hexbuf, 32, 1);\n\t\tsprintf(buf, \"str:%ld:\\\"%s\\\"\", (long) dv->len, hexbuf);\n\t\tbreak;\n\tcase DUK_DVALUE_BUFFER:\n\t\tduk__dvalue_bufesc(dv, hexbuf, 32, 0);\n\t\tsprintf(buf, \"buf:%ld:%s\", (long) dv->len, hexbuf);\n\t\tbreak;\n\tcase DUK_DVALUE_UNUSED:\n\t\tsprintf(buf, \"undefined\");\n\t\tbreak;\n\tcase DUK_DVALUE_UNDEFINED:\n\t\tsprintf(buf, \"undefined\");\n\t\tbreak;\n\tcase DUK_DVALUE_NULL:\n\t\tsprintf(buf, \"null\");\n\t\tbreak;\n\tcase DUK_DVALUE_TRUE:\n\t\tsprintf(buf, \"true\");\n\t\tbreak;\n\tcase DUK_DVALUE_FALSE:\n\t\tsprintf(buf, \"false\");\n\t\tbreak;\n\tcase DUK_DVALUE_NUMBER:\n\t\tif (fpclassify(dv->d) == FP_ZERO) {\n\t\t\tif (signbit(dv->d)) {\n\t\t\t\tsprintf(buf, \"-0\");\n\t\t\t} else {\n\t\t\t\tsprintf(buf, \"0\");\n\t\t\t}\n\t\t} else {\n\t\t\tsprintf(buf, \"%lg\", dv->d);\n\t\t}\n\t\tbreak;\n\tcase DUK_DVALUE_OBJECT:\n\t\tduk__dvalue_bufesc(dv, hexbuf, 32, 0);\n\t\tsprintf(buf, \"obj:%d:%s\", (int) dv->i, hexbuf);\n\t\tbreak;\n\tcase DUK_DVALUE_POINTER:\n\t\tduk__dvalue_bufesc(dv, hexbuf, 32, 0);\n\t\tsprintf(buf, \"ptr:%s\", hexbuf);\n\t\tbreak;\n\tcase DUK_DVALUE_LIGHTFUNC:\n\t\tduk__dvalue_bufesc(dv, hexbuf, 32, 0);\n\t\tsprintf(buf, \"lfunc:%04x:%s\", (unsigned int) dv->i, hexbuf);\n\t\tbreak;\n\tcase DUK_DVALUE_HEAPPTR:\n\t\tduk__dvalue_bufesc(dv, hexbuf, 32, 0);\n\t\tsprintf(buf, \"heapptr:%s\", hexbuf);\n\t\tbreak;\n\tdefault:\n\t\tsprintf(buf, \"unknown:%d\", (int) dv->tag);\n\t}\n}\n\nduk_dvalue *duk_dvalue_make_tag(int tag) {\n\tduk_dvalue *dv = duk_dvalue_alloc();\n\tif (!dv) { return NULL; }\n\tdv->tag = tag;\n\treturn dv;\n}\n\nduk_dvalue *duk_dvalue_make_tag_int(int tag, int intval) {\n\tduk_dvalue *dv = duk_dvalue_alloc();\n\tif (!dv) { return NULL; }\n\tdv->tag = tag;\n\tdv->i = intval;\n\treturn dv;\n}\n\nduk_dvalue *duk_dvalue_make_tag_double(int tag, double dblval) {\n\tduk_dvalue *dv = duk_dvalue_alloc();\n\tif (!dv) { return NULL; }\n\tdv->tag = tag;\n\tdv->d = dblval;\n\treturn dv;\n}\n\nduk_dvalue *duk_dvalue_make_tag_data(int tag, const char *buf, size_t len) {\n\tunsigned char *p;\n\tduk_dvalue *dv = duk_dvalue_alloc();\n\tif (!dv) { return NULL; }\n\t/* Alloc size is len + 1 so that a NUL terminator is always\n\t * guaranteed which is convenient, e.g. you can printf() the\n\t * value safely.\n\t */\n\tp = (unsigned char *) malloc(len + 1);\n\tif (!p) {\n\t\tfree(dv);\n\t\treturn NULL;\n\t}\n\tmemcpy((void *) p, (const void *) buf, len);\n\tp[len] = (unsigned char) 0;\n\tdv->tag = tag;\n\tdv->buf = p;\n\tdv->len = len;\n\treturn dv;\n}\n\nduk_dvalue *duk_dvalue_make_tag_int_data(int tag, int intval, const char *buf, size_t len) {\n\tduk_dvalue *dv = duk_dvalue_make_tag_data(tag, buf, len);\n\tif (!dv) { return NULL; }\n\tdv->i = intval;\n\treturn dv;\n}\n\n/*\n *  Dvalue transport handling\n */\n\nstatic void duk__trans_dvalue_double_byteswap(duk_trans_dvalue_ctx *ctx, volatile unsigned char *p) {\n\tunsigned char t;\n\n\t/* Portable IEEE double byteswap.  Relies on runtime detection of\n\t * host endianness.\n\t */\n\n\tif (ctx->double_byteorder == 0) {\n\t\t/* little endian */\n\t\tt = p[0]; p[0] = p[7]; p[7] = t;\n\t\tt = p[1]; p[1] = p[6]; p[6] = t;\n\t\tt = p[2]; p[2] = p[5]; p[5] = t;\n\t\tt = p[3]; p[3] = p[4]; p[4] = t;\n\t} else if (ctx->double_byteorder == 1) {\n\t\t/* big endian: ok as is */\n\t\t;\n\t} else {\n\t\t/* mixed endian */\n\t\tt = p[0]; p[0] = p[3]; p[3] = t;\n\t\tt = p[1]; p[1] = p[2]; p[2] = t;\n\t\tt = p[4]; p[4] = p[7]; p[7] = t;\n\t\tt = p[5]; p[5] = p[6]; p[6] = t;\n\t}\n}\n\nstatic unsigned int duk__trans_dvalue_parse_u32(duk_trans_dvalue_ctx *ctx, unsigned char *p) {\n\t/* Integers are network endian, read back into host format in\n\t * a portable manner.\n\t */\n\t(void) ctx;\n\treturn (((unsigned int) p[0]) << 24) +\n\t       (((unsigned int) p[1]) << 16) +\n\t       (((unsigned int) p[2]) << 8) +\n\t       (((unsigned int) p[3]) << 0);\n}\n\nstatic int duk__trans_dvalue_parse_i32(duk_trans_dvalue_ctx *ctx, unsigned char *p) {\n\t/* Portable sign handling, doesn't assume 'int' is exactly 32 bits\n\t * like a direct cast would.\n\t */\n\tunsigned int tmp = duk__trans_dvalue_parse_u32(ctx, p);\n\tif (tmp & 0x80000000UL) {\n\t\treturn -((int) ((tmp ^ 0xffffffffUL) + 1UL));\n\t} else {\n\t\treturn tmp;\n\t}\n}\n\nstatic unsigned int duk__trans_dvalue_parse_u16(duk_trans_dvalue_ctx *ctx, unsigned char *p) {\n\t/* Integers are network endian, read back into host format. */\n\t(void) ctx;\n\treturn (((unsigned int) p[0]) << 8) +\n\t       (((unsigned int) p[1]) << 0);\n}\n\nstatic double duk__trans_dvalue_parse_double(duk_trans_dvalue_ctx *ctx, unsigned char *p) {\n\t/* IEEE doubles are network endian, read back into host format. */\n\tvolatile union {\n\t\tdouble d;\n\t\tunsigned char b[8];\n\t} u;\n\tmemcpy((void *) u.b, (const void *) p, 8);\n\tduk__trans_dvalue_double_byteswap(ctx, u.b);\n\treturn u.d;\n}\n\nstatic unsigned char *duk__trans_dvalue_encode_u32(duk_trans_dvalue_ctx *ctx, unsigned char *p, unsigned int val) {\n\t/* Integers are written in network endian format. */\n\t(void) ctx;\n\t*p++ = (unsigned char) ((val >> 24) & 0xff);\n\t*p++ = (unsigned char) ((val >> 16) & 0xff);\n\t*p++ = (unsigned char) ((val >> 8) & 0xff);\n\t*p++ = (unsigned char) (val & 0xff);\n\treturn p;\n}\n\nstatic unsigned char *duk__trans_dvalue_encode_i32(duk_trans_dvalue_ctx *ctx, unsigned char *p, int val) {\n\treturn duk__trans_dvalue_encode_u32(ctx, p, (unsigned int) val & 0xffffffffUL);\n}\n\nstatic unsigned char *duk__trans_dvalue_encode_u16(duk_trans_dvalue_ctx *ctx, unsigned char *p, unsigned int val) {\n\t/* Integers are written in network endian format. */\n\t(void) ctx;\n\t*p++ = (unsigned char) ((val >> 8) & 0xff);\n\t*p++ = (unsigned char) (val & 0xff);\n\treturn p;\n}\n\nstatic unsigned char *duk__trans_dvalue_encode_double(duk_trans_dvalue_ctx *ctx, unsigned char *p, double val) {\n\t/* IEEE doubles are written in network endian format. */\n\tvolatile union {\n\t\tdouble d;\n\t\tunsigned char b[8];\n\t} u;\n\tu.d = val;\n\tduk__trans_dvalue_double_byteswap(ctx, u.b);\n\tmemcpy((void *) p, (const void *) u.b, 8);\n\tp += 8;\n\treturn p;\n}\n\nstatic unsigned char *duk__trans_buffer_ensure(duk_trans_buffer *dbuf, size_t space) {\n\tsize_t avail;\n\tsize_t used;\n\tsize_t new_size;\n\tvoid *new_alloc;\n\n\tused = dbuf->write_offset;\n\tavail = dbuf->alloc_size - dbuf->write_offset;\n\n\tif (avail >= space) {\n\t\tif (avail - space > 256) {\n\t\t\t/* Too big, resize so that we reclaim memory if we have just\n\t\t\t * received a large string/buffer value.\n\t\t\t */\n\t\t\tgoto do_realloc;\n\t\t}\n\t} else {\n\t\t/* Too small, resize. */\n\t\tgoto do_realloc;\n\t}\n\n\treturn dbuf->base + dbuf->write_offset;\n\n do_realloc:\n\tnew_size = used + space + 256;  /* some extra to reduce resizes */\n\tnew_alloc = realloc(dbuf->base, new_size);\n\tif (new_alloc) {\n\t\tdbuf->base = (unsigned char *) new_alloc;\n\t\tdbuf->alloc_size = new_size;\n#if defined(DEBUG_PRINTS)\n\t\tfprintf(stderr, \"%s: resized buffer %p to %ld bytes, read_offset=%ld, write_offset=%ld\\n\",\n\t\t        __func__, (void *) dbuf, (long) new_size, (long) dbuf->read_offset, (long) dbuf->write_offset);\n\t\tfflush(stderr);\n#endif\n\t\treturn dbuf->base + dbuf->write_offset;\n\t} else {\n\t\treturn NULL;\n\t}\n}\n\n/* When read_offset is large enough, \"rebase\" buffer by deleting already\n * read data and updating offsets.\n */\nstatic void duk__trans_buffer_rebase(duk_trans_buffer *dbuf) {\n\tif (dbuf->read_offset > 64) {\n#if defined(DEBUG_PRINTS)\n\t\tfprintf(stderr, \"%s: rebasing buffer %p, read_offset=%ld, write_offset=%ld\\n\",\n\t\t        __func__, (void *) dbuf, (long) dbuf->read_offset, (long) dbuf->write_offset);\n\t\tfflush(stderr);\n#endif\n\t\tif (dbuf->write_offset > dbuf->read_offset) {\n\t\t\tmemmove((void *) dbuf->base, (const void *) (dbuf->base + dbuf->read_offset), dbuf->write_offset - dbuf->read_offset);\n\t\t}\n\t\tdbuf->write_offset -= dbuf->read_offset;\n\t\tdbuf->read_offset = 0;\n\t}\n}\n\nduk_trans_dvalue_ctx *duk_trans_dvalue_init(void) {\n\tvolatile union {\n\t\tdouble d;\n\t\tunsigned char b[8];\n\t} u;\n\tduk_trans_dvalue_ctx *ctx = NULL;\n\n\tctx = (duk_trans_dvalue_ctx *) malloc(sizeof(duk_trans_dvalue_ctx));\n\tif (!ctx) { goto fail; }\n\tmemset((void *) ctx, 0, sizeof(duk_trans_dvalue_ctx));\n\tctx->received = NULL;\n\tctx->cooperate = NULL;\n\tctx->handshake = NULL;\n\tctx->detached = NULL;\n\tctx->send_buf.base = NULL;\n\tctx->recv_buf.base = NULL;\n\n\tctx->send_buf.base = malloc(256);\n\tif (!ctx->send_buf.base) { goto fail; }\n\tctx->send_buf.alloc_size = 256;\n\n\tctx->recv_buf.base = malloc(256);\n\tif (!ctx->recv_buf.base) { goto fail; }\n\tctx->recv_buf.alloc_size = 256;\n\n\t/* IEEE double byte order, detect at run time (could also use\n\t * preprocessor defines but that's verbose to make portable).\n\t *\n\t * >>> struct.unpack('>d', '1122334455667788'.decode('hex'))\n\t * (3.841412024471731e-226,)\n\t * >>> struct.unpack('>d', '8877665544332211'.decode('hex'))\n\t * (-7.086876636573014e-268,)\n\t * >>> struct.unpack('>d', '4433221188776655'.decode('hex'))\n\t * (3.5294303071877444e+20,)\n\t */\n\tu.b[0] = 0x11; u.b[1] = 0x22; u.b[2] = 0x33; u.b[3] = 0x44;\n\tu.b[4] = 0x55; u.b[5] = 0x66; u.b[6] = 0x77; u.b[7] = 0x88;\n\tif (u.d < 0.0) {\n\t\tctx->double_byteorder = 0;  /* little endian */\n\t} else if (u.d < 1.0) {\n\t\tctx->double_byteorder = 1;  /* big endian */\n\t} else {\n\t\tctx->double_byteorder = 2;  /* mixed endian (arm) */\n\t}\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"double endianness test value is %lg -> byteorder %d\\n\",\n\t        u.d, ctx->double_byteorder);\n\tfflush(stderr);\n#endif\n\n\treturn ctx;\n\n fail:\n\tif (ctx) {\n\t\tfree(ctx->recv_buf.base);  /* tolerates NULL */\n\t\tfree(ctx->send_buf.base);  /* tolerates NULL */\n\t\tfree(ctx);\n\t}\n\treturn NULL;\n}\n\nvoid duk_trans_dvalue_free(duk_trans_dvalue_ctx *ctx) {\n\tif (ctx) {\n\t\tfree(ctx->send_buf.base);  /* tolerates NULL */\n\t\tfree(ctx->recv_buf.base);  /* tolerates NULL */\n\t\tfree(ctx);\n\t}\n}\n\nvoid duk_trans_dvalue_send(duk_trans_dvalue_ctx *ctx, duk_dvalue *dv) {\n\tunsigned char *p;\n\n\t/* Convert argument dvalue into Duktape debug protocol format.\n\t * Literal constants are used here for the debug protocol,\n\t * e.g. initial byte 0x02 is REP, see doc/debugger.rst.\n\t */\n\n#if defined(DEBUG_PRINTS)\n\t{\n\t\tchar buf[DUK_DVALUE_TOSTRING_BUFLEN];\n\t\tduk_dvalue_to_string(dv, buf);\n\t\tfprintf(stderr, \"%s: sending dvalue: %s\\n\", __func__, buf);\n\t\tfflush(stderr);\n\t}\n#endif\n\n\tswitch (dv->tag) {\n\tcase DUK_DVALUE_EOM: {\n\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 1);\n\t\tif (!p) { goto alloc_error; }\n\t\t*p++ = 0x00;\n\t\tctx->send_buf.write_offset += 1;\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_REQ: {\n\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 1);\n\t\tif (!p) { goto alloc_error; }\n\t\t*p++ = 0x01;\n\t\tctx->send_buf.write_offset += 1;\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_REP: {\n\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 1);\n\t\tif (!p) { goto alloc_error; }\n\t\t*p++ = 0x02;\n\t\tctx->send_buf.write_offset += 1;\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_ERR: {\n\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 1);\n\t\tif (!p) { goto alloc_error; }\n\t\t*p++ = 0x03;\n\t\tctx->send_buf.write_offset += 1;\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_NFY: {\n\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 1);\n\t\tif (!p) { goto alloc_error; }\n\t\t*p++ = 0x04;\n\t\tctx->send_buf.write_offset += 1;\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_INTEGER: {\n\t\tint i = dv->i;\n\t\tif (i >= 0 && i <= 63) {\n\t\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 1);\n\t\t\tif (!p) { goto alloc_error; }\n\t\t\t*p++ = (unsigned char) (0x80 + i);\n\t\t\tctx->send_buf.write_offset += 1;\n\t\t} else if (i >= 0 && i <= 16383L) {\n\t\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 2);\n\t\t\tif (!p) { goto alloc_error; }\n\t\t\t*p++ = (unsigned char) (0xc0 + (i >> 8));\n\t\t\t*p++ = (unsigned char) (i & 0xff);\n\t\t\tctx->send_buf.write_offset += 2;\n\t\t} else if (i >= -0x80000000L && i <= 0x7fffffffL) {  /* Harmless warning on some platforms (re: range) */\n\t\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 5);\n\t\t\tif (!p) { goto alloc_error; }\n\t\t\t*p++ = 0x10;\n\t\t\tp = duk__trans_dvalue_encode_i32(ctx, p, i);\n\t\t\tctx->send_buf.write_offset += 5;\n\t\t} else {\n\t\t\tgoto dvalue_error;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_STRING: {\n\t\tsize_t i = dv->len;\n\t\tif (i <= 0x1fUL) {\n\t\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 1 + i);\n\t\t\tif (!p) { goto alloc_error; }\n\t\t\t*p++ = (unsigned char) (0x60 + i);\n\t\t\tmemcpy((void *) p, (const void *) dv->buf, i);\n\t\t\tp += i;\n\t\t\tctx->send_buf.write_offset += 1 + i;\n\t\t} else if (i <= 0xffffUL) {\n\t\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 3 + i);\n\t\t\tif (!p) { goto alloc_error; }\n\t\t\t*p++ = 0x12;\n\t\t\tp = duk__trans_dvalue_encode_u16(ctx, p, (unsigned int) i);\n\t\t\tmemcpy((void *) p, (const void *) dv->buf, i);\n\t\t\tp += i;\n\t\t\tctx->send_buf.write_offset += 3 + i;\n\t\t} else if (i <= 0xffffffffUL) {\n\t\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 5 + i);\n\t\t\tif (!p) { goto alloc_error; }\n\t\t\t*p++ = 0x11;\n\t\t\tp = duk__trans_dvalue_encode_u32(ctx, p, (unsigned int) i);\n\t\t\tmemcpy((void *) p, (const void *) dv->buf, i);\n\t\t\tp += i;\n\t\t\tctx->send_buf.write_offset += 5 + i;\n\t\t} else {\n\t\t\tgoto dvalue_error;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_BUFFER: {\n\t\tsize_t i = dv->len;\n\t\tif (i <= 0xffffUL) {\n\t\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 3 + i);\n\t\t\tif (!p) { goto alloc_error; }\n\t\t\t*p++ = 0x14;\n\t\t\tp = duk__trans_dvalue_encode_u16(ctx, p, (unsigned int) i);\n\t\t\tmemcpy((void *) p, (const void *) dv->buf, i);\n\t\t\tp += i;\n\t\t\tctx->send_buf.write_offset += 3 + i;\n\t\t} else if (i <= 0xffffffffUL) {\n\t\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 5 + i);\n\t\t\tif (!p) { goto alloc_error; }\n\t\t\t*p++ = 0x13;\n\t\t\tp = duk__trans_dvalue_encode_u32(ctx, p, (unsigned int) i);\n\t\t\tmemcpy((void *) p, (const void *) dv->buf, i);\n\t\t\tp += i;\n\t\t\tctx->send_buf.write_offset += 5 + i;\n\t\t} else {\n\t\t\tgoto dvalue_error;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_UNUSED: {\n\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 1);\n\t\tif (!p) { goto alloc_error; }\n\t\t*p++ = 0x15;\n\t\tctx->send_buf.write_offset += 1;\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_UNDEFINED: {\n\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 1);\n\t\tif (!p) { goto alloc_error; }\n\t\t*p++ = 0x16;\n\t\tctx->send_buf.write_offset += 1;\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_NULL: {\n\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 1);\n\t\tif (!p) { goto alloc_error; }\n\t\t*p++ = 0x17;\n\t\tctx->send_buf.write_offset += 1;\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_TRUE: {\n\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 1);\n\t\tif (!p) { goto alloc_error; }\n\t\t*p++ = 0x18;\n\t\tctx->send_buf.write_offset += 1;\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_FALSE: {\n\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 1);\n\t\tif (!p) { goto alloc_error; }\n\t\t*p++ = 0x19;\n\t\tctx->send_buf.write_offset += 1;\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_NUMBER: {\n\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 9);\n\t\tif (!p) { goto alloc_error; }\n\t\t*p++ = 0x1a;\n\t\tp = duk__trans_dvalue_encode_double(ctx, p, dv->d);\n\t\tctx->send_buf.write_offset += 9;\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_OBJECT: {\n\t\tsize_t i = dv->len;\n\t\tif (i <= 0xffUL && dv->i >= 0 && dv->i <= 0xffL) {\n\t\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 3 + i);\n\t\t\tif (!p) { goto alloc_error; }\n\t\t\t*p++ = 0x1b;\n\t\t\t*p++ = (unsigned char) dv->i;\n\t\t\t*p++ = (unsigned char) i;\n\t\t\tmemcpy((void *) p, (const void *) dv->buf, i);\n\t\t\tctx->send_buf.write_offset += 3 + i;\n\t\t} else {\n\t\t\tgoto dvalue_error;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_POINTER: {\n\t\tsize_t i = dv->len;\n\t\tif (i <= 0xffUL) {\n\t\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 2 + i);\n\t\t\tif (!p) { goto alloc_error; }\n\t\t\t*p++ = 0x1c;\n\t\t\t*p++ = (unsigned char) i;\n\t\t\tmemcpy((void *) p, (const void *) dv->buf, i);\n\t\t\tctx->send_buf.write_offset += 2 + i;\n\t\t} else {\n\t\t\tgoto dvalue_error;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_LIGHTFUNC: {\n\t\tsize_t i = dv->len;\n\t\tif (i <= 0xffUL && dv->i >= 0 && dv->i <= 0xffffL) {\n\t\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 4 + i);\n\t\t\tif (!p) { goto alloc_error; }\n\t\t\t*p++ = 0x1d;\n\t\t\tp = duk__trans_dvalue_encode_u16(ctx, p, (unsigned int) dv->i);\n\t\t\t*p++ = (unsigned char) i;\n\t\t\tmemcpy((void *) p, (const void *) dv->buf, i);\n\t\t\tctx->send_buf.write_offset += 4 + i;\n\t\t} else {\n\t\t\tgoto dvalue_error;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_DVALUE_HEAPPTR: {\n\t\tsize_t i = dv->len;\n\t\tif (i <= 0xffUL) {\n\t\t\tp = duk__trans_buffer_ensure(&ctx->send_buf, 2 + i);\n\t\t\tif (!p) { goto alloc_error; }\n\t\t\t*p++ = 0x1e;\n\t\t\t*p++ = (unsigned char) i;\n\t\t\tmemcpy((void *) p, (const void *) dv->buf, i);\n\t\t\tctx->send_buf.write_offset += 2 + i;\n\t\t} else {\n\t\t\tgoto dvalue_error;\n\t\t}\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tgoto dvalue_error;\n\t}\n\t}  /* end switch */\n\n\treturn;\n\n dvalue_error:\n#if defined(ERROR_PRINTS)\n\tfprintf(stderr, \"%s: internal error, argument dvalue is invalid\\n\", __func__);\n\tfflush(stdout);\n#endif\n\treturn;\n\n alloc_error:\n#if defined(ERROR_PRINTS)\n\tfprintf(stderr, \"%s: internal error, failed to allocate space for write\\n\", __func__);\n\tfflush(stdout);\n#endif\n\treturn;\n}\n\nstatic void duk__trans_dvalue_send_and_free(duk_trans_dvalue_ctx *ctx, duk_dvalue *dv) {\n\tif (!dv) { return; }\n\tduk_trans_dvalue_send(ctx, dv);\n\tduk_dvalue_free(dv);\n}\n\nvoid duk_trans_dvalue_send_eom(duk_trans_dvalue_ctx *ctx) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag(DUK_DVALUE_EOM));\n}\n\nvoid duk_trans_dvalue_send_req(duk_trans_dvalue_ctx *ctx) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag(DUK_DVALUE_REQ));\n}\n\nvoid duk_trans_dvalue_send_rep(duk_trans_dvalue_ctx *ctx) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag(DUK_DVALUE_REP));\n}\n\nvoid duk_trans_dvalue_send_err(duk_trans_dvalue_ctx *ctx) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag(DUK_DVALUE_ERR));\n}\n\nvoid duk_trans_dvalue_send_nfy(duk_trans_dvalue_ctx *ctx) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag(DUK_DVALUE_NFY));\n}\n\nvoid duk_trans_dvalue_send_integer(duk_trans_dvalue_ctx *ctx, int val) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag_int(DUK_DVALUE_INTEGER, val));\n}\n\nvoid duk_trans_dvalue_send_string(duk_trans_dvalue_ctx *ctx, const char *str) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag_data(DUK_DVALUE_STRING, str, strlen(str)));\n}\n\nvoid duk_trans_dvalue_send_lstring(duk_trans_dvalue_ctx *ctx, const char *str, size_t len) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag_data(DUK_DVALUE_STRING, str, len));\n}\n\nvoid duk_trans_dvalue_send_buffer(duk_trans_dvalue_ctx *ctx, const char *buf, size_t len) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag_data(DUK_DVALUE_BUFFER, buf, len));\n}\n\nvoid duk_trans_dvalue_send_unused(duk_trans_dvalue_ctx *ctx) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag(DUK_DVALUE_UNUSED));\n}\n\nvoid duk_trans_dvalue_send_undefined(duk_trans_dvalue_ctx *ctx) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag(DUK_DVALUE_UNDEFINED));\n}\n\nvoid duk_trans_dvalue_send_null(duk_trans_dvalue_ctx *ctx) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag(DUK_DVALUE_NULL));\n}\n\nvoid duk_trans_dvalue_send_true(duk_trans_dvalue_ctx *ctx) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag(DUK_DVALUE_TRUE));\n}\n\nvoid duk_trans_dvalue_send_false(duk_trans_dvalue_ctx *ctx) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag(DUK_DVALUE_FALSE));\n}\n\nvoid duk_trans_dvalue_send_number(duk_trans_dvalue_ctx *ctx, double val) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag_double(DUK_DVALUE_NUMBER, val));\n}\n\nvoid duk_trans_dvalue_send_object(duk_trans_dvalue_ctx *ctx, int classnum, const char *ptr_data, size_t ptr_len) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag_int_data(DUK_DVALUE_OBJECT, classnum, ptr_data, ptr_len));\n}\n\nvoid duk_trans_dvalue_send_pointer(duk_trans_dvalue_ctx *ctx, const char *ptr_data, size_t ptr_len) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag_data(DUK_DVALUE_POINTER, ptr_data, ptr_len));\n}\n\nvoid duk_trans_dvalue_send_lightfunc(duk_trans_dvalue_ctx *ctx, int lf_flags, const char *ptr_data, size_t ptr_len) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag_int_data(DUK_DVALUE_LIGHTFUNC, lf_flags, ptr_data, ptr_len));\n}\n\nvoid duk_trans_dvalue_send_heapptr(duk_trans_dvalue_ctx *ctx, const char *ptr_data, size_t ptr_len) {\n\tduk__trans_dvalue_send_and_free(ctx, duk_dvalue_make_tag_data(DUK_DVALUE_HEAPPTR, ptr_data, ptr_len));\n}\n\nvoid duk_trans_dvalue_send_req_cmd(duk_trans_dvalue_ctx *ctx, int cmd) {\n\tduk_trans_dvalue_send_req(ctx);\n\tduk_trans_dvalue_send_integer(ctx, cmd);\n}\n\nstatic duk_dvalue *duk__trans_trial_parse_dvalue(duk_trans_dvalue_ctx *ctx) {\n\tunsigned char *p;\n\tsize_t len;\n\tunsigned char ib;\n\tduk_dvalue *dv;\n\tsize_t datalen;\n\n\tp = ctx->recv_buf.base + ctx->recv_buf.read_offset;\n\tlen = ctx->recv_buf.write_offset - ctx->recv_buf.read_offset;\n\n\tif (len == 0) {\n\t\treturn NULL;\n\t}\n\tib = p[0];\n\n#if defined(DEBUG_PRINTS)\n\t{\n\t\tsize_t i;\n\t\tfprintf(stderr, \"%s: parsing dvalue, window:\", __func__);\n\t\tfor (i = 0; i < 16; i++) {\n\t\t\tif (i < len) {\n\t\t\t\tfprintf(stderr, \" %02x\", (unsigned int) p[i]);\n\t\t\t} else {\n\t\t\t\tfprintf(stderr, \" ??\");\n\t\t\t}\n\t\t}\n\t\tfprintf(stderr, \" (length %ld, read_offset %ld, write_offset %ld, alloc_size %ld)\\n\",\n\t\t        (long) len, (long) ctx->recv_buf.read_offset, (long) ctx->recv_buf.write_offset,\n\t\t        (long) ctx->recv_buf.alloc_size);\n\t\tfflush(stderr);\n\t}\n#endif\n\n\tif (ib <= 0x1fU) {\n\t\t/* 0x00 ... 0x1f */\n\t\tswitch (ib) {\n\t\tcase 0x00: {\n\t\t\tctx->recv_buf.read_offset += 1;\n\t\t\tdv = duk_dvalue_make_tag(DUK_DVALUE_EOM);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x01: {\n\t\t\tctx->recv_buf.read_offset += 1;\n\t\t\tdv = duk_dvalue_make_tag(DUK_DVALUE_REQ);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x02: {\n\t\t\tctx->recv_buf.read_offset += 1;\n\t\t\tdv = duk_dvalue_make_tag(DUK_DVALUE_REP);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x03: {\n\t\t\tctx->recv_buf.read_offset += 1;\n\t\t\tdv = duk_dvalue_make_tag(DUK_DVALUE_ERR);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x04: {\n\t\t\tctx->recv_buf.read_offset += 1;\n\t\t\tdv = duk_dvalue_make_tag(DUK_DVALUE_NFY);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x10: {\n\t\t\tint intval;\n\t\t\tif (len < 5) { goto partial; }\n\t\t\tintval = duk__trans_dvalue_parse_i32(ctx, p + 1);\n\t\t\tctx->recv_buf.read_offset += 5;\n\t\t\tdv = duk_dvalue_make_tag_int(DUK_DVALUE_INTEGER, intval);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x11: {\n\t\t\tif (len < 5) { goto partial; }\n\t\t\tdatalen = (size_t) duk__trans_dvalue_parse_u32(ctx, p + 1);\n\t\t\tif (len < 5 + datalen) { goto partial; }\n\t\t\tctx->recv_buf.read_offset += 5 + datalen;\n\t\t\tdv = duk_dvalue_make_tag_data(DUK_DVALUE_STRING, (const char *) (p + 5), datalen);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x12: {\n\t\t\tif (len < 3) { goto partial; }\n\t\t\tdatalen = (size_t) duk__trans_dvalue_parse_u16(ctx, p + 1);\n\t\t\tif (len < 3 + datalen) { goto partial; }\n\t\t\tctx->recv_buf.read_offset += 3 + datalen;\n\t\t\tdv = duk_dvalue_make_tag_data(DUK_DVALUE_STRING, (const char *) (p + 3), datalen);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x13: {\n\t\t\tif (len < 5) { goto partial; }\n\t\t\tdatalen = (size_t) duk__trans_dvalue_parse_u32(ctx, p + 1);\n\t\t\tif (len < 5 + datalen) { goto partial; }\n\t\t\tctx->recv_buf.read_offset += 5 + datalen;\n\t\t\tdv = duk_dvalue_make_tag_data(DUK_DVALUE_BUFFER, (const char *) (p + 5), datalen);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x14: {\n\t\t\tif (len < 3) { goto partial; }\n\t\t\tdatalen = (size_t) duk__trans_dvalue_parse_u16(ctx, p + 1);\n\t\t\tif (len < 3 + datalen) { goto partial; }\n\t\t\tctx->recv_buf.read_offset += 3 + datalen;\n\t\t\tdv = duk_dvalue_make_tag_data(DUK_DVALUE_BUFFER, (const char *) (p + 3), datalen);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x15: {\n\t\t\tctx->recv_buf.read_offset += 1;\n\t\t\tdv = duk_dvalue_make_tag(DUK_DVALUE_UNUSED);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x16: {\n\t\t\tctx->recv_buf.read_offset += 1;\n\t\t\tdv = duk_dvalue_make_tag(DUK_DVALUE_UNDEFINED);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x17: {\n\t\t\tctx->recv_buf.read_offset += 1;\n\t\t\tdv = duk_dvalue_make_tag(DUK_DVALUE_NULL);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x18: {\n\t\t\tctx->recv_buf.read_offset += 1;\n\t\t\tdv = duk_dvalue_make_tag(DUK_DVALUE_TRUE);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x19: {\n\t\t\tctx->recv_buf.read_offset += 1;\n\t\t\tdv = duk_dvalue_make_tag(DUK_DVALUE_FALSE);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x1a: {\n\t\t\tdouble dblval;\n\t\t\tif (len < 9) { goto partial; }\n\t\t\tdblval = duk__trans_dvalue_parse_double(ctx, p + 1);\n\t\t\tctx->recv_buf.read_offset += 9;\n\t\t\tdv = duk_dvalue_make_tag_double(DUK_DVALUE_NUMBER, dblval);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x1b: {\n\t\t\tint classnum;\n\t\t\tif (len < 3) { goto partial; }\n\t\t\tdatalen = (size_t) p[2];\n\t\t\tif (len < 3 + datalen) { goto partial; }\n\t\t\tclassnum = (int) p[1];\n\t\t\tctx->recv_buf.read_offset += 3 + datalen;\n\t\t\tdv = duk_dvalue_make_tag_int_data(DUK_DVALUE_OBJECT, classnum, (const char *) (p + 3), datalen);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x1c: {\n\t\t\tif (len < 2) { goto partial; }\n\t\t\tdatalen = (size_t) p[1];\n\t\t\tif (len < 2 + datalen) { goto partial; }\n\t\t\tctx->recv_buf.read_offset += 2 + datalen;\n\t\t\tdv = duk_dvalue_make_tag_data(DUK_DVALUE_POINTER, (const char *) (p + 2), datalen);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x1d: {\n\t\t\tint lf_flags;\n\t\t\tif (len < 4) { goto partial; }\n\t\t\tdatalen = (size_t) p[3];\n\t\t\tif (len < 4 + datalen) { goto partial; }\n\t\t\tlf_flags = (int) duk__trans_dvalue_parse_u16(ctx, p + 1);\n\t\t\tctx->recv_buf.read_offset += 4 + datalen;\n\t\t\tdv = duk_dvalue_make_tag_int_data(DUK_DVALUE_LIGHTFUNC, lf_flags, (const char *) (p + 4), datalen);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tcase 0x1e: {\n\t\t\tif (len < 2) { goto partial; }\n\t\t\tdatalen = (size_t) p[1];\n\t\t\tif (len < 2 + datalen) { goto partial; }\n\t\t\tctx->recv_buf.read_offset += 2 + datalen;\n\t\t\tdv = duk_dvalue_make_tag_data(DUK_DVALUE_HEAPPTR, (const char *) (p + 2), datalen);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t\tdefault: {\n\t\t\tgoto format_error;\n\t\t}\n\t\t}  /* end switch */\n\t} else if (ib <= 0x5fU) {\n\t\t/* 0x20 ... 0x5f */\n\t\tgoto format_error;\n\t} else if (ib <= 0x7fU) {\n\t\t/* 0x60 ... 0x7f */\n\t\tdatalen = (size_t) (ib - 0x60U);\n\t\tif (len < 1 + datalen) { goto partial; }\n\t\tctx->recv_buf.read_offset += 1 + datalen;\n\t\tdv = duk_dvalue_make_tag_data(DUK_DVALUE_STRING, (const char *) (p + 1), datalen);\n\t\tif (!dv) { goto alloc_error; }\n\t\treturn dv;\n\t} else if (ib <= 0xbfU) {\n\t\t/* 0x80 ... 0xbf */\n\t\tint intval;\n\t\tintval = (int) (ib - 0x80U);\n\t\tctx->recv_buf.read_offset += 1;\n\t\tdv = duk_dvalue_make_tag_int(DUK_DVALUE_INTEGER, intval);\n\t\tif (!dv) { goto alloc_error; }\n\t\treturn dv;\n\t} else {\n\t\t/* 0xc0 ... 0xff */\n\t\tint intval;\n\t\tif (len < 2) { goto partial; }\n\t\tintval = (((int) (ib - 0xc0U)) << 8) + (int) p[1];\n\t\tctx->recv_buf.read_offset += 2;\n\t\tdv = duk_dvalue_make_tag_int(DUK_DVALUE_INTEGER, intval);\n\t\tif (!dv) { goto alloc_error; }\n\t\treturn dv;\n\t}\n\n\t/* never here */\n\n partial:\n\treturn NULL;\n\n alloc_error:\n#if defined(ERROR_PRINTS)\n\tfprintf(stderr, \"%s: internal error, cannot allocate space for dvalue\\n\", __func__);\n\tfflush(stdout);\n#endif\n\treturn NULL;\n\n format_error:\n#if defined(ERROR_PRINTS)\n\tfprintf(stderr, \"%s: internal error, dvalue format error\\n\", __func__);\n\tfflush(stdout);\n#endif\n\treturn NULL;\n}\n\nstatic duk_dvalue *duk__trans_trial_parse_handshake(duk_trans_dvalue_ctx *ctx) {\n\tunsigned char *p;\n\tsize_t len;\n\tduk_dvalue *dv;\n\tsize_t i;\n\n\tp = ctx->recv_buf.base + ctx->recv_buf.read_offset;\n\tlen = ctx->recv_buf.write_offset - ctx->recv_buf.read_offset;\n\n\tfor (i = 0; i < len; i++) {\n\t\tif (p[i] == 0x0a) {\n\t\t\t/* Handshake line is returned as a dvalue for convenience; it's\n\t\t\t * not actually a part of the dvalue phase of the protocol.\n\t\t\t */\n\t\t\tctx->recv_buf.read_offset += i + 1;\n\t\t\tdv = duk_dvalue_make_tag_data(DUK_DVALUE_STRING, (const char *) p, i);\n\t\t\tif (!dv) { goto alloc_error; }\n\t\t\treturn dv;\n\t\t}\n\t}\n\n\treturn NULL;\n\n alloc_error:\n#if defined(ERROR_PRINTS)\n\tfprintf(stderr, \"%s: internal error, cannot allocate space for handshake line\\n\", __func__);\n\tfflush(stdout);\n#endif\n\treturn NULL;\n}\n\nstatic void duk__trans_call_cooperate(duk_trans_dvalue_ctx *ctx, int block) {\n\tif (ctx->cooperate) {\n\t\tctx->cooperate(ctx, block);\n\t}\n}\n\nstatic void duk__trans_call_received(duk_trans_dvalue_ctx *ctx, duk_dvalue *dv) {\n\tif (ctx->received) {\n\t\tctx->received(ctx, dv);\n\t}\n}\n\nstatic void duk__trans_call_handshake(duk_trans_dvalue_ctx *ctx, const char *line) {\n\tif (ctx->handshake) {\n\t\tctx->handshake(ctx, line);\n\t}\n}\n\nstatic void duk__trans_call_detached(duk_trans_dvalue_ctx *ctx) {\n\tif (ctx->detached) {\n\t\tctx->detached(ctx);\n\t}\n}\n\n/*\n *  Duktape callbacks\n */\n\nduk_size_t duk_trans_dvalue_read_cb(void *udata, char *buffer, duk_size_t length) {\n\tduk_trans_dvalue_ctx *ctx = (duk_trans_dvalue_ctx *) udata;\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: %p %p %ld\\n\", __func__, udata, (void *) buffer, (long) length);\n\tfflush(stderr);\n#endif\n\n\tduk__trans_call_cooperate(ctx, 0);\n\n\tfor (;;) {\n\t\tsize_t avail, now;\n\n\t\tavail = (size_t) (ctx->send_buf.write_offset - ctx->send_buf.read_offset);\n\t\tif (avail == 0) {\n\t\t\t/* Must cooperate until user callback provides data.  From\n\t\t\t * Duktape's perspective we MUST block until data is received.\n\t\t\t */\n\t\t\tduk__trans_call_cooperate(ctx, 1);\n\t\t} else {\n\t\t\tnow = avail;\n\t\t\tif (now > length) {\n\t\t\t\tnow = length;\n\t\t\t}\n\t\t\tmemcpy((void *) buffer, (const void *) (ctx->send_buf.base + ctx->send_buf.read_offset), now);\n\t\t\tduk__trans_buffer_rebase(&ctx->send_buf);\n\t\t\tctx->send_buf.read_offset += now;\n\t\t\treturn now;\n\t\t}\n\t}\n}\n\nduk_size_t duk_trans_dvalue_write_cb(void *udata, const char *buffer, duk_size_t length) {\n\tduk_trans_dvalue_ctx *ctx = (duk_trans_dvalue_ctx *) udata;\n\tunsigned char *p;\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: %p %p %ld\\n\", __func__, udata, (void *) buffer, (long) length);\n\tfflush(stderr);\n#endif\n\n\tduk__trans_call_cooperate(ctx, 0);\n\n\t/* Append data. */\n\tduk__trans_buffer_rebase(&ctx->recv_buf);\n\tp = duk__trans_buffer_ensure(&ctx->recv_buf, length);\n\tmemcpy((void *) p, (const void *) buffer, (size_t) length);\n\tctx->recv_buf.write_offset += length;\n\n\t/* Trial parse handshake line or dvalue(s). */\n\tif (!ctx->handshake_done) {\n\t\tduk_dvalue *dv = duk__trans_trial_parse_handshake(ctx);\n\t\tif (dv) {\n\t\t\t/* Handshake line is available for caller for the\n\t\t\t * duration of the callback, and must not be freed\n\t\t\t * by the caller.\n\t\t\t */\n\t\t\tduk__trans_call_handshake(ctx, (const char *) dv->buf);\n#if defined(DEBUG_PRINTS)\n\t\t\tfprintf(stderr, \"%s: handshake ok\\n\", __func__);\n\t\t\tfflush(stderr);\n#endif\n\t\t\tduk_dvalue_free(dv);\n\t\t\tctx->handshake_done = 1;\n\t\t}\n\t}\n\tif (ctx->handshake_done) {\n\t\tfor (;;) {\n\t\t\tduk_dvalue *dv = duk__trans_trial_parse_dvalue(ctx);\n\t\t\tif (dv) {\n#if defined(DEBUG_PRINTS)\n\t\t\t\t{\n\t\t\t\t\tchar buf[DUK_DVALUE_TOSTRING_BUFLEN];\n\t\t\t\t\tduk_dvalue_to_string(dv, buf);\n\t\t\t\t\tfprintf(stderr, \"%s: received dvalue: %s\\n\", __func__, buf);\n\t\t\t\t\tfflush(stderr);\n\t\t\t\t}\n#endif\n\n\t\t\t\tduk__trans_call_received(ctx, dv);\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tduk__trans_call_cooperate(ctx, 0);  /* just in case, if dvalues changed something */\n\n\treturn length;\n}\n\nduk_size_t duk_trans_dvalue_peek_cb(void *udata) {\n\tduk_trans_dvalue_ctx *ctx = (duk_trans_dvalue_ctx *) udata;\n\tsize_t avail;\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: %p\\n\", __func__, udata);\n\tfflush(stderr);\n#endif\n\n\tduk__trans_call_cooperate(ctx, 0);\n\tavail = (size_t) (ctx->send_buf.write_offset - ctx->send_buf.read_offset);\n\treturn (duk_size_t) avail;\n}\n\nvoid duk_trans_dvalue_read_flush_cb(void *udata) {\n\tduk_trans_dvalue_ctx *ctx = (duk_trans_dvalue_ctx *) udata;\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: %p\\n\", __func__, udata);\n\tfflush(stderr);\n#endif\n\n\tduk__trans_call_cooperate(ctx, 0);\n}\n\nvoid duk_trans_dvalue_write_flush_cb(void *udata) {\n\tduk_trans_dvalue_ctx *ctx = (duk_trans_dvalue_ctx *) udata;\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: %p\\n\", __func__, udata);\n\tfflush(stderr);\n#endif\n\n\tduk__trans_call_cooperate(ctx, 0);\n}\n\nvoid duk_trans_dvalue_detached_cb(duk_context *duk_ctx, void *udata) {\n\tduk_trans_dvalue_ctx *ctx = (duk_trans_dvalue_ctx *) udata;\n\n\t(void) duk_ctx;\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: %p\\n\", __func__, udata);\n\tfflush(stderr);\n#endif\n\n\tduk__trans_call_detached(ctx);\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/debug-trans-dvalue/duk_trans_dvalue.h",
    "content": "#if !defined(DUK_TRANS_DVALUE_H_INCLUDED)\n#define DUK_TRANS_DVALUE_H_INCLUDED\n\n#include \"duktape.h\"\n\ntypedef struct duk_dvalue duk_dvalue;\ntypedef struct duk_trans_buffer duk_trans_buffer;\ntypedef struct duk_trans_dvalue_ctx duk_trans_dvalue_ctx;\n\ntypedef void (*duk_trans_dvalue_received_function)(duk_trans_dvalue_ctx *ctx, duk_dvalue *dv);\ntypedef void (*duk_trans_dvalue_cooperate_function)(duk_trans_dvalue_ctx *ctx, int block);\ntypedef void (*duk_trans_dvalue_handshake_function)(duk_trans_dvalue_ctx *ctx, const char *handshake_line);\ntypedef void (*duk_trans_dvalue_detached_function)(duk_trans_dvalue_ctx *ctx);\n\n/* struct duk_dvalue 'tag' values, note that these have nothing to do with\n * Duktape debug protocol inital byte.  Struct fields used with the type\n * are noted next to the define.\n */\n#define DUK_DVALUE_EOM         1   /* no fields */\n#define DUK_DVALUE_REQ         2   /* no fields */\n#define DUK_DVALUE_REP         3   /* no fields */\n#define DUK_DVALUE_ERR         4   /* no fields */\n#define DUK_DVALUE_NFY         5   /* no fields */\n#define DUK_DVALUE_INTEGER     6   /* i: 32-bit signed integer */\n#define DUK_DVALUE_STRING      7   /* buf: string data, len: string length */\n#define DUK_DVALUE_BUFFER      8   /* buf: buffer data, len: buffer length */\n#define DUK_DVALUE_UNUSED      9   /* no fields */\n#define DUK_DVALUE_UNDEFINED   10  /* no fields */\n#define DUK_DVALUE_NULL        11  /* no fields */\n#define DUK_DVALUE_TRUE        12  /* no fields */\n#define DUK_DVALUE_FALSE       13  /* no fields */\n#define DUK_DVALUE_NUMBER      14  /* d: ieee double */\n#define DUK_DVALUE_OBJECT      15  /* i: class number, buf: pointer data, len: pointer length */\n#define DUK_DVALUE_POINTER     16  /* buf: pointer data, len: pointer length */\n#define DUK_DVALUE_LIGHTFUNC   17  /* i: lightfunc flags, buf: pointer data, len: pointer length */\n#define DUK_DVALUE_HEAPPTR     18  /* buf: pointer data, len: pointer length */\n\nstruct duk_dvalue {\n\t/* Could use a union for the value but the gain would be relatively small. */\n\tint tag;\n\tint i;\n\tdouble d;\n\tsize_t len;\n\tunsigned char *buf;\n};\n\nstruct duk_trans_buffer {\n\tunsigned char *base;\n\tsize_t write_offset;\n\tsize_t read_offset;\n\tsize_t alloc_size;\n};\n\nstruct duk_trans_dvalue_ctx {\n\tduk_trans_dvalue_received_function received;\n\tduk_trans_dvalue_cooperate_function cooperate;\n\tduk_trans_dvalue_handshake_function handshake;\n\tduk_trans_dvalue_detached_function detached;\n\tduk_trans_buffer send_buf;  /* sending towards Duktape (duktape read callback) */\n\tduk_trans_buffer recv_buf;  /* receiving from Duktape (duktape write callback) */\n\tint handshake_done;\n\tint double_byteorder;  /* 0=little endian, 1=big endian, 2=mixed endian */\n};\n\n/* Buffer size needed by duk_dvalue_to_string(). */\n#define DUK_DVALUE_TOSTRING_BUFLEN 256\n\n/* Dvalue handling. */\nduk_dvalue *duk_dvalue_alloc(void);\nvoid duk_dvalue_free(duk_dvalue *dv);\nvoid duk_dvalue_to_string(duk_dvalue *dv, char *buf);\nduk_dvalue *duk_dvalue_make_tag(int tag);\nduk_dvalue *duk_dvalue_make_tag_int(int tag, int intval);\nduk_dvalue *duk_dvalue_make_tag_double(int tag, double dblval);\nduk_dvalue *duk_dvalue_make_tag_data(int tag, const char *buf, size_t len);\nduk_dvalue *duk_dvalue_make_tag_int_data(int tag, int intval, const char *buf, size_t len);\n\n/* Initializing and freeing the transport context. */\nduk_trans_dvalue_ctx *duk_trans_dvalue_init(void);\nvoid duk_trans_dvalue_free(duk_trans_dvalue_ctx *ctx);\n\n/* Sending dvalues towards Duktape. */\nvoid duk_trans_dvalue_send(duk_trans_dvalue_ctx *ctx, duk_dvalue *dv);\nvoid duk_trans_dvalue_send_eom(duk_trans_dvalue_ctx *ctx);\nvoid duk_trans_dvalue_send_req(duk_trans_dvalue_ctx *ctx);\nvoid duk_trans_dvalue_send_rep(duk_trans_dvalue_ctx *ctx);\nvoid duk_trans_dvalue_send_err(duk_trans_dvalue_ctx *ctx);\nvoid duk_trans_dvalue_send_nfy(duk_trans_dvalue_ctx *ctx);\nvoid duk_trans_dvalue_send_integer(duk_trans_dvalue_ctx *ctx, int val);\nvoid duk_trans_dvalue_send_string(duk_trans_dvalue_ctx *ctx, const char *str);\nvoid duk_trans_dvalue_send_lstring(duk_trans_dvalue_ctx *ctx, const char *str, size_t len);\nvoid duk_trans_dvalue_send_buffer(duk_trans_dvalue_ctx *ctx, const char *buf, size_t len);\nvoid duk_trans_dvalue_send_unused(duk_trans_dvalue_ctx *ctx);\nvoid duk_trans_dvalue_send_undefined(duk_trans_dvalue_ctx *ctx);\nvoid duk_trans_dvalue_send_null(duk_trans_dvalue_ctx *ctx);\nvoid duk_trans_dvalue_send_true(duk_trans_dvalue_ctx *ctx);\nvoid duk_trans_dvalue_send_false(duk_trans_dvalue_ctx *ctx);\nvoid duk_trans_dvalue_send_number(duk_trans_dvalue_ctx *ctx, double val);\nvoid duk_trans_dvalue_send_object(duk_trans_dvalue_ctx *ctx, int classnum, const char *ptr_data, size_t ptr_len);\nvoid duk_trans_dvalue_send_pointer(duk_trans_dvalue_ctx *ctx, const char *ptr_data, size_t ptr_len);\nvoid duk_trans_dvalue_send_lightfunc(duk_trans_dvalue_ctx *ctx, int lf_flags, const char *ptr_data, size_t ptr_len);\nvoid duk_trans_dvalue_send_heapptr(duk_trans_dvalue_ctx *ctx, const char *ptr_data, size_t ptr_len);\nvoid duk_trans_dvalue_send_req_cmd(duk_trans_dvalue_ctx *ctx, int cmd);\n\n/* Duktape debug callbacks provided by the transport. */\nduk_size_t duk_trans_dvalue_read_cb(void *udata, char *buffer, duk_size_t length);\nduk_size_t duk_trans_dvalue_write_cb(void *udata, const char *buffer, duk_size_t length);\nduk_size_t duk_trans_dvalue_peek_cb(void *udata);\nvoid duk_trans_dvalue_read_flush_cb(void *udata);\nvoid duk_trans_dvalue_write_flush_cb(void *udata);\nvoid duk_trans_dvalue_detached_cb(duk_context *ctx, void *udata);\n\n#endif  /* DUK_TRANS_DVALUE_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/examples/debug-trans-dvalue/test.c",
    "content": "/*\n *  Example program using the dvalue debug transport.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n\n#include \"duktape.h\"\n#include \"duk_trans_dvalue.h\"\n\nvoid my_cooperate(duk_trans_dvalue_ctx *ctx, int block) {\n\tstatic int first_blocked = 1;\n\n\tif (!block) {\n\t\t/* Duktape is not blocked; you can cooperate with e.g. a user\n\t\t * interface here and send dvalues to Duktape, but don't block.\n\t\t */\n\t\treturn;\n\t}\n\n\t/* Duktape is blocked on a read and won't continue until debug\n\t * command(s) are sent.\n\t *\n\t * Normally you'd enter your own event loop here, and process\n\t * events until something needs to be sent to Duktape.  For\n\t * example, the user might press a \"Step over\" button in the\n\t * UI which would cause dvalues to be sent.  You can then\n\t * return from this callback.\n\t *\n\t * The code below sends some example messages for testing the\n\t * dvalue handling of the transport.\n\t *\n\t * If you create dvalues manually and send them using\n\t * duk_trans_dvalue_send(), you must free the dvalues after\n\t * the send call returns using duk_dvalue_free().\n\t */\n\n\tif (first_blocked) {\n\t\tchar *tmp;\n\t\tint i;\n\n\t\t/* First time Duktape becomes blocked, send DumpHeap which\n\t\t * exercises a lot of parsing code.\n\t\t *\n\t\t * NOTE: Valgrind may complain about reading uninitialized\n\t\t * bytes.  This is caused by the DumpHeap command writing out\n\t\t * verbatim duk_tval values which are intentionally not\n\t\t * always fully initialized for performance reasons.\n\t\t */\n\t\tfirst_blocked = 0;\n\n\t\tfprintf(stderr, \"Duktape is blocked, send DumpHeap\\n\");\n\t\tfflush(stderr);\n\n\t\tduk_trans_dvalue_send_req(ctx);\n\t\tduk_trans_dvalue_send_integer(ctx, 0x20);  /* DumpHeap */\n\t\tduk_trans_dvalue_send_eom(ctx);\n\n\t\t/* Also send a dummy TriggerStatus request with trailing dvalues\n\t\t * ignored by Duktape; Duktape will parse the dvalues to be able to\n\t\t * skip them, so that the dvalue encoding is exercised.\n\t\t */\n\n\t\ttmp = malloc(100000);  /* long buffer, >= 65536 chars */\n\t\tfor (i = 0; i < 100000; i++) {\n\t\t\ttmp[i] = (char) i;\n\t\t}\n\t\tduk_trans_dvalue_send_req(ctx);\n\t\tduk_trans_dvalue_send_integer(ctx, 0x11);  /* TriggerStatus */\n\t\tduk_trans_dvalue_send_string(ctx, \"dummy\");  /* short, <= 31 chars */\n\t\tduk_trans_dvalue_send_string(ctx, \"123456789012345678901234567890foobar\");  /* medium, >= 32 chars */\n\t\tduk_trans_dvalue_send_lstring(ctx, (const char *) tmp, 65535UL);\n\t\tduk_trans_dvalue_send_lstring(ctx, (const char *) tmp, 65536UL);\n\t\tduk_trans_dvalue_send_lstring(ctx, (const char *) tmp, 100000UL);\n\t\tduk_trans_dvalue_send_buffer(ctx, (const char *) tmp, 255U);\n\t\tduk_trans_dvalue_send_buffer(ctx, (const char *) tmp, 65535UL);\n\t\tduk_trans_dvalue_send_buffer(ctx, (const char *) tmp, 65536UL);\n\t\tduk_trans_dvalue_send_buffer(ctx, (const char *) tmp, 100000UL);\n\t\tduk_trans_dvalue_send_unused(ctx);\n\t\tduk_trans_dvalue_send_undefined(ctx);\n\t\tduk_trans_dvalue_send_null(ctx);\n\t\tduk_trans_dvalue_send_true(ctx);\n\t\tduk_trans_dvalue_send_false(ctx);\n\t\tduk_trans_dvalue_send_number(ctx, 123.456);\n\t\tduk_trans_dvalue_send_object(ctx, 12 /*classnum*/, (const char *) tmp, 8);  /* fake ptr len */\n\t\tduk_trans_dvalue_send_pointer(ctx, (const char *) tmp, 8);  /* fake ptr len */\n\t\tduk_trans_dvalue_send_lightfunc(ctx, 0xdabc /*lf_flags*/, (const char *) tmp, 8);  /* fake ptr len */\n\t\tduk_trans_dvalue_send_heapptr(ctx, (const char *) tmp, 8);  /* fake ptr len */\n\n\t\tduk_trans_dvalue_send_eom(ctx);\n\t}\n\n\tfprintf(stderr, \"Duktape is blocked, send Eval and StepInto to resume execution\\n\");\n\tfflush(stderr);\n\n\t/* duk_trans_dvalue_send_req_cmd() sends a REQ dvalue followed by\n\t * an integer dvalue (command) for convenience.\n\t */\n\n\tduk_trans_dvalue_send_req_cmd(ctx, 0x1e);  /* 0x1e = Eval */\n\tduk_trans_dvalue_send_string(ctx, \"evalMe\");\n\tduk_trans_dvalue_send_eom(ctx);\n\n\tduk_trans_dvalue_send_req_cmd(ctx, 0x14);  /* 0x14 = StepOver */\n\tduk_trans_dvalue_send_eom(ctx);\n}\n\nvoid my_received(duk_trans_dvalue_ctx *ctx, duk_dvalue *dv) {\n\tchar buf[DUK_DVALUE_TOSTRING_BUFLEN];\n\t(void) ctx;\n\n\tduk_dvalue_to_string(dv, buf);\n\tfprintf(stderr, \"Received dvalue: %s\\n\", buf);\n\tfflush(stderr);\n\n\t/* Here a normal debug client would wait for dvalues until an EOM\n\t * dvalue was received (which completes a debug message).  The\n\t * debug message would then be handled, possibly causing UI changes\n\t * and/or causing debug commands to be sent to Duktape.\n\t *\n\t * The callback is responsible for eventually freeing the dvalue.\n\t * Here we free it immediately, but an actual client would probably\n\t * gather dvalues into an array or linked list to handle when the\n\t * debug message was complete.\n\t */\n\n\tduk_dvalue_free(dv);\n}\n\nvoid my_handshake(duk_trans_dvalue_ctx *ctx, const char *line) {\n\t(void) ctx;\n\n\t/* The Duktape handshake line is given in 'line' (without LF).\n\t * The 'line' argument can be accessed for the duration of the\n\t * callback (read only).  Don't free 'line' here, the transport\n\t * handles that.\n\t */\n\n\tfprintf(stderr, \"Received handshake line: '%s'\\n\", line);\n\tfflush(stderr);\n}\n\nvoid my_detached(duk_trans_dvalue_ctx *ctx) {\n\t(void) ctx;\n\n\t/* Detached call forwarded as is. */\n\n\tfprintf(stderr, \"Debug transport detached\\n\");\n\tfflush(stderr);\n}\n\nstatic duk_ret_t native_print(duk_context *ctx) {\n\tduk_push_string(ctx, \" \");\n\tduk_insert(ctx, 0);\n\tduk_join(ctx, duk_get_top(ctx) - 1);\n\tprintf(\"%s\\n\", duk_to_string(ctx, -1));\n\treturn 0;\n}\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx;\n\tduk_trans_dvalue_ctx *trans_ctx;\n\tint exitval = 0;\n\n\t(void) argc; (void) argv;  /* suppress warning */\n\n\tctx = duk_create_heap_default();\n\tif (!ctx) {\n\t\tfprintf(stderr, \"Failed to create Duktape heap\\n\");\n\t\tfflush(stderr);\n\t\texitval = 1;\n\t\tgoto cleanup;\n\t}\n\n\tduk_push_c_function(ctx, native_print, DUK_VARARGS);\n\tduk_put_global_string(ctx, \"print\");\n\n\ttrans_ctx = duk_trans_dvalue_init();\n\tif (!trans_ctx) {\n\t\tfprintf(stderr, \"Failed to create debug transport context\\n\");\n\t\tfflush(stderr);\n\t\texitval = 1;\n\t\tgoto cleanup;\n\t}\n\ttrans_ctx->cooperate = my_cooperate;\n\ttrans_ctx->received = my_received;\n\ttrans_ctx->handshake = my_handshake;\n\ttrans_ctx->detached = my_detached;\n\n\t/* Attach debugger; this will fail with a fatal error here unless\n\t * debugger support is compiled in.  To fail more gracefully, call\n\t * this under a duk_safe_call() to catch the error.\n\t */\n\tduk_debugger_attach(ctx,\n\t                    duk_trans_dvalue_read_cb,\n\t                    duk_trans_dvalue_write_cb,\n\t                    duk_trans_dvalue_peek_cb,\n\t                    duk_trans_dvalue_read_flush_cb,\n\t                    duk_trans_dvalue_write_flush_cb,\n\t                    NULL,  /* app request cb */\n\t                    duk_trans_dvalue_detached_cb,\n\t                    (void *) trans_ctx);\n\n\tfprintf(stderr, \"Debugger attached, running eval\\n\");\n\tfflush(stderr);\n\n\t/* Evaluate simple test code, callbacks will \"step over\" until end.\n\t *\n\t * The test code here is just for exercising the debug transport.\n\t * The 'evalMe' variable is evaluated (using debugger command Eval)\n\t * before every step to force different dvalues to be carried over\n\t * the transport.\n\t */\n\n\tduk_eval_string(ctx,\n\t\t\"var evalMe;\\n\"\n\t\t\"\\n\"\n\t\t\"print('Hello world!');\\n\"\n\t\t\"[ undefined, null, true, false, 123, -123, 123.1, 0, -0, 1/0, 0/0, -1/0, \\n\"\n\t\t\"  'foo', Uint8Array.allocPlain('bar'), Duktape.Pointer('dummy'), Math.cos, \\n\"\n\t\t\"].forEach(function (val) {\\n\"\n\t\t\"    print(val);\\n\"\n\t\t\"    evalMe = val;\\n\"\n\t\t\"});\\n\"\n\t\t\"\\n\"\n\t\t\"var str = 'xxx'\\n\"\n\t\t\"for (i = 0; i < 10; i++) {\\n\"\n\t\t\"    print(i, str);\\n\"\n\t\t\"    evalMe = str;\\n\"\n\t\t\"    evalMe = Uint8Array.allocPlain(str);\\n\"\n\t\t\"    str = str + str;\\n\"\n\t\t\"}\\n\"\n\t);\n\tduk_pop(ctx);\n\n\tduk_debugger_detach(ctx);\n\n cleanup:\n\tif (trans_ctx) {\n\t\tduk_trans_dvalue_free(trans_ctx);\n\t\ttrans_ctx = NULL;\n\t}\n\tif (ctx) {\n\t\tduk_destroy_heap(ctx);\n\t}\n\n\treturn exitval;\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/debug-trans-socket/README.rst",
    "content": "================================================\nDebug transport using a simple socket connection\n================================================\n\nThis example implements an example debug transport which uses a Linux or\nWindows TCP server socket on the debug target.\n\nFiles:\n\n* ``duk_trans_socket.h``: header file for the transport, used for both Linux\n  and Windows socket variants.\n\n* ``duk_trans_socket_unix.c``: implementation for Linux/Unix.\n\n* ``duk_trans_socket_windows.c``: implementation for Windows.\n\nCompile either Unix or Windows source file only.\n"
  },
  {
    "path": "react_juce/duktape/examples/debug-trans-socket/duk_trans_socket.h",
    "content": "#if !defined(DUK_TRANS_SOCKET_H_INCLUDED)\n#define DUK_TRANS_SOCKET_H_INCLUDED\n\n#include \"duktape.h\"\n\nvoid duk_trans_socket_init(void);\nvoid duk_trans_socket_finish(void);\nvoid duk_trans_socket_waitconn(void);\nduk_size_t duk_trans_socket_read_cb(void *udata, char *buffer, duk_size_t length);\nduk_size_t duk_trans_socket_write_cb(void *udata, const char *buffer, duk_size_t length);\nduk_size_t duk_trans_socket_peek_cb(void *udata);\nvoid duk_trans_socket_read_flush_cb(void *udata);\nvoid duk_trans_socket_write_flush_cb(void *udata);\n\n#endif  /* DUK_TRANS_SOCKET_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/examples/debug-trans-socket/duk_trans_socket_unix.c",
    "content": "/*\n *  Example debug transport using a Linux/Unix TCP socket\n *\n *  Provides a TCP server socket which a debug client can connect to.\n *  After that data is just passed through.\n *\n *  On some UNIX systems poll() may not be available but select() is.\n *  The default is to use poll(), but you can switch to select() by\n *  defining USE_SELECT.  See https://daniel.haxx.se/docs/poll-vs-select.html.\n */\n\n#include <stdio.h>\n#include <string.h>\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <unistd.h>\n#if !defined(USE_SELECT)\n#include <poll.h>\n#endif  /* !USE_SELECT */\n#include <errno.h>\n#include \"duktape.h\"\n#include \"duk_trans_socket.h\"\n\n#if !defined(DUK_DEBUG_PORT)\n#define DUK_DEBUG_PORT 9091\n#endif\n\n#if 0\n#define DEBUG_PRINTS\n#endif\n\nstatic int server_sock = -1;\nstatic int client_sock = -1;\n\n/*\n *  Transport init and finish\n */\n\nvoid duk_trans_socket_init(void) {\n\tstruct sockaddr_in addr;\n\tint on;\n\n\tserver_sock = socket(AF_INET, SOCK_STREAM, 0);\n\tif (server_sock < 0) {\n\t\tfprintf(stderr, \"%s: failed to create server socket: %s\\n\",\n\t\t        __FILE__, strerror(errno));\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\ton = 1;\n\tif (setsockopt(server_sock, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof(on)) < 0) {\n\t\tfprintf(stderr, \"%s: failed to set SO_REUSEADDR for server socket: %s\\n\",\n\t\t        __FILE__, strerror(errno));\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\tmemset((void *) &addr, 0, sizeof(addr));\n\taddr.sin_family = AF_INET;\n\taddr.sin_addr.s_addr = INADDR_ANY;\n\taddr.sin_port = htons(DUK_DEBUG_PORT);\n\n\tif (bind(server_sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {\n\t\tfprintf(stderr, \"%s: failed to bind server socket: %s\\n\",\n\t\t        __FILE__, strerror(errno));\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\tlisten(server_sock, 1 /*backlog*/);\n\treturn;\n\n fail:\n\tif (server_sock >= 0) {\n\t\t(void) close(server_sock);\n\t\tserver_sock = -1;\n\t}\n}\n\nvoid duk_trans_socket_finish(void) {\n\tif (client_sock >= 0) {\n\t\t(void) close(client_sock);\n\t\tclient_sock = -1;\n\t}\n\tif (server_sock >= 0) {\n\t\t(void) close(server_sock);\n\t\tserver_sock = -1;\n\t}\n}\n\nvoid duk_trans_socket_waitconn(void) {\n\tstruct sockaddr_in addr;\n\tsocklen_t sz;\n\n\tif (server_sock < 0) {\n\t\tfprintf(stderr, \"%s: no server socket, skip waiting for connection\\n\",\n\t\t        __FILE__);\n\t\tfflush(stderr);\n\t\treturn;\n\t}\n\tif (client_sock >= 0) {\n\t\t(void) close(client_sock);\n\t\tclient_sock = -1;\n\t}\n\n\tfprintf(stderr, \"Waiting for debug connection on port %d\\n\", (int) DUK_DEBUG_PORT);\n\tfflush(stderr);\n\n\tsz = (socklen_t) sizeof(addr);\n\tclient_sock = accept(server_sock, (struct sockaddr *) &addr, &sz);\n\tif (client_sock < 0) {\n\t\tfprintf(stderr, \"%s: accept() failed, skip waiting for connection: %s\\n\",\n\t\t        __FILE__, strerror(errno));\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\tfprintf(stderr, \"Debug connection established\\n\");\n\tfflush(stderr);\n\n\t/* XXX: For now, close the listen socket because we won't accept new\n\t * connections anyway.  A better implementation would allow multiple\n\t * debug attaches.\n\t */\n\n\tif (server_sock >= 0) {\n\t\t(void) close(server_sock);\n\t\tserver_sock = -1;\n\t}\n\treturn;\n\n fail:\n\tif (client_sock >= 0) {\n\t\t(void) close(client_sock);\n\t\tclient_sock = -1;\n\t}\n}\n\n/*\n *  Duktape callbacks\n */\n\n/* Duktape debug transport callback: (possibly partial) read. */\nduk_size_t duk_trans_socket_read_cb(void *udata, char *buffer, duk_size_t length) {\n\tssize_t ret;\n\n\t(void) udata;  /* not needed by the example */\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: udata=%p, buffer=%p, length=%ld\\n\",\n\t        __func__, (void *) udata, (void *) buffer, (long) length);\n\tfflush(stderr);\n#endif\n\n\tif (client_sock < 0) {\n\t\treturn 0;\n\t}\n\n\tif (length == 0) {\n\t\t/* This shouldn't happen. */\n\t\tfprintf(stderr, \"%s: read request length == 0, closing connection\\n\",\n\t\t        __FILE__);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\tif (buffer == NULL) {\n\t\t/* This shouldn't happen. */\n\t\tfprintf(stderr, \"%s: read request buffer == NULL, closing connection\\n\",\n\t\t        __FILE__);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\t/* In a production quality implementation there would be a sanity\n\t * timeout here to recover from \"black hole\" disconnects.\n\t */\n\n\tret = read(client_sock, (void *) buffer, (size_t) length);\n\tif (ret < 0) {\n\t\tfprintf(stderr, \"%s: debug read failed, closing connection: %s\\n\",\n\t\t        __FILE__, strerror(errno));\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t} else if (ret == 0) {\n\t\tfprintf(stderr, \"%s: debug read failed, ret == 0 (EOF), closing connection\\n\",\n\t\t        __FILE__);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t} else if (ret > (ssize_t) length) {\n\t\tfprintf(stderr, \"%s: debug read failed, ret too large (%ld > %ld), closing connection\\n\",\n\t\t        __FILE__, (long) ret, (long) length);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\treturn (duk_size_t) ret;\n\n fail:\n\tif (client_sock >= 0) {\n\t\t(void) close(client_sock);\n\t\tclient_sock = -1;\n\t}\n\treturn 0;\n}\n\n/* Duktape debug transport callback: (possibly partial) write. */\nduk_size_t duk_trans_socket_write_cb(void *udata, const char *buffer, duk_size_t length) {\n\tssize_t ret;\n\n\t(void) udata;  /* not needed by the example */\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: udata=%p, buffer=%p, length=%ld\\n\",\n\t        __func__, (void *) udata, (const void *) buffer, (long) length);\n\tfflush(stderr);\n#endif\n\n\tif (client_sock < 0) {\n\t\treturn 0;\n\t}\n\n\tif (length == 0) {\n\t\t/* This shouldn't happen. */\n\t\tfprintf(stderr, \"%s: write request length == 0, closing connection\\n\",\n\t\t        __FILE__);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\tif (buffer == NULL) {\n\t\t/* This shouldn't happen. */\n\t\tfprintf(stderr, \"%s: write request buffer == NULL, closing connection\\n\",\n\t\t        __FILE__);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\t/* In a production quality implementation there would be a sanity\n\t * timeout here to recover from \"black hole\" disconnects.\n\t */\n\n\t//TODO: Hacked the example implementation for now to avoid SIGPIPE errors terminating the\n\t//      program when debug client terminates the tcp connection.\n\t//      We should probably move this to a react-juce specific debug transport implementation at some point.\n\t//      For more advanced users, it may be useful to allow a mechanism to easily override the\n\t//      transport mechanism used for debugging. i.e. to allow debug over serial etc.\n\tsignal(SIGPIPE, SIG_IGN);\n\tret = write(client_sock, (const void *) buffer, (size_t) length);\n    signal(SIGPIPE, SIG_DFL);\n\n\tif (ret <= 0 || ret > (ssize_t) length) {\n\t\tfprintf(stderr, \"%s: debug write failed, closing connection: %s\\n\",\n\t\t        __FILE__, strerror(errno));\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\treturn (duk_size_t) ret;\n\n fail:\n\tif (client_sock >= 0) {\n\t\t(void) close(client_sock);\n\t\tclient_sock = -1;\n\t}\n\treturn 0;\n}\n\nduk_size_t duk_trans_socket_peek_cb(void *udata) {\n#if defined(USE_SELECT)\n\tstruct timeval tm;\n\tfd_set rfds;\n\tint select_rc;\n#else\n\tstruct pollfd fds[1];\n\tint poll_rc;\n#endif\n\n\t(void) udata;  /* not needed by the example */\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: udata=%p\\n\", __func__, (void *) udata);\n\tfflush(stderr);\n#endif\n\n\tif (client_sock < 0) {\n\t\treturn 0;\n\t}\n#if defined(USE_SELECT)\n\tFD_ZERO(&rfds);\n\tFD_SET(client_sock, &rfds);\n\ttm.tv_sec = tm.tv_usec = 0;\n\tselect_rc = select(client_sock + 1, &rfds, NULL, NULL, &tm);\n\tif (select_rc == 0) {\n\t\treturn 0;\n\t} else if (select_rc == 1) {\n\t\treturn 1;\n\t}\n\tgoto fail;\n#else  /* USE_SELECT */\n\tfds[0].fd = client_sock;\n\tfds[0].events = POLLIN;\n\tfds[0].revents = 0;\n\n\tpoll_rc = poll(fds, 1, 0);\n\tif (poll_rc < 0) {\n\t\tfprintf(stderr, \"%s: poll returned < 0, closing connection: %s\\n\",\n\t\t        __FILE__, strerror(errno));\n\t\tfflush(stderr);\n\t\tgoto fail;  /* also returns 0, which is correct */\n\t} else if (poll_rc > 1) {\n\t\tfprintf(stderr, \"%s: poll returned > 1, treating like 1\\n\",\n\t\t        __FILE__);\n\t\tfflush(stderr);\n\t\treturn 1;  /* should never happen */\n\t} else if (poll_rc == 0) {\n\t\treturn 0;  /* nothing to read */\n\t} else {\n\t\treturn 1;  /* something to read */\n\t}\n#endif  /* USE_SELECT */\n fail:\n\tif (client_sock >= 0) {\n\t\t(void) close(client_sock);\n\t\tclient_sock = -1;\n\t}\n\treturn 0;\n}\n\nvoid duk_trans_socket_read_flush_cb(void *udata) {\n\t(void) udata;  /* not needed by the example */\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: udata=%p\\n\", __func__, (void *) udata);\n\tfflush(stderr);\n#endif\n\n\t/* Read flush: Duktape may not be making any more read calls at this\n\t * time.  If the transport maintains a receive window, it can use a\n\t * read flush as a signal to update the window status to the remote\n\t * peer.  A read flush is guaranteed to occur before Duktape stops\n\t * reading for a while; it may occur in other situations as well so\n\t * it's not a 100% reliable indication.\n\t */\n\n\t/* This TCP transport requires no read flush handling so ignore.\n\t * You can also pass a NULL to duk_debugger_attach() and not\n\t * implement this callback at all.\n\t */\n}\n\nvoid duk_trans_socket_write_flush_cb(void *udata) {\n\t(void) udata;  /* not needed by the example */\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: udata=%p\\n\", __func__, (void *) udata);\n\tfflush(stderr);\n#endif\n\n\t/* Write flush.  If the transport combines multiple writes\n\t * before actually sending, a write flush is an indication\n\t * to write out any pending bytes: Duktape may not be doing\n\t * any more writes on this occasion.\n\t */\n\n\t/* This TCP transport requires no write flush handling so ignore.\n\t * You can also pass a NULL to duk_debugger_attach() and not\n\t * implement this callback at all.\n\t */\n\treturn;\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/debug-trans-socket/duk_trans_socket_windows.c",
    "content": "/*\n *  Example debug transport using a Windows TCP socket\n *\n *  Provides a TCP server socket which a debug client can connect to.\n *  After that data is just passed through.\n *\n *  https://msdn.microsoft.com/en-us/library/windows/desktop/ms737593(v=vs.85).aspx\n *\n *  Compiling 'duk' with debugger support using MSVC (Visual Studio):\n *\n *    > python2 tools\\configure.py \\\n *          --output-directory prep\n *          -DDUK_USE_DEBUGGER_SUPPORT -DDUK_USE_INTERRUPT_COUNTER\n *    > cl /W3 /O2 /Feduk.exe \\\n *          /DDUK_CMDLINE_DEBUGGER_SUPPORT\n *          /Iexamples\\debug-trans-socket /Iprep\n *          examples\\cmdline\\duk_cmdline.c\n *          examples\\debug-trans-socket\\duk_trans_socket_windows.c\n *          prep\\duktape.c\n *\n *  With MinGW:\n *\n *    $ python2 tools\\configure.py \\\n *          --output-directory prep\n *          -DDUK_USE_DEBUGGER_SUPPORT -DDUK_USE_INTERRUPT_COUNTER\n *    $ gcc -oduk.exe -Wall -O2 \\\n *          -DDUK_CMDLINE_DEBUGGER_SUPPORT \\\n *          -Iexamples/debug-trans-socket -Iprep \\\n *          examples/cmdline/duk_cmdline.c \\\n *          examples/debug-trans-socket/duk_trans_socket_windows.c \\\n *          prep/duktape.c -lm -lws2_32\n */\n\n#undef UNICODE\n#if !defined(WIN32_LEAN_AND_MEAN)\n#define WIN32_LEAN_AND_MEAN\n#endif\n\n/* MinGW workaround for missing getaddrinfo() etc:\n * http://programmingrants.blogspot.fi/2009/09/tips-on-undefined-reference-to.html\n */\n#if defined(__MINGW32__) || defined(__MINGW64__)\n#if !defined(_WIN32_WINNT)\n#define _WIN32_WINNT 0x0501\n#endif\n#endif\n\n#include <windows.h>\n#include <winsock2.h>\n#include <ws2tcpip.h>\n#include <stdio.h>\n#include <string.h>\n#include \"duktape.h\"\n#include \"duk_trans_socket.h\"\n\n#if defined(_MSC_VER)\n#pragma comment (lib, \"Ws2_32.lib\")\n#endif\n\n#if !defined(DUK_DEBUG_PORT)\n#define DUK_DEBUG_PORT 9091\n#endif\n#if !defined(DUK_DEBUG_ADDRESS)\n#define DUK_DEBUG_ADDRESS \"0.0.0.0\"\n#endif\n#define DUK__STRINGIFY_HELPER(x) #x\n#define DUK__STRINGIFY(x) DUK__STRINGIFY_HELPER(x)\n\n#if 0\n#define DEBUG_PRINTS\n#endif\n\nstatic SOCKET server_sock = INVALID_SOCKET;\nstatic SOCKET client_sock = INVALID_SOCKET;\nstatic int wsa_inited = 0;\n\n/*\n *  Transport init and finish\n */\n\nvoid duk_trans_socket_init(void) {\n\tWSADATA wsa_data;\n\tstruct addrinfo hints;\n\tstruct addrinfo *result = NULL;\n\tint rc;\n\n\tmemset((void *) &wsa_data, 0, sizeof(wsa_data));\n\tmemset((void *) &hints, 0, sizeof(hints));\n\n\trc = WSAStartup(MAKEWORD(2, 2), &wsa_data);\n\tif (rc != 0) {\n\t\tfprintf(stderr, \"%s: WSAStartup() failed: %d\\n\", __FILE__, rc);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\twsa_inited = 1;\n\n\thints.ai_family = AF_UNSPEC;\n\thints.ai_socktype = SOCK_STREAM;\n\thints.ai_protocol = IPPROTO_TCP;\n\thints.ai_flags = AI_PASSIVE;\n\n\trc = getaddrinfo(DUK_DEBUG_ADDRESS, DUK__STRINGIFY(DUK_DEBUG_PORT), &hints, &result);\n\tif (rc != 0) {\n\t\tfprintf(stderr, \"%s: getaddrinfo() failed: %d\\n\", __FILE__, rc);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\tserver_sock = socket(result->ai_family, result->ai_socktype, result->ai_protocol);\n\tif (server_sock == INVALID_SOCKET) {\n\t\tfprintf(stderr, \"%s: socket() failed with error: %ld\\n\",\n\t\t        __FILE__, (long) WSAGetLastError());\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\trc = bind(server_sock, result->ai_addr, (int) result->ai_addrlen);\n\tif (rc == SOCKET_ERROR) {\n\t\tfprintf(stderr, \"%s: bind() failed with error: %ld\\n\",\n\t\t        __FILE__, (long) WSAGetLastError());\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\trc = listen(server_sock, SOMAXCONN);\n\tif (rc == SOCKET_ERROR) {\n\t\tfprintf(stderr, \"%s: listen() failed with error: %ld\\n\",\n\t\t        __FILE__, (long) WSAGetLastError());\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\tif (result != NULL) {\n\t\tfreeaddrinfo(result);\n\t\tresult = NULL;\n\t}\n\treturn;\n\n fail:\n\tif (result != NULL) {\n\t\tfreeaddrinfo(result);\n\t\tresult = NULL;\n\t}\n\tif (server_sock != INVALID_SOCKET) {\n\t\t(void) closesocket(server_sock);\n\t\tserver_sock = INVALID_SOCKET;\n\t}\n\tif (wsa_inited) {\n\t\tWSACleanup();\n\t\twsa_inited = 0;\n\t}\n}\n\nvoid duk_trans_socket_finish(void) {\n\tif (client_sock != INVALID_SOCKET) {\n\t\t(void) closesocket(client_sock);\n\t\tclient_sock = INVALID_SOCKET;\n\t}\n\tif (server_sock != INVALID_SOCKET) {\n\t\t(void) closesocket(server_sock);\n\t\tserver_sock = INVALID_SOCKET;\n\t}\n\tif (wsa_inited) {\n\t\tWSACleanup();\n\t\twsa_inited = 0;\n\t}\n}\n\nvoid duk_trans_socket_waitconn(void) {\n\tif (server_sock == INVALID_SOCKET) {\n\t\tfprintf(stderr, \"%s: no server socket, skip waiting for connection\\n\",\n\t\t        __FILE__);\n\t\tfflush(stderr);\n\t\treturn;\n\t}\n\tif (client_sock != INVALID_SOCKET) {\n\t\t(void) closesocket(client_sock);\n\t\tclient_sock = INVALID_SOCKET;\n\t}\n\n\tfprintf(stderr, \"Waiting for debug connection on port %d\\n\", (int) DUK_DEBUG_PORT);\n\tfflush(stderr);\n\n\tclient_sock = accept(server_sock, NULL, NULL);\n\tif (client_sock == INVALID_SOCKET) {\n\t\tfprintf(stderr, \"%s: accept() failed with error %ld, skip waiting for connection\\n\",\n\t\t        __FILE__, (long) WSAGetLastError());\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\tfprintf(stderr, \"Debug connection established\\n\");\n\tfflush(stderr);\n\n\t/* XXX: For now, close the listen socket because we won't accept new\n\t * connections anyway.  A better implementation would allow multiple\n\t * debug attaches.\n\t */\n\n\tif (server_sock != INVALID_SOCKET) {\n\t\t(void) closesocket(server_sock);\n\t\tserver_sock = INVALID_SOCKET;\n\t}\n\treturn;\n\n fail:\n\tif (client_sock != INVALID_SOCKET) {\n\t\t(void) closesocket(client_sock);\n\t\tclient_sock = INVALID_SOCKET;\n\t}\n}\n\n/*\n *  Duktape callbacks\n */\n\n/* Duktape debug transport callback: (possibly partial) read. */\nduk_size_t duk_trans_socket_read_cb(void *udata, char *buffer, duk_size_t length) {\n\tint ret;\n\n\t(void) udata;  /* not needed by the example */\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: udata=%p, buffer=%p, length=%ld\\n\",\n\t        __FUNCTION__, (void *) udata, (void *) buffer, (long) length);\n\tfflush(stderr);\n#endif\n\n\tif (client_sock == INVALID_SOCKET) {\n\t\treturn 0;\n\t}\n\n\tif (length == 0) {\n\t\t/* This shouldn't happen. */\n\t\tfprintf(stderr, \"%s: read request length == 0, closing connection\\n\",\n\t\t        __FILE__);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\tif (buffer == NULL) {\n\t\t/* This shouldn't happen. */\n\t\tfprintf(stderr, \"%s: read request buffer == NULL, closing connection\\n\",\n\t\t        __FILE__);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\t/* In a production quality implementation there would be a sanity\n\t * timeout here to recover from \"black hole\" disconnects.\n\t */\n\n\tret = recv(client_sock, buffer, (int) length, 0);\n\tif (ret < 0) {\n\t\tfprintf(stderr, \"%s: debug read failed, error %d, closing connection\\n\",\n\t\t        __FILE__, ret);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t} else if (ret == 0) {\n\t\tfprintf(stderr, \"%s: debug read failed, ret == 0 (EOF), closing connection\\n\",\n\t\t        __FILE__);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t} else if (ret > (int) length) {\n\t\tfprintf(stderr, \"%s: debug read failed, ret too large (%ld > %ld), closing connection\\n\",\n\t\t        __FILE__, (long) ret, (long) length);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\treturn (duk_size_t) ret;\n\n fail:\n\tif (client_sock != INVALID_SOCKET) {\n\t\t(void) closesocket(client_sock);\n\t\tclient_sock = INVALID_SOCKET;\n\t}\n\treturn 0;\n}\n\n/* Duktape debug transport callback: (possibly partial) write. */\nduk_size_t duk_trans_socket_write_cb(void *udata, const char *buffer, duk_size_t length) {\n\tint ret;\n\n\t(void) udata;  /* not needed by the example */\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: udata=%p, buffer=%p, length=%ld\\n\",\n\t        __FUNCTION__, (void *) udata, (const void *) buffer, (long) length);\n\tfflush(stderr);\n#endif\n\n\tif (client_sock == INVALID_SOCKET) {\n\t\treturn 0;\n\t}\n\n\tif (length == 0) {\n\t\t/* This shouldn't happen. */\n\t\tfprintf(stderr, \"%s: write request length == 0, closing connection\\n\",\n\t\t        __FILE__);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\tif (buffer == NULL) {\n\t\t/* This shouldn't happen. */\n\t\tfprintf(stderr, \"%s: write request buffer == NULL, closing connection\\n\",\n\t\t        __FILE__);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\t/* In a production quality implementation there would be a sanity\n\t * timeout here to recover from \"black hole\" disconnects.\n\t */\n\n\tret = send(client_sock, buffer, (int) length, 0);\n\tif (ret <= 0 || ret > (int) length) {\n\t\tfprintf(stderr, \"%s: debug write failed, ret %d, closing connection\\n\",\n\t\t        __FILE__, ret);\n\t\tfflush(stderr);\n\t\tgoto fail;\n\t}\n\n\treturn (duk_size_t) ret;\n\n fail:\n\tif (client_sock != INVALID_SOCKET) {\n\t\t(void) closesocket(INVALID_SOCKET);\n\t\tclient_sock = INVALID_SOCKET;\n\t}\n\treturn 0;\n}\n\nduk_size_t duk_trans_socket_peek_cb(void *udata) {\n\tu_long avail;\n\tint rc;\n\n\t(void) udata;  /* not needed by the example */\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: udata=%p\\n\", __FUNCTION__, (void *) udata);\n\tfflush(stderr);\n#endif\n\n\tif (client_sock == INVALID_SOCKET) {\n\t\treturn 0;\n\t}\n\n\tavail = 0;\n\trc = ioctlsocket(client_sock, FIONREAD, &avail);\n\tif (rc != 0) {\n\t\tfprintf(stderr, \"%s: ioctlsocket() returned %d, closing connection\\n\",\n\t\t        __FILE__, rc);\n\t\tfflush(stderr);\n\t\tgoto fail;  /* also returns 0, which is correct */\n\t} else {\n\t\tif (avail == 0) {\n\t\t\treturn 0;  /* nothing to read */\n\t\t} else {\n\t\t\treturn 1;  /* something to read */\n\t\t}\n\t}\n\t/* never here */\n\n fail:\n\tif (client_sock != INVALID_SOCKET) {\n\t\t(void) closesocket(client_sock);\n\t\tclient_sock = INVALID_SOCKET;\n\t}\n\treturn 0;\n}\n\nvoid duk_trans_socket_read_flush_cb(void *udata) {\n\t(void) udata;  /* not needed by the example */\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: udata=%p\\n\", __FUNCTION__, (void *) udata);\n\tfflush(stderr);\n#endif\n\n\t/* Read flush: Duktape may not be making any more read calls at this\n\t * time.  If the transport maintains a receive window, it can use a\n\t * read flush as a signal to update the window status to the remote\n\t * peer.  A read flush is guaranteed to occur before Duktape stops\n\t * reading for a while; it may occur in other situations as well so\n\t * it's not a 100% reliable indication.\n\t */\n\n\t/* This TCP transport requires no read flush handling so ignore.\n\t * You can also pass a NULL to duk_debugger_attach() and not\n\t * implement this callback at all.\n\t */\n}\n\nvoid duk_trans_socket_write_flush_cb(void *udata) {\n\t(void) udata;  /* not needed by the example */\n\n#if defined(DEBUG_PRINTS)\n\tfprintf(stderr, \"%s: udata=%p\\n\", __FUNCTION__, (void *) udata);\n\tfflush(stderr);\n#endif\n\n\t/* Write flush.  If the transport combines multiple writes\n\t * before actually sending, a write flush is an indication\n\t * to write out any pending bytes: Duktape may not be doing\n\t * any more writes on this occasion.\n\t */\n\n\t/* This TCP transport requires no write flush handling so ignore.\n\t * You can also pass a NULL to duk_debugger_attach() and not\n\t * implement this callback at all.\n\t */\n\treturn;\n}\n\n#undef DUK__STRINGIFY_HELPER\n#undef DUK__STRINGIFY\n"
  },
  {
    "path": "react_juce/duktape/examples/dummy-date-provider/README.rst",
    "content": "====================================\nDummy external Date provider example\n====================================\n\nThis example implements a dummy, minimal external Date provider.\n"
  },
  {
    "path": "react_juce/duktape/examples/dummy-date-provider/dummy_date_provider.c",
    "content": "/*\n *  Dummy Date provider\n *\n *  There are two minimally required macros which you must provide in\n *  duk_config.h:\n *\n *    extern duk_double_t dummy_get_now(void);\n *\n *    #define DUK_USE_DATE_GET_NOW(ctx) dummy_get_now()\n *    #define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d)  0\n *\n *  Note that since the providers are macros, you don't need to use\n *  all arguments.  Similarly, you can \"return\" fixed values as\n *  constants.  Above, local timezone offset is always zero i.e.\n *  we're always in UTC.\n *\n *  You can also provide optional macros to parse and format timestamps\n *  in a platform specific format.  If not provided, Duktape will use\n *  ISO 8601 only (which is often good enough).\n */\n\n#include \"duktape.h\"\n\nduk_double_t dummy_get_now(void) {\n\t/* Return a fixed time here as a dummy example. */\n\treturn -11504520000.0;\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/eval/README.rst",
    "content": "============\nEval example\n============\n\nEvaluate expressions from command line.\n"
  },
  {
    "path": "react_juce/duktape/examples/eval/eval.c",
    "content": "/*\n *  Very simple example program for evaluating expressions from\n *  command line\n */\n\n#include \"duktape.h\"\n#include <stdio.h>\n\nstatic duk_ret_t native_print(duk_context *ctx) {\n\tduk_push_string(ctx, \" \");\n\tduk_insert(ctx, 0);\n\tduk_join(ctx, duk_get_top(ctx) - 1);\n\tprintf(\"%s\\n\", duk_to_string(ctx, -1));\n\treturn 0;\n}\n\nstatic void usage_exit(void) {\n\tfprintf(stderr, \"Usage: eval <expression> [<expression>] ...\\n\");\n\tfflush(stderr);\n\texit(1);\n}\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx;\n\tint i;\n\tconst char *res;\n\tduk_int_t rc;\n\n\tif (argc < 2) {\n\t\tusage_exit();\n\t}\n\n\tctx = duk_create_heap_default();\n\n\tduk_push_c_function(ctx, native_print, DUK_VARARGS);\n\tduk_put_global_string(ctx, \"print\");\n\n\tfor (i = 1; i < argc; i++) {\n\t\tprintf(\"=== eval: '%s' ===\\n\", argv[i]);\n\t\tduk_push_string(ctx, argv[i]);\n\t\trc = duk_peval(ctx);\n\t\tif (rc != 0) {\n\t\t\tduk_safe_to_stacktrace(ctx, -1);\n\t\t} else {\n\t\t\tduk_safe_to_string(ctx, -1);\n\t\t}\n\t\tres = duk_get_string(ctx, -1);\n\t\tprintf(\"%s\\n\", res ? res : \"null\");\n\t\tduk_pop(ctx);\n\t}\n\n\tduk_destroy_heap(ctx);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/eventloop/README.rst",
    "content": "==================\nEventloop examples\n==================\n\nOverview and usage\n==================\n\nA few examples on how an event loop can be implemented with Duktape, mainly\nilllustrating how the Duktape interface works (not how event loops should be\nbuilt otherwise).\n\nTo test (Linux only, perhaps other Unix)::\n\n  $ ./evloop timer-test.js     # run with ECMAScript eventloop\n  $ ./evloop -c timer-test.js  # run with C eventloop\n\nImplementation approaches\n=========================\n\nThere are several approaches to implementation timers.  Here we demonstrate\ntwo main approaches:\n\n1. Using a C eventloop which calls into ECMAScript.  All the event loop state\n   like timers, sockets, etc, is held in C structures.\n   (See ``c_eventloop.c`` and ``c_eventloop.js``.)\n\n2. Using an ECMAScript eventloop which never returns.  All the event loop state\n   can be managed with ECMAScript code instead of C structures.  The ECMAScript\n   eventloop calls a Duktape/C helper to do the lowest level poll() call.\n   (See ``ecma_eventloop.js``.)\n\nServices provided\n=================\n\nThe event loop API provided by both examples is the same, and includes:\n\n* Timers: setTimeout, clearTimeout, setInterval, clearInterval\n\n* Sockets: simple network sockets\n\nIn addition there are a few synchronous API bindings which are not event loop\nrelated:\n\n* File I/O\n\nLimitations\n===========\n\nThis is **not** a production quality event loop.  This is on purpose, to\nkeep the example somewhat simple.  Some shortcomings include:\n\n* A production quality event loop would track its internal state (active\n  timers and sockets) much more efficiently.  In general memory usage and\n  code footprint can be reduced.\n\n* Buffer churn caused by allocating a new buffer for every socket read\n  should be eliminated by reusing buffers where appropriate.  Although\n  churn doesn't increase memory footprint with reference counting, it\n  is slower than reusing buffers and might increase memory fragmentation.\n\n* There is no way to suspend reading or writing in the example.  Adding\n  them is straightforward: the poll set needs to be managed dynamically.\n\n* The example uses poll() while one should use epoll() on Linux, kqueue()\n  on BSD systems, etc.\n\n* Timers are not very accurate, e.g. setInterval() does not try to guarantee\n  a steady schedule.  Instead, the next interval is scheduled after the\n  current callback has finished.  This is not the best behavior for some\n  environments, but avoids bunching callbacks.\n\n* Error handling is mostly missing.\n"
  },
  {
    "path": "react_juce/duktape/examples/eventloop/basic-test.js",
    "content": "/*\n *  A few basic tests\n */\n\nvar count = 0;\nvar intervalId;\n\nsetTimeout(function (x) { print('timer 1', x); }, 1234, 'foo');\nsetTimeout('print(\"timer 2\");', 4321);\nsetTimeout(function () { print('timer 3'); }, 2345);\nintervalId = setInterval(function (x, y) {\n    print('interval', ++count, x, y);\n    if (count >= 10) {\n        clearInterval(intervalId);\n    }\n}, 400, 'foo', 'bar');\n"
  },
  {
    "path": "react_juce/duktape/examples/eventloop/c_eventloop.c",
    "content": "/*\n *  C eventloop example.\n *\n *  Timer management is similar to eventloop.js but implemented in C.\n *  In particular, timer insertion is an O(n) operation; in a real world\n *  eventloop based on a heap insertion would be O(log N).\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n#include <sys/time.h>\n#include <poll.h>\n\n#include \"duktape.h\"\n#include \"c_eventloop.h\"\n\n#if !defined(DUKTAPE_EVENTLOOP_DEBUG)\n#define DUKTAPE_EVENTLOOP_DEBUG 0       /* set to 1 to debug with printf */\n#endif\n\n#define  TIMERS_SLOT_NAME       \"eventTimers\"\n#define  MIN_DELAY              1.0\n#define  MIN_WAIT               1.0\n#define  MAX_WAIT               60000.0\n#define  MAX_EXPIRIES           10\n\n#define  MAX_FDS                256\n#define  MAX_TIMERS             4096     /* this is quite excessive for embedded use, but good for testing */\n\ntypedef struct {\n\tint64_t id;       /* numeric ID (returned from e.g. setTimeout); zero if unused */\n\tdouble target;    /* next target time */\n\tdouble delay;     /* delay/interval */\n\tint oneshot;      /* oneshot=1 (setTimeout), repeated=0 (setInterval) */\n\tint removed;      /* timer has been requested for removal */\n\n\t/* The callback associated with the timer is held in the \"global stash\",\n\t * in <stash>.eventTimers[String(id)].  The references must be deleted\n\t * when a timer struct is deleted.\n\t */\n} ev_timer;\n\n/* Active timers.  Dense list, terminates to end of list or first unused timer.\n * The list is sorted by 'target', with lowest 'target' (earliest expiry) last\n * in the list.  When a timer's callback is being called, the timer is moved\n * to 'timer_expiring' as it needs special handling should the user callback\n * delete that particular timer.\n */\nstatic ev_timer timer_list[MAX_TIMERS];\nstatic ev_timer timer_expiring;\nstatic int timer_count;  /* last timer at timer_count - 1 */\nstatic int64_t timer_next_id = 1;\n\n/* Socket poll state. */\nstatic struct pollfd poll_list[MAX_FDS];\nstatic int poll_count = 0;\n\n/* Misc */\nstatic int exit_requested = 0;\n\n/* Get Javascript compatible 'now' timestamp (millisecs since 1970). */\nstatic double get_now(void) {\n\tstruct timeval tv;\n\tint rc;\n\n\trc = gettimeofday(&tv, NULL);\n\tif (rc != 0) {\n\t\t/* Should never happen, so return whatever. */\n\t\treturn 0.0;\n\t}\n\treturn ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0;\n}\n\nstatic ev_timer *find_nearest_timer(void) {\n\t/* Last timer expires first (list is always kept sorted). */\n\tif (timer_count <= 0) {\n\t\treturn NULL;\n\t}\n\treturn timer_list + timer_count - 1;\n}\n\n/* Bubble last timer on timer list backwards until it has been moved to\n * its proper sorted position (based on 'target' time).\n */\nstatic void bubble_last_timer(void) {\n\tint i;\n\tint n = timer_count;\n\tev_timer *t;\n\tev_timer tmp;\n\n\tfor (i = n - 1; i > 0; i--) {\n\t\t/* Timer to bubble is at index i, timer to compare to is\n\t\t * at i-1 (both guaranteed to exist).\n\t\t */\n\t\tt = timer_list + i;\n\t\tif (t->target <= (t-1)->target) {\n\t\t\t/* 't' expires earlier than (or same time as) 't-1', so we're done. */\n\t\t\tbreak;\n\t\t} else {\n\t\t\t/* 't' expires later than 't-1', so swap them and repeat. */\n\t\t\tmemcpy((void *) &tmp, (void *) (t - 1), sizeof(ev_timer));\n\t\t\tmemcpy((void *) (t - 1), (void *) t, sizeof(ev_timer));\n\t\t\tmemcpy((void *) t, (void *) &tmp, sizeof(ev_timer));\n\t\t}\n\t}\n}\n\nstatic void expire_timers(duk_context *ctx) {\n\tev_timer *t;\n\tint sanity = MAX_EXPIRIES;\n\tdouble now;\n\tint rc;\n\n\t/* Because a user callback can mutate the timer list (by adding or deleting\n\t * a timer), we expire one timer and then rescan from the end again.  There\n\t * is a sanity limit on how many times we do this per expiry round.\n\t */\n\n\tduk_push_global_stash(ctx);\n\tduk_get_prop_string(ctx, -1, TIMERS_SLOT_NAME);\n\n\t/* [ ... stash eventTimers ] */\n\n\tnow = get_now();\n\twhile (sanity-- > 0) {\n\t\t/*\n\t\t *  If exit has been requested, exit without running further\n\t\t *  callbacks.\n\t\t */\n\n\t\tif (exit_requested) {\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\t\tfprintf(stderr, \"exit requested, exiting timer expiry loop\\n\");\n\t\t\tfflush(stderr);\n#endif\n\t\t\tbreak;\n\t\t}\n\n\t\t/*\n\t\t *  Expired timer(s) still exist?\n\t\t */\n\n\t\tif (timer_count <= 0) {\n\t\t\tbreak;\n\t\t}\n\t\tt = timer_list + timer_count - 1;\n\t\tif (t->target > now) {\n\t\t\tbreak;\n\t\t}\n\n\t\t/*\n\t\t *  Move the timer to 'expiring' for the duration of the callback.\n\t\t *  Mark a one-shot timer deleted, compute a new target for an interval.\n\t\t */\n\n\t\tmemcpy((void *) &timer_expiring, (void *) t, sizeof(ev_timer));\n\t\tmemset((void *) t, 0, sizeof(ev_timer));\n\t\ttimer_count--;\n\t\tt = &timer_expiring;\n\n\t\tif (t->oneshot) {\n\t\t\tt->removed = 1;\n\t\t} else {\n\t\t\tt->target = now + t->delay;  /* XXX: or t->target + t->delay? */\n\t\t}\n\n\t\t/*\n\t\t *  Call timer callback.  The callback can operate on the timer list:\n\t\t *  add new timers, remove timers.  The callback can even remove the\n\t\t *  expired timer whose callback we're calling.  However, because the\n\t\t *  timer being expired has been moved to 'timer_expiring', we don't\n\t\t *  need to worry about the timer's offset changing on the timer list.\n\t\t */\n\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\tfprintf(stderr, \"calling user callback for timer id %d\\n\", (int) t->id);\n\t\tfflush(stderr);\n#endif\n\n\t\tduk_push_number(ctx, (double) t->id);\n\t\tduk_get_prop(ctx, -2);  /* -> [ ... stash eventTimers func ] */\n\t\trc = duk_pcall(ctx, 0 /*nargs*/);  /* -> [ ... stash eventTimers retval ] */\n\t\tif (rc != 0) {\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\t\tfprintf(stderr, \"timer callback failed for timer %d: %s\\n\", (int) t->id, duk_to_string(ctx, -1));\n\t\t\tfflush(stderr);\n#endif\n\t\t}\n\t\tduk_pop(ctx);    /* ignore errors for now -> [ ... stash eventTimers ] */\n\n\t\tif (t->removed) {\n\t\t\t/* One-shot timer (always removed) or removed by user callback. */\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\t\tfprintf(stderr, \"deleting callback state for timer %d\\n\", (int) t->id);\n\t\t\tfflush(stderr);\n#endif\n\t\t\tduk_push_number(ctx, (double) t->id);\n\t\t\tduk_del_prop(ctx, -2);\n\t\t} else {\n\t\t\t/* Interval timer, not removed by user callback.  Queue back to\n\t\t\t * timer list and bubble to its final sorted position.\n\t\t\t */\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\t\tfprintf(stderr, \"queueing timer %d back into active list\\n\", (int) t->id);\n\t\t\tfflush(stderr);\n#endif\n\t\t\tif (timer_count >= MAX_TIMERS) {\n\t\t\t\t(void) duk_error(ctx, DUK_ERR_RANGE_ERROR, \"out of timer slots\");\n\t\t\t}\n\t\t\tmemcpy((void *) (timer_list + timer_count), (void *) t, sizeof(ev_timer));\n\t\t\ttimer_count++;\n\t\t\tbubble_last_timer();\n\t\t}\n\t}\n\n\tmemset((void *) &timer_expiring, 0, sizeof(ev_timer));\n\n\tduk_pop_2(ctx);  /* -> [ ... ] */\n}\n\nstatic void compact_poll_list(void) {\n\tint i, j, n;\n\n\t/* i = input index\n\t * j = output index (initially same as i)\n\t */\n\n\tn = poll_count;\n\tfor (i = 0, j = 0; i < n; i++) {\n\t\tstruct pollfd *pfd = poll_list + i;\n\t\tif (pfd->fd == 0) {\n\t\t\t/* keep output index the same */\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\t\tfprintf(stderr, \"remove pollfd (index %d): fd=%d, events=%d, revents=%d\\n\",\n\t\t\t        i, pfd->fd, pfd->events, pfd->revents),\n\t\t\tfflush(stderr);\n#endif\n\n\t\t\tcontinue;\n\t\t}\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\tfprintf(stderr, \"keep pollfd (index %d -> %d): fd=%d, events=%d, revents=%d\\n\",\n\t\t        i, j, pfd->fd, pfd->events, pfd->revents),\n\t\tfflush(stderr);\n#endif\n\t\tif (i != j) {\n\t\t\t/* copy only if indices have diverged */\n\t\t\tmemcpy((void *) (poll_list + j), (void *) (poll_list + i), sizeof(struct pollfd));\n\t\t}\n\t\tj++;\n\t}\n\n\tif (j < poll_count) {\n\t\t/* zeroize unused entries for sanity */\n\t\tmemset((void *) (poll_list + j), 0, (poll_count - j) * sizeof(struct pollfd));\n\t}\n\n\tpoll_count = j;\n}\n\nduk_ret_t eventloop_run(duk_context *ctx, void *udata) {\n\tev_timer *t;\n\tdouble now;\n\tdouble diff;\n\tint timeout;\n\tint rc;\n\tint i, n;\n\tint idx_eventloop;\n\tint idx_fd_handler;\n\n\t(void) udata;\n\n\t/* The ECMAScript poll handler is passed through EventLoop.fdPollHandler\n\t * which c_eventloop.js sets before we come here.\n\t */\n\tduk_push_global_object(ctx);\n\tduk_get_prop_string(ctx, -1, \"EventLoop\");\n\tduk_get_prop_string(ctx, -1, \"fdPollHandler\");  /* -> [ global EventLoop fdPollHandler ] */\n\tidx_fd_handler = duk_get_top_index(ctx);\n\tidx_eventloop = idx_fd_handler - 1;\n\n\tfor (;;) {\n\t\t/*\n\t\t *  Expire timers.\n\t\t */\n\n\t\texpire_timers(ctx);\n\n\t\t/*\n\t\t *  If exit requested, bail out as fast as possible.\n\t\t */\n\n\t\tif (exit_requested) {\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\t\tfprintf(stderr, \"exit requested, exiting event loop\\n\");\n\t\t\tfflush(stderr);\n#endif\n\t\t\tbreak;\n\t\t}\n\n\t\t/*\n\t\t *  Compact poll list by removing pollfds with fd == 0.\n\t\t */\n\n\t\tcompact_poll_list();\n\n\t\t/*\n\t\t *  Determine poll() timeout (as close to poll() as possible as\n\t\t *  the wait is relative).\n\t\t */\n\n\t\tnow = get_now();\n\t\tt = find_nearest_timer();\n\t\tif (t) {\n\t\t\tdiff = t->target - now;\n\t\t\tif (diff < MIN_WAIT) {\n\t\t\t\tdiff = MIN_WAIT;\n\t\t\t} else if (diff > MAX_WAIT) {\n\t\t\t\tdiff = MAX_WAIT;\n\t\t\t}\n\t\t\ttimeout = (int) diff;  /* clamping ensures that fits */\n\t\t} else {\n\t\t\tif (poll_count == 0) {\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\t\t\tfprintf(stderr, \"no timers and no sockets to poll, exiting\\n\");\n\t\t\t\tfflush(stderr);\n#endif\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\ttimeout = (int) MAX_WAIT;\n\t\t}\n\n\t\t/*\n\t\t *  Poll for activity or timeout.\n\t\t */\n\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\tfprintf(stderr, \"going to poll, timeout %d ms, pollfd count %d\\n\", timeout, poll_count);\n\t\tfflush(stderr);\n#endif\n\n\t\trc = poll(poll_list, poll_count, timeout);\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\tfprintf(stderr, \"poll rc: %d\\n\", rc);\n\t\tfflush(stderr);\n#endif\n\t\tif (rc < 0) {\n\t\t\t/* error */\n\t\t} else if (rc == 0) {\n\t\t\t/* timeout */\n\t\t} else {\n\t\t\t/* 'rc' fds active */\n\t\t}\n\n\t\t/*\n\t\t *  Check socket activity, handle all sockets.  Handling is offloaded to\n\t\t *  ECMAScript code (fd + revents).\n\t\t *\n\t\t *  If FDs are removed from the poll list while we're processing callbacks,\n\t\t *  the entries are simply marked unused (fd set to 0) without actually\n\t\t *  removing them from the poll list.  This ensures indices are not\n\t\t *  disturbed.  The poll list is compacted before next poll().\n\t\t */\n\n\t\tn = (rc == 0 ? 0 : poll_count);  /* if timeout, no need to check pollfd */\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tstruct pollfd *pfd = poll_list + i;\n\n\t\t\tif (pfd->fd == 0) {\n\t\t\t\t/* deleted, perhaps by previous callback */\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (pfd->revents) {\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\t\t\tfprintf(stderr, \"fd %d has revents: %d\\n\", (int) pfd->fd, (int) pfd->revents);\n\t\t\t\tfflush(stderr);\n#endif\n\t\t\t\tduk_dup(ctx, idx_fd_handler);\n\t\t\t\tduk_dup(ctx, idx_eventloop);\n\t\t\t\tduk_push_int(ctx, pfd->fd);\n\t\t\t\tduk_push_int(ctx, pfd->revents);\n\t\t\t\trc = duk_pcall_method(ctx, 2 /*nargs*/);\n\t\t\t\tif (rc) {\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\t\t\t\tfprintf(stderr, \"fd callback failed for fd %d: %s\\n\", (int) pfd->fd, duk_to_string(ctx, -1));\n\t\t\t\t\tfflush(stderr);\n#endif\n\t\t\t\t}\n\t\t\t\tduk_pop(ctx);\n\n\t\t\t\tpfd->revents = 0;\n\t\t\t}\n\n\t\t}\n\t}\n\n\tduk_pop_n(ctx, 3);\n\n\treturn 0;\n}\n\nstatic int create_timer(duk_context *ctx) {\n\tdouble delay;\n\tint oneshot;\n\tint idx;\n\tint64_t timer_id;\n\tdouble now;\n\tev_timer *t;\n\n\tnow = get_now();\n\n\t/* indexes:\n\t *   0 = function (callback)\n\t *   1 = delay\n\t *   2 = boolean: oneshot\n\t */\n\n\tdelay = duk_require_number(ctx, 1);\n\tif (delay < MIN_DELAY) {\n\t\tdelay = MIN_DELAY;\n\t}\n\toneshot = duk_require_boolean(ctx, 2);\n\n\tif (timer_count >= MAX_TIMERS) {\n\t\t(void) duk_error(ctx, DUK_ERR_RANGE_ERROR, \"out of timer slots\");\n\t}\n\tidx = timer_count++;\n\ttimer_id = timer_next_id++;\n\tt = timer_list + idx;\n\n\tmemset((void *) t, 0, sizeof(ev_timer));\n\tt->id = timer_id;\n\tt->target = now + delay;\n\tt->delay = delay;\n\tt->oneshot = oneshot;\n\tt->removed = 0;\n\n\t/* Timer is now at the last position; use swaps to \"bubble\" it to its\n\t * correct sorted position.\n\t */\n\n\tbubble_last_timer();\n\n\t/* Finally, register the callback to the global stash 'eventTimers' object. */\n\n\tduk_push_global_stash(ctx);\n\tduk_get_prop_string(ctx, -1, TIMERS_SLOT_NAME);  /* -> [ func delay oneshot stash eventTimers ] */\n\tduk_push_number(ctx, (double) timer_id);\n\tduk_dup(ctx, 0);\n\tduk_put_prop(ctx, -3);  /* eventTimers[timer_id] = callback */\n\n\t/* Return timer id. */\n\n\tduk_push_number(ctx, (double) timer_id);\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\tfprintf(stderr, \"created timer id: %d\\n\", (int) timer_id);\n\tfflush(stderr);\n#endif\n\treturn 1;\n}\n\nstatic int delete_timer(duk_context *ctx) {\n\tint i, n;\n\tint64_t timer_id;\n\tev_timer *t;\n\tint found = 0;\n\n\t/* indexes:\n\t *   0 = timer id\n\t */\n\n\ttimer_id = (int64_t) duk_require_number(ctx, 0);\n\n\t/*\n\t *  Unlike insertion, deletion needs a full scan of the timer list\n\t *  and an expensive remove.  If no match is found, nothing is deleted.\n\t *  Caller gets a boolean return code indicating match.\n\t *\n\t *  When a timer is being expired and its user callback is running,\n\t *  the timer has been moved to 'timer_expiring' and its deletion\n\t *  needs special handling: just mark it to-be-deleted and let the\n\t *  expiry code remove it.\n\t */\n\n\tt = &timer_expiring;\n\tif (t->id == timer_id) {\n\t\tt->removed = 1;\n\t\tduk_push_true(ctx);\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\tfprintf(stderr, \"deleted expiring timer id: %d\\n\", (int) timer_id);\n\t\tfflush(stderr);\n#endif\n\t\treturn 1;\n\t}\n\n\tn = timer_count;\n\tfor (i = 0; i < n; i++) {\n\t\tt = timer_list + i;\n\t\tif (t->id == timer_id) {\n\t\t\tfound = 1;\n\n\t\t\t/* Shift elements downwards to keep the timer list dense\n\t\t\t * (no need if last element).\n\t\t\t */\n\t\t\tif (i < timer_count - 1) {\n\t\t\t\tmemmove((void *) t, (void *) (t + 1), (timer_count - i - 1) * sizeof(ev_timer));\n\t\t\t}\n\n\t\t\t/* Zero last element for clarity. */\n\t\t\tmemset((void *) (timer_list + n - 1), 0, sizeof(ev_timer));\n\n\t\t\t/* Update timer_count. */\n\t\t\ttimer_count--;\n\n\t\t\t/* The C state is now up-to-date, but we still need to delete\n\t\t\t * the timer callback state from the global 'stash'.\n\t\t\t */\n\n\t\t\tduk_push_global_stash(ctx);\n\t\t\tduk_get_prop_string(ctx, -1, TIMERS_SLOT_NAME);  /* -> [ timer_id stash eventTimers ] */\n\t\t\tduk_push_number(ctx, (double) timer_id);\n\t\t\tduk_del_prop(ctx, -2);  /* delete eventTimers[timer_id] */\n\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\t\tfprintf(stderr, \"deleted timer id: %d\\n\", (int) timer_id);\n\t\t\tfflush(stderr);\n#endif\n\t\t\tbreak;\n\t\t}\n\t}\n\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\tif (!found) {\n\t\tfprintf(stderr, \"trying to delete timer id %d, but not found; ignoring\\n\", (int) timer_id);\n\t\tfflush(stderr);\n\t}\n#endif\n\n\tduk_push_boolean(ctx, found);\n\treturn 1;\n}\n\nstatic int listen_fd(duk_context *ctx) {\n\tint fd = duk_require_int(ctx, 0);\n\tint events = duk_require_int(ctx, 1);\n\tint i, n;\n\tstruct pollfd *pfd;\n\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\tfprintf(stderr, \"listen_fd: fd=%d, events=%d\\n\", fd, events);\n\tfflush(stderr);\n#endif\n\t/* events == 0 means stop listening to the FD */\n\n\tn = poll_count;\n\tfor (i = 0; i < n; i++) {\n\t\tpfd = poll_list + i;\n\t\tif (pfd->fd == fd) {\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\t\t\tfprintf(stderr, \"listen_fd: fd found at index %d\\n\", i);\n\t\t\tfflush(stderr);\n#endif\n\t\t\tif (events == 0) {\n\t\t\t\t/* mark to-be-deleted, cleaned up by next poll */\n\t\t\t\tpfd->fd = 0;\n\t\t\t} else {\n\t\t\t\tpfd->events = events;\n\t\t\t}\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* not found, append to list */\n#if DUKTAPE_EVENTLOOP_DEBUG > 0\n\tfprintf(stderr, \"listen_fd: fd not found on list, add new entry\\n\");\n\tfflush(stderr);\n#endif\n\n\tif (poll_count >= MAX_FDS) {\n\t\t(void) duk_error(ctx, DUK_ERR_ERROR, \"out of fd slots\");\n\t}\n\n\tpfd = poll_list + poll_count;\n\tpfd->fd = fd;\n\tpfd->events = events;\n\tpfd->revents = 0;\n\tpoll_count++;\n\n\treturn 0;\n}\n\nstatic int request_exit(duk_context *ctx) {\n\t(void) ctx;\n\texit_requested = 1;\n\treturn 0;\n}\n\nstatic duk_function_list_entry eventloop_funcs[] = {\n\t{ \"createTimer\", create_timer, 3 },\n\t{ \"deleteTimer\", delete_timer, 1 },\n\t{ \"listenFd\", listen_fd, 2 },\n\t{ \"requestExit\", request_exit, 0 },\n\t{ NULL, NULL, 0 }\n};\n\nvoid eventloop_register(duk_context *ctx) {\n\tmemset((void *) timer_list, 0, MAX_TIMERS * sizeof(ev_timer));\n\tmemset((void *) &timer_expiring, 0, sizeof(ev_timer));\n\tmemset((void *) poll_list, 0, MAX_FDS * sizeof(struct pollfd));\n\n\t/* Set global 'EventLoop'. */\n\tduk_push_global_object(ctx);\n\tduk_push_object(ctx);\n\tduk_put_function_list(ctx, -1, eventloop_funcs);\n\tduk_put_prop_string(ctx, -2, \"EventLoop\");\n\tduk_pop(ctx);\n\n\t/* Initialize global stash 'eventTimers'. */\n\tduk_push_global_stash(ctx);\n\tduk_push_object(ctx);\n\tduk_put_prop_string(ctx, -2, TIMERS_SLOT_NAME);\n\tduk_pop(ctx);\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/eventloop/c_eventloop.h",
    "content": "#if !defined(C_EVENTLOOP_H)\n#define C_EVENTLOOP_H\n\nvoid eventloop_register(duk_context *ctx);\nduk_ret_t eventloop_run(duk_context *ctx, void *udata);\n\n#endif\n"
  },
  {
    "path": "react_juce/duktape/examples/eventloop/c_eventloop.js",
    "content": "/*\n *  C eventloop example (c_eventloop.c).\n *\n *  ECMAScript code to initialize the exposed API (setTimeout() etc) when\n *  using the C eventloop.\n *\n *  https://developer.mozilla.org/en-US/docs/Web/JavaScript/Timers\n */\n\n/*\n *  Timer API\n */\n\nfunction setTimeout(func, delay) {\n    var cb_func;\n    var bind_args;\n    var timer_id;\n\n    // Delay can be optional at least in some contexts, so tolerate that.\n    // https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout\n    if (typeof delay !== 'number') {\n        if (typeof delay === 'undefined') {\n            delay = 0;\n        } else {\n            throw new TypeError('invalid delay');\n        }\n    }\n\n    if (typeof func === 'string') {\n        // Legacy case: callback is a string.\n        cb_func = eval.bind(this, func);\n    } else if (typeof func !== 'function') {\n        throw new TypeError('callback is not a function/string');\n    } else if (arguments.length > 2) {\n        // Special case: callback arguments are provided.\n        bind_args = Array.prototype.slice.call(arguments, 2);  // [ arg1, arg2, ... ]\n        bind_args.unshift(this);  // [ global(this), arg1, arg2, ... ]\n        cb_func = func.bind.apply(func, bind_args);\n    } else {\n        // Normal case: callback given as a function without arguments.\n        cb_func = func;\n    }\n\n    timer_id = EventLoop.createTimer(cb_func, delay, true /*oneshot*/);\n\n    return timer_id;\n}\n\nfunction clearTimeout(timer_id) {\n    if (typeof timer_id !== 'number') {\n        throw new TypeError('timer ID is not a number');\n    }\n    var success = EventLoop.deleteTimer(timer_id);  /* retval ignored */\n}\n\nfunction setInterval(func, delay) {\n    var cb_func;\n    var bind_args;\n    var timer_id;\n\n    if (typeof delay !== 'number') {\n        if (typeof delay === 'undefined') {\n            delay = 0;\n        } else {\n            throw new TypeError('invalid delay');\n        }\n    }\n\n    if (typeof func === 'string') {\n        // Legacy case: callback is a string.\n        cb_func = eval.bind(this, func);\n    } else if (typeof func !== 'function') {\n        throw new TypeError('callback is not a function/string');\n    } else if (arguments.length > 2) {\n        // Special case: callback arguments are provided.\n        bind_args = Array.prototype.slice.call(arguments, 2);  // [ arg1, arg2, ... ]\n        bind_args.unshift(this);  // [ global(this), arg1, arg2, ... ]\n        cb_func = func.bind.apply(func, bind_args);\n    } else {\n        // Normal case: callback given as a function without arguments.\n        cb_func = func;\n    }\n\n    timer_id = EventLoop.createTimer(cb_func, delay, false /*oneshot*/);\n\n    return timer_id;\n}\n\nfunction clearInterval(timer_id) {\n    if (typeof timer_id !== 'number') {\n        throw new TypeError('timer ID is not a number');\n    }\n    EventLoop.deleteTimer(timer_id);\n}\n\nfunction requestEventLoopExit() {\n    EventLoop.requestExit();\n}\n\n/*\n *  Socket handling\n *\n *  Ideally this would be implemented more in C than here for more speed\n *  and smaller footprint: C code would directly maintain the callback state\n *  and such.\n *\n *  Also for more optimal I/O, the buffer churn caused by allocating and\n *  freeing a lot of buffer values could be eliminated by reusing buffers.\n *  Socket reads would then go into a pre-allocated buffer, for instance.\n */\n\nEventLoop.socketListening = {};\nEventLoop.socketReading = {};\nEventLoop.socketConnecting = {};\n\nEventLoop.fdPollHandler = function(fd, revents) {\n    var data;\n    var cb;\n    var rc;\n    var acc_res;\n\n    //print('activity on fd', fd, 'revents', revents);\n\n    if (revents & Poll.POLLIN) {\n        cb = this.socketReading[fd];\n        if (cb) {\n            data = Socket.read(fd);  // no size control now\n            //print('READ', Duktape.enc('jx', data));\n            if (data.length === 0) {\n                this.close(fd);\n                return;\n            }\n            cb(fd, data);\n        } else {\n            cb = this.socketListening[fd];\n            if (cb) {\n                acc_res = Socket.accept(fd);\n                //print('ACCEPT:', Duktape.enc('jx', acc_res));\n                cb(acc_res.fd, acc_res.addr, acc_res.port);\n            } else {\n                //print('UNKNOWN');\n            }\n        }\n    }\n\n    if (revents & Poll.POLLOUT) {\n        // Connected\n        cb = this.socketConnecting[fd];\n        if (cb) {\n            delete this.socketConnecting[fd];\n            cb(fd);\n        }\n    }\n\n    if ((revents & ~(Poll.POLLIN | Poll.POLLOUT)) !== 0) {\n        //print('unexpected revents, close fd');\n        this.close(fd);\n    }\n}\n\nEventLoop.server = function(address, port, cb_accepted) {\n    var fd = Socket.createServerSocket(address, port);\n    this.socketListening[fd] = cb_accepted;\n    this.listenFd(fd, Poll.POLLIN);\n}\n\nEventLoop.connect = function(address, port, cb_connected) {\n    var fd = Socket.connect(address, port);\n    this.socketConnecting[fd] = cb_connected;\n    this.listenFd(fd, Poll.POLLOUT);\n}\n\nEventLoop.close = function(fd) {\n    EventLoop.listenFd(fd, 0);\n    delete this.socketListening[fd];\n    delete this.socketReading[fd];\n    delete this.socketConnecting[fd];\n    Socket.close(fd);\n}\n\nEventLoop.setReader = function(fd, cb_read) {\n    this.socketReading[fd] = cb_read;\n    this.listenFd(fd, Poll.POLLIN);\n}\n\nEventLoop.write = function(fd, data) {\n    // This simple example doesn't have support for write blocking / draining\n    if (typeof data === 'string') {\n        data = new TextEncoder().encode(data);\n    }\n    var rc = Socket.write(fd, data);\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/eventloop/client-socket-test.js",
    "content": "var HOST = 'localhost';\nvar PORT = 80;\n\nEventLoop.connect(HOST, PORT, function (fd) {\n    print('connected to ' + HOST + ':' + PORT + ', fd', fd);\n    EventLoop.setReader(fd, function (fd, data) {\n        print('read from fd', fd);\n        print(new TextDecoder().decode(data));\n        // Read until completion, socket is closed by server.\n    });\n    EventLoop.write(fd, \"GET / HTTP/1.1\\r\\n\" +\n                        \"Host: \" + HOST + \"\\r\\n\" +\n                        \"User-Agent: client-socket-test.js\\r\\n\" +\n                        \"Connection: close\\r\\n\" +\n                        \"\\r\\n\");\n});\n"
  },
  {
    "path": "react_juce/duktape/examples/eventloop/ecma_eventloop.js",
    "content": "/*\n *  Pure ECMAScript eventloop example.\n *\n *  Timer state handling is inefficient in this trivial example.  Timers are\n *  kept in an array sorted by their expiry time which works well for expiring\n *  timers, but has O(n) insertion performance.  A better implementation would\n *  use a heap or some other efficient structure for managing timers so that\n *  all operations (insert, remove, get nearest timer) have good performance.\n *\n *  https://developer.mozilla.org/en-US/docs/Web/JavaScript/Timers\n */\n\n/*\n *  Event loop\n *\n *  Timers are sorted by 'target' property which indicates expiry time of\n *  the timer.  The timer expiring next is last in the array, so that\n *  removals happen at the end, and inserts for timers expiring in the\n *  near future displace as few elements in the array as possible.\n */\n\nEventLoop = {\n    // timers\n    timers: [],         // active timers, sorted (nearest expiry last)\n    expiring: null,     // set to timer being expired (needs special handling in clearTimeout/clearInterval)\n    nextTimerId: 1,\n    minimumDelay: 1,\n    minimumWait: 1,\n    maximumWait: 60000,\n    maxExpirys: 10,\n\n    // sockets\n    socketListening: {},  // fd -> callback\n    socketReading: {},    // fd -> callback\n    socketConnecting: {}, // fd -> callback\n\n    // misc\n    exitRequested: false\n};\n\nEventLoop.dumpState = function() {\n    print('TIMER STATE:');\n    this.timers.forEach(function(t) {\n        print('    ' + Duktape.enc('jx', t));\n    });\n    if (this.expiring) {\n        print('    EXPIRING: ' + Duktape.enc('jx', this.expiring));\n    }\n}\n\n// Get timer with lowest expiry time.  Since the active timers list is\n// sorted, it's always the last timer.\nEventLoop.getEarliestTimer = function() {\n    var timers = this.timers;\n    n = timers.length;\n    return (n > 0 ? timers[n - 1] : null);\n}\n\nEventLoop.getEarliestWait = function() {\n    var t = this.getEarliestTimer();\n    return (t ? t.target - Date.now() : null);\n}\n\nEventLoop.insertTimer = function(timer) {\n    var timers = this.timers;\n    var i, n, t;\n\n    /*\n     *  Find 'i' such that we want to insert *after* timers[i] at index i+1.\n     *  If no such timer, for-loop terminates with i-1, and we insert at -1+1=0.\n     */\n\n    n = timers.length;\n    for (i = n - 1; i >= 0; i--) {\n        t = timers[i];\n        if (timer.target <= t.target) {\n            // insert after 't', to index i+1\n            break;\n        }\n    }\n\n    timers.splice(i + 1 /*start*/, 0 /*deleteCount*/, timer);\n}\n\n// Remove timer/interval with a timer ID.  The timer/interval can reside\n// either on the active list or it may be an expired timer (this.expiring)\n// whose user callback we're running when this function gets called.\nEventLoop.removeTimerById = function(timer_id) {\n    var timers = this.timers;\n    var i, n, t;\n\n    t = this.expiring;\n    if (t) {\n        if (t.id === timer_id) {\n            // Timer has expired and we're processing its callback.  User\n            // callback has requested timer deletion.  Mark removed, so\n            // that the timer is not reinserted back into the active list.\n            // This is actually a common case because an interval may very\n            // well cancel itself.\n            t.removed = true;\n            return;\n        }\n    }\n\n    n = timers.length;\n    for (i = 0; i < n; i++) {\n        t = timers[i];\n        if (t.id === timer_id) {\n            // Timer on active list: mark removed (not really necessary, but\n            // nice for dumping), and remove from active list.\n            t.removed = true;\n            this.timers.splice(i /*start*/, 1 /*deleteCount*/);\n            return;\n        }\n    }\n\n   // no such ID, ignore\n}\n\nEventLoop.processTimers = function() {\n    var now = Date.now();\n    var timers = this.timers;\n    var sanity = this.maxExpirys;\n    var n, t;\n\n    /*\n     *  Here we must be careful with mutations: user callback may add and\n     *  delete an arbitrary number of timers.\n     *\n     *  Current solution is simple: check whether the timer at the end of\n     *  the list has expired.  If not, we're done.  If it has expired,\n     *  remove it from the active list, record it in this.expiring, and call\n     *  the user callback.  If user code deletes the this.expiring timer,\n     *  there is special handling which just marks the timer deleted so\n     *  it won't get inserted back into the active list.\n     *\n     *  This process is repeated at most maxExpirys times to ensure we don't\n     *  get stuck forever; user code could in principle add more and more\n     *  already expired timers.\n     */\n\n    while (sanity-- > 0) {\n        // If exit requested, don't call any more callbacks.  This allows\n        // a callback to do cleanups and request exit, and can be sure that\n        // no more callbacks are processed.\n\n        if (this.exitRequested) {\n            //print('exit requested, exit');\n            break;\n        }\n\n        // Timers to expire?\n\n        n = timers.length;\n        if (n <= 0) {\n            break;\n        }\n        t = timers[n - 1];\n        if (now <= t.target) {\n            // Timer has not expired, and no other timer could have expired\n            // either because the list is sorted.\n            break;\n        }\n        timers.pop();\n\n        // Remove the timer from the active list and process it.  The user\n        // callback may add new timers which is not a problem.  The callback\n        // may also delete timers which is not a problem unless the timer\n        // being deleted is the timer whose callback we're running; this is\n        // why the timer is recorded in this.expiring so that clearTimeout()\n        // and clearInterval() can detect this situation.\n\n        if (t.oneshot) {\n            t.removed = true;  // flag for removal\n        } else {\n            t.target = now + t.delay;\n        }\n        this.expiring = t;\n        try {\n            t.cb();\n        } catch (e) {\n            print('timer callback failed, ignored: ' + e);\n        }\n        this.expiring = null;\n\n        // If the timer was one-shot, it's marked 'removed'.  If the user callback\n        // requested deletion for the timer, it's also marked 'removed'.  If the\n        // timer is an interval (and is not marked removed), insert it back into\n        // the timer list.\n\n        if (!t.removed) {\n            // Reinsert interval timer to correct sorted position.  The timer\n            // must be an interval timer because one-shot timers are marked\n            // 'removed' above.\n            this.insertTimer(t);\n        }\n    }\n}\n\nEventLoop.run = function() {\n    var wait;\n    var POLLIN = Poll.POLLIN;\n    var POLLOUT = Poll.POLLOUT;\n    var poll_set;\n    var poll_count;\n    var fd;\n    var t, rev;\n    var rc;\n    var acc_res;\n\n    for (;;) {\n        /*\n         *  Process expired timers.\n         */\n\n        this.processTimers();\n        //this.dumpState();\n\n        /*\n         *  Exit check (may be requested by a user callback)\n         */\n\n        if (this.exitRequested) {\n            //print('exit requested, exit');\n            break;\n        }\n\n        /*\n         *  Create poll socket list.  This is a very naive approach.\n         *  On Linux, one could use e.g. epoll() and manage socket lists\n         *  incrementally.\n         */\n\n        poll_set = {};\n        poll_count = 0;\n        for (fd in this.socketListening) {\n            poll_set[fd] = { events: POLLIN, revents: 0 };\n            poll_count++;\n        }\n        for (fd in this.socketReading) {\n            poll_set[fd] = { events: POLLIN, revents: 0 };\n            poll_count++;\n        }\n        for (fd in this.socketConnecting) {\n            poll_set[fd] = { events: POLLOUT, revents: 0 };\n            poll_count++;\n        }\n        //print(new Date(), 'poll_set IN:', Duktape.enc('jx', poll_set));\n\n        /*\n         *  Wait timeout for timer closest to expiry.  Since the poll\n         *  timeout is relative, get this as close to poll() as possible.\n         */\n\n        wait = this.getEarliestWait();\n        if (wait === null) {\n            if (poll_count === 0) {\n                print('no active timers and no sockets to poll, exit');\n                break;\n            } else {\n                wait = this.maximumWait;\n            }\n        } else {\n            wait = Math.min(this.maximumWait, Math.max(this.minimumWait, wait));\n        }\n\n        /*\n         *  Do the actual poll.\n         */\n\n        try {\n            Poll.poll(poll_set, wait);\n        } catch (e) {\n            // Eat errors silently.\n        }\n\n        /*\n         *  Process all sockets so that nothing is left unhandled for the\n         *  next round.\n         */\n\n        //print(new Date(), 'poll_set OUT:', Duktape.enc('jx', poll_set));\n        for (fd in poll_set) {\n            t = poll_set[fd];\n            rev = t.revents;\n\n            if (rev & POLLIN) {\n                cb = this.socketReading[fd];\n                if (cb) {\n                    data = Socket.read(fd);  // no size control now\n                    //print('READ', Duktape.enc('jx', data));\n                    if (data.length === 0) {\n                        //print('zero read for fd ' + fd + ', closing forcibly');\n                        rc = Socket.close(fd);  // ignore result\n                        delete this.socketListening[fd];\n                        delete this.socketReading[fd];\n                    } else {\n                        cb(fd, data);\n                    }\n                } else {\n                    cb = this.socketListening[fd];\n                    if (cb) {\n                        acc_res = Socket.accept(fd);\n                        //print('ACCEPT:', Duktape.enc('jx', acc_res));\n                        cb(acc_res.fd, acc_res.addr, acc_res.port);\n                    } else {\n                        //print('UNKNOWN');\n                    }\n                }\n            }\n\n            if (rev & POLLOUT) {\n                cb = this.socketConnecting[fd];\n                if (cb) {\n                    delete this.socketConnecting[fd];\n                    cb(fd);\n                } else {\n                    //print('UNKNOWN POLLOUT');\n                }\n            }\n\n            if ((rev & ~(POLLIN | POLLOUT)) !== 0) {\n                //print('revents ' + t.revents + ' for fd ' + fd + ', closing forcibly');\n                rc = Socket.close(fd);  // ignore result\n                delete this.socketListening[fd];\n                delete this.socketReading[fd];\n            }\n        }\n    }\n}\n\nEventLoop.requestExit = function() {\n    this.exitRequested = true;\n}\n\nEventLoop.server = function(address, port, cb_accepted) {\n    var fd = Socket.createServerSocket(address, port);\n    this.socketListening[fd] = cb_accepted;\n}\n\nEventLoop.connect = function(address, port, cb_connected) {\n    var fd = Socket.connect(address, port);\n    this.socketConnecting[fd] = cb_connected;\n}\n\nEventLoop.close = function(fd) {\n    delete this.socketReading[fd];\n    delete this.socketListening[fd];\n}\n\nEventLoop.setReader = function(fd, cb_read) {\n    this.socketReading[fd] = cb_read;\n}\n\nEventLoop.write = function(fd, data) {\n    // This simple example doesn't have support for write blocking / draining\n    if (typeof data === 'string') {\n        data = new TextEncoder().encode(data);\n    }\n    var rc = Socket.write(fd, data);\n}\n\n/*\n *  Timer API\n *\n *  These interface with the singleton EventLoop.\n */\n\nfunction setTimeout(func, delay) {\n    var cb_func;\n    var bind_args;\n    var timer_id;\n    var evloop = EventLoop;\n\n    // Delay can be optional at least in some contexts, so tolerate that.\n    // https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout\n    if (typeof delay !== 'number') {\n        if (typeof delay === 'undefined') {\n            delay = 0;\n        } else {\n            throw new TypeError('invalid delay');\n        }\n    }\n    delay = Math.max(evloop.minimumDelay, delay);\n\n    if (typeof func === 'string') {\n        // Legacy case: callback is a string.\n        cb_func = eval.bind(this, func);\n    } else if (typeof func !== 'function') {\n        throw new TypeError('callback is not a function/string');\n    } else if (arguments.length > 2) {\n        // Special case: callback arguments are provided.\n        bind_args = Array.prototype.slice.call(arguments, 2);  // [ arg1, arg2, ... ]\n        bind_args.unshift(this);  // [ global(this), arg1, arg2, ... ]\n        cb_func = func.bind.apply(func, bind_args);\n    } else {\n        // Normal case: callback given as a function without arguments.\n        cb_func = func;\n    }\n\n    timer_id = evloop.nextTimerId++;\n\n    evloop.insertTimer({\n        id: timer_id,\n        oneshot: true,\n        cb: cb_func,\n        delay: delay,\n        target: Date.now() + delay\n    });\n\n    return timer_id;\n}\n\nfunction clearTimeout(timer_id) {\n    var evloop = EventLoop;\n\n    if (typeof timer_id !== 'number') {\n        throw new TypeError('timer ID is not a number');\n    }\n    evloop.removeTimerById(timer_id);\n}\n\nfunction setInterval(func, delay) {\n    var cb_func;\n    var bind_args;\n    var timer_id;\n    var evloop = EventLoop;\n\n    if (typeof delay !== 'number') {\n        if (typeof delay === 'undefined') {\n            delay = 0;\n        } else {\n            throw new TypeError('invalid delay');\n        }\n    }\n    delay = Math.max(evloop.minimumDelay, delay);\n\n    if (typeof func === 'string') {\n        // Legacy case: callback is a string.\n        cb_func = eval.bind(this, func);\n    } else if (typeof func !== 'function') {\n        throw new TypeError('callback is not a function/string');\n    } else if (arguments.length > 2) {\n        // Special case: callback arguments are provided.\n        bind_args = Array.prototype.slice.call(arguments, 2);  // [ arg1, arg2, ... ]\n        bind_args.unshift(this);  // [ global(this), arg1, arg2, ... ]\n        cb_func = func.bind.apply(func, bind_args);\n    } else {\n        // Normal case: callback given as a function without arguments.\n        cb_func = func;\n    }\n\n    timer_id = evloop.nextTimerId++;\n\n    evloop.insertTimer({\n        id: timer_id,\n        oneshot: false,\n        cb: cb_func,\n        delay: delay,\n        target: Date.now() + delay\n    });\n\n    return timer_id;\n}\n\nfunction clearInterval(timer_id) {\n    var evloop = EventLoop;\n\n    if (typeof timer_id !== 'number') {\n        throw new TypeError('timer ID is not a number');\n    }\n    evloop.removeTimerById(timer_id);\n}\n\n/* custom call */\nfunction requestEventLoopExit() {\n    EventLoop.requestExit();\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/eventloop/fileio.c",
    "content": "/*\n *  File I/O binding example.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"duktape.h\"\n\n/* Push file as a buffer. */\nvoid fileio_push_file_buffer(duk_context *ctx, const char *filename) {\n\tFILE *f = NULL;\n\tlong len;\n\tvoid *buf;\n\tsize_t got;\n\n\tif (!filename) {\n\t\tgoto error;\n\t}\n\n\tf = fopen(filename, \"rb\");\n\tif (!f) {\n\t\tgoto error;\n\t}\n\n\tif (fseek(f, 0, SEEK_END) != 0) {\n\t\tgoto error;\n\t}\n\n\tlen = ftell(f);\n\n\tif (fseek(f, 0, SEEK_SET) != 0) {\n\t\tgoto error;\n\t}\n\n\tbuf = duk_push_fixed_buffer(ctx, (size_t) len);\n\n\tgot = fread(buf, 1, len, f);\n\tif (got != (size_t) len) {\n\t\tduk_pop(ctx);\n\t\tgoto error;\n\t}\n\n\tfclose(f);\n\treturn;\n\n error:\n\tif (f) {\n\t\tfclose(f);\n\t}\n\tduk_push_undefined(ctx);\n}\n\n/* Push file as a string. */\nvoid fileio_push_file_string(duk_context *ctx, const char *filename) {\n\tfileio_push_file_buffer(ctx, filename);\n\tif (duk_is_buffer_data(ctx, -1)) {\n\t\tduk_buffer_to_string(ctx, -1);\n\t}\n}\n\nstatic int fileio_readfile(duk_context *ctx) {\n\tconst char *filename = duk_to_string(ctx, 0);\n\tfileio_push_file_buffer(ctx, filename);\n\tif (!duk_is_buffer_data(ctx, -1)) {\n\t\treturn DUK_RET_ERROR;\n\t}\n\treturn 1;\n}\n\nstatic duk_function_list_entry fileio_funcs[] = {\n\t{ \"readfile\", fileio_readfile, 1 },\n\t{ NULL, NULL, 0 }\n};\n\nvoid fileio_register(duk_context *ctx) {\n\t/* Set global 'FileIo'. */\n\tduk_push_global_object(ctx);\n\tduk_push_object(ctx);\n\tduk_put_function_list(ctx, -1, fileio_funcs);\n\tduk_put_prop_string(ctx, -2, \"FileIo\");\n\tduk_pop(ctx);\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/eventloop/main.c",
    "content": "/*\n *  Main for evloop command line tool.\n *\n *  Runs a given script from file or stdin inside an eventloop.  The\n *  script can then access setTimeout() etc.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#if !defined(NO_SIGNAL)\n#include <signal.h>\n#endif\n\n#include \"duktape.h\"\n\nextern void poll_register(duk_context *ctx);\nextern void socket_register(duk_context *ctx);\nextern void fileio_register(duk_context *ctx);\nextern void fileio_push_file_buffer(duk_context *ctx, const char *filename);\nextern void fileio_push_file_string(duk_context *ctx, const char *filename);\nextern void eventloop_register(duk_context *ctx);\nextern duk_ret_t eventloop_run(duk_context *ctx, void *udata);\n\nstatic int c_evloop = 0;\n\n#if !defined(NO_SIGNAL)\nstatic void my_sighandler(int x) {\n\tfprintf(stderr, \"Got signal %d\\n\", x);\n\tfflush(stderr);\n}\nstatic void set_sigint_handler(void) {\n\t(void) signal(SIGINT, my_sighandler);\n}\n#endif  /* NO_SIGNAL */\n\n/* Print error to stderr and pop error. */\nstatic void print_error(duk_context *ctx, FILE *f) {\n\tif (duk_is_object(ctx, -1) && duk_has_prop_string(ctx, -1, \"stack\")) {\n\t\t/* XXX: print error objects specially */\n\t\t/* XXX: pcall the string coercion */\n\t\tduk_get_prop_string(ctx, -1, \"stack\");\n\t\tif (duk_is_string(ctx, -1)) {\n\t\t\tfprintf(f, \"%s\\n\", duk_get_string(ctx, -1));\n\t\t\tfflush(f);\n\t\t\tduk_pop_2(ctx);\n\t\t\treturn;\n\t\t} else {\n\t\t\tduk_pop(ctx);\n\t\t}\n\t}\n\tduk_to_string(ctx, -1);\n\tfprintf(f, \"%s\\n\", duk_get_string(ctx, -1));\n\tfflush(f);\n\tduk_pop(ctx);\n}\n\nstatic duk_ret_t native_print(duk_context *ctx) {\n\tduk_push_string(ctx, \" \");\n\tduk_insert(ctx, 0);\n\tduk_join(ctx, duk_get_top(ctx) - 1);\n\tprintf(\"%s\\n\", duk_safe_to_string(ctx, -1));\n\treturn 0;\n}\n\nstatic void print_register(duk_context *ctx) {\n\tduk_push_c_function(ctx, native_print, DUK_VARARGS);\n\tduk_put_global_string(ctx, \"print\");\n}\n\nstatic duk_ret_t wrapped_compile_execute(duk_context *ctx, void *udata) {\n\tint comp_flags = 0;\n\tint rc;\n\n\t(void) udata;\n\n\t/* Compile input and place it into global _USERCODE */\n\tduk_compile(ctx, comp_flags);\n\tduk_push_global_object(ctx);\n\tduk_insert(ctx, -2);  /* [ ... global func ] */\n\tduk_put_prop_string(ctx, -2, \"_USERCODE\");\n\tduk_pop(ctx);\n#if 0\n\tprintf(\"compiled usercode\\n\");\n#endif\n\n\t/* Start a zero timer which will call _USERCODE from within\n\t * the event loop.\n\t */\n\tfprintf(stderr, \"set _USERCODE timer\\n\");\n\tfflush(stderr);\n\tduk_eval_string(ctx, \"setTimeout(function() { _USERCODE(); }, 0);\");\n\tduk_pop(ctx);\n\n\t/* Finally, launch eventloop.  This call only returns after the\n\t * eventloop terminates.\n\t */\n\tif (c_evloop) {\n\t\tfprintf(stderr, \"calling eventloop_run()\\n\");\n\t\tfflush(stderr);\n\t\trc = duk_safe_call(ctx, eventloop_run, NULL, 0 /*nargs*/, 1 /*nrets*/);\n\t\tif (rc != 0) {\n\t\t\tfprintf(stderr, \"eventloop_run() failed: %s\\n\", duk_to_string(ctx, -1));\n\t\t\tfflush(stderr);\n\t\t}\n\t\tduk_pop(ctx);\n\t} else {\n\t\tfprintf(stderr, \"calling EventLoop.run()\\n\");\n\t\tfflush(stderr);\n\t\tduk_eval_string(ctx, \"EventLoop.run();\");\n\t\tduk_pop(ctx);\n\t}\n\n\treturn 0;\n}\n\nstatic int handle_fh(duk_context *ctx, FILE *f, const char *filename) {\n\tchar *buf = NULL;\n\tint len;\n\tint got;\n\tint rc;\n\tint retval = -1;\n\n\tif (fseek(f, 0, SEEK_END) < 0) {\n\t\tgoto error;\n\t}\n\tlen = (int) ftell(f);\n\tif (fseek(f, 0, SEEK_SET) < 0) {\n\t\tgoto error;\n\t}\n\tbuf = (char *) malloc(len);\n\tif (!buf) {\n\t\tgoto error;\n\t}\n\n\tgot = fread((void *) buf, (size_t) 1, (size_t) len, f);\n\n\tduk_push_lstring(ctx, buf, got);\n\tduk_push_string(ctx, filename);\n\n\tfree(buf);\n\tbuf = NULL;\n\n\trc = duk_safe_call(ctx, wrapped_compile_execute, NULL, 2 /*nargs*/, 1 /*nret*/);\n\tif (rc != DUK_EXEC_SUCCESS) {\n\t\tprint_error(ctx, stderr);\n\t\tgoto error;\n\t} else {\n\t\tduk_pop(ctx);\n\t\tretval = 0;\n\t}\n\t/* fall thru */\n\n error:\n\tif (buf) {\n\t\tfree(buf);\n\t}\n\treturn retval;\n}\n\nstatic int handle_file(duk_context *ctx, const char *filename) {\n\tFILE *f = NULL;\n\tint retval;\n\n\tf = fopen(filename, \"rb\");\n\tif (!f) {\n\t\tfprintf(stderr, \"failed to open source file: %s\\n\", filename);\n\t\tfflush(stderr);\n\t\tgoto error;\n\t}\n\n\tretval = handle_fh(ctx, f, filename);\n\n\tfclose(f);\n\treturn retval;\n\n error:\n\treturn -1;\n}\n\nstatic int handle_stdin(duk_context *ctx) {\n\tint retval;\n\n\tretval = handle_fh(ctx, stdin, \"stdin\");\n\n\treturn retval;\n}\n\nstatic duk_ret_t init_duktape_context(duk_context *ctx, void *udata) {\n\t(void) udata;\n\n\tprint_register(ctx);\n\tpoll_register(ctx);\n\tsocket_register(ctx);\n\tfileio_register(ctx);\n\n\tif (c_evloop) {\n\t\tfprintf(stderr, \"Using C based eventloop (omit -c to use ECMAScript based eventloop)\\n\");\n\t\tfflush(stderr);\n\n\t\teventloop_register(ctx);\n\t\tfileio_push_file_string(ctx, \"c_eventloop.js\");\n\t\tduk_eval(ctx);\n\t} else {\n\t\tfprintf(stderr, \"Using ECMAScript based eventloop (give -c to use C based eventloop)\\n\");\n\t\tfflush(stderr);\n\n\t\tfileio_push_file_string(ctx, \"ecma_eventloop.js\");\n\t\tduk_eval(ctx);\n\t}\n\n\treturn 0;\n}\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx = NULL;\n\tint retval = 1;\n\tconst char *filename = NULL;\n\tint i;\n\n#if !defined(NO_SIGNAL)\n\tset_sigint_handler();\n\n\t/* This is useful at the global level; libraries should avoid SIGPIPE though */\n\t/*signal(SIGPIPE, SIG_IGN);*/\n#endif\n\n\tfor (i = 1; i < argc; i++) {\n\t\tchar *arg = argv[i];\n\t\tif (!arg) {\n\t\t\tgoto usage;\n\t\t}\n\t\tif (strcmp(arg, \"-c\") == 0) {\n\t\t\tc_evloop = 1;\n\t\t} else if (strlen(arg) > 1 && arg[0] == '-') {\n\t\t\tgoto usage;\n\t\t} else {\n\t\t\tif (filename) {\n\t\t\t\tgoto usage;\n\t\t\t}\n\t\t\tfilename = arg;\n\t\t}\n\t}\n\tif (!filename) {\n\t\tgoto usage;\n\t}\n\n\tctx = duk_create_heap_default();\n\n\tif (duk_safe_call(ctx, init_duktape_context, NULL, 0 /*nargs*/, 1 /*nrets*/) != 0) {\n\t\tfprintf(stderr, \"Failed to initialize: %s\\n\", duk_safe_to_string(ctx, -1));\n\t\tgoto cleanup;\n\t}\n\tduk_pop(ctx);\n\n\tfprintf(stderr, \"Executing code from: '%s'\\n\", filename);\n\tfflush(stderr);\n\n\tif (strcmp(filename, \"-\") == 0) {\n\t\tif (handle_stdin(ctx) != 0) {\n\t\t\tgoto cleanup;\n\t\t}\n\t} else {\n\t\tif (handle_file(ctx, filename) != 0) {\n\t\t\tgoto cleanup;\n\t\t}\n\t}\n\n\tretval = 0;\n\t/* fall through */\n cleanup:\n\tif (ctx) {\n\t\tduk_destroy_heap(ctx);\n\t}\n\n\treturn retval;\n\n usage:\n\tfprintf(stderr, \"Usage: evloop [-c] <filename>\\n\");\n\tfprintf(stderr, \"\\n\");\n\tfprintf(stderr, \"Uses an ECMAScript based eventloop (ecma_eventloop.js) by default.\\n\");\n\tfprintf(stderr, \"If -c option given, uses a C based eventloop (c_eventloop.{c,js}).\\n\");\n\tfprintf(stderr, \"If <filename> is '-', the entire STDIN executed.\\n\");\n\tfflush(stderr);\n\texit(1);\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/eventloop/poll.c",
    "content": "/*\n *  C wrapper for poll().\n */\n\n#define _GNU_SOURCE\n#include <errno.h>\n#include <string.h>\n#include <stdio.h>\n\n#if defined(_WIN32)\n#include <WinSock2.h>\n#define poll WSAPoll\n#pragma comment(lib, \"ws2_32\")\n#else\n#include <poll.h>\n#endif\n\n#include <time.h>\n\n#include \"duktape.h\"\n\nstatic int poll_poll(duk_context *ctx) {\n\tint timeout = duk_to_int(ctx, 1);\n\tint i, n, nchanged;\n\tint fd, rc;\n\tstruct pollfd fds[20];\n\tstruct timespec ts;\n\n\tmemset(fds, 0, sizeof(fds));\n\n\tn = 0;\n\tduk_enum(ctx, 0, 0 /*enum_flags*/);\n\twhile (duk_next(ctx, -1, 0)) {\n\t\tif ((size_t) n >= sizeof(fds) / sizeof(struct pollfd)) {\n\t\t\treturn -1;\n\t\t}\n\n\t\t/* [... enum key] */\n\t\tduk_dup_top(ctx);  /* -> [... enum key key] */\n\t\tduk_get_prop(ctx, 0);  /* -> [... enum key val] */\n\t\tfd = duk_to_int(ctx, -2);\n\n\t\tduk_push_string(ctx, \"events\");\n\t\tduk_get_prop(ctx, -2);  /* -> [... enum key val events] */\n\n\t\tfds[n].fd = fd;\n\t\tfds[n].events = duk_to_int(ctx, -1);\n\t\tfds[n].revents = 0;\n\n\t\tduk_pop_n(ctx, 3);  /* -> [... enum] */\n\n\t\tn++;\n\t}\n\t/* leave enum on stack */\n\n\tmemset(&ts, 0, sizeof(ts));\n\tts.tv_nsec = (timeout % 1000) * 1000000;\n\tts.tv_sec = timeout / 1000;\n\n\t/*rc = ppoll(fds, n, &ts, NULL);*/\n\trc = poll(fds, n, timeout);\n\tif (rc < 0) {\n\t\t(void) duk_error(ctx, DUK_ERR_ERROR, \"%s (errno=%d)\", strerror(errno), errno);\n\t}\n\n\tduk_push_array(ctx);\n\tnchanged = 0;\n\tfor (i = 0; i < n; i++) {\n\t\t/* update revents */\n\n\t\tif (fds[i].revents) {\n\t\t\tduk_push_int(ctx, fds[i].fd);  /* -> [... retarr fd] */\n\t\t\tduk_put_prop_index(ctx, -2, nchanged);\n\t\t\tnchanged++;\n\t\t}\n\n\t\tduk_push_int(ctx, fds[i].fd);  /* -> [... retarr key] */\n\t\tduk_get_prop(ctx, 0);  /* -> [... retarr val] */\n\t\tduk_push_string(ctx, \"revents\");\n\t\tduk_push_int(ctx, fds[i].revents);  /* -> [... retarr val \"revents\" fds[i].revents] */\n\t\tduk_put_prop(ctx, -3);  /* -> [... retarr val] */\n\t\tduk_pop(ctx);\n\t}\n\n\t/* [retarr] */\n\n\treturn 1;\n}\n\nstatic duk_function_list_entry poll_funcs[] = {\n\t{ \"poll\", poll_poll, 2 },\n\t{ NULL, NULL, 0 }\n};\n\nstatic duk_number_list_entry poll_consts[] = {\n\t{ \"POLLIN\", (double) POLLIN },\n\t{ \"POLLPRI\", (double) POLLPRI },\n\t{ \"POLLOUT\", (double) POLLOUT },\n#if 0\n\t/* Linux 2.6.17 and upwards, requires _GNU_SOURCE etc, not added\n\t * now because we don't use it.\n\t */\n\t{ \"POLLRDHUP\", (double) POLLRDHUP },\n#endif\n\t{ \"POLLERR\", (double) POLLERR },\n\t{ \"POLLHUP\", (double) POLLHUP },\n\t{ \"POLLNVAL\", (double) POLLNVAL },\n\t{ NULL, 0.0 }\n};\n\nvoid poll_register(duk_context *ctx) {\n\t/* Set global 'Poll' with functions and constants. */\n\tduk_push_global_object(ctx);\n\tduk_push_object(ctx);\n\tduk_put_function_list(ctx, -1, poll_funcs);\n\tduk_put_number_list(ctx, -1, poll_consts);\n\tduk_put_prop_string(ctx, -2, \"Poll\");\n\tduk_pop(ctx);\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/eventloop/server-socket-test.js",
    "content": "var HOST = 'localhost'\nvar PORT = 12345;\nvar EXIT_TIMEOUT = 300e3;\n\nprint('automatic exit after ' + (EXIT_TIMEOUT / 1e3) + ' seconds');\nsetTimeout(function () {\n    print('exit timer');\n    EventLoop.requestExit();\n}, EXIT_TIMEOUT);\n\nprint('listen on ' + HOST + ':' + PORT);\nEventLoop.server(HOST, PORT, function (fd, addr, port) {\n    print('new connection on fd ' + fd + ' from ' + addr + ':' + port);\n    EventLoop.setReader(fd, function (fd, data) {\n        var b, i, n, x;\n\n        // Handle socket data carefully: if you convert it to a string,\n        // it may not be valid UTF-8 etc.  Here we operate on the data\n        // directly in the buffer.\n\n        b = data.valueOf();  // ensure we get a plain buffer\n        n = b.length;\n        for (i = 0; i < n; i++) {\n            x = b[i];\n            if (x >= 0x61 && x <= 0x7a) {\n                b[i] = x - 0x20;  // uppercase\n            }\n        }\n\n        print('read data on fd ' + fd + ', length ' + data.length);\n        EventLoop.write(fd, data);\n    });\n});\n"
  },
  {
    "path": "react_juce/duktape/examples/eventloop/socket.c",
    "content": "/*\n *  TCP sockets binding example.\n */\n\n#define _GNU_SOURCE\n#include <errno.h>\n#include <string.h>\n#include <stdio.h>\n#include <unistd.h>\n#include <fcntl.h>\n#include <netdb.h>\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <time.h>\n\n#include \"duktape.h\"\n\n#define  ERROR_FROM_ERRNO(ctx)  do { \\\n\t\t(void) duk_error(ctx, DUK_ERR_ERROR, \"%s (errno=%d)\", strerror(errno), errno); \\\n\t} while (0)\n\nstatic void set_nonblocking(duk_context *ctx, int fd) {\n\tint rc;\n\tint flags;\n\n\trc = fcntl(fd, F_GETFL);\n\tif (rc < 0) {\n\t\tERROR_FROM_ERRNO(ctx);\n\t}\n\tflags = rc;\n\n\tflags |= O_NONBLOCK;\n\n\trc = fcntl(fd, F_SETFL, flags);\n\tif (rc < 0) {\n\t\tERROR_FROM_ERRNO(ctx);\n\t}\n}\n\nstatic void set_reuseaddr(duk_context *ctx, int fd) {\n\tint val;\n\tint rc;\n\n\tval = 1;\n\trc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *) &val, sizeof(val));\n\tif (rc != 0) {\n\t\tERROR_FROM_ERRNO(ctx);\n\t}\n}\n\n#if defined(__APPLE__)\nstatic void set_nosigpipe(duk_context *ctx, int fd) {\n\tint val;\n\tint rc;\n\n\tval = 1;\n\trc = setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (const void *) &val, sizeof(val));\n\tif (rc != 0) {\n\t\tERROR_FROM_ERRNO(ctx);\n\t}\n}\n#endif\n\nstatic int socket_create_server_socket(duk_context *ctx) {\n\tconst char *addr = duk_to_string(ctx, 0);\n\tint port = duk_to_int(ctx, 1);\n\tint sock;\n\tstruct sockaddr_in sockaddr;\n\tstruct hostent *ent;\n\tstruct in_addr **addr_list;\n\tstruct in_addr *addr_inet;\n\tint i;\n\tint rc;\n\n\tsock = socket(AF_INET, SOCK_STREAM, 0);\n\tif (sock < 0) {\n\t\tERROR_FROM_ERRNO(ctx);\n\t}\n\n\tset_nonblocking(ctx, sock);\n\tset_reuseaddr(ctx, sock);\n#if defined(__APPLE__)\n\tset_nosigpipe(ctx, sock);\n#endif\n\n\tent = gethostbyname(addr);\n\tif (!ent) {\n\t\tERROR_FROM_ERRNO(ctx);\n\t}\n\n\taddr_list = (struct in_addr **) ent->h_addr_list;\n\taddr_inet = NULL;\n\tfor (i = 0; addr_list[i]; i++) {\n\t\taddr_inet = addr_list[i];\n\t\tbreak;\n\t}\n\tif (!addr_inet) {\n\t\t(void) duk_error(ctx, DUK_ERR_ERROR, \"cannot resolve %s\", addr);\n\t}\n\n\tmemset(&sockaddr, 0, sizeof(sockaddr));\n\tsockaddr.sin_family = AF_INET;\n\tsockaddr.sin_port = htons(port);\n\tsockaddr.sin_addr = *addr_inet;\n\n\trc = bind(sock, (const struct sockaddr *) &sockaddr, sizeof(sockaddr));\n\tif (rc < 0) {\n\t\tERROR_FROM_ERRNO(ctx);\n\t}\n\n\trc = listen(sock, 10 /*backlog*/);\n\tif (rc < 0) {\n\t\t(void) close(sock);\n\t\tERROR_FROM_ERRNO(ctx);\n\t}\n\n\tduk_push_int(ctx, sock);\n\treturn 1;\n}\n\nstatic int socket_close(duk_context *ctx) {\n\tint sock = duk_to_int(ctx, 0);\n\tint rc;\n\n\trc = close(sock);\n\tif (rc < 0) {\n\t\tERROR_FROM_ERRNO(ctx);\n\t}\n\treturn 0;\n}\n\nstatic int socket_accept(duk_context *ctx) {\n\tint sock = duk_to_int(ctx, 0);\n\tint rc;\n\tstruct sockaddr_in addr;\n\tsocklen_t addrlen;\n\n\tmemset(&addr, 0, sizeof(addr));\n\taddr.sin_family = AF_INET;\n\taddrlen = sizeof(addr);\n\n\trc = accept(sock, (struct sockaddr *) &addr, &addrlen);\n\tif (rc < 0) {\n\t\tERROR_FROM_ERRNO(ctx);\n\t}\n\n\tset_nonblocking(ctx, sock);\n#if defined(__APPLE__)\n\tset_nosigpipe(ctx, sock);\n#endif\n\n\tif (addrlen == sizeof(addr)) {\n\t\tuint32_t tmp = ntohl(addr.sin_addr.s_addr);\n\n\t\tduk_push_object(ctx);\n\n\t\tduk_push_string(ctx, \"fd\");\n\t\tduk_push_int(ctx, rc);\n\t\tduk_put_prop(ctx, -3);\n\t\tduk_push_string(ctx, \"addr\");\n\t\tduk_push_sprintf(ctx, \"%d.%d.%d.%d\", ((tmp >> 24) & 0xff), ((tmp >> 16) & 0xff), ((tmp >> 8) & 0xff), (tmp & 0xff));\n\t\tduk_put_prop(ctx, -3);\n\t\tduk_push_string(ctx, \"port\");\n\t\tduk_push_int(ctx, ntohs(addr.sin_port));\n\t\tduk_put_prop(ctx, -3);\n\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\nstatic int socket_connect(duk_context *ctx) {\n\tconst char *addr = duk_to_string(ctx, 0);\n\tint port = duk_to_int(ctx, 1);\n\tint sock;\n\tstruct sockaddr_in sockaddr;\n\tstruct hostent *ent;\n\tstruct in_addr **addr_list;\n\tstruct in_addr *addr_inet;\n\tint i;\n\tint rc;\n\n\tsock = socket(AF_INET, SOCK_STREAM, 0);\n\tif (sock < 0) {\n\t\tERROR_FROM_ERRNO(ctx);\n\t}\n\n\tset_nonblocking(ctx, sock);\n#if defined(__APPLE__)\n\tset_nosigpipe(ctx, sock);\n#endif\n\n\tent = gethostbyname(addr);\n\tif (!ent) {\n\t\tERROR_FROM_ERRNO(ctx);\n\t}\n\n\taddr_list = (struct in_addr **) ent->h_addr_list;\n\taddr_inet = NULL;\n\tfor (i = 0; addr_list[i]; i++) {\n\t\taddr_inet = addr_list[i];\n\t\tbreak;\n\t}\n\tif (!addr_inet) {\n\t\t(void) duk_error(ctx, DUK_ERR_ERROR, \"cannot resolve %s\", addr);\n\t}\n\n\tmemset(&sockaddr, 0, sizeof(sockaddr));\n\tsockaddr.sin_family = AF_INET;\n\tsockaddr.sin_port = htons(port);\n\tsockaddr.sin_addr = *addr_inet;\n\n\trc = connect(sock, (const struct sockaddr *) &sockaddr, (socklen_t) sizeof(sockaddr));\n\tif (rc < 0) {\n\t\tif (errno == EINPROGRESS) {\n#if 0\n\t\t\tfprintf(stderr, \"connect() returned EINPROGRESS as expected, need to poll writability\\n\");\n\t\t\tfflush(stderr);\n#endif\n\t\t} else {\n\t\t\tERROR_FROM_ERRNO(ctx);\n\t\t}\n\t}\n\n\tduk_push_int(ctx, sock);\n\treturn 1;\n}\n\nstatic int socket_read(duk_context *ctx) {\n\tint sock = duk_to_int(ctx, 0);\n\tchar readbuf[1024];\n\tint rc;\n\tvoid *data;\n\n\trc = recvfrom(sock, (void *) readbuf, sizeof(readbuf), 0, NULL, NULL);\n\tif (rc < 0) {\n\t\tERROR_FROM_ERRNO(ctx);\n\t}\n\n\tdata = duk_push_fixed_buffer(ctx, rc);\n\tmemcpy(data, readbuf, rc);\n\treturn 1;\n}\n\nstatic int socket_write(duk_context *ctx) {\n\tint sock = duk_to_int(ctx, 0);\n\tconst char *data;\n\tsize_t len;\n\tssize_t rc;\n\n\tdata = duk_require_buffer_data(ctx, 1, &len);\n\n\t/* MSG_NOSIGNAL: avoid SIGPIPE */\n#if defined(__APPLE__)\n\trc = sendto(sock, (void *) data, len, 0, NULL, 0);\n#else\n\trc = sendto(sock, (void *) data, len, MSG_NOSIGNAL, NULL, 0);\n#endif\n\tif (rc < 0) {\n\t\tERROR_FROM_ERRNO(ctx);\n\t}\n\n\tduk_push_int(ctx, rc);\n\treturn 1;\n}\n\nstatic duk_function_list_entry socket_funcs[] = {\n\t{ \"createServerSocket\", socket_create_server_socket, 2 },\n\t{ \"close\", socket_close, 1 },\n\t{ \"accept\", socket_accept, 1 },\n\t{ \"connect\", socket_connect, 2 },\n\t{ \"read\", socket_read, 1 },\n\t{ \"write\", socket_write, 2 },\n\t{ NULL, NULL, 0 }\n};\n\nvoid socket_register(duk_context *ctx) {\n\t/* Set global 'Socket'. */\n\tduk_push_global_object(ctx);\n\tduk_push_object(ctx);\n\tduk_put_function_list(ctx, -1, socket_funcs);\n\tduk_put_prop_string(ctx, -2, \"Socket\");\n\tduk_pop(ctx);\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/eventloop/timer-test.js",
    "content": "/*\n *  Test using timers and intervals.\n */\n\nfunction main() {\n    var i;\n    var counters = [];\n    var ntimers = 0;\n\n    print('set interval timer');\n    var intervalTimer = setInterval(function () {\n        print(new Date().toISOString() + ': timers pending: ' + ntimers);\n        if (ntimers === 0) {\n            clearInterval(intervalTimer);\n        }\n    }, 500);\n\n    function addTimer(interval) {\n        ntimers++;\n        setTimeout(function () {\n            ntimers--;\n        }, interval);\n    }\n\n    /* Here the inserts take a lot of time because the underlying timer manager\n     * data structure has O(n) insertion performance.\n     */\n    print('launch timers');\n    for (i = 0; i < 4000; i++) {\n        // Math.exp(0)...Math.exp(8) is an uneven distribution between 1...~2980.\n        addTimer(16000 - Math.exp(Math.random() * 8) * 5);\n    }\n    print('timers launched');\n}\n\ntry {\n    main();\n} catch (e) {\n    print(e.stack || e);\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/guide/README.rst",
    "content": "===========================\nDuktape guide example files\n===========================\n\nExamples used in the Duktape guide.\n"
  },
  {
    "path": "react_juce/duktape/examples/guide/fib.js",
    "content": "// fib.js\nfunction fib(n) {\n    if (n == 0) { return 0; }\n    if (n == 1) { return 1; }\n    return fib(n-1) + fib(n-2);\n}\n\nfunction test() {\n    var res = [];\n    for (i = 0; i < 20; i++) {\n        res.push(fib(i));\n    }\n    print(res.join(' '));\n}\n\ntest();\n"
  },
  {
    "path": "react_juce/duktape/examples/guide/prime.js",
    "content": "// prime.js\n\n// Pure ECMAScript version of low level helper\nfunction primeCheckECMAScript(val, limit) {\n    for (var i = 2; i <= limit; i++) {\n        if ((val % i) == 0) { return false; }\n    }\n    return true;\n}\n\n// Select available helper at load time\nvar primeCheckHelper = (this.primeCheckNative || primeCheckECMAScript);\n\n// Check 'val' for primality\nfunction primeCheck(val) {\n    if (val == 1 || val == 2) { return true; }\n    var limit = Math.ceil(Math.sqrt(val));\n    while (limit * limit < val) { limit += 1; }\n    return primeCheckHelper(val, limit);\n}\n\n// Find primes below one million ending in '9999'.\nfunction primeTest() {\n    var res = [];\n\n    print('Have native helper: ' + (primeCheckHelper !== primeCheckECMAScript));\n    for (var i = 1; i < 1000000; i++) {\n        if (primeCheck(i) && (i % 10000) == 9999) { res.push(i); }\n    } \n    print(res.join(' '));\n}\n\n"
  },
  {
    "path": "react_juce/duktape/examples/guide/primecheck.c",
    "content": "/* primecheck.c */\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include \"duktape.h\"\n\n/* For brevity assumes a maximum file length of 16kB. */\nstatic void push_file_as_string(duk_context *ctx, const char *filename) {\n    FILE *f;\n    size_t len;\n    char buf[16384];\n\n    f = fopen(filename, \"rb\");\n    if (f) {\n        len = fread((void *) buf, 1, sizeof(buf), f);\n        fclose(f);\n        duk_push_lstring(ctx, (const char *) buf, (duk_size_t) len);\n    } else {\n        duk_push_undefined(ctx);\n    }\n}\n\nstatic duk_ret_t native_print(duk_context *ctx) {\n    duk_push_string(ctx, \" \");\n    duk_insert(ctx, 0);\n    duk_join(ctx, duk_get_top(ctx) - 1);\n    printf(\"%s\\n\", duk_to_string(ctx, -1));\n    return 0;\n}\n\nstatic duk_ret_t native_prime_check(duk_context *ctx) {\n    int val = duk_require_int(ctx, 0);\n    int lim = duk_require_int(ctx, 1);\n    int i;\n\n    for (i = 2; i <= lim; i++) {\n        if (val % i == 0) {\n            duk_push_false(ctx);\n            return 1;\n        }\n    }\n\n    duk_push_true(ctx);\n    return 1;\n}\n\nint main(int argc, const char *argv[]) {\n    duk_context *ctx = NULL;\n\n    (void) argc; (void) argv;\n\n    ctx = duk_create_heap_default();\n    if (!ctx) {\n        printf(\"Failed to create a Duktape heap.\\n\");\n        exit(1);\n    }\n\n    duk_push_global_object(ctx);\n    duk_push_c_function(ctx, native_print, DUK_VARARGS);\n    duk_put_prop_string(ctx, -2, \"print\");\n    duk_push_c_function(ctx, native_prime_check, 2 /*nargs*/);\n    duk_put_prop_string(ctx, -2, \"primeCheckNative\");\n\n    push_file_as_string(ctx, \"prime.js\");\n    if (duk_peval(ctx) != 0) {\n        printf(\"Error running: %s\\n\", duk_safe_to_string(ctx, -1));\n        goto finished;\n    }\n    duk_pop(ctx);  /* ignore result */\n\n    duk_get_prop_string(ctx, -1, \"primeTest\");\n    if (duk_pcall(ctx, 0) != 0) {\n        printf(\"Error: %s\\n\", duk_safe_to_string(ctx, -1));\n    }\n    duk_pop(ctx);  /* ignore result */\n\n finished:\n    duk_destroy_heap(ctx);\n\n    exit(0);\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/guide/process.js",
    "content": "// process.js\nfunction processLine(line) {\n    return line.trim()\n        .replace(/[<>&\"'\\u0000-\\u001F\\u007E-\\uFFFF]/g, function(x) {\n            // escape HTML characters\n            return '&#' + x.charCodeAt(0) + ';'\n         })\n        .replace(/\\*(.*?)\\*/g, function(x, m) {\n            // automatically bold text between stars\n            return '<b>' + m + '</b>';\n         });\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/guide/processlines.c",
    "content": "/* processlines.c */\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include \"duktape.h\"\n\n/* For brevity assumes a maximum file length of 16kB. */\nstatic void push_file_as_string(duk_context *ctx, const char *filename) {\n    FILE *f;\n    size_t len;\n    char buf[16384];\n\n    f = fopen(filename, \"rb\");\n    if (f) {\n        len = fread((void *) buf, 1, sizeof(buf), f);\n        fclose(f);\n        duk_push_lstring(ctx, (const char *) buf, (duk_size_t) len);\n    } else {\n        duk_push_undefined(ctx);\n    }\n}\n\nint main(int argc, const char *argv[]) {\n    duk_context *ctx = NULL;\n    char line[4096];\n    size_t idx;\n    int ch;\n\n    (void) argc; (void) argv;\n\n    ctx = duk_create_heap_default();\n    if (!ctx) {\n        printf(\"Failed to create a Duktape heap.\\n\");\n        exit(1);\n    }\n\n    push_file_as_string(ctx, \"process.js\");\n    if (duk_peval(ctx) != 0) {\n        printf(\"Error: %s\\n\", duk_safe_to_string(ctx, -1));\n        goto finished;\n    }\n    duk_pop(ctx);  /* ignore result */\n\n    memset(line, 0, sizeof(line));\n    idx = 0;\n    for (;;) {\n        if (idx >= sizeof(line)) {\n            printf(\"Line too long\\n\");\n            exit(1);\n        }\n\n        ch = fgetc(stdin);\n        if (ch == 0x0a) {\n            line[idx++] = '\\0';\n\n            duk_push_global_object(ctx);\n            duk_get_prop_string(ctx, -1 /*index*/, \"processLine\");\n            duk_push_string(ctx, line);\n            if (duk_pcall(ctx, 1 /*nargs*/) != 0) {\n                printf(\"Error: %s\\n\", duk_safe_to_string(ctx, -1));\n            } else {\n                printf(\"%s\\n\", duk_safe_to_string(ctx, -1));\n            }\n            duk_pop(ctx);  /* pop result/error */\n\n            idx = 0;\n        } else if (ch == EOF) {\n            break;\n        } else {\n            line[idx++] = (char) ch;\n        }\n    }\n\n finished:\n    duk_destroy_heap(ctx);\n\n    exit(0);\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/guide/uppercase.c",
    "content": "/* uppercase.c */\n#include <stdio.h>\n#include <stdlib.h>\n#include \"duktape.h\"\n\nstatic int dummy_upper_case(duk_context *ctx) {\n    size_t sz;\n    const char *val = duk_require_lstring(ctx, 0, &sz);\n    size_t i;\n\n    /* We're going to need 'sz' additional entries on the stack. */\n    duk_require_stack(ctx, sz);\n\n    for (i = 0; i < sz; i++) {\n        char ch = val[i];\n        if (ch >= 'a' && ch <= 'z') {\n            ch = ch - 'a' + 'A';\n        }\n        duk_push_lstring(ctx, (const char *) &ch, 1);\n    }\n\n    duk_concat(ctx, sz);\n    return 1;\n}\n\nint main(int argc, char *argv[]) {\n    duk_context *ctx;\n\n    if (argc < 2) { exit(1); }\n\n    ctx = duk_create_heap_default();\n    if (!ctx) { exit(1); }\n\n    duk_push_c_function(ctx, dummy_upper_case, 1);\n    duk_push_string(ctx, argv[1]);\n    duk_call(ctx, 1);\n    printf(\"%s -> %s\\n\", argv[1], duk_to_string(ctx, -1));\n    duk_pop(ctx);\n\n    duk_destroy_heap(ctx);\n    return 0;\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/hello/README.rst",
    "content": "===================\nHello world example\n===================\n\nVery simple example, most useful for compilation tests.\n"
  },
  {
    "path": "react_juce/duktape/examples/hello/hello.c",
    "content": "/*\n *  Very simple example program\n */\n\n#include \"duktape.h\"\n\nstatic duk_ret_t native_print(duk_context *ctx) {\n\tduk_push_string(ctx, \" \");\n\tduk_insert(ctx, 0);\n\tduk_join(ctx, duk_get_top(ctx) - 1);\n\tprintf(\"%s\\n\", duk_safe_to_string(ctx, -1));\n\treturn 0;\n}\n\nstatic duk_ret_t native_adder(duk_context *ctx) {\n\tint i;\n\tint n = duk_get_top(ctx);  /* #args */\n\tdouble res = 0.0;\n\n\tfor (i = 0; i < n; i++) {\n\t\tres += duk_to_number(ctx, i);\n\t}\n\n\tduk_push_number(ctx, res);\n\treturn 1;  /* one return value */\n}\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx = duk_create_heap_default();\n\n\t(void) argc; (void) argv;  /* suppress warning */\n\n\tduk_push_c_function(ctx, native_print, DUK_VARARGS);\n\tduk_put_global_string(ctx, \"print\");\n\tduk_push_c_function(ctx, native_adder, DUK_VARARGS);\n\tduk_put_global_string(ctx, \"adder\");\n\n\tduk_eval_string(ctx, \"print('Hello world!');\");\n\n\tduk_eval_string(ctx, \"print('2+3=' + adder(2, 3));\");\n\tduk_pop(ctx);  /* pop eval result */\n\n\tduk_destroy_heap(ctx);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/jxpretty/README.rst",
    "content": "================\nJxpretty example\n================\n\nSimple command line utility to pretty print JSON in the JX format.\n"
  },
  {
    "path": "react_juce/duktape/examples/jxpretty/jxpretty.c",
    "content": "/*\n *  Pretty print JSON from stdin into indented JX.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include \"duktape.h\"\n\nstatic duk_ret_t duk__print(duk_context *ctx) {\n\tduk_push_string(ctx, \" \");\n\tduk_insert(ctx, 0);\n\tduk_join(ctx, duk_get_top(ctx) - 1);\n\tprintf(\"%s\\n\", duk_safe_to_string(ctx, -1));\n\treturn 0;\n}\n\nstatic duk_ret_t do_jxpretty(duk_context *ctx, void *udata) {\n\tFILE *f = stdin;\n\tchar buf[4096];\n\tsize_t ret;\n\n\t(void) udata;\n\n\tfor (;;) {\n\t\tif (ferror(f)) {\n\t\t\t(void) duk_error(ctx, DUK_ERR_ERROR, \"ferror() on stdin\");\n\t\t}\n\t\tif (feof(f)) {\n\t\t\tbreak;\n\t\t}\n\n\t\tret = fread(buf, 1, sizeof(buf), f);\n#if 0\n\t\tfprintf(stderr, \"Read: %ld\\n\", (long) ret);\n\t\tfflush(stderr);\n#endif\n\t\tif (ret == 0) {\n\t\t\tbreak;\n\t\t}\n\n\t\tduk_require_stack(ctx, 1);\n\t\tduk_push_lstring(ctx, (const char *) buf, ret);\n\t}\n\n\tduk_concat(ctx, duk_get_top(ctx));\n\n\tduk_eval_string(ctx, \"(function (v) { print(Duktape.enc('jx', JSON.parse(v), null, 4)); })\");\n\tduk_insert(ctx, -2);\n\tduk_call(ctx, 1);\n\n\treturn 0;\n}\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx;\n\tduk_int_t rc;\n\n\t/* suppress warnings */\n\t(void) argc;\n\t(void) argv;\n\n\tctx = duk_create_heap_default();\n\n\tduk_push_c_function(ctx, duk__print, DUK_VARARGS);\n\tduk_put_global_string(ctx, \"print\");\n\n\trc = duk_safe_call(ctx, do_jxpretty, NULL, 0 /*nargs*/, 1 /*nrets*/);\n\tif (rc) {\n\t\tfprintf(stderr, \"ERROR: %s\\n\", duk_safe_to_string(ctx, -1));\n\t\tfflush(stderr);\n\t}\n\n\tduk_destroy_heap(ctx);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "react_juce/duktape/examples/sandbox/README.rst",
    "content": "===============\nSandbox example\n===============\n\nVery simple, minimal sandboxing example.\n"
  },
  {
    "path": "react_juce/duktape/examples/sandbox/sandbox.c",
    "content": "/*\n *  Sandboxing example\n *\n *  Uses custom memory allocation functions which keep track of total amount\n *  of memory allocated, imposing a maximum total allocation size.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include \"duktape.h\"\n\n/*\n *  Memory allocator which backs to standard library memory functions but\n *  keeps a small header to track current allocation size.\n *\n *  Many other sandbox allocation models are useful, e.g. preallocated pools.\n */\n\ntypedef struct {\n\t/* The double value in the union is there to ensure alignment is\n\t * good for IEEE doubles too.  In many 32-bit environments 4 bytes\n\t * would be sufficiently aligned and the double value is unnecessary.\n\t */\n\tunion {\n\t\tsize_t sz;\n\t\tdouble d;\n\t} u;\n} alloc_hdr;\n\nstatic size_t total_allocated = 0;\nstatic size_t max_allocated = 256 * 1024;  /* 256kB sandbox */\n\nstatic void sandbox_dump_memstate(void) {\n#if 0\n\tfprintf(stderr, \"Total allocated: %ld\\n\", (long) total_allocated);\n\tfflush(stderr);\n#endif\n}\n\nstatic void *sandbox_alloc(void *udata, duk_size_t size) {\n\talloc_hdr *hdr;\n\n\t(void) udata;  /* Suppress warning. */\n\n\tif (size == 0) {\n\t\treturn NULL;\n\t}\n\n\tif (total_allocated + size > max_allocated) {\n\t\tfprintf(stderr, \"Sandbox maximum allocation size reached, %ld requested in sandbox_alloc\\n\",\n\t\t        (long) size);\n\t\tfflush(stderr);\n\t\treturn NULL;\n\t}\n\n\thdr = (alloc_hdr *) malloc(size + sizeof(alloc_hdr));\n\tif (!hdr) {\n\t\treturn NULL;\n\t}\n\thdr->u.sz = size;\n\ttotal_allocated += size;\n\tsandbox_dump_memstate();\n\treturn (void *) (hdr + 1);\n}\n\nstatic void *sandbox_realloc(void *udata, void *ptr, duk_size_t size) {\n\talloc_hdr *hdr;\n\tsize_t old_size;\n\tvoid *t;\n\n\t(void) udata;  /* Suppress warning. */\n\n\t/* Handle the ptr-NULL vs. size-zero cases explicitly to minimize\n\t * platform assumptions.  You can get away with much less in specific\n\t * well-behaving environments.\n\t */\n\n\tif (ptr) {\n\t\thdr = (alloc_hdr *) (((char *) ptr) - sizeof(alloc_hdr));\n\t\told_size = hdr->u.sz;\n\n\t\tif (size == 0) {\n\t\t\ttotal_allocated -= old_size;\n\t\t\tfree((void *) hdr);\n\t\t\tsandbox_dump_memstate();\n\t\t\treturn NULL;\n\t\t} else {\n\t\t\tif (total_allocated - old_size + size > max_allocated) {\n\t\t\t\tfprintf(stderr, \"Sandbox maximum allocation size reached, %ld requested in sandbox_realloc\\n\",\n\t\t\t\t        (long) size);\n\t\t\t\tfflush(stderr);\n\t\t\t\treturn NULL;\n\t\t\t}\n\n\t\t\tt = realloc((void *) hdr, size + sizeof(alloc_hdr));\n\t\t\tif (!t) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\thdr = (alloc_hdr *) t;\n\t\t\ttotal_allocated -= old_size;\n\t\t\ttotal_allocated += size;\n\t\t\thdr->u.sz = size;\n\t\t\tsandbox_dump_memstate();\n\t\t\treturn (void *) (hdr + 1);\n\t\t}\n\t} else {\n\t\tif (size == 0) {\n\t\t\treturn NULL;\n\t\t} else {\n\t\t\tif (total_allocated + size > max_allocated) {\n\t\t\t\tfprintf(stderr, \"Sandbox maximum allocation size reached, %ld requested in sandbox_realloc\\n\",\n\t\t\t\t        (long) size);\n\t\t\t\tfflush(stderr);\n\t\t\t\treturn NULL;\n\t\t\t}\n\n\t\t\thdr = (alloc_hdr *) malloc(size + sizeof(alloc_hdr));\n\t\t\tif (!hdr) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\thdr->u.sz = size;\n\t\t\ttotal_allocated += size;\n\t\t\tsandbox_dump_memstate();\n\t\t\treturn (void *) (hdr + 1);\n\t\t}\n\t}\n}\n\nstatic void sandbox_free(void *udata, void *ptr) {\n\talloc_hdr *hdr;\n\n\t(void) udata;  /* Suppress warning. */\n\n\tif (!ptr) {\n\t\treturn;\n\t}\n\thdr = (alloc_hdr *) (((char *) ptr) - sizeof(alloc_hdr));\n\ttotal_allocated -= hdr->u.sz;\n\tfree((void *) hdr);\n\tsandbox_dump_memstate();\n}\n\n/*\n *  Sandbox setup and test\n */\n\nstatic duk_ret_t duk__print(duk_context *ctx) {\n\tduk_push_string(ctx, \" \");\n\tduk_insert(ctx, 0);\n\tduk_join(ctx, duk_get_top(ctx) - 1);\n\tprintf(\"%s\\n\", duk_safe_to_string(ctx, -1));\n\treturn 0;\n}\n\nstatic duk_ret_t do_sandbox_test(duk_context *ctx, void *udata) {\n\tFILE *f;\n\tchar buf[4096];\n\tsize_t ret;\n\tconst char *globobj;\n\n\t(void) udata;\n\n\t/*\n\t *  Setup sandbox\n\t */\n\n\t/* Minimal print() provider. */\n\tduk_push_c_function(ctx, duk__print, DUK_VARARGS);\n\tduk_put_global_string(ctx, \"print\");\n\n\tglobobj =\n\t\t\"({\\n\"\n\t\t\"    print: print,\\n\"\n\t\t\"    Math: {\\n\"\n\t\t\"        max: Math.max\\n\"\n\t\t\"    }\\n\"\n\t\t\"})\\n\";\n#if 1\n\tfprintf(stderr, \"Sandbox global object:\\n----------------\\n%s----------------\\n\", globobj);\n\tfflush(stderr);\n#endif\n\tduk_eval_string(ctx, globobj);\n\tduk_set_global_object(ctx);\n\n\t/*\n\t *  Execute code from specified file\n\t */\n\n\tf = fopen(duk_require_string(ctx, -1), \"rb\");\n\tif (!f) {\n\t\tduk_error(ctx, DUK_ERR_ERROR, \"failed to open file\");\n\t}\n\n\tfor (;;) {\n\t\tif (ferror(f)) {\n\t\t\tfclose(f);\n\t\t\tduk_error(ctx, DUK_ERR_ERROR, \"ferror when reading file\");\n\t\t}\n\t\tif (feof(f)) {\n\t\t\tbreak;\n\t\t}\n\n\t\tret = fread(buf, 1, sizeof(buf), f);\n\t\tif (ret == 0) {\n\t\t\tbreak;\n\t\t}\n\n\t\tduk_push_lstring(ctx, (const char *) buf, ret);\n\t}\n\n\tduk_concat(ctx, duk_get_top(ctx) - 1);  /* -1 for filename */\n\n\t/* -> [ ... filename source ] */\n\n\tduk_insert(ctx, -2);\n\n\t/* -> [ ... source filename ] */\n\n\tduk_compile(ctx, 0 /*flags*/);  /* Compile as program */\n\tduk_call(ctx, 0 /*nargs*/);\n\n\treturn 0;\n}\n\n/*\n *  Main\n */\n\nstatic void sandbox_fatal(void *udata, const char *msg) {\n\t(void) udata;  /* Suppress warning. */\n\tfprintf(stderr, \"FATAL: %s\\n\", (msg ? msg : \"no message\"));\n\tfflush(stderr);\n\texit(1);  /* must not return */\n}\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx;\n\tduk_int_t rc;\n\n\tif (argc < 2) {\n\t\tfprintf(stderr, \"Usage: sandbox <test.js>\\n\");\n\t\tfflush(stderr);\n\t\texit(1);\n\t}\n\n\tctx = duk_create_heap(sandbox_alloc,\n\t                      sandbox_realloc,\n\t                      sandbox_free,\n\t                      NULL,\n\t                      sandbox_fatal);\n\n\tduk_push_string(ctx, argv[1]);\n\trc = duk_safe_call(ctx, do_sandbox_test, NULL, 1 /*nargs*/, 1 /*nrets*/);\n\tif (rc) {\n\t\tfprintf(stderr, \"ERROR: %s\\n\", duk_safe_to_string(ctx, -1));\n\t\tfflush(stderr);\n\t}\n\n\tduk_destroy_heap(ctx);\n\n\t/* Should be zero. */\n\tfprintf(stderr, \"Final allocation: %ld\\n\", (long) total_allocated);\n\tfflush(stderr);\n\n\treturn 1;\n}\n"
  },
  {
    "path": "react_juce/duktape/extras/README.rst",
    "content": "==============\nDuktape extras\n==============\n\nExtra modules and utilities.  Extras provide functionality that doesn't\ncomfortably fit into the main Duktape library, perhaps for footprint or\nportability reasons, but are still useful for most users.\n\nExtras are maintained and will be bug fixed.  However, they don't have the\nsame semantic versioning guarantees like the main Duktape library.  Extras\nmay be dropped without warning as Duktape is versioned.  For instance, if\nan extra breaks due to Duktape changes and there is no time to fix it, the\nmissing extra won't block a release and will be dropped.\n"
  },
  {
    "path": "react_juce/duktape/extras/alloc-pool/Makefile",
    "content": "# For manual testing; say 'make' in extras/alloc-pool and run ./test.\n\nCC = gcc\nDEFS =\n#DEFS += '-DDUK_ALLOC_POOL_DEBUG'\n\n.PHONY: test\ntest:\n\trm -rf ./prep\n\techo 'DUK_USE_FATAL_HANDLER:' > opts.yaml\n\techo '  verbatim: \"#define DUK_USE_FATAL_HANDLER(udata,msg) my_fatal((msg))\"' >> opts.yaml\n\tpython2 ../../tools/configure.py \\\n\t\t--output-directory ./prep \\\n\t\t--option-file ./opts.yaml \\\n\t\t--fixup-line 'extern void my_fatal(const char *msg);'\n\t$(CC) -std=c99 -Wall -Wextra -m32 -Os -otest \\\n\t\t-I./prep ./prep/duktape.c \\\n\t\t$(DEFS) \\\n\t\tduk_alloc_pool.c test.c \\\n\t\t-lm\n\t./test 'print(\"foo\", \"bar\", 1, 2, 3)'\n\t./test 'alert(\"foo\", \"bar\", 1, 2, 3)'\n\n.PHONY: ptrcomptest\nptrcomptest:\n\trm -rf ./prep\n\techo 'DUK_USE_FATAL_HANDLER:' > opts.yaml\n\techo '  verbatim: \"#define DUK_USE_FATAL_HANDLER(udata,msg) my_fatal((msg))\"' >> opts.yaml\n\tpython2 ../../tools/configure.py \\\n\t\t--output-directory ./prep \\\n\t\t--option-file ./opts.yaml \\\n\t\t--fixup-line 'extern void my_fatal(const char *msg);' \\\n\t\t--option-file ../../config/examples/low_memory.yaml \\\n\t\t--option-file ptrcomp.yaml \\\n\t\t--fixup-file ptrcomp_fixup.h\n\t$(CC) -std=c99 -Wall -Wextra -m32 -Os -optrcomptest \\\n\t\t-I. -I./prep ./prep/duktape.c \\\n\t\t$(DEFS) \\\n\t\tduk_alloc_pool.c test.c \\\n\t\t-lm\n\t./ptrcomptest 'print(\"foo\", \"bar\", 1, 2, 3)'\n\t./ptrcomptest 'alert(\"foo\", \"bar\", 1, 2, 3)'\n"
  },
  {
    "path": "react_juce/duktape/extras/alloc-pool/README.rst",
    "content": "=====================================\nPool allocator for low memory targets\n=====================================\n\nA simple pool allocator which satisfies allocations from preallocated pools\ncontaining blocks of a certain size.  The caller provides a continuous memory\nregion and a pool configuration when initializing the allocator.\n\nThe pool configuration specifies the block sizes used, and parameters to\ncontrol how many entries are allocated for each block size.  The parameters\nare specified with respect to an arbitrary floating point scaling parameter\n``t`` as follows::\n\n    bytes = A*t + B\n    count = floor(bytes / block_size)\n          = floor((A*t + B) / block_size)\n\n    A: constant which indicates how quickly more bytes are assigned for this\n       block size as the total allocation grows\n\n    B: constant which indicates the base allocation for this block size, i.e.\n       the allocated needed by Duktape initialization\n\nPool initialization finds the largest floating point ``t`` which still fits in\nthe memory region provided.  Any leftover bytes are sprinkled to the pools to\nminimize wasted space.\n\nA pool configuration can be written manually (by trial and error) or using\nsome automatic tooling such as ``pool_simulator.py``.\n\nWhen using pointer compression only a single global pool is supported.  This\nreduces code footprint and is usually sufficient in low memory targets.\n\nPointer compression functions are defined as inline functions in\n``duk_alloc_pool.h`` to allow the compiler to inline pointer compression when\nappropriate.  As a side effect ``duk_config.h`` must include\n``duk_alloc_pool.h`` so that the declarations are visible when compiling\nDuktape.\n"
  },
  {
    "path": "react_juce/duktape/extras/alloc-pool/duk_alloc_pool.c",
    "content": "/*\n *  Pool allocator for low memory targets.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdint.h>\n#include <stdarg.h>\n#include \"duktape.h\"\n#include \"duk_alloc_pool.h\"\n\n/* Define to enable some debug printfs. */\n/* #define DUK_ALLOC_POOL_DEBUG */\n\n/* Define to enable approximate waste tracking. */\n/* #define DUK_ALLOC_POOL_TRACK_WASTE */\n\n/* Define to track global highwater for used and waste bytes.  VERY SLOW, only\n * useful for manual testing.\n */\n/* #define DUK_ALLOC_POOL_TRACK_HIGHWATER */\n\n#if defined(DUK_ALLOC_POOL_ROMPTR_COMPRESSION)\n#if 0  /* This extern declaration is provided by duktape.h, array provided by duktape.c. */\nextern const void * const duk_rom_compressed_pointers[];\n#endif\nconst void *duk_alloc_pool_romptr_low = NULL;\nconst void *duk_alloc_pool_romptr_high = NULL;\nstatic void duk__alloc_pool_romptr_init(void);\n#endif\n\n#if defined(DUK_USE_HEAPPTR16)\nvoid *duk_alloc_pool_ptrcomp_base = NULL;\n#endif\n\n#if defined(DUK_ALLOC_POOL_DEBUG)\nstatic void duk__alloc_pool_dprintf(const char *fmt, ...) {\n\tva_list ap;\n\tva_start(ap, fmt);\n\tvfprintf(stderr, fmt, ap);\n\tva_end(ap);\n}\n#endif\n\n/*\n *  Pool initialization\n */\n\nvoid *duk_alloc_pool_init(char *buffer,\n                          size_t size,\n                          const duk_pool_config *configs,\n                          duk_pool_state *states,\n                          int num_pools,\n                          duk_pool_global *global) {\n\tdouble t_min, t_max, t_curr, x;\n\tint step, i, j, n;\n\tsize_t total;\n\tchar *p;\n\n\t/* XXX: check that 'size' is not too large when using pointer\n\t * compression.\n\t */\n\n\t/* To optimize pool counts first come up with a 't' which still allows\n\t * total pool size to fit within user provided region.  After that\n\t * sprinkle any remaining bytes to the counts.  Binary search with a\n\t * fixed step count; last round uses 't_min' as 't_curr' to ensure it\n\t * succeeds.\n\t */\n\n\tt_min = 0.0;  /* Unless config is insane, this should always be \"good\". */\n\tt_max = 1e6;\n\n\tfor (step = 0; ; step++) {\n\t\tif (step >= 100) {\n\t\t\t/* Force \"known good\", rerun config, and break out.\n\t\t\t * Deals with rounding corner cases where t_curr is\n\t\t\t * persistently \"bad\" even though t_min is a valid\n\t\t\t * solution.\n\t\t\t */\n\t\t\tt_curr = t_min;\n\t\t} else {\n\t\t\tt_curr = (t_min + t_max) / 2.0;\n\t\t}\n\n\t\tfor (i = 0, total = 0; i < num_pools; i++) {\n\t\t\tstates[i].size = configs[i].size;\n\n\t\t\t/* Target bytes = A*t + B ==> target count = (A*t + B) / block_size.\n\t\t\t * Rely on A and B being small enough so that 'x' won't wrap.\n\t\t\t */\n\t\t\tx = ((double) configs[i].a * t_curr + (double) configs[i].b) / (double) configs[i].size;\n\n\t\t\tstates[i].count = (unsigned int) x;\n\t\t\ttotal += (size_t) states[i].size * (size_t) states[i].count;\n\t\t\tif (total > size) {\n\t\t\t\tgoto bad;\n\t\t\t}\n\t\t}\n\n\t\t/* t_curr is good. */\n#if defined(DUK_ALLOC_POOL_DEBUG)\n\t\tduk__alloc_pool_dprintf(\"duk_alloc_pool_init: step=%d, t=[%lf %lf %lf] -> total %ld/%ld (good)\\n\",\n\t\t                        step, t_min, t_curr, t_max, (long) total, (long) size);\n#endif\n\t\tif (step >= 100) {\n\t\t\t/* Keep state[] initialization state.  The state was\n\t\t\t * created using the highest 't_min'.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\t\tt_min = t_curr;\n\t\tcontinue;\n\n\t bad:\n\t\t/* t_curr is bad. */\n#if defined(DUK_ALLOC_POOL_DEBUG)\n\t\tduk__alloc_pool_dprintf(\"duk_alloc_pool_init: step=%d, t=[%lf %lf %lf] -> total %ld/%ld (bad)\\n\",\n\t\t                        step, t_min, t_curr, t_max, (long) total, (long) size);\n#endif\n\n\t\tif (step >= 1000) {\n\t\t\t/* Cannot find any good solution; shouldn't happen\n\t\t\t * unless config is bad or 'size' is so small that\n\t\t\t * even a baseline allocation won't fit.\n\t\t\t */\n\t\t\treturn NULL;\n\t\t}\n\t\tt_max = t_curr;\n\t\t/* continue */\n\t}\n\n\t/* The base configuration is now good; sprinkle any leftovers to\n\t * pools in descending order.  Note that for good t_curr, 'total'\n\t * indicates allocated bytes so far and 'size - total' indicates\n\t * leftovers.\n\t */\n\tfor (i = num_pools - 1; i >= 0; i--) {\n\t\twhile (size - total >= states[i].size) {\n\t\t\t/* Ignore potential wrapping of states[i].count as the count\n\t\t\t * is 32 bits and shouldn't wrap in practice.\n\t\t\t */\n\t\t\tstates[i].count++;\n\t\t\ttotal += states[i].size;\n#if defined(DUK_ALLOC_POOL_DEBUG)\n\t\t\tduk__alloc_pool_dprintf(\"duk_alloc_pool_init: sprinkle %ld bytes (%ld left after) to pool index %ld, new count %ld\\n\",\n\t\t\t                        (long) states[i].size, (long) (size - total), (long) i, (long) states[i].count);\n#endif\n\t\t}\n\t}\n\n\t/* Pool counts are final.  Allocate the user supplied region based\n\t * on the final counts, initialize free lists for each block size,\n\t * and otherwise finalize 'state' for use.\n\t */\n\tp = buffer;\n\tglobal->num_pools = num_pools;\n\tglobal->states = states;\n#if defined(DUK_ALLOC_POOL_TRACK_HIGHWATER)\n#if defined(DUK_ALLOC_POOL_DEBUG)\n\tduk__alloc_pool_dprintf(\"duk_alloc_pool_init: global highwater mark tracking enabled, THIS IS VERY SLOW!\\n\");\n#endif\n\tglobal->hwm_used_bytes = 0U;\n\tglobal->hwm_waste_bytes = 0U;\n#endif\n#if defined(DUK_ALLOC_POOL_TRACK_WASTE)\n#if defined(DUK_ALLOC_POOL_DEBUG)\n\tduk__alloc_pool_dprintf(\"duk_alloc_pool_init: approximate waste tracking enabled\\n\");\n#endif\n#endif\n\n#if defined(DUK_USE_HEAPPTR16)\n\t/* Register global base value for pointer compression, assumes\n\t * a single active pool  -4 allows a single subtract to be used and\n\t * still ensures no non-NULL pointer encodes to zero.\n\t */\n\tduk_alloc_pool_ptrcomp_base = (void *) (p - 4);\n#endif\n\n\tfor (i = 0; i < num_pools; i++) {\n\t\tn = (int) states[i].count;\n\t\tif (n > 0) {\n\t\t\tstates[i].first = (duk_pool_free *) p;\n\t\t\tfor (j = 0; j < n; j++) {\n\t\t\t\tchar *p_next = p + states[i].size;\n\t\t\t\t((duk_pool_free *) p)->next =\n\t\t\t\t\t(j == n - 1) ? (duk_pool_free *) NULL : (duk_pool_free *) p_next;\n\t\t\t\tp = p_next;\n\t\t\t}\n\t\t} else {\n\t\t\tstates[i].first = (duk_pool_free *) NULL;\n\t\t}\n\t\tstates[i].alloc_end = p;\n#if defined(DUK_ALLOC_POOL_TRACK_HIGHWATER)\n\t\tstates[i].hwm_used_count = 0;\n#endif\n\t\t/* All members of 'state' now initialized. */\n\n#if defined(DUK_ALLOC_POOL_DEBUG)\n\t\tduk__alloc_pool_dprintf(\"duk_alloc_pool_init: block size %5ld, count %5ld, %8ld total bytes, \"\n\t\t                        \"end %p\\n\",\n\t\t                        (long) states[i].size, (long) states[i].count,\n\t\t                        (long) states[i].size * (long) states[i].count,\n\t\t                        (void *) states[i].alloc_end);\n#endif\n\t}\n\n#if defined(DUK_ALLOC_POOL_ROMPTR_COMPRESSION)\n\t/* ROM pointer compression precomputation.  Assumes a single active\n\t * pool.\n\t */\n\tduk__alloc_pool_romptr_init();\n#endif\n\n\t/* Use 'global' as udata. */\n\treturn (void *) global;\n}\n\n/*\n *  Misc helpers\n */\n\n#if defined(DUK_ALLOC_POOL_TRACK_WASTE)\nstatic void duk__alloc_pool_set_waste_marker(void *ptr, size_t used, size_t size) {\n\t/* Rely on the base pointer and size being divisible by 4 and thus\n\t * aligned.  Use 32-bit markers: a 4-byte resolution is good enough,\n\t * and comparing 32 bits at a time makes false waste estimates less\n\t * likely than when comparing as bytes.\n\t */\n\tduk_uint32_t *p, *p_start, *p_end;\n\tsize_t used_round;\n\n\tused_round = (used + 3U) & ~0x03U;  /* round up to 4 */\n\tp_end = (duk_uint32_t *) ((duk_uint8_t *) ptr + size);\n\tp_start = (duk_uint32_t *) ((duk_uint8_t *) ptr + used_round);\n\tp = (duk_uint32_t *) p_start;\n\twhile (p != p_end) {\n\t\t*p++ = DUK_ALLOC_POOL_WASTE_MARKER;\n\t}\n}\n#else  /* DUK_ALLOC_POOL_TRACK_WASTE */\nstatic void duk__alloc_pool_set_waste_marker(void *ptr, size_t used, size_t size) {\n\t(void) ptr; (void) used; (void) size;\n}\n#endif  /* DUK_ALLOC_POOL_TRACK_WASTE */\n\n#if defined(DUK_ALLOC_POOL_TRACK_WASTE)\nstatic size_t duk__alloc_pool_get_waste_estimate(void *ptr, size_t size) {\n\tduk_uint32_t *p, *p_end, *p_start;\n\n\t/* Assumes size is >= 4. */\n\tp_start = (duk_uint32_t *) ptr;\n\tp_end = (duk_uint32_t *) ((duk_uint8_t *) ptr + size);\n\tp = p_end;\n\n\t/* This scan may cause harmless valgrind complaints: there may be\n\t * uninitialized bytes within the legitimate allocation or between\n\t * the start of the waste marker and the end of the allocation.\n\t */\n\tdo {\n\t\tp--;\n\t\tif (*p == DUK_ALLOC_POOL_WASTE_MARKER) {\n\t\t\t;\n\t\t} else {\n\t\t\treturn (size_t) (p_end - p - 1) * 4U;\n\t\t}\n\t} while (p != p_start);\n\n\treturn size;\n}\n#else  /* DUK_ALLOC_POOL_TRACK_WASTE */\nstatic size_t duk__alloc_pool_get_waste_estimate(void *ptr, size_t size) {\n\t(void) ptr; (void) size;\n\treturn 0;\n}\n#endif  /* DUK_ALLOC_POOL_TRACK_WASTE */\n\nstatic int duk__alloc_pool_ptr_in_freelist(duk_pool_state *s, void *ptr) {\n\tduk_pool_free *curr;\n\n\tfor (curr = s->first; curr != NULL; curr = curr->next) {\n\t\tif ((void *) curr == ptr) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n}\n\nvoid duk_alloc_pool_get_pool_stats(duk_pool_state *s, duk_pool_stats *res) {\n\tvoid *curr;\n\tsize_t free_count;\n\tsize_t used_count;\n\tsize_t waste_bytes;\n\n\tcurr = s->alloc_end - (s->size * s->count);\n\tfree_count = 0U;\n\twaste_bytes = 0U;\n\twhile (curr != s->alloc_end) {\n\t\tif (duk__alloc_pool_ptr_in_freelist(s, curr)) {\n\t\t\tfree_count++;\n\t\t} else {\n\t\t\twaste_bytes += duk__alloc_pool_get_waste_estimate(curr, s->size);\n\t\t}\n\t\tcurr = curr + s->size;\n\t}\n\tused_count = (size_t) (s->count - free_count);\n\n\tres->used_count = used_count;\n\tres->used_bytes = (size_t) (used_count * s->size);\n\tres->free_count = free_count;\n\tres->free_bytes = (size_t) (free_count * s->size);\n\tres->waste_bytes = waste_bytes;\n#if defined(DUK_ALLOC_POOL_TRACK_HIGHWATER)\n\tres->hwm_used_count = s->hwm_used_count;\n#else\n\tres->hwm_used_count = 0U;\n#endif\n}\n\nvoid duk_alloc_pool_get_global_stats(duk_pool_global *g, duk_pool_global_stats *res) {\n\tint i;\n\tsize_t total_used = 0U;\n\tsize_t total_free = 0U;\n\tsize_t total_waste = 0U;\n\n\tfor (i = 0; i < g->num_pools; i++) {\n\t\tduk_pool_state *s = &g->states[i];\n\t\tduk_pool_stats stats;\n\n\t\tduk_alloc_pool_get_pool_stats(s, &stats);\n\n\t\ttotal_used += stats.used_bytes;\n\t\ttotal_free += stats.free_bytes;\n\t\ttotal_waste += stats.waste_bytes;\n\t}\n\n\tres->used_bytes = total_used;\n\tres->free_bytes = total_free;\n\tres->waste_bytes = total_waste;\n#if defined(DUK_ALLOC_POOL_TRACK_HIGHWATER)\n\tres->hwm_used_bytes = g->hwm_used_bytes;\n\tres->hwm_waste_bytes = g->hwm_waste_bytes;\n#else\n\tres->hwm_used_bytes = 0U;\n\tres->hwm_waste_bytes = 0U;\n#endif\n}\n\n#if defined(DUK_ALLOC_POOL_TRACK_HIGHWATER)\nstatic void duk__alloc_pool_update_highwater(duk_pool_global *g) {\n\tint i;\n\tsize_t total_used = 0U;\n\tsize_t total_free = 0U;\n\tsize_t total_waste = 0U;\n\n\t/* Per pool highwater used count, useful to checking if a pool is\n\t * too small.\n\t */\n\tfor (i = 0; i < g->num_pools; i++) {\n\t\tduk_pool_state *s = &g->states[i];\n\t\tduk_pool_stats stats;\n\n\t\tduk_alloc_pool_get_pool_stats(s, &stats);\n\t\tif (stats.used_count > s->hwm_used_count) {\n#if defined(DUK_ALLOC_POOL_DEBUG)\n\t\t\tduk__alloc_pool_dprintf(\"duk__alloc_pool_update_highwater: pool %ld (%ld bytes) highwater updated: count %ld -> %ld\\n\",\n\t\t\t                        (long) i, (long) s->size,\n\t\t\t                        (long) s->hwm_used_count, (long) stats.used_count);\n#endif\n\t\t\ts->hwm_used_count = stats.used_count;\n\t\t}\n\n\t\ttotal_used += stats.used_bytes;\n\t\ttotal_free += stats.free_bytes;\n\t\ttotal_waste += stats.waste_bytes;\n\t}\n\n\t/* Global highwater mark for used and waste bytes.  Both fields are\n\t * updated from the same snapshot based on highest used count.\n\t * This is VERY, VERY slow and only useful for development.\n\t * (Note that updating HWM states for pools individually and then\n\t * summing them won't create a consistent global snapshot.  There\n\t * are still easy ways to make this much, much faster.)\n\t */\n\tif (total_used > g->hwm_used_bytes) {\n#if defined(DUK_ALLOC_POOL_DEBUG)\n\t\tduk__alloc_pool_dprintf(\"duk__alloc_pool_update_highwater: global highwater updated: used=%ld, bytes=%ld -> \"\n\t\t                        \"used=%ld, bytes=%ld\\n\",\n\t\t                        (long) g->hwm_used_bytes, (long) g->hwm_waste_bytes,\n\t\t                        (long) total_used, (long) total_waste);\n#endif\n\t\tg->hwm_used_bytes = total_used;\n\t\tg->hwm_waste_bytes = total_waste;\n\t}\n}\n#else  /* DUK_ALLOC_POOL_TRACK_HIGHWATER */\nstatic void duk__alloc_pool_update_highwater(duk_pool_global *g) {\n\t(void) g;\n}\n#endif  /* DUK_ALLOC_POOL_TRACK_HIGHWATER */\n\n/*\n *  Allocation providers\n */\n\nvoid *duk_alloc_pool(void *udata, duk_size_t size) {\n\tduk_pool_global *g = (duk_pool_global *) udata;\n\tint i, n;\n\n#if defined(DUK_ALLOC_POOL_DEBUG)\n\tduk__alloc_pool_dprintf(\"duk_alloc_pool: %p %ld\\n\", udata, (long) size);\n#endif\n\n\tif (size == 0) {\n\t\treturn NULL;\n\t}\n\n\tfor (i = 0, n = g->num_pools; i < n; i++) {\n\t\tduk_pool_state *st = g->states + i;\n\n\t\tif (size <= st->size) {\n\t\t\tduk_pool_free *res = st->first;\n\t\t\tif (res != NULL) {\n\t\t\t\tst->first = res->next;\n\t\t\t\tduk__alloc_pool_set_waste_marker((void *) res, size, st->size);\n\t\t\t\tduk__alloc_pool_update_highwater(g);\n\t\t\t\treturn (void *) res;\n\t\t\t}\n\t\t}\n\n\t\t/* Allocation doesn't fit or no free entries, try to borrow\n\t\t * from the next block size.  There's no support for preventing\n\t\t * a borrow at present.\n\t\t */\n\t}\n\n\treturn NULL;\n}\n\nvoid *duk_realloc_pool(void *udata, void *ptr, duk_size_t size) {\n\tduk_pool_global *g = (duk_pool_global *) udata;\n\tint i, j, n;\n\n#if defined(DUK_ALLOC_POOL_DEBUG)\n\tduk__alloc_pool_dprintf(\"duk_realloc_pool: %p %p %ld\\n\", udata, ptr, (long) size);\n#endif\n\n\tif (ptr == NULL) {\n\t\treturn duk_alloc_pool(udata, size);\n\t}\n\tif (size == 0) {\n\t\tduk_free_pool(udata, ptr);\n\t\treturn NULL;\n\t}\n\n\t/* Non-NULL pointers are necessarily from the pool so we should\n\t * always be able to find the allocation.\n\t */\n\n\tfor (i = 0, n = g->num_pools; i < n; i++) {\n\t\tduk_pool_state *st = g->states + i;\n\t\tchar *new_ptr;\n\n\t\t/* Because 'ptr' is assumed to be in the pool and pools are\n\t\t * allocated in sequence, it suffices to check for end pointer\n\t\t * only.\n\t\t */\n\t\tif ((char *) ptr >= st->alloc_end) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (size <= st->size) {\n\t\t\t/* Allocation still fits existing allocation.  Check if\n\t\t\t * we can shrink the allocation to a smaller block size\n\t\t\t * (smallest possible).\n\t\t\t */\n\t\t\tfor (j = 0; j < i; j++) {\n\t\t\t\tduk_pool_state *st2 = g->states + j;\n\n\t\t\t\tif (size <= st2->size) {\n\t\t\t\t\tnew_ptr = (char *) st2->first;\n\t\t\t\t\tif (new_ptr != NULL) {\n#if defined(DUK_ALLOC_POOL_DEBUG)\n\t\t\t\t\t\tduk__alloc_pool_dprintf(\"duk_realloc_pool: shrink, block size %ld -> %ld\\n\",\n\t\t\t\t\t\t                        (long) st->size, (long) st2->size);\n#endif\n\t\t\t\t\t\tst2->first = ((duk_pool_free *) new_ptr)->next;\n\t\t\t\t\t\tmemcpy((void *) new_ptr, (const void *) ptr, (size_t) size);\n\t\t\t\t\t\t((duk_pool_free *) ptr)->next = st->first;\n\t\t\t\t\t\tst->first = (duk_pool_free *) ptr;\n\t\t\t\t\t\tduk__alloc_pool_set_waste_marker((void *) new_ptr, size, st2->size);\n\t\t\t\t\t\tduk__alloc_pool_update_highwater(g);\n\t\t\t\t\t\treturn (void *) new_ptr;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* Failed to shrink; return existing pointer. */\n\t\t\tduk__alloc_pool_set_waste_marker((void *) ptr, size, st->size);\n\t\t\treturn ptr;\n\t\t}\n\n\t\t/* Find first free larger block. */\n\t\tfor (j = i + 1; j < n; j++) {\n\t\t\tduk_pool_state *st2 = g->states + j;\n\n\t\t\tif (size <= st2->size) {\n\t\t\t\tnew_ptr = (char *) st2->first;\n\t\t\t\tif (new_ptr != NULL) {\n\t\t\t\t\tst2->first = ((duk_pool_free *) new_ptr)->next;\n\t\t\t\t\tmemcpy((void *) new_ptr, (const void *) ptr, (size_t) st->size);\n\t\t\t\t\t((duk_pool_free *) ptr)->next = st->first;\n\t\t\t\t\tst->first = (duk_pool_free *) ptr;\n\t\t\t\t\tduk__alloc_pool_set_waste_marker((void *) new_ptr, size, st2->size);\n\t\t\t\t\tduk__alloc_pool_update_highwater(g);\n\t\t\t\t\treturn (void *) new_ptr;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/* Failed to resize. */\n\t\treturn NULL;\n\t}\n\n\t/* We should never be here because 'ptr' should be a valid pool\n\t * entry and thus always found above.\n\t */\n\treturn NULL;\n}\n\nvoid duk_free_pool(void *udata, void *ptr) {\n\tduk_pool_global *g = (duk_pool_global *) udata;\n\tint i, n;\n\n#if defined(DUK_ALLOC_POOL_DEBUG)\n\tduk__alloc_pool_dprintf(\"duk_free_pool: %p %p\\n\", udata, ptr);\n#endif\n\n\tif (ptr == NULL) {\n\t\treturn;\n\t}\n\n\tfor (i = 0, n = g->num_pools; i < n; i++) {\n\t\tduk_pool_state *st = g->states + i;\n\n\t\t/* Enough to check end address only. */\n\t\tif ((char *) ptr >= st->alloc_end) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t((duk_pool_free *) ptr)->next = st->first;\n\t\tst->first = (duk_pool_free *) ptr;\n#if 0  /* never necessary when freeing */\n\t\tduk__alloc_pool_update_highwater(g);\n#endif\n\t\treturn;\n\t}\n\n\t/* We should never be here because 'ptr' should be a valid pool\n\t * entry and thus always found above.\n\t */\n}\n\n/*\n *  Pointer compression\n */\n\n#if defined(DUK_ALLOC_POOL_ROMPTR_COMPRESSION)\nstatic void duk__alloc_pool_romptr_init(void) {\n\t/* Scan ROM pointer range for faster detection of \"is 'p' a ROM pointer\"\n\t * later on.\n\t */\n\tconst void * const * ptrs = (const void * const *) duk_rom_compressed_pointers;\n\tduk_alloc_pool_romptr_low = duk_alloc_pool_romptr_high = (const void *) *ptrs;\n\twhile (*ptrs) {\n\t\tif (*ptrs > duk_alloc_pool_romptr_high) {\n\t\t\tduk_alloc_pool_romptr_high = (const void *) *ptrs;\n\t\t}\n\t\tif (*ptrs < duk_alloc_pool_romptr_low) {\n\t\t\tduk_alloc_pool_romptr_low = (const void *) *ptrs;\n\t\t}\n\t\tptrs++;\n\t}\n}\n#endif\n\n/* Encode/decode functions are defined in the header to allow inlining. */\n\n#if defined(DUK_ALLOC_POOL_ROMPTR_COMPRESSION)\nduk_uint16_t duk_alloc_pool_enc16_rom(void *ptr) {\n\t/* The if-condition should be the fastest possible check\n\t * for \"is 'ptr' in ROM?\".  If pointer is in ROM, we'd like\n\t * to compress it quickly.  Here we just scan a ~1K array\n\t * which is very bad for performance.\n\t */\n\tconst void * const * ptrs = duk_rom_compressed_pointers;\n\twhile (*ptrs) {\n\t\tif (*ptrs == ptr) {\n\t\t\treturn DUK_ALLOC_POOL_ROMPTR_FIRST + (duk_uint16_t) (ptrs - duk_rom_compressed_pointers);\n\t\t}\n\t\tptrs++;\n\t}\n\n\t/* We should really never be here: Duktape should only be\n\t * compressing pointers which are in the ROM compressed\n\t * pointers list, which are known at 'make dist' time.\n\t * We go on, causing a pointer compression error.\n\t */\n\treturn 0;\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/extras/alloc-pool/duk_alloc_pool.h",
    "content": "#if !defined(DUK_ALLOC_POOL_H_INCLUDED)\n#define DUK_ALLOC_POOL_H_INCLUDED\n\n#include \"duktape.h\"\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/* 32-bit (big endian) marker used at the end of pool entries so that wasted\n * space can be detected.  Waste tracking must be enabled explicitly.\n */\n#if defined(DUK_ALLOC_POOL_TRACK_WASTE)\n#define DUK_ALLOC_POOL_WASTE_MARKER  0xedcb2345UL\n#endif\n\n/* Pointer compression with ROM strings/objects:\n *\n * For now, use DUK_USE_ROM_OBJECTS to signal the need for compressed ROM\n * pointers.  DUK_USE_ROM_PTRCOMP_FIRST is provided for the ROM pointer\n * compression range minimum to avoid duplication in user code.\n */\n#if defined(DUK_USE_ROM_OBJECTS) && defined(DUK_USE_HEAPPTR16)\n#define DUK_ALLOC_POOL_ROMPTR_COMPRESSION\n#define DUK_ALLOC_POOL_ROMPTR_FIRST DUK_USE_ROM_PTRCOMP_FIRST\n\n/* This extern declaration is provided by duktape.h, array provided by duktape.c.\n * Because duk_config.h may include this file (to get the inline functions) we\n * need to forward declare this also here.\n */\nextern const void * const duk_rom_compressed_pointers[];\n#endif\n\n/* Pool configuration for a certain block size. */\ntypedef struct {\n\tunsigned int size;  /* must be divisible by 4 and >= sizeof(void *) */\n\tunsigned int a;     /* bytes (not count) to allocate: a*t + b, t is an arbitrary scale parameter */\n\tunsigned int b;\n} duk_pool_config;\n\n/* Freelist entry, must fit into the smallest block size. */\nstruct duk_pool_free;\ntypedef struct duk_pool_free duk_pool_free;\nstruct duk_pool_free {\n\tduk_pool_free *next;\n};\n\n/* Pool state for a certain block size. */\ntypedef struct {\n\tduk_pool_free *first;\n\tchar *alloc_end;\n\tunsigned int size;\n\tunsigned int count;\n#if defined(DUK_ALLOC_POOL_TRACK_HIGHWATER)\n\tunsigned int hwm_used_count;\n#endif\n} duk_pool_state;\n\n/* Statistics for a certain pool. */\ntypedef struct {\n\tsize_t used_count;\n\tsize_t used_bytes;\n\tsize_t free_count;\n\tsize_t free_bytes;\n\tsize_t waste_bytes;\n\tsize_t hwm_used_count;\n} duk_pool_stats;\n\n/* Top level state for all pools.  Pointer to this struct is used as the allocator\n * userdata pointer.\n */\ntypedef struct {\n\tint num_pools;\n\tduk_pool_state *states;\n#if defined(DUK_ALLOC_POOL_TRACK_HIGHWATER)\n\tsize_t hwm_used_bytes;\n\tsize_t hwm_waste_bytes;\n#endif\n} duk_pool_global;\n\n/* Statistics for the entire set of pools. */\ntypedef struct {\n\tsize_t used_bytes;\n\tsize_t free_bytes;\n\tsize_t waste_bytes;\n\tsize_t hwm_used_bytes;\n\tsize_t hwm_waste_bytes;\n} duk_pool_global_stats;\n\n/* Initialize a pool allocator, arguments:\n *   - buffer and size: continuous region to use for pool, must align to 4\n *   - config: configuration for pools in ascending block size\n *   - state: state for pools, matches config order\n *   - num_pools: number of entries in 'config' and 'state'\n *   - global: global state structure\n *\n * The 'config', 'state', and 'global' pointers must be valid beyond the init\n * call, as long as the pool is used.\n *\n * Returns a void pointer to be used as userdata for the allocator functions.\n * Concretely the return value will be \"(void *) global\", i.e. the global\n * state struct.  If pool init fails, the return value will be NULL.\n */\nvoid *duk_alloc_pool_init(char *buffer,\n                          size_t size,\n                          const duk_pool_config *configs,\n                          duk_pool_state *states,\n                          int num_pools,\n                          duk_pool_global *global);\n\n/* Duktape allocation providers.  Typing matches Duktape requirements. */\nvoid *duk_alloc_pool(void *udata, duk_size_t size);\nvoid *duk_realloc_pool(void *udata, void *ptr, duk_size_t size);\nvoid duk_free_pool(void *udata, void *ptr);\n\n/* Stats. */\nvoid duk_alloc_pool_get_pool_stats(duk_pool_state *s, duk_pool_stats *res);\nvoid duk_alloc_pool_get_global_stats(duk_pool_global *g, duk_pool_global_stats *res);\n\n/* Duktape pointer compression global state (assumes single pool). */\n#if defined(DUK_USE_ROM_OBJECTS) && defined(DUK_USE_HEAPPTR16)\nextern const void *duk_alloc_pool_romptr_low;\nextern const void *duk_alloc_pool_romptr_high;\nduk_uint16_t duk_alloc_pool_enc16_rom(void *ptr);\n#endif\n#if defined(DUK_USE_HEAPPTR16)\nextern void *duk_alloc_pool_ptrcomp_base;\n#endif\n\n#if 0\nduk_uint16_t duk_alloc_pool_enc16(void *ptr);\nvoid *duk_alloc_pool_dec16(duk_uint16_t val);\n#endif\n\n/* Inlined pointer compression functions.  Gcc and clang -Os won't in\n * practice inline these without an \"always inline\" attribute because it's\n * more size efficient (by a few kB) to use explicit calls instead.  Having\n * these defined inline here allows performance optimized builds to inline\n * pointer compression operations.\n *\n * Pointer compression assumes there's a single globally registered memory\n * pool which makes pointer compression more efficient.  This would be easy\n * to fix by adding a userdata pointer to the compression functions and\n * plumbing the heap userdata from the compression/decompression macros.\n */\n\n/* DUK_ALWAYS_INLINE is not a public API symbol so it may go away in even a\n * minor update.  But it's pragmatic for this extra because it handles many\n * compilers via duk_config.h detection.  Check that the macro exists so that\n * if it's gone, we can still compile.\n */\n#if defined(DUK_ALWAYS_INLINE)\n#define DUK__ALLOC_POOL_ALWAYS_INLINE DUK_ALWAYS_INLINE\n#else\n#define DUK__ALLOC_POOL_ALWAYS_INLINE /* nop */\n#endif\n\n#if defined(DUK_USE_HEAPPTR16)\nstatic DUK__ALLOC_POOL_ALWAYS_INLINE duk_uint16_t duk_alloc_pool_enc16(void *ptr) {\n\tif (ptr == NULL) {\n\t\t/* With 'return 0' gcc and clang -Os generate inefficient code.\n\t\t * For example, gcc -Os generates:\n\t\t *\n\t\t *   0804911d <duk_alloc_pool_enc16>:\n\t\t *    804911d:       55                      push   %ebp\n\t\t *    804911e:       85 c0                   test   %eax,%eax\n\t\t *    8049120:       89 e5                   mov    %esp,%ebp\n\t\t *    8049122:       74 0b                   je     804912f <duk_alloc_pool_enc16+0x12>\n\t\t *    8049124:       2b 05 e4 90 07 08       sub    0x80790e4,%eax\n\t\t *    804912a:       c1 e8 02                shr    $0x2,%eax\n\t\t *    804912d:       eb 02                   jmp    8049131 <duk_alloc_pool_enc16+0x14>\n\t\t *    804912f:       31 c0                   xor    %eax,%eax\n\t\t *    8049131:       5d                      pop    %ebp\n\t\t *    8049132:       c3                      ret\n\t\t *\n\t\t * The NULL path checks %eax for zero; if it is zero, a zero\n\t\t * is unnecessarily loaded into %eax again.  The non-zero path\n\t\t * has an unnecessary jump as a side effect of this.\n\t\t *\n\t\t * Using 'return (duk_uint16_t) (intptr_t) ptr;' generates similarly\n\t\t * inefficient code; not sure how to make the result better.\n\t\t */\n\t\treturn 0;\n\t}\n#if defined(DUK_ALLOC_POOL_ROMPTR_COMPRESSION)\n\tif (ptr >= duk_alloc_pool_romptr_low && ptr <= duk_alloc_pool_romptr_high) {\n\t\t/* This is complex enough now to need a separate function. */\n\t\treturn duk_alloc_pool_enc16_rom(ptr);\n\t}\n#endif\n\treturn (duk_uint16_t) (((size_t) ((char *) ptr - (char *) duk_alloc_pool_ptrcomp_base)) >> 2);\n}\n\nstatic DUK__ALLOC_POOL_ALWAYS_INLINE void *duk_alloc_pool_dec16(duk_uint16_t val) {\n\tif (val == 0) {\n\t\t/* As with enc16 the gcc and clang -Os output is inefficient,\n\t\t * e.g. gcc -Os:\n\t\t *\n\t\t *   08049133 <duk_alloc_pool_dec16>:\n\t\t *    8049133:       55                      push   %ebp\n\t\t *    8049134:       66 85 c0                test   %ax,%ax\n\t\t *    8049137:       89 e5                   mov    %esp,%ebp\n\t\t *    8049139:       74 0e                   je     8049149 <duk_alloc_pool_dec16+0x16>\n\t\t *    804913b:       8b 15 e4 90 07 08       mov    0x80790e4,%edx\n\t\t *    8049141:       0f b7 c0                movzwl %ax,%eax\n\t\t *    8049144:       8d 04 82                lea    (%edx,%eax,4),%eax\n\t\t *    8049147:       eb 02                   jmp    804914b <duk_alloc_pool_dec16+0x18>\n\t\t *    8049149:       31 c0                   xor    %eax,%eax\n\t\t *    804914b:       5d                      pop    %ebp\n\t\t *    804914c:       c3                      ret\n\t\t */\n\t\treturn NULL;\n\t}\n#if defined(DUK_ALLOC_POOL_ROMPTR_COMPRESSION)\n\tif (val >= DUK_ALLOC_POOL_ROMPTR_FIRST) {\n\t\t/* This is a blind lookup, could check index validity.\n\t\t * Duktape should never decompress a pointer which would\n\t\t * be out-of-bounds here.\n\t\t */\n\t\treturn (void *) (intptr_t) (duk_rom_compressed_pointers[val - DUK_ALLOC_POOL_ROMPTR_FIRST]);\n\t}\n#endif\n\treturn (void *) ((char *) duk_alloc_pool_ptrcomp_base + (((size_t) val) << 2));\n}\n#endif\n\n#if defined(__cplusplus)\n}\n#endif  /* end 'extern \"C\"' wrapper */\n\n#endif  /* DUK_ALLOC_POOL_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/extras/alloc-pool/ptrcomp.yaml",
    "content": "DUK_USE_REFCOUNT16: true\nDUK_USE_STRHASH16: true\nDUK_USE_STRLEN16: true\nDUK_USE_BUFLEN16: true\nDUK_USE_OBJSIZES16: true\nDUK_USE_HSTRING_CLEN: false\nDUK_USE_HOBJECT_HASH_PART: false\nDUK_USE_HEAPPTR16: true\nDUK_USE_HEAPPTR_ENC16:\n  verbatim: \"#define DUK_USE_HEAPPTR_ENC16(ud,p) duk_alloc_pool_enc16((p))\"\nDUK_USE_HEAPPTR_DEC16:\n  verbatim: \"#define DUK_USE_HEAPPTR_DEC16(ud,p) duk_alloc_pool_dec16((p))\"\n\n#DUK_USE_ROM_OBJECTS: true\n#DUK_USE_ROM_STRINGS: true\n#DUK_USE_ROM_GLOBAL_INHERIT: true\n"
  },
  {
    "path": "react_juce/duktape/extras/alloc-pool/ptrcomp_fixup.h",
    "content": "/* To provide declarations for inline pointer compression functions. */\n#include \"duk_alloc_pool.h\"\n"
  },
  {
    "path": "react_juce/duktape/extras/alloc-pool/test.c",
    "content": "#include <stdio.h>\n#include <stdlib.h>\n#include \"duktape.h\"\n#include \"duk_alloc_pool.h\"\n\nvoid my_fatal(const char *msg) {\n\tfprintf(stderr, \"*** FATAL: %s\\n\", msg ? msg : \"no message\");\n\tfflush(stderr);\n\tabort();\n}\n\nstatic duk_ret_t my_print(duk_context *ctx) {\n\tduk_push_string(ctx, \" \");\n\tduk_insert(ctx, 0);\n\tduk_join(ctx, duk_get_top(ctx) - 1);\n\tprintf(\"%s\\n\", duk_safe_to_string(ctx, -1));\n\treturn 1;\n}\n\nstatic void dump_pool_state(duk_pool_global *g) {\n\tint i;\n\tlong total_size = 0;\n\tlong total_used = 0;\n\n\tfor (i = 0; i < g->num_pools; i++) {\n\t\tduk_pool_state *st = g->states + i;\n\t\tint free, used;\n\t\tduk_pool_free *f;\n\n\t\tfor (free = 0, f = st->first; f; f = f->next) {\n\t\t\tfree++;\n\t\t}\n\t\tused = st->count - free;\n\t\tprintf(\"Pool %2d: block size %5d, count %4d/%4d, bytes %6d/%6d\\n\",\n\t\t       i, (int) st->size, used, (int) st->count,\n\t\t       (int) st->size * used, (int) st->size * (int) st->count);\n\n\t\ttotal_size += (long) st->size * (long) st->count;\n\t\ttotal_used += (long) st->size * (long) used;\n\t}\n\tprintf(\"=== Total: %ld/%ld, free %ld\\n\",\n\t       (long) total_used, (long) total_size, (long) (total_size - total_used));\n}\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx;\n\tint i;\n\tint exitcode = 0;\n\n\t/* NOTE! This pool configuration is NOT a good pool configuration\n\t * for practical use (and is not intended to be one).  A production\n\t * pool configuration should be created using measurements.\n\t */\n\tconst duk_pool_config pool_configs[15] = {\n\t\t{ 16, 20, 200 },\n\t\t{ 20, 40, 100 },\n\t\t{ 24, 40, 100 },\n\t\t{ 32, 60, 50 },\n\t\t{ 40, 60, 50 },\n\t\t{ 48, 60, 50 },\n\t\t{ 56, 60, 50 },\n\t\t{ 64, 60, 50 },\n\t\t{ 80, 60, 50 },\n\t\t{ 256, 100, 10 },\n\t\t{ 1024, 20, 2 },\n\t\t{ 2048, 20, 2 },\n\t\t{ 4096, 100, 2 },\n\t\t{ 6144, 60, 2 },\n\t\t{ 8192, 100, 2 },\n\t};\n\tduk_pool_state pool_states[15];  /* Count must match pool_configs[]. */\n\tduk_pool_global pool_global;\n\n\tchar buffer[200000];\n\tvoid *pool_udata;\n\n\tpool_udata = duk_alloc_pool_init(buffer, sizeof(buffer), pool_configs, pool_states, sizeof(pool_configs) / sizeof(duk_pool_config), &pool_global);\n\tif (!pool_udata) {\n\t\treturn 1;\n\t}\n\n\tprintf(\"Pool after pool init:\\n\");\n\tdump_pool_state(&pool_global);\n\n\tctx = duk_create_heap(duk_alloc_pool, duk_realloc_pool, duk_free_pool, pool_udata, NULL);\n\tif (!ctx) {\n\t\treturn 1;\n\t}\n\n\tprintf(\"Pool after Duktape heap creation:\\n\");\n\tdump_pool_state(&pool_global);\n\n\tduk_push_c_function(ctx, my_print, DUK_VARARGS);\n\tduk_put_global_string(ctx, \"print\");\n\tduk_push_c_function(ctx, my_print, DUK_VARARGS);\n\tduk_put_global_string(ctx, \"alert\");\n\tprintf(\"top after init: %ld\\n\", (long) duk_get_top(ctx));\n\n\tfor (i = 1; i < argc; i++) {\n\t\tprintf(\"Evaling: %s\\n\", argv[i]);\n\t\tif (duk_peval_string(ctx, argv[i]) != 0) {\n\t\t\texitcode = 1;\n\t\t}\n\t\tprintf(\"--> %s\\n\", duk_safe_to_string(ctx, -1));\n\t\tduk_pop(ctx);\n\t}\n\n\tprintf(\"Pool after evaling code:\\n\");\n\tdump_pool_state(&pool_global);\n\n\tprintf(\"Done\\n\");\n\tduk_destroy_heap(ctx);\n\treturn exitcode;\n}\n"
  },
  {
    "path": "react_juce/duktape/extras/cbor/Makefile",
    "content": "# For manual testing; say 'make' in extras/cbor.\n\nVALGRIND = valgrind\nCC = gcc\nCCOPTS = -std=c99 -Wall -Wextra -O2\n#CCOPTS += -fsanitize=undefined\n\n.PHONY: all\nall: clean jsoncbor test-runs\n\n.PHONY: clean\nclean:\n\t-rm -rf ./prep\n\t-rm -f jsoncbor\n\t-rm -f appendix_a.json\n\njsoncbor: jsoncbor.c duk_cbor.c duk_cbor.h\n\t-rm -rf ./prep\n\tpython2 ../../tools/configure.py --quiet --output-directory ./prep \\\n\t\t-DDUK_USE_JSON_DECNUMBER_FASTPATH \\\n\t\t-DDUK_USE_JSON_DECSTRING_FASTPATH \\\n\t\t-DDUK_USE_JSON_EATWHITE_FASTPATH \\\n\t\t-DDUK_USE_JSON_QUOTESTRING_FASTPATH \\\n\t\t-DDUK_USE_JSON_STRINGIFY_FASTPATH\n\t$(CC) $(CCOPTS) -o $@ -I./prep -I. ./prep/duktape.c duk_cbor.c jsoncbor.c -lm\n\nappendix_a.json:\n\twget -O $@ https://raw.githubusercontent.com/cbor/test-vectors/master/appendix_a.json\n\n.PHONY: test-runs\ntest-runs: jsoncbor \\\n\tenc-primitives enc-number enc-buffer enc-string enc-array enc-object enc-half-float enc-float enc-misc \\\n\tdec-half-float dec-half-float dec-array dec-object\n\n.PHONY: test-vectors\ntest-vectors: appendix_a.json\n\techo \"Expects 'duk' to exist in local directory for now...\"\n\t./duk run_testvectors.js\n\n.PHONY: dec-half-float\ndec-half-float: jsoncbor\n\t@echo \"half-float zero\"\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x00\\x00\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x00\\x00\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x80\\x00\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x80\\x00\")'| $(VALGRIND) -q ./jsoncbor -d\n\t@echo \"half-float denormal\"\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x00\\x01\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x00\\x01\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x80\\x01\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x80\\x01\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x00\\x02\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x00\\x02\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x80\\x02\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x80\\x02\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x03\\xff\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x03\\xff\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x83\\xff\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x83\\xff\")'| $(VALGRIND) -q ./jsoncbor -d\n\t@echo \"half-float normal\"\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x04\\x00\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x04\\x00\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x84\\x00\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x84\\x00\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x07\\xfe\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x07\\xfe\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x87\\xfe\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x87\\xfe\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x08\\x00\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x08\\x00\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x88\\x00\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x88\\x00\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x78\\x00\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x78\\x00\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\xf8\\x00\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\xf8\\x00\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x7b\\xff\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x7b\\xff\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\xfb\\xff\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\xfb\\xff\")'| $(VALGRIND) -q ./jsoncbor -d\n\t@echo \"half-float inf\"\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x7c\\x00\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x7c\\x00\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\xfc\\x00\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\xfc\\x00\")'| $(VALGRIND) -q ./jsoncbor -d\n\t@echo \"half-float nan\"\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x7c\\x01\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x7c\\x01\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\xfc\\x01\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\xfc\\x01\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x7e\\x00\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x7e\\x00\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\xfe\\x00\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\xfe\\x00\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x7f\\x12\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\x7f\\x12\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\xff\\x12\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xf9\\xff\\x12\")'| $(VALGRIND) -q ./jsoncbor -d\n\n.PHONY: dec-array\ndec-array: jsoncbor\n\tpython -c 'import sys; sys.stdout.write(\"\\x9f\\x01\\x02\\x03\\x9f\\xff\\x04\\x80\\x80\\x9f\\x10\\x11\\xff\\x84\\x04\\x03\\x02\\x01\\xff\")' | python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\x9f\\x01\\x02\\x03\\x9f\\xff\\x04\\x80\\x80\\x9f\\x10\\x11\\xff\\x84\\x04\\x03\\x02\\x01\\xff\")' | $(VALGRIND) -q ./jsoncbor -d\n\n.PHONY: dec-object\ndec-object: jsoncbor\n\tpython -c 'import sys; sys.stdout.write(\"\\xbf\\x63foo\\x63bar\\x63bar\\xa0\\x64quux\\xbf\\xff\\x63baz\\xa2\\x61a\\x61b\\x61c\\x61d\\x65quuux\\xbf\\x61x\\x61y\\x61z\\x61w\\xff\\xff\")' | python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xbf\\x63foo\\x63bar\\x63bar\\xa0\\x64quux\\xbf\\xff\\x63baz\\xa2\\x61a\\x61b\\x61c\\x61d\\x65quuux\\xbf\\x61x\\x61y\\x61z\\x61w\\xff\\xff\")' | $(VALGRIND) -q ./jsoncbor -d\n\n.PHONY: dec-misc\ndec-misc: jsoncbor\n\tpython -c 'import sys; sys.stdout.write(\"\\xa1cfoocbar\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xa1cfoocbar\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xa1\\xa0\\xa0\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xa1\\xa0\\xa0\")'| $(VALGRIND) -q ./jsoncbor -d  # object key, gets string coerced in JSON output\n\tpython -c 'import sys; sys.stdout.write(\"\\x7f\\xff\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\x7f\\xff\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\x7f`````````````````````````````````````````````````````````````````````````````````````````````````````````\\xff\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\x7f`````````````````````````````````````````````````````````````````````````````````````````````````````````\\xff\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\x7fcfoo\\xff\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\x7fcfoo\\xff\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\x7fcfoocbaraqau`auax\\xff\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\x7fcfoocbaraqau`auax\\xff\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\x5f\\xff\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\x5f\\xff\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\x5f@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\\xff\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\x5f@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\\xff\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\x5fCfoo\\xff\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\x5fCfoo\\xff\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\x5fCfooCbarAqAu@AuAx\\xff\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\x5fCfooCbarAqAu@AuAx\\xff\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xc0cfoo\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xc0cfoo\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xc0\\xc1cfoo\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xc0\\xc1cfoo\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xc0\\xd7cfoo\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xc0\\xd7cfoo\")'| $(VALGRIND) -q ./jsoncbor -d\n\tpython -c 'import sys; sys.stdout.write(\"\\xc0\\xd8\\xffcfoo\")'| python cbordecode.py\n\tpython -c 'import sys; sys.stdout.write(\"\\xc0\\xd8\\xffcfoo\")'| $(VALGRIND) -q ./jsoncbor -d\n\n\n.PHONY: enc-primitives\nenc-primitives: jsoncbor\n\techo 'void 0' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo 'null' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo 'true' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo 'false' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\n.PHONY: enc-number\nenc-number: jsoncbor\n\techo '0' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '0.1' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '1' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '23' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '24' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '25' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '255' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '256' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '65535' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '65536' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '65536.9' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '1048576' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '4294967295' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '4294967296' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py  # shortest encoding: ieee single\n\techo '4294967297' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '0xdeadbeef' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '3.141592653589793' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-0' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-0.1' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-1' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-23' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-24' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-25' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-255' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-256' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-257' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-65535' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-65536' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-65536.9' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-65537' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-1048576' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-4294967295' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-4294967296' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-4294967297' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-0xdeadbeef' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-3.141592653589793' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '1/0' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py  # shortest encoding: half-float\n\techo '0/0' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py  # shortest encoding: half-float\n\techo '-1/0' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py  # shortest encoding: half-float\n\n.PHONY: enc-half-float\nenc-half-float:\n\techo '1.5' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '1/16384' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '1/32768' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-1.5' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-1/16384' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-1/32768' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\n.PHONY: enc-float\nenc-float:\n\techo '0xffffffff' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '0x100000000' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '0x1fedcbe0000000000' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '0x1fedcbf0000000000' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\t# Unlike for positive integers, 0x100000000 encodes to a cbor integer (sint).\n\t# Then -0x100000001 doesn't encode to a float because the mantissa is too long.\n\techo '-0x100000000' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-0x100000001' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-0x100010000' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-0x1fedcbe0000000000' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '-0x1fedcbf0000000000' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\n.PHONY: enc-buffer\nenc-buffer: jsoncbor\n\techo '(function () { var p = Uint8Array.allocPlain(0); return p; })()' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '(function () { var p = Uint8Array.allocPlain(1); p[0] = 0xfe; return p; })()' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '(function () { var p = Uint8Array.allocPlain(2); p[0] = 0xc0; p[1] = 0x80; return p; })()' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '(function () { var p = Uint8Array.allocPlain(3); p[0] = 0x31; p[1] = 0x4a; p[2] = 0x7a; return p; })()' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '(function () { var p = Uint8Array.allocPlain(23); p[22] = 0xfe; return p; })()' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '(function () { var p = Uint8Array.allocPlain(24); p[23] = 0xfe; return p; })()' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '(function () { var p = Uint8Array.allocPlain(255); p[254] = 0xfe; return p; })()' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '(function () { var p = Uint8Array.allocPlain(256); p[255] = 0xfe; return p; })()' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '(function () { var p = Uint8Array.allocPlain(256); p[255] = 0xfe; return p; })()' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '(function () { var p = new Uint16Array([ 1, 2, 3, 4 ]); return p; })()' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\n.PHONY: enc-string\nenc-string: jsoncbor\n\techo '\"\"' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '\"foo\"' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '\"foo\\u20acbar\"' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '\"foo\\ud800bar\"' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py  # unpaired surrogate\n\techo '\"\\u4321\\u4321\\u4321\\u4321\\u4321\\u4321\\u4321xy\"' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '\"\\u4321\\u4321\\u4321\\u4321\\u4321\\u4321\\u4321xyz\"' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '\"\\u4321\\u4321\\u4321\\u4321\\u4321\\u4321\\u4321xyzw\"' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '\"\\u4321\\u4321\\u4321\\u4321\\u4321\\u4321\\u4321xyzw......................................................................................................................................................................................................................................\"' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '\"\\u4321\\u4321\\u4321\\u4321\\u4321\\u4321\\u4321xyzw......................................................................................................................................................................................................................................!\"' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\n.PHONY: enc-array\nenc-array: jsoncbor\n\techo '[]' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '[ \"foo\", \"bar\", \"quux\" ]' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\t# XXX: other lengths\n\techo '([[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{ foo: 123 }]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]])' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\n.PHONY: enc-object\nenc-object: jsoncbor\n\techo '({})' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '({ foo: 123 })' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '({ foo: 123, bar: 234, quux: 345 })' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '({ foo: 123, bar: [ \"foo\", \"bar\", { baz: true } ], quux: 345 })' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '({ a:1, b:2, c:3, d:4, e:5, f:6, g:7, h:8, i:9, j:10, k:11, l:12, m:13, n:14, o:15, p:16, q:17, r:18, s:19, t:20, u:21, v:22 })' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '({ a:1, b:2, c:3, d:4, e:5, f:6, g:7, h:8, i:9, j:10, k:11, l:12, m:13, n:14, o:15, p:16, q:17, r:18, s:19, t:20, u:21, v:22, w:23 })' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '({ a:1, b:2, c:3, d:4, e:5, f:6, g:7, h:8, i:9, j:10, k:11, l:12, m:13, n:14, o:15, p:16, q:17, r:18, s:19, t:20, u:21, v:22, w:23, x:24 })' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '({ a:1, b:2, c:3, d:4, e:5, f:6, g:7, h:8, i:9, j:10, k:11, l:12, m:13, n:14, o:15, p:16, q:17, r:18, s:19, t:20, u:21, v:22, w:23, x:24, y:25 })' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '({ a:1, b:2, c:3, d:4, e:5, f:6, g:7, h:8, i:9, j:10, k:11, l:12, m:13, n:14, o:15, p:16, q:17, r:18, s:19, t:20, u:21, v:22, w:23, x:24, y:25, z:26 })' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\techo '({foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:{foo:123}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}})' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n\n.PHONY: enc-misc\nenc-misc: jsoncbor\n\techo '({ jsonrpc: \"2.0\", id: \"foo-1\", method: \"Add\", params: { a: 123, b: 234 }})' | $(VALGRIND) -q ./jsoncbor -r js -w cbor | python2 cbordecode.py\n"
  },
  {
    "path": "react_juce/duktape/extras/cbor/README.rst",
    "content": "============\nCBOR binding\n============\n\nOverview\n========\n\nC functions to encode/decode values in CBOR format, and a simple command\nline utility to convert between JSON and CBOR.\n\nTo integrate CBOR into your application:\n\n* Call ``duk_cbor_encode()`` and ``duk_cbor_decode()`` directly if a C API\n  is enough.\n\n* Call ``duk_cbor_init()`` to register a global ``CBOR`` object with\n  ECMAScript bindings ``CBOR.encode()`` and ``CBOR.decode()``, roughly\n  matching https://github.com/paroga/cbor-js.\n\nBasic usage of the ``jsoncbor`` conversion tool::\n\n    $ make jsoncbor\n    [...]\n    $ cat test.json | ./jsoncbor -e   # writes CBOR to stdout\n    $ cat test.cbor | ./jsoncbor -d   # writes JSON to stdout\n\nCBOR objects are decoded into ECMAScript objects, with non-string keys\ncoerced into strings.\n\nDirect support for CBOR is likely to be included in the Duktape API in the\nfuture.  This extra will then become unnecessary.\n\nCBOR\n====\n\nCBOR is a standard format for JSON-like binary interchange.  It is\nfaster and smaller, and can encode more data types than JSON.  In particular,\nbinary data can be serialized without encoding e.g. in base-64.  These\nproperties make it useful for storing state files, IPC, etc.\n\nSome CBOR shortcomings for preserving information:\n\n* No property attribute or inheritance support.\n\n* No DAGs or looped graphs.\n\n* Array objects with properties lose their non-index properties.\n\n* Array objects with gaps lose their gaps as they read back as undefined.\n\n* Buffer objects and views lose much of their detail besides the raw data.\n\n* ECMAScript strings cannot be fully represented; strings must be UTF-8.\n\n* Functions and native objects lose most of their detail.\n\n* CBOR tags are useful to provide soft decoding information, but the tags\n  are just integers from an IANA controlled space with no space for custom\n  tags.  So tags cannot be easily used for private, application specific tags.\n  IANA allows reserving custom tags with little effort however, see\n  https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml.\n\nFuture work\n===========\n\nGeneral:\n\n* Add flags to control encode/decode behavior.\n\n* Allow decoding with a trailer so that stream parsing is easier.\n  Similar change would be useful for JSON decoding.\n\n* Reserve CBOR tag for missing value.\n\n* Reserve other necessary CBOR tags.\n\n* Explicit support for encoding with and without side effects (e.g.\n  skipping Proxy traps and getters).\n\n* JSON encoding supports .toJSON(), maybe something like .toCBOR()?\n\n* Optimize encoding and decoding more.\n\nEncoding:\n\n* Tagging of typed arrays:\n  https://datatracker.ietf.org/doc/draft-ietf-cbor-array-tags/.\n  Mixed endian encode must convert to e.g. little endian because\n  no mixed endian tag exists.\n\n* Encoding typed arrays as integer arrays instead?\n\n* Float16Array encoding support (once/if supported by main engine).\n\n* Tagging of array gaps, once IANA reservation is complete:\n  https://github.com/svaarala/duktape/blob/master/doc/cbor-missing-tag.rst.\n\n* Support 64-bit integer when encoding, e.g. up to 2^53?\n\n* Definite-length object encoding even when object has more than 23 keys.\n\n* Map/Set encoding (once supported in the main engine), maybe tagged\n  so they decode back into Map/Set.\n\n* Bigint encoding (once supported in the main engine), as tagged byte\n  strings like in Python CBOR.\n\n* String encoding options: combining surrogate pairs, tagging non-UTF-8\n  byte strings so they decode back to string, using U+FFFD replacement,\n  etc.\n\n* Detection of Symbols, encode them in a useful tagged form.\n\n* Better encoding of functions.\n\n* Hook for serialization, to allow caller to serialize values (especially\n  objects) in a context specific manner (e.g. serialize functions with\n  IPC metadata to allow them to be called remotely).  Such a hook should\n  be able to emit tag(s) to mark custom values for decode processing.\n\nDecoding:\n\n* Typed array decoding support.  Should decoder convert to host\n  endianness?\n\n* Float16Array decoding support (once/if supported by main engine).\n\n* Decoding objects with non-string keys, could be represented as a Map.\n\n* Use bare objects and arrays when decoding?\n\n* Use a Map rather than a plain object when decoding, which would allow\n  non-string keys.\n\n* Bigint decoding (once supported in the main engine).\n\n* Decoding of non-BMP codepoints into surrogate pairs.\n\n* Decoding of Symbols when call site indicates it is safe.\n\n* Hooking for revival, to allow caller to revive objects in a context\n  specific manner (e.g. revive serialized function objects into IPC\n  proxy functions).  Such a hook should have access to encoding tags,\n  so that revival can depend on tags present.\n\n* Option to compact decoded objects and arrays.\n\n* Improve fastint decoding support, e.g. decode non-optimally encoded\n  integers as fastints, decode compatible floating point values as\n  fastints.\n"
  },
  {
    "path": "react_juce/duktape/extras/cbor/cbordecode.py",
    "content": "#!/usr/bin/env python2\n\ndef main():\n    import sys\n    import cbor\n    import json\n\n    data = sys.stdin.read()\n    print('LEN: %d' % len(data))\n    sys.stdout.flush()\n    print('HEX: ' + data.encode('hex'))\n    sys.stdout.flush()\n    doc = cbor.loads(data)\n    print('REPR: ' + repr(doc))\n    sys.stdout.flush()\n    try:\n        print('JSON: ' + json.dumps(doc))\n        sys.stdout.flush()\n    except:\n        print('JSON: cannot encode')\n        sys.stdout.flush()\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/extras/cbor/duk_cbor.c",
    "content": "/*\n *  CBOR bindings for Duktape.\n *\n *  https://tools.ietf.org/html/rfc7049\n */\n\n#include <math.h>\n#include <string.h>\n#include \"duktape.h\"\n#include \"duk_cbor.h\"\n\n/* #define DUK_CBOR_DPRINT */\n/* #define DUK_CBOR_STRESS */\n\n#if 1\n#define DUK_CBOR_ASSERT(x) do {} while (0)\n#else\n#include <stdio.h>\n#include <stdlib.h>\n#define DUK_CBOR_ASSERT(x) do { \\\n\t\tif (!(x)) { \\\n\t\t\tfprintf(stderr, \"ASSERT FAILED on %s:%d\\n\", __FILE__, __LINE__); \\\n\t\t\tfflush(stderr); \\\n\t\t\tabort(); \\\n\t\t} \\\n\t} while (0)\n#endif\n\n#if 0\n#define DUK_CBOR_LIKELY(x) __builtin_expect (!!(x), 1)\n#define DUK_CBOR_UNLIKELY(x) __builtin_expect (!!(x), 0)\n#define DUK_CBOR_INLINE inline\n#define DUK_CBOR_NOINLINE __attribute__((noinline))\n#else\n#define DUK_CBOR_LIKELY(x) (x)\n#define DUK_CBOR_UNLIKELY(x) (x)\n#define DUK_CBOR_INLINE\n#define DUK_CBOR_NOINLINE\n#endif\n\n/* #define DUK_CBOR_GCC_BUILTINS */\n\n/* Default behavior for encoding strings: use CBOR text string if string\n * is UTF-8 compatible, otherwise use CBOR byte string.  These defines\n * can be used to force either type for all strings.  Using text strings\n * for non-UTF-8 data is technically invalid CBOR.\n */\n/* #define DUK_CBOR_TEXT_STRINGS */\n/* #define DUK_CBOR_BYTE_STRINGS */\n\n/* Misc. defines. */\n/* #define DUK_CBOR_PREFER_SIZE */\n/* #define DUK_CBOR_DOUBLE_AS_IS */\n/* #define DUK_CBOR_DECODE_FASTPATH */\n\ntypedef struct {\n\tduk_context *ctx;\n\tduk_uint8_t *ptr;\n\tduk_uint8_t *buf;\n\tduk_uint8_t *buf_end;\n\tduk_size_t len;\n\tduk_idx_t idx_buf;\n} duk_cbor_encode_context;\n\ntypedef struct {\n\tduk_context *ctx;\n\tconst duk_uint8_t *buf;\n\tduk_size_t off;\n\tduk_size_t len;\n} duk_cbor_decode_context;\n\ntypedef union {\n\tduk_uint8_t x[8];\n\tduk_uint16_t s[4];\n\tduk_uint32_t i[2];\n#if 0\n\tduk_uint64_t i64[1];\n#endif\n\tdouble d;\n} duk_cbor_dblunion;\n\ntypedef union {\n\tduk_uint8_t x[4];\n\tduk_uint16_t s[2];\n\tduk_uint32_t i[1];\n\tfloat f;\n} duk_cbor_fltunion;\n\nstatic void duk__cbor_encode_value(duk_cbor_encode_context *enc_ctx);\nstatic void duk__cbor_decode_value(duk_cbor_decode_context *dec_ctx);\n\n/*\n *  Misc\n */\n\n/* XXX: These are sometimes portability concerns and would be nice to expose\n * from Duktape itself as portability helpers.\n */\n\nstatic int duk__cbor_signbit(double d) {\n\treturn signbit(d);\n}\n\nstatic int duk__cbor_fpclassify(double d) {\n\treturn fpclassify(d);\n}\n\nstatic int duk__cbor_isnan(double d) {\n\treturn isnan(d);\n}\n\nstatic int duk__cbor_isinf(double d) {\n\treturn isinf(d);\n}\n\nstatic duk_uint32_t duk__cbor_double_to_uint32(double d) {\n\t/* Out of range casts are undefined behavior, so caller must avoid. */\n\tDUK_CBOR_ASSERT(d >= 0.0 && d <= 4294967295.0);\n\treturn (duk_uint32_t) d;\n}\n\n/* Endian detection.  Technically happens at runtime, but in practice\n * resolves at compile time to a constant and gets inlined.\n */\n#define DUK__CBOR_LITTLE_ENDIAN  1\n#define DUK__CBOR_MIXED_ENDIAN   2\n#define DUK__CBOR_BIG_ENDIAN     3\n\nstatic int duk__cbor_check_endian(void) {\n\tduk_cbor_dblunion u;\n\n\t/* >>> struct.pack('>d', 1.23456789).encode('hex')\n\t * '3ff3c0ca4283de1b'\n\t */\n\n\tu.d = 1.23456789;\n\tif (u.x[0] == 0x1bU) {\n\t\treturn DUK__CBOR_LITTLE_ENDIAN;\n\t} else if (u.x[0] == 0x3fU) {\n\t\treturn DUK__CBOR_BIG_ENDIAN;\n\t} else if (u.x[0] == 0xcaU) {\n\t\treturn DUK__CBOR_MIXED_ENDIAN;\n\t} else {\n\t\tDUK_CBOR_ASSERT(0);\n\t}\n\treturn 0;\n}\n\nstatic DUK_CBOR_INLINE duk_uint16_t duk__cbor_bswap16(duk_uint16_t x) {\n#if defined(DUK_CBOR_GCC_BUILTINS)\n\treturn __builtin_bswap16(x);\n#else\n\t/* XXX: matches, DUK_BSWAP16(), use that if exposed. */\n\treturn (x >> 8) | (x << 8);\n#endif\n}\n\nstatic DUK_CBOR_INLINE duk_uint32_t duk__cbor_bswap32(duk_uint32_t x) {\n#if defined(DUK_CBOR_GCC_BUILTINS)\n\treturn __builtin_bswap32(x);\n#else\n\t/* XXX: matches, DUK_BSWAP32(), use that if exposed. */\n\treturn (x >> 24) | ((x >> 8) & 0xff00UL) | ((x << 8) & 0xff0000UL) | (x << 24);\n#endif\n}\n\n#if 0\nstatic duk_uint64_t duk__cbor_bswap64(duk_uint64_t x) {\n\t/* XXX */\n}\n#endif\n\nstatic DUK_CBOR_INLINE void duk__cbor_write_uint16_big(duk_uint8_t *p, duk_uint16_t x) {\n#if 0\n\t*p++ = (duk_uint8_t) ((x >> 8) & 0xffU);\n\t*p++ = (duk_uint8_t) (x & 0xffU);\n#endif\n\tduk_uint16_t a;\n\n\tswitch (duk__cbor_check_endian()) {\n\tcase DUK__CBOR_LITTLE_ENDIAN:\n\tcase DUK__CBOR_MIXED_ENDIAN:\n\t\ta = duk__cbor_bswap16(x);\n\t\t(void) memcpy((void *) p, (const void *) &a, 2);\n\t\tbreak;\n\tcase DUK__CBOR_BIG_ENDIAN:\n\t\ta = x;\n\t\t(void) memcpy((void *) p, (const void *) &a, 2);\n\t\tbreak;\n\tdefault:\n\t\tDUK_CBOR_ASSERT(0);\n\t}\n}\n\nstatic DUK_CBOR_INLINE duk_uint16_t duk__cbor_read_uint16_big(const duk_uint8_t *p) {\n\tduk_uint16_t a, x;\n\n#if 0\n\tx = (((duk_uint16_t) p[0]) << 8U) +\n\t    ((duk_uint16_t) p[1]);\n#endif\n\tswitch (duk__cbor_check_endian()) {\n\tcase DUK__CBOR_LITTLE_ENDIAN:\n\tcase DUK__CBOR_MIXED_ENDIAN:\n\t\t(void) memcpy((void *) &a, (const void *) p, 2);\n\t\tx = duk__cbor_bswap16(a);\n\t\tbreak;\n\tcase DUK__CBOR_BIG_ENDIAN:\n\t\t(void) memcpy((void *) &a, (const void *) p, 2);\n\t\tx = a;\n\t\tbreak;\n\tdefault:\n\t\tDUK_CBOR_ASSERT(0);\n\t\tx = 0;\n\t}\n\treturn x;\n}\n\nstatic DUK_CBOR_INLINE void duk__cbor_write_uint32_big(duk_uint8_t *p, duk_uint32_t x) {\n#if 0\n\t*p++ = (duk_uint8_t) ((x >> 24) & 0xffU);\n\t*p++ = (duk_uint8_t) ((x >> 16) & 0xffU);\n\t*p++ = (duk_uint8_t) ((x >> 8) & 0xffU);\n\t*p++ = (duk_uint8_t) (x & 0xffU);\n#endif\n\tduk_uint32_t a;\n\n\tswitch (duk__cbor_check_endian()) {\n\tcase DUK__CBOR_LITTLE_ENDIAN:\n\tcase DUK__CBOR_MIXED_ENDIAN:\n\t\ta = duk__cbor_bswap32(x);\n\t\t(void) memcpy((void *) p, (const void *) &a, 4);\n\t\tbreak;\n\tcase DUK__CBOR_BIG_ENDIAN:\n\t\ta = x;\n\t\t(void) memcpy((void *) p, (const void *) &a, 4);\n\t\tbreak;\n\tdefault:\n\t\tDUK_CBOR_ASSERT(0);\n\t}\n}\n\nstatic DUK_CBOR_INLINE duk_uint32_t duk__cbor_read_uint32_big(const duk_uint8_t *p) {\n\tduk_uint32_t a, x;\n\n#if 0\n\tx = (((duk_uint32_t) p[0]) << 24U) +\n\t    (((duk_uint32_t) p[1]) << 16U) +\n\t    (((duk_uint32_t) p[2]) << 8U) +\n\t    ((duk_uint32_t) p[3]);\n#endif\n\tswitch (duk__cbor_check_endian()) {\n\tcase DUK__CBOR_LITTLE_ENDIAN:\n\tcase DUK__CBOR_MIXED_ENDIAN:\n\t\t(void) memcpy((void *) &a, (const void *) p, 4);\n\t\tx = duk__cbor_bswap32(a);\n\t\tbreak;\n\tcase DUK__CBOR_BIG_ENDIAN:\n\t\t(void) memcpy((void *) &a, (const void *) p, 4);\n\t\tx = a;\n\t\tbreak;\n\tdefault:\n\t\tDUK_CBOR_ASSERT(0);\n\t\tx = 0;\n\t}\n\treturn x;\n}\n\nstatic DUK_CBOR_INLINE void duk__cbor_write_double_big(duk_uint8_t *p, double x) {\n\tduk_cbor_dblunion u;\n\tduk_uint32_t a, b;\n\n\tu.d = x;\n\n\tswitch (duk__cbor_check_endian()) {\n\tcase DUK__CBOR_LITTLE_ENDIAN:\n#if 0\n\t\tu.i64[0] = duk__cbor_bswap64(u.i64[0]);\n\t\t(void) memcpy((void *) p, (const void *) u.x, 8);\n#endif\n\t\ta = u.i[0];\n\t\tb = u.i[1];\n\t\tu.i[0] = duk__cbor_bswap32(b);\n\t\tu.i[1] = duk__cbor_bswap32(a);\n\t\t(void) memcpy((void *) p, (const void *) u.x, 8);\n\t\tbreak;\n\tcase DUK__CBOR_MIXED_ENDIAN:\n\t\ta = u.i[0];\n\t\tb = u.i[1];\n\t\tu.i[0] = duk__cbor_bswap32(a);\n\t\tu.i[1] = duk__cbor_bswap32(b);\n\t\t(void) memcpy((void *) p, (const void *) u.x, 8);\n\t\tbreak;\n\tcase DUK__CBOR_BIG_ENDIAN:\n\t\t(void) memcpy((void *) p, (const void *) u.x, 8);\n\t\tbreak;\n\tdefault:\n\t\tDUK_CBOR_ASSERT(0);\n\t}\n}\n\nstatic DUK_CBOR_INLINE void duk__cbor_write_float_big(duk_uint8_t *p, float x) {\n\tduk_cbor_fltunion u;\n\tduk_uint32_t a;\n\n\tu.f = x;\n\tswitch (duk__cbor_check_endian()) {\n\tcase DUK__CBOR_LITTLE_ENDIAN:\n\tcase DUK__CBOR_MIXED_ENDIAN:\n\t\ta = u.i[0];\n\t\tu.i[0] = duk__cbor_bswap32(a);\n\t\t(void) memcpy((void *) p, (const void *) u.x, 4);\n\t\tbreak;\n\tcase DUK__CBOR_BIG_ENDIAN:\n\t\t(void) memcpy((void *) p, (const void *) u.x, 4);\n\t\tbreak;\n\tdefault:\n\t\tDUK_CBOR_ASSERT(0);\n\t}\n}\n\nstatic DUK_CBOR_INLINE void duk__cbor_dblunion_host_to_little(duk_cbor_dblunion *u) {\n\tduk_uint32_t a, b;\n\n\tswitch (duk__cbor_check_endian()) {\n\tcase DUK__CBOR_LITTLE_ENDIAN:\n\t\t/* HGFEDCBA -> HGFEDCBA */\n\t\tbreak;\n\tcase DUK__CBOR_MIXED_ENDIAN:\n\t\t/* DCBAHGFE -> HGFEDCBA */\n\t\ta = u->i[0];\n\t\tb = u->i[1];\n\t\tu->i[0] = b;\n\t\tu->i[1] = a;\n\t\tbreak;\n\tcase DUK__CBOR_BIG_ENDIAN:\n\t\t/* ABCDEFGH -> HGFEDCBA */\n#if 0\n\t\tu->i64[0] = duk__cbor_bswap64(u->i64[0]);\n#endif\n\t\ta = u->i[0];\n\t\tb = u->i[1];\n\t\tu->i[0] = duk__cbor_bswap32(b);\n\t\tu->i[1] = duk__cbor_bswap32(a);\n\t\tbreak;\n\t}\n}\n\nstatic DUK_CBOR_INLINE void duk__cbor_dblunion_little_to_host(duk_cbor_dblunion *u) {\n\tduk__cbor_dblunion_host_to_little(u);\n}\n\nstatic DUK_CBOR_INLINE void duk__cbor_dblunion_host_to_big(duk_cbor_dblunion *u) {\n\tduk_uint32_t a, b;\n\n\tswitch (duk__cbor_check_endian()) {\n\tcase DUK__CBOR_LITTLE_ENDIAN:\n\t\t/* HGFEDCBA -> ABCDEFGH */\n#if 0\n\t\tu->i64[0] = duk__cbor_bswap64(u->i64[0]);\n#else\n\t\ta = u->i[0];\n\t\tb = u->i[1];\n\t\tu->i[0] = duk__cbor_bswap32(b);\n\t\tu->i[1] = duk__cbor_bswap32(a);\n#endif\n\t\tbreak;\n\tcase DUK__CBOR_MIXED_ENDIAN:\n\t\t/* DCBAHGFE -> ABCDEFGH */\n\t\ta = u->i[0];\n\t\tb = u->i[1];\n\t\tu->i[0] = duk__cbor_bswap32(a);\n\t\tu->i[1] = duk__cbor_bswap32(b);\n\t\tbreak;\n\tcase DUK__CBOR_BIG_ENDIAN:\n\t\t/* ABCDEFGH -> ABCDEFGH */\n\t\tbreak;\n\t}\n}\n\nstatic DUK_CBOR_INLINE void duk__cbor_dblunion_big_to_host(duk_cbor_dblunion *u) {\n\tduk__cbor_dblunion_host_to_big(u);\n}\n\nstatic DUK_CBOR_INLINE void duk__cbor_fltunion_host_to_big(duk_cbor_fltunion *u) {\n\tswitch (duk__cbor_check_endian()) {\n\tcase DUK__CBOR_LITTLE_ENDIAN:\n\tcase DUK__CBOR_MIXED_ENDIAN:\n\t\t/* DCBA -> ABCD */\n\t\tu->i[0] = duk__cbor_bswap32(u->i[0]);\n\t\tbreak;\n\tcase DUK__CBOR_BIG_ENDIAN:\n\t\t/* ABCD -> ABCD */\n\t\tbreak;\n\t}\n}\n\nstatic DUK_CBOR_INLINE void duk__cbor_fltunion_big_to_host(duk_cbor_fltunion *u) {\n\tduk__cbor_fltunion_host_to_big(u);\n}\n\n/*\n *  Encoding\n */\n\nstatic void duk__cbor_encode_error(duk_cbor_encode_context *enc_ctx) {\n\t(void) duk_type_error(enc_ctx->ctx, \"cbor encode error\");\n}\n\n/* Check whether a string is UTF-8 compatible or not. */\nstatic int duk__cbor_is_utf8_compatible(const duk_uint8_t *buf, duk_size_t len) {\n\tduk_size_t i = 0;\n#if !defined(DUK_CBOR_PREFER_SIZE)\n\tduk_size_t len_safe;\n#endif\n\n\t/* Many practical strings are ASCII only, so use a fast path check\n\t * to check chunks of bytes at once with minimal branch cost.\n\t */\n#if !defined(DUK_CBOR_PREFER_SIZE)\n\tlen_safe = len & ~0x03UL;\n\tfor (; i < len_safe; i += 4) {\n\t\tduk_uint8_t t = buf[i] | buf[i + 1] | buf[i + 2] | buf[i + 3];\n\t\tif (DUK_CBOR_UNLIKELY((t & 0x80U) != 0U)) {\n\t\t\t/* At least one byte was outside 0x00-0x7f, break\n\t\t\t * out to slow path (and remain there).\n\t\t\t *\n\t\t\t * XXX: We could also deal with the problem character\n\t\t\t * and resume fast path later.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\t}\n#endif\n\n\tfor (; i < len;) {\n\t\tduk_uint8_t t;\n\t\tduk_size_t left;\n\t\tduk_size_t ncont;\n\t\tduk_uint32_t cp;\n\t\tduk_uint32_t mincp;\n\n\t\tt = buf[i++];\n\t\tif (DUK_CBOR_LIKELY((t & 0x80U) == 0U)) {\n\t\t\t/* Fast path, ASCII. */\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Non-ASCII start byte, slow path.\n\t\t *\n\t\t * 10xx xxxx          -> continuation byte\n\t\t * 110x xxxx + 1*CONT -> [0x80, 0x7ff]\n\t\t * 1110 xxxx + 2*CONT -> [0x800, 0xffff], must reject [0xd800,0xdfff]\n\t\t * 1111 0xxx + 3*CONT -> [0x10000, 0x10ffff]\n\t\t */\n\t\tleft = len - i;\n\t\tif (t <= 0xdfU) {  /* 1101 1111 = 0xdf */\n\t\t\tif (t <= 0xbfU) {  /* 1011 1111 = 0xbf */\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tncont = 1;\n\t\t\tmincp = 0x80UL;\n\t\t\tcp = t & 0x1fU;\n\t\t} else if (t <= 0xefU) {  /* 1110 1111 = 0xef */\n\t\t\tncont = 2;\n\t\t\tmincp = 0x800UL;\n\t\t\tcp = t & 0x0fU;\n\t\t} else if (t <= 0xf7U) {  /* 1111 0111 = 0xf7 */\n\t\t\tncont = 3;\n\t\t\tmincp = 0x10000UL;\n\t\t\tcp = t & 0x07U;\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t\tif (left < ncont) {\n\t\t\treturn 0;\n\t\t}\n\t\twhile (ncont > 0U) {\n\t\t\tt = buf[i++];\n\t\t\tif ((t & 0xc0U) != 0x80U) {  /* 10xx xxxx */\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tcp = (cp << 6) + (t & 0x3fU);\n\t\t\tncont--;\n\t\t}\n\t\tif (cp < mincp || cp > 0x10ffffUL || (cp >= 0xd800UL && cp <= 0xdfffUL)) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\treturn 1;\n}\n\n/* Check that a size_t is in uint32 range to avoid out-of-range casts. */\nstatic void duk__cbor_encode_sizet_uint32_check(duk_cbor_encode_context *enc_ctx, duk_size_t len) {\n\tif (DUK_CBOR_UNLIKELY(sizeof(duk_size_t) > sizeof(duk_uint32_t) && len > (duk_size_t) DUK_UINT32_MAX)) {\n\t\tduk__cbor_encode_error(enc_ctx);\n\t}\n}\n\nstatic DUK_CBOR_NOINLINE void duk__cbor_encode_ensure_slowpath(duk_cbor_encode_context *enc_ctx, duk_size_t len) {\n\tduk_size_t oldlen;\n\tduk_size_t minlen;\n\tduk_size_t newlen;\n\tduk_uint8_t *p_new;\n\tduk_size_t old_data_len;\n\n\tDUK_CBOR_ASSERT(enc_ctx->ptr >= enc_ctx->buf);\n\tDUK_CBOR_ASSERT(enc_ctx->buf_end >= enc_ctx->ptr);\n\tDUK_CBOR_ASSERT(enc_ctx->buf_end >= enc_ctx->buf);\n\n\t/* Overflow check.\n\t *\n\t * Limit example: 0xffffffffUL / 2U = 0x7fffffffUL, we reject >= 0x80000000UL.\n\t */\n\toldlen = enc_ctx->len;\n\tminlen = oldlen + len;\n\tif (DUK_CBOR_UNLIKELY(oldlen > DUK_SIZE_MAX / 2U || minlen < oldlen)) {\n\t\tduk__cbor_encode_error(enc_ctx);\n\t}\n\n#if defined(DUK_CBOR_STRESS)\n\tnewlen = oldlen + 1U;\n#else\n\tnewlen = oldlen * 2U;\n#endif\n\tDUK_CBOR_ASSERT(newlen >= oldlen);\n\n\tif (minlen > newlen) {\n\t\tnewlen = minlen;\n\t}\n\tDUK_CBOR_ASSERT(newlen >= oldlen);\n\tDUK_CBOR_ASSERT(newlen >= minlen);\n\tDUK_CBOR_ASSERT(newlen > 0U);\n\n#if defined(DUK_CBOR_DPRINT)\n\tfprintf(stderr, \"cbor encode buffer resized to %ld\\n\", (long) newlen);\n#endif\n\n\tp_new = (duk_uint8_t *) duk_resize_buffer(enc_ctx->ctx, enc_ctx->idx_buf, newlen);\n\tDUK_CBOR_ASSERT(p_new != NULL);\n\told_data_len = (duk_size_t) (enc_ctx->ptr - enc_ctx->buf);\n\tenc_ctx->buf = p_new;\n\tenc_ctx->buf_end = p_new + newlen;\n\tenc_ctx->ptr = p_new + old_data_len;\n\tenc_ctx->len = newlen;\n}\n\nstatic DUK_CBOR_INLINE void duk__cbor_encode_ensure(duk_cbor_encode_context *enc_ctx, duk_size_t len) {\n\tif (DUK_CBOR_LIKELY((duk_size_t) (enc_ctx->buf_end - enc_ctx->ptr) >= len)) {\n\t\treturn;\n\t}\n\tduk__cbor_encode_ensure_slowpath(enc_ctx, len);\n}\n\nstatic duk_size_t duk__cbor_get_reserve(duk_cbor_encode_context *enc_ctx) {\n\tDUK_CBOR_ASSERT(enc_ctx->ptr >= enc_ctx->buf);\n\tDUK_CBOR_ASSERT(enc_ctx->ptr <= enc_ctx->buf_end);\n\treturn (duk_size_t) (enc_ctx->buf_end - enc_ctx->ptr);\n}\n\nstatic void duk__cbor_encode_uint32(duk_cbor_encode_context *enc_ctx, duk_uint32_t u, duk_uint8_t base) {\n\tduk_uint8_t *p;\n\n\t/* Caller must ensure space. */\n\tDUK_CBOR_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 4);\n\n\tp = enc_ctx->ptr;\n\tif (DUK_CBOR_LIKELY(u <= 23U)) {\n\t\t*p++ = (duk_uint8_t) (base + (duk_uint8_t) u);\n\t} else if (u <= 0xffUL) {\n\t\t*p++ = base + 0x18U;\n\t\t*p++ = (duk_uint8_t) u;\n\t} else if (u <= 0xffffUL) {\n\t\t*p++ = base + 0x19U;\n\t\tduk__cbor_write_uint16_big(p, (duk_uint16_t) u);\n\t\tp += 2;\n\t} else {\n\t\t*p++ = base + 0x1aU;\n\t\tduk__cbor_write_uint32_big(p, u);\n\t\tp += 4;\n\t}\n\tenc_ctx->ptr = p;\n}\n\n#if defined(DUK_CBOR_DOUBLE_AS_IS)\nstatic void duk__cbor_encode_double(duk_cbor_encode_context *enc_ctx, double d) {\n\tduk_uint8_t *p;\n\n\t/* Caller must ensure space. */\n\tDUK_CBOR_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8);\n\n\tp = enc_ctx->ptr;\n\t*p++ = 0xfbU;\n\tduk__cbor_write_double_big(p, d);\n\tp += 8;\n\tenc_ctx->ptr = p;\n}\n#else  /* DUK_CBOR_DOUBLE_AS_IS */\nstatic void duk__cbor_encode_double_fp(duk_cbor_encode_context *enc_ctx, double d) {\n\tduk_cbor_dblunion u;\n\tduk_uint16_t u16;\n\tduk_int16_t exp;\n\tduk_uint8_t *p;\n\n\tDUK_CBOR_ASSERT(duk__cbor_fpclassify(d) != FP_ZERO);\n\n\t/* Caller must ensure space. */\n\tDUK_CBOR_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8);\n\n\t/* Organize into little endian (no-op if platform is little endian). */\n\tu.d = d;\n\tduk__cbor_dblunion_host_to_little(&u);\n\n\t/* Check if 'd' can represented as a normal half-float.\n\t * Denormal half-floats could also be used, but that check\n\t * isn't done now (denormal half-floats are decoded of course).\n\t * So just check exponent range and that at most 10 significant\n\t * bits (excluding implicit leading 1) are used in 'd'.\n\t */\n\tu16 = (((duk_uint16_t) u.x[7]) << 8) | ((duk_uint16_t) u.x[6]);\n\texp = (duk_int16_t) ((u16 & 0x7ff0U) >> 4) - 1023;\n\n\tif (exp >= -14 && exp <= 15) {\n\t\t/* Half-float normal exponents (excl. denormals).\n\t\t *\n\t\t *          7        6        5        4        3        2        1        0  (LE index)\n\t\t * double: seeeeeee eeeemmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm\n\t\t * half:         seeeee mmmm mmmmmm00 00000000 00000000 00000000 00000000 00000000\n\t\t */\n\t\tint use_half_float;\n\n\t\tuse_half_float =\n\t\t    (u.x[0] == 0 && u.x[1] == 0 && u.x[2] == 0 && u.x[3] == 0 &&\n\t\t     u.x[4] == 0 && (u.x[5] & 0x03U) == 0);\n\n\t\tif (use_half_float) {\n\t\t\tduk_uint32_t t;\n\n\t\t\texp += 15;\n\t\t\tt = (duk_uint32_t) (u.x[7] & 0x80U) << 8;\n\t\t\tt += (duk_uint32_t) exp << 10;\n\t\t\tt += ((duk_uint32_t) u.x[6] & 0x0fU) << 6;\n\t\t\tt += ((duk_uint32_t) u.x[5]) >> 2;\n\n\t\t\t/* seeeeemm mmmmmmmm */\n\t\t\tp = enc_ctx->ptr;\n\t\t\t*p++ = 0xf9U;\n\t\t\tduk__cbor_write_uint16_big(p, (duk_uint16_t) t);\n\t\t\tp += 2;\n\t\t\tenc_ctx->ptr = p;\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/* Same check for plain float.  Also no denormal support here. */\n\tif (exp >= -126 && exp <= 127) {\n\t\t/* Float normal exponents (excl. denormals).\n\t\t *\n\t\t * double: seeeeeee eeeemmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm mmmmmmmm\n\t\t * float:     seeee eeeemmmm mmmmmmmm mmmmmmmm mmm00000 00000000 00000000 00000000\n\t\t */\n\t\tint use_float;\n\t\tduk_float_t d_float;\n\n\t\t/* We could do this explicit mantissa check, but doing\n\t\t * a double-float-double cast is fine because we've\n\t\t * already verified that the exponent is in range so\n\t\t * that the narrower cast is not undefined behavior.\n\t\t */\n#if 0\n\t\tuse_float =\n\t\t    (u.x[0] == 0 && u.x[1] == 0 && u.x[2] == 0 && (u.x[3] & 0xe0U) == 0);\n#endif\n\t\td_float = (duk_float_t) d;\n\t\tuse_float = ((duk_double_t) d_float == d);\n\t\tif (use_float) {\n\t\t\tp = enc_ctx->ptr;\n\t\t\t*p++ = 0xfaU;\n\t\t\tduk__cbor_write_float_big(p, d_float);\n\t\t\tp += 4;\n\t\t\tenc_ctx->ptr = p;\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/* Special handling for NaN and Inf which we want to encode as\n\t * half-floats.  They share the same (maximum) exponent.\n\t */\n\tif (exp == 1024) {\n\t\tDUK_CBOR_ASSERT(duk__cbor_isnan(d) || duk__cbor_isinf(d));\n\t\tp = enc_ctx->ptr;\n\t\t*p++ = 0xf9U;\n\t\tif (duk__cbor_isnan(d)) {\n\t\t\t/* Shortest NaN encoding is using a half-float.  Lose the\n\t\t\t * exact NaN bits in the process.  IEEE double would be\n\t\t\t * 7ff8 0000 0000 0000, i.e. a quiet NaN in most architectures\n\t\t\t * (https://en.wikipedia.org/wiki/NaN#Encoding).  The\n\t\t\t * equivalent half float is 7e00.\n\t\t\t */\n\t\t\t*p++ = 0x7eU;\n\t\t} else {\n\t\t\t/* Shortest +/- Infinity encoding is using a half-float. */\n\t\t\tif (duk__cbor_signbit(d)) {\n\t\t\t\t*p++ = 0xfcU;\n\t\t\t} else {\n\t\t\t\t*p++ = 0x7cU;\n\t\t\t}\n\t\t}\n\t\t*p++ = 0x00U;\n\t\tenc_ctx->ptr = p;\n\t\treturn;\n\t}\n\n\t/* Cannot use half-float or float, encode as full IEEE double. */\n\tp = enc_ctx->ptr;\n\t*p++ = 0xfbU;\n\tduk__cbor_write_double_big(p, d);\n\tp += 8;\n\tenc_ctx->ptr = p;\n}\n\nstatic void duk__cbor_encode_double(duk_cbor_encode_context *enc_ctx, double d) {\n\tduk_uint8_t *p;\n\tdouble d_floor;\n\n\t/* Integers and floating point values of all types are conceptually\n\t * equivalent in CBOR.  Try to always choose the shortest encoding\n\t * which is not always immediately obvious.  For example, NaN and Inf\n\t * can be most compactly represented as a half-float (assuming NaN\n\t * bits are not preserved), and 0x1'0000'0000 as a single precision\n\t * float.  Shortest forms in preference order (prefer integer over\n\t * float when equal length):\n\t *\n\t *   uint        1 byte    [0,23] (not -0)\n\t *   sint        1 byte    [-24,-1]\n\t *   uint+1      2 bytes   [24,255]\n\t *   sint+1      2 bytes   [-256,-25]\n\t *   uint+2      3 bytes   [256,65535]\n\t *   sint+2      3 bytes   [-65536,-257]\n\t *   half-float  3 bytes   -0, NaN, +/- Infinity, range [-65504,65504]\n\t *   uint+4      5 bytes   [65536,4294967295]\n\t *   sint+4      5 bytes   [-4294967296,-258]\n\t *   float       5 bytes   range [-(1 - 2^(-24)) * 2^128, (1 - 2^(-24)) * 2^128]\n\t *   uint+8      9 bytes   [4294967296,18446744073709551615]\n\t *   sint+8      9 bytes   [-18446744073709551616,-4294967297]\n\t *   double      9 bytes\n\t *\n\t * For whole numbers (compatible with integers):\n\t *   - 1-byte or 2-byte uint/sint representation is preferred for\n\t *     [-256,255].\n\t *   - 3-byte uint/sint is preferred for [-65536,65535].  Half floats\n\t *     are never preferred because they have the same length.\n\t *   - 5-byte uint/sint is preferred for [-4294967296,4294967295].\n\t *     Single precision floats are never preferred, and half-floats\n\t *     don't reach above the 3-byte uint/sint range so they're never\n\t *     preferred.\n\t *   - So, for all integers up to signed/unsigned 32-bit range the\n\t *     preferred encoding is always an integer uint/sint.\n\t *   - For integers above 32 bits the situation is more complicated.\n\t *     Half-floats are never useful for them because of their limited\n\t *     range, but IEEE single precision floats (5 bytes encoded) can\n\t *     represent some integers between the 32-bit and 64-bit ranges\n\t *     which require 9 bytes as a uint/sint.\n\t *\n\t * For floating point values not compatible with integers, the\n\t * preferred encoding is quite clear:\n\t *   - For +Inf/-Inf use half-float.\n\t *   - For NaN use a half-float, assuming NaN bits (\"payload\") is\n\t *     not worth preserving.  Duktape doesn't in general guarantee\n\t *     preservation of the NaN payload so using a half-float seems\n\t *     consistent with that.\n\t *   - For remaining values, prefer the shortest form which doesn't\n\t *     lose any precision.  For normal half-floats and single precision\n\t *     floats this is simple: just check exponent and mantissa bits\n\t *     using a fixed mask.  For denormal half-floats and single\n\t *     precision floats the check is a bit more complicated: a normal\n\t *     IEEE double can sometimes be represented as a denormal\n\t *     half-float or single precision float.\n\t *\n\t * https://en.wikipedia.org/wiki/Half-precision_floating-point_format#IEEE_754_half-precision_binary_floating-point_format:_binary16\n\t */\n\n\t/* Caller must ensure space. */\n\tDUK_CBOR_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8);\n\n\t/* Most important path is integers.  The floor() test will be true\n\t * for Inf too (but not NaN).\n\t */\n\td_floor = floor(d);  /* identity if d is +/- 0.0, NaN, or +/- Infinity */\n\tif (DUK_CBOR_LIKELY(d_floor == d)) {\n\t\tDUK_CBOR_ASSERT(!duk__cbor_isnan(d));  /* NaN == NaN compares false. */\n\t\tif (duk__cbor_signbit(d)) {\n\t\t\tif (d >= -4294967296.0) {\n\t\t\t\td = -1.0 - d;\n\t\t\t\tif (d >= 0.0) {\n\t\t\t\t\tDUK_CBOR_ASSERT(d >= 0.0);\n\t\t\t\t\tduk__cbor_encode_uint32(enc_ctx, duk__cbor_double_to_uint32(d), 0x20U);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t/* Input was negative zero, d == -1.0 < 0.0.\n\t\t\t\t * Shortest -0 is using half-float.\n\t\t\t\t */\n\t\t\t\tp = enc_ctx->ptr;\n\t\t\t\t*p++ = 0xf9U;\n\t\t\t\t*p++ = 0x80U;\n\t\t\t\t*p++ = 0x00U;\n\t\t\t\tenc_ctx->ptr = p;\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\tif (d <= 4294967295.0) {\n\t\t\t\t/* Positive zero needs no special handling. */\n\t\t\t\tDUK_CBOR_ASSERT(d >= 0.0);\n\t\t\t\tduk__cbor_encode_uint32(enc_ctx, duk__cbor_double_to_uint32(d), 0x00U);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t/* 64-bit integers are not supported at present.  So\n\t * we also don't need to deal with choosing between a\n\t * 64-bit uint/sint representation vs. IEEE double or\n\t * float.\n\t */\n\n\tDUK_CBOR_ASSERT(duk__cbor_fpclassify(d) != FP_ZERO);\n\tduk__cbor_encode_double_fp(enc_ctx, d);\n}\n#endif  /* DUK_CBOR_DOUBLE_AS_IS */\n\nstatic void duk__cbor_encode_string_top(duk_cbor_encode_context *enc_ctx) {\n\tconst duk_uint8_t *str;\n\tduk_size_t len;\n\tduk_uint8_t *p;\n\n\t/* CBOR differentiates between UTF-8 text strings and byte strings.\n\t * Text strings MUST be valid UTF-8, so not all Duktape strings can\n\t * be encoded as valid CBOR text strings.  Possible behaviors:\n\t *\n\t *   1. Use text string when input is valid UTF-8, otherwise use\n\t *      byte string (maybe tagged to indicate it was an extended\n\t *      UTF-8 string).\n\t *   2. Always use text strings, but sanitize input string so that\n\t *      invalid UTF-8 is replaced with U+FFFD for example.  Combine\n\t *      surrogates whenever possible.\n\t *   3. Always use byte strings.  This is simple and produces valid\n\t *      CBOR, but isn't ideal for interoperability.\n\t *   4. Always use text strings, even for invalid UTF-8 such as\n\t *      codepoints in the surrogate pair range.  This is simple but\n\t *      produces technically invalid CBOR for non-UTF-8 strings which\n\t *      may affect interoperability.\n\t *\n\t * Current default is 1; can be changed with defines.\n\t */\n\n\t/* Caller must ensure space. */\n\tDUK_CBOR_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8);\n\n\tstr = (const duk_uint8_t *) duk_require_lstring(enc_ctx->ctx, -1, &len);\n\tif (duk_is_symbol(enc_ctx->ctx, -1)) {\n\t\t/* Symbols, encode as an empty table for now.  This matches\n\t\t * the behavior of cbor-js.\n\t\t *\n\t\t * XXX: Maybe encode String() coercion with a tag?\n\t\t * XXX: Option to keep enough information to recover\n\t\t * Symbols when decoding (this is not always desirable).\n\t\t */\n\t\tp = enc_ctx->ptr;\n\t\t*p++ = 0xa0U;\n\t\tenc_ctx->ptr = p;\n\t\treturn;\n\t}\n\n\tduk__cbor_encode_sizet_uint32_check(enc_ctx, len);\n#if defined(DUK_CBOR_TEXT_STRINGS)\n\tduk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len, 0x60U);\n#elif defined(DUK_CBOR_BYTE_STRINGS)\n\tduk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len, 0x40U);\n#else\n\tduk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len,\n\t                        (DUK_CBOR_LIKELY(duk__cbor_is_utf8_compatible(str, len)) ? 0x60U : 0x40U));\n#endif\n\tduk__cbor_encode_ensure(enc_ctx, len);\n\tp = enc_ctx->ptr;\n\t(void) memcpy((void *) p, (const void *) str, len);\n\tp += len;\n\tenc_ctx->ptr = p;\n}\n\nstatic void duk__cbor_encode_object(duk_cbor_encode_context *enc_ctx) {\n\tduk_uint8_t *buf;\n\tduk_size_t len;\n\tduk_uint8_t *p;\n\tduk_size_t i;\n\tduk_size_t off_ib;\n\tduk_uint32_t count;\n\n\t/* Caller must ensure space. */\n\tDUK_CBOR_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8);\n\n\t/* XXX: Support for specific built-ins like Date and RegExp. */\n\tif (duk_is_array(enc_ctx->ctx, -1)) {\n\t\t/* Shortest encoding for arrays >= 256 in length is actually\n\t\t * the indefinite length one (3 or more bytes vs. 2 bytes).\n\t\t * We still use the definite length version because it is\n\t\t * more decoding friendly.\n\t\t */\n\t\tlen = duk_get_length(enc_ctx->ctx, -1);\n\t\tduk__cbor_encode_sizet_uint32_check(enc_ctx, len);\n\t\tduk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len, 0x80U);\n\t\tfor (i = 0; i < len; i++) {\n\t\t\tduk_get_prop_index(enc_ctx->ctx, -1, (duk_uarridx_t) i);\n\t\t\tduk__cbor_encode_value(enc_ctx);\n\t\t}\n\t} else if (duk_is_buffer_data(enc_ctx->ctx, -1)) {\n\t\t/* XXX: Tag buffer data?\n\t\t * XXX: Encode typed arrays as integer arrays rather\n\t\t * than buffer data as is?\n\t\t */\n\t\tbuf = (duk_uint8_t *) duk_require_buffer_data(enc_ctx->ctx, -1, &len);\n\t\tduk__cbor_encode_sizet_uint32_check(enc_ctx, len);\n\t\tduk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len, 0x40U);\n\t\tduk__cbor_encode_ensure(enc_ctx, len);\n\t\tp = enc_ctx->ptr;\n\t\t(void) memcpy((void *) p, (const void *) buf, len);\n\t\tp += len;\n\t\tenc_ctx->ptr = p;\n\t} else {\n\t\t/* We don't know the number of properties in advance\n\t\t * but would still like to encode at least small\n\t\t * objects without indefinite length.  Emit an\n\t\t * indefinite length byte initially, and if the final\n\t\t * property count is small enough to also fit in one\n\t\t * byte, backpatch it later.  Otherwise keep the\n\t\t * indefinite length.  This works well up to 23\n\t\t * properties which is practical and good enough.\n\t\t */\n\t\toff_ib = (duk_size_t) (enc_ctx->ptr - enc_ctx->buf);  /* XXX: get_offset? */\n\t\tcount = 0U;\n\t\tp = enc_ctx->ptr;\n\t\t*p++ = 0xa0U + 0x1fU;  /* indefinite length */\n\t\tenc_ctx->ptr = p;\n\t\tduk_enum(enc_ctx->ctx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY);\n\t\twhile (duk_next(enc_ctx->ctx, -1, 1 /*get_value*/)) {\n\t\t\tduk_insert(enc_ctx->ctx, -2);  /* [ ... key value ] -> [ ... value key ] */\n\t\t\tduk__cbor_encode_value(enc_ctx);\n\t\t\tduk__cbor_encode_value(enc_ctx);\n\t\t\tcount++;\n\t\t\tif (count == 0U) {\n\t\t\t\tduk__cbor_encode_error(enc_ctx);\n\t\t\t}\n\t\t}\n\t\tduk_pop(enc_ctx->ctx);\n\t\tif (count <= 0x17U) {\n\t\t\tDUK_CBOR_ASSERT(off_ib < enc_ctx->len);\n\t\t\tenc_ctx->buf[off_ib] = 0xa0U + (duk_uint8_t) count;\n\t\t} else {\n\t\t\tduk__cbor_encode_ensure(enc_ctx, 1);\n\t\t\tp = enc_ctx->ptr;\n\t\t\t*p++ = 0xffU;  /* break */\n\t\t\tenc_ctx->ptr = p;\n\t\t}\n\t}\n}\n\nstatic void duk__cbor_encode_buffer(duk_cbor_encode_context *enc_ctx) {\n\tduk_uint8_t *buf;\n\tduk_size_t len;\n\tduk_uint8_t *p;\n\n\t/* Caller must ensure space. */\n\tDUK_CBOR_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8);\n\n\t/* Tag buffer data? */\n\tbuf = (duk_uint8_t *) duk_require_buffer(enc_ctx->ctx, -1, &len);\n\tduk__cbor_encode_sizet_uint32_check(enc_ctx, len);\n\tduk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len, 0x40U);\n\tduk__cbor_encode_ensure(enc_ctx, len);\n\tp = enc_ctx->ptr;\n\t(void) memcpy((void *) p, (const void *) buf, len);\n\tp += len;\n\tenc_ctx->ptr = p;\n}\n\nstatic void duk__cbor_encode_pointer(duk_cbor_encode_context *enc_ctx) {\n\t/* Pointers (void *) are challenging to encode.  They can't\n\t * be relied to be even 64-bit integer compatible (there are\n\t * pointer models larger than that), nor can floats encode\n\t * them.  They could be encoded as strings (%p format) but\n\t * that's not portable.  They could be encoded as direct memory\n\t * representations.  Recovering pointers is non-portable in any\n\t * case but it would be nice to be able to detect and recover\n\t * compatible pointers.\n\t *\n\t * For now, encode as \"(%p)\" string, matching JX.  There doesn't\n\t * seem to be an appropriate tag, so pointers don't currently\n\t * survive a CBOR encode/decode roundtrip intact.\n\t */\n\tconst char *ptr;\n\n\tptr = duk_to_string(enc_ctx->ctx, -1);\n\tDUK_CBOR_ASSERT(ptr != NULL);\n\tduk_push_sprintf(enc_ctx->ctx, \"(%s)\", ptr);\n\tduk_remove(enc_ctx->ctx, -2);\n\tduk__cbor_encode_string_top(enc_ctx);\n}\n\nstatic void duk__cbor_encode_lightfunc(duk_cbor_encode_context *enc_ctx) {\n\tduk_uint8_t *p;\n\n\t/* Caller must ensure space. */\n\tDUK_CBOR_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8);\n\n\t/* For now encode as an empty object. */\n\tp = enc_ctx->ptr;\n\t*p++ = 0xa0U;\n\tenc_ctx->ptr = p;\n}\n\nstatic void duk__cbor_encode_value(duk_cbor_encode_context *enc_ctx) {\n\tduk_uint8_t *p;\n\n\t/* Encode/decode cycle currently loses some type information.\n\t * This can be improved by registering custom tags with IANA.\n\t */\n\n\t/* When working with deeply recursive structures, this is important\n\t * to ensure there's no effective depth limit.\n\t */\n\tduk_require_stack(enc_ctx->ctx, 4);\n\n\t/* Reserve space for up to 64-bit types (1 initial byte + 8\n\t * followup bytes).  This allows encoding of integers, floats,\n\t * string/buffer length fields, etc without separate checks\n\t * in each code path.\n\t */\n\tduk__cbor_encode_ensure(enc_ctx, 1 + 8);\n\n\tswitch (duk_get_type(enc_ctx->ctx, -1)) {\n\tcase DUK_TYPE_UNDEFINED: {\n\t\tp = enc_ctx->ptr;\n\t\t*p++ = 0xf7;\n\t\tenc_ctx->ptr = p;\n\t\tbreak;\n\t}\n\tcase DUK_TYPE_NULL: {\n\t\tp = enc_ctx->ptr;\n\t\t*p++ = 0xf6;\n\t\tenc_ctx->ptr = p;\n\t\tbreak;\n\t}\n\tcase DUK_TYPE_BOOLEAN: {\n\t\tduk_uint8_t u8 = duk_get_boolean(enc_ctx->ctx, -1) ? 0xf5U : 0xf4U;\n\t\tp = enc_ctx->ptr;\n\t\t*p++ = u8;\n\t\tenc_ctx->ptr = p;\n\t\tbreak;\n\t}\n\tcase DUK_TYPE_NUMBER: {\n\t\tduk__cbor_encode_double(enc_ctx, duk_get_number(enc_ctx->ctx, -1));\n\t\tbreak;\n\t}\n\tcase DUK_TYPE_STRING: {\n\t\tduk__cbor_encode_string_top(enc_ctx);\n\t\tbreak;\n\t}\n\tcase DUK_TYPE_OBJECT: {\n\t\tduk__cbor_encode_object(enc_ctx);\n\t\tbreak;\n\t}\n\tcase DUK_TYPE_BUFFER: {\n\t\tduk__cbor_encode_buffer(enc_ctx);\n\t\tbreak;\n\t}\n\tcase DUK_TYPE_POINTER: {\n\t\tduk__cbor_encode_pointer(enc_ctx);\n\t\tbreak;\n\t}\n\tcase DUK_TYPE_LIGHTFUNC: {\n\t\tduk__cbor_encode_lightfunc(enc_ctx);\n\t\tbreak;\n\t}\n\tcase DUK_TYPE_NONE:\n\tdefault:\n\t\tgoto fail;\n\t}\n\n\tduk_pop(enc_ctx->ctx);\n\treturn;\n\n fail:\n\tduk__cbor_encode_error(enc_ctx);\n}\n\n/*\n *  Decoding\n */\n\nstatic void duk__cbor_req_stack(duk_cbor_decode_context *dec_ctx) {\n\tduk_require_stack(dec_ctx->ctx, 4);\n}\n\nstatic void duk__cbor_decode_error(duk_cbor_decode_context *dec_ctx) {\n\t(void) duk_type_error(dec_ctx->ctx, \"cbor decode error\");\n}\n\nstatic duk_uint8_t duk__cbor_decode_readbyte(duk_cbor_decode_context *dec_ctx) {\n\tDUK_CBOR_ASSERT(dec_ctx->off <= dec_ctx->len);\n\tif (DUK_CBOR_UNLIKELY(dec_ctx->len - dec_ctx->off < 1U)) {\n\t\tduk__cbor_decode_error(dec_ctx);\n\t}\n\treturn dec_ctx->buf[dec_ctx->off++];\n}\n\nstatic duk_uint16_t duk__cbor_decode_read_u16(duk_cbor_decode_context *dec_ctx) {\n\tduk_uint16_t res;\n\n\tif (DUK_CBOR_UNLIKELY(dec_ctx->len - dec_ctx->off < 2U)) {\n\t\tduk__cbor_decode_error(dec_ctx);\n\t}\n\tres = duk__cbor_read_uint16_big(dec_ctx->buf + dec_ctx->off);\n\tdec_ctx->off += 2;\n\treturn res;\n}\n\nstatic duk_uint32_t duk__cbor_decode_read_u32(duk_cbor_decode_context *dec_ctx) {\n\tduk_uint32_t res;\n\n\tif (DUK_CBOR_UNLIKELY(dec_ctx->len - dec_ctx->off < 4U)) {\n\t\tduk__cbor_decode_error(dec_ctx);\n\t}\n\tres = duk__cbor_read_uint32_big(dec_ctx->buf + dec_ctx->off);\n\tdec_ctx->off += 4;\n\treturn res;\n}\n\nstatic duk_uint8_t duk__cbor_decode_peekbyte(duk_cbor_decode_context *dec_ctx) {\n\tif (DUK_CBOR_UNLIKELY(dec_ctx->off >= dec_ctx->len)) {\n\t\tduk__cbor_decode_error(dec_ctx);\n\t}\n\treturn dec_ctx->buf[dec_ctx->off];\n}\n\nstatic void duk__cbor_decode_rewind(duk_cbor_decode_context *dec_ctx, duk_size_t len) {\n\tDUK_CBOR_ASSERT(len <= dec_ctx->off);  /* Caller must ensure. */\n\tdec_ctx->off -= len;\n}\n\n#if 0\nstatic void duk__cbor_decode_ensure(duk_cbor_decode_context *dec_ctx, duk_size_t len) {\n\tif (dec_ctx->off + len > dec_ctx->len) {\n\t\tduk__cbor_decode_error(dec_ctx);\n\t}\n}\n#endif\n\nstatic const duk_uint8_t *duk__cbor_decode_consume(duk_cbor_decode_context *dec_ctx, duk_size_t len) {\n\tDUK_CBOR_ASSERT(dec_ctx->off <= dec_ctx->len);\n\tif (DUK_CBOR_LIKELY(dec_ctx->len - dec_ctx->off >= len)) {\n\t\tconst duk_uint8_t *res = dec_ctx->buf + dec_ctx->off;\n\t\tdec_ctx->off += len;\n\t\treturn res;\n\t}\n\n\tduk__cbor_decode_error(dec_ctx);  /* Not enough input. */\n\treturn NULL;\n}\n\nstatic int duk__cbor_decode_checkbreak(duk_cbor_decode_context *dec_ctx) {\n\tif (duk__cbor_decode_peekbyte(dec_ctx) == 0xffU) {\n\t\tDUK_CBOR_ASSERT(dec_ctx->off < dec_ctx->len);\n\t\tdec_ctx->off++;\n#if 0\n\t\t(void) duk__cbor_decode_readbyte(dec_ctx);\n#endif\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nstatic void duk__cbor_decode_push_aival_int(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib, duk_bool_t negative) {\n\tduk_uint8_t ai;\n\tduk_uint32_t t, t1, t2;\n#if 0\n\tduk_uint64_t t3;\n#endif\n\tduk_double_t d1, d2;\n\tduk_double_t d;\n\n\tai = ib & 0x1fU;\n\tif (ai <= 0x17U) {\n\t\tt = ai;\n\t\tgoto shared_exit;\n\t}\n\n\tswitch (ai) {\n\tcase 0x18U:  /* 1 byte */\n\t\tt = (duk_uint32_t) duk__cbor_decode_readbyte(dec_ctx);\n\t\tgoto shared_exit;\n\tcase 0x19U:  /* 2 byte */\n\t\tt = (duk_uint32_t) duk__cbor_decode_read_u16(dec_ctx);\n\t\tgoto shared_exit;\n\tcase 0x1aU:  /* 4 byte */\n\t\tt = (duk_uint32_t) duk__cbor_decode_read_u32(dec_ctx);\n\t\tgoto shared_exit;\n\tcase 0x1bU:  /* 8 byte */\n\t\t/* For uint64 it's important to handle the -1.0 part before\n\t\t * casting to double: otherwise the adjustment might be lost\n\t\t * in the cast.  Uses: -1.0 - d <=> -(d + 1.0).\n\t\t */\n\t\tt = (duk_uint32_t) duk__cbor_decode_read_u32(dec_ctx);\n\t\tt2 = t;\n\t\tt = (duk_uint32_t) duk__cbor_decode_read_u32(dec_ctx);\n\t\tt1 = t;\n#if 0\n\t\tt3 = (duk_uint64_t) t2 * 0x100000000ULL + (duk_uint64_t) t1;\n\t\tif (negative) {\n\t\t\tif (t3 == DUK_UINT64_MAX) {\n\t\t\t\t/* -(0xffff'ffff'ffff'ffffULL + 1) =\n\t\t\t\t * -0x1'0000'0000'0000'0000\n\t\t\t\t *\n\t\t\t\t * >>> -0x10000000000000000\n\t\t\t\t * -18446744073709551616L\n\t\t\t\t */\n\t\t\t\treturn -18446744073709551616.0;\n\t\t\t} else {\n\t\t\t\treturn -((duk_double_t) (t3 + 1ULL));\n\t\t\t}\n\t\t} else {\n\t\t\treturn (duk_double_t) t3;  /* XXX: cast helper */\n\t\t}\n#endif\n#if 0\n\t\tt3 = (duk_uint64_t) t2 * 0x100000000ULL + (duk_uint64_t) t1;\n\t\tif (negative) {\n\t\t\t/* Simpler version: take advantage of the fact that\n\t\t\t * 0xffff'ffff'ffff'ffff and 0x1'0000'0000'0000'0000\n\t\t\t * both round to 0x1'0000'0000'0000'0000:\n\t\t\t * > (0xffffffffffffffff).toString(16)\n\t\t\t * '10000000000000000'\n\t\t\t * > (0x10000000000000000).toString(16)\n\t\t\t * '10000000000000000'\n\t\t\t *\n\t\t\t * For the DUK_UINT64_MAX case we just skip the +1\n\t\t\t * increment to avoid wrapping; the result still\n\t\t\t * comes out right for an IEEE double cast.\n\t\t\t */\n\t\t\tif (t3 != DUK_UINT64_MAX) {\n\t\t\t\tt3++;\n\t\t\t}\n\t\t\treturn -((duk_double_t) t3);\n\t\t} else {\n\t\t\treturn (duk_double_t) t3;  /* XXX: cast helper */\n\t\t}\n#endif\n#if 1\n\t\t/* Use two double parts, avoids dependency on 64-bit type.\n\t\t * Avoid precision loss carefully, especially when dealing\n\t\t * with the required +1 for negative values.\n\t\t *\n\t\t * No fastint check for this path at present.\n\t\t */\n\t\td1 = (duk_double_t) t1;  /* XXX: cast helpers */\n\t\td2 = (duk_double_t) t2 * 4294967296.0;\n\t\tif (negative) {\n\t\t\td1 += 1.0;\n\t\t}\n\t\td = d2 + d1;\n\t\tif (negative) {\n\t\t\td = -d;\n\t\t}\n#endif\n\t\t/* XXX: a push and check for fastint API would be nice */\n\t\tduk_push_number(dec_ctx->ctx, d);\n\t\treturn;\n\t}\n\n\tduk__cbor_decode_error(dec_ctx);\n\treturn;\n\n shared_exit:\n\tif (negative) {\n\t\t/* XXX: a push and check for fastint API would be nice */\n\t\tif ((duk_uint_t) t <= (duk_uint_t) -(DUK_INT_MIN + 1)) {\n\t\t\tduk_push_int(dec_ctx->ctx, -1 - ((duk_int_t) t));\n\t\t} else {\n\t\t\tduk_push_number(dec_ctx->ctx, -1.0 - (duk_double_t) t);\n\t\t}\n\t} else {\n\t\tduk_push_uint(dec_ctx->ctx, (duk_uint_t) t);\n\t}\n}\n\nstatic void duk__cbor_decode_skip_aival_int(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib) {\n\tconst duk_int8_t skips[32] = {\n\t\t0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n\t\t0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 8, -1, -1, -1, -1\n\t};\n\tduk_uint8_t ai;\n\tduk_int8_t skip;\n\n\tai = ib & 0x1fU;\n\tskip = skips[ai];\n\tif (DUK_UNLIKELY(skip < 0)) {\n\t\tduk__cbor_decode_error(dec_ctx);\n\t}\n\tduk__cbor_decode_consume(dec_ctx, (duk_size_t) skip);\n\treturn;\n}\n\nstatic duk_uint32_t duk__cbor_decode_aival_uint32(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib) {\n\tduk_uint8_t ai;\n\tduk_uint32_t t;\n\n\tai = ib & 0x1fU;\n\tif (ai <= 0x17U) {\n\t\treturn (duk_uint32_t) ai;\n\t}\n\n\tswitch (ai) {\n\tcase 0x18U:  /* 1 byte */\n\t\tt = (duk_uint32_t) duk__cbor_decode_readbyte(dec_ctx);\n\t\treturn t;\n\tcase 0x19U:  /* 2 byte */\n\t\tt = (duk_uint32_t) duk__cbor_decode_read_u16(dec_ctx);\n\t\treturn t;\n\tcase 0x1aU:  /* 4 byte */\n\t\tt = (duk_uint32_t) duk__cbor_decode_read_u32(dec_ctx);\n\t\treturn t;\n\tcase 0x1bU:  /* 8 byte */\n\t\tt = (duk_uint32_t) duk__cbor_decode_read_u32(dec_ctx);\n\t\tif (t != 0U) {\n\t\t\tbreak;\n\t\t}\n\t\tt = (duk_uint32_t) duk__cbor_decode_read_u32(dec_ctx);\n\t\treturn t;\n\t}\n\n\tduk__cbor_decode_error(dec_ctx);\n\treturn 0U;\n}\n\nstatic void duk__cbor_decode_buffer(duk_cbor_decode_context *dec_ctx, duk_uint8_t expected_base) {\n\tduk_uint32_t len;\n\tduk_uint8_t *buf;\n\tconst duk_uint8_t *inp;\n\tduk_uint8_t ib;\n\n\tib = duk__cbor_decode_readbyte(dec_ctx);\n\tif ((ib & 0xe0U) != expected_base) {\n\t\tduk__cbor_decode_error(dec_ctx);\n\t}\n\t/* Indefinite format is rejected by the following on purpose. */\n\tlen = duk__cbor_decode_aival_uint32(dec_ctx, ib);\n\tinp = duk__cbor_decode_consume(dec_ctx, len);\n\t/* XXX: duk_push_fixed_buffer_with_data() would be a nice API addition. */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer(dec_ctx->ctx, (duk_size_t) len);\n\t(void) memcpy((void *) buf, (const void *) inp, (size_t) len);\n}\n\nstatic void duk__cbor_decode_join_buffers(duk_cbor_decode_context *dec_ctx, duk_idx_t count) {\n\tduk_size_t total_size = 0;\n\tduk_idx_t top = duk_get_top(dec_ctx->ctx);\n\tduk_idx_t base = top - count;  /* count is >= 1 */\n\tduk_idx_t idx;\n\tduk_uint8_t *p = NULL;\n\n\tDUK_CBOR_ASSERT(count >= 1);\n\tDUK_CBOR_ASSERT(top >= count);\n\n\tfor (;;) {\n\t\t/* First round: compute total size.\n\t\t * Second round: copy into place.\n\t\t */\n\t\tfor (idx = base; idx < top; idx++) {\n\t\t\tduk_uint8_t *buf_data;\n\t\t\tduk_size_t buf_size;\n\n\t\t\tbuf_data = (duk_uint8_t *) duk_require_buffer(dec_ctx->ctx, idx, &buf_size);\n\t\t\tif (p != NULL) {\n\t\t\t\tif (buf_size > 0U) {\n\t\t\t\t\t(void) memcpy((void *) p, (const void *) buf_data, buf_size);\n\t\t\t\t}\n\t\t\t\tp += buf_size;\n\t\t\t} else {\n\t\t\t\ttotal_size += buf_size;\n\t\t\t\tif (DUK_CBOR_UNLIKELY(total_size < buf_size)) {  /* Wrap check. */\n\t\t\t\t\tduk__cbor_decode_error(dec_ctx);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (p != NULL) {\n\t\t\tbreak;\n\t\t} else {\n\t\t\tp = (duk_uint8_t *) duk_push_fixed_buffer(dec_ctx->ctx, total_size);\n\t\t\tDUK_CBOR_ASSERT(p != NULL);\n\t\t}\n\t}\n\n\tduk_replace(dec_ctx->ctx, base);\n\tduk_pop_n(dec_ctx->ctx, count - 1);\n}\n\nstatic void duk__cbor_decode_and_join_strbuf(duk_cbor_decode_context *dec_ctx, duk_uint8_t expected_base) {\n\tduk_idx_t count = 0;\n\tfor (;;) {\n\t\tif (duk__cbor_decode_checkbreak(dec_ctx)) {\n\t\t\tbreak;\n\t\t}\n\t\tduk_require_stack(dec_ctx->ctx, 1);\n\t\tduk__cbor_decode_buffer(dec_ctx, expected_base);\n\t\tcount++;\n\t\tif (DUK_UNLIKELY(count <= 0)) {  /* Wrap check. */\n\t\t\tduk__cbor_decode_error(dec_ctx);\n\t\t}\n\t}\n\tif (count == 0) {\n\t\t(void) duk_push_fixed_buffer(dec_ctx->ctx, 0);\n\t} else if (count > 1) {\n\t\tduk__cbor_decode_join_buffers(dec_ctx, count);\n\t}\n}\n\nstatic duk_double_t duk__cbor_decode_half_float(duk_cbor_decode_context *dec_ctx) {\n\tduk_cbor_dblunion u;\n\tconst duk_uint8_t *inp;\n\tduk_int_t exp;\n\tduk_uint_t u16;\n\tduk_uint_t tmp;\n\tduk_double_t res;\n\n\tinp = duk__cbor_decode_consume(dec_ctx, 2);\n\tu16 = ((duk_uint_t) inp[0] << 8) + (duk_uint_t) inp[1];\n\texp = (duk_int_t) ((u16 >> 10) & 0x1fU) - 15;\n\n\t/* Reconstruct IEEE double into little endian order first, then convert\n\t * to host order.\n\t */\n\n\tmemset((void *) &u, 0, sizeof(u));\n\n\tif (exp == -15) {\n\t\t/* Zero or denormal; but note that half float\n\t\t * denormals become double normals.\n\t\t */\n\t\tif ((u16 & 0x03ffU) == 0) {\n\t\t\tu.x[7] = inp[0] & 0x80U;\n\t\t} else {\n\t\t\t/* Create denormal by first creating a double that\n\t\t\t * contains the denormal bits and a leading implicit\n\t\t\t * 1-bit.  Then subtract away the implicit 1-bit.\n\t\t\t *\n\t\t\t *    0.mmmmmmmmmm * 2^-14\n\t\t\t *    1.mmmmmmmmmm 0.... * 2^-14\n\t\t\t *   -1.0000000000 0.... * 2^-14\n\t\t\t *\n\t\t\t * Double exponent: -14 + 1023 = 0x3f1\n\t\t\t */\n\t\t\tu.x[7] = 0x3fU;\n\t\t\tu.x[6] = 0x10U + (duk_uint8_t) ((u16 >> 6) & 0x0fU);\n\t\t\tu.x[5] = (duk_uint8_t) ((u16 << 2) & 0xffU);  /* Mask is really 0xfcU */\n\n\t\t\tduk__cbor_dblunion_little_to_host(&u);\n\t\t\tres = u.d - 0.00006103515625;  /* 2^(-14) */\n\t\t\tif (u16 & 0x8000U) {\n\t\t\t\tres = -res;\n\t\t\t}\n\t\t\treturn res;\n\t\t}\n\t} else if (exp == 16) {\n\t\t/* +/- Inf or NaN. */\n\t\tif ((u16 & 0x03ffU) == 0) {\n\t\t\tu.x[7] = (inp[0] & 0x80U) + 0x7fU;\n\t\t\tu.x[6] = 0xf0U;\n\t\t} else {\n\t\t\t/* Create a 'quiet NaN' with highest\n\t\t\t * bit set (there are some platforms\n\t\t\t * where the NaN payload convention is\n\t\t\t * the opposite).  Keep sign.\n\t\t\t */\n\t\t\tu.x[7] = (inp[0] & 0x80U) + 0x7fU;\n\t\t\tu.x[6] = 0xf8U;\n\t\t}\n\t} else {\n\t\t/* Normal. */\n\t\ttmp = (inp[0] & 0x80U) ? 0x80000000UL : 0UL;\n\t\ttmp += (duk_uint_t) (exp + 1023) << 20;\n\t\ttmp += (duk_uint_t) (inp[0] & 0x03U) << 18;\n\t\ttmp += (duk_uint_t) (inp[1] & 0xffU) << 10;\n\t\tu.x[7] = (tmp >> 24) & 0xffU;\n\t\tu.x[6] = (tmp >> 16) & 0xffU;\n\t\tu.x[5] = (tmp >> 8) & 0xffU;\n\t\tu.x[4] = (tmp >> 0) & 0xffU;\n\t}\n\n\tduk__cbor_dblunion_little_to_host(&u);\n\treturn u.d;\n}\n\nstatic void duk__cbor_decode_string(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib, duk_uint8_t ai) {\n\t/* If the CBOR string data is not valid UTF-8 it is technically\n\t * invalid CBOR.  Possible behaviors at least:\n\t *\n\t *   1. Reject the input, i.e. throw TypeError.\n\t *\n\t *   2. Accept the input, but sanitize non-UTF-8 data into UTF-8\n\t *      using U+FFFD replacements.  Also it might make sense to\n\t *      decode non-BMP codepoints into surrogates for better\n\t *      ECMAScript compatibility.\n\t *\n\t *   3. Accept the input as a Duktape string (which are not always\n\t *      valid UTF-8), but reject any input that would create a\n\t *      Symbol representation.\n\t *\n\t * Current behavior is 3.\n\t */\n\n\tif (ai == 0x1fU) {\n\t\tduk_uint8_t *buf_data;\n\t\tduk_size_t buf_size;\n\n\t\tduk__cbor_decode_and_join_strbuf(dec_ctx, 0x60U);\n\t\tbuf_data = (duk_uint8_t *) duk_require_buffer(dec_ctx->ctx, -1, &buf_size);\n\t\t(void) duk_push_lstring(dec_ctx->ctx, (const char *) buf_data, buf_size);\n\t\tduk_remove(dec_ctx->ctx, -2);\n\t} else {\n\t\tduk_uint32_t len;\n\t\tconst duk_uint8_t *inp;\n\n\t\tlen = duk__cbor_decode_aival_uint32(dec_ctx, ib);\n\t\tinp = duk__cbor_decode_consume(dec_ctx, len);\n\t\t(void) duk_push_lstring(dec_ctx->ctx, (const char *) inp, (duk_size_t) len);\n\t}\n\tif (duk_is_symbol(dec_ctx->ctx, -1)) {\n\t\t/* Refuse to create Symbols when decoding. */\n\t\tduk__cbor_decode_error(dec_ctx);\n\t}\n\n\t/* XXX: Here a Duktape API call to convert input -> utf-8 with\n\t * replacements would be nice.\n\t */\n}\n\nstatic duk_bool_t duk__cbor_decode_array(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib, duk_uint8_t ai) {\n\tduk_uint32_t idx, len;\n\n\tduk__cbor_req_stack(dec_ctx);\n\n\t/* Support arrays up to 0xfffffffeU in length.  0xffffffff is\n\t * used as an indefinite length marker.\n\t */\n\tif (ai == 0x1fU) {\n\t\tlen = 0xffffffffUL;\n\t} else {\n\t\tlen = duk__cbor_decode_aival_uint32(dec_ctx, ib);\n\t\tif (len == 0xffffffffUL) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* XXX: use bare array? */\n\tduk_push_array(dec_ctx->ctx);\n\tfor (idx = 0U; ;) {\n\t\tif (len == 0xffffffffUL && duk__cbor_decode_checkbreak(dec_ctx)) {\n\t\t\tbreak;\n\t\t}\n\t\tif (idx == len) {\n\t\t\tif (ai == 0x1fU) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tduk__cbor_decode_value(dec_ctx);\n\t\tduk_put_prop_index(dec_ctx->ctx, -2, (duk_uarridx_t) idx);\n\t\tidx++;\n\t\tif (idx == 0U) {\n\t\t\treturn 0;  /* wrapped */\n\t\t}\n\t}\n\n\treturn 1;\n}\n\nstatic duk_bool_t duk__cbor_decode_map(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib, duk_uint8_t ai) {\n\tduk_uint32_t count;\n\n\tduk__cbor_req_stack(dec_ctx);\n\n\tif (ai == 0x1fU) {\n\t\tcount = 0xffffffffUL;\n\t} else {\n\t\tcount = duk__cbor_decode_aival_uint32(dec_ctx, ib);\n\t\tif (count == 0xffffffffUL) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* XXX: use bare object? */\n\tduk_push_object(dec_ctx->ctx);\n\tfor (;;) {\n\t\tif (count == 0xffffffffUL) {\n\t\t\tif (duk__cbor_decode_checkbreak(dec_ctx)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (count == 0UL) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcount--;\n\t\t}\n\n\t\t/* Non-string keys are coerced to strings,\n\t\t * possibly leading to overwriting previous\n\t\t * keys.  Last key of a certain coerced name\n\t\t * wins.  If key is an object, it will coerce\n\t\t * to '[object Object]' which is consistent\n\t\t * but potentially misleading.  One alternative\n\t\t * would be to skip non-string keys.\n\t\t */\n\t\tduk__cbor_decode_value(dec_ctx);\n\t\tduk__cbor_decode_value(dec_ctx);\n\t\tduk_put_prop(dec_ctx->ctx, -3);\n\t}\n\n\treturn 1;\n}\n\nstatic duk_double_t duk__cbor_decode_float(duk_cbor_decode_context *dec_ctx) {\n\tduk_cbor_fltunion u;\n\tconst duk_uint8_t *inp;\n\tinp = duk__cbor_decode_consume(dec_ctx, 4);\n\t(void) memcpy((void *) u.x, (const void *) inp, 4);\n\tduk__cbor_fltunion_big_to_host(&u);\n\treturn (duk_double_t) u.f;\n}\n\nstatic duk_double_t duk__cbor_decode_double(duk_cbor_decode_context *dec_ctx) {\n\tduk_cbor_dblunion u;\n\tconst duk_uint8_t *inp;\n\tinp = duk__cbor_decode_consume(dec_ctx, 8);\n\t(void) memcpy((void *) u.x, (const void *) inp, 8);\n\tduk__cbor_dblunion_big_to_host(&u);\n\treturn u.d;\n}\n\n#if defined(DUK_CBOR_DECODE_FASTPATH)\n#define DUK__CBOR_AI  (ib & 0x1fU)\n\nstatic void duk__cbor_decode_value(duk_cbor_decode_context *dec_ctx) {\n\tduk_uint8_t ib;\n\n\t/* Any paths potentially recursing back to duk__cbor_decode_value()\n\t * must perform a Duktape value stack growth check.  Avoid the check\n\t * here for simple paths like primitive values.\n\t */\n\n reread_initial_byte:\n#if defined(DUK_CBOR_DPRINT)\n\tfprintf(stderr, \"cbor decode off=%ld len=%ld\\n\", (long) dec_ctx->off, (long) dec_ctx->len);\n#endif\n\n\tib = duk__cbor_decode_readbyte(dec_ctx);\n\n\t/* Full initial byte switch, footprint cost over baseline is ~+1kB. */\n\t/* XXX: Force full switch with no range check. */\n\n\tswitch (ib) {\n\tcase 0x00U: case 0x01U: case 0x02U: case 0x03U: case 0x04U: case 0x05U: case 0x06U: case 0x07U:\n\tcase 0x08U: case 0x09U: case 0x0aU: case 0x0bU: case 0x0cU: case 0x0dU: case 0x0eU: case 0x0fU:\n\tcase 0x10U: case 0x11U: case 0x12U: case 0x13U: case 0x14U: case 0x15U: case 0x16U: case 0x17U:\n\t\tduk_push_uint(dec_ctx->ctx, ib);\n\t\tbreak;\n\tcase 0x18U: case 0x19U: case 0x1aU: case 0x1bU:\n\t\tduk__cbor_decode_push_aival_int(dec_ctx, ib, 0 /*negative*/);\n\t\tbreak;\n\tcase 0x1cU: case 0x1dU: case 0x1eU: case 0x1fU:\n\t\tgoto format_error;\n\tcase 0x20U: case 0x21U: case 0x22U: case 0x23U: case 0x24U: case 0x25U: case 0x26U: case 0x27U:\n\tcase 0x28U: case 0x29U: case 0x2aU: case 0x2bU: case 0x2cU: case 0x2dU: case 0x2eU: case 0x2fU:\n\tcase 0x30U: case 0x31U: case 0x32U: case 0x33U: case 0x34U: case 0x35U: case 0x36U: case 0x37U:\n\t\tduk_push_int(dec_ctx->ctx, -((duk_int_t) ((ib - 0x20U) + 1U)));\n\t\tbreak;\n\tcase 0x38U: case 0x39U: case 0x3aU: case 0x3bU:\n\t\tduk__cbor_decode_push_aival_int(dec_ctx, ib, 1 /*negative*/);\n\t\tbreak;\n\tcase 0x3cU: case 0x3dU: case 0x3eU: case 0x3fU:\n\t\tgoto format_error;\n\tcase 0x40U: case 0x41U: case 0x42U: case 0x43U: case 0x44U: case 0x45U: case 0x46U: case 0x47U:\n\tcase 0x48U: case 0x49U: case 0x4aU: case 0x4bU: case 0x4cU: case 0x4dU: case 0x4eU: case 0x4fU:\n\tcase 0x50U: case 0x51U: case 0x52U: case 0x53U: case 0x54U: case 0x55U: case 0x56U: case 0x57U:\n\t\t/* XXX: Avoid rewind, we know the length already. */\n\t\tDUK_CBOR_ASSERT(dec_ctx->off > 0U);\n\t\tdec_ctx->off--;\n\t\tduk__cbor_decode_buffer(dec_ctx, 0x40U);\n\t\tbreak;\n\tcase 0x58U: case 0x59U: case 0x5aU: case 0x5bU:\n\t\t/* XXX: Avoid rewind, decode length inline. */\n\t\tDUK_CBOR_ASSERT(dec_ctx->off > 0U);\n\t\tdec_ctx->off--;\n\t\tduk__cbor_decode_buffer(dec_ctx, 0x40U);\n\t\tbreak;\n\tcase 0x5cU: case 0x5dU: case 0x5eU:\n\t\tgoto format_error;\n\tcase 0x5fU:\n\t\tduk__cbor_decode_and_join_strbuf(dec_ctx, 0x40U);\n\t\tbreak;\n\tcase 0x60U: case 0x61U: case 0x62U: case 0x63U: case 0x64U: case 0x65U: case 0x66U: case 0x67U:\n\tcase 0x68U: case 0x69U: case 0x6aU: case 0x6bU: case 0x6cU: case 0x6dU: case 0x6eU: case 0x6fU:\n\tcase 0x70U: case 0x71U: case 0x72U: case 0x73U: case 0x74U: case 0x75U: case 0x76U: case 0x77U:\n\t\t/* XXX: Avoid double decode of length. */\n\t\tduk__cbor_decode_string(dec_ctx, ib, DUK__CBOR_AI);\n\t\tbreak;\n\tcase 0x78U: case 0x79U: case 0x7aU: case 0x7bU:\n\t\t/* XXX: Avoid double decode of length. */\n\t\tduk__cbor_decode_string(dec_ctx, ib, DUK__CBOR_AI);\n\t\tbreak;\n\tcase 0x7cU: case 0x7dU: case 0x7eU:\n\t\tgoto format_error;\n\tcase 0x7fU:\n\t\tduk__cbor_decode_string(dec_ctx, ib, DUK__CBOR_AI);\n\t\tbreak;\n\tcase 0x80U: case 0x81U: case 0x82U: case 0x83U: case 0x84U: case 0x85U: case 0x86U: case 0x87U:\n\tcase 0x88U: case 0x89U: case 0x8aU: case 0x8bU: case 0x8cU: case 0x8dU: case 0x8eU: case 0x8fU:\n\tcase 0x90U: case 0x91U: case 0x92U: case 0x93U: case 0x94U: case 0x95U: case 0x96U: case 0x97U:\n\t\tif (DUK_CBOR_UNLIKELY(duk__cbor_decode_array(dec_ctx, ib, DUK__CBOR_AI) == 0)) {\n\t\t\tgoto format_error;\n\t\t}\n\t\tbreak;\n\tcase 0x98U: case 0x99U: case 0x9aU: case 0x9bU:\n\t\tif (DUK_CBOR_UNLIKELY(duk__cbor_decode_array(dec_ctx, ib, DUK__CBOR_AI) == 0)) {\n\t\t\tgoto format_error;\n\t\t}\n\t\tbreak;\n\tcase 0x9cU: case 0x9dU: case 0x9eU:\n\t\tgoto format_error;\n\tcase 0x9fU:\n\t\tif (DUK_CBOR_UNLIKELY(duk__cbor_decode_array(dec_ctx, ib, DUK__CBOR_AI) == 0)) {\n\t\t\tgoto format_error;\n\t\t}\n\t\tbreak;\n\tcase 0xa0U: case 0xa1U: case 0xa2U: case 0xa3U: case 0xa4U: case 0xa5U: case 0xa6U: case 0xa7U:\n\tcase 0xa8U: case 0xa9U: case 0xaaU: case 0xabU: case 0xacU: case 0xadU: case 0xaeU: case 0xafU:\n\tcase 0xb0U: case 0xb1U: case 0xb2U: case 0xb3U: case 0xb4U: case 0xb5U: case 0xb6U: case 0xb7U:\n\t\tif (DUK_CBOR_UNLIKELY(duk__cbor_decode_map(dec_ctx, ib, DUK__CBOR_AI) == 0)) {\n\t\t\tgoto format_error;\n\t\t}\n\t\tbreak;\n\tcase 0xb8U: case 0xb9U: case 0xbaU: case 0xbbU:\n\t\tif (DUK_CBOR_UNLIKELY(duk__cbor_decode_map(dec_ctx, ib, DUK__CBOR_AI) == 0)) {\n\t\t\tgoto format_error;\n\t\t}\n\t\tbreak;\n\tcase 0xbcU: case 0xbdU: case 0xbeU:\n\t\tgoto format_error;\n\tcase 0xbfU:\n\t\tif (DUK_CBOR_UNLIKELY(duk__cbor_decode_map(dec_ctx, ib, DUK__CBOR_AI) == 0)) {\n\t\t\tgoto format_error;\n\t\t}\n\t\tbreak;\n\tcase 0xc0U: case 0xc1U: case 0xc2U: case 0xc3U: case 0xc4U: case 0xc5U: case 0xc6U: case 0xc7U:\n\tcase 0xc8U: case 0xc9U: case 0xcaU: case 0xcbU: case 0xccU: case 0xcdU: case 0xceU: case 0xcfU:\n\tcase 0xd0U: case 0xd1U: case 0xd2U: case 0xd3U: case 0xd4U: case 0xd5U: case 0xd6U: case 0xd7U:\n\t\t/* Tag 0-23: drop. */\n\t\tgoto reread_initial_byte;\n\tcase 0xd8U: case 0xd9U: case 0xdaU: case 0xdbU:\n\t\tduk__cbor_decode_skip_aival_int(dec_ctx, ib);\n\t\tgoto reread_initial_byte;\n\tcase 0xdcU: case 0xddU: case 0xdeU: case 0xdfU:\n\t\tgoto format_error;\n\tcase 0xe0U:\n\t\tgoto format_error;\n\tcase 0xe1U:\n\t\tgoto format_error;\n\tcase 0xe2U:\n\t\tgoto format_error;\n\tcase 0xe3U:\n\t\tgoto format_error;\n\tcase 0xe4U:\n\t\tgoto format_error;\n\tcase 0xe5U:\n\t\tgoto format_error;\n\tcase 0xe6U:\n\t\tgoto format_error;\n\tcase 0xe7U:\n\t\tgoto format_error;\n\tcase 0xe8U:\n\t\tgoto format_error;\n\tcase 0xe9U:\n\t\tgoto format_error;\n\tcase 0xeaU:\n\t\tgoto format_error;\n\tcase 0xebU:\n\t\tgoto format_error;\n\tcase 0xecU:\n\t\tgoto format_error;\n\tcase 0xedU:\n\t\tgoto format_error;\n\tcase 0xeeU:\n\t\tgoto format_error;\n\tcase 0xefU:\n\t\tgoto format_error;\n\tcase 0xf0U:\n\t\tgoto format_error;\n\tcase 0xf1U:\n\t\tgoto format_error;\n\tcase 0xf2U:\n\t\tgoto format_error;\n\tcase 0xf3U:\n\t\tgoto format_error;\n\tcase 0xf4U:\n\t\tduk_push_false(dec_ctx->ctx);\n\t\tbreak;\n\tcase 0xf5U:\n\t\tduk_push_true(dec_ctx->ctx);\n\t\tbreak;\n\tcase 0xf6U:\n\t\tduk_push_null(dec_ctx->ctx);\n\t\tbreak;\n\tcase 0xf7U:\n\t\tduk_push_undefined(dec_ctx->ctx);\n\t\tbreak;\n\tcase 0xf8U:\n\t\t/* Simple value 32-255, nothing defined yet, so reject. */\n\t\tgoto format_error;\n\tcase 0xf9U: {\n\t\tduk_double_t d;\n\t\td = duk__cbor_decode_half_float(dec_ctx);\n\t\tduk_push_number(dec_ctx->ctx, d);\n\t\tbreak;\n\t}\n\tcase 0xfaU: {\n\t\tduk_double_t d;\n\t\td = duk__cbor_decode_float(dec_ctx);\n\t\tduk_push_number(dec_ctx->ctx, d);\n\t\tbreak;\n\t}\n\tcase 0xfbU: {\n\t\tduk_double_t d;\n\t\td = duk__cbor_decode_double(dec_ctx);\n\t\tduk_push_number(dec_ctx->ctx, d);\n\t\tbreak;\n\t}\n\tcase 0xfcU:\n\tcase 0xfdU:\n\tcase 0xfeU:\n\tcase 0xffU:\n\t\tgoto format_error;\n\t}  /* end switch */\n\n\treturn;\n\n format_error:\n\tduk__cbor_decode_error(dec_ctx);\n}\n#else  /* DUK_CBOR_DECODE_FASTPATH */\nstatic void duk__cbor_decode_value(duk_cbor_decode_context *dec_ctx) {\n\tduk_uint8_t ib, mt, ai;\n\n\t/* Any paths potentially recursing back to duk__cbor_decode_value()\n\t * must perform a Duktape value stack growth check.  Avoid the check\n\t * here for simple paths like primitive values.\n\t */\n\n reread_initial_byte:\n#if defined(DUK_CBOR_DPRINT)\n\tfprintf(stderr, \"cbor decode off=%ld len=%ld\\n\", (long) dec_ctx->off, (long) dec_ctx->len);\n#endif\n\n\tib = duk__cbor_decode_readbyte(dec_ctx);\n\tmt = ib >> 5U;\n\tai = ib & 0x1fU;\n\n\t/* Additional information in [24,27] = [0x18,0x1b] has relatively\n\t * uniform handling for all major types: read 1/2/4/8 additional\n\t * bytes.  For major type 7 the 1-byte value is a 'simple type', and\n\t * 2/4/8-byte values are floats.  For other major types the 1/2/4/8\n\t * byte values are integers.  The lengths are uniform, but the typing\n\t * is not.\n\t */\n\n\tswitch (mt) {\n\tcase 0U: {  /* unsigned integer */\n\t\tduk__cbor_decode_push_aival_int(dec_ctx, ib, 0 /*negative*/);\n\t\tbreak;\n\t}\n\tcase 1U: {  /* negative integer */\n\t\tduk__cbor_decode_push_aival_int(dec_ctx, ib, 1 /*negative*/);\n\t\tbreak;\n\t}\n\tcase 2U: {  /* byte string */\n\t\tif (ai == 0x1fU) {\n\t\t\tduk__cbor_decode_and_join_strbuf(dec_ctx, 0x40U);\n\t\t} else {\n\t\t\tduk__cbor_decode_rewind(dec_ctx, 1U);\n\t\t\tduk__cbor_decode_buffer(dec_ctx, 0x40U);\n\t\t}\n\t\tbreak;\n\t}\n\tcase 3U: {  /* text string */\n\t\tduk__cbor_decode_string(dec_ctx, ib, ai);\n\t\tbreak;\n\t}\n\tcase 4U: {  /* array of data items */\n\t\tif (DUK_CBOR_UNLIKELY(duk__cbor_decode_array(dec_ctx, ib, ai) == 0)) {\n\t\t\tgoto format_error;\n\t\t}\n\t\tbreak;\n\t}\n\tcase 5U: {  /* map of pairs of data items */\n\t\tif (DUK_CBOR_UNLIKELY(duk__cbor_decode_map(dec_ctx, ib, ai) == 0)) {\n\t\t\tgoto format_error;\n\t\t}\n\t\tbreak;\n\t}\n\tcase 6U: {  /* semantic tagging */\n\t\t/* Tags are ignored now, re-read initial byte.  A tagged\n\t\t * value may itself be tagged (an unlimited number of times)\n\t\t * so keep on peeling away tags.\n\t\t */\n\t\tduk__cbor_decode_skip_aival_int(dec_ctx, ib);\n\t\tgoto reread_initial_byte;\n\t}\n\tcase 7U: {  /* floating point numbers, simple data types, break; other */\n\t\tswitch (ai) {\n\t\tcase 0x14U: {\n\t\t\tduk_push_false(dec_ctx->ctx);\n\t\t\tbreak;\n\t\t}\n\t\tcase 0x15U: {\n\t\t\tduk_push_true(dec_ctx->ctx);\n\t\t\tbreak;\n\t\t}\n\t\tcase 0x16U: {\n\t\t\tduk_push_null(dec_ctx->ctx);\n\t\t\tbreak;\n\t\t}\n\t\tcase 0x17U: {\n\t\t\tduk_push_undefined(dec_ctx->ctx);\n\t\t\tbreak;\n\t\t}\n\t\tcase 0x18U: {  /* more simple values (1 byte) */\n\t\t\t/* Simple value encoded in additional byte (none\n\t\t\t * are defined so far).  RFC 7049 states that the\n\t\t\t * follow-up byte must be 32-255 to minimize\n\t\t\t * confusion.  So, a non-shortest encoding like\n\t\t\t * f815 (= true, shortest encoding f5) must be\n\t\t\t * rejected.  cbor.me tester rejects f815, but\n\t\t\t * e.g. Python CBOR binding decodes it as true.\n\t\t\t */\n\t\t\tgoto format_error;\n\t\t}\n\t\tcase 0x19U: {  /* half-float (2 bytes) */\n\t\t\tduk_double_t d;\n\t\t\td = duk__cbor_decode_half_float(dec_ctx);\n\t\t\tduk_push_number(dec_ctx->ctx, d);\n\t\t\tbreak;\n\t\t}\n\t\tcase 0x1aU: {  /* float (4 bytes) */\n\t\t\tduk_double_t d;\n\t\t\td = duk__cbor_decode_float(dec_ctx);\n\t\t\tduk_push_number(dec_ctx->ctx, d);\n\t\t\tbreak;\n\t\t}\n\t\tcase 0x1bU: {  /* double (8 bytes) */\n\t\t\tduk_double_t d;\n\t\t\td = duk__cbor_decode_double(dec_ctx);\n\t\t\tduk_push_number(dec_ctx->ctx, d);\n\t\t\tbreak;\n\t\t}\n\t\tcase 0xffU:  /* unexpected break */\n\t\tdefault: {\n\t\t\tgoto format_error;\n\t\t}\n\t\t}  /* end switch */\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tgoto format_error;  /* will never actually occur */\n\t}\n\t}  /* end switch */\n\n\treturn;\n\n format_error:\n\tduk__cbor_decode_error(dec_ctx);\n}\n#endif  /* DUK_CBOR_DECODE_FASTPATH */\n\n/*\n *  Public APIs\n */\n\nstatic duk_ret_t duk__cbor_encode_binding(duk_context *ctx) {\n\t/* Produce an ArrayBuffer by first decoding into a plain buffer which\n\t * mimics a Uint8Array and gettings its .buffer property.\n\t */\n\tduk_cbor_encode(ctx, -1, 0);\n\tduk_get_prop_string(ctx, -1, \"buffer\");\n\treturn 1;\n}\n\nstatic duk_ret_t duk__cbor_decode_binding(duk_context *ctx) {\n\t/* Lenient: accept any buffer like. */\n\tduk_cbor_decode(ctx, -1, 0);\n\treturn 1;\n}\n\nvoid duk_cbor_init(duk_context *ctx, duk_uint_t flags) {\n\t(void) flags;\n\tduk_push_global_object(ctx);\n\tduk_push_string(ctx, \"CBOR\");\n\tduk_push_object(ctx);\n\tduk_push_string(ctx, \"encode\");\n\tduk_push_c_function(ctx, duk__cbor_encode_binding, 1);\n\tduk_def_prop(ctx, -3, DUK_DEFPROP_ATTR_WC | DUK_DEFPROP_HAVE_VALUE);\n\tduk_push_string(ctx, \"decode\");\n\tduk_push_c_function(ctx, duk__cbor_decode_binding, 1);\n\tduk_def_prop(ctx, -3, DUK_DEFPROP_ATTR_WC | DUK_DEFPROP_HAVE_VALUE);\n\tduk_def_prop(ctx, -3, DUK_DEFPROP_ATTR_WC | DUK_DEFPROP_HAVE_VALUE);\n\tduk_pop(ctx);\n}\n\nvoid duk_cbor_encode(duk_context *ctx, duk_idx_t idx, duk_uint_t encode_flags) {\n\tduk_cbor_encode_context enc_ctx;\n\tduk_uint8_t *buf;\n\n\t(void) encode_flags;\n\n\tidx = duk_require_normalize_index(ctx, idx);\n\n\tenc_ctx.ctx = ctx;\n\tenc_ctx.idx_buf = duk_get_top(ctx);\n\n\tenc_ctx.len = 64;\n\tbuf = (duk_uint8_t *) duk_push_dynamic_buffer(ctx, enc_ctx.len);\n\tenc_ctx.ptr = buf;\n\tenc_ctx.buf = buf;\n\tenc_ctx.buf_end = buf + enc_ctx.len;\n\n\tduk_dup(ctx, idx);\n\tduk__cbor_encode_value(&enc_ctx);\n\tduk_resize_buffer(enc_ctx.ctx, enc_ctx.idx_buf, (duk_size_t) (enc_ctx.ptr - enc_ctx.buf));\n\tduk_replace(ctx, idx);\n}\n\nvoid duk_cbor_decode(duk_context *ctx, duk_idx_t idx, duk_uint_t decode_flags) {\n\tduk_cbor_decode_context dec_ctx;\n\n\t(void) decode_flags;\n\n\t/* Suppress compile warnings for functions only needed with e.g.\n\t * asserts enabled.\n\t */\n\t(void) duk__cbor_get_reserve;\n\t(void) duk__cbor_isinf;\n\t(void) duk__cbor_fpclassify;\n\n\tidx = duk_require_normalize_index(ctx, idx);\n\n\tdec_ctx.ctx = ctx;\n\tdec_ctx.buf = (const duk_uint8_t *) duk_require_buffer_data(ctx, idx, &dec_ctx.len);\n\tdec_ctx.off = 0;\n\t/* dec_ctx.len: set above */\n\n\tduk__cbor_req_stack(&dec_ctx);\n\tduk__cbor_decode_value(&dec_ctx);\n\tif (dec_ctx.off != dec_ctx.len) {\n\t\t(void) duk_type_error(ctx, \"trailing garbage\");\n\t}\n\n\tduk_replace(ctx, idx);\n}\n"
  },
  {
    "path": "react_juce/duktape/extras/cbor/duk_cbor.h",
    "content": "#if !defined(DUK_CBOR_H_INCLUDED)\n#define DUK_CBOR_H_INCLUDED\n\n#include \"duktape.h\"\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/* No flags at present. */\n\nextern void duk_cbor_init(duk_context *ctx, duk_uint_t flags);\nextern void duk_cbor_encode(duk_context *ctx, duk_idx_t idx, duk_uint_t encode_flags);\nextern void duk_cbor_decode(duk_context *ctx, duk_idx_t idx, duk_uint_t decode_flags);\n\n#if defined(__cplusplus)\n}\n#endif  /* end 'extern \"C\"' wrapper */\n\n#endif /* DUK_CBOR_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/extras/cbor/jsoncbor.c",
    "content": "#include <stdio.h>\n#include \"duktape.h\"\n#include \"duk_cbor.h\"\n\n#define FMT_CBOR 1\n#define FMT_JSON 2\n#define FMT_JX 3\n#define FMT_JS 4\n\nstatic int read_format = 0;\nstatic int write_format = 0;\nstatic int write_indent = 0;\n\nstatic void push_stdin(duk_context *ctx, int to_string) {\n\tunsigned char *buf;\n\tsize_t off;\n\tsize_t len;\n\tsize_t got;\n\n\toff = 0;\n\tlen = 256;\n\tbuf = (unsigned char *) duk_push_dynamic_buffer(ctx, len);\n\n\tfor (;;) {\n#if 0\n\t\tfprintf(stderr, \"reading %ld of input\\n\", (long) (len - off));\n#endif\n\t\tgot = fread(buf + off, 1, len - off, stdin);\n\t\tif (got == 0U) {\n\t\t\tbreak;\n\t\t}\n\t\toff += got;\n\t\tif (len - off < 256U) {\n\t\t\tsize_t newlen = len * 2U;\n\t\t\tbuf = (unsigned char *) duk_resize_buffer(ctx, -1, newlen);\n\t\t\tlen = newlen;\n\t\t}\n\t}\n\tbuf = (unsigned char *) duk_resize_buffer(ctx, -1, off);\n\n\tif (to_string) {\n\t\tduk_push_lstring(ctx, (const char *) buf, off);\n\t\tduk_remove(ctx, -2);\n\t}\n}\n\nstatic void usage_and_exit(void) {\n\tfprintf(stderr, \"Usage: jsoncbor -r cbor|json|jx|js -w cbor|json|jx [--indent N]\\n\"\n\t                \"       jsoncbor -e               # shorthand for -r json -w cbor\\n\"\n\t                \"       jsoncbor -d [--indent N]  # shorthand for -r cbor -w json [--indent N]\\n\"\n\t                \"\\n\"\n\t                \"       Input is read from stdin, output is written to stdout.\\n\"\n\t                \"       'jx' is a Duktape custom JSON extension.\\n\"\n\t                \"       'js' means evaluate input as an ECMAScript expression.\\n\");\n\texit(1);\n}\n\nstatic duk_ret_t transcode_helper(duk_context *ctx, void *udata) {\n\tconst unsigned char *buf;\n\tsize_t len;\n\tduk_idx_t top;\n\n\t(void) udata;\n\n\t/* For Duktape->JSON conversion map all typed arrays into base-64.\n\t * This is generally more useful than the default behavior.  However,\n\t * the base-64 value doesn't have any kind of 'tag' to allow it to be\n\t * parsed back into binary automatically.  Right now the CBOR parser\n\t * creates plain fixed buffers from incoming binary strings.\n\t */\n\tduk_eval_string_noresult(ctx,\n\t\t\"(function () {\\n\"\n\t\t\"    Object.getPrototypeOf(new Uint8Array(0)).toJSON = function () {\\n\"\n\t\t\"        return Duktape.enc('base64', this);\\n\"\n\t\t\"    };\\n\"\n\t\t\"}())\\n\");\n\n\ttop = duk_get_top(ctx);\n\n\tif (read_format == FMT_CBOR) {\n\t\tpush_stdin(ctx, 0 /*to_string*/);\n\t\tduk_cbor_decode(ctx, -1, 0);\n\t} else if (read_format == FMT_JSON) {\n\t\tpush_stdin(ctx, 1 /*to_string*/);\n\t\tduk_json_decode(ctx, -1);\n\t} else if (read_format == FMT_JX) {\n\t\tduk_eval_string(ctx, \"(function(v){return Duktape.dec('jx',v)})\");\n\t\tpush_stdin(ctx, 1 /*to_string*/);\n\t\tduk_call(ctx, 1);\n\t} else if (read_format == FMT_JS) {\n\t\tpush_stdin(ctx, 1 /*to_string*/);\n\t\tduk_eval(ctx);\n\t} else {\n\t\t(void) duk_type_error(ctx, \"invalid read format\");\n\t}\n\n\tif (duk_get_top(ctx) != top + 1) {\n\t\tfprintf(stderr, \"top invalid after decoding: %d vs. %d\\n\", duk_get_top(ctx), top + 1);\n\t\texit(1);\n\t}\n\n\tif (write_format == FMT_CBOR) {\n\t\tduk_cbor_encode(ctx, -1, 0);\n\t} else if (write_format == FMT_JSON) {\n\t\tduk_eval_string(ctx, \"(function(v,i){return JSON.stringify(v,null,i)})\");\n\t\tduk_insert(ctx, -2);\n\t\tduk_push_int(ctx, write_indent);\n\t\tduk_call(ctx, 2);\n\t} else if (write_format == FMT_JX) {\n\t\tduk_eval_string(ctx, \"(function(v,i){return Duktape.enc('jx',v,null,i)})\");\n\t\tduk_insert(ctx, -2);\n\t\tduk_push_int(ctx, write_indent);\n\t\tduk_call(ctx, 2);\n\t} else {\n\t\t(void) duk_type_error(ctx, \"invalid write format\");\n\t}\n\n\tif (duk_is_string(ctx, -1)) {\n\t\tbuf = (const unsigned char *) duk_require_lstring(ctx, -1, &len);\n\t\tfwrite((const void *) buf, 1, len, stdout);\n\t\tfprintf(stdout, \"\\n\");\n\t} else {\n\t\tbuf = (const unsigned char *) duk_require_buffer_data(ctx, -1, &len);\n\t\tfwrite((const void *) buf, 1, len, stdout);\n\t}\n\n\tif (duk_get_top(ctx) != top + 1) {\n\t\tfprintf(stderr, \"top invalid after encoding: %d vs. %d\\n\", duk_get_top(ctx), top + 1);\n\t\texit(1);\n\t}\n\n\treturn 0;\n}\n\nstatic int parse_format(const char *s) {\n\tif (strcmp(s, \"cbor\") == 0) {\n\t\treturn FMT_CBOR;\n\t} else if (strcmp(s, \"json\") == 0) {\n\t\treturn FMT_JSON;\n\t} else if (strcmp(s, \"jx\") == 0) {\n\t\treturn FMT_JX;\n\t} else if (strcmp(s, \"js\") == 0) {\n\t\treturn FMT_JS;\n\t} else {\n\t\treturn 0;\n\t}\n}\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx;\n\tduk_int_t rc;\n\tint exitcode = 0;\n\tint i;\n\n\tfor (i = 1; i < argc; i++) {\n\t\tif (strcmp(argv[i], \"-e\") == 0) {\n\t\t\tread_format = FMT_JSON;\n\t\t\twrite_format = FMT_CBOR;\n\t\t} else if (strcmp(argv[i], \"-d\") == 0) {\n\t\t\tread_format = FMT_CBOR;\n\t\t\twrite_format = FMT_JSON;\n\t\t} else if (strcmp(argv[i], \"-r\") == 0) {\n\t\t\tif (i + 1 >= argc) {\n\t\t\t\tgoto usage;\n\t\t\t}\n\t\t\tread_format = parse_format(argv[i + 1]);\n\t\t\ti++;\n\t\t} else if (strcmp(argv[i], \"-w\") == 0) {\n\t\t\tif (i + 1 >= argc) {\n\t\t\t\tgoto usage;\n\t\t\t}\n\t\t\twrite_format = parse_format(argv[i + 1]);\n\t\t\ti++;\n\t\t} else if (strcmp(argv[i], \"--indent\") == 0) {\n\t\t\tif (i + 1 >= argc) {\n\t\t\t\tgoto usage;\n\t\t\t}\n\t\t\twrite_indent = atoi(argv[i + 1]);\n\t\t\ti++;\n\t\t} else {\n\t\t\tgoto usage;\n\t\t}\n\t}\n\n\tif (read_format == 0 || write_format == 0) {\n\t\tgoto usage;\n\t}\n\n\tctx = duk_create_heap_default();\n\tif (!ctx) {\n\t\treturn 1;\n\t}\n\n\trc = duk_safe_call(ctx, transcode_helper, NULL, 0, 1);\n\tif (rc != 0) {\n\t\tfprintf(stderr, \"%s\\n\", duk_safe_to_string(ctx, -1));\n\t\texitcode = 1;\n\t}\n\t/* duk_pop(ctx): unnecessary */\n\n\tduk_destroy_heap(ctx);\n\n\treturn exitcode;\n\n usage:\n\tusage_and_exit();\n}\n"
  },
  {
    "path": "react_juce/duktape/extras/cbor/run_testvectors.js",
    "content": "var testvectors = JSON.parse(new TextDecoder().decode(readFile('appendix_a.json')));\n\n// Very rudimentary for now, just dump useful information about decode\n// results and (simple, unstructured) comparison to expected.  This is\n// only useful for manually inspecting the results right now.\n\ntestvectors.forEach(function (test, idx) {\n    print('===', idx, '->', Duktape.enc('jx', test));\n\n    var cbor = Duktape.dec('base64', test.cbor);\n    try {\n        var dec = CBOR.decode(cbor);\n    } catch (e) {\n        print('decode failed: ' + e);\n        return;\n    }\n\n    print('dec (jx): ' + Duktape.enc('jx', dec));\n\n    if (dec !== test.decoded) {\n        print('decoded compare failed');\n    }\n    if (test.roundtrip) {\n        var enc = CBOR.encode(dec);\n        print('re-enc: ' + Duktape.enc('hex', enc));\n        if (Duktape.enc('base64', cbor) !== Duktape.enc('base64', enc)) {\n            print('roundtrip failed');\n        }\n    }\n});\n"
  },
  {
    "path": "react_juce/duktape/extras/console/Makefile",
    "content": "# For manual testing; say 'make' in extras/console and run ./test.\n\nCC = gcc\n\n.PHONY: test\ntest:\n\t-rm -rf ./prep\n\tpython2 ../../tools/configure.py --quiet --output-directory ./prep\n\t$(CC) -std=c99 -Wall -Wextra -o $@ -I./prep -I. ./prep/duktape.c duk_console.c test.c -lm\n\t./test 'console.assert(true, \"not shown\");'\n\t./test 'console.assert(false, \"shown\", { foo: 123 });'\n\t./test 'console.log(1, 2, 3, { foo: \"bar\" });'\n\t./test 'a={}; b={}; a.ref=b; console.log(a,b); b.ref=a; console.log(a,b)'  # circular ref\n\t./test 'console.trace(1, 2, 3)'\n\t./test 'console.dir({ foo: 123, bar: [ \"foo\", \"bar\" ]});'\n\n.PHONY: clean\nclean:\n\t-rm -rf ./prep\n\t-rm -f test\n"
  },
  {
    "path": "react_juce/duktape/extras/console/README.rst",
    "content": "=========================\nMinimal 'console' binding\n=========================\n\nDuktape doesn't provide a ``console`` binding (for example ``console.log``)\nby default because it would be a portability issue for some targets.  Instead,\nan application should provide its own ``console`` binding.  This directory\ncontains an example binding:\n\n* Add ``duk_console.c`` to list of C sources to compile.\n\n* Ensure ``duk_console.h`` is in the include path.\n\n* Include the extra header in calling code and initialize the bindings::\n\n      #include \"duktape.h\"\n      #include \"duk_console.h\"\n\n      /* After initializing the Duktape heap or when creating a new\n       * thread with a new global environment:\n       */\n      duk_console_init(ctx, 0 /*flags*/);\n\n  Use the ``DUK_CONSOLE_PROXY_WRAPPER`` to enable a Proxy wrapper for the\n  console object.  The wrapper allows all undefined methods (for example,\n  ``console.foo``) to be handled as no-ops instead of throwing an error.\n  See ``duk_console.h`` for full flags list.\n\n* After these steps, ``console`` will be registered to the global object\n  and is ready to use.\n\n* By default the console object will use ``stdout`` for log levels up to\n  info, and ``stderr`` for warning and above.  You can change this by\n  providing either ``DUK_CONSOLE_STDOUT_ONLY`` or ``DUK_CONSOLE_STDERR_ONLY``\n  in ``duk_console_init()`` flags.\n"
  },
  {
    "path": "react_juce/duktape/extras/console/duk_console.c",
    "content": "/*\n *  Minimal 'console' binding.\n *\n *  https://github.com/DeveloperToolsWG/console-object/blob/master/api.md\n *  https://developers.google.com/web/tools/chrome-devtools/debug/console/console-reference\n *  https://developer.mozilla.org/en/docs/Web/API/console\n */\n\n#include <stdio.h>\n#include <stdarg.h>\n#include \"duktape.h\"\n#include \"duk_console.h\"\n\n/* XXX: Add some form of log level filtering. */\n\n/* XXX: Should all output be written via e.g. console.write(formattedMsg)?\n * This would make it easier for user code to redirect all console output\n * to a custom backend.\n */\n\n/* XXX: Init console object using duk_def_prop() when that call is available. */\n\nstatic duk_ret_t duk__console_log_helper(duk_context *ctx, const char *error_name) {\n\tduk_uint_t flags = (duk_uint_t) duk_get_current_magic(ctx);\n\tFILE *output = (flags & DUK_CONSOLE_STDOUT_ONLY) ? stdout : stderr;\n\tduk_idx_t n = duk_get_top(ctx);\n\tduk_idx_t i;\n\n\tduk_get_global_string(ctx, \"console\");\n\tduk_get_prop_string(ctx, -1, \"format\");\n\n\tfor (i = 0; i < n; i++) {\n\t\tif (duk_check_type_mask(ctx, i, DUK_TYPE_MASK_OBJECT)) {\n\t\t\t/* Slow path formatting. */\n\t\t\tduk_dup(ctx, -1);  /* console.format */\n\t\t\tduk_dup(ctx, i);\n\t\t\tduk_call(ctx, 1);\n\t\t\tduk_replace(ctx, i);  /* arg[i] = console.format(arg[i]); */\n\t\t}\n\t}\n\n\tduk_pop_2(ctx);\n\n\tduk_push_string(ctx, \" \");\n\tduk_insert(ctx, 0);\n\tduk_join(ctx, n);\n\n\tif (error_name) {\n\t\tduk_push_error_object(ctx, DUK_ERR_ERROR, \"%s\", duk_require_string(ctx, -1));\n\t\tduk_push_string(ctx, \"name\");\n\t\tduk_push_string(ctx, error_name);\n\t\tduk_def_prop(ctx, -3, DUK_DEFPROP_FORCE | DUK_DEFPROP_HAVE_VALUE);  /* to get e.g. 'Trace: 1 2 3' */\n\t\tduk_get_prop_string(ctx, -1, \"stack\");\n\t}\n\n\tfprintf(output, \"%s\\n\", duk_to_string(ctx, -1));\n\tif (flags & DUK_CONSOLE_FLUSH) {\n\t\tfflush(output);\n\t}\n\treturn 0;\n}\n\nstatic duk_ret_t duk__console_assert(duk_context *ctx) {\n\tif (duk_to_boolean(ctx, 0)) {\n\t\treturn 0;\n\t}\n\tduk_remove(ctx, 0);\n\n\treturn duk__console_log_helper(ctx, \"AssertionError\");\n}\n\nstatic duk_ret_t duk__console_log(duk_context *ctx) {\n\treturn duk__console_log_helper(ctx, NULL);\n}\n\nstatic duk_ret_t duk__console_trace(duk_context *ctx) {\n\treturn duk__console_log_helper(ctx, \"Trace\");\n}\n\nstatic duk_ret_t duk__console_info(duk_context *ctx) {\n\treturn duk__console_log_helper(ctx, NULL);\n}\n\nstatic duk_ret_t duk__console_warn(duk_context *ctx) {\n\treturn duk__console_log_helper(ctx, NULL);\n}\n\nstatic duk_ret_t duk__console_error(duk_context *ctx) {\n\treturn duk__console_log_helper(ctx, \"Error\");\n}\n\nstatic duk_ret_t duk__console_dir(duk_context *ctx) {\n\t/* For now, just share the formatting of .log() */\n\treturn duk__console_log_helper(ctx, 0);\n}\n\nstatic void duk__console_reg_vararg_func(duk_context *ctx, duk_c_function func, const char *name, duk_uint_t flags) {\n\tduk_push_c_function(ctx, func, DUK_VARARGS);\n\tduk_push_string(ctx, \"name\");\n\tduk_push_string(ctx, name);\n\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_FORCE);  /* Improve stacktraces by displaying function name */\n\tduk_set_magic(ctx, -1, (duk_int_t) flags);\n\tduk_put_prop_string(ctx, -2, name);\n}\n\nvoid duk_console_init(duk_context *ctx, duk_uint_t flags) {\n\tduk_uint_t flags_orig;\n\n\t/* If both DUK_CONSOLE_STDOUT_ONLY and DUK_CONSOLE_STDERR_ONLY where specified,\n\t * just turn off DUK_CONSOLE_STDOUT_ONLY and keep DUK_CONSOLE_STDERR_ONLY.\n\t */\n\tif ((flags & DUK_CONSOLE_STDOUT_ONLY) && (flags & DUK_CONSOLE_STDERR_ONLY)) {\n\t    flags &= ~DUK_CONSOLE_STDOUT_ONLY;\n\t}\n\t/* Remember the (possibly corrected) flags we received. */\n\tflags_orig = flags;\n\n\tduk_push_object(ctx);\n\n\t/* Custom function to format objects; user can replace.\n\t * For now, try JX-formatting and if that fails, fall back\n\t * to ToString(v).\n\t */\n\tduk_eval_string(ctx,\n\t\t\"(function (E) {\"\n\t\t    \"return function format(v){\"\n\t\t        \"try{\"\n\t\t            \"return E('jx',v);\"\n\t\t        \"}catch(e){\"\n\t\t            \"return String(v);\"  /* String() allows symbols, ToString() internal algorithm doesn't. */\n\t\t        \"}\"\n\t\t    \"};\"\n\t\t\"})(Duktape.enc)\");\n\tduk_put_prop_string(ctx, -2, \"format\");\n\n\tflags = flags_orig;\n\tif (!(flags & DUK_CONSOLE_STDOUT_ONLY) && !(flags & DUK_CONSOLE_STDERR_ONLY)) {\n\t    /* No output indicators were specified; these levels go to stdout. */\n\t    flags |= DUK_CONSOLE_STDOUT_ONLY;\n\t}\n\tduk__console_reg_vararg_func(ctx, duk__console_assert, \"assert\", flags);\n\tduk__console_reg_vararg_func(ctx, duk__console_log, \"log\", flags);\n\tduk__console_reg_vararg_func(ctx, duk__console_log, \"debug\", flags);  /* alias to console.log */\n\tduk__console_reg_vararg_func(ctx, duk__console_trace, \"trace\", flags);\n\tduk__console_reg_vararg_func(ctx, duk__console_info, \"info\", flags);\n\n\tflags = flags_orig;\n\tif (!(flags & DUK_CONSOLE_STDOUT_ONLY) && !(flags & DUK_CONSOLE_STDERR_ONLY)) {\n\t    /* No output indicators were specified; these levels go to stderr. */\n\t    flags |= DUK_CONSOLE_STDERR_ONLY;\n\t}\n\tduk__console_reg_vararg_func(ctx, duk__console_warn, \"warn\", flags);\n\tduk__console_reg_vararg_func(ctx, duk__console_error, \"error\", flags);\n\tduk__console_reg_vararg_func(ctx, duk__console_error, \"exception\", flags);  /* alias to console.error */\n\tduk__console_reg_vararg_func(ctx, duk__console_dir, \"dir\", flags);\n\n\tduk_put_global_string(ctx, \"console\");\n\n\t/* Proxy wrapping: ensures any undefined console method calls are\n\t * ignored silently.  This was required specifically by the\n\t * DeveloperToolsWG proposal (and was implemented also by Firefox:\n\t * https://bugzilla.mozilla.org/show_bug.cgi?id=629607).  This is\n\t * apparently no longer the preferred way of implementing console.\n\t * When Proxy is enabled, whitelist at least .toJSON() to avoid\n\t * confusing JX serialization of the console object.\n\t */\n\n\tif (flags & DUK_CONSOLE_PROXY_WRAPPER) {\n\t\t/* Tolerate failure to initialize Proxy wrapper in case\n\t\t * Proxy support is disabled.\n\t\t */\n\t\t(void) duk_peval_string_noresult(ctx,\n\t\t\t\"(function(){\"\n\t\t\t    \"var D=function(){};\"\n\t\t\t    \"var W={toJSON:true};\"  /* whitelisted */\n\t\t\t    \"console=new Proxy(console,{\"\n\t\t\t        \"get:function(t,k){\"\n\t\t\t            \"var v=t[k];\"\n\t\t\t            \"return typeof v==='function'||W[k]?v:D;\"\n\t\t\t        \"}\"\n\t\t\t    \"});\"\n\t\t\t\"})();\"\n\t\t);\n\t}\n}\n"
  },
  {
    "path": "react_juce/duktape/extras/console/duk_console.h",
    "content": "#if !defined(DUK_CONSOLE_H_INCLUDED)\n#define DUK_CONSOLE_H_INCLUDED\n\n#include \"duktape.h\"\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/* Use a proxy wrapper to make undefined methods (console.foo()) no-ops. */\n#define DUK_CONSOLE_PROXY_WRAPPER  (1U << 0)\n\n/* Flush output after every call. */\n#define DUK_CONSOLE_FLUSH          (1U << 1)\n\n/* Send output to stdout only (default is mixed stdout/stderr). */\n#define DUK_CONSOLE_STDOUT_ONLY    (1U << 2)\n\n/* Send output to stderr only (default is mixed stdout/stderr). */\n#define DUK_CONSOLE_STDERR_ONLY    (1U << 3)\n\n/* Initialize the console system */\nextern void duk_console_init(duk_context *ctx, duk_uint_t flags);\n\n#if defined(__cplusplus)\n}\n#endif  /* end 'extern \"C\"' wrapper */\n\n#endif  /* DUK_CONSOLE_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/extras/console/test.c",
    "content": "#include <stdio.h>\n#include \"duktape.h\"\n#include \"duk_console.h\"\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx;\n\tint i;\n\tint exitcode = 0;\n\n\tctx = duk_create_heap_default();\n\tif (!ctx) {\n\t\treturn 1;\n\t}\n\n\tduk_console_init(ctx, DUK_CONSOLE_PROXY_WRAPPER /*flags*/);\n\tprintf(\"top after init: %ld\\n\", (long) duk_get_top(ctx));\n\n\tfor (i = 1; i < argc; i++) {\n\t\tprintf(\"Evaling: %s\\n\", argv[i]);\n\t\tif (duk_peval_string(ctx, argv[i]) != 0) {\n\t\t\texitcode = 1;\n\t\t}\n\t\tprintf(\"--> %s\\n\", duk_safe_to_string(ctx, -1));\n\t\tduk_pop(ctx);\n\t}\n\n\tprintf(\"Done\\n\");\n\tduk_destroy_heap(ctx);\n\treturn exitcode;\n}\n"
  },
  {
    "path": "react_juce/duktape/extras/duk-v1-compat/Makefile",
    "content": "# For manual testing; say 'make' in extras/duk-v1-compat and run ./test.\n\nCC = gcc\n\n.PHONY: test\ntest:\n\t-rm -rf ./prep\n\tpython2 ../../tools/configure.py --quiet --output-directory ./prep\n\t$(CC) -std=c99 -Wall -Wextra -o $@ -I./prep -I. ./prep/duktape.c duk_v1_compat.c test.c -lm\n\t./test\n\n.PHONY: clean\nclean:\n\t-rm -rf ./prep\n\t-rm -f test\n"
  },
  {
    "path": "react_juce/duktape/extras/duk-v1-compat/README.rst",
    "content": "================================\nDuktape V1 compatibility helpers\n================================\n\nProvides helpers for migrating from Duktape 1.x to 2.x:\n\n* Add ``duk_v1_compat.c`` to list of C sources to compile.\n\n* Ensure ``duk_v1_compat.h`` is in the include path.\n\n* Include the extra header in calling code::\n\n      #include \"duktape.h\"\n      #include \"duk_v1_compat.h\"\n\n      /* ... */\n\n      duk_dump_context_stdout(ctx);  /* Removed in Duktape 2.x. */\n\nThe helpers don't restore full 1.x compatibility because some API calls such\nas ``duk_safe_call()`` have changed in an incompatible manner.\n\nThe old APIs are documented in:\n\n* http://duktape.org/1.5.0/api.html\n"
  },
  {
    "path": "react_juce/duktape/extras/duk-v1-compat/duk_v1_compat.c",
    "content": "#include <stdio.h>\n#include \"duktape.h\"\n#include \"duk_v1_compat.h\"\n\n/*\n *  duk_dump_context_{stdout,stderr}()\n */\n\nvoid duk_dump_context_stdout(duk_context *ctx) {\n\tduk_push_context_dump(ctx);\n\tfprintf(stdout, \"%s\\n\", duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n}\n\nvoid duk_dump_context_stderr(duk_context *ctx) {\n\tduk_push_context_dump(ctx);\n\tfprintf(stderr, \"%s\\n\", duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n}\n\n/*\n *  duk_push_string_file() and duk_push_string_file_raw()\n */\n\nconst char *duk_push_string_file_raw(duk_context *ctx, const char *path, duk_uint_t flags) {\n\tFILE *f = NULL;\n\tchar *buf;\n\tlong sz;  /* ANSI C typing */\n\n\tif (!path) {\n\t\tgoto fail;\n\t}\n\tf = fopen(path, \"rb\");\n\tif (!f) {\n\t\tgoto fail;\n\t}\n\tif (fseek(f, 0, SEEK_END) < 0) {\n\t\tgoto fail;\n\t}\n\tsz = ftell(f);\n\tif (sz < 0) {\n\t\tgoto fail;\n\t}\n\tif (fseek(f, 0, SEEK_SET) < 0) {\n\t\tgoto fail;\n\t}\n\tbuf = (char *) duk_push_fixed_buffer(ctx, (duk_size_t) sz);\n\tif ((size_t) fread(buf, 1, (size_t) sz, f) != (size_t) sz) {\n\t\tduk_pop(ctx);\n\t\tgoto fail;\n\t}\n\t(void) fclose(f);  /* ignore fclose() error */\n\treturn duk_buffer_to_string(ctx, -1);\n\n fail:\n\tif (f) {\n\t\t(void) fclose(f);  /* ignore fclose() error */\n\t}\n\n\tif (flags & DUK_STRING_PUSH_SAFE) {\n\t\tduk_push_undefined(ctx);\n\t} else {\n\t\t(void) duk_type_error(ctx, \"read file error\");\n\t}\n\treturn NULL;\n}\n\n/*\n *  duk_eval_file(), duk_compile_file(), and their variants\n */\n\nvoid duk_eval_file(duk_context *ctx, const char *path) {\n\tduk_push_string_file_raw(ctx, path, 0);\n\tduk_push_string(ctx, path);\n\tduk_compile(ctx, DUK_COMPILE_EVAL);\n\tduk_push_global_object(ctx);  /* 'this' binding */\n\tduk_call_method(ctx, 0);\n}\n\nvoid duk_eval_file_noresult(duk_context *ctx, const char *path) {\n\tduk_eval_file(ctx, path);\n\tduk_pop(ctx);\n}\n\nduk_int_t duk_peval_file(duk_context *ctx, const char *path) {\n\tduk_int_t rc;\n\n\tduk_push_string_file_raw(ctx, path, DUK_STRING_PUSH_SAFE);\n\tduk_push_string(ctx, path);\n\trc = duk_pcompile(ctx, DUK_COMPILE_EVAL);\n\tif (rc != 0) {\n\t\treturn rc;\n\t}\n\tduk_push_global_object(ctx);  /* 'this' binding */\n\trc = duk_pcall_method(ctx, 0);\n\treturn rc;\n}\n\nduk_int_t duk_peval_file_noresult(duk_context *ctx, const char *path) {\n\tduk_int_t rc;\n\n\trc = duk_peval_file(ctx, path);\n\tduk_pop(ctx);\n\treturn rc;\n}\n\nvoid duk_compile_file(duk_context *ctx, duk_uint_t flags, const char *path) {\n\tduk_push_string_file_raw(ctx, path, 0);\n\tduk_push_string(ctx, path);\n\tduk_compile(ctx, flags);\n}\n\nduk_int_t duk_pcompile_file(duk_context *ctx, duk_uint_t flags, const char *path) {\n\tduk_int_t rc;\n\n\tduk_push_string_file_raw(ctx, path, DUK_STRING_PUSH_SAFE);\n\tduk_push_string(ctx, path);\n\trc = duk_pcompile(ctx, flags);\n\treturn rc;\n}\n\n/*\n *  duk_to_defaultvalue()\n */\n\nvoid duk_to_defaultvalue(duk_context *ctx, duk_idx_t idx, duk_int_t hint) {\n\tduk_require_type_mask(ctx, idx, DUK_TYPE_MASK_OBJECT |\n\t                                DUK_TYPE_MASK_BUFFER |\n\t                                DUK_TYPE_MASK_LIGHTFUNC);\n\tduk_to_primitive(ctx, idx, hint);\n}\n"
  },
  {
    "path": "react_juce/duktape/extras/duk-v1-compat/duk_v1_compat.h",
    "content": "#if !defined(DUK_V1_COMPAT_INCLUDED)\n#define DUK_V1_COMPAT_INCLUDED\n\n#include \"duktape.h\"\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/* Straight flag rename */\n#if !defined(DUK_ENUM_INCLUDE_INTERNAL)\n#define DUK_ENUM_INCLUDE_INTERNAL DUK_ENUM_INCLUDE_HIDDEN\n#endif\n\n/* Flags for duk_push_string_file_raw() */\n#define DUK_STRING_PUSH_SAFE              (1 << 0)    /* no error if file does not exist */\n\nextern void duk_dump_context_stdout(duk_context *ctx);\nextern void duk_dump_context_stderr(duk_context *ctx);\nextern const char *duk_push_string_file_raw(duk_context *ctx, const char *path, duk_uint_t flags);\nextern void duk_eval_file(duk_context *ctx, const char *path);\nextern void duk_eval_file_noresult(duk_context *ctx, const char *path);\nextern duk_int_t duk_peval_file(duk_context *ctx, const char *path);\nextern duk_int_t duk_peval_file_noresult(duk_context *ctx, const char *path);\nextern void duk_compile_file(duk_context *ctx, duk_uint_t flags, const char *path);\nextern duk_int_t duk_pcompile_file(duk_context *ctx, duk_uint_t flags, const char *path);\nextern void duk_to_defaultvalue(duk_context *ctx, duk_idx_t idx, duk_int_t hint);\n\n#define duk_push_string_file(ctx,path) \\\n\tduk_push_string_file_raw((ctx), (path), 0)\n\n#if defined(__cplusplus)\n}\n#endif  /* end 'extern \"C\"' wrapper */\n\n#endif  /* DUK_V1_COMPAT_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/extras/duk-v1-compat/test.c",
    "content": "#include <stdio.h>\n#include \"duktape.h\"\n#include \"duk_v1_compat.h\"\n\nstatic duk_ret_t my_print(duk_context *ctx) {\n\tduk_push_string(ctx, \" \");\n\tduk_insert(ctx, 0);\n\tduk_join(ctx, duk_get_top(ctx) - 1);\n\tprintf(\"%s\\n\", duk_to_string(ctx, -1));\n\tfflush(stdout);\n\treturn 0;\n}\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx;\n\tint i;\n\tduk_int_t rc;\n\n\tctx = duk_create_heap_default();\n\tif (!ctx) {\n\t\treturn 1;\n\t}\n\n\t/* Minimal print() provider. */\n\tduk_push_c_function(ctx, my_print, DUK_VARARGS);\n\tduk_put_global_string(ctx, \"print\");\n\n\tprintf(\"top after init: %ld\\n\", (long) duk_get_top(ctx));\n\n\tfor (i = 1; i < argc; i++) {\n\t\tprintf(\"Evaling: %s\\n\", argv[i]);\n\t\t(void) duk_peval_string(ctx, argv[i]);\n\t\tprintf(\"--> %s\\n\", duk_safe_to_string(ctx, -1));\n\t\tduk_pop(ctx);\n\t}\n\n\t/* Test duk_dump_context_{stdout,stderr}() */\n\n\tduk_push_string(ctx, \"dump to stdout\");\n\tduk_dump_context_stdout(ctx);\n\tduk_pop(ctx);\n\n\tduk_push_string(ctx, \"dump to stderr\");\n\tduk_dump_context_stderr(ctx);\n\tduk_pop(ctx);\n\n\t/* Test duk_eval_file() and related. */\n\n\tprintf(\"top before duk_eval_file(): %ld\\n\", (long) duk_get_top(ctx));\n\tduk_eval_file(ctx, \"test_eval1.js\");\n\tprintf(\"top after duk_eval_file(): %ld\\n\", (long) duk_get_top(ctx));\n\tprintf(\" --> %s\\n\", duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\n\tprintf(\"top before duk_eval_file_noresult(): %ld\\n\", (long) duk_get_top(ctx));\n\tduk_eval_file_noresult(ctx, \"test_eval1.js\");\n\tprintf(\"top after duk_eval_file_noresult(): %ld\\n\", (long) duk_get_top(ctx));\n\n\tprintf(\"top before duk_peval_file(): %ld\\n\", (long) duk_get_top(ctx));\n\trc = duk_peval_file(ctx, \"test_eval1.js\");\n\tprintf(\"top after duk_peval_file(): %ld\\n\", (long) duk_get_top(ctx));\n\tprintf(\" --> %ld, %s\\n\", (long) rc, duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\n\tprintf(\"top before duk_peval_file(): %ld\\n\", (long) duk_get_top(ctx));\n\trc = duk_peval_file(ctx, \"test_eval2.js\");\n\tprintf(\"top after duk_peval_file(): %ld\\n\", (long) duk_get_top(ctx));\n\tprintf(\" --> %ld, %s\\n\", (long) rc, duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\n\tprintf(\"top before duk_peval_file_noresult(): %ld\\n\", (long) duk_get_top(ctx));\n\trc = duk_peval_file_noresult(ctx, \"test_eval1.js\");\n\tprintf(\"top after duk_peval_file_noresult(): %ld\\n\", (long) duk_get_top(ctx));\n\tprintf(\" --> %ld\\n\", (long) rc);\n\n\tprintf(\"top before duk_peval_file_noresult(): %ld\\n\", (long) duk_get_top(ctx));\n\trc = duk_peval_file_noresult(ctx, \"test_eval2.js\");\n\tprintf(\"top after duk_peval_file_noresult(): %ld\\n\", (long) duk_get_top(ctx));\n\tprintf(\" --> %ld\\n\", (long) rc);\n\n\t/* Test duk_compile_file() and related. */\n\n\tprintf(\"top before duk_compile_file(): %ld\\n\", (long) duk_get_top(ctx));\n\tduk_compile_file(ctx, 0, \"test_compile1.js\");\n\tprintf(\"top after duk_compile_file(): %ld\\n\", (long) duk_get_top(ctx));\n\tduk_call(ctx, 0);\n\tduk_pop(ctx);\n\n\tprintf(\"top before duk_pcompile_file(): %ld\\n\", (long) duk_get_top(ctx));\n\trc = duk_pcompile_file(ctx, 0, \"test_compile1.js\");\n\tprintf(\"top after duk_pcompile_file(): %ld\\n\", (long) duk_get_top(ctx));\n\tprintf(\" --> %ld: %s\\n\", (long) rc, duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\n\tprintf(\"top before duk_pcompile_file(): %ld\\n\", (long) duk_get_top(ctx));\n\trc = duk_pcompile_file(ctx, 0, \"test_compile2.js\");\n\tprintf(\"top after duk_pcompile_file(): %ld\\n\", (long) duk_get_top(ctx));\n\tprintf(\" --> %ld: %s\\n\", (long) rc, duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\n\tprintf(\"Done\\n\");\n\tduk_destroy_heap(ctx);\n\treturn 0;\n}\n"
  },
  {
    "path": "react_juce/duktape/extras/duk-v1-compat/test_compile1.js",
    "content": "// File to compile, no error\nprint('Hello from test_compile1.js');\nprint(new Error('test error for traceback (shows filename)').stack);\n"
  },
  {
    "path": "react_juce/duktape/extras/duk-v1-compat/test_compile2.js",
    "content": "// File to compile, syntax error\nprint('Hello from test_compile2.js');\n= y +;\n"
  },
  {
    "path": "react_juce/duktape/extras/duk-v1-compat/test_eval1.js",
    "content": "// File to eval, no error\nprint('Hello from test_eval1.js');\nprint(new Error('test error for traceback (shows filename)').stack);\n123;\n"
  },
  {
    "path": "react_juce/duktape/extras/duk-v1-compat/test_eval2.js",
    "content": "// File to eval, throws error\nprint('Hello from test_eval2.js');\nprint(new Error('test error for traceback (shows filename)').stack);\nthrow new Error('aiee');\n"
  },
  {
    "path": "react_juce/duktape/extras/logging/Makefile",
    "content": "# For manual testing; say 'make' in extras/logging and run ./test.\n\nCC = gcc\n\n.PHONY: test\ntest:\n\t-rm -rf ./prep\n\tpython2 ../../tools/configure.py --quiet --output-directory ./prep\n\t$(CC) -std=c99 -Wall -Wextra -otest -I./prep ./prep/duktape.c duk_logging.c test.c -lm\n\t./test 'L = new Duktape.Logger(); L.trace(\"testing\"); L.l = 0; L.trace(\"testing 2\");'\n\t./test 'L = new Duktape.Logger(); L.debug(\"testing\"); L.l = 1; L.debug(\"testing 2\");'\n\t./test 'L = new Duktape.Logger(); L.info(\"testing\");'\n\t./test 'L = new Duktape.Logger(); L.warn(\"testing\");'\n\t./test 'L = new Duktape.Logger(); L.error(\"testing\");'\n\t./test 'L = new Duktape.Logger(); L.fatal(\"testing\");'\n\t./test 'L = new Duktape.Logger(); L.info(\"testing\"); L.n = \"loggerName\"; L.info(\"new name\");'\n\t./test 'L = new Duktape.Logger(\"argname\"); L.info(\"testing\");'\n\n.PHONY: clean\nclean:\n\t-rm -rf ./prep\n\t-rm -f test\n"
  },
  {
    "path": "react_juce/duktape/extras/logging/README.rst",
    "content": "========================================\nDuktape 1.x compatible logging framework\n========================================\n\nThe default ``Duktape.Logger`` object and the logging related C API calls\n(``duk_log()``, ``duk_log_va()``) were removed in Duktape 2.x because they\ndepended on stdout/stderr and were thus a portability issue for some targets\n(there were also other issues, such as the logging framework not always\nmatching user expectations).  This directory contains Duktape 1.x compatible\n``Duktape.Logger`` object and logging API calls:\n\n* Add ``duk_logging.c`` to list of C sources to compile.\n\n* Ensure ``duk_logging.h`` is in the include path.\n\n* Include the extra header in calling code and initialize the bindings::\n\n      #include \"duktape.h\"\n      #include \"duk_logging.h\"\n\n      /* After initializing the Duktape heap or when creating a new\n       * thread with a new global environment:\n       */\n      duk_logging_init(ctx, 0 /*flags*/);\n\n  See ``duk_logging.h`` for available flags.\n\n* After these steps, ``Duktape.Logger`` will be registered to the ``Duktape``\n  object and is ready to use.\n\nSee https://github.com/svaarala/duktape/blob/master/doc/logging.rst and\nhttp://wiki.duktape.org/HowtoLogging.html for more information on the\nlogging framework design and functionality.\n"
  },
  {
    "path": "react_juce/duktape/extras/logging/duk_logging.c",
    "content": "/*\n *  Logging support\n */\n\n#include <stdio.h>\n#include <string.h>\n#include <stdarg.h>\n#include \"duktape.h\"\n#include \"duk_logging.h\"\n\n/* XXX: uses stderr always for now, configurable? */\n\n#define DUK_LOGGING_FLUSH  /* Duktape 1.x: flush stderr */\n\n/* 3-letter log level strings. */\nstatic const char duk__log_level_strings[] = {\n\t'T', 'R', 'C', 'D', 'B', 'G', 'I', 'N', 'F',\n\t'W', 'R', 'N', 'E', 'R', 'R', 'F', 'T', 'L'\n};\n\n/* Log method names. */\nstatic const char *duk__log_method_names[] = {\n\t\"trace\", \"debug\", \"info\", \"warn\", \"error\", \"fatal\"\n};\n\n/* Constructor. */\nstatic duk_ret_t duk__logger_constructor(duk_context *ctx) {\n\tduk_idx_t nargs;\n\n\t/* Calling as a non-constructor is not meaningful. */\n\tif (!duk_is_constructor_call(ctx)) {\n\t\treturn DUK_RET_TYPE_ERROR;\n\t}\n\n\tnargs = duk_get_top(ctx);\n\tduk_set_top(ctx, 1);\n\n\tduk_push_this(ctx);\n\n\t/* [ name this ] */\n\n\tif (nargs == 0) {\n\t\t/* Automatic defaulting of logger name from caller.  This\n\t\t * would work poorly with tail calls, but constructor calls\n\t\t * are currently never tail calls, so tail calls are not an\n\t\t * issue now.\n\t\t */\n\n\t\tduk_inspect_callstack_entry(ctx, -2);\n\t\tif (duk_is_object(ctx, -1)) {\n\t\t\tif (duk_get_prop_string(ctx, -1, \"function\")) {\n\t\t\t\tif (duk_get_prop_string(ctx, -1, \"fileName\")) {\n\t\t\t\t\tif (duk_is_string(ctx, -1)) {\n\t\t\t\t\t\tduk_replace(ctx, 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t/* Leave values on stack on purpose, ignored below. */\n\n\t\t/* Stripping the filename might be a good idea\n\t\t * (\"/foo/bar/quux.js\" -> logger name \"quux\"),\n\t\t * but now used verbatim.\n\t\t */\n\t}\n\t/* The stack is unbalanced here on purpose; we only rely on the\n\t * initial two values: [ name this ].\n\t */\n\n\tif (duk_is_string(ctx, 0)) {\n\t\tduk_dup(ctx, 0);\n\t\tduk_put_prop_string(ctx, 1, \"n\");\n\t} else {\n\t\t/* don't set 'n' at all, inherited value is used as name */\n\t}\n\n\tduk_compact(ctx, 1);\n\n\treturn 0;  /* keep default instance */\n}\n\n/* Default function to format objects.  Tries to use toLogString() but falls\n * back to toString().  Any errors are propagated out without catching.\n */\nstatic duk_ret_t duk__logger_prototype_fmt(duk_context *ctx) {\n\tif (duk_get_prop_string(ctx, 0, \"toLogString\")) {\n\t\t/* [ arg toLogString ] */\n\n\t\tduk_dup(ctx, 0);\n\t\tduk_call_method(ctx, 0);\n\n\t\t/* [ arg result ] */\n\t\treturn 1;\n\t}\n\n\t/* [ arg undefined ] */\n\tduk_pop(ctx);\n\tduk_to_string(ctx, 0);\n\treturn 1;\n}\n\n/* Default function to write a formatted log line.  Writes to stderr,\n * appending a newline to the log line.\n *\n * The argument is a buffer; avoid coercing the buffer to a string to\n * avoid string table traffic.\n */\nstatic duk_ret_t duk__logger_prototype_raw(duk_context *ctx) {\n\tconst char *data;\n\tduk_size_t data_len;\n\n\tdata = (const char *) duk_require_buffer_data(ctx, 0, &data_len);\n\tfwrite((const void *) data, 1, data_len, stderr);\n\tfputc((int) '\\n', stderr);\n#if defined(DUK_LOGGING_FLUSH)\n\tfflush(stderr);\n#endif\n\treturn 0;\n}\n\n/* Log frontend shared helper, magic value indicates log level.  Provides\n * frontend functions: trace(), debug(), info(), warn(), error(), fatal().\n * This needs to have small footprint, reasonable performance, minimal\n * memory churn, etc.\n */\nstatic duk_ret_t duk__logger_prototype_log_shared(duk_context *ctx) {\n\tduk_double_t now;\n\tduk_time_components comp;\n\tduk_small_int_t entry_lev;\n\tduk_small_int_t logger_lev;\n\tduk_int_t nargs;\n\tduk_int_t i;\n\tduk_size_t tot_len;\n\tconst duk_uint8_t *arg_str;\n\tduk_size_t arg_len;\n\tduk_uint8_t *buf, *p;\n\tconst duk_uint8_t *q;\n\tduk_uint8_t date_buf[32];  /* maximum format length is 24+1 (NUL), round up. */\n\tduk_size_t date_len;\n\tduk_small_int_t rc;\n\n\t/* XXX: sanitize to printable (and maybe ASCII) */\n\t/* XXX: better multiline */\n\n\t/*\n\t *  Logger arguments are:\n\t *\n\t *    magic: log level (0-5)\n\t *    this: logger\n\t *    stack: plain log args\n\t *\n\t *  We want to minimize memory churn so a two-pass approach\n\t *  is used: first pass formats arguments and computes final\n\t *  string length, second pass copies strings into a buffer\n\t *  allocated directly with the correct size.  If the backend\n\t *  function plays nice, it won't coerce the buffer to a string\n\t *  (and thus intern it).\n\t */\n\n\tentry_lev = duk_get_current_magic(ctx);\n\tif (entry_lev < DUK_LOG_TRACE || entry_lev > DUK_LOG_FATAL) {\n\t\t/* Should never happen, check just in case. */\n\t\treturn 0;\n\t}\n\tnargs = duk_get_top(ctx);\n\n\t/* [ arg1 ... argN this ] */\n\n\t/*\n\t *  Log level check\n\t */\n\n\tduk_push_this(ctx);\n\n\tduk_get_prop_string(ctx, -1, \"l\");\n\tlogger_lev = (duk_small_int_t) duk_get_int(ctx, -1);\n\tif (entry_lev < logger_lev) {\n\t\treturn 0;\n\t}\n\t/* log level could be popped but that's not necessary */\n\n\tnow = duk_get_now(ctx);\n\tduk_time_to_components(ctx, now, &comp);\n\tsprintf((char *) date_buf, \"%04d-%02d-%02dT%02d:%02d:%02d.%03dZ\",\n\t        (int) comp.year, (int) comp.month + 1, (int) comp.day,\n\t        (int) comp.hours, (int) comp.minutes, (int) comp.seconds,\n\t        (int) comp.milliseconds);\n\n\tdate_len = strlen((const char *) date_buf);\n\n\tduk_get_prop_string(ctx, -2, \"n\");\n\tduk_to_string(ctx, -1);\n\n\t/* [ arg1 ... argN this loggerLevel loggerName ] */\n\n\t/*\n\t *  Pass 1\n\t */\n\n\t/* Line format: <time> <entryLev> <loggerName>: <msg> */\n\n\ttot_len = 0;\n\ttot_len += 3 +  /* separators: space, space, colon */\n\t           3 +  /* level string */\n\t           date_len +  /* time */\n\t           duk_get_length(ctx, -1);  /* loggerName */\n\n\tfor (i = 0; i < nargs; i++) {\n\t\t/* When formatting an argument to a string, errors may happen from multiple\n\t\t * causes.  In general we want to catch obvious errors like a toLogString()\n\t\t * throwing an error, but we don't currently try to catch every possible\n\t\t * error.  In particular, internal errors (like out of memory or stack) are\n\t\t * not caught.  Also, we expect Error toString() to not throw an error.\n\t\t */\n\t\tif (duk_is_object(ctx, i)) {\n\t\t\t/* duk_pcall_prop() may itself throw an error, but we're content\n\t\t\t * in catching the obvious errors (like toLogString() throwing an\n\t\t\t * error).\n\t\t\t */\n\t\t\tduk_push_string(ctx, \"fmt\");\n\t\t\tduk_dup(ctx, i);\n\t\t\t/* [ arg1 ... argN this loggerLevel loggerName 'fmt' arg ] */\n\t\t\t/* call: this.fmt(arg) */\n\t\t\trc = duk_pcall_prop(ctx, -5 /*obj_index*/, 1 /*nargs*/);\n\t\t\tif (rc) {\n\t\t\t\t/* Keep the error as the result (coercing it might fail below,\n\t\t\t\t * but we don't catch that now).\n\t\t\t\t */\n\t\t\t\t;\n\t\t\t}\n\t\t\tduk_replace(ctx, i);\n\t\t}\n\t\t(void) duk_to_lstring(ctx, i, &arg_len);\n\t\ttot_len++;  /* sep (even before first one) */\n\t\ttot_len += arg_len;\n\t}\n\n\t/*\n\t *  Pass 2\n\t */\n\n\t/* XXX: Here it'd be nice if we didn't need to allocate a new fixed\n\t * buffer for every write.  This would be possible if raw() took a\n\t * buffer and a length.  We could then use a preallocated buffer for\n\t * most log writes and request raw() to write a partial buffer.\n\t */\n\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer(ctx, tot_len);\n\tp = buf;\n\n\tmemcpy((void *) p, (const void *) date_buf, (size_t) date_len);\n\tp += date_len;\n\t*p++ = (duk_uint8_t) ' ';\n\n\tq = (const duk_uint8_t *) duk__log_level_strings + (entry_lev * 3);\n\tmemcpy((void *) p, (const void *) q, (size_t) 3);\n\tp += 3;\n\n\t*p++ = (duk_uint8_t) ' ';\n\n\targ_str = (const duk_uint8_t *) duk_get_lstring(ctx, -2, &arg_len);\n\tmemcpy((void *) p, (const void *) arg_str, (size_t) arg_len);\n\tp += arg_len;\n\n\t*p++ = (duk_uint8_t) ':';\n\n\tfor (i = 0; i < nargs; i++) {\n\t\t*p++ = (duk_uint8_t) ' ';\n\n\t\targ_str = (const duk_uint8_t *) duk_get_lstring(ctx, i, &arg_len);\n\t\tmemcpy((void *) p, (const void *) arg_str, (size_t) arg_len);\n\t\tp += arg_len;\n\t}\n\n\t/* [ arg1 ... argN this loggerLevel loggerName buffer ] */\n\n\t/* Call this.raw(msg); look up through the instance allows user to override\n\t * the raw() function in the instance or in the prototype for maximum\n\t * flexibility.\n\t */\n\tduk_push_string(ctx, \"raw\");\n\tduk_dup(ctx, -2);\n\t/* [ arg1 ... argN this loggerLevel loggerName buffer 'raw' buffer ] */\n\tduk_call_prop(ctx, -6, 1);  /* this.raw(buffer) */\n\n\treturn 0;\n}\n\nvoid duk_log_va(duk_context *ctx, duk_int_t level, const char *fmt, va_list ap) {\n\tif (level < 0) {\n\t\tlevel = 0;\n\t} else if (level > (int) (sizeof(duk__log_method_names) / sizeof(const char *)) - 1) {\n\t\tlevel = (int) (sizeof(duk__log_method_names) / sizeof(const char *)) - 1;\n\t}\n\n\tduk_push_global_stash(ctx);\n\tduk_get_prop_string(ctx, -1, \"\\xff\" \"logger:constructor\");  /* fixed at init time */\n\tduk_get_prop_string(ctx, -1, \"clog\");\n\tduk_get_prop_string(ctx, -1, duk__log_method_names[level]);\n\tduk_dup(ctx, -2);\n\tduk_push_vsprintf(ctx, fmt, ap);\n\n\t/* [ ... stash Logger clog logfunc clog(=this) msg ] */\n\n\tduk_call_method(ctx, 1 /*nargs*/);\n\n\t/* [ ... stash Logger clog res ] */\n\n\tduk_pop_n(ctx, 4);\n}\n\nvoid duk_log(duk_context *ctx, duk_int_t level, const char *fmt, ...) {\n\tva_list ap;\n\n\tva_start(ap, fmt);\n\tduk_log_va(ctx, level, fmt, ap);\n\tva_end(ap);\n}\n\nvoid duk_logging_init(duk_context *ctx, duk_uint_t flags) {\n\t/* XXX: Add .name property for logger functions (useful for stack traces if they throw). */\n\n\t(void) flags;\n\n\tduk_eval_string(ctx,\n\t\t\"(function(cons,prot){\"\n\t\t\"Object.defineProperty(Duktape,'Logger',{value:cons,writable:true,configurable:true});\"\n\t\t\"Object.defineProperty(cons,'prototype',{value:prot});\"\n\t\t\"Object.defineProperty(cons,'clog',{value:new Duktape.Logger('C'),writable:true,configurable:true});\"\n\t\t\"});\");\n\n\tduk_push_c_function(ctx, duk__logger_constructor, DUK_VARARGS /*nargs*/);  /* Duktape.Logger */\n\tduk_push_object(ctx);  /* Duktape.Logger.prototype */\n\n\t/* [ ... func Duktape.Logger Duktape.Logger.prototype ] */\n\n\tduk_push_string(ctx, \"name\");\n\tduk_push_string(ctx, \"Logger\");\n\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_FORCE);\n\n\tduk_dup_top(ctx);\n\tduk_put_prop_string(ctx, -2, \"constructor\");\n\tduk_push_int(ctx, 2);\n\tduk_put_prop_string(ctx, -2, \"l\");\n\tduk_push_string(ctx, \"anon\");\n\tduk_put_prop_string(ctx, -2, \"n\");\n\tduk_push_c_function(ctx, duk__logger_prototype_fmt, 1 /*nargs*/);\n\tduk_put_prop_string(ctx, -2, \"fmt\");\n\tduk_push_c_function(ctx, duk__logger_prototype_raw, 1 /*nargs*/);\n\tduk_put_prop_string(ctx, -2, \"raw\");\n\tduk_push_c_function(ctx, duk__logger_prototype_log_shared, DUK_VARARGS /*nargs*/);\n\tduk_set_magic(ctx, -1, 0);  /* magic=0: trace */\n\tduk_put_prop_string(ctx, -2, \"trace\");\n\tduk_push_c_function(ctx, duk__logger_prototype_log_shared, DUK_VARARGS /*nargs*/);\n\tduk_set_magic(ctx, -1, 1);  /* magic=1: debug */\n\tduk_put_prop_string(ctx, -2, \"debug\");\n\tduk_push_c_function(ctx, duk__logger_prototype_log_shared, DUK_VARARGS /*nargs*/);\n\tduk_set_magic(ctx, -1, 2);  /* magic=2: info */\n\tduk_put_prop_string(ctx, -2, \"info\");\n\tduk_push_c_function(ctx, duk__logger_prototype_log_shared, DUK_VARARGS /*nargs*/);\n\tduk_set_magic(ctx, -1, 3);  /* magic=3: warn */\n\tduk_put_prop_string(ctx, -2, \"warn\");\n\tduk_push_c_function(ctx, duk__logger_prototype_log_shared, DUK_VARARGS /*nargs*/);\n\tduk_set_magic(ctx, -1, 4);  /* magic=4: error */\n\tduk_put_prop_string(ctx, -2, \"error\");\n\tduk_push_c_function(ctx, duk__logger_prototype_log_shared, DUK_VARARGS /*nargs*/);\n\tduk_set_magic(ctx, -1, 5);  /* magic=5: fatal */\n\tduk_put_prop_string(ctx, -2, \"fatal\");\n\n\t/* [ ... func Duktape.Logger Duktape.Logger.prototype ] */\n\n\t/* XXX: when using ROM built-ins, \"Duktape\" is read-only by default so\n\t * setting Duktape.Logger will now fail.\n\t */\n\n\t/* [ ... func Duktape.Logger Duktape.Logger.prototype ] */\n\n\tduk_call(ctx, 2);\n\tduk_pop(ctx);\n}\n"
  },
  {
    "path": "react_juce/duktape/extras/logging/duk_logging.h",
    "content": "#if !defined(DUK_LOGGING_H_INCLUDED)\n#define DUK_LOGGING_H_INCLUDED\n\n#include \"duktape.h\"\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/* Log levels. */\n#define DUK_LOG_TRACE                     0\n#define DUK_LOG_DEBUG                     1\n#define DUK_LOG_INFO                      2\n#define DUK_LOG_WARN                      3\n#define DUK_LOG_ERROR                     4\n#define DUK_LOG_FATAL                     5\n\n/* No flags at the moment. */\n\nextern void duk_logging_init(duk_context *ctx, duk_uint_t flags);\nextern void duk_log_va(duk_context *ctx, duk_int_t level, const char *fmt, va_list ap);\nextern void duk_log(duk_context *ctx, duk_int_t level, const char *fmt, ...);\n\n#if defined(__cplusplus)\n}\n#endif  /* end 'extern \"C\"' wrapper */\n\n#endif  /* DUK_LOGGING_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/extras/logging/test.c",
    "content": "#include <stdio.h>\n#include \"duktape.h\"\n#include \"duk_logging.h\"\n\nstatic duk_ret_t init_logging(duk_context *ctx, void *udata) {\n\t(void) udata;\n\tduk_logging_init(ctx, 0 /*flags*/);\n\tprintf(\"top after init: %ld\\n\", (long) duk_get_top(ctx));\n\n\t/* C API test */\n\tduk_eval_string_noresult(ctx, \"Duktape.Logger.clog.l = 0;\");\n\tduk_log(ctx, DUK_LOG_TRACE, \"c logger test: %d\", 123);\n\tduk_log(ctx, DUK_LOG_DEBUG, \"c logger test: %d\", 123);\n\tduk_log(ctx, DUK_LOG_INFO, \"c logger test: %d\", 123);\n\tduk_log(ctx, DUK_LOG_WARN, \"c logger test: %d\", 123);\n\tduk_log(ctx, DUK_LOG_ERROR, \"c logger test: %d\", 123);\n\tduk_log(ctx, DUK_LOG_FATAL, \"c logger test: %d\", 123);\n\tduk_log(ctx, -1, \"negative level: %s %d 0x%08lx\", \"arg string\", -123, 0xdeadbeefUL);\n\tduk_log(ctx, 6, \"level too large: %s %d 0x%08lx\", \"arg string\", 123, 0x1234abcdUL);\n\n\treturn 0;\n}\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx;\n\tint i;\n\tint exitcode = 0;\n\n\tctx = duk_create_heap_default();\n\tif (!ctx) {\n\t\treturn 1;\n\t}\n\n\t(void) duk_safe_call(ctx, init_logging, NULL, 0, 1);\n\tprintf(\"logging init: %s\\n\", duk_safe_to_string(ctx, -1));\n\tduk_pop(ctx);\n\n\tfor (i = 1; i < argc; i++) {\n\t\tprintf(\"Evaling: %s\\n\", argv[i]);\n\t\tduk_push_string(ctx, argv[i]);\n\t\tduk_push_string(ctx, \"evalCodeFileName\");  /* for automatic logger name testing */\n\t\tif (duk_pcompile(ctx, DUK_COMPILE_EVAL) != 0) {\n\t\t\texitcode = 1;\n\t\t} else {\n\t\t\tif (duk_pcall(ctx, 0) != 0) {\n\t\t\t\texitcode = 1;\n\t\t\t}\n\t\t}\n\t\tprintf(\"--> %s\\n\", duk_safe_to_string(ctx, -1));\n\t\tduk_pop(ctx);\n\t}\n\n\tprintf(\"Done\\n\");\n\tduk_destroy_heap(ctx);\n\treturn exitcode;\n}\n"
  },
  {
    "path": "react_juce/duktape/extras/minimal-printf/Makefile",
    "content": "# Just for manual testing\nCC = gcc\n\n.PHONY: test\ntest: duk_minimal_printf.c\n\t$(CC) -std=c99 -Wall -Wextra -fno-stack-protector -m32 -Os -fomit-frame-pointer -otest duk_minimal_printf.c test.c\n\t./test\n"
  },
  {
    "path": "react_juce/duktape/extras/minimal-printf/README.rst",
    "content": "==============================================\nMinimal sprintf/sscanf replacement for Duktape\n==============================================\n\nThe ``duk_minimal_printf.c`` provides a portable provider for sprintf()/scanf()\nwith a feature set matching minimally what Duktape internals need.  The provider\ncompiles to less than 1kB.  The functions provided are::\n\n    sprintf()\n    snprintf()\n    vsnprintf()\n    sscanf()\n\nIn addition to Duktape internals, the set of supported formats affects the\n``duk_push_(v)sprintf()`` call which may have an impact on user code.\n\nAssumptions:\n\n* ``sizeof(void *) <= sizeof(long)``\n\n* ``sizeof(long) <= 8``\n\nNote that these assumptions don't hold e.g. on 64-bit Windows.  This printf\nprovider is mostly useful for low memory targets where these assumptions are\ntypically not an issue.  The limitations are easy to fix if one relies more\non platform typing.\n\nSupported formatting\n====================\n\nsprintf()\n---------\n\nDuktape relies on a ``sprintf()`` provider which supports at least the\nfollowing (this list is from Duktape 1.5.0)::\n\n    %c\n    %s\n    %p\n\n    %02d\n    %03d\n    %ld\n    %lld    (JSON fast path only)\n\n    %lu\n\n    %lx\n    %02lx\n    %08lx\n\nThis minimal provider supports the following slightly different, wider set.\n\n* Character format ``%c``.\n\n* String format ``%s``.\n\n* Pointer format ``%p``.\n\n* Integer formats ``%d``, ``%ld``, ``%lu`` with optional padding and\n  length modifiers.\n\n* Hex formats ``%x``, ``%lx`` with optional padding and length modifiers.\n\nThe wider set is useful to make ``duk_push_(v)sprintf()`` behave reasonably\nfor any user code call sites.\n\nThe ``%lld`` format is not supported to avoid depending on the ``long long``\ntype; this makes the replacement incompatible with the JSON fast path which\nmust thus be disabled.\n\nsscanf()\n--------\n\nThere's only one call site for ``sscanf()``, for JX parsing of pointers::\n\n    duk_bi_json.c:        (void) DUK_SSCANF((const char *) js_ctx->p, DUK_STR_FMT_PTR, &voidptr);\n\nThe exact format string here is ``%p`` and nothing else needs to be supported.\nFurther, when the minimal printf/scanf providers are used together we only\nneed to parse what we produce.  In particular:\n\n* Pointer prefix is ``0x``, no need to match ``0X`` for example.\n\n* All digits are ``[0-9a-f]`` with no need to match uppercase.\n\nBuilding \"duk\" with minimal printf/scanf\n========================================\n\nThe necessary defines in ``duk_config.h`` can be given to genconfig, but you\ncan also just make the following manual additions to the bottom of the config\nfile::\n\n    #include \"duk_minimal_printf.h\"\n\n    #undef DUK_SPRINTF\n    #define DUK_SPRINTF duk_minimal_sprintf\n    #undef DUK_SNPRINTF\n    #define DUK_SNPRINTF duk_minimal_snprintf\n    #undef DUK_VSNPRINTF\n    #define DUK_VSNPRINTF duk_minimal_vsnprintf\n    #undef DUK_SSCANF\n    #define DUK_SSCANF duk_minimal_sscanf\n\nThen just add ``duk_minimal_printf.c`` to build and compile the application.\n\nFuture work\n===========\n\n* Add support for ``%lld`` (maybe conditional) to allow JSON fast path to\n  be supported.\n\n* Add support for platforms such as 64-bit Windows where\n  ``sizeof(long) < sizeof(void *)``.  This can be achieved by using a few\n  typedefs internally; typedef an integer type large enough to hold all\n  formatted types.\n"
  },
  {
    "path": "react_juce/duktape/extras/minimal-printf/duk_minimal_printf.c",
    "content": "/*\n *  Minimal vsnprintf(), snprintf(), sprintf(), and sscanf() for Duktape.\n *  The supported conversion formats narrowly match what Duktape needs.\n */\n\n#include <stdarg.h>  /* va_list etc */\n#include <stddef.h>  /* size_t */\n#include <stdint.h>  /* SIZE_MAX */\n\n/* Write character with bound checking.  Offset 'off' is updated regardless\n * of whether an actual write is made.  This is necessary to satisfy snprintf()\n * return value semantics.\n */\n#define DUK__WRITE_CHAR(c) do { \\\n\t\tif (off < size) { \\\n\t\t\tstr[off] = (char) c; \\\n\t\t} \\\n\t\toff++; \\\n\t} while (0)\n\n/* Digits up to radix 16. */\nstatic const char duk__format_digits[16] = {\n\t'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'\n};\n\n/* Format an unsigned long with various options.  An unsigned long is large\n * enough for formatting all supported types.\n */\nstatic size_t duk__format_long(char *str,\n                               size_t size,\n                               size_t off,\n                               int fixed_length,\n                               char pad,\n                               int radix,\n                               int neg_sign,\n                               unsigned long v) {\n\tchar buf[24];  /* 2^64 = 18446744073709552000, length 20 */\n\tchar *required;\n\tchar *p;\n\tint i;\n\n\t/* Format in reverse order first.  Ensure at least one digit is output\n\t * to handle '0' correctly.  Note that space padding and zero padding\n\t * handle negative sign differently:\n\t *\n\t *     %9d and -321  => '     -321'\n\t *     %09d and -321 => '-00000321'\n\t */\n\n\tfor (i = 0; i < (int) sizeof(buf); i++) {\n\t\tbuf[i] = pad;  /* compiles into memset() equivalent, avoid memset() dependency */\n\t}\n\n\tp = buf;\n\tdo {\n\t\t*p++ = duk__format_digits[v % radix];\n\t\tv /= radix;\n\t} while (v != 0);\n\n\trequired = buf + fixed_length;\n\tif (p < required && pad == (char) '0') {\n\t\t/* Zero padding and we didn't reach maximum length: place\n\t\t * negative sign at the last position.  We can't get here\n\t\t * with fixed_length == 0 so that required[-1] is safe.\n\t\t *\n\t\t * Technically we should only do this for 'neg_sign == 1',\n\t\t * but it's OK to advance the pointer even when that's not\n\t\t * the case.\n\t\t */\n\t\tp = required - 1;\n\t}\n\tif (neg_sign) {\n\t\t*p++ = (char) '-';\n\t}\n\tif (p < required) {\n\t\tp = required;\n\t}\n\n\t/* Now [buf,p[ contains the result in reverse; copy into place. */\n\n\twhile (p > buf) {\n\t\tp--;\n\t\tDUK__WRITE_CHAR(*p);\n\t}\n\n\treturn off;\n}\n\n/* Parse a pointer.  Must parse whatever is produced by '%p' in sprintf(). */\nstatic int duk__parse_pointer(const char *str, void **out) {\n\tconst unsigned char *p;\n\tunsigned char ch;\n\tint count;\n\tint limit;\n\tlong val;  /* assume void * fits into long */\n\n\t/* We only need to parse what our minimal printf() produces, so that\n\t * we can check for a '0x' prefix, and assume all hex digits are\n\t * lowercase.\n\t */\n\n\tp = (const unsigned char *) str;\n\tif (p[0] != (unsigned char) '0' || p[1] != (unsigned char) 'x') {\n\t\treturn 0;\n\t}\n\tp += 2;\n\n\tfor (val = 0, count = 0, limit = sizeof(void *) * 2; count < limit; count++) {\n\t\tch = *p++;\n\n\t\tval <<= 4;\n\t\tif (ch >= (unsigned char) '0' && ch <= (unsigned char) '9') {\n\t\t\tval += ch - (unsigned char) '0';\n\t\t} else if (ch >= (unsigned char) 'a' && ch <= (unsigned char) 'f') {\n\t\t\tval += ch - (unsigned char) 'a' + 0x0a;\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* The input may end at a NUL or garbage may follow.  As long as we\n\t * parse the '%p' correctly, garbage is allowed to follow, and the\n\t * JX pointer parsing also relies on that.\n\t */\n\n\t*out = (void *) val;\n\treturn 1;\n}\n\n/* Minimal vsnprintf() entry point. */\nint duk_minimal_vsnprintf(char *str, size_t size, const char *format, va_list ap) {\n\tsize_t off = 0;\n\tconst char *p;\n#if 0\n\tconst char *p_tmp;\n\tconst char *p_fmt_start;\n#endif\n\tchar c;\n\tchar pad;\n\tint fixed_length;\n\tint is_long;\n\n\t/* Assume str != NULL unless size == 0.\n\t * Assume format != NULL.\n\t */\n\n\tp = format;\n\tfor (;;) {\n\t\tc = *p++;\n\t\tif (c == (char) 0) {\n\t\t\tbreak;\n\t\t}\n\t\tif (c != (char) '%') {\n\t\t\tDUK__WRITE_CHAR(c);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Start format sequence.  Scan flags and format specifier. */\n\n#if 0\n\t\tp_fmt_start = p - 1;\n#endif\n\t\tis_long = 0;\n\t\tpad = ' ';\n\t\tfixed_length = 0;\n\t\tfor (;;) {\n\t\t\tc = *p++;\n\t\t\tif (c == (char) 'l') {\n\t\t\t\tis_long = 1;\n\t\t\t} else if (c == (char) '0') {\n\t\t\t\t/* Only support pad character '0'. */\n\t\t\t\tpad = '0';\n\t\t\t} else if (c >= (char) '1' && c <= (char) '9') {\n\t\t\t\t/* Only support fixed lengths 1-9. */\n\t\t\t\tfixed_length = (int) (c - (char) '0');\n\t\t\t} else if (c == (char) 'd') {\n\t\t\t\tlong v;\n\t\t\t\tint neg_sign = 0;\n\t\t\t\tif (is_long) {\n\t\t\t\t\tv = va_arg(ap, long);\n\t\t\t\t} else {\n\t\t\t\t\tv = (long) va_arg(ap, int);\n\t\t\t\t}\n\t\t\t\tif (v < 0) {\n\t\t\t\t\tneg_sign = 1;\n\t\t\t\t\tv = -v;\n\t\t\t\t}\n\t\t\t\toff = duk__format_long(str, size, off, fixed_length, pad, 10, neg_sign, (unsigned long) v);\n\t\t\t\tbreak;\n\t\t\t} else if (c == (char) 'u') {\n\t\t\t\tunsigned long v;\n\t\t\t\tif (is_long) {\n\t\t\t\t\tv = va_arg(ap, unsigned long);\n\t\t\t\t} else {\n\t\t\t\t\tv = (unsigned long) va_arg(ap, unsigned int);\n\t\t\t\t}\n\t\t\t\toff = duk__format_long(str, size, off, fixed_length, pad, 10, 0, v);\n\t\t\t\tbreak;\n\t\t\t} else if (c == (char) 'x') {\n\t\t\t\tunsigned long v;\n\t\t\t\tif (is_long) {\n\t\t\t\t\tv = va_arg(ap, unsigned long);\n\t\t\t\t} else {\n\t\t\t\t\tv = (unsigned long) va_arg(ap, unsigned int);\n\t\t\t\t}\n\t\t\t\toff = duk__format_long(str, size, off, fixed_length, pad, 16, 0, v);\n\t\t\t\tbreak;\n\t\t\t} else if (c == (char) 'c') {\n\t\t\t\tchar v;\n\t\t\t\tv = (char) va_arg(ap, int);  /* intentionally not 'char' */\n\t\t\t\tDUK__WRITE_CHAR(v);\n\t\t\t\tbreak;\n\t\t\t} else if (c == (char) 's') {\n\t\t\t\tconst char *v;\n\t\t\t\tchar c_tmp;\n\t\t\t\tv = va_arg(ap, const char *);\n\t\t\t\tif (v) {\n\t\t\t\t\tfor (;;) {\n\t\t\t\t\t\tc_tmp = *v++;\n\t\t\t\t\t\tif (c_tmp) {\n\t\t\t\t\t\t\tDUK__WRITE_CHAR(c_tmp);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t} else if (c == (char) 'p') {\n\t\t\t\t/* Assume a void * can be represented by 'long'.  This is not\n\t\t\t\t * always the case.  NULL pointer is printed out as 0x0000...\n\t\t\t\t */\n\t\t\t\tvoid *v;\n\t\t\t\tv = va_arg(ap, void *);\n\t\t\t\tDUK__WRITE_CHAR('0');\n\t\t\t\tDUK__WRITE_CHAR('x');\n\t\t\t\toff = duk__format_long(str, size, off, sizeof(void *) * 2, '0', 16, 0, (unsigned long) v);\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t/* Unrecognized, bail out early.  We could also emit the format\n\t\t\t\t * specifier verbatim, but it'd be a waste of footprint because\n\t\t\t\t * this case should never happen in practice.\n\t\t\t\t */\n#if 0\n\t\t\t\tDUK__WRITE_CHAR('!');\n#endif\n#if 0\n\t\t\t\tfor (p_tmp = p_fmt_start; p_tmp != p; p_tmp++) {\n\t\t\t\t\tDUK__WRITE_CHAR(*p_tmp);\n\t\t\t\t}\n\t\t\t\tbreak;\n#endif\n\t\t\t\tgoto finish;\n\t\t\t}\n\t\t}\n\t}\n\n finish:\n\tif (off < size) {\n\t\tstr[off] = (char) 0;  /* No increment for 'off', not counted in return value. */\n\t} else if (size > 0) {\n\t\t/* Forced termination. */\n\t\tstr[size - 1] = 0;\n\t}\n\n\treturn (int) off;\n}\n\n/* Minimal snprintf() entry point. */\nint duk_minimal_snprintf(char *str, size_t size, const char *format, ...) {\n\tva_list ap;\n\tint ret;\n\n\tva_start(ap, format);\n\tret = duk_minimal_vsnprintf(str, size, format, ap);\n\tva_end(ap);\n\n\treturn ret;\n}\n\n/* Minimal sprintf() entry point. */\nint duk_minimal_sprintf(char *str, const char *format, ...) {\n\tva_list ap;\n\tint ret;\n\n\tva_start(ap, format);\n\tret = duk_minimal_vsnprintf(str, SIZE_MAX, format, ap);\n\tva_end(ap);\n\n\treturn ret;\n}\n\n/* Minimal sscanf() entry point. */\nint duk_minimal_sscanf(const char *str, const char *format, ...) {\n\tva_list ap;\n\tint ret;\n\tvoid **out;\n\n\t/* Only the exact \"%p\" format is supported. */\n\tif (format[0] != (char) '%' ||\n\t    format[1] != (char) 'p' ||\n\t    format[2] != (char) 0) {\n\t}\n\n\tva_start(ap, format);\n\tout = va_arg(ap, void **);\n\tret = duk__parse_pointer(str, out);\n\tva_end(ap);\n\n\treturn ret;\n}\n\n#undef DUK__WRITE_CHAR\n"
  },
  {
    "path": "react_juce/duktape/extras/minimal-printf/duk_minimal_printf.h",
    "content": "#if !defined(DUK_MINIMAL_PRINTF_H_INCLUDED)\n#define DUK_MINIMAL_PRINTF_H_INCLUDED\n\n#include <stdarg.h>  /* va_list etc */\n#include <stddef.h>  /* size_t */\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\nextern int duk_minimal_sprintf(char *str, const char *format, ...);\nextern int duk_minimal_snprintf(char *str, size_t size, const char *format, ...);\nextern int duk_minimal_vsnprintf(char *str, size_t size, const char *format, va_list ap);\nextern int duk_minimal_sscanf(const char *str, const char *format, ...);\n\n#if defined(__cplusplus)\n}\n#endif  /* end 'extern \"C\"' wrapper */\n\n#endif  /* DUK_MINIMAL_PRINTF_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/extras/minimal-printf/test.c",
    "content": "#include <stdio.h>\n#include <string.h>\n#include \"duk_minimal_printf.h\"\n\nchar buffer[32];\n\nstatic void init_buffer(void) {\n\tint i;\n\n\tfor (i = 0; i < (int) sizeof(buffer); i++) {\n\t\tbuffer[i] = 0xff;\n\t}\n}\n\nstatic void dump_buffer(void) {\n\tint i;\n\tunsigned char c;\n\n\tprintf(\"Buffer: '\");\n\tfor (i = 0; i < (int) sizeof(buffer); i++) {\n\t\tc = (unsigned char) buffer[i];\n\t\tif (c < 0x20 || c >= 0x7e) {\n\t\t\tprintf(\"<%02x>\", (unsigned int) c);\n\t\t} else {\n\t\t\tprintf(\"%c\", (int) c);\n\t\t}\n\t}\n\tprintf(\"'\");\n#if 0\n\tprintf(\" -> \");\n\tprintf(\"Buffer:\");\n\tfor (i = 0; i < sizeof(buffer); i++) {\n\t\tc = (unsigned char) buffer[i];\n\t\tif (c <= 0x20 || c >= 0x7e) {\n\t\t\tprintf(\" <%02x>\", (unsigned int) c);\n\t\t} else {\n\t\t\tprintf(\" %c\", (char) c);\n\t\t}\n\t}\n#endif\n\tprintf(\"\\n\");\n}\n\nint main(int argc, char *argv[]) {\n\tint ret;\n\tvoid *voidptr;\n\tint i;\n\n\t(void) argc; (void) argv;\n\n\t/* Char format. */\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, sizeof(buffer), \"foo %c bar\", 'Z');\n\tdump_buffer();\n\n\t/* Signed long format. */\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, sizeof(buffer), \"%ld %9ld\", (long) 123, (long) 4321);\n\tdump_buffer();\n\n\t/* Signed long with zero padding. */\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, sizeof(buffer), \"%09ld\", (long) 4321);\n\tdump_buffer();\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, sizeof(buffer), \"%03ld %03ld %03ld\", (long) -4321, (long) -432, (long) -43);\n\tdump_buffer();\n\n\t/* Unsigned long with zero padding. */\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, sizeof(buffer), \"%03lu %03lu %03lu\", (long) -4321, (long) -432, (long) -43);\n\tdump_buffer();\n\n\t/* Signed integer. */\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, sizeof(buffer), \"%d %9d\", (int) 0, (int) 4321);\n\tdump_buffer();\n\n\t/* Signed negative integer, fixed field width. */\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, sizeof(buffer), \"%9d\", (int) -321);\n\tdump_buffer();\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, sizeof(buffer), \"%09d\", (int) -321);\n\tdump_buffer();\n\tprintf(\"  -- printf comparison: %9d %09d\\n\", -321, -321);\n\n\t/* Hex formatting. */\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, sizeof(buffer), \"%03x %03lx 0x%08lx\", (int) 510, (long) 5105, (long) 0xdeadbeef);\n\tdump_buffer();\n\n\t/* Pointer formatting, NULL and non-NULL. */\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, sizeof(buffer), \"%p %p\", (void *) NULL, (void *) buffer);\n\tdump_buffer();\n\n\t/* File/line like format test. */\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, sizeof(buffer), \"%s:%d\", \"foo bar quux\", 123);\n\tdump_buffer();\n\n\t/* Zero size output buffer. */\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, 0, \"%s:%d\", \"foo bar quux\", 123);\n\tdump_buffer();\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, 0, \"\");\n\tdump_buffer();\n\n\t/* NUL terminator boundary test. */\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, 7, \"foo: %s\", \"bar\");\n\tdump_buffer();\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, 8, \"foo: %s\", \"bar\");\n\tdump_buffer();\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, 9, \"foo: %s\", \"bar\");\n\tdump_buffer();\n\n\t/* sprintf() binding, uses SIZE_MAX internally. */\n\tinit_buffer();\n\tduk_minimal_sprintf(buffer, \"unbounded print %s\", \"foo\");\n\tdump_buffer();\n\n\t/* Pointer formatting; non-NULL and NULL. */\n\tinit_buffer();\n\tduk_minimal_snprintf(buffer, sizeof(buffer), \"%p %p\", (void *) NULL, (void *) 0xdeadbeef);\n\tdump_buffer();\n\n\t/* Pointer parsing, non-NULL (32-bit) pointer. */\n\tvoidptr = (void *) 123;\n\tret = duk_minimal_sscanf(\"0xdeadbeef\", \"%p\", &voidptr);\n\tprintf(\"ret=%d, void pointer: %p\\n\", ret, voidptr);\n\n\t/* Pointer parsing, NULL (32-bit) pointer. */\n\tvoidptr = (void *) 123;\n\tret = duk_minimal_sscanf(\"0x00000000\", \"%p\", &voidptr);\n\tprintf(\"ret=%d, void pointer: %p\\n\", ret, voidptr);\n\n\t/* Pointer parsing, non-NULL (32-bit) pointer but garbage follows. */\n\tvoidptr = (void *) 123;\n\tret = duk_minimal_sscanf(\"0xdeadbeefx\", \"%p\", &voidptr);\n\tprintf(\"ret=%d, void pointer: %p\\n\", ret, voidptr);\n\n\t/* Fixed width test over a range of widths. */\n\tfor (i = 0; i <= 9; i++) {\n\t\tchar fmtbuf[16];\n\n\t\tprintf(\"--- pos/neg fixed width test, i=%d\\n\", i);\n\n\t\t/* %0<i>d. %00d makes no sense, but tested anyway. */\n\t\tmemset((void *) fmtbuf, 0, sizeof(fmtbuf));\n\t\tfmtbuf[0] = (char) '%';\n\t\tfmtbuf[1] = (char) '0';\n\t\tfmtbuf[2] = (char) ('0' + i);\n\t\tfmtbuf[3] = 'd';\n\t\tinit_buffer();\n\t\tduk_minimal_sprintf(buffer, (const char *) fmtbuf, 321);\n\t\tdump_buffer();\n\t\tinit_buffer();\n\t\tduk_minimal_sprintf(buffer, (const char *) fmtbuf, -321);\n\t\tdump_buffer();\n\t\tprintf(\"  ==> printf: |\");\n\t\tprintf((const char *) fmtbuf, 321);\n\t\tprintf(\"| |\");\n\t\tprintf((const char *) fmtbuf, -321);\n\t\tprintf(\"|\\n\");\n\n\t\t/* %<i>d. */\n\t\tmemset((void *) fmtbuf, 0, sizeof(fmtbuf));\n\t\tfmtbuf[0] = (char) '%';\n\t\tfmtbuf[1] = (char) ('0' + i);\n\t\tfmtbuf[2] = 'd';\n\t\tinit_buffer();\n\t\tduk_minimal_sprintf(buffer, (const char *) fmtbuf, 321);\n\t\tdump_buffer();\n\t\tinit_buffer();\n\t\tduk_minimal_sprintf(buffer, (const char *) fmtbuf, -321);\n\t\tdump_buffer();\n\t\tprintf(\"  ==> printf: |\");\n\t\tprintf((const char *) fmtbuf, 321);\n\t\tprintf(\"| |\");\n\t\tprintf((const char *) fmtbuf, -321);\n\t\tprintf(\"|\\n\");\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "react_juce/duktape/extras/module-duktape/Makefile",
    "content": "# For manual testing; say 'make' in extras/module-duktape and run ./test.\n# There's test coverage in tests/ecmascript, so tests here are very simple.\n\nCC = gcc\n\n.PHONY: test\ntest:\n\t-rm -rf ./prep\n\tpython2 ../../tools/configure.py --quiet --output-directory ./prep\n\t$(CC) -std=c99 -Wall -Wextra -o $@ -I./prep -I. ./prep/duktape.c duk_module_duktape.c test.c -lm\n\t@printf '\\n'\n\t./test 'assert(typeof require === \"function\");'\n\t./test 'assert(require.name === \"require\");'\n\t./test 'assert(typeof Duktape.modLoaded === \"object\");'\n\t./test 'assert(typeof Duktape.modSearch === \"undefined\");'\n\t./test 'Duktape.modSearch = function myModSearch(id) { return \"exports.foo = 123;\" }; assert(require(\"dummy\").foo === 123);'\n\t./test 'Duktape.modSearch = function myModSearch(id) { return \"exports.foo = 234;\" }; delete Duktape; assert(typeof Duktape === \"undefined\"); assert(require(\"dummy\").foo === 234);'\n\t./test 'Duktape.modSearch = function myModSearch(id) { return \"exports.foo = 234; // comment\" }; delete Duktape; assert(typeof Duktape === \"undefined\"); assert(require(\"dummy\").foo === 234);'\n\n.PHONY: clean\nclean:\n\t-rm -rf ./prep\n\t-rm -f test\n"
  },
  {
    "path": "react_juce/duktape/extras/module-duktape/README.rst",
    "content": "===============================================\nDuktape 1.x compatible module loading framework\n===============================================\n\nThe default built-in module loading framework was removed in Duktape 2.x\nbecause more flexibility was needed for module loading.  This directory\ncontains a Duktape 1.x compatible module loading framework which you can\nadd to your build:\n\n* Add ``duk_module_duktape.c`` to list of C sources to compile.\n\n* Ensure ``duk_module_duktape.h`` is in the include path.\n\n* Include the extra header in calling code and initialize the bindings::\n\n      #include \"duktape.h\"\n      #include \"duk_module_duktape.h\"\n\n      /* After initializing the Duktape heap or when creating a new\n       * thread with a new global environment:\n       */\n      duk_module_duktape_init(ctx);\n\n  Don't call ``duk_module_duktape_init()`` more than once for the same global\n  environment.\n\n* As usual in Duktape 1.x, you should define ``Duktape.modSearch()`` to provide\n  environment specific module lookups.\n\n* After these steps, ``require()`` will be registered to the global object and\n  the module system is ready to use.\n"
  },
  {
    "path": "react_juce/duktape/extras/module-duktape/duk_module_duktape.c",
    "content": "/*\n *  Duktape 1.x compatible module loading framework\n */\n\n#include \"duktape.h\"\n#include \"duk_module_duktape.h\"\n\n/* (v)snprintf() is missing before MSVC 2015.  Note that _(v)snprintf() does\n * NOT NUL terminate on truncation, but that's OK here.\n * http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010\n */\n#if defined(_MSC_VER) && (_MSC_VER < 1900)\n#define snprintf _snprintf\n#endif\n\n#if 0  /* Enable manually */\n#define DUK__ASSERT(x) do { \\\n\t\tif (!(x)) { \\\n\t\t\tfprintf(stderr, \"ASSERTION FAILED at %s:%d: \" #x \"\\n\", __FILE__, __LINE__); \\\n\t\t\tfflush(stderr);  \\\n\t\t} \\\n\t} while (0)\n#define DUK__ASSERT_TOP(ctx,val) do { \\\n\t\tDUK__ASSERT(duk_get_top((ctx)) == (val)); \\\n\t} while (0)\n#else\n#define DUK__ASSERT(x) do { (void) (x); } while (0)\n#define DUK__ASSERT_TOP(ctx,val) do { (void) ctx; (void) (val); } while (0)\n#endif\n\nstatic void duk__resolve_module_id(duk_context *ctx, const char *req_id, const char *mod_id) {\n\tduk_uint8_t buf[DUK_COMMONJS_MODULE_ID_LIMIT];\n\tduk_uint8_t *p;\n\tduk_uint8_t *q;\n\tduk_uint8_t *q_last;  /* last component */\n\tduk_int_t int_rc;\n\n\tDUK__ASSERT(req_id != NULL);\n\t/* mod_id may be NULL */\n\n\t/*\n\t *  A few notes on the algorithm:\n\t *\n\t *    - Terms are not allowed to begin with a period unless the term\n\t *      is either '.' or '..'.  This simplifies implementation (and\n\t *      is within CommonJS modules specification).\n\t *\n\t *    - There are few output bound checks here.  This is on purpose:\n\t *      the resolution input is length checked and the output is never\n\t *      longer than the input.  The resolved output is written directly\n\t *      over the input because it's never longer than the input at any\n\t *      point in the algorithm.\n\t *\n\t *    - Non-ASCII characters are processed as individual bytes and\n\t *      need no special treatment.  However, U+0000 terminates the\n\t *      algorithm; this is not an issue because U+0000 is not a\n\t *      desirable term character anyway.\n\t */\n\n\t/*\n\t *  Set up the resolution input which is the requested ID directly\n\t *  (if absolute or no current module path) or with current module\n\t *  ID prepended (if relative and current module path exists).\n\t *\n\t *  Suppose current module is 'foo/bar' and relative path is './quux'.\n\t *  The 'bar' component must be replaced so the initial input here is\n\t *  'foo/bar/.././quux'.\n\t */\n\n\tif (mod_id != NULL && req_id[0] == '.') {\n\t\tint_rc = snprintf((char *) buf, sizeof(buf), \"%s/../%s\", mod_id, req_id);\n\t} else {\n\t\tint_rc = snprintf((char *) buf, sizeof(buf), \"%s\", req_id);\n\t}\n\tif (int_rc >= (duk_int_t) sizeof(buf) || int_rc < 0) {\n\t\t/* Potentially truncated, NUL not guaranteed in any case.\n\t\t * The (int_rc < 0) case should not occur in practice.\n\t\t */\n\t\tgoto resolve_error;\n\t}\n\tDUK__ASSERT(strlen((const char *) buf) < sizeof(buf));  /* at most sizeof(buf) - 1 */\n\n\t/*\n\t *  Resolution loop.  At the top of the loop we're expecting a valid\n\t *  term: '.', '..', or a non-empty identifier not starting with a period.\n\t */\n\n\tp = buf;\n\tq = buf;\n\tfor (;;) {\n\t\tduk_uint_fast8_t c;\n\n\t\t/* Here 'p' always points to the start of a term.\n\t\t *\n\t\t * We can also unconditionally reset q_last here: if this is\n\t\t * the last (non-empty) term q_last will have the right value\n\t\t * on loop exit.\n\t\t */\n\n\t\tDUK__ASSERT(p >= q);  /* output is never longer than input during resolution */\n\n\t\tq_last = q;\n\n\t\tc = *p++;\n\t\tif (c == 0) {\n\t\t\tgoto resolve_error;\n\t\t} else if (c == '.') {\n\t\t\tc = *p++;\n\t\t\tif (c == '/') {\n\t\t\t\t/* Term was '.' and is eaten entirely (including dup slashes). */\n\t\t\t\tgoto eat_dup_slashes;\n\t\t\t}\n\t\t\tif (c == '.' && *p == '/') {\n\t\t\t\t/* Term was '..', backtrack resolved name by one component.\n\t\t\t\t *  q[-1] = previous slash (or beyond start of buffer)\n\t\t\t\t *  q[-2] = last char of previous component (or beyond start of buffer)\n\t\t\t\t */\n\t\t\t\tp++;  /* eat (first) input slash */\n\t\t\t\tDUK__ASSERT(q >= buf);\n\t\t\t\tif (q == buf) {\n\t\t\t\t\tgoto resolve_error;\n\t\t\t\t}\n\t\t\t\tDUK__ASSERT(*(q - 1) == '/');\n\t\t\t\tq--;  /* Backtrack to last output slash (dups already eliminated). */\n\t\t\t\tfor (;;) {\n\t\t\t\t\t/* Backtrack to previous slash or start of buffer. */\n\t\t\t\t\tDUK__ASSERT(q >= buf);\n\t\t\t\t\tif (q == buf) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (*(q - 1) == '/') {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tq--;\n\t\t\t\t}\n\t\t\t\tgoto eat_dup_slashes;\n\t\t\t}\n\t\t\tgoto resolve_error;\n\t\t} else if (c == '/') {\n\t\t\t/* e.g. require('/foo'), empty terms not allowed */\n\t\t\tgoto resolve_error;\n\t\t} else {\n\t\t\tfor (;;) {\n\t\t\t\t/* Copy term name until end or '/'. */\n\t\t\t\t*q++ = c;\n\t\t\t\tc = *p++;\n\t\t\t\tif (c == 0) {\n\t\t\t\t\t/* This was the last term, and q_last was\n\t\t\t\t\t * updated to match this term at loop top.\n\t\t\t\t\t */\n\t\t\t\t\tgoto loop_done;\n\t\t\t\t} else if (c == '/') {\n\t\t\t\t\t*q++ = '/';\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\t/* write on next loop */\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t eat_dup_slashes:\n\t\tfor (;;) {\n\t\t\t/* eat dup slashes */\n\t\t\tc = *p;\n\t\t\tif (c != '/') {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tp++;\n\t\t}\n\t}\n loop_done:\n\t/* Output #1: resolved absolute name. */\n\tDUK__ASSERT(q >= buf);\n\tduk_push_lstring(ctx, (const char *) buf, (size_t) (q - buf));\n\n\t/* Output #2: last component name. */\n\tDUK__ASSERT(q >= q_last);\n\tDUK__ASSERT(q_last >= buf);\n\tduk_push_lstring(ctx, (const char *) q_last, (size_t) (q - q_last));\n\treturn;\n\n resolve_error:\n\t(void) duk_type_error(ctx, \"cannot resolve module id: %s\", (const char *) req_id);\n}\n\n/* Stack indices for better readability. */\n#define DUK__IDX_REQUESTED_ID   0   /* module id requested */\n#define DUK__IDX_REQUIRE        1   /* current require() function */\n#define DUK__IDX_REQUIRE_ID     2   /* the base ID of the current require() function, resolution base */\n#define DUK__IDX_RESOLVED_ID    3   /* resolved, normalized absolute module ID */\n#define DUK__IDX_LASTCOMP       4   /* last component name in resolved path */\n#define DUK__IDX_DUKTAPE        5   /* Duktape object */\n#define DUK__IDX_MODLOADED      6   /* Duktape.modLoaded[] module cache */\n#define DUK__IDX_UNDEFINED      7   /* 'undefined', artifact of lookup */\n#define DUK__IDX_FRESH_REQUIRE  8   /* new require() function for module, updated resolution base */\n#define DUK__IDX_EXPORTS        9   /* default exports table */\n#define DUK__IDX_MODULE         10  /* module object containing module.exports, etc */\n\nstatic duk_ret_t duk__require(duk_context *ctx) {\n\tconst char *str_req_id;  /* requested identifier */\n\tconst char *str_mod_id;  /* require.id of current module */\n\tduk_int_t pcall_rc;\n\n\t/* NOTE: we try to minimize code size by avoiding unnecessary pops,\n\t * so the stack looks a bit cluttered in this function.  DUK__ASSERT_TOP()\n\t * assertions are used to ensure stack configuration is correct at each\n\t * step.\n\t */\n\n\t/*\n\t *  Resolve module identifier into canonical absolute form.\n\t */\n\n\tstr_req_id = duk_require_string(ctx, DUK__IDX_REQUESTED_ID);\n\tduk_push_current_function(ctx);\n\tduk_get_prop_string(ctx, -1, \"id\");\n\tstr_mod_id = duk_get_string(ctx, DUK__IDX_REQUIRE_ID);  /* ignore non-strings */\n\tduk__resolve_module_id(ctx, str_req_id, str_mod_id);\n\tstr_req_id = NULL;\n\tstr_mod_id = NULL;\n\n\t/* [ requested_id require require.id resolved_id last_comp ] */\n\tDUK__ASSERT_TOP(ctx, DUK__IDX_LASTCOMP + 1);\n\n\t/*\n\t *  Cached module check.\n\t *\n\t *  If module has been loaded or its loading has already begun without\n\t *  finishing, return the same cached value (module.exports).  The\n\t *  value is registered when module load starts so that circular\n\t *  references can be supported to some extent.\n\t */\n\n\tduk_push_global_stash(ctx);\n\tduk_get_prop_string(ctx, -1, \"\\xff\" \"module:Duktape\");\n\tduk_remove(ctx, -2);  /* Lookup stashed, original 'Duktape' object. */\n\tduk_get_prop_string(ctx, DUK__IDX_DUKTAPE, \"modLoaded\");  /* Duktape.modLoaded */\n\tduk_require_type_mask(ctx, DUK__IDX_MODLOADED, DUK_TYPE_MASK_OBJECT);\n\tDUK__ASSERT_TOP(ctx, DUK__IDX_MODLOADED + 1);\n\n\tduk_dup(ctx, DUK__IDX_RESOLVED_ID);\n\tif (duk_get_prop(ctx, DUK__IDX_MODLOADED)) {\n\t\t/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded Duktape.modLoaded[id] ] */\n\t\tduk_get_prop_string(ctx, -1, \"exports\");  /* return module.exports */\n\t\treturn 1;\n\t}\n\tDUK__ASSERT_TOP(ctx, DUK__IDX_UNDEFINED + 1);\n\n\t/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined ] */\n\n\t/*\n\t *  Module not loaded (and loading not started previously).\n\t *\n\t *  Create a new require() function with 'id' set to resolved ID\n\t *  of module being loaded.  Also create 'exports' and 'module'\n\t *  tables but don't register exports to the loaded table yet.\n\t *  We don't want to do that unless the user module search callbacks\n\t *  succeeds in finding the module.\n\t */\n\n\t/* Fresh require: require.id is left configurable (but not writable)\n\t * so that is not easy to accidentally tweak it, but it can still be\n\t * done with Object.defineProperty().\n\t *\n\t * XXX: require.id could also be just made non-configurable, as there\n\t * is no practical reason to touch it (at least from ECMAScript code).\n\t */\n\tduk_push_c_function(ctx, duk__require, 1 /*nargs*/);\n\tduk_push_string(ctx, \"name\");\n\tduk_push_string(ctx, \"require\");\n\tduk_def_prop(ctx, DUK__IDX_FRESH_REQUIRE, DUK_DEFPROP_HAVE_VALUE);  /* not writable, not enumerable, not configurable */\n\tduk_push_string(ctx, \"id\");\n\tduk_dup(ctx, DUK__IDX_RESOLVED_ID);\n\tduk_def_prop(ctx, DUK__IDX_FRESH_REQUIRE, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_CONFIGURABLE);  /* a fresh require() with require.id = resolved target module id */\n\n\t/* Module table:\n\t * - module.exports: initial exports table (may be replaced by user)\n\t * - module.id is non-writable and non-configurable, as the CommonJS\n\t *   spec suggests this if possible\n\t * - module.filename: not set, defaults to resolved ID if not explicitly\n\t *   set by modSearch() (note capitalization, not .fileName, matches Node.js)\n\t * - module.name: not set, defaults to last component of resolved ID if\n\t *   not explicitly set by modSearch()\n\t */\n\tduk_push_object(ctx);  /* exports */\n\tduk_push_object(ctx);  /* module */\n\tduk_push_string(ctx, \"exports\");\n\tduk_dup(ctx, DUK__IDX_EXPORTS);\n\tduk_def_prop(ctx, DUK__IDX_MODULE, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_CONFIGURABLE);  /* module.exports = exports */\n\tduk_push_string(ctx, \"id\");\n\tduk_dup(ctx, DUK__IDX_RESOLVED_ID);  /* resolved id: require(id) must return this same module */\n\tduk_def_prop(ctx, DUK__IDX_MODULE, DUK_DEFPROP_HAVE_VALUE);  /* module.id = resolved_id; not writable, not enumerable, not configurable */\n\tduk_compact(ctx, DUK__IDX_MODULE);  /* module table remains registered to modLoaded, minimize its size */\n\tDUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 1);\n\n\t/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module ] */\n\n\t/* Register the module table early to modLoaded[] so that we can\n\t * support circular references even in modSearch().  If an error\n\t * is thrown, we'll delete the reference.\n\t */\n\tduk_dup(ctx, DUK__IDX_RESOLVED_ID);\n\tduk_dup(ctx, DUK__IDX_MODULE);\n\tduk_put_prop(ctx, DUK__IDX_MODLOADED);  /* Duktape.modLoaded[resolved_id] = module */\n\n\t/*\n\t *  Call user provided module search function and build the wrapped\n\t *  module source code (if necessary).  The module search function\n\t *  can be used to implement pure Ecmacsript, pure C, and mixed\n\t *  ECMAScript/C modules.\n\t *\n\t *  The module search function can operate on the exports table directly\n\t *  (e.g. DLL code can register values to it).  It can also return a\n\t *  string which is interpreted as module source code (if a non-string\n\t *  is returned the module is assumed to be a pure C one).  If a module\n\t *  cannot be found, an error must be thrown by the user callback.\n\t *\n\t *  Because Duktape.modLoaded[] already contains the module being\n\t *  loaded, circular references for C modules should also work\n\t *  (although expected to be quite rare).\n\t */\n\n\tduk_push_string(ctx, \"(function(require,exports,module){\");\n\n\t/* Duktape.modSearch(resolved_id, fresh_require, exports, module). */\n\tduk_get_prop_string(ctx, DUK__IDX_DUKTAPE, \"modSearch\");  /* Duktape.modSearch */\n\tduk_dup(ctx, DUK__IDX_RESOLVED_ID);\n\tduk_dup(ctx, DUK__IDX_FRESH_REQUIRE);\n\tduk_dup(ctx, DUK__IDX_EXPORTS);\n\tduk_dup(ctx, DUK__IDX_MODULE);  /* [ ... Duktape.modSearch resolved_id last_comp fresh_require exports module ] */\n\tpcall_rc = duk_pcall(ctx, 4 /*nargs*/);  /* -> [ ... source ] */\n\tDUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 3);\n\n\tif (pcall_rc != DUK_EXEC_SUCCESS) {\n\t\t/* Delete entry in Duktape.modLoaded[] and rethrow. */\n\t\tgoto delete_rethrow;\n\t}\n\n\t/* If user callback did not return source code, module loading\n\t * is finished (user callback initialized exports table directly).\n\t */\n\tif (!duk_is_string(ctx, -1)) {\n\t\t/* User callback did not return source code, so module loading\n\t\t * is finished: just update modLoaded with final module.exports\n\t\t * and we're done.\n\t\t */\n\t\tgoto return_exports;\n\t}\n\n\t/* Finish the wrapped module source.  Force module.filename as the\n\t * function .fileName so it gets set for functions defined within a\n\t * module.  This also ensures loggers created within the module get\n\t * the module ID (or overridden filename) as their default logger name.\n\t * (Note capitalization: .filename matches Node.js while .fileName is\n\t * used elsewhere in Duktape.)\n\t */\n\tduk_push_string(ctx, \"\\n})\");  /* Newline allows module last line to contain a // comment. */\n\tduk_concat(ctx, 3);\n\tif (!duk_get_prop_string(ctx, DUK__IDX_MODULE, \"filename\")) {\n\t\t/* module.filename for .fileName, default to resolved ID if\n\t\t * not present.\n\t\t */\n\t\tduk_pop(ctx);\n\t\tduk_dup(ctx, DUK__IDX_RESOLVED_ID);\n\t}\n\tpcall_rc = duk_pcompile(ctx, DUK_COMPILE_EVAL);\n\tif (pcall_rc != DUK_EXEC_SUCCESS) {\n\t\tgoto delete_rethrow;\n\t}\n\tpcall_rc = duk_pcall(ctx, 0);  /* -> eval'd function wrapper (not called yet) */\n\tif (pcall_rc != DUK_EXEC_SUCCESS) {\n\t\tgoto delete_rethrow;\n\t}\n\n\t/* Module has now evaluated to a wrapped module function.  Force its\n\t * .name to match module.name (defaults to last component of resolved\n\t * ID) so that it is shown in stack traces too.  Note that we must not\n\t * introduce an actual name binding into the function scope (which is\n\t * usually the case with a named function) because it would affect the\n\t * scope seen by the module and shadow accesses to globals of the same name.\n\t * This is now done by compiling the function as anonymous and then forcing\n\t * its .name without setting a \"has name binding\" flag.\n\t */\n\n\tduk_push_string(ctx, \"name\");\n\tif (!duk_get_prop_string(ctx, DUK__IDX_MODULE, \"name\")) {\n\t\t/* module.name for .name, default to last component if\n\t\t * not present.\n\t\t */\n\t\tduk_pop(ctx);\n\t\tduk_dup(ctx, DUK__IDX_LASTCOMP);\n\t}\n\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_FORCE);\n\n\t/*\n\t *  Call the wrapped module function.\n\t *\n\t *  Use a protected call so that we can update Duktape.modLoaded[resolved_id]\n\t *  even if the module throws an error.\n\t */\n\n\t/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module mod_func ] */\n\tDUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 2);\n\n\tduk_dup(ctx, DUK__IDX_EXPORTS);  /* exports (this binding) */\n\tduk_dup(ctx, DUK__IDX_FRESH_REQUIRE);  /* fresh require (argument) */\n\tduk_get_prop_string(ctx, DUK__IDX_MODULE, \"exports\");  /* relookup exports from module.exports in case it was changed by modSearch */\n\tduk_dup(ctx, DUK__IDX_MODULE);  /* module (argument) */\n\tDUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 6);\n\n\t/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module mod_func exports fresh_require exports module ] */\n\n\tpcall_rc = duk_pcall_method(ctx, 3 /*nargs*/);\n\tif (pcall_rc != DUK_EXEC_SUCCESS) {\n\t\t/* Module loading failed.  Node.js will forget the module\n\t\t * registration so that another require() will try to load\n\t\t * the module again.  Mimic that behavior.\n\t\t */\n\t\tgoto delete_rethrow;\n\t}\n\n\t/* [ requested_id require require.id resolved_id last_comp Duktape Duktape.modLoaded undefined fresh_require exports module result(ignored) ] */\n\tDUK__ASSERT_TOP(ctx, DUK__IDX_MODULE + 2);\n\n\t/* fall through */\n\n return_exports:\n\tduk_get_prop_string(ctx, DUK__IDX_MODULE, \"exports\");\n\tduk_compact(ctx, -1);  /* compact the exports table */\n\treturn 1;  /* return module.exports */\n\n delete_rethrow:\n\tduk_dup(ctx, DUK__IDX_RESOLVED_ID);\n\tduk_del_prop(ctx, DUK__IDX_MODLOADED);  /* delete Duktape.modLoaded[resolved_id] */\n\t(void) duk_throw(ctx);  /* rethrow original error */\n\treturn 0;  /* not reachable */\n}\n\nvoid duk_module_duktape_init(duk_context *ctx) {\n\t/* Stash 'Duktape' in case it's modified. */\n\tduk_push_global_stash(ctx);\n\tduk_get_global_string(ctx, \"Duktape\");\n\tduk_put_prop_string(ctx, -2, \"\\xff\" \"module:Duktape\");\n\tduk_pop(ctx);\n\n\t/* Register `require` as a global function. */\n\tduk_eval_string(ctx,\n\t\t\"(function(req){\"\n\t\t\"var D=Object.defineProperty;\"\n\t\t\"D(req,'name',{value:'require'});\"\n\t\t\"D(this,'require',{value:req,writable:true,configurable:true});\"\n\t\t\"D(Duktape,'modLoaded',{value:Object.create(null),writable:true,configurable:true});\"\n\t\t\"})\");\n\tduk_push_c_function(ctx, duk__require, 1 /*nargs*/);\n\tduk_call(ctx, 1);\n\tduk_pop(ctx);\n}\n\n#undef DUK__ASSERT\n#undef DUK__ASSERT_TOP\n#undef DUK__IDX_REQUESTED_ID\n#undef DUK__IDX_REQUIRE\n#undef DUK__IDX_REQUIRE_ID\n#undef DUK__IDX_RESOLVED_ID\n#undef DUK__IDX_LASTCOMP\n#undef DUK__IDX_DUKTAPE\n#undef DUK__IDX_MODLOADED\n#undef DUK__IDX_UNDEFINED\n#undef DUK__IDX_FRESH_REQUIRE\n#undef DUK__IDX_EXPORTS\n#undef DUK__IDX_MODULE\n"
  },
  {
    "path": "react_juce/duktape/extras/module-duktape/duk_module_duktape.h",
    "content": "#if !defined(DUK_MODULE_DUKTAPE_H_INCLUDED)\n#define DUK_MODULE_DUKTAPE_H_INCLUDED\n\n#include \"duktape.h\"\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/* Maximum length of CommonJS module identifier to resolve.  Length includes\n * both current module ID, requested (possibly relative) module ID, and a\n * slash in between.\n */\n#define  DUK_COMMONJS_MODULE_ID_LIMIT  256\n\nextern void duk_module_duktape_init(duk_context *ctx);\n\n#if defined(__cplusplus)\n}\n#endif  /* end 'extern \"C\"' wrapper */\n\n#endif  /* DUK_MODULE_DUKTAPE_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/extras/module-duktape/test.c",
    "content": "#include <stdio.h>\n#include <string.h>\n#include \"duktape.h\"\n#include \"duk_module_duktape.h\"\n\nstatic duk_ret_t handle_print(duk_context *ctx) {\n\tprintf(\"%s\\n\", duk_safe_to_string(ctx, 0));\n\treturn 0;\n}\n\nstatic duk_ret_t handle_assert(duk_context *ctx) {\n\tif (duk_to_boolean(ctx, 0)) {\n\t\treturn 0;\n\t}\n\t(void) duk_generic_error(ctx, \"assertion failed: %s\", duk_safe_to_string(ctx, 1));\n\treturn 0;\n}\n\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx;\n\tint i;\n\tint exitcode = 0;\n\n\tctx = duk_create_heap_default();\n\tif (!ctx) {\n\t\treturn 1;\n\t}\n\n\tduk_push_c_function(ctx, handle_print, 1);\n\tduk_put_global_string(ctx, \"print\");\n\tduk_push_c_function(ctx, handle_assert, 2);\n\tduk_put_global_string(ctx, \"assert\");\n\n\tduk_module_duktape_init(ctx);\n\tprintf(\"top after init: %ld\\n\", (long) duk_get_top(ctx));\n\n\tfor (i = 1; i < argc; i++) {\n\t\tprintf(\"Evaling: %s\\n\", argv[i]);\n\t\tif (duk_peval_string(ctx, argv[i]) != 0) {\n\t\t\tif (duk_get_prop_string(ctx, -1, \"stack\")) {\n\t\t\t\tduk_replace(ctx, -2);\n\t\t\t} else {\n\t\t\t\tduk_pop(ctx);\n\t\t\t}\n\t\t\texitcode = 1;\n\t\t}\n\t\tprintf(\"--> %s\\n\", duk_safe_to_string(ctx, -1));\n\t\tduk_pop(ctx);\n\t}\n\n\tprintf(\"Done\\n\");\n\tduk_destroy_heap(ctx);\n\treturn exitcode;\n}\n"
  },
  {
    "path": "react_juce/duktape/extras/module-node/Makefile",
    "content": "# For manual testing; say 'make' in extras/module-node and run ./test.\n\nCC = gcc\n\n.PHONY: test\ntest:\n\t-rm -rf ./prep\n\tpython2 ../../tools/configure.py --quiet --output-directory ./prep\n\t$(CC) -std=c99 -Wall -Wextra -o $@ -I./prep -I. ./prep/duktape.c duk_module_node.c test.c -lm\n\t@printf '\\n'\n\t./test 'assert(typeof require(\"pig\") === \"string\", \"basic require()\");'\n\t./test 'assert(require(\"cow\").indexOf(\"pig\") !== -1, \"nested require()\");'\n\t./test 'var ape1 = require(\"ape\"); var ape2 = require(\"ape\"); assert(ape1 === ape2, \"caching\");'\n\t./test 'var ape1 = require(\"ape\"); var inCache = \"ape.js\" in require.cache; delete require.cache[\"ape.js\"]; var ape2 = require(\"ape\"); assert(inCache && ape2 !== ape1, \"require.cache\");'\n\t./test 'var ape = require(\"ape\"); assert(typeof ape.module.require === \"function\", \"module.require()\");'\n\t./test 'var ape = require(\"ape\"); assert(ape.module.exports === ape, \"module.exports\");'\n\t./test 'var ape = require(\"ape\"); assert(ape.module.id === \"ape.js\" && ape.module.id === ape.module.filename, \"module.id\");'\n\t./test 'var ape = require(\"ape\"); assert(ape.module.filename === \"ape.js\", \"module.filename\");'\n\t./test 'var ape = require(\"ape\"); assert(ape.module.loaded === true && ape.wasLoaded === false, \"module.loaded\");'\n\t./test 'var ape = require(\"ape\"); assert(ape.__filename === \"ape.js\", \"__filename\");'\n\t./test 'var badger = require(\"badger\"); assert(badger.foo === 123 && badger.bar === 234, \"exports.foo assignment\");'\n\t./test 'var comment = require(\"comment\"); assert(comment.foo === 123 && comment.bar === 234, \"last line with // comment\");'\n\t./test 'var shebang = require(\"shebang\"); assert(shebang.foo === 123 && shebang.bar === 234, \"shebang\");'\n\n.PHONY: clean\nclean:\n\t-rm -rf ./prep\n\t-rm -f test\n"
  },
  {
    "path": "react_juce/duktape/extras/module-node/README.rst",
    "content": "=====================================\nNode.js-like module loading framework\n=====================================\n\nThis directory contains an example module resolution and loading framework and\n``require()`` implementation based on the Node.js module system:\n\n* https://nodejs.org/api/modules.html\n\nThe application needs only to provide the module resolution and loading logic:\n\n* Add ``duk_module_node.c`` to list of C sources to compile.\n\n* Ensure ``duk_module_node.h`` is in the include path.\n\n* Include the extra header in calling code and initialize the bindings::\n\n      #include \"duktape.h\"\n      #include \"duk_module_node.h\"\n\n      /* After initializing the Duktape heap or when creating a new\n       * thread with a new global environment:\n       */\n      duk_push_object(ctx);\n      duk_push_c_function(ctx, cb_resolve_module, DUK_VARARGS);\n      duk_put_prop_string(ctx, -2, \"resolve\");\n      duk_push_c_function(ctx, cb_load_module, DUK_VARARGS);\n      duk_put_prop_string(ctx, -2, \"load\");\n      duk_module_node_init(ctx);\n\n  Do not call ``duk_module_node_init()`` more than once for the same global\n  environment.  Doing so is undefined behavior and may put the module system\n  in an inconsistent state.\n  \n  It is possible to replace the callbacks after initialization by setting the\n  following internal properties on the global stash:\n  \n  - ``\\xffmodResolve``\n  \n  - ``\\xffmodLoad``\n\n* The resolve callback is a Duktape/C function which takes the string passed\n  to ``require()`` and resolves it to a canonical module ID (for Node.js this\n  is usually the fully resolved filename of the module)::\n\n      duk_ret_t cb_resolve_module(duk_context *ctx) {\n          /*\n           *  Entry stack: [ requested_id parent_id ]\n           */\n\n          const char *requested_id = duk_get_string(ctx, 0);\n          const char *parent_id = duk_get_string(ctx, 1);  /* calling module */\n          const char *resolved_id;\n\n          /* Arrive at the canonical module ID somehow. */\n\n          duk_push_string(ctx, resolved_id);\n          return 1;  /*nrets*/\n      }\n\n  If the module ID cannot be resolved, the resolve callback should throw an\n  error, which will propagate out of the ``require()`` call.  Note also that\n  when the global ``require()`` is called, the parent ID is an empty string.\n\n* The load callback is a Duktape/C function which takes the resolved module ID\n  and: (1) returns the ECMAScript source code for the module or ``undefined``\n  if there's no source code, e.g. for pure C modules, (2) can populate\n  ``module.exports`` itself, and (3) can replace ``module.exports``::\n\n      duk_ret_t cb_load_module(duk_context *ctx) {\n          /*\n           *  Entry stack: [ resolved_id exports module ]\n           */\n\n          /* Arrive at the JS source code for the module somehow. */\n\n          duk_push_string(ctx, module_source);\n          return 1;  /*nrets*/\n      }\n\n  As with the resolve callback, the load callback should throw an error if the\n  module cannot be loaded for any reason.\n\n* After these steps, ``require()`` will be registered to the global object and\n  the module system is ready to use.\n\n* The main module (file being evaluated) should be loaded using\n  ``duk_module_node_peval_main()``.  This function registers the module in\n  ``require.main`` and thus should only be called once.\n"
  },
  {
    "path": "react_juce/duktape/extras/module-node/duk_module_node.c",
    "content": "/*\n *  Node.js-like module loading framework for Duktape\n *\n *  https://nodejs.org/api/modules.html\n */\n\n#include \"duktape.h\"\n#include \"duk_module_node.h\"\n\n#if DUK_VERSION >= 19999\nstatic duk_int_t duk__eval_module_source(duk_context *ctx, void *udata);\n#else\nstatic duk_int_t duk__eval_module_source(duk_context *ctx);\n#endif\nstatic void duk__push_module_object(duk_context *ctx, const char *id, duk_bool_t main);\n\nstatic duk_bool_t duk__get_cached_module(duk_context *ctx, const char *id) {\n\tduk_push_global_stash(ctx);\n\t(void) duk_get_prop_string(ctx, -1, \"\\xff\" \"requireCache\");\n\tif (duk_get_prop_string(ctx, -1, id)) {\n\t\tduk_remove(ctx, -2);\n\t\tduk_remove(ctx, -2);\n\t\treturn 1;\n\t} else {\n\t\tduk_pop_3(ctx);\n\t\treturn 0;\n\t}\n}\n\n/* Place a `module` object on the top of the value stack into the require cache\n * based on its `.id` property.  As a convenience to the caller, leave the\n * object on top of the value stack afterwards.\n */\nstatic void duk__put_cached_module(duk_context *ctx) {\n\t/* [ ... module ] */\n\n\tduk_push_global_stash(ctx);\n\t(void) duk_get_prop_string(ctx, -1, \"\\xff\" \"requireCache\");\n\tduk_dup(ctx, -3);\n\n\t/* [ ... module stash req_cache module ] */\n\n\t(void) duk_get_prop_string(ctx, -1, \"id\");\n\tduk_dup(ctx, -2);\n\tduk_put_prop(ctx, -4);\n\n\tduk_pop_3(ctx);  /* [ ... module ] */\n}\n\nstatic void duk__del_cached_module(duk_context *ctx, const char *id) {\n\tduk_push_global_stash(ctx);\n\t(void) duk_get_prop_string(ctx, -1, \"\\xff\" \"requireCache\");\n\tduk_del_prop_string(ctx, -1, id);\n\tduk_pop_2(ctx);\n}\n\nstatic duk_ret_t duk__handle_require(duk_context *ctx) {\n\t/*\n\t *  Value stack handling here is a bit sloppy but should be correct.\n\t *  Call handling will clean up any extra garbage for us.\n\t */\n\n\tconst char *id;\n\tconst char *parent_id;\n\tduk_idx_t module_idx;\n\tduk_idx_t stash_idx;\n\tduk_int_t ret;\n\n\tduk_push_global_stash(ctx);\n\tstash_idx = duk_normalize_index(ctx, -1);\n\n\tduk_push_current_function(ctx);\n\t(void) duk_get_prop_string(ctx, -1, \"\\xff\" \"moduleId\");\n\tparent_id = duk_require_string(ctx, -1);\n\t(void) parent_id;  /* not used directly; suppress warning */\n\n\t/* [ id stash require parent_id ] */\n\n\tid = duk_require_string(ctx, 0);\n\n\t(void) duk_get_prop_string(ctx, stash_idx, \"\\xff\" \"modResolve\");\n\tduk_dup(ctx, 0);   /* module ID */\n\tduk_dup(ctx, -3);  /* parent ID */\n\tduk_call(ctx, 2);\n\n\t/* [ ... stash ... resolved_id ] */\n\n\tid = duk_require_string(ctx, -1);\n\n\tif (duk__get_cached_module(ctx, id)) {\n\t\tgoto have_module;  /* use the cached module */\n\t}\n\n\tduk__push_module_object(ctx, id, 0 /*main*/);\n\tduk__put_cached_module(ctx);  /* module remains on stack */\n\n\t/*\n\t *  From here on out, we have to be careful not to throw.  If it can't be\n\t *  avoided, the error must be caught and the module removed from the\n\t *  require cache before rethrowing.  This allows the application to\n\t *  reattempt loading the module.\n\t */\n\n\tmodule_idx = duk_normalize_index(ctx, -1);\n\n\t/* [ ... stash ... resolved_id module ] */\n\n\t(void) duk_get_prop_string(ctx, stash_idx, \"\\xff\" \"modLoad\");\n\tduk_dup(ctx, -3);  /* resolved ID */\n\t(void) duk_get_prop_string(ctx, module_idx, \"exports\");\n\tduk_dup(ctx, module_idx);\n\tret = duk_pcall(ctx, 3);\n\tif (ret != DUK_EXEC_SUCCESS) {\n\t\tduk__del_cached_module(ctx, id);\n\t\t(void) duk_throw(ctx);  /* rethrow */\n\t}\n\n\tif (duk_is_string(ctx, -1)) {\n\t\tduk_int_t ret;\n\n\t\t/* [ ... module source ] */\n\n#if DUK_VERSION >= 19999\n\t\tret = duk_safe_call(ctx, duk__eval_module_source, NULL, 2, 1);\n#else\n\t\tret = duk_safe_call(ctx, duk__eval_module_source, 2, 1);\n#endif\n\t\tif (ret != DUK_EXEC_SUCCESS) {\n\t\t\tduk__del_cached_module(ctx, id);\n\t\t\t(void) duk_throw(ctx);  /* rethrow */\n\t\t}\n\t} else if (duk_is_undefined(ctx, -1)) {\n\t\tduk_pop(ctx);\n\t} else {\n\t\tduk__del_cached_module(ctx, id);\n\t\t(void) duk_type_error(ctx, \"invalid module load callback return value\");\n\t}\n\n\t/* fall through */\n\n have_module:\n\t/* [ ... module ] */\n\n\t(void) duk_get_prop_string(ctx, -1, \"exports\");\n\treturn 1;\n}\n\nstatic void duk__push_require_function(duk_context *ctx, const char *id) {\n\tduk_push_c_function(ctx, duk__handle_require, 1);\n\tduk_push_string(ctx, \"name\");\n\tduk_push_string(ctx, \"require\");\n\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE);\n\tduk_push_string(ctx, id);\n\tduk_put_prop_string(ctx, -2, \"\\xff\" \"moduleId\");\n\n\t/* require.cache */\n\tduk_push_global_stash(ctx);\n\t(void) duk_get_prop_string(ctx, -1, \"\\xff\" \"requireCache\");\n\tduk_put_prop_string(ctx, -3, \"cache\");\n\tduk_pop(ctx);\n\n\t/* require.main */\n\tduk_push_global_stash(ctx);\n\t(void) duk_get_prop_string(ctx, -1, \"\\xff\" \"mainModule\");\n\tduk_put_prop_string(ctx, -3, \"main\");\n\tduk_pop(ctx);\n}\n\nstatic void duk__push_module_object(duk_context *ctx, const char *id, duk_bool_t main) {\n\tduk_push_object(ctx);\n\n\t/* Set this as the main module, if requested */\n\tif (main) {\n\t\tduk_push_global_stash(ctx);\n\t\tduk_dup(ctx, -2);\n\t\tduk_put_prop_string(ctx, -2, \"\\xff\" \"mainModule\");\n\t\tduk_pop(ctx);\n\t}\n\n\t/* Node.js uses the canonicalized filename of a module for both module.id\n\t * and module.filename.  We have no concept of a file system here, so just\n\t * use the module ID for both values.\n\t */\n\tduk_push_string(ctx, id);\n\tduk_dup(ctx, -1);\n\tduk_put_prop_string(ctx, -3, \"filename\");\n\tduk_put_prop_string(ctx, -2, \"id\");\n\n\t/* module.exports = {} */\n\tduk_push_object(ctx);\n\tduk_put_prop_string(ctx, -2, \"exports\");\n\n\t/* module.loaded = false */\n\tduk_push_false(ctx);\n\tduk_put_prop_string(ctx, -2, \"loaded\");\n\n\t/* module.require */\n\tduk__push_require_function(ctx, id);\n\tduk_put_prop_string(ctx, -2, \"require\");\n}\n\n#if DUK_VERSION >= 19999\nstatic duk_int_t duk__eval_module_source(duk_context *ctx, void *udata) {\n#else\nstatic duk_int_t duk__eval_module_source(duk_context *ctx) {\n#endif\n\tconst char *src;\n\n\t/*\n\t *  Stack: [ ... module source ]\n\t */\n\n#if DUK_VERSION >= 19999\n\t(void) udata;\n#endif\n\n\t/* Wrap the module code in a function expression.  This is the simplest\n\t * way to implement CommonJS closure semantics and matches the behavior of\n\t * e.g. Node.js.\n\t */\n\tduk_push_string(ctx, \"(function(exports,require,module,__filename,__dirname){\");\n\tsrc = duk_require_string(ctx, -2);\n\tduk_push_string(ctx, (src[0] == '#' && src[1] == '!') ? \"//\" : \"\");  /* Shebang support. */\n\tduk_dup(ctx, -3);  /* source */\n\tduk_push_string(ctx, \"\\n})\");  /* Newline allows module last line to contain a // comment. */\n\tduk_concat(ctx, 4);\n\n\t/* [ ... module source func_src ] */\n\n\t(void) duk_get_prop_string(ctx, -3, \"filename\");\n\tduk_compile(ctx, DUK_COMPILE_EVAL);\n\tduk_call(ctx, 0);\n\n\t/* [ ... module source func ] */\n\n\t/* Set name for the wrapper function. */\n\tduk_push_string(ctx, \"name\");\n\tduk_push_string(ctx, \"main\");\n\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_FORCE);\n\n\t/* call the function wrapper */\n\t(void) duk_get_prop_string(ctx, -3, \"exports\");   /* exports */\n\t(void) duk_get_prop_string(ctx, -4, \"require\");   /* require */\n\tduk_dup(ctx, -5);                                 /* module */\n\t(void) duk_get_prop_string(ctx, -6, \"filename\");  /* __filename */\n\tduk_push_undefined(ctx);                          /* __dirname */\n\tduk_call(ctx, 5);\n\n\t/* [ ... module source result(ignore) ] */\n\n\t/* module.loaded = true */\n\tduk_push_true(ctx);\n\tduk_put_prop_string(ctx, -4, \"loaded\");\n\n\t/* [ ... module source retval ] */\n\n\tduk_pop_2(ctx);\n\n\t/* [ ... module ] */\n\n\treturn 1;\n}\n\n/* Load a module as the 'main' module. */\nduk_ret_t duk_module_node_peval_main(duk_context *ctx, const char *path) {\n\t/*\n\t *  Stack: [ ... source ]\n\t */\n\n\tduk__push_module_object(ctx, path, 1 /*main*/);\n\t/* [ ... source module ] */\n\n\tduk_dup(ctx, 0);\n\t/* [ ... source module source ] */\n\n#if DUK_VERSION >= 19999\n\treturn duk_safe_call(ctx, duk__eval_module_source, NULL, 2, 1);\n#else\n\treturn duk_safe_call(ctx, duk__eval_module_source, 2, 1);\n#endif\n}\n\nvoid duk_module_node_init(duk_context *ctx) {\n\t/*\n\t *  Stack: [ ... options ] => [ ... ]\n\t */\n\n\tduk_idx_t options_idx;\n\n\tduk_require_object_coercible(ctx, -1);  /* error before setting up requireCache */\n\toptions_idx = duk_require_normalize_index(ctx, -1);\n\n\t/* Initialize the require cache to a fresh object. */\n\tduk_push_global_stash(ctx);\n#if DUK_VERSION >= 19999\n\tduk_push_bare_object(ctx);\n#else\n\tduk_push_object(ctx);\n\tduk_push_undefined(ctx);\n\tduk_set_prototype(ctx, -2);\n#endif\n\tduk_put_prop_string(ctx, -2, \"\\xff\" \"requireCache\");\n\tduk_pop(ctx);\n\n\t/* Stash callbacks for later use.  User code can overwrite them later\n\t * on directly by accessing the global stash.\n\t */\n\tduk_push_global_stash(ctx);\n\tduk_get_prop_string(ctx, options_idx, \"resolve\");\n\tduk_require_function(ctx, -1);\n\tduk_put_prop_string(ctx, -2, \"\\xff\" \"modResolve\");\n\tduk_get_prop_string(ctx, options_idx, \"load\");\n\tduk_require_function(ctx, -1);\n\tduk_put_prop_string(ctx, -2, \"\\xff\" \"modLoad\");\n\tduk_pop(ctx);\n\n\t/* Stash main module. */\n\tduk_push_global_stash(ctx);\n\tduk_push_undefined(ctx);\n\tduk_put_prop_string(ctx, -2, \"\\xff\" \"mainModule\");\n\tduk_pop(ctx);\n\n\t/* register `require` as a global function. */\n\tduk_push_global_object(ctx);\n\tduk_push_string(ctx, \"require\");\n\tduk__push_require_function(ctx, \"\");\n\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE |\n\t                      DUK_DEFPROP_SET_WRITABLE |\n\t                      DUK_DEFPROP_SET_CONFIGURABLE);\n\tduk_pop(ctx);\n\n\tduk_pop(ctx);  /* pop argument */\n}\n"
  },
  {
    "path": "react_juce/duktape/extras/module-node/duk_module_node.h",
    "content": "#if !defined(DUK_MODULE_NODE_H_INCLUDED)\n#define DUK_MODULE_NODE_H_INCLUDED\n\n#include \"duktape.h\"\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\nextern duk_ret_t duk_module_node_peval_main(duk_context *ctx, const char *path);\nextern void duk_module_node_init(duk_context *ctx);\n\n#if defined(__cplusplus)\n}\n#endif  /* end 'extern \"C\"' wrapper */\n\n#endif  /* DUK_MODULE_NODE_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/extras/module-node/test.c",
    "content": "#include <stdio.h>\n#include <string.h>\n#include \"duktape.h\"\n#include \"duk_module_node.h\"\n\nstatic duk_ret_t cb_resolve_module(duk_context *ctx) {\n\tconst char *module_id;\n\tconst char *parent_id;\n\n\tmodule_id = duk_require_string(ctx, 0);\n\tparent_id = duk_require_string(ctx, 1);\n\n\tduk_push_sprintf(ctx, \"%s.js\", module_id);\n\tprintf(\"resolve_cb: id:'%s', parent-id:'%s', resolve-to:'%s'\\n\",\n\t\tmodule_id, parent_id, duk_get_string(ctx, -1));\n\n\treturn 1;\n}\n\nstatic duk_ret_t cb_load_module(duk_context *ctx) {\n\tconst char *filename;\n\tconst char *module_id;\n\n\tmodule_id = duk_require_string(ctx, 0);\n\tduk_get_prop_string(ctx, 2, \"filename\");\n\tfilename = duk_require_string(ctx, -1);\n\n\tprintf(\"load_cb: id:'%s', filename:'%s'\\n\", module_id, filename);\n\n\tif (strcmp(module_id, \"pig.js\") == 0) {\n\t\tduk_push_sprintf(ctx, \"module.exports = 'you\\\\'re about to get eaten by %s';\",\n\t\t\tmodule_id);\n\t} else if (strcmp(module_id, \"cow.js\") == 0) {\n\t\tduk_push_string(ctx, \"module.exports = require('pig');\");\n\t} else if (strcmp(module_id, \"ape.js\") == 0) {\n\t\tduk_push_string(ctx, \"module.exports = { module: module, __filename: __filename, wasLoaded: module.loaded };\");\n\t} else if (strcmp(module_id, \"badger.js\") == 0) {\n\t\tduk_push_string(ctx, \"exports.foo = 123; exports.bar = 234;\");\n\t} else if (strcmp(module_id, \"comment.js\") == 0) {\n\t\tduk_push_string(ctx, \"exports.foo = 123; exports.bar = 234; // comment\");\n\t} else if (strcmp(module_id, \"shebang.js\") == 0) {\n\t\tduk_push_string(ctx, \"#!ignored\\nexports.foo = 123; exports.bar = 234;\");\n\t} else {\n\t\t(void) duk_type_error(ctx, \"cannot find module: %s\", module_id);\n\t}\n\n\treturn 1;\n}\n\nstatic duk_ret_t handle_print(duk_context *ctx) {\n\tprintf(\"%s\\n\", duk_safe_to_string(ctx, 0));\n\treturn 0;\n}\n\nstatic duk_ret_t handle_assert(duk_context *ctx) {\n\tif (duk_to_boolean(ctx, 0)) {\n\t\treturn 0;\n\t}\n\t(void) duk_generic_error(ctx, \"assertion failed: %s\", duk_safe_to_string(ctx, 1));\n\treturn 0;\n}\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx;\n\tint i;\n\tint exitcode = 0;\n\n\tctx = duk_create_heap_default();\n\tif (!ctx) {\n\t\treturn 1;\n\t}\n\n\tduk_push_c_function(ctx, handle_print, 1);\n\tduk_put_global_string(ctx, \"print\");\n\tduk_push_c_function(ctx, handle_assert, 2);\n\tduk_put_global_string(ctx, \"assert\");\n\n\tduk_push_object(ctx);\n\tduk_push_c_function(ctx, cb_resolve_module, DUK_VARARGS);\n\tduk_put_prop_string(ctx, -2, \"resolve\");\n\tduk_push_c_function(ctx, cb_load_module, DUK_VARARGS);\n\tduk_put_prop_string(ctx, -2, \"load\");\n\tduk_module_node_init(ctx);\n\tprintf(\"top after init: %ld\\n\", (long) duk_get_top(ctx));\n\n\tfor (i = 1; i < argc; i++) {\n\t\tprintf(\"Evaling: %s\\n\", argv[i]);\n\t\tif (duk_peval_string(ctx, argv[i]) != 0) {\n\t\t\tif (duk_get_prop_string(ctx, -1, \"stack\")) {\n\t\t\t\tduk_replace(ctx, -2);\n\t\t\t} else {\n\t\t\t\tduk_pop(ctx);\n\t\t\t}\n\t\t\texitcode = 1;\n\t\t}\n\t\tprintf(\"--> %s\\n\", duk_safe_to_string(ctx, -1));\n\t\tduk_pop(ctx);\n\t}\n\n\tprintf(\"Done\\n\");\n\tduk_destroy_heap(ctx);\n\treturn exitcode;\n}\n"
  },
  {
    "path": "react_juce/duktape/extras/print-alert/Makefile",
    "content": "# For manual testing; say 'make' in extras/print-alert and run ./test.\n\nCC = gcc\n\n.PHONY: test\ntest:\n\t-rm -rf ./prep\n\tpython2 ../../tools/configure.py --quiet --output-directory ./prep\n\t$(CC) -std=c99 -Wall -Wextra -otest -I./prep ./prep/duktape.c duk_print_alert.c test.c -lm\n\t./test 'print(\"foo\", \"bar\", 1, 2, 3)'\n\t./test 'alert(\"foo\", \"bar\", 1, 2, 3)'\n\n.PHONY: clean\nclean:\n\t-rm -rf ./prep\n\t-rm -f test\n"
  },
  {
    "path": "react_juce/duktape/extras/print-alert/README.rst",
    "content": "===================================================\nDuktape 1.x compatible print() and alert() bindings\n===================================================\n\nThe default ``print()`` and ``alert()`` built-ins were removed in Duktape 2.x\nbecause they depended on stdout/stderr and were thus a portability issue for\nsome targets.  This directory contains Duktape 1.x compatible optional\nprint() and alert() bindings:\n\n* Add ``duk_print_alert.c`` to list of C sources to compile.\n\n* Ensure ``duk_print_alert.h`` is in the include path.\n\n* Include the extra header in calling code and initialize the bindings::\n\n      #include \"duktape.h\"\n      #include \"duk_print_alert.h\"\n\n      /* After initializing the Duktape heap or when creating a new\n       * thread with a new global environment:\n       */\n      duk_print_alert_init(ctx, 0 /*flags*/);\n\n  See ``duk_print_alert.h`` for available flags.\n\n* After these steps, ``print()`` and ``alert()`` will be registered to the\n  global object and are ready to use.\n"
  },
  {
    "path": "react_juce/duktape/extras/print-alert/duk_print_alert.c",
    "content": "/*\n *  Duktape 1.x compatible print() and alert() bindings.\n */\n\n#include <stdio.h>\n#include <string.h>\n#include \"duktape.h\"\n#include \"duk_print_alert.h\"\n\n#define DUK_PRINT_ALERT_FLUSH   /* Flush after stdout/stderr write (Duktape 1.x: yes) */\n#undef DUK_PRINT_ALERT_SMALL    /* Prefer smaller footprint (but slower and more memory churn) */\n\n#if defined(DUK_PRINT_ALERT_SMALL)\nstatic duk_ret_t duk__print_alert_helper(duk_context *ctx, FILE *fh) {\n\tduk_idx_t nargs;\n\n\tnargs = duk_get_top(ctx);\n\n\t/* If argument count is 1 and first argument is a buffer, write the buffer\n\t * as raw data into the file without a newline; this allows exact control\n\t * over stdout/stderr without an additional entrypoint (useful for now).\n\t * Otherwise current print/alert semantics are to ToString() coerce\n\t * arguments, join them with a single space, and append a newline.\n\t */\n\n\tif (nargs == 1 && duk_is_buffer_data(ctx, 0)) {\n\t\tbuf = (const duk_uint8_t *) duk_get_buffer_data(ctx, 0, &sz_buf);\n\t\tfwrite((const void *) buf, 1, (size_t) sz_buf, fh);\n\t} else {\n\t\tduk_push_string(ctx, \" \");\n\t\tduk_insert(ctx, 0);\n\t\tduk_concat(ctx, nargs);\n\t\tfprintf(fh, \"%s\\n\", duk_require_string(ctx, -1));\n\t}\n\n#if defined(DUK_PRINT_ALERT_FLUSH)\n\tfflush(fh);\n#endif\n\n\treturn 0;\n}\n#else\n/* Faster, less churn, higher footprint option. */\nstatic duk_ret_t duk__print_alert_helper(duk_context *ctx, FILE *fh) {\n\tduk_idx_t nargs;\n\tconst duk_uint8_t *buf;\n\tduk_size_t sz_buf;\n\tconst char nl = (const char) '\\n';\n\tduk_uint8_t buf_stack[256];\n\n\tnargs = duk_get_top(ctx);\n\n\t/* If argument count is 1 and first argument is a buffer, write the buffer\n\t * as raw data into the file without a newline; this allows exact control\n\t * over stdout/stderr without an additional entrypoint (useful for now).\n\t * Otherwise current print/alert semantics are to ToString() coerce\n\t * arguments, join them with a single space, and append a newline.\n\t */\n\n\tif (nargs == 1 && duk_is_buffer_data(ctx, 0)) {\n\t\tbuf = (const duk_uint8_t *) duk_get_buffer_data(ctx, 0, &sz_buf);\n\t} else if (nargs > 0) {\n\t\tduk_idx_t i;\n\t\tduk_size_t sz_str;\n\t\tconst duk_uint8_t *p_str;\n\t\tduk_uint8_t *p;\n\n\t\tsz_buf = (duk_size_t) nargs;  /* spaces (nargs - 1) + newline */\n\t\tfor (i = 0; i < nargs; i++) {\n\t\t\t(void) duk_to_lstring(ctx, i, &sz_str);\n\t\t\tsz_buf += sz_str;\n\t\t}\n\n\t\tif (sz_buf <= sizeof(buf_stack)) {\n\t\t\tp = (duk_uint8_t *) buf_stack;\n\t\t} else {\n\t\t\tp = (duk_uint8_t *) duk_push_fixed_buffer(ctx, sz_buf);\n\t\t}\n\n\t\tbuf = (const duk_uint8_t *) p;\n\t\tfor (i = 0; i < nargs; i++) {\n\t\t\tp_str = (const duk_uint8_t *) duk_get_lstring(ctx, i, &sz_str);\n\t\t\tmemcpy((void *) p, (const void *) p_str, sz_str);\n\t\t\tp += sz_str;\n\t\t\t*p++ = (duk_uint8_t) (i == nargs - 1 ? '\\n' : ' ');\n\t\t}\n\t} else {\n\t\tbuf = (const duk_uint8_t *) &nl;\n\t\tsz_buf = 1;\n\t}\n\n\t/* 'buf' contains the string to write, 'sz_buf' contains the length\n\t * (which may be zero).\n\t */\n\n\tif (sz_buf > 0) {\n\t\tfwrite((const void *) buf, 1, (size_t) sz_buf, fh);\n#if defined(DUK_PRINT_ALERT_FLUSH)\n\t\tfflush(fh);\n#endif\n\t}\n\n\treturn 0;\n}\n#endif\n\nstatic duk_ret_t duk__print(duk_context *ctx) {\n\treturn duk__print_alert_helper(ctx, stdout);\n}\n\nstatic duk_ret_t duk__alert(duk_context *ctx) {\n\treturn duk__print_alert_helper(ctx, stderr);\n}\n\nvoid duk_print_alert_init(duk_context *ctx, duk_uint_t flags) {\n\t(void) flags;  /* unused at the moment */\n\n\t/* XXX: use duk_def_prop_list(). */\n\tduk_push_global_object(ctx);\n\tduk_push_string(ctx, \"print\");\n\tduk_push_c_function(ctx, duk__print, DUK_VARARGS);\n\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_CONFIGURABLE);\n\tduk_push_string(ctx, \"alert\");\n\tduk_push_c_function(ctx, duk__alert, DUK_VARARGS);\n\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_CONFIGURABLE);\n\tduk_pop(ctx);\n}\n"
  },
  {
    "path": "react_juce/duktape/extras/print-alert/duk_print_alert.h",
    "content": "#if !defined(DUK_PRINT_ALERT_H_INCLUDED)\n#define DUK_PRINT_ALERT_H_INCLUDED\n\n#include \"duktape.h\"\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/* No flags at the moment. */\n\nextern void duk_print_alert_init(duk_context *ctx, duk_uint_t flags);\n\n#if defined(__cplusplus)\n}\n#endif  /* end 'extern \"C\"' wrapper */\n\n#endif /* DUK_PRINT_ALERT_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/extras/print-alert/test.c",
    "content": "#include <stdio.h>\n#include \"duktape.h\"\n#include \"duk_print_alert.h\"\n\nint main(int argc, char *argv[]) {\n\tduk_context *ctx;\n\tint i;\n\tint exitcode = 0;\n\n\tctx = duk_create_heap_default();\n\tif (!ctx) {\n\t\treturn 1;\n\t}\n\n\tduk_print_alert_init(ctx, 0 /*flags*/);\n\tprintf(\"top after init: %ld\\n\", (long) duk_get_top(ctx));\n\n\tfor (i = 1; i < argc; i++) {\n\t\tprintf(\"Evaling: %s\\n\", argv[i]);\n\t\tif (duk_peval_string(ctx, argv[i]) != 0) {\n\t\t\texitcode = 1;\n\t\t}\n\t\tprintf(\"--> %s\\n\", duk_safe_to_string(ctx, -1));\n\t\tduk_pop(ctx);\n\t}\n\n\tprintf(\"Done\\n\");\n\tduk_destroy_heap(ctx);\n\treturn exitcode;\n}\n"
  },
  {
    "path": "react_juce/duktape/licenses/commonjs.txt",
    "content": "CommonJS specification snapshots are included in the references/\ndirectory.  CommonJS is under the MIT license: http://www.commonjs.org/.\n"
  },
  {
    "path": "react_juce/duktape/licenses/lua.txt",
    "content": "Lua is under the MIT license: http://www.lua.org/license.html.\n"
  },
  {
    "path": "react_juce/duktape/licenses/murmurhash2.txt",
    "content": "The MIT License\n\nCopyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "react_juce/duktape/licenses/splitmix64.txt",
    "content": "/*  Written in 2015 by Sebastiano Vigna (vigna@acm.org)\n\nTo the extent possible under law, the author has dedicated all copyright\nand related and neighboring rights to this software to the public domain\nworldwide. This software is distributed without any warranty.\n\nSee <http://creativecommons.org/publicdomain/zero/1.0/>. */\n"
  },
  {
    "path": "react_juce/duktape/licenses/xoroshiro128plus.txt",
    "content": "/*  Written in 2016 by David Blackman and Sebastiano Vigna (vigna@acm.org)\n\nTo the extent possible under law, the author has dedicated all copyright\nand related and neighboring rights to this software to the public domain\nworldwide. This software is distributed without any warranty.\n\nSee <http://creativecommons.org/publicdomain/zero/1.0/>. */\n"
  },
  {
    "path": "react_juce/duktape/mandel.js",
    "content": "/*\n *  Mandelbrot example:\n *\n *    $ ./duk mandel.js\n *    [...]\n */\n\nfunction mandel() {\n    var w = 76, h = 28, iter = 100;\n    var i, j, k, c;\n    var x0, y0, xx, yy, xx2, yy2;\n    var line;\n\n    for (i = 0; i < h; i++) {\n        y0 = (i / h) * 2.5 - 1.25;\n\n        for (j = 0, line = []; j < w; j++) {\n            x0 = (j / w) * 3.0 - 2.0;\n\n            for (k = 0, xx = 0, yy = 0, c = '#'; k < iter; k++) {\n                /* z -> z^2 + c\n                 *   -> (xx+i*yy)^2 + (x0+i*y0)\n                 *   -> xx*xx+i*2*xx*yy-yy*yy + x0 + i*y0\n                 *   -> (xx*xx - yy*yy + x0) + i*(2*xx*yy + y0)\n                 */\n\n                xx2 = xx*xx; yy2 = yy*yy;\n\n                if (xx2 + yy2 < 4.0) {\n                    yy = 2*xx*yy + y0;\n                    xx = xx2 - yy2 + x0;\n                } else {\n                    /* xx^2 + yy^2 >= 4.0 */\n                    if (k < 3) { c = '.'; }\n                    else if (k < 5) { c = ','; }\n                    else if (k < 10) { c = '-'; }\n                    else { c = '='; }\n                    break;\n                }\n            }\n\n            line.push(c);\n        }\n\n        print(line.join(''));\n    }\n}\n\ntry {\n    mandel();\n} catch (e) {\n    print(e.stack || e);\n}\n"
  },
  {
    "path": "react_juce/duktape/polyfills/console-minimal.js",
    "content": "/*\n *  Minimal console.log() polyfill\n */\n\nif (typeof console === 'undefined') {\n    Object.defineProperty(this, 'console', {\n        value: {}, writable: true, enumerable: false, configurable: true\n    });\n}\nif (typeof console.log === 'undefined') {\n    (function () {\n        var origPrint = print;  // capture in closure in case changed later\n        Object.defineProperty(this.console, 'log', {\n            value: function () {\n                var strArgs = Array.prototype.map.call(arguments, function (v) { return String(v); });\n                origPrint(Array.prototype.join.call(strArgs, ' '));\n            }, writable: true, enumerable: false, configurable: true\n        });\n    })();\n}\n"
  },
  {
    "path": "react_juce/duktape/polyfills/duktape-buffer.js",
    "content": "/*\n *  Duktape.Buffer polyfill for Duktape 1.x compatibility.\n *\n *  Because plain buffer and other buffer behavior changed in Duktape 2.x\n *  quite a bit, 100% matching behavior is not possible.\n */\n\nif (typeof Duktape === 'object' && typeof Duktape.Buffer === 'undefined') {\n    (function () {\n        function isBufferOrView(v) {\n            return v instanceof Buffer ||\n                   v instanceof ArrayBuffer ||\n                   v instanceof Uint8Array ||  // also matches plain buffer in 2.x\n                   v instanceof Uint8ClampedArray ||\n                   v instanceof Int8Array ||\n                   v instanceof Uint16Array ||\n                   v instanceof Int16Array ||\n                   v instanceof Uint32Array ||\n                   v instanceof Int32Array ||\n                   v instanceof Float32Array ||\n                   v instanceof Float64Array ||\n                   v instanceof DataView;\n        }\n        var fn = function Buffer(arg) {\n            if (this instanceof fn) {\n                // Constructor call (not 100% reliable check); result is an\n                // ArrayBuffer (in 1.x Duktape.Buffer).  For a buffer argument\n                // the ArrayBuffer shares the argument's storage with any slice\n                //offset/length lost.\n                if (isBufferOrView(arg)) {\n                    return Object(Uint8Array.plainOf(arg));\n                } else {\n                    return Object(Uint8Array.allocPlain(arg));\n                }\n            } else {\n                // Normal call; result is a plain buffer.  For a buffer argument the\n                // underlying buffer is returned (shared, not copy).  Otherwise a\n                // new plain buffer is created.\n                if (isBufferOrView(arg)) {\n                    return Uint8Array.plainOf(arg);\n                } else {\n                    return Uint8Array.allocPlain(arg);\n                }\n            }\n        };\n        Object.defineProperty(Duktape, 'Buffer', {\n            value: fn,\n            writable: true,\n            enumerable: false,\n            configurable: true\n        });\n    })();\n}\n"
  },
  {
    "path": "react_juce/duktape/polyfills/duktape-error-setter-nonwritable.js",
    "content": "/*\n *  Ensure Error .fileName, .lineNumber, and .stack are not directly writable,\n *  but can be written using Object.defineProperty().  This matches Duktape\n *  1.3.0 and prior.\n *\n *  See: https://github.com/svaarala/duktape/pull/390.\n */\n\n(function () {\n    var err = new Error('test');\n    err.fileName = 999;\n    if (err.fileName !== 999) { return; }  // already non-writable\n\n    var fn = new Function('');  // nop\n    Object.defineProperties(Error.prototype, {\n        fileName: { set: fn },\n        lineNumber: { set: fn },\n        stack: { set: fn }\n    });\n})();\n"
  },
  {
    "path": "react_juce/duktape/polyfills/duktape-error-setter-writable.js",
    "content": "/*\n *  Ensure Error .fileName, .lineNumber, and .stack are directly writable\n *  without having to use Object.defineProperty().  This matches Duktape\n *  1.4.0 behavior.\n *\n *  See: https://github.com/svaarala/duktape/pull/390.\n */\n\n(function () {\n    var err = new Error('test');\n    err.fileName = 999;\n    if (err.fileName === 999) { return; }  // already writable\n\n    Object.defineProperties(Error.prototype, {\n        fileName: { set: new Function('v', 'Object.defineProperty(this, \"fileName\", { value: v, writable: true, enumerable: false, configurable: true });') },\n        lineNumber: { set: new Function('v', 'Object.defineProperty(this, \"lineNumber\", { value: v, writable: true, enumerable: false, configurable: true });') },\n        stack: { set: new Function('v', 'Object.defineProperty(this, \"stack\", { value: v, writable: true, enumerable: false, configurable: true });') },\n    });\n})();\n"
  },
  {
    "path": "react_juce/duktape/polyfills/duktape-isfastint.js",
    "content": "/*\n *  Helper to check if a number is internally represented as a fastint:\n *\n *    if (Duktape.isFastint(x)) {\n *        print('fastint');\n *    } else {\n *        print('not a fastint (or not a number)');\n *    }\n *\n *  NOTE: This helper depends on the internal tag numbering (defined in\n *  duk_tval.h) which is both version specific and depends on whether\n *  duk_tval is packed or not.\n */\n\nif (typeof Duktape === 'object') {\n    if (typeof Duktape.fastintTag === 'undefined') {\n        Object.defineProperty(Duktape, 'fastintTag', {\n            /* Tag number depends on duk_tval packing. */\n            value: (Duktape.info(true).itag >= 0xfff0) ?\n                    0xfff1 /* tag for packed duk_tval */ :\n                    1 /* tag for unpacked duk_tval */,\n            writable: false,\n            enumerable: false,\n            configurable: true\n        });\n    }\n    if (typeof Duktape.isFastint === 'undefined') {\n        Object.defineProperty(Duktape, 'isFastint', {\n            value: function (v) {\n                return Duktape.info(v).type === 4 &&                 /* public type is DUK_TYPE_NUMBER */\n                       Duktape.info(v).itag === Duktape.fastintTag;  /* internal tag is fastint */\n            },\n            writable: false,\n            enumerable: false,\n            configurable: true\n        });\n    }\n}\n"
  },
  {
    "path": "react_juce/duktape/polyfills/global.js",
    "content": "/*\n *  Duktape 2.1.0 adds a 'global' binding.  Polyfill for earlier versions.\n */\n\nif (typeof global === 'undefined') {\n    (function () {\n        var global = new Function('return this;')();\n        Object.defineProperty(global, 'global', {\n            value: global,\n            writable: true,\n            enumerable: false,\n            configurable: true\n        });\n    })();\n}\n"
  },
  {
    "path": "react_juce/duktape/polyfills/object-assign.js",
    "content": "/*\n *  Object.assign(), described in E6 Section 19.1.2.1\n *\n *  http://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.assign\n */\n\nif (typeof Object.assign === 'undefined') {\n   Object.defineProperty(Object, 'assign', {\n       value: function (target) {\n           var i, n, j, m, k;\n           var source, keys;\n           var gotError;\n           var pendingError;\n\n           if (target == null) {\n               throw new Exception('target null or undefined');\n           }\n\n           for (i = 1, n = arguments.length; i < n; i++) {\n               source = arguments[i];\n               if (source == null) {\n                   continue;  // null or undefined\n               }\n               source = Object(source);\n               keys = Object.keys(source);  // enumerable own keys\n\n               for (j = 0, m = keys.length; j < m; j++) {\n                   k = keys[j];\n                   try {\n                       target[k] = source[k];\n                   } catch (e) {\n                       if (!gotError) {\n                           gotError = true;\n                           pendingError = e;\n                       }\n                   }\n               }\n           }\n\n           if (gotError) {\n               throw pendingError;\n           }\n       }, writable: true, enumerable: false, configurable: true\n   });\n}\n"
  },
  {
    "path": "react_juce/duktape/polyfills/object-prototype-definegetter.js",
    "content": "/*\n *  Object.prototype.__defineGetter__ polyfill\n */\n\n(function () {\n    if (typeof Object.prototype.__defineGetter__ === 'undefined') {\n        var DP = Object.defineProperty;\n        DP(Object.prototype, '__defineGetter__', {\n            value: function (n, f) {\n                DP(this, n, { enumerable: true, configurable: true, get: f });\n            }, writable: true, enumerable: false, configurable: true\n        });\n    }\n})();\n"
  },
  {
    "path": "react_juce/duktape/polyfills/object-prototype-definesetter.js",
    "content": "/*\n *  Object.prototype.__defineSetter__ polyfill\n */\n\n(function () {\n    if (typeof Object.prototype.__defineSetter__ === 'undefined') {\n        var DP = Object.defineProperty;\n        DP(Object.prototype, '__defineSetter__', {\n            value: function (n, f) {\n                DP(this, n, { enumerable: true, configurable: true, set: f });\n            }, writable: true, enumerable: false, configurable: true\n        });\n    }\n})();\n"
  },
  {
    "path": "react_juce/duktape/polyfills/performance-now.js",
    "content": "/*\n *  Performance.now() polyfill\n *\n *  http://www.w3.org/TR/hr-time/#sec-high-resolution-time\n *\n *  Dummy implementation which uses the Date built-in and has no higher\n *  resolution.  If/when Duktape has a built-in high resolution timer\n *  interface, reimplement this.\n */\n\nvar _perfNowZeroTime = Date.now();\n\nif (typeof Performance === 'undefined') {\n    Object.defineProperty(this, 'Performance', {\n        value: {},\n        writable: true, enumerable: false, configurable: true\n    });\n}\nif (typeof Performance.now === 'undefined') {\n    Object.defineProperty(Performance, 'now', {\n        value: function () {\n            return Date.now() - _perfNowZeroTime;\n        }, writable: true, enumerable: false, configurable: true\n    });\n}\n"
  },
  {
    "path": "react_juce/duktape/polyfills/promise.js",
    "content": "/*\n *  Minimal ES2015+ Promise polyfill\n *\n *  Limitations (also see XXX in source):\n *\n *    - Caller must manually call Promise.runQueue() to process pending jobs.\n *    - No Promise subclassing or non-subclass foreign Promises yet.\n *    - Promise.all() and Promise.race() assume a plain array, not iterator.\n *    - Doesn't handle errors from core operations, e.g. out-of-memory or\n *      internal error when queueing/running jobs.  These are implementation\n *      defined for the most part.\n *\n *  This polyfill was originally used to gain a better understanding of the\n *  ES2015 specification algorithms, before implementing Promises natively.\n *\n *  The polyfill uses a Symbol to mark Promise instances, but falls back to\n *  an ordinary (non-enumerable) property if no Symbol support is available.\n *  Presence of the polyfill itself can be checked using \"Promise.isPolyfill\".\n *\n *  Unhandled Promise rejections use a custom API signature.  For now, a\n *  single Promise.unhandledRejection() hook receives both 'rawReject' and\n *  'rawHandle' events directly from HostPromiseRejectionTracker, and higher\n *  level (Node.js / WHATWG like) 'reject' and 'handle' events which filter\n *  out cases where a rejected Promise is initially unhandled but gets handled\n *  within the same \"tick\".\n *\n *  See also: https://github.com/stefanpenner/es6-promise#readme\n */\n\n(function () {\n    if (typeof Promise !== 'undefined') { return; }\n\n    // As far as the specification goes, almost all Promise settling is via\n    // concrete resolve/reject functions with mutual protection from being\n    // called multiple times.  Sometimes the actual resolve/reject functions\n    // are not exposed to calling code, and can safely be omitted which is\n    // useful because resolve/reject functions are memory heavy.  These\n    // optimizations are enabled by default; set to false to disable.\n    var allowOptimization = true;\n\n    // Job queue to simulate ES2015 job queues, linked list, 'next' reference.\n    // While ES2015 doesn't guarantee the relative order of jobs in different\n    // job queues, within a certain queue strict FIFO is required.  See ES5.1\n    // https://www.ecma-international.org/ecma-262/6.0/#sec-jobs-and-job-queues:\n    // \"The PendingJob records from a single Job Queue are always initiated in\n    // FIFO order. This specification does not define the order in which\n    // multiple Job Queues are serviced.\"\n    var queueHead = null, queueTail = null;\n    function enqueueJob(job) {\n        // Avoid inheriting conflicting properties if caller already didn't\n        // ensure it.\n        Object.setPrototypeOf(job, null);\n        compact(job);\n        if (queueHead) {\n            queueTail.next = job;\n            compact(queueTail);\n            queueTail = job;\n        } else {\n            queueHead = job;\n            queueTail = job;\n        }\n    }\n    function dequeueJob() {\n        var ret = queueHead;\n        if (ret) {\n            queueHead = ret.next;\n            if (!queueHead) {\n                queueTail = null;\n            }\n        }\n        return ret;\n    }\n    function queueEmpty() {\n        return !queueHead;\n    }\n\n    // Helper to define/modify properties more compactly.\n    function def(obj, key, val, attrs) {\n        if (attrs === void 0) { attrs = 'wc'; }\n        Object.defineProperty(obj, key, {\n            value: val,\n            writable: attrs.indexOf('w') >= 0,\n            enumerable: attrs.indexOf('e') >= 0,\n            configurable: attrs.indexOf('c') >= 0\n        });\n    }\n\n    // Helper for Duktape specific object compaction.\n    var compact = (typeof Duktape === 'object' && Duktape.compact) ||\n                  function (v) { return v; };\n\n    // Shared no-op function.\n    var nop = function nop() {};\n\n    // Promise detection (plain or subclassed Promise), in spec has\n    // [[PromiseState]] internal slot which isn't affected by Proxy\n    // behaviors etc.\n    var haveSymbols = (typeof Symbol === 'function');\n    var promiseMarker = haveSymbols ? Symbol('promise') : '__PromiseInstance__';\n    function isPromise(p) {\n        return p !== null && typeof p === 'object' && promiseMarker in p;\n    }\n    function requirePromise(p) {\n        if (!isPromise(p)) { throw new TypeError('Promise required'); }\n    }\n\n    // Raw HostPromiseRejectionTracker call.  This operation should \"never\"\n    // fail but that's in practice unachievable due to possible out-of-memory\n    // on any operation (including invocation of the callback).  Higher level\n    // hook events are emitted from Promise.runQueue().\n    function safeCallUnhandledRejection(event) {\n        try {\n            cons.unhandledRejection(event);\n        } catch (e) {\n            //console.log('Promise.unhandledRejection failed:', e);\n        }\n    }\n    function rejectionTracker(p, operation) {\n        try {\n            if (operation === 'reject') {\n                // Unhandled at resolution.\n                safeCallUnhandledRejection({ promise: p, event: 'rawReject', reason: p.value });\n                def(p, 'unhandled', 1);\n                cons.potentiallyUnhandled.push(p);\n            } else if (operation === 'handle') {\n                safeCallUnhandledRejection({ promise: p, event: 'rawHandle', reason: p.value });\n                if (p.unhandled === 2) {\n                    // Unhandled, already notified, need handled notification.\n                    def(p, 'unhandled', 3);\n                    cons.potentiallyUnhandled.push(p);\n                } else {\n                    // Handled but not yet notified -> no action needed.\n                    // XXX: If this.unhandled was 1, we'd like to remove\n                    // the Promise from cons.potentiallyUnhandled list.\n                    // We skip that here because it would mean an expensive\n                    // list remove.  If cons.potentiallyUnhandled was a\n                    // Set, it would be natural to remove from Set here.\n                    delete p.unhandled;\n                }\n            }\n        } catch (e) {\n            //console.log('HostPromiseRejectionTracker failed:', e);\n        }\n    }\n\n    // Raw fulfill/reject operations, assume resolution processing done.\n    // The specification algorithms RejectPromise() and FulfillPromise()\n    // assert that the Promise is pending so the initial check in these\n    // implementations (p.state !== void 0) is not needed: the resolve/reject\n    // function pairs always ensure a Promise is not ultimately settled twice.\n    // With some of the \"as if\" optimizations we rely on these raw operations\n    // to protect against multiple attempts to settle the Promise so the checks\n    // are actually needed.\n    function doFulfill(p, val) {\n        if (p.state !== void 0) { return; }  // additional check needed with optimizations\n        p.state = true; p.value = val;\n        var reactions = p.fulfillReactions;\n        delete p.fulfillReactions; delete p.rejectReactions; compact(p);\n        reactions.forEach(function (ent) {\n            // Conceptually: create a job from the registered reaction.\n            // In practice: reuse the reaction object because it is unique,\n            // never leaks to calling code, and is never reused.\n            ent.value = val;\n            enqueueJob(ent);\n        });\n    }\n    function doReject(p, val) {\n        if (p.state !== void 0) { return; }  // additional check needed with optimizations\n        p.state = false; p.value = val;\n        var reactions = p.rejectReactions;\n        delete p.fulfillReactions; delete p.rejectReactions; compact(p);\n        reactions.forEach(function (ent) {\n            // As for doFulfill(), reuse the registered reaction object.\n            ent.value = val;\n            if (!ent.handler) {\n                // Without a .handler, we're dealing with an optimized\n                // entry where only .target exists and the resolve/reject\n                // behavior is simulated when the entry runs.  However,\n                // we need to know whether to simulate resolve or reject\n                // at that time, so flag rejection explicitly (resolve\n                // requires no flag).\n                ent.rejected = true;\n            }\n            enqueueJob(ent);\n        });\n        if (!p.isHandled) {\n            rejectionTracker(p, 'reject');\n        }\n    }\n\n    // Create a new resolve/reject pair for a Promise.  Multiple pairs are\n    // needed in thenable handling, with all but the most recent pair being\n    // neutralized ('alreadyResolved').  Because Promises are resolved only\n    // via this resolution process, it shouldn't be possible for the Promise\n    // to be settled but check it anyway: it may be useful for e.g. the C API\n    // to forcibly resolve/fulfill/reject a Promise regardless of extant\n    // resolve/reject functions.\n    function createResolutionFunctions(p) {\n        // In ES2015 the resolve/reject functions have a shared 'state' object\n        // with a [[AlreadyResolved]] slot.  Here we use an in-scope variable.\n        var alreadyResolved = false;\n        var reject = function (err) {\n            if (new.target) { throw new TypeError('reject is not constructable'); }\n            if (alreadyResolved) { return; }\n            alreadyResolved = true;  // neutralize resolve/reject\n            if (p.state !== void 0) { return; }\n            doReject(p, err);\n        };\n        reject.prototype = null;  // drop .prototype object\n        var resolve = function (val) {\n            if (new.target) { throw new TypeError('resolve is not constructable'); }\n            if (alreadyResolved) { return; }\n            alreadyResolved = true;  // neutralize resolve/reject\n            if (p.state !== void 0) { return; }\n            if (val === p) {\n                return doReject(p, new TypeError('self resolution'));\n            }\n            try {\n                var then = (val !== null && typeof val === 'object' &&\n                            val.then);\n                if (typeof then === 'function') {\n                    var t = createResolutionFunctions(p);\n                    var optimized = allowOptimization;\n                    if (optimized) {\n                        // XXX: this optimization may not be useful because the\n                        // job entry runs usually very quickly, and as part of\n                        // running the job, the resolve/reject function must be\n                        // created for the then() call.\n                        return enqueueJob({\n                            thenable: val,\n                            then: then,\n                            target: p\n                        });\n                    } else {\n                        return enqueueJob({\n                            thenable: val,\n                            then: then,\n                            resolve: t.resolve,\n                            reject: t.reject\n                        });\n                    }\n                    // old resolve/reject is neutralized, only new pair is live\n                }\n                return doFulfill(p, val);\n            } catch (e) {\n                return doReject(p, e);\n            }\n        };\n        resolve.prototype = null;  // drop .prototype object\n        return { resolve: resolve, reject: reject };\n    }\n\n    // Job queue simulation.\n    function runQueueEntry() {\n        // XXX: In optimized cases, creating both resolution functions is\n        // not always necessary.  There's also no need for alreadySettled\n        // protections for the optimized cases either.\n        var job = dequeueJob();\n        var tmp;\n        if (!job) { return false; }\n        if (job.then) {\n            // PromiseResolveThenableJob\n            if (job.target) {\n                tmp = createResolutionFunctions(job.target);\n            }\n            try {\n                if (tmp) {\n                    void job.then.call(job.thenable, tmp.resolve, tmp.reject);\n                } else {\n                    void job.then.call(job.thenable, job.resolve, job.reject);\n                }\n            } catch (e) {\n                if (tmp) {\n                    tmp.reject.call(void 0, e);\n                } else {\n                    job.reject.call(void 0, e);\n                }\n            }\n        } else {\n            // PromiseReactionJob\n            try {\n                if (job.handler === void 0) {\n                    // Optimized case where two Promises are tied together\n                    // without the need for an actual 'handler'.\n                    tmp = createResolutionFunctions(job.target);  // must exist in this case\n                    tmp = job.rejected ? tmp.reject : tmp.resolve;\n                    tmp.call(void 0, job.value);\n                    return true;\n                } else if (job.handler === 'Identity') {\n                    res = job.value;\n                } else if (job.handler === 'Thrower') {\n                    throw job.value;\n                } else {\n                    res = job.handler.call(void 0, job.value);\n                }\n                if (job.target) {\n                    createResolutionFunctions(job.target).resolve.call(void 0, res);\n                } else {\n                    job.resolve.call(void 0, res);\n                }\n            } catch (e) {\n                if (job.target) {\n                    createResolutionFunctions(job.target).reject.call(void 0, e);\n                } else {\n                    job.reject.call(void 0, e);\n                }\n            }\n        }\n        return true;\n    }\n\n    // %Promise% constructor.\n    var cons = function Promise(executor) {\n        if (!new.target) {\n            throw new TypeError('Promise must be called as a constructor');\n        }\n        if (typeof executor !== 'function') {\n            throw new TypeError('executor must be callable');\n        }\n        var _this = this;\n        def(this, promiseMarker, true, '');\n        def(this, 'state', void 0);   // undefined (pending), true/false\n        def(this, 'value', void 0);\n        def(this, 'fulfillReactions', []);\n        def(this, 'rejectReactions', []);\n        def(this, 'isHandled', false);  // XXX: roll into 'state' to minimize fields\n        compact(this);\n        var t = createResolutionFunctions(this);\n        try {\n            void executor(t.resolve, t.reject);\n        } catch (e) {\n            t.reject(e);\n        }\n    };\n    var proto = cons.prototype;\n    def(cons, 'prototype', proto, '');\n    def(cons, 'potentiallyUnhandled', [], '');\n\n    // %Promise%.resolve().\n    // XXX: direct handling\n    function resolve(val) {\n        if (isPromise(val) && val.constructor === this) { return val; }\n        return new Promise(function (resolve, reject) { resolve(val); });\n    }\n\n    // %Promise%.reject()\n    // XXX: direct handling\n    function reject(val) {\n        return new Promise(function (resolve, reject) { reject(val); });\n    }\n\n    // %Promise%.all().\n    function all(list) {\n        if (!Array.isArray(list)) {\n            throw new TypeError('non-array all() argument not supported');\n        }\n        var resolveFn, rejectFn;\n        var p = new Promise(function (resolve, reject) {\n            resolveFn = resolve; rejectFn = reject;\n        });\n        var values = [];\n        var index = 0;\n        var remaining = 1;  // remaining intentionally 1, not 0\n        list.forEach(function (x) {  // XXX: no iterator support\n            var t = Promise.resolve(x);\n            var f = function promiseAllElement(val) {\n                var F = promiseAllElement;\n                if (F.alreadyCalled) { return; }\n                F.alreadyCalled = true;\n                values[F.index] = val;\n                if (--remaining === 0) {\n                    resolveFn.call(void 0, values);\n                }\n            };\n            // In ES2015 the functions would reference a shared state object\n            // explicitly.  Here the conceptual state is in scope.\n            f.index = index++;\n            remaining++;\n            t.then(f, rejectFn);\n        });\n        if (--remaining === 0) {\n            resolveFn.call(void 0, values);\n        }\n        return p;\n    }\n\n    // %Promise%.race().\n    function race(list) {\n        if (!Array.isArray(list)) {\n            throw new TypeError('non-array race() argument not supported');\n        }\n        var resolveFn, rejectFn;\n        var p = new Promise(function (resolve, reject) {\n            resolveFn = resolve; rejectFn = reject;\n        });\n        list.forEach(function (x) {  // XXX: no iterator support\n            var t = Promise.resolve(x);\n            var func = t.then;\n            var optimized = (func === then) && allowOptimization;\n            if (optimized) {\n                // If the .then() of the Promise.resolve() is the original\n                // built-in implementation, we don't need to queue the actual\n                // resolve and reject functions explicitly because (1) the\n                // functions don't leak and can't be called by anyone else,\n                // and (2) the onFulfilled/onRejected functions would just\n                // directly forward the result from 't' to 'p'.\n                optimizedThen(t, p);\n            } else {\n                // Generic case, the result Promise of .then() is ignored.\n                void func.call(t, resolveFn, rejectFn);\n            }\n        });\n        return p;\n    }\n\n    // %PromisePrototype%.then(), also used for .catch().\n    function then(onFulfilled, onRejected) {\n        // No subclassing support here now, no NewPromiseCapability() handling.\n        requirePromise(this);\n        var resolveFn, rejectFn;\n        var p = new Promise(function (resolve, reject) {\n            resolveFn = resolve; rejectFn = reject;\n        });\n        var optimized = allowOptimization;\n        if (typeof onFulfilled !== 'function') { onFulfilled = 'Identity'; }\n        if (typeof onRejected !== 'function') { onRejected = 'Thrower'; }\n\n        if (this.state === void 0) {  // pending\n            if (optimized) {\n                this.fulfillReactions.push({\n                    handler: onFulfilled,\n                    target: p\n                });\n                this.rejectReactions.push({\n                    handler: onRejected,\n                    target: p\n                });\n            } else {\n                this.fulfillReactions.push({\n                    handler: onFulfilled,\n                    resolve: resolveFn,\n                    reject: rejectFn\n                });\n                this.rejectReactions.push({\n                    handler: onRejected,\n                    resolve: resolveFn,\n                    reject: rejectFn\n                });\n            }\n        } else if (this.state) {  // fulfilled\n            if (optimized) {\n                enqueueJob({\n                    handler: onFulfilled,\n                    target: p,\n                    value: this.value\n                });\n            } else {\n                enqueueJob({\n                    handler: onFulfilled,\n                    resolve: resolveFn,\n                    reject: rejectFn,\n                    value: this.value\n                });\n            }\n        } else {  // rejected\n            if (!this.isHandled) {\n                rejectionTracker(this, 'handle');\n            }\n            if (optimized) {\n                enqueueJob({\n                    handler: onRejected,\n                    target: p,\n                    value: this.value\n                });\n            } else {\n                enqueueJob({\n                    handler: onRejected,\n                    resolve: resolveFn,\n                    reject: rejectFn,\n                    value: this.value\n                });\n            }\n        }\n        this.isHandled = true;\n        return p;\n    }\n\n    // Optimized .then() where a specific source Promise just forwards its\n    // result to a target Promise unless its already settled.\n    function optimizedThen(source, target) {\n        if (source.state === void 0) {  // pending\n            source.fulfillReactions.push({\n                target: target\n            });\n            source.rejectReactions.push({\n                target: target\n            });\n        } else if (source.state) {  // fulfilled\n            enqueueJob({\n                target: target,\n                value: source.value\n            });\n        } else {  // rejected\n            if (!source.isHandled) {\n                rejectionTracker(source, 'handle');\n            }\n            enqueueJob({\n                target: target,\n                value: source.value,\n                rejected: true\n            });\n        }\n        source.isHandled = true;\n    }\n\n    // %PromisePrototype%.catch.\n    var _catch = function (onRejected) {\n        return this.then.call(this, void 0, onRejected);\n    };\n    def(_catch, 'name', 'catch', 'c');\n\n    // %Promise%.try(), https://github.com/tc39/proposal-promise-try,\n    // simple polyfill-style implementation.\n    var _try = function (func) {\n        // XXX: check 'this' for callability, or Promise / subclass.\n        return new this(function (resolve, reject) { resolve(func()); });\n    };\n    def(_try, 'name', 'try', 'c');\n\n    // Emit higher level Node.js/WHATWG like 'reject' and 'handle' events,\n    // filtering out some cases where a rejected Promise is initially unhandled\n    // but is handled within the same \"tick\" (for a relatively murky definition\n    // of a \"tick\").\n    // https://html.spec.whatwg.org/multipage/webappapis.html#unhandled-promise-rejections\n    // https://www.ecma-international.org/ecma-262/8.0/#sec-host-promise-rejection-tracker\n    function checkUnhandledRejections() {\n        var idx;\n\n        // The unhandledRejection() callbacks may have queued more Promises,\n        // settled existing Promises on the list, etc.  Keep going until\n        // the list is empty.  Null out entries to allow early GC when the\n        // Promises are no longer reachable.  Callbacks may also queue more\n        // ordinary Promise jobs; they are also handled to completion within\n        // the tick.\n\n        // XXX: It might be more natural to handle the notification callbacks\n        // via the job queue.  This might be a bit simpler, but would change\n        // the Promise job vs. unhandledRejection callback ordering a bit.\n        // For example, Node.js emits 'handle' events before the related\n        // catch callbacks are called, while the polyfill in its current\n        // state does not.\n\n        for (idx = 0; idx < cons.potentiallyUnhandled.length; idx++) {\n            var p = cons.potentiallyUnhandled[idx];\n            cons.potentiallyUnhandled[idx] = null;\n\n            // For consistency with hook calls from HostPromiseRejectionTracker\n            // errors from user callback are silently eaten.  If a process exit\n            // is desirable, user callback may call a custom native binding to\n            // do that (\"process.exit(1)\" or similar).\n            //\n            // Use a custom object argument convention for flexibility.\n\n            if (p.unhandled === 1) {\n                safeCallUnhandledRejection({ promise: p, event: 'reject', reason: p.value });\n                def(p, 'unhandled', 2);\n            } else if (p.unhandled === 3) {\n                safeCallUnhandledRejection({ promise: p, event: 'handle', reason: p.value });\n                delete p.unhandled;\n            }\n        }\n\n        cons.potentiallyUnhandled.length = 0;\n\n        return idx > 0;  // true if we processed entries\n    }\n\n    // Define visible objects and properties.\n    (function () {\n        def(this, 'Promise', cons);\n        def(cons, 'resolve', resolve);\n        def(cons, 'reject', reject);\n        def(cons, 'all', all);\n        def(cons, 'race', race);\n        def(cons, 'try', _try);\n        def(cons, 'isPolyfill', true);  // needed by e.g. testcases\n        def(proto, 'then', then);\n        def(proto, 'catch', _catch);\n        if (haveSymbols) {\n            def(proto, Symbol.toStringTag, 'Promise', 'c');\n        }\n\n        // Custom API to drive the \"job queue\".  We only want to exit when\n        // there are no more Promise jobs or unhandledRejection() callbacks,\n        // i.e. no more work to do.  Note that an unhandledRejection()\n        // callback may queue more Promise job entries and vice versa.\n        def(cons, 'runQueue', function _runQueueUntilEmpty() {\n            do {\n                while (runQueueEntry()) {}\n                checkUnhandledRejections();\n            } while(!(queueEmpty() && cons.potentiallyUnhandled.length === 0));\n        });\n        def(cons, 'unhandledRejection', nop);\n\n        compact(this); compact(cons); compact(proto);\n    }());\n}());\n"
  },
  {
    "path": "react_juce/duktape/src/duk_config.h",
    "content": "/*\n *  duk_config.h configuration header generated by genconfig.py.\n *\n *  Git commit: d4f2cff1c592d70f58bab8e1bd85705174c02a58\n *  Git describe: v2.4.0\n *  Git branch: master\n *\n *  Supported platforms:\n *      - Mac OSX, iPhone, Darwin\n *      - Orbis\n *      - OpenBSD\n *      - Generic BSD\n *      - Atari ST TOS\n *      - AmigaOS\n *      - Durango (XboxOne)\n *      - Windows\n *      - Flashplayer (Crossbridge)\n *      - QNX\n *      - TI-Nspire\n *      - Emscripten\n *      - Android\n *      - Linux\n *      - Solaris\n *      - AIX\n *      - HPUX\n *      - Generic POSIX\n *      - Cygwin\n *      - Generic UNIX\n *      - Generic fallback\n *\n *  Supported architectures:\n *      - x86\n *      - x64\n *      - x32\n *      - ARM 32-bit\n *      - ARM 64-bit\n *      - MIPS 32-bit\n *      - MIPS 64-bit\n *      - PowerPC 32-bit\n *      - PowerPC 64-bit\n *      - SPARC 32-bit\n *      - SPARC 64-bit\n *      - SuperH\n *      - Motorola 68k\n *      - Emscripten\n *      - Generic\n *\n *  Supported compilers:\n *      - Clang\n *      - GCC\n *      - MSVC\n *      - Emscripten\n *      - TinyC\n *      - VBCC\n *      - Bruce's C compiler\n *      - Generic\n *\n */\n\n#if !defined(DUK_CONFIG_H_INCLUDED)\n#define DUK_CONFIG_H_INCLUDED\n\n/*\n *  Intermediate helper defines\n */\n\n/* DLL build detection */\n/* not configured for DLL build */\n#undef DUK_F_DLL_BUILD\n\n/* Apple OSX, iOS */\n#if defined(__APPLE__)\n#define DUK_F_APPLE\n#endif\n\n/* FreeBSD */\n#if defined(__FreeBSD__) || defined(__FreeBSD)\n#define DUK_F_FREEBSD\n#endif\n\n/* Orbis (PS4) variant */\n#if defined(DUK_F_FREEBSD) && defined(__ORBIS__)\n#define DUK_F_ORBIS\n#endif\n\n/* OpenBSD */\n#if defined(__OpenBSD__) || defined(__OpenBSD)\n#define DUK_F_OPENBSD\n#endif\n\n/* NetBSD */\n#if defined(__NetBSD__) || defined(__NetBSD)\n#define DUK_F_NETBSD\n#endif\n\n/* BSD variant */\n#if defined(DUK_F_FREEBSD) || defined(DUK_F_NETBSD) || defined(DUK_F_OPENBSD) || \\\n    defined(__bsdi__) || defined(__DragonFly__)\n#define DUK_F_BSD\n#endif\n\n/* Atari ST TOS.  __TOS__ defined by PureC.  No platform define in VBCC\n * apparently, so to use with VBCC user must define __TOS__ manually.\n  */\n#if defined(__TOS__)\n#define DUK_F_TOS\n#endif\n\n/* Motorola 68K.  Not defined by VBCC, so user must define one of these\n * manually when using VBCC.\n */\n#if defined(__m68k__) || defined(M68000) || defined(__MC68K__)\n#define DUK_F_M68K\n#endif\n\n/* AmigaOS.  Neither AMIGA nor __amigaos__ is defined on VBCC, so user must\n * define 'AMIGA' manually when using VBCC.\n */\n#if defined(AMIGA) || defined(__amigaos__)\n#define DUK_F_AMIGAOS\n#endif\n\n/* PowerPC */\n#if defined(__powerpc) || defined(__powerpc__) || defined(__PPC__)\n#define DUK_F_PPC\n#if defined(__PPC64__) || defined(__LP64__) || defined(_LP64)\n#define DUK_F_PPC64\n#else\n#define DUK_F_PPC32\n#endif\n#endif\n\n/* Durango (Xbox One) */\n#if defined(_DURANGO) || defined(_XBOX_ONE)\n#define DUK_F_DURANGO\n#endif\n\n/* Windows, both 32-bit and 64-bit */\n#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64) || \\\n    defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__)\n#define DUK_F_WINDOWS\n#if defined(_WIN64) || defined(WIN64)\n#define DUK_F_WIN64\n#else\n#define DUK_F_WIN32\n#endif\n#endif\n\n/* Flash player (e.g. Crossbridge) */\n#if defined(__FLASHPLAYER__)\n#define DUK_F_FLASHPLAYER\n#endif\n\n/* QNX */\n#if defined(__QNX__)\n#define DUK_F_QNX\n#endif\n\n/* TI-Nspire (using Ndless) */\n#if defined(_TINSPIRE)\n#define DUK_F_TINSPIRE\n#endif\n\n/* Emscripten (provided explicitly by user), improve if possible */\n#if defined(EMSCRIPTEN)\n#define DUK_F_EMSCRIPTEN\n#endif\n\n/* BCC (Bruce's C compiler): this is a \"torture target\" for compilation */\n#if defined(__BCC__) || defined(__BCC_VERSION__)\n#define DUK_F_BCC\n#endif\n\n#if defined(ANDROID) || defined(__ANDROID__)\n#define DUK_F_ANDROID\n#endif\n\n/* Linux */\n#if defined(__linux) || defined(__linux__) || defined(linux)\n#define DUK_F_LINUX\n#endif\n\n/* illumos / Solaris */\n#if defined(__sun) && defined(__SVR4)\n#define DUK_F_SUN\n#if defined(__SUNPRO_C) && (__SUNPRO_C < 0x550)\n#define DUK_F_OLD_SOLARIS\n/* Defines _ILP32 / _LP64 required by DUK_F_X86/DUK_F_X64.  Platforms\n * are processed before architectures, so this happens before the\n * DUK_F_X86/DUK_F_X64 detection is emitted.\n */\n#include <sys/isa_defs.h>\n#endif\n#endif\n\n/* AIX */\n#if defined(_AIX)\n/* defined(__xlc__) || defined(__IBMC__): works but too wide */\n#define DUK_F_AIX\n#endif\n\n/* HPUX */\n#if defined(__hpux)\n#define DUK_F_HPUX\n#if defined(__ia64)\n#define DUK_F_HPUX_ITANIUM\n#endif\n#endif\n\n/* POSIX */\n#if defined(__posix)\n#define DUK_F_POSIX\n#endif\n\n/* Cygwin */\n#if defined(__CYGWIN__)\n#define DUK_F_CYGWIN\n#endif\n\n/* Generic Unix (includes Cygwin) */\n#if defined(__unix) || defined(__unix__) || defined(unix) || \\\n    defined(DUK_F_LINUX) || defined(DUK_F_BSD)\n#define DUK_F_UNIX\n#endif\n\n/* Intel x86 (32-bit), x64 (64-bit) or x32 (64-bit but 32-bit pointers),\n * define only one of DUK_F_X86, DUK_F_X64, DUK_F_X32.\n * https://sites.google.com/site/x32abi/\n *\n * With DUK_F_OLD_SOLARIS the <sys/isa_defs.h> header must be included\n * before this.\n */\n#if defined(__amd64__) || defined(__amd64) || \\\n    defined(__x86_64__) || defined(__x86_64) || \\\n    defined(_M_X64) || defined(_M_AMD64)\n#if defined(__ILP32__) || defined(_ILP32)\n#define DUK_F_X32\n#else\n#define DUK_F_X64\n#endif\n#elif defined(i386) || defined(__i386) || defined(__i386__) || \\\n      defined(__i486__) || defined(__i586__) || defined(__i686__) || \\\n      defined(__IA32__) || defined(_M_IX86) || defined(__X86__) || \\\n      defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__)\n#if defined(__LP64__) || defined(_LP64)\n/* This should not really happen, but would indicate x64. */\n#define DUK_F_X64\n#else\n#define DUK_F_X86\n#endif\n#endif\n\n/* ARM */\n#if defined(__arm__) || defined(__thumb__) || defined(_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__)\n#define DUK_F_ARM\n#if defined(__LP64__) || defined(_LP64) || defined(__arm64) || defined(__arm64__) || defined(_M_ARM64) || defined(__aarch64__)\n#define DUK_F_ARM64\n#else\n#define DUK_F_ARM32\n#endif\n#endif\n\n/* MIPS.  Related defines: __MIPSEB__, __MIPSEL__, __mips_isa_rev, __LP64__ */\n#if defined(__mips__) || defined(mips) || defined(_MIPS_ISA) || \\\n    defined(_R3000) || defined(_R4000) || defined(_R5900) || \\\n    defined(_MIPS_ISA_MIPS1) || defined(_MIPS_ISA_MIPS2) || \\\n    defined(_MIPS_ISA_MIPS3) || defined(_MIPS_ISA_MIPS4) || \\\n    defined(__mips) || defined(__MIPS__)\n#define DUK_F_MIPS\n#if defined(__LP64__) || defined(_LP64) || defined(__mips64) || \\\n    defined(__mips64__) || defined(__mips_n64)\n#define DUK_F_MIPS64\n#else\n#define DUK_F_MIPS32\n#endif\n#endif\n\n/* SPARC */\n#if defined(sparc) || defined(__sparc) || defined(__sparc__)\n#define DUK_F_SPARC\n#if defined(__LP64__) || defined(_LP64)\n#define DUK_F_SPARC64\n#else\n#define DUK_F_SPARC32\n#endif\n#endif\n\n/* SuperH */\n#if defined(__sh__) || \\\n    defined(__sh1__) || defined(__SH1__) || \\\n    defined(__sh2__) || defined(__SH2__) || \\\n    defined(__sh3__) || defined(__SH3__) || \\\n    defined(__sh4__) || defined(__SH4__) || \\\n    defined(__sh5__) || defined(__SH5__)\n#define DUK_F_SUPERH\n#endif\n\n/* Clang */\n#if defined(__clang__)\n#define DUK_F_CLANG\n#endif\n\n/* C++ */\n#undef DUK_F_CPP\n#if defined(__cplusplus)\n#define DUK_F_CPP\n#endif\n\n/* C99 or above */\n#undef DUK_F_C99\n#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)\n#define DUK_F_C99\n#endif\n\n/* C++11 or above */\n#undef DUK_F_CPP11\n#if defined(__cplusplus) && (__cplusplus >= 201103L)\n#define DUK_F_CPP11\n#endif\n\n/* GCC.  Clang also defines __GNUC__ so don't detect GCC if using Clang. */\n#if defined(__GNUC__) && !defined(__clang__) && !defined(DUK_F_CLANG)\n#define DUK_F_GCC\n#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)\n/* Convenience, e.g. gcc 4.5.1 == 40501; http://stackoverflow.com/questions/6031819/emulating-gccs-builtin-unreachable */\n#define DUK_F_GCC_VERSION  (__GNUC__ * 10000L + __GNUC_MINOR__ * 100L + __GNUC_PATCHLEVEL__)\n#else\n#error cannot figure out gcc version\n#endif\n#endif\n\n/* MinGW.  Also GCC flags (DUK_F_GCC) are enabled now. */\n#if defined(__MINGW32__) || defined(__MINGW64__)\n#define DUK_F_MINGW\n#endif\n\n/* MSVC */\n#if defined(_MSC_VER)\n/* MSVC preprocessor defines: http://msdn.microsoft.com/en-us/library/b0084kay.aspx\n * _MSC_FULL_VER includes the build number, but it has at least two formats, see e.g.\n * BOOST_MSVC_FULL_VER in http://www.boost.org/doc/libs/1_52_0/boost/config/compiler/visualc.hpp\n */\n#define DUK_F_MSVC\n#if defined(_MSC_FULL_VER)\n#if (_MSC_FULL_VER > 100000000)\n#define DUK_F_MSVC_FULL_VER _MSC_FULL_VER\n#else\n#define DUK_F_MSCV_FULL_VER (_MSC_FULL_VER * 10)\n#endif\n#endif\n#endif  /* _MSC_VER */\n\n/* TinyC */\n#if defined(__TINYC__)\n/* http://bellard.org/tcc/tcc-doc.html#SEC9 */\n#define DUK_F_TINYC\n#endif\n\n/* VBCC */\n#if defined(__VBCC__)\n#define DUK_F_VBCC\n#endif\n\n/* Atari Mint */\n#if defined(__MINT__)\n#define DUK_F_MINT\n#endif\n\n/*\n *  Platform autodetection\n */\n\n/* Workaround for older C++ compilers before including <inttypes.h>,\n * see e.g.: https://sourceware.org/bugzilla/show_bug.cgi?id=15366\n */\n#if defined(__cplusplus) && !defined(__STDC_LIMIT_MACROS)\n#define __STDC_LIMIT_MACROS\n#endif\n#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS)\n#define __STDC_CONSTANT_MACROS\n#endif\n\n#if defined(DUK_F_APPLE)\n/* --- Mac OSX, iPhone, Darwin --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <TargetConditionals.h>\n#include <architecture/byte_order.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n/* http://stackoverflow.com/questions/5919996/how-to-detect-reliably-mac-os-x-ios-linux-windows-in-c-preprocessor */\n#if TARGET_IPHONE_SIMULATOR\n#define DUK_USE_OS_STRING \"iphone-sim\"\n#elif TARGET_OS_IPHONE\n#define DUK_USE_OS_STRING \"iphone\"\n#elif TARGET_OS_MAC\n#define DUK_USE_OS_STRING \"osx\"\n#else\n#define DUK_USE_OS_STRING \"osx-unknown\"\n#endif\n\n/* Use _setjmp() on Apple by default, see GH-55. */\n#define DUK_JMPBUF_TYPE       jmp_buf\n#define DUK_SETJMP(jb)        _setjmp((jb))\n#define DUK_LONGJMP(jb)       _longjmp((jb), 1)\n#elif defined(DUK_F_ORBIS)\n/* --- Orbis --- */\n/* Orbis = PS4 */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_S\n/* no parsing (not an error) */\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <machine/endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"orbis\"\n#elif defined(DUK_F_OPENBSD)\n/* --- OpenBSD --- */\n/* http://www.monkey.org/openbsd/archive/ports/0401/msg00089.html */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"openbsd\"\n#elif defined(DUK_F_BSD)\n/* --- Generic BSD --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"bsd\"\n#elif defined(DUK_F_TOS)\n/* --- Atari ST TOS --- */\n#define DUK_USE_DATE_NOW_TIME\n#define DUK_USE_DATE_TZO_GMTIME\n/* no parsing (not an error) */\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"tos\"\n\n/* TOS on M68K is always big endian. */\n#if !defined(DUK_USE_BYTEORDER) && defined(DUK_F_M68K)\n#define DUK_USE_BYTEORDER 3\n#endif\n#elif defined(DUK_F_AMIGAOS)\n/* --- AmigaOS --- */\n#if defined(DUK_F_M68K)\n/* AmigaOS on M68k */\n#define DUK_USE_DATE_NOW_TIME\n#define DUK_USE_DATE_TZO_GMTIME\n/* no parsing (not an error) */\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n#elif defined(DUK_F_PPC)\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n#if !defined(UINTPTR_MAX)\n#define UINTPTR_MAX UINT_MAX\n#endif\n#else\n#error AmigaOS but not M68K/PPC, not supported now\n#endif\n\n#define DUK_USE_OS_STRING \"amigaos\"\n\n/* AmigaOS on M68K or PPC is always big endian. */\n#if !defined(DUK_USE_BYTEORDER) && (defined(DUK_F_M68K) || defined(DUK_F_PPC))\n#define DUK_USE_BYTEORDER 3\n#endif\n#elif defined(DUK_F_DURANGO)\n/* --- Durango (XboxOne) --- */\n/* Durango = XboxOne\n * Configuration is nearly identical to Windows, except for\n * DUK_USE_DATE_TZO_WINDOWS.\n */\n\n/* Initial fix: disable secure CRT related warnings when compiling Duktape\n * itself (must be defined before including Windows headers).  Don't define\n * for user code including duktape.h.\n */\n#if defined(DUK_COMPILING_DUKTAPE) && !defined(_CRT_SECURE_NO_WARNINGS)\n#define _CRT_SECURE_NO_WARNINGS\n#endif\n\n/* MSVC does not have sys/param.h */\n#define DUK_USE_DATE_NOW_WINDOWS\n#define DUK_USE_DATE_TZO_WINDOWS_NO_DST\n/* Note: PRS and FMT are intentionally left undefined for now.  This means\n * there is no platform specific date parsing/formatting but there is still\n * the ISO 8601 standard format.\n */\n#if defined(DUK_COMPILING_DUKTAPE)\n/* Only include when compiling Duktape to avoid polluting application build\n * with a lot of unnecessary defines.\n */\n#include <windows.h>\n#endif\n\n#define DUK_USE_OS_STRING \"durango\"\n\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#elif defined(DUK_F_WINDOWS)\n/* --- Windows --- */\n/* Windows version can't obviously be determined at compile time,\n * but _WIN32_WINNT indicates the minimum version targeted:\n * - https://msdn.microsoft.com/en-us/library/6sehtctf.aspx\n */\n\n/* Initial fix: disable secure CRT related warnings when compiling Duktape\n * itself (must be defined before including Windows headers).  Don't define\n * for user code including duktape.h.\n */\n#if defined(DUK_COMPILING_DUKTAPE) && !defined(_CRT_SECURE_NO_WARNINGS)\n#define _CRT_SECURE_NO_WARNINGS\n#endif\n\n/* Windows 32-bit and 64-bit are currently the same. */\n/* MSVC does not have sys/param.h */\n\n#if defined(DUK_COMPILING_DUKTAPE)\n/* Only include when compiling Duktape to avoid polluting application build\n * with a lot of unnecessary defines.\n */\n#include <windows.h>\n#endif\n\n/* GetSystemTimePreciseAsFileTime() available from Windows 8:\n * https://msdn.microsoft.com/en-us/library/windows/desktop/hh706895(v=vs.85).aspx\n */\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS) || defined(DUK_USE_DATE_NOW_WINDOWS)\n/* User forced provider. */\n#else\n#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)\n#define DUK_USE_DATE_NOW_WINDOWS_SUBMS\n#else\n#define DUK_USE_DATE_NOW_WINDOWS\n#endif\n#endif\n\n#define DUK_USE_DATE_TZO_WINDOWS\n\n/* Note: PRS and FMT are intentionally left undefined for now.  This means\n * there is no platform specific date parsing/formatting but there is still\n * the ISO 8601 standard format.\n */\n\n/* QueryPerformanceCounter() may go backwards in Windows XP, so enable for\n * Vista and later: https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx#qpc_support_in_windows_versions\n */\n#if !defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC) && \\\n    defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)\n#define DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC\n#endif\n\n#define DUK_USE_OS_STRING \"windows\"\n\n/* On Windows, assume we're little endian.  Even Itanium which has a\n * configurable endianness runs little endian in Windows.\n */\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#elif defined(DUK_F_FLASHPLAYER)\n/* --- Flashplayer (Crossbridge) --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"flashplayer\"\n\n#if !defined(DUK_USE_BYTEORDER) && defined(DUK_F_FLASHPLAYER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#elif defined(DUK_F_QNX)\n/* --- QNX --- */\n#if defined(DUK_F_QNX) && defined(DUK_COMPILING_DUKTAPE)\n/* See: /opt/qnx650/target/qnx6/usr/include/sys/platform.h */\n#define _XOPEN_SOURCE    600\n#define _POSIX_C_SOURCE  200112L\n#endif\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"qnx\"\n#elif defined(DUK_F_TINSPIRE)\n/* --- TI-Nspire --- */\n#if defined(DUK_COMPILING_DUKTAPE) && !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"tinspire\"\n#elif defined(DUK_F_EMSCRIPTEN)\n/* --- Emscripten --- */\n#if defined(DUK_COMPILING_DUKTAPE)\n#if !defined(_POSIX_C_SOURCE)\n#define _POSIX_C_SOURCE  200809L\n#endif\n#if !defined(_GNU_SOURCE)\n#define _GNU_SOURCE      /* e.g. getdate_r */\n#endif\n#if !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n#endif  /* DUK_COMPILING_DUKTAPE */\n\n#include <sys/types.h>\n#if defined(DUK_F_BCC)\n/* no endian.h */\n#else\n#include <endian.h>\n#endif  /* DUK_F_BCC */\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n#include <stdint.h>\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#define DUK_USE_OS_STRING \"emscripten\"\n#elif defined(DUK_F_ANDROID)\n/* --- Android --- */\n#if defined(DUK_COMPILING_DUKTAPE)\n#if !defined(_POSIX_C_SOURCE)\n#define _POSIX_C_SOURCE  200809L\n#endif\n#if !defined(_GNU_SOURCE)\n#define _GNU_SOURCE      /* e.g. getdate_r */\n#endif\n#if !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n#endif  /* DUK_COMPILING_DUKTAPE */\n\n#include <sys/types.h>\n#if defined(DUK_F_BCC)\n/* no endian.h or stdint.h */\n#else\n#include <endian.h>\n#include <stdint.h>\n#endif  /* DUK_F_BCC */\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#if 0  /* XXX: safe condition? */\n#define DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME\n#endif\n\n#define DUK_USE_OS_STRING \"android\"\n#elif defined(DUK_F_LINUX)\n/* --- Linux --- */\n#if defined(DUK_COMPILING_DUKTAPE)\n#if !defined(_POSIX_C_SOURCE)\n#define _POSIX_C_SOURCE  200809L\n#endif\n#if !defined(_GNU_SOURCE)\n#define _GNU_SOURCE      /* e.g. getdate_r */\n#endif\n#if !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n#endif  /* DUK_COMPILING_DUKTAPE */\n\n#include <sys/types.h>\n#if defined(DUK_F_BCC)\n/* no endian.h or stdint.h */\n#else\n#include <endian.h>\n#include <stdint.h>\n#endif  /* DUK_F_BCC */\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#if 0  /* XXX: safe condition? */\n#define DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME\n#endif\n\n#define DUK_USE_OS_STRING \"linux\"\n#elif defined(DUK_F_SUN)\n/* --- Solaris --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#include <sys/types.h>\n#if defined(DUK_F_OLD_SOLARIS)\n/* Old Solaris with no endian.h, stdint.h */\n#define DUK_F_NO_STDINT_H\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#else  /* DUK_F_OLD_SOLARIS */\n#include <ast/endian.h>\n#endif  /* DUK_F_OLD_SOLARIS */\n\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"solaris\"\n#elif defined(DUK_F_AIX)\n/* --- AIX --- */\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"aix\"\n#elif defined(DUK_F_HPUX)\n/* --- HPUX --- */\n#define DUK_F_NO_STDINT_H\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"hpux\"\n#elif defined(DUK_F_POSIX)\n/* --- Generic POSIX --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"posix\"\n#elif defined(DUK_F_CYGWIN)\n/* --- Cygwin --- */\n/* don't use strptime() for now */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_JMPBUF_TYPE       jmp_buf\n#define DUK_SETJMP(jb)        _setjmp((jb))\n#define DUK_LONGJMP(jb)       _longjmp((jb), 1)\n\n#define DUK_USE_OS_STRING \"windows\"\n#elif defined(DUK_F_UNIX)\n/* --- Generic UNIX --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n#include <sys/time.h>\n#define DUK_USE_OS_STRING \"unknown\"\n#else\n/* --- Generic fallback --- */\n/* The most portable current time provider is time(), but it only has a\n * one second resolution.\n */\n#define DUK_USE_DATE_NOW_TIME\n\n/* The most portable way to figure out local time offset is gmtime(),\n * but it's not thread safe so use with caution.\n */\n#define DUK_USE_DATE_TZO_GMTIME\n\n/* Avoid custom date parsing and formatting for portability. */\n#undef DUK_USE_DATE_PRS_STRPTIME\n#undef DUK_USE_DATE_FMT_STRFTIME\n\n/* Rely on C89 headers only; time.h must be here. */\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"unknown\"\n#endif  /* autodetect platform */\n\n/* Shared includes: C89 */\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdarg.h>  /* varargs */\n#include <setjmp.h>\n#include <stddef.h>  /* e.g. ptrdiff_t */\n#include <math.h>\n#include <limits.h>\n\n/* date.h is omitted, and included per platform */\n\n/* Shared includes: stdint.h is C99 */\n#if defined(DUK_F_NO_STDINT_H)\n/* stdint.h not available */\n#else\n/* Technically C99 (C++11) but found in many systems.  On some systems\n * __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS must be defined before\n * including stdint.h (see above).\n */\n#include <stdint.h>\n#endif\n\n/* <exception> is only included if needed, based on DUK_USE_xxx flags. */\n\n/*\n *  Architecture autodetection\n */\n\n#if defined(DUK_F_X86)\n/* --- x86 --- */\n#define DUK_USE_ARCH_STRING \"x86\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n\n#define DUK_USE_PACKED_TVAL\n\n/* FreeBSD, -m32, and clang prior to 5.0 has union aliasing issues which\n * break duk_tval copying.  Disable packed duk_tval automatically.\n */\n#if defined(DUK_F_FREEBSD) && defined(DUK_F_X86) && \\\n    defined(__clang__) && defined(__clang_major__) && (__clang_major__ < 5)\n#undef DUK_USE_PACKED_TVAL\n#endif\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_X64)\n/* --- x64 --- */\n#define DUK_USE_ARCH_STRING \"x64\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_X32)\n/* --- x32 --- */\n#define DUK_USE_ARCH_STRING \"x32\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_ARM32)\n/* --- ARM 32-bit --- */\n#define DUK_USE_ARCH_STRING \"arm32\"\n/* Byte order varies, so rely on autodetect. */\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_ARM64)\n/* --- ARM 64-bit --- */\n#define DUK_USE_ARCH_STRING \"arm64\"\n/* Byte order varies, so rely on autodetect. */\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_MIPS32)\n/* --- MIPS 32-bit --- */\n#define DUK_USE_ARCH_STRING \"mips32\"\n/* MIPS byte order varies so rely on autodetection. */\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_MIPS64)\n/* --- MIPS 64-bit --- */\n#define DUK_USE_ARCH_STRING \"mips64\"\n/* MIPS byte order varies so rely on autodetection. */\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_PPC32)\n/* --- PowerPC 32-bit --- */\n#define DUK_USE_ARCH_STRING \"ppc32\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_PPC64)\n/* --- PowerPC 64-bit --- */\n#define DUK_USE_ARCH_STRING \"ppc64\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_SPARC32)\n/* --- SPARC 32-bit --- */\n#define DUK_USE_ARCH_STRING \"sparc32\"\n/* SPARC byte order varies so rely on autodetection. */\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_SPARC64)\n/* --- SPARC 64-bit --- */\n#define DUK_USE_ARCH_STRING \"sparc64\"\n/* SPARC byte order varies so rely on autodetection. */\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_SUPERH)\n/* --- SuperH --- */\n#define DUK_USE_ARCH_STRING \"sh\"\n/* Byte order varies, rely on autodetection. */\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_M68K)\n/* --- Motorola 68k --- */\n#define DUK_USE_ARCH_STRING \"m68k\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_EMSCRIPTEN)\n/* --- Emscripten --- */\n#define DUK_USE_ARCH_STRING \"emscripten\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#else\n/* --- Generic --- */\n/* These are necessary wild guesses. */\n#define DUK_USE_ARCH_STRING \"generic\"\n/* Rely on autodetection for byte order, alignment, and packed tval. */\n#endif  /* autodetect architecture */\n\n/*\n *  Compiler autodetection\n */\n\n#if defined(DUK_F_CLANG)\n/* --- Clang --- */\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n/* C99 / C++11 and above: rely on va_copy() which is required. */\n#define DUK_VA_COPY(dest,src) va_copy(dest,src)\n#else\n/* Clang: assume we have __va_copy() in non-C99 mode. */\n#define DUK_VA_COPY(dest,src) __va_copy(dest,src)\n#endif\n\n#define DUK_NORETURN(decl)  decl __attribute__((noreturn))\n\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unreachable)\n#define DUK_UNREACHABLE()  do { __builtin_unreachable(); } while (0)\n#endif\n#endif\n\n#define DUK_USE_BRANCH_HINTS\n#define DUK_LIKELY(x)    __builtin_expect((x), 1)\n#define DUK_UNLIKELY(x)  __builtin_expect((x), 0)\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unpredictable)\n#define DUK_UNPREDICTABLE(x)  __builtin_unpredictable((x))\n#endif\n#endif\n\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_NOINLINE        __attribute__((noinline))\n#define DUK_INLINE          inline\n#define DUK_ALWAYS_INLINE   inline __attribute__((always_inline))\n#endif\n\n/* DUK_HOT */\n/* DUK_COLD */\n\n#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS)\n/* MSVC dllexport/dllimport: appropriate __declspec depends on whether we're\n * compiling Duktape or the application.\n */\n#if defined(DUK_COMPILING_DUKTAPE)\n#define DUK_EXTERNAL_DECL  extern __declspec(dllexport)\n#define DUK_EXTERNAL       __declspec(dllexport)\n#else\n#define DUK_EXTERNAL_DECL  extern __declspec(dllimport)\n#define DUK_EXTERNAL       should_not_happen\n#endif\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#else\n#define DUK_INTERNAL_DECL  extern\n#define DUK_INTERNAL       /*empty*/\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n#else\n#define DUK_EXTERNAL_DECL  __attribute__ ((visibility(\"default\"))) extern\n#define DUK_EXTERNAL       __attribute__ ((visibility(\"default\")))\n#if defined(DUK_SINGLE_FILE)\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n/* Minimize warnings for unused internal functions with GCC >= 3.1.1 and\n * Clang.  Based on documentation it should suffice to have the attribute\n * in the declaration only, but in practice some warnings are generated unless\n * the attribute is also applied to the definition.\n */\n#define DUK_INTERNAL_DECL  static __attribute__ ((unused))\n#define DUK_INTERNAL       static __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#endif\n#else\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused)) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\")))\n#endif\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n#endif\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"clang\"\n#else\n#define DUK_USE_COMPILER_STRING \"clang\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#define DUK_USE_UNION_INITIALIZERS\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#undef DUK_USE_GCC_PRAGMAS\n#define DUK_USE_PACK_CLANG_ATTR\n\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_bswap64)\n#define DUK_BSWAP64(x) ((duk_uint64_t) __builtin_bswap64((duk_uint64_t) (x)))\n#endif\n#if __has_builtin(__builtin_bswap32)\n#define DUK_BSWAP32(x) ((duk_uint32_t) __builtin_bswap32((duk_uint32_t) (x)))\n#endif\n#if __has_builtin(__builtin_bswap16)\n#define DUK_BSWAP16(x) ((duk_uint16_t) __builtin_bswap16((duk_uint16_t) (x)))\n#endif\n#endif\n#elif defined(DUK_F_GCC)\n/* --- GCC --- */\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n/* C99 / C++11 and above: rely on va_copy() which is required. */\n#define DUK_VA_COPY(dest,src) va_copy(dest,src)\n#else\n/* GCC: assume we have __va_copy() in non-C99 mode. */\n#define DUK_VA_COPY(dest,src) __va_copy(dest,src)\n#endif\n\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 20500L) && (DUK_F_GCC_VERSION < 50000L)\n/* Since gcc-2.5.\n *\n * Disabled temporarily in GCC 5+ because of an unresolved noreturn-related\n * issue: https://github.com/svaarala/duktape/issues/2155.\n */\n#define DUK_NORETURN(decl)  decl __attribute__((noreturn))\n#endif\n\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L)\n/* Since gcc-4.5. */\n#define DUK_UNREACHABLE()  do { __builtin_unreachable(); } while (0)\n#endif\n\n#define DUK_USE_BRANCH_HINTS\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L)\n/* GCC: test not very accurate; enable only in relatively recent builds\n * because of bugs in gcc-4.4 (http://lists.debian.org/debian-gcc/2010/04/msg00000.html)\n */\n#define DUK_LIKELY(x)    __builtin_expect((x), 1)\n#define DUK_UNLIKELY(x)  __builtin_expect((x), 0)\n#endif\n/* XXX: equivalent of clang __builtin_unpredictable? */\n\n#if (defined(DUK_F_C99) || defined(DUK_F_CPP11)) && \\\n    defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 30101)\n#define DUK_NOINLINE        __attribute__((noinline))\n#define DUK_INLINE          inline\n#define DUK_ALWAYS_INLINE   inline __attribute__((always_inline))\n#endif\n\n#if (defined(DUK_F_C99) || defined(DUK_F_CPP11)) && \\\n    defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40300)\n#define DUK_HOT             __attribute__((hot))\n#define DUK_COLD            __attribute__((cold))\n#endif\n\n#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS)\n/* MSVC dllexport/dllimport: appropriate __declspec depends on whether we're\n * compiling Duktape or the application.\n */\n#if defined(DUK_COMPILING_DUKTAPE)\n#define DUK_EXTERNAL_DECL  extern __declspec(dllexport)\n#define DUK_EXTERNAL       __declspec(dllexport)\n#else\n#define DUK_EXTERNAL_DECL  extern __declspec(dllimport)\n#define DUK_EXTERNAL       should_not_happen\n#endif\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#else\n#define DUK_INTERNAL_DECL  extern\n#define DUK_INTERNAL       /*empty*/\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n#elif defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40000)\n#define DUK_EXTERNAL_DECL  __attribute__ ((visibility(\"default\"))) extern\n#define DUK_EXTERNAL       __attribute__ ((visibility(\"default\")))\n#if defined(DUK_SINGLE_FILE)\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n/* Minimize warnings for unused internal functions with GCC >= 3.1.1 and\n * Clang.  Based on documentation it should suffice to have the attribute\n * in the declaration only, but in practice some warnings are generated unless\n * the attribute is also applied to the definition.\n */\n#define DUK_INTERNAL_DECL  static __attribute__ ((unused))\n#define DUK_INTERNAL       static __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#endif\n#else\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused)) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\")))\n#endif\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n#endif\n\n#if defined(DUK_F_MINGW)\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"mingw++\"\n#else\n#define DUK_USE_COMPILER_STRING \"mingw\"\n#endif\n#else\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"g++\"\n#else\n#define DUK_USE_COMPILER_STRING \"gcc\"\n#endif\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || (defined(DUK_F_CPP11) && defined(__GNUC__))\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#define DUK_USE_UNION_INITIALIZERS\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40600)\n#define DUK_USE_GCC_PRAGMAS\n#else\n#undef DUK_USE_GCC_PRAGMAS\n#endif\n\n#define DUK_USE_PACK_GCC_ATTR\n\n/* Availability varies based on platform (between GCC 4.4 and 4.8), and there\n * are apparently some bugs in GCC 4.x.  Check for GCC 5.0 before enabling\n * these to be safe.\n */\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 50000L)\n#define DUK_BSWAP64(x) ((duk_uint64_t) __builtin_bswap64((duk_uint64_t) (x)))\n#define DUK_BSWAP32(x) ((duk_uint32_t) __builtin_bswap32((duk_uint32_t) (x)))\n#define DUK_BSWAP16(x) ((duk_uint16_t) __builtin_bswap16((duk_uint16_t) (x)))\n#endif\n#elif defined(DUK_F_MSVC)\n/* --- MSVC --- */\n/* http://msdn.microsoft.com/en-us/library/aa235362(VS.60).aspx */\n#define DUK_NORETURN(decl)  __declspec(noreturn) decl\n\n/* XXX: DUK_UNREACHABLE for msvc? */\n\n#undef DUK_USE_BRANCH_HINTS\n\n/* XXX: DUK_LIKELY, DUK_UNLIKELY for msvc? */\n/* XXX: DUK_NOINLINE, DUK_INLINE, DUK_ALWAYS_INLINE for msvc? */\n\n#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS)\n/* MSVC dllexport/dllimport: appropriate __declspec depends on whether we're\n * compiling Duktape or the application.\n */\n#if defined(DUK_COMPILING_DUKTAPE)\n#define DUK_EXTERNAL_DECL  extern __declspec(dllexport)\n#define DUK_EXTERNAL       __declspec(dllexport)\n#else\n#define DUK_EXTERNAL_DECL  extern __declspec(dllimport)\n#define DUK_EXTERNAL       should_not_happen\n#endif\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#else\n#define DUK_INTERNAL_DECL  extern\n#define DUK_INTERNAL       /*empty*/\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n#endif\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"msvc++\"\n#else\n#define DUK_USE_COMPILER_STRING \"msvc\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99)\n#define DUK_USE_VARIADIC_MACROS\n#elif defined(_MSC_VER) && (_MSC_VER >= 1400)\n/* VS2005+ should have variadic macros even when they're not C99. */\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#undef DUK_USE_UNION_INITIALIZERS\n#if defined(_MSC_VER) && (_MSC_VER >= 1800)\n/* VS2013+ supports union initializers but there's a bug involving union-inside-struct:\n * https://connect.microsoft.com/VisualStudio/feedback/details/805981\n * The bug was fixed (at least) in VS2015 so check for VS2015 for now:\n * https://blogs.msdn.microsoft.com/vcblog/2015/07/01/c-compiler-front-end-fixes-in-vs2015/\n * Manually tested using VS2013, CL reports 18.00.31101, so enable for VS2013 too.\n */\n#define DUK_USE_UNION_INITIALIZERS\n#endif\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#undef DUK_USE_GCC_PRAGMAS\n\n#define DUK_USE_PACK_MSVC_PRAGMA\n\n/* These have been tested from VS2008 onwards; may work in older VS versions\n * too but not enabled by default.\n */\n#if defined(_MSC_VER) && (_MSC_VER >= 1500)\n#define DUK_NOINLINE        __declspec(noinline)\n#define DUK_INLINE          __inline\n#define DUK_ALWAYS_INLINE   __forceinline\n#endif\n\n#if defined(_MSC_VER) && (_MSC_VER >= 1900)\n#define DUK_SNPRINTF     snprintf\n#define DUK_VSNPRINTF    vsnprintf\n#else\n/* (v)snprintf() is missing before MSVC 2015.  Note that _(v)snprintf() does\n * NOT NUL terminate on truncation, but Duktape code never assumes that.\n * http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010\n */\n#define DUK_SNPRINTF     _snprintf\n#define DUK_VSNPRINTF    _vsnprintf\n#endif\n\n/* Avoid warning when doing DUK_UNREF(some_function). */\n#if defined(_MSC_VER) && (_MSC_VER < 1500)\n#pragma warning(disable: 4100 4101 4550 4551)\n#define DUK_UNREF(x)\n#else\n#define DUK_UNREF(x)  do { __pragma(warning(suppress:4100 4101 4550 4551)) (x); } while (0)\n#endif\n\n/* Older versions of MSVC don't support the LL/ULL suffix. */\n#define DUK_U64_CONSTANT(x) x##ui64\n#define DUK_I64_CONSTANT(x) x##i64\n#elif defined(DUK_F_EMSCRIPTEN)\n/* --- Emscripten --- */\n#define DUK_NORETURN(decl)  decl __attribute__((noreturn))\n\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unreachable)\n#define DUK_UNREACHABLE()  do { __builtin_unreachable(); } while (0)\n#endif\n#endif\n\n#define DUK_USE_BRANCH_HINTS\n#define DUK_LIKELY(x)    __builtin_expect((x), 1)\n#define DUK_UNLIKELY(x)  __builtin_expect((x), 0)\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unpredictable)\n#define DUK_UNPREDICTABLE(x)  __builtin_unpredictable((x))\n#endif\n#endif\n\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_NOINLINE        __attribute__((noinline))\n#define DUK_INLINE          inline\n#define DUK_ALWAYS_INLINE   inline __attribute__((always_inline))\n#endif\n\n#define DUK_EXTERNAL_DECL  __attribute__ ((visibility(\"default\"))) extern\n#define DUK_EXTERNAL       __attribute__ ((visibility(\"default\")))\n#if defined(DUK_SINGLE_FILE)\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n/* Minimize warnings for unused internal functions with GCC >= 3.1.1 and\n * Clang.  Based on documentation it should suffice to have the attribute\n * in the declaration only, but in practice some warnings are generated unless\n * the attribute is also applied to the definition.\n */\n#define DUK_INTERNAL_DECL  static __attribute__ ((unused))\n#define DUK_INTERNAL       static __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#endif\n#else\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused)) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\")))\n#endif\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n\n#define DUK_USE_COMPILER_STRING \"emscripten\"\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#define DUK_USE_UNION_INITIALIZERS\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#undef DUK_USE_GCC_PRAGMAS\n#define DUK_USE_PACK_CLANG_ATTR\n#elif defined(DUK_F_TINYC)\n/* --- TinyC --- */\n#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"tinyc++\"\n#else\n#define DUK_USE_COMPILER_STRING \"tinyc\"\n#endif\n\n/* http://bellard.org/tcc/tcc-doc.html#SEC7 */\n#define DUK_USE_VARIADIC_MACROS\n\n#define DUK_USE_UNION_INITIALIZERS\n\n/* Most portable, wastes space */\n#define DUK_USE_FLEX_ONESIZE\n\n/* Most portable, potentially wastes space */\n#define DUK_USE_PACK_DUMMY_MEMBER\n#elif defined(DUK_F_VBCC)\n/* --- VBCC --- */\n#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"vbcc-c++\"\n#else\n#define DUK_USE_COMPILER_STRING \"vbcc\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n/* VBCC supports C99 so check only for C99 for union initializer support.\n * Designated union initializers would possibly work even without a C99 check.\n */\n#undef DUK_USE_UNION_INITIALIZERS\n#if defined(DUK_F_C99)\n#define DUK_USE_UNION_INITIALIZERS\n#endif\n\n#define DUK_USE_FLEX_ZEROSIZE\n#define DUK_USE_PACK_DUMMY_MEMBER\n#elif defined(DUK_F_BCC)\n/* --- Bruce's C compiler --- */\n#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"bcc++\"\n#else\n#define DUK_USE_COMPILER_STRING \"bcc\"\n#endif\n\n/* Most portable */\n#undef DUK_USE_VARIADIC_MACROS\n\n/* Most portable, wastes space */\n#undef DUK_USE_UNION_INITIALIZERS\n\n/* Most portable, wastes space */\n#define DUK_USE_FLEX_ONESIZE\n\n/* Most portable, potentially wastes space */\n#define DUK_USE_PACK_DUMMY_MEMBER\n\n/* BCC, assume we're on x86. */\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#else\n/* --- Generic --- */\n#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"generic-c++\"\n#else\n#define DUK_USE_COMPILER_STRING \"generic\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n/* C++ doesn't have standard designated union initializers ({ .foo = 1 }). */\n#undef DUK_USE_UNION_INITIALIZERS\n#if defined(DUK_F_C99)\n#define DUK_USE_UNION_INITIALIZERS\n#endif\n\n/* Most portable, wastes space */\n#define DUK_USE_FLEX_ONESIZE\n\n/* Most portable, potentially wastes space */\n#define DUK_USE_PACK_DUMMY_MEMBER\n#endif  /* autodetect compiler */\n\n/* uclibc */\n#if defined(__UCLIBC__)\n#define DUK_F_UCLIBC\n#endif\n\n/*\n *  Wrapper typedefs and constants for integer types, also sanity check types.\n *\n *  C99 typedefs are quite good but not always available, and we want to avoid\n *  forcibly redefining the C99 typedefs.  So, there are Duktape wrappers for\n *  all C99 typedefs and Duktape code should only use these typedefs.  Type\n *  detection when C99 is not supported is best effort and may end up detecting\n *  some types incorrectly.\n *\n *  Pointer sizes are a portability problem: pointers to different types may\n *  have a different size and function pointers are very difficult to manage\n *  portably.\n *\n *  http://en.wikipedia.org/wiki/C_data_types#Fixed-width_integer_types\n *\n *  Note: there's an interesting corner case when trying to define minimum\n *  signed integer value constants which leads to the current workaround of\n *  defining e.g. -0x80000000 as (-0x7fffffffL - 1L).  See doc/code-issues.txt\n *  for a longer discussion.\n *\n *  Note: avoid typecasts and computations in macro integer constants as they\n *  can then no longer be used in macro relational expressions (such as\n *  #if DUK_SIZE_MAX < 0xffffffffUL).  There is internal code which relies on\n *  being able to compare DUK_SIZE_MAX against a limit.\n */\n\n/* XXX: add feature options to force basic types from outside? */\n\n#if !defined(INT_MAX)\n#error INT_MAX not defined\n#endif\n\n/* Check that architecture is two's complement, standard C allows e.g.\n * INT_MIN to be -2**31+1 (instead of -2**31).\n */\n#if defined(INT_MAX) && defined(INT_MIN)\n#if INT_MAX != -(INT_MIN + 1)\n#error platform does not seem complement of two\n#endif\n#else\n#error cannot check complement of two\n#endif\n\n/* Pointer size determination based on __WORDSIZE or architecture when\n * that's not available.\n */\n#if defined(DUK_F_X86) || defined(DUK_F_X32) || \\\n    defined(DUK_F_M68K) || defined(DUK_F_PPC32) || \\\n    defined(DUK_F_BCC) || \\\n    (defined(__WORDSIZE) && (__WORDSIZE == 32)) || \\\n    ((defined(DUK_F_OLD_SOLARIS) || defined(DUK_F_AIX) || \\\n      defined(DUK_F_HPUX)) && defined(_ILP32)) || \\\n    defined(DUK_F_ARM32)\n#define DUK_F_32BIT_PTRS\n#elif defined(DUK_F_X64) || \\\n      (defined(__WORDSIZE) && (__WORDSIZE == 64)) || \\\n   ((defined(DUK_F_OLD_SOLARIS) || defined(DUK_F_AIX) || \\\n     defined(DUK_F_HPUX)) && defined(_LP64)) || \\\n    defined(DUK_F_ARM64)\n#define DUK_F_64BIT_PTRS\n#else\n/* not sure, not needed with C99 anyway */\n#endif\n\n/* Intermediate define for 'have inttypes.h' */\n#undef DUK_F_HAVE_INTTYPES\n#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \\\n    !(defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC))\n/* vbcc + AmigaOS has C99 but no inttypes.h */\n#define DUK_F_HAVE_INTTYPES\n#elif defined(__cplusplus) && (__cplusplus >= 201103L)\n/* C++11 apparently ratified stdint.h */\n#define DUK_F_HAVE_INTTYPES\n#endif\n\n/* Basic integer typedefs and limits, preferably from inttypes.h, otherwise\n * through automatic detection.\n */\n#if defined(DUK_F_HAVE_INTTYPES)\n/* C99 or compatible */\n\n#define DUK_F_HAVE_64BIT\n#include <inttypes.h>\n\ntypedef uint8_t duk_uint8_t;\ntypedef int8_t duk_int8_t;\ntypedef uint16_t duk_uint16_t;\ntypedef int16_t duk_int16_t;\ntypedef uint32_t duk_uint32_t;\ntypedef int32_t duk_int32_t;\ntypedef uint64_t duk_uint64_t;\ntypedef int64_t duk_int64_t;\ntypedef uint_least8_t duk_uint_least8_t;\ntypedef int_least8_t duk_int_least8_t;\ntypedef uint_least16_t duk_uint_least16_t;\ntypedef int_least16_t duk_int_least16_t;\ntypedef uint_least32_t duk_uint_least32_t;\ntypedef int_least32_t duk_int_least32_t;\ntypedef uint_least64_t duk_uint_least64_t;\ntypedef int_least64_t duk_int_least64_t;\ntypedef uint_fast8_t duk_uint_fast8_t;\ntypedef int_fast8_t duk_int_fast8_t;\ntypedef uint_fast16_t duk_uint_fast16_t;\ntypedef int_fast16_t duk_int_fast16_t;\ntypedef uint_fast32_t duk_uint_fast32_t;\ntypedef int_fast32_t duk_int_fast32_t;\ntypedef uint_fast64_t duk_uint_fast64_t;\ntypedef int_fast64_t duk_int_fast64_t;\ntypedef uintptr_t duk_uintptr_t;\ntypedef intptr_t duk_intptr_t;\ntypedef uintmax_t duk_uintmax_t;\ntypedef intmax_t duk_intmax_t;\n\n#define DUK_UINT8_MIN         0\n#define DUK_UINT8_MAX         UINT8_MAX\n#define DUK_INT8_MIN          INT8_MIN\n#define DUK_INT8_MAX          INT8_MAX\n#define DUK_UINT_LEAST8_MIN   0\n#define DUK_UINT_LEAST8_MAX   UINT_LEAST8_MAX\n#define DUK_INT_LEAST8_MIN    INT_LEAST8_MIN\n#define DUK_INT_LEAST8_MAX    INT_LEAST8_MAX\n#define DUK_UINT_FAST8_MIN    0\n#define DUK_UINT_FAST8_MAX    UINT_FAST8_MAX\n#define DUK_INT_FAST8_MIN     INT_FAST8_MIN\n#define DUK_INT_FAST8_MAX     INT_FAST8_MAX\n#define DUK_UINT16_MIN        0\n#define DUK_UINT16_MAX        UINT16_MAX\n#define DUK_INT16_MIN         INT16_MIN\n#define DUK_INT16_MAX         INT16_MAX\n#define DUK_UINT_LEAST16_MIN  0\n#define DUK_UINT_LEAST16_MAX  UINT_LEAST16_MAX\n#define DUK_INT_LEAST16_MIN   INT_LEAST16_MIN\n#define DUK_INT_LEAST16_MAX   INT_LEAST16_MAX\n#define DUK_UINT_FAST16_MIN   0\n#define DUK_UINT_FAST16_MAX   UINT_FAST16_MAX\n#define DUK_INT_FAST16_MIN    INT_FAST16_MIN\n#define DUK_INT_FAST16_MAX    INT_FAST16_MAX\n#define DUK_UINT32_MIN        0\n#define DUK_UINT32_MAX        UINT32_MAX\n#define DUK_INT32_MIN         INT32_MIN\n#define DUK_INT32_MAX         INT32_MAX\n#define DUK_UINT_LEAST32_MIN  0\n#define DUK_UINT_LEAST32_MAX  UINT_LEAST32_MAX\n#define DUK_INT_LEAST32_MIN   INT_LEAST32_MIN\n#define DUK_INT_LEAST32_MAX   INT_LEAST32_MAX\n#define DUK_UINT_FAST32_MIN   0\n#define DUK_UINT_FAST32_MAX   UINT_FAST32_MAX\n#define DUK_INT_FAST32_MIN    INT_FAST32_MIN\n#define DUK_INT_FAST32_MAX    INT_FAST32_MAX\n#define DUK_UINT64_MIN        0\n#define DUK_UINT64_MAX        UINT64_MAX\n#define DUK_INT64_MIN         INT64_MIN\n#define DUK_INT64_MAX         INT64_MAX\n#define DUK_UINT_LEAST64_MIN  0\n#define DUK_UINT_LEAST64_MAX  UINT_LEAST64_MAX\n#define DUK_INT_LEAST64_MIN   INT_LEAST64_MIN\n#define DUK_INT_LEAST64_MAX   INT_LEAST64_MAX\n#define DUK_UINT_FAST64_MIN   0\n#define DUK_UINT_FAST64_MAX   UINT_FAST64_MAX\n#define DUK_INT_FAST64_MIN    INT_FAST64_MIN\n#define DUK_INT_FAST64_MAX    INT_FAST64_MAX\n\n#define DUK_UINTPTR_MIN       0\n#define DUK_UINTPTR_MAX       UINTPTR_MAX\n#define DUK_INTPTR_MIN        INTPTR_MIN\n#define DUK_INTPTR_MAX        INTPTR_MAX\n\n#define DUK_UINTMAX_MIN       0\n#define DUK_UINTMAX_MAX       UINTMAX_MAX\n#define DUK_INTMAX_MIN        INTMAX_MIN\n#define DUK_INTMAX_MAX        INTMAX_MAX\n\n#define DUK_SIZE_MIN          0\n#define DUK_SIZE_MAX          SIZE_MAX\n#undef DUK_SIZE_MAX_COMPUTED\n\n#else  /* C99 types */\n\n/* When C99 types are not available, we use heuristic detection to get\n * the basic 8, 16, 32, and (possibly) 64 bit types.  The fast/least\n * types are then assumed to be exactly the same for now: these could\n * be improved per platform but C99 types are very often now available.\n * 64-bit types are not available on all platforms; this is OK at least\n * on 32-bit platforms.\n *\n * This detection code is necessarily a bit hacky and can provide typedefs\n * and defines that won't work correctly on some exotic platform.\n */\n\n#if (defined(CHAR_BIT) && (CHAR_BIT == 8)) || \\\n    (defined(UCHAR_MAX) && (UCHAR_MAX == 255))\ntypedef unsigned char duk_uint8_t;\ntypedef signed char duk_int8_t;\n#else\n#error cannot detect 8-bit type\n#endif\n\n#if defined(USHRT_MAX) && (USHRT_MAX == 65535UL)\ntypedef unsigned short duk_uint16_t;\ntypedef signed short duk_int16_t;\n#elif defined(UINT_MAX) && (UINT_MAX == 65535UL)\n/* On some platforms int is 16-bit but long is 32-bit (e.g. PureC) */\ntypedef unsigned int duk_uint16_t;\ntypedef signed int duk_int16_t;\n#else\n#error cannot detect 16-bit type\n#endif\n\n#if defined(UINT_MAX) && (UINT_MAX == 4294967295UL)\ntypedef unsigned int duk_uint32_t;\ntypedef signed int duk_int32_t;\n#elif defined(ULONG_MAX) && (ULONG_MAX == 4294967295UL)\n/* On some platforms int is 16-bit but long is 32-bit (e.g. PureC) */\ntypedef unsigned long duk_uint32_t;\ntypedef signed long duk_int32_t;\n#else\n#error cannot detect 32-bit type\n#endif\n\n/* 64-bit type detection is a bit tricky.\n *\n * ULLONG_MAX is a standard define.  __LONG_LONG_MAX__ and __ULONG_LONG_MAX__\n * are used by at least GCC (even if system headers don't provide ULLONG_MAX).\n * Some GCC variants may provide __LONG_LONG_MAX__ but not __ULONG_LONG_MAX__.\n *\n * ULL / LL constants are rejected / warned about by some compilers, even if\n * the compiler has a 64-bit type and the compiler/system headers provide an\n * unsupported constant (ULL/LL)!  Try to avoid using ULL / LL constants.\n * As a side effect we can only check that e.g. ULONG_MAX is larger than 32\n * bits but can't be sure it is exactly 64 bits.  Self tests will catch such\n * cases.\n */\n#undef DUK_F_HAVE_64BIT\n#if !defined(DUK_F_HAVE_64BIT) && defined(ULONG_MAX)\n#if (ULONG_MAX > 4294967295UL)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long duk_uint64_t;\ntypedef signed long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(ULLONG_MAX)\n#if (ULLONG_MAX > 4294967295UL)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long long duk_uint64_t;\ntypedef signed long long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(__ULONG_LONG_MAX__)\n#if (__ULONG_LONG_MAX__ > 4294967295UL)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long long duk_uint64_t;\ntypedef signed long long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(__LONG_LONG_MAX__)\n#if (__LONG_LONG_MAX__ > 2147483647L)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long long duk_uint64_t;\ntypedef signed long long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(DUK_F_MINGW)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long duk_uint64_t;\ntypedef signed long duk_int64_t;\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(DUK_F_MSVC)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned __int64 duk_uint64_t;\ntypedef signed __int64 duk_int64_t;\n#endif\n#if !defined(DUK_F_HAVE_64BIT)\n/* cannot detect 64-bit type, not always needed so don't error */\n#endif\n\ntypedef duk_uint8_t duk_uint_least8_t;\ntypedef duk_int8_t duk_int_least8_t;\ntypedef duk_uint16_t duk_uint_least16_t;\ntypedef duk_int16_t duk_int_least16_t;\ntypedef duk_uint32_t duk_uint_least32_t;\ntypedef duk_int32_t duk_int_least32_t;\ntypedef duk_uint8_t duk_uint_fast8_t;\ntypedef duk_int8_t duk_int_fast8_t;\ntypedef duk_uint16_t duk_uint_fast16_t;\ntypedef duk_int16_t duk_int_fast16_t;\ntypedef duk_uint32_t duk_uint_fast32_t;\ntypedef duk_int32_t duk_int_fast32_t;\n#if defined(DUK_F_HAVE_64BIT)\ntypedef duk_uint64_t duk_uint_least64_t;\ntypedef duk_int64_t duk_int_least64_t;\ntypedef duk_uint64_t duk_uint_fast64_t;\ntypedef duk_int64_t duk_int_fast64_t;\n#endif\n#if defined(DUK_F_HAVE_64BIT)\ntypedef duk_uint64_t duk_uintmax_t;\ntypedef duk_int64_t duk_intmax_t;\n#else\ntypedef duk_uint32_t duk_uintmax_t;\ntypedef duk_int32_t duk_intmax_t;\n#endif\n\n/* Note: the funny looking computations for signed minimum 16-bit, 32-bit, and\n * 64-bit values are intentional as the obvious forms (e.g. -0x80000000L) are\n * -not- portable.  See code-issues.txt for a detailed discussion.\n */\n#define DUK_UINT8_MIN         0UL\n#define DUK_UINT8_MAX         0xffUL\n#define DUK_INT8_MIN          (-0x80L)\n#define DUK_INT8_MAX          0x7fL\n#define DUK_UINT_LEAST8_MIN   0UL\n#define DUK_UINT_LEAST8_MAX   0xffUL\n#define DUK_INT_LEAST8_MIN    (-0x80L)\n#define DUK_INT_LEAST8_MAX    0x7fL\n#define DUK_UINT_FAST8_MIN    0UL\n#define DUK_UINT_FAST8_MAX    0xffUL\n#define DUK_INT_FAST8_MIN     (-0x80L)\n#define DUK_INT_FAST8_MAX     0x7fL\n#define DUK_UINT16_MIN        0UL\n#define DUK_UINT16_MAX        0xffffUL\n#define DUK_INT16_MIN         (-0x7fffL - 1L)\n#define DUK_INT16_MAX         0x7fffL\n#define DUK_UINT_LEAST16_MIN  0UL\n#define DUK_UINT_LEAST16_MAX  0xffffUL\n#define DUK_INT_LEAST16_MIN   (-0x7fffL - 1L)\n#define DUK_INT_LEAST16_MAX   0x7fffL\n#define DUK_UINT_FAST16_MIN   0UL\n#define DUK_UINT_FAST16_MAX   0xffffUL\n#define DUK_INT_FAST16_MIN    (-0x7fffL - 1L)\n#define DUK_INT_FAST16_MAX    0x7fffL\n#define DUK_UINT32_MIN        0UL\n#define DUK_UINT32_MAX        0xffffffffUL\n#define DUK_INT32_MIN         (-0x7fffffffL - 1L)\n#define DUK_INT32_MAX         0x7fffffffL\n#define DUK_UINT_LEAST32_MIN  0UL\n#define DUK_UINT_LEAST32_MAX  0xffffffffUL\n#define DUK_INT_LEAST32_MIN   (-0x7fffffffL - 1L)\n#define DUK_INT_LEAST32_MAX   0x7fffffffL\n#define DUK_UINT_FAST32_MIN   0UL\n#define DUK_UINT_FAST32_MAX   0xffffffffUL\n#define DUK_INT_FAST32_MIN    (-0x7fffffffL - 1L)\n#define DUK_INT_FAST32_MAX    0x7fffffffL\n\n/* 64-bit constants.  Since LL / ULL constants are not always available,\n * use computed values.  These values can't be used in preprocessor\n * comparisons; flag them as such.\n */\n#if defined(DUK_F_HAVE_64BIT)\n#define DUK_UINT64_MIN        ((duk_uint64_t) 0)\n#define DUK_UINT64_MAX        ((duk_uint64_t) -1)\n#define DUK_INT64_MIN         ((duk_int64_t) (~(DUK_UINT64_MAX >> 1)))\n#define DUK_INT64_MAX         ((duk_int64_t) (DUK_UINT64_MAX >> 1))\n#define DUK_UINT_LEAST64_MIN  DUK_UINT64_MIN\n#define DUK_UINT_LEAST64_MAX  DUK_UINT64_MAX\n#define DUK_INT_LEAST64_MIN   DUK_INT64_MIN\n#define DUK_INT_LEAST64_MAX   DUK_INT64_MAX\n#define DUK_UINT_FAST64_MIN   DUK_UINT64_MIN\n#define DUK_UINT_FAST64_MAX   DUK_UINT64_MAX\n#define DUK_INT_FAST64_MIN    DUK_INT64_MIN\n#define DUK_INT_FAST64_MAX    DUK_INT64_MAX\n#define DUK_UINT64_MIN_COMPUTED\n#define DUK_UINT64_MAX_COMPUTED\n#define DUK_INT64_MIN_COMPUTED\n#define DUK_INT64_MAX_COMPUTED\n#define DUK_UINT_LEAST64_MIN_COMPUTED\n#define DUK_UINT_LEAST64_MAX_COMPUTED\n#define DUK_INT_LEAST64_MIN_COMPUTED\n#define DUK_INT_LEAST64_MAX_COMPUTED\n#define DUK_UINT_FAST64_MIN_COMPUTED\n#define DUK_UINT_FAST64_MAX_COMPUTED\n#define DUK_INT_FAST64_MIN_COMPUTED\n#define DUK_INT_FAST64_MAX_COMPUTED\n#endif\n\n#if defined(DUK_F_HAVE_64BIT)\n#define DUK_UINTMAX_MIN       DUK_UINT64_MIN\n#define DUK_UINTMAX_MAX       DUK_UINT64_MAX\n#define DUK_INTMAX_MIN        DUK_INT64_MIN\n#define DUK_INTMAX_MAX        DUK_INT64_MAX\n#define DUK_UINTMAX_MIN_COMPUTED\n#define DUK_UINTMAX_MAX_COMPUTED\n#define DUK_INTMAX_MIN_COMPUTED\n#define DUK_INTMAX_MAX_COMPUTED\n#else\n#define DUK_UINTMAX_MIN       0UL\n#define DUK_UINTMAX_MAX       0xffffffffUL\n#define DUK_INTMAX_MIN        (-0x7fffffffL - 1L)\n#define DUK_INTMAX_MAX        0x7fffffffL\n#endif\n\n/* This detection is not very reliable. */\n#if defined(DUK_F_32BIT_PTRS)\ntypedef duk_int32_t duk_intptr_t;\ntypedef duk_uint32_t duk_uintptr_t;\n#define DUK_UINTPTR_MIN       DUK_UINT32_MIN\n#define DUK_UINTPTR_MAX       DUK_UINT32_MAX\n#define DUK_INTPTR_MIN        DUK_INT32_MIN\n#define DUK_INTPTR_MAX        DUK_INT32_MAX\n#elif defined(DUK_F_64BIT_PTRS) && defined(DUK_F_HAVE_64BIT)\ntypedef duk_int64_t duk_intptr_t;\ntypedef duk_uint64_t duk_uintptr_t;\n#define DUK_UINTPTR_MIN       DUK_UINT64_MIN\n#define DUK_UINTPTR_MAX       DUK_UINT64_MAX\n#define DUK_INTPTR_MIN        DUK_INT64_MIN\n#define DUK_INTPTR_MAX        DUK_INT64_MAX\n#define DUK_UINTPTR_MIN_COMPUTED\n#define DUK_UINTPTR_MAX_COMPUTED\n#define DUK_INTPTR_MIN_COMPUTED\n#define DUK_INTPTR_MAX_COMPUTED\n#else\n#error cannot determine intptr type\n#endif\n\n/* SIZE_MAX may be missing so use an approximate value for it. */\n#undef DUK_SIZE_MAX_COMPUTED\n#if !defined(SIZE_MAX)\n#define DUK_SIZE_MAX_COMPUTED\n#define SIZE_MAX              ((size_t) (-1))\n#endif\n#define DUK_SIZE_MIN          0\n#define DUK_SIZE_MAX          SIZE_MAX\n\n#endif  /* C99 types */\n\n/* A few types are assumed to always exist. */\ntypedef size_t duk_size_t;\ntypedef ptrdiff_t duk_ptrdiff_t;\n\n/* The best type for an \"all around int\" in Duktape internals is \"at least\n * 32 bit signed integer\" which is most convenient.  Same for unsigned type.\n * Prefer 'int' when large enough, as it is almost always a convenient type.\n */\n#if defined(UINT_MAX) && (UINT_MAX >= 0xffffffffUL)\ntypedef int duk_int_t;\ntypedef unsigned int duk_uint_t;\n#define DUK_INT_MIN           INT_MIN\n#define DUK_INT_MAX           INT_MAX\n#define DUK_UINT_MIN          0\n#define DUK_UINT_MAX          UINT_MAX\n#else\ntypedef duk_int_fast32_t duk_int_t;\ntypedef duk_uint_fast32_t duk_uint_t;\n#define DUK_INT_MIN           DUK_INT_FAST32_MIN\n#define DUK_INT_MAX           DUK_INT_FAST32_MAX\n#define DUK_UINT_MIN          DUK_UINT_FAST32_MIN\n#define DUK_UINT_MAX          DUK_UINT_FAST32_MAX\n#endif\n\n/* Same as 'duk_int_t' but guaranteed to be a 'fast' variant if this\n * distinction matters for the CPU.  These types are used mainly in the\n * executor where it might really matter.\n */\ntypedef duk_int_fast32_t duk_int_fast_t;\ntypedef duk_uint_fast32_t duk_uint_fast_t;\n#define DUK_INT_FAST_MIN      DUK_INT_FAST32_MIN\n#define DUK_INT_FAST_MAX      DUK_INT_FAST32_MAX\n#define DUK_UINT_FAST_MIN     DUK_UINT_FAST32_MIN\n#define DUK_UINT_FAST_MAX     DUK_UINT_FAST32_MAX\n\n/* Small integers (16 bits or more) can fall back to the 'int' type, but\n * have a typedef so they are marked \"small\" explicitly.\n */\ntypedef int duk_small_int_t;\ntypedef unsigned int duk_small_uint_t;\n#define DUK_SMALL_INT_MIN     INT_MIN\n#define DUK_SMALL_INT_MAX     INT_MAX\n#define DUK_SMALL_UINT_MIN    0\n#define DUK_SMALL_UINT_MAX    UINT_MAX\n\n/* Fast variants of small integers, again for really fast paths like the\n * executor.\n */\ntypedef duk_int_fast16_t duk_small_int_fast_t;\ntypedef duk_uint_fast16_t duk_small_uint_fast_t;\n#define DUK_SMALL_INT_FAST_MIN    DUK_INT_FAST16_MIN\n#define DUK_SMALL_INT_FAST_MAX    DUK_INT_FAST16_MAX\n#define DUK_SMALL_UINT_FAST_MIN   DUK_UINT_FAST16_MIN\n#define DUK_SMALL_UINT_FAST_MAX   DUK_UINT_FAST16_MAX\n\n/* Boolean values are represented with the platform 'unsigned int'. */\ntypedef duk_small_uint_t duk_bool_t;\n#define DUK_BOOL_MIN              DUK_SMALL_UINT_MIN\n#define DUK_BOOL_MAX              DUK_SMALL_UINT_MAX\n\n/* Index values must have at least 32-bit signed range. */\ntypedef duk_int_t duk_idx_t;\n#define DUK_IDX_MIN               DUK_INT_MIN\n#define DUK_IDX_MAX               DUK_INT_MAX\n\n/* Unsigned index variant. */\ntypedef duk_uint_t duk_uidx_t;\n#define DUK_UIDX_MIN              DUK_UINT_MIN\n#define DUK_UIDX_MAX              DUK_UINT_MAX\n\n/* Array index values, could be exact 32 bits.\n * Currently no need for signed duk_arridx_t.\n */\ntypedef duk_uint_t duk_uarridx_t;\n#define DUK_UARRIDX_MIN           DUK_UINT_MIN\n#define DUK_UARRIDX_MAX           DUK_UINT_MAX\n\n/* Duktape/C function return value, platform int is enough for now to\n * represent 0, 1, or negative error code.  Must be compatible with\n * assigning truth values (e.g. duk_ret_t rc = (foo == bar);).\n */\ntypedef duk_small_int_t duk_ret_t;\n#define DUK_RET_MIN               DUK_SMALL_INT_MIN\n#define DUK_RET_MAX               DUK_SMALL_INT_MAX\n\n/* Error codes are represented with platform int.  High bits are used\n * for flags and such, so 32 bits are needed.\n */\ntypedef duk_int_t duk_errcode_t;\n#define DUK_ERRCODE_MIN           DUK_INT_MIN\n#define DUK_ERRCODE_MAX           DUK_INT_MAX\n\n/* Codepoint type.  Must be 32 bits or more because it is used also for\n * internal codepoints.  The type is signed because negative codepoints\n * are used as internal markers (e.g. to mark EOF or missing argument).\n * (X)UTF-8/CESU-8 encode/decode take and return an unsigned variant to\n * ensure duk_uint32_t casts back and forth nicely.  Almost everything\n * else uses the signed one.\n */\ntypedef duk_int_t duk_codepoint_t;\ntypedef duk_uint_t duk_ucodepoint_t;\n#define DUK_CODEPOINT_MIN         DUK_INT_MIN\n#define DUK_CODEPOINT_MAX         DUK_INT_MAX\n#define DUK_UCODEPOINT_MIN        DUK_UINT_MIN\n#define DUK_UCODEPOINT_MAX        DUK_UINT_MAX\n\n/* IEEE float/double typedef. */\ntypedef float duk_float_t;\ntypedef double duk_double_t;\n\n/* We're generally assuming that we're working on a platform with a 32-bit\n * address space.  If DUK_SIZE_MAX is a typecast value (which is necessary\n * if SIZE_MAX is missing), the check must be avoided because the\n * preprocessor can't do a comparison.\n */\n#if !defined(DUK_SIZE_MAX)\n#error DUK_SIZE_MAX is undefined, probably missing SIZE_MAX\n#elif !defined(DUK_SIZE_MAX_COMPUTED)\n#if DUK_SIZE_MAX < 0xffffffffUL\n/* On some systems SIZE_MAX can be smaller than max unsigned 32-bit value\n * which seems incorrect if size_t is (at least) an unsigned 32-bit type.\n * However, it doesn't seem useful to error out compilation if this is the\n * case.\n */\n#endif\n#endif\n\n/* Type used in public API declarations and user code.  Typedef maps to\n * 'struct duk_hthread' like the 'duk_hthread' typedef which is used\n * exclusively in internals.\n */\ntypedef struct duk_hthread duk_context;\n\n/* Check whether we should use 64-bit integers or not.\n *\n * Quite incomplete now.  Use 64-bit types if detected (C99 or other detection)\n * unless they are known to be unreliable.  For instance, 64-bit types are\n * available on VBCC but seem to misbehave.\n */\n#if defined(DUK_F_HAVE_64BIT) && !defined(DUK_F_VBCC)\n#define DUK_USE_64BIT_OPS\n#else\n#undef DUK_USE_64BIT_OPS\n#endif\n\n/*\n *  Fill-ins for platform, architecture, and compiler\n */\n\n/* An abort()-like primitive is needed by the default fatal error handler. */\n#if !defined(DUK_ABORT)\n#define DUK_ABORT             abort\n#endif\n\n#if !defined(DUK_SETJMP)\n#define DUK_JMPBUF_TYPE       jmp_buf\n#define DUK_SETJMP(jb)        setjmp((jb))\n#define DUK_LONGJMP(jb)       longjmp((jb), 1)\n#endif\n\n#if 0\n/* sigsetjmp() alternative */\n#define DUK_JMPBUF_TYPE       sigjmp_buf\n#define DUK_SETJMP(jb)        sigsetjmp((jb))\n#define DUK_LONGJMP(jb)       siglongjmp((jb), 1)\n#endif\n\n/* Special naming to avoid conflict with e.g. DUK_FREE() in duk_heap.h\n * (which is unfortunately named).  May sometimes need replacement, e.g.\n * some compilers don't handle zero length or NULL correctly in realloc().\n */\n#if !defined(DUK_ANSI_MALLOC)\n#define DUK_ANSI_MALLOC      malloc\n#endif\n#if !defined(DUK_ANSI_REALLOC)\n#define DUK_ANSI_REALLOC     realloc\n#endif\n#if !defined(DUK_ANSI_CALLOC)\n#define DUK_ANSI_CALLOC      calloc\n#endif\n#if !defined(DUK_ANSI_FREE)\n#define DUK_ANSI_FREE        free\n#endif\n\n/* ANSI C (various versions) and some implementations require that the\n * pointer arguments to memset(), memcpy(), and memmove() be valid values\n * even when byte size is 0 (even a NULL pointer is considered invalid in\n * this context).  Zero-size operations as such are allowed, as long as their\n * pointer arguments point to a valid memory area.  The DUK_MEMSET(),\n * DUK_MEMCPY(), and DUK_MEMMOVE() macros require this same behavior, i.e.:\n * (1) pointers must be valid and non-NULL, (2) zero size must otherwise be\n * allowed.  If these are not fulfilled, a macro wrapper is needed.\n *\n *   http://stackoverflow.com/questions/5243012/is-it-guaranteed-to-be-safe-to-perform-memcpy0-0-0\n *   http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-October/011065.html\n *\n * Not sure what's the required behavior when a pointer points just past the\n * end of a buffer, which often happens in practice (e.g. zero size memmoves).\n * For example, if allocation size is 3, the following pointer would not\n * technically point to a valid memory byte:\n *\n *   <-- alloc -->\n *   | 0 | 1 | 2 | .....\n *                 ^-- p=3, points after last valid byte (2)\n */\n#if !defined(DUK_MEMCPY)\n#if defined(DUK_F_UCLIBC)\n/* Old uclibcs have a broken memcpy so use memmove instead (this is overly wide\n * now on purpose): http://lists.uclibc.org/pipermail/uclibc-cvs/2008-October/025511.html\n */\n#define DUK_MEMCPY       memmove\n#else\n#define DUK_MEMCPY       memcpy\n#endif\n#endif\n#if !defined(DUK_MEMMOVE)\n#define DUK_MEMMOVE      memmove\n#endif\n#if !defined(DUK_MEMCMP)\n#define DUK_MEMCMP       memcmp\n#endif\n#if !defined(DUK_MEMSET)\n#define DUK_MEMSET       memset\n#endif\n#if !defined(DUK_STRLEN)\n#define DUK_STRLEN       strlen\n#endif\n#if !defined(DUK_STRCMP)\n#define DUK_STRCMP       strcmp\n#endif\n#if !defined(DUK_STRNCMP)\n#define DUK_STRNCMP      strncmp\n#endif\n#if !defined(DUK_SPRINTF)\n#define DUK_SPRINTF      sprintf\n#endif\n#if !defined(DUK_SNPRINTF)\n/* snprintf() is technically not part of C89 but usually available. */\n#define DUK_SNPRINTF     snprintf\n#endif\n#if !defined(DUK_VSPRINTF)\n#define DUK_VSPRINTF     vsprintf\n#endif\n#if !defined(DUK_VSNPRINTF)\n/* vsnprintf() is technically not part of C89 but usually available. */\n#define DUK_VSNPRINTF    vsnprintf\n#endif\n#if !defined(DUK_SSCANF)\n#define DUK_SSCANF       sscanf\n#endif\n#if !defined(DUK_VSSCANF)\n#define DUK_VSSCANF      vsscanf\n#endif\n#if !defined(DUK_MEMZERO)\n#define DUK_MEMZERO(p,n) DUK_MEMSET((p), 0, (n))\n#endif\n\n#if !defined(DUK_DOUBLE_INFINITY)\n#undef DUK_USE_COMPUTED_INFINITY\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION < 40600)\n/* GCC older than 4.6: avoid overflow warnings related to using INFINITY */\n#define DUK_DOUBLE_INFINITY  (__builtin_inf())\n#elif defined(INFINITY)\n#define DUK_DOUBLE_INFINITY  ((double) INFINITY)\n#elif !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) && !defined(DUK_F_BCC) && \\\n      !defined(DUK_F_OLD_SOLARIS) && !defined(DUK_F_AIX)\n#define DUK_DOUBLE_INFINITY  (1.0 / 0.0)\n#else\n/* In VBCC (1.0 / 0.0) results in a warning and 0.0 instead of infinity.\n * Use a computed infinity (initialized when a heap is created at the\n * latest).\n */\n#define DUK_USE_COMPUTED_INFINITY\n#define DUK_DOUBLE_INFINITY  duk_computed_infinity\n#endif\n#endif\n\n#if !defined(DUK_DOUBLE_NAN)\n#undef DUK_USE_COMPUTED_NAN\n#if defined(NAN)\n#define DUK_DOUBLE_NAN       NAN\n#elif !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) && !defined(DUK_F_BCC) && \\\n      !defined(DUK_F_OLD_SOLARIS) && !defined(DUK_F_AIX)\n#define DUK_DOUBLE_NAN       (0.0 / 0.0)\n#else\n/* In VBCC (0.0 / 0.0) results in a warning and 0.0 instead of NaN.\n * In MSVC (VS2010 Express) (0.0 / 0.0) results in a compile error.\n * Use a computed NaN (initialized when a heap is created at the\n * latest).\n */\n#define DUK_USE_COMPUTED_NAN\n#define DUK_DOUBLE_NAN       duk_computed_nan\n#endif\n#endif\n\n/* Many platforms are missing fpclassify() and friends, so use replacements\n * if necessary.  The replacement constants (FP_NAN etc) can be anything but\n * match Linux constants now.\n */\n#undef DUK_USE_REPL_FPCLASSIFY\n#undef DUK_USE_REPL_SIGNBIT\n#undef DUK_USE_REPL_ISFINITE\n#undef DUK_USE_REPL_ISNAN\n#undef DUK_USE_REPL_ISINF\n\n/* Complex condition broken into separate parts. */\n#undef DUK_F_USE_REPL_ALL\n#if !(defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO) && \\\n      defined(FP_SUBNORMAL) && defined(FP_NORMAL))\n/* Missing some obvious constants. */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC)\n/* VBCC is missing the built-ins even in C99 mode (perhaps a header issue). */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_AMIGAOS) && defined(DUK_F_M68K)\n/* AmigaOS + M68K seems to have math issues even when using GCC cross\n * compilation.  Use replacements for all AmigaOS versions on M68K\n * regardless of compiler.\n */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_FREEBSD) && defined(DUK_F_CLANG)\n/* Placeholder fix for (detection is wider than necessary):\n * http://llvm.org/bugs/show_bug.cgi?id=17788\n */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_UCLIBC)\n/* At least some uclibc versions have broken floating point math.  For\n * example, fpclassify() can incorrectly classify certain NaN formats.\n * To be safe, use replacements.\n */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_AIX)\n/* Older versions may be missing isnan(), etc. */\n#define DUK_F_USE_REPL_ALL\n#endif\n\n#if defined(DUK_F_USE_REPL_ALL)\n#define DUK_USE_REPL_FPCLASSIFY\n#define DUK_USE_REPL_SIGNBIT\n#define DUK_USE_REPL_ISFINITE\n#define DUK_USE_REPL_ISNAN\n#define DUK_USE_REPL_ISINF\n#define DUK_FPCLASSIFY       duk_repl_fpclassify\n#define DUK_SIGNBIT          duk_repl_signbit\n#define DUK_ISFINITE         duk_repl_isfinite\n#define DUK_ISNAN            duk_repl_isnan\n#define DUK_ISINF            duk_repl_isinf\n#define DUK_FP_NAN           0\n#define DUK_FP_INFINITE      1\n#define DUK_FP_ZERO          2\n#define DUK_FP_SUBNORMAL     3\n#define DUK_FP_NORMAL        4\n#else\n#define DUK_FPCLASSIFY       fpclassify\n#define DUK_SIGNBIT          signbit\n#define DUK_ISFINITE         isfinite\n#define DUK_ISNAN            isnan\n#define DUK_ISINF            isinf\n#define DUK_FP_NAN           FP_NAN\n#define DUK_FP_INFINITE      FP_INFINITE\n#define DUK_FP_ZERO          FP_ZERO\n#define DUK_FP_SUBNORMAL     FP_SUBNORMAL\n#define DUK_FP_NORMAL        FP_NORMAL\n#endif\n\n#if defined(DUK_F_USE_REPL_ALL)\n#undef DUK_F_USE_REPL_ALL\n#endif\n\n/* These functions don't currently need replacement but are wrapped for\n * completeness.  Because these are used as function pointers, they need\n * to be defined as concrete C functions (not macros).\n */\n#if !defined(DUK_FABS)\n#define DUK_FABS             fabs\n#endif\n#if !defined(DUK_FLOOR)\n#define DUK_FLOOR            floor\n#endif\n#if !defined(DUK_CEIL)\n#define DUK_CEIL             ceil\n#endif\n#if !defined(DUK_FMOD)\n#define DUK_FMOD             fmod\n#endif\n#if !defined(DUK_POW)\n#define DUK_POW              pow\n#endif\n#if !defined(DUK_ACOS)\n#define DUK_ACOS             acos\n#endif\n#if !defined(DUK_ASIN)\n#define DUK_ASIN             asin\n#endif\n#if !defined(DUK_ATAN)\n#define DUK_ATAN             atan\n#endif\n#if !defined(DUK_ATAN2)\n#define DUK_ATAN2            atan2\n#endif\n#if !defined(DUK_SIN)\n#define DUK_SIN              sin\n#endif\n#if !defined(DUK_COS)\n#define DUK_COS              cos\n#endif\n#if !defined(DUK_TAN)\n#define DUK_TAN              tan\n#endif\n#if !defined(DUK_EXP)\n#define DUK_EXP              exp\n#endif\n#if !defined(DUK_LOG)\n#define DUK_LOG              log\n#endif\n#if !defined(DUK_SQRT)\n#define DUK_SQRT             sqrt\n#endif\n\n/* The functions below exist only in C99/C++11 or later and need a workaround\n * for platforms that don't include them.  MSVC isn't detected as C99, but\n * these functions also exist in MSVC 2013 and later so include a clause for\n * that too.  Android doesn't have log2; disable all of these for Android.\n */\n#if (defined(DUK_F_C99) || defined(DUK_F_CPP11) || (defined(_MSC_VER) && (_MSC_VER >= 1800))) && \\\n    !defined(DUK_F_ANDROID) && !defined(DUK_F_MINT)\n#if !defined(DUK_CBRT)\n#define DUK_CBRT             cbrt\n#endif\n#if !defined(DUK_LOG2)\n#define DUK_LOG2             log2\n#endif\n#if !defined(DUK_LOG10)\n#define DUK_LOG10            log10\n#endif\n#if !defined(DUK_TRUNC)\n#define DUK_TRUNC            trunc\n#endif\n#endif  /* DUK_F_C99 etc */\n\n/* NetBSD 6.0 x86 (at least) has a few problems with pow() semantics,\n * see test-bug-netbsd-math-pow.js.  MinGW has similar (but different)\n * issues, see test-bug-mingw-math-issues.js.  Enable pow() workarounds\n * for these targets.\n */\n#undef DUK_USE_POW_WORKAROUNDS\n#if defined(DUK_F_NETBSD) || defined(DUK_F_MINGW)\n#define DUK_USE_POW_WORKAROUNDS\n#endif\n\n/* Similar workarounds for atan2() semantics issues.  MinGW issues are\n * documented in test-bug-mingw-math-issues.js.\n */\n#undef DUK_USE_ATAN2_WORKAROUNDS\n#if defined(DUK_F_MINGW)\n#define DUK_USE_ATAN2_WORKAROUNDS\n#endif\n\n/* Rely as little as possible on compiler behavior for NaN comparison,\n * signed zero handling, etc.  Currently never activated but may be needed\n * for broken compilers.\n */\n#undef DUK_USE_PARANOID_MATH\n\n/* There was a curious bug where test-bi-date-canceling.js would fail e.g.\n * on 64-bit Ubuntu, gcc-4.8.1, -m32, and no -std=c99.  Some date computations\n * using doubles would be optimized which then broke some corner case tests.\n * The problem goes away by adding 'volatile' to the datetime computations.\n * Not sure what the actual triggering conditions are, but using this on\n * non-C99 systems solves the known issues and has relatively little cost\n * on other platforms.\n */\n#undef DUK_USE_PARANOID_DATE_COMPUTATION\n#if !defined(DUK_F_C99)\n#define DUK_USE_PARANOID_DATE_COMPUTATION\n#endif\n\n/*\n *  Byte order and double memory layout detection\n *\n *  Endianness detection is a major portability hassle because the macros\n *  and headers are not standardized.  There's even variance across UNIX\n *  platforms.  Even with \"standard\" headers, details like underscore count\n *  varies between platforms, e.g. both __BYTE_ORDER and _BYTE_ORDER are used\n *  (Crossbridge has a single underscore, for instance).\n *\n *  The checks below are structured with this in mind: several approaches are\n *  used, and at the end we check if any of them worked.  This allows generic\n *  approaches to be tried first, and platform/compiler specific hacks tried\n *  last.  As a last resort, the user can force a specific endianness, as it's\n *  not likely that automatic detection will work on the most exotic platforms.\n *\n *  Duktape supports little and big endian machines.  There's also support\n *  for a hybrid used by some ARM machines where integers are little endian\n *  but IEEE double values use a mixed order (12345678 -> 43218765).  This\n *  byte order for doubles is referred to as \"mixed endian\".\n */\n\n/* GCC and Clang provide endianness defines as built-in predefines, with\n * leading and trailing double underscores (e.g. __BYTE_ORDER__).  See\n * output of \"make gccpredefs\" and \"make clangpredefs\".  Clang doesn't\n * seem to provide __FLOAT_WORD_ORDER__; assume not mixed endian for clang.\n * http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html\n */\n#if !defined(DUK_USE_BYTEORDER) && defined(__BYTE_ORDER__)\n#if defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__)\n#define DUK_USE_BYTEORDER 1\n#elif defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__)\n#define DUK_USE_BYTEORDER 2\n#elif !defined(__FLOAT_WORD_ORDER__)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 1\n#else\n/* Byte order is little endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#elif defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__)\n#define DUK_USE_BYTEORDER 3\n#elif !defined(__FLOAT_WORD_ORDER__)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 3\n#else\n/* Byte order is big endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#else\n/* Cannot determine byte order; __ORDER_PDP_ENDIAN__ is related to 32-bit\n * integer ordering and is not relevant.\n */\n#endif  /* integer byte order */\n#endif  /* !defined(DUK_USE_BYTEORDER) && defined(__BYTE_ORDER__) */\n\n/* More or less standard endianness predefines provided by header files.\n * The ARM hybrid case is detected by assuming that __FLOAT_WORD_ORDER\n * will be big endian, see: http://lists.mysql.com/internals/443.\n * On some platforms some defines may be present with an empty value which\n * causes comparisons to fail: https://github.com/svaarala/duktape/issues/453.\n */\n#if !defined(DUK_USE_BYTEORDER)\n#if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN) || \\\n    defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN) || \\\n    defined(__LITTLE_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER) && defined(__LITTLE_ENDIAN) && (__FLOAT_WORD_ORDER == __LITTLE_ENDIAN) || \\\n    defined(_FLOAT_WORD_ORDER) && defined(_LITTLE_ENDIAN) && (_FLOAT_WORD_ORDER == _LITTLE_ENDIAN)\n#define DUK_USE_BYTEORDER 1\n#elif defined(__FLOAT_WORD_ORDER) && defined(__BIG_ENDIAN) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN) || \\\n      defined(_FLOAT_WORD_ORDER) && defined(_BIG_ENDIAN) && (_FLOAT_WORD_ORDER == _BIG_ENDIAN)\n#define DUK_USE_BYTEORDER 2\n#elif !defined(__FLOAT_WORD_ORDER) && !defined(_FLOAT_WORD_ORDER)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 1\n#else\n/* Byte order is little endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN) || \\\n      defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN) || \\\n      defined(__BIG_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER) && defined(__BIG_ENDIAN) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN) || \\\n    defined(_FLOAT_WORD_ORDER) && defined(_BIG_ENDIAN) && (_FLOAT_WORD_ORDER == _BIG_ENDIAN)\n#define DUK_USE_BYTEORDER 3\n#elif !defined(__FLOAT_WORD_ORDER) && !defined(_FLOAT_WORD_ORDER)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 3\n#else\n/* Byte order is big endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#else\n/* Cannot determine byte order. */\n#endif  /* integer byte order */\n#endif  /* !defined(DUK_USE_BYTEORDER) */\n\n/* QNX gcc cross compiler seems to define e.g. __LITTLEENDIAN__ or __BIGENDIAN__:\n *  $ /opt/qnx650/host/linux/x86/usr/bin/i486-pc-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian\n *  67:#define __LITTLEENDIAN__ 1\n *  $ /opt/qnx650/host/linux/x86/usr/bin/mips-unknown-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian\n *  81:#define __BIGENDIAN__ 1\n *  $ /opt/qnx650/host/linux/x86/usr/bin/arm-unknown-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian\n *  70:#define __LITTLEENDIAN__ 1\n */\n#if !defined(DUK_USE_BYTEORDER)\n#if defined(__LITTLEENDIAN__)\n#define DUK_USE_BYTEORDER 1\n#elif defined(__BIGENDIAN__)\n#define DUK_USE_BYTEORDER 3\n#endif\n#endif\n\n/*\n *  Alignment requirement and support for unaligned accesses\n *\n *  Assume unaligned accesses are not supported unless specifically allowed\n *  in the target platform.  Some platforms may support unaligned accesses\n *  but alignment to 4 or 8 may still be desirable.  Note that unaligned\n *  accesses (and even pointers) relative to natural alignment (regardless\n *  of target alignment) are technically undefined behavior and thus\n *  compiler/architecture specific.\n */\n\n/* If not forced, use safe default for alignment. */\n#if !defined(DUK_USE_ALIGN_BY)\n#define DUK_USE_ALIGN_BY 8\n#endif\n\n/* Compiler specific hackery needed to force struct size to match alignment,\n * see e.g. duk_hbuffer.h.\n *\n * http://stackoverflow.com/questions/11130109/c-struct-size-alignment\n * http://stackoverflow.com/questions/10951039/specifying-64-bit-alignment\n */\n#if !(defined(DUK_USE_PACK_MSVC_PRAGMA) || defined(DUK_USE_PACK_GCC_ATTR) || \\\n      defined(DUK_USE_PACK_CLANG_ATTR) || defined(DUK_USE_PACK_DUMMY_MEMBER))\n#define DUK_USE_PACK_DUMMY_MEMBER\n#endif\n\n#if !defined(DUK_U64_CONSTANT)\n#define DUK_U64_CONSTANT(x) x##ULL\n#endif\n#if !defined(DUK_I64_CONSTANT)\n#define DUK_I64_CONSTANT(x) x##LL\n#endif\n\n#if !defined(DUK_VA_COPY)\n/* We need va_copy() which is defined in C99 / C++11, so an awkward\n * replacement is needed for pre-C99 / pre-C++11 environments.  This\n * will quite likely need portability hacks for some non-C99\n * environments.\n */\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n/* C99 / C++11 and above: rely on va_copy() which is required.\n * Omit parenthesis on macro right side on purpose to minimize differences\n * to direct use.\n */\n#define DUK_VA_COPY(dest,src) va_copy(dest,src)\n#else\n/* Pre-C99: va_list type is implementation dependent.  This replacement\n * assumes it is a plain value so that a simple assignment will work.\n * This is not the case on all platforms (it may be a single-array element,\n * for instance).\n */\n#define DUK_VA_COPY(dest,src) do { (dest) = (src); } while (0)\n#endif\n#endif\n\n#if !defined(DUK_MACRO_STRINGIFY)\n/* Macro hackery to convert e.g. __LINE__ to a string without formatting,\n * see: http://stackoverflow.com/questions/240353/convert-a-preprocessor-token-to-a-string\n */\n#define DUK_MACRO_STRINGIFY_HELPER(x)  #x\n#define DUK_MACRO_STRINGIFY(x)  DUK_MACRO_STRINGIFY_HELPER(x)\n#endif\n\n#if !defined(DUK_CAUSE_SEGFAULT)\n/* This can be used for testing; valgrind will then indicate the C call stack\n * leading to the call site.\n */\n#define DUK_CAUSE_SEGFAULT()  do { *((volatile duk_uint32_t *) NULL) = (duk_uint32_t) 0xdeadbeefUL; } while (0)\n#endif\n\n#if !defined(DUK_UNREF)\n/* Macro for suppressing warnings for potentially unreferenced variables.\n * The variables can be actually unreferenced or unreferenced in some\n * specific cases only; for instance, if a variable is only debug printed,\n * it is unreferenced when debug printing is disabled.  May cause warnings\n * for volatile arguments.\n */\n#define DUK_UNREF(x)  do { (void) (x); } while (0)\n#endif\n\n/* Fillin for DUK_NORETURN; DUK_WO_NORETURN() is used to insert dummy\n * dummy statements after noreturn calls to silence harmless compiler\n * warnings, e.g.:\n *\n *   DUK_ERROR_TYPE(thr, \"aiee\");\n *   DUK_WO_NORETURN(return 0;);\n *\n * Statements inside DUK_WO_NORETURN() must NEVER be actually reachable,\n * and they're only included to satisfy the compiler.\n */\n#if defined(DUK_NORETURN)\n#define DUK_WO_NORETURN(stmt) do { } while (0)\n#else\n#define DUK_NORETURN(decl)  decl\n#define DUK_WO_NORETURN(stmt) do { stmt } while (0)\n#endif\n\n#if !defined(DUK_UNREACHABLE)\n/* Don't know how to declare unreachable point, so don't do it; this\n * may cause some spurious compilation warnings (e.g. \"variable used\n * uninitialized\").\n */\n#define DUK_UNREACHABLE()  do { } while (0)\n#endif\n\n#if !defined(DUK_LOSE_CONST)\n/* Convert any input pointer into a \"void *\", losing a const qualifier.\n * This is not fully portable because casting through duk_uintptr_t may\n * not work on all architectures (e.g. those with long, segmented pointers).\n */\n#define DUK_LOSE_CONST(src) ((void *) (duk_uintptr_t) (src))\n#endif\n\n#if !defined(DUK_LIKELY)\n#define DUK_LIKELY(x)    (x)\n#endif\n#if !defined(DUK_UNLIKELY)\n#define DUK_UNLIKELY(x)  (x)\n#endif\n#if !defined(DUK_UNPREDICTABLE)\n#define DUK_UNPREDICTABLE(x)  (x)\n#endif\n\n#if !defined(DUK_NOINLINE)\n#define DUK_NOINLINE       /*nop*/\n#endif\n#if !defined(DUK_INLINE)\n#define DUK_INLINE         /*nop*/\n#endif\n#if !defined(DUK_ALWAYS_INLINE)\n#define DUK_ALWAYS_INLINE  /*nop*/\n#endif\n\n#if !defined(DUK_HOT)\n#define DUK_HOT            /*nop*/\n#endif\n#if !defined(DUK_COLD)\n#define DUK_COLD           /*nop*/\n#endif\n\n#if !defined(DUK_EXTERNAL_DECL)\n#define DUK_EXTERNAL_DECL  extern\n#endif\n#if !defined(DUK_EXTERNAL)\n#define DUK_EXTERNAL       /*empty*/\n#endif\n#if !defined(DUK_INTERNAL_DECL)\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL_DECL  static\n#else\n#define DUK_INTERNAL_DECL  extern\n#endif\n#endif\n#if !defined(DUK_INTERNAL)\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL       static\n#else\n#define DUK_INTERNAL       /*empty*/\n#endif\n#endif\n#if !defined(DUK_LOCAL_DECL)\n#define DUK_LOCAL_DECL     static\n#endif\n#if !defined(DUK_LOCAL)\n#define DUK_LOCAL          static\n#endif\n\n#if !defined(DUK_FILE_MACRO)\n#define DUK_FILE_MACRO  __FILE__\n#endif\n#if !defined(DUK_LINE_MACRO)\n#define DUK_LINE_MACRO  __LINE__\n#endif\n#if !defined(DUK_FUNC_MACRO)\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_FUNC_MACRO  __func__\n#elif defined(__FUNCTION__)\n#define DUK_FUNC_MACRO  __FUNCTION__\n#else\n#define DUK_FUNC_MACRO  \"unknown\"\n#endif\n#endif\n\n#if defined(DUK_F_HAVE_64BIT)\n#if !defined(DUK_BSWAP64)\n#define DUK_BSWAP64(x) \\\n\t((((duk_uint64_t) (x)) >> 56U) | \\\n\t ((((duk_uint64_t) (x)) >> 40U) & DUK_U64_CONSTANT(0xff00)) | \\\n\t ((((duk_uint64_t) (x)) >> 24U) & DUK_U64_CONSTANT(0xff0000)) | \\\n\t ((((duk_uint64_t) (x)) >> 8U) & DUK_U64_CONSTANT(0xff000000)) | \\\n\t ((((duk_uint64_t) (x)) << 8U) & DUK_U64_CONSTANT(0xff00000000)) | \\\n\t ((((duk_uint64_t) (x)) << 24U) & DUK_U64_CONSTANT(0xff0000000000)) | \\\n\t ((((duk_uint64_t) (x)) << 40U) & DUK_U64_CONSTANT(0xff000000000000)) | \\\n\t (((duk_uint64_t) (x)) << 56U))\n#endif\n#endif\n#if !defined(DUK_BSWAP32)\n#define DUK_BSWAP32(x) \\\n\t((((duk_uint32_t) (x)) >> 24U) | \\\n\t ((((duk_uint32_t) (x)) >> 8U) & 0xff00UL) | \\\n\t ((((duk_uint32_t) (x)) << 8U) & 0xff0000UL) | \\\n\t (((duk_uint32_t) (x)) << 24U))\n#endif\n#if !defined(DUK_BSWAP16)\n#define DUK_BSWAP16(x) \\\n\t((duk_uint16_t) (x) >> 8U) | \\\n\t((duk_uint16_t) (x) << 8U)\n#endif\n\n/* DUK_USE_VARIADIC_MACROS: required from compilers, so no fill-in. */\n/* DUK_USE_UNION_INITIALIZERS: required from compilers, so no fill-in. */\n\n#if !(defined(DUK_USE_FLEX_C99) || defined(DUK_USE_FLEX_ZEROSIZE) || defined(DUK_USE_FLEX_ONESIZE))\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE  /* Not standard but common enough */\n#endif\n#endif\n\n#if !(defined(DUK_USE_PACK_GCC_ATTR) || defined(DUK_USE_PACK_CLANG_ATTR) || \\\n      defined(DUK_USE_PACK_MSVC_PRAGMA) || defined(DUK_USE_PACK_DUMMY_MEMBER))\n#define DUK_USE_PACK_DUMMY_MEMBER\n#endif\n\n#if 0  /* not defined by default */\n#undef DUK_USE_GCC_PRAGMAS\n#endif\n\n/* Workaround for GH-323: avoid inlining control when compiling from\n * multiple sources, as it causes compiler portability trouble.\n */\n#if !defined(DUK_SINGLE_FILE)\n#undef DUK_NOINLINE\n#undef DUK_INLINE\n#undef DUK_ALWAYS_INLINE\n#define DUK_NOINLINE       /*nop*/\n#define DUK_INLINE         /*nop*/\n#define DUK_ALWAYS_INLINE  /*nop*/\n#endif\n\n/*\n *  Check whether or not a packed duk_tval representation is possible.\n *  What's basically required is that pointers are 32-bit values\n *  (sizeof(void *) == 4).  Best effort check, not always accurate.\n *  If guess goes wrong, crashes may result; self tests also verify\n *  the guess.\n */\n\n/* Explicit marker needed; may be 'defined', 'undefined, 'or 'not provided'. */\n#if !defined(DUK_F_PACKED_TVAL_PROVIDED)\n#undef DUK_F_PACKED_TVAL_POSSIBLE\n\n/* Strict C99 case: DUK_UINTPTR_MAX (= UINTPTR_MAX) should be very reliable */\n#if !defined(DUK_F_PACKED_TVAL_POSSIBLE) && defined(DUK_UINTPTR_MAX)\n#if (DUK_UINTPTR_MAX <= 0xffffffffUL)\n#define DUK_F_PACKED_TVAL_POSSIBLE\n#endif\n#endif\n\n/* Non-C99 case, still relying on DUK_UINTPTR_MAX, as long as it is not a computed value */\n#if !defined(DUK_F_PACKED_TVAL_POSSIBLE) && defined(DUK_UINTPTR_MAX) && !defined(DUK_UINTPTR_MAX_COMPUTED)\n#if (DUK_UINTPTR_MAX <= 0xffffffffUL)\n#define DUK_F_PACKED_TVAL_POSSIBLE\n#endif\n#endif\n\n/* DUK_SIZE_MAX (= SIZE_MAX) is often reliable */\n#if !defined(DUK_F_PACKED_TVAL_POSSIBLE) && defined(DUK_SIZE_MAX) && !defined(DUK_SIZE_MAX_COMPUTED)\n#if (DUK_SIZE_MAX <= 0xffffffffUL)\n#define DUK_F_PACKED_TVAL_POSSIBLE\n#endif\n#endif\n\n#undef DUK_USE_PACKED_TVAL\n#if defined(DUK_F_PACKED_TVAL_POSSIBLE)\n#define DUK_USE_PACKED_TVAL\n#endif\n#undef DUK_F_PACKED_TVAL_POSSIBLE\n\n#endif  /* DUK_F_PACKED_TVAL_PROVIDED */\n/* Object property allocation layout has implications for memory and code\n * footprint and generated code size/speed.  The best layout also depends\n * on whether the platform has alignment requirements or benefits from\n * having mostly aligned accesses.\n */\n#undef DUK_USE_HOBJECT_LAYOUT_1\n#undef DUK_USE_HOBJECT_LAYOUT_2\n#undef DUK_USE_HOBJECT_LAYOUT_3\n#if (DUK_USE_ALIGN_BY == 1)\n/* On platforms without any alignment issues, layout 1 is preferable\n * because it compiles to slightly less code and provides direct access\n * to property keys.\n */\n#define DUK_USE_HOBJECT_LAYOUT_1\n#else\n/* On other platforms use layout 2, which requires some padding but\n * is a bit more natural than layout 3 in ordering the entries.  Layout\n * 3 is currently not used.\n */\n#define DUK_USE_HOBJECT_LAYOUT_2\n#endif\n\n/* GCC/clang inaccurate math would break compliance and probably duk_tval,\n * so refuse to compile.  Relax this if -ffast-math is tested to work.\n */\n#if defined(__FAST_MATH__)\n#error __FAST_MATH__ defined, refusing to compile\n#endif\n\n/*\n *  Autogenerated defaults\n */\n\n#undef DUK_USE_ALLOW_UNDEFINED_BEHAVIOR\n#define DUK_USE_ARRAY_BUILTIN\n#define DUK_USE_ARRAY_FASTPATH\n#define DUK_USE_ARRAY_PROP_FASTPATH\n#undef DUK_USE_ASSERTIONS\n#define DUK_USE_AUGMENT_ERROR_CREATE\n#define DUK_USE_AUGMENT_ERROR_THROW\n#define DUK_USE_AVOID_PLATFORM_FUNCPTRS\n#define DUK_USE_BASE64_FASTPATH\n#define DUK_USE_BASE64_SUPPORT\n#define DUK_USE_BOOLEAN_BUILTIN\n#define DUK_USE_BUFFEROBJECT_SUPPORT\n#undef DUK_USE_BUFLEN16\n#define DUK_USE_BYTECODE_DUMP_SUPPORT\n#define DUK_USE_CACHE_ACTIVATION\n#define DUK_USE_CACHE_CATCHER\n#define DUK_USE_CALLSTACK_LIMIT 10000\n#define DUK_USE_COMPILER_RECLIMIT 2500\n#define DUK_USE_COROUTINE_SUPPORT\n#undef DUK_USE_CPP_EXCEPTIONS\n#undef DUK_USE_DATAPTR16\n#undef DUK_USE_DATAPTR_DEC16\n#undef DUK_USE_DATAPTR_ENC16\n#define DUK_USE_DATE_BUILTIN\n#undef DUK_USE_DATE_FORMAT_STRING\n#undef DUK_USE_DATE_GET_LOCAL_TZOFFSET\n#undef DUK_USE_DATE_GET_NOW\n#undef DUK_USE_DATE_PARSE_STRING\n#undef DUK_USE_DATE_PRS_GETDATE\n#undef DUK_USE_DEBUG\n#undef DUK_USE_DEBUGGER_DUMPHEAP\n#undef DUK_USE_DEBUGGER_INSPECT\n#undef DUK_USE_DEBUGGER_PAUSE_UNCAUGHT\n#undef DUK_USE_DEBUGGER_SUPPORT\n#define DUK_USE_DEBUGGER_THROW_NOTIFY\n#undef DUK_USE_DEBUGGER_TRANSPORT_TORTURE\n#define DUK_USE_DEBUG_BUFSIZE 65536L\n#define DUK_USE_DEBUG_LEVEL 0\n#undef DUK_USE_DEBUG_WRITE\n#define DUK_USE_DOUBLE_LINKED_HEAP\n#define DUK_USE_DUKTAPE_BUILTIN\n#define DUK_USE_ENCODING_BUILTINS\n#define DUK_USE_ERRCREATE\n#define DUK_USE_ERRTHROW\n#define DUK_USE_ES6\n#define DUK_USE_ES6_OBJECT_PROTO_PROPERTY\n#define DUK_USE_ES6_OBJECT_SETPROTOTYPEOF\n#define DUK_USE_ES6_PROXY\n#define DUK_USE_ES6_REGEXP_SYNTAX\n#define DUK_USE_ES6_UNICODE_ESCAPE\n#define DUK_USE_ES7\n#define DUK_USE_ES7_EXP_OPERATOR\n#define DUK_USE_ES8\n#define DUK_USE_ES9\n#define DUK_USE_ESBC_LIMITS\n#define DUK_USE_ESBC_MAX_BYTES 2147418112L\n#define DUK_USE_ESBC_MAX_LINENUMBER 2147418112L\n#undef DUK_USE_EXEC_FUN_LOCAL\n#undef DUK_USE_EXEC_INDIRECT_BOUND_CHECK\n#undef DUK_USE_EXEC_PREFER_SIZE\n#define DUK_USE_EXEC_REGCONST_OPTIMIZE\n#undef DUK_USE_EXEC_TIMEOUT_CHECK\n#undef DUK_USE_EXPLICIT_NULL_INIT\n#undef DUK_USE_EXTSTR_FREE\n#undef DUK_USE_EXTSTR_INTERN_CHECK\n#undef DUK_USE_FASTINT\n#define DUK_USE_FAST_REFCOUNT_DEFAULT\n#undef DUK_USE_FATAL_HANDLER\n#define DUK_USE_FATAL_MAXLEN 128\n#define DUK_USE_FINALIZER_SUPPORT\n#undef DUK_USE_FINALIZER_TORTURE\n#undef DUK_USE_FUNCPTR16\n#undef DUK_USE_FUNCPTR_DEC16\n#undef DUK_USE_FUNCPTR_ENC16\n#define DUK_USE_FUNCTION_BUILTIN\n#define DUK_USE_FUNC_FILENAME_PROPERTY\n#define DUK_USE_FUNC_NAME_PROPERTY\n#undef DUK_USE_GC_TORTURE\n#undef DUK_USE_GET_MONOTONIC_TIME\n#undef DUK_USE_GET_RANDOM_DOUBLE\n#undef DUK_USE_GLOBAL_BINDING\n#define DUK_USE_GLOBAL_BUILTIN\n#undef DUK_USE_HEAPPTR16\n#undef DUK_USE_HEAPPTR_DEC16\n#undef DUK_USE_HEAPPTR_ENC16\n#define DUK_USE_HEX_FASTPATH\n#define DUK_USE_HEX_SUPPORT\n#define DUK_USE_HOBJECT_ARRAY_ABANDON_LIMIT 2\n#define DUK_USE_HOBJECT_ARRAY_FAST_RESIZE_LIMIT 9\n#define DUK_USE_HOBJECT_ARRAY_MINGROW_ADD 16\n#define DUK_USE_HOBJECT_ARRAY_MINGROW_DIVISOR 8\n#define DUK_USE_HOBJECT_ENTRY_MINGROW_ADD 16\n#define DUK_USE_HOBJECT_ENTRY_MINGROW_DIVISOR 8\n#define DUK_USE_HOBJECT_HASH_PART\n#define DUK_USE_HOBJECT_HASH_PROP_LIMIT 8\n#define DUK_USE_HSTRING_ARRIDX\n#define DUK_USE_HSTRING_CLEN\n#undef DUK_USE_HSTRING_EXTDATA\n#define DUK_USE_HSTRING_LAZY_CLEN\n#define DUK_USE_HTML_COMMENTS\n#define DUK_USE_IDCHAR_FASTPATH\n#undef DUK_USE_INJECT_HEAP_ALLOC_ERROR\n#undef DUK_USE_INTERRUPT_COUNTER\n#undef DUK_USE_INTERRUPT_DEBUG_FIXUP\n#define DUK_USE_JC\n#define DUK_USE_JSON_BUILTIN\n#define DUK_USE_JSON_DECNUMBER_FASTPATH\n#define DUK_USE_JSON_DECSTRING_FASTPATH\n#define DUK_USE_JSON_DEC_RECLIMIT 1000\n#define DUK_USE_JSON_EATWHITE_FASTPATH\n#define DUK_USE_JSON_ENC_RECLIMIT 1000\n#define DUK_USE_JSON_QUOTESTRING_FASTPATH\n#undef DUK_USE_JSON_STRINGIFY_FASTPATH\n#define DUK_USE_JSON_SUPPORT\n#define DUK_USE_JX\n#define DUK_USE_LEXER_SLIDING_WINDOW\n#undef DUK_USE_LIGHTFUNC_BUILTINS\n#define DUK_USE_LITCACHE_SIZE 256\n#define DUK_USE_MARK_AND_SWEEP_RECLIMIT 256\n#define DUK_USE_MATH_BUILTIN\n#define DUK_USE_NATIVE_CALL_RECLIMIT 1000\n#undef DUK_USE_NATIVE_STACK_CHECK\n#define DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT\n#undef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY\n#undef DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY\n#define DUK_USE_NONSTD_FUNC_STMT\n#define DUK_USE_NONSTD_GETTER_KEY_ARGUMENT\n#define DUK_USE_NONSTD_JSON_ESC_U2028_U2029\n#define DUK_USE_NONSTD_SETTER_KEY_ARGUMENT\n#define DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT\n#define DUK_USE_NUMBER_BUILTIN\n#define DUK_USE_OBJECT_BUILTIN\n#undef DUK_USE_OBJSIZES16\n#undef DUK_USE_PARANOID_ERRORS\n#define DUK_USE_PC2LINE\n#define DUK_USE_PERFORMANCE_BUILTIN\n#undef DUK_USE_PREFER_SIZE\n#undef DUK_USE_PROMISE_BUILTIN\n#define DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS\n#undef DUK_USE_REFCOUNT16\n#define DUK_USE_REFCOUNT32\n#define DUK_USE_REFERENCE_COUNTING\n#define DUK_USE_REFLECT_BUILTIN\n#define DUK_USE_REGEXP_CANON_BITMAP\n#undef DUK_USE_REGEXP_CANON_WORKAROUND\n#define DUK_USE_REGEXP_COMPILER_RECLIMIT 10000\n#define DUK_USE_REGEXP_EXECUTOR_RECLIMIT 10000\n#define DUK_USE_REGEXP_SUPPORT\n#undef DUK_USE_ROM_GLOBAL_CLONE\n#undef DUK_USE_ROM_GLOBAL_INHERIT\n#undef DUK_USE_ROM_OBJECTS\n#define DUK_USE_ROM_PTRCOMP_FIRST 63488L\n#undef DUK_USE_ROM_STRINGS\n#define DUK_USE_SECTION_B\n#undef DUK_USE_SELF_TESTS\n#define DUK_USE_SHEBANG_COMMENTS\n#undef DUK_USE_SHUFFLE_TORTURE\n#define DUK_USE_SOURCE_NONBMP\n#undef DUK_USE_STRHASH16\n#undef DUK_USE_STRHASH_DENSE\n#define DUK_USE_STRHASH_SKIP_SHIFT 5\n#define DUK_USE_STRICT_DECL\n#undef DUK_USE_STRICT_UTF8_SOURCE\n#define DUK_USE_STRING_BUILTIN\n#undef DUK_USE_STRLEN16\n#define DUK_USE_STRTAB_GROW_LIMIT 17\n#define DUK_USE_STRTAB_MAXSIZE 268435456L\n#define DUK_USE_STRTAB_MINSIZE 1024\n#undef DUK_USE_STRTAB_PTRCOMP\n#define DUK_USE_STRTAB_RESIZE_CHECK_MASK 255\n#define DUK_USE_STRTAB_SHRINK_LIMIT 6\n#undef DUK_USE_STRTAB_TORTURE\n#define DUK_USE_SYMBOL_BUILTIN\n#define DUK_USE_TAILCALL\n#define DUK_USE_TARGET_INFO \"unknown\"\n#define DUK_USE_TRACEBACKS\n#define DUK_USE_TRACEBACK_DEPTH 10\n#define DUK_USE_VALSTACK_GROW_SHIFT 2\n#define DUK_USE_VALSTACK_LIMIT 1000000L\n#define DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT 2\n#define DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT 4\n#undef DUK_USE_VALSTACK_UNSAFE\n#define DUK_USE_VERBOSE_ERRORS\n#define DUK_USE_VERBOSE_EXECUTOR_ERRORS\n#define DUK_USE_VOLUNTARY_GC\n#define DUK_USE_ZERO_BUFFER_DATA\n\n/*\n *  You may add overriding #define/#undef directives below for\n *  customization.  You of course cannot un-#include or un-typedef\n *  anything; these require direct changes above.\n */\n\n/* __OVERRIDE_DEFINES__ */\n\n/*\n *  Conditional includes\n */\n\n#if defined(DUK_F_CPP) && defined(DUK_USE_CPP_EXCEPTIONS)\n#include <exception>  /* std::exception */\n#include <stdexcept>  /* std::runtime_error */\n#endif\n\n/*\n *  Date provider selection\n *\n *  User may define DUK_USE_DATE_GET_NOW() etc directly, in which case we'll\n *  rely on an external provider.  If this is not done, revert to previous\n *  behavior and use Unix/Windows built-in provider.\n */\n\n#if defined(DUK_COMPILING_DUKTAPE)\n\n#if defined(DUK_USE_DATE_GET_NOW)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_gettimeofday()\n#elif defined(DUK_USE_DATE_NOW_TIME)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_time()\n#elif defined(DUK_USE_DATE_NOW_WINDOWS)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_windows()\n#elif defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_windows_subms()\n#else\n#error no provider for DUK_USE_DATE_GET_NOW()\n#endif\n\n#if defined(DUK_USE_DATE_GET_LOCAL_TZOFFSET)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S) || defined(DUK_USE_DATE_TZO_GMTIME)\n#define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d)   duk_bi_date_get_local_tzoffset_gmtime((d))\n#elif defined(DUK_USE_DATE_TZO_WINDOWS)\n#define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d)   duk_bi_date_get_local_tzoffset_windows((d))\n#elif defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST)\n#define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d)   duk_bi_date_get_local_tzoffset_windows_no_dst((d))\n#else\n#error no provider for DUK_USE_DATE_GET_LOCAL_TZOFFSET()\n#endif\n\n#if defined(DUK_USE_DATE_PARSE_STRING)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_PRS_STRPTIME)\n#define DUK_USE_DATE_PARSE_STRING(ctx,str)   duk_bi_date_parse_string_strptime((ctx), (str))\n#elif defined(DUK_USE_DATE_PRS_GETDATE)\n#define DUK_USE_DATE_PARSE_STRING(ctx,str)   duk_bi_date_parse_string_getdate((ctx), (str))\n#else\n/* No provider for DUK_USE_DATE_PARSE_STRING(), fall back to ISO 8601 only. */\n#endif\n\n#if defined(DUK_USE_DATE_FORMAT_STRING)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_FMT_STRFTIME)\n#define DUK_USE_DATE_FORMAT_STRING(ctx,parts,tzoffset,flags) \\\n\tduk_bi_date_format_parts_strftime((ctx), (parts), (tzoffset), (flags))\n#else\n/* No provider for DUK_USE_DATE_FORMAT_STRING(), fall back to ISO 8601 only. */\n#endif\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME)\n/* External provider already defined. */\n#elif defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)\n#define DUK_USE_GET_MONOTONIC_TIME(ctx)  duk_bi_date_get_monotonic_time_clock_gettime()\n#elif defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC)\n#define DUK_USE_GET_MONOTONIC_TIME(ctx)  duk_bi_date_get_monotonic_time_windows_qpc()\n#else\n/* No provider for DUK_USE_GET_MONOTONIC_TIME(), fall back to DUK_USE_DATE_GET_NOW(). */\n#endif\n\n#endif  /* DUK_COMPILING_DUKTAPE */\n\n/*\n *  Checks for legacy feature options (DUK_OPT_xxx)\n */\n\n#if defined(DUK_OPT_ASSERTIONS)\n#error unsupported legacy feature option DUK_OPT_ASSERTIONS used\n#endif\n#if defined(DUK_OPT_BUFFEROBJECT_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_BUFFEROBJECT_SUPPORT used\n#endif\n#if defined(DUK_OPT_BUFLEN16)\n#error unsupported legacy feature option DUK_OPT_BUFLEN16 used\n#endif\n#if defined(DUK_OPT_DATAPTR16)\n#error unsupported legacy feature option DUK_OPT_DATAPTR16 used\n#endif\n#if defined(DUK_OPT_DATAPTR_DEC16)\n#error unsupported legacy feature option DUK_OPT_DATAPTR_DEC16 used\n#endif\n#if defined(DUK_OPT_DATAPTR_ENC16)\n#error unsupported legacy feature option DUK_OPT_DATAPTR_ENC16 used\n#endif\n#if defined(DUK_OPT_DDDPRINT)\n#error unsupported legacy feature option DUK_OPT_DDDPRINT used\n#endif\n#if defined(DUK_OPT_DDPRINT)\n#error unsupported legacy feature option DUK_OPT_DDPRINT used\n#endif\n#if defined(DUK_OPT_DEBUG)\n#error unsupported legacy feature option DUK_OPT_DEBUG used\n#endif\n#if defined(DUK_OPT_DEBUGGER_DUMPHEAP)\n#error unsupported legacy feature option DUK_OPT_DEBUGGER_DUMPHEAP used\n#endif\n#if defined(DUK_OPT_DEBUGGER_FWD_LOGGING)\n#error unsupported legacy feature option DUK_OPT_DEBUGGER_FWD_LOGGING used\n#endif\n#if defined(DUK_OPT_DEBUGGER_FWD_PRINTALERT)\n#error unsupported legacy feature option DUK_OPT_DEBUGGER_FWD_PRINTALERT used\n#endif\n#if defined(DUK_OPT_DEBUGGER_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_DEBUGGER_SUPPORT used\n#endif\n#if defined(DUK_OPT_DEBUGGER_TRANSPORT_TORTURE)\n#error unsupported legacy feature option DUK_OPT_DEBUGGER_TRANSPORT_TORTURE used\n#endif\n#if defined(DUK_OPT_DEBUG_BUFSIZE)\n#error unsupported legacy feature option DUK_OPT_DEBUG_BUFSIZE used\n#endif\n#if defined(DUK_OPT_DECLARE)\n#error unsupported legacy feature option DUK_OPT_DECLARE used\n#endif\n#if defined(DUK_OPT_DEEP_C_STACK)\n#error unsupported legacy feature option DUK_OPT_DEEP_C_STACK used\n#endif\n#if defined(DUK_OPT_DLL_BUILD)\n#error unsupported legacy feature option DUK_OPT_DLL_BUILD used\n#endif\n#if defined(DUK_OPT_DPRINT)\n#error unsupported legacy feature option DUK_OPT_DPRINT used\n#endif\n#if defined(DUK_OPT_DPRINT_COLORS)\n#error unsupported legacy feature option DUK_OPT_DPRINT_COLORS used\n#endif\n#if defined(DUK_OPT_DPRINT_RDTSC)\n#error unsupported legacy feature option DUK_OPT_DPRINT_RDTSC used\n#endif\n#if defined(DUK_OPT_EXEC_TIMEOUT_CHECK)\n#error unsupported legacy feature option DUK_OPT_EXEC_TIMEOUT_CHECK used\n#endif\n#if defined(DUK_OPT_EXTERNAL_STRINGS)\n#error unsupported legacy feature option DUK_OPT_EXTERNAL_STRINGS used\n#endif\n#if defined(DUK_OPT_EXTSTR_FREE)\n#error unsupported legacy feature option DUK_OPT_EXTSTR_FREE used\n#endif\n#if defined(DUK_OPT_EXTSTR_INTERN_CHECK)\n#error unsupported legacy feature option DUK_OPT_EXTSTR_INTERN_CHECK used\n#endif\n#if defined(DUK_OPT_FASTINT)\n#error unsupported legacy feature option DUK_OPT_FASTINT used\n#endif\n#if defined(DUK_OPT_FORCE_ALIGN)\n#error unsupported legacy feature option DUK_OPT_FORCE_ALIGN used\n#endif\n#if defined(DUK_OPT_FORCE_BYTEORDER)\n#error unsupported legacy feature option DUK_OPT_FORCE_BYTEORDER used\n#endif\n#if defined(DUK_OPT_FUNCPTR16)\n#error unsupported legacy feature option DUK_OPT_FUNCPTR16 used\n#endif\n#if defined(DUK_OPT_FUNCPTR_DEC16)\n#error unsupported legacy feature option DUK_OPT_FUNCPTR_DEC16 used\n#endif\n#if defined(DUK_OPT_FUNCPTR_ENC16)\n#error unsupported legacy feature option DUK_OPT_FUNCPTR_ENC16 used\n#endif\n#if defined(DUK_OPT_FUNC_NONSTD_CALLER_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_FUNC_NONSTD_CALLER_PROPERTY used\n#endif\n#if defined(DUK_OPT_FUNC_NONSTD_SOURCE_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_FUNC_NONSTD_SOURCE_PROPERTY used\n#endif\n#if defined(DUK_OPT_GC_TORTURE)\n#error unsupported legacy feature option DUK_OPT_GC_TORTURE used\n#endif\n#if defined(DUK_OPT_HAVE_CUSTOM_H)\n#error unsupported legacy feature option DUK_OPT_HAVE_CUSTOM_H used\n#endif\n#if defined(DUK_OPT_HEAPPTR16)\n#error unsupported legacy feature option DUK_OPT_HEAPPTR16 used\n#endif\n#if defined(DUK_OPT_HEAPPTR_DEC16)\n#error unsupported legacy feature option DUK_OPT_HEAPPTR_DEC16 used\n#endif\n#if defined(DUK_OPT_HEAPPTR_ENC16)\n#error unsupported legacy feature option DUK_OPT_HEAPPTR_ENC16 used\n#endif\n#if defined(DUK_OPT_INTERRUPT_COUNTER)\n#error unsupported legacy feature option DUK_OPT_INTERRUPT_COUNTER used\n#endif\n#if defined(DUK_OPT_JSON_STRINGIFY_FASTPATH)\n#error unsupported legacy feature option DUK_OPT_JSON_STRINGIFY_FASTPATH used\n#endif\n#if defined(DUK_OPT_LIGHTFUNC_BUILTINS)\n#error unsupported legacy feature option DUK_OPT_LIGHTFUNC_BUILTINS used\n#endif\n#if defined(DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY used\n#endif\n#if defined(DUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY used\n#endif\n#if defined(DUK_OPT_NO_ARRAY_SPLICE_NONSTD_DELCOUNT)\n#error unsupported legacy feature option DUK_OPT_NO_ARRAY_SPLICE_NONSTD_DELCOUNT used\n#endif\n#if defined(DUK_OPT_NO_AUGMENT_ERRORS)\n#error unsupported legacy feature option DUK_OPT_NO_AUGMENT_ERRORS used\n#endif\n#if defined(DUK_OPT_NO_BROWSER_LIKE)\n#error unsupported legacy feature option DUK_OPT_NO_BROWSER_LIKE used\n#endif\n#if defined(DUK_OPT_NO_BUFFEROBJECT_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_NO_BUFFEROBJECT_SUPPORT used\n#endif\n#if defined(DUK_OPT_NO_BYTECODE_DUMP_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_NO_BYTECODE_DUMP_SUPPORT used\n#endif\n#if defined(DUK_OPT_NO_COMMONJS_MODULES)\n#error unsupported legacy feature option DUK_OPT_NO_COMMONJS_MODULES used\n#endif\n#if defined(DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY used\n#endif\n#if defined(DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF)\n#error unsupported legacy feature option DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF used\n#endif\n#if defined(DUK_OPT_NO_ES6_PROXY)\n#error unsupported legacy feature option DUK_OPT_NO_ES6_PROXY used\n#endif\n#if defined(DUK_OPT_NO_FILE_IO)\n#error unsupported legacy feature option DUK_OPT_NO_FILE_IO used\n#endif\n#if defined(DUK_OPT_NO_FUNC_STMT)\n#error unsupported legacy feature option DUK_OPT_NO_FUNC_STMT used\n#endif\n#if defined(DUK_OPT_NO_JC)\n#error unsupported legacy feature option DUK_OPT_NO_JC used\n#endif\n#if defined(DUK_OPT_NO_JSONC)\n#error unsupported legacy feature option DUK_OPT_NO_JSONC used\n#endif\n#if defined(DUK_OPT_NO_JSONX)\n#error unsupported legacy feature option DUK_OPT_NO_JSONX used\n#endif\n#if defined(DUK_OPT_NO_JX)\n#error unsupported legacy feature option DUK_OPT_NO_JX used\n#endif\n#if defined(DUK_OPT_NO_MARK_AND_SWEEP)\n#error unsupported legacy feature option DUK_OPT_NO_MARK_AND_SWEEP used\n#endif\n#if defined(DUK_OPT_NO_MS_STRINGTABLE_RESIZE)\n#error unsupported legacy feature option DUK_OPT_NO_MS_STRINGTABLE_RESIZE used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_ACCESSOR_KEY_ARGUMENT)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_ACCESSOR_KEY_ARGUMENT used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_ARRAY_CONCAT_TRAILER)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_ARRAY_CONCAT_TRAILER used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_ARRAY_MAP_TRAILER)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_ARRAY_MAP_TRAILER used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_FUNC_STMT)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_FUNC_STMT used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_JSON_ESC_U2028_U2029)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_JSON_ESC_U2028_U2029 used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_STRING_FROMCHARCODE_32BIT)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_STRING_FROMCHARCODE_32BIT used\n#endif\n#if defined(DUK_OPT_NO_OBJECT_ES6_PROTO_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_NO_OBJECT_ES6_PROTO_PROPERTY used\n#endif\n#if defined(DUK_OPT_NO_OBJECT_ES6_SETPROTOTYPEOF)\n#error unsupported legacy feature option DUK_OPT_NO_OBJECT_ES6_SETPROTOTYPEOF used\n#endif\n#if defined(DUK_OPT_NO_OCTAL_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_NO_OCTAL_SUPPORT used\n#endif\n#if defined(DUK_OPT_NO_PACKED_TVAL)\n#error unsupported legacy feature option DUK_OPT_NO_PACKED_TVAL used\n#endif\n#if defined(DUK_OPT_NO_PC2LINE)\n#error unsupported legacy feature option DUK_OPT_NO_PC2LINE used\n#endif\n#if defined(DUK_OPT_NO_REFERENCE_COUNTING)\n#error unsupported legacy feature option DUK_OPT_NO_REFERENCE_COUNTING used\n#endif\n#if defined(DUK_OPT_NO_REGEXP_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_NO_REGEXP_SUPPORT used\n#endif\n#if defined(DUK_OPT_NO_SECTION_B)\n#error unsupported legacy feature option DUK_OPT_NO_SECTION_B used\n#endif\n#if defined(DUK_OPT_NO_SOURCE_NONBMP)\n#error unsupported legacy feature option DUK_OPT_NO_SOURCE_NONBMP used\n#endif\n#if defined(DUK_OPT_NO_STRICT_DECL)\n#error unsupported legacy feature option DUK_OPT_NO_STRICT_DECL used\n#endif\n#if defined(DUK_OPT_NO_TRACEBACKS)\n#error unsupported legacy feature option DUK_OPT_NO_TRACEBACKS used\n#endif\n#if defined(DUK_OPT_NO_VERBOSE_ERRORS)\n#error unsupported legacy feature option DUK_OPT_NO_VERBOSE_ERRORS used\n#endif\n#if defined(DUK_OPT_NO_VOLUNTARY_GC)\n#error unsupported legacy feature option DUK_OPT_NO_VOLUNTARY_GC used\n#endif\n#if defined(DUK_OPT_NO_ZERO_BUFFER_DATA)\n#error unsupported legacy feature option DUK_OPT_NO_ZERO_BUFFER_DATA used\n#endif\n#if defined(DUK_OPT_OBJSIZES16)\n#error unsupported legacy feature option DUK_OPT_OBJSIZES16 used\n#endif\n#if defined(DUK_OPT_PANIC_HANDLER)\n#error unsupported legacy feature option DUK_OPT_PANIC_HANDLER used\n#endif\n#if defined(DUK_OPT_REFCOUNT16)\n#error unsupported legacy feature option DUK_OPT_REFCOUNT16 used\n#endif\n#if defined(DUK_OPT_SEGFAULT_ON_PANIC)\n#error unsupported legacy feature option DUK_OPT_SEGFAULT_ON_PANIC used\n#endif\n#if defined(DUK_OPT_SELF_TESTS)\n#error unsupported legacy feature option DUK_OPT_SELF_TESTS used\n#endif\n#if defined(DUK_OPT_SETJMP)\n#error unsupported legacy feature option DUK_OPT_SETJMP used\n#endif\n#if defined(DUK_OPT_SHUFFLE_TORTURE)\n#error unsupported legacy feature option DUK_OPT_SHUFFLE_TORTURE used\n#endif\n#if defined(DUK_OPT_SIGSETJMP)\n#error unsupported legacy feature option DUK_OPT_SIGSETJMP used\n#endif\n#if defined(DUK_OPT_STRHASH16)\n#error unsupported legacy feature option DUK_OPT_STRHASH16 used\n#endif\n#if defined(DUK_OPT_STRICT_UTF8_SOURCE)\n#error unsupported legacy feature option DUK_OPT_STRICT_UTF8_SOURCE used\n#endif\n#if defined(DUK_OPT_STRLEN16)\n#error unsupported legacy feature option DUK_OPT_STRLEN16 used\n#endif\n#if defined(DUK_OPT_STRTAB_CHAIN)\n#error unsupported legacy feature option DUK_OPT_STRTAB_CHAIN used\n#endif\n#if defined(DUK_OPT_STRTAB_CHAIN_SIZE)\n#error unsupported legacy feature option DUK_OPT_STRTAB_CHAIN_SIZE used\n#endif\n#if defined(DUK_OPT_TARGET_INFO)\n#error unsupported legacy feature option DUK_OPT_TARGET_INFO used\n#endif\n#if defined(DUK_OPT_TRACEBACK_DEPTH)\n#error unsupported legacy feature option DUK_OPT_TRACEBACK_DEPTH used\n#endif\n#if defined(DUK_OPT_UNDERSCORE_SETJMP)\n#error unsupported legacy feature option DUK_OPT_UNDERSCORE_SETJMP used\n#endif\n#if defined(DUK_OPT_USER_INITJS)\n#error unsupported legacy feature option DUK_OPT_USER_INITJS used\n#endif\n\n/*\n *  Checks for config option consistency (DUK_USE_xxx)\n */\n\n#if defined(DUK_USE_32BIT_PTRS)\n#error unsupported config option used (option has been removed): DUK_USE_32BIT_PTRS\n#endif\n#if defined(DUK_USE_ALIGN_4)\n#error unsupported config option used (option has been removed): DUK_USE_ALIGN_4\n#endif\n#if defined(DUK_USE_ALIGN_8)\n#error unsupported config option used (option has been removed): DUK_USE_ALIGN_8\n#endif\n#if defined(DUK_USE_BROWSER_LIKE)\n#error unsupported config option used (option has been removed): DUK_USE_BROWSER_LIKE\n#endif\n#if defined(DUK_USE_BUILTIN_INITJS)\n#error unsupported config option used (option has been removed): DUK_USE_BUILTIN_INITJS\n#endif\n#if defined(DUK_USE_BYTEORDER_FORCED)\n#error unsupported config option used (option has been removed): DUK_USE_BYTEORDER_FORCED\n#endif\n#if defined(DUK_USE_COMMONJS_MODULES)\n#error unsupported config option used (option has been removed): DUK_USE_COMMONJS_MODULES\n#endif\n#if defined(DUK_USE_DATAPTR_DEC16) && !defined(DUK_USE_DATAPTR16)\n#error config option DUK_USE_DATAPTR_DEC16 requires option DUK_USE_DATAPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_DATAPTR_ENC16) && !defined(DUK_USE_DATAPTR16)\n#error config option DUK_USE_DATAPTR_ENC16 requires option DUK_USE_DATAPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_DDDPRINT)\n#error unsupported config option used (option has been removed): DUK_USE_DDDPRINT\n#endif\n#if defined(DUK_USE_DDPRINT)\n#error unsupported config option used (option has been removed): DUK_USE_DDPRINT\n#endif\n#if defined(DUK_USE_DEBUGGER_FWD_LOGGING)\n#error unsupported config option used (option has been removed): DUK_USE_DEBUGGER_FWD_LOGGING\n#endif\n#if defined(DUK_USE_DEBUGGER_FWD_PRINTALERT)\n#error unsupported config option used (option has been removed): DUK_USE_DEBUGGER_FWD_PRINTALERT\n#endif\n#if defined(DUK_USE_DEBUGGER_SUPPORT) && !defined(DUK_USE_INTERRUPT_COUNTER)\n#error config option DUK_USE_DEBUGGER_SUPPORT requires option DUK_USE_INTERRUPT_COUNTER (which is missing)\n#endif\n#if defined(DUK_USE_DEEP_C_STACK)\n#error unsupported config option used (option has been removed): DUK_USE_DEEP_C_STACK\n#endif\n#if defined(DUK_USE_DOUBLE_BE)\n#error unsupported config option used (option has been removed): DUK_USE_DOUBLE_BE\n#endif\n#if defined(DUK_USE_DOUBLE_BE) && defined(DUK_USE_DOUBLE_LE)\n#error config option DUK_USE_DOUBLE_BE conflicts with option DUK_USE_DOUBLE_LE (which is also defined)\n#endif\n#if defined(DUK_USE_DOUBLE_BE) && defined(DUK_USE_DOUBLE_ME)\n#error config option DUK_USE_DOUBLE_BE conflicts with option DUK_USE_DOUBLE_ME (which is also defined)\n#endif\n#if defined(DUK_USE_DOUBLE_LE)\n#error unsupported config option used (option has been removed): DUK_USE_DOUBLE_LE\n#endif\n#if defined(DUK_USE_DOUBLE_LE) && defined(DUK_USE_DOUBLE_BE)\n#error config option DUK_USE_DOUBLE_LE conflicts with option DUK_USE_DOUBLE_BE (which is also defined)\n#endif\n#if defined(DUK_USE_DOUBLE_LE) && defined(DUK_USE_DOUBLE_ME)\n#error config option DUK_USE_DOUBLE_LE conflicts with option DUK_USE_DOUBLE_ME (which is also defined)\n#endif\n#if defined(DUK_USE_DOUBLE_ME)\n#error unsupported config option used (option has been removed): DUK_USE_DOUBLE_ME\n#endif\n#if defined(DUK_USE_DOUBLE_ME) && defined(DUK_USE_DOUBLE_LE)\n#error config option DUK_USE_DOUBLE_ME conflicts with option DUK_USE_DOUBLE_LE (which is also defined)\n#endif\n#if defined(DUK_USE_DOUBLE_ME) && defined(DUK_USE_DOUBLE_BE)\n#error config option DUK_USE_DOUBLE_ME conflicts with option DUK_USE_DOUBLE_BE (which is also defined)\n#endif\n#if defined(DUK_USE_DPRINT)\n#error unsupported config option used (option has been removed): DUK_USE_DPRINT\n#endif\n#if defined(DUK_USE_DPRINT) && !defined(DUK_USE_DEBUG)\n#error config option DUK_USE_DPRINT requires option DUK_USE_DEBUG (which is missing)\n#endif\n#if defined(DUK_USE_DPRINT_COLORS)\n#error unsupported config option used (option has been removed): DUK_USE_DPRINT_COLORS\n#endif\n#if defined(DUK_USE_DPRINT_RDTSC)\n#error unsupported config option used (option has been removed): DUK_USE_DPRINT_RDTSC\n#endif\n#if defined(DUK_USE_ES6_REGEXP_BRACES)\n#error unsupported config option used (option has been removed): DUK_USE_ES6_REGEXP_BRACES\n#endif\n#if defined(DUK_USE_ESBC_MAX_BYTES) && !defined(DUK_USE_ESBC_LIMITS)\n#error config option DUK_USE_ESBC_MAX_BYTES requires option DUK_USE_ESBC_LIMITS (which is missing)\n#endif\n#if defined(DUK_USE_ESBC_MAX_LINENUMBER) && !defined(DUK_USE_ESBC_LIMITS)\n#error config option DUK_USE_ESBC_MAX_LINENUMBER requires option DUK_USE_ESBC_LIMITS (which is missing)\n#endif\n#if defined(DUK_USE_EXEC_TIMEOUT_CHECK) && !defined(DUK_USE_INTERRUPT_COUNTER)\n#error config option DUK_USE_EXEC_TIMEOUT_CHECK requires option DUK_USE_INTERRUPT_COUNTER (which is missing)\n#endif\n#if defined(DUK_USE_EXTSTR_FREE) && !defined(DUK_USE_HSTRING_EXTDATA)\n#error config option DUK_USE_EXTSTR_FREE requires option DUK_USE_HSTRING_EXTDATA (which is missing)\n#endif\n#if defined(DUK_USE_EXTSTR_INTERN_CHECK) && !defined(DUK_USE_HSTRING_EXTDATA)\n#error config option DUK_USE_EXTSTR_INTERN_CHECK requires option DUK_USE_HSTRING_EXTDATA (which is missing)\n#endif\n#if defined(DUK_USE_FASTINT) && !defined(DUK_USE_64BIT_OPS)\n#error config option DUK_USE_FASTINT requires option DUK_USE_64BIT_OPS (which is missing)\n#endif\n#if defined(DUK_USE_FILE_IO)\n#error unsupported config option used (option has been removed): DUK_USE_FILE_IO\n#endif\n#if defined(DUK_USE_FULL_TVAL)\n#error unsupported config option used (option has been removed): DUK_USE_FULL_TVAL\n#endif\n#if defined(DUK_USE_FUNCPTR_DEC16) && !defined(DUK_USE_FUNCPTR16)\n#error config option DUK_USE_FUNCPTR_DEC16 requires option DUK_USE_FUNCPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_FUNCPTR_ENC16) && !defined(DUK_USE_FUNCPTR16)\n#error config option DUK_USE_FUNCPTR_ENC16 requires option DUK_USE_FUNCPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS)\n#error unsupported config option used (option has been removed): DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS\n#endif\n#if defined(DUK_USE_HEAPPTR16) && defined(DUK_USE_DEBUG)\n#error config option DUK_USE_HEAPPTR16 conflicts with option DUK_USE_DEBUG (which is also defined)\n#endif\n#if defined(DUK_USE_HEAPPTR_DEC16) && !defined(DUK_USE_HEAPPTR16)\n#error config option DUK_USE_HEAPPTR_DEC16 requires option DUK_USE_HEAPPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_HEAPPTR_ENC16) && !defined(DUK_USE_HEAPPTR16)\n#error config option DUK_USE_HEAPPTR_ENC16 requires option DUK_USE_HEAPPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_INTEGER_BE)\n#error unsupported config option used (option has been removed): DUK_USE_INTEGER_BE\n#endif\n#if defined(DUK_USE_INTEGER_BE) && defined(DUK_USE_INTEGER_LE)\n#error config option DUK_USE_INTEGER_BE conflicts with option DUK_USE_INTEGER_LE (which is also defined)\n#endif\n#if defined(DUK_USE_INTEGER_BE) && defined(DUK_USE_INTEGER_ME)\n#error config option DUK_USE_INTEGER_BE conflicts with option DUK_USE_INTEGER_ME (which is also defined)\n#endif\n#if defined(DUK_USE_INTEGER_LE)\n#error unsupported config option used (option has been removed): DUK_USE_INTEGER_LE\n#endif\n#if defined(DUK_USE_INTEGER_LE) && defined(DUK_USE_INTEGER_BE)\n#error config option DUK_USE_INTEGER_LE conflicts with option DUK_USE_INTEGER_BE (which is also defined)\n#endif\n#if defined(DUK_USE_INTEGER_LE) && defined(DUK_USE_INTEGER_ME)\n#error config option DUK_USE_INTEGER_LE conflicts with option DUK_USE_INTEGER_ME (which is also defined)\n#endif\n#if defined(DUK_USE_INTEGER_ME)\n#error unsupported config option used (option has been removed): DUK_USE_INTEGER_ME\n#endif\n#if defined(DUK_USE_INTEGER_ME) && defined(DUK_USE_INTEGER_LE)\n#error config option DUK_USE_INTEGER_ME conflicts with option DUK_USE_INTEGER_LE (which is also defined)\n#endif\n#if defined(DUK_USE_INTEGER_ME) && defined(DUK_USE_INTEGER_BE)\n#error config option DUK_USE_INTEGER_ME conflicts with option DUK_USE_INTEGER_BE (which is also defined)\n#endif\n#if defined(DUK_USE_MARKANDSWEEP_FINALIZER_TORTURE)\n#error unsupported config option used (option has been removed): DUK_USE_MARKANDSWEEP_FINALIZER_TORTURE\n#endif\n#if defined(DUK_USE_MARK_AND_SWEEP)\n#error unsupported config option used (option has been removed): DUK_USE_MARK_AND_SWEEP\n#endif\n#if defined(DUK_USE_MATH_FMAX)\n#error unsupported config option used (option has been removed): DUK_USE_MATH_FMAX\n#endif\n#if defined(DUK_USE_MATH_FMIN)\n#error unsupported config option used (option has been removed): DUK_USE_MATH_FMIN\n#endif\n#if defined(DUK_USE_MATH_ROUND)\n#error unsupported config option used (option has been removed): DUK_USE_MATH_ROUND\n#endif\n#if defined(DUK_USE_MS_STRINGTABLE_RESIZE)\n#error unsupported config option used (option has been removed): DUK_USE_MS_STRINGTABLE_RESIZE\n#endif\n#if defined(DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER)\n#error unsupported config option used (option has been removed): DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER\n#endif\n#if defined(DUK_USE_NONSTD_ARRAY_MAP_TRAILER)\n#error unsupported config option used (option has been removed): DUK_USE_NONSTD_ARRAY_MAP_TRAILER\n#endif\n#if defined(DUK_USE_NONSTD_REGEXP_DOLLAR_ESCAPE)\n#error unsupported config option used (option has been removed): DUK_USE_NONSTD_REGEXP_DOLLAR_ESCAPE\n#endif\n#if defined(DUK_USE_NO_DOUBLE_ALIASING_SELFTEST)\n#error unsupported config option used (option has been removed): DUK_USE_NO_DOUBLE_ALIASING_SELFTEST\n#endif\n#if defined(DUK_USE_OCTAL_SUPPORT)\n#error unsupported config option used (option has been removed): DUK_USE_OCTAL_SUPPORT\n#endif\n#if defined(DUK_USE_PACKED_TVAL_POSSIBLE)\n#error unsupported config option used (option has been removed): DUK_USE_PACKED_TVAL_POSSIBLE\n#endif\n#if defined(DUK_USE_PANIC_ABORT)\n#error unsupported config option used (option has been removed): DUK_USE_PANIC_ABORT\n#endif\n#if defined(DUK_USE_PANIC_EXIT)\n#error unsupported config option used (option has been removed): DUK_USE_PANIC_EXIT\n#endif\n#if defined(DUK_USE_PANIC_HANDLER)\n#error unsupported config option used (option has been removed): DUK_USE_PANIC_HANDLER\n#endif\n#if defined(DUK_USE_PANIC_SEGFAULT)\n#error unsupported config option used (option has been removed): DUK_USE_PANIC_SEGFAULT\n#endif\n#if defined(DUK_USE_POW_NETBSD_WORKAROUND)\n#error unsupported config option used (option has been removed): DUK_USE_POW_NETBSD_WORKAROUND\n#endif\n#if defined(DUK_USE_RDTSC)\n#error unsupported config option used (option has been removed): DUK_USE_RDTSC\n#endif\n#if defined(DUK_USE_REFZERO_FINALIZER_TORTURE)\n#error unsupported config option used (option has been removed): DUK_USE_REFZERO_FINALIZER_TORTURE\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) && !defined(DUK_USE_ROM_STRINGS)\n#error config option DUK_USE_ROM_GLOBAL_CLONE requires option DUK_USE_ROM_STRINGS (which is missing)\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) && !defined(DUK_USE_ROM_OBJECTS)\n#error config option DUK_USE_ROM_GLOBAL_CLONE requires option DUK_USE_ROM_OBJECTS (which is missing)\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) && defined(DUK_USE_ROM_GLOBAL_INHERIT)\n#error config option DUK_USE_ROM_GLOBAL_CLONE conflicts with option DUK_USE_ROM_GLOBAL_INHERIT (which is also defined)\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_INHERIT) && !defined(DUK_USE_ROM_STRINGS)\n#error config option DUK_USE_ROM_GLOBAL_INHERIT requires option DUK_USE_ROM_STRINGS (which is missing)\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_INHERIT) && !defined(DUK_USE_ROM_OBJECTS)\n#error config option DUK_USE_ROM_GLOBAL_INHERIT requires option DUK_USE_ROM_OBJECTS (which is missing)\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_INHERIT) && defined(DUK_USE_ROM_GLOBAL_CLONE)\n#error config option DUK_USE_ROM_GLOBAL_INHERIT conflicts with option DUK_USE_ROM_GLOBAL_CLONE (which is also defined)\n#endif\n#if defined(DUK_USE_ROM_OBJECTS) && !defined(DUK_USE_ROM_STRINGS)\n#error config option DUK_USE_ROM_OBJECTS requires option DUK_USE_ROM_STRINGS (which is missing)\n#endif\n#if defined(DUK_USE_ROM_STRINGS) && !defined(DUK_USE_ROM_OBJECTS)\n#error config option DUK_USE_ROM_STRINGS requires option DUK_USE_ROM_OBJECTS (which is missing)\n#endif\n#if defined(DUK_USE_SETJMP)\n#error unsupported config option used (option has been removed): DUK_USE_SETJMP\n#endif\n#if defined(DUK_USE_SIGSETJMP)\n#error unsupported config option used (option has been removed): DUK_USE_SIGSETJMP\n#endif\n#if defined(DUK_USE_STRTAB_CHAIN)\n#error unsupported config option used (option has been removed): DUK_USE_STRTAB_CHAIN\n#endif\n#if defined(DUK_USE_STRTAB_CHAIN_SIZE)\n#error unsupported config option used (option has been removed): DUK_USE_STRTAB_CHAIN_SIZE\n#endif\n#if defined(DUK_USE_STRTAB_CHAIN_SIZE) && !defined(DUK_USE_STRTAB_CHAIN)\n#error config option DUK_USE_STRTAB_CHAIN_SIZE requires option DUK_USE_STRTAB_CHAIN (which is missing)\n#endif\n#if defined(DUK_USE_STRTAB_PROBE)\n#error unsupported config option used (option has been removed): DUK_USE_STRTAB_PROBE\n#endif\n#if defined(DUK_USE_STRTAB_PTRCOMP) && !defined(DUK_USE_HEAPPTR16)\n#error config option DUK_USE_STRTAB_PTRCOMP requires option DUK_USE_HEAPPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_TAILCALL) && defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n#error config option DUK_USE_TAILCALL conflicts with option DUK_USE_NONSTD_FUNC_CALLER_PROPERTY (which is also defined)\n#endif\n#if defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)\n#error unsupported config option used (option has been removed): DUK_USE_UNALIGNED_ACCESSES_POSSIBLE\n#endif\n#if defined(DUK_USE_UNDERSCORE_SETJMP)\n#error unsupported config option used (option has been removed): DUK_USE_UNDERSCORE_SETJMP\n#endif\n#if defined(DUK_USE_USER_DECLARE)\n#error unsupported config option used (option has been removed): DUK_USE_USER_DECLARE\n#endif\n#if defined(DUK_USE_USER_INITJS)\n#error unsupported config option used (option has been removed): DUK_USE_USER_INITJS\n#endif\n\n#if defined(DUK_USE_CPP_EXCEPTIONS) && !defined(__cplusplus)\n#error DUK_USE_CPP_EXCEPTIONS enabled but not compiling with a C++ compiler\n#endif\n\n/*\n *  Convert DUK_USE_BYTEORDER, from whatever source, into currently used\n *  internal defines.  If detection failed, #error out.\n */\n\n#if defined(DUK_USE_BYTEORDER)\n#if (DUK_USE_BYTEORDER == 1)\n#define DUK_USE_INTEGER_LE\n#define DUK_USE_DOUBLE_LE\n#elif (DUK_USE_BYTEORDER == 2)\n#define DUK_USE_INTEGER_LE  /* integer endianness is little on purpose */\n#define DUK_USE_DOUBLE_ME\n#elif (DUK_USE_BYTEORDER == 3)\n#define DUK_USE_INTEGER_BE\n#define DUK_USE_DOUBLE_BE\n#else\n#error unsupported: byte order invalid\n#endif  /* byte order */\n#else\n#error unsupported: byte order detection failed\n#endif  /* defined(DUK_USE_BYTEORDER) */\n\n#endif  /* DUK_CONFIG_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src/duk_source_meta.json",
    "content": "{\n    \"comment\": \"Metadata for Duktape sources\", \n    \"duk_version_string\": \"2.4.0\", \n    \"type\": \"duk_source_meta\", \n    \"line_map\": [\n        {\n            \"original_line\": 1, \n            \"combined_line\": 155, \n            \"original_file\": \"duk_replacements.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 165, \n            \"original_file\": \"duk_internal.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 203, \n            \"original_file\": \"duk_dblunion.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 628, \n            \"original_file\": \"duk_replacements.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 659, \n            \"original_file\": \"duk_jmpbuf.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 685, \n            \"original_file\": \"duk_exception.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 717, \n            \"original_file\": \"duk_forwdecl.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 853, \n            \"original_file\": \"duk_tval.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 1494, \n            \"original_file\": \"duk_builtins.h\"\n        }, \n        {\n            \"original_line\": 44, \n            \"combined_line\": 2281, \n            \"original_file\": \"duk_internal.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 2284, \n            \"original_file\": \"duk_util.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 2992, \n            \"original_file\": \"duk_strings.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 3161, \n            \"original_file\": \"duk_js_bytecode.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 3645, \n            \"original_file\": \"duk_lexer.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 4085, \n            \"original_file\": \"duk_js_compiler.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 4314, \n            \"original_file\": \"duk_regexp.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 4400, \n            \"original_file\": \"duk_heaphdr.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 4699, \n            \"original_file\": \"duk_refcount.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 5426, \n            \"original_file\": \"duk_api_internal.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 5792, \n            \"original_file\": \"duk_hstring.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 6047, \n            \"original_file\": \"duk_hobject.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 7030, \n            \"original_file\": \"duk_hcompfunc.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 7305, \n            \"original_file\": \"duk_hnatfunc.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 7346, \n            \"original_file\": \"duk_hboundfunc.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 7385, \n            \"original_file\": \"duk_hbufobj.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 7514, \n            \"original_file\": \"duk_hthread.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 7924, \n            \"original_file\": \"duk_harray.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 7974, \n            \"original_file\": \"duk_henv.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 8021, \n            \"original_file\": \"duk_hbuffer.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 8359, \n            \"original_file\": \"duk_hproxy.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 8387, \n            \"original_file\": \"duk_heap.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 9115, \n            \"original_file\": \"duk_debugger.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 9268, \n            \"original_file\": \"duk_debug.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 9454, \n            \"original_file\": \"duk_error.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 9981, \n            \"original_file\": \"duk_unicode.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 10272, \n            \"original_file\": \"duk_json.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 10342, \n            \"original_file\": \"duk_js.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 10458, \n            \"original_file\": \"duk_numconv.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 10564, \n            \"original_file\": \"duk_bi_protos.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 10647, \n            \"original_file\": \"duk_selftest.h\"\n        }, \n        {\n            \"original_line\": 75, \n            \"combined_line\": 10663, \n            \"original_file\": \"duk_internal.h\"\n        }, \n        {\n            \"original_line\": 10, \n            \"combined_line\": 10666, \n            \"original_file\": \"duk_replacements.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 10740, \n            \"original_file\": \"duk_debug_macros.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 10832, \n            \"original_file\": \"duk_builtins.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 11689, \n            \"original_file\": \"duk_error_macros.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 11845, \n            \"original_file\": \"duk_unicode_support.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 13027, \n            \"original_file\": \"duk_util_misc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 13211, \n            \"original_file\": \"duk_hobject_class.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 13341, \n            \"original_file\": \"duk_alloc_default.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 13376, \n            \"original_file\": \"duk_api_buffer.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 13450, \n            \"original_file\": \"duk_api_bytecode.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 14219, \n            \"original_file\": \"duk_api_call.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 14736, \n            \"original_file\": \"duk_api_codec.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 15663, \n            \"original_file\": \"duk_api_compile.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 15836, \n            \"original_file\": \"duk_api_debug.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 16098, \n            \"original_file\": \"duk_api_heap.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 16304, \n            \"original_file\": \"duk_api_inspect.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 16550, \n            \"original_file\": \"duk_api_memory.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 16631, \n            \"original_file\": \"duk_api_object.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 17682, \n            \"original_file\": \"duk_api_random.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 17692, \n            \"original_file\": \"duk_api_stack.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 24647, \n            \"original_file\": \"duk_api_string.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 25026, \n            \"original_file\": \"duk_api_time.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 25137, \n            \"original_file\": \"duk_bi_array.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 26795, \n            \"original_file\": \"duk_bi_boolean.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 26865, \n            \"original_file\": \"duk_bi_buffer.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 29802, \n            \"original_file\": \"duk_bi_date.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 31621, \n            \"original_file\": \"duk_bi_date_unix.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 31951, \n            \"original_file\": \"duk_bi_date_windows.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 32145, \n            \"original_file\": \"duk_bi_duktape.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 32304, \n            \"original_file\": \"duk_bi_encoding.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 32843, \n            \"original_file\": \"duk_bi_error.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 33236, \n            \"original_file\": \"duk_bi_function.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 33690, \n            \"original_file\": \"duk_bi_global.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 34422, \n            \"original_file\": \"duk_bi_json.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 37692, \n            \"original_file\": \"duk_bi_math.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 38211, \n            \"original_file\": \"duk_bi_number.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 38492, \n            \"original_file\": \"duk_bi_object.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 39296, \n            \"original_file\": \"duk_bi_performance.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 39328, \n            \"original_file\": \"duk_bi_pointer.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 39404, \n            \"original_file\": \"duk_bi_promise.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 39449, \n            \"original_file\": \"duk_bi_proxy.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 39546, \n            \"original_file\": \"duk_bi_reflect.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 39646, \n            \"original_file\": \"duk_bi_regexp.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 39873, \n            \"original_file\": \"duk_bi_string.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 41454, \n            \"original_file\": \"duk_bi_symbol.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 41625, \n            \"original_file\": \"duk_bi_thread.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 41952, \n            \"original_file\": \"duk_bi_thrower.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 41962, \n            \"original_file\": \"duk_debug_fixedbuffer.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 42032, \n            \"original_file\": \"duk_debug_vsnprintf.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 43133, \n            \"original_file\": \"duk_debugger.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 46048, \n            \"original_file\": \"duk_error_augment.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 46616, \n            \"original_file\": \"duk_error_longjmp.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 46720, \n            \"original_file\": \"duk_error_misc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 46895, \n            \"original_file\": \"duk_error_throw.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 47058, \n            \"original_file\": \"duk_hbuffer_alloc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 47191, \n            \"original_file\": \"duk_hbuffer_assert.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 47205, \n            \"original_file\": \"duk_hbuffer_ops.c\"\n        }, \n        {\n            \"original_line\": 2, \n            \"combined_line\": 47285, \n            \"original_file\": \"duk_hbufobj_misc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 47305, \n            \"original_file\": \"duk_heap_alloc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 48531, \n            \"original_file\": \"duk_heap_finalize.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 48977, \n            \"original_file\": \"duk_heap_hashstring.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 49099, \n            \"original_file\": \"duk_heap_markandsweep.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 50582, \n            \"original_file\": \"duk_heap_memory.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 50948, \n            \"original_file\": \"duk_heap_misc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 51136, \n            \"original_file\": \"duk_heap_refcount.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 51983, \n            \"original_file\": \"duk_heap_stringcache.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 52293, \n            \"original_file\": \"duk_heap_stringtable.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 53343, \n            \"original_file\": \"duk_heaphdr_assert.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 53422, \n            \"original_file\": \"duk_hobject_alloc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 53694, \n            \"original_file\": \"duk_hobject_assert.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 53822, \n            \"original_file\": \"duk_hobject_enum.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 54532, \n            \"original_file\": \"duk_hobject_misc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 54586, \n            \"original_file\": \"duk_hobject_pc2line.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 54831, \n            \"original_file\": \"duk_hobject_props.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 61043, \n            \"original_file\": \"duk_hstring_assert.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 61057, \n            \"original_file\": \"duk_hstring_misc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 61254, \n            \"original_file\": \"duk_hthread_alloc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 61314, \n            \"original_file\": \"duk_hthread_builtins.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 62201, \n            \"original_file\": \"duk_hthread_misc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 62299, \n            \"original_file\": \"duk_hthread_stacks.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 62707, \n            \"original_file\": \"duk_js_arith.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 62845, \n            \"original_file\": \"duk_js_call.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 65782, \n            \"original_file\": \"duk_js_compiler.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 73890, \n            \"original_file\": \"duk_js_executor.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 79162, \n            \"original_file\": \"duk_js_ops.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 80621, \n            \"original_file\": \"duk_js_var.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 82415, \n            \"original_file\": \"duk_lexer.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 84877, \n            \"original_file\": \"duk_numconv.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 87171, \n            \"original_file\": \"duk_regexp_compiler.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 88463, \n            \"original_file\": \"duk_regexp_executor.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 89491, \n            \"original_file\": \"duk_selftest.c\"\n        }, \n        {\n            \"original_line\": 2, \n            \"combined_line\": 90179, \n            \"original_file\": \"duk_tval.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 90331, \n            \"original_file\": \"duk_unicode_tables.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 96507, \n            \"original_file\": \"duk_util_bitdecoder.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 96674, \n            \"original_file\": \"duk_util_bitencoder.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 96718, \n            \"original_file\": \"duk_util_bufwriter.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 97097, \n            \"original_file\": \"duk_util_cast.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 97266, \n            \"original_file\": \"duk_util_double.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 97501, \n            \"original_file\": \"duk_util_hashbytes.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 97563, \n            \"original_file\": \"duk_util_memory.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 97600, \n            \"original_file\": \"duk_util_tinyrandom.c\"\n        }\n    ], \n    \"duk_version\": 20400, \n    \"git_branch\": \"master\", \n    \"git_commit\": \"d4f2cff1c592d70f58bab8e1bd85705174c02a58\", \n    \"builtin_strings_info\": [\n        {\n            \"plain\": \"Undefined\", \n            \"base64\": \"VW5kZWZpbmVk\", \n            \"define\": \"DUK_STRIDX_UC_UNDEFINED\"\n        }, \n        {\n            \"plain\": \"Null\", \n            \"base64\": \"TnVsbA==\", \n            \"define\": \"DUK_STRIDX_UC_NULL\"\n        }, \n        {\n            \"plain\": \"Symbol\", \n            \"base64\": \"U3ltYm9s\", \n            \"define\": \"DUK_STRIDX_UC_SYMBOL\"\n        }, \n        {\n            \"plain\": \"Arguments\", \n            \"base64\": \"QXJndW1lbnRz\", \n            \"define\": \"DUK_STRIDX_UC_ARGUMENTS\"\n        }, \n        {\n            \"plain\": \"Object\", \n            \"base64\": \"T2JqZWN0\", \n            \"define\": \"DUK_STRIDX_UC_OBJECT\"\n        }, \n        {\n            \"plain\": \"Function\", \n            \"base64\": \"RnVuY3Rpb24=\", \n            \"define\": \"DUK_STRIDX_UC_FUNCTION\"\n        }, \n        {\n            \"plain\": \"Array\", \n            \"base64\": \"QXJyYXk=\", \n            \"define\": \"DUK_STRIDX_ARRAY\"\n        }, \n        {\n            \"plain\": \"String\", \n            \"base64\": \"U3RyaW5n\", \n            \"define\": \"DUK_STRIDX_UC_STRING\"\n        }, \n        {\n            \"plain\": \"Boolean\", \n            \"base64\": \"Qm9vbGVhbg==\", \n            \"define\": \"DUK_STRIDX_UC_BOOLEAN\"\n        }, \n        {\n            \"plain\": \"Number\", \n            \"base64\": \"TnVtYmVy\", \n            \"define\": \"DUK_STRIDX_UC_NUMBER\"\n        }, \n        {\n            \"plain\": \"Date\", \n            \"base64\": \"RGF0ZQ==\", \n            \"define\": \"DUK_STRIDX_DATE\"\n        }, \n        {\n            \"plain\": \"RegExp\", \n            \"base64\": \"UmVnRXhw\", \n            \"define\": \"DUK_STRIDX_REG_EXP\"\n        }, \n        {\n            \"plain\": \"Error\", \n            \"base64\": \"RXJyb3I=\", \n            \"define\": \"DUK_STRIDX_UC_ERROR\"\n        }, \n        {\n            \"plain\": \"Math\", \n            \"base64\": \"TWF0aA==\", \n            \"define\": \"DUK_STRIDX_MATH\"\n        }, \n        {\n            \"plain\": \"JSON\", \n            \"base64\": \"SlNPTg==\", \n            \"define\": \"DUK_STRIDX_JSON\"\n        }, \n        {\n            \"plain\": \"\", \n            \"base64\": \"\", \n            \"define\": \"DUK_STRIDX_EMPTY_STRING\"\n        }, \n        {\n            \"plain\": \"ArrayBuffer\", \n            \"base64\": \"QXJyYXlCdWZmZXI=\", \n            \"define\": \"DUK_STRIDX_ARRAY_BUFFER\"\n        }, \n        {\n            \"plain\": \"DataView\", \n            \"base64\": \"RGF0YVZpZXc=\", \n            \"define\": \"DUK_STRIDX_DATA_VIEW\"\n        }, \n        {\n            \"plain\": \"Int8Array\", \n            \"base64\": \"SW50OEFycmF5\", \n            \"define\": \"DUK_STRIDX_INT8_ARRAY\"\n        }, \n        {\n            \"plain\": \"Uint8Array\", \n            \"base64\": \"VWludDhBcnJheQ==\", \n            \"define\": \"DUK_STRIDX_UINT8_ARRAY\"\n        }, \n        {\n            \"plain\": \"Uint8ClampedArray\", \n            \"base64\": \"VWludDhDbGFtcGVkQXJyYXk=\", \n            \"define\": \"DUK_STRIDX_UINT8_CLAMPED_ARRAY\"\n        }, \n        {\n            \"plain\": \"Int16Array\", \n            \"base64\": \"SW50MTZBcnJheQ==\", \n            \"define\": \"DUK_STRIDX_INT16_ARRAY\"\n        }, \n        {\n            \"plain\": \"Uint16Array\", \n            \"base64\": \"VWludDE2QXJyYXk=\", \n            \"define\": \"DUK_STRIDX_UINT16_ARRAY\"\n        }, \n        {\n            \"plain\": \"Int32Array\", \n            \"base64\": \"SW50MzJBcnJheQ==\", \n            \"define\": \"DUK_STRIDX_INT32_ARRAY\"\n        }, \n        {\n            \"plain\": \"Uint32Array\", \n            \"base64\": \"VWludDMyQXJyYXk=\", \n            \"define\": \"DUK_STRIDX_UINT32_ARRAY\"\n        }, \n        {\n            \"plain\": \"Float32Array\", \n            \"base64\": \"RmxvYXQzMkFycmF5\", \n            \"define\": \"DUK_STRIDX_FLOAT32_ARRAY\"\n        }, \n        {\n            \"plain\": \"Float64Array\", \n            \"base64\": \"RmxvYXQ2NEFycmF5\", \n            \"define\": \"DUK_STRIDX_FLOAT64_ARRAY\"\n        }, \n        {\n            \"plain\": \"global\", \n            \"base64\": \"Z2xvYmFs\", \n            \"define\": \"DUK_STRIDX_GLOBAL\"\n        }, \n        {\n            \"plain\": \"ObjEnv\", \n            \"base64\": \"T2JqRW52\", \n            \"define\": \"DUK_STRIDX_OBJ_ENV\"\n        }, \n        {\n            \"plain\": \"DecEnv\", \n            \"base64\": \"RGVjRW52\", \n            \"define\": \"DUK_STRIDX_DEC_ENV\"\n        }, \n        {\n            \"plain\": \"Buffer\", \n            \"base64\": \"QnVmZmVy\", \n            \"define\": \"DUK_STRIDX_UC_BUFFER\"\n        }, \n        {\n            \"plain\": \"Pointer\", \n            \"base64\": \"UG9pbnRlcg==\", \n            \"define\": \"DUK_STRIDX_UC_POINTER\"\n        }, \n        {\n            \"plain\": \"Thread\", \n            \"base64\": \"VGhyZWFk\", \n            \"define\": \"DUK_STRIDX_UC_THREAD\"\n        }, \n        {\n            \"plain\": \"eval\", \n            \"base64\": \"ZXZhbA==\", \n            \"define\": \"DUK_STRIDX_EVAL\"\n        }, \n        {\n            \"plain\": \"value\", \n            \"base64\": \"dmFsdWU=\", \n            \"define\": \"DUK_STRIDX_VALUE\"\n        }, \n        {\n            \"plain\": \"writable\", \n            \"base64\": \"d3JpdGFibGU=\", \n            \"define\": \"DUK_STRIDX_WRITABLE\"\n        }, \n        {\n            \"plain\": \"configurable\", \n            \"base64\": \"Y29uZmlndXJhYmxl\", \n            \"define\": \"DUK_STRIDX_CONFIGURABLE\"\n        }, \n        {\n            \"plain\": \"enumerable\", \n            \"base64\": \"ZW51bWVyYWJsZQ==\", \n            \"define\": \"DUK_STRIDX_ENUMERABLE\"\n        }, \n        {\n            \"plain\": \"join\", \n            \"base64\": \"am9pbg==\", \n            \"define\": \"DUK_STRIDX_JOIN\"\n        }, \n        {\n            \"plain\": \"toLocaleString\", \n            \"base64\": \"dG9Mb2NhbGVTdHJpbmc=\", \n            \"define\": \"DUK_STRIDX_TO_LOCALE_STRING\"\n        }, \n        {\n            \"plain\": \"valueOf\", \n            \"base64\": \"dmFsdWVPZg==\", \n            \"define\": \"DUK_STRIDX_VALUE_OF\"\n        }, \n        {\n            \"plain\": \"toUTCString\", \n            \"base64\": \"dG9VVENTdHJpbmc=\", \n            \"define\": \"DUK_STRIDX_TO_UTC_STRING\"\n        }, \n        {\n            \"plain\": \"toISOString\", \n            \"base64\": \"dG9JU09TdHJpbmc=\", \n            \"define\": \"DUK_STRIDX_TO_ISO_STRING\"\n        }, \n        {\n            \"plain\": \"toGMTString\", \n            \"base64\": \"dG9HTVRTdHJpbmc=\", \n            \"define\": \"DUK_STRIDX_TO_GMT_STRING\"\n        }, \n        {\n            \"plain\": \"source\", \n            \"base64\": \"c291cmNl\", \n            \"define\": \"DUK_STRIDX_SOURCE\"\n        }, \n        {\n            \"plain\": \"ignoreCase\", \n            \"base64\": \"aWdub3JlQ2FzZQ==\", \n            \"define\": \"DUK_STRIDX_IGNORE_CASE\"\n        }, \n        {\n            \"plain\": \"multiline\", \n            \"base64\": \"bXVsdGlsaW5l\", \n            \"define\": \"DUK_STRIDX_MULTILINE\"\n        }, \n        {\n            \"plain\": \"lastIndex\", \n            \"base64\": \"bGFzdEluZGV4\", \n            \"define\": \"DUK_STRIDX_LAST_INDEX\"\n        }, \n        {\n            \"plain\": \"flags\", \n            \"base64\": \"ZmxhZ3M=\", \n            \"define\": \"DUK_STRIDX_FLAGS\"\n        }, \n        {\n            \"plain\": \"index\", \n            \"base64\": \"aW5kZXg=\", \n            \"define\": \"DUK_STRIDX_INDEX\"\n        }, \n        {\n            \"plain\": \"prototype\", \n            \"base64\": \"cHJvdG90eXBl\", \n            \"define\": \"DUK_STRIDX_PROTOTYPE\"\n        }, \n        {\n            \"plain\": \"constructor\", \n            \"base64\": \"Y29uc3RydWN0b3I=\", \n            \"define\": \"DUK_STRIDX_CONSTRUCTOR\"\n        }, \n        {\n            \"plain\": \"message\", \n            \"base64\": \"bWVzc2FnZQ==\", \n            \"define\": \"DUK_STRIDX_MESSAGE\"\n        }, \n        {\n            \"plain\": \"boolean\", \n            \"base64\": \"Ym9vbGVhbg==\", \n            \"define\": \"DUK_STRIDX_LC_BOOLEAN\"\n        }, \n        {\n            \"plain\": \"number\", \n            \"base64\": \"bnVtYmVy\", \n            \"define\": \"DUK_STRIDX_LC_NUMBER\"\n        }, \n        {\n            \"plain\": \"string\", \n            \"base64\": \"c3RyaW5n\", \n            \"define\": \"DUK_STRIDX_LC_STRING\"\n        }, \n        {\n            \"plain\": \"symbol\", \n            \"base64\": \"c3ltYm9s\", \n            \"define\": \"DUK_STRIDX_LC_SYMBOL\"\n        }, \n        {\n            \"plain\": \"object\", \n            \"base64\": \"b2JqZWN0\", \n            \"define\": \"DUK_STRIDX_LC_OBJECT\"\n        }, \n        {\n            \"plain\": \"undefined\", \n            \"base64\": \"dW5kZWZpbmVk\", \n            \"define\": \"DUK_STRIDX_LC_UNDEFINED\"\n        }, \n        {\n            \"plain\": \"NaN\", \n            \"base64\": \"TmFO\", \n            \"define\": \"DUK_STRIDX_NAN\"\n        }, \n        {\n            \"plain\": \"Infinity\", \n            \"base64\": \"SW5maW5pdHk=\", \n            \"define\": \"DUK_STRIDX_INFINITY\"\n        }, \n        {\n            \"plain\": \"-Infinity\", \n            \"base64\": \"LUluZmluaXR5\", \n            \"define\": \"DUK_STRIDX_MINUS_INFINITY\"\n        }, \n        {\n            \"plain\": \"-0\", \n            \"base64\": \"LTA=\", \n            \"define\": \"DUK_STRIDX_MINUS_ZERO\"\n        }, \n        {\n            \"plain\": \",\", \n            \"base64\": \"LA==\", \n            \"define\": \"DUK_STRIDX_COMMA\"\n        }, \n        {\n            \"plain\": \"\\n    \", \n            \"base64\": \"CiAgICA=\", \n            \"define\": \"DUK_STRIDX_NEWLINE_4SPACE\"\n        }, \n        {\n            \"plain\": \"[...]\", \n            \"base64\": \"Wy4uLl0=\", \n            \"define\": \"DUK_STRIDX_BRACKETED_ELLIPSIS\"\n        }, \n        {\n            \"plain\": \"Invalid Date\", \n            \"base64\": \"SW52YWxpZCBEYXRl\", \n            \"define\": \"DUK_STRIDX_INVALID_DATE\"\n        }, \n        {\n            \"plain\": \"arguments\", \n            \"base64\": \"YXJndW1lbnRz\", \n            \"define\": \"DUK_STRIDX_LC_ARGUMENTS\"\n        }, \n        {\n            \"plain\": \"callee\", \n            \"base64\": \"Y2FsbGVl\", \n            \"define\": \"DUK_STRIDX_CALLEE\"\n        }, \n        {\n            \"plain\": \"caller\", \n            \"base64\": \"Y2FsbGVy\", \n            \"define\": \"DUK_STRIDX_CALLER\"\n        }, \n        {\n            \"plain\": \"apply\", \n            \"base64\": \"YXBwbHk=\", \n            \"define\": \"DUK_STRIDX_APPLY\"\n        }, \n        {\n            \"plain\": \"construct\", \n            \"base64\": \"Y29uc3RydWN0\", \n            \"define\": \"DUK_STRIDX_CONSTRUCT\"\n        }, \n        {\n            \"plain\": \"deleteProperty\", \n            \"base64\": \"ZGVsZXRlUHJvcGVydHk=\", \n            \"define\": \"DUK_STRIDX_DELETE_PROPERTY\"\n        }, \n        {\n            \"plain\": \"get\", \n            \"base64\": \"Z2V0\", \n            \"define\": \"DUK_STRIDX_GET\"\n        }, \n        {\n            \"plain\": \"has\", \n            \"base64\": \"aGFz\", \n            \"define\": \"DUK_STRIDX_HAS\"\n        }, \n        {\n            \"plain\": \"ownKeys\", \n            \"base64\": \"b3duS2V5cw==\", \n            \"define\": \"DUK_STRIDX_OWN_KEYS\"\n        }, \n        {\n            \"plain\": \"\\u0081Symbol.toPrimitive\\u00ff\", \n            \"base64\": \"gVN5bWJvbC50b1ByaW1pdGl2Zf8=\", \n            \"define\": \"DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE\"\n        }, \n        {\n            \"plain\": \"\\u0081Symbol.hasInstance\\u00ff\", \n            \"base64\": \"gVN5bWJvbC5oYXNJbnN0YW5jZf8=\", \n            \"define\": \"DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE\"\n        }, \n        {\n            \"plain\": \"\\u0081Symbol.toStringTag\\u00ff\", \n            \"base64\": \"gVN5bWJvbC50b1N0cmluZ1RhZ/8=\", \n            \"define\": \"DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG\"\n        }, \n        {\n            \"plain\": \"\\u0081Symbol.isConcatSpreadable\\u00ff\", \n            \"base64\": \"gVN5bWJvbC5pc0NvbmNhdFNwcmVhZGFibGX/\", \n            \"define\": \"DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE\"\n        }, \n        {\n            \"plain\": \"setPrototypeOf\", \n            \"base64\": \"c2V0UHJvdG90eXBlT2Y=\", \n            \"define\": \"DUK_STRIDX_SET_PROTOTYPE_OF\"\n        }, \n        {\n            \"plain\": \"__proto__\", \n            \"base64\": \"X19wcm90b19f\", \n            \"define\": \"DUK_STRIDX___PROTO__\"\n        }, \n        {\n            \"plain\": \"toString\", \n            \"base64\": \"dG9TdHJpbmc=\", \n            \"define\": \"DUK_STRIDX_TO_STRING\"\n        }, \n        {\n            \"plain\": \"toJSON\", \n            \"base64\": \"dG9KU09O\", \n            \"define\": \"DUK_STRIDX_TO_JSON\"\n        }, \n        {\n            \"plain\": \"type\", \n            \"base64\": \"dHlwZQ==\", \n            \"define\": \"DUK_STRIDX_TYPE\"\n        }, \n        {\n            \"plain\": \"data\", \n            \"base64\": \"ZGF0YQ==\", \n            \"define\": \"DUK_STRIDX_DATA\"\n        }, \n        {\n            \"plain\": \"length\", \n            \"base64\": \"bGVuZ3Ro\", \n            \"define\": \"DUK_STRIDX_LENGTH\"\n        }, \n        {\n            \"plain\": \"set\", \n            \"base64\": \"c2V0\", \n            \"define\": \"DUK_STRIDX_SET\"\n        }, \n        {\n            \"plain\": \"stack\", \n            \"base64\": \"c3RhY2s=\", \n            \"define\": \"DUK_STRIDX_STACK\"\n        }, \n        {\n            \"plain\": \"pc\", \n            \"base64\": \"cGM=\", \n            \"define\": \"DUK_STRIDX_PC\"\n        }, \n        {\n            \"plain\": \"lineNumber\", \n            \"base64\": \"bGluZU51bWJlcg==\", \n            \"define\": \"DUK_STRIDX_LINE_NUMBER\"\n        }, \n        {\n            \"plain\": \"\\u0082Tracedata\", \n            \"base64\": \"glRyYWNlZGF0YQ==\", \n            \"define\": \"DUK_STRIDX_INT_TRACEDATA\"\n        }, \n        {\n            \"plain\": \"name\", \n            \"base64\": \"bmFtZQ==\", \n            \"define\": \"DUK_STRIDX_NAME\"\n        }, \n        {\n            \"plain\": \"fileName\", \n            \"base64\": \"ZmlsZU5hbWU=\", \n            \"define\": \"DUK_STRIDX_FILE_NAME\"\n        }, \n        {\n            \"plain\": \"pointer\", \n            \"base64\": \"cG9pbnRlcg==\", \n            \"define\": \"DUK_STRIDX_LC_POINTER\"\n        }, \n        {\n            \"plain\": \"\\u0082Target\", \n            \"base64\": \"glRhcmdldA==\", \n            \"define\": \"DUK_STRIDX_INT_TARGET\"\n        }, \n        {\n            \"plain\": \"\\u0082Next\", \n            \"base64\": \"gk5leHQ=\", \n            \"define\": \"DUK_STRIDX_INT_NEXT\"\n        }, \n        {\n            \"plain\": \"\\u0082Bytecode\", \n            \"base64\": \"gkJ5dGVjb2Rl\", \n            \"define\": \"DUK_STRIDX_INT_BYTECODE\"\n        }, \n        {\n            \"plain\": \"\\u0082Formals\", \n            \"base64\": \"gkZvcm1hbHM=\", \n            \"define\": \"DUK_STRIDX_INT_FORMALS\"\n        }, \n        {\n            \"plain\": \"\\u0082Varmap\", \n            \"base64\": \"glZhcm1hcA==\", \n            \"define\": \"DUK_STRIDX_INT_VARMAP\"\n        }, \n        {\n            \"plain\": \"\\u0082Source\", \n            \"base64\": \"glNvdXJjZQ==\", \n            \"define\": \"DUK_STRIDX_INT_SOURCE\"\n        }, \n        {\n            \"plain\": \"\\u0082Pc2line\", \n            \"base64\": \"glBjMmxpbmU=\", \n            \"define\": \"DUK_STRIDX_INT_PC2LINE\"\n        }, \n        {\n            \"plain\": \"\\u0082Map\", \n            \"base64\": \"gk1hcA==\", \n            \"define\": \"DUK_STRIDX_INT_MAP\"\n        }, \n        {\n            \"plain\": \"\\u0082Varenv\", \n            \"base64\": \"glZhcmVudg==\", \n            \"define\": \"DUK_STRIDX_INT_VARENV\"\n        }, \n        {\n            \"plain\": \"\\u0082Finalizer\", \n            \"base64\": \"gkZpbmFsaXplcg==\", \n            \"define\": \"DUK_STRIDX_INT_FINALIZER\"\n        }, \n        {\n            \"plain\": \"\\u0082Value\", \n            \"base64\": \"glZhbHVl\", \n            \"define\": \"DUK_STRIDX_INT_VALUE\"\n        }, \n        {\n            \"plain\": \"compile\", \n            \"base64\": \"Y29tcGlsZQ==\", \n            \"define\": \"DUK_STRIDX_COMPILE\"\n        }, \n        {\n            \"plain\": \"input\", \n            \"base64\": \"aW5wdXQ=\", \n            \"define\": \"DUK_STRIDX_INPUT\"\n        }, \n        {\n            \"plain\": \"errCreate\", \n            \"base64\": \"ZXJyQ3JlYXRl\", \n            \"define\": \"DUK_STRIDX_ERR_CREATE\"\n        }, \n        {\n            \"plain\": \"errThrow\", \n            \"base64\": \"ZXJyVGhyb3c=\", \n            \"define\": \"DUK_STRIDX_ERR_THROW\"\n        }, \n        {\n            \"plain\": \"env\", \n            \"base64\": \"ZW52\", \n            \"define\": \"DUK_STRIDX_ENV\"\n        }, \n        {\n            \"plain\": \"hex\", \n            \"base64\": \"aGV4\", \n            \"define\": \"DUK_STRIDX_HEX\"\n        }, \n        {\n            \"plain\": \"base64\", \n            \"base64\": \"YmFzZTY0\", \n            \"define\": \"DUK_STRIDX_BASE64\"\n        }, \n        {\n            \"plain\": \"jx\", \n            \"base64\": \"ang=\", \n            \"define\": \"DUK_STRIDX_JX\"\n        }, \n        {\n            \"plain\": \"jc\", \n            \"base64\": \"amM=\", \n            \"define\": \"DUK_STRIDX_JC\"\n        }, \n        {\n            \"plain\": \"{\\\"_undef\\\":true}\", \n            \"base64\": \"eyJfdW5kZWYiOnRydWV9\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_UNDEFINED\"\n        }, \n        {\n            \"plain\": \"{\\\"_nan\\\":true}\", \n            \"base64\": \"eyJfbmFuIjp0cnVlfQ==\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_NAN\"\n        }, \n        {\n            \"plain\": \"{\\\"_inf\\\":true}\", \n            \"base64\": \"eyJfaW5mIjp0cnVlfQ==\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_POSINF\"\n        }, \n        {\n            \"plain\": \"{\\\"_ninf\\\":true}\", \n            \"base64\": \"eyJfbmluZiI6dHJ1ZX0=\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_NEGINF\"\n        }, \n        {\n            \"plain\": \"{\\\"_func\\\":true}\", \n            \"base64\": \"eyJfZnVuYyI6dHJ1ZX0=\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_FUNCTION1\"\n        }, \n        {\n            \"plain\": \"{_func:true}\", \n            \"base64\": \"e19mdW5jOnRydWV9\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_FUNCTION2\"\n        }, \n        {\n            \"plain\": \"break\", \n            \"base64\": \"YnJlYWs=\", \n            \"define\": \"DUK_STRIDX_BREAK\"\n        }, \n        {\n            \"plain\": \"case\", \n            \"base64\": \"Y2FzZQ==\", \n            \"define\": \"DUK_STRIDX_CASE\"\n        }, \n        {\n            \"plain\": \"catch\", \n            \"base64\": \"Y2F0Y2g=\", \n            \"define\": \"DUK_STRIDX_CATCH\"\n        }, \n        {\n            \"plain\": \"continue\", \n            \"base64\": \"Y29udGludWU=\", \n            \"define\": \"DUK_STRIDX_CONTINUE\"\n        }, \n        {\n            \"plain\": \"debugger\", \n            \"base64\": \"ZGVidWdnZXI=\", \n            \"define\": \"DUK_STRIDX_DEBUGGER\"\n        }, \n        {\n            \"plain\": \"default\", \n            \"base64\": \"ZGVmYXVsdA==\", \n            \"define\": \"DUK_STRIDX_DEFAULT\"\n        }, \n        {\n            \"plain\": \"delete\", \n            \"base64\": \"ZGVsZXRl\", \n            \"define\": \"DUK_STRIDX_DELETE\"\n        }, \n        {\n            \"plain\": \"do\", \n            \"base64\": \"ZG8=\", \n            \"define\": \"DUK_STRIDX_DO\"\n        }, \n        {\n            \"plain\": \"else\", \n            \"base64\": \"ZWxzZQ==\", \n            \"define\": \"DUK_STRIDX_ELSE\"\n        }, \n        {\n            \"plain\": \"finally\", \n            \"base64\": \"ZmluYWxseQ==\", \n            \"define\": \"DUK_STRIDX_FINALLY\"\n        }, \n        {\n            \"plain\": \"for\", \n            \"base64\": \"Zm9y\", \n            \"define\": \"DUK_STRIDX_FOR\"\n        }, \n        {\n            \"plain\": \"function\", \n            \"base64\": \"ZnVuY3Rpb24=\", \n            \"define\": \"DUK_STRIDX_LC_FUNCTION\"\n        }, \n        {\n            \"plain\": \"if\", \n            \"base64\": \"aWY=\", \n            \"define\": \"DUK_STRIDX_IF\"\n        }, \n        {\n            \"plain\": \"in\", \n            \"base64\": \"aW4=\", \n            \"define\": \"DUK_STRIDX_IN\"\n        }, \n        {\n            \"plain\": \"instanceof\", \n            \"base64\": \"aW5zdGFuY2VvZg==\", \n            \"define\": \"DUK_STRIDX_INSTANCEOF\"\n        }, \n        {\n            \"plain\": \"new\", \n            \"base64\": \"bmV3\", \n            \"define\": \"DUK_STRIDX_NEW\"\n        }, \n        {\n            \"plain\": \"return\", \n            \"base64\": \"cmV0dXJu\", \n            \"define\": \"DUK_STRIDX_RETURN\"\n        }, \n        {\n            \"plain\": \"switch\", \n            \"base64\": \"c3dpdGNo\", \n            \"define\": \"DUK_STRIDX_SWITCH\"\n        }, \n        {\n            \"plain\": \"this\", \n            \"base64\": \"dGhpcw==\", \n            \"define\": \"DUK_STRIDX_THIS\"\n        }, \n        {\n            \"plain\": \"throw\", \n            \"base64\": \"dGhyb3c=\", \n            \"define\": \"DUK_STRIDX_THROW\"\n        }, \n        {\n            \"plain\": \"try\", \n            \"base64\": \"dHJ5\", \n            \"define\": \"DUK_STRIDX_TRY\"\n        }, \n        {\n            \"plain\": \"typeof\", \n            \"base64\": \"dHlwZW9m\", \n            \"define\": \"DUK_STRIDX_TYPEOF\"\n        }, \n        {\n            \"plain\": \"var\", \n            \"base64\": \"dmFy\", \n            \"define\": \"DUK_STRIDX_VAR\"\n        }, \n        {\n            \"plain\": \"const\", \n            \"base64\": \"Y29uc3Q=\", \n            \"define\": \"DUK_STRIDX_CONST\"\n        }, \n        {\n            \"plain\": \"void\", \n            \"base64\": \"dm9pZA==\", \n            \"define\": \"DUK_STRIDX_VOID\"\n        }, \n        {\n            \"plain\": \"while\", \n            \"base64\": \"d2hpbGU=\", \n            \"define\": \"DUK_STRIDX_WHILE\"\n        }, \n        {\n            \"plain\": \"with\", \n            \"base64\": \"d2l0aA==\", \n            \"define\": \"DUK_STRIDX_WITH\"\n        }, \n        {\n            \"plain\": \"class\", \n            \"base64\": \"Y2xhc3M=\", \n            \"define\": \"DUK_STRIDX_CLASS\"\n        }, \n        {\n            \"plain\": \"enum\", \n            \"base64\": \"ZW51bQ==\", \n            \"define\": \"DUK_STRIDX_ENUM\"\n        }, \n        {\n            \"plain\": \"export\", \n            \"base64\": \"ZXhwb3J0\", \n            \"define\": \"DUK_STRIDX_EXPORT\"\n        }, \n        {\n            \"plain\": \"extends\", \n            \"base64\": \"ZXh0ZW5kcw==\", \n            \"define\": \"DUK_STRIDX_EXTENDS\"\n        }, \n        {\n            \"plain\": \"import\", \n            \"base64\": \"aW1wb3J0\", \n            \"define\": \"DUK_STRIDX_IMPORT\"\n        }, \n        {\n            \"plain\": \"super\", \n            \"base64\": \"c3VwZXI=\", \n            \"define\": \"DUK_STRIDX_SUPER\"\n        }, \n        {\n            \"plain\": \"null\", \n            \"base64\": \"bnVsbA==\", \n            \"define\": \"DUK_STRIDX_LC_NULL\"\n        }, \n        {\n            \"plain\": \"true\", \n            \"base64\": \"dHJ1ZQ==\", \n            \"define\": \"DUK_STRIDX_TRUE\"\n        }, \n        {\n            \"plain\": \"false\", \n            \"base64\": \"ZmFsc2U=\", \n            \"define\": \"DUK_STRIDX_FALSE\"\n        }, \n        {\n            \"plain\": \"implements\", \n            \"base64\": \"aW1wbGVtZW50cw==\", \n            \"define\": \"DUK_STRIDX_IMPLEMENTS\"\n        }, \n        {\n            \"plain\": \"interface\", \n            \"base64\": \"aW50ZXJmYWNl\", \n            \"define\": \"DUK_STRIDX_INTERFACE\"\n        }, \n        {\n            \"plain\": \"let\", \n            \"base64\": \"bGV0\", \n            \"define\": \"DUK_STRIDX_LET\"\n        }, \n        {\n            \"plain\": \"package\", \n            \"base64\": \"cGFja2FnZQ==\", \n            \"define\": \"DUK_STRIDX_PACKAGE\"\n        }, \n        {\n            \"plain\": \"private\", \n            \"base64\": \"cHJpdmF0ZQ==\", \n            \"define\": \"DUK_STRIDX_PRIVATE\"\n        }, \n        {\n            \"plain\": \"protected\", \n            \"base64\": \"cHJvdGVjdGVk\", \n            \"define\": \"DUK_STRIDX_PROTECTED\"\n        }, \n        {\n            \"plain\": \"public\", \n            \"base64\": \"cHVibGlj\", \n            \"define\": \"DUK_STRIDX_PUBLIC\"\n        }, \n        {\n            \"plain\": \"static\", \n            \"base64\": \"c3RhdGlj\", \n            \"define\": \"DUK_STRIDX_STATIC\"\n        }, \n        {\n            \"plain\": \"yield\", \n            \"base64\": \"eWllbGQ=\", \n            \"define\": \"DUK_STRIDX_YIELD\"\n        }\n    ], \n    \"builtin_strings_base64\": [\n        \"VW5kZWZpbmVk\", \n        \"TnVsbA==\", \n        \"U3ltYm9s\", \n        \"QXJndW1lbnRz\", \n        \"T2JqZWN0\", \n        \"RnVuY3Rpb24=\", \n        \"QXJyYXk=\", \n        \"U3RyaW5n\", \n        \"Qm9vbGVhbg==\", \n        \"TnVtYmVy\", \n        \"RGF0ZQ==\", \n        \"UmVnRXhw\", \n        \"RXJyb3I=\", \n        \"TWF0aA==\", \n        \"SlNPTg==\", \n        \"\", \n        \"QXJyYXlCdWZmZXI=\", \n        \"RGF0YVZpZXc=\", \n        \"SW50OEFycmF5\", \n        \"VWludDhBcnJheQ==\", \n        \"VWludDhDbGFtcGVkQXJyYXk=\", \n        \"SW50MTZBcnJheQ==\", \n        \"VWludDE2QXJyYXk=\", \n        \"SW50MzJBcnJheQ==\", \n        \"VWludDMyQXJyYXk=\", \n        \"RmxvYXQzMkFycmF5\", \n        \"RmxvYXQ2NEFycmF5\", \n        \"Z2xvYmFs\", \n        \"T2JqRW52\", \n        \"RGVjRW52\", \n        \"QnVmZmVy\", \n        \"UG9pbnRlcg==\", \n        \"VGhyZWFk\", \n        \"ZXZhbA==\", \n        \"dmFsdWU=\", \n        \"d3JpdGFibGU=\", \n        \"Y29uZmlndXJhYmxl\", \n        \"ZW51bWVyYWJsZQ==\", \n        \"am9pbg==\", \n        \"dG9Mb2NhbGVTdHJpbmc=\", \n        \"dmFsdWVPZg==\", \n        \"dG9VVENTdHJpbmc=\", \n        \"dG9JU09TdHJpbmc=\", \n        \"dG9HTVRTdHJpbmc=\", \n        \"c291cmNl\", \n        \"aWdub3JlQ2FzZQ==\", \n        \"bXVsdGlsaW5l\", \n        \"bGFzdEluZGV4\", \n        \"ZmxhZ3M=\", \n        \"aW5kZXg=\", \n        \"cHJvdG90eXBl\", \n        \"Y29uc3RydWN0b3I=\", \n        \"bWVzc2FnZQ==\", \n        \"Ym9vbGVhbg==\", \n        \"bnVtYmVy\", \n        \"c3RyaW5n\", \n        \"c3ltYm9s\", \n        \"b2JqZWN0\", \n        \"dW5kZWZpbmVk\", \n        \"TmFO\", \n        \"SW5maW5pdHk=\", \n        \"LUluZmluaXR5\", \n        \"LTA=\", \n        \"LA==\", \n        \"CiAgICA=\", \n        \"Wy4uLl0=\", \n        \"SW52YWxpZCBEYXRl\", \n        \"YXJndW1lbnRz\", \n        \"Y2FsbGVl\", \n        \"Y2FsbGVy\", \n        \"YXBwbHk=\", \n        \"Y29uc3RydWN0\", \n        \"ZGVsZXRlUHJvcGVydHk=\", \n        \"Z2V0\", \n        \"aGFz\", \n        \"b3duS2V5cw==\", \n        \"gVN5bWJvbC50b1ByaW1pdGl2Zf8=\", \n        \"gVN5bWJvbC5oYXNJbnN0YW5jZf8=\", \n        \"gVN5bWJvbC50b1N0cmluZ1RhZ/8=\", \n        \"gVN5bWJvbC5pc0NvbmNhdFNwcmVhZGFibGX/\", \n        \"c2V0UHJvdG90eXBlT2Y=\", \n        \"X19wcm90b19f\", \n        \"dG9TdHJpbmc=\", \n        \"dG9KU09O\", \n        \"dHlwZQ==\", \n        \"ZGF0YQ==\", \n        \"bGVuZ3Ro\", \n        \"c2V0\", \n        \"c3RhY2s=\", \n        \"cGM=\", \n        \"bGluZU51bWJlcg==\", \n        \"glRyYWNlZGF0YQ==\", \n        \"bmFtZQ==\", \n        \"ZmlsZU5hbWU=\", \n        \"cG9pbnRlcg==\", \n        \"glRhcmdldA==\", \n        \"gk5leHQ=\", \n        \"gkJ5dGVjb2Rl\", \n        \"gkZvcm1hbHM=\", \n        \"glZhcm1hcA==\", \n        \"glNvdXJjZQ==\", \n        \"glBjMmxpbmU=\", \n        \"gk1hcA==\", \n        \"glZhcmVudg==\", \n        \"gkZpbmFsaXplcg==\", \n        \"glZhbHVl\", \n        \"Y29tcGlsZQ==\", \n        \"aW5wdXQ=\", \n        \"ZXJyQ3JlYXRl\", \n        \"ZXJyVGhyb3c=\", \n        \"ZW52\", \n        \"aGV4\", \n        \"YmFzZTY0\", \n        \"ang=\", \n        \"amM=\", \n        \"eyJfdW5kZWYiOnRydWV9\", \n        \"eyJfbmFuIjp0cnVlfQ==\", \n        \"eyJfaW5mIjp0cnVlfQ==\", \n        \"eyJfbmluZiI6dHJ1ZX0=\", \n        \"eyJfZnVuYyI6dHJ1ZX0=\", \n        \"e19mdW5jOnRydWV9\", \n        \"YnJlYWs=\", \n        \"Y2FzZQ==\", \n        \"Y2F0Y2g=\", \n        \"Y29udGludWU=\", \n        \"ZGVidWdnZXI=\", \n        \"ZGVmYXVsdA==\", \n        \"ZGVsZXRl\", \n        \"ZG8=\", \n        \"ZWxzZQ==\", \n        \"ZmluYWxseQ==\", \n        \"Zm9y\", \n        \"ZnVuY3Rpb24=\", \n        \"aWY=\", \n        \"aW4=\", \n        \"aW5zdGFuY2VvZg==\", \n        \"bmV3\", \n        \"cmV0dXJu\", \n        \"c3dpdGNo\", \n        \"dGhpcw==\", \n        \"dGhyb3c=\", \n        \"dHJ5\", \n        \"dHlwZW9m\", \n        \"dmFy\", \n        \"Y29uc3Q=\", \n        \"dm9pZA==\", \n        \"d2hpbGU=\", \n        \"d2l0aA==\", \n        \"Y2xhc3M=\", \n        \"ZW51bQ==\", \n        \"ZXhwb3J0\", \n        \"ZXh0ZW5kcw==\", \n        \"aW1wb3J0\", \n        \"c3VwZXI=\", \n        \"bnVsbA==\", \n        \"dHJ1ZQ==\", \n        \"ZmFsc2U=\", \n        \"aW1wbGVtZW50cw==\", \n        \"aW50ZXJmYWNl\", \n        \"bGV0\", \n        \"cGFja2FnZQ==\", \n        \"cHJpdmF0ZQ==\", \n        \"cHJvdGVjdGVk\", \n        \"cHVibGlj\", \n        \"c3RhdGlj\", \n        \"eWllbGQ=\"\n    ], \n    \"git_describe\": \"v2.4.0\", \n    \"builtin_strings\": [\n        \"Undefined\", \n        \"Null\", \n        \"Symbol\", \n        \"Arguments\", \n        \"Object\", \n        \"Function\", \n        \"Array\", \n        \"String\", \n        \"Boolean\", \n        \"Number\", \n        \"Date\", \n        \"RegExp\", \n        \"Error\", \n        \"Math\", \n        \"JSON\", \n        \"\", \n        \"ArrayBuffer\", \n        \"DataView\", \n        \"Int8Array\", \n        \"Uint8Array\", \n        \"Uint8ClampedArray\", \n        \"Int16Array\", \n        \"Uint16Array\", \n        \"Int32Array\", \n        \"Uint32Array\", \n        \"Float32Array\", \n        \"Float64Array\", \n        \"global\", \n        \"ObjEnv\", \n        \"DecEnv\", \n        \"Buffer\", \n        \"Pointer\", \n        \"Thread\", \n        \"eval\", \n        \"value\", \n        \"writable\", \n        \"configurable\", \n        \"enumerable\", \n        \"join\", \n        \"toLocaleString\", \n        \"valueOf\", \n        \"toUTCString\", \n        \"toISOString\", \n        \"toGMTString\", \n        \"source\", \n        \"ignoreCase\", \n        \"multiline\", \n        \"lastIndex\", \n        \"flags\", \n        \"index\", \n        \"prototype\", \n        \"constructor\", \n        \"message\", \n        \"boolean\", \n        \"number\", \n        \"string\", \n        \"symbol\", \n        \"object\", \n        \"undefined\", \n        \"NaN\", \n        \"Infinity\", \n        \"-Infinity\", \n        \"-0\", \n        \",\", \n        \"\\n    \", \n        \"[...]\", \n        \"Invalid Date\", \n        \"arguments\", \n        \"callee\", \n        \"caller\", \n        \"apply\", \n        \"construct\", \n        \"deleteProperty\", \n        \"get\", \n        \"has\", \n        \"ownKeys\", \n        \"\\u0081Symbol.toPrimitive\\u00ff\", \n        \"\\u0081Symbol.hasInstance\\u00ff\", \n        \"\\u0081Symbol.toStringTag\\u00ff\", \n        \"\\u0081Symbol.isConcatSpreadable\\u00ff\", \n        \"setPrototypeOf\", \n        \"__proto__\", \n        \"toString\", \n        \"toJSON\", \n        \"type\", \n        \"data\", \n        \"length\", \n        \"set\", \n        \"stack\", \n        \"pc\", \n        \"lineNumber\", \n        \"\\u0082Tracedata\", \n        \"name\", \n        \"fileName\", \n        \"pointer\", \n        \"\\u0082Target\", \n        \"\\u0082Next\", \n        \"\\u0082Bytecode\", \n        \"\\u0082Formals\", \n        \"\\u0082Varmap\", \n        \"\\u0082Source\", \n        \"\\u0082Pc2line\", \n        \"\\u0082Map\", \n        \"\\u0082Varenv\", \n        \"\\u0082Finalizer\", \n        \"\\u0082Value\", \n        \"compile\", \n        \"input\", \n        \"errCreate\", \n        \"errThrow\", \n        \"env\", \n        \"hex\", \n        \"base64\", \n        \"jx\", \n        \"jc\", \n        \"{\\\"_undef\\\":true}\", \n        \"{\\\"_nan\\\":true}\", \n        \"{\\\"_inf\\\":true}\", \n        \"{\\\"_ninf\\\":true}\", \n        \"{\\\"_func\\\":true}\", \n        \"{_func:true}\", \n        \"break\", \n        \"case\", \n        \"catch\", \n        \"continue\", \n        \"debugger\", \n        \"default\", \n        \"delete\", \n        \"do\", \n        \"else\", \n        \"finally\", \n        \"for\", \n        \"function\", \n        \"if\", \n        \"in\", \n        \"instanceof\", \n        \"new\", \n        \"return\", \n        \"switch\", \n        \"this\", \n        \"throw\", \n        \"try\", \n        \"typeof\", \n        \"var\", \n        \"const\", \n        \"void\", \n        \"while\", \n        \"with\", \n        \"class\", \n        \"enum\", \n        \"export\", \n        \"extends\", \n        \"import\", \n        \"super\", \n        \"null\", \n        \"true\", \n        \"false\", \n        \"implements\", \n        \"interface\", \n        \"let\", \n        \"package\", \n        \"private\", \n        \"protected\", \n        \"public\", \n        \"static\", \n        \"yield\"\n    ]\n}"
  },
  {
    "path": "react_juce/duktape/src/duktape.c",
    "content": "/*\n *  Single source autogenerated distributable for Duktape 2.4.0.\n *\n *  Git commit d4f2cff1c592d70f58bab8e1bd85705174c02a58 (v2.4.0).\n *  Git branch master.\n *\n *  See Duktape AUTHORS.rst and LICENSE.txt for copyright and\n *  licensing information.\n */\n\n/* LICENSE.txt */\n/*\n*  ===============\n*  Duktape license\n*  ===============\n*\n*  (http://opensource.org/licenses/MIT)\n*\n*  Copyright (c) 2013-2019 by Duktape authors (see AUTHORS.rst)\n*\n*  Permission is hereby granted, free of charge, to any person obtaining a copy\n*  of this software and associated documentation files (the \"Software\"), to deal\n*  in the Software without restriction, including without limitation the rights\n*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n*  copies of the Software, and to permit persons to whom the Software is\n*  furnished to do so, subject to the following conditions:\n*\n*  The above copyright notice and this permission notice shall be included in\n*  all copies or substantial portions of the Software.\n*\n*  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n*  THE SOFTWARE.\n*/\n\n/* AUTHORS.rst */\n/*\n*  ===============\n*  Duktape authors\n*  ===============\n*\n*  Copyright\n*  =========\n*\n*  Duktape copyrights are held by its authors.  Each author has a copyright\n*  to their contribution, and agrees to irrevocably license the contribution\n*  under the Duktape ``LICENSE.txt``.\n*\n*  Authors\n*  =======\n*\n*  Please include an e-mail address, a link to your GitHub profile, or something\n*  similar to allow your contribution to be identified accurately.\n*\n*  The following people have contributed code, website contents, or Wiki contents,\n*  and agreed to irrevocably license their contributions under the Duktape\n*  ``LICENSE.txt`` (in order of appearance):\n*\n*  * Sami Vaarala <sami.vaarala@iki.fi>\n*  * Niki Dobrev\n*  * Andreas \\u00d6man <andreas@lonelycoder.com>\n*  * L\\u00e1szl\\u00f3 Lang\\u00f3 <llango.u-szeged@partner.samsung.com>\n*  * Legimet <legimet.calc@gmail.com>\n*  * Karl Skomski <karl@skomski.com>\n*  * Bruce Pascoe <fatcerberus1@gmail.com>\n*  * Ren\\u00e9 Hollander <rene@rene8888.at>\n*  * Julien Hamaide (https://github.com/crazyjul)\n*  * Sebastian G\\u00f6tte (https://github.com/jaseg)\n*  * Tomasz Magulski (https://github.com/magul)\n*  * \\D. Bohdan (https://github.com/dbohdan)\n*  * Ond\\u0159ej Jirman (https://github.com/megous)\n*  * Sa\\u00fal Ibarra Corretg\\u00e9 <saghul@gmail.com>\n*  * Jeremy HU <huxingyi@msn.com>\n*  * Ole Andr\\u00e9 Vadla Ravn\\u00e5s (https://github.com/oleavr)\n*  * Harold Brenes (https://github.com/harold-b)\n*  * Oliver Crow (https://github.com/ocrow)\n*  * Jakub Ch\\u0142api\\u0144ski (https://github.com/jchlapinski)\n*  * Brett Vickers (https://github.com/beevik)\n*  * Dominik Okwieka (https://github.com/okitec)\n*  * Remko Tron\\u00e7on (https://el-tramo.be)\n*  * Romero Malaquias (rbsm@ic.ufal.br)\n*  * Michael Drake <michael.drake@codethink.co.uk>\n*  * Steven Don (https://github.com/shdon)\n*  * Simon Stone (https://github.com/sstone1)\n*  * \\J. McC. (https://github.com/jmhmccr)\n*  * Jakub Nowakowski (https://github.com/jimvonmoon)\n*  * Tommy Nguyen (https://github.com/tn0502)\n*  * Fabrice Fontaine (https://github.com/ffontaine)\n*  * Christopher Hiller (https://github.com/boneskull)\n*  * Gonzalo Diethelm (https://github.com/gonzus)\n*  * Michal Kasperek (https://github.com/michalkas)\n*  * Andrew Janke (https://github.com/apjanke)\n*  * Steve Fan (https://github.com/stevefan1999)\n*  * Edward Betts (https://github.com/edwardbetts)\n*  * Ozhan Duz (https://github.com/webfolderio)\n*  * Akos Kiss (https://github.com/akosthekiss)\n*  * TheBrokenRail (https://github.com/TheBrokenRail)\n*  * Jesse Doyle (https://github.com/jessedoyle)\n*  * Gero Kuehn (https://github.com/dc6jgk)\n*  * James Swift (https://github.com/phraemer)\n*  * Luis de Bethencourt (https://github.com/luisbg)\n*  * Ian Whyman (https://github.com/v00d00)\n*\n*  Other contributions\n*  ===================\n*\n*  The following people have contributed something other than code (e.g. reported\n*  bugs, provided ideas, etc; roughly in order of appearance):\n*\n*  * Greg Burns\n*  * Anthony Rabine\n*  * Carlos Costa\n*  * Aur\\u00e9lien Bouilland\n*  * Preet Desai (Pris Matic)\n*  * judofyr (http://www.reddit.com/user/judofyr)\n*  * Jason Woofenden\n*  * Micha\\u0142 Przyby\\u015b\n*  * Anthony Howe\n*  * Conrad Pankoff\n*  * Jim Schimpf\n*  * Rajaran Gaunker (https://github.com/zimbabao)\n*  * Andreas \\u00d6man\n*  * Doug Sanden\n*  * Josh Engebretson (https://github.com/JoshEngebretson)\n*  * Remo Eichenberger (https://github.com/remoe)\n*  * Mamod Mehyar (https://github.com/mamod)\n*  * David Demelier (https://github.com/markand)\n*  * Tim Caswell (https://github.com/creationix)\n*  * Mitchell Blank Jr (https://github.com/mitchblank)\n*  * https://github.com/yushli\n*  * Seo Sanghyeon (https://github.com/sanxiyn)\n*  * Han ChoongWoo (https://github.com/tunz)\n*  * Joshua Peek (https://github.com/josh)\n*  * Bruce E. Pascoe (https://github.com/fatcerberus)\n*  * https://github.com/Kelledin\n*  * https://github.com/sstruchtrup\n*  * Michael Drake (https://github.com/tlsa)\n*  * https://github.com/chris-y\n*  * Laurent Zubiaur (https://github.com/lzubiaur)\n*  * Neil Kolban (https://github.com/nkolban)\n*  * Wilhelm Wanecek (https://github.com/wanecek)\n*  * Andrew Janke (https://github.com/apjanke)\n*  * Unamer (https://github.com/unamer)\n*  * Karl Dahlke (eklhad@gmail.com)\n*\n*  If you are accidentally missing from this list, send me an e-mail\n*  (``sami.vaarala@iki.fi``) and I'll fix the omission.\n*/\n\n#line 1 \"duk_replacements.c\"\n/*\n *  Replacements for missing platform functions.\n *\n *  Unlike the originals, fpclassify() and signbit() replacements don't\n *  work on any floating point types, only doubles.  The C typing here\n *  mimics the standard prototypes.\n */\n\n/* #include duk_internal.h */\n#line 1 \"duk_internal.h\"\n/*\n *  Top-level include file to be used for all (internal) source files.\n *\n *  Source files should not include individual header files, as they\n *  have not been designed to be individually included.\n */\n\n#if !defined(DUK_INTERNAL_H_INCLUDED)\n#define DUK_INTERNAL_H_INCLUDED\n\n/*\n *  The 'duktape.h' header provides the public API, but also handles all\n *  compiler and platform specific feature detection, Duktape feature\n *  resolution, inclusion of system headers, etc.  These have been merged\n *  because the public API is also dependent on e.g. detecting appropriate\n *  C types which is quite platform/compiler specific especially for a non-C99\n *  build.  The public API is also dependent on the resolved feature set.\n *\n *  Some actions taken by the merged header (such as including system headers)\n *  are not appropriate for building a user application.  The define\n *  DUK_COMPILING_DUKTAPE allows the merged header to skip/include some\n *  sections depending on what is being built.\n */\n\n#define DUK_COMPILING_DUKTAPE\n#include \"duktape.h\"\n\n/*\n *  Duktape includes (other than duk_features.h)\n *\n *  The header files expect to be included in an order which satisfies header\n *  dependencies correctly (the headers themselves don't include any other\n *  includes).  Forward declarations are used to break circular struct/typedef\n *  dependencies.\n */\n\n/* #include duk_dblunion.h */\n#line 1 \"duk_dblunion.h\"\n/*\n *  Union to access IEEE double memory representation, indexes for double\n *  memory representation, and some macros for double manipulation.\n *\n *  Also used by packed duk_tval.  Use a union for bit manipulation to\n *  minimize aliasing issues in practice.  The C99 standard does not\n *  guarantee that this should work, but it's a very widely supported\n *  practice for low level manipulation.\n *\n *  IEEE double format summary:\n *\n *    seeeeeee eeeeffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n *       A        B        C        D        E        F        G        H\n *\n *    s       sign bit\n *    eee...  exponent field\n *    fff...  fraction\n *\n *  See http://en.wikipedia.org/wiki/Double_precision_floating-point_format.\n *\n *  NaNs are represented as exponent 0x7ff and mantissa != 0.  The NaN is a\n *  signaling NaN when the highest bit of the mantissa is zero, and a quiet\n *  NaN when the highest bit is set.\n *\n *  At least three memory layouts are relevant here:\n *\n *    A B C D E F G H    Big endian (e.g. 68k)           DUK_USE_DOUBLE_BE\n *    H G F E D C B A    Little endian (e.g. x86)        DUK_USE_DOUBLE_LE\n *    D C B A H G F E    Mixed/cross endian (e.g. ARM)   DUK_USE_DOUBLE_ME\n *\n *  ARM is a special case: ARM double values are in mixed/cross endian\n *  format while ARM duk_uint64_t values are in standard little endian\n *  format (H G F E D C B A).  When a double is read as a duk_uint64_t\n *  from memory, the register will contain the (logical) value\n *  E F G H A B C D.  This requires some special handling below.\n *\n *  Indexes of various types (8-bit, 16-bit, 32-bit) in memory relative to\n *  the logical (big endian) order:\n *\n *  byte order      duk_uint8_t    duk_uint16_t     duk_uint32_t\n *    BE             01234567         0123               01\n *    LE             76543210         3210               10\n *    ME (ARM)       32107654         1032               01\n *\n *  Some processors may alter NaN values in a floating point load+store.\n *  For instance, on X86 a FLD + FSTP may convert a signaling NaN to a\n *  quiet one.  This is catastrophic when NaN space is used in packed\n *  duk_tval values.  See: misc/clang_aliasing.c.\n */\n\n#if !defined(DUK_DBLUNION_H_INCLUDED)\n#define DUK_DBLUNION_H_INCLUDED\n\n/*\n *  Union for accessing double parts, also serves as packed duk_tval\n */\n\nunion duk_double_union {\n\tdouble d;\n\tfloat f[2];\n#if defined(DUK_USE_64BIT_OPS)\n\tduk_uint64_t ull[1];\n#endif\n\tduk_uint32_t ui[2];\n\tduk_uint16_t us[4];\n\tduk_uint8_t uc[8];\n#if defined(DUK_USE_PACKED_TVAL)\n\tvoid *vp[2];  /* used by packed duk_tval, assumes sizeof(void *) == 4 */\n#endif\n};\n\ntypedef union duk_double_union duk_double_union;\n\n/*\n *  Indexes of various types with respect to big endian (logical) layout\n */\n\n#if defined(DUK_USE_DOUBLE_LE)\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBL_IDX_ULL0   0\n#endif\n#define DUK_DBL_IDX_UI0    1\n#define DUK_DBL_IDX_UI1    0\n#define DUK_DBL_IDX_US0    3\n#define DUK_DBL_IDX_US1    2\n#define DUK_DBL_IDX_US2    1\n#define DUK_DBL_IDX_US3    0\n#define DUK_DBL_IDX_UC0    7\n#define DUK_DBL_IDX_UC1    6\n#define DUK_DBL_IDX_UC2    5\n#define DUK_DBL_IDX_UC3    4\n#define DUK_DBL_IDX_UC4    3\n#define DUK_DBL_IDX_UC5    2\n#define DUK_DBL_IDX_UC6    1\n#define DUK_DBL_IDX_UC7    0\n#define DUK_DBL_IDX_VP0    DUK_DBL_IDX_UI0  /* packed tval */\n#define DUK_DBL_IDX_VP1    DUK_DBL_IDX_UI1  /* packed tval */\n#elif defined(DUK_USE_DOUBLE_BE)\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBL_IDX_ULL0   0\n#endif\n#define DUK_DBL_IDX_UI0    0\n#define DUK_DBL_IDX_UI1    1\n#define DUK_DBL_IDX_US0    0\n#define DUK_DBL_IDX_US1    1\n#define DUK_DBL_IDX_US2    2\n#define DUK_DBL_IDX_US3    3\n#define DUK_DBL_IDX_UC0    0\n#define DUK_DBL_IDX_UC1    1\n#define DUK_DBL_IDX_UC2    2\n#define DUK_DBL_IDX_UC3    3\n#define DUK_DBL_IDX_UC4    4\n#define DUK_DBL_IDX_UC5    5\n#define DUK_DBL_IDX_UC6    6\n#define DUK_DBL_IDX_UC7    7\n#define DUK_DBL_IDX_VP0    DUK_DBL_IDX_UI0  /* packed tval */\n#define DUK_DBL_IDX_VP1    DUK_DBL_IDX_UI1  /* packed tval */\n#elif defined(DUK_USE_DOUBLE_ME)\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBL_IDX_ULL0   0  /* not directly applicable, byte order differs from a double */\n#endif\n#define DUK_DBL_IDX_UI0    0\n#define DUK_DBL_IDX_UI1    1\n#define DUK_DBL_IDX_US0    1\n#define DUK_DBL_IDX_US1    0\n#define DUK_DBL_IDX_US2    3\n#define DUK_DBL_IDX_US3    2\n#define DUK_DBL_IDX_UC0    3\n#define DUK_DBL_IDX_UC1    2\n#define DUK_DBL_IDX_UC2    1\n#define DUK_DBL_IDX_UC3    0\n#define DUK_DBL_IDX_UC4    7\n#define DUK_DBL_IDX_UC5    6\n#define DUK_DBL_IDX_UC6    5\n#define DUK_DBL_IDX_UC7    4\n#define DUK_DBL_IDX_VP0    DUK_DBL_IDX_UI0  /* packed tval */\n#define DUK_DBL_IDX_VP1    DUK_DBL_IDX_UI1  /* packed tval */\n#else\n#error internal error\n#endif\n\n/*\n *  Helper macros for reading/writing memory representation parts, used\n *  by duk_numconv.c and duk_tval.h.\n */\n\n#define DUK_DBLUNION_SET_DOUBLE(u,v)  do {  \\\n\t\t(u)->d = (v); \\\n\t} while (0)\n\n#define DUK_DBLUNION_SET_HIGH32(u,v)  do {  \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) (v); \\\n\t} while (0)\n\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = (duk_uint64_t) (v); \\\n\t} while (0)\n#else\n#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = ((duk_uint64_t) (v)) << 32; \\\n\t} while (0)\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v)  do { \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) (v); \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0; \\\n\t} while (0)\n#endif  /* DUK_USE_64BIT_OPS */\n\n#define DUK_DBLUNION_SET_LOW32(u,v)  do {  \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (v); \\\n\t} while (0)\n\n#define DUK_DBLUNION_GET_DOUBLE(u)  ((u)->d)\n#define DUK_DBLUNION_GET_HIGH32(u)  ((u)->ui[DUK_DBL_IDX_UI0])\n#define DUK_DBLUNION_GET_LOW32(u)   ((u)->ui[DUK_DBL_IDX_UI1])\n\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK_DBLUNION_SET_UINT64(u,v)  do { \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) ((v) >> 32); \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (v); \\\n\t} while (0)\n#define DUK_DBLUNION_GET_UINT64(u) \\\n\t((((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI0]) << 32) | \\\n\t ((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI1]))\n#else\n#define DUK_DBLUNION_SET_UINT64(u,v)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = (duk_uint64_t) (v); \\\n\t} while (0)\n#define DUK_DBLUNION_GET_UINT64(u)  ((u)->ull[DUK_DBL_IDX_ULL0])\n#endif\n#define DUK_DBLUNION_SET_INT64(u,v) DUK_DBLUNION_SET_UINT64((u), (duk_uint64_t) (v))\n#define DUK_DBLUNION_GET_INT64(u)   ((duk_int64_t) DUK_DBLUNION_GET_UINT64((u)))\n#endif  /* DUK_USE_64BIT_OPS */\n\n/*\n *  Double NaN manipulation macros related to NaN normalization needed when\n *  using the packed duk_tval representation.  NaN normalization is necessary\n *  to keep double values compatible with the duk_tval format.\n *\n *  When packed duk_tval is used, the NaN space is used to store pointers\n *  and other tagged values in addition to NaNs.  Actual NaNs are normalized\n *  to a specific quiet NaN.  The macros below are used by the implementation\n *  to check and normalize NaN values when they might be created.  The macros\n *  are essentially NOPs when the non-packed duk_tval representation is used.\n *\n *  A FULL check is exact and checks all bits.  A NOTFULL check is used by\n *  the packed duk_tval and works correctly for all NaNs except those that\n *  begin with 0x7ff0.  Since the 'normalized NaN' values used with packed\n *  duk_tval begin with 0x7ff8, the partial check is reliable when packed\n *  duk_tval is used.  The 0x7ff8 prefix means the normalized NaN will be a\n *  quiet NaN regardless of its remaining lower bits.\n *\n *  The ME variant below is specifically for ARM byte order, which has the\n *  feature that while doubles have a mixed byte order (32107654), unsigned\n *  long long values has a little endian byte order (76543210).  When writing\n *  a logical double value through a ULL pointer, the 32-bit words need to be\n *  swapped; hence the #if defined()s below for ULL writes with DUK_USE_DOUBLE_ME.\n *  This is not full ARM support but suffices for some environments.\n */\n\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n/* Macros for 64-bit ops + mixed endian doubles. */\n#define DUK__DBLUNION_SET_NAN_FULL(u)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x000000007ff80000); \\\n\t} while (0)\n#define DUK__DBLUNION_IS_NAN_FULL(u) \\\n\t((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000)) && \\\n\t ((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0xffffffff000fffff)) != 0))\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff80000))\n#define DUK__DBLUNION_IS_ANYINF(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x000000007ff00000))\n#define DUK__DBLUNION_IS_POSINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff00000))\n#define DUK__DBLUNION_IS_NEGINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x00000000fff00000))\n#define DUK__DBLUNION_IS_ANYZERO(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_POSZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_NEGZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000080000000))\n#else\n/* Macros for 64-bit ops + big/little endian doubles. */\n#define DUK__DBLUNION_SET_NAN_FULL(u)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x7ff8000000000000); \\\n\t} while (0)\n#define DUK__DBLUNION_IS_NAN_FULL(u) \\\n\t((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000)) && \\\n\t ((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0x000fffffffffffff)) != 0))\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff8000000000000))\n#define DUK__DBLUNION_IS_ANYINF(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x7ff0000000000000))\n#define DUK__DBLUNION_IS_POSINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff0000000000000))\n#define DUK__DBLUNION_IS_NEGINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0xfff0000000000000))\n#define DUK__DBLUNION_IS_ANYZERO(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_POSZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_NEGZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x8000000000000000))\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n/* Macros for no 64-bit ops, any endianness. */\n#define DUK__DBLUNION_SET_NAN_FULL(u)  do { \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) 0x7ff80000UL; \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0x00000000UL; \\\n\t} while (0)\n#define DUK__DBLUNION_IS_NAN_FULL(u) \\\n\t((((u)->ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL) && \\\n\t (((u)->ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) != 0 || \\\n          (u)->ui[DUK_DBL_IDX_UI1] != 0))\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff80000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_ANYINF(u) \\\n\t((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x7ff00000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_POSINF(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff00000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_NEGINF(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0xfff00000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_ANYZERO(u) \\\n\t((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x00000000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_POSZERO(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x00000000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_NEGZERO(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x80000000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#endif  /* DUK_USE_64BIT_OPS */\n\n#define DUK__DBLUNION_SET_NAN_NOTFULL(u)  do { \\\n\t\t(u)->us[DUK_DBL_IDX_US0] = 0x7ff8UL; \\\n\t} while (0)\n\n#define DUK__DBLUNION_IS_NAN_NOTFULL(u) \\\n\t/* E == 0x7ff, topmost four bits of F != 0 => assume NaN */ \\\n\t((((u)->us[DUK_DBL_IDX_US0] & 0x7ff0UL) == 0x7ff0UL) && \\\n\t (((u)->us[DUK_DBL_IDX_US0] & 0x000fUL) != 0x0000UL))\n\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL(u) \\\n\t/* E == 0x7ff, F == 8 => normalized NaN */ \\\n\t((u)->us[DUK_DBL_IDX_US0] == 0x7ff8UL)\n\n#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL(u)  do { \\\n\t\tif (DUK__DBLUNION_IS_NAN_FULL((u))) { \\\n\t\t\tDUK__DBLUNION_SET_NAN_FULL((u)); \\\n\t\t} \\\n\t} while (0)\n\n#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL(u)  do { \\\n\t\tif (DUK__DBLUNION_IS_NAN_NOTFULL((u))) { \\\n\t\t\tDUK__DBLUNION_SET_NAN_NOTFULL((u)); \\\n\t\t} \\\n\t} while (0)\n\n/* Concrete macros for NaN handling used by the implementation internals.\n * Chosen so that they match the duk_tval representation: with a packed\n * duk_tval, ensure NaNs are properly normalized; with a non-packed duk_tval\n * these are essentially NOPs.\n */\n\n#if defined(DUK_USE_PACKED_TVAL)\n#if defined(DUK_USE_FULL_TVAL)\n#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u)  DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL((u))\n#define DUK_DBLUNION_IS_NAN(u)               DUK__DBLUNION_IS_NAN_FULL((u))\n#define DUK_DBLUNION_IS_NORMALIZED_NAN(u)    DUK__DBLUNION_IS_NORMALIZED_NAN_FULL((u))\n#define DUK_DBLUNION_SET_NAN(d)              DUK__DBLUNION_SET_NAN_FULL((d))\n#else\n#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u)  DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL((u))\n#define DUK_DBLUNION_IS_NAN(u)               DUK__DBLUNION_IS_NAN_NOTFULL((u))\n#define DUK_DBLUNION_IS_NORMALIZED_NAN(u)    DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL((u))\n#define DUK_DBLUNION_SET_NAN(d)              DUK__DBLUNION_SET_NAN_NOTFULL((d))\n#endif\n#define DUK_DBLUNION_IS_NORMALIZED(u) \\\n\t(!DUK_DBLUNION_IS_NAN((u)) ||  /* either not a NaN */ \\\n\t DUK_DBLUNION_IS_NORMALIZED_NAN((u)))  /* or is a normalized NaN */\n#else  /* DUK_USE_PACKED_TVAL */\n#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u)  /* nop: no need to normalize */\n#define DUK_DBLUNION_IS_NAN(u)               DUK__DBLUNION_IS_NAN_FULL((u))  /* (DUK_ISNAN((u)->d)) */\n#define DUK_DBLUNION_IS_NORMALIZED_NAN(u)    DUK__DBLUNION_IS_NAN_FULL((u))  /* (DUK_ISNAN((u)->d)) */\n#define DUK_DBLUNION_IS_NORMALIZED(u)        1  /* all doubles are considered normalized */\n#define DUK_DBLUNION_SET_NAN(u)  do { \\\n\t\t/* in non-packed representation we don't care about which NaN is used */ \\\n\t\t(u)->d = DUK_DOUBLE_NAN; \\\n\t} while (0)\n#endif  /* DUK_USE_PACKED_TVAL */\n\n#define DUK_DBLUNION_IS_ANYINF(u) DUK__DBLUNION_IS_ANYINF((u))\n#define DUK_DBLUNION_IS_POSINF(u) DUK__DBLUNION_IS_POSINF((u))\n#define DUK_DBLUNION_IS_NEGINF(u) DUK__DBLUNION_IS_NEGINF((u))\n\n#define DUK_DBLUNION_IS_ANYZERO(u) DUK__DBLUNION_IS_ANYZERO((u))\n#define DUK_DBLUNION_IS_POSZERO(u) DUK__DBLUNION_IS_POSZERO((u))\n#define DUK_DBLUNION_IS_NEGZERO(u) DUK__DBLUNION_IS_NEGZERO((u))\n\n/* XXX: native 64-bit byteswaps when available */\n\n/* 64-bit byteswap, same operation independent of target endianness. */\n#define DUK_DBLUNION_BSWAP64(u) do { \\\n\t\tduk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \\\n\t\tduk__bswaptmp1 = (u)->ui[0]; \\\n\t\tduk__bswaptmp2 = (u)->ui[1]; \\\n\t\tduk__bswaptmp1 = DUK_BSWAP32(duk__bswaptmp1); \\\n\t\tduk__bswaptmp2 = DUK_BSWAP32(duk__bswaptmp2); \\\n\t\t(u)->ui[0] = duk__bswaptmp2; \\\n\t\t(u)->ui[1] = duk__bswaptmp1; \\\n\t} while (0)\n\n/* Byteswap an IEEE double in the duk_double_union from host to network\n * order.  For a big endian target this is a no-op.\n */\n#if defined(DUK_USE_DOUBLE_LE)\n#define DUK_DBLUNION_DOUBLE_HTON(u) do { \\\n\t\tduk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \\\n\t\tduk__bswaptmp1 = (u)->ui[0]; \\\n\t\tduk__bswaptmp2 = (u)->ui[1]; \\\n\t\tduk__bswaptmp1 = DUK_BSWAP32(duk__bswaptmp1); \\\n\t\tduk__bswaptmp2 = DUK_BSWAP32(duk__bswaptmp2); \\\n\t\t(u)->ui[0] = duk__bswaptmp2; \\\n\t\t(u)->ui[1] = duk__bswaptmp1; \\\n\t} while (0)\n#elif defined(DUK_USE_DOUBLE_ME)\n#define DUK_DBLUNION_DOUBLE_HTON(u) do { \\\n\t\tduk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \\\n\t\tduk__bswaptmp1 = (u)->ui[0]; \\\n\t\tduk__bswaptmp2 = (u)->ui[1]; \\\n\t\tduk__bswaptmp1 = DUK_BSWAP32(duk__bswaptmp1); \\\n\t\tduk__bswaptmp2 = DUK_BSWAP32(duk__bswaptmp2); \\\n\t\t(u)->ui[0] = duk__bswaptmp1; \\\n\t\t(u)->ui[1] = duk__bswaptmp2; \\\n\t} while (0)\n#elif defined(DUK_USE_DOUBLE_BE)\n#define DUK_DBLUNION_DOUBLE_HTON(u) do { } while (0)\n#else\n#error internal error, double endianness insane\n#endif\n\n/* Reverse operation is the same. */\n#define DUK_DBLUNION_DOUBLE_NTOH(u) DUK_DBLUNION_DOUBLE_HTON((u))\n\n/* Some sign bit helpers. */\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBLUNION_HAS_SIGNBIT(u) (((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x8000000000000000)) != 0)\n#define DUK_DBLUNION_GET_SIGNBIT(u) (((u)->ull[DUK_DBL_IDX_ULL0] >> 63U))\n#else\n#define DUK_DBLUNION_HAS_SIGNBIT(u) (((u)->ui[DUK_DBL_IDX_UI0] & 0x80000000UL) != 0)\n#define DUK_DBLUNION_GET_SIGNBIT(u) (((u)->ui[DUK_DBL_IDX_UI0] >> 31U))\n#endif\n\n#endif  /* DUK_DBLUNION_H_INCLUDED */\n/* #include duk_replacements.h */\n#line 1 \"duk_replacements.h\"\n#if !defined(DUK_REPLACEMENTS_H_INCLUDED)\n#define DUK_REPLACEMENTS_H_INCLUDED\n\n#if !defined(DUK_SINGLE_FILE)\n#if defined(DUK_USE_COMPUTED_INFINITY)\nDUK_INTERNAL_DECL double duk_computed_infinity;\n#endif\n#if defined(DUK_USE_COMPUTED_NAN)\nDUK_INTERNAL_DECL double duk_computed_nan;\n#endif\n#endif  /* !DUK_SINGLE_FILE */\n\n#if defined(DUK_USE_REPL_FPCLASSIFY)\nDUK_INTERNAL_DECL int duk_repl_fpclassify(double x);\n#endif\n#if defined(DUK_USE_REPL_SIGNBIT)\nDUK_INTERNAL_DECL int duk_repl_signbit(double x);\n#endif\n#if defined(DUK_USE_REPL_ISFINITE)\nDUK_INTERNAL_DECL int duk_repl_isfinite(double x);\n#endif\n#if defined(DUK_USE_REPL_ISNAN)\nDUK_INTERNAL_DECL int duk_repl_isnan(double x);\n#endif\n#if defined(DUK_USE_REPL_ISINF)\nDUK_INTERNAL_DECL int duk_repl_isinf(double x);\n#endif\n\n#endif  /* DUK_REPLACEMENTS_H_INCLUDED */\n/* #include duk_jmpbuf.h */\n#line 1 \"duk_jmpbuf.h\"\n/*\n *  Wrapper for jmp_buf.\n *\n *  This is used because jmp_buf is an array type for backward compatibility.\n *  Wrapping jmp_buf in a struct makes pointer references, sizeof, etc,\n *  behave more intuitively.\n *\n *  http://en.wikipedia.org/wiki/Setjmp.h#Member_types\n */\n\n#if !defined(DUK_JMPBUF_H_INCLUDED)\n#define DUK_JMPBUF_H_INCLUDED\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\nstruct duk_jmpbuf {\n\tduk_small_int_t dummy;  /* unused */\n};\n#else\nstruct duk_jmpbuf {\n\tDUK_JMPBUF_TYPE jb;\n};\n#endif\n\n#endif  /* DUK_JMPBUF_H_INCLUDED */\n/* #include duk_exception.h */\n#line 1 \"duk_exception.h\"\n/*\n *  Exceptions for Duktape internal throws when C++ exceptions are used\n *  for long control transfers.\n */\n\n#if !defined(DUK_EXCEPTION_H_INCLUDED)\n#define DUK_EXCEPTION_H_INCLUDED\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n/* Internal exception used as a setjmp-longjmp replacement.  User code should\n * NEVER see or catch this exception, so it doesn't inherit from any base\n * class which should minimize the chance of user code accidentally catching\n * the exception.\n */\nclass duk_internal_exception {\n\t/* intentionally empty */\n};\n\n/* Fatal error, thrown as a specific C++ exception with C++ exceptions\n * enabled.  It is unsafe to continue; doing so may cause crashes or memory\n * leaks.  This is intended to be either uncaught, or caught by user code\n * aware of the \"unsafe to continue\" semantics.\n */\nclass duk_fatal_exception : public virtual std::runtime_error {\n public:\n\tduk_fatal_exception(const char *message) : std::runtime_error(message) {}\n};\n#endif\n\n#endif  /* DUK_EXCEPTION_H_INCLUDED */\n/* #include duk_forwdecl.h */\n#line 1 \"duk_forwdecl.h\"\n/*\n *  Forward declarations for all Duktape structures.\n */\n\n#if !defined(DUK_FORWDECL_H_INCLUDED)\n#define DUK_FORWDECL_H_INCLUDED\n\n/*\n *  Forward declarations\n */\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\nclass duk_internal_exception;\n#else\nstruct duk_jmpbuf;\n#endif\n\n/* duk_tval intentionally skipped */\nstruct duk_heaphdr;\nstruct duk_heaphdr_string;\nstruct duk_harray;\nstruct duk_hstring;\nstruct duk_hstring_external;\nstruct duk_hobject;\nstruct duk_hcompfunc;\nstruct duk_hnatfunc;\nstruct duk_hboundfunc;\nstruct duk_hthread;\nstruct duk_hbufobj;\nstruct duk_hdecenv;\nstruct duk_hobjenv;\nstruct duk_hproxy;\nstruct duk_hbuffer;\nstruct duk_hbuffer_fixed;\nstruct duk_hbuffer_dynamic;\nstruct duk_hbuffer_external;\n\nstruct duk_propaccessor;\nunion duk_propvalue;\nstruct duk_propdesc;\n\nstruct duk_heap;\nstruct duk_breakpoint;\n\nstruct duk_activation;\nstruct duk_catcher;\nstruct duk_ljstate;\nstruct duk_strcache_entry;\nstruct duk_litcache_entry;\nstruct duk_strtab_entry;\n\n#if defined(DUK_USE_DEBUG)\nstruct duk_fixedbuffer;\n#endif\n\nstruct duk_bitdecoder_ctx;\nstruct duk_bitencoder_ctx;\nstruct duk_bufwriter_ctx;\n\nstruct duk_token;\nstruct duk_re_token;\nstruct duk_lexer_point;\nstruct duk_lexer_ctx;\nstruct duk_lexer_codepoint;\n\nstruct duk_compiler_instr;\nstruct duk_compiler_func;\nstruct duk_compiler_ctx;\n\nstruct duk_re_matcher_ctx;\nstruct duk_re_compiler_ctx;\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n/* no typedef */\n#else\ntypedef struct duk_jmpbuf duk_jmpbuf;\n#endif\n\n/* duk_tval intentionally skipped */\ntypedef struct duk_heaphdr duk_heaphdr;\ntypedef struct duk_heaphdr_string duk_heaphdr_string;\ntypedef struct duk_harray duk_harray;\ntypedef struct duk_hstring duk_hstring;\ntypedef struct duk_hstring_external duk_hstring_external;\ntypedef struct duk_hobject duk_hobject;\ntypedef struct duk_hcompfunc duk_hcompfunc;\ntypedef struct duk_hnatfunc duk_hnatfunc;\ntypedef struct duk_hboundfunc duk_hboundfunc;\ntypedef struct duk_hthread duk_hthread;\ntypedef struct duk_hbufobj duk_hbufobj;\ntypedef struct duk_hdecenv duk_hdecenv;\ntypedef struct duk_hobjenv duk_hobjenv;\ntypedef struct duk_hproxy duk_hproxy;\ntypedef struct duk_hbuffer duk_hbuffer;\ntypedef struct duk_hbuffer_fixed duk_hbuffer_fixed;\ntypedef struct duk_hbuffer_dynamic duk_hbuffer_dynamic;\ntypedef struct duk_hbuffer_external duk_hbuffer_external;\n\ntypedef struct duk_propaccessor duk_propaccessor;\ntypedef union duk_propvalue duk_propvalue;\ntypedef struct duk_propdesc duk_propdesc;\n\ntypedef struct duk_heap duk_heap;\ntypedef struct duk_breakpoint duk_breakpoint;\n\ntypedef struct duk_activation duk_activation;\ntypedef struct duk_catcher duk_catcher;\ntypedef struct duk_ljstate duk_ljstate;\ntypedef struct duk_strcache_entry duk_strcache_entry;\ntypedef struct duk_litcache_entry duk_litcache_entry;\ntypedef struct duk_strtab_entry duk_strtab_entry;\n\n#if defined(DUK_USE_DEBUG)\ntypedef struct duk_fixedbuffer duk_fixedbuffer;\n#endif\n\ntypedef struct duk_bitdecoder_ctx duk_bitdecoder_ctx;\ntypedef struct duk_bitencoder_ctx duk_bitencoder_ctx;\ntypedef struct duk_bufwriter_ctx duk_bufwriter_ctx;\n\ntypedef struct duk_token duk_token;\ntypedef struct duk_re_token duk_re_token;\ntypedef struct duk_lexer_point duk_lexer_point;\ntypedef struct duk_lexer_ctx duk_lexer_ctx;\ntypedef struct duk_lexer_codepoint duk_lexer_codepoint;\n\ntypedef struct duk_compiler_instr duk_compiler_instr;\ntypedef struct duk_compiler_func duk_compiler_func;\ntypedef struct duk_compiler_ctx duk_compiler_ctx;\n\ntypedef struct duk_re_matcher_ctx duk_re_matcher_ctx;\ntypedef struct duk_re_compiler_ctx duk_re_compiler_ctx;\n\n#endif  /* DUK_FORWDECL_H_INCLUDED */\n/* #include duk_tval.h */\n#line 1 \"duk_tval.h\"\n/*\n *  Tagged type definition (duk_tval) and accessor macros.\n *\n *  Access all fields through the accessor macros, as the representation\n *  is quite tricky.\n *\n *  There are two packed type alternatives: an 8-byte representation\n *  based on an IEEE double (preferred for compactness), and a 12-byte\n *  representation (portability).  The latter is needed also in e.g.\n *  64-bit environments (it usually pads to 16 bytes per value).\n *\n *  Selecting the tagged type format involves many trade-offs (memory\n *  use, size and performance of generated code, portability, etc).\n *\n *  NB: because macro arguments are often expressions, macros should\n *  avoid evaluating their argument more than once.\n */\n\n#if !defined(DUK_TVAL_H_INCLUDED)\n#define DUK_TVAL_H_INCLUDED\n\n/* sanity */\n#if !defined(DUK_USE_DOUBLE_LE) && !defined(DUK_USE_DOUBLE_ME) && !defined(DUK_USE_DOUBLE_BE)\n#error unsupported: cannot determine byte order variant\n#endif\n\n#if defined(DUK_USE_PACKED_TVAL)\n/* ======================================================================== */\n\n/*\n *  Packed 8-byte representation\n */\n\n/* use duk_double_union as duk_tval directly */\ntypedef union duk_double_union duk_tval;\ntypedef struct {\n\tduk_uint16_t a;\n\tduk_uint16_t b;\n\tduk_uint16_t c;\n\tduk_uint16_t d;\n} duk_tval_unused;\n\n/* tags */\n#define DUK_TAG_NORMALIZED_NAN    0x7ff8UL   /* the NaN variant we use */\n/* avoid tag 0xfff0, no risk of confusion with negative infinity */\n#define DUK_TAG_MIN               0xfff1UL\n#if defined(DUK_USE_FASTINT)\n#define DUK_TAG_FASTINT           0xfff1UL   /* embed: integer value */\n#endif\n#define DUK_TAG_UNUSED            0xfff2UL   /* marker; not actual tagged value */\n#define DUK_TAG_UNDEFINED         0xfff3UL   /* embed: nothing */\n#define DUK_TAG_NULL              0xfff4UL   /* embed: nothing */\n#define DUK_TAG_BOOLEAN           0xfff5UL   /* embed: 0 or 1 (false or true) */\n/* DUK_TAG_NUMBER would logically go here, but it has multiple 'tags' */\n#define DUK_TAG_POINTER           0xfff6UL   /* embed: void ptr */\n#define DUK_TAG_LIGHTFUNC         0xfff7UL   /* embed: func ptr */\n#define DUK_TAG_STRING            0xfff8UL   /* embed: duk_hstring ptr */\n#define DUK_TAG_OBJECT            0xfff9UL   /* embed: duk_hobject ptr */\n#define DUK_TAG_BUFFER            0xfffaUL   /* embed: duk_hbuffer ptr */\n#define DUK_TAG_MAX               0xfffaUL\n\n/* for convenience */\n#define DUK_XTAG_BOOLEAN_FALSE    0xfff50000UL\n#define DUK_XTAG_BOOLEAN_TRUE     0xfff50001UL\n\n#define DUK_TVAL_IS_VALID_TAG(tv) \\\n\t(DUK_TVAL_GET_TAG((tv)) - DUK_TAG_MIN <= DUK_TAG_MAX - DUK_TAG_MIN)\n\n/* DUK_TVAL_UNUSED initializer for duk_tval_unused, works for any endianness. */\n#define DUK_TVAL_UNUSED_INITIALIZER() \\\n\t{ DUK_TAG_UNUSED, DUK_TAG_UNUSED, DUK_TAG_UNUSED, DUK_TAG_UNUSED }\n\n/* two casts to avoid gcc warning: \"warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]\" */\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) (tag)) << 16) | (((duk_uint64_t) (duk_uint32_t) (h)) << 32); \\\n\t} while (0)\n#else\n#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) (tag)) << 48) | ((duk_uint64_t) (duk_uint32_t) (h)); \\\n\t} while (0)\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) (tag)) << 16; \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (h); \\\n\t} while (0)\n#endif  /* DUK_USE_64BIT_OPS */\n\n#if defined(DUK_USE_64BIT_OPS)\n/* Double casting for pointer to avoid gcc warning (cast from pointer to integer of different size) */\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_LIGHTFUNC) << 16) | \\\n\t\t                              ((duk_uint64_t) (flags)) | \\\n\t\t                              (((duk_uint64_t) (duk_uint32_t) (fp)) << 32); \\\n\t} while (0)\n#else\n#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_LIGHTFUNC) << 48) | \\\n\t\t                              (((duk_uint64_t) (flags)) << 32) | \\\n\t\t                              ((duk_uint64_t) (duk_uint32_t) (fp)); \\\n\t} while (0)\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = (((duk_uint32_t) DUK_TAG_LIGHTFUNC) << 16) | ((duk_uint32_t) (flags)); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (fp); \\\n\t} while (0)\n#endif  /* DUK_USE_64BIT_OPS */\n\n#if defined(DUK_USE_FASTINT)\n/* Note: masking is done for 'i' to deal with negative numbers correctly */\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_SET_I48(tv,i)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) DUK_TAG_FASTINT) << 16 | (((duk_uint32_t) ((i) >> 32)) & 0x0000ffffUL); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (i); \\\n\t} while (0)\n#define DUK__TVAL_SET_U32(tv,i)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) DUK_TAG_FASTINT) << 16; \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (i); \\\n\t} while (0)\n#else\n#define DUK__TVAL_SET_I48(tv,i)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (((duk_uint64_t) (i)) & DUK_U64_CONSTANT(0x0000ffffffffffff)); \\\n\t} while (0)\n#define DUK__TVAL_SET_U32(tv,i)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (duk_uint64_t) (i); \\\n\t} while (0)\n#endif\n\n/* This needs to go through a cast because sign extension is needed. */\n#define DUK__TVAL_SET_I32(tv,i)  do { \\\n\t\tduk_int64_t duk__tmp = (duk_int64_t) (i); \\\n\t\tDUK_TVAL_SET_I48((tv), duk__tmp); \\\n\t} while (0)\n\n/* XXX: Clumsy sign extend and masking of 16 topmost bits. */\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_GET_FASTINT(tv)      (((duk_int64_t) ((((duk_uint64_t) (tv)->ui[DUK_DBL_IDX_UI0]) << 32) | ((duk_uint64_t) (tv)->ui[DUK_DBL_IDX_UI1]))) << 16 >> 16)\n#else\n#define DUK__TVAL_GET_FASTINT(tv)      ((((duk_int64_t) (tv)->ull[DUK_DBL_IDX_ULL0]) << 16) >> 16)\n#endif\n#define DUK__TVAL_GET_FASTINT_U32(tv)  ((tv)->ui[DUK_DBL_IDX_UI1])\n#define DUK__TVAL_GET_FASTINT_I32(tv)  ((duk_int32_t) (tv)->ui[DUK_DBL_IDX_UI1])\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_UNDEFINED(tv)  do { \\\n\t\t(tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNDEFINED; \\\n\t} while (0)\n#define DUK_TVAL_SET_UNUSED(tv)  do { \\\n\t\t(tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNUSED; \\\n\t} while (0)\n#define DUK_TVAL_SET_NULL(tv)  do { \\\n\t\t(tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_NULL; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN(tv,val)         DUK_DBLUNION_SET_HIGH32((tv), (((duk_uint32_t) DUK_TAG_BOOLEAN) << 16) | ((duk_uint32_t) (val)))\n\n#define DUK_TVAL_SET_NAN(tv)                 DUK_DBLUNION_SET_NAN_FULL((tv))\n\n/* Assumes that caller has normalized NaNs, otherwise trouble ahead. */\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_DOUBLE(tv,d)  do { \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (d); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); \\\n\t\tDUK_DBLUNION_SET_DOUBLE((tv), duk__dblval); \\\n\t} while (0)\n#define DUK_TVAL_SET_I48(tv,i)               DUK__TVAL_SET_I48((tv), (i))\n#define DUK_TVAL_SET_I32(tv,i)               DUK__TVAL_SET_I32((tv), (i))\n#define DUK_TVAL_SET_U32(tv,i)               DUK__TVAL_SET_U32((tv), (i))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d)  duk_tval_set_number_chkfast_fast((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d)  duk_tval_set_number_chkfast_slow((tv), (d))\n#define DUK_TVAL_SET_NUMBER(tv,d)            DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#else  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_DOUBLE(tv,d)  do { \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (d); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); \\\n\t\tDUK_DBLUNION_SET_DOUBLE((tv), duk__dblval); \\\n\t} while (0)\n#define DUK_TVAL_SET_I48(tv,i)               DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i))  /* XXX: fast int-to-double */\n#define DUK_TVAL_SET_I32(tv,i)               DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i))\n#define DUK_TVAL_SET_U32(tv,i)               DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d)    DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d)    DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_SET_NUMBER(tv,d)            DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { } while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { } while (0)\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_FASTINT(tv,i)           DUK_TVAL_SET_I48((tv), (i))  /* alias */\n\n#define DUK_TVAL_SET_LIGHTFUNC(tv,fp,flags)  DUK__TVAL_SET_LIGHTFUNC((tv), (fp), (flags))\n#define DUK_TVAL_SET_STRING(tv,h)            DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_STRING)\n#define DUK_TVAL_SET_OBJECT(tv,h)            DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_OBJECT)\n#define DUK_TVAL_SET_BUFFER(tv,h)            DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_BUFFER)\n#define DUK_TVAL_SET_POINTER(tv,p)           DUK__TVAL_SET_TAGGEDPOINTER((tv), (p), DUK_TAG_POINTER)\n\n#define DUK_TVAL_SET_TVAL(tv,x)              do { *(tv) = *(x); } while (0)\n\n/* getters */\n#define DUK_TVAL_GET_BOOLEAN(tv)             ((duk_small_uint_t) (tv)->us[DUK_DBL_IDX_US1])\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_GET_DOUBLE(tv)              ((tv)->d)\n#define DUK_TVAL_GET_FASTINT(tv)             DUK__TVAL_GET_FASTINT((tv))\n#define DUK_TVAL_GET_FASTINT_U32(tv)         DUK__TVAL_GET_FASTINT_U32((tv))\n#define DUK_TVAL_GET_FASTINT_I32(tv)         DUK__TVAL_GET_FASTINT_I32((tv))\n#define DUK_TVAL_GET_NUMBER(tv)              duk_tval_get_number_packed((tv))\n#else\n#define DUK_TVAL_GET_NUMBER(tv)              ((tv)->d)\n#define DUK_TVAL_GET_DOUBLE(tv)              ((tv)->d)\n#endif\n#define DUK_TVAL_GET_LIGHTFUNC(tv,out_fp,out_flags)  do { \\\n\t\t(out_flags) = (tv)->ui[DUK_DBL_IDX_UI0] & 0xffffUL; \\\n\t\t(out_fp) = (duk_c_function) (tv)->ui[DUK_DBL_IDX_UI1]; \\\n\t} while (0)\n#define DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv)   ((duk_c_function) ((tv)->ui[DUK_DBL_IDX_UI1]))\n#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv)     (((duk_small_uint_t) (tv)->ui[DUK_DBL_IDX_UI0]) & 0xffffUL)\n#define DUK_TVAL_GET_STRING(tv)              ((duk_hstring *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_OBJECT(tv)              ((duk_hobject *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_BUFFER(tv)              ((duk_hbuffer *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_POINTER(tv)             ((void *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_HEAPHDR(tv)             ((duk_heaphdr *) (tv)->vp[DUK_DBL_IDX_VP1])\n\n/* decoding */\n#define DUK_TVAL_GET_TAG(tv)                 ((duk_small_uint_t) (tv)->us[DUK_DBL_IDX_US0])\n\n#define DUK_TVAL_IS_UNDEFINED(tv)            (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_UNDEFINED)\n#define DUK_TVAL_IS_UNUSED(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_UNUSED)\n#define DUK_TVAL_IS_NULL(tv)                 (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_NULL)\n#define DUK_TVAL_IS_BOOLEAN(tv)              (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_BOOLEAN)\n#define DUK_TVAL_IS_BOOLEAN_TRUE(tv)         ((tv)->ui[DUK_DBL_IDX_UI0] == DUK_XTAG_BOOLEAN_TRUE)\n#define DUK_TVAL_IS_BOOLEAN_FALSE(tv)        ((tv)->ui[DUK_DBL_IDX_UI0] == DUK_XTAG_BOOLEAN_FALSE)\n#define DUK_TVAL_IS_LIGHTFUNC(tv)            (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_LIGHTFUNC)\n#define DUK_TVAL_IS_STRING(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_STRING)\n#define DUK_TVAL_IS_OBJECT(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_OBJECT)\n#define DUK_TVAL_IS_BUFFER(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_BUFFER)\n#define DUK_TVAL_IS_POINTER(tv)              (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_POINTER)\n#if defined(DUK_USE_FASTINT)\n/* 0xfff0 is -Infinity */\n#define DUK_TVAL_IS_DOUBLE(tv)               (DUK_TVAL_GET_TAG((tv)) <= 0xfff0UL)\n#define DUK_TVAL_IS_FASTINT(tv)              (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_FASTINT)\n#define DUK_TVAL_IS_NUMBER(tv)               (DUK_TVAL_GET_TAG((tv)) <= 0xfff1UL)\n#else\n#define DUK_TVAL_IS_NUMBER(tv)               (DUK_TVAL_GET_TAG((tv)) <= 0xfff0UL)\n#define DUK_TVAL_IS_DOUBLE(tv)               DUK_TVAL_IS_NUMBER((tv))\n#endif\n\n/* This is performance critical because it appears in every DECREF. */\n#define DUK_TVAL_IS_HEAP_ALLOCATED(tv)       (DUK_TVAL_GET_TAG((tv)) >= DUK_TAG_STRING)\n\n#if defined(DUK_USE_FASTINT)\nDUK_INTERNAL_DECL duk_double_t duk_tval_get_number_packed(duk_tval *tv);\n#endif\n\n#else  /* DUK_USE_PACKED_TVAL */\n/* ======================================================================== */\n\n/*\n *  Portable 12-byte representation\n */\n\n/* Note: not initializing all bytes is normally not an issue: Duktape won't\n * read or use the uninitialized bytes so valgrind won't issue warnings.\n * In some special cases a harmless valgrind warning may be issued though.\n * For example, the DumpHeap debugger command writes out a compiled function's\n * 'data' area as is, including any uninitialized bytes, which causes a\n * valgrind warning.\n */\n\ntypedef struct duk_tval_struct duk_tval;\n\nstruct duk_tval_struct {\n\tduk_small_uint_t t;\n\tduk_small_uint_t v_extra;\n\tunion {\n\t\tduk_double_t d;\n\t\tduk_small_int_t i;\n#if defined(DUK_USE_FASTINT)\n\t\tduk_int64_t fi;  /* if present, forces 16-byte duk_tval */\n#endif\n\t\tvoid *voidptr;\n\t\tduk_hstring *hstring;\n\t\tduk_hobject *hobject;\n\t\tduk_hcompfunc *hcompfunc;\n\t\tduk_hnatfunc *hnatfunc;\n\t\tduk_hthread *hthread;\n\t\tduk_hbuffer *hbuffer;\n\t\tduk_heaphdr *heaphdr;\n\t\tduk_c_function lightfunc;\n\t} v;\n};\n\ntypedef struct {\n\tduk_small_uint_t t;\n\tduk_small_uint_t v_extra;\n\t/* The rest of the fields don't matter except for debug dumps and such\n\t * for which a partial initializer may trigger out-ot-bounds memory\n\t * reads.  Include a double field which is usually as large or larger\n\t * than pointers (not always however).\n\t */\n\tduk_double_t d;\n} duk_tval_unused;\n\n#define DUK_TVAL_UNUSED_INITIALIZER() \\\n\t{ DUK_TAG_UNUSED, 0, 0.0 }\n\n#define DUK_TAG_MIN                   0\n#define DUK_TAG_NUMBER                0  /* DUK_TAG_NUMBER only defined for non-packed duk_tval */\n#if defined(DUK_USE_FASTINT)\n#define DUK_TAG_FASTINT               1\n#endif\n#define DUK_TAG_UNDEFINED             2\n#define DUK_TAG_NULL                  3\n#define DUK_TAG_BOOLEAN               4\n#define DUK_TAG_POINTER               5\n#define DUK_TAG_LIGHTFUNC             6\n#define DUK_TAG_UNUSED                7  /* marker; not actual tagged type */\n#define DUK_TAG_STRING                8  /* first heap allocated, match bit boundary */\n#define DUK_TAG_OBJECT                9\n#define DUK_TAG_BUFFER                10\n#define DUK_TAG_MAX                   10\n\n#define DUK_TVAL_IS_VALID_TAG(tv) \\\n\t(DUK_TVAL_GET_TAG((tv)) - DUK_TAG_MIN <= DUK_TAG_MAX - DUK_TAG_MIN)\n\n/* DUK_TAG_NUMBER is intentionally first, as it is the default clause in code\n * to support the 8-byte representation.  Further, it is a non-heap-allocated\n * type so it should come before DUK_TAG_STRING.  Finally, it should not break\n * the tag value ranges covered by case-clauses in a switch-case.\n */\n\n/* setters */\n#define DUK_TVAL_SET_UNDEFINED(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_UNDEFINED; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNUSED(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_UNUSED; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NULL(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NULL; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_BOOLEAN; \\\n\t\tduk__tv->v.i = (duk_small_int_t) (val); \\\n\t} while (0)\n\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_DOUBLE(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (val); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); /* nop for unpacked duk_tval */ \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NUMBER; \\\n\t\tduk__tv->v.d = duk__dblval; \\\n\t} while (0)\n#define DUK_TVAL_SET_I48(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_FASTINT; \\\n\t\tduk__tv->v.fi = (val); \\\n\t} while (0)\n#define DUK_TVAL_SET_U32(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_FASTINT; \\\n\t\tduk__tv->v.fi = (duk_int64_t) (val); \\\n\t} while (0)\n#define DUK_TVAL_SET_I32(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_FASTINT; \\\n\t\tduk__tv->v.fi = (duk_int64_t) (val); \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) \\\n\tduk_tval_set_number_chkfast_fast((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) \\\n\tduk_tval_set_number_chkfast_slow((tv), (d))\n#define DUK_TVAL_SET_NUMBER(tv,val) \\\n\tDUK_TVAL_SET_DOUBLE((tv), (val))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#else  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_DOUBLE(tv,d) \\\n\tDUK_TVAL_SET_NUMBER((tv), (d))\n#define DUK_TVAL_SET_I48(tv,val) \\\n\tDUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val))  /* XXX: fast int-to-double */\n#define DUK_TVAL_SET_U32(tv,val) \\\n\tDUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val))\n#define DUK_TVAL_SET_I32(tv,val) \\\n\tDUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val))\n#define DUK_TVAL_SET_NUMBER(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (val); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); /* nop for unpacked duk_tval */ \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NUMBER; \\\n\t\tduk__tv->v.d = duk__dblval; \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) \\\n\tDUK_TVAL_SET_NUMBER((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) \\\n\tDUK_TVAL_SET_NUMBER((tv), (d))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { } while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { } while (0)\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_FASTINT(tv,i) \\\n\tDUK_TVAL_SET_I48((tv), (i))  /* alias */\n\n#define DUK_TVAL_SET_POINTER(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_POINTER; \\\n\t\tduk__tv->v.voidptr = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_LIGHTFUNC; \\\n\t\tduk__tv->v_extra = (flags); \\\n\t\tduk__tv->v.lightfunc = (duk_c_function) (fp); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_STRING(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_STRING; \\\n\t\tduk__tv->v.hstring = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_OBJECT(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_OBJECT; \\\n\t\tduk__tv->v.hobject = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BUFFER(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_BUFFER; \\\n\t\tduk__tv->v.hbuffer = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NAN(tv)  do { \\\n\t\t/* in non-packed representation we don't care about which NaN is used */ \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NUMBER; \\\n\t\tduk__tv->v.d = DUK_DOUBLE_NAN; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_TVAL(tv,x)            do { *(tv) = *(x); } while (0)\n\n/* getters */\n#define DUK_TVAL_GET_BOOLEAN(tv)           ((duk_small_uint_t) (tv)->v.i)\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_GET_DOUBLE(tv)            ((tv)->v.d)\n#define DUK_TVAL_GET_FASTINT(tv)           ((tv)->v.fi)\n#define DUK_TVAL_GET_FASTINT_U32(tv)       ((duk_uint32_t) ((tv)->v.fi))\n#define DUK_TVAL_GET_FASTINT_I32(tv)       ((duk_int32_t) ((tv)->v.fi))\n#if 0\n#define DUK_TVAL_GET_NUMBER(tv)            (DUK_TVAL_IS_FASTINT((tv)) ? \\\n                                               (duk_double_t) DUK_TVAL_GET_FASTINT((tv)) : \\\n                                               DUK_TVAL_GET_DOUBLE((tv)))\n#define DUK_TVAL_GET_NUMBER(tv)            duk_tval_get_number_unpacked((tv))\n#else\n/* This seems reasonable overall. */\n#define DUK_TVAL_GET_NUMBER(tv)            (DUK_TVAL_IS_FASTINT((tv)) ? \\\n                                               duk_tval_get_number_unpacked_fastint((tv)) : \\\n                                               DUK_TVAL_GET_DOUBLE((tv)))\n#endif\n#else\n#define DUK_TVAL_GET_NUMBER(tv)            ((tv)->v.d)\n#define DUK_TVAL_GET_DOUBLE(tv)            ((tv)->v.d)\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_GET_POINTER(tv)           ((tv)->v.voidptr)\n#define DUK_TVAL_GET_LIGHTFUNC(tv,out_fp,out_flags)  do { \\\n\t\t(out_flags) = (duk_uint32_t) (tv)->v_extra; \\\n\t\t(out_fp) = (tv)->v.lightfunc; \\\n\t} while (0)\n#define DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv) ((tv)->v.lightfunc)\n#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv)   ((duk_small_uint_t) ((tv)->v_extra))\n#define DUK_TVAL_GET_STRING(tv)            ((tv)->v.hstring)\n#define DUK_TVAL_GET_OBJECT(tv)            ((tv)->v.hobject)\n#define DUK_TVAL_GET_BUFFER(tv)            ((tv)->v.hbuffer)\n#define DUK_TVAL_GET_HEAPHDR(tv)           ((tv)->v.heaphdr)\n\n/* decoding */\n#define DUK_TVAL_GET_TAG(tv)               ((tv)->t)\n#define DUK_TVAL_IS_UNDEFINED(tv)          ((tv)->t == DUK_TAG_UNDEFINED)\n#define DUK_TVAL_IS_UNUSED(tv)             ((tv)->t == DUK_TAG_UNUSED)\n#define DUK_TVAL_IS_NULL(tv)               ((tv)->t == DUK_TAG_NULL)\n#define DUK_TVAL_IS_BOOLEAN(tv)            ((tv)->t == DUK_TAG_BOOLEAN)\n#define DUK_TVAL_IS_BOOLEAN_TRUE(tv)       (((tv)->t == DUK_TAG_BOOLEAN) && ((tv)->v.i != 0))\n#define DUK_TVAL_IS_BOOLEAN_FALSE(tv)      (((tv)->t == DUK_TAG_BOOLEAN) && ((tv)->v.i == 0))\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_IS_DOUBLE(tv)             ((tv)->t == DUK_TAG_NUMBER)\n#define DUK_TVAL_IS_FASTINT(tv)            ((tv)->t == DUK_TAG_FASTINT)\n#define DUK_TVAL_IS_NUMBER(tv)             ((tv)->t == DUK_TAG_NUMBER || \\\n                                            (tv)->t == DUK_TAG_FASTINT)\n#else\n#define DUK_TVAL_IS_NUMBER(tv)             ((tv)->t == DUK_TAG_NUMBER)\n#define DUK_TVAL_IS_DOUBLE(tv)             DUK_TVAL_IS_NUMBER((tv))\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_IS_POINTER(tv)            ((tv)->t == DUK_TAG_POINTER)\n#define DUK_TVAL_IS_LIGHTFUNC(tv)          ((tv)->t == DUK_TAG_LIGHTFUNC)\n#define DUK_TVAL_IS_STRING(tv)             ((tv)->t == DUK_TAG_STRING)\n#define DUK_TVAL_IS_OBJECT(tv)             ((tv)->t == DUK_TAG_OBJECT)\n#define DUK_TVAL_IS_BUFFER(tv)             ((tv)->t == DUK_TAG_BUFFER)\n\n/* This is performance critical because it's needed for every DECREF.\n * Take advantage of the fact that the first heap allocated tag is 8,\n * so that bit 3 is set for all heap allocated tags (and never set for\n * non-heap-allocated tags).\n */\n#if 0\n#define DUK_TVAL_IS_HEAP_ALLOCATED(tv)     ((tv)->t >= DUK_TAG_STRING)\n#endif\n#define DUK_TVAL_IS_HEAP_ALLOCATED(tv)     ((tv)->t & 0x08)\n\n#if defined(DUK_USE_FASTINT)\n#if 0\nDUK_INTERNAL_DECL duk_double_t duk_tval_get_number_unpacked(duk_tval *tv);\n#endif\nDUK_INTERNAL_DECL duk_double_t duk_tval_get_number_unpacked_fastint(duk_tval *tv);\n#endif\n\n#endif  /* DUK_USE_PACKED_TVAL */\n\n/*\n *  Convenience (independent of representation)\n */\n\n#define DUK_TVAL_SET_BOOLEAN_TRUE(tv)        DUK_TVAL_SET_BOOLEAN((tv), 1)\n#define DUK_TVAL_SET_BOOLEAN_FALSE(tv)       DUK_TVAL_SET_BOOLEAN((tv), 0)\n\n#define DUK_TVAL_STRING_IS_SYMBOL(tv) \\\n\tDUK_HSTRING_HAS_SYMBOL(DUK_TVAL_GET_STRING((tv)))\n\n/* Lightfunc flags packing and unpacking. */\n/* Sign extend: 0x0000##00 -> 0x##000000 -> sign extend to 0xssssss##.\n * Avoid signed shifts due to portability limitations.\n */\n#define DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags) \\\n\t((duk_int32_t) (duk_int8_t) (((duk_uint16_t) (lf_flags)) >> 8))\n#define DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags) \\\n\t(((lf_flags) >> 4) & 0x0fU)\n#define DUK_LFUNC_FLAGS_GET_NARGS(lf_flags) \\\n\t((lf_flags) & 0x0fU)\n#define DUK_LFUNC_FLAGS_PACK(magic,length,nargs) \\\n\t((((duk_small_uint_t) (magic)) & 0xffU) << 8) | ((length) << 4) | (nargs)\n\n#define DUK_LFUNC_NARGS_VARARGS             0x0f   /* varargs marker */\n#define DUK_LFUNC_NARGS_MIN                 0x00\n#define DUK_LFUNC_NARGS_MAX                 0x0e   /* max, excl. varargs marker */\n#define DUK_LFUNC_LENGTH_MIN                0x00\n#define DUK_LFUNC_LENGTH_MAX                0x0f\n#define DUK_LFUNC_MAGIC_MIN                 (-0x80)\n#define DUK_LFUNC_MAGIC_MAX                 0x7f\n\n/* fastint constants etc */\n#if defined(DUK_USE_FASTINT)\n#define DUK_FASTINT_MIN           (DUK_I64_CONSTANT(-0x800000000000))\n#define DUK_FASTINT_MAX           (DUK_I64_CONSTANT(0x7fffffffffff))\n#define DUK_FASTINT_BITS          48\n\nDUK_INTERNAL_DECL void duk_tval_set_number_chkfast_fast(duk_tval *tv, duk_double_t x);\nDUK_INTERNAL_DECL void duk_tval_set_number_chkfast_slow(duk_tval *tv, duk_double_t x);\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_tval_assert_valid(duk_tval *tv);\n#define DUK_TVAL_ASSERT_VALID(tv)  do { duk_tval_assert_valid((tv)); } while (0)\n#else\n#define DUK_TVAL_ASSERT_VALID(tv)  do {} while (0)\n#endif\n\n#endif  /* DUK_TVAL_H_INCLUDED */\n/* #include duk_builtins.h */\n#line 1 \"duk_builtins.h\"\n/*\n *  Automatically generated by genbuiltins.py, do not edit!\n */\n\n#if !defined(DUK_BUILTINS_H_INCLUDED)\n#define DUK_BUILTINS_H_INCLUDED\n\n#if defined(DUK_USE_ROM_STRINGS)\n#error ROM support not enabled, rerun configure.py with --rom-support\n#else  /* DUK_USE_ROM_STRINGS */\n#define DUK_STRIDX_UC_UNDEFINED                                       0                              /* 'Undefined' */\n#define DUK_HEAP_STRING_UC_UNDEFINED(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_UNDEFINED)\n#define DUK_HTHREAD_STRING_UC_UNDEFINED(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_UNDEFINED)\n#define DUK_STRIDX_UC_NULL                                            1                              /* 'Null' */\n#define DUK_HEAP_STRING_UC_NULL(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_NULL)\n#define DUK_HTHREAD_STRING_UC_NULL(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_NULL)\n#define DUK_STRIDX_UC_SYMBOL                                          2                              /* 'Symbol' */\n#define DUK_HEAP_STRING_UC_SYMBOL(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_SYMBOL)\n#define DUK_HTHREAD_STRING_UC_SYMBOL(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_SYMBOL)\n#define DUK_STRIDX_UC_ARGUMENTS                                       3                              /* 'Arguments' */\n#define DUK_HEAP_STRING_UC_ARGUMENTS(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_ARGUMENTS)\n#define DUK_HTHREAD_STRING_UC_ARGUMENTS(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_ARGUMENTS)\n#define DUK_STRIDX_UC_OBJECT                                          4                              /* 'Object' */\n#define DUK_HEAP_STRING_UC_OBJECT(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_OBJECT)\n#define DUK_HTHREAD_STRING_UC_OBJECT(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_OBJECT)\n#define DUK_STRIDX_UC_FUNCTION                                        5                              /* 'Function' */\n#define DUK_HEAP_STRING_UC_FUNCTION(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_FUNCTION)\n#define DUK_HTHREAD_STRING_UC_FUNCTION(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_FUNCTION)\n#define DUK_STRIDX_ARRAY                                              6                              /* 'Array' */\n#define DUK_HEAP_STRING_ARRAY(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ARRAY)\n#define DUK_HTHREAD_STRING_ARRAY(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ARRAY)\n#define DUK_STRIDX_UC_STRING                                          7                              /* 'String' */\n#define DUK_HEAP_STRING_UC_STRING(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_STRING)\n#define DUK_HTHREAD_STRING_UC_STRING(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_STRING)\n#define DUK_STRIDX_UC_BOOLEAN                                         8                              /* 'Boolean' */\n#define DUK_HEAP_STRING_UC_BOOLEAN(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_BOOLEAN)\n#define DUK_HTHREAD_STRING_UC_BOOLEAN(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_BOOLEAN)\n#define DUK_STRIDX_UC_NUMBER                                          9                              /* 'Number' */\n#define DUK_HEAP_STRING_UC_NUMBER(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_NUMBER)\n#define DUK_HTHREAD_STRING_UC_NUMBER(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_NUMBER)\n#define DUK_STRIDX_DATE                                               10                             /* 'Date' */\n#define DUK_HEAP_STRING_DATE(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DATE)\n#define DUK_HTHREAD_STRING_DATE(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DATE)\n#define DUK_STRIDX_REG_EXP                                            11                             /* 'RegExp' */\n#define DUK_HEAP_STRING_REG_EXP(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_REG_EXP)\n#define DUK_HTHREAD_STRING_REG_EXP(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_REG_EXP)\n#define DUK_STRIDX_UC_ERROR                                           12                             /* 'Error' */\n#define DUK_HEAP_STRING_UC_ERROR(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_ERROR)\n#define DUK_HTHREAD_STRING_UC_ERROR(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_ERROR)\n#define DUK_STRIDX_MATH                                               13                             /* 'Math' */\n#define DUK_HEAP_STRING_MATH(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MATH)\n#define DUK_HTHREAD_STRING_MATH(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MATH)\n#define DUK_STRIDX_JSON                                               14                             /* 'JSON' */\n#define DUK_HEAP_STRING_JSON(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON)\n#define DUK_HTHREAD_STRING_JSON(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON)\n#define DUK_STRIDX_EMPTY_STRING                                       15                             /* '' */\n#define DUK_HEAP_STRING_EMPTY_STRING(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EMPTY_STRING)\n#define DUK_HTHREAD_STRING_EMPTY_STRING(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EMPTY_STRING)\n#define DUK_STRIDX_ARRAY_BUFFER                                       16                             /* 'ArrayBuffer' */\n#define DUK_HEAP_STRING_ARRAY_BUFFER(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ARRAY_BUFFER)\n#define DUK_HTHREAD_STRING_ARRAY_BUFFER(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ARRAY_BUFFER)\n#define DUK_STRIDX_DATA_VIEW                                          17                             /* 'DataView' */\n#define DUK_HEAP_STRING_DATA_VIEW(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DATA_VIEW)\n#define DUK_HTHREAD_STRING_DATA_VIEW(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DATA_VIEW)\n#define DUK_STRIDX_INT8_ARRAY                                         18                             /* 'Int8Array' */\n#define DUK_HEAP_STRING_INT8_ARRAY(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT8_ARRAY)\n#define DUK_HTHREAD_STRING_INT8_ARRAY(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT8_ARRAY)\n#define DUK_STRIDX_UINT8_ARRAY                                        19                             /* 'Uint8Array' */\n#define DUK_HEAP_STRING_UINT8_ARRAY(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT8_ARRAY)\n#define DUK_HTHREAD_STRING_UINT8_ARRAY(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT8_ARRAY)\n#define DUK_STRIDX_UINT8_CLAMPED_ARRAY                                20                             /* 'Uint8ClampedArray' */\n#define DUK_HEAP_STRING_UINT8_CLAMPED_ARRAY(heap)                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT8_CLAMPED_ARRAY)\n#define DUK_HTHREAD_STRING_UINT8_CLAMPED_ARRAY(thr)                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT8_CLAMPED_ARRAY)\n#define DUK_STRIDX_INT16_ARRAY                                        21                             /* 'Int16Array' */\n#define DUK_HEAP_STRING_INT16_ARRAY(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT16_ARRAY)\n#define DUK_HTHREAD_STRING_INT16_ARRAY(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT16_ARRAY)\n#define DUK_STRIDX_UINT16_ARRAY                                       22                             /* 'Uint16Array' */\n#define DUK_HEAP_STRING_UINT16_ARRAY(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT16_ARRAY)\n#define DUK_HTHREAD_STRING_UINT16_ARRAY(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT16_ARRAY)\n#define DUK_STRIDX_INT32_ARRAY                                        23                             /* 'Int32Array' */\n#define DUK_HEAP_STRING_INT32_ARRAY(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT32_ARRAY)\n#define DUK_HTHREAD_STRING_INT32_ARRAY(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT32_ARRAY)\n#define DUK_STRIDX_UINT32_ARRAY                                       24                             /* 'Uint32Array' */\n#define DUK_HEAP_STRING_UINT32_ARRAY(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT32_ARRAY)\n#define DUK_HTHREAD_STRING_UINT32_ARRAY(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT32_ARRAY)\n#define DUK_STRIDX_FLOAT32_ARRAY                                      25                             /* 'Float32Array' */\n#define DUK_HEAP_STRING_FLOAT32_ARRAY(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FLOAT32_ARRAY)\n#define DUK_HTHREAD_STRING_FLOAT32_ARRAY(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FLOAT32_ARRAY)\n#define DUK_STRIDX_FLOAT64_ARRAY                                      26                             /* 'Float64Array' */\n#define DUK_HEAP_STRING_FLOAT64_ARRAY(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FLOAT64_ARRAY)\n#define DUK_HTHREAD_STRING_FLOAT64_ARRAY(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FLOAT64_ARRAY)\n#define DUK_STRIDX_GLOBAL                                             27                             /* 'global' */\n#define DUK_HEAP_STRING_GLOBAL(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_GLOBAL)\n#define DUK_HTHREAD_STRING_GLOBAL(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_GLOBAL)\n#define DUK_STRIDX_OBJ_ENV                                            28                             /* 'ObjEnv' */\n#define DUK_HEAP_STRING_OBJ_ENV(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_OBJ_ENV)\n#define DUK_HTHREAD_STRING_OBJ_ENV(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_OBJ_ENV)\n#define DUK_STRIDX_DEC_ENV                                            29                             /* 'DecEnv' */\n#define DUK_HEAP_STRING_DEC_ENV(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEC_ENV)\n#define DUK_HTHREAD_STRING_DEC_ENV(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEC_ENV)\n#define DUK_STRIDX_UC_BUFFER                                          30                             /* 'Buffer' */\n#define DUK_HEAP_STRING_UC_BUFFER(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_BUFFER)\n#define DUK_HTHREAD_STRING_UC_BUFFER(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_BUFFER)\n#define DUK_STRIDX_UC_POINTER                                         31                             /* 'Pointer' */\n#define DUK_HEAP_STRING_UC_POINTER(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_POINTER)\n#define DUK_HTHREAD_STRING_UC_POINTER(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_POINTER)\n#define DUK_STRIDX_UC_THREAD                                          32                             /* 'Thread' */\n#define DUK_HEAP_STRING_UC_THREAD(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_THREAD)\n#define DUK_HTHREAD_STRING_UC_THREAD(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_THREAD)\n#define DUK_STRIDX_EVAL                                               33                             /* 'eval' */\n#define DUK_HEAP_STRING_EVAL(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EVAL)\n#define DUK_HTHREAD_STRING_EVAL(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EVAL)\n#define DUK_STRIDX_VALUE                                              34                             /* 'value' */\n#define DUK_HEAP_STRING_VALUE(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VALUE)\n#define DUK_HTHREAD_STRING_VALUE(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VALUE)\n#define DUK_STRIDX_WRITABLE                                           35                             /* 'writable' */\n#define DUK_HEAP_STRING_WRITABLE(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WRITABLE)\n#define DUK_HTHREAD_STRING_WRITABLE(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WRITABLE)\n#define DUK_STRIDX_CONFIGURABLE                                       36                             /* 'configurable' */\n#define DUK_HEAP_STRING_CONFIGURABLE(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONFIGURABLE)\n#define DUK_HTHREAD_STRING_CONFIGURABLE(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONFIGURABLE)\n#define DUK_STRIDX_ENUMERABLE                                         37                             /* 'enumerable' */\n#define DUK_HEAP_STRING_ENUMERABLE(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENUMERABLE)\n#define DUK_HTHREAD_STRING_ENUMERABLE(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENUMERABLE)\n#define DUK_STRIDX_JOIN                                               38                             /* 'join' */\n#define DUK_HEAP_STRING_JOIN(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JOIN)\n#define DUK_HTHREAD_STRING_JOIN(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JOIN)\n#define DUK_STRIDX_TO_LOCALE_STRING                                   39                             /* 'toLocaleString' */\n#define DUK_HEAP_STRING_TO_LOCALE_STRING(heap)                        DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_LOCALE_STRING)\n#define DUK_HTHREAD_STRING_TO_LOCALE_STRING(thr)                      DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_LOCALE_STRING)\n#define DUK_STRIDX_VALUE_OF                                           40                             /* 'valueOf' */\n#define DUK_HEAP_STRING_VALUE_OF(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VALUE_OF)\n#define DUK_HTHREAD_STRING_VALUE_OF(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VALUE_OF)\n#define DUK_STRIDX_TO_UTC_STRING                                      41                             /* 'toUTCString' */\n#define DUK_HEAP_STRING_TO_UTC_STRING(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_UTC_STRING)\n#define DUK_HTHREAD_STRING_TO_UTC_STRING(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_UTC_STRING)\n#define DUK_STRIDX_TO_ISO_STRING                                      42                             /* 'toISOString' */\n#define DUK_HEAP_STRING_TO_ISO_STRING(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_ISO_STRING)\n#define DUK_HTHREAD_STRING_TO_ISO_STRING(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_ISO_STRING)\n#define DUK_STRIDX_TO_GMT_STRING                                      43                             /* 'toGMTString' */\n#define DUK_HEAP_STRING_TO_GMT_STRING(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_GMT_STRING)\n#define DUK_HTHREAD_STRING_TO_GMT_STRING(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_GMT_STRING)\n#define DUK_STRIDX_SOURCE                                             44                             /* 'source' */\n#define DUK_HEAP_STRING_SOURCE(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SOURCE)\n#define DUK_HTHREAD_STRING_SOURCE(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SOURCE)\n#define DUK_STRIDX_IGNORE_CASE                                        45                             /* 'ignoreCase' */\n#define DUK_HEAP_STRING_IGNORE_CASE(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IGNORE_CASE)\n#define DUK_HTHREAD_STRING_IGNORE_CASE(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IGNORE_CASE)\n#define DUK_STRIDX_MULTILINE                                          46                             /* 'multiline' */\n#define DUK_HEAP_STRING_MULTILINE(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MULTILINE)\n#define DUK_HTHREAD_STRING_MULTILINE(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MULTILINE)\n#define DUK_STRIDX_LAST_INDEX                                         47                             /* 'lastIndex' */\n#define DUK_HEAP_STRING_LAST_INDEX(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LAST_INDEX)\n#define DUK_HTHREAD_STRING_LAST_INDEX(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LAST_INDEX)\n#define DUK_STRIDX_FLAGS                                              48                             /* 'flags' */\n#define DUK_HEAP_STRING_FLAGS(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FLAGS)\n#define DUK_HTHREAD_STRING_FLAGS(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FLAGS)\n#define DUK_STRIDX_INDEX                                              49                             /* 'index' */\n#define DUK_HEAP_STRING_INDEX(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INDEX)\n#define DUK_HTHREAD_STRING_INDEX(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INDEX)\n#define DUK_STRIDX_PROTOTYPE                                          50                             /* 'prototype' */\n#define DUK_HEAP_STRING_PROTOTYPE(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PROTOTYPE)\n#define DUK_HTHREAD_STRING_PROTOTYPE(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PROTOTYPE)\n#define DUK_STRIDX_CONSTRUCTOR                                        51                             /* 'constructor' */\n#define DUK_HEAP_STRING_CONSTRUCTOR(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONSTRUCTOR)\n#define DUK_HTHREAD_STRING_CONSTRUCTOR(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONSTRUCTOR)\n#define DUK_STRIDX_MESSAGE                                            52                             /* 'message' */\n#define DUK_HEAP_STRING_MESSAGE(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MESSAGE)\n#define DUK_HTHREAD_STRING_MESSAGE(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MESSAGE)\n#define DUK_STRIDX_LC_BOOLEAN                                         53                             /* 'boolean' */\n#define DUK_HEAP_STRING_LC_BOOLEAN(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_BOOLEAN)\n#define DUK_HTHREAD_STRING_LC_BOOLEAN(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_BOOLEAN)\n#define DUK_STRIDX_LC_NUMBER                                          54                             /* 'number' */\n#define DUK_HEAP_STRING_LC_NUMBER(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_NUMBER)\n#define DUK_HTHREAD_STRING_LC_NUMBER(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_NUMBER)\n#define DUK_STRIDX_LC_STRING                                          55                             /* 'string' */\n#define DUK_HEAP_STRING_LC_STRING(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_STRING)\n#define DUK_HTHREAD_STRING_LC_STRING(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_STRING)\n#define DUK_STRIDX_LC_SYMBOL                                          56                             /* 'symbol' */\n#define DUK_HEAP_STRING_LC_SYMBOL(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_SYMBOL)\n#define DUK_HTHREAD_STRING_LC_SYMBOL(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_SYMBOL)\n#define DUK_STRIDX_LC_OBJECT                                          57                             /* 'object' */\n#define DUK_HEAP_STRING_LC_OBJECT(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_OBJECT)\n#define DUK_HTHREAD_STRING_LC_OBJECT(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_OBJECT)\n#define DUK_STRIDX_LC_UNDEFINED                                       58                             /* 'undefined' */\n#define DUK_HEAP_STRING_LC_UNDEFINED(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_UNDEFINED)\n#define DUK_HTHREAD_STRING_LC_UNDEFINED(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_UNDEFINED)\n#define DUK_STRIDX_NAN                                                59                             /* 'NaN' */\n#define DUK_HEAP_STRING_NAN(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NAN)\n#define DUK_HTHREAD_STRING_NAN(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NAN)\n#define DUK_STRIDX_INFINITY                                           60                             /* 'Infinity' */\n#define DUK_HEAP_STRING_INFINITY(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INFINITY)\n#define DUK_HTHREAD_STRING_INFINITY(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INFINITY)\n#define DUK_STRIDX_MINUS_INFINITY                                     61                             /* '-Infinity' */\n#define DUK_HEAP_STRING_MINUS_INFINITY(heap)                          DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MINUS_INFINITY)\n#define DUK_HTHREAD_STRING_MINUS_INFINITY(thr)                        DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MINUS_INFINITY)\n#define DUK_STRIDX_MINUS_ZERO                                         62                             /* '-0' */\n#define DUK_HEAP_STRING_MINUS_ZERO(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MINUS_ZERO)\n#define DUK_HTHREAD_STRING_MINUS_ZERO(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MINUS_ZERO)\n#define DUK_STRIDX_COMMA                                              63                             /* ',' */\n#define DUK_HEAP_STRING_COMMA(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_COMMA)\n#define DUK_HTHREAD_STRING_COMMA(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_COMMA)\n#define DUK_STRIDX_NEWLINE_4SPACE                                     64                             /* '\\n    ' */\n#define DUK_HEAP_STRING_NEWLINE_4SPACE(heap)                          DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NEWLINE_4SPACE)\n#define DUK_HTHREAD_STRING_NEWLINE_4SPACE(thr)                        DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NEWLINE_4SPACE)\n#define DUK_STRIDX_BRACKETED_ELLIPSIS                                 65                             /* '[...]' */\n#define DUK_HEAP_STRING_BRACKETED_ELLIPSIS(heap)                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BRACKETED_ELLIPSIS)\n#define DUK_HTHREAD_STRING_BRACKETED_ELLIPSIS(thr)                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BRACKETED_ELLIPSIS)\n#define DUK_STRIDX_INVALID_DATE                                       66                             /* 'Invalid Date' */\n#define DUK_HEAP_STRING_INVALID_DATE(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INVALID_DATE)\n#define DUK_HTHREAD_STRING_INVALID_DATE(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INVALID_DATE)\n#define DUK_STRIDX_LC_ARGUMENTS                                       67                             /* 'arguments' */\n#define DUK_HEAP_STRING_LC_ARGUMENTS(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_ARGUMENTS)\n#define DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_ARGUMENTS)\n#define DUK_STRIDX_CALLEE                                             68                             /* 'callee' */\n#define DUK_HEAP_STRING_CALLEE(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CALLEE)\n#define DUK_HTHREAD_STRING_CALLEE(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CALLEE)\n#define DUK_STRIDX_CALLER                                             69                             /* 'caller' */\n#define DUK_HEAP_STRING_CALLER(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CALLER)\n#define DUK_HTHREAD_STRING_CALLER(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CALLER)\n#define DUK_STRIDX_APPLY                                              70                             /* 'apply' */\n#define DUK_HEAP_STRING_APPLY(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_APPLY)\n#define DUK_HTHREAD_STRING_APPLY(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_APPLY)\n#define DUK_STRIDX_CONSTRUCT                                          71                             /* 'construct' */\n#define DUK_HEAP_STRING_CONSTRUCT(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONSTRUCT)\n#define DUK_HTHREAD_STRING_CONSTRUCT(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONSTRUCT)\n#define DUK_STRIDX_DELETE_PROPERTY                                    72                             /* 'deleteProperty' */\n#define DUK_HEAP_STRING_DELETE_PROPERTY(heap)                         DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DELETE_PROPERTY)\n#define DUK_HTHREAD_STRING_DELETE_PROPERTY(thr)                       DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DELETE_PROPERTY)\n#define DUK_STRIDX_GET                                                73                             /* 'get' */\n#define DUK_HEAP_STRING_GET(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_GET)\n#define DUK_HTHREAD_STRING_GET(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_GET)\n#define DUK_STRIDX_HAS                                                74                             /* 'has' */\n#define DUK_HEAP_STRING_HAS(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_HAS)\n#define DUK_HTHREAD_STRING_HAS(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_HAS)\n#define DUK_STRIDX_OWN_KEYS                                           75                             /* 'ownKeys' */\n#define DUK_HEAP_STRING_OWN_KEYS(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_OWN_KEYS)\n#define DUK_HTHREAD_STRING_OWN_KEYS(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_OWN_KEYS)\n#define DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE                      76                             /* '\\x81Symbol.toPrimitive\\xff' */\n#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_TO_PRIMITIVE(heap)           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE)\n#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_TO_PRIMITIVE(thr)         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE)\n#define DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE                      77                             /* '\\x81Symbol.hasInstance\\xff' */\n#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_HAS_INSTANCE(heap)           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE)\n#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_HAS_INSTANCE(thr)         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE)\n#define DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG                     78                             /* '\\x81Symbol.toStringTag\\xff' */\n#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_TO_STRING_TAG(heap)          DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG)\n#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_TO_STRING_TAG(thr)        DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG)\n#define DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE              79                             /* '\\x81Symbol.isConcatSpreadable\\xff' */\n#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE(heap)   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE)\n#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE(thr)  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE)\n#define DUK_STRIDX_SET_PROTOTYPE_OF                                   80                             /* 'setPrototypeOf' */\n#define DUK_HEAP_STRING_SET_PROTOTYPE_OF(heap)                        DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SET_PROTOTYPE_OF)\n#define DUK_HTHREAD_STRING_SET_PROTOTYPE_OF(thr)                      DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SET_PROTOTYPE_OF)\n#define DUK_STRIDX___PROTO__                                          81                             /* '__proto__' */\n#define DUK_HEAP_STRING___PROTO__(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX___PROTO__)\n#define DUK_HTHREAD_STRING___PROTO__(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX___PROTO__)\n#define DUK_STRIDX_TO_STRING                                          82                             /* 'toString' */\n#define DUK_HEAP_STRING_TO_STRING(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_STRING)\n#define DUK_HTHREAD_STRING_TO_STRING(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_STRING)\n#define DUK_STRIDX_TO_JSON                                            83                             /* 'toJSON' */\n#define DUK_HEAP_STRING_TO_JSON(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_JSON)\n#define DUK_HTHREAD_STRING_TO_JSON(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_JSON)\n#define DUK_STRIDX_TYPE                                               84                             /* 'type' */\n#define DUK_HEAP_STRING_TYPE(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TYPE)\n#define DUK_HTHREAD_STRING_TYPE(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TYPE)\n#define DUK_STRIDX_DATA                                               85                             /* 'data' */\n#define DUK_HEAP_STRING_DATA(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DATA)\n#define DUK_HTHREAD_STRING_DATA(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DATA)\n#define DUK_STRIDX_LENGTH                                             86                             /* 'length' */\n#define DUK_HEAP_STRING_LENGTH(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LENGTH)\n#define DUK_HTHREAD_STRING_LENGTH(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LENGTH)\n#define DUK_STRIDX_SET                                                87                             /* 'set' */\n#define DUK_HEAP_STRING_SET(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SET)\n#define DUK_HTHREAD_STRING_SET(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SET)\n#define DUK_STRIDX_STACK                                              88                             /* 'stack' */\n#define DUK_HEAP_STRING_STACK(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_STACK)\n#define DUK_HTHREAD_STRING_STACK(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_STACK)\n#define DUK_STRIDX_PC                                                 89                             /* 'pc' */\n#define DUK_HEAP_STRING_PC(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PC)\n#define DUK_HTHREAD_STRING_PC(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PC)\n#define DUK_STRIDX_LINE_NUMBER                                        90                             /* 'lineNumber' */\n#define DUK_HEAP_STRING_LINE_NUMBER(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LINE_NUMBER)\n#define DUK_HTHREAD_STRING_LINE_NUMBER(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LINE_NUMBER)\n#define DUK_STRIDX_INT_TRACEDATA                                      91                             /* '\\x82Tracedata' */\n#define DUK_HEAP_STRING_INT_TRACEDATA(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_TRACEDATA)\n#define DUK_HTHREAD_STRING_INT_TRACEDATA(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_TRACEDATA)\n#define DUK_STRIDX_NAME                                               92                             /* 'name' */\n#define DUK_HEAP_STRING_NAME(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NAME)\n#define DUK_HTHREAD_STRING_NAME(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NAME)\n#define DUK_STRIDX_FILE_NAME                                          93                             /* 'fileName' */\n#define DUK_HEAP_STRING_FILE_NAME(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FILE_NAME)\n#define DUK_HTHREAD_STRING_FILE_NAME(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FILE_NAME)\n#define DUK_STRIDX_LC_POINTER                                         94                             /* 'pointer' */\n#define DUK_HEAP_STRING_LC_POINTER(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_POINTER)\n#define DUK_HTHREAD_STRING_LC_POINTER(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_POINTER)\n#define DUK_STRIDX_INT_TARGET                                         95                             /* '\\x82Target' */\n#define DUK_HEAP_STRING_INT_TARGET(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_TARGET)\n#define DUK_HTHREAD_STRING_INT_TARGET(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_TARGET)\n#define DUK_STRIDX_INT_NEXT                                           96                             /* '\\x82Next' */\n#define DUK_HEAP_STRING_INT_NEXT(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_NEXT)\n#define DUK_HTHREAD_STRING_INT_NEXT(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_NEXT)\n#define DUK_STRIDX_INT_BYTECODE                                       97                             /* '\\x82Bytecode' */\n#define DUK_HEAP_STRING_INT_BYTECODE(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_BYTECODE)\n#define DUK_HTHREAD_STRING_INT_BYTECODE(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_BYTECODE)\n#define DUK_STRIDX_INT_FORMALS                                        98                             /* '\\x82Formals' */\n#define DUK_HEAP_STRING_INT_FORMALS(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_FORMALS)\n#define DUK_HTHREAD_STRING_INT_FORMALS(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_FORMALS)\n#define DUK_STRIDX_INT_VARMAP                                         99                             /* '\\x82Varmap' */\n#define DUK_HEAP_STRING_INT_VARMAP(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VARMAP)\n#define DUK_HTHREAD_STRING_INT_VARMAP(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VARMAP)\n#define DUK_STRIDX_INT_SOURCE                                         100                            /* '\\x82Source' */\n#define DUK_HEAP_STRING_INT_SOURCE(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_SOURCE)\n#define DUK_HTHREAD_STRING_INT_SOURCE(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_SOURCE)\n#define DUK_STRIDX_INT_PC2LINE                                        101                            /* '\\x82Pc2line' */\n#define DUK_HEAP_STRING_INT_PC2LINE(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_PC2LINE)\n#define DUK_HTHREAD_STRING_INT_PC2LINE(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_PC2LINE)\n#define DUK_STRIDX_INT_MAP                                            102                            /* '\\x82Map' */\n#define DUK_HEAP_STRING_INT_MAP(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_MAP)\n#define DUK_HTHREAD_STRING_INT_MAP(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_MAP)\n#define DUK_STRIDX_INT_VARENV                                         103                            /* '\\x82Varenv' */\n#define DUK_HEAP_STRING_INT_VARENV(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VARENV)\n#define DUK_HTHREAD_STRING_INT_VARENV(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VARENV)\n#define DUK_STRIDX_INT_FINALIZER                                      104                            /* '\\x82Finalizer' */\n#define DUK_HEAP_STRING_INT_FINALIZER(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_FINALIZER)\n#define DUK_HTHREAD_STRING_INT_FINALIZER(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_FINALIZER)\n#define DUK_STRIDX_INT_VALUE                                          105                            /* '\\x82Value' */\n#define DUK_HEAP_STRING_INT_VALUE(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VALUE)\n#define DUK_HTHREAD_STRING_INT_VALUE(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VALUE)\n#define DUK_STRIDX_COMPILE                                            106                            /* 'compile' */\n#define DUK_HEAP_STRING_COMPILE(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_COMPILE)\n#define DUK_HTHREAD_STRING_COMPILE(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_COMPILE)\n#define DUK_STRIDX_INPUT                                              107                            /* 'input' */\n#define DUK_HEAP_STRING_INPUT(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INPUT)\n#define DUK_HTHREAD_STRING_INPUT(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INPUT)\n#define DUK_STRIDX_ERR_CREATE                                         108                            /* 'errCreate' */\n#define DUK_HEAP_STRING_ERR_CREATE(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ERR_CREATE)\n#define DUK_HTHREAD_STRING_ERR_CREATE(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ERR_CREATE)\n#define DUK_STRIDX_ERR_THROW                                          109                            /* 'errThrow' */\n#define DUK_HEAP_STRING_ERR_THROW(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ERR_THROW)\n#define DUK_HTHREAD_STRING_ERR_THROW(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ERR_THROW)\n#define DUK_STRIDX_ENV                                                110                            /* 'env' */\n#define DUK_HEAP_STRING_ENV(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENV)\n#define DUK_HTHREAD_STRING_ENV(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENV)\n#define DUK_STRIDX_HEX                                                111                            /* 'hex' */\n#define DUK_HEAP_STRING_HEX(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_HEX)\n#define DUK_HTHREAD_STRING_HEX(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_HEX)\n#define DUK_STRIDX_BASE64                                             112                            /* 'base64' */\n#define DUK_HEAP_STRING_BASE64(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BASE64)\n#define DUK_HTHREAD_STRING_BASE64(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BASE64)\n#define DUK_STRIDX_JX                                                 113                            /* 'jx' */\n#define DUK_HEAP_STRING_JX(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JX)\n#define DUK_HTHREAD_STRING_JX(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JX)\n#define DUK_STRIDX_JC                                                 114                            /* 'jc' */\n#define DUK_HEAP_STRING_JC(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JC)\n#define DUK_HTHREAD_STRING_JC(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JC)\n#define DUK_STRIDX_JSON_EXT_UNDEFINED                                 115                            /* '{\"_undef\":true}' */\n#define DUK_HEAP_STRING_JSON_EXT_UNDEFINED(heap)                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_UNDEFINED)\n#define DUK_HTHREAD_STRING_JSON_EXT_UNDEFINED(thr)                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_UNDEFINED)\n#define DUK_STRIDX_JSON_EXT_NAN                                       116                            /* '{\"_nan\":true}' */\n#define DUK_HEAP_STRING_JSON_EXT_NAN(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_NAN)\n#define DUK_HTHREAD_STRING_JSON_EXT_NAN(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_NAN)\n#define DUK_STRIDX_JSON_EXT_POSINF                                    117                            /* '{\"_inf\":true}' */\n#define DUK_HEAP_STRING_JSON_EXT_POSINF(heap)                         DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_POSINF)\n#define DUK_HTHREAD_STRING_JSON_EXT_POSINF(thr)                       DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_POSINF)\n#define DUK_STRIDX_JSON_EXT_NEGINF                                    118                            /* '{\"_ninf\":true}' */\n#define DUK_HEAP_STRING_JSON_EXT_NEGINF(heap)                         DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_NEGINF)\n#define DUK_HTHREAD_STRING_JSON_EXT_NEGINF(thr)                       DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_NEGINF)\n#define DUK_STRIDX_JSON_EXT_FUNCTION1                                 119                            /* '{\"_func\":true}' */\n#define DUK_HEAP_STRING_JSON_EXT_FUNCTION1(heap)                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_FUNCTION1)\n#define DUK_HTHREAD_STRING_JSON_EXT_FUNCTION1(thr)                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_FUNCTION1)\n#define DUK_STRIDX_JSON_EXT_FUNCTION2                                 120                            /* '{_func:true}' */\n#define DUK_HEAP_STRING_JSON_EXT_FUNCTION2(heap)                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_FUNCTION2)\n#define DUK_HTHREAD_STRING_JSON_EXT_FUNCTION2(thr)                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_FUNCTION2)\n#define DUK_STRIDX_BREAK                                              121                            /* 'break' */\n#define DUK_HEAP_STRING_BREAK(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BREAK)\n#define DUK_HTHREAD_STRING_BREAK(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BREAK)\n#define DUK_STRIDX_CASE                                               122                            /* 'case' */\n#define DUK_HEAP_STRING_CASE(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CASE)\n#define DUK_HTHREAD_STRING_CASE(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CASE)\n#define DUK_STRIDX_CATCH                                              123                            /* 'catch' */\n#define DUK_HEAP_STRING_CATCH(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CATCH)\n#define DUK_HTHREAD_STRING_CATCH(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CATCH)\n#define DUK_STRIDX_CONTINUE                                           124                            /* 'continue' */\n#define DUK_HEAP_STRING_CONTINUE(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONTINUE)\n#define DUK_HTHREAD_STRING_CONTINUE(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONTINUE)\n#define DUK_STRIDX_DEBUGGER                                           125                            /* 'debugger' */\n#define DUK_HEAP_STRING_DEBUGGER(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEBUGGER)\n#define DUK_HTHREAD_STRING_DEBUGGER(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEBUGGER)\n#define DUK_STRIDX_DEFAULT                                            126                            /* 'default' */\n#define DUK_HEAP_STRING_DEFAULT(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEFAULT)\n#define DUK_HTHREAD_STRING_DEFAULT(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEFAULT)\n#define DUK_STRIDX_DELETE                                             127                            /* 'delete' */\n#define DUK_HEAP_STRING_DELETE(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DELETE)\n#define DUK_HTHREAD_STRING_DELETE(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DELETE)\n#define DUK_STRIDX_DO                                                 128                            /* 'do' */\n#define DUK_HEAP_STRING_DO(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DO)\n#define DUK_HTHREAD_STRING_DO(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DO)\n#define DUK_STRIDX_ELSE                                               129                            /* 'else' */\n#define DUK_HEAP_STRING_ELSE(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ELSE)\n#define DUK_HTHREAD_STRING_ELSE(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ELSE)\n#define DUK_STRIDX_FINALLY                                            130                            /* 'finally' */\n#define DUK_HEAP_STRING_FINALLY(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FINALLY)\n#define DUK_HTHREAD_STRING_FINALLY(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FINALLY)\n#define DUK_STRIDX_FOR                                                131                            /* 'for' */\n#define DUK_HEAP_STRING_FOR(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FOR)\n#define DUK_HTHREAD_STRING_FOR(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FOR)\n#define DUK_STRIDX_LC_FUNCTION                                        132                            /* 'function' */\n#define DUK_HEAP_STRING_LC_FUNCTION(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_FUNCTION)\n#define DUK_HTHREAD_STRING_LC_FUNCTION(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_FUNCTION)\n#define DUK_STRIDX_IF                                                 133                            /* 'if' */\n#define DUK_HEAP_STRING_IF(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IF)\n#define DUK_HTHREAD_STRING_IF(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IF)\n#define DUK_STRIDX_IN                                                 134                            /* 'in' */\n#define DUK_HEAP_STRING_IN(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IN)\n#define DUK_HTHREAD_STRING_IN(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IN)\n#define DUK_STRIDX_INSTANCEOF                                         135                            /* 'instanceof' */\n#define DUK_HEAP_STRING_INSTANCEOF(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INSTANCEOF)\n#define DUK_HTHREAD_STRING_INSTANCEOF(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INSTANCEOF)\n#define DUK_STRIDX_NEW                                                136                            /* 'new' */\n#define DUK_HEAP_STRING_NEW(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NEW)\n#define DUK_HTHREAD_STRING_NEW(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NEW)\n#define DUK_STRIDX_RETURN                                             137                            /* 'return' */\n#define DUK_HEAP_STRING_RETURN(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_RETURN)\n#define DUK_HTHREAD_STRING_RETURN(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_RETURN)\n#define DUK_STRIDX_SWITCH                                             138                            /* 'switch' */\n#define DUK_HEAP_STRING_SWITCH(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SWITCH)\n#define DUK_HTHREAD_STRING_SWITCH(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SWITCH)\n#define DUK_STRIDX_THIS                                               139                            /* 'this' */\n#define DUK_HEAP_STRING_THIS(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_THIS)\n#define DUK_HTHREAD_STRING_THIS(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_THIS)\n#define DUK_STRIDX_THROW                                              140                            /* 'throw' */\n#define DUK_HEAP_STRING_THROW(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_THROW)\n#define DUK_HTHREAD_STRING_THROW(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_THROW)\n#define DUK_STRIDX_TRY                                                141                            /* 'try' */\n#define DUK_HEAP_STRING_TRY(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TRY)\n#define DUK_HTHREAD_STRING_TRY(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TRY)\n#define DUK_STRIDX_TYPEOF                                             142                            /* 'typeof' */\n#define DUK_HEAP_STRING_TYPEOF(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TYPEOF)\n#define DUK_HTHREAD_STRING_TYPEOF(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TYPEOF)\n#define DUK_STRIDX_VAR                                                143                            /* 'var' */\n#define DUK_HEAP_STRING_VAR(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VAR)\n#define DUK_HTHREAD_STRING_VAR(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VAR)\n#define DUK_STRIDX_CONST                                              144                            /* 'const' */\n#define DUK_HEAP_STRING_CONST(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONST)\n#define DUK_HTHREAD_STRING_CONST(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONST)\n#define DUK_STRIDX_VOID                                               145                            /* 'void' */\n#define DUK_HEAP_STRING_VOID(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VOID)\n#define DUK_HTHREAD_STRING_VOID(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VOID)\n#define DUK_STRIDX_WHILE                                              146                            /* 'while' */\n#define DUK_HEAP_STRING_WHILE(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WHILE)\n#define DUK_HTHREAD_STRING_WHILE(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WHILE)\n#define DUK_STRIDX_WITH                                               147                            /* 'with' */\n#define DUK_HEAP_STRING_WITH(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WITH)\n#define DUK_HTHREAD_STRING_WITH(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WITH)\n#define DUK_STRIDX_CLASS                                              148                            /* 'class' */\n#define DUK_HEAP_STRING_CLASS(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CLASS)\n#define DUK_HTHREAD_STRING_CLASS(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CLASS)\n#define DUK_STRIDX_ENUM                                               149                            /* 'enum' */\n#define DUK_HEAP_STRING_ENUM(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENUM)\n#define DUK_HTHREAD_STRING_ENUM(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENUM)\n#define DUK_STRIDX_EXPORT                                             150                            /* 'export' */\n#define DUK_HEAP_STRING_EXPORT(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EXPORT)\n#define DUK_HTHREAD_STRING_EXPORT(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EXPORT)\n#define DUK_STRIDX_EXTENDS                                            151                            /* 'extends' */\n#define DUK_HEAP_STRING_EXTENDS(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EXTENDS)\n#define DUK_HTHREAD_STRING_EXTENDS(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EXTENDS)\n#define DUK_STRIDX_IMPORT                                             152                            /* 'import' */\n#define DUK_HEAP_STRING_IMPORT(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IMPORT)\n#define DUK_HTHREAD_STRING_IMPORT(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IMPORT)\n#define DUK_STRIDX_SUPER                                              153                            /* 'super' */\n#define DUK_HEAP_STRING_SUPER(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SUPER)\n#define DUK_HTHREAD_STRING_SUPER(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SUPER)\n#define DUK_STRIDX_LC_NULL                                            154                            /* 'null' */\n#define DUK_HEAP_STRING_LC_NULL(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_NULL)\n#define DUK_HTHREAD_STRING_LC_NULL(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_NULL)\n#define DUK_STRIDX_TRUE                                               155                            /* 'true' */\n#define DUK_HEAP_STRING_TRUE(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TRUE)\n#define DUK_HTHREAD_STRING_TRUE(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TRUE)\n#define DUK_STRIDX_FALSE                                              156                            /* 'false' */\n#define DUK_HEAP_STRING_FALSE(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FALSE)\n#define DUK_HTHREAD_STRING_FALSE(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FALSE)\n#define DUK_STRIDX_IMPLEMENTS                                         157                            /* 'implements' */\n#define DUK_HEAP_STRING_IMPLEMENTS(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IMPLEMENTS)\n#define DUK_HTHREAD_STRING_IMPLEMENTS(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IMPLEMENTS)\n#define DUK_STRIDX_INTERFACE                                          158                            /* 'interface' */\n#define DUK_HEAP_STRING_INTERFACE(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INTERFACE)\n#define DUK_HTHREAD_STRING_INTERFACE(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INTERFACE)\n#define DUK_STRIDX_LET                                                159                            /* 'let' */\n#define DUK_HEAP_STRING_LET(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LET)\n#define DUK_HTHREAD_STRING_LET(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LET)\n#define DUK_STRIDX_PACKAGE                                            160                            /* 'package' */\n#define DUK_HEAP_STRING_PACKAGE(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PACKAGE)\n#define DUK_HTHREAD_STRING_PACKAGE(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PACKAGE)\n#define DUK_STRIDX_PRIVATE                                            161                            /* 'private' */\n#define DUK_HEAP_STRING_PRIVATE(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PRIVATE)\n#define DUK_HTHREAD_STRING_PRIVATE(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PRIVATE)\n#define DUK_STRIDX_PROTECTED                                          162                            /* 'protected' */\n#define DUK_HEAP_STRING_PROTECTED(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PROTECTED)\n#define DUK_HTHREAD_STRING_PROTECTED(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PROTECTED)\n#define DUK_STRIDX_PUBLIC                                             163                            /* 'public' */\n#define DUK_HEAP_STRING_PUBLIC(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PUBLIC)\n#define DUK_HTHREAD_STRING_PUBLIC(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PUBLIC)\n#define DUK_STRIDX_STATIC                                             164                            /* 'static' */\n#define DUK_HEAP_STRING_STATIC(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_STATIC)\n#define DUK_HTHREAD_STRING_STATIC(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_STATIC)\n#define DUK_STRIDX_YIELD                                              165                            /* 'yield' */\n#define DUK_HEAP_STRING_YIELD(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_YIELD)\n#define DUK_HTHREAD_STRING_YIELD(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_YIELD)\n\n#define DUK_HEAP_NUM_STRINGS                                          166\n#define DUK_STRIDX_START_RESERVED                                     121\n#define DUK_STRIDX_START_STRICT_RESERVED                              157\n#define DUK_STRIDX_END_RESERVED                                       166                            /* exclusive endpoint */\n\n/* To convert a heap stridx to a token number, subtract\n * DUK_STRIDX_START_RESERVED and add DUK_TOK_START_RESERVED.\n */\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_strings_data[967];\n#endif  /* !DUK_SINGLE_FILE */\n#define DUK_STRDATA_MAX_STRLEN                                        27\n#define DUK_STRDATA_DATA_LENGTH                                       967\n#endif  /* DUK_USE_ROM_STRINGS */\n\n#if defined(DUK_USE_ROM_OBJECTS)\n#error RAM support not enabled, rerun configure.py with --ram-support\n#else  /* DUK_USE_ROM_OBJECTS */\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_boolean_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_constructor_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_type_error_thrower(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_parse_int(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_parse_float(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_thread_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_pointer_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_proxy_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_constructor_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_arraybuffer_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_dataview_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_eval(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_is_nan(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_is_finite(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_decode_uri(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_decode_uri_component(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_encode_uri(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_encode_uri_component(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_escape(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_unescape(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_getprototype_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_setprototype_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_get_own_property_descriptor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_keys_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_assign(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_create(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_define_property(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_define_properties(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_seal_freeze_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_is_sealed_frozen_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_is_extensible(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_is(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_locale_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_value_of(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_has_own_property(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_property_is_enumerable(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_defineaccessor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_lookupaccessor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_apply(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_call(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_bind(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_hasinstance(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_native_function_length(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_native_function_name(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_constructor_is_array(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_join_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_concat(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_pop(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_push(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_reverse(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_shift(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_slice(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_sort(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_unshift(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_indexof_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_iter_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_reduce_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_constructor_from_char_code(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_constructor_from_code_point(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_char_at(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_char_code_at(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_concat(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_indexof_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_locale_compare(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_match(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_search(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_slice(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_split(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_substring(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_caseconv_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_trim(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_repeat(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_includes(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_substr(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_check_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_locale_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_value_of(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_fixed(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_exponential(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_precision(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor_parse(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor_utc(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor_now(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_tostring_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_to_json(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_value_of(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_get_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_get_timezone_offset(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_set_time(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_set_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_toprimitive(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_exec(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_test(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_tostring(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_flags(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_stack_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_stack_setter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_filename_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_filename_setter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_linenumber_setter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_onearg_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_twoarg_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_clz32(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_hypot(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_imul(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_max(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_min(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_random(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_sign(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_json_object_parse(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_json_object_stringify(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_info(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_act(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_gc(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_fin(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_enc(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_dec(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_compact(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_thread_yield(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_thread_resume(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_thread_current(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_apply(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_construct(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_delete_property(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_get(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_has(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_set(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_key_for(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_tostring_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_toprimitive(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_arraybuffer_isview(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_buffer_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_set(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_uint8array_allocplain(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_uint8array_plainof(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_concat(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_is_encoding(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_byte_length(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_compare_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_fill(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_copy(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_write(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_prototype_encoding_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_prototype_encode(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_performance_now(duk_context *ctx);\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[183];\n#endif  /* !DUK_SINGLE_FILE */\n#define DUK_BIDX_GLOBAL                                               0\n#define DUK_BIDX_GLOBAL_ENV                                           1\n#define DUK_BIDX_OBJECT_CONSTRUCTOR                                   2\n#define DUK_BIDX_OBJECT_PROTOTYPE                                     3\n#define DUK_BIDX_FUNCTION_CONSTRUCTOR                                 4\n#define DUK_BIDX_FUNCTION_PROTOTYPE                                   5\n#define DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE                            6\n#define DUK_BIDX_ARRAY_CONSTRUCTOR                                    7\n#define DUK_BIDX_ARRAY_PROTOTYPE                                      8\n#define DUK_BIDX_STRING_CONSTRUCTOR                                   9\n#define DUK_BIDX_STRING_PROTOTYPE                                     10\n#define DUK_BIDX_BOOLEAN_CONSTRUCTOR                                  11\n#define DUK_BIDX_BOOLEAN_PROTOTYPE                                    12\n#define DUK_BIDX_NUMBER_CONSTRUCTOR                                   13\n#define DUK_BIDX_NUMBER_PROTOTYPE                                     14\n#define DUK_BIDX_DATE_CONSTRUCTOR                                     15\n#define DUK_BIDX_DATE_PROTOTYPE                                       16\n#define DUK_BIDX_REGEXP_CONSTRUCTOR                                   17\n#define DUK_BIDX_REGEXP_PROTOTYPE                                     18\n#define DUK_BIDX_ERROR_CONSTRUCTOR                                    19\n#define DUK_BIDX_ERROR_PROTOTYPE                                      20\n#define DUK_BIDX_EVAL_ERROR_CONSTRUCTOR                               21\n#define DUK_BIDX_EVAL_ERROR_PROTOTYPE                                 22\n#define DUK_BIDX_RANGE_ERROR_CONSTRUCTOR                              23\n#define DUK_BIDX_RANGE_ERROR_PROTOTYPE                                24\n#define DUK_BIDX_REFERENCE_ERROR_CONSTRUCTOR                          25\n#define DUK_BIDX_REFERENCE_ERROR_PROTOTYPE                            26\n#define DUK_BIDX_SYNTAX_ERROR_CONSTRUCTOR                             27\n#define DUK_BIDX_SYNTAX_ERROR_PROTOTYPE                               28\n#define DUK_BIDX_TYPE_ERROR_CONSTRUCTOR                               29\n#define DUK_BIDX_TYPE_ERROR_PROTOTYPE                                 30\n#define DUK_BIDX_URI_ERROR_CONSTRUCTOR                                31\n#define DUK_BIDX_URI_ERROR_PROTOTYPE                                  32\n#define DUK_BIDX_TYPE_ERROR_THROWER                                   33\n#define DUK_BIDX_DUKTAPE                                              34\n#define DUK_BIDX_THREAD_PROTOTYPE                                     35\n#define DUK_BIDX_POINTER_PROTOTYPE                                    36\n#define DUK_BIDX_DOUBLE_ERROR                                         37\n#define DUK_BIDX_SYMBOL_PROTOTYPE                                     38\n#define DUK_BIDX_ARRAYBUFFER_PROTOTYPE                                39\n#define DUK_BIDX_DATAVIEW_PROTOTYPE                                   40\n#define DUK_BIDX_INT8ARRAY_PROTOTYPE                                  41\n#define DUK_BIDX_UINT8ARRAY_PROTOTYPE                                 42\n#define DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE                          43\n#define DUK_BIDX_INT16ARRAY_PROTOTYPE                                 44\n#define DUK_BIDX_UINT16ARRAY_PROTOTYPE                                45\n#define DUK_BIDX_INT32ARRAY_PROTOTYPE                                 46\n#define DUK_BIDX_UINT32ARRAY_PROTOTYPE                                47\n#define DUK_BIDX_FLOAT32ARRAY_PROTOTYPE                               48\n#define DUK_BIDX_FLOAT64ARRAY_PROTOTYPE                               49\n#define DUK_BIDX_NODEJS_BUFFER_PROTOTYPE                              50\n#define DUK_NUM_BUILTINS                                              51\n#define DUK_NUM_BIDX_BUILTINS                                         51\n#define DUK_NUM_ALL_BUILTINS                                          79\n#if defined(DUK_USE_DOUBLE_LE)\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4251];\n#endif  /* !DUK_SINGLE_FILE */\n#define DUK_BUILTINS_DATA_LENGTH                                      4251\n#elif defined(DUK_USE_DOUBLE_BE)\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4251];\n#endif  /* !DUK_SINGLE_FILE */\n#define DUK_BUILTINS_DATA_LENGTH                                      4251\n#elif defined(DUK_USE_DOUBLE_ME)\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4251];\n#endif  /* !DUK_SINGLE_FILE */\n#define DUK_BUILTINS_DATA_LENGTH                                      4251\n#else\n#error invalid endianness defines\n#endif\n#endif  /* DUK_USE_ROM_OBJECTS */\n#endif  /* DUK_BUILTINS_H_INCLUDED */\n#line 44 \"duk_internal.h\"\n\n/* #include duk_util.h */\n#line 1 \"duk_util.h\"\n/*\n *  Utilities\n */\n\n#if !defined(DUK_UTIL_H_INCLUDED)\n#define DUK_UTIL_H_INCLUDED\n\n#if defined(DUK_USE_GET_RANDOM_DOUBLE)\n#define DUK_UTIL_GET_RANDOM_DOUBLE(thr) DUK_USE_GET_RANDOM_DOUBLE((thr)->heap_udata)\n#else\n#define DUK_UTIL_GET_RANDOM_DOUBLE(thr) duk_util_tinyrandom_get_double(thr)\n#endif\n\n/*\n *  Some useful constants\n */\n\n#define DUK_DOUBLE_2TO32     4294967296.0\n#define DUK_DOUBLE_2TO31     2147483648.0\n#define DUK_DOUBLE_LOG2E     1.4426950408889634\n#define DUK_DOUBLE_LOG10E    0.4342944819032518\n\n/*\n *  Endian conversion\n */\n\n#if defined(DUK_USE_INTEGER_LE)\n#define DUK_HTON32(x) DUK_BSWAP32((x))\n#define DUK_NTOH32(x) DUK_BSWAP32((x))\n#define DUK_HTON16(x) DUK_BSWAP16((x))\n#define DUK_NTOH16(x) DUK_BSWAP16((x))\n#elif defined(DUK_USE_INTEGER_BE)\n#define DUK_HTON32(x) (x)\n#define DUK_NTOH32(x) (x)\n#define DUK_HTON16(x) (x)\n#define DUK_NTOH16(x) (x)\n#else\n#error internal error, endianness defines broken\n#endif\n\n/*\n *  Bitstream decoder\n */\n\nstruct duk_bitdecoder_ctx {\n\tconst duk_uint8_t *data;\n\tduk_size_t offset;\n\tduk_size_t length;\n\tduk_uint32_t currval;\n\tduk_small_int_t currbits;\n};\n\n#define DUK_BD_BITPACKED_STRING_MAXLEN 256\n\n/*\n *  Bitstream encoder\n */\n\nstruct duk_bitencoder_ctx {\n\tduk_uint8_t *data;\n\tduk_size_t offset;\n\tduk_size_t length;\n\tduk_uint32_t currval;\n\tduk_small_int_t currbits;\n\tduk_small_int_t truncated;\n};\n\n/*\n *  Raw write/read macros for big endian, unaligned basic values.\n *  Caller ensures there's enough space.  The macros update the pointer\n *  argument automatically on resizes.  The idiom seems a bit odd, but\n *  leads to compact code.\n */\n\n#define DUK_RAW_WRITE_U8(ptr,val)  do { \\\n\t\t*(ptr)++ = (duk_uint8_t) (val); \\\n\t} while (0)\n#define DUK_RAW_WRITE_U16_BE(ptr,val) duk_raw_write_u16_be(&(ptr), (duk_uint16_t) (val))\n#define DUK_RAW_WRITE_U32_BE(ptr,val) duk_raw_write_u32_be(&(ptr), (duk_uint32_t) (val))\n#define DUK_RAW_WRITE_DOUBLE_BE(ptr,val) duk_raw_write_double_be(&(ptr), (duk_double_t) (val))\n#define DUK_RAW_WRITE_XUTF8(ptr,val)  do { \\\n\t\t/* 'ptr' is evaluated both as LHS and RHS. */ \\\n\t\tduk_uint8_t *duk__ptr; \\\n\t\tduk_small_int_t duk__len; \\\n\t\tduk__ptr = (duk_uint8_t *) (ptr); \\\n\t\tduk__len = duk_unicode_encode_xutf8((duk_ucodepoint_t) (val), duk__ptr); \\\n\t\tduk__ptr += duk__len; \\\n\t\t(ptr) = duk__ptr; \\\n\t} while (0)\n#define DUK_RAW_WRITE_CESU8(ptr,val)  do { \\\n\t\t/* 'ptr' is evaluated both as LHS and RHS. */ \\\n\t\tduk_uint8_t *duk__ptr; \\\n\t\tduk_small_int_t duk__len; \\\n\t\tduk__ptr = (duk_uint8_t *) (ptr); \\\n\t\tduk__len = duk_unicode_encode_cesu8((duk_ucodepoint_t) (val), duk__ptr); \\\n\t\tduk__ptr += duk__len; \\\n\t\t(ptr) = duk__ptr; \\\n\t} while (0)\n\n#define DUK_RAW_READ_U8(ptr) ((duk_uint8_t) (*(ptr)++))\n#define DUK_RAW_READ_U16_BE(ptr) duk_raw_read_u16_be(&(ptr));\n#define DUK_RAW_READ_U32_BE(ptr) duk_raw_read_u32_be(&(ptr));\n#define DUK_RAW_READ_DOUBLE_BE(ptr) duk_raw_read_double_be(&(ptr));\n\n/*\n *  Buffer writer (dynamic buffer only)\n *\n *  Helper for writing to a dynamic buffer with a concept of a \"slack\" area\n *  to reduce resizes.  You can ensure there is enough space beforehand and\n *  then write for a while without further checks, relying on a stable data\n *  pointer.  Slack handling is automatic so call sites only indicate how\n *  much data they need right now.\n *\n *  There are several ways to write using bufwriter.  The best approach\n *  depends mainly on how much performance matters over code footprint.\n *  The key issues are (1) ensuring there is space and (2) keeping the\n *  pointers consistent.  Fast code should ensure space for multiple writes\n *  with one ensure call.  Fastest inner loop code can temporarily borrow\n *  the 'p' pointer but must write it back eventually.\n *\n *  Be careful to ensure all macro arguments (other than static pointers like\n *  'thr' and 'bw_ctx') are evaluated exactly once, using temporaries if\n *  necessary (if that's not possible, there should be a note near the macro).\n *  Buffer write arguments often contain arithmetic etc so this is\n *  particularly important here.\n */\n\n/* XXX: Migrate bufwriter and other read/write helpers to its own header? */\n\nstruct duk_bufwriter_ctx {\n\tduk_uint8_t *p;\n\tduk_uint8_t *p_base;\n\tduk_uint8_t *p_limit;\n\tduk_hbuffer_dynamic *buf;\n};\n\n#if defined(DUK_USE_PREFER_SIZE)\n#define DUK_BW_SLACK_ADD           64\n#define DUK_BW_SLACK_SHIFT         4    /* 2^4 -> 1/16 = 6.25% slack */\n#else\n#define DUK_BW_SLACK_ADD           64\n#define DUK_BW_SLACK_SHIFT         2    /* 2^2 -> 1/4 = 25% slack */\n#endif\n\n/* Initialization and finalization (compaction), converting to other types. */\n\n#define DUK_BW_INIT_PUSHBUF(thr,bw_ctx,sz) do { \\\n\t\tduk_bw_init_pushbuf((thr), (bw_ctx), (sz)); \\\n\t} while (0)\n#define DUK_BW_INIT_WITHBUF(thr,bw_ctx,buf) do { \\\n\t\tduk_bw_init((thr), (bw_ctx), (buf)); \\\n\t} while (0)\n#define DUK_BW_COMPACT(thr,bw_ctx) do { \\\n\t\t/* Make underlying buffer compact to match DUK_BW_GET_SIZE(). */ \\\n\t\tduk_bw_compact((thr), (bw_ctx)); \\\n\t} while (0)\n#define DUK_BW_PUSH_AS_STRING(thr,bw_ctx) do { \\\n\t\tduk_push_lstring((thr), \\\n\t\t                 (const char *) (bw_ctx)->p_base, \\\n\t\t                 (duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base)); \\\n\t} while (0)\n\n/* Pointers may be NULL for a while when 'buf' size is zero and before any\n * ENSURE calls have been made.  Once an ENSURE has been made, the pointers\n * are required to be non-NULL so that it's always valid to use memcpy() and\n * memmove(), even for zero size.\n */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_bw_assert_valid(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx);\n#define DUK_BW_ASSERT_VALID_EXPR(thr,bw_ctx)  (duk_bw_assert_valid((thr), (bw_ctx)))\n#define DUK_BW_ASSERT_VALID(thr,bw_ctx)  do { duk_bw_assert_valid((thr), (bw_ctx)); } while (0)\n#else\n#define DUK_BW_ASSERT_VALID_EXPR(thr,bw_ctx)  DUK_ASSERT_EXPR(1)\n#define DUK_BW_ASSERT_VALID(thr,bw_ctx)  do {} while (0)\n#endif\n\n/* Working with the pointer and current size. */\n\n#define DUK_BW_GET_PTR(thr,bw_ctx) \\\n\t((bw_ctx)->p)\n#define DUK_BW_SET_PTR(thr,bw_ctx,ptr) do { \\\n\t\t(bw_ctx)->p = (ptr); \\\n\t} while (0)\n#define DUK_BW_ADD_PTR(thr,bw_ctx,delta) do { \\\n\t\t(bw_ctx)->p += (delta); \\\n\t} while (0)\n#define DUK_BW_GET_BASEPTR(thr,bw_ctx) \\\n\t((bw_ctx)->p_base)\n#define DUK_BW_GET_LIMITPTR(thr,bw_ctx) \\\n\t((bw_ctx)->p_limit)\n#define DUK_BW_GET_SIZE(thr,bw_ctx) \\\n\t((duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base))\n#define DUK_BW_SET_SIZE(thr,bw_ctx,sz) do { \\\n\t\tDUK_ASSERT((duk_size_t) (sz) <= (duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base)); \\\n\t\t(bw_ctx)->p = (bw_ctx)->p_base + (sz); \\\n\t} while (0)\n#define DUK_BW_RESET_SIZE(thr,bw_ctx) do { \\\n\t\t/* Reset to zero size, keep current limit. */ \\\n\t\t(bw_ctx)->p = (bw_ctx)->p_base; \\\n\t} while (0)\n#define DUK_BW_GET_BUFFER(thr,bw_ctx) \\\n\t((bw_ctx)->buf)\n\n/* Ensuring (reserving) space. */\n\n#define DUK_BW_ENSURE(thr,bw_ctx,sz) do { \\\n\t\tduk_size_t duk__sz, duk__space; \\\n\t\tDUK_BW_ASSERT_VALID((thr), (bw_ctx)); \\\n\t\tduk__sz = (sz); \\\n\t\tduk__space = (duk_size_t) ((bw_ctx)->p_limit - (bw_ctx)->p); \\\n\t\tif (duk__space < duk__sz) { \\\n\t\t\t(void) duk_bw_resize((thr), (bw_ctx), duk__sz); \\\n\t\t} \\\n\t} while (0)\n/* NOTE: Multiple evaluation of 'ptr' in this macro. */\n/* XXX: Rework to use an always-inline function? */\n#define DUK_BW_ENSURE_RAW(thr,bw_ctx,sz,ptr) \\\n\t(((duk_size_t) ((bw_ctx)->p_limit - (ptr)) >= (sz)) ? \\\n\t (ptr) : \\\n\t ((bw_ctx)->p = (ptr), duk_bw_resize((thr),(bw_ctx),(sz))))\n#define DUK_BW_ENSURE_GETPTR(thr,bw_ctx,sz) \\\n\tDUK_BW_ENSURE_RAW((thr), (bw_ctx), (sz), (bw_ctx)->p)\n#define DUK_BW_ASSERT_SPACE_EXPR(thr,bw_ctx,sz) \\\n\t(DUK_BW_ASSERT_VALID_EXPR((thr), (bw_ctx)), \\\n\t DUK_ASSERT_EXPR((duk_size_t) ((bw_ctx)->p_limit - (bw_ctx)->p) >= (duk_size_t) (sz)))\n#define DUK_BW_ASSERT_SPACE(thr,bw_ctx,sz) do { \\\n\t\tDUK_BW_ASSERT_SPACE_EXPR((thr), (bw_ctx), (sz)); \\\n\t} while (0)\n\n/* Miscellaneous. */\n\n#define DUK_BW_SETPTR_AND_COMPACT(thr,bw_ctx,ptr) do { \\\n\t\t(bw_ctx)->p = (ptr); \\\n\t\tduk_bw_compact((thr), (bw_ctx)); \\\n\t} while (0)\n\n/* Fast write calls which assume you control the slack beforehand.\n * Multibyte write variants exist and use a temporary write pointer\n * because byte writes alias with anything: with a stored pointer\n * explicit pointer load/stores get generated (e.g. gcc -Os).\n */\n\n#define DUK_BW_WRITE_RAW_U8(thr,bw_ctx,val) do { \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 1); \\\n\t\t*(bw_ctx)->p++ = (duk_uint8_t) (val); \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_2(thr,bw_ctx,val1,val2) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 2); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_3(thr,bw_ctx,val1,val2,val3) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 3); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_4(thr,bw_ctx,val1,val2,val3,val4) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 4); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t*duk__p++ = (duk_uint8_t) (val4); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_5(thr,bw_ctx,val1,val2,val3,val4,val5) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 5); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t*duk__p++ = (duk_uint8_t) (val4); \\\n\t\t*duk__p++ = (duk_uint8_t) (val5); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_6(thr,bw_ctx,val1,val2,val3,val4,val5,val6) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 6); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t*duk__p++ = (duk_uint8_t) (val4); \\\n\t\t*duk__p++ = (duk_uint8_t) (val5); \\\n\t\t*duk__p++ = (duk_uint8_t) (val6); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_XUTF8(thr,bw_ctx,cp) do { \\\n\t\tduk_ucodepoint_t duk__cp; \\\n\t\tduk_small_int_t duk__enc_len; \\\n\t\tduk__cp = (duk_ucodepoint_t) (cp); \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), duk_unicode_get_xutf8_length(duk__cp)); \\\n\t\tduk__enc_len = duk_unicode_encode_xutf8(duk__cp, (bw_ctx)->p); \\\n\t\t(bw_ctx)->p += duk__enc_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_CESU8(thr,bw_ctx,cp) do { \\\n\t\tduk_ucodepoint_t duk__cp; \\\n\t\tduk_small_int_t duk__enc_len; \\\n\t\tduk__cp = (duk_ucodepoint_t) (cp); \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), duk_unicode_get_cesu8_length(duk__cp)); \\\n\t\tduk__enc_len = duk_unicode_encode_cesu8(duk__cp, (bw_ctx)->p); \\\n\t\t(bw_ctx)->p += duk__enc_len; \\\n\t} while (0)\n/* XXX: add temporary duk__p pointer here too; sharing */\n/* XXX: avoid unsafe variants */\n#define DUK_BW_WRITE_RAW_BYTES(thr,bw_ctx,valptr,valsz) do { \\\n\t\tconst void *duk__valptr; \\\n\t\tduk_size_t duk__valsz; \\\n\t\tduk__valptr = (const void *) (valptr); \\\n\t\tduk__valsz = (duk_size_t) (valsz); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), duk__valptr, duk__valsz); \\\n\t\t(bw_ctx)->p += duk__valsz; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_CSTRING(thr,bw_ctx,val) do { \\\n\t\tconst duk_uint8_t *duk__val; \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val = (const duk_uint8_t *) (val); \\\n\t\tduk__val_len = DUK_STRLEN((const char *) duk__val); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) duk__val, duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HSTRING(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HSTRING_GET_BYTELEN((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HSTRING_GET_DATA((val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HBUFFER(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_GET_SIZE((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HBUFFER_FIXED(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_FIXED_GET_SIZE((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_FIXED_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HBUFFER_DYNAMIC(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_DYNAMIC_GET_SIZE((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n\n/* Append bytes from a slice already in the buffer. */\n#define DUK_BW_WRITE_RAW_SLICE(thr,bw,dst_off,dst_len) \\\n\tduk_bw_write_raw_slice((thr), (bw), (dst_off), (dst_len))\n\n/* Insert bytes in the middle of the buffer from an external buffer. */\n#define DUK_BW_INSERT_RAW_BYTES(thr,bw,dst_off,buf,len) \\\n\tduk_bw_insert_raw_bytes((thr), (bw), (dst_off), (buf), (len))\n\n/* Insert bytes in the middle of the buffer from a slice already\n * in the buffer.  Source offset is interpreted \"before\" the operation.\n */\n#define DUK_BW_INSERT_RAW_SLICE(thr,bw,dst_off,src_off,len) \\\n\tduk_bw_insert_raw_slice((thr), (bw), (dst_off), (src_off), (len))\n\n/* Insert a reserved area somewhere in the buffer; caller fills it.\n * Evaluates to a (duk_uint_t *) pointing to the start of the reserved\n * area for convenience.\n */\n#define DUK_BW_INSERT_RAW_AREA(thr,bw,off,len) \\\n\tduk_bw_insert_raw_area((thr), (bw), (off), (len))\n\n/* Remove a slice from inside buffer. */\n#define DUK_BW_REMOVE_RAW_SLICE(thr,bw,off,len) \\\n\tduk_bw_remove_raw_slice((thr), (bw), (off), (len))\n\n/* Safe write calls which will ensure space first. */\n\n#define DUK_BW_WRITE_ENSURE_U8(thr,bw_ctx,val) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 1); \\\n\t\tDUK_BW_WRITE_RAW_U8((thr), (bw_ctx), (val)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_2(thr,bw_ctx,val1,val2) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 2); \\\n\t\tDUK_BW_WRITE_RAW_U8_2((thr), (bw_ctx), (val1), (val2)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_3(thr,bw_ctx,val1,val2,val3) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 3); \\\n\t\tDUK_BW_WRITE_RAW_U8_3((thr), (bw_ctx), (val1), (val2), (val3)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_4(thr,bw_ctx,val1,val2,val3,val4) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 4); \\\n\t\tDUK_BW_WRITE_RAW_U8_4((thr), (bw_ctx), (val1), (val2), (val3), (val4)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_5(thr,bw_ctx,val1,val2,val3,val4,val5) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 5); \\\n\t\tDUK_BW_WRITE_RAW_U8_5((thr), (bw_ctx), (val1), (val2), (val3), (val4), (val5)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_6(thr,bw_ctx,val1,val2,val3,val4,val5,val6) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 6); \\\n\t\tDUK_BW_WRITE_RAW_U8_6((thr), (bw_ctx), (val1), (val2), (val3), (val4), (val5), (val6)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_XUTF8(thr,bw_ctx,cp) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), DUK_UNICODE_MAX_XUTF8_LENGTH); \\\n\t\tDUK_BW_WRITE_RAW_XUTF8((thr), (bw_ctx), (cp)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_CESU8(thr,bw_ctx,cp) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), DUK_UNICODE_MAX_CESU8_LENGTH); \\\n\t\tDUK_BW_WRITE_RAW_CESU8((thr), (bw_ctx), (cp)); \\\n\t} while (0)\n/* XXX: add temporary duk__p pointer here too; sharing */\n/* XXX: avoid unsafe */\n#define DUK_BW_WRITE_ENSURE_BYTES(thr,bw_ctx,valptr,valsz) do { \\\n\t\tconst void *duk__valptr; \\\n\t\tduk_size_t duk__valsz; \\\n\t\tduk__valptr = (const void *) (valptr); \\\n\t\tduk__valsz = (duk_size_t) (valsz); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__valsz); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), duk__valptr, duk__valsz); \\\n\t\t(bw_ctx)->p += duk__valsz; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_CSTRING(thr,bw_ctx,val) do { \\\n\t\tconst duk_uint8_t *duk__val; \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val = (const duk_uint8_t *) (val); \\\n\t\tduk__val_len = DUK_STRLEN((const char *) duk__val); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) duk__val, duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HSTRING(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HSTRING_GET_BYTELEN((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HSTRING_GET_DATA((val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HBUFFER(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_GET_SIZE((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HBUFFER_FIXED(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_FIXED_GET_SIZE((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_FIXED_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HBUFFER_DYNAMIC(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_DYNAMIC_GET_SIZE((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n\n#define DUK_BW_WRITE_ENSURE_SLICE(thr,bw,dst_off,dst_len) \\\n\tduk_bw_write_ensure_slice((thr), (bw), (dst_off), (dst_len))\n#define DUK_BW_INSERT_ENSURE_BYTES(thr,bw,dst_off,buf,len) \\\n\tduk_bw_insert_ensure_bytes((thr), (bw), (dst_off), (buf), (len))\n#define DUK_BW_INSERT_ENSURE_SLICE(thr,bw,dst_off,src_off,len) \\\n\tduk_bw_insert_ensure_slice((thr), (bw), (dst_off), (src_off), (len))\n#define DUK_BW_INSERT_ENSURE_AREA(thr,bw,off,len) \\\n\t/* Evaluates to (duk_uint8_t *) pointing to start of area. */ \\\n\tduk_bw_insert_ensure_area((thr), (bw), (off), (len))\n#define DUK_BW_REMOVE_ENSURE_SLICE(thr,bw,off,len) \\\n\t/* No difference between raw/ensure because the buffer shrinks. */ \\\n\tDUK_BW_REMOVE_RAW_SLICE((thr), (bw), (off), (len))\n\n/*\n *  Externs and prototypes\n */\n\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_lc_digits[36];\nDUK_INTERNAL_DECL const duk_uint8_t duk_uc_nybbles[16];\nDUK_INTERNAL_DECL const duk_int8_t duk_hex_dectab[256];\n#if defined(DUK_USE_HEX_FASTPATH)\nDUK_INTERNAL_DECL const duk_int16_t duk_hex_dectab_shift4[256];\nDUK_INTERNAL_DECL const duk_uint16_t duk_hex_enctab[256];\n#endif\n#endif  /* !DUK_SINGLE_FILE */\n\n/* Note: assumes that duk_util_probe_steps size is 32 */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL duk_uint8_t duk_util_probe_steps[32];\n#endif  /* !DUK_SINGLE_FILE */\n#endif\n\n#if defined(DUK_USE_STRHASH_DENSE)\nDUK_INTERNAL_DECL duk_uint32_t duk_util_hashbytes(const duk_uint8_t *data, duk_size_t len, duk_uint32_t seed);\n#endif\n\nDUK_INTERNAL_DECL duk_uint32_t duk_bd_decode(duk_bitdecoder_ctx *ctx, duk_small_int_t bits);\nDUK_INTERNAL_DECL duk_small_uint_t duk_bd_decode_flag(duk_bitdecoder_ctx *ctx);\nDUK_INTERNAL_DECL duk_uint32_t duk_bd_decode_flagged(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_uint32_t def_value);\nDUK_INTERNAL_DECL duk_int32_t duk_bd_decode_flagged_signed(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_int32_t def_value);\nDUK_INTERNAL_DECL duk_uint32_t duk_bd_decode_varuint(duk_bitdecoder_ctx *ctx);\nDUK_INTERNAL_DECL duk_small_uint_t duk_bd_decode_bitpacked_string(duk_bitdecoder_ctx *bd, duk_uint8_t *out);\n\nDUK_INTERNAL_DECL void duk_be_encode(duk_bitencoder_ctx *ctx, duk_uint32_t data, duk_small_int_t bits);\nDUK_INTERNAL_DECL void duk_be_finish(duk_bitencoder_ctx *ctx);\n\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\nDUK_INTERNAL_DECL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL void duk_bw_init(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_hbuffer_dynamic *h_buf);\nDUK_INTERNAL_DECL void duk_bw_init_pushbuf(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t buf_size);\nDUK_INTERNAL_DECL duk_uint8_t *duk_bw_resize(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t sz);\nDUK_INTERNAL_DECL void duk_bw_compact(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx);\nDUK_INTERNAL_DECL void duk_bw_write_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_write_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_raw_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_ensure_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL duk_uint8_t *duk_bw_insert_raw_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len);\nDUK_INTERNAL_DECL duk_uint8_t *duk_bw_insert_ensure_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len);\n/* No duk_bw_remove_ensure_slice(), functionality would be identical. */\n\nDUK_INTERNAL_DECL duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p);\nDUK_INTERNAL_DECL duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p);\nDUK_INTERNAL_DECL duk_double_t duk_raw_read_double_be(duk_uint8_t **p);\nDUK_INTERNAL_DECL void duk_raw_write_u16_be(duk_uint8_t **p, duk_uint16_t val);\nDUK_INTERNAL_DECL void duk_raw_write_u32_be(duk_uint8_t **p, duk_uint32_t val);\nDUK_INTERNAL_DECL void duk_raw_write_double_be(duk_uint8_t **p, duk_double_t val);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* For now only needed by the debugger. */\nDUK_INTERNAL_DECL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len);\n#endif\n\n/* memcpy(), memmove() etc wrappers.  The plain variants like duk_memcpy()\n * assume C99+ and 'src' and 'dst' pointers must be non-NULL even when the\n * operation size is zero.  The unsafe variants like duk_memcpy_safe() deal\n * with the zero size case explicitly, and allow NULL pointers in that case\n * (which is undefined behavior in C99+).  For the majority of actual targets\n * a NULL pointer with a zero length is fine in practice.  These wrappers are\n * macros to force inlining; because there are hundreds of call sites, even a\n * few extra bytes per call site adds up to ~1kB footprint.\n */\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n#define duk_memcpy(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memcpy_unsafe(dst,src,len)  duk_memcpy((dst), (src), (len))\n#define duk_memmove(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memmove_unsafe(dst,src,len)  duk_memmove((dst), (src), (len))\n#define duk_memset(dst,val,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_small_int_t duk__val = (val); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memset_unsafe(dst,val,len)  duk_memset((dst), (val), (len))\n#define duk_memzero(dst,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memzero_unsafe(dst,len)  duk_memzero((dst), (len))\n#else  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\n#define duk_memcpy(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t(void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memcpy_unsafe(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t\t(void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#define duk_memmove(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t(void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memmove_unsafe(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t\t(void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#define duk_memset(dst,val,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_small_int_t duk__val = (val); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t(void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memset_unsafe(dst,val,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_small_int_t duk__val = (val); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\t(void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#define duk_memzero(dst,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t(void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memzero_unsafe(dst,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\t(void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#endif  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\n\nDUK_INTERNAL_DECL duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len);\nDUK_INTERNAL_DECL duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len);\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_whole_get_int32_nonegzero(duk_double_t x, duk_int32_t *ival);\nDUK_INTERNAL_DECL duk_bool_t duk_is_whole_get_int32(duk_double_t x, duk_int32_t *ival);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_anyinf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_posinf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_neginf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_or_zero(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_or_inf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_zero_inf(duk_double_t x);\nDUK_INTERNAL_DECL duk_small_uint_t duk_double_signbit(duk_double_t x);\nDUK_INTERNAL_DECL duk_double_t duk_double_trunc_towards_zero(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_same_sign(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_double_t duk_double_fmin(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_finite(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_integer(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_safe_integer(duk_double_t x);\n\nDUK_INTERNAL_DECL duk_double_t duk_double_div(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_int_t duk_double_to_int_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_uint_t duk_double_to_uint_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_int32_t duk_double_to_int32_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_uint32_t duk_double_to_uint32_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_float_t duk_double_to_float_t(duk_double_t x);\n\n/*\n *  Miscellaneous\n */\n\n/* Example: x     = 0x10 = 0b00010000\n *          x - 1 = 0x0f = 0b00001111\n *          x & (x - 1) == 0\n *\n *          x     = 0x07 = 0b00000111\n *          x - 1 = 0x06 = 0b00000110\n *          x & (x - 1) != 0\n *\n * However, incorrectly true for x == 0 so check for that explicitly.\n */\n#define DUK_IS_POWER_OF_TWO(x) \\\n\t((x) != 0U && ((x) & ((x) - 1U)) == 0U)\n\n#endif  /* DUK_UTIL_H_INCLUDED */\n/* #include duk_strings.h */\n#line 1 \"duk_strings.h\"\n/*\n *  Shared string macros.\n *\n *  Using shared macros helps minimize strings data size because it's easy\n *  to check if an existing string could be used.  String constants don't\n *  need to be all defined here; defining a string here makes sense if there's\n *  a high chance the string could be reused.  Also, using macros allows\n *  a call site express the exact string needed, but the macro may map to an\n *  approximate string to reduce unique string count.  Macros can also be\n *  more easily tuned for low memory targets than #if defined()s throughout\n *  the code base.\n *\n *  Because format strings behave differently in the call site (they need to\n *  be followed by format arguments), they use a special prefix DUK_STR_FMT_.\n *\n *  On some compilers using explicit shared strings is preferable; on others\n *  it may be better to use straight literals because the compiler will combine\n *  them anyway, and such strings won't end up unnecessarily in a symbol table.\n */\n\n#if !defined(DUK_ERRMSG_H_INCLUDED)\n#define DUK_ERRMSG_H_INCLUDED\n\n/* Mostly API and built-in method related */\n#define DUK_STR_INTERNAL_ERROR                   \"internal error\"\n#define DUK_STR_UNSUPPORTED                      \"unsupported\"\n#define DUK_STR_INVALID_COUNT                    \"invalid count\"\n#define DUK_STR_INVALID_ARGS                     \"invalid args\"\n#define DUK_STR_INVALID_STATE                    \"invalid state\"\n#define DUK_STR_INVALID_INPUT                    \"invalid input\"\n#define DUK_STR_INVALID_LENGTH                   \"invalid length\"\n#define DUK_STR_NOT_CONSTRUCTABLE                \"not constructable\"\n#define DUK_STR_CONSTRUCT_ONLY                   \"constructor requires 'new'\"\n#define DUK_STR_NOT_CALLABLE                     \"not callable\"\n#define DUK_STR_NOT_EXTENSIBLE                   \"not extensible\"\n#define DUK_STR_NOT_WRITABLE                     \"not writable\"\n#define DUK_STR_NOT_CONFIGURABLE                 \"not configurable\"\n#define DUK_STR_INVALID_CONTEXT                  \"invalid context\"\n#define DUK_STR_INVALID_INDEX                    \"invalid args\"\n#define DUK_STR_PUSH_BEYOND_ALLOC_STACK          \"cannot push beyond allocated stack\"\n#define DUK_STR_NOT_UNDEFINED                    \"unexpected type\"\n#define DUK_STR_NOT_NULL                         \"unexpected type\"\n#define DUK_STR_NOT_BOOLEAN                      \"unexpected type\"\n#define DUK_STR_NOT_NUMBER                       \"unexpected type\"\n#define DUK_STR_NOT_STRING                       \"unexpected type\"\n#define DUK_STR_NOT_OBJECT                       \"unexpected type\"\n#define DUK_STR_NOT_POINTER                      \"unexpected type\"\n#define DUK_STR_NOT_BUFFER                       \"not buffer\"  /* still in use with verbose messages */\n#define DUK_STR_UNEXPECTED_TYPE                  \"unexpected type\"\n#define DUK_STR_NOT_THREAD                       \"unexpected type\"\n#define DUK_STR_NOT_COMPFUNC                     \"unexpected type\"\n#define DUK_STR_NOT_NATFUNC                      \"unexpected type\"\n#define DUK_STR_NOT_C_FUNCTION                   \"unexpected type\"\n#define DUK_STR_NOT_FUNCTION                     \"unexpected type\"\n#define DUK_STR_NOT_REGEXP                       \"unexpected type\"\n#define DUK_STR_TOPRIMITIVE_FAILED               \"coercion to primitive failed\"\n#define DUK_STR_NUMBER_OUTSIDE_RANGE             \"number outside range\"\n#define DUK_STR_NOT_OBJECT_COERCIBLE             \"not object coercible\"\n#define DUK_STR_CANNOT_NUMBER_COERCE_SYMBOL      \"cannot number coerce Symbol\"\n#define DUK_STR_CANNOT_STRING_COERCE_SYMBOL      \"cannot string coerce Symbol\"\n#define DUK_STR_STRING_TOO_LONG                  \"string too long\"\n#define DUK_STR_BUFFER_TOO_LONG                  \"buffer too long\"\n#define DUK_STR_ALLOC_FAILED                     \"alloc failed\"\n#define DUK_STR_WRONG_BUFFER_TYPE                \"wrong buffer type\"\n#define DUK_STR_BASE64_ENCODE_FAILED             \"base64 encode failed\"\n#define DUK_STR_SOURCE_DECODE_FAILED             \"source decode failed\"\n#define DUK_STR_UTF8_DECODE_FAILED               \"utf-8 decode failed\"\n#define DUK_STR_BASE64_DECODE_FAILED             \"base64 decode failed\"\n#define DUK_STR_HEX_DECODE_FAILED                \"hex decode failed\"\n#define DUK_STR_INVALID_BYTECODE                 \"invalid bytecode\"\n#define DUK_STR_NO_SOURCECODE                    \"no sourcecode\"\n#define DUK_STR_RESULT_TOO_LONG                  \"result too long\"\n#define DUK_STR_INVALID_CFUNC_RC                 \"invalid C function rc\"\n#define DUK_STR_INVALID_INSTANCEOF_RVAL          \"invalid instanceof rval\"\n#define DUK_STR_INVALID_INSTANCEOF_RVAL_NOPROTO  \"instanceof rval has no .prototype\"\n\n/* JSON */\n#define DUK_STR_FMT_PTR                          \"%p\"\n#define DUK_STR_FMT_INVALID_JSON                 \"invalid json (at offset %ld)\"\n#define DUK_STR_JSONDEC_RECLIMIT                 \"json decode recursion limit\"\n#define DUK_STR_JSONENC_RECLIMIT                 \"json encode recursion limit\"\n#define DUK_STR_CYCLIC_INPUT                     \"cyclic input\"\n\n/* Object property access */\n#define DUK_STR_INVALID_BASE                     \"invalid base value\"\n#define DUK_STR_STRICT_CALLER_READ               \"cannot read strict 'caller'\"\n#define DUK_STR_PROXY_REJECTED                   \"proxy rejected\"\n#define DUK_STR_INVALID_ARRAY_LENGTH             \"invalid array length\"\n#define DUK_STR_SETTER_UNDEFINED                 \"setter undefined\"\n#define DUK_STR_INVALID_DESCRIPTOR               \"invalid descriptor\"\n\n/* Proxy */\n#define DUK_STR_PROXY_REVOKED                    \"proxy revoked\"\n#define DUK_STR_INVALID_TRAP_RESULT              \"invalid trap result\"\n\n/* Variables */\n\n/* Lexer */\n#define DUK_STR_INVALID_ESCAPE                   \"invalid escape\"\n#define DUK_STR_UNTERMINATED_STRING              \"unterminated string\"\n#define DUK_STR_UNTERMINATED_COMMENT             \"unterminated comment\"\n#define DUK_STR_UNTERMINATED_REGEXP              \"unterminated regexp\"\n#define DUK_STR_TOKEN_LIMIT                      \"token limit\"\n#define DUK_STR_REGEXP_SUPPORT_DISABLED          \"regexp support disabled\"\n#define DUK_STR_INVALID_NUMBER_LITERAL           \"invalid number literal\"\n#define DUK_STR_INVALID_TOKEN                    \"invalid token\"\n\n/* Compiler */\n#define DUK_STR_PARSE_ERROR                      \"parse error\"\n#define DUK_STR_DUPLICATE_LABEL                  \"duplicate label\"\n#define DUK_STR_INVALID_LABEL                    \"invalid label\"\n#define DUK_STR_INVALID_ARRAY_LITERAL            \"invalid array literal\"\n#define DUK_STR_INVALID_OBJECT_LITERAL           \"invalid object literal\"\n#define DUK_STR_INVALID_VAR_DECLARATION          \"invalid variable declaration\"\n#define DUK_STR_CANNOT_DELETE_IDENTIFIER         \"cannot delete identifier\"\n#define DUK_STR_INVALID_EXPRESSION               \"invalid expression\"\n#define DUK_STR_INVALID_LVALUE                   \"invalid lvalue\"\n#define DUK_STR_INVALID_NEWTARGET                \"invalid new.target\"\n#define DUK_STR_EXPECTED_IDENTIFIER              \"expected identifier\"\n#define DUK_STR_EMPTY_EXPR_NOT_ALLOWED           \"empty expression not allowed\"\n#define DUK_STR_INVALID_FOR                      \"invalid for statement\"\n#define DUK_STR_INVALID_SWITCH                   \"invalid switch statement\"\n#define DUK_STR_INVALID_BREAK_CONT_LABEL         \"invalid break/continue label\"\n#define DUK_STR_INVALID_RETURN                   \"invalid return\"\n#define DUK_STR_INVALID_TRY                      \"invalid try\"\n#define DUK_STR_INVALID_THROW                    \"invalid throw\"\n#define DUK_STR_WITH_IN_STRICT_MODE              \"with in strict mode\"\n#define DUK_STR_FUNC_STMT_NOT_ALLOWED            \"function statement not allowed\"\n#define DUK_STR_UNTERMINATED_STMT                \"unterminated statement\"\n#define DUK_STR_INVALID_ARG_NAME                 \"invalid argument name\"\n#define DUK_STR_INVALID_FUNC_NAME                \"invalid function name\"\n#define DUK_STR_INVALID_GETSET_NAME              \"invalid getter/setter name\"\n#define DUK_STR_FUNC_NAME_REQUIRED               \"function name required\"\n\n/* RegExp */\n#define DUK_STR_INVALID_QUANTIFIER               \"invalid regexp quantifier\"\n#define DUK_STR_INVALID_QUANTIFIER_NO_ATOM       \"quantifier without preceding atom\"\n#define DUK_STR_INVALID_QUANTIFIER_VALUES        \"quantifier values invalid (qmin > qmax)\"\n#define DUK_STR_QUANTIFIER_TOO_MANY_COPIES       \"quantifier requires too many atom copies\"\n#define DUK_STR_UNEXPECTED_CLOSING_PAREN         \"unexpected closing parenthesis\"\n#define DUK_STR_UNEXPECTED_END_OF_PATTERN        \"unexpected end of pattern\"\n#define DUK_STR_UNEXPECTED_REGEXP_TOKEN          \"unexpected token in regexp\"\n#define DUK_STR_INVALID_REGEXP_FLAGS             \"invalid regexp flags\"\n#define DUK_STR_INVALID_REGEXP_ESCAPE            \"invalid regexp escape\"\n#define DUK_STR_INVALID_BACKREFS                 \"invalid backreference(s)\"\n#define DUK_STR_INVALID_REGEXP_CHARACTER         \"invalid regexp character\"\n#define DUK_STR_INVALID_REGEXP_GROUP             \"invalid regexp group\"\n#define DUK_STR_UNTERMINATED_CHARCLASS           \"unterminated character class\"\n#define DUK_STR_INVALID_RANGE                    \"invalid range\"\n\n/* Limits */\n#define DUK_STR_VALSTACK_LIMIT                   \"valstack limit\"\n#define DUK_STR_CALLSTACK_LIMIT                  \"callstack limit\"\n#define DUK_STR_PROTOTYPE_CHAIN_LIMIT            \"prototype chain limit\"\n#define DUK_STR_BOUND_CHAIN_LIMIT                \"function call bound chain limit\"\n#define DUK_STR_NATIVE_STACK_LIMIT               \"C stack depth limit\"\n#define DUK_STR_COMPILER_RECURSION_LIMIT         \"compiler recursion limit\"\n#define DUK_STR_BYTECODE_LIMIT                   \"bytecode limit\"\n#define DUK_STR_REG_LIMIT                        \"register limit\"\n#define DUK_STR_TEMP_LIMIT                       \"temp limit\"\n#define DUK_STR_CONST_LIMIT                      \"const limit\"\n#define DUK_STR_FUNC_LIMIT                       \"function limit\"\n#define DUK_STR_REGEXP_COMPILER_RECURSION_LIMIT  \"regexp compiler recursion limit\"\n#define DUK_STR_REGEXP_EXECUTOR_RECURSION_LIMIT  \"regexp executor recursion limit\"\n#define DUK_STR_REGEXP_EXECUTOR_STEP_LIMIT       \"regexp step limit\"\n\n#endif  /* DUK_ERRMSG_H_INCLUDED */\n/* #include duk_js_bytecode.h */\n#line 1 \"duk_js_bytecode.h\"\n/*\n *  ECMAScript bytecode\n */\n\n#if !defined(DUK_JS_BYTECODE_H_INCLUDED)\n#define DUK_JS_BYTECODE_H_INCLUDED\n\n/*\n *  Bytecode instruction layout\n *  ===========================\n *\n *  Instructions are unsigned 32-bit integers divided as follows:\n *\n *  !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! !\n *  !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!\n *  +-----------------------------------------------+---------------+\n *  !       C       !       B       !       A       !       OP      !\n *  +-----------------------------------------------+---------------+\n *\n *  OP (8 bits):  opcode (DUK_OP_*), access should be fastest\n *                consecutive opcodes allocated when opcode needs flags\n *   A (8 bits):  typically a target register number\n *   B (8 bits):  typically first source register/constant number\n *   C (8 bits):  typically second source register/constant number\n *\n *  Some instructions combine BC or ABC together for larger parameter values.\n *  Signed integers (e.g. jump offsets) are encoded as unsigned, with an\n *  opcode specific bias.\n *\n *  Some opcodes have flags which are handled by allocating consecutive\n *  opcodes to make space for 1-N flags.  Flags can also be e.g. in the 'A'\n *  field when there's room for the specific opcode.\n *\n *  For example, if three flags were needed, they could be allocated from\n *  the opcode field as follows:\n *\n *  !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! !\n *  !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!\n *  +-----------------------------------------------+---------------+\n *  !       C       !       B       !       A       !    OP   !Z!Y!X!\n *  +-----------------------------------------------+---------------+\n *\n *  Some opcodes accept a reg/const argument which is handled by allocating\n *  flags in the OP field, see DUK_BC_ISREG() and DUK_BC_ISCONST().  The\n *  following convention is shared by most opcodes, so that the compiler\n *  can handle reg/const flagging without opcode specific code paths:\n *\n *  !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! !\n *  !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!\n *  +-----------------------------------------------+---------------+\n *  !       C       !       B       !       A       !     OP    !Y!X!\n *  +-----------------------------------------------+---------------+\n *\n *    X  1=B is const, 0=B is reg\n *    Y  1=C is const, 0=C is reg\n *\n *    In effect OP, OP + 1, OP + 2, and OP + 3 are allocated from the\n *    8-bit opcode space for a single logical opcode.  The base opcode\n *    number should be divisible by 4.  If the opcode is called 'FOO'\n *    the following opcode constants would be defined:\n *\n *      DUK_OP_FOO     100       // base opcode number\n *      DUK_OP_FOO_RR  100       // FOO, B=reg, C=reg\n *      DUK_OP_FOO_CR  101       // FOO, B=const, C=reg\n *      DUK_OP_FOO_RC  102       // FOO, B=reg, C=const\n *      DUK_OP_FOO_CC  103       // FOO, B=const, C=const\n *\n *  If only B or C is a reg/const, the unused opcode combinations can be\n *  used for other opcodes (which take no reg/const argument).  However,\n *  such opcode values are initially reserved, at least while opcode space\n *  is available.  For example, if 'BAR' uses B for a register field and\n *  C is a reg/const:\n *\n *      DUK_OP_BAR            116    // base opcode number\n *      DUK_OP_BAR_RR         116    // BAR, B=reg, C=reg\n *      DUK_OP_BAR_CR_UNUSED  117    // unused, could be repurposed\n *      DUK_OP_BAR_RC         118    // BAR, B=reg, C=const\n *      DUK_OP_BAR_CC_UNUSED  119    // unused, could be repurposed\n *\n *  Macro naming is a bit misleading, e.g. \"ABC\" in macro name but the\n *  field layout is concretely \"CBA\" in the register.\n */\n\ntypedef duk_uint32_t duk_instr_t;\n\n#define DUK_BC_SHIFT_OP             0\n#define DUK_BC_SHIFT_A              8\n#define DUK_BC_SHIFT_B              16\n#define DUK_BC_SHIFT_C              24\n#define DUK_BC_SHIFT_BC             DUK_BC_SHIFT_B\n#define DUK_BC_SHIFT_ABC            DUK_BC_SHIFT_A\n\n#define DUK_BC_UNSHIFTED_MASK_OP    0xffUL\n#define DUK_BC_UNSHIFTED_MASK_A     0xffUL\n#define DUK_BC_UNSHIFTED_MASK_B     0xffUL\n#define DUK_BC_UNSHIFTED_MASK_C     0xffUL\n#define DUK_BC_UNSHIFTED_MASK_BC    0xffffUL\n#define DUK_BC_UNSHIFTED_MASK_ABC   0xffffffUL\n\n#define DUK_BC_SHIFTED_MASK_OP      (DUK_BC_UNSHIFTED_MASK_OP << DUK_BC_SHIFT_OP)\n#define DUK_BC_SHIFTED_MASK_A       (DUK_BC_UNSHIFTED_MASK_A << DUK_BC_SHIFT_A)\n#define DUK_BC_SHIFTED_MASK_B       (DUK_BC_UNSHIFTED_MASK_B << DUK_BC_SHIFT_B)\n#define DUK_BC_SHIFTED_MASK_C       (DUK_BC_UNSHIFTED_MASK_C << DUK_BC_SHIFT_C)\n#define DUK_BC_SHIFTED_MASK_BC      (DUK_BC_UNSHIFTED_MASK_BC << DUK_BC_SHIFT_BC)\n#define DUK_BC_SHIFTED_MASK_ABC     (DUK_BC_UNSHIFTED_MASK_ABC << DUK_BC_SHIFT_ABC)\n\n#define DUK_DEC_OP(x)               ((x) & 0xffUL)\n#define DUK_DEC_A(x)                (((x) >> 8) & 0xffUL)\n#define DUK_DEC_B(x)                (((x) >> 16) & 0xffUL)\n#define DUK_DEC_C(x)                (((x) >> 24) & 0xffUL)\n#define DUK_DEC_BC(x)               (((x) >> 16) & 0xffffUL)\n#define DUK_DEC_ABC(x)              (((x) >> 8) & 0xffffffUL)\n\n#define DUK_ENC_OP(op)              ((duk_instr_t) (op))\n#define DUK_ENC_OP_ABC(op,abc)      ((duk_instr_t) ( \\\n                                        (((duk_instr_t) (abc)) << 8) | \\\n                                        ((duk_instr_t) (op)) \\\n                                    ))\n#define DUK_ENC_OP_A_BC(op,a,bc)    ((duk_instr_t) ( \\\n                                        (((duk_instr_t) (bc)) << 16) | \\\n                                        (((duk_instr_t) (a)) << 8) | \\\n                                        ((duk_instr_t) (op)) \\\n                                    ))\n#define DUK_ENC_OP_A_B_C(op,a,b,c)  ((duk_instr_t) ( \\\n                                        (((duk_instr_t) (c)) << 24) | \\\n                                        (((duk_instr_t) (b)) << 16) | \\\n                                        (((duk_instr_t) (a)) << 8) | \\\n                                        ((duk_instr_t) (op)) \\\n                                    ))\n#define DUK_ENC_OP_A_B(op,a,b)      DUK_ENC_OP_A_B_C((op),(a),(b),0)\n#define DUK_ENC_OP_A(op,a)          DUK_ENC_OP_A_B_C((op),(a),0,0)\n#define DUK_ENC_OP_BC(op,bc)        DUK_ENC_OP_A_BC((op),0,(bc))\n\n/* Get opcode base value with B/C reg/const flags cleared. */\n#define DUK_BC_NOREGCONST_OP(op)    ((op) & 0xfc)\n\n/* Constants should be signed so that signed arithmetic involving them\n * won't cause values to be coerced accidentally to unsigned.\n */\n#define DUK_BC_OP_MIN               0\n#define DUK_BC_OP_MAX               0xffL\n#define DUK_BC_A_MIN                0\n#define DUK_BC_A_MAX                0xffL\n#define DUK_BC_B_MIN                0\n#define DUK_BC_B_MAX                0xffL\n#define DUK_BC_C_MIN                0\n#define DUK_BC_C_MAX                0xffL\n#define DUK_BC_BC_MIN               0\n#define DUK_BC_BC_MAX               0xffffL\n#define DUK_BC_ABC_MIN              0\n#define DUK_BC_ABC_MAX              0xffffffL\n\n/* Masks for B/C reg/const indicator in opcode field. */\n#define DUK_BC_REGCONST_B           (0x01UL)\n#define DUK_BC_REGCONST_C           (0x02UL)\n\n/* Misc. masks for opcode field. */\n#define DUK_BC_INCDECP_FLAG_DEC     (0x04UL)\n#define DUK_BC_INCDECP_FLAG_POST    (0x08UL)\n\n/* Opcodes. */\n#define DUK_OP_LDREG                0\n#define DUK_OP_STREG                1\n#define DUK_OP_JUMP                 2\n#define DUK_OP_LDCONST              3\n#define DUK_OP_LDINT                4\n#define DUK_OP_LDINTX               5\n#define DUK_OP_LDTHIS               6\n#define DUK_OP_LDUNDEF              7\n#define DUK_OP_LDNULL               8\n#define DUK_OP_LDTRUE               9\n#define DUK_OP_LDFALSE              10\n#define DUK_OP_GETVAR               11\n#define DUK_OP_BNOT                 12\n#define DUK_OP_LNOT                 13\n#define DUK_OP_UNM                  14\n#define DUK_OP_UNP                  15\n#define DUK_OP_EQ                   16\n#define DUK_OP_EQ_RR                16\n#define DUK_OP_EQ_CR                17\n#define DUK_OP_EQ_RC                18\n#define DUK_OP_EQ_CC                19\n#define DUK_OP_NEQ                  20\n#define DUK_OP_NEQ_RR               20\n#define DUK_OP_NEQ_CR               21\n#define DUK_OP_NEQ_RC               22\n#define DUK_OP_NEQ_CC               23\n#define DUK_OP_SEQ                  24\n#define DUK_OP_SEQ_RR               24\n#define DUK_OP_SEQ_CR               25\n#define DUK_OP_SEQ_RC               26\n#define DUK_OP_SEQ_CC               27\n#define DUK_OP_SNEQ                 28\n#define DUK_OP_SNEQ_RR              28\n#define DUK_OP_SNEQ_CR              29\n#define DUK_OP_SNEQ_RC              30\n#define DUK_OP_SNEQ_CC              31\n#define DUK_OP_GT                   32\n#define DUK_OP_GT_RR                32\n#define DUK_OP_GT_CR                33\n#define DUK_OP_GT_RC                34\n#define DUK_OP_GT_CC                35\n#define DUK_OP_GE                   36\n#define DUK_OP_GE_RR                36\n#define DUK_OP_GE_CR                37\n#define DUK_OP_GE_RC                38\n#define DUK_OP_GE_CC                39\n#define DUK_OP_LT                   40\n#define DUK_OP_LT_RR                40\n#define DUK_OP_LT_CR                41\n#define DUK_OP_LT_RC                42\n#define DUK_OP_LT_CC                43\n#define DUK_OP_LE                   44\n#define DUK_OP_LE_RR                44\n#define DUK_OP_LE_CR                45\n#define DUK_OP_LE_RC                46\n#define DUK_OP_LE_CC                47\n#define DUK_OP_IFTRUE               48\n#define DUK_OP_IFTRUE_R             48\n#define DUK_OP_IFTRUE_C             49\n#define DUK_OP_IFFALSE              50\n#define DUK_OP_IFFALSE_R            50\n#define DUK_OP_IFFALSE_C            51\n#define DUK_OP_ADD                  52\n#define DUK_OP_ADD_RR               52\n#define DUK_OP_ADD_CR               53\n#define DUK_OP_ADD_RC               54\n#define DUK_OP_ADD_CC               55\n#define DUK_OP_SUB                  56\n#define DUK_OP_SUB_RR               56\n#define DUK_OP_SUB_CR               57\n#define DUK_OP_SUB_RC               58\n#define DUK_OP_SUB_CC               59\n#define DUK_OP_MUL                  60\n#define DUK_OP_MUL_RR               60\n#define DUK_OP_MUL_CR               61\n#define DUK_OP_MUL_RC               62\n#define DUK_OP_MUL_CC               63\n#define DUK_OP_DIV                  64\n#define DUK_OP_DIV_RR               64\n#define DUK_OP_DIV_CR               65\n#define DUK_OP_DIV_RC               66\n#define DUK_OP_DIV_CC               67\n#define DUK_OP_MOD                  68\n#define DUK_OP_MOD_RR               68\n#define DUK_OP_MOD_CR               69\n#define DUK_OP_MOD_RC               70\n#define DUK_OP_MOD_CC               71\n#define DUK_OP_EXP                  72\n#define DUK_OP_EXP_RR               72\n#define DUK_OP_EXP_CR               73\n#define DUK_OP_EXP_RC               74\n#define DUK_OP_EXP_CC               75\n#define DUK_OP_BAND                 76\n#define DUK_OP_BAND_RR              76\n#define DUK_OP_BAND_CR              77\n#define DUK_OP_BAND_RC              78\n#define DUK_OP_BAND_CC              79\n#define DUK_OP_BOR                  80\n#define DUK_OP_BOR_RR               80\n#define DUK_OP_BOR_CR               81\n#define DUK_OP_BOR_RC               82\n#define DUK_OP_BOR_CC               83\n#define DUK_OP_BXOR                 84\n#define DUK_OP_BXOR_RR              84\n#define DUK_OP_BXOR_CR              85\n#define DUK_OP_BXOR_RC              86\n#define DUK_OP_BXOR_CC              87\n#define DUK_OP_BASL                 88\n#define DUK_OP_BASL_RR              88\n#define DUK_OP_BASL_CR              89\n#define DUK_OP_BASL_RC              90\n#define DUK_OP_BASL_CC              91\n#define DUK_OP_BLSR                 92\n#define DUK_OP_BLSR_RR              92\n#define DUK_OP_BLSR_CR              93\n#define DUK_OP_BLSR_RC              94\n#define DUK_OP_BLSR_CC              95\n#define DUK_OP_BASR                 96\n#define DUK_OP_BASR_RR              96\n#define DUK_OP_BASR_CR              97\n#define DUK_OP_BASR_RC              98\n#define DUK_OP_BASR_CC              99\n#define DUK_OP_INSTOF               100\n#define DUK_OP_INSTOF_RR            100\n#define DUK_OP_INSTOF_CR            101\n#define DUK_OP_INSTOF_RC            102\n#define DUK_OP_INSTOF_CC            103\n#define DUK_OP_IN                   104\n#define DUK_OP_IN_RR                104\n#define DUK_OP_IN_CR                105\n#define DUK_OP_IN_RC                106\n#define DUK_OP_IN_CC                107\n#define DUK_OP_GETPROP              108\n#define DUK_OP_GETPROP_RR           108\n#define DUK_OP_GETPROP_CR           109\n#define DUK_OP_GETPROP_RC           110\n#define DUK_OP_GETPROP_CC           111\n#define DUK_OP_PUTPROP              112\n#define DUK_OP_PUTPROP_RR           112\n#define DUK_OP_PUTPROP_CR           113\n#define DUK_OP_PUTPROP_RC           114\n#define DUK_OP_PUTPROP_CC           115\n#define DUK_OP_DELPROP              116\n#define DUK_OP_DELPROP_RR           116\n#define DUK_OP_DELPROP_CR_UNUSED    117  /* unused now */\n#define DUK_OP_DELPROP_RC           118\n#define DUK_OP_DELPROP_CC_UNUSED    119  /* unused now */\n#define DUK_OP_PREINCR              120  /* pre/post opcode values have constraints, */\n#define DUK_OP_PREDECR              121  /* see duk_js_executor.c and duk_js_compiler.c. */\n#define DUK_OP_POSTINCR             122\n#define DUK_OP_POSTDECR             123\n#define DUK_OP_PREINCV              124\n#define DUK_OP_PREDECV              125\n#define DUK_OP_POSTINCV             126\n#define DUK_OP_POSTDECV             127\n#define DUK_OP_PREINCP              128  /* pre/post inc/dec prop opcodes have constraints */\n#define DUK_OP_PREINCP_RR           128\n#define DUK_OP_PREINCP_CR           129\n#define DUK_OP_PREINCP_RC           130\n#define DUK_OP_PREINCP_CC           131\n#define DUK_OP_PREDECP              132\n#define DUK_OP_PREDECP_RR           132\n#define DUK_OP_PREDECP_CR           133\n#define DUK_OP_PREDECP_RC           134\n#define DUK_OP_PREDECP_CC           135\n#define DUK_OP_POSTINCP             136\n#define DUK_OP_POSTINCP_RR          136\n#define DUK_OP_POSTINCP_CR          137\n#define DUK_OP_POSTINCP_RC          138\n#define DUK_OP_POSTINCP_CC          139\n#define DUK_OP_POSTDECP             140\n#define DUK_OP_POSTDECP_RR          140\n#define DUK_OP_POSTDECP_CR          141\n#define DUK_OP_POSTDECP_RC          142\n#define DUK_OP_POSTDECP_CC          143\n#define DUK_OP_DECLVAR              144\n#define DUK_OP_DECLVAR_RR           144\n#define DUK_OP_DECLVAR_CR           145\n#define DUK_OP_DECLVAR_RC           146\n#define DUK_OP_DECLVAR_CC           147\n#define DUK_OP_REGEXP               148\n#define DUK_OP_REGEXP_RR            148\n#define DUK_OP_REGEXP_CR            149\n#define DUK_OP_REGEXP_RC            150\n#define DUK_OP_REGEXP_CC            151\n#define DUK_OP_CLOSURE              152\n#define DUK_OP_TYPEOF               153\n#define DUK_OP_TYPEOFID             154\n#define DUK_OP_PUTVAR               155\n#define DUK_OP_DELVAR               156\n#define DUK_OP_RETREG               157\n#define DUK_OP_RETUNDEF             158\n#define DUK_OP_RETCONST             159\n#define DUK_OP_RETCONSTN            160  /* return const without incref (e.g. number) */\n#define DUK_OP_LABEL                161\n#define DUK_OP_ENDLABEL             162\n#define DUK_OP_BREAK                163\n#define DUK_OP_CONTINUE             164\n#define DUK_OP_TRYCATCH             165\n#define DUK_OP_ENDTRY               166\n#define DUK_OP_ENDCATCH             167\n#define DUK_OP_ENDFIN               168\n#define DUK_OP_THROW                169\n#define DUK_OP_INVLHS               170\n#define DUK_OP_CSREG                171\n#define DUK_OP_CSVAR                172\n#define DUK_OP_CSVAR_RR             172\n#define DUK_OP_CSVAR_CR             173\n#define DUK_OP_CSVAR_RC             174\n#define DUK_OP_CSVAR_CC             175\n#define DUK_OP_CALL0                176  /* DUK_OP_CALL0 & 0x0F must be zero. */\n#define DUK_OP_CALL1                177\n#define DUK_OP_CALL2                178\n#define DUK_OP_CALL3                179\n#define DUK_OP_CALL4                180\n#define DUK_OP_CALL5                181\n#define DUK_OP_CALL6                182\n#define DUK_OP_CALL7                183\n#define DUK_OP_CALL8                184\n#define DUK_OP_CALL9                185\n#define DUK_OP_CALL10               186\n#define DUK_OP_CALL11               187\n#define DUK_OP_CALL12               188\n#define DUK_OP_CALL13               189\n#define DUK_OP_CALL14               190\n#define DUK_OP_CALL15               191\n#define DUK_OP_NEWOBJ               192\n#define DUK_OP_NEWARR               193\n#define DUK_OP_MPUTOBJ              194\n#define DUK_OP_MPUTOBJI             195\n#define DUK_OP_INITSET              196\n#define DUK_OP_INITGET              197\n#define DUK_OP_MPUTARR              198\n#define DUK_OP_MPUTARRI             199\n#define DUK_OP_SETALEN              200\n#define DUK_OP_INITENUM             201\n#define DUK_OP_NEXTENUM             202\n#define DUK_OP_NEWTARGET            203\n#define DUK_OP_DEBUGGER             204\n#define DUK_OP_NOP                  205\n#define DUK_OP_INVALID              206\n#define DUK_OP_UNUSED207            207\n#define DUK_OP_GETPROPC             208\n#define DUK_OP_GETPROPC_RR          208\n#define DUK_OP_GETPROPC_CR          209\n#define DUK_OP_GETPROPC_RC          210\n#define DUK_OP_GETPROPC_CC          211\n#define DUK_OP_UNUSED212            212\n#define DUK_OP_UNUSED213            213\n#define DUK_OP_UNUSED214            214\n#define DUK_OP_UNUSED215            215\n#define DUK_OP_UNUSED216            216\n#define DUK_OP_UNUSED217            217\n#define DUK_OP_UNUSED218            218\n#define DUK_OP_UNUSED219            219\n#define DUK_OP_UNUSED220            220\n#define DUK_OP_UNUSED221            221\n#define DUK_OP_UNUSED222            222\n#define DUK_OP_UNUSED223            223\n#define DUK_OP_UNUSED224            224\n#define DUK_OP_UNUSED225            225\n#define DUK_OP_UNUSED226            226\n#define DUK_OP_UNUSED227            227\n#define DUK_OP_UNUSED228            228\n#define DUK_OP_UNUSED229            229\n#define DUK_OP_UNUSED230            230\n#define DUK_OP_UNUSED231            231\n#define DUK_OP_UNUSED232            232\n#define DUK_OP_UNUSED233            233\n#define DUK_OP_UNUSED234            234\n#define DUK_OP_UNUSED235            235\n#define DUK_OP_UNUSED236            236\n#define DUK_OP_UNUSED237            237\n#define DUK_OP_UNUSED238            238\n#define DUK_OP_UNUSED239            239\n#define DUK_OP_UNUSED240            240\n#define DUK_OP_UNUSED241            241\n#define DUK_OP_UNUSED242            242\n#define DUK_OP_UNUSED243            243\n#define DUK_OP_UNUSED244            244\n#define DUK_OP_UNUSED245            245\n#define DUK_OP_UNUSED246            246\n#define DUK_OP_UNUSED247            247\n#define DUK_OP_UNUSED248            248\n#define DUK_OP_UNUSED249            249\n#define DUK_OP_UNUSED250            250\n#define DUK_OP_UNUSED251            251\n#define DUK_OP_UNUSED252            252\n#define DUK_OP_UNUSED253            253\n#define DUK_OP_UNUSED254            254\n#define DUK_OP_UNUSED255            255\n#define DUK_OP_NONE                 256  /* dummy value used as marker (doesn't fit in 8-bit field) */\n\n/* XXX: Allocate flags from opcode field?  Would take 16 opcode slots\n * but avoids shuffling in more cases.  Maybe not worth it.\n */\n/* DUK_OP_TRYCATCH flags in A. */\n#define DUK_BC_TRYCATCH_FLAG_HAVE_CATCH     (1U << 0)\n#define DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY   (1U << 1)\n#define DUK_BC_TRYCATCH_FLAG_CATCH_BINDING  (1U << 2)\n#define DUK_BC_TRYCATCH_FLAG_WITH_BINDING   (1U << 3)\n\n/* DUK_OP_DECLVAR flags in A; bottom bits are reserved for propdesc flags\n * (DUK_PROPDESC_FLAG_XXX).\n */\n#define DUK_BC_DECLVAR_FLAG_FUNC_DECL       (1U << 4)  /* function declaration */\n\n/* DUK_OP_CALLn flags, part of opcode field.  Three lowest bits must match\n * DUK_CALL_FLAG_xxx directly.\n */\n#define DUK_BC_CALL_FLAG_TAILCALL           (1U << 0)\n#define DUK_BC_CALL_FLAG_CONSTRUCT          (1U << 1)\n#define DUK_BC_CALL_FLAG_CALLED_AS_EVAL     (1U << 2)\n#define DUK_BC_CALL_FLAG_INDIRECT           (1U << 3)\n\n/* Misc constants and helper macros. */\n#define DUK_BC_LDINT_BIAS           (1L << 15)\n#define DUK_BC_LDINTX_SHIFT         16\n#define DUK_BC_JUMP_BIAS            (1L << 23)\n\n#endif  /* DUK_JS_BYTECODE_H_INCLUDED */\n/* #include duk_lexer.h */\n#line 1 \"duk_lexer.h\"\n/*\n *  Lexer defines.\n */\n\n#if !defined(DUK_LEXER_H_INCLUDED)\n#define DUK_LEXER_H_INCLUDED\n\ntypedef void (*duk_re_range_callback)(void *user, duk_codepoint_t r1, duk_codepoint_t r2, duk_bool_t direct);\n\n/*\n *  A token is interpreted as any possible production of InputElementDiv\n *  and InputElementRegExp, see E5 Section 7 in its entirety.  Note that\n *  the E5 \"Token\" production does not cover all actual tokens of the\n *  language (which is explicitly stated in the specification, Section 7.5).\n *  Null and boolean literals are defined as part of both ReservedWord\n *  (E5 Section 7.6.1) and Literal (E5 Section 7.8) productions.  Here,\n *  null and boolean values have literal tokens, and are not reserved\n *  words.\n *\n *  Decimal literal negative/positive sign is -not- part of DUK_TOK_NUMBER.\n *  The number tokens always have a non-negative value.  The unary minus\n *  operator in \"-1.0\" is optimized during compilation to yield a single\n *  negative constant.\n *\n *  Token numbering is free except that reserved words are required to be\n *  in a continuous range and in a particular order.  See genstrings.py.\n */\n\n#define DUK_LEXER_INITCTX(ctx)        duk_lexer_initctx((ctx))\n\n#define DUK_LEXER_SETPOINT(ctx,pt)    duk_lexer_setpoint((ctx), (pt))\n\n#define DUK_LEXER_GETPOINT(ctx,pt)    duk_lexer_getpoint((ctx), (pt))\n\n/* Currently 6 characters of lookup are actually needed (duk_lexer.c). */\n#define DUK_LEXER_WINDOW_SIZE                     6\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\n#define DUK_LEXER_BUFFER_SIZE                     64\n#endif\n\n#define DUK_TOK_MINVAL                            0\n\n/* returned after EOF (infinite amount) */\n#define DUK_TOK_EOF                               0\n\n/* identifier names (E5 Section 7.6) */\n#define DUK_TOK_IDENTIFIER                        1\n\n/* reserved words: keywords */\n#define DUK_TOK_START_RESERVED                    2\n#define DUK_TOK_BREAK                             2\n#define DUK_TOK_CASE                              3\n#define DUK_TOK_CATCH                             4\n#define DUK_TOK_CONTINUE                          5\n#define DUK_TOK_DEBUGGER                          6\n#define DUK_TOK_DEFAULT                           7\n#define DUK_TOK_DELETE                            8\n#define DUK_TOK_DO                                9\n#define DUK_TOK_ELSE                              10\n#define DUK_TOK_FINALLY                           11\n#define DUK_TOK_FOR                               12\n#define DUK_TOK_FUNCTION                          13\n#define DUK_TOK_IF                                14\n#define DUK_TOK_IN                                15\n#define DUK_TOK_INSTANCEOF                        16\n#define DUK_TOK_NEW                               17\n#define DUK_TOK_RETURN                            18\n#define DUK_TOK_SWITCH                            19\n#define DUK_TOK_THIS                              20\n#define DUK_TOK_THROW                             21\n#define DUK_TOK_TRY                               22\n#define DUK_TOK_TYPEOF                            23\n#define DUK_TOK_VAR                               24\n#define DUK_TOK_CONST                             25\n#define DUK_TOK_VOID                              26\n#define DUK_TOK_WHILE                             27\n#define DUK_TOK_WITH                              28\n\n/* reserved words: future reserved words */\n#define DUK_TOK_CLASS                             29\n#define DUK_TOK_ENUM                              30\n#define DUK_TOK_EXPORT                            31\n#define DUK_TOK_EXTENDS                           32\n#define DUK_TOK_IMPORT                            33\n#define DUK_TOK_SUPER                             34\n\n/* \"null\", \"true\", and \"false\" are always reserved words.\n * Note that \"get\" and \"set\" are not!\n */\n#define DUK_TOK_NULL                              35\n#define DUK_TOK_TRUE                              36\n#define DUK_TOK_FALSE                             37\n\n/* reserved words: additional future reserved words in strict mode */\n#define DUK_TOK_START_STRICT_RESERVED             38  /* inclusive */\n#define DUK_TOK_IMPLEMENTS                        38\n#define DUK_TOK_INTERFACE                         39\n#define DUK_TOK_LET                               40\n#define DUK_TOK_PACKAGE                           41\n#define DUK_TOK_PRIVATE                           42\n#define DUK_TOK_PROTECTED                         43\n#define DUK_TOK_PUBLIC                            44\n#define DUK_TOK_STATIC                            45\n#define DUK_TOK_YIELD                             46\n\n#define DUK_TOK_END_RESERVED                      47  /* exclusive */\n\n/* \"get\" and \"set\" are tokens but NOT ReservedWords.  They are currently\n * parsed and identifiers and these defines are actually now unused.\n */\n#define DUK_TOK_GET                               47\n#define DUK_TOK_SET                               48\n\n/* punctuators (unlike the spec, also includes \"/\" and \"/=\") */\n#define DUK_TOK_LCURLY                            49\n#define DUK_TOK_RCURLY                            50\n#define DUK_TOK_LBRACKET                          51\n#define DUK_TOK_RBRACKET                          52\n#define DUK_TOK_LPAREN                            53\n#define DUK_TOK_RPAREN                            54\n#define DUK_TOK_PERIOD                            55\n#define DUK_TOK_SEMICOLON                         56\n#define DUK_TOK_COMMA                             57\n#define DUK_TOK_LT                                58\n#define DUK_TOK_GT                                59\n#define DUK_TOK_LE                                60\n#define DUK_TOK_GE                                61\n#define DUK_TOK_EQ                                62\n#define DUK_TOK_NEQ                               63\n#define DUK_TOK_SEQ                               64\n#define DUK_TOK_SNEQ                              65\n#define DUK_TOK_ADD                               66\n#define DUK_TOK_SUB                               67\n#define DUK_TOK_MUL                               68\n#define DUK_TOK_DIV                               69\n#define DUK_TOK_MOD                               70\n#define DUK_TOK_EXP                               71\n#define DUK_TOK_INCREMENT                         72\n#define DUK_TOK_DECREMENT                         73\n#define DUK_TOK_ALSHIFT                           74   /* named \"arithmetic\" because result is signed */\n#define DUK_TOK_ARSHIFT                           75\n#define DUK_TOK_RSHIFT                            76\n#define DUK_TOK_BAND                              77\n#define DUK_TOK_BOR                               78\n#define DUK_TOK_BXOR                              79\n#define DUK_TOK_LNOT                              80\n#define DUK_TOK_BNOT                              81\n#define DUK_TOK_LAND                              82\n#define DUK_TOK_LOR                               83\n#define DUK_TOK_QUESTION                          84\n#define DUK_TOK_COLON                             85\n#define DUK_TOK_EQUALSIGN                         86\n#define DUK_TOK_ADD_EQ                            87\n#define DUK_TOK_SUB_EQ                            88\n#define DUK_TOK_MUL_EQ                            89\n#define DUK_TOK_DIV_EQ                            90\n#define DUK_TOK_MOD_EQ                            91\n#define DUK_TOK_EXP_EQ                            92\n#define DUK_TOK_ALSHIFT_EQ                        93\n#define DUK_TOK_ARSHIFT_EQ                        94\n#define DUK_TOK_RSHIFT_EQ                         95\n#define DUK_TOK_BAND_EQ                           96\n#define DUK_TOK_BOR_EQ                            97\n#define DUK_TOK_BXOR_EQ                           98\n\n/* literals (E5 Section 7.8), except null, true, false, which are treated\n * like reserved words (above).\n */\n#define DUK_TOK_NUMBER                            99\n#define DUK_TOK_STRING                            100\n#define DUK_TOK_REGEXP                            101\n\n#define DUK_TOK_MAXVAL                            101  /* inclusive */\n\n#define DUK_TOK_INVALID                           DUK_SMALL_UINT_MAX\n\n/* Convert heap string index to a token (reserved words) */\n#define DUK_STRIDX_TO_TOK(x)                        ((x) - DUK_STRIDX_START_RESERVED + DUK_TOK_START_RESERVED)\n\n/* Sanity check */\n#if (DUK_TOK_MAXVAL > 255)\n#error DUK_TOK_MAXVAL too large, code assumes it fits into 8 bits\n#endif\n\n/* Sanity checks for string and token defines */\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_BREAK) != DUK_TOK_BREAK)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CASE) != DUK_TOK_CASE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CATCH) != DUK_TOK_CATCH)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CONTINUE) != DUK_TOK_CONTINUE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DEBUGGER) != DUK_TOK_DEBUGGER)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DEFAULT) != DUK_TOK_DEFAULT)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DELETE) != DUK_TOK_DELETE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DO) != DUK_TOK_DO)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_ELSE) != DUK_TOK_ELSE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_FINALLY) != DUK_TOK_FINALLY)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_FOR) != DUK_TOK_FOR)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_LC_FUNCTION) != DUK_TOK_FUNCTION)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IF) != DUK_TOK_IF)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IN) != DUK_TOK_IN)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_INSTANCEOF) != DUK_TOK_INSTANCEOF)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_NEW) != DUK_TOK_NEW)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_RETURN) != DUK_TOK_RETURN)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_SWITCH) != DUK_TOK_SWITCH)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_THIS) != DUK_TOK_THIS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_THROW) != DUK_TOK_THROW)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_TRY) != DUK_TOK_TRY)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_TYPEOF) != DUK_TOK_TYPEOF)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_VAR) != DUK_TOK_VAR)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_VOID) != DUK_TOK_VOID)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_WHILE) != DUK_TOK_WHILE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_WITH) != DUK_TOK_WITH)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CLASS) != DUK_TOK_CLASS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CONST) != DUK_TOK_CONST)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_ENUM) != DUK_TOK_ENUM)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_EXPORT) != DUK_TOK_EXPORT)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_EXTENDS) != DUK_TOK_EXTENDS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IMPORT) != DUK_TOK_IMPORT)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_SUPER) != DUK_TOK_SUPER)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_LC_NULL) != DUK_TOK_NULL)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_TRUE) != DUK_TOK_TRUE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_FALSE) != DUK_TOK_FALSE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IMPLEMENTS) != DUK_TOK_IMPLEMENTS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_INTERFACE) != DUK_TOK_INTERFACE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_LET) != DUK_TOK_LET)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PACKAGE) != DUK_TOK_PACKAGE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PRIVATE) != DUK_TOK_PRIVATE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PROTECTED) != DUK_TOK_PROTECTED)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PUBLIC) != DUK_TOK_PUBLIC)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_STATIC) != DUK_TOK_STATIC)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_YIELD) != DUK_TOK_YIELD)\n#error mismatch in token defines\n#endif\n\n/* Regexp tokens */\n#define DUK_RETOK_EOF                              0\n#define DUK_RETOK_DISJUNCTION                      1\n#define DUK_RETOK_QUANTIFIER                       2\n#define DUK_RETOK_ASSERT_START                     3\n#define DUK_RETOK_ASSERT_END                       4\n#define DUK_RETOK_ASSERT_WORD_BOUNDARY             5\n#define DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY         6\n#define DUK_RETOK_ASSERT_START_POS_LOOKAHEAD       7\n#define DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD       8\n#define DUK_RETOK_ATOM_PERIOD                      9\n#define DUK_RETOK_ATOM_CHAR                        10\n#define DUK_RETOK_ATOM_DIGIT                       11  /* assumptions in regexp compiler */\n#define DUK_RETOK_ATOM_NOT_DIGIT                   12  /* -\"\"- */\n#define DUK_RETOK_ATOM_WHITE                       13  /* -\"\"- */\n#define DUK_RETOK_ATOM_NOT_WHITE                   14  /* -\"\"- */\n#define DUK_RETOK_ATOM_WORD_CHAR                   15  /* -\"\"- */\n#define DUK_RETOK_ATOM_NOT_WORD_CHAR               16  /* -\"\"- */\n#define DUK_RETOK_ATOM_BACKREFERENCE               17\n#define DUK_RETOK_ATOM_START_CAPTURE_GROUP         18\n#define DUK_RETOK_ATOM_START_NONCAPTURE_GROUP      19\n#define DUK_RETOK_ATOM_START_CHARCLASS             20\n#define DUK_RETOK_ATOM_START_CHARCLASS_INVERTED    21\n#define DUK_RETOK_ATOM_END_GROUP                   22\n\n/* Constants for duk_lexer_ctx.buf. */\n#define DUK_LEXER_TEMP_BUF_LIMIT                   256\n\n/* A token value.  Can be memcpy()'d, but note that slot1/slot2 values are on the valstack.\n * Some fields (like num, str1, str2) are only valid for specific token types and may have\n * stale values otherwise.\n */\nstruct duk_token {\n\tduk_small_uint_t t;           /* token type (with reserved word identification) */\n\tduk_small_uint_t t_nores;     /* token type (with reserved words as DUK_TOK_IDENTIFER) */\n\tduk_double_t num;             /* numeric value of token */\n\tduk_hstring *str1;            /* string 1 of token (borrowed, stored to ctx->slot1_idx) */\n\tduk_hstring *str2;            /* string 2 of token (borrowed, stored to ctx->slot2_idx) */\n\tduk_size_t start_offset;      /* start byte offset of token in lexer input */\n\tduk_int_t start_line;         /* start line of token (first char) */\n\tduk_int_t num_escapes;        /* number of escapes and line continuations (for directive prologue) */\n\tduk_bool_t lineterm;          /* token was preceded by a lineterm */\n\tduk_bool_t allow_auto_semi;   /* token allows automatic semicolon insertion (eof or preceded by newline) */\n};\n\n#define DUK_RE_QUANTIFIER_INFINITE         ((duk_uint32_t) 0xffffffffUL)\n\n/* A regexp token value. */\nstruct duk_re_token {\n\tduk_small_uint_t t;          /* token type */\n\tduk_small_uint_t greedy;\n\tduk_uint32_t num;            /* numeric value (character, count) */\n\tduk_uint32_t qmin;\n\tduk_uint32_t qmax;\n};\n\n/* A structure for 'snapshotting' a point for rewinding */\nstruct duk_lexer_point {\n\tduk_size_t offset;\n\tduk_int_t line;\n};\n\n/* Lexer codepoint with additional info like offset/line number */\nstruct duk_lexer_codepoint {\n\tduk_codepoint_t codepoint;\n\tduk_size_t offset;\n\tduk_int_t line;\n};\n\n/* Lexer context.  Same context is used for ECMAScript and Regexp parsing. */\nstruct duk_lexer_ctx {\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\n\tduk_lexer_codepoint *window; /* unicode code points, window[0] is always next, points to 'buffer' */\n\tduk_lexer_codepoint buffer[DUK_LEXER_BUFFER_SIZE];\n#else\n\tduk_lexer_codepoint window[DUK_LEXER_WINDOW_SIZE]; /* unicode code points, window[0] is always next */\n#endif\n\n\tduk_hthread *thr;                              /* thread; minimizes argument passing */\n\n\tconst duk_uint8_t *input;                      /* input string (may be a user pointer) */\n\tduk_size_t input_length;                       /* input byte length */\n\tduk_size_t input_offset;                       /* input offset for window leading edge (not window[0]) */\n\tduk_int_t input_line;                          /* input linenumber at input_offset (not window[0]), init to 1 */\n\n\tduk_idx_t slot1_idx;                           /* valstack slot for 1st token value */\n\tduk_idx_t slot2_idx;                           /* valstack slot for 2nd token value */\n\tduk_idx_t buf_idx;                             /* valstack slot for temp buffer */\n\tduk_hbuffer_dynamic *buf;                      /* temp accumulation buffer */\n\tduk_bufwriter_ctx bw;                          /* bufwriter for temp accumulation */\n\n\tduk_int_t token_count;                         /* number of tokens parsed */\n\tduk_int_t token_limit;                         /* maximum token count before error (sanity backstop) */\n\n\tduk_small_uint_t flags;                        /* lexer flags, use compiler flag defines for now */\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_lexer_initctx(duk_lexer_ctx *lex_ctx);\n\nDUK_INTERNAL_DECL void duk_lexer_getpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt);\nDUK_INTERNAL_DECL void duk_lexer_setpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt);\n\nDUK_INTERNAL_DECL\nvoid duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,\n                                      duk_token *out_token,\n                                      duk_bool_t strict_mode,\n                                      duk_bool_t regexp_mode);\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL_DECL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token *out_token);\nDUK_INTERNAL_DECL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_range_callback gen_range, void *userdata);\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n#endif  /* DUK_LEXER_H_INCLUDED */\n/* #include duk_js_compiler.h */\n#line 1 \"duk_js_compiler.h\"\n/*\n *  ECMAScript compiler.\n */\n\n#if !defined(DUK_JS_COMPILER_H_INCLUDED)\n#define DUK_JS_COMPILER_H_INCLUDED\n\n/* ECMAScript compiler limits */\n#define DUK_COMPILER_TOKEN_LIMIT           100000000L  /* 1e8: protects against deeply nested inner functions */\n\n/* maximum loopcount for peephole optimization */\n#define DUK_COMPILER_PEEPHOLE_MAXITER      3\n\n/* maximum bytecode length in instructions */\n#define DUK_COMPILER_MAX_BYTECODE_LENGTH   (256L * 1024L * 1024L)  /* 1 GB */\n\n/*\n *  Compiler intermediate values\n *\n *  Intermediate values describe either plain values (e.g. strings or\n *  numbers) or binary operations which have not yet been coerced into\n *  either a left-hand-side or right-hand-side role (e.g. object property).\n */\n\n#define DUK_IVAL_NONE          0   /* no value */\n#define DUK_IVAL_PLAIN         1   /* register, constant, or value */\n#define DUK_IVAL_ARITH         2   /* binary arithmetic; DUK_OP_ADD, DUK_OP_EQ, other binary ops */\n#define DUK_IVAL_PROP          3   /* property access */\n#define DUK_IVAL_VAR           4   /* variable access */\n\n#define DUK_ISPEC_NONE         0   /* no value */\n#define DUK_ISPEC_VALUE        1   /* value resides in 'valstack_idx' */\n#define DUK_ISPEC_REGCONST     2   /* value resides in a register or constant */\n\n/* Bit mask which indicates that a regconst is a constant instead of a register.\n * Chosen so that when a regconst is cast to duk_int32_t, all consts are\n * negative values.\n */\n#define DUK_REGCONST_CONST_MARKER    DUK_INT32_MIN  /* = -0x80000000 */\n\n/* Type to represent a reg/const reference during compilation, with <0\n * indicating a constant.  Some call sites also use -1 to indicate 'none'.\n */\ntypedef duk_int32_t duk_regconst_t;\n\ntypedef struct {\n\tduk_small_uint_t t;          /* DUK_ISPEC_XXX */\n\tduk_regconst_t regconst;\n\tduk_idx_t valstack_idx;      /* always set; points to a reserved valstack slot */\n} duk_ispec;\n\ntypedef struct {\n\t/*\n\t *  PLAIN: x1\n\t *  ARITH: x1 <op> x2\n\t *  PROP: x1.x2\n\t *  VAR: x1 (name)\n\t */\n\n\t/* XXX: can be optimized for smaller footprint esp. on 32-bit environments */\n\tduk_small_uint_t t;          /* DUK_IVAL_XXX */\n\tduk_small_uint_t op;         /* bytecode opcode for binary ops */\n\tduk_ispec x1;\n\tduk_ispec x2;\n} duk_ivalue;\n\n/*\n *  Bytecode instruction representation during compilation\n *\n *  Contains the actual instruction and (optionally) debug info.\n */\n\nstruct duk_compiler_instr {\n\tduk_instr_t ins;\n#if defined(DUK_USE_PC2LINE)\n\tduk_uint32_t line;\n#endif\n};\n\n/*\n *  Compiler state\n */\n\n#define DUK_LABEL_FLAG_ALLOW_BREAK       (1U << 0)\n#define DUK_LABEL_FLAG_ALLOW_CONTINUE    (1U << 1)\n\n#define DUK_DECL_TYPE_VAR                0\n#define DUK_DECL_TYPE_FUNC               1\n\n/* XXX: optimize to 16 bytes */\ntypedef struct {\n\tduk_small_uint_t flags;\n\tduk_int_t label_id;          /* numeric label_id (-1 reserved as marker) */\n\tduk_hstring *h_label;        /* borrowed label name */\n\tduk_int_t catch_depth;       /* catch depth at point of definition */\n\tduk_int_t pc_label;          /* pc of label statement:\n\t                              * pc+1: break jump site\n\t                              * pc+2: continue jump site\n\t                              */\n\n\t/* Fast jumps (which avoid longjmp) jump directly to the jump sites\n\t * which are always known even while the iteration/switch statement\n\t * is still being parsed.  A final peephole pass \"straightens out\"\n\t * the jumps.\n\t */\n} duk_labelinfo;\n\n/* Compiling state of one function, eventually converted to duk_hcompfunc */\nstruct duk_compiler_func {\n\t/* These pointers are at the start of the struct so that they pack\n\t * nicely.  Mixing pointers and integer values is bad on some\n\t * platforms (e.g. if int is 32 bits and pointers are 64 bits).\n\t */\n\n\tduk_bufwriter_ctx bw_code;          /* bufwriter for code */\n\n\tduk_hstring *h_name;                /* function name (borrowed reference), ends up in _name */\n\t/* h_code: held in bw_code */\n\tduk_hobject *h_consts;              /* array */\n\tduk_hobject *h_funcs;               /* array of function templates: [func1, offset1, line1, func2, offset2, line2]\n\t                                     * offset/line points to closing brace to allow skipping on pass 2\n\t                                     */\n\tduk_hobject *h_decls;               /* array of declarations: [ name1, val1, name2, val2, ... ]\n\t                                     * valN = (typeN) | (fnum << 8), where fnum is inner func number (0 for vars)\n\t                                     * record function and variable declarations in pass 1\n\t                                     */\n\tduk_hobject *h_labelnames;          /* array of active label names */\n\tduk_hbuffer_dynamic *h_labelinfos;  /* C array of duk_labelinfo */\n\tduk_hobject *h_argnames;            /* array of formal argument names (-> _Formals) */\n\tduk_hobject *h_varmap;              /* variable map for pass 2 (identifier -> register number or null (unmapped)) */\n\n\t/* Value stack indices for tracking objects. */\n\t/* code_idx: not needed */\n\tduk_idx_t consts_idx;\n\tduk_idx_t funcs_idx;\n\tduk_idx_t decls_idx;\n\tduk_idx_t labelnames_idx;\n\tduk_idx_t labelinfos_idx;\n\tduk_idx_t argnames_idx;\n\tduk_idx_t varmap_idx;\n\n\t/* Temp reg handling. */\n\tduk_regconst_t temp_first;           /* first register that is a temporary (below: variables) */\n\tduk_regconst_t temp_next;            /* next temporary register to allocate */\n\tduk_regconst_t temp_max;             /* highest value of temp_reg (temp_max - 1 is highest used reg) */\n\n\t/* Shuffle registers if large number of regs/consts. */\n\tduk_regconst_t shuffle1;\n\tduk_regconst_t shuffle2;\n\tduk_regconst_t shuffle3;\n\n\t/* Stats for current expression being parsed. */\n\tduk_int_t nud_count;\n\tduk_int_t led_count;\n\tduk_int_t paren_level;              /* parenthesis count, 0 = top level */\n\tduk_bool_t expr_lhs;                /* expression is left-hand-side compatible */\n\tduk_bool_t allow_in;                /* current paren level allows 'in' token */\n\n\t/* Misc. */\n\tduk_int_t stmt_next;                /* statement id allocation (running counter) */\n\tduk_int_t label_next;               /* label id allocation (running counter) */\n\tduk_int_t catch_depth;              /* catch stack depth */\n\tduk_int_t with_depth;               /* with stack depth (affects identifier lookups) */\n\tduk_int_t fnum_next;                /* inner function numbering */\n\tduk_int_t num_formals;              /* number of formal arguments */\n\tduk_regconst_t reg_stmt_value;      /* register for writing value of 'non-empty' statements (global or eval code), -1 is marker */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_int_t min_line;                 /* XXX: typing (duk_hcompfunc has duk_uint32_t) */\n\tduk_int_t max_line;\n#endif\n\n\t/* Status booleans. */\n\tduk_uint8_t is_function;             /* is an actual function (not global/eval code) */\n\tduk_uint8_t is_eval;                 /* is eval code */\n\tduk_uint8_t is_global;               /* is global code */\n\tduk_uint8_t is_namebinding;          /* needs a name binding */\n\tduk_uint8_t is_constructable;        /* result is constructable */\n\tduk_uint8_t is_setget;               /* is a setter/getter */\n\tduk_uint8_t is_strict;               /* function is strict */\n\tduk_uint8_t is_notail;               /* function must not be tail called */\n\tduk_uint8_t in_directive_prologue;   /* parsing in \"directive prologue\", recognize directives */\n\tduk_uint8_t in_scanning;             /* parsing in \"scanning\" phase (first pass) */\n\tduk_uint8_t may_direct_eval;         /* function may call direct eval */\n\tduk_uint8_t id_access_arguments;     /* function refers to 'arguments' identifier */\n\tduk_uint8_t id_access_slow;          /* function makes one or more slow path accesses that won't match own static variables */\n\tduk_uint8_t id_access_slow_own;      /* function makes one or more slow path accesses that may match own static variables */\n\tduk_uint8_t is_arguments_shadowed;   /* argument/function declaration shadows 'arguments' */\n\tduk_uint8_t needs_shuffle;           /* function needs shuffle registers */\n\tduk_uint8_t reject_regexp_in_adv;    /* reject RegExp literal on next advance() call; needed for handling IdentifierName productions */\n\tduk_uint8_t allow_regexp_in_adv;     /* allow RegExp literal on next advance() call */\n};\n\nstruct duk_compiler_ctx {\n\tduk_hthread *thr;\n\n\t/* filename being compiled (ends up in functions' '_filename' property) */\n\tduk_hstring *h_filename;            /* borrowed reference */\n\n\t/* lexing (tokenization) state (contains two valstack slot indices) */\n\tduk_lexer_ctx lex;\n\n\t/* current and previous token for parsing */\n\tduk_token prev_token;\n\tduk_token curr_token;\n\tduk_idx_t tok11_idx;                /* curr_token slot1 (matches 'lex' slot1_idx) */\n\tduk_idx_t tok12_idx;                /* curr_token slot2 (matches 'lex' slot2_idx) */\n\tduk_idx_t tok21_idx;                /* prev_token slot1 */\n\tduk_idx_t tok22_idx;                /* prev_token slot2 */\n\n\t/* recursion limit */\n\tduk_int_t recursion_depth;\n\tduk_int_t recursion_limit;\n\n\t/* code emission temporary */\n\tduk_int_t emit_jumpslot_pc;\n\n\t/* current function being compiled (embedded instead of pointer for more compact access) */\n\tduk_compiler_func curr_func;\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer, duk_size_t src_length, duk_small_uint_t flags);\n\n#endif  /* DUK_JS_COMPILER_H_INCLUDED */\n/* #include duk_regexp.h */\n#line 1 \"duk_regexp.h\"\n/*\n *  Regular expression structs, constants, and bytecode defines.\n */\n\n#if !defined(DUK_REGEXP_H_INCLUDED)\n#define DUK_REGEXP_H_INCLUDED\n\n/* maximum bytecode copies for {n,m} quantifiers */\n#define DUK_RE_MAX_ATOM_COPIES             1000\n\n/* regexp compilation limits */\n#define DUK_RE_COMPILE_TOKEN_LIMIT         100000000L   /* 1e8 */\n\n/* regexp execution limits */\n#define DUK_RE_EXECUTE_STEPS_LIMIT         1000000000L  /* 1e9 */\n\n/* regexp opcodes */\n#define DUK_REOP_MATCH                     1\n#define DUK_REOP_CHAR                      2\n#define DUK_REOP_PERIOD                    3\n#define DUK_REOP_RANGES                    4\n#define DUK_REOP_INVRANGES                 5\n#define DUK_REOP_JUMP                      6\n#define DUK_REOP_SPLIT1                    7\n#define DUK_REOP_SPLIT2                    8\n#define DUK_REOP_SQMINIMAL                 9\n#define DUK_REOP_SQGREEDY                  10\n#define DUK_REOP_SAVE                      11\n#define DUK_REOP_WIPERANGE                 12\n#define DUK_REOP_LOOKPOS                   13\n#define DUK_REOP_LOOKNEG                   14\n#define DUK_REOP_BACKREFERENCE             15\n#define DUK_REOP_ASSERT_START              16\n#define DUK_REOP_ASSERT_END                17\n#define DUK_REOP_ASSERT_WORD_BOUNDARY      18\n#define DUK_REOP_ASSERT_NOT_WORD_BOUNDARY  19\n\n/* flags */\n#define DUK_RE_FLAG_GLOBAL                 (1U << 0)\n#define DUK_RE_FLAG_IGNORE_CASE            (1U << 1)\n#define DUK_RE_FLAG_MULTILINE              (1U << 2)\n\nstruct duk_re_matcher_ctx {\n\tduk_hthread *thr;\n\n\tduk_uint32_t re_flags;\n\tconst duk_uint8_t *input;\n\tconst duk_uint8_t *input_end;\n\tconst duk_uint8_t *bytecode;\n\tconst duk_uint8_t *bytecode_end;\n\tconst duk_uint8_t **saved;  /* allocated from valstack (fixed buffer) */\n\tduk_uint32_t nsaved;\n\tduk_uint32_t recursion_depth;\n\tduk_uint32_t recursion_limit;\n\tduk_uint32_t steps_count;\n\tduk_uint32_t steps_limit;\n};\n\nstruct duk_re_compiler_ctx {\n\tduk_hthread *thr;\n\n\tduk_uint32_t re_flags;\n\tduk_lexer_ctx lex;\n\tduk_re_token curr_token;\n\tduk_bufwriter_ctx bw;\n\tduk_uint32_t captures;  /* highest capture number emitted so far (used as: ++captures) */\n\tduk_uint32_t highest_backref;\n\tduk_uint32_t recursion_depth;\n\tduk_uint32_t recursion_limit;\n\tduk_uint32_t nranges;  /* internal temporary value, used for char classes */\n};\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL_DECL void duk_regexp_compile(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_regexp_create_instance(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_regexp_match(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_regexp_match_force_global(duk_hthread *thr);  /* hacky helper for String.prototype.split() */\n#endif\n\n#endif  /* DUK_REGEXP_H_INCLUDED */\n/* #include duk_heaphdr.h */\n#line 1 \"duk_heaphdr.h\"\n/*\n *  Heap header definition and assorted macros, including ref counting.\n *  Access all fields through the accessor macros.\n */\n\n#if !defined(DUK_HEAPHDR_H_INCLUDED)\n#define DUK_HEAPHDR_H_INCLUDED\n\n/*\n *  Common heap header\n *\n *  All heap objects share the same flags and refcount fields.  Objects other\n *  than strings also need to have a single or double linked list pointers\n *  for insertion into the \"heap allocated\" list.  Strings have single linked\n *  list pointers for string table chaining.\n *\n *  Technically, 'h_refcount' must be wide enough to guarantee that it cannot\n *  wrap; otherwise objects might be freed incorrectly after wrapping.  The\n *  default refcount field is 32 bits even on 64-bit systems: while that's in\n *  theory incorrect, the Duktape heap needs to be larger than 64GB for the\n *  count to actually wrap (assuming 16-byte duk_tvals).  This is very unlikely\n *  to ever be an issue, but if it is, disabling DUK_USE_REFCOUNT32 causes\n *  Duktape to use size_t for refcounts which should always be safe.\n *\n *  Heap header size on 32-bit platforms: 8 bytes without reference counting,\n *  16 bytes with reference counting.\n *\n *  Note that 'raw' macros such as DUK_HEAPHDR_GET_REFCOUNT() are not\n *  defined without DUK_USE_REFERENCE_COUNTING, so caller must #if defined()\n *  around them.\n */\n\n/* XXX: macro for shared header fields (avoids some padding issues) */\n\nstruct duk_heaphdr {\n\tduk_uint32_t h_flags;\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#if defined(DUK_USE_ASSERTIONS)\n\t/* When assertions enabled, used by mark-and-sweep for refcount\n\t * validation.  Largest reasonable type; also detects overflows.\n\t */\n\tduk_size_t h_assert_refcount;\n#endif\n#if defined(DUK_USE_REFCOUNT16)\n\tduk_uint16_t h_refcount;\n#elif defined(DUK_USE_REFCOUNT32)\n\tduk_uint32_t h_refcount;\n#else\n\tduk_size_t h_refcount;\n#endif\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t h_next16;\n#else\n\tduk_heaphdr *h_next;\n#endif\n\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\t/* refcounting requires direct heap frees, which in turn requires a dual linked heap */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t h_prev16;\n#else\n\tduk_heaphdr *h_prev;\n#endif\n#endif\n\n\t/* When DUK_USE_HEAPPTR16 (and DUK_USE_REFCOUNT16) is in use, the\n\t * struct won't align nicely to 4 bytes.  This 16-bit extra field\n\t * is added to make the alignment clean; the field can be used by\n\t * heap objects when 16-bit packing is used.  This field is now\n\t * conditional to DUK_USE_HEAPPTR16 only, but it is intended to be\n\t * used with DUK_USE_REFCOUNT16 and DUK_USE_DOUBLE_LINKED_HEAP;\n\t * this only matter to low memory environments anyway.\n\t */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t h_extra16;\n#endif\n};\n\nstruct duk_heaphdr_string {\n\t/* 16 bits would be enough for shared heaphdr flags and duk_hstring\n\t * flags.  The initial parts of duk_heaphdr_string and duk_heaphdr\n\t * must match so changing the flags field size here would be quite\n\t * awkward.  However, to minimize struct size, we can pack at least\n\t * 16 bits of duk_hstring data into the flags field.\n\t */\n\tduk_uint32_t h_flags;\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#if defined(DUK_USE_ASSERTIONS)\n\t/* When assertions enabled, used by mark-and-sweep for refcount\n\t * validation.  Largest reasonable type; also detects overflows.\n\t */\n\tduk_size_t h_assert_refcount;\n#endif\n#if defined(DUK_USE_REFCOUNT16)\n\tduk_uint16_t h_refcount;\n\tduk_uint16_t h_strextra16;  /* round out to 8 bytes */\n#elif defined(DUK_USE_REFCOUNT32)\n\tduk_uint32_t h_refcount;\n#else\n\tduk_size_t h_refcount;\n#endif\n#else\n\tduk_uint16_t h_strextra16;\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n\tduk_hstring *h_next;\n\t/* No 'h_prev' pointer for strings. */\n};\n\n#define DUK_HEAPHDR_FLAGS_TYPE_MASK      0x00000003UL\n#define DUK_HEAPHDR_FLAGS_FLAG_MASK      (~DUK_HEAPHDR_FLAGS_TYPE_MASK)\n\n                                             /* 2 bits for heap type */\n#define DUK_HEAPHDR_FLAGS_HEAP_START     2   /* 5 heap flags */\n#define DUK_HEAPHDR_FLAGS_USER_START     7   /* 25 user flags */\n\n#define DUK_HEAPHDR_HEAP_FLAG_NUMBER(n)  (DUK_HEAPHDR_FLAGS_HEAP_START + (n))\n#define DUK_HEAPHDR_USER_FLAG_NUMBER(n)  (DUK_HEAPHDR_FLAGS_USER_START + (n))\n#define DUK_HEAPHDR_HEAP_FLAG(n)         (1UL << (DUK_HEAPHDR_FLAGS_HEAP_START + (n)))\n#define DUK_HEAPHDR_USER_FLAG(n)         (1UL << (DUK_HEAPHDR_FLAGS_USER_START + (n)))\n\n#define DUK_HEAPHDR_FLAG_REACHABLE       DUK_HEAPHDR_HEAP_FLAG(0)  /* mark-and-sweep: reachable */\n#define DUK_HEAPHDR_FLAG_TEMPROOT        DUK_HEAPHDR_HEAP_FLAG(1)  /* mark-and-sweep: children not processed */\n#define DUK_HEAPHDR_FLAG_FINALIZABLE     DUK_HEAPHDR_HEAP_FLAG(2)  /* mark-and-sweep: finalizable (on current pass) */\n#define DUK_HEAPHDR_FLAG_FINALIZED       DUK_HEAPHDR_HEAP_FLAG(3)  /* mark-and-sweep: finalized (on previous pass) */\n#define DUK_HEAPHDR_FLAG_READONLY        DUK_HEAPHDR_HEAP_FLAG(4)  /* read-only object, in code section */\n\n#define DUK_HTYPE_MIN                    0\n#define DUK_HTYPE_STRING                 0\n#define DUK_HTYPE_OBJECT                 1\n#define DUK_HTYPE_BUFFER                 2\n#define DUK_HTYPE_MAX                    2\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HEAPHDR_GET_NEXT(heap,h) \\\n\t((duk_heaphdr *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->h_next16))\n#define DUK_HEAPHDR_SET_NEXT(heap,h,val)   do { \\\n\t\t(h)->h_next16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) val); \\\n\t} while (0)\n#else\n#define DUK_HEAPHDR_GET_NEXT(heap,h)  ((h)->h_next)\n#define DUK_HEAPHDR_SET_NEXT(heap,h,val)   do { \\\n\t\t(h)->h_next = (val); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HEAPHDR_GET_PREV(heap,h) \\\n\t((duk_heaphdr *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->h_prev16))\n#define DUK_HEAPHDR_SET_PREV(heap,h,val)   do { \\\n\t\t(h)->h_prev16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (val)); \\\n\t} while (0)\n#else\n#define DUK_HEAPHDR_GET_PREV(heap,h)       ((h)->h_prev)\n#define DUK_HEAPHDR_SET_PREV(heap,h,val)   do { \\\n\t\t(h)->h_prev = (val); \\\n\t} while (0)\n#endif\n#endif\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_HEAPHDR_GET_REFCOUNT(h)   ((h)->h_refcount)\n#define DUK_HEAPHDR_SET_REFCOUNT(h,val)  do { \\\n\t\t(h)->h_refcount = (val); \\\n\t\tDUK_ASSERT((h)->h_refcount == (val));  /* No truncation. */ \\\n\t} while (0)\n#define DUK_HEAPHDR_PREINC_REFCOUNT(h)  (++(h)->h_refcount)  /* result: updated refcount */\n#define DUK_HEAPHDR_PREDEC_REFCOUNT(h)  (--(h)->h_refcount)  /* result: updated refcount */\n#else\n/* refcount macros not defined without refcounting, caller must #if defined() now */\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/*\n *  Note: type is treated as a field separate from flags, so some masking is\n *  involved in the macros below.\n */\n\n#define DUK_HEAPHDR_GET_FLAGS_RAW(h)  ((h)->h_flags)\n#define DUK_HEAPHDR_SET_FLAGS_RAW(h,val)  do { \\\n\t\t(h)->h_flags = (val); } \\\n\t}\n#define DUK_HEAPHDR_GET_FLAGS(h)      ((h)->h_flags & DUK_HEAPHDR_FLAGS_FLAG_MASK)\n#define DUK_HEAPHDR_SET_FLAGS(h,val)  do { \\\n\t\t(h)->h_flags = ((h)->h_flags & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) | (val); \\\n\t} while (0)\n#define DUK_HEAPHDR_GET_TYPE(h)       ((h)->h_flags & DUK_HEAPHDR_FLAGS_TYPE_MASK)\n#define DUK_HEAPHDR_SET_TYPE(h,val)   do { \\\n\t\t(h)->h_flags = ((h)->h_flags & ~(DUK_HEAPHDR_FLAGS_TYPE_MASK)) | (val); \\\n\t} while (0)\n\n/* Comparison for type >= DUK_HTYPE_MIN skipped; because DUK_HTYPE_MIN is zero\n * and the comparison is unsigned, it's always true and generates warnings.\n */\n#define DUK_HEAPHDR_HTYPE_VALID(h)    ( \\\n\tDUK_HEAPHDR_GET_TYPE((h)) <= DUK_HTYPE_MAX \\\n\t)\n\n#define DUK_HEAPHDR_SET_TYPE_AND_FLAGS(h,tval,fval)  do { \\\n\t\t(h)->h_flags = ((tval) & DUK_HEAPHDR_FLAGS_TYPE_MASK) | \\\n\t\t               ((fval) & DUK_HEAPHDR_FLAGS_FLAG_MASK); \\\n\t} while (0)\n\n#define DUK_HEAPHDR_SET_FLAG_BITS(h,bits)  do { \\\n\t\tDUK_ASSERT(((bits) & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) == 0); \\\n\t\t(h)->h_flags |= (bits); \\\n\t} while (0)\n\n#define DUK_HEAPHDR_CLEAR_FLAG_BITS(h,bits)  do { \\\n\t\tDUK_ASSERT(((bits) & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) == 0); \\\n\t\t(h)->h_flags &= ~((bits)); \\\n\t} while (0)\n\n#define DUK_HEAPHDR_CHECK_FLAG_BITS(h,bits)  (((h)->h_flags & (bits)) != 0)\n\n#define DUK_HEAPHDR_SET_REACHABLE(h)      DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_REACHABLE)\n#define DUK_HEAPHDR_CLEAR_REACHABLE(h)    DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_REACHABLE)\n#define DUK_HEAPHDR_HAS_REACHABLE(h)      DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_REACHABLE)\n\n#define DUK_HEAPHDR_SET_TEMPROOT(h)       DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_TEMPROOT)\n#define DUK_HEAPHDR_CLEAR_TEMPROOT(h)     DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_TEMPROOT)\n#define DUK_HEAPHDR_HAS_TEMPROOT(h)       DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_TEMPROOT)\n\n#define DUK_HEAPHDR_SET_FINALIZABLE(h)    DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZABLE)\n#define DUK_HEAPHDR_CLEAR_FINALIZABLE(h)  DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZABLE)\n#define DUK_HEAPHDR_HAS_FINALIZABLE(h)    DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZABLE)\n\n#define DUK_HEAPHDR_SET_FINALIZED(h)      DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZED)\n#define DUK_HEAPHDR_CLEAR_FINALIZED(h)    DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZED)\n#define DUK_HEAPHDR_HAS_FINALIZED(h)      DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZED)\n\n#define DUK_HEAPHDR_SET_READONLY(h)       DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_READONLY)\n#define DUK_HEAPHDR_CLEAR_READONLY(h)     DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_READONLY)\n#define DUK_HEAPHDR_HAS_READONLY(h)       DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_READONLY)\n\n/* get or set a range of flags; m=first bit number, n=number of bits */\n#define DUK_HEAPHDR_GET_FLAG_RANGE(h,m,n)  (((h)->h_flags >> (m)) & ((1UL << (n)) - 1UL))\n\n#define DUK_HEAPHDR_SET_FLAG_RANGE(h,m,n,v)  do { \\\n\t\t(h)->h_flags = \\\n\t\t\t((h)->h_flags & (~(((1UL << (n)) - 1UL) << (m)))) \\\n\t\t\t| ((v) << (m)); \\\n\t} while (0)\n\n/* init pointer fields to null */\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n#define DUK_HEAPHDR_INIT_NULLS(h)       do { \\\n\t\tDUK_HEAPHDR_SET_NEXT((h), (void *) NULL); \\\n\t\tDUK_HEAPHDR_SET_PREV((h), (void *) NULL); \\\n\t} while (0)\n#else\n#define DUK_HEAPHDR_INIT_NULLS(h)       do { \\\n\t\tDUK_HEAPHDR_SET_NEXT((h), (void *) NULL); \\\n\t} while (0)\n#endif\n\n#define DUK_HEAPHDR_STRING_INIT_NULLS(h)  do { \\\n\t\t(h)->h_next = NULL; \\\n\t} while (0)\n\n/*\n *  Type tests\n */\n\n/* Take advantage of the fact that for DUK_HTYPE_xxx numbers the lowest bit\n * is only set for DUK_HTYPE_OBJECT (= 1).\n */\n#if 0\n#define DUK_HEAPHDR_IS_OBJECT(h) (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_OBJECT)\n#endif\n#define DUK_HEAPHDR_IS_OBJECT(h) ((h)->h_flags & 0x01UL)\n#define DUK_HEAPHDR_IS_STRING(h) (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_STRING)\n#define DUK_HEAPHDR_IS_BUFFER(h) (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_BUFFER)\n\n/*\n *  Assert helpers\n */\n\n/* Check that prev/next links are consistent: if e.g. h->prev is != NULL,\n * h->prev->next should point back to h.\n */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_heaphdr_assert_valid_subclassed(duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_assert_valid(duk_heaphdr *h);\n#define DUK_HEAPHDR_ASSERT_LINKS(heap,h)  do { duk_heaphdr_assert_links((heap), (h)); } while (0)\n#define DUK_HEAPHDR_ASSERT_VALID(h)  do { duk_heaphdr_assert_valid((h)); } while (0)\n#else\n#define DUK_HEAPHDR_ASSERT_LINKS(heap,h)  do {} while (0)\n#define DUK_HEAPHDR_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n#endif  /* DUK_HEAPHDR_H_INCLUDED */\n/* #include duk_refcount.h */\n#line 1 \"duk_refcount.h\"\n/*\n *  Reference counting helper macros.  The macros take a thread argument\n *  and must thus always be executed in a specific thread context.  The\n *  thread argument is not really needed anymore: DECREF can operate with\n *  a heap pointer only, and INCREF needs neither.\n */\n\n#if !defined(DUK_REFCOUNT_H_INCLUDED)\n#define DUK_REFCOUNT_H_INCLUDED\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\n#if defined(DUK_USE_ROM_OBJECTS)\n/* With ROM objects \"needs refcount update\" is true when the value is\n * heap allocated and is not a ROM object.\n */\n/* XXX: double evaluation for 'tv' argument. */\n#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv) \\\n\t(DUK_TVAL_IS_HEAP_ALLOCATED((tv)) && !DUK_HEAPHDR_HAS_READONLY(DUK_TVAL_GET_HEAPHDR((tv))))\n#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h)  (!DUK_HEAPHDR_HAS_READONLY((h)))\n#else  /* DUK_USE_ROM_OBJECTS */\n/* Without ROM objects \"needs refcount update\" == is heap allocated. */\n#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)    DUK_TVAL_IS_HEAP_ALLOCATED((tv))\n#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h)  1\n#endif  /* DUK_USE_ROM_OBJECTS */\n\n/* Fast variants, inline refcount operations except for refzero handling.\n * Can be used explicitly when speed is always more important than size.\n * For a good compiler and a single file build, these are basically the\n * same as a forced inline.\n */\n#define DUK_TVAL_INCREF_FAST(thr,tv) do { \\\n\t\tduk_tval *duk__tv = (tv); \\\n\t\tDUK_ASSERT(duk__tv != NULL); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \\\n\t\t\tduk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \\\n\t\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(duk__h); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) != 0);  /* No wrapping. */ \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_DECREF_FAST(thr,tv) do { \\\n\t\tduk_tval *duk__tv = (tv); \\\n\t\tDUK_ASSERT(duk__tv != NULL); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \\\n\t\t\tduk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \\\n\t\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \\\n\t\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \\\n\t\t\t\tduk_heaphdr_refzero((thr), duk__h); \\\n\t\t\t} \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_DECREF_NORZ_FAST(thr,tv) do { \\\n\t\tduk_tval *duk__tv = (tv); \\\n\t\tDUK_ASSERT(duk__tv != NULL); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \\\n\t\t\tduk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \\\n\t\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \\\n\t\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \\\n\t\t\t\tduk_heaphdr_refzero_norz((thr), duk__h); \\\n\t\t\t} \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_INCREF_FAST(thr,h) do { \\\n\t\tduk_heaphdr *duk__h = (duk_heaphdr *) (h); \\\n\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\tif (DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(duk__h)) { \\\n\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(duk__h); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) != 0);  /* No wrapping. */ \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_FAST_RAW(thr,h,rzcall,rzcast) do { \\\n\t\tduk_heaphdr *duk__h = (duk_heaphdr *) (h); \\\n\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \\\n\t\tif (DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(duk__h)) { \\\n\t\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \\\n\t\t\t\t(rzcall)((thr), (rzcast) duk__h); \\\n\t\t\t} \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_FAST(thr,h) \\\n\tDUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero,duk_heaphdr *)\n#define DUK_HEAPHDR_DECREF_NORZ_FAST(thr,h) \\\n\tDUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero_norz,duk_heaphdr *)\n\n/* Slow variants, call to a helper to reduce code size.\n * Can be used explicitly when size is always more important than speed.\n */\n#define DUK_TVAL_INCREF_SLOW(thr,tv)         do { duk_tval_incref((tv)); } while (0)\n#define DUK_TVAL_DECREF_SLOW(thr,tv)         do { duk_tval_decref((thr), (tv)); } while (0)\n#define DUK_TVAL_DECREF_NORZ_SLOW(thr,tv)    do { duk_tval_decref_norz((thr), (tv)); } while (0)\n#define DUK_HEAPHDR_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HEAPHDR_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HSTRING_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HSTRING_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HSTRING_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HBUFFER_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HBUFFER_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HBUFFER_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HOBJECT_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HOBJECT_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HOBJECT_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n\n/* Default variants.  Selection depends on speed/size preference.\n * Concretely: with gcc 4.8.1 -Os x64 the difference in final binary\n * is about +1kB for _FAST variants.\n */\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n/* XXX: It would be nice to specialize for specific duk_hobject subtypes\n * but current refzero queue handling prevents that.\n */\n#define DUK_TVAL_INCREF(thr,tv)                DUK_TVAL_INCREF_FAST((thr),(tv))\n#define DUK_TVAL_DECREF(thr,tv)                DUK_TVAL_DECREF_FAST((thr),(tv))\n#define DUK_TVAL_DECREF_NORZ(thr,tv)           DUK_TVAL_DECREF_NORZ_FAST((thr),(tv))\n#define DUK_HEAPHDR_INCREF(thr,h)              DUK_HEAPHDR_INCREF_FAST((thr),(h))\n#define DUK_HEAPHDR_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero,duk_heaphdr *)\n#define DUK_HEAPHDR_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero_norz,duk_heaphdr *)\n#define DUK_HSTRING_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HSTRING_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hstring_refzero,duk_hstring *)\n#define DUK_HSTRING_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hstring_refzero,duk_hstring *)  /* no 'norz' variant */\n#define DUK_HOBJECT_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HOBJECT_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HOBJECT_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HBUFFER_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HBUFFER_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hbuffer_refzero,duk_hbuffer *)\n#define DUK_HBUFFER_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hbuffer_refzero,duk_hbuffer *)  /* no 'norz' variant */\n#define DUK_HCOMPFUNC_INCREF(thr,h)            DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HCOMPFUNC_DECREF(thr,h)            DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h)       DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HNATFUNC_INCREF(thr,h)             DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HNATFUNC_DECREF(thr,h)             DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HNATFUNC_DECREF_NORZ(thr,h)        DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HBUFOBJ_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HBUFOBJ_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HBUFOBJ_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HTHREAD_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HTHREAD_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HTHREAD_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#else\n#define DUK_TVAL_INCREF(thr,tv)                DUK_TVAL_INCREF_SLOW((thr),(tv))\n#define DUK_TVAL_DECREF(thr,tv)                DUK_TVAL_DECREF_SLOW((thr),(tv))\n#define DUK_TVAL_DECREF_NORZ(thr,tv)           DUK_TVAL_DECREF_NORZ_SLOW((thr),(tv))\n#define DUK_HEAPHDR_INCREF(thr,h)              DUK_HEAPHDR_INCREF_SLOW((thr),(h))\n#define DUK_HEAPHDR_DECREF(thr,h)              DUK_HEAPHDR_DECREF_SLOW((thr),(h))\n#define DUK_HEAPHDR_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HSTRING_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HSTRING_DECREF(thr,h)              DUK_HSTRING_DECREF_SLOW((thr),(h))\n#define DUK_HSTRING_DECREF_NORZ(thr,h)         DUK_HSTRING_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HOBJECT_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HOBJECT_DECREF(thr,h)              DUK_HOBJECT_DECREF_SLOW((thr),(h))\n#define DUK_HOBJECT_DECREF_NORZ(thr,h)         DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HBUFFER_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HBUFFER_DECREF(thr,h)              DUK_HBUFFER_DECREF_SLOW((thr),(h))\n#define DUK_HBUFFER_DECREF_NORZ(thr,h)         DUK_HBUFFER_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HCOMPFUNC_INCREF(thr,h)            DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HCOMPFUNC_DECREF(thr,h)            DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h)       DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HNATFUNC_INCREF(thr,h)             DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HNATFUNC_DECREF(thr,h)             DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HNATFUNC_DECREF_NORZ(thr,h)        DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HBUFOBJ_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HBUFOBJ_DECREF(thr,h)              DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HBUFOB_DECREF_NORZ(thr,h)          DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HTHREAD_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HTHREAD_DECREF(thr,h)              DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HTHREAD_DECREF_NORZ(thr,h)         DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#endif\n\n/* Convenience for some situations; the above macros don't allow NULLs\n * for performance reasons.  Macros cover only actually needed cases.\n */\n#define DUK_HEAPHDR_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HEAPHDR_DECREF((thr), (duk_heaphdr *) (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HEAPHDR_DECREF_NORZ((thr), (duk_heaphdr *) (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HOBJECT_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HOBJECT_INCREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HOBJECT_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HOBJECT_DECREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HOBJECT_DECREF_NORZ((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HBUFFER_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HBUFFER_INCREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HBUFFER_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HBUFFER_DECREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HBUFFER_DECREF_NORZ((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HTHREAD_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HTHREAD_INCREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HTHREAD_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HTHREAD_DECREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HTHREAD_DECREF_NORZ((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n\n/* Called after one or more DECREF NORZ calls to handle pending side effects.\n * At present DECREF NORZ does freeing inline but doesn't execute finalizers,\n * so these macros check for pending finalizers and execute them.  The FAST\n * variant is performance critical.\n */\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n#define DUK_REFZERO_CHECK_FAST(thr) do { \\\n\t\tduk_refzero_check_fast((thr)); \\\n\t} while (0)\n#define DUK_REFZERO_CHECK_SLOW(thr) do { \\\n\t\tduk_refzero_check_slow((thr)); \\\n\t} while (0)\n#else  /* DUK_USE_FINALIZER_SUPPORT */\n#define DUK_REFZERO_CHECK_FAST(thr) do { } while (0)\n#define DUK_REFZERO_CHECK_SLOW(thr) do { } while (0)\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Macros to set a duk_tval and update refcount of the target (decref the\n *  old value and incref the new value if necessary).  This is both performance\n *  and footprint critical; any changes made should be measured for size/speed.\n */\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_UNDEFINED(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_UNDEFINED(tv__dst); \\\n\t\tDUK_TVAL_DECREF_NORZ((thr), &tv__tmp); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_UNUSED(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NULL_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NULL(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_BOOLEAN(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NUMBER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NUMBER(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_DOUBLE(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_NAN_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NAN(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_I48(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_I32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_I32(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_U32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_U32(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#else\n#define DUK_TVAL_SET_DOUBLE_CAST_UPDREF(thr,tvptr_dst,newval) \\\n\tDUK_TVAL_SET_DOUBLE_UPDREF((thr), (tvptr_dst), (duk_double_t) (newval))\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0(thr,tvptr_dst,lf_v,lf_fp,lf_flags) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_LIGHTFUNC(tv__dst, (lf_v), (lf_fp), (lf_flags)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_STRING_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_STRING(tv__dst, (newval)); \\\n\t\tDUK_HSTRING_INCREF((thr), (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_OBJECT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_OBJECT(tv__dst, (newval)); \\\n\t\tDUK_HOBJECT_INCREF((thr), (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BUFFER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_BUFFER(tv__dst, (newval)); \\\n\t\tDUK_HBUFFER_INCREF((thr), (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_POINTER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_POINTER(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n/* DUK_TVAL_SET_TVAL_UPDREF() is used a lot in executor, property lookups,\n * etc, so it's very important for performance.  Measure when changing.\n *\n * NOTE: the source and destination duk_tval pointers may be the same, and\n * the macros MUST deal with that correctly.\n */\n\n/* Original idiom used, minimal code size. */\n#define DUK_TVAL_SET_TVAL_UPDREF_ALT0(thr,tvptr_dst,tvptr_src) do { \\\n\t\tduk_tval *tv__dst, *tv__src; duk_tval tv__tmp; \\\n\t\ttv__dst = (tvptr_dst); tv__src = (tvptr_src); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\tDUK_TVAL_INCREF((thr), tv__src); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n/* Faster alternative: avoid making a temporary copy of tvptr_dst and use\n * fast incref/decref macros.\n */\n#define DUK_TVAL_SET_TVAL_UPDREF_ALT1(thr,tvptr_dst,tvptr_src) do { \\\n\t\tduk_tval *tv__dst, *tv__src; duk_heaphdr *h__obj; \\\n\t\ttv__dst = (tvptr_dst); tv__src = (tvptr_src); \\\n\t\tDUK_TVAL_INCREF_FAST((thr), tv__src); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv__dst)) { \\\n\t\t\th__obj = DUK_TVAL_GET_HEAPHDR(tv__dst); \\\n\t\t\tDUK_ASSERT(h__obj != NULL); \\\n\t\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\t\tDUK_HEAPHDR_DECREF_FAST((thr), h__obj);  /* side effects */ \\\n\t\t} else { \\\n\t\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\t} \\\n\t} while (0)\n\n/* XXX: no optimized variants yet */\n#define DUK_TVAL_SET_UNDEFINED_UPDREF         DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ    DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0\n#define DUK_TVAL_SET_UNUSED_UPDREF            DUK_TVAL_SET_UNUSED_UPDREF_ALT0\n#define DUK_TVAL_SET_NULL_UPDREF              DUK_TVAL_SET_NULL_UPDREF_ALT0\n#define DUK_TVAL_SET_BOOLEAN_UPDREF           DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_UPDREF            DUK_TVAL_SET_NUMBER_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF    DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0\n#define DUK_TVAL_SET_DOUBLE_UPDREF            DUK_TVAL_SET_DOUBLE_UPDREF_ALT0\n#define DUK_TVAL_SET_NAN_UPDREF               DUK_TVAL_SET_NAN_UPDREF_ALT0\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_I48_UPDREF_ALT0\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_I32_UPDREF_ALT0\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_U32_UPDREF_ALT0\n#else\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF  /* XXX: fast int-to-double */\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_FASTINT_UPDREF           DUK_TVAL_SET_I48_UPDREF  /* convenience */\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF         DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0\n#define DUK_TVAL_SET_STRING_UPDREF            DUK_TVAL_SET_STRING_UPDREF_ALT0\n#define DUK_TVAL_SET_OBJECT_UPDREF            DUK_TVAL_SET_OBJECT_UPDREF_ALT0\n#define DUK_TVAL_SET_BUFFER_UPDREF            DUK_TVAL_SET_BUFFER_UPDREF_ALT0\n#define DUK_TVAL_SET_POINTER_UPDREF           DUK_TVAL_SET_POINTER_UPDREF_ALT0\n\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n/* Optimized for speed. */\n#define DUK_TVAL_SET_TVAL_UPDREF              DUK_TVAL_SET_TVAL_UPDREF_ALT1\n#define DUK_TVAL_SET_TVAL_UPDREF_FAST         DUK_TVAL_SET_TVAL_UPDREF_ALT1\n#define DUK_TVAL_SET_TVAL_UPDREF_SLOW         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#else\n/* Optimized for size. */\n#define DUK_TVAL_SET_TVAL_UPDREF              DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_FAST         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_SLOW         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#endif\n\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\n#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)     0\n#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h)   0\n\n#define DUK_TVAL_INCREF_FAST(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_FAST(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_NORZ_FAST(thr,v)       do {} while (0) /* nop */\n#define DUK_TVAL_INCREF_SLOW(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_SLOW(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_NORZ_SLOW(thr,v)       do {} while (0) /* nop */\n#define DUK_TVAL_INCREF(thr,v)                 do {} while (0) /* nop */\n#define DUK_TVAL_DECREF(thr,v)                 do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_NORZ(thr,v)            do {} while (0) /* nop */\n#define DUK_HEAPHDR_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HEAPHDR_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HEAPHDR_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HSTRING_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HSTRING_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n\n#define DUK_HCOMPFUNC_INCREF(thr,h)            do {} while (0) /* nop */\n#define DUK_HCOMPFUNC_DECREF(thr,h)            do {} while (0) /* nop */\n#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h)       do {} while (0) /* nop */\n#define DUK_HNATFUNC_INCREF(thr,h)             do {} while (0) /* nop */\n#define DUK_HNATFUNC_DECREF(thr,h)             do {} while (0) /* nop */\n#define DUK_HNATFUNC_DECREF_NORZ(thr,h)        do {} while (0) /* nop */\n#define DUK_HBUFOBJ_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFOBJ_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFOBJ_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HTHREAD_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HTHREAD_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HTHREAD_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr,h)  do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr,h)  do {} while (0) /* nop */\n\n#define DUK_REFZERO_CHECK_FAST(thr)            do {} while (0) /* nop */\n#define DUK_REFZERO_CHECK_SLOW(thr)            do {} while (0) /* nop */\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_UNDEFINED(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_UNUSED(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NULL_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NULL(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_BOOLEAN(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NUMBER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NUMBER(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_DOUBLE(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_NAN_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NAN(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_I48(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_I32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_I32(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_U32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_U32(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#else\n#define DUK_TVAL_SET_DOUBLE_CAST_UPDREF(thr,tvptr_dst,newval) \\\n\tDUK_TVAL_SET_DOUBLE_UPDREF((thr), (tvptr_dst), (duk_double_t) (newval))\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0(thr,tvptr_dst,lf_v,lf_fp,lf_flags) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_LIGHTFUNC(tv__dst, (lf_v), (lf_fp), (lf_flags)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_STRING_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_STRING(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_OBJECT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_OBJECT(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BUFFER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_BUFFER(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_POINTER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_POINTER(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_TVAL_UPDREF_ALT0(thr,tvptr_dst,tvptr_src) do { \\\n\t\tduk_tval *tv__dst, *tv__src; \\\n\t\ttv__dst = (tvptr_dst); tv__src = (tvptr_src); \\\n\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF         DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ    DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0\n#define DUK_TVAL_SET_UNUSED_UPDREF            DUK_TVAL_SET_UNUSED_UPDREF_ALT0\n#define DUK_TVAL_SET_NULL_UPDREF              DUK_TVAL_SET_NULL_UPDREF_ALT0\n#define DUK_TVAL_SET_BOOLEAN_UPDREF           DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_UPDREF            DUK_TVAL_SET_NUMBER_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF    DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0\n#define DUK_TVAL_SET_DOUBLE_UPDREF            DUK_TVAL_SET_DOUBLE_UPDREF_ALT0\n#define DUK_TVAL_SET_NAN_UPDREF               DUK_TVAL_SET_NAN_UPDREF_ALT0\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_I48_UPDREF_ALT0\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_I32_UPDREF_ALT0\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_U32_UPDREF_ALT0\n#else\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF  /* XXX: fast-int-to-double */\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_FASTINT_UPDREF           DUK_TVAL_SET_I48_UPDREF  /* convenience */\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF         DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0\n#define DUK_TVAL_SET_STRING_UPDREF            DUK_TVAL_SET_STRING_UPDREF_ALT0\n#define DUK_TVAL_SET_OBJECT_UPDREF            DUK_TVAL_SET_OBJECT_UPDREF_ALT0\n#define DUK_TVAL_SET_BUFFER_UPDREF            DUK_TVAL_SET_BUFFER_UPDREF_ALT0\n#define DUK_TVAL_SET_POINTER_UPDREF           DUK_TVAL_SET_POINTER_UPDREF_ALT0\n\n#define DUK_TVAL_SET_TVAL_UPDREF              DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_FAST         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_SLOW         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/*\n *  Some convenience macros that don't have optimized implementations now.\n */\n\n#define DUK_TVAL_SET_TVAL_UPDREF_NORZ(thr,tv_dst,tv_src) do { \\\n\t\tduk_hthread *duk__thr = (thr); \\\n\t\tduk_tval *duk__dst = (tv_dst); \\\n\t\tduk_tval *duk__src = (tv_src); \\\n\t\tDUK_UNREF(duk__thr); \\\n\t\tDUK_TVAL_DECREF_NORZ(thr, duk__dst); \\\n\t\tDUK_TVAL_SET_TVAL(duk__dst, duk__src); \\\n\t\tDUK_TVAL_INCREF(thr, duk__dst); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_U32_UPDREF_NORZ(thr,tv_dst,val) do { \\\n\t\tduk_hthread *duk__thr = (thr); \\\n\t\tduk_tval *duk__dst = (tv_dst); \\\n\t\tduk_uint32_t duk__val = (duk_uint32_t) (val); \\\n\t\tDUK_UNREF(duk__thr); \\\n\t\tDUK_TVAL_DECREF_NORZ(thr, duk__dst); \\\n\t\tDUK_TVAL_SET_U32(duk__dst, duk__val); \\\n\t} while (0)\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL_DECL void duk_refzero_check_slow(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_refzero_check_fast(duk_hthread *thr);\n#endif\nDUK_INTERNAL_DECL void duk_heaphdr_refcount_finalize_norz(duk_heap *heap, duk_heaphdr *hdr);\nDUK_INTERNAL_DECL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject *h);\n#if 0  /* Not needed: fast path handles inline; slow path uses duk_heaphdr_decref() which is needed anyway. */\nDUK_INTERNAL_DECL void duk_hstring_decref(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_hstring_decref_norz(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_hbuffer_decref(duk_hthread *thr, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_hbuffer_decref_norz(duk_hthread *thr, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_hobject_decref(duk_hthread *thr, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_hobject_decref_norz(duk_hthread *thr, duk_hobject *h);\n#endif\nDUK_INTERNAL_DECL void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_refzero_norz(duk_hthread *thr, duk_heaphdr *h);\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\nDUK_INTERNAL_DECL void duk_hstring_refzero(duk_hthread *thr, duk_hstring *h);  /* no 'norz' variant */\nDUK_INTERNAL_DECL void duk_hbuffer_refzero(duk_hthread *thr, duk_hbuffer *h);  /* no 'norz' variant */\nDUK_INTERNAL_DECL void duk_hobject_refzero(duk_hthread *thr, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_hobject_refzero_norz(duk_hthread *thr, duk_hobject *h);\n#else\nDUK_INTERNAL_DECL void duk_tval_incref(duk_tval *tv);\nDUK_INTERNAL_DECL void duk_tval_decref(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL void duk_tval_decref_norz(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL void duk_heaphdr_incref(duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h);\n#endif\n#else  /* DUK_USE_REFERENCE_COUNTING */\n/* no refcounting */\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#endif  /* DUK_REFCOUNT_H_INCLUDED */\n/* #include duk_api_internal.h */\n#line 1 \"duk_api_internal.h\"\n/*\n *  Internal API calls which have (stack and other) semantics similar\n *  to the public API.\n */\n\n#if !defined(DUK_API_INTERNAL_H_INCLUDED)\n#define DUK_API_INTERNAL_H_INCLUDED\n\n/* duk_push_sprintf constants */\n#define DUK_PUSH_SPRINTF_INITIAL_SIZE  256L\n#define DUK_PUSH_SPRINTF_SANITY_LIMIT  (1L * 1024L * 1024L * 1024L)\n\n/* Flag ORed to err_code to indicate __FILE__ / __LINE__ is not\n * blamed as source of error for error fileName / lineNumber.\n */\n#define DUK_ERRCODE_FLAG_NOBLAME_FILELINE  (1L << 24)\n\n/* Current convention is to use duk_size_t for value stack sizes and global indices,\n * and duk_idx_t for local frame indices.\n */\nDUK_INTERNAL_DECL void duk_valstack_grow_check_throw(duk_hthread *thr, duk_size_t min_bytes);\nDUK_INTERNAL_DECL duk_bool_t duk_valstack_grow_check_nothrow(duk_hthread *thr, duk_size_t min_bytes);\nDUK_INTERNAL_DECL void duk_valstack_shrink_check_nothrow(duk_hthread *thr, duk_bool_t snug);\n\nDUK_INTERNAL_DECL void duk_copy_tvals_incref(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_size_t count);\n\nDUK_INTERNAL_DECL duk_tval *duk_reserve_gap(duk_hthread *thr, duk_idx_t idx_base, duk_idx_t count);\n\nDUK_INTERNAL_DECL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_set_top_and_wipe(duk_hthread *thr, duk_idx_t top, duk_idx_t idx_wipe_start);\n\nDUK_INTERNAL_DECL void duk_dup_0(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_1(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_2(duk_hthread *thr);\n/* duk_dup_m1() would be same as duk_dup_top() */\nDUK_INTERNAL_DECL void duk_dup_m2(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_m3(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_m4(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_remove_unsafe(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_remove_m2(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_remove_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count);\nDUK_INTERNAL_DECL void duk_remove_n_unsafe(duk_hthread *thr, duk_idx_t idx, duk_idx_t count);\n\nDUK_INTERNAL_DECL duk_int_t duk_get_type_tval(duk_tval *tv);\nDUK_INTERNAL_DECL duk_uint_t duk_get_type_mask_tval(duk_tval *tv);\n\n#if defined(DUK_USE_VERBOSE_ERRORS) && defined(DUK_USE_PARANOID_ERRORS)\nDUK_INTERNAL_DECL const char *duk_get_type_name(duk_hthread *thr, duk_idx_t idx);\n#endif\nDUK_INTERNAL_DECL duk_small_uint_t duk_get_class_number(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_tval *duk_get_tval(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_tval *duk_get_tval_or_unused(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_tval *duk_require_tval(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_push_tval(duk_hthread *thr, duk_tval *tv);\n\n/* Push the current 'this' binding; throw TypeError if binding is not object\n * coercible (CheckObjectCoercible).\n */\nDUK_INTERNAL_DECL void duk_push_this_check_object_coercible(duk_hthread *thr);\n\n/* duk_push_this() + CheckObjectCoercible() + duk_to_object() */\nDUK_INTERNAL_DECL duk_hobject *duk_push_this_coercible_to_object(duk_hthread *thr);\n\n/* duk_push_this() + CheckObjectCoercible() + duk_to_string() */\nDUK_INTERNAL_DECL duk_hstring *duk_push_this_coercible_to_string(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_hstring *duk_push_uint_to_hstring(duk_hthread *thr, duk_uint_t i);\n\n/* Get a borrowed duk_tval pointer to the current 'this' binding.  Caller must\n * make sure there's an active callstack entry.  Note that the returned pointer\n * is unstable with regards to side effects.\n */\nDUK_INTERNAL_DECL duk_tval *duk_get_borrowed_this_tval(duk_hthread *thr);\n\n/* XXX: add fastint support? */\n#define duk_push_u64(thr,val) \\\n\tduk_push_number((thr), (duk_double_t) (val))\n#define duk_push_i64(thr,val) \\\n\tduk_push_number((thr), (duk_double_t) (val))\n\n/* duk_push_(u)int() is guaranteed to support at least (un)signed 32-bit range */\n#define duk_push_u32(thr,val) \\\n\tduk_push_uint((thr), (duk_uint_t) (val))\n#define duk_push_i32(thr,val) \\\n\tduk_push_int((thr), (duk_int_t) (val))\n\n/* sometimes stack and array indices need to go on the stack */\n#define duk_push_idx(thr,val) \\\n\tduk_push_int((thr), (duk_int_t) (val))\n#define duk_push_uarridx(thr,val) \\\n\tduk_push_uint((thr), (duk_uint_t) (val))\n#define duk_push_size_t(thr,val) \\\n\tduk_push_uint((thr), (duk_uint_t) (val))  /* XXX: assumed to fit for now */\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_string_notsymbol(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_callable_tval(duk_hthread *thr, duk_tval *tv);\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_bare_object(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hstring *duk_get_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hstring *duk_get_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL const char *duk_get_string_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hobject *duk_get_hobject(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hbuffer *duk_get_hbuffer(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hthread *duk_get_hthread(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_get_hcompfunc(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_get_hnatfunc(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL void *duk_get_buffer_data_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len, duk_bool_t throw_flag, duk_bool_t *out_isbuffer);\n\nDUK_INTERNAL_DECL duk_hobject *duk_get_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum);\n\nDUK_INTERNAL_DECL duk_hobject *duk_get_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask);\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask);\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject_accept_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask);\n#define duk_require_hobject_promote_lfunc(thr,idx) \\\n\tduk_require_hobject_promote_mask((thr), (idx), DUK_TYPE_MASK_LIGHTFUNC)\n#define duk_get_hobject_promote_lfunc(thr,idx) \\\n\tduk_get_hobject_promote_mask((thr), (idx), DUK_TYPE_MASK_LIGHTFUNC)\n\n#if 0  /*unused*/\nDUK_INTERNAL_DECL void *duk_get_voidptr(duk_hthread *thr, duk_idx_t idx);\n#endif\n\nDUK_INTERNAL_DECL duk_hstring *duk_known_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hobject *duk_known_hobject(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hbuffer *duk_known_hbuffer(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_known_hcompfunc(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_known_hnatfunc(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_double_t duk_to_number_tval(duk_hthread *thr, duk_tval *tv);\n\nDUK_INTERNAL_DECL duk_hstring *duk_to_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hstring *duk_to_hstring_m1(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_hstring *duk_to_hstring_acceptsymbol(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hobject *duk_to_hobject(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_double_t duk_to_number_m1(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_double_t duk_to_number_m2(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_bool_t duk_to_boolean_top_pop(duk_hthread *thr);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* only needed by debugger for now */\nDUK_INTERNAL_DECL duk_hstring *duk_safe_to_hstring(duk_hthread *thr, duk_idx_t idx);\n#endif\nDUK_INTERNAL_DECL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects);\n\nDUK_INTERNAL_DECL duk_int_t duk_to_int_clamped_raw(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped);  /* out_clamped=NULL, RangeError if outside range */\nDUK_INTERNAL_DECL duk_int_t duk_to_int_clamped(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval);\nDUK_INTERNAL_DECL duk_int_t duk_to_int_check_range(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL_DECL duk_uint8_t duk_to_uint8clamped(duk_hthread *thr, duk_idx_t idx);\n#endif\nDUK_INTERNAL_DECL duk_hstring *duk_to_property_key_hstring(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hstring *duk_require_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hstring *duk_require_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL const char *duk_require_lstring_notsymbol(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len);\nDUK_INTERNAL_DECL const char *duk_require_string_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hbuffer *duk_require_hbuffer(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hthread *duk_require_hthread(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_require_hcompfunc(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_require_hnatfunc(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum);\n\nDUK_INTERNAL_DECL void duk_push_hstring(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_push_hstring_stridx(duk_hthread *thr, duk_small_uint_t stridx);\nDUK_INTERNAL_DECL void duk_push_hstring_empty(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_push_hobject(duk_hthread *thr, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_push_hbuffer(duk_hthread *thr, duk_hbuffer *h);\n#define duk_push_hthread(thr,h) \\\n\tduk_push_hobject((thr), (duk_hobject *) (h))\n#define duk_push_hnatfunc(thr,h) \\\n\tduk_push_hobject((thr), (duk_hobject *) (h))\nDUK_INTERNAL_DECL void duk_push_hobject_bidx(duk_hthread *thr, duk_small_int_t builtin_idx);\nDUK_INTERNAL_DECL duk_hobject *duk_push_object_helper(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx);\nDUK_INTERNAL_DECL duk_hobject *duk_push_object_helper_proto(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_hobject *proto);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_push_hcompfunc(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_hboundfunc *duk_push_hboundfunc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_push_c_function_builtin(duk_hthread *thr, duk_c_function func, duk_int_t nargs);\nDUK_INTERNAL_DECL void duk_push_c_function_builtin_noconstruct(duk_hthread *thr, duk_c_function func, duk_int_t nargs);\n\n/* XXX: duk_push_harray() and duk_push_hcompfunc() are inconsistent with\n * duk_push_hobject() etc which don't create a new value.\n */\nDUK_INTERNAL_DECL duk_harray *duk_push_harray(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_harray *duk_push_harray_with_size(duk_hthread *thr, duk_uint32_t size);\nDUK_INTERNAL_DECL duk_tval *duk_push_harray_with_size_outptr(duk_hthread *thr, duk_uint32_t size);\n\nDUK_INTERNAL_DECL void duk_push_string_funcptr(duk_hthread *thr, duk_uint8_t *ptr, duk_size_t sz);\nDUK_INTERNAL_DECL void duk_push_lightfunc_name_raw(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags);\nDUK_INTERNAL_DECL void duk_push_lightfunc_name(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL void duk_push_lightfunc_tostring(duk_hthread *thr, duk_tval *tv);\n#if 0  /* not used yet */\nDUK_INTERNAL_DECL void duk_push_hnatfunc_name(duk_hthread *thr, duk_hnatfunc *h);\n#endif\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL_DECL duk_hbufobj *duk_push_bufobj_raw(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx);\n#endif\n\nDUK_INTERNAL_DECL void *duk_push_fixed_buffer_nozero(duk_hthread *thr, duk_size_t len);\nDUK_INTERNAL_DECL void *duk_push_fixed_buffer_zero(duk_hthread *thr, duk_size_t len);\n\nDUK_INTERNAL_DECL const char *duk_push_string_readable(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL const char *duk_push_string_tval_readable(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL const char *duk_push_string_tval_readable_error(duk_hthread *thr, duk_tval *tv);\n\n/* The duk_xxx_prop_stridx_short() variants expect their arguments to be short\n * enough to be packed into a single 32-bit integer argument.  Argument limits\n * vary per call; typically 16 bits are assigned to the signed value stack index\n * and the stridx.  In practice these work well for footprint with constant\n * arguments and such call sites are also easiest to verify to be correct.\n */\n\nDUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [] -> [val] */\nDUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_get_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t duk_get_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\nDUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_boolean(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop);  /* [] -> [] */\n\nDUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop(duk_hthread *thr, duk_idx_t obj_idx);\nDUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);\nDUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_xget_owndataprop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t duk_xget_owndataprop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n\nDUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [val] -> [] */\nDUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_put_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t duk_put_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n\nDUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [] -> [] */\n#if 0  /* Too few call sites to be useful. */\nDUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_del_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((obj_idx) >= -0x8000L && (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((stridx) >= 0 && (stridx) <= 0xffffL), \\\n\t duk_del_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n#endif\n#define duk_del_prop_stridx_short(thr,obj_idx,stridx) \\\n\tduk_del_prop_stridx((thr), (obj_idx), (stridx))\n\nDUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [] -> [] */\n#if 0  /* Too few call sites to be useful. */\nDUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_has_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((obj_idx) >= -0x8000L && (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((stridx) >= 0 && (stridx) <= 0xffffL), \\\n\t duk_has_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n#endif\n#define duk_has_prop_stridx_short(thr,obj_idx,stridx) \\\n\tduk_has_prop_stridx((thr), (obj_idx), (stridx))\n\nDUK_INTERNAL_DECL void duk_xdef_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t desc_flags);  /* [key val] -> [] */\n\nDUK_INTERNAL_DECL void duk_xdef_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags);  /* [val] -> [] */\n\n/* XXX: Because stridx and desc_flags have a limited range, this call could\n * always pack stridx and desc_flags into a single argument.\n */\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags);  /* [val] -> [] */\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_xdef_prop_stridx_short(thr,obj_idx,stridx,desc_flags) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x80L && (duk_int_t) (obj_idx) <= 0x7fL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (desc_flags) >= 0 && (duk_int_t) (desc_flags) <= 0xffL), \\\n\t duk_xdef_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 24) + (((duk_uint_t) (stridx)) << 8) + (duk_uint_t) (desc_flags)))\n\n#define duk_xdef_prop_wec(thr,obj_idx) \\\n\tduk_xdef_prop((thr), (obj_idx), DUK_PROPDESC_FLAGS_WEC)\n#define duk_xdef_prop_index_wec(thr,obj_idx,arr_idx) \\\n\tduk_xdef_prop_index((thr), (obj_idx), (arr_idx), DUK_PROPDESC_FLAGS_WEC)\n#define duk_xdef_prop_stridx_wec(thr,obj_idx,stridx) \\\n\tduk_xdef_prop_stridx((thr), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC)\n#define duk_xdef_prop_stridx_short_wec(thr,obj_idx,stridx) \\\n\tduk_xdef_prop_stridx_short((thr), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC)\n\n#if 0  /*unused*/\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx_builtin(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags);  /* [] -> [] */\n#endif\n\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx_thrower(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);  /* [] -> [] */\n\nDUK_INTERNAL_DECL duk_bool_t duk_get_method_stridx(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t stridx);\n\nDUK_INTERNAL_DECL void duk_pack(duk_hthread *thr, duk_idx_t count);\nDUK_INTERNAL_DECL duk_idx_t duk_unpack_array_like(duk_hthread *thr, duk_idx_t idx);\n#if 0\nDUK_INTERNAL_DECL void duk_unpack(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL void duk_push_symbol_descriptive_string(duk_hthread *thr, duk_hstring *h);\n\nDUK_INTERNAL_DECL void duk_resolve_nonbound_function(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_idx_t duk_get_top_require_min(duk_hthread *thr, duk_idx_t min_top);\nDUK_INTERNAL_DECL duk_idx_t duk_get_top_index_unsafe(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count);\nDUK_INTERNAL_DECL void duk_pop_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_2_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_3_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count);\nDUK_INTERNAL_DECL void duk_pop_nodecref_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_2_nodecref_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_3_nodecref_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_undefined(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_compact_m1(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_seal_freeze_raw(duk_hthread *thr, duk_idx_t obj_idx, duk_bool_t is_freeze);\n\nDUK_INTERNAL_DECL void duk_insert_undefined(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_insert_undefined_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count);\n\nDUK_INTERNAL_DECL void duk_concat_2(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_int_t duk_pcall_method_flags(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags);\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL_DECL void duk_to_primitive_ordinary(duk_hthread *thr, duk_idx_t idx, duk_int_t hint);\n#endif\n\nDUK_INTERNAL_DECL void duk_clear_prototype(duk_hthread *thr, duk_idx_t idx);\n\n/* Raw internal valstack access macros: access is unsafe so call site\n * must have a guarantee that the index is valid.  When that is the case,\n * using these macro results in faster and smaller code than duk_get_tval().\n * Both 'ctx' and 'idx' are evaluted multiple times, but only for asserts.\n */\n#define DUK_ASSERT_VALID_NEGIDX(thr,idx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (idx) < 0), DUK_ASSERT_EXPR(duk_is_valid_index((thr), (idx))))\n#define DUK_ASSERT_VALID_POSIDX(thr,idx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (idx) >= 0), DUK_ASSERT_EXPR(duk_is_valid_index((thr), (idx))))\n#define DUK_GET_TVAL_NEGIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_NEGIDX((thr),(idx)), ((duk_hthread *) (thr))->valstack_top + (idx))\n#define DUK_GET_TVAL_POSIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_POSIDX((thr),(idx)), ((duk_hthread *) (thr))->valstack_bottom + (idx))\n#define DUK_GET_HOBJECT_NEGIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_NEGIDX((thr),(idx)), DUK_TVAL_GET_OBJECT(((duk_hthread *) (thr))->valstack_top + (idx)))\n#define DUK_GET_HOBJECT_POSIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_POSIDX((thr),(idx)), DUK_TVAL_GET_OBJECT(((duk_hthread *) (thr))->valstack_bottom + (idx)))\n\n#define DUK_GET_THIS_TVAL_PTR(thr) \\\n\t(DUK_ASSERT_EXPR((thr)->valstack_bottom > (thr)->valstack), \\\n\t (thr)->valstack_bottom - 1)\n\nDUK_INTERNAL_DECL duk_double_t duk_time_get_ecmascript_time(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_double_t duk_time_get_ecmascript_time_nofrac(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr);\n\n#endif  /* DUK_API_INTERNAL_H_INCLUDED */\n/* #include duk_hstring.h */\n#line 1 \"duk_hstring.h\"\n/*\n *  Heap string representation.\n *\n *  Strings are byte sequences ordinarily stored in extended UTF-8 format,\n *  allowing values larger than the official UTF-8 range (used internally)\n *  and also allowing UTF-8 encoding of surrogate pairs (CESU-8 format).\n *  Strings may also be invalid UTF-8 altogether which is the case e.g. with\n *  strings used as internal property names and raw buffers converted to\n *  strings.  In such cases the 'clen' field contains an inaccurate value.\n *\n *  ECMAScript requires support for 32-bit long strings.  However, since each\n *  16-bit codepoint can take 3 bytes in CESU-8, this representation can only\n *  support about 1.4G codepoint long strings in extreme cases.  This is not\n *  really a practical issue.\n */\n\n#if !defined(DUK_HSTRING_H_INCLUDED)\n#define DUK_HSTRING_H_INCLUDED\n\n/* Impose a maximum string length for now.  Restricted artificially to\n * ensure adding a heap header length won't overflow size_t.  The limit\n * should be synchronized with DUK_HBUFFER_MAX_BYTELEN.\n *\n * E5.1 makes provisions to support strings longer than 4G characters.\n * This limit should be eliminated on 64-bit platforms (and increased\n * closer to maximum support on 32-bit platforms).\n */\n\n#if defined(DUK_USE_STRLEN16)\n#define DUK_HSTRING_MAX_BYTELEN                     (0x0000ffffUL)\n#else\n#define DUK_HSTRING_MAX_BYTELEN                     (0x7fffffffUL)\n#endif\n\n/* XXX: could add flags for \"is valid CESU-8\" (ECMAScript compatible strings),\n * \"is valid UTF-8\", \"is valid extended UTF-8\" (internal strings are not,\n * regexp bytecode is), and \"contains non-BMP characters\".  These are not\n * needed right now.\n */\n\n/* With lowmem builds the high 16 bits of duk_heaphdr are used for other\n * purposes, so this leaves 7 duk_heaphdr flags and 9 duk_hstring flags.\n */\n#define DUK_HSTRING_FLAG_ASCII                      DUK_HEAPHDR_USER_FLAG(0)  /* string is ASCII, clen == blen */\n#define DUK_HSTRING_FLAG_ARRIDX                     DUK_HEAPHDR_USER_FLAG(1)  /* string is a valid array index */\n#define DUK_HSTRING_FLAG_SYMBOL                     DUK_HEAPHDR_USER_FLAG(2)  /* string is a symbol (invalid utf-8) */\n#define DUK_HSTRING_FLAG_HIDDEN                     DUK_HEAPHDR_USER_FLAG(3)  /* string is a hidden symbol (implies symbol, Duktape 1.x internal string) */\n#define DUK_HSTRING_FLAG_RESERVED_WORD              DUK_HEAPHDR_USER_FLAG(4)  /* string is a reserved word (non-strict) */\n#define DUK_HSTRING_FLAG_STRICT_RESERVED_WORD       DUK_HEAPHDR_USER_FLAG(5)  /* string is a reserved word (strict) */\n#define DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS          DUK_HEAPHDR_USER_FLAG(6)  /* string is 'eval' or 'arguments' */\n#define DUK_HSTRING_FLAG_EXTDATA                    DUK_HEAPHDR_USER_FLAG(7)  /* string data is external (duk_hstring_external) */\n#define DUK_HSTRING_FLAG_PINNED_LITERAL             DUK_HEAPHDR_USER_FLAG(8)  /* string is a literal, and pinned */\n\n#define DUK_HSTRING_HAS_ASCII(x)                    DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII)\n#define DUK_HSTRING_HAS_ARRIDX(x)                   DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX)\n#define DUK_HSTRING_HAS_SYMBOL(x)                   DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL)\n#define DUK_HSTRING_HAS_HIDDEN(x)                   DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN)\n#define DUK_HSTRING_HAS_RESERVED_WORD(x)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD)\n#define DUK_HSTRING_HAS_STRICT_RESERVED_WORD(x)     DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD)\n#define DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(x)        DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS)\n#define DUK_HSTRING_HAS_EXTDATA(x)                  DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA)\n#define DUK_HSTRING_HAS_PINNED_LITERAL(x)           DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL)\n\n#define DUK_HSTRING_SET_ASCII(x)                    DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII)\n#define DUK_HSTRING_SET_ARRIDX(x)                   DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX)\n#define DUK_HSTRING_SET_SYMBOL(x)                   DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL)\n#define DUK_HSTRING_SET_HIDDEN(x)                   DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN)\n#define DUK_HSTRING_SET_RESERVED_WORD(x)            DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD)\n#define DUK_HSTRING_SET_STRICT_RESERVED_WORD(x)     DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD)\n#define DUK_HSTRING_SET_EVAL_OR_ARGUMENTS(x)        DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS)\n#define DUK_HSTRING_SET_EXTDATA(x)                  DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA)\n#define DUK_HSTRING_SET_PINNED_LITERAL(x)           DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL)\n\n#define DUK_HSTRING_CLEAR_ASCII(x)                  DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII)\n#define DUK_HSTRING_CLEAR_ARRIDX(x)                 DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX)\n#define DUK_HSTRING_CLEAR_SYMBOL(x)                 DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL)\n#define DUK_HSTRING_CLEAR_HIDDEN(x)                 DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN)\n#define DUK_HSTRING_CLEAR_RESERVED_WORD(x)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD)\n#define DUK_HSTRING_CLEAR_STRICT_RESERVED_WORD(x)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD)\n#define DUK_HSTRING_CLEAR_EVAL_OR_ARGUMENTS(x)      DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS)\n#define DUK_HSTRING_CLEAR_EXTDATA(x)                DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA)\n#define DUK_HSTRING_CLEAR_PINNED_LITERAL(x)         DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL)\n\n#if 0  /* Slightly smaller code without explicit flag, but explicit flag\n        * is very useful when 'clen' is dropped.\n        */\n#define DUK_HSTRING_IS_ASCII(x)                     (DUK_HSTRING_GET_BYTELEN((x)) == DUK_HSTRING_GET_CHARLEN((x)))\n#endif\n#define DUK_HSTRING_IS_ASCII(x)                     DUK_HSTRING_HAS_ASCII((x))  /* lazily set! */\n#define DUK_HSTRING_IS_EMPTY(x)                     (DUK_HSTRING_GET_BYTELEN((x)) == 0)\n\n#if defined(DUK_USE_STRHASH16)\n#define DUK_HSTRING_GET_HASH(x)                     ((x)->hdr.h_flags >> 16)\n#define DUK_HSTRING_SET_HASH(x,v) do { \\\n\t\t(x)->hdr.h_flags = ((x)->hdr.h_flags & 0x0000ffffUL) | ((v) << 16); \\\n\t} while (0)\n#else\n#define DUK_HSTRING_GET_HASH(x)                     ((x)->hash)\n#define DUK_HSTRING_SET_HASH(x,v) do { \\\n\t\t(x)->hash = (v); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_STRLEN16)\n#define DUK_HSTRING_GET_BYTELEN(x)                  ((x)->hdr.h_strextra16)\n#define DUK_HSTRING_SET_BYTELEN(x,v) do { \\\n\t\t(x)->hdr.h_strextra16 = (v); \\\n\t} while (0)\n#if defined(DUK_USE_HSTRING_CLEN)\n#define DUK_HSTRING_GET_CHARLEN(x)                  duk_hstring_get_charlen((x))\n#define DUK_HSTRING_SET_CHARLEN(x,v) do { \\\n\t\t(x)->clen16 = (v); \\\n\t} while (0)\n#else\n#define DUK_HSTRING_GET_CHARLEN(x)                  duk_hstring_get_charlen((x))\n#define DUK_HSTRING_SET_CHARLEN(x,v) do { \\\n\t\tDUK_ASSERT(0);  /* should never be called */ \\\n\t} while (0)\n#endif\n#else\n#define DUK_HSTRING_GET_BYTELEN(x)                  ((x)->blen)\n#define DUK_HSTRING_SET_BYTELEN(x,v) do { \\\n\t\t(x)->blen = (v); \\\n\t} while (0)\n#define DUK_HSTRING_GET_CHARLEN(x)                  duk_hstring_get_charlen((x))\n#define DUK_HSTRING_SET_CHARLEN(x,v) do { \\\n\t\t(x)->clen = (v); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_HSTRING_EXTDATA)\n#define DUK_HSTRING_GET_EXTDATA(x) \\\n\t((x)->extdata)\n#define DUK_HSTRING_GET_DATA(x) \\\n\t(DUK_HSTRING_HAS_EXTDATA((x)) ? \\\n\t\tDUK_HSTRING_GET_EXTDATA((const duk_hstring_external *) (x)) : ((const duk_uint8_t *) ((x) + 1)))\n#else\n#define DUK_HSTRING_GET_DATA(x) \\\n\t((const duk_uint8_t *) ((x) + 1))\n#endif\n\n#define DUK_HSTRING_GET_DATA_END(x) \\\n\t(DUK_HSTRING_GET_DATA((x)) + (x)->blen)\n\n/* Marker value; in E5 2^32-1 is not a valid array index (2^32-2 is highest\n * valid).\n */\n#define DUK_HSTRING_NO_ARRAY_INDEX  (0xffffffffUL)\n\n#if defined(DUK_USE_HSTRING_ARRIDX)\n#define DUK_HSTRING_GET_ARRIDX_FAST(h)  ((h)->arridx)\n#define DUK_HSTRING_GET_ARRIDX_SLOW(h)  ((h)->arridx)\n#else\n/* Get array index related to string (or return DUK_HSTRING_NO_ARRAY_INDEX);\n * avoids helper call if string has no array index value.\n */\n#define DUK_HSTRING_GET_ARRIDX_FAST(h)  \\\n\t(DUK_HSTRING_HAS_ARRIDX((h)) ? duk_js_to_arrayindex_hstring_fast_known((h)) : DUK_HSTRING_NO_ARRAY_INDEX)\n\n/* Slower but more compact variant. */\n#define DUK_HSTRING_GET_ARRIDX_SLOW(h)  \\\n\t(duk_js_to_arrayindex_hstring_fast((h)))\n#endif\n\n/* XXX: these actually fit into duk_hstring */\n#define DUK_SYMBOL_TYPE_HIDDEN 0\n#define DUK_SYMBOL_TYPE_GLOBAL 1\n#define DUK_SYMBOL_TYPE_LOCAL 2\n#define DUK_SYMBOL_TYPE_WELLKNOWN 3\n\n/* Assertion for duk_hstring validity. */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hstring_assert_valid(duk_hstring *h);\n#define DUK_HSTRING_ASSERT_VALID(h)  do { duk_hstring_assert_valid((h)); } while (0)\n#else\n#define DUK_HSTRING_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Misc\n */\n\nstruct duk_hstring {\n\t/* Smaller heaphdr than for other objects, because strings are held\n\t * in string intern table which requires no link pointers.  Much of\n\t * the 32-bit flags field is unused by flags, so we can stuff a 16-bit\n\t * field in there.\n\t */\n\tduk_heaphdr_string hdr;\n\n\t/* String hash. */\n#if defined(DUK_USE_STRHASH16)\n\t/* If 16-bit hash is in use, stuff it into duk_heaphdr_string flags. */\n#else\n\tduk_uint32_t hash;\n#endif\n\n\t/* Precomputed array index (or DUK_HSTRING_NO_ARRAY_INDEX). */\n#if defined(DUK_USE_HSTRING_ARRIDX)\n\tduk_uarridx_t arridx;\n#endif\n\n\t/* Length in bytes (not counting NUL term). */\n#if defined(DUK_USE_STRLEN16)\n\t/* placed in duk_heaphdr_string */\n#else\n\tduk_uint32_t blen;\n#endif\n\n\t/* Length in codepoints (must be E5 compatible). */\n#if defined(DUK_USE_STRLEN16)\n#if defined(DUK_USE_HSTRING_CLEN)\n\tduk_uint16_t clen16;\n#else\n\t/* computed live */\n#endif\n#else\n\tduk_uint32_t clen;\n#endif\n\n\t/*\n\t *  String data of 'blen+1' bytes follows (+1 for NUL termination\n\t *  convenience for C API).  No alignment needs to be guaranteed\n\t *  for strings, but fields above should guarantee alignment-by-4\n\t *  (but not alignment-by-8).\n\t */\n};\n\n/* The external string struct is defined even when the feature is inactive. */\nstruct duk_hstring_external {\n\tduk_hstring str;\n\n\t/*\n\t *  For an external string, the NUL-terminated string data is stored\n\t *  externally.  The user must guarantee that data behind this pointer\n\t *  doesn't change while it's used.\n\t */\n\n\tconst duk_uint8_t *extdata;\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, duk_uint_t pos, duk_bool_t surrogate_aware);\nDUK_INTERNAL_DECL duk_bool_t duk_hstring_equals_ascii_cstring(duk_hstring *h, const char *cstr);\nDUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);\n#if !defined(DUK_USE_HSTRING_LAZY_CLEN)\nDUK_INTERNAL_DECL void duk_hstring_init_charlen(duk_hstring *h);\n#endif\n\n#endif  /* DUK_HSTRING_H_INCLUDED */\n/* #include duk_hobject.h */\n#line 1 \"duk_hobject.h\"\n/*\n *  Heap object representation.\n *\n *  Heap objects are used for ECMAScript objects, arrays, and functions,\n *  but also for internal control like declarative and object environment\n *  records.  Compiled functions, native functions, and threads are also\n *  objects but with an extended C struct.\n *\n *  Objects provide the required ECMAScript semantics and exotic behaviors\n *  especially for property access.\n *\n *  Properties are stored in three conceptual parts:\n *\n *    1. A linear 'entry part' contains ordered key-value-attributes triples\n *       and is the main method of string properties.\n *\n *    2. An optional linear 'array part' is used for array objects to store a\n *       (dense) range of [0,N[ array indexed entries with default attributes\n *       (writable, enumerable, configurable).  If the array part would become\n *       sparse or non-default attributes are required, the array part is\n *       abandoned and moved to the 'entry part'.\n *\n *    3. An optional 'hash part' is used to optimize lookups of the entry\n *       part; it is used only for objects with sufficiently many properties\n *       and can be abandoned without loss of information.\n *\n *  These three conceptual parts are stored in a single memory allocated area.\n *  This minimizes memory allocation overhead but also means that all three\n *  parts are resized together, and makes property access a bit complicated.\n */\n\n#if !defined(DUK_HOBJECT_H_INCLUDED)\n#define DUK_HOBJECT_H_INCLUDED\n\n/* Object flags.  Make sure this stays in sync with debugger object\n * inspection code.\n */\n\n/* XXX: some flags are object subtype specific (e.g. common to all function\n * subtypes, duk_harray, etc) and could be reused for different subtypes.\n */\n#define DUK_HOBJECT_FLAG_EXTENSIBLE            DUK_HEAPHDR_USER_FLAG(0)   /* object is extensible */\n#define DUK_HOBJECT_FLAG_CONSTRUCTABLE         DUK_HEAPHDR_USER_FLAG(1)   /* object is constructable */\n#define DUK_HOBJECT_FLAG_CALLABLE              DUK_HEAPHDR_USER_FLAG(2)   /* object is callable */\n#define DUK_HOBJECT_FLAG_BOUNDFUNC             DUK_HEAPHDR_USER_FLAG(3)   /* object established using Function.prototype.bind() */\n#define DUK_HOBJECT_FLAG_COMPFUNC              DUK_HEAPHDR_USER_FLAG(4)   /* object is a compiled function (duk_hcompfunc) */\n#define DUK_HOBJECT_FLAG_NATFUNC               DUK_HEAPHDR_USER_FLAG(5)   /* object is a native function (duk_hnatfunc) */\n#define DUK_HOBJECT_FLAG_BUFOBJ                DUK_HEAPHDR_USER_FLAG(6)   /* object is a buffer object (duk_hbufobj) (always exotic) */\n#define DUK_HOBJECT_FLAG_FASTREFS              DUK_HEAPHDR_USER_FLAG(7)   /* object has no fields needing DECREF/marking beyond base duk_hobject header */\n#define DUK_HOBJECT_FLAG_ARRAY_PART            DUK_HEAPHDR_USER_FLAG(8)   /* object has an array part (a_size may still be 0) */\n#define DUK_HOBJECT_FLAG_STRICT                DUK_HEAPHDR_USER_FLAG(9)   /* function: function object is strict */\n#define DUK_HOBJECT_FLAG_NOTAIL                DUK_HEAPHDR_USER_FLAG(10)  /* function: function must not be tail called */\n#define DUK_HOBJECT_FLAG_NEWENV                DUK_HEAPHDR_USER_FLAG(11)  /* function: create new environment when called (see duk_hcompfunc) */\n#define DUK_HOBJECT_FLAG_NAMEBINDING           DUK_HEAPHDR_USER_FLAG(12)  /* function: create binding for func name (function templates only, used for named function expressions) */\n#define DUK_HOBJECT_FLAG_CREATEARGS            DUK_HEAPHDR_USER_FLAG(13)  /* function: create an arguments object on function call */\n#define DUK_HOBJECT_FLAG_HAVE_FINALIZER        DUK_HEAPHDR_USER_FLAG(14)  /* object has a callable (own) finalizer property */\n#define DUK_HOBJECT_FLAG_EXOTIC_ARRAY          DUK_HEAPHDR_USER_FLAG(15)  /* 'Array' object, array length and index exotic behavior */\n#define DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ      DUK_HEAPHDR_USER_FLAG(16)  /* 'String' object, array index exotic behavior */\n#define DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS      DUK_HEAPHDR_USER_FLAG(17)  /* 'Arguments' object and has arguments exotic behavior (non-strict callee) */\n#define DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ       DUK_HEAPHDR_USER_FLAG(18)  /* 'Proxy' object */\n#define DUK_HOBJECT_FLAG_SPECIAL_CALL          DUK_HEAPHDR_USER_FLAG(19)  /* special casing in call behavior, for .call(), .apply(), etc. */\n\n#define DUK_HOBJECT_FLAG_CLASS_BASE            DUK_HEAPHDR_USER_FLAG_NUMBER(20)\n#define DUK_HOBJECT_FLAG_CLASS_BITS            5\n\n#define DUK_HOBJECT_GET_CLASS_NUMBER(h)        \\\n\tDUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS)\n#define DUK_HOBJECT_SET_CLASS_NUMBER(h,v)      \\\n\tDUK_HEAPHDR_SET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS, (v))\n\n#define DUK_HOBJECT_GET_CLASS_MASK(h)          \\\n\t(1UL << DUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS))\n\n/* Macro for creating flag initializer from a class number.\n * Unsigned type cast is needed to avoid warnings about coercing\n * a signed integer to an unsigned one; the largest class values\n * have the highest bit (bit 31) set which causes this.\n */\n#define DUK_HOBJECT_CLASS_AS_FLAGS(v)          (((duk_uint_t) (v)) << DUK_HOBJECT_FLAG_CLASS_BASE)\n\n/* E5 Section 8.6.2 + custom classes */\n#define DUK_HOBJECT_CLASS_NONE                 0\n#define DUK_HOBJECT_CLASS_OBJECT               1\n#define DUK_HOBJECT_CLASS_ARRAY                2\n#define DUK_HOBJECT_CLASS_FUNCTION             3\n#define DUK_HOBJECT_CLASS_ARGUMENTS            4\n#define DUK_HOBJECT_CLASS_BOOLEAN              5\n#define DUK_HOBJECT_CLASS_DATE                 6\n#define DUK_HOBJECT_CLASS_ERROR                7\n#define DUK_HOBJECT_CLASS_JSON                 8\n#define DUK_HOBJECT_CLASS_MATH                 9\n#define DUK_HOBJECT_CLASS_NUMBER               10\n#define DUK_HOBJECT_CLASS_REGEXP               11\n#define DUK_HOBJECT_CLASS_STRING               12\n#define DUK_HOBJECT_CLASS_GLOBAL               13\n#define DUK_HOBJECT_CLASS_SYMBOL               14\n#define DUK_HOBJECT_CLASS_OBJENV               15  /* custom */\n#define DUK_HOBJECT_CLASS_DECENV               16  /* custom */\n#define DUK_HOBJECT_CLASS_POINTER              17  /* custom */\n#define DUK_HOBJECT_CLASS_THREAD               18  /* custom; implies DUK_HOBJECT_IS_THREAD */\n#define DUK_HOBJECT_CLASS_BUFOBJ_MIN           19\n#define DUK_HOBJECT_CLASS_ARRAYBUFFER          19  /* implies DUK_HOBJECT_IS_BUFOBJ */\n#define DUK_HOBJECT_CLASS_DATAVIEW             20\n#define DUK_HOBJECT_CLASS_INT8ARRAY            21\n#define DUK_HOBJECT_CLASS_UINT8ARRAY           22\n#define DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY    23\n#define DUK_HOBJECT_CLASS_INT16ARRAY           24\n#define DUK_HOBJECT_CLASS_UINT16ARRAY          25\n#define DUK_HOBJECT_CLASS_INT32ARRAY           26\n#define DUK_HOBJECT_CLASS_UINT32ARRAY          27\n#define DUK_HOBJECT_CLASS_FLOAT32ARRAY         28\n#define DUK_HOBJECT_CLASS_FLOAT64ARRAY         29\n#define DUK_HOBJECT_CLASS_BUFOBJ_MAX           29\n#define DUK_HOBJECT_CLASS_MAX                  29\n\n/* Class masks. */\n#define DUK_HOBJECT_CMASK_ALL                  ((1UL << (DUK_HOBJECT_CLASS_MAX + 1)) - 1UL)\n#define DUK_HOBJECT_CMASK_NONE                 (1UL << DUK_HOBJECT_CLASS_NONE)\n#define DUK_HOBJECT_CMASK_ARGUMENTS            (1UL << DUK_HOBJECT_CLASS_ARGUMENTS)\n#define DUK_HOBJECT_CMASK_ARRAY                (1UL << DUK_HOBJECT_CLASS_ARRAY)\n#define DUK_HOBJECT_CMASK_BOOLEAN              (1UL << DUK_HOBJECT_CLASS_BOOLEAN)\n#define DUK_HOBJECT_CMASK_DATE                 (1UL << DUK_HOBJECT_CLASS_DATE)\n#define DUK_HOBJECT_CMASK_ERROR                (1UL << DUK_HOBJECT_CLASS_ERROR)\n#define DUK_HOBJECT_CMASK_FUNCTION             (1UL << DUK_HOBJECT_CLASS_FUNCTION)\n#define DUK_HOBJECT_CMASK_JSON                 (1UL << DUK_HOBJECT_CLASS_JSON)\n#define DUK_HOBJECT_CMASK_MATH                 (1UL << DUK_HOBJECT_CLASS_MATH)\n#define DUK_HOBJECT_CMASK_NUMBER               (1UL << DUK_HOBJECT_CLASS_NUMBER)\n#define DUK_HOBJECT_CMASK_OBJECT               (1UL << DUK_HOBJECT_CLASS_OBJECT)\n#define DUK_HOBJECT_CMASK_REGEXP               (1UL << DUK_HOBJECT_CLASS_REGEXP)\n#define DUK_HOBJECT_CMASK_STRING               (1UL << DUK_HOBJECT_CLASS_STRING)\n#define DUK_HOBJECT_CMASK_GLOBAL               (1UL << DUK_HOBJECT_CLASS_GLOBAL)\n#define DUK_HOBJECT_CMASK_SYMBOL               (1UL << DUK_HOBJECT_CLASS_SYMBOL)\n#define DUK_HOBJECT_CMASK_OBJENV               (1UL << DUK_HOBJECT_CLASS_OBJENV)\n#define DUK_HOBJECT_CMASK_DECENV               (1UL << DUK_HOBJECT_CLASS_DECENV)\n#define DUK_HOBJECT_CMASK_POINTER              (1UL << DUK_HOBJECT_CLASS_POINTER)\n#define DUK_HOBJECT_CMASK_ARRAYBUFFER          (1UL << DUK_HOBJECT_CLASS_ARRAYBUFFER)\n#define DUK_HOBJECT_CMASK_DATAVIEW             (1UL << DUK_HOBJECT_CLASS_DATAVIEW)\n#define DUK_HOBJECT_CMASK_INT8ARRAY            (1UL << DUK_HOBJECT_CLASS_INT8ARRAY)\n#define DUK_HOBJECT_CMASK_UINT8ARRAY           (1UL << DUK_HOBJECT_CLASS_UINT8ARRAY)\n#define DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY    (1UL << DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY)\n#define DUK_HOBJECT_CMASK_INT16ARRAY           (1UL << DUK_HOBJECT_CLASS_INT16ARRAY)\n#define DUK_HOBJECT_CMASK_UINT16ARRAY          (1UL << DUK_HOBJECT_CLASS_UINT16ARRAY)\n#define DUK_HOBJECT_CMASK_INT32ARRAY           (1UL << DUK_HOBJECT_CLASS_INT32ARRAY)\n#define DUK_HOBJECT_CMASK_UINT32ARRAY          (1UL << DUK_HOBJECT_CLASS_UINT32ARRAY)\n#define DUK_HOBJECT_CMASK_FLOAT32ARRAY         (1UL << DUK_HOBJECT_CLASS_FLOAT32ARRAY)\n#define DUK_HOBJECT_CMASK_FLOAT64ARRAY         (1UL << DUK_HOBJECT_CLASS_FLOAT64ARRAY)\n\n#define DUK_HOBJECT_CMASK_ALL_BUFOBJS \\\n\t(DUK_HOBJECT_CMASK_ARRAYBUFFER | \\\n\t DUK_HOBJECT_CMASK_DATAVIEW | \\\n\t DUK_HOBJECT_CMASK_INT8ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT8ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY | \\\n\t DUK_HOBJECT_CMASK_INT16ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT16ARRAY | \\\n\t DUK_HOBJECT_CMASK_INT32ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT32ARRAY | \\\n\t DUK_HOBJECT_CMASK_FLOAT32ARRAY | \\\n\t DUK_HOBJECT_CMASK_FLOAT64ARRAY)\n\n#define DUK_HOBJECT_IS_OBJENV(h)               (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_OBJENV)\n#define DUK_HOBJECT_IS_DECENV(h)               (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_DECENV)\n#define DUK_HOBJECT_IS_ENV(h)                  (DUK_HOBJECT_IS_OBJENV((h)) || DUK_HOBJECT_IS_DECENV((h)))\n#define DUK_HOBJECT_IS_ARRAY(h)                DUK_HOBJECT_HAS_EXOTIC_ARRAY((h))  /* Rely on class Array <=> exotic Array */\n#define DUK_HOBJECT_IS_BOUNDFUNC(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_IS_COMPFUNC(h)             DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_IS_NATFUNC(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_IS_BUFOBJ(h)               DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#else\n#define DUK_HOBJECT_IS_BUFOBJ(h)               0\n#endif\n#define DUK_HOBJECT_IS_THREAD(h)               (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_THREAD)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_IS_PROXY(h)                DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ((h))\n#else\n#define DUK_HOBJECT_IS_PROXY(h)                0\n#endif\n\n#define DUK_HOBJECT_IS_NONBOUND_FUNCTION(h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \\\n                                                        DUK_HOBJECT_FLAG_COMPFUNC | \\\n                                                        DUK_HOBJECT_FLAG_NATFUNC)\n\n#define DUK_HOBJECT_IS_FUNCTION(h)             DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \\\n                                                        DUK_HOBJECT_FLAG_BOUNDFUNC | \\\n                                                        DUK_HOBJECT_FLAG_COMPFUNC | \\\n                                                        DUK_HOBJECT_FLAG_NATFUNC)\n\n#define DUK_HOBJECT_IS_CALLABLE(h)             DUK_HOBJECT_HAS_CALLABLE((h))\n\n/* Object has any exotic behavior(s). */\n#define DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS      (DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | \\\n                                                DUK_HOBJECT_FLAG_BUFOBJ | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#define DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR(h)     DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS)\n\n/* Object has any virtual properties (not counting Proxy behavior). */\n#define DUK_HOBJECT_VIRTUAL_PROPERTY_FLAGS     (DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | \\\n                                                DUK_HOBJECT_FLAG_BUFOBJ)\n#define DUK_HOBJECT_HAS_VIRTUAL_PROPERTIES(h)  DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_VIRTUAL_PROPERTY_FLAGS)\n\n#define DUK_HOBJECT_HAS_EXTENSIBLE(h)          DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)\n#define DUK_HOBJECT_HAS_CONSTRUCTABLE(h)       DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)\n#define DUK_HOBJECT_HAS_CALLABLE(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE)\n#define DUK_HOBJECT_HAS_BOUNDFUNC(h)           DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_HAS_COMPFUNC(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_HAS_NATFUNC(h)             DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_HAS_BUFOBJ(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#else\n#define DUK_HOBJECT_HAS_BUFOBJ(h)              0\n#endif\n#define DUK_HOBJECT_HAS_FASTREFS(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)\n#define DUK_HOBJECT_HAS_ARRAY_PART(h)          DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)\n#define DUK_HOBJECT_HAS_STRICT(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)\n#define DUK_HOBJECT_HAS_NOTAIL(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)\n#define DUK_HOBJECT_HAS_NEWENV(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)\n#define DUK_HOBJECT_HAS_NAMEBINDING(h)         DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)\n#define DUK_HOBJECT_HAS_CREATEARGS(h)          DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)\n#define DUK_HOBJECT_HAS_HAVE_FINALIZER(h)      DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER)\n#define DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)        DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)\n#define DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)\n#define DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)     DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#else\n#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)     0\n#endif\n#define DUK_HOBJECT_HAS_SPECIAL_CALL(h)        DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)\n\n#define DUK_HOBJECT_SET_EXTENSIBLE(h)          DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)\n#define DUK_HOBJECT_SET_CONSTRUCTABLE(h)       DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)\n#define DUK_HOBJECT_SET_CALLABLE(h)            DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE)\n#define DUK_HOBJECT_SET_BOUNDFUNC(h)           DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_SET_COMPFUNC(h)            DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_SET_NATFUNC(h)             DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_SET_BUFOBJ(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#endif\n#define DUK_HOBJECT_SET_FASTREFS(h)            DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)\n#define DUK_HOBJECT_SET_ARRAY_PART(h)          DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)\n#define DUK_HOBJECT_SET_STRICT(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)\n#define DUK_HOBJECT_SET_NOTAIL(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)\n#define DUK_HOBJECT_SET_NEWENV(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)\n#define DUK_HOBJECT_SET_NAMEBINDING(h)         DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)\n#define DUK_HOBJECT_SET_CREATEARGS(h)          DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)\n#define DUK_HOBJECT_SET_HAVE_FINALIZER(h)      DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER)\n#define DUK_HOBJECT_SET_EXOTIC_ARRAY(h)        DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)\n#define DUK_HOBJECT_SET_EXOTIC_STRINGOBJ(h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)\n#define DUK_HOBJECT_SET_EXOTIC_ARGUMENTS(h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_SET_EXOTIC_PROXYOBJ(h)     DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#endif\n#define DUK_HOBJECT_SET_SPECIAL_CALL(h)        DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)\n\n#define DUK_HOBJECT_CLEAR_EXTENSIBLE(h)        DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)\n#define DUK_HOBJECT_CLEAR_CONSTRUCTABLE(h)     DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)\n#define DUK_HOBJECT_CLEAR_CALLABLE(h)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE)\n#define DUK_HOBJECT_CLEAR_BOUNDFUNC(h)         DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_CLEAR_COMPFUNC(h)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_CLEAR_NATFUNC(h)           DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_CLEAR_BUFOBJ(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#endif\n#define DUK_HOBJECT_CLEAR_FASTREFS(h)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)\n#define DUK_HOBJECT_CLEAR_ARRAY_PART(h)        DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)\n#define DUK_HOBJECT_CLEAR_STRICT(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)\n#define DUK_HOBJECT_CLEAR_NOTAIL(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)\n#define DUK_HOBJECT_CLEAR_NEWENV(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)\n#define DUK_HOBJECT_CLEAR_NAMEBINDING(h)       DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)\n#define DUK_HOBJECT_CLEAR_CREATEARGS(h)        DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)\n#define DUK_HOBJECT_CLEAR_HAVE_FINALIZER(h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER)\n#define DUK_HOBJECT_CLEAR_EXOTIC_ARRAY(h)      DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)\n#define DUK_HOBJECT_CLEAR_EXOTIC_STRINGOBJ(h)  DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)\n#define DUK_HOBJECT_CLEAR_EXOTIC_ARGUMENTS(h)  DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_CLEAR_EXOTIC_PROXYOBJ(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#endif\n#define DUK_HOBJECT_CLEAR_SPECIAL_CALL(h)      DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)\n\n/* Object can/cannot use FASTREFS, i.e. has no strong reference fields beyond\n * duk_hobject base header.  This is used just for asserts so doesn't need to\n * be optimized.\n */\n#define DUK_HOBJECT_PROHIBITS_FASTREFS(h) \\\n\t(DUK_HOBJECT_IS_COMPFUNC((h)) || DUK_HOBJECT_IS_DECENV((h)) || DUK_HOBJECT_IS_OBJENV((h)) || \\\n\t DUK_HOBJECT_IS_BUFOBJ((h)) || DUK_HOBJECT_IS_THREAD((h)) || DUK_HOBJECT_IS_PROXY((h)) || \\\n\t DUK_HOBJECT_IS_BOUNDFUNC((h)))\n#define DUK_HOBJECT_ALLOWS_FASTREFS(h) (!DUK_HOBJECT_PROHIBITS_FASTREFS((h)))\n\n/* Flags used for property attributes in duk_propdesc and packed flags.\n * Must fit into 8 bits.\n */\n#define DUK_PROPDESC_FLAG_WRITABLE              (1U << 0)    /* E5 Section 8.6.1 */\n#define DUK_PROPDESC_FLAG_ENUMERABLE            (1U << 1)    /* E5 Section 8.6.1 */\n#define DUK_PROPDESC_FLAG_CONFIGURABLE          (1U << 2)    /* E5 Section 8.6.1 */\n#define DUK_PROPDESC_FLAG_ACCESSOR              (1U << 3)    /* accessor */\n#define DUK_PROPDESC_FLAG_VIRTUAL               (1U << 4)    /* property is virtual: used in duk_propdesc, never stored\n                                                             * (used by e.g. buffer virtual properties)\n                                                             */\n#define DUK_PROPDESC_FLAGS_MASK                 (DUK_PROPDESC_FLAG_WRITABLE | \\\n                                                 DUK_PROPDESC_FLAG_ENUMERABLE | \\\n                                                 DUK_PROPDESC_FLAG_CONFIGURABLE | \\\n                                                 DUK_PROPDESC_FLAG_ACCESSOR)\n\n/* Additional flags which are passed in the same flags argument as property\n * flags but are not stored in object properties.\n */\n#define DUK_PROPDESC_FLAG_NO_OVERWRITE          (1U << 4)    /* internal define property: skip write silently if exists */\n\n/* Convenience defines for property attributes. */\n#define DUK_PROPDESC_FLAGS_NONE                 0\n#define DUK_PROPDESC_FLAGS_W                    (DUK_PROPDESC_FLAG_WRITABLE)\n#define DUK_PROPDESC_FLAGS_E                    (DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_PROPDESC_FLAGS_C                    (DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_PROPDESC_FLAGS_WE                   (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_PROPDESC_FLAGS_WC                   (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_PROPDESC_FLAGS_EC                   (DUK_PROPDESC_FLAG_ENUMERABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_PROPDESC_FLAGS_WEC                  (DUK_PROPDESC_FLAG_WRITABLE | \\\n                                                 DUK_PROPDESC_FLAG_ENUMERABLE | \\\n                                                 DUK_PROPDESC_FLAG_CONFIGURABLE)\n\n/* Flags for duk_hobject_get_own_propdesc() and variants. */\n#define DUK_GETDESC_FLAG_PUSH_VALUE          (1U << 0)  /* push value to stack */\n#define DUK_GETDESC_FLAG_IGNORE_PROTOLOOP    (1U << 1)  /* don't throw for prototype loop */\n\n/*\n *  Macro for object validity check\n *\n *  Assert for currently guaranteed relations between flags, for instance.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hobject_assert_valid(duk_hobject *h);\n#define DUK_HOBJECT_ASSERT_VALID(h)  do { duk_hobject_assert_valid((h)); } while (0)\n#else\n#define DUK_HOBJECT_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Macros to access the 'props' allocation.\n */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HOBJECT_GET_PROPS(heap,h) \\\n\t((duk_uint8_t *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, ((duk_heaphdr *) (h))->h_extra16))\n#define DUK_HOBJECT_SET_PROPS(heap,h,x) do { \\\n\t\t((duk_heaphdr *) (h))->h_extra16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \\\n\t} while (0)\n#else\n#define DUK_HOBJECT_GET_PROPS(heap,h) \\\n\t((h)->props)\n#define DUK_HOBJECT_SET_PROPS(heap,h,x) do { \\\n\t\t(h)->props = (duk_uint8_t *) (x); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_HOBJECT_LAYOUT_1)\n/* LAYOUT 1 */\n#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \\\n\t((duk_hstring **) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) \\\n\t))\n#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \\\n\t((duk_propvalue *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_hstring *) \\\n\t))\n#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \\\n\t((duk_uint8_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \\\n\t))\n#define DUK_HOBJECT_A_GET_BASE(heap,h) \\\n\t((duk_tval *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) \\\n\t))\n#define DUK_HOBJECT_H_GET_BASE(heap,h) \\\n\t((duk_uint32_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \\\n\t( \\\n\t\t(n_ent) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t(n_arr) * sizeof(duk_tval) + \\\n\t\t(n_hash) * sizeof(duk_uint32_t) \\\n\t)\n#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash)  do { \\\n\t\t(set_e_k) = (duk_hstring **) (void *) (p_base); \\\n\t\t(set_e_pv) = (duk_propvalue *) (void *) ((set_e_k) + (n_ent)); \\\n\t\t(set_e_f) = (duk_uint8_t *) (void *) ((set_e_pv) + (n_ent)); \\\n\t\t(set_a) = (duk_tval *) (void *) ((set_e_f) + (n_ent)); \\\n\t\t(set_h) = (duk_uint32_t *) (void *) ((set_a) + (n_arr)); \\\n\t} while (0)\n#elif defined(DUK_USE_HOBJECT_LAYOUT_2)\n/* LAYOUT 2 */\n#if (DUK_USE_ALIGN_BY == 4)\n#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) ((4 - (e_sz)) & 0x03)\n#elif (DUK_USE_ALIGN_BY == 8)\n#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) ((8 - (e_sz)) & 0x07)\n#elif (DUK_USE_ALIGN_BY == 1)\n#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) 0\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \\\n\t((duk_hstring **) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) \\\n\t))\n#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \\\n\t((duk_propvalue *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) \\\n\t))\n#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \\\n\t((duk_uint8_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \\\n\t))\n#define DUK_HOBJECT_A_GET_BASE(heap,h) \\\n\t((duk_tval *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t\tDUK_HOBJECT_E_FLAG_PADDING(DUK_HOBJECT_GET_ESIZE((h))) \\\n\t))\n#define DUK_HOBJECT_H_GET_BASE(heap,h) \\\n\t((duk_uint32_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t\tDUK_HOBJECT_E_FLAG_PADDING(DUK_HOBJECT_GET_ESIZE((h))) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \\\n\t( \\\n\t\t(n_ent) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\tDUK_HOBJECT_E_FLAG_PADDING((n_ent)) + \\\n\t\t(n_arr) * sizeof(duk_tval) + \\\n\t\t(n_hash) * sizeof(duk_uint32_t) \\\n\t)\n#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash)  do { \\\n\t\t(set_e_pv) = (duk_propvalue *) (void *) (p_base); \\\n\t\t(set_e_k) = (duk_hstring **) (void *) ((set_e_pv) + (n_ent)); \\\n\t\t(set_e_f) = (duk_uint8_t *) (void *) ((set_e_k) + (n_ent)); \\\n\t\t(set_a) = (duk_tval *) (void *) (((duk_uint8_t *) (set_e_f)) + \\\n\t\t                                 sizeof(duk_uint8_t) * (n_ent) + \\\n\t\t                                 DUK_HOBJECT_E_FLAG_PADDING((n_ent))); \\\n\t\t(set_h) = (duk_uint32_t *) (void *) ((set_a) + (n_arr)); \\\n\t} while (0)\n#elif defined(DUK_USE_HOBJECT_LAYOUT_3)\n/* LAYOUT 3 */\n#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \\\n\t((duk_hstring **) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \\\n\t((duk_propvalue *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) \\\n\t))\n#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \\\n\t((duk_uint8_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_propvalue) + sizeof(duk_hstring *)) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) + \\\n\t\t\tDUK_HOBJECT_GET_HSIZE((h)) * sizeof(duk_uint32_t) \\\n\t))\n#define DUK_HOBJECT_A_GET_BASE(heap,h) \\\n\t((duk_tval *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) \\\n\t))\n#define DUK_HOBJECT_H_GET_BASE(heap,h) \\\n\t((duk_uint32_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_propvalue) + sizeof(duk_hstring *)) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \\\n\t( \\\n\t\t(n_ent) * (sizeof(duk_propvalue) + sizeof(duk_hstring *) + sizeof(duk_uint8_t)) + \\\n\t\t(n_arr) * sizeof(duk_tval) + \\\n\t\t(n_hash) * sizeof(duk_uint32_t) \\\n\t)\n#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash)  do { \\\n\t\t(set_e_pv) = (duk_propvalue *) (void *) (p_base); \\\n\t\t(set_a) = (duk_tval *) (void *) ((set_e_pv) + (n_ent)); \\\n\t\t(set_e_k) = (duk_hstring **) (void *) ((set_a) + (n_arr)); \\\n\t\t(set_h) = (duk_uint32_t *) (void *) ((set_e_k) + (n_ent)); \\\n\t\t(set_e_f) = (duk_uint8_t *) (void *) ((set_h) + (n_hash)); \\\n\t} while (0)\n#else\n#error invalid hobject layout defines\n#endif  /* hobject property layout */\n\n#define DUK_HOBJECT_P_ALLOC_SIZE(h) \\\n\tDUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE((h)), DUK_HOBJECT_GET_ASIZE((h)), DUK_HOBJECT_GET_HSIZE((h)))\n\n#define DUK_HOBJECT_E_GET_KEY(heap,h,i)              (DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_KEY_PTR(heap,h,i)          (&DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_VALUE(heap,h,i)            (DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_VALUE_PTR(heap,h,i)        (&DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_VALUE_TVAL(heap,h,i)       (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)\n#define DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap,h,i)   (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)\n#define DUK_HOBJECT_E_GET_VALUE_GETTER(heap,h,i)     (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)\n#define DUK_HOBJECT_E_GET_VALUE_GETTER_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)\n#define DUK_HOBJECT_E_GET_VALUE_SETTER(heap,h,i)     (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)\n#define DUK_HOBJECT_E_GET_VALUE_SETTER_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)\n#define DUK_HOBJECT_E_GET_FLAGS(heap,h,i)            (DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_FLAGS_PTR(heap,h,i)        (&DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_A_GET_VALUE(heap,h,i)            (DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_A_GET_VALUE_PTR(heap,h,i)        (&DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_H_GET_INDEX(heap,h,i)            (DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_H_GET_INDEX_PTR(heap,h,i)        (&DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])\n\n#define DUK_HOBJECT_E_SET_KEY(heap,h,i,k)  do { \\\n\t\tDUK_HOBJECT_E_GET_KEY((heap), (h), (i)) = (k); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)) = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE_TVAL(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE_GETTER(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE_SETTER(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_FLAGS(heap,h,i,f)  do { \\\n\t\tDUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) = (duk_uint8_t) (f); \\\n\t} while (0)\n#define DUK_HOBJECT_A_SET_VALUE(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_A_GET_VALUE((heap), (h), (i)) = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_A_SET_VALUE_TVAL(heap,h,i,v) \\\n\tDUK_HOBJECT_A_SET_VALUE((heap), (h), (i), (v))  /* alias for above */\n#define DUK_HOBJECT_H_SET_INDEX(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_H_GET_INDEX((heap), (h), (i)) = (v); \\\n\t} while (0)\n\n#define DUK_HOBJECT_E_SET_FLAG_BITS(heap,h,i,mask)  do { \\\n\t\tDUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] |= (mask); \\\n\t} while (0)\n\n#define DUK_HOBJECT_E_CLEAR_FLAG_BITS(heap,h,i,mask)  do { \\\n\t\tDUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] &= ~(mask); \\\n\t} while (0)\n\n#define DUK_HOBJECT_E_SLOT_IS_WRITABLE(heap,h,i)     ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_WRITABLE) != 0)\n#define DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(heap,h,i)   ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)\n#define DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)\n#define DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap,h,i)     ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ACCESSOR) != 0)\n\n#define DUK_HOBJECT_E_SLOT_SET_WRITABLE(heap,h,i)        DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)\n#define DUK_HOBJECT_E_SLOT_SET_ENUMERABLE(heap,h,i)      DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_HOBJECT_E_SLOT_SET_CONFIGURABLE(heap,h,i)    DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_HOBJECT_E_SLOT_SET_ACCESSOR(heap,h,i)        DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)\n\n#define DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(heap,h,i)      DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)\n#define DUK_HOBJECT_E_SLOT_CLEAR_ENUMERABLE(heap,h,i)    DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_HOBJECT_E_SLOT_CLEAR_CONFIGURABLE(heap,h,i)  DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(heap,h,i)      DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)\n\n#define DUK_PROPDESC_IS_WRITABLE(p)             (((p)->flags & DUK_PROPDESC_FLAG_WRITABLE) != 0)\n#define DUK_PROPDESC_IS_ENUMERABLE(p)           (((p)->flags & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)\n#define DUK_PROPDESC_IS_CONFIGURABLE(p)         (((p)->flags & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)\n#define DUK_PROPDESC_IS_ACCESSOR(p)             (((p)->flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0)\n\n#define DUK_HOBJECT_HASHIDX_UNUSED              0xffffffffUL\n#define DUK_HOBJECT_HASHIDX_DELETED             0xfffffffeUL\n\n/*\n *  Macros for accessing size fields\n */\n\n#if defined(DUK_USE_OBJSIZES16)\n#define DUK_HOBJECT_GET_ESIZE(h) ((h)->e_size16)\n#define DUK_HOBJECT_SET_ESIZE(h,v) do { (h)->e_size16 = (v); } while (0)\n#define DUK_HOBJECT_GET_ENEXT(h) ((h)->e_next16)\n#define DUK_HOBJECT_SET_ENEXT(h,v) do { (h)->e_next16 = (v); } while (0)\n#define DUK_HOBJECT_POSTINC_ENEXT(h) ((h)->e_next16++)\n#define DUK_HOBJECT_GET_ASIZE(h) ((h)->a_size16)\n#define DUK_HOBJECT_SET_ASIZE(h,v) do { (h)->a_size16 = (v); } while (0)\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n#define DUK_HOBJECT_GET_HSIZE(h) ((h)->h_size16)\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { (h)->h_size16 = (v); } while (0)\n#else\n#define DUK_HOBJECT_GET_HSIZE(h) 0\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { DUK_ASSERT((v) == 0); } while (0)\n#endif\n#else\n#define DUK_HOBJECT_GET_ESIZE(h) ((h)->e_size)\n#define DUK_HOBJECT_SET_ESIZE(h,v) do { (h)->e_size = (v); } while (0)\n#define DUK_HOBJECT_GET_ENEXT(h) ((h)->e_next)\n#define DUK_HOBJECT_SET_ENEXT(h,v) do { (h)->e_next = (v); } while (0)\n#define DUK_HOBJECT_POSTINC_ENEXT(h) ((h)->e_next++)\n#define DUK_HOBJECT_GET_ASIZE(h) ((h)->a_size)\n#define DUK_HOBJECT_SET_ASIZE(h,v) do { (h)->a_size = (v); } while (0)\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n#define DUK_HOBJECT_GET_HSIZE(h) ((h)->h_size)\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { (h)->h_size = (v); } while (0)\n#else\n#define DUK_HOBJECT_GET_HSIZE(h) 0\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { DUK_ASSERT((v) == 0); } while (0)\n#endif\n#endif\n\n/*\n *  Misc\n */\n\n/* Maximum prototype traversal depth.  Sanity limit which handles e.g.\n * prototype loops (even complex ones like 1->2->3->4->2->3->4->2->3->4).\n */\n#define DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY      10000L\n\n/*\n *  ECMAScript [[Class]]\n */\n\n/* range check not necessary because all 4-bit values are mapped */\n#define DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(n)  duk_class_number_to_stridx[(n)]\n\n#define DUK_HOBJECT_GET_CLASS_STRING(heap,h)          \\\n\tDUK_HEAP_GET_STRING( \\\n\t\t(heap), \\\n\t\tDUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(DUK_HOBJECT_GET_CLASS_NUMBER((h))) \\\n\t)\n\n/*\n *  Macros for property handling\n */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HOBJECT_GET_PROTOTYPE(heap,h) \\\n\t((duk_hobject *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->prototype16))\n#define DUK_HOBJECT_SET_PROTOTYPE(heap,h,x) do { \\\n\t\t(h)->prototype16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \\\n\t} while (0)\n#else\n#define DUK_HOBJECT_GET_PROTOTYPE(heap,h) \\\n\t((h)->prototype)\n#define DUK_HOBJECT_SET_PROTOTYPE(heap,h,x) do { \\\n\t\t(h)->prototype = (x); \\\n\t} while (0)\n#endif\n\n/* Set prototype, DECREF earlier value, INCREF new value (tolerating NULLs). */\n#define DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr,h,p)       duk_hobject_set_prototype_updref((thr), (h), (p))\n\n/* Set initial prototype, assume NULL previous prototype, INCREF new value,\n * tolerate NULL.\n */\n#define DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr,h,proto) do { \\\n\t\tduk_hthread *duk__thr = (thr); \\\n\t\tduk_hobject *duk__obj = (h); \\\n\t\tduk_hobject *duk__proto = (proto); \\\n\t\tDUK_UNREF(duk__thr); \\\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(duk__thr->heap, duk__obj) == NULL); \\\n\t\tDUK_HOBJECT_SET_PROTOTYPE(duk__thr->heap, duk__obj, duk__proto); \\\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(duk__thr, duk__proto); \\\n\t} while (0)\n\n/*\n *  Finalizer check\n */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HOBJECT_HAS_FINALIZER_FAST(heap,h) duk_hobject_has_finalizer_fast_raw((heap), (h))\n#else\n#define DUK_HOBJECT_HAS_FINALIZER_FAST(heap,h) duk_hobject_has_finalizer_fast_raw((h))\n#endif\n\n/*\n *  Resizing and hash behavior\n */\n\n/* Sanity limit on max number of properties (allocated, not necessarily used).\n * This is somewhat arbitrary, but if we're close to 2**32 properties some\n * algorithms will fail (e.g. hash size selection, next prime selection).\n * Also, we use negative array/entry table indices to indicate 'not found',\n * so anything above 0x80000000 will cause trouble now.\n */\n#if defined(DUK_USE_OBJSIZES16)\n#define DUK_HOBJECT_MAX_PROPERTIES       0x0000ffffUL\n#else\n#define DUK_HOBJECT_MAX_PROPERTIES       0x3fffffffUL   /* 2**30-1 ~= 1G properties */\n#endif\n\n/* internal align target for props allocation, must be 2*n for some n */\n#if (DUK_USE_ALIGN_BY == 4)\n#define DUK_HOBJECT_ALIGN_TARGET         4\n#elif (DUK_USE_ALIGN_BY == 8)\n#define DUK_HOBJECT_ALIGN_TARGET         8\n#elif (DUK_USE_ALIGN_BY == 1)\n#define DUK_HOBJECT_ALIGN_TARGET         1\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\n/*\n *  PC-to-line constants\n */\n\n#define DUK_PC2LINE_SKIP    64\n\n/* maximum length for a SKIP-1 diffstream: 35 bits per entry, rounded up to bytes */\n#define DUK_PC2LINE_MAX_DIFF_LENGTH    (((DUK_PC2LINE_SKIP - 1) * 35 + 7) / 8)\n\n/*\n *  Struct defs\n */\n\nstruct duk_propaccessor {\n\tduk_hobject *get;\n\tduk_hobject *set;\n};\n\nunion duk_propvalue {\n\t/* The get/set pointers could be 16-bit pointer compressed but it\n\t * would make no difference on 32-bit platforms because duk_tval is\n\t * 8 bytes or more anyway.\n\t */\n\tduk_tval v;\n\tduk_propaccessor a;\n};\n\nstruct duk_propdesc {\n\t/* read-only values 'lifted' for ease of use */\n\tduk_small_uint_t flags;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\n\t/* for updating (all are set to < 0 for virtual properties) */\n\tduk_int_t e_idx;  /* prop index in 'entry part', < 0 if not there */\n\tduk_int_t h_idx;  /* prop index in 'hash part', < 0 if not there */\n\tduk_int_t a_idx;  /* prop index in 'array part', < 0 if not there */\n};\n\nstruct duk_hobject {\n\tduk_heaphdr hdr;\n\n\t/*\n\t *  'props' contains {key,value,flags} entries, optional array entries, and\n\t *  an optional hash lookup table for non-array entries in a single 'sliced'\n\t *  allocation.  There are several layout options, which differ slightly in\n\t *  generated code size/speed and alignment/padding; duk_features.h selects\n\t *  the layout used.\n\t *\n\t *  Layout 1 (DUK_USE_HOBJECT_LAYOUT_1):\n\t *\n\t *    e_size * sizeof(duk_hstring *)         bytes of   entry keys (e_next gc reachable)\n\t *    e_size * sizeof(duk_propvalue)         bytes of   entry values (e_next gc reachable)\n\t *    e_size * sizeof(duk_uint8_t)           bytes of   entry flags (e_next gc reachable)\n\t *    a_size * sizeof(duk_tval)              bytes of   (opt) array values (plain only) (all gc reachable)\n\t *    h_size * sizeof(duk_uint32_t)          bytes of   (opt) hash indexes to entries (e_size),\n\t *                                                      0xffffffffUL = unused, 0xfffffffeUL = deleted\n\t *\n\t *  Layout 2 (DUK_USE_HOBJECT_LAYOUT_2):\n\t *\n\t *    e_size * sizeof(duk_propvalue)         bytes of   entry values (e_next gc reachable)\n\t *    e_size * sizeof(duk_hstring *)         bytes of   entry keys (e_next gc reachable)\n\t *    e_size * sizeof(duk_uint8_t) + pad     bytes of   entry flags (e_next gc reachable)\n\t *    a_size * sizeof(duk_tval)              bytes of   (opt) array values (plain only) (all gc reachable)\n\t *    h_size * sizeof(duk_uint32_t)          bytes of   (opt) hash indexes to entries (e_size),\n\t *                                                      0xffffffffUL = unused, 0xfffffffeUL = deleted\n\t *\n\t *  Layout 3 (DUK_USE_HOBJECT_LAYOUT_3):\n\t *\n\t *    e_size * sizeof(duk_propvalue)         bytes of   entry values (e_next gc reachable)\n\t *    a_size * sizeof(duk_tval)              bytes of   (opt) array values (plain only) (all gc reachable)\n\t *    e_size * sizeof(duk_hstring *)         bytes of   entry keys (e_next gc reachable)\n\t *    h_size * sizeof(duk_uint32_t)          bytes of   (opt) hash indexes to entries (e_size),\n\t *                                                      0xffffffffUL = unused, 0xfffffffeUL = deleted\n\t *    e_size * sizeof(duk_uint8_t)           bytes of   entry flags (e_next gc reachable)\n\t *\n\t *  In layout 1, the 'e_next' count is rounded to 4 or 8 on platforms\n\t *  requiring 4 or 8 byte alignment.  This ensures proper alignment\n\t *  for the entries, at the cost of memory footprint.  However, it's\n\t *  probably preferable to use another layout on such platforms instead.\n\t *\n\t *  In layout 2, the key and value parts are swapped to avoid padding\n\t *  the key array on platforms requiring alignment by 8.  The flags part\n\t *  is padded to get alignment for array entries.  The 'e_next' count does\n\t *  not need to be rounded as in layout 1.\n\t *\n\t *  In layout 3, entry values and array values are always aligned properly,\n\t *  and assuming pointers are at most 8 bytes, so are the entry keys.  Hash\n\t *  indices will be properly aligned (assuming pointers are at least 4 bytes).\n\t *  Finally, flags don't need additional alignment.  This layout provides\n\t *  compact allocations without padding (even on platforms with alignment\n\t *  requirements) at the cost of a bit slower lookups.\n\t *\n\t *  Objects with few keys don't have a hash index; keys are looked up linearly,\n\t *  which is cache efficient because the keys are consecutive.  Larger objects\n\t *  have a hash index part which contains integer indexes to the entries part.\n\t *\n\t *  A single allocation reduces memory allocation overhead but requires more\n\t *  work when any part needs to be resized.  A sliced allocation for entries\n\t *  makes linear key matching faster on most platforms (more locality) and\n\t *  skimps on flags size (which would be followed by 3 bytes of padding in\n\t *  most architectures if entries were placed in a struct).\n\t *\n\t *  'props' also contains internal properties distinguished with a non-BMP\n\t *  prefix.  Often used properties should be placed early in 'props' whenever\n\t *  possible to make accessing them as fast a possible.\n\t */\n\n#if defined(DUK_USE_HEAPPTR16)\n\t/* Located in duk_heaphdr h_extra16.  Subclasses of duk_hobject (like\n\t * duk_hcompfunc) are not free to use h_extra16 for this reason.\n\t */\n#else\n\tduk_uint8_t *props;\n#endif\n\n\t/* prototype: the only internal property lifted outside 'e' as it is so central */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t prototype16;\n#else\n\tduk_hobject *prototype;\n#endif\n\n#if defined(DUK_USE_OBJSIZES16)\n\tduk_uint16_t e_size16;\n\tduk_uint16_t e_next16;\n\tduk_uint16_t a_size16;\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tduk_uint16_t h_size16;\n#endif\n#else\n\tduk_uint32_t e_size;  /* entry part size */\n\tduk_uint32_t e_next;  /* index for next new key ([0,e_next[ are gc reachable) */\n\tduk_uint32_t a_size;  /* array part size (entirely gc reachable) */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tduk_uint32_t h_size;  /* hash part size or 0 if unused */\n#endif\n#endif\n};\n\n/*\n *  Exposed data\n */\n\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL duk_uint8_t duk_class_number_to_stridx[32];\n#endif  /* !DUK_SINGLE_FILE */\n\n/*\n *  Prototypes\n */\n\n/* alloc and init */\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_harray *duk_harray_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_hcompfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_hnatfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hboundfunc *duk_hboundfunc_alloc(duk_heap *heap, duk_uint_t hobject_flags);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL_DECL duk_hbufobj *duk_hbufobj_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\n#endif\nDUK_INTERNAL_DECL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hthread *duk_hthread_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hdecenv *duk_hdecenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hobjenv *duk_hobjenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hproxy *duk_hproxy_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\n\n/* resize */\nDUK_INTERNAL_DECL void duk_hobject_realloc_props(duk_hthread *thr,\n                                                 duk_hobject *obj,\n                                                 duk_uint32_t new_e_size,\n                                                 duk_uint32_t new_a_size,\n                                                 duk_uint32_t new_h_size,\n                                                 duk_bool_t abandon_array);\nDUK_INTERNAL_DECL void duk_hobject_resize_entrypart(duk_hthread *thr,\n                                                    duk_hobject *obj,\n                                                    duk_uint32_t new_e_size);\n#if 0  /*unused*/\nDUK_INTERNAL_DECL void duk_hobject_resize_arraypart(duk_hthread *thr,\n                                                    duk_hobject *obj,\n                                                    duk_uint32_t new_a_size);\n#endif\n\n/* low-level property functions */\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_find_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_get_own_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags);\n\n/* core property functions */\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_tval *tv_val, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key);\n\n/* internal property functions */\n#define DUK_DELPROP_FLAG_THROW  (1U << 0)\n#define DUK_DELPROP_FLAG_FORCE  (1U << 1)\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key);\nDUK_INTERNAL_DECL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags);\nDUK_INTERNAL_DECL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj);\n#if defined(DUK_USE_HEAPPTR16)\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_heap *heap, duk_hobject *obj);\n#else\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_hobject *obj);\n#endif\n\n/* helpers for defineProperty() and defineProperties() */\nDUK_INTERNAL_DECL void duk_hobject_prepare_property_descriptor(duk_hthread *thr,\n                                                               duk_idx_t idx_in,\n                                                               duk_uint_t *out_defprop_flags,\n                                                               duk_idx_t *out_idx_value,\n                                                               duk_hobject **out_getter,\n                                                               duk_hobject **out_setter);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,\n                                                                duk_uint_t defprop_flags,\n                                                                duk_hobject *obj,\n                                                                duk_hstring *key,\n                                                                duk_idx_t idx_value,\n                                                                duk_hobject *get,\n                                                                duk_hobject *set,\n                                                                duk_bool_t throw_flag);\n\n/* Object built-in methods */\nDUK_INTERNAL_DECL void duk_hobject_object_get_own_property_descriptor(duk_hthread *thr, duk_idx_t obj_idx);\nDUK_INTERNAL_DECL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_object_ownprop_helper(duk_hthread *thr, duk_small_uint_t required_desc_flags);\n\n/* internal properties */\nDUK_INTERNAL_DECL duk_tval *duk_hobject_get_internal_value_tval_ptr(duk_heap *heap, duk_hobject *obj);\nDUK_INTERNAL_DECL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *heap, duk_hobject *obj);\nDUK_INTERNAL_DECL duk_harray *duk_hobject_get_formals(duk_hthread *thr, duk_hobject *obj);\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_get_varmap(duk_hthread *thr, duk_hobject *obj);\n\n/* hobject management functions */\nDUK_INTERNAL_DECL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj);\n\n/* ES2015 proxy */\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_proxy_check(duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler);\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_resolve_proxy_target(duk_hobject *obj);\n#endif\n\n/* enumeration */\nDUK_INTERNAL_DECL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint_t enum_flags);\nDUK_INTERNAL_DECL duk_ret_t duk_hobject_get_enumerated_keys(duk_hthread *thr, duk_small_uint_t enum_flags);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_enumerator_next(duk_hthread *thr, duk_bool_t get_value);\n\n/* macros */\nDUK_INTERNAL_DECL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject *h, duk_hobject *p);\n\n/* pc2line */\n#if defined(DUK_USE_PC2LINE)\nDUK_INTERNAL_DECL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr *instrs, duk_uint_fast32_t length);\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_hobject_pc2line_query(duk_hthread *thr, duk_idx_t idx_func, duk_uint_fast32_t pc);\n#endif\n\n/* misc */\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, duk_hobject *h, duk_hobject *p, duk_bool_t ignore_loop);\n\n#if !defined(DUK_USE_OBJECT_BUILTIN)\n/* These declarations are needed when related built-in is disabled and\n * genbuiltins.py won't automatically emit the declerations.\n */\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_string(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_hthread *thr);\n#endif\n\n#endif  /* DUK_HOBJECT_H_INCLUDED */\n/* #include duk_hcompfunc.h */\n#line 1 \"duk_hcompfunc.h\"\n/*\n *  Heap compiled function (ECMAScript function) representation.\n *\n *  There is a single data buffer containing the ECMAScript function's\n *  bytecode, constants, and inner functions.\n */\n\n#if !defined(DUK_HCOMPFUNC_H_INCLUDED)\n#define DUK_HCOMPFUNC_H_INCLUDED\n\n/*\n *  Field accessor macros\n */\n\n/* XXX: casts could be improved, especially for GET/SET DATA */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HCOMPFUNC_GET_DATA(heap,h) \\\n\t((duk_hbuffer_fixed *) (void *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->data16))\n#define DUK_HCOMPFUNC_SET_DATA(heap,h,v) do { \\\n\t\t(h)->data16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_FUNCS(heap,h)  \\\n\t((duk_hobject **) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->funcs16)))\n#define DUK_HCOMPFUNC_SET_FUNCS(heap,h,v)  do { \\\n\t\t(h)->funcs16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_BYTECODE(heap,h)  \\\n\t((duk_instr_t *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->bytecode16)))\n#define DUK_HCOMPFUNC_SET_BYTECODE(heap,h,v)  do { \\\n\t\t(h)->bytecode16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_LEXENV(heap,h)  \\\n\t((duk_hobject *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->lex_env16)))\n#define DUK_HCOMPFUNC_SET_LEXENV(heap,h,v)  do { \\\n\t\t(h)->lex_env16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_VARENV(heap,h)  \\\n\t((duk_hobject *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->var_env16)))\n#define DUK_HCOMPFUNC_SET_VARENV(heap,h,v)  do { \\\n\t\t(h)->var_env16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#else\n#define DUK_HCOMPFUNC_GET_DATA(heap,h)  ((duk_hbuffer_fixed *) (void *) (h)->data)\n#define DUK_HCOMPFUNC_SET_DATA(heap,h,v) do { \\\n\t\t(h)->data = (duk_hbuffer *) (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_FUNCS(heap,h)  ((h)->funcs)\n#define DUK_HCOMPFUNC_SET_FUNCS(heap,h,v)  do { \\\n\t\t(h)->funcs = (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_BYTECODE(heap,h)  ((h)->bytecode)\n#define DUK_HCOMPFUNC_SET_BYTECODE(heap,h,v)  do { \\\n\t\t(h)->bytecode = (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_LEXENV(heap,h)  ((h)->lex_env)\n#define DUK_HCOMPFUNC_SET_LEXENV(heap,h,v)  do { \\\n\t\t(h)->lex_env = (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_VARENV(heap,h)  ((h)->var_env)\n#define DUK_HCOMPFUNC_SET_VARENV(heap,h,v)  do { \\\n\t\t(h)->var_env = (v); \\\n\t} while (0)\n#endif\n\n/*\n *  Accessor macros for function specific data areas\n */\n\n/* Note: assumes 'data' is always a fixed buffer */\n#define DUK_HCOMPFUNC_GET_BUFFER_BASE(heap,h)  \\\n\tDUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPFUNC_GET_DATA((heap), (h)))\n\n#define DUK_HCOMPFUNC_GET_CONSTS_BASE(heap,h)  \\\n\t((duk_tval *) (void *) DUK_HCOMPFUNC_GET_BUFFER_BASE((heap), (h)))\n\n#define DUK_HCOMPFUNC_GET_FUNCS_BASE(heap,h)  \\\n\tDUK_HCOMPFUNC_GET_FUNCS((heap), (h))\n\n#define DUK_HCOMPFUNC_GET_CODE_BASE(heap,h)  \\\n\tDUK_HCOMPFUNC_GET_BYTECODE((heap), (h))\n\n#define DUK_HCOMPFUNC_GET_CONSTS_END(heap,h)  \\\n\t((duk_tval *) (void *) DUK_HCOMPFUNC_GET_FUNCS((heap), (h)))\n\n#define DUK_HCOMPFUNC_GET_FUNCS_END(heap,h)  \\\n\t((duk_hobject **) (void *) DUK_HCOMPFUNC_GET_BYTECODE((heap), (h)))\n\n/* XXX: double evaluation of DUK_HCOMPFUNC_GET_DATA() */\n#define DUK_HCOMPFUNC_GET_CODE_END(heap,h)  \\\n\t((duk_instr_t *) (void *) (DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPFUNC_GET_DATA((heap), (h))) + \\\n\t                DUK_HBUFFER_GET_SIZE((duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA((heap), h))))\n\n#define DUK_HCOMPFUNC_GET_CONSTS_SIZE(heap,h)  \\\n\t( \\\n\t (duk_size_t) \\\n\t ( \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CONSTS_END((heap), (h))) - \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CONSTS_BASE((heap), (h))) \\\n\t ) \\\n\t)\n\n#define DUK_HCOMPFUNC_GET_FUNCS_SIZE(heap,h)  \\\n\t( \\\n\t (duk_size_t) \\\n\t ( \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_FUNCS_END((heap), (h))) - \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_FUNCS_BASE((heap), (h))) \\\n\t ) \\\n\t)\n\n#define DUK_HCOMPFUNC_GET_CODE_SIZE(heap,h)  \\\n\t( \\\n\t (duk_size_t) \\\n\t ( \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CODE_END((heap),(h))) - \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CODE_BASE((heap),(h))) \\\n\t ) \\\n\t)\n\n#define DUK_HCOMPFUNC_GET_CONSTS_COUNT(heap,h)  \\\n\t((duk_size_t) (DUK_HCOMPFUNC_GET_CONSTS_SIZE((heap), (h)) / sizeof(duk_tval)))\n\n#define DUK_HCOMPFUNC_GET_FUNCS_COUNT(heap,h)  \\\n\t((duk_size_t) (DUK_HCOMPFUNC_GET_FUNCS_SIZE((heap), (h)) / sizeof(duk_hobject *)))\n\n#define DUK_HCOMPFUNC_GET_CODE_COUNT(heap,h)  \\\n\t((duk_size_t) (DUK_HCOMPFUNC_GET_CODE_SIZE((heap), (h)) / sizeof(duk_instr_t)))\n\n/*\n *  Validity assert\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hcompfunc_assert_valid(duk_hcompfunc *h);\n#define DUK_HCOMPFUNC_ASSERT_VALID(h)  do { duk_hcompfunc_assert_valid((h)); } while (0)\n#else\n#define DUK_HCOMPFUNC_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Main struct\n */\n\nstruct duk_hcompfunc {\n\t/* shared object part */\n\tduk_hobject obj;\n\n\t/*\n\t *  Pointers to function data area for faster access.  Function\n\t *  data is a buffer shared between all closures of the same\n\t *  \"template\" function.  The data buffer is always fixed (non-\n\t *  dynamic, hence stable), with a layout as follows:\n\t *\n\t *    constants (duk_tval)\n\t *    inner functions (duk_hobject *)\n\t *    bytecode (duk_instr_t)\n\t *\n\t *  Note: bytecode end address can be computed from 'data' buffer\n\t *  size.  It is not strictly necessary functionally, assuming\n\t *  bytecode never jumps outside its allocated area.  However,\n\t *  it's a safety/robustness feature for avoiding the chance of\n\t *  executing random data as bytecode due to a compiler error.\n\t *\n\t *  Note: values in the data buffer must be incref'd (they will\n\t *  be decref'd on release) for every compiledfunction referring\n\t *  to the 'data' element.\n\t */\n\n\t/* Data area, fixed allocation, stable data ptrs. */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t data16;\n#else\n\tduk_hbuffer *data;\n#endif\n\n\t/* No need for constants pointer (= same as data).\n\t *\n\t * When using 16-bit packing alignment to 4 is nice.  'funcs' will be\n\t * 4-byte aligned because 'constants' are duk_tvals.  For now the\n\t * inner function pointers are not compressed, so that 'bytecode' will\n\t * also be 4-byte aligned.\n\t */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t funcs16;\n\tduk_uint16_t bytecode16;\n#else\n\tduk_hobject **funcs;\n\tduk_instr_t *bytecode;\n#endif\n\n\t/* Lexenv: lexical environment of closure, NULL for templates.\n\t * Varenv: variable environment of closure, NULL for templates.\n\t */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t lex_env16;\n\tduk_uint16_t var_env16;\n#else\n\tduk_hobject *lex_env;\n\tduk_hobject *var_env;\n#endif\n\n\t/*\n\t *  'nregs' registers are allocated on function entry, at most 'nargs'\n\t *  are initialized to arguments, and the rest to undefined.  Arguments\n\t *  above 'nregs' are not mapped to registers.  All registers in the\n\t *  active stack range must be initialized because they are GC reachable.\n\t *  'nargs' is needed so that if the function is given more than 'nargs'\n\t *  arguments, the additional arguments do not 'clobber' registers\n\t *  beyond 'nregs' which must be consistently initialized to undefined.\n\t *\n\t *  Usually there is no need to know which registers are mapped to\n\t *  local variables.  Registers may be allocated to variable in any\n\t *  way (even including gaps).  However, a register-variable mapping\n\t *  must be the same for the duration of the function execution and\n\t *  the register cannot be used for anything else.\n\t *\n\t *  When looking up variables by name, the '_Varmap' map is used.\n\t *  When an activation closes, registers mapped to arguments are\n\t *  copied into the environment record based on the same map.  The\n\t *  reverse map (from register to variable) is not currently needed\n\t *  at run time, except for debugging, so it is not maintained.\n\t */\n\n\tduk_uint16_t nregs;                /* regs to allocate */\n\tduk_uint16_t nargs;                /* number of arguments allocated to regs */\n\n\t/*\n\t *  Additional control information is placed into the object itself\n\t *  as internal properties to avoid unnecessary fields for the\n\t *  majority of functions.  The compiler tries to omit internal\n\t *  control fields when possible.\n\t *\n\t *  Function templates:\n\t *\n\t *    {\n\t *      name: \"func\",    // declaration, named function expressions\n\t *      fileName: <debug info for creating nice errors>\n\t *      _Varmap: { \"arg1\": 0, \"arg2\": 1, \"varname\": 2 },\n\t *      _Formals: [ \"arg1\", \"arg2\" ],\n\t *      _Source: \"function func(arg1, arg2) { ... }\",\n\t *      _Pc2line: <debug info for pc-to-line mapping>,\n\t *    }\n\t *\n\t *  Function instances:\n\t *\n\t *    {\n\t *      length: 2,\n\t *      prototype: { constructor: <func> },\n\t *      caller: <thrower>,\n\t *      arguments: <thrower>,\n\t *      name: \"func\",    // declaration, named function expressions\n\t *      fileName: <debug info for creating nice errors>\n\t *      _Varmap: { \"arg1\": 0, \"arg2\": 1, \"varname\": 2 },\n\t *      _Formals: [ \"arg1\", \"arg2\" ],\n\t *      _Source: \"function func(arg1, arg2) { ... }\",\n\t *      _Pc2line: <debug info for pc-to-line mapping>,\n\t *    }\n\t *\n\t *  More detailed description of these properties can be found\n\t *  in the documentation.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* Line number range for function.  Needed during debugging to\n\t * determine active breakpoints.\n\t */\n\tduk_uint32_t start_line;\n\tduk_uint32_t end_line;\n#endif\n};\n\n#endif  /* DUK_HCOMPFUNC_H_INCLUDED */\n/* #include duk_hnatfunc.h */\n#line 1 \"duk_hnatfunc.h\"\n/*\n *  Heap native function representation.\n */\n\n#if !defined(DUK_HNATFUNC_H_INCLUDED)\n#define DUK_HNATFUNC_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hnatfunc_assert_valid(duk_hnatfunc *h);\n#define DUK_HNATFUNC_ASSERT_VALID(h)  do { duk_hnatfunc_assert_valid((h)); } while (0)\n#else\n#define DUK_HNATFUNC_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n#define DUK_HNATFUNC_NARGS_VARARGS  ((duk_int16_t) -1)\n#define DUK_HNATFUNC_NARGS_MAX      ((duk_int16_t) 0x7fff)\n\nstruct duk_hnatfunc {\n\t/* shared object part */\n\tduk_hobject obj;\n\n\tduk_c_function func;\n\tduk_int16_t nargs;\n\tduk_int16_t magic;\n\n\t/* The 'magic' field allows an opaque 16-bit field to be accessed by the\n\t * Duktape/C function.  This allows, for instance, the same native function\n\t * to be used for a set of very similar functions, with the 'magic' field\n\t * providing the necessary non-argument flags / values to guide the behavior\n\t * of the native function.  The value is signed on purpose: it is easier to\n\t * convert a signed value to unsigned (simply AND with 0xffff) than vice\n\t * versa.\n\t *\n\t * Note: cannot place nargs/magic into the heaphdr flags, because\n\t * duk_hobject takes almost all flags already.\n\t */\n};\n\n#endif  /* DUK_HNATFUNC_H_INCLUDED */\n/* #include duk_hboundfunc.h */\n#line 1 \"duk_hboundfunc.h\"\n/*\n *  Bound function representation.\n */\n\n#if !defined(DUK_HBOUNDFUNC_H_INCLUDED)\n#define DUK_HBOUNDFUNC_H_INCLUDED\n\n/* Artificial limit for args length.  Ensures arithmetic won't overflow\n * 32 bits when combining bound functions.\n */\n#define DUK_HBOUNDFUNC_MAX_ARGS 0x20000000UL\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hboundfunc_assert_valid(duk_hboundfunc *h);\n#define DUK_HBOUNDFUNC_ASSERT_VALID(h)  do { duk_hboundfunc_assert_valid((h)); } while (0)\n#else\n#define DUK_HBOUNDFUNC_ASSERT_VALID(h)  do {} while (0)\n#endif\n\nstruct duk_hboundfunc {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Final target function, stored as duk_tval so that lightfunc can be\n\t * represented too.\n\t */\n\tduk_tval target;\n\n\t/* This binding. */\n\tduk_tval this_binding;\n\n\t/* Arguments to prepend. */\n\tduk_tval *args;  /* Separate allocation. */\n\tduk_idx_t nargs;\n};\n\n#endif  /* DUK_HBOUNDFUNC_H_INCLUDED */\n/* #include duk_hbufobj.h */\n#line 1 \"duk_hbufobj.h\"\n/*\n *  Heap Buffer object representation.  Used for all Buffer variants.\n */\n\n#if !defined(DUK_HBUFOBJ_H_INCLUDED)\n#define DUK_HBUFOBJ_H_INCLUDED\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\n/* All element accessors are host endian now (driven by TypedArray spec). */\n#define DUK_HBUFOBJ_ELEM_UINT8           0\n#define DUK_HBUFOBJ_ELEM_UINT8CLAMPED    1\n#define DUK_HBUFOBJ_ELEM_INT8            2\n#define DUK_HBUFOBJ_ELEM_UINT16          3\n#define DUK_HBUFOBJ_ELEM_INT16           4\n#define DUK_HBUFOBJ_ELEM_UINT32          5\n#define DUK_HBUFOBJ_ELEM_INT32           6\n#define DUK_HBUFOBJ_ELEM_FLOAT32         7\n#define DUK_HBUFOBJ_ELEM_FLOAT64         8\n#define DUK_HBUFOBJ_ELEM_MAX             8\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hbufobj_assert_valid(duk_hbufobj *h);\n#define DUK_HBUFOBJ_ASSERT_VALID(h)  do { duk_hbufobj_assert_valid((h)); } while (0)\n#else\n#define DUK_HBUFOBJ_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/* Get the current data pointer (caller must ensure buf != NULL) as a\n * duk_uint8_t ptr.  Note that the result may be NULL if the underlying\n * buffer has zero size and is not a fixed buffer.\n */\n#define DUK_HBUFOBJ_GET_SLICE_BASE(heap,h) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t(((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR((heap), (h)->buf)) + (h)->offset))\n\n/* True if slice is full, i.e. offset is zero and length covers the entire\n * buffer.  This status may change independently of the duk_hbufobj if\n * the underlying buffer is dynamic and changes without the hbufobj\n * being changed.\n */\n#define DUK_HBUFOBJ_FULL_SLICE(h) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset == 0 && (h)->length == DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n/* Validate that the whole slice [0,length[ is contained in the underlying\n * buffer.  Caller must ensure 'buf' != NULL.\n */\n#define DUK_HBUFOBJ_VALID_SLICE(h) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset + (h)->length <= DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n/* Validate byte read/write for virtual 'offset', i.e. check that the\n * offset, taking into account h->offset, is within the underlying\n * buffer size.  This is a safety check which is needed to ensure\n * that even a misconfigured duk_hbufobj never causes memory unsafe\n * behavior (e.g. if an underlying dynamic buffer changes after being\n * setup).  Caller must ensure 'buf' != NULL.\n */\n#define DUK_HBUFOBJ_VALID_BYTEOFFSET_INCL(h,off) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset + (off) < DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n#define DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h,off) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset + (off) <= DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n/* Clamp an input byte length (already assumed to be within the nominal\n * duk_hbufobj 'length') to the current dynamic buffer limits to yield\n * a byte length limit that's safe for memory accesses.  This value can\n * be invalidated by any side effect because it may trigger a user\n * callback that resizes the underlying buffer.\n */\n#define DUK_HBUFOBJ_CLAMP_BYTELENGTH(h,len) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), \\\n\tduk_hbufobj_clamp_bytelength((h), (len)))\n\n/* Typed arrays have virtual indices, ArrayBuffer and DataView do not. */\n#define DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h)  ((h)->is_typedarray)\n\nstruct duk_hbufobj {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Underlying buffer (refcounted), may be NULL. */\n\tduk_hbuffer *buf;\n\n\t/* .buffer reference to an ArrayBuffer, may be NULL. */\n\tduk_hobject *buf_prop;\n\n\t/* Slice and accessor information.\n\t *\n\t * Because the underlying buffer may be dynamic, these may be\n\t * invalidated by the buffer being modified so that both offset\n\t * and length should be validated before every access.  Behavior\n\t * when the underlying buffer has changed doesn't need to be clean:\n\t * virtual 'length' doesn't need to be affected, reads can return\n\t * zero/NaN, and writes can be ignored.\n\t *\n\t * Note that a data pointer cannot be precomputed because 'buf' may\n\t * be dynamic and its pointer unstable.\n\t */\n\n\tduk_uint_t offset;       /* byte offset to buf */\n\tduk_uint_t length;       /* byte index limit for element access, exclusive */\n\tduk_uint8_t shift;       /* element size shift:\n\t                          *   0 = u8/i8\n\t                          *   1 = u16/i16\n\t                          *   2 = u32/i32/float\n\t                          *   3 = double\n\t                          */\n\tduk_uint8_t elem_type;   /* element type */\n\tduk_uint8_t is_typedarray;\n};\n\nDUK_INTERNAL_DECL duk_uint_t duk_hbufobj_clamp_bytelength(duk_hbufobj *h_bufobj, duk_uint_t len);\nDUK_INTERNAL_DECL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_hbuffer *h_buf);\nDUK_INTERNAL_DECL void duk_hbufobj_push_validated_read(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);\nDUK_INTERNAL_DECL void duk_hbufobj_validated_write(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);\nDUK_INTERNAL_DECL void duk_hbufobj_promote_plain(duk_hthread *thr, duk_idx_t idx);\n\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* nothing */\n\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n#endif  /* DUK_HBUFOBJ_H_INCLUDED */\n/* #include duk_hthread.h */\n#line 1 \"duk_hthread.h\"\n/*\n *  Heap thread object representation.\n *\n *  duk_hthread is also the 'context' for public API functions via a\n *  different typedef.  Most API calls operate on the topmost frame\n *  of the value stack only.\n */\n\n#if !defined(DUK_HTHREAD_H_INCLUDED)\n#define DUK_HTHREAD_H_INCLUDED\n\n/*\n *  Stack constants\n */\n\n/* Initial valstack size, roughly 0.7kiB. */\n#define DUK_VALSTACK_INITIAL_SIZE       96U\n\n/* Internal extra elements assumed on function entry, always added to\n * user-defined 'extra' for e.g. the duk_check_stack() call.\n */\n#define DUK_VALSTACK_INTERNAL_EXTRA     32U\n\n/* Number of elements guaranteed to be user accessible (in addition to call\n * arguments) on Duktape/C function entry.  This is the major public API\n * commitment.\n */\n#define DUK_VALSTACK_API_ENTRY_MINIMUM  DUK_API_ENTRY_STACK\n\n/*\n *  Activation defines\n */\n\n#define DUK_ACT_FLAG_STRICT             (1U << 0)  /* function executes in strict mode */\n#define DUK_ACT_FLAG_TAILCALLED         (1U << 1)  /* activation has tail called one or more times */\n#define DUK_ACT_FLAG_CONSTRUCT          (1U << 2)  /* function executes as a constructor (called via \"new\") */\n#define DUK_ACT_FLAG_PREVENT_YIELD      (1U << 3)  /* activation prevents yield (native call or \"new\") */\n#define DUK_ACT_FLAG_DIRECT_EVAL        (1U << 4)  /* activation is a direct eval call */\n#define DUK_ACT_FLAG_CONSTRUCT_PROXY    (1U << 5)  /* activation is for Proxy 'construct' call, special return value handling */\n#define DUK_ACT_FLAG_BREAKPOINT_ACTIVE  (1U << 6)  /* activation has active breakpoint(s) */\n\n#define DUK_ACT_GET_FUNC(act)           ((act)->func)\n\n/*\n *  Flags for __FILE__ / __LINE__ registered into tracedata\n */\n\n#define DUK_TB_FLAG_NOBLAME_FILELINE    (1U << 0)  /* don't report __FILE__ / __LINE__ as fileName/lineNumber */\n\n/*\n *  Catcher defines\n */\n\n/* XXX: remove catcher type entirely */\n\n/* flags field: LLLLLLFT, L = label (24 bits), F = flags (4 bits), T = type (4 bits) */\n#define DUK_CAT_TYPE_MASK            0x0000000fUL\n#define DUK_CAT_TYPE_BITS            4\n#define DUK_CAT_LABEL_MASK           0xffffff00UL\n#define DUK_CAT_LABEL_BITS           24\n#define DUK_CAT_LABEL_SHIFT          8\n\n#define DUK_CAT_FLAG_CATCH_ENABLED          (1U << 4)   /* catch part will catch */\n#define DUK_CAT_FLAG_FINALLY_ENABLED        (1U << 5)   /* finally part will catch */\n#define DUK_CAT_FLAG_CATCH_BINDING_ENABLED  (1U << 6)   /* request to create catch binding */\n#define DUK_CAT_FLAG_LEXENV_ACTIVE          (1U << 7)   /* catch or with binding is currently active */\n\n#define DUK_CAT_TYPE_UNKNOWN         0\n#define DUK_CAT_TYPE_TCF             1\n#define DUK_CAT_TYPE_LABEL           2\n\n#define DUK_CAT_GET_TYPE(c)          ((c)->flags & DUK_CAT_TYPE_MASK)\n#define DUK_CAT_GET_LABEL(c)         (((c)->flags & DUK_CAT_LABEL_MASK) >> DUK_CAT_LABEL_SHIFT)\n\n#define DUK_CAT_HAS_CATCH_ENABLED(c)           ((c)->flags & DUK_CAT_FLAG_CATCH_ENABLED)\n#define DUK_CAT_HAS_FINALLY_ENABLED(c)         ((c)->flags & DUK_CAT_FLAG_FINALLY_ENABLED)\n#define DUK_CAT_HAS_CATCH_BINDING_ENABLED(c)   ((c)->flags & DUK_CAT_FLAG_CATCH_BINDING_ENABLED)\n#define DUK_CAT_HAS_LEXENV_ACTIVE(c)           ((c)->flags & DUK_CAT_FLAG_LEXENV_ACTIVE)\n\n#define DUK_CAT_SET_CATCH_ENABLED(c)    do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_CATCH_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_SET_FINALLY_ENABLED(c)  do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_FINALLY_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_SET_CATCH_BINDING_ENABLED(c)    do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_CATCH_BINDING_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_SET_LEXENV_ACTIVE(c)    do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_LEXENV_ACTIVE; \\\n\t} while (0)\n\n#define DUK_CAT_CLEAR_CATCH_ENABLED(c)    do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_CATCH_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_CLEAR_FINALLY_ENABLED(c)  do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_FINALLY_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_CLEAR_CATCH_BINDING_ENABLED(c)    do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_CATCH_BINDING_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_CLEAR_LEXENV_ACTIVE(c)    do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_LEXENV_ACTIVE; \\\n\t} while (0)\n\n/*\n *  Thread defines\n */\n\n#if defined(DUK_USE_ROM_STRINGS)\n#define DUK_HTHREAD_GET_STRING(thr,idx) \\\n\t((duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_stridx[(idx)]))\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HTHREAD_GET_STRING(thr,idx) \\\n\t((duk_hstring *) DUK_USE_HEAPPTR_DEC16((thr)->heap->heap_udata, (thr)->strs16[(idx)]))\n#else\n#define DUK_HTHREAD_GET_STRING(thr,idx) \\\n\t((thr)->strs[(idx)])\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n/* values for the state field */\n#define DUK_HTHREAD_STATE_INACTIVE     1   /* thread not currently running */\n#define DUK_HTHREAD_STATE_RUNNING      2   /* thread currently running (only one at a time) */\n#define DUK_HTHREAD_STATE_RESUMED      3   /* thread resumed another thread (active but not running) */\n#define DUK_HTHREAD_STATE_YIELDED      4   /* thread has yielded */\n#define DUK_HTHREAD_STATE_TERMINATED   5   /* thread has terminated */\n\n/* Executor interrupt default interval when nothing else requires a\n * smaller value.  The default interval must be small enough to allow\n * for reasonable execution timeout checking but large enough to keep\n * impact on execution performance low.\n */\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n#define DUK_HTHREAD_INTCTR_DEFAULT     (256L * 1024L)\n#endif\n\n/*\n *  Assert context is valid: non-NULL pointer, fields look sane.\n *\n *  This is used by public API call entrypoints to catch invalid 'ctx' pointers\n *  as early as possible; invalid 'ctx' pointers cause very odd and difficult to\n *  diagnose behavior so it's worth checking even when the check is not 100%.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n/* Assertions for internals. */\nDUK_INTERNAL_DECL void duk_hthread_assert_valid(duk_hthread *thr);\n#define DUK_HTHREAD_ASSERT_VALID(thr)  do { duk_hthread_assert_valid((thr)); } while (0)\n\n/* Assertions for public API calls; a bit stronger. */\nDUK_INTERNAL_DECL void duk_ctx_assert_valid(duk_hthread *thr);\n#define DUK_CTX_ASSERT_VALID(thr)  do { duk_ctx_assert_valid((thr)); } while (0)\n#else\n#define DUK_HTHREAD_ASSERT_VALID(thr)  do {} while (0)\n#define DUK_CTX_ASSERT_VALID(thr)  do {} while (0)\n#endif\n\n/* Assertions for API call entry specifically.  Checks 'ctx' but also may\n * check internal state (e.g. not in a debugger transport callback).\n */\n#define DUK_ASSERT_API_ENTRY(thr) do { \\\n\t\tDUK_CTX_ASSERT_VALID((thr)); \\\n\t\tDUK_ASSERT((thr)->heap != NULL); \\\n\t\tDUK_ASSERT((thr)->heap->dbg_calling_transport == 0); \\\n\t} while (0)\n\n/*\n *  Assertion helpers.\n */\n\n#define DUK_ASSERT_STRIDX_VALID(val) \\\n\tDUK_ASSERT((duk_uint_t) (val) < DUK_HEAP_NUM_STRINGS)\n\n#define DUK_ASSERT_BIDX_VALID(val) \\\n\tDUK_ASSERT((duk_uint_t) (val) < DUK_NUM_BUILTINS)\n\n/*\n *  Misc\n */\n\n/* Fast access to 'this' binding.  Assumes there's a call in progress. */\n#define DUK_HTHREAD_THIS_PTR(thr) \\\n\t(DUK_ASSERT_EXPR((thr) != NULL), \\\n\t DUK_ASSERT_EXPR((thr)->valstack_bottom > (thr)->valstack), \\\n\t (thr)->valstack_bottom - 1)\n\n/*\n *  Struct defines\n */\n\n/* Fields are ordered for alignment/packing. */\nstruct duk_activation {\n\tduk_tval tv_func;       /* borrowed: full duk_tval for function being executed; for lightfuncs */\n\tduk_hobject *func;      /* borrowed: function being executed; for bound function calls, this is the final, real function, NULL for lightfuncs */\n\tduk_activation *parent; /* previous (parent) activation (or NULL if none) */\n\tduk_hobject *var_env;   /* current variable environment (may be NULL if delayed) */\n\tduk_hobject *lex_env;   /* current lexical environment (may be NULL if delayed) */\n\tduk_catcher *cat;       /* current catcher (or NULL) */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t/* Previous value of 'func' caller, restored when unwound.  Only in use\n\t * when 'func' is non-strict.\n\t */\n\tduk_hobject *prev_caller;\n#endif\n\n\tduk_instr_t *curr_pc;   /* next instruction to execute (points to 'func' bytecode, stable pointer), NULL for native calls */\n\n\t/* bottom_byteoff and retval_byteoff are only used for book-keeping\n\t * of ECMAScript-initiated calls, to allow returning to an ECMAScript\n\t * function properly.\n\t */\n\n\t/* Bottom of valstack for this activation, used to reset\n\t * valstack_bottom on return; offset is absolute.  There's\n\t * no need to track 'top' because native call handling deals\n\t * with that using locals, and for ECMAScript returns 'nregs'\n\t * indicates the necessary top.\n\t */\n\tduk_size_t bottom_byteoff;\n\n\t/* Return value when returning to this activation (points to caller\n\t * reg, not callee reg); offset is absolute (only set if activation is\n\t * not topmost).\n\t *\n\t * Note: bottom_byteoff is always set, while retval_byteoff is only\n\t * applicable for activations below the topmost one.  Currently\n\t * retval_byteoff for the topmost activation is considered garbage\n\t * (and it not initialized on entry or cleared on return; may contain\n\t * previous or garbage values).\n\t */\n\tduk_size_t retval_byteoff;\n\n\t/* Current 'this' binding is the value just below bottom.\n\t * Previously, 'this' binding was handled with an index to the\n\t * (calling) valstack.  This works for everything except tail\n\t * calls, which must not \"accumulate\" valstack temps.\n\t */\n\n\t/* Value stack reserve (valstack_end) byte offset to be restored\n\t * when returning to this activation.  Only used by the bytecode\n\t * executor.\n\t */\n\tduk_size_t reserve_byteoff;\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_uint32_t prev_line; /* needed for stepping */\n#endif\n\n\tduk_small_uint_t flags;\n};\n\nstruct duk_catcher {\n\tduk_catcher *parent;            /* previous (parent) catcher (or NULL if none) */\n\tduk_hstring *h_varname;         /* borrowed reference to catch variable name (or NULL if none) */\n\t                                /* (reference is valid as long activation exists) */\n\tduk_instr_t *pc_base;           /* resume execution from pc_base or pc_base+1 (points to 'func' bytecode, stable pointer) */\n\tduk_size_t idx_base;            /* idx_base and idx_base+1 get completion value and type */\n\tduk_uint32_t flags;             /* type and control flags, label number */\n\t/* XXX: could pack 'flags' and 'idx_base' to same value in practice,\n\t * on 32-bit targets this would make duk_catcher 16 bytes.\n\t */\n};\n\nstruct duk_hthread {\n\t/* Shared object part */\n\tduk_hobject obj;\n\n\t/* Pointer to bytecode executor's 'curr_pc' variable.  Used to copy\n\t * the current PC back into the topmost activation when activation\n\t * state is about to change (or \"syncing\" is otherwise needed).  This\n\t * is rather awkward but important for performance, see execution.rst.\n\t */\n\tduk_instr_t **ptr_curr_pc;\n\n\t/* Backpointers. */\n\tduk_heap *heap;\n\n\t/* Current strictness flag: affects API calls. */\n\tduk_uint8_t strict;\n\n\t/* Thread state. */\n\tduk_uint8_t state;\n\tduk_uint8_t unused1;\n\tduk_uint8_t unused2;\n\n\t/* XXX: Valstack and callstack are currently assumed to have non-NULL\n\t * pointers.  Relaxing this would not lead to big benefits (except\n\t * perhaps for terminated threads).\n\t */\n\n\t/* Value stack: these are expressed as pointers for faster stack\n\t * manipulation.  [valstack,valstack_top[ is GC-reachable,\n\t * [valstack_top,valstack_alloc_end[ is not GC-reachable but kept\n\t * initialized as 'undefined'.  [valstack,valstack_end[ is the\n\t * guaranteed/reserved space and the valstack cannot be resized to\n\t * a smaller size.  [valstack_end,valstack_alloc_end[ is currently\n\t * allocated slack that can be used to grow the current guaranteed\n\t * space but may be shrunk away without notice.\n\t *\n\t *\n\t * <----------------------- guaranteed --->\n\t *                                        <---- slack --->\n\t *               <--- frame --->\n\t * .-------------+=============+----------+--------------.\n\t * |xxxxxxxxxxxxx|yyyyyyyyyyyyy|uuuuuuuuuu|uuuuuuuuuuuuuu|\n\t * `-------------+=============+----------+--------------'\n\t *\n\t * ^             ^             ^          ^              ^\n\t * |             |             |          |              |\n\t * valstack      bottom        top        end            alloc_end\n\t *\n\t *     xxx = arbitrary values, below current frame\n\t *     yyy = arbitrary values, inside current frame\n\t *     uuu = outside active value stack, initialized to 'undefined'\n\t */\n\tduk_tval *valstack;                     /* start of valstack allocation */\n\tduk_tval *valstack_end;                 /* end of valstack reservation/guarantee (exclusive) */\n\tduk_tval *valstack_alloc_end;           /* end of valstack allocation */\n\tduk_tval *valstack_bottom;              /* bottom of current frame */\n\tduk_tval *valstack_top;                 /* top of current frame (exclusive) */\n\n\t/* Call stack, represented as a linked list starting from the current\n\t * activation (or NULL if nothing is active).\n\t */\n\tduk_activation *callstack_curr;         /* current activation (or NULL if none) */\n\tduk_size_t callstack_top;               /* number of activation records in callstack (0 if none) */\n\tduk_size_t callstack_preventcount;      /* number of activation records in callstack preventing a yield */\n\n\t/* Yield/resume book-keeping. */\n\tduk_hthread *resumer;                   /* who resumed us (if any) */\n\n\t/* Current compiler state (if any), used for augmenting SyntaxErrors. */\n\tduk_compiler_ctx *compile_ctx;\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\t/* Interrupt counter for triggering a slow path check for execution\n\t * timeout, debugger interaction such as breakpoints, etc.  The value\n\t * is valid for the current running thread, and both the init and\n\t * counter values are copied whenever a thread switch occurs.  It's\n\t * important for the counter to be conveniently accessible for the\n\t * bytecode executor inner loop for performance reasons.\n\t */\n\tduk_int_t interrupt_counter;    /* countdown state */\n\tduk_int_t interrupt_init;       /* start value for current countdown */\n#endif\n\n\t/* Builtin-objects; may or may not be shared with other threads,\n\t * threads existing in different \"compartments\" will have different\n\t * built-ins.  Must be stored on a per-thread basis because there\n\t * is no intermediate structure for a thread group / compartment.\n\t * This takes quite a lot of space, currently 43x4 = 172 bytes on\n\t * 32-bit platforms.\n\t *\n\t * In some cases the builtins array could be ROM based, but it's\n\t * sometimes edited (e.g. for sandboxing) so it's better to keep\n\t * this array in RAM.\n\t */\n\tduk_hobject *builtins[DUK_NUM_BUILTINS];\n\n\t/* Convenience copies from heap/vm for faster access. */\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* No field needed when strings are in ROM. */\n#else\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t *strs16;\n#else\n\tduk_hstring **strs;\n#endif\n#endif\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_hthread_copy_builtin_objects(duk_hthread *thr_from, duk_hthread *thr_to);\nDUK_INTERNAL_DECL void duk_hthread_create_builtin_objects(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_terminate(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_activation *duk_hthread_activation_alloc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_activation_free(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_hthread_activation_unwind_norz(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_activation_unwind_reuse_norz(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_activation *duk_hthread_get_activation_for_level(duk_hthread *thr, duk_int_t level);\n\nDUK_INTERNAL_DECL duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_catcher_free(duk_hthread *thr, duk_catcher *cat);\nDUK_INTERNAL_DECL void duk_hthread_catcher_unwind_norz(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_hthread_catcher_unwind_nolexenv_norz(duk_hthread *thr, duk_activation *act);\n\n#if defined(DUK_USE_FINALIZER_TORTURE)\nDUK_INTERNAL_DECL void duk_hthread_valstack_torture_realloc(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud);  /* indirect allocs */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_hthread_get_act_curr_pc(duk_hthread *thr, duk_activation *act);\n#endif\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_hthread_get_act_prev_pc(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_hthread_sync_currpc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_sync_and_null_currpc(duk_hthread *thr);\n\n#endif  /* DUK_HTHREAD_H_INCLUDED */\n/* #include duk_harray.h */\n#line 1 \"duk_harray.h\"\n/*\n *  Array object representation, used for actual Array instances.\n *\n *  All objects with the exotic array behavior (which must coincide with having\n *  internal class array) MUST be duk_harrays.  No other object can be a\n *  duk_harray.  However, duk_harrays may not always have an array part.\n */\n\n#if !defined(DUK_HARRAY_H_INCLUDED)\n#define DUK_HARRAY_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_harray_assert_valid(duk_harray *h);\n#define DUK_HARRAY_ASSERT_VALID(h)  do { duk_harray_assert_valid((h)); } while (0)\n#else\n#define DUK_HARRAY_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n#define DUK_HARRAY_LENGTH_WRITABLE(h)         (!(h)->length_nonwritable)\n#define DUK_HARRAY_LENGTH_NONWRITABLE(h)      ((h)->length_nonwritable)\n#define DUK_HARRAY_SET_LENGTH_WRITABLE(h)     do { (h)->length_nonwritable = 0; } while (0)\n#define DUK_HARRAY_SET_LENGTH_NONWRITABLE(h)  do { (h)->length_nonwritable = 1; } while (0)\n\nstruct duk_harray {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Array .length.\n\t *\n\t * At present Array .length may be smaller, equal, or even larger\n\t * than the allocated underlying array part.  Fast path code must\n\t * always take this into account carefully.\n\t */\n\tduk_uint32_t length;\n\n\t/* Array .length property attributes.  The property is always\n\t * non-enumerable and non-configurable.  It's initially writable\n\t * but per Object.defineProperty() rules it can be made non-writable\n\t * even if it is non-configurable.  Thus we need to track the\n\t * writability explicitly.\n\t *\n\t * XXX: this field to be eliminated and moved into duk_hobject\n\t * flags field to save space.\n\t */\n\tduk_bool_t length_nonwritable;\n};\n\n#endif  /* DUK_HARRAY_H_INCLUDED */\n/* #include duk_henv.h */\n#line 1 \"duk_henv.h\"\n/*\n *  Environment object representation.\n */\n\n#if !defined(DUK_HENV_H_INCLUDED)\n#define DUK_HENV_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hdecenv_assert_valid(duk_hdecenv *h);\nDUK_INTERNAL_DECL void duk_hobjenv_assert_valid(duk_hobjenv *h);\n#define DUK_HDECENV_ASSERT_VALID(h)  do { duk_hdecenv_assert_valid((h)); } while (0)\n#define DUK_HOBJENV_ASSERT_VALID(h)  do { duk_hobjenv_assert_valid((h)); } while (0)\n#else\n#define DUK_HDECENV_ASSERT_VALID(h)  do {} while (0)\n#define DUK_HOBJENV_ASSERT_VALID(h)  do {} while (0)\n#endif\n\nstruct duk_hdecenv {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* These control variables provide enough information to access live\n\t * variables for a closure that is still open.  If thread == NULL,\n\t * the record is closed and the identifiers are in the property table.\n\t */\n\tduk_hthread *thread;\n\tduk_hobject *varmap;\n\tduk_size_t regbase_byteoff;\n};\n\nstruct duk_hobjenv {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Target object and 'this' binding for object binding. */\n\tduk_hobject *target;\n\n\t/* The 'target' object is used as a this binding in only some object\n\t * environments.  For example, the global environment does not provide\n\t * a this binding, but a with statement does.\n\t */\n\tduk_bool_t has_this;\n};\n\n#endif  /* DUK_HENV_H_INCLUDED */\n/* #include duk_hbuffer.h */\n#line 1 \"duk_hbuffer.h\"\n/*\n *  Heap buffer representation.\n *\n *  Heap allocated user data buffer which is either:\n *\n *    1. A fixed size buffer (data follows header statically)\n *    2. A dynamic size buffer (data pointer follows header)\n *\n *  The data pointer for a variable size buffer of zero size may be NULL.\n */\n\n#if !defined(DUK_HBUFFER_H_INCLUDED)\n#define DUK_HBUFFER_H_INCLUDED\n\n/*\n *  Flags\n *\n *  Fixed buffer:     0\n *  Dynamic buffer:   DUK_HBUFFER_FLAG_DYNAMIC\n *  External buffer:  DUK_HBUFFER_FLAG_DYNAMIC | DUK_HBUFFER_FLAG_EXTERNAL\n */\n\n#define DUK_HBUFFER_FLAG_DYNAMIC                  DUK_HEAPHDR_USER_FLAG(0)    /* buffer is behind a pointer, dynamic or external */\n#define DUK_HBUFFER_FLAG_EXTERNAL                 DUK_HEAPHDR_USER_FLAG(1)    /* buffer pointer is to an externally allocated buffer */\n\n#define DUK_HBUFFER_HAS_DYNAMIC(x)                DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)\n#define DUK_HBUFFER_HAS_EXTERNAL(x)               DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL)\n\n#define DUK_HBUFFER_SET_DYNAMIC(x)                DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)\n#define DUK_HBUFFER_SET_EXTERNAL(x)               DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL)\n\n#define DUK_HBUFFER_CLEAR_DYNAMIC(x)              DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)\n#define DUK_HBUFFER_CLEAR_EXTERNAL(x)             DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL)\n\n/*\n *  Misc defines\n */\n\n/* Impose a maximum buffer length for now.  Restricted artificially to\n * ensure resize computations or adding a heap header length won't\n * overflow size_t and that a signed duk_int_t can hold a buffer\n * length.  The limit should be synchronized with DUK_HSTRING_MAX_BYTELEN.\n */\n\n#if defined(DUK_USE_BUFLEN16)\n#define DUK_HBUFFER_MAX_BYTELEN                   (0x0000ffffUL)\n#else\n/* Intentionally not 0x7fffffffUL; at least JSON code expects that\n * 2*len + 2 fits in 32 bits.\n */\n#define DUK_HBUFFER_MAX_BYTELEN                   (0x7ffffffeUL)\n#endif\n\n/*\n *  Field access\n */\n\n#if defined(DUK_USE_BUFLEN16)\n/* size stored in duk_heaphdr unused flag bits */\n#define DUK_HBUFFER_GET_SIZE(x)     ((x)->hdr.h_flags >> 16)\n#define DUK_HBUFFER_SET_SIZE(x,v)   do { \\\n\t\tduk_size_t duk__v; \\\n\t\tduk__v = (v); \\\n\t\tDUK_ASSERT(duk__v <= 0xffffUL); \\\n\t\t(x)->hdr.h_flags = ((x)->hdr.h_flags & 0x0000ffffUL) | (((duk_uint32_t) duk__v) << 16); \\\n\t} while (0)\n#define DUK_HBUFFER_ADD_SIZE(x,dv)  do { \\\n\t\t(x)->hdr.h_flags += ((dv) << 16); \\\n\t} while (0)\n#define DUK_HBUFFER_SUB_SIZE(x,dv)  do { \\\n\t\t(x)->hdr.h_flags -= ((dv) << 16); \\\n\t} while (0)\n#else\n#define DUK_HBUFFER_GET_SIZE(x)     (((duk_hbuffer *) (x))->size)\n#define DUK_HBUFFER_SET_SIZE(x,v)   do { \\\n\t\t((duk_hbuffer *) (x))->size = (v); \\\n\t} while (0)\n#define DUK_HBUFFER_ADD_SIZE(x,dv)  do { \\\n\t\t(x)->size += (dv); \\\n\t} while (0)\n#define DUK_HBUFFER_SUB_SIZE(x,dv)  do { \\\n\t\t(x)->size -= (dv); \\\n\t} while (0)\n#endif\n\n#define DUK_HBUFFER_FIXED_GET_SIZE(x)       DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x))\n#define DUK_HBUFFER_FIXED_SET_SIZE(x,v)     DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x))\n\n#define DUK_HBUFFER_DYNAMIC_GET_SIZE(x)     DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x))\n#define DUK_HBUFFER_DYNAMIC_SET_SIZE(x,v)   DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x), (v))\n#define DUK_HBUFFER_DYNAMIC_ADD_SIZE(x,dv)  DUK_HBUFFER_ADD_SIZE((duk_hbuffer *) (x), (dv))\n#define DUK_HBUFFER_DYNAMIC_SUB_SIZE(x,dv)  DUK_HBUFFER_SUB_SIZE((duk_hbuffer *) (x), (dv))\n\n#define DUK_HBUFFER_EXTERNAL_GET_SIZE(x)    DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x))\n#define DUK_HBUFFER_EXTERNAL_SET_SIZE(x,v)  DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x), (v))\n\n#define DUK_HBUFFER_FIXED_GET_DATA_PTR(heap,x)    ((duk_uint8_t *) (((duk_hbuffer_fixed *) (void *) (x)) + 1))\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap,x) \\\n\t((void *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, ((duk_heaphdr *) (x))->h_extra16))\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t((duk_heaphdr *) (x))->h_extra16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t((duk_heaphdr *) (x))->h_extra16 = 0;  /* assume 0 <=> NULL */ \\\n\t} while (0)\n#else\n#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap,x)       ((x)->curr_alloc)\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t(x)->curr_alloc = (void *) (v); \\\n\t} while (0)\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t(x)->curr_alloc = (void *) NULL; \\\n\t} while (0)\n#endif\n\n/* No pointer compression because pointer is potentially outside of\n * Duktape heap.\n */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap,x) \\\n\t((void *) (x)->curr_alloc)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t(x)->curr_alloc = (void *) (v); \\\n\t} while (0)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t(x)->curr_alloc = (void *) NULL; \\\n\t} while (0)\n#else\n#define DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap,x) \\\n\t((void *) (x)->curr_alloc)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t(x)->curr_alloc = (void *) (v); \\\n\t} while (0)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t(x)->curr_alloc = (void *) NULL; \\\n\t} while (0)\n#endif\n\n/* Get a pointer to the current buffer contents (matching current allocation\n * size).  May be NULL for zero size dynamic/external buffer.\n */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HBUFFER_GET_DATA_PTR(heap,x)  ( \\\n\tDUK_HBUFFER_HAS_DYNAMIC((x)) ? \\\n\t\t( \\\n\t\t\tDUK_HBUFFER_HAS_EXTERNAL((x)) ? \\\n\t\t\t\tDUK_HBUFFER_EXTERNAL_GET_DATA_PTR((heap), (duk_hbuffer_external *) (x)) : \\\n\t\t\t\tDUK_HBUFFER_DYNAMIC_GET_DATA_PTR((heap), (duk_hbuffer_dynamic *) (x)) \\\n\t\t) : \\\n\t\tDUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (void *) (x)) \\\n\t)\n#else\n/* Without heap pointer compression duk_hbuffer_dynamic and duk_hbuffer_external\n * have the same layout so checking for fixed vs. dynamic (or external) is enough.\n */\n#define DUK_HBUFFER_GET_DATA_PTR(heap,x)  ( \\\n\tDUK_HBUFFER_HAS_DYNAMIC((x)) ? \\\n\t\tDUK_HBUFFER_DYNAMIC_GET_DATA_PTR((heap), (duk_hbuffer_dynamic *) (x)) : \\\n\t\tDUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (void *) (x)) \\\n\t)\n#endif\n\n/* Validity assert. */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hbuffer_assert_valid(duk_hbuffer *h);\n#define DUK_HBUFFER_ASSERT_VALID(h)  do { duk_hbuffer_assert_valid((h)); } while (0)\n#else\n#define DUK_HBUFFER_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Structs\n */\n\n/* Shared prefix for all buffer types. */\nstruct duk_hbuffer {\n\tduk_heaphdr hdr;\n\n\t/* It's not strictly necessary to track the current size, but\n\t * it is useful for writing robust native code.\n\t */\n\n\t/* Current size. */\n#if defined(DUK_USE_BUFLEN16)\n\t/* Stored in duk_heaphdr unused flags. */\n#else\n\tduk_size_t size;\n#endif\n\n\t/*\n\t *  Data following the header depends on the DUK_HBUFFER_FLAG_DYNAMIC\n\t *  flag.\n\t *\n\t *  If the flag is clear (the buffer is a fixed size one), the buffer\n\t *  data follows the header directly, consisting of 'size' bytes.\n\t *\n\t *  If the flag is set, the actual buffer is allocated separately, and\n\t *  a few control fields follow the header.  Specifically:\n\t *\n\t *    - a \"void *\" pointing to the current allocation\n\t *    - a duk_size_t indicating the full allocated size (always >= 'size')\n\t *\n\t *  If DUK_HBUFFER_FLAG_EXTERNAL is set, the buffer has been allocated\n\t *  by user code, so that Duktape won't be able to resize it and won't\n\t *  free it.  This allows buffers to point to e.g. an externally\n\t *  allocated structure such as a frame buffer.\n\t *\n\t *  Unlike strings, no terminator byte (NUL) is guaranteed after the\n\t *  data.  This would be convenient, but would pad aligned user buffers\n\t *  unnecessarily upwards in size.  For instance, if user code requested\n\t *  a 64-byte dynamic buffer, 65 bytes would actually be allocated which\n\t *  would then potentially round upwards to perhaps 68 or 72 bytes.\n\t */\n};\n\n/* Fixed buffer; data follows struct, with proper alignment guaranteed by\n * struct size.\n */\n#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)\n#pragma pack(push, 8)\n#endif\nstruct duk_hbuffer_fixed {\n\t/* A union is used here as a portable struct size / alignment trick:\n\t * by adding a 32-bit or a 64-bit (unused) union member, the size of\n\t * the struct is effectively forced to be a multiple of 4 or 8 bytes\n\t * (respectively) without increasing the size of the struct unless\n\t * necessary.\n\t */\n\tunion {\n\t\tstruct {\n\t\t\tduk_heaphdr hdr;\n#if defined(DUK_USE_BUFLEN16)\n\t\t\t/* Stored in duk_heaphdr unused flags. */\n#else\n\t\t\tduk_size_t size;\n#endif\n\t\t} s;\n#if (DUK_USE_ALIGN_BY == 4)\n\t\tduk_uint32_t dummy_for_align4;\n#elif (DUK_USE_ALIGN_BY == 8)\n\t\tduk_double_t dummy_for_align8_1;\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_uint64_t dummy_for_align8_2;\n#endif\n#elif (DUK_USE_ALIGN_BY == 1)\n\t\t/* no extra padding */\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\t} u;\n\n\t/*\n\t *  Data follows the struct header.  The struct size is padded by the\n\t *  compiler based on the struct members.  This guarantees that the\n\t *  buffer data will be aligned-by-4 but not necessarily aligned-by-8.\n\t *\n\t *  On platforms where alignment does not matter, the struct padding\n\t *  could be removed (if there is any).  On platforms where alignment\n\t *  by 8 is required, the struct size must be forced to be a multiple\n\t *  of 8 by some means.  Without it, some user code may break, and also\n\t *  Duktape itself breaks (e.g. the compiler stores duk_tvals in a\n\t *  dynamic buffer).\n\t */\n}\n#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_GCC_ATTR)\n__attribute__ ((aligned (8)))\n#elif (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_CLANG_ATTR)\n__attribute__ ((aligned (8)))\n#endif\n;\n#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)\n#pragma pack(pop)\n#endif\n\n/* Dynamic buffer with 'curr_alloc' pointing to a dynamic area allocated using\n * heap allocation primitives.  Also used for external buffers when low memory\n * options are not used.\n */\nstruct duk_hbuffer_dynamic {\n\tduk_heaphdr hdr;\n\n#if defined(DUK_USE_BUFLEN16)\n\t/* Stored in duk_heaphdr unused flags. */\n#else\n\tduk_size_t size;\n#endif\n\n#if defined(DUK_USE_HEAPPTR16)\n\t/* Stored in duk_heaphdr h_extra16. */\n#else\n\tvoid *curr_alloc;  /* may be NULL if alloc_size == 0 */\n#endif\n\n\t/*\n\t *  Allocation size for 'curr_alloc' is alloc_size.  There is no\n\t *  automatic NUL terminator for buffers (see above for rationale).\n\t *\n\t *  'curr_alloc' is explicitly allocated with heap allocation\n\t *  primitives and will thus always have alignment suitable for\n\t *  e.g. duk_tval and an IEEE double.\n\t */\n};\n\n/* External buffer with 'curr_alloc' managed by user code and pointing to an\n * arbitrary address.  When heap pointer compression is not used, this struct\n * has the same layout as duk_hbuffer_dynamic.\n */\nstruct duk_hbuffer_external {\n\tduk_heaphdr hdr;\n\n#if defined(DUK_USE_BUFLEN16)\n\t/* Stored in duk_heaphdr unused flags. */\n#else\n\tduk_size_t size;\n#endif\n\n\t/* Cannot be compressed as a heap pointer because may point to\n\t * an arbitrary address.\n\t */\n\tvoid *curr_alloc;  /* may be NULL if alloc_size == 0 */\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk_small_uint_t flags, void **out_bufdata);\nDUK_INTERNAL_DECL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud);  /* indirect allocs */\n\n/* dynamic buffer ops */\nDUK_INTERNAL_DECL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf, duk_size_t new_size);\nDUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *buf);\n\n#endif  /* DUK_HBUFFER_H_INCLUDED */\n/* #include duk_hproxy.h */\n#line 1 \"duk_hproxy.h\"\n/*\n *  Proxy object representation.\n */\n\n#if !defined(DUK_HPROXY_H_INCLUDED)\n#define DUK_HPROXY_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hproxy_assert_valid(duk_hproxy *h);\n#define DUK_HPROXY_ASSERT_VALID(h)  do { duk_hproxy_assert_valid((h)); } while (0)\n#else\n#define DUK_HPROXY_ASSERT_VALID(h)  do {} while (0)\n#endif\n\nstruct duk_hproxy {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Proxy target object. */\n\tduk_hobject *target;\n\n\t/* Proxy handlers (traps). */\n\tduk_hobject *handler;\n};\n\n#endif  /* DUK_HPROXY_H_INCLUDED */\n/* #include duk_heap.h */\n#line 1 \"duk_heap.h\"\n/*\n *  Heap structure.\n *\n *  Heap contains allocated heap objects, interned strings, and built-in\n *  strings for one or more threads.\n */\n\n#if !defined(DUK_HEAP_H_INCLUDED)\n#define DUK_HEAP_H_INCLUDED\n\n/* alloc function typedefs in duktape.h */\n\n/*\n *  Heap flags\n */\n\n#define DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED            (1U << 0)  /* mark-and-sweep marking reached a recursion limit and must use multi-pass marking */\n#define DUK_HEAP_FLAG_INTERRUPT_RUNNING                        (1U << 1)  /* executor interrupt running (used to avoid nested interrupts) */\n#define DUK_HEAP_FLAG_FINALIZER_NORESCUE                       (1U << 2)  /* heap destruction ongoing, finalizer rescue no longer possible */\n#define DUK_HEAP_FLAG_DEBUGGER_PAUSED                          (1U << 3)  /* debugger is paused: talk with debug client until step/resume */\n\n#define DUK__HEAP_HAS_FLAGS(heap,bits)               ((heap)->flags & (bits))\n#define DUK__HEAP_SET_FLAGS(heap,bits)  do { \\\n\t\t(heap)->flags |= (bits); \\\n\t} while (0)\n#define DUK__HEAP_CLEAR_FLAGS(heap,bits)  do { \\\n\t\t(heap)->flags &= ~(bits); \\\n\t} while (0)\n\n#define DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap)   DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)\n#define DUK_HEAP_HAS_INTERRUPT_RUNNING(heap)               DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)\n#define DUK_HEAP_HAS_FINALIZER_NORESCUE(heap)              DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE)\n#define DUK_HEAP_HAS_DEBUGGER_PAUSED(heap)                 DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED)\n\n#define DUK_HEAP_SET_MARKANDSWEEP_RECLIMIT_REACHED(heap)   DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)\n#define DUK_HEAP_SET_INTERRUPT_RUNNING(heap)               DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)\n#define DUK_HEAP_SET_FINALIZER_NORESCUE(heap)              DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE)\n#define DUK_HEAP_SET_DEBUGGER_PAUSED(heap)                 DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED)\n\n#define DUK_HEAP_CLEAR_MARKANDSWEEP_RECLIMIT_REACHED(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)\n#define DUK_HEAP_CLEAR_INTERRUPT_RUNNING(heap)             DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)\n#define DUK_HEAP_CLEAR_FINALIZER_NORESCUE(heap)            DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE)\n#define DUK_HEAP_CLEAR_DEBUGGER_PAUSED(heap)               DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED)\n\n/*\n *  Longjmp types, also double as identifying continuation type for a rethrow (in 'finally')\n */\n\n#define DUK_LJ_TYPE_UNKNOWN      0    /* unused */\n#define DUK_LJ_TYPE_THROW        1    /* value1 -> error object */\n#define DUK_LJ_TYPE_YIELD        2    /* value1 -> yield value, iserror -> error / normal */\n#define DUK_LJ_TYPE_RESUME       3    /* value1 -> resume value, value2 -> resumee thread, iserror -> error/normal */\n#define DUK_LJ_TYPE_BREAK        4    /* value1 -> label number, pseudo-type to indicate a break continuation (for ENDFIN) */\n#define DUK_LJ_TYPE_CONTINUE     5    /* value1 -> label number, pseudo-type to indicate a continue continuation (for ENDFIN) */\n#define DUK_LJ_TYPE_RETURN       6    /* value1 -> return value, pseudo-type to indicate a return continuation (for ENDFIN) */\n#define DUK_LJ_TYPE_NORMAL       7    /* no value, pseudo-type to indicate a normal continuation (for ENDFIN) */\n\n/*\n *  Mark-and-sweep flags\n *\n *  These are separate from heap level flags now but could be merged.\n *  The heap structure only contains a 'base mark-and-sweep flags'\n *  field and the GC caller can impose further flags.\n */\n\n/* Emergency mark-and-sweep: try extra hard, even at the cost of\n * performance.\n */\n#define DUK_MS_FLAG_EMERGENCY                (1U << 0)\n\n/* Voluntary mark-and-sweep: triggered periodically. */\n#define DUK_MS_FLAG_VOLUNTARY                (1U << 1)\n\n/* Postpone rescue decisions for reachable objects with FINALIZED set.\n * Used during finalize_list processing to avoid incorrect rescue\n * decisions due to finalize_list being a reachability root.\n */\n#define DUK_MS_FLAG_POSTPONE_RESCUE          (1U << 2)\n\n/* Don't compact objects; needed during object property table resize\n * to prevent a recursive resize.  It would suffice to protect only the\n * current object being resized, but this is not yet implemented.\n */\n#define DUK_MS_FLAG_NO_OBJECT_COMPACTION     (1U << 3)\n\n/*\n *  Thread switching\n *\n *  To switch heap->curr_thread, use the macro below so that interrupt counters\n *  get updated correctly.  The macro allows a NULL target thread because that\n *  happens e.g. in call handling.\n */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n#define DUK_HEAP_SWITCH_THREAD(heap,newthr)  duk_heap_switch_thread((heap), (newthr))\n#else\n#define DUK_HEAP_SWITCH_THREAD(heap,newthr)  do { \\\n\t\t(heap)->curr_thread = (newthr); \\\n\t} while (0)\n#endif\n\n/*\n *  Stats\n */\n\n#if defined(DUK_USE_DEBUG)\n#define DUK_STATS_INC(heap,fieldname) do { \\\n\t\t(heap)->fieldname += 1; \\\n\t} while (0)\n#else\n#define DUK_STATS_INC(heap,fieldname) do {} while (0)\n#endif\n\n/*\n *  Other heap related defines\n */\n\n/* Mark-and-sweep interval is relative to combined count of objects and\n * strings kept in the heap during the latest mark-and-sweep pass.\n * Fixed point .8 multiplier and .0 adder.  Trigger count (interval) is\n * decreased by each (re)allocation attempt (regardless of size), and each\n * refzero processed object.\n *\n * 'SKIP' indicates how many (re)allocations to wait until a retry if\n * GC is skipped because there is no thread do it with yet (happens\n * only during init phases).\n */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT              12800L  /* 50x heap size */\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD               1024L\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_SKIP              256L\n#else\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT              256L    /* 1x heap size */\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD               1024L\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_SKIP              256L\n#endif\n\n/* GC torture. */\n#if defined(DUK_USE_GC_TORTURE)\n#define DUK_GC_TORTURE(heap) do { duk_heap_mark_and_sweep((heap), 0); } while (0)\n#else\n#define DUK_GC_TORTURE(heap) do { } while (0)\n#endif\n\n/* Stringcache is used for speeding up char-offset-to-byte-offset\n * translations for non-ASCII strings.\n */\n#define DUK_HEAP_STRCACHE_SIZE                            4\n#define DUK_HEAP_STRINGCACHE_NOCACHE_LIMIT                16  /* strings up to the this length are not cached */\n\n/* Some list management macros. */\n#define DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap,hdr)     duk_heap_insert_into_heap_allocated((heap), (hdr))\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_HEAP_REMOVE_FROM_HEAP_ALLOCATED(heap,hdr)     duk_heap_remove_from_heap_allocated((heap), (hdr))\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n#define DUK_HEAP_INSERT_INTO_FINALIZE_LIST(heap,hdr)      duk_heap_insert_into_finalize_list((heap), (hdr))\n#define DUK_HEAP_REMOVE_FROM_FINALIZE_LIST(heap,hdr)      duk_heap_remove_from_finalize_list((heap), (hdr))\n#endif\n\n/*\n *  Built-in strings\n */\n\n/* heap string indices are autogenerated in duk_strings.h */\n#if defined(DUK_USE_ROM_STRINGS)\n#define DUK_HEAP_GET_STRING(heap,idx) \\\n\t((duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_stridx[(idx)]))\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HEAP_GET_STRING(heap,idx) \\\n\t((duk_hstring *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (heap)->strs16[(idx)]))\n#else\n#define DUK_HEAP_GET_STRING(heap,idx) \\\n\t((heap)->strs[(idx)])\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n/*\n *  Raw memory calls: relative to heap, but no GC interaction\n */\n\n#define DUK_ALLOC_RAW(heap,size) \\\n\t((heap)->alloc_func((heap)->heap_udata, (size)))\n\n#define DUK_REALLOC_RAW(heap,ptr,newsize) \\\n\t((heap)->realloc_func((heap)->heap_udata, (void *) (ptr), (newsize)))\n\n#define DUK_FREE_RAW(heap,ptr) \\\n\t((heap)->free_func((heap)->heap_udata, (void *) (ptr)))\n\n/*\n *  Memory calls: relative to heap, GC interaction, but no error throwing.\n *\n *  XXX: Currently a mark-and-sweep triggered by memory allocation will run\n *  using the heap->heap_thread.  This thread is also used for running\n *  mark-and-sweep finalization; this is not ideal because it breaks the\n *  isolation between multiple global environments.\n *\n *  Notes:\n *\n *    - DUK_FREE() is required to ignore NULL and any other possible return\n *      value of a zero-sized alloc/realloc (same as ANSI C free()).\n *\n *    - There is no DUK_REALLOC_ZEROED because we don't assume to know the\n *      old size.  Caller must zero the reallocated memory.\n *\n *    - DUK_REALLOC_INDIRECT() must be used when a mark-and-sweep triggered\n *      by an allocation failure might invalidate the original 'ptr', thus\n *      causing a realloc retry to use an invalid pointer.  Example: we're\n *      reallocating the value stack and a finalizer resizes the same value\n *      stack during mark-and-sweep.  The indirect variant requests for the\n *      current location of the pointer being reallocated using a callback\n *      right before every realloc attempt; this circuitous approach is used\n *      to avoid strict aliasing issues in a more straightforward indirect\n *      pointer (void **) approach.  Note: the pointer in the storage\n *      location is read but is NOT updated; the caller must do that.\n */\n\n/* callback for indirect reallocs, request for current pointer */\ntypedef void *(*duk_mem_getptr)(duk_heap *heap, void *ud);\n\n#define DUK_ALLOC(heap,size)                            duk_heap_mem_alloc((heap), (size))\n#define DUK_ALLOC_ZEROED(heap,size)                     duk_heap_mem_alloc_zeroed((heap), (size))\n#define DUK_REALLOC(heap,ptr,newsize)                   duk_heap_mem_realloc((heap), (ptr), (newsize))\n#define DUK_REALLOC_INDIRECT(heap,cb,ud,newsize)        duk_heap_mem_realloc_indirect((heap), (cb), (ud), (newsize))\n#define DUK_FREE(heap,ptr)                              duk_heap_mem_free((heap), (ptr))\n\n/*\n *  Checked allocation, relative to a thread\n *\n *  DUK_FREE_CHECKED() doesn't actually throw, but accepts a 'thr' argument\n *  for convenience.\n */\n\n#define DUK_ALLOC_CHECKED(thr,size)                     duk_heap_mem_alloc_checked((thr), (size))\n#define DUK_ALLOC_CHECKED_ZEROED(thr,size)              duk_heap_mem_alloc_checked_zeroed((thr), (size))\n#define DUK_FREE_CHECKED(thr,ptr)                       duk_heap_mem_free((thr)->heap, (ptr))\n\n/*\n *  Memory constants\n */\n\n#define DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT           10  /* Retry allocation after mark-and-sweep for this\n                                                              * many times.  A single mark-and-sweep round is\n                                                              * not guaranteed to free all unreferenced memory\n                                                              * because of finalization (in fact, ANY number of\n                                                              * rounds is strictly not enough).\n                                                              */\n\n#define DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT  3  /* Starting from this round, use emergency mode\n                                                              * for mark-and-sweep.\n                                                              */\n\n/*\n *  Debugger support\n */\n\n/* Maximum number of breakpoints.  Only breakpoints that are set are\n * consulted so increasing this has no performance impact.\n */\n#define DUK_HEAP_MAX_BREAKPOINTS          16\n\n/* Opcode interval for a Date-based status/peek rate limit check.  Only\n * relevant when debugger is attached.  Requesting a timestamp may be a\n * slow operation on some platforms so this shouldn't be too low.  On the\n * other hand a high value makes Duktape react to a pause request slowly.\n */\n#define DUK_HEAP_DBG_RATELIMIT_OPCODES    4000\n\n/* Milliseconds between status notify and transport peeks. */\n#define DUK_HEAP_DBG_RATELIMIT_MILLISECS  200\n\n/* Debugger pause flags. */\n#define DUK_PAUSE_FLAG_ONE_OPCODE        (1U << 0)   /* pause when a single opcode has been executed */\n#define DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE (1U << 1)   /* one opcode pause actually active; artifact of current implementation */\n#define DUK_PAUSE_FLAG_LINE_CHANGE       (1U << 2)   /* pause when current line number changes */\n#define DUK_PAUSE_FLAG_FUNC_ENTRY        (1U << 3)   /* pause when entering a function */\n#define DUK_PAUSE_FLAG_FUNC_EXIT         (1U << 4)   /* pause when exiting current function */\n#define DUK_PAUSE_FLAG_CAUGHT_ERROR      (1U << 5)   /* pause when about to throw an error that is caught */\n#define DUK_PAUSE_FLAG_UNCAUGHT_ERROR    (1U << 6)   /* pause when about to throw an error that won't be caught */\n\nstruct duk_breakpoint {\n\tduk_hstring *filename;\n\tduk_uint32_t line;\n};\n\n/*\n *  String cache should ideally be at duk_hthread level, but that would\n *  cause string finalization to slow down relative to the number of\n *  threads; string finalization must check the string cache for \"weak\"\n *  references to the string being finalized to avoid dead pointers.\n *\n *  Thus, string caches are now at the heap level now.\n */\n\nstruct duk_strcache_entry {\n\tduk_hstring *h;\n\tduk_uint32_t bidx;\n\tduk_uint32_t cidx;\n};\n\n/*\n *  Longjmp state, contains the information needed to perform a longjmp.\n *  Longjmp related values are written to value1, value2, and iserror.\n */\n\nstruct duk_ljstate {\n\tduk_jmpbuf *jmpbuf_ptr;   /* current setjmp() catchpoint */\n\tduk_small_uint_t type;    /* longjmp type */\n\tduk_bool_t iserror;       /* isError flag for yield */\n\tduk_tval value1;          /* 1st related value (type specific) */\n\tduk_tval value2;          /* 2nd related value (type specific) */\n};\n\n#define DUK_ASSERT_LJSTATE_UNSET(heap) do { \\\n\t\tDUK_ASSERT(heap != NULL); \\\n\t\tDUK_ASSERT(heap->lj.type == DUK_LJ_TYPE_UNKNOWN); \\\n\t\tDUK_ASSERT(heap->lj.iserror == 0); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&heap->lj.value1)); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&heap->lj.value2)); \\\n\t} while (0)\n#define DUK_ASSERT_LJSTATE_SET(heap) do { \\\n\t\tDUK_ASSERT(heap != NULL); \\\n\t\tDUK_ASSERT(heap->lj.type != DUK_LJ_TYPE_UNKNOWN); \\\n\t} while (0)\n\n/*\n *  Literal intern cache\n */\n\nstruct duk_litcache_entry {\n\tconst duk_uint8_t *addr;\n\tduk_hstring *h;\n};\n\n/*\n *  Main heap structure\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_heap_assert_valid(duk_heap *heap);\n#define DUK_HEAP_ASSERT_VALID(heap)  do { duk_heap_assert_valid((heap)); } while (0)\n#else\n#define DUK_HEAP_ASSERT_VALID(heap)  do {} while (0)\n#endif\n\nstruct duk_heap {\n\tduk_small_uint_t flags;\n\n\t/* Allocator functions. */\n\tduk_alloc_function alloc_func;\n\tduk_realloc_function realloc_func;\n\tduk_free_function free_func;\n\n\t/* Heap udata, used for allocator functions but also for other heap\n\t * level callbacks like fatal function, pointer compression, etc.\n\t */\n\tvoid *heap_udata;\n\n\t/* Fatal error handling, called e.g. when a longjmp() is needed but\n\t * lj.jmpbuf_ptr is NULL.  fatal_func must never return; it's not\n\t * declared as \"noreturn\" because doing that for typedefs is a bit\n\t * challenging portability-wise.\n\t */\n\tduk_fatal_function fatal_func;\n\n\t/* Main list of allocated heap objects.  Objects are either here,\n\t * in finalize_list waiting for processing, or in refzero_list\n\t * temporarily while a DECREF refzero cascade finishes.\n\t */\n\tduk_heaphdr *heap_allocated;\n\n\t/* Temporary work list for freeing a cascade of objects when a DECREF\n\t * (or DECREF_NORZ) encounters a zero refcount.  Using a work list\n\t * allows fixed C stack size when refcounts go to zero for a chain of\n\t * objects.  Outside of DECREF this is always a NULL because DECREF is\n\t * processed without side effects (only memory free calls).\n\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_heaphdr *refzero_list;\n#endif\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t/* Work list for objects to be finalized. */\n\tduk_heaphdr *finalize_list;\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Object whose finalizer is executing right now (no nesting). */\n\tduk_heaphdr *currently_finalizing;\n#endif\n#endif\n\n\t/* Freelist for duk_activations and duk_catchers. */\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\tduk_activation *activation_free;\n#endif\n#if defined(DUK_USE_CACHE_CATCHER)\n\tduk_catcher *catcher_free;\n#endif\n\n\t/* Voluntary mark-and-sweep trigger counter.  Intentionally signed\n\t * because we continue decreasing the value when voluntary GC cannot\n\t * run.\n\t */\n#if defined(DUK_USE_VOLUNTARY_GC)\n\tduk_int_t ms_trigger_counter;\n#endif\n\n\t/* Mark-and-sweep recursion control: too deep recursion causes\n\t * multi-pass processing to avoid growing C stack without bound.\n\t */\n\tduk_uint_t ms_recursion_depth;\n\n\t/* Mark-and-sweep flags automatically active (used for critical sections). */\n\tduk_small_uint_t ms_base_flags;\n\n\t/* Mark-and-sweep running flag.  Prevents re-entry, and also causes\n\t * refzero events to be ignored (= objects won't be queued to refzero_list).\n\t *\n\t * 0: mark-and-sweep not running\n\t * 1: mark-and-sweep is running\n\t * 2: heap destruction active or debugger active, prevent mark-and-sweep\n\t *    and refzero processing (but mark-and-sweep not itself running)\n\t */\n\tduk_uint_t ms_running;\n\n\t/* Mark-and-sweep prevent count, stacking.  Used to avoid M&S side\n\t * effects (besides finalizers which are controlled separately) such\n\t * as compacting the string table or object property tables.  This\n\t * is also bumped when ms_running is set to prevent recursive re-entry.\n\t * Can also be bumped when mark-and-sweep is not running.\n\t */\n\tduk_uint_t ms_prevent_count;\n\n\t/* Finalizer processing prevent count, stacking.  Bumped when finalizers\n\t * are processed to prevent recursive finalizer processing (first call site\n\t * processing finalizers handles all finalizers until the list is empty).\n\t * Can also be bumped explicitly to prevent finalizer execution.\n\t */\n\tduk_uint_t pf_prevent_count;\n\n\t/* When processing finalize_list, don't actually run finalizers but\n\t * queue finalizable objects back to heap_allocated as is.  This is\n\t * used during heap destruction to deal with finalizers that keep\n\t * on creating more finalizable garbage.\n\t */\n\tduk_uint_t pf_skip_finalizers;\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Set when we're in a critical path where an error throw would cause\n\t * e.g. sandboxing/protected call violations or state corruption.  This\n\t * is just used for asserts.\n\t */\n\tduk_bool_t error_not_allowed;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Set when heap is still being initialized, helps with writing\n\t * some assertions.\n\t */\n\tduk_bool_t heap_initializing;\n#endif\n\n\t/* Marker for detecting internal \"double faults\", errors thrown when\n\t * we're trying to create an error object, see duk_error_throw.c.\n\t */\n\tduk_bool_t creating_error;\n\n\t/* Marker for indicating we're calling a user error augmentation\n\t * (errCreate/errThrow) function.  Errors created/thrown during\n\t * such a call are not augmented.\n\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tduk_bool_t augmenting_error;\n#endif\n\n\t/* Longjmp state. */\n\tduk_ljstate lj;\n\n\t/* Heap thread, used internally and for finalization. */\n\tduk_hthread *heap_thread;\n\n\t/* Current running thread. */\n\tduk_hthread *curr_thread;\n\n\t/* Heap level \"stash\" object (e.g., various reachability roots). */\n\tduk_hobject *heap_object;\n\n\t/* duk_handle_call / duk_handle_safe_call recursion depth limiting */\n\tduk_int_t call_recursion_depth;\n\tduk_int_t call_recursion_limit;\n\n\t/* Mix-in value for computing string hashes; should be reasonably unpredictable. */\n\tduk_uint32_t hash_seed;\n\n\t/* Random number state for duk_util_tinyrandom.c. */\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\n#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS)\n\tduk_uint32_t rnd_state;  /* State for Shamir's three-op algorithm */\n#else\n\tduk_uint64_t rnd_state[2];  /* State for xoroshiro128+ */\n#endif\n#endif\n\n\t/* Counter for unique local symbol creation. */\n\t/* XXX: When 64-bit types are available, it would be more efficient to\n\t * use a duk_uint64_t at least for incrementing but maybe also for\n\t * string formatting in the Symbol constructor.\n\t */\n\tduk_uint32_t sym_counter[2];\n\n\t/* For manual debugging: instruction count based on executor and\n\t * interrupt counter book-keeping.  Inspect debug logs to see how\n\t * they match up.\n\t */\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\tduk_int_t inst_count_exec;\n\tduk_int_t inst_count_interrupt;\n#endif\n\n\t/* Debugger state. */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* Callbacks and udata; dbg_read_cb != NULL is used to indicate attached state. */\n\tduk_debug_read_function dbg_read_cb;                /* required, NULL implies detached */\n\tduk_debug_write_function dbg_write_cb;              /* required */\n\tduk_debug_peek_function dbg_peek_cb;\n\tduk_debug_read_flush_function dbg_read_flush_cb;\n\tduk_debug_write_flush_function dbg_write_flush_cb;\n\tduk_debug_request_function dbg_request_cb;\n\tduk_debug_detached_function dbg_detached_cb;\n\tvoid *dbg_udata;\n\n\t/* The following are only relevant when debugger is attached. */\n\tduk_bool_t dbg_processing;              /* currently processing messages or breakpoints: don't enter message processing recursively (e.g. no breakpoints when processing debugger eval) */\n\tduk_bool_t dbg_state_dirty;             /* resend state next time executor is about to run */\n\tduk_bool_t dbg_force_restart;           /* force executor restart to recheck breakpoints; used to handle function returns (see GH-303) */\n\tduk_bool_t dbg_detaching;               /* debugger detaching; used to avoid calling detach handler recursively */\n\tduk_small_uint_t dbg_pause_flags;       /* flags for automatic pause behavior */\n\tduk_activation *dbg_pause_act;          /* activation related to pause behavior (pause on line change, function entry/exit) */\n\tduk_uint32_t dbg_pause_startline;       /* starting line number for line change related pause behavior */\n\tduk_breakpoint dbg_breakpoints[DUK_HEAP_MAX_BREAKPOINTS];  /* breakpoints: [0,breakpoint_count[ gc reachable */\n\tduk_small_uint_t dbg_breakpoint_count;\n\tduk_breakpoint *dbg_breakpoints_active[DUK_HEAP_MAX_BREAKPOINTS + 1];  /* currently active breakpoints: NULL term, borrowed pointers */\n\t/* XXX: make active breakpoints actual copies instead of pointers? */\n\n\t/* These are for rate limiting Status notifications and transport peeking. */\n\tduk_uint_t dbg_exec_counter;            /* cumulative opcode execution count (overflows are OK) */\n\tduk_uint_t dbg_last_counter;            /* value of dbg_exec_counter when we last did a Date-based check */\n\tduk_double_t dbg_last_time;             /* time when status/peek was last done (Date-based rate limit) */\n\n\t/* Used to support single-byte stream lookahead. */\n\tduk_bool_t dbg_have_next_byte;\n\tduk_uint8_t dbg_next_byte;\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_bool_t dbg_calling_transport;       /* transport call in progress, calling into Duktape forbidden */\n#endif\n\n\t/* String intern table (weak refs). */\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable16;\n#else\n\tduk_hstring **strtable;\n#endif\n\tduk_uint32_t st_mask;    /* mask for lookup, st_size - 1 */\n\tduk_uint32_t st_size;    /* stringtable size */\n#if (DUK_USE_STRTAB_MINSIZE != DUK_USE_STRTAB_MAXSIZE)\n\tduk_uint32_t st_count;   /* string count for resize load factor checks */\n#endif\n\tduk_bool_t st_resizing;  /* string table is being resized; avoid recursive resize */\n\n\t/* String access cache (codepoint offset -> byte offset) for fast string\n\t * character looping; 'weak' reference which needs special handling in GC.\n\t */\n\tduk_strcache_entry strcache[DUK_HEAP_STRCACHE_SIZE];\n\n#if defined(DUK_USE_LITCACHE_SIZE)\n\t/* Literal intern cache.  When enabled, strings interned as literals\n\t * (e.g. duk_push_literal()) will be pinned and cached for the lifetime\n\t * of the heap.\n\t */\n\tduk_litcache_entry litcache[DUK_USE_LITCACHE_SIZE];\n#endif\n\n\t/* Built-in strings. */\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* No field needed when strings are in ROM. */\n#else\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t strs16[DUK_HEAP_NUM_STRINGS];\n#else\n\tduk_hstring *strs[DUK_HEAP_NUM_STRINGS];\n#endif\n#endif\n\n\t/* Stats. */\n#if defined(DUK_USE_DEBUG)\n\tduk_int_t stats_exec_opcodes;\n\tduk_int_t stats_exec_interrupt;\n\tduk_int_t stats_exec_throw;\n\tduk_int_t stats_call_all;\n\tduk_int_t stats_call_tailcall;\n\tduk_int_t stats_call_ecmatoecma;\n\tduk_int_t stats_safecall_all;\n\tduk_int_t stats_safecall_nothrow;\n\tduk_int_t stats_safecall_throw;\n\tduk_int_t stats_ms_try_count;\n\tduk_int_t stats_ms_skip_count;\n\tduk_int_t stats_ms_emergency_count;\n\tduk_int_t stats_strtab_intern_hit;\n\tduk_int_t stats_strtab_intern_miss;\n\tduk_int_t stats_strtab_resize_check;\n\tduk_int_t stats_strtab_resize_grow;\n\tduk_int_t stats_strtab_resize_shrink;\n\tduk_int_t stats_strtab_litcache_hit;\n\tduk_int_t stats_strtab_litcache_miss;\n\tduk_int_t stats_strtab_litcache_pin;\n\tduk_int_t stats_object_realloc_props;\n\tduk_int_t stats_object_abandon_array;\n\tduk_int_t stats_getownpropdesc_count;\n\tduk_int_t stats_getownpropdesc_hit;\n\tduk_int_t stats_getownpropdesc_miss;\n\tduk_int_t stats_getpropdesc_count;\n\tduk_int_t stats_getpropdesc_hit;\n\tduk_int_t stats_getpropdesc_miss;\n\tduk_int_t stats_getprop_all;\n\tduk_int_t stats_getprop_arrayidx;\n\tduk_int_t stats_getprop_bufobjidx;\n\tduk_int_t stats_getprop_bufferidx;\n\tduk_int_t stats_getprop_bufferlen;\n\tduk_int_t stats_getprop_stringidx;\n\tduk_int_t stats_getprop_stringlen;\n\tduk_int_t stats_getprop_proxy;\n\tduk_int_t stats_getprop_arguments;\n\tduk_int_t stats_putprop_all;\n\tduk_int_t stats_putprop_arrayidx;\n\tduk_int_t stats_putprop_bufobjidx;\n\tduk_int_t stats_putprop_bufferidx;\n\tduk_int_t stats_putprop_proxy;\n\tduk_int_t stats_getvar_all;\n\tduk_int_t stats_putvar_all;\n\tduk_int_t stats_envrec_delayedcreate;\n\tduk_int_t stats_envrec_create;\n\tduk_int_t stats_envrec_newenv;\n\tduk_int_t stats_envrec_oldenv;\n\tduk_int_t stats_envrec_pushclosure;\n#endif\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL\nduk_heap *duk_heap_alloc(duk_alloc_function alloc_func,\n                         duk_realloc_function realloc_func,\n                         duk_free_function free_func,\n                         void *heap_udata,\n                         duk_fatal_function fatal_func);\nDUK_INTERNAL_DECL void duk_heap_free(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_free_hobject(duk_heap *heap, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_free_hbuffer(duk_heap *heap, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_free_hstring(duk_heap *heap, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr);\n\nDUK_INTERNAL_DECL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphdr *hdr);\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL_DECL void duk_heap_remove_from_heap_allocated(duk_heap *heap, duk_heaphdr *hdr);\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL_DECL void duk_heap_insert_into_finalize_list(duk_heap *heap, duk_heaphdr *hdr);\nDUK_INTERNAL_DECL void duk_heap_remove_from_finalize_list(duk_heap *heap, duk_heaphdr *hdr);\n#endif\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL duk_bool_t duk_heap_in_heap_allocated(duk_heap *heap, duk_heaphdr *ptr);\n#endif\n#if defined(DUK_USE_INTERRUPT_COUNTER)\nDUK_INTERNAL_DECL void duk_heap_switch_thread(duk_heap *heap, duk_hthread *new_thr);\n#endif\n\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen);\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t len);\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_literal_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen);\n#endif\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_u32(duk_heap *heap, duk_uint32_t val);\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_u32_checked(duk_hthread *thr, duk_uint32_t val);\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL_DECL void duk_heap_strtable_unlink(duk_heap *heap, duk_hstring *h);\n#endif\nDUK_INTERNAL_DECL void duk_heap_strtable_unlink_prev(duk_heap *heap, duk_hstring *h, duk_hstring *prev);\nDUK_INTERNAL_DECL void duk_heap_strtable_force_resize(duk_heap *heap);\nDUK_INTERNAL void duk_heap_strtable_free(duk_heap *heap);\n#if defined(DUK_USE_DEBUG)\nDUK_INTERNAL void duk_heap_strtable_dump(duk_heap *heap);\n#endif\n\nDUK_INTERNAL_DECL void duk_heap_strcache_string_remove(duk_heap *heap, duk_hstring *h);\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *thr, duk_hstring *h, duk_uint_fast32_t char_offset);\n\n#if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS)\nDUK_INTERNAL_DECL void *duk_default_alloc_function(void *udata, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_default_realloc_function(void *udata, void *ptr, duk_size_t newsize);\nDUK_INTERNAL_DECL void duk_default_free_function(void *udata, void *ptr);\n#endif\n\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc(duk_heap *heap, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc_zeroed(duk_heap *heap, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc_checked(duk_hthread *thr, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc_checked_zeroed(duk_hthread *thr, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, duk_size_t newsize);\nDUK_INTERNAL_DECL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize);\nDUK_INTERNAL_DECL void duk_heap_mem_free(duk_heap *heap, void *ptr);\n\nDUK_INTERNAL_DECL void duk_heap_free_freelists(duk_heap *heap);\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL_DECL void duk_heap_run_finalizer(duk_heap *heap, duk_hobject *obj);\nDUK_INTERNAL_DECL void duk_heap_process_finalize_list(duk_heap *heap);\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_INTERNAL_DECL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags);\n\nDUK_INTERNAL_DECL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len);\n\n#endif  /* DUK_HEAP_H_INCLUDED */\n/* #include duk_debugger.h */\n#line 1 \"duk_debugger.h\"\n#if !defined(DUK_DEBUGGER_H_INCLUDED)\n#define DUK_DEBUGGER_H_INCLUDED\n\n/* Debugger protocol version is defined in the public API header. */\n\n/* Initial bytes for markers. */\n#define DUK_DBG_IB_EOM                   0x00\n#define DUK_DBG_IB_REQUEST               0x01\n#define DUK_DBG_IB_REPLY                 0x02\n#define DUK_DBG_IB_ERROR                 0x03\n#define DUK_DBG_IB_NOTIFY                0x04\n\n/* Other initial bytes. */\n#define DUK_DBG_IB_INT4                  0x10\n#define DUK_DBG_IB_STR4                  0x11\n#define DUK_DBG_IB_STR2                  0x12\n#define DUK_DBG_IB_BUF4                  0x13\n#define DUK_DBG_IB_BUF2                  0x14\n#define DUK_DBG_IB_UNUSED                0x15\n#define DUK_DBG_IB_UNDEFINED             0x16\n#define DUK_DBG_IB_NULL                  0x17\n#define DUK_DBG_IB_TRUE                  0x18\n#define DUK_DBG_IB_FALSE                 0x19\n#define DUK_DBG_IB_NUMBER                0x1a\n#define DUK_DBG_IB_OBJECT                0x1b\n#define DUK_DBG_IB_POINTER               0x1c\n#define DUK_DBG_IB_LIGHTFUNC             0x1d\n#define DUK_DBG_IB_HEAPPTR               0x1e\n/* The short string/integer initial bytes starting from 0x60 don't have\n * defines now.\n */\n\n/* Error codes. */\n#define DUK_DBG_ERR_UNKNOWN              0x00\n#define DUK_DBG_ERR_UNSUPPORTED          0x01\n#define DUK_DBG_ERR_TOOMANY              0x02\n#define DUK_DBG_ERR_NOTFOUND             0x03\n#define DUK_DBG_ERR_APPLICATION          0x04\n\n/* Commands and notifys initiated by Duktape. */\n#define DUK_DBG_CMD_STATUS               0x01\n#define DUK_DBG_CMD_UNUSED_2             0x02  /* Duktape 1.x: print notify */\n#define DUK_DBG_CMD_UNUSED_3             0x03  /* Duktape 1.x: alert notify */\n#define DUK_DBG_CMD_UNUSED_4             0x04  /* Duktape 1.x: log notify */\n#define DUK_DBG_CMD_THROW                0x05\n#define DUK_DBG_CMD_DETACHING            0x06\n#define DUK_DBG_CMD_APPNOTIFY            0x07\n\n/* Commands initiated by debug client. */\n#define DUK_DBG_CMD_BASICINFO            0x10\n#define DUK_DBG_CMD_TRIGGERSTATUS        0x11\n#define DUK_DBG_CMD_PAUSE                0x12\n#define DUK_DBG_CMD_RESUME               0x13\n#define DUK_DBG_CMD_STEPINTO             0x14\n#define DUK_DBG_CMD_STEPOVER             0x15\n#define DUK_DBG_CMD_STEPOUT              0x16\n#define DUK_DBG_CMD_LISTBREAK            0x17\n#define DUK_DBG_CMD_ADDBREAK             0x18\n#define DUK_DBG_CMD_DELBREAK             0x19\n#define DUK_DBG_CMD_GETVAR               0x1a\n#define DUK_DBG_CMD_PUTVAR               0x1b\n#define DUK_DBG_CMD_GETCALLSTACK         0x1c\n#define DUK_DBG_CMD_GETLOCALS            0x1d\n#define DUK_DBG_CMD_EVAL                 0x1e\n#define DUK_DBG_CMD_DETACH               0x1f\n#define DUK_DBG_CMD_DUMPHEAP             0x20\n#define DUK_DBG_CMD_GETBYTECODE          0x21\n#define DUK_DBG_CMD_APPREQUEST           0x22\n#define DUK_DBG_CMD_GETHEAPOBJINFO       0x23\n#define DUK_DBG_CMD_GETOBJPROPDESC       0x24\n#define DUK_DBG_CMD_GETOBJPROPDESCRANGE  0x25\n\n/* The low 8 bits map directly to duk_hobject.h DUK_PROPDESC_FLAG_xxx.\n * The remaining flags are specific to the debugger.\n */\n#define DUK_DBG_PROPFLAG_SYMBOL          (1U << 8)\n#define DUK_DBG_PROPFLAG_HIDDEN          (1U << 9)\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL_DECL void duk_debug_do_detach(duk_heap *heap);\n\nDUK_INTERNAL_DECL duk_bool_t duk_debug_read_peek(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_write_flush(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_debug_skip_bytes(duk_hthread *thr, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_skip_byte(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_size_t length);\nDUK_INTERNAL_DECL duk_uint8_t duk_debug_read_byte(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_int32_t duk_debug_read_int(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_hstring *duk_debug_read_hstring(duk_hthread *thr);\n/* XXX: exposed duk_debug_read_pointer */\n/* XXX: exposed duk_debug_read_buffer */\n/* XXX: exposed duk_debug_read_hbuffer */\n#if 0\nDUK_INTERNAL_DECL duk_heaphdr *duk_debug_read_heapptr(duk_hthread *thr);\n#endif\n#if defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL_DECL duk_heaphdr *duk_debug_read_any_ptr(duk_hthread *thr);\n#endif\nDUK_INTERNAL_DECL duk_tval *duk_debug_read_tval(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_debug_write_bytes(duk_hthread *thr, const duk_uint8_t *data, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_write_byte(duk_hthread *thr, duk_uint8_t x);\nDUK_INTERNAL_DECL void duk_debug_write_unused(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_write_undefined(duk_hthread *thr);\n#if defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL_DECL void duk_debug_write_null(duk_hthread *thr);\n#endif\nDUK_INTERNAL_DECL void duk_debug_write_boolean(duk_hthread *thr, duk_uint_t val);\nDUK_INTERNAL_DECL void duk_debug_write_int(duk_hthread *thr, duk_int32_t x);\nDUK_INTERNAL_DECL void duk_debug_write_uint(duk_hthread *thr, duk_uint32_t x);\nDUK_INTERNAL_DECL void duk_debug_write_string(duk_hthread *thr, const char *data, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_write_cstring(duk_hthread *thr, const char *data);\nDUK_INTERNAL_DECL void duk_debug_write_hstring(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_debug_write_buffer(duk_hthread *thr, const char *data, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_write_hbuffer(duk_hthread *thr, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_debug_write_pointer(duk_hthread *thr, void *ptr);\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP) || defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL_DECL void duk_debug_write_heapptr(duk_hthread *thr, duk_heaphdr *h);\n#endif\nDUK_INTERNAL_DECL void duk_debug_write_hobject(duk_hthread *thr, duk_hobject *obj);\nDUK_INTERNAL_DECL void duk_debug_write_tval(duk_hthread *thr, duk_tval *tv);\n#if 0  /* unused */\nDUK_INTERNAL_DECL void duk_debug_write_request(duk_hthread *thr, duk_small_uint_t command);\n#endif\nDUK_INTERNAL_DECL void duk_debug_write_reply(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_write_error_eom(duk_hthread *thr, duk_small_uint_t err_code, const char *msg);\nDUK_INTERNAL_DECL void duk_debug_write_notify(duk_hthread *thr, duk_small_uint_t command);\nDUK_INTERNAL_DECL void duk_debug_write_eom(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_debug_curr_line(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_send_status(duk_hthread *thr);\n#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)\nDUK_INTERNAL_DECL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal);\n#endif\n\nDUK_INTERNAL_DECL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev_pc);\nDUK_INTERNAL_DECL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t no_block);\n\nDUK_INTERNAL_DECL duk_small_int_t duk_debug_add_breakpoint(duk_hthread *thr, duk_hstring *filename, duk_uint32_t line);\nDUK_INTERNAL_DECL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_small_uint_t breakpoint_index);\n\nDUK_INTERNAL_DECL duk_bool_t duk_debug_is_attached(duk_heap *heap);\nDUK_INTERNAL_DECL duk_bool_t duk_debug_is_paused(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_debug_set_paused(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_debug_clear_paused(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_debug_clear_pause_state(duk_heap *heap);\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n#endif  /* DUK_DEBUGGER_H_INCLUDED */\n/* #include duk_debug.h */\n#line 1 \"duk_debug.h\"\n/*\n *  Debugging macros, DUK_DPRINT() and its variants in particular.\n *\n *  DUK_DPRINT() allows formatted debug prints, and supports standard\n *  and Duktape specific formatters.  See duk_debug_vsnprintf.c for details.\n *\n *  DUK_D(x), DUK_DD(x), and DUK_DDD(x) are used together with log macros\n *  for technical reasons.  They are concretely used to hide 'x' from the\n *  compiler when the corresponding log level is disabled.  This allows\n *  clean builds on non-C99 compilers, at the cost of more verbose code.\n *  Examples:\n *\n *    DUK_D(DUK_DPRINT(\"foo\"));\n *    DUK_DD(DUK_DDPRINT(\"foo\"));\n *    DUK_DDD(DUK_DDDPRINT(\"foo\"));\n *\n *  This approach is preferable to the old \"double parentheses\" hack because\n *  double parentheses make the C99 solution worse: __FILE__ and __LINE__ can\n *  no longer be added transparently without going through globals, which\n *  works poorly with threading.\n */\n\n#if !defined(DUK_DEBUG_H_INCLUDED)\n#define DUK_DEBUG_H_INCLUDED\n\n#if defined(DUK_USE_DEBUG)\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0)\n#define DUK_D(x) x\n#else\n#define DUK_D(x) do { } while (0) /* omit */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n#define DUK_DD(x) x\n#else\n#define DUK_DD(x) do { } while (0) /* omit */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK_DDD(x) x\n#else\n#define DUK_DDD(x) do { } while (0) /* omit */\n#endif\n\n/*\n *  Exposed debug macros: debugging enabled\n */\n\n#if defined(DUK_USE_VARIADIC_MACROS)\n\n/* Note: combining __FILE__, __LINE__, and __func__ into fmt would be\n * possible compile time, but waste some space with shared function names.\n */\n#define DUK__DEBUG_LOG(lev,...)  duk_debug_log((duk_int_t) (lev), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, DUK_FUNC_MACRO, __VA_ARGS__);\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0)\n#define DUK_DPRINT(...)          DUK__DEBUG_LOG(DUK_LEVEL_DEBUG, __VA_ARGS__)\n#else\n#define DUK_DPRINT(...)\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n#define DUK_DDPRINT(...)         DUK__DEBUG_LOG(DUK_LEVEL_DDEBUG, __VA_ARGS__)\n#else\n#define DUK_DDPRINT(...)\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK_DDDPRINT(...)        DUK__DEBUG_LOG(DUK_LEVEL_DDDEBUG, __VA_ARGS__)\n#else\n#define DUK_DDDPRINT(...)\n#endif\n\n#else  /* DUK_USE_VARIADIC_MACROS */\n\n#define DUK__DEBUG_STASH(lev)    \\\n\t(void) DUK_SNPRINTF(duk_debug_file_stash, DUK_DEBUG_STASH_SIZE, \"%s\", (const char *) DUK_FILE_MACRO), \\\n\t(void) (duk_debug_file_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), \\\n\t(void) (duk_debug_line_stash = (duk_int_t) DUK_LINE_MACRO), \\\n\t(void) DUK_SNPRINTF(duk_debug_func_stash, DUK_DEBUG_STASH_SIZE, \"%s\", (const char *) DUK_FUNC_MACRO), \\\n\t(void) (duk_debug_func_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), \\\n\t(void) (duk_debug_level_stash = (lev))\n\n/* Without variadic macros resort to comma expression trickery to handle debug\n * prints.  This generates a lot of harmless warnings.  These hacks are not\n * needed normally because DUK_D() and friends will hide the entire debug log\n * statement from the compiler.\n */\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0)\n#define DUK_DPRINT  DUK__DEBUG_STASH(DUK_LEVEL_DEBUG), (void) duk_debug_log  /* args go here in parens */\n#else\n#define DUK_DPRINT  0 && /* args go here as a comma expression in parens */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n#define DUK_DDPRINT  DUK__DEBUG_STASH(DUK_LEVEL_DDEBUG), (void) duk_debug_log  /* args go here in parens */\n#else\n#define DUK_DDPRINT  0 && /* args */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK_DDDPRINT  DUK__DEBUG_STASH(DUK_LEVEL_DDDEBUG), (void) duk_debug_log  /* args go here in parens */\n#else\n#define DUK_DDDPRINT  0 && /* args */\n#endif\n\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n#else  /* DUK_USE_DEBUG */\n\n/*\n *  Exposed debug macros: debugging disabled\n */\n\n#define DUK_D(x) do { } while (0) /* omit */\n#define DUK_DD(x) do { } while (0) /* omit */\n#define DUK_DDD(x) do { } while (0) /* omit */\n\n#if defined(DUK_USE_VARIADIC_MACROS)\n\n#define DUK_DPRINT(...)\n#define DUK_DDPRINT(...)\n#define DUK_DDDPRINT(...)\n\n#else  /* DUK_USE_VARIADIC_MACROS */\n\n#define DUK_DPRINT    0 && /* args go here as a comma expression in parens */\n#define DUK_DDPRINT   0 && /* args */\n#define DUK_DDDPRINT  0 && /* args */\n\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n#endif  /* DUK_USE_DEBUG */\n\n/*\n *  Structs\n */\n\n#if defined(DUK_USE_DEBUG)\nstruct duk_fixedbuffer {\n\tduk_uint8_t *buffer;\n\tduk_size_t length;\n\tduk_size_t offset;\n\tduk_bool_t truncated;\n};\n#endif\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_INTERNAL_DECL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const char *format, va_list ap);\n#if 0  /*unused*/\nDUK_INTERNAL_DECL duk_int_t duk_debug_snprintf(char *str, duk_size_t size, const char *format, ...);\n#endif\nDUK_INTERNAL_DECL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_uint8_t *fptr, duk_size_t fptr_size);\n\n#if defined(DUK_USE_VARIADIC_MACROS)\nDUK_INTERNAL_DECL void duk_debug_log(duk_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...);\n#else  /* DUK_USE_VARIADIC_MACROS */\n/* parameter passing, not thread safe */\n#define DUK_DEBUG_STASH_SIZE  128\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL_DECL duk_int_t duk_debug_line_stash;\nDUK_INTERNAL_DECL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL_DECL duk_int_t duk_debug_level_stash;\n#endif\nDUK_INTERNAL_DECL void duk_debug_log(const char *fmt, ...);\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\nDUK_INTERNAL_DECL void duk_fb_put_bytes(duk_fixedbuffer *fb, const duk_uint8_t *buffer, duk_size_t length);\nDUK_INTERNAL_DECL void duk_fb_put_byte(duk_fixedbuffer *fb, duk_uint8_t x);\nDUK_INTERNAL_DECL void duk_fb_put_cstring(duk_fixedbuffer *fb, const char *x);\nDUK_INTERNAL_DECL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...);\nDUK_INTERNAL_DECL void duk_fb_put_funcptr(duk_fixedbuffer *fb, duk_uint8_t *fptr, duk_size_t fptr_size);\nDUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);\n\n#endif  /* DUK_USE_DEBUG */\n\n#endif  /* DUK_DEBUG_H_INCLUDED */\n/* #include duk_error.h */\n#line 1 \"duk_error.h\"\n/*\n *  Error handling macros, assertion macro, error codes.\n *\n *  There are three types of 'errors':\n *\n *    1. Ordinary errors relative to a thread, cause a longjmp, catchable.\n *    2. Fatal errors relative to a heap, cause fatal handler to be called.\n *    3. Fatal errors without context, cause the default (not heap specific)\n *       fatal handler to be called.\n *\n *  Fatal errors without context are used by debug code such as assertions.\n *  By providing a fatal error handler for a Duktape heap, user code can\n *  avoid fatal errors without context in non-debug builds.\n */\n\n#if !defined(DUK_ERROR_H_INCLUDED)\n#define DUK_ERROR_H_INCLUDED\n\n/*\n *  Error codes: defined in duktape.h\n *\n *  Error codes are used as a shorthand to throw exceptions from inside\n *  the implementation.  The appropriate ECMAScript object is constructed\n *  based on the code.  ECMAScript code throws objects directly.  The error\n *  codes are defined in the public API header because they are also used\n *  by calling code.\n */\n\n/*\n *  Normal error\n *\n *  Normal error is thrown with a longjmp() through the current setjmp()\n *  catchpoint record in the duk_heap.  The 'curr_thread' of the duk_heap\n *  identifies the throwing thread.\n *\n *  Error formatting is usually unnecessary.  The error macros provide a\n *  zero argument version (no formatting) and separate macros for small\n *  argument counts.  Variadic macros are not used to avoid portability\n *  issues and avoid the need for stash-based workarounds when they're not\n *  available.  Vararg calls are avoided for non-formatted error calls\n *  because vararg call sites are larger than normal, and there are a lot\n *  of call sites with no formatting.\n *\n *  Note that special formatting provided by debug macros is NOT available.\n *\n *  The _RAW variants allow the caller to specify file and line.  This makes\n *  it easier to write checked calls which want to use the call site of the\n *  checked function, not the error macro call inside the checked function.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\n/* Because there are quite many call sites, pack error code (require at most\n * 8-bit) into a single argument.\n */\n#define DUK_ERROR(thr,err,msg) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (msg)); \\\n\t} while (0)\n#define DUK_ERROR_RAW(thr,file,line,err,msg) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (msg)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT1(thr,err,fmt,arg1) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT1(thr,file,line,err,fmt,arg1) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT2(thr,err,fmt,arg1,arg2) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT2(thr,file,line,err,fmt,arg1,arg2) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT3(thr,err,fmt,arg1,arg2,arg3) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT3(thr,file,line,err,fmt,arg1,arg2,arg3) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT4(thr,err,fmt,arg1,arg2,arg3,arg4) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3), (arg4)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT4(thr,file,line,err,fmt,arg1,arg2,arg3,arg4) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3), (arg4)); \\\n\t} while (0)\n\n#else  /* DUK_USE_VERBOSE_ERRORS */\n\n#define DUK_ERROR(thr,err,msg)                    duk_err_handle_error((thr), (err))\n#define DUK_ERROR_RAW(thr,file,line,err,msg)      duk_err_handle_error((thr), (err))\n\n#define DUK_ERROR_FMT1(thr,err,fmt,arg1) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT1(thr,file,line,err,fmt,arg1) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#define DUK_ERROR_FMT2(thr,err,fmt,arg1,arg2) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT2(thr,file,line,err,fmt,arg1,arg2) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#define DUK_ERROR_FMT3(thr,err,fmt,arg1,arg2,arg3) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT3(thr,file,line,err,fmt,arg1,arg2,arg3) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#define DUK_ERROR_FMT4(thr,err,fmt,arg1,arg2,arg3,arg4) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT4(thr,file,line,err,fmt,arg1,arg2,arg3,arg4) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n/*\n *  Fatal error without context\n *\n *  The macro is an expression to make it compatible with DUK_ASSERT_EXPR().\n */\n\n#define DUK_FATAL_WITHOUT_CONTEXT(msg) \\\n\tduk_default_fatal_handler(NULL, (msg))\n\n/*\n *  Error throwing helpers\n *\n *  The goal is to provide verbose and configurable error messages.  Call\n *  sites should be clean in source code and compile to a small footprint.\n *  Small footprint is also useful for performance because small cold paths\n *  reduce code cache pressure.  Adding macros here only makes sense if there\n *  are enough call sites to get concrete benefits.\n *\n *  DUK_ERROR_xxx() macros are generic and can be used anywhere.\n *\n *  DUK_DCERROR_xxx() macros can only be used in Duktape/C functions where\n *  the \"return DUK_RET_xxx;\" shorthand is available for low memory targets.\n *  The DUK_DCERROR_xxx() macros always either throw or perform a\n *  'return DUK_RET_xxx' from the calling function.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n/* Verbose errors with key/value summaries (non-paranoid) or without key/value\n * summaries (paranoid, for some security sensitive environments), the paranoid\n * vs. non-paranoid distinction affects only a few specific errors.\n */\n#if defined(DUK_USE_PARANOID_ERRORS)\n#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \\\n\t\tduk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx), (expectname)); \\\n\t} while (0)\n#else  /* DUK_USE_PARANOID_ERRORS */\n#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \\\n\t\tduk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx), (expectname)); \\\n\t} while (0)\n#endif  /* DUK_USE_PARANOID_ERRORS */\n\n#define DUK_ERROR_INTERNAL(thr) do { \\\n\t\tduk_err_error_internal((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_INTERNAL(thr) do { \\\n\t\tDUK_ERROR_INTERNAL((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_ALLOC_FAILED(thr) do { \\\n\t\tduk_err_error_alloc_failed((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_ERROR_UNSUPPORTED(thr) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_ERROR, DUK_STR_UNSUPPORTED); \\\n\t} while (0)\n#define DUK_DCERROR_UNSUPPORTED(thr) do { \\\n\t\tDUK_ERROR_UNSUPPORTED((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_ERROR(thr,msg) do { \\\n\t\tduk_err_error((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INDEX(thr,idx) do { \\\n\t\tduk_err_range_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) do { \\\n\t\tduk_err_range_push_beyond((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tDUK_ERROR_RANGE((thr), DUK_STR_INVALID_ARGS); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tDUK_ERROR_RANGE_INVALID_ARGS((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tDUK_ERROR_RANGE((thr), DUK_STR_INVALID_COUNT); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tDUK_ERROR_RANGE_INVALID_COUNT((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tDUK_ERROR_RANGE((thr), DUK_STR_INVALID_LENGTH); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tDUK_ERROR_RANGE_INVALID_LENGTH((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_RANGE(thr,msg) do { \\\n\t\tduk_err_range((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_EVAL(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_EVAL_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_REFERENCE(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_REFERENCE_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_SYNTAX(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_SYNTAX_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tduk_err_type_invalid_args((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tDUK_ERROR_TYPE_INVALID_ARGS((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tduk_err_type_invalid_state((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tDUK_ERROR_TYPE_INVALID_STATE((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tduk_err_type_invalid_trap_result((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tDUK_ERROR_TYPE((thr), DUK_STR_INVALID_TRAP_RESULT); \\\n\t} while (0)\n#define DUK_ERROR_TYPE(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_TYPE_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_URI(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_URI_ERROR, (msg)); \\\n\t} while (0)\n#else  /* DUK_USE_VERBOSE_ERRORS */\n/* Non-verbose errors for low memory targets: no file, line, or message. */\n\n#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n\n#define DUK_ERROR_INTERNAL(thr) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_INTERNAL(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_ALLOC_FAILED(thr) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_ERROR_UNSUPPORTED(thr) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_UNSUPPORTED(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_ERROR(thr,msg) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INDEX(thr,idx) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_RANGE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_RANGE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_RANGE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_RANGE(thr,msg) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_ERROR_EVAL(thr,msg) do { \\\n\t\tduk_err_eval((thr)); \\\n\t} while (0)\n#define DUK_ERROR_REFERENCE(thr,msg) do { \\\n\t\tduk_err_reference((thr)); \\\n\t} while (0)\n#define DUK_ERROR_SYNTAX(thr,msg) do { \\\n\t\tduk_err_syntax((thr)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_TYPE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_TYPE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE(thr,msg) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_ERROR_URI(thr,msg) do { \\\n\t\tduk_err_uri((thr)); \\\n\t} while (0)\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n/*\n *  Assert macro: failure causes a fatal error.\n *\n *  NOTE: since the assert macro doesn't take a heap/context argument, there's\n *  no way to look up a heap/context specific fatal error handler which may have\n *  been given by the application.  Instead, assertion failures always use the\n *  internal default fatal error handler; it can be replaced via duk_config.h\n *  and then applies to all Duktape heaps.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n\n/* The message should be a compile time constant without formatting (less risk);\n * we don't care about assertion text size because they're not used in production\n * builds.\n */\n#define DUK_ASSERT(x)  do { \\\n\tif (!(x)) { \\\n\t\tDUK_FATAL_WITHOUT_CONTEXT(\"assertion failed: \" #x \\\n\t\t\t\" (\" DUK_FILE_MACRO \":\" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) \")\"); \\\n\t} \\\n\t} while (0)\n\n/* Assertion compatible inside a comma expression, evaluates to void. */\n#define DUK_ASSERT_EXPR(x) \\\n\t((void) ((x) ? 0 : (DUK_FATAL_WITHOUT_CONTEXT(\"assertion failed: \" #x \\\n\t\t\t\t\" (\" DUK_FILE_MACRO \":\" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) \")\"), 0)))\n\n#else  /* DUK_USE_ASSERTIONS */\n\n#define DUK_ASSERT(x)  do { /* assertion omitted */ } while (0)\n\n#define DUK_ASSERT_EXPR(x)  ((void) 0)\n\n#endif  /* DUK_USE_ASSERTIONS */\n\n/* this variant is used when an assert would generate a compile warning by\n * being always true (e.g. >= 0 comparison for an unsigned value\n */\n#define DUK_ASSERT_DISABLE(x)  do { /* assertion disabled */ } while (0)\n\n/*\n *  Assertion helpers\n */\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h)  do { \\\n\t\tDUK_ASSERT((h) == NULL || DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) (h)) > 0); \\\n\t} while (0)\n#define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv)  do { \\\n\t\tif ((tv) != NULL && DUK_TVAL_IS_HEAP_ALLOCATED((tv))) { \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(DUK_TVAL_GET_HEAPHDR((tv))) > 0); \\\n\t\t} \\\n\t} while (0)\n#else\n#define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h)  /* no refcount check */\n#define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv)    /* no refcount check */\n#endif\n\n#define DUK_ASSERT_TOP(ctx,n)  DUK_ASSERT((duk_idx_t) duk_get_top((ctx)) == (duk_idx_t) (n))\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_PACKED_TVAL)\n#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval)  do { \\\n\t\tduk_double_union duk__assert_tmp_du; \\\n\t\tduk__assert_tmp_du.d = (dval); \\\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&duk__assert_tmp_du)); \\\n\t} while (0)\n#else\n#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval)  /* nop */\n#endif\n\n#define DUK_ASSERT_VS_SPACE(thr) \\\n\tDUK_ASSERT(thr->valstack_top < thr->valstack_end)\n\n/*\n *  Helper to initialize a memory area (e.g. struct) with garbage when\n *  assertions enabled.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n#define DUK_ASSERT_SET_GARBAGE(ptr,size) do { \\\n\t\tduk_memset_unsafe((void *) (ptr), 0x5a, size); \\\n\t} while (0)\n#else\n#define DUK_ASSERT_SET_GARBAGE(ptr,size) do {} while (0)\n#endif\n\n/*\n *  Helper for valstack space\n *\n *  Caller of DUK_ASSERT_VALSTACK_SPACE() estimates the number of free stack entries\n *  required for its own use, and any child calls which are not (a) Duktape API calls\n *  or (b) Duktape calls which involve extending the valstack (e.g. getter call).\n */\n\n#define DUK_VALSTACK_ASSERT_EXTRA  5  /* this is added to checks to allow for Duktape\n                                       * API calls in addition to function's own use\n                                       */\n#if defined(DUK_USE_ASSERTIONS)\n#define DUK_ASSERT_VALSTACK_SPACE(thr,n)   do { \\\n\t\tDUK_ASSERT((thr) != NULL); \\\n\t\tDUK_ASSERT((thr)->valstack_end - (thr)->valstack_top >= (n) + DUK_VALSTACK_ASSERT_EXTRA); \\\n\t} while (0)\n#else\n#define DUK_ASSERT_VALSTACK_SPACE(thr,n)   /* no valstack space check */\n#endif\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *msg));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error_fmt(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *fmt, ...));\n#else  /* DUK_USE_VERBOSE_ERRORS */\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error(duk_hthread *thr, duk_errcode_t code));\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code, const char *msg, const char *filename, duk_int_t line));\n#else\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code));\n#endif\n\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t rc));\n\n#define DUK_AUGMENT_FLAG_NOBLAME_FILELINE  (1U << 0)  /* if set, don't blame C file/line for .fileName and .lineNumber */\n#define DUK_AUGMENT_FLAG_SKIP_ONE          (1U << 1)  /* if set, skip topmost activation in traceback construction */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_INTERNAL_DECL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *filename, duk_int_t line, duk_small_uint_t flags);\n#endif\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\nDUK_INTERNAL_DECL void duk_err_augment_error_throw(duk_hthread *thr);\n#endif\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name));\n#else\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name));\n#endif\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error_alloc_failed(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range_push_beyond(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_args(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_state(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_trap_result(duk_hthread *thr, const char *filename, duk_int_t linenumber));\n#else  /* DUK_VERBOSE_ERRORS */\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_eval(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_reference(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_syntax(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_uri(duk_hthread *thr));\n#endif /* DUK_VERBOSE_ERRORS */\n\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_longjmp(duk_hthread *thr));\n\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_default_fatal_handler(void *udata, const char *msg));\n\nDUK_INTERNAL_DECL void duk_err_setup_ljstate1(duk_hthread *thr, duk_small_uint_t lj_type, duk_tval *tv_val);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL_DECL void duk_err_check_debugger_integration(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_errcode_t err_code);\n\n#endif  /* DUK_ERROR_H_INCLUDED */\n/* #include duk_unicode.h */\n#line 1 \"duk_unicode.h\"\n/*\n *  Unicode helpers\n */\n\n#if !defined(DUK_UNICODE_H_INCLUDED)\n#define DUK_UNICODE_H_INCLUDED\n\n/*\n *  UTF-8 / XUTF-8 / CESU-8 constants\n */\n\n#define DUK_UNICODE_MAX_XUTF8_LENGTH      7   /* up to 36 bit codepoints */\n#define DUK_UNICODE_MAX_XUTF8_BMP_LENGTH  3   /* all codepoints up to U+FFFF */\n#define DUK_UNICODE_MAX_CESU8_LENGTH      6   /* all codepoints up to U+10FFFF */\n#define DUK_UNICODE_MAX_CESU8_BMP_LENGTH  3   /* all codepoints up to U+FFFF */\n\n/*\n *  Useful Unicode codepoints\n *\n *  Integer constants must be signed to avoid unexpected coercions\n *  in comparisons.\n */\n\n#define DUK_UNICODE_CP_ZWNJ                   0x200cL  /* zero-width non-joiner */\n#define DUK_UNICODE_CP_ZWJ                    0x200dL  /* zero-width joiner */\n#define DUK_UNICODE_CP_REPLACEMENT_CHARACTER  0xfffdL  /* http://en.wikipedia.org/wiki/Replacement_character#Replacement_character */\n\n/*\n *  ASCII character constants\n *\n *  C character literals like 'x' have a platform specific value and do\n *  not match ASCII (UTF-8) values on e.g. EBCDIC platforms.  So, use\n *  these (admittedly awkward) constants instead.  These constants must\n *  also have signed values to avoid unexpected coercions in comparisons.\n *\n *  http://en.wikipedia.org/wiki/ASCII\n */\n\n#define DUK_ASC_NUL              0x00\n#define DUK_ASC_SOH              0x01\n#define DUK_ASC_STX              0x02\n#define DUK_ASC_ETX              0x03\n#define DUK_ASC_EOT              0x04\n#define DUK_ASC_ENQ              0x05\n#define DUK_ASC_ACK              0x06\n#define DUK_ASC_BEL              0x07\n#define DUK_ASC_BS               0x08\n#define DUK_ASC_HT               0x09\n#define DUK_ASC_LF               0x0a\n#define DUK_ASC_VT               0x0b\n#define DUK_ASC_FF               0x0c\n#define DUK_ASC_CR               0x0d\n#define DUK_ASC_SO               0x0e\n#define DUK_ASC_SI               0x0f\n#define DUK_ASC_DLE              0x10\n#define DUK_ASC_DC1              0x11\n#define DUK_ASC_DC2              0x12\n#define DUK_ASC_DC3              0x13\n#define DUK_ASC_DC4              0x14\n#define DUK_ASC_NAK              0x15\n#define DUK_ASC_SYN              0x16\n#define DUK_ASC_ETB              0x17\n#define DUK_ASC_CAN              0x18\n#define DUK_ASC_EM               0x19\n#define DUK_ASC_SUB              0x1a\n#define DUK_ASC_ESC              0x1b\n#define DUK_ASC_FS               0x1c\n#define DUK_ASC_GS               0x1d\n#define DUK_ASC_RS               0x1e\n#define DUK_ASC_US               0x1f\n#define DUK_ASC_SPACE            0x20\n#define DUK_ASC_EXCLAMATION      0x21\n#define DUK_ASC_DOUBLEQUOTE      0x22\n#define DUK_ASC_HASH             0x23\n#define DUK_ASC_DOLLAR           0x24\n#define DUK_ASC_PERCENT          0x25\n#define DUK_ASC_AMP              0x26\n#define DUK_ASC_SINGLEQUOTE      0x27\n#define DUK_ASC_LPAREN           0x28\n#define DUK_ASC_RPAREN           0x29\n#define DUK_ASC_STAR             0x2a\n#define DUK_ASC_PLUS             0x2b\n#define DUK_ASC_COMMA            0x2c\n#define DUK_ASC_MINUS            0x2d\n#define DUK_ASC_PERIOD           0x2e\n#define DUK_ASC_SLASH            0x2f\n#define DUK_ASC_0                0x30\n#define DUK_ASC_1                0x31\n#define DUK_ASC_2                0x32\n#define DUK_ASC_3                0x33\n#define DUK_ASC_4                0x34\n#define DUK_ASC_5                0x35\n#define DUK_ASC_6                0x36\n#define DUK_ASC_7                0x37\n#define DUK_ASC_8                0x38\n#define DUK_ASC_9                0x39\n#define DUK_ASC_COLON            0x3a\n#define DUK_ASC_SEMICOLON        0x3b\n#define DUK_ASC_LANGLE           0x3c\n#define DUK_ASC_EQUALS           0x3d\n#define DUK_ASC_RANGLE           0x3e\n#define DUK_ASC_QUESTION         0x3f\n#define DUK_ASC_ATSIGN           0x40\n#define DUK_ASC_UC_A             0x41\n#define DUK_ASC_UC_B             0x42\n#define DUK_ASC_UC_C             0x43\n#define DUK_ASC_UC_D             0x44\n#define DUK_ASC_UC_E             0x45\n#define DUK_ASC_UC_F             0x46\n#define DUK_ASC_UC_G             0x47\n#define DUK_ASC_UC_H             0x48\n#define DUK_ASC_UC_I             0x49\n#define DUK_ASC_UC_J             0x4a\n#define DUK_ASC_UC_K             0x4b\n#define DUK_ASC_UC_L             0x4c\n#define DUK_ASC_UC_M             0x4d\n#define DUK_ASC_UC_N             0x4e\n#define DUK_ASC_UC_O             0x4f\n#define DUK_ASC_UC_P             0x50\n#define DUK_ASC_UC_Q             0x51\n#define DUK_ASC_UC_R             0x52\n#define DUK_ASC_UC_S             0x53\n#define DUK_ASC_UC_T             0x54\n#define DUK_ASC_UC_U             0x55\n#define DUK_ASC_UC_V             0x56\n#define DUK_ASC_UC_W             0x57\n#define DUK_ASC_UC_X             0x58\n#define DUK_ASC_UC_Y             0x59\n#define DUK_ASC_UC_Z             0x5a\n#define DUK_ASC_LBRACKET         0x5b\n#define DUK_ASC_BACKSLASH        0x5c\n#define DUK_ASC_RBRACKET         0x5d\n#define DUK_ASC_CARET            0x5e\n#define DUK_ASC_UNDERSCORE       0x5f\n#define DUK_ASC_GRAVE            0x60\n#define DUK_ASC_LC_A             0x61\n#define DUK_ASC_LC_B             0x62\n#define DUK_ASC_LC_C             0x63\n#define DUK_ASC_LC_D             0x64\n#define DUK_ASC_LC_E             0x65\n#define DUK_ASC_LC_F             0x66\n#define DUK_ASC_LC_G             0x67\n#define DUK_ASC_LC_H             0x68\n#define DUK_ASC_LC_I             0x69\n#define DUK_ASC_LC_J             0x6a\n#define DUK_ASC_LC_K             0x6b\n#define DUK_ASC_LC_L             0x6c\n#define DUK_ASC_LC_M             0x6d\n#define DUK_ASC_LC_N             0x6e\n#define DUK_ASC_LC_O             0x6f\n#define DUK_ASC_LC_P             0x70\n#define DUK_ASC_LC_Q             0x71\n#define DUK_ASC_LC_R             0x72\n#define DUK_ASC_LC_S             0x73\n#define DUK_ASC_LC_T             0x74\n#define DUK_ASC_LC_U             0x75\n#define DUK_ASC_LC_V             0x76\n#define DUK_ASC_LC_W             0x77\n#define DUK_ASC_LC_X             0x78\n#define DUK_ASC_LC_Y             0x79\n#define DUK_ASC_LC_Z             0x7a\n#define DUK_ASC_LCURLY           0x7b\n#define DUK_ASC_PIPE             0x7c\n#define DUK_ASC_RCURLY           0x7d\n#define DUK_ASC_TILDE            0x7e\n#define DUK_ASC_DEL              0x7f\n\n/*\n *  Miscellaneous\n */\n\n/* Uppercase A is 0x41, lowercase a is 0x61; OR 0x20 to convert uppercase\n * to lowercase.\n */\n#define DUK_LOWERCASE_CHAR_ASCII(x)  ((x) | 0x20)\n\n/*\n *  Unicode tables\n */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_ids_noa[1116];\n#else\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_ids_noabmp[625];\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_ids_m_let_noa[42];\n#else\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_ids_m_let_noabmp[24];\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_idp_m_ids_noa[576];\n#else\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_idp_m_ids_noabmp[358];\n#endif\n\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_caseconv_uc[1411];\nextern const duk_uint8_t duk_unicode_caseconv_lc[706];\n\n#if defined(DUK_USE_REGEXP_CANON_WORKAROUND)\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\nextern const duk_uint16_t duk_unicode_re_canon_lookup[65536];\n#endif\n\n#if defined(DUK_USE_REGEXP_CANON_BITMAP)\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\n#define DUK_CANON_BITMAP_BLKSIZE                                      32\n#define DUK_CANON_BITMAP_BLKSHIFT                                     5\n#define DUK_CANON_BITMAP_BLKMASK                                      31\nextern const duk_uint8_t duk_unicode_re_canon_bitmap[256];\n#endif\n\n/*\n *  Extern\n */\n\n/* duk_unicode_support.c */\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_unicode_xutf8_markers[7];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_digit[2];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_white[22];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_wordchar[8];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_not_digit[4];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_not_white[24];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_not_wordchar[10];\nDUK_INTERNAL_DECL const duk_int8_t duk_is_idchar_tab[128];\n#endif  /* !DUK_SINGLE_FILE */\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_get_xutf8_length(duk_ucodepoint_t cp);\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_get_cesu8_length(duk_ucodepoint_t cp);\n#endif\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_encode_xutf8(duk_ucodepoint_t cp, duk_uint8_t *out);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_encode_cesu8(duk_ucodepoint_t cp, duk_uint8_t *out);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_decode_xutf8(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_ucodepoint_t *out_cp);\nDUK_INTERNAL_DECL duk_ucodepoint_t duk_unicode_decode_xutf8_checked(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end);\nDUK_INTERNAL_DECL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_whitespace(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_line_terminator(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_identifier_start(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_identifier_part(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_letter(duk_codepoint_t cp);\nDUK_INTERNAL_DECL void duk_unicode_case_convert_string(duk_hthread *thr, duk_bool_t uppercase);\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL_DECL duk_codepoint_t duk_unicode_re_canonicalize_char(duk_hthread *thr, duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_re_is_wordchar(duk_codepoint_t cp);\n#endif\n\n#endif  /* DUK_UNICODE_H_INCLUDED */\n/* #include duk_json.h */\n#line 1 \"duk_json.h\"\n/*\n *  Defines for JSON, especially duk_bi_json.c.\n */\n\n#if !defined(DUK_JSON_H_INCLUDED)\n#define DUK_JSON_H_INCLUDED\n\n/* Encoding/decoding flags */\n#define DUK_JSON_FLAG_ASCII_ONLY              (1U << 0)  /* escape any non-ASCII characters */\n#define DUK_JSON_FLAG_AVOID_KEY_QUOTES        (1U << 1)  /* avoid key quotes when key is an ASCII Identifier */\n#define DUK_JSON_FLAG_EXT_CUSTOM              (1U << 2)  /* extended types: custom encoding */\n#define DUK_JSON_FLAG_EXT_COMPATIBLE          (1U << 3)  /* extended types: compatible encoding */\n\n/* How much stack to require on entry to object/array encode */\n#define DUK_JSON_ENC_REQSTACK                 32\n\n/* How much stack to require on entry to object/array decode */\n#define DUK_JSON_DEC_REQSTACK                 32\n\n/* How large a loop detection stack to use */\n#define DUK_JSON_ENC_LOOPARRAY                64\n\n/* Encoding state.  Heap object references are all borrowed. */\ntypedef struct {\n\tduk_hthread *thr;\n\tduk_bufwriter_ctx bw;        /* output bufwriter */\n\tduk_hobject *h_replacer;     /* replacer function */\n\tduk_hstring *h_gap;          /* gap (if empty string, NULL) */\n\tduk_idx_t idx_proplist;      /* explicit PropertyList */\n\tduk_idx_t idx_loop;          /* valstack index of loop detection object */\n\tduk_small_uint_t flags;\n\tduk_small_uint_t flag_ascii_only;\n\tduk_small_uint_t flag_avoid_key_quotes;\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tduk_small_uint_t flag_ext_custom;\n\tduk_small_uint_t flag_ext_compatible;\n\tduk_small_uint_t flag_ext_custom_or_compatible;\n#endif\n\tduk_uint_t recursion_depth;\n\tduk_uint_t recursion_limit;\n\tduk_uint_t mask_for_undefined;      /* type bit mask: types which certainly produce 'undefined' */\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tduk_small_uint_t stridx_custom_undefined;\n\tduk_small_uint_t stridx_custom_nan;\n\tduk_small_uint_t stridx_custom_neginf;\n\tduk_small_uint_t stridx_custom_posinf;\n\tduk_small_uint_t stridx_custom_function;\n#endif\n\tduk_hobject *visiting[DUK_JSON_ENC_LOOPARRAY];  /* indexed by recursion_depth */\n} duk_json_enc_ctx;\n\ntypedef struct {\n\tduk_hthread *thr;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p_end;\n\tduk_idx_t idx_reviver;\n\tduk_small_uint_t flags;\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tduk_small_uint_t flag_ext_custom;\n\tduk_small_uint_t flag_ext_compatible;\n\tduk_small_uint_t flag_ext_custom_or_compatible;\n#endif\n\tduk_int_t recursion_depth;\n\tduk_int_t recursion_limit;\n} duk_json_dec_ctx;\n\n#endif  /* DUK_JSON_H_INCLUDED */\n/* #include duk_js.h */\n#line 1 \"duk_js.h\"\n/*\n *  ECMAScript execution, support primitives.\n */\n\n#if !defined(DUK_JS_H_INCLUDED)\n#define DUK_JS_H_INCLUDED\n\n/* Flags for call handling.  Lowest flags must match bytecode DUK_BC_CALL_FLAG_xxx 1:1. */\n#define DUK_CALL_FLAG_TAILCALL                 (1U << 0)  /* setup for a tail call */\n#define DUK_CALL_FLAG_CONSTRUCT                (1U << 1)  /* constructor call (i.e. called as 'new Foo()') */\n#define DUK_CALL_FLAG_CALLED_AS_EVAL           (1U << 2)  /* call was made using the identifier 'eval' */\n#define DUK_CALL_FLAG_ALLOW_ECMATOECMA         (1U << 3)  /* ecma-to-ecma call with executor reuse is possible */\n#define DUK_CALL_FLAG_DIRECT_EVAL              (1U << 4)  /* call is a direct eval call */\n#define DUK_CALL_FLAG_CONSTRUCT_PROXY          (1U << 5)  /* handled via 'construct' proxy trap, check return value invariant(s) */\n#define DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED (1U << 6)  /* prototype of 'default instance' updated, temporary flag in call handling */\n\n/* Flags for duk_js_equals_helper(). */\n#define DUK_EQUALS_FLAG_SAMEVALUE            (1U << 0)  /* use SameValue instead of non-strict equality */\n#define DUK_EQUALS_FLAG_STRICT               (1U << 1)  /* use strict equality instead of non-strict equality */\n\n/* Flags for duk_js_compare_helper(). */\n#define DUK_COMPARE_FLAG_NEGATE              (1U << 0)  /* negate result */\n#define DUK_COMPARE_FLAG_EVAL_LEFT_FIRST     (1U << 1)  /* eval left argument first */\n\n/* conversions, coercions, comparison, etc */\nDUK_INTERNAL_DECL duk_bool_t duk_js_toboolean(duk_tval *tv);\nDUK_INTERNAL_DECL duk_double_t duk_js_tonumber(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_double_t duk_js_tointeger_number(duk_double_t x);\nDUK_INTERNAL_DECL duk_double_t duk_js_tointeger(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_uint32_t duk_js_touint32(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_int32_t duk_js_toint32(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_uint16_t duk_js_touint16(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_string(const duk_uint8_t *str, duk_uint32_t blen);\n#if !defined(DUK_USE_HSTRING_ARRIDX)\nDUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_hstring_fast_known(duk_hstring *h);\nDUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_hstring_fast(duk_hstring *h);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_small_int_t duk_js_data_compare(const duk_uint8_t *buf1, const duk_uint8_t *buf2, duk_size_t len1, duk_size_t len2);\nDUK_INTERNAL_DECL duk_small_int_t duk_js_string_compare(duk_hstring *h1, duk_hstring *h2);\n#if 0  /* unused */\nDUK_INTERNAL_DECL duk_small_int_t duk_js_buffer_compare(duk_heap *heap, duk_hbuffer *h1, duk_hbuffer *h2);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL_DECL duk_bool_t duk_js_instanceof_ordinary(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_in(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);\nDUK_INTERNAL_DECL duk_small_uint_t duk_js_typeof_stridx(duk_tval *tv_x);\n\n/* arithmetic */\nDUK_INTERNAL_DECL double duk_js_arith_pow(double x, double y);\nDUK_INTERNAL_DECL double duk_js_arith_mod(double x, double y);\n\n#define duk_js_equals(thr,tv_x,tv_y) \\\n\tduk_js_equals_helper((thr), (tv_x), (tv_y), 0)\n#define duk_js_strict_equals(tv_x,tv_y) \\\n\tduk_js_equals_helper(NULL, (tv_x), (tv_y), DUK_EQUALS_FLAG_STRICT)\n#define duk_js_samevalue(tv_x,tv_y) \\\n\tduk_js_equals_helper(NULL, (tv_x), (tv_y), DUK_EQUALS_FLAG_SAMEVALUE)\n\n/* E5 Sections 11.8.1, 11.8.5; x < y */\n#define duk_js_lessthan(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_x), (tv_Y), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST)\n\n/* E5 Sections 11.8.2, 11.8.5; x > y  -->  y < x */\n#define duk_js_greaterthan(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_y), (tv_x), 0)\n\n/* E5 Sections 11.8.3, 11.8.5; x <= y  -->  not (x > y)  -->  not (y < x) */\n#define duk_js_lessthanorequal(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_y), (tv_x), DUK_COMPARE_FLAG_NEGATE)\n\n/* E5 Sections 11.8.4, 11.8.5; x >= y  -->  not (x < y) */\n#define duk_js_greaterthanorequal(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_x), (tv_y), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST | DUK_COMPARE_FLAG_NEGATE)\n\n/* identifiers and environment handling */\n#if 0  /*unused*/\nDUK_INTERNAL duk_bool_t duk_js_hasvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_getvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL duk_bool_t duk_js_getvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL void duk_js_putvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name, duk_tval *val, duk_bool_t strict);\nDUK_INTERNAL_DECL void duk_js_putvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_tval *val, duk_bool_t strict);\n#if 0  /*unused*/\nDUK_INTERNAL_DECL duk_bool_t duk_js_delvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_delvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name);\nDUK_INTERNAL_DECL duk_bool_t duk_js_declvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_tval *val, duk_small_uint_t prop_flags, duk_bool_t is_func_decl);\nDUK_INTERNAL_DECL void duk_js_init_activation_environment_records_delayed(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject *env);\nDUK_INTERNAL_DECL duk_hobject *duk_create_activation_environment_record(duk_hthread *thr, duk_hobject *func, duk_size_t bottom_byteoff);\nDUK_INTERNAL_DECL void duk_js_push_closure(duk_hthread *thr,\n                                           duk_hcompfunc *fun_temp,\n                                           duk_hobject *outer_var_env,\n                                           duk_hobject *outer_lex_env,\n                                           duk_bool_t add_auto_proto);\n\n/* call handling */\nDUK_INTERNAL_DECL void duk_native_stack_check(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_int_t duk_handle_call_unprotected(duk_hthread *thr, duk_idx_t idx_func, duk_small_uint_t call_flags);\nDUK_INTERNAL_DECL duk_int_t duk_handle_call_unprotected_nargs(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags);\nDUK_INTERNAL_DECL duk_int_t duk_handle_safe_call(duk_hthread *thr, duk_safe_call_function func, void *udata, duk_idx_t num_stack_args, duk_idx_t num_stack_res);\nDUK_INTERNAL_DECL void duk_call_construct_postprocess(duk_hthread *thr, duk_small_uint_t proxy_invariant);\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_INTERNAL_DECL void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_base, duk_tval *tv_key);\n#endif\n\n/* bytecode execution */\nDUK_INTERNAL_DECL void duk_js_execute_bytecode(duk_hthread *exec_thr);\n\n#endif  /* DUK_JS_H_INCLUDED */\n/* #include duk_numconv.h */\n#line 1 \"duk_numconv.h\"\n/*\n *  Number-to-string conversion.  The semantics of these is very tightly\n *  bound with the ECMAScript semantics required for call sites.\n */\n\n#if !defined(DUK_NUMCONV_H_INCLUDED)\n#define DUK_NUMCONV_H_INCLUDED\n\n/* Output a specified number of digits instead of using the shortest\n * form.  Used for toPrecision() and toFixed().\n */\n#define DUK_N2S_FLAG_FIXED_FORMAT         (1U << 0)\n\n/* Force exponential format.  Used for toExponential(). */\n#define DUK_N2S_FLAG_FORCE_EXP            (1U << 1)\n\n/* If number would need zero padding (for whole number part), use\n * exponential format instead.  E.g. if input number is 12300, 3\n * digits are generated (\"123\"), output \"1.23e+4\" instead of \"12300\".\n * Used for toPrecision().\n */\n#define DUK_N2S_FLAG_NO_ZERO_PAD          (1U << 2)\n\n/* Digit count indicates number of fractions (i.e. an absolute\n * digit index instead of a relative one).  Used together with\n * DUK_N2S_FLAG_FIXED_FORMAT for toFixed().\n */\n#define DUK_N2S_FLAG_FRACTION_DIGITS      (1U << 3)\n\n/*\n *  String-to-number conversion\n */\n\n/* Maximum exponent value when parsing numbers.  This is not strictly\n * compliant as there should be no upper limit, but as we parse the\n * exponent without a bigint, impose some limit.  The limit should be\n * small enough that multiplying it (or limit-1 to be precise) won't\n * overflow signed 32-bit integer range.  Exponent is only parsed with\n * radix 10, but with maximum radix (36) a safe limit is:\n * (10000000*36).toString(16) -> '15752a00'\n */\n#define DUK_S2N_MAX_EXPONENT              10000000L\n\n/* Trim white space (= allow leading and trailing whitespace) */\n#define DUK_S2N_FLAG_TRIM_WHITE           (1U << 0)\n\n/* Allow exponent */\n#define DUK_S2N_FLAG_ALLOW_EXP            (1U << 1)\n\n/* Allow trailing garbage (e.g. treat \"123foo\" as \"123) */\n#define DUK_S2N_FLAG_ALLOW_GARBAGE        (1U << 2)\n\n/* Allow leading plus sign */\n#define DUK_S2N_FLAG_ALLOW_PLUS           (1U << 3)\n\n/* Allow leading minus sign */\n#define DUK_S2N_FLAG_ALLOW_MINUS          (1U << 4)\n\n/* Allow 'Infinity' */\n#define DUK_S2N_FLAG_ALLOW_INF            (1U << 5)\n\n/* Allow fraction part */\n#define DUK_S2N_FLAG_ALLOW_FRAC           (1U << 6)\n\n/* Allow naked fraction (e.g. \".123\") */\n#define DUK_S2N_FLAG_ALLOW_NAKED_FRAC     (1U << 7)\n\n/* Allow empty fraction (e.g. \"123.\") */\n#define DUK_S2N_FLAG_ALLOW_EMPTY_FRAC     (1U << 8)\n\n/* Allow empty string to be interpreted as 0 */\n#define DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO  (1U << 9)\n\n/* Allow leading zeroes (e.g. \"0123\" -> \"123\") */\n#define DUK_S2N_FLAG_ALLOW_LEADING_ZERO   (1U << 10)\n\n/* Allow automatic detection of hex base (\"0x\" or \"0X\" prefix),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT   (1U << 11)\n\n/* Allow automatic detection of legacy octal base (\"0n\"),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_LEGACY_OCT_INT   (1U << 12)\n\n/* Allow automatic detection of ES2015 octal base (\"0o123\"),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT   (1U << 13)\n\n/* Allow automatic detection of ES2015 binary base (\"0b10001\"),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT   (1U << 14)\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags);\nDUK_INTERNAL_DECL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags);\n\n#endif  /* DUK_NUMCONV_H_INCLUDED */\n/* #include duk_bi_protos.h */\n#line 1 \"duk_bi_protos.h\"\n/*\n *  Prototypes for built-in functions not automatically covered by the\n *  header declarations emitted by genbuiltins.py.\n */\n\n#if !defined(DUK_BUILTIN_PROTOS_H_INCLUDED)\n#define DUK_BUILTIN_PROTOS_H_INCLUDED\n\n/* Buffer size needed for ISO 8601 formatting.\n * Accurate value is 32 + 1 for NUL termination:\n *   >>> len('+123456-01-23T12:34:56.123+12:34')\n *   32\n * Include additional space to be safe.\n */\n#define  DUK_BI_DATE_ISO8601_BUFSIZE  40\n\n/* Helpers exposed for internal use */\nDUK_INTERNAL_DECL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts, duk_double_t *dparts, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_timeval_from_dparts(duk_double_t *dparts, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_is_leap_year(duk_int_t year);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_timeval_in_valid_range(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_year_in_valid_range(duk_double_t year);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_timeval_in_leeway_range(duk_double_t x);\n/* Built-in providers */\n#if defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_gettimeofday(void);\n#endif\n#if defined(DUK_USE_DATE_NOW_TIME)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_time(void);\n#endif\n#if defined(DUK_USE_DATE_NOW_WINDOWS)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows(void);\n#endif\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows_subms(void);\n#endif\n#if defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S) || defined(DUK_USE_DATE_TZO_GMTIME)\nDUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d);\n#endif\n#if defined(DUK_USE_DATE_TZO_WINDOWS)\nDUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d);\n#endif\n#if defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST)\nDUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_t d);\n#endif\n#if defined(DUK_USE_DATE_PRS_STRPTIME)\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_strptime(duk_hthread *thr, const char *str);\n#endif\n#if defined(DUK_USE_DATE_PRS_GETDATE)\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_getdate(duk_hthread *thr, const char *str);\n#endif\n#if defined(DUK_USE_DATE_FMT_STRFTIME)\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags);\n#endif\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_monotonic_time_clock_gettime(void);\n#endif\n#if defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_monotonic_time_windows_qpc(void);\n#endif\n\nDUK_INTERNAL_DECL\nvoid duk_bi_json_parse_helper(duk_hthread *thr,\n                              duk_idx_t idx_value,\n                              duk_idx_t idx_reviver,\n                              duk_small_uint_t flags);\nDUK_INTERNAL_DECL\nvoid duk_bi_json_stringify_helper(duk_hthread *thr,\n                                  duk_idx_t idx_value,\n                                  duk_idx_t idx_replacer,\n                                  duk_idx_t idx_space,\n                                  duk_small_uint_t flags);\n\nDUK_INTERNAL_DECL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_hthread *thr);\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL_DECL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h_proxy_target, duk_uint_t flags);\n#endif\n\n#endif  /* DUK_BUILTIN_PROTOS_H_INCLUDED */\n/* #include duk_selftest.h */\n#line 1 \"duk_selftest.h\"\n/*\n *  Selftest code\n */\n\n#if !defined(DUK_SELFTEST_H_INCLUDED)\n#define DUK_SELFTEST_H_INCLUDED\n\n#if defined(DUK_USE_SELF_TESTS)\nDUK_INTERNAL_DECL duk_uint_t duk_selftest_run_tests(duk_alloc_function alloc_func,\n                                                    duk_realloc_function realloc_func,\n                                                    duk_free_function free_func,\n                                                    void *udata);\n#endif\n\n#endif  /* DUK_SELFTEST_H_INCLUDED */\n#line 75 \"duk_internal.h\"\n\n#endif  /* DUK_INTERNAL_H_INCLUDED */\n#line 10 \"duk_replacements.c\"\n\n#if defined(DUK_USE_COMPUTED_NAN)\nDUK_INTERNAL double duk_computed_nan;\n#endif\n\n#if defined(DUK_USE_COMPUTED_INFINITY)\nDUK_INTERNAL double duk_computed_infinity;\n#endif\n\n#if defined(DUK_USE_REPL_FPCLASSIFY)\nDUK_INTERNAL int duk_repl_fpclassify(double x) {\n\tduk_double_union u;\n\tduk_uint_fast16_t expt;\n\tduk_small_int_t mzero;\n\n\tu.d = x;\n\texpt = (duk_uint_fast16_t) (u.us[DUK_DBL_IDX_US0] & 0x7ff0UL);\n\tif (expt > 0x0000UL && expt < 0x7ff0UL) {\n\t\t/* expt values [0x001,0x7fe] = normal */\n\t\treturn DUK_FP_NORMAL;\n\t}\n\n\tmzero = (u.ui[DUK_DBL_IDX_UI1] == 0 && (u.ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) == 0);\n\tif (expt == 0x0000UL) {\n\t\t/* expt 0x000 is zero/subnormal */\n\t\tif (mzero) {\n\t\t\treturn DUK_FP_ZERO;\n\t\t} else {\n\t\t\treturn DUK_FP_SUBNORMAL;\n\t\t}\n\t} else {\n\t\t/* expt 0xfff is infinite/nan */\n\t\tif (mzero) {\n\t\t\treturn DUK_FP_INFINITE;\n\t\t} else {\n\t\t\treturn DUK_FP_NAN;\n\t\t}\n\t}\n}\n#endif\n\n#if defined(DUK_USE_REPL_SIGNBIT)\nDUK_INTERNAL int duk_repl_signbit(double x) {\n\tduk_double_union u;\n\tu.d = x;\n\treturn (int) (u.uc[DUK_DBL_IDX_UC0] & 0x80UL);\n}\n#endif\n\n#if defined(DUK_USE_REPL_ISFINITE)\nDUK_INTERNAL int duk_repl_isfinite(double x) {\n\tint c = DUK_FPCLASSIFY(x);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\treturn 0;\n\t} else {\n\t\treturn 1;\n\t}\n}\n#endif\n\n#if defined(DUK_USE_REPL_ISNAN)\nDUK_INTERNAL int duk_repl_isnan(double x) {\n\tint c = DUK_FPCLASSIFY(x);\n\treturn (c == DUK_FP_NAN);\n}\n#endif\n\n#if defined(DUK_USE_REPL_ISINF)\nDUK_INTERNAL int duk_repl_isinf(double x) {\n\tint c = DUK_FPCLASSIFY(x);\n\treturn (c == DUK_FP_INFINITE);\n}\n#endif\n#line 1 \"duk_debug_macros.c\"\n/*\n *  Debugging macro calls.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_DEBUG)\n\n/*\n *  Debugging enabled\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdarg.h>\n\n#if !defined(DUK_USE_DEBUG_WRITE)\n#error debugging enabled (DUK_USE_DEBUG) but DUK_USE_DEBUG_WRITE not defined\n#endif\n\n#define DUK__DEBUG_BUFSIZE  DUK_USE_DEBUG_BUFSIZE\n\n#if defined(DUK_USE_VARIADIC_MACROS)\n\nDUK_INTERNAL void duk_debug_log(duk_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...) {\n\tva_list ap;\n\tlong arg_level;\n\tconst char *arg_file;\n\tlong arg_line;\n\tconst char *arg_func;\n\tconst char *arg_msg;\n\tchar buf[DUK__DEBUG_BUFSIZE];\n\n\tva_start(ap, fmt);\n\n\tduk_memzero((void *) buf, (size_t) DUK__DEBUG_BUFSIZE);\n\tduk_debug_vsnprintf(buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap);\n\n\targ_level = (long) level;\n\targ_file = (const char *) file;\n\targ_line = (long) line;\n\targ_func = (const char *) func;\n\targ_msg = (const char *) buf;\n\tDUK_USE_DEBUG_WRITE(arg_level, arg_file, arg_line, arg_func, arg_msg);\n\n\tva_end(ap);\n}\n\n#else  /* DUK_USE_VARIADIC_MACROS */\n\nDUK_INTERNAL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL duk_int_t duk_debug_line_stash;\nDUK_INTERNAL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL duk_int_t duk_debug_level_stash;\n\nDUK_INTERNAL void duk_debug_log(const char *fmt, ...) {\n\tva_list ap;\n\tlong arg_level;\n\tconst char *arg_file;\n\tlong arg_line;\n\tconst char *arg_func;\n\tconst char *arg_msg;\n\tchar buf[DUK__DEBUG_BUFSIZE];\n\n\tva_start(ap, fmt);\n\n\tduk_memzero((void *) buf, (size_t) DUK__DEBUG_BUFSIZE);\n\tduk_debug_vsnprintf(buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap);\n\n\targ_level = (long) duk_debug_level_stash;\n\targ_file = (const char *) duk_debug_file_stash;\n\targ_line = (long) duk_debug_line_stash;\n\targ_func = (const char *) duk_debug_func_stash;\n\targ_msg = (const char *) buf;\n\tDUK_USE_DEBUG_WRITE(arg_level, arg_file, arg_line, arg_func, arg_msg);\n\n\tva_end(ap);\n}\n\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n#else  /* DUK_USE_DEBUG */\n\n/*\n *  Debugging disabled\n */\n\n#endif  /* DUK_USE_DEBUG */\n\n/* automatic undefs */\n#undef DUK__DEBUG_BUFSIZE\n#line 1 \"duk_builtins.c\"\n/*\n *  Automatically generated by genbuiltins.py, do not edit!\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ASSERTIONS)\n#define DUK__REFCINIT(refc) 0 /*h_assert_refcount*/, (refc) /*actual*/\n#else\n#define DUK__REFCINIT(refc) (refc) /*actual*/\n#endif\n\n#if defined(DUK_USE_ROM_STRINGS)\n#error ROM support not enabled, rerun configure.py with --rom-support\n#else  /* DUK_USE_ROM_STRINGS */\nDUK_INTERNAL const duk_uint8_t duk_strings_data[967] = {\n79,40,209,144,168,105,6,78,54,139,89,185,44,48,46,90,120,8,154,140,35,103,\n35,113,193,73,5,52,112,180,104,166,135,52,188,4,98,12,27,146,156,80,211,31,\n129,115,150,64,52,220,109,24,18,68,156,24,38,67,114,36,55,9,119,151,132,\n140,93,18,113,128,153,201,212,201,205,2,248,8,196,24,224,104,82,146,40,224,\n193,48,114,168,37,147,196,54,123,28,4,98,12,43,148,67,103,177,192,70,32,\n196,121,68,54,123,28,18,192,199,144,124,4,98,12,43,136,108,244,117,184,8,\n196,24,95,40,134,207,71,91,128,140,65,133,113,13,158,158,151,1,24,131,11,\n229,16,217,233,233,112,17,136,48,206,21,110,4,244,244,184,8,196,24,103,10,\n183,2,122,218,156,4,98,12,24,203,112,64,179,113,193,79,8,218,155,131,32,\n184,70,212,220,13,10,82,68,252,123,144,217,146,38,228,207,18,0,100,37,64,\n178,212,11,161,17,104,162,96,10,200,193,57,165,65,169,16,5,100,81,27,70,18,\n32,10,200,68,185,13,116,221,197,184,64,89,57,41,197,13,49,234,5,208,156,\n113,87,55,118,147,20,187,56,161,166,92,221,212,73,210,236,226,134,153,115,\n119,76,201,203,179,138,26,99,73,212,136,136,164,25,174,137,56,32,72,137,\n101,23,52,45,13,34,86,9,79,136,104,201,114,149,96,52,138,134,140,151,75,\n226,233,186,120,121,22,39,54,83,141,5,55,68,236,36,164,3,16,225,115,150,64,\n52,205,163,2,72,154,83,138,26,99,75,12,11,150,103,5,36,20,211,70,140,133,\n67,72,49,241,160,227,81,196,52,168,106,39,132,252,183,136,105,80,212,79,2,\n249,110,128,126,88,95,133,109,237,237,237,151,235,127,46,249,119,203,190,\n186,206,33,181,2,208,61,190,12,19,34,65,19,81,132,108,228,97,1,107,33,12,\n32,45,100,137,64,247,175,9,19,155,41,198,130,155,134,69,146,100,227,226,\n231,146,51,192,204,73,140,224,145,221,102,241,68,196,169,248,30,75,12,11,\n151,242,233,187,143,138,24,137,162,164,255,253,63,3,201,97,129,114,254,92,\n112,75,136,108,166,6,136,159,255,167,224,121,44,48,46,95,203,166,238,74,\n113,67,77,201,128,223,255,223,224,121,44,48,46,95,203,145,46,9,205,16,39,\n201,62,36,0,192,21,147,255,238,145,39,199,197,211,116,240,242,113,197,78,\n214,211,226,233,187,107,105,19,119,37,56,161,166,52,221,212,201,205,36,240,\n242,16,96,152,12,178,52,211,56,228,73,150,83,0,148,39,137,75,67,73,198,209,\n129,36,85,185,201,196,2,32,193,48,17,160,97,16,84,44,156,104,24,67,189,200,\n108,201,19,238,114,96,137,137,50,238,113,164,188,211,185,192,226,100,19,\n134,68,110,112,174,139,0,185,31,115,149,4,88,7,159,115,146,117,34,34,35,\n115,143,22,146,208,210,19,115,140,3,207,185,202,130,36,109,85,185,194,161,\n160,90,50,72,155,115,149,2,232,67,137,204,122,22,66,161,175,164,210,72,199,\n130,137,1,50,32,145,143,38,120,186,195,35,106,51,146,230,8,36,77,109,65,38,\n226,72,159,191,189,181,70,140,133,222,249,212,227,66,125,245,187,251,219,\n77,3,119,190,117,56,208,159,125,110,254,246,210,26,93,239,157,78,52,39,223,\n93,191,189,180,212,52,187,223,58,156,104,79,190,187,127,123,104,180,104,\n183,190,117,56,208,159,125,102,254,209,104,209,124,234,113,161,62,250,80,\n196,128,81,4,9,16,162,4,196,116,9,205,154,27,66,32,100,13,12,98,68,227,33,\n65,69,204,195,34,201,50,8,110,33,23,34,28,168,104,22,188,12,174,138,11,70,\n138,104,115,68,130,137,13,82,27,41,129,162,35,138,54,146,198,137,39,72,180,\n210,178,38,35,146,103,68,139,51,197,214,28,227,131,79,15,35,138,58,130,37,\n19,155,41,146,174,64,203,99,161,100,37,145,51,148,75,4,164,66,54,140,49,46,\n247,70,103,37,230,70,142,70,67,30,232,204,178,163,201,18,54,139,89,39,26,\n16,165,2,228,69,33,143,89,24,70,206,73,67,102,72,148,2,32,214,73,157,224,\n18,128,98,29,241,69,65,50,37,241,116,200,41,144,102,125,2,180,8,210,152,38,\n129,23,8,34,198,\n};\n#endif  /* DUK_USE_ROM_STRINGS */\n\n#if defined(DUK_USE_ROM_OBJECTS)\n#error ROM support not enabled, rerun configure.py with --rom-support\n#else  /* DUK_USE_ROM_OBJECTS */\n/* native functions: 183 */\nDUK_INTERNAL const duk_c_function duk_bi_native_functions[183] = {\n\tNULL,\n\tduk_bi_array_constructor,\n\tduk_bi_array_constructor_is_array,\n\tduk_bi_array_prototype_concat,\n\tduk_bi_array_prototype_indexof_shared,\n\tduk_bi_array_prototype_iter_shared,\n\tduk_bi_array_prototype_join_shared,\n\tduk_bi_array_prototype_pop,\n\tduk_bi_array_prototype_push,\n\tduk_bi_array_prototype_reduce_shared,\n\tduk_bi_array_prototype_reverse,\n\tduk_bi_array_prototype_shift,\n\tduk_bi_array_prototype_slice,\n\tduk_bi_array_prototype_sort,\n\tduk_bi_array_prototype_splice,\n\tduk_bi_array_prototype_to_string,\n\tduk_bi_array_prototype_unshift,\n\tduk_bi_arraybuffer_constructor,\n\tduk_bi_arraybuffer_isview,\n\tduk_bi_boolean_constructor,\n\tduk_bi_boolean_prototype_tostring_shared,\n\tduk_bi_buffer_compare_shared,\n\tduk_bi_buffer_readfield,\n\tduk_bi_buffer_slice_shared,\n\tduk_bi_buffer_writefield,\n\tduk_bi_dataview_constructor,\n\tduk_bi_date_constructor,\n\tduk_bi_date_constructor_now,\n\tduk_bi_date_constructor_parse,\n\tduk_bi_date_constructor_utc,\n\tduk_bi_date_prototype_get_shared,\n\tduk_bi_date_prototype_get_timezone_offset,\n\tduk_bi_date_prototype_set_shared,\n\tduk_bi_date_prototype_set_time,\n\tduk_bi_date_prototype_to_json,\n\tduk_bi_date_prototype_toprimitive,\n\tduk_bi_date_prototype_tostring_shared,\n\tduk_bi_date_prototype_value_of,\n\tduk_bi_duktape_object_act,\n\tduk_bi_duktape_object_compact,\n\tduk_bi_duktape_object_dec,\n\tduk_bi_duktape_object_enc,\n\tduk_bi_duktape_object_fin,\n\tduk_bi_duktape_object_gc,\n\tduk_bi_duktape_object_info,\n\tduk_bi_error_constructor_shared,\n\tduk_bi_error_prototype_filename_getter,\n\tduk_bi_error_prototype_filename_setter,\n\tduk_bi_error_prototype_linenumber_getter,\n\tduk_bi_error_prototype_linenumber_setter,\n\tduk_bi_error_prototype_stack_getter,\n\tduk_bi_error_prototype_stack_setter,\n\tduk_bi_error_prototype_to_string,\n\tduk_bi_function_constructor,\n\tduk_bi_function_prototype,\n\tduk_bi_function_prototype_apply,\n\tduk_bi_function_prototype_bind,\n\tduk_bi_function_prototype_call,\n\tduk_bi_function_prototype_hasinstance,\n\tduk_bi_function_prototype_to_string,\n\tduk_bi_global_object_decode_uri,\n\tduk_bi_global_object_decode_uri_component,\n\tduk_bi_global_object_encode_uri,\n\tduk_bi_global_object_encode_uri_component,\n\tduk_bi_global_object_escape,\n\tduk_bi_global_object_eval,\n\tduk_bi_global_object_is_finite,\n\tduk_bi_global_object_is_nan,\n\tduk_bi_global_object_parse_float,\n\tduk_bi_global_object_parse_int,\n\tduk_bi_global_object_unescape,\n\tduk_bi_json_object_parse,\n\tduk_bi_json_object_stringify,\n\tduk_bi_math_object_clz32,\n\tduk_bi_math_object_hypot,\n\tduk_bi_math_object_imul,\n\tduk_bi_math_object_max,\n\tduk_bi_math_object_min,\n\tduk_bi_math_object_onearg_shared,\n\tduk_bi_math_object_random,\n\tduk_bi_math_object_sign,\n\tduk_bi_math_object_twoarg_shared,\n\tduk_bi_native_function_length,\n\tduk_bi_native_function_name,\n\tduk_bi_nodejs_buffer_byte_length,\n\tduk_bi_nodejs_buffer_concat,\n\tduk_bi_nodejs_buffer_constructor,\n\tduk_bi_nodejs_buffer_copy,\n\tduk_bi_nodejs_buffer_fill,\n\tduk_bi_nodejs_buffer_is_buffer,\n\tduk_bi_nodejs_buffer_is_encoding,\n\tduk_bi_nodejs_buffer_tojson,\n\tduk_bi_nodejs_buffer_tostring,\n\tduk_bi_nodejs_buffer_write,\n\tduk_bi_number_check_shared,\n\tduk_bi_number_constructor,\n\tduk_bi_number_prototype_to_exponential,\n\tduk_bi_number_prototype_to_fixed,\n\tduk_bi_number_prototype_to_locale_string,\n\tduk_bi_number_prototype_to_precision,\n\tduk_bi_number_prototype_to_string,\n\tduk_bi_number_prototype_value_of,\n\tduk_bi_object_constructor,\n\tduk_bi_object_constructor_assign,\n\tduk_bi_object_constructor_create,\n\tduk_bi_object_constructor_define_properties,\n\tduk_bi_object_constructor_define_property,\n\tduk_bi_object_constructor_get_own_property_descriptor,\n\tduk_bi_object_constructor_is,\n\tduk_bi_object_constructor_is_extensible,\n\tduk_bi_object_constructor_is_sealed_frozen_shared,\n\tduk_bi_object_constructor_keys_shared,\n\tduk_bi_object_constructor_prevent_extensions,\n\tduk_bi_object_constructor_seal_freeze_shared,\n\tduk_bi_object_getprototype_shared,\n\tduk_bi_object_prototype_defineaccessor,\n\tduk_bi_object_prototype_has_own_property,\n\tduk_bi_object_prototype_is_prototype_of,\n\tduk_bi_object_prototype_lookupaccessor,\n\tduk_bi_object_prototype_property_is_enumerable,\n\tduk_bi_object_prototype_to_locale_string,\n\tduk_bi_object_prototype_to_string,\n\tduk_bi_object_prototype_value_of,\n\tduk_bi_object_setprototype_shared,\n\tduk_bi_performance_now,\n\tduk_bi_pointer_constructor,\n\tduk_bi_pointer_prototype_tostring_shared,\n\tduk_bi_proxy_constructor,\n\tduk_bi_reflect_apply,\n\tduk_bi_reflect_construct,\n\tduk_bi_reflect_object_delete_property,\n\tduk_bi_reflect_object_get,\n\tduk_bi_reflect_object_has,\n\tduk_bi_reflect_object_set,\n\tduk_bi_regexp_constructor,\n\tduk_bi_regexp_prototype_exec,\n\tduk_bi_regexp_prototype_flags,\n\tduk_bi_regexp_prototype_shared_getter,\n\tduk_bi_regexp_prototype_test,\n\tduk_bi_regexp_prototype_tostring,\n\tduk_bi_string_constructor,\n\tduk_bi_string_constructor_from_char_code,\n\tduk_bi_string_constructor_from_code_point,\n\tduk_bi_string_prototype_caseconv_shared,\n\tduk_bi_string_prototype_char_at,\n\tduk_bi_string_prototype_char_code_at,\n\tduk_bi_string_prototype_concat,\n\tduk_bi_string_prototype_includes,\n\tduk_bi_string_prototype_indexof_shared,\n\tduk_bi_string_prototype_locale_compare,\n\tduk_bi_string_prototype_match,\n\tduk_bi_string_prototype_repeat,\n\tduk_bi_string_prototype_replace,\n\tduk_bi_string_prototype_search,\n\tduk_bi_string_prototype_slice,\n\tduk_bi_string_prototype_split,\n\tduk_bi_string_prototype_startswith_endswith,\n\tduk_bi_string_prototype_substr,\n\tduk_bi_string_prototype_substring,\n\tduk_bi_string_prototype_to_string,\n\tduk_bi_string_prototype_trim,\n\tduk_bi_symbol_constructor_shared,\n\tduk_bi_symbol_key_for,\n\tduk_bi_symbol_toprimitive,\n\tduk_bi_symbol_tostring_shared,\n\tduk_bi_textdecoder_constructor,\n\tduk_bi_textdecoder_prototype_decode,\n\tduk_bi_textdecoder_prototype_shared_getter,\n\tduk_bi_textencoder_constructor,\n\tduk_bi_textencoder_prototype_encode,\n\tduk_bi_textencoder_prototype_encoding_getter,\n\tduk_bi_thread_constructor,\n\tduk_bi_thread_current,\n\tduk_bi_thread_resume,\n\tduk_bi_thread_yield,\n\tduk_bi_type_error_thrower,\n\tduk_bi_typedarray_buffer_getter,\n\tduk_bi_typedarray_bytelength_getter,\n\tduk_bi_typedarray_byteoffset_getter,\n\tduk_bi_typedarray_constructor,\n\tduk_bi_typedarray_set,\n\tduk_bi_uint8array_allocplain,\n\tduk_bi_uint8array_plainof,\n};\n#if defined(DUK_USE_DOUBLE_LE)\nDUK_INTERNAL const duk_uint8_t duk_builtins_data[4251] = {\n144,148,105,225,32,68,52,228,126,12,104,201,37,132,52,167,194,138,105,244,\n124,57,28,211,57,18,64,52,238,254,44,138,111,171,241,164,19,87,137,30,33,\n167,18,145,159,8,211,137,9,225,42,5,240,145,139,163,163,8,211,137,10,228,\n64,211,19,132,140,93,29,56,70,156,72,119,34,66,146,36,104,137,194,70,46,\n142,172,35,78,36,47,146,195,102,11,240,145,139,163,175,8,211,137,9,228,240,\n242,112,145,139,163,179,8,211,137,8,237,34,130,118,49,116,118,225,26,48,0,\n1,94,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,\n33,8,66,26,180,41,97,167,64,150,34,33,154,112,0,1,87,247,35,79,103,237,198,\n174,216,47,31,23,95,17,13,31,217,96,211,49,50,53,212,77,141,24,0,0,179,10,\n228,240,242,15,128,140,65,128,134,188,0,0,89,167,97,181,224,0,2,205,62,53,\n224,0,2,205,66,237,120,0,0,179,81,204,107,192,0,5,154,150,67,94,0,0,44,212,\n245,90,240,0,1,102,169,162,215,128,0,11,53,93,150,188,0,0,89,171,111,53,\n108,150,163,70,0,0,42,2,249,50,94,124,35,68,225,146,49,13,24,0,0,165,161,\n124,153,47,62,12,130,112,201,24,132,56,97,115,16,0,0,0,0,0,0,62,31,243,48,\n0,0,0,0,0,0,60,31,242,241,32,26,193,55,132,112,161,156,72,135,26,41,200,\n140,114,163,156,201,7,56,79,9,80,47,132,140,93,19,160,43,145,3,76,78,18,49,\n116,78,144,238,68,133,36,72,209,19,132,140,93,19,168,47,146,195,102,11,240,\n145,139,162,117,132,242,120,121,56,72,197,209,59,2,59,72,160,157,140,93,19,\n181,36,242,50,143,36,31,131,162,166,7,144,238,133,227,226,235,224,242,161,\n249,18,21,100,20,207,44,199,151,180,122,89,135,152,154,121,153,199,156,158,\n121,218,7,158,162,121,250,71,160,166,122,26,135,162,170,122,58,199,164,16,\n240,70,68,226,27,51,199,138,120,35,34,112,171,112,38,121,1,124,153,47,62,\n17,162,112,201,19,211,11,228,201,121,240,100,19,134,72,158,160,91,201,18,\n186,44,3,68,79,122,168,151,115,165,40,21,18,227,65,198,231,200,8,68,184,84,\n53,19,38,120,128,145,144,78,25,59,72,163,48,64,144,200,39,12,157,164,80,46,\n185,143,115,72,217,230,72,9,35,68,225,147,180,138,51,68,9,17,162,112,201,\n218,69,2,235,152,247,52,141,158,108,128,98,72,64,121,51,132,4,81,164,144,\n128,242,104,136,0,16,92,38,14,49,39,199,197,211,116,240,242,113,197,231,18,\n53,189,116,65,131,18,124,117,155,199,197,207,36,103,142,12,146,20,80,249,\n186,60,116,4,204,73,241,214,111,31,23,60,145,158,56,208,48,146,229,146,3,2,\n82,65,155,195,94,3,10,36,4,201,196,64,56,100,42,26,78,62,46,121,35,60,113,\n152,16,25,10,134,147,143,139,158,72,205,4,151,21,0,73,16,11,230,144,12,88,\n144,153,39,52,144,69,241,37,72,217,240,151,153,27,36,57,178,230,16,16,137,\n114,68,2,200,62,81,1,8,151,11,23,100,141,229,18,6,34,92,37,230,70,201,1,89,\n57,36,2,40,152,151,44,129,83,18,124,117,155,199,197,207,36,103,142,75,12,\n11,151,46,89,40,18,37,200,64,12,154,236,252,238,185,23,95,213,1,132,234,0,\n194,245,128,14,56,37,199,89,188,124,92,242,70,120,232,16,26,137,113,241,\n116,221,60,60,156,113,122,36,10,62,46,121,35,60,113,18,225,27,70,18,32,10,\n201,211,32,67,107,104,100,42,26,78,24,147,153,35,181,181,207,64,67,107,104,\n100,42,26,78,72,147,153,35,181,181,207,68,16,218,218,91,156,170,63,134,36,\n230,72,237,109,116,136,16,218,218,91,156,170,63,146,36,230,72,237,109,116,\n137,16,96,128,228,2,6,191,46,3,71,147,68,4,16,22,188,169,240,16,40,104,242,\n135,198,171,44,68,65,5,217,231,215,6,231,62,188,8,49,1,3,162,92,4,98,12,41,\n7,33,148,53,242,128,97,32,130,3,9,205,16,38,199,198,14,9,0,111,115,225,0,8,\n250,72,240,207,128,241,37,73,25,18,40,0,178,58,11,56,192,2,201,104,17,35,\n160,9,39,70,114,8,6,147,214,129,18,74,240,30,141,145,208,89,203,62,3,161,\n163,37,248,226,185,244,11,88,37,62,33,163,37,248,226,185,252,0,127,255,130,\n146,164,142,32,26,1,36,230,18,1,164,7,43,163,194,0,71,128,105,64,216,7,192,\n52,192,197,66,230,72,192,52,224,209,32,232,34,68,62,129,113,32,232,34,114,\n40,49,231,16,254,0,63,255,208,99,2,140,44,92,206,8,224,143,4,225,147,210,\n124,13,44,92,206,9,195,39,30,228,54,126,163,225,200,169,198,133,42,166,191,\n246,3,11,251,0,24,71,4,120,9,251,8,10,17,193,30,9,195,39,1,63,105,1,98,112,\n201,199,185,13,159,1,63,105,32,48,156,209,2,126,227,224,58,26,50,95,142,47,\n192,208,22,176,74,124,67,70,75,241,197,248,26,64,213,184,64,89,56,39,49,\n224,137,62,36,2,176,19,17,254,68,3,196,143,88,4,79,162,0,210,32,34,35,253,\n72,5,146,208,34,125,144,5,147,214,137,253,208,9,149,3,41,197,13,55,233,0,\n185,187,139,117,137,30,8,18,39,172,1,25,187,139,112,128,178,113,110,177,35,\n193,2,68,245,128,23,55,114,143,121,35,193,2,68,245,130,8,205,220,91,132,5,\n147,148,123,201,30,8,18,39,172,16,18,113,67,63,128,3,68,143,32,39,243,32,\n42,83,4,103,46,89,19,63,224,208,16,70,142,92,178,38,127,193,164,8,67,68,\n186,12,146,247,154,1,165,64,202,113,252,160,131,32,7,35,167,26,50,235,231,\n130,48,179,192,65,148,69,19,214,2,251,85,2,232,72,31,255,255,255,255,255,\n253,239,226,122,196,55,106,160,93,9,0,4,0,0,0,0,0,0,3,49,0,0,0,0,0,0,3,225,\n252,143,94,233,34,104,169,54,144,210,161,168,158,32,0,0,0,0,0,0,120,63,145,\n235,72,96,77,21,38,210,26,84,53,19,196,0,0,0,0,0,0,15,15,240,253,35,228,\n133,185,176,0,0,0,0,0,0,44,15,8,117,128,190,212,128,82,109,33,179,33,137,\n24,31,255,255,255,255,255,231,232,100,58,196,55,106,64,41,54,144,217,144,\n196,140,15,255,255,255,255,255,243,252,49,15,4,100,78,33,179,60,120,167,\n130,50,39,10,183,2,103,144,113,8,151,10,134,162,100,221,16,18,137,113,13,\n153,12,72,238,137,1,81,46,52,28,110,232,148,53,18,228,128,82,113,13,153,12,\n72,238,137,142,73,78,52,0,0,0,0,0,0,0,0,8,58,254,1,12,38,248,134,23,130,0,\n60,221,194,162,228,30,244,128,217,187,132,187,220,210,54,104,2,247,132,5,\n205,220,124,72,36,73,14,110,252,132,25,128,193,94,8,200,149,200,3,237,38,\n43,31,192,54,186,213,128,57,45,56,210,0,0,0,0,0,0,62,31,241,90,251,224,6,\n77,220,24,38,78,74,113,67,77,124,16,50,110,228,208,194,114,83,138,26,107,\n224,172,37,240,97,41,187,139,112,128,178,112,96,153,57,41,197,13,53,240,\n113,41,187,139,112,128,178,114,104,97,57,41,197,13,53,240,128,195,95,8,44,\n61,240,132,216,93,33,133,192,128,14,98,79,147,67,9,129,0,44,196,159,11,69,\n175,152,32,35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,\n39,198,57,179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,\n240,96,153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,\n197,144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,\n150,22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,\n161,166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,\n100,39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,\n18,32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,\n72,68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,\n46,16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,\n117,11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,\n178,36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,\n173,191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,\n117,35,43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,\n131,4,201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,\n102,123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,\n162,215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,\n192,131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,181,55,136,\n200,51,128,114,108,28,100,128,0,0,0,0,0,0,0,12,110,127,32,98,115,249,73,\n117,243,249,67,21,159,202,38,47,63,148,86,8,75,144,94,50,1,38,73,79,204,67,\n95,231,1,6,128,14,79,129,185,40,249,18,149,181,207,142,199,155,172,248,172,\n89,183,207,140,198,137,175,200,0,159,72,10,5,21,220,138,120,74,129,124,36,\n98,232,228,74,81,62,160,20,10,107,185,21,114,32,105,137,194,70,46,142,68,\n165,19,235,1,64,170,187,145,119,34,66,146,36,104,137,194,70,46,142,68,165,\n19,236,1,64,174,187,145,95,37,134,204,23,225,35,23,71,34,82,137,246,128,\n160,89,93,200,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,145,\n71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,0,0,0,0,0,118,\n105,160,91,60,165,195,201,194,8,134,149,216,130,0,192,41,224,136,2,48,176,\n228,1,149,13,195,15,0,200,209,97,71,128,99,32,176,131,192,113,57,143,0,167,\n131,32,230,80,28,202,139,175,237,2,48,189,160,20,1,119,48,87,193,186,129,\n89,56,72,197,209,200,193,185,35,23,71,109,13,219,36,98,232,237,156,13,26,\n208,211,14,102,19,87,137,91,95,128,0,10,64,24,92,0,0,82,2,53,63,240,49,204,\n202,10,14,38,78,44,141,52,207,31,0,0,22,32,129,100,180,8,148,145,78,102,\n152,80,113,50,113,100,105,166,120,248,0,0,177,1,65,196,201,199,20,178,36,\n227,224,0,2,200,3,6,133,41,35,31,0,0,22,1,44,57,137,62,33,179,216,162,152,\n192,131,18,124,162,27,61,138,41,108,32,196,159,16,217,232,235,81,76,104,73,\n137,62,81,13,158,142,181,20,184,16,98,79,136,108,244,244,168,166,56,36,196,\n159,40,134,207,79,74,138,93,10,49,39,194,173,192,158,158,149,20,188,20,98,\n79,133,91,129,61,109,74,41,124,30,68,159,16,217,236,83,108,96,68,137,62,81,\n13,158,197,54,182,17,34,79,136,108,244,117,169,182,52,38,68,159,40,134,207,\n71,90,155,92,8,145,39,196,54,122,122,84,219,28,19,34,79,148,67,103,167,165,\n77,174,133,72,147,225,86,224,79,79,74,155,94,10,145,39,194,173,192,158,182,\n165,54,190,206,25,212,35,208,226,100,150,211,201,29,162,44,140,35,103,0,0,\n0,0,0,0,3,192,252,206,25,228,35,208,226,100,150,211,201,29,162,44,140,35,\n103,0,0,0,0,0,0,3,192,252,206,25,244,35,208,226,100,150,211,201,29,162,44,\n140,35,103,0,0,0,0,0,0,3,192,252,206,26,4,35,208,226,100,150,211,201,29,\n162,44,140,35,103,0,0,0,0,0,0,0,1,0,206,26,20,35,208,226,100,150,211,201,\n29,162,44,140,35,103,0,0,0,0,0,0,0,1,0,206,26,36,35,208,226,100,150,211,\n201,29,162,44,140,35,103,0,0,0,0,0,0,0,65,0,206,26,52,35,208,226,100,150,\n211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,65,0,206,26,68,35,208,226,100,\n150,211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,65,0,206,26,84,35,208,226,\n100,150,211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,129,0,195,154,99,16,38,\n36,0,251,68,117,179,216,162,128,68,72,1,241,13,158,197,20,150,25,18,0,125,\n162,58,217,232,235,117,100,162,136,25,18,0,125,162,58,217,232,235,116,36,\n162,145,2,226,64,15,136,108,244,117,186,178,81,73,129,113,32,7,196,54,122,\n58,221,9,40,165,64,200,144,3,237,17,214,207,79,75,171,37,20,80,200,144,3,\n237,17,214,207,79,75,161,37,20,138,23,18,0,124,67,103,167,165,213,146,138,\n77,11,137,0,62,33,179,211,210,232,73,69,42,133,196,128,31,10,183,2,125,89,\n40,163,5,196,128,31,10,183,2,125,9,40,164,96,200,144,3,224,221,64,172,157,\n89,40,163,134,68,128,31,6,234,5,100,232,73,69,35,133,68,128,31,104,142,182,\n125,89,40,180,0,168,144,3,237,17,214,207,161,37,22,144,19,18,0,124,67,103,\n213,146,139,80,9,137,0,62,33,179,232,73,69,172,5,90,40,153,59,68,117,179,\n216,166,192,77,162,137,147,136,108,246,41,180,176,219,69,19,39,104,142,182,\n122,58,221,89,41,178,6,218,40,153,59,68,117,179,209,214,232,73,77,162,6,90,\n40,153,56,134,207,71,91,171,37,54,152,25,104,162,100,226,27,61,29,110,132,\n148,218,160,109,162,137,147,180,71,91,61,61,46,172,148,217,67,109,20,76,\n157,162,58,217,233,233,116,36,166,209,67,45,20,76,156,67,103,167,165,213,\n146,155,77,12,180,81,50,113,13,158,158,151,66,74,109,84,50,209,68,201,194,\n173,192,159,86,74,108,193,150,138,38,78,21,110,4,250,18,83,104,193,182,138,\n38,78,13,212,10,201,213,146,155,56,109,162,137,147,131,117,2,178,116,36,\n166,209,194,237,20,76,157,162,58,217,245,100,167,16,2,237,20,76,157,162,58,\n217,244,36,167,18,2,173,20,76,156,67,103,213,146,156,80,10,180,81,50,113,\n13,159,66,74,113,97,175,220,48,216,109,192,4,42,22,189,163,0,196,133,0,185,\n80,32,28,78,99,193,18,80,36,4,19,159,141,156,0,178,90,4,74,73,0,22,209,68,\n201,185,129,4,2,8,3,132,64,60,36,6,149,113,72,176,171,240,84,0,157,91,116,\n116,32,11,42,218,221,216,181,129,32,3,234,219,165,3,188,231,235,249,8,187,\n152,252,47,86,227,105,18,7,244,17,91,42,56,175,185,248,110,173,198,209,208,\n36,0,238,82,97,87,188,189,179,240,93,122,32,12,22,162,42,125,144,132,160,7,\n236,161,25,232,237,105,64,205,59,127,102,158,160,230,63,11,217,66,51,210,\n129,154,118,254,205,61,65,236,127,171,197,34,168,48,6,90,162,1,0,39,75,84,\n72,8,9,33,186,162,80,64,76,13,213,19,2,130,96,110,150,181,0,65,6,51,213,20,\n128,65,17,11,213,19,130,137,121,211,210,210,144,6,39,75,84,80,0,201,119,\n234,138,8,41,86,231,71,84,80,129,79,135,186,122,101,224,34,25,69,233,208,3,\n91,141,170,40,96,139,113,180,181,69,36,21,110,54,142,134,168,165,1,176,23,\n212,47,0,216,134,234,87,128,111,117,181,168,128,209,3,70,230,106,192,5,139,\n168,209,234,138,32,36,144,102,235,8,3,146,27,170,40,160,146,132,103,170,40,\n192,115,3,117,69,28,22,113,163,69,170,41,103,1,66,188,17,145,52,104,4,202,\n113,67,76,130,227,72,194,13,240,108,0,0,83,96,0,2,185,0,104,146,84,97,48,0,\n1,90,192,56,169,24,145,179,192,0,5,96,8,56,16,32,128,56,18,52,125,198,86,\n147,186,140,28,50,21,13,39,31,23,60,145,158,56,204,141,47,121,6,155,190,\n188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,199,68,\n14,49,39,199,197,211,116,240,242,113,197,231,18,180,254,4,3,17,46,18,243,\n35,100,128,172,156,146,70,163,150,76,34,248,146,164,108,248,75,204,141,146,\n28,217,115,9,27,79,11,241,173,235,162,160,224,200,2,206,9,113,13,148,192,\n209,18,22,164,146,37,193,57,162,4,249,39,196,128,24,2,178,66,213,136,68,\n201,16,77,209,131,31,192,242,88,96,92,191,151,34,100,136,38,232,255,252,92,\n221,199,197,12,68,209,82,66,212,11,155,185,41,197,13,55,38,3,66,213,47,131,\n250,72,12,162,99,133,116,127,196,32,225,1,3,34,92,170,9,105,164,32,225,64,\n131,156,1,193,133,7,19,39,22,70,154,103,143,128,0,11,16,20,28,76,156,113,\n75,34,78,62,0,0,44,128,48,104,82,146,49,240,0,1,96,11,180,192,0,5,162,1,18,\n160,65,24,131,20,145,25,188,48,132,122,28,76,146,218,121,35,180,69,145,132,\n108,224,0,0,0,0,0,0,120,31,153,188,56,132,122,28,76,146,218,121,35,180,69,\n145,132,108,224,0,0,0,0,0,0,120,31,168,160,45,110,23,30,176,33,184,0,0,181,\n32,29,235,2,27,199,23,0,0,22,196,51,120,129,8,244,56,153,37,180,242,71,104,\n139,35,8,217,192,0,0,0,0,0,0,240,63,51,120,145,8,244,56,153,37,180,242,71,\n104,139,35,8,217,192,0,0,0,0,0,0,0,64,51,120,161,8,244,56,153,37,180,242,\n71,104,139,35,8,217,192,0,0,0,0,0,0,0,64,51,120,177,8,244,56,153,37,180,\n242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,120,193,8,244,56,153,37,\n180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,120,209,8,244,56,153,\n37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,120,225,8,244,56,\n153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,32,64,32,227,194,0,97,\n57,162,4,246,40,5,34,92,35,68,225,161,166,219,16,16,137,112,52,41,73,29,\n169,1,65,196,201,197,145,166,153,246,8,3,137,204,120,34,74,8,200,58,128,28,\n211,160,130,52,78,26,26,110,248,0,0,170,4,12,70,137,195,38,0,0,42,68,159,7,\n84,3,154,150,16,70,137,195,67,77,223,0,0,20,224,20,160,152,23,223,0,0,20,\n226,9,65,154,232,147,161,115,59,224,0,2,156,84,12,50,9,195,38,0,0,41,133,\n30,224,32,54,186,221,128,60,\n};\n#elif defined(DUK_USE_DOUBLE_BE)\nDUK_INTERNAL const duk_uint8_t duk_builtins_data[4251] = {\n144,148,105,225,32,68,52,228,126,12,104,201,37,132,52,167,194,138,105,244,\n124,57,28,211,57,18,64,52,238,254,44,138,111,171,241,164,19,87,137,30,33,\n167,18,145,159,8,211,137,9,225,42,5,240,145,139,163,163,8,211,137,10,228,\n64,211,19,132,140,93,29,56,70,156,72,119,34,66,146,36,104,137,194,70,46,\n142,172,35,78,36,47,146,195,102,11,240,145,139,163,175,8,211,137,9,228,240,\n242,112,145,139,163,179,8,211,137,8,237,34,130,118,49,116,118,225,26,48,0,\n1,94,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,\n33,8,66,26,180,41,97,167,64,150,34,33,154,112,0,1,87,247,35,79,103,237,198,\n174,216,47,31,23,95,17,13,31,217,96,211,49,50,53,212,77,141,24,0,0,179,10,\n228,240,242,15,128,140,65,128,134,188,0,0,89,167,97,181,224,0,2,205,62,53,\n224,0,2,205,66,237,120,0,0,179,81,204,107,192,0,5,154,150,67,94,0,0,44,212,\n245,90,240,0,1,102,169,162,215,128,0,11,53,93,150,188,0,0,89,171,111,53,\n108,150,163,70,0,0,42,2,249,50,94,124,35,68,225,146,49,13,24,0,0,165,161,\n124,153,47,62,12,130,112,201,24,132,56,97,115,16,31,254,0,0,0,0,0,0,51,48,\n31,252,0,0,0,0,0,0,50,241,32,26,193,55,132,112,161,156,72,135,26,41,200,\n140,114,163,156,201,7,56,79,9,80,47,132,140,93,19,160,43,145,3,76,78,18,49,\n116,78,144,238,68,133,36,72,209,19,132,140,93,19,168,47,146,195,102,11,240,\n145,139,162,117,132,242,120,121,56,72,197,209,59,2,59,72,160,157,140,93,19,\n181,36,242,50,143,36,31,131,162,166,7,144,238,133,227,226,235,224,242,161,\n249,18,21,100,20,207,44,199,151,180,122,89,135,152,154,121,153,199,156,158,\n121,218,7,158,162,121,250,71,160,166,122,26,135,162,170,122,58,199,164,16,\n240,70,68,226,27,51,199,138,120,35,34,112,171,112,38,121,1,124,153,47,62,\n17,162,112,201,19,211,11,228,201,121,240,100,19,134,72,158,160,91,201,18,\n186,44,3,68,79,122,168,151,115,165,40,21,18,227,65,198,231,200,8,68,184,84,\n53,19,38,120,128,145,144,78,25,59,72,163,48,64,144,200,39,12,157,164,80,46,\n185,143,115,72,217,230,72,9,35,68,225,147,180,138,51,68,9,17,162,112,201,\n218,69,2,235,152,247,52,141,158,108,128,98,72,64,121,51,132,4,81,164,144,\n128,242,104,136,0,16,92,38,14,49,39,199,197,211,116,240,242,113,197,231,18,\n53,189,116,65,131,18,124,117,155,199,197,207,36,103,142,12,146,20,80,249,\n186,60,116,4,204,73,241,214,111,31,23,60,145,158,56,208,48,146,229,146,3,2,\n82,65,155,195,94,3,10,36,4,201,196,64,56,100,42,26,78,62,46,121,35,60,113,\n152,16,25,10,134,147,143,139,158,72,205,4,151,21,0,73,16,11,230,144,12,88,\n144,153,39,52,144,69,241,37,72,217,240,151,153,27,36,57,178,230,16,16,137,\n114,68,2,200,62,81,1,8,151,11,23,100,141,229,18,6,34,92,37,230,70,201,1,89,\n57,36,2,40,152,151,44,129,83,18,124,117,155,199,197,207,36,103,142,75,12,\n11,151,46,89,40,18,37,200,64,12,154,236,252,238,185,23,95,213,1,132,234,0,\n194,245,128,14,56,37,199,89,188,124,92,242,70,120,232,16,26,137,113,241,\n116,221,60,60,156,113,122,36,10,62,46,121,35,60,113,18,225,27,70,18,32,10,\n201,211,32,67,107,104,100,42,26,78,24,147,153,35,181,181,207,64,67,107,104,\n100,42,26,78,72,147,153,35,181,181,207,68,16,218,218,91,156,170,63,134,36,\n230,72,237,109,116,136,16,218,218,91,156,170,63,146,36,230,72,237,109,116,\n137,16,96,128,228,2,6,191,46,3,71,147,68,4,16,22,188,169,240,16,40,104,242,\n135,198,171,44,68,65,5,217,231,215,6,231,62,188,8,49,1,3,162,92,4,98,12,41,\n7,33,148,53,242,128,97,32,130,3,9,205,16,38,199,198,14,9,0,111,115,225,0,8,\n250,72,240,207,128,241,37,73,25,18,40,0,178,58,11,56,192,2,201,104,17,35,\n160,9,39,70,114,8,6,147,214,129,18,74,240,30,141,145,208,89,203,62,3,161,\n163,37,248,226,185,244,11,88,37,62,33,163,37,248,226,185,252,0,127,255,130,\n146,164,142,32,26,1,36,230,18,1,164,7,43,163,194,0,71,128,105,64,216,7,192,\n52,192,197,66,230,72,192,52,224,209,32,232,34,68,62,129,113,32,232,34,114,\n40,49,231,16,254,0,63,255,208,99,2,140,44,92,206,8,224,143,4,225,147,210,\n124,13,44,92,206,9,195,39,30,228,54,126,163,225,200,169,198,133,42,166,191,\n246,3,11,251,0,24,71,4,120,9,251,8,10,17,193,30,9,195,39,1,63,105,1,98,112,\n201,199,185,13,159,1,63,105,32,48,156,209,2,126,227,224,58,26,50,95,142,47,\n192,208,22,176,74,124,67,70,75,241,197,248,26,64,213,184,64,89,56,39,49,\n224,137,62,36,2,176,19,17,254,68,3,196,143,88,4,79,162,0,210,32,34,35,253,\n72,5,146,208,34,125,144,5,147,214,137,253,208,9,149,3,41,197,13,55,233,0,\n185,187,139,117,137,30,8,18,39,172,1,25,187,139,112,128,178,113,110,177,35,\n193,2,68,245,128,23,55,114,143,121,35,193,2,68,245,130,8,205,220,91,132,5,\n147,148,123,201,30,8,18,39,172,16,18,113,67,63,128,3,68,143,32,39,243,32,\n42,83,4,103,46,89,19,63,224,208,16,70,142,92,178,38,127,193,164,8,67,68,\n186,12,146,247,154,1,165,64,202,113,252,160,131,32,7,35,167,26,50,235,231,\n130,48,179,192,65,148,69,19,214,2,251,85,2,232,72,15,253,255,255,255,255,\n255,255,226,122,196,55,106,160,93,9,0,0,0,0,0,0,0,0,7,49,1,255,224,0,0,0,0,\n0,0,143,94,233,34,104,169,54,144,210,161,168,158,32,63,248,0,0,0,0,0,0,17,\n235,72,96,77,21,38,210,26,84,53,19,196,15,255,0,0,0,0,0,0,0,253,35,228,133,\n185,176,15,44,0,0,0,0,0,0,8,117,128,190,212,128,82,109,33,179,33,137,24,8,\n103,255,255,255,255,255,255,228,58,196,55,106,64,41,54,144,217,144,196,140,\n12,51,255,255,255,255,255,255,241,15,4,100,78,33,179,60,120,167,130,50,39,\n10,183,2,103,144,113,8,151,10,134,162,100,221,16,18,137,113,13,153,12,72,\n238,137,1,81,46,52,28,110,232,148,53,18,228,128,82,113,13,153,12,72,238,\n137,142,73,78,52,0,0,0,0,0,0,0,0,8,58,254,1,12,38,248,134,23,130,0,60,221,\n194,162,228,30,244,128,217,187,132,187,220,210,54,104,2,247,132,5,205,220,\n124,72,36,73,14,110,252,132,25,128,193,94,8,200,149,200,3,237,38,43,31,192,\n54,186,213,128,57,45,56,210,31,254,0,0,0,0,0,0,49,90,251,224,6,77,220,24,\n38,78,74,113,67,77,124,16,50,110,228,208,194,114,83,138,26,107,224,172,37,\n240,97,41,187,139,112,128,178,112,96,153,57,41,197,13,53,240,113,41,187,\n139,112,128,178,114,104,97,57,41,197,13,53,240,128,195,95,8,44,61,240,132,\n216,93,33,133,192,128,14,98,79,147,67,9,129,0,44,196,159,11,69,175,152,32,\n35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,39,198,57,\n179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,240,96,\n153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,197,\n144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,150,\n22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,161,\n166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,100,\n39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,18,\n32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,72,\n68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,46,\n16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,117,\n11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,178,\n36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,173,\n191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,117,35,\n43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,131,4,\n201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,102,\n123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,162,\n215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,192,\n131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,181,55,136,200,\n51,128,114,108,28,100,128,0,0,0,0,0,0,0,12,110,127,32,98,115,249,73,117,\n243,249,67,21,159,202,38,47,63,148,86,8,75,144,94,50,1,38,73,79,204,67,95,\n231,1,6,128,14,79,129,185,40,249,18,149,181,207,142,199,155,172,248,172,89,\n183,207,140,198,137,175,200,0,159,72,10,5,21,220,138,120,74,129,124,36,98,\n232,228,74,81,62,160,20,10,107,185,21,114,32,105,137,194,70,46,142,68,165,\n19,235,1,64,170,187,145,119,34,66,146,36,104,137,194,70,46,142,68,165,19,\n236,1,64,174,187,145,95,37,134,204,23,225,35,23,71,34,82,137,246,128,160,\n89,93,200,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,145,71,\n105,20,19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,32,105,246,0,0,0,\n0,0,91,60,165,195,201,194,8,134,149,216,130,0,192,41,224,136,2,48,176,228,\n1,149,13,195,15,0,200,209,97,71,128,99,32,176,131,192,113,57,143,0,167,131,\n32,230,80,28,202,139,175,237,2,48,189,160,20,1,119,48,87,193,186,129,89,56,\n72,197,209,200,193,185,35,23,71,109,13,219,36,98,232,237,156,13,26,208,211,\n14,102,19,87,137,91,95,128,0,10,64,24,92,0,0,82,2,53,63,240,49,204,202,10,\n14,38,78,44,141,52,207,31,0,0,22,32,129,100,180,8,148,145,78,102,152,80,\n113,50,113,100,105,166,120,248,0,0,177,1,65,196,201,199,20,178,36,227,224,\n0,2,200,3,6,133,41,35,31,0,0,22,1,44,57,137,62,33,179,216,162,152,192,131,\n18,124,162,27,61,138,41,108,32,196,159,16,217,232,235,81,76,104,73,137,62,\n81,13,158,142,181,20,184,16,98,79,136,108,244,244,168,166,56,36,196,159,40,\n134,207,79,74,138,93,10,49,39,194,173,192,158,158,149,20,188,20,98,79,133,\n91,129,61,109,74,41,124,30,68,159,16,217,236,83,108,96,68,137,62,81,13,158,\n197,54,182,17,34,79,136,108,244,117,169,182,52,38,68,159,40,134,207,71,90,\n155,92,8,145,39,196,54,122,122,84,219,28,19,34,79,148,67,103,167,165,77,\n174,133,72,147,225,86,224,79,79,74,155,94,10,145,39,194,173,192,158,182,\n165,54,190,206,25,212,35,208,226,100,150,211,201,29,162,44,140,35,103,0,\n255,192,0,0,0,0,0,0,206,25,228,35,208,226,100,150,211,201,29,162,44,140,35,\n103,0,255,192,0,0,0,0,0,0,206,25,244,35,208,226,100,150,211,201,29,162,44,\n140,35,103,0,255,192,0,0,0,0,0,0,206,26,4,35,208,226,100,150,211,201,29,\n162,44,140,35,103,1,0,0,0,0,0,0,0,0,206,26,20,35,208,226,100,150,211,201,\n29,162,44,140,35,103,1,0,0,0,0,0,0,0,0,206,26,36,35,208,226,100,150,211,\n201,29,162,44,140,35,103,1,0,64,0,0,0,0,0,0,206,26,52,35,208,226,100,150,\n211,201,29,162,44,140,35,103,1,0,64,0,0,0,0,0,0,206,26,68,35,208,226,100,\n150,211,201,29,162,44,140,35,103,1,0,64,0,0,0,0,0,0,206,26,84,35,208,226,\n100,150,211,201,29,162,44,140,35,103,1,0,128,0,0,0,0,0,0,195,154,99,16,38,\n36,0,251,68,117,179,216,162,128,68,72,1,241,13,158,197,20,150,25,18,0,125,\n162,58,217,232,235,117,100,162,136,25,18,0,125,162,58,217,232,235,116,36,\n162,145,2,226,64,15,136,108,244,117,186,178,81,73,129,113,32,7,196,54,122,\n58,221,9,40,165,64,200,144,3,237,17,214,207,79,75,171,37,20,80,200,144,3,\n237,17,214,207,79,75,161,37,20,138,23,18,0,124,67,103,167,165,213,146,138,\n77,11,137,0,62,33,179,211,210,232,73,69,42,133,196,128,31,10,183,2,125,89,\n40,163,5,196,128,31,10,183,2,125,9,40,164,96,200,144,3,224,221,64,172,157,\n89,40,163,134,68,128,31,6,234,5,100,232,73,69,35,133,68,128,31,104,142,182,\n125,89,40,180,0,168,144,3,237,17,214,207,161,37,22,144,19,18,0,124,67,103,\n213,146,139,80,9,137,0,62,33,179,232,73,69,172,5,90,40,153,59,68,117,179,\n216,166,192,77,162,137,147,136,108,246,41,180,176,219,69,19,39,104,142,182,\n122,58,221,89,41,178,6,218,40,153,59,68,117,179,209,214,232,73,77,162,6,90,\n40,153,56,134,207,71,91,171,37,54,152,25,104,162,100,226,27,61,29,110,132,\n148,218,160,109,162,137,147,180,71,91,61,61,46,172,148,217,67,109,20,76,\n157,162,58,217,233,233,116,36,166,209,67,45,20,76,156,67,103,167,165,213,\n146,155,77,12,180,81,50,113,13,158,158,151,66,74,109,84,50,209,68,201,194,\n173,192,159,86,74,108,193,150,138,38,78,21,110,4,250,18,83,104,193,182,138,\n38,78,13,212,10,201,213,146,155,56,109,162,137,147,131,117,2,178,116,36,\n166,209,194,237,20,76,157,162,58,217,245,100,167,16,2,237,20,76,157,162,58,\n217,244,36,167,18,2,173,20,76,156,67,103,213,146,156,80,10,180,81,50,113,\n13,159,66,74,113,97,175,220,48,216,109,192,4,42,22,189,163,0,196,133,0,185,\n80,32,28,78,99,193,18,80,36,4,19,159,141,156,0,178,90,4,74,73,0,22,209,68,\n201,185,129,4,2,8,3,132,64,60,36,4,0,91,240,168,177,69,118,144,157,91,116,\n116,32,32,1,53,216,221,218,170,139,3,234,219,165,0,255,152,185,11,251,232,\n231,188,47,86,227,105,18,1,255,184,170,59,41,92,23,240,110,173,198,209,208,\n36,3,253,188,183,177,82,110,80,224,93,122,32,32,4,144,253,170,34,22,140,7,\n236,161,25,232,237,105,64,63,230,160,158,102,127,59,205,11,217,66,51,210,\n128,127,237,65,60,204,254,119,155,171,197,34,168,48,6,90,162,1,0,39,75,84,\n72,8,9,33,186,162,80,64,76,13,213,19,2,130,96,110,150,181,0,65,6,51,213,20,\n128,65,17,11,213,19,130,137,121,211,210,210,144,6,39,75,84,80,0,201,119,\n234,138,8,41,86,231,71,84,80,129,79,135,186,122,101,224,34,25,69,233,208,3,\n91,141,170,40,96,139,113,180,181,69,36,21,110,54,142,134,168,165,1,176,23,\n212,47,0,216,134,234,87,128,111,117,181,168,128,209,3,70,230,106,192,5,139,\n168,209,234,138,32,36,144,102,235,8,3,146,27,170,40,160,146,132,103,170,40,\n192,115,3,117,69,28,22,113,163,69,170,41,103,1,66,188,17,145,52,104,4,202,\n113,67,76,130,227,72,194,13,240,108,0,0,83,96,0,2,185,0,104,146,84,97,48,0,\n1,90,192,56,169,24,145,179,192,0,5,96,8,56,16,32,128,56,18,52,125,198,86,\n147,186,140,28,50,21,13,39,31,23,60,145,158,56,204,141,47,121,6,155,190,\n188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,199,68,\n14,49,39,199,197,211,116,240,242,113,197,231,18,180,254,4,3,17,46,18,243,\n35,100,128,172,156,146,70,163,150,76,34,248,146,164,108,248,75,204,141,146,\n28,217,115,9,27,79,11,241,173,235,162,160,224,200,2,206,9,113,13,148,192,\n209,18,22,164,146,37,193,57,162,4,249,39,196,128,24,2,178,66,213,136,68,\n201,16,77,209,131,31,192,242,88,96,92,191,151,34,100,136,38,232,255,252,92,\n221,199,197,12,68,209,82,66,212,11,155,185,41,197,13,55,38,3,66,213,47,131,\n250,72,12,162,99,133,116,127,196,32,225,1,3,34,92,170,9,105,164,32,225,64,\n131,156,1,193,133,7,19,39,22,70,154,103,143,128,0,11,16,20,28,76,156,113,\n75,34,78,62,0,0,44,128,48,104,82,146,49,240,0,1,96,11,180,192,0,5,162,1,18,\n160,65,24,131,20,145,25,188,48,132,122,28,76,146,218,121,35,180,69,145,132,\n108,224,31,248,0,0,0,0,0,0,25,188,56,132,122,28,76,146,218,121,35,180,69,\n145,132,108,224,31,248,0,0,0,0,0,0,40,160,45,110,23,30,176,33,184,0,0,181,\n32,29,235,2,27,199,23,0,0,22,196,51,120,129,8,244,56,153,37,180,242,71,104,\n139,35,8,217,192,63,240,0,0,0,0,0,0,51,120,145,8,244,56,153,37,180,242,71,\n104,139,35,8,217,192,64,0,0,0,0,0,0,0,51,120,161,8,244,56,153,37,180,242,\n71,104,139,35,8,217,192,64,0,0,0,0,0,0,0,51,120,177,8,244,56,153,37,180,\n242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,120,193,8,244,56,153,37,\n180,242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,120,209,8,244,56,153,\n37,180,242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,120,225,8,244,56,\n153,37,180,242,71,104,139,35,8,217,192,64,32,0,0,0,0,0,0,32,227,194,0,97,\n57,162,4,246,40,5,34,92,35,68,225,161,166,219,16,16,137,112,52,41,73,29,\n169,1,65,196,201,197,145,166,153,246,8,3,137,204,120,34,74,8,200,58,128,28,\n211,160,130,52,78,26,26,110,248,0,0,170,4,12,70,137,195,38,0,0,42,68,159,7,\n84,3,154,150,16,70,137,195,67,77,223,0,0,20,224,20,160,152,23,223,0,0,20,\n226,9,65,154,232,147,161,115,59,224,0,2,156,84,12,50,9,195,38,0,0,41,133,\n30,224,32,54,186,221,128,60,\n};\n#elif defined(DUK_USE_DOUBLE_ME)\nDUK_INTERNAL const duk_uint8_t duk_builtins_data[4251] = {\n144,148,105,225,32,68,52,228,126,12,104,201,37,132,52,167,194,138,105,244,\n124,57,28,211,57,18,64,52,238,254,44,138,111,171,241,164,19,87,137,30,33,\n167,18,145,159,8,211,137,9,225,42,5,240,145,139,163,163,8,211,137,10,228,\n64,211,19,132,140,93,29,56,70,156,72,119,34,66,146,36,104,137,194,70,46,\n142,172,35,78,36,47,146,195,102,11,240,145,139,163,175,8,211,137,9,228,240,\n242,112,145,139,163,179,8,211,137,8,237,34,130,118,49,116,118,225,26,48,0,\n1,94,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,\n33,8,66,26,180,41,97,167,64,150,34,33,154,112,0,1,87,247,35,79,103,237,198,\n174,216,47,31,23,95,17,13,31,217,96,211,49,50,53,212,77,141,24,0,0,179,10,\n228,240,242,15,128,140,65,128,134,188,0,0,89,167,97,181,224,0,2,205,62,53,\n224,0,2,205,66,237,120,0,0,179,81,204,107,192,0,5,154,150,67,94,0,0,44,212,\n245,90,240,0,1,102,169,162,215,128,0,11,53,93,150,188,0,0,89,171,111,53,\n108,150,163,70,0,0,42,2,249,50,94,124,35,68,225,146,49,13,24,0,0,165,161,\n124,153,47,62,12,130,112,201,24,132,56,97,115,16,0,0,62,31,192,0,0,0,51,48,\n0,0,60,31,192,0,0,0,50,241,32,26,193,55,132,112,161,156,72,135,26,41,200,\n140,114,163,156,201,7,56,79,9,80,47,132,140,93,19,160,43,145,3,76,78,18,49,\n116,78,144,238,68,133,36,72,209,19,132,140,93,19,168,47,146,195,102,11,240,\n145,139,162,117,132,242,120,121,56,72,197,209,59,2,59,72,160,157,140,93,19,\n181,36,242,50,143,36,31,131,162,166,7,144,238,133,227,226,235,224,242,161,\n249,18,21,100,20,207,44,199,151,180,122,89,135,152,154,121,153,199,156,158,\n121,218,7,158,162,121,250,71,160,166,122,26,135,162,170,122,58,199,164,16,\n240,70,68,226,27,51,199,138,120,35,34,112,171,112,38,121,1,124,153,47,62,\n17,162,112,201,19,211,11,228,201,121,240,100,19,134,72,158,160,91,201,18,\n186,44,3,68,79,122,168,151,115,165,40,21,18,227,65,198,231,200,8,68,184,84,\n53,19,38,120,128,145,144,78,25,59,72,163,48,64,144,200,39,12,157,164,80,46,\n185,143,115,72,217,230,72,9,35,68,225,147,180,138,51,68,9,17,162,112,201,\n218,69,2,235,152,247,52,141,158,108,128,98,72,64,121,51,132,4,81,164,144,\n128,242,104,136,0,16,92,38,14,49,39,199,197,211,116,240,242,113,197,231,18,\n53,189,116,65,131,18,124,117,155,199,197,207,36,103,142,12,146,20,80,249,\n186,60,116,4,204,73,241,214,111,31,23,60,145,158,56,208,48,146,229,146,3,2,\n82,65,155,195,94,3,10,36,4,201,196,64,56,100,42,26,78,62,46,121,35,60,113,\n152,16,25,10,134,147,143,139,158,72,205,4,151,21,0,73,16,11,230,144,12,88,\n144,153,39,52,144,69,241,37,72,217,240,151,153,27,36,57,178,230,16,16,137,\n114,68,2,200,62,81,1,8,151,11,23,100,141,229,18,6,34,92,37,230,70,201,1,89,\n57,36,2,40,152,151,44,129,83,18,124,117,155,199,197,207,36,103,142,75,12,\n11,151,46,89,40,18,37,200,64,12,154,236,252,238,185,23,95,213,1,132,234,0,\n194,245,128,14,56,37,199,89,188,124,92,242,70,120,232,16,26,137,113,241,\n116,221,60,60,156,113,122,36,10,62,46,121,35,60,113,18,225,27,70,18,32,10,\n201,211,32,67,107,104,100,42,26,78,24,147,153,35,181,181,207,64,67,107,104,\n100,42,26,78,72,147,153,35,181,181,207,68,16,218,218,91,156,170,63,134,36,\n230,72,237,109,116,136,16,218,218,91,156,170,63,146,36,230,72,237,109,116,\n137,16,96,128,228,2,6,191,46,3,71,147,68,4,16,22,188,169,240,16,40,104,242,\n135,198,171,44,68,65,5,217,231,215,6,231,62,188,8,49,1,3,162,92,4,98,12,41,\n7,33,148,53,242,128,97,32,130,3,9,205,16,38,199,198,14,9,0,111,115,225,0,8,\n250,72,240,207,128,241,37,73,25,18,40,0,178,58,11,56,192,2,201,104,17,35,\n160,9,39,70,114,8,6,147,214,129,18,74,240,30,141,145,208,89,203,62,3,161,\n163,37,248,226,185,244,11,88,37,62,33,163,37,248,226,185,252,0,127,255,130,\n146,164,142,32,26,1,36,230,18,1,164,7,43,163,194,0,71,128,105,64,216,7,192,\n52,192,197,66,230,72,192,52,224,209,32,232,34,68,62,129,113,32,232,34,114,\n40,49,231,16,254,0,63,255,208,99,2,140,44,92,206,8,224,143,4,225,147,210,\n124,13,44,92,206,9,195,39,30,228,54,126,163,225,200,169,198,133,42,166,191,\n246,3,11,251,0,24,71,4,120,9,251,8,10,17,193,30,9,195,39,1,63,105,1,98,112,\n201,199,185,13,159,1,63,105,32,48,156,209,2,126,227,224,58,26,50,95,142,47,\n192,208,22,176,74,124,67,70,75,241,197,248,26,64,213,184,64,89,56,39,49,\n224,137,62,36,2,176,19,17,254,68,3,196,143,88,4,79,162,0,210,32,34,35,253,\n72,5,146,208,34,125,144,5,147,214,137,253,208,9,149,3,41,197,13,55,233,0,\n185,187,139,117,137,30,8,18,39,172,1,25,187,139,112,128,178,113,110,177,35,\n193,2,68,245,128,23,55,114,143,121,35,193,2,68,245,130,8,205,220,91,132,5,\n147,148,123,201,30,8,18,39,172,16,18,113,67,63,128,3,68,143,32,39,243,32,\n42,83,4,103,46,89,19,63,224,208,16,70,142,92,178,38,127,193,164,8,67,68,\n186,12,146,247,154,1,165,64,202,113,252,160,131,32,7,35,167,26,50,235,231,\n130,48,179,192,65,148,69,19,214,2,251,85,2,232,72,31,255,253,239,255,255,\n255,255,226,122,196,55,106,160,93,9,0,0,0,0,0,4,0,0,3,49,0,0,3,225,252,0,0,\n0,0,143,94,233,34,104,169,54,144,210,161,168,158,32,0,0,120,63,128,0,0,0,\n17,235,72,96,77,21,38,210,26,84,53,19,196,0,0,15,15,240,0,0,0,0,253,35,228,\n133,185,176,0,0,44,15,0,0,0,0,8,117,128,190,212,128,82,109,33,179,33,137,\n24,31,255,231,232,127,255,255,255,228,58,196,55,106,64,41,54,144,217,144,\n196,140,15,255,243,252,63,255,255,255,241,15,4,100,78,33,179,60,120,167,\n130,50,39,10,183,2,103,144,113,8,151,10,134,162,100,221,16,18,137,113,13,\n153,12,72,238,137,1,81,46,52,28,110,232,148,53,18,228,128,82,113,13,153,12,\n72,238,137,142,73,78,52,0,0,0,0,0,0,0,0,8,58,254,1,12,38,248,134,23,130,0,\n60,221,194,162,228,30,244,128,217,187,132,187,220,210,54,104,2,247,132,5,\n205,220,124,72,36,73,14,110,252,132,25,128,193,94,8,200,149,200,3,237,38,\n43,31,192,54,186,213,128,57,45,56,210,0,0,62,31,192,0,0,0,49,90,251,224,6,\n77,220,24,38,78,74,113,67,77,124,16,50,110,228,208,194,114,83,138,26,107,\n224,172,37,240,97,41,187,139,112,128,178,112,96,153,57,41,197,13,53,240,\n113,41,187,139,112,128,178,114,104,97,57,41,197,13,53,240,128,195,95,8,44,\n61,240,132,216,93,33,133,192,128,14,98,79,147,67,9,129,0,44,196,159,11,69,\n175,152,32,35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,\n39,198,57,179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,\n240,96,153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,\n197,144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,\n150,22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,\n161,166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,\n100,39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,\n18,32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,\n72,68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,\n46,16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,\n117,11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,\n178,36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,\n173,191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,\n117,35,43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,\n131,4,201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,\n102,123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,\n162,215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,\n192,131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,181,55,136,\n200,51,128,114,108,28,100,128,0,0,0,0,0,0,0,12,110,127,32,98,115,249,73,\n117,243,249,67,21,159,202,38,47,63,148,86,8,75,144,94,50,1,38,73,79,204,67,\n95,231,1,6,128,14,79,129,185,40,249,18,149,181,207,142,199,155,172,248,172,\n89,183,207,140,198,137,175,200,0,159,72,10,5,21,220,138,120,74,129,124,36,\n98,232,228,74,81,62,160,20,10,107,185,21,114,32,105,137,194,70,46,142,68,\n165,19,235,1,64,170,187,145,119,34,66,146,36,104,137,194,70,46,142,68,165,\n19,236,1,64,174,187,145,95,37,134,204,23,225,35,23,71,34,82,137,246,128,\n160,89,93,200,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,145,\n71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,0,118,105,160,\n0,0,0,0,91,60,165,195,201,194,8,134,149,216,130,0,192,41,224,136,2,48,176,\n228,1,149,13,195,15,0,200,209,97,71,128,99,32,176,131,192,113,57,143,0,167,\n131,32,230,80,28,202,139,175,237,2,48,189,160,20,1,119,48,87,193,186,129,\n89,56,72,197,209,200,193,185,35,23,71,109,13,219,36,98,232,237,156,13,26,\n208,211,14,102,19,87,137,91,95,128,0,10,64,24,92,0,0,82,2,53,63,240,49,204,\n202,10,14,38,78,44,141,52,207,31,0,0,22,32,129,100,180,8,148,145,78,102,\n152,80,113,50,113,100,105,166,120,248,0,0,177,1,65,196,201,199,20,178,36,\n227,224,0,2,200,3,6,133,41,35,31,0,0,22,1,44,57,137,62,33,179,216,162,152,\n192,131,18,124,162,27,61,138,41,108,32,196,159,16,217,232,235,81,76,104,73,\n137,62,81,13,158,142,181,20,184,16,98,79,136,108,244,244,168,166,56,36,196,\n159,40,134,207,79,74,138,93,10,49,39,194,173,192,158,158,149,20,188,20,98,\n79,133,91,129,61,109,74,41,124,30,68,159,16,217,236,83,108,96,68,137,62,81,\n13,158,197,54,182,17,34,79,136,108,244,117,169,182,52,38,68,159,40,134,207,\n71,90,155,92,8,145,39,196,54,122,122,84,219,28,19,34,79,148,67,103,167,165,\n77,174,133,72,147,225,86,224,79,79,74,155,94,10,145,39,194,173,192,158,182,\n165,54,190,206,25,212,35,208,226,100,150,211,201,29,162,44,140,35,103,0,0,\n3,192,252,0,0,0,0,206,25,228,35,208,226,100,150,211,201,29,162,44,140,35,\n103,0,0,3,192,252,0,0,0,0,206,25,244,35,208,226,100,150,211,201,29,162,44,\n140,35,103,0,0,3,192,252,0,0,0,0,206,26,4,35,208,226,100,150,211,201,29,\n162,44,140,35,103,0,0,0,1,0,0,0,0,0,206,26,20,35,208,226,100,150,211,201,\n29,162,44,140,35,103,0,0,0,1,0,0,0,0,0,206,26,36,35,208,226,100,150,211,\n201,29,162,44,140,35,103,0,0,0,65,0,0,0,0,0,206,26,52,35,208,226,100,150,\n211,201,29,162,44,140,35,103,0,0,0,65,0,0,0,0,0,206,26,68,35,208,226,100,\n150,211,201,29,162,44,140,35,103,0,0,0,65,0,0,0,0,0,206,26,84,35,208,226,\n100,150,211,201,29,162,44,140,35,103,0,0,0,129,0,0,0,0,0,195,154,99,16,38,\n36,0,251,68,117,179,216,162,128,68,72,1,241,13,158,197,20,150,25,18,0,125,\n162,58,217,232,235,117,100,162,136,25,18,0,125,162,58,217,232,235,116,36,\n162,145,2,226,64,15,136,108,244,117,186,178,81,73,129,113,32,7,196,54,122,\n58,221,9,40,165,64,200,144,3,237,17,214,207,79,75,171,37,20,80,200,144,3,\n237,17,214,207,79,75,161,37,20,138,23,18,0,124,67,103,167,165,213,146,138,\n77,11,137,0,62,33,179,211,210,232,73,69,42,133,196,128,31,10,183,2,125,89,\n40,163,5,196,128,31,10,183,2,125,9,40,164,96,200,144,3,224,221,64,172,157,\n89,40,163,134,68,128,31,6,234,5,100,232,73,69,35,133,68,128,31,104,142,182,\n125,89,40,180,0,168,144,3,237,17,214,207,161,37,22,144,19,18,0,124,67,103,\n213,146,139,80,9,137,0,62,33,179,232,73,69,172,5,90,40,153,59,68,117,179,\n216,166,192,77,162,137,147,136,108,246,41,180,176,219,69,19,39,104,142,182,\n122,58,221,89,41,178,6,218,40,153,59,68,117,179,209,214,232,73,77,162,6,90,\n40,153,56,134,207,71,91,171,37,54,152,25,104,162,100,226,27,61,29,110,132,\n148,218,160,109,162,137,147,180,71,91,61,61,46,172,148,217,67,109,20,76,\n157,162,58,217,233,233,116,36,166,209,67,45,20,76,156,67,103,167,165,213,\n146,155,77,12,180,81,50,113,13,158,158,151,66,74,109,84,50,209,68,201,194,\n173,192,159,86,74,108,193,150,138,38,78,21,110,4,250,18,83,104,193,182,138,\n38,78,13,212,10,201,213,146,155,56,109,162,137,147,131,117,2,178,116,36,\n166,209,194,237,20,76,157,162,58,217,245,100,167,16,2,237,20,76,157,162,58,\n217,244,36,167,18,2,173,20,76,156,67,103,213,146,156,80,10,180,81,50,113,\n13,159,66,74,113,97,175,220,48,216,109,192,4,42,22,189,163,0,196,133,0,185,\n80,32,28,78,99,193,18,80,36,4,19,159,141,156,0,178,90,4,74,73,0,22,209,68,\n201,185,129,4,2,8,3,132,64,60,36,0,171,240,84,6,149,113,72,176,157,91,116,\n116,32,88,181,129,32,11,42,218,221,131,234,219,165,1,8,187,152,255,188,231,\n235,248,47,86,227,105,18,2,56,175,185,255,244,17,91,40,110,173,198,209,208,\n36,7,188,189,179,240,238,82,97,80,93,122,32,125,144,132,160,12,22,162,42,7,\n236,161,25,232,237,105,64,158,160,230,63,205,59,127,102,11,217,66,51,210,\n129,61,65,236,127,154,118,254,205,171,197,34,168,48,6,90,162,1,0,39,75,84,\n72,8,9,33,186,162,80,64,76,13,213,19,2,130,96,110,150,181,0,65,6,51,213,20,\n128,65,17,11,213,19,130,137,121,211,210,210,144,6,39,75,84,80,0,201,119,\n234,138,8,41,86,231,71,84,80,129,79,135,186,122,101,224,34,25,69,233,208,3,\n91,141,170,40,96,139,113,180,181,69,36,21,110,54,142,134,168,165,1,176,23,\n212,47,0,216,134,234,87,128,111,117,181,168,128,209,3,70,230,106,192,5,139,\n168,209,234,138,32,36,144,102,235,8,3,146,27,170,40,160,146,132,103,170,40,\n192,115,3,117,69,28,22,113,163,69,170,41,103,1,66,188,17,145,52,104,4,202,\n113,67,76,130,227,72,194,13,240,108,0,0,83,96,0,2,185,0,104,146,84,97,48,0,\n1,90,192,56,169,24,145,179,192,0,5,96,8,56,16,32,128,56,18,52,125,198,86,\n147,186,140,28,50,21,13,39,31,23,60,145,158,56,204,141,47,121,6,155,190,\n188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,199,68,\n14,49,39,199,197,211,116,240,242,113,197,231,18,180,254,4,3,17,46,18,243,\n35,100,128,172,156,146,70,163,150,76,34,248,146,164,108,248,75,204,141,146,\n28,217,115,9,27,79,11,241,173,235,162,160,224,200,2,206,9,113,13,148,192,\n209,18,22,164,146,37,193,57,162,4,249,39,196,128,24,2,178,66,213,136,68,\n201,16,77,209,131,31,192,242,88,96,92,191,151,34,100,136,38,232,255,252,92,\n221,199,197,12,68,209,82,66,212,11,155,185,41,197,13,55,38,3,66,213,47,131,\n250,72,12,162,99,133,116,127,196,32,225,1,3,34,92,170,9,105,164,32,225,64,\n131,156,1,193,133,7,19,39,22,70,154,103,143,128,0,11,16,20,28,76,156,113,\n75,34,78,62,0,0,44,128,48,104,82,146,49,240,0,1,96,11,180,192,0,5,162,1,18,\n160,65,24,131,20,145,25,188,48,132,122,28,76,146,218,121,35,180,69,145,132,\n108,224,0,0,120,31,128,0,0,0,25,188,56,132,122,28,76,146,218,121,35,180,69,\n145,132,108,224,0,0,120,31,128,0,0,0,40,160,45,110,23,30,176,33,184,0,0,\n181,32,29,235,2,27,199,23,0,0,22,196,51,120,129,8,244,56,153,37,180,242,71,\n104,139,35,8,217,192,0,0,240,63,0,0,0,0,51,120,145,8,244,56,153,37,180,242,\n71,104,139,35,8,217,192,0,0,0,64,0,0,0,0,51,120,161,8,244,56,153,37,180,\n242,71,104,139,35,8,217,192,0,0,0,64,0,0,0,0,51,120,177,8,244,56,153,37,\n180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,120,193,8,244,56,153,\n37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,120,209,8,244,56,\n153,37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,120,225,8,244,\n56,153,37,180,242,71,104,139,35,8,217,192,0,0,32,64,0,0,0,0,32,227,194,0,\n97,57,162,4,246,40,5,34,92,35,68,225,161,166,219,16,16,137,112,52,41,73,29,\n169,1,65,196,201,197,145,166,153,246,8,3,137,204,120,34,74,8,200,58,128,28,\n211,160,130,52,78,26,26,110,248,0,0,170,4,12,70,137,195,38,0,0,42,68,159,7,\n84,3,154,150,16,70,137,195,67,77,223,0,0,20,224,20,160,152,23,223,0,0,20,\n226,9,65,154,232,147,161,115,59,224,0,2,156,84,12,50,9,195,38,0,0,41,133,\n30,224,32,54,186,221,128,60,\n};\n#else\n#error invalid endianness defines\n#endif\n#endif  /* DUK_USE_ROM_OBJECTS */\n\n/* automatic undefs */\n#undef DUK__REFCINIT\n#line 1 \"duk_error_macros.c\"\n/*\n *  Error and fatal handling.\n */\n\n/* #include duk_internal.h -> already included */\n\n#define DUK__ERRFMT_BUFSIZE  256  /* size for formatting buffers */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\nDUK_INTERNAL DUK_COLD void duk_err_handle_error_fmt(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *fmt, ...) {\n\tva_list ap;\n\tchar msg[DUK__ERRFMT_BUFSIZE];\n\tva_start(ap, fmt);\n\t(void) DUK_VSNPRINTF(msg, sizeof(msg), fmt, ap);\n\tmsg[sizeof(msg) - 1] = (char) 0;\n\tduk_err_create_and_throw(thr, (duk_errcode_t) (line_and_code >> 24), msg, filename, (duk_int_t) (line_and_code & 0x00ffffffL));\n\tva_end(ap);  /* dead code, but ensures portability (see Linux man page notes) */\n}\n\nDUK_INTERNAL DUK_COLD void duk_err_handle_error(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *msg) {\n\tduk_err_create_and_throw(thr, (duk_errcode_t) (line_and_code >> 24), msg, filename, (duk_int_t) (line_and_code & 0x00ffffffL));\n}\n\n#else  /* DUK_USE_VERBOSE_ERRORS */\n\nDUK_INTERNAL DUK_COLD void duk_err_handle_error(duk_hthread *thr, duk_errcode_t code) {\n\tduk_err_create_and_throw(thr, code);\n}\n\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n/*\n *  Error throwing helpers\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\nDUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) {\n\tDUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, \"%s required, found %s (stack index %ld)\",\n\t                   expect_name, duk_get_type_name(thr, idx), (long) idx);\n}\n#else\nDUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) {\n\tDUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, \"%s required, found %s (stack index %ld)\",\n\t                   expect_name, duk_push_string_readable(thr, idx), (long) idx);\n}\n#endif\nDUK_INTERNAL DUK_COLD void duk_err_error_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, DUK_STR_INTERNAL_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_error_alloc_failed(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, DUK_STR_ALLOC_FAILED);\n}\nDUK_INTERNAL DUK_COLD void duk_err_error(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, message);\n}\nDUK_INTERNAL DUK_COLD void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, message);\n}\nDUK_INTERNAL DUK_COLD void duk_err_range_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx) {\n\tDUK_ERROR_RAW_FMT1(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, \"invalid stack index %ld\", (long) (idx));\n}\nDUK_INTERNAL DUK_COLD void duk_err_range_push_beyond(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, DUK_STR_PUSH_BEYOND_ALLOC_STACK);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type_invalid_args(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_ARGS);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type_invalid_state(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_STATE);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type_invalid_trap_result(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_TRAP_RESULT);\n}\n#else\n/* The file/line arguments are NULL and 0, they're ignored by DUK_ERROR_RAW()\n * when non-verbose errors are used.\n */\n\nDUK_NORETURN(DUK_LOCAL_DECL void duk__err_shared(duk_hthread *thr, duk_errcode_t code));\nDUK_LOCAL void duk__err_shared(duk_hthread *thr, duk_errcode_t code) {\n\tDUK_ERROR_RAW(thr, NULL, 0, code, NULL);\n}\nDUK_INTERNAL DUK_COLD void duk_err_error(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_range(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_RANGE_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_eval(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_EVAL_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_reference(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_REFERENCE_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_syntax(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_SYNTAX_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_TYPE_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_uri(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_URI_ERROR);\n}\n#endif\n\n/*\n *  Default fatal error handler\n */\n\nDUK_INTERNAL DUK_COLD void duk_default_fatal_handler(void *udata, const char *msg) {\n\tDUK_UNREF(udata);\n\tDUK_UNREF(msg);\n\n\tmsg = msg ? msg : \"NULL\";\n\n#if defined(DUK_USE_FATAL_HANDLER)\n\t/* duk_config.h provided a custom default fatal handler. */\n\tDUK_D(DUK_DPRINT(\"custom default fatal error handler called: %s\", msg));\n\tDUK_USE_FATAL_HANDLER(udata, msg);\n#elif defined(DUK_USE_CPP_EXCEPTIONS)\n\t/* With C++ use a duk_fatal_exception which user code can catch in\n\t * a natural way.\n\t */\n\tDUK_D(DUK_DPRINT(\"built-in default C++ fatal error handler called: %s\", msg));\n\tthrow duk_fatal_exception(msg);\n#else\n\t/* Default behavior is to abort() on error.  There's no printout\n\t * which makes this awkward, so it's always recommended to use an\n\t * explicit fatal error handler.\n\t *\n\t * ====================================================================\n\t * NOTE: If you are seeing this, you are most likely dealing with an\n\t * uncaught error.  You should provide a fatal error handler in Duktape\n\t * heap creation, and should consider using a protected call as your\n\t * first call into an empty Duktape context to properly handle errors.\n\t * See:\n\t *   - http://duktape.org/guide.html#error-handling\n\t *   - http://wiki.duktape.org/HowtoFatalErrors.html\n\t *   - http://duktape.org/api.html#taglist-protected\n\t * ====================================================================\n\t */\n\tDUK_D(DUK_DPRINT(\"built-in default fatal error handler called: %s\", msg));\n\tDUK_ABORT();\n#endif\n\n\tDUK_D(DUK_DPRINT(\"fatal error handler returned, enter forever loop\"));\n\tfor (;;) {\n\t\t/* Loop forever to ensure we don't return. */\n\t}\n}\n\n/* automatic undefs */\n#undef DUK__ERRFMT_BUFSIZE\n#line 1 \"duk_unicode_support.c\"\n/*\n *  Various Unicode help functions for character classification predicates,\n *  case conversion, decoding, etc.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Fast path tables\n */\n\n#if defined(DUK_USE_IDCHAR_FASTPATH)\nDUK_INTERNAL const duk_int8_t duk_is_idchar_tab[128] = {\n\t/* 0: not IdentifierStart or IdentifierPart\n\t * 1: IdentifierStart and IdentifierPart\n\t * -1: IdentifierPart only\n\t */\n\t0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   /* 0x00...0x0f */\n\t0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   /* 0x10...0x1f */\n\t0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   /* 0x20...0x2f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0,  0,  0,  0,  0,  0,   /* 0x30...0x3f */\n\t0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,   /* 0x40...0x4f */\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  1,   /* 0x50...0x5f */\n\t0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,   /* 0x60...0x6f */\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0    /* 0x70...0x7f */\n};\n#endif\n\n/*\n *  XUTF-8 and CESU-8 encoding/decoding\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_get_xutf8_length(duk_ucodepoint_t cp) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tif (x < 0x80UL) {\n\t\t/* 7 bits */\n\t\treturn 1;\n\t} else if (x < 0x800UL) {\n\t\t/* 11 bits */\n\t\treturn 2;\n\t} else if (x < 0x10000UL) {\n\t\t/* 16 bits */\n\t\treturn 3;\n\t} else if (x < 0x200000UL) {\n\t\t/* 21 bits */\n\t\treturn 4;\n\t} else if (x < 0x4000000UL) {\n\t\t/* 26 bits */\n\t\treturn 5;\n\t} else if (x < (duk_ucodepoint_t) 0x80000000UL) {\n\t\t/* 31 bits */\n\t\treturn 6;\n\t} else {\n\t\t/* 36 bits */\n\t\treturn 7;\n\t}\n}\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL duk_small_int_t duk_unicode_get_cesu8_length(duk_ucodepoint_t cp) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tif (x < 0x80UL) {\n\t\t/* 7 bits */\n\t\treturn 1;\n\t} else if (x < 0x800UL) {\n\t\t/* 11 bits */\n\t\treturn 2;\n\t} else if (x < 0x10000UL) {\n\t\t/* 16 bits */\n\t\treturn 3;\n\t} else {\n\t\t/* Encoded as surrogate pair, each encoding to 3 bytes for\n\t\t * 6 bytes total.  Codepoints above U+10FFFF encode as 6 bytes\n\t\t * too, see duk_unicode_encode_cesu8().\n\t\t  */\n\t\treturn 3 + 3;\n\t}\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\nDUK_INTERNAL const duk_uint8_t duk_unicode_xutf8_markers[7] = {\n\t0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe\n};\n\n/* Encode to extended UTF-8; 'out' must have space for at least\n * DUK_UNICODE_MAX_XUTF8_LENGTH bytes.  Allows encoding of any\n * 32-bit (unsigned) codepoint.\n */\nDUK_INTERNAL duk_small_int_t duk_unicode_encode_xutf8(duk_ucodepoint_t cp, duk_uint8_t *out) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tduk_small_int_t len;\n\tduk_uint8_t marker;\n\tduk_small_int_t i;\n\n\tlen = duk_unicode_get_xutf8_length(cp);\n\tDUK_ASSERT(len > 0);\n\n\tmarker = duk_unicode_xutf8_markers[len - 1];  /* 64-bit OK because always >= 0 */\n\n\ti = len;\n\tDUK_ASSERT(i > 0);\n\tdo {\n\t\ti--;\n\t\tif (i > 0) {\n\t\t\tout[i] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\t\tx >>= 6;\n\t\t} else {\n\t\t\t/* Note: masking of 'x' is not necessary because of\n\t\t\t * range check and shifting -> no bits overlapping\n\t\t\t * the marker should be set.\n\t\t\t */\n\t\t\tout[0] = (duk_uint8_t) (marker + x);\n\t\t}\n\t} while (i > 0);\n\n\treturn len;\n}\n\n/* Encode to CESU-8; 'out' must have space for at least\n * DUK_UNICODE_MAX_CESU8_LENGTH bytes; codepoints above U+10FFFF\n * will encode to garbage but won't overwrite the output buffer.\n */\nDUK_INTERNAL duk_small_int_t duk_unicode_encode_cesu8(duk_ucodepoint_t cp, duk_uint8_t *out) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tduk_small_int_t len;\n\n\tif (x < 0x80UL) {\n\t\tout[0] = (duk_uint8_t) x;\n\t\tlen = 1;\n\t} else if (x < 0x800UL) {\n\t\tout[0] = (duk_uint8_t) (0xc0 + ((x >> 6) & 0x1f));\n\t\tout[1] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\tlen = 2;\n\t} else if (x < 0x10000UL) {\n\t\t/* surrogate pairs get encoded here */\n\t\tout[0] = (duk_uint8_t) (0xe0 + ((x >> 12) & 0x0f));\n\t\tout[1] = (duk_uint8_t) (0x80 + ((x >> 6) & 0x3f));\n\t\tout[2] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\tlen = 3;\n\t} else {\n\t\t/*\n\t\t *  Unicode codepoints above U+FFFF are encoded as surrogate\n\t\t *  pairs here.  This ensures that all CESU-8 codepoints are\n\t\t *  16-bit values as expected in ECMAScript.  The surrogate\n\t\t *  pairs always get a 3-byte encoding (each) in CESU-8.\n\t\t *  See: http://en.wikipedia.org/wiki/Surrogate_pair\n\t\t *\n\t\t *  20-bit codepoint, 10 bits (A and B) per surrogate pair:\n\t\t *\n\t\t *    x = 0b00000000 0000AAAA AAAAAABB BBBBBBBB\n\t\t *  sp1 = 0b110110AA AAAAAAAA  (0xd800 + ((x >> 10) & 0x3ff))\n\t\t *  sp2 = 0b110111BB BBBBBBBB  (0xdc00 + (x & 0x3ff))\n\t\t *\n\t\t *  Encoded into CESU-8:\n\t\t *\n\t\t *  sp1 -> 0b11101101  (0xe0 + ((sp1 >> 12) & 0x0f))\n\t\t *      -> 0b1010AAAA  (0x80 + ((sp1 >> 6) & 0x3f))\n\t\t *      -> 0b10AAAAAA  (0x80 + (sp1 & 0x3f))\n\t\t *  sp2 -> 0b11101101  (0xe0 + ((sp2 >> 12) & 0x0f))\n\t\t *      -> 0b1011BBBB  (0x80 + ((sp2 >> 6) & 0x3f))\n\t\t *      -> 0b10BBBBBB  (0x80 + (sp2 & 0x3f))\n\t\t *\n\t\t *  Note that 0x10000 must be subtracted first.  The code below\n\t\t *  avoids the sp1, sp2 temporaries which saves around 20 bytes\n\t\t *  of code.\n\t\t */\n\n\t\tx -= 0x10000UL;\n\n\t\tout[0] = (duk_uint8_t) (0xed);\n\t\tout[1] = (duk_uint8_t) (0xa0 + ((x >> 16) & 0x0f));\n\t\tout[2] = (duk_uint8_t) (0x80 + ((x >> 10) & 0x3f));\n\t\tout[3] = (duk_uint8_t) (0xed);\n\t\tout[4] = (duk_uint8_t) (0xb0 + ((x >> 6) & 0x0f));\n\t\tout[5] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\tlen = 6;\n\t}\n\n\treturn len;\n}\n\n/* Decode helper.  Return zero on error. */\nDUK_INTERNAL duk_small_int_t duk_unicode_decode_xutf8(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_ucodepoint_t *out_cp) {\n\tconst duk_uint8_t *p;\n\tduk_uint32_t res;\n\tduk_uint_fast8_t ch;\n\tduk_small_int_t n;\n\n\tDUK_UNREF(thr);\n\n\tp = *ptr;\n\tif (p < ptr_start || p >= ptr_end) {\n\t\tgoto fail;\n\t}\n\n\t/*\n\t *  UTF-8 decoder which accepts longer than standard byte sequences.\n\t *  This allows full 32-bit code points to be used.\n\t */\n\n\tch = (duk_uint_fast8_t) (*p++);\n\tif (ch < 0x80) {\n\t\t/* 0xxx xxxx   [7 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x7f);\n\t\tn = 0;\n\t} else if (ch < 0xc0) {\n\t\t/* 10xx xxxx -> invalid */\n\t\tgoto fail;\n\t} else if (ch < 0xe0) {\n\t\t/* 110x xxxx   10xx xxxx   [11 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x1f);\n\t\tn = 1;\n\t} else if (ch < 0xf0) {\n\t\t/* 1110 xxxx   10xx xxxx   10xx xxxx   [16 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x0f);\n\t\tn = 2;\n\t} else if (ch < 0xf8) {\n\t\t/* 1111 0xxx   10xx xxxx   10xx xxxx   10xx xxxx   [21 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x07);\n\t\tn = 3;\n\t} else if (ch < 0xfc) {\n\t\t/* 1111 10xx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [26 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x03);\n\t\tn = 4;\n\t} else if (ch < 0xfe) {\n\t\t/* 1111 110x   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [31 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x01);\n\t\tn = 5;\n\t} else if (ch < 0xff) {\n\t\t/* 1111 1110   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [36 bits] */\n\t\tres = (duk_uint32_t) (0);\n\t\tn = 6;\n\t} else {\n\t\t/* 8-byte format could be:\n\t\t * 1111 1111   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [41 bits]\n\t\t *\n\t\t * However, this format would not have a zero bit following the\n\t\t * leading one bits and would not allow 0xFF to be used as an\n\t\t * \"invalid xutf-8\" marker for internal keys.  Further, 8-byte\n\t\t * encodings (up to 41 bit code points) are not currently needed.\n\t\t */\n\t\tgoto fail;\n\t}\n\n\tDUK_ASSERT(p >= ptr_start);  /* verified at beginning */\n\tif (p + n > ptr_end) {\n\t\t/* check pointer at end */\n\t\tgoto fail;\n\t}\n\n\twhile (n > 0) {\n\t\tDUK_ASSERT(p >= ptr_start && p < ptr_end);\n\t\tch = (duk_uint_fast8_t) (*p++);\n#if 0\n\t\tif (ch & 0xc0 != 0x80) {\n\t\t\t/* not a continuation byte */\n\t\t\tp--;\n\t\t\t*ptr = p;\n\t\t\t*out_cp = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\treturn 1;\n\t\t}\n#endif\n\t\tres = (res << 6) + (duk_uint32_t) (ch & 0x3f);\n\t\tn--;\n\t}\n\n\t*ptr = p;\n\t*out_cp = res;\n\treturn 1;\n\n fail:\n\treturn 0;\n}\n\n/* used by e.g. duk_regexp_executor.c, string built-ins */\nDUK_INTERNAL duk_ucodepoint_t duk_unicode_decode_xutf8_checked(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end) {\n\tduk_ucodepoint_t cp;\n\n\tif (duk_unicode_decode_xutf8(thr, ptr, ptr_start, ptr_end, &cp)) {\n\t\treturn cp;\n\t}\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Compute (extended) utf-8 length without codepoint encoding validation,\n * used for string interning.\n *\n * NOTE: This algorithm is performance critical, more so than string hashing\n * in some cases.  It is needed when interning a string and needs to scan\n * every byte of the string with no skipping.  Having an ASCII fast path\n * is useful if possible in the algorithm.  The current algorithms were\n * chosen from several variants, based on x64 gcc -O2 testing.  See:\n * https://github.com/svaarala/duktape/pull/422\n *\n * NOTE: must match tools/dukutil.py:duk_unicode_unvalidated_utf8_length().\n */\n\n#if defined(DUK_USE_PREFER_SIZE)\n/* Small variant; roughly 150 bytes smaller than the fast variant. */\nDUK_INTERNAL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_size_t ncont;\n\tduk_size_t clen;\n\n\tp = data;\n\tp_end = data + blen;\n\tncont = 0;\n\twhile (p != p_end) {\n\t\tduk_uint8_t x;\n\t\tx = *p++;\n\t\tif (DUK_UNLIKELY(x >= 0x80 && x <= 0xbf)) {\n\t\t\tncont++;\n\t\t}\n\t}\n\n\tDUK_ASSERT(ncont <= blen);\n\tclen = blen - ncont;\n\tDUK_ASSERT(clen <= blen);\n\treturn clen;\n}\n#else  /* DUK_USE_PREFER_SIZE */\n/* This seems like a good overall approach.  Fast path for ASCII in 4 byte\n * blocks.\n */\nDUK_INTERNAL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint32_t *p32_end;\n\tconst duk_uint32_t *p32;\n\tduk_size_t ncont;\n\tduk_size_t clen;\n\n\tncont = 0;  /* number of continuation (non-initial) bytes in [0x80,0xbf] */\n\tp = data;\n\tp_end = data + blen;\n\tif (blen < 16) {\n\t\tgoto skip_fastpath;\n\t}\n\n\t/* Align 'p' to 4; the input data may have arbitrary alignment.\n\t * End of string check not needed because blen >= 16.\n\t */\n\twhile (((duk_size_t) (const void *) p) & 0x03U) {\n\t\tduk_uint8_t x;\n\t\tx = *p++;\n\t\tif (DUK_UNLIKELY(x >= 0x80 && x <= 0xbf)) {\n\t\t\tncont++;\n\t\t}\n\t}\n\n\t/* Full, aligned 4-byte reads. */\n\tp32_end = (const duk_uint32_t *) (const void *) (p + ((duk_size_t) (p_end - p) & (duk_size_t) (~0x03)));\n\tp32 = (const duk_uint32_t *) (const void *) p;\n\twhile (p32 != (const duk_uint32_t *) p32_end) {\n\t\tduk_uint32_t x;\n\t\tx = *p32++;\n\t\tif (DUK_LIKELY((x & 0x80808080UL) == 0)) {\n\t\t\t;  /* ASCII fast path */\n\t\t} else {\n\t\t\t/* Flip highest bit of each byte which changes\n\t\t\t * the bit pattern 10xxxxxx into 00xxxxxx which\n\t\t\t * allows an easy bit mask test.\n\t\t\t */\n\t\t\tx ^= 0x80808080UL;\n\t\t\tif (DUK_UNLIKELY(!(x & 0xc0000000UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(!(x & 0x00c00000UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(!(x & 0x0000c000UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(!(x & 0x000000c0UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t}\n\t}\n\tp = (const duk_uint8_t *) p32;\n\t/* Fall through to handle the rest. */\n\n skip_fastpath:\n\twhile (p != p_end) {\n\t\tduk_uint8_t x;\n\t\tx = *p++;\n\t\tif (DUK_UNLIKELY(x >= 0x80 && x <= 0xbf)) {\n\t\t\tncont++;\n\t\t}\n\t}\n\n\tDUK_ASSERT(ncont <= blen);\n\tclen = blen - ncont;\n\tDUK_ASSERT(clen <= blen);\n\treturn clen;\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/*\n *  Unicode range matcher\n *\n *  Matches a codepoint against a packed bitstream of character ranges.\n *  Used for slow path Unicode matching.\n */\n\n/* Must match tools/extract_chars.py, generate_match_table3(). */\nDUK_LOCAL duk_uint32_t duk__uni_decode_value(duk_bitdecoder_ctx *bd_ctx) {\n\tduk_uint32_t t;\n\n\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 4);\n\tif (t <= 0x0eU) {\n\t\treturn t;\n\t}\n\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 8);\n\tif (t <= 0xfdU) {\n\t\treturn t + 0x0f;\n\t}\n\tif (t == 0xfeU) {\n\t\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 12);\n\t\treturn t + 0x0fU + 0xfeU;\n\t} else {\n\t\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 24);\n\t\treturn t + 0x0fU + 0xfeU + 0x1000UL;\n\t}\n}\n\nDUK_LOCAL duk_small_int_t duk__uni_range_match(const duk_uint8_t *unitab, duk_size_t unilen, duk_codepoint_t cp) {\n\tduk_bitdecoder_ctx bd_ctx;\n\tduk_codepoint_t prev_re;\n\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tbd_ctx.data = (const duk_uint8_t *) unitab;\n\tbd_ctx.length = (duk_size_t) unilen;\n\n\tprev_re = 0;\n\tfor (;;) {\n\t\tduk_codepoint_t r1, r2;\n\t\tr1 = (duk_codepoint_t) duk__uni_decode_value(&bd_ctx);\n\t\tif (r1 == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tr2 = (duk_codepoint_t) duk__uni_decode_value(&bd_ctx);\n\n\t\tr1 = prev_re + r1;\n\t\tr2 = r1 + r2;\n\t\tprev_re = r2;\n\n\t\t/* [r1,r2] is the range */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__uni_range_match: cp=%06lx range=[0x%06lx,0x%06lx]\",\n\t\t                     (unsigned long) cp, (unsigned long) r1, (unsigned long) r2));\n\t\tif (cp >= r1 && cp <= r2) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n/*\n *  \"WhiteSpace\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_whitespace(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.2 specifies six characters specifically as\n\t *  white space:\n\t *\n\t *    0009;<control>;Cc;0;S;;;;;N;CHARACTER TABULATION;;;;\n\t *    000B;<control>;Cc;0;S;;;;;N;LINE TABULATION;;;;\n\t *    000C;<control>;Cc;0;WS;;;;;N;FORM FEED (FF);;;;\n\t *    0020;SPACE;Zs;0;WS;;;;;N;;;;;\n\t *    00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;\n\t *    FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;;\n\t *\n\t *  It also specifies any Unicode category 'Zs' characters as white\n\t *  space.  These can be extracted with the \"tools/extract_chars.py\" script.\n\t *  Current result:\n\t *\n\t *    RAW OUTPUT:\n\t *    ===========\n\t *    0020;SPACE;Zs;0;WS;;;;;N;;;;;\n\t *    00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;\n\t *    1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;;\n\t *    180E;MONGOLIAN VOWEL SEPARATOR;Zs;0;WS;;;;;N;;;;;\n\t *    2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;;\n\t *    2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;;\n\t *    2002;EN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2003;EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2004;THREE-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2005;FOUR-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2006;SIX-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2007;FIGURE SPACE;Zs;0;WS;<noBreak> 0020;;;;N;;;;;\n\t *    2008;PUNCTUATION SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2009;THIN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    200A;HAIR SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    202F;NARROW NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;;;;;\n\t *    205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    3000;IDEOGRAPHIC SPACE;Zs;0;WS;<wide> 0020;;;;N;;;;;\n\t *\n\t *    RANGES:\n\t *    =======\n\t *    0x0020\n\t *    0x00a0\n\t *    0x1680\n\t *    0x180e\n\t *    0x2000 ... 0x200a\n\t *    0x202f\n\t *    0x205f\n\t *    0x3000\n\t *\n\t *  A manual decoder (below) is probably most compact for this.\n\t */\n\n\tduk_uint_fast8_t lo;\n\tduk_uint_fast32_t hi;\n\n\t/* cp == -1 (EOF) never matches and causes return value 0 */\n\n\tlo = (duk_uint_fast8_t) (cp & 0xff);\n\thi = (duk_uint_fast32_t) (cp >> 8);  /* does not fit into an uchar */\n\n\tif (hi == 0x0000UL) {\n\t\tif (lo == 0x09U || lo == 0x0bU || lo == 0x0cU ||\n\t\t    lo == 0x20U || lo == 0xa0U) {\n\t\t\treturn 1;\n\t\t}\n\t} else if (hi == 0x0020UL) {\n\t\tif (lo <= 0x0aU || lo == 0x2fU || lo == 0x5fU) {\n\t\t\treturn 1;\n\t\t}\n\t} else if (cp == 0x1680L || cp == 0x180eL || cp == 0x3000L ||\n\t           cp == 0xfeffL) {\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n/*\n *  \"LineTerminator\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_line_terminator(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.3\n\t *\n\t *  A LineTerminatorSequence essentially merges <CR> <LF> sequences\n\t *  into a single line terminator.  This must be handled by the caller.\n\t */\n\n\tif (cp == 0x000aL || cp == 0x000dL || cp == 0x2028L ||\n\t    cp == 0x2029L) {\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n/*\n *  \"IdentifierStart\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_identifier_start(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.6:\n\t *\n\t *    IdentifierStart:\n\t *      UnicodeLetter\n\t *      $\n\t *      _\n\t *      \\ UnicodeEscapeSequence\n\t *\n\t *  IdentifierStart production has one multi-character production:\n\t *\n\t *    \\ UnicodeEscapeSequence\n\t *\n\t *  The '\\' character is -not- matched by this function.  Rather, the caller\n\t *  should decode the escape and then call this function to check whether the\n\t *  decoded character is acceptable (see discussion in E5 Section 7.6).\n\t *\n\t *  The \"UnicodeLetter\" alternative of the production allows letters\n\t *  from various Unicode categories.  These can be extracted with the\n\t *  \"tools/extract_chars.py\" script.\n\t *\n\t *  Because the result has hundreds of Unicode codepoint ranges, matching\n\t *  for any values >= 0x80 are done using a very slow range-by-range scan\n\t *  and a packed range format.\n\t *\n\t *  The ASCII portion (codepoints 0x00 ... 0x7f) is fast-pathed below because\n\t *  it matters the most.  The ASCII related ranges of IdentifierStart are:\n\t *\n\t *    0x0041 ... 0x005a     ['A' ... 'Z']\n\t *    0x0061 ... 0x007a     ['a' ... 'z']\n\t *    0x0024                ['$']\n\t *    0x005f                ['_']\n\t */\n\n\t/* ASCII (and EOF) fast path -- quick accept and reject */\n\tif (cp <= 0x7fL) {\n#if defined(DUK_USE_IDCHAR_FASTPATH)\n\t\treturn (cp >= 0) && (duk_is_idchar_tab[cp] > 0);\n#else\n\t\tif ((cp >= 'a' && cp <= 'z') ||\n\t\t    (cp >= 'A' && cp <= 'Z') ||\n\t\t    cp == '_' || cp == '$') {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n#endif\n\t}\n\n\t/* Non-ASCII slow path (range-by-range linear comparison), very slow */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n\tif (duk__uni_range_match(duk_unicode_ids_noa,\n\t                         (duk_size_t) sizeof(duk_unicode_ids_noa),\n\t                         (duk_codepoint_t) cp)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else\n\tif (cp < 0x10000L) {\n\t\tif (duk__uni_range_match(duk_unicode_ids_noabmp,\n\t\t                         sizeof(duk_unicode_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp)) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t} else {\n\t\t/* without explicit non-BMP support, assume non-BMP characters\n\t\t * are always accepted as identifier characters.\n\t\t */\n\t\treturn 1;\n\t}\n#endif\n}\n\n/*\n *  \"IdentifierPart\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_identifier_part(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.6:\n\t *\n\t *    IdentifierPart:\n\t *      IdentifierStart\n\t *      UnicodeCombiningMark\n\t *      UnicodeDigit\n\t *      UnicodeConnectorPunctuation\n\t *      <ZWNJ>  [U+200C]\n\t *      <ZWJ>   [U+200D]\n\t *\n\t *  IdentifierPart production has one multi-character production\n\t *  as part of its IdentifierStart alternative.  The '\\' character\n\t *  of an escape sequence is not matched here, see discussion in\n\t *  duk_unicode_is_identifier_start().\n\t *\n\t *  To match non-ASCII characters (codepoints >= 0x80), a very slow\n\t *  linear range-by-range scan is used.  The codepoint is first compared\n\t *  to the IdentifierStart ranges, and if it doesn't match, then to a\n\t *  set consisting of code points in IdentifierPart but not in\n\t *  IdentifierStart.  This is done to keep the unicode range data small,\n\t *  at the expense of speed.\n\t *\n\t *  The ASCII fast path consists of:\n\t *\n\t *    0x0030 ... 0x0039     ['0' ... '9', UnicodeDigit]\n\t *    0x0041 ... 0x005a     ['A' ... 'Z', IdentifierStart]\n\t *    0x0061 ... 0x007a     ['a' ... 'z', IdentifierStart]\n\t *    0x0024                ['$', IdentifierStart]\n\t *    0x005f                ['_', IdentifierStart and\n\t *                                UnicodeConnectorPunctuation]\n\t *\n\t *  UnicodeCombiningMark has no code points <= 0x7f.\n\t *\n\t *  The matching code reuses the \"identifier start\" tables, and then\n\t *  consults a separate range set for characters in \"identifier part\"\n\t *  but not in \"identifier start\".  These can be extracted with the\n\t *  \"tools/extract_chars.py\" script.\n\t *\n\t *  UnicodeCombiningMark -> categories Mn, Mc\n\t *  UnicodeDigit -> categories Nd\n\t *  UnicodeConnectorPunctuation -> categories Pc\n\t */\n\n\t/* ASCII (and EOF) fast path -- quick accept and reject */\n\tif (cp <= 0x7fL) {\n#if defined(DUK_USE_IDCHAR_FASTPATH)\n\t\treturn (cp >= 0) && (duk_is_idchar_tab[cp] != 0);\n#else\n\t\tif ((cp >= 'a' && cp <= 'z') ||\n\t\t    (cp >= 'A' && cp <= 'Z') ||\n\t\t    (cp >= '0' && cp <= '9') ||\n\t\t    cp == '_' || cp == '$') {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n#endif\n\t}\n\n\t/* Non-ASCII slow path (range-by-range linear comparison), very slow */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n\tif (duk__uni_range_match(duk_unicode_ids_noa,\n\t                         sizeof(duk_unicode_ids_noa),\n\t                         (duk_codepoint_t) cp) ||\n\t    duk__uni_range_match(duk_unicode_idp_m_ids_noa,\n\t                         sizeof(duk_unicode_idp_m_ids_noa),\n\t                         (duk_codepoint_t) cp)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else\n\tif (cp < 0x10000L) {\n\t\tif (duk__uni_range_match(duk_unicode_ids_noabmp,\n\t\t                         sizeof(duk_unicode_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp) ||\n\t\t    duk__uni_range_match(duk_unicode_idp_m_ids_noabmp,\n\t\t                         sizeof(duk_unicode_idp_m_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp)) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t} else {\n\t\t/* without explicit non-BMP support, assume non-BMP characters\n\t\t * are always accepted as identifier characters.\n\t\t */\n\t\treturn 1;\n\t}\n#endif\n}\n\n/*\n *  Unicode letter check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_letter(duk_codepoint_t cp) {\n\t/*\n\t *  Unicode letter is now taken to be the categories:\n\t *\n\t *    Lu, Ll, Lt, Lm, Lo\n\t *\n\t *  (Not sure if this is exactly correct.)\n\t *\n\t *  The ASCII fast path consists of:\n\t *\n\t *    0x0041 ... 0x005a     ['A' ... 'Z']\n\t *    0x0061 ... 0x007a     ['a' ... 'z']\n\t */\n\n\t/* ASCII (and EOF) fast path -- quick accept and reject */\n\tif (cp <= 0x7fL) {\n\t\tif ((cp >= 'a' && cp <= 'z') ||\n\t\t    (cp >= 'A' && cp <= 'Z')) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t}\n\n\t/* Non-ASCII slow path (range-by-range linear comparison), very slow */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n\tif (duk__uni_range_match(duk_unicode_ids_noa,\n\t                         sizeof(duk_unicode_ids_noa),\n\t                         (duk_codepoint_t) cp) &&\n\t    !duk__uni_range_match(duk_unicode_ids_m_let_noa,\n\t                          sizeof(duk_unicode_ids_m_let_noa),\n\t                          (duk_codepoint_t) cp)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else\n\tif (cp < 0x10000L) {\n\t\tif (duk__uni_range_match(duk_unicode_ids_noabmp,\n\t\t                         sizeof(duk_unicode_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp) &&\n\t\t    !duk__uni_range_match(duk_unicode_ids_m_let_noabmp,\n\t\t                          sizeof(duk_unicode_ids_m_let_noabmp),\n\t\t                          (duk_codepoint_t) cp)) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t} else {\n\t\t/* without explicit non-BMP support, assume non-BMP characters\n\t\t * are always accepted as letters.\n\t\t */\n\t\treturn 1;\n\t}\n#endif\n}\n\n/*\n *  Complex case conversion helper which decodes a bit-packed conversion\n *  control stream generated by tools/extract_caseconv.py.  The conversion\n *  is very slow because it runs through the conversion data in a linear\n *  fashion to save space (which is why ASCII characters have a special\n *  fast path before arriving here).\n *\n *  The particular bit counts etc have been determined experimentally to\n *  be small but still sufficient, and must match the Python script\n *  (tools/extract_caseconv.py).\n *\n *  The return value is the case converted codepoint or -1 if the conversion\n *  results in multiple characters (this is useful for regexp Canonicalization\n *  operation).  If 'buf' is not NULL, the result codepoint(s) are also\n *  appended to the hbuffer.\n *\n *  Context and locale specific rules must be checked before consulting\n *  this function.\n */\n\nDUK_LOCAL\nduk_codepoint_t duk__slow_case_conversion(duk_hthread *thr,\n                                          duk_bufwriter_ctx *bw,\n                                          duk_codepoint_t cp,\n                                          duk_bitdecoder_ctx *bd_ctx) {\n\tduk_small_int_t skip = 0;\n\tduk_small_int_t n;\n\tduk_small_int_t t;\n\tduk_small_int_t count;\n\tduk_codepoint_t tmp_cp;\n\tduk_codepoint_t start_i;\n\tduk_codepoint_t start_o;\n\n\tDUK_ASSERT(bd_ctx != NULL);\n\tDUK_UNREF(thr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"slow case conversion for codepoint: %ld\", (long) cp));\n\n\t/* range conversion with a \"skip\" */\n\tDUK_DDD(DUK_DDDPRINT(\"checking ranges\"));\n\tfor (;;) {\n\t\tskip++;\n\t\tn = (duk_small_int_t) duk_bd_decode(bd_ctx, 6);\n\t\tif (n == 0x3f) {\n\t\t\t/* end marker */\n\t\t\tbreak;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"skip=%ld, n=%ld\", (long) skip, (long) n));\n\n\t\twhile (n--) {\n\t\t\tstart_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\t\tstart_o = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\t\tcount = (duk_small_int_t) duk_bd_decode(bd_ctx, 7);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"range: start_i=%ld, start_o=%ld, count=%ld, skip=%ld\",\n\t\t\t                     (long) start_i, (long) start_o, (long) count, (long) skip));\n\n\t\t\tif (cp >= start_i) {\n\t\t\t\ttmp_cp = cp - start_i;  /* always >= 0 */\n\t\t\t\tif (tmp_cp < (duk_codepoint_t) count * (duk_codepoint_t) skip &&\n\t\t\t\t    (tmp_cp % (duk_codepoint_t) skip) == 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"range matches input codepoint\"));\n\t\t\t\t\tcp = start_o + tmp_cp;\n\t\t\t\t\tgoto single;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/* 1:1 conversion */\n\tn = (duk_small_int_t) duk_bd_decode(bd_ctx, 7);\n\tDUK_DDD(DUK_DDDPRINT(\"checking 1:1 conversions (count %ld)\", (long) n));\n\twhile (n--) {\n\t\tstart_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\tstart_o = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\tDUK_DDD(DUK_DDDPRINT(\"1:1 conversion %ld -> %ld\", (long) start_i, (long) start_o));\n\t\tif (cp == start_i) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"1:1 matches input codepoint\"));\n\t\t\tcp = start_o;\n\t\t\tgoto single;\n\t\t}\n\t}\n\n\t/* complex, multicharacter conversion */\n\tn = (duk_small_int_t) duk_bd_decode(bd_ctx, 7);\n\tDUK_DDD(DUK_DDDPRINT(\"checking 1:n conversions (count %ld)\", (long) n));\n\twhile (n--) {\n\t\tstart_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\tt = (duk_small_int_t) duk_bd_decode(bd_ctx, 2);\n\t\tDUK_DDD(DUK_DDDPRINT(\"1:n conversion %ld -> %ld chars\", (long) start_i, (long) t));\n\t\tif (cp == start_i) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"1:n matches input codepoint\"));\n\t\t\tif (bw != NULL) {\n\t\t\t\twhile (t--) {\n\t\t\t\t\ttmp_cp = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\t\t\t\tDUK_BW_WRITE_RAW_XUTF8(thr, bw, (duk_ucodepoint_t) tmp_cp);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t} else {\n\t\t\twhile (t--) {\n\t\t\t\t(void) duk_bd_decode(bd_ctx, 16);\n\t\t\t}\n\t\t}\n\t}\n\n\t/* default: no change */\n\tDUK_DDD(DUK_DDDPRINT(\"no rule matches, output is same as input\"));\n\t/* fall through */\n\n single:\n\tif (bw != NULL) {\n\t\tDUK_BW_WRITE_RAW_XUTF8(thr, bw, (duk_ucodepoint_t) cp);\n\t}\n\treturn cp;\n}\n\n/*\n *  Case conversion helper, with context/local sensitivity.\n *  For proper case conversion, one needs to know the character\n *  and the preceding and following characters, as well as\n *  locale/language.\n */\n\n/* XXX: add 'language' argument when locale/language sensitive rule\n * support added.\n */\nDUK_LOCAL\nduk_codepoint_t duk__case_transform_helper(duk_hthread *thr,\n                                           duk_bufwriter_ctx *bw,\n                                           duk_codepoint_t cp,\n                                           duk_codepoint_t prev,\n                                           duk_codepoint_t next,\n                                           duk_bool_t uppercase) {\n\tduk_bitdecoder_ctx bd_ctx;\n\n\t/* fast path for ASCII */\n\tif (cp < 0x80L) {\n\t\t/* XXX: there are language sensitive rules for the ASCII range.\n\t\t * If/when language/locale support is implemented, they need to\n\t\t * be implemented here for the fast path.  There are no context\n\t\t * sensitive rules for ASCII range.\n\t\t */\n\n\t\tif (uppercase) {\n\t\t\tif (cp >= 'a' && cp <= 'z') {\n\t\t\t\tcp = cp - 'a' + 'A';\n\t\t\t}\n\t\t} else {\n\t\t\tif (cp >= 'A' && cp <= 'Z') {\n\t\t\t\tcp = cp - 'A' + 'a';\n\t\t\t}\n\t\t}\n\n\t\tif (bw != NULL) {\n\t\t\tDUK_BW_WRITE_RAW_U8(thr, bw, (duk_uint8_t) cp);\n\t\t}\n\t\treturn cp;\n\t}\n\n\t/* context and locale specific rules which cannot currently be represented\n\t * in the caseconv bitstream: hardcoded rules in C\n\t */\n\tif (uppercase) {\n\t\t/* XXX: turkish / azeri */\n\t} else {\n\t\t/*\n\t\t *  Final sigma context specific rule.  This is a rather tricky\n\t\t *  rule and this handling is probably not 100% correct now.\n\t\t *  The rule is not locale/language specific so it is supported.\n\t\t */\n\n\t\tif (cp == 0x03a3L &&    /* U+03A3 = GREEK CAPITAL LETTER SIGMA */\n\t\t    duk_unicode_is_letter(prev) &&        /* prev exists and is not a letter */\n\t\t    !duk_unicode_is_letter(next)) {       /* next does not exist or next is not a letter */\n\t\t\t/* Capital sigma occurred at \"end of word\", lowercase to\n\t\t\t * U+03C2 = GREEK SMALL LETTER FINAL SIGMA.  Otherwise\n\t\t\t * fall through and let the normal rules lowercase it to\n\t\t\t * U+03C3 = GREEK SMALL LETTER SIGMA.\n\t\t\t */\n\t\t\tcp = 0x03c2L;\n\t\t\tgoto singlechar;\n\t\t}\n\n\t\t/* XXX: lithuanian not implemented */\n\t\t/* XXX: lithuanian, explicit dot rules */\n\t\t/* XXX: turkish / azeri, lowercase rules */\n\t}\n\n\t/* 1:1 or special conversions, but not locale/context specific: script generated rules */\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tif (uppercase) {\n\t\tbd_ctx.data = (const duk_uint8_t *) duk_unicode_caseconv_uc;\n\t\tbd_ctx.length = (duk_size_t) sizeof(duk_unicode_caseconv_uc);\n\t} else {\n\t\tbd_ctx.data = (const duk_uint8_t *) duk_unicode_caseconv_lc;\n\t\tbd_ctx.length = (duk_size_t) sizeof(duk_unicode_caseconv_lc);\n\t}\n\treturn duk__slow_case_conversion(thr, bw, cp, &bd_ctx);\n\n singlechar:\n\tif (bw != NULL) {\n\t\tDUK_BW_WRITE_RAW_XUTF8(thr, bw, (duk_ucodepoint_t) cp);\n\t}\n\treturn cp;\n\n /* unused now, not needed until Turkish/Azeri */\n#if 0\n nochar:\n\treturn -1;\n#endif\n}\n\n/*\n *  Replace valstack top with case converted version.\n */\n\nDUK_INTERNAL void duk_unicode_case_convert_string(duk_hthread *thr, duk_bool_t uppercase) {\n\tduk_hstring *h_input;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_codepoint_t prev, curr, next;\n\n\th_input = duk_require_hstring(thr, -1);  /* Accept symbols. */\n\tDUK_ASSERT(h_input != NULL);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input));\n\n\t/* [ ... input buffer ] */\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\n\tprev = -1; DUK_UNREF(prev);\n\tcurr = -1;\n\tnext = -1;\n\tfor (;;) {\n\t\tprev = curr;\n\t\tcurr = next;\n\t\tnext = -1;\n\t\tif (p < p_end) {\n\t\t\tnext = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end);\n\t\t} else {\n\t\t\t/* end of input and last char has been processed */\n\t\t\tif (curr < 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* on first round, skip */\n\t\tif (curr >= 0) {\n\t\t\t/* XXX: could add a fast path to process chunks of input codepoints,\n\t\t\t * but relative benefit would be quite small.\n\t\t\t */\n\n\t\t\t/* Ensure space for maximum multi-character result; estimate is overkill. */\n\t\t\tDUK_BW_ENSURE(thr, bw, 8 * DUK_UNICODE_MAX_XUTF8_LENGTH);\n\n\t\t\tduk__case_transform_helper(thr,\n\t\t\t                           bw,\n\t\t\t                           (duk_codepoint_t) curr,\n\t\t\t                           prev,\n\t\t\t                           next,\n\t\t\t                           uppercase);\n\t\t}\n\t}\n\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe, output is encoded. */\n\t/* invalidates h_buf pointer */\n\tduk_remove_m2(thr);\n}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Canonicalize() abstract operation needed for canonicalization of individual\n *  codepoints during regexp compilation and execution, see E5 Section 15.10.2.8.\n *  Note that codepoints are canonicalized one character at a time, so no context\n *  specific rules can apply.  Locale specific rules can apply, though.\n */\n\nDUK_INTERNAL duk_codepoint_t duk_unicode_re_canonicalize_char(duk_hthread *thr, duk_codepoint_t cp) {\n#if defined(DUK_USE_REGEXP_CANON_WORKAROUND)\n\t/* Fast canonicalization lookup at the cost of 128kB footprint. */\n\tDUK_ASSERT(cp >= 0);\n\tDUK_UNREF(thr);\n\tif (DUK_LIKELY(cp < 0x10000L)) {\n\t\treturn (duk_codepoint_t) duk_unicode_re_canon_lookup[cp];\n\t}\n\treturn cp;\n#else  /* DUK_USE_REGEXP_CANON_WORKAROUND */\n\tduk_codepoint_t y;\n\n\ty = duk__case_transform_helper(thr,\n\t                               NULL,    /* NULL is allowed, no output */\n\t                               cp,      /* curr char */\n\t                               -1,      /* prev char */\n\t                               -1,      /* next char */\n\t                               1);      /* uppercase */\n\n\tif ((y < 0) || (cp >= 0x80 && y < 0x80)) {\n\t\t/* multiple codepoint conversion or non-ASCII mapped to ASCII\n\t\t * --> leave as is.\n\t\t */\n\t\treturn cp;\n\t}\n\n\treturn y;\n#endif  /* DUK_USE_REGEXP_CANON_WORKAROUND */\n}\n\n/*\n *  E5 Section 15.10.2.6 \"IsWordChar\" abstract operation.  Assume\n *  x < 0 for characters read outside the string.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_re_is_wordchar(duk_codepoint_t x) {\n\t/*\n\t *  Note: the description in E5 Section 15.10.2.6 has a typo, it\n\t *  contains 'A' twice and lacks 'a'; the intent is [0-9a-zA-Z_].\n\t */\n\tif ((x >= '0' && x <= '9') ||\n\t    (x >= 'a' && x <= 'z') ||\n\t    (x >= 'A' && x <= 'Z') ||\n\t    (x == '_')) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\n/*\n *  Regexp range tables\n */\n\n/* exposed because lexer needs these too */\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_digit[2] = {\n\t(duk_uint16_t) 0x0030UL, (duk_uint16_t) 0x0039UL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_white[22] = {\n\t(duk_uint16_t) 0x0009UL, (duk_uint16_t) 0x000DUL,\n\t(duk_uint16_t) 0x0020UL, (duk_uint16_t) 0x0020UL,\n\t(duk_uint16_t) 0x00A0UL, (duk_uint16_t) 0x00A0UL,\n\t(duk_uint16_t) 0x1680UL, (duk_uint16_t) 0x1680UL,\n\t(duk_uint16_t) 0x180EUL, (duk_uint16_t) 0x180EUL,\n\t(duk_uint16_t) 0x2000UL, (duk_uint16_t) 0x200AUL,\n\t(duk_uint16_t) 0x2028UL, (duk_uint16_t) 0x2029UL,\n\t(duk_uint16_t) 0x202FUL, (duk_uint16_t) 0x202FUL,\n\t(duk_uint16_t) 0x205FUL, (duk_uint16_t) 0x205FUL,\n\t(duk_uint16_t) 0x3000UL, (duk_uint16_t) 0x3000UL,\n\t(duk_uint16_t) 0xFEFFUL, (duk_uint16_t) 0xFEFFUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_wordchar[8] = {\n\t(duk_uint16_t) 0x0030UL, (duk_uint16_t) 0x0039UL,\n\t(duk_uint16_t) 0x0041UL, (duk_uint16_t) 0x005AUL,\n\t(duk_uint16_t) 0x005FUL, (duk_uint16_t) 0x005FUL,\n\t(duk_uint16_t) 0x0061UL, (duk_uint16_t) 0x007AUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_digit[4] = {\n\t(duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x002FUL,\n\t(duk_uint16_t) 0x003AUL, (duk_uint16_t) 0xFFFFUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_white[24] = {\n\t(duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x0008UL,\n\t(duk_uint16_t) 0x000EUL, (duk_uint16_t) 0x001FUL,\n\t(duk_uint16_t) 0x0021UL, (duk_uint16_t) 0x009FUL,\n\t(duk_uint16_t) 0x00A1UL, (duk_uint16_t) 0x167FUL,\n\t(duk_uint16_t) 0x1681UL, (duk_uint16_t) 0x180DUL,\n\t(duk_uint16_t) 0x180FUL, (duk_uint16_t) 0x1FFFUL,\n\t(duk_uint16_t) 0x200BUL, (duk_uint16_t) 0x2027UL,\n\t(duk_uint16_t) 0x202AUL, (duk_uint16_t) 0x202EUL,\n\t(duk_uint16_t) 0x2030UL, (duk_uint16_t) 0x205EUL,\n\t(duk_uint16_t) 0x2060UL, (duk_uint16_t) 0x2FFFUL,\n\t(duk_uint16_t) 0x3001UL, (duk_uint16_t) 0xFEFEUL,\n\t(duk_uint16_t) 0xFF00UL, (duk_uint16_t) 0xFFFFUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_wordchar[10] = {\n\t(duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x002FUL,\n\t(duk_uint16_t) 0x003AUL, (duk_uint16_t) 0x0040UL,\n\t(duk_uint16_t) 0x005BUL, (duk_uint16_t) 0x005EUL,\n\t(duk_uint16_t) 0x0060UL, (duk_uint16_t) 0x0060UL,\n\t(duk_uint16_t) 0x007BUL, (duk_uint16_t) 0xFFFFUL,\n};\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n#line 1 \"duk_util_misc.c\"\n/*\n *  Misc util stuff.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Lowercase digits for radix values 2 to 36.  Also doubles as lowercase\n *  hex nybble table.\n */\n\nDUK_INTERNAL const duk_uint8_t duk_lc_digits[36] = {\n\tDUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3,\n\tDUK_ASC_4, DUK_ASC_5, DUK_ASC_6, DUK_ASC_7,\n\tDUK_ASC_8, DUK_ASC_9, DUK_ASC_LC_A, DUK_ASC_LC_B,\n\tDUK_ASC_LC_C, DUK_ASC_LC_D, DUK_ASC_LC_E, DUK_ASC_LC_F,\n\tDUK_ASC_LC_G, DUK_ASC_LC_H, DUK_ASC_LC_I, DUK_ASC_LC_J,\n\tDUK_ASC_LC_K, DUK_ASC_LC_L, DUK_ASC_LC_M, DUK_ASC_LC_N,\n\tDUK_ASC_LC_O, DUK_ASC_LC_P, DUK_ASC_LC_Q, DUK_ASC_LC_R,\n\tDUK_ASC_LC_S, DUK_ASC_LC_T, DUK_ASC_LC_U, DUK_ASC_LC_V,\n\tDUK_ASC_LC_W, DUK_ASC_LC_X, DUK_ASC_LC_Y, DUK_ASC_LC_Z\n};\n\nDUK_INTERNAL const duk_uint8_t duk_uc_nybbles[16] = {\n\tDUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3,\n\tDUK_ASC_4, DUK_ASC_5, DUK_ASC_6, DUK_ASC_7,\n\tDUK_ASC_8, DUK_ASC_9, DUK_ASC_UC_A, DUK_ASC_UC_B,\n\tDUK_ASC_UC_C, DUK_ASC_UC_D, DUK_ASC_UC_E, DUK_ASC_UC_F\n};\n\n/*\n *  Table for hex decoding ASCII hex digits\n */\n\nDUK_INTERNAL const duk_int8_t duk_hex_dectab[256] = {\n\t/* -1 if invalid */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x00-0x0f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x10-0x1f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x20-0x2f */\n\t 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,  /* 0x30-0x3f */\n\t-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x40-0x4f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x50-0x5f */\n\t-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x60-0x6f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x70-0x7f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x80-0x8f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x90-0x9f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xa0-0xaf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xb0-0xbf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xc0-0xcf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xd0-0xdf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xe0-0xef */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1   /* 0xf0-0xff */\n};\n\n#if defined(DUK_USE_HEX_FASTPATH)\n/* Preshifted << 4.  Must use 16-bit entry to allow negative value signaling. */\nDUK_INTERNAL const duk_int16_t duk_hex_dectab_shift4[256] = {\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x00-0x0f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x10-0x1f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x20-0x2f */\n\t0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x30-0x3f */\n\t  -1, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x40-0x4f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x50-0x5f */\n\t  -1, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x60-0x6f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x70-0x7f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x80-0x8f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x90-0x9f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xa0-0xaf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xb0-0xbf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xc0-0xcf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xd0-0xdf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xe0-0xef */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1   /* 0xf0-0xff */\n};\n#endif\n\n/*\n *  Table for hex encoding bytes\n */\n\n#if defined(DUK_USE_HEX_FASTPATH)\n/* Lookup to encode one byte directly into 2 characters:\n *\n *   def genhextab(bswap):\n *       for i in xrange(256):\n *           t = chr(i).encode('hex')\n *           if bswap:\n *               t = t[1] + t[0]\n *           print('0x' + t.encode('hex') + 'U')\n *   print('big endian'); genhextab(False)\n *   print('little endian'); genhextab(True)\n*/\nDUK_INTERNAL const duk_uint16_t duk_hex_enctab[256] = {\n#if defined(DUK_USE_INTEGER_BE)\n\t0x3030U, 0x3031U, 0x3032U, 0x3033U, 0x3034U, 0x3035U, 0x3036U, 0x3037U,\n\t0x3038U, 0x3039U, 0x3061U, 0x3062U, 0x3063U, 0x3064U, 0x3065U, 0x3066U,\n\t0x3130U, 0x3131U, 0x3132U, 0x3133U, 0x3134U, 0x3135U, 0x3136U, 0x3137U,\n\t0x3138U, 0x3139U, 0x3161U, 0x3162U, 0x3163U, 0x3164U, 0x3165U, 0x3166U,\n\t0x3230U, 0x3231U, 0x3232U, 0x3233U, 0x3234U, 0x3235U, 0x3236U, 0x3237U,\n\t0x3238U, 0x3239U, 0x3261U, 0x3262U, 0x3263U, 0x3264U, 0x3265U, 0x3266U,\n\t0x3330U, 0x3331U, 0x3332U, 0x3333U, 0x3334U, 0x3335U, 0x3336U, 0x3337U,\n\t0x3338U, 0x3339U, 0x3361U, 0x3362U, 0x3363U, 0x3364U, 0x3365U, 0x3366U,\n\t0x3430U, 0x3431U, 0x3432U, 0x3433U, 0x3434U, 0x3435U, 0x3436U, 0x3437U,\n\t0x3438U, 0x3439U, 0x3461U, 0x3462U, 0x3463U, 0x3464U, 0x3465U, 0x3466U,\n\t0x3530U, 0x3531U, 0x3532U, 0x3533U, 0x3534U, 0x3535U, 0x3536U, 0x3537U,\n\t0x3538U, 0x3539U, 0x3561U, 0x3562U, 0x3563U, 0x3564U, 0x3565U, 0x3566U,\n\t0x3630U, 0x3631U, 0x3632U, 0x3633U, 0x3634U, 0x3635U, 0x3636U, 0x3637U,\n\t0x3638U, 0x3639U, 0x3661U, 0x3662U, 0x3663U, 0x3664U, 0x3665U, 0x3666U,\n\t0x3730U, 0x3731U, 0x3732U, 0x3733U, 0x3734U, 0x3735U, 0x3736U, 0x3737U,\n\t0x3738U, 0x3739U, 0x3761U, 0x3762U, 0x3763U, 0x3764U, 0x3765U, 0x3766U,\n\t0x3830U, 0x3831U, 0x3832U, 0x3833U, 0x3834U, 0x3835U, 0x3836U, 0x3837U,\n\t0x3838U, 0x3839U, 0x3861U, 0x3862U, 0x3863U, 0x3864U, 0x3865U, 0x3866U,\n\t0x3930U, 0x3931U, 0x3932U, 0x3933U, 0x3934U, 0x3935U, 0x3936U, 0x3937U,\n\t0x3938U, 0x3939U, 0x3961U, 0x3962U, 0x3963U, 0x3964U, 0x3965U, 0x3966U,\n\t0x6130U, 0x6131U, 0x6132U, 0x6133U, 0x6134U, 0x6135U, 0x6136U, 0x6137U,\n\t0x6138U, 0x6139U, 0x6161U, 0x6162U, 0x6163U, 0x6164U, 0x6165U, 0x6166U,\n\t0x6230U, 0x6231U, 0x6232U, 0x6233U, 0x6234U, 0x6235U, 0x6236U, 0x6237U,\n\t0x6238U, 0x6239U, 0x6261U, 0x6262U, 0x6263U, 0x6264U, 0x6265U, 0x6266U,\n\t0x6330U, 0x6331U, 0x6332U, 0x6333U, 0x6334U, 0x6335U, 0x6336U, 0x6337U,\n\t0x6338U, 0x6339U, 0x6361U, 0x6362U, 0x6363U, 0x6364U, 0x6365U, 0x6366U,\n\t0x6430U, 0x6431U, 0x6432U, 0x6433U, 0x6434U, 0x6435U, 0x6436U, 0x6437U,\n\t0x6438U, 0x6439U, 0x6461U, 0x6462U, 0x6463U, 0x6464U, 0x6465U, 0x6466U,\n\t0x6530U, 0x6531U, 0x6532U, 0x6533U, 0x6534U, 0x6535U, 0x6536U, 0x6537U,\n\t0x6538U, 0x6539U, 0x6561U, 0x6562U, 0x6563U, 0x6564U, 0x6565U, 0x6566U,\n\t0x6630U, 0x6631U, 0x6632U, 0x6633U, 0x6634U, 0x6635U, 0x6636U, 0x6637U,\n\t0x6638U, 0x6639U, 0x6661U, 0x6662U, 0x6663U, 0x6664U, 0x6665U, 0x6666U\n#else  /* DUK_USE_INTEGER_BE */\n\t0x3030U, 0x3130U, 0x3230U, 0x3330U, 0x3430U, 0x3530U, 0x3630U, 0x3730U,\n\t0x3830U, 0x3930U, 0x6130U, 0x6230U, 0x6330U, 0x6430U, 0x6530U, 0x6630U,\n\t0x3031U, 0x3131U, 0x3231U, 0x3331U, 0x3431U, 0x3531U, 0x3631U, 0x3731U,\n\t0x3831U, 0x3931U, 0x6131U, 0x6231U, 0x6331U, 0x6431U, 0x6531U, 0x6631U,\n\t0x3032U, 0x3132U, 0x3232U, 0x3332U, 0x3432U, 0x3532U, 0x3632U, 0x3732U,\n\t0x3832U, 0x3932U, 0x6132U, 0x6232U, 0x6332U, 0x6432U, 0x6532U, 0x6632U,\n\t0x3033U, 0x3133U, 0x3233U, 0x3333U, 0x3433U, 0x3533U, 0x3633U, 0x3733U,\n\t0x3833U, 0x3933U, 0x6133U, 0x6233U, 0x6333U, 0x6433U, 0x6533U, 0x6633U,\n\t0x3034U, 0x3134U, 0x3234U, 0x3334U, 0x3434U, 0x3534U, 0x3634U, 0x3734U,\n\t0x3834U, 0x3934U, 0x6134U, 0x6234U, 0x6334U, 0x6434U, 0x6534U, 0x6634U,\n\t0x3035U, 0x3135U, 0x3235U, 0x3335U, 0x3435U, 0x3535U, 0x3635U, 0x3735U,\n\t0x3835U, 0x3935U, 0x6135U, 0x6235U, 0x6335U, 0x6435U, 0x6535U, 0x6635U,\n\t0x3036U, 0x3136U, 0x3236U, 0x3336U, 0x3436U, 0x3536U, 0x3636U, 0x3736U,\n\t0x3836U, 0x3936U, 0x6136U, 0x6236U, 0x6336U, 0x6436U, 0x6536U, 0x6636U,\n\t0x3037U, 0x3137U, 0x3237U, 0x3337U, 0x3437U, 0x3537U, 0x3637U, 0x3737U,\n\t0x3837U, 0x3937U, 0x6137U, 0x6237U, 0x6337U, 0x6437U, 0x6537U, 0x6637U,\n\t0x3038U, 0x3138U, 0x3238U, 0x3338U, 0x3438U, 0x3538U, 0x3638U, 0x3738U,\n\t0x3838U, 0x3938U, 0x6138U, 0x6238U, 0x6338U, 0x6438U, 0x6538U, 0x6638U,\n\t0x3039U, 0x3139U, 0x3239U, 0x3339U, 0x3439U, 0x3539U, 0x3639U, 0x3739U,\n\t0x3839U, 0x3939U, 0x6139U, 0x6239U, 0x6339U, 0x6439U, 0x6539U, 0x6639U,\n\t0x3061U, 0x3161U, 0x3261U, 0x3361U, 0x3461U, 0x3561U, 0x3661U, 0x3761U,\n\t0x3861U, 0x3961U, 0x6161U, 0x6261U, 0x6361U, 0x6461U, 0x6561U, 0x6661U,\n\t0x3062U, 0x3162U, 0x3262U, 0x3362U, 0x3462U, 0x3562U, 0x3662U, 0x3762U,\n\t0x3862U, 0x3962U, 0x6162U, 0x6262U, 0x6362U, 0x6462U, 0x6562U, 0x6662U,\n\t0x3063U, 0x3163U, 0x3263U, 0x3363U, 0x3463U, 0x3563U, 0x3663U, 0x3763U,\n\t0x3863U, 0x3963U, 0x6163U, 0x6263U, 0x6363U, 0x6463U, 0x6563U, 0x6663U,\n\t0x3064U, 0x3164U, 0x3264U, 0x3364U, 0x3464U, 0x3564U, 0x3664U, 0x3764U,\n\t0x3864U, 0x3964U, 0x6164U, 0x6264U, 0x6364U, 0x6464U, 0x6564U, 0x6664U,\n\t0x3065U, 0x3165U, 0x3265U, 0x3365U, 0x3465U, 0x3565U, 0x3665U, 0x3765U,\n\t0x3865U, 0x3965U, 0x6165U, 0x6265U, 0x6365U, 0x6465U, 0x6565U, 0x6665U,\n\t0x3066U, 0x3166U, 0x3266U, 0x3366U, 0x3466U, 0x3566U, 0x3666U, 0x3766U,\n\t0x3866U, 0x3966U, 0x6166U, 0x6266U, 0x6366U, 0x6466U, 0x6566U, 0x6666U\n#endif  /* DUK_USE_INTEGER_BE */\n};\n#endif  /* DUK_USE_HEX_FASTPATH */\n\n/*\n *  Arbitrary byteswap for potentially unaligned values\n *\n *  Used to byteswap pointers e.g. in debugger code.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* For now only needed by the debugger. */\nDUK_INTERNAL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len) {\n\tduk_uint8_t tmp;\n\tduk_uint8_t *q = p + len - 1;\n\n\twhile (p - q < 0) {\n\t\ttmp = *p;\n\t\t*p = *q;\n\t\t*q = tmp;\n\t\tp++;\n\t\tq--;\n\t}\n}\n#endif\n#line 1 \"duk_hobject_class.c\"\n/*\n *  Hobject ECMAScript [[Class]].\n */\n\n/* #include duk_internal.h -> already included */\n\n#if (DUK_STRIDX_UC_ARGUMENTS > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_BOOLEAN > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_DATE > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_ERROR > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_FUNCTION > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_JSON > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_MATH > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_NUMBER > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_OBJECT > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_REG_EXP > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_STRING > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_GLOBAL > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_OBJ_ENV > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_DEC_ENV > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_POINTER > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_THREAD > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_ARRAY_BUFFER > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_DATA_VIEW > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_INT8_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT8_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT8_CLAMPED_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_INT16_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT16_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_INT32_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT32_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_FLOAT32_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_FLOAT64_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_EMPTY_STRING > 255)\n#error constant too large\n#endif\n\n/* Note: assumes that these string indexes are 8-bit, genstrings.py must ensure that */\nDUK_INTERNAL duk_uint8_t duk_class_number_to_stridx[32] = {\n\tDUK_STRIDX_EMPTY_STRING,  /* NONE, intentionally empty */\n\tDUK_STRIDX_UC_OBJECT,\n\tDUK_STRIDX_ARRAY,\n\tDUK_STRIDX_UC_FUNCTION,\n\tDUK_STRIDX_UC_ARGUMENTS,\n\tDUK_STRIDX_UC_BOOLEAN,\n\tDUK_STRIDX_DATE,\n\tDUK_STRIDX_UC_ERROR,\n\tDUK_STRIDX_JSON,\n\tDUK_STRIDX_MATH,\n\tDUK_STRIDX_UC_NUMBER,\n\tDUK_STRIDX_REG_EXP,\n\tDUK_STRIDX_UC_STRING,\n\tDUK_STRIDX_GLOBAL,\n\tDUK_STRIDX_UC_SYMBOL,\n\tDUK_STRIDX_OBJ_ENV,\n\tDUK_STRIDX_DEC_ENV,\n\tDUK_STRIDX_UC_POINTER,\n\tDUK_STRIDX_UC_THREAD,\n\tDUK_STRIDX_ARRAY_BUFFER,\n\tDUK_STRIDX_DATA_VIEW,\n\tDUK_STRIDX_INT8_ARRAY,\n\tDUK_STRIDX_UINT8_ARRAY,\n\tDUK_STRIDX_UINT8_CLAMPED_ARRAY,\n\tDUK_STRIDX_INT16_ARRAY,\n\tDUK_STRIDX_UINT16_ARRAY,\n\tDUK_STRIDX_INT32_ARRAY,\n\tDUK_STRIDX_UINT32_ARRAY,\n\tDUK_STRIDX_FLOAT32_ARRAY,\n\tDUK_STRIDX_FLOAT64_ARRAY,\n\tDUK_STRIDX_EMPTY_STRING,  /* UNUSED, intentionally empty */\n\tDUK_STRIDX_EMPTY_STRING,  /* UNUSED, intentionally empty */\n};\n#line 1 \"duk_alloc_default.c\"\n/*\n *  Default allocation functions.\n *\n *  Assumes behavior such as malloc allowing zero size, yielding\n *  a NULL or a unique pointer which is a no-op for free.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS)\nDUK_INTERNAL void *duk_default_alloc_function(void *udata, duk_size_t size) {\n\tvoid *res;\n\tDUK_UNREF(udata);\n\tres = DUK_ANSI_MALLOC(size);\n\tDUK_DDD(DUK_DDDPRINT(\"default alloc function: %lu -> %p\",\n\t                     (unsigned long) size, (void *) res));\n\treturn res;\n}\n\nDUK_INTERNAL void *duk_default_realloc_function(void *udata, void *ptr, duk_size_t newsize) {\n\tvoid *res;\n\tDUK_UNREF(udata);\n\tres = DUK_ANSI_REALLOC(ptr, newsize);\n\tDUK_DDD(DUK_DDDPRINT(\"default realloc function: %p %lu -> %p\",\n\t                     (void *) ptr, (unsigned long) newsize, (void *) res));\n\treturn res;\n}\n\nDUK_INTERNAL void duk_default_free_function(void *udata, void *ptr) {\n\tDUK_DDD(DUK_DDDPRINT(\"default free function: %p\", (void *) ptr));\n\tDUK_UNREF(udata);\n\tDUK_ANSI_FREE(ptr);\n}\n#endif  /* DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS */\n#line 1 \"duk_api_buffer.c\"\n/*\n *  Buffer\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_EXTERNAL void *duk_resize_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t new_size) {\n\tduk_hbuffer_dynamic *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer_dynamic *) duk_require_hbuffer(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tif (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\t/* Maximum size check is handled by callee. */\n\tduk_hbuffer_resize(thr, h, new_size);\n\n\treturn DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h);\n}\n\nDUK_EXTERNAL void *duk_steal_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tduk_hbuffer_dynamic *h;\n\tvoid *ptr;\n\tduk_size_t sz;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer_dynamic *) duk_require_hbuffer(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tif (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\t/* Forget the previous allocation, setting size to 0 and alloc to\n\t * NULL.  Caller is responsible for freeing the previous allocation.\n\t * Getting the allocation and clearing it is done in the same API\n\t * call to avoid any chance of a realloc.\n\t */\n\tptr = DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h);\n\tsz = DUK_HBUFFER_DYNAMIC_GET_SIZE(h);\n\tif (out_size) {\n\t\t*out_size = sz;\n\t}\n\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(thr->heap, h);\n\tDUK_HBUFFER_DYNAMIC_SET_SIZE(h, 0);\n\n\treturn ptr;\n}\n\nDUK_EXTERNAL void duk_config_buffer(duk_hthread *thr, duk_idx_t idx, void *ptr, duk_size_t len) {\n\tduk_hbuffer_external *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer_external *) duk_require_hbuffer(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tif (!DUK_HBUFFER_HAS_EXTERNAL(h)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h));\n\n\tDUK_HBUFFER_EXTERNAL_SET_DATA_PTR(thr->heap, h, ptr);\n\tDUK_HBUFFER_EXTERNAL_SET_SIZE(h, len);\n}\n#line 1 \"duk_api_bytecode.c\"\n/*\n *  Bytecode dump/load\n *\n *  The bytecode load primitive is more important performance-wise than the\n *  dump primitive.\n *\n *  Unlike most Duktape API calls, bytecode dump/load is not guaranteed to be\n *  memory safe for invalid arguments - caller beware!  There's little point\n *  in trying to achieve memory safety unless bytecode instructions are also\n *  validated which is not easy to do with indirect register references etc.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_BYTECODE_DUMP_SUPPORT)\n\n#define DUK__SER_MARKER  0xbf\n#define DUK__SER_STRING  0x00\n#define DUK__SER_NUMBER  0x01\n#define DUK__BYTECODE_INITIAL_ALLOC 256\n#define DUK__NO_FORMALS  0xffffffffUL\n\n/*\n *  Dump/load helpers, xxx_raw() helpers do no buffer checks\n */\n\nDUK_LOCAL duk_uint8_t *duk__load_string_raw(duk_hthread *thr, duk_uint8_t *p) {\n\tduk_uint32_t len;\n\n\tlen = DUK_RAW_READ_U32_BE(p);\n\tduk_push_lstring(thr, (const char *) p, len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__load_buffer_raw(duk_hthread *thr, duk_uint8_t *p) {\n\tduk_uint32_t len;\n\tduk_uint8_t *buf;\n\n\tlen = DUK_RAW_READ_U32_BE(p);\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) len);\n\tDUK_ASSERT(buf != NULL);\n\tduk_memcpy((void *) buf, (const void *) p, (size_t) len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_hstring_raw(duk_uint8_t *p, duk_hstring *h) {\n\tduk_size_t len;\n\tduk_uint32_t tmp32;\n\n\tDUK_ASSERT(h != NULL);\n\n\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\tDUK_ASSERT(len <= 0xffffffffUL);  /* string limits */\n\ttmp32 = (duk_uint32_t) len;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\tduk_memcpy((void *) p,\n\t           (const void *) DUK_HSTRING_GET_DATA(h),\n\t           len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_hbuffer_raw(duk_hthread *thr, duk_uint8_t *p, duk_hbuffer *h) {\n\tduk_size_t len;\n\tduk_uint32_t tmp32;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\tDUK_UNREF(thr);\n\n\tlen = DUK_HBUFFER_GET_SIZE(h);\n\tDUK_ASSERT(len <= 0xffffffffUL);  /* buffer limits */\n\ttmp32 = (duk_uint32_t) len;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\t/* When len == 0, buffer data pointer may be NULL. */\n\tduk_memcpy_unsafe((void *) p,\n\t                  (const void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h),\n\t                  len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_string_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx) {\n\tduk_hstring *h_str;\n\tduk_tval *tv;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_STRING(tv)) {\n\t\th_str = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h_str != NULL);\n\t} else {\n\t\th_str = DUK_HTHREAD_STRING_EMPTY_STRING(thr);\n\t\tDUK_ASSERT(h_str != NULL);\n\t}\n\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(h_str), p);\n\tp = duk__dump_hstring_raw(p, h_str);\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_buffer_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx) {\n\tduk_tval *tv;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h_buf;\n\t\th_buf = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h_buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFFER_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HBUFFER_GET_SIZE(h_buf), p);\n\t\tp = duk__dump_hbuffer_raw(thr, p, h_buf);\n\t} else {\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\t\tDUK_RAW_WRITE_U32_BE(p, 0);\n\t}\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_uint32_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx, duk_uint32_t def_value) {\n\tduk_tval *tv;\n\tduk_uint32_t val;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_NUMBER(tv)) {\n\t\tval = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv);\n\t} else {\n\t\tval = def_value;\n\t}\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\tDUK_RAW_WRITE_U32_BE(p, val);\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_varmap(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func) {\n\tduk_hobject *h;\n\n\th = duk_hobject_get_varmap(thr, (duk_hobject *) func);\n\tif (h != NULL) {\n\t\tduk_uint_fast32_t i;\n\n\t\t/* We know _Varmap only has own properties so walk property\n\t\t * table directly.  We also know _Varmap is dense and all\n\t\t * values are numbers; assert for these.  GC and finalizers\n\t\t * shouldn't affect _Varmap so side effects should be fine.\n\t\t */\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\t\tduk_hstring *key;\n\t\t\tduk_tval *tv_val;\n\t\t\tduk_uint32_t val;\n\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, h, i);\n\t\t\tDUK_ASSERT(key != NULL);  /* _Varmap is dense */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, h, i));\n\t\t\ttv_val = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, h, i);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_val));  /* known to be number; in fact an integer */\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv_val));\n\t\t\tDUK_ASSERT(DUK_TVAL_GET_FASTINT(tv_val) == (duk_int64_t) DUK_TVAL_GET_FASTINT_U32(tv_val));  /* known to be 32-bit */\n\t\t\tval = DUK_TVAL_GET_FASTINT_U32(tv_val);\n#else\n\t\t\tval = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv_val);\n#endif\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(key) + 4U, p);\n\t\t\tp = duk__dump_hstring_raw(p, key);\n\t\t\tDUK_RAW_WRITE_U32_BE(p, val);\n\t\t}\n\t}\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\tDUK_RAW_WRITE_U32_BE(p, 0);  /* end of _Varmap */\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_formals(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func) {\n\tduk_harray *h;\n\n\th = duk_hobject_get_formals(thr, (duk_hobject *) func);\n\tif (h != NULL) {\n\t\tduk_uint32_t i;\n\n\t\t/* Here we rely on _Formals being a dense array containing\n\t\t * strings.  This should be the case unless _Formals has been\n\t\t * tweaked by the application (which we don't support right\n\t\t * now).\n\t\t */\n\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\t\tDUK_ASSERT(h->length != DUK__NO_FORMALS);  /* limits */\n\t\tDUK_RAW_WRITE_U32_BE(p, h->length);\n\n\t\tfor (i = 0; i < h->length; i++) {\n\t\t\tduk_tval *tv_val;\n\t\t\tduk_hstring *varname;\n\n\t\t\ttv_val = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, (duk_hobject *) h, i);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_val));\n\n\t\t\tvarname = DUK_TVAL_GET_STRING(tv_val);\n\t\t\tDUK_ASSERT(varname != NULL);\n\t\t\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(varname) >= 1);\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(varname), p);\n\t\t\tp = duk__dump_hstring_raw(p, varname);\n\t\t}\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"dumping function without _Formals, emit marker to indicate missing _Formals\"));\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\t\tDUK_RAW_WRITE_U32_BE(p, DUK__NO_FORMALS);  /* marker: no formals */\n\t}\n\treturn p;\n}\n\nstatic duk_uint8_t *duk__dump_func(duk_hthread *thr, duk_hcompfunc *func, duk_bufwriter_ctx *bw_ctx, duk_uint8_t *p) {\n\tduk_tval *tv, *tv_end;\n\tduk_instr_t *ins, *ins_end;\n\tduk_hobject **fn, **fn_end;\n\tduk_hstring *h_str;\n\tduk_uint32_t count_instr;\n\tduk_uint32_t tmp32;\n\tduk_uint16_t tmp16;\n\tduk_double_t d;\n\n\tDUK_DD(DUK_DDPRINT(\"dumping function %p to %p: \"\n\t                   \"consts=[%p,%p[ (%ld bytes, %ld items), \"\n\t                   \"funcs=[%p,%p[ (%ld bytes, %ld items), \"\n\t                   \"code=[%p,%p[ (%ld bytes, %ld items)\",\n\t                   (void *) func,\n\t                   (void *) p,\n\t                   (void *) DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CONSTS_SIZE(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CONSTS_COUNT(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_FUNCS_SIZE(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_CODE_END(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CODE_SIZE(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CODE_COUNT(thr->heap, func)));\n\n\tDUK_ASSERT(DUK_USE_ESBC_MAX_BYTES <= 0x7fffffffUL);  /* ensures no overflow */\n\tcount_instr = (duk_uint32_t) DUK_HCOMPFUNC_GET_CODE_COUNT(thr->heap, func);\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 3U * 4U + 2U * 2U + 3U * 4U + count_instr * 4U, p);\n\n\t/* Fixed header info. */\n\ttmp32 = count_instr;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp32 = (duk_uint32_t) DUK_HCOMPFUNC_GET_CONSTS_COUNT(thr->heap, func);\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp32 = (duk_uint32_t) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, func);\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp16 = func->nregs;\n\tDUK_RAW_WRITE_U16_BE(p, tmp16);\n\ttmp16 = func->nargs;\n\tDUK_RAW_WRITE_U16_BE(p, tmp16);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\ttmp32 = func->start_line;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp32 = func->end_line;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n#else\n\tDUK_RAW_WRITE_U32_BE(p, 0);\n\tDUK_RAW_WRITE_U32_BE(p, 0);\n#endif\n\ttmp32 = DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) func);  /* masks flags, only duk_hobject flags */\n\ttmp32 &= ~(DUK_HOBJECT_FLAG_HAVE_FINALIZER);  /* finalizer flag is lost */\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\n\t/* Bytecode instructions: endian conversion needed unless\n\t * platform is big endian.\n\t */\n\tins = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, func);\n\tins_end = DUK_HCOMPFUNC_GET_CODE_END(thr->heap, func);\n\tDUK_ASSERT((duk_size_t) (ins_end - ins) == (duk_size_t) count_instr);\n#if defined(DUK_USE_INTEGER_BE)\n\tduk_memcpy_unsafe((void *) p, (const void *) ins, (size_t) (ins_end - ins));\n\tp += (size_t) (ins_end - ins);\n#else\n\twhile (ins != ins_end) {\n\t\ttmp32 = (duk_uint32_t) (*ins);\n\t\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\t\tins++;\n\t}\n#endif\n\n\t/* Constants: variable size encoding. */\n\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, func);\n\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, func);\n\twhile (tv != tv_end) {\n\t\t/* constants are strings or numbers now */\n\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv) ||\n\t\t           DUK_TVAL_IS_NUMBER(tv));\n\n\t\tif (DUK_TVAL_IS_STRING(tv)) {\n\t\t\th_str = DUK_TVAL_GET_STRING(tv);\n\t\t\tDUK_ASSERT(h_str != NULL);\n\t\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1U + 4U + DUK_HSTRING_GET_BYTELEN(h_str), p);\n\t\t\t*p++ = DUK__SER_STRING;\n\t\t\tp = duk__dump_hstring_raw(p, h_str);\n\t\t} else {\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1U + 8U, p);\n\t\t\t*p++ = DUK__SER_NUMBER;\n\t\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t\t\tDUK_RAW_WRITE_DOUBLE_BE(p, d);\n\t\t}\n\t\ttv++;\n\t}\n\n\t/* Inner functions recursively. */\n\tfn = (duk_hobject **) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, func);\n\tfn_end = (duk_hobject **) DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, func);\n\twhile (fn != fn_end) {\n\t\t/* XXX: This causes recursion up to inner function depth\n\t\t * which is normally not an issue, e.g. mark-and-sweep uses\n\t\t * a recursion limiter to avoid C stack issues.  Avoiding\n\t\t * this would mean some sort of a work list or just refusing\n\t\t * to serialize deep functions.\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(*fn));\n\t\tp = duk__dump_func(thr, (duk_hcompfunc *) *fn, bw_ctx, p);\n\t\tfn++;\n\t}\n\n\t/* Lexenv and varenv are not dumped. */\n\n\t/* Object extra properties.\n\t *\n\t * There are some difference between function templates and functions.\n\t * For example, function templates don't have .length and nargs is\n\t * normally used to instantiate the functions.\n\t */\n\n\tp = duk__dump_uint32_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_LENGTH, (duk_uint32_t) func->nargs);\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tp = duk__dump_string_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_NAME);\n#endif\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tp = duk__dump_string_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_FILE_NAME);\n#endif\n#if defined(DUK_USE_PC2LINE)\n\tp = duk__dump_buffer_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_INT_PC2LINE);\n#endif\n\tp = duk__dump_varmap(thr, p, bw_ctx, (duk_hobject *) func);\n\tp = duk__dump_formals(thr, p, bw_ctx, (duk_hobject *) func);\n\n\tDUK_DD(DUK_DDPRINT(\"serialized function %p -> final pointer %p\", (void *) func, (void *) p));\n\n\treturn p;\n}\n\n/* Load a function from bytecode.  The function object returned here must\n * match what is created by duk_js_push_closure() with respect to its flags,\n * properties, etc.\n *\n * NOTE: there are intentionally no input buffer length / bound checks.\n * Adding them would be easy but wouldn't ensure memory safety as untrusted\n * or broken bytecode is unsafe during execution unless the opcodes themselves\n * are validated (which is quite complex, especially for indirect opcodes).\n */\n\n#define DUK__ASSERT_LEFT(n) do { \\\n\t\tDUK_ASSERT((duk_size_t) (p_end - p) >= (duk_size_t) (n)); \\\n\t} while (0)\n\nstatic duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t *p_end) {\n\tduk_hcompfunc *h_fun;\n\tduk_hbuffer *h_data;\n\tduk_size_t data_size;\n\tduk_uint32_t count_instr, count_const, count_funcs;\n\tduk_uint32_t n;\n\tduk_uint32_t tmp32;\n\tduk_small_uint_t const_type;\n\tduk_uint8_t *fun_data;\n\tduk_uint8_t *q;\n\tduk_idx_t idx_base;\n\tduk_tval *tv1;\n\tduk_uarridx_t arr_idx;\n\tduk_uarridx_t arr_limit;\n\tduk_hobject *func_env;\n\tduk_bool_t need_pop;\n\n\t/* XXX: There's some overlap with duk_js_closure() here, but\n\t * seems difficult to share code.  Ensure that the final function\n\t * looks the same as created by duk_js_closure().\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"loading function, p=%p, p_end=%p\", (void *) p, (void *) p_end));\n\n\tDUK__ASSERT_LEFT(3 * 4);\n\tcount_instr = DUK_RAW_READ_U32_BE(p);\n\tcount_const = DUK_RAW_READ_U32_BE(p);\n\tcount_funcs = DUK_RAW_READ_U32_BE(p);\n\n\tdata_size = sizeof(duk_tval) * count_const +\n\t            sizeof(duk_hobject *) * count_funcs +\n\t            sizeof(duk_instr_t) * count_instr;\n\n\tDUK_DD(DUK_DDPRINT(\"instr=%ld, const=%ld, funcs=%ld, data_size=%ld\",\n\t                   (long) count_instr, (long) count_const,\n\t                   (long) count_const, (long) data_size));\n\n\t/* Value stack is used to ensure reachability of constants and\n\t * inner functions being loaded.  Require enough space to handle\n\t * large functions correctly.\n\t */\n\tduk_require_stack(thr, (duk_idx_t) (2 + count_const + count_funcs));\n\tidx_base = duk_get_top(thr);\n\n\t/* Push function object, init flags etc.  This must match\n\t * duk_js_push_closure() quite carefully.\n\t */\n\th_fun = duk_push_hcompfunc(thr);\n\tDUK_ASSERT(h_fun != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) h_fun));\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, h_fun) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, h_fun) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, h_fun) == NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_fun) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\n\th_fun->nregs = DUK_RAW_READ_U16_BE(p);\n\th_fun->nargs = DUK_RAW_READ_U16_BE(p);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\th_fun->start_line = DUK_RAW_READ_U32_BE(p);\n\th_fun->end_line = DUK_RAW_READ_U32_BE(p);\n#else\n\tp += 8;  /* skip line info */\n#endif\n\n\t/* duk_hcompfunc flags; quite version specific */\n\ttmp32 = DUK_RAW_READ_U32_BE(p);\n\tDUK_HEAPHDR_SET_FLAGS((duk_heaphdr *) h_fun, tmp32);  /* masks flags to only change duk_hobject flags */\n\n\t/* standard prototype (no need to set here, already set) */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_fun) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#if 0\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, &h_fun->obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#endif\n\n\t/* assert just a few critical flags */\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h_fun) == DUK_HTYPE_OBJECT);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&h_fun->obj));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_IS_PROXY(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(&h_fun->obj));\n\n\t/* Create function 'data' buffer but don't attach it yet. */\n\tfun_data = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, data_size);\n\tDUK_ASSERT(fun_data != NULL);\n\n\t/* Load bytecode instructions. */\n\tDUK_ASSERT(sizeof(duk_instr_t) == 4);\n\tDUK__ASSERT_LEFT(count_instr * sizeof(duk_instr_t));\n#if defined(DUK_USE_INTEGER_BE)\n\tq = fun_data + sizeof(duk_tval) * count_const + sizeof(duk_hobject *) * count_funcs;\n\tduk_memcpy((void *) q,\n\t           (const void *) p,\n\t           sizeof(duk_instr_t) * count_instr);\n\tp += sizeof(duk_instr_t) * count_instr;\n#else\n\tq = fun_data + sizeof(duk_tval) * count_const + sizeof(duk_hobject *) * count_funcs;\n\tfor (n = count_instr; n > 0; n--) {\n\t\t*((duk_instr_t *) (void *) q) = DUK_RAW_READ_U32_BE(p);\n\t\tq += sizeof(duk_instr_t);\n\t}\n#endif\n\n\t/* Load constants onto value stack but don't yet copy to buffer. */\n\tfor (n = count_const; n > 0; n--) {\n\t\tDUK__ASSERT_LEFT(1);\n\t\tconst_type = DUK_RAW_READ_U8(p);\n\t\tswitch (const_type) {\n\t\tcase DUK__SER_STRING: {\n\t\t\tp = duk__load_string_raw(thr, p);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK__SER_NUMBER: {\n\t\t\t/* Important to do a fastint check so that constants are\n\t\t\t * properly read back as fastints.\n\t\t\t */\n\t\t\tduk_tval tv_tmp;\n\t\t\tduk_double_t val;\n\t\t\tDUK__ASSERT_LEFT(8);\n\t\t\tval = DUK_RAW_READ_DOUBLE_BE(p);\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(&tv_tmp, val);\n\t\t\tduk_push_tval(thr, &tv_tmp);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tgoto format_error;\n\t\t}\n\t\t}\n\t}\n\n\t/* Load inner functions to value stack, but don't yet copy to buffer. */\n\tfor (n = count_funcs; n > 0; n--) {\n\t\tp = duk__load_func(thr, p, p_end);\n\t\tif (p == NULL) {\n\t\t\tgoto format_error;\n\t\t}\n\t}\n\n\t/* With constants and inner functions on value stack, we can now\n\t * atomically finish the function 'data' buffer, bump refcounts,\n\t * etc.\n\t *\n\t * Here we take advantage of the value stack being just a duk_tval\n\t * array: we can just memcpy() the constants as long as we incref\n\t * them afterwards.\n\t */\n\n\th_data = (duk_hbuffer *) duk_known_hbuffer(thr, idx_base + 1);\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC(h_data));\n\tDUK_HCOMPFUNC_SET_DATA(thr->heap, h_fun, h_data);\n\tDUK_HBUFFER_INCREF(thr, h_data);\n\n\ttv1 = duk_get_tval(thr, idx_base + 2);  /* may be NULL if no constants or inner funcs */\n\tDUK_ASSERT((count_const == 0 && count_funcs == 0) || tv1 != NULL);\n\n\tq = fun_data;\n\tduk_memcpy_unsafe((void *) q, (const void *) tv1, sizeof(duk_tval) * count_const);\n\tfor (n = count_const; n > 0; n--) {\n\t\tDUK_TVAL_INCREF_FAST(thr, (duk_tval *) (void *) q);  /* no side effects */\n\t\tq += sizeof(duk_tval);\n\t}\n\ttv1 += count_const;\n\n\tDUK_HCOMPFUNC_SET_FUNCS(thr->heap, h_fun, (duk_hobject **) (void *) q);\n\tfor (n = count_funcs; n > 0; n--) {\n\t\tduk_hobject *h_obj;\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv1));\n\t\th_obj = DUK_TVAL_GET_OBJECT(tv1);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\ttv1++;\n\t\tDUK_HOBJECT_INCREF(thr, h_obj);\n\n\t\t*((duk_hobject **) (void *) q) = h_obj;\n\t\tq += sizeof(duk_hobject *);\n\t}\n\n\tDUK_HCOMPFUNC_SET_BYTECODE(thr->heap, h_fun, (duk_instr_t *) (void *) q);\n\n\t/* The function object is now reachable and refcounts are fine,\n\t * so we can pop off all the temporaries.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"function is reachable, reset top; func: %!iT\", duk_get_tval(thr, idx_base)));\n\tduk_set_top(thr, idx_base + 1);\n\n\t/* Setup function properties. */\n\ttmp32 = DUK_RAW_READ_U32_BE(p);\n\tduk_push_u32(thr, tmp32);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tp = duk__load_string_raw(thr, p);  /* -> [ func funcname ] */\n\tfunc_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\tDUK_ASSERT(func_env != NULL);\n\tneed_pop = 0;\n\tif (DUK_HOBJECT_HAS_NAMEBINDING((duk_hobject *) h_fun)) {\n\t\t/* Original function instance/template had NAMEBINDING.\n\t\t * Must create a lexical environment on loading to allow\n\t\t * recursive functions like 'function foo() { foo(); }'.\n\t\t */\n\t\tduk_hdecenv *new_env;\n\n\t\tnew_env = duk_hdecenv_alloc(thr,\n\t\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\t\tDUK_ASSERT(new_env != NULL);\n\t\tDUK_ASSERT(new_env->thread == NULL);  /* Closed. */\n\t\tDUK_ASSERT(new_env->varmap == NULL);\n\t\tDUK_ASSERT(new_env->regbase_byteoff == 0);\n\t\tDUK_HDECENV_ASSERT_VALID(new_env);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, func_env);\n\t\tDUK_HOBJECT_INCREF(thr, func_env);\n\n\t\tfunc_env = (duk_hobject *) new_env;\n\n\t\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\n\t\tduk_dup_m2(thr);                                  /* -> [ func funcname env funcname ] */\n\t\tduk_dup(thr, idx_base);                           /* -> [ func funcname env funcname func ] */\n\t\tduk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_NONE);  /* -> [ func funcname env ] */\n\n\t\tneed_pop = 1;  /* Need to pop env, but -after- updating h_fun and increfs. */\n\t}\n\tDUK_ASSERT(func_env != NULL);\n\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, h_fun, func_env);\n\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, h_fun, func_env);\n\tDUK_HOBJECT_INCREF(thr, func_env);\n\tDUK_HOBJECT_INCREF(thr, func_env);\n\tif (need_pop) {\n\t\tduk_pop(thr);\n\t}\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n#endif  /* DUK_USE_FUNC_NAME_PROPERTY */\n\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tp = duk__load_string_raw(thr, p);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C);\n#endif  /* DUK_USE_FUNC_FILENAME_PROPERTY */\n\n\tif (DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) h_fun)) {\n\t\t/* Restore empty external .prototype only for constructable\n\t\t * functions.  The prototype object should inherit from\n\t\t * Object.prototype.\n\t\t */\n\t\tduk_push_object(thr);\n\t\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\t\tduk_dup_m2(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC);  /* func.prototype.constructor = func */\n\t\tduk_compact_m1(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W);\n\t}\n\n#if defined(DUK_USE_PC2LINE)\n\tp = duk__load_buffer_raw(thr, p);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_WC);\n#endif  /* DUK_USE_PC2LINE */\n\n\tduk_push_bare_object(thr);  /* _Varmap */\n\tfor (;;) {\n\t\t/* XXX: awkward */\n\t\tp = duk__load_string_raw(thr, p);\n\t\tif (duk_get_length(thr, -1) == 0) {\n\t\t\tduk_pop(thr);\n\t\t\tbreak;\n\t\t}\n\t\ttmp32 = DUK_RAW_READ_U32_BE(p);\n\t\tduk_push_u32(thr, tmp32);\n\t\tduk_put_prop(thr, -3);\n\t}\n\tduk_compact_m1(thr);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VARMAP, DUK_PROPDESC_FLAGS_NONE);\n\n\t/* _Formals may have been missing in the original function, which is\n\t * handled using a marker length.\n\t */\n\tarr_limit = DUK_RAW_READ_U32_BE(p);\n\tif (arr_limit != DUK__NO_FORMALS) {\n\t\tduk_push_bare_array(thr);  /* _Formals */\n\t\tfor (arr_idx = 0; arr_idx < arr_limit; arr_idx++) {\n\t\t\tp = duk__load_string_raw(thr, p);\n\t\t\tduk_put_prop_index(thr, -2, arr_idx);\n\t\t}\n\t\tduk_compact_m1(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_FORMALS, DUK_PROPDESC_FLAGS_NONE);\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"no _Formals in dumped function\"));\n\t}\n\n\t/* Return with final function pushed on stack top. */\n\tDUK_DD(DUK_DDPRINT(\"final loaded function: %!iT\", duk_get_tval(thr, -1)));\n\tDUK_ASSERT_TOP(thr, idx_base + 1);\n\treturn p;\n\n format_error:\n\treturn NULL;\n}\n\nDUK_EXTERNAL void duk_dump_function(duk_hthread *thr) {\n\tduk_hcompfunc *func;\n\tduk_bufwriter_ctx bw_ctx_alloc;\n\tduk_bufwriter_ctx *bw_ctx = &bw_ctx_alloc;\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Bound functions don't have all properties so we'd either need to\n\t * lookup the non-bound target function or reject bound functions.\n\t * For now, bound functions are rejected with TypeError.\n\t */\n\tfunc = duk_require_hcompfunc(thr, -1);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&func->obj));\n\n\t/* Estimating the result size beforehand would be costly, so\n\t * start with a reasonable size and extend as needed.\n\t */\n\tDUK_BW_INIT_PUSHBUF(thr, bw_ctx, DUK__BYTECODE_INITIAL_ALLOC);\n\tp = DUK_BW_GET_PTR(thr, bw_ctx);\n\t*p++ = DUK__SER_MARKER;\n\tp = duk__dump_func(thr, func, bw_ctx, p);\n\tDUK_BW_SET_PTR(thr, bw_ctx, p);\n\tDUK_BW_COMPACT(thr, bw_ctx);\n\n\tDUK_DD(DUK_DDPRINT(\"serialized result: %!T\", duk_get_tval(thr, -1)));\n\n\tduk_remove_m2(thr);  /* [ ... func buf ] -> [ ... buf ] */\n}\n\nDUK_EXTERNAL void duk_load_function(duk_hthread *thr) {\n\tduk_uint8_t *p_buf, *p, *p_end;\n\tduk_size_t sz;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tp_buf = (duk_uint8_t *) duk_require_buffer(thr, -1, &sz);\n\tDUK_ASSERT(p_buf != NULL);\n\n\t/* The caller is responsible for being sure that bytecode being loaded\n\t * is valid and trusted.  Invalid bytecode can cause memory unsafe\n\t * behavior directly during loading or later during bytecode execution\n\t * (instruction validation would be quite complex to implement).\n\t *\n\t * This signature check is the only sanity check for detecting\n\t * accidental invalid inputs.  The initial byte ensures no ordinary\n\t * string or Symbol will be accepted by accident.\n\t */\n\tp = p_buf;\n\tp_end = p_buf + sz;\n\tif (sz < 1 || p[0] != DUK__SER_MARKER) {\n\t\tgoto format_error;\n\t}\n\tp++;\n\n\tp = duk__load_func(thr, p, p_end);\n\tif (p == NULL) {\n\t\tgoto format_error;\n\t}\n\n\tduk_remove_m2(thr);  /* [ ... buf func ] -> [ ... func ] */\n\treturn;\n\n format_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BYTECODE);\n\tDUK_WO_NORETURN(return;);\n}\n\n#else  /* DUK_USE_BYTECODE_DUMP_SUPPORT */\n\nDUK_EXTERNAL void duk_dump_function(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_load_function(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n#endif  /* DUK_USE_BYTECODE_DUMP_SUPPORT */\n\n/* automatic undefs */\n#undef DUK__ASSERT_LEFT\n#undef DUK__BYTECODE_INITIAL_ALLOC\n#undef DUK__NO_FORMALS\n#undef DUK__SER_MARKER\n#undef DUK__SER_NUMBER\n#undef DUK__SER_STRING\n#line 1 \"duk_api_call.c\"\n/*\n *  Calls.\n *\n *  Protected variants should avoid ever throwing an error.  Must be careful\n *  to catch errors related to value stack manipulation and property lookup,\n *  not just the call itself.\n *\n *  The only exception is when arguments are insane, e.g. nargs/nrets are out\n *  of bounds; in such cases an error is thrown for two reasons.  First, we\n *  can't always respect the value stack input/output guarantees in such cases\n *  so the caller would end up with the value stack in an unexpected state.\n *  Second, an attempt to create an error might itself fail (although this\n *  could be avoided by pushing a preallocated object/string or a primitive\n *  value).\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Helpers\n */\n\nstruct duk__pcall_prop_args {\n\tduk_idx_t obj_idx;\n\tduk_idx_t nargs;\n\tduk_small_uint_t call_flags;\n};\ntypedef struct duk__pcall_prop_args duk__pcall_prop_args;\n\nstruct duk__pcall_method_args {\n\tduk_idx_t nargs;\n\tduk_small_uint_t call_flags;\n};\ntypedef struct duk__pcall_method_args duk__pcall_method_args;\n\nstruct duk__pcall_args {\n\tduk_idx_t nargs;\n\tduk_small_uint_t call_flags;\n};\ntypedef struct duk__pcall_args duk__pcall_args;\n\n/* Compute and validate idx_func for a certain 'nargs' and 'other'\n * parameter count (1 or 2, depending on whether 'this' binding is\n * present).\n */\nDUK_LOCAL duk_idx_t duk__call_get_idx_func(duk_hthread *thr, duk_idx_t nargs, duk_idx_t other) {\n\tduk_idx_t idx_func;\n\n\t/* XXX: byte arithmetic? */\n\n\tDUK_ASSERT(other >= 0);\n\n\tidx_func = duk_get_top(thr) - nargs - other;\n\tif (DUK_UNLIKELY((idx_func | nargs) < 0)) {  /* idx_func < 0 || nargs < 0; OR sign bits */\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\treturn idx_func;\n}\n\n/* Compute idx_func, assume index will be valid.  This is a valid assumption\n * for protected calls: nargs < 0 is checked explicitly and duk_safe_call()\n * validates the argument count.\n */\nDUK_LOCAL duk_idx_t duk__call_get_idx_func_unvalidated(duk_hthread *thr, duk_idx_t nargs, duk_idx_t other) {\n\tduk_idx_t idx_func;\n\n\t/* XXX: byte arithmetic? */\n\n\tDUK_ASSERT(nargs >= 0);\n\tDUK_ASSERT(other >= 0);\n\n\tidx_func = duk_get_top(thr) - nargs - other;\n\tDUK_ASSERT(idx_func >= 0);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\treturn idx_func;\n}\n\n/* Prepare value stack for a method call through an object property.\n * May currently throw an error e.g. when getting the property.\n */\nDUK_LOCAL void duk__call_prop_prep_stack(duk_hthread *thr, duk_idx_t normalized_obj_idx, duk_idx_t nargs) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(nargs >= 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__call_prop_prep_stack, normalized_obj_idx=%ld, nargs=%ld, stacktop=%ld\",\n\t                     (long) normalized_obj_idx, (long) nargs, (long) duk_get_top(thr)));\n\n\t/* [... key arg1 ... argN] */\n\n\t/* duplicate key */\n\tduk_dup(thr, -nargs - 1);  /* Note: -nargs alone would fail for nargs == 0, this is OK */\n\t(void) duk_get_prop(thr, normalized_obj_idx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"func: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\tif (DUK_UNLIKELY(!duk_is_callable(thr, -1))) {\n\t\tduk_tval *tv_base;\n\t\tduk_tval *tv_key;\n\n\t\t/* tv_targ is passed on stack top (at index -1). */\n\t\ttv_base = DUK_GET_TVAL_POSIDX(thr, normalized_obj_idx);\n\t\ttv_key = DUK_GET_TVAL_NEGIDX(thr, -nargs - 2);\n\t\tDUK_ASSERT(tv_base >= thr->valstack_bottom && tv_base < thr->valstack_top);\n\t\tDUK_ASSERT(tv_key >= thr->valstack_bottom && tv_key < thr->valstack_top);\n\n\t\tduk_call_setup_propcall_error(thr, tv_base, tv_key);\n\t}\n#endif\n\n\t/* [... key arg1 ... argN func] */\n\n\tduk_replace(thr, -nargs - 2);\n\n\t/* [... func arg1 ... argN] */\n\n\tduk_dup(thr, normalized_obj_idx);\n\tduk_insert(thr, -nargs - 1);\n\n\t/* [... func this arg1 ... argN] */\n}\n\nDUK_EXTERNAL void duk_call(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_small_uint_t call_flags;\n\tduk_idx_t idx_func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx_func = duk__call_get_idx_func(thr, nargs, 1);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tduk_insert_undefined(thr, idx_func + 1);\n\n\tcall_flags = 0;  /* not protected, respect reclimit, not constructor */\n\tduk_handle_call_unprotected(thr, idx_func, call_flags);\n}\n\nDUK_EXTERNAL void duk_call_method(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_small_uint_t call_flags;\n\tduk_idx_t idx_func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx_func = duk__call_get_idx_func(thr, nargs, 2);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tcall_flags = 0;  /* not protected, respect reclimit, not constructor */\n\tduk_handle_call_unprotected(thr, idx_func, call_flags);\n}\n\nDUK_EXTERNAL void duk_call_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t nargs) {\n\t/*\n\t *  XXX: if duk_handle_call() took values through indices, this could be\n\t *  made much more sensible.  However, duk_handle_call() needs to fudge\n\t *  the 'this' and 'func' values to handle bound functions, which is now\n\t *  done \"in-place\", so this is not a trivial change.\n\t */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);  /* make absolute */\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk__call_prop_prep_stack(thr, obj_idx, nargs);\n\n\tduk_call_method(thr, nargs);\n}\n\nDUK_LOCAL duk_ret_t duk__pcall_raw(duk_hthread *thr, void *udata) {\n\tduk__pcall_args *args;\n\tduk_idx_t idx_func;\n\tduk_int_t ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\targs = (duk__pcall_args *) udata;\n\tidx_func = duk__call_get_idx_func_unvalidated(thr, args->nargs, 1);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tduk_insert_undefined(thr, idx_func + 1);\n\n\tret = duk_handle_call_unprotected(thr, idx_func, args->call_flags);\n\tDUK_ASSERT(ret == 0);\n\tDUK_UNREF(ret);\n\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_pcall(duk_hthread *thr, duk_idx_t nargs) {\n\tduk__pcall_args args;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\targs.nargs = nargs;\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\targs.call_flags = 0;\n\n\treturn duk_safe_call(thr, duk__pcall_raw, (void *) &args /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);\n}\n\nDUK_LOCAL duk_ret_t duk__pcall_method_raw(duk_hthread *thr, void *udata) {\n\tduk__pcall_method_args *args;\n\tduk_idx_t idx_func;\n\tduk_int_t ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\targs = (duk__pcall_method_args *) udata;\n\n\tidx_func = duk__call_get_idx_func_unvalidated(thr, args->nargs, 2);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tret = duk_handle_call_unprotected(thr, idx_func, args->call_flags);\n\tDUK_ASSERT(ret == 0);\n\tDUK_UNREF(ret);\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_int_t duk_pcall_method_flags(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags) {\n\tduk__pcall_method_args args;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\targs.nargs = nargs;\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\targs.call_flags = call_flags;\n\n\treturn duk_safe_call(thr, duk__pcall_method_raw, (void *) &args /*udata*/, nargs + 2 /*nargs*/, 1 /*nrets*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_pcall_method(duk_hthread *thr, duk_idx_t nargs) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_pcall_method_flags(thr, nargs, 0);\n}\n\nDUK_LOCAL duk_ret_t duk__pcall_prop_raw(duk_hthread *thr, void *udata) {\n\tduk__pcall_prop_args *args;\n\tduk_idx_t obj_idx;\n\tduk_int_t ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\targs = (duk__pcall_prop_args *) udata;\n\n\tobj_idx = duk_require_normalize_index(thr, args->obj_idx);  /* make absolute */\n\tduk__call_prop_prep_stack(thr, obj_idx, args->nargs);\n\n\tret = duk_handle_call_unprotected_nargs(thr, args->nargs, args->call_flags);\n\tDUK_ASSERT(ret == 0);\n\tDUK_UNREF(ret);\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_pcall_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t nargs) {\n\tduk__pcall_prop_args args;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\targs.obj_idx = obj_idx;\n\targs.nargs = nargs;\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\targs.call_flags = 0;\n\n\treturn duk_safe_call(thr, duk__pcall_prop_raw, (void *) &args /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_safe_call(duk_hthread *thr, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* nargs condition; fail if: top - bottom < nargs\n\t *                      <=>  top < bottom + nargs\n\t * nrets condition; fail if: end - (top - nargs) < nrets\n\t *                      <=>  end - top + nargs < nrets\n\t *                      <=>  end + nargs < top + nrets\n\t */\n\t/* XXX: check for any reserve? */\n\n\tif (DUK_UNLIKELY((nargs | nrets) < 0 ||  /* nargs < 0 || nrets < 0; OR sign bits */\n\t                 thr->valstack_top < thr->valstack_bottom + nargs ||        /* nargs too large compared to top */\n\t                 thr->valstack_end + nargs < thr->valstack_top + nrets)) {  /* nrets too large compared to reserve */\n\t\tDUK_D(DUK_DPRINT(\"not enough stack reserve for safe call or invalid arguments: \"\n\t\t                 \"nargs=%ld < 0 (?), nrets=%ld < 0 (?), top=%ld < bottom=%ld + nargs=%ld (?), \"\n\t\t                 \"end=%ld + nargs=%ld < top=%ld + nrets=%ld (?)\",\n\t\t                  (long) nargs,\n\t\t                  (long) nrets,\n\t\t                  (long) (thr->valstack_top - thr->valstack),\n\t\t                  (long) (thr->valstack_bottom - thr->valstack),\n\t\t                  (long) nargs,\n\t\t                  (long) (thr->valstack_end - thr->valstack),\n\t\t                  (long) nargs,\n\t\t                  (long) (thr->valstack_top - thr->valstack),\n\t\t                  (long) nrets));\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\n\trc = duk_handle_safe_call(thr,           /* thread */\n\t                          func,          /* func */\n\t                          udata,         /* udata */\n\t                          nargs,         /* num_stack_args */\n\t                          nrets);        /* num_stack_res */\n\n\treturn rc;\n}\n\nDUK_EXTERNAL void duk_new(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_idx_t idx_func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx_func = duk__call_get_idx_func(thr, nargs, 1);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tduk_push_object(thr);  /* default instance; internal proto updated by call handling */\n\tduk_insert(thr, idx_func + 1);\n\n\tduk_handle_call_unprotected(thr, idx_func, DUK_CALL_FLAG_CONSTRUCT);\n}\n\nDUK_LOCAL duk_ret_t duk__pnew_helper(duk_hthread *thr, void *udata) {\n\tduk_idx_t nargs;\n\n\tDUK_ASSERT(udata != NULL);\n\tnargs = *((duk_idx_t *) udata);\n\n\tduk_new(thr, nargs);\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_pnew(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* For now, just use duk_safe_call() to wrap duk_new().  We can't\n\t * simply use a protected duk_handle_call() because pushing the\n\t * default instance might throw.\n\t */\n\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\n\trc = duk_safe_call(thr, duk__pnew_helper, (void *) &nargs /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);\n\treturn rc;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_constructor_call(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\treturn ((act->flags & DUK_ACT_FLAG_CONSTRUCT) != 0 ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL void duk_require_constructor_call(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (!duk_is_constructor_call(thr)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_CONSTRUCT_ONLY);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_strict_call(duk_hthread *thr) {\n\tduk_activation *act;\n\n\t/* For user code this could just return 1 (strict) always\n\t * because all Duktape/C functions are considered strict,\n\t * and strict is also the default when nothing is running.\n\t * However, Duktape may call this function internally when\n\t * the current activation is an ECMAScript function, so\n\t * this cannot be replaced by a 'return 1' without fixing\n\t * the internal call sites.\n\t */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\treturn ((act->flags & DUK_ACT_FLAG_STRICT) != 0 ? 1 : 0);\n\t} else {\n\t\t/* Strict by default. */\n\t\treturn 1;\n\t}\n}\n\n/*\n *  Duktape/C function magic\n */\n\nDUK_EXTERNAL duk_int_t duk_get_current_magic(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_hobject *func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act) {\n\t\tfunc = DUK_ACT_GET_FUNC(act);\n\t\tif (!func) {\n\t\t\tduk_tval *tv = &act->tv_func;\n\t\t\tduk_small_uint_t lf_flags;\n\t\t\tlf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv);\n\t\t\treturn (duk_int_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags);\n\t\t}\n\t\tDUK_ASSERT(func != NULL);\n\n\t\tif (DUK_HOBJECT_IS_NATFUNC(func)) {\n\t\t\tduk_hnatfunc *nf = (duk_hnatfunc *) func;\n\t\t\treturn (duk_int_t) nf->magic;\n\t\t}\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_int_t duk_get_magic(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (!DUK_HOBJECT_HAS_NATFUNC(h)) {\n\t\t\tgoto type_error;\n\t\t}\n\t\treturn (duk_int_t) ((duk_hnatfunc *) h)->magic;\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_small_uint_t lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv);\n\t\treturn (duk_int_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags);\n\t}\n\n\t/* fall through */\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_UNEXPECTED_TYPE);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_EXTERNAL void duk_set_magic(duk_hthread *thr, duk_idx_t idx, duk_int_t magic) {\n\tduk_hnatfunc *nf;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tnf = duk_require_hnatfunc(thr, idx);\n\tDUK_ASSERT(nf != NULL);\n\tnf->magic = (duk_int16_t) magic;\n}\n\n/*\n *  Misc helpers\n */\n\n/* Resolve a bound function on value stack top to a non-bound target\n * (leave other values as is).\n */\nDUK_INTERNAL void duk_resolve_nonbound_function(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_HTHREAD_ASSERT_VALID(thr);\n\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(h)) {\n\t\t\tduk_push_tval(thr, &((duk_hboundfunc *) (void *) h)->target);\n\t\t\tduk_replace(thr, -2);\n#if 0\n\t\t\tDUK_TVAL_SET_TVAL(tv, &((duk_hboundfunc *) h)->target);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tDUK_HOBJECT_DECREF_NORZ(thr, h);\n#endif\n\t\t\t/* Rely on Function.prototype.bind() on never creating a bound\n\t\t\t * function whose target is not proper.  This is now safe\n\t\t\t * because the target is not even an internal property but a\n\t\t\t * struct member.\n\t\t\t */\n\t\t\tDUK_ASSERT(duk_is_lightfunc(thr, -1) || duk_is_callable(thr, -1));\n\t\t}\n\t}\n\n\t/* Lightfuncs cannot be bound but are always callable and\n\t * constructable.\n\t */\n}\n#line 1 \"duk_api_codec.c\"\n/*\n *  Encoding and decoding basic formats: hex, base64.\n *\n *  These are in-place operations which may allow an optimized implementation.\n *\n *  Base-64: https://tools.ietf.org/html/rfc4648#section-4\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Misc helpers\n */\n\n/* Shared handling for encode/decode argument.  Fast path handling for\n * buffer and string values because they're the most common.  In particular,\n * avoid creating a temporary string or buffer when possible.  Return value\n * is guaranteed to be non-NULL, even for zero length input.\n */\nDUK_LOCAL const duk_uint8_t *duk__prep_codec_arg(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tconst void *def_ptr = (const void *) out_len;  /* Any non-NULL pointer will do. */\n\tconst void *ptr;\n\tduk_bool_t isbuffer;\n\n\tDUK_ASSERT(out_len != NULL);\n\tDUK_ASSERT(def_ptr != NULL);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx));  /* checked by caller */\n\n\tptr = (const void *) duk_get_buffer_data_raw(thr, idx, out_len, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, &isbuffer);\n\tif (isbuffer) {\n\t\tDUK_ASSERT(ptr != NULL || *out_len == 0U);\n\t\tif (DUK_UNLIKELY(ptr == NULL)) {\n\t\t\tptr = def_ptr;\n\t\t}\n\t\tDUK_ASSERT(ptr != NULL);\n\t} else {\n\t\t/* For strings a non-NULL pointer is always guaranteed because\n\t\t * at least a NUL will be present.\n\t\t */\n\t\tptr = (const void *) duk_to_lstring(thr, idx, out_len);\n\t\tDUK_ASSERT(ptr != NULL);\n\t}\n\tDUK_ASSERT(ptr != NULL);\n\treturn (const duk_uint8_t *) ptr;\n}\n\n/*\n *  Base64\n */\n\n#if defined(DUK_USE_BASE64_SUPPORT)\n/* Bytes emitted for number of padding characters in range [0,4]. */\nDUK_LOCAL const duk_int8_t duk__base64_decode_nequal_step[5] = {\n\t3,   /* #### -> 24 bits, emit 3 bytes */\n\t2,   /* ###= -> 18 bits, emit 2 bytes */\n\t1,   /* ##== -> 12 bits, emit 1 byte */\n\t-1,  /* #=== -> 6 bits, error */\n\t0,   /* ==== -> 0 bits, emit 0 bytes */\n};\n\n#if defined(DUK_USE_BASE64_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__base64_enctab_fast[64] = {\n\t0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, 0x50U,  /* A...P */\n\t0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, 0x58U, 0x59U, 0x5aU, 0x61U, 0x62U, 0x63U, 0x64U, 0x65U, 0x66U,  /* Q...f */\n\t0x67U, 0x68U, 0x69U, 0x6aU, 0x6bU, 0x6cU, 0x6dU, 0x6eU, 0x6fU, 0x70U, 0x71U, 0x72U, 0x73U, 0x74U, 0x75U, 0x76U,  /* g...v */\n\t0x77U, 0x78U, 0x79U, 0x7aU, 0x30U, 0x31U, 0x32U, 0x33U, 0x34U, 0x35U, 0x36U, 0x37U, 0x38U, 0x39U, 0x2bU, 0x2fU   /* w.../ */\n};\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\n#if defined(DUK_USE_BASE64_FASTPATH)\n/* Decode table for one byte of input:\n *   -1 = allowed whitespace\n *   -2 = padding\n *   -3 = error\n *    0...63 decoded bytes\n */\nDUK_LOCAL const duk_int8_t duk__base64_dectab_fast[256] = {\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -1, -1, -3, -3, -1, -3, -3,  /* 0x00...0x0f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0x10...0x1f */\n\t-1, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, 62, -3, -3, -3, 63,  /* 0x20...0x2f */\n\t52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -3, -3, -3, -2, -3, -3,  /* 0x30...0x3f */\n\t-3,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,  /* 0x40...0x4f */\n\t15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -3, -3, -3, -3, -3,  /* 0x50...0x5f */\n\t-3, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,  /* 0x60...0x6f */\n\t41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -3, -3, -3, -3, -3,  /* 0x70...0x7f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0x80...0x8f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0x90...0x9f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xa0...0xaf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xb0...0xbf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xc0...0xcf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xd0...0xdf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xe0...0xef */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3   /* 0xf0...0xff */\n};\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\n#if defined(DUK_USE_BASE64_FASTPATH)\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_3(const duk_uint8_t *src, duk_uint8_t *dst) {\n\tduk_uint_t t;\n\n\tt = (duk_uint_t) src[0];\n\tt = (t << 8) + (duk_uint_t) src[1];\n\tt = (t << 8) + (duk_uint_t) src[2];\n\n\tdst[0] = duk__base64_enctab_fast[t >> 18];\n\tdst[1] = duk__base64_enctab_fast[(t >> 12) & 0x3fU];\n\tdst[2] = duk__base64_enctab_fast[(t >> 6) & 0x3fU];\n\tdst[3] = duk__base64_enctab_fast[t & 0x3fU];\n\n#if 0\n\t/* Tested: not faster on x64, most likely due to aliasing between\n\t * output and input index computation.\n\t */\n\t/* aaaaaabb bbbbcccc ccdddddd */\n\tdst[0] = duk__base64_enctab_fast[(src[0] >> 2) & 0x3fU];\n\tdst[1] = duk__base64_enctab_fast[((src[0] << 4) & 0x30U) | ((src[1] >> 4) & 0x0fU)];\n\tdst[2] = duk__base64_enctab_fast[((src[1] << 2) & 0x3fU) | ((src[2] >> 6) & 0x03U)];\n\tdst[3] = duk__base64_enctab_fast[src[2] & 0x3fU];\n#endif\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_2(const duk_uint8_t *src, duk_uint8_t *dst) {\n\tduk_uint_t t;\n\n\tt = (duk_uint_t) src[0];\n\tt = (t << 8) + (duk_uint_t) src[1];\n\tdst[0] = duk__base64_enctab_fast[t >> 10];           /* XXXXXX-- -------- */\n\tdst[1] = duk__base64_enctab_fast[(t >> 4) & 0x3fU];  /* ------XX XXXX---- */\n\tdst[2] = duk__base64_enctab_fast[(t << 2) & 0x3fU];  /* -------- ----XXXX */\n\tdst[3] = DUK_ASC_EQUALS;\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_1(const duk_uint8_t *src, duk_uint8_t *dst) {\n\tduk_uint_t t;\n\n\tt = (duk_uint_t) src[0];\n\tdst[0] = duk__base64_enctab_fast[t >> 2];            /* XXXXXX-- */\n\tdst[1] = duk__base64_enctab_fast[(t << 4) & 0x3fU];  /* ------XX */\n\tdst[2] = DUK_ASC_EQUALS;\n\tdst[3] = DUK_ASC_EQUALS;\n}\n\nDUK_LOCAL void duk__base64_encode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst) {\n\tduk_size_t n;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t *q;\n\n\tn = srclen;\n\tp = src;\n\tq = dst;\n\n\tif (n >= 16U) {\n\t\t/* Fast path, unrolled by 4, allows interleaving.  Process\n\t\t * 12-byte input chunks which encode to 16-char output chunks.\n\t\t * Only enter when at least one block is emitted (avoids div+mul\n\t\t * for short inputs too).\n\t\t */\n\t\tconst duk_uint8_t *p_end_fast;\n\n\t\tp_end_fast = p + ((n / 12U) * 12U);\n\t\tDUK_ASSERT(p_end_fast >= p + 12);\n\t\tdo {\n\t\t\tduk__base64_encode_fast_3(p, q);\n\t\t\tduk__base64_encode_fast_3(p + 3, q + 4);\n\t\t\tduk__base64_encode_fast_3(p + 6, q + 8);\n\t\t\tduk__base64_encode_fast_3(p + 9, q + 12);\n\t\t\tp += 12;\n\t\t\tq += 16;\n\t\t} while (DUK_LIKELY(p != p_end_fast));\n\n\t\tDUK_ASSERT(src + srclen >= p);\n\t\tn = (duk_size_t) (src + srclen - p);\n\t\tDUK_ASSERT(n < 12U);\n\t}\n\n\t/* Remainder. */\n\twhile (n >= 3U) {\n\t\tduk__base64_encode_fast_3(p, q);\n\t\tp += 3;\n\t\tq += 4;\n\t\tn -= 3U;\n\t}\n\tDUK_ASSERT(n == 0U || n == 1U || n == 2U);\n\tif (n == 1U) {\n\t\tduk__base64_encode_fast_1(p, q);\n#if 0  /* Unnecessary. */\n\t\tp += 1;\n\t\tq += 4;\n\t\tn -= 1U;\n#endif\n\t} else if (n == 2U) {\n\t\tduk__base64_encode_fast_2(p, q);\n#if 0  /* Unnecessary. */\n\t\tp += 2;\n\t\tq += 4;\n\t\tn -= 2U;\n#endif\n\t} else {\n\t\tDUK_ASSERT(n == 0U);  /* nothing to do */\n\t\t;\n\t}\n}\n#else  /* DUK_USE_BASE64_FASTPATH */\nDUK_LOCAL void duk__base64_encode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst) {\n\tduk_small_uint_t i, npad;\n\tduk_uint_t t, x, y;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint8_t *q;\n\n\tp = src;\n\tp_end = src + srclen;\n\tq = dst;\n\tnpad = 0U;\n\n\twhile (p < p_end) {\n\t\t/* Read 3 bytes into 't', padded by zero. */\n\t\tt = 0;\n\t\tfor (i = 0; i < 3; i++) {\n\t\t\tt = t << 8;\n\t\t\tif (p < p_end) {\n\t\t\t\tt += (duk_uint_t) (*p++);\n\t\t\t} else {\n\t\t\t\t/* This only happens on the last loop and we're\n\t\t\t\t * guaranteed to exit on the next loop.\n\t\t\t\t */\n\t\t\t\tnpad++;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(npad <= 2U);\n\n\t\t/* Emit 4 encoded characters.  If npad > 0, some of the\n\t\t * chars will be incorrect (zero bits) but we fix up the\n\t\t * padding after the loop.  A straightforward 64-byte\n\t\t * lookup would be faster and cleaner, but this is shorter.\n\t\t */\n\t\tfor (i = 0; i < 4; i++) {\n\t\t\tx = ((t >> 18) & 0x3fU);\n\t\t\tt = t << 6;\n\n\t\t\tif (x <= 51U) {\n\t\t\t\tif (x <= 25) {\n\t\t\t\t\ty = x + DUK_ASC_UC_A;\n\t\t\t\t} else {\n\t\t\t\t\ty = x - 26 + DUK_ASC_LC_A;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (x <= 61U) {\n\t\t\t\t\ty = x - 52 + DUK_ASC_0;\n\t\t\t\t} else if (x == 62) {\n\t\t\t\t\ty = DUK_ASC_PLUS;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(x == 63);\n\t\t\t\t\ty = DUK_ASC_SLASH;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t*q++ = (duk_uint8_t) y;\n\t\t}\n\t}\n\n\t/* Handle padding by rewriting 0-2 bogus characters at the end.\n\t *\n\t *  Missing bytes    npad     base64 example\n\t *    0               0         ####\n\t *    1               1         ###=\n\t *    2               2         ##==\n\t */\n\tDUK_ASSERT(npad <= 2U);\n\twhile (npad > 0U) {\n\t\t*(q - npad) = DUK_ASC_EQUALS;\n\t\tnpad--;\n\t}\n}\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\n#if defined(DUK_USE_BASE64_FASTPATH)\nDUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst, duk_uint8_t **out_dst_final) {\n\tduk_int_t x;\n\tduk_uint_t t;\n\tduk_small_uint_t n_equal;\n\tduk_int8_t step;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint8_t *p_end_safe;\n\tduk_uint8_t *q;\n\n\tDUK_ASSERT(src != NULL);  /* Required by pointer arithmetic below, which fails for NULL. */\n\n\tp = src;\n\tp_end = src + srclen;\n\tp_end_safe = p_end - 8;  /* If 'src <= src_end_safe', safe to read 8 bytes. */\n\tq = dst;\n\n\t/* Alternate between a fast path which processes clean groups with no\n\t * padding or whitespace, and a slow path which processes one arbitrary\n\t * group and then re-enters the fast path.  This handles e.g. base64\n\t * with newlines reasonably well because the majority of a line is in\n\t * the fast path.\n\t */\n\tfor (;;) {\n\t\t/* Fast path, on each loop handle two 4-char input groups.\n\t\t * If both are clean, emit 6 bytes and continue.  If first\n\t\t * is clean, emit 3 bytes and drop out; otherwise emit\n\t\t * nothing and drop out.  This approach could be extended to\n\t\t * more groups per loop, but for inputs with e.g. periodic\n\t\t * newlines (which are common) it might not be an improvement.\n\t\t */\n\t\twhile (DUK_LIKELY(p <= p_end_safe)) {\n\t\t\tduk_int_t t1, t2;\n\n\t\t\t/* The lookup byte is intentionally sign extended to\n\t\t\t * (at least) 32 bits and then ORed.  This ensures\n\t\t\t * that is at least 1 byte is negative, the highest\n\t\t\t * bit of the accumulator will be set at the end and\n\t\t\t * we don't need to check every byte.\n\t\t\t *\n\t\t\t * Read all input bytes first before writing output\n\t\t\t * bytes to minimize aliasing.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast loop: p=%p, p_end_safe=%p, p_end=%p\",\n\t\t\t                     (const void *) p, (const void *) p_end_safe, (const void *) p_end));\n\n\t\t\tt1 = (duk_int_t) duk__base64_dectab_fast[p[0]];\n\t\t\tt1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[1]];\n\t\t\tt1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[2]];\n\t\t\tt1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[3]];\n\n\t\t\tt2 = (duk_int_t) duk__base64_dectab_fast[p[4]];\n\t\t\tt2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[5]];\n\t\t\tt2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[6]];\n\t\t\tt2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[7]];\n\n\t\t\tq[0] = (duk_uint8_t) (((duk_uint_t) t1 >> 16) & 0xffU);\n\t\t\tq[1] = (duk_uint8_t) (((duk_uint_t) t1 >> 8) & 0xffU);\n\t\t\tq[2] = (duk_uint8_t) ((duk_uint_t) t1 & 0xffU);\n\n\t\t\tq[3] = (duk_uint8_t) (((duk_uint_t) t2 >> 16) & 0xffU);\n\t\t\tq[4] = (duk_uint8_t) (((duk_uint_t) t2 >> 8) & 0xffU);\n\t\t\tq[5] = (duk_uint8_t) ((duk_uint_t) t2 & 0xffU);\n\n\t\t\t/* Optimistic check using one branch. */\n\t\t\tif (DUK_LIKELY((t1 | t2) >= 0)) {\n\t\t\t\tp += 8;\n\t\t\t\tq += 6;\n\t\t\t} else if (t1 >= 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast loop first group was clean, second was not, process one slow path group\"));\n\t\t\t\tDUK_ASSERT(t2 < 0);\n\t\t\t\tp += 4;\n\t\t\t\tq += 3;\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast loop first group was not clean, second does not matter, process one slow path group\"));\n\t\t\t\tDUK_ASSERT(t1 < 0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}  /* fast path */\n\n\t\t/* Slow path step 1: try to scan a 4-character encoded group,\n\t\t * end-of-input, or start-of-padding.  We exit with:\n\t\t *   1. n_chars == 4: full group, no padding, no end-of-input.\n\t\t *   2. n_chars < 4: partial group (may also be 0), encountered\n\t\t *      padding or end of input.\n\t\t *\n\t\t * The accumulator is initialized to 1; this allows us to detect\n\t\t * a full group by comparing >= 0x1000000 without an extra\n\t\t * counter variable.\n\t\t */\n\t\tt = 1UL;\n\t\tfor (;;) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slow loop: p=%p, p_end=%p, t=%lu\",\n\t\t\t                     (const void *) p, (const void *) p_end, (unsigned long) t));\n\n\t\t\tif (DUK_LIKELY(p < p_end)) {\n\t\t\t\tx = duk__base64_dectab_fast[*p++];\n\t\t\t\tif (DUK_LIKELY(x >= 0)) {\n\t\t\t\t\tDUK_ASSERT(x >= 0 && x <= 63);\n\t\t\t\t\tt = (t << 6) + (duk_uint_t) x;\n\t\t\t\t\tif (t >= 0x1000000UL) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} else if (x == -1) {\n\t\t\t\t\tcontinue;  /* allowed ascii whitespace */\n\t\t\t\t} else if (x == -2) {\n\t\t\t\t\tp--;\n\t\t\t\t\tbreak;  /* start of padding */\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(x == -3);\n\t\t\t\t\tgoto decode_error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tbreak;  /* end of input */\n\t\t\t}\n\t\t}  /* slow path step 1 */\n\n\t\t/* Complete the padding by simulating pad characters,\n\t\t * regardless of actual input padding chars.\n\t\t */\n\t\tn_equal = 0;\n\t\twhile (t < 0x1000000UL) {\n\t\t\tt = (t << 6) + 0U;\n\t\t\tn_equal++;\n\t\t}\n\n\t\t/* Slow path step 2: deal with full/partial group, padding,\n\t\t * etc.  Note that for num chars in [0,3] we intentionally emit\n\t\t * 3 bytes but don't step forward that much, buffer space is\n\t\t * guaranteed in setup.\n\t\t *\n\t\t *  num chars:\n\t\t *   0      ####   no output (= step 0)\n\t\t *   1      #===   reject, 6 bits of data\n\t\t *   2      ##==   12 bits of data, output 1 byte (= step 1)\n\t\t *   3      ###=   18 bits of data, output 2 bytes (= step 2)\n\t\t *   4      ####   24 bits of data, output 3 bytes (= step 3)\n\t\t */\n\t\tq[0] = (duk_uint8_t) ((t >> 16) & 0xffU);\n\t\tq[1] = (duk_uint8_t) ((t >> 8) & 0xffU);\n\t\tq[2] = (duk_uint8_t) (t & 0xffU);\n\n\t\tDUK_ASSERT(n_equal <= 4);\n\t\tstep = duk__base64_decode_nequal_step[n_equal];\n\t\tif (DUK_UNLIKELY(step < 0)) {\n\t\t\tgoto decode_error;\n\t\t}\n\t\tq += step;\n\n\t\t/* Slow path step 3: read and ignore padding and whitespace\n\t\t * until (a) next non-padding and non-whitespace character\n\t\t * after which we resume the fast path, or (b) end of input.\n\t\t * This allows us to accept missing, partial, full, and extra\n\t\t * padding cases uniformly.  We also support concatenated\n\t\t * base-64 documents because we resume scanning afterwards.\n\t\t *\n\t\t * Note that to support concatenated documents well, the '='\n\t\t * padding found inside the input must also allow for 'extra'\n\t\t * padding.  For example, 'Zm===' decodes to 'f' and has one\n\t\t * extra padding char.  So, 'Zm===Zm' should decode 'ff', even\n\t\t * though the standard break-up would be 'Zm==' + '=Zm' which\n\t\t * doesn't make sense.\n\t\t *\n\t\t * We also accept prepended padding like '==Zm9', because it\n\t\t * is equivalent to an empty document with extra padding ('==')\n\t\t * followed by a valid document.\n\t\t */\n\n\t\tfor (;;) {\n\t\t\tif (DUK_UNLIKELY(p >= p_end)) {\n\t\t\t\tgoto done;\n\t\t\t}\n\t\t\tx = duk__base64_dectab_fast[*p++];\n\t\t\tif (x == -1 || x == -2) {\n\t\t\t\t;  /* padding or whitespace, keep eating */\n\t\t\t} else {\n\t\t\t\tp--;\n\t\t\t\tbreak;  /* backtrack and go back to fast path, even for -1 */\n\t\t\t}\n\t\t}  /* slow path step 3 */\n\t}  /* outer fast+slow path loop */\n\n done:\n\tDUK_DDD(DUK_DDDPRINT(\"done; p=%p, p_end=%p\",\n\t                     (const void *) p, (const void *) p_end));\n\n\tDUK_ASSERT(p == p_end);\n\n\t*out_dst_final = q;\n\treturn 1;\n\n decode_error:\n\treturn 0;\n}\n#else  /* DUK_USE_BASE64_FASTPATH */\nDUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst, duk_uint8_t **out_dst_final) {\n\tduk_uint_t t, x;\n\tduk_int_t y;\n\tduk_int8_t step;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint8_t *q;\n\t/* 0x09, 0x0a, or 0x0d */\n\tduk_uint32_t mask_white = (1U << 9) | (1U << 10) | (1U << 13);\n\n\t/* 't' tracks progress of the decoded group:\n\t *\n\t *  t == 1             no valid chars yet\n\t *  t >= 0x40          1x6 = 6 bits shifted in\n\t *  t >= 0x1000        2x6 = 12 bits shifted in\n\t *  t >= 0x40000       3x6 = 18 bits shifted in\n\t *  t >= 0x1000000     4x6 = 24 bits shifted in\n\t *\n\t * By initializing t=1 there's no need for a separate counter for\n\t * the number of characters found so far.\n\t */\n\tp = src;\n\tp_end = src + srclen;\n\tq = dst;\n\tt = 1UL;\n\n\tfor (;;) {\n\t\tduk_small_uint_t n_equal;\n\n\t\tDUK_ASSERT(t >= 1U);\n\t\tif (p >= p_end) {\n\t\t\t/* End of input: if input exists, treat like\n\t\t\t * start of padding, finish the block, then\n\t\t\t * re-enter here to see we're done.\n\t\t\t */\n\t\t\tif (t == 1U) {\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tgoto simulate_padding;\n\t\t\t}\n\t\t}\n\n\t\tx = *p++;\n\n\t\tif (x >= 0x41U) {\n\t\t\t/* Valid: a-z and A-Z. */\n\t\t\tDUK_ASSERT(x >= 0x41U && x <= 0xffU);\n\t\t\tif (x >= 0x61U && x <= 0x7aU) {\n\t\t\t\ty = (duk_int_t) x - 0x61 + 26;\n\t\t\t} else if (x <= 0x5aU) {\n\t\t\t\ty = (duk_int_t) x - 0x41;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t} else if (x >= 0x30U) {\n\t\t\t/* Valid: 0-9 and =. */\n\t\t\tDUK_ASSERT(x >= 0x30U && x <= 0x40U);\n\t\t\tif (x <= 0x39U) {\n\t\t\t\ty = (duk_int_t) x - 0x30 + 52;\n\t\t\t} else if (x == 0x3dU) {\n\t\t\t\t/* Skip padding and whitespace unless we're in the\n\t\t\t\t * middle of a block.  Otherwise complete group by\n\t\t\t\t * simulating shifting in the correct padding.\n\t\t\t\t */\n\t\t\t\tif (t == 1U) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tgoto simulate_padding;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t} else if (x >= 0x20U) {\n\t\t\t/* Valid: +, /, and 0x20 whitespace. */\n\t\t\tDUK_ASSERT(x >= 0x20U && x <= 0x2fU);\n\t\t\tif (x == 0x2bU) {\n\t\t\t\ty = 62;\n\t\t\t} else if (x == 0x2fU) {\n\t\t\t\ty = 63;\n\t\t\t} else if (x == 0x20U) {\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t} else {\n\t\t\t/* Valid: whitespace. */\n\t\t\tduk_uint32_t m;\n\t\t\tDUK_ASSERT(x < 0x20U);  /* 0x00 to 0x1f */\n\t\t\tm = (1U << x);\n\t\t\tif (mask_white & m) {\n\t\t\t\t/* Allow basic ASCII whitespace. */\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t}\n\n\t\tDUK_ASSERT(y >= 0 && y <= 63);\n\t\tt = (t << 6) + (duk_uint_t) y;\n\t\tif (t < 0x1000000UL) {\n\t\t\tcontinue;\n\t\t}\n\t\t/* fall through; no padding will be added */\n\n\t simulate_padding:\n\t\tn_equal = 0;\n\t\twhile (t < 0x1000000UL) {\n\t\t\tt = (t << 6) + 0U;\n\t\t\tn_equal++;\n\t\t}\n\n\t\t/* Output 3 bytes from 't' and advance as needed. */\n\t\tq[0] = (duk_uint8_t) ((t >> 16) & 0xffU);\n\t\tq[1] = (duk_uint8_t) ((t >> 8) & 0xffU);\n\t\tq[2] = (duk_uint8_t) (t & 0xffU);\n\n\t\tDUK_ASSERT(n_equal <= 4U);\n\t\tstep = duk__base64_decode_nequal_step[n_equal];\n\t\tif (step < 0) {\n\t\t\tgoto decode_error;\n\t\t}\n\t\tq += step;\n\n\t\t/* Re-enter loop.  The actual padding characters are skipped\n\t\t * by the main loop.  This handles cases like missing, partial,\n\t\t * full, and extra padding, and allows parsing of concatenated\n\t\t * documents (with extra padding) like: Zm===Zm.  Also extra\n\t\t * prepended padding is accepted: ===Zm9v.\n\t\t */\n\t\tt = 1U;\n\t}\n\tDUK_ASSERT(t == 1UL);\n\n\t*out_dst_final = q;\n\treturn 1;\n\n decode_error:\n\treturn 0;\n}\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\nDUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *src;\n\tduk_size_t srclen;\n\tduk_size_t dstlen;\n\tduk_uint8_t *dst;\n\tconst char *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tsrc = duk__prep_codec_arg(thr, idx, &srclen);\n\tDUK_ASSERT(src != NULL);\n\n\t/* Compute exact output length.  Computation must not wrap; this\n\t * limit works for 32-bit size_t:\n\t * >>> srclen = 3221225469\n\t * >>> '%x' % ((srclen + 2) / 3 * 4)\n\t * 'fffffffc'\n\t */\n\tif (srclen > 3221225469UL) {\n\t\tgoto type_error;\n\t}\n\tdstlen = (srclen + 2U) / 3U * 4U;\n\tdst = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, dstlen);\n\n\tduk__base64_encode_helper((const duk_uint8_t *) src, srclen, dst);\n\n\tret = duk_buffer_to_string(thr, -1);  /* Safe, result is ASCII. */\n\tduk_replace(thr, idx);\n\treturn ret;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_BASE64_ENCODE_FAILED);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *src;\n\tduk_size_t srclen;\n\tduk_size_t dstlen;\n\tduk_uint8_t *dst;\n\tduk_uint8_t *dst_final;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tsrc = duk__prep_codec_arg(thr, idx, &srclen);\n\tDUK_ASSERT(src != NULL);\n\n\t/* Round up and add safety margin.  Avoid addition before division to\n\t * avoid possibility of wrapping.  Margin includes +3 for rounding up,\n\t * and +3 for one extra group: the decoder may emit and then backtrack\n\t * a full group (3 bytes) from zero-sized input for technical reasons.\n\t * Similarly, 'xx' may ecause 1+3 = bytes to be emitted and then\n\t * backtracked.\n\t */\n\tdstlen = (srclen / 4) * 3 + 6;  /* upper limit, assuming no whitespace etc */\n\tdst = (duk_uint8_t *) duk_push_dynamic_buffer(thr, dstlen);\n\t/* Note: for dstlen=0, dst may be NULL */\n\n\tif (!duk__base64_decode_helper((const duk_uint8_t *) src, srclen, dst, &dst_final)) {\n\t\tgoto type_error;\n\t}\n\n\t/* XXX: convert to fixed buffer? */\n\t(void) duk_resize_buffer(thr, -1, (duk_size_t) (dst_final - dst));\n\tduk_replace(thr, idx);\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_BASE64_DECODE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n#else  /* DUK_USE_BASE64_SUPPORT */\nDUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_BASE64_SUPPORT */\n\n/*\n *  Hex\n */\n\n#if defined(DUK_USE_HEX_SUPPORT)\nDUK_EXTERNAL const char *duk_hex_encode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *inp;\n\tduk_size_t len;\n\tduk_size_t i;\n\tduk_uint8_t *buf;\n\tconst char *ret;\n#if defined(DUK_USE_HEX_FASTPATH)\n\tduk_size_t len_safe;\n\tduk_uint16_t *p16;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tinp = duk__prep_codec_arg(thr, idx, &len);\n\tDUK_ASSERT(inp != NULL);\n\n\t/* Fixed buffer, no zeroing because we'll fill all the data. */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len * 2);\n\tDUK_ASSERT(buf != NULL);\n\n#if defined(DUK_USE_HEX_FASTPATH)\n\tDUK_ASSERT((((duk_size_t) buf) & 0x01U) == 0);   /* pointer is aligned, guaranteed for fixed buffer */\n\tp16 = (duk_uint16_t *) (void *) buf;\n\tlen_safe = len & ~0x03U;\n\tfor (i = 0; i < len_safe; i += 4) {\n\t\tp16[0] = duk_hex_enctab[inp[i]];\n\t\tp16[1] = duk_hex_enctab[inp[i + 1]];\n\t\tp16[2] = duk_hex_enctab[inp[i + 2]];\n\t\tp16[3] = duk_hex_enctab[inp[i + 3]];\n\t\tp16 += 4;\n\t}\n\tfor (; i < len; i++) {\n\t\t*p16++ = duk_hex_enctab[inp[i]];\n\t}\n#else  /* DUK_USE_HEX_FASTPATH */\n\tfor (i = 0; i < len; i++) {\n\t\tduk_small_uint_t t;\n\t\tt = (duk_small_uint_t) inp[i];\n\t\tbuf[i*2 + 0] = duk_lc_digits[t >> 4];\n\t\tbuf[i*2 + 1] = duk_lc_digits[t & 0x0f];\n\t}\n#endif  /* DUK_USE_HEX_FASTPATH */\n\n\t/* XXX: Using a string return value forces a string intern which is\n\t * not always necessary.  As a rough performance measure, hex encode\n\t * time for tests/perf/test-hex-encode.js dropped from ~35s to ~15s\n\t * without string coercion.  Change to returning a buffer and let the\n\t * caller coerce to string if necessary?\n\t */\n\n\tret = duk_buffer_to_string(thr, -1);  /* Safe, result is ASCII. */\n\tduk_replace(thr, idx);\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *inp;\n\tduk_size_t len;\n\tduk_size_t i;\n\tduk_int_t t;\n\tduk_uint8_t *buf;\n#if defined(DUK_USE_HEX_FASTPATH)\n\tduk_int_t chk;\n\tduk_uint8_t *p;\n\tduk_size_t len_safe;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tinp = duk__prep_codec_arg(thr, idx, &len);\n\tDUK_ASSERT(inp != NULL);\n\n\tif (len & 0x01) {\n\t\tgoto type_error;\n\t}\n\n\t/* Fixed buffer, no zeroing because we'll fill all the data. */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len / 2);\n\tDUK_ASSERT(buf != NULL);\n\n#if defined(DUK_USE_HEX_FASTPATH)\n\tp = buf;\n\tlen_safe = len & ~0x07U;\n\tfor (i = 0; i < len_safe; i += 8) {\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 1]]);\n\t\tchk = t;\n\t\tp[0] = (duk_uint8_t) t;\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 2]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 3]]);\n\t\tchk |= t;\n\t\tp[1] = (duk_uint8_t) t;\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 4]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 5]]);\n\t\tchk |= t;\n\t\tp[2] = (duk_uint8_t) t;\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 6]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 7]]);\n\t\tchk |= t;\n\t\tp[3] = (duk_uint8_t) t;\n\t\tp += 4;\n\n\t\t/* Check if any lookup above had a negative result. */\n\t\tif (DUK_UNLIKELY(chk < 0)) {\n\t\t\tgoto type_error;\n\t\t}\n\t}\n\tfor (; i < len; i += 2) {\n\t\t/* First cast to duk_int_t to sign extend, second cast to\n\t\t * duk_uint_t to avoid signed left shift, and final cast to\n\t\t * duk_int_t result type.\n\t\t */\n\t\tt = (duk_int_t) ((((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i]]) << 4U) |\n\t\t                 ((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i + 1]]));\n\t\tif (DUK_UNLIKELY(t < 0)) {\n\t\t\tgoto type_error;\n\t\t}\n\t\t*p++ = (duk_uint8_t) t;\n\t}\n#else  /* DUK_USE_HEX_FASTPATH */\n\tfor (i = 0; i < len; i += 2) {\n\t\t/* For invalid characters the value -1 gets extended to\n\t\t * at least 16 bits.  If either nybble is invalid, the\n\t\t * resulting 't' will be < 0.\n\t\t */\n\t\tt = (duk_int_t) ((((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i]]) << 4U) |\n\t\t                 ((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i + 1]]));\n\t\tif (DUK_UNLIKELY(t < 0)) {\n\t\t\tgoto type_error;\n\t\t}\n\t\tbuf[i >> 1] = (duk_uint8_t) t;\n\t}\n#endif  /* DUK_USE_HEX_FASTPATH */\n\n\tduk_replace(thr, idx);\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_HEX_DECODE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n#else  /* DUK_USE_HEX_SUPPORT */\nDUK_EXTERNAL const char *duk_hex_encode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\nDUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_HEX_SUPPORT */\n\n/*\n *  JSON\n */\n\n#if defined(DUK_USE_JSON_SUPPORT)\nDUK_EXTERNAL const char *duk_json_encode(duk_hthread *thr, duk_idx_t idx) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t top_at_entry;\n#endif\n\tconst char *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\ttop_at_entry = duk_get_top(thr);\n#endif\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tduk_bi_json_stringify_helper(thr,\n\t                             idx /*idx_value*/,\n\t                             DUK_INVALID_INDEX /*idx_replacer*/,\n\t                             DUK_INVALID_INDEX /*idx_space*/,\n\t                             0 /*flags*/);\n\tDUK_ASSERT(duk_is_string(thr, -1));\n\tduk_replace(thr, idx);\n\tret = duk_get_string(thr, idx);\n\n\tDUK_ASSERT(duk_get_top(thr) == top_at_entry);\n\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_json_decode(duk_hthread *thr, duk_idx_t idx) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t top_at_entry;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\ttop_at_entry = duk_get_top(thr);\n#endif\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tduk_bi_json_parse_helper(thr,\n\t                         idx /*idx_value*/,\n\t                         DUK_INVALID_INDEX /*idx_reviver*/,\n\t                         0 /*flags*/);\n\tduk_replace(thr, idx);\n\n\tDUK_ASSERT(duk_get_top(thr) == top_at_entry);\n}\n#else  /* DUK_USE_JSON_SUPPORT */\nDUK_EXTERNAL const char *duk_json_encode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_EXTERNAL void duk_json_decode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_JSON_SUPPORT */\n#line 1 \"duk_api_compile.c\"\n/*\n *  Compilation and evaluation\n */\n\n/* #include duk_internal.h -> already included */\n\ntypedef struct duk__compile_raw_args duk__compile_raw_args;\nstruct duk__compile_raw_args {\n\tduk_size_t src_length;  /* should be first on 64-bit platforms */\n\tconst duk_uint8_t *src_buffer;\n\tduk_uint_t flags;\n};\n\n/* Eval is just a wrapper now. */\nDUK_EXTERNAL duk_int_t duk_eval_raw(duk_hthread *thr, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: strictness is *not* inherited from the current Duktape/C.\n\t * This would be confusing because the current strictness state\n\t * depends on whether we're running inside a Duktape/C activation\n\t * (= strict mode) or outside of any activation (= non-strict mode).\n\t * See tests/api/test-eval-strictness.c for more discussion.\n\t */\n\n\t/* [ ... source? filename? ] (depends on flags) */\n\n\trc = duk_compile_raw(thr, src_buffer, src_length, flags | DUK_COMPILE_EVAL);  /* may be safe, or non-safe depending on flags */\n\n\t/* [ ... closure/error ] */\n\n\tif (rc != DUK_EXEC_SUCCESS) {\n\t\trc = DUK_EXEC_ERROR;\n\t\tgoto got_rc;\n\t}\n\n\tduk_push_global_object(thr);  /* explicit 'this' binding, see GH-164 */\n\n\tif (flags & DUK_COMPILE_SAFE) {\n\t\trc = duk_pcall_method(thr, 0);\n\t} else {\n\t\tduk_call_method(thr, 0);\n\t\trc = DUK_EXEC_SUCCESS;\n\t}\n\n\t/* [ ... result/error ] */\n\n got_rc:\n\tif (flags & DUK_COMPILE_NORESULT) {\n\t\tduk_pop(thr);\n\t}\n\n\treturn rc;\n}\n\n/* Helper which can be called both directly and with duk_safe_call(). */\nDUK_LOCAL duk_ret_t duk__do_compile(duk_hthread *thr, void *udata) {\n\tduk__compile_raw_args *comp_args;\n\tduk_uint_t flags;\n\tduk_hcompfunc *h_templ;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\t/* Note: strictness is not inherited from the current Duktape/C\n\t * context.  Otherwise it would not be possible to compile\n\t * non-strict code inside a Duktape/C activation (which is\n\t * always strict now).  See tests/api/test-eval-strictness.c\n\t * for discussion.\n\t */\n\n\t/* [ ... source? filename? ] (depends on flags) */\n\n\tcomp_args = (duk__compile_raw_args *) udata;\n\tflags = comp_args->flags;\n\n\tif (flags & DUK_COMPILE_NOFILENAME) {\n\t\t/* Automatic filename: 'eval' or 'input'. */\n\t\tduk_push_hstring_stridx(thr, (flags & DUK_COMPILE_EVAL) ? DUK_STRIDX_EVAL : DUK_STRIDX_INPUT);\n\t}\n\n\t/* [ ... source? filename ] */\n\n\tif (!comp_args->src_buffer) {\n\t\tduk_hstring *h_sourcecode;\n\n\t\th_sourcecode = duk_get_hstring(thr, -2);\n\t\tif ((flags & DUK_COMPILE_NOSOURCE) ||  /* args incorrect */\n\t\t    (h_sourcecode == NULL)) {          /* e.g. duk_push_string_file_raw() pushed undefined */\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_NO_SOURCECODE);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tDUK_ASSERT(h_sourcecode != NULL);\n\t\tcomp_args->src_buffer = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_sourcecode);\n\t\tcomp_args->src_length = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sourcecode);\n\t}\n\tDUK_ASSERT(comp_args->src_buffer != NULL);\n\n\tif (flags & DUK_COMPILE_FUNCTION) {\n\t\tflags |= DUK_COMPILE_EVAL | DUK_COMPILE_FUNCEXPR;\n\t}\n\n\t/* [ ... source? filename ] */\n\n\tduk_js_compile(thr, comp_args->src_buffer, comp_args->src_length, flags);\n\n\t/* [ ... source? func_template ] */\n\n\tif (flags & DUK_COMPILE_NOSOURCE) {\n\t\t;\n\t} else {\n\t\tduk_remove_m2(thr);\n\t}\n\n\t/* [ ... func_template ] */\n\n\th_templ = (duk_hcompfunc *) duk_known_hobject(thr, -1);\n\tduk_js_push_closure(thr,\n\t                   h_templ,\n\t                   thr->builtins[DUK_BIDX_GLOBAL_ENV],\n\t                   thr->builtins[DUK_BIDX_GLOBAL_ENV],\n\t                   1 /*add_auto_proto*/);\n\tduk_remove_m2(thr);   /* -> [ ... closure ] */\n\n\t/* [ ... closure ] */\n\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_compile_raw(duk_hthread *thr, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) {\n\tduk__compile_raw_args comp_args_alloc;\n\tduk__compile_raw_args *comp_args = &comp_args_alloc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif ((flags & DUK_COMPILE_STRLEN) && (src_buffer != NULL)) {\n\t\t/* String length is computed here to avoid multiple evaluation\n\t\t * of a macro argument in the calling side.\n\t\t */\n\t\tsrc_length = DUK_STRLEN(src_buffer);\n\t}\n\n\tcomp_args->src_buffer = (const duk_uint8_t *) src_buffer;\n\tcomp_args->src_length = src_length;\n\tcomp_args->flags = flags;\n\n\t/* [ ... source? filename? ] (depends on flags) */\n\n\tif (flags & DUK_COMPILE_SAFE) {\n\t\tduk_int_t rc;\n\t\tduk_int_t nargs;\n\t\tduk_int_t nrets = 1;\n\n\t\t/* Arguments can be: [ source? filename? &comp_args] so that\n\t\t * nargs is 1 to 3.  Call site encodes the correct nargs count\n\t\t * directly into flags.\n\t\t */\n\t\tnargs = flags & 0x07;\n\t\tDUK_ASSERT(nargs == ((flags & DUK_COMPILE_NOSOURCE) ? 0 : 1) +\n\t\t                    ((flags & DUK_COMPILE_NOFILENAME) ? 0 : 1));\n\t\trc = duk_safe_call(thr, duk__do_compile, (void *) comp_args, nargs, nrets);\n\n\t\t/* [ ... closure ] */\n\t\treturn rc;\n\t}\n\n\t(void) duk__do_compile(thr, (void *) comp_args);\n\n\t/* [ ... closure ] */\n\treturn DUK_EXEC_SUCCESS;\n}\n#line 1 \"duk_api_debug.c\"\n/*\n *  Debugging related API calls\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_JSON_SUPPORT)\nDUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr) {\n\tduk_idx_t idx;\n\tduk_idx_t top;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* We don't duk_require_stack() here now, but rely on the caller having\n\t * enough space.\n\t */\n\n\ttop = duk_get_top(thr);\n\tduk_push_bare_array(thr);\n\tfor (idx = 0; idx < top; idx++) {\n\t\tduk_dup(thr, idx);\n\t\tduk_put_prop_index(thr, -2, (duk_uarridx_t) idx);\n\t}\n\n\t/* XXX: conversion errors should not propagate outwards.\n\t * Perhaps values need to be coerced individually?\n\t */\n\tduk_bi_json_stringify_helper(thr,\n\t                             duk_get_top_index(thr),  /*idx_value*/\n\t                             DUK_INVALID_INDEX,  /*idx_replacer*/\n\t                             DUK_INVALID_INDEX,  /*idx_space*/\n\t                             DUK_JSON_FLAG_EXT_CUSTOM |\n\t                             DUK_JSON_FLAG_ASCII_ONLY |\n\t                             DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/);\n\n\tduk_push_sprintf(thr, \"ctx: top=%ld, stack=%s\", (long) top, (const char *) duk_safe_to_string(thr, -1));\n\tduk_replace(thr, -3);  /* [ ... arr jsonx(arr) res ] -> [ ... res jsonx(arr) ] */\n\tduk_pop(thr);\n\tDUK_ASSERT(duk_is_string(thr, -1));\n}\n#else  /* DUK_USE_JSON_SUPPORT */\nDUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_JSON_SUPPORT */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\nDUK_EXTERNAL void duk_debugger_attach(duk_hthread *thr,\n                                      duk_debug_read_function read_cb,\n                                      duk_debug_write_function write_cb,\n                                      duk_debug_peek_function peek_cb,\n                                      duk_debug_read_flush_function read_flush_cb,\n                                      duk_debug_write_flush_function write_flush_cb,\n                                      duk_debug_request_function request_cb,\n                                      duk_debug_detached_function detached_cb,\n                                      void *udata) {\n\tduk_heap *heap;\n\tconst char *str;\n\tduk_size_t len;\n\n\t/* XXX: should there be an error or an automatic detach if\n\t * already attached?\n\t */\n\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_attach()\"));\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(read_cb != NULL);\n\tDUK_ASSERT(write_cb != NULL);\n\t/* Other callbacks are optional. */\n\n\theap = thr->heap;\n\theap->dbg_read_cb = read_cb;\n\theap->dbg_write_cb = write_cb;\n\theap->dbg_peek_cb = peek_cb;\n\theap->dbg_read_flush_cb = read_flush_cb;\n\theap->dbg_write_flush_cb = write_flush_cb;\n\theap->dbg_request_cb = request_cb;\n\theap->dbg_detached_cb = detached_cb;\n\theap->dbg_udata = udata;\n\theap->dbg_have_next_byte = 0;\n\n\t/* Start in paused state. */\n\theap->dbg_processing = 0;\n\theap->dbg_state_dirty = 0;\n\theap->dbg_force_restart = 0;\n\theap->dbg_pause_flags = 0;\n\theap->dbg_pause_act = NULL;\n\theap->dbg_pause_startline = 0;\n\theap->dbg_exec_counter = 0;\n\theap->dbg_last_counter = 0;\n\theap->dbg_last_time = 0.0;\n\tduk_debug_set_paused(heap);  /* XXX: overlap with fields above */\n\n\t/* Send version identification and flush right afterwards.  Note that\n\t * we must write raw, unframed bytes here.\n\t */\n\tduk_push_sprintf(thr, \"%ld %ld %s %s\\n\",\n\t                 (long) DUK_DEBUG_PROTOCOL_VERSION,\n\t                 (long) DUK_VERSION,\n\t                 (const char *) DUK_GIT_DESCRIBE,\n\t                 (const char *) DUK_USE_TARGET_INFO);\n\tstr = duk_get_lstring(thr, -1, &len);\n\tDUK_ASSERT(str != NULL);\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) str, len);\n\tduk_debug_write_flush(thr);\n\tduk_pop(thr);\n}\n\nDUK_EXTERNAL void duk_debugger_detach(duk_hthread *thr) {\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_detach()\"));\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\t/* Can be called multiple times with no harm. */\n\tduk_debug_do_detach(thr->heap);\n}\n\nDUK_EXTERNAL void duk_debugger_cooperate(duk_hthread *thr) {\n\tduk_bool_t processed_messages;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tif (!duk_debug_is_attached(thr->heap)) {\n\t\treturn;\n\t}\n\tif (thr->callstack_curr != NULL || thr->heap->dbg_processing) {\n\t\t/* Calling duk_debugger_cooperate() while Duktape is being\n\t\t * called into is not supported.  This is not a 100% check\n\t\t * but prevents any damage in most cases.\n\t\t */\n\t\treturn;\n\t}\n\n\tprocessed_messages = duk_debug_process_messages(thr, 1 /*no_block*/);\n\tDUK_UNREF(processed_messages);\n}\n\nDUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_hthread *thr, duk_idx_t nvalues) {\n\tduk_idx_t top;\n\tduk_idx_t idx;\n\tduk_bool_t ret = 0;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_notify() with nvalues=%ld\", (long) nvalues));\n\n\ttop = duk_get_top(thr);\n\tif (top < nvalues) {\n\t\tDUK_ERROR_RANGE(thr, \"not enough stack values for notify\");\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tduk_debug_write_notify(thr, DUK_DBG_CMD_APPNOTIFY);\n\t\tfor (idx = top - nvalues; idx < top; idx++) {\n\t\t\tduk_tval *tv = DUK_GET_TVAL_POSIDX(thr, idx);\n\t\t\tduk_debug_write_tval(thr, tv);\n\t\t}\n\t\tduk_debug_write_eom(thr);\n\n\t\t/* Return non-zero (true) if we have a good reason to believe\n\t\t * the notify was delivered; if we're still attached at least\n\t\t * a transport error was not indicated by the transport write\n\t\t * callback.  This is not a 100% guarantee of course.\n\t\t */\n\t\tif (duk_debug_is_attached(thr->heap)) {\n\t\t\tret = 1;\n\t\t}\n\t}\n\tduk_pop_n(thr, nvalues);\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_debugger_pause(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_pause()\"));\n\n\t/* Treat like a debugger statement: ignore when not attached. */\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tif (duk_debug_is_paused(thr->heap)) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_debugger_pause() called when already paused; ignoring\"));\n\t\t} else {\n\t\t\tduk_debug_set_paused(thr->heap);\n\n\t\t\t/* Pause on the next opcode executed.  This is always safe to do even\n\t\t\t * inside the debugger message loop: the interrupt counter will be reset\n\t\t\t * to its proper value when the message loop exits.\n\t\t\t */\n\t\t\tthr->interrupt_init = 1;\n\t\t\tthr->interrupt_counter = 0;\n\t\t}\n\t}\n}\n\n#else  /* DUK_USE_DEBUGGER_SUPPORT */\n\nDUK_EXTERNAL void duk_debugger_attach(duk_hthread *thr,\n                                      duk_debug_read_function read_cb,\n                                      duk_debug_write_function write_cb,\n                                      duk_debug_peek_function peek_cb,\n                                      duk_debug_read_flush_function read_flush_cb,\n                                      duk_debug_write_flush_function write_flush_cb,\n                                      duk_debug_request_function request_cb,\n                                      duk_debug_detached_function detached_cb,\n                                      void *udata) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(read_cb);\n\tDUK_UNREF(write_cb);\n\tDUK_UNREF(peek_cb);\n\tDUK_UNREF(read_flush_cb);\n\tDUK_UNREF(write_flush_cb);\n\tDUK_UNREF(request_cb);\n\tDUK_UNREF(detached_cb);\n\tDUK_UNREF(udata);\n\tDUK_ERROR_TYPE(thr, \"no debugger support\");\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_debugger_detach(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_TYPE(thr, \"no debugger support\");\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_debugger_cooperate(duk_hthread *thr) {\n\t/* nop */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n}\n\nDUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_hthread *thr, duk_idx_t nvalues) {\n\tduk_idx_t top;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttop = duk_get_top(thr);\n\tif (top < nvalues) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* No debugger support, just pop values. */\n\tduk_pop_n(thr, nvalues);\n\treturn 0;\n}\n\nDUK_EXTERNAL void duk_debugger_pause(duk_hthread *thr) {\n\t/* Treat like debugger statement: nop */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n}\n\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n#line 1 \"duk_api_heap.c\"\n/*\n *  Heap creation and destruction\n */\n\n/* #include duk_internal.h -> already included */\n\ntypedef struct duk_internal_thread_state duk_internal_thread_state;\n\nstruct duk_internal_thread_state {\n\tduk_ljstate lj;\n\tduk_bool_t creating_error;\n\tduk_hthread *curr_thread;\n\tduk_int_t call_recursion_depth;\n};\n\nDUK_EXTERNAL duk_hthread *duk_create_heap(duk_alloc_function alloc_func,\n                                          duk_realloc_function realloc_func,\n                                          duk_free_function free_func,\n                                          void *heap_udata,\n                                          duk_fatal_function fatal_handler) {\n\tduk_heap *heap = NULL;\n\tduk_hthread *thr;\n\n\t/* Assume that either all memory funcs are NULL or non-NULL, mixed\n\t * cases will now be unsafe.\n\t */\n\n\t/* XXX: just assert non-NULL values here and make caller arguments\n\t * do the defaulting to the default implementations (smaller code)?\n\t */\n\n\tif (!alloc_func) {\n\t\tDUK_ASSERT(realloc_func == NULL);\n\t\tDUK_ASSERT(free_func == NULL);\n#if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS)\n\t\talloc_func = duk_default_alloc_function;\n\t\trealloc_func = duk_default_realloc_function;\n\t\tfree_func = duk_default_free_function;\n#else\n\t\tDUK_D(DUK_DPRINT(\"no allocation functions given and no default providers\"));\n\t\treturn NULL;\n#endif\n\t} else {\n\t\tDUK_ASSERT(realloc_func != NULL);\n\t\tDUK_ASSERT(free_func != NULL);\n\t}\n\n\tif (!fatal_handler) {\n\t\tfatal_handler = duk_default_fatal_handler;\n\t}\n\n\tDUK_ASSERT(alloc_func != NULL);\n\tDUK_ASSERT(realloc_func != NULL);\n\tDUK_ASSERT(free_func != NULL);\n\tDUK_ASSERT(fatal_handler != NULL);\n\n\theap = duk_heap_alloc(alloc_func, realloc_func, free_func, heap_udata, fatal_handler);\n\tif (!heap) {\n\t\treturn NULL;\n\t}\n\tthr = heap->heap_thread;\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\treturn thr;\n}\n\nDUK_EXTERNAL void duk_destroy_heap(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tif (!thr) {\n\t\treturn;\n\t}\n\tDUK_ASSERT_API_ENTRY(thr);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tduk_heap_free(heap);\n}\n\nDUK_EXTERNAL void duk_suspend(duk_hthread *thr, duk_thread_state *state) {\n\tduk_internal_thread_state *snapshot = (duk_internal_thread_state *) (void *) state;\n\tduk_heap *heap;\n\tduk_ljstate *lj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(state != NULL);  /* unvalidated */\n\n\t/* Currently not supported when called from within a finalizer.\n\t * If that is done, the finalizer will remain running indefinitely,\n\t * preventing other finalizers from executing.  The assert is a bit\n\t * wider, checking that it would be OK to run pending finalizers.\n\t */\n\tDUK_ASSERT(thr->heap->pf_prevent_count == 0);\n\n\t/* Currently not supported to duk_suspend() from an errCreate()\n\t * call.\n\t */\n\tDUK_ASSERT(thr->heap->creating_error == 0);\n\n\theap = thr->heap;\n\tlj = &heap->lj;\n\n\tduk_push_tval(thr, &lj->value1);\n\tduk_push_tval(thr, &lj->value2);\n\n\t/* XXX: creating_error == 0 is asserted above, so no need to store. */\n\tduk_memcpy((void *) &snapshot->lj, (const void *) lj, sizeof(duk_ljstate));\n\tsnapshot->creating_error = heap->creating_error;\n\tsnapshot->curr_thread = heap->curr_thread;\n\tsnapshot->call_recursion_depth = heap->call_recursion_depth;\n\n\tlj->jmpbuf_ptr = NULL;\n\tlj->type = DUK_LJ_TYPE_UNKNOWN;\n\tDUK_TVAL_SET_UNDEFINED(&lj->value1);\n\tDUK_TVAL_SET_UNDEFINED(&lj->value2);\n\theap->creating_error = 0;\n\theap->curr_thread = NULL;\n\theap->call_recursion_depth = 0;\n}\n\nDUK_EXTERNAL void duk_resume(duk_hthread *thr, const duk_thread_state *state) {\n\tconst duk_internal_thread_state *snapshot = (const duk_internal_thread_state *) (const void *) state;\n\tduk_heap *heap;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(state != NULL);  /* unvalidated */\n\n\t/* Shouldn't be necessary if duk_suspend() is called before\n\t * duk_resume(), but assert in case API sequence is incorrect.\n\t */\n\tDUK_ASSERT(thr->heap->pf_prevent_count == 0);\n\tDUK_ASSERT(thr->heap->creating_error == 0);\n\n\theap = thr->heap;\n\n\tduk_memcpy((void *) &heap->lj, (const void *) &snapshot->lj, sizeof(duk_ljstate));\n\theap->creating_error = snapshot->creating_error;\n\theap->curr_thread = snapshot->curr_thread;\n\theap->call_recursion_depth = snapshot->call_recursion_depth;\n\n\tduk_pop_2(thr);\n}\n\n/* XXX: better place for this */\nDUK_EXTERNAL void duk_set_global_object(duk_hthread *thr) {\n\tduk_hobject *h_glob;\n\tduk_hobject *h_prev_glob;\n\tduk_hobjenv *h_env;\n\tduk_hobject *h_prev_env;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_D(DUK_DPRINT(\"replace global object with: %!T\", duk_get_tval(thr, -1)));\n\n\th_glob = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(h_glob != NULL);\n\n\t/*\n\t *  Replace global object.\n\t */\n\n\th_prev_glob = thr->builtins[DUK_BIDX_GLOBAL];\n\tDUK_UNREF(h_prev_glob);\n\tthr->builtins[DUK_BIDX_GLOBAL] = h_glob;\n\tDUK_HOBJECT_INCREF(thr, h_glob);\n\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, h_prev_glob);  /* side effects, in theory (referenced by global env) */\n\n\t/*\n\t *  Replace lexical environment for global scope\n\t *\n\t *  Create a new object environment for the global lexical scope.\n\t *  We can't just reset the _Target property of the current one,\n\t *  because the lexical scope is shared by other threads with the\n\t *  same (initial) built-ins.\n\t */\n\n\th_env = duk_hobjenv_alloc(thr,\n\t                          DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                          DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\tDUK_ASSERT(h_env != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_env) == NULL);\n\n\tDUK_ASSERT(h_env->target == NULL);\n\tDUK_ASSERT(h_glob != NULL);\n\th_env->target = h_glob;\n\tDUK_HOBJECT_INCREF(thr, h_glob);\n\tDUK_ASSERT(h_env->has_this == 0);\n\n\t/* [ ... new_glob ] */\n\n\th_prev_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\tthr->builtins[DUK_BIDX_GLOBAL_ENV] = (duk_hobject *) h_env;\n\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) h_env);\n\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, h_prev_env);  /* side effects */\n\tDUK_UNREF(h_env);  /* without refcounts */\n\tDUK_UNREF(h_prev_env);\n\n\t/* [ ... new_glob ] */\n\n\tduk_pop(thr);\n\n\t/* [ ... ] */\n}\n#line 1 \"duk_api_inspect.c\"\n/*\n *  Inspection\n */\n\n/* #include duk_internal.h -> already included */\n\n/* For footprint efficient multiple value setting: arrays are much better than\n * varargs, format string with parsing is often better than string pointer arrays.\n */\nDUK_LOCAL void duk__inspect_multiple_uint(duk_hthread *thr, const char *fmt, duk_int_t *vals) {\n\tduk_int_t val;\n\tconst char *p;\n\tconst char *p_curr;\n\tduk_size_t len;\n\n\tfor (p = fmt;;) {\n\t\tlen = DUK_STRLEN(p);\n\t\tp_curr = p;\n\t\tp += len + 1;\n\t\tif (len == 0) {\n\t\t\t/* Double NUL (= empty key) terminates. */\n\t\t\tbreak;\n\t\t}\n\t\tval = *vals++;\n\t\tif (val >= 0) {\n\t\t\t/* Negative values are markers to skip key. */\n\t\t\tduk_push_string(thr, p_curr);\n\t\t\tduk_push_int(thr, val);\n\t\t\tduk_put_prop(thr, -3);\n\t\t}\n\t}\n}\n\n/* Raw helper to extract internal information / statistics about a value.\n * The return value is an object with properties that are version specific.\n * The properties must not expose anything that would lead to security\n * issues (e.g. exposing compiled function 'data' buffer might be an issue).\n * Currently only counts and sizes and such are given so there shouldn't\n * be security implications.\n */\n\n#define DUK__IDX_TYPE     0\n#define DUK__IDX_ITAG     1\n#define DUK__IDX_REFC     2\n#define DUK__IDX_HBYTES   3\n#define DUK__IDX_CLASS    4\n#define DUK__IDX_PBYTES   5\n#define DUK__IDX_ESIZE    6\n#define DUK__IDX_ENEXT    7\n#define DUK__IDX_ASIZE    8\n#define DUK__IDX_HSIZE    9\n#define DUK__IDX_BCBYTES  10\n#define DUK__IDX_DBYTES   11\n#define DUK__IDX_TSTATE   12\n#define DUK__IDX_VARIANT  13\n\nDUK_EXTERNAL void duk_inspect_value(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_heaphdr *h;\n\t/* The temporary values should be in an array rather than individual\n\t * variables which (in practice) ensures that the compiler won't map\n\t * them to registers and emit a lot of unnecessary shuffling code.\n\t */\n\tduk_int_t vals[14];\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Assume two's complement and set everything to -1. */\n\tduk_memset((void *) &vals, (int) 0xff, sizeof(vals));\n\tDUK_ASSERT(vals[DUK__IDX_TYPE] == -1);  /* spot check one */\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\th = (DUK_TVAL_IS_HEAP_ALLOCATED(tv) ? DUK_TVAL_GET_HEAPHDR(tv) : NULL);\n\n\tvals[DUK__IDX_TYPE] = duk_get_type_tval(tv);\n\tvals[DUK__IDX_ITAG] = (duk_int_t) DUK_TVAL_GET_TAG(tv);\n\n\tduk_push_bare_object(thr);  /* Invalidates 'tv'. */\n\ttv = NULL;\n\n\tif (h == NULL) {\n\t\tgoto finish;\n\t}\n\tduk_push_pointer(thr, (void *) h);\n\tduk_put_prop_literal(thr, -2, \"hptr\");\n\n#if 0\n\t/* Covers a lot of information, e.g. buffer and string variants. */\n\tduk_push_uint(thr, (duk_uint_t) DUK_HEAPHDR_GET_FLAGS(h));\n\tduk_put_prop_literal(thr, -2, \"hflags\");\n#endif\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tvals[DUK__IDX_REFC] = (duk_int_t) DUK_HEAPHDR_GET_REFCOUNT(h);\n#endif\n\tvals[DUK__IDX_VARIANT] = 0;\n\n\t/* Heaphdr size and additional allocation size, followed by\n\t * type specific stuff (with varying value count).\n\t */\n\tswitch ((duk_small_int_t) DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h_str = (duk_hstring *) h;\n\t\tvals[DUK__IDX_HBYTES] = (duk_int_t) (sizeof(duk_hstring) + DUK_HSTRING_GET_BYTELEN(h_str) + 1);\n#if defined(DUK_USE_HSTRING_EXTDATA)\n\t\tif (DUK_HSTRING_HAS_EXTDATA(h_str)) {\n\t\t\tvals[DUK__IDX_VARIANT] = 1;\n\t\t}\n#endif\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h_obj = (duk_hobject *) h;\n\n\t\t/* XXX: variants here are maybe pointless; class is enough? */\n\t\tif (DUK_HOBJECT_IS_ARRAY(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_harray);\n\t\t} else if (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hcompfunc);\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hnatfunc);\n\t\t} else if (DUK_HOBJECT_IS_THREAD(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hthread);\n\t\t\tvals[DUK__IDX_TSTATE] = ((duk_hthread *) h_obj)->state;\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hbufobj);\n\t\t\t/* XXX: some size information */\n#endif\n\t\t} else {\n\t\t\tvals[DUK__IDX_HBYTES] = (duk_small_uint_t) sizeof(duk_hobject);\n\t\t}\n\n\t\tvals[DUK__IDX_CLASS] = (duk_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h_obj);\n\t\tvals[DUK__IDX_PBYTES] = (duk_int_t) DUK_HOBJECT_P_ALLOC_SIZE(h_obj);\n\t\tvals[DUK__IDX_ESIZE] = (duk_int_t) DUK_HOBJECT_GET_ESIZE(h_obj);\n\t\tvals[DUK__IDX_ENEXT] = (duk_int_t) DUK_HOBJECT_GET_ENEXT(h_obj);\n\t\tvals[DUK__IDX_ASIZE] = (duk_int_t) DUK_HOBJECT_GET_ASIZE(h_obj);\n\t\tvals[DUK__IDX_HSIZE] = (duk_int_t) DUK_HOBJECT_GET_HSIZE(h_obj);\n\n\t\t/* Note: e_next indicates the number of gc-reachable entries\n\t\t * in the entry part, and also indicates the index where the\n\t\t * next new property would be inserted.  It does *not* indicate\n\t\t * the number of non-NULL keys present in the object.  That\n\t\t * value could be counted separately but requires a pass through\n\t\t * the key list.\n\t\t */\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tduk_hbuffer *h_data = (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(thr->heap, (duk_hcompfunc *) h_obj);\n\t\t\tvals[DUK__IDX_BCBYTES] = (duk_int_t) (h_data ? DUK_HBUFFER_GET_SIZE(h_data) : 0);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h_buf = (duk_hbuffer *) h;\n\n\t\tif (DUK_HBUFFER_HAS_DYNAMIC(h_buf)) {\n\t\t\tif (DUK_HBUFFER_HAS_EXTERNAL(h_buf)) {\n\t\t\t\tvals[DUK__IDX_VARIANT] = 2;  /* buffer variant 2: external */\n\t\t\t\tvals[DUK__IDX_HBYTES] = (duk_uint_t) (sizeof(duk_hbuffer_external));\n\t\t\t} else {\n\t\t\t\t/* When alloc_size == 0 the second allocation may not\n\t\t\t\t * actually exist.\n\t\t\t\t */\n\t\t\t\tvals[DUK__IDX_VARIANT] = 1;  /* buffer variant 1: dynamic */\n\t\t\t\tvals[DUK__IDX_HBYTES] = (duk_uint_t) (sizeof(duk_hbuffer_dynamic));\n\t\t\t}\n\t\t\tvals[DUK__IDX_DBYTES] = (duk_int_t) (DUK_HBUFFER_GET_SIZE(h_buf));\n\t\t} else {\n\t\t\tDUK_ASSERT(vals[DUK__IDX_VARIANT] == 0);  /* buffer variant 0: fixed */\n\t\t\tvals[DUK__IDX_HBYTES] = (duk_int_t) (sizeof(duk_hbuffer_fixed) + DUK_HBUFFER_GET_SIZE(h_buf));\n\t\t}\n\t\tbreak;\n\t}\n\t}\n\n finish:\n\tduk__inspect_multiple_uint(thr,\n\t    \"type\" \"\\x00\" \"itag\" \"\\x00\" \"refc\" \"\\x00\" \"hbytes\" \"\\x00\" \"class\" \"\\x00\"\n\t    \"pbytes\" \"\\x00\" \"esize\" \"\\x00\" \"enext\" \"\\x00\" \"asize\" \"\\x00\" \"hsize\" \"\\x00\"\n\t    \"bcbytes\" \"\\x00\" \"dbytes\" \"\\x00\" \"tstate\" \"\\x00\" \"variant\" \"\\x00\" \"\\x00\",\n\t    (duk_int_t *) &vals);\n}\n\nDUK_EXTERNAL void duk_inspect_callstack_entry(duk_hthread *thr, duk_int_t level) {\n\tduk_activation *act;\n\tduk_uint_fast32_t pc;\n\tduk_uint_fast32_t line;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* -1   = top callstack entry\n\t * -2   = caller of level -1\n\t * etc\n\t */\n\tact = duk_hthread_get_activation_for_level(thr, level);\n\tif (act == NULL) {\n\t\tduk_push_undefined(thr);\n\t\treturn;\n\t}\n\tduk_push_bare_object(thr);\n\n\t/* Relevant PC is just before current one because PC is\n\t * post-incremented.  This should match what error augment\n\t * code does.\n\t */\n\tpc = duk_hthread_get_act_prev_pc(thr, act);\n\n\tduk_push_tval(thr, &act->tv_func);\n\n\tduk_push_uint(thr, (duk_uint_t) pc);\n\tduk_put_prop_stridx_short(thr, -3, DUK_STRIDX_PC);\n\n#if defined(DUK_USE_PC2LINE)\n\tline = duk_hobject_pc2line_query(thr, -1, pc);\n#else\n\tline = 0;\n#endif\n\tduk_push_uint(thr, (duk_uint_t) line);\n\tduk_put_prop_stridx_short(thr, -3, DUK_STRIDX_LINE_NUMBER);\n\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_LC_FUNCTION);\n\t/* Providing access to e.g. act->lex_env would be dangerous: these\n\t * internal structures must never be accessible to the application.\n\t * Duktape relies on them having consistent data, and this consistency\n\t * is only asserted for, not checked for.\n\t */\n}\n\n/* automatic undefs */\n#undef DUK__IDX_ASIZE\n#undef DUK__IDX_BCBYTES\n#undef DUK__IDX_CLASS\n#undef DUK__IDX_DBYTES\n#undef DUK__IDX_ENEXT\n#undef DUK__IDX_ESIZE\n#undef DUK__IDX_HBYTES\n#undef DUK__IDX_HSIZE\n#undef DUK__IDX_ITAG\n#undef DUK__IDX_PBYTES\n#undef DUK__IDX_REFC\n#undef DUK__IDX_TSTATE\n#undef DUK__IDX_TYPE\n#undef DUK__IDX_VARIANT\n#line 1 \"duk_api_memory.c\"\n/*\n *  Memory calls.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_EXTERNAL void *duk_alloc_raw(duk_hthread *thr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn DUK_ALLOC_RAW(thr->heap, size);\n}\n\nDUK_EXTERNAL void duk_free_raw(duk_hthread *thr, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_FREE_RAW(thr->heap, ptr);\n}\n\nDUK_EXTERNAL void *duk_realloc_raw(duk_hthread *thr, void *ptr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn DUK_REALLOC_RAW(thr->heap, ptr, size);\n}\n\nDUK_EXTERNAL void *duk_alloc(duk_hthread *thr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn DUK_ALLOC(thr->heap, size);\n}\n\nDUK_EXTERNAL void duk_free(duk_hthread *thr, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_FREE_CHECKED(thr, ptr);\n}\n\nDUK_EXTERNAL void *duk_realloc(duk_hthread *thr, void *ptr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/*\n\t *  Note: since this is an exposed API call, there should be\n\t *  no way a mark-and-sweep could have a side effect on the\n\t *  memory allocation behind 'ptr'; the pointer should never\n\t *  be something that Duktape wants to change.\n\t *\n\t *  Thus, no need to use DUK_REALLOC_INDIRECT (and we don't\n\t *  have the storage location here anyway).\n\t */\n\n\treturn DUK_REALLOC(thr->heap, ptr, size);\n}\n\nDUK_EXTERNAL void duk_get_memory_functions(duk_hthread *thr, duk_memory_functions *out_funcs) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(out_funcs != NULL);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\theap = thr->heap;\n\tout_funcs->alloc_func = heap->alloc_func;\n\tout_funcs->realloc_func = heap->realloc_func;\n\tout_funcs->free_func = heap->free_func;\n\tout_funcs->udata = heap->heap_udata;\n}\n\nDUK_EXTERNAL void duk_gc(duk_hthread *thr, duk_uint_t flags) {\n\tduk_heap *heap;\n\tduk_small_uint_t ms_flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep requested by application\"));\n\tDUK_ASSERT(DUK_GC_COMPACT == DUK_MS_FLAG_EMERGENCY);  /* Compact flag is 1:1 with emergency flag which forces compaction. */\n\tms_flags = (duk_small_uint_t) flags;\n\tduk_heap_mark_and_sweep(heap, ms_flags);\n}\n#line 1 \"duk_api_object.c\"\n/*\n *  Object handling: property access and other support functions.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Property handling\n *\n *  The API exposes only the most common property handling functions.\n *  The caller can invoke ECMAScript built-ins for full control (e.g.\n *  defineProperty, getOwnPropertyDescriptor).\n */\n\nDUK_EXTERNAL duk_bool_t duk_get_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property get right now.\n\t */\n\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, -1);\n\n\trc = duk_hobject_getprop(thr, tv_obj, tv_key);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\t/* a value is left on stack regardless of rc */\n\n\tduk_remove_m2(thr);  /* remove key */\n\tDUK_ASSERT(duk_is_undefined(thr, -1) || rc == 1);\n\treturn rc;  /* 1 if property found, 0 otherwise */\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk_get_prop(thr, obj_idx);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_get_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk_get_prop(thr, obj_idx);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_get_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_get_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_get_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n\nDUK_INTERNAL duk_bool_t duk_get_prop_stridx_boolean(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop) {\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\trc = duk_get_prop_stridx(thr, obj_idx, stridx);\n\tif (out_has_prop) {\n\t\t*out_has_prop = rc;\n\t}\n\treturn duk_to_boolean_top_pop(thr);\n}\n\n/* This get variant is for internal use, it differs from standard\n * duk_get_prop() in that:\n *   - Object argument must be an object (primitive values not supported).\n *   - Key argument must be a string (no coercion).\n *   - Only own properties are checked (no inheritance).  Only \"entry part\"\n *     properties are checked (not array index properties).\n *   - Property must be a plain data property, not a getter.\n *   - Proxy traps are not triggered.\n */\nDUK_INTERNAL duk_bool_t duk_xget_owndataprop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_hobject *h_obj;\n\tduk_hstring *h_key;\n\tduk_tval *tv_val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property get right now.\n\t */\n\n\th_obj = duk_get_hobject(thr, obj_idx);\n\tif (h_obj == NULL) {\n\t\treturn 0;\n\t}\n\th_key = duk_require_hstring(thr, -1);\n\n\ttv_val = duk_hobject_find_entry_tval_ptr(thr->heap, h_obj, h_key);\n\tif (tv_val == NULL) {\n\t\treturn 0;\n\t}\n\n\tduk_push_tval(thr, tv_val);\n\tduk_remove_m2(thr);  /* remove key */\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_bool_t duk_xget_owndataprop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_xget_owndataprop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_xget_owndataprop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_xget_owndataprop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                   (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n\nDUK_LOCAL duk_bool_t duk__put_prop_shared(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t idx_key) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_tval *tv_val;\n\tduk_bool_t throw_flag;\n\tduk_bool_t rc;\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property put right now (putprop protects\n\t * against it internally).\n\t */\n\n\t/* Key and value indices are either (-2, -1) or (-1, -2).  Given idx_key,\n\t * idx_val is always (idx_key ^ 0x01).\n\t */\n\tDUK_ASSERT((idx_key == -2 && (idx_key ^ 1) == -1) ||\n\t           (idx_key == -1 && (idx_key ^ 1) == -2));\n\t/* XXX: Direct access; faster validation. */\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, idx_key);\n\ttv_val = duk_require_tval(thr, idx_key ^ 1);\n\tthrow_flag = duk_is_strict_call(thr);\n\n\trc = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, throw_flag);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\n\tduk_pop_2(thr);  /* remove key and value */\n\treturn rc;  /* 1 if property found, 0 otherwise */\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__put_prop_shared(thr, obj_idx, -2);\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\t/* Careful here and with other duk_put_prop_xxx() helpers: the\n\t * target object and the property value may be in the same value\n\t * stack slot (unusual, but still conceptually clear).\n\t */\n\tobj_idx = duk_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_put_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\n\nDUK_INTERNAL duk_bool_t duk_put_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\nDUK_INTERNAL duk_bool_t duk_put_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_put_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t throw_flag;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property delete right now.\n\t */\n\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, -1);\n\tthrow_flag = duk_is_strict_call(thr);\n\n\trc = duk_hobject_delprop(thr, tv_obj, tv_key, throw_flag);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\n\tduk_pop(thr);  /* remove key */\n\treturn rc;\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk_del_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk_del_prop(thr, obj_idx);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_del_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk_del_prop(thr, obj_idx);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk_del_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk_del_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_del_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_del_prop(thr, obj_idx);\n}\n\n#if 0\nDUK_INTERNAL duk_bool_t duk_del_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_del_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_has_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property existence check right now.\n\t */\n\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, -1);\n\n\trc = duk_hobject_hasprop(thr, tv_obj, tv_key);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\n\tduk_pop(thr);  /* remove key */\n\treturn rc;  /* 1 if property found, 0 otherwise */\n}\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk_has_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk_has_prop(thr, obj_idx);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_has_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk_has_prop(thr, obj_idx);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk_has_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk_has_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_has_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_has_prop(thr, obj_idx);\n}\n\n#if 0\nDUK_INTERNAL duk_bool_t duk_has_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_has_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n#endif\n\n/* Define own property without inheritance lookups and such.  This differs from\n * [[DefineOwnProperty]] because special behaviors (like Array 'length') are\n * not invoked by this method.  The caller must be careful to invoke any such\n * behaviors if necessary.\n */\nDUK_INTERNAL void duk_xdef_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\tkey = duk_to_property_key_hstring(thr, -2);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(duk_require_tval(thr, -1) != NULL);\n\n\tduk_hobject_define_property_internal(thr, obj, key, desc_flags);\n\n\tduk_pop(thr);  /* pop key */\n}\n\nDUK_INTERNAL void duk_xdef_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\n\tduk_hobject_define_property_internal_arridx(thr, obj, arr_idx, desc_flags);\n\t/* value popped by call */\n}\n\nDUK_INTERNAL void duk_xdef_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\tkey = DUK_HTHREAD_GET_STRING(thr, stridx);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(duk_require_tval(thr, -1) != NULL);\n\n\tduk_hobject_define_property_internal(thr, obj, key, desc_flags);\n\t/* value popped by call */\n}\n\nDUK_INTERNAL void duk_xdef_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\tduk_xdef_prop_stridx(thr, (duk_idx_t) (duk_int8_t) (packed_args >> 24),\n\t                          (duk_small_uint_t) (packed_args >> 8) & 0xffffUL,\n\t                          (duk_small_uint_t) (packed_args & 0xffL));\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL void duk_xdef_prop_stridx_builtin(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\tDUK_ASSERT_BIDX_VALID(builtin_idx);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\tkey = DUK_HTHREAD_GET_STRING(thr, stridx);\n\tDUK_ASSERT(key != NULL);\n\n\tduk_push_hobject(thr, thr->builtins[builtin_idx]);\n\tduk_hobject_define_property_internal(thr, obj, key, desc_flags);\n\t/* value popped by call */\n}\n#endif\n\n/* This is a rare property helper; it sets the global thrower (E5 Section 13.2.3)\n * setter/getter into an object property.  This is needed by the 'arguments'\n * object creation code, function instance creation code, and Function.prototype.bind().\n */\n\nDUK_INTERNAL void duk_xdef_prop_stridx_thrower(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring_stridx(thr, stridx);\n\tduk_push_hobject_bidx(thr, DUK_BIDX_TYPE_ERROR_THROWER);\n\tduk_dup_top(thr);\n\tduk_def_prop(thr, obj_idx, DUK_DEFPROP_HAVE_SETTER | DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_FORCE);  /* attributes always 0 */\n}\n\n/* Object.getOwnPropertyDescriptor() equivalent C binding. */\nDUK_EXTERNAL void duk_get_prop_desc(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(flags);  /* no flags defined yet */\n\n\tduk_hobject_object_get_own_property_descriptor(thr, obj_idx);  /* [ ... key ] -> [ ... desc ] */\n}\n\n/* Object.defineProperty() equivalent C binding. */\nDUK_EXTERNAL void duk_def_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t flags) {\n\tduk_idx_t idx_base;\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_idx_t idx_value;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\tduk_uint_t is_data_desc;\n\tduk_uint_t is_acc_desc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\n\tis_data_desc = flags & (DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE);\n\tis_acc_desc = flags & (DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER);\n\tif (is_data_desc && is_acc_desc) {\n\t\t/* \"Have\" flags must not be conflicting so that they would\n\t\t * apply to both a plain property and an accessor at the same\n\t\t * time.\n\t\t */\n\t\tgoto fail_invalid_desc;\n\t}\n\n\tidx_base = duk_get_top_index(thr);\n\tif (flags & DUK_DEFPROP_HAVE_SETTER) {\n\t\tduk_require_type_mask(thr, idx_base, DUK_TYPE_MASK_UNDEFINED |\n\t\t                                     DUK_TYPE_MASK_OBJECT |\n\t\t                                     DUK_TYPE_MASK_LIGHTFUNC);\n\t\tset = duk_get_hobject_promote_lfunc(thr, idx_base);\n\t\tif (set != NULL && !DUK_HOBJECT_IS_CALLABLE(set)) {\n\t\t\tgoto fail_not_callable;\n\t\t}\n\t\tidx_base--;\n\t} else {\n\t\tset = NULL;\n\t}\n\tif (flags & DUK_DEFPROP_HAVE_GETTER) {\n\t\tduk_require_type_mask(thr, idx_base, DUK_TYPE_MASK_UNDEFINED |\n\t\t                                     DUK_TYPE_MASK_OBJECT |\n\t\t                                     DUK_TYPE_MASK_LIGHTFUNC);\n\t\tget = duk_get_hobject_promote_lfunc(thr, idx_base);\n\t\tif (get != NULL && !DUK_HOBJECT_IS_CALLABLE(get)) {\n\t\t\tgoto fail_not_callable;\n\t\t}\n\t\tidx_base--;\n\t} else {\n\t\tget = NULL;\n\t}\n\tif (flags & DUK_DEFPROP_HAVE_VALUE) {\n\t\tidx_value = idx_base;\n\t\tidx_base--;\n\t} else {\n\t\tidx_value = (duk_idx_t) -1;\n\t}\n\tkey = duk_to_property_key_hstring(thr, idx_base);\n\tDUK_ASSERT(key != NULL);\n\n\tduk_require_valid_index(thr, idx_base);\n\n\tduk_hobject_define_property_helper(thr,\n\t                                   flags /*defprop_flags*/,\n\t                                   obj,\n\t                                   key,\n\t                                   idx_value,\n\t                                   get,\n\t                                   set,\n\t                                   1 /*throw_flag*/);\n\n\t/* Clean up stack */\n\n\tduk_set_top(thr, idx_base);\n\n\t/* [ ... obj ... ] */\n\n\treturn;\n\n fail_invalid_desc:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_DESCRIPTOR);\n\tDUK_WO_NORETURN(return;);\n\n fail_not_callable:\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Object related\n */\n\nDUK_EXTERNAL void duk_compact(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, obj_idx);\n\tif (obj) {\n\t\t/* Note: this may fail, caller should protect the call if necessary */\n\t\tduk_hobject_compact_props(thr, obj);\n\t}\n}\n\nDUK_INTERNAL void duk_compact_m1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_compact(thr, -1);\n}\n\n/* XXX: the duk_hobject_enum.c stack APIs should be reworked */\n\nDUK_EXTERNAL void duk_enum(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t enum_flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_dup(thr, obj_idx);\n\tduk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tduk_hobject_enumerator_create(thr, enum_flags);   /* [target] -> [enum] */\n}\n\nDUK_EXTERNAL duk_bool_t duk_next(duk_hthread *thr, duk_idx_t enum_index, duk_bool_t get_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_require_hobject(thr, enum_index);\n\tduk_dup(thr, enum_index);\n\treturn duk_hobject_enumerator_next(thr, get_value);\n}\n\nDUK_INTERNAL void duk_seal_freeze_raw(duk_hthread *thr, duk_idx_t obj_idx, duk_bool_t is_freeze) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, obj_idx);\n\tDUK_ASSERT(tv != NULL);\n\n\t/* Seal/freeze are quite rare in practice so it'd be nice to get the\n\t * correct behavior simply via automatic promotion (at the cost of some\n\t * memory churn).  However, the promoted objects don't behave the same,\n\t * e.g. promoted lightfuncs are extensible.\n\t */\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_BUFFER:\n\t\t/* Plain buffer: already sealed, but not frozen (and can't be frozen\n\t\t * because index properties can't be made non-writable.\n\t\t */\n\t\tif (is_freeze) {\n\t\t\tgoto fail_cannot_freeze;\n\t\t}\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\t/* Lightfunc: already sealed and frozen, success. */\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (is_freeze && DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\t/* Buffer objects cannot be frozen because there's no internal\n\t\t\t * support for making virtual array indices non-writable.\n\t\t\t */\n\t\t\tDUK_DD(DUK_DDPRINT(\"cannot freeze a buffer object\"));\n\t\t\tgoto fail_cannot_freeze;\n\t\t}\n\t\tduk_hobject_object_seal_freeze_helper(thr, h, is_freeze);\n\n\t\t/* Sealed and frozen objects cannot gain any more properties,\n\t\t * so this is a good time to compact them.\n\t\t */\n\t\tduk_hobject_compact_props(thr, h);\n\t\tbreak;\n\tdefault:\n\t\t/* ES2015 Sections 19.1.2.5, 19.1.2.17 */\n\t\tbreak;\n\t}\n\treturn;\n\n fail_cannot_freeze:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);  /* XXX: proper error message */\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_seal(duk_hthread *thr, duk_idx_t obj_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_seal_freeze_raw(thr, obj_idx, 0 /*is_freeze*/);\n}\n\nDUK_EXTERNAL void duk_freeze(duk_hthread *thr, duk_idx_t obj_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_seal_freeze_raw(thr, obj_idx, 1 /*is_freeze*/);\n}\n\n/*\n *  Helpers for writing multiple properties\n */\n\nDUK_EXTERNAL void duk_put_function_list(duk_hthread *thr, duk_idx_t obj_idx, const duk_function_list_entry *funcs) {\n\tconst duk_function_list_entry *ent = funcs;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tif (ent != NULL) {\n\t\twhile (ent->key != NULL) {\n\t\t\tduk_push_c_function(thr, ent->value, ent->nargs);\n\t\t\tduk_put_prop_string(thr, obj_idx, ent->key);\n\t\t\tent++;\n\t\t}\n\t}\n}\n\nDUK_EXTERNAL void duk_put_number_list(duk_hthread *thr, duk_idx_t obj_idx, const duk_number_list_entry *numbers) {\n\tconst duk_number_list_entry *ent = numbers;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tif (ent != NULL) {\n\t\twhile (ent->key != NULL) {\n\t\t\ttv = thr->valstack_top++;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));  /* value stack init policy */\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv, ent->value);  /* no need for decref/incref */\n\t\t\tduk_put_prop_string(thr, obj_idx, ent->key);\n\t\t\tent++;\n\t\t}\n\t}\n}\n\n/*\n *  Shortcut for accessing global object properties\n */\n\nDUK_EXTERNAL duk_bool_t duk_get_global_string(duk_hthread *thr, const char *key) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_string(thr, -1, key);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_global_lstring(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_lstring(thr, -1, key, key_len);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_get_global_literal_raw(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_literal_raw(thr, -1, key, key_len);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_get_global_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_heapptr(thr, -1, ptr);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n\n\nDUK_EXTERNAL duk_bool_t duk_put_global_string(duk_hthread *thr, const char *key) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_string(thr, -2, key);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_global_lstring(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_lstring(thr, -2, key, key_len);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_put_global_literal_raw(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_literal_raw(thr, -2, key, key_len);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_put_global_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_heapptr(thr, -2, ptr);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n\n/*\n *  ES2015 GetMethod()\n */\n\nDUK_INTERNAL duk_bool_t duk_get_method_stridx(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t stridx) {\n\t(void) duk_get_prop_stridx(thr, idx, stridx);\n\tif (duk_is_null_or_undefined(thr, -1)) {\n\t\tduk_pop_nodecref_unsafe(thr);\n\t\treturn 0;\n\t}\n\tif (!duk_is_callable(thr, -1)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 1;\n}\n\n/*\n *  Object prototype\n */\n\nDUK_EXTERNAL void duk_get_prototype(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\n\t/* XXX: shared helper for duk_push_hobject_or_undefined()? */\n\tproto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, obj);\n\tif (proto) {\n\t\tduk_push_hobject(thr, proto);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n}\n\nDUK_EXTERNAL void duk_set_prototype(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\tduk_require_type_mask(thr, -1, DUK_TYPE_MASK_UNDEFINED |\n\t                               DUK_TYPE_MASK_OBJECT);\n\tproto = duk_get_hobject(thr, -1);\n\t/* proto can also be NULL here (allowed explicitly) */\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);  /* XXX: \"read only object\"? */\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, obj, proto);\n\n\tduk_pop(thr);\n}\n\nDUK_INTERNAL void duk_clear_prototype(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);  /* XXX: \"read only object\"? */\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, obj, NULL);\n}\n\nDUK_INTERNAL duk_bool_t duk_is_bare_object(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\n\tproto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, obj);\n\treturn (proto == NULL);\n}\n\n/*\n *  Object finalizer\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n/* XXX: these could be implemented as macros calling an internal function\n * directly.\n * XXX: same issue as with Duktape.fin: there's no way to delete the property\n * now (just set it to undefined).\n */\nDUK_EXTERNAL void duk_get_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* This get intentionally walks the inheritance chain at present,\n\t * which matches how the effective finalizer property is also\n\t * looked up in GC.\n\t */\n\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_INT_FINALIZER);\n}\n\nDUK_EXTERNAL void duk_set_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\tduk_bool_t callable;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hobject(thr, idx);  /* Get before 'put' so that 'idx' is correct. */\n\tcallable = duk_is_callable(thr, -1);\n\n\t/* At present finalizer is stored as a hidden Symbol, with normal\n\t * inheritance and access control.  As a result, finalizer cannot\n\t * currently be set on a non-extensible (sealed or frozen) object.\n\t * It might be useful to allow it.\n\t */\n\tduk_put_prop_stridx(thr, idx, DUK_STRIDX_INT_FINALIZER);\n\n\t/* In addition to setting the finalizer property, keep a \"have\n\t * finalizer\" flag in duk_hobject in sync so that refzero can do\n\t * a very quick finalizer check by walking the prototype chain\n\t * and checking the flag alone.  (Note that this means that just\n\t * setting _Finalizer on an object won't affect finalizer checks.)\n\t *\n\t * NOTE: if the argument is a Proxy object, this flag will be set\n\t * on the Proxy, not the target.  As a result, the target won't get\n\t * a finalizer flag and the Proxy also won't be finalized as there's\n\t * an explicit Proxy check in finalization now.\n\t */\n\tif (callable) {\n\t\tDUK_HOBJECT_SET_HAVE_FINALIZER(h);\n\t} else {\n\t\tDUK_HOBJECT_CLEAR_HAVE_FINALIZER(h);\n\t}\n}\n#else  /* DUK_USE_FINALIZER_SUPPORT */\nDUK_EXTERNAL void duk_get_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_set_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n#line 1 \"duk_api_random.c\"\n/*\n *  Random numbers\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_EXTERNAL duk_double_t duk_random(duk_hthread *thr) {\n\treturn (duk_double_t) DUK_UTIL_GET_RANDOM_DOUBLE(thr);\n}\n#line 1 \"duk_api_stack.c\"\n/*\n *  API calls related to general value stack manipulation: resizing the value\n *  stack, pushing and popping values, type checking and reading values,\n *  coercing values, etc.\n *\n *  Also contains internal functions (such as duk_get_tval()), defined\n *  in duk_api_internal.h, with semantics similar to the public API.\n */\n\n/* XXX: repetition of stack pre-checks -> helper or macro or inline */\n/* XXX: shared api error strings, and perhaps even throw code for rare cases? */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Forward declarations\n */\n\nDUK_LOCAL_DECL duk_idx_t duk__push_c_function_raw(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_uint_t flags, duk_small_uint_t proto_bidx);\n\n/*\n *  Global state for working around missing variadic macros\n */\n\n#if !defined(DUK_USE_VARIADIC_MACROS)\nDUK_EXTERNAL const char *duk_api_global_filename = NULL;\nDUK_EXTERNAL duk_int_t duk_api_global_line = 0;\n#endif\n\n/*\n *  Misc helpers\n */\n\nDUK_LOCAL const char * const duk__symbol_type_strings[4] = {\n\t\"hidden\", \"global\", \"local\", \"wellknown\"\n};\n\n#if !defined(DUK_USE_PACKED_TVAL)\nDUK_LOCAL const duk_uint_t duk__type_from_tag[] = {\n\tDUK_TYPE_NUMBER,\n\tDUK_TYPE_NUMBER,  /* fastint */\n\tDUK_TYPE_UNDEFINED,\n\tDUK_TYPE_NULL,\n\tDUK_TYPE_BOOLEAN,\n\tDUK_TYPE_POINTER,\n\tDUK_TYPE_LIGHTFUNC,\n\tDUK_TYPE_NONE,\n\tDUK_TYPE_STRING,\n\tDUK_TYPE_OBJECT,\n\tDUK_TYPE_BUFFER,\n};\nDUK_LOCAL const duk_uint_t duk__type_mask_from_tag[] = {\n\tDUK_TYPE_MASK_NUMBER,\n\tDUK_TYPE_MASK_NUMBER,  /* fastint */\n\tDUK_TYPE_MASK_UNDEFINED,\n\tDUK_TYPE_MASK_NULL,\n\tDUK_TYPE_MASK_BOOLEAN,\n\tDUK_TYPE_MASK_POINTER,\n\tDUK_TYPE_MASK_LIGHTFUNC,\n\tDUK_TYPE_MASK_NONE,\n\tDUK_TYPE_MASK_STRING,\n\tDUK_TYPE_MASK_OBJECT,\n\tDUK_TYPE_MASK_BUFFER,\n};\n#endif  /* !DUK_USE_PACKED_TVAL */\n\n/* Assert that there's room for one value. */\n#define DUK__ASSERT_SPACE() do { \\\n\t\tDUK_ASSERT(!(thr->valstack_top >= thr->valstack_end)); \\\n\t} while (0)\n\n/* Check that there's room to push one value. */\n#if defined(DUK_USE_VALSTACK_UNSAFE)\n/* Faster but value stack overruns are memory unsafe. */\n#define DUK__CHECK_SPACE() DUK__ASSERT_SPACE()\n#else\n#define DUK__CHECK_SPACE() do { \\\n\t\tif (DUK_UNLIKELY(thr->valstack_top >= thr->valstack_end)) { \\\n\t\t\tDUK_ERROR_RANGE_PUSH_BEYOND(thr); \\\n\t\t} \\\n\t} while (0)\n#endif\n\nDUK_LOCAL duk_small_uint_t duk__get_symbol_type(duk_hstring *h) {\n\tconst duk_uint8_t *data;\n\tduk_size_t len;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HSTRING_HAS_SYMBOL(h));\n\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(h) >= 1);  /* always true, symbol prefix */\n\n\tdata = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\tDUK_ASSERT(len >= 1);\n\n\t/* XXX: differentiate between 0x82 and 0xff (hidden vs. internal?)? */\n\n\tif (data[0] == 0xffU) {\n\t\treturn DUK_SYMBOL_TYPE_HIDDEN;\n\t} else if (data[0] == 0x82U) {\n\t\treturn DUK_SYMBOL_TYPE_HIDDEN;\n\t} else if (data[0] == 0x80U) {\n\t\treturn DUK_SYMBOL_TYPE_GLOBAL;\n\t} else if (data[len - 1] != 0xffU) {\n\t\treturn DUK_SYMBOL_TYPE_LOCAL;\n\t} else {\n\t\treturn DUK_SYMBOL_TYPE_WELLKNOWN;\n\t}\n}\n\nDUK_LOCAL const char *duk__get_symbol_type_string(duk_hstring *h) {\n\tduk_small_uint_t idx;\n\tidx = duk__get_symbol_type(h);\n\tDUK_ASSERT(idx < sizeof(duk__symbol_type_strings));\n\treturn duk__symbol_type_strings[idx];\n}\n\nDUK_LOCAL_DECL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t tag);\n\nDUK_LOCAL duk_int_t duk__api_coerce_d2i(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value, duk_bool_t require) {\n\tduk_tval *tv;\n\tduk_small_int_t c;\n\tduk_double_t d;\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\t/*\n\t *  Special cases like NaN and +/- Infinity are handled explicitly\n\t *  because a plain C coercion from double to int handles these cases\n\t *  in undesirable ways.  For instance, NaN may coerce to INT_MIN\n\t *  (not zero), and INT_MAX + 1 may coerce to INT_MIN (not INT_MAX).\n\t *\n\t *  This double-to-int coercion differs from ToInteger() because it\n\t *  has a finite range (ToInteger() allows e.g. +/- Infinity).  It\n\t *  also differs from ToInt32() because the INT_MIN/INT_MAX clamping\n\t *  depends on the size of the int type on the platform.  In particular,\n\t *  on platforms with a 64-bit int type, the full range is allowed.\n\t */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tduk_int64_t t = DUK_TVAL_GET_FASTINT(tv);\n#if (DUK_INT_MAX <= 0x7fffffffL)\n\t\t/* Clamping only necessary for 32-bit ints. */\n\t\tif (t < DUK_INT_MIN) {\n\t\t\tt = DUK_INT_MIN;\n\t\t} else if (t > DUK_INT_MAX) {\n\t\t\tt = DUK_INT_MAX;\n\t\t}\n#endif\n\t\treturn (duk_int_t) t;\n\t}\n#endif\n\n\tif (DUK_TVAL_IS_NUMBER(tv)) {\n\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\t\tif (c == DUK_FP_NAN) {\n\t\t\treturn 0;\n\t\t} else if (d < (duk_double_t) DUK_INT_MIN) {\n\t\t\t/* covers -Infinity */\n\t\t\treturn DUK_INT_MIN;\n\t\t} else if (d > (duk_double_t) DUK_INT_MAX) {\n\t\t\t/* covers +Infinity */\n\t\t\treturn DUK_INT_MAX;\n\t\t} else {\n\t\t\t/* coerce towards zero */\n\t\t\treturn (duk_int_t) d;\n\t\t}\n\t}\n\n\tif (require) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"number\", DUK_STR_NOT_NUMBER);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\treturn def_value;\n}\n\nDUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value, duk_bool_t require) {\n\tduk_tval *tv;\n\tduk_small_int_t c;\n\tduk_double_t d;\n\n\t/* Same as above but for unsigned int range. */\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tduk_int64_t t = DUK_TVAL_GET_FASTINT(tv);\n\t\tif (t < 0) {\n\t\t\tt = 0;\n\t\t}\n#if (DUK_UINT_MAX <= 0xffffffffUL)\n\t\t/* Clamping only necessary for 32-bit ints. */\n\t\telse if (t > DUK_UINT_MAX) {\n\t\t\tt = DUK_UINT_MAX;\n\t\t}\n#endif\n\t\treturn (duk_uint_t) t;\n\t}\n#endif\n\n\tif (DUK_TVAL_IS_NUMBER(tv)) {\n\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\t\tif (c == DUK_FP_NAN) {\n\t\t\treturn 0;\n\t\t} else if (d < 0.0) {\n\t\t\t/* covers -Infinity */\n\t\t\treturn (duk_uint_t) 0;\n\t\t} else if (d > (duk_double_t) DUK_UINT_MAX) {\n\t\t\t/* covers +Infinity */\n\t\t\treturn (duk_uint_t) DUK_UINT_MAX;\n\t\t} else {\n\t\t\t/* coerce towards zero */\n\t\t\treturn (duk_uint_t) d;\n\t\t}\n\t}\n\n\tif (require) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"number\", DUK_STR_NOT_NUMBER);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\treturn def_value;\n}\n\n/*\n *  Stack index validation/normalization and getting a stack duk_tval ptr.\n *\n *  These are called by many API entrypoints so the implementations must be\n *  fast and \"inlined\".\n *\n *  There's some repetition because of this; keep the functions in sync.\n */\n\nDUK_EXTERNAL duk_idx_t duk_normalize_index(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\t/* Care must be taken to avoid pointer wrapping in the index\n\t * validation.  For instance, on a 32-bit platform with 8-byte\n\t * duk_tval the index 0x20000000UL would wrap the memory space\n\t * once.\n\t */\n\n\t/* Assume value stack sizes (in elements) fits into duk_idx_t. */\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\t/* since index non-negative */\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn (duk_idx_t) uidx;\n\t}\n\treturn DUK_INVALID_INDEX;\n}\n\nDUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn (duk_idx_t) uidx;\n\t}\n\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_tval *duk_get_tval(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn thr->valstack_bottom + uidx;\n\t}\n\treturn NULL;\n}\n\n/* Variant of duk_get_tval() which is guaranteed to return a valid duk_tval\n * pointer.  When duk_get_tval() would return NULL, this variant returns a\n * pointer to a duk_tval with tag DUK_TAG_UNUSED.  This allows the call site\n * to avoid an unnecessary NULL check which sometimes leads to better code.\n * The return duk_tval is read only (at least for the UNUSED value).\n */\nDUK_LOCAL const duk_tval_unused duk__const_tval_unused = DUK_TVAL_UNUSED_INITIALIZER();\n\nDUK_INTERNAL duk_tval *duk_get_tval_or_unused(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval(thr, idx);\n\tif (tv != NULL) {\n\t\treturn tv;\n\t}\n\treturn (duk_tval *) DUK_LOSE_CONST(&duk__const_tval_unused);\n}\n\nDUK_INTERNAL duk_tval *duk_require_tval(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\t/* Use unsigned arithmetic to optimize comparison. */\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn thr->valstack_bottom + uidx;\n\t}\n\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/* Non-critical. */\nDUK_EXTERNAL duk_bool_t duk_is_valid_index(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\treturn (duk_normalize_index(thr, idx) >= 0);\n}\n\n/* Non-critical. */\nDUK_EXTERNAL void duk_require_valid_index(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tif (DUK_UNLIKELY(duk_normalize_index(thr, idx) < 0)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\n/*\n *  Value stack top handling\n */\n\nDUK_EXTERNAL duk_idx_t duk_get_top(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n}\n\n/* Internal helper to get current top but to require a minimum top value\n * (TypeError if not met).\n */\nDUK_INTERNAL duk_idx_t duk_get_top_require_min(duk_hthread *thr, duk_idx_t min_top) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tif (DUK_UNLIKELY(ret < min_top)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn ret;\n}\n\n/* Set stack top within currently allocated range, but don't reallocate.\n * This is performance critical especially for call handling, so whenever\n * changing, profile and look at generated code.\n */\nDUK_EXTERNAL void duk_set_top(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t vs_limit;\n\tduk_uidx_t uidx;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tvs_limit = (duk_uidx_t) (thr->valstack_end - thr->valstack_bottom);\n\n\tif (idx < 0) {\n\t\t/* Negative indices are always within allocated stack but\n\t\t * must not go below zero index.\n\t\t */\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\t/* Positive index can be higher than valstack top but must\n\t\t * not go above allocated stack (equality is OK).\n\t\t */\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_limit);\n\n#if defined(DUK_USE_VALSTACK_UNSAFE)\n\tDUK_ASSERT(uidx <= vs_limit);\n\tDUK_UNREF(vs_limit);\n#else\n\tif (DUK_UNLIKELY(uidx > vs_limit)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\tDUK_ASSERT(uidx <= vs_limit);\n\n\t/* Handle change in value stack top.  Respect value stack\n\t * initialization policy: 'undefined' above top.  Note that\n\t * DECREF may cause a side effect that reallocates valstack,\n\t * so must relookup after DECREF.\n\t */\n\n\tif (uidx >= vs_size) {\n\t\t/* Stack size increases or stays the same. */\n#if defined(DUK_USE_ASSERTIONS)\n\t\tduk_uidx_t count;\n\n\t\tcount = uidx - vs_size;\n\t\twhile (count != 0) {\n\t\t\tcount--;\n\t\t\ttv = thr->valstack_top + count;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\t}\n#endif\n\t\tthr->valstack_top = thr->valstack_bottom + uidx;\n\t} else {\n\t\t/* Stack size decreases. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\tDUK_ASSERT(count > 0);\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);  /* Because count > 0. */\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n\t\tDUK_REFZERO_CHECK_FAST(thr);\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\t}\n}\n\n/* Internal variant with a non-negative index and no runtime size checks. */\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_set_top(thr, idx);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t uidx;\n\tduk_uidx_t vs_size;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_bottom);\n\tDUK_ASSERT(idx >= 0);\n\tDUK_ASSERT(idx <= (duk_idx_t) (thr->valstack_end - thr->valstack_bottom));\n\n\t/* XXX: byte arithmetic */\n\tuidx = (duk_uidx_t) idx;\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\n\tif (uidx >= vs_size) {\n\t\t/* Stack size increases or stays the same. */\n#if defined(DUK_USE_ASSERTIONS)\n\t\tduk_uidx_t count;\n\n\t\tcount = uidx - vs_size;\n\t\twhile (count != 0) {\n\t\t\tcount--;\n\t\t\ttv = thr->valstack_top + count;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\t}\n#endif\n\t\tthr->valstack_top = thr->valstack_bottom + uidx;\n\t} else {\n\t\t/* Stack size decreases. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\tDUK_ASSERT(count > 0);\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);  /* Because count > 0. */\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n\t\tDUK_REFZERO_CHECK_FAST(thr);\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\t}\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/* Internal helper: set top to 'top', and set [idx_wipe_start,top[ to\n * 'undefined' (doing nothing if idx_wipe_start == top).  Indices are\n * positive and within value stack reserve.  This is used by call handling.\n */\nDUK_INTERNAL void duk_set_top_and_wipe(duk_hthread *thr, duk_idx_t top, duk_idx_t idx_wipe_start) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(top >= 0);\n\tDUK_ASSERT(idx_wipe_start >= 0);\n\tDUK_ASSERT(idx_wipe_start <= top);\n\tDUK_ASSERT(thr->valstack_bottom + top <= thr->valstack_end);\n\tDUK_ASSERT(thr->valstack_bottom + idx_wipe_start <= thr->valstack_end);\n\n\tduk_set_top_unsafe(thr, idx_wipe_start);\n\tduk_set_top_unsafe(thr, top);\n}\n\nDUK_EXTERNAL duk_idx_t duk_get_top_index(duk_hthread *thr) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;\n\tif (DUK_UNLIKELY(ret < 0)) {\n\t\t/* Return invalid index; if caller uses this without checking\n\t\t * in another API call, the index won't map to a valid stack\n\t\t * entry.\n\t\t */\n\t\treturn DUK_INVALID_INDEX;\n\t}\n\treturn ret;\n}\n\n/* Internal variant: call assumes there is at least one element on the value\n * stack frame; this is only asserted for.\n */\nDUK_INTERNAL duk_idx_t duk_get_top_index_unsafe(duk_hthread *thr) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_idx_t duk_require_top_index(duk_hthread *thr) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;\n\tif (DUK_UNLIKELY(ret < 0)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, -1);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn ret;\n}\n\n/*\n *  Value stack resizing.\n *\n *  This resizing happens above the current \"top\": the value stack can be\n *  grown or shrunk, but the \"top\" is not affected.  The value stack cannot\n *  be resized to a size below the current reserve.\n *\n *  The low level reallocation primitive must carefully recompute all value\n *  stack pointers, and must also work if ALL pointers are NULL.  The resize\n *  is quite tricky because the valstack realloc may cause a mark-and-sweep,\n *  which may run finalizers.  Running finalizers may resize the valstack\n *  recursively (the same value stack we're working on).  So, after realloc\n *  returns, we know that the valstack bottom, top, and reserve should still\n *  be the same (there should not be live values above the \"top\"), but its\n *  underlying size, alloc_end, and base pointer may have changed.\n *\n *  'new_size' is known to be <= DUK_USE_VALSTACK_LIMIT, which ensures that\n *  size_t and pointer arithmetic won't wrap in duk__resize_valstack().\n */\n\n/* Low level valstack resize primitive, used for both grow and shrink.  All\n * adjustments for slack etc have already been done.  Doesn't throw but does\n * have allocation side effects.\n */\nDUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__resize_valstack(duk_hthread *thr, duk_size_t new_size) {\n\tduk_tval *pre_valstack;\n\tduk_tval *pre_bottom;\n\tduk_tval *pre_top;\n\tduk_tval *pre_end;\n\tduk_tval *pre_alloc_end;\n\tduk_ptrdiff_t ptr_diff;\n\tduk_tval *new_valstack;\n\tduk_size_t new_alloc_size;\n\tduk_tval *tv_prev_alloc_end;\n\tduk_tval *p;\n\n\tDUK_HTHREAD_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack) <= new_size);  /* can't resize below 'top' */\n\tDUK_ASSERT(new_size <= DUK_USE_VALSTACK_LIMIT);  /* valstack limit caller has check, prevents wrapping */\n\tDUK_ASSERT(new_size <= DUK_SIZE_MAX / sizeof(duk_tval));  /* specific assert for wrapping */\n\n\t/* Pre-realloc pointer copies for asserts and debug logs. */\n\tpre_valstack = thr->valstack;\n\tpre_bottom = thr->valstack_bottom;\n\tpre_top = thr->valstack_top;\n\tpre_end = thr->valstack_end;\n\tpre_alloc_end = thr->valstack_alloc_end;\n\n\tDUK_UNREF(pre_valstack);\n\tDUK_UNREF(pre_bottom);\n\tDUK_UNREF(pre_top);\n\tDUK_UNREF(pre_end);\n\tDUK_UNREF(pre_alloc_end);\n\n\t/* If finalizer torture enabled, force base pointer change every time\n\t * when it would be allowed.\n\t */\n#if defined(DUK_USE_FINALIZER_TORTURE)\n\tif (thr->heap->pf_prevent_count == 0) {\n\t\tduk_hthread_valstack_torture_realloc(thr);\n\t}\n#endif\n\n\t/* Allocate a new valstack using DUK_REALLOC_DIRECT() to deal with\n\t * a side effect changing the base pointer.\n\t */\n\tnew_alloc_size = sizeof(duk_tval) * new_size;\n\tnew_valstack = (duk_tval *) DUK_REALLOC_INDIRECT(thr->heap, duk_hthread_get_valstack_ptr, (void *) thr, new_alloc_size);\n\tif (DUK_UNLIKELY(new_valstack == NULL)) {\n\t\t/* Because new_size != 0, if condition doesn't need to be\n\t\t * (new_valstack != NULL || new_size == 0).\n\t\t */\n\t\tDUK_ASSERT(new_size != 0);\n\t\tDUK_D(DUK_DPRINT(\"failed to resize valstack to %lu entries (%lu bytes)\",\n\t\t                 (unsigned long) new_size, (unsigned long) new_alloc_size));\n\t\treturn 0;\n\t}\n\n\t/* Debug log any changes in pointer(s) by side effects.  These don't\n\t * necessarily imply any incorrect behavior, but should be rare in\n\t * practice.\n\t */\n#if defined(DUK_USE_DEBUG)\n\tif (thr->valstack != pre_valstack) {\n\t\tDUK_D(DUK_DPRINT(\"valstack base pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_valstack, (void *) thr->valstack));\n\t}\n\tif (thr->valstack_bottom != pre_bottom) {\n\t\tDUK_D(DUK_DPRINT(\"valstack bottom pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_bottom, (void *) thr->valstack_bottom));\n\t}\n\tif (thr->valstack_top != pre_top) {\n\t\tDUK_D(DUK_DPRINT(\"valstack top pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_top, (void *) thr->valstack_top));\n\t}\n\tif (thr->valstack_end != pre_end) {\n\t\tDUK_D(DUK_DPRINT(\"valstack end pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_end, (void *) thr->valstack_end));\n\t}\n\tif (thr->valstack_alloc_end != pre_alloc_end) {\n\t\tDUK_D(DUK_DPRINT(\"valstack alloc_end pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_alloc_end, (void *) thr->valstack_alloc_end));\n\t}\n#endif\n\n\t/* Assertions: offsets for bottom, top, and end (reserve) must not\n\t * have changed even with side effects because they are always\n\t * restored in unwind.  For alloc_end there's no guarantee: it may\n\t * have grown or shrunk (but remain above 'end').\n\t */\n\tDUK_ASSERT(thr->valstack_bottom - thr->valstack == pre_bottom - pre_valstack);\n\tDUK_ASSERT(thr->valstack_top - thr->valstack == pre_top - pre_valstack);\n\tDUK_ASSERT(thr->valstack_end - thr->valstack == pre_end - pre_valstack);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\n\t/* Write new pointers.  Most pointers can be handled as a pointer\n\t * difference.\n\t */\n\tptr_diff = (duk_ptrdiff_t) ((duk_uint8_t *) new_valstack - (duk_uint8_t *) thr->valstack);\n\ttv_prev_alloc_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_alloc_end + ptr_diff);\n\tthr->valstack = new_valstack;\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + ptr_diff);\n\tthr->valstack_top = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_top + ptr_diff);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_end + ptr_diff);\n\tthr->valstack_alloc_end = (duk_tval *) (void *) ((duk_uint8_t *) new_valstack + new_alloc_size);\n\n\t/* Assertions: pointer sanity after pointer updates. */\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\n\tDUK_D(DUK_DPRINT(\"resized valstack %lu -> %lu elements (%lu -> %lu bytes): \"\n\t                 \"base=%p -> %p, bottom=%p -> %p (%ld), top=%p -> %p (%ld), \"\n\t                 \"end=%p -> %p (%ld), alloc_end=%p -> %p (%ld);\"\n\t                 \" tv_prev_alloc_end=%p (-> %ld inits; <0 means shrink)\",\n\t                 (unsigned long) (pre_alloc_end - pre_valstack),\n\t                 (unsigned long) new_size,\n\t                 (unsigned long) ((duk_uint8_t *) pre_alloc_end - (duk_uint8_t *) pre_valstack),\n\t                 (unsigned long) new_alloc_size,\n\t                 (void *) pre_valstack, (void *) thr->valstack,\n\t                 (void *) pre_bottom, (void *) thr->valstack_bottom, (long) (thr->valstack_bottom - thr->valstack),\n\t                 (void *) pre_top, (void *) thr->valstack_top, (long) (thr->valstack_top - thr->valstack),\n\t                 (void *) pre_end, (void *) thr->valstack_end, (long) (thr->valstack_end - thr->valstack),\n\t                 (void *) pre_alloc_end, (void *) thr->valstack_alloc_end, (long) (thr->valstack_alloc_end - thr->valstack),\n\t                 (void *) tv_prev_alloc_end, (long) (thr->valstack_alloc_end - tv_prev_alloc_end)));\n\n\t/* If allocation grew, init any new slots to 'undefined'. */\n\tp = tv_prev_alloc_end;\n\twhile (p < thr->valstack_alloc_end) {\n\t\t/* Never executed if new size is smaller. */\n\t\tDUK_TVAL_SET_UNDEFINED(p);\n\t\tp++;\n\t}\n\n\t/* Assert for value stack initialization policy. */\n#if defined(DUK_USE_ASSERTIONS)\n\tp = thr->valstack_top;\n\twhile (p < thr->valstack_alloc_end) {\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(p));\n\t\tp++;\n\t}\n#endif\n\n\treturn 1;\n}\n\nDUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__valstack_grow(duk_hthread *thr, duk_size_t min_bytes, duk_bool_t throw_on_error) {\n\tduk_size_t min_size;\n\tduk_size_t new_size;\n\n\tDUK_ASSERT(min_bytes / sizeof(duk_tval) * sizeof(duk_tval) == min_bytes);\n\tmin_size = min_bytes / sizeof(duk_tval);  /* from bytes to slots */\n\n#if defined(DUK_USE_VALSTACK_GROW_SHIFT)\n\t/* New size is minimum size plus a proportional slack, e.g. shift of\n\t * 2 means a 25% slack.\n\t */\n\tnew_size = min_size + (min_size >> DUK_USE_VALSTACK_GROW_SHIFT);\n#else\n\t/* New size is tight with no slack.  This is sometimes preferred in\n\t * low memory environments.\n\t */\n\tnew_size = min_size;\n#endif\n\n\tif (DUK_UNLIKELY(new_size > DUK_USE_VALSTACK_LIMIT || new_size < min_size /*wrap*/)) {\n\t\t/* Note: may be triggered even if minimal new_size would not reach the limit,\n\t\t * plan limit accordingly.\n\t\t */\n\t\tif (throw_on_error) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_VALSTACK_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\treturn 0;\n\t}\n\n\tif (duk__resize_valstack(thr, new_size) == 0) {\n\t\tif (throw_on_error) {\n\t\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\treturn 0;\n\t}\n\n\tthr->valstack_end = thr->valstack + min_size;\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\n\treturn 1;\n}\n\n/* Hot, inlined value stack grow check.  Because value stack almost never\n * grows, the actual resize call is in a NOINLINE helper.\n */\nDUK_INTERNAL DUK_INLINE void duk_valstack_grow_check_throw(duk_hthread *thr, duk_size_t min_bytes) {\n\tduk_tval *tv;\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + min_bytes);\n\tif (DUK_LIKELY(thr->valstack_end >= tv)) {\n\t\treturn;\n\t}\n\tif (DUK_LIKELY(thr->valstack_alloc_end >= tv)) {\n\t\t/* Values in [valstack_top,valstack_alloc_end[ are initialized\n\t\t * to 'undefined' so we can just move the end pointer.\n\t\t */\n\t\tthr->valstack_end = tv;\n\t\treturn;\n\t}\n\t(void) duk__valstack_grow(thr, min_bytes, 1 /*throw_on_error*/);\n}\n\n/* Hot, inlined value stack grow check which doesn't throw. */\nDUK_INTERNAL DUK_INLINE duk_bool_t duk_valstack_grow_check_nothrow(duk_hthread *thr, duk_size_t min_bytes) {\n\tduk_tval *tv;\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + min_bytes);\n\tif (DUK_LIKELY(thr->valstack_end >= tv)) {\n\t\treturn 1;\n\t}\n\tif (DUK_LIKELY(thr->valstack_alloc_end >= tv)) {\n\t\tthr->valstack_end = tv;\n\t\treturn 1;\n\t}\n\treturn duk__valstack_grow(thr, min_bytes, 0 /*throw_on_error*/);\n}\n\n/* Value stack shrink check, called from mark-and-sweep. */\nDUK_INTERNAL void duk_valstack_shrink_check_nothrow(duk_hthread *thr, duk_bool_t snug) {\n\tduk_size_t alloc_bytes;\n\tduk_size_t reserve_bytes;\n\tduk_size_t shrink_bytes;\n\n\talloc_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_alloc_end - (duk_uint8_t *) thr->valstack);\n\treserve_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tDUK_ASSERT(alloc_bytes >= reserve_bytes);\n\n\t/* We're free to shrink the value stack allocation down to\n\t * reserve_bytes but not more.  If 'snug' (emergency GC)\n\t * shrink whatever we can.  Otherwise only shrink if the new\n\t * size would be considerably smaller.\n\t */\n\n#if defined(DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT)\n\tif (snug) {\n\t\tshrink_bytes = reserve_bytes;\n\t} else {\n\t\tduk_size_t proportion, slack;\n\n\t\t/* Require that value stack shrinks by at least X% of its\n\t\t * current size.  For example, shift of 2 means at least\n\t\t * 25%.  The proportion is computed as bytes and may not\n\t\t * be a multiple of sizeof(duk_tval); that's OK here.\n\t\t */\n\t\tproportion = alloc_bytes >> DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT;\n\t\tif (alloc_bytes - reserve_bytes < proportion) {\n\t\t\t/* Too little would be freed, do nothing. */\n\t\t\treturn;\n\t\t}\n\n\t\t/* Keep a slack after shrinking.  The slack is again a\n\t\t * proportion of the current size (the proportion should\n\t\t * of course be smaller than the check proportion above).\n\t\t */\n#if defined(DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT)\n\t\tDUK_ASSERT(DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT > DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT);\n\t\tslack = alloc_bytes >> DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT;\n#else\n\t\tslack = 0;\n#endif\n\t\tshrink_bytes = reserve_bytes +\n\t\t               slack / sizeof(duk_tval) * sizeof(duk_tval);  /* multiple of duk_tval */\n\t}\n#else  /* DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT */\n\t/* Always snug, useful in some low memory environments. */\n\tDUK_UNREF(snug);\n\tshrink_bytes = reserve_bytes;\n#endif  /* DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT */\n\n\tDUK_D(DUK_DPRINT(\"valstack shrink check: alloc_bytes=%ld, reserve_bytes=%ld, shrink_bytes=%ld (unvalidated)\",\n\t                 (long) alloc_bytes, (long) reserve_bytes, (long) shrink_bytes));\n\tDUK_ASSERT(shrink_bytes >= reserve_bytes);\n\tif (shrink_bytes >= alloc_bytes) {\n\t\t/* Skip if shrink target is same as current one (or higher,\n\t\t * though that shouldn't happen in practice).\n\t\t */\n\t\treturn;\n\t}\n\tDUK_ASSERT(shrink_bytes / sizeof(duk_tval) * sizeof(duk_tval) == shrink_bytes);\n\n\tDUK_D(DUK_DPRINT(\"valstack shrink check: decided to shrink, snug: %ld\", (long) snug));\n\n\tduk__resize_valstack(thr, shrink_bytes / sizeof(duk_tval));\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_stack(duk_hthread *thr, duk_idx_t extra) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\n\tif (DUK_UNLIKELY(extra < 0 || extra > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (extra < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\textra = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\textra = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) extra + DUK_VALSTACK_INTERNAL_EXTRA);\n\treturn duk_valstack_grow_check_nothrow(thr, min_new_bytes);\n}\n\nDUK_EXTERNAL void duk_require_stack(duk_hthread *thr, duk_idx_t extra) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\n\tif (DUK_UNLIKELY(extra < 0 || extra > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (extra < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\textra = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\textra = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) extra + DUK_VALSTACK_INTERNAL_EXTRA);\n\tduk_valstack_grow_check_throw(thr, min_new_bytes);\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_stack_top(duk_hthread *thr, duk_idx_t top) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (DUK_UNLIKELY(top < 0 || top > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (top < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\ttop = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\ttop = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tDUK_ASSERT(top >= 0);\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) top + DUK_VALSTACK_INTERNAL_EXTRA);\n\treturn duk_valstack_grow_check_nothrow(thr, min_new_bytes);\n}\n\nDUK_EXTERNAL void duk_require_stack_top(duk_hthread *thr, duk_idx_t top) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (DUK_UNLIKELY(top < 0 || top > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (top < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\ttop = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\ttop = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tDUK_ASSERT(top >= 0);\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) top + DUK_VALSTACK_INTERNAL_EXTRA);\n\tduk_valstack_grow_check_throw(thr, min_new_bytes);\n}\n\n/*\n *  Basic stack manipulation: swap, dup, insert, replace, etc\n */\n\nDUK_EXTERNAL void duk_swap(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n\tduk_tval tv_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_require_tval(thr, idx1);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, idx2);\n\tDUK_ASSERT(tv2 != NULL);\n\n\t/* If tv1==tv2 this is a NOP, no check is needed */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv1);\n\tDUK_TVAL_SET_TVAL(tv1, tv2);\n\tDUK_TVAL_SET_TVAL(tv2, &tv_tmp);\n}\n\nDUK_EXTERNAL void duk_swap_top(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_swap(thr, idx, -1);\n}\n\nDUK_EXTERNAL void duk_dup(duk_hthread *thr, duk_idx_t from_idx) {\n\tduk_tval *tv_from;\n\tduk_tval *tv_to;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\n\ttv_from = duk_require_tval(thr, from_idx);\n\ttv_to = thr->valstack_top++;\n\tDUK_ASSERT(tv_from != NULL);\n\tDUK_ASSERT(tv_to != NULL);\n\tDUK_TVAL_SET_TVAL(tv_to, tv_from);\n\tDUK_TVAL_INCREF(thr, tv_to);  /* no side effects */\n}\n\nDUK_EXTERNAL void duk_dup_top(duk_hthread *thr) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_dup(thr, -1);\n#else\n\tduk_tval *tv_from;\n\tduk_tval *tv_to;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\n\tif (DUK_UNLIKELY(thr->valstack_top - thr->valstack_bottom <= 0)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, -1);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\ttv_from = thr->valstack_top - 1;\n\ttv_to = thr->valstack_top++;\n\tDUK_ASSERT(tv_from != NULL);\n\tDUK_ASSERT(tv_to != NULL);\n\tDUK_TVAL_SET_TVAL(tv_to, tv_from);\n\tDUK_TVAL_INCREF(thr, tv_to);  /* no side effects */\n#endif\n}\n\nDUK_INTERNAL void duk_dup_0(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, 0);\n}\nDUK_INTERNAL void duk_dup_1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, 1);\n}\nDUK_INTERNAL void duk_dup_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, 2);\n}\nDUK_INTERNAL void duk_dup_m2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, -2);\n}\nDUK_INTERNAL void duk_dup_m3(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, -3);\n}\nDUK_INTERNAL void duk_dup_m4(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, -4);\n}\n\nDUK_EXTERNAL void duk_insert(duk_hthread *thr, duk_idx_t to_idx) {\n\tduk_tval *p;\n\tduk_tval *q;\n\tduk_tval tv_tmp;\n\tduk_size_t nbytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tp = duk_require_tval(thr, to_idx);\n\tDUK_ASSERT(p != NULL);\n\tq = duk_require_tval(thr, -1);\n\tDUK_ASSERT(q != NULL);\n\n\tDUK_ASSERT(q >= p);\n\n\t/*              nbytes\n\t *           <--------->\n\t *    [ ... | p | x | x | q ]\n\t * => [ ... | q | p | x | x ]\n\t */\n\n\tnbytes = (duk_size_t) (((duk_uint8_t *) q) - ((duk_uint8_t *) p));  /* Note: 'q' is top-1 */\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk_insert: to_idx=%ld, p=%p, q=%p, nbytes=%lu\",\n\t                     (long) to_idx, (void *) p, (void *) q, (unsigned long) nbytes));\n\n\t/* No net refcount changes.  No need to special case nbytes == 0\n\t * (p == q).\n\t */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, q);\n\tduk_memmove((void *) (p + 1), (const void *) p, (size_t) nbytes);\n\tDUK_TVAL_SET_TVAL(p, &tv_tmp);\n}\n\nDUK_INTERNAL void duk_insert_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(idx >= 0);  /* Doesn't support negative indices. */\n\n\tduk_push_undefined(thr);\n\tduk_insert(thr, idx);\n}\n\nDUK_INTERNAL void duk_insert_undefined_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) {\n\tduk_tval *tv, *tv_end;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(idx >= 0);  /* Doesn't support negative indices or count. */\n\tDUK_ASSERT(count >= 0);\n\n\ttv = duk_reserve_gap(thr, idx, count);\n\ttv_end = tv + count;\n\twhile (tv != tv_end) {\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t\ttv++;\n\t}\n}\n\nDUK_EXTERNAL void duk_replace(duk_hthread *thr, duk_idx_t to_idx) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n\tduk_tval tv_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, to_idx);\n\tDUK_ASSERT(tv2 != NULL);\n\n\t/* For tv1 == tv2, both pointing to stack top, the end result\n\t * is same as duk_pop(thr).\n\t */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv2);\n\tDUK_TVAL_SET_TVAL(tv2, tv1);\n\tDUK_TVAL_SET_UNDEFINED(tv1);\n\tthr->valstack_top--;\n\tDUK_TVAL_DECREF(thr, &tv_tmp);  /* side effects */\n}\n\nDUK_EXTERNAL void duk_copy(duk_hthread *thr, duk_idx_t from_idx, duk_idx_t to_idx) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_require_tval(thr, from_idx);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, to_idx);\n\tDUK_ASSERT(tv2 != NULL);\n\n\t/* For tv1 == tv2, this is a no-op (no explicit check needed). */\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv2, tv1);  /* side effects */\n}\n\nDUK_EXTERNAL void duk_remove(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *p;\n\tduk_tval *q;\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_tval tv_tmp;\n#endif\n\tduk_size_t nbytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tp = duk_require_tval(thr, idx);\n\tDUK_ASSERT(p != NULL);\n\tq = duk_require_tval(thr, -1);\n\tDUK_ASSERT(q != NULL);\n\n\tDUK_ASSERT(q >= p);\n\n\t/*              nbytes            zero size case\n\t *           <--------->\n\t *    [ ... | p | x | x | q ]     [ ... | p==q ]\n\t * => [ ... | x | x | q ]         [ ... ]\n\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* use a temp: decref only when valstack reachable values are correct */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, p);\n#endif\n\n\tnbytes = (duk_size_t) (((duk_uint8_t *) q) - ((duk_uint8_t *) p));  /* Note: 'q' is top-1 */\n\tduk_memmove((void *) p, (const void *) (p + 1), (size_t) nbytes);\n\n\tDUK_TVAL_SET_UNDEFINED(q);\n\tthr->valstack_top--;\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_DECREF(thr, &tv_tmp);  /* side effects */\n#endif\n}\n\nDUK_INTERNAL void duk_remove_unsafe(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_remove(thr, idx);  /* XXX: no optimization for now */\n}\n\nDUK_INTERNAL void duk_remove_m2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_remove(thr, -2);\n}\n\nDUK_INTERNAL void duk_remove_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) {\n#if defined(DUK_USE_PREFER_SIZE)\n\t/* XXX: maybe too slow even when preferring size? */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT(idx >= 0);\n\n\twhile (count-- > 0) {\n\t\tduk_remove(thr, idx);\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_tval *tv_newtop;\n\tduk_tval *tv;\n\tduk_size_t bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT(idx >= 0);\n\n\ttv_dst = thr->valstack_bottom + idx;\n\tDUK_ASSERT(tv_dst <= thr->valstack_top);\n\ttv_src = tv_dst + count;\n\tDUK_ASSERT(tv_src <= thr->valstack_top);\n\tbytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) tv_src);\n\n\tfor (tv = tv_dst; tv < tv_src; tv++) {\n\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t}\n\n\tduk_memmove((void *) tv_dst, (const void *) tv_src, bytes);\n\n\ttv_newtop = thr->valstack_top - count;\n\tfor (tv = tv_newtop; tv < thr->valstack_top; tv++) {\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t}\n\tthr->valstack_top = tv_newtop;\n\n\t/* When not preferring size, only NORZ macros are used; caller\n\t * is expected to DUK_REFZERO_CHECK().\n\t */\n#endif  /* DUK_USE_PREFER_SIZE */\n}\n\nDUK_INTERNAL void duk_remove_n_unsafe(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_remove_n(thr, idx, count);  /* XXX: no optimization for now */\n}\n\n/*\n *  Stack slice primitives\n */\n\nDUK_EXTERNAL void duk_xcopymove_raw(duk_hthread *to_thr, duk_hthread *from_thr, duk_idx_t count, duk_bool_t is_copy) {\n\tvoid *src;\n\tduk_size_t nbytes;\n\tduk_tval *p;\n\tduk_tval *q;\n\n\t/* XXX: several pointer comparison issues here */\n\n\tDUK_ASSERT_API_ENTRY(to_thr);\n\tDUK_CTX_ASSERT_VALID(to_thr);\n\tDUK_CTX_ASSERT_VALID(from_thr);\n\tDUK_ASSERT(to_thr->heap == from_thr->heap);\n\n\tif (DUK_UNLIKELY(to_thr == from_thr)) {\n\t\tDUK_ERROR_TYPE(to_thr, DUK_STR_INVALID_CONTEXT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tif (DUK_UNLIKELY((duk_uidx_t) count > (duk_uidx_t) DUK_USE_VALSTACK_LIMIT)) {\n\t\t/* Maximum value check ensures 'nbytes' won't wrap below.\n\t\t * Also handles negative count.\n\t\t */\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(to_thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(count >= 0);\n\n\tnbytes = sizeof(duk_tval) * (duk_size_t) count;\n\tif (DUK_UNLIKELY(nbytes == 0)) {\n\t\treturn;\n\t}\n\tDUK_ASSERT(to_thr->valstack_top <= to_thr->valstack_end);\n\tif (DUK_UNLIKELY((duk_size_t) ((duk_uint8_t *) to_thr->valstack_end - (duk_uint8_t *) to_thr->valstack_top) < nbytes)) {\n\t\tDUK_ERROR_RANGE_PUSH_BEYOND(to_thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tsrc = (void *) ((duk_uint8_t *) from_thr->valstack_top - nbytes);\n\tif (DUK_UNLIKELY(src < (void *) from_thr->valstack_bottom)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(to_thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* Copy values (no overlap even if to_thr == from_thr; that's not\n\t * allowed now anyway).\n\t */\n\tDUK_ASSERT(nbytes > 0);\n\tduk_memcpy((void *) to_thr->valstack_top, (const void *) src, (size_t) nbytes);\n\n\tp = to_thr->valstack_top;\n\tto_thr->valstack_top = (duk_tval *) (void *) (((duk_uint8_t *) p) + nbytes);\n\n\tif (is_copy) {\n\t\t/* Incref copies, keep originals. */\n\t\tq = to_thr->valstack_top;\n\t\twhile (p < q) {\n\t\t\tDUK_TVAL_INCREF(to_thr, p);  /* no side effects */\n\t\t\tp++;\n\t\t}\n\t} else {\n\t\t/* No net refcount change. */\n\t\tp = from_thr->valstack_top;\n\t\tq = (duk_tval *) (void *) (((duk_uint8_t *) p) - nbytes);\n\t\tfrom_thr->valstack_top = q;\n\n\t\twhile (p > q) {\n\t\t\tp--;\n\t\t\tDUK_TVAL_SET_UNDEFINED(p);\n\t\t\t/* XXX: fast primitive to set a bunch of values to UNDEFINED */\n\t\t}\n\t}\n}\n\n/* Internal helper: reserve a gap of 'count' elements at 'idx_base' and return a\n * pointer to the gap.  Values in the gap are garbage and MUST be initialized by\n * the caller before any side effects may occur.  The caller must ensure there's\n * enough stack reserve for 'count' values.\n */\nDUK_INTERNAL duk_tval *duk_reserve_gap(duk_hthread *thr, duk_idx_t idx_base, duk_idx_t count) {\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_size_t gap_bytes;\n\tduk_size_t copy_bytes;\n\n\t/* Caller is responsible for ensuring there's enough preallocated\n\t * value stack.\n\t */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_end - thr->valstack_top) >= (duk_size_t) count);\n\n\ttv_src = thr->valstack_bottom + idx_base;\n\tgap_bytes = (duk_size_t) count * sizeof(duk_tval);\n\ttv_dst = (duk_tval *) (void *) ((duk_uint8_t *) tv_src + gap_bytes);\n\tcopy_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) tv_src);\n\tthr->valstack_top = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_top + gap_bytes);\n\tduk_memmove((void *) tv_dst, (const void *) tv_src, copy_bytes);\n\n\t/* Values in the gap are left as garbage: caller must fill them in\n\t * and INCREF them before any side effects.\n\t */\n\treturn tv_src;\n}\n\n/*\n *  Get/opt/require\n */\n\nDUK_EXTERNAL void duk_require_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_UNDEFINED(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"undefined\", DUK_STR_NOT_UNDEFINED);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_EXTERNAL void duk_require_null(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_NULL(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"null\", DUK_STR_NOT_NULL);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_bool_t duk__get_boolean_raw(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) {\n\tduk_bool_t ret;\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BOOLEAN(tv)) {\n\t\tret = DUK_TVAL_GET_BOOLEAN(tv);\n\t\tDUK_ASSERT(ret == 0 || ret == 1);\n\t} else {\n\t\tret = def_value;\n\t\t/* Not guaranteed to be 0 or 1. */\n\t}\n\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_boolean_raw(thr, idx, 0);  /* default: false */\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_boolean_default(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_boolean_raw(thr, idx, def_value);\n}\n\nDUK_EXTERNAL duk_bool_t duk_require_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_LIKELY(DUK_TVAL_IS_BOOLEAN(tv))) {\n\t\tret = DUK_TVAL_GET_BOOLEAN(tv);\n\t\tDUK_ASSERT(ret == 0 || ret == 1);\n\t\treturn ret;\n\t} else {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"boolean\", DUK_STR_NOT_BOOLEAN);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n}\n\nDUK_EXTERNAL duk_bool_t duk_opt_boolean(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_boolean(thr, idx);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_double_t duk__get_number_raw(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {\n\tduk_double_union ret;\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tret.d = (duk_double_t) DUK_TVAL_GET_FASTINT(tv);  /* XXX: cast trick */\n\t}\n\telse\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv)) {\n\t\t/* When using packed duk_tval, number must be in NaN-normalized form\n\t\t * for it to be a duk_tval, so no need to normalize.  NOP for unpacked\n\t\t * duk_tval.\n\t\t */\n\t\tret.d = DUK_TVAL_GET_DOUBLE(tv);\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&ret));\n\t} else {\n\t\tret.d = def_value;\n\t\t/* Default value (including NaN) may not be normalized. */\n\t}\n\n\treturn ret.d;\n}\n\nDUK_EXTERNAL duk_double_t duk_get_number(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_number_raw(thr, idx, DUK_DOUBLE_NAN);  /* default: NaN */\n}\n\nDUK_EXTERNAL duk_double_t duk_get_number_default(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_number_raw(thr, idx, def_value);\n}\n\nDUK_EXTERNAL duk_double_t duk_require_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_double_union ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_NUMBER(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"number\", DUK_STR_NOT_NUMBER);\n\t\tDUK_WO_NORETURN(return 0.0;);\n\t}\n\n\tret.d = DUK_TVAL_GET_NUMBER(tv);\n\n\t/* When using packed duk_tval, number must be in NaN-normalized form\n\t * for it to be a duk_tval, so no need to normalize.  NOP for unpacked\n\t * duk_tval.\n\t */\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&ret));\n\treturn ret.d;\n}\n\nDUK_EXTERNAL duk_double_t duk_opt_number(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\t/* User provided default is not NaN normalized. */\n\t\treturn def_value;\n\t}\n\treturn duk_require_number(thr, idx);\n}\n\nDUK_EXTERNAL duk_int_t duk_get_int(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_get_uint(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_get_int_default(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, def_value, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_get_uint_default(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, def_value, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_require_int(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 1 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_require_uint(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 1 /*require*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_opt_int(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_int(thr, idx);\n}\n\nDUK_EXTERNAL duk_uint_t duk_opt_uint(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_uint(thr, idx);\n}\n\nDUK_EXTERNAL const char *duk_get_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tduk_hstring *h;\n\tconst char *ret;\n\tduk_size_t len;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\t\tret = (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\tlen = 0;\n\t\tret = NULL;\n\t}\n\n\tif (out_len != NULL) {\n\t\t*out_len = len;\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL const char *duk_require_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\tif (out_len) {\n\t\t*out_len = DUK_HSTRING_GET_BYTELEN(h);\n\t}\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_INTERNAL const char *duk_require_lstring_notsymbol(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hstring_notsymbol(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\tif (out_len) {\n\t\t*out_len = DUK_HSTRING_GET_BYTELEN(h);\n\t}\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_EXTERNAL const char *duk_get_string(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\treturn NULL;\n\t}\n}\n\nDUK_EXTERNAL const char *duk_opt_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\tif (out_len != NULL) {\n\t\t\t*out_len = def_len;\n\t\t}\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_lstring(thr, idx, out_len);\n}\n\nDUK_EXTERNAL const char *duk_opt_string(duk_hthread *thr, duk_idx_t idx, const char *def_ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_string(thr, idx);\n}\n\nDUK_EXTERNAL const char *duk_get_lstring_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len) {\n\tduk_hstring *h;\n\tconst char *ret;\n\tduk_size_t len;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\t\tret = (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\tlen = def_len;\n\t\tret = def_ptr;\n\t}\n\n\tif (out_len != NULL) {\n\t\t*out_len = len;\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL const char *duk_get_string_default(duk_hthread *thr, duk_idx_t idx, const char *def_value) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\treturn def_value;\n\t}\n}\n\nDUK_INTERNAL const char *duk_get_string_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring_notsymbol(thr, idx);\n\tif (h) {\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\treturn NULL;\n\t}\n}\n\nDUK_EXTERNAL const char *duk_require_string(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_require_lstring(thr, idx, NULL);\n}\n\nDUK_INTERNAL const char *duk_require_string_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hstring_notsymbol(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_EXTERNAL void duk_require_object(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_OBJECT(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"object\", DUK_STR_NOT_OBJECT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_LOCAL void *duk__get_pointer_raw(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tduk_tval *tv;\n\tvoid *p;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (!DUK_TVAL_IS_POINTER(tv)) {\n\t\treturn def_value;\n\t}\n\n\tp = DUK_TVAL_GET_POINTER(tv);  /* may be NULL */\n\treturn p;\n}\n\nDUK_EXTERNAL void *duk_get_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_pointer_raw(thr, idx, NULL /*def_value*/);\n}\n\nDUK_EXTERNAL void *duk_opt_pointer(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_pointer(thr, idx);\n}\n\nDUK_EXTERNAL void *duk_get_pointer_default(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_pointer_raw(thr, idx, def_value);\n}\n\nDUK_EXTERNAL void *duk_require_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *p;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: here we must be wary of the fact that a pointer may be\n\t * valid and be a NULL.\n\t */\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_POINTER(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"pointer\", DUK_STR_NOT_POINTER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\tp = DUK_TVAL_GET_POINTER(tv);  /* may be NULL */\n\treturn p;\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL void *duk_get_voidptr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_heaphdr *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (!DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\treturn NULL;\n\t}\n\n\th = DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(h != NULL);\n\treturn (void *) h;\n}\n#endif\n\nDUK_LOCAL void *duk__get_buffer_helper(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size, duk_bool_t throw_flag) {\n\tduk_hbuffer *h;\n\tvoid *ret;\n\tduk_size_t len;\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tif (out_size != NULL) {\n\t\t*out_size = 0;\n\t}\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_LIKELY(DUK_TVAL_IS_BUFFER(tv))) {\n\t\th = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tlen = DUK_HBUFFER_GET_SIZE(h);\n\t\tret = DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);\n\t} else {\n\t\tif (throw_flag) {\n\t\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"buffer\", DUK_STR_NOT_BUFFER);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t\tlen = def_size;\n\t\tret = def_ptr;\n\t}\n\n\tif (out_size != NULL) {\n\t\t*out_size = len;\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL void *duk_get_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_buffer_helper(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/);\n}\n\nDUK_EXTERNAL void *duk_opt_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\tif (out_size != NULL) {\n\t\t\t*out_size = def_size;\n\t\t}\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_buffer(thr, idx, out_size);\n}\n\nDUK_EXTERNAL void *duk_get_buffer_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_buffer_helper(thr, idx, out_size, def_ptr, def_len, 0 /*throw_flag*/);\n}\n\nDUK_EXTERNAL void *duk_require_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_buffer_helper(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 1 /*throw_flag*/);\n}\n\n/* Get the active buffer data area for a plain buffer or a buffer object.\n * Return NULL if the the value is not a buffer.  Note that a buffer may\n * have a NULL data pointer when its size is zero, the optional 'out_isbuffer'\n * argument allows caller to detect this reliably.\n */\nDUK_INTERNAL void *duk_get_buffer_data_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size, duk_bool_t throw_flag, duk_bool_t *out_isbuffer) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (out_isbuffer != NULL) {\n\t\t*out_isbuffer = 0;\n\t}\n\tif (out_size != NULL) {\n\t\t*out_size = def_size;\n\t}\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (out_size != NULL) {\n\t\t\t*out_size = DUK_HBUFFER_GET_SIZE(h);\n\t\t}\n\t\tif (out_isbuffer != NULL) {\n\t\t\t*out_isbuffer = 1;\n\t\t}\n\t\treturn (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);  /* may be NULL (but only if size is 0) */\n\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\telse if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\t/* XXX: this is probably a useful shared helper: for a\n\t\t\t * duk_hbufobj, get a validated buffer pointer/length.\n\t\t\t */\n\t\t\tduk_hbufobj *h_bufobj = (duk_hbufobj *) h;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t\t\tif (h_bufobj->buf != NULL &&\n\t\t\t    DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {\n\t\t\t\tduk_uint8_t *p;\n\n\t\t\t\tp = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf);\n\t\t\t\tif (out_size != NULL) {\n\t\t\t\t\t*out_size = (duk_size_t) h_bufobj->length;\n\t\t\t\t}\n\t\t\t\tif (out_isbuffer != NULL) {\n\t\t\t\t\t*out_isbuffer = 1;\n\t\t\t\t}\n\t\t\t\treturn (void *) (p + h_bufobj->offset);\n\t\t\t}\n\t\t\t/* if slice not fully valid, treat as error */\n\t\t}\n\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\tif (throw_flag) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"buffer\", DUK_STR_NOT_BUFFER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn def_ptr;\n}\n\nDUK_EXTERNAL void *duk_get_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_buffer_data_raw(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, NULL);\n}\n\nDUK_EXTERNAL void *duk_get_buffer_data_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_buffer_data_raw(thr, idx, out_size, def_ptr, def_size, 0 /*throw_flag*/, NULL);\n}\n\nDUK_EXTERNAL void *duk_opt_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\tif (out_size != NULL) {\n\t\t\t*out_size = def_size;\n\t\t}\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_buffer_data(thr, idx, out_size);\n}\n\nDUK_EXTERNAL void *duk_require_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_buffer_data_raw(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 1 /*throw_flag*/, NULL);\n}\n\n/* Raw helper for getting a value from the stack, checking its tag.\n * The tag cannot be a number because numbers don't have an internal\n * tag in the packed representation.\n */\n\nDUK_LOCAL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t tag) {\n\tduk_tval *tv;\n\tduk_heaphdr *ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_GET_TAG(tv) != tag) {\n\t\treturn (duk_heaphdr *) NULL;\n\t}\n\n\tret = DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(ret != NULL);  /* tagged null pointers should never occur */\n\treturn ret;\n\n}\n\nDUK_INTERNAL duk_hstring *duk_get_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n}\n\nDUK_INTERNAL duk_hstring *duk_get_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n\tif (DUK_UNLIKELY(h && DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\treturn NULL;\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_require_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"string\", DUK_STR_NOT_STRING);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_require_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n\tif (DUK_UNLIKELY(h == NULL || DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"string\", DUK_STR_NOT_STRING);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_get_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n}\n\nDUK_INTERNAL duk_hobject *duk_require_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"object\", DUK_STR_NOT_OBJECT);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hbuffer *duk_get_hbuffer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn (duk_hbuffer *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_BUFFER);\n}\n\nDUK_INTERNAL duk_hbuffer *duk_require_hbuffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hbuffer *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_BUFFER);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"buffer\", DUK_STR_NOT_BUFFER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hthread *duk_get_hthread(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_THREAD(h))) {\n\t\th = NULL;\n\t}\n\treturn (duk_hthread *) h;\n}\n\nDUK_INTERNAL duk_hthread *duk_require_hthread(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_THREAD(h)))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"thread\", DUK_STR_NOT_THREAD);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn (duk_hthread *) h;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_get_hcompfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_COMPFUNC(h))) {\n\t\th = NULL;\n\t}\n\treturn (duk_hcompfunc *) h;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_require_hcompfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_COMPFUNC(h)))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"compiledfunction\", DUK_STR_NOT_COMPFUNC);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn (duk_hcompfunc *) h;\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_get_hnatfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_NATFUNC(h))) {\n\t\th = NULL;\n\t}\n\treturn (duk_hnatfunc *) h;\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_require_hnatfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_NATFUNC(h)))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"nativefunction\", DUK_STR_NOT_NATFUNC);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn (duk_hnatfunc *) h;\n}\n\nDUK_EXTERNAL duk_c_function duk_get_c_function(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\tduk_hnatfunc *f;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_OBJECT(tv))) {\n\t\treturn NULL;\n\t}\n\th = DUK_TVAL_GET_OBJECT(tv);\n\tDUK_ASSERT(h != NULL);\n\n\tif (DUK_UNLIKELY(!DUK_HOBJECT_IS_NATFUNC(h))) {\n\t\treturn NULL;\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_HAS_NATFUNC(h));\n\tf = (duk_hnatfunc *) h;\n\n\treturn f->func;\n}\n\nDUK_EXTERNAL duk_c_function duk_opt_c_function(duk_hthread *thr, duk_idx_t idx, duk_c_function def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_c_function(thr, idx);\n}\n\nDUK_EXTERNAL duk_c_function duk_get_c_function_default(duk_hthread *thr, duk_idx_t idx, duk_c_function def_value) {\n\tduk_c_function ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_c_function(thr, idx);\n\tif (ret != NULL) {\n\t\treturn ret;\n\t}\n\n\treturn def_value;\n}\n\nDUK_EXTERNAL duk_c_function duk_require_c_function(duk_hthread *thr, duk_idx_t idx) {\n\tduk_c_function ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_c_function(thr, idx);\n\tif (DUK_UNLIKELY(!ret)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"nativefunction\", DUK_STR_NOT_NATFUNC);\n\t\tDUK_WO_NORETURN(return ret;);\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_require_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tif (DUK_UNLIKELY(!duk_is_function(thr, idx))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"function\", DUK_STR_NOT_FUNCTION);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_EXTERNAL void duk_require_constructable(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hobject_accept_mask(thr, idx, DUK_TYPE_MASK_LIGHTFUNC);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_HAS_CONSTRUCTABLE(h))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"constructable\", DUK_STR_NOT_CONSTRUCTABLE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\t/* Lightfuncs (h == NULL) are constructable. */\n}\n\nDUK_EXTERNAL duk_hthread *duk_get_context(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_get_hthread(thr, idx);\n}\n\nDUK_EXTERNAL duk_hthread *duk_require_context(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_require_hthread(thr, idx);\n}\n\nDUK_EXTERNAL duk_hthread *duk_opt_context(duk_hthread *thr, duk_idx_t idx, duk_hthread *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_context(thr, idx);\n}\n\nDUK_EXTERNAL duk_hthread *duk_get_context_default(duk_hthread *thr, duk_idx_t idx, duk_hthread *def_value) {\n\tduk_hthread *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_context(thr, idx);\n\tif (ret != NULL) {\n\t\treturn ret;\n\t}\n\n\treturn def_value;\n}\n\nDUK_EXTERNAL void *duk_get_heapptr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_HEAP_ALLOCATED(tv))) {\n\t\treturn (void *) NULL;\n\t}\n\n\tret = (void *) DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(ret != NULL);\n\treturn ret;\n}\n\nDUK_EXTERNAL void *duk_opt_heapptr(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_heapptr(thr, idx);\n}\n\nDUK_EXTERNAL void *duk_get_heapptr_default(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tvoid *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_heapptr(thr, idx);\n\tif (ret != NULL) {\n\t\treturn ret;\n\t}\n\n\treturn def_value;\n}\n\nDUK_EXTERNAL void *duk_require_heapptr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_HEAP_ALLOCATED(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"heapobject\", DUK_STR_UNEXPECTED_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\tret = (void *) DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(ret != NULL);\n\treturn ret;\n}\n\n/* Internal helper for getting/requiring a duk_hobject with possible promotion. */\nDUK_LOCAL duk_hobject *duk__get_hobject_promote_mask_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tduk_uint_t val_mask;\n\tduk_hobject *res;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tres = duk_get_hobject(thr, idx);  /* common case, not promoted */\n\tif (DUK_LIKELY(res != NULL)) {\n\t\tDUK_ASSERT(res != NULL);\n\t\treturn res;\n\t}\n\n\tval_mask = duk_get_type_mask(thr, idx);\n\tif (val_mask & type_mask) {\n\t\tif (type_mask & DUK_TYPE_MASK_PROMOTE) {\n\t\t\tres = duk_to_hobject(thr, idx);\n\t\t\tDUK_ASSERT(res != NULL);\n\t\t\treturn res;\n\t\t} else {\n\t\t\treturn NULL;  /* accept without promoting */\n\t\t}\n\t}\n\n\tif (type_mask & DUK_TYPE_MASK_THROW) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"object\", DUK_STR_NOT_OBJECT);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn NULL;\n}\n\n/* Get a duk_hobject * at 'idx'; if the value is not an object but matches the\n * supplied 'type_mask', promote it to an object and return the duk_hobject *.\n * This is useful for call sites which want an object but also accept a plain\n * buffer and/or a lightfunc which gets automatically promoted to an object.\n * Return value is NULL if value is neither an object nor a plain type allowed\n * by the mask.\n */\nDUK_INTERNAL duk_hobject *duk_get_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_PROMOTE);\n}\n\n/* Like duk_get_hobject_promote_mask() but throw a TypeError instead of\n * returning a NULL.\n */\nDUK_INTERNAL duk_hobject *duk_require_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_THROW | DUK_TYPE_MASK_PROMOTE);\n}\n\n/* Require a duk_hobject * at 'idx'; if the value is not an object but matches the\n * supplied 'type_mask', return a NULL instead.  Otherwise throw a TypeError.\n */\nDUK_INTERNAL duk_hobject *duk_require_hobject_accept_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_THROW);\n}\n\nDUK_INTERNAL duk_hobject *duk_get_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_DISABLE(classnum >= 0);  /* unsigned */\n\tDUK_ASSERT(classnum <= DUK_HOBJECT_CLASS_MAX);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h) != classnum)) {\n\t\th = NULL;\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_require_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_DISABLE(classnum >= 0);  /* unsigned */\n\tDUK_ASSERT(classnum <= DUK_HOBJECT_CLASS_MAX);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h) == classnum))) {\n\t\tduk_hstring *h_class;\n\t\th_class = DUK_HTHREAD_GET_STRING(thr, DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum));\n\t\tDUK_UNREF(h_class);\n\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, (const char *) DUK_HSTRING_GET_DATA(h_class), DUK_STR_UNEXPECTED_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_EXTERNAL duk_size_t duk_get_length(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\tcase DUK_TAG_BOOLEAN:\n\tcase DUK_TAG_POINTER:\n\t\treturn 0;\n#if defined(DUK_USE_PREFER_SIZE)\n\t/* String and buffer have a virtual non-configurable .length property\n\t * which is within size_t range so it can be looked up without specific\n\t * type checks.  Lightfuncs inherit from %NativeFunctionPrototype%\n\t * which provides an inherited .length accessor; it could be overwritten\n\t * to produce unexpected types or values, but just number convert and\n\t * duk_size_t cast for now.\n\t */\n\tcase DUK_TAG_STRING:\n\tcase DUK_TAG_BUFFER:\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tduk_size_t ret;\n\t\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n\t\tret = (duk_size_t) duk_to_number_m1(thr);\n\t\tduk_pop_unsafe(thr);\n\t\treturn ret;\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn (duk_size_t) DUK_HSTRING_GET_CHARLEN(h);\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (duk_size_t) DUK_HBUFFER_GET_SIZE(h);\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* We could look up the length from the lightfunc duk_tval,\n\t\t * but since Duktape 2.2 lightfunc .length comes from\n\t\t * %NativeFunctionPrototype% which can be overridden, so\n\t\t * look up the property explicitly.\n\t\t */\n\t\tduk_size_t ret;\n\t\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n\t\tret = (duk_size_t) duk_to_number_m1(thr);\n\t\tduk_pop_unsafe(thr);\n\t\treturn ret;\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (duk_size_t) duk_hobject_get_length(thr, h);\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* number or 'unused' */\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv) || DUK_TVAL_IS_UNUSED(tv));\n\t\treturn 0;\n\t}\n\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  duk_known_xxx() helpers\n *\n *  Used internally when we're 100% sure that a certain index is valid and\n *  contains an object of a certain type.  For example, if we duk_push_object()\n *  we can then safely duk_known_hobject(thr, -1).  These helpers just assert\n *  for the index and type, and if the assumptions are not valid, memory unsafe\n *  behavior happens.\n */\n\nDUK_LOCAL duk_heaphdr *duk__known_heaphdr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_heaphdr *h;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tif (idx < 0) {\n\t\ttv = thr->valstack_top + idx;\n\t} else {\n\t\ttv = thr->valstack_bottom + idx;\n\t}\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\tDUK_ASSERT(tv < thr->valstack_top);\n\th = DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(h != NULL);\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_known_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hstring(thr, idx) != NULL);\n\treturn (duk_hstring *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hobject *duk_known_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hobject(thr, idx) != NULL);\n\treturn (duk_hobject *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hbuffer *duk_known_hbuffer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hbuffer(thr, idx) != NULL);\n\treturn (duk_hbuffer *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_known_hcompfunc(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hcompfunc(thr, idx) != NULL);\n\treturn (duk_hcompfunc *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_known_hnatfunc(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hnatfunc(thr, idx) != NULL);\n\treturn (duk_hnatfunc *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_EXTERNAL void duk_set_length(duk_hthread *thr, duk_idx_t idx, duk_size_t len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_normalize_index(thr, idx);\n\tduk_push_uint(thr, (duk_uint_t) len);\n\tduk_put_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n}\n\n/*\n *  Conversions and coercions\n *\n *  The conversion/coercions are in-place operations on the value stack.\n *  Some operations are implemented here directly, while others call a\n *  helper in duk_js_ops.c after validating arguments.\n */\n\n/* E5 Section 8.12.8 */\n\nDUK_LOCAL duk_bool_t duk__defaultvalue_coerce_attempt(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t func_stridx) {\n\tif (duk_get_prop_stridx(thr, idx, func_stridx)) {\n\t\t/* [ ... func ] */\n\t\tif (duk_is_callable(thr, -1)) {\n\t\t\tduk_dup(thr, idx);         /* -> [ ... func this ] */\n\t\t\tduk_call_method(thr, 0);     /* -> [ ... retval ] */\n\t\t\tif (duk_is_primitive(thr, -1)) {\n\t\t\t\tduk_replace(thr, idx);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\t/* [ ... retval ]; popped below */\n\t\t}\n\t}\n\tduk_pop_unsafe(thr);  /* [ ... func/retval ] -> [ ... ] */\n\treturn 0;\n}\n\nDUK_EXTERNAL void duk_to_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n}\n\nDUK_EXTERNAL void duk_to_null(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tDUK_TVAL_SET_NULL_UPDREF(thr, tv);  /* side effects */\n}\n\n/* E5 Section 9.1 */\nDUK_LOCAL const char * const duk__toprim_hint_strings[3] = {\n\t\"default\", \"string\", \"number\"\n};\nDUK_LOCAL void duk__to_primitive_helper(duk_hthread *thr, duk_idx_t idx, duk_int_t hint, duk_bool_t check_symbol) {\n\t/* Inline initializer for coercers[] is not allowed by old compilers like BCC. */\n\tduk_small_uint_t coercers[2];\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(hint == DUK_HINT_NONE || hint == DUK_HINT_NUMBER || hint == DUK_HINT_STRING);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\t/* If already primitive, return as is. */\n\tif (!duk_check_type_mask(thr, idx, DUK_TYPE_MASK_OBJECT |\n\t                                   DUK_TYPE_MASK_LIGHTFUNC |\n\t                                   DUK_TYPE_MASK_BUFFER)) {\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* duk_to_string() relies on this behavior */\n\t\treturn;\n\t}\n\n\t/* @@toPrimitive lookup.  Also do for plain buffers and lightfuncs\n\t * which mimic objects.\n\t */\n\tif (check_symbol && duk_get_method_stridx(thr, idx, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE)) {\n\t\tDUK_ASSERT(hint >= 0 && (duk_size_t) hint < sizeof(duk__toprim_hint_strings) / sizeof(const char *));\n\t\tduk_dup(thr, idx);\n\t\tduk_push_string(thr, duk__toprim_hint_strings[hint]);\n\t\tduk_call_method(thr, 1);  /* [ ... method value hint ] -> [ ... res] */\n\t\tif (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT |\n\t                                         DUK_TYPE_MASK_LIGHTFUNC |\n\t\t                                 DUK_TYPE_MASK_BUFFER)) {\n\t\t\tgoto fail;\n\t\t}\n\t\tduk_replace(thr, idx);\n\t\treturn;\n\t}\n\n\t/* Objects are coerced based on E5 specification.\n\t * Lightfuncs are coerced because they behave like\n\t * objects even if they're internally a primitive\n\t * type.  Same applies to plain buffers, which behave\n\t * like ArrayBuffer objects since Duktape 2.x.\n\t */\n\n\t/* Hint magic for Date is unnecessary in ES2015 because of\n\t * Date.prototype[@@toPrimitive].  However, it is needed if\n\t * symbol support is not enabled.\n\t */\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\tif (hint == DUK_HINT_NONE) {\n\t\thint = DUK_HINT_NUMBER;\n\t}\n#else  /* DUK_USE_SYMBOL_BUILTIN */\n\tif (hint == DUK_HINT_NONE) {\n\t\tduk_small_uint_t class_number;\n\n\t\tclass_number = duk_get_class_number(thr, idx);\n\t\tif (class_number == DUK_HOBJECT_CLASS_DATE) {\n\t\t\thint = DUK_HINT_STRING;\n\t\t} else {\n\t\t\thint = DUK_HINT_NUMBER;\n\t\t}\n\t}\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n\n\tcoercers[0] = DUK_STRIDX_VALUE_OF;\n\tcoercers[1] = DUK_STRIDX_TO_STRING;\n\tif (hint == DUK_HINT_STRING) {\n\t\tcoercers[0] = DUK_STRIDX_TO_STRING;\n\t\tcoercers[1] = DUK_STRIDX_VALUE_OF;\n\t}\n\n\tif (duk__defaultvalue_coerce_attempt(thr, idx, coercers[0])) {\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* duk_to_string() relies on this behavior */\n\t\treturn;\n\t}\n\n\tif (duk__defaultvalue_coerce_attempt(thr, idx, coercers[1])) {\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* duk_to_string() relies on this behavior */\n\t\treturn;\n\t}\n\n fail:\n\tDUK_ERROR_TYPE(thr, DUK_STR_TOPRIMITIVE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_to_primitive(duk_hthread *thr, duk_idx_t idx, duk_int_t hint) {\n\tduk__to_primitive_helper(thr, idx, hint, 1 /*check_symbol*/);\n}\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL void duk_to_primitive_ordinary(duk_hthread *thr, duk_idx_t idx, duk_int_t hint) {\n\tduk__to_primitive_helper(thr, idx, hint, 0 /*check_symbol*/);\n}\n#endif\n\n/* E5 Section 9.2 */\nDUK_EXTERNAL duk_bool_t duk_to_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_bool_t val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tval = duk_js_toboolean(tv);\n\tDUK_ASSERT(val == 0 || val == 1);\n\n\t/* Note: no need to re-lookup tv, conversion is side effect free. */\n\tDUK_ASSERT(tv != NULL);\n\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv, val);  /* side effects */\n\treturn val;\n}\n\nDUK_INTERNAL duk_bool_t duk_to_boolean_top_pop(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_bool_t val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tval = duk_js_toboolean(tv);\n\tDUK_ASSERT(val == 0 || val == 1);\n\n\tduk_pop_unsafe(thr);\n\treturn val;\n}\n\nDUK_EXTERNAL duk_double_t duk_to_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_double_t d;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: No need to normalize; the whole operation could be inlined here to\n\t * avoid 'tv' re-lookup.\n\t */\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\td = duk_js_tonumber(thr, tv);  /* XXX: fastint coercion? now result will always be a non-fastint */\n\n\t/* ToNumber() may have side effects so must relookup 'tv'. */\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d);  /* side effects */\n\treturn d;\n}\n\nDUK_INTERNAL duk_double_t duk_to_number_m1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_number(thr, -1);\n}\nDUK_INTERNAL duk_double_t duk_to_number_m2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_number(thr, -2);\n}\n\nDUK_INTERNAL duk_double_t duk_to_number_tval(duk_hthread *thr, duk_tval *tv) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_double_t res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_tval(thr, tv);\n\tres = duk_to_number_m1(thr);\n\tduk_pop_unsafe(thr);\n\treturn res;\n#else\n\tduk_double_t res;\n\tduk_tval *tv_dst;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ASSERT_SPACE();\n\n\ttv_dst = thr->valstack_top++;\n\tDUK_TVAL_SET_TVAL(tv_dst, tv);\n\tDUK_TVAL_INCREF(thr, tv_dst);  /* decref not necessary */\n\tres = duk_to_number_m1(thr);  /* invalidates tv_dst */\n\n\ttv_dst = --thr->valstack_top;\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_dst));\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv_dst));  /* plain number */\n\tDUK_TVAL_SET_UNDEFINED(tv_dst);  /* valstack init policy */\n\n\treturn res;\n#endif\n}\n\n/* XXX: combine all the integer conversions: they share everything\n * but the helper function for coercion.\n */\n\ntypedef duk_double_t (*duk__toint_coercer)(duk_hthread *thr, duk_tval *tv);\n\nDUK_LOCAL duk_double_t duk__to_int_uint_helper(duk_hthread *thr, duk_idx_t idx, duk__toint_coercer coerce_func) {\n\tduk_tval *tv;\n\tduk_double_t d;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_FASTINT)\n\t/* If argument is a fastint, guarantee that it remains one.\n\t * There's no downgrade check for other cases.\n\t */\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\t/* XXX: Unnecessary conversion back and forth. */\n\t\treturn (duk_double_t) DUK_TVAL_GET_FASTINT(tv);\n\t}\n#endif\n\td = coerce_func(thr, tv);\n\n\t/* XXX: fastint? */\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d);  /* side effects */\n\treturn d;\n}\n\nDUK_EXTERNAL duk_int_t duk_to_int(duk_hthread *thr, duk_idx_t idx) {\n\t/* Value coercion (in stack): ToInteger(), E5 Section 9.4,\n\t * API return value coercion: custom.\n\t */\n\tDUK_ASSERT_API_ENTRY(thr);\n\t(void) duk__to_int_uint_helper(thr, idx, duk_js_tointeger);\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_to_uint(duk_hthread *thr, duk_idx_t idx) {\n\t/* Value coercion (in stack): ToInteger(), E5 Section 9.4,\n\t * API return value coercion: custom.\n\t */\n\tDUK_ASSERT_API_ENTRY(thr);\n\t(void) duk__to_int_uint_helper(thr, idx, duk_js_tointeger);\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_int32_t duk_to_int32(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_int32_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tret = duk_js_toint32(thr, tv);\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_I32_UPDREF(thr, tv, ret);  /* side effects */\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_uint32_t duk_to_uint32(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_uint32_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tret = duk_js_touint32(thr, tv);\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_U32_UPDREF(thr, tv, ret);  /* side effects */\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_uint16_t duk_to_uint16(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_uint16_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tret = duk_js_touint16(thr, tv);\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_U32_UPDREF(thr, tv, ret);  /* side effects */\n\treturn ret;\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Special coercion for Uint8ClampedArray. */\nDUK_INTERNAL duk_uint8_t duk_to_uint8clamped(duk_hthread *thr, duk_idx_t idx) {\n\tduk_double_t d;\n\tduk_double_t t;\n\tduk_uint8_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: Simplify this algorithm, should be possible to come up with\n\t * a shorter and faster algorithm by inspecting IEEE representation\n\t * directly.\n\t */\n\n\td = duk_to_number(thr, idx);\n\tif (d <= 0.0) {\n\t\treturn 0;\n\t} else if (d >= 255) {\n\t\treturn 255;\n\t} else if (DUK_ISNAN(d)) {\n\t\t/* Avoid NaN-to-integer coercion as it is compiler specific. */\n\t\treturn 0;\n\t}\n\n\tt = d - DUK_FLOOR(d);\n\tif (t == 0.5) {\n\t\t/* Exact halfway, round to even. */\n\t\tret = (duk_uint8_t) d;\n\t\tret = (ret + 1) & 0xfe;  /* Example: d=3.5, t=0.5 -> ret = (3 + 1) & 0xfe = 4 & 0xfe = 4\n\t\t                          * Example: d=4.5, t=0.5 -> ret = (4 + 1) & 0xfe = 5 & 0xfe = 4\n\t\t                          */\n\t} else {\n\t\t/* Not halfway, round to nearest. */\n\t\tret = (duk_uint8_t) (d + 0.5);\n\t}\n\treturn ret;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_EXTERNAL const char *duk_to_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_to_string(thr, idx);\n\tDUK_ASSERT(duk_is_string(thr, idx));\n\treturn duk_require_lstring(thr, idx, out_len);\n}\n\nDUK_LOCAL duk_ret_t duk__safe_to_string_raw(duk_hthread *thr, void *udata) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(udata);\n\n\t(void) duk_to_string(thr, -1);\n\treturn 1;\n}\n\nDUK_EXTERNAL const char *duk_safe_to_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\t/* We intentionally ignore the duk_safe_call() return value and only\n\t * check the output type.  This way we don't also need to check that\n\t * the returned value is indeed a string in the success case.\n\t */\n\n\tduk_dup(thr, idx);\n\t(void) duk_safe_call(thr, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\tif (!duk_is_string(thr, -1)) {\n\t\t/* Error: try coercing error to string once. */\n\t\t(void) duk_safe_call(thr, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\t\tif (!duk_is_string(thr, -1)) {\n\t\t\t/* Double error */\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_ERROR);\n\t\t} else {\n\t\t\t;\n\t\t}\n\t} else {\n\t\t/* String; may be a symbol, accepted. */\n\t\t;\n\t}\n\tDUK_ASSERT(duk_is_string(thr, -1));\n\n\tduk_replace(thr, idx);\n\tDUK_ASSERT(duk_get_string(thr, idx) != NULL);\n\treturn duk_get_lstring(thr, idx, out_len);\n}\n\nDUK_EXTERNAL const char *duk_to_stacktrace(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tidx = duk_require_normalize_index(thr, idx);\n\n\t/* The expected argument to the call is an Error object.  The stack\n\t * trace is extracted without an inheritance-based instanceof check\n\t * so that one can also extract the stack trace of a foreign error\n\t * created in another Realm.  Accept only a string .stack property.\n\t */\n\tif (duk_is_object(thr, idx)) {\n\t\t(void) duk_get_prop_string(thr, idx, \"stack\");\n\t\tif (duk_is_string(thr, -1)) {\n\t\t\tduk_replace(thr, idx);\n\t\t} else {\n\t\t\tduk_pop(thr);\n\t\t}\n\t}\n\n\treturn duk_to_string(thr, idx);\n}\n\nDUK_LOCAL duk_ret_t duk__safe_to_stacktrace_raw(duk_hthread *thr, void *udata) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(udata);\n\n\t(void) duk_to_stacktrace(thr, -1);\n\n\treturn 1;\n}\n\nDUK_EXTERNAL const char *duk_safe_to_stacktrace(duk_hthread *thr, duk_idx_t idx) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tidx = duk_require_normalize_index(thr, idx);\n\n\tduk_dup(thr, idx);\n\trc = duk_safe_call(thr, duk__safe_to_stacktrace_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\tif (rc != 0) {\n\t\t/* Coercion failed.  Try to coerce the coercion itself error\n\t\t * to a stack trace once.  If that also fails, return a fixed,\n\t\t * preallocated 'Error' string to avoid potential infinite loop.\n\t\t */\n\t\trc = duk_safe_call(thr, duk__safe_to_stacktrace_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\t\tif (rc != 0) {\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_ERROR);\n\t\t}\n\t}\n\tduk_replace(thr, idx);\n\n\treturn duk_get_string(thr, idx);\n}\n\nDUK_INTERNAL duk_hstring *duk_to_property_key_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_to_primitive(thr, idx, DUK_HINT_STRING);  /* needed for e.g. Symbol objects */\n\th = duk_get_hstring(thr, idx);\n\tif (h == NULL) {\n\t\t/* The \"is string?\" check may seem unnecessary, but as things\n\t\t * are duk_to_hstring() invokes ToString() which fails for\n\t\t * symbols.  But since symbols are already strings for Duktape\n\t\t * C API, we check for that before doing the coercion.\n\t\t */\n\t\th = duk_to_hstring(thr, idx);\n\t}\n\tDUK_ASSERT(h != NULL);\n\treturn h;\n}\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* only needed by debugger for now */\nDUK_INTERNAL duk_hstring *duk_safe_to_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_safe_to_string(thr, idx);\n\tDUK_ASSERT(duk_is_string(thr, idx));\n\tDUK_ASSERT(duk_get_hstring(thr, idx) != NULL);\n\treturn duk_known_hstring(thr, idx);\n}\n#endif\n\n/* Push Object.prototype.toString() output for 'tv'. */\n#if 0  /* See XXX note why this variant doesn't work. */\nDUK_INTERNAL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects) {\n\tduk_uint_t stridx_bidx = 0;  /* (prototype_bidx << 16) + default_tag_stridx */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Conceptually for any non-undefined/null value we should do a\n\t * ToObject() coercion and look up @@toStringTag (from the object\n\t * prototype) to see if a custom tag should be used.  Avoid the\n\t * actual conversion by doing a prototype lookup without the object\n\t * coercion.  However, see problem below.\n\t */\n\n\tduk_push_literal(thr, \"[object \");  /* -> [ ... \"[object\" ] */\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:  /* Treat like 'undefined', shouldn't happen. */\n\tcase DUK_TAG_UNDEFINED: {\n\t\tstridx_bidx = DUK_STRIDX_UC_UNDEFINED;\n\t\tgoto use_stridx;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tstridx_bidx = DUK_STRIDX_UC_NULL;\n\t\tgoto use_stridx;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tstridx_bidx = (DUK_BIDX_BOOLEAN_PROTOTYPE << 16) + DUK_STRIDX_UC_BOOLEAN;\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tstridx_bidx = (DUK_BIDX_POINTER_PROTOTYPE << 16) + DUK_STRIDX_UC_POINTER;\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tstridx_bidx = (DUK_BIDX_FUNCTION_PROTOTYPE << 16) + DUK_STRIDX_UC_FUNCTION;\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\t/* Even without DUK_USE_SYMBOL_BUILTIN the Symbol\n\t\t\t * prototype exists so we can lookup @@toStringTag\n\t\t\t * and provide [object Symbol] for symbol values\n\t\t\t * created from C code.\n\t\t\t */\n\t\t\tstridx_bidx = (DUK_BIDX_SYMBOL_PROTOTYPE << 16) + DUK_STRIDX_UC_SYMBOL;\n\t\t} else {\n\t\t\tstridx_bidx = (DUK_BIDX_STRING_PROTOTYPE << 16) + DUK_STRIDX_UC_STRING;\n\t\t}\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_push_tval(thr, tv);\n\t\tstridx_bidx = 0xffffffffUL;  /* Marker value. */\n\t\tgoto use_pushed_object;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\tstridx_bidx = (DUK_BIDX_UINT8ARRAY_PROTOTYPE << 16) + DUK_STRIDX_UINT8_ARRAY;\n\t\tgoto use_proto_bidx;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\t/* Fall through to generic number case. */\n#endif\n\tdefault: {\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));  /* number (maybe fastint) */\n\t\tstridx_bidx = (DUK_BIDX_NUMBER_PROTOTYPE << 16) + DUK_STRIDX_UC_NUMBER;\n\t\tgoto use_proto_bidx;\n\t}\n\t}\n\tDUK_ASSERT(0);  /* Never here. */\n\n use_proto_bidx:\n\tDUK_ASSERT_BIDX_VALID((stridx_bidx >> 16) & 0xffffUL);\n\tduk_push_hobject(thr, thr->builtins[(stridx_bidx >> 16) & 0xffffUL]);\n\t/* Fall through. */\n\n use_pushed_object:\n\t/* [ ... \"[object\" obj ] */\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t/* XXX: better handling with avoid_side_effects == 1; lookup tval\n\t * without Proxy or getter side effects, and use it in sanitized\n\t * form if it's a string.\n\t */\n\tif (!avoid_side_effects) {\n\t\t/* XXX: The problem with using the prototype object as the\n\t\t * lookup base is that if @@toStringTag is a getter, its\n\t\t * 'this' binding must be the ToObject() coerced input value,\n\t\t * not the prototype object of the type.\n\t\t */\n\t\t(void) duk_get_prop_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG);\n\t\tif (duk_is_string_notsymbol(thr, -1)) {\n\t\t\tduk_remove_m2(thr);\n\t\t\tgoto finish;\n\t\t}\n\t\tduk_pop_unsafe(thr);\n\t}\n#endif\n\n\tif (stridx_bidx == 0xffffffffUL) {\n\t\tduk_hobject *h_obj;\n\t\tduk_small_uint_t classnum;\n\n\t\th_obj = duk_known_hobject(thr, -1);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tclassnum = DUK_HOBJECT_GET_CLASS_NUMBER(h_obj);\n\t\tstridx_bidx = DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum);\n\t} else {\n\t\t/* stridx_bidx already has the desired fallback stridx. */\n\t\t;\n\t}\n\tduk_pop_unsafe(thr);\n\t/* Fall through. */\n\n use_stridx:\n\t/* [ ... \"[object\" ] */\n\tduk_push_hstring_stridx(thr, stridx_bidx & 0xffffUL);\n\n finish:\n\t/* [ ... \"[object\" tag ] */\n\tduk_push_literal(thr, \"]\");\n\tduk_concat(thr, 3);  /* [ ... \"[object\" tag \"]\" ] -> [ ... res ] */\n}\n#endif  /* 0 */\n\nDUK_INTERNAL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects) {\n\tduk_hobject *h_obj;\n\tduk_small_uint_t classnum;\n\tduk_small_uint_t stridx;\n\tduk_tval tv_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\t/* Stabilize 'tv', duk_push_literal() may trigger side effects. */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv);\n\ttv = &tv_tmp;\n\n\t/* Conceptually for any non-undefined/null value we should do a\n\t * ToObject() coercion and look up @@toStringTag (from the object\n\t * prototype) to see if a custom result should be used.  We'd like to\n\t * avoid the actual conversion, but even for primitive types the\n\t * prototype may have @@toStringTag.  What's worse, the @@toStringTag\n\t * property may be a getter that must get the object coerced value\n\t * (not the prototype) as its 'this' binding.\n\t *\n\t * For now, do an actual object coercion.  This could be avoided by\n\t * doing a side effect free lookup to see if a getter would be invoked.\n\t * If not, the value can be read directly and the object coercion could\n\t * be avoided.  This may not be worth it in practice, because\n\t * Object.prototype.toString() is usually not performance critical.\n\t */\n\n\tduk_push_literal(thr, \"[object \");  /* -> [ ... \"[object\" ] */\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:  /* Treat like 'undefined', shouldn't happen. */\n\tcase DUK_TAG_UNDEFINED: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_UNDEFINED);\n\t\tgoto finish;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_NULL);\n\t\tgoto finish;\n\t}\n\t}\n\n\tduk_push_tval(thr, tv);\n\ttv = NULL;  /* Invalidated by ToObject(). */\n\tduk_to_object(thr, -1);\n\n\t/* [ ... \"[object\" obj ] */\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t/* XXX: better handling with avoid_side_effects == 1; lookup tval\n\t * without Proxy or getter side effects, and use it in sanitized\n\t * form if it's a string.\n\t */\n\tif (!avoid_side_effects) {\n\t\t(void) duk_get_prop_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG);\n\t\tif (duk_is_string_notsymbol(thr, -1)) {\n\t\t\tduk_remove_m2(thr);\n\t\t\tgoto finish;\n\t\t}\n\t\tduk_pop_unsafe(thr);\n\t}\n#else\n\tDUK_UNREF(avoid_side_effects);\n#endif\n\n\th_obj = duk_known_hobject(thr, -1);\n\tDUK_ASSERT(h_obj != NULL);\n\tclassnum = DUK_HOBJECT_GET_CLASS_NUMBER(h_obj);\n\tstridx = DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum);\n\tduk_pop_unsafe(thr);\n\tduk_push_hstring_stridx(thr, stridx);\n\n finish:\n\t/* [ ... \"[object\" tag ] */\n\tduk_push_literal(thr, \"]\");\n\tduk_concat(thr, 3);  /* [ ... \"[object\" tag \"]\" ] -> [ ... res ] */\n}\n\n/* XXX: other variants like uint, u32 etc */\nDUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped) {\n\tduk_tval *tv;\n\tduk_tval tv_tmp;\n\tduk_double_t d, dmin, dmax;\n\tduk_int_t res;\n\tduk_bool_t clamped = 0;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\td = duk_js_tointeger(thr, tv);  /* E5 Section 9.4, ToInteger() */\n\n\tdmin = (duk_double_t) minval;\n\tdmax = (duk_double_t) maxval;\n\n\tif (d < dmin) {\n\t\tclamped = 1;\n\t\tres = minval;\n\t\td = dmin;\n\t} else if (d > dmax) {\n\t\tclamped = 1;\n\t\tres = maxval;\n\t\td = dmax;\n\t} else {\n\t\tres = (duk_int_t) d;\n\t}\n\tDUK_UNREF(d);  /* SCANBUILD: with suitable dmin/dmax limits 'd' is unused */\n\t/* 'd' and 'res' agree here */\n\n\t/* Relookup in case duk_js_tointeger() ends up e.g. coercing an object. */\n\ttv = duk_get_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);  /* not popped by side effect */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv);\n#if defined(DUK_USE_FASTINT)\n#if (DUK_INT_MAX <= 0x7fffffffL)\n\tDUK_TVAL_SET_I32(tv, res);\n#else\n\t/* Clamping needed if duk_int_t is 64 bits. */\n\tif (res >= DUK_FASTINT_MIN && res <= DUK_FASTINT_MAX) {\n\t\tDUK_TVAL_SET_FASTINT(tv, res);\n\t} else {\n\t\tDUK_TVAL_SET_NUMBER(tv, d);\n\t}\n#endif\n#else\n\tDUK_TVAL_SET_NUMBER(tv, d);  /* no need to incref */\n#endif\n\tDUK_TVAL_DECREF(thr, &tv_tmp);  /* side effects */\n\n\tif (out_clamped) {\n\t\t*out_clamped = clamped;\n\t} else {\n\t\t/* coerced value is updated to value stack even when RangeError thrown */\n\t\tif (clamped) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_NUMBER_OUTSIDE_RANGE);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t}\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_int_t duk_to_int_clamped(duk_hthread *thr, duk_idx_t idx, duk_idx_t minval, duk_idx_t maxval) {\n\tduk_bool_t dummy;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_to_int_clamped_raw(thr, idx, minval, maxval, &dummy);\n}\n\nDUK_INTERNAL duk_int_t duk_to_int_check_range(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_int_clamped_raw(thr, idx, minval, maxval, NULL);  /* out_clamped==NULL -> RangeError if outside range */\n}\n\nDUK_EXTERNAL const char *duk_to_string(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_LC_UNDEFINED);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_LC_NULL);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tif (DUK_TVAL_GET_BOOLEAN(tv)) {\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_TRUE);\n\t\t} else {\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_FALSE);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\t/* Nop for actual strings, TypeError for Symbols.\n\t\t * Because various internals rely on ToString() coercion of\n\t\t * internal strings, -allow- (NOP) string coercion for hidden\n\t\t * symbols.\n\t\t */\n#if 1\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CANNOT_STRING_COERCE_SYMBOL);\n\t\t\tDUK_WO_NORETURN(goto skip_replace;);\n\t\t} else {\n\t\t\tgoto skip_replace;\n\t\t}\n#else\n\t\tgoto skip_replace;\n#endif\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: /* Go through Uint8Array.prototype.toString() for coercion. */\n\tcase DUK_TAG_OBJECT: {\n\t\t/* Plain buffers: go through ArrayBuffer.prototype.toString()\n\t\t * for coercion.\n\t\t *\n\t\t * Symbol objects: duk_to_primitive() results in a plain symbol\n\t\t * value, and duk_to_string() then causes a TypeError.\n\t\t */\n\t\tduk_to_primitive(thr, idx, DUK_HINT_STRING);\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* ToPrimitive() must guarantee */\n\t\tDUK_ASSERT(!duk_is_object(thr, idx));\n\t\treturn duk_to_string(thr, idx);  /* Note: recursive call */\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tvoid *ptr = DUK_TVAL_GET_POINTER(tv);\n\t\tif (ptr != NULL) {\n\t\t\tduk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) ptr);\n\t\t} else {\n\t\t\t/* Represent a null pointer as 'null' to be consistent with\n\t\t\t * the JX format variant.  Native '%p' format for a NULL\n\t\t\t * pointer may be e.g. '(nil)'.\n\t\t\t */\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_LC_NULL);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Should match Function.prototype.toString() */\n\t\tduk_push_lightfunc_tostring(thr, tv);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tduk_push_tval(thr, tv);\n\t\tduk_numconv_stringify(thr,\n\t\t                      10 /*radix*/,\n\t\t                      0 /*precision:shortest*/,\n\t\t                      0 /*force_exponential*/);\n\t\tbreak;\n\t}\n\t}\n\n\tduk_replace(thr, idx);\n\n skip_replace:\n\tDUK_ASSERT(duk_is_string(thr, idx));\n\treturn duk_require_string(thr, idx);\n}\n\nDUK_INTERNAL duk_hstring *duk_to_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_to_string(thr, idx);\n\tret = duk_get_hstring(thr, idx);\n\tDUK_ASSERT(ret != NULL);\n\treturn ret;\n}\n\nDUK_INTERNAL duk_hstring *duk_to_hstring_m1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_hstring(thr, -1);\n}\n\nDUK_INTERNAL duk_hstring *duk_to_hstring_acceptsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_hstring(thr, idx);\n\tif (DUK_UNLIKELY(ret && DUK_HSTRING_HAS_SYMBOL(ret))) {\n\t\treturn ret;\n\t}\n\treturn duk_to_hstring(thr, idx);\n}\n\n/* Convert a plain buffer or any buffer object into a string, using the buffer\n * bytes 1:1 in the internal string representation.  For views the active byte\n * slice (not element slice interpreted as an initializer) is used.  This is\n * necessary in Duktape 2.x because ToString(plainBuffer) no longer creates a\n * string with the same bytes as in the buffer but rather (usually)\n * '[object ArrayBuffer]'.\n */\nDUK_EXTERNAL const char *duk_buffer_to_string(duk_hthread *thr, duk_idx_t idx) {\n\tvoid *ptr_src;\n\tduk_size_t len;\n\tconst char *res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\tptr_src = duk_require_buffer_data(thr, idx, &len);\n\tDUK_ASSERT(ptr_src != NULL || len == 0);\n\n\tres = duk_push_lstring(thr, (const char *) ptr_src, len);\n\tduk_replace(thr, idx);\n\treturn res;\n}\n\nDUK_EXTERNAL void *duk_to_buffer_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, duk_uint_t mode) {\n\tduk_hbuffer *h_buf;\n\tconst duk_uint8_t *src_data;\n\tduk_size_t src_size;\n\tduk_uint8_t *dst_data;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\th_buf = duk_get_hbuffer(thr, idx);\n\tif (h_buf != NULL) {\n\t\t/* Buffer is kept as is, with the fixed/dynamic nature of the\n\t\t * buffer only changed if requested.  An external buffer\n\t\t * is converted into a non-external dynamic buffer in a\n\t\t * duk_to_dynamic_buffer() call.\n\t\t */\n\t\tduk_uint_t tmp;\n\t\tduk_uint8_t *tmp_ptr;\n\n\t\ttmp_ptr = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_buf);\n\t\tsrc_data = (const duk_uint8_t *) tmp_ptr;\n\t\tsrc_size = DUK_HBUFFER_GET_SIZE(h_buf);\n\n\t\ttmp = (DUK_HBUFFER_HAS_DYNAMIC(h_buf) ? DUK_BUF_MODE_DYNAMIC : DUK_BUF_MODE_FIXED);\n\t\tif ((tmp == mode && !DUK_HBUFFER_HAS_EXTERNAL(h_buf)) ||\n\t\t    mode == DUK_BUF_MODE_DONTCARE) {\n\t\t\t/* Note: src_data may be NULL if input is a zero-size\n\t\t\t * dynamic buffer.\n\t\t\t */\n\t\t\tdst_data = tmp_ptr;\n\t\t\tgoto skip_copy;\n\t\t}\n\t} else {\n\t\t/* Non-buffer value is first ToString() coerced, then converted\n\t\t * to a buffer (fixed buffer is used unless a dynamic buffer is\n\t\t * explicitly requested).  Symbols are rejected with a TypeError.\n\t\t * XXX: C API could maybe allow symbol-to-buffer coercion?\n\t\t */\n\t\tsrc_data = (const duk_uint8_t *) duk_to_lstring(thr, idx, &src_size);\n\t}\n\n\tdst_data = (duk_uint8_t *) duk_push_buffer(thr, src_size, (mode == DUK_BUF_MODE_DYNAMIC) /*dynamic*/);\n\t/* dst_data may be NULL if size is zero. */\n\tduk_memcpy_unsafe((void *) dst_data, (const void *) src_data, (size_t) src_size);\n\n\tduk_replace(thr, idx);\n skip_copy:\n\n\tif (out_size) {\n\t\t*out_size = src_size;\n\t}\n\treturn dst_data;\n}\n\nDUK_EXTERNAL void *duk_to_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\tcase DUK_TAG_BOOLEAN:\n\t\tres = NULL;\n\t\tbreak;\n\tcase DUK_TAG_POINTER:\n\t\tres = DUK_TVAL_GET_POINTER(tv);\n\t\tbreak;\n\tcase DUK_TAG_STRING:\n\tcase DUK_TAG_OBJECT:\n\tcase DUK_TAG_BUFFER:\n\t\t/* Heap allocated: return heap pointer which is NOT useful\n\t\t * for the caller, except for debugging.\n\t\t */\n\t\tres = (void *) DUK_TVAL_GET_HEAPHDR(tv);\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\t/* Function pointers do not always cast correctly to void *\n\t\t * (depends on memory and segmentation model for instance),\n\t\t * so they coerce to NULL.\n\t\t */\n\t\tres = NULL;\n\t\tbreak;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tres = NULL;\n\t\tbreak;\n\t}\n\n\tduk_push_pointer(thr, res);\n\tduk_replace(thr, idx);\n\treturn res;\n}\n\nDUK_LOCAL void duk__push_func_from_lightfunc(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags) {\n\tduk_idx_t nargs;\n\tduk_uint_t flags = 0;   /* shared flags for a subset of types */\n\tduk_small_uint_t lf_len;\n\tduk_hnatfunc *nf;\n\n\tnargs = (duk_idx_t) DUK_LFUNC_FLAGS_GET_NARGS(lf_flags);\n\tif (nargs == DUK_LFUNC_NARGS_VARARGS) {\n\t\tnargs = (duk_idx_t) DUK_VARARGS;\n\t}\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\t(void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE);\n\n\tlf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags);\n\tif ((duk_idx_t) lf_len != nargs) {\n\t\t/* Explicit length is only needed if it differs from 'nargs'. */\n\t\tduk_push_int(thr, (duk_int_t) lf_len);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tduk_push_lightfunc_name_raw(thr, func, lf_flags);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n#endif\n\n\tnf = duk_known_hnatfunc(thr, -1);\n\tnf->magic = (duk_int16_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags);\n}\n\nDUK_EXTERNAL void duk_to_object(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_uint_t flags = 0;   /* shared flags for a subset of types */\n\tduk_small_int_t proto = 0;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n#if !defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tcase DUK_TAG_BUFFER:  /* With no bufferobject support, don't object coerce. */\n#endif\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL: {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_OBJECT_COERCIBLE);\n\t\tDUK_WO_NORETURN(return;);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BOOLEAN);\n\t\tproto = DUK_BIDX_BOOLEAN_PROTOTYPE;\n\t\tgoto create_object;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_SYMBOL);\n\t\t\tproto = DUK_BIDX_SYMBOL_PROTOTYPE;\n\t\t} else {\n\t\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t\t        DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ |\n\t\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_STRING);\n\t\t\tproto = DUK_BIDX_STRING_PROTOTYPE;\n\t\t}\n\t\tgoto create_object;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\t/* nop */\n\t\tbreak;\n\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tcase DUK_TAG_BUFFER: {\n\t\t/* A plain buffer object coerces to a full ArrayBuffer which\n\t\t * is not fully transparent behavior (ToObject() should be a\n\t\t * nop for an object).  This behavior matches lightfuncs which\n\t\t * also coerce to an equivalent Function object.  There are\n\t\t * also downsides to defining ToObject(plainBuffer) as a no-op;\n\t\t * for example duk_to_hobject() could result in a NULL pointer.\n\t\t */\n\t\tduk_hbuffer *h_buf;\n\n\t\th_buf = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h_buf != NULL);\n\t\tduk_hbufobj_push_uint8array_from_plain(thr, h_buf);\n\t\tgoto replace_value;\n\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\tcase DUK_TAG_POINTER: {\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER);\n\t\tproto = DUK_BIDX_POINTER_PROTOTYPE;\n\t\tgoto create_object;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Lightfunc coerces to a Function instance with concrete\n\t\t * properties.  Since 'length' is virtual for Duktape/C\n\t\t * functions, don't need to define that.  The result is made\n\t\t * extensible to mimic what happens to strings in object\n\t\t * coercion:\n\t\t *\n\t\t *   > Object.isExtensible(Object('foo'))\n\t\t *   true\n\t\t */\n\t\tduk_small_uint_t lf_flags;\n\t\tduk_c_function func;\n\n\t\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);\n\t\tduk__push_func_from_lightfunc(thr, func, lf_flags);\n\t\tgoto replace_value;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_NUMBER);\n\t\tproto = DUK_BIDX_NUMBER_PROTOTYPE;\n\t\tgoto create_object;\n\t}\n\t}\n\tDUK_ASSERT(duk_is_object(thr, idx));\n\treturn;\n\n create_object:\n\t(void) duk_push_object_helper(thr, flags, proto);\n\n\t/* Note: Boolean prototype's internal value property is not writable,\n\t * but duk_xdef_prop_stridx() disregards the write protection.  Boolean\n\t * instances are immutable.\n\t *\n\t * String and buffer special behaviors are already enabled which is not\n\t * ideal, but a write to the internal value is not affected by them.\n\t */\n\tduk_dup(thr, idx);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\n replace_value:\n\tduk_replace(thr, idx);\n\tDUK_ASSERT(duk_is_object(thr, idx));\n}\n\nDUK_INTERNAL duk_hobject *duk_to_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_to_object(thr, idx);\n\tret = duk_known_hobject(thr, idx);\n\treturn ret;\n}\n\n/*\n *  Type checking\n */\n\nDUK_LOCAL duk_bool_t duk__tag_check(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t tag) {\n\tduk_tval *tv;\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\treturn (DUK_TVAL_GET_TAG(tv) == tag);\n}\n\nDUK_LOCAL duk_bool_t duk__obj_flag_any_default_false(duk_hthread *thr, duk_idx_t idx, duk_uint_t flag_mask) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, idx);\n\tif (obj) {\n\t\treturn (DUK_HEAPHDR_CHECK_FLAG_BITS((duk_heaphdr *) obj, flag_mask) ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_INTERNAL duk_int_t duk_get_type_tval(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_PACKED_TVAL)\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:\n\t\treturn DUK_TYPE_NONE;\n\tcase DUK_TAG_UNDEFINED:\n\t\treturn DUK_TYPE_UNDEFINED;\n\tcase DUK_TAG_NULL:\n\t\treturn DUK_TYPE_NULL;\n\tcase DUK_TAG_BOOLEAN:\n\t\treturn DUK_TYPE_BOOLEAN;\n\tcase DUK_TAG_STRING:\n\t\treturn DUK_TYPE_STRING;\n\tcase DUK_TAG_OBJECT:\n\t\treturn DUK_TYPE_OBJECT;\n\tcase DUK_TAG_BUFFER:\n\t\treturn DUK_TYPE_BUFFER;\n\tcase DUK_TAG_POINTER:\n\t\treturn DUK_TYPE_POINTER;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\treturn DUK_TYPE_LIGHTFUNC;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* Note: number has no explicit tag (in 8-byte representation) */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\treturn DUK_TYPE_NUMBER;\n\t}\n#else  /* DUK_USE_PACKED_TVAL */\n\tDUK_ASSERT(DUK_TVAL_IS_VALID_TAG(tv));\n\tDUK_ASSERT(sizeof(duk__type_from_tag) / sizeof(duk_uint_t) == DUK_TAG_MAX - DUK_TAG_MIN + 1);\n\treturn (duk_int_t) duk__type_from_tag[DUK_TVAL_GET_TAG(tv) - DUK_TAG_MIN];\n#endif  /* DUK_USE_PACKED_TVAL */\n}\n\nDUK_EXTERNAL duk_int_t duk_get_type(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\treturn duk_get_type_tval(tv);\n}\n\n#if defined(DUK_USE_VERBOSE_ERRORS) && defined(DUK_USE_PARANOID_ERRORS)\nDUK_LOCAL const char * const duk__type_names[] = {\n\t\"none\",\n\t\"undefined\",\n\t\"null\",\n\t\"boolean\",\n\t\"number\",\n\t\"string\",\n\t\"object\",\n\t\"buffer\",\n\t\"pointer\",\n\t\"lightfunc\"\n};\n\nDUK_INTERNAL const char *duk_get_type_name(duk_hthread *thr, duk_idx_t idx) {\n\tduk_int_t type_tag;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttype_tag = duk_get_type(thr, idx);\n\tDUK_ASSERT(type_tag >= DUK_TYPE_MIN && type_tag <= DUK_TYPE_MAX);\n\tDUK_ASSERT(DUK_TYPE_MIN == 0 && sizeof(duk__type_names) / sizeof(const char *) == DUK_TYPE_MAX + 1);\n\n\treturn duk__type_names[type_tag];\n}\n#endif  /* DUK_USE_VERBOSE_ERRORS && DUK_USE_PARANOID_ERRORS */\n\nDUK_INTERNAL duk_small_uint_t duk_get_class_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_OBJECT:\n\t\tobj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(obj != NULL);\n\t\treturn DUK_HOBJECT_GET_CLASS_NUMBER(obj);\n\tcase DUK_TAG_BUFFER:\n\t\t/* Buffers behave like Uint8Array objects. */\n\t\treturn DUK_HOBJECT_CLASS_UINT8ARRAY;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\t/* Lightfuncs behave like Function objects. */\n\t\treturn DUK_HOBJECT_CLASS_FUNCTION;\n\tdefault:\n\t\t/* Primitive or UNUSED, no class number. */\n\t\treturn DUK_HOBJECT_CLASS_NONE;\n\t}\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_type(duk_hthread *thr, duk_idx_t idx, duk_int_t type) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_get_type(thr, idx) == type) ? 1 : 0;\n}\n\nDUK_INTERNAL duk_uint_t duk_get_type_mask_tval(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_PACKED_TVAL)\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:\n\t\treturn DUK_TYPE_MASK_NONE;\n\tcase DUK_TAG_UNDEFINED:\n\t\treturn DUK_TYPE_MASK_UNDEFINED;\n\tcase DUK_TAG_NULL:\n\t\treturn DUK_TYPE_MASK_NULL;\n\tcase DUK_TAG_BOOLEAN:\n\t\treturn DUK_TYPE_MASK_BOOLEAN;\n\tcase DUK_TAG_STRING:\n\t\treturn DUK_TYPE_MASK_STRING;\n\tcase DUK_TAG_OBJECT:\n\t\treturn DUK_TYPE_MASK_OBJECT;\n\tcase DUK_TAG_BUFFER:\n\t\treturn DUK_TYPE_MASK_BUFFER;\n\tcase DUK_TAG_POINTER:\n\t\treturn DUK_TYPE_MASK_POINTER;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\treturn DUK_TYPE_MASK_LIGHTFUNC;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* Note: number has no explicit tag (in 8-byte representation) */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\treturn DUK_TYPE_MASK_NUMBER;\n\t}\n#else  /* DUK_USE_PACKED_TVAL */\n\tDUK_ASSERT(DUK_TVAL_IS_VALID_TAG(tv));\n\tDUK_ASSERT(sizeof(duk__type_mask_from_tag) / sizeof(duk_uint_t) == DUK_TAG_MAX - DUK_TAG_MIN + 1);\n\treturn duk__type_mask_from_tag[DUK_TVAL_GET_TAG(tv) - DUK_TAG_MIN];\n#endif  /* DUK_USE_PACKED_TVAL */\n}\n\nDUK_EXTERNAL duk_uint_t duk_get_type_mask(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\treturn duk_get_type_mask_tval(tv);\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_type_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (DUK_LIKELY((duk_get_type_mask(thr, idx) & mask) != 0U)) {\n\t\treturn 1;\n\t}\n\tif (mask & DUK_TYPE_MASK_THROW) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_UNEXPECTED_TYPE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_UNDEFINED);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_null(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_NULL);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_BOOLEAN);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/*\n\t *  Number is special because it doesn't have a specific\n\t *  tag in the 8-byte representation.\n\t */\n\n\t/* XXX: shorter version for unpacked representation? */\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\treturn DUK_TVAL_IS_NUMBER(tv);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_nan(duk_hthread *thr, duk_idx_t idx) {\n\t/* XXX: This will now return false for non-numbers, even though they would\n\t * coerce to NaN (as a general rule).  In particular, duk_get_number()\n\t * returns a NaN for non-numbers, so should this function also return\n\t * true for non-numbers?\n\t */\n\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\t/* XXX: for packed duk_tval an explicit \"is number\" check is unnecessary */\n\tif (!DUK_TVAL_IS_NUMBER(tv)) {\n\t\treturn 0;\n\t}\n\treturn (duk_bool_t) DUK_ISNAN(DUK_TVAL_GET_NUMBER(tv));\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_string(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_STRING);\n}\n\nDUK_INTERNAL duk_bool_t duk_is_string_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_hstring_notsymbol(thr, idx) != NULL;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_object(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_OBJECT);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_BUFFER);\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\treturn 1;\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\nDUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_is_buffer(thr, idx);\n}\n\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_EXTERNAL duk_bool_t duk_is_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_POINTER);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_lightfunc(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_LIGHTFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_symbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\th = duk_get_hstring(thr, idx);\n\t/* Use DUK_LIKELY() here because caller may be more likely to type\n\t * check an expected symbol than not.\n\t */\n\tif (DUK_LIKELY(h != NULL && DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_array(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, idx);\n\tif (obj) {\n\t\treturn (DUK_HOBJECT_GET_CLASS_NUMBER(obj) == DUK_HOBJECT_CLASS_ARRAY ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_function(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn DUK_HOBJECT_HAS_CALLABLE(h) ? 1 : 0;\n\t}\n\tif (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_INTERNAL duk_bool_t duk_is_callable_tval(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_UNREF(thr);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn DUK_HOBJECT_HAS_CALLABLE(h) ? 1 : 0;\n\t}\n\tif (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_constructable(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn DUK_HOBJECT_HAS_CONSTRUCTABLE(h) ? 1 : 0;\n\t}\n\tif (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_c_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__obj_flag_any_default_false(thr,\n\t                                       idx,\n\t                                       DUK_HOBJECT_FLAG_NATFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_ecmascript_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__obj_flag_any_default_false(thr,\n\t                                       idx,\n\t                                       DUK_HOBJECT_FLAG_COMPFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_bound_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__obj_flag_any_default_false(thr,\n\t                                       idx,\n\t                                       DUK_HOBJECT_FLAG_BOUNDFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_thread(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, idx);\n\tif (obj) {\n\t\treturn (DUK_HOBJECT_GET_CLASS_NUMBER(obj) == DUK_HOBJECT_CLASS_THREAD ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_fixed_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HBUFFER_HAS_DYNAMIC(h) ? 0 : 1);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_dynamic_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h) ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_external_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HBUFFER_HAS_DYNAMIC(h) && DUK_HBUFFER_HAS_EXTERNAL(h) ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_errcode_t duk_get_error_code(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hobject(thr, idx);\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (!h) {\n\t\t\treturn DUK_ERR_NONE;\n\t\t}\n\n\t\t/* XXX: something more convenient? */\n\n\t\tif (h == thr->builtins[DUK_BIDX_EVAL_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_EVAL_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_RANGE_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_RANGE_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_REFERENCE_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_REFERENCE_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_SYNTAX_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_SYNTAX_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_TYPE_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_TYPE_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_URI_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_URI_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_ERROR;\n\t\t}\n\n\t\th = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t} while (--sanity > 0);\n\n\treturn DUK_ERR_NONE;\n}\n\n/*\n *  Pushers\n */\n\nDUK_INTERNAL void duk_push_tval(duk_hthread *thr, duk_tval *tv) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_TVAL(tv_slot, tv);\n\tDUK_TVAL_INCREF(thr, tv);  /* no side effects */\n}\n\nDUK_EXTERNAL void duk_push_undefined(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\t/* Because value stack init policy is 'undefined above top',\n\t * we don't need to write, just assert.\n\t */\n\tthr->valstack_top++;\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));\n}\n\nDUK_EXTERNAL void duk_push_null(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NULL(tv_slot);\n}\n\nDUK_EXTERNAL void duk_push_boolean(duk_hthread *thr, duk_bool_t val) {\n\tduk_tval *tv_slot;\n\tduk_small_int_t b;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\tb = (val ? 1 : 0);  /* ensure value is 1 or 0 (not other non-zero) */\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_BOOLEAN(tv_slot, b);\n}\n\nDUK_EXTERNAL void duk_push_true(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_BOOLEAN_TRUE(tv_slot);\n}\n\nDUK_EXTERNAL void duk_push_false(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_BOOLEAN_FALSE(tv_slot);\n}\n\n/* normalize NaN which may not match our canonical internal NaN */\nDUK_EXTERNAL void duk_push_number(duk_hthread *thr, duk_double_t val) {\n\tduk_tval *tv_slot;\n\tduk_double_union du;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\tdu.d = val;\n\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, du.d);\n}\n\nDUK_EXTERNAL void duk_push_int(duk_hthread *thr, duk_int_t val) {\n#if defined(DUK_USE_FASTINT)\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n#if DUK_INT_MAX <= 0x7fffffffL\n\tDUK_TVAL_SET_I32(tv_slot, (duk_int32_t) val);\n#else\n\tif (val >= DUK_FASTINT_MIN && val <= DUK_FASTINT_MAX) {\n\t\tDUK_TVAL_SET_FASTINT(tv_slot, (duk_int64_t) val);\n\t} else {\n\t\tduk_double_t = (duk_double_t) val;\n\t\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n\t}\n#endif\n#else  /* DUK_USE_FASTINT */\n\tduk_tval *tv_slot;\n\tduk_double_t d;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\td = (duk_double_t) val;\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n#endif  /* DUK_USE_FASTINT */\n}\n\nDUK_EXTERNAL void duk_push_uint(duk_hthread *thr, duk_uint_t val) {\n#if defined(DUK_USE_FASTINT)\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n#if DUK_UINT_MAX <= 0xffffffffUL\n\tDUK_TVAL_SET_U32(tv_slot, (duk_uint32_t) val);\n#else\n\tif (val <= DUK_FASTINT_MAX) {  /* val is unsigned so >= 0 */\n\t\t/* XXX: take advantage of val being unsigned, no need to mask */\n\t\tDUK_TVAL_SET_FASTINT(tv_slot, (duk_int64_t) val);\n\t} else {\n\t\tduk_double_t = (duk_double_t) val;\n\t\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n\t}\n#endif\n#else  /* DUK_USE_FASTINT */\n\tduk_tval *tv_slot;\n\tduk_double_t d;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\td = (duk_double_t) val;\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n#endif  /* DUK_USE_FASTINT */\n}\n\nDUK_EXTERNAL void duk_push_nan(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\tduk_double_union du;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\tDUK_DBLUNION_SET_NAN(&du);\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, du.d);\n}\n\nDUK_EXTERNAL const char *duk_push_lstring(duk_hthread *thr, const char *str, duk_size_t len) {\n\tduk_hstring *h;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Check stack before interning (avoid hanging temp). */\n\tDUK__CHECK_SPACE();\n\n\t/* NULL with zero length represents an empty string; NULL with higher\n\t * length is also now treated like an empty string although it is\n\t * a bit dubious.  This is unlike duk_push_string() which pushes a\n\t * 'null' if the input string is a NULL.\n\t */\n\tif (DUK_UNLIKELY(str == NULL)) {\n\t\tlen = 0U;\n\t}\n\n\t/* Check for maximum string length. */\n\tif (DUK_UNLIKELY(len > DUK_HSTRING_MAX_BYTELEN)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_STRING_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\th = duk_heap_strtable_intern_checked(thr, (const duk_uint8_t *) str, (duk_uint32_t) len);\n\tDUK_ASSERT(h != NULL);\n\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_STRING(tv_slot, h);\n\tDUK_HSTRING_INCREF(thr, h);  /* no side effects */\n\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_EXTERNAL const char *duk_push_string(duk_hthread *thr, const char *str) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (str) {\n\t\treturn duk_push_lstring(thr, str, DUK_STRLEN(str));\n\t} else {\n\t\tduk_push_null(thr);\n\t\treturn NULL;\n\t}\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_EXTERNAL const char *duk_push_literal_raw(duk_hthread *thr, const char *str, duk_size_t len) {\n\tduk_hstring *h;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(str != NULL);\n\tDUK_ASSERT(str[len] == (char) 0);\n\n\t/* Check for maximum string length. */\n\tif (DUK_UNLIKELY(len > DUK_HSTRING_MAX_BYTELEN)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_STRING_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\th = duk_heap_strtable_intern_literal_checked(thr, (const duk_uint8_t *) str, (duk_uint32_t) len);\n\tDUK_ASSERT(h != NULL);\n\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_STRING(tv_slot, h);\n\tDUK_HSTRING_INCREF(thr, h);  /* no side effects */\n\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n#else  /* DUK_USE_LITCACHE_SIZE */\nDUK_EXTERNAL const char *duk_push_literal_raw(duk_hthread *thr, const char *str, duk_size_t len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(str != NULL);\n\tDUK_ASSERT(str[len] == (char) 0);\n\n\treturn duk_push_lstring(thr, str, len);\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n#endif  /* !DUK_USE_PREFER_SIZE */\n\nDUK_EXTERNAL void duk_push_pointer(duk_hthread *thr, void *val) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_POINTER(tv_slot, val);\n}\n\nDUK_INTERNAL duk_hstring *duk_push_uint_to_hstring(duk_hthread *thr, duk_uint_t i) {\n\tduk_hstring *h_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: this could be a direct DUK_SPRINTF to a buffer followed by duk_push_string() */\n\tduk_push_uint(thr, (duk_uint_t) i);\n\th_tmp = duk_to_hstring_m1(thr);\n\tDUK_ASSERT(h_tmp != NULL);\n\treturn h_tmp;\n}\n\nDUK_LOCAL void duk__push_this_helper(duk_hthread *thr, duk_small_uint_t check_object_coercible) {\n\tduk_tval *tv_slot;\n\n\tDUK__CHECK_SPACE();\n\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* because of valstack init policy */\n\ttv_slot = thr->valstack_top++;\n\n\tif (DUK_UNLIKELY(thr->callstack_curr == NULL)) {\n\t\tif (check_object_coercible) {\n\t\t\tgoto type_error;\n\t\t}\n\t\t/* 'undefined' already on stack top */\n\t} else {\n\t\tduk_tval *tv;\n\n\t\t/* 'this' binding is just before current activation's bottom */\n\t\tDUK_ASSERT(thr->valstack_bottom > thr->valstack);\n\t\ttv = thr->valstack_bottom - 1;\n\t\tif (check_object_coercible &&\n\t\t    (DUK_TVAL_IS_UNDEFINED(tv) || DUK_TVAL_IS_NULL(tv))) {\n\t\t\t/* XXX: better macro for DUK_TVAL_IS_UNDEFINED_OR_NULL(tv) */\n\t\t\tgoto type_error;\n\t\t}\n\n\t\tDUK_TVAL_SET_TVAL(tv_slot, tv);\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t}\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_OBJECT_COERCIBLE);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_push_this(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 0 /*check_object_coercible*/);\n}\n\nDUK_INTERNAL void duk_push_this_check_object_coercible(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 1 /*check_object_coercible*/);\n}\n\nDUK_INTERNAL duk_hobject *duk_push_this_coercible_to_object(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 1 /*check_object_coercible*/);\n\th = duk_to_hobject(thr, -1);\n\tDUK_ASSERT(h != NULL);\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_push_this_coercible_to_string(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 1 /*check_object_coercible*/);\n\treturn duk_to_hstring_m1(thr);  /* This will reject all Symbol values; accepts Symbol objects. */\n}\n\nDUK_INTERNAL duk_tval *duk_get_borrowed_this_tval(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->callstack_top > 0);  /* caller required to know */\n\tDUK_ASSERT(thr->callstack_curr != NULL);  /* caller required to know */\n\tDUK_ASSERT(thr->valstack_bottom > thr->valstack);  /* consequence of above */\n\tDUK_ASSERT(thr->valstack_bottom - 1 >= thr->valstack);  /* 'this' binding exists */\n\n\treturn thr->valstack_bottom - 1;\n}\n\nDUK_EXTERNAL void duk_push_new_target(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* https://www.ecma-international.org/ecma-262/6.0/#sec-meta-properties-runtime-semantics-evaluation\n\t * https://www.ecma-international.org/ecma-262/6.0/#sec-getnewtarget\n\t *\n\t * No newTarget support now, so as a first approximation\n\t * use the resolved (non-bound) target function.\n\t *\n\t * Check CONSTRUCT flag from current function, or if running\n\t * direct eval, from a non-direct-eval parent (with possibly\n\t * more than one nested direct eval).  An alternative to this\n\t * would be to store [[NewTarget]] as a hidden symbol of the\n\t * lexical scope, and then just look up that variable.\n\t *\n\t * Calls from the application will either be for an empty\n\t * call stack, or a Duktape/C function as the top activation.\n\t */\n\n\tact = thr->callstack_curr;\n\tfor (;;) {\n\t\tif (act == NULL) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (act->flags & DUK_ACT_FLAG_CONSTRUCT) {\n\t\t\tduk_push_tval(thr, &act->tv_func);\n\t\t\treturn;\n\t\t} else if (act->flags & DUK_ACT_FLAG_DIRECT_EVAL) {\n\t\t\tact = act->parent;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tduk_push_undefined(thr);\n}\n\nDUK_EXTERNAL void duk_push_current_function(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\tduk_push_tval(thr, &act->tv_func);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n}\n\nDUK_EXTERNAL void duk_push_current_thread(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (thr->heap->curr_thread) {\n\t\tduk_push_hobject(thr, (duk_hobject *) thr->heap->curr_thread);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n}\n\nDUK_EXTERNAL void duk_push_global_object(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_hobject_bidx(thr, DUK_BIDX_GLOBAL);\n}\n\n/* XXX: size optimize */\nDUK_LOCAL void duk__push_stash(duk_hthread *thr) {\n\tif (!duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"creating heap/global/thread stash on first use\"));\n\t\tduk_pop_unsafe(thr);\n\t\tduk_push_bare_object(thr);\n\t\tduk_dup_top(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_C);  /* [ ... parent stash stash ] -> [ ... parent stash ] */\n\t}\n\tduk_remove_m2(thr);\n}\n\nDUK_EXTERNAL void duk_push_heap_stash(duk_hthread *thr) {\n\tduk_heap *heap;\n\tDUK_ASSERT_API_ENTRY(thr);\n\theap = thr->heap;\n\tDUK_ASSERT(heap->heap_object != NULL);\n\tduk_push_hobject(thr, heap->heap_object);\n\tduk__push_stash(thr);\n}\n\nDUK_EXTERNAL void duk_push_global_stash(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_push_global_object(thr);\n\tduk__push_stash(thr);\n}\n\nDUK_EXTERNAL void duk_push_thread_stash(duk_hthread *thr, duk_hthread *target_thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tif (DUK_UNLIKELY(target_thr == NULL)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tduk_push_hobject(thr, (duk_hobject *) target_thr);\n\tduk__push_stash(thr);\n}\n\n/* XXX: duk_ssize_t would be useful here */\nDUK_LOCAL duk_int_t duk__try_push_vsprintf(duk_hthread *thr, void *buf, duk_size_t sz, const char *fmt, va_list ap) {\n\tduk_int_t len;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(thr);\n\n\t/* NUL terminator handling doesn't matter here */\n\tlen = DUK_VSNPRINTF((char *) buf, sz, fmt, ap);\n\tif (len < (duk_int_t) sz) {\n\t\t/* Return value of 'sz' or more indicates output was (potentially)\n\t\t * truncated.\n\t\t */\n\t\treturn (duk_int_t) len;\n\t}\n\treturn -1;\n}\n\nDUK_EXTERNAL const char *duk_push_vsprintf(duk_hthread *thr, const char *fmt, va_list ap) {\n\tduk_uint8_t stack_buf[DUK_PUSH_SPRINTF_INITIAL_SIZE];\n\tduk_size_t sz = DUK_PUSH_SPRINTF_INITIAL_SIZE;\n\tduk_bool_t pushed_buf = 0;\n\tvoid *buf;\n\tduk_int_t len;  /* XXX: duk_ssize_t */\n\tconst char *res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* special handling of fmt==NULL */\n\tif (!fmt) {\n\t\tduk_hstring *h_str;\n\t\tduk_push_hstring_empty(thr);\n\t\th_str = duk_known_hstring(thr, -1);\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h_str);\n\t}\n\n\t/* initial estimate based on format string */\n\tsz = DUK_STRLEN(fmt) + 16;  /* format plus something to avoid just missing */\n\tif (sz < DUK_PUSH_SPRINTF_INITIAL_SIZE) {\n\t\tsz = DUK_PUSH_SPRINTF_INITIAL_SIZE;\n\t}\n\tDUK_ASSERT(sz > 0);\n\n\t/* Try to make do with a stack buffer to avoid allocating a temporary buffer.\n\t * This works 99% of the time which is quite nice.\n\t */\n\tfor (;;) {\n\t\tva_list ap_copy;  /* copied so that 'ap' can be reused */\n\n\t\tif (sz <= sizeof(stack_buf)) {\n\t\t\tbuf = stack_buf;\n\t\t} else if (!pushed_buf) {\n\t\t\tpushed_buf = 1;\n\t\t\tbuf = duk_push_dynamic_buffer(thr, sz);\n\t\t} else {\n\t\t\tbuf = duk_resize_buffer(thr, -1, sz);\n\t\t}\n\t\tDUK_ASSERT(buf != NULL);\n\n\t\tDUK_VA_COPY(ap_copy, ap);\n\t\tlen = duk__try_push_vsprintf(thr, buf, sz, fmt, ap_copy);\n\t\tva_end(ap_copy);\n\t\tif (len >= 0) {\n\t\t\tbreak;\n\t\t}\n\n\t\t/* failed, resize and try again */\n\t\tsz = sz * 2;\n\t\tif (DUK_UNLIKELY(sz >= DUK_PUSH_SPRINTF_SANITY_LIMIT)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t}\n\n\t/* Cannot use duk_buffer_to_string() on the buffer because it is\n\t * usually larger than 'len'; 'buf' is also usually a stack buffer.\n\t */\n\tres = duk_push_lstring(thr, (const char *) buf, (duk_size_t) len);  /* [ buf? res ] */\n\tif (pushed_buf) {\n\t\tduk_remove_m2(thr);\n\t}\n\treturn res;\n}\n\nDUK_EXTERNAL const char *duk_push_sprintf(duk_hthread *thr, const char *fmt, ...) {\n\tva_list ap;\n\tconst char *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* allow fmt==NULL */\n\tva_start(ap, fmt);\n\tret = duk_push_vsprintf(thr, fmt, ap);\n\tva_end(ap);\n\n\treturn ret;\n}\n\nDUK_INTERNAL duk_hobject *duk_push_object_helper(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx) {\n\tduk_tval *tv_slot;\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(prototype_bidx == -1 ||\n\t           (prototype_bidx >= 0 && prototype_bidx < DUK_NUM_BUILTINS));\n\n\tDUK__CHECK_SPACE();\n\n\th = duk_hobject_alloc(thr, hobject_flags_and_class);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"created object with flags: 0x%08lx\", (unsigned long) h->hdr.h_flags));\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, h);\n\tDUK_HOBJECT_INCREF(thr, h);  /* no side effects */\n\tthr->valstack_top++;\n\n\t/* object is now reachable */\n\n\tif (prototype_bidx >= 0) {\n\t\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, h, thr->builtins[prototype_bidx]);\n\t} else {\n\t\tDUK_ASSERT(prototype_bidx == -1);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h) == NULL);\n\t}\n\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_push_object_helper_proto(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_hobject *proto) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_push_object_helper(thr, hobject_flags_and_class, -1);\n\tDUK_ASSERT(h != NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, h, proto);\n\treturn h;\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_object(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              DUK_BIDX_OBJECT_PROTOTYPE);\n\treturn duk_get_top_index_unsafe(thr);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_array(duk_hthread *thr) {\n\tduk_uint_t flags;\n\tduk_harray *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_ARRAY_PART |\n\t        DUK_HOBJECT_FLAG_EXOTIC_ARRAY |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAY);\n\n\tobj = duk_harray_alloc(thr, flags);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[DUK_BIDX_ARRAY_PROTOTYPE]);\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);  /* XXX: could preallocate with refcount = 1 */\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\tDUK_ASSERT(obj->length == 0);  /* Array .length starts at zero. */\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_bare_array(duk_hthread *thr) {\n\tduk_uint_t flags;\n\tduk_harray *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_ARRAY_PART |\n\t        DUK_HOBJECT_FLAG_EXOTIC_ARRAY |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAY);\n\n\tobj = duk_harray_alloc(thr, flags);\n\tDUK_ASSERT(obj != NULL);\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);  /* XXX: could preallocate with refcount = 1 */\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\tDUK_ASSERT(obj->length == 0);  /* Array .length starts at zero. */\n\treturn ret;\n}\n\nDUK_INTERNAL duk_harray *duk_push_harray(duk_hthread *thr) {\n\t/* XXX: API call could do this directly, cast to void in API macro. */\n\tduk_harray *a;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_push_array(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(thr->valstack_top - 1));\n\ta = (duk_harray *) DUK_TVAL_GET_OBJECT(thr->valstack_top - 1);\n\tDUK_ASSERT(a != NULL);\n\treturn a;\n}\n\n/* Push a duk_harray with preallocated size (.length also set to match size).\n * Caller may then populate array part of the duk_harray directly.\n */\nDUK_INTERNAL duk_harray *duk_push_harray_with_size(duk_hthread *thr, duk_uint32_t size) {\n\tduk_harray *a;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ta = duk_push_harray(thr);\n\n\tduk_hobject_realloc_props(thr,\n\t                          (duk_hobject *) a,\n\t                          0,\n\t                          size,\n\t                          0,\n\t                          0);\n\ta->length = size;\n\treturn a;\n}\n\nDUK_INTERNAL duk_tval *duk_push_harray_with_size_outptr(duk_hthread *thr, duk_uint32_t size) {\n\tduk_harray *a;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ta = duk_push_harray_with_size(thr, size);\n\tDUK_ASSERT(a != NULL);\n\treturn DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_thread_raw(duk_hthread *thr, duk_uint_t flags) {\n\tduk_hthread *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\tobj = duk_hthread_alloc(thr,\n\t                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_THREAD));\n\tDUK_ASSERT(obj != NULL);\n\tobj->state = DUK_HTHREAD_STATE_INACTIVE;\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* Nothing to initialize, strs[] is in ROM. */\n#else\n#if defined(DUK_USE_HEAPPTR16)\n\tobj->strs16 = thr->strs16;\n#else\n\tobj->strs = thr->strs;\n#endif\n#endif\n\tDUK_DDD(DUK_DDDPRINT(\"created thread object with flags: 0x%08lx\", (unsigned long) obj->obj.hdr.h_flags));\n\n\t/* make the new thread reachable */\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HTHREAD_INCREF(thr, obj);\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\t/* important to do this *after* pushing, to make the thread reachable for gc */\n\tif (DUK_UNLIKELY(!duk_hthread_init_stacks(thr->heap, obj))) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* initialize built-ins - either by copying or creating new ones */\n\tif (flags & DUK_THREAD_NEW_GLOBAL_ENV) {\n\t\tduk_hthread_create_builtin_objects(obj);\n\t} else {\n\t\tduk_hthread_copy_builtin_objects(thr, obj);\n\t}\n\n\t/* default prototype */\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, obj->builtins[DUK_BIDX_THREAD_PROTOTYPE]);\n\n\t/* Initial stack size satisfies the stack slack constraints so there\n\t * is no need to require stack here.\n\t */\n\tDUK_ASSERT(DUK_VALSTACK_INITIAL_SIZE >=\n\t           DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\n\treturn ret;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_push_hcompfunc(duk_hthread *thr) {\n\tduk_hcompfunc *obj;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\t/* Template functions are not strictly constructable (they don't\n\t * have a \"prototype\" property for instance), so leave the\n\t * DUK_HOBJECT_FLAG_CONSRUCTABLE flag cleared here.\n\t */\n\n\tobj = duk_hcompfunc_alloc(thr,\n\t                          DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                          DUK_HOBJECT_FLAG_CALLABLE |\n\t                          DUK_HOBJECT_FLAG_COMPFUNC |\n\t                          DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION));\n\tif (DUK_UNLIKELY(obj == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"created compiled function object with flags: 0x%08lx\", (unsigned long) obj->obj.hdr.h_flags));\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\tthr->valstack_top++;\n\n\t/* default prototype */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) obj) == NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\n\treturn obj;\n}\n\nDUK_INTERNAL duk_hboundfunc *duk_push_hboundfunc(duk_hthread *thr) {\n\tduk_hboundfunc *obj;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\tobj = duk_hboundfunc_alloc(thr->heap,\n\t                           DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                           DUK_HOBJECT_FLAG_BOUNDFUNC |\n\t                           DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t                           DUK_HOBJECT_FLAG_CALLABLE |\n\t                           DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION));\n\tif (!obj) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\n\t/* Prototype is left as NULL because the caller always sets it (and\n\t * it depends on the target function).\n\t */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) obj) == NULL);\n\n\treturn obj;\n}\n\nDUK_LOCAL duk_idx_t duk__push_c_function_raw(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_uint_t flags, duk_small_uint_t proto_bidx) {\n\tduk_hnatfunc *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\tduk_int16_t func_nargs;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tDUK__CHECK_SPACE();\n\n\tif (DUK_UNLIKELY(func == NULL)) {\n\t\tgoto api_error;\n\t}\n\tif (nargs >= 0 && nargs < DUK_HNATFUNC_NARGS_MAX) {\n\t\tfunc_nargs = (duk_int16_t) nargs;\n\t} else if (nargs == DUK_VARARGS) {\n\t\tfunc_nargs = DUK_HNATFUNC_NARGS_VARARGS;\n\t} else {\n\t\tgoto api_error;\n\t}\n\n\tobj = duk_hnatfunc_alloc(thr, flags);\n\tDUK_ASSERT(obj != NULL);\n\n\tobj->func = func;\n\tobj->nargs = func_nargs;\n\n\tDUK_DDD(DUK_DDDPRINT(\"created native function object with flags: 0x%08lx, nargs=%ld\",\n\t                     (unsigned long) obj->obj.hdr.h_flags, (long) obj->nargs));\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\tDUK_ASSERT_BIDX_VALID(proto_bidx);\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[proto_bidx]);\n\treturn ret;\n\n api_error:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_c_function(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\n\t/* Default prototype is a Duktape specific %NativeFunctionPrototype%\n\t * which provides .length and .name getters.\n\t */\n\treturn duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE);\n}\n\nDUK_INTERNAL void duk_push_c_function_builtin(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\n\t/* Must use Function.prototype for standard built-in functions. */\n\t(void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_FUNCTION_PROTOTYPE);\n}\n\nDUK_INTERNAL void duk_push_c_function_builtin_noconstruct(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\n\t/* Must use Function.prototype for standard built-in functions. */\n\t(void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_FUNCTION_PROTOTYPE);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_c_lightfunc(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_idx_t length, duk_int_t magic) {\n\tduk_small_uint_t lf_flags;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\tif (nargs >= DUK_LFUNC_NARGS_MIN && nargs <= DUK_LFUNC_NARGS_MAX) {\n\t\t/* as is */\n\t} else if (nargs == DUK_VARARGS) {\n\t\tnargs = DUK_LFUNC_NARGS_VARARGS;\n\t} else {\n\t\tgoto api_error;\n\t}\n\tif (DUK_UNLIKELY(!(length >= DUK_LFUNC_LENGTH_MIN && length <= DUK_LFUNC_LENGTH_MAX))) {\n\t\tgoto api_error;\n\t}\n\tif (DUK_UNLIKELY(!(magic >= DUK_LFUNC_MAGIC_MIN && magic <= DUK_LFUNC_MAGIC_MAX))) {\n\t\tgoto api_error;\n\t}\n\n\tlf_flags = DUK_LFUNC_FLAGS_PACK((duk_small_int_t) magic, (duk_small_uint_t) length, (duk_small_uint_t) nargs);\n\ttv_slot = thr->valstack_top++;\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_slot));\n\tDUK_TVAL_SET_LIGHTFUNC(tv_slot, func, lf_flags);\n\tDUK_ASSERT(tv_slot >= thr->valstack_bottom);\n\treturn (duk_idx_t) (tv_slot - thr->valstack_bottom);\n\n api_error:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_hbufobj *duk_push_bufobj_raw(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx) {\n\tduk_hbufobj *obj;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(prototype_bidx >= 0);\n\n\tDUK__CHECK_SPACE();\n\n\tobj = duk_hbufobj_alloc(thr, hobject_flags_and_class);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[prototype_bidx]);\n\tDUK_HBUFOBJ_ASSERT_VALID(obj);\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\tthr->valstack_top++;\n\n\treturn obj;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* XXX: There's quite a bit of overlap with buffer creation handling in\n * duk_bi_buffer.c.  Look for overlap and refactor.\n */\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK__PACK_ARGS(classnum,protobidx,elemtype,elemshift,istypedarray) \\\n\t(((classnum) << 24) | ((protobidx) << 16) | ((elemtype) << 8) | ((elemshift) << 4) | (istypedarray))\n\nstatic const duk_uint32_t duk__bufobj_flags_lookup[] = {\n\t/* Node.js Buffers are Uint8Array instances which inherit from Buffer.prototype. */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_ARRAYBUFFER,       DUK_BIDX_ARRAYBUFFER_PROTOTYPE,       DUK_HBUFOBJ_ELEM_UINT8,        0, 0),  /* DUK_BUFOBJ_ARRAYBUFFER */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8ARRAY,        DUK_BIDX_NODEJS_BUFFER_PROTOTYPE,     DUK_HBUFOBJ_ELEM_UINT8,        0, 1),  /* DUK_BUFOBJ_NODEJS_BUFFER */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_DATAVIEW,          DUK_BIDX_DATAVIEW_PROTOTYPE,          DUK_HBUFOBJ_ELEM_UINT8,        0, 0),  /* DUK_BUFOBJ_DATAVIEW */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT8ARRAY,         DUK_BIDX_INT8ARRAY_PROTOTYPE,         DUK_HBUFOBJ_ELEM_INT8,         0, 1),  /* DUK_BUFOBJ_INT8ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8ARRAY,        DUK_BIDX_UINT8ARRAY_PROTOTYPE,        DUK_HBUFOBJ_ELEM_UINT8,        0, 1),  /* DUK_BUFOBJ_UINT8ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY, DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE, DUK_HBUFOBJ_ELEM_UINT8CLAMPED, 0, 1),  /* DUK_BUFOBJ_UINT8CLAMPEDARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT16ARRAY,        DUK_BIDX_INT16ARRAY_PROTOTYPE,        DUK_HBUFOBJ_ELEM_INT16,        1, 1),  /* DUK_BUFOBJ_INT16ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT16ARRAY,       DUK_BIDX_UINT16ARRAY_PROTOTYPE,       DUK_HBUFOBJ_ELEM_UINT16,       1, 1),  /* DUK_BUFOBJ_UINT16ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT32ARRAY,        DUK_BIDX_INT32ARRAY_PROTOTYPE,        DUK_HBUFOBJ_ELEM_INT32,        2, 1),  /* DUK_BUFOBJ_INT32ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT32ARRAY,       DUK_BIDX_UINT32ARRAY_PROTOTYPE,       DUK_HBUFOBJ_ELEM_UINT32,       2, 1),  /* DUK_BUFOBJ_UINT32ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_FLOAT32ARRAY,      DUK_BIDX_FLOAT32ARRAY_PROTOTYPE,      DUK_HBUFOBJ_ELEM_FLOAT32,      2, 1),  /* DUK_BUFOBJ_FLOAT32ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_FLOAT64ARRAY,      DUK_BIDX_FLOAT64ARRAY_PROTOTYPE,      DUK_HBUFOBJ_ELEM_FLOAT64,      3, 1)   /* DUK_BUFOBJ_FLOAT64ARRAY */\n};\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags) {\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_hobject *h_arraybuf;\n\tduk_uint32_t tmp;\n\tduk_uint_t classnum;\n\tduk_uint_t protobidx;\n\tduk_uint_t lookupidx;\n\tduk_uint_t uint_offset, uint_length, uint_added;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* The underlying types for offset/length in duk_hbufobj is\n\t * duk_uint_t; make sure argument values fit.\n\t */\n\tuint_offset = (duk_uint_t) byte_offset;\n\tuint_length = (duk_uint_t) byte_length;\n\tif (sizeof(duk_size_t) != sizeof(duk_uint_t)) {\n\t\tif (DUK_UNLIKELY((duk_size_t) uint_offset != byte_offset || (duk_size_t) uint_length != byte_length)) {\n\t\t\tgoto range_error;\n\t\t}\n\t}\n\n\tDUK_ASSERT_DISABLE(flags >= 0);  /* flags is unsigned */\n\tlookupidx = flags;\n\tif (DUK_UNLIKELY(lookupidx >= sizeof(duk__bufobj_flags_lookup) / sizeof(duk_uint32_t))) {\n\t\tgoto arg_error;\n\t}\n\ttmp = duk__bufobj_flags_lookup[lookupidx];\n\tclassnum = tmp >> 24;\n\tprotobidx = (tmp >> 16) & 0xff;\n\n\th_arraybuf = duk_get_hobject(thr, idx_buffer);\n\tif (h_arraybuf != NULL &&  /* argument is an object */\n\t    flags != DUK_BUFOBJ_ARRAYBUFFER &&  /* creating a view */\n\t    DUK_HOBJECT_GET_CLASS_NUMBER(h_arraybuf) == DUK_HOBJECT_CLASS_ARRAYBUFFER  /* argument is ArrayBuffer */) {\n\t\tduk_uint_t tmp_offset;\n\n\t\tDUK_HBUFOBJ_ASSERT_VALID((duk_hbufobj *) h_arraybuf);\n\t\th_val = ((duk_hbufobj *) h_arraybuf)->buf;\n\t\tif (DUK_UNLIKELY(h_val == NULL)) {\n\t\t\tgoto arg_error;\n\t\t}\n\n\t\ttmp_offset = uint_offset + ((duk_hbufobj *) h_arraybuf)->offset;\n\t\tif (DUK_UNLIKELY(tmp_offset < uint_offset)) {\n\t\t\tgoto range_error;\n\t\t}\n\t\tuint_offset = tmp_offset;\n\n\t\t/* Note intentional difference to new TypedArray(): we allow\n\t\t * caller to create an uncovered typed array (which is memory\n\t\t * safe); new TypedArray() rejects it.\n\t\t */\n\t} else {\n\t\t/* Handle unexpected object arguments here too, for nice error\n\t\t * messages.\n\t\t */\n\t\th_arraybuf = NULL;\n\t\th_val = duk_require_hbuffer(thr, idx_buffer);\n\t}\n\n\t/* Wrap check for offset+length. */\n\tuint_added = uint_offset + uint_length;\n\tif (DUK_UNLIKELY(uint_added < uint_offset)) {\n\t\tgoto range_error;\n\t}\n\tDUK_ASSERT(uint_added >= uint_offset && uint_added >= uint_length);\n\n\tDUK_ASSERT(h_val != NULL);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(classnum),\n\t                               (duk_small_int_t) protobidx);\n\tDUK_ASSERT(h_bufobj != NULL);\n\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\th_bufobj->buf_prop = h_arraybuf;\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, h_arraybuf);\n\th_bufobj->offset = uint_offset;\n\th_bufobj->length = uint_length;\n\th_bufobj->shift = (tmp >> 4) & 0x0f;\n\th_bufobj->elem_type = (tmp >> 8) & 0xff;\n\th_bufobj->is_typedarray = tmp & 0x0f;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t/* TypedArray views need an automatic ArrayBuffer which must be\n\t * provided as .buffer property of the view.  The ArrayBuffer is\n\t * referenced via duk_hbufobj->buf_prop and an inherited .buffer\n\t * accessor returns it.  The ArrayBuffer is created lazily on first\n\t * access if necessary so we don't need to do anything more here.\n\t */\n\treturn;\n\n range_error:\n\tDUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARGS);\n\tDUK_WO_NORETURN(return;);\n\n arg_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_ARGS);\n\tDUK_WO_NORETURN(return;);\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\nDUK_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx_buffer);\n\tDUK_UNREF(byte_offset);\n\tDUK_UNREF(byte_length);\n\tDUK_UNREF(flags);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_EXTERNAL duk_idx_t duk_push_error_object_va_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap) {\n\tduk_hobject *proto;\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tduk_small_uint_t augment_flags;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_UNREF(filename);\n\tDUK_UNREF(line);\n\n\t/* Error code also packs a tracedata related flag. */\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\taugment_flags = 0;\n\tif (err_code & DUK_ERRCODE_FLAG_NOBLAME_FILELINE) {\n\t\taugment_flags = DUK_AUGMENT_FLAG_NOBLAME_FILELINE;\n\t}\n#endif\n\terr_code = err_code & (~DUK_ERRCODE_FLAG_NOBLAME_FILELINE);\n\n\t/* error gets its 'name' from the prototype */\n\tproto = duk_error_prototype_from_code(thr, err_code);\n\t(void) duk_push_object_helper_proto(thr,\n\t                                    DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                    DUK_HOBJECT_FLAG_FASTREFS |\n\t                                    DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ERROR),\n\t                                    proto);\n\n\t/* ... and its 'message' from an instance property */\n\tif (fmt) {\n\t\tduk_push_vsprintf(thr, fmt, ap);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);\n\t} else {\n\t\t/* If no explicit message given, put error code into message field\n\t\t * (as a number).  This is not fully in keeping with the ECMAScript\n\t\t * error model because messages are supposed to be strings (Error\n\t\t * constructors use ToString() on their argument).  However, it's\n\t\t * probably more useful than having a separate 'code' property.\n\t\t */\n\t\tduk_push_int(thr, err_code);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);\n\t}\n\n\t/* XXX: .code = err_code disabled, not sure if useful */\n\n\t/* Creation time error augmentation */\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\t/* filename may be NULL in which case file/line is not recorded */\n\tduk_err_augment_error_create(thr, thr, filename, line, augment_flags);  /* may throw an error */\n#endif\n\n\treturn duk_get_top_index_unsafe(thr);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_error_object_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...) {\n\tva_list ap;\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tva_start(ap, fmt);\n\tret = duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\n#if !defined(DUK_USE_VARIADIC_MACROS)\nDUK_EXTERNAL duk_idx_t duk_push_error_object_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, ...) {\n\tconst char *filename = duk_api_global_filename;\n\tduk_int_t line = duk_api_global_line;\n\tva_list ap;\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_api_global_filename = NULL;\n\tduk_api_global_line = 0;\n\tva_start(ap, fmt);\n\tret = duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\nDUK_EXTERNAL void *duk_push_buffer_raw(duk_hthread *thr, duk_size_t size, duk_small_uint_t flags) {\n\tduk_tval *tv_slot;\n\tduk_hbuffer *h;\n\tvoid *buf_data;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\t/* Check for maximum buffer length. */\n\tif (DUK_UNLIKELY(size > DUK_HBUFFER_MAX_BYTELEN)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_BUFFER_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\th = duk_hbuffer_alloc(thr->heap, size, flags, &buf_data);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_BUFFER(tv_slot, h);\n\tDUK_HBUFFER_INCREF(thr, h);\n\tthr->valstack_top++;\n\n\treturn (void *) buf_data;\n}\n\nDUK_INTERNAL void *duk_push_fixed_buffer_nozero(duk_hthread *thr, duk_size_t len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_push_buffer_raw(thr, len, DUK_BUF_FLAG_NOZERO);\n}\n\nDUK_INTERNAL void *duk_push_fixed_buffer_zero(duk_hthread *thr, duk_size_t len) {\n\tvoid *ptr;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tptr = duk_push_buffer_raw(thr, len, 0);\n\tDUK_ASSERT(ptr != NULL);\n#if !defined(DUK_USE_ZERO_BUFFER_DATA)\n\t/* ES2015 requires zeroing even when DUK_USE_ZERO_BUFFER_DATA\n\t * is not set.\n\t */\n\tduk_memzero((void *) ptr, (size_t) len);\n#endif\n\treturn ptr;\n}\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_EXTERNAL duk_idx_t duk_push_proxy(duk_hthread *thr, duk_uint_t proxy_flags) {\n\tduk_hobject *h_target;\n\tduk_hobject *h_handler;\n\tduk_hproxy *h_proxy;\n\tduk_tval *tv_slot;\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(proxy_flags);\n\n\t/* DUK__CHECK_SPACE() unnecessary because the Proxy is written to\n\t * value stack in-place.\n\t */\n#if 0\n\tDUK__CHECK_SPACE();\n#endif\n\n\t/* Reject a proxy object as the target because it would need\n\t * special handling in property lookups.  (ES2015 has no such\n\t * restriction.)\n\t */\n\th_target = duk_require_hobject_promote_mask(thr, -2, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(h_target != NULL);\n\tif (DUK_HOBJECT_IS_PROXY(h_target)) {\n\t\tgoto fail_args;\n\t}\n\n\t/* Reject a proxy object as the handler because it would cause\n\t * potentially unbounded recursion.  (ES2015 has no such\n\t * restriction.)\n\t *\n\t * There's little practical reason to use a lightfunc or a plain\n\t * buffer as the handler table: one could only provide traps via\n\t * their prototype objects (Function.prototype and ArrayBuffer.prototype).\n\t * Even so, as lightfuncs and plain buffers mimic their object\n\t * counterparts, they're promoted and accepted here.\n\t */\n\th_handler = duk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(h_handler != NULL);\n\tif (DUK_HOBJECT_IS_PROXY(h_handler)) {\n\t\tgoto fail_args;\n\t}\n\n\t/* XXX: Proxy object currently has no prototype, so ToPrimitive()\n\t * coercion fails which is a bit confusing.\n\t */\n\n\t/* CALLABLE and CONSTRUCTABLE flags are copied from the (initial)\n\t * target, see ES2015 Sections 9.5.15 and 9.5.13.\n\t */\n\tflags = DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h_target) &\n\t        (DUK_HOBJECT_FLAG_CALLABLE | DUK_HOBJECT_FLAG_CONSTRUCTABLE);\n\tflags |= DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t         DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ;\n\tif (flags & DUK_HOBJECT_FLAG_CALLABLE) {\n\t\tflags |= DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION) |\n\t\t         DUK_HOBJECT_FLAG_SPECIAL_CALL;\n\t} else {\n\t\tflags |= DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT);\n\t}\n\n\th_proxy = duk_hproxy_alloc(thr, flags);\n\tDUK_ASSERT(h_proxy != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_proxy) == NULL);\n\n\t/* Initialize Proxy target and handler references; avoid INCREF\n\t * by stealing the value stack refcounts via direct value stack\n\t * manipulation.  INCREF is needed for the Proxy itself however.\n\t */\n\tDUK_ASSERT(h_target != NULL);\n\th_proxy->target = h_target;\n\tDUK_ASSERT(h_handler != NULL);\n\th_proxy->handler = h_handler;\n\tDUK_HPROXY_ASSERT_VALID(h_proxy);\n\n\tDUK_ASSERT(duk_get_hobject(thr, -2) == h_target);\n\tDUK_ASSERT(duk_get_hobject(thr, -1) == h_handler);\n\ttv_slot = thr->valstack_top - 2;\n\tDUK_ASSERT(tv_slot >= thr->valstack_bottom);\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) h_proxy);\n\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) h_proxy);\n\ttv_slot++;\n\tDUK_TVAL_SET_UNDEFINED(tv_slot);  /* [ ... target handler ] -> [ ... proxy undefined ] */\n\tthr->valstack_top = tv_slot;      /* -> [ ... proxy ] */\n\n\tDUK_DD(DUK_DDPRINT(\"created Proxy: %!iT\", duk_get_tval(thr, -1)));\n\n\treturn (duk_idx_t) (thr->valstack_top - thr->valstack_bottom - 1);\n\n fail_args:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n#else  /* DUK_USE_ES6_PROXY */\nDUK_EXTERNAL duk_idx_t duk_push_proxy(duk_hthread *thr, duk_uint_t proxy_flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(proxy_flags);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_LOCAL void duk__validate_push_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_heaphdr *h;\n\tduk_heaphdr *curr;\n\tduk_bool_t found = 0;\n\n\th = (duk_heaphdr *) ptr;\n\tif (h == NULL) {\n\t\t/* Allowed. */\n\t\treturn;\n\t}\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\n\t/* One particular problem case is where an object has been\n\t * queued for finalization but the finalizer hasn't yet been\n\t * executed.\n\t *\n\t * Corner case: we're running in a finalizer for object X, and\n\t * user code calls duk_push_heapptr() for X itself.  In this\n\t * case X will be in finalize_list, and we can detect the case\n\t * by seeing that X's FINALIZED flag is set (which is done before\n\t * the finalizer starts executing).\n\t */\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tfor (curr = thr->heap->finalize_list;\n\t     curr != NULL;\n\t     curr = DUK_HEAPHDR_GET_NEXT(thr->heap, curr)) {\n\t\t/* FINALIZABLE is set for all objects on finalize_list\n\t\t * except for an object being finalized right now.  So\n\t\t * can't assert here.\n\t\t */\n#if 0\n\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZABLE(curr));\n#endif\n\n\t\tif (curr == h) {\n\t\t\tif (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) h)) {\n\t\t\t\t/* Object is currently being finalized. */\n\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\tfound = 1;\n\t\t\t} else {\n\t\t\t\t/* Not being finalized but on finalize_list,\n\t\t\t\t * allowed since Duktape 2.1.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\tfound = 1;\n\t\t\t}\n\t\t}\n\t}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* Because refzero_list is now processed to completion inline with\n\t * no side effects, it's always empty here.\n\t */\n\tDUK_ASSERT(thr->heap->refzero_list == NULL);\n#endif\n\n\t/* If not present in finalize_list (or refzero_list), it\n\t * must be either in heap_allocated or the string table.\n\t */\n\tif (DUK_HEAPHDR_IS_STRING(h)) {\n\t\tduk_uint32_t i;\n\t\tduk_hstring *str;\n\t\tduk_heap *heap = thr->heap;\n\n\t\tDUK_ASSERT(found == 0);\n\t\tfor (i = 0; i < heap->st_size; i++) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\t\tstr = DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, heap->strtable16[i]);\n#else\n\t\t\tstr = heap->strtable[i];\n#endif\n\t\t\twhile (str != NULL) {\n\t\t\t\tif (str == (duk_hstring *) h) {\n\t\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\t\tfound = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tstr = str->hdr.h_next;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(found != 0);\n\t} else {\n\t\tfor (curr = thr->heap->heap_allocated;\n\t\t     curr != NULL;\n\t\t     curr = DUK_HEAPHDR_GET_NEXT(thr->heap, curr)) {\n\t\t\tif (curr == h) {\n\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\tfound = 1;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(found != 0);\n\t}\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\nDUK_EXTERNAL duk_idx_t duk_push_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_idx_t ret;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Reviving an object using a heap pointer is a dangerous API\n\t * operation: if the application doesn't guarantee that the\n\t * pointer target is always reachable, difficult-to-diagnose\n\t * problems may ensue.  Try to validate the 'ptr' argument to\n\t * the extent possible.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__validate_push_heapptr(thr, ptr);\n#endif\n\n\tDUK__CHECK_SPACE();\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\ttv = thr->valstack_top++;\n\n\tif (ptr == NULL) {\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\treturn ret;\n\t}\n\n\tDUK_HEAPHDR_ASSERT_VALID((duk_heaphdr *) ptr);\n\n\t/* If the argument is on finalize_list it has technically been\n\t * unreachable before duk_push_heapptr() but it's still safe to\n\t * push it.  Starting from Duktape 2.1 allow application code to\n\t * do so.  There are two main cases:\n\t *\n\t *   (1) The object is on the finalize_list and we're called by\n\t *       the finalizer for the object being finalized.  In this\n\t *       case do nothing: finalize_list handling will deal with\n\t *       the object queueing.  This is detected by the object not\n\t *       having a FINALIZABLE flag despite being on the finalize_list;\n\t *       the flag is cleared for the object being finalized only.\n\t *\n\t *   (2) The object is on the finalize_list but is not currently\n\t *       being processed.  In this case the object can be queued\n\t *       back to heap_allocated with a few flags cleared, in effect\n\t *       cancelling the finalizer.\n\t */\n\tif (DUK_UNLIKELY(DUK_HEAPHDR_HAS_FINALIZABLE((duk_heaphdr *) ptr))) {\n\t\tduk_heaphdr *curr;\n\n\t\tDUK_D(DUK_DPRINT(\"duk_push_heapptr() with a pointer on finalize_list, autorescue\"));\n\n\t\tcurr = (duk_heaphdr *) ptr;\n\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\n\t\t/* Because FINALIZED is set prior to finalizer call, it will\n\t\t * be set for the object being currently finalized, but not\n\t\t * for other objects on finalize_list.\n\t\t */\n\t\tDUK_HEAPHDR_CLEAR_FINALIZED(curr);\n\n\t\t/* Dequeue object from finalize_list and queue it back to\n\t\t * heap_allocated.\n\t\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) >= 1);  /* Preincremented on finalize_list insert. */\n\t\tDUK_HEAPHDR_PREDEC_REFCOUNT(curr);\n#endif\n\t\tDUK_HEAP_REMOVE_FROM_FINALIZE_LIST(thr->heap, curr);\n\t\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(thr->heap, curr);\n\n\t\t/* Continue with the rest. */\n\t}\n\n\tswitch (DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) ptr)) {\n\tcase DUK_HTYPE_STRING:\n\t\tDUK_TVAL_SET_STRING(tv, (duk_hstring *) ptr);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tDUK_TVAL_SET_OBJECT(tv, (duk_hobject *) ptr);\n\t\tbreak;\n\tdefault:\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) ptr) == DUK_HTYPE_BUFFER);\n\t\tDUK_TVAL_SET_BUFFER(tv, (duk_hbuffer *) ptr);\n\t\tbreak;\n\t}\n\n\tDUK_HEAPHDR_INCREF(thr, (duk_heaphdr *) ptr);\n\n\treturn ret;\n}\n\n/* Push object with no prototype, i.e. a \"bare\" object. */\nDUK_EXTERNAL duk_idx_t duk_push_bare_object(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              -1);  /* no prototype */\n\treturn duk_get_top_index_unsafe(thr);\n}\n\nDUK_INTERNAL void duk_push_hstring(duk_hthread *thr, duk_hstring *h) {\n\tduk_tval tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_TVAL_SET_STRING(&tv, h);\n\tduk_push_tval(thr, &tv);\n}\n\nDUK_INTERNAL void duk_push_hstring_stridx(duk_hthread *thr, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n}\n\nDUK_INTERNAL void duk_push_hstring_empty(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, DUK_STRIDX_EMPTY_STRING));\n}\n\nDUK_INTERNAL void duk_push_hobject(duk_hthread *thr, duk_hobject *h) {\n\tduk_tval tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_TVAL_SET_OBJECT(&tv, h);\n\tduk_push_tval(thr, &tv);\n}\n\nDUK_INTERNAL void duk_push_hbuffer(duk_hthread *thr, duk_hbuffer *h) {\n\tduk_tval tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_TVAL_SET_BUFFER(&tv, h);\n\tduk_push_tval(thr, &tv);\n}\n\nDUK_INTERNAL void duk_push_hobject_bidx(duk_hthread *thr, duk_small_int_t builtin_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(builtin_idx >= 0 && builtin_idx < DUK_NUM_BUILTINS);\n\tDUK_ASSERT(thr->builtins[builtin_idx] != NULL);\n\n\tduk_push_hobject(thr, thr->builtins[builtin_idx]);\n}\n\n/*\n *  Poppers\n */\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_n_unsafe_raw(duk_hthread *thr, duk_idx_t count) {\n\tduk_tval *tv;\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_tval *tv_end;\n#endif\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) count);\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\ttv = thr->valstack_top;\n\ttv_end = tv - count;\n\twhile (tv != tv_end) {\n\t\ttv--;\n\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t}\n\tthr->valstack_top = tv;\n\tDUK_REFZERO_CHECK_FAST(thr);\n#else\n\ttv = thr->valstack_top;\n\twhile (count > 0) {\n\t\tcount--;\n\t\ttv--;\n\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t}\n\tthr->valstack_top = tv;\n#endif\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n\nDUK_EXTERNAL void duk_pop_n(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\n\tif (DUK_UNLIKELY((duk_uidx_t) (thr->valstack_top - thr->valstack_bottom) < (duk_uidx_t) count)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(count >= 0);\n\n\tduk__pop_n_unsafe_raw(thr, count);\n}\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, count);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk__pop_n_unsafe_raw(thr, count);\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/* Pop N elements without DECREF (in effect \"stealing\" any actual refcounts). */\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) count);\n\n\ttv = thr->valstack_top;\n\twhile (count > 0) {\n\t\tcount--;\n\t\ttv--;\n\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t}\n\tthr->valstack_top = tv;\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#else  /* DUK_USE_REFERENCE_COUNTING */\nDUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, count);\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/* Popping one element is called so often that when footprint is not an issue,\n * compile a specialized function for it.\n */\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL void duk_pop(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, 1);\n}\nDUK_INTERNAL void duk_pop_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, 1);\n}\nDUK_INTERNAL void duk_pop_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_nodecref_unsafe(thr, 1);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_unsafe_raw(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);\n\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n#else\n\tDUK_TVAL_SET_UNDEFINED(tv);\n#endif\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\nDUK_EXTERNAL void duk_pop(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tif (DUK_UNLIKELY(thr->valstack_top == thr->valstack_bottom)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk__pop_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk__pop_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_nodecref_unsafe(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);\n\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\tDUK_TVAL_SET_UNDEFINED(tv);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_pop_undefined(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_nodecref_unsafe(thr);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_pop_undefined(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);\n\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));\n\tthr->valstack_top--;\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL void duk_pop_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, 2);\n}\nDUK_INTERNAL void duk_pop_2_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, 2);\n}\nDUK_INTERNAL void duk_pop_2_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_nodecref_unsafe(thr, 2);\n}\n#else\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_2_unsafe_raw(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 2);\n\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n#else\n\tDUK_TVAL_SET_UNDEFINED(tv);\n#endif\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n#else\n\tDUK_TVAL_SET_UNDEFINED(tv);\n#endif\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\nDUK_EXTERNAL void duk_pop_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tif (DUK_UNLIKELY(thr->valstack_top - 2 < thr->valstack_bottom)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk__pop_2_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_2_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk__pop_2_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_2_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 2);\n\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 2));\n\tthr->valstack_top -= 2;\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\nDUK_EXTERNAL void duk_pop_3(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, 3);\n}\n\nDUK_INTERNAL void duk_pop_3_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, 3);\n}\n\nDUK_INTERNAL void duk_pop_3_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_nodecref_unsafe(thr, 3);\n}\n\n/*\n *  Pack and unpack (pack value stack entries into an array and vice versa)\n */\n\n/* XXX: pack index range? array index offset? */\n/* XXX: need ability to pack into a bare array? */\nDUK_INTERNAL void duk_pack(duk_hthread *thr, duk_idx_t count) {\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_tval *tv_curr;\n\tduk_tval *tv_limit;\n\tduk_idx_t top;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\ttop = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT(top >= 0);\n\tif (DUK_UNLIKELY((duk_uidx_t) count > (duk_uidx_t) top)) {\n\t\t/* Also handles negative count. */\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(count >= 0);\n\n\t/* Wrapping is controlled by the check above: value stack top can be\n\t * at most DUK_USE_VALSTACK_LIMIT which is low enough so that\n\t * multiplying with sizeof(duk_tval) won't wrap.\n\t */\n\tDUK_ASSERT(count >= 0 && count <= (duk_idx_t) DUK_USE_VALSTACK_LIMIT);\n\tDUK_ASSERT((duk_size_t) count <= DUK_SIZE_MAX / sizeof(duk_tval));  /* no wrapping */\n\n\ttv_dst = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) count);  /* XXX: uninitialized would be OK */\n\tDUK_ASSERT(count == 0 || tv_dst != NULL);\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\t/* Copy value stack values directly to the array part without\n\t * any refcount updates: net refcount changes are zero.\n\t */\n\ttv_src = thr->valstack_top - count - 1;\n\tduk_memcpy_unsafe((void *) tv_dst, (const void *) tv_src, (size_t) count * sizeof(duk_tval));\n\n\t/* Overwrite result array to final value stack location and wipe\n\t * the rest; no refcount operations needed.\n\t */\n\n\ttv_dst = tv_src;  /* when count == 0, same as tv_src (OK) */\n\ttv_src = thr->valstack_top - 1;\n\tDUK_TVAL_SET_TVAL(tv_dst, tv_src);\n\n\t/* XXX: internal helper to wipe a value stack segment? */\n\ttv_curr = tv_dst + 1;\n\ttv_limit = thr->valstack_top;\n\twhile (tv_curr != tv_limit) {\n\t\t/* Wipe policy: keep as 'undefined'. */\n\t\tDUK_TVAL_SET_UNDEFINED(tv_curr);\n\t\ttv_curr++;\n\t}\n\tthr->valstack_top = tv_dst + 1;\n}\n\nDUK_INTERNAL duk_idx_t duk_unpack_array_like(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tif (DUK_LIKELY(DUK_TVAL_IS_OBJECT(tv))) {\n\t\tduk_hobject *h;\n\t\tduk_uint32_t len;\n\t\tduk_uint32_t i;\n\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_UNREF(h);\n\n#if defined(DUK_USE_ARRAY_FASTPATH)  /* close enough */\n\t\tif (DUK_LIKELY(DUK_HOBJECT_IS_ARRAY(h) &&\n\t\t               ((duk_harray *) h)->length <= DUK_HOBJECT_GET_ASIZE(h))) {\n\t\t\tduk_harray *h_arr;\n\t\t\tduk_tval *tv_src;\n\t\t\tduk_tval *tv_dst;\n\n\t\t\th_arr = (duk_harray *) h;\n\t\t\tlen = h_arr->length;\n\t\t\tif (DUK_UNLIKELY(len >= 0x80000000UL)) {\n\t\t\t\tgoto fail_over_2g;\n\t\t\t}\n\t\t\tduk_require_stack(thr, (duk_idx_t) len);\n\n\t\t\t/* The potential allocation in duk_require_stack() may\n\t\t\t * run a finalizer which modifies the argArray so that\n\t\t\t * e.g. becomes sparse.  So, we need to recheck that the\n\t\t\t * array didn't change size and that there's still a\n\t\t\t * valid backing array part.\n\t\t\t *\n\t\t\t * XXX: alternatively, could prevent finalizers for the\n\t\t\t * duration.\n\t\t\t */\n\t\t\tif (DUK_UNLIKELY(len != h_arr->length ||\n\t\t\t                 h_arr->length > DUK_HOBJECT_GET_ASIZE((duk_hobject *) h_arr))) {\n\t\t\t\tgoto skip_fast;\n\t\t\t}\n\n\t\t\t/* Main fast path: arguments array is almost always\n\t\t\t * an actual array (though it might also be an arguments\n\t\t\t * object).\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path for %ld elements\", (long) h_arr->length));\n\t\t\ttv_src = DUK_HOBJECT_A_GET_BASE(thr->heap, h);\n\t\t\ttv_dst = thr->valstack_top;\n\t\t\twhile (len-- > 0) {\n\t\t\t\tDUK_ASSERT(tv_dst < thr->valstack_end);\n\t\t\t\tif (DUK_UNLIKELY(DUK_TVAL_IS_UNUSED(tv_src))) {\n\t\t\t\t\t/* Gaps are very unlikely.  Skip over them,\n\t\t\t\t\t * without an ancestor lookup (technically\n\t\t\t\t\t * not compliant).\n\t\t\t\t\t */\n\t\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_dst));  /* valstack policy */\n\t\t\t\t} else {\n\t\t\t\t\tDUK_TVAL_SET_TVAL(tv_dst, tv_src);\n\t\t\t\t\tDUK_TVAL_INCREF(thr, tv_dst);\n\t\t\t\t}\n\t\t\t\ttv_src++;\n\t\t\t\ttv_dst++;\n\t\t\t}\n\t\t\tDUK_ASSERT(tv_dst <= thr->valstack_end);\n\t\t\tthr->valstack_top = tv_dst;\n\t\t\treturn (duk_idx_t) h_arr->length;\n\t\t}\n\t skip_fast:\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\n\t\t/* Slow path: actual lookups.  The initial 'length' lookup\n\t\t * decides the output length, regardless of side effects that\n\t\t * may resize or change the argArray while we read the\n\t\t * indices.\n\t\t */\n\t\tidx = duk_normalize_index(thr, idx);\n\t\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n\t\tlen = duk_to_uint32(thr, -1);  /* ToUint32() coercion required */\n\t\tif (DUK_UNLIKELY(len >= 0x80000000UL)) {\n\t\t\tgoto fail_over_2g;\n\t\t}\n\t\tduk_pop_unsafe(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"slow path for %ld elements\", (long) len));\n\n\t\tduk_require_stack(thr, (duk_idx_t) len);\n\t\tfor (i = 0; i < len; i++) {\n\t\t\tduk_get_prop_index(thr, idx, (duk_uarridx_t) i);\n\t\t}\n\t\treturn (duk_idx_t) len;\n\t} else if (DUK_TVAL_IS_UNDEFINED(tv) || DUK_TVAL_IS_NULL(tv)) {\n\t\treturn 0;\n\t}\n\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n\n fail_over_2g:\n\tDUK_ERROR_RANGE_INVALID_LENGTH(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/*\n *  Error throwing\n */\n\nDUK_EXTERNAL void duk_throw_raw(duk_hthread *thr) {\n\tduk_tval *tv_val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\n\tif (DUK_UNLIKELY(thr->valstack_top == thr->valstack_bottom)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* Errors are augmented when they are created, not when they are\n\t * thrown or re-thrown.  The current error handler, however, runs\n\t * just before an error is thrown.\n\t */\n\n\t/* Sync so that augmentation sees up-to-date activations, NULL\n\t * thr->ptr_curr_pc so that it's not used if side effects occur\n\t * in augmentation or longjmp handling.\n\t */\n\tduk_hthread_sync_and_null_currpc(thr);\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (API): %!dT (before throw augment)\", (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_err_augment_error_throw(thr);\n#endif\n\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (API): %!dT (after throw augment)\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\ttv_val = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, tv_val);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_err_check_debugger_integration(thr);\n#endif\n\n\t/* thr->heap->lj.jmpbuf_ptr is checked by duk_err_longjmp() so we don't\n\t * need to check that here.  If the value is NULL, a fatal error occurs\n\t * because we can't return.\n\t */\n\n\tduk_err_longjmp(thr);\n\tDUK_UNREACHABLE();\n}\n\nDUK_EXTERNAL void duk_fatal_raw(duk_hthread *thr, const char *err_msg) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->heap->fatal_func != NULL);\n\n\tDUK_D(DUK_DPRINT(\"fatal error occurred: %s\", err_msg ? err_msg : \"NULL\"));\n\n\t/* fatal_func should be noreturn, but noreturn declarations on function\n\t * pointers has a very spotty support apparently so it's not currently\n\t * done.\n\t */\n\tthr->heap->fatal_func(thr->heap->heap_udata, err_msg);\n\n\t/* If the fatal handler returns, all bets are off.  It'd be nice to\n\t * print something here but since we don't want to depend on stdio,\n\t * there's no way to do so portably.\n\t */\n\tDUK_D(DUK_DPRINT(\"fatal error handler returned, all bets are off!\"));\n\tfor (;;) {\n\t\t/* loop forever, don't return (function marked noreturn) */\n\t}\n}\n\nDUK_EXTERNAL void duk_error_va_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\t(void) duk_throw(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_error_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...) {\n\tva_list ap;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tva_start(ap, fmt);\n\tduk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\tva_end(ap);\n\t(void) duk_throw(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n#if !defined(DUK_USE_VARIADIC_MACROS)\nDUK_NORETURN(DUK_LOCAL_DECL void duk__throw_error_from_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, va_list ap));\n\nDUK_LOCAL void duk__throw_error_from_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, va_list ap) {\n\tconst char *filename;\n\tduk_int_t line;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tfilename = duk_api_global_filename;\n\tline = duk_api_global_line;\n\tduk_api_global_filename = NULL;\n\tduk_api_global_line = 0;\n\n\tduk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\t(void) duk_throw(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n#define DUK__ERROR_STASH_SHARED(code) do { \\\n\t\tva_list ap; \\\n\t\tva_start(ap, fmt); \\\n\t\tduk__throw_error_from_stash(thr, (code), fmt, ap); \\\n\t\tva_end(ap); \\\n\t\tDUK_WO_NORETURN(return 0;); \\\n\t} while (0)\n\nDUK_EXTERNAL duk_ret_t duk_error_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(err_code);\n}\nDUK_EXTERNAL duk_ret_t duk_generic_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_eval_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_EVAL_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_range_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_RANGE_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_reference_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_REFERENCE_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_syntax_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_SYNTAX_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_type_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_TYPE_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_uri_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_URI_ERROR);\n}\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n/*\n *  Comparison\n */\n\nDUK_EXTERNAL duk_bool_t duk_equals(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_get_tval(thr, idx1);\n\ttv2 = duk_get_tval(thr, idx2);\n\tif ((tv1 == NULL) || (tv2 == NULL)) {\n\t\treturn 0;\n\t}\n\n\t/* Coercion may be needed, the helper handles that by pushing the\n\t * tagged values to the stack.\n\t */\n\treturn duk_js_equals(thr, tv1, tv2);\n}\n\nDUK_EXTERNAL duk_bool_t duk_strict_equals(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_get_tval(thr, idx1);\n\ttv2 = duk_get_tval(thr, idx2);\n\tif ((tv1 == NULL) || (tv2 == NULL)) {\n\t\treturn 0;\n\t}\n\n\t/* No coercions or other side effects, so safe */\n\treturn duk_js_strict_equals(tv1, tv2);\n}\n\nDUK_EXTERNAL duk_bool_t duk_samevalue(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_get_tval(thr, idx1);\n\ttv2 = duk_get_tval(thr, idx2);\n\tif ((tv1 == NULL) || (tv2 == NULL)) {\n\t\treturn 0;\n\t}\n\n\t/* No coercions or other side effects, so safe */\n\treturn duk_js_samevalue(tv1, tv2);\n}\n\n/*\n *  instanceof\n */\n\nDUK_EXTERNAL duk_bool_t duk_instanceof(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Index validation is strict, which differs from duk_equals().\n\t * The strict behavior mimics how instanceof itself works, e.g.\n\t * it is a TypeError if rval is not a -callable- object.  It would\n\t * be somewhat inconsistent if rval would be allowed to be\n\t * non-existent without a TypeError.\n\t */\n\ttv1 = duk_require_tval(thr, idx1);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, idx2);\n\tDUK_ASSERT(tv2 != NULL);\n\n\treturn duk_js_instanceof(thr, tv1, tv2);\n}\n\n/*\n *  Lightfunc\n */\n\nDUK_INTERNAL void duk_push_lightfunc_name_raw(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags) {\n\t/* Lightfunc name, includes Duktape/C native function pointer, which\n\t * can often be used to locate the function from a symbol table.\n\t * The name also includes the 16-bit duk_tval flags field because it\n\t * includes the magic value.  Because a single native function often\n\t * provides different functionality depending on the magic value, it\n\t * seems reasonably to include it in the name.\n\t *\n\t * On the other hand, a complicated name increases string table\n\t * pressure in low memory environments (but only when function name\n\t * is accessed).\n\t */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_literal(thr, \"light_\");\n\tduk_push_string_funcptr(thr, (duk_uint8_t *) &func, sizeof(func));\n\tduk_push_sprintf(thr, \"_%04x\", (unsigned int) lf_flags);\n\tduk_concat(thr, 3);\n}\n\nDUK_INTERNAL void duk_push_lightfunc_name(duk_hthread *thr, duk_tval *tv) {\n\tduk_c_function func;\n\tduk_small_uint_t lf_flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv));\n\n\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);\n\tduk_push_lightfunc_name_raw(thr, func, lf_flags);\n}\n\nDUK_INTERNAL void duk_push_lightfunc_tostring(duk_hthread *thr, duk_tval *tv) {\n\tduk_c_function func;\n\tduk_small_uint_t lf_flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv));\n\n\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);  /* read before 'tv' potentially invalidated */\n\tduk_push_literal(thr, \"function \");\n\tduk_push_lightfunc_name_raw(thr, func, lf_flags);\n\tduk_push_literal(thr, \"() { [lightfunc code] }\");\n\tduk_concat(thr, 3);\n}\n\n/*\n *  Function pointers\n *\n *  Printing function pointers is non-portable, so we do that by hex printing\n *  bytes from memory.\n */\n\nDUK_INTERNAL void duk_push_string_funcptr(duk_hthread *thr, duk_uint8_t *ptr, duk_size_t sz) {\n\tduk_uint8_t buf[32 * 2];\n\tduk_uint8_t *p, *q;\n\tduk_small_uint_t i;\n\tduk_small_uint_t t;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(sz <= 32);  /* sanity limit for function pointer size */\n\n\tp = buf;\n#if defined(DUK_USE_INTEGER_LE)\n\tq = ptr + sz;\n#else\n\tq = ptr;\n#endif\n\tfor (i = 0; i < sz; i++) {\n#if defined(DUK_USE_INTEGER_LE)\n\t\tt = *(--q);\n#else\n\t\tt = *(q++);\n#endif\n\t\t*p++ = duk_lc_digits[t >> 4];\n\t\t*p++ = duk_lc_digits[t & 0x0f];\n\t}\n\n\tduk_push_lstring(thr, (const char *) buf, sz * 2);\n}\n\n/*\n *  Push readable string summarizing duk_tval.  The operation is side effect\n *  free and will only throw from internal errors (e.g. out of memory).\n *  This is used by e.g. property access code to summarize a key/base safely,\n *  and is not intended to be fast (but small and safe).\n */\n\n/* String limits for summary strings. */\n#define DUK__READABLE_SUMMARY_MAXCHARS 96  /* maximum supported by helper */\n#define DUK__READABLE_STRING_MAXCHARS  32  /* for strings/symbols */\n#define DUK__READABLE_ERRMSG_MAXCHARS  96  /* for error messages */\n\n/* String sanitizer which escapes ASCII control characters and a few other\n * ASCII characters, passes Unicode as is, and replaces invalid UTF-8 with\n * question marks.  No errors are thrown for any input string, except in out\n * of memory situations.\n */\nDUK_LOCAL void duk__push_hstring_readable_unicode(duk_hthread *thr, duk_hstring *h_input, duk_small_uint_t maxchars) {\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_uint8_t buf[DUK_UNICODE_MAX_XUTF8_LENGTH * DUK__READABLE_SUMMARY_MAXCHARS +\n\t                2 /*quotes*/ + 3 /*periods*/];\n\tduk_uint8_t *q;\n\tduk_ucodepoint_t cp;\n\tduk_small_uint_t nchars;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(h_input != NULL);\n\tDUK_ASSERT(maxchars <= DUK__READABLE_SUMMARY_MAXCHARS);\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\tq = buf;\n\n\tnchars = 0;\n\t*q++ = (duk_uint8_t) DUK_ASC_SINGLEQUOTE;\n\tfor (;;) {\n\t\tif (p >= p_end) {\n\t\t\tbreak;\n\t\t}\n\t\tif (nchars == maxchars) {\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_PERIOD;\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_PERIOD;\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_PERIOD;\n\t\t\tbreak;\n\t\t}\n\t\tif (duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp)) {\n\t\t\tif (cp < 0x20 || cp == 0x7f || cp == DUK_ASC_SINGLEQUOTE || cp == DUK_ASC_BACKSLASH) {\n\t\t\t\tDUK_ASSERT(DUK_UNICODE_MAX_XUTF8_LENGTH >= 4);  /* estimate is valid */\n\t\t\t\tDUK_ASSERT((cp >> 4) <= 0x0f);\n\t\t\t\t*q++ = (duk_uint8_t) DUK_ASC_BACKSLASH;\n\t\t\t\t*q++ = (duk_uint8_t) DUK_ASC_LC_X;\n\t\t\t\t*q++ = (duk_uint8_t) duk_lc_digits[cp >> 4];\n\t\t\t\t*q++ = (duk_uint8_t) duk_lc_digits[cp & 0x0f];\n\t\t\t} else {\n\t\t\t\tq += duk_unicode_encode_xutf8(cp, q);\n\t\t\t}\n\t\t} else {\n\t\t\tp++;  /* advance manually */\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_QUESTION;\n\t\t}\n\t\tnchars++;\n\t}\n\t*q++ = (duk_uint8_t) DUK_ASC_SINGLEQUOTE;\n\n\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) (q - buf));\n}\n\nDUK_LOCAL const char *duk__push_string_tval_readable(duk_hthread *thr, duk_tval *tv, duk_bool_t error_aware) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\t/* 'tv' may be NULL */\n\n\tif (tv == NULL) {\n\t\tduk_push_literal(thr, \"none\");\n\t} else {\n\t\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\t\tcase DUK_TAG_STRING: {\n\t\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\t\tif (DUK_HSTRING_HAS_SYMBOL(h)) {\n\t\t\t\t/* XXX: string summary produces question marks\n\t\t\t\t * so this is not very ideal.\n\t\t\t\t */\n\t\t\t\tduk_push_literal(thr, \"[Symbol \");\n\t\t\t\tduk_push_string(thr, duk__get_symbol_type_string(h));\n\t\t\t\tduk_push_literal(thr, \" \");\n\t\t\t\tduk__push_hstring_readable_unicode(thr, h, DUK__READABLE_STRING_MAXCHARS);\n\t\t\t\tduk_push_literal(thr, \"]\");\n\t\t\t\tduk_concat(thr, 5);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tduk__push_hstring_readable_unicode(thr, h, DUK__READABLE_STRING_MAXCHARS);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_OBJECT: {\n\t\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\t\tDUK_ASSERT(h != NULL);\n\n\t\t\tif (error_aware &&\n\t\t\t    duk_hobject_prototype_chain_contains(thr, h, thr->builtins[DUK_BIDX_ERROR_PROTOTYPE], 1 /*ignore_loop*/)) {\n\t\t\t\t/* Get error message in a side effect free way if\n\t\t\t\t * possible; if not, summarize as a generic object.\n\t\t\t\t * Error message currently gets quoted.\n\t\t\t\t */\n\t\t\t\t/* XXX: better internal getprop call; get without side effects\n\t\t\t\t * but traverse inheritance chain.\n\t\t\t\t */\n\t\t\t\tduk_tval *tv_msg;\n\t\t\t\ttv_msg = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, h, DUK_STRIDX_MESSAGE);\n\t\t\t\tif (tv_msg != NULL && DUK_TVAL_IS_STRING(tv_msg)) {\n\t\t\t\t\t/* It's critical to avoid recursion so\n\t\t\t\t\t * only summarize a string .message.\n\t\t\t\t\t */\n\t\t\t\t\tduk__push_hstring_readable_unicode(thr, DUK_TVAL_GET_STRING(tv_msg), DUK__READABLE_ERRMSG_MAXCHARS);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tduk_push_class_string_tval(thr, tv, 1 /*avoid_side_effects*/);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_BUFFER: {\n\t\t\t/* While plain buffers mimic Uint8Arrays, they summarize differently.\n\t\t\t * This is useful so that the summarized string accurately reflects the\n\t\t\t * internal type which may matter for figuring out bugs etc.\n\t\t\t */\n\t\t\t/* XXX: Hex encoded, length limited buffer summary here? */\n\t\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\t\tDUK_ASSERT(h != NULL);\n\t\t\tduk_push_sprintf(thr, \"[buffer:%ld]\", (long) DUK_HBUFFER_GET_SIZE(h));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_POINTER: {\n\t\t\t/* Surround with parentheses like in JX, ensures NULL pointer\n\t\t\t * is distinguishable from null value (\"(null)\" vs \"null\").\n\t\t\t */\n\t\t\tduk_push_tval(thr, tv);\n\t\t\tduk_push_sprintf(thr, \"(%s)\", duk_to_string(thr, -1));\n\t\t\tduk_remove_m2(thr);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tduk_push_tval(thr, tv);\n\t\t\tbreak;\n\t\t}\n\t\t}\n\t}\n\n\treturn duk_to_string(thr, -1);\n}\nDUK_INTERNAL const char *duk_push_string_tval_readable(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__push_string_tval_readable(thr, tv, 0 /*error_aware*/);\n}\n\nDUK_INTERNAL const char *duk_push_string_readable(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_push_string_tval_readable(thr, duk_get_tval(thr, idx));\n}\n\nDUK_INTERNAL const char *duk_push_string_tval_readable_error(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__push_string_tval_readable(thr, tv, 1 /*error_aware*/);\n}\n\nDUK_INTERNAL void duk_push_symbol_descriptive_string(duk_hthread *thr, duk_hstring *h) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint8_t *q;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* .toString() */\n\tduk_push_literal(thr, \"Symbol(\");\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tp_end = p + DUK_HSTRING_GET_BYTELEN(h);\n\tDUK_ASSERT(p[0] == 0xff || (p[0] & 0xc0) == 0x80);\n\tp++;\n\tfor (q = p; q < p_end; q++) {\n\t\tif (*q == 0xffU) {\n\t\t\t/* Terminate either at end-of-string (but NUL MUST\n\t\t\t * be accepted without terminating description) or\n\t\t\t * 0xFF, which is used to mark start of unique trailer\n\t\t\t * (and cannot occur in CESU-8 / extended UTF-8).\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\t}\n\tduk_push_lstring(thr, (const char *) p, (duk_size_t) (q - p));\n\tduk_push_literal(thr, \")\");\n\tduk_concat(thr, 3);\n}\n\n/*\n *  Functions\n */\n\n#if 0  /* not used yet */\nDUK_INTERNAL void duk_push_hnatfunc_name(duk_hthread *thr, duk_hnatfunc *h) {\n\tduk_c_function func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h));\n\n\tduk_push_sprintf(thr, \"native_\");\n\tfunc = h->func;\n\tduk_push_string_funcptr(thr, (duk_uint8_t *) &func, sizeof(func));\n\tduk_push_sprintf(thr, \"_%04x_%04x\",\n\t                 (unsigned int) (duk_uint16_t) h->nargs,\n\t                 (unsigned int) (duk_uint16_t) h->magic);\n\tduk_concat(thr, 3);\n}\n#endif\n\n/*\n *  duk_tval slice copy\n */\n\nDUK_INTERNAL void duk_copy_tvals_incref(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_size_t count) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n\tDUK_ASSERT(count * sizeof(duk_tval) >= count);  /* no wrap */\n\n\tduk_memcpy_unsafe((void *) tv_dst, (const void *) tv_src, count * sizeof(duk_tval));\n\n\ttv = tv_dst;\n\twhile (count-- > 0) {\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\ttv++;\n\t}\n}\n\n/* automatic undefs */\n#undef DUK__ASSERT_SPACE\n#undef DUK__CHECK_SPACE\n#undef DUK__ERROR_STASH_SHARED\n#undef DUK__PACK_ARGS\n#undef DUK__READABLE_ERRMSG_MAXCHARS\n#undef DUK__READABLE_STRING_MAXCHARS\n#undef DUK__READABLE_SUMMARY_MAXCHARS\n#line 1 \"duk_api_string.c\"\n/*\n *  String manipulation\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_LOCAL void duk__concat_and_join_helper(duk_hthread *thr, duk_idx_t count_in, duk_bool_t is_join) {\n\tduk_uint_t count;\n\tduk_uint_t i;\n\tduk_size_t idx;\n\tduk_size_t len;\n\tduk_hstring *h;\n\tduk_uint8_t *buf;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tif (DUK_UNLIKELY(count_in <= 0)) {\n\t\tif (count_in < 0) {\n\t\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tDUK_ASSERT(count_in == 0);\n\t\tduk_push_hstring_empty(thr);\n\t\treturn;\n\t}\n\tcount = (duk_uint_t) count_in;\n\n\tif (is_join) {\n\t\tduk_size_t t1, t2, limit;\n\t\th = duk_to_hstring(thr, -((duk_idx_t) count) - 1);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* A bit tricky overflow test, see doc/code-issues.rst. */\n\t\tt1 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);\n\t\tt2 = (duk_size_t) (count - 1);\n\t\tlimit = (duk_size_t) DUK_HSTRING_MAX_BYTELEN;\n\t\tif (DUK_UNLIKELY(t2 != 0 && t1 > limit / t2)) {\n\t\t\t/* Combined size of separators already overflows. */\n\t\t\tgoto error_overflow;\n\t\t}\n\t\tlen = (duk_size_t) (t1 * t2);\n\t} else {\n\t\tlen = (duk_size_t) 0;\n\t}\n\n\tfor (i = count; i >= 1; i--) {\n\t\tduk_size_t new_len;\n\t\th = duk_to_hstring(thr, -((duk_idx_t) i));\n\t\tnew_len = len + (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);\n\n\t\t/* Impose a string maximum length, need to handle overflow\n\t\t * correctly.\n\t\t */\n\t\tif (new_len < len ||  /* wrapped */\n\t\t    new_len > (duk_size_t) DUK_HSTRING_MAX_BYTELEN) {\n\t\t\tgoto error_overflow;\n\t\t}\n\t\tlen = new_len;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"join/concat %lu strings, total length %lu bytes\",\n\t                     (unsigned long) count, (unsigned long) len));\n\n\t/* Use stack allocated buffer to ensure reachability in errors\n\t * (e.g. intern error).\n\t */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len);\n\tDUK_ASSERT(buf != NULL);\n\n\t/* [ ... (sep) str1 str2 ... strN buf ] */\n\n\tidx = 0;\n\tfor (i = count; i >= 1; i--) {\n\t\tif (is_join && i != count) {\n\t\t\th = duk_require_hstring(thr, -((duk_idx_t) count) - 2);  /* extra -1 for buffer */\n\t\t\tduk_memcpy(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\t\t\tidx += DUK_HSTRING_GET_BYTELEN(h);\n\t\t}\n\t\th = duk_require_hstring(thr, -((duk_idx_t) i) - 1);  /* extra -1 for buffer */\n\t\tduk_memcpy(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\t\tidx += DUK_HSTRING_GET_BYTELEN(h);\n\t}\n\n\tDUK_ASSERT(idx == len);\n\n\t/* [ ... (sep) str1 str2 ... strN buf ] */\n\n\t/* Get rid of the strings early to minimize memory use before intern. */\n\n\tif (is_join) {\n\t\tduk_replace(thr, -((duk_idx_t) count) - 2);  /* overwrite sep */\n\t\tduk_pop_n(thr, (duk_idx_t) count);\n\t} else {\n\t\tduk_replace(thr, -((duk_idx_t) count) - 1);  /* overwrite str1 */\n\t\tduk_pop_n(thr, (duk_idx_t) (count - 1));\n\t}\n\n\t/* [ ... buf ] */\n\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if inputs are safe. */\n\n\t/* [ ... res ] */\n\treturn;\n\n error_overflow:\n\tDUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_concat(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__concat_and_join_helper(thr, count, 0 /*is_join*/);\n}\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_concat_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_concat(thr, 2);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_concat_2(duk_hthread *thr) {\n\tduk_hstring *h1;\n\tduk_hstring *h2;\n\tduk_uint8_t *buf;\n\tduk_size_t len1;\n\tduk_size_t len2;\n\tduk_size_t len;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_top(thr) >= 2);  /* Trusted caller. */\n\n\th1 = duk_to_hstring(thr, -2);\n\th2 = duk_to_hstring(thr, -1);\n\tlen1 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1);\n\tlen2 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2);\n\tlen = len1 + len2;\n\tif (DUK_UNLIKELY(len < len1 ||  /* wrapped */\n\t                 len > (duk_size_t) DUK_HSTRING_MAX_BYTELEN)) {\n\t\tgoto error_overflow;\n\t}\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len);\n\tDUK_ASSERT(buf != NULL);\n\n\tduk_memcpy((void *) buf, (const void *) DUK_HSTRING_GET_DATA(h1), (size_t) len1);\n\tduk_memcpy((void *) (buf + len1), (const void *) DUK_HSTRING_GET_DATA(h2), (size_t) len2);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if inputs are safe. */\n\n\t/* [ ... str1 str2 buf ] */\n\n\tduk_replace(thr, -3);\n\tduk_pop_unsafe(thr);\n\treturn;\n\n error_overflow:\n\tDUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\nDUK_EXTERNAL void duk_join(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__concat_and_join_helper(thr, count, 1 /*is_join*/);\n}\n\n/* XXX: could map/decode be unified with duk_unicode_support.c code?\n * Case conversion needs also the character surroundings though.\n */\n\nDUK_EXTERNAL void duk_decode_string(duk_hthread *thr, duk_idx_t idx, duk_decode_char_function callback, void *udata) {\n\tduk_hstring *h_input;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th_input = duk_require_hstring(thr, idx);  /* Accept symbols. */\n\tDUK_ASSERT(h_input != NULL);\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\n\tfor (;;) {\n\t\tif (p >= p_end) {\n\t\t\tbreak;\n\t\t}\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end);\n\t\tcallback(udata, cp);\n\t}\n}\n\nDUK_EXTERNAL void duk_map_string(duk_hthread *thr, duk_idx_t idx, duk_map_char_function callback, void *udata) {\n\tduk_hstring *h_input;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_normalize_index(thr, idx);\n\n\th_input = duk_require_hstring(thr, idx);  /* Accept symbols. */\n\tDUK_ASSERT(h_input != NULL);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input));  /* Reasonable output estimate. */\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\n\tfor (;;) {\n\t\t/* XXX: could write output in chunks with fewer ensure calls,\n\t\t * but relative benefit would be small here.\n\t\t */\n\n\t\tif (p >= p_end) {\n\t\t\tbreak;\n\t\t}\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end);\n\t\tcp = callback(udata, cp);\n\n\t\tDUK_BW_WRITE_ENSURE_XUTF8(thr, bw, cp);\n\t}\n\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe, extended UTF-8 encoded. */\n\tduk_replace(thr, idx);\n}\n\nDUK_EXTERNAL void duk_substring(duk_hthread *thr, duk_idx_t idx, duk_size_t start_offset, duk_size_t end_offset) {\n\tduk_hstring *h;\n\tduk_hstring *res;\n\tduk_size_t start_byte_offset;\n\tduk_size_t end_byte_offset;\n\tduk_size_t charlen;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);  /* Accept symbols. */\n\th = duk_require_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tcharlen = DUK_HSTRING_GET_CHARLEN(h);\n\tif (end_offset >= charlen) {\n\t\tend_offset = charlen;\n\t}\n\tif (start_offset > end_offset) {\n\t\tstart_offset = end_offset;\n\t}\n\n\tDUK_ASSERT_DISABLE(start_offset >= 0);\n\tDUK_ASSERT(start_offset <= end_offset && start_offset <= DUK_HSTRING_GET_CHARLEN(h));\n\tDUK_ASSERT_DISABLE(end_offset >= 0);\n\tDUK_ASSERT(end_offset >= start_offset && end_offset <= DUK_HSTRING_GET_CHARLEN(h));\n\n\t/* Guaranteed by string limits. */\n\tDUK_ASSERT(start_offset <= DUK_UINT32_MAX);\n\tDUK_ASSERT(end_offset <= DUK_UINT32_MAX);\n\n\tstart_byte_offset = (duk_size_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) start_offset);\n\tend_byte_offset = (duk_size_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) end_offset);\n\n\tDUK_ASSERT(end_byte_offset >= start_byte_offset);\n\tDUK_ASSERT(end_byte_offset - start_byte_offset <= DUK_UINT32_MAX);  /* Guaranteed by string limits. */\n\n\t/* No size check is necessary. */\n\tres = duk_heap_strtable_intern_checked(thr,\n\t                                       DUK_HSTRING_GET_DATA(h) + start_byte_offset,\n\t                                       (duk_uint32_t) (end_byte_offset - start_byte_offset));\n\n\tduk_push_hstring(thr, res);\n\tduk_replace(thr, idx);\n}\n\n/* XXX: this is quite clunky.  Add Unicode helpers to scan backwards and\n * forwards with a callback to process codepoints?\n */\nDUK_EXTERNAL void duk_trim(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p, *p_start, *p_end, *p_tmp1, *p_tmp2;  /* pointers for scanning */\n\tconst duk_uint8_t *q_start, *q_end;  /* start (incl) and end (excl) of trimmed part */\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);  /* Accept symbols. */\n\th = duk_require_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tp_start = DUK_HSTRING_GET_DATA(h);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h);\n\n\tp = p_start;\n\twhile (p < p_end) {\n\t\tp_tmp1 = p;\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p_tmp1, p_start, p_end);\n\t\tif (!(duk_unicode_is_whitespace(cp) || duk_unicode_is_line_terminator(cp))) {\n\t\t\tbreak;\n\t\t}\n\t\tp = p_tmp1;\n\t}\n\tq_start = p;\n\tif (p == p_end) {\n\t\t/* Entire string is whitespace. */\n\t\tq_end = p;\n\t\tgoto scan_done;\n\t}\n\n\tp = p_end;\n\twhile (p > p_start) {\n\t\tp_tmp1 = p;\n\t\twhile (p > p_start) {\n\t\t\tp--;\n\t\t\tif (((*p) & 0xc0) != 0x80) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tp_tmp2 = p;\n\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p_tmp2, p_start, p_end);\n\t\tif (!(duk_unicode_is_whitespace(cp) || duk_unicode_is_line_terminator(cp))) {\n\t\t\tp = p_tmp1;\n\t\t\tbreak;\n\t\t}\n\t}\n\tq_end = p;\n\n scan_done:\n\t/* This may happen when forward and backward scanning disagree\n\t * (possible for non-extended-UTF-8 strings).\n\t */\n\tif (q_end < q_start) {\n\t\tq_end = q_start;\n\t}\n\n\tDUK_ASSERT(q_start >= p_start && q_start <= p_end);\n\tDUK_ASSERT(q_end >= p_start && q_end <= p_end);\n\tDUK_ASSERT(q_end >= q_start);\n\n\tDUK_DDD(DUK_DDDPRINT(\"trim: p_start=%p, p_end=%p, q_start=%p, q_end=%p\",\n\t                     (const void *) p_start, (const void *) p_end,\n\t                     (const void *) q_start, (const void *) q_end));\n\n\tif (q_start == p_start && q_end == p_end) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"nothing was trimmed: avoid interning (hashing etc)\"));\n\t\treturn;\n\t}\n\n\tduk_push_lstring(thr, (const char *) q_start, (duk_size_t) (q_end - q_start));\n\tduk_replace(thr, idx);\n}\n\nDUK_EXTERNAL duk_codepoint_t duk_char_code_at(duk_hthread *thr, duk_idx_t idx, duk_size_t char_offset) {\n\tduk_hstring *h;\n\tduk_ucodepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: Share code with String.prototype.charCodeAt?  Main difference\n\t * is handling of clamped offsets.\n\t */\n\n\th = duk_require_hstring(thr, idx);  /* Accept symbols. */\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_ASSERT_DISABLE(char_offset >= 0);  /* Always true, arg is unsigned. */\n\tif (char_offset >= DUK_HSTRING_GET_CHARLEN(h)) {\n\t\treturn 0;\n\t}\n\n\tDUK_ASSERT(char_offset <= DUK_UINT_MAX);  /* Guaranteed by string limits. */\n\tcp = duk_hstring_char_code_at_raw(thr, h, (duk_uint_t) char_offset, 0 /*surrogate_aware*/);\n\treturn (duk_codepoint_t) cp;\n}\n#line 1 \"duk_api_time.c\"\n/*\n *  Date/time.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL duk_double_t duk_time_get_ecmascript_time(duk_hthread *thr) {\n\t/* ECMAScript time, with millisecond fractions.  Exposed via\n\t * duk_get_now() for example.\n\t */\n\tDUK_UNREF(thr);\n\treturn (duk_double_t) DUK_USE_DATE_GET_NOW(thr);\n}\n\nDUK_INTERNAL duk_double_t duk_time_get_ecmascript_time_nofrac(duk_hthread *thr) {\n\t/* ECMAScript time without millisecond fractions.  Exposed via\n\t * the Date built-in which doesn't allow fractions.\n\t */\n\tDUK_UNREF(thr);\n\treturn (duk_double_t) DUK_FLOOR(DUK_USE_DATE_GET_NOW(thr));\n}\n\nDUK_INTERNAL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr) {\n\tDUK_UNREF(thr);\n#if defined(DUK_USE_GET_MONOTONIC_TIME)\n\treturn (duk_double_t) DUK_USE_GET_MONOTONIC_TIME(thr);\n#else\n\treturn (duk_double_t) DUK_USE_DATE_GET_NOW(thr);\n#endif\n}\n\nDUK_EXTERNAL duk_double_t duk_get_now(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n\n\t/* This API intentionally allows millisecond fractions. */\n\treturn duk_time_get_ecmascript_time(thr);\n}\n\n#if 0  /* XXX: worth exposing? */\nDUK_EXTERNAL duk_double_t duk_get_monotonic_time(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n\n\treturn duk_time_get_monotonic_time(thr);\n}\n#endif\n\nDUK_EXTERNAL void duk_time_to_components(duk_hthread *thr, duk_double_t timeval, duk_time_components *comp) {\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(comp != NULL);  /* XXX: or check? */\n\tDUK_UNREF(thr);\n\n\t/* Convert as one-based, but change month to zero-based to match the\n\t * ECMAScript Date built-in behavior 1:1.\n\t */\n\tflags = DUK_DATE_FLAG_ONEBASED | DUK_DATE_FLAG_NAN_TO_ZERO;\n\n\tduk_bi_date_timeval_to_parts(timeval, parts, dparts, flags);\n\n\t/* XXX: sub-millisecond accuracy for the API */\n\n\tDUK_ASSERT(dparts[DUK_DATE_IDX_MONTH] >= 1.0 && dparts[DUK_DATE_IDX_MONTH] <= 12.0);\n\tcomp->year = dparts[DUK_DATE_IDX_YEAR];\n\tcomp->month = dparts[DUK_DATE_IDX_MONTH] - 1.0;\n\tcomp->day = dparts[DUK_DATE_IDX_DAY];\n\tcomp->hours = dparts[DUK_DATE_IDX_HOUR];\n\tcomp->minutes = dparts[DUK_DATE_IDX_MINUTE];\n\tcomp->seconds = dparts[DUK_DATE_IDX_SECOND];\n\tcomp->milliseconds = dparts[DUK_DATE_IDX_MILLISECOND];\n\tcomp->weekday = dparts[DUK_DATE_IDX_WEEKDAY];\n}\n\nDUK_EXTERNAL duk_double_t duk_components_to_time(duk_hthread *thr, duk_time_components *comp) {\n\tduk_double_t d;\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(comp != NULL);  /* XXX: or check? */\n\tDUK_UNREF(thr);\n\n\t/* Match Date constructor behavior (with UTC time).  Month is given\n\t * as zero-based.  Day-of-month is given as one-based so normalize\n\t * it to zero-based as the internal conversion helpers expects all\n\t * components to be zero-based.\n\t */\n\tflags = 0;\n\n\t/* XXX: expensive conversion; use array format in API instead, or unify\n\t * time provider and time API to use same struct?\n\t */\n\n\tdparts[DUK_DATE_IDX_YEAR] = comp->year;\n\tdparts[DUK_DATE_IDX_MONTH] = comp->month;\n\tdparts[DUK_DATE_IDX_DAY] = comp->day - 1.0;\n\tdparts[DUK_DATE_IDX_HOUR] = comp->hours;\n\tdparts[DUK_DATE_IDX_MINUTE] = comp->minutes;\n\tdparts[DUK_DATE_IDX_SECOND] = comp->seconds;\n\tdparts[DUK_DATE_IDX_MILLISECOND] = comp->milliseconds;\n\tdparts[DUK_DATE_IDX_WEEKDAY] = 0;  /* ignored */\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, flags);\n\n\treturn d;\n}\n#line 1 \"duk_bi_array.c\"\n/*\n *  Array built-ins\n *\n *  Most Array built-ins are intentionally generic in ECMAScript, and are\n *  intended to work even when the 'this' binding is not an Array instance.\n *  This ECMAScript feature is also used by much real world code.  For this\n *  reason the implementations here don't assume exotic Array behavior or\n *  e.g. presence of a .length property.  However, some algorithms have a\n *  fast path for duk_harray backed actual Array instances, enabled when\n *  footprint is not a concern.\n *\n *  XXX: the \"Throw\" flag should be set for (almost?) all [[Put]] and\n *  [[Delete]] operations, but it's currently false throughout.  Go through\n *  all put/delete cases and check throw flag use.  Need a new API primitive\n *  which allows throws flag to be specified.\n *\n *  XXX: array lengths above 2G won't work reliably.  There are many places\n *  where one needs a full signed 32-bit range ([-0xffffffff, 0xffffffff],\n *  i.e. -33- bits).  Although array 'length' cannot be written to be outside\n *  the unsigned 32-bit range (E5.1 Section 15.4.5.1 throws a RangeError if so)\n *  some intermediate values may be above 0xffffffff and this may not be always\n *  correctly handled now (duk_uint32_t is not enough for all algorithms).\n *  For instance, push() can legitimately write entries beyond length 0xffffffff\n *  and cause a RangeError only at the end.  To do this properly, the current\n *  push() implementation tracks the array index using a 'double' instead of a\n *  duk_uint32_t (which is somewhat awkward).  See test-bi-array-push-maxlen.js.\n *\n *  On using \"put\" vs. \"def\" prop\n *  =============================\n *\n *  Code below must be careful to use the appropriate primitive as it matters\n *  for compliance.  When using \"put\" there may be inherited properties in\n *  Array.prototype which cause side effects when values are written.  When\n *  using \"define\" there are no such side effects, and many test262 test cases\n *  check for this (for real world code, such side effects are very rare).\n *  Both \"put\" and \"define\" are used in the E5.1 specification; as a rule,\n *  \"put\" is used when modifying an existing array (or a non-array 'this'\n *  binding) and \"define\" for setting values into a fresh result array.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Perform an intermediate join when this many elements have been pushed\n * on the value stack.\n */\n#define  DUK__ARRAY_MID_JOIN_LIMIT  4096\n\n#if defined(DUK_USE_ARRAY_BUILTIN)\n\n/*\n *  Shared helpers.\n */\n\n/* Shared entry code for many Array built-ins: the 'this' binding is pushed\n * on the value stack and object coerced, and the current .length is returned.\n * Note that length is left on stack (it could be popped, but that's not\n * usually necessary because call handling will clean it up automatically).\n */\nDUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32(duk_hthread *thr) {\n\tduk_uint32_t len;\n\n\t/* XXX: push more directly? */\n\t(void) duk_push_this_coercible_to_object(thr);\n\tDUK_HOBJECT_ASSERT_VALID(duk_get_hobject(thr, -1));\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_LENGTH);\n\tlen = duk_to_uint32(thr, -1);\n\n\t/* -> [ ... ToObject(this) ToUint32(length) ] */\n\treturn len;\n}\n\nDUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32_limited(duk_hthread *thr) {\n\t/* Range limited to [0, 0x7fffffff] range, i.e. range that can be\n\t * represented with duk_int32_t.  Use this when the method doesn't\n\t * handle the full 32-bit unsigned range correctly.\n\t */\n\tduk_uint32_t ret = duk__push_this_obj_len_u32(thr);\n\tif (DUK_UNLIKELY(ret >= 0x80000000UL)) {\n\t\tDUK_ERROR_RANGE_INVALID_LENGTH(thr);\n\t\tDUK_WO_NORETURN(return 0U;);\n\t}\n\treturn ret;\n}\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\n/* Check if 'this' binding is an Array instance (duk_harray) which satisfies\n * a few other guarantees for fast path operation.  The fast path doesn't\n * need to handle all operations, even for duk_harrays, but must handle a\n * significant fraction to improve performance.  Return a non-NULL duk_harray\n * pointer when all fast path criteria are met, NULL otherwise.\n */\nDUK_LOCAL duk_harray *duk__arraypart_fastpath_this(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\tduk_uint_t flags_mask, flags_bits, flags_value;\n\n\tDUK_ASSERT(thr->valstack_bottom > thr->valstack);  /* because call in progress */\n\ttv = DUK_GET_THIS_TVAL_PTR(thr);\n\n\t/* Fast path requires that 'this' is a duk_harray.  Read only arrays\n\t * (ROM backed) are also rejected for simplicity.\n\t */\n\tif (!DUK_TVAL_IS_OBJECT(tv)) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject array fast path: not an object\"));\n\t\treturn NULL;\n\t}\n\th = DUK_TVAL_GET_OBJECT(tv);\n\tDUK_ASSERT(h != NULL);\n\tflags_mask = DUK_HOBJECT_FLAG_ARRAY_PART | \\\n\t             DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \\\n\t             DUK_HEAPHDR_FLAG_READONLY;\n\tflags_bits = DUK_HOBJECT_FLAG_ARRAY_PART | \\\n\t             DUK_HOBJECT_FLAG_EXOTIC_ARRAY;\n\tflags_value = DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) h);\n\tif ((flags_value & flags_mask) != flags_bits) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject array fast path: object flag check failed\"));\n\t\treturn NULL;\n\t}\n\n\t/* In some cases a duk_harray's 'length' may be larger than the\n\t * current array part allocation.  Avoid the fast path in these\n\t * cases, so that all fast path code can safely assume that all\n\t * items in the range [0,length[ are backed by the current array\n\t * part allocation.\n\t */\n\tif (((duk_harray *) h)->length > DUK_HOBJECT_GET_ASIZE(h)) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject array fast path: length > array part size\"));\n\t\treturn NULL;\n\t}\n\n\t/* Guarantees for fast path. */\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0 || DUK_HOBJECT_A_GET_BASE(thr->heap, h) != NULL);\n\tDUK_ASSERT(((duk_harray *) h)->length <= DUK_HOBJECT_GET_ASIZE(h));\n\n\tDUK_DD(DUK_DDPRINT(\"array fast path allowed for: %!O\", (duk_heaphdr *) h));\n\treturn (duk_harray *) h;\n}\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_constructor(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_harray *a;\n\tduk_double_t d;\n\tduk_uint32_t len;\n\tduk_uint32_t len_prealloc;\n\n\tnargs = duk_get_top(thr);\n\n\tif (nargs == 1 && duk_is_number(thr, 0)) {\n\t\t/* XXX: expensive check (also shared elsewhere - so add a shared internal API call?) */\n\t\td = duk_get_number(thr, 0);\n\t\tlen = duk_to_uint32(thr, 0);\n\t\tif (((duk_double_t) len) != d) {\n\t\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t\t}\n\n\t\t/* For small lengths create a dense preallocated array.\n\t\t * For large arrays preallocate an initial part.\n\t\t */\n\t\tlen_prealloc = len < 64 ? len : 64;\n\t\ta = duk_push_harray_with_size(thr, len_prealloc);\n\t\tDUK_ASSERT(a != NULL);\n\t\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\t\ta->length = len;\n\t\treturn 1;\n\t}\n\n\tduk_pack(thr, nargs);\n\treturn 1;\n}\n\n/*\n *  isArray()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_constructor_is_array(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\th = duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_ARRAY);\n\tduk_push_boolean(thr, (h != NULL));\n\treturn 1;\n}\n\n/*\n *  toString()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_to_string(duk_hthread *thr) {\n\t(void) duk_push_this_coercible_to_object(thr);\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_JOIN);\n\n\t/* [ ... this func ] */\n\tif (!duk_is_callable(thr, -1)) {\n\t\t/* Fall back to the initial (original) Object.toString().  We don't\n\t\t * currently have pointers to the built-in functions, only the top\n\t\t * level global objects (like \"Array\") so this is now done in a bit\n\t\t * of a hacky manner.  It would be cleaner to push the (original)\n\t\t * function and use duk_call_method().\n\t\t */\n\n\t\t/* XXX: 'this' will be ToObject() coerced twice, which is incorrect\n\t\t * but should have no visible side effects.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"this.join is not callable, fall back to (original) Object.toString\"));\n\t\tduk_set_top(thr, 0);\n\t\treturn duk_bi_object_prototype_to_string(thr);  /* has access to 'this' binding */\n\t}\n\n\t/* [ ... this func ] */\n\n\tduk_insert(thr, -2);\n\n\t/* [ ... func this ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"calling: func=%!iT, this=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_call_method(thr, 0);\n\n\treturn 1;\n}\n\n/*\n *  concat()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_concat(duk_hthread *thr) {\n\tduk_idx_t i, n;\n\tduk_uint32_t j, idx, len;\n\tduk_hobject *h;\n\tduk_size_t tmp_len;\n\n\t/* XXX: In ES2015 Array .length can be up to 2^53-1.  The current\n\t * implementation is limited to 2^32-1.\n\t */\n\n\t/* XXX: Fast path for array 'this' and array element. */\n\n\t/* XXX: The insert here is a bit expensive if there are a lot of items.\n\t * It could also be special cased in the outermost for loop quite easily\n\t * (as the element is dup()'d anyway).\n\t */\n\n\t(void) duk_push_this_coercible_to_object(thr);\n\tduk_insert(thr, 0);\n\tn = duk_get_top(thr);\n\tduk_push_array(thr);  /* -> [ ToObject(this) item1 ... itemN arr ] */\n\n\t/* NOTE: The Array special behaviors are NOT invoked by duk_xdef_prop_index()\n\t * (which differs from the official algorithm).  If no error is thrown, this\n\t * doesn't matter as the length is updated at the end.  However, if an error\n\t * is thrown, the length will be unset.  That shouldn't matter because the\n\t * caller won't get a reference to the intermediate value.\n\t */\n\n\tidx = 0;\n\tfor (i = 0; i < n; i++) {\n\t\tduk_bool_t spreadable;\n\t\tduk_bool_t need_has_check;\n\n\t\tDUK_ASSERT_TOP(thr, n + 1);\n\n\t\t/* [ ToObject(this) item1 ... itemN arr ] */\n\n\t\th = duk_get_hobject(thr, i);\n\n\t\tif (h == NULL) {\n\t\t\tspreadable = 0;\n\t\t} else {\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t\t\tduk_get_prop_stridx(thr, i, DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE);\n\t\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\t\tspreadable = (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY);\n\t\t\t} else {\n\t\t\t\tspreadable = duk_to_boolean(thr, -1);\n\t\t\t}\n\t\t\tduk_pop_nodecref_unsafe(thr);\n#else\n\t\t\tspreadable = (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY);\n#endif\n\t\t}\n\n\t\tif (!spreadable) {\n\t\t\tduk_dup(thr, i);\n\t\t\tduk_xdef_prop_index_wec(thr, -2, idx);\n\t\t\tidx++;\n\t\t\tif (DUK_UNLIKELY(idx == 0U)) {\n\t\t\t\t/* Index after update is 0, and index written\n\t\t\t\t * was 0xffffffffUL which is no longer a valid\n\t\t\t\t * array index.\n\t\t\t\t */\n\t\t\t\tgoto fail_wrap;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_ASSERT(duk_is_object(thr, i));\n\t\tneed_has_check = (DUK_HOBJECT_IS_PROXY(h) != 0);  /* Always 0 w/o Proxy support. */\n\n\t\t/* [ ToObject(this) item1 ... itemN arr ] */\n\n\t\ttmp_len = duk_get_length(thr, i);\n\t\tlen = (duk_uint32_t) tmp_len;\n\t\tif (DUK_UNLIKELY(tmp_len != (duk_size_t) len)) {\n\t\t\tgoto fail_wrap;\n\t\t}\n\t\tif (DUK_UNLIKELY(idx + len < idx)) {\n\t\t\t/* Result length must be at most 0xffffffffUL to be\n\t\t\t * a valid 32-bit array index.\n\t\t\t */\n\t\t\tgoto fail_wrap;\n\t\t}\n\t\tfor (j = 0; j < len; j++) {\n\t\t\t/* For a Proxy element, an explicit 'has' check is\n\t\t\t * needed to allow the Proxy to present gaps.\n\t\t\t */\n\t\t\tif (need_has_check) {\n\t\t\t\tif (duk_has_prop_index(thr, i, j)) {\n\t\t\t\t\tduk_get_prop_index(thr, i, j);\n\t\t\t\t\tduk_xdef_prop_index_wec(thr, -2, idx);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (duk_get_prop_index(thr, i, j)) {\n\t\t\t\t\tduk_xdef_prop_index_wec(thr, -2, idx);\n\t\t\t\t} else {\n\t\t\t\t\tduk_pop_undefined(thr);\n\t\t\t\t}\n\t\t\t}\n\t\t\tidx++;\n\t\t\tDUK_ASSERT(idx != 0U);  /* Wrap check above. */\n\t\t}\n\t}\n\n\t/* ES5.1 has a specification \"bug\" in that nonexistent trailing\n\t * elements don't affect the result .length.  Test262 and other\n\t * engines disagree, and the specification bug was fixed in ES2015\n\t * (see NOTE 1 in https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.concat).\n\t */\n\tduk_push_uarridx(thr, idx);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\n\tDUK_ASSERT_TOP(thr, n + 1);\n\treturn 1;\n\n fail_wrap:\n\tDUK_ERROR_RANGE_INVALID_LENGTH(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/*\n *  join(), toLocaleString()\n *\n *  Note: checking valstack is necessary, but only in the per-element loop.\n *\n *  Note: the trivial approach of pushing all the elements on the value stack\n *  and then calling duk_join() fails when the array contains a large number\n *  of elements.  This problem can't be offloaded to duk_join() because the\n *  elements to join must be handled here and have special handling.  Current\n *  approach is to do intermediate joins with very large number of elements.\n *  There is no fancy handling; the prefix gets re-joined multiple times.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_join_shared(duk_hthread *thr) {\n\tduk_uint32_t len, count;\n\tduk_uint32_t idx;\n\tduk_small_int_t to_locale_string = duk_get_current_magic(thr);\n\tduk_idx_t valstack_required;\n\n\t/* For join(), nargs is 1.  For toLocaleString(), nargs is 0 and\n\t * setting the top essentially pushes an undefined to the stack,\n\t * thus defaulting to a comma separator.\n\t */\n\tduk_set_top(thr, 1);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tduk_pop_undefined(thr);\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_COMMA);\n\t} else {\n\t\tduk_to_string(thr, 0);\n\t}\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\n\t/* [ sep ToObject(this) len ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"sep=%!T, this=%!T, len=%lu\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1),\n\t                     (unsigned long) len));\n\n\t/* The extra (+4) is tight. */\n\tvalstack_required = (duk_idx_t) ((len >= DUK__ARRAY_MID_JOIN_LIMIT ?\n\t                                  DUK__ARRAY_MID_JOIN_LIMIT : len) + 4);\n\tduk_require_stack(thr, valstack_required);\n\n\tduk_dup_0(thr);\n\n\t/* [ sep ToObject(this) len sep ] */\n\n\tcount = 0;\n\tidx = 0;\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"join idx=%ld\", (long) idx));\n\t\tif (count >= DUK__ARRAY_MID_JOIN_LIMIT ||   /* intermediate join to avoid valstack overflow */\n\t\t    idx >= len) { /* end of loop (careful with len==0) */\n\t\t\t/* [ sep ToObject(this) len sep str0 ... str(count-1) ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"mid/final join, count=%ld, idx=%ld, len=%ld\",\n\t\t\t                     (long) count, (long) idx, (long) len));\n\t\t\tduk_join(thr, (duk_idx_t) count);  /* -> [ sep ToObject(this) len str ] */\n\t\t\tduk_dup_0(thr);                    /* -> [ sep ToObject(this) len str sep ] */\n\t\t\tduk_insert(thr, -2);               /* -> [ sep ToObject(this) len sep str ] */\n\t\t\tcount = 1;\n\t\t}\n\t\tif (idx >= len) {\n\t\t\t/* if true, the stack already contains the final result */\n\t\t\tbreak;\n\t\t}\n\n\t\tduk_get_prop_index(thr, 1, (duk_uarridx_t) idx);\n\t\tif (duk_is_null_or_undefined(thr, -1)) {\n\t\t\tduk_pop_nodecref_unsafe(thr);\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tif (to_locale_string) {\n\t\t\t\tduk_to_object(thr, -1);\n\t\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_LOCALE_STRING);\n\t\t\t\tduk_insert(thr, -2);  /* -> [ ... toLocaleString ToObject(val) ] */\n\t\t\t\tduk_call_method(thr, 0);\n\t\t\t}\n\t\t\tduk_to_string(thr, -1);\n\t\t}\n\n\t\tcount++;\n\t\tidx++;\n\t}\n\n\t/* [ sep ToObject(this) len sep result ] */\n\n\treturn 1;\n}\n\n/*\n *  pop(), push()\n */\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\nDUK_LOCAL duk_ret_t duk__array_pop_fastpath(duk_hthread *thr, duk_harray *h_arr) {\n\tduk_tval *tv_arraypart;\n\tduk_tval *tv_val;\n\tduk_uint32_t len;\n\n\ttv_arraypart = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) h_arr);\n\tlen = h_arr->length;\n\tif (len <= 0) {\n\t\t/* nop, return undefined */\n\t\treturn 0;\n\t}\n\n\tlen--;\n\th_arr->length = len;\n\n\t/* Fast path doesn't check for an index property inherited from\n\t * Array.prototype.  This is quite often acceptable; if not,\n\t * disable fast path.\n\t */\n\tDUK_ASSERT_VS_SPACE(thr);\n\ttv_val = tv_arraypart + len;\n\tif (DUK_TVAL_IS_UNUSED(tv_val)) {\n\t\t/* No net refcount change.  Value stack already has\n\t\t * 'undefined' based on value stack init policy.\n\t\t */\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv_val));\n\t} else {\n\t\t/* No net refcount change. */\n\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv_val);\n\t\tDUK_TVAL_SET_UNUSED(tv_val);\n\t}\n\tthr->valstack_top++;\n\n\t/* XXX: there's no shrink check in the fast path now */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_pop(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t idx;\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\tduk_harray *h_arr;\n#endif\n\n\tDUK_ASSERT_TOP(thr, 0);\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\th_arr = duk__arraypart_fastpath_this(thr);\n\tif (h_arr) {\n\t\treturn duk__array_pop_fastpath(thr, h_arr);\n\t}\n#endif\n\n\t/* XXX: Merge fastpath check into a related call (push this, coerce length, etc)? */\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tif (len == 0) {\n\t\tduk_push_int(thr, 0);\n\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\t\treturn 0;\n\t}\n\tidx = len - 1;\n\n\tduk_get_prop_index(thr, 0, (duk_uarridx_t) idx);\n\tduk_del_prop_index(thr, 0, (duk_uarridx_t) idx);\n\tduk_push_u32(thr, idx);\n\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\treturn 1;\n}\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\nDUK_LOCAL duk_ret_t duk__array_push_fastpath(duk_hthread *thr, duk_harray *h_arr) {\n\tduk_tval *tv_arraypart;\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_uint32_t len;\n\tduk_idx_t i, n;\n\n\tlen = h_arr->length;\n\ttv_arraypart = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) h_arr);\n\n\tn = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT(n >= 0);\n\tDUK_ASSERT((duk_uint32_t) n <= DUK_UINT32_MAX);\n\tif (DUK_UNLIKELY(len + (duk_uint32_t) n < len)) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.push() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);  /* != 0 return value returned as is by caller */\n\t}\n\tif (len + (duk_uint32_t) n > DUK_HOBJECT_GET_ASIZE((duk_hobject *) h_arr)) {\n\t\t/* Array part would need to be extended.  Rely on slow path\n\t\t * for now.\n\t\t *\n\t\t * XXX: Rework hobject code a bit and add extend support.\n\t\t */\n\t\treturn 0;\n\t}\n\n\ttv_src = thr->valstack_bottom;\n\ttv_dst = tv_arraypart + len;\n\tfor (i = 0; i < n; i++) {\n\t\t/* No net refcount change; reset value stack values to\n\t\t * undefined to satisfy value stack init policy.\n\t\t */\n\t\tDUK_TVAL_SET_TVAL(tv_dst, tv_src);\n\t\tDUK_TVAL_SET_UNDEFINED(tv_src);\n\t\ttv_src++;\n\t\ttv_dst++;\n\t}\n\tthr->valstack_top = thr->valstack_bottom;\n\tlen += (duk_uint32_t) n;\n\th_arr->length = len;\n\n\tDUK_ASSERT((duk_uint_t) len == len);\n\tduk_push_uint(thr, (duk_uint_t) len);\n\treturn 1;\n}\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_push(duk_hthread *thr) {\n\t/* Note: 'this' is not necessarily an Array object.  The push()\n\t * algorithm is supposed to work for other kinds of objects too,\n\t * so the algorithm has e.g. an explicit update for the 'length'\n\t * property which is normally \"magical\" in arrays.\n\t */\n\n\tduk_uint32_t len;\n\tduk_idx_t i, n;\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\tduk_harray *h_arr;\n#endif\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\th_arr = duk__arraypart_fastpath_this(thr);\n\tif (h_arr) {\n\t\tduk_ret_t rc;\n\t\trc = duk__array_push_fastpath(thr, h_arr);\n\t\tif (rc != 0) {\n\t\t\treturn rc;\n\t\t}\n\t\tDUK_DD(DUK_DDPRINT(\"array push() fast path exited, resize case\"));\n\t}\n#endif\n\n\tn = duk_get_top(thr);\n\tlen = duk__push_this_obj_len_u32(thr);\n\n\t/* [ arg1 ... argN obj length ] */\n\n\t/* Technically Array.prototype.push() can create an Array with length\n\t * longer than 2^32-1, i.e. outside the 32-bit range.  The final length\n\t * is *not* wrapped to 32 bits in the specification.\n\t *\n\t * This implementation tracks length with a uint32 because it's much\n\t * more practical.\n\t *\n\t * See: test-bi-array-push-maxlen.js.\n\t */\n\n\tif (len + (duk_uint32_t) n < len) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.push() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t}\n\n\tfor (i = 0; i < n; i++) {\n\t\tduk_dup(thr, i);\n\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) (len + (duk_uint32_t) i));\n\t}\n\tlen += (duk_uint32_t) n;\n\n\tduk_push_u32(thr, len);\n\tduk_dup_top(thr);\n\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH);\n\n\t/* [ arg1 ... argN obj length new_length ] */\n\treturn 1;\n}\n\n/*\n *  sort()\n *\n *  Currently qsort with random pivot.  This is now really, really slow,\n *  because there is no fast path for array parts.\n *\n *  Signed indices are used because qsort() leaves and degenerate cases\n *  may use a negative offset.\n */\n\nDUK_LOCAL duk_small_int_t duk__array_sort_compare(duk_hthread *thr, duk_int_t idx1, duk_int_t idx2) {\n\tduk_bool_t have1, have2;\n\tduk_bool_t undef1, undef2;\n\tduk_small_int_t ret;\n\tduk_idx_t idx_obj = 1;  /* fixed offsets in valstack */\n\tduk_idx_t idx_fn = 0;\n\tduk_hstring *h1, *h2;\n\n\t/* Fast exit if indices are identical.  This is valid for a non-existent property,\n\t * for an undefined value, and almost always for ToString() coerced comparison of\n\t * arbitrary values (corner cases where this is not the case include e.g. a an\n\t * object with varying ToString() coercion).\n\t *\n\t * The specification does not prohibit \"caching\" of values read from the array, so\n\t * assuming equality for comparing an index with itself falls into the category of\n\t * \"caching\".\n\t *\n\t * Also, compareFn may be inconsistent, so skipping a call to compareFn here may\n\t * have an effect on the final result.  The specification does not require any\n\t * specific behavior for inconsistent compare functions, so again, this fast path\n\t * is OK.\n\t */\n\n\tif (idx1 == idx2) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__array_sort_compare: idx1=%ld, idx2=%ld -> indices identical, quick exit\",\n\t\t                     (long) idx1, (long) idx2));\n\t\treturn 0;\n\t}\n\n\thave1 = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) idx1);\n\thave2 = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) idx2);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__array_sort_compare: idx1=%ld, idx2=%ld, have1=%ld, have2=%ld, val1=%!T, val2=%!T\",\n\t                     (long) idx1, (long) idx2, (long) have1, (long) have2,\n\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (have1) {\n\t\tif (have2) {\n\t\t\t;\n\t\t} else {\n\t\t\tret = -1;\n\t\t\tgoto pop_ret;\n\t\t}\n\t} else {\n\t\tif (have2) {\n\t\t\tret = 1;\n\t\t\tgoto pop_ret;\n\t\t} else {\n\t\t\tret = 0;\n\t\t\tgoto pop_ret;\n\t\t}\n\t}\n\n\tundef1 = duk_is_undefined(thr, -2);\n\tundef2 = duk_is_undefined(thr, -1);\n\tif (undef1) {\n\t\tif (undef2) {\n\t\t\tret = 0;\n\t\t\tgoto pop_ret;\n\t\t} else {\n\t\t\tret = 1;\n\t\t\tgoto pop_ret;\n\t\t}\n\t} else {\n\t\tif (undef2) {\n\t\t\tret = -1;\n\t\t\tgoto pop_ret;\n\t\t} else {\n\t\t\t;\n\t\t}\n\t}\n\n\tif (!duk_is_undefined(thr, idx_fn)) {\n\t\tduk_double_t d;\n\n\t\t/* No need to check callable; duk_call() will do that. */\n\t\tduk_dup(thr, idx_fn);    /* -> [ ... x y fn ] */\n\t\tduk_insert(thr, -3);     /* -> [ ... fn x y ] */\n\t\tduk_call(thr, 2);        /* -> [ ... res ] */\n\n\t\t/* ES5 is a bit vague about what to do if the return value is\n\t\t * not a number.  ES2015 provides a concrete description:\n\t\t * http://www.ecma-international.org/ecma-262/6.0/#sec-sortcompare.\n\t\t */\n\n\t\td = duk_to_number_m1(thr);\n\t\tif (d < 0.0) {\n\t\t\tret = -1;\n\t\t} else if (d > 0.0) {\n\t\t\tret = 1;\n\t\t} else {\n\t\t\t/* Because NaN compares to false, NaN is handled here\n\t\t\t * without an explicit check above.\n\t\t\t */\n\t\t\tret = 0;\n\t\t}\n\n\t\tduk_pop_nodecref_unsafe(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> result %ld (from comparefn, after coercion)\", (long) ret));\n\t\treturn ret;\n\t}\n\n\t/* string compare is the default (a bit oddly) */\n\n\t/* XXX: any special handling for plain array; causes repeated coercion now? */\n\th1 = duk_to_hstring(thr, -2);\n\th2 = duk_to_hstring_m1(thr);\n\tDUK_ASSERT(h1 != NULL);\n\tDUK_ASSERT(h2 != NULL);\n\n\tret = duk_js_string_compare(h1, h2);  /* retval is directly usable */\n\tgoto pop_ret;\n\n pop_ret:\n\tduk_pop_2_unsafe(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"-> result %ld\", (long) ret));\n\treturn ret;\n}\n\nDUK_LOCAL void duk__array_sort_swap(duk_hthread *thr, duk_int_t l, duk_int_t r) {\n\tduk_bool_t have_l, have_r;\n\tduk_idx_t idx_obj = 1;  /* fixed offset in valstack */\n\n\tif (l == r) {\n\t\treturn;\n\t}\n\n\t/* swap elements; deal with non-existent elements correctly */\n\thave_l = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) l);\n\thave_r = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) r);\n\n\tif (have_r) {\n\t\t/* right exists, [[Put]] regardless whether or not left exists */\n\t\tduk_put_prop_index(thr, idx_obj, (duk_uarridx_t) l);\n\t} else {\n\t\tduk_del_prop_index(thr, idx_obj, (duk_uarridx_t) l);\n\t\tduk_pop_undefined(thr);\n\t}\n\n\tif (have_l) {\n\t\tduk_put_prop_index(thr, idx_obj, (duk_uarridx_t) r);\n\t} else {\n\t\tduk_del_prop_index(thr, idx_obj, (duk_uarridx_t) r);\n\t\tduk_pop_undefined(thr);\n\t}\n}\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n/* Debug print which visualizes the qsort partitioning process. */\nDUK_LOCAL void duk__debuglog_qsort_state(duk_hthread *thr, duk_int_t lo, duk_int_t hi, duk_int_t pivot) {\n\tchar buf[4096];\n\tchar *ptr = buf;\n\tduk_int_t i, n;\n\tn = (duk_int_t) duk_get_length(thr, 1);\n\tif (n > 4000) {\n\t\tn = 4000;\n\t}\n\t*ptr++ = '[';\n\tfor (i = 0; i < n; i++) {\n\t\tif (i == pivot) {\n\t\t\t*ptr++ = '|';\n\t\t} else if (i == lo) {\n\t\t\t*ptr++ = '<';\n\t\t} else if (i == hi) {\n\t\t\t*ptr++ = '>';\n\t\t} else if (i >= lo && i <= hi) {\n\t\t\t*ptr++ = '-';\n\t\t} else {\n\t\t\t*ptr++ = ' ';\n\t\t}\n\t}\n\t*ptr++ = ']';\n\t*ptr++ = '\\0';\n\n\tDUK_DDD(DUK_DDDPRINT(\"%s   (lo=%ld, hi=%ld, pivot=%ld)\",\n\t                     (const char *) buf, (long) lo, (long) hi, (long) pivot));\n}\n#endif\n\nDUK_LOCAL void duk__array_qsort(duk_hthread *thr, duk_int_t lo, duk_int_t hi) {\n\tduk_int_t p, l, r;\n\n\t/* The lo/hi indices may be crossed and hi < 0 is possible at entry. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__array_qsort: lo=%ld, hi=%ld, obj=%!T\",\n\t                     (long) lo, (long) hi, (duk_tval *) duk_get_tval(thr, 1)));\n\n\tDUK_ASSERT_TOP(thr, 3);\n\n\t/* In some cases it may be that lo > hi, or hi < 0; these\n\t * degenerate cases happen e.g. for empty arrays, and in\n\t * recursion leaves.\n\t */\n\n\t/* trivial cases */\n\tif (hi - lo < 1) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"degenerate case, return immediately\"));\n\t\treturn;\n\t}\n\tDUK_ASSERT(hi > lo);\n\tDUK_ASSERT(hi - lo + 1 >= 2);\n\n\t/* randomized pivot selection */\n\tp = lo + (duk_int_t) (DUK_UTIL_GET_RANDOM_DOUBLE(thr) * (duk_double_t) (hi - lo + 1));\n\tDUK_ASSERT(p >= lo && p <= hi);\n\tDUK_DDD(DUK_DDDPRINT(\"lo=%ld, hi=%ld, chose pivot p=%ld\", (long) lo, (long) hi, (long) p));\n\n\t/* move pivot out of the way */\n\tduk__array_sort_swap(thr, p, lo);\n\tp = lo;\n\tDUK_DDD(DUK_DDDPRINT(\"pivot moved out of the way: %!T\", (duk_tval *) duk_get_tval(thr, 1)));\n\n\tl = lo + 1;\n\tr = hi;\n\tfor (;;) {\n\t\t/* find elements to swap */\n\t\tfor (;;) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"left scan: l=%ld, r=%ld, p=%ld\",\n\t\t\t                     (long) l, (long) r, (long) p));\n\t\t\tif (l >= hi) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (duk__array_sort_compare(thr, l, p) >= 0) {  /* !(l < p) */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tl++;\n\t\t}\n\t\tfor (;;) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"right scan: l=%ld, r=%ld, p=%ld\",\n\t\t\t                     (long) l, (long) r, (long) p));\n\t\t\tif (r <= lo) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (duk__array_sort_compare(thr, p, r) >= 0) {  /* !(p < r) */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tr--;\n\t\t}\n\t\tif (l >= r) {\n\t\t\tgoto done;\n\t\t}\n\t\tDUK_ASSERT(l < r);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"swap %ld and %ld\", (long) l, (long) r));\n\n\t\tduk__array_sort_swap(thr, l, r);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"after swap: %!T\", (duk_tval *) duk_get_tval(thr, 1)));\n\t\tl++;\n\t\tr--;\n\t}\n done:\n\t/* Note that 'l' and 'r' may cross, i.e. r < l */\n\tDUK_ASSERT(l >= lo && l <= hi);\n\tDUK_ASSERT(r >= lo && r <= hi);\n\n\t/* XXX: there's no explicit recursion bound here now.  For the average\n\t * qsort recursion depth O(log n) that's not really necessary: e.g. for\n\t * 2**32 recursion depth would be about 32 which is OK.  However, qsort\n\t * worst case recursion depth is O(n) which may be a problem.\n\t */\n\n\t/* move pivot to its final place */\n\tDUK_DDD(DUK_DDDPRINT(\"before final pivot swap: %!T\", (duk_tval *) duk_get_tval(thr, 1)));\n\tduk__array_sort_swap(thr, lo, r);\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\tduk__debuglog_qsort_state(thr, lo, hi, r);\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"recurse: pivot=%ld, obj=%!T\", (long) r, (duk_tval *) duk_get_tval(thr, 1)));\n\tduk__array_qsort(thr, lo, r - 1);\n\tduk__array_qsort(thr, r + 1, hi);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_sort(duk_hthread *thr) {\n\tduk_uint32_t len;\n\n\t/* XXX: len >= 0x80000000 won't work below because a signed type\n\t * is needed by qsort.\n\t */\n\tlen = duk__push_this_obj_len_u32_limited(thr);\n\n\t/* stack[0] = compareFn\n\t * stack[1] = ToObject(this)\n\t * stack[2] = ToUint32(length)\n\t */\n\n\tif (len > 0) {\n\t\t/* avoid degenerate cases, so that (len - 1) won't underflow */\n\t\tduk__array_qsort(thr, (duk_int_t) 0, (duk_int_t) (len - 1));\n\t}\n\n\tDUK_ASSERT_TOP(thr, 3);\n\tduk_pop_nodecref_unsafe(thr);\n\treturn 1;  /* return ToObject(this) */\n}\n\n/*\n *  splice()\n */\n\n/* XXX: this compiles to over 500 bytes now, even without special handling\n * for an array part.  Uses signed ints so does not handle full array range correctly.\n */\n\n/* XXX: can shift() / unshift() use the same helper?\n *   shift() is (close to?) <--> splice(0, 1)\n *   unshift is (close to?) <--> splice(0, 0, [items])?\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_uint32_t len_u32;\n\tduk_int_t len;\n\tduk_bool_t have_delcount;\n\tduk_int_t item_count;\n\tduk_int_t act_start;\n\tduk_int_t del_count;\n\tduk_int_t i, n;\n\n\tDUK_UNREF(have_delcount);\n\n\tnargs = duk_get_top(thr);\n\tif (nargs < 2) {\n\t\tduk_set_top(thr, 2);\n\t\tnargs = 2;\n\t\thave_delcount = 0;\n\t} else {\n\t\thave_delcount = 1;\n\t}\n\n\t/* XXX: len >= 0x80000000 won't work below because we need to be\n\t * able to represent -len.\n\t */\n\tlen_u32 = duk__push_this_obj_len_u32_limited(thr);\n\tlen = (duk_int_t) len_u32;\n\tDUK_ASSERT(len >= 0);\n\n\tact_start = duk_to_int_clamped(thr, 0, -len, len);\n\tif (act_start < 0) {\n\t\tact_start = len + act_start;\n\t}\n\tDUK_ASSERT(act_start >= 0 && act_start <= len);\n\n#if defined(DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT)\n\tif (have_delcount) {\n#endif\n\t\tdel_count = duk_to_int_clamped(thr, 1, 0, len - act_start);\n#if defined(DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT)\n\t} else {\n\t\t/* E5.1 standard behavior when deleteCount is not given would be\n\t\t * to treat it just like if 'undefined' was given, which coerces\n\t\t * ultimately to 0.  Real world behavior is to splice to the end\n\t\t * of array, see test-bi-array-proto-splice-no-delcount.js.\n\t\t */\n\t\tdel_count = len - act_start;\n\t}\n#endif\n\n\tDUK_ASSERT(nargs >= 2);\n\titem_count = (duk_int_t) (nargs - 2);\n\n\tDUK_ASSERT(del_count >= 0 && del_count <= len - act_start);\n\tDUK_ASSERT(del_count + act_start <= len);\n\n\t/* For now, restrict result array into 32-bit length range. */\n\tif (((duk_double_t) len) - ((duk_double_t) del_count) + ((duk_double_t) item_count) > (duk_double_t) DUK_UINT32_MAX) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.splice() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t}\n\n\tduk_push_array(thr);\n\n\t/* stack[0] = start\n\t * stack[1] = deleteCount\n\t * stack[2...nargs-1] = items\n\t * stack[nargs] = ToObject(this)               -3\n\t * stack[nargs+1] = ToUint32(length)           -2\n\t * stack[nargs+2] = result array               -1\n\t */\n\n\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t/* Step 9: copy elements-to-be-deleted into the result array */\n\n\tfor (i = 0; i < del_count; i++) {\n\t\tif (duk_get_prop_index(thr, -3, (duk_uarridx_t) (act_start + i))) {\n\t\t\tduk_xdef_prop_index_wec(thr, -2, (duk_uarridx_t) i);  /* throw flag irrelevant (false in std alg) */\n\t\t} else {\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\t}\n\tduk_push_u32(thr, (duk_uint32_t) del_count);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\n\t/* Steps 12 and 13: reorganize elements to make room for itemCount elements */\n\n\tif (item_count < del_count) {\n\t\t/*    [ A B C D E F G H ]    rel_index = 2, del_count 3, item count 1\n\t\t * -> [ A B F G H ]          (conceptual intermediate step)\n\t\t * -> [ A B . F G H ]        (placeholder marked)\n\t\t *    [ A B C F G H ]        (actual result at this point, C will be replaced)\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t\tn = len - del_count;\n\t\tfor (i = act_start; i < n; i++) {\n\t\t\tif (duk_get_prop_index(thr, -3, (duk_uarridx_t) (i + del_count))) {\n\t\t\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) (i + item_count));\n\t\t\t} else {\n\t\t\t\tduk_pop_undefined(thr);\n\t\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) (i + item_count));\n\t\t\t}\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t\t/* loop iterator init and limit changed from standard algorithm */\n\t\tn = len - del_count + item_count;\n\t\tfor (i = len - 1; i >= n; i--) {\n\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) i);\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\t} else if (item_count > del_count) {\n\t\t/*    [ A B C D E F G H ]    rel_index = 2, del_count 3, item count 4\n\t\t * -> [ A B F G H ]          (conceptual intermediate step)\n\t\t * -> [ A B . . . . F G H ]  (placeholder marked)\n\t\t *    [ A B C D E F F G H ]  (actual result at this point)\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t\t/* loop iterator init and limit changed from standard algorithm */\n\t\tfor (i = len - del_count - 1; i >= act_start; i--) {\n\t\t\tif (duk_get_prop_index(thr, -3, (duk_uarridx_t) (i + del_count))) {\n\t\t\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) (i + item_count));\n\t\t\t} else {\n\t\t\t\tduk_pop_undefined(thr);\n\t\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) (i + item_count));\n\t\t\t}\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\t} else {\n\t\t/*    [ A B C D E F G H ]    rel_index = 2, del_count 3, item count 3\n\t\t * -> [ A B F G H ]          (conceptual intermediate step)\n\t\t * -> [ A B . . . F G H ]    (placeholder marked)\n\t\t *    [ A B C D E F G H ]    (actual result at this point)\n\t\t */\n\t}\n\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t/* Step 15: insert itemCount elements into the hole made above */\n\n\tfor (i = 0; i < item_count; i++) {\n\t\tduk_dup(thr, i + 2);  /* args start at index 2 */\n\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) (act_start + i));\n\t}\n\n\t/* Step 16: update length; note that the final length may be above 32 bit range\n\t * (but we checked above that this isn't the case here)\n\t */\n\n\tduk_push_u32(thr, (duk_uint32_t) (len - del_count + item_count));\n\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH);\n\n\t/* result array is already at the top of stack */\n\tDUK_ASSERT_TOP(thr, nargs + 3);\n\treturn 1;\n}\n\n/*\n *  reverse()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_reverse(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t middle;\n\tduk_uint32_t lower, upper;\n\tduk_bool_t have_lower, have_upper;\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tmiddle = len / 2;\n\n\t/* If len <= 1, middle will be 0 and for-loop bails out\n\t * immediately (0 < 0 -> false).\n\t */\n\n\tfor (lower = 0; lower < middle; lower++) {\n\t\tDUK_ASSERT(len >= 2);\n\t\tDUK_ASSERT_TOP(thr, 2);\n\n\t\tDUK_ASSERT(len >= lower + 1);\n\t\tupper = len - lower - 1;\n\n\t\thave_lower = duk_get_prop_index(thr, -2, (duk_uarridx_t) lower);\n\t\thave_upper = duk_get_prop_index(thr, -3, (duk_uarridx_t) upper);\n\n\t\t/* [ ToObject(this) ToUint32(length) lowerValue upperValue ] */\n\n\t\tif (have_upper) {\n\t\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) lower);\n\t\t} else {\n\t\t\tduk_del_prop_index(thr, -4, (duk_uarridx_t) lower);\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\n\t\tif (have_lower) {\n\t\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) upper);\n\t\t} else {\n\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) upper);\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t}\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_pop_unsafe(thr);  /* -> [ ToObject(this) ] */\n\treturn 1;\n}\n\n/*\n *  slice()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_slice(duk_hthread *thr) {\n\tduk_uint32_t len_u32;\n\tduk_int_t len;\n\tduk_int_t start, end;\n\tduk_int_t i;\n\tduk_uarridx_t idx;\n\tduk_uint32_t res_length = 0;\n\n\t/* XXX: len >= 0x80000000 won't work below because we need to be\n\t * able to represent -len.\n\t */\n\tlen_u32 = duk__push_this_obj_len_u32_limited(thr);\n\tlen = (duk_int_t) len_u32;\n\tDUK_ASSERT(len >= 0);\n\n\tduk_push_array(thr);\n\n\t/* stack[0] = start\n\t * stack[1] = end\n\t * stack[2] = ToObject(this)\n\t * stack[3] = ToUint32(length)\n\t * stack[4] = result array\n\t */\n\n\tstart = duk_to_int_clamped(thr, 0, -len, len);\n\tif (start < 0) {\n\t\tstart = len + start;\n\t}\n\t/* XXX: could duk_is_undefined() provide defaulting undefined to 'len'\n\t * (the upper limit)?\n\t */\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend = len;\n\t} else {\n\t\tend = duk_to_int_clamped(thr, 1, -len, len);\n\t\tif (end < 0) {\n\t\t\tend = len + end;\n\t\t}\n\t}\n\tDUK_ASSERT(start >= 0 && start <= len);\n\tDUK_ASSERT(end >= 0 && end <= len);\n\n\tidx = 0;\n\tfor (i = start; i < end; i++) {\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t\tif (duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\tduk_xdef_prop_index_wec(thr, 4, idx);\n\t\t\tres_length = idx + 1;\n\t\t} else {\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\t\tidx++;\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t}\n\n\tduk_push_u32(thr, res_length);\n\tduk_xdef_prop_stridx_short(thr, 4, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\n\tDUK_ASSERT_TOP(thr, 5);\n\treturn 1;\n}\n\n/*\n *  shift()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_shift(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t i;\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tif (len == 0) {\n\t\tduk_push_int(thr, 0);\n\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\t\treturn 0;\n\t}\n\n\tduk_get_prop_index(thr, 0, 0);\n\n\t/* stack[0] = object (this)\n\t * stack[1] = ToUint32(length)\n\t * stack[2] = elem at index 0 (retval)\n\t */\n\n\tfor (i = 1; i < len; i++) {\n\t\tDUK_ASSERT_TOP(thr, 3);\n\t\tif (duk_get_prop_index(thr, 0, (duk_uarridx_t) i)) {\n\t\t\t/* fromPresent = true */\n\t\t\tduk_put_prop_index(thr, 0, (duk_uarridx_t) (i - 1));\n\t\t} else {\n\t\t\t/* fromPresent = false */\n\t\t\tduk_del_prop_index(thr, 0, (duk_uarridx_t) (i - 1));\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\t}\n\tduk_del_prop_index(thr, 0, (duk_uarridx_t) (len - 1));\n\n\tduk_push_u32(thr, (duk_uint32_t) (len - 1));\n\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\n\tDUK_ASSERT_TOP(thr, 3);\n\treturn 1;\n}\n\n/*\n *  unshift()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_unshift(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_uint32_t len;\n\tduk_uint32_t i;\n\n\tnargs = duk_get_top(thr);\n\tlen = duk__push_this_obj_len_u32(thr);\n\n\t/* stack[0...nargs-1] = unshift args (vararg)\n\t * stack[nargs] = ToObject(this)\n\t * stack[nargs+1] = ToUint32(length)\n\t */\n\n\tDUK_ASSERT_TOP(thr, nargs + 2);\n\n\t/* Note: unshift() may operate on indices above unsigned 32-bit range\n\t * and the final length may be >= 2**32.  However, we restrict the\n\t * final result to 32-bit range for practicality.\n\t */\n\n\tif (len + (duk_uint32_t) nargs < len) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.unshift() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t}\n\n\ti = len;\n\twhile (i > 0) {\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t\ti--;\n\t\t/* k+argCount-1; note that may be above 32-bit range */\n\n\t\tif (duk_get_prop_index(thr, -2, (duk_uarridx_t) i)) {\n\t\t\t/* fromPresent = true */\n\t\t\t/* [ ... ToObject(this) ToUint32(length) val ] */\n\t\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) (i + (duk_uint32_t) nargs));  /* -> [ ... ToObject(this) ToUint32(length) ] */\n\t\t} else {\n\t\t\t/* fromPresent = false */\n\t\t\t/* [ ... ToObject(this) ToUint32(length) val ] */\n\t\t\tduk_pop_undefined(thr);\n\t\t\tduk_del_prop_index(thr, -2, (duk_uarridx_t) (i + (duk_uint32_t) nargs));  /* -> [ ... ToObject(this) ToUint32(length) ] */\n\t\t}\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t}\n\n\tfor (i = 0; i < (duk_uint32_t) nargs; i++) {\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t\tduk_dup(thr, (duk_idx_t) i);  /* -> [ ... ToObject(this) ToUint32(length) arg[i] ] */\n\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) i);\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t}\n\n\tDUK_ASSERT_TOP(thr, nargs + 2);\n\tduk_push_u32(thr, len + (duk_uint32_t) nargs);\n\tduk_dup_top(thr);  /* -> [ ... ToObject(this) ToUint32(length) final_len final_len ] */\n\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH);\n\treturn 1;\n}\n\n/*\n *  indexOf(), lastIndexOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_indexof_shared(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_int_t i, len;\n\tduk_int_t from_idx;\n\tduk_small_int_t idx_step = duk_get_current_magic(thr);  /* idx_step is +1 for indexOf, -1 for lastIndexOf */\n\n\t/* lastIndexOf() needs to be a vararg function because we must distinguish\n\t * between an undefined fromIndex and a \"not given\" fromIndex; indexOf() is\n\t * made vararg for symmetry although it doesn't strictly need to be.\n\t */\n\n\tnargs = duk_get_top(thr);\n\tduk_set_top(thr, 2);\n\n\t/* XXX: must be able to represent -len */\n\tlen = (duk_int_t) duk__push_this_obj_len_u32_limited(thr);\n\tif (len == 0) {\n\t\tgoto not_found;\n\t}\n\n\t/* Index clamping is a bit tricky, we must ensure that we'll only iterate\n\t * through elements that exist and that the specific requirements from E5.1\n\t * Sections 15.4.4.14 and 15.4.4.15 are fulfilled; especially:\n\t *\n\t *   - indexOf: clamp to [-len,len], negative handling -> [0,len],\n\t *     if clamped result is len, for-loop bails out immediately\n\t *\n\t *   - lastIndexOf: clamp to [-len-1, len-1], negative handling -> [-1, len-1],\n\t *     if clamped result is -1, for-loop bails out immediately\n\t *\n\t * If fromIndex is not given, ToInteger(undefined) = 0, which is correct\n\t * for indexOf() but incorrect for lastIndexOf().  Hence special handling,\n\t * and why lastIndexOf() needs to be a vararg function.\n\t */\n\n\tif (nargs >= 2) {\n\t\t/* indexOf: clamp fromIndex to [-len, len]\n\t\t * (if fromIndex == len, for-loop terminates directly)\n\t\t *\n\t\t * lastIndexOf: clamp fromIndex to [-len - 1, len - 1]\n\t\t * (if clamped to -len-1 -> fromIndex becomes -1, terminates for-loop directly)\n\t\t */\n\t\tfrom_idx = duk_to_int_clamped(thr,\n\t\t                              1,\n\t\t                              (idx_step > 0 ? -len : -len - 1),\n\t\t                              (idx_step > 0 ? len : len - 1));\n\t\tif (from_idx < 0) {\n\t\t\t/* for lastIndexOf, result may be -1 (mark immediate termination) */\n\t\t\tfrom_idx = len + from_idx;\n\t\t}\n\t} else {\n\t\t/* for indexOf, ToInteger(undefined) would be 0, i.e. correct, but\n\t\t * handle both indexOf and lastIndexOf specially here.\n\t\t */\n\t\tif (idx_step > 0) {\n\t\t\tfrom_idx = 0;\n\t\t} else {\n\t\t\tfrom_idx = len - 1;\n\t\t}\n\t}\n\n\t/* stack[0] = searchElement\n\t * stack[1] = fromIndex\n\t * stack[2] = object\n\t * stack[3] = length (not needed, but not popped above)\n\t */\n\n\tfor (i = from_idx; i >= 0 && i < len; i += idx_step) {\n\t\tDUK_ASSERT_TOP(thr, 4);\n\n\t\tif (duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t\tif (duk_strict_equals(thr, 0, 4)) {\n\t\t\t\tduk_push_int(thr, i);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\tduk_pop_unsafe(thr);\n\t}\n\n not_found:\n\tduk_push_int(thr, -1);\n\treturn 1;\n}\n\n/*\n *  every(), some(), forEach(), map(), filter()\n */\n\n#define DUK__ITER_EVERY    0\n#define DUK__ITER_SOME     1\n#define DUK__ITER_FOREACH  2\n#define DUK__ITER_MAP      3\n#define DUK__ITER_FILTER   4\n\n/* XXX: This helper is a bit awkward because the handling for the different iteration\n * callers is quite different.  This now compiles to a bit less than 500 bytes, so with\n * 5 callers the net result is about 100 bytes / caller.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_iter_shared(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t i;\n\tduk_uarridx_t k;\n\tduk_bool_t bval;\n\tduk_small_int_t iter_type = duk_get_current_magic(thr);\n\tduk_uint32_t res_length = 0;\n\n\t/* each call this helper serves has nargs==2 */\n\tDUK_ASSERT_TOP(thr, 2);\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tduk_require_callable(thr, 0);\n\t/* if thisArg not supplied, behave as if undefined was supplied */\n\n\tif (iter_type == DUK__ITER_MAP || iter_type == DUK__ITER_FILTER) {\n\t\tduk_push_array(thr);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n\n\t/* stack[0] = callback\n\t * stack[1] = thisArg\n\t * stack[2] = object\n\t * stack[3] = ToUint32(length)  (unused, but avoid unnecessary pop)\n\t * stack[4] = result array (or undefined)\n\t */\n\n\tk = 0;  /* result index for filter() */\n\tfor (i = 0; i < len; i++) {\n\t\tDUK_ASSERT_TOP(thr, 5);\n\n\t\tif (!duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\t/* For 'map' trailing missing elements don't invoke the\n\t\t\t * callback but count towards the result length.\n\t\t\t */\n\t\t\tif (iter_type == DUK__ITER_MAP) {\n\t\t\t\tres_length = i + 1;\n\t\t\t}\n\t\t\tduk_pop_undefined(thr);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* The original value needs to be preserved for filter(), hence\n\t\t * this funny order.  We can't re-get the value because of side\n\t\t * effects.\n\t\t */\n\n\t\tduk_dup_0(thr);\n\t\tduk_dup_1(thr);\n\t\tduk_dup_m3(thr);\n\t\tduk_push_u32(thr, i);\n\t\tduk_dup_2(thr);  /* [ ... val callback thisArg val i obj ] */\n\t\tduk_call_method(thr, 3); /* -> [ ... val retval ] */\n\n\t\tswitch (iter_type) {\n\t\tcase DUK__ITER_EVERY:\n\t\t\tbval = duk_to_boolean(thr, -1);\n\t\t\tif (!bval) {\n\t\t\t\t/* stack top contains 'false' */\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase DUK__ITER_SOME:\n\t\t\tbval = duk_to_boolean(thr, -1);\n\t\t\tif (bval) {\n\t\t\t\t/* stack top contains 'true' */\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase DUK__ITER_FOREACH:\n\t\t\t/* nop */\n\t\t\tbreak;\n\t\tcase DUK__ITER_MAP:\n\t\t\tduk_dup_top(thr);\n\t\t\tduk_xdef_prop_index_wec(thr, 4, (duk_uarridx_t) i);  /* retval to result[i] */\n\t\t\tres_length = i + 1;\n\t\t\tbreak;\n\t\tcase DUK__ITER_FILTER:\n\t\t\tbval = duk_to_boolean(thr, -1);\n\t\t\tif (bval) {\n\t\t\t\tduk_dup_m2(thr);  /* orig value */\n\t\t\t\tduk_xdef_prop_index_wec(thr, 4, (duk_uarridx_t) k);\n\t\t\t\tk++;\n\t\t\t\tres_length = k;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tduk_pop_2_unsafe(thr);\n\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t}\n\n\tswitch (iter_type) {\n\tcase DUK__ITER_EVERY:\n\t\tduk_push_true(thr);\n\t\tbreak;\n\tcase DUK__ITER_SOME:\n\t\tduk_push_false(thr);\n\t\tbreak;\n\tcase DUK__ITER_FOREACH:\n\t\tduk_push_undefined(thr);\n\t\tbreak;\n\tcase DUK__ITER_MAP:\n\tcase DUK__ITER_FILTER:\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t\tDUK_ASSERT(duk_is_array(thr, -1));  /* topmost element is the result array already */\n\t\tduk_push_u32(thr, res_length);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\t\tbreak;\n\tdefault:\n\t\tDUK_UNREACHABLE();\n\t\tbreak;\n\t}\n\n\treturn 1;\n}\n\n/*\n *  reduce(), reduceRight()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_reduce_shared(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_bool_t have_acc;\n\tduk_uint32_t i, len;\n\tduk_small_int_t idx_step = duk_get_current_magic(thr);  /* idx_step is +1 for reduce, -1 for reduceRight */\n\n\t/* We're a varargs function because we need to detect whether\n\t * initialValue was given or not.\n\t */\n\tnargs = duk_get_top(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"nargs=%ld\", (long) nargs));\n\n\tduk_set_top(thr, 2);\n\tlen = duk__push_this_obj_len_u32(thr);\n\tduk_require_callable(thr, 0);\n\n\t/* stack[0] = callback fn\n\t * stack[1] = initialValue\n\t * stack[2] = object (coerced this)\n\t * stack[3] = length (not needed, but not popped above)\n\t * stack[4] = accumulator\n\t */\n\n\thave_acc = 0;\n\tif (nargs >= 2) {\n\t\tduk_dup_1(thr);\n\t\thave_acc = 1;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"have_acc=%ld, acc=%!T\",\n\t                     (long) have_acc, (duk_tval *) duk_get_tval(thr, 3)));\n\n\t/* For len == 0, i is initialized to len - 1 which underflows.\n\t * The condition (i < len) will then exit the for-loop on the\n\t * first round which is correct.  Similarly, loop termination\n\t * happens by i underflowing.\n\t */\n\n\tfor (i = (idx_step >= 0 ? 0 : len - 1);\n\t     i < len;  /* i >= 0 would always be true */\n\t     i += (duk_uint32_t) idx_step) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"i=%ld, len=%ld, have_acc=%ld, top=%ld, acc=%!T\",\n\t\t                     (long) i, (long) len, (long) have_acc,\n\t\t                     (long) duk_get_top(thr),\n\t\t                     (duk_tval *) duk_get_tval(thr, 4)));\n\n\t\tDUK_ASSERT((have_acc && duk_get_top(thr) == 5) ||\n\t\t           (!have_acc && duk_get_top(thr) == 4));\n\n\t\tif (!duk_has_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!have_acc) {\n\t\t\tDUK_ASSERT_TOP(thr, 4);\n\t\t\tduk_get_prop_index(thr, 2, (duk_uarridx_t) i);\n\t\t\thave_acc = 1;\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t} else {\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_dup(thr, 4);\n\t\t\tduk_get_prop_index(thr, 2, (duk_uarridx_t) i);\n\t\t\tduk_push_u32(thr, i);\n\t\t\tduk_dup_2(thr);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"calling reduce function: func=%!T, prev=%!T, curr=%!T, idx=%!T, obj=%!T\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -5), (duk_tval *) duk_get_tval(thr, -4),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -3), (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tduk_call(thr, 4);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> result: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tduk_replace(thr, 4);\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t}\n\t}\n\n\tif (!have_acc) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tDUK_ASSERT_TOP(thr, 5);\n\treturn 1;\n}\n\n#endif  /* DUK_USE_ARRAY_BUILTIN */\n\n/* automatic undefs */\n#undef DUK__ARRAY_MID_JOIN_LIMIT\n#undef DUK__ITER_EVERY\n#undef DUK__ITER_FILTER\n#undef DUK__ITER_FOREACH\n#undef DUK__ITER_MAP\n#undef DUK__ITER_SOME\n#line 1 \"duk_bi_boolean.c\"\n/*\n *  Boolean built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_BOOLEAN_BUILTIN)\n\n/* Shared helper to provide toString() and valueOf().  Checks 'this', gets\n * the primitive value to stack top, and optionally coerces with ToString().\n */\nDUK_INTERNAL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\tduk_small_int_t coerce_tostring = duk_get_current_magic(thr);\n\n\t/* XXX: there is room to use a shared helper here, many built-ins\n\t * check the 'this' type, and if it's an object, check its class,\n\t * then get its internal value, etc.\n\t */\n\n\tduk_push_this(thr);\n\ttv = duk_get_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_BOOLEAN(tv)) {\n\t\tgoto type_ok;\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_BOOLEAN) {\n\t\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t\t\tDUK_ASSERT(duk_is_boolean(thr, -1));\n\t\t\tgoto type_ok;\n\t\t}\n\t}\n\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t/* never here */\n\n type_ok:\n\tif (coerce_tostring) {\n\t\tduk_to_string(thr, -1);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_boolean_constructor(duk_hthread *thr) {\n\tduk_hobject *h_this;\n\n\tduk_to_boolean(thr, 0);\n\n\tif (duk_is_constructor_call(thr)) {\n\t\t/* XXX: helper; rely on Boolean.prototype as being non-writable, non-configurable */\n\t\tduk_push_this(thr);\n\t\th_this = duk_known_hobject(thr, -1);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE]);\n\n\t\tDUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_BOOLEAN);\n\n\t\tduk_dup_0(thr);  /* -> [ val obj val ] */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);  /* XXX: proper flags? */\n\t}  /* unbalanced stack */\n\n\treturn 1;\n}\n\n#endif  /* DUK_USE_BOOLEAN_BUILTIN */\n#line 1 \"duk_bi_buffer.c\"\n/*\n *  ES2015 TypedArray and Node.js Buffer built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Helpers for buffer handling, enabled with DUK_USE_BUFFEROBJECT_SUPPORT.\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Map class number (minus DUK_HOBJECT_CLASS_BUFOBJ_MIN) to a bidx for the\n * default internal prototype.\n */\nstatic const duk_uint8_t duk__buffer_proto_from_classnum[] = {\n\tDUK_BIDX_ARRAYBUFFER_PROTOTYPE,\n\tDUK_BIDX_DATAVIEW_PROTOTYPE,\n\tDUK_BIDX_INT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE,\n\tDUK_BIDX_INT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_INT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT64ARRAY_PROTOTYPE\n};\n\n/* Map DUK_HBUFOBJ_ELEM_xxx to duk_hobject class number.\n * Sync with duk_hbufobj.h and duk_hobject.h.\n */\nstatic const duk_uint8_t duk__buffer_class_from_elemtype[9] = {\n\tDUK_HOBJECT_CLASS_UINT8ARRAY,\n\tDUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY,\n\tDUK_HOBJECT_CLASS_INT8ARRAY,\n\tDUK_HOBJECT_CLASS_UINT16ARRAY,\n\tDUK_HOBJECT_CLASS_INT16ARRAY,\n\tDUK_HOBJECT_CLASS_UINT32ARRAY,\n\tDUK_HOBJECT_CLASS_INT32ARRAY,\n\tDUK_HOBJECT_CLASS_FLOAT32ARRAY,\n\tDUK_HOBJECT_CLASS_FLOAT64ARRAY\n};\n\n/* Map DUK_HBUFOBJ_ELEM_xxx to prototype object built-in index.\n * Sync with duk_hbufobj.h.\n */\nstatic const duk_uint8_t duk__buffer_proto_from_elemtype[9] = {\n\tDUK_BIDX_UINT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE,\n\tDUK_BIDX_INT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_INT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_INT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT64ARRAY_PROTOTYPE\n};\n\n/* Map DUK__FLD_xxx to byte size. */\nstatic const duk_uint8_t duk__buffer_nbytes_from_fldtype[6] = {\n\t1,  /* DUK__FLD_8BIT */\n\t2,  /* DUK__FLD_16BIT */\n\t4,  /* DUK__FLD_32BIT */\n\t4,  /* DUK__FLD_FLOAT */\n\t8,  /* DUK__FLD_DOUBLE */\n\t0   /* DUK__FLD_VARINT; not relevant here */\n};\n\n/* Bitfield for each DUK_HBUFOBJ_ELEM_xxx indicating which element types\n * are compatible with a blind byte copy for the TypedArray set() method (also\n * used for TypedArray constructor).  Array index is target buffer elem type,\n * bitfield indicates compatible source types.  The types must have same byte\n * size and they must be coercion compatible.\n */\n#if !defined(DUK_USE_PREFER_SIZE)\nstatic duk_uint16_t duk__buffer_elemtype_copy_compatible[9] = {\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT8 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT8) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_UINT8CLAMPED) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT8),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT8CLAMPED\n\t * Note: INT8 is -not- copy compatible, e.g. -1 would coerce to 0x00.\n\t */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT8) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_UINT8CLAMPED),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_INT8 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT8) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_UINT8CLAMPED) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT8),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT16 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT16) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT16),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_INT16 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT16) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT16),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT32 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT32) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT32),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_INT32 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT32) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT32),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_FLOAT32 */\n\t(1U << DUK_HBUFOBJ_ELEM_FLOAT32),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_FLOAT64 */\n\t(1U << DUK_HBUFOBJ_ELEM_FLOAT64)\n};\n#endif  /* !DUK_USE_PREFER_SIZE */\n\nDUK_LOCAL duk_hbufobj *duk__hbufobj_promote_this(duk_hthread *thr) {\n\tduk_tval *tv_dst;\n\tduk_hbufobj *res;\n\n\tduk_push_this(thr);\n\tDUK_ASSERT(duk_is_buffer(thr, -1));\n\tres = (duk_hbufobj *) duk_to_hobject(thr, -1);\n\tDUK_HBUFOBJ_ASSERT_VALID(res);\n\tDUK_DD(DUK_DDPRINT(\"promoted 'this' automatically to an ArrayBuffer: %!iT\", duk_get_tval(thr, -1)));\n\n\ttv_dst = duk_get_borrowed_this_tval(thr);\n\tDUK_TVAL_SET_OBJECT_UPDREF(thr, tv_dst, (duk_hobject *) res);\n\tduk_pop(thr);\n\n\treturn res;\n}\n\n#define DUK__BUFOBJ_FLAG_THROW    (1 << 0)\n#define DUK__BUFOBJ_FLAG_PROMOTE  (1 << 1)\n\n/* Shared helper.  When DUK__BUFOBJ_FLAG_PROMOTE is given, the return value is\n * always a duk_hbufobj *.  Without the flag the return value can also be a\n * plain buffer, and the caller must check for it using DUK_HEAPHDR_IS_BUFFER().\n */\nDUK_LOCAL duk_heaphdr *duk__getrequire_bufobj_this(duk_hthread *thr, duk_small_uint_t flags) {\n\tduk_tval *tv;\n\tduk_hbufobj *h_this;\n\n\tDUK_ASSERT(thr != NULL);\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_this = (duk_hbufobj *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_this != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h_this)) {\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\t\t\treturn (duk_heaphdr *) h_this;\n\t\t}\n\t} else if (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tif (flags & DUK__BUFOBJ_FLAG_PROMOTE) {\n\t\t\t/* Promote a plain buffer to a Uint8Array.  This is very\n\t\t\t * inefficient but allows plain buffer to be used wherever an\n\t\t\t * Uint8Array is used with very small cost; hot path functions\n\t\t\t * like index read/write calls should provide direct buffer\n\t\t\t * support to avoid promotion.\n\t\t\t */\n\t\t\t/* XXX: make this conditional to a flag if call sites need it? */\n\t\t\th_this = duk__hbufobj_promote_this(thr);\n\t\t\tDUK_ASSERT(h_this != NULL);\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\t\t\treturn (duk_heaphdr *) h_this;\n\t\t} else {\n\t\t\t/* XXX: ugly, share return pointer for duk_hbuffer. */\n\t\t\treturn (duk_heaphdr *) DUK_TVAL_GET_BUFFER(tv);\n\t\t}\n\t}\n\n\tif (flags & DUK__BUFOBJ_FLAG_THROW) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_BUFFER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn NULL;\n}\n\n/* Check that 'this' is a duk_hbufobj and return a pointer to it. */\nDUK_LOCAL duk_hbufobj *duk__get_bufobj_this(duk_hthread *thr) {\n\treturn (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_PROMOTE);\n}\n\n/* Check that 'this' is a duk_hbufobj and return a pointer to it\n * (NULL if not).\n */\nDUK_LOCAL duk_hbufobj *duk__require_bufobj_this(duk_hthread *thr) {\n\treturn (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW | DUK__BUFOBJ_FLAG_PROMOTE);\n}\n\n/* Check that value is a duk_hbufobj and return a pointer to it. */\nDUK_LOCAL duk_hbufobj *duk__require_bufobj_value(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hbufobj *h_obj;\n\n\t/* Don't accept relative indices now. */\n\tDUK_ASSERT(idx >= 0);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_obj = (duk_hbufobj *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h_obj)) {\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_obj);\n\t\t\treturn h_obj;\n\t\t}\n\t} else if (DUK_TVAL_IS_BUFFER(tv)) {\n\t\th_obj = (duk_hbufobj *) duk_to_hobject(thr, idx);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tDUK_HBUFOBJ_ASSERT_VALID(h_obj);\n\t\treturn h_obj;\n\t}\n\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_BUFFER);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_LOCAL void duk__set_bufobj_buffer(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_hbuffer *h_val) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tDUK_ASSERT(h_bufobj->buf == NULL);  /* no need to decref */\n\tDUK_ASSERT(h_val != NULL);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\tDUK_UNREF(thr);\n\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\th_bufobj->length = (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_val);\n\tDUK_ASSERT(h_bufobj->shift == 0);\n\tDUK_ASSERT(h_bufobj->elem_type == DUK_HBUFOBJ_ELEM_UINT8);\n\tDUK_ASSERT(h_bufobj->is_typedarray == 0);\n\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n}\n\n/* Shared offset/length coercion helper. */\nDUK_LOCAL void duk__resolve_offset_opt_length(duk_hthread *thr,\n                                              duk_hbufobj *h_bufarg,\n                                              duk_idx_t idx_offset,\n                                              duk_idx_t idx_length,\n                                              duk_uint_t *out_offset,\n                                              duk_uint_t *out_length,\n                                              duk_bool_t throw_flag) {\n\tduk_int_t offset_signed;\n\tduk_int_t length_signed;\n\tduk_uint_t offset;\n\tduk_uint_t length;\n\n\toffset_signed = duk_to_int(thr, idx_offset);\n\tif (offset_signed < 0) {\n\t\tgoto fail_range;\n\t}\n\toffset = (duk_uint_t) offset_signed;\n\tif (offset > h_bufarg->length) {\n\t\tgoto fail_range;\n\t}\n\tDUK_ASSERT_DISABLE(offset >= 0);  /* unsigned */\n\tDUK_ASSERT(offset <= h_bufarg->length);\n\n\tif (duk_is_undefined(thr, idx_length)) {\n\t\tDUK_ASSERT(h_bufarg->length >= offset);\n\t\tlength = h_bufarg->length - offset;  /* >= 0 */\n\t} else {\n\t\tlength_signed = duk_to_int(thr, idx_length);\n\t\tif (length_signed < 0) {\n\t\t\tgoto fail_range;\n\t\t}\n\t\tlength = (duk_uint_t) length_signed;\n\t\tDUK_ASSERT(h_bufarg->length >= offset);\n\t\tif (length > h_bufarg->length - offset) {\n\t\t\t/* Unlike for negative arguments, some call sites\n\t\t\t * want length to be clamped if it's positive.\n\t\t\t */\n\t\t\tif (throw_flag) {\n\t\t\t\tgoto fail_range;\n\t\t\t} else {\n\t\t\t\tlength = h_bufarg->length - offset;\n\t\t\t}\n\t\t}\n\t}\n\tDUK_ASSERT_DISABLE(length >= 0);  /* unsigned */\n\tDUK_ASSERT(offset + length <= h_bufarg->length);\n\n\t*out_offset = offset;\n\t*out_length = length;\n\treturn;\n\n fail_range:\n\tDUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARGS);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Shared lenient buffer length clamping helper.  No negative indices, no\n * element/byte shifting.\n */\nDUK_LOCAL void duk__clamp_startend_nonegidx_noshift(duk_hthread *thr,\n                                                    duk_int_t buffer_length,\n                                                    duk_idx_t idx_start,\n                                                    duk_idx_t idx_end,\n                                                    duk_int_t *out_start_offset,\n                                                    duk_int_t *out_end_offset) {\n\tduk_int_t start_offset;\n\tduk_int_t end_offset;\n\n\tDUK_ASSERT(out_start_offset != NULL);\n\tDUK_ASSERT(out_end_offset != NULL);\n\n\t/* undefined coerces to zero which is correct */\n\tstart_offset = duk_to_int_clamped(thr, idx_start, 0, buffer_length);\n\tif (duk_is_undefined(thr, idx_end)) {\n\t\tend_offset = buffer_length;\n\t} else {\n\t\tend_offset = duk_to_int_clamped(thr, idx_end, start_offset, buffer_length);\n\t}\n\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(start_offset <= buffer_length);\n\tDUK_ASSERT(end_offset >= 0);\n\tDUK_ASSERT(end_offset <= buffer_length);\n\tDUK_ASSERT(start_offset <= end_offset);\n\n\t*out_start_offset = start_offset;\n\t*out_end_offset = end_offset;\n}\n\n/* Shared lenient buffer length clamping helper.  Indices are treated as\n * element indices (though output values are byte offsets) which only\n * really matters for TypedArray views as other buffer object have a zero\n * shift.  Negative indices are counted from end of input slice; crossed\n * indices are clamped to zero length; and final indices are clamped\n * against input slice.  Used for e.g. ArrayBuffer slice().\n */\nDUK_LOCAL void duk__clamp_startend_negidx_shifted(duk_hthread *thr,\n                                                  duk_int_t buffer_length,\n                                                  duk_uint8_t buffer_shift,\n                                                  duk_idx_t idx_start,\n                                                  duk_idx_t idx_end,\n                                                  duk_int_t *out_start_offset,\n                                                  duk_int_t *out_end_offset) {\n\tduk_int_t start_offset;\n\tduk_int_t end_offset;\n\n\tDUK_ASSERT(out_start_offset != NULL);\n\tDUK_ASSERT(out_end_offset != NULL);\n\n\tbuffer_length >>= buffer_shift;  /* as (full) elements */\n\n\t/* Resolve start/end offset as element indices first; arguments\n\t * at idx_start/idx_end are element offsets.  Working with element\n\t * indices first also avoids potential for wrapping.\n\t */\n\n\tstart_offset = duk_to_int(thr, idx_start);\n\tif (start_offset < 0) {\n\t\tstart_offset = buffer_length + start_offset;\n\t}\n\tif (duk_is_undefined(thr, idx_end)) {\n\t\tend_offset = buffer_length;\n\t} else {\n\t\tend_offset = duk_to_int(thr, idx_end);\n\t\tif (end_offset < 0) {\n\t\t\tend_offset = buffer_length + end_offset;\n\t\t}\n\t}\n\t/* Note: start_offset/end_offset can still be < 0 here. */\n\n\tif (start_offset < 0) {\n\t\tstart_offset = 0;\n\t} else if (start_offset > buffer_length) {\n\t\tstart_offset = buffer_length;\n\t}\n\tif (end_offset < start_offset) {\n\t\tend_offset = start_offset;\n\t} else if (end_offset > buffer_length) {\n\t\tend_offset = buffer_length;\n\t}\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(start_offset <= buffer_length);\n\tDUK_ASSERT(end_offset >= 0);\n\tDUK_ASSERT(end_offset <= buffer_length);\n\tDUK_ASSERT(start_offset <= end_offset);\n\n\t/* Convert indices to byte offsets. */\n\tstart_offset <<= buffer_shift;\n\tend_offset <<= buffer_shift;\n\n\t*out_start_offset = start_offset;\n\t*out_end_offset = end_offset;\n}\n\nDUK_INTERNAL void duk_hbufobj_promote_plain(duk_hthread *thr, duk_idx_t idx) {\n\tif (duk_is_buffer(thr, idx)) {\n\t\tduk_to_object(thr, idx);\n\t}\n}\n\nDUK_INTERNAL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_hbuffer *h_buf) {\n\t/* Push Uint8Array which will share the same underlying buffer as\n\t * the plain buffer argument.  Also create an ArrayBuffer with the\n\t * same backing for the result .buffer property.\n\t */\n\n\tduk_push_hbuffer(thr, h_buf);\n\tduk_push_buffer_object(thr, -1, 0, (duk_size_t) DUK_HBUFFER_GET_SIZE(h_buf), DUK_BUFOBJ_UINT8ARRAY);\n\tduk_remove_m2(thr);\n\n#if 0\n\t/* More verbose equivalent; maybe useful if e.g. .buffer is omitted. */\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_UINT8ARRAY),\n\t                               DUK_BIDX_UINT8ARRAY_PROTOTYPE);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tduk__set_bufobj_buffer(thr, h_bufobj, h_buf);\n\th_bufobj->is_typedarray = 1;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\th_arrbuf = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),\n\t                               DUK_BIDX_ARRAYBUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_arrbuf != NULL);\n\tduk__set_bufobj_buffer(thr, h_arrbuf, h_buf);\n\tDUK_ASSERT(h_arrbuf->is_typedarray == 0);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_arrbuf);\n\n\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\th_bufobj->buf_prop = (duk_hobject *) h_arrbuf;\n\tDUK_ASSERT(h_arrbuf != NULL);\n\tDUK_HBUFOBJ_INCREF(thr, h_arrbuf);\n\tduk_pop(thr);\n#endif\n}\n\n/* Indexed read helper for buffer objects, also called from outside this file. */\nDUK_INTERNAL void duk_hbufobj_push_validated_read(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size) {\n\tduk_double_union du;\n\n\tDUK_ASSERT(elem_size > 0);\n\tduk_memcpy((void *) du.uc, (const void *) p, (size_t) elem_size);\n\n\tswitch (h_bufobj->elem_type) {\n\tcase DUK_HBUFOBJ_ELEM_UINT8:\n\tcase DUK_HBUFOBJ_ELEM_UINT8CLAMPED:\n\t\tduk_push_uint(thr, (duk_uint_t) du.uc[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT8:\n\t\tduk_push_int(thr, (duk_int_t) (duk_int8_t) du.uc[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT16:\n\t\tduk_push_uint(thr, (duk_uint_t) du.us[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT16:\n\t\tduk_push_int(thr, (duk_int_t) (duk_int16_t) du.us[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT32:\n\t\tduk_push_uint(thr, (duk_uint_t) du.ui[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT32:\n\t\tduk_push_int(thr, (duk_int_t) (duk_int32_t) du.ui[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT32:\n\t\tduk_push_number(thr, (duk_double_t) du.f[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT64:\n\t\tduk_push_number(thr, (duk_double_t) du.d);\n\t\tbreak;\n\tdefault:\n\t\tDUK_UNREACHABLE();\n\t}\n}\n\n/* Indexed write helper for buffer objects, also called from outside this file. */\nDUK_INTERNAL void duk_hbufobj_validated_write(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size) {\n\tduk_double_union du;\n\n\t/* NOTE! Caller must ensure that any side effects from the\n\t * coercions below are safe.  If that cannot be guaranteed\n\t * (which is normally the case), caller must coerce the\n\t * argument using duk_to_number() before any pointer\n\t * validations; the result of duk_to_number() always coerces\n\t * without side effects here.\n\t */\n\n\tswitch (h_bufobj->elem_type) {\n\tcase DUK_HBUFOBJ_ELEM_UINT8:\n\t\tdu.uc[0] = (duk_uint8_t) duk_to_uint32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT8CLAMPED:\n\t\tdu.uc[0] = (duk_uint8_t) duk_to_uint8clamped(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT8:\n\t\tdu.uc[0] = (duk_uint8_t) duk_to_int32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT16:\n\t\tdu.us[0] = (duk_uint16_t) duk_to_uint32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT16:\n\t\tdu.us[0] = (duk_uint16_t) duk_to_int32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT32:\n\t\tdu.ui[0] = (duk_uint32_t) duk_to_uint32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT32:\n\t\tdu.ui[0] = (duk_uint32_t) duk_to_int32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT32:\n\t\t/* A double-to-float cast is undefined behavior in C99 if\n\t\t * the cast is out-of-range, so use a helper.  Example:\n\t\t * runtime error: value -1e+100 is outside the range of representable values of type 'float'\n\t\t */\n\t\tdu.f[0] = duk_double_to_float_t(duk_to_number_m1(thr));\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT64:\n\t\tdu.d = (duk_double_t) duk_to_number_m1(thr);\n\t\tbreak;\n\tdefault:\n\t\tDUK_UNREACHABLE();\n\t}\n\n\tDUK_ASSERT(elem_size > 0);\n\tduk_memcpy((void *) p, (const void *) du.uc, (size_t) elem_size);\n}\n\n/* Helper to create a fixed buffer from argument value at index 0.\n * Node.js and allocPlain() compatible.\n */\nDUK_LOCAL duk_hbuffer *duk__hbufobj_fixed_from_argvalue(duk_hthread *thr) {\n\tduk_int_t len;\n\tduk_int_t i;\n\tduk_size_t buf_size;\n\tduk_uint8_t *buf;\n\n\tswitch (duk_get_type(thr, 0)) {\n\tcase DUK_TYPE_NUMBER: {\n\t\tlen = duk_to_int_clamped(thr, 0, 0, DUK_INT_MAX);\n\t\t(void) duk_push_fixed_buffer_zero(thr, (duk_size_t) len);\n\t\tbreak;\n\t}\n\tcase DUK_TYPE_BUFFER: { /* Treat like Uint8Array. */\n\t\tgoto slow_copy;\n\t}\n\tcase DUK_TYPE_OBJECT: {\n\t\tduk_hobject *h;\n\t\tduk_hbufobj *h_bufobj;\n\n\t\t/* For Node.js Buffers \"Passing an ArrayBuffer returns a Buffer\n\t\t * that shares allocated memory with the given ArrayBuffer.\"\n\t\t * https://nodejs.org/api/buffer.html#buffer_buffer_from_buffer_alloc_and_buffer_allocunsafe\n\t\t */\n\n\t\th = duk_known_hobject(thr, 0);\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ(h));\n\t\t\th_bufobj = (duk_hbufobj *) h;\n\t\t\tif (DUK_UNLIKELY(h_bufobj->buf == NULL)) {\n\t\t\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(h_bufobj->offset != 0 || h_bufobj->length != DUK_HBUFFER_GET_SIZE(h_bufobj->buf))) {\n\t\t\t\t/* No support for ArrayBuffers with slice\n\t\t\t\t * offset/length.\n\t\t\t\t */\n\t\t\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t\t}\n\t\t\tduk_push_hbuffer(thr, h_bufobj->buf);\n\t\t\treturn h_bufobj->buf;\n\t\t}\n\t\tgoto slow_copy;\n\t}\n\tcase DUK_TYPE_STRING: {\n\t\t/* ignore encoding for now */\n\t\tduk_require_hstring_notsymbol(thr, 0);\n\t\tduk_dup_0(thr);\n\t\t(void) duk_to_buffer(thr, -1, &buf_size);\n\t\tbreak;\n\t}\n\tdefault:\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n done:\n\tDUK_ASSERT(duk_is_buffer(thr, -1));\n\treturn duk_known_hbuffer(thr, -1);\n\n slow_copy:\n\t/* XXX: fast path for typed arrays and other buffer objects? */\n\n\t(void) duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\tlen = duk_to_int_clamped(thr, -1, 0, DUK_INT_MAX);\n\tduk_pop(thr);\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) len);  /* no zeroing, all indices get initialized */\n\tfor (i = 0; i < len; i++) {\n\t\t/* XXX: fast path for array or buffer arguments? */\n\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);\n\t\tbuf[i] = (duk_uint8_t) (duk_to_uint32(thr, -1) & 0xffU);\n\t\tduk_pop(thr);\n\t}\n\tgoto done;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer constructor\n *\n *  Node.js Buffers are just Uint8Arrays with internal prototype set to\n *  Buffer.prototype so they're handled otherwise the same as Uint8Array.\n *  However, the constructor arguments are very different so a separate\n *  constructor entry point is used.\n */\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_hthread *thr) {\n\tduk_hbuffer *h_buf;\n\n\th_buf = duk__hbufobj_fixed_from_argvalue(thr);\n\tDUK_ASSERT(h_buf != NULL);\n\n\tduk_push_buffer_object(thr,\n\t                       -1,\n\t                       0,\n\t                       DUK_HBUFFER_FIXED_GET_SIZE((duk_hbuffer_fixed *) (void *) h_buf),\n\t                       DUK_BUFOBJ_UINT8ARRAY);\n\tduk_push_hobject_bidx(thr, DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);\n\tduk_set_prototype(thr, -2);\n\n\t/* XXX: a more direct implementation */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  ArrayBuffer, DataView, and TypedArray constructors\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_arraybuffer_constructor(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_int_t len;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tduk_require_constructor_call(thr);\n\n\tlen = duk_to_int(thr, 0);\n\tif (len < 0) {\n\t\tgoto fail_length;\n\t}\n\t(void) duk_push_fixed_buffer_zero(thr, (duk_size_t) len);\n\th_val = (duk_hbuffer *) duk_known_hbuffer(thr, -1);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),\n\t                               DUK_BIDX_ARRAYBUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_bufobj != NULL);\n\n\tduk__set_bufobj_buffer(thr, h_bufobj, h_val);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\treturn 1;\n\n fail_length:\n\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\n/* Format of magic, bits:\n *   0...1: elem size shift (0-3)\n *   2...5: elem type (DUK_HBUFOBJ_ELEM_xxx)\n *\n * XXX: add prototype bidx explicitly to magic instead of using a mapping?\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hobject *h_obj;\n\tduk_hbufobj *h_bufobj = NULL;\n\tduk_hbufobj *h_bufarg = NULL;\n\tduk_hbuffer *h_val;\n\tduk_small_uint_t magic;\n\tduk_small_uint_t shift;\n\tduk_small_uint_t elem_type;\n\tduk_small_uint_t elem_size;\n\tduk_small_uint_t class_num;\n\tduk_small_uint_t proto_bidx;\n\tduk_uint_t align_mask;\n\tduk_uint_t elem_length;\n\tduk_int_t elem_length_signed;\n\tduk_uint_t byte_length;\n\tduk_small_uint_t copy_mode;\n\n\t/* XXX: The same copy helpers could be shared with at least some\n\t * buffer functions.\n\t */\n\n\tduk_require_constructor_call(thr);\n\n\t/* We could fit built-in index into magic but that'd make the magic\n\t * number dependent on built-in numbering (genbuiltins.py doesn't\n\t * handle that yet).  So map both class and prototype from the\n\t * element type.\n\t */\n\tmagic = (duk_small_uint_t) duk_get_current_magic(thr);\n\tshift = magic & 0x03U;               /* bits 0...1: shift */\n\telem_type = (magic >> 2) & 0x0fU;    /* bits 2...5: type */\n\telem_size = 1U << shift;\n\talign_mask = elem_size - 1;\n\tDUK_ASSERT(elem_type < sizeof(duk__buffer_proto_from_elemtype) / sizeof(duk_uint8_t));\n\tproto_bidx = duk__buffer_proto_from_elemtype[elem_type];\n\tDUK_ASSERT(proto_bidx < DUK_NUM_BUILTINS);\n\tDUK_ASSERT(elem_type < sizeof(duk__buffer_class_from_elemtype) / sizeof(duk_uint8_t));\n\tclass_num = duk__buffer_class_from_elemtype[elem_type];\n\n\tDUK_DD(DUK_DDPRINT(\"typedarray constructor, magic=%d, shift=%d, elem_type=%d, \"\n\t                   \"elem_size=%d, proto_bidx=%d, class_num=%d\",\n\t                   (int) magic, (int) shift, (int) elem_type, (int) elem_size,\n\t                   (int) proto_bidx, (int) class_num));\n\n\t/* Argument variants.  When the argument is an ArrayBuffer a view to\n\t * the same buffer is created; otherwise a new ArrayBuffer is always\n\t * created.\n\t */\n\n\t/* XXX: initial iteration to treat a plain buffer like an ArrayBuffer:\n\t * coerce to an ArrayBuffer object and use that as .buffer.  The underlying\n\t * buffer will be the same but result .buffer !== inputPlainBuffer.\n\t */\n\tduk_hbufobj_promote_plain(thr, 0);\n\n\ttv = duk_get_tval(thr, 0);\n\tDUK_ASSERT(tv != NULL);  /* arg count */\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_obj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_obj != NULL);\n\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\t\t/* ArrayBuffer: unlike any other argument variant, create\n\t\t\t * a view into the existing buffer.\n\t\t\t */\n\n\t\t\tduk_int_t byte_offset_signed;\n\t\t\tduk_uint_t byte_offset;\n\n\t\t\th_bufarg = (duk_hbufobj *) h_obj;\n\n\t\t\tbyte_offset_signed = duk_to_int(thr, 1);\n\t\t\tif (byte_offset_signed < 0) {\n\t\t\t\tgoto fail_arguments;\n\t\t\t}\n\t\t\tbyte_offset = (duk_uint_t) byte_offset_signed;\n\t\t\tif (byte_offset > h_bufarg->length ||\n\t\t\t    (byte_offset & align_mask) != 0) {\n\t\t\t\t/* Must be >= 0 and multiple of element size. */\n\t\t\t\tgoto fail_arguments;\n\t\t\t}\n\t\t\tif (duk_is_undefined(thr, 2)) {\n\t\t\t\tDUK_ASSERT(h_bufarg->length >= byte_offset);\n\t\t\t\tbyte_length = h_bufarg->length - byte_offset;\n\t\t\t\tif ((byte_length & align_mask) != 0) {\n\t\t\t\t\t/* Must be element size multiple from\n\t\t\t\t\t * start offset to end of buffer.\n\t\t\t\t\t */\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t\telem_length = (byte_length >> shift);\n\t\t\t} else {\n\t\t\t\telem_length_signed = duk_to_int(thr, 2);\n\t\t\t\tif (elem_length_signed < 0) {\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t\telem_length = (duk_uint_t) elem_length_signed;\n\t\t\t\tbyte_length = elem_length << shift;\n\t\t\t\tif ((byte_length >> shift) != elem_length) {\n\t\t\t\t\t/* Byte length would overflow. */\n\t\t\t\t\t/* XXX: easier check with less code? */\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(h_bufarg->length >= byte_offset);\n\t\t\t\tif (byte_length > h_bufarg->length - byte_offset) {\n\t\t\t\t\t/* Not enough data. */\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t}\n\t\t\tDUK_UNREF(elem_length);\n\t\t\tDUK_ASSERT_DISABLE(byte_offset >= 0);\n\t\t\tDUK_ASSERT(byte_offset <= h_bufarg->length);\n\t\t\tDUK_ASSERT_DISABLE(byte_length >= 0);\n\t\t\tDUK_ASSERT(byte_offset + byte_length <= h_bufarg->length);\n\t\t\tDUK_ASSERT((elem_length << shift) == byte_length);\n\n\t\t\th_bufobj = duk_push_bufobj_raw(thr,\n\t\t\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t\t\t                               DUK_HOBJECT_CLASS_AS_FLAGS(class_num),\n\t\t\t                               (duk_small_int_t) proto_bidx);\n\t\t\th_val = h_bufarg->buf;\n\t\t\tif (h_val == NULL) {\n\t\t\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t}\n\t\t\th_bufobj->buf = h_val;\n\t\t\tDUK_HBUFFER_INCREF(thr, h_val);\n\t\t\th_bufobj->offset = h_bufarg->offset + byte_offset;\n\t\t\th_bufobj->length = byte_length;\n\t\t\th_bufobj->shift = (duk_uint8_t) shift;\n\t\t\th_bufobj->elem_type = (duk_uint8_t) elem_type;\n\t\t\th_bufobj->is_typedarray = 1;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t\t\t/* Set .buffer to the argument ArrayBuffer. */\n\t\t\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\t\t\th_bufobj->buf_prop = (duk_hobject *) h_bufarg;\n\t\t\tDUK_ASSERT(h_bufarg != NULL);\n\t\t\tDUK_HBUFOBJ_INCREF(thr, h_bufarg);\n\t\t\treturn 1;\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\t/* TypedArray (or other non-ArrayBuffer duk_hbufobj).\n\t\t\t * Conceptually same behavior as for an Array-like argument,\n\t\t\t * with a few fast paths.\n\t\t\t */\n\n\t\t\th_bufarg = (duk_hbufobj *) h_obj;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufarg);\n\t\t\telem_length_signed = (duk_int_t) (h_bufarg->length >> h_bufarg->shift);\n\t\t\tif (h_bufarg->buf == NULL) {\n\t\t\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t}\n\n\t\t\t/* Select copy mode.  Must take into account element\n\t\t\t * compatibility and validity of the underlying source\n\t\t\t * buffer.\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"selecting copy mode for bufobj arg, \"\n\t\t\t                     \"src byte_length=%ld, src shift=%d, \"\n\t\t\t                     \"src/dst elem_length=%ld; \"\n\t\t\t                     \"dst shift=%d -> dst byte_length=%ld\",\n\t\t\t                     (long) h_bufarg->length, (int) h_bufarg->shift,\n\t\t\t                     (long) elem_length_signed, (int) shift,\n\t\t\t                     (long) (elem_length_signed << shift)));\n\n\t\t\tcopy_mode = 2;  /* default is explicit index read/write copy */\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t/* With a size optimized build copy_mode 2 is enough.\n\t\t\t * Modes 0 and 1 are faster but conceptually the same.\n\t\t\t */\n\t\t\tDUK_ASSERT(elem_type < sizeof(duk__buffer_elemtype_copy_compatible) / sizeof(duk_uint16_t));\n\t\t\tif (DUK_HBUFOBJ_VALID_SLICE(h_bufarg)) {\n\t\t\t\tif ((duk__buffer_elemtype_copy_compatible[elem_type] & (1 << h_bufarg->elem_type)) != 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"source/target are copy compatible, memcpy\"));\n\t\t\t\t\tDUK_ASSERT(shift == h_bufarg->shift);  /* byte sizes will match */\n\t\t\t\t\tcopy_mode = 0;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"source/target not copy compatible but valid, fast copy\"));\n\t\t\t\t\tcopy_mode = 1;\n\t\t\t\t}\n\t\t\t}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\t\t} else {\n\t\t\t/* Array or Array-like */\n\t\t\telem_length_signed = (duk_int_t) duk_get_length(thr, 0);\n\t\t\tcopy_mode = 2;\n\t\t}\n\t} else {\n\t\t/* Non-object argument is simply int coerced, matches\n\t\t * V8 behavior (except for \"null\", which we coerce to\n\t\t * 0 but V8 TypeErrors).\n\t\t */\n\t\telem_length_signed = duk_to_int(thr, 0);\n\t\tcopy_mode = 3;\n\t}\n\tif (elem_length_signed < 0) {\n\t\tgoto fail_arguments;\n\t}\n\telem_length = (duk_uint_t) elem_length_signed;\n\tbyte_length = (duk_uint_t) (elem_length << shift);\n\tif ((byte_length >> shift) != elem_length) {\n\t\t/* Byte length would overflow. */\n\t\t/* XXX: easier check with less code? */\n\t\tgoto fail_arguments;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"elem_length=%ld, byte_length=%ld\",\n\t                     (long) elem_length, (long) byte_length));\n\n\t/* ArrayBuffer argument is handled specially above; the rest of the\n\t * argument variants are handled by shared code below.\n\t *\n\t * ArrayBuffer in h_bufobj->buf_prop is intentionally left unset.\n\t * It will be automatically created by the .buffer accessor on\n\t * first access.\n\t */\n\n\t/* Push the resulting view object on top of a plain fixed buffer. */\n\t(void) duk_push_fixed_buffer(thr, byte_length);\n\th_val = duk_known_hbuffer(thr, -1);\n\tDUK_ASSERT(h_val != NULL);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(class_num),\n\t                               (duk_small_int_t) proto_bidx);\n\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\tDUK_ASSERT(h_bufobj->offset == 0);\n\th_bufobj->length = byte_length;\n\th_bufobj->shift = (duk_uint8_t) shift;\n\th_bufobj->elem_type = (duk_uint8_t) elem_type;\n\th_bufobj->is_typedarray = 1;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t/* Copy values, the copy method depends on the arguments.\n\t *\n\t * Copy mode decision may depend on the validity of the underlying\n\t * buffer of the source argument; there must be no harmful side effects\n\t * from there to here for copy_mode to still be valid.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"copy mode: %d\", (int) copy_mode));\n\tswitch (copy_mode) {\n\t\t/* Copy modes 0 and 1 can be omitted in size optimized build,\n\t\t * copy mode 2 handles them (but more slowly).\n\t\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tcase 0: {\n\t\t/* Use byte copy. */\n\n\t\tduk_uint8_t *p_src;\n\t\tduk_uint8_t *p_dst;\n\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\t\tDUK_ASSERT(h_bufobj->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufobj));\n\t\tDUK_ASSERT(h_bufarg != NULL);\n\t\tDUK_ASSERT(h_bufarg->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufarg));\n\n\t\tp_dst = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj);\n\t\tp_src = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using memcpy: p_src=%p, p_dst=%p, byte_length=%ld\",\n\t\t                     (void *) p_src, (void *) p_dst, (long) byte_length));\n\n\t\tduk_memcpy_unsafe((void *) p_dst, (const void *) p_src, (size_t) byte_length);\n\t\tbreak;\n\t}\n\tcase 1: {\n\t\t/* Copy values through direct validated reads and writes. */\n\n\t\tduk_small_uint_t src_elem_size;\n\t\tduk_small_uint_t dst_elem_size;\n\t\tduk_uint8_t *p_src;\n\t\tduk_uint8_t *p_src_end;\n\t\tduk_uint8_t *p_dst;\n\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\t\tDUK_ASSERT(h_bufobj->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufobj));\n\t\tDUK_ASSERT(h_bufarg != NULL);\n\t\tDUK_ASSERT(h_bufarg->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufarg));\n\n\t\tsrc_elem_size = (duk_small_uint_t) (1U << h_bufarg->shift);\n\t\tdst_elem_size = elem_size;\n\n\t\tp_src = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg);\n\t\tp_dst = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj);\n\t\tp_src_end = p_src + h_bufarg->length;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using fast copy: p_src=%p, p_src_end=%p, p_dst=%p, \"\n\t\t                     \"src_elem_size=%d, dst_elem_size=%d\",\n\t\t                     (void *) p_src, (void *) p_src_end, (void *) p_dst,\n\t\t                     (int) src_elem_size, (int) dst_elem_size));\n\n\t\twhile (p_src != p_src_end) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path per element copy loop: \"\n\t\t\t                     \"p_src=%p, p_src_end=%p, p_dst=%p\",\n\t\t\t                     (void *) p_src, (void *) p_src_end, (void *) p_dst));\n\t\t\t/* A validated read() is always a number, so it's write coercion\n\t\t\t * is always side effect free an won't invalidate pointers etc.\n\t\t\t */\n\t\t\tduk_hbufobj_push_validated_read(thr, h_bufarg, p_src, src_elem_size);\n\t\t\tduk_hbufobj_validated_write(thr, h_bufobj, p_dst, dst_elem_size);\n\t\t\tduk_pop(thr);\n\t\t\tp_src += src_elem_size;\n\t\t\tp_dst += dst_elem_size;\n\t\t}\n\t\tbreak;\n\t}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\tcase 2: {\n\t\t/* Copy values by index reads and writes.  Let virtual\n\t\t * property handling take care of coercion.\n\t\t */\n\t\tduk_uint_t i;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using slow copy\"));\n\n\t\tfor (i = 0; i < elem_length; i++) {\n\t\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);\n\t\t\tduk_put_prop_index(thr, -2, (duk_uarridx_t) i);\n\t\t}\n\t\tbreak;\n\t}\n\tdefault:\n\tcase 3: {\n\t\t/* No copy, leave zero bytes in the buffer.  There's no\n\t\t * ambiguity with Float32/Float64 because zero bytes also\n\t\t * represent 0.0.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using no copy\"));\n\t\tbreak;\n\t}\n\t}\n\n\treturn 1;\n\n fail_arguments:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n/* When bufferobject support is disabled, new Uint8Array() could still be\n * supported to create a plain fixed buffer.  Disabled for now.\n */\n#if 0\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) {\n\tduk_int_t elem_length_signed;\n\tduk_uint_t byte_length;\n\n\t/* XXX: The same copy helpers could be shared with at least some\n\t * buffer functions.\n\t */\n\n\tduk_require_constructor_call(thr);\n\n\telem_length_signed = duk_require_int(thr, 0);\n\tif (elem_length_signed < 0) {\n\t\tgoto fail_arguments;\n\t}\n\tbyte_length = (duk_uint_t) elem_length_signed;\n\n\t(void) duk_push_fixed_buffer_zero(thr, (duk_size_t) byte_length);\n\treturn 1;\n\n fail_arguments:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* 0 */\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_dataview_constructor(duk_hthread *thr) {\n\tduk_hbufobj *h_bufarg;\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_uint_t offset;\n\tduk_uint_t length;\n\n\tduk_require_constructor_call(thr);\n\n\th_bufarg = duk__require_bufobj_value(thr, 0);\n\tDUK_ASSERT(h_bufarg != NULL);\n\tif (DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *) h_bufarg) != DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tduk__resolve_offset_opt_length(thr, h_bufarg, 1, 2, &offset, &length, 1 /*throw_flag*/);\n\tDUK_ASSERT(offset <= h_bufarg->length);\n\tDUK_ASSERT(offset + length <= h_bufarg->length);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATAVIEW),\n\t                               DUK_BIDX_DATAVIEW_PROTOTYPE);\n\n\th_val = h_bufarg->buf;\n\tif (h_val == NULL) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\th_bufobj->offset = h_bufarg->offset + offset;\n\th_bufobj->length = length;\n\tDUK_ASSERT(h_bufobj->shift == 0);\n\tDUK_ASSERT(h_bufobj->elem_type == DUK_HBUFOBJ_ELEM_UINT8);\n\tDUK_ASSERT(h_bufobj->is_typedarray == 0);\n\n\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\th_bufobj->buf_prop = (duk_hobject *) h_bufarg;\n\tDUK_ASSERT(h_bufarg != NULL);\n\tDUK_HBUFOBJ_INCREF(thr, h_bufarg);\n\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  ArrayBuffer.isView()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_arraybuffer_isview(duk_hthread *thr) {\n\tduk_hobject *h_obj;\n\tduk_bool_t ret = 0;\n\n\tif (duk_is_buffer(thr, 0)) {\n\t\tret = 1;\n\t} else {\n\t\th_obj = duk_get_hobject(thr, 0);\n\t\tif (h_obj != NULL && DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\t/* DataView needs special casing: ArrayBuffer.isView() is\n\t\t\t * true, but ->is_typedarray is 0.\n\t\t\t */\n\t\t\tret = ((duk_hbufobj *) h_obj)->is_typedarray ||\n\t\t\t      (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_DATAVIEW);\n\t\t}\n\t}\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Uint8Array.allocPlain()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_uint8array_allocplain(duk_hthread *thr) {\n\tduk__hbufobj_fixed_from_argvalue(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Uint8Array.plainOf()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_uint8array_plainof(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\t/* Avoid churn if argument is already a plain buffer. */\n\tif (duk_is_buffer(thr, 0)) {\n\t\treturn 1;\n\t}\n#endif\n\n\t/* Promotes plain buffers to ArrayBuffers, so for a plain buffer\n\t * argument we'll create a pointless temporary (but still work\n\t * correctly).\n\t */\n\th_bufobj = duk__require_bufobj_value(thr, 0);\n\tif (h_bufobj->buf == NULL) {\n\t\tduk_push_undefined(thr);\n\t} else {\n\t\tduk_push_hbuffer(thr, h_bufobj->buf);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer: toString([encoding], [start], [end])\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_int_t start_offset, end_offset;\n\tduk_uint8_t *buf_slice;\n\tduk_size_t slice_length;\n\n\th_this = duk__get_bufobj_this(thr);\n\tif (h_this == NULL) {\n\t\t/* XXX: happens e.g. when evaluating: String(Buffer.prototype). */\n\t\tduk_push_literal(thr, \"[object Object]\");\n\t\treturn 1;\n\t}\n\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\n\t/* Ignore encoding for now. */\n\n\tduk__clamp_startend_nonegidx_noshift(thr,\n\t                                     (duk_int_t) h_this->length,\n\t                                     1 /*idx_start*/,\n\t                                     2 /*idx_end*/,\n\t                                     &start_offset,\n\t                                     &end_offset);\n\n\tslice_length = (duk_size_t) (end_offset - start_offset);\n\tbuf_slice = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, slice_length);  /* all bytes initialized below */\n\tDUK_ASSERT(buf_slice != NULL);\n\n\t/* Neutered or uncovered, TypeError. */\n\tif (h_this->buf == NULL ||\n\t    !DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, (duk_size_t) start_offset + slice_length)) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* XXX: ideally we wouldn't make a copy but a view into the buffer for the\n\t * decoding process.  Or the decoding helper could be changed to accept\n\t * the slice info (a buffer pointer is NOT a good approach because guaranteeing\n\t * its stability is difficult).\n\t */\n\n\tDUK_ASSERT(DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, (duk_size_t) start_offset + slice_length));\n\tduk_memcpy_unsafe((void *) buf_slice,\n\t                  (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + start_offset),\n\t                  (size_t) slice_length);\n\n\t/* Use the equivalent of: new TextEncoder().encode(this) to convert the\n\t * string.  Result will be valid UTF-8; non-CESU-8 inputs are currently\n\t * interpreted loosely.  Value stack convention is a bit odd for now.\n\t */\n\tduk_replace(thr, 0);\n\tduk_set_top(thr, 1);\n\treturn duk_textdecoder_decode_utf8_nodejs(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype: toJSON()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_uint8_t *buf;\n\tduk_uint_t i, n;\n\tduk_tval *tv;\n\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\n\tif (h_this->buf == NULL || !DUK_HBUFOBJ_VALID_SLICE(h_this)) {\n\t\t/* Serialize uncovered backing buffer as a null; doesn't\n\t\t * really matter as long we're memory safe.\n\t\t */\n\t\tduk_push_null(thr);\n\t\treturn 1;\n\t}\n\n\tduk_push_object(thr);\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_BUFFER);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_TYPE);\n\n\t/* XXX: uninitialized would be OK */\n\tDUK_ASSERT_DISABLE((duk_size_t) h_this->length <= (duk_size_t) DUK_UINT32_MAX);\n\ttv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) h_this->length);  /* XXX: needs revision with >4G buffers */\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\tDUK_ASSERT(h_this->buf != NULL);\n\tbuf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this);\n\tfor (i = 0, n = h_this->length; i < n; i++) {\n\t\tDUK_TVAL_SET_U32(tv + i, (duk_uint32_t) buf[i]);  /* no need for decref or incref */\n\t}\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_DATA);\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.equals()\n *  Node.js Buffer.prototype.compare()\n *  Node.js Buffer.compare()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_buffer_compare_shared(duk_hthread *thr) {\n\tduk_small_uint_t magic;\n\tduk_hbufobj *h_bufarg1;\n\tduk_hbufobj *h_bufarg2;\n\tduk_small_int_t comp_res;\n\n\t/* XXX: keep support for plain buffers and non-Node.js buffers? */\n\n\tmagic = (duk_small_uint_t) duk_get_current_magic(thr);\n\tif (magic & 0x02U) {\n\t\t/* Static call style. */\n\t\th_bufarg1 = duk__require_bufobj_value(thr, 0);\n\t\th_bufarg2 = duk__require_bufobj_value(thr, 1);\n\t} else {\n\t\th_bufarg1 = duk__require_bufobj_this(thr);\n\t\th_bufarg2 = duk__require_bufobj_value(thr, 0);\n\t}\n\tDUK_ASSERT(h_bufarg1 != NULL);\n\tDUK_ASSERT(h_bufarg2 != NULL);\n\n\t/* We want to compare the slice/view areas of the arguments.\n\t * If either slice/view is invalid (underlying buffer is shorter)\n\t * ensure equals() is false, but otherwise the only thing that\n\t * matters is to be memory safe.\n\t */\n\n\tif (DUK_HBUFOBJ_VALID_SLICE(h_bufarg1) &&\n\t    DUK_HBUFOBJ_VALID_SLICE(h_bufarg2)) {\n\t\tcomp_res = duk_js_data_compare((const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufarg1->buf) + h_bufarg1->offset,\n\t\t                               (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufarg2->buf) + h_bufarg2->offset,\n\t\t                               (duk_size_t) h_bufarg1->length,\n\t\t                               (duk_size_t) h_bufarg2->length);\n\t} else {\n\t\tcomp_res = -1;  /* either nonzero value is ok */\n\t}\n\n\tif (magic & 0x01U) {\n\t\t/* compare: similar to string comparison but for buffer data. */\n\t\tduk_push_int(thr, comp_res);\n\t} else {\n\t\t/* equals */\n\t\tduk_push_boolean(thr, (comp_res == 0));\n\t}\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.fill()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tconst duk_uint8_t *fill_str_ptr;\n\tduk_size_t fill_str_len;\n\tduk_uint8_t fill_value;\n\tduk_int_t fill_offset;\n\tduk_int_t fill_end;\n\tduk_size_t fill_length;\n\tduk_uint8_t *p;\n\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\tif (h_this->buf == NULL) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* [ value offset end ] */\n\n\tif (duk_is_string_notsymbol(thr, 0)) {\n\t\tfill_str_ptr = (const duk_uint8_t *) duk_get_lstring(thr, 0, &fill_str_len);\n\t\tDUK_ASSERT(fill_str_ptr != NULL);\n\t} else {\n\t\t/* Symbols get ToNumber() coerced and cause TypeError. */\n\t\tfill_value = (duk_uint8_t) duk_to_uint32(thr, 0);\n\t\tfill_str_ptr = (const duk_uint8_t *) &fill_value;\n\t\tfill_str_len = 1;\n\t}\n\n\t/* Fill offset handling is more lenient than in Node.js. */\n\n\tduk__clamp_startend_nonegidx_noshift(thr,\n\t                                     (duk_int_t) h_this->length,\n\t                                     1 /*idx_start*/,\n\t                                     2 /*idx_end*/,\n\t                                     &fill_offset,\n\t                                     &fill_end);\n\n\tDUK_DDD(DUK_DDDPRINT(\"fill: fill_value=%02x, fill_offset=%ld, fill_end=%ld, view length=%ld\",\n\t                     (unsigned int) fill_value, (long) fill_offset, (long) fill_end, (long) h_this->length));\n\n\tDUK_ASSERT(fill_end - fill_offset >= 0);\n\tDUK_ASSERT(h_this->buf != NULL);\n\n\tp = (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + fill_offset);\n\tfill_length = (duk_size_t) (fill_end - fill_offset);\n\tif (fill_str_len == 1) {\n\t\t/* Handle single character fills as memset() even when\n\t\t * the fill data comes from a one-char argument.\n\t\t */\n\t\tduk_memset_unsafe((void *) p, (int) fill_str_ptr[0], (size_t) fill_length);\n\t} else if (fill_str_len > 1) {\n\t\tduk_size_t i, n, t;\n\n\t\tfor (i = 0, n = (duk_size_t) (fill_end - fill_offset), t = 0; i < n; i++) {\n\t\t\tp[i] = fill_str_ptr[t++];\n\t\t\tif (t >= fill_str_len) {\n\t\t\t\tt = 0;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"zero size fill pattern, ignore silently\"));\n\t}\n\n\t/* Return the Buffer to allow chaining: b.fill(0x11).fill(0x22, 3, 5).toString() */\n\tduk_push_this(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.write(string, [offset], [length], [encoding])\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_write(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_uint_t offset;\n\tduk_uint_t length;\n\tconst duk_uint8_t *str_data;\n\tduk_size_t str_len;\n\n\t/* XXX: very inefficient support for plain buffers */\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\n\t/* Argument must be a string, e.g. a buffer is not allowed. */\n\tstr_data = (const duk_uint8_t *) duk_require_lstring_notsymbol(thr, 0, &str_len);\n\n\tduk__resolve_offset_opt_length(thr, h_this, 1, 2, &offset, &length, 0 /*throw_flag*/);\n\tDUK_ASSERT(offset <= h_this->length);\n\tDUK_ASSERT(offset + length <= h_this->length);\n\n\t/* XXX: encoding is ignored now. */\n\n\tif (length > str_len) {\n\t\tlength = (duk_uint_t) str_len;\n\t}\n\n\tif (DUK_HBUFOBJ_VALID_SLICE(h_this)) {\n\t\t/* Cannot overlap. */\n\t\tduk_memcpy_unsafe((void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + offset),\n\t\t                  (const void *) str_data,\n\t\t                  (size_t) length);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"write() target buffer is not covered, silent ignore\"));\n\t}\n\n\tduk_push_uint(thr, length);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.copy()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_hbufobj *h_bufarg;\n\tduk_int_t source_length;\n\tduk_int_t target_length;\n\tduk_int_t target_start, source_start, source_end;\n\tduk_uint_t target_ustart, source_ustart, source_uend;\n\tduk_uint_t copy_size = 0;\n\n\t/* [ targetBuffer targetStart sourceStart sourceEnd ] */\n\n\th_this = duk__require_bufobj_this(thr);\n\th_bufarg = duk__require_bufobj_value(thr, 0);\n\tDUK_ASSERT(h_this != NULL);\n\tDUK_ASSERT(h_bufarg != NULL);\n\tsource_length = (duk_int_t) h_this->length;\n\ttarget_length = (duk_int_t) h_bufarg->length;\n\n\ttarget_start = duk_to_int(thr, 1);\n\tsource_start = duk_to_int(thr, 2);\n\tif (duk_is_undefined(thr, 3)) {\n\t\tsource_end = source_length;\n\t} else {\n\t\tsource_end = duk_to_int(thr, 3);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"checking copy args: target_start=%ld, target_length=%ld, \"\n\t                     \"source_start=%ld, source_end=%ld, source_length=%ld\",\n\t                     (long) target_start, (long) h_bufarg->length,\n\t                     (long) source_start, (long) source_end, (long) source_length));\n\n\t/* This behavior mostly mimics Node.js now. */\n\n\tif (source_start < 0 || source_end < 0 || target_start < 0) {\n\t\t/* Negative offsets cause a RangeError. */\n\t\tgoto fail_bounds;\n\t}\n\tsource_ustart = (duk_uint_t) source_start;\n\tsource_uend = (duk_uint_t) source_end;\n\ttarget_ustart = (duk_uint_t) target_start;\n\tif (source_ustart >= source_uend ||  /* crossed offsets or zero size */\n\t    source_ustart >= (duk_uint_t) source_length ||  /* source out-of-bounds (but positive) */\n\t    target_ustart >= (duk_uint_t) target_length) {  /* target out-of-bounds (but positive) */\n\t\tgoto silent_ignore;\n\t}\n\tif (source_uend >= (duk_uint_t) source_length) {\n\t\t/* Source end clamped silently to available length. */\n\t\tsource_uend = (duk_uint_t) source_length;\n\t}\n\tcopy_size = source_uend - source_ustart;\n\tif (target_ustart + copy_size > (duk_uint_t) target_length) {\n\t\t/* Clamp to target's end if too long.\n\t\t *\n\t\t * NOTE: there's no overflow possibility in the comparison;\n\t\t * both target_ustart and copy_size are >= 0 and based on\n\t\t * values in duk_int_t range.  Adding them as duk_uint_t\n\t\t * values is then guaranteed not to overflow.\n\t\t */\n\t\tDUK_ASSERT(target_ustart + copy_size >= target_ustart);  /* no overflow */\n\t\tDUK_ASSERT(target_ustart + copy_size >= copy_size);  /* no overflow */\n\t\tcopy_size = (duk_uint_t) target_length - target_ustart;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"making copy: target_ustart=%lu source_ustart=%lu copy_size=%lu\",\n\t                     (unsigned long) target_ustart, (unsigned long) source_ustart,\n\t                     (unsigned long) copy_size));\n\n\tDUK_ASSERT(copy_size >= 1);\n\tDUK_ASSERT(source_ustart <= (duk_uint_t) source_length);\n\tDUK_ASSERT(source_ustart + copy_size <= (duk_uint_t) source_length);\n\tDUK_ASSERT(target_ustart <= (duk_uint_t) target_length);\n\tDUK_ASSERT(target_ustart + copy_size <= (duk_uint_t) target_length);\n\n\t/* Ensure copy is covered by underlying buffers. */\n\tDUK_ASSERT(h_bufarg->buf != NULL);  /* length check */\n\tDUK_ASSERT(h_this->buf != NULL);    /* length check */\n\tif (DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufarg, target_ustart + copy_size) &&\n\t    DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, source_ustart + copy_size)) {\n\t\t/* Must use memmove() because copy area may overlap (source and target\n\t\t * buffer may be the same, or from different slices.\n\t\t */\n\t\tduk_memmove_unsafe((void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg) + target_ustart),\n\t\t                   (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + source_ustart),\n\t\t                   (size_t) copy_size);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"buffer copy not covered by underlying buffer(s), ignoring\"));\n\t}\n\n silent_ignore:\n\t/* Return value is like write(), number of bytes written.\n\t * The return value matters because of code like:\n\t * \"off += buf.copy(...)\".\n         */\n\tduk_push_uint(thr, copy_size);\n\treturn 1;\n\n fail_bounds:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  TypedArray.prototype.set()\n *\n *  TypedArray set() is pretty interesting to implement because:\n *\n *    - The source argument may be a plain array or a typedarray.  If the\n *      source is a TypedArray, values are decoded and re-encoded into the\n *      target (not as a plain byte copy).  This may happen even when the\n *      element byte size is the same, e.g. integer values may be re-encoded\n *      into floats.\n *\n *    - Source and target may refer to the same underlying buffer, so that\n *      the set() operation may overlap.  The specification requires that this\n *      must work as if a copy was made before the operation.  Note that this\n *      is NOT a simple memmove() situation because the source and target\n *      byte sizes may be different -- e.g. a 4-byte source (Int8Array) may\n *      expand to a 16-byte target (Uint32Array) so that the target overlaps\n *      the source both from beginning and the end (unlike in typical memmove).\n *\n *    - Even if 'buf' pointers of the source and target differ, there's no\n *      guarantee that their memory areas don't overlap.  This may be the\n *      case with external buffers.\n *\n *  Even so, it is nice to optimize for the common case:\n *\n *    - Source and target separate buffers or non-overlapping.\n *\n *    - Source and target have a compatible type so that a plain byte copy\n *      is possible.  Note that while e.g. uint8 and int8 are compatible\n *      (coercion one way or another doesn't change the byte representation),\n *      e.g. int8 and uint8clamped are NOT compatible when writing int8\n *      values into uint8clamped typedarray (-1 would clamp to 0 for instance).\n *\n *  See test-bi-typedarray-proto-set.js.\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_hobject *h_obj;\n\tduk_uarridx_t i, n;\n\tduk_int_t offset_signed;\n\tduk_uint_t offset_elems;\n\tduk_uint_t offset_bytes;\n\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\n\tif (h_this->buf == NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"source neutered, skip copy\"));\n\t\treturn 0;\n\t}\n\n\tduk_hbufobj_promote_plain(thr, 0);\n\th_obj = duk_require_hobject(thr, 0);\n\n\t/* XXX: V8 throws a TypeError for negative values.  Would it\n\t * be more useful to interpret negative offsets here from the\n\t * end of the buffer too?\n\t */\n\toffset_signed = duk_to_int(thr, 1);\n\tif (offset_signed < 0) {\n\t\t/* For some reason this is a TypeError (at least in V8). */\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\toffset_elems = (duk_uint_t) offset_signed;\n\toffset_bytes = offset_elems << h_this->shift;\n\tif ((offset_bytes >> h_this->shift) != offset_elems) {\n\t\t/* Byte length would overflow. */\n\t\t/* XXX: easier check with less code? */\n\t\tgoto fail_args;\n\t}\n\tif (offset_bytes > h_this->length) {\n\t\t/* Equality may be OK but >length not.  Checking\n\t\t * this explicitly avoids some overflow cases\n\t\t * below.\n\t\t */\n\t\tgoto fail_args;\n\t}\n\tDUK_ASSERT(offset_bytes <= h_this->length);\n\n\t/* Fast path: source is a TypedArray (or any bufobj). */\n\n\tif (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\tduk_hbufobj *h_bufarg;\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\tduk_uint16_t comp_mask;\n#endif\n\t\tduk_small_int_t no_overlap = 0;\n\t\tduk_uint_t src_length;\n\t\tduk_uint_t dst_length;\n\t\tduk_uint_t dst_length_elems;\n\t\tduk_uint8_t *p_src_base;\n\t\tduk_uint8_t *p_src_end;\n\t\tduk_uint8_t *p_src;\n\t\tduk_uint8_t *p_dst_base;\n\t\tduk_uint8_t *p_dst;\n\t\tduk_small_uint_t src_elem_size;\n\t\tduk_small_uint_t dst_elem_size;\n\n\t\th_bufarg = (duk_hbufobj *) h_obj;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufarg);\n\n\t\tif (h_bufarg->buf == NULL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"target neutered, skip copy\"));\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* Nominal size check. */\n\t\tsrc_length = h_bufarg->length;  /* bytes in source */\n\t\tdst_length_elems = (src_length >> h_bufarg->shift);  /* elems in source and dest */\n\t\tdst_length = dst_length_elems << h_this->shift;  /* bytes in dest */\n\t\tif ((dst_length >> h_this->shift) != dst_length_elems) {\n\t\t\t/* Byte length would overflow. */\n\t\t\t/* XXX: easier check with less code? */\n\t\t\tgoto fail_args;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"nominal size check: src_length=%ld, dst_length=%ld\",\n\t\t                     (long) src_length, (long) dst_length));\n\t\tDUK_ASSERT(offset_bytes <= h_this->length);\n\t\tif (dst_length > h_this->length - offset_bytes) {\n\t\t\t/* Overflow not an issue because subtraction is used on the right\n\t\t\t * side and guaranteed to be >= 0.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copy exceeds target buffer nominal length\"));\n\t\t\tgoto fail_args;\n\t\t}\n\t\tif (!DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, offset_bytes + dst_length)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copy not covered by underlying target buffer, ignore\"));\n\t\t\treturn 0;\n\t\t}\n\n\t\tp_src_base = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg);\n\t\tp_dst_base = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + offset_bytes;\n\n\t\t/* Check actual underlying buffers for validity and that they\n\t\t * cover the copy.  No side effects are allowed after the check\n\t\t * so that the validity status doesn't change.\n\t\t */\n\t\tif (!DUK_HBUFOBJ_VALID_SLICE(h_this) ||\n\t\t    !DUK_HBUFOBJ_VALID_SLICE(h_bufarg)) {\n\t\t\t/* The condition could be more narrow and check for the\n\t\t\t * copy area only, but there's no need for fine grained\n\t\t\t * behavior when the underlying buffer is misconfigured.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"source and/or target not covered by underlying buffer, skip copy\"));\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* We want to do a straight memory copy if possible: this is\n\t\t * an important operation because .set() is the TypedArray\n\t\t * way to copy chunks of memory.  However, because set()\n\t\t * conceptually works in terms of elements, not all views are\n\t\t * compatible with direct byte copying.\n\t\t *\n\t\t * If we do manage a direct copy, the \"overlap issue\" handled\n\t\t * below can just be solved using memmove() because the source\n\t\t * and destination element sizes are necessarily equal.\n\t\t */\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\tDUK_ASSERT(h_this->elem_type < sizeof(duk__buffer_elemtype_copy_compatible) / sizeof(duk_uint16_t));\n\t\tcomp_mask = duk__buffer_elemtype_copy_compatible[h_this->elem_type];\n\t\tif (comp_mask & (1 << h_bufarg->elem_type)) {\n\t\t\tDUK_ASSERT(src_length == dst_length);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path: able to use memmove() because views are compatible\"));\n\t\t\tduk_memmove_unsafe((void *) p_dst_base, (const void *) p_src_base, (size_t) dst_length);\n\t\t\treturn 0;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"fast path: views are not compatible with a byte copy, copy by item\"));\n#endif  /* !DUK_USE_PREFER_SIZE */\n\n\t\t/* We want to avoid making a copy to process set() but that's\n\t\t * not always possible: the source and the target may overlap\n\t\t * and because element sizes are different, the overlap cannot\n\t\t * always be handled with a memmove() or choosing the copy\n\t\t * direction in a certain way.  For example, if source type is\n\t\t * uint8 and target type is uint32, the target area may exceed\n\t\t * the source area from both ends!\n\t\t *\n\t\t * Note that because external buffers may point to the same\n\t\t * memory areas, we must ultimately make this check using\n\t\t * pointers.\n\t\t *\n\t\t * NOTE: careful with side effects: any side effect may cause\n\t\t * a buffer resize (or external buffer pointer/length update)!\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"overlap check: p_src_base=%p, src_length=%ld, \"\n\t\t                     \"p_dst_base=%p, dst_length=%ld\",\n\t\t                     (void *) p_src_base, (long) src_length,\n\t\t                     (void *) p_dst_base, (long) dst_length));\n\n\t\tif (p_src_base >= p_dst_base + dst_length ||  /* source starts after dest ends */\n\t\t    p_src_base + src_length <= p_dst_base) {   /* source ends before dest starts */\n\t\t\tno_overlap = 1;\n\t\t}\n\n\t\tif (!no_overlap) {\n\t\t\t/* There's overlap: the desired end result is that\n\t\t\t * conceptually a copy is made to avoid \"trampling\"\n\t\t\t * of source data by destination writes.  We make\n\t\t\t * an actual temporary copy to handle this case.\n\t\t\t */\n\t\t\tduk_uint8_t *p_src_copy;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"there is overlap, make a copy of the source\"));\n\t\t\tp_src_copy = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, src_length);\n\t\t\tDUK_ASSERT(p_src_copy != NULL);\n\t\t\tduk_memcpy_unsafe((void *) p_src_copy, (const void *) p_src_base, (size_t) src_length);\n\n\t\t\tp_src_base = p_src_copy;  /* use p_src_base from now on */\n\t\t}\n\t\t/* Value stack intentionally mixed size here. */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"after overlap check: p_src_base=%p, src_length=%ld, \"\n\t\t                     \"p_dst_base=%p, dst_length=%ld, valstack top=%ld\",\n\t\t                     (void *) p_src_base, (long) src_length,\n\t\t                     (void *) p_dst_base, (long) dst_length,\n\t\t                     (long) duk_get_top(thr)));\n\n\t\t/* Ready to make the copy.  We must proceed element by element\n\t\t * and must avoid any side effects that might cause the buffer\n\t\t * validity check above to become invalid.\n\t\t *\n\t\t * Although we work through the value stack here, only plain\n\t\t * numbers are handled which should be side effect safe.\n\t\t */\n\n\t\tsrc_elem_size = (duk_small_uint_t) (1U << h_bufarg->shift);\n\t\tdst_elem_size = (duk_small_uint_t) (1U << h_this->shift);\n\t\tp_src = p_src_base;\n\t\tp_dst = p_dst_base;\n\t\tp_src_end = p_src_base + src_length;\n\n\t\twhile (p_src != p_src_end) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path per element copy loop: \"\n\t\t\t                     \"p_src=%p, p_src_end=%p, p_dst=%p\",\n\t\t\t                     (void *) p_src, (void *) p_src_end, (void *) p_dst));\n\t\t\t/* A validated read() is always a number, so it's write coercion\n\t\t\t * is always side effect free an won't invalidate pointers etc.\n\t\t\t */\n\t\t\tduk_hbufobj_push_validated_read(thr, h_bufarg, p_src, src_elem_size);\n\t\t\tduk_hbufobj_validated_write(thr, h_this, p_dst, dst_elem_size);\n\t\t\tduk_pop(thr);\n\t\t\tp_src += src_elem_size;\n\t\t\tp_dst += dst_elem_size;\n\t\t}\n\n\t\treturn 0;\n\t} else {\n\t\t/* Slow path: quite slow, but we save space by using the property code\n\t\t * to write coerce target values.  We don't need to worry about overlap\n\t\t * here because the source is not a TypedArray.\n\t\t *\n\t\t * We could use the bufobj write coercion helper but since the\n\t\t * property read may have arbitrary side effects, full validity checks\n\t\t * would be needed for every element anyway.\n\t\t */\n\n\t\tn = (duk_uarridx_t) duk_get_length(thr, 0);\n\t\tDUK_ASSERT(offset_bytes <= h_this->length);\n\t\tif ((n << h_this->shift) > h_this->length - offset_bytes) {\n\t\t\t/* Overflow not an issue because subtraction is used on the right\n\t\t\t * side and guaranteed to be >= 0.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copy exceeds target buffer nominal length\"));\n\t\t\tgoto fail_args;\n\t\t}\n\n\t\t/* There's no need to check for buffer validity status for the\n\t\t * target here: the property access code will do that for each\n\t\t * element.  Moreover, if we did check the validity here, side\n\t\t * effects from reading the source argument might invalidate\n\t\t * the results anyway.\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t\tduk_push_this(thr);\n\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk_get_prop_index(thr, 0, i);\n\t\t\tduk_put_prop_index(thr, 2, offset_elems + i);\n\t\t}\n\t}\n\n\treturn 0;\n\n fail_args:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.slice([start], [end])\n *  ArrayBuffer.prototype.slice(begin, [end])\n *  TypedArray.prototype.subarray(begin, [end])\n *\n *  The API calls are almost identical; negative indices are counted from end\n *  of buffer, and final indices are clamped (allowing crossed indices).  Main\n *  differences:\n *\n *    - Copy/view behavior; Node.js .slice() and TypedArray .subarray() create\n *      views, ArrayBuffer .slice() creates a copy\n *\n *    - Resulting object has a different class and prototype depending on the\n *      call (or 'this' argument)\n *\n *    - TypedArray .subarray() arguments are element indices, not byte offsets\n *\n *    - Plain buffer argument creates a plain buffer slice\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL void duk__arraybuffer_plain_slice(duk_hthread *thr, duk_hbuffer *h_val) {\n\tduk_int_t start_offset, end_offset;\n\tduk_uint_t slice_length;\n\tduk_uint8_t *p_copy;\n\tduk_size_t copy_length;\n\n\tduk__clamp_startend_negidx_shifted(thr,\n\t                                   (duk_int_t) DUK_HBUFFER_GET_SIZE(h_val),\n\t                                   0 /*buffer_shift*/,\n\t                                   0 /*idx_start*/,\n\t                                   1 /*idx_end*/,\n\t                                   &start_offset,\n\t                                   &end_offset);\n\tDUK_ASSERT(end_offset <= (duk_int_t) DUK_HBUFFER_GET_SIZE(h_val));\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(end_offset >= start_offset);\n\tslice_length = (duk_uint_t) (end_offset - start_offset);\n\n\tp_copy = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) slice_length);\n\tDUK_ASSERT(p_copy != NULL);\n\tcopy_length = slice_length;\n\n\tduk_memcpy_unsafe((void *) p_copy,\n\t                  (const void *) ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_val) + start_offset),\n\t                  copy_length);\n}\n#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Shared helper for slice/subarray operation.\n * Magic: 0x01=isView, 0x02=copy, 0x04=Node.js Buffer special handling.\n */\nDUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_hthread *thr) {\n\tduk_small_int_t magic;\n\tduk_small_uint_t res_class_num;\n\tduk_small_int_t res_proto_bidx;\n\tduk_hbufobj *h_this;\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_int_t start_offset, end_offset;\n\tduk_uint_t slice_length;\n\tduk_tval *tv;\n\n\t/* [ start end ] */\n\n\tmagic = duk_get_current_magic(thr);\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\t/* For plain buffers return a plain buffer slice. */\n\t\th_val = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h_val != NULL);\n\n\t\tif (magic & 0x02) {\n\t\t\t/* Make copy: ArrayBuffer.prototype.slice() uses this. */\n\t\t\tduk__arraybuffer_plain_slice(thr, h_val);\n\t\t\treturn 1;\n\t\t} else {\n\t\t\t/* View into existing buffer: cannot be done if the\n\t\t\t * result is a plain buffer because there's no slice\n\t\t\t * info.  So return an ArrayBuffer instance; coerce\n\t\t\t * the 'this' binding into an object and behave as if\n\t\t\t * the original call was for an Object-coerced plain\n\t\t\t * buffer (handled automatically by duk__require_bufobj_this()).\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slice() doesn't handle view into plain buffer, coerce 'this' to ArrayBuffer object\"));\n\t\t\t/* fall through */\n\t\t}\n\t}\n\ttv = NULL;  /* No longer valid nor needed. */\n\n\th_this = duk__require_bufobj_this(thr);\n\n\t/* Slice offsets are element (not byte) offsets, which only matters\n\t * for TypedArray views, Node.js Buffer and ArrayBuffer have shift\n\t * zero so byte and element offsets are the same.  Negative indices\n\t * are counted from end of slice, crossed indices are allowed (and\n\t * result in zero length result), and final values are clamped\n\t * against the current slice.  There's intentionally no check\n\t * against the underlying buffer here.\n\t */\n\n\tduk__clamp_startend_negidx_shifted(thr,\n\t                                   (duk_int_t) h_this->length,\n\t                                   (duk_uint8_t) h_this->shift,\n\t                                   0 /*idx_start*/,\n\t                                   1 /*idx_end*/,\n\t                                   &start_offset,\n\t                                   &end_offset);\n\tDUK_ASSERT(end_offset >= start_offset);\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(end_offset >= 0);\n\tslice_length = (duk_uint_t) (end_offset - start_offset);\n\n\t/* The resulting buffer object gets the same class and prototype as\n\t * the buffer in 'this', e.g. if the input is a Uint8Array the\n\t * result is a Uint8Array; if the input is a Float32Array, the\n\t * result is a Float32Array.  The result internal prototype should\n\t * be the default prototype for the class (e.g. initial value of\n\t * Uint8Array.prototype), not copied from the argument (Duktape 1.x\n\t * did that).\n\t *\n\t * Node.js Buffers have special handling: they're Uint8Arrays as far\n\t * as the internal class is concerned, so the new Buffer should also\n\t * be an Uint8Array but inherit from Buffer.prototype.\n\t */\n\tres_class_num = DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *) h_this);\n\tDUK_ASSERT(res_class_num >= DUK_HOBJECT_CLASS_BUFOBJ_MIN);  /* type check guarantees */\n\tDUK_ASSERT(res_class_num <= DUK_HOBJECT_CLASS_BUFOBJ_MAX);\n\tres_proto_bidx = duk__buffer_proto_from_classnum[res_class_num - DUK_HOBJECT_CLASS_BUFOBJ_MIN];\n\tif (magic & 0x04) {\n\t\tres_proto_bidx = DUK_BIDX_NODEJS_BUFFER_PROTOTYPE;\n\t}\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(res_class_num),\n\t                               res_proto_bidx);\n\tDUK_ASSERT(h_bufobj != NULL);\n\n\tDUK_ASSERT(h_bufobj->length == 0);\n\th_bufobj->shift = h_this->shift;  /* inherit */\n\th_bufobj->elem_type = h_this->elem_type;  /* inherit */\n\th_bufobj->is_typedarray = magic & 0x01;\n\tDUK_ASSERT(h_bufobj->is_typedarray == 0 || h_bufobj->is_typedarray == 1);\n\n\th_val = h_this->buf;\n\tif (h_val == NULL) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tif (magic & 0x02) {\n\t\t/* non-zero: make copy */\n\t\tduk_uint8_t *p_copy;\n\t\tduk_size_t copy_length;\n\n\t\tp_copy = (duk_uint8_t *) duk_push_fixed_buffer_zero(thr, (duk_size_t) slice_length);  /* must be zeroed, not all bytes always copied */\n\t\tDUK_ASSERT(p_copy != NULL);\n\n\t\t/* Copy slice, respecting underlying buffer limits; remainder\n\t\t * is left as zero.\n\t\t */\n\t\tcopy_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, slice_length);\n\t\tduk_memcpy_unsafe((void *) p_copy,\n\t\t                  (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + start_offset),\n\t\t                  copy_length);\n\n\t\th_val = duk_known_hbuffer(thr, -1);\n\n\t\th_bufobj->buf = h_val;\n\t\tDUK_HBUFFER_INCREF(thr, h_val);\n\t\th_bufobj->length = slice_length;\n\t\tDUK_ASSERT(h_bufobj->offset == 0);\n\n\t\tduk_pop(thr);  /* reachable so pop OK */\n\t} else {\n\t\th_bufobj->buf = h_val;\n\t\tDUK_HBUFFER_INCREF(thr, h_val);\n\t\th_bufobj->length = slice_length;\n\t\th_bufobj->offset = h_this->offset + (duk_uint_t) start_offset;\n\n\t\t/* Copy the .buffer property, needed for TypedArray.prototype.subarray().\n\t\t *\n\t\t * XXX: limit copy only for TypedArray classes specifically?\n\t\t */\n\n\t\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\t\th_bufobj->buf_prop = h_this->buf_prop;  /* may be NULL */\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, (duk_hobject *) h_bufobj->buf_prop);\n\t}\n\t/* unbalanced stack on purpose */\n\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.isEncoding()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_encoding(duk_hthread *thr) {\n\tconst char *encoding;\n\n\t/* only accept lowercase 'utf8' now. */\n\n\tencoding = duk_to_string(thr, 0);\n\tDUK_ASSERT(duk_is_string(thr, 0));  /* guaranteed by duk_to_string() */\n\tduk_push_boolean(thr, DUK_STRCMP(encoding, \"utf8\") == 0);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.isBuffer()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_hthread *thr) {\n\tduk_hobject *h;\n\tduk_hobject *h_proto;\n\tduk_bool_t ret = 0;\n\n\tDUK_ASSERT(duk_get_top(thr) >= 1);  /* nargs */\n\th = duk_get_hobject(thr, 0);\n\tif (h != NULL) {\n\t\th_proto = thr->builtins[DUK_BIDX_NODEJS_BUFFER_PROTOTYPE];\n\t\tDUK_ASSERT(h_proto != NULL);\n\n\t\th = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t\tif (h != NULL) {\n\t\t\tret = duk_hobject_prototype_chain_contains(thr, h, h_proto, 0 /*ignore_loop*/);\n\t\t}\n\t}\n\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.byteLength()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_byte_length(duk_hthread *thr) {\n\tconst char *str;\n\tduk_size_t len;\n\n\t/* At the moment Buffer(<str>) will just use the string bytes as\n\t * is (ignoring encoding), so we return the string length here\n\t * unconditionally.\n\t */\n\n\t/* XXX: to be revised; Old Node.js behavior just coerces any buffer\n\t * values to string:\n\t * $ node\n\t * > Buffer.byteLength(new Uint32Array(10))\n\t * 20\n\t * > Buffer.byteLength(new Uint32Array(100))\n\t * 20\n\t * (The 20 comes from '[object Uint32Array]'.length\n\t */\n\n\tstr = duk_to_lstring(thr, 0, &len);\n\tDUK_UNREF(str);\n\tduk_push_size_t(thr, len);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.concat()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_hthread *thr) {\n\tduk_hobject *h_arg;\n\tduk_uint_t total_length;\n\tduk_hbufobj *h_bufobj;\n\tduk_hbufobj *h_bufres;\n\tduk_hbuffer *h_val;\n\tduk_uint_t i, n;\n\tduk_uint8_t *p;\n\tduk_size_t space_left;\n\tduk_size_t copy_size;\n\n\t/* Node.js accepts only actual Arrays. */\n\th_arg = duk_require_hobject(thr, 0);\n\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h_arg) != DUK_HOBJECT_CLASS_ARRAY) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* Compute result length and validate argument buffers. */\n\tn = (duk_uint_t) duk_get_length(thr, 0);\n\ttotal_length = 0;\n\tfor (i = 0; i < n; i++) {\n\t\t/* Neutered checks not necessary here: neutered buffers have\n\t\t * zero 'length' so we'll effectively skip them.\n\t\t */\n\t\tDUK_ASSERT_TOP(thr, 2);  /* [ array totalLength ] */\n\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);  /* -> [ array totalLength buf ] */\n\t\th_bufobj = duk__require_bufobj_value(thr, 2);\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\t\ttotal_length += h_bufobj->length;\n\t\tif (DUK_UNLIKELY(total_length < h_bufobj->length)) {\n\t\t\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);  /* Wrapped. */\n\t\t}\n\t\tduk_pop(thr);\n\t}\n\t/* In Node.js v0.12.1 a 1-element array is special and won't create a\n\t * copy, this was fixed later so an explicit check no longer needed.\n\t */\n\n\t/* User totalLength overrides a computed length, but we'll check\n\t * every copy in the copy loop.  Note that duk_to_int() can\n\t * technically have arbitrary side effects so we need to recheck\n\t * the buffers in the copy loop.\n\t */\n\tif (!duk_is_undefined(thr, 1) && n > 0) {\n\t\t/* For n == 0, Node.js ignores totalLength argument and\n\t\t * returns a zero length buffer.\n\t\t */\n\t\tduk_int_t total_length_signed;\n\t\ttotal_length_signed = duk_to_int(thr, 1);\n\t\tif (total_length_signed < 0) {\n\t\t\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n\t\t}\n\t\ttotal_length = (duk_uint_t) total_length_signed;\n\t}\n\n\th_bufres = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_UINT8ARRAY),\n\t                               DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_bufres != NULL);\n\n\tp = (duk_uint8_t *) duk_push_fixed_buffer_zero(thr, total_length);  /* must be zeroed, all bytes not necessarily written over */\n\tDUK_ASSERT(p != NULL);\n\tspace_left = (duk_size_t) total_length;\n\n\tfor (i = 0; i < n; i++) {\n\t\tDUK_ASSERT_TOP(thr, 4);  /* [ array totalLength bufres buf ] */\n\n\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);\n\t\th_bufobj = duk__require_bufobj_value(thr, 4);\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\n\t\tcopy_size = h_bufobj->length;\n\t\tif (copy_size > space_left) {\n\t\t\tcopy_size = space_left;\n\t\t}\n\n\t\tif (h_bufobj->buf != NULL &&\n\t\t    DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {\n\t\t\tduk_memcpy_unsafe((void *) p,\n\t\t\t                  (const void *) DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj),\n\t\t\t                  copy_size);\n\t\t} else {\n\t\t\t/* Just skip, leaving zeroes in the result. */\n\t\t\t;\n\t\t}\n\t\tp += copy_size;\n\t\tspace_left -= copy_size;\n\n\t\tduk_pop(thr);\n\t}\n\n\th_val = duk_known_hbuffer(thr, -1);\n\n\tduk__set_bufobj_buffer(thr, h_bufres, h_val);\n\th_bufres->is_typedarray = 1;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufres);\n\n\tduk_pop(thr);  /* pop plain buffer, now reachable through h_bufres */\n\n\treturn 1;  /* return h_bufres */\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Shared readfield and writefield methods\n *\n *  The readfield/writefield methods need support for endianness and field\n *  types.  All offsets are byte based so no offset shifting is needed.\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Format of magic, bits:\n *   0...1: field type; 0=uint8, 1=uint16, 2=uint32, 3=float, 4=double, 5=unused, 6=unused, 7=unused\n *       3: endianness: 0=little, 1=big\n *       4: signed: 1=yes, 0=no\n *       5: typedarray: 1=yes, 0=no\n */\n#define  DUK__FLD_8BIT         0\n#define  DUK__FLD_16BIT        1\n#define  DUK__FLD_32BIT        2\n#define  DUK__FLD_FLOAT        3\n#define  DUK__FLD_DOUBLE       4\n#define  DUK__FLD_VARINT       5\n#define  DUK__FLD_BIGENDIAN    (1 << 3)\n#define  DUK__FLD_SIGNED       (1 << 4)\n#define  DUK__FLD_TYPEDARRAY   (1 << 5)\n\n/* XXX: split into separate functions for each field type? */\nDUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_hthread *thr) {\n\tduk_small_int_t magic = (duk_small_int_t) duk_get_current_magic(thr);\n\tduk_small_int_t magic_ftype;\n\tduk_small_int_t magic_bigendian;\n\tduk_small_int_t magic_signed;\n\tduk_small_int_t magic_typedarray;\n\tduk_small_int_t endswap;\n\tduk_hbufobj *h_this;\n\tduk_bool_t no_assert;\n\tduk_int_t offset_signed;\n\tduk_uint_t offset;\n\tduk_uint_t buffer_length;\n\tduk_uint_t check_length;\n\tduk_uint8_t *buf;\n\tduk_double_union du;\n\n\tmagic_ftype = magic & 0x0007;\n\tmagic_bigendian = magic & 0x0008;\n\tmagic_signed = magic & 0x0010;\n\tmagic_typedarray = magic & 0x0020;\n\n\th_this = duk__require_bufobj_this(thr);  /* XXX: very inefficient for plain buffers */\n\tDUK_ASSERT(h_this != NULL);\n\tbuffer_length = h_this->length;\n\n\t/* [ offset noAssert                 ], when ftype != DUK__FLD_VARINT */\n\t/* [ offset fieldByteLength noAssert ], when ftype == DUK__FLD_VARINT */\n\t/* [ offset littleEndian             ], when DUK__FLD_TYPEDARRAY (regardless of ftype) */\n\n\t/* Handle TypedArray vs. Node.js Buffer arg differences */\n\tif (magic_typedarray) {\n\t\tno_assert = 0;\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = !duk_to_boolean(thr, 1);  /* 1=little endian */\n#else\n\t\tendswap = duk_to_boolean(thr, 1);  /* 1=little endian */\n#endif\n\t} else {\n\t\tno_assert = duk_to_boolean(thr, (magic_ftype == DUK__FLD_VARINT) ? 2 : 1);\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = magic_bigendian;\n#else\n\t\tendswap = !magic_bigendian;\n#endif\n\t}\n\n\t/* Offset is coerced first to signed integer range and then to unsigned.\n\t * This ensures we can add a small byte length (1-8) to the offset in\n\t * bound checks and not wrap.\n\t */\n\toffset_signed = duk_to_int(thr, 0);\n\toffset = (duk_uint_t) offset_signed;\n\tif (offset_signed < 0) {\n\t\tgoto fail_bounds;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"readfield, buffer_length=%ld, offset=%ld, no_assert=%d, \"\n\t                     \"magic=%04x, magic_fieldtype=%d, magic_bigendian=%d, magic_signed=%d, \"\n\t                     \"endswap=%d\",\n\t                     (long) buffer_length, (long) offset, (int) no_assert,\n\t                     (unsigned int) magic, (int) magic_ftype, (int) (magic_bigendian >> 3),\n\t                     (int) (magic_signed >> 4), (int) endswap));\n\n\t/* Update 'buffer_length' to be the effective, safe limit which\n\t * takes into account the underlying buffer.  This value will be\n\t * potentially invalidated by any side effect.\n\t */\n\tcheck_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, buffer_length);\n\tDUK_DDD(DUK_DDDPRINT(\"buffer_length=%ld, check_length=%ld\",\n\t                     (long) buffer_length, (long) check_length));\n\n\tif (h_this->buf) {\n\t\tbuf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this);\n\t} else {\n\t\t/* Neutered.  We could go into the switch-case safely with\n\t\t * buf == NULL because check_length == 0.  To avoid scanbuild\n\t\t * warnings, fail directly instead.\n\t\t */\n\t\tDUK_ASSERT(check_length == 0);\n\t\tgoto fail_neutered;\n\t}\n\tDUK_ASSERT(buf != NULL);\n\n\tswitch (magic_ftype) {\n\tcase DUK__FLD_8BIT: {\n\t\tduk_uint8_t tmp;\n\t\tif (offset + 1U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\ttmp = buf[offset];\n\t\tif (magic_signed) {\n\t\t\tduk_push_int(thr, (duk_int_t) ((duk_int8_t) tmp));\n\t\t} else {\n\t\t\tduk_push_uint(thr, (duk_uint_t) tmp);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK__FLD_16BIT: {\n\t\tduk_uint16_t tmp;\n\t\tif (offset + 2U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 2);\n\t\ttmp = du.us[0];\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP16(tmp);\n\t\t}\n\t\tif (magic_signed) {\n\t\t\tduk_push_int(thr, (duk_int_t) ((duk_int16_t) tmp));\n\t\t} else {\n\t\t\tduk_push_uint(thr, (duk_uint_t) tmp);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK__FLD_32BIT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 4);\n\t\ttmp = du.ui[0];\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t}\n\t\tif (magic_signed) {\n\t\t\tduk_push_int(thr, (duk_int_t) ((duk_int32_t) tmp));\n\t\t} else {\n\t\t\tduk_push_uint(thr, (duk_uint_t) tmp);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK__FLD_FLOAT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 4);\n\t\tif (endswap) {\n\t\t\ttmp = du.ui[0];\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t\tdu.ui[0] = tmp;\n\t\t}\n\t\tduk_push_number(thr, (duk_double_t) du.f[0]);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_DOUBLE: {\n\t\tif (offset + 8U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 8);\n\t\tif (endswap) {\n\t\t\tDUK_DBLUNION_BSWAP64(&du);\n\t\t}\n\t\tduk_push_number(thr, (duk_double_t) du.d);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_VARINT: {\n\t\t/* Node.js Buffer variable width integer field.  We don't really\n\t\t * care about speed here, so aim for shortest algorithm.\n\t\t */\n\t\tduk_int_t field_bytelen;\n\t\tduk_int_t i, i_step, i_end;\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_int64_t tmp;\n\t\tduk_small_uint_t shift_tmp;\n#else\n\t\tduk_double_t tmp;\n\t\tduk_small_int_t highbyte;\n#endif\n\t\tconst duk_uint8_t *p;\n\n\t\tfield_bytelen = duk_get_int(thr, 1);  /* avoid side effects! */\n\t\tif (field_bytelen < 1 || field_bytelen > 6) {\n\t\t\tgoto fail_field_length;\n\t\t}\n\t\tif (offset + (duk_uint_t) field_bytelen > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tp = (const duk_uint8_t *) (buf + offset);\n\n\t\t/* Slow gathering of value using either 64-bit arithmetic\n\t\t * or IEEE doubles if 64-bit types not available.  Handling\n\t\t * of negative numbers is a bit non-obvious in both cases.\n\t\t */\n\n\t\tif (magic_bigendian) {\n\t\t\t/* Gather in big endian */\n\t\t\ti = 0;\n\t\t\ti_step = 1;\n\t\t\ti_end = field_bytelen;  /* one i_step over */\n\t\t} else {\n\t\t\t/* Gather in little endian */\n\t\t\ti = field_bytelen - 1;\n\t\t\ti_step = -1;\n\t\t\ti_end = -1;  /* one i_step over */\n\t\t}\n\n#if defined(DUK_USE_64BIT_OPS)\n\t\ttmp = 0;\n\t\tdo {\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\ttmp = (tmp << 8) + (duk_int64_t) p[i];\n\t\t\ti += i_step;\n\t\t} while (i != i_end);\n\n\t\tif (magic_signed) {\n\t\t\t/* Shift to sign extend.  Left shift must be unsigned\n\t\t\t * to avoid undefined behavior; right shift must be\n\t\t\t * signed to sign extend properly.\n\t\t\t */\n\t\t\tshift_tmp = (duk_small_uint_t) (64U - (duk_small_uint_t) field_bytelen * 8U);\n\t\t\ttmp = (duk_int64_t) ((duk_uint64_t) tmp << shift_tmp) >> shift_tmp;\n\t\t}\n\n\t\tduk_push_i64(thr, tmp);\n#else\n\t\thighbyte = p[i];\n\t\tif (magic_signed && (highbyte & 0x80) != 0) {\n\t\t\t/* 0xff => 255 - 256 = -1; 0x80 => 128 - 256 = -128 */\n\t\t\ttmp = (duk_double_t) (highbyte - 256);\n\t\t} else {\n\t\t\ttmp = (duk_double_t) highbyte;\n\t\t}\n\t\tfor (;;) {\n\t\t\ti += i_step;\n\t\t\tif (i == i_end) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\ttmp = (tmp * 256.0) + (duk_double_t) p[i];\n\t\t}\n\n\t\tduk_push_number(thr, tmp);\n#endif\n\t\tbreak;\n\t}\n\tdefault: {  /* should never happen but default here */\n\t\tgoto fail_bounds;\n\t}\n\t}\n\n\treturn 1;\n\n fail_neutered:\n fail_field_length:\n fail_bounds:\n\tif (no_assert) {\n\t\t/* Node.js return value for noAssert out-of-bounds reads is\n\t\t * usually (but not always) NaN.  Return NaN consistently.\n\t\t */\n\t\tduk_push_nan(thr);\n\t\treturn 1;\n\t}\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* XXX: split into separate functions for each field type? */\nDUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_hthread *thr) {\n\tduk_small_int_t magic = (duk_small_int_t) duk_get_current_magic(thr);\n\tduk_small_int_t magic_ftype;\n\tduk_small_int_t magic_bigendian;\n\tduk_small_int_t magic_signed;\n\tduk_small_int_t magic_typedarray;\n\tduk_small_int_t endswap;\n\tduk_hbufobj *h_this;\n\tduk_bool_t no_assert;\n\tduk_int_t offset_signed;\n\tduk_uint_t offset;\n\tduk_uint_t buffer_length;\n\tduk_uint_t check_length;\n\tduk_uint8_t *buf;\n\tduk_double_union du;\n\tduk_int_t nbytes = 0;\n\n\tmagic_ftype = magic & 0x0007;\n\tmagic_bigendian = magic & 0x0008;\n\tmagic_signed = magic & 0x0010;\n\tmagic_typedarray = magic & 0x0020;\n\tDUK_UNREF(magic_signed);\n\n\th_this = duk__require_bufobj_this(thr);  /* XXX: very inefficient for plain buffers */\n\tDUK_ASSERT(h_this != NULL);\n\tbuffer_length = h_this->length;\n\n\t/* [ value  offset noAssert                 ], when ftype != DUK__FLD_VARINT */\n\t/* [ value  offset fieldByteLength noAssert ], when ftype == DUK__FLD_VARINT */\n\t/* [ offset value  littleEndian             ], when DUK__FLD_TYPEDARRAY (regardless of ftype) */\n\n\t/* Handle TypedArray vs. Node.js Buffer arg differences */\n\tif (magic_typedarray) {\n\t\tno_assert = 0;\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = !duk_to_boolean(thr, 2);  /* 1=little endian */\n#else\n\t\tendswap = duk_to_boolean(thr, 2);  /* 1=little endian */\n#endif\n\t\tduk_swap(thr, 0, 1);  /* offset/value order different from Node.js */\n\t} else {\n\t\tno_assert = duk_to_boolean(thr, (magic_ftype == DUK__FLD_VARINT) ? 3 : 2);\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = magic_bigendian;\n#else\n\t\tendswap = !magic_bigendian;\n#endif\n\t}\n\n\t/* Offset is coerced first to signed integer range and then to unsigned.\n\t * This ensures we can add a small byte length (1-8) to the offset in\n\t * bound checks and not wrap.\n\t */\n\toffset_signed = duk_to_int(thr, 1);\n\toffset = (duk_uint_t) offset_signed;\n\n\t/* We need 'nbytes' even for a failed offset; return value must be\n\t * (offset + nbytes) even when write fails due to invalid offset.\n\t */\n\tif (magic_ftype != DUK__FLD_VARINT) {\n\t\tDUK_ASSERT(magic_ftype >= 0 && magic_ftype < (duk_small_int_t) (sizeof(duk__buffer_nbytes_from_fldtype) / sizeof(duk_uint8_t)));\n\t\tnbytes = duk__buffer_nbytes_from_fldtype[magic_ftype];\n\t} else {\n\t\tnbytes = duk_get_int(thr, 2);\n\t\tif (nbytes < 1 || nbytes > 6) {\n\t\t\tgoto fail_field_length;\n\t\t}\n\t}\n\tDUK_ASSERT(nbytes >= 1 && nbytes <= 8);\n\n\t/* Now we can check offset validity. */\n\tif (offset_signed < 0) {\n\t\tgoto fail_bounds;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"writefield, value=%!T, buffer_length=%ld, offset=%ld, no_assert=%d, \"\n\t                     \"magic=%04x, magic_fieldtype=%d, magic_bigendian=%d, magic_signed=%d, \"\n\t                     \"endswap=%d\",\n\t                     duk_get_tval(thr, 0), (long) buffer_length, (long) offset, (int) no_assert,\n\t                     (unsigned int) magic, (int) magic_ftype, (int) (magic_bigendian >> 3),\n\t                     (int) (magic_signed >> 4), (int) endswap));\n\n\t/* Coerce value to a number before computing check_length, so that\n\t * the field type specific coercion below can't have side effects\n\t * that would invalidate check_length.\n\t */\n\tduk_to_number(thr, 0);\n\n\t/* Update 'buffer_length' to be the effective, safe limit which\n\t * takes into account the underlying buffer.  This value will be\n\t * potentially invalidated by any side effect.\n\t */\n\tcheck_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, buffer_length);\n\tDUK_DDD(DUK_DDDPRINT(\"buffer_length=%ld, check_length=%ld\",\n\t                     (long) buffer_length, (long) check_length));\n\n\tif (h_this->buf) {\n\t\tbuf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this);\n\t} else {\n\t\t/* Neutered.  We could go into the switch-case safely with\n\t\t * buf == NULL because check_length == 0.  To avoid scanbuild\n\t\t * warnings, fail directly instead.\n\t\t */\n\t\tDUK_ASSERT(check_length == 0);\n\t\tgoto fail_neutered;\n\t}\n\tDUK_ASSERT(buf != NULL);\n\n\tswitch (magic_ftype) {\n\tcase DUK__FLD_8BIT: {\n\t\tif (offset + 1U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\t/* sign doesn't matter when writing */\n\t\tbuf[offset] = (duk_uint8_t) duk_to_uint32(thr, 0);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_16BIT: {\n\t\tduk_uint16_t tmp;\n\t\tif (offset + 2U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\ttmp = (duk_uint16_t) duk_to_uint32(thr, 0);\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP16(tmp);\n\t\t}\n\t\tdu.us[0] = tmp;\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 2);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_32BIT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\ttmp = (duk_uint32_t) duk_to_uint32(thr, 0);\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t}\n\t\tdu.ui[0] = tmp;\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 4);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_FLOAT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tdu.f[0] = (duk_float_t) duk_to_number(thr, 0);\n\t\tif (endswap) {\n\t\t\ttmp = du.ui[0];\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t\tdu.ui[0] = tmp;\n\t\t}\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 4);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_DOUBLE: {\n\t\tif (offset + 8U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tdu.d = (duk_double_t) duk_to_number(thr, 0);\n\t\tif (endswap) {\n\t\t\tDUK_DBLUNION_BSWAP64(&du);\n\t\t}\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 8);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_VARINT: {\n\t\t/* Node.js Buffer variable width integer field.  We don't really\n\t\t * care about speed here, so aim for shortest algorithm.\n\t\t */\n\t\tduk_int_t field_bytelen;\n\t\tduk_int_t i, i_step, i_end;\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_int64_t tmp;\n#else\n\t\tduk_double_t tmp;\n#endif\n\t\tduk_uint8_t *p;\n\n\t\tfield_bytelen = (duk_int_t) nbytes;\n\t\tif (offset + (duk_uint_t) field_bytelen > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\n\t\t/* Slow writing of value using either 64-bit arithmetic\n\t\t * or IEEE doubles if 64-bit types not available.  There's\n\t\t * no special sign handling when writing varints.\n\t\t */\n\n\t\tif (magic_bigendian) {\n\t\t\t/* Write in big endian */\n\t\t\ti = field_bytelen;  /* one i_step added at top of loop */\n\t\t\ti_step = -1;\n\t\t\ti_end = 0;\n\t\t} else {\n\t\t\t/* Write in little endian */\n\t\t\ti = -1;  /* one i_step added at top of loop */\n\t\t\ti_step = 1;\n\t\t\ti_end = field_bytelen - 1;\n\t\t}\n\n\t\t/* XXX: The duk_to_number() cast followed by integer coercion\n\t\t * is platform specific so NaN, +/- Infinity, and out-of-bounds\n\t\t * values result in platform specific output now.\n\t\t * See: test-bi-nodejs-buffer-proto-varint-special.js\n\t\t */\n\n#if defined(DUK_USE_64BIT_OPS)\n\t\ttmp = (duk_int64_t) duk_to_number(thr, 0);\n\t\tp = (duk_uint8_t *) (buf + offset);\n\t\tdo {\n\t\t\ti += i_step;\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\tp[i] = (duk_uint8_t) (tmp & 0xff);\n\t\t\ttmp = tmp >> 8;  /* unnecessary shift for last byte */\n\t\t} while (i != i_end);\n#else\n\t\ttmp = duk_to_number(thr, 0);\n\t\tp = (duk_uint8_t *) (buf + offset);\n\t\tdo {\n\t\t\ti += i_step;\n\t\t\ttmp = DUK_FLOOR(tmp);\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\tp[i] = (duk_uint8_t) (DUK_FMOD(tmp, 256.0));\n\t\t\ttmp = tmp / 256.0;  /* unnecessary div for last byte */\n\t\t} while (i != i_end);\n#endif\n\t\tbreak;\n\t}\n\tdefault: {  /* should never happen but default here */\n\t\tgoto fail_bounds;\n\t}\n\t}\n\n\t/* Node.js Buffer: return offset + #bytes written (i.e. next\n\t * write offset).\n\t */\n\tif (magic_typedarray) {\n\t\t/* For TypedArrays 'undefined' return value is specified\n\t\t * by ES2015 (matches V8).\n\t\t */\n\t\treturn 0;\n\t}\n\tduk_push_uint(thr, offset + (duk_uint_t) nbytes);\n\treturn 1;\n\n fail_neutered:\n fail_field_length:\n fail_bounds:\n\tif (no_assert) {\n\t\t/* Node.js return value for failed writes is offset + #bytes\n\t\t * that would have been written.\n\t\t */\n\t\t/* XXX: for negative input offsets, 'offset' will be a large\n\t\t * positive value so the result here is confusing.\n\t\t */\n\t\tif (magic_typedarray) {\n\t\t\treturn 0;\n\t\t}\n\t\tduk_push_uint(thr, offset + (duk_uint_t) nbytes);\n\t\treturn 1;\n\t}\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Accessors for .buffer, .byteLength, .byteOffset\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL duk_hbufobj *duk__autospawn_arraybuffer(duk_hthread *thr, duk_hbuffer *h_buf) {\n\tduk_hbufobj *h_res;\n\n\th_res = duk_push_bufobj_raw(thr,\n\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                            DUK_HOBJECT_FLAG_BUFOBJ |\n\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),\n\t                            DUK_BIDX_ARRAYBUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_res != NULL);\n\tDUK_UNREF(h_res);\n\n\tduk__set_bufobj_buffer(thr, h_res, h_buf);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_res);\n\tDUK_ASSERT(h_res->buf_prop == NULL);\n\treturn h_res;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n\th_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW /*flags*/);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tif (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *) h_bufobj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"autospawn ArrayBuffer for plain buffer\"));\n\t\t(void) duk__autospawn_arraybuffer(thr, (duk_hbuffer *) h_bufobj);\n\t\treturn 1;\n\t} else {\n\t\tif (h_bufobj->buf_prop == NULL &&\n\t\t    DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *) h_bufobj) != DUK_HOBJECT_CLASS_ARRAYBUFFER &&\n\t\t    h_bufobj->buf != NULL) {\n\t\t\tduk_hbufobj *h_arrbuf;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"autospawn ArrayBuffer for typed array or DataView\"));\n\t\t\th_arrbuf = duk__autospawn_arraybuffer(thr, h_bufobj->buf);\n\n\t\t\tif (h_bufobj->buf_prop == NULL) {\n\t\t\t\t/* Must recheck buf_prop, in case ArrayBuffer\n\t\t\t\t * alloc had a side effect which already filled\n\t\t\t\t * it!\n\t\t\t\t */\n\n\t\t\t\t/* Set ArrayBuffer's .byteOffset and .byteLength based\n\t\t\t\t * on the view so that Arraybuffer[view.byteOffset]\n\t\t\t\t * matches view[0].\n\t\t\t\t */\n\t\t\t\th_arrbuf->offset = 0;\n\t\t\t\tDUK_ASSERT(h_bufobj->offset + h_bufobj->length >= h_bufobj->offset);  /* Wrap check on creation. */\n\t\t\t\th_arrbuf->length = h_bufobj->offset + h_bufobj->length;\n\t\t\t\tDUK_ASSERT(h_arrbuf->buf_prop == NULL);\n\n\t\t\t\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\t\t\t\th_bufobj->buf_prop = (duk_hobject *) h_arrbuf;\n\t\t\t\tDUK_HBUFOBJ_INCREF(thr, h_arrbuf);  /* Now reachable and accounted for. */\n\t\t\t}\n\n\t\t\t/* Left on stack; pushed for the second time below (OK). */\n\t\t}\n\t\tif (h_bufobj->buf_prop) {\n\t\t\tduk_push_hobject(thr, h_bufobj->buf_prop);\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n\th_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW /*flags*/);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tif (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *) h_bufobj)) {\n\t\tduk_push_uint(thr, 0);\n\t} else {\n\t\t/* If neutered must return 0; offset is zeroed during\n\t\t * neutering.\n\t\t */\n\t\tduk_push_uint(thr, h_bufobj->offset);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n\th_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW /*flags*/);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tif (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *) h_bufobj)) {\n\t\tduk_hbuffer *h_buf;\n\n\t\th_buf = (duk_hbuffer *) h_bufobj;\n\t\tDUK_ASSERT(DUK_HBUFFER_GET_SIZE(h_buf) <= DUK_UINT_MAX);  /* Buffer limits. */\n\t\tduk_push_uint(thr, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_buf));\n\t} else {\n\t\t/* If neutered must return 0; length is zeroed during\n\t\t * neutering.\n\t\t */\n\t\tduk_push_uint(thr, h_bufobj->length);\n\t}\n\treturn 1;\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n/* No .buffer getter without ArrayBuffer support. */\n#if 0\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_hthread *thr) {\n\treturn 0;\n}\n#endif\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_hthread *thr) {\n\tduk_push_uint(thr, 0);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_hthread *thr) {\n\tduk_hbuffer *h_buf;\n\n\t/* XXX: helper? */\n\tduk_push_this(thr);\n\th_buf = duk_require_hbuffer(thr, -1);\n\tduk_push_uint(thr, DUK_HBUFFER_GET_SIZE(h_buf));\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* automatic undefs */\n#undef DUK__BUFOBJ_FLAG_PROMOTE\n#undef DUK__BUFOBJ_FLAG_THROW\n#undef DUK__FLD_16BIT\n#undef DUK__FLD_32BIT\n#undef DUK__FLD_8BIT\n#undef DUK__FLD_BIGENDIAN\n#undef DUK__FLD_DOUBLE\n#undef DUK__FLD_FLOAT\n#undef DUK__FLD_SIGNED\n#undef DUK__FLD_TYPEDARRAY\n#undef DUK__FLD_VARINT\n#line 1 \"duk_bi_date.c\"\n/*\n *  Date built-ins\n *\n *  Unlike most built-ins, Date has some platform dependencies for getting\n *  UTC time, converting between UTC and local time, and parsing and\n *  formatting time values.  These are all abstracted behind DUK_USE_xxx\n *  config options.  There are built-in platform specific providers for\n *  POSIX and Windows, but external providers can also be used.\n *\n *  See doc/datetime.rst.\n *\n */\n\n/* #include duk_internal.h -> already included */\n\n/* XXX: currently defines unnecessary symbols when DUK_USE_DATE_BUILTIN is disabled. */\n\n/*\n *  Forward declarations\n */\n\nDUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval_tzoffset(duk_hthread *thr, duk_small_uint_t flags, duk_int_t *out_tzoffset);\nDUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval(duk_hthread *thr, duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__twodigit_year_fixup(duk_hthread *thr, duk_idx_t idx_val);\nDUK_LOCAL_DECL duk_ret_t duk__set_this_timeval_from_dparts(duk_hthread *thr, duk_double_t *dparts, duk_small_uint_t flags);\n\n/*\n *  Other file level defines\n */\n\n/* Debug macro to print all parts and dparts (used manually because of debug level). */\n#define  DUK__DPRINT_PARTS_AND_DPARTS(parts,dparts)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"parts: %ld %ld %ld %ld %ld %ld %ld %ld, dparts: %lf %lf %lf %lf %lf %lf %lf %lf\", \\\n\t\t                 (long) (parts)[0], (long) (parts)[1], \\\n\t\t                 (long) (parts)[2], (long) (parts)[3], \\\n\t\t                 (long) (parts)[4], (long) (parts)[5], \\\n\t\t                 (long) (parts)[6], (long) (parts)[7], \\\n\t\t                 (double) (dparts)[0], (double) (dparts)[1], \\\n\t\t                 (double) (dparts)[2], (double) (dparts)[3], \\\n\t\t                 (double) (dparts)[4], (double) (dparts)[5], \\\n\t\t                 (double) (dparts)[6], (double) (dparts)[7])); \\\n\t} while (0)\n#define  DUK__DPRINT_PARTS(parts)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"parts: %ld %ld %ld %ld %ld %ld %ld %ld\", \\\n\t\t                 (long) (parts)[0], (long) (parts)[1], \\\n\t\t                 (long) (parts)[2], (long) (parts)[3], \\\n\t\t                 (long) (parts)[4], (long) (parts)[5], \\\n\t\t                 (long) (parts)[6], (long) (parts)[7])); \\\n\t} while (0)\n#define  DUK__DPRINT_DPARTS(dparts)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"dparts: %lf %lf %lf %lf %lf %lf %lf %lf\", \\\n\t\t                 (double) (dparts)[0], (double) (dparts)[1], \\\n\t\t                 (double) (dparts)[2], (double) (dparts)[3], \\\n\t\t                 (double) (dparts)[4], (double) (dparts)[5], \\\n\t\t                 (double) (dparts)[6], (double) (dparts)[7])); \\\n\t} while (0)\n\n/* Equivalent year for DST calculations outside [1970,2038[ range, see\n * E5 Section 15.9.1.8.  Equivalent year has the same leap-year-ness and\n * starts with the same weekday on Jan 1.\n * https://bugzilla.mozilla.org/show_bug.cgi?id=351066\n */\n#define DUK__YEAR(x) ((duk_uint8_t) ((x) - 1970))\nDUK_LOCAL duk_uint8_t duk__date_equivyear[14] = {\n#if 1\n\t/* This is based on V8 EquivalentYear() algorithm (see util/genequivyear.py):\n\t * http://code.google.com/p/v8/source/browse/trunk/src/date.h#146\n\t */\n\n\t/* non-leap year: sunday, monday, ... */\n\tDUK__YEAR(2023), DUK__YEAR(2035), DUK__YEAR(2019), DUK__YEAR(2031),\n\tDUK__YEAR(2015), DUK__YEAR(2027), DUK__YEAR(2011),\n\n\t/* leap year: sunday, monday, ... */\n\tDUK__YEAR(2012), DUK__YEAR(2024), DUK__YEAR(2008), DUK__YEAR(2020),\n\tDUK__YEAR(2032), DUK__YEAR(2016), DUK__YEAR(2028)\n#endif\n\n#if 0\n\t/* This is based on Rhino EquivalentYear() algorithm:\n\t * https://github.com/mozilla/rhino/blob/f99cc11d616f0cdda2c42bde72b3484df6182947/src/org/mozilla/javascript/NativeDate.java\n\t */\n\n\t/* non-leap year: sunday, monday, ... */\n\tDUK__YEAR(1978), DUK__YEAR(1973), DUK__YEAR(1985), DUK__YEAR(1986),\n\tDUK__YEAR(1981), DUK__YEAR(1971), DUK__YEAR(1977),\n\n\t/* leap year: sunday, monday, ... */\n\tDUK__YEAR(1984), DUK__YEAR(1996), DUK__YEAR(1980), DUK__YEAR(1992),\n\tDUK__YEAR(1976), DUK__YEAR(1988), DUK__YEAR(1972)\n#endif\n};\n\n/*\n *  ISO 8601 subset parser.\n */\n\n/* Parser part count. */\n#define DUK__NUM_ISO8601_PARSER_PARTS  9\n\n/* Parser part indices. */\n#define DUK__PI_YEAR         0\n#define DUK__PI_MONTH        1\n#define DUK__PI_DAY          2\n#define DUK__PI_HOUR         3\n#define DUK__PI_MINUTE       4\n#define DUK__PI_SECOND       5\n#define DUK__PI_MILLISECOND  6\n#define DUK__PI_TZHOUR       7\n#define DUK__PI_TZMINUTE     8\n\n/* Parser part masks. */\n#define DUK__PM_YEAR         (1 << DUK__PI_YEAR)\n#define DUK__PM_MONTH        (1 << DUK__PI_MONTH)\n#define DUK__PM_DAY          (1 << DUK__PI_DAY)\n#define DUK__PM_HOUR         (1 << DUK__PI_HOUR)\n#define DUK__PM_MINUTE       (1 << DUK__PI_MINUTE)\n#define DUK__PM_SECOND       (1 << DUK__PI_SECOND)\n#define DUK__PM_MILLISECOND  (1 << DUK__PI_MILLISECOND)\n#define DUK__PM_TZHOUR       (1 << DUK__PI_TZHOUR)\n#define DUK__PM_TZMINUTE     (1 << DUK__PI_TZMINUTE)\n\n/* Parser separator indices. */\n#define DUK__SI_PLUS         0\n#define DUK__SI_MINUS        1\n#define DUK__SI_T            2\n#define DUK__SI_SPACE        3\n#define DUK__SI_COLON        4\n#define DUK__SI_PERIOD       5\n#define DUK__SI_Z            6\n#define DUK__SI_NUL          7\n\n/* Parser separator masks. */\n#define DUK__SM_PLUS         (1 << DUK__SI_PLUS)\n#define DUK__SM_MINUS        (1 << DUK__SI_MINUS)\n#define DUK__SM_T            (1 << DUK__SI_T)\n#define DUK__SM_SPACE        (1 << DUK__SI_SPACE)\n#define DUK__SM_COLON        (1 << DUK__SI_COLON)\n#define DUK__SM_PERIOD       (1 << DUK__SI_PERIOD)\n#define DUK__SM_Z            (1 << DUK__SI_Z)\n#define DUK__SM_NUL          (1 << DUK__SI_NUL)\n\n/* Rule control flags. */\n#define DUK__CF_NEG          (1 << 0)  /* continue matching, set neg_tzoffset flag */\n#define DUK__CF_ACCEPT       (1 << 1)  /* accept string */\n#define DUK__CF_ACCEPT_NUL   (1 << 2)  /* accept string if next char is NUL (otherwise reject) */\n\n#define DUK__PACK_RULE(partmask,sepmask,nextpart,flags)  \\\n\t((duk_uint32_t) (partmask) + \\\n\t (((duk_uint32_t) (sepmask)) << 9) + \\\n\t (((duk_uint32_t) (nextpart)) << 17) + \\\n\t (((duk_uint32_t) (flags)) << 21))\n\n#define DUK__UNPACK_RULE(rule,var_nextidx,var_flags)  do { \\\n\t\t(var_nextidx) = (duk_small_uint_t) (((rule) >> 17) & 0x0f); \\\n\t\t(var_flags) = (duk_small_uint_t) ((rule) >> 21); \\\n\t} while (0)\n\n#define DUK__RULE_MASK_PART_SEP  0x1ffffUL\n\n/* Matching separator index is used in the control table */\nDUK_LOCAL const duk_uint8_t duk__parse_iso8601_seps[] = {\n\tDUK_ASC_PLUS /*0*/, DUK_ASC_MINUS /*1*/, DUK_ASC_UC_T /*2*/, DUK_ASC_SPACE /*3*/,\n\tDUK_ASC_COLON /*4*/, DUK_ASC_PERIOD /*5*/, DUK_ASC_UC_Z /*6*/, DUK_ASC_NUL /*7*/\n};\n\n/* Rule table: first matching rule is used to determine what to do next. */\nDUK_LOCAL const duk_uint32_t duk__parse_iso8601_control[] = {\n\tDUK__PACK_RULE(DUK__PM_YEAR, DUK__SM_MINUS, DUK__PI_MONTH, 0),\n\tDUK__PACK_RULE(DUK__PM_MONTH, DUK__SM_MINUS, DUK__PI_DAY, 0),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY, DUK__SM_T | DUK__SM_SPACE, DUK__PI_HOUR, 0),\n\tDUK__PACK_RULE(DUK__PM_HOUR, DUK__SM_COLON, DUK__PI_MINUTE, 0),\n\tDUK__PACK_RULE(DUK__PM_MINUTE, DUK__SM_COLON, DUK__PI_SECOND, 0),\n\tDUK__PACK_RULE(DUK__PM_SECOND, DUK__SM_PERIOD, DUK__PI_MILLISECOND, 0),\n\tDUK__PACK_RULE(DUK__PM_TZHOUR, DUK__SM_COLON, DUK__PI_TZMINUTE, 0),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_PLUS, DUK__PI_TZHOUR, 0),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_MINUS, DUK__PI_TZHOUR, DUK__CF_NEG),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_Z, 0, DUK__CF_ACCEPT_NUL),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND | DUK__PM_TZHOUR /*Note2*/ | DUK__PM_TZMINUTE, DUK__SM_NUL, 0, DUK__CF_ACCEPT)\n\n\t/* Note1: the specification doesn't require matching a time form with\n\t *        just hours (\"HH\"), but we accept it here, e.g. \"2012-01-02T12Z\".\n\t *\n\t * Note2: the specification doesn't require matching a timezone offset\n\t *        with just hours (\"HH\"), but accept it here, e.g. \"2012-01-02T03:04:05+02\"\n\t */\n};\n\nDUK_LOCAL duk_bool_t duk__parse_string_iso8601_subset(duk_hthread *thr, const char *str) {\n\tduk_int_t parts[DUK__NUM_ISO8601_PARSER_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t d;\n\tconst duk_uint8_t *p;\n\tduk_small_uint_t part_idx = 0;\n\tduk_int_t accum = 0;\n\tduk_small_uint_t ndigits = 0;\n\tduk_bool_t neg_year = 0;\n\tduk_bool_t neg_tzoffset = 0;\n\tduk_uint_fast8_t ch;\n\tduk_small_uint_t i;\n\n\t/* During parsing, month and day are one-based; set defaults here. */\n\tduk_memzero(parts, sizeof(parts));\n\tDUK_ASSERT(parts[DUK_DATE_IDX_YEAR] == 0);  /* don't care value, year is mandatory */\n\tparts[DUK_DATE_IDX_MONTH] = 1;\n\tparts[DUK_DATE_IDX_DAY] = 1;\n\n\t/* Special handling for year sign. */\n\tp = (const duk_uint8_t *) str;\n\tch = p[0];\n\tif (ch == DUK_ASC_PLUS) {\n\t\tp++;\n\t} else if (ch == DUK_ASC_MINUS) {\n\t\tneg_year = 1;\n\t\tp++;\n\t}\n\n\tfor (;;) {\n\t\tch = *p++;\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsing, part_idx=%ld, char=%ld ('%c')\",\n\t\t                     (long) part_idx, (long) ch,\n\t\t                     (int) ((ch >= 0x20 && ch <= 0x7e) ? ch : DUK_ASC_QUESTION)));\n\n\t\tif (ch >= DUK_ASC_0 && ch <= DUK_ASC_9) {\n\t\t\tif (ndigits >= 9) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"too many digits -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tif (part_idx == DUK__PI_MILLISECOND && ndigits >= 3) {\n\t\t\t\t/* ignore millisecond fractions after 3 */\n\t\t\t} else {\n\t\t\t\taccum = accum * 10 + ((duk_int_t) ch) - ((duk_int_t) DUK_ASC_0) + 0x00;\n\t\t\t\tndigits++;\n\t\t\t}\n\t\t} else {\n\t\t\tduk_uint_fast32_t match_val;\n\t\t\tduk_small_uint_t sep_idx;\n\n\t\t\tif (ndigits <= 0) {\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tif (part_idx == DUK__PI_MILLISECOND) {\n\t\t\t\t/* complete the millisecond field */\n\t\t\t\twhile (ndigits < 3) {\n\t\t\t\t\taccum *= 10;\n\t\t\t\t\tndigits++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tparts[part_idx] = accum;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"wrote part %ld -> value %ld\", (long) part_idx, (long) accum));\n\n\t\t\taccum = 0;\n\t\t\tndigits = 0;\n\n\t\t\tfor (i = 0; i < (duk_small_uint_t) (sizeof(duk__parse_iso8601_seps) / sizeof(duk_uint8_t)); i++) {\n\t\t\t\tif (duk__parse_iso8601_seps[i] == ch) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (i == (duk_small_uint_t) (sizeof(duk__parse_iso8601_seps) / sizeof(duk_uint8_t))) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"separator character doesn't match -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\n\t\t\tsep_idx = i;\n\t\t\tmatch_val = (1UL << part_idx) + (1UL << (sep_idx + 9));  /* match against rule part/sep bits */\n\n\t\t\tfor (i = 0; i < (duk_small_uint_t) (sizeof(duk__parse_iso8601_control) / sizeof(duk_uint32_t)); i++) {\n\t\t\t\tduk_uint_fast32_t rule = duk__parse_iso8601_control[i];\n\t\t\t\tduk_small_uint_t nextpart;\n\t\t\t\tduk_small_uint_t cflags;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"part_idx=%ld, sep_idx=%ld, match_val=0x%08lx, considering rule=0x%08lx\",\n\t\t\t\t                     (long) part_idx, (long) sep_idx,\n\t\t\t\t                     (unsigned long) match_val, (unsigned long) rule));\n\n\t\t\t\tif ((rule & match_val) != match_val) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tDUK__UNPACK_RULE(rule, nextpart, cflags);\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rule match -> part_idx=%ld, sep_idx=%ld, match_val=0x%08lx, \"\n\t\t\t\t                     \"rule=0x%08lx -> nextpart=%ld, cflags=0x%02lx\",\n\t\t\t\t                     (long) part_idx, (long) sep_idx,\n\t\t\t\t                     (unsigned long) match_val, (unsigned long) rule,\n\t\t\t\t                     (long) nextpart, (unsigned long) cflags));\n\n\t\t\t\tif (cflags & DUK__CF_NEG) {\n\t\t\t\t\tneg_tzoffset = 1;\n\t\t\t\t}\n\n\t\t\t\tif (cflags & DUK__CF_ACCEPT) {\n\t\t\t\t\tgoto accept;\n\t\t\t\t}\n\n\t\t\t\tif (cflags & DUK__CF_ACCEPT_NUL) {\n\t\t\t\t\tDUK_ASSERT(*(p - 1) != (char) 0);\n\t\t\t\t\tif (*p == DUK_ASC_NUL) {\n\t\t\t\t\t\tgoto accept;\n\t\t\t\t\t}\n\t\t\t\t\tgoto reject;\n\t\t\t\t}\n\n\t\t\t\tpart_idx = nextpart;\n\t\t\t\tbreak;\n\t\t\t}  /* rule match */\n\n\t\t\tif (i == (duk_small_uint_t) (sizeof(duk__parse_iso8601_control) / sizeof(duk_uint32_t))) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"no rule matches -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\n\t\t\tif (ch == 0) {\n\t\t\t\t/* This shouldn't be necessary, but check just in case\n\t\t\t\t * to avoid any chance of overruns.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"NUL after rule matching (should not happen) -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t}  /* if-digit-else-ctrl */\n\t}  /* char loop */\n\n\t/* We should never exit the loop above. */\n\tDUK_UNREACHABLE();\n\n reject:\n\tDUK_DDD(DUK_DDDPRINT(\"reject\"));\n\treturn 0;\n\n accept:\n\tDUK_DDD(DUK_DDDPRINT(\"accept\"));\n\n\t/* Apply timezone offset to get the main parts in UTC */\n\tif (neg_year) {\n\t\tparts[DUK__PI_YEAR] = -parts[DUK__PI_YEAR];\n\t}\n\tif (neg_tzoffset) {\n\t\tparts[DUK__PI_HOUR] += parts[DUK__PI_TZHOUR];\n\t\tparts[DUK__PI_MINUTE] += parts[DUK__PI_TZMINUTE];\n\t} else {\n\t\tparts[DUK__PI_HOUR] -= parts[DUK__PI_TZHOUR];\n\t\tparts[DUK__PI_MINUTE] -= parts[DUK__PI_TZMINUTE];\n\t}\n\tparts[DUK__PI_MONTH] -= 1;  /* zero-based month */\n\tparts[DUK__PI_DAY] -= 1;  /* zero-based day */\n\n\t/* Use double parts, they tolerate unnormalized time.\n\t *\n\t * Note: DUK_DATE_IDX_WEEKDAY is initialized with a bogus value (DUK__PI_TZHOUR)\n\t * on purpose.  It won't be actually used by duk_bi_date_get_timeval_from_dparts(),\n\t * but will make the value initialized just in case, and avoid any\n\t * potential for Valgrind issues.\n\t */\n\tfor (i = 0; i < DUK_DATE_IDX_NUM_PARTS; i++) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"part[%ld] = %ld\", (long) i, (long) parts[i]));\n\t\tdparts[i] = parts[i];\n\t}\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);\n\tduk_push_number(thr, d);\n\treturn 1;\n}\n\n/*\n *  Date/time parsing helper.\n *\n *  Parse a datetime string into a time value.  We must first try to parse\n *  the input according to the standard format in E5.1 Section 15.9.1.15.\n *  If that fails, we can try to parse using custom parsing, which can\n *  either be platform neutral (custom code) or platform specific (using\n *  existing platform API calls).\n *\n *  Note in particular that we must parse whatever toString(), toUTCString(),\n *  and toISOString() can produce; see E5.1 Section 15.9.4.2.\n *\n *  Returns 1 to allow tail calling.\n *\n *  There is much room for improvement here with respect to supporting\n *  alternative datetime formats.  For instance, V8 parses '2012-01-01' as\n *  UTC and '2012/01/01' as local time.\n */\n\nDUK_LOCAL duk_ret_t duk__parse_string(duk_hthread *thr, const char *str) {\n\t/* XXX: there is a small risk here: because the ISO 8601 parser is\n\t * very loose, it may end up parsing some datetime values which\n\t * would be better parsed with a platform specific parser.\n\t */\n\n\tDUK_ASSERT(str != NULL);\n\tDUK_DDD(DUK_DDDPRINT(\"parse datetime from string '%s'\", (const char *) str));\n\n\tif (duk__parse_string_iso8601_subset(thr, str) != 0) {\n\t\treturn 1;\n\t}\n\n#if defined(DUK_USE_DATE_PARSE_STRING)\n\t/* Contract, either:\n\t * - Push value on stack and return 1\n\t * - Don't push anything on stack and return 0\n\t */\n\n\tif (DUK_USE_DATE_PARSE_STRING(thr, str) != 0) {\n\t\treturn 1;\n\t}\n#else\n\t/* No platform-specific parsing, this is not an error. */\n#endif\n\n\tduk_push_nan(thr);\n\treturn 1;\n}\n\n/*\n *  Calendar helpers\n *\n *  Some helpers are used for getters and can operate on normalized values\n *  which can be represented with 32-bit signed integers.  Other helpers are\n *  needed by setters and operate on un-normalized double values, must watch\n *  out for non-finite numbers etc.\n */\n\nDUK_LOCAL duk_uint8_t duk__days_in_month[12] = {\n\t(duk_uint8_t) 31, (duk_uint8_t) 28, (duk_uint8_t) 31, (duk_uint8_t) 30,\n\t(duk_uint8_t) 31, (duk_uint8_t) 30, (duk_uint8_t) 31, (duk_uint8_t) 31,\n\t(duk_uint8_t) 30, (duk_uint8_t) 31, (duk_uint8_t) 30, (duk_uint8_t) 31\n};\n\n/* Maximum iteration count for computing UTC-to-local time offset when\n * creating an ECMAScript time value from local parts.\n */\n#define DUK__LOCAL_TZOFFSET_MAXITER   4\n\n/* Because 'day since epoch' can be negative and is used to compute weekday\n * using a modulo operation, add this multiple of 7 to avoid negative values\n * when year is below 1970 epoch.  ECMAScript time values are restricted to\n * +/- 100 million days from epoch, so this adder fits nicely into 32 bits.\n * Round to a multiple of 7 (= floor(100000000 / 7) * 7) and add margin.\n */\n#define DUK__WEEKDAY_MOD_ADDER  (20000000 * 7)  /* 0x08583b00 */\n\nDUK_INTERNAL duk_bool_t duk_bi_date_is_leap_year(duk_int_t year) {\n\tif ((year % 4) != 0) {\n\t\treturn 0;\n\t}\n\tif ((year % 100) != 0) {\n\t\treturn 1;\n\t}\n\tif ((year % 400) != 0) {\n\t\treturn 0;\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_bool_t duk_bi_date_timeval_in_valid_range(duk_double_t x) {\n\treturn (x >= -DUK_DATE_MSEC_100M_DAYS && x <= DUK_DATE_MSEC_100M_DAYS);\n}\n\nDUK_INTERNAL duk_bool_t duk_bi_date_timeval_in_leeway_range(duk_double_t x) {\n\treturn (x >= -DUK_DATE_MSEC_100M_DAYS_LEEWAY && x <= DUK_DATE_MSEC_100M_DAYS_LEEWAY);\n}\n\nDUK_INTERNAL duk_bool_t duk_bi_date_year_in_valid_range(duk_double_t x) {\n\treturn (x >= DUK_DATE_MIN_ECMA_YEAR && x <= DUK_DATE_MAX_ECMA_YEAR);\n}\n\nDUK_LOCAL duk_double_t duk__timeclip(duk_double_t x) {\n\tif (!DUK_ISFINITE(x)) {\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\n\tif (!duk_bi_date_timeval_in_valid_range(x)) {\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\n\tx = duk_js_tointeger_number(x);\n\n\t/* Here we'd have the option to normalize -0 to +0. */\n\treturn x;\n}\n\n/* Integer division which floors also negative values correctly. */\nDUK_LOCAL duk_int_t duk__div_floor(duk_int_t a, duk_int_t b) {\n\tDUK_ASSERT(b > 0);\n\tif (a >= 0) {\n\t\treturn a / b;\n\t} else {\n\t\t/* e.g. a = -4, b = 5  -->  -4 - 5 + 1 / 5  -->  -8 / 5  -->  -1\n\t\t *      a = -5, b = 5  -->  -5 - 5 + 1 / 5  -->  -9 / 5  -->  -1\n\t\t *      a = -6, b = 5  -->  -6 - 5 + 1 / 5  -->  -10 / 5  -->  -2\n\t\t */\n\t\treturn (a - b + 1) / b;\n\t}\n}\n\n/* Compute day number of the first day of a given year. */\nDUK_LOCAL duk_int_t duk__day_from_year(duk_int_t year) {\n\t/* Note: in integer arithmetic, (x / 4) is same as floor(x / 4) for non-negative\n\t * values, but is incorrect for negative ones.\n\t */\n\treturn 365 * (year - 1970)\n\t       + duk__div_floor(year - 1969, 4)\n\t       - duk__div_floor(year - 1901, 100)\n\t       + duk__div_floor(year - 1601, 400);\n}\n\n/* Given a day number, determine year and day-within-year. */\nDUK_LOCAL duk_int_t duk__year_from_day(duk_int_t day, duk_small_int_t *out_day_within_year) {\n\tduk_int_t year;\n\tduk_int_t diff_days;\n\n\t/* estimate year upwards (towards positive infinity), then back down;\n\t * two iterations should be enough\n\t */\n\n\tif (day >= 0) {\n\t\tyear = 1970 + day / 365;\n\t} else {\n\t\tyear = 1970 + day / 366;\n\t}\n\n\tfor (;;) {\n\t\tdiff_days = duk__day_from_year(year) - day;\n\t\tDUK_DDD(DUK_DDDPRINT(\"year=%ld day=%ld, diff_days=%ld\", (long) year, (long) day, (long) diff_days));\n\t\tif (diff_days <= 0) {\n\t\t\tDUK_ASSERT(-diff_days < 366);  /* fits into duk_small_int_t */\n\t\t\t*out_day_within_year = -diff_days;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"--> year=%ld, day-within-year=%ld\",\n\t\t\t                     (long) year, (long) *out_day_within_year));\n\t\t\tDUK_ASSERT(*out_day_within_year >= 0);\n\t\t\tDUK_ASSERT(*out_day_within_year < (duk_bi_date_is_leap_year(year) ? 366 : 365));\n\t\t\treturn year;\n\t\t}\n\n\t\t/* Note: this is very tricky; we must never 'overshoot' the\n\t\t * correction downwards.\n\t\t */\n\t\tyear -= 1 + (diff_days - 1) / 366;  /* conservative */\n\t}\n}\n\n/* Given a (year, month, day-within-month) triple, compute day number.\n * The input triple is un-normalized and may contain non-finite values.\n */\nDUK_LOCAL duk_double_t duk__make_day(duk_double_t year, duk_double_t month, duk_double_t day) {\n\tduk_int_t day_num;\n\tduk_bool_t is_leap;\n\tduk_small_int_t i, n;\n\n\t/* Assume that year, month, day are all coerced to whole numbers.\n\t * They may also be NaN or infinity, in which case this function\n\t * must return NaN or infinity to ensure time value becomes NaN.\n\t * If 'day' is NaN, the final return will end up returning a NaN,\n\t * so it doesn't need to be checked here.\n\t */\n\n\tif (!DUK_ISFINITE(year) || !DUK_ISFINITE(month)) {\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\n\tyear += DUK_FLOOR(month / 12.0);\n\n\tmonth = DUK_FMOD(month, 12.0);\n\tif (month < 0.0) {\n\t\t/* handle negative values */\n\t\tmonth += 12.0;\n\t}\n\n\t/* The algorithm in E5.1 Section 15.9.1.12 normalizes month, but\n\t * does not normalize the day-of-month (nor check whether or not\n\t * it is finite) because it's not necessary for finding the day\n\t * number which matches the (year,month) pair.\n\t *\n\t * We assume that duk__day_from_year() is exact here.\n\t *\n\t * Without an explicit infinity / NaN check in the beginning,\n\t * day_num would be a bogus integer here.\n\t *\n\t * It's possible for 'year' to be out of integer range here.\n\t * If so, we need to return NaN without integer overflow.\n\t * This fixes test-bug-setyear-overflow.js.\n\t */\n\n\tif (!duk_bi_date_year_in_valid_range(year)) {\n\t\tDUK_DD(DUK_DDPRINT(\"year not in ecmascript valid range, avoid integer overflow: %lf\", (double) year));\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\tday_num = duk__day_from_year((duk_int_t) year);\n\tis_leap = duk_bi_date_is_leap_year((duk_int_t) year);\n\n\tn = (duk_small_int_t) month;\n\tfor (i = 0; i < n; i++) {\n\t\tday_num += duk__days_in_month[i];\n\t\tif (i == 1 && is_leap) {\n\t\t\tday_num++;\n\t\t}\n\t}\n\n\t/* If 'day' is NaN, returns NaN. */\n\treturn (duk_double_t) day_num + day;\n}\n\n/* Split time value into parts.  The time value may contain fractions (it may\n * come from duk_time_to_components() API call) which are truncated.  Possible\n * local time adjustment has already been applied when reading the time value.\n */\nDUK_INTERNAL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts, duk_double_t *dparts, duk_small_uint_t flags) {\n\tduk_double_t d1, d2;\n\tduk_int_t t1, t2;\n\tduk_int_t day_since_epoch;\n\tduk_int_t year;  /* does not fit into 16 bits */\n\tduk_small_int_t day_in_year;\n\tduk_small_int_t month;\n\tduk_small_int_t day;\n\tduk_small_int_t dim;\n\tduk_int_t jan1_since_epoch;\n\tduk_small_int_t jan1_weekday;\n\tduk_int_t equiv_year;\n\tduk_small_uint_t i;\n\tduk_bool_t is_leap;\n\tduk_small_int_t arridx;\n\n\tDUK_ASSERT(DUK_ISFINITE(d));    /* caller checks */\n\td = DUK_FLOOR(d);  /* remove fractions if present */\n\tDUK_ASSERT(DUK_FLOOR(d) == d);\n\n\t/* The timevalue must be in valid ECMAScript range, but since a local\n\t * time offset can be applied, we need to allow a +/- 24h leeway to\n\t * the value.  In other words, although the UTC time is within the\n\t * ECMAScript range, the local part values can be just outside of it.\n\t */\n\tDUK_UNREF(duk_bi_date_timeval_in_leeway_range);\n\tDUK_ASSERT(duk_bi_date_timeval_in_leeway_range(d));\n\n\t/* These computations are guaranteed to be exact for the valid\n\t * E5 time value range, assuming milliseconds without fractions.\n\t */\n\td1 = (duk_double_t) DUK_FMOD(d, (double) DUK_DATE_MSEC_DAY);\n\tif (d1 < 0.0) {\n\t\t/* deal with negative values */\n\t\td1 += (duk_double_t) DUK_DATE_MSEC_DAY;\n\t}\n\td2 = DUK_FLOOR((double) (d / (duk_double_t) DUK_DATE_MSEC_DAY));\n\tDUK_ASSERT(d2 * ((duk_double_t) DUK_DATE_MSEC_DAY) + d1 == d);\n\t/* now expected to fit into a 32-bit integer */\n\tt1 = (duk_int_t) d1;\n\tt2 = (duk_int_t) d2;\n\tday_since_epoch = t2;\n\tDUK_ASSERT((duk_double_t) t1 == d1);\n\tDUK_ASSERT((duk_double_t) t2 == d2);\n\n\t/* t1 = milliseconds within day (fits 32 bit)\n\t * t2 = day number from epoch (fits 32 bit, may be negative)\n\t */\n\n\tparts[DUK_DATE_IDX_MILLISECOND] = t1 % 1000; t1 /= 1000;\n\tparts[DUK_DATE_IDX_SECOND] = t1 % 60; t1 /= 60;\n\tparts[DUK_DATE_IDX_MINUTE] = t1 % 60; t1 /= 60;\n\tparts[DUK_DATE_IDX_HOUR] = t1;\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MILLISECOND] >= 0 && parts[DUK_DATE_IDX_MILLISECOND] <= 999);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_SECOND] >= 0 && parts[DUK_DATE_IDX_SECOND] <= 59);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MINUTE] >= 0 && parts[DUK_DATE_IDX_MINUTE] <= 59);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_HOUR] >= 0 && parts[DUK_DATE_IDX_HOUR] <= 23);\n\n\tDUK_DDD(DUK_DDDPRINT(\"d=%lf, d1=%lf, d2=%lf, t1=%ld, t2=%ld, parts: hour=%ld min=%ld sec=%ld msec=%ld\",\n\t                     (double) d, (double) d1, (double) d2, (long) t1, (long) t2,\n\t                     (long) parts[DUK_DATE_IDX_HOUR],\n\t                     (long) parts[DUK_DATE_IDX_MINUTE],\n\t                     (long) parts[DUK_DATE_IDX_SECOND],\n\t                     (long) parts[DUK_DATE_IDX_MILLISECOND]));\n\n\t/* This assert depends on the input parts representing time inside\n\t * the ECMAScript range.\n\t */\n\tDUK_ASSERT(t2 + DUK__WEEKDAY_MOD_ADDER >= 0);\n\tparts[DUK_DATE_IDX_WEEKDAY] = (t2 + 4 + DUK__WEEKDAY_MOD_ADDER) % 7;  /* E5.1 Section 15.9.1.6 */\n\tDUK_ASSERT(parts[DUK_DATE_IDX_WEEKDAY] >= 0 && parts[DUK_DATE_IDX_WEEKDAY] <= 6);\n\n\tyear = duk__year_from_day(t2, &day_in_year);\n\tday = day_in_year;\n\tis_leap = duk_bi_date_is_leap_year(year);\n\tfor (month = 0; month < 12; month++) {\n\t\tdim = duk__days_in_month[month];\n\t\tif (month == 1 && is_leap) {\n\t\t\tdim++;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"month=%ld, dim=%ld, day=%ld\",\n\t\t                     (long) month, (long) dim, (long) day));\n\t\tif (day < dim) {\n\t\t\tbreak;\n\t\t}\n\t\tday -= dim;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"final month=%ld\", (long) month));\n\tDUK_ASSERT(month >= 0 && month <= 11);\n\tDUK_ASSERT(day >= 0 && day <= 31);\n\n\t/* Equivalent year mapping, used to avoid DST trouble when platform\n\t * may fail to provide reasonable DST answers for dates outside the\n\t * ordinary range (e.g. 1970-2038).  An equivalent year has the same\n\t * leap-year-ness as the original year and begins on the same weekday\n\t * (Jan 1).\n\t *\n\t * The year 2038 is avoided because there seem to be problems with it\n\t * on some platforms.  The year 1970 is also avoided as there were\n\t * practical problems with it; an equivalent year is used for it too,\n\t * which breaks some DST computations for 1970 right now, see e.g.\n\t * test-bi-date-tzoffset-brute-fi.js.\n\t */\n\tif ((flags & DUK_DATE_FLAG_EQUIVYEAR) && (year < 1971 || year > 2037)) {\n\t\tDUK_ASSERT(is_leap == 0 || is_leap == 1);\n\n\t\tjan1_since_epoch = day_since_epoch - day_in_year;  /* day number for Jan 1 since epoch */\n\t\tDUK_ASSERT(jan1_since_epoch + DUK__WEEKDAY_MOD_ADDER >= 0);\n\t\tjan1_weekday = (jan1_since_epoch + 4 + DUK__WEEKDAY_MOD_ADDER) % 7;  /* E5.1 Section 15.9.1.6 */\n\t\tDUK_ASSERT(jan1_weekday >= 0 && jan1_weekday <= 6);\n\t\tarridx = jan1_weekday;\n\t\tif (is_leap) {\n\t\t\tarridx += 7;\n\t\t}\n\t\tDUK_ASSERT(arridx >= 0 && arridx < (duk_small_int_t) (sizeof(duk__date_equivyear) / sizeof(duk_uint8_t)));\n\n\t\tequiv_year = (duk_int_t) duk__date_equivyear[arridx] + 1970;\n\t\tyear = equiv_year;\n\t\tDUK_DDD(DUK_DDDPRINT(\"equiv year mapping, year=%ld, day_in_year=%ld, day_since_epoch=%ld, \"\n\t\t                     \"jan1_since_epoch=%ld, jan1_weekday=%ld -> equiv year %ld\",\n\t\t                     (long) year, (long) day_in_year, (long) day_since_epoch,\n\t\t                     (long) jan1_since_epoch, (long) jan1_weekday, (long) equiv_year));\n\t}\n\n\tparts[DUK_DATE_IDX_YEAR] = year;\n\tparts[DUK_DATE_IDX_MONTH] = month;\n\tparts[DUK_DATE_IDX_DAY] = day;\n\n\tif (flags & DUK_DATE_FLAG_ONEBASED) {\n\t\tparts[DUK_DATE_IDX_MONTH]++;  /* zero-based -> one-based */\n\t\tparts[DUK_DATE_IDX_DAY]++;    /* -\"\"- */\n\t}\n\n\tif (dparts != NULL) {\n\t\tfor (i = 0; i < DUK_DATE_IDX_NUM_PARTS; i++) {\n\t\t\tdparts[i] = (duk_double_t) parts[i];\n\t\t}\n\t}\n}\n\n/* Compute time value from (double) parts.  The parts can be either UTC\n * or local time; if local, they need to be (conceptually) converted into\n * UTC time.  The parts may represent valid or invalid time, and may be\n * wildly out of range (but may cancel each other and still come out in\n * the valid Date range).\n */\nDUK_INTERNAL duk_double_t duk_bi_date_get_timeval_from_dparts(duk_double_t *dparts, duk_small_uint_t flags) {\n#if defined(DUK_USE_PARANOID_DATE_COMPUTATION)\n\t/* See comments below on MakeTime why these are volatile. */\n\tvolatile duk_double_t tmp_time;\n\tvolatile duk_double_t tmp_day;\n\tvolatile duk_double_t d;\n#else\n\tduk_double_t tmp_time;\n\tduk_double_t tmp_day;\n\tduk_double_t d;\n#endif\n\tduk_small_uint_t i;\n\tduk_int_t tzoff, tzoffprev1, tzoffprev2;\n\n\t/* Expects 'this' at top of stack on entry. */\n\n\t/* Coerce all finite parts with ToInteger().  ToInteger() must not\n\t * be called for NaN/Infinity because it will convert e.g. NaN to\n\t * zero.  If ToInteger() has already been called, this has no side\n\t * effects and is idempotent.\n\t *\n\t * Don't read dparts[DUK_DATE_IDX_WEEKDAY]; it will cause Valgrind\n\t * issues if the value is uninitialized.\n\t */\n\tfor (i = 0; i <= DUK_DATE_IDX_MILLISECOND; i++) {\n\t\t/* SCANBUILD: scan-build complains here about assigned value\n\t\t * being garbage or undefined.  This is correct but operating\n\t\t * on undefined values has no ill effect and is ignored by the\n\t\t * caller in the case where this happens.\n\t\t */\n\t\td = dparts[i];\n\t\tif (DUK_ISFINITE(d)) {\n\t\t\tdparts[i] = duk_js_tointeger_number(d);\n\t\t}\n\t}\n\n\t/* Use explicit steps in computation to try to ensure that\n\t * computation happens with intermediate results coerced to\n\t * double values (instead of using something more accurate).\n\t * E.g. E5.1 Section 15.9.1.11 requires use of IEEE 754\n\t * rules (= ECMAScript '+' and '*' operators).\n\t *\n\t * Without 'volatile' even this approach fails on some platform\n\t * and compiler combinations.  For instance, gcc 4.8.1 on Ubuntu\n\t * 64-bit, with -m32 and without -std=c99, test-bi-date-canceling.js\n\t * would fail because of some optimizations when computing tmp_time\n\t * (MakeTime below).  Adding 'volatile' to tmp_time solved this\n\t * particular problem (annoyingly, also adding debug prints or\n\t * running the executable under valgrind hides it).\n\t */\n\n\t/* MakeTime */\n\ttmp_time = 0.0;\n\ttmp_time += dparts[DUK_DATE_IDX_HOUR] * ((duk_double_t) DUK_DATE_MSEC_HOUR);\n\ttmp_time += dparts[DUK_DATE_IDX_MINUTE] * ((duk_double_t) DUK_DATE_MSEC_MINUTE);\n\ttmp_time += dparts[DUK_DATE_IDX_SECOND] * ((duk_double_t) DUK_DATE_MSEC_SECOND);\n\ttmp_time += dparts[DUK_DATE_IDX_MILLISECOND];\n\n\t/* MakeDay */\n\ttmp_day = duk__make_day(dparts[DUK_DATE_IDX_YEAR], dparts[DUK_DATE_IDX_MONTH], dparts[DUK_DATE_IDX_DAY]);\n\n\t/* MakeDate */\n\td = tmp_day * ((duk_double_t) DUK_DATE_MSEC_DAY) + tmp_time;\n\n\tDUK_DDD(DUK_DDDPRINT(\"time=%lf day=%lf --> timeval=%lf\",\n\t                     (double) tmp_time, (double) tmp_day, (double) d));\n\n\t/* Optional UTC conversion. */\n\tif (flags & DUK_DATE_FLAG_LOCALTIME) {\n\t\t/* DUK_USE_DATE_GET_LOCAL_TZOFFSET() needs to be called with a\n\t\t * time value computed from UTC parts.  At this point we only\n\t\t * have 'd' which is a time value computed from local parts, so\n\t\t * it is off by the UTC-to-local time offset which we don't know\n\t\t * yet.  The current solution for computing the UTC-to-local\n\t\t * time offset is to iterate a few times and detect a fixed\n\t\t * point or a two-cycle loop (or a sanity iteration limit),\n\t\t * see test-bi-date-local-parts.js and test-bi-date-tzoffset-basic-fi.js.\n\t\t *\n\t\t * E5.1 Section 15.9.1.9:\n\t\t * UTC(t) = t - LocalTZA - DaylightSavingTA(t - LocalTZA)\n\t\t *\n\t\t * For NaN/inf, DUK_USE_DATE_GET_LOCAL_TZOFFSET() returns 0.\n\t\t */\n\n#if 0\n\t\t/* Old solution: don't iterate, incorrect */\n\t\ttzoff = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);\n\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset w/o iteration, tzoff=%ld\", (long) tzoff));\n\t\td -= tzoff * 1000L;\n\t\tDUK_UNREF(tzoffprev1);\n\t\tDUK_UNREF(tzoffprev2);\n#endif\n\n\t\t/* Iteration solution */\n\t\ttzoff = 0;\n\t\ttzoffprev1 = 999999999L;  /* invalid value which never matches */\n\t\tfor (i = 0; i < DUK__LOCAL_TZOFFSET_MAXITER; i++) {\n\t\t\ttzoffprev2 = tzoffprev1;\n\t\t\ttzoffprev1 = tzoff;\n\t\t\ttzoff = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d - tzoff * 1000L);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration, i=%d, tzoff=%ld, tzoffprev1=%ld tzoffprev2=%ld\",\n\t\t\t                     (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2));\n\t\t\tif (tzoff == tzoffprev1) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration finished, i=%d, tzoff=%ld, tzoffprev1=%ld, tzoffprev2=%ld\",\n\t\t\t\t                     (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2));\n\t\t\t\tbreak;\n\t\t\t} else if (tzoff == tzoffprev2) {\n\t\t\t\t/* Two value cycle, see e.g. test-bi-date-tzoffset-basic-fi.js.\n\t\t\t\t * In these cases, favor a higher tzoffset to get a consistent\n\t\t\t\t * result which is independent of iteration count.  Not sure if\n\t\t\t\t * this is a generically correct solution.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration two-value cycle, i=%d, tzoff=%ld, tzoffprev1=%ld, tzoffprev2=%ld\",\n\t\t\t\t                     (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2));\n\t\t\t\tif (tzoffprev1 > tzoff) {\n\t\t\t\t\ttzoff = tzoffprev1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration, tzoff=%ld\", (long) tzoff));\n\t\td -= tzoff * 1000L;\n\t}\n\n\t/* TimeClip(), which also handles Infinity -> NaN conversion */\n\td = duk__timeclip(d);\n\n\treturn d;\n}\n\n/*\n *  API oriented helpers\n */\n\n/* Push 'this' binding, check that it is a Date object; then push the\n * internal time value.  At the end, stack is: [ ... this timeval ].\n * Returns the time value.  Local time adjustment is done if requested.\n */\nDUK_LOCAL duk_double_t duk__push_this_get_timeval_tzoffset(duk_hthread *thr, duk_small_uint_t flags, duk_int_t *out_tzoffset) {\n\tduk_hobject *h;\n\tduk_double_t d;\n\tduk_int_t tzoffset = 0;\n\n\tduk_push_this(thr);\n\th = duk_get_hobject(thr, -1);  /* XXX: getter with class check, useful in built-ins */\n\tif (h == NULL || DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_DATE) {\n\t\tDUK_ERROR_TYPE(thr, \"expected Date\");\n\t\tDUK_WO_NORETURN(return 0.0;);\n\t}\n\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\td = duk_to_number_m1(thr);\n\tduk_pop(thr);\n\n\tif (DUK_ISNAN(d)) {\n\t\tif (flags & DUK_DATE_FLAG_NAN_TO_ZERO) {\n\t\t\td = 0.0;\n\t\t}\n\t\tif (flags & DUK_DATE_FLAG_NAN_TO_RANGE_ERROR) {\n\t\t\tDUK_ERROR_RANGE(thr, \"Invalid Date\");\n\t\t\tDUK_WO_NORETURN(return 0.0;);\n\t\t}\n\t}\n\t/* if no NaN handling flag, may still be NaN here, but not Inf */\n\tDUK_ASSERT(!DUK_ISINF(d));\n\n\tif (flags & DUK_DATE_FLAG_LOCALTIME) {\n\t\t/* Note: DST adjustment is determined using UTC time.\n\t\t * If 'd' is NaN, tzoffset will be 0.\n\t\t */\n\t\ttzoffset = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);  /* seconds */\n\t\td += tzoffset * 1000L;\n\t}\n\tif (out_tzoffset) {\n\t\t*out_tzoffset = tzoffset;\n\t}\n\n\t/* [ ... this ] */\n\treturn d;\n}\n\nDUK_LOCAL duk_double_t duk__push_this_get_timeval(duk_hthread *thr, duk_small_uint_t flags) {\n\treturn duk__push_this_get_timeval_tzoffset(thr, flags, NULL);\n}\n\n/* Set timeval to 'this' from dparts, push the new time value onto the\n * value stack and return 1 (caller can then tail call us).  Expects\n * the value stack to contain 'this' on the stack top.\n */\nDUK_LOCAL duk_ret_t duk__set_this_timeval_from_dparts(duk_hthread *thr, duk_double_t *dparts, duk_small_uint_t flags) {\n\tduk_double_t d;\n\n\t/* [ ... this ] */\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, flags);\n\tduk_push_number(thr, d);  /* -> [ ... this timeval_new ] */\n\tduk_dup_top(thr);         /* -> [ ... this timeval_new timeval_new ] */\n\n\t/* Must force write because e.g. .setYear() must work even when\n\t * the Date instance is frozen.\n\t */\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\n\t/* Stack top: new time value, return 1 to allow tail calls. */\n\treturn 1;\n}\n\n/* 'out_buf' must be at least DUK_BI_DATE_ISO8601_BUFSIZE long. */\nDUK_LOCAL void duk__format_parts_iso8601(duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags, duk_uint8_t *out_buf) {\n\tchar yearstr[8];   /* \"-123456\\0\" */\n\tchar tzstr[8];     /* \"+11:22\\0\" */\n\tchar sep = (flags & DUK_DATE_FLAG_SEP_T) ? DUK_ASC_UC_T : DUK_ASC_SPACE;\n\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MONTH] >= 1 && parts[DUK_DATE_IDX_MONTH] <= 12);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_DAY] >= 1 && parts[DUK_DATE_IDX_DAY] <= 31);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_YEAR] >= -999999 && parts[DUK_DATE_IDX_YEAR] <= 999999);\n\n\t/* Note: %06d for positive value, %07d for negative value to include\n\t * sign and 6 digits.\n\t */\n\tDUK_SNPRINTF(yearstr,\n\t             sizeof(yearstr),\n\t             (parts[DUK_DATE_IDX_YEAR] >= 0 && parts[DUK_DATE_IDX_YEAR] <= 9999) ? \"%04ld\" :\n\t                    ((parts[DUK_DATE_IDX_YEAR] >= 0) ? \"+%06ld\" : \"%07ld\"),\n\t             (long) parts[DUK_DATE_IDX_YEAR]);\n\tyearstr[sizeof(yearstr) - 1] = (char) 0;\n\n\tif (flags & DUK_DATE_FLAG_LOCALTIME) {\n\t\t/* tzoffset seconds are dropped; 16 bits suffice for\n\t\t * time offset in minutes\n\t\t */\n\t\tconst char *fmt;\n\t\tduk_small_int_t tmp, arg_hours, arg_minutes;\n\n\t\tif (tzoffset >= 0) {\n\t\t\ttmp = tzoffset;\n\t\t\tfmt = \"+%02d:%02d\";\n\t\t} else {\n\t\t\ttmp = -tzoffset;\n\t\t\tfmt = \"-%02d:%02d\";\n\t\t}\n\t\ttmp = tmp / 60;\n\t\targ_hours = tmp / 60;\n\t\targ_minutes = tmp % 60;\n\t\tDUK_ASSERT(arg_hours <= 24);  /* Even less is actually guaranteed for a valid tzoffset. */\n\t\targ_hours = arg_hours & 0x3f;  /* For [0,24] this is a no-op, but fixes GCC 7 warning, see https://github.com/svaarala/duktape/issues/1602. */\n\n\t\tDUK_SNPRINTF(tzstr, sizeof(tzstr), fmt, (int) arg_hours, (int) arg_minutes);\n\t\ttzstr[sizeof(tzstr) - 1] = (char) 0;\n\t} else {\n\t\ttzstr[0] = DUK_ASC_UC_Z;\n\t\ttzstr[1] = (char) 0;\n\t}\n\n\t/* Unlike year, the other parts fit into 16 bits so %d format\n\t * is portable.\n\t */\n\tif ((flags & DUK_DATE_FLAG_TOSTRING_DATE) && (flags & DUK_DATE_FLAG_TOSTRING_TIME)) {\n\t\tDUK_SPRINTF((char *) out_buf, \"%s-%02d-%02d%c%02d:%02d:%02d.%03d%s\",\n\t\t            (const char *) yearstr, (int) parts[DUK_DATE_IDX_MONTH], (int) parts[DUK_DATE_IDX_DAY], (int) sep,\n\t\t            (int) parts[DUK_DATE_IDX_HOUR], (int) parts[DUK_DATE_IDX_MINUTE],\n\t\t            (int) parts[DUK_DATE_IDX_SECOND], (int) parts[DUK_DATE_IDX_MILLISECOND], (const char *) tzstr);\n\t} else if (flags & DUK_DATE_FLAG_TOSTRING_DATE) {\n\t\tDUK_SPRINTF((char *) out_buf, \"%s-%02d-%02d\",\n\t\t            (const char *) yearstr, (int) parts[DUK_DATE_IDX_MONTH], (int) parts[DUK_DATE_IDX_DAY]);\n\t} else {\n\t\tDUK_ASSERT(flags & DUK_DATE_FLAG_TOSTRING_TIME);\n\t\tDUK_SPRINTF((char *) out_buf, \"%02d:%02d:%02d.%03d%s\",\n\t\t            (int) parts[DUK_DATE_IDX_HOUR], (int) parts[DUK_DATE_IDX_MINUTE],\n\t\t            (int) parts[DUK_DATE_IDX_SECOND], (int) parts[DUK_DATE_IDX_MILLISECOND],\n\t\t            (const char *) tzstr);\n\t}\n}\n\n/* Helper for string conversion calls: check 'this' binding, get the\n * internal time value, and format date and/or time in a few formats.\n * Return value allows tail calls.\n */\nDUK_LOCAL duk_ret_t duk__to_string_helper(duk_hthread *thr, duk_small_uint_t flags) {\n\tduk_double_t d;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_int_t tzoffset;  /* seconds, doesn't fit into 16 bits */\n\tduk_bool_t rc;\n\tduk_uint8_t buf[DUK_BI_DATE_ISO8601_BUFSIZE];\n\n\tDUK_UNREF(rc);  /* unreferenced with some options */\n\n\td = duk__push_this_get_timeval_tzoffset(thr, flags, &tzoffset);\n\tif (DUK_ISNAN(d)) {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_INVALID_DATE);\n\t\treturn 1;\n\t}\n\tDUK_ASSERT(DUK_ISFINITE(d));\n\n\t/* formatters always get one-based month/day-of-month */\n\tduk_bi_date_timeval_to_parts(d, parts, NULL, DUK_DATE_FLAG_ONEBASED);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MONTH] >= 1 && parts[DUK_DATE_IDX_MONTH] <= 12);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_DAY] >= 1 && parts[DUK_DATE_IDX_DAY] <= 31);\n\n\tif (flags & DUK_DATE_FLAG_TOSTRING_LOCALE) {\n\t\t/* try locale specific formatter; if it refuses to format the\n\t\t * string, fall back to an ISO 8601 formatted value in local\n\t\t * time.\n\t\t */\n#if defined(DUK_USE_DATE_FORMAT_STRING)\n\t\t/* Contract, either:\n\t\t * - Push string to value stack and return 1\n\t\t * - Don't push anything and return 0\n\t\t */\n\n\t\trc = DUK_USE_DATE_FORMAT_STRING(thr, parts, tzoffset, flags);\n\t\tif (rc != 0) {\n\t\t\treturn 1;\n\t\t}\n#else\n\t\t/* No locale specific formatter; this is OK, we fall back\n\t\t * to ISO 8601.\n\t\t */\n#endif\n\t}\n\n\t/* Different calling convention than above used because the helper\n\t * is shared.\n\t */\n\tduk__format_parts_iso8601(parts, tzoffset, flags, buf);\n\tduk_push_string(thr, (const char *) buf);\n\treturn 1;\n}\n\n/* Helper for component getter calls: check 'this' binding, get the\n * internal time value, split it into parts (either as UTC time or\n * local time), push a specified component as a return value to the\n * value stack and return 1 (caller can then tail call us).\n */\nDUK_LOCAL duk_ret_t duk__get_part_helper(duk_hthread *thr, duk_small_uint_t flags_and_idx) {\n\tduk_double_t d;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_small_uint_t idx_part = (duk_small_uint_t) (flags_and_idx >> DUK_DATE_FLAG_VALUE_SHIFT);  /* unpack args */\n\n\tDUK_ASSERT_DISABLE(idx_part >= 0);  /* unsigned */\n\tDUK_ASSERT(idx_part < DUK_DATE_IDX_NUM_PARTS);\n\n\td = duk__push_this_get_timeval(thr, flags_and_idx);\n\tif (DUK_ISNAN(d)) {\n\t\tduk_push_nan(thr);\n\t\treturn 1;\n\t}\n\tDUK_ASSERT(DUK_ISFINITE(d));\n\n\tduk_bi_date_timeval_to_parts(d, parts, NULL, flags_and_idx);  /* no need to mask idx portion */\n\n\t/* Setter APIs detect special year numbers (0...99) and apply a +1900\n\t * only in certain cases.  The legacy getYear() getter applies -1900\n\t * unconditionally.\n\t */\n\tduk_push_int(thr, (flags_and_idx & DUK_DATE_FLAG_SUB1900) ? parts[idx_part] - 1900 : parts[idx_part]);\n\treturn 1;\n}\n\n/* Helper for component setter calls: check 'this' binding, get the\n * internal time value, split it into parts (either as UTC time or\n * local time), modify one or more components as specified, recompute\n * the time value, set it as the internal value.  Finally, push the\n * new time value as a return value to the value stack and return 1\n * (caller can then tail call us).\n */\nDUK_LOCAL duk_ret_t duk__set_part_helper(duk_hthread *thr, duk_small_uint_t flags_and_maxnargs) {\n\tduk_double_t d;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_idx_t nargs;\n\tduk_small_uint_t maxnargs = (duk_small_uint_t) (flags_and_maxnargs >> DUK_DATE_FLAG_VALUE_SHIFT);  /* unpack args */\n\tduk_small_uint_t idx_first, idx;\n\tduk_small_uint_t i;\n\n\tnargs = duk_get_top(thr);\n\td = duk__push_this_get_timeval(thr, flags_and_maxnargs);\n\tDUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));\n\n\tif (DUK_ISFINITE(d)) {\n\t\tduk_bi_date_timeval_to_parts(d, parts, dparts, flags_and_maxnargs);\n\t} else {\n\t\t/* NaN timevalue: we need to coerce the arguments, but\n\t\t * the resulting internal timestamp needs to remain NaN.\n\t\t * This works but is not pretty: parts and dparts will\n\t\t * be partially uninitialized, but we only write to them.\n\t\t */\n\t}\n\n\t/*\n\t *  Determining which datetime components to overwrite based on\n\t *  stack arguments is a bit complicated, but important to factor\n\t *  out from setters themselves for compactness.\n\t *\n\t *  If DUK_DATE_FLAG_TIMESETTER, maxnargs indicates setter type:\n\t *\n\t *   1 -> millisecond\n\t *   2 -> second, [millisecond]\n\t *   3 -> minute, [second], [millisecond]\n\t *   4 -> hour, [minute], [second], [millisecond]\n\t *\n\t *  Else:\n\t *\n\t *   1 -> date\n\t *   2 -> month, [date]\n\t *   3 -> year, [month], [date]\n\t *\n\t *  By comparing nargs and maxnargs (and flags) we know which\n\t *  components to override.  We rely on part index ordering.\n\t */\n\n\tif (flags_and_maxnargs & DUK_DATE_FLAG_TIMESETTER) {\n\t\tDUK_ASSERT(maxnargs >= 1 && maxnargs <= 4);\n\t\tidx_first = DUK_DATE_IDX_MILLISECOND - (maxnargs - 1);\n\t} else {\n\t\tDUK_ASSERT(maxnargs >= 1 && maxnargs <= 3);\n\t\tidx_first = DUK_DATE_IDX_DAY - (maxnargs - 1);\n\t}\n\tDUK_ASSERT_DISABLE(idx_first >= 0);  /* unsigned */\n\tDUK_ASSERT(idx_first < DUK_DATE_IDX_NUM_PARTS);\n\n\tfor (i = 0; i < maxnargs; i++) {\n\t\tif ((duk_idx_t) i >= nargs) {\n\t\t\t/* no argument given -> leave components untouched */\n\t\t\tbreak;\n\t\t}\n\t\tidx = idx_first + i;\n\t\tDUK_ASSERT_DISABLE(idx >= 0);  /* unsigned */\n\t\tDUK_ASSERT(idx < DUK_DATE_IDX_NUM_PARTS);\n\n\t\tif (idx == DUK_DATE_IDX_YEAR && (flags_and_maxnargs & DUK_DATE_FLAG_YEAR_FIXUP)) {\n\t\t\tduk__twodigit_year_fixup(thr, (duk_idx_t) i);\n\t\t}\n\n\t\tdparts[idx] = duk_to_number(thr, (duk_idx_t) i);\n\n\t\tif (idx == DUK_DATE_IDX_DAY) {\n\t\t\t/* Day-of-month is one-based in the API, but zero-based\n\t\t\t * internally, so fix here.  Note that month is zero-based\n\t\t\t * both in the API and internally.\n\t\t\t */\n\t\t\t/* SCANBUILD: complains about use of uninitialized values.\n\t\t\t * The complaint is correct, but operating in undefined\n\t\t\t * values here is intentional in some cases and the caller\n\t\t\t * ignores the results.\n\t\t\t */\n\t\t\tdparts[idx] -= 1.0;\n\t\t}\n\t}\n\n\t/* Leaves new timevalue on stack top and returns 1, which is correct\n\t * for part setters.\n\t */\n\tif (DUK_ISFINITE(d)) {\n\t\treturn duk__set_this_timeval_from_dparts(thr, dparts, flags_and_maxnargs);\n\t} else {\n\t\t/* Internal timevalue is already NaN, so don't touch it. */\n\t\tduk_push_nan(thr);\n\t\treturn 1;\n\t}\n}\n\n/* Apply ToNumber() to specified index; if ToInteger(val) in [0,99], add\n * 1900 and replace value at idx_val.\n */\nDUK_LOCAL void duk__twodigit_year_fixup(duk_hthread *thr, duk_idx_t idx_val) {\n\tduk_double_t d;\n\n\t/* XXX: idx_val would fit into 16 bits, but using duk_small_uint_t\n\t * might not generate better code due to casting.\n\t */\n\n\t/* E5 Sections 15.9.3.1, B.2.4, B.2.5 */\n\tduk_to_number(thr, idx_val);\n\tif (duk_is_nan(thr, idx_val)) {\n\t\treturn;\n\t}\n\tduk_dup(thr, idx_val);\n\tduk_to_int(thr, -1);\n\td = duk_get_number(thr, -1);  /* get as double to handle huge numbers correctly */\n\tif (d >= 0.0 && d <= 99.0) {\n\t\td += 1900.0;\n\t\tduk_push_number(thr, d);\n\t\tduk_replace(thr, idx_val);\n\t}\n\tduk_pop(thr);\n}\n\n/* Set datetime parts from stack arguments, defaulting any missing values.\n * Day-of-week is not set; it is not required when setting the time value.\n */\nDUK_LOCAL void duk__set_parts_from_args(duk_hthread *thr, duk_double_t *dparts, duk_idx_t nargs) {\n\tduk_double_t d;\n\tduk_small_uint_t i;\n\tduk_small_uint_t idx;\n\n\t/* Causes a ToNumber() coercion, but doesn't break coercion order since\n\t * year is coerced first anyway.\n\t */\n\tduk__twodigit_year_fixup(thr, 0);\n\n\t/* There are at most 7 args, but we use 8 here so that also\n\t * DUK_DATE_IDX_WEEKDAY gets initialized (to zero) to avoid the potential\n\t * for any Valgrind gripes later.\n\t */\n\tfor (i = 0; i < 8; i++) {\n\t\t/* Note: rely on index ordering */\n\t\tidx = DUK_DATE_IDX_YEAR + i;\n\t\tif ((duk_idx_t) i < nargs) {\n\t\t\td = duk_to_number(thr, (duk_idx_t) i);\n\t\t\tif (idx == DUK_DATE_IDX_DAY) {\n\t\t\t\t/* Convert day from one-based to zero-based (internal).  This may\n\t\t\t\t * cause the day part to be negative, which is OK.\n\t\t\t\t */\n\t\t\t\td -= 1.0;\n\t\t\t}\n\t\t} else {\n\t\t\t/* All components default to 0 except day-of-month which defaults\n\t\t\t * to 1.  However, because our internal day-of-month is zero-based,\n\t\t\t * it also defaults to zero here.\n\t\t\t */\n\t\t\td = 0.0;\n\t\t}\n\t\tdparts[idx] = d;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"parts from args -> %lf %lf %lf %lf %lf %lf %lf %lf\",\n\t                     (double) dparts[0], (double) dparts[1],\n\t                     (double) dparts[2], (double) dparts[3],\n\t                     (double) dparts[4], (double) dparts[5],\n\t                     (double) dparts[6], (double) dparts[7]));\n}\n\n/*\n *  Indirect magic value lookup for Date methods.\n *\n *  Date methods don't put their control flags into the function magic value\n *  because they wouldn't fit into a LIGHTFUNC's magic field.  Instead, the\n *  magic value is set to an index pointing to the array of control flags\n *  below.\n *\n *  This must be kept in strict sync with genbuiltins.py!\n */\n\nstatic duk_uint16_t duk__date_magics[] = {\n\t/* 0: toString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 1: toDateString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 2: toTimeString */\n\tDUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 3: toLocaleString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 4: toLocaleDateString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 5: toLocaleTimeString */\n\tDUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 6: toUTCString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME,\n\n\t/* 7: toISOString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_NAN_TO_RANGE_ERROR + DUK_DATE_FLAG_SEP_T,\n\n\t/* 8: getFullYear */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 9: getUTCFullYear */\n\t0 + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 10: getMonth */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MONTH << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 11: getUTCMonth */\n\t0 + (DUK_DATE_IDX_MONTH << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 12: getDate */\n\tDUK_DATE_FLAG_ONEBASED + DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_DAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 13: getUTCDate */\n\tDUK_DATE_FLAG_ONEBASED + (DUK_DATE_IDX_DAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 14: getDay */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_WEEKDAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 15: getUTCDay */\n\t0 + (DUK_DATE_IDX_WEEKDAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 16: getHours */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_HOUR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 17: getUTCHours */\n\t0 + (DUK_DATE_IDX_HOUR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 18: getMinutes */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MINUTE << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 19: getUTCMinutes */\n\t0 + (DUK_DATE_IDX_MINUTE << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 20: getSeconds */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_SECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 21: getUTCSeconds */\n\t0 + (DUK_DATE_IDX_SECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 22: getMilliseconds */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MILLISECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 23: getUTCMilliseconds */\n\t0 + (DUK_DATE_IDX_MILLISECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 24: setMilliseconds */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 25: setUTCMilliseconds */\n\tDUK_DATE_FLAG_TIMESETTER + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 26: setSeconds */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 27: setUTCSeconds */\n\tDUK_DATE_FLAG_TIMESETTER + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 28: setMinutes */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 29: setUTCMinutes */\n\tDUK_DATE_FLAG_TIMESETTER + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 30: setHours */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (4 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 31: setUTCHours */\n\tDUK_DATE_FLAG_TIMESETTER + (4 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 32: setDate */\n\tDUK_DATE_FLAG_LOCALTIME + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 33: setUTCDate */\n\t0 + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 34: setMonth */\n\tDUK_DATE_FLAG_LOCALTIME + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 35: setUTCMonth */\n\t0 + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 36: setFullYear */\n\tDUK_DATE_FLAG_NAN_TO_ZERO + DUK_DATE_FLAG_LOCALTIME + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 37: setUTCFullYear */\n\tDUK_DATE_FLAG_NAN_TO_ZERO + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 38: getYear */\n\tDUK_DATE_FLAG_LOCALTIME + DUK_DATE_FLAG_SUB1900 + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 39: setYear */\n\tDUK_DATE_FLAG_NAN_TO_ZERO + DUK_DATE_FLAG_YEAR_FIXUP + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n};\n\nDUK_LOCAL duk_small_uint_t duk__date_get_indirect_magic(duk_hthread *thr) {\n\tduk_small_uint_t magicidx = (duk_small_uint_t) duk_get_current_magic(thr);\n\tDUK_ASSERT(magicidx < (duk_small_int_t) (sizeof(duk__date_magics) / sizeof(duk_uint16_t)));\n\treturn (duk_small_uint_t) duk__date_magics[magicidx];\n}\n\n#if defined(DUK_USE_DATE_BUILTIN)\n/*\n *  Constructor calls\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor(duk_hthread *thr) {\n\tduk_idx_t nargs = duk_get_top(thr);\n\tduk_bool_t is_cons = duk_is_constructor_call(thr);\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t d;\n\n\tDUK_DDD(DUK_DDDPRINT(\"Date constructor, nargs=%ld, is_cons=%ld\", (long) nargs, (long) is_cons));\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATE),\n\t                              DUK_BIDX_DATE_PROTOTYPE);\n\n\t/* Unlike most built-ins, the internal [[PrimitiveValue]] of a Date\n\t * is mutable.\n\t */\n\n\tif (nargs == 0 || !is_cons) {\n\t\td = duk__timeclip(duk_time_get_ecmascript_time_nofrac(thr));\n\t\tduk_push_number(thr, d);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\t\tif (!is_cons) {\n\t\t\t/* called as a normal function: return new Date().toString() */\n\t\t\tduk_to_string(thr, -1);\n\t\t}\n\t\treturn 1;\n\t} else if (nargs == 1) {\n\t\tconst char *str;\n\t\tduk_to_primitive(thr, 0, DUK_HINT_NONE);\n\t\tstr = duk_get_string_notsymbol(thr, 0);\n\t\tif (str) {\n\t\t\tduk__parse_string(thr, str);\n\t\t\tduk_replace(thr, 0);  /* may be NaN */\n\t\t}\n\t\td = duk__timeclip(duk_to_number(thr, 0));  /* symbols fail here */\n\t\tduk_push_number(thr, d);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\t\treturn 1;\n\t}\n\n\tduk__set_parts_from_args(thr, dparts, nargs);\n\n\t/* Parts are in local time, convert when setting. */\n\n\t(void) duk__set_this_timeval_from_dparts(thr, dparts, DUK_DATE_FLAG_LOCALTIME /*flags*/);  /* -> [ ... this timeval ] */\n\tduk_pop(thr);  /* -> [ ... this ] */\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor_parse(duk_hthread *thr) {\n\treturn duk__parse_string(thr, duk_to_string(thr, 0));\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor_utc(duk_hthread *thr) {\n\tduk_idx_t nargs = duk_get_top(thr);\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t d;\n\n\t/* Behavior for nargs < 2 is implementation dependent: currently we'll\n\t * set a NaN time value (matching V8 behavior) in this case.\n\t */\n\n\tif (nargs < 2) {\n\t\tduk_push_nan(thr);\n\t} else {\n\t\tduk__set_parts_from_args(thr, dparts, nargs);\n\t\td = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);\n\t\tduk_push_number(thr, d);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor_now(duk_hthread *thr) {\n\tduk_double_t d;\n\n\td = duk_time_get_ecmascript_time_nofrac(thr);\n\tDUK_ASSERT(duk__timeclip(d) == d);  /* TimeClip() should never be necessary */\n\tduk_push_number(thr, d);\n\treturn 1;\n}\n\n/*\n *  String/JSON conversions\n *\n *  Human readable conversions are now basically ISO 8601 with a space\n *  (instead of 'T') as the date/time separator.  This is a good baseline\n *  and is platform independent.\n *\n *  A shared native helper to provide many conversions.  Magic value contains\n *  a set of flags.  The helper provides:\n *\n *    toString()\n *    toDateString()\n *    toTimeString()\n *    toLocaleString()\n *    toLocaleDateString()\n *    toLocaleTimeString()\n *    toUTCString()\n *    toISOString()\n *\n *  Notes:\n *\n *    - Date.prototype.toGMTString() and Date.prototype.toUTCString() are\n *      required to be the same ECMAScript function object (!), so it is\n *      omitted from here.\n *\n *    - Date.prototype.toUTCString(): E5.1 specification does not require a\n *      specific format, but result should be human readable.  The\n *      specification suggests using ISO 8601 format with a space (instead\n *      of 'T') separator if a more human readable format is not available.\n *\n *    - Date.prototype.toISOString(): unlike other conversion functions,\n *      toISOString() requires a RangeError for invalid date values.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_tostring_shared(duk_hthread *thr) {\n\tduk_small_uint_t flags = duk__date_get_indirect_magic(thr);\n\treturn duk__to_string_helper(thr, flags);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_value_of(duk_hthread *thr) {\n\t/* This native function is also used for Date.prototype.getTime()\n\t * as their behavior is identical.\n\t */\n\n\tduk_double_t d = duk__push_this_get_timeval(thr, 0 /*flags*/);  /* -> [ this ] */\n\tDUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));\n\tduk_push_number(thr, d);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_to_json(duk_hthread *thr) {\n\t/* Note: toJSON() is a generic function which works even if 'this'\n\t * is not a Date.  The sole argument is ignored.\n\t */\n\n\tduk_push_this(thr);\n\tduk_to_object(thr, -1);\n\n\tduk_dup_top(thr);\n\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);\n\tif (duk_is_number(thr, -1)) {\n\t\tduk_double_t d = duk_get_number(thr, -1);\n\t\tif (!DUK_ISFINITE(d)) {\n\t\t\tduk_push_null(thr);\n\t\t\treturn 1;\n\t\t}\n\t}\n\tduk_pop(thr);\n\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_ISO_STRING);\n\tduk_dup_m2(thr);  /* -> [ O toIsoString O ] */\n\tduk_call_method(thr, 0);\n\treturn 1;\n}\n\n/*\n *  Getters.\n *\n *  Implementing getters is quite easy.  The internal time value is either\n *  NaN, or represents milliseconds (without fractions) from Jan 1, 1970.\n *  The internal time value can be converted to integer parts, and each\n *  part will be normalized and will fit into a 32-bit signed integer.\n *\n *  A shared native helper to provide all getters.  Magic value contains\n *  a set of flags and also packs the date component index argument.  The\n *  helper provides:\n *\n *    getFullYear()\n *    getUTCFullYear()\n *    getMonth()\n *    getUTCMonth()\n *    getDate()\n *    getUTCDate()\n *    getDay()\n *    getUTCDay()\n *    getHours()\n *    getUTCHours()\n *    getMinutes()\n *    getUTCMinutes()\n *    getSeconds()\n *    getUTCSeconds()\n *    getMilliseconds()\n *    getUTCMilliseconds()\n *    getYear()\n *\n *  Notes:\n *\n *    - Date.prototype.getDate(): 'date' means day-of-month, and is\n *      zero-based in internal calculations but public API expects it to\n *      be one-based.\n *\n *    - Date.prototype.getTime() and Date.prototype.valueOf() have identical\n *      behavior.  They have separate function objects, but share the same C\n *      function (duk_bi_date_prototype_value_of).\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_shared(duk_hthread *thr) {\n\tduk_small_uint_t flags_and_idx = duk__date_get_indirect_magic(thr);\n\treturn duk__get_part_helper(thr, flags_and_idx);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_timezone_offset(duk_hthread *thr) {\n\t/*\n\t *  Return (t - LocalTime(t)) in minutes:\n\t *\n\t *    t - LocalTime(t) = t - (t + LocalTZA + DaylightSavingTA(t))\n\t *                     = -(LocalTZA + DaylightSavingTA(t))\n\t *\n\t *  where DaylightSavingTA() is checked for time 't'.\n\t *\n\t *  Note that the sign of the result is opposite to common usage,\n\t *  e.g. for EE(S)T which normally is +2h or +3h from UTC, this\n\t *  function returns -120 or -180.\n\t *\n\t */\n\n\tduk_double_t d;\n\tduk_int_t tzoffset;\n\n\t/* Note: DST adjustment is determined using UTC time. */\n\td = duk__push_this_get_timeval(thr, 0 /*flags*/);\n\tDUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));\n\tif (DUK_ISNAN(d)) {\n\t\tduk_push_nan(thr);\n\t} else {\n\t\tDUK_ASSERT(DUK_ISFINITE(d));\n\t\ttzoffset = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);\n\t\tduk_push_int(thr, -tzoffset / 60);\n\t}\n\treturn 1;\n}\n\n/*\n *  Setters.\n *\n *  Setters are a bit more complicated than getters.  Component setters\n *  break down the current time value into its (normalized) component\n *  parts, replace one or more components with -unnormalized- new values,\n *  and the components are then converted back into a time value.  As an\n *  example of using unnormalized values:\n *\n *    var d = new Date(1234567890);\n *\n *  is equivalent to:\n *\n *    var d = new Date(0);\n *    d.setUTCMilliseconds(1234567890);\n *\n *  A shared native helper to provide almost all setters.  Magic value\n *  contains a set of flags and also packs the \"maxnargs\" argument.  The\n *  helper provides:\n *\n *    setMilliseconds()\n *    setUTCMilliseconds()\n *    setSeconds()\n *    setUTCSeconds()\n *    setMinutes()\n *    setUTCMinutes()\n *    setHours()\n *    setUTCHours()\n *    setDate()\n *    setUTCDate()\n *    setMonth()\n *    setUTCMonth()\n *    setFullYear()\n *    setUTCFullYear()\n *    setYear()\n *\n *  Notes:\n *\n *    - Date.prototype.setYear() (Section B addition): special year check\n *      is omitted.  NaN / Infinity will just flow through and ultimately\n *      result in a NaN internal time value.\n *\n *    - Date.prototype.setYear() does not have optional arguments for\n *      setting month and day-in-month (like setFullYear()), but we indicate\n *      'maxnargs' to be 3 to get the year written to the correct component\n *      index in duk__set_part_helper().  The function has nargs == 1, so only\n *      the year will be set regardless of actual argument count.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_shared(duk_hthread *thr) {\n\tduk_small_uint_t flags_and_maxnargs = duk__date_get_indirect_magic(thr);\n\treturn duk__set_part_helper(thr, flags_and_maxnargs);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_time(duk_hthread *thr) {\n\tduk_double_t d;\n\n\t(void) duk__push_this_get_timeval(thr, 0 /*flags*/); /* -> [ timeval this ] */\n\td = duk__timeclip(duk_to_number(thr, 0));\n\tduk_push_number(thr, d);\n\tduk_dup_top(thr);\n\t/* Must force write because .setTime() must work even when\n\t * the Date instance is frozen.\n\t */\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\t/* -> [ timeval this timeval ] */\n\n\treturn 1;\n}\n\n/*\n *  Misc.\n */\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_toprimitive(duk_hthread *thr) {\n\tduk_size_t hintlen;\n\tconst char *hintstr;\n\tduk_int_t hint;\n\n\t/* Invokes OrdinaryToPrimitive() with suitable hint.  Note that the\n\t * method is generic, and works on non-Date arguments too.\n\t *\n\t * https://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype-@@toprimitive\n\t */\n\n\tduk_push_this(thr);\n\tduk_require_object(thr, -1);\n\tDUK_ASSERT_TOP(thr, 2);\n\n\thintstr = duk_require_lstring(thr, 0, &hintlen);\n\tif ((hintlen == 6 && DUK_STRCMP(hintstr, \"string\") == 0) ||\n\t    (hintlen == 7 && DUK_STRCMP(hintstr, \"default\") == 0)) {\n\t\thint = DUK_HINT_STRING;\n\t} else if (hintlen == 6 && DUK_STRCMP(hintstr, \"number\") == 0) {\n\t\thint = DUK_HINT_NUMBER;\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tduk_to_primitive_ordinary(thr, -1, hint);\n\treturn 1;\n}\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n\n#endif  /* DUK_USE_DATE_BUILTIN */\n\n/* automatic undefs */\n#undef DUK__CF_ACCEPT\n#undef DUK__CF_ACCEPT_NUL\n#undef DUK__CF_NEG\n#undef DUK__DPRINT_DPARTS\n#undef DUK__DPRINT_PARTS\n#undef DUK__DPRINT_PARTS_AND_DPARTS\n#undef DUK__LOCAL_TZOFFSET_MAXITER\n#undef DUK__NUM_ISO8601_PARSER_PARTS\n#undef DUK__PACK_RULE\n#undef DUK__PI_DAY\n#undef DUK__PI_HOUR\n#undef DUK__PI_MILLISECOND\n#undef DUK__PI_MINUTE\n#undef DUK__PI_MONTH\n#undef DUK__PI_SECOND\n#undef DUK__PI_TZHOUR\n#undef DUK__PI_TZMINUTE\n#undef DUK__PI_YEAR\n#undef DUK__PM_DAY\n#undef DUK__PM_HOUR\n#undef DUK__PM_MILLISECOND\n#undef DUK__PM_MINUTE\n#undef DUK__PM_MONTH\n#undef DUK__PM_SECOND\n#undef DUK__PM_TZHOUR\n#undef DUK__PM_TZMINUTE\n#undef DUK__PM_YEAR\n#undef DUK__RULE_MASK_PART_SEP\n#undef DUK__SI_COLON\n#undef DUK__SI_MINUS\n#undef DUK__SI_NUL\n#undef DUK__SI_PERIOD\n#undef DUK__SI_PLUS\n#undef DUK__SI_SPACE\n#undef DUK__SI_T\n#undef DUK__SI_Z\n#undef DUK__SM_COLON\n#undef DUK__SM_MINUS\n#undef DUK__SM_NUL\n#undef DUK__SM_PERIOD\n#undef DUK__SM_PLUS\n#undef DUK__SM_SPACE\n#undef DUK__SM_T\n#undef DUK__SM_Z\n#undef DUK__UNPACK_RULE\n#undef DUK__WEEKDAY_MOD_ADDER\n#undef DUK__YEAR\n#line 1 \"duk_bi_date_unix.c\"\n/*\n *  Unix-like Date providers\n *\n *  Generally useful Unix / POSIX / ANSI Date providers.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* The necessary #includes are in place in duk_config.h. */\n\n/* Buffer sizes for some UNIX calls.  Larger than strictly necessary\n * to avoid Valgrind errors.\n */\n#define DUK__STRPTIME_BUF_SIZE  64\n#define DUK__STRFTIME_BUF_SIZE  64\n\n#if defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)\n/* Get current ECMAScript time (= UNIX/Posix time, but in milliseconds). */\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_gettimeofday(void) {\n\tstruct timeval tv;\n\tduk_double_t d;\n\n\tif (gettimeofday(&tv, NULL) != 0) {\n\t\tDUK_D(DUK_DPRINT(\"gettimeofday() failed\"));\n\t\treturn 0.0;\n\t}\n\n\t/* As of Duktape 2.2.0 allow fractions. */\n\td = ((duk_double_t) tv.tv_sec) * 1000.0 +\n\t    ((duk_double_t) tv.tv_usec) / 1000.0;\n\n\treturn d;\n}\n#endif  /* DUK_USE_DATE_NOW_GETTIMEOFDAY */\n\n#if defined(DUK_USE_DATE_NOW_TIME)\n/* Not a very good provider: only full seconds are available. */\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_time(void) {\n\ttime_t t;\n\n\tt = time(NULL);\n\tif (t == (time_t) -1) {\n\t\tDUK_D(DUK_DPRINT(\"time() failed\"));\n\t\treturn 0.0;\n\t}\n\treturn ((duk_double_t) t) * 1000.0;\n}\n#endif  /* DUK_USE_DATE_NOW_TIME */\n\n#if defined(DUK_USE_DATE_TZO_GMTIME) || defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S)\n/* Get local time offset (in seconds) for a certain (UTC) instant 'd'. */\nDUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d) {\n\ttime_t t, t1, t2;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tstruct tm tms[2];\n#if defined(DUK_USE_DATE_TZO_GMTIME)\n\tstruct tm *tm_ptr;\n#endif\n\n\t/* For NaN/inf, the return value doesn't matter. */\n\tif (!DUK_ISFINITE(d)) {\n\t\treturn 0;\n\t}\n\n\t/* If not within ECMAScript range, some integer time calculations\n\t * won't work correctly (and some asserts will fail), so bail out\n\t * if so.  This fixes test-bug-date-insane-setyear.js.  There is\n\t * a +/- 24h leeway in this range check to avoid a test262 corner\n\t * case documented in test-bug-date-timeval-edges.js.\n\t */\n\tif (!duk_bi_date_timeval_in_leeway_range(d)) {\n\t\tDUK_DD(DUK_DDPRINT(\"timeval not within valid range, skip tzoffset computation to avoid integer overflows\"));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  This is a bit tricky to implement portably.  The result depends\n\t *  on the timestamp (specifically, DST depends on the timestamp).\n\t *  If e.g. UNIX APIs are used, they'll have portability issues with\n\t *  very small and very large years.\n\t *\n\t *  Current approach:\n\t *\n\t *  - Stay within portable UNIX limits by using equivalent year mapping.\n\t *    Avoid year 1970 and 2038 as some conversions start to fail, at\n\t *    least on some platforms.  Avoiding 1970 means that there are\n\t *    currently DST discrepancies for 1970.\n\t *\n\t *  - Create a UTC and local time breakdowns from 't'.  Then create\n\t *    a time_t using gmtime() and localtime() and compute the time\n\t *    difference between the two.\n\t *\n\t *  Equivalent year mapping (E5 Section 15.9.1.8):\n\t *\n\t *    If the host environment provides functionality for determining\n\t *    daylight saving time, the implementation of ECMAScript is free\n\t *    to map the year in question to an equivalent year (same\n\t *    leap-year-ness and same starting week day for the year) for which\n\t *    the host environment provides daylight saving time information.\n\t *    The only restriction is that all equivalent years should produce\n\t *    the same result.\n\t *\n\t *  This approach is quite reasonable but not entirely correct, e.g.\n\t *  the specification also states (E5 Section 15.9.1.8):\n\t *\n\t *    The implementation of ECMAScript should not try to determine\n\t *    whether the exact time was subject to daylight saving time, but\n\t *    just whether daylight saving time would have been in effect if\n\t *    the _current daylight saving time algorithm_ had been used at the\n\t *    time.  This avoids complications such as taking into account the\n\t *    years that the locale observed daylight saving time year round.\n\t *\n\t *  Since we rely on the platform APIs for conversions between local\n\t *  time and UTC, we can't guarantee the above.  Rather, if the platform\n\t *  has historical DST rules they will be applied.  This seems to be the\n\t *  general preferred direction in ECMAScript standardization (or at least\n\t *  implementations) anyway, and even the equivalent year mapping should\n\t *  be disabled if the platform is known to handle DST properly for the\n\t *  full ECMAScript range.\n\t *\n\t *  The following has useful discussion and links:\n\t *\n\t *    https://bugzilla.mozilla.org/show_bug.cgi?id=351066\n\t */\n\n\tduk_bi_date_timeval_to_parts(d, parts, dparts, DUK_DATE_FLAG_EQUIVYEAR /*flags*/);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_YEAR] >= 1970 && parts[DUK_DATE_IDX_YEAR] <= 2038);\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);\n\tDUK_ASSERT(d >= 0 && d < 2147483648.0 * 1000.0);  /* unsigned 31-bit range */\n\tt = (time_t) (d / 1000.0);\n\tDUK_DDD(DUK_DDDPRINT(\"timeval: %lf -> time_t %ld\", (double) d, (long) t));\n\n\tduk_memzero((void *) tms, sizeof(struct tm) * 2);\n\n#if defined(DUK_USE_DATE_TZO_GMTIME_R)\n\t(void) gmtime_r(&t, &tms[0]);\n\t(void) localtime_r(&t, &tms[1]);\n#elif defined(DUK_USE_DATE_TZO_GMTIME_S)\n\t(void) gmtime_s(&t, &tms[0]);\n\t(void) localtime_s(&t, &tms[1]);\n#elif defined(DUK_USE_DATE_TZO_GMTIME)\n\ttm_ptr = gmtime(&t);\n\tduk_memcpy((void *) &tms[0], tm_ptr, sizeof(struct tm));\n\ttm_ptr = localtime(&t);\n\tduk_memcpy((void *) &tms[1], tm_ptr, sizeof(struct tm));\n#else\n#error internal error\n#endif\n\tDUK_DDD(DUK_DDDPRINT(\"gmtime result: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,\"\n\t                     \"wday:%ld,yday:%ld,isdst:%ld}\",\n\t                     (long) tms[0].tm_sec, (long) tms[0].tm_min, (long) tms[0].tm_hour,\n\t                     (long) tms[0].tm_mday, (long) tms[0].tm_mon, (long) tms[0].tm_year,\n\t                     (long) tms[0].tm_wday, (long) tms[0].tm_yday, (long) tms[0].tm_isdst));\n\tDUK_DDD(DUK_DDDPRINT(\"localtime result: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,\"\n\t                     \"wday:%ld,yday:%ld,isdst:%ld}\",\n\t                     (long) tms[1].tm_sec, (long) tms[1].tm_min, (long) tms[1].tm_hour,\n\t                     (long) tms[1].tm_mday, (long) tms[1].tm_mon, (long) tms[1].tm_year,\n\t                     (long) tms[1].tm_wday, (long) tms[1].tm_yday, (long) tms[1].tm_isdst));\n\n\t/* tm_isdst is both an input and an output to mktime(), use 0 to\n\t * avoid DST handling in mktime():\n\t * - https://github.com/svaarala/duktape/issues/406\n\t * - http://stackoverflow.com/questions/8558919/mktime-and-tm-isdst\n\t */\n\ttms[0].tm_isdst = 0;\n\ttms[1].tm_isdst = 0;\n\tt1 = mktime(&tms[0]);  /* UTC */\n\tt2 = mktime(&tms[1]);  /* local */\n\tif (t1 == (time_t) -1 || t2 == (time_t) -1) {\n\t\t/* This check used to be for (t < 0) but on some platforms\n\t\t * time_t is unsigned and apparently the proper way to detect\n\t\t * an mktime() error return is the cast above.  See e.g.:\n\t\t * http://pubs.opengroup.org/onlinepubs/009695299/functions/mktime.html\n\t\t */\n\t\tgoto mktime_error;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"t1=%ld (utc), t2=%ld (local)\", (long) t1, (long) t2));\n\n\t/* Compute final offset in seconds, positive if local time ahead of\n\t * UTC (returned value is UTC-to-local offset).\n\t *\n\t * difftime() returns a double, so coercion to int generates quite\n\t * a lot of code.  Direct subtraction is not portable, however.\n\t * XXX: allow direct subtraction on known platforms.\n\t */\n#if 0\n\treturn (duk_int_t) (t2 - t1);\n#endif\n\treturn (duk_int_t) difftime(t2, t1);\n\n mktime_error:\n\t/* XXX: return something more useful, so that caller can throw? */\n\tDUK_D(DUK_DPRINT(\"mktime() failed, d=%lf\", (double) d));\n\treturn 0;\n}\n#endif  /* DUK_USE_DATE_TZO_GMTIME */\n\n#if defined(DUK_USE_DATE_PRS_STRPTIME)\nDUK_INTERNAL duk_bool_t duk_bi_date_parse_string_strptime(duk_hthread *thr, const char *str) {\n\tstruct tm tm;\n\ttime_t t;\n\tchar buf[DUK__STRPTIME_BUF_SIZE];\n\n\t/* Copy to buffer with slack to avoid Valgrind gripes from strptime. */\n\tDUK_ASSERT(str != NULL);\n\tduk_memzero(buf, sizeof(buf));  /* valgrind whine without this */\n\tDUK_SNPRINTF(buf, sizeof(buf), \"%s\", (const char *) str);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parsing: '%s'\", (const char *) buf));\n\n\tduk_memzero(&tm, sizeof(tm));\n\tif (strptime((const char *) buf, \"%c\", &tm) != NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"before mktime: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,\"\n\t\t                     \"wday:%ld,yday:%ld,isdst:%ld}\",\n\t\t                     (long) tm.tm_sec, (long) tm.tm_min, (long) tm.tm_hour,\n\t\t                     (long) tm.tm_mday, (long) tm.tm_mon, (long) tm.tm_year,\n\t\t                     (long) tm.tm_wday, (long) tm.tm_yday, (long) tm.tm_isdst));\n\t\ttm.tm_isdst = -1;  /* negative: dst info not available */\n\n\t\tt = mktime(&tm);\n\t\tDUK_DDD(DUK_DDDPRINT(\"mktime() -> %ld\", (long) t));\n\t\tif (t >= 0) {\n\t\t\tduk_push_number(thr, ((duk_double_t) t) * 1000.0);\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n#endif  /* DUK_USE_DATE_PRS_STRPTIME */\n\n#if defined(DUK_USE_DATE_PRS_GETDATE)\nDUK_INTERNAL duk_bool_t duk_bi_date_parse_string_getdate(duk_hthread *thr, const char *str) {\n\tstruct tm tm;\n\tduk_small_int_t rc;\n\ttime_t t;\n\n\t/* For this to work, DATEMSK must be set, so this is not very\n\t * convenient for an embeddable interpreter.\n\t */\n\n\tduk_memzero(&tm, sizeof(struct tm));\n\trc = (duk_small_int_t) getdate_r(str, &tm);\n\tDUK_DDD(DUK_DDDPRINT(\"getdate_r() -> %ld\", (long) rc));\n\n\tif (rc == 0) {\n\t\tt = mktime(&tm);\n\t\tDUK_DDD(DUK_DDDPRINT(\"mktime() -> %ld\", (long) t));\n\t\tif (t >= 0) {\n\t\t\tduk_push_number(thr, (duk_double_t) t);\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n#endif  /* DUK_USE_DATE_PRS_GETDATE */\n\n#if defined(DUK_USE_DATE_FMT_STRFTIME)\nDUK_INTERNAL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags) {\n\tchar buf[DUK__STRFTIME_BUF_SIZE];\n\tstruct tm tm;\n\tconst char *fmt;\n\n\tDUK_UNREF(tzoffset);\n\n\t/* If the platform doesn't support the entire ECMAScript range, we need\n\t * to return 0 so that the caller can fall back to the default formatter.\n\t *\n\t * For now, assume that if time_t is 8 bytes or more, the whole ECMAScript\n\t * range is supported.  For smaller time_t values (4 bytes in practice),\n\t * assumes that the signed 32-bit range is supported.\n\t *\n\t * XXX: detect this more correctly per platform.  The size of time_t is\n\t * probably not an accurate guarantee of strftime() supporting or not\n\t * supporting a large time range (the full ECMAScript range).\n\t */\n\tif (sizeof(time_t) < 8 &&\n\t    (parts[DUK_DATE_IDX_YEAR] < 1970 || parts[DUK_DATE_IDX_YEAR] > 2037)) {\n\t\t/* be paranoid for 32-bit time values (even avoiding negative ones) */\n\t\treturn 0;\n\t}\n\n\tduk_memzero(&tm, sizeof(tm));\n\ttm.tm_sec = parts[DUK_DATE_IDX_SECOND];\n\ttm.tm_min = parts[DUK_DATE_IDX_MINUTE];\n\ttm.tm_hour = parts[DUK_DATE_IDX_HOUR];\n\ttm.tm_mday = parts[DUK_DATE_IDX_DAY];       /* already one-based */\n\ttm.tm_mon = parts[DUK_DATE_IDX_MONTH] - 1;  /* one-based -> zero-based */\n\ttm.tm_year = parts[DUK_DATE_IDX_YEAR] - 1900;\n\ttm.tm_wday = parts[DUK_DATE_IDX_WEEKDAY];\n\ttm.tm_isdst = 0;\n\n\tduk_memzero(buf, sizeof(buf));\n\tif ((flags & DUK_DATE_FLAG_TOSTRING_DATE) && (flags & DUK_DATE_FLAG_TOSTRING_TIME)) {\n\t\tfmt = \"%c\";\n\t} else if (flags & DUK_DATE_FLAG_TOSTRING_DATE) {\n\t\tfmt = \"%x\";\n\t} else {\n\t\tDUK_ASSERT(flags & DUK_DATE_FLAG_TOSTRING_TIME);\n\t\tfmt = \"%X\";\n\t}\n\t(void) strftime(buf, sizeof(buf) - 1, fmt, &tm);\n\tDUK_ASSERT(buf[sizeof(buf) - 1] == 0);\n\n\tduk_push_string(thr, buf);\n\treturn 1;\n}\n#endif  /* DUK_USE_DATE_FMT_STRFTIME */\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)\nDUK_INTERNAL duk_double_t duk_bi_date_get_monotonic_time_clock_gettime(void) {\n\tstruct timespec ts;\n\n\tif (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {\n\t\treturn (duk_double_t) ts.tv_sec * 1000.0 + (duk_double_t) ts.tv_nsec / 1000000.0;\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"clock_gettime(CLOCK_MONOTONIC) failed\"));\n\t\treturn 0.0;\n\t}\n}\n#endif\n\n/* automatic undefs */\n#undef DUK__STRFTIME_BUF_SIZE\n#undef DUK__STRPTIME_BUF_SIZE\n#line 1 \"duk_bi_date_windows.c\"\n/*\n *  Windows Date providers\n *\n *  Platform specific links:\n *\n *    - http://msdn.microsoft.com/en-us/library/windows/desktop/ms725473(v=vs.85).aspx\n */\n\n/* #include duk_internal.h -> already included */\n\n/* The necessary #includes are in place in duk_config.h. */\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS) || defined(DUK_USE_DATE_TZO_WINDOWS)\n/* Shared Windows helpers. */\nDUK_LOCAL void duk__convert_systime_to_ularge(const SYSTEMTIME *st, ULARGE_INTEGER *res) {\n\tFILETIME ft;\n\tif (SystemTimeToFileTime(st, &ft) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"SystemTimeToFileTime() failed, returning 0\"));\n\t\tres->QuadPart = 0;\n\t} else {\n\t\tres->LowPart = ft.dwLowDateTime;\n\t\tres->HighPart = ft.dwHighDateTime;\n\t}\n}\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\nDUK_LOCAL void duk__convert_filetime_to_ularge(const FILETIME *ft, ULARGE_INTEGER *res) {\n\tres->LowPart = ft->dwLowDateTime;\n\tres->HighPart = ft->dwHighDateTime;\n}\n#endif  /* DUK_USE_DATE_NOW_WINDOWS_SUBMS */\n\nDUK_LOCAL void duk__set_systime_jan1970(SYSTEMTIME *st) {\n\tduk_memzero((void *) st, sizeof(*st));\n\tst->wYear = 1970;\n\tst->wMonth = 1;\n\tst->wDayOfWeek = 4;  /* not sure whether or not needed; Thursday */\n\tst->wDay = 1;\n\tDUK_ASSERT(st->wHour == 0);\n\tDUK_ASSERT(st->wMinute == 0);\n\tDUK_ASSERT(st->wSecond == 0);\n\tDUK_ASSERT(st->wMilliseconds == 0);\n}\n#endif  /* defined(DUK_USE_DATE_NOW_WINDOWS) || defined(DUK_USE_DATE_TZO_WINDOWS) */\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS)\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_windows(void) {\n\t/* Suggested step-by-step method from documentation of RtlTimeToSecondsSince1970:\n\t * http://msdn.microsoft.com/en-us/library/windows/desktop/ms724928(v=vs.85).aspx\n\t */\n\tSYSTEMTIME st1, st2;\n\tULARGE_INTEGER tmp1, tmp2;\n\n\tGetSystemTime(&st1);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1);\n\n\tduk__set_systime_jan1970(&st2);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);\n\n\t/* Difference is in 100ns units, convert to milliseconds, keeping\n\t * fractions since Duktape 2.2.0.  This is only theoretical because\n\t * SYSTEMTIME is limited to milliseconds.\n\t */\n\treturn (duk_double_t) ((LONGLONG) tmp1.QuadPart - (LONGLONG) tmp2.QuadPart) / 10000.0;\n}\n#endif  /* DUK_USE_DATE_NOW_WINDOWS */\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_windows_subms(void) {\n\t/* Variant of the basic algorithm using GetSystemTimePreciseAsFileTime()\n\t * for more accuracy.\n\t */\n\tFILETIME ft1;\n\tSYSTEMTIME st2;\n\tULARGE_INTEGER tmp1, tmp2;\n\n\tGetSystemTimePreciseAsFileTime(&ft1);\n\tduk__convert_filetime_to_ularge((const FILETIME *) &ft1, &tmp1);\n\n\tduk__set_systime_jan1970(&st2);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);\n\n\t/* Difference is in 100ns units, convert to milliseconds, keeping\n\t * fractions since Duktape 2.2.0.\n\t */\n\treturn (duk_double_t) ((LONGLONG) tmp1.QuadPart - (LONGLONG) tmp2.QuadPart) / 10000.0;\n}\n#endif  /* DUK_USE_DATE_NOW_WINDOWS */\n\n#if defined(DUK_USE_DATE_TZO_WINDOWS)\nDUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d) {\n\tSYSTEMTIME st1;\n\tSYSTEMTIME st2;\n\tSYSTEMTIME st3;\n\tULARGE_INTEGER tmp1;\n\tULARGE_INTEGER tmp2;\n\tULARGE_INTEGER tmp3;\n\tFILETIME ft1;\n\n\t/* XXX: handling of timestamps outside Windows supported range.\n\t * How does Windows deal with dates before 1600?  Does windows\n\t * support all ECMAScript years (like -200000 and +200000)?\n\t * Should equivalent year mapping be used here too?  If so, use\n\t * a shared helper (currently integrated into timeval-to-parts).\n\t */\n\n\t/* Use the approach described in \"Remarks\" of FileTimeToLocalFileTime:\n\t * http://msdn.microsoft.com/en-us/library/windows/desktop/ms724277(v=vs.85).aspx\n\t */\n\n\tduk__set_systime_jan1970(&st1);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1);\n\ttmp2.QuadPart = (ULONGLONG) (d * 10000.0);  /* millisec -> 100ns units since jan 1, 1970 */\n\ttmp2.QuadPart += tmp1.QuadPart;             /* input 'd' in Windows UTC, 100ns units */\n\n\tft1.dwLowDateTime = tmp2.LowPart;\n\tft1.dwHighDateTime = tmp2.HighPart;\n\tif (FileTimeToSystemTime((const FILETIME *) &ft1, &st2) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"FileTimeToSystemTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tif (SystemTimeToTzSpecificLocalTime((LPTIME_ZONE_INFORMATION) NULL, &st2, &st3) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"SystemTimeToTzSpecificLocalTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st3, &tmp3);\n\n\t/* Positive if local time ahead of UTC. */\n\treturn (duk_int_t) (((LONGLONG) tmp3.QuadPart - (LONGLONG) tmp2.QuadPart) / DUK_I64_CONSTANT(10000000));  /* seconds */\n}\n#endif  /* DUK_USE_DATE_TZO_WINDOWS */\n\n#if defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST)\nDUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_t d) {\n\tSYSTEMTIME st1;\n\tSYSTEMTIME st2;\n\tFILETIME ft1;\n\tFILETIME ft2;\n\tULARGE_INTEGER tmp1;\n\tULARGE_INTEGER tmp2;\n\n\t/* Do a similar computation to duk_bi_date_get_local_tzoffset_windows\n\t * but without accounting for daylight savings time.  Use this on\n\t * Windows platforms (like Durango) that don't support the\n\t * SystemTimeToTzSpecificLocalTime() call.\n\t */\n\n\t/* current time not needed for this computation */\n\tDUK_UNREF(d);\n\n\tduk__set_systime_jan1970(&st1);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1);\n\n\tft1.dwLowDateTime = tmp1.LowPart;\n\tft1.dwHighDateTime = tmp1.HighPart;\n\tif (FileTimeToLocalFileTime((const FILETIME *) &ft1, &ft2) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"FileTimeToLocalFileTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tif (FileTimeToSystemTime((const FILETIME *) &ft2, &st2) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"FileTimeToSystemTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);\n\n\treturn (duk_int_t) (((LONGLONG) tmp2.QuadPart - (LONGLONG) tmp1.QuadPart) / DUK_I64_CONSTANT(10000000));  /* seconds */\n}\n#endif  /* DUK_USE_DATE_TZO_WINDOWS_NO_DST */\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC)\nDUK_INTERNAL duk_double_t duk_bi_date_get_monotonic_time_windows_qpc(void) {\n\tLARGE_INTEGER count, freq;\n\n\t/* There are legacy issues with QueryPerformanceCounter():\n\t * - Potential jumps: https://support.microsoft.com/en-us/help/274323/performance-counter-value-may-unexpectedly-leap-forward\n\t * - Differences between cores (XP): https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx#qpc_support_in_windows_versions\n\t *\n\t * We avoid these by enabling QPC by default only for Vista or later.\n\t */\n\n\tif (QueryPerformanceCounter(&count) && QueryPerformanceFrequency(&freq)) {\n\t\t/* XXX: QueryPerformanceFrequency() can be cached */\n\t\treturn (duk_double_t) count.QuadPart / (duk_double_t) freq.QuadPart * 1000.0;\n\t} else {\n\t\t/* MSDN: \"On systems that run Windows XP or later, the function\n\t\t * will always succeed and will thus never return zero.\"\n\t\t * Provide minimal error path just in case user enables this\n\t\t * feature in pre-XP Windows.\n\t\t */\n\t\treturn 0.0;\n\t}\n}\n#endif  /* DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC */\n#line 1 \"duk_bi_duktape.c\"\n/*\n *  Duktape built-ins\n *\n *  Size optimization note: it might seem that vararg multipurpose functions\n *  like fin(), enc(), and dec() are not very size optimal, but using a single\n *  user-visible ECMAScript function saves a lot of run-time footprint; each\n *  Function instance takes >100 bytes.  Using a shared native helper and a\n *  'magic' value won't save much if there are multiple Function instances\n *  anyway.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_DUKTAPE_BUILTIN)\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_info(duk_hthread *thr) {\n\tduk_inspect_value(thr, -1);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_act(duk_hthread *thr) {\n\tduk_int_t level;\n\n\tlevel = duk_to_int(thr, 0);\n\tduk_inspect_callstack_entry(thr, level);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_gc(duk_hthread *thr) {\n\tduk_small_uint_t flags;\n\n\tflags = (duk_small_uint_t) duk_get_uint(thr, 0);\n\tduk_heap_mark_and_sweep(thr->heap, flags);\n\n\t/* XXX: Not sure what the best return value would be in the API.\n\t * Return true for now.\n\t */\n\tduk_push_true(thr);\n\treturn 1;\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_fin(duk_hthread *thr) {\n\t(void) duk_require_hobject(thr, 0);\n\tif (duk_get_top(thr) >= 2) {\n\t\t/* Set: currently a finalizer is disabled by setting it to\n\t\t * undefined; this does not remove the property at the moment.\n\t\t * The value could be type checked to be either a function\n\t\t * or something else; if something else, the property could\n\t\t * be deleted.  Must use duk_set_finalizer() to keep\n\t\t * DUK_HOBJECT_FLAG_HAVE_FINALIZER in sync.\n\t\t */\n\t\tduk_set_top(thr, 2);\n\t\tduk_set_finalizer(thr, 0);\n\t\treturn 0;\n\t} else {\n\t\t/* Get. */\n\t\tDUK_ASSERT(duk_get_top(thr) == 1);\n\t\tduk_get_finalizer(thr, 0);\n\t\treturn 1;\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_enc(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\t/* Vararg function: must be careful to check/require arguments.\n\t * The JSON helpers accept invalid indices and treat them like\n\t * non-existent optional parameters.\n\t */\n\n\th_str = duk_require_hstring(thr, 0);  /* Could reject symbols, but no point: won't match comparisons. */\n\tduk_require_valid_index(thr, 1);\n\n\tif (h_str == DUK_HTHREAD_STRING_HEX(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_hex_encode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t} else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_base64_encode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX)\n\t} else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {\n\t\tduk_bi_json_stringify_helper(thr,\n\t\t                             1 /*idx_value*/,\n\t\t                             2 /*idx_replacer*/,\n\t\t                             3 /*idx_space*/,\n\t\t                             DUK_JSON_FLAG_EXT_CUSTOM |\n\t\t                             DUK_JSON_FLAG_ASCII_ONLY |\n\t\t                             DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/);\n#endif\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC)\n\t} else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {\n\t\tduk_bi_json_stringify_helper(thr,\n\t\t                             1 /*idx_value*/,\n\t\t                             2 /*idx_replacer*/,\n\t\t                             3 /*idx_space*/,\n\t\t                             DUK_JSON_FLAG_EXT_COMPATIBLE |\n\t\t                             DUK_JSON_FLAG_ASCII_ONLY /*flags*/);\n#endif\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_dec(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\t/* Vararg function: must be careful to check/require arguments.\n\t * The JSON helpers accept invalid indices and treat them like\n\t * non-existent optional parameters.\n\t */\n\n\th_str = duk_require_hstring(thr, 0);  /* Could reject symbols, but no point: won't match comparisons */\n\tduk_require_valid_index(thr, 1);\n\n\tif (h_str == DUK_HTHREAD_STRING_HEX(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_hex_decode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t} else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_base64_decode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX)\n\t} else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {\n\t\tduk_bi_json_parse_helper(thr,\n\t\t                         1 /*idx_value*/,\n\t\t                         2 /*idx_replacer*/,\n\t\t                         DUK_JSON_FLAG_EXT_CUSTOM /*flags*/);\n#endif\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC)\n\t} else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {\n\t\tduk_bi_json_parse_helper(thr,\n\t\t                         1 /*idx_value*/,\n\t\t                         2 /*idx_replacer*/,\n\t\t                         DUK_JSON_FLAG_EXT_COMPATIBLE /*flags*/);\n#endif\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\treturn 1;\n}\n\n/*\n *  Compact an object\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_compact(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 1);\n\tduk_compact(thr, 0);\n\treturn 1;  /* return the argument object */\n}\n\n#endif  /* DUK_USE_DUKTAPE_BUILTIN */\n#line 1 \"duk_bi_encoding.c\"\n/*\n *  WHATWG Encoding API built-ins\n *\n *  API specification: https://encoding.spec.whatwg.org/#api\n *  Web IDL: https://www.w3.org/TR/WebIDL/\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Data structures for encoding/decoding\n */\n\ntypedef struct {\n\tduk_uint8_t *out;      /* where to write next byte(s) */\n\tduk_codepoint_t lead;  /* lead surrogate */\n} duk__encode_context;\n\ntypedef struct {\n\t/* UTF-8 decoding state */\n\tduk_codepoint_t codepoint;  /* built up incrementally */\n\tduk_uint8_t upper;          /* max value of next byte (decode error otherwise) */\n\tduk_uint8_t lower;          /* min value of next byte (ditto) */\n\tduk_uint8_t needed;         /* how many more bytes we need */\n\tduk_uint8_t bom_handled;    /* BOM seen or no longer expected */\n\n\t/* Decoder configuration */\n\tduk_uint8_t fatal;\n\tduk_uint8_t ignore_bom;\n} duk__decode_context;\n\n/* The signed duk_codepoint_t type is used to signal a decoded codepoint\n * (>= 0) or various other states using negative values.\n */\n#define DUK__CP_CONTINUE   (-1)  /* continue to next byte, no completed codepoint */\n#define DUK__CP_ERROR      (-2)  /* decoding error */\n#define DUK__CP_RETRY      (-3)  /* decoding error; retry last byte */\n\n/*\n *  Raw helpers for encoding/decoding\n */\n\n/* Emit UTF-8 (= CESU-8) encoded U+FFFD (replacement char), i.e. ef bf bd. */\nDUK_LOCAL duk_uint8_t *duk__utf8_emit_repl(duk_uint8_t *ptr) {\n\t*ptr++ = 0xef;\n\t*ptr++ = 0xbf;\n\t*ptr++ = 0xbd;\n\treturn ptr;\n}\n\nDUK_LOCAL void duk__utf8_decode_init(duk__decode_context *dec_ctx) {\n\t/* (Re)init the decoding state of 'dec_ctx' but leave decoder\n\t * configuration fields untouched.\n\t */\n\tdec_ctx->codepoint = 0x0000L;\n\tdec_ctx->upper = 0xbf;\n\tdec_ctx->lower = 0x80;\n\tdec_ctx->needed = 0;\n\tdec_ctx->bom_handled = 0;\n}\n\nDUK_LOCAL duk_codepoint_t duk__utf8_decode_next(duk__decode_context *dec_ctx, duk_uint8_t x) {\n\t/*\n\t *  UTF-8 algorithm based on the Encoding specification:\n\t *  https://encoding.spec.whatwg.org/#utf-8-decoder\n\t *\n\t *  Two main states: decoding initial byte vs. decoding continuation\n\t *  bytes.  Shortest length encoding is validated by restricting the\n\t *  allowed range of first continuation byte using 'lower' and 'upper'.\n\t */\n\n\tif (dec_ctx->needed == 0) {\n\t\t/* process initial byte */\n\t\tif (x <= 0x7f) {\n\t\t\t/* U+0000-U+007F, 1 byte (ASCII) */\n\t\t\treturn (duk_codepoint_t) x;\n\t\t} else if (x >= 0xc2 && x <= 0xdf) {\n\t\t\t/* U+0080-U+07FF, 2 bytes */\n\t\t\tdec_ctx->needed = 1;\n\t\t\tdec_ctx->codepoint = x & 0x1f;\n\t\t\tDUK_ASSERT(dec_ctx->lower == 0x80);\n\t\t\tDUK_ASSERT(dec_ctx->upper == 0xbf);\n\t\t\treturn DUK__CP_CONTINUE;\n\t\t} else if (x >= 0xe0 && x <= 0xef) {\n\t\t\t/* U+0800-U+FFFF, 3 bytes */\n\t\t\tif (x == 0xe0) {\n\t\t\t\tdec_ctx->lower = 0xa0;\n\t\t\t\tDUK_ASSERT(dec_ctx->upper == 0xbf);\n\t\t\t} else if (x == 0xed) {\n\t\t\t\tDUK_ASSERT(dec_ctx->lower == 0x80);\n\t\t\t\tdec_ctx->upper = 0x9f;\n\t\t\t}\n\t\t\tdec_ctx->needed = 2;\n\t\t\tdec_ctx->codepoint = x & 0x0f;\n\t\t\treturn DUK__CP_CONTINUE;\n\t\t} else if (x >= 0xf0 && x <= 0xf4) {\n\t\t\t/* U+010000-U+10FFFF, 4 bytes */\n\t\t\tif (x == 0xf0) {\n\t\t\t\tdec_ctx->lower = 0x90;\n\t\t\t\tDUK_ASSERT(dec_ctx->upper == 0xbf);\n\t\t\t} else if (x == 0xf4) {\n\t\t\t\tDUK_ASSERT(dec_ctx->lower == 0x80);\n\t\t\t\tdec_ctx->upper = 0x8f;\n\t\t\t}\n\t\t\tdec_ctx->needed = 3;\n\t\t\tdec_ctx->codepoint = x & 0x07;\n\t\t\treturn DUK__CP_CONTINUE;\n\t\t} else {\n\t\t\t/* not a legal initial byte */\n\t\t\treturn DUK__CP_ERROR;\n\t\t}\n\t} else {\n\t\t/* process continuation byte */\n\t\tif (x >= dec_ctx->lower && x <= dec_ctx->upper) {\n\t\t\tdec_ctx->lower = 0x80;\n\t\t\tdec_ctx->upper = 0xbf;\n\t\t\tdec_ctx->codepoint = (dec_ctx->codepoint << 6) | (x & 0x3f);\n\t\t\tif (--dec_ctx->needed > 0) {\n\t\t\t\t/* need more bytes */\n\t\t\t\treturn DUK__CP_CONTINUE;\n\t\t\t} else {\n\t\t\t\t/* got a codepoint */\n\t\t\t\tduk_codepoint_t ret;\n\t\t\t\tDUK_ASSERT(dec_ctx->codepoint <= 0x10ffffL);  /* Decoding rules guarantee. */\n\t\t\t\tret = dec_ctx->codepoint;\n\t\t\t\tdec_ctx->codepoint = 0x0000L;\n\t\t\t\tdec_ctx->needed = 0;\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} else {\n\t\t\t/* We just encountered an illegal UTF-8 continuation byte.  This might\n\t\t\t * be the initial byte of the next character; if we return a plain\n\t\t\t * error status and the decoder is in replacement mode, the character\n\t\t\t * will be masked.  We still need to alert the caller to the error\n\t\t\t * though.\n\t\t\t */\n\t\t\tdec_ctx->codepoint = 0x0000L;\n\t\t\tdec_ctx->needed = 0;\n\t\t\tdec_ctx->lower = 0x80;\n\t\t\tdec_ctx->upper = 0xbf;\n\t\t\treturn DUK__CP_RETRY;\n\t\t}\n\t}\n}\n\n#if defined(DUK_USE_ENCODING_BUILTINS)\nDUK_LOCAL void duk__utf8_encode_char(void *udata, duk_codepoint_t codepoint) {\n\tduk__encode_context *enc_ctx;\n\n\tDUK_ASSERT(codepoint >= 0);\n\tenc_ctx = (duk__encode_context *) udata;\n\tDUK_ASSERT(enc_ctx != NULL);\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\tif (codepoint <= 0x7f && enc_ctx->lead == 0x0000L) {\n\t\t/* Fast path for ASCII. */\n\t\t*enc_ctx->out++ = (duk_uint8_t) codepoint;\n\t\treturn;\n\t}\n#endif\n\n\tif (DUK_UNLIKELY(codepoint > 0x10ffffL)) {\n\t\t/* cannot legally encode in UTF-8 */\n\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t} else if (codepoint >= 0xd800L && codepoint <= 0xdfffL) {\n\t\tif (codepoint <= 0xdbffL) {\n\t\t\t/* high surrogate */\n\t\t\tduk_codepoint_t prev_lead = enc_ctx->lead;\n\t\t\tenc_ctx->lead = codepoint;\n\t\t\tif (prev_lead == 0x0000L) {\n\t\t\t\t/* high surrogate, no output */\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\t/* consecutive high surrogates, consider first one unpaired */\n\t\t\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\t}\n\t\t} else {\n\t\t\t/* low surrogate */\n\t\t\tif (enc_ctx->lead != 0x0000L) {\n\t\t\t\tcodepoint = (duk_codepoint_t) (0x010000L + ((enc_ctx->lead - 0xd800L) << 10) + (codepoint - 0xdc00L));\n\t\t\t\tenc_ctx->lead = 0x0000L;\n\t\t\t} else {\n\t\t\t\t/* unpaired low surrogate */\n\t\t\t\tDUK_ASSERT(enc_ctx->lead == 0x0000L);\n\t\t\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif (enc_ctx->lead != 0x0000L) {\n\t\t\t/* unpaired high surrogate: emit replacement character and the input codepoint */\n\t\t\tenc_ctx->lead = 0x0000L;\n\t\t\tenc_ctx->out = duk__utf8_emit_repl(enc_ctx->out);\n\t\t}\n\t}\n\n\t/* Codepoint may be original input, a decoded surrogate pair, or may\n\t * have been replaced with U+FFFD.\n\t */\n\tenc_ctx->out += duk_unicode_encode_xutf8((duk_ucodepoint_t) codepoint, enc_ctx->out);\n}\n#endif  /* DUK_USE_ENCODING_BUILTINS */\n\n/* Shared helper for buffer-to-string using a TextDecoder() compatible UTF-8\n * decoder.\n */\nDUK_LOCAL duk_ret_t duk__decode_helper(duk_hthread *thr, duk__decode_context *dec_ctx) {\n\tconst duk_uint8_t *input;\n\tduk_size_t len = 0;\n\tduk_size_t len_tmp;\n\tduk_bool_t stream = 0;\n\tduk_codepoint_t codepoint;\n\tduk_uint8_t *output;\n\tconst duk_uint8_t *in;\n\tduk_uint8_t *out;\n\n\tDUK_ASSERT(dec_ctx != NULL);\n\n\t/* Careful with input buffer pointer: any side effects involving\n\t * code execution (e.g. getters, coercion calls, and finalizers)\n\t * may cause a resize and invalidate a pointer we've read.  This\n\t * is why the pointer is actually looked up at the last minute.\n\t * Argument validation must still happen first to match WHATWG\n\t * required side effect order.\n\t */\n\n\tif (duk_is_undefined(thr, 0)) {\n\t\tduk_push_fixed_buffer_nozero(thr, 0);\n\t\tduk_replace(thr, 0);\n\t}\n\t(void) duk_require_buffer_data(thr, 0, &len);  /* Need 'len', avoid pointer. */\n\n\tif (duk_check_type_mask(thr, 1, DUK_TYPE_MASK_UNDEFINED |\n\t                                DUK_TYPE_MASK_NULL |\n\t                                DUK_TYPE_MASK_NONE)) {\n\t\t/* Use defaults, treat missing value like undefined. */\n\t} else {\n\t\tduk_require_type_mask(thr, 1, DUK_TYPE_MASK_UNDEFINED |\n\t                                      DUK_TYPE_MASK_NULL |\n\t                                      DUK_TYPE_MASK_LIGHTFUNC |\n\t                                      DUK_TYPE_MASK_BUFFER |\n\t\t                              DUK_TYPE_MASK_OBJECT);\n\t\tif (duk_get_prop_literal(thr, 1, \"stream\")) {\n\t\t\tstream = duk_to_boolean(thr, -1);\n\t\t}\n\t}\n\n\t/* Allowance is 3*len in the general case because all bytes may potentially\n\t * become U+FFFD.  If the first byte completes a non-BMP codepoint it will\n\t * decode to a CESU-8 surrogate pair (6 bytes) so we allow 3 extra bytes to\n\t * compensate: (1*3)+3 = 6.  Non-BMP codepoints are safe otherwise because\n\t * the 4->6 expansion is well under the 3x allowance.\n\t *\n\t * XXX: As with TextEncoder, need a better buffer allocation strategy here.\n\t */\n\tif (len >= (DUK_HBUFFER_MAX_BYTELEN / 3) - 3) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_RESULT_TOO_LONG);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\toutput = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, 3 + (3 * len));  /* used parts will be always manually written over */\n\n\tinput = (const duk_uint8_t *) duk_get_buffer_data(thr, 0, &len_tmp);\n\tDUK_ASSERT(input != NULL || len == 0);\n\tif (DUK_UNLIKELY(len != len_tmp)) {\n\t\t/* Very unlikely but possible: source buffer was resized by\n\t\t * a side effect when fixed buffer was pushed.  Output buffer\n\t\t * may not be large enough to hold output, so just fail if\n\t\t * length has changed.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"input buffer resized by side effect, fail\"));\n\t\tgoto fail_type;\n\t}\n\n\t/* From this point onwards it's critical that no side effect occur\n\t * which may disturb 'input': finalizer execution, property accesses,\n\t * active coercions, etc.  Even an allocation related mark-and-sweep\n\t * may affect the pointer because it may trigger a pending finalizer.\n\t */\n\n\tin = input;\n\tout = output;\n\twhile (in < input + len) {\n\t\tcodepoint = duk__utf8_decode_next(dec_ctx, *in++);\n\t\tif (codepoint < 0) {\n\t\t\tif (codepoint == DUK__CP_CONTINUE) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* Decoding error with or without retry. */\n\t\t\tDUK_ASSERT(codepoint == DUK__CP_ERROR || codepoint == DUK__CP_RETRY);\n\t\t\tif (codepoint == DUK__CP_RETRY) {\n\t\t\t\t--in;  /* retry last byte */\n\t\t\t}\n\t\t\t/* replacement mode: replace with U+FFFD */\n\t\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\tif (dec_ctx->fatal) {\n\t\t\t\t/* fatal mode: throw a TypeError */\n\t\t\t\tgoto fail_type;\n\t\t\t}\n\t\t\t/* Continue with 'codepoint', Unicode replacement. */\n\t\t}\n\t\tDUK_ASSERT(codepoint >= 0x0000L && codepoint <= 0x10ffffL);\n\n\t\tif (!dec_ctx->bom_handled) {\n\t\t\tdec_ctx->bom_handled = 1;\n\t\t\tif (codepoint == 0xfeffL && !dec_ctx->ignore_bom) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tout += duk_unicode_encode_cesu8((duk_ucodepoint_t) codepoint, out);\n\t\tDUK_ASSERT(out <= output + (3 + (3 * len)));\n\t}\n\n\tif (!stream) {\n\t\tif (dec_ctx->needed != 0) {\n\t\t\t/* truncated sequence at end of buffer */\n\t\t\tif (dec_ctx->fatal) {\n\t\t\t\tgoto fail_type;\n\t\t\t} else {\n\t\t\t\tout += duk_unicode_encode_cesu8(DUK_UNICODE_CP_REPLACEMENT_CHARACTER, out);\n\t\t\t\tDUK_ASSERT(out <= output + (3 + (3 * len)));\n\t\t\t}\n\t\t}\n\t\tduk__utf8_decode_init(dec_ctx);  /* Initialize decoding state for potential reuse. */\n\t}\n\n\t/* Output buffer is fixed and thus stable even if there had been\n\t * side effects (which there shouldn't be).\n\t */\n\tduk_push_lstring(thr, (const char *) output, (duk_size_t) (out - output));\n\treturn 1;\n\n fail_type:\n\tDUK_ERROR_TYPE(thr, DUK_STR_UTF8_DECODE_FAILED);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/*\n *  Built-in bindings\n */\n\n#if defined(DUK_USE_ENCODING_BUILTINS)\nDUK_INTERNAL duk_ret_t duk_bi_textencoder_constructor(duk_hthread *thr) {\n\t/* TextEncoder currently requires no persistent state, so the constructor\n\t * does nothing on purpose.\n\t */\n\n\tduk_require_constructor_call(thr);\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encoding_getter(duk_hthread *thr) {\n\tduk_push_literal(thr, \"utf-8\");\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encode(duk_hthread *thr) {\n\tduk__encode_context enc_ctx;\n\tduk_size_t len;\n\tduk_size_t final_len;\n\tduk_uint8_t *output;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tlen = 0;\n\t} else {\n\t\tduk_hstring *h_input;\n\n\t\th_input = duk_to_hstring(thr, 0);\n\t\tDUK_ASSERT(h_input != NULL);\n\n\t\tlen = (duk_size_t) DUK_HSTRING_GET_CHARLEN(h_input);\n\t\tif (len >= DUK_HBUFFER_MAX_BYTELEN / 3) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_RESULT_TOO_LONG);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t}\n\n\t/* Allowance is 3*len because all bytes can potentially be replaced with\n\t * U+FFFD -- which rather inconveniently encodes to 3 bytes in UTF-8.\n\t * Rely on dynamic buffer data pointer stability: no other code has\n\t * access to the data pointer.\n\t *\n\t * XXX: The buffer allocation strategy used here is rather inefficient.\n\t * Maybe switch to a chunk-based strategy, or preprocess the string to\n\t * figure out the space needed ahead of time?\n\t */\n\tDUK_ASSERT(3 * len >= len);\n\toutput = (duk_uint8_t *) duk_push_dynamic_buffer(thr, 3 * len);\n\n\tif (len > 0) {\n\t\tDUK_ASSERT(duk_is_string(thr, 0));  /* True if len > 0. */\n\n\t\t/* XXX: duk_decode_string() is used to process the input\n\t\t * string.  For standard ECMAScript strings, represented\n\t\t * internally as CESU-8, this is fine.  However, behavior\n\t\t * beyond CESU-8 is not very strict: codepoints using an\n\t\t * extended form of UTF-8 are also accepted, and invalid\n\t\t * codepoint sequences (which are allowed in Duktape strings)\n\t\t * are not handled as well as they could (e.g. invalid\n\t\t * continuation bytes may mask following codepoints).\n\t\t * This is how ECMAScript code would also see such strings.\n\t\t * Maybe replace duk_decode_string() with an explicit strict\n\t\t * CESU-8 decoder here?\n\t\t */\n\t\tenc_ctx.lead = 0x0000L;\n\t\tenc_ctx.out = output;\n\t\tduk_decode_string(thr, 0, duk__utf8_encode_char, (void *) &enc_ctx);\n\t\tif (enc_ctx.lead != 0x0000L) {\n\t\t\t/* unpaired high surrogate at end of string */\n\t\t\tenc_ctx.out = duk__utf8_emit_repl(enc_ctx.out);\n\t\t\tDUK_ASSERT(enc_ctx.out <= output + (3 * len));\n\t\t}\n\n\t\t/* The output buffer is usually very much oversized, so shrink it to\n\t\t * actually needed size.  Pointer stability assumed up to this point.\n\t\t */\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t\tDUK_ASSERT(output == (duk_uint8_t *) duk_get_buffer_data(thr, -1, NULL));\n\n\t\tfinal_len = (duk_size_t) (enc_ctx.out - output);\n\t\tduk_resize_buffer(thr, -1, final_len);\n\t\t/* 'output' and 'enc_ctx.out' are potentially invalidated by the resize. */\n\t} else {\n\t\tfinal_len = 0;\n\t}\n\n\t/* Standard WHATWG output is a Uint8Array.  Here the Uint8Array will\n\t * be backed by a dynamic buffer which differs from e.g. Uint8Arrays\n\t * created as 'new Uint8Array(N)'.  ECMAScript code won't see the\n\t * difference but C code will.  When bufferobjects are not supported,\n\t * returns a plain dynamic buffer.\n\t */\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tduk_push_buffer_object(thr, -1, 0, final_len, DUK_BUFOBJ_UINT8ARRAY);\n#endif\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textdecoder_constructor(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\tduk_bool_t fatal = 0;\n\tduk_bool_t ignore_bom = 0;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_require_constructor_call(thr);\n\tif (!duk_is_undefined(thr, 0)) {\n\t\t/* XXX: For now ignore 'label' (encoding identifier). */\n\t\tduk_to_string(thr, 0);\n\t}\n\tif (!duk_is_null_or_undefined(thr, 1)) {\n\t\tif (duk_get_prop_literal(thr, 1, \"fatal\")) {\n\t\t\tfatal = duk_to_boolean(thr, -1);\n\t\t}\n\t\tif (duk_get_prop_literal(thr, 1, \"ignoreBOM\")) {\n\t\t\tignore_bom = duk_to_boolean(thr, -1);\n\t\t}\n\t}\n\n\tduk_push_this(thr);\n\n\t/* The decode context is not assumed to be zeroed; all fields are\n\t * initialized explicitly.\n\t */\n\tdec_ctx = (duk__decode_context *) duk_push_fixed_buffer(thr, sizeof(duk__decode_context));\n\tdec_ctx->fatal = (duk_uint8_t) fatal;\n\tdec_ctx->ignore_bom = (duk_uint8_t) ignore_bom;\n\tduk__utf8_decode_init(dec_ctx);  /* Initializes remaining fields. */\n\n\tduk_put_prop_literal(thr, -2, DUK_INTERNAL_SYMBOL(\"Context\"));\n\treturn 0;\n}\n\n/* Get TextDecoder context from 'this'; leaves garbage on stack. */\nDUK_LOCAL duk__decode_context *duk__get_textdecoder_context(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\tduk_push_this(thr);\n\tduk_get_prop_literal(thr, -1, DUK_INTERNAL_SYMBOL(\"Context\"));\n\tdec_ctx = (duk__decode_context *) duk_require_buffer(thr, -1, NULL);\n\tDUK_ASSERT(dec_ctx != NULL);\n\treturn dec_ctx;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\tduk_int_t magic;\n\n\tdec_ctx = duk__get_textdecoder_context(thr);\n\tmagic = duk_get_current_magic(thr);\n\tswitch (magic) {\n\tcase 0:\n\t\t/* Encoding is now fixed, so _Context lookup is only needed to\n\t\t * validate the 'this' binding (TypeError if not TextDecoder-like).\n\t\t */\n\t\tduk_push_literal(thr, \"utf-8\");\n\t\tbreak;\n\tcase 1:\n\t\tduk_push_boolean(thr, dec_ctx->fatal);\n\t\tbreak;\n\tdefault:\n\t\tduk_push_boolean(thr, dec_ctx->ignore_bom);\n\t\tbreak;\n\t}\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\n\tdec_ctx = duk__get_textdecoder_context(thr);\n\treturn duk__decode_helper(thr, dec_ctx);\n}\n#endif  /* DUK_USE_ENCODING_BUILTINS */\n\n/*\n *  Internal helper for Node.js Buffer\n */\n\n/* Internal helper used for Node.js Buffer .toString().  Value stack convention\n * is currently odd: it mimics TextDecoder .decode() so that argument must be at\n * index 0, and decode options (not present for Buffer) at index 1.  Return value\n * is a Duktape/C function return value.\n */\nDUK_INTERNAL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_hthread *thr) {\n\tduk__decode_context dec_ctx;\n\n\tdec_ctx.fatal = 0;  /* use replacement chars */\n\tdec_ctx.ignore_bom = 1;  /* ignore BOMs (matches Node.js Buffer .toString()) */\n\tduk__utf8_decode_init(&dec_ctx);\n\n\treturn duk__decode_helper(thr, &dec_ctx);\n}\n\n/* automatic undefs */\n#undef DUK__CP_CONTINUE\n#undef DUK__CP_ERROR\n#undef DUK__CP_RETRY\n#line 1 \"duk_bi_error.c\"\n/*\n *  Error built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL duk_ret_t duk_bi_error_constructor_shared(duk_hthread *thr) {\n\t/* Behavior for constructor and non-constructor call is\n\t * the same except for augmenting the created error.  When\n\t * called as a constructor, the caller (duk_new()) will handle\n\t * augmentation; when called as normal function, we need to do\n\t * it here.\n\t */\n\n\tduk_small_int_t bidx_prototype = duk_get_current_magic(thr);\n\n\t/* same for both error and each subclass like TypeError */\n\tduk_uint_t flags_and_class = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                             DUK_HOBJECT_FLAG_FASTREFS |\n\t                             DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ERROR);\n\n\t(void) duk_push_object_helper(thr, flags_and_class, bidx_prototype);\n\n\t/* If message is undefined, the own property 'message' is not set at\n\t * all to save property space.  An empty message is inherited anyway.\n\t */\n\tif (!duk_is_undefined(thr, 0)) {\n\t\tduk_to_string(thr, 0);\n\t\tduk_dup_0(thr);  /* [ message error message ] */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);\n\t}\n\n\t/* Augment the error if called as a normal function.  __FILE__ and __LINE__\n\t * are not desirable in this case.\n\t */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tif (!duk_is_constructor_call(thr)) {\n\t\tduk_err_augment_error_create(thr, thr, NULL, 0, DUK_AUGMENT_FLAG_NOBLAME_FILELINE);\n\t}\n#endif\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_to_string(duk_hthread *thr) {\n\t/* XXX: optimize with more direct internal access */\n\n\tduk_push_this(thr);\n\t(void) duk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\n\t/* [ ... this ] */\n\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME);\n\tif (duk_is_undefined(thr, -1)) {\n\t\tduk_pop(thr);\n\t\tduk_push_literal(thr, \"Error\");\n\t} else {\n\t\tduk_to_string(thr, -1);\n\t}\n\n\t/* [ ... this name ] */\n\n\t/* XXX: Are steps 6 and 7 in E5 Section 15.11.4.4 duplicated by\n\t * accident or are they actually needed?  The first ToString()\n\t * could conceivably return 'undefined'.\n\t */\n\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE);\n\tif (duk_is_undefined(thr, -1)) {\n\t\tduk_pop(thr);\n\t\tduk_push_hstring_empty(thr);\n\t} else {\n\t\tduk_to_string(thr, -1);\n\t}\n\n\t/* [ ... this name message ] */\n\n\tif (duk_get_length(thr, -2) == 0) {\n\t\t/* name is empty -> return message */\n\t\treturn 1;\n\t}\n\tif (duk_get_length(thr, -1) == 0) {\n\t\t/* message is empty -> return name */\n\t\tduk_pop(thr);\n\t\treturn 1;\n\t}\n\tduk_push_literal(thr, \": \");\n\tduk_insert(thr, -2);  /* ... name ': ' message */\n\tduk_concat(thr, 3);\n\n\treturn 1;\n}\n\n#if defined(DUK_USE_TRACEBACKS)\n\n/*\n *  Traceback handling\n *\n *  The unified helper decodes the traceback and produces various requested\n *  outputs.  It should be optimized for size, and may leave garbage on stack,\n *  only the topmost return value matters.  For instance, traceback separator\n *  and decoded strings are pushed even when looking for filename only.\n *\n *  NOTE: although _Tracedata is an internal property, user code can currently\n *  write to the array (or replace it with something other than an array).\n *  The code below must tolerate arbitrary _Tracedata.  It can throw errors\n *  etc, but cannot cause a segfault or memory unsafe behavior.\n */\n\n/* constants arbitrary, chosen for small loads */\n#define DUK__OUTPUT_TYPE_TRACEBACK   (-1)\n#define DUK__OUTPUT_TYPE_FILENAME    0\n#define DUK__OUTPUT_TYPE_LINENUMBER  1\n\nDUK_LOCAL duk_ret_t duk__error_getter_helper(duk_hthread *thr, duk_small_int_t output_type) {\n\tduk_idx_t idx_td;\n\tduk_small_int_t i;  /* traceback depth fits into 16 bits */\n\tduk_small_int_t t;  /* stack type fits into 16 bits */\n\tduk_small_int_t count_func = 0;  /* traceback depth ensures fits into 16 bits */\n\tconst char *str_tailcall = \" tailcall\";\n\tconst char *str_strict = \" strict\";\n\tconst char *str_construct = \" construct\";\n\tconst char *str_prevyield = \" preventsyield\";\n\tconst char *str_directeval = \" directeval\";\n\tconst char *str_empty = \"\";\n\n\tDUK_ASSERT_TOP(thr, 0);  /* fixed arg count */\n\n\tduk_push_this(thr);\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_TRACEDATA);\n\tidx_td = duk_get_top_index(thr);\n\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_NEWLINE_4SPACE);\n\tduk_push_this(thr);\n\n\t/* [ ... this tracedata sep this ] */\n\n\t/* XXX: skip null filename? */\n\n\tif (duk_check_type(thr, idx_td, DUK_TYPE_OBJECT)) {\n\t\t/* Current tracedata contains 2 entries per callstack entry. */\n\t\tfor (i = 0; ; i += 2) {\n\t\t\tduk_int_t pc;\n\t\t\tduk_uint_t line;\n\t\t\tduk_uint_t flags;\n\t\t\tduk_double_t d;\n\t\t\tconst char *funcname;\n\t\t\tconst char *filename;\n\t\t\tduk_hobject *h_func;\n\t\t\tduk_hstring *h_name;\n\n\t\t\tduk_require_stack(thr, 5);\n\t\t\tduk_get_prop_index(thr, idx_td, (duk_uarridx_t) i);\n\t\t\tduk_get_prop_index(thr, idx_td, (duk_uarridx_t) (i + 1));\n\t\t\td = duk_to_number_m1(thr);\n\t\t\tpc = duk_double_to_int_t(DUK_FMOD(d, DUK_DOUBLE_2TO32));\n\t\t\tflags = duk_double_to_uint_t(DUK_FLOOR(d / DUK_DOUBLE_2TO32));\n\t\t\tt = (duk_small_int_t) duk_get_type(thr, -2);\n\n\t\t\tif (t == DUK_TYPE_OBJECT || t == DUK_TYPE_LIGHTFUNC) {\n\t\t\t\t/*\n\t\t\t\t *  ECMAScript/native function call or lightfunc call\n\t\t\t\t */\n\n\t\t\t\tcount_func++;\n\n\t\t\t\t/* [ ... v1(func) v2(pc+flags) ] */\n\n\t\t\t\t/* These may be systematically omitted by Duktape\n\t\t\t\t * with certain config options, but allow user to\n\t\t\t\t * set them on a case-by-case basis.\n\t\t\t\t */\n\t\t\t\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME);\n\t\t\t\tduk_get_prop_stridx_short(thr, -3, DUK_STRIDX_FILE_NAME);\n\n#if defined(DUK_USE_PC2LINE)\n\t\t\t\tline = (duk_uint_t) duk_hobject_pc2line_query(thr, -4, (duk_uint_fast32_t) pc);\n#else\n\t\t\t\tline = 0;\n#endif\n\n\t\t\t\t/* [ ... v1 v2 name filename ] */\n\n\t\t\t\t/* When looking for .fileName/.lineNumber, blame first\n\t\t\t\t * function which has a .fileName.\n\t\t\t\t */\n\t\t\t\tif (duk_is_string_notsymbol(thr, -1)) {\n\t\t\t\t\tif (output_type == DUK__OUTPUT_TYPE_FILENAME) {\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t} else if (output_type == DUK__OUTPUT_TYPE_LINENUMBER) {\n\t\t\t\t\t\tduk_push_uint(thr, line);\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* XXX: Change 'anon' handling here too, to use empty string for anonymous functions? */\n\t\t\t\t/* XXX: Could be improved by coercing to a readable duk_tval (especially string escaping) */\n\t\t\t\th_name = duk_get_hstring_notsymbol(thr, -2);  /* may be NULL */\n\t\t\t\tfuncname = (h_name == NULL || h_name == DUK_HTHREAD_STRING_EMPTY_STRING(thr)) ?\n\t\t\t\t           \"[anon]\" : (const char *) DUK_HSTRING_GET_DATA(h_name);\n\t\t\t\tfilename = duk_get_string_notsymbol(thr, -1);\n\t\t\t\tfilename = filename ? filename : \"\";\n\t\t\t\tDUK_ASSERT(funcname != NULL);\n\t\t\t\tDUK_ASSERT(filename != NULL);\n\n\t\t\t\th_func = duk_get_hobject(thr, -4);  /* NULL for lightfunc */\n\n\t\t\t\tif (h_func == NULL) {\n\t\t\t\t\tduk_push_sprintf(thr, \"at %s light%s%s%s%s%s\",\n\t\t\t\t\t                 (const char *) funcname,\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));\n\t\t\t\t} else if (DUK_HOBJECT_HAS_NATFUNC(h_func)) {\n\t\t\t\t\tduk_push_sprintf(thr, \"at %s (%s) native%s%s%s%s%s\",\n\t\t\t\t\t                 (const char *) funcname,\n\t\t\t\t\t                 (const char *) filename,\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));\n\t\t\t\t} else {\n\t\t\t\t\tduk_push_sprintf(thr, \"at %s (%s:%lu)%s%s%s%s%s\",\n\t\t\t\t\t                 (const char *) funcname,\n\t\t\t\t\t                 (const char *) filename,\n\t\t\t\t\t                 (unsigned long) line,\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));\n\t\t\t\t}\n\t\t\t\tduk_replace(thr, -5);   /* [ ... v1 v2 name filename str ] -> [ ... str v2 name filename ] */\n\t\t\t\tduk_pop_3(thr);         /* -> [ ... str ] */\n\t\t\t} else if (t == DUK_TYPE_STRING) {\n\t\t\t\tconst char *str_file;\n\n\t\t\t\t/*\n\t\t\t\t *  __FILE__ / __LINE__ entry, here 'pc' is line number directly.\n\t\t\t\t *  Sometimes __FILE__ / __LINE__ is reported as the source for\n\t\t\t\t *  the error (fileName, lineNumber), sometimes not.\n\t\t\t\t */\n\n\t\t\t\t/* [ ... v1(filename) v2(line+flags) ] */\n\n\t\t\t\t/* When looking for .fileName/.lineNumber, blame compilation\n\t\t\t\t * or C call site unless flagged not to do so.\n\t\t\t\t */\n\t\t\t\tif (!(flags & DUK_TB_FLAG_NOBLAME_FILELINE)) {\n\t\t\t\t\tif (output_type == DUK__OUTPUT_TYPE_FILENAME) {\n\t\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t} else if (output_type == DUK__OUTPUT_TYPE_LINENUMBER) {\n\t\t\t\t\t\tduk_push_int(thr, pc);\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* Tracedata is trusted but avoid any risk of using a NULL\n\t\t\t\t * for %s format because it has undefined behavior.  Symbols\n\t\t\t\t * don't need to be explicitly rejected as they pose no memory\n\t\t\t\t * safety issues.\n\t\t\t\t */\n\t\t\t\tstr_file = (const char *) duk_get_string(thr, -2);\n\t\t\t\tduk_push_sprintf(thr, \"at [anon] (%s:%ld) internal\",\n\t\t\t\t                 (const char *) (str_file ? str_file : \"null\"), (long) pc);\n\t\t\t\tduk_replace(thr, -3);  /* [ ... v1 v2 str ] -> [ ... str v2 ] */\n\t\t\t\tduk_pop(thr);          /* -> [ ... str ] */\n\t\t\t} else {\n\t\t\t\t/* unknown, ignore */\n\t\t\t\tduk_pop_2(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (count_func >= DUK_USE_TRACEBACK_DEPTH) {\n\t\t\t/* Possibly truncated; there is no explicit truncation\n\t\t\t * marker so this is the best we can do.\n\t\t\t */\n\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_BRACKETED_ELLIPSIS);\n\t\t}\n\t}\n\n\t/* [ ... this tracedata sep this str1 ... strN ] */\n\n\tif (output_type != DUK__OUTPUT_TYPE_TRACEBACK) {\n\t\treturn 0;\n\t} else {\n\t\t/* The 'this' after 'sep' will get ToString() coerced by\n\t\t * duk_join() automatically.  We don't want to do that\n\t\t * coercion when providing .fileName or .lineNumber (GH-254).\n\t\t */\n\t\tduk_join(thr, duk_get_top(thr) - (idx_td + 2) /*count, not including sep*/);\n\t\treturn 1;\n\t}\n}\n\n/* XXX: Output type could be encoded into native function 'magic' value to\n * save space.  For setters the stridx could be encoded into 'magic'.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter(duk_hthread *thr) {\n\treturn duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_TRACEBACK);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter(duk_hthread *thr) {\n\treturn duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_FILENAME);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_hthread *thr) {\n\treturn duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_LINENUMBER);\n}\n\n#else  /* DUK_USE_TRACEBACKS */\n\n/*\n *  Traceback handling when tracebacks disabled.\n *\n *  The fileName / lineNumber stubs are now necessary because built-in\n *  data will include the accessor properties in Error.prototype.  If those\n *  are removed for builds without tracebacks, these can also be removed.\n *  'stack' should still be present and produce a ToString() equivalent:\n *  this is useful for user code which prints a stacktrace and expects to\n *  see something useful.  A normal stacktrace also begins with a ToString()\n *  of the error so this makes sense.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter(duk_hthread *thr) {\n\t/* XXX: remove this native function and map 'stack' accessor\n\t * to the toString() implementation directly.\n\t */\n\treturn duk_bi_error_prototype_to_string(thr);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter(duk_hthread *thr) {\n\tDUK_UNREF(thr);\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_hthread *thr) {\n\tDUK_UNREF(thr);\n\treturn 0;\n}\n\n#endif  /* DUK_USE_TRACEBACKS */\n\nDUK_LOCAL duk_ret_t duk__error_setter_helper(duk_hthread *thr, duk_small_uint_t stridx_key) {\n\t/* Attempt to write 'stack', 'fileName', 'lineNumber' works as if\n\t * user code called Object.defineProperty() to create an overriding\n\t * own property.  This allows user code to overwrite .fileName etc\n\t * intuitively as e.g. \"err.fileName = 'dummy'\" as one might expect.\n\t * See https://github.com/svaarala/duktape/issues/387.\n\t */\n\n\tDUK_ASSERT_TOP(thr, 1);  /* fixed arg count: value */\n\n\tduk_push_this(thr);\n\tduk_push_hstring_stridx(thr, stridx_key);\n\tduk_dup_0(thr);\n\n\t/* [ ... obj key value ] */\n\n\tDUK_DD(DUK_DDPRINT(\"error setter: %!T %!T %!T\",\n\t                   duk_get_tval(thr, -3), duk_get_tval(thr, -2), duk_get_tval(thr, -1)));\n\n\tduk_def_prop(thr, -3, DUK_DEFPROP_HAVE_VALUE |\n\t                      DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE |\n\t                      DUK_DEFPROP_HAVE_ENUMERABLE | /*not enumerable*/\n\t                      DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE);\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_setter(duk_hthread *thr) {\n\treturn duk__error_setter_helper(thr, DUK_STRIDX_STACK);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_setter(duk_hthread *thr) {\n\treturn duk__error_setter_helper(thr, DUK_STRIDX_FILE_NAME);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_setter(duk_hthread *thr) {\n\treturn duk__error_setter_helper(thr, DUK_STRIDX_LINE_NUMBER);\n}\n\n/* automatic undefs */\n#undef DUK__OUTPUT_TYPE_FILENAME\n#undef DUK__OUTPUT_TYPE_LINENUMBER\n#undef DUK__OUTPUT_TYPE_TRACEBACK\n#line 1 \"duk_bi_function.c\"\n/*\n *  Function built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Needed even when Function built-in is disabled. */\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype(duk_hthread *thr) {\n\t/* ignore arguments, return undefined (E5 Section 15.3.4) */\n\tDUK_UNREF(thr);\n\treturn 0;\n}\n\n#if defined(DUK_USE_FUNCTION_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_function_constructor(duk_hthread *thr) {\n\tduk_hstring *h_sourcecode;\n\tduk_idx_t nargs;\n\tduk_idx_t i;\n\tduk_small_uint_t comp_flags;\n\tduk_hcompfunc *func;\n\tduk_hobject *outer_lex_env;\n\tduk_hobject *outer_var_env;\n\n\t/* normal and constructor calls have identical semantics */\n\n\tnargs = duk_get_top(thr);\n\tfor (i = 0; i < nargs; i++) {\n\t\tduk_to_string(thr, i);  /* Rejects Symbols during coercion. */\n\t}\n\n\tif (nargs == 0) {\n\t\tduk_push_hstring_empty(thr);\n\t\tduk_push_hstring_empty(thr);\n\t} else if (nargs == 1) {\n\t\t/* XXX: cover this with the generic >1 case? */\n\t\tduk_push_hstring_empty(thr);\n\t} else {\n\t\tduk_insert(thr, 0);   /* [ arg1 ... argN-1 body] -> [body arg1 ... argN-1] */\n\t\tduk_push_literal(thr, \",\");\n\t\tduk_insert(thr, 1);\n\t\tduk_join(thr, nargs - 1);\n\t}\n\n\t/* [ body formals ], formals is comma separated list that needs to be parsed */\n\n\tDUK_ASSERT_TOP(thr, 2);\n\n\t/* XXX: this placeholder is not always correct, but use for now.\n\t * It will fail in corner cases; see test-dev-func-cons-args.js.\n\t */\n\tduk_push_literal(thr, \"function(\");\n\tduk_dup_1(thr);\n\tduk_push_literal(thr, \"){\");\n\tduk_dup_0(thr);\n\tduk_push_literal(thr, \"\\n}\");  /* Newline is important to handle trailing // comment. */\n\tduk_concat(thr, 5);\n\n\t/* [ body formals source ] */\n\n\tDUK_ASSERT_TOP(thr, 3);\n\n\t/* strictness is not inherited, intentional */\n\tcomp_flags = DUK_COMPILE_FUNCEXPR;\n\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_COMPILE);  /* XXX: copy from caller? */  /* XXX: ignored now */\n\th_sourcecode = duk_require_hstring(thr, -2);  /* no symbol check needed; -2 is concat'd code */\n\tduk_js_compile(thr,\n\t               (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_sourcecode),\n\t               (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sourcecode),\n\t               comp_flags);\n\n\t/* Force .name to 'anonymous' (ES2015). */\n\tduk_push_literal(thr, \"anonymous\");\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n\n\tfunc = (duk_hcompfunc *) duk_known_hobject(thr, -1);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) func));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) func));\n\n\t/* [ body formals source template ] */\n\n\t/* only outer_lex_env matters, as functions always get a new\n\t * variable declaration environment.\n\t */\n\n\touter_lex_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\touter_var_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\n\tduk_js_push_closure(thr, func, outer_var_env, outer_lex_env, 1 /*add_auto_proto*/);\n\n\t/* [ body formals source template closure ] */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_FUNCTION_BUILTIN */\n\n#if defined(DUK_USE_FUNCTION_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_to_string(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\t/*\n\t *  E5 Section 15.3.4.2 places few requirements on the output of\n\t *  this function: the result is implementation dependent, must\n\t *  follow FunctionDeclaration syntax (in particular, must have a\n\t *  name even for anonymous functions or functions with empty name).\n\t *  The output does NOT need to compile into anything useful.\n\t *\n\t *  E6 Section 19.2.3.5 changes the requirements completely: the\n\t *  result must either eval() to a functionally equivalent object\n\t *  OR eval() to a SyntaxError.\n\t *\n\t *  We opt for the SyntaxError approach for now, with a syntax that\n\t *  mimics V8's native function syntax:\n\t *\n\t *      'function cos() { [native code] }'\n\t *\n\t *  but extended with [ecmascript code], [bound code], and\n\t *  [lightfunc code].\n\t */\n\n\tduk_push_this(thr);\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *obj = DUK_TVAL_GET_OBJECT(tv);\n\t\tconst char *func_name;\n\n\t\t/* Function name: missing/undefined is mapped to empty string,\n\t\t * otherwise coerce to string.  No handling for invalid identifier\n\t\t * characters or e.g. '{' in the function name.  This doesn't\n\t\t * really matter as long as a SyntaxError results.  Technically\n\t\t * if the name contained a suitable prefix followed by '//' it\n\t\t * might cause the result to parse without error.\n\t\t */\n\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME);\n\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\tfunc_name = \"\";\n\t\t} else {\n\t\t\tfunc_name = duk_to_string(thr, -1);\n\t\t\tDUK_ASSERT(func_name != NULL);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(obj)) {\n\t\t\tduk_push_sprintf(thr, \"function %s() { [ecmascript code] }\", (const char *) func_name);\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(obj)) {\n\t\t\tduk_push_sprintf(thr, \"function %s() { [native code] }\", (const char *) func_name);\n\t\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(obj)) {\n\t\t\tduk_push_sprintf(thr, \"function %s() { [bound code] }\", (const char *) func_name);\n\t\t} else {\n\t\t\tgoto type_error;\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_push_lightfunc_tostring(thr, tv);\n\t} else {\n\t\tgoto type_error;\n\t}\n\n\treturn 1;\n\n type_error:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n#endif\n\n/* Always present because the native function pointer is needed in call\n * handling.\n */\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_call(duk_hthread *thr) {\n\t/* .call() is dealt with in call handling by simulating its\n\t * effects so this function is actually never called.\n\t */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_apply(duk_hthread *thr) {\n\t/* Like .call(), never actually called. */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_apply(duk_hthread *thr) {\n\t/* Like .call(), never actually called. */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_construct(duk_hthread *thr) {\n\t/* Like .call(), never actually called. */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\n#if defined(DUK_USE_FUNCTION_BUILTIN)\n/* Create a bound function which points to a target function which may\n * be bound or non-bound.  If the target is bound, the argument lists\n * and 'this' binding of the functions are merged and the resulting\n * function points directly to the non-bound target.\n */\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_bind(duk_hthread *thr) {\n\tduk_hboundfunc *h_bound;\n\tduk_idx_t nargs;  /* bound args, not counting 'this' binding */\n\tduk_idx_t bound_nargs;\n\tduk_int_t bound_len;\n\tduk_tval *tv_prevbound;\n\tduk_idx_t n_prevbound;\n\tduk_tval *tv_res;\n\tduk_tval *tv_tmp;\n\n\t/* XXX: C API call, e.g. duk_push_bound_function(thr, target_idx, nargs); */\n\n\t/* Vararg function, careful arg handling, e.g. thisArg may not\n\t * be present.\n\t */\n\tnargs = duk_get_top(thr) - 1;  /* actual args, not counting 'this' binding */\n\tif (nargs < 0) {\n\t\tnargs++;\n\t\tduk_push_undefined(thr);\n\t}\n\tDUK_ASSERT(nargs >= 0);\n\n\t/* Limit 'nargs' for bound functions to guarantee arithmetic\n\t * below will never wrap.\n\t */\n\tif (nargs > (duk_idx_t) DUK_HBOUNDFUNC_MAX_ARGS) {\n\t\tDUK_DCERROR_RANGE_INVALID_COUNT(thr);\n\t}\n\n\tduk_push_this(thr);\n\tduk_require_callable(thr, -1);\n\n\t/* [ thisArg arg1 ... argN func ]  (thisArg+args == nargs+1 total) */\n\tDUK_ASSERT_TOP(thr, nargs + 2);\n\n\t/* Create bound function object. */\n\th_bound = duk_push_hboundfunc(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&h_bound->target));\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&h_bound->this_binding));\n\tDUK_ASSERT(h_bound->args == NULL);\n\tDUK_ASSERT(h_bound->nargs == 0);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_bound) == NULL);\n\n\t/* [ thisArg arg1 ... argN func boundFunc ] */\n\n\t/* If the target is a bound function, argument lists must be\n\t * merged.  The 'this' binding closest to the target function\n\t * wins because in call handling the 'this' gets replaced over\n\t * and over again until we call the non-bound function.\n\t */\n\ttv_prevbound = NULL;\n\tn_prevbound = 0;\n\ttv_tmp = DUK_GET_TVAL_POSIDX(thr, 0);\n\tDUK_TVAL_SET_TVAL(&h_bound->this_binding, tv_tmp);\n\ttv_tmp = DUK_GET_TVAL_NEGIDX(thr, -2);\n\tDUK_TVAL_SET_TVAL(&h_bound->target, tv_tmp);\n\n\tif (DUK_TVAL_IS_OBJECT(tv_tmp)) {\n\t\tduk_hobject *h_target;\n\t\tduk_hobject *bound_proto;\n\n\t\th_target = DUK_TVAL_GET_OBJECT(tv_tmp);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(h_target));\n\n\t\t/* Internal prototype must be copied from the target.\n\t\t * For lightfuncs Function.prototype is used and is already\n\t\t * in place.\n\t\t */\n\t\tbound_proto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_target);\n\t\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) h_bound, bound_proto);\n\n\t\t/* The 'strict' flag is copied to get the special [[Get]] of E5.1\n\t\t * Section 15.3.5.4 to apply when a 'caller' value is a strict bound\n\t\t * function.  Not sure if this is correct, because the specification\n\t\t * is a bit ambiguous on this point but it would make sense.\n\t\t */\n\t\t/* Strictness is inherited from target. */\n\t\tif (DUK_HOBJECT_HAS_STRICT(h_target)) {\n\t\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_bound);\n\t\t}\n\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(h_target)) {\n\t\t\tduk_hboundfunc *h_boundtarget;\n\n\t\t\th_boundtarget = (duk_hboundfunc *) (void *) h_target;\n\n\t\t\t/* The final function should always be non-bound, unless\n\t\t\t * there's a bug in the internals.  Assert for it.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(&h_boundtarget->target) ||\n\t\t\t           (DUK_TVAL_IS_OBJECT(&h_boundtarget->target) &&\n\t\t\t            DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(&h_boundtarget->target)) &&\n\t\t\t            !DUK_HOBJECT_IS_BOUNDFUNC(DUK_TVAL_GET_OBJECT(&h_boundtarget->target))));\n\n\t\t\tDUK_TVAL_SET_TVAL(&h_bound->target, &h_boundtarget->target);\n\t\t\tDUK_TVAL_SET_TVAL(&h_bound->this_binding, &h_boundtarget->this_binding);\n\n\t\t\ttv_prevbound = h_boundtarget->args;\n\t\t\tn_prevbound = h_boundtarget->nargs;\n\t\t}\n\t} else {\n\t\t/* Lightfuncs are always strict. */\n\t\tduk_hobject *bound_proto;\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_tmp));\n\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_bound);\n\t\tbound_proto = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];\n\t\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) h_bound, bound_proto);\n\t}\n\n\tDUK_TVAL_INCREF(thr, &h_bound->target);  /* old values undefined, no decref needed */\n\tDUK_TVAL_INCREF(thr, &h_bound->this_binding);\n\n\tbound_nargs = n_prevbound + nargs;\n\tif (bound_nargs > (duk_idx_t) DUK_HBOUNDFUNC_MAX_ARGS) {\n\t\tDUK_DCERROR_RANGE_INVALID_COUNT(thr);\n\t}\n\ttv_res = (duk_tval *) DUK_ALLOC_CHECKED(thr, ((duk_size_t) bound_nargs) * sizeof(duk_tval));\n\tDUK_ASSERT(tv_res != NULL || bound_nargs == 0);\n\tDUK_ASSERT(h_bound->args == NULL);\n\tDUK_ASSERT(h_bound->nargs == 0);\n\th_bound->args = tv_res;\n\th_bound->nargs = bound_nargs;\n\n\tDUK_ASSERT(n_prevbound >= 0);\n\tduk_copy_tvals_incref(thr, tv_res, tv_prevbound, (duk_size_t) n_prevbound);\n\tDUK_ASSERT(nargs >= 0);\n\tduk_copy_tvals_incref(thr, tv_res + n_prevbound, DUK_GET_TVAL_POSIDX(thr, 1), (duk_size_t) nargs);\n\n\t/* [ thisArg arg1 ... argN func boundFunc ] */\n\n\t/* Bound function 'length' property is interesting.\n\t * For lightfuncs, simply read the virtual property.\n\t */\n\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH);\n\tbound_len = duk_get_int(thr, -1);  /* ES2015: no coercion */\n\tif (bound_len < nargs) {\n\t\tbound_len = 0;\n\t} else {\n\t\tbound_len -= nargs;\n\t}\n\tif (sizeof(duk_int_t) > 4 && bound_len > (duk_int_t) DUK_UINT32_MAX) {\n\t\tbound_len = (duk_int_t) DUK_UINT32_MAX;\n\t}\n\tduk_pop(thr);\n\tDUK_ASSERT(bound_len >= 0);\n\ttv_tmp = thr->valstack_top++;\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_tmp));\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv_tmp));\n\tDUK_TVAL_SET_U32(tv_tmp, (duk_uint32_t) bound_len);  /* in-place update, fastint */\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);  /* attrs in E6 Section 9.2.4 */\n\n\t/* XXX: could these be virtual? */\n\t/* Caller and arguments must use the same thrower, [[ThrowTypeError]]. */\n\tduk_xdef_prop_stridx_thrower(thr, -1, DUK_STRIDX_CALLER);\n\tduk_xdef_prop_stridx_thrower(thr, -1, DUK_STRIDX_LC_ARGUMENTS);\n\n\t/* Function name and fileName (non-standard). */\n\tduk_push_literal(thr, \"bound \");  /* ES2015 19.2.3.2. */\n\tduk_get_prop_stridx(thr, -3, DUK_STRIDX_NAME);\n\tif (!duk_is_string_notsymbol(thr, -1)) {\n\t\t/* ES2015 has requirement to check that .name of target is a string\n\t\t * (also must check for Symbol); if not, targetName should be the\n\t\t * empty string.  ES2015 19.2.3.2.\n\t\t */\n\t\tduk_pop(thr);\n\t\tduk_push_hstring_empty(thr);\n\t}\n\tduk_concat(thr, 2);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C);\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"created bound function: %!iT\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\treturn 1;\n}\n#endif  /* DUK_USE_FUNCTION_BUILTIN */\n\n/* %NativeFunctionPrototype% .length getter. */\nDUK_INTERNAL duk_ret_t duk_bi_native_function_length(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hnatfunc *h;\n\tduk_int16_t func_nargs;\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = (duk_hnatfunc *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (!DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h)) {\n\t\t\tgoto fail_type;\n\t\t}\n\t\tfunc_nargs = h->nargs;\n\t\tduk_push_int(thr, func_nargs == DUK_HNATFUNC_NARGS_VARARGS ? 0 : func_nargs);\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_small_uint_t lf_flags;\n\t\tduk_small_uint_t lf_len;\n\n\t\tlf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv);\n\t\tlf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags);\n\t\tduk_push_uint(thr, lf_len);\n\t} else {\n\t\tgoto fail_type;\n\t}\n\treturn 1;\n\n fail_type:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n\n/* %NativeFunctionPrototype% .name getter. */\nDUK_INTERNAL duk_ret_t duk_bi_native_function_name(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hnatfunc *h;\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = (duk_hnatfunc *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (!DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h)) {\n\t\t\tgoto fail_type;\n\t\t}\n#if 0\n\t\tduk_push_hnatfunc_name(thr, h);\n#endif\n\t\tduk_push_hstring_empty(thr);\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_push_lightfunc_name(thr, tv);\n\t} else {\n\t\tgoto fail_type;\n\t}\n\treturn 1;\n\n fail_type:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_hasinstance(duk_hthread *thr) {\n\t/* This binding: RHS, stack index 0: LHS. */\n\tduk_bool_t ret;\n\n\tret = duk_js_instanceof_ordinary(thr, DUK_GET_TVAL_POSIDX(thr, 0), DUK_GET_THIS_TVAL_PTR(thr));\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n#line 1 \"duk_bi_global.c\"\n/*\n *  Global object built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Encoding/decoding helpers\n */\n\n/* XXX: Could add fast path (for each transform callback) with direct byte\n * lookups (no shifting) and no explicit check for x < 0x80 before table\n * lookup.\n */\n\n/* Macros for creating and checking bitmasks for character encoding.\n * Bit number is a bit counterintuitive, but minimizes code size.\n */\n#define DUK__MKBITS(a,b,c,d,e,f,g,h)  ((duk_uint8_t) ( \\\n\t((a) << 0) | ((b) << 1) | ((c) << 2) | ((d) << 3) | \\\n\t((e) << 4) | ((f) << 5) | ((g) << 6) | ((h) << 7) \\\n\t))\n#define DUK__CHECK_BITMASK(table,cp)  ((table)[(cp) >> 3] & (1 << ((cp) & 0x07)))\n\n/* E5.1 Section 15.1.3.3: uriReserved + uriUnescaped + '#' */\nDUK_LOCAL const duk_uint8_t duk__encode_uriunescaped_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 1, 0, 1, 1, 0, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x20-0x2f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 0, 1, 0, 1),  /* 0x30-0x3f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x40-0x4f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x60-0x6f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 1, 0),  /* 0x70-0x7f */\n};\n\n/* E5.1 Section 15.1.3.4: uriUnescaped */\nDUK_LOCAL const duk_uint8_t duk__encode_uricomponent_unescaped_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 1, 0, 0, 0, 0, 0, 1), DUK__MKBITS(1, 1, 1, 0, 0, 1, 1, 0),  /* 0x20-0x2f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 0, 0, 0, 0, 0, 0),  /* 0x30-0x3f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x40-0x4f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x60-0x6f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 1, 0),  /* 0x70-0x7f */\n};\n\n/* E5.1 Section 15.1.3.1: uriReserved + '#' */\nDUK_LOCAL const duk_uint8_t duk__decode_uri_reserved_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 0, 0, 1, 1, 0, 1, 0), DUK__MKBITS(0, 0, 0, 1, 1, 0, 0, 1),  /* 0x20-0x2f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 1, 1, 0, 1, 0, 1),  /* 0x30-0x3f */\n\tDUK__MKBITS(1, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x40-0x4f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x60-0x6f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x70-0x7f */\n};\n\n/* E5.1 Section 15.1.3.2: empty */\nDUK_LOCAL const duk_uint8_t duk__decode_uri_component_reserved_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x20-0x2f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x30-0x3f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x40-0x4f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x60-0x6f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x70-0x7f */\n};\n\n#if defined(DUK_USE_SECTION_B)\n/* E5.1 Section B.2.2, step 7. */\nDUK_LOCAL const duk_uint8_t duk__escape_unescaped_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 1, 1, 0, 1, 1, 1),  /* 0x20-0x2f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 0, 0, 0, 0, 0, 0),  /* 0x30-0x3f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x40-0x4f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x60-0x6f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 0)   /* 0x70-0x7f */\n};\n#endif  /* DUK_USE_SECTION_B */\n\ntypedef struct {\n\tduk_hthread *thr;\n\tduk_hstring *h_str;\n\tduk_bufwriter_ctx bw;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p_end;\n} duk__transform_context;\n\ntypedef void (*duk__transform_callback)(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp);\n\n/* XXX: refactor and share with other code */\nDUK_LOCAL duk_small_int_t duk__decode_hex_escape(const duk_uint8_t *p, duk_small_int_t n) {\n\tduk_small_int_t ch;\n\tduk_small_int_t t = 0;\n\n\twhile (n > 0) {\n\t\tt = t * 16;\n\t\tch = (duk_small_int_t) duk_hex_dectab[*p++];\n\t\tif (DUK_LIKELY(ch >= 0)) {\n\t\t\tt += ch;\n\t\t} else {\n\t\t\treturn -1;\n\t\t}\n\t\tn--;\n\t}\n\treturn t;\n}\n\nDUK_LOCAL int duk__transform_helper(duk_hthread *thr, duk__transform_callback callback, const void *udata) {\n\tduk__transform_context tfm_ctx_alloc;\n\tduk__transform_context *tfm_ctx = &tfm_ctx_alloc;\n\tduk_codepoint_t cp;\n\n\ttfm_ctx->thr = thr;\n\n\ttfm_ctx->h_str = duk_to_hstring(thr, 0);\n\tDUK_ASSERT(tfm_ctx->h_str != NULL);\n\n\tDUK_BW_INIT_PUSHBUF(thr, &tfm_ctx->bw, DUK_HSTRING_GET_BYTELEN(tfm_ctx->h_str));  /* initial size guess */\n\n\ttfm_ctx->p_start = DUK_HSTRING_GET_DATA(tfm_ctx->h_str);\n\ttfm_ctx->p_end = tfm_ctx->p_start + DUK_HSTRING_GET_BYTELEN(tfm_ctx->h_str);\n\ttfm_ctx->p = tfm_ctx->p_start;\n\n\twhile (tfm_ctx->p < tfm_ctx->p_end) {\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &tfm_ctx->p, tfm_ctx->p_start, tfm_ctx->p_end);\n\t\tcallback(tfm_ctx, udata, cp);\n\t}\n\n\tDUK_BW_COMPACT(thr, &tfm_ctx->bw);\n\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if transform is safe. */\n\treturn 1;\n}\n\nDUK_LOCAL void duk__transform_callback_encode_uri(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tduk_uint8_t xutf8_buf[DUK_UNICODE_MAX_XUTF8_LENGTH];\n\tduk_small_int_t len;\n\tduk_codepoint_t cp1, cp2;\n\tduk_small_int_t i, t;\n\tconst duk_uint8_t *unescaped_table = (const duk_uint8_t *) udata;\n\n\t/* UTF-8 encoded bytes escaped as %xx%xx%xx... -> 3 * nbytes.\n\t * Codepoint range is restricted so this is a slightly too large\n\t * but doesn't matter.\n\t */\n\tDUK_BW_ENSURE(tfm_ctx->thr, &tfm_ctx->bw, 3 * DUK_UNICODE_MAX_XUTF8_LENGTH);\n\n\tif (cp < 0) {\n\t\tgoto uri_error;\n\t} else if ((cp < 0x80L) && DUK__CHECK_BITMASK(unescaped_table, cp)) {\n\t\tDUK_BW_WRITE_RAW_U8(tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t) cp);\n\t\treturn;\n\t} else if (cp >= 0xdc00L && cp <= 0xdfffL) {\n\t\tgoto uri_error;\n\t} else if (cp >= 0xd800L && cp <= 0xdbffL) {\n\t\t/* Needs lookahead */\n\t\tif (duk_unicode_decode_xutf8(tfm_ctx->thr, &tfm_ctx->p, tfm_ctx->p_start, tfm_ctx->p_end, (duk_ucodepoint_t *) &cp2) == 0) {\n\t\t\tgoto uri_error;\n\t\t}\n\t\tif (!(cp2 >= 0xdc00L && cp2 <= 0xdfffL)) {\n\t\t\tgoto uri_error;\n\t\t}\n\t\tcp1 = cp;\n\t\tcp = (duk_codepoint_t) (((cp1 - 0xd800L) << 10) + (cp2 - 0xdc00L) + 0x10000L);\n\t} else if (cp > 0x10ffffL) {\n\t\t/* Although we can allow non-BMP characters (they'll decode\n\t\t * back into surrogate pairs), we don't allow extended UTF-8\n\t\t * characters; they would encode to URIs which won't decode\n\t\t * back because of strict UTF-8 checks in URI decoding.\n\t\t * (However, we could just as well allow them here.)\n\t\t */\n\t\tgoto uri_error;\n\t} else {\n\t\t/* Non-BMP characters within valid UTF-8 range: encode as is.\n\t\t * They'll decode back into surrogate pairs if the escaped\n\t\t * output is decoded.\n\t\t */\n\t\t;\n\t}\n\n\tlen = duk_unicode_encode_xutf8((duk_ucodepoint_t) cp, xutf8_buf);\n\tfor (i = 0; i < len; i++) {\n\t\tt = (duk_small_int_t) xutf8_buf[i];\n\t\tDUK_BW_WRITE_RAW_U8_3(tfm_ctx->thr,\n\t\t                      &tfm_ctx->bw,\n\t\t                      DUK_ASC_PERCENT,\n\t\t                      (duk_uint8_t) duk_uc_nybbles[t >> 4],\n                                      (duk_uint8_t) duk_uc_nybbles[t & 0x0f]);\n\t}\n\n\treturn;\n\n uri_error:\n\tDUK_ERROR_URI(tfm_ctx->thr, DUK_STR_INVALID_INPUT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__transform_callback_decode_uri(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tconst duk_uint8_t *reserved_table = (const duk_uint8_t *) udata;\n\tduk_small_uint_t utf8_blen;\n\tduk_codepoint_t min_cp;\n\tduk_small_int_t t;  /* must be signed */\n\tduk_small_uint_t i;\n\n\t/* Maximum write size: XUTF8 path writes max DUK_UNICODE_MAX_XUTF8_LENGTH,\n\t * percent escape path writes max two times CESU-8 encoded BMP length.\n\t */\n\tDUK_BW_ENSURE(tfm_ctx->thr,\n\t              &tfm_ctx->bw,\n\t              (DUK_UNICODE_MAX_XUTF8_LENGTH >= 2 * DUK_UNICODE_MAX_CESU8_BMP_LENGTH ?\n\t              DUK_UNICODE_MAX_XUTF8_LENGTH : DUK_UNICODE_MAX_CESU8_BMP_LENGTH));\n\n\tif (cp == (duk_codepoint_t) '%') {\n\t\tconst duk_uint8_t *p = tfm_ctx->p;\n\t\tduk_size_t left = (duk_size_t) (tfm_ctx->p_end - p);  /* bytes left */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"percent encoding, left=%ld\", (long) left));\n\n\t\tif (left < 2) {\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tt = duk__decode_hex_escape(p, 2);\n\t\tDUK_DDD(DUK_DDDPRINT(\"first byte: %ld\", (long) t));\n\t\tif (t < 0) {\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tif (t < 0x80) {\n\t\t\tif (DUK__CHECK_BITMASK(reserved_table, t)) {\n\t\t\t\t/* decode '%xx' to '%xx' if decoded char in reserved set */\n\t\t\t\tDUK_ASSERT(tfm_ctx->p - 1 >= tfm_ctx->p_start);\n\t\t\t\tDUK_BW_WRITE_RAW_U8_3(tfm_ctx->thr,\n\t\t\t\t                      &tfm_ctx->bw,\n\t\t\t\t                      DUK_ASC_PERCENT,\n\t\t\t\t                      p[0],\n\t\t\t\t                      p[1]);\n\t\t\t} else {\n\t\t\t\tDUK_BW_WRITE_RAW_U8(tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t) t);\n\t\t\t}\n\t\t\ttfm_ctx->p += 2;\n\t\t\treturn;\n\t\t}\n\n\t\t/* Decode UTF-8 codepoint from a sequence of hex escapes.  The\n\t\t * first byte of the sequence has been decoded to 't'.\n\t\t *\n\t\t * Note that UTF-8 validation must be strict according to the\n\t\t * specification: E5.1 Section 15.1.3, decode algorithm step\n\t\t * 4.d.vii.8.  URIError from non-shortest encodings is also\n\t\t * specifically noted in the spec.\n\t\t */\n\n\t\tDUK_ASSERT(t >= 0x80);\n\t\tif (t < 0xc0) {\n\t\t\t/* continuation byte */\n\t\t\tgoto uri_error;\n\t\t} else if (t < 0xe0) {\n\t\t\t/* 110x xxxx; 2 bytes */\n\t\t\tutf8_blen = 2;\n\t\t\tmin_cp = 0x80L;\n\t\t\tcp = t & 0x1f;\n\t\t} else if (t < 0xf0) {\n\t\t\t/* 1110 xxxx; 3 bytes */\n\t\t\tutf8_blen = 3;\n\t\t\tmin_cp = 0x800L;\n\t\t\tcp = t & 0x0f;\n\t\t} else if (t < 0xf8) {\n\t\t\t/* 1111 0xxx; 4 bytes */\n\t\t\tutf8_blen = 4;\n\t\t\tmin_cp = 0x10000L;\n\t\t\tcp = t & 0x07;\n\t\t} else {\n\t\t\t/* extended utf-8 not allowed for URIs */\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tif (left < utf8_blen * 3 - 1) {\n\t\t\t/* '%xx%xx...%xx', p points to char after first '%' */\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tp += 3;\n\t\tfor (i = 1; i < utf8_blen; i++) {\n\t\t\t/* p points to digit part ('%xy', p points to 'x') */\n\t\t\tt = duk__decode_hex_escape(p, 2);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"i=%ld utf8_blen=%ld cp=%ld t=0x%02lx\",\n\t\t\t                     (long) i, (long) utf8_blen, (long) cp, (unsigned long) t));\n\t\t\tif (t < 0) {\n\t\t\t\tgoto uri_error;\n\t\t\t}\n\t\t\tif ((t & 0xc0) != 0x80) {\n\t\t\t\tgoto uri_error;\n\t\t\t}\n\t\t\tcp = (cp << 6) + (t & 0x3f);\n\t\t\tp += 3;\n\t\t}\n\t\tp--;  /* p overshoots */\n\t\ttfm_ctx->p = p;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"final cp=%ld, min_cp=%ld\", (long) cp, (long) min_cp));\n\n\t\tif (cp < min_cp || cp > 0x10ffffL || (cp >= 0xd800L && cp <= 0xdfffL)) {\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\t/* The E5.1 algorithm checks whether or not a decoded codepoint\n\t\t * is below 0x80 and perhaps may be in the \"reserved\" set.\n\t\t * This seems pointless because the single byte UTF-8 case is\n\t\t * handled separately, and non-shortest encodings are rejected.\n\t\t * So, 'cp' cannot be below 0x80 here, and thus cannot be in\n\t\t * the reserved set.\n\t\t */\n\n\t\t/* utf-8 validation ensures these */\n\t\tDUK_ASSERT(cp >= 0x80L && cp <= 0x10ffffL);\n\n\t\tif (cp >= 0x10000L) {\n\t\t\tcp -= 0x10000L;\n\t\t\tDUK_ASSERT(cp < 0x100000L);\n\n\t\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, ((cp >> 10) + 0xd800L));\n\t\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, ((cp & 0x03ffL) + 0xdc00L));\n\t\t} else {\n\t\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp);\n\t\t}\n\t} else {\n\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp);\n\t}\n\treturn;\n\n uri_error:\n\tDUK_ERROR_URI(tfm_ctx->thr, DUK_STR_INVALID_INPUT);\n\tDUK_WO_NORETURN(return;);\n}\n\n#if defined(DUK_USE_SECTION_B)\nDUK_LOCAL void duk__transform_callback_escape(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tDUK_UNREF(udata);\n\n\tDUK_BW_ENSURE(tfm_ctx->thr, &tfm_ctx->bw, 6);\n\n\tif (cp < 0) {\n\t\tgoto esc_error;\n\t} else if ((cp < 0x80L) && DUK__CHECK_BITMASK(duk__escape_unescaped_table, cp)) {\n\t\tDUK_BW_WRITE_RAW_U8(tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t) cp);\n\t} else if (cp < 0x100L) {\n\t\tDUK_BW_WRITE_RAW_U8_3(tfm_ctx->thr,\n\t\t                      &tfm_ctx->bw,\n\t\t                      (duk_uint8_t) DUK_ASC_PERCENT,\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp >> 4],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp & 0x0f]);\n\t} else if (cp < 0x10000L) {\n\t\tDUK_BW_WRITE_RAW_U8_6(tfm_ctx->thr,\n\t\t                      &tfm_ctx->bw,\n\t\t                      (duk_uint8_t) DUK_ASC_PERCENT,\n\t\t                      (duk_uint8_t) DUK_ASC_LC_U,\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp >> 12],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[(cp >> 8) & 0x0f],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[(cp >> 4) & 0x0f],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp & 0x0f]);\n\t} else {\n\t\t/* Characters outside BMP cannot be escape()'d.  We could\n\t\t * encode them as surrogate pairs (for codepoints inside\n\t\t * valid UTF-8 range, but not extended UTF-8).  Because\n\t\t * escape() and unescape() are legacy functions, we don't.\n\t\t */\n\t\tgoto esc_error;\n\t}\n\n\treturn;\n\n esc_error:\n\tDUK_ERROR_TYPE(tfm_ctx->thr, DUK_STR_INVALID_INPUT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__transform_callback_unescape(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tduk_small_int_t t;\n\n\tDUK_UNREF(udata);\n\n\tif (cp == (duk_codepoint_t) '%') {\n\t\tconst duk_uint8_t *p = tfm_ctx->p;\n\t\tduk_size_t left = (duk_size_t) (tfm_ctx->p_end - p);  /* bytes left */\n\n\t\tif (left >= 5 && p[0] == 'u' &&\n\t\t    ((t = duk__decode_hex_escape(p + 1, 4)) >= 0)) {\n\t\t\tcp = (duk_codepoint_t) t;\n\t\t\ttfm_ctx->p += 5;\n\t\t} else if (left >= 2 &&\n\t\t           ((t = duk__decode_hex_escape(p, 2)) >= 0)) {\n\t\t\tcp = (duk_codepoint_t) t;\n\t\t\ttfm_ctx->p += 2;\n\t\t}\n\t}\n\n\tDUK_BW_WRITE_ENSURE_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp);\n}\n#endif  /* DUK_USE_SECTION_B */\n\n/*\n *  Eval\n *\n *  Eval needs to handle both a \"direct eval\" and an \"indirect eval\".\n *  Direct eval handling needs access to the caller's activation so that its\n *  lexical environment can be accessed.  A direct eval is only possible from\n *  ECMAScript code; an indirect eval call is possible also from C code.\n *  When an indirect eval call is made from C code, there may not be a\n *  calling activation at all which needs careful handling.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_activation *act_caller;\n\tduk_activation *act_eval;\n\tduk_hcompfunc *func;\n\tduk_hobject *outer_lex_env;\n\tduk_hobject *outer_var_env;\n\tduk_bool_t this_to_global = 1;\n\tduk_small_uint_t comp_flags;\n\tduk_int_t level = -2;\n\tduk_small_uint_t call_flags;\n\n\tDUK_ASSERT(duk_get_top(thr) == 1 || duk_get_top(thr) == 2);  /* 2 when called by debugger */\n\tDUK_ASSERT(thr->callstack_top >= 1);  /* at least this function exists */\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT((thr->callstack_curr->flags & DUK_ACT_FLAG_DIRECT_EVAL) == 0 || /* indirect eval */\n\t           (thr->callstack_top >= 2));  /* if direct eval, calling activation must exist */\n\n\t/*\n\t *  callstack_top - 1 --> this function\n\t *  callstack_top - 2 --> caller (may not exist)\n\t *\n\t *  If called directly from C, callstack_top might be 1.  If calling\n\t *  activation doesn't exist, call must be indirect.\n\t */\n\n\th = duk_get_hstring_notsymbol(thr, 0);\n\tif (!h) {\n\t\t/* Symbol must be returned as is, like any non-string values. */\n\t\treturn 1;  /* return arg as-is */\n\t}\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* NOTE: level is used only by the debugger and should never be present\n\t * for an ECMAScript eval().\n\t */\n\tDUK_ASSERT(level == -2);  /* by default, use caller's environment */\n\tif (duk_get_top(thr) >= 2 && duk_is_number(thr, 1)) {\n\t\tlevel = duk_get_int(thr, 1);\n\t}\n\tDUK_ASSERT(level <= -2);  /* This is guaranteed by debugger code. */\n#endif\n\n\t/* [ source ] */\n\n\tcomp_flags = DUK_COMPILE_EVAL;\n\tact_eval = thr->callstack_curr;  /* this function */\n\tDUK_ASSERT(act_eval != NULL);\n\tact_caller = duk_hthread_get_activation_for_level(thr, level);\n\tif (act_caller != NULL) {\n\t\t/* Have a calling activation, check for direct eval (otherwise\n\t\t * assume indirect eval.\n\t\t */\n\t\tif ((act_caller->flags & DUK_ACT_FLAG_STRICT) &&\n\t\t    (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL)) {\n\t\t\t/* Only direct eval inherits strictness from calling code\n\t\t\t * (E5.1 Section 10.1.1).\n\t\t\t */\n\t\t\tcomp_flags |= DUK_COMPILE_STRICT;\n\t\t}\n\t} else {\n\t\tDUK_ASSERT((act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) == 0);\n\t}\n\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_INPUT);  /* XXX: copy from caller? */\n\tduk_js_compile(thr,\n\t               (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h),\n\t               (duk_size_t) DUK_HSTRING_GET_BYTELEN(h),\n\t               comp_flags);\n\tfunc = (duk_hcompfunc *) duk_known_hobject(thr, -1);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) func));\n\n\t/* [ source template ] */\n\n\t/* E5 Section 10.4.2 */\n\n\tif (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) {\n\t\tDUK_ASSERT(thr->callstack_top >= 2);\n\t\tDUK_ASSERT(act_caller != NULL);\n\t\tif (act_caller->lex_env == NULL) {\n\t\t\tDUK_ASSERT(act_caller->var_env == NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"delayed environment initialization\"));\n\n\t\t\t/* this may have side effects, so re-lookup act */\n\t\t\tduk_js_init_activation_environment_records_delayed(thr, act_caller);\n\t\t}\n\t\tDUK_ASSERT(act_caller->lex_env != NULL);\n\t\tDUK_ASSERT(act_caller->var_env != NULL);\n\n\t\tthis_to_global = 0;\n\n\t\tif (DUK_HOBJECT_HAS_STRICT((duk_hobject *) func)) {\n\t\t\tduk_hdecenv *new_env;\n\t\t\tduk_hobject *act_lex_env;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"direct eval call to a strict function -> \"\n\t\t\t                     \"var_env and lex_env to a fresh env, \"\n\t\t\t                     \"this_binding to caller's this_binding\"));\n\n\t\t\tact_lex_env = act_caller->lex_env;\n\n\t\t\tnew_env = duk_hdecenv_alloc(thr,\n\t\t\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\t\t\tDUK_ASSERT(new_env != NULL);\n\t\t\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, act_lex_env);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, act_lex_env);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new_env allocated: %!iO\", (duk_heaphdr *) new_env));\n\n\t\t\touter_lex_env = (duk_hobject *) new_env;\n\t\t\touter_var_env = (duk_hobject *) new_env;\n\n\t\t\tduk_insert(thr, 0);  /* stash to bottom of value stack to keep new_env reachable for duration of eval */\n\n\t\t\t/* compiler's responsibility */\n\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV((duk_hobject *) func));\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"direct eval call to a non-strict function -> \"\n\t\t\t                     \"var_env and lex_env to caller's envs, \"\n\t\t\t                     \"this_binding to caller's this_binding\"));\n\n\t\t\touter_lex_env = act_caller->lex_env;\n\t\t\touter_var_env = act_caller->var_env;\n\n\t\t\t/* compiler's responsibility */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV((duk_hobject *) func));\n\t\t}\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"indirect eval call -> var_env and lex_env to \"\n\t\t                     \"global object, this_binding to global object\"));\n\n\t\tthis_to_global = 1;\n\t\touter_lex_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t\touter_var_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t}\n\n\t/* Eval code doesn't need an automatic .prototype object. */\n\tduk_js_push_closure(thr, func, outer_var_env, outer_lex_env, 0 /*add_auto_proto*/);\n\n\t/* [ env? source template closure ] */\n\n\tif (this_to_global) {\n\t\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\t\tduk_push_hobject_bidx(thr, DUK_BIDX_GLOBAL);\n\t} else {\n\t\tduk_tval *tv;\n\t\tDUK_ASSERT(thr->callstack_top >= 2);\n\t\tDUK_ASSERT(act_caller != NULL);\n\t\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act_caller->bottom_byteoff - sizeof(duk_tval));  /* this is just beneath bottom */\n\t\tDUK_ASSERT(tv >= thr->valstack);\n\t\tduk_push_tval(thr, tv);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"eval -> lex_env=%!iO, var_env=%!iO, this_binding=%!T\",\n\t                     (duk_heaphdr *) outer_lex_env,\n\t                     (duk_heaphdr *) outer_var_env,\n\t                     duk_get_tval(thr, -1)));\n\n\t/* [ env? source template closure this ] */\n\n\tcall_flags = 0;\n\tif (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) {\n\t\t/* Set DIRECT_EVAL flag for the call; it's not strictly\n\t\t * needed for the 'inner' eval call (the eval body) but\n\t\t * current new.target implementation expects to find it\n\t\t * so it can traverse direct eval chains up to the real\n\t\t * calling function.\n\t\t */\n\t\tcall_flags |= DUK_CALL_FLAG_DIRECT_EVAL;\n\t}\n\tduk_handle_call_unprotected_nargs(thr, 0, call_flags);\n\n\t/* [ env? source template result ] */\n\n\treturn 1;\n}\n\n/*\n *  Parsing of ints and floats\n */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_parse_int(duk_hthread *thr) {\n\tduk_int32_t radix;\n\tduk_small_uint_t s2n_flags;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, 0);  /* Reject symbols. */\n\n\tradix = duk_to_int32(thr, 1);\n\n\t/* While parseInt() recognizes 0xdeadbeef, it doesn't recognize\n\t * ES2015 0o123 or 0b10001.\n\t */\n\ts2n_flags = DUK_S2N_FLAG_TRIM_WHITE |\n\t            DUK_S2N_FLAG_ALLOW_GARBAGE |\n\t            DUK_S2N_FLAG_ALLOW_PLUS |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |\n\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT;\n\n\t/* Specification stripPrefix maps to DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT.\n\t *\n\t * Don't autodetect octals (from leading zeroes), require user code to\n\t * provide an explicit radix 8 for parsing octal.  See write-up from Mozilla:\n\t * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt#ECMAScript_5_Removes_Octal_Interpretation\n\t */\n\n\tif (radix != 0) {\n\t\tif (radix < 2 || radix > 36) {\n\t\t\tgoto ret_nan;\n\t\t}\n\t\tif (radix != 16) {\n\t\t\ts2n_flags &= ~DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT;\n\t\t}\n\t} else {\n\t\tradix = 10;\n\t}\n\n\tduk_dup_0(thr);\n\tduk_numconv_parse(thr, (duk_small_int_t) radix, s2n_flags);\n\treturn 1;\n\n ret_nan:\n\tduk_push_nan(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_parse_float(duk_hthread *thr) {\n\tduk_small_uint_t s2n_flags;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\tduk_to_string(thr, 0);  /* Reject symbols. */\n\n\t/* XXX: check flags */\n\ts2n_flags = DUK_S2N_FLAG_TRIM_WHITE |\n\t            DUK_S2N_FLAG_ALLOW_EXP |\n\t            DUK_S2N_FLAG_ALLOW_GARBAGE |\n\t            DUK_S2N_FLAG_ALLOW_PLUS |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |\n\t            DUK_S2N_FLAG_ALLOW_INF |\n\t            DUK_S2N_FLAG_ALLOW_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO;\n\n\tduk_numconv_parse(thr, 10 /*radix*/, s2n_flags);\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n/*\n *  Number checkers\n */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_is_nan(duk_hthread *thr) {\n\tduk_double_t d = duk_to_number(thr, 0);\n\tduk_push_boolean(thr, (duk_bool_t) DUK_ISNAN(d));\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_is_finite(duk_hthread *thr) {\n\tduk_double_t d = duk_to_number(thr, 0);\n\tduk_push_boolean(thr, (duk_bool_t) DUK_ISFINITE(d));\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n/*\n *  URI handling\n */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_decode_uri(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_decode_uri, (const void *) duk__decode_uri_reserved_table);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_decode_uri_component(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_decode_uri, (const void *) duk__decode_uri_component_reserved_table);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_encode_uri(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_encode_uri, (const void *) duk__encode_uriunescaped_table);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_encode_uri_component(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_encode_uri, (const void *) duk__encode_uricomponent_unescaped_table);\n}\n\n#if defined(DUK_USE_SECTION_B)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_escape(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_escape, (const void *) NULL);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_unescape(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_unescape, (const void *) NULL);\n}\n#endif  /* DUK_USE_SECTION_B */\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n/* automatic undefs */\n#undef DUK__CHECK_BITMASK\n#undef DUK__MKBITS\n#line 1 \"duk_bi_json.c\"\n/*\n *  JSON built-ins.\n *\n *  See doc/json.rst.\n *\n *  Codepoints are handled as duk_uint_fast32_t to ensure that the full\n *  unsigned 32-bit range is supported.  This matters to e.g. JX.\n *\n *  Input parsing doesn't do an explicit end-of-input check at all.  This is\n *  safe: input string data is always NUL-terminated (0x00) and valid JSON\n *  inputs never contain plain NUL characters, so that as long as syntax checks\n *  are correct, we'll never read past the NUL.  This approach reduces code size\n *  and improves parsing performance, but it's critical that syntax checks are\n *  indeed correct!\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_JSON_SUPPORT)\n\n/*\n *  Local defines and forward declarations.\n */\n\n#define DUK__JSON_DECSTR_BUFSIZE 128\n#define DUK__JSON_DECSTR_CHUNKSIZE 64\n#define DUK__JSON_ENCSTR_CHUNKSIZE 64\n#define DUK__JSON_STRINGIFY_BUFSIZE 128\n#define DUK__JSON_MAX_ESC_LEN 10  /* '\\Udeadbeef' */\n\nDUK_LOCAL_DECL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx);\n#if defined(DUK_USE_JX)\nDUK_LOCAL_DECL duk_uint8_t duk__dec_peek(duk_json_dec_ctx *js_ctx);\n#endif\nDUK_LOCAL_DECL duk_uint8_t duk__dec_get(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL duk_uint8_t duk__dec_get_nonwhite(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n);\nDUK_LOCAL_DECL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx);\nDUK_LOCAL_DECL void duk__dec_string(duk_json_dec_ctx *js_ctx);\n#if defined(DUK_USE_JX)\nDUK_LOCAL_DECL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_pointer(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_buffer(duk_json_dec_ctx *js_ctx);\n#endif\nDUK_LOCAL_DECL void duk__dec_number(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_object(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_array(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_value(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx);\n\nDUK_LOCAL_DECL void duk__emit_1(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch);\nDUK_LOCAL_DECL void duk__emit_2(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch1, duk_uint_fast8_t ch2);\nDUK_LOCAL_DECL void duk__unemit_1(duk_json_enc_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__emit_hstring(duk_json_enc_ctx *js_ctx, duk_hstring *h);\n#if defined(DUK_USE_FASTINT)\nDUK_LOCAL_DECL void duk__emit_cstring(duk_json_enc_ctx *js_ctx, const char *p);\n#endif\nDUK_LOCAL_DECL void duk__emit_stridx(duk_json_enc_ctx *js_ctx, duk_small_uint_t stridx);\nDUK_LOCAL_DECL duk_uint8_t *duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uint_fast32_t cp, duk_uint8_t *q);\nDUK_LOCAL_DECL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k);\nDUK_LOCAL_DECL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str);\nDUK_LOCAL_DECL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top);\nDUK_LOCAL_DECL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top);\nDUK_LOCAL_DECL void duk__enc_object(duk_json_enc_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__enc_array(duk_json_enc_ctx *js_ctx);\nDUK_LOCAL_DECL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder);\nDUK_LOCAL_DECL duk_bool_t duk__enc_allow_into_proplist(duk_tval *tv);\nDUK_LOCAL_DECL void duk__enc_double(duk_json_enc_ctx *js_ctx);\n#if defined(DUK_USE_FASTINT)\nDUK_LOCAL_DECL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv);\n#endif\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL_DECL void duk__enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h);\nDUK_LOCAL_DECL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL_DECL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj);\n#endif\n#endif\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\nDUK_LOCAL_DECL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h);\n#endif\nDUK_LOCAL_DECL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth);\n\n/*\n *  Helper tables\n */\n\n#if defined(DUK_USE_JSON_QUOTESTRING_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_quotestr_lookup[256] = {\n\t/* 0x00 ... 0x7f: as is\n\t * 0x80: escape generically\n\t * 0x81: slow path\n\t * 0xa0 ... 0xff: backslash + one char\n\t */\n\n\t0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xe2, 0xf4, 0xee, 0x80, 0xe6, 0xf2, 0x80, 0x80,\n\t0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,\n\t0x20, 0x21, 0xa2, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,\n\t0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,\n\t0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,\n\t0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0xdc, 0x5d, 0x5e, 0x5f,\n\t0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81\n};\n#else  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\nDUK_LOCAL const duk_uint8_t duk__json_quotestr_esc[14] = {\n\tDUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL,\n\tDUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL,\n\tDUK_ASC_LC_B, DUK_ASC_LC_T, DUK_ASC_LC_N, DUK_ASC_NUL,\n\tDUK_ASC_LC_F, DUK_ASC_LC_R\n};\n#endif  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\n\n#if defined(DUK_USE_JSON_DECSTRING_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_decstr_lookup[256] = {\n\t/* 0x00: slow path\n\t * other: as is\n\t */\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x20, 0x21, 0x00, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,\n\t0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,\n\t0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,\n\t0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x00, 0x5d, 0x5e, 0x5f,\n\t0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,\n\t0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,\n\t0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,\n\t0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,\n\t0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,\n\t0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,\n\t0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,\n\t0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,\n\t0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff\n};\n#endif  /* DUK_USE_JSON_DECSTRING_FASTPATH */\n\n#if defined(DUK_USE_JSON_EATWHITE_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_eatwhite_lookup[256] = {\n\t/* 0x00: finish (non-white)\n\t * 0x01: continue\n\t */\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\n#endif  /* DUK_USE_JSON_EATWHITE_FASTPATH */\n\n#if defined(DUK_USE_JSON_DECNUMBER_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_decnumber_lookup[256] = {\n\t/* 0x00: finish (not part of number)\n\t * 0x01: continue\n\t */\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00,\n\t0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\n#endif  /* DUK_USE_JSON_DECNUMBER_FASTPATH */\n\n/*\n *  Parsing implementation.\n *\n *  JSON lexer is now separate from duk_lexer.c because there are numerous\n *  small differences making it difficult to share the lexer.\n *\n *  The parser here works with raw bytes directly; this works because all\n *  JSON delimiters are ASCII characters.  Invalid xUTF-8 encoded values\n *  inside strings will be passed on without normalization; this is not a\n *  compliance concern because compliant inputs will always be valid\n *  CESU-8 encodings.\n */\n\nDUK_LOCAL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx) {\n\t/* Shared handler to minimize parser size.  Cause will be\n\t * hidden, unfortunately, but we'll have an offset which\n\t * is often quite enough.\n\t */\n\tDUK_ERROR_FMT1(js_ctx->thr, DUK_ERR_SYNTAX_ERROR, DUK_STR_FMT_INVALID_JSON,\n\t               (long) (js_ctx->p - js_ctx->p_start));\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx) {\n\tconst duk_uint8_t *p;\n\tduk_uint8_t t;\n\n\tp = js_ctx->p;\n\tfor (;;) {\n\t\tDUK_ASSERT(p <= js_ctx->p_end);\n\t\tt = *p;\n\n#if defined(DUK_USE_JSON_EATWHITE_FASTPATH)\n\t\t/* This fast path is pretty marginal in practice.\n\t\t * XXX: candidate for removal.\n\t\t */\n\t\tDUK_ASSERT(duk__json_eatwhite_lookup[0x00] == 0x00);  /* end-of-input breaks */\n\t\tif (duk__json_eatwhite_lookup[t] == 0) {\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_JSON_EATWHITE_FASTPATH */\n\t\tif (!(t == 0x20 || t == 0x0a || t == 0x0d || t == 0x09)) {\n\t\t\t/* NUL also comes here.  Comparison order matters, 0x20\n\t\t\t * is most common whitespace.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_JSON_EATWHITE_FASTPATH */\n\t\tp++;\n\t}\n\tjs_ctx->p = p;\n}\n\n#if defined(DUK_USE_JX)\nDUK_LOCAL duk_uint8_t duk__dec_peek(duk_json_dec_ctx *js_ctx) {\n\tDUK_ASSERT(js_ctx->p <= js_ctx->p_end);\n\treturn *js_ctx->p;\n}\n#endif\n\nDUK_LOCAL duk_uint8_t duk__dec_get(duk_json_dec_ctx *js_ctx) {\n\tDUK_ASSERT(js_ctx->p <= js_ctx->p_end);\n\treturn *js_ctx->p++;\n}\n\nDUK_LOCAL duk_uint8_t duk__dec_get_nonwhite(duk_json_dec_ctx *js_ctx) {\n\tduk__dec_eat_white(js_ctx);\n\treturn duk__dec_get(js_ctx);\n}\n\n/* For JX, expressing the whole unsigned 32-bit range matters. */\nDUK_LOCAL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n) {\n\tduk_small_uint_t i;\n\tduk_uint_fast32_t res = 0;\n\tduk_uint8_t x;\n\tduk_small_int_t t;\n\n\tfor (i = 0; i < n; i++) {\n\t\t/* XXX: share helper from lexer; duk_lexer.c / hexval(). */\n\n\t\tx = duk__dec_get(js_ctx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"decode_hex_escape: i=%ld, n=%ld, res=%ld, x=%ld\",\n\t\t                     (long) i, (long) n, (long) res, (long) x));\n\n\t\t/* x == 0x00 (EOF) causes syntax_error */\n\t\tDUK_ASSERT(duk_hex_dectab[0] == -1);\n\t\tt = duk_hex_dectab[x & 0xff];\n\t\tif (DUK_LIKELY(t >= 0)) {\n\t\t\tres = (res * 16) + (duk_uint_fast32_t) t;\n\t\t} else {\n\t\t\t/* catches EOF and invalid digits */\n\t\t\tgoto syntax_error;\n\t\t}\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"final hex decoded value: %ld\", (long) res));\n\treturn res;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n\treturn 0;\n}\n\nDUK_LOCAL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t x, y;\n\n\t/* First character has already been eaten and checked by the caller.\n\t * We can scan until a NUL in stridx string because no built-in strings\n\t * have internal NULs.\n\t */\n\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\th = DUK_HTHREAD_GET_STRING(js_ctx->thr, stridx);\n\tDUK_ASSERT(h != NULL);\n\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h) + 1;\n\tDUK_ASSERT(*(js_ctx->p - 1) == *(p - 1));  /* first character has been matched */\n\n\tfor (;;) {\n\t\tx = *p;\n\t\tif (x == 0) {\n\t\t\tbreak;\n\t\t}\n\t\ty = duk__dec_get(js_ctx);\n\t\tif (x != y) {\n\t\t\t/* Catches EOF of JSON input. */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\tp++;\n\t}\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\nDUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_uint8_t **ext_p) {\n\tduk_uint_fast32_t cp;\n\n\t/* EOF (-1) will be cast to an unsigned value first\n\t * and then re-cast for the switch.  In any case, it\n\t * will match the default case (syntax error).\n\t */\n\tcp = (duk_uint_fast32_t) duk__dec_get(js_ctx);\n\tswitch (cp) {\n\tcase DUK_ASC_BACKSLASH: break;\n\tcase DUK_ASC_DOUBLEQUOTE: break;\n\tcase DUK_ASC_SLASH: break;\n\tcase DUK_ASC_LC_T: cp = 0x09; break;\n\tcase DUK_ASC_LC_N: cp = 0x0a; break;\n\tcase DUK_ASC_LC_R: cp = 0x0d; break;\n\tcase DUK_ASC_LC_F: cp = 0x0c; break;\n\tcase DUK_ASC_LC_B: cp = 0x08; break;\n\tcase DUK_ASC_LC_U: {\n\t\tcp = duk__dec_decode_hex_escape(js_ctx, 4);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_JX)\n\tcase DUK_ASC_UC_U: {\n\t\tif (js_ctx->flag_ext_custom) {\n\t\t\tcp = duk__dec_decode_hex_escape(js_ctx, 8);\n\t\t} else {\n\t\t\treturn 1;  /* syntax error */\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LC_X: {\n\t\tif (js_ctx->flag_ext_custom) {\n\t\t\tcp = duk__dec_decode_hex_escape(js_ctx, 2);\n\t\t} else {\n\t\t\treturn 1;  /* syntax error */\n\t\t}\n\t\tbreak;\n\t}\n#endif  /* DUK_USE_JX */\n\tdefault:\n\t\t/* catches EOF (0x00) */\n\t\treturn 1;  /* syntax error */\n\t}\n\n\tDUK_RAW_WRITE_XUTF8(*ext_p, cp);\n\n\treturn 0;\n}\n\nDUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tduk_uint8_t *q;\n\n\t/* '\"' was eaten by caller */\n\n\t/* Note that we currently parse -bytes-, not codepoints.\n\t * All non-ASCII extended UTF-8 will encode to bytes >= 0x80,\n\t * so they'll simply pass through (valid UTF-8 or not).\n\t */\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(js_ctx->thr, bw, DUK__JSON_DECSTR_BUFSIZE);\n\tq = DUK_BW_GET_PTR(js_ctx->thr, bw);\n\n#if defined(DUK_USE_JSON_DECSTRING_FASTPATH)\n\tfor (;;) {\n\t\tduk_small_uint_t safe;\n\t\tduk_uint8_t b, x;\n\t\tconst duk_uint8_t *p;\n\n\t\t/* Select a safe loop count where no output checks are\n\t\t * needed assuming we won't encounter escapes.  Input\n\t\t * bound checks are not necessary as a NUL (guaranteed)\n\t\t * will cause a SyntaxError before we read out of bounds.\n\t\t */\n\n\t\tsafe = DUK__JSON_DECSTR_CHUNKSIZE;\n\n\t\t/* Ensure space for 1:1 output plus one escape. */\n\t\tq = DUK_BW_ENSURE_RAW(js_ctx->thr, bw, safe + DUK_UNICODE_MAX_XUTF8_LENGTH, q);\n\n\t\tp = js_ctx->p;  /* temp copy, write back for next loop */\n\t\tfor (;;) {\n\t\t\tif (safe == 0) {\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tsafe--;\n\n\t\t\t/* End of input (NUL) goes through slow path and causes SyntaxError. */\n\t\t\tDUK_ASSERT(duk__json_decstr_lookup[0] == 0x00);\n\n\t\t\tb = *p++;\n\t\t\tx = (duk_small_int_t) duk__json_decstr_lookup[b];\n\t\t\tif (DUK_LIKELY(x != 0)) {\n\t\t\t\t/* Fast path, decode as is. */\n\t\t\t\t*q++ = b;\n\t\t\t} else if (b == DUK_ASC_DOUBLEQUOTE) {\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tgoto found_quote;\n\t\t\t} else if (b == DUK_ASC_BACKSLASH) {\n\t\t\t\t/* We've ensured space for one escaped input; then\n\t\t\t\t * bail out and recheck (this makes escape handling\n\t\t\t\t * quite slow but it's uncommon).\n\t\t\t\t */\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tif (duk__dec_string_escape(js_ctx, &q) != 0) {\n\t\t\t\t\tgoto syntax_error;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t}\n\t}\n found_quote:\n#else  /* DUK_USE_JSON_DECSTRING_FASTPATH */\n\tfor (;;) {\n\t\tduk_uint8_t x;\n\n\t\tq = DUK_BW_ENSURE_RAW(js_ctx->thr, bw, DUK_UNICODE_MAX_XUTF8_LENGTH, q);\n\n\t\tx = duk__dec_get(js_ctx);\n\n\t\tif (x == DUK_ASC_DOUBLEQUOTE) {\n\t\t\tbreak;\n\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\tif (duk__dec_string_escape(js_ctx, &q) != 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t} else if (x < 0x20) {\n\t\t\t/* catches EOF (NUL) */\n\t\t\tgoto syntax_error;\n\t\t} else {\n\t\t\t*q++ = (duk_uint8_t) x;\n\t\t}\n\t}\n#endif  /* DUK_USE_JSON_DECSTRING_FASTPATH */\n\n\tDUK_BW_SETPTR_AND_COMPACT(js_ctx->thr, bw, q);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if input string is safe. */\n\n\t/* [ ... str ] */\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\n#if defined(DUK_USE_JX)\n/* Decode a plain string consisting entirely of identifier characters.\n * Used to parse plain keys (e.g. \"foo: 123\").\n */\nDUK_LOCAL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p;\n\tduk_small_int_t x;\n\n\t/* Caller has already eaten the first char so backtrack one byte. */\n\n\tjs_ctx->p--;  /* safe */\n\tp = js_ctx->p;\n\n\t/* Here again we parse bytes, and non-ASCII UTF-8 will cause end of\n\t * parsing (which is correct except if there are non-shortest encodings).\n\t * There is also no need to check explicitly for end of input buffer as\n\t * the input is NUL padded and NUL will exit the parsing loop.\n\t *\n\t * Because no unescaping takes place, we can just scan to the end of the\n\t * plain string and intern from the input buffer.\n\t */\n\n\tfor (;;) {\n\t\tx = *p;\n\n\t\t/* There is no need to check the first character specially here\n\t\t * (i.e. reject digits): the caller only accepts valid initial\n\t\t * characters and won't call us if the first character is a digit.\n\t\t * This also ensures that the plain string won't be empty.\n\t\t */\n\n\t\tif (!duk_unicode_is_identifier_part((duk_codepoint_t) x)) {\n\t\t\tbreak;\n\t\t}\n\t\tp++;\n\t}\n\n\tduk_push_lstring(thr, (const char *) js_ctx->p, (duk_size_t) (p - js_ctx->p));\n\tjs_ctx->p = p;\n\n\t/* [ ... str ] */\n}\n#endif  /* DUK_USE_JX */\n\n#if defined(DUK_USE_JX)\nDUK_LOCAL void duk__dec_pointer(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p;\n\tduk_small_int_t x;\n\tvoid *voidptr;\n\n\t/* Caller has already eaten the first character ('(') which we don't need. */\n\n\tp = js_ctx->p;\n\n\tfor (;;) {\n\t\tx = *p;\n\n\t\t/* Assume that the native representation never contains a closing\n\t\t * parenthesis.\n\t\t */\n\n\t\tif (x == DUK_ASC_RPAREN) {\n\t\t\tbreak;\n\t\t} else if (x <= 0) {\n\t\t\t/* NUL term or -1 (EOF), NUL check would suffice */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\tp++;\n\t}\n\n\t/* There is no need to NUL delimit the sscanf() call: trailing garbage is\n\t * ignored and there is always a NUL terminator which will force an error\n\t * if no error is encountered before it.  It's possible that the scan\n\t * would scan further than between [js_ctx->p,p[ though and we'd advance\n\t * by less than the scanned value.\n\t *\n\t * Because pointers are platform specific, a failure to scan a pointer\n\t * results in a null pointer which is a better placeholder than a missing\n\t * value or an error.\n\t */\n\n\tvoidptr = NULL;\n\t(void) DUK_SSCANF((const char *) js_ctx->p, DUK_STR_FMT_PTR, &voidptr);\n\tduk_push_pointer(thr, voidptr);\n\tjs_ctx->p = p + 1;  /* skip ')' */\n\n\t/* [ ... ptr ] */\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n#endif  /* DUK_USE_JX */\n\n#if defined(DUK_USE_JX)\nDUK_LOCAL void duk__dec_buffer(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t *buf;\n\tduk_size_t src_len;\n\tduk_small_int_t x;\n\n\t/* Caller has already eaten the first character ('|') which we don't need. */\n\n\tp = js_ctx->p;\n\n\t/* XXX: Would be nice to share the fast path loop from duk_hex_decode()\n\t * and avoid creating a temporary buffer.  However, there are some\n\t * differences which prevent trivial sharing:\n\t *\n\t *   - Pipe char detection\n\t *   - EOF detection\n\t *   - Unknown length of input and output\n\t *\n\t * The best approach here would be a bufwriter and a reasonaly sized\n\t * safe inner loop (e.g. 64 output bytes at a time).\n\t */\n\n\tfor (;;) {\n\t\tx = *p;\n\n\t\t/* This loop intentionally does not ensure characters are valid\n\t\t * ([0-9a-fA-F]) because the hex decode call below will do that.\n\t\t */\n\t\tif (x == DUK_ASC_PIPE) {\n\t\t\tbreak;\n\t\t} else if (x <= 0) {\n\t\t\t/* NUL term or -1 (EOF), NUL check would suffice */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\tp++;\n\t}\n\n\t/* XXX: this is not very nice; unnecessary copy is made. */\n\tsrc_len = (duk_size_t) (p - js_ctx->p);\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, src_len);\n\tDUK_ASSERT(buf != NULL);\n\tduk_memcpy((void *) buf, (const void *) js_ctx->p, src_len);\n\tduk_hex_decode(thr, -1);\n\n\tjs_ctx->p = p + 1;  /* skip '|' */\n\n\t/* [ ... buf ] */\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n#endif  /* DUK_USE_JX */\n\n/* Parse a number, other than NaN or +/- Infinity */\nDUK_LOCAL void duk__dec_number(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t x;\n\tduk_small_uint_t s2n_flags;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_number\"));\n\n\tp_start = js_ctx->p;\n\n\t/* First pass parse is very lenient (e.g. allows '1.2.3') and extracts a\n\t * string for strict number parsing.\n\t */\n\n\tp = js_ctx->p;\n\tfor (;;) {\n\t\tx = *p;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse_number: p_start=%p, p=%p, p_end=%p, x=%ld\",\n\t\t                     (const void *) p_start, (const void *) p,\n\t\t                     (const void *) js_ctx->p_end, (long) x));\n\n#if defined(DUK_USE_JSON_DECNUMBER_FASTPATH)\n\t\t/* This fast path is pretty marginal in practice.\n\t\t * XXX: candidate for removal.\n\t\t */\n\t\tDUK_ASSERT(duk__json_decnumber_lookup[0x00] == 0x00);  /* end-of-input breaks */\n\t\tif (duk__json_decnumber_lookup[x] == 0) {\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_JSON_DECNUMBER_FASTPATH */\n\t\tif (!((x >= DUK_ASC_0 && x <= DUK_ASC_9) ||\n\t\t      (x == DUK_ASC_PERIOD || x == DUK_ASC_LC_E ||\n\t\t       x == DUK_ASC_UC_E || x == DUK_ASC_MINUS || x == DUK_ASC_PLUS))) {\n\t\t\t/* Plus sign must be accepted for positive exponents\n\t\t\t * (e.g. '1.5e+2').  This clause catches NULs.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_JSON_DECNUMBER_FASTPATH */\n\t\tp++;  /* safe, because matched (NUL causes a break) */\n\t}\n\tjs_ctx->p = p;\n\n\tDUK_ASSERT(js_ctx->p > p_start);\n\tduk_push_lstring(thr, (const char *) p_start, (duk_size_t) (p - p_start));\n\n\ts2n_flags = DUK_S2N_FLAG_ALLOW_EXP |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |  /* but don't allow leading plus */\n\t            DUK_S2N_FLAG_ALLOW_FRAC;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_number: string before parsing: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_numconv_parse(thr, 10 /*radix*/, s2n_flags);\n\tif (duk_is_nan(thr, -1)) {\n\t\tduk__dec_syntax_error(js_ctx);\n\t}\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\tDUK_DDD(DUK_DDDPRINT(\"parse_number: final number: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* [ ... num ] */\n}\n\nDUK_LOCAL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_require_stack(thr, DUK_JSON_DEC_REQSTACK);\n\n\t/* c recursion check */\n\n\tDUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0);  /* unsigned */\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tif (js_ctx->recursion_depth >= js_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_JSONDEC_RECLIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tjs_ctx->recursion_depth++;\n}\n\nDUK_LOCAL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx) {\n\t/* c recursion check */\n\n\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tjs_ctx->recursion_depth--;\n}\n\nDUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_int_t key_count;  /* XXX: a \"first\" flag would suffice */\n\tduk_uint8_t x;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_object\"));\n\n\tduk__dec_objarr_entry(js_ctx);\n\n\tduk_push_object(thr);\n\n\t/* Initial '{' has been checked and eaten by caller. */\n\n\tkey_count = 0;\n\tfor (;;) {\n\t\tx = duk__dec_get_nonwhite(js_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse_object: obj=%!T, x=%ld, key_count=%ld\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t\t                     (long) x, (long) key_count));\n\n\t\t/* handle comma and closing brace */\n\n\t\tif (x == DUK_ASC_COMMA && key_count > 0) {\n\t\t\t/* accept comma, expect new value */\n\t\t\tx = duk__dec_get_nonwhite(js_ctx);\n\t\t} else if (x == DUK_ASC_RCURLY) {\n\t\t\t/* eat closing brace */\n\t\t\tbreak;\n\t\t} else if (key_count == 0) {\n\t\t\t/* accept anything, expect first value (EOF will be\n\t\t\t * caught by key parsing below.\n\t\t\t */\n\t\t\t;\n\t\t} else {\n\t\t\t/* catches EOF (NUL) and initial comma */\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/* parse key and value */\n\n\t\tif (x == DUK_ASC_DOUBLEQUOTE) {\n\t\t\tduk__dec_string(js_ctx);\n#if defined(DUK_USE_JX)\n\t\t} else if (js_ctx->flag_ext_custom &&\n\t\t           duk_unicode_is_identifier_start((duk_codepoint_t) x)) {\n\t\t\tduk__dec_plain_string(js_ctx);\n#endif\n\t\t} else {\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/* [ ... obj key ] */\n\n\t\tx = duk__dec_get_nonwhite(js_ctx);\n\t\tif (x != DUK_ASC_COLON) {\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\tduk__dec_value(js_ctx);\n\n\t\t/* [ ... obj key val ] */\n\n\t\tduk_xdef_prop_wec(thr, -3);\n\n\t\t/* [ ... obj ] */\n\n\t\tkey_count++;\n\t}\n\n\t/* [ ... obj ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_object: final object is %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__dec_objarr_exit(js_ctx);\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\nDUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_uarridx_t arr_idx;\n\tduk_uint8_t x;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_array\"));\n\n\tduk__dec_objarr_entry(js_ctx);\n\n\tduk_push_array(thr);\n\n\t/* Initial '[' has been checked and eaten by caller. */\n\n\tarr_idx = 0;\n\tfor (;;) {\n\t\tx = duk__dec_get_nonwhite(js_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse_array: arr=%!T, x=%ld, arr_idx=%ld\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t\t                     (long) x, (long) arr_idx));\n\n\t\t/* handle comma and closing bracket */\n\n\t\tif ((x == DUK_ASC_COMMA) && (arr_idx != 0)) {\n\t\t\t/* accept comma, expect new value */\n\t\t\t;\n\t\t} else if (x == DUK_ASC_RBRACKET) {\n\t\t\t/* eat closing bracket */\n\t\t\tbreak;\n\t\t} else if (arr_idx == 0) {\n\t\t\t/* accept anything, expect first value (EOF will be\n\t\t\t * caught by duk__dec_value() below.\n\t\t\t */\n\t\t\tjs_ctx->p--;  /* backtrack (safe) */\n\t\t} else {\n\t\t\t/* catches EOF (NUL) and initial comma */\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/* parse value */\n\n\t\tduk__dec_value(js_ctx);\n\n\t\t/* [ ... arr val ] */\n\n\t\tduk_xdef_prop_index_wec(thr, -2, arr_idx);\n\t\tarr_idx++;\n\t}\n\n\t/* Must set 'length' explicitly when using duk_xdef_prop_xxx() to\n\t * set the values.\n\t */\n\n\tduk_set_length(thr, -1, arr_idx);\n\n\t/* [ ... arr ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_array: final array is %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__dec_objarr_exit(js_ctx);\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\nDUK_LOCAL void duk__dec_value(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_uint8_t x;\n\n\tx = duk__dec_get_nonwhite(js_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_value: initial x=%ld\", (long) x));\n\n\t/* Note: duk__dec_req_stridx() backtracks one char */\n\n\tif (x == DUK_ASC_DOUBLEQUOTE) {\n\t\tduk__dec_string(js_ctx);\n\t} else if ((x >= DUK_ASC_0 && x <= DUK_ASC_9) || (x == DUK_ASC_MINUS)) {\n#if defined(DUK_USE_JX)\n\t\tif (js_ctx->flag_ext_custom && x == DUK_ASC_MINUS && duk__dec_peek(js_ctx) == DUK_ASC_UC_I) {\n\t\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_MINUS_INFINITY);  /* \"-Infinity\", '-' has been eaten */\n\t\t\tduk_push_number(thr, -DUK_DOUBLE_INFINITY);\n\t\t} else {\n#else\n\t\t{  /* unconditional block */\n#endif\n\t\t\t/* We already ate 'x', so backup one byte. */\n\t\t\tjs_ctx->p--;  /* safe */\n\t\t\tduk__dec_number(js_ctx);\n\t\t}\n\t} else if (x == DUK_ASC_LC_T) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_TRUE);\n\t\tduk_push_true(thr);\n\t} else if (x == DUK_ASC_LC_F) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_FALSE);\n\t\tduk_push_false(thr);\n\t} else if (x == DUK_ASC_LC_N) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_NULL);\n\t\tduk_push_null(thr);\n#if defined(DUK_USE_JX)\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_LC_U) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_UNDEFINED);\n\t\tduk_push_undefined(thr);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_N) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_NAN);\n\t\tduk_push_nan(thr);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_I) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_INFINITY);\n\t\tduk_push_number(thr, DUK_DOUBLE_INFINITY);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_LPAREN) {\n\t\tduk__dec_pointer(js_ctx);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_PIPE) {\n\t\tduk__dec_buffer(js_ctx);\n#endif\n\t} else if (x == DUK_ASC_LCURLY) {\n\t\tduk__dec_object(js_ctx);\n\t} else if (x == DUK_ASC_LBRACKET) {\n\t\tduk__dec_array(js_ctx);\n\t} else {\n\t\t/* catches EOF (NUL) */\n\t\tgoto syntax_error;\n\t}\n\n\tduk__dec_eat_white(js_ctx);\n\n\t/* [ ... val ] */\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\n/* Recursive value reviver, implements the Walk() algorithm.  No C recursion\n * check is done here because the initial parsing step will already ensure\n * there is a reasonable limit on C recursion depth and hence object depth.\n */\nDUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hobject *h;\n\tduk_uarridx_t i, arr_len;\n\n\tDUK_DDD(DUK_DDDPRINT(\"walk: top=%ld, holder=%!T, name=%!T\",\n\t                     (long) duk_get_top(thr),\n\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk_dup_top(thr);\n\tduk_get_prop(thr, -3);  /* -> [ ... holder name val ] */\n\n\th = duk_get_hobject(thr, -1);\n\tif (h != NULL) {\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tarr_len = (duk_uarridx_t) duk_get_length(thr, -1);\n\t\t\tfor (i = 0; i < arr_len; i++) {\n\t\t\t\t/* [ ... holder name val ] */\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"walk: array, top=%ld, i=%ld, arr_len=%ld, holder=%!T, name=%!T, val=%!T\",\n\t\t\t\t                     (long) duk_get_top(thr), (long) i, (long) arr_len,\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -3), (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t\tduk_dup_top(thr);\n\t\t\t\t(void) duk_push_uint_to_hstring(thr, (duk_uint_t) i);  /* -> [ ... holder name val val ToString(i) ] */\n\t\t\t\tduk__dec_reviver_walk(js_ctx);  /* -> [ ... holder name val new_elem ] */\n\n\t\t\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\tduk_del_prop_index(thr, -1, i);\n\t\t\t\t} else {\n\t\t\t\t\t/* XXX: duk_xdef_prop_index_wec() would be more appropriate\n\t\t\t\t\t * here but it currently makes some assumptions that might\n\t\t\t\t\t * not hold (e.g. that previous property is not an accessor).\n\t\t\t\t\t */\n\t\t\t\t\tduk_put_prop_index(thr, -2, i);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t/* [ ... holder name val ] */\n\t\t\tduk_enum(thr, -1, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/);\n\t\t\twhile (duk_next(thr, -1 /*enum_index*/, 0 /*get_value*/)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"walk: object, top=%ld, holder=%!T, name=%!T, val=%!T, enum=%!iT, obj_key=%!T\",\n\t\t\t\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, -5),\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -4), (duk_tval *) duk_get_tval(thr, -3),\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t\t/* [ ... holder name val enum obj_key ] */\n\t\t\t\tduk_dup_m3(thr);\n\t\t\t\tduk_dup_m2(thr);\n\n\t\t\t\t/* [ ... holder name val enum obj_key val obj_key ] */\n\t\t\t\tduk__dec_reviver_walk(js_ctx);\n\n\t\t\t\t/* [ ... holder name val enum obj_key new_elem ] */\n\t\t\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\tduk_del_prop(thr, -3);\n\t\t\t\t} else {\n\t\t\t\t\t/* XXX: duk_xdef_prop_index_wec() would be more appropriate\n\t\t\t\t\t * here but it currently makes some assumptions that might\n\t\t\t\t\t * not hold (e.g. that previous property is not an accessor).\n\t\t\t\t\t *\n\t\t\t\t\t * Using duk_put_prop() works incorrectly with '__proto__'\n\t\t\t\t\t * if the own property with that name has been deleted.  This\n\t\t\t\t\t * does not happen normally, but a clever reviver can trigger\n\t\t\t\t\t * that, see complex reviver case in: test-bug-json-parse-__proto__.js.\n\t\t\t\t\t */\n\t\t\t\t\tduk_put_prop(thr, -4);\n\t\t\t\t}\n\t\t\t}\n\t\t\tduk_pop(thr);  /* pop enum */\n\t\t}\n\t}\n\n\t/* [ ... holder name val ] */\n\n\tduk_dup(thr, js_ctx->idx_reviver);\n\tduk_insert(thr, -4);  /* -> [ ... reviver holder name val ] */\n\tduk_call_method(thr, 2);  /* -> [ ... res ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"walk: top=%ld, result=%!T\",\n\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, -1)));\n}\n\n/*\n *  Stringify implementation.\n */\n\n#define DUK__EMIT_1(js_ctx,ch)          duk__emit_1((js_ctx), (duk_uint_fast8_t) (ch))\n#define DUK__EMIT_2(js_ctx,ch1,ch2)     duk__emit_2((js_ctx), (duk_uint_fast8_t) (ch1), (duk_uint_fast8_t) (ch2))\n#define DUK__EMIT_HSTR(js_ctx,h)        duk__emit_hstring((js_ctx), (h))\n#if defined(DUK_USE_FASTINT) || defined(DUK_USE_JX) || defined(DUK_USE_JC)\n#define DUK__EMIT_CSTR(js_ctx,p)        duk__emit_cstring((js_ctx), (p))\n#endif\n#define DUK__EMIT_STRIDX(js_ctx,i)      duk__emit_stridx((js_ctx), (i))\n#define DUK__UNEMIT_1(js_ctx)           duk__unemit_1((js_ctx))\n\nDUK_LOCAL void duk__emit_1(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch) {\n\tDUK_BW_WRITE_ENSURE_U8(js_ctx->thr, &js_ctx->bw, ch);\n}\n\nDUK_LOCAL void duk__emit_2(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch1, duk_uint_fast8_t ch2) {\n\tDUK_BW_WRITE_ENSURE_U8_2(js_ctx->thr, &js_ctx->bw, ch1, ch2);\n}\n\nDUK_LOCAL void duk__emit_hstring(duk_json_enc_ctx *js_ctx, duk_hstring *h) {\n\tDUK_BW_WRITE_ENSURE_HSTRING(js_ctx->thr, &js_ctx->bw, h);\n}\n\n#if defined(DUK_USE_FASTINT) || defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL void duk__emit_cstring(duk_json_enc_ctx *js_ctx, const char *str) {\n\tDUK_BW_WRITE_ENSURE_CSTRING(js_ctx->thr, &js_ctx->bw, str);\n}\n#endif\n\nDUK_LOCAL void duk__emit_stridx(duk_json_enc_ctx *js_ctx, duk_small_uint_t stridx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\th = DUK_HTHREAD_GET_STRING(js_ctx->thr, stridx);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_BW_WRITE_ENSURE_HSTRING(js_ctx->thr, &js_ctx->bw, h);\n}\n\nDUK_LOCAL void duk__unemit_1(duk_json_enc_ctx *js_ctx) {\n\tDUK_ASSERT(DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw) >= 1);\n\tDUK_BW_ADD_PTR(js_ctx->thr, &js_ctx->bw, -1);\n}\n\n#define DUK__MKESC(nybbles,esc1,esc2)  \\\n\t(((duk_uint_fast32_t) (nybbles)) << 16) | \\\n\t(((duk_uint_fast32_t) (esc1)) << 8) | \\\n\t((duk_uint_fast32_t) (esc2))\n\nDUK_LOCAL duk_uint8_t *duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uint_fast32_t cp, duk_uint8_t *q) {\n\tduk_uint_fast32_t tmp;\n\tduk_small_uint_t dig;\n\n\tDUK_UNREF(js_ctx);\n\n\t/* Caller ensures space for at least DUK__JSON_MAX_ESC_LEN. */\n\n\t/* Select appropriate escape format automatically, and set 'tmp' to a\n\t * value encoding both the escape format character and the nybble count:\n\t *\n\t *   (nybble_count << 16) | (escape_char1) | (escape_char2)\n\t */\n\n#if defined(DUK_USE_JX)\n\tif (DUK_LIKELY(cp < 0x100UL)) {\n\t\tif (DUK_UNLIKELY(js_ctx->flag_ext_custom != 0U)) {\n\t\t\ttmp = DUK__MKESC(2, DUK_ASC_BACKSLASH, DUK_ASC_LC_X);\n\t\t} else {\n\t\t\ttmp = DUK__MKESC(4, DUK_ASC_BACKSLASH, DUK_ASC_LC_U);\n\t\t}\n\t} else\n#endif\n\tif (DUK_LIKELY(cp < 0x10000UL)) {\n\t\ttmp = DUK__MKESC(4, DUK_ASC_BACKSLASH, DUK_ASC_LC_U);\n\t} else {\n#if defined(DUK_USE_JX)\n\t\tif (DUK_LIKELY(js_ctx->flag_ext_custom != 0U)) {\n\t\t\ttmp = DUK__MKESC(8, DUK_ASC_BACKSLASH, DUK_ASC_UC_U);\n\t\t} else\n#endif\n\t\t{\n\t\t\t/* In compatible mode and standard JSON mode, output\n\t\t\t * something useful for non-BMP characters.  This won't\n\t\t\t * roundtrip but will still be more or less readable and\n\t\t\t * more useful than an error.\n\t\t\t */\n\t\t\ttmp = DUK__MKESC(8, DUK_ASC_UC_U, DUK_ASC_PLUS);\n\t\t}\n\t}\n\n\t*q++ = (duk_uint8_t) ((tmp >> 8) & 0xff);\n\t*q++ = (duk_uint8_t) (tmp & 0xff);\n\n\ttmp = tmp >> 16;\n\twhile (tmp > 0) {\n\t\ttmp--;\n\t\tdig = (duk_small_uint_t) ((cp >> (4 * tmp)) & 0x0f);\n\t\t*q++ = duk_lc_digits[dig];\n\t}\n\n\treturn q;\n}\n\nDUK_LOCAL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k) {\n\tconst duk_int8_t *p, *p_start, *p_end;  /* Note: intentionally signed. */\n\tduk_size_t k_len;\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT(k != NULL);\n\n\t/* Accept ASCII strings which conform to identifier requirements\n\t * as being emitted without key quotes.  Since we only accept ASCII\n\t * there's no need for actual decoding: 'p' is intentionally signed\n\t * so that bytes >= 0x80 extend to negative values and are rejected\n\t * as invalid identifier codepoints.\n\t */\n\n\tif (js_ctx->flag_avoid_key_quotes) {\n\t\tk_len = DUK_HSTRING_GET_BYTELEN(k);\n\t\tp_start = (const duk_int8_t *) DUK_HSTRING_GET_DATA(k);\n\t\tp_end = p_start + k_len;\n\t\tp = p_start;\n\n\t\tif (p == p_end) {\n\t\t\t/* Zero length string is not accepted without quotes */\n\t\t\tgoto quote_normally;\n\t\t}\n\t\tcp = (duk_codepoint_t) (*p++);\n\t\tif (DUK_UNLIKELY(!duk_unicode_is_identifier_start(cp))) {\n\t\t\tgoto quote_normally;\n\t\t}\n\t\twhile (p < p_end) {\n\t\t\tcp = (duk_codepoint_t) (*p++);\n\t\t\tif (DUK_UNLIKELY(!duk_unicode_is_identifier_part(cp))) {\n\t\t\t\tgoto quote_normally;\n\t\t\t}\n\t\t}\n\n\t\t/* This seems faster than emitting bytes one at a time and\n\t\t * then potentially rewinding.\n\t\t */\n\t\tDUK__EMIT_HSTR(js_ctx, k);\n\t\treturn;\n\t}\n\n quote_normally:\n\tduk__enc_quote_string(js_ctx, k);\n}\n\n/* The Quote(value) operation: quote a string.\n *\n * Stack policy: [ ] -> [ ].\n */\n\nDUK_LOCAL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p, *p_start, *p_end, *p_now, *p_tmp;\n\tduk_uint8_t *q;\n\tduk_ucodepoint_t cp;  /* typed for duk_unicode_decode_xutf8() */\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_quote_string: h_str=%!O\", (duk_heaphdr *) h_str));\n\n\tDUK_ASSERT(h_str != NULL);\n\tp_start = DUK_HSTRING_GET_DATA(h_str);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_str);\n\tp = p_start;\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_DOUBLEQUOTE);\n\n\t/* Encode string in small chunks, estimating the maximum expansion so that\n\t * there's no need to ensure space while processing the chunk.\n\t */\n\n\twhile (p < p_end) {\n\t\tduk_size_t left, now, space;\n\n\t\tleft = (duk_size_t) (p_end - p);\n\t\tnow = (left > DUK__JSON_ENCSTR_CHUNKSIZE ?\n\t\t       DUK__JSON_ENCSTR_CHUNKSIZE : left);\n\n\t\t/* Maximum expansion per input byte is 6:\n\t\t *   - invalid UTF-8 byte causes \"\\uXXXX\" to be emitted (6/1 = 6).\n\t\t *   - 2-byte UTF-8 encodes as \"\\uXXXX\" (6/2 = 3).\n\t\t *   - 4-byte UTF-8 encodes as \"\\Uxxxxxxxx\" (10/4 = 2.5).\n\t\t */\n\t\tspace = now * 6;\n\t\tq = DUK_BW_ENSURE_GETPTR(thr, &js_ctx->bw, space);\n\n\t\tp_now = p + now;\n\n\t\twhile (p < p_now) {\n#if defined(DUK_USE_JSON_QUOTESTRING_FASTPATH)\n\t\t\tduk_uint8_t b;\n\n\t\t\tb = duk__json_quotestr_lookup[*p++];\n\t\t\tif (DUK_LIKELY(b < 0x80)) {\n\t\t\t\t/* Most input bytes go through here. */\n\t\t\t\t*q++ = b;\n\t\t\t} else if (b >= 0xa0) {\n\t\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t\t\t*q++ = (duk_uint8_t) (b - 0x80);\n\t\t\t} else if (b == 0x80) {\n\t\t\t\tcp = (duk_ucodepoint_t) (*(p - 1));\n\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t} else if (b == 0x7f && js_ctx->flag_ascii_only) {\n\t\t\t\t/* 0x7F is special */\n\t\t\t\tDUK_ASSERT(b == 0x81);\n\t\t\t\tcp = (duk_ucodepoint_t) 0x7f;\n\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(b == 0x81);\n\t\t\t\tp--;\n\n\t\t\t\t/* slow path is shared */\n#else  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\n\t\t\tcp = *p;\n\n\t\t\tif (DUK_LIKELY(cp <= 0x7f)) {\n\t\t\t\t/* ascii fast path: avoid decoding utf-8 */\n\t\t\t\tp++;\n\t\t\t\tif (cp == 0x22 || cp == 0x5c) {\n\t\t\t\t\t/* double quote or backslash */\n\t\t\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t\t\t\t*q++ = (duk_uint8_t) cp;\n\t\t\t\t} else if (cp < 0x20) {\n\t\t\t\t\tduk_uint_fast8_t esc_char;\n\n\t\t\t\t\t/* This approach is a bit shorter than a straight\n\t\t\t\t\t * if-else-ladder and also a bit faster.\n\t\t\t\t\t */\n\t\t\t\t\tif (cp < (sizeof(duk__json_quotestr_esc) / sizeof(duk_uint8_t)) &&\n\t\t\t\t\t    (esc_char = duk__json_quotestr_esc[cp]) != 0) {\n\t\t\t\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t\t\t\t\t*q++ = (duk_uint8_t) esc_char;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t\t\t}\n\t\t\t\t} else if (cp == 0x7f && js_ctx->flag_ascii_only) {\n\t\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t\t} else {\n\t\t\t\t\t/* any other printable -> as is */\n\t\t\t\t\t*q++ = (duk_uint8_t) cp;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* slow path is shared */\n#endif  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\n\n\t\t\t\t/* slow path decode */\n\n\t\t\t\t/* If XUTF-8 decoding fails, treat the offending byte as a codepoint directly\n\t\t\t\t * and go forward one byte.  This is of course very lossy, but allows some kind\n\t\t\t\t * of output to be produced even for internal strings which don't conform to\n\t\t\t\t * XUTF-8.  All standard ECMAScript strings are always CESU-8, so this behavior\n\t\t\t\t * does not violate the ECMAScript specification.  The behavior is applied to\n\t\t\t\t * all modes, including ECMAScript standard JSON.  Because the current XUTF-8\n\t\t\t\t * decoding is not very strict, this behavior only really affects initial bytes\n\t\t\t\t * and truncated codepoints.\n\t\t\t\t *\n\t\t\t\t * Another alternative would be to scan forwards to start of next codepoint\n\t\t\t\t * (or end of input) and emit just one replacement codepoint.\n\t\t\t\t */\n\n\t\t\t\tp_tmp = p;\n\t\t\t\tif (!duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp)) {\n\t\t\t\t\t/* Decode failed. */\n\t\t\t\t\tcp = *p_tmp;\n\t\t\t\t\tp = p_tmp + 1;\n\t\t\t\t}\n\n#if defined(DUK_USE_NONSTD_JSON_ESC_U2028_U2029)\n\t\t\t\tif (js_ctx->flag_ascii_only || cp == 0x2028 || cp == 0x2029) {\n#else\n\t\t\t\tif (js_ctx->flag_ascii_only) {\n#endif\n\t\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t\t} else {\n\t\t\t\t\t/* as is */\n\t\t\t\t\tDUK_RAW_WRITE_XUTF8(q, cp);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tDUK_BW_SET_PTR(thr, &js_ctx->bw, q);\n\t}\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_DOUBLEQUOTE);\n}\n\n/* Encode a double (checked by caller) from stack top.  Stack top may be\n * replaced by serialized string but is not popped (caller does that).\n */\nDUK_LOCAL void duk__enc_double(duk_json_enc_ctx *js_ctx) {\n\tduk_hthread *thr;\n\tduk_tval *tv;\n\tduk_double_t d;\n\tduk_small_int_t c;\n\tduk_small_int_t s;\n\tduk_small_uint_t stridx;\n\tduk_small_uint_t n2s_flags;\n\tduk_hstring *h_str;\n\n\tDUK_ASSERT(js_ctx != NULL);\n\tthr = js_ctx->thr;\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Caller must ensure 'tv' is indeed a double and not a fastint! */\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\td = DUK_TVAL_GET_DOUBLE(tv);\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\ts = (duk_small_int_t) DUK_SIGNBIT(d);\n\tDUK_UNREF(s);\n\n\tif (DUK_LIKELY(!(c == DUK_FP_INFINITE || c == DUK_FP_NAN))) {\n\t\tDUK_ASSERT(DUK_ISFINITE(d));\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t/* Negative zero needs special handling in JX/JC because\n\t\t * it would otherwise serialize to '0', not '-0'.\n\t\t */\n\t\tif (DUK_UNLIKELY(c == DUK_FP_ZERO && s != 0 &&\n\t\t                 (js_ctx->flag_ext_custom_or_compatible))) {\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_MINUS_ZERO);  /* '-0' */\n\t\t} else\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\t\t{\n\t\t\tn2s_flags = 0;\n\t\t\t/* [ ... number ] -> [ ... string ] */\n\t\t\tduk_numconv_stringify(thr, 10 /*radix*/, 0 /*digits*/, n2s_flags);\n\t\t}\n\t\th_str = duk_known_hstring(thr, -1);\n\t\tDUK__EMIT_HSTR(js_ctx, h_str);\n\t\treturn;\n\t}\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tif (!(js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM |\n\t                       DUK_JSON_FLAG_EXT_COMPATIBLE))) {\n\t\tstridx = DUK_STRIDX_LC_NULL;\n\t} else if (c == DUK_FP_NAN) {\n\t\tstridx = js_ctx->stridx_custom_nan;\n\t} else if (s == 0) {\n\t\tstridx = js_ctx->stridx_custom_posinf;\n\t} else {\n\t\tstridx = js_ctx->stridx_custom_neginf;\n\t}\n#else\n\tstridx = DUK_STRIDX_LC_NULL;\n#endif\n\tDUK__EMIT_STRIDX(js_ctx, stridx);\n}\n\n#if defined(DUK_USE_FASTINT)\n/* Encode a fastint from duk_tval ptr, no value stack effects. */\nDUK_LOCAL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv) {\n\tduk_int64_t v;\n\n\t/* Fastint range is signed 48-bit so longest value is -2^47 = -140737488355328\n\t * (16 chars long), longest signed 64-bit value is -2^63 = -9223372036854775808\n\t * (20 chars long).  Alloc space for 64-bit range to be safe.\n\t */\n\tduk_uint8_t buf[20 + 1];\n\n\t/* Caller must ensure 'tv' is indeed a fastint! */\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\tv = DUK_TVAL_GET_FASTINT(tv);\n\n\t/* XXX: There are no format strings in duk_config.h yet, could add\n\t * one for formatting duk_int64_t.  For now, assumes \"%lld\" and that\n\t * \"long long\" type exists.  Could also rely on C99 directly but that\n\t * won't work for older MSVC.\n\t */\n\tDUK_SPRINTF((char *) buf, \"%lld\", (long long) v);\n\tDUK__EMIT_CSTR(js_ctx, (const char *) buf);\n}\n#endif\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n#if defined(DUK_USE_HEX_FASTPATH)\nDUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) {\n\tduk_uint8_t *q;\n\tduk_uint16_t *q16;\n\tduk_small_uint_t x;\n\tduk_size_t i, len_safe;\n#if !defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)\n\tduk_bool_t shift_dst;\n#endif\n\n\t/* Unlike in duk_hex_encode() 'dst' is not necessarily aligned by 2.\n\t * For platforms where unaligned accesses are not allowed, shift 'dst'\n\t * ahead by 1 byte to get alignment and then duk_memmove() the result\n\t * in place.  The faster encoding loop makes up the difference.\n\t * There's always space for one extra byte because a terminator always\n\t * follows the hex data and that's been accounted for by the caller.\n\t */\n\n#if defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)\n\tq16 = (duk_uint16_t *) (void *) dst;\n#else\n\tshift_dst = (duk_bool_t) (((duk_size_t) dst) & 0x01U);\n\tif (shift_dst) {\n\t\tDUK_DD(DUK_DDPRINT(\"unaligned accesses not possible, dst not aligned -> step to dst + 1\"));\n\t\tq16 = (duk_uint16_t *) (void *) (dst + 1);\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"unaligned accesses not possible, dst is aligned\"));\n\t\tq16 = (duk_uint16_t *) (void *) dst;\n\t}\n\tDUK_ASSERT((((duk_size_t) q16) & 0x01U) == 0);\n#endif\n\n\tlen_safe = src_len & ~0x03U;\n\tfor (i = 0; i < len_safe; i += 4) {\n\t\tq16[0] = duk_hex_enctab[src[i]];\n\t\tq16[1] = duk_hex_enctab[src[i + 1]];\n\t\tq16[2] = duk_hex_enctab[src[i + 2]];\n\t\tq16[3] = duk_hex_enctab[src[i + 3]];\n\t\tq16 += 4;\n\t}\n\tq = (duk_uint8_t *) q16;\n\n#if !defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)\n\tif (shift_dst) {\n\t\tq--;\n\t\tduk_memmove((void *) dst, (const void *) (dst + 1), 2 * len_safe);\n\t\tDUK_ASSERT(dst + 2 * len_safe == q);\n\t}\n#endif\n\n\tfor (; i < src_len; i++) {\n\t\tx = src[i];\n\t\t*q++ = duk_lc_digits[x >> 4];\n\t\t*q++ = duk_lc_digits[x & 0x0f];\n\t}\n\n\treturn q;\n}\n#else  /* DUK_USE_HEX_FASTPATH */\nDUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint8_t *q;\n\tduk_small_uint_t x;\n\n\tp = src;\n\tp_end = src + src_len;\n\tq = dst;\n\twhile (p != p_end) {\n\t\tx = *p++;\n\t\t*q++ = duk_lc_digits[x >> 4];\n\t\t*q++ = duk_lc_digits[x & 0x0f];\n\t}\n\n\treturn q;\n}\n#endif  /* DUK_USE_HEX_FASTPATH */\n\nDUK_LOCAL void duk__enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_data, duk_size_t buf_len) {\n\tduk_hthread *thr;\n\tduk_uint8_t *q;\n\tduk_size_t space;\n\n\tthr = js_ctx->thr;\n\n\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);  /* caller checks */\n\tDUK_ASSERT(js_ctx->flag_ext_custom_or_compatible);\n\n\t/* Buffer values are encoded in (lowercase) hex to make the\n\t * binary data readable.  Base64 or similar would be more\n\t * compact but less readable, and the point of JX/JC\n\t * variants is to be as useful to a programmer as possible.\n\t */\n\n\t/* The #if defined() clutter here needs to handle the three\n\t * cases: (1) JX+JC, (2) JX only, (3) JC only.\n\t */\n\n\t/* Note: space must cater for both JX and JC. */\n\tspace = 9 + buf_len * 2 + 2;\n\tDUK_ASSERT(DUK_HBUFFER_MAX_BYTELEN <= 0x7ffffffeUL);\n\tDUK_ASSERT((space - 2) / 2 >= buf_len);  /* overflow not possible, buffer limits */\n\tq = DUK_BW_ENSURE_GETPTR(thr, &js_ctx->bw, space);\n\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\tif (js_ctx->flag_ext_custom)\n#endif\n#if defined(DUK_USE_JX)\n\t{\n\t\t*q++ = DUK_ASC_PIPE;\n\t\tq = duk__enc_buffer_data_hex(buf_data, buf_len, q);\n\t\t*q++ = DUK_ASC_PIPE;\n\n\t}\n#endif\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\telse\n#endif\n#if defined(DUK_USE_JC)\n\t{\n\t\tDUK_ASSERT(js_ctx->flag_ext_compatible);\n\t\tduk_memcpy((void *) q, (const void *) \"{\\\"_buf\\\":\\\"\", 9);  /* len: 9 */\n\t\tq += 9;\n\t\tq = duk__enc_buffer_data_hex(buf_data, buf_len, q);\n\t\t*q++ = DUK_ASC_DOUBLEQUOTE;\n\t\t*q++ = DUK_ASC_RCURLY;\n\t}\n#endif\n\n\tDUK_BW_SET_PTR(thr, &js_ctx->bw, q);\n}\n\nDUK_LOCAL void duk__enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) {\n\tduk__enc_buffer_data(js_ctx,\n\t                     (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(js_ctx->thr->heap, h),\n\t                     (duk_size_t) DUK_HBUFFER_GET_SIZE(h));\n}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\nDUK_LOCAL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) {\n\tduk_size_t i, n;\n\tconst duk_uint8_t *buf;\n\tduk_uint8_t *q;\n\n\tn = DUK_HBUFFER_GET_SIZE(h);\n\tif (n == 0) {\n\t\tDUK__EMIT_2(js_ctx, DUK_ASC_LCURLY, DUK_ASC_RCURLY);\n\t\treturn;\n\t}\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);\n\n\t/* Maximum encoded length with 32-bit index: 1 + 10 + 2 + 3 + 1 + 1 = 18,\n\t * with 64-bit index: 1 + 20 + 2 + 3 + 1 + 1 = 28.  32 has some slack.\n\t *\n\t * Note that because the output buffer is reallocated from time to time,\n\t * side effects (such as finalizers) affecting the buffer 'h' must be\n\t * disabled.  This is the case in the JSON.stringify() fast path.\n\t */\n\n\tbuf = (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(js_ctx->thr->heap, h);\n\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth + 1);\n\t\t\tq = DUK_BW_ENSURE_GETPTR(js_ctx->thr, &js_ctx->bw, 32);\n\t\t\tq += DUK_SPRINTF((char *) q, \"\\\"%lu\\\": %u,\", (unsigned long) i, (unsigned int) buf[i]);\n\t\t\tDUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, q);\n\t\t}\n\t} else {\n\t\tq = DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw);\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tq = DUK_BW_ENSURE_RAW(js_ctx->thr, &js_ctx->bw, 32, q);\n\t\t\tq += DUK_SPRINTF((char *) q, \"\\\"%lu\\\":%u,\", (unsigned long) i, (unsigned int) buf[i]);\n\t\t}\n\t\tDUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, q);\n\t}\n\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\n\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t}\n\tDUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);\n}\n#endif  /* DUK_USE_JSON_STRINGIFY_FASTPATH */\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr) {\n\tchar buf[64];  /* XXX: how to figure correct size? */\n\tconst char *fmt;\n\n\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);  /* caller checks */\n\tDUK_ASSERT(js_ctx->flag_ext_custom_or_compatible);\n\n\tduk_memzero(buf, sizeof(buf));\n\n\t/* The #if defined() clutter here needs to handle the three\n\t * cases: (1) JX+JC, (2) JX only, (3) JC only.\n\t */\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\tif (js_ctx->flag_ext_custom)\n#endif\n#if defined(DUK_USE_JX)\n\t{\n\t\tfmt = ptr ? \"(%p)\" : \"(null)\";\n\t}\n#endif\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\telse\n#endif\n#if defined(DUK_USE_JC)\n\t{\n\t\tDUK_ASSERT(js_ctx->flag_ext_compatible);\n\t\tfmt = ptr ? \"{\\\"_ptr\\\":\\\"%p\\\"}\" : \"{\\\"_ptr\\\":\\\"null\\\"}\";\n\t}\n#endif\n\n\t/* When ptr == NULL, the format argument is unused. */\n\tDUK_SNPRINTF(buf, sizeof(buf) - 1, fmt, ptr);  /* must not truncate */\n\tDUK__EMIT_CSTR(js_ctx, buf);\n}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj) {\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\tif (h_bufobj->buf == NULL || !DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t} else {\n\t\t/* Handle both full and partial slice (as long as covered). */\n\t\tduk__enc_buffer_data(js_ctx,\n\t\t                     (duk_uint8_t *) DUK_HBUFOBJ_GET_SLICE_BASE(js_ctx->thr->heap, h_bufobj),\n\t\t                     (duk_size_t) h_bufobj->length);\n\t}\n}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* Indent helper.  Calling code relies on js_ctx->recursion_depth also being\n * directly related to indent depth.\n */\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) {\n\tDUK_ASSERT(js_ctx->h_gap != NULL);\n\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) > 0);  /* caller guarantees */\n\n\tDUK__EMIT_1(js_ctx, 0x0a);\n\twhile (depth-- > 0) {\n\t\tDUK__EMIT_HSTR(js_ctx, js_ctx->h_gap);\n\t}\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) {\n\tconst duk_uint8_t *gap_data;\n\tduk_size_t gap_len;\n\tduk_size_t avail_bytes;   /* bytes of indent available for copying */\n\tduk_size_t need_bytes;    /* bytes of indent still needed */\n\tduk_uint8_t *p_start;\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT(js_ctx->h_gap != NULL);\n\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) > 0);  /* caller guarantees */\n\n\tDUK__EMIT_1(js_ctx, 0x0a);\n\tif (DUK_UNLIKELY(depth == 0)) {\n\t\treturn;\n\t}\n\n\t/* To handle deeper indents efficiently, make use of copies we've\n\t * already emitted.  In effect we can emit a sequence of 1, 2, 4,\n\t * 8, etc copies, and then finish the last run.  Byte counters\n\t * avoid multiply with gap_len on every loop.\n\t */\n\n\tgap_data = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(js_ctx->h_gap);\n\tgap_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap);\n\tDUK_ASSERT(gap_len > 0);\n\n\tneed_bytes = gap_len * depth;\n\tp = DUK_BW_ENSURE_GETPTR(js_ctx->thr, &js_ctx->bw, need_bytes);\n\tp_start = p;\n\n\tduk_memcpy((void *) p, (const void *) gap_data, (size_t) gap_len);\n\tp += gap_len;\n\tavail_bytes = gap_len;\n\tDUK_ASSERT(need_bytes >= gap_len);\n\tneed_bytes -= gap_len;\n\n\twhile (need_bytes >= avail_bytes) {\n\t\tduk_memcpy((void *) p, (const void *) p_start, (size_t) avail_bytes);\n\t\tp += avail_bytes;\n\t\tneed_bytes -= avail_bytes;\n\t\tavail_bytes <<= 1;\n\t}\n\n\tDUK_ASSERT(need_bytes < avail_bytes);  /* need_bytes may be zero */\n\tduk_memcpy((void *) p, (const void *) p_start, (size_t) need_bytes);\n\tp += need_bytes;\n\t/*avail_bytes += need_bytes*/\n\n\tDUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, p);\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/* Shared entry handling for object/array serialization. */\nDUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hobject *h_target;\n\tduk_uint_fast32_t i, n;\n\n\t*entry_top = duk_get_top(thr);\n\n\tduk_require_stack(thr, DUK_JSON_ENC_REQSTACK);\n\n\t/* Loop check using a hybrid approach: a fixed-size visited[] array\n\t * with overflow in a loop check object.\n\t */\n\n\th_target = duk_known_hobject(thr, -1);  /* object or array */\n\n\tn = js_ctx->recursion_depth;\n\tif (DUK_UNLIKELY(n > DUK_JSON_ENC_LOOPARRAY)) {\n\t\tn = DUK_JSON_ENC_LOOPARRAY;\n\t}\n\tfor (i = 0; i < n; i++) {\n\t\tif (DUK_UNLIKELY(js_ctx->visiting[i] == h_target)) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"slow path loop detect\"));\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CYCLIC_INPUT);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t}\n\tif (js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY) {\n\t\tjs_ctx->visiting[js_ctx->recursion_depth] = h_target;\n\t} else {\n\t\tduk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) h_target);\n\t\tduk_dup_top(thr);  /* -> [ ... voidp voidp ] */\n\t\tif (duk_has_prop(thr, js_ctx->idx_loop)) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CYCLIC_INPUT);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tduk_push_true(thr);  /* -> [ ... voidp true ] */\n\t\tduk_put_prop(thr, js_ctx->idx_loop);  /* -> [ ... ] */\n\t}\n\n\t/* C recursion check. */\n\n\tDUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0);  /* unsigned */\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tif (js_ctx->recursion_depth >= js_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_JSONENC_RECLIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tjs_ctx->recursion_depth++;\n\n\tDUK_DDD(DUK_DDDPRINT(\"shared entry finished: top=%ld, loop=%!T\",\n\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop)));\n}\n\n/* Shared exit handling for object/array serialization. */\nDUK_LOCAL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hobject *h_target;\n\n\t/* C recursion check. */\n\n\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tjs_ctx->recursion_depth--;\n\n\t/* Loop check. */\n\n\th_target = duk_known_hobject(thr, *entry_top - 1);  /* original target at entry_top - 1 */\n\n\tif (js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY) {\n\t\t/* Previous entry was inside visited[], nothing to do. */\n\t} else {\n\t\tduk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) h_target);\n\t\tduk_del_prop(thr, js_ctx->idx_loop);  /* -> [ ... ] */\n\t}\n\n\t/* Restore stack top after unbalanced code paths. */\n\tduk_set_top(thr, *entry_top);\n\n\tDUK_DDD(DUK_DDDPRINT(\"shared entry finished: top=%ld, loop=%!T\",\n\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop)));\n}\n\n/* The JO(value) operation: encode object.\n *\n * Stack policy: [ object ] -> [ object ].\n */\nDUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hstring *h_key;\n\tduk_idx_t entry_top;\n\tduk_idx_t idx_obj;\n\tduk_idx_t idx_keys;\n\tduk_bool_t emitted;\n\tduk_uarridx_t arr_len, i;\n\tduk_size_t prev_size;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_object: obj=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__enc_objarr_entry(js_ctx, &entry_top);\n\n\tidx_obj = entry_top - 1;\n\n\tif (js_ctx->idx_proplist >= 0) {\n\t\tidx_keys = js_ctx->idx_proplist;\n\t} else {\n\t\t/* XXX: would be nice to enumerate an object at specified index */\n\t\tduk_dup(thr, idx_obj);\n\t\t(void) duk_hobject_get_enumerated_keys(thr, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/);  /* [ ... target ] -> [ ... target keys ] */\n\t\tidx_keys = duk_require_normalize_index(thr, -1);\n\t\t/* leave stack unbalanced on purpose */\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"idx_keys=%ld, h_keys=%!T\",\n\t                     (long) idx_keys, (duk_tval *) duk_get_tval(thr, idx_keys)));\n\n\t/* Steps 8-10 have been merged to avoid a \"partial\" variable. */\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);\n\n\t/* XXX: keys is an internal object with all keys to be processed\n\t * in its (gapless) array part.  Because nobody can touch the keys\n\t * object, we could iterate its array part directly (keeping in mind\n\t * that it can be reallocated).\n\t */\n\n\tarr_len = (duk_uarridx_t) duk_get_length(thr, idx_keys);\n\temitted = 0;\n\tfor (i = 0; i < arr_len; i++) {\n\t\tduk_get_prop_index(thr, idx_keys, i);  /* -> [ ... key ] */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"object property loop: holder=%!T, key=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_obj),\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\th_key = duk_known_hstring(thr, -1);\n\t\tDUK_ASSERT(h_key != NULL);\n\t\tDUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(h_key));  /* proplist filtering; enum options */\n\n\t\tprev_size = DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw);\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t\tduk__enc_key_autoquote(js_ctx, h_key);\n\t\t\tDUK__EMIT_2(js_ctx, DUK_ASC_COLON, DUK_ASC_SPACE);\n\t\t} else {\n\t\t\tduk__enc_key_autoquote(js_ctx, h_key);\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COLON);\n\t\t}\n\n\t\t/* [ ... key ] */\n\n\t\tif (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_obj) == 0)) {\n\t\t\t/* Value would yield 'undefined', so skip key altogether.\n\t\t\t * Side effects have already happened.\n\t\t\t */\n\t\t\tDUK_BW_SET_SIZE(js_ctx->thr, &js_ctx->bw, prev_size);\n\t\t} else {\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\t\temitted = 1;\n\t\t}\n\n\t\t/* [ ... ] */\n\t}\n\n\tif (emitted) {\n\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t}\n\t}\n\tDUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);\n\n\tduk__enc_objarr_exit(js_ctx, &entry_top);\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n}\n\n/* The JA(value) operation: encode array.\n *\n * Stack policy: [ array ] -> [ array ].\n */\nDUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_idx_t entry_top;\n\tduk_idx_t idx_arr;\n\tduk_bool_t emitted;\n\tduk_uarridx_t i, arr_len;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_array: array=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__enc_objarr_entry(js_ctx, &entry_top);\n\n\tidx_arr = entry_top - 1;\n\n\t/* Steps 8-10 have been merged to avoid a \"partial\" variable. */\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_LBRACKET);\n\n\tarr_len = (duk_uarridx_t) duk_get_length(thr, idx_arr);\n\temitted = 0;\n\tfor (i = 0; i < arr_len; i++) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"array entry loop: array=%!T, index=%ld, arr_len=%ld\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_arr),\n\t\t                     (long) i, (long) arr_len));\n\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t}\n\n\t\t(void) duk_push_uint_to_hstring(thr, (duk_uint_t) i);  /* -> [ ... key ] */\n\n\t\t/* [ ... key ] */\n\n\t\tif (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_arr) == 0)) {\n\t\t\t/* Value would normally be omitted, replace with 'null'. */\n\t\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\t} else {\n\t\t\t;\n\t\t}\n\n\t\t/* [ ... ] */\n\n\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\temitted = 1;\n\t}\n\n\tif (emitted) {\n\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t}\n\t}\n\tDUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET);\n\n\tduk__enc_objarr_exit(js_ctx, &entry_top);\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n}\n\n/* The Str(key, holder) operation.\n *\n * Stack policy: [ ... key ] -> [ ... ]\n */\nDUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_tval *tv;\n\tduk_tval *tv_holder;\n\tduk_tval *tv_key;\n\tduk_small_int_t c;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_value: idx_holder=%ld, holder=%!T, key=%!T\",\n\t                     (long) idx_holder, (duk_tval *) duk_get_tval(thr, idx_holder),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\ttv_holder = DUK_GET_TVAL_POSIDX(thr, idx_holder);\n\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_holder));\n\ttv_key = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_key));\n\tDUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(DUK_TVAL_GET_STRING(tv_key)));  /* Caller responsible. */\n\t(void) duk_hobject_getprop(thr, tv_holder, tv_key);\n\n\t/* -> [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* Standard JSON checks for .toJSON() only for actual objects; for\n\t * example, setting Number.prototype.toJSON and then serializing a\n\t * number won't invoke the .toJSON() method.  However, lightfuncs and\n\t * plain buffers mimic objects so we check for their .toJSON() method.\n\t */\n\tif (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT |\n\t                                 DUK_TYPE_MASK_LIGHTFUNC |\n\t                                 DUK_TYPE_MASK_BUFFER)) {\n\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_JSON);\n\t\tif (duk_is_callable(thr, -1)) {  /* toJSON() can also be a lightfunc */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is object, has callable toJSON() -> call it\"));\n\t\t\t/* XXX: duk_dup_unvalidated(thr, -2) etc. */\n\t\t\tduk_dup_m2(thr);          /* -> [ ... key val toJSON val ] */\n\t\t\tduk_dup_m4(thr);          /* -> [ ... key val toJSON val key ] */\n\t\t\tduk_call_method(thr, 1);  /* -> [ ... key val val' ] */\n\t\t\tduk_remove_m2(thr);       /* -> [ ... key val' ] */\n\t\t} else {\n\t\t\tduk_pop(thr);             /* -> [ ... key val ] */\n\t\t}\n\t}\n\n\t/* [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (js_ctx->h_replacer) {\n\t\t/* XXX: Here a \"slice copy\" would be useful. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"replacer is set, call replacer\"));\n\t\tduk_push_hobject(thr, js_ctx->h_replacer);  /* -> [ ... key val replacer ] */\n\t\tduk_dup(thr, idx_holder);                   /* -> [ ... key val replacer holder ] */\n\t\tduk_dup_m4(thr);                            /* -> [ ... key val replacer holder key ] */\n\t\tduk_dup_m4(thr);                            /* -> [ ... key val replacer holder key val ] */\n\t\tduk_call_method(thr, 2);                    /* -> [ ... key val val' ] */\n\t\tduk_remove_m2(thr);                         /* -> [ ... key val' ] */\n\t}\n\n\t/* [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h) &&\n\t\t    js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE)) {\n\t\t\t/* With JX/JC a bufferobject gets serialized specially. */\n\t\t\tduk_hbufobj *h_bufobj;\n\t\t\th_bufobj = (duk_hbufobj *) h;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\t\t\tduk__enc_bufobj(js_ctx, h_bufobj);\n\t\t\tgoto pop2_emitted;\n\t\t}\n\t\t/* Otherwise bufferobjects get serialized as normal objects. */\n#endif  /* JX || JC */\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t\tc = (duk_small_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h);\n\t\tswitch (c) {\n\t\tcase DUK_HOBJECT_CLASS_NUMBER: {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is a Number object -> coerce with ToNumber()\"));\n\t\t\tduk_to_number_m1(thr);\n\t\t\t/* The coercion potentially invokes user .valueOf() and .toString()\n\t\t\t * but can't result in a function value because ToPrimitive() would\n\t\t\t * reject such a result: test-dev-json-stringify-coercion-1.js.\n\t\t\t */\n\t\t\tDUK_ASSERT(!duk_is_callable(thr, -1));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_HOBJECT_CLASS_STRING: {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is a String object -> coerce with ToString()\"));\n\t\t\tduk_to_string(thr, -1);\n\t\t\t/* Same coercion behavior as for Number. */\n\t\t\tDUK_ASSERT(!duk_is_callable(thr, -1));\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tcase DUK_HOBJECT_CLASS_POINTER:\n#endif\n\t\tcase DUK_HOBJECT_CLASS_BOOLEAN: {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is a Boolean/Buffer/Pointer object -> get internal value\"));\n\t\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t\t\tduk_remove_m2(thr);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\t/* Normal object which doesn't get automatically coerced to a\n\t\t\t * primitive value.  Functions are checked for specially.  The\n\t\t\t * primitive value coercions for Number, String, Pointer, and\n\t\t\t * Boolean can't result in functions so suffices to check here.\n\t\t\t * Symbol objects are handled like plain objects (their primitive\n\t\t\t * value is NOT looked up like for e.g. String objects).\n\t\t\t */\n\t\t\tDUK_ASSERT(h != NULL);\n\t\t\tif (DUK_HOBJECT_IS_CALLABLE(h)) {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t\t\tif (js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM |\n\t\t\t\t                     DUK_JSON_FLAG_EXT_COMPATIBLE)) {\n\t\t\t\t\t/* We only get here when doing non-standard JSON encoding */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> function allowed, serialize to custom format\"));\n\t\t\t\t\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);\n\t\t\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function);\n\t\t\t\t\tgoto pop2_emitted;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> will result in undefined (function)\"));\n\t\t\t\t\tgoto pop2_undef;\n\t\t\t\t}\n#else  /* DUK_USE_JX || DUK_USE_JC */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> will result in undefined (function)\"));\n\t\t\t\tgoto pop2_undef;\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\t\t\t}\n\t\t}\n\t\t}  /* end switch */\n\t}\n\n\t/* [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (duk_check_type_mask(thr, -1, js_ctx->mask_for_undefined)) {\n\t\t/* will result in undefined */\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> will result in undefined (type mask check)\"));\n\t\tgoto pop2_undef;\n\t}\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t/* When JX/JC not in use, the type mask above will avoid this case if needed. */\n\tcase DUK_TAG_UNDEFINED: {\n\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined);\n\t\tbreak;\n\t}\n#endif\n\tcase DUK_TAG_NULL: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_TVAL_GET_BOOLEAN(tv) ?\n\t\t                 DUK_STRIDX_TRUE : DUK_STRIDX_FALSE);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t/* When JX/JC not in use, the type mask above will avoid this case if needed. */\n\tcase DUK_TAG_POINTER: {\n\t\tduk__enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv));\n\t\tbreak;\n\t}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tgoto pop2_undef;\n\t\t}\n\t\tduk__enc_quote_string(js_ctx, h);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* Function values are handled completely above (including\n\t\t * coercion results):\n\t\t */\n\t\tDUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE(h));\n\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tduk__enc_array(js_ctx);\n\t\t} else {\n\t\t\tduk__enc_object(js_ctx);\n\t\t}\n\t\tbreak;\n\t}\n\t/* Because plain buffers mimics Uint8Array, they have enumerable\n\t * index properties [0,byteLength[.  Because JSON only serializes\n\t * enumerable own properties, no properties can be serialized for\n\t * plain buffers (all virtual properties are non-enumerable).  However,\n\t * there may be a .toJSON() method which was already handled above.\n\t */\n\tcase DUK_TAG_BUFFER: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tduk__enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv));\n\t\t\tbreak;\n\t\t}\n#endif\n\n\t\t/* Could implement a fastpath, but the fast path would need\n\t\t * to handle realloc side effects correctly.\n\t\t */\n\t\tduk_to_object(thr, -1);\n\t\tduk__enc_object(js_ctx);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t/* We only get here when doing non-standard JSON encoding */\n\t\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);\n\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function);\n#else\n\t\t/* Standard JSON omits functions */\n\t\tDUK_UNREACHABLE();\n#endif\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\t/* Number serialization has a significant impact relative to\n\t\t * other fast path code, so careful fast path for fastints.\n\t\t */\n\t\tduk__enc_fastint_tval(js_ctx, tv);\n\t\tbreak;\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\t/* XXX: A fast path for usual integers would be useful when\n\t\t * fastint support is not enabled.\n\t\t */\n\t\tduk__enc_double(js_ctx);\n\t\tbreak;\n\t}\n\t}\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n pop2_emitted:\n#endif\n\tduk_pop_2(thr); /* [ ... key val ] -> [ ... ] */\n\treturn 1;  /* emitted */\n\n pop2_undef:\n\tduk_pop_2(thr);  /* [ ... key val ] -> [ ... ] */\n\treturn 0;  /* not emitted */\n}\n\n/* E5 Section 15.12.3, main algorithm, step 4.b.ii steps 1-4. */\nDUK_LOCAL duk_bool_t duk__enc_allow_into_proplist(duk_tval *tv) {\n\tduk_small_int_t c;\n\n\t/* XXX: some kind of external internal type checker?\n\t * - type mask; symbol flag; class mask\n\t */\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_STRING(tv)) {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn 1;\n\t} else if (DUK_TVAL_IS_NUMBER(tv)) {\n\t\treturn 1;\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tc = (duk_small_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h);\n\t\tif (c == DUK_HOBJECT_CLASS_STRING || c == DUK_HOBJECT_CLASS_NUMBER) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n/*\n *  JSON.stringify() fast path\n *\n *  Otherwise supports full JSON, JX, and JC features, but bails out on any\n *  possible side effect which might change the value being serialized.  The\n *  fast path can take advantage of the fact that the value being serialized\n *  is unchanged so that we can walk directly through property tables etc.\n */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\nDUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, duk_tval *tv) {\n\tduk_uint_fast32_t i, n;\n\n\tDUK_DDD(DUK_DDDPRINT(\"stringify fast: %!T\", tv));\n\n\tDUK_ASSERT(js_ctx != NULL);\n\tDUK_ASSERT(js_ctx->thr != NULL);\n\n#if 0 /* disabled for now */\n restart_match:\n#endif\n\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible) {\n\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined);\n\t\t\tbreak;\n\t\t} else {\n\t\t\tgoto emit_undefined;\n\t\t}\n#else\n\t\tgoto emit_undefined;\n#endif\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_TVAL_GET_BOOLEAN(tv) ?\n\t\t                 DUK_STRIDX_TRUE : DUK_STRIDX_FALSE);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tgoto emit_undefined;\n\t\t}\n\t\tduk__enc_quote_string(js_ctx, h);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *obj;\n\t\tduk_tval *tv_val;\n\t\tduk_bool_t emitted = 0;\n\t\tduk_uint32_t c_bit, c_all, c_array, c_unbox, c_undef,\n\t\t             c_func, c_bufobj, c_object, c_abort;\n\n\t\t/* For objects JSON.stringify() only looks for own, enumerable\n\t\t * properties which is nice for the fast path here.\n\t\t *\n\t\t * For arrays JSON.stringify() uses [[Get]] so it will actually\n\t\t * inherit properties during serialization!  This fast path\n\t\t * supports gappy arrays as long as there's no actual inherited\n\t\t * property (which might be a getter etc).\n\t\t *\n\t\t * Since recursion only happens for objects, we can have both\n\t\t * recursion and loop checks here.  We use a simple, depth-limited\n\t\t * loop check in the fast path because the object-based tracking\n\t\t * is very slow (when tested, it accounted for 50% of fast path\n\t\t * execution time for input data with a lot of small objects!).\n\t\t */\n\n\t\t/* XXX: for real world code, could just ignore array inheritance\n\t\t * and only look at array own properties.\n\t\t */\n\n\t\t/* We rely on a few object flag / class number relationships here,\n\t\t * assert for them.\n\t\t */\n\n\t\tobj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(obj != NULL);\n\t\tDUK_HOBJECT_ASSERT_VALID(obj);\n\n\t\t/* Once recursion depth is increased, exit path must decrease\n\t\t * it (though it's OK to abort the fast path).\n\t\t */\n\n\t\tDUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0);  /* unsigned */\n\t\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\t\tif (js_ctx->recursion_depth >= js_ctx->recursion_limit) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"fast path recursion limit\"));\n\t\t\tDUK_ERROR_RANGE(js_ctx->thr, DUK_STR_JSONDEC_RECLIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\n\t\tfor (i = 0, n = (duk_uint_fast32_t) js_ctx->recursion_depth; i < n; i++) {\n\t\t\tif (DUK_UNLIKELY(js_ctx->visiting[i] == obj)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"fast path loop detect\"));\n\t\t\t\tDUK_ERROR_TYPE(js_ctx->thr, DUK_STR_CYCLIC_INPUT);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\n\t\t/* Guaranteed by recursion_limit setup so we don't have to\n\t\t * check twice.\n\t\t */\n\t\tDUK_ASSERT(js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY);\n\t\tjs_ctx->visiting[js_ctx->recursion_depth] = obj;\n\t\tjs_ctx->recursion_depth++;\n\n\t\t/* If object has a .toJSON() property, we can't be certain\n\t\t * that it wouldn't mutate any value arbitrarily, so bail\n\t\t * out of the fast path.\n\t\t *\n\t\t * If an object is a Proxy we also can't avoid side effects\n\t\t * so abandon.\n\t\t */\n\t\t/* XXX: non-callable .toJSON() doesn't need to cause an abort\n\t\t * but does at the moment, probably not worth fixing.\n\t\t */\n\t\tif (duk_hobject_hasprop_raw(js_ctx->thr, obj, DUK_HTHREAD_STRING_TO_JSON(js_ctx->thr)) ||\n\t\t    DUK_HOBJECT_IS_PROXY(obj)) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"object has a .toJSON property or object is a Proxy, abort fast path\"));\n\t\t\tgoto abort_fastpath;\n\t\t}\n\n\t\t/* We could use a switch-case for the class number but it turns out\n\t\t * a small if-else ladder on class masks is better.  The if-ladder\n\t\t * should be in order of relevancy.\n\t\t */\n\n\t\t/* XXX: move masks to js_ctx? they don't change during one\n\t\t * fast path invocation.\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_CLASS_MAX <= 31);\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tc_all = DUK_HOBJECT_CMASK_ALL;\n\t\t\tc_array = DUK_HOBJECT_CMASK_ARRAY;\n\t\t\tc_unbox = DUK_HOBJECT_CMASK_NUMBER |\n\t\t\t          DUK_HOBJECT_CMASK_STRING |\n\t\t\t          DUK_HOBJECT_CMASK_BOOLEAN |\n\t\t\t          DUK_HOBJECT_CMASK_POINTER;  /* Symbols are not unboxed. */\n\t\t\tc_func = DUK_HOBJECT_CMASK_FUNCTION;\n\t\t\tc_bufobj = DUK_HOBJECT_CMASK_ALL_BUFOBJS;\n\t\t\tc_undef = 0;\n\t\t\tc_abort = 0;\n\t\t\tc_object = c_all & ~(c_array | c_unbox | c_func | c_bufobj | c_undef | c_abort);\n\t\t}\n\t\telse\n#endif\n\t\t{\n\t\t\tc_all = DUK_HOBJECT_CMASK_ALL;\n\t\t\tc_array = DUK_HOBJECT_CMASK_ARRAY;\n\t\t\tc_unbox = DUK_HOBJECT_CMASK_NUMBER |\n\t\t\t          DUK_HOBJECT_CMASK_STRING |\n\t\t\t          DUK_HOBJECT_CMASK_BOOLEAN;  /* Symbols are not unboxed. */\n\t\t\tc_func = 0;\n\t\t\tc_bufobj = 0;\n\t\t\tc_undef = DUK_HOBJECT_CMASK_FUNCTION |\n\t\t\t          DUK_HOBJECT_CMASK_POINTER;\n\t\t\t/* As the fast path doesn't currently properly support\n\t\t\t * duk_hbufobj virtual properties, abort fast path if\n\t\t\t * we encounter them in plain JSON mode.\n\t\t\t */\n\t\t\tc_abort = DUK_HOBJECT_CMASK_ALL_BUFOBJS;\n\t\t\tc_object = c_all & ~(c_array | c_unbox | c_func | c_bufobj | c_undef | c_abort);\n\t\t}\n\n\t\tc_bit = (duk_uint32_t) DUK_HOBJECT_GET_CLASS_MASK(obj);\n\t\tif (c_bit & c_object) {\n\t\t\t/* All other object types. */\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);\n\n\t\t\t/* A non-Array object should not have an array part in practice.\n\t\t\t * But since it is supported internally (and perhaps used at some\n\t\t\t * point), check and abandon if that's the case.\n\t\t\t */\n\t\t\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"non-Array object has array part, abort fast path\"));\n\t\t\t\tgoto abort_fastpath;\n\t\t\t}\n\n\t\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\t\tduk_hstring *k;\n\t\t\t\tduk_size_t prev_size;\n\n\t\t\t\tk = DUK_HOBJECT_E_GET_KEY(js_ctx->thr->heap, obj, i);\n\t\t\t\tif (!k) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (DUK_HSTRING_HAS_ARRIDX(k)) {\n\t\t\t\t\t/* If an object has array index keys we would need\n\t\t\t\t\t * to sort them into the ES2015 enumeration order to\n\t\t\t\t\t * be consistent with the slow path.  Abort the fast\n\t\t\t\t\t * path and handle in the slow path for now.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"property key is an array index, abort fast path\"));\n\t\t\t\t\tgoto abort_fastpath;\n\t\t\t\t}\n\t\t\t\tif (!DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(js_ctx->thr->heap, obj, i)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(js_ctx->thr->heap, obj, i)) {\n\t\t\t\t\t/* Getter might have arbitrary side effects,\n\t\t\t\t\t * so bail out.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"property is an accessor, abort fast path\"));\n\t\t\t\t\tgoto abort_fastpath;\n\t\t\t\t}\n\t\t\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(k))) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\ttv_val = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(js_ctx->thr->heap, obj, i);\n\n\t\t\t\tprev_size = DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw);\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t\t\t\tduk__enc_key_autoquote(js_ctx, k);\n\t\t\t\t\tDUK__EMIT_2(js_ctx, DUK_ASC_COLON, DUK_ASC_SPACE);\n\t\t\t\t} else {\n\t\t\t\t\tduk__enc_key_autoquote(js_ctx, k);\n\t\t\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COLON);\n\t\t\t\t}\n\n\t\t\t\tif (duk__json_stringify_fast_value(js_ctx, tv_val) == 0) {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"prop value not supported, rewind key and colon\"));\n\t\t\t\t\tDUK_BW_SET_SIZE(js_ctx->thr, &js_ctx->bw, prev_size);\n\t\t\t\t} else {\n\t\t\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\t\t\t\temitted = 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* If any non-Array value had enumerable virtual own\n\t\t\t * properties, they should be serialized here (actually,\n\t\t\t * before the explicit properties).  Standard types don't.\n\t\t\t */\n\n\t\t\tif (emitted) {\n\t\t\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\t\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t\t\t}\n\t\t\t}\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);\n\t\t} else if (c_bit & c_array) {\n\t\t\tduk_uint_fast32_t arr_len;\n\t\t\tduk_uint_fast32_t asize;\n\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_LBRACKET);\n\n\t\t\t/* Assume arrays are dense in the fast path. */\n\t\t\tif (!DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"Array object is sparse, abort fast path\"));\n\t\t\t\tgoto abort_fastpath;\n\t\t\t}\n\n\t\t\tarr_len = (duk_uint_fast32_t) ((duk_harray *) obj)->length;\n\t\t\tasize = (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(obj);\n\t\t\t/* Array part may be larger than 'length'; if so, iterate\n\t\t\t * only up to array 'length'.  Array part may also be smaller\n\t\t\t * than 'length' in some cases.\n\t\t\t */\n\t\t\tfor (i = 0; i < arr_len; i++) {\n\t\t\t\tduk_tval *tv_arrval;\n\t\t\t\tduk_hstring *h_tmp;\n\t\t\t\tduk_bool_t has_inherited;\n\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t\t\t}\n\n\t\t\t\tif (DUK_LIKELY(i < asize)) {\n\t\t\t\t\ttv_arrval = DUK_HOBJECT_A_GET_VALUE_PTR(js_ctx->thr->heap, obj, i);\n\t\t\t\t\tif (DUK_LIKELY(!DUK_TVAL_IS_UNUSED(tv_arrval))) {\n\t\t\t\t\t\t/* Expected case: element is present. */\n\t\t\t\t\t\tif (duk__json_stringify_fast_value(js_ctx, tv_arrval) == 0) {\n\t\t\t\t\t\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tgoto elem_done;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* Gap in array; check for inherited property,\n\t\t\t\t * bail out if one exists.  This should be enough\n\t\t\t\t * to support gappy arrays for all practical code.\n\t\t\t\t */\n\n\t\t\t\th_tmp = duk_push_uint_to_hstring(js_ctx->thr, (duk_uint_t) i);\n\t\t\t\thas_inherited = duk_hobject_hasprop_raw(js_ctx->thr, obj, h_tmp);\n\t\t\t\tduk_pop(js_ctx->thr);\n\t\t\t\tif (has_inherited) {\n\t\t\t\t\tDUK_D(DUK_DPRINT(\"gap in array, conflicting inherited property, abort fast path\"));\n\t\t\t\t\tgoto abort_fastpath;\n\t\t\t\t}\n\n\t\t\t\t/* Ordinary gap, undefined encodes to 'null' in\n\t\t\t\t * standard JSON, but JX/JC use their form for\n\t\t\t\t * undefined to better preserve the typing.\n\t\t\t\t */\n\t\t\t\tDUK_D(DUK_DPRINT(\"gap in array, no conflicting inherited property, remain on fast path\"));\n#if defined(DUK_USE_JX)\n\t\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined);\n#else\n\t\t\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n#endif\n\t\t\t\t/* fall through */\n\n\t\t\t elem_done:\n\t\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\t\t\temitted = 1;\n\t\t\t}\n\n\t\t\tif (emitted) {\n\t\t\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\t\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t\t\t}\n\t\t\t}\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET);\n\t\t} else if (c_bit & c_unbox) {\n\t\t\t/* Certain boxed types are required to go through\n\t\t\t * automatic unboxing.  Rely on internal value being\n\t\t\t * sane (to avoid infinite recursion).\n\t\t\t */\n\t\t\tDUK_ASSERT((c_bit & DUK_HOBJECT_CMASK_SYMBOL) == 0);  /* Symbols are not unboxed. */\n\n#if 1\n\t\t\t/* The code below is incorrect if .toString() or .valueOf() have\n\t\t\t * have been overridden.  The correct approach would be to look up\n\t\t\t * the method(s) and if they resolve to the built-in function we\n\t\t\t * can safely bypass it and look up the internal value directly.\n\t\t\t * Unimplemented for now, abort fast path for boxed values.\n\t\t\t */\n\t\t\tgoto abort_fastpath;\n#else  /* disabled */\n\t\t\t/* Disabled until fixed, see above. */\n\t\t\tduk_tval *tv_internal;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"auto unboxing in fast path\"));\n\n\t\t\ttv_internal = duk_hobject_get_internal_value_tval_ptr(js_ctx->thr->heap, obj);\n\t\t\tDUK_ASSERT(tv_internal != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_internal) ||\n\t\t\t           DUK_TVAL_IS_NUMBER(tv_internal) ||\n\t\t\t           DUK_TVAL_IS_BOOLEAN(tv_internal) ||\n\t\t\t           DUK_TVAL_IS_POINTER(tv_internal));\n\n\t\t\ttv = tv_internal;\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\t\t\tjs_ctx->recursion_depth--;  /* required to keep recursion depth correct */\n\t\t\tgoto restart_match;\n#endif  /* disabled */\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t} else if (c_bit & c_func) {\n\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t} else if (c_bit & c_bufobj) {\n\t\t\tduk__enc_bufobj(js_ctx, (duk_hbufobj *) obj);\n#endif\n#endif\n\t\t} else if (c_bit & c_abort) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"abort fast path for unsupported type\"));\n\t\t\tgoto abort_fastpath;\n\t\t} else {\n\t\t\tDUK_ASSERT((c_bit & c_undef) != 0);\n\n\t\t\t/* Must decrease recursion depth before returning. */\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\t\t\tjs_ctx->recursion_depth--;\n\t\t\tgoto emit_undefined;\n\t\t}\n\n\t\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\t\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\t\tjs_ctx->recursion_depth--;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\t/* Plain buffers are treated like Uint8Arrays: they have\n\t\t * enumerable indices.  Other virtual properties are not\n\t\t * enumerable, and inherited properties are not serialized.\n\t\t * However, there can be a replacer (not relevant here) or\n\t\t * a .toJSON() method (which we need to check for explicitly).\n\t\t */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (duk_hobject_hasprop_raw(js_ctx->thr,\n\t\t                            js_ctx->thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE],\n\t\t                            DUK_HTHREAD_STRING_TO_JSON(js_ctx->thr))) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"value is a plain buffer and there's an inherited .toJSON, abort fast path\"));\n\t\t\tgoto abort_fastpath;\n\t\t}\n#endif\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tduk__enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv));\n\t\t\tbreak;\n\t\t}\n#endif\n\n\t\t/* Plain buffers mimic Uint8Arrays, and have enumerable index\n\t\t * properties.\n\t\t */\n\t\tduk__enc_buffer_json_fastpath(js_ctx, DUK_TVAL_GET_BUFFER(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_POINTER: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tduk__enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv));\n\t\t\tbreak;\n\t\t} else {\n\t\t\tgoto emit_undefined;\n\t\t}\n#else\n\t\tgoto emit_undefined;\n#endif\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* A lightfunc might also inherit a .toJSON() so just bail out. */\n\t\t/* XXX: Could just lookup .toJSON() and continue in fast path,\n\t\t * as it would almost never be defined.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"value is a lightfunc, abort fast path\"));\n\t\tgoto abort_fastpath;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT: {\n\t\t/* Number serialization has a significant impact relative to\n\t\t * other fast path code, so careful fast path for fastints.\n\t\t */\n\t\tduk__enc_fastint_tval(js_ctx, tv);\n\t\tbreak;\n\t}\n#endif\n\tdefault: {\n\t\t/* XXX: A fast path for usual integers would be useful when\n\t\t * fastint support is not enabled.\n\t\t */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\n\t\t/* XXX: Stack discipline is annoying, could be changed in numconv. */\n\t\tduk_push_tval(js_ctx->thr, tv);\n\t\tduk__enc_double(js_ctx);\n\t\tduk_pop(js_ctx->thr);\n\n#if 0\n\t\t/* Could also rely on native sprintf(), but it will handle\n\t\t * values like NaN, Infinity, -0, exponent notation etc in\n\t\t * a JSON-incompatible way.\n\t\t */\n\t\tduk_double_t d;\n\t\tchar buf[64];\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\t\td = DUK_TVAL_GET_DOUBLE(tv);\n\t\tDUK_SPRINTF(buf, \"%lg\", d);\n\t\tDUK__EMIT_CSTR(js_ctx, buf);\n#endif\n\t}\n\t}\n\treturn 1;  /* not undefined */\n\n emit_undefined:\n\treturn 0;  /* value was undefined/unsupported */\n\n abort_fastpath:\n\t/* Error message doesn't matter: the error is ignored anyway. */\n\tDUK_DD(DUK_DDPRINT(\"aborting fast path\"));\n\tDUK_ERROR_INTERNAL(js_ctx->thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_LOCAL duk_ret_t duk__json_stringify_fast(duk_hthread *thr, void *udata) {\n\tduk_json_enc_ctx *js_ctx;\n\tduk_tval *tv;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(udata != NULL);\n\n\tjs_ctx = (duk_json_enc_ctx *) udata;\n\tDUK_ASSERT(js_ctx != NULL);\n\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tif (duk__json_stringify_fast_value(js_ctx, tv) == 0) {\n\t\tDUK_DD(DUK_DDPRINT(\"top level value not supported, fail fast path\"));\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);  /* Error message is ignored, so doesn't matter. */\n\t}\n\n\treturn 0;\n}\n#endif  /* DUK_USE_JSON_STRINGIFY_FASTPATH */\n\n/*\n *  Top level wrappers\n */\n\nDUK_INTERNAL\nvoid duk_bi_json_parse_helper(duk_hthread *thr,\n                              duk_idx_t idx_value,\n                              duk_idx_t idx_reviver,\n                              duk_small_uint_t flags) {\n\tduk_json_dec_ctx js_ctx_alloc;\n\tduk_json_dec_ctx *js_ctx = &js_ctx_alloc;\n\tduk_hstring *h_text;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top = duk_get_top(thr);\n#endif\n\n\t/* negative top-relative indices not allowed now */\n\tDUK_ASSERT(idx_value == DUK_INVALID_INDEX || idx_value >= 0);\n\tDUK_ASSERT(idx_reviver == DUK_INVALID_INDEX || idx_reviver >= 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON parse start: text=%!T, reviver=%!T, flags=0x%08lx, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_reviver),\n\t                     (unsigned long) flags,\n\t                     (long) duk_get_top(thr)));\n\n\tduk_memzero(&js_ctx_alloc, sizeof(js_ctx_alloc));\n\tjs_ctx->thr = thr;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t/* nothing now */\n#endif\n\tjs_ctx->recursion_limit = DUK_USE_JSON_DEC_RECLIMIT;\n\tDUK_ASSERT(js_ctx->recursion_depth == 0);\n\n\t/* Flag handling currently assumes that flags are consistent.  This is OK\n\t * because the call sites are now strictly controlled.\n\t */\n\n\tjs_ctx->flags = flags;\n#if defined(DUK_USE_JX)\n\tjs_ctx->flag_ext_custom = flags & DUK_JSON_FLAG_EXT_CUSTOM;\n#endif\n#if defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_compatible = flags & DUK_JSON_FLAG_EXT_COMPATIBLE;\n#endif\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_custom_or_compatible = flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE);\n#endif\n\n\th_text = duk_to_hstring(thr, idx_value);  /* coerce in-place; rejects Symbols */\n\tDUK_ASSERT(h_text != NULL);\n\n\t/* JSON parsing code is allowed to read [p_start,p_end]: p_end is\n\t * valid and points to the string NUL terminator (which is always\n\t * guaranteed for duk_hstrings.\n\t */\n\tjs_ctx->p_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_text);\n\tjs_ctx->p = js_ctx->p_start;\n\tjs_ctx->p_end = ((const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_text)) +\n\t                DUK_HSTRING_GET_BYTELEN(h_text);\n\tDUK_ASSERT(*(js_ctx->p_end) == 0x00);\n\n\tduk__dec_value(js_ctx);  /* -> [ ... value ] */\n\n\t/* Trailing whitespace has been eaten by duk__dec_value(), so if\n\t * we're not at end of input here, it's a SyntaxError.\n\t */\n\n\tif (js_ctx->p != js_ctx->p_end) {\n\t\tduk__dec_syntax_error(js_ctx);\n\t}\n\n\tif (duk_is_callable(thr, idx_reviver)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"applying reviver: %!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_reviver)));\n\n\t\tjs_ctx->idx_reviver = idx_reviver;\n\n\t\tduk_push_object(thr);\n\t\tduk_dup_m2(thr);  /* -> [ ... val root val ] */\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_EMPTY_STRING);  /* default attrs ok */\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_EMPTY_STRING);  /* -> [ ... val root \"\" ] */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"start reviver walk, root=%!T, name=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\tduk__dec_reviver_walk(js_ctx);  /* [ ... val root \"\" ] -> [ ... val val' ] */\n\t\tduk_remove_m2(thr);             /* -> [ ... val' ] */\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"reviver does not exist or is not callable: %!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_reviver)));\n\t}\n\n\t/* Final result is at stack top. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON parse end: text=%!T, reviver=%!T, flags=0x%08lx, result=%!T, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_reviver),\n\t                     (unsigned long) flags,\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (long) duk_get_top(thr)));\n\n\tDUK_ASSERT(duk_get_top(thr) == entry_top + 1);\n}\n\nDUK_INTERNAL\nvoid duk_bi_json_stringify_helper(duk_hthread *thr,\n                                  duk_idx_t idx_value,\n                                  duk_idx_t idx_replacer,\n                                  duk_idx_t idx_space,\n                                  duk_small_uint_t flags) {\n\tduk_json_enc_ctx js_ctx_alloc;\n\tduk_json_enc_ctx *js_ctx = &js_ctx_alloc;\n\tduk_hobject *h;\n\tduk_idx_t idx_holder;\n\tduk_idx_t entry_top;\n\n\t/* negative top-relative indices not allowed now */\n\tDUK_ASSERT(idx_value == DUK_INVALID_INDEX || idx_value >= 0);\n\tDUK_ASSERT(idx_replacer == DUK_INVALID_INDEX || idx_replacer >= 0);\n\tDUK_ASSERT(idx_space == DUK_INVALID_INDEX || idx_space >= 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON stringify start: value=%!T, replacer=%!T, space=%!T, flags=0x%08lx, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_replacer),\n\t                     (duk_tval *) duk_get_tval(thr, idx_space),\n\t                     (unsigned long) flags,\n\t                     (long) duk_get_top(thr)));\n\n\tentry_top = duk_get_top(thr);\n\n\t/*\n\t *  Context init\n\t */\n\n\tduk_memzero(&js_ctx_alloc, sizeof(js_ctx_alloc));\n\tjs_ctx->thr = thr;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tjs_ctx->h_replacer = NULL;\n\tjs_ctx->h_gap = NULL;\n#endif\n\tjs_ctx->idx_proplist = -1;\n\n\t/* Flag handling currently assumes that flags are consistent.  This is OK\n\t * because the call sites are now strictly controlled.\n\t */\n\n\tjs_ctx->flags = flags;\n\tjs_ctx->flag_ascii_only = flags & DUK_JSON_FLAG_ASCII_ONLY;\n\tjs_ctx->flag_avoid_key_quotes = flags & DUK_JSON_FLAG_AVOID_KEY_QUOTES;\n#if defined(DUK_USE_JX)\n\tjs_ctx->flag_ext_custom = flags & DUK_JSON_FLAG_EXT_CUSTOM;\n#endif\n#if defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_compatible = flags & DUK_JSON_FLAG_EXT_COMPATIBLE;\n#endif\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_custom_or_compatible = flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE);\n#endif\n\n\t/* The #if defined() clutter here handles the JX/JC enable/disable\n\t * combinations properly.\n\t */\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tjs_ctx->stridx_custom_undefined = DUK_STRIDX_LC_NULL;  /* standard JSON; array gaps */\n#if defined(DUK_USE_JX)\n\tif (flags & DUK_JSON_FLAG_EXT_CUSTOM) {\n\t\tjs_ctx->stridx_custom_undefined = DUK_STRIDX_LC_UNDEFINED;\n\t\tjs_ctx->stridx_custom_nan = DUK_STRIDX_NAN;\n\t\tjs_ctx->stridx_custom_neginf = DUK_STRIDX_MINUS_INFINITY;\n\t\tjs_ctx->stridx_custom_posinf = DUK_STRIDX_INFINITY;\n\t\tjs_ctx->stridx_custom_function =\n\t\t        (flags & DUK_JSON_FLAG_AVOID_KEY_QUOTES) ?\n\t\t                DUK_STRIDX_JSON_EXT_FUNCTION2 :\n\t\t                DUK_STRIDX_JSON_EXT_FUNCTION1;\n\t}\n#endif  /* DUK_USE_JX */\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\telse\n#endif  /* DUK_USE_JX && DUK_USE_JC */\n#if defined(DUK_USE_JC)\n\tif (js_ctx->flags & DUK_JSON_FLAG_EXT_COMPATIBLE) {\n\t\tjs_ctx->stridx_custom_undefined = DUK_STRIDX_JSON_EXT_UNDEFINED;\n\t\tjs_ctx->stridx_custom_nan = DUK_STRIDX_JSON_EXT_NAN;\n\t\tjs_ctx->stridx_custom_neginf = DUK_STRIDX_JSON_EXT_NEGINF;\n\t\tjs_ctx->stridx_custom_posinf = DUK_STRIDX_JSON_EXT_POSINF;\n\t\tjs_ctx->stridx_custom_function = DUK_STRIDX_JSON_EXT_FUNCTION1;\n\t}\n#endif  /* DUK_USE_JC */\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tif (js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM |\n\t                     DUK_JSON_FLAG_EXT_COMPATIBLE)) {\n\t\tDUK_ASSERT(js_ctx->mask_for_undefined == 0);  /* already zero */\n\t}\n\telse\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\t{\n\t\t/* Plain buffer is treated like ArrayBuffer and serialized.\n\t\t * Lightfuncs are treated like objects, but JSON explicitly\n\t\t * skips serializing Function objects so we can just reject\n\t\t * lightfuncs here.\n\t\t */\n\t\tjs_ctx->mask_for_undefined = DUK_TYPE_MASK_UNDEFINED |\n\t\t                             DUK_TYPE_MASK_POINTER |\n\t\t                             DUK_TYPE_MASK_LIGHTFUNC;\n\t}\n\n\tDUK_BW_INIT_PUSHBUF(thr, &js_ctx->bw, DUK__JSON_STRINGIFY_BUFSIZE);\n\n\tjs_ctx->idx_loop = duk_push_bare_object(thr);\n\tDUK_ASSERT(js_ctx->idx_loop >= 0);\n\n\t/* [ ... buf loop ] */\n\n\t/*\n\t *  Process replacer/proplist (2nd argument to JSON.stringify)\n\t */\n\n\th = duk_get_hobject(thr, idx_replacer);\n\tif (h != NULL) {\n\t\tif (DUK_HOBJECT_IS_CALLABLE(h)) {\n\t\t\tjs_ctx->h_replacer = h;\n\t\t} else if (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\t/* Here the specification requires correct array index enumeration\n\t\t\t * which is a bit tricky for sparse arrays (it is handled by the\n\t\t\t * enum setup code).  We now enumerate ancestors too, although the\n\t\t\t * specification is not very clear on whether that is required.\n\t\t\t */\n\n\t\t\tduk_uarridx_t plist_idx = 0;\n\t\t\tduk_small_uint_t enum_flags;\n\n\t\t\tjs_ctx->idx_proplist = duk_push_array(thr);  /* XXX: array internal? */\n\n\t\t\tenum_flags = DUK_ENUM_ARRAY_INDICES_ONLY |\n\t\t\t             DUK_ENUM_SORT_ARRAY_INDICES;  /* expensive flag */\n\t\t\tduk_enum(thr, idx_replacer, enum_flags);\n\t\t\twhile (duk_next(thr, -1 /*enum_index*/, 1 /*get_value*/)) {\n\t\t\t\t/* [ ... proplist enum_obj key val ] */\n\t\t\t\tif (duk__enc_allow_into_proplist(duk_get_tval(thr, -1))) {\n\t\t\t\t\t/* XXX: duplicates should be eliminated here */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proplist enum: key=%!T, val=%!T --> accept\",\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\t\t\tduk_to_string(thr, -1);  /* extra coercion of strings is OK */\n\t\t\t\t\tduk_put_prop_index(thr, -4, plist_idx);  /* -> [ ... proplist enum_obj key ] */\n\t\t\t\t\tplist_idx++;\n\t\t\t\t\tduk_pop(thr);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proplist enum: key=%!T, val=%!T --> reject\",\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\t\t\tduk_pop_2(thr);\n\t\t\t\t}\n                        }\n                        duk_pop(thr);  /* pop enum */\n\n\t\t\t/* [ ... proplist ] */\n\t\t}\n\t}\n\n\t/* [ ... buf loop (proplist) ] */\n\n\t/*\n\t *  Process space (3rd argument to JSON.stringify)\n\t */\n\n\th = duk_get_hobject(thr, idx_space);\n\tif (h != NULL) {\n\t\tduk_small_uint_t c = DUK_HOBJECT_GET_CLASS_NUMBER(h);\n\t\tif (c == DUK_HOBJECT_CLASS_NUMBER) {\n\t\t\tduk_to_number(thr, idx_space);\n\t\t} else if (c == DUK_HOBJECT_CLASS_STRING) {\n\t\t\tduk_to_string(thr, idx_space);\n\t\t}\n\t}\n\n\tif (duk_is_number(thr, idx_space)) {\n\t\tduk_small_int_t nspace;\n\t\t/* spaces[] must be static to allow initializer with old compilers like BCC */\n\t\tstatic const char spaces[10] = {\n\t\t\tDUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE,\n\t\t\tDUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE,\n\t\t\tDUK_ASC_SPACE, DUK_ASC_SPACE\n\t\t};  /* XXX: helper */\n\n\t\t/* ToInteger() coercion; NaN -> 0, infinities are clamped to 0 and 10 */\n\t\tnspace = (duk_small_int_t) duk_to_int_clamped(thr, idx_space, 0 /*minval*/, 10 /*maxval*/);\n\t\tDUK_ASSERT(nspace >= 0 && nspace <= 10);\n\n\t\tduk_push_lstring(thr, spaces, (duk_size_t) nspace);\n\t\tjs_ctx->h_gap = duk_known_hstring(thr, -1);\n\t\tDUK_ASSERT(js_ctx->h_gap != NULL);\n\t} else if (duk_is_string_notsymbol(thr, idx_space)) {\n\t\tduk_dup(thr, idx_space);\n\t\tduk_substring(thr, -1, 0, 10);  /* clamp to 10 chars */\n\t\tjs_ctx->h_gap = duk_known_hstring(thr, -1);\n\t} else {\n\t\t/* nop */\n\t}\n\n\tif (js_ctx->h_gap != NULL) {\n\t\t/* If gap is empty, behave as if not given at all.  Check\n\t\t * against byte length because character length is more\n\t\t * expensive.\n\t\t */\n\t\tif (DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) == 0) {\n\t\t\tjs_ctx->h_gap = NULL;\n\t\t}\n\t}\n\n\t/* [ ... buf loop (proplist) (gap) ] */\n\n\t/*\n\t *  Fast path: assume no mutation, iterate object property tables\n\t *  directly; bail out if that assumption doesn't hold.\n\t */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\n\tif (js_ctx->h_replacer == NULL &&  /* replacer is a mutation risk */\n\t    js_ctx->idx_proplist == -1) {  /* proplist is very rare */\n\t\tduk_int_t pcall_rc;\n\t\tduk_small_uint_t prev_ms_base_flags;\n\n\t\tDUK_DD(DUK_DDPRINT(\"try JSON.stringify() fast path\"));\n\n\t\t/* Use recursion_limit to ensure we don't overwrite js_ctx->visiting[]\n\t\t * array so we don't need two counter checks in the fast path.  The\n\t\t * slow path has a much larger recursion limit which we'll use if\n\t\t * necessary.\n\t\t */\n\t\tDUK_ASSERT(DUK_USE_JSON_ENC_RECLIMIT >= DUK_JSON_ENC_LOOPARRAY);\n\t\tjs_ctx->recursion_limit = DUK_JSON_ENC_LOOPARRAY;\n\t\tDUK_ASSERT(js_ctx->recursion_depth == 0);\n\n\t\t/* Execute the fast path in a protected call.  If any error is thrown,\n\t\t * fall back to the slow path.  This includes e.g. recursion limit\n\t\t * because the fast path has a smaller recursion limit (and simpler,\n\t\t * limited loop detection).\n\t\t */\n\n\t\tduk_dup(thr, idx_value);\n\n\t\t/* Must prevent finalizers which may have arbitrary side effects. */\n\t\tprev_ms_base_flags = thr->heap->ms_base_flags;\n\t\tthr->heap->ms_base_flags |=\n\t\t        DUK_MS_FLAG_NO_OBJECT_COMPACTION;      /* Avoid attempt to compact any objects. */\n\t\tthr->heap->pf_prevent_count++;                 /* Prevent finalizers. */\n\t\tDUK_ASSERT(thr->heap->pf_prevent_count != 0);  /* Wrap. */\n\n\t\tpcall_rc = duk_safe_call(thr, duk__json_stringify_fast, (void *) js_ctx /*udata*/, 1 /*nargs*/, 0 /*nret*/);\n\n\t\tDUK_ASSERT(thr->heap->pf_prevent_count > 0);\n\t\tthr->heap->pf_prevent_count--;\n\t\tthr->heap->ms_base_flags = prev_ms_base_flags;\n\n\t\tif (pcall_rc == DUK_EXEC_SUCCESS) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"fast path successful\"));\n\t\t\tDUK_BW_PUSH_AS_STRING(thr, &js_ctx->bw);\n\t\t\tgoto replace_finished;\n\t\t}\n\n\t\t/* We come here for actual aborts (like encountering .toJSON())\n\t\t * but also for recursion/loop errors.  Bufwriter size can be\n\t\t * kept because we'll probably need at least as much as we've\n\t\t * allocated so far.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"fast path failed, serialize using slow path instead\"));\n\t\tDUK_BW_RESET_SIZE(thr, &js_ctx->bw);\n\t\tjs_ctx->recursion_depth = 0;\n\t}\n#endif\n\n\t/*\n\t *  Create wrapper object and serialize\n\t */\n\n\tidx_holder = duk_push_object(thr);\n\tduk_dup(thr, idx_value);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_EMPTY_STRING);\n\n\tDUK_DDD(DUK_DDDPRINT(\"before: flags=0x%08lx, loop=%!T, replacer=%!O, \"\n\t                     \"proplist=%!T, gap=%!O, holder=%!T\",\n\t                     (unsigned long) js_ctx->flags,\n\t                     (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop),\n\t                     (duk_heaphdr *) js_ctx->h_replacer,\n\t                     (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(thr, js_ctx->idx_proplist) : NULL),\n\t                     (duk_heaphdr *) js_ctx->h_gap,\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* serialize the wrapper with empty string key */\n\n\tduk_push_hstring_empty(thr);\n\n\t/* [ ... buf loop (proplist) (gap) holder \"\" ] */\n\n\tjs_ctx->recursion_limit = DUK_USE_JSON_ENC_RECLIMIT;\n\tDUK_ASSERT(js_ctx->recursion_depth == 0);\n\n\tif (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_holder) == 0)) {  /* [ ... holder key ] -> [ ... holder ] */\n\t\t/* Result is undefined. */\n\t\tduk_push_undefined(thr);\n\t} else {\n\t\t/* Convert buffer to result string. */\n\t\tDUK_BW_PUSH_AS_STRING(thr, &js_ctx->bw);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"after: flags=0x%08lx, loop=%!T, replacer=%!O, \"\n\t                     \"proplist=%!T, gap=%!O, holder=%!T\",\n\t                     (unsigned long) js_ctx->flags,\n\t                     (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop),\n\t                     (duk_heaphdr *) js_ctx->h_replacer,\n\t                     (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(thr, js_ctx->idx_proplist) : NULL),\n\t                     (duk_heaphdr *) js_ctx->h_gap,\n\t                     (duk_tval *) duk_get_tval(thr, idx_holder)));\n\n\t/* The stack has a variable shape here, so force it to the\n\t * desired one explicitly.\n\t */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\n replace_finished:\n#endif\n\tduk_replace(thr, entry_top);\n\tduk_set_top(thr, entry_top + 1);\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON stringify end: value=%!T, replacer=%!T, space=%!T, \"\n\t                     \"flags=0x%08lx, result=%!T, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_replacer),\n\t                     (duk_tval *) duk_get_tval(thr, idx_space),\n\t                     (unsigned long) flags,\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (long) duk_get_top(thr)));\n\n\tDUK_ASSERT(duk_get_top(thr) == entry_top + 1);\n}\n\n#if defined(DUK_USE_JSON_BUILTIN)\n\n/*\n *  Entry points\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_json_object_parse(duk_hthread *thr) {\n\tduk_bi_json_parse_helper(thr,\n\t                         0 /*idx_value*/,\n\t                         1 /*idx_replacer*/,\n\t                         0 /*flags*/);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_json_object_stringify(duk_hthread *thr) {\n\tduk_bi_json_stringify_helper(thr,\n\t                             0 /*idx_value*/,\n\t                             1 /*idx_replacer*/,\n\t                             2 /*idx_space*/,\n\t                             0 /*flags*/);\n\treturn 1;\n}\n\n#endif  /* DUK_USE_JSON_BUILTIN */\n\n#endif  /* DUK_USE_JSON_SUPPORT */\n\n/* automatic undefs */\n#undef DUK__EMIT_1\n#undef DUK__EMIT_2\n#undef DUK__EMIT_CSTR\n#undef DUK__EMIT_HSTR\n#undef DUK__EMIT_STRIDX\n#undef DUK__JSON_DECSTR_BUFSIZE\n#undef DUK__JSON_DECSTR_CHUNKSIZE\n#undef DUK__JSON_ENCSTR_CHUNKSIZE\n#undef DUK__JSON_MAX_ESC_LEN\n#undef DUK__JSON_STRINGIFY_BUFSIZE\n#undef DUK__MKESC\n#undef DUK__UNEMIT_1\n#line 1 \"duk_bi_math.c\"\n/*\n *  Math built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_MATH_BUILTIN)\n\n/*\n *  Use static helpers which can work with math.h functions matching\n *  the following signatures. This is not portable if any of these math\n *  functions is actually a macro.\n *\n *  Typing here is intentionally 'double' wherever values interact with\n *  the standard library APIs.\n */\n\ntypedef double (*duk__one_arg_func)(double);\ntypedef double (*duk__two_arg_func)(double, double);\n\nDUK_LOCAL duk_ret_t duk__math_minmax(duk_hthread *thr, duk_double_t initial, duk__two_arg_func min_max) {\n\tduk_idx_t n = duk_get_top(thr);\n\tduk_idx_t i;\n\tduk_double_t res = initial;\n\tduk_double_t t;\n\n\t/*\n\t *  Note: fmax() does not match the E5 semantics.  E5 requires\n\t *  that if -any- input to Math.max() is a NaN, the result is a\n\t *  NaN.  fmax() will return a NaN only if -both- inputs are NaN.\n\t *  Same applies to fmin().\n\t *\n\t *  Note: every input value must be coerced with ToNumber(), even\n\t *  if we know the result will be a NaN anyway: ToNumber() may have\n\t *  side effects for which even order of evaluation matters.\n\t */\n\n\tfor (i = 0; i < n; i++) {\n\t\tt = duk_to_number(thr, i);\n\t\tif (DUK_FPCLASSIFY(t) == DUK_FP_NAN || DUK_FPCLASSIFY(res) == DUK_FP_NAN) {\n\t\t\t/* Note: not normalized, but duk_push_number() will normalize */\n\t\t\tres = (duk_double_t) DUK_DOUBLE_NAN;\n\t\t} else {\n\t\t\tres = (duk_double_t) min_max(res, (double) t);\n\t\t}\n\t}\n\n\tduk_push_number(thr, res);\n\treturn 1;\n}\n\nDUK_LOCAL double duk__fmin_fixed(double x, double y) {\n\t/* fmin() with args -0 and +0 is not guaranteed to return\n\t * -0 as ECMAScript requires.\n\t */\n\tif (x == 0 && y == 0) {\n\t\tduk_double_union du1, du2;\n\t\tdu1.d = x;\n\t\tdu2.d = y;\n\n\t\t/* Already checked to be zero so these must hold, and allow us\n\t\t * to check for \"x is -0 or y is -0\" by ORing the high parts\n\t\t * for comparison.\n\t\t */\n\t\tDUK_ASSERT(du1.ui[DUK_DBL_IDX_UI0] == 0 || du1.ui[DUK_DBL_IDX_UI0] == 0x80000000UL);\n\t\tDUK_ASSERT(du2.ui[DUK_DBL_IDX_UI0] == 0 || du2.ui[DUK_DBL_IDX_UI0] == 0x80000000UL);\n\n\t\t/* XXX: what's the safest way of creating a negative zero? */\n\t\tif ((du1.ui[DUK_DBL_IDX_UI0] | du2.ui[DUK_DBL_IDX_UI0]) != 0) {\n\t\t\t/* Enter here if either x or y (or both) is -0. */\n\t\t\treturn -0.0;\n\t\t} else {\n\t\t\treturn +0.0;\n\t\t}\n\t}\n\treturn duk_double_fmin(x, y);\n}\n\nDUK_LOCAL double duk__fmax_fixed(double x, double y) {\n\t/* fmax() with args -0 and +0 is not guaranteed to return\n\t * +0 as ECMAScript requires.\n\t */\n\tif (x == 0 && y == 0) {\n\t\tif (DUK_SIGNBIT(x) == 0 || DUK_SIGNBIT(y) == 0) {\n\t\t\treturn +0.0;\n\t\t} else {\n\t\t\treturn -0.0;\n\t\t}\n\t}\n\treturn duk_double_fmax(x, y);\n}\n\n#if defined(DUK_USE_ES6)\nDUK_LOCAL double duk__cbrt(double x) {\n\t/* cbrt() is C99.  To avoid hassling embedders with the need to provide a\n\t * cube root function, we can get by with pow().  The result is not\n\t * identical, but that's OK: ES2015 says it's implementation-dependent.\n\t */\n\n#if defined(DUK_CBRT)\n\t/* cbrt() matches ES2015 requirements. */\n\treturn DUK_CBRT(x);\n#else\n\tduk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\n\t/* pow() does not, however. */\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE || c == DUK_FP_ZERO) {\n\t\treturn x;\n\t}\n\tif (DUK_SIGNBIT(x)) {\n\t\treturn -DUK_POW(-x, 1.0 / 3.0);\n\t} else {\n\t\treturn DUK_POW(x, 1.0 / 3.0);\n\t}\n#endif\n}\n\nDUK_LOCAL double duk__log2(double x) {\n#if defined(DUK_LOG2)\n\treturn DUK_LOG2(x);\n#else\n\treturn DUK_LOG(x) * DUK_DOUBLE_LOG2E;\n#endif\n}\n\nDUK_LOCAL double duk__log10(double x) {\n#if defined(DUK_LOG10)\n\treturn DUK_LOG10(x);\n#else\n\treturn DUK_LOG(x) * DUK_DOUBLE_LOG10E;\n#endif\n}\n\nDUK_LOCAL double duk__trunc(double x) {\n#if defined(DUK_TRUNC)\n\treturn DUK_TRUNC(x);\n#else\n\t/* Handles -0 correctly: -0.0 matches 'x >= 0.0' but floor()\n\t * is required to return -0 when the argument is -0.\n\t */\n\treturn x >= 0.0 ? DUK_FLOOR(x) : DUK_CEIL(x);\n#endif\n}\n#endif  /* DUK_USE_ES6 */\n\nDUK_LOCAL double duk__round_fixed(double x) {\n\t/* Numbers half-way between integers must be rounded towards +Infinity,\n\t * e.g. -3.5 must be rounded to -3 (not -4).  When rounded to zero, zero\n\t * sign must be set appropriately.  E5.1 Section 15.8.2.15.\n\t *\n\t * Note that ANSI C round() is \"round to nearest integer, away from zero\",\n\t * which is incorrect for negative values.  Here we make do with floor().\n\t */\n\n\tduk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE || c == DUK_FP_ZERO) {\n\t\treturn x;\n\t}\n\n\t/*\n\t *  x is finite and non-zero\n\t *\n\t *  -1.6 -> floor(-1.1) -> -2\n\t *  -1.5 -> floor(-1.0) -> -1  (towards +Inf)\n\t *  -1.4 -> floor(-0.9) -> -1\n\t *  -0.5 -> -0.0               (special case)\n\t *  -0.1 -> -0.0               (special case)\n\t *  +0.1 -> +0.0               (special case)\n\t *  +0.5 -> floor(+1.0) -> 1   (towards +Inf)\n\t *  +1.4 -> floor(+1.9) -> 1\n\t *  +1.5 -> floor(+2.0) -> 2   (towards +Inf)\n\t *  +1.6 -> floor(+2.1) -> 2\n\t */\n\n\tif (x >= -0.5 && x < 0.5) {\n\t\t/* +0.5 is handled by floor, this is on purpose */\n\t\tif (x < 0.0) {\n\t\t\treturn -0.0;\n\t\t} else {\n\t\t\treturn +0.0;\n\t\t}\n\t}\n\n\treturn DUK_FLOOR(x + 0.5);\n}\n\n/* Wrappers for calling standard math library methods.  These may be required\n * on platforms where one or more of the math built-ins are defined as macros\n * or inline functions and are thus not suitable to be used as function pointers.\n */\n#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)\nDUK_LOCAL double duk__fabs(double x) {\n\treturn DUK_FABS(x);\n}\nDUK_LOCAL double duk__acos(double x) {\n\treturn DUK_ACOS(x);\n}\nDUK_LOCAL double duk__asin(double x) {\n\treturn DUK_ASIN(x);\n}\nDUK_LOCAL double duk__atan(double x) {\n\treturn DUK_ATAN(x);\n}\nDUK_LOCAL double duk__ceil(double x) {\n\treturn DUK_CEIL(x);\n}\nDUK_LOCAL double duk__cos(double x) {\n\treturn DUK_COS(x);\n}\nDUK_LOCAL double duk__exp(double x) {\n\treturn DUK_EXP(x);\n}\nDUK_LOCAL double duk__floor(double x) {\n\treturn DUK_FLOOR(x);\n}\nDUK_LOCAL double duk__log(double x) {\n\treturn DUK_LOG(x);\n}\nDUK_LOCAL double duk__sin(double x) {\n\treturn DUK_SIN(x);\n}\nDUK_LOCAL double duk__sqrt(double x) {\n\treturn DUK_SQRT(x);\n}\nDUK_LOCAL double duk__tan(double x) {\n\treturn DUK_TAN(x);\n}\nDUK_LOCAL double duk__atan2_fixed(double x, double y) {\n#if defined(DUK_USE_ATAN2_WORKAROUNDS)\n\t/* Specific fixes to common atan2() implementation issues:\n\t * - test-bug-mingw-math-issues.js\n\t */\n\tif (DUK_ISINF(x) && DUK_ISINF(y)) {\n\t\tif (DUK_SIGNBIT(x)) {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn -2.356194490192345;\n\t\t\t} else {\n\t\t\t\treturn -0.7853981633974483;\n\t\t\t}\n\t\t} else {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn 2.356194490192345;\n\t\t\t} else {\n\t\t\t\treturn 0.7853981633974483;\n\t\t\t}\n\t\t}\n\t}\n#else\n\t/* Some ISO C assumptions. */\n\tDUK_ASSERT(DUK_ATAN2(DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY) == 0.7853981633974483);\n\tDUK_ASSERT(DUK_ATAN2(-DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY) == -0.7853981633974483);\n\tDUK_ASSERT(DUK_ATAN2(DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY) == 2.356194490192345);\n\tDUK_ASSERT(DUK_ATAN2(-DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY) == -2.356194490192345);\n#endif\n\n\treturn DUK_ATAN2(x, y);\n}\n#endif  /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */\n\n/* order must match constants in genbuiltins.py */\nDUK_LOCAL const duk__one_arg_func duk__one_arg_funcs[] = {\n#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)\n\tduk__fabs,\n\tduk__acos,\n\tduk__asin,\n\tduk__atan,\n\tduk__ceil,\n\tduk__cos,\n\tduk__exp,\n\tduk__floor,\n\tduk__log,\n\tduk__round_fixed,\n\tduk__sin,\n\tduk__sqrt,\n\tduk__tan,\n#if defined(DUK_USE_ES6)\n\tduk__cbrt,\n\tduk__log2,\n\tduk__log10,\n\tduk__trunc\n#endif\n#else  /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */\n\tDUK_FABS,\n\tDUK_ACOS,\n\tDUK_ASIN,\n\tDUK_ATAN,\n\tDUK_CEIL,\n\tDUK_COS,\n\tDUK_EXP,\n\tDUK_FLOOR,\n\tDUK_LOG,\n\tduk__round_fixed,\n\tDUK_SIN,\n\tDUK_SQRT,\n\tDUK_TAN,\n#if defined(DUK_USE_ES6)\n\tduk__cbrt,\n\tduk__log2,\n\tduk__log10,\n\tduk__trunc\n#endif\n#endif  /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */\n};\n\n/* order must match constants in genbuiltins.py */\nDUK_LOCAL const duk__two_arg_func duk__two_arg_funcs[] = {\n#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)\n\tduk__atan2_fixed,\n\tduk_js_arith_pow\n#else\n\tduk__atan2_fixed,\n\tduk_js_arith_pow\n#endif\n};\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_onearg_shared(duk_hthread *thr) {\n\tduk_small_int_t fun_idx = duk_get_current_magic(thr);\n\tduk__one_arg_func fun;\n\tduk_double_t arg1;\n\n\tDUK_ASSERT(fun_idx >= 0);\n\tDUK_ASSERT(fun_idx < (duk_small_int_t) (sizeof(duk__one_arg_funcs) / sizeof(duk__one_arg_func)));\n\targ1 = duk_to_number(thr, 0);\n\tfun = duk__one_arg_funcs[fun_idx];\n\tduk_push_number(thr, (duk_double_t) fun((double) arg1));\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_twoarg_shared(duk_hthread *thr) {\n\tduk_small_int_t fun_idx = duk_get_current_magic(thr);\n\tduk__two_arg_func fun;\n\tduk_double_t arg1;\n\tduk_double_t arg2;\n\n\tDUK_ASSERT(fun_idx >= 0);\n\tDUK_ASSERT(fun_idx < (duk_small_int_t) (sizeof(duk__two_arg_funcs) / sizeof(duk__two_arg_func)));\n\targ1 = duk_to_number(thr, 0);  /* explicit ordered evaluation to match coercion semantics */\n\targ2 = duk_to_number(thr, 1);\n\tfun = duk__two_arg_funcs[fun_idx];\n\tduk_push_number(thr, (duk_double_t) fun((double) arg1, (double) arg2));\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_max(duk_hthread *thr) {\n\treturn duk__math_minmax(thr, -DUK_DOUBLE_INFINITY, duk__fmax_fixed);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_min(duk_hthread *thr) {\n\treturn duk__math_minmax(thr, DUK_DOUBLE_INFINITY, duk__fmin_fixed);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_random(duk_hthread *thr) {\n\tduk_push_number(thr, (duk_double_t) DUK_UTIL_GET_RANDOM_DOUBLE(thr));\n\treturn 1;\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_hypot(duk_hthread *thr) {\n\t/*\n\t *  E6 Section 20.2.2.18: Math.hypot\n\t *\n\t *  - If no arguments are passed, the result is +0.\n\t *  - If any argument is +inf, the result is +inf.\n\t *  - If any argument is -inf, the result is +inf.\n\t *  - If no argument is +inf or -inf, and any argument is NaN, the result is\n\t *    NaN.\n\t *  - If all arguments are either +0 or -0, the result is +0.\n\t */\n\n\tduk_idx_t nargs;\n\tduk_idx_t i;\n\tduk_bool_t found_nan;\n\tduk_double_t max;\n\tduk_double_t sum, summand;\n\tduk_double_t comp, prelim;\n\tduk_double_t t;\n\n\tnargs = duk_get_top(thr);\n\n\t/* Find the highest value.  Also ToNumber() coerces. */\n\tmax = 0.0;\n\tfound_nan = 0;\n\tfor (i = 0; i < nargs; i++) {\n\t\tt = DUK_FABS(duk_to_number(thr, i));\n\t\tif (DUK_FPCLASSIFY(t) == DUK_FP_NAN) {\n\t\t\tfound_nan = 1;\n\t\t} else {\n\t\t\tmax = duk_double_fmax(max, t);\n\t\t}\n\t}\n\n\t/* Early return cases. */\n\tif (max == DUK_DOUBLE_INFINITY) {\n\t\tduk_push_number(thr, DUK_DOUBLE_INFINITY);\n\t\treturn 1;\n\t} else if (found_nan) {\n\t\tduk_push_number(thr, DUK_DOUBLE_NAN);\n\t\treturn 1;\n\t} else if (max == 0.0) {\n\t\tduk_push_number(thr, 0.0);\n\t\t/* Otherwise we'd divide by zero. */\n\t\treturn 1;\n\t}\n\n\t/* Use Kahan summation and normalize to the highest value to minimize\n\t * floating point rounding error and avoid overflow.\n\t *\n\t * https://en.wikipedia.org/wiki/Kahan_summation_algorithm\n\t */\n\tsum = 0.0;\n\tcomp = 0.0;\n\tfor (i = 0; i < nargs; i++) {\n\t\tt = DUK_FABS(duk_get_number(thr, i)) / max;\n\t\tsummand = (t * t) - comp;\n\t\tprelim = sum + summand;\n\t\tcomp = (prelim - sum) - summand;\n\t\tsum = prelim;\n\t}\n\n\tduk_push_number(thr, (duk_double_t) DUK_SQRT(sum) * max);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_sign(duk_hthread *thr) {\n\tduk_double_t d;\n\n\td = duk_to_number(thr, 0);\n\tif (duk_double_is_nan(d)) {\n\t\tDUK_ASSERT(duk_is_nan(thr, -1));\n\t\treturn 1;  /* NaN input -> return NaN */\n\t}\n\tif (d == 0.0) {\n\t\t/* Zero sign kept, i.e. -0 -> -0, +0 -> +0. */\n\t\treturn 1;\n\t}\n\tduk_push_int(thr, (d > 0.0 ? 1 : -1));\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_clz32(duk_hthread *thr) {\n\tduk_uint32_t x;\n\tduk_small_uint_t i;\n\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_uint32_t mask;\n\n\tx = duk_to_uint32(thr, 0);\n\tfor (i = 0, mask = 0x80000000UL; mask != 0; mask >>= 1) {\n\t\tif (x & mask) {\n\t\t\tbreak;\n\t\t}\n\t\ti++;\n\t}\n\tDUK_ASSERT(i <= 32);\n\tduk_push_uint(thr, i);\n\treturn 1;\n#else  /* DUK_USE_PREFER_SIZE */\n\ti = 0;\n\tx = duk_to_uint32(thr, 0);\n\tif (x & 0xffff0000UL) {\n\t\tx >>= 16;\n\t} else {\n\t\ti += 16;\n\t}\n\tif (x & 0x0000ff00UL) {\n\t\tx >>= 8;\n\t} else {\n\t\ti += 8;\n\t}\n\tif (x & 0x000000f0UL) {\n\t\tx >>= 4;\n\t} else {\n\t\ti += 4;\n\t}\n\tif (x & 0x0000000cUL) {\n\t\tx >>= 2;\n\t} else {\n\t\ti += 2;\n\t}\n\tif (x & 0x00000002UL) {\n\t\tx >>= 1;\n\t} else {\n\t\ti += 1;\n\t}\n\tif (x & 0x00000001UL) {\n\t\t;\n\t} else {\n\t\ti += 1;\n\t}\n\tDUK_ASSERT(i <= 32);\n\tduk_push_uint(thr, i);\n\treturn 1;\n#endif  /* DUK_USE_PREFER_SIZE */\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_imul(duk_hthread *thr) {\n\tduk_uint32_t x, y, z;\n\n\tx = duk_to_uint32(thr, 0);\n\ty = duk_to_uint32(thr, 1);\n\tz = x * y;\n\n\t/* While arguments are ToUint32() coerced and the multiplication\n\t * is unsigned as such, the final result is curiously interpreted\n\t * as a signed 32-bit value.\n\t */\n\tduk_push_i32(thr, (duk_int32_t) z);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#endif  /* DUK_USE_MATH_BUILTIN */\n#line 1 \"duk_bi_number.c\"\n/*\n *  Number built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_NUMBER_BUILTIN)\n\nDUK_LOCAL duk_double_t duk__push_this_number_plain(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\t/* Number built-in accepts a plain number or a Number object (whose\n\t * internal value is operated on).  Other types cause TypeError.\n\t */\n\n\tduk_push_this(thr);\n\tif (duk_is_number(thr, -1)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"plain number value: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\t\tgoto done;\n\t}\n\th = duk_get_hobject(thr, -1);\n\tif (!h ||\n\t    (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_NUMBER)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"unacceptable this value: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\t\tDUK_ERROR_TYPE(thr, \"number expected\");\n\t\tDUK_WO_NORETURN(return 0.0;);\n\t}\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\tDUK_DDD(DUK_DDDPRINT(\"number object: %!T, internal value: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_remove_m2(thr);\n\n done:\n\treturn duk_get_number(thr, -1);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_constructor(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_hobject *h_this;\n\n\t/*\n\t *  The Number constructor uses ToNumber(arg) for number coercion\n\t *  (coercing an undefined argument to NaN).  However, if the\n\t *  argument is not given at all, +0 must be used instead.  To do\n\t *  this, a vararg function is used.\n\t */\n\n\tnargs = duk_get_top(thr);\n\tif (nargs == 0) {\n\t\tduk_push_int(thr, 0);\n\t}\n\tduk_to_number(thr, 0);\n\tduk_set_top(thr, 1);\n\tDUK_ASSERT_TOP(thr, 1);\n\n\tif (!duk_is_constructor_call(thr)) {\n\t\treturn 1;\n\t}\n\n\t/*\n\t *  E5 Section 15.7.2.1 requires that the constructed object\n\t *  must have the original Number.prototype as its internal\n\t *  prototype.  However, since Number.prototype is non-writable\n\t *  and non-configurable, this doesn't have to be enforced here:\n\t *  The default object (bound to 'this') is OK, though we have\n\t *  to change its class.\n\t *\n\t *  Internal value set to ToNumber(arg) or +0; if no arg given,\n\t *  ToNumber(undefined) = NaN, so special treatment is needed\n\t *  (above).  String internal value is immutable.\n\t */\n\n\t/* XXX: helper */\n\tduk_push_this(thr);\n\th_this = duk_known_hobject(thr, -1);\n\tDUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_NUMBER);\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE]);\n\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_this) == DUK_HOBJECT_CLASS_NUMBER);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_this));\n\n\tduk_dup_0(thr);  /* -> [ val obj val ] */\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\treturn 0;  /* no return value -> don't replace created value */\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_value_of(duk_hthread *thr) {\n\t(void) duk__push_this_number_plain(thr);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_string(duk_hthread *thr) {\n\tduk_small_int_t radix;\n\tduk_small_uint_t n2s_flags;\n\n\t(void) duk__push_this_number_plain(thr);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tradix = 10;\n\t} else {\n\t\tradix = (duk_small_int_t) duk_to_int_check_range(thr, 0, 2, 36);\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"radix=%ld\", (long) radix));\n\n\tn2s_flags = 0;\n\n\tduk_numconv_stringify(thr,\n\t                      radix /*radix*/,\n\t                      0 /*digits*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_locale_string(duk_hthread *thr) {\n\t/* XXX: just use toString() for now; permitted although not recommended.\n\t * nargs==1, so radix is passed to toString().\n\t */\n\treturn duk_bi_number_prototype_to_string(thr);\n}\n\n/*\n *  toFixed(), toExponential(), toPrecision()\n */\n\n/* XXX: shared helper for toFixed(), toExponential(), toPrecision()? */\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_fixed(duk_hthread *thr) {\n\tduk_small_int_t frac_digits;\n\tduk_double_t d;\n\tduk_small_int_t c;\n\tduk_small_uint_t n2s_flags;\n\n\t/* In ES5.1 frac_digits is coerced first; in ES2015 the 'this number\n\t * value' check is done first.\n\t */\n\td = duk__push_this_number_plain(thr);\n\tfrac_digits = (duk_small_int_t) duk_to_int_check_range(thr, 0, 0, 20);\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\tgoto use_to_string;\n\t}\n\n\tif (d >= 1.0e21 || d <= -1.0e21) {\n\t\tgoto use_to_string;\n\t}\n\n\tn2s_flags = DUK_N2S_FLAG_FIXED_FORMAT |\n\t            DUK_N2S_FLAG_FRACTION_DIGITS;\n\n\tduk_numconv_stringify(thr,\n\t                      10 /*radix*/,\n\t                      frac_digits /*digits*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n\n use_to_string:\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, -1);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_exponential(duk_hthread *thr) {\n\tduk_bool_t frac_undefined;\n\tduk_small_int_t frac_digits;\n\tduk_double_t d;\n\tduk_small_int_t c;\n\tduk_small_uint_t n2s_flags;\n\n\td = duk__push_this_number_plain(thr);\n\n\tfrac_undefined = duk_is_undefined(thr, 0);\n\tduk_to_int(thr, 0);  /* for side effects */\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\tgoto use_to_string;\n\t}\n\n\tfrac_digits = (duk_small_int_t) duk_to_int_check_range(thr, 0, 0, 20);\n\n\tn2s_flags = DUK_N2S_FLAG_FORCE_EXP |\n\t           (frac_undefined ? 0 : DUK_N2S_FLAG_FIXED_FORMAT);\n\n\tduk_numconv_stringify(thr,\n\t                      10 /*radix*/,\n\t                      frac_digits + 1 /*leading digit + fractions*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n\n use_to_string:\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, -1);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_precision(duk_hthread *thr) {\n\t/* The specification has quite awkward order of coercion and\n\t * checks for toPrecision().  The operations below are a bit\n\t * reordered, within constraints of observable side effects.\n\t */\n\n\tduk_double_t d;\n\tduk_small_int_t prec;\n\tduk_small_int_t c;\n\tduk_small_uint_t n2s_flags;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\n\td = duk__push_this_number_plain(thr);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tgoto use_to_string;\n\t}\n\tDUK_ASSERT_TOP(thr, 2);\n\n\tduk_to_int(thr, 0);  /* for side effects */\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\tgoto use_to_string;\n\t}\n\n\tprec = (duk_small_int_t) duk_to_int_check_range(thr, 0, 1, 21);\n\n\tn2s_flags = DUK_N2S_FLAG_FIXED_FORMAT |\n\t            DUK_N2S_FLAG_NO_ZERO_PAD;\n\n\tduk_numconv_stringify(thr,\n\t                      10 /*radix*/,\n\t                      prec /*digits*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n\n use_to_string:\n\t/* Used when precision is undefined; also used for NaN (-> \"NaN\"),\n\t * and +/- infinity (-> \"Infinity\", \"-Infinity\").\n\t */\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, -1);\n\treturn 1;\n}\n\n/*\n *  ES2015 isFinite() etc\n */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_number_check_shared(duk_hthread *thr) {\n\tduk_int_t magic;\n\tduk_bool_t ret = 0;\n\n\tif (duk_is_number(thr, 0)) {\n\t\tduk_double_t d;\n\n\t\tmagic = duk_get_current_magic(thr);\n\t\td = duk_get_number(thr, 0);\n\n\t\tswitch (magic) {\n\t\tcase 0:  /* isFinite() */\n\t\t\tret = duk_double_is_finite(d);\n\t\t\tbreak;\n\t\tcase 1:  /* isInteger() */\n\t\t\tret = duk_double_is_integer(d);\n\t\t\tbreak;\n\t\tcase 2:  /* isNaN() */\n\t\t\tret = duk_double_is_nan(d);\n\t\t\tbreak;\n\t\tdefault:  /* isSafeInteger() */\n\t\t\tDUK_ASSERT(magic == 3);\n\t\t\tret = duk_double_is_safe_integer(d);\n\t\t}\n\t}\n\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#endif  /* DUK_USE_NUMBER_BUILTIN */\n#line 1 \"duk_bi_object.c\"\n/*\n *  Object built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Needed even when Object built-in disabled. */\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_string(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\ttv = DUK_HTHREAD_THIS_PTR(thr);\n\tduk_push_class_string_tval(thr, tv, 0 /*avoid_side_effects*/);\n\treturn 1;\n}\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor(duk_hthread *thr) {\n\tduk_uint_t arg_mask;\n\n\targ_mask = duk_get_type_mask(thr, 0);\n\n\tif (!duk_is_constructor_call(thr) &&  /* not a constructor call */\n\t    ((arg_mask & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED)) == 0)) {  /* and argument not null or undefined */\n\t\tduk_to_object(thr, 0);\n\t\treturn 1;\n\t}\n\n\t/* Pointer and buffer primitive values are treated like other\n\t * primitives values which have a fully fledged object counterpart:\n\t * promote to an object value.  Lightfuncs and plain buffers are\n\t * coerced with ToObject() even they could also be returned as is.\n\t */\n\tif (arg_mask & (DUK_TYPE_MASK_OBJECT |\n\t                DUK_TYPE_MASK_STRING |\n\t                DUK_TYPE_MASK_BOOLEAN |\n\t                DUK_TYPE_MASK_NUMBER |\n\t                DUK_TYPE_MASK_POINTER |\n\t                DUK_TYPE_MASK_BUFFER |\n\t                DUK_TYPE_MASK_LIGHTFUNC)) {\n\t\t/* For DUK_TYPE_OBJECT the coercion is a no-op and could\n\t\t * be checked for explicitly, but Object(obj) calls are\n\t\t * not very common so opt for minimal footprint.\n\t\t */\n\t\tduk_to_object(thr, 0);\n\t\treturn 1;\n\t}\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              DUK_BIDX_OBJECT_PROTOTYPE);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) && defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_assign(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_int_t idx;\n\n\tnargs = duk_get_top_require_min(thr, 1 /*min_top*/);\n\n\tduk_to_object(thr, 0);\n\tfor (idx = 1; idx < nargs; idx++) {\n\t\t/* E7 19.1.2.1 (step 4a) */\n\t\tif (duk_is_null_or_undefined(thr, idx)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* duk_enum() respects ES2015+ [[OwnPropertyKeys]] ordering, which is\n\t\t * convenient here.\n\t\t */\n\t\tduk_to_object(thr, idx);\n\t\tduk_enum(thr, idx, DUK_ENUM_OWN_PROPERTIES_ONLY);\n\t\twhile (duk_next(thr, -1, 1 /*get_value*/)) {\n\t\t\t/* [ target ... enum key value ] */\n\t\t\tduk_put_prop(thr, 0);\n\t\t\t/* [ target ... enum ] */\n\t\t}\n\t\t/* Could pop enumerator, but unnecessary because of duk_set_top()\n\t\t * below.\n\t\t */\n\t}\n\n\tduk_set_top(thr, 1);\n\treturn 1;\n}\n#endif\n\n#if defined(DUK_USE_OBJECT_BUILTIN) && defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_is(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_push_boolean(thr, duk_samevalue(thr, 0, 1));\n\treturn 1;\n}\n#endif\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_create(duk_hthread *thr) {\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tduk_hbufobj_promote_plain(thr, 0);\n#endif\n\tproto = duk_require_hobject_accept_mask(thr, 0, DUK_TYPE_MASK_NULL);\n\tDUK_ASSERT(proto != NULL || duk_is_null(thr, 0));\n\n\t(void) duk_push_object_helper_proto(thr,\n\t                                    DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                    DUK_HOBJECT_FLAG_FASTREFS |\n\t                                    DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                                    proto);\n\n\tif (!duk_is_undefined(thr, 1)) {\n\t\t/* [ O Properties obj ] */\n\n\t\tduk_replace(thr, 0);\n\n\t\t/* [ obj Properties ] */\n\n\t\t/* Just call the \"original\" Object.defineProperties() to\n\t\t * finish up.\n\t\t */\n\n\t\treturn duk_bi_object_constructor_define_properties(thr);\n\t}\n\n\t/* [ O Properties obj ] */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_hthread *thr) {\n\tduk_small_uint_t pass;\n\tduk_uint_t defprop_flags;\n\tduk_hobject *obj;\n\tduk_idx_t idx_value;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\n\t/* Lightfunc and plain buffer handling by ToObject() coercion. */\n\tobj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(obj != NULL);\n\n\tduk_to_object(thr, 1);        /* properties object */\n\n\tDUK_DDD(DUK_DDDPRINT(\"target=%!iT, properties=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\n\t/*\n\t *  Two pass approach to processing the property descriptors.\n\t *  On first pass validate and normalize all descriptors before\n\t *  any changes are made to the target object.  On second pass\n\t *  make the actual modifications to the target object.\n\t *\n\t *  Right now we'll just use the same normalize/validate helper\n\t *  on both passes, ignoring its outputs on the first pass.\n\t */\n\n\tfor (pass = 0; pass < 2; pass++) {\n\t\tduk_set_top(thr, 2);  /* -> [ hobject props ] */\n\t\tduk_enum(thr, 1, DUK_ENUM_OWN_PROPERTIES_ONLY | DUK_ENUM_INCLUDE_SYMBOLS /*enum_flags*/);\n\n\t\tfor (;;) {\n\t\t\tduk_hstring *key;\n\n\t\t\t/* [ hobject props enum(props) ] */\n\n\t\t\tduk_set_top(thr, 3);\n\n\t\t\tif (!duk_next(thr, 2, 1 /*get_value*/)) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> key=%!iT, desc=%!iT\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t/* [ hobject props enum(props) key desc ] */\n\n\t\t\tduk_hobject_prepare_property_descriptor(thr,\n\t\t\t                                        4 /*idx_desc*/,\n\t\t\t                                        &defprop_flags,\n\t\t\t                                        &idx_value,\n\t\t\t                                        &get,\n\t\t\t                                        &set);\n\n\t\t\t/* [ hobject props enum(props) key desc [multiple values] ] */\n\n\t\t\tif (pass == 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* This allows symbols on purpose. */\n\t\t\tkey = duk_known_hstring(thr, 3);\n\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\tduk_hobject_define_property_helper(thr,\n\t\t\t                                   defprop_flags,\n\t\t\t                                   obj,\n\t\t\t                                   key,\n\t\t\t                                   idx_value,\n\t\t\t                                   get,\n\t\t\t                                   set,\n\t\t\t                                   1 /*throw_flag*/);\n\t\t}\n\t}\n\n\t/*\n\t *  Return target object\n\t */\n\n\tduk_dup_0(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_seal_freeze_shared(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 1);\n\n\tduk_seal_freeze_raw(thr, 0, (duk_bool_t) duk_get_current_magic(thr) /*is_freeze*/);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_sealed_frozen_shared(duk_hthread *thr) {\n\tduk_hobject *h;\n\tduk_bool_t is_frozen;\n\tduk_uint_t mask;\n\n\tis_frozen = (duk_bool_t) duk_get_current_magic(thr);\n\tmask = duk_get_type_mask(thr, 0);\n\tif (mask & (DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER)) {\n\t\tDUK_ASSERT(is_frozen == 0 || is_frozen == 1);\n\t\tduk_push_boolean(thr, (mask & DUK_TYPE_MASK_LIGHTFUNC) ?\n\t\t                          1 :               /* lightfunc always frozen and sealed */\n\t\t                          (is_frozen ^ 1)); /* buffer sealed but not frozen (index props writable) */\n\t} else {\n\t\t/* ES2015 Sections 19.1.2.12, 19.1.2.13: anything other than an object\n\t\t * is considered to be already sealed and frozen.\n\t\t */\n\t\th = duk_get_hobject(thr, 0);\n\t\tduk_push_boolean(thr, (h == NULL) ||\n\t\t                      duk_hobject_object_is_sealed_frozen_helper(thr, h, is_frozen /*is_frozen*/));\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_locale_string(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 0);\n\t(void) duk_push_this_coercible_to_object(thr);\n\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_TO_STRING);\n#if 0  /* This is mentioned explicitly in the E5.1 spec, but duk_call_method() checks for it in practice. */\n\tduk_require_callable(thr, 1);\n#endif\n\tduk_dup_0(thr);  /* -> [ O toString O ] */\n\tduk_call_method(thr, 0);  /* XXX: call method tail call? */\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_value_of(duk_hthread *thr) {\n\t/* For lightfuncs and plain buffers, returns Object() coerced. */\n\t(void) duk_push_this_coercible_to_object(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_hthread *thr) {\n\tduk_hobject *h_v;\n\tduk_hobject *h_obj;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\n\th_v = duk_get_hobject(thr, 0);\n\tif (!h_v) {\n\t\tduk_push_false(thr);  /* XXX: tail call: return duk_push_false(thr) */\n\t\treturn 1;\n\t}\n\n\th_obj = duk_push_this_coercible_to_object(thr);\n\tDUK_ASSERT(h_obj != NULL);\n\n\t/* E5.1 Section 15.2.4.6, step 3.a, lookup proto once before compare.\n\t * Prototype loops should cause an error to be thrown.\n\t */\n\tduk_push_boolean(thr, duk_hobject_prototype_chain_contains(thr, DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_v), h_obj, 0 /*ignore_loop*/));\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_has_own_property(duk_hthread *thr) {\n\treturn (duk_ret_t) duk_hobject_object_ownprop_helper(thr, 0 /*required_desc_flags*/);\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_property_is_enumerable(duk_hthread *thr) {\n\treturn (duk_ret_t) duk_hobject_object_ownprop_helper(thr, DUK_PROPDESC_FLAG_ENUMERABLE /*required_desc_flags*/);\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\n/* Shared helper to implement Object.getPrototypeOf,\n * Object.prototype.__proto__ getter, and Reflect.getPrototypeOf.\n *\n * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-get-object.prototype.__proto__\n */\nDUK_INTERNAL duk_ret_t duk_bi_object_getprototype_shared(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: __proto__ getter\n\t *  magic = 1: Object.getPrototypeOf()\n\t *  magic = 2: Reflect.getPrototypeOf()\n\t */\n\n\tduk_hobject *h;\n\tduk_hobject *proto;\n\tduk_tval *tv;\n\tduk_int_t magic;\n\n\tmagic = duk_get_current_magic(thr);\n\n\tif (magic == 0) {\n\t\tDUK_ASSERT_TOP(thr, 0);\n\t\tduk_push_this_coercible_to_object(thr);\n\t}\n\tDUK_ASSERT(duk_get_top(thr) >= 1);\n\tif (magic < 2) {\n\t\t/* ES2015 Section 19.1.2.9, step 1 */\n\t\tduk_to_object(thr, 0);\n\t}\n\ttv = DUK_GET_TVAL_POSIDX(thr, 0);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_BUFFER:\n\t\tproto = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\tproto = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tproto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t\tbreak;\n\tdefault:\n\t\t/* This implicitly handles CheckObjectCoercible() caused\n\t\t * TypeError.\n\t\t */\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\tif (proto != NULL) {\n\t\tduk_push_hobject(thr, proto);\n\t} else {\n\t\tduk_push_null(thr);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\n/* Shared helper to implement ES2015 Object.setPrototypeOf,\n * Object.prototype.__proto__ setter, and Reflect.setPrototypeOf.\n *\n * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-get-object.prototype.__proto__\n * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.setprototypeof\n */\nDUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: __proto__ setter\n\t *  magic = 1: Object.setPrototypeOf()\n\t *  magic = 2: Reflect.setPrototypeOf()\n\t */\n\n\tduk_hobject *h_obj;\n\tduk_hobject *h_new_proto;\n\tduk_hobject *h_curr;\n\tduk_ret_t ret_success = 1;  /* retval for success path */\n\tduk_uint_t mask;\n\tduk_int_t magic;\n\n\t/* Preliminaries for __proto__ and setPrototypeOf (E6 19.1.2.18 steps 1-4). */\n\tmagic = duk_get_current_magic(thr);\n\tif (magic == 0) {\n\t\tduk_push_this_check_object_coercible(thr);\n\t\tduk_insert(thr, 0);\n\t\tif (!duk_check_type_mask(thr, 1, DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_OBJECT)) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* __proto__ setter returns 'undefined' on success unlike the\n\t\t * setPrototypeOf() call which returns the target object.\n\t\t */\n\t\tret_success = 0;\n\t} else {\n\t\tif (magic == 1) {\n\t\t\tduk_require_object_coercible(thr, 0);\n\t\t} else {\n\t\t\tduk_require_hobject_accept_mask(thr, 0,\n\t\t\t                                DUK_TYPE_MASK_LIGHTFUNC |\n\t\t\t                                DUK_TYPE_MASK_BUFFER);\n\t\t}\n\t\tduk_require_type_mask(thr, 1, DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_OBJECT);\n\t}\n\n\th_new_proto = duk_get_hobject(thr, 1);\n\t/* h_new_proto may be NULL */\n\n\tmask = duk_get_type_mask(thr, 0);\n\tif (mask & (DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER)) {\n\t\tduk_hobject *curr_proto;\n\t\tcurr_proto = thr->builtins[(mask & DUK_TYPE_MASK_LIGHTFUNC) ?\n\t\t                               DUK_BIDX_FUNCTION_PROTOTYPE :\n\t\t                               DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tif (h_new_proto == curr_proto) {\n\t\t\tgoto skip;\n\t\t}\n\t\tgoto fail_nonextensible;\n\t}\n\th_obj = duk_get_hobject(thr, 0);\n\tif (h_obj == NULL) {\n\t\tgoto skip;\n\t}\n\tDUK_ASSERT(h_obj != NULL);\n\n\t/* [[SetPrototypeOf]] standard behavior, E6 9.1.2. */\n\t/* TODO: implement Proxy object support here */\n\n\tif (h_new_proto == DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_obj)) {\n\t\tgoto skip;\n\t}\n\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(h_obj)) {\n\t\tgoto fail_nonextensible;\n\t}\n\tfor (h_curr = h_new_proto; h_curr != NULL; h_curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_curr)) {\n\t\t/* Loop prevention. */\n\t\tif (h_curr == h_obj) {\n\t\t\tgoto fail_loop;\n\t\t}\n\t}\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h_obj, h_new_proto);\n\t/* fall thru */\n\n skip:\n\tduk_set_top(thr, 1);\n\tif (magic == 2) {\n\t\tduk_push_true(thr);\n\t}\n\treturn ret_success;\n\n fail_nonextensible:\n fail_loop:\n\tif (magic != 2) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t} else {\n\t\tduk_push_false(thr);\n\t\treturn 1;\n\t}\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: Object.defineProperty()\n\t *  magic = 1: Reflect.defineProperty()\n\t */\n\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\tduk_idx_t idx_value;\n\tduk_uint_t defprop_flags;\n\tduk_small_uint_t magic;\n\tduk_bool_t throw_flag;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"Object.defineProperty(): ctx=%p obj=%!T key=%!T desc=%!T\",\n\t                     (void *) thr,\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1),\n\t                     (duk_tval *) duk_get_tval(thr, 2)));\n\n\t/* [ obj key desc ] */\n\n\tmagic = (duk_small_uint_t) duk_get_current_magic(thr);\n\n\t/* Lightfuncs are currently supported by coercing to a temporary\n\t * Function object; changes will be allowed (the coerced value is\n\t * extensible) but will be lost.  Same for plain buffers.\n\t */\n\tobj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(obj != NULL);\n\tkey = duk_to_property_key_hstring(thr, 1);\n\t(void) duk_require_hobject(thr, 2);\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(duk_get_hobject(thr, 2) != NULL);\n\n\t/*\n\t *  Validate and convert argument property descriptor (an ECMAScript\n\t *  object) into a set of defprop_flags and possibly property value,\n\t *  getter, and/or setter values on the value stack.\n\t *\n\t *  Lightfunc set/get values are coerced to full Functions.\n\t */\n\n\tduk_hobject_prepare_property_descriptor(thr,\n\t                                        2 /*idx_desc*/,\n\t                                        &defprop_flags,\n\t                                        &idx_value,\n\t                                        &get,\n\t                                        &set);\n\n\t/*\n\t *  Use Object.defineProperty() helper for the actual operation.\n\t */\n\n\tDUK_ASSERT(magic == 0U || magic == 1U);\n\tthrow_flag = magic ^ 1U;\n\tret = duk_hobject_define_property_helper(thr,\n\t                                         defprop_flags,\n\t                                         obj,\n\t                                         key,\n\t                                         idx_value,\n\t                                         get,\n\t                                         set,\n\t                                         throw_flag);\n\n\t/* Ignore the normalize/validate helper outputs on the value stack,\n\t * they're popped automatically.\n\t */\n\n\tif (magic == 0U) {\n\t\t/* Object.defineProperty(): return target object. */\n\t\tduk_push_hobject(thr, obj);\n\t} else {\n\t\t/* Reflect.defineProperty(): return success/fail. */\n\t\tduk_push_boolean(thr, ret);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_get_own_property_descriptor(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 2);\n\n\t/* ES2015 Section 19.1.2.6, step 1 */\n\tif (duk_get_current_magic(thr) == 0) {\n\t\tduk_to_object(thr, 0);\n\t}\n\n\t/* [ obj key ] */\n\n\tduk_hobject_object_get_own_property_descriptor(thr, -2);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_extensible(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: Object.isExtensible()\n\t *  magic = 1: Reflect.isExtensible()\n\t */\n\n\tduk_hobject *h;\n\n\tif (duk_get_current_magic(thr) == 0) {\n\t\th = duk_get_hobject(thr, 0);\n\t} else {\n\t\t/* Reflect.isExtensible(): throw if non-object, but we accept lightfuncs\n\t\t * and plain buffers here because they pretend to be objects.\n\t\t */\n\t\th = duk_require_hobject_accept_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\t}\n\n\tduk_push_boolean(thr, (h != NULL) && DUK_HOBJECT_HAS_EXTENSIBLE(h));\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\n/* Shared helper for various key/symbol listings, magic:\n * 0=Object.keys()\n * 1=Object.getOwnPropertyNames(),\n * 2=Object.getOwnPropertySymbols(),\n * 3=Reflect.ownKeys()\n */\nDUK_LOCAL const duk_small_uint_t duk__object_keys_enum_flags[4] = {\n\t/* Object.keys() */\n\tDUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR,\n\n\t/* Object.getOwnPropertyNames() */\n\tDUK_ENUM_INCLUDE_NONENUMERABLE |\n\t    DUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR,\n\n\t/* Object.getOwnPropertySymbols() */\n\tDUK_ENUM_INCLUDE_SYMBOLS |\n\t    DUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_EXCLUDE_STRINGS |\n\t    DUK_ENUM_INCLUDE_NONENUMERABLE |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR,\n\n\t/* Reflect.ownKeys() */\n\tDUK_ENUM_INCLUDE_SYMBOLS |\n\t    DUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_INCLUDE_NONENUMERABLE |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR\n};\n\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_keys_shared(duk_hthread *thr) {\n\tduk_hobject *obj;\n#if defined(DUK_USE_ES6_PROXY)\n\tduk_hobject *h_proxy_target;\n\tduk_hobject *h_proxy_handler;\n\tduk_hobject *h_trap_result;\n#endif\n\tduk_small_uint_t enum_flags;\n\tduk_int_t magic;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\n\tmagic = duk_get_current_magic(thr);\n\tif (magic == 3) {\n\t\t/* ES2015 Section 26.1.11 requires a TypeError for non-objects.  Lightfuncs\n\t\t * and plain buffers pretend to be objects, so accept those too.\n\t\t */\n\t\tobj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\t} else {\n\t\t/* ES2015: ToObject coerce. */\n\t\tobj = duk_to_hobject(thr, 0);\n\t}\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(obj);\n\n\t/* XXX: proxy chains */\n\n#if defined(DUK_USE_ES6_PROXY)\n\t/* XXX: better sharing of code between proxy target call sites */\n\tif (DUK_LIKELY(!duk_hobject_proxy_check(obj,\n\t                                        &h_proxy_target,\n\t                                        &h_proxy_handler))) {\n\t\tgoto skip_proxy;\n\t}\n\n\tduk_push_hobject(thr, h_proxy_handler);\n\tif (!duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_OWN_KEYS)) {\n\t\t/* Careful with reachability here: don't pop 'obj' before pushing\n\t\t * proxy target.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"no ownKeys trap, get keys of target instead\"));\n\t\tduk_pop_2(thr);\n\t\tduk_push_hobject(thr, h_proxy_target);\n\t\tduk_replace(thr, 0);\n\t\tDUK_ASSERT_TOP(thr, 1);\n\t\tgoto skip_proxy;\n\t}\n\n\t/* [ obj handler trap ] */\n\tduk_insert(thr, -2);\n\tduk_push_hobject(thr, h_proxy_target);  /* -> [ obj trap handler target ] */\n\tduk_call_method(thr, 1 /*nargs*/);      /* -> [ obj trap_result ] */\n\th_trap_result = duk_require_hobject(thr, -1);\n\tDUK_UNREF(h_trap_result);\n\n\tmagic = duk_get_current_magic(thr);\n\tDUK_ASSERT(magic >= 0 && magic < (duk_int_t) (sizeof(duk__object_keys_enum_flags) / sizeof(duk_small_uint_t)));\n\tenum_flags = duk__object_keys_enum_flags[magic];\n\n\tduk_proxy_ownkeys_postprocess(thr, h_proxy_target, enum_flags);\n\treturn 1;\n\n skip_proxy:\n#endif  /* DUK_USE_ES6_PROXY */\n\n\tDUK_ASSERT_TOP(thr, 1);\n\tmagic = duk_get_current_magic(thr);\n\tDUK_ASSERT(magic >= 0 && magic < (duk_int_t) (sizeof(duk__object_keys_enum_flags) / sizeof(duk_small_uint_t)));\n\tenum_flags = duk__object_keys_enum_flags[magic];\n\treturn duk_hobject_get_enumerated_keys(thr, enum_flags);\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: Object.preventExtensions()\n\t *  magic = 1: Reflect.preventExtensions()\n\t */\n\n\tduk_hobject *h;\n\tduk_uint_t mask;\n\tduk_int_t magic;\n\n\tmagic = duk_get_current_magic(thr);\n\n\t/* Silent success for lightfuncs and plain buffers always. */\n\tmask = DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER;\n\n\t/* Object.preventExtensions() silent success for non-object. */\n\tif (magic == 0) {\n\t\tmask |= DUK_TYPE_MASK_UNDEFINED |\n\t\t        DUK_TYPE_MASK_NULL |\n\t\t        DUK_TYPE_MASK_BOOLEAN |\n\t\t        DUK_TYPE_MASK_NUMBER |\n\t\t        DUK_TYPE_MASK_STRING |\n\t\t        DUK_TYPE_MASK_POINTER;\n\t}\n\n\tif (duk_check_type_mask(thr, 0, mask)) {\n\t\t/* Not an object, already non-extensible so always success. */\n\t\tgoto done;\n\t}\n\th = duk_require_hobject(thr, 0);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_HOBJECT_CLEAR_EXTENSIBLE(h);\n\n\t/* A non-extensible object cannot gain any more properties,\n\t * so this is a good time to compact.\n\t */\n\tduk_hobject_compact_props(thr, h);\n\n done:\n\tif (magic == 1) {\n\t\tduk_push_true(thr);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n/*\n *  __defineGetter__, __defineSetter__, __lookupGetter__, __lookupSetter__\n */\n\n#if defined(DUK_USE_ES8)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_defineaccessor(duk_hthread *thr) {\n\tduk_push_this(thr);\n\tduk_insert(thr, 0);\n\tduk_to_object(thr, 0);\n\tduk_require_callable(thr, 2);\n\n\t/* [ ToObject(this) key getter/setter ] */\n\n\t/* ToPropertyKey() coercion is not needed, duk_def_prop() does it. */\n\tduk_def_prop(thr, 0, DUK_DEFPROP_SET_ENUMERABLE |\n\t                     DUK_DEFPROP_SET_CONFIGURABLE |\n\t                     (duk_get_current_magic(thr) ? DUK_DEFPROP_HAVE_SETTER : DUK_DEFPROP_HAVE_GETTER));\n\treturn 0;\n}\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_lookupaccessor(duk_hthread *thr) {\n\tduk_uint_t sanity;\n\n\tduk_push_this(thr);\n\tduk_to_object(thr, -1);\n\n\t/* XXX: Prototype walk (with sanity) should be a core property\n\t * operation, could add a flag to e.g. duk_get_prop_desc().\n\t */\n\n\t/* ToPropertyKey() coercion is not needed, duk_get_prop_desc() does it. */\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\twhile (!duk_is_undefined(thr, -1)) {\n\t\t/* [ key obj ] */\n\t\tduk_dup(thr, 0);\n\t\tduk_get_prop_desc(thr, 1, 0 /*flags*/);\n\t\tif (!duk_is_undefined(thr, -1)) {\n\t\t\tduk_get_prop_stridx(thr, -1, (duk_get_current_magic(thr) != 0 ? DUK_STRIDX_SET : DUK_STRIDX_GET));\n\t\t\treturn 1;\n\t\t}\n\t\tduk_pop(thr);\n\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\n\t\tduk_get_prototype(thr, -1);\n\t\tduk_remove(thr, -2);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_ES8 */\n#line 1 \"duk_bi_performance.c\"\n/*\n *  High resolution time API (performance.now() et al)\n *\n *  API specification: https://encoding.spec.whatwg.org/#ap://www.w3.org/TR/hr-time/\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_PERFORMANCE_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_performance_now(duk_hthread *thr) {\n\t/* From API spec:\n\t * The DOMHighResTimeStamp type is used to store a time value in\n\t * milliseconds, measured relative from the time origin, global\n\t * monotonic clock, or a time value that represents a duration\n\t * between two DOMHighResTimeStamp's.\n\t */\n\tduk_push_number(thr, duk_time_get_monotonic_time(thr));\n\treturn 1;\n}\n\n#if 0  /* Missing until semantics decided. */\nDUK_INTERNAL duk_ret_t duk_bi_performance_timeorigin_getter(duk_hthread *thr) {\n\t/* No decision yet how to handle timeOrigins, e.g. should one be\n\t * initialized per heap, or per global object set.  See\n\t * https://www.w3.org/TR/hr-time/#time-origin.\n\t */\n\tduk_push_uint(thr, 0);\n\treturn 1;\n}\n#endif  /* 0 */\n#endif  /* DUK_USE_PERFORMANCE_BUILTIN */\n#line 1 \"duk_bi_pointer.c\"\n/*\n *  Pointer built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_pointer_constructor(duk_hthread *thr) {\n\t/* XXX: this behavior is quite useless now; it would be nice to be able\n\t * to create pointer values from e.g. numbers or strings.  Numbers are\n\t * problematic on 64-bit platforms though.  Hex encoded strings?\n\t */\n\tif (duk_get_top(thr) == 0) {\n\t\tduk_push_pointer(thr, NULL);\n\t} else {\n\t\tduk_to_pointer(thr, 0);\n\t}\n\tDUK_ASSERT(duk_is_pointer(thr, 0));\n\tduk_set_top(thr, 1);\n\n\tif (duk_is_constructor_call(thr)) {\n\t\t(void) duk_push_object_helper(thr,\n\t\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER),\n\t\t                              DUK_BIDX_POINTER_PROTOTYPE);\n\n\t\t/* Pointer object internal value is immutable. */\n\t\tduk_dup_0(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\t/* Note: unbalanced stack on purpose */\n\n\treturn 1;\n}\n\n/*\n *  toString(), valueOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_small_int_t to_string = duk_get_current_magic(thr);\n\n\tduk_push_this(thr);\n\ttv = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_POINTER(tv)) {\n\t\t/* nop */\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* Must be a \"pointer object\", i.e. class \"Pointer\" */\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_POINTER) {\n\t\t\tgoto type_error;\n\t\t}\n\n\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t} else {\n\t\tgoto type_error;\n\t}\n\n\tif (to_string) {\n\t\tduk_to_string(thr, -1);\n\t}\n\treturn 1;\n\n type_error:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n#line 1 \"duk_bi_promise.c\"\n/*\n *  Promise built-in\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_PROMISE_BUILTIN)\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_constructor(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_all(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_race(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_reject(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_resolve(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_catch(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_then(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\n#endif  /* DUK_USE_PROMISE_BUILTIN */\n#line 1 \"duk_bi_proxy.c\"\n/*\n *  Proxy built-in (ES2015)\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ES6_PROXY)\n/* Post-process a Proxy ownKeys() result at stack top.  Push a cleaned up\n * array of valid result keys (strings or symbols).  TypeError for invalid\n * values.  Flags are shared with duk_enum().\n */\nDUK_INTERNAL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h_proxy_target, duk_uint_t flags) {\n\tduk_uarridx_t i, len, idx;\n\tduk_propdesc desc;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(h_proxy_target != NULL);\n\n\tlen = (duk_uarridx_t) duk_get_length(thr, -1);\n\tidx = 0;\n\tduk_push_array(thr);\n\t/* XXX: preallocated dense array, fill in directly */\n\tfor (i = 0; i < len; i++) {\n\t\tduk_hstring *h;\n\n\t\t/* [ obj trap_result res_arr ] */\n\t\t(void) duk_get_prop_index(thr, -2, i);\n\t\th = duk_get_hstring(thr, -1);\n\t\tif (h == NULL) {\n\t\t\tDUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\n\t\tif (!(flags & DUK_ENUM_INCLUDE_NONENUMERABLE)) {\n\t\t\t/* No support for 'getOwnPropertyDescriptor' trap yet,\n\t\t\t * so check enumerability always from target object\n\t\t\t * descriptor.\n\t\t\t */\n\t\t\tif (duk_hobject_get_own_propdesc(thr, h_proxy_target, duk_known_hstring(thr, -1), &desc, 0 /*flags*/)) {\n\t\t\t\tif ((desc.flags & DUK_PROPDESC_FLAG_ENUMERABLE) == 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore non-enumerable property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\t\tgoto skip_key;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore non-existent property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t}\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tif (!(flags & DUK_ENUM_INCLUDE_SYMBOLS)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore symbol property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t\tif (DUK_HSTRING_HAS_HIDDEN(h) && !(flags & DUK_ENUM_INCLUDE_HIDDEN)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore hidden symbol property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t} else {\n\t\t\tif (flags & DUK_ENUM_EXCLUDE_STRINGS) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore string property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t}\n\n\t\t/* [ obj trap_result res_arr propname ] */\n\t\tduk_put_prop_index(thr, -2, idx++);\n\t\tcontinue;\n\n\t skip_key:\n\t\tduk_pop(thr);\n\t\tcontinue;\n\t}\n\n\t/* XXX: Missing trap result validation for non-configurable target keys\n\t * (must be present), for non-extensible target all target keys must be\n\t * present and no extra keys can be present.\n\t * http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys\n\t */\n\n\t/* XXX: The key enumerability check should trigger the \"getOwnPropertyDescriptor\"\n\t * trap which has not yet been implemented.  In the absence of such a trap,\n\t * the enumerability should be checked from the target object; this is\n\t * handled above.\n\t */\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL duk_ret_t duk_bi_proxy_constructor(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 2);  /* [ target handler ] */\n\n\tduk_require_constructor_call(thr);\n\tduk_push_proxy(thr, 0 /*flags*/);  /* [ target handler ] -> [ proxy ] */\n\treturn 1;  /* replacement */\n}\n#endif  /* DUK_USE_ES6_PROXY */\n#line 1 \"duk_bi_reflect.c\"\n/*\n *  'Reflect' built-in (ES2016 Section 26.1)\n *  http://www.ecma-international.org/ecma-262/7.0/#sec-reflect-object\n *\n *  Many Reflect built-in functions are provided by shared helpers in\n *  duk_bi_object.c or duk_bi_function.c.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_delete_property(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\n\t/* [ target key ] */\n\n\tDUK_ASSERT(thr != NULL);\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\tret = duk_hobject_delprop(thr, tv_obj, tv_key, 0 /*throw_flag*/);\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_get(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_idx_t nargs;\n\n\tDUK_ASSERT(thr != NULL);\n\tnargs = duk_get_top_require_min(thr, 2 /*min_top*/);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\tif (nargs >= 3 && !duk_strict_equals(thr, 0, 2)) {\n\t\t/* XXX: [[Get]] receiver currently unsupported */\n\t\tDUK_ERROR_UNSUPPORTED(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* [ target key receiver? ...? ] */\n\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\t(void) duk_hobject_getprop(thr, tv_obj, tv_key);  /* This could also be a duk_get_prop(). */\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_has(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT_TOP(thr, 2);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\n\t/* [ target key ] */\n\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\tret = duk_hobject_hasprop(thr, tv_obj, tv_key);\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_set(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_tval *tv_val;\n\tduk_idx_t nargs;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\tnargs = duk_get_top_require_min(thr, 3 /*min_top*/);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\tif (nargs >= 4 && !duk_strict_equals(thr, 0, 3)) {\n\t\t/* XXX: [[Set]] receiver currently unsupported */\n\t\tDUK_ERROR_UNSUPPORTED(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* [ target key value receiver? ...? ] */\n\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\ttv_val = DUK_GET_TVAL_POSIDX(thr, 2);\n\tret = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, 0 /*throw_flag*/);\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_REFLECT_BUILTIN */\n#line 1 \"duk_bi_regexp.c\"\n/*\n *  RegExp built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\nDUK_LOCAL void duk__get_this_regexp(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\tduk_push_this(thr);\n\th = duk_require_hobject_with_class(thr, -1, DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_ASSERT(h != NULL);\n\tDUK_UNREF(h);\n\tduk_insert(thr, 0);  /* prepend regexp to valstack 0 index */\n}\n\n/* XXX: much to improve (code size) */\nDUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_hthread *thr) {\n\tduk_hobject *h_pattern;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\th_pattern = duk_get_hobject(thr, 0);\n\n\tif (!duk_is_constructor_call(thr) &&\n\t    h_pattern != NULL &&\n\t    DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP &&\n\t    duk_is_undefined(thr, 1)) {\n\t\t/* Called as a function, pattern has [[Class]] \"RegExp\" and\n\t\t * flags is undefined -> return object as is.\n\t\t */\n\t\t/* XXX: ES2015 has a NewTarget SameValue() check which is not\n\t\t * yet implemented.\n\t\t */\n\t\tduk_dup_0(thr);\n\t\treturn 1;\n\t}\n\n\t/* Else functionality is identical for function call and constructor\n\t * call.\n\t */\n\n\tif (h_pattern != NULL &&\n\t    DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP) {\n\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_SOURCE);\n\t\tif (duk_is_undefined(thr, 1)) {\n\t\t\t/* In ES5 one would need to read the flags individually;\n\t\t\t * in ES2015 just read .flags.\n\t\t\t */\n\t\t\tduk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS);\n\t\t} else {\n\t\t\t/* In ES2015 allowed; overrides argument RegExp flags. */\n\t\t\tduk_dup_1(thr);\n\t\t}\n\t} else {\n\t\tif (duk_is_undefined(thr, 0)) {\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_to_string(thr, -1);  /* Rejects Symbols. */\n\t\t}\n\t\tif (duk_is_undefined(thr, 1)) {\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tduk_dup_1(thr);\n\t\t\tduk_to_string(thr, -1);  /* Rejects Symbols. */\n\t\t}\n\n\t\t/* [ ... pattern flags ] */\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"RegExp constructor/function call, pattern=%!T, flags=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* [ ... pattern flags ] (both uncoerced) */\n\n\tduk_to_string(thr, -2);\n\tduk_to_string(thr, -1);\n\tduk_regexp_compile(thr);\n\n\t/* [ ... bytecode escaped_source ] */\n\n\tduk_regexp_create_instance(thr);\n\n\t/* [ ... RegExp ] */\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_exec(duk_hthread *thr) {\n\tduk__get_this_regexp(thr);\n\n\t/* [ regexp input ] */\n\n\tduk_regexp_match(thr);\n\n\t/* [ result ] */\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_test(duk_hthread *thr) {\n\tduk__get_this_regexp(thr);\n\n\t/* [ regexp input ] */\n\n\t/* result object is created and discarded; wasteful but saves code space */\n\tduk_regexp_match(thr);\n\n\t/* [ result ] */\n\n\tduk_push_boolean(thr, (duk_is_null(thr, -1) ? 0 : 1));\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_tostring(duk_hthread *thr) {\n\t/* This must be generic in ES2015 and later. */\n\tDUK_ASSERT_TOP(thr, 0);\n\tduk_push_this(thr);\n\tduk_push_literal(thr, \"/\");\n\tduk_get_prop_stridx(thr, 0, DUK_STRIDX_SOURCE);\n\tduk_dup_m2(thr);  /* another \"/\" */\n\tduk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS);\n\tduk_concat(thr, 4);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_flags(duk_hthread *thr) {\n\t/* .flags is ES2015 but present even when ES2015 bindings are\n\t * disabled because the constructor relies on it.\n\t */\n\tduk_uint8_t buf[8];  /* enough for all flags + NUL */\n\tduk_uint8_t *p = buf;\n\n\t/* .flags is generic and works on any object. */\n\tduk_push_this(thr);\n\t(void) duk_require_hobject(thr, -1);\n\tif (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL)) {\n\t\t*p++ = DUK_ASC_LC_G;\n\t}\n\tif (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_IGNORE_CASE, NULL)) {\n\t\t*p++ = DUK_ASC_LC_I;\n\t}\n\tif (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_MULTILINE, NULL)) {\n\t\t*p++ = DUK_ASC_LC_M;\n\t}\n\t/* .unicode: to be added */\n\t/* .sticky: to be added */\n\t*p++ = DUK_ASC_NUL;\n\tDUK_ASSERT((duk_size_t) (p - buf) <= sizeof(buf));\n\n\tduk_push_string(thr, (const char *) buf);\n\treturn 1;\n}\n\n/* Shared helper for providing .source, .global, .multiline, etc getters. */\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_hthread *thr) {\n\tduk_hstring *h_bc;\n\tduk_small_uint_t re_flags;\n\tduk_hobject *h;\n\tduk_int_t magic;\n\n\tDUK_ASSERT_TOP(thr, 0);\n\n\tduk_push_this(thr);\n\th = duk_require_hobject(thr, -1);\n\tmagic = duk_get_current_magic(thr);\n\n\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_REGEXP) {\n\t\tduk_xget_owndataprop_stridx_short(thr, 0, DUK_STRIDX_INT_SOURCE);\n\t\tduk_xget_owndataprop_stridx_short(thr, 0, DUK_STRIDX_INT_BYTECODE);\n\t\th_bc = duk_require_hstring(thr, -1);\n\t\tre_flags = (duk_small_uint_t) DUK_HSTRING_GET_DATA(h_bc)[0];  /* Safe even if h_bc length is 0 (= NUL) */\n\t\tduk_pop(thr);\n\t} else if (h == thr->builtins[DUK_BIDX_REGEXP_PROTOTYPE]) {\n\t\t/* In ES2015 and ES2016 a TypeError would be thrown here.\n\t\t * However, this had real world issues so ES2017 draft\n\t\t * allows RegExp.prototype specifically, returning '(?:)'\n\t\t * for .source and undefined for all flags.\n\t\t */\n\t\tif (magic != 16 /* .source */) {\n\t\t\treturn 0;\n\t\t}\n\t\tduk_push_literal(thr, \"(?:)\");  /* .source handled by switch-case */\n\t\tre_flags = 0;\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* [ regexp source ] */\n\n\tswitch (magic) {\n\tcase 0: {  /* global */\n\t\tduk_push_boolean(thr, (re_flags & DUK_RE_FLAG_GLOBAL));\n\t\tbreak;\n\t}\n\tcase 1: {  /* ignoreCase */\n\t\tduk_push_boolean(thr, (re_flags & DUK_RE_FLAG_IGNORE_CASE));\n\t\tbreak;\n\t}\n\tcase 2: {  /* multiline */\n\t\tduk_push_boolean(thr, (re_flags & DUK_RE_FLAG_MULTILINE));\n\t\tbreak;\n\t}\n#if 0\n\t/* Don't provide until implemented to avoid interfering with feature\n\t * detection in user code.\n\t */\n\tcase 3:    /* sticky */\n\tcase 4: {  /* unicode */\n\t\tduk_push_false(thr);\n\t\tbreak;\n\t}\n#endif\n\tdefault: {  /* source */\n\t\t/* leave 'source' on top */\n\t\tbreak;\n\t}\n\t}\n\n\treturn 1;\n}\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n#line 1 \"duk_bi_string.c\"\n/*\n *  String built-ins\n *\n *  Most String built-ins must only accept strings (or String objects).\n *  Symbols, represented internally as strings, must be generally rejected.\n *  The duk_push_this_coercible_to_string() helper does this automatically.\n */\n\n/* XXX: There are several limitations in the current implementation for\n * strings with >= 0x80000000UL characters.  In some cases one would need\n * to be able to represent the range [-0xffffffff,0xffffffff] and so on.\n * Generally character and byte length are assumed to fit into signed 32\n * bits (< 0x80000000UL).  Places with issues are not marked explicitly\n * below in all cases, look for signed type usage (duk_int_t etc) for\n * offsets/lengths.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_STRING_BUILTIN)\n\n/*\n *  Helpers\n */\n\nDUK_LOCAL duk_hstring *duk__str_tostring_notregexp(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tif (duk_get_class_number(thr, idx) == DUK_HOBJECT_CLASS_REGEXP) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\th = duk_to_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\treturn h;\n}\n\nDUK_LOCAL duk_int_t duk__str_search_shared(duk_hthread *thr, duk_hstring *h_this, duk_hstring *h_search, duk_int_t start_cpos, duk_bool_t backwards) {\n\tduk_int_t cpos;\n\tduk_int_t bpos;\n\tconst duk_uint8_t *p_start, *p_end, *p;\n\tconst duk_uint8_t *q_start;\n\tduk_int_t q_blen;\n\tduk_uint8_t firstbyte;\n\tduk_uint8_t t;\n\n\tcpos = start_cpos;\n\n\t/* Empty searchstring always matches; cpos must be clamped here.\n\t * (If q_blen were < 0 due to clamped coercion, it would also be\n\t * caught here.)\n\t */\n\tq_start = DUK_HSTRING_GET_DATA(h_search);\n\tq_blen = (duk_int_t) DUK_HSTRING_GET_BYTELEN(h_search);\n\tif (q_blen <= 0) {\n\t\treturn cpos;\n\t}\n\tDUK_ASSERT(q_blen > 0);\n\n\tbpos = (duk_int_t) duk_heap_strcache_offset_char2byte(thr, h_this, (duk_uint32_t) cpos);\n\n\tp_start = DUK_HSTRING_GET_DATA(h_this);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_this);\n\tp = p_start + bpos;\n\n\t/* This loop is optimized for size.  For speed, there should be\n\t * two separate loops, and we should ensure that memcmp() can be\n\t * used without an extra \"will searchstring fit\" check.  Doing\n\t * the preconditioning for 'p' and 'p_end' is easy but cpos\n\t * must be updated if 'p' is wound back (backward scanning).\n\t */\n\n\tfirstbyte = q_start[0];  /* leading byte of match string */\n\twhile (p <= p_end && p >= p_start) {\n\t\tt = *p;\n\n\t\t/* For ECMAScript strings, this check can only match for\n\t\t * initial UTF-8 bytes (not continuation bytes).  For other\n\t\t * strings all bets are off.\n\t\t */\n\n\t\tif ((t == firstbyte) && ((duk_size_t) (p_end - p) >= (duk_size_t) q_blen)) {\n\t\t\tDUK_ASSERT(q_blen > 0);\n\t\t\tif (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {\n\t\t\t\treturn cpos;\n\t\t\t}\n\t\t}\n\n\t\t/* track cpos while scanning */\n\t\tif (backwards) {\n\t\t\t/* when going backwards, we decrement cpos 'early';\n\t\t\t * 'p' may point to a continuation byte of the char\n\t\t\t * at offset 'cpos', but that's OK because we'll\n\t\t\t * backtrack all the way to the initial byte.\n\t\t\t */\n\t\t\tif ((t & 0xc0) != 0x80) {\n\t\t\t\tcpos--;\n\t\t\t}\n\t\t\tp--;\n\t\t} else {\n\t\t\tif ((t & 0xc0) != 0x80) {\n\t\t\t\tcpos++;\n\t\t\t}\n\t\t\tp++;\n\t\t}\n\t}\n\n\t/* Not found.  Empty string case is handled specially above. */\n\treturn -1;\n}\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_constructor(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_uint_t flags;\n\n\t/* String constructor needs to distinguish between an argument not given at all\n\t * vs. given as 'undefined'.  We're a vararg function to handle this properly.\n\t */\n\n\t/* XXX: copy current activation flags to thr, including current magic,\n\t * is_constructor_call etc.  This takes a few bytes in duk_hthread but\n\t * makes call sites smaller (there are >30 is_constructor_call and get\n\t * current magic call sites.\n\t */\n\n\tif (duk_get_top(thr) == 0) {\n\t\tduk_push_hstring_empty(thr);\n\t} else {\n\t\th = duk_to_hstring_acceptsymbol(thr, 0);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h) && !duk_is_constructor_call(thr))) {\n\t\t\tduk_push_symbol_descriptive_string(thr, h);\n\t\t\tduk_replace(thr, 0);\n\t\t}\n\t}\n\tduk_to_string(thr, 0);  /* catches symbol argument for constructor call */\n\tDUK_ASSERT(duk_is_string(thr, 0));\n\tduk_set_top(thr, 1);  /* Top may be 1 or larger. */\n\n\tif (duk_is_constructor_call(thr)) {\n\t\t/* String object internal value is immutable */\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_STRING);\n\t\tduk_push_object_helper(thr, flags, DUK_BIDX_STRING_PROTOTYPE);\n\t\tduk_dup_0(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\t/* Note: unbalanced stack on purpose */\n\n\treturn 1;\n}\n\nDUK_LOCAL duk_ret_t duk__construct_from_codepoints(duk_hthread *thr, duk_bool_t nonbmp) {\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tduk_idx_t i, n;\n\tduk_ucodepoint_t cp;\n\n\t/* XXX: It would be nice to build the string directly but ToUint16()\n\t * coercion is needed so a generic helper would not be very\n\t * helpful (perhaps coerce the value stack first here and then\n\t * build a string from a duk_tval number sequence in one go?).\n\t */\n\n\tn = duk_get_top(thr);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, (duk_size_t) n);  /* initial estimate for ASCII only codepoints */\n\n\tfor (i = 0; i < n; i++) {\n\t\t/* XXX: could improve bufwriter handling to write multiple codepoints\n\t\t * with one ensure call but the relative benefit would be quite small.\n\t\t */\n\n\t\tif (nonbmp) {\n\t\t\t/* ES2015 requires that (1) SameValue(cp, ToInteger(cp)) and\n\t\t\t * (2) cp >= 0 and cp <= 0x10ffff.  This check does not\n\t\t\t * implement the steps exactly but the outcome should be\n\t\t\t * the same.\n\t\t\t */\n\t\t\tduk_int32_t i32 = 0;\n\t\t\tif (!duk_is_whole_get_int32(duk_to_number(thr, i), &i32) ||\n\t\t\t    i32 < 0 || i32 > 0x10ffffL) {\n\t\t\t\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n\t\t\t}\n\t\t\tDUK_ASSERT(i32 >= 0 && i32 <= 0x10ffffL);\n\t\t\tcp = (duk_ucodepoint_t) i32;\n\t\t\tDUK_BW_WRITE_ENSURE_CESU8(thr, bw, cp);\n\t\t} else {\n#if defined(DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT)\n\t\t\t/* ToUint16() coercion is mandatory in the E5.1 specification, but\n\t\t\t * this non-compliant behavior makes more sense because we support\n\t\t\t * non-BMP codepoints.  Don't use CESU-8 because that'd create\n\t\t\t * surrogate pairs.\n\t\t\t */\n\t\t\tcp = (duk_ucodepoint_t) duk_to_uint32(thr, i);\n\t\t\tDUK_BW_WRITE_ENSURE_XUTF8(thr, bw, cp);\n#else\n\t\t\tcp = (duk_ucodepoint_t) duk_to_uint16(thr, i);\n\t\t\tDUK_ASSERT(cp >= 0 && cp <= 0x10ffffL);\n\t\t\tDUK_BW_WRITE_ENSURE_CESU8(thr, bw, cp);\n#endif\n\t\t}\n\t}\n\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe, extended UTF-8 or CESU-8 encoded. */\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_string_constructor_from_char_code(duk_hthread *thr) {\n\treturn duk__construct_from_codepoints(thr, 0 /*nonbmp*/);\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_constructor_from_code_point(duk_hthread *thr) {\n\treturn duk__construct_from_codepoints(thr, 1 /*nonbmp*/);\n}\n#endif\n\n/*\n *  toString(), valueOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_to_string(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tduk_push_this(thr);\n\ttv = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_STRING(tv)) {\n\t\t/* return as is */\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* Must be a \"string object\", i.e. class \"String\" */\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_STRING) {\n\t\t\tgoto type_error;\n\t\t}\n\n\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\t} else {\n\t\tgoto type_error;\n\t}\n\n\t(void) duk_require_hstring_notsymbol(thr, -1);  /* Reject symbols (and wrapped symbols). */\n\treturn 1;\n\n type_error:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n\n/*\n *  Character and charcode access\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_at(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t pos;\n\n\t/* XXX: faster implementation */\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tpos = duk_to_int(thr, 0);\n\n\tif (sizeof(duk_size_t) >= sizeof(duk_uint_t)) {\n\t\t/* Cast to duk_size_t works in this case:\n\t\t * - If pos < 0, (duk_size_t) pos will always be\n\t\t *   >= max_charlen, and result will be the empty string\n\t\t *   (see duk_substring()).\n\t\t * - If pos >= 0, pos + 1 cannot wrap.\n\t\t */\n\t\tDUK_ASSERT((duk_size_t) DUK_INT_MIN >= DUK_HSTRING_MAX_BYTELEN);\n\t\tDUK_ASSERT((duk_size_t) DUK_INT_MAX + 1U > (duk_size_t) DUK_INT_MAX);\n\t\tduk_substring(thr, -1, (duk_size_t) pos, (duk_size_t) pos + 1U);\n\t} else {\n\t\t/* If size_t is smaller than int, explicit bounds checks\n\t\t * are needed because an int may wrap multiple times.\n\t\t */\n\t\tif (DUK_UNLIKELY(pos < 0 || (duk_uint_t) pos >= (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h))) {\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tduk_substring(thr, -1, (duk_size_t) pos, (duk_size_t) pos + 1U);\n\t\t}\n\t}\n\n\treturn 1;\n}\n\n/* Magic: 0=charCodeAt, 1=codePointAt */\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_code_at(duk_hthread *thr) {\n\tduk_int_t pos;\n\tduk_hstring *h;\n\tduk_bool_t clamped;\n\tduk_uint32_t cp;\n\tduk_int_t magic;\n\n\t/* XXX: faster implementation */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arg=%!T\", (duk_tval *) duk_get_tval(thr, 0)));\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tpos = duk_to_int_clamped_raw(thr,\n\t                             0 /*index*/,\n\t                             0 /*min(incl)*/,\n\t                             (duk_int_t) DUK_HSTRING_GET_CHARLEN(h) - 1 /*max(incl)*/,\n\t                             &clamped /*out_clamped*/);\n#if defined(DUK_USE_ES6)\n\tmagic = duk_get_current_magic(thr);\n#else\n\tDUK_ASSERT(duk_get_current_magic(thr) == 0);\n\tmagic = 0;\n#endif\n\tif (clamped) {\n\t\t/* For out-of-bounds indices .charCodeAt() returns NaN and\n\t\t * .codePointAt() returns undefined.\n\t\t */\n\t\tif (magic != 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tduk_push_nan(thr);\n\t} else {\n\t\tDUK_ASSERT(pos >= 0);\n\t\tcp = (duk_uint32_t) duk_hstring_char_code_at_raw(thr, h, (duk_uint_t) pos, (duk_bool_t) magic /*surrogate_aware*/);\n\t\tduk_push_u32(thr, cp);\n\t}\n\treturn 1;\n}\n\n/*\n *  substring(), substr(), slice()\n */\n\n/* XXX: any chance of merging these three similar but still slightly\n * different algorithms so that footprint would be reduced?\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_substring(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t start_pos, end_pos;\n\tduk_int_t len;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\n\t/* [ start end str ] */\n\n\tstart_pos = duk_to_int_clamped(thr, 0, 0, len);\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend_pos = len;\n\t} else {\n\t\tend_pos = duk_to_int_clamped(thr, 1, 0, len);\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\tDUK_ASSERT(end_pos >= 0 && end_pos <= len);\n\n\tif (start_pos > end_pos) {\n\t\tduk_int_t tmp = start_pos;\n\t\tstart_pos = end_pos;\n\t\tend_pos = tmp;\n\t}\n\n\tDUK_ASSERT(end_pos >= start_pos);\n\n\tduk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);\n\treturn 1;\n}\n\n#if defined(DUK_USE_SECTION_B)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_substr(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t start_pos, end_pos;\n\tduk_int_t len;\n\n\t/* Unlike non-obsolete String calls, substr() algorithm in E5.1\n\t * specification will happily coerce undefined and null to strings\n\t * (\"undefined\" and \"null\").\n\t */\n\tduk_push_this(thr);\n\th = duk_to_hstring_m1(thr);  /* Reject Symbols. */\n\tDUK_ASSERT(h != NULL);\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\n\t/* [ start length str ] */\n\n\t/* The implementation for computing of start_pos and end_pos differs\n\t * from the standard algorithm, but is intended to result in the exactly\n\t * same behavior.  This is not always obvious.\n\t */\n\n\t/* combines steps 2 and 5; -len ensures max() not needed for step 5 */\n\tstart_pos = duk_to_int_clamped(thr, 0, -len, len);\n\tif (start_pos < 0) {\n\t\tstart_pos = len + start_pos;\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\n\t/* combines steps 3, 6; step 7 is not needed */\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend_pos = len;\n\t} else {\n\t\tDUK_ASSERT(start_pos <= len);\n\t\tend_pos = start_pos + duk_to_int_clamped(thr, 1, 0, len - start_pos);\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\tDUK_ASSERT(end_pos >= 0 && end_pos <= len);\n\tDUK_ASSERT(end_pos >= start_pos);\n\n\tduk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);\n\treturn 1;\n}\n#endif  /* DUK_USE_SECTION_B */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_slice(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t start_pos, end_pos;\n\tduk_int_t len;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\n\t/* [ start end str ] */\n\n\tstart_pos = duk_to_int_clamped(thr, 0, -len, len);\n\tif (start_pos < 0) {\n\t\tstart_pos = len + start_pos;\n\t}\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend_pos = len;\n\t} else {\n\t\tend_pos = duk_to_int_clamped(thr, 1, -len, len);\n\t\tif (end_pos < 0) {\n\t\t\tend_pos = len + end_pos;\n\t\t}\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\tDUK_ASSERT(end_pos >= 0 && end_pos <= len);\n\n\tif (end_pos < start_pos) {\n\t\tend_pos = start_pos;\n\t}\n\n\tDUK_ASSERT(end_pos >= start_pos);\n\n\tduk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);\n\treturn 1;\n}\n\n/*\n *  Case conversion\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_caseconv_shared(duk_hthread *thr) {\n\tduk_small_int_t uppercase = duk_get_current_magic(thr);\n\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk_unicode_case_convert_string(thr, (duk_bool_t) uppercase);\n\treturn 1;\n}\n\n/*\n *  indexOf() and lastIndexOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_indexof_shared(duk_hthread *thr) {\n\tduk_hstring *h_this;\n\tduk_hstring *h_search;\n\tduk_int_t clen_this;\n\tduk_int_t cpos;\n\tduk_small_uint_t is_lastindexof = (duk_small_uint_t) duk_get_current_magic(thr);  /* 0=indexOf, 1=lastIndexOf */\n\n\th_this = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_this != NULL);\n\tclen_this = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h_this);\n\n\th_search = duk_to_hstring(thr, 0);\n\tDUK_ASSERT(h_search != NULL);\n\n\tduk_to_number(thr, 1);\n\tif (duk_is_nan(thr, 1) && is_lastindexof) {\n\t\t/* indexOf: NaN should cause pos to be zero.\n\t\t * lastIndexOf: NaN should cause pos to be +Infinity\n\t\t * (and later be clamped to len).\n\t\t */\n\t\tcpos = clen_this;\n\t} else {\n\t\tcpos = duk_to_int_clamped(thr, 1, 0, clen_this);\n\t}\n\n\tcpos = duk__str_search_shared(thr, h_this, h_search, cpos, is_lastindexof /*backwards*/);\n\tduk_push_int(thr, cpos);\n\treturn 1;\n}\n\n/*\n *  replace()\n */\n\n/* XXX: the current implementation works but is quite clunky; it compiles\n * to almost 1,4kB of x86 code so it needs to be simplified (better approach,\n * shared helpers, etc).  Some ideas for refactoring:\n *\n * - a primitive to convert a string into a regexp matcher (reduces matching\n *   code at the cost of making matching much slower)\n * - use replace() as a basic helper for match() and split(), which are both\n *   much simpler\n * - API call to get_prop and to_boolean\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {\n\tduk_hstring *h_input;\n\tduk_hstring *h_match;\n\tduk_hstring *h_search;\n\tduk_hobject *h_re;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tduk_bool_t is_regexp;\n\tduk_bool_t is_global;\n#endif\n\tduk_bool_t is_repl_func;\n\tduk_uint32_t match_start_coff, match_start_boff;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tduk_int_t match_caps;\n#endif\n\tduk_uint32_t prev_match_end_boff;\n\tconst duk_uint8_t *r_start, *r_end, *r;   /* repl string scan */\n\tduk_size_t tmp_sz;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\th_input = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_input != NULL);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input));  /* input size is good output starting point */\n\n\tDUK_ASSERT_TOP(thr, 4);\n\n\t/* stack[0] = search value\n\t * stack[1] = replace value\n\t * stack[2] = input string\n\t * stack[3] = result buffer\n\t */\n\n\th_re = duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_REGEXP);\n\tif (h_re) {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tis_regexp = 1;\n\t\tis_global = duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL);\n\n\t\tif (is_global) {\n\t\t\t/* start match from beginning */\n\t\t\tduk_push_int(thr, 0);\n\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t}\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\tDUK_DCERROR_UNSUPPORTED(thr);\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t} else {\n\t\tduk_to_string(thr, 0);  /* rejects symbols */\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tis_regexp = 0;\n\t\tis_global = 0;\n#endif\n\t}\n\n\tif (duk_is_function(thr, 1)) {\n\t\tis_repl_func = 1;\n\t\tr_start = NULL;\n\t\tr_end = NULL;\n\t} else {\n\t\tduk_hstring *h_repl;\n\n\t\tis_repl_func = 0;\n\t\th_repl = duk_to_hstring(thr, 1);  /* reject symbols */\n\t\tDUK_ASSERT(h_repl != NULL);\n\t\tr_start = DUK_HSTRING_GET_DATA(h_repl);\n\t\tr_end = r_start + DUK_HSTRING_GET_BYTELEN(h_repl);\n\t}\n\n\tprev_match_end_boff = 0;\n\n\tfor (;;) {\n\t\t/*\n\t\t *  If matching with a regexp:\n\t\t *    - non-global RegExp: lastIndex not touched on a match, zeroed\n\t\t *      on a non-match\n\t\t *    - global RegExp: on match, lastIndex will be updated by regexp\n\t\t *      executor to point to next char after the matching part (so that\n\t\t *      characters in the matching part are not matched again)\n\t\t *\n\t\t *  If matching with a string:\n\t\t *    - always non-global match, find first occurrence\n\t\t *\n\t\t *  We need:\n\t\t *    - The character offset of start-of-match for the replacer function\n\t\t *    - The byte offsets for start-of-match and end-of-match to implement\n\t\t *      the replacement values $&, $`, and $', and to copy non-matching\n\t\t *      input string portions (including header and trailer) verbatim.\n\t\t *\n\t\t *  NOTE: the E5.1 specification is a bit vague how the RegExp should\n\t\t *  behave in the replacement process; e.g. is matching done first for\n\t\t *  all matches (in the global RegExp case) before any replacer calls\n\t\t *  are made?  See: test-bi-string-proto-replace.js for discussion.\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, 4);\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (is_regexp) {\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_dup_2(thr);\n\t\t\tduk_regexp_match(thr);  /* [ ... regexp input ] -> [ res_obj ] */\n\t\t\tif (!duk_is_object(thr, -1)) {\n\t\t\t\tduk_pop(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX);\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tmatch_start_coff = duk_get_uint(thr, -1);\n\t\t\tduk_pop(thr);\n\n\t\t\tduk_get_prop_index(thr, -1, 0);\n\t\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\t\t\th_match = duk_known_hstring(thr, -1);\n\t\t\tduk_pop(thr);  /* h_match is borrowed, remains reachable through match_obj */\n\n\t\t\tif (DUK_HSTRING_GET_BYTELEN(h_match) == 0) {\n\t\t\t\t/* This should be equivalent to match() algorithm step 8.f.iii.2:\n\t\t\t\t * detect an empty match and allow it, but don't allow it twice.\n\t\t\t\t */\n\t\t\t\tduk_uint32_t last_index;\n\n\t\t\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\t\tlast_index = (duk_uint32_t) duk_get_uint(thr, -1);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"empty match, bump lastIndex: %ld -> %ld\",\n\t\t\t\t                     (long) last_index, (long) (last_index + 1)));\n\t\t\t\tduk_pop(thr);\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) (last_index + 1));\n\t\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\t}\n\n\t\t\tDUK_ASSERT(duk_get_length(thr, -1) <= DUK_INT_MAX);  /* string limits */\n\t\t\tmatch_caps = (duk_int_t) duk_get_length(thr, -1);\n\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\tconst duk_uint8_t *p_start, *p_end, *p;   /* input string scan */\n\t\t\tconst duk_uint8_t *q_start;               /* match string */\n\t\t\tduk_size_t q_blen;\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\tDUK_ASSERT(!is_global);  /* single match always */\n#endif\n\n\t\t\tp_start = DUK_HSTRING_GET_DATA(h_input);\n\t\t\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\t\t\tp = p_start;\n\n\t\t\th_search = duk_known_hstring(thr, 0);\n\t\t\tq_start = DUK_HSTRING_GET_DATA(h_search);\n\t\t\tq_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_search);\n\n\t\t\tp_end -= q_blen;  /* ensure full memcmp() fits in while */\n\n\t\t\tmatch_start_coff = 0;\n\n\t\t\twhile (p <= p_end) {\n\t\t\t\tDUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + DUK_HSTRING_GET_BYTELEN(h_input));\n\t\t\t\tif (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {\n\t\t\t\t\tduk_dup_0(thr);\n\t\t\t\t\th_match = duk_known_hstring(thr, -1);\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t\t\tmatch_caps = 0;\n#endif\n\t\t\t\t\tgoto found;\n\t\t\t\t}\n\n\t\t\t\t/* track utf-8 non-continuation bytes */\n\t\t\t\tif ((p[0] & 0xc0) != 0x80) {\n\t\t\t\t\tmatch_start_coff++;\n\t\t\t\t}\n\t\t\t\tp++;\n\t\t\t}\n\n\t\t\t/* not found */\n\t\t\tbreak;\n\t\t}\n\t found:\n\n\t\t/* stack[0] = search value\n\t\t * stack[1] = replace value\n\t\t * stack[2] = input string\n\t\t * stack[3] = result buffer\n\t\t * stack[4] = regexp match OR match string\n\t\t */\n\n\t\tmatch_start_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h_input, match_start_coff);\n\n\t\ttmp_sz = (duk_size_t) (match_start_boff - prev_match_end_boff);\n\t\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff, tmp_sz);\n\n\t\tprev_match_end_boff = match_start_boff + DUK_HSTRING_GET_BYTELEN(h_match);\n\n\t\tif (is_repl_func) {\n\t\t\tduk_idx_t idx_args;\n\t\t\tduk_hstring *h_repl;\n\n\t\t\t/* regexp res_obj is at index 4 */\n\n\t\t\tduk_dup_1(thr);\n\t\t\tidx_args = duk_get_top(thr);\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\tif (is_regexp) {\n\t\t\t\tduk_int_t idx;\n\t\t\t\tduk_require_stack(thr, match_caps + 2);\n\t\t\t\tfor (idx = 0; idx < match_caps; idx++) {\n\t\t\t\t\t/* match followed by capture(s) */\n\t\t\t\t\tduk_get_prop_index(thr, 4, (duk_uarridx_t) idx);\n\t\t\t\t}\n\t\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t\t/* match == search string, by definition */\n\t\t\t\tduk_dup_0(thr);\n\t\t\t}\n\t\t\tduk_push_uint(thr, (duk_uint_t) match_start_coff);\n\t\t\tduk_dup_2(thr);\n\n\t\t\t/* [ ... replacer match [captures] match_char_offset input ] */\n\n\t\t\tduk_call(thr, duk_get_top(thr) - idx_args);\n\t\t\th_repl = duk_to_hstring_m1(thr);  /* -> [ ... repl_value ] */\n\t\t\tDUK_ASSERT(h_repl != NULL);\n\n\t\t\tDUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_repl);\n\n\t\t\tduk_pop(thr);  /* repl_value */\n\t\t} else {\n\t\t\tr = r_start;\n\n\t\t\twhile (r < r_end) {\n\t\t\t\tduk_int_t ch1;\n\t\t\t\tduk_int_t ch2;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t\tduk_int_t ch3;\n#endif\n\t\t\t\tduk_size_t left;\n\n\t\t\t\tch1 = *r++;\n\t\t\t\tif (ch1 != DUK_ASC_DOLLAR) {\n\t\t\t\t\tgoto repl_write;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(r <= r_end);\n\t\t\t\tleft = (duk_size_t) (r_end - r);\n\n\t\t\t\tif (left <= 0) {\n\t\t\t\t\tgoto repl_write;\n\t\t\t\t}\n\n\t\t\t\tch2 = r[0];\n\t\t\t\tswitch (ch2) {\n\t\t\t\tcase DUK_ASC_DOLLAR: {\n\t\t\t\t\tch1 = (1 << 8) + DUK_ASC_DOLLAR;\n\t\t\t\t\tgoto repl_write;\n\t\t\t\t}\n\t\t\t\tcase DUK_ASC_AMP: {\n\t\t\t\t\tDUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_match);\n\t\t\t\t\tr++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcase DUK_ASC_GRAVE: {\n\t\t\t\t\ttmp_sz = (duk_size_t) match_start_boff;\n\t\t\t\t\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input), tmp_sz);\n\t\t\t\t\tr++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcase DUK_ASC_SINGLEQUOTE: {\n\t\t\t\t\tduk_uint32_t match_end_boff;\n\n\t\t\t\t\t/* Use match charlen instead of bytelen, just in case the input and\n\t\t\t\t\t * match codepoint encodings would have different lengths.\n\t\t\t\t\t */\n\t\t\t\t\t/* XXX: charlen computed here, and also in char2byte helper. */\n\t\t\t\t\tmatch_end_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr,\n\t\t\t\t\t                                                                   h_input,\n\t\t\t\t\t                                                                   match_start_coff + (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h_match));\n\n\t\t\t\t\ttmp_sz = (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - match_end_boff);\n\t\t\t\t\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + match_end_boff, tmp_sz);\n\t\t\t\t\tr++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tdefault: {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t\t\tduk_int_t capnum, captmp, capadv;\n\t\t\t\t\t/* XXX: optional check, match_caps is zero if no regexp,\n\t\t\t\t\t * so dollar will be interpreted literally anyway.\n\t\t\t\t\t */\n\n\t\t\t\t\tif (!is_regexp) {\n\t\t\t\t\t\tgoto repl_write;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!(ch2 >= DUK_ASC_0 && ch2 <= DUK_ASC_9)) {\n\t\t\t\t\t\tgoto repl_write;\n\t\t\t\t\t}\n\t\t\t\t\tcapnum = ch2 - DUK_ASC_0;\n\t\t\t\t\tcapadv = 1;\n\n\t\t\t\t\tif (left >= 2) {\n\t\t\t\t\t\tch3 = r[1];\n\t\t\t\t\t\tif (ch3 >= DUK_ASC_0 && ch3 <= DUK_ASC_9) {\n\t\t\t\t\t\t\tcaptmp = capnum * 10 + (ch3 - DUK_ASC_0);\n\t\t\t\t\t\t\tif (captmp < match_caps) {\n\t\t\t\t\t\t\t\tcapnum = captmp;\n\t\t\t\t\t\t\t\tcapadv = 2;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (capnum > 0 && capnum < match_caps) {\n\t\t\t\t\t\tDUK_ASSERT(is_regexp != 0);  /* match_caps == 0 without regexps */\n\n\t\t\t\t\t\t/* regexp res_obj is at offset 4 */\n\t\t\t\t\t\tduk_get_prop_index(thr, 4, (duk_uarridx_t) capnum);\n\t\t\t\t\t\tif (duk_is_string(thr, -1)) {\n\t\t\t\t\t\t\tduk_hstring *h_tmp_str;\n\n\t\t\t\t\t\t\th_tmp_str = duk_known_hstring(thr, -1);\n\n\t\t\t\t\t\t\tDUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_tmp_str);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t/* undefined -> skip (replaced with empty) */\n\t\t\t\t\t\t}\n\t\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\t\tr += capadv;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgoto repl_write;\n\t\t\t\t\t}\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t\t\tgoto repl_write;  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t\t}  /* default case */\n\t\t\t\t}  /* switch (ch2) */\n\n\t\t\t repl_write:\n\t\t\t\t/* ch1 = (r_increment << 8) + byte */\n\n\t\t\t\tDUK_BW_WRITE_ENSURE_U8(thr, bw, (duk_uint8_t) (ch1 & 0xff));\n\t\t\t\tr += ch1 >> 8;\n\t\t\t}  /* while repl */\n\t\t}  /* if (is_repl_func) */\n\n\t\tduk_pop(thr);  /* pop regexp res_obj or match string */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (!is_global) {\n#else\n\t\t{  /* unconditionally; is_global==0 */\n#endif\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* trailer */\n\ttmp_sz = (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - prev_match_end_boff);\n\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff, tmp_sz);\n\n\tDUK_ASSERT_TOP(thr, 4);\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if inputs are safe. */\n\treturn 1;\n}\n\n/*\n *  split()\n */\n\n/* XXX: very messy now, but works; clean up, remove unused variables (nomimally\n * used so compiler doesn't complain).\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {\n\tduk_hstring *h_input;\n\tduk_hstring *h_sep;\n\tduk_uint32_t limit;\n\tduk_uint32_t arr_idx;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tduk_bool_t is_regexp;\n#endif\n\tduk_bool_t matched;  /* set to 1 if any match exists (needed for empty input special case) */\n\tduk_uint32_t prev_match_end_coff, prev_match_end_boff;\n\tduk_uint32_t match_start_boff, match_start_coff;\n\tduk_uint32_t match_end_boff, match_end_coff;\n\n\th_input = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_input != NULL);\n\n\tduk_push_array(thr);\n\n\tif (duk_is_undefined(thr, 1)) {\n\t\tlimit = 0xffffffffUL;\n\t} else {\n\t\tlimit = duk_to_uint32(thr, 1);\n\t}\n\n\tif (limit == 0) {\n\t\treturn 1;\n\t}\n\n\t/* If the separator is a RegExp, make a \"clone\" of it.  The specification\n\t * algorithm calls [[Match]] directly for specific indices; we emulate this\n\t * by tweaking lastIndex and using a \"force global\" variant of duk_regexp_match()\n\t * which will use global-style matching even when the RegExp itself is non-global.\n\t */\n\n\tif (duk_is_undefined(thr, 0)) {\n\t\t/* The spec algorithm first does \"R = ToString(separator)\" before checking\n\t\t * whether separator is undefined.  Since this is side effect free, we can\n\t\t * skip the ToString() here.\n\t\t */\n\t\tduk_dup_2(thr);\n\t\tduk_put_prop_index(thr, 3, 0);\n\t\treturn 1;\n\t} else if (duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_REGEXP) != NULL) {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tduk_push_hobject_bidx(thr, DUK_BIDX_REGEXP_CONSTRUCTOR);\n\t\tduk_dup_0(thr);\n\t\tduk_new(thr, 1);  /* [ ... RegExp val ] -> [ ... res ] */\n\t\tduk_replace(thr, 0);\n\t\t/* lastIndex is initialized to zero by new RegExp() */\n\t\tis_regexp = 1;\n#else\n\t\tDUK_DCERROR_UNSUPPORTED(thr);\n#endif\n\t} else {\n\t\tduk_to_string(thr, 0);\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tis_regexp = 0;\n#endif\n\t}\n\n\t/* stack[0] = separator (string or regexp)\n\t * stack[1] = limit\n\t * stack[2] = input string\n\t * stack[3] = result array\n\t */\n\n\tprev_match_end_boff = 0;\n\tprev_match_end_coff = 0;\n\tarr_idx = 0;\n\tmatched = 0;\n\n\tfor (;;) {\n\t\t/*\n\t\t *  The specification uses RegExp [[Match]] to attempt match at specific\n\t\t *  offsets.  We don't have such a primitive, so we use an actual RegExp\n\t\t *  and tweak lastIndex.  Since the RegExp may be non-global, we use a\n\t\t *  special variant which forces global-like behavior for matching.\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, 4);\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (is_regexp) {\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_dup_2(thr);\n\t\t\tduk_regexp_match_force_global(thr);  /* [ ... regexp input ] -> [ res_obj ] */\n\t\t\tif (!duk_is_object(thr, -1)) {\n\t\t\t\tduk_pop(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched = 1;\n\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX);\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tmatch_start_coff = duk_get_uint(thr, -1);\n\t\t\tmatch_start_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h_input, match_start_coff);\n\t\t\tduk_pop(thr);\n\n\t\t\tif (match_start_coff == DUK_HSTRING_GET_CHARLEN(h_input)) {\n\t\t\t\t/* don't allow an empty match at the end of the string */\n\t\t\t\tduk_pop(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tmatch_end_coff = duk_get_uint(thr, -1);\n\t\t\tmatch_end_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h_input, match_end_coff);\n\t\t\tduk_pop(thr);\n\n\t\t\t/* empty match -> bump and continue */\n\t\t\tif (prev_match_end_boff == match_end_boff) {\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) (match_end_coff + 1));\n\t\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\t\tduk_pop(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\tconst duk_uint8_t *p_start, *p_end, *p;   /* input string scan */\n\t\t\tconst duk_uint8_t *q_start;               /* match string */\n\t\t\tduk_size_t q_blen, q_clen;\n\n\t\t\tp_start = DUK_HSTRING_GET_DATA(h_input);\n\t\t\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\t\t\tp = p_start + prev_match_end_boff;\n\n\t\t\th_sep = duk_known_hstring(thr, 0);  /* symbol already rejected above */\n\t\t\tq_start = DUK_HSTRING_GET_DATA(h_sep);\n\t\t\tq_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sep);\n\t\t\tq_clen = (duk_size_t) DUK_HSTRING_GET_CHARLEN(h_sep);\n\n\t\t\tp_end -= q_blen;  /* ensure full memcmp() fits in while */\n\n\t\t\tmatch_start_coff = prev_match_end_coff;\n\n\t\t\tif (q_blen == 0) {\n\t\t\t\t/* Handle empty separator case: it will always match, and always\n\t\t\t\t * triggers the check in step 13.c.iii initially.  Note that we\n\t\t\t\t * must skip to either end of string or start of first codepoint,\n\t\t\t\t * skipping over any continuation bytes!\n\t\t\t\t *\n\t\t\t\t * Don't allow an empty string to match at the end of the input.\n\t\t\t\t */\n\n\t\t\t\tmatched = 1;  /* empty separator can always match */\n\n\t\t\t\tmatch_start_coff++;\n\t\t\t\tp++;\n\t\t\t\twhile (p < p_end) {\n\t\t\t\t\tif ((p[0] & 0xc0) != 0x80) {\n\t\t\t\t\t\tgoto found;\n\t\t\t\t\t}\n\t\t\t\t\tp++;\n\t\t\t\t}\n\t\t\t\tgoto not_found;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(q_blen > 0 && q_clen > 0);\n\t\t\twhile (p <= p_end) {\n\t\t\t\tDUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + DUK_HSTRING_GET_BYTELEN(h_input));\n\t\t\t\tDUK_ASSERT(q_blen > 0);  /* no issues with empty memcmp() */\n\t\t\t\tif (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {\n\t\t\t\t\t/* never an empty match, so step 13.c.iii can't be triggered */\n\t\t\t\t\tgoto found;\n\t\t\t\t}\n\n\t\t\t\t/* track utf-8 non-continuation bytes */\n\t\t\t\tif ((p[0] & 0xc0) != 0x80) {\n\t\t\t\t\tmatch_start_coff++;\n\t\t\t\t}\n\t\t\t\tp++;\n\t\t\t}\n\n\t\t not_found:\n\t\t\t/* not found */\n\t\t\tbreak;\n\n\t\t found:\n\t\t\tmatched = 1;\n\t\t\tmatch_start_boff = (duk_uint32_t) (p - p_start);\n\t\t\tmatch_end_coff = (duk_uint32_t) (match_start_coff + q_clen);  /* constrained by string length */\n\t\t\tmatch_end_boff = (duk_uint32_t) (match_start_boff + q_blen);  /* ditto */\n\n\t\t\t/* empty match (may happen with empty separator) -> bump and continue */\n\t\t\tif (prev_match_end_boff == match_end_boff) {\n\t\t\t\tprev_match_end_boff++;\n\t\t\t\tprev_match_end_coff++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}  /* if (is_regexp) */\n\n\t\t/* stack[0] = separator (string or regexp)\n\t\t * stack[1] = limit\n\t\t * stack[2] = input string\n\t\t * stack[3] = result array\n\t\t * stack[4] = regexp res_obj (if is_regexp)\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"split; match_start b=%ld,c=%ld, match_end b=%ld,c=%ld, prev_end b=%ld,c=%ld\",\n\t\t                     (long) match_start_boff, (long) match_start_coff,\n\t\t                     (long) match_end_boff, (long) match_end_coff,\n\t\t                     (long) prev_match_end_boff, (long) prev_match_end_coff));\n\n\t\tduk_push_lstring(thr,\n\t\t                 (const char *) (DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff),\n\t\t                 (duk_size_t) (match_start_boff - prev_match_end_boff));\n\t\tduk_put_prop_index(thr, 3, arr_idx);\n\t\tarr_idx++;\n\t\tif (arr_idx >= limit) {\n\t\t\tgoto hit_limit;\n\t\t}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (is_regexp) {\n\t\t\tduk_size_t i, len;\n\n\t\t\tlen = duk_get_length(thr, 4);\n\t\t\tfor (i = 1; i < len; i++) {\n\t\t\t\tDUK_ASSERT(i <= DUK_UARRIDX_MAX);  /* cannot have >4G captures */\n\t\t\t\tduk_get_prop_index(thr, 4, (duk_uarridx_t) i);\n\t\t\t\tduk_put_prop_index(thr, 3, arr_idx);\n\t\t\t\tarr_idx++;\n\t\t\t\tif (arr_idx >= limit) {\n\t\t\t\t\tgoto hit_limit;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_pop(thr);\n\t\t\t/* lastIndex already set up for next match */\n\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t/* no action */\n\t\t}\n\n\t\tprev_match_end_boff = match_end_boff;\n\t\tprev_match_end_coff = match_end_coff;\n\t\tcontinue;\n\t}  /* for */\n\n\t/* Combined step 11 (empty string special case) and 14-15. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"split trailer; prev_end b=%ld,c=%ld\",\n\t                     (long) prev_match_end_boff, (long) prev_match_end_coff));\n\n\tif (DUK_HSTRING_GET_BYTELEN(h_input) > 0 || !matched) {\n\t\t/* Add trailer if:\n\t\t *   a) non-empty input\n\t\t *   b) empty input and no (zero size) match found (step 11)\n\t\t */\n\n\t\tduk_push_lstring(thr,\n\t\t                 (const char *) DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff,\n\t\t                 (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - prev_match_end_boff));\n\t\tduk_put_prop_index(thr, 3, arr_idx);\n\t\t/* No arr_idx update or limit check */\n\t}\n\n\treturn 1;\n\n hit_limit:\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tif (is_regexp) {\n\t\tduk_pop(thr);\n\t}\n#endif\n\n\treturn 1;\n}\n\n/*\n *  Various\n */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_LOCAL void duk__to_regexp_helper(duk_hthread *thr, duk_idx_t idx, duk_bool_t force_new) {\n\tduk_hobject *h;\n\n\t/* Shared helper for match() steps 3-4, search() steps 3-4. */\n\n\tDUK_ASSERT(idx >= 0);\n\n\tif (force_new) {\n\t\tgoto do_new;\n\t}\n\n\th = duk_get_hobject_with_class(thr, idx, DUK_HOBJECT_CLASS_REGEXP);\n\tif (!h) {\n\t\tgoto do_new;\n\t}\n\treturn;\n\n do_new:\n\tduk_push_hobject_bidx(thr, DUK_BIDX_REGEXP_CONSTRUCTOR);\n\tduk_dup(thr, idx);\n\tduk_new(thr, 1);  /* [ ... RegExp val ] -> [ ... res ] */\n\tduk_replace(thr, idx);\n}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_search(duk_hthread *thr) {\n\t/* Easiest way to implement the search required by the specification\n\t * is to do a RegExp test() with lastIndex forced to zero.  To avoid\n\t * side effects on the argument, \"clone\" the RegExp if a RegExp was\n\t * given as input.\n\t *\n\t * The global flag of the RegExp should be ignored; setting lastIndex\n\t * to zero (which happens when \"cloning\" the RegExp) should have an\n\t * equivalent effect.\n\t */\n\n\tDUK_ASSERT_TOP(thr, 1);\n\t(void) duk_push_this_coercible_to_string(thr);  /* at index 1 */\n\tduk__to_regexp_helper(thr, 0 /*index*/, 1 /*force_new*/);\n\n\t/* stack[0] = regexp\n\t * stack[1] = string\n\t */\n\n\t/* Avoid using RegExp.prototype methods, as they're writable and\n\t * configurable and may have been changed.\n\t */\n\n\tduk_dup_0(thr);\n\tduk_dup_1(thr);  /* [ ... re_obj input ] */\n\tduk_regexp_match(thr);  /* -> [ ... res_obj ] */\n\n\tif (!duk_is_object(thr, -1)) {\n\t\tduk_push_int(thr, -1);\n\t\treturn 1;\n\t}\n\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX);\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\treturn 1;\n}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_match(duk_hthread *thr) {\n\tduk_bool_t global;\n\tduk_int_t prev_last_index;\n\tduk_int_t this_index;\n\tduk_int_t arr_idx;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk__to_regexp_helper(thr, 0 /*index*/, 0 /*force_new*/);\n\tglobal = duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL);\n\tDUK_ASSERT_TOP(thr, 2);\n\n\t/* stack[0] = regexp\n\t * stack[1] = string\n\t */\n\n\tif (!global) {\n\t\tduk_regexp_match(thr);  /* -> [ res_obj ] */\n\t\treturn 1;  /* return 'res_obj' */\n\t}\n\n\t/* Global case is more complex. */\n\n\t/* [ regexp string ] */\n\n\tduk_push_int(thr, 0);\n\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\tduk_push_array(thr);\n\n\t/* [ regexp string res_arr ] */\n\n\tprev_last_index = 0;\n\tarr_idx = 0;\n\n\tfor (;;) {\n\t\tDUK_ASSERT_TOP(thr, 3);\n\n\t\tduk_dup_0(thr);\n\t\tduk_dup_1(thr);\n\t\tduk_regexp_match(thr);  /* -> [ ... regexp string ] -> [ ... res_obj ] */\n\n\t\tif (!duk_is_object(thr, -1)) {\n\t\t\tduk_pop(thr);\n\t\t\tbreak;\n\t\t}\n\n\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\tthis_index = duk_get_int(thr, -1);\n\t\tduk_pop(thr);\n\n\t\tif (this_index == prev_last_index) {\n\t\t\tthis_index++;\n\t\t\tduk_push_int(thr, this_index);\n\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t}\n\t\tprev_last_index = this_index;\n\n\t\tduk_get_prop_index(thr, -1, 0);  /* match string */\n\t\tduk_put_prop_index(thr, 2, (duk_uarridx_t) arr_idx);\n\t\tarr_idx++;\n\t\tduk_pop(thr);  /* res_obj */\n\t}\n\n\tif (arr_idx == 0) {\n\t\tduk_push_null(thr);\n\t}\n\n\treturn 1;  /* return 'res_arr' or 'null' */\n}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_concat(duk_hthread *thr) {\n\t/* duk_concat() coerces arguments with ToString() in correct order */\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk_insert(thr, 0);  /* this is relatively expensive */\n\tduk_concat(thr, duk_get_top(thr));\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_trim(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 0);\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk_trim(thr, 0);\n\tDUK_ASSERT_TOP(thr, 1);\n\treturn 1;\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_hthread *thr) {\n\tduk_hstring *h_input;\n\tduk_size_t input_blen;\n\tduk_size_t result_len;\n\tduk_int_t count_signed;\n\tduk_uint_t count;\n\tconst duk_uint8_t *src;\n\tduk_uint8_t *buf;\n\tduk_uint8_t *p;\n\tduk_double_t d;\n#if !defined(DUK_USE_PREFER_SIZE)\n\tduk_size_t copy_size;\n\tduk_uint8_t *p_end;\n#endif\n\n\tDUK_ASSERT_TOP(thr, 1);\n\th_input = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_input != NULL);\n\tinput_blen = DUK_HSTRING_GET_BYTELEN(h_input);\n\n\t/* Count is ToNumber() coerced; +Infinity must be always rejected\n\t * (even if input string is zero length), as well as negative values\n\t * and -Infinity.  -Infinity doesn't require an explicit check\n\t * because duk_get_int() clamps it to DUK_INT_MIN which gets rejected\n\t * as a negative value (regardless of input string length).\n\t */\n\td = duk_to_number(thr, 0);\n\tif (duk_double_is_posinf(d)) {\n\t\tgoto fail_range;\n\t}\n\tcount_signed = duk_get_int(thr, 0);\n\tif (count_signed < 0) {\n\t\tgoto fail_range;\n\t}\n\tcount = (duk_uint_t) count_signed;\n\n\t/* Overflow check for result length. */\n\tresult_len = count * input_blen;\n\tif (count != 0 && result_len / count != input_blen) {\n\t\tgoto fail_range;\n\t}\n\n\t/* Temporary fixed buffer, later converted to string. */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, result_len);\n\tDUK_ASSERT(buf != NULL);\n\tsrc = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tDUK_ASSERT(src != NULL);\n\n#if defined(DUK_USE_PREFER_SIZE)\n\tp = buf;\n\twhile (count-- > 0) {\n\t\tduk_memcpy((void *) p, (const void *) src, input_blen);  /* copy size may be zero, but pointers are valid */\n\t\tp += input_blen;\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\t/* Take advantage of already copied pieces to speed up the process\n\t * especially for small repeated strings.\n\t */\n\tp = buf;\n\tp_end = p + result_len;\n\tcopy_size = input_blen;\n\tfor (;;) {\n\t\tduk_size_t remain = (duk_size_t) (p_end - p);\n\t\tDUK_DDD(DUK_DDDPRINT(\"remain=%ld, copy_size=%ld, input_blen=%ld, result_len=%ld\",\n\t\t                     (long) remain, (long) copy_size, (long) input_blen,\n\t\t                     (long) result_len));\n\t\tif (remain <= copy_size) {\n\t\t\t/* If result_len is zero, this case is taken and does\n\t\t\t * a zero size copy (with valid pointers).\n\t\t\t */\n\t\t\tduk_memcpy((void *) p, (const void *) src, remain);\n\t\t\tbreak;\n\t\t} else {\n\t\t\tduk_memcpy((void *) p, (const void *) src, copy_size);\n\t\t\tp += copy_size;\n\t\t}\n\n\t\tsrc = (const duk_uint8_t *) buf;  /* Use buf as source for larger copies. */\n\t\tcopy_size = (duk_size_t) (p - buf);\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n\t/* XXX: It would be useful to be able to create a duk_hstring with\n\t * a certain byte size whose data area wasn't initialized and which\n\t * wasn't in the string table yet.  This would allow a string to be\n\t * constructed directly without a buffer temporary and when it was\n\t * finished, it could be injected into the string table.  Currently\n\t * this isn't possible because duk_hstrings are only tracked by the\n\t * intern table (they are not in heap_allocated).\n\t */\n\n\tduk_buffer_to_string(thr, -1);  /* Safe if input is safe. */\n\treturn 1;\n\n fail_range:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_ES6 */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_locale_compare(duk_hthread *thr) {\n\tduk_hstring *h1;\n\tduk_hstring *h2;\n\tduk_size_t h1_len, h2_len, prefix_len;\n\tduk_small_int_t ret = 0;\n\tduk_small_int_t rc;\n\n\t/* The current implementation of localeCompare() is simply a codepoint\n\t * by codepoint comparison, implemented with a simple string compare\n\t * because UTF-8 should preserve codepoint ordering (assuming valid\n\t * shortest UTF-8 encoding).\n\t *\n\t * The specification requires that the return value must be related\n\t * to the sort order: e.g. negative means that 'this' comes before\n\t * 'that' in sort order.  We assume an ascending sort order.\n\t */\n\n\t/* XXX: could share code with duk_js_ops.c, duk_js_compare_helper */\n\n\th1 = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h1 != NULL);\n\n\th2 = duk_to_hstring(thr, 0);\n\tDUK_ASSERT(h2 != NULL);\n\n\th1_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1);\n\th2_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2);\n\tprefix_len = (h1_len <= h2_len ? h1_len : h2_len);\n\n\trc = (duk_small_int_t) duk_memcmp((const void *) DUK_HSTRING_GET_DATA(h1),\n\t                                  (const void *) DUK_HSTRING_GET_DATA(h2),\n\t                                  (size_t) prefix_len);\n\n\tif (rc < 0) {\n\t\tret = -1;\n\t\tgoto done;\n\t} else if (rc > 0) {\n\t\tret = 1;\n\t\tgoto done;\n\t}\n\n\t/* prefix matches, lengths matter now */\n\tif (h1_len > h2_len) {\n\t\tret = 1;\n\t\tgoto done;\n\t} else if (h1_len == h2_len) {\n\t\tDUK_ASSERT(ret == 0);\n\t\tgoto done;\n\t}\n\tret = -1;\n\tgoto done;\n\n done:\n\tduk_push_int(thr, (duk_int_t) ret);\n\treturn 1;\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_hthread *thr) {\n\tduk_int_t magic;\n\tduk_hstring *h;\n\tduk_hstring *h_search;\n\tduk_size_t blen_search;\n\tconst duk_uint8_t *p_cmp_start;\n\tduk_bool_t result;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\th_search = duk__str_tostring_notregexp(thr, 0);\n\tDUK_ASSERT(h_search != NULL);\n\n\tmagic = duk_get_current_magic(thr);\n\n\tp_cmp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tblen_search = DUK_HSTRING_GET_BYTELEN(h_search);\n\n\tif (duk_is_undefined(thr, 1)) {\n\t\tif (magic) {\n\t\t\tp_cmp_start = p_cmp_start + DUK_HSTRING_GET_BYTELEN(h) - blen_search;\n\t\t} else {\n\t\t\t/* p_cmp_start already OK */\n\t\t}\n\t} else {\n\t\tduk_int_t len;\n\t\tduk_int_t pos;\n\n\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= DUK_INT_MAX);\n\t\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\t\tpos = duk_to_int_clamped(thr, 1, 0, len);\n\t\tDUK_ASSERT(pos >= 0 && pos <= len);\n\n\t\tif (magic) {\n\t\t\tp_cmp_start -= blen_search;  /* Conceptually subtracted last, but do already here. */\n\t\t}\n\t\tDUK_ASSERT(pos >= 0 && pos <= len);\n\n\t\tp_cmp_start += duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) pos);\n\t}\n\n\t/* The main comparison can be done using a memcmp() rather than\n\t * doing codepoint comparisons: for CESU-8 strings there is a\n\t * canonical representation for every codepoint.  But we do need\n\t * to deal with the char/byte offset translation to find the\n\t * comparison range.\n\t */\n\n\tresult = 0;\n\tif (p_cmp_start >= DUK_HSTRING_GET_DATA(h) &&\n\t    (duk_size_t) (p_cmp_start - (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h)) + blen_search <= DUK_HSTRING_GET_BYTELEN(h)) {\n\t\tif (duk_memcmp((const void *) p_cmp_start,\n\t\t               (const void *) DUK_HSTRING_GET_DATA(h_search),\n\t\t               (size_t) blen_search) == 0) {\n\t\t\tresult = 1;\n\t\t}\n\t}\n\n\tduk_push_boolean(thr, result);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_includes(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_hstring *h_search;\n\tduk_int_t len;\n\tduk_int_t pos;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\th_search = duk__str_tostring_notregexp(thr, 0);\n\tDUK_ASSERT(h_search != NULL);\n\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\tpos = duk_to_int_clamped(thr, 1, 0, len);\n\tDUK_ASSERT(pos >= 0 && pos <= len);\n\n\tpos = duk__str_search_shared(thr, h, h_search, pos, 0 /*backwards*/);\n\tduk_push_boolean(thr, pos >= 0);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n#endif  /* DUK_USE_STRING_BUILTIN */\n#line 1 \"duk_bi_symbol.c\"\n/*\n *  Symbol built-in\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_constructor_shared(duk_hthread *thr) {\n\tconst duk_uint8_t *desc;\n\tduk_size_t len;\n\tduk_uint8_t *buf;\n\tduk_uint8_t *p;\n\tduk_int_t magic;\n\n\tmagic = duk_get_current_magic(thr);\n\tif (duk_is_undefined(thr, 0) && (magic == 0)) {\n\t\t/* Symbol() accepts undefined and empty string, but they are\n\t\t * treated differently.\n\t\t */\n\t\tdesc = NULL;\n\t\tlen = 0;\n\t} else {\n\t\t/* Symbol.for() coerces undefined to 'undefined' */\n\t\tdesc = (const duk_uint8_t *) duk_to_lstring(thr, 0, &len);\n\t}\n\n\t/* Maximum symbol data length:\n\t *   +1    initial byte (0x80 or 0x81)\n\t *   +len  description\n\t *   +1    0xff after description, before unique suffix\n\t *   +17   autogenerated unique suffix: 'ffffffff-ffffffff' is longest\n\t *   +1    0xff after unique suffix for symbols with undefined description\n\t */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer(thr, 1 + len + 1 + 17 + 1);\n\tDUK_ASSERT(buf != NULL);\n\tp = buf + 1;\n\tDUK_ASSERT(desc != NULL || len == 0);  /* may be NULL if len is 0 */\n\tduk_memcpy_unsafe((void *) p, (const void *) desc, len);\n\tp += len;\n\tif (magic == 0) {\n\t\t/* Symbol(): create unique symbol.  Use two 32-bit values\n\t\t * to avoid dependency on 64-bit types and 64-bit integer\n\t\t * formatting (at least for now).\n\t\t */\n\t\tif (++thr->heap->sym_counter[0] == 0) {\n\t\t\tthr->heap->sym_counter[1]++;\n\t\t}\n\t\tp += DUK_SPRINTF((char *) p, \"\\xFF\" \"%lx-%lx\",\n\t\t                 (unsigned long) thr->heap->sym_counter[1],\n\t\t                 (unsigned long) thr->heap->sym_counter[0]);\n\t\tif (desc == NULL) {\n\t\t\t/* Special case for 'undefined' description, trailing\n\t\t\t * 0xff distinguishes from empty string description,\n\t\t\t * but needs minimal special case handling elsewhere.\n\t\t\t */\n\t\t\t*p++ = 0xff;\n\t\t}\n\t\tbuf[0] = 0x81;\n\t} else {\n\t\t/* Symbol.for(): create a global symbol */\n\t\tbuf[0] = 0x80;\n\t}\n\n\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) (p - buf));\n\tDUK_DDD(DUK_DDDPRINT(\"created symbol: %!T\", duk_get_tval(thr, -1)));\n\treturn 1;\n}\n\nDUK_LOCAL duk_hstring *duk__auto_unbox_symbol(duk_hthread *thr, duk_tval *tv_arg) {\n\tduk_tval *tv;\n\tduk_hobject *h_obj;\n\tduk_hstring *h_str;\n\n\tDUK_ASSERT(tv_arg != NULL);\n\n\t/* XXX: add internal helper: duk_auto_unbox_tval(thr, tv, mask); */\n\t/* XXX: add internal helper: duk_auto_unbox(thr, tv, idx); */\n\n\ttv = tv_arg;\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_obj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_SYMBOL) {\n\t\t\ttv = duk_hobject_get_internal_value_tval_ptr(thr->heap, h_obj);\n\t\t\tif (tv == NULL) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t} else {\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\tif (!DUK_TVAL_IS_STRING(tv)) {\n\t\treturn NULL;\n\t}\n\th_str = DUK_TVAL_GET_STRING(tv);\n\tDUK_ASSERT(h_str != NULL);\n\n\t/* Here symbol is more expected than not. */\n\tif (DUK_UNLIKELY(!DUK_HSTRING_HAS_SYMBOL(h_str))) {\n\t\treturn NULL;\n\t}\n\n\treturn h_str;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_tostring_shared(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\th_str = duk__auto_unbox_symbol(thr, DUK_HTHREAD_THIS_PTR(thr));\n\tif (h_str == NULL) {\n\t\treturn DUK_RET_TYPE_ERROR;\n\t}\n\n\tif (duk_get_current_magic(thr) == 0) {\n\t\t/* .toString() */\n\t\tduk_push_symbol_descriptive_string(thr, h_str);\n\t} else {\n\t\t/* .valueOf() */\n\t\tduk_push_hstring(thr, h_str);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_key_for(duk_hthread *thr) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p;\n\n\t/* Argument must be a symbol but not checked here.  The initial byte\n\t * check will catch non-symbol strings.\n\t */\n\th = duk_require_hstring(thr, 0);\n\tDUK_ASSERT(h != NULL);\n\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tDUK_ASSERT(p != NULL);\n\n\t/* Even for zero length strings there's at least one NUL byte so\n\t * we can safely check the initial byte.\n\t */\n\tif (p[0] == 0x80) {\n\t\t/* Global symbol, return its key (bytes just after the initial byte). */\n\t\tduk_push_lstring(thr, (const char *) (p + 1), (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h) - 1));\n\t\treturn 1;\n\t} else if (p[0] == 0x81 || p[0] == 0x82 || p[0] == 0xff) {\n\t\t/* Local symbol or hidden symbol, return undefined. */\n\t\treturn 0;\n\t}\n\n\t/* Covers normal strings and unknown initial bytes. */\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_toprimitive(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\th_str = duk__auto_unbox_symbol(thr, DUK_HTHREAD_THIS_PTR(thr));\n\tif (h_str == NULL) {\n\t\treturn DUK_RET_TYPE_ERROR;\n\t}\n\tduk_push_hstring(thr, h_str);\n\treturn 1;\n}\n\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n#line 1 \"duk_bi_thread.c\"\n/*\n *  Thread builtins\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Constructor\n */\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_constructor(duk_hthread *thr) {\n\tduk_hthread *new_thr;\n\tduk_hobject *func;\n\n\t/* Check that the argument is callable; this is not 100% because we\n\t * don't allow native functions to be a thread's initial function.\n\t * Resume will reject such functions in any case.\n\t */\n\t/* XXX: need a duk_require_func_promote_lfunc() */\n\tfunc = duk_require_hobject_promote_lfunc(thr, 0);\n\tDUK_ASSERT(func != NULL);\n\tduk_require_callable(thr, 0);\n\n\tduk_push_thread(thr);\n\tnew_thr = (duk_hthread *) duk_known_hobject(thr, -1);\n\tnew_thr->state = DUK_HTHREAD_STATE_INACTIVE;\n\n\t/* push initial function call to new thread stack; this is\n\t * picked up by resume().\n\t */\n\tduk_push_hobject(new_thr, func);\n\n\treturn 1;  /* return thread */\n}\n#endif\n\n/*\n *  Resume a thread.\n *\n *  The thread must be in resumable state, either (a) new thread which hasn't\n *  yet started, or (b) a thread which has previously yielded.  This method\n *  must be called from an ECMAScript function.\n *\n *  Args:\n *    - thread\n *    - value\n *    - isError (defaults to false)\n *\n *  Note: yield and resume handling is currently asymmetric.\n */\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) {\n\tduk_hthread *thr = (duk_hthread *) ctx;\n\tduk_hthread *thr_resume;\n\tduk_hobject *caller_func;\n\tduk_small_uint_t is_error;\n\n\tDUK_DDD(DUK_DDDPRINT(\"Duktape.Thread.resume(): thread=%!T, value=%!T, is_error=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1),\n\t                     (duk_tval *) duk_get_tval(thr, 2)));\n\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\tDUK_ASSERT(thr->heap->curr_thread == thr);\n\n\tthr_resume = duk_require_hthread(thr, 0);\n\tDUK_ASSERT(duk_get_top(thr) == 3);\n\tis_error = (duk_small_uint_t) duk_to_boolean_top_pop(thr);\n\tDUK_ASSERT(duk_get_top(thr) == 2);\n\n\t/* [ thread value ] */\n\n\t/*\n\t *  Thread state and calling context checks\n\t */\n\n\tif (thr->callstack_top < 2) {\n\t\tDUK_DD(DUK_DDPRINT(\"resume state invalid: callstack should contain at least 2 entries (caller and Duktape.Thread.resume)\"));\n\t\tgoto state_error;\n\t}\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);  /* us */\n\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL);  /* caller */\n\n\tcaller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent);\n\tif (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) {\n\t\tDUK_DD(DUK_DDPRINT(\"resume state invalid: caller must be ECMAScript code\"));\n\t\tgoto state_error;\n\t}\n\n\t/* Note: there is no requirement that: 'thr->callstack_preventcount == 1'\n\t * like for yield.\n\t */\n\n\tif (thr_resume->state != DUK_HTHREAD_STATE_INACTIVE &&\n\t    thr_resume->state != DUK_HTHREAD_STATE_YIELDED) {\n\t\tDUK_DD(DUK_DDPRINT(\"resume state invalid: target thread must be INACTIVE or YIELDED\"));\n\t\tgoto state_error;\n\t}\n\n\tDUK_ASSERT(thr_resume->state == DUK_HTHREAD_STATE_INACTIVE ||\n\t           thr_resume->state == DUK_HTHREAD_STATE_YIELDED);\n\n\t/* Further state-dependent pre-checks */\n\n\tif (thr_resume->state == DUK_HTHREAD_STATE_YIELDED) {\n\t\t/* no pre-checks now, assume a previous yield() has left things in\n\t\t * tip-top shape (longjmp handler will assert for these).\n\t\t */\n\t} else {\n\t\tduk_hobject *h_fun;\n\n\t\tDUK_ASSERT(thr_resume->state == DUK_HTHREAD_STATE_INACTIVE);\n\n\t\t/* The initial function must be an ECMAScript function (but\n\t\t * can be bound).  We must make sure of that before we longjmp\n\t\t * because an error in the RESUME handler call processing will\n\t\t * not be handled very cleanly.\n\t\t */\n\t\tif ((thr_resume->callstack_top != 0) ||\n\t\t    (thr_resume->valstack_top - thr_resume->valstack != 1)) {\n\t\t\tgoto state_error;\n\t\t}\n\n\t\tduk_push_tval(thr, DUK_GET_TVAL_NEGIDX(thr_resume, -1));\n\t\tduk_resolve_nonbound_function(thr);\n\t\th_fun = duk_require_hobject(thr, -1);  /* reject lightfuncs on purpose */\n\t\tif (!DUK_HOBJECT_IS_CALLABLE(h_fun) || !DUK_HOBJECT_IS_COMPFUNC(h_fun)) {\n\t\t\tgoto state_error;\n\t\t}\n\t\tduk_pop(thr);\n\t}\n\n#if 0\n\t/* This check would prevent a heap destruction time finalizer from\n\t * launching a coroutine, which would ensure that during finalization\n\t * 'thr' would always equal heap_thread.  Normal runtime finalizers\n\t * run with ms_running == 0, i.e. outside mark-and-sweep.  See GH-2030.\n\t */\n\tif (thr->heap->ms_running) {\n\t\tDUK_D(DUK_DPRINT(\"refuse Duktape.Thread.resume() when ms_running != 0\"));\n\t\tgoto state_error;\n\t}\n#endif\n\n\t/*\n\t *  The error object has been augmented with a traceback and other\n\t *  info from its creation point -- usually another thread.  The\n\t *  error handler is called here right before throwing, but it also\n\t *  runs in the resumer's thread.  It might be nice to get a traceback\n\t *  from the resumee but this is not the case now.\n\t */\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\tif (is_error) {\n\t\tDUK_ASSERT_TOP(thr, 2);  /* value (error) is at stack top */\n\t\tduk_err_augment_error_throw(thr);  /* in resumer's context */\n\t}\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\tif (is_error) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"RESUME ERROR: thread=%!T, value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\t} else if (thr_resume->state == DUK_HTHREAD_STATE_YIELDED) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"RESUME NORMAL: thread=%!T, value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"RESUME INITIAL: thread=%!T, value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\t}\n#endif\n\n\tthr->heap->lj.type = DUK_LJ_TYPE_RESUME;\n\n\t/* lj value2: thread */\n\tDUK_ASSERT(thr->valstack_bottom < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value2, &thr->valstack_bottom[0]);  /* side effects */\n\n\t/* lj value1: value */\n\tDUK_ASSERT(thr->valstack_bottom + 1 < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, &thr->valstack_bottom[1]);  /* side effects */\n\tDUK_TVAL_CHKFAST_INPLACE_SLOW(&thr->heap->lj.value1);\n\n\tthr->heap->lj.iserror = is_error;\n\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* call is from executor, so we know we have a jmpbuf */\n\tduk_err_longjmp(thr);  /* execution resumes in bytecode executor */\n\tDUK_UNREACHABLE();\n\t/* Never here, fall through to error (from compiler point of view). */\n\n state_error:\n\tDUK_DCERROR_TYPE_INVALID_STATE(thr);\n}\n#endif\n\n/*\n *  Yield the current thread.\n *\n *  The thread must be in yieldable state: it must have a resumer, and there\n *  must not be any yield-preventing calls (native calls and constructor calls,\n *  currently) in the thread's call stack (otherwise a resume would not be\n *  possible later).  This method must be called from an ECMAScript function.\n *\n *  Args:\n *    - value\n *    - isError (defaults to false)\n *\n *  Note: yield and resume handling is currently asymmetric.\n */\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_hthread *thr) {\n\tduk_hobject *caller_func;\n\tduk_small_uint_t is_error;\n\n\tDUK_DDD(DUK_DDDPRINT(\"Duktape.Thread.yield(): value=%!T, is_error=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\tDUK_ASSERT(thr->heap->curr_thread == thr);\n\n\tDUK_ASSERT(duk_get_top(thr) == 2);\n\tis_error = (duk_small_uint_t) duk_to_boolean_top_pop(thr);\n\tDUK_ASSERT(duk_get_top(thr) == 1);\n\n\t/* [ value ] */\n\n\t/*\n\t *  Thread state and calling context checks\n\t */\n\n\tif (!thr->resumer) {\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: current thread must have a resumer\"));\n\t\tgoto state_error;\n\t}\n\tDUK_ASSERT(thr->resumer->state == DUK_HTHREAD_STATE_RESUMED);\n\n\tif (thr->callstack_top < 2) {\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: callstack should contain at least 2 entries (caller and Duktape.Thread.yield)\"));\n\t\tgoto state_error;\n\t}\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);  /* us */\n\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL);  /* caller */\n\n\tcaller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent);\n\tif (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) {\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: caller must be ECMAScript code\"));\n\t\tgoto state_error;\n\t}\n\n\tDUK_ASSERT(thr->callstack_preventcount >= 1);  /* should never be zero, because we (Duktape.Thread.yield) are on the stack */\n\tif (thr->callstack_preventcount != 1) {\n\t\t/* Note: the only yield-preventing call is Duktape.Thread.yield(), hence check for 1, not 0 */\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: there must be no yield-preventing calls in current thread callstack (preventcount is %ld)\",\n\t\t                   (long) thr->callstack_preventcount));\n\t\tgoto state_error;\n\t}\n\n\t/*\n\t *  The error object has been augmented with a traceback and other\n\t *  info from its creation point -- usually the current thread.\n\t *  The error handler, however, is called right before throwing\n\t *  and runs in the yielder's thread.\n\t */\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\tif (is_error) {\n\t\tDUK_ASSERT_TOP(thr, 1);  /* value (error) is at stack top */\n\t\tduk_err_augment_error_throw(thr);  /* in yielder's context */\n\t}\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\tif (is_error) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"YIELD ERROR: value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0)));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"YIELD NORMAL: value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0)));\n\t}\n#endif\n\n\t/*\n\t *  Process yield\n\t *\n\t *  After longjmp(), processing continues in bytecode executor longjmp\n\t *  handler, which will e.g. update thr->resumer to NULL.\n\t */\n\n\tthr->heap->lj.type = DUK_LJ_TYPE_YIELD;\n\n\t/* lj value1: value */\n\tDUK_ASSERT(thr->valstack_bottom < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, &thr->valstack_bottom[0]);  /* side effects */\n\tDUK_TVAL_CHKFAST_INPLACE_SLOW(&thr->heap->lj.value1);\n\n\tthr->heap->lj.iserror = is_error;\n\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* call is from executor, so we know we have a jmpbuf */\n\tduk_err_longjmp(thr);  /* execution resumes in bytecode executor */\n\tDUK_UNREACHABLE();\n\t/* Never here, fall through to error (from compiler point of view). */\n\n state_error:\n\tDUK_DCERROR_TYPE_INVALID_STATE(thr);\n}\n#endif\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_current(duk_hthread *thr) {\n\tduk_push_current_thread(thr);\n\treturn 1;\n}\n#endif\n#line 1 \"duk_bi_thrower.c\"\n/*\n *  Type error thrower, E5 Section 13.2.3.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL duk_ret_t duk_bi_type_error_thrower(duk_hthread *thr) {\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n#line 1 \"duk_debug_fixedbuffer.c\"\n/*\n *  Fixed buffer helper useful for debugging, requires no allocation\n *  which is critical for debugging.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_DEBUG)\n\nDUK_INTERNAL void duk_fb_put_bytes(duk_fixedbuffer *fb, const duk_uint8_t *buffer, duk_size_t length) {\n\tduk_size_t avail;\n\tduk_size_t copylen;\n\n\tavail = (fb->offset >= fb->length ? (duk_size_t) 0 : (duk_size_t) (fb->length - fb->offset));\n\tif (length > avail) {\n\t\tcopylen = avail;\n\t\tfb->truncated = 1;\n\t} else {\n\t\tcopylen = length;\n\t}\n\tduk_memcpy_unsafe(fb->buffer + fb->offset, buffer, copylen);\n\tfb->offset += copylen;\n}\n\nDUK_INTERNAL void duk_fb_put_byte(duk_fixedbuffer *fb, duk_uint8_t x) {\n\tduk_fb_put_bytes(fb, (const duk_uint8_t *) &x, 1);\n}\n\nDUK_INTERNAL void duk_fb_put_cstring(duk_fixedbuffer *fb, const char *x) {\n\tduk_fb_put_bytes(fb, (const duk_uint8_t *) x, (duk_size_t) DUK_STRLEN(x));\n}\n\nDUK_INTERNAL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...) {\n\tduk_size_t avail;\n\tva_list ap;\n\n\tva_start(ap, fmt);\n\tavail = (fb->offset >= fb->length ? (duk_size_t) 0 : (duk_size_t) (fb->length - fb->offset));\n\tif (avail > 0) {\n\t\tduk_int_t res = (duk_int_t) DUK_VSNPRINTF((char *) (fb->buffer + fb->offset), avail, fmt, ap);\n\t\tif (res < 0) {\n\t\t\t/* error */\n\t\t} else if ((duk_size_t) res >= avail) {\n\t\t\t/* (maybe) truncated */\n\t\t\tfb->offset += avail;\n\t\t\tif ((duk_size_t) res > avail) {\n\t\t\t\t/* actual chars dropped (not just NUL term) */\n\t\t\t\tfb->truncated = 1;\n\t\t\t}\n\t\t} else {\n\t\t\t/* normal */\n\t\t\tfb->offset += (duk_size_t) res;\n\t\t}\n\t}\n\tva_end(ap);\n}\n\nDUK_INTERNAL void duk_fb_put_funcptr(duk_fixedbuffer *fb, duk_uint8_t *fptr, duk_size_t fptr_size) {\n\tchar buf[64+1];\n\tduk_debug_format_funcptr(buf, sizeof(buf), fptr, fptr_size);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\tduk_fb_put_cstring(fb, buf);\n}\n\nDUK_INTERNAL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb) {\n\treturn (fb->offset >= fb->length);\n}\n\n#endif  /* DUK_USE_DEBUG */\n#line 1 \"duk_debug_vsnprintf.c\"\n/*\n *  Custom formatter for debug printing, allowing Duktape specific data\n *  structures (such as tagged values and heap objects) to be printed with\n *  a nice format string.  Because debug printing should not affect execution\n *  state, formatting here must be independent of execution (see implications\n *  below) and must not allocate memory.\n *\n *  Custom format tags begin with a '%!' to safely distinguish them from\n *  standard format tags.  The following conversions are supported:\n *\n *     %!T    tagged value (duk_tval *)\n *     %!O    heap object (duk_heaphdr *)\n *     %!I    decoded bytecode instruction\n *     %!X    bytecode instruction opcode name (arg is long)\n *     %!C    catcher (duk_catcher *)\n *     %!A    activation (duk_activation *)\n *\n *  Everything is serialized in a JSON-like manner.  The default depth is one\n *  level, internal prototype is not followed, and internal properties are not\n *  serialized.  The following modifiers change this behavior:\n *\n *     @      print pointers\n *     #      print binary representations (where applicable)\n *     d      deep traversal of own properties (not prototype)\n *     p      follow prototype chain (useless without 'd')\n *     i      include internal properties (other than prototype)\n *     x      hexdump buffers\n *     h      heavy formatting\n *\n *  For instance, the following serializes objects recursively, but does not\n *  follow the prototype chain nor print internal properties: \"%!dO\".\n *\n *  Notes:\n *\n *    * Standard snprintf return value semantics seem to vary.  This\n *      implementation returns the number of bytes it actually wrote\n *      (excluding the null terminator).  If retval == buffer size,\n *      output was truncated (except for corner cases).\n *\n *    * Output format is intentionally different from ECMAScript\n *      formatting requirements, as formatting here serves debugging\n *      of internals.\n *\n *    * Depth checking (and updating) is done in each type printer\n *      separately, to allow them to call each other freely.\n *\n *    * Some pathological structures might take ages to print (e.g.\n *      self recursion with 100 properties pointing to the object\n *      itself).  To guard against these, each printer also checks\n *      whether the output buffer is full; if so, early exit.\n *\n *    * Reference loops are detected using a loop stack.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_DEBUG)\n\n/* #include stdio.h -> already included */\n/* #include stdarg.h -> already included */\n#include <string.h>\n\n/* list of conversion specifiers that terminate a format tag;\n * this is unfortunately guesswork.\n */\n#define DUK__ALLOWED_STANDARD_SPECIFIERS  \"diouxXeEfFgGaAcsCSpnm\"\n\n/* maximum length of standard format tag that we support */\n#define DUK__MAX_FORMAT_TAG_LENGTH  32\n\n/* heapobj recursion depth when deep printing is selected */\n#define DUK__DEEP_DEPTH_LIMIT  8\n\n/* maximum recursion depth for loop detection stacks */\n#define DUK__LOOP_STACK_DEPTH  256\n\n/* must match bytecode defines now; build autogenerate? */\nDUK_LOCAL const char * const duk__bc_optab[256] = {\n\t\"LDREG\", \"STREG\", \"JUMP\", \"LDCONST\", \"LDINT\", \"LDINTX\", \"LDTHIS\", \"LDUNDEF\",\n\t\"LDNULL\", \"LDTRUE\", \"LDFALSE\", \"GETVAR\", \"BNOT\", \"LNOT\", \"UNM\", \"UNP\",\n\t\"EQ_RR\", \"EQ_CR\", \"EQ_RC\", \"EQ_CC\", \"NEQ_RR\", \"NEQ_CR\", \"NEQ_RC\", \"NEQ_CC\",\n\t\"SEQ_RR\", \"SEQ_CR\", \"SEQ_RC\", \"SEQ_CC\", \"SNEQ_RR\", \"SNEQ_CR\", \"SNEQ_RC\", \"SNEQ_CC\",\n\n\t\"GT_RR\", \"GT_CR\", \"GT_RC\", \"GT_CC\", \"GE_RR\", \"GE_CR\", \"GE_RC\", \"GE_CC\",\n\t\"LT_RR\", \"LT_CR\", \"LT_RC\", \"LT_CC\", \"LE_RR\", \"LE_CR\", \"LE_RC\", \"LE_CC\",\n\t\"IFTRUE_R\", \"IFTRUE_C\", \"IFFALSE_R\", \"IFFALSE_C\", \"ADD_RR\", \"ADD_CR\", \"ADD_RC\", \"ADD_CC\",\n\t\"SUB_RR\", \"SUB_CR\", \"SUB_RC\", \"SUB_CC\", \"MUL_RR\", \"MUL_CR\", \"MUL_RC\", \"MUL_CC\",\n\n\t\"DIV_RR\", \"DIV_CR\", \"DIV_RC\", \"DIV_CC\", \"MOD_RR\", \"MOD_CR\", \"MOD_RC\", \"MOD_CC\",\n\t\"EXP_RR\", \"EXP_CR\", \"EXP_RC\", \"EXP_CC\", \"BAND_RR\", \"BAND_CR\", \"BAND_RC\", \"BAND_CC\",\n\t\"BOR_RR\", \"BOR_CR\", \"BOR_RC\", \"BOR_CC\", \"BXOR_RR\", \"BXOR_CR\", \"BXOR_RC\", \"BXOR_CC\",\n\t\"BASL_RR\", \"BASL_CR\", \"BASL_RC\", \"BASL_CC\", \"BLSR_RR\", \"BLSR_CR\", \"BLSR_RC\", \"BLSR_CC\",\n\n\t\"BASR_RR\", \"BASR_CR\", \"BASR_RC\", \"BASR_CC\", \"INSTOF_RR\", \"INSTOF_CR\", \"INSTOF_RC\", \"INSTOF_CC\",\n\t\"IN_RR\", \"IN_CR\", \"IN_RC\", \"IN_CC\", \"GETPROP_RR\", \"GETPROP_CR\", \"GETPROP_RC\", \"GETPROP_CC\",\n\t\"PUTPROP_RR\", \"PUTPROP_CR\", \"PUTPROP_RC\", \"PUTPROP_CC\", \"DELPROP_RR\", \"DELPROP_CR\", \"DELPROP_RC\", \"DELPROP_CC\",\n\t\"PREINCR\", \"PREDECR\", \"POSTINCR\", \"POSTDECR\", \"PREINCV\", \"PREDECV\", \"POSTINCV\", \"POSTDECV\",\n\n\t\"PREINCP_RR\", \"PREINCP_CR\", \"PREINCP_RC\", \"PREINCP_CC\", \"PREDECP_RR\", \"PREDECP_CR\", \"PREDECP_RC\", \"PREDECP_CC\",\n\t\"POSTINCP_RR\", \"POSTINCP_CR\", \"POSTINCP_RC\", \"POSTINCP_CC\", \"POSTDECP_RR\", \"POSTDECP_CR\", \"POSTDECP_RC\", \"POSTDECP_CC\",\n\t\"DECLVAR_RR\", \"DECLVAR_CR\", \"DECLVAR_RC\", \"DECLVAR_CC\", \"REGEXP_RR\", \"REGEXP_RC\", \"REGEXP_CR\", \"REGEXP_CC\",\n\t\"CLOSURE\", \"TYPEOF\", \"TYPEOFID\", \"PUTVAR\", \"DELVAR\", \"RETREG\", \"RETUNDEF\", \"RETCONST\",\n\n\t\"RETCONSTN\", \"LABEL\", \"ENDLABEL\", \"BREAK\", \"CONTINUE\", \"TRYCATCH\", \"ENDTRY\", \"ENDCATCH\",\n\t\"ENDFIN\", \"THROW\", \"INVLHS\", \"CSREG\", \"CSVAR_RR\", \"CSVAR_CR\", \"CSVAR_RC\", \"CSVAR_CC\",\n\t\"CALL0\", \"CALL1\", \"CALL2\", \"CALL3\", \"CALL4\", \"CALL5\", \"CALL6\", \"CALL7\",\n\t\"CALL8\", \"CALL9\", \"CALL10\", \"CALL11\", \"CALL12\", \"CALL13\", \"CALL14\", \"CALL15\",\n\n\t\"NEWOBJ\", \"NEWARR\", \"MPUTOBJ\", \"MPUTOBJI\", \"INITSET\", \"INITGET\", \"MPUTARR\", \"MPUTARRI\",\n\t\"SETALEN\", \"INITENUM\", \"NEXTENUM\", \"NEWTARGET\", \"DEBUGGER\", \"NOP\", \"INVALID\", \"UNUSED207\",\n\t\"GETPROPC_RR\", \"GETPROPC_CR\", \"GETPROPC_RC\", \"GETPROPC_CC\", \"UNUSED212\", \"UNUSED213\", \"UNUSED214\", \"UNUSED215\",\n\t\"UNUSED216\", \"UNUSED217\", \"UNUSED218\", \"UNUSED219\", \"UNUSED220\", \"UNUSED221\", \"UNUSED222\", \"UNUSED223\",\n\n\t\"UNUSED224\", \"UNUSED225\", \"UNUSED226\", \"UNUSED227\", \"UNUSED228\", \"UNUSED229\", \"UNUSED230\", \"UNUSED231\",\n\t\"UNUSED232\", \"UNUSED233\", \"UNUSED234\", \"UNUSED235\", \"UNUSED236\", \"UNUSED237\", \"UNUSED238\", \"UNUSED239\",\n\t\"UNUSED240\", \"UNUSED241\", \"UNUSED242\", \"UNUSED243\", \"UNUSED244\", \"UNUSED245\", \"UNUSED246\", \"UNUSED247\",\n\t\"UNUSED248\", \"UNUSED249\", \"UNUSED250\", \"UNUSED251\", \"UNUSED252\", \"UNUSED253\", \"UNUSED254\", \"UNUSED255\"\n};\n\ntypedef struct duk__dprint_state duk__dprint_state;\nstruct duk__dprint_state {\n\tduk_fixedbuffer *fb;\n\n\t/* loop_stack_index could be perhaps be replaced by 'depth', but it's nice\n\t * to not couple these two mechanisms unnecessarily.\n\t */\n\tduk_hobject *loop_stack[DUK__LOOP_STACK_DEPTH];\n\tduk_int_t loop_stack_index;\n\tduk_int_t loop_stack_limit;\n\n\tduk_int_t depth;\n\tduk_int_t depth_limit;\n\n\tduk_bool_t pointer;\n\tduk_bool_t heavy;\n\tduk_bool_t binary;\n\tduk_bool_t follow_proto;\n\tduk_bool_t internal;\n\tduk_bool_t hexdump;\n};\n\n/* helpers */\nDUK_LOCAL_DECL void duk__print_hstring(duk__dprint_state *st, duk_hstring *k, duk_bool_t quotes);\nDUK_LOCAL_DECL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h);\nDUK_LOCAL_DECL void duk__print_hbuffer(duk__dprint_state *st, duk_hbuffer *h);\nDUK_LOCAL_DECL void duk__print_tval(duk__dprint_state *st, duk_tval *tv);\nDUK_LOCAL_DECL void duk__print_instr(duk__dprint_state *st, duk_instr_t ins);\nDUK_LOCAL_DECL void duk__print_heaphdr(duk__dprint_state *st, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__print_shared_heaphdr(duk__dprint_state *st, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__print_shared_heaphdr_string(duk__dprint_state *st, duk_heaphdr_string *h);\n\nDUK_LOCAL void duk__print_shared_heaphdr(duk__dprint_state *st, duk_heaphdr *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"(%p)\", (void *) h);\n\t}\n\n\tif (!h) {\n\t\treturn;\n\t}\n\n\tif (st->binary) {\n\t\tduk_size_t i;\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET);\n\t\tfor (i = 0; i < (duk_size_t) sizeof(*h); i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) ((duk_uint8_t *)h)[i]);\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET);\n\t}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)  /* currently implicitly also DUK_USE_DOUBLE_LINKED_HEAP */\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_next=%p,h_prev=%p,h_refcount=%lu,h_flags=%08lx,type=%ld,\"\n\t\t               \"reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (void *) DUK_HEAPHDR_GET_NEXT(NULL, h),\n\t\t               (void *) DUK_HEAPHDR_GET_PREV(NULL, h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS(h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE(h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED(h) ? 1 : 0));\n\t}\n#else\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_next=%p,h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (void *) DUK_HEAPHDR_GET_NEXT(NULL, h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS(h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE(h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED(h) ? 1 : 0));\n\t}\n#endif\n}\n\nDUK_LOCAL void duk__print_shared_heaphdr_string(duk__dprint_state *st, duk_heaphdr_string *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"(%p)\", (void *) h);\n\t}\n\n\tif (!h) {\n\t\treturn;\n\t}\n\n\tif (st->binary) {\n\t\tduk_size_t i;\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET);\n\t\tfor (i = 0; i < (duk_size_t) sizeof(*h); i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) ((duk_uint8_t *)h)[i]);\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET);\n\t}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_refcount=%lu,h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (unsigned long) DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) h) ? 1 : 0));\n\t}\n#else\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) h) ? 1 : 0));\n\t}\n#endif\n}\n\nDUK_LOCAL void duk__print_hstring(duk__dprint_state *st, duk_hstring *h, duk_bool_t quotes) {\n\tduk_fixedbuffer *fb = st->fb;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\n\t/* terminal type: no depth check */\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tduk__print_shared_heaphdr_string(st, &h->hdr);\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tp = DUK_HSTRING_GET_DATA(h);\n\tp_end = p + DUK_HSTRING_GET_BYTELEN(h);\n\n\tif (p_end > p && p[0] == DUK_ASC_UNDERSCORE) {\n\t\t/* If property key begins with underscore, encode it with\n\t\t * forced quotes (e.g. \"_Foo\") to distinguish it from encoded\n\t\t * internal properties (e.g. \\x82Bar -> _Bar).\n\t\t */\n\t\tquotes = 1;\n\t}\n\n\tif (quotes) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_DOUBLEQUOTE);\n\t}\n\twhile (p < p_end) {\n\t\tduk_uint8_t ch = *p++;\n\n\t\t/* two special escapes: '\\' and '\"', other printables as is */\n\t\tif (ch == '\\\\') {\n\t\t\tduk_fb_sprintf(fb, \"\\\\\\\\\");\n\t\t} else if (ch == '\"') {\n\t\t\tduk_fb_sprintf(fb, \"\\\\\\\"\");\n\t\t} else if (ch >= 0x20 && ch <= 0x7e) {\n\t\t\tduk_fb_put_byte(fb, ch);\n\t\t} else if (ch == 0x82 && !quotes) {\n\t\t\t/* encode \\x82Bar as _Bar if no quotes are\n\t\t\t * applied, this is for readable internal keys.\n\t\t\t */\n\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_UNDERSCORE);\n\t\t} else {\n\t\t\tduk_fb_sprintf(fb, \"\\\\x%02lx\", (unsigned long) ch);\n\t\t}\n\t}\n\tif (quotes) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_DOUBLEQUOTE);\n\t}\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* XXX: limit to quoted strings only, to save keys from being cluttered? */\n\tduk_fb_sprintf(fb, \"/%lu\", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(&h->hdr));\n#endif\n}\n\n#define DUK__COMMA()  do { \\\n\t\tif (first) { \\\n\t\t\tfirst = 0; \\\n\t\t} else { \\\n\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COMMA); \\\n\t\t} \\\n\t} while (0)\n\nDUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\tduk_uint_fast32_t i;\n\tduk_tval *tv;\n\tduk_hstring *key;\n\tduk_bool_t first = 1;\n\tconst char *brace1 = \"{\";\n\tconst char *brace2 = \"}\";\n\tduk_bool_t pushed_loopstack = 0;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tduk__print_shared_heaphdr(st, &h->hdr);\n\n\tif (h && DUK_HOBJECT_HAS_ARRAY_PART(h)) {\n\t\tbrace1 = \"[\";\n\t\tbrace2 = \"]\";\n\t}\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\tgoto finished;\n\t}\n\n\tif (st->depth >= st->depth_limit) {\n\t\tconst char *subtype = \"generic\";\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\t\tsubtype = \"compfunc\";\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\t\tsubtype = \"natfunc\";\n\t\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\t\tsubtype = \"thread\";\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\tsubtype = \"bufobj\";\n\t\t} else if (DUK_HOBJECT_IS_ARRAY(h)) {\n\t\t\tsubtype = \"array\";\n\t\t}\n\t\tduk_fb_sprintf(fb, \"%sobject/%s %p%s\", (const char *) brace1, subtype, (void *) h, (const char *) brace2);\n\t\treturn;\n\t}\n\n\tfor (i = 0; i < (duk_uint_fast32_t) st->loop_stack_index; i++) {\n\t\tif (st->loop_stack[i] == h) {\n\t\t\tduk_fb_sprintf(fb, \"%sLOOP:%p%s\", (const char *) brace1, (void *) h, (const char *) brace2);\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/* after this, return paths should 'goto finished' for decrement */\n\tst->depth++;\n\n\tif (st->loop_stack_index >= st->loop_stack_limit) {\n\t\tduk_fb_sprintf(fb, \"%sOUT-OF-LOOP-STACK%s\", (const char *) brace1, (const char *) brace2);\n\t\tgoto finished;\n\t}\n\tst->loop_stack[st->loop_stack_index++] = h;\n\tpushed_loopstack = 1;\n\n\t/*\n\t *  Notation: double underscore used for internal properties which are not\n\t *  stored in the property allocation (e.g. '__valstack').\n\t */\n\n\tduk_fb_put_cstring(fb, brace1);\n\n\tif (DUK_HOBJECT_GET_PROPS(NULL, h)) {\n\t\tduk_uint32_t a_limit;\n\n\t\ta_limit = DUK_HOBJECT_GET_ASIZE(h);\n\t\tif (st->internal) {\n\t\t\t/* dump all allocated entries, unused entries print as 'unused',\n\t\t\t * note that these may extend beyond current 'length' and look\n\t\t\t * a bit funny.\n\t\t\t */\n\t\t} else {\n\t\t\t/* leave out trailing 'unused' elements */\n\t\t\twhile (a_limit > 0) {\n\t\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(NULL, h, a_limit - 1);\n\t\t\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ta_limit--;\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < a_limit; i++) {\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(NULL, h, i);\n\t\t\tDUK__COMMA();\n\t\t\tduk__print_tval(st, tv);\n\t\t}\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(NULL, h, i);\n\t\t\tif (!key) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!st->internal && DUK_HSTRING_HAS_HIDDEN(key)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tDUK__COMMA();\n\t\t\tduk__print_hstring(st, key, 0);\n\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COLON);\n\t\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(NULL, h, i)) {\n\t\t\t\tduk_fb_sprintf(fb, \"[get:%p,set:%p]\",\n\t\t\t\t               (void *) DUK_HOBJECT_E_GET_VALUE(NULL, h, i).a.get,\n\t\t\t\t               (void *) DUK_HOBJECT_E_GET_VALUE(NULL, h, i).a.set);\n\t\t\t} else {\n\t\t\t\ttv = &DUK_HOBJECT_E_GET_VALUE(NULL, h, i).v;\n\t\t\t\tduk__print_tval(st, tv);\n\t\t\t}\n\t\t\tif (st->heavy) {\n\t\t\t\tduk_fb_sprintf(fb, \"<%02lx>\", (unsigned long) DUK_HOBJECT_E_GET_FLAGS(NULL, h, i));\n\t\t\t}\n\t\t}\n\t}\n\tif (st->internal) {\n\t\tif (DUK_HOBJECT_IS_ARRAY(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__array:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXTENSIBLE(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__extensible:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_CONSTRUCTABLE(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__constructable:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__boundfunc:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_COMPFUNC(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__compfunc:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NATFUNC(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__natfunc:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_BUFOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__bufobj:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_IS_THREAD(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__thread:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_ARRAY_PART(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__array_part:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_STRICT(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__strict:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NOTAIL(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__notail:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NEWENV(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__newenv:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NAMEBINDING(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__namebinding:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_CREATEARGS(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__createargs:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_array:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_stringobj:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_arguments:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_bufobj:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_proxyobj:true\");\n\t\t}\n\t}\n\n\tif (st->internal && DUK_HOBJECT_IS_ARRAY(h)) {\n\t\tduk_harray *a = (duk_harray *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__length:%ld\", (long) a->length);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__length_nonwritable:%ld\", (long) a->length_nonwritable);\n\t} else if (st->internal && DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__data:\");\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(NULL, f));\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__lexenv:\"); duk__print_hobject(st, DUK_HCOMPFUNC_GET_LEXENV(NULL, f));\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__varenv:\"); duk__print_hobject(st, DUK_HCOMPFUNC_GET_VARENV(NULL, f));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__nregs:%ld\", (long) f->nregs);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__nargs:%ld\", (long) f->nargs);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__start_line:%ld\", (long) f->start_line);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__end_line:%ld\", (long) f->end_line);\n#endif\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__data:\");\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(NULL, f));\n\t} else if (st->internal && DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\tduk_hnatfunc *f = (duk_hnatfunc *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__func:\");\n\t\tduk_fb_put_funcptr(fb, (duk_uint8_t *) &f->func, sizeof(f->func));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__nargs:%ld\", (long) f->nargs);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__magic:%ld\", (long) f->magic);\n\t} else if (st->internal && DUK_HOBJECT_IS_DECENV(h)) {\n\t\tduk_hdecenv *e = (duk_hdecenv *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__thread:\"); duk__print_hobject(st, (duk_hobject *) e->thread);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__varmap:\"); duk__print_hobject(st, (duk_hobject *) e->varmap);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__regbase_byteoff:%ld\", (long) e->regbase_byteoff);\n\t} else if (st->internal && DUK_HOBJECT_IS_OBJENV(h)) {\n\t\tduk_hobjenv *e = (duk_hobjenv *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__target:\"); duk__print_hobject(st, (duk_hobject *) e->target);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__has_this:%ld\", (long) e->has_this);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t} else if (st->internal && DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\tduk_hbufobj *b = (duk_hbufobj *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__buf:\");\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) b->buf);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__buf_prop:\");\n\t\tduk__print_hobject(st, (duk_hobject *) b->buf_prop);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__offset:%ld\", (long) b->offset);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__length:%ld\", (long) b->length);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__shift:%ld\", (long) b->shift);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__elemtype:%ld\", (long) b->elem_type);\n#endif\n\t} else if (st->internal && DUK_HOBJECT_IS_PROXY(h)) {\n\t\tduk_hproxy *p = (duk_hproxy *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__target:\");\n\t\tduk__print_hobject(st, p->target);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__handler:\");\n\t\tduk__print_hobject(st, p->handler);\n\t} else if (st->internal && DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__ptr_curr_pc:%p\", (void *) t->ptr_curr_pc);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__heap:%p\", (void *) t->heap);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__strict:%ld\", (long) t->strict);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__state:%ld\", (long) t->state);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__unused1:%ld\", (long) t->unused1);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__unused2:%ld\", (long) t->unused2);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack:%p\", (void *) t->valstack);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_end:%p/%ld\", (void *) t->valstack_end, (long) (t->valstack_end - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_alloc_end:%p/%ld\", (void *) t->valstack_alloc_end, (long) (t->valstack_alloc_end - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_bottom:%p/%ld\", (void *) t->valstack_bottom, (long) (t->valstack_bottom - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_top:%p/%ld\", (void *) t->valstack_top, (long) (t->valstack_top - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__callstack_curr:%p\", (void *) t->callstack_curr);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__callstack_top:%ld\", (long) t->callstack_top);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__callstack_preventcount:%ld\", (long) t->callstack_preventcount);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__resumer:\"); duk__print_hobject(st, (duk_hobject *) t->resumer);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__compile_ctx:%p\", (void *) t->compile_ctx);\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__interrupt_counter:%ld\", (long) t->interrupt_counter);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__interrupt_init:%ld\", (long) t->interrupt_init);\n#endif\n\n\t\t/* XXX: print built-ins array? */\n\n\t}\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tif (st->internal) {\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__refcount:%lu\", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h));\n\t}\n#endif\n\tif (st->internal) {\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__class:%ld\", (long) DUK_HOBJECT_GET_CLASS_NUMBER(h));\n\t}\n\n\tDUK__COMMA(); duk_fb_sprintf(fb, \"__heapptr:%p\", (void *) h);  /* own pointer */\n\n\t/* prototype should be last, for readability */\n\tif (DUK_HOBJECT_GET_PROTOTYPE(NULL, h)) {\n\t\tif (st->follow_proto) {\n\t\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__prototype:\"); duk__print_hobject(st, DUK_HOBJECT_GET_PROTOTYPE(NULL, h));\n\t\t} else {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__prototype:%p\", (void *) DUK_HOBJECT_GET_PROTOTYPE(NULL, h));\n\t\t}\n\t}\n\n\tduk_fb_put_cstring(fb, brace2);\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (st->heavy && DUK_HOBJECT_GET_HSIZE(h) > 0) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LANGLE);\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_HSIZE(h); i++) {\n\t\t\tduk_uint_t h_idx = DUK_HOBJECT_H_GET_INDEX(NULL, h, i);\n\t\t\tif (i > 0) {\n\t\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COMMA);\n\t\t\t}\n\t\t\tif (h_idx == DUK_HOBJECT_HASHIDX_UNUSED) {\n\t\t\t\tduk_fb_sprintf(fb, \"u\");\n\t\t\t} else if (h_idx == DUK_HOBJECT_HASHIDX_DELETED) {\n\t\t\t\tduk_fb_sprintf(fb, \"d\");\n\t\t\t} else {\n\t\t\t\tduk_fb_sprintf(fb, \"%ld\", (long) h_idx);\n\t\t\t}\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RANGLE);\n\t}\n#endif\n\n finished:\n\tst->depth--;\n\tif (pushed_loopstack) {\n\t\tst->loop_stack_index--;\n\t\tst->loop_stack[st->loop_stack_index] = NULL;\n\t}\n}\n\nDUK_LOCAL void duk__print_hbuffer(duk__dprint_state *st, duk_hbuffer *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\tduk_size_t i, n;\n\tduk_uint8_t *p;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\t/* terminal type: no depth check */\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tif (DUK_HBUFFER_HAS_DYNAMIC(h)) {\n\t\tif (DUK_HBUFFER_HAS_EXTERNAL(h)) {\n\t\t\tduk_hbuffer_external *g = (duk_hbuffer_external *) h;\n\t\t\tduk_fb_sprintf(fb, \"buffer:external:%p:%ld\",\n\t\t\t               (void *) DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(NULL, g),\n\t\t\t               (long) DUK_HBUFFER_EXTERNAL_GET_SIZE(g));\n\t\t} else {\n\t\t\tduk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h;\n\t\t\tduk_fb_sprintf(fb, \"buffer:dynamic:%p:%ld\",\n\t\t\t               (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(NULL, g),\n\t\t\t               (long) DUK_HBUFFER_DYNAMIC_GET_SIZE(g));\n\t\t}\n\t} else {\n\t\tduk_fb_sprintf(fb, \"buffer:fixed:%ld\", (long) DUK_HBUFFER_GET_SIZE(h));\n\t}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_fb_sprintf(fb, \"/%lu\", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(&h->hdr));\n#endif\n\n\tif (st->hexdump) {\n\t\tduk_fb_sprintf(fb, \"=[\");\n\t\tn = DUK_HBUFFER_GET_SIZE(h);\n\t\tp = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(NULL, h);\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) p[i]);\n\t\t}\n\t\tduk_fb_sprintf(fb, \"]\");\n\t}\n}\n\nDUK_LOCAL void duk__print_heaphdr(duk__dprint_state *st, duk_heaphdr *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING:\n\t\tduk__print_hstring(st, (duk_hstring *) h, 1);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tduk__print_hobject(st, (duk_hobject *) h);\n\t\tbreak;\n\tcase DUK_HTYPE_BUFFER:\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) h);\n\t\tbreak;\n\tdefault:\n\t\tduk_fb_sprintf(fb, \"[unknown htype %ld]\", (long) DUK_HEAPHDR_GET_TYPE(h));\n\t\tbreak;\n\t}\n}\n\nDUK_LOCAL void duk__print_tval(duk__dprint_state *st, duk_tval *tv) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\t/* depth check is done when printing an actual type */\n\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"(%p)\", (void *) tv);\n\t}\n\n\tif (!tv) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tif (st->binary) {\n\t\tduk_size_t i;\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET);\n\t\tfor (i = 0; i < (duk_size_t) sizeof(*tv); i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) ((duk_uint8_t *)tv)[i]);\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET);\n\t}\n\n\tif (st->heavy) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LANGLE);\n\t}\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\tduk_fb_put_cstring(fb, \"undefined\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_UNUSED: {\n\t\tduk_fb_put_cstring(fb, \"unused\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tduk_fb_put_cstring(fb, \"null\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tduk_fb_put_cstring(fb, DUK_TVAL_GET_BOOLEAN(tv) ? \"true\" : \"false\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\t/* Note: string is a terminal heap object, so no depth check here */\n\t\tduk__print_hstring(st, DUK_TVAL_GET_STRING(tv), 1);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk__print_hobject(st, DUK_TVAL_GET_OBJECT(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\tduk__print_hbuffer(st, DUK_TVAL_GET_BUFFER(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tduk_fb_sprintf(fb, \"pointer:%p\", (void *) DUK_TVAL_GET_POINTER(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tduk_c_function func;\n\t\tduk_small_uint_t lf_flags;\n\n\t\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);\n\t\tduk_fb_sprintf(fb, \"lightfunc:\");\n\t\tduk_fb_put_funcptr(fb, (duk_uint8_t *) &func, sizeof(func));\n\t\tduk_fb_sprintf(fb, \":%04lx\", (long) lf_flags);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tduk_fb_sprintf(fb, \"%.18g_F\", (double) DUK_TVAL_GET_NUMBER(tv));\n\t\tbreak;\n#endif\n\tdefault: {\n\t\t/* IEEE double is approximately 16 decimal digits; print a couple extra */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tduk_fb_sprintf(fb, \"%.18g\", (double) DUK_TVAL_GET_NUMBER(tv));\n\t\tbreak;\n\t}\n\t}\n\tif (st->heavy) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RANGLE);\n\t}\n}\n\nDUK_LOCAL void duk__print_instr(duk__dprint_state *st, duk_instr_t ins) {\n\tduk_fixedbuffer *fb = st->fb;\n\tduk_small_int_t op;\n\tconst char *op_name;\n\n\top = (duk_small_int_t) DUK_DEC_OP(ins);\n\top_name = duk__bc_optab[op];\n\n\t/* XXX: option to fix opcode length so it lines up nicely */\n\n\tif (op == DUK_OP_JUMP) {\n\t\tduk_int_t diff1 = (duk_int_t) (DUK_DEC_ABC(ins) - DUK_BC_JUMP_BIAS);  /* from next pc */\n\t\tduk_int_t diff2 = diff1 + 1;                                          /* from curr pc */\n\n\t\tduk_fb_sprintf(fb, \"%s %ld (to pc%c%ld)\",\n\t\t               (const char *) op_name, (long) diff1,\n\t\t               (int) (diff2 >= 0 ? '+' : '-'),  /* char format: use int */\n\t\t               (long) (diff2 >= 0 ? diff2 : -diff2));\n\t} else {\n\t\tduk_fb_sprintf(fb, \"%s %ld, %ld, %ld\",\n\t\t               (const char *) op_name, (long) DUK_DEC_A(ins),\n\t\t               (long) DUK_DEC_B(ins), (long) DUK_DEC_C(ins));\n\t}\n}\n\nDUK_LOCAL void duk__print_opcode(duk__dprint_state *st, duk_small_int_t opcode) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (opcode < DUK_BC_OP_MIN || opcode > DUK_BC_OP_MAX) {\n\t\tduk_fb_sprintf(fb, \"?(%ld)\", (long) opcode);\n\t} else {\n\t\tduk_fb_sprintf(fb, \"%s\", (const char *) duk__bc_optab[opcode]);\n\t}\n}\n\nDUK_LOCAL void duk__print_catcher(duk__dprint_state *st, duk_catcher *cat) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tif (!cat) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tduk_fb_sprintf(fb, \"[catcher ptr=%p parent=%p varname=%p pc_base=%p, idx_base=%ld, flags=0x%08lx]\",\n\t               (void *) cat,\n\t               (void *) cat->parent, (void *) cat->h_varname, (void *) cat->pc_base,\n\t\t       (long) cat->idx_base, (unsigned long) cat->flags);\n}\n\n\nDUK_LOCAL void duk__print_activation(duk__dprint_state *st, duk_activation *act) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tif (!act) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\t/* prev_caller: conditional, omitted on purpose, it's rarely used. */\n\t/* prev_line: conditional, omitted on purpose (but would be nice). */\n\tduk_fb_sprintf(fb, \"[activation ptr=%p tv_func=<omit> func=%p parent=%p var_env=%p lex_env=%p cat=%p curr_pc=%p bottom_byteoff=%ld retval_byteoff=%ld reserve_byteoff=%ld flags=%ld]\",\n\t               (void *) act,\n\t               (void *) act->func, (void *) act->parent, (void *) act->var_env,\n\t\t       (void *) act->lex_env, (void *) act->cat, (void *) act->curr_pc,\n\t\t       (long) act->bottom_byteoff, (long) act->retval_byteoff, (long) act->reserve_byteoff,\n\t\t       (long) act->flags);\n}\n\nDUK_INTERNAL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const char *format, va_list ap) {\n\tduk_fixedbuffer fb;\n\tconst char *p = format;\n\tconst char *p_end = p + DUK_STRLEN(format);\n\tduk_int_t retval;\n\n\tduk_memzero(&fb, sizeof(fb));\n\tfb.buffer = (duk_uint8_t *) str;\n\tfb.length = size;\n\tfb.offset = 0;\n\tfb.truncated = 0;\n\n\twhile (p < p_end) {\n\t\tchar ch = *p++;\n\t\tconst char *p_begfmt = NULL;\n\t\tduk_bool_t got_exclamation = 0;\n\t\tduk_bool_t got_long = 0;  /* %lf, %ld etc */\n\t\tduk__dprint_state st;\n\n\t\tif (ch != DUK_ASC_PERCENT) {\n\t\t\tduk_fb_put_byte(&fb, (duk_uint8_t) ch);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/*\n\t\t *  Format tag parsing.  Since we don't understand all the\n\t\t *  possible format tags allowed, we just scan for a terminating\n\t\t *  specifier and keep track of relevant modifiers that we do\n\t\t *  understand.  See man 3 printf.\n\t\t */\n\n\t\tduk_memzero(&st, sizeof(st));\n\t\tst.fb = &fb;\n\t\tst.depth = 0;\n\t\tst.depth_limit = 1;\n\t\tst.loop_stack_index = 0;\n\t\tst.loop_stack_limit = DUK__LOOP_STACK_DEPTH;\n\n\t\tp_begfmt = p - 1;\n\t\twhile (p < p_end) {\n\t\t\tch = *p++;\n\n\t\t\tif (ch == DUK_ASC_STAR) {\n\t\t\t\t/* unsupported: would consume multiple args */\n\t\t\t\tgoto format_error;\n\t\t\t} else if (ch == DUK_ASC_PERCENT) {\n\t\t\t\tduk_fb_put_byte(&fb, (duk_uint8_t) DUK_ASC_PERCENT);\n\t\t\t\tbreak;\n\t\t\t} else if (ch == DUK_ASC_EXCLAMATION) {\n\t\t\t\tgot_exclamation = 1;\n\t\t\t} else if (!got_exclamation && ch == DUK_ASC_LC_L) {\n\t\t\t\tgot_long = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_D) {\n\t\t\t\tst.depth_limit = DUK__DEEP_DEPTH_LIMIT;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_P) {\n\t\t\t\tst.follow_proto = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_I) {\n\t\t\t\tst.internal = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_X) {\n\t\t\t\tst.hexdump = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_H) {\n\t\t\t\tst.heavy = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_ATSIGN) {\n\t\t\t\tst.pointer = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_HASH) {\n\t\t\t\tst.binary = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_T) {\n\t\t\t\tduk_tval *t = va_arg(ap, duk_tval *);\n\t\t\t\tif (st.pointer && !st.heavy) {\n\t\t\t\t\tduk_fb_sprintf(&fb, \"(%p)\", (void *) t);\n\t\t\t\t}\n\t\t\t\tduk__print_tval(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_O) {\n\t\t\t\tduk_heaphdr *t = va_arg(ap, duk_heaphdr *);\n\t\t\t\tif (st.pointer && !st.heavy) {\n\t\t\t\t\tduk_fb_sprintf(&fb, \"(%p)\", (void *) t);\n\t\t\t\t}\n\t\t\t\tduk__print_heaphdr(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_I) {\n\t\t\t\tduk_instr_t t = va_arg(ap, duk_instr_t);\n\t\t\t\tduk__print_instr(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_X) {\n\t\t\t\tlong t = va_arg(ap, long);\n\t\t\t\tduk__print_opcode(&st, (duk_small_int_t) t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_C) {\n\t\t\t\tduk_catcher *t = va_arg(ap, duk_catcher *);\n\t\t\t\tduk__print_catcher(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_A) {\n\t\t\t\tduk_activation *t = va_arg(ap, duk_activation *);\n\t\t\t\tduk__print_activation(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (!got_exclamation && strchr(DUK__ALLOWED_STANDARD_SPECIFIERS, (int) ch)) {\n\t\t\t\tchar fmtbuf[DUK__MAX_FORMAT_TAG_LENGTH];\n\t\t\t\tduk_size_t fmtlen;\n\n\t\t\t\tDUK_ASSERT(p >= p_begfmt);\n\t\t\t\tfmtlen = (duk_size_t) (p - p_begfmt);\n\t\t\t\tif (fmtlen >= sizeof(fmtbuf)) {\n\t\t\t\t\t/* format is too large, abort */\n\t\t\t\t\tgoto format_error;\n\t\t\t\t}\n\t\t\t\tduk_memzero(fmtbuf, sizeof(fmtbuf));\n\t\t\t\tduk_memcpy(fmtbuf, p_begfmt, fmtlen);\n\n\t\t\t\t/* assume exactly 1 arg, which is why '*' is forbidden; arg size still\n\t\t\t\t * depends on type though.\n\t\t\t\t */\n\n\t\t\t\tif (ch == DUK_ASC_LC_F || ch == DUK_ASC_LC_G || ch == DUK_ASC_LC_E) {\n\t\t\t\t\t/* %f and %lf both consume a 'long' */\n\t\t\t\t\tdouble arg = va_arg(ap, double);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_D && got_long) {\n\t\t\t\t\t/* %ld */\n\t\t\t\t\tlong arg = va_arg(ap, long);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_D) {\n\t\t\t\t\t/* %d; only 16 bits are guaranteed */\n\t\t\t\t\tint arg = va_arg(ap, int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_U && got_long) {\n\t\t\t\t\t/* %lu */\n\t\t\t\t\tunsigned long arg = va_arg(ap, unsigned long);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_U) {\n\t\t\t\t\t/* %u; only 16 bits are guaranteed */\n\t\t\t\t\tunsigned int arg = va_arg(ap, unsigned int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_X && got_long) {\n\t\t\t\t\t/* %lx */\n\t\t\t\t\tunsigned long arg = va_arg(ap, unsigned long);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_X) {\n\t\t\t\t\t/* %x; only 16 bits are guaranteed */\n\t\t\t\t\tunsigned int arg = va_arg(ap, unsigned int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_S) {\n\t\t\t\t\t/* %s */\n\t\t\t\t\tconst char *arg = va_arg(ap, const char *);\n\t\t\t\t\tif (arg == NULL) {\n\t\t\t\t\t\t/* '%s' and NULL is not portable, so special case\n\t\t\t\t\t\t * it for debug printing.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk_fb_sprintf(&fb, \"NULL\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t\t}\n\t\t\t\t} else if (ch == DUK_ASC_LC_P) {\n\t\t\t\t\t/* %p */\n\t\t\t\t\tvoid *arg = va_arg(ap, void *);\n\t\t\t\t\tif (arg == NULL) {\n\t\t\t\t\t\t/* '%p' and NULL is portable, but special case it\n\t\t\t\t\t\t * anyway to get a standard NULL marker in logs.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk_fb_sprintf(&fb, \"NULL\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t\t}\n\t\t\t\t} else if (ch == DUK_ASC_LC_C) {\n\t\t\t\t\t/* '%c', passed concretely as int */\n\t\t\t\t\tint arg = va_arg(ap, int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else {\n\t\t\t\t\t/* Should not happen. */\n\t\t\t\t\tduk_fb_sprintf(&fb, \"INVALID-FORMAT(%s)\", (const char *) fmtbuf);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t/* ignore */\n\t\t\t}\n\t\t}\n\t}\n\tgoto done;\n\n format_error:\n\tduk_fb_put_cstring(&fb, \"FMTERR\");\n\t/* fall through */\n\n done:\n\tretval = (duk_int_t) fb.offset;\n\tduk_fb_put_byte(&fb, (duk_uint8_t) 0);\n\n\t/* return total chars written excluding terminator */\n\treturn retval;\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL duk_int_t duk_debug_snprintf(char *str, duk_size_t size, const char *format, ...) {\n\tduk_int_t retval;\n\tva_list ap;\n\tva_start(ap, format);\n\tretval = duk_debug_vsnprintf(str, size, format, ap);\n\tva_end(ap);\n\treturn retval;\n}\n#endif\n\n/* Formatting function pointers is tricky: there is no standard pointer for\n * function pointers and the size of a function pointer may depend on the\n * specific pointer type.  This helper formats a function pointer based on\n * its memory layout to get something useful on most platforms.\n */\nDUK_INTERNAL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_uint8_t *fptr, duk_size_t fptr_size) {\n\tduk_size_t i;\n\tduk_uint8_t *p = (duk_uint8_t *) buf;\n\tduk_uint8_t *p_end = (duk_uint8_t *) (buf + buf_size - 1);\n\n\tDUK_ASSERT(buf != NULL);\n\tduk_memzero(buf, buf_size);\n\n\tfor (i = 0; i < fptr_size; i++) {\n\t\tduk_int_t left = (duk_int_t) (p_end - p);\n\t\tduk_uint8_t ch;\n\t\tif (left <= 0) {\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Quite approximate but should be useful for little and big endian. */\n#if defined(DUK_USE_INTEGER_BE)\n\t\tch = fptr[i];\n#else\n\t\tch = fptr[fptr_size - 1 - i];\n#endif\n\t\tp += DUK_SNPRINTF((char *) p, (duk_size_t) left, \"%02lx\", (unsigned long) ch);\n\t}\n}\n\n#endif  /* DUK_USE_DEBUG */\n\n/* automatic undefs */\n#undef DUK__ALLOWED_STANDARD_SPECIFIERS\n#undef DUK__COMMA\n#undef DUK__DEEP_DEPTH_LIMIT\n#undef DUK__LOOP_STACK_DEPTH\n#undef DUK__MAX_FORMAT_TAG_LENGTH\n#line 1 \"duk_debugger.c\"\n/*\n *  Duktape debugger\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\n/*\n *  Assert helpers\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n#define DUK__DBG_TPORT_ENTER() do { \\\n\t\tDUK_ASSERT(heap->dbg_calling_transport == 0); \\\n\t\theap->dbg_calling_transport = 1; \\\n\t} while (0)\n#define DUK__DBG_TPORT_EXIT() do { \\\n\t\tDUK_ASSERT(heap->dbg_calling_transport == 1); \\\n\t\theap->dbg_calling_transport = 0; \\\n\t} while (0)\n#else\n#define DUK__DBG_TPORT_ENTER() do {} while (0)\n#define DUK__DBG_TPORT_EXIT() do {} while (0)\n#endif\n\n/*\n *  Helper structs\n */\n\ntypedef union {\n\tvoid *p;\n\tduk_uint_t b[1];\n\t/* Use b[] to access the size of the union, which is strictly not\n\t * correct.  Can't use fixed size unless there's feature detection\n\t * for pointer byte size.\n\t */\n} duk__ptr_union;\n\n/*\n *  Detach handling\n */\n\n#define DUK__SET_CONN_BROKEN(thr,reason) do { \\\n\t\t/* For now shared handler is fine. */ \\\n\t\tduk__debug_do_detach1((thr)->heap, (reason)); \\\n\t} while (0)\n\nDUK_LOCAL void duk__debug_do_detach1(duk_heap *heap, duk_int_t reason) {\n\t/* Can be called multiple times with no harm.  Mark the transport\n\t * bad (dbg_read_cb == NULL) and clear state except for the detached\n\t * callback and the udata field.  The detached callback is delayed\n\t * to the message loop so that it can be called between messages;\n\t * this avoids corner cases related to immediate debugger reattach\n\t * inside the detached callback.\n\t */\n\n\tif (heap->dbg_detaching) {\n\t\tDUK_D(DUK_DPRINT(\"debugger already detaching, ignore detach1\"));\n\t\treturn;\n\t}\n\n\tDUK_D(DUK_DPRINT(\"debugger transport detaching, marking transport broken\"));\n\n\theap->dbg_detaching = 1;  /* prevent multiple in-progress detaches */\n\n\tif (heap->dbg_write_cb != NULL) {\n\t\tduk_hthread *thr;\n\n\t\tthr = heap->heap_thread;\n\t\tDUK_ASSERT(thr != NULL);\n\n\t\tduk_debug_write_notify(thr, DUK_DBG_CMD_DETACHING);\n\t\tduk_debug_write_int(thr, reason);\n\t\tduk_debug_write_eom(thr);\n\t}\n\n\theap->dbg_read_cb = NULL;\n\theap->dbg_write_cb = NULL;\n\theap->dbg_peek_cb = NULL;\n\theap->dbg_read_flush_cb = NULL;\n\theap->dbg_write_flush_cb = NULL;\n\theap->dbg_request_cb = NULL;\n\t/* heap->dbg_detached_cb: keep */\n\t/* heap->dbg_udata: keep */\n\t/* heap->dbg_processing: keep on purpose to avoid debugger re-entry in detaching state */\n\theap->dbg_state_dirty = 0;\n\theap->dbg_force_restart = 0;\n\theap->dbg_pause_flags = 0;\n\theap->dbg_pause_act = NULL;\n\theap->dbg_pause_startline = 0;\n\theap->dbg_have_next_byte = 0;\n\tduk_debug_clear_paused(heap);  /* XXX: some overlap with field inits above */\n\theap->dbg_state_dirty = 0;     /* XXX: clear_paused sets dirty; rework? */\n\n\t/* Ensure there are no stale active breakpoint pointers.\n\t * Breakpoint list is currently kept - we could empty it\n\t * here but we'd need to handle refcounts correctly, and\n\t * we'd need a 'thr' reference for that.\n\t *\n\t * XXX: clear breakpoint on either attach or detach?\n\t */\n\theap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;\n}\n\nDUK_LOCAL void duk__debug_do_detach2(duk_heap *heap) {\n\tduk_debug_detached_function detached_cb;\n\tvoid *detached_udata;\n\tduk_hthread *thr;\n\n\tthr = heap->heap_thread;\n\tif (thr == NULL) {\n\t\tDUK_ASSERT(heap->dbg_detached_cb == NULL);\n\t\treturn;\n\t}\n\n\t/* Safe to call multiple times. */\n\n\tdetached_cb = heap->dbg_detached_cb;\n\tdetached_udata = heap->dbg_udata;\n\theap->dbg_detached_cb = NULL;\n\theap->dbg_udata = NULL;\n\n\tif (detached_cb) {\n\t\t/* Careful here: state must be wiped before the call\n\t\t * so that we can cleanly handle a re-attach from\n\t\t * inside the callback.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"detached during message loop, delayed call to detached_cb\"));\n\t\tdetached_cb(thr, detached_udata);\n\t}\n\n\theap->dbg_detaching = 0;\n}\n\nDUK_INTERNAL void duk_debug_do_detach(duk_heap *heap) {\n\tduk__debug_do_detach1(heap, 0);\n\tduk__debug_do_detach2(heap);\n}\n\n/* Called on a read/write error: NULL all callbacks except the detached\n * callback so that we never accidentally call them after a read/write\n * error has been indicated.  This is especially important for the transport\n * I/O callbacks to fulfill guaranteed callback semantics.\n */\nDUK_LOCAL void duk__debug_null_most_callbacks(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\n\theap = thr->heap;\n\tDUK_D(DUK_DPRINT(\"transport read/write error, NULL all callbacks expected detached\"));\n\theap->dbg_read_cb = NULL;\n\theap->dbg_write_cb = NULL;  /* this is especially critical to avoid another write call in detach1() */\n\theap->dbg_peek_cb = NULL;\n\theap->dbg_read_flush_cb = NULL;\n\theap->dbg_write_flush_cb = NULL;\n\theap->dbg_request_cb = NULL;\n\t/* keep heap->dbg_detached_cb */\n}\n\n/*\n *  Pause handling\n */\n\nDUK_LOCAL void duk__debug_set_pause_state(duk_hthread *thr, duk_heap *heap, duk_small_uint_t pause_flags) {\n\tduk_uint_fast32_t line;\n\n\tline = duk_debug_curr_line(thr);\n\tif (line == 0) {\n\t\t/* No line info for current function. */\n\t\tduk_small_uint_t updated_flags;\n\n\t\tupdated_flags = pause_flags & ~(DUK_PAUSE_FLAG_LINE_CHANGE);\n\t\tDUK_D(DUK_DPRINT(\"no line info for current activation, disable line-based pause flags: 0x%08lx -> 0x%08lx\",\n\t\t                 (long) pause_flags, (long) updated_flags));\n\t\tpause_flags = updated_flags;\n\t}\n\n\theap->dbg_pause_flags = pause_flags;\n\theap->dbg_pause_act = thr->callstack_curr;\n\theap->dbg_pause_startline = (duk_uint32_t) line;\n\theap->dbg_state_dirty = 1;\n\n\tDUK_D(DUK_DPRINT(\"set state for automatic pause triggers, flags=0x%08lx, act=%p, startline=%ld\",\n\t                 (long) heap->dbg_pause_flags, (void *) heap->dbg_pause_act,\n\t                 (long) heap->dbg_pause_startline));\n}\n\n/*\n *  Debug connection peek and flush primitives\n */\n\nDUK_INTERNAL duk_bool_t duk_debug_read_peek(duk_hthread *thr) {\n\tduk_heap *heap;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to peek in detached state, return zero (= no data)\"));\n\t\treturn 0;\n\t}\n\tif (heap->dbg_peek_cb == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"no peek callback, return zero (= no data)\"));\n\t\treturn 0;\n\t}\n\n\tDUK__DBG_TPORT_ENTER();\n\tret = (duk_bool_t) (heap->dbg_peek_cb(heap->dbg_udata) > 0);\n\tDUK__DBG_TPORT_EXIT();\n\treturn ret;\n}\n\nDUK_INTERNAL void duk_debug_read_flush(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to read flush in detached state, ignore\"));\n\t\treturn;\n\t}\n\tif (heap->dbg_read_flush_cb == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"no read flush callback, ignore\"));\n\t\treturn;\n\t}\n\n\tDUK__DBG_TPORT_ENTER();\n\theap->dbg_read_flush_cb(heap->dbg_udata);\n\tDUK__DBG_TPORT_EXIT();\n}\n\nDUK_INTERNAL void duk_debug_write_flush(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to write flush in detached state, ignore\"));\n\t\treturn;\n\t}\n\tif (heap->dbg_write_flush_cb == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"no write flush callback, ignore\"));\n\t\treturn;\n\t}\n\n\tDUK__DBG_TPORT_ENTER();\n\theap->dbg_write_flush_cb(heap->dbg_udata);\n\tDUK__DBG_TPORT_EXIT();\n}\n\n/*\n *  Debug connection skip primitives\n */\n\n/* Skip fully. */\nDUK_INTERNAL void duk_debug_skip_bytes(duk_hthread *thr, duk_size_t length) {\n\tduk_uint8_t dummy[64];\n\tduk_size_t now;\n\n\tDUK_ASSERT(thr != NULL);\n\n\twhile (length > 0) {\n\t\tnow = (length > sizeof(dummy) ? sizeof(dummy) : length);\n\t\tduk_debug_read_bytes(thr, dummy, now);\n\t\tlength -= now;\n\t}\n}\n\nDUK_INTERNAL void duk_debug_skip_byte(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\t(void) duk_debug_read_byte(thr);\n}\n\n/*\n *  Debug connection read primitives\n */\n\n/* Peek ahead in the stream one byte. */\nDUK_INTERNAL uint8_t duk_debug_peek_byte(duk_hthread *thr) {\n\t/* It is important not to call this if the last byte read was an EOM.\n\t * Reading ahead in this scenario would cause unnecessary blocking if\n\t * another message is not available.\n\t */\n\n\tduk_uint8_t x;\n\n\tx = duk_debug_read_byte(thr);\n\tthr->heap->dbg_have_next_byte = 1;\n\tthr->heap->dbg_next_byte = x;\n\treturn x;\n}\n\n/* Read fully. */\nDUK_INTERNAL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_size_t length) {\n\tduk_heap *heap;\n\tduk_uint8_t *p;\n\tduk_size_t left;\n\tduk_size_t got;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(data != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to read %ld bytes in detached state, return zero data\", (long) length));\n\t\tgoto fail;\n\t}\n\n\t/* NOTE: length may be zero */\n\tp = data;\n\tif (length >= 1 && heap->dbg_have_next_byte) {\n\t\theap->dbg_have_next_byte = 0;\n\t\t*p++ = heap->dbg_next_byte;\n\t}\n\tfor (;;) {\n\t\tleft = (duk_size_t) ((data + length) - p);\n\t\tif (left == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tDUK_ASSERT(heap->dbg_read_cb != NULL);\n\t\tDUK_ASSERT(left >= 1);\n#if defined(DUK_USE_DEBUGGER_TRANSPORT_TORTURE)\n\t\tleft = 1;\n#endif\n\t\tDUK__DBG_TPORT_ENTER();\n\t\tgot = heap->dbg_read_cb(heap->dbg_udata, (char *) p, left);\n\t\tDUK__DBG_TPORT_EXIT();\n\n\t\tif (got == 0 || got > left) {\n\t\t\tDUK_D(DUK_DPRINT(\"connection error during read, return zero data\"));\n\t\t\tduk__debug_null_most_callbacks(thr);  /* avoid calling write callback in detach1() */\n\t\t\tDUK__SET_CONN_BROKEN(thr, 1);\n\t\t\tgoto fail;\n\t\t}\n\t\tp += got;\n\t}\n\treturn;\n\n fail:\n\tduk_memzero((void *) data, (size_t) length);\n}\n\nDUK_INTERNAL duk_uint8_t duk_debug_read_byte(duk_hthread *thr) {\n\tduk_uint8_t x;\n\n\tx = 0;  /* just in case callback is broken and won't write 'x' */\n\tduk_debug_read_bytes(thr, &x, 1);\n\treturn x;\n}\n\nDUK_LOCAL duk_uint32_t duk__debug_read_uint32_raw(duk_hthread *thr) {\n\tduk_uint8_t buf[4];\n\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_read_bytes(thr, buf, 4);\n\treturn ((duk_uint32_t) buf[0] << 24) |\n\t       ((duk_uint32_t) buf[1] << 16) |\n\t       ((duk_uint32_t) buf[2] << 8) |\n\t       (duk_uint32_t) buf[3];\n}\n\nDUK_LOCAL duk_int32_t duk__debug_read_int32_raw(duk_hthread *thr) {\n\treturn (duk_int32_t) duk__debug_read_uint32_raw(thr);\n}\n\nDUK_LOCAL duk_uint16_t duk__debug_read_uint16_raw(duk_hthread *thr) {\n\tduk_uint8_t buf[2];\n\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_read_bytes(thr, buf, 2);\n\treturn ((duk_uint16_t) buf[0] << 8) |\n\t       (duk_uint16_t) buf[1];\n}\n\nDUK_INTERNAL duk_int32_t duk_debug_read_int(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\tduk_small_uint_t t;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x >= 0xc0) {\n\t\tt = duk_debug_read_byte(thr);\n\t\treturn (duk_int32_t) (((x - 0xc0) << 8) + t);\n\t} else if (x >= 0x80) {\n\t\treturn (duk_int32_t) (x - 0x80);\n\t} else if (x == DUK_DBG_IB_INT4) {\n\t\treturn (duk_int32_t) duk__debug_read_uint32_raw(thr);\n\t}\n\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode int\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn 0;\n}\n\nDUK_LOCAL duk_hstring *duk__debug_read_hstring_raw(duk_hthread *thr, duk_uint32_t len) {\n\tduk_uint8_t buf[31];\n\tduk_uint8_t *p;\n\n\tif (len <= sizeof(buf)) {\n\t\tduk_debug_read_bytes(thr, buf, (duk_size_t) len);\n\t\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) len);\n\t} else {\n\t\tp = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len);  /* zero for paranoia */\n\t\tDUK_ASSERT(p != NULL);\n\t\tduk_debug_read_bytes(thr, p, (duk_size_t) len);\n\t\t(void) duk_buffer_to_string(thr, -1);  /* Safety relies on debug client, which is OK. */\n\t}\n\n\treturn duk_require_hstring(thr, -1);\n}\n\nDUK_INTERNAL duk_hstring *duk_debug_read_hstring(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\tduk_uint32_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x >= 0x60 && x <= 0x7f) {\n\t\t/* For short strings, use a fixed temp buffer. */\n\t\tlen = (duk_uint32_t) (x - 0x60);\n\t} else if (x == DUK_DBG_IB_STR2) {\n\t\tlen = (duk_uint32_t) duk__debug_read_uint16_raw(thr);\n\t} else if (x == DUK_DBG_IB_STR4) {\n\t\tlen = (duk_uint32_t) duk__debug_read_uint32_raw(thr);\n\t} else {\n\t\tgoto fail;\n\t}\n\n\treturn duk__debug_read_hstring_raw(thr, len);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode int\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\tduk_push_hstring_empty(thr);  /* always push some string */\n\treturn duk_require_hstring(thr, -1);\n}\n\nDUK_LOCAL duk_hbuffer *duk__debug_read_hbuffer_raw(duk_hthread *thr, duk_uint32_t len) {\n\tduk_uint8_t *p;\n\n\tp = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len);  /* zero for paranoia */\n\tDUK_ASSERT(p != NULL);\n\tduk_debug_read_bytes(thr, p, (duk_size_t) len);\n\n\treturn duk_require_hbuffer(thr, -1);\n}\n\nDUK_LOCAL void *duk__debug_read_pointer_raw(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\tduk__ptr_union pu;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x != sizeof(pu)) {\n\t\tgoto fail;\n\t}\n\tduk_debug_read_bytes(thr, (duk_uint8_t *) &pu.p, sizeof(pu));\n#if defined(DUK_USE_INTEGER_LE)\n\tduk_byteswap_bytes((duk_uint8_t *) pu.b, sizeof(pu));\n#endif\n\treturn (void *) pu.p;\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode pointer\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn (void *) NULL;\n}\n\nDUK_LOCAL duk_double_t duk__debug_read_double_raw(duk_hthread *thr) {\n\tduk_double_union du;\n\n\tDUK_ASSERT(sizeof(du.uc) == 8);\n\tduk_debug_read_bytes(thr, (duk_uint8_t *) du.uc, sizeof(du.uc));\n\tDUK_DBLUNION_DOUBLE_NTOH(&du);\n\treturn du.d;\n}\n\n#if 0\nDUK_INTERNAL duk_heaphdr *duk_debug_read_heapptr(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x != DUK_DBG_IB_HEAPPTR) {\n\t\tgoto fail;\n\t}\n\n\treturn (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode heapptr\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn NULL;\n}\n#endif\n\nDUK_INTERNAL duk_heaphdr *duk_debug_read_any_ptr(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tswitch (x) {\n\tcase DUK_DBG_IB_OBJECT:\n\tcase DUK_DBG_IB_POINTER:\n\tcase DUK_DBG_IB_HEAPPTR:\n\t\t/* Accept any pointer-like value; for 'object' dvalue, read\n\t\t * and ignore the class number.\n\t\t */\n\t\tif (x == DUK_DBG_IB_OBJECT) {\n\t\t\tduk_debug_skip_byte(thr);\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tgoto fail;\n\t}\n\n\treturn (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode any pointer (object, pointer, heapptr)\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_tval *duk_debug_read_tval(duk_hthread *thr) {\n\tduk_uint8_t x;\n\tduk_uint_t t;\n\tduk_uint32_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\n\tif (x >= 0xc0) {\n\t\tt = (duk_uint_t) (x - 0xc0);\n\t\tt = (t << 8) + duk_debug_read_byte(thr);\n\t\tduk_push_uint(thr, (duk_uint_t) t);\n\t\tgoto return_ptr;\n\t}\n\tif (x >= 0x80) {\n\t\tduk_push_uint(thr, (duk_uint_t) (x - 0x80));\n\t\tgoto return_ptr;\n\t}\n\tif (x >= 0x60) {\n\t\tlen = (duk_uint32_t) (x - 0x60);\n\t\tduk__debug_read_hstring_raw(thr, len);\n\t\tgoto return_ptr;\n\t}\n\n\tswitch (x) {\n\tcase DUK_DBG_IB_INT4: {\n\t\tduk_int32_t i = duk__debug_read_int32_raw(thr);\n\t\tduk_push_i32(thr, i);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_STR4: {\n\t\tlen = duk__debug_read_uint32_raw(thr);\n\t\tduk__debug_read_hstring_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_STR2: {\n\t\tlen = duk__debug_read_uint16_raw(thr);\n\t\tduk__debug_read_hstring_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_BUF4: {\n\t\tlen = duk__debug_read_uint32_raw(thr);\n\t\tduk__debug_read_hbuffer_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_BUF2: {\n\t\tlen = duk__debug_read_uint16_raw(thr);\n\t\tduk__debug_read_hbuffer_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_UNDEFINED: {\n\t\tduk_push_undefined(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_NULL: {\n\t\tduk_push_null(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_TRUE: {\n\t\tduk_push_true(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_FALSE: {\n\t\tduk_push_false(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_NUMBER: {\n\t\tduk_double_t d;\n\t\td = duk__debug_read_double_raw(thr);\n\t\tduk_push_number(thr, d);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_OBJECT: {\n\t\tduk_heaphdr *h;\n\t\tduk_debug_skip_byte(thr);\n\t\th = (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\t\tduk_push_heapptr(thr, (void *) h);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_POINTER: {\n\t\tvoid *ptr;\n\t\tptr = duk__debug_read_pointer_raw(thr);\n\t\tduk_push_pointer(thr, ptr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_LIGHTFUNC: {\n\t\t/* XXX: Not needed for now, so not implemented.  Note that\n\t\t * function pointers may have different size/layout than\n\t\t * a void pointer.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"reading lightfunc values unimplemented\"));\n\t\tgoto fail;\n\t}\n\tcase DUK_DBG_IB_HEAPPTR: {\n\t\tduk_heaphdr *h;\n\t\th = (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\t\tduk_push_heapptr(thr, (void *) h);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_UNUSED:  /* unused: not accepted in inbound messages */\n\tdefault:\n\t\tgoto fail;\n\t}\n\n return_ptr:\n\treturn DUK_GET_TVAL_NEGIDX(thr, -1);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode tval\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn NULL;\n}\n\n/*\n *  Debug connection write primitives\n */\n\n/* Write fully. */\nDUK_INTERNAL void duk_debug_write_bytes(duk_hthread *thr, const duk_uint8_t *data, duk_size_t length) {\n\tduk_heap *heap;\n\tconst duk_uint8_t *p;\n\tduk_size_t left;\n\tduk_size_t got;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(length == 0 || data != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_write_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to write %ld bytes in detached state, ignore\", (long) length));\n\t\treturn;\n\t}\n\tif (length == 0) {\n\t\t/* Avoid doing an actual write callback with length == 0,\n\t\t * because that's reserved for a write flush.\n\t\t */\n\t\treturn;\n\t}\n\tDUK_ASSERT(data != NULL);\n\n\tp = data;\n\tfor (;;) {\n\t\tleft = (duk_size_t) ((data + length) - p);\n\t\tif (left == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tDUK_ASSERT(heap->dbg_write_cb != NULL);\n\t\tDUK_ASSERT(left >= 1);\n#if defined(DUK_USE_DEBUGGER_TRANSPORT_TORTURE)\n\t\tleft = 1;\n#endif\n\t\tDUK__DBG_TPORT_ENTER();\n\t\tgot = heap->dbg_write_cb(heap->dbg_udata, (const char *) p, left);\n\t\tDUK__DBG_TPORT_EXIT();\n\n\t\tif (got == 0 || got > left) {\n\t\t\tduk__debug_null_most_callbacks(thr);  /* avoid calling write callback in detach1() */\n\t\t\tDUK_D(DUK_DPRINT(\"connection error during write\"));\n\t\t\tDUK__SET_CONN_BROKEN(thr, 1);\n\t\t\treturn;\n\t\t}\n\t\tp += got;\n\t}\n}\n\nDUK_INTERNAL void duk_debug_write_byte(duk_hthread *thr, duk_uint8_t x) {\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &x, 1);\n}\n\nDUK_INTERNAL void duk_debug_write_unused(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_UNUSED);\n}\n\nDUK_INTERNAL void duk_debug_write_undefined(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_UNDEFINED);\n}\n\n#if defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL void duk_debug_write_null(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_NULL);\n}\n#endif\n\nDUK_INTERNAL void duk_debug_write_boolean(duk_hthread *thr, duk_uint_t val) {\n\tduk_debug_write_byte(thr, val ? DUK_DBG_IB_TRUE : DUK_DBG_IB_FALSE);\n}\n\n/* Write signed 32-bit integer. */\nDUK_INTERNAL void duk_debug_write_int(duk_hthread *thr, duk_int32_t x) {\n\tduk_uint8_t buf[5];\n\tduk_size_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tif (x >= 0 && x <= 0x3fL) {\n\t\tbuf[0] = (duk_uint8_t) (0x80 + x);\n\t\tlen = 1;\n\t} else if (x >= 0 && x <= 0x3fffL) {\n\t\tbuf[0] = (duk_uint8_t) (0xc0 + (x >> 8));\n\t\tbuf[1] = (duk_uint8_t) (x & 0xff);\n\t\tlen = 2;\n\t} else {\n\t\t/* Signed integers always map to 4 bytes now. */\n\t\tbuf[0] = (duk_uint8_t) DUK_DBG_IB_INT4;\n\t\tbuf[1] = (duk_uint8_t) ((x >> 24) & 0xff);\n\t\tbuf[2] = (duk_uint8_t) ((x >> 16) & 0xff);\n\t\tbuf[3] = (duk_uint8_t) ((x >> 8) & 0xff);\n\t\tbuf[4] = (duk_uint8_t) (x & 0xff);\n\t\tlen = 5;\n\t}\n\tduk_debug_write_bytes(thr, buf, len);\n}\n\n/* Write unsigned 32-bit integer. */\nDUK_INTERNAL void duk_debug_write_uint(duk_hthread *thr, duk_uint32_t x) {\n\t/* The debugger protocol doesn't support a plain integer encoding for\n\t * the full 32-bit unsigned range (only 32-bit signed).  For now,\n\t * unsigned 32-bit values simply written as signed ones.  This is not\n\t * a concrete issue except for 32-bit heaphdr fields.  Proper solutions\n\t * would be to (a) write such integers as IEEE doubles or (b) add an\n\t * unsigned 32-bit dvalue.\n\t */\n\tif (x >= 0x80000000UL) {\n\t\tDUK_D(DUK_DPRINT(\"writing unsigned integer 0x%08lx as signed integer\",\n\t\t                 (long) x));\n\t}\n\tduk_debug_write_int(thr, (duk_int32_t) x);\n}\n\nDUK_INTERNAL void duk_debug_write_strbuf(duk_hthread *thr, const char *data, duk_size_t length, duk_uint8_t marker_base) {\n\tduk_uint8_t buf[5];\n\tduk_size_t buflen;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(length == 0 || data != NULL);\n\n\tif (length <= 0x1fUL && marker_base == DUK_DBG_IB_STR4) {\n\t\t/* For strings, special form for short lengths. */\n\t\tbuf[0] = (duk_uint8_t) (0x60 + length);\n\t\tbuflen = 1;\n\t} else if (length <= 0xffffUL) {\n\t\tbuf[0] = (duk_uint8_t) (marker_base + 1);\n\t\tbuf[1] = (duk_uint8_t) (length >> 8);\n\t\tbuf[2] = (duk_uint8_t) (length & 0xff);\n\t\tbuflen = 3;\n\t} else {\n\t\tbuf[0] = (duk_uint8_t) marker_base;\n\t\tbuf[1] = (duk_uint8_t) (length >> 24);\n\t\tbuf[2] = (duk_uint8_t) ((length >> 16) & 0xff);\n\t\tbuf[3] = (duk_uint8_t) ((length >> 8) & 0xff);\n\t\tbuf[4] = (duk_uint8_t) (length & 0xff);\n\t\tbuflen = 5;\n\t}\n\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) buf, buflen);\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) data, length);\n}\n\nDUK_INTERNAL void duk_debug_write_string(duk_hthread *thr, const char *data, duk_size_t length) {\n\tduk_debug_write_strbuf(thr, data, length, DUK_DBG_IB_STR4);\n}\n\nDUK_INTERNAL void duk_debug_write_cstring(duk_hthread *thr, const char *data) {\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_write_string(thr,\n\t                       data,\n\t                       data ? DUK_STRLEN(data) : 0);\n}\n\nDUK_INTERNAL void duk_debug_write_hstring(duk_hthread *thr, duk_hstring *h) {\n\tDUK_ASSERT(thr != NULL);\n\n\t/* XXX: differentiate null pointer from empty string? */\n\tduk_debug_write_string(thr,\n\t                       (h != NULL ? (const char *) DUK_HSTRING_GET_DATA(h) : NULL),\n\t                       (h != NULL ? (duk_size_t) DUK_HSTRING_GET_BYTELEN(h) : 0));\n}\n\nDUK_LOCAL void duk__debug_write_hstring_safe_top(duk_hthread *thr) {\n\tduk_debug_write_hstring(thr, duk_safe_to_hstring(thr, -1));\n}\n\nDUK_INTERNAL void duk_debug_write_buffer(duk_hthread *thr, const char *data, duk_size_t length) {\n\tduk_debug_write_strbuf(thr, data, length, DUK_DBG_IB_BUF4);\n}\n\nDUK_INTERNAL void duk_debug_write_hbuffer(duk_hthread *thr, duk_hbuffer *h) {\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_write_buffer(thr,\n\t                       (h != NULL ? (const char *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h) : NULL),\n\t                       (h != NULL ? (duk_size_t) DUK_HBUFFER_GET_SIZE(h) : 0));\n}\n\nDUK_LOCAL void duk__debug_write_pointer_raw(duk_hthread *thr, void *ptr, duk_uint8_t ibyte) {\n\tduk_uint8_t buf[2];\n\tduk__ptr_union pu;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(sizeof(ptr) >= 1 && sizeof(ptr) <= 16);\n\t/* ptr may be NULL */\n\n\tbuf[0] = ibyte;\n\tbuf[1] = sizeof(pu);\n\tduk_debug_write_bytes(thr, buf, 2);\n\tpu.p = (void *) ptr;\n#if defined(DUK_USE_INTEGER_LE)\n\tduk_byteswap_bytes((duk_uint8_t *) pu.b, sizeof(pu));\n#endif\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &pu.p, (duk_size_t) sizeof(pu));\n}\n\nDUK_INTERNAL void duk_debug_write_pointer(duk_hthread *thr, void *ptr) {\n\tduk__debug_write_pointer_raw(thr, ptr, DUK_DBG_IB_POINTER);\n}\n\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP) || defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL void duk_debug_write_heapptr(duk_hthread *thr, duk_heaphdr *h) {\n\tduk__debug_write_pointer_raw(thr, (void *) h, DUK_DBG_IB_HEAPPTR);\n}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP || DUK_USE_DEBUGGER_INSPECT */\n\nDUK_INTERNAL void duk_debug_write_hobject(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint8_t buf[3];\n\tduk__ptr_union pu;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(sizeof(obj) >= 1 && sizeof(obj) <= 16);\n\tDUK_ASSERT(obj != NULL);\n\n\tbuf[0] = DUK_DBG_IB_OBJECT;\n\tbuf[1] = (duk_uint8_t) DUK_HOBJECT_GET_CLASS_NUMBER(obj);\n\tbuf[2] = sizeof(pu);\n\tduk_debug_write_bytes(thr, buf, 3);\n\tpu.p = (void *) obj;\n#if defined(DUK_USE_INTEGER_LE)\n\tduk_byteswap_bytes((duk_uint8_t *) pu.b, sizeof(pu));\n#endif\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &pu.p, (duk_size_t) sizeof(pu));\n}\n\nDUK_INTERNAL void duk_debug_write_tval(duk_hthread *thr, duk_tval *tv) {\n\tduk_c_function lf_func;\n\tduk_small_uint_t lf_flags;\n\tduk_uint8_t buf[4];\n\tduk_double_union du1;\n\tduk_double_union du2;\n\tduk_int32_t i32;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\t\tduk_debug_write_byte(thr, DUK_DBG_IB_UNDEFINED);\n\t\tbreak;\n\tcase DUK_TAG_UNUSED:\n\t\tduk_debug_write_byte(thr, DUK_DBG_IB_UNUSED);\n\t\tbreak;\n\tcase DUK_TAG_NULL:\n\t\tduk_debug_write_byte(thr, DUK_DBG_IB_NULL);\n\t\tbreak;\n\tcase DUK_TAG_BOOLEAN:\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv) == 0 ||\n\t\t           DUK_TVAL_GET_BOOLEAN(tv) == 1);\n\t\tduk_debug_write_boolean(thr, DUK_TVAL_GET_BOOLEAN(tv));\n\t\tbreak;\n\tcase DUK_TAG_POINTER:\n\t\tduk_debug_write_pointer(thr, (void *) DUK_TVAL_GET_POINTER(tv));\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\tDUK_TVAL_GET_LIGHTFUNC(tv, lf_func, lf_flags);\n\t\tbuf[0] = DUK_DBG_IB_LIGHTFUNC;\n\t\tbuf[1] = (duk_uint8_t) (lf_flags >> 8);\n\t\tbuf[2] = (duk_uint8_t) (lf_flags & 0xff);\n\t\tbuf[3] = sizeof(lf_func);\n\t\tduk_debug_write_bytes(thr, buf, 4);\n\t\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &lf_func, sizeof(lf_func));\n\t\tbreak;\n\tcase DUK_TAG_STRING:\n\t\tduk_debug_write_hstring(thr, DUK_TVAL_GET_STRING(tv));\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\tduk_debug_write_hobject(thr, DUK_TVAL_GET_OBJECT(tv));\n\t\tbreak;\n\tcase DUK_TAG_BUFFER:\n\t\tduk_debug_write_hbuffer(thr, DUK_TVAL_GET_BUFFER(tv));\n\t\tbreak;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* Numbers are normalized to big (network) endian.  We can\n\t\t * (but are not required) to use integer dvalues when there's\n\t\t * no loss of precision.\n\t\t *\n\t\t * XXX: share check with other code; this check is slow but\n\t\t * reliable and doesn't require careful exponent/mantissa\n\t\t * mask tricks as in the fastint downgrade code.\n\t\t */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tdu1.d = DUK_TVAL_GET_NUMBER(tv);\n\t\ti32 = (duk_int32_t) du1.d;\n\t\tdu2.d = (duk_double_t) i32;\n\n\t\tDUK_DD(DUK_DDPRINT(\"i32=%ld du1=%02x%02x%02x%02x%02x%02x%02x%02x \"\n\t\t                   \"du2=%02x%02x%02x%02x%02x%02x%02x%02x\",\n\t\t                   (long) i32,\n\t\t                   (unsigned int) du1.uc[0], (unsigned int) du1.uc[1],\n\t\t                   (unsigned int) du1.uc[2], (unsigned int) du1.uc[3],\n\t\t                   (unsigned int) du1.uc[4], (unsigned int) du1.uc[5],\n\t\t                   (unsigned int) du1.uc[6], (unsigned int) du1.uc[7],\n\t\t                   (unsigned int) du2.uc[0], (unsigned int) du2.uc[1],\n\t\t                   (unsigned int) du2.uc[2], (unsigned int) du2.uc[3],\n\t\t                   (unsigned int) du2.uc[4], (unsigned int) du2.uc[5],\n\t\t                   (unsigned int) du2.uc[6], (unsigned int) du2.uc[7]));\n\n\t\tif (duk_memcmp((const void *) du1.uc, (const void *) du2.uc, sizeof(du1.uc)) == 0) {\n\t\t\tduk_debug_write_int(thr, i32);\n\t\t} else {\n\t\t\tDUK_DBLUNION_DOUBLE_HTON(&du1);\n\t\t\tduk_debug_write_byte(thr, DUK_DBG_IB_NUMBER);\n\t\t\tduk_debug_write_bytes(thr, (const duk_uint8_t *) du1.uc, sizeof(du1.uc));\n\t\t}\n\t}\n}\n\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP)\n/* Variant for writing duk_tvals so that any heap allocated values are\n * written out as tagged heap pointers.\n */\nDUK_LOCAL void duk__debug_write_tval_heapptr(duk_hthread *thr, duk_tval *tv) {\n\tif (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tduk_debug_write_heapptr(thr, h);\n\t} else {\n\t\tduk_debug_write_tval(thr, tv);\n\t}\n}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP */\n\n/*\n *  Debug connection message write helpers\n */\n\n#if 0  /* unused */\nDUK_INTERNAL void duk_debug_write_request(duk_hthread *thr, duk_small_uint_t command) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_REQUEST);\n\tduk_debug_write_int(thr, command);\n}\n#endif\n\nDUK_INTERNAL void duk_debug_write_reply(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_REPLY);\n}\n\nDUK_INTERNAL void duk_debug_write_error_eom(duk_hthread *thr, duk_small_uint_t err_code, const char *msg) {\n\t/* Allow NULL 'msg' */\n\tduk_debug_write_byte(thr, DUK_DBG_IB_ERROR);\n\tduk_debug_write_int(thr, (duk_int32_t) err_code);\n\tduk_debug_write_cstring(thr, msg);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_INTERNAL void duk_debug_write_notify(duk_hthread *thr, duk_small_uint_t command) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_NOTIFY);\n\tduk_debug_write_int(thr, (duk_int32_t) command);\n}\n\nDUK_INTERNAL void duk_debug_write_eom(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_EOM);\n\n\t/* As an initial implementation, write flush after every EOM (and the\n\t * version identifier).  A better implementation would flush only when\n\t * Duktape is finished processing messages so that a flush only happens\n\t * after all outbound messages are finished on that occasion.\n\t */\n\tduk_debug_write_flush(thr);\n}\n\n/*\n *  Status message and helpers\n */\n\nDUK_INTERNAL duk_uint_fast32_t duk_debug_curr_line(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_uint_fast32_t line;\n\tduk_uint_fast32_t pc;\n\n\tact = thr->callstack_curr;\n\tif (act == NULL) {\n\t\treturn 0;\n\t}\n\n\t/* We're conceptually between two opcodes; act->pc indicates the next\n\t * instruction to be executed.  This is usually the correct pc/line to\n\t * indicate in Status.  (For the 'debugger' statement this now reports\n\t * the pc/line after the debugger statement because the debugger opcode\n\t * has already been executed.)\n\t */\n\n\tpc = duk_hthread_get_act_curr_pc(thr, act);\n\n\t/* XXX: this should be optimized to be a raw query and avoid valstack\n\t * operations if possible.\n\t */\n\tduk_push_tval(thr, &act->tv_func);\n\tline = duk_hobject_pc2line_query(thr, -1, pc);\n\tduk_pop(thr);\n\treturn line;\n}\n\nDUK_INTERNAL void duk_debug_send_status(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tduk_debug_write_notify(thr, DUK_DBG_CMD_STATUS);\n\tduk_debug_write_int(thr, (DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) ? 1 : 0));\n\n\tact = thr->callstack_curr;\n\tif (act == NULL) {\n\t\tduk_debug_write_undefined(thr);\n\t\tduk_debug_write_undefined(thr);\n\t\tduk_debug_write_int(thr, 0);\n\t\tduk_debug_write_int(thr, 0);\n\t} else {\n\t\tduk_push_tval(thr, &act->tv_func);\n\t\tduk_get_prop_literal(thr, -1, \"fileName\");\n\t\tduk__debug_write_hstring_safe_top(thr);\n\t\tduk_get_prop_literal(thr, -2, \"name\");\n\t\tduk__debug_write_hstring_safe_top(thr);\n\t\tduk_pop_3(thr);\n\t\t/* Report next pc/line to be executed. */\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) duk_debug_curr_line(thr));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) duk_hthread_get_act_curr_pc(thr, act));\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n\n#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)\nDUK_INTERNAL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal) {\n\t/*\n\t *  NFY <int: 5> <int: fatal> <str: msg> <str: filename> <int: linenumber> EOM\n\t */\n\n\tduk_activation *act;\n\tduk_uint32_t pc;\n\n\tDUK_ASSERT(thr->valstack_top > thr->valstack);  /* At least: ... [err] */\n\n\tduk_debug_write_notify(thr, DUK_DBG_CMD_THROW);\n\tduk_debug_write_int(thr, (duk_int32_t) fatal);\n\n\t/* Report thrown value to client coerced to string */\n\tduk_dup_top(thr);\n\tduk__debug_write_hstring_safe_top(thr);\n\tduk_pop(thr);\n\n\tif (duk_is_error(thr, -1)) {\n\t\t/* Error instance, use augmented error data directly */\n\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME);\n\t\tduk__debug_write_hstring_safe_top(thr);\n\t\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_LINE_NUMBER);\n\t\tduk_debug_write_uint(thr, duk_get_uint(thr, -1));\n\t\tduk_pop_2(thr);\n\t} else {\n\t\t/* For anything other than an Error instance, we calculate the\n\t\t * error location directly from the current activation if one\n\t\t * exists.\n\t\t */\n\t\tact = thr->callstack_curr;\n\t\tif (act != NULL) {\n\t\t\tduk_push_tval(thr, &act->tv_func);\n\t\t\tduk_get_prop_literal(thr, -1, \"fileName\");\n\t\t\tduk__debug_write_hstring_safe_top(thr);\n\t\t\tpc = (duk_uint32_t) duk_hthread_get_act_prev_pc(thr, act);\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) duk_hobject_pc2line_query(thr, -2, pc));\n\t\t\tduk_pop_2(thr);\n\t\t} else {\n\t\t\t/* Can happen if duk_throw() is called on an empty\n\t\t\t * callstack.\n\t\t\t */\n\t\t\tduk_debug_write_cstring(thr, \"\");\n\t\t\tduk_debug_write_uint(thr, 0);\n\t\t}\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n#endif  /* DUK_USE_DEBUGGER_THROW_NOTIFY */\n\n/*\n *  Debug message processing\n */\n\n/* Skip dvalue. */\nDUK_LOCAL duk_bool_t duk__debug_skip_dvalue(duk_hthread *thr) {\n\tduk_uint8_t x;\n\tduk_uint32_t len;\n\n\tx = duk_debug_read_byte(thr);\n\n\tif (x >= 0xc0) {\n\t\tduk_debug_skip_byte(thr);\n\t\treturn 0;\n\t}\n\tif (x >= 0x80) {\n\t\treturn 0;\n\t}\n\tif (x >= 0x60) {\n\t\tduk_debug_skip_bytes(thr, (duk_size_t) (x - 0x60));\n\t\treturn 0;\n\t}\n\tswitch(x) {\n\tcase DUK_DBG_IB_EOM:\n\t\treturn 1;  /* Return 1: got EOM */\n\tcase DUK_DBG_IB_REQUEST:\n\tcase DUK_DBG_IB_REPLY:\n\tcase DUK_DBG_IB_ERROR:\n\tcase DUK_DBG_IB_NOTIFY:\n\t\tbreak;\n\tcase DUK_DBG_IB_INT4:\n\t\t(void) duk__debug_read_uint32_raw(thr);\n\t\tbreak;\n\tcase DUK_DBG_IB_STR4:\n\tcase DUK_DBG_IB_BUF4:\n\t\tlen = duk__debug_read_uint32_raw(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_STR2:\n\tcase DUK_DBG_IB_BUF2:\n\t\tlen = duk__debug_read_uint16_raw(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_UNUSED:\n\tcase DUK_DBG_IB_UNDEFINED:\n\tcase DUK_DBG_IB_NULL:\n\tcase DUK_DBG_IB_TRUE:\n\tcase DUK_DBG_IB_FALSE:\n\t\tbreak;\n\tcase DUK_DBG_IB_NUMBER:\n\t\tduk_debug_skip_bytes(thr, 8);\n\t\tbreak;\n\tcase DUK_DBG_IB_OBJECT:\n\t\tduk_debug_skip_byte(thr);\n\t\tlen = duk_debug_read_byte(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_POINTER:\n\tcase DUK_DBG_IB_HEAPPTR:\n\t\tlen = duk_debug_read_byte(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_LIGHTFUNC:\n\t\tduk_debug_skip_bytes(thr, 2);\n\t\tlen = duk_debug_read_byte(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tdefault:\n\t\tgoto fail;\n\t}\n\n\treturn 0;\n\n fail:\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn 1;  /* Pretend like we got EOM */\n}\n\n/* Skip dvalues to EOM. */\nDUK_LOCAL void duk__debug_skip_to_eom(duk_hthread *thr) {\n\tfor (;;) {\n\t\tif (duk__debug_skip_dvalue(thr)) {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/* Read and validate a call stack index.  If index is invalid, write out an\n * error message and return zero.\n */\nDUK_LOCAL duk_int32_t duk__debug_read_validate_csindex(duk_hthread *thr) {\n\tduk_int32_t level;\n\tlevel = duk_debug_read_int(thr);\n\tif (level >= 0 || -level > (duk_int32_t) thr->callstack_top) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid callstack index\");\n\t\treturn 0;  /* zero indicates failure */\n\t}\n\treturn level;\n}\n\n/* Read a call stack index and lookup the corresponding duk_activation.\n * If index is invalid, write out an error message and return NULL.\n */\nDUK_LOCAL duk_activation *duk__debug_read_level_get_activation(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_int32_t level;\n\n\tlevel = duk_debug_read_int(thr);\n\tact = duk_hthread_get_activation_for_level(thr, level);\n\tif (act == NULL) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid callstack index\");\n\t}\n\treturn act;\n}\n\n/*\n *  Simple commands\n */\n\nDUK_LOCAL void duk__debug_handle_basic_info(duk_hthread *thr, duk_heap *heap) {\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command Version\"));\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_int(thr, DUK_VERSION);\n\tduk_debug_write_cstring(thr, DUK_GIT_DESCRIBE);\n\tduk_debug_write_cstring(thr, DUK_USE_TARGET_INFO);\n#if defined(DUK_USE_DOUBLE_LE)\n\tduk_debug_write_int(thr, 1);\n#elif defined(DUK_USE_DOUBLE_ME)\n\tduk_debug_write_int(thr, 2);\n#elif defined(DUK_USE_DOUBLE_BE)\n\tduk_debug_write_int(thr, 3);\n#else\n\tduk_debug_write_int(thr, 0);\n#endif\n\tduk_debug_write_int(thr, (duk_int_t) sizeof(void *));\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_trigger_status(duk_hthread *thr, duk_heap *heap) {\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command TriggerStatus\"));\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n\theap->dbg_state_dirty = 1;\n}\n\nDUK_LOCAL void duk__debug_handle_pause(duk_hthread *thr, duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"debug command Pause\"));\n\tduk_debug_set_paused(heap);\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_resume(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_uint_t pause_flags;\n\n\tDUK_D(DUK_DPRINT(\"debug command Resume\"));\n\n\tduk_debug_clear_paused(heap);\n\n\tpause_flags = 0;\n#if 0  /* manual testing */\n\tpause_flags |= DUK_PAUSE_FLAG_ONE_OPCODE;\n\tpause_flags |= DUK_PAUSE_FLAG_CAUGHT_ERROR;\n\tpause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;\n#endif\n#if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)\n\tpause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;\n#endif\n\n\tduk__debug_set_pause_state(thr, heap, pause_flags);\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_step(duk_hthread *thr, duk_heap *heap, duk_int32_t cmd) {\n\tduk_small_uint_t pause_flags;\n\n\tDUK_D(DUK_DPRINT(\"debug command StepInto/StepOver/StepOut: %d\", (int) cmd));\n\n\tif (cmd == DUK_DBG_CMD_STEPINTO) {\n\t\tpause_flags = DUK_PAUSE_FLAG_LINE_CHANGE |\n\t\t              DUK_PAUSE_FLAG_FUNC_ENTRY |\n\t\t              DUK_PAUSE_FLAG_FUNC_EXIT;\n\t} else if (cmd == DUK_DBG_CMD_STEPOVER) {\n\t\tpause_flags = DUK_PAUSE_FLAG_LINE_CHANGE |\n\t\t              DUK_PAUSE_FLAG_FUNC_EXIT;\n\t} else {\n\t\tDUK_ASSERT(cmd == DUK_DBG_CMD_STEPOUT);\n\t\tpause_flags = DUK_PAUSE_FLAG_FUNC_EXIT;\n\t}\n#if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)\n\tpause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;\n#endif\n\n\t/* If current activation doesn't have line information, line-based\n\t * pause flags are automatically disabled.  As a result, e.g.\n\t * StepInto will then pause on (native) function entry or exit.\n\t */\n\tduk_debug_clear_paused(heap);\n\tduk__debug_set_pause_state(thr, heap, pause_flags);\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_list_break(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_int_t i;\n\n\tDUK_D(DUK_DPRINT(\"debug command ListBreak\"));\n\tduk_debug_write_reply(thr);\n\tfor (i = 0; i < (duk_small_int_t) heap->dbg_breakpoint_count; i++) {\n\t\tduk_debug_write_hstring(thr, heap->dbg_breakpoints[i].filename);\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) heap->dbg_breakpoints[i].line);\n\t}\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_add_break(duk_hthread *thr, duk_heap *heap) {\n\tduk_hstring *filename;\n\tduk_uint32_t linenumber;\n\tduk_small_int_t idx;\n\n\tDUK_UNREF(heap);\n\n\tfilename = duk_debug_read_hstring(thr);\n\tlinenumber = (duk_uint32_t) duk_debug_read_int(thr);\n\tDUK_D(DUK_DPRINT(\"debug command AddBreak: %!O:%ld\", (duk_hobject *) filename, (long) linenumber));\n\tidx = duk_debug_add_breakpoint(thr, filename, linenumber);\n\tif (idx >= 0) {\n\t\tduk_debug_write_reply(thr);\n\t\tduk_debug_write_int(thr, (duk_int32_t) idx);\n\t\tduk_debug_write_eom(thr);\n\t} else {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_TOOMANY, \"no space for breakpoint\");\n\t}\n}\n\nDUK_LOCAL void duk__debug_handle_del_break(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_uint_t idx;\n\n\tDUK_UNREF(heap);\n\n\tDUK_D(DUK_DPRINT(\"debug command DelBreak\"));\n\tidx = (duk_small_uint_t) duk_debug_read_int(thr);\n\tif (duk_debug_remove_breakpoint(thr, idx)) {\n\t\tduk_debug_write_reply(thr);\n\t\tduk_debug_write_eom(thr);\n\t} else {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid breakpoint index\");\n\t}\n}\n\nDUK_LOCAL void duk__debug_handle_get_var(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hstring *str;\n\tduk_bool_t rc;\n\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command GetVar\"));\n\n\tact = duk__debug_read_level_get_activation(thr);\n\tif (act == NULL) {\n\t\treturn;\n\t}\n\tstr = duk_debug_read_hstring(thr);  /* push to stack */\n\tDUK_ASSERT(str != NULL);\n\n\trc = duk_js_getvar_activation(thr, act, str, 0);\n\n\tduk_debug_write_reply(thr);\n\tif (rc) {\n\t\tduk_debug_write_int(thr, 1);\n\t\tDUK_ASSERT(duk_get_tval(thr, -2) != NULL);\n\t\tduk_debug_write_tval(thr, duk_get_tval(thr, -2));\n\t} else {\n\t\tduk_debug_write_int(thr, 0);\n\t\tduk_debug_write_unused(thr);\n\t}\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_put_var(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hstring *str;\n\tduk_tval *tv;\n\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command PutVar\"));\n\n\tact = duk__debug_read_level_get_activation(thr);\n\tif (act == NULL) {\n\t\treturn;\n\t}\n\tstr = duk_debug_read_hstring(thr);  /* push to stack */\n\tDUK_ASSERT(str != NULL);\n\ttv = duk_debug_read_tval(thr);\n\tif (tv == NULL) {\n\t\t/* detached */\n\t\treturn;\n\t}\n\n\tduk_js_putvar_activation(thr, act, str, tv, 0);\n\n\t/* XXX: Current putvar implementation doesn't have a success flag,\n\t * add one and send to debug client?\n\t */\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_get_call_stack(duk_hthread *thr, duk_heap *heap) {\n\tduk_hthread *curr_thr = thr;\n\tduk_activation *curr_act;\n\tduk_uint_fast32_t pc;\n\tduk_uint_fast32_t line;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_UNREF(heap);\n\n\tduk_debug_write_reply(thr);\n\twhile (curr_thr != NULL) {\n\t\tfor (curr_act = curr_thr->callstack_curr; curr_act != NULL; curr_act = curr_act->parent) {\n\t\t\t/* PC/line semantics here are:\n\t\t\t *   - For callstack top we're conceptually between two\n\t\t\t *     opcodes and current PC indicates next line to\n\t\t\t *     execute, so report that (matches Status).\n\t\t\t *   - For other activations we're conceptually still\n\t\t\t *     executing the instruction at PC-1, so report that\n\t\t\t *     (matches error stacktrace behavior).\n\t\t\t *   - See: https://github.com/svaarala/duktape/issues/281\n\t\t\t */\n\n\t\t\t/* XXX: optimize to use direct reads, i.e. avoid\n\t\t\t * value stack operations.\n\t\t\t */\n\t\t\tduk_push_tval(thr, &curr_act->tv_func);\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME);\n\t\t\tduk__debug_write_hstring_safe_top(thr);\n\t\t\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME);\n\t\t\tduk__debug_write_hstring_safe_top(thr);\n\t\t\tpc = duk_hthread_get_act_curr_pc(thr, curr_act);\n\t\t\tif (curr_act != curr_thr->callstack_curr && pc > 0) {\n\t\t\t\tpc--;\n\t\t\t}\n\t\t\tline = duk_hobject_pc2line_query(thr, -3, pc);\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) line);\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) pc);\n\t\t\tduk_pop_3(thr);\n\t\t}\n\t\tcurr_thr = curr_thr->resumer;\n\t}\n\t/* SCANBUILD: warning about 'thr' potentially being NULL here,\n\t * warning is incorrect because thr != NULL always here.\n\t */\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_get_locals(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hstring *varname;\n\n\tDUK_UNREF(heap);\n\n\tact = duk__debug_read_level_get_activation(thr);\n\tif (act == NULL) {\n\t\treturn;\n\t}\n\n\tduk_debug_write_reply(thr);\n\n\t/* XXX: several nice-to-have improvements here:\n\t *   - Use direct reads avoiding value stack operations\n\t *   - Avoid triggering getters, indicate getter values to debug client\n\t *   - If side effects are possible, add error catching\n\t */\n\n\tif (DUK_TVAL_IS_OBJECT(&act->tv_func)) {\n\t\tduk_hobject *h_func = DUK_TVAL_GET_OBJECT(&act->tv_func);\n\t\tduk_hobject *h_varmap;\n\n\t\th_varmap = duk_hobject_get_varmap(thr, h_func);\n\t\tif (h_varmap != NULL) {\n\t\t\tduk_push_hobject(thr, h_varmap);\n\t\t\tduk_enum(thr, -1, 0 /*enum_flags*/);\n\t\t\twhile (duk_next(thr, -1 /*enum_index*/, 0 /*get_value*/)) {\n\t\t\t\tvarname = duk_known_hstring(thr, -1);\n\n\t\t\t\tduk_js_getvar_activation(thr, act, varname, 0 /*throw_flag*/);\n\t\t\t\t/* [ ... func varmap enum key value this ] */\n\t\t\t\tduk_debug_write_hstring(thr, duk_get_hstring(thr, -3));\n\t\t\t\tduk_debug_write_tval(thr, duk_get_tval(thr, -2));\n\t\t\t\tduk_pop_3(thr);  /* -> [ ... func varmap enum ] */\n\t\t\t}\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"varmap missing in GetLocals, ignore\"));\n\t\t}\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"varmap is not an object in GetLocals, ignore\"));\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_uint_t call_flags;\n\tduk_int_t call_ret;\n\tduk_small_int_t eval_err;\n\tduk_bool_t direct_eval;\n\tduk_int32_t level;\n\tduk_idx_t idx_func;\n\n\tDUK_UNREF(heap);\n\n\tDUK_D(DUK_DPRINT(\"debug command Eval\"));\n\n\t/* The eval code is executed within the lexical environment of a specified\n\t * activation.  For now, use global object eval() function, with the eval\n\t * considered a 'direct call to eval'.\n\t *\n\t * Callstack index for debug commands only affects scope -- the callstack\n\t * as seen by, e.g. Duktape.act() will be the same regardless.\n\t */\n\n\t/* nargs == 2 so we can pass a callstack index to eval(). */\n\tidx_func = duk_get_top(thr);\n\tduk_push_c_function(thr, duk_bi_global_object_eval, 2 /*nargs*/);\n\tduk_push_undefined(thr);  /* 'this' binding shouldn't matter here */\n\n\t/* Read callstack index, if non-null. */\n\tif (duk_debug_peek_byte(thr) == DUK_DBG_IB_NULL) {\n\t\tdirect_eval = 0;\n\t\tlevel = -1;  /* Not needed, but silences warning. */\n\t\t(void) duk_debug_read_byte(thr);\n\t} else {\n\t\tdirect_eval = 1;\n\t\tlevel = duk__debug_read_validate_csindex(thr);\n\t\tif (level == 0) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\tDUK_ASSERT(!direct_eval ||\n\t           (level < 0 && -level <= (duk_int32_t) thr->callstack_top));\n\n\t(void) duk_debug_read_hstring(thr);\n\tif (direct_eval) {\n\t\tduk_push_int(thr, level - 1);  /* compensate for eval() call */\n\t}\n\n\t/* [ ... eval \"eval\" eval_input level? ] */\n\n\tcall_flags = 0;\n\tif (direct_eval) {\n\t\tduk_activation *act;\n\t\tduk_hobject *fun;\n\n\t\tact = duk_hthread_get_activation_for_level(thr, level);\n\t\tif (act != NULL) {\n\t\t\tfun = DUK_ACT_GET_FUNC(act);\n\t\t\tif (fun != NULL && DUK_HOBJECT_IS_COMPFUNC(fun)) {\n\t\t\t\t/* Direct eval requires that there's a current\n\t\t\t\t * activation and it is an ECMAScript function.\n\t\t\t\t * When Eval is executed from e.g. cooperate API\n\t\t\t\t * call we'll need to do an indirect eval instead.\n\t\t\t\t */\n\t\t\t\tcall_flags |= DUK_CALL_FLAG_DIRECT_EVAL;\n\t\t\t}\n\t\t}\n\t}\n\n\tcall_ret = duk_pcall_method_flags(thr, duk_get_top(thr) - (idx_func + 2), call_flags);\n\n\tif (call_ret == DUK_EXEC_SUCCESS) {\n\t\teval_err = 0;\n\t\t/* Use result value as is. */\n\t} else {\n\t\t/* For errors a string coerced result is most informative\n\t\t * right now, as the debug client doesn't have the capability\n\t\t * to traverse the error object.\n\t\t */\n\t\teval_err = 1;\n\t\tduk_safe_to_string(thr, -1);\n\t}\n\n\t/* [ ... result ] */\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_int(thr, (duk_int32_t) eval_err);\n\tDUK_ASSERT(duk_get_tval(thr, -1) != NULL);\n\tduk_debug_write_tval(thr, duk_get_tval(thr, -1));\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_detach(duk_hthread *thr, duk_heap *heap) {\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command Detach\"));\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n\n\tDUK_D(DUK_DPRINT(\"debug connection detached, mark broken\"));\n\tDUK__SET_CONN_BROKEN(thr, 0);  /* not an error */\n}\n\nDUK_LOCAL void duk__debug_handle_apprequest(duk_hthread *thr, duk_heap *heap) {\n\tduk_idx_t old_top;\n\n\tDUK_D(DUK_DPRINT(\"debug command AppRequest\"));\n\n\told_top = duk_get_top(thr);  /* save stack top */\n\n\tif (heap->dbg_request_cb != NULL) {\n\t\tduk_idx_t nrets;\n\t\tduk_idx_t nvalues = 0;\n\t\tduk_idx_t top, idx;\n\n\t\t/* Read tvals from the message and push them onto the valstack,\n\t\t * then call the request callback to process the request.\n\t\t */\n\t\twhile (duk_debug_peek_byte(thr) != DUK_DBG_IB_EOM) {\n\t\t\tduk_tval *tv;\n\t\t\tif (!duk_check_stack(thr, 1)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"failed to allocate space for request dvalue(s)\"));\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\ttv = duk_debug_read_tval(thr);  /* push to stack */\n\t\t\tif (tv == NULL) {\n\t\t\t\t/* detached */\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnvalues++;\n\t\t}\n\t\tDUK_ASSERT(duk_get_top(thr) == old_top + nvalues);\n\n\t\t/* Request callback should push values for reply to client onto valstack */\n\t\tDUK_D(DUK_DPRINT(\"calling into AppRequest request_cb with nvalues=%ld, old_top=%ld, top=%ld\",\n\t\t                 (long) nvalues, (long) old_top, (long) duk_get_top(thr)));\n\t\tnrets = heap->dbg_request_cb(thr, heap->dbg_udata, nvalues);\n\t\tDUK_D(DUK_DPRINT(\"returned from AppRequest request_cb; nvalues=%ld -> nrets=%ld, old_top=%ld, top=%ld\",\n\t\t                 (long) nvalues, (long) nrets, (long) old_top, (long) duk_get_top(thr)));\n\t\tif (nrets >= 0) {\n\t\t\tDUK_ASSERT(duk_get_top(thr) >= old_top + nrets);\n\t\t\tif (duk_get_top(thr) < old_top + nrets) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"AppRequest callback doesn't match value stack configuration, \"\n\t\t\t\t                 \"top=%ld < old_top=%ld + nrets=%ld; \"\n\t\t\t\t                 \"this might mean it's unsafe to continue!\",\n\t\t\t\t                 (long) duk_get_top(thr), (long) old_top, (long) nrets));\n\t\t\t\tgoto fail;\n\t\t\t}\n\n\t\t\t/* Reply with tvals pushed by request callback */\n\t\t\tduk_debug_write_byte(thr, DUK_DBG_IB_REPLY);\n\t\t\ttop = duk_get_top(thr);\n\t\t\tfor (idx = top - nrets; idx < top; idx++) {\n\t\t\t\tduk_debug_write_tval(thr, DUK_GET_TVAL_POSIDX(thr, idx));\n\t\t\t}\n\t\t\tduk_debug_write_eom(thr);\n\t\t} else {\n\t\t\tDUK_ASSERT(duk_get_top(thr) >= old_top + 1);\n\t\t\tif (duk_get_top(thr) < old_top + 1) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"request callback return value doesn't match value stack configuration\"));\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_APPLICATION, duk_get_string(thr, -1));\n\t\t}\n\n\t\tduk_set_top(thr, old_top);  /* restore stack top */\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"no request callback, treat AppRequest as unsupported\"));\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNSUPPORTED, \"AppRequest unsupported by target\");\n\t}\n\n\treturn;\n\n fail:\n\tduk_set_top(thr, old_top);  /* restore stack top */\n\tDUK__SET_CONN_BROKEN(thr, 1);\n}\n\n/*\n *  DumpHeap command\n */\n\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP)\n/* XXX: this has some overlap with object inspection; remove this and make\n * DumpHeap return lists of heapptrs instead?\n */\nDUK_LOCAL void duk__debug_dump_heaphdr(duk_hthread *thr, duk_heap *heap, duk_heaphdr *hdr) {\n\tDUK_UNREF(heap);\n\n\tduk_debug_write_heapptr(thr, hdr);\n\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HEAPHDR_GET_TYPE(hdr));\n\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HEAPHDR_GET_FLAGS_RAW(hdr));\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HEAPHDR_GET_REFCOUNT(hdr));\n#else\n\tduk_debug_write_int(thr, (duk_int32_t) -1);\n#endif\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(hdr)) {\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h = (duk_hstring *) hdr;\n\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_BYTELEN(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_CHARLEN(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_HASH(h));\n\t\tduk_debug_write_hstring(thr, h);\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h = (duk_hobject *) hdr;\n\t\tduk_hstring *k;\n\t\tduk_uint_fast32_t i;\n\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_CLASS_NUMBER(h));\n\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(heap, h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_ESIZE(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_ENEXT(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_ASIZE(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_HSIZE(h));\n\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_E_GET_FLAGS(heap, h, i));\n\t\t\tk = DUK_HOBJECT_E_GET_KEY(heap, h, i);\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) k);\n\t\t\tif (k == NULL) {\n\t\t\t\tduk_debug_write_int(thr, 0);  /* isAccessor */\n\t\t\t\tduk_debug_write_unused(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)) {\n\t\t\t\tduk_debug_write_int(thr, 1);  /* isAccessor */\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.get);\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.set);\n\t\t\t} else {\n\t\t\t\tduk_debug_write_int(thr, 0);  /* isAccessor */\n\n\t\t\t\tduk__debug_write_tval_heapptr(thr, &DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->v);\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(h); i++) {\n\t\t\t/* Note: array dump will include elements beyond\n\t\t\t * 'length'.\n\t\t\t */\n\t\t\tduk__debug_write_tval_heapptr(thr, DUK_HOBJECT_A_GET_VALUE_PTR(heap, h, i));\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h = (duk_hbuffer *) hdr;\n\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HBUFFER_GET_SIZE(h));\n\t\tduk_debug_write_buffer(thr, (const char *) DUK_HBUFFER_GET_DATA_PTR(heap, h), (duk_size_t) DUK_HBUFFER_GET_SIZE(h));\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tDUK_D(DUK_DPRINT(\"invalid htype: %d\", (int) DUK_HEAPHDR_GET_TYPE(hdr)));\n\t}\n\t}\n}\n\nDUK_LOCAL void duk__debug_dump_heap_allocated(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\n\thdr = heap->heap_allocated;\n\twhile (hdr != NULL) {\n\t\tduk__debug_dump_heaphdr(thr, heap, hdr);\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n}\n\nDUK_LOCAL void duk__debug_dump_strtab(duk_hthread *thr, duk_heap *heap) {\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\n\tfor (i = 0; i < heap->st_size; i++) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\th = DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, heap->strtable16[i]);\n#else\n\t\th = heap->strtable[i];\n#endif\n\t\twhile (h != NULL) {\n\t\t\tduk__debug_dump_heaphdr(thr, heap, (duk_heaphdr *) h);\n\t\t\th = h->hdr.h_next;\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__debug_handle_dump_heap(duk_hthread *thr, duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"debug command DumpHeap\"));\n\n\tduk_debug_write_reply(thr);\n\tduk__debug_dump_heap_allocated(thr, heap);\n\tduk__debug_dump_strtab(thr, heap);\n\tduk_debug_write_eom(thr);\n}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP */\n\nDUK_LOCAL void duk__debug_handle_get_bytecode(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hcompfunc *fun = NULL;\n\tduk_size_t i, n;\n\tduk_tval *tv;\n\tduk_hobject **fn;\n\tduk_int32_t level = -1;\n\tduk_uint8_t ibyte;\n\n\tDUK_UNREF(heap);\n\n\tDUK_D(DUK_DPRINT(\"debug command GetBytecode\"));\n\n\tibyte = duk_debug_peek_byte(thr);\n\tif (ibyte != DUK_DBG_IB_EOM) {\n\t\ttv = duk_debug_read_tval(thr);\n\t\tif (tv == NULL) {\n\t\t\t/* detached */\n\t\t\treturn;\n\t\t}\n\t\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\t\t/* tentative, checked later */\n\t\t\tfun = (duk_hcompfunc *) DUK_TVAL_GET_OBJECT(tv);\n\t\t\tDUK_ASSERT(fun != NULL);\n\t\t} else if (DUK_TVAL_IS_NUMBER(tv)) {\n\t\t\tlevel = (duk_int32_t) DUK_TVAL_GET_NUMBER(tv);\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"invalid argument to GetBytecode: %!T\", tv));\n\t\t\tgoto fail_args;\n\t\t}\n\t}\n\n\tif (fun == NULL) {\n\t\tact = duk_hthread_get_activation_for_level(thr, level);\n\t\tif (act == NULL) {\n\t\t\tgoto fail_index;\n\t\t}\n\t\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\t}\n\n\tif (fun == NULL || !DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun)) {\n\t\tDUK_D(DUK_DPRINT(\"invalid argument to GetBytecode: %!O\", fun));\n\t\tgoto fail_args;\n\t}\n\tDUK_ASSERT(fun != NULL && DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun));\n\n\tduk_debug_write_reply(thr);\n\tn = DUK_HCOMPFUNC_GET_CONSTS_COUNT(heap, fun);\n\tduk_debug_write_int(thr, (duk_int32_t) n);\n\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, fun);\n\tfor (i = 0; i < n; i++) {\n\t\tduk_debug_write_tval(thr, tv);\n\t\ttv++;\n\t}\n\tn = DUK_HCOMPFUNC_GET_FUNCS_COUNT(heap, fun);\n\tduk_debug_write_int(thr, (duk_int32_t) n);\n\tfn = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, fun);\n\tfor (i = 0; i < n; i++) {\n\t\tduk_debug_write_hobject(thr, *fn);\n\t\tfn++;\n\t}\n\tduk_debug_write_string(thr,\n\t                       (const char *) DUK_HCOMPFUNC_GET_CODE_BASE(heap, fun),\n\t                       (duk_size_t) DUK_HCOMPFUNC_GET_CODE_SIZE(heap, fun));\n\tduk_debug_write_eom(thr);\n\treturn;\n\n fail_args:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid argument\");\n\treturn;\n\n fail_index:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid callstack index\");\n\treturn;\n}\n\n/*\n *  Object inspection commands: GetHeapObjInfo, GetObjPropDesc,\n *  GetObjPropDescRange\n */\n\n#if defined(DUK_USE_DEBUGGER_INSPECT)\n\n#if 0 /* pruned */\nDUK_LOCAL const char * const duk__debug_getinfo_heaphdr_keys[] = {\n\t\"reachable\",\n\t\"temproot\",\n\t\"finalizable\",\n\t\"finalized\",\n\t\"readonly\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_heaphdr_masks[] = {\n\tDUK_HEAPHDR_FLAG_REACHABLE,\n\tDUK_HEAPHDR_FLAG_TEMPROOT,\n\tDUK_HEAPHDR_FLAG_FINALIZABLE,\n\tDUK_HEAPHDR_FLAG_FINALIZED,\n\tDUK_HEAPHDR_FLAG_READONLY,\n\t0  /* terminator */\n};\n#endif\nDUK_LOCAL const char * const duk__debug_getinfo_hstring_keys[] = {\n#if 0\n\t\"arridx\",\n\t\"symbol\",\n\t\"hidden\",\n\t\"reserved_word\",\n\t\"strict_reserved_word\",\n\t\"eval_or_arguments\",\n#endif\n\t\"extdata\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_hstring_masks[] = {\n#if 0\n\tDUK_HSTRING_FLAG_ARRIDX,\n\tDUK_HSTRING_FLAG_SYMBOL,\n\tDUK_HSTRING_FLAG_HIDDEN,\n\tDUK_HSTRING_FLAG_RESERVED_WORD,\n\tDUK_HSTRING_FLAG_STRICT_RESERVED_WORD,\n\tDUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS,\n#endif\n\tDUK_HSTRING_FLAG_EXTDATA,\n\t0  /* terminator */\n};\nDUK_LOCAL const char * const duk__debug_getinfo_hobject_keys[] = {\n\t\"extensible\",\n\t\"constructable\",\n\t\"callable\",\n\t\"boundfunc\",\n\t\"compfunc\",\n\t\"natfunc\",\n\t\"bufobj\",\n\t\"fastrefs\",\n\t\"array_part\",\n\t\"strict\",\n\t\"notail\",\n\t\"newenv\",\n\t\"namebinding\",\n\t\"createargs\",\n\t\"have_finalizer\",\n\t\"exotic_array\",\n\t\"exotic_stringobj\",\n\t\"exotic_arguments\",\n\t\"exotic_proxyobj\",\n\t\"special_call\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_hobject_masks[] = {\n\tDUK_HOBJECT_FLAG_EXTENSIBLE,\n\tDUK_HOBJECT_FLAG_CONSTRUCTABLE,\n\tDUK_HOBJECT_FLAG_CALLABLE,\n\tDUK_HOBJECT_FLAG_BOUNDFUNC,\n\tDUK_HOBJECT_FLAG_COMPFUNC,\n\tDUK_HOBJECT_FLAG_NATFUNC,\n\tDUK_HOBJECT_FLAG_BUFOBJ,\n\tDUK_HOBJECT_FLAG_FASTREFS,\n\tDUK_HOBJECT_FLAG_ARRAY_PART,\n\tDUK_HOBJECT_FLAG_STRICT,\n\tDUK_HOBJECT_FLAG_NOTAIL,\n\tDUK_HOBJECT_FLAG_NEWENV,\n\tDUK_HOBJECT_FLAG_NAMEBINDING,\n\tDUK_HOBJECT_FLAG_CREATEARGS,\n\tDUK_HOBJECT_FLAG_HAVE_FINALIZER,\n\tDUK_HOBJECT_FLAG_EXOTIC_ARRAY,\n\tDUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ,\n\tDUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS,\n\tDUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ,\n\tDUK_HOBJECT_FLAG_SPECIAL_CALL,\n\t0  /* terminator */\n};\nDUK_LOCAL const char * const duk__debug_getinfo_hbuffer_keys[] = {\n\t\"dynamic\",\n\t\"external\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_hbuffer_masks[] = {\n\tDUK_HBUFFER_FLAG_DYNAMIC,\n\tDUK_HBUFFER_FLAG_EXTERNAL,\n\t0  /* terminator */\n};\n\nDUK_LOCAL void duk__debug_getinfo_flags_key(duk_hthread *thr, const char *key) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n}\n\nDUK_LOCAL void duk__debug_getinfo_prop_uint(duk_hthread *thr, const char *key, duk_uint_t val) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n\tduk_debug_write_uint(thr, val);\n}\n\nDUK_LOCAL void duk__debug_getinfo_prop_int(duk_hthread *thr, const char *key, duk_int_t val) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n\tduk_debug_write_int(thr, val);\n}\n\nDUK_LOCAL void duk__debug_getinfo_prop_bool(duk_hthread *thr, const char *key, duk_bool_t val) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n\tduk_debug_write_boolean(thr, val);\n}\n\nDUK_LOCAL void duk__debug_getinfo_bitmask(duk_hthread *thr, const char * const * keys, duk_uint_t *masks, duk_uint_t flags) {\n\tconst char *key;\n\tduk_uint_t mask;\n\n\tfor (;;) {\n\t\tmask = *masks++;\n\t\tif (mask == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tkey = *keys++;\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tDUK_DD(DUK_DDPRINT(\"inspect bitmask: key=%s, mask=0x%08lx, flags=0x%08lx\", key, (unsigned long) mask, (unsigned long) flags));\n\t\tduk__debug_getinfo_prop_bool(thr, key, flags & mask);\n\t}\n}\n\n/* Inspect a property using a virtual index into a conceptual property list\n * consisting of (1) all array part items from [0,a_size[ (even when above\n * .length) and (2) all entry part items from [0,e_next[.  Unused slots are\n * indicated using dvalue 'unused'.\n */\nDUK_LOCAL duk_bool_t duk__debug_getprop_index(duk_hthread *thr, duk_heap *heap, duk_hobject *h_obj, duk_uint_t idx) {\n\tduk_uint_t a_size;\n\tduk_tval *tv;\n\tduk_hstring *h_key;\n\tduk_hobject *h_getset;\n\tduk_uint_t flags;\n\n\tDUK_UNREF(heap);\n\n\ta_size = DUK_HOBJECT_GET_ASIZE(h_obj);\n\tif (idx < a_size) {\n\t\tduk_debug_write_uint(thr, DUK_PROPDESC_FLAGS_WEC);\n\t\tduk_debug_write_uint(thr, idx);\n\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(heap, h_obj, idx);\n\t\tduk_debug_write_tval(thr, tv);\n\t\treturn 1;\n\t}\n\n\tidx -= a_size;\n\tif (idx >= DUK_HOBJECT_GET_ENEXT(h_obj)) {\n\t\treturn 0;\n\t}\n\n\th_key = DUK_HOBJECT_E_GET_KEY(heap, h_obj, idx);\n\tif (h_key == NULL) {\n\t\tduk_debug_write_uint(thr, 0);\n\t\tduk_debug_write_null(thr);\n\t\tduk_debug_write_unused(thr);\n\t\treturn 1;\n\t}\n\n\tflags = DUK_HOBJECT_E_GET_FLAGS(heap, h_obj, idx);\n\tif (DUK_HSTRING_HAS_SYMBOL(h_key)) {\n\t\tflags |= DUK_DBG_PROPFLAG_SYMBOL;\n\t}\n\tif (DUK_HSTRING_HAS_HIDDEN(h_key)) {\n\t\tflags |= DUK_DBG_PROPFLAG_HIDDEN;\n\t}\n\tduk_debug_write_uint(thr, flags);\n\tduk_debug_write_hstring(thr, h_key);\n\tif (flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\th_getset = DUK_HOBJECT_E_GET_VALUE_GETTER(heap, h_obj, idx);\n\t\tif (h_getset) {\n\t\t\tduk_debug_write_hobject(thr, h_getset);\n\t\t} else {\n\t\t\tduk_debug_write_null(thr);\n\t\t}\n\t\th_getset = DUK_HOBJECT_E_GET_VALUE_SETTER(heap, h_obj, idx);\n\t\tif (h_getset) {\n\t\t\tduk_debug_write_hobject(thr, h_getset);\n\t\t} else {\n\t\t\tduk_debug_write_null(thr);\n\t\t}\n\t} else {\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, h_obj, idx);\n\t\tduk_debug_write_tval(thr, tv);\n\t}\n\treturn 1;\n}\n\nDUK_LOCAL void duk__debug_handle_get_heap_obj_info(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *h;\n\n\tDUK_D(DUK_DPRINT(\"debug command GetHeapObjInfo\"));\n\tDUK_UNREF(heap);\n\n\tDUK_ASSERT(sizeof(duk__debug_getinfo_hstring_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hstring_masks) / sizeof(duk_uint_t) - 1);\n\tDUK_ASSERT(sizeof(duk__debug_getinfo_hobject_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hobject_masks) / sizeof(duk_uint_t) - 1);\n\tDUK_ASSERT(sizeof(duk__debug_getinfo_hbuffer_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hbuffer_masks) / sizeof(duk_uint_t) - 1);\n\n\th = duk_debug_read_any_ptr(thr);\n\tif (!h) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid target\");\n\t\treturn;\n\t}\n\n\tduk_debug_write_reply(thr);\n\n\t/* As with all inspection code, we rely on the debug client providing\n\t * a valid, non-stale pointer: there's no portable way to safely\n\t * validate the pointer here.\n\t */\n\n\tduk__debug_getinfo_flags_key(thr, \"heapptr\");\n\tduk_debug_write_heapptr(thr, h);\n\n\t/* XXX: comes out as signed now */\n\tduk__debug_getinfo_prop_uint(thr, \"heaphdr_flags\", (duk_uint_t) DUK_HEAPHDR_GET_FLAGS(h));\n\tduk__debug_getinfo_prop_uint(thr, \"heaphdr_type\", (duk_uint_t) DUK_HEAPHDR_GET_TYPE(h));\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__debug_getinfo_prop_uint(thr, \"refcount\", (duk_uint_t) DUK_HEAPHDR_GET_REFCOUNT(h));\n#endif\n#if 0 /* pruned */\n\tduk__debug_getinfo_bitmask(thr,\n\t                           duk__debug_getinfo_heaphdr_keys,\n\t                           duk__debug_getinfo_heaphdr_masks,\n\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n#endif\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h_str;\n\n\t\th_str = (duk_hstring *) h;\n\t\tduk__debug_getinfo_bitmask(thr,\n\t\t                           duk__debug_getinfo_hstring_keys,\n\t\t                           duk__debug_getinfo_hstring_masks,\n\t\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n\t\tduk__debug_getinfo_prop_uint(thr, \"bytelen\", (duk_uint_t) DUK_HSTRING_GET_BYTELEN(h_str));\n\t\tduk__debug_getinfo_prop_uint(thr, \"charlen\", (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h_str));\n\t\tduk__debug_getinfo_prop_uint(thr, \"hash\", (duk_uint_t) DUK_HSTRING_GET_HASH(h_str));\n\t\tduk__debug_getinfo_flags_key(thr, \"data\");\n\t\tduk_debug_write_hstring(thr, h_str);\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h_obj;\n\t\tduk_hobject *h_proto;\n\n\t\th_obj = (duk_hobject *) h;\n\t\th_proto = DUK_HOBJECT_GET_PROTOTYPE(heap, h_obj);\n\n\t\t/* duk_hobject specific fields. */\n\t\tduk__debug_getinfo_bitmask(thr,\n\t\t                           duk__debug_getinfo_hobject_keys,\n\t\t                           duk__debug_getinfo_hobject_masks,\n\t\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n\t\tduk__debug_getinfo_prop_uint(thr, \"class_number\", DUK_HOBJECT_GET_CLASS_NUMBER(h_obj));\n\t\tduk__debug_getinfo_flags_key(thr, \"class_name\");\n\t\tduk_debug_write_hstring(thr, DUK_HOBJECT_GET_CLASS_STRING(heap, h_obj));\n\t\tduk__debug_getinfo_flags_key(thr, \"prototype\");\n\t\tif (h_proto != NULL) {\n\t\t\tduk_debug_write_hobject(thr, h_proto);\n\t\t} else {\n\t\t\tduk_debug_write_null(thr);\n\t\t}\n\t\tduk__debug_getinfo_flags_key(thr, \"props\");\n\t\tduk_debug_write_pointer(thr, (void *) DUK_HOBJECT_GET_PROPS(heap, h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"e_size\", (duk_uint_t) DUK_HOBJECT_GET_ESIZE(h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"e_next\", (duk_uint_t) DUK_HOBJECT_GET_ENEXT(h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"a_size\", (duk_uint_t) DUK_HOBJECT_GET_ASIZE(h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"h_size\", (duk_uint_t) DUK_HOBJECT_GET_HSIZE(h_obj));\n\n\t\tif (DUK_HOBJECT_IS_ARRAY(h_obj)) {\n\t\t\tduk_harray *h_arr;\n\t\t\th_arr = (duk_harray *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"length\", (duk_uint_t) h_arr->length);\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"length_nonwritable\", h_arr->length_nonwritable);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_NATFUNC(h_obj)) {\n\t\t\tduk_hnatfunc *h_fun;\n\t\t\th_fun = (duk_hnatfunc *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_int(thr, \"nargs\", h_fun->nargs);\n\t\t\tduk__debug_getinfo_prop_int(thr, \"magic\", h_fun->magic);\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"varargs\", h_fun->magic == DUK_HNATFUNC_NARGS_VARARGS);\n\t\t\t/* Native function pointer may be different from a void pointer,\n\t\t\t * and we serialize it from memory directly now (no byte swapping etc).\n\t\t\t */\n\t\t\tduk__debug_getinfo_flags_key(thr, \"funcptr\");\n\t\t\tduk_debug_write_buffer(thr, (const char *) &h_fun->func, sizeof(h_fun->func));\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tduk_hcompfunc *h_fun;\n\t\t\tduk_hbuffer *h_buf;\n\t\t\tduk_hobject *h_lexenv;\n\t\t\tduk_hobject *h_varenv;\n\t\t\th_fun = (duk_hcompfunc *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_int(thr, \"nregs\", h_fun->nregs);\n\t\t\tduk__debug_getinfo_prop_int(thr, \"nargs\", h_fun->nargs);\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"lex_env\");\n\t\t\th_lexenv = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, h_fun);\n\t\t\tif (h_lexenv != NULL) {\n\t\t\t\tduk_debug_write_hobject(thr, h_lexenv);\n\t\t\t} else {\n\t\t\t\tduk_debug_write_null(thr);\n\t\t\t}\n\t\t\tduk__debug_getinfo_flags_key(thr, \"var_env\");\n\t\t\th_varenv = DUK_HCOMPFUNC_GET_VARENV(thr->heap, h_fun);\n\t\t\tif (h_varenv != NULL) {\n\t\t\t\tduk_debug_write_hobject(thr, h_varenv);\n\t\t\t} else {\n\t\t\t\tduk_debug_write_null(thr);\n\t\t\t}\n\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"start_line\", h_fun->start_line);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"end_line\", h_fun->end_line);\n\t\t\th_buf = (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(thr->heap, h_fun);\n\t\t\tif (h_buf != NULL) {\n\t\t\t\tduk__debug_getinfo_flags_key(thr, \"data\");\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) h_buf);\n\t\t\t}\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_BOUNDFUNC(h_obj)) {\n\t\t\tduk_hboundfunc *h_bfun;\n\t\t\th_bfun = (duk_hboundfunc *) (void *) h_obj;\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"target\");\n\t\t\tduk_debug_write_tval(thr, &h_bfun->target);\n\t\t\tduk__debug_getinfo_flags_key(thr, \"this_binding\");\n\t\t\tduk_debug_write_tval(thr, &h_bfun->this_binding);\n\t\t\tduk__debug_getinfo_flags_key(thr, \"nargs\");\n\t\t\tduk_debug_write_int(thr, h_bfun->nargs);\n\t\t\t/* h_bfun->args not exposed now */\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_THREAD(h_obj)) {\n\t\t\t/* XXX: Currently no inspection of threads, e.g. value stack, call\n\t\t\t * stack, catch stack, etc.\n\t\t\t */\n\t\t\tduk_hthread *h_thr;\n\t\t\th_thr = (duk_hthread *) h_obj;\n\t\t\tDUK_UNREF(h_thr);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_DECENV(h_obj)) {\n\t\t\tduk_hdecenv *h_env;\n\t\t\th_env = (duk_hdecenv *) h_obj;\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"thread\");\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->thread));\n\t\t\tduk__debug_getinfo_flags_key(thr, \"varmap\");\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->varmap));\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"regbase\", (duk_uint_t) h_env->regbase_byteoff);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_OBJENV(h_obj)) {\n\t\t\tduk_hobjenv *h_env;\n\t\t\th_env = (duk_hobjenv *) h_obj;\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"target\");\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->target));\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"has_this\", h_env->has_this);\n\t\t}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\tduk_hbufobj *h_bufobj;\n\t\t\th_bufobj = (duk_hbufobj *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"slice_offset\", h_bufobj->offset);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"slice_length\", h_bufobj->length);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"elem_shift\", (duk_uint_t) h_bufobj->shift);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"elem_type\", (duk_uint_t) h_bufobj->elem_type);\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"is_typedarray\", (duk_uint_t) h_bufobj->is_typedarray);\n\t\t\tif (h_bufobj->buf != NULL) {\n\t\t\t\tduk__debug_getinfo_flags_key(thr, \"buffer\");\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) h_bufobj->buf);\n\t\t\t}\n\t\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h_buf;\n\n\t\th_buf = (duk_hbuffer *) h;\n\t\tduk__debug_getinfo_bitmask(thr,\n\t\t                           duk__debug_getinfo_hbuffer_keys,\n\t\t                           duk__debug_getinfo_hbuffer_masks,\n\t\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n\t\tduk__debug_getinfo_prop_uint(thr, \"size\", (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_buf));\n\t\tduk__debug_getinfo_flags_key(thr, \"dataptr\");\n\t\tduk_debug_write_pointer(thr, (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_buf));\n\t\tduk__debug_getinfo_flags_key(thr, \"data\");\n\t\tduk_debug_write_hbuffer(thr, h_buf);  /* tolerates NULL h_buf */\n\t\tbreak;\n\t}\n\tdefault: {\n\t\t/* Since we already started writing the reply, just emit nothing. */\n\t\tDUK_D(DUK_DPRINT(\"inspect target pointer has invalid heaphdr type\"));\n\t}\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_get_obj_prop_desc(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *h;\n\tduk_hobject *h_obj;\n\tduk_hstring *h_key;\n\tduk_propdesc desc;\n\n\tDUK_D(DUK_DPRINT(\"debug command GetObjPropDesc\"));\n\tDUK_UNREF(heap);\n\n\th = duk_debug_read_any_ptr(thr);\n\tif (!h) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid target\");\n\t\treturn;\n\t}\n\th_key = duk_debug_read_hstring(thr);\n\tif (h == NULL || DUK_HEAPHDR_GET_TYPE(h) != DUK_HTYPE_OBJECT || h_key == NULL) {\n\t\tgoto fail_args;\n\t}\n\th_obj = (duk_hobject *) h;\n\n\tif (duk_hobject_get_own_propdesc(thr, h_obj, h_key, &desc, 0 /*flags*/)) {\n\t\tduk_int_t virtual_idx;\n\t\tduk_bool_t rc;\n\n\t\t/* To use the shared helper need the virtual index. */\n\t\tDUK_ASSERT(desc.e_idx >= 0 || desc.a_idx >= 0);\n\t\tvirtual_idx = (desc.a_idx >= 0 ? desc.a_idx :\n\t\t               (duk_int_t) DUK_HOBJECT_GET_ASIZE(h_obj) + desc.e_idx);\n\n\t\tduk_debug_write_reply(thr);\n\t\trc = duk__debug_getprop_index(thr, heap, h_obj, (duk_uint_t) virtual_idx);\n\t\tDUK_ASSERT(rc == 1);\n\t\tDUK_UNREF(rc);\n\t\tduk_debug_write_eom(thr);\n\t} else {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"not found\");\n\t}\n\treturn;\n\n fail_args:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid args\");\n}\n\nDUK_LOCAL void duk__debug_handle_get_obj_prop_desc_range(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *h;\n\tduk_hobject *h_obj;\n\tduk_uint_t idx, idx_start, idx_end;\n\n\tDUK_D(DUK_DPRINT(\"debug command GetObjPropDescRange\"));\n\tDUK_UNREF(heap);\n\n\th = duk_debug_read_any_ptr(thr);\n\tidx_start = (duk_uint_t) duk_debug_read_int(thr);\n\tidx_end = (duk_uint_t) duk_debug_read_int(thr);\n\tif (h == NULL || DUK_HEAPHDR_GET_TYPE(h) != DUK_HTYPE_OBJECT) {\n\t\tgoto fail_args;\n\t}\n\th_obj = (duk_hobject *) h;\n\n\t/* The index range space is conceptually the array part followed by the\n\t * entry part.  Unlike normal enumeration all slots are exposed here as\n\t * is and return 'unused' if the slots are not in active use.  In particular\n\t * the array part is included for the full a_size regardless of what the\n\t * array .length is.\n\t */\n\n\tduk_debug_write_reply(thr);\n\tfor (idx = idx_start; idx < idx_end; idx++) {\n\t\tif (!duk__debug_getprop_index(thr, heap, h_obj, idx)) {\n\t\t\tbreak;\n\t\t}\n\t}\n\tduk_debug_write_eom(thr);\n\treturn;\n\n fail_args:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid args\");\n}\n\n#endif  /* DUK_USE_DEBUGGER_INSPECT */\n\n/*\n *  Process incoming debug requests\n *\n *  Individual request handlers can push temporaries on the value stack and\n *  rely on duk__debug_process_message() to restore the value stack top\n *  automatically.\n */\n\n/* Process one debug message.  Automatically restore value stack top to its\n * entry value, so that individual message handlers don't need exact value\n * stack handling which is convenient.\n */\nDUK_LOCAL void duk__debug_process_message(duk_hthread *thr) {\n\tduk_heap *heap;\n\tduk_uint8_t x;\n\tduk_int32_t cmd;\n\tduk_idx_t entry_top;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tentry_top = duk_get_top(thr);\n\n\tx = duk_debug_read_byte(thr);\n\tswitch (x) {\n\tcase DUK_DBG_IB_REQUEST: {\n\t\tcmd = duk_debug_read_int(thr);\n\t\tswitch (cmd) {\n\t\tcase DUK_DBG_CMD_BASICINFO: {\n\t\t\tduk__debug_handle_basic_info(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_TRIGGERSTATUS: {\n\t\t\tduk__debug_handle_trigger_status(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_PAUSE: {\n\t\t\tduk__debug_handle_pause(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_RESUME: {\n\t\t\tduk__debug_handle_resume(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_STEPINTO:\n\t\tcase DUK_DBG_CMD_STEPOVER:\n\t\tcase DUK_DBG_CMD_STEPOUT: {\n\t\t\tduk__debug_handle_step(thr, heap, cmd);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_LISTBREAK: {\n\t\t\tduk__debug_handle_list_break(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_ADDBREAK: {\n\t\t\tduk__debug_handle_add_break(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_DELBREAK: {\n\t\t\tduk__debug_handle_del_break(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETVAR: {\n\t\t\tduk__debug_handle_get_var(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_PUTVAR: {\n\t\t\tduk__debug_handle_put_var(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETCALLSTACK: {\n\t\t\tduk__debug_handle_get_call_stack(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETLOCALS: {\n\t\t\tduk__debug_handle_get_locals(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_EVAL: {\n\t\t\tduk__debug_handle_eval(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_DETACH: {\n\t\t\t/* The actual detached_cb call is postponed to message loop so\n\t\t\t * we don't need any special precautions here (just skip to EOM\n\t\t\t * on the already closed connection).\n\t\t\t */\n\t\t\tduk__debug_handle_detach(thr, heap);\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP)\n\t\tcase DUK_DBG_CMD_DUMPHEAP: {\n\t\t\tduk__debug_handle_dump_heap(thr, heap);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP */\n\t\tcase DUK_DBG_CMD_GETBYTECODE: {\n\t\t\tduk__debug_handle_get_bytecode(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_APPREQUEST: {\n\t\t\tduk__debug_handle_apprequest(thr, heap);\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_DEBUGGER_INSPECT)\n\t\tcase DUK_DBG_CMD_GETHEAPOBJINFO: {\n\t\t\tduk__debug_handle_get_heap_obj_info(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETOBJPROPDESC: {\n\t\t\tduk__debug_handle_get_obj_prop_desc(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETOBJPROPDESCRANGE: {\n\t\t\tduk__debug_handle_get_obj_prop_desc_range(thr, heap);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_DEBUGGER_INSPECT */\n\t\tdefault: {\n\t\t\tDUK_D(DUK_DPRINT(\"debug command unsupported: %d\", (int) cmd));\n\t\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNSUPPORTED, \"unsupported command\");\n\t\t}\n\t\t}  /* switch cmd */\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_REPLY: {\n\t\tDUK_D(DUK_DPRINT(\"debug reply, skipping\"));\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_ERROR: {\n\t\tDUK_D(DUK_DPRINT(\"debug error, skipping\"));\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_NOTIFY: {\n\t\tDUK_D(DUK_DPRINT(\"debug notify, skipping\"));\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tDUK_D(DUK_DPRINT(\"invalid initial byte, drop connection: %d\", (int) x));\n\t\tgoto fail;\n\t}\n\t}  /* switch initial byte */\n\n\tDUK_ASSERT(duk_get_top(thr) >= entry_top);\n\tduk_set_top(thr, entry_top);\n\tduk__debug_skip_to_eom(thr);\n\treturn;\n\n fail:\n\tDUK_ASSERT(duk_get_top(thr) >= entry_top);\n\tduk_set_top(thr, entry_top);\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn;\n}\n\nDUK_LOCAL void duk__check_resend_status(duk_hthread *thr) {\n\tif (thr->heap->dbg_read_cb != NULL && thr->heap->dbg_state_dirty) {\n\t\tduk_debug_send_status(thr);\n\t\tthr->heap->dbg_state_dirty = 0;\n\t}\n}\n\nDUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t no_block) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top;\n#endif\n\tduk_bool_t retval = 0;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\n\tDUK_D(DUK_DPRINT(\"process debug messages: read_cb=%s, no_block=%ld, detaching=%ld, processing=%ld\",\n\t                 thr->heap->dbg_read_cb ? \"not NULL\" : \"NULL\", (long) no_block,\n\t                 (long) thr->heap->dbg_detaching, (long) thr->heap->dbg_processing));\n\tDUK_DD(DUK_DDPRINT(\"top at entry: %ld\", (long) duk_get_top(thr)));\n\n\t/* thr->heap->dbg_detaching may be != 0 if a debugger write outside\n\t * the message loop caused a transport error and detach1() to run.\n\t */\n\tDUK_ASSERT(thr->heap->dbg_detaching == 0 || thr->heap->dbg_detaching == 1);\n\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\tthr->heap->dbg_processing = 1;\n\n\t/* Ensure dirty state causes a Status even if never process any\n\t * messages.  This is expected by the bytecode executor when in\n\t * the running state.\n\t */\n\tduk__check_resend_status(thr);\n\n\tfor (;;) {\n\t\t/* Process messages until we're no longer paused or we peek\n\t\t * and see there's nothing to read right now.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"top at loop top: %ld\", (long) duk_get_top(thr)));\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 1);\n\n\t\twhile (thr->heap->dbg_read_cb == NULL && thr->heap->dbg_detaching) {\n\t\t\t/* Detach is pending; can be triggered from outside the\n\t\t\t * debugger loop (e.g. Status notify write error) or by\n\t\t\t * previous message handling.  Call detached callback\n\t\t\t * here, in a controlled state, to ensure a possible\n\t\t\t * reattach inside the detached_cb is handled correctly.\n\t\t\t *\n\t\t\t * Recheck for detach in a while loop: an immediate\n\t\t\t * reattach involves a call to duk_debugger_attach()\n\t\t\t * which writes a debugger handshake line immediately\n\t\t\t * inside the API call.  If the transport write fails\n\t\t\t * for that handshake, we can immediately end up in a\n\t\t\t * \"transport broken, detaching\" case several times here.\n\t\t\t * Loop back until we're either cleanly attached or\n\t\t\t * fully detached.\n\t\t\t *\n\t\t\t * NOTE: Reset dbg_processing = 1 forcibly, in case we\n\t\t\t * re-attached; duk_debugger_attach() sets dbg_processing\n\t\t\t * to 0 at the moment.\n\t\t\t */\n\n\t\t\tDUK_D(DUK_DPRINT(\"detach pending (dbg_read_cb == NULL, dbg_detaching != 0), call detach2\"));\n\n\t\t\tduk__debug_do_detach2(thr->heap);\n\t\t\tthr->heap->dbg_processing = 1;  /* may be set to 0 by duk_debugger_attach() inside callback */\n\n\t\t\tDUK_D(DUK_DPRINT(\"after detach2 (and possible reattach): dbg_read_cb=%s, dbg_detaching=%ld\",\n\t\t\t                 thr->heap->dbg_read_cb ? \"not NULL\" : \"NULL\", (long) thr->heap->dbg_detaching));\n\t\t}\n\t\tDUK_ASSERT(thr->heap->dbg_detaching == 0);  /* true even with reattach */\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 1);  /* even after a detach and possible reattach */\n\n\t\tif (thr->heap->dbg_read_cb == NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"debug connection broken (and not detaching), stop processing messages\"));\n\t\t\tbreak;\n\t\t}\n\n\t\tif (!DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || no_block) {\n\t\t\tif (!duk_debug_read_peek(thr)) {\n\t\t\t\t/* Note: peek cannot currently trigger a detach\n\t\t\t\t * so the dbg_detaching == 0 assert outside the\n\t\t\t\t * loop is correct.\n\t\t\t\t */\n\t\t\t\tDUK_D(DUK_DPRINT(\"processing debug message, peek indicated no data, stop processing messages\"));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_D(DUK_DPRINT(\"processing debug message, peek indicated there is data, handle it\"));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"paused, process debug message, blocking if necessary\"));\n\t\t}\n\n\t\tduk__check_resend_status(thr);\n\t\tduk__debug_process_message(thr);\n\t\tduk__check_resend_status(thr);\n\n\t\tretval = 1;  /* processed one or more messages */\n\t}\n\n\tDUK_ASSERT(thr->heap->dbg_detaching == 0);\n\tDUK_ASSERT(thr->heap->dbg_processing == 1);\n\tthr->heap->dbg_processing = 0;\n\n\t/* As an initial implementation, read flush after exiting the message\n\t * loop.  If transport is broken, this is a no-op (with debug logs).\n\t */\n\tduk_debug_read_flush(thr);  /* this cannot initiate a detach */\n\tDUK_ASSERT(thr->heap->dbg_detaching == 0);\n\n\tDUK_DD(DUK_DDPRINT(\"top at exit: %ld\", (long) duk_get_top(thr)));\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Easy to get wrong, so assert for it. */\n\tDUK_ASSERT(entry_top == duk_get_top(thr));\n#endif\n\n\treturn retval;\n}\n\n/*\n *  Halt execution helper\n */\n\n/* Halt execution and enter a debugger message loop until execution is resumed\n * by the client.  PC for the current activation may be temporarily decremented\n * so that the \"current\" instruction will be shown by the client.  This helper\n * is callable from anywhere, also outside bytecode executor.\n */\n\nDUK_INTERNAL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev_pc) {\n\tduk_activation *act;\n\tduk_hcompfunc *fun;\n\tduk_instr_t *old_pc = NULL;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(duk_debug_is_attached(thr->heap));\n\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\tDUK_ASSERT(!duk_debug_is_paused(thr->heap));\n\n\tduk_debug_set_paused(thr->heap);\n\n\tact = thr->callstack_curr;\n\n\t/* NOTE: act may be NULL if an error is thrown outside of any activation,\n\t * which may happen in the case of, e.g. syntax errors.\n\t */\n\n\t/* Decrement PC if that was requested, this requires a PC sync. */\n\tif (act != NULL) {\n\t\tduk_hthread_sync_currpc(thr);\n\t\told_pc = act->curr_pc;\n\t\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\n\t\t/* Short circuit if is safe: if act->curr_pc != NULL, 'fun' is\n\t\t * guaranteed to be a non-NULL ECMAScript function.\n\t\t */\n\t\tDUK_ASSERT(act->curr_pc == NULL ||\n\t\t           (fun != NULL && DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun)));\n\t\tif (use_prev_pc &&\n\t\t    act->curr_pc != NULL &&\n\t\t    act->curr_pc > DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, fun)) {\n\t\t\tact->curr_pc--;\n\t\t}\n\t}\n\n\t/* Process debug messages until we are no longer paused. */\n\n\t/* NOTE: This is a bit fragile.  It's important to ensure that\n\t * duk_debug_process_messages() never throws an error or\n\t * act->curr_pc will never be reset.\n\t */\n\n\tthr->heap->dbg_state_dirty = 1;\n\twhile (DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap)) {\n\t\tDUK_ASSERT(duk_debug_is_attached(thr->heap));\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\t\tduk_debug_process_messages(thr, 0 /*no_block*/);\n\t}\n\n\t/* XXX: Decrementing and restoring act->curr_pc works now, but if the\n\t * debugger message loop gains the ability to adjust the current PC\n\t * (e.g. a forced jump) restoring the PC here will break.  Another\n\t * approach would be to use a state flag for the \"decrement 1 from\n\t * topmost activation's PC\" and take it into account whenever dealing\n\t * with PC values.\n\t */\n\tif (act != NULL) {\n\t\tact->curr_pc = old_pc;  /* restore PC */\n\t}\n}\n\n/*\n *  Breakpoint management\n */\n\nDUK_INTERNAL duk_small_int_t duk_debug_add_breakpoint(duk_hthread *thr, duk_hstring *filename, duk_uint32_t line) {\n\tduk_heap *heap;\n\tduk_breakpoint *b;\n\n\t/* Caller must trigger recomputation of active breakpoint list.  To\n\t * ensure stale values are not used if that doesn't happen, clear the\n\t * active breakpoint list here.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(filename != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_breakpoint_count >= DUK_HEAP_MAX_BREAKPOINTS) {\n\t\tDUK_D(DUK_DPRINT(\"failed to add breakpoint for %O:%ld, all breakpoint slots used\",\n\t\t                 (duk_heaphdr *) filename, (long) line));\n\t\treturn -1;\n\t}\n\theap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;\n\tb = heap->dbg_breakpoints + (heap->dbg_breakpoint_count++);\n\tb->filename = filename;\n\tb->line = line;\n\tDUK_HSTRING_INCREF(thr, filename);\n\n\treturn (duk_small_int_t) (heap->dbg_breakpoint_count - 1);  /* index */\n}\n\nDUK_INTERNAL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_small_uint_t breakpoint_index) {\n\tduk_heap *heap;\n\tduk_hstring *h;\n\tduk_breakpoint *b;\n\tduk_size_t move_size;\n\n\t/* Caller must trigger recomputation of active breakpoint list.  To\n\t * ensure stale values are not used if that doesn't happen, clear the\n\t * active breakpoint list here.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(duk_debug_is_attached(thr->heap));\n\tDUK_ASSERT_DISABLE(breakpoint_index >= 0);  /* unsigned */\n\n\tif (breakpoint_index >= heap->dbg_breakpoint_count) {\n\t\tDUK_D(DUK_DPRINT(\"invalid breakpoint index: %ld\", (long) breakpoint_index));\n\t\treturn 0;\n\t}\n\tb = heap->dbg_breakpoints + breakpoint_index;\n\n\th = b->filename;\n\tDUK_ASSERT(h != NULL);\n\n\tmove_size = sizeof(duk_breakpoint) * (heap->dbg_breakpoint_count - breakpoint_index - 1);\n\tduk_memmove((void *) b,\n\t            (const void *) (b + 1),\n\t            (size_t) move_size);\n\n\theap->dbg_breakpoint_count--;\n\theap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;\n\n\tDUK_HSTRING_DECREF(thr, h);  /* side effects */\n\tDUK_UNREF(h);  /* w/o refcounting */\n\n\t/* Breakpoint entries above the used area are left as garbage. */\n\n\treturn 1;\n}\n\n/*\n *  Misc state management\n */\n\nDUK_INTERNAL duk_bool_t duk_debug_is_attached(duk_heap *heap) {\n\treturn (heap->dbg_read_cb != NULL);\n}\n\nDUK_INTERNAL duk_bool_t duk_debug_is_paused(duk_heap *heap) {\n\treturn (DUK_HEAP_HAS_DEBUGGER_PAUSED(heap) != 0);\n}\n\nDUK_INTERNAL void duk_debug_set_paused(duk_heap *heap) {\n\tif (duk_debug_is_paused(heap)) {\n\t\tDUK_D(DUK_DPRINT(\"trying to set paused state when already paused, ignoring\"));\n\t} else {\n\t\tDUK_HEAP_SET_DEBUGGER_PAUSED(heap);\n\t\theap->dbg_state_dirty = 1;\n\t\tduk_debug_clear_pause_state(heap);\n\t\tDUK_ASSERT(heap->ms_running == 0);  /* debugger can't be triggered within mark-and-sweep */\n\t\theap->ms_running = 2;  /* prevent mark-and-sweep, prevent refzero queueing */\n\t\theap->ms_prevent_count++;\n\t\tDUK_ASSERT(heap->ms_prevent_count != 0);  /* Wrap. */\n\t\tDUK_ASSERT(heap->heap_thread != NULL);\n\t}\n}\n\nDUK_INTERNAL void duk_debug_clear_paused(duk_heap *heap) {\n\tif (duk_debug_is_paused(heap)) {\n\t\tDUK_HEAP_CLEAR_DEBUGGER_PAUSED(heap);\n\t\theap->dbg_state_dirty = 1;\n\t\tduk_debug_clear_pause_state(heap);\n\t\tDUK_ASSERT(heap->ms_running == 2);\n\t\tDUK_ASSERT(heap->ms_prevent_count > 0);\n\t\theap->ms_prevent_count--;\n\t\theap->ms_running = 0;\n\t\tDUK_ASSERT(heap->heap_thread != NULL);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"trying to clear paused state when not paused, ignoring\"));\n\t}\n}\n\nDUK_INTERNAL void duk_debug_clear_pause_state(duk_heap *heap) {\n\theap->dbg_pause_flags = 0;\n\theap->dbg_pause_act = NULL;\n\theap->dbg_pause_startline = 0;\n}\n\n#else  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/* No debugger support. */\n\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/* automatic undefs */\n#undef DUK__DBG_TPORT_ENTER\n#undef DUK__DBG_TPORT_EXIT\n#undef DUK__SET_CONN_BROKEN\n#line 1 \"duk_error_augment.c\"\n/*\n *  Augmenting errors at their creation site and their throw site.\n *\n *  When errors are created, traceback data is added by built-in code\n *  and a user error handler (if defined) can process or replace the\n *  error.  Similarly, when errors are thrown, a user error handler\n *  (if defined) can process or replace the error.\n *\n *  Augmentation and other processing at error creation time is nice\n *  because an error is only created once, but it may be thrown and\n *  rethrown multiple times.  User error handler registered for processing\n *  an error at its throw site must be careful to handle rethrowing in\n *  a useful manner.\n *\n *  Error augmentation may throw an internal error (e.g. alloc error).\n *\n *  ECMAScript allows throwing any values, so all values cannot be\n *  augmented.  Currently, the built-in augmentation at error creation\n *  only augments error values which are Error instances (= have the\n *  built-in Error.prototype in their prototype chain) and are also\n *  extensible.  User error handlers have no limitations in this respect.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Helper for calling a user error handler.\n *\n *  'thr' must be the currently active thread; the error handler is called\n *  in its context.  The valstack of 'thr' must have the error value on\n *  top, and will be replaced by another error value based on the return\n *  value of the error handler.\n *\n *  The helper calls duk_handle_call() recursively in protected mode.\n *  Before that call happens, no longjmps should happen; as a consequence,\n *  we must assume that the valstack contains enough temporary space for\n *  arguments and such.\n *\n *  While the error handler runs, any errors thrown will not trigger a\n *  recursive error handler call (this is implemented using a heap level\n *  flag which will \"follow\" through any coroutines resumed inside the\n *  error handler).  If the error handler is not callable or throws an\n *  error, the resulting error replaces the original error (for Duktape\n *  internal errors, duk_error_throw.c further substitutes this error with\n *  a DoubleError which is not ideal).  This would be easy to change and\n *  even signal to the caller.\n *\n *  The user error handler is stored in 'Duktape.errCreate' or\n *  'Duktape.errThrow' depending on whether we're augmenting the error at\n *  creation or throw time.  There are several alternatives to this approach,\n *  see doc/error-objects.rst for discussion.\n *\n *  Note: since further longjmp()s may occur while calling the error handler\n *  (for many reasons, e.g. a labeled 'break' inside the handler), the\n *  caller can make no assumptions on the thr->heap->lj state after the\n *  call (this affects especially duk_error_throw.c).  This is not an issue\n *  as long as the caller writes to the lj state only after the error handler\n *  finishes.\n */\n\n#if defined(DUK_USE_ERRTHROW) || defined(DUK_USE_ERRCREATE)\nDUK_LOCAL void duk__err_augment_user(duk_hthread *thr, duk_small_uint_t stridx_cb) {\n\tduk_tval *tv_hnd;\n\tduk_int_t rc;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT_STRIDX_VALID(stridx_cb);\n\n\tif (thr->heap->augmenting_error) {\n\t\tDUK_D(DUK_DPRINT(\"recursive call to error augmentation, ignore\"));\n\t\treturn;\n\t}\n\n\t/*\n\t *  Check whether or not we have an error handler.\n\t *\n\t *  We must be careful of not triggering an error when looking up the\n\t *  property.  For instance, if the property is a getter, we don't want\n\t *  to call it, only plain values are allowed.  The value, if it exists,\n\t *  is not checked.  If the value is not a function, a TypeError happens\n\t *  when it is called and that error replaces the original one.\n\t */\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, 4);  /* 3 entries actually needed below */\n\n\t/* [ ... errval ] */\n\n\tif (thr->builtins[DUK_BIDX_DUKTAPE] == NULL) {\n\t\t/* When creating built-ins, some of the built-ins may not be set\n\t\t * and we want to tolerate that when throwing errors.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"error occurred when DUK_BIDX_DUKTAPE is NULL, ignoring\"));\n\t\treturn;\n\t}\n\ttv_hnd = duk_hobject_find_entry_tval_ptr_stridx(thr->heap,\n\t                                                thr->builtins[DUK_BIDX_DUKTAPE],\n\t                                                stridx_cb);\n\tif (tv_hnd == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"error handler does not exist or is not a plain value: %!T\",\n\t\t                   (duk_tval *) tv_hnd));\n\t\treturn;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"error handler dump (callability not checked): %!T\",\n\t                     (duk_tval *) tv_hnd));\n\tduk_push_tval(thr, tv_hnd);\n\n\t/* [ ... errval errhandler ] */\n\n\tduk_insert(thr, -2);  /* -> [ ... errhandler errval ] */\n\tduk_push_undefined(thr);\n\tduk_insert(thr, -2);  /* -> [ ... errhandler undefined(= this) errval ] */\n\n\t/* [ ... errhandler undefined errval ] */\n\n\t/*\n\t *  heap->augmenting_error prevents recursive re-entry and also causes\n\t *  call handling to use a larger (but not unbounded) call stack limit\n\t *  for the duration of error augmentation.\n\t *\n\t *  We ignore errors now: a success return and an error value both\n\t *  replace the original error value.  (This would be easy to change.)\n\t */\n\n\tDUK_ASSERT(thr->heap->augmenting_error == 0);\n\tthr->heap->augmenting_error = 1;\n\n\trc = duk_pcall_method(thr, 1);\n\tDUK_UNREF(rc);  /* no need to check now: both success and error are OK */\n\n\tDUK_ASSERT(thr->heap->augmenting_error == 1);\n\tthr->heap->augmenting_error = 0;\n\n\t/* [ ... errval ] */\n}\n#endif  /* DUK_USE_ERRTHROW || DUK_USE_ERRCREATE */\n\n/*\n *  Add ._Tracedata to an error on the stack top.\n */\n\n#if defined(DUK_USE_TRACEBACKS)\nDUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {\n\tduk_activation *act;\n\tduk_int_t depth;\n\tduk_int_t arr_size;\n\tduk_tval *tv;\n\tduk_hstring *s;\n\tduk_uint32_t u32;\n\tduk_double_t d;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr_callstack != NULL);\n\n\t/* [ ... error ] */\n\n\t/*\n\t *  The traceback format is pretty arcane in an attempt to keep it compact\n\t *  and cheap to create.  It may change arbitrarily from version to version.\n\t *  It should be decoded/accessed through version specific accessors only.\n\t *\n\t *  See doc/error-objects.rst.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"adding traceback to object: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* Preallocate array to correct size, so that we can just write out\n\t * the _Tracedata values into the array part.\n\t */\n\tact = thr->callstack_curr;\n\tdepth = DUK_USE_TRACEBACK_DEPTH;\n\tDUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX);  /* callstack limits */\n\tif (depth > (duk_int_t) thr_callstack->callstack_top) {\n\t\tdepth = (duk_int_t) thr_callstack->callstack_top;\n\t}\n\tif (depth > 0) {\n\t\tif (flags & DUK_AUGMENT_FLAG_SKIP_ONE) {\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\tact = act->parent;\n\t\t\tdepth--;\n\t\t}\n\t}\n\tarr_size = depth * 2;\n\tif (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) {\n\t\tarr_size += 2;\n\t}\n\tif (c_filename) {\n\t\t/* We need the C filename to be interned before getting the\n\t\t * array part pointer to avoid any GC interference while the\n\t\t * array part is populated.\n\t\t */\n\t\tduk_push_string(thr, c_filename);\n\t\tarr_size += 2;\n\t}\n\n\t/* XXX: Uninitialized would be OK.  Maybe add internal primitive to\n\t * push bare duk_harray with size?\n\t */\n\tDUK_D(DUK_DPRINT(\"preallocated _Tracedata to %ld items\", (long) arr_size));\n\ttv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) arr_size);\n\tduk_clear_prototype(thr, -1);\n\tDUK_ASSERT(duk_is_bare_object(thr, -1));\n\tDUK_ASSERT(arr_size == 0 || tv != NULL);\n\n\t/* Compiler SyntaxErrors (and other errors) come first, and are\n\t * blamed by default (not flagged \"noblame\").\n\t */\n\tif (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) {\n\t\ts = thr->compile_ctx->h_filename;\n\t\tDUK_TVAL_SET_STRING(tv, s);\n\t\tDUK_HSTRING_INCREF(thr, s);\n\t\ttv++;\n\n\t\tu32 = (duk_uint32_t) thr->compile_ctx->curr_token.start_line;  /* (flags<<32) + (line), flags = 0 */\n\t\tDUK_TVAL_SET_U32(tv, u32);\n\t\ttv++;\n\t}\n\n\t/* Filename/line from C macros (__FILE__, __LINE__) are added as an\n\t * entry with a special format: (string, number).  The number contains\n\t * the line and flags.\n\t */\n\n\t/* [ ... error c_filename? arr ] */\n\n\tif (c_filename) {\n\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(thr->valstack_top - 2));\n\t\ts = DUK_TVAL_GET_STRING(thr->valstack_top - 2);  /* interned c_filename */\n\t\tDUK_ASSERT(s != NULL);\n\t\tDUK_TVAL_SET_STRING(tv, s);\n\t\tDUK_HSTRING_INCREF(thr, s);\n\t\ttv++;\n\n\t\td = ((flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE) ? ((duk_double_t) DUK_TB_FLAG_NOBLAME_FILELINE) * DUK_DOUBLE_2TO32 : 0.0) +\n\t\t    (duk_double_t) c_line;\n\t\tDUK_TVAL_SET_DOUBLE(tv, d);\n\t\ttv++;\n\t}\n\n\t/* Traceback depth doesn't take into account the filename/line\n\t * special handling above (intentional).\n\t */\n\tfor (; depth-- > 0; act = act->parent) {\n\t\tduk_uint32_t pc;\n\t\tduk_tval *tv_src;\n\n\t\t/* [... arr] */\n\n\t\tDUK_ASSERT(act != NULL);  /* depth check above, assumes book-keeping is correct */\n\t\tDUK_ASSERT_DISABLE(act->pc >= 0);  /* unsigned */\n\n\t\t/* Add function object. */\n\t\ttv_src = &act->tv_func;  /* object (function) or lightfunc */\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_src) || DUK_TVAL_IS_LIGHTFUNC(tv_src));\n\t\tDUK_TVAL_SET_TVAL(tv, tv_src);\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\ttv++;\n\n\t\t/* Add a number containing: pc, activation flags.\n\t\t *\n\t\t * PC points to next instruction, find offending PC.  Note that\n\t\t * PC == 0 for native code.\n\t\t */\n\t\tpc = (duk_uint32_t) duk_hthread_get_act_prev_pc(thr_callstack, act);\n\t\tDUK_ASSERT_DISABLE(pc >= 0);  /* unsigned */\n\t\tDUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32);  /* assume PC is at most 32 bits and non-negative */\n\t\td = ((duk_double_t) act->flags) * DUK_DOUBLE_2TO32 + (duk_double_t) pc;\n\t\tDUK_TVAL_SET_DOUBLE(tv, d);\n\t\ttv++;\n\t}\n\n#if defined(DUK_USE_ASSERTIONS)\n\t{\n\t\tduk_harray *a;\n\t\ta = (duk_harray *) duk_known_hobject(thr, -1);\n\t\tDUK_ASSERT(a != NULL);\n\t\tDUK_ASSERT((duk_uint32_t) (tv - DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a)) == a->length);\n\t\tDUK_ASSERT(a->length == (duk_uint32_t) arr_size);\n\t\tDUK_ASSERT(duk_is_bare_object(thr, -1));\n\t}\n#endif\n\n\t/* [ ... error c_filename? arr ] */\n\n\tif (c_filename) {\n\t\tduk_remove_m2(thr);\n\t}\n\n\t/* [ ... error arr ] */\n\n\tduk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INT_TRACEDATA);  /* -> [ ... error ] */\n}\n#endif  /* DUK_USE_TRACEBACKS */\n\n/*\n *  Add .fileName and .lineNumber to an error on the stack top.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE) && !defined(DUK_USE_TRACEBACKS)\nDUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_int_t entry_top;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\n\t/*\n\t *  If tracebacks are disabled, 'fileName' and 'lineNumber' are added\n\t *  as plain own properties.  Since Error.prototype has accessors of\n\t *  the same name, we need to define own properties directly (cannot\n\t *  just use e.g. duk_put_prop_stridx).  Existing properties are not\n\t *  overwritten in case they already exist.\n\t */\n\n\tif (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) {\n\t\t/* Compiler SyntaxError (or other error) gets the primary blame.\n\t\t * Currently no flag to prevent blaming.\n\t\t */\n\t\tduk_push_uint(thr, (duk_uint_t) thr->compile_ctx->curr_token.start_line);\n\t\tduk_push_hstring(thr, thr->compile_ctx->h_filename);\n\t} else if (c_filename && (flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE) == 0) {\n\t\t/* C call site gets blamed next, unless flagged not to do so.\n\t\t * XXX: file/line is disabled in minimal builds, so disable this\n\t\t * too when appropriate.\n\t\t */\n\t\tduk_push_int(thr, c_line);\n\t\tduk_push_string(thr, c_filename);\n\t} else {\n\t\t/* Finally, blame the innermost callstack entry which has a\n\t\t * .fileName property.\n\t\t */\n\t\tduk_small_uint_t depth;\n\t\tduk_uint32_t ecma_line;\n\t\tduk_activation *act;\n\n\t\tDUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX);  /* callstack limits */\n\t\tdepth = DUK_USE_TRACEBACK_DEPTH;\n\t\tif (depth > thr_callstack->callstack_top) {\n\t\t\tdepth = thr_callstack->callstack_top;\n\t\t}\n\t\tfor (act = thr_callstack->callstack_curr; depth-- > 0; act = act->parent) {\n\t\t\tduk_hobject *func;\n\t\t\tduk_uint32_t pc;\n\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\tfunc = DUK_ACT_GET_FUNC(act);\n\t\t\tif (func == NULL) {\n\t\t\t\t/* Lightfunc, not blamed now. */\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* PC points to next instruction, find offending PC,\n\t\t\t * PC == 0 for native code.\n\t\t\t */\n\t\t\tpc = duk_hthread_get_act_prev_pc(thr, act);  /* thr argument only used for thr->heap, so specific thread doesn't matter */\n\t\t\tDUK_UNREF(pc);\n\t\t\tDUK_ASSERT_DISABLE(pc >= 0);  /* unsigned */\n\t\t\tDUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32);  /* assume PC is at most 32 bits and non-negative */\n\n\t\t\tduk_push_hobject(thr, func);\n\n\t\t\t/* [ ... error func ] */\n\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME);\n\t\t\tif (!duk_is_string_notsymbol(thr, -1)) {\n\t\t\t\tduk_pop_2(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* [ ... error func fileName ] */\n\n\t\t\tecma_line = 0;\n#if defined(DUK_USE_PC2LINE)\n\t\t\tif (DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\t\t\tecma_line = duk_hobject_pc2line_query(thr, -2, (duk_uint_fast32_t) pc);\n\t\t\t} else {\n\t\t\t\t/* Native function, no relevant lineNumber. */\n\t\t\t}\n#endif  /* DUK_USE_PC2LINE */\n\t\t\tduk_push_u32(thr, ecma_line);\n\n\t\t\t/* [ ... error func fileName lineNumber ] */\n\n\t\t\tduk_replace(thr, -3);\n\n\t\t\t/* [ ... error lineNumber fileName ] */\n\t\t\tgoto define_props;\n\t\t}\n\n\t\t/* No activation matches, use undefined for both .fileName and\n\t\t * .lineNumber (matches what we do with a _Tracedata based\n\t\t * no-match lookup.\n\t\t */\n\t\tduk_push_undefined(thr);\n\t\tduk_push_undefined(thr);\n\t}\n\n define_props:\n\t/* [ ... error lineNumber fileName ] */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(duk_get_top(thr) == entry_top + 2);\n#endif\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LINE_NUMBER, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE);\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE && !DUK_USE_TRACEBACKS */\n\n/*\n *  Add line number to a compiler error.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_LOCAL void duk__add_compiler_error_line(duk_hthread *thr) {\n\n\t/* Append a \"(line NNN)\" to the \"message\" property of any error\n\t * thrown during compilation.  Usually compilation errors are\n\t * SyntaxErrors but they can also be out-of-memory errors and\n\t * the like.\n\t */\n\n\t/* [ ... error ] */\n\n\tDUK_ASSERT(duk_is_object(thr, -1));\n\n\tif (!(thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL)) {\n\t\treturn;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"compile error, before adding line info: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_MESSAGE)) {\n\t\tduk_push_sprintf(thr, \" (line %ld)\", (long) thr->compile_ctx->curr_token.start_line);\n\t\tduk_concat(thr, 2);\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE);\n\t} else {\n\t\tduk_pop(thr);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"compile error, after adding line info: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE */\n\n/*\n *  Augment an error being created using Duktape specific properties\n *  like _Tracedata or .fileName/.lineNumber.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_LOCAL void duk__err_augment_builtin_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_hobject *obj, duk_small_uint_t flags) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_int_t entry_top;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_UNREF(obj);  /* unreferenced w/o tracebacks */\n\n\tduk__add_compiler_error_line(thr);\n\n#if defined(DUK_USE_TRACEBACKS)\n\t/* If tracebacks are enabled, the '_Tracedata' property is the only\n\t * thing we need: 'fileName' and 'lineNumber' are virtual properties\n\t * which use '_Tracedata'.  (Check _Tracedata only as own property.)\n\t */\n\tif (duk_hobject_find_entry_tval_ptr_stridx(thr->heap, obj, DUK_STRIDX_INT_TRACEDATA) != NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"error value already has a '_Tracedata' property, not modifying it\"));\n\t} else {\n\t\tduk__add_traceback(thr, thr_callstack, c_filename, c_line, flags);\n\t}\n#else\n\t/* Without tracebacks the concrete .fileName and .lineNumber need\n\t * to be added directly.\n\t */\n\tduk__add_fileline(thr, thr_callstack, c_filename, c_line, flags);\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(duk_get_top(thr) == entry_top);\n#endif\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE */\n\n/*\n *  Augment an error at creation time with _Tracedata/fileName/lineNumber\n *  and allow a user error handler (if defined) to process/replace the error.\n *  The error to be augmented is at the stack top.\n *\n *  thr: thread containing the error value\n *  thr_callstack: thread which should be used for generating callstack etc.\n *  c_filename: C __FILE__ related to the error\n *  c_line: C __LINE__ related to the error\n *  flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE:\n *      if true, don't fileName/line as error source, otherwise use traceback\n *      (needed because user code filename/line are reported but internal ones\n *      are not)\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_INTERNAL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr_callstack != NULL);\n\n\t/* [ ... error ] */\n\n\t/*\n\t *  Criteria for augmenting:\n\t *\n\t *   - augmentation enabled in build (naturally)\n\t *   - error value internal prototype chain contains the built-in\n\t *     Error prototype object (i.e. 'val instanceof Error')\n\t *\n\t *  Additional criteria for built-in augmenting:\n\t *\n\t *   - error value is an extensible object\n\t */\n\n\tobj = duk_get_hobject(thr, -1);\n\tif (!obj) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"value is not an object, skip both built-in and user augment\"));\n\t\treturn;\n\t}\n\tif (!duk_hobject_prototype_chain_contains(thr, obj, thr->builtins[DUK_BIDX_ERROR_PROTOTYPE], 1 /*ignore_loop*/)) {\n\t\t/* If the value has a prototype loop, it's critical not to\n\t\t * throw here.  Instead, assume the value is not to be\n\t\t * augmented.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"value is not an error instance, skip both built-in and user augment\"));\n\t\treturn;\n\t}\n\tif (DUK_HOBJECT_HAS_EXTENSIBLE(obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"error meets criteria, built-in augment\"));\n\t\tduk__err_augment_builtin_create(thr, thr_callstack, c_filename, c_line, obj, flags);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"error does not meet criteria, no built-in augment\"));\n\t}\n\n\t/* [ ... error ] */\n\n#if defined(DUK_USE_ERRCREATE)\n\tduk__err_augment_user(thr, DUK_STRIDX_ERR_CREATE);\n#endif\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE */\n\n/*\n *  Augment an error at throw time; allow a user error handler (if defined)\n *  to process/replace the error.  The error to be augmented is at the\n *  stack top.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\nDUK_INTERNAL void duk_err_augment_error_throw(duk_hthread *thr) {\n#if defined(DUK_USE_ERRTHROW)\n\tduk__err_augment_user(thr, DUK_STRIDX_ERR_THROW);\n#endif  /* DUK_USE_ERRTHROW */\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_THROW */\n#line 1 \"duk_error_longjmp.c\"\n/*\n *  Do a longjmp call, calling the fatal error handler if no\n *  catchpoint exists.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_minimal(duk_hthread *thr));\nDUK_LOCAL void duk__uncaught_minimal(duk_hthread *thr) {\n\t(void) duk_fatal(thr, \"uncaught error\");\n\tDUK_WO_NORETURN(return;);\n}\n#endif\n\n#if 0\nDUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_readable(duk_hthread *thr));\nDUK_LOCAL void duk__uncaught_readable(duk_hthread *thr) {\n\tconst char *summary;\n\tchar buf[DUK_USE_FATAL_MAXLEN];\n\n\tsummary = duk_push_string_tval_readable(thr, &thr->heap->lj.value1);\n\tDUK_SNPRINTF(buf, sizeof(buf), \"uncaught: %s\", summary);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\t(void) duk_fatal(thr, (const char *) buf);\n\tDUK_WO_NORETURN(return;);\n}\n#endif\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_error_aware(duk_hthread *thr));\nDUK_LOCAL void duk__uncaught_error_aware(duk_hthread *thr) {\n\tconst char *summary;\n\tchar buf[DUK_USE_FATAL_MAXLEN];\n\n\tsummary = duk_push_string_tval_readable_error(thr, &thr->heap->lj.value1);\n\tDUK_ASSERT(summary != NULL);\n\tDUK_SNPRINTF(buf, sizeof(buf), \"uncaught: %s\", summary);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\t(void) duk_fatal(thr, (const char *) buf);\n\tDUK_WO_NORETURN(return;);\n}\n#endif\n\nDUK_INTERNAL void duk_err_longjmp(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"longjmp error: type=%d iserror=%d value1=%!T value2=%!T\",\n\t                   (int) thr->heap->lj.type, (int) thr->heap->lj.iserror,\n\t                   &thr->heap->lj.value1, &thr->heap->lj.value2));\n\n\t/* Prevent finalizer execution during error handling.  All error\n\t * handling sites will process pending finalizers once error handling\n\t * is complete and we're ready for the side effects.  Does not prevent\n\t * refzero freeing or mark-and-sweep during error handling.\n\t *\n\t * NOTE: when we come here some calling code may have used DECREF\n\t * NORZ macros without an explicit DUK_REFZERO_CHECK_xxx() call.\n\t * We don't want to do it here because it would just check for\n\t * pending finalizers and we prevent that explicitly.  Instead,\n\t * the error catcher will run the finalizers once error handling\n\t * is complete.\n\t */\n\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\n\tthr->heap->pf_prevent_count++;\n\tDUK_ASSERT(thr->heap->pf_prevent_count != 0);  /* Wrap. */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* XXX: set this immediately when longjmp state is set */\n\tDUK_ASSERT(thr->heap->error_not_allowed == 0);  /* Detect error within critical section. */\n\tthr->heap->error_not_allowed = 1;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"about to longjmp, pf_prevent_count=%ld\", (long) thr->heap->pf_prevent_count));\n\n\t/* If we don't have a jmpbuf_ptr, there is little we can do except\n\t * cause a fatal error.  The caller's expectation is that we never\n\t * return.\n\t */\n\tif (!thr->heap->lj.jmpbuf_ptr) {\n\t\tDUK_D(DUK_DPRINT(\"uncaught error: type=%d iserror=%d value1=%!T value2=%!T\",\n\t\t                 (int) thr->heap->lj.type, (int) thr->heap->lj.iserror,\n\t\t                 &thr->heap->lj.value1, &thr->heap->lj.value2));\n\n#if defined(DUK_USE_PREFER_SIZE)\n\t\tduk__uncaught_minimal(thr);\n#else\n\t\tduk__uncaught_error_aware(thr);\n#endif\n\t\tDUK_UNREACHABLE();\n\t}\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\tthrow duk_internal_exception();  /* dummy */\n#else\n\tDUK_LONGJMP(thr->heap->lj.jmpbuf_ptr->jb);\n#endif\n\n\tDUK_UNREACHABLE();\n}\n#line 1 \"duk_error_misc.c\"\n/*\n *  Error helpers\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Helper to walk the thread chain and see if there is an active error\n *  catcher.  Protected calls or finally blocks aren't considered catching.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_LOCAL duk_bool_t duk__have_active_catcher(duk_hthread *thr) {\n\t/* As noted above, a protected API call won't be counted as a\n\t * catcher.  This is usually convenient, e.g. in the case of a top-\n\t * level duk_pcall(), but may not always be desirable.  Perhaps add\n\t * an argument to treat them as catchers?\n\t */\n\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tfor (; thr != NULL; thr = thr->resumer) {\n\t\tfor (act = thr->callstack_curr; act != NULL; act = act->parent) {\n\t\t\tfor (cat = act->cat; cat != NULL; cat = cat->parent) {\n\t\t\t\tif (DUK_CAT_HAS_CATCH_ENABLED(cat)) {\n\t\t\t\t\treturn 1;  /* all we need to know */\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn 0;\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/*\n *  Get prototype object for an integer error code.\n */\n\nDUK_INTERNAL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_errcode_t code) {\n\tswitch (code) {\n\tcase DUK_ERR_EVAL_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_EVAL_ERROR_PROTOTYPE];\n\tcase DUK_ERR_RANGE_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_RANGE_ERROR_PROTOTYPE];\n\tcase DUK_ERR_REFERENCE_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_REFERENCE_ERROR_PROTOTYPE];\n\tcase DUK_ERR_SYNTAX_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_SYNTAX_ERROR_PROTOTYPE];\n\tcase DUK_ERR_TYPE_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_TYPE_ERROR_PROTOTYPE];\n\tcase DUK_ERR_URI_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_URI_ERROR_PROTOTYPE];\n\tcase DUK_ERR_ERROR:\n\tdefault:\n\t\treturn thr->builtins[DUK_BIDX_ERROR_PROTOTYPE];\n\t}\n}\n\n/*\n *  Helper for debugger throw notify and pause-on-uncaught integration.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL void duk_err_check_debugger_integration(duk_hthread *thr) {\n\tduk_bool_t uncaught;\n\tduk_tval *tv_obj;\n\n\t/* If something is thrown with the debugger attached and nobody will\n\t * catch it, execution is paused before the longjmp, turning over\n\t * control to the debug client.  This allows local state to be examined\n\t * before the stack is unwound.  Errors are not intercepted when debug\n\t * message loop is active (e.g. for Eval).\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\t/* XXX: Allow customizing the pause and notify behavior at runtime\n\t * using debugger runtime flags.  For now the behavior is fixed using\n\t * config options.\n\t */\n\n\tif (!duk_debug_is_attached(thr->heap) ||\n\t    thr->heap->dbg_processing ||\n\t    thr->heap->lj.type != DUK_LJ_TYPE_THROW ||\n\t    thr->heap->creating_error) {\n\t\tDUK_D(DUK_DPRINT(\"skip debugger error integration; not attached, debugger processing, not THROW, or error thrown while creating error\"));\n\t\treturn;\n\t}\n\n\t/* Don't intercept a DoubleError, we may have caused the initial double\n\t * fault and attempting to intercept it will cause us to be called\n\t * recursively and exhaust the C stack.  (This should no longer happen\n\t * for the initial throw because DoubleError path doesn't do a debugger\n\t * integration check, but it might happen for rethrows.)\n\t */\n\ttv_obj = &thr->heap->lj.value1;\n\tif (DUK_TVAL_IS_OBJECT(tv_obj) && DUK_TVAL_GET_OBJECT(tv_obj) == thr->builtins[DUK_BIDX_DOUBLE_ERROR]) {\n\t\tDUK_D(DUK_DPRINT(\"built-in DoubleError instance (re)thrown, not intercepting\"));\n\t\treturn;\n\t}\n\n\tuncaught = !duk__have_active_catcher(thr);\n\n\t/* Debugger code expects the value at stack top.  This also serves\n\t * as a backup: we need to store/restore the longjmp state because\n\t * when the debugger is paused Eval commands may be executed and\n\t * they can arbitrarily clobber the longjmp state.\n\t */\n\tduk_push_tval(thr, tv_obj);\n\n\t/* Store and reset longjmp state. */\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\tDUK_TVAL_DECREF_NORZ(thr, tv_obj);\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value2));  /* Always for THROW type. */\n\tDUK_TVAL_SET_UNDEFINED(tv_obj);\n\tthr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)\n\t/* Report it to the debug client */\n\tDUK_D(DUK_DPRINT(\"throw with debugger attached, report to client\"));\n\tduk_debug_send_throw(thr, uncaught);\n#endif\n\n\tif (uncaught) {\n\t\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_UNCAUGHT_ERROR) {\n\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by uncaught error\"));\n\t\t\tduk_debug_halt_execution(thr, 1 /*use_prev_pc*/);\n\t\t}\n\t} else {\n\t\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_CAUGHT_ERROR) {\n\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by caught error\"));\n\t\t\tduk_debug_halt_execution(thr, 1 /*use_prev_pc*/);\n\t\t}\n\t}\n\n\t/* Restore longjmp state. */\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\tthr->heap->lj.type = DUK_LJ_TYPE_THROW;\n\ttv_obj = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value1));\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value2));\n\tDUK_TVAL_SET_TVAL(&thr->heap->lj.value1, tv_obj);\n\tDUK_TVAL_INCREF(thr, tv_obj);\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\n\tduk_pop(thr);\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/*\n *  Helpers for setting up heap longjmp state.\n */\n\nDUK_INTERNAL void duk_err_setup_ljstate1(duk_hthread *thr, duk_small_uint_t lj_type, duk_tval *tv_val) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(tv_val != NULL);\n\n\tDUK_ASSERT_LJSTATE_UNSET(heap);\n\n\theap->lj.type = lj_type;\n\tDUK_TVAL_SET_TVAL(&heap->lj.value1, tv_val);\n\tDUK_TVAL_INCREF(thr, tv_val);\n\n\tDUK_ASSERT_LJSTATE_SET(heap);\n}\n#line 1 \"duk_error_throw.c\"\n/*\n *  Create and throw an ECMAScript error object based on a code and a message.\n *\n *  Used when we throw errors internally.  ECMAScript generated error objects\n *  are created by ECMAScript code, and the throwing is handled by the bytecode\n *  executor.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Create and throw an error (originating from Duktape internally)\n *\n *  Push an error object on top of the stack, possibly throw augmenting\n *  the error, and finally longjmp.\n *\n *  If an error occurs while we're dealing with the current error, we might\n *  enter an infinite recursion loop.  This is prevented by detecting a\n *  \"double fault\" through the heap->creating_error flag; the recursion\n *  then stops at the second level.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code, const char *msg, const char *filename, duk_int_t line) {\n#else\nDUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code) {\n#endif\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\tDUK_DD(DUK_DDPRINT(\"duk_err_create_and_throw(): code=%ld, msg=%s, filename=%s, line=%ld\",\n\t                   (long) code, (const char *) msg,\n\t                   (const char *) filename, (long) line));\n#else\n\tDUK_DD(DUK_DDPRINT(\"duk_err_create_and_throw(): code=%ld\", (long) code));\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Even though nested call is possible because we throw an error when\n\t * trying to create an error, the potential errors must happen before\n\t * the longjmp state is configured.\n\t */\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\t/* Sync so that augmentation sees up-to-date activations, NULL\n\t * thr->ptr_curr_pc so that it's not used if side effects occur\n\t * in augmentation or longjmp handling.\n\t */\n\tduk_hthread_sync_and_null_currpc(thr);\n\n\t/*\n\t *  Create and push an error object onto the top of stack.\n\t *  The error is potentially augmented before throwing.\n\t *\n\t *  If a \"double error\" occurs, use a fixed error instance\n\t *  to avoid further trouble.\n\t */\n\n\tif (thr->heap->creating_error) {\n\t\tduk_tval tv_val;\n\t\tduk_hobject *h_err;\n\n\t\tthr->heap->creating_error = 0;\n\n\t\th_err = thr->builtins[DUK_BIDX_DOUBLE_ERROR];\n\t\tif (h_err != NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"double fault detected -> use built-in fixed 'double error' instance\"));\n\t\t\tDUK_TVAL_SET_OBJECT(&tv_val, h_err);\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"double fault detected; there is no built-in fixed 'double error' instance \"\n\t\t\t                 \"-> use the error code as a number\"));\n\t\t\tDUK_TVAL_SET_I32(&tv_val, (duk_int32_t) code);\n\t\t}\n\n\t\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, &tv_val);\n\n\t\t/* No augmentation to avoid any allocations or side effects. */\n\t} else {\n\t\t/* Prevent infinite recursion.  Extra call stack and C\n\t\t * recursion headroom (see GH-191) is added for augmentation.\n\t\t * That is now signalled by heap->augmenting error and taken\n\t\t * into account in call handling without an explicit limit bump.\n\t\t */\n\t\tthr->heap->creating_error = 1;\n\n\t\tduk_require_stack(thr, 1);\n\n\t\t/* XXX: usually unnecessary '%s' formatting here, but cannot\n\t\t * use 'msg' as a format string directly.\n\t\t */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\tduk_push_error_object_raw(thr,\n\t\t                          code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t\t                          filename,\n\t\t                          line,\n\t\t                          \"%s\",\n\t\t                          (const char *) msg);\n#else\n\t\tduk_push_error_object_raw(thr,\n\t\t                          code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t\t                          NULL,\n\t\t                          0,\n\t\t                          NULL);\n#endif\n\n\t\t/* Note that an alloc error may happen during error augmentation.\n\t\t * This may happen both when the original error is an alloc error\n\t\t * and when it's something else.  Because any error in augmentation\n\t\t * must be handled correctly anyway, there's no special check for\n\t\t * avoiding it for alloc errors (this differs from Duktape 1.x).\n\t\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\t\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (INTERNAL): %!iT (before throw augment)\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\tduk_err_augment_error_throw(thr);\n#endif\n\n\t\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, DUK_GET_TVAL_NEGIDX(thr, -1));\n\t\tthr->heap->creating_error = 0;\n\n\t\t/* Error is now created and we assume no errors can occur any\n\t\t * more.  Check for debugger Throw integration only when the\n\t\t * error is complete.  If we enter debugger message loop,\n\t\t * creating_error must be 0 so that errors can be thrown in\n\t\t * the paused state, e.g. in Eval commands.\n\t\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tduk_err_check_debugger_integration(thr);\n#endif\n\t}\n\n\t/*\n\t *  Finally, longjmp\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (INTERNAL): %!iT, %!iT (after throw augment)\",\n\t                     (duk_tval *) &thr->heap->lj.value1, (duk_tval *) &thr->heap->lj.value2));\n\n\tduk_err_longjmp(thr);\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  Helper for C function call negative return values.\n */\n\nDUK_INTERNAL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t rc) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(rc < 0);\n\n\t/*\n\t *  The __FILE__ and __LINE__ information is intentionally not used in the\n\t *  creation of the error object, as it isn't useful in the tracedata.  The\n\t *  tracedata still contains the function which returned the negative return\n\t *  code, and having the file/line of this function isn't very useful.\n\t *\n\t *  The error messages for DUK_RET_xxx shorthand are intentionally very\n\t *  minimal: they're only really useful for low memory targets.\n\t */\n\n\tduk_error_raw(thr, -rc, NULL, 0, \"error (rc %ld)\", (long) rc);\n\tDUK_WO_NORETURN(return;);\n}\n#line 1 \"duk_hbuffer_alloc.c\"\n/*\n *  duk_hbuffer allocation and freeing.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Allocate a new duk_hbuffer of a certain type and return a pointer to it\n * (NULL on error).  Write buffer data pointer to 'out_bufdata' (only if\n * allocation successful).\n */\nDUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk_small_uint_t flags, void **out_bufdata) {\n\tduk_hbuffer *res = NULL;\n\tduk_size_t header_size;\n\tduk_size_t alloc_size;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(out_bufdata != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"allocate hbuffer\"));\n\n\t/* Size sanity check.  Should not be necessary because caller is\n\t * required to check this, but we don't want to cause a segfault\n\t * if the size wraps either in duk_size_t computation or when\n\t * storing the size in a 16-bit field.\n\t */\n\tif (size > DUK_HBUFFER_MAX_BYTELEN) {\n\t\tDUK_D(DUK_DPRINT(\"hbuffer alloc failed: size too large: %ld\", (long) size));\n\t\treturn NULL;  /* no need to write 'out_bufdata' */\n\t}\n\n\tif (flags & DUK_BUF_FLAG_EXTERNAL) {\n\t\theader_size = sizeof(duk_hbuffer_external);\n\t\talloc_size = sizeof(duk_hbuffer_external);\n\t} else if (flags & DUK_BUF_FLAG_DYNAMIC) {\n\t\theader_size = sizeof(duk_hbuffer_dynamic);\n\t\talloc_size = sizeof(duk_hbuffer_dynamic);\n\t} else {\n\t\theader_size = sizeof(duk_hbuffer_fixed);\n\t\talloc_size = sizeof(duk_hbuffer_fixed) + size;\n\t\tDUK_ASSERT(alloc_size >= sizeof(duk_hbuffer_fixed));  /* no wrapping */\n\t}\n\n\tres = (duk_hbuffer *) DUK_ALLOC(heap, alloc_size);\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\tgoto alloc_error;\n\t}\n\n\t/* zero everything unless requested not to do so */\n#if defined(DUK_USE_ZERO_BUFFER_DATA)\n\tduk_memzero((void *) res,\n\t            (flags & DUK_BUF_FLAG_NOZERO) ? header_size : alloc_size);\n#else\n\tduk_memzero((void *) res, header_size);\n#endif\n\n\tif (flags & DUK_BUF_FLAG_EXTERNAL) {\n\t\tduk_hbuffer_external *h;\n\t\th = (duk_hbuffer_external *) res;\n\t\tDUK_UNREF(h);\n\t\t*out_bufdata = NULL;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_HEAPPTR16)\n/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */\n#else\n\t\tDUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap, h, NULL);\n#endif\n#endif\n\t\tDUK_ASSERT(DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap, h) == NULL);\n\t} else if (flags & DUK_BUF_FLAG_DYNAMIC) {\n\t\tduk_hbuffer_dynamic *h = (duk_hbuffer_dynamic *) res;\n\t\tvoid *ptr;\n\n\t\tif (size > 0) {\n\t\t\tDUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL));  /* alloc external with size zero */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"dynamic buffer with nonzero size, alloc actual buffer\"));\n#if defined(DUK_USE_ZERO_BUFFER_DATA)\n\t\t\tptr = DUK_ALLOC_ZEROED(heap, size);\n#else\n\t\t\tptr = DUK_ALLOC(heap, size);\n#endif\n\t\t\tif (DUK_UNLIKELY(ptr == NULL)) {\n\t\t\t\t/* Because size > 0, NULL check is correct */\n\t\t\t\tgoto alloc_error;\n\t\t\t}\n\t\t\t*out_bufdata = ptr;\n\n\t\t\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, ptr);\n\t\t} else {\n\t\t\t*out_bufdata = NULL;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_HEAPPTR16)\n/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */\n#else\n\t\t\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, NULL);\n#endif\n#endif\n\t\t\tDUK_ASSERT(DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, h) == NULL);\n\t\t}\n\t} else {\n\t\t*out_bufdata = (void *) ((duk_hbuffer_fixed *) (void *) res + 1);\n\t}\n\n\tDUK_HBUFFER_SET_SIZE(res, size);\n\n\tDUK_HEAPHDR_SET_TYPE(&res->hdr, DUK_HTYPE_BUFFER);\n\tif (flags & DUK_BUF_FLAG_DYNAMIC) {\n\t\tDUK_HBUFFER_SET_DYNAMIC(res);\n\t\tif (flags & DUK_BUF_FLAG_EXTERNAL) {\n\t\t\tDUK_HBUFFER_SET_EXTERNAL(res);\n\t\t}\n\t} else {\n\t\tDUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL));\n\t}\n        DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &res->hdr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"allocated hbuffer: %p\", (void *) res));\n\treturn res;\n\n alloc_error:\n\tDUK_DD(DUK_DDPRINT(\"hbuffer allocation failed\"));\n\n\tDUK_FREE(heap, res);\n\treturn NULL;  /* no need to write 'out_bufdata' */\n}\n\n/* For indirect allocs. */\n\nDUK_INTERNAL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud) {\n\tduk_hbuffer_dynamic *buf = (duk_hbuffer_dynamic *) ud;\n\tDUK_UNREF(heap);\n\treturn (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, buf);\n}\n#line 1 \"duk_hbuffer_assert.c\"\n/*\n *  duk_hbuffer assertion helpers\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ASSERTIONS)\n\nDUK_INTERNAL void duk_hbuffer_assert_valid(duk_hbuffer *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n#line 1 \"duk_hbuffer_ops.c\"\n/*\n *  duk_hbuffer operations such as resizing and inserting/appending data to\n *  a dynamic buffer.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Resizing\n */\n\nDUK_INTERNAL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf, duk_size_t new_size) {\n\tvoid *res;\n\tduk_size_t prev_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf));\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf));\n\n\t/*\n\t *  Maximum size check\n\t */\n\n\tif (new_size > DUK_HBUFFER_MAX_BYTELEN) {\n\t\tDUK_ERROR_RANGE(thr, \"buffer too long\");\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/*\n\t *  Note: use indirect realloc variant just in case mark-and-sweep\n\t *  (finalizers) might resize this same buffer during garbage\n\t *  collection.\n\t */\n\n\tres = DUK_REALLOC_INDIRECT(thr->heap, duk_hbuffer_get_dynalloc_ptr, (void *) buf, new_size);\n\tif (DUK_LIKELY(res != NULL || new_size == 0)) {\n\t\t/* 'res' may be NULL if new allocation size is 0. */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"resized dynamic buffer %p:%ld -> %p:%ld\",\n\t\t                     (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, buf),\n\t\t                     (long) DUK_HBUFFER_DYNAMIC_GET_SIZE(buf),\n\t\t                     (void *) res,\n\t\t                     (long) new_size));\n\n\t\t/*\n\t\t *  The entire allocated buffer area, regardless of actual used\n\t\t *  size, is kept zeroed in resizes for simplicity.  If the buffer\n\t\t *  is grown, zero the new part.\n\t\t */\n\n\t\tprev_size = DUK_HBUFFER_DYNAMIC_GET_SIZE(buf);\n\t\tif (new_size > prev_size) {\n\t\t\tDUK_ASSERT(new_size - prev_size > 0);\n#if defined(DUK_USE_ZERO_BUFFER_DATA)\n\t\t\tduk_memzero((void *) ((char *) res + prev_size),\n\t\t\t            (duk_size_t) (new_size - prev_size));\n#endif\n\t\t}\n\n\t\tDUK_HBUFFER_DYNAMIC_SET_SIZE(buf, new_size);\n\t\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR(thr->heap, buf, res);\n\t} else {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_ASSERT(res != NULL || new_size == 0);\n}\n\nDUK_INTERNAL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *buf) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf));\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf));\n\n\tduk_hbuffer_resize(thr, buf, 0);\n}\n/* #include duk_internal.h -> already included */\n#line 2 \"duk_hbufobj_misc.c\"\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_uint_t duk_hbufobj_clamp_bytelength(duk_hbufobj *h_bufobj, duk_uint_t len) {\n\tduk_uint_t buf_size;\n\tduk_uint_t buf_avail;\n\n\tDUK_ASSERT(h_bufobj != NULL);\n\tDUK_ASSERT(h_bufobj->buf != NULL);\n\n\tbuf_size = (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_bufobj->buf);\n\tif (h_bufobj->offset > buf_size) {\n\t\t/* Slice starting point is beyond current length. */\n\t\treturn 0;\n\t}\n\tbuf_avail = buf_size - h_bufobj->offset;\n\n\treturn buf_avail >= len ? len : buf_avail;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n#line 1 \"duk_heap_alloc.c\"\n/*\n *  duk_heap allocation and freeing.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ROM_STRINGS)\n/* Fixed seed value used with ROM strings. */\n#define DUK__FIXED_HASH_SEED       0xabcd1234\n#endif\n\n/*\n *  Free a heap object.\n *\n *  Free heap object and its internal (non-heap) pointers.  Assumes that\n *  caller has removed the object from heap allocated list or the string\n *  intern table, and any weak references (which strings may have) have\n *  been already dealt with.\n */\n\nDUK_INTERNAL void duk_free_hobject(duk_heap *heap, duk_hobject *h) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_FREE(heap, DUK_HOBJECT_GET_PROPS(heap, h));\n\n\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tDUK_UNREF(f);\n\t\t/* Currently nothing to free; 'data' is a heap object */\n\t} else if (DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\tduk_hnatfunc *f = (duk_hnatfunc *) h;\n\t\tDUK_UNREF(f);\n\t\t/* Currently nothing to free */\n\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tduk_activation *act;\n\n\t\tDUK_FREE(heap, t->valstack);\n\n\t\t/* Don't free h->resumer because it exists in the heap.\n\t\t * Callstack entries also contain function pointers which\n\t\t * are not freed for the same reason.  They are decref\n\t\t * finalized and the targets are freed if necessary based\n\t\t * on their refcount (or reachability).\n\t\t */\n\t\tfor (act = t->callstack_curr; act != NULL;) {\n\t\t\tduk_activation *act_next;\n\t\t\tduk_catcher *cat;\n\n\t\t\tfor (cat = act->cat; cat != NULL;) {\n\t\t\t\tduk_catcher *cat_next;\n\n\t\t\t\tcat_next = cat->parent;\n\t\t\t\tDUK_FREE(heap, (void *) cat);\n\t\t\t\tcat = cat_next;\n\t\t\t}\n\n\t\t\tact_next = act->parent;\n\t\t\tDUK_FREE(heap, (void *) act);\n\t\t\tact = act_next;\n\t\t}\n\n\t\t/* XXX: with 'caller' property the callstack would need\n\t\t * to be unwound to update the 'caller' properties of\n\t\t * functions in the callstack.\n\t\t */\n\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {\n\t\tduk_hboundfunc *f = (duk_hboundfunc *) (void *) h;\n\n\t\tDUK_FREE(heap, f->args);\n\t}\n\n\tDUK_FREE(heap, (void *) h);\n}\n\nDUK_INTERNAL void duk_free_hbuffer(duk_heap *heap, duk_hbuffer *h) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n\tif (DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h)) {\n\t\tduk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h;\n\t\tDUK_DDD(DUK_DDDPRINT(\"free dynamic buffer %p\", (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, g)));\n\t\tDUK_FREE(heap, DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, g));\n\t}\n\tDUK_FREE(heap, (void *) h);\n}\n\nDUK_INTERNAL void duk_free_hstring(duk_heap *heap, duk_hstring *h) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_UNREF(heap);\n\tDUK_UNREF(h);\n\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_FREE)\n\tif (DUK_HSTRING_HAS_EXTDATA(h)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"free extstr: hstring %!O, extdata: %p\",\n\t\t                     h, DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) h)));\n\t\tDUK_USE_EXTSTR_FREE(heap->heap_udata, (const void *) DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) h));\n\t}\n#endif\n\tDUK_FREE(heap, (void *) h);\n}\n\nDUK_INTERNAL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr) {\n\tDUK_ASSERT(heap);\n\tDUK_ASSERT(hdr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"free heaphdr %p, htype %ld\", (void *) hdr, (long) DUK_HEAPHDR_GET_TYPE(hdr)));\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(hdr)) {\n\tcase DUK_HTYPE_STRING:\n\t\tduk_free_hstring(heap, (duk_hstring *) hdr);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tduk_free_hobject(heap, (duk_hobject *) hdr);\n\t\tbreak;\n\tdefault:\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) == DUK_HTYPE_BUFFER);\n\t\tduk_free_hbuffer(heap, (duk_hbuffer *) hdr);\n\t}\n\n}\n\n/*\n *  Free the heap.\n *\n *  Frees heap-related non-heap-tracked allocations such as the\n *  string intern table; then frees the heap allocated objects;\n *  and finally frees the heap structure itself.  Reference counts\n *  and GC markers are ignored (and not updated) in this process,\n *  and finalizers won't be called.\n *\n *  The heap pointer and heap object pointers must not be used\n *  after this call.\n */\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\nDUK_LOCAL duk_size_t duk__heap_free_activation_freelist(duk_heap *heap) {\n\tduk_activation *act;\n\tduk_activation *act_next;\n\tduk_size_t count_act = 0;\n\n\tfor (act = heap->activation_free; act != NULL;) {\n\t\tact_next = act->parent;\n\t\tDUK_FREE(heap, (void *) act);\n\t\tact = act_next;\n#if defined(DUK_USE_DEBUG)\n\t\tcount_act++;\n#endif\n\t}\n\theap->activation_free = NULL;  /* needed when called from mark-and-sweep */\n\treturn count_act;\n}\n#endif  /* DUK_USE_CACHE_ACTIVATION */\n\n#if defined(DUK_USE_CACHE_CATCHER)\nDUK_LOCAL duk_size_t duk__heap_free_catcher_freelist(duk_heap *heap) {\n\tduk_catcher *cat;\n\tduk_catcher *cat_next;\n\tduk_size_t count_cat = 0;\n\n\tfor (cat = heap->catcher_free; cat != NULL;) {\n\t\tcat_next = cat->parent;\n\t\tDUK_FREE(heap, (void *) cat);\n\t\tcat = cat_next;\n#if defined(DUK_USE_DEBUG)\n\t\tcount_cat++;\n#endif\n\t}\n\theap->catcher_free = NULL;  /* needed when called from mark-and-sweep */\n\n\treturn count_cat;\n}\n#endif  /* DUK_USE_CACHE_CATCHER */\n\nDUK_INTERNAL void duk_heap_free_freelists(duk_heap *heap) {\n\tduk_size_t count_act = 0;\n\tduk_size_t count_cat = 0;\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\tcount_act = duk__heap_free_activation_freelist(heap);\n#endif\n#if defined(DUK_USE_CACHE_CATCHER)\n\tcount_cat = duk__heap_free_catcher_freelist(heap);\n#endif\n\tDUK_UNREF(heap);\n\tDUK_UNREF(count_act);\n\tDUK_UNREF(count_cat);\n\n\tDUK_D(DUK_DPRINT(\"freed %ld activation freelist entries, %ld catcher freelist entries\",\n\t                 (long) count_act, (long) count_cat));\n}\n\nDUK_LOCAL void duk__free_allocated(duk_heap *heap) {\n\tduk_heaphdr *curr;\n\tduk_heaphdr *next;\n\n\tcurr = heap->heap_allocated;\n\twhile (curr) {\n\t\t/* We don't log or warn about freeing zero refcount objects\n\t\t * because they may happen with finalizer processing.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"FINALFREE (allocated): %!iO\",\n\t\t                     (duk_heaphdr *) curr));\n\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\tduk_heap_free_heaphdr_raw(heap, curr);\n\t\tcurr = next;\n\t}\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__free_finalize_list(duk_heap *heap) {\n\tduk_heaphdr *curr;\n\tduk_heaphdr *next;\n\n\tcurr = heap->finalize_list;\n\twhile (curr) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"FINALFREE (finalize_list): %!iO\",\n\t\t                     (duk_heaphdr *) curr));\n\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\tduk_heap_free_heaphdr_raw(heap, curr);\n\t\tcurr = next;\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_LOCAL void duk__free_stringtable(duk_heap *heap) {\n\t/* strings are only tracked by stringtable */\n\tduk_heap_strtable_free(heap);\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__free_run_finalizers(duk_heap *heap) {\n\tduk_heaphdr *curr;\n\tduk_uint_t round_no;\n\tduk_size_t count_all;\n\tduk_size_t count_finalized;\n\tduk_size_t curr_limit;\n\n\tDUK_ASSERT(heap != NULL);\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* refzero not running -> must be empty */\n#endif\n\tDUK_ASSERT(heap->finalize_list == NULL);  /* mark-and-sweep last pass */\n\n\tif (heap->heap_thread == NULL) {\n\t\t/* May happen when heap allocation fails right off.  There\n\t\t * cannot be any finalizable objects in this case.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"no heap_thread in heap destruct, assume no finalizable objects\"));\n\t\treturn;\n\t}\n\n\t/* Prevent finalize_list processing and mark-and-sweep entirely.\n\t * Setting ms_running != 0 also prevents refzero handling from moving\n\t * objects away from the heap_allocated list.  The flag name is a bit\n\t * misleading here.\n\t *\n\t * Use a distinct value for ms_running here (== 2) so that assertions\n\t * can detect this situation separate from the normal runtime\n\t * mark-and-sweep case.  This allows better assertions (GH-2030).\n\t */\n\tDUK_ASSERT(heap->pf_prevent_count == 0);\n\tDUK_ASSERT(heap->ms_running == 0);\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\theap->pf_prevent_count = 1;\n\theap->ms_running = 2;  /* Use distinguishable value. */\n\theap->ms_prevent_count = 1;  /* Bump, because mark-and-sweep assumes it's bumped when ms_running is set. */\n\n\tcurr_limit = 0;  /* suppress warning, not used */\n\tfor (round_no = 0; ; round_no++) {\n\t\tcurr = heap->heap_allocated;\n\t\tcount_all = 0;\n\t\tcount_finalized = 0;\n\t\twhile (curr) {\n\t\t\tcount_all++;\n\t\t\tif (DUK_HEAPHDR_IS_OBJECT(curr)) {\n\t\t\t\t/* Only objects in heap_allocated may have finalizers.  Check that\n\t\t\t\t * the object itself has a _Finalizer property (own or inherited)\n\t\t\t\t * so that we don't execute finalizers for e.g. Proxy objects.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(curr != NULL);\n\n\t\t\t\tif (DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) curr)) {\n\t\t\t\t\tif (!DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) curr)) {\n\t\t\t\t\t\tDUK_ASSERT(DUK_HEAP_HAS_FINALIZER_NORESCUE(heap));  /* maps to finalizer 2nd argument */\n\t\t\t\t\t\tduk_heap_run_finalizer(heap, (duk_hobject *) curr);\n\t\t\t\t\t\tcount_finalized++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurr = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\t}\n\n\t\t/* Each round of finalizer execution may spawn new finalizable objects\n\t\t * which is normal behavior for some applications.  Allow multiple\n\t\t * rounds of finalization, but use a shrinking limit based on the\n\t\t * first round to detect the case where a runaway finalizer creates\n\t\t * an unbounded amount of new finalizable objects.  Finalizer rescue\n\t\t * is not supported: the semantics are unclear because most of the\n\t\t * objects being finalized here are already reachable.  The finalizer\n\t\t * is given a boolean to indicate that rescue is not possible.\n\t\t *\n\t\t * See discussion in: https://github.com/svaarala/duktape/pull/473\n\t\t */\n\n\t\tif (round_no == 0) {\n\t\t\t/* Cannot wrap: each object is at least 8 bytes so count is\n\t\t\t * at most 1/8 of that.\n\t\t\t */\n\t\t\tcurr_limit = count_all * 2;\n\t\t} else {\n\t\t\tcurr_limit = (curr_limit * 3) / 4;   /* Decrease by 25% every round */\n\t\t}\n\t\tDUK_D(DUK_DPRINT(\"finalizer round %ld complete, %ld objects, tried to execute %ld finalizers, current limit is %ld\",\n\t\t                 (long) round_no, (long) count_all, (long) count_finalized, (long) curr_limit));\n\n\t\tif (count_finalized == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"no more finalizable objects, forced finalization finished\"));\n\t\t\tbreak;\n\t\t}\n\t\tif (count_finalized >= curr_limit) {\n\t\t\tDUK_D(DUK_DPRINT(\"finalizer count above limit, potentially runaway finalizer; skip remaining finalizers\"));\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tDUK_ASSERT(heap->ms_running == 2);\n\tDUK_ASSERT(heap->pf_prevent_count == 1);\n\theap->ms_running = 0;\n\theap->pf_prevent_count = 0;\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_INTERNAL void duk_heap_free(duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"free heap: %p\", (void *) heap));\n\n#if defined(DUK_USE_DEBUG)\n\tduk_heap_strtable_dump(heap);\n#endif\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* Detach a debugger if attached (can be called multiple times)\n\t * safely.\n\t */\n\t/* XXX: Add a flag to reject an attempt to re-attach?  Otherwise\n\t * the detached callback may immediately reattach.\n\t */\n\tduk_debug_do_detach(heap);\n#endif\n\n\t/* Execute finalizers before freeing the heap, even for reachable\n\t * objects.  This gives finalizers the chance to free any native\n\t * resources like file handles, allocations made outside Duktape,\n\t * etc.  This is quite tricky to get right, so that all finalizer\n\t * guarantees are honored.\n\t *\n\t * Run mark-and-sweep a few times just in case (unreachable object\n\t * finalizers run already here).  The last round must rescue objects\n\t * from the previous round without running any more finalizers.  This\n\t * ensures rescued objects get their FINALIZED flag cleared so that\n\t * their finalizer is called once more in forced finalization to\n\t * satisfy finalizer guarantees.  However, we don't want to run any\n\t * more finalizers because that'd required one more loop, and so on.\n\t *\n\t * XXX: this perhaps requires an execution time limit.\n\t */\n\tDUK_D(DUK_DPRINT(\"execute finalizers before freeing heap\"));\n\tDUK_ASSERT(heap->pf_skip_finalizers == 0);\n\tDUK_D(DUK_DPRINT(\"forced gc #1 in heap destruction\"));\n\tduk_heap_mark_and_sweep(heap, 0);\n\tDUK_D(DUK_DPRINT(\"forced gc #2 in heap destruction\"));\n\tduk_heap_mark_and_sweep(heap, 0);\n\tDUK_D(DUK_DPRINT(\"forced gc #3 in heap destruction (don't run finalizers)\"));\n\theap->pf_skip_finalizers = 1;\n\tduk_heap_mark_and_sweep(heap, 0);  /* Skip finalizers; queue finalizable objects to heap_allocated. */\n\n\t/* There are never objects in refzero_list at this point, or at any\n\t * point beyond a DECREF (even a DECREF_NORZ).  Since Duktape 2.1\n\t * refzero_list processing is side effect free, so it is always\n\t * processed to completion by a DECREF initially triggering a zero\n\t * refcount.\n\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always processed to completion inline. */\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tDUK_ASSERT(heap->finalize_list == NULL);  /* Last mark-and-sweep with skip_finalizers. */\n#endif\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tDUK_D(DUK_DPRINT(\"run finalizers for remaining finalizable objects\"));\n\tDUK_HEAP_SET_FINALIZER_NORESCUE(heap);  /* Rescue no longer supported. */\n\tduk__free_run_finalizers(heap);\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n\t/* Note: heap->heap_thread, heap->curr_thread, and heap->heap_object\n\t * are on the heap allocated list.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"freeing temporary freelists\"));\n\tduk_heap_free_freelists(heap);\n\n\tDUK_D(DUK_DPRINT(\"freeing heap_allocated of heap: %p\", (void *) heap));\n\tduk__free_allocated(heap);\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always processed to completion inline. */\n#endif\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tDUK_D(DUK_DPRINT(\"freeing finalize_list of heap: %p\", (void *) heap));\n\tduk__free_finalize_list(heap);\n#endif\n\n\tDUK_D(DUK_DPRINT(\"freeing string table of heap: %p\", (void *) heap));\n\tduk__free_stringtable(heap);\n\n\tDUK_D(DUK_DPRINT(\"freeing heap structure: %p\", (void *) heap));\n\theap->free_func(heap->heap_udata, heap);\n}\n\n/*\n *  Allocate a heap.\n *\n *  String table is initialized with built-in strings from genbuiltins.py,\n *  either by dynamically creating the strings or by referring to ROM strings.\n */\n\n#if defined(DUK_USE_ROM_STRINGS)\nDUK_LOCAL duk_bool_t duk__init_heap_strings(duk_heap *heap) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_small_uint_t i;\n#endif\n\n\tDUK_UNREF(heap);\n\n\t/* With ROM-based strings, heap->strs[] and thr->strs[] are omitted\n\t * so nothing to initialize for strs[].\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tfor (i = 0; i < sizeof(duk_rom_strings_lookup) / sizeof(const duk_hstring *); i++) {\n\t\tconst duk_hstring *h;\n\t\tduk_uint32_t hash;\n\n\t\th = duk_rom_strings_lookup[i];\n\t\twhile (h != NULL) {\n\t\t\thash = duk_heap_hashstring(heap, (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\t\t\tDUK_DD(DUK_DDPRINT(\"duk_rom_strings_lookup[%d] -> hash 0x%08lx, computed 0x%08lx\",\n\t\t\t                   (int) i, (unsigned long) DUK_HSTRING_GET_HASH(h), (unsigned long) hash));\n\t\t\tDUK_ASSERT(hash == (duk_uint32_t) DUK_HSTRING_GET_HASH(h));\n\n\t\t\th = (const duk_hstring *) h->hdr.h_next;\n\t\t}\n\t}\n#endif\n\treturn 1;\n}\n#else  /* DUK_USE_ROM_STRINGS */\n\nDUK_LOCAL duk_bool_t duk__init_heap_strings(duk_heap *heap) {\n\tduk_bitdecoder_ctx bd_ctx;\n\tduk_bitdecoder_ctx *bd = &bd_ctx;  /* convenience */\n\tduk_small_uint_t i;\n\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tbd->data = (const duk_uint8_t *) duk_strings_data;\n\tbd->length = (duk_size_t) DUK_STRDATA_DATA_LENGTH;\n\n\tfor (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) {\n\t\tduk_uint8_t tmp[DUK_STRDATA_MAX_STRLEN];\n\t\tduk_small_uint_t len;\n\t\tduk_hstring *h;\n\n\t\tlen = duk_bd_decode_bitpacked_string(bd, tmp);\n\n\t\t/* No need to length check string: it will never exceed even\n\t\t * the 16-bit length maximum.\n\t\t */\n\t\tDUK_ASSERT(len <= 0xffffUL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"intern built-in string %ld\", (long) i));\n\t\th = duk_heap_strtable_intern(heap, tmp, len);\n\t\tif (!h) {\n\t\t\tgoto failed;\n\t\t}\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h));\n\n\t\t/* Special flags checks.  Since these strings are always\n\t\t * reachable and a string cannot appear twice in the string\n\t\t * table, there's no need to check/set these flags elsewhere.\n\t\t * The 'internal' flag is set by string intern code.\n\t\t */\n\t\tif (i == DUK_STRIDX_EVAL || i == DUK_STRIDX_LC_ARGUMENTS) {\n\t\t\tDUK_HSTRING_SET_EVAL_OR_ARGUMENTS(h);\n\t\t}\n\t\tif (i >= DUK_STRIDX_START_RESERVED && i < DUK_STRIDX_END_RESERVED) {\n\t\t\tDUK_HSTRING_SET_RESERVED_WORD(h);\n\t\t\tif (i >= DUK_STRIDX_START_STRICT_RESERVED) {\n\t\t\t\tDUK_HSTRING_SET_STRICT_RESERVED_WORD(h);\n\t\t\t}\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"interned: %!O\", (duk_heaphdr *) h));\n\n\t\t/* XXX: The incref macro takes a thread pointer but doesn't\n\t\t * use it right now.\n\t\t */\n\t\tDUK_HSTRING_INCREF(_never_referenced_, h);\n\n#if defined(DUK_USE_HEAPPTR16)\n\t\theap->strs16[i] = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) h);\n#else\n\t\theap->strs[i] = h;\n#endif\n\t}\n\n\treturn 1;\n\n failed:\n\treturn 0;\n}\n#endif  /* DUK_USE_ROM_STRINGS */\n\nDUK_LOCAL duk_bool_t duk__init_heap_thread(duk_heap *heap) {\n\tduk_hthread *thr;\n\n\tDUK_D(DUK_DPRINT(\"heap init: alloc heap thread\"));\n\tthr = duk_hthread_alloc_unchecked(heap,\n\t                                  DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                  DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_THREAD));\n\tif (thr == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"failed to alloc heap_thread\"));\n\t\treturn 0;\n\t}\n\tthr->state = DUK_HTHREAD_STATE_INACTIVE;\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* No strs[] pointer. */\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n\tthr->strs16 = heap->strs16;\n#else\n\tthr->strs = heap->strs;\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n\theap->heap_thread = thr;\n\tDUK_HTHREAD_INCREF(thr, thr);  /* Note: first argument not really used */\n\n\t/* 'thr' is now reachable */\n\n\tDUK_D(DUK_DPRINT(\"heap init: init heap thread stacks\"));\n\tif (!duk_hthread_init_stacks(heap, thr)) {\n\t\treturn 0;\n\t}\n\n\t/* XXX: this may now fail, and is not handled correctly */\n\tduk_hthread_create_builtin_objects(thr);\n\n\t/* default prototype */\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) thr, thr->builtins[DUK_BIDX_THREAD_PROTOTYPE]);\n\n\treturn 1;\n}\n\n#if defined(DUK_USE_DEBUG)\n#define DUK__DUMPSZ(t)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"\" #t \"=%ld\", (long) sizeof(t))); \\\n\t} while (0)\n\n/* These is not 100% because format would need to be non-portable \"long long\".\n * Also print out as doubles to catch cases where the \"long\" type is not wide\n * enough; the limits will then not be printed accurately but the magnitude\n * will be correct.\n */\n#define DUK__DUMPLM_SIGNED_RAW(t,a,b)  do { \\\n\t\tDUK_D(DUK_DPRINT(t \"=[%ld,%ld]=[%lf,%lf]\", \\\n\t\t                 (long) (a), (long) (b), \\\n\t\t                 (double) (a), (double) (b))); \\\n\t} while (0)\n#define DUK__DUMPLM_UNSIGNED_RAW(t,a,b)  do { \\\n\t\tDUK_D(DUK_DPRINT(t \"=[%lu,%lu]=[%lf,%lf]\", \\\n\t\t                 (unsigned long) (a), (unsigned long) (b), \\\n\t\t                 (double) (a), (double) (b))); \\\n\t} while (0)\n#define DUK__DUMPLM_SIGNED(t)  do { \\\n\t\tDUK__DUMPLM_SIGNED_RAW(\"DUK_\" #t \"_{MIN,MAX}\", DUK_##t##_MIN, DUK_##t##_MAX); \\\n\t} while (0)\n#define DUK__DUMPLM_UNSIGNED(t)  do { \\\n\t\tDUK__DUMPLM_UNSIGNED_RAW(\"DUK_\" #t \"_{MIN,MAX}\", DUK_##t##_MIN, DUK_##t##_MAX); \\\n\t} while (0)\n\nDUK_LOCAL void duk__dump_type_sizes(void) {\n\tDUK_D(DUK_DPRINT(\"sizeof()\"));\n\n\t/* basic platform types */\n\tDUK__DUMPSZ(char);\n\tDUK__DUMPSZ(short);\n\tDUK__DUMPSZ(int);\n\tDUK__DUMPSZ(long);\n\tDUK__DUMPSZ(double);\n\tDUK__DUMPSZ(void *);\n\tDUK__DUMPSZ(size_t);\n\n\t/* basic types from duk_features.h */\n\tDUK__DUMPSZ(duk_uint8_t);\n\tDUK__DUMPSZ(duk_int8_t);\n\tDUK__DUMPSZ(duk_uint16_t);\n\tDUK__DUMPSZ(duk_int16_t);\n\tDUK__DUMPSZ(duk_uint32_t);\n\tDUK__DUMPSZ(duk_int32_t);\n\tDUK__DUMPSZ(duk_uint64_t);\n\tDUK__DUMPSZ(duk_int64_t);\n\tDUK__DUMPSZ(duk_uint_least8_t);\n\tDUK__DUMPSZ(duk_int_least8_t);\n\tDUK__DUMPSZ(duk_uint_least16_t);\n\tDUK__DUMPSZ(duk_int_least16_t);\n\tDUK__DUMPSZ(duk_uint_least32_t);\n\tDUK__DUMPSZ(duk_int_least32_t);\n#if defined(DUK_USE_64BIT_OPS)\n\tDUK__DUMPSZ(duk_uint_least64_t);\n\tDUK__DUMPSZ(duk_int_least64_t);\n#endif\n\tDUK__DUMPSZ(duk_uint_fast8_t);\n\tDUK__DUMPSZ(duk_int_fast8_t);\n\tDUK__DUMPSZ(duk_uint_fast16_t);\n\tDUK__DUMPSZ(duk_int_fast16_t);\n\tDUK__DUMPSZ(duk_uint_fast32_t);\n\tDUK__DUMPSZ(duk_int_fast32_t);\n#if defined(DUK_USE_64BIT_OPS)\n\tDUK__DUMPSZ(duk_uint_fast64_t);\n\tDUK__DUMPSZ(duk_int_fast64_t);\n#endif\n\tDUK__DUMPSZ(duk_uintptr_t);\n\tDUK__DUMPSZ(duk_intptr_t);\n\tDUK__DUMPSZ(duk_uintmax_t);\n\tDUK__DUMPSZ(duk_intmax_t);\n\tDUK__DUMPSZ(duk_double_t);\n\n\t/* important chosen base types */\n\tDUK__DUMPSZ(duk_int_t);\n\tDUK__DUMPSZ(duk_uint_t);\n\tDUK__DUMPSZ(duk_int_fast_t);\n\tDUK__DUMPSZ(duk_uint_fast_t);\n\tDUK__DUMPSZ(duk_small_int_t);\n\tDUK__DUMPSZ(duk_small_uint_t);\n\tDUK__DUMPSZ(duk_small_int_fast_t);\n\tDUK__DUMPSZ(duk_small_uint_fast_t);\n\n\t/* some derived types */\n\tDUK__DUMPSZ(duk_codepoint_t);\n\tDUK__DUMPSZ(duk_ucodepoint_t);\n\tDUK__DUMPSZ(duk_idx_t);\n\tDUK__DUMPSZ(duk_errcode_t);\n\tDUK__DUMPSZ(duk_uarridx_t);\n\n\t/* tval */\n\tDUK__DUMPSZ(duk_double_union);\n\tDUK__DUMPSZ(duk_tval);\n\n\t/* structs from duk_forwdecl.h */\n\tDUK__DUMPSZ(duk_jmpbuf);  /* just one 'int' for C++ exceptions */\n\tDUK__DUMPSZ(duk_heaphdr);\n\tDUK__DUMPSZ(duk_heaphdr_string);\n\tDUK__DUMPSZ(duk_hstring);\n\tDUK__DUMPSZ(duk_hstring_external);\n\tDUK__DUMPSZ(duk_hobject);\n\tDUK__DUMPSZ(duk_harray);\n\tDUK__DUMPSZ(duk_hcompfunc);\n\tDUK__DUMPSZ(duk_hnatfunc);\n\tDUK__DUMPSZ(duk_hdecenv);\n\tDUK__DUMPSZ(duk_hobjenv);\n\tDUK__DUMPSZ(duk_hthread);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tDUK__DUMPSZ(duk_hbufobj);\n#endif\n\tDUK__DUMPSZ(duk_hproxy);\n\tDUK__DUMPSZ(duk_hbuffer);\n\tDUK__DUMPSZ(duk_hbuffer_fixed);\n\tDUK__DUMPSZ(duk_hbuffer_dynamic);\n\tDUK__DUMPSZ(duk_hbuffer_external);\n\tDUK__DUMPSZ(duk_propaccessor);\n\tDUK__DUMPSZ(duk_propvalue);\n\tDUK__DUMPSZ(duk_propdesc);\n\tDUK__DUMPSZ(duk_heap);\n\tDUK__DUMPSZ(duk_activation);\n\tDUK__DUMPSZ(duk_catcher);\n\tDUK__DUMPSZ(duk_strcache_entry);\n\tDUK__DUMPSZ(duk_litcache_entry);\n\tDUK__DUMPSZ(duk_ljstate);\n\tDUK__DUMPSZ(duk_fixedbuffer);\n\tDUK__DUMPSZ(duk_bitdecoder_ctx);\n\tDUK__DUMPSZ(duk_bitencoder_ctx);\n\tDUK__DUMPSZ(duk_token);\n\tDUK__DUMPSZ(duk_re_token);\n\tDUK__DUMPSZ(duk_lexer_point);\n\tDUK__DUMPSZ(duk_lexer_ctx);\n\tDUK__DUMPSZ(duk_compiler_instr);\n\tDUK__DUMPSZ(duk_compiler_func);\n\tDUK__DUMPSZ(duk_compiler_ctx);\n\tDUK__DUMPSZ(duk_re_matcher_ctx);\n\tDUK__DUMPSZ(duk_re_compiler_ctx);\n}\nDUK_LOCAL void duk__dump_type_limits(void) {\n\tDUK_D(DUK_DPRINT(\"limits\"));\n\n\t/* basic types */\n\tDUK__DUMPLM_SIGNED(INT8);\n\tDUK__DUMPLM_UNSIGNED(UINT8);\n\tDUK__DUMPLM_SIGNED(INT_FAST8);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST8);\n\tDUK__DUMPLM_SIGNED(INT_LEAST8);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST8);\n\tDUK__DUMPLM_SIGNED(INT16);\n\tDUK__DUMPLM_UNSIGNED(UINT16);\n\tDUK__DUMPLM_SIGNED(INT_FAST16);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST16);\n\tDUK__DUMPLM_SIGNED(INT_LEAST16);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST16);\n\tDUK__DUMPLM_SIGNED(INT32);\n\tDUK__DUMPLM_UNSIGNED(UINT32);\n\tDUK__DUMPLM_SIGNED(INT_FAST32);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST32);\n\tDUK__DUMPLM_SIGNED(INT_LEAST32);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST32);\n#if defined(DUK_USE_64BIT_OPS)\n\tDUK__DUMPLM_SIGNED(INT64);\n\tDUK__DUMPLM_UNSIGNED(UINT64);\n\tDUK__DUMPLM_SIGNED(INT_FAST64);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST64);\n\tDUK__DUMPLM_SIGNED(INT_LEAST64);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST64);\n#endif\n\tDUK__DUMPLM_SIGNED(INTPTR);\n\tDUK__DUMPLM_UNSIGNED(UINTPTR);\n\tDUK__DUMPLM_SIGNED(INTMAX);\n\tDUK__DUMPLM_UNSIGNED(UINTMAX);\n\n\t/* derived types */\n\tDUK__DUMPLM_SIGNED(INT);\n\tDUK__DUMPLM_UNSIGNED(UINT);\n\tDUK__DUMPLM_SIGNED(INT_FAST);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST);\n\tDUK__DUMPLM_SIGNED(SMALL_INT);\n\tDUK__DUMPLM_UNSIGNED(SMALL_UINT);\n\tDUK__DUMPLM_SIGNED(SMALL_INT_FAST);\n\tDUK__DUMPLM_UNSIGNED(SMALL_UINT_FAST);\n}\n\nDUK_LOCAL void duk__dump_misc_options(void) {\n\tDUK_D(DUK_DPRINT(\"DUK_VERSION: %ld\", (long) DUK_VERSION));\n\tDUK_D(DUK_DPRINT(\"DUK_GIT_DESCRIBE: %s\", DUK_GIT_DESCRIBE));\n\tDUK_D(DUK_DPRINT(\"OS string: %s\", DUK_USE_OS_STRING));\n\tDUK_D(DUK_DPRINT(\"architecture string: %s\", DUK_USE_ARCH_STRING));\n\tDUK_D(DUK_DPRINT(\"compiler string: %s\", DUK_USE_COMPILER_STRING));\n\tDUK_D(DUK_DPRINT(\"debug level: %ld\", (long) DUK_USE_DEBUG_LEVEL));\n#if defined(DUK_USE_PACKED_TVAL)\n\tDUK_D(DUK_DPRINT(\"DUK_USE_PACKED_TVAL: yes\"));\n#else\n\tDUK_D(DUK_DPRINT(\"DUK_USE_PACKED_TVAL: no\"));\n#endif\n#if defined(DUK_USE_VARIADIC_MACROS)\n\tDUK_D(DUK_DPRINT(\"DUK_USE_VARIADIC_MACROS: yes\"));\n#else\n\tDUK_D(DUK_DPRINT(\"DUK_USE_VARIADIC_MACROS: no\"));\n#endif\n#if defined(DUK_USE_INTEGER_LE)\n\tDUK_D(DUK_DPRINT(\"integer endianness: little\"));\n#elif defined(DUK_USE_INTEGER_ME)\n\tDUK_D(DUK_DPRINT(\"integer endianness: mixed\"));\n#elif defined(DUK_USE_INTEGER_BE)\n\tDUK_D(DUK_DPRINT(\"integer endianness: big\"));\n#else\n\tDUK_D(DUK_DPRINT(\"integer endianness: ???\"));\n#endif\n#if defined(DUK_USE_DOUBLE_LE)\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: little\"));\n#elif defined(DUK_USE_DOUBLE_ME)\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: mixed\"));\n#elif defined(DUK_USE_DOUBLE_BE)\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: big\"));\n#else\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: ???\"));\n#endif\n}\n#endif  /* DUK_USE_DEBUG */\n\nDUK_INTERNAL\nduk_heap *duk_heap_alloc(duk_alloc_function alloc_func,\n                         duk_realloc_function realloc_func,\n                         duk_free_function free_func,\n                         void *heap_udata,\n                         duk_fatal_function fatal_func) {\n\tduk_heap *res = NULL;\n\tduk_uint32_t st_initsize;\n\n\tDUK_D(DUK_DPRINT(\"allocate heap\"));\n\n\t/*\n\t *  Random config sanity asserts\n\t */\n\n\tDUK_ASSERT(DUK_USE_STRTAB_MINSIZE >= 64);\n\n\tDUK_ASSERT((DUK_HTYPE_STRING & 0x01U) == 0);\n\tDUK_ASSERT((DUK_HTYPE_BUFFER & 0x01U) == 0);\n\tDUK_ASSERT((DUK_HTYPE_OBJECT & 0x01U) == 1);  /* DUK_HEAPHDR_IS_OBJECT() relies ont his. */\n\n\t/*\n\t *  Debug dump type sizes\n\t */\n\n#if defined(DUK_USE_DEBUG)\n\tduk__dump_misc_options();\n\tduk__dump_type_sizes();\n\tduk__dump_type_limits();\n#endif\n\n\t/*\n\t *  If selftests enabled, run them as early as possible.\n\t */\n\n#if defined(DUK_USE_SELF_TESTS)\n\tDUK_D(DUK_DPRINT(\"run self tests\"));\n\tif (duk_selftest_run_tests(alloc_func, realloc_func, free_func, heap_udata) > 0) {\n\t\tfatal_func(heap_udata, \"self test(s) failed\");\n\t}\n\tDUK_D(DUK_DPRINT(\"self tests passed\"));\n#endif\n\n\t/*\n\t *  Important assert-like checks that should be enabled even\n\t *  when assertions are otherwise not enabled.\n\t */\n\n#if defined(DUK_USE_EXEC_REGCONST_OPTIMIZE)\n\t/* Can't check sizeof() using preprocessor so explicit check.\n\t * This will be optimized away in practice; unfortunately a\n\t * warning is generated on some compilers as a result.\n\t */\n#if defined(DUK_USE_PACKED_TVAL)\n\tif (sizeof(duk_tval) != 8) {\n#else\n\tif (sizeof(duk_tval) != 16) {\n#endif\n\t\tfatal_func(heap_udata, \"sizeof(duk_tval) not 8 or 16, cannot use DUK_USE_EXEC_REGCONST_OPTIMIZE option\");\n\t}\n#endif  /* DUK_USE_EXEC_REGCONST_OPTIMIZE */\n\n\t/*\n\t *  Computed values (e.g. INFINITY)\n\t */\n\n#if defined(DUK_USE_COMPUTED_NAN)\n\tdo {\n\t\t/* Workaround for some exotic platforms where NAN is missing\n\t\t * and the expression (0.0 / 0.0) does NOT result in a NaN.\n\t\t * Such platforms use the global 'duk_computed_nan' which must\n\t\t * be initialized at runtime.  Use 'volatile' to ensure that\n\t\t * the compiler will actually do the computation and not try\n\t\t * to do constant folding which might result in the original\n\t\t * problem.\n\t\t */\n\t\tvolatile double dbl1 = 0.0;\n\t\tvolatile double dbl2 = 0.0;\n\t\tduk_computed_nan = dbl1 / dbl2;\n\t} while (0);\n#endif\n\n#if defined(DUK_USE_COMPUTED_INFINITY)\n\tdo {\n\t\t/* Similar workaround for INFINITY. */\n\t\tvolatile double dbl1 = 1.0;\n\t\tvolatile double dbl2 = 0.0;\n\t\tduk_computed_infinity = dbl1 / dbl2;\n\t} while (0);\n#endif\n\n\t/*\n\t *  Allocate heap struct\n\t *\n\t *  Use a raw call, all macros expect the heap to be initialized\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 1)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"alloc duk_heap object\"));\n\tres = (duk_heap *) alloc_func(heap_udata, sizeof(duk_heap));\n\tif (!res) {\n\t\tgoto failed;\n\t}\n\n\t/*\n\t *  Zero the struct, and start initializing roughly in order\n\t */\n\n\tduk_memzero(res, sizeof(*res));\n#if defined(DUK_USE_ASSERTIONS)\n\tres->heap_initializing = 1;\n#endif\n\n\t/* explicit NULL inits */\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->heap_udata = NULL;\n\tres->heap_allocated = NULL;\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tres->refzero_list = NULL;\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tres->finalize_list = NULL;\n#if defined(DUK_USE_ASSERTIONS)\n\tres->currently_finalizing = NULL;\n#endif\n#endif\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\tres->activation_free = NULL;\n#endif\n#if defined(DUK_USE_CACHE_CATCHER)\n\tres->catcher_free = NULL;\n#endif\n\tres->heap_thread = NULL;\n\tres->curr_thread = NULL;\n\tres->heap_object = NULL;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tres->strtable16 = NULL;\n#else\n\tres->strtable = NULL;\n#endif\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* no res->strs[] */\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n\t/* res->strs16[] is zeroed and zero decodes to NULL, so no NULL inits. */\n#else\n\t{\n\t\tduk_small_uint_t i;\n\t        for (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) {\n\t\t\tres->strs[i] = NULL;\n\t        }\n\t}\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tres->dbg_read_cb = NULL;\n\tres->dbg_write_cb = NULL;\n\tres->dbg_peek_cb = NULL;\n\tres->dbg_read_flush_cb = NULL;\n\tres->dbg_write_flush_cb = NULL;\n\tres->dbg_request_cb = NULL;\n\tres->dbg_udata = NULL;\n\tres->dbg_pause_act = NULL;\n#endif\n#endif  /* DUK_USE_EXPLICIT_NULL_INIT */\n\n\tres->alloc_func = alloc_func;\n\tres->realloc_func = realloc_func;\n\tres->free_func = free_func;\n\tres->heap_udata = heap_udata;\n\tres->fatal_func = fatal_func;\n\n\t/* XXX: for now there's a pointer packing zero assumption, i.e.\n\t * NULL <=> compressed pointer 0.  If this is removed, may need\n\t * to precompute e.g. null16 here.\n\t */\n\n\t/* res->ms_trigger_counter == 0 -> now causes immediate GC; which is OK */\n\n\t/* Prevent mark-and-sweep and finalizer execution until heap is completely\n\t * initialized.\n\t */\n\tDUK_ASSERT(res->ms_prevent_count == 0);\n\tDUK_ASSERT(res->pf_prevent_count == 0);\n\tres->ms_prevent_count = 1;\n\tres->pf_prevent_count = 1;\n\tDUK_ASSERT(res->ms_running == 0);\n\n\tres->call_recursion_depth = 0;\n\tres->call_recursion_limit = DUK_USE_NATIVE_CALL_RECLIMIT;\n\n\t/* XXX: use the pointer as a seed for now: mix in time at least */\n\n\t/* The casts through duk_uintptr_t is to avoid the following GCC warning:\n\t *\n\t *   warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]\n\t *\n\t * This still generates a /Wp64 warning on VS2010 when compiling for x86.\n\t */\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* XXX: make a common DUK_USE_ option, and allow custom fixed seed? */\n\tDUK_D(DUK_DPRINT(\"using rom strings, force heap hash_seed to fixed value 0x%08lx\", (long) DUK__FIXED_HASH_SEED));\n\tres->hash_seed = (duk_uint32_t) DUK__FIXED_HASH_SEED;\n#else  /* DUK_USE_ROM_STRINGS */\n\tres->hash_seed = (duk_uint32_t) (duk_uintptr_t) res;\n#if !defined(DUK_USE_STRHASH_DENSE)\n\tres->hash_seed ^= 5381;  /* Bernstein hash init value is normally 5381; XOR it in in case pointer low bits are 0 */\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->lj.jmpbuf_ptr = NULL;\n#endif\n\tDUK_ASSERT(res->lj.type == DUK_LJ_TYPE_UNKNOWN);  /* zero */\n\tDUK_ASSERT(res->lj.iserror == 0);\n\tDUK_TVAL_SET_UNDEFINED(&res->lj.value1);\n\tDUK_TVAL_SET_UNDEFINED(&res->lj.value2);\n\n\tDUK_ASSERT_LJSTATE_UNSET(res);\n\n\t/*\n\t *  Init stringtable: fixed variant\n\t */\n\n\tst_initsize = DUK_USE_STRTAB_MINSIZE;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tres->strtable16 = (duk_uint16_t *) alloc_func(heap_udata, sizeof(duk_uint16_t) * st_initsize);\n\tif (res->strtable16 == NULL) {\n\t\tgoto failed;\n\t}\n#else\n\tres->strtable = (duk_hstring **) alloc_func(heap_udata, sizeof(duk_hstring *) * st_initsize);\n\tif (res->strtable == NULL) {\n\t\tgoto failed;\n\t}\n#endif\n\tres->st_size = st_initsize;\n\tres->st_mask = st_initsize - 1;\n#if (DUK_USE_STRTAB_MINSIZE != DUK_USE_STRTAB_MAXSIZE)\n\tDUK_ASSERT(res->st_count == 0);\n#endif\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t/* zero assumption */\n\tduk_memzero(res->strtable16, sizeof(duk_uint16_t) * st_initsize);\n#else\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t{\n\t\tduk_uint32_t i;\n\t        for (i = 0; i < st_initsize; i++) {\n\t\t\tres->strtable[i] = NULL;\n\t        }\n\t}\n#else\n\tduk_memzero(res->strtable, sizeof(duk_hstring *) * st_initsize);\n#endif  /* DUK_USE_EXPLICIT_NULL_INIT */\n#endif  /* DUK_USE_STRTAB_PTRCOMP */\n\n\t/*\n\t *  Init stringcache\n\t */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t{\n\t\tduk_uint_t i;\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tres->strcache[i].h = NULL;\n\t\t}\n\t}\n#endif\n\n\t/*\n\t *  Init litcache\n\t */\n#if defined(DUK_USE_LITCACHE_SIZE)\n\tDUK_ASSERT(DUK_USE_LITCACHE_SIZE > 0);\n\tDUK_ASSERT(DUK_IS_POWER_OF_TWO((duk_uint_t) DUK_USE_LITCACHE_SIZE));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t{\n\t\tduk_uint_t i;\n\t\tfor (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) {\n\t\t\tres->litcache[i].addr = NULL;\n\t\t\tres->litcache[i].h = NULL;\n\t\t}\n\t}\n#endif\n#endif  /* DUK_USE_LITCACHE_SIZE */\n\n\t/* XXX: error handling is incomplete.  It would be cleanest if\n\t * there was a setjmp catchpoint, so that all init code could\n\t * freely throw errors.  If that were the case, the return code\n\t * passing here could be removed.\n\t */\n\n\t/*\n\t *  Init built-in strings\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 2)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"heap init: initialize heap strings\"));\n\tif (!duk__init_heap_strings(res)) {\n\t\tgoto failed;\n\t}\n\n\t/*\n\t *  Init the heap thread\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 3)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"heap init: initialize heap thread\"));\n\tif (!duk__init_heap_thread(res)) {\n\t\tgoto failed;\n\t}\n\n\t/*\n\t *  Init the heap object\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 4)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"heap init: initialize heap object\"));\n\tDUK_ASSERT(res->heap_thread != NULL);\n\tres->heap_object = duk_hobject_alloc_unchecked(res, DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                                    DUK_HOBJECT_FLAG_FASTREFS |\n\t                                                    DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT));\n\tif (res->heap_object == NULL) {\n\t\tgoto failed;\n\t}\n\tDUK_HOBJECT_INCREF(res->heap_thread, res->heap_object);\n\n\t/*\n\t *  Odds and ends depending on the heap thread\n\t */\n\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\n#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS)\n\tres->rnd_state = (duk_uint32_t) duk_time_get_ecmascript_time(res->heap_thread);\n\tduk_util_tinyrandom_prepare_seed(res->heap_thread);\n#else\n\tres->rnd_state[0] = (duk_uint64_t) duk_time_get_ecmascript_time(res->heap_thread);\n\tDUK_ASSERT(res->rnd_state[1] == 0);  /* Not filled here, filled in by seed preparation. */\n#if 0  /* Manual test values matching misc/xoroshiro128plus_test.c. */\n\tres->rnd_state[0] = DUK_U64_CONSTANT(0xdeadbeef12345678);\n\tres->rnd_state[1] = DUK_U64_CONSTANT(0xcafed00d12345678);\n#endif\n\tduk_util_tinyrandom_prepare_seed(res->heap_thread);\n\t/* Mix in heap pointer: this ensures that if two Duktape heaps are\n\t * created on the same millisecond, they get a different PRNG\n\t * sequence (unless e.g. virtual memory addresses cause also the\n\t * heap object pointer to be the same).\n\t */\n\t{\n\t\tduk_uint64_t tmp_u64;\n\t\ttmp_u64 = 0;\n\t\tduk_memcpy((void *) &tmp_u64,\n\t\t           (const void *) &res,\n\t\t           (size_t) (sizeof(void *) >= sizeof(duk_uint64_t) ? sizeof(duk_uint64_t) : sizeof(void *)));\n\t\tres->rnd_state[1] ^= tmp_u64;\n\t}\n\tdo {\n\t\tduk_small_uint_t i;\n\t\tfor (i = 0; i < 10; i++) {\n\t\t\t/* Throw away a few initial random numbers just in\n\t\t\t * case.  Probably unnecessary due to SplitMix64\n\t\t\t * preparation.\n\t\t\t */\n\t\t\t(void) duk_util_tinyrandom_get_double(res->heap_thread);\n\t\t}\n\t} while (0);\n#endif\n#endif\n\n\t/*\n\t *  Allow finalizer and mark-and-sweep processing.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"heap init: allow finalizer/mark-and-sweep processing\"));\n\tDUK_ASSERT(res->ms_prevent_count == 1);\n\tDUK_ASSERT(res->pf_prevent_count == 1);\n\tres->ms_prevent_count = 0;\n\tres->pf_prevent_count = 0;\n\tDUK_ASSERT(res->ms_running == 0);\n#if defined(DUK_USE_ASSERTIONS)\n\tres->heap_initializing = 0;\n#endif\n\n\t/*\n\t *  All done.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"allocated heap: %p\", (void *) res));\n\treturn res;\n\n failed:\n\tDUK_D(DUK_DPRINT(\"heap allocation failed\"));\n\n\tif (res != NULL) {\n\t\t/* Assumes that allocated pointers and alloc funcs are valid\n\t\t * if res exists.\n\t\t */\n\t\tDUK_ASSERT(res->ms_prevent_count == 1);\n\t\tDUK_ASSERT(res->pf_prevent_count == 1);\n\t\tDUK_ASSERT(res->ms_running == 0);\n\t\tif (res->heap_thread != NULL) {\n\t\t\tres->ms_prevent_count = 0;\n\t\t\tres->pf_prevent_count = 0;\n\t\t}\n#if defined(DUK_USE_ASSERTIONS)\n\t\tres->heap_initializing = 0;\n#endif\n\n\t\tDUK_ASSERT(res->alloc_func != NULL);\n\t\tDUK_ASSERT(res->realloc_func != NULL);\n\t\tDUK_ASSERT(res->free_func != NULL);\n\t\tduk_heap_free(res);\n\t}\n\n\treturn NULL;\n}\n\n/* automatic undefs */\n#undef DUK__DUMPLM_SIGNED\n#undef DUK__DUMPLM_SIGNED_RAW\n#undef DUK__DUMPLM_UNSIGNED\n#undef DUK__DUMPLM_UNSIGNED_RAW\n#undef DUK__DUMPSZ\n#undef DUK__FIXED_HASH_SEED\n#line 1 \"duk_heap_finalize.c\"\n/*\n *  Finalizer handling.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\n/*\n *  Fake torture finalizer.\n */\n\n#if defined(DUK_USE_FINALIZER_TORTURE)\nDUK_LOCAL duk_ret_t duk__fake_global_finalizer(duk_hthread *thr) {\n\tDUK_DD(DUK_DDPRINT(\"fake global torture finalizer executed\"));\n\n\t/* Require a lot of stack to force a value stack grow/shrink. */\n\tduk_require_stack(thr, 100000);\n\n\t/* Force a reallocation with pointer change for value stack\n\t * to maximize side effects.\n\t */\n\tduk_hthread_valstack_torture_realloc(thr);\n\n\t/* Inner function call, error throw. */\n\tduk_eval_string_noresult(thr,\n\t\t\"(function dummy() {\\n\"\n\t\t\"    dummy.prototype = null;  /* break reference loop */\\n\"\n\t\t\"    try {\\n\"\n\t\t\"        throw 'fake-finalizer-dummy-error';\\n\"\n\t\t\"    } catch (e) {\\n\"\n\t\t\"        void e;\\n\"\n\t\t\"    }\\n\"\n\t\t\"})()\");\n\n\t/* The above creates garbage (e.g. a function instance).  Because\n\t * the function/prototype reference loop is broken, it gets collected\n\t * immediately by DECREF.  If Function.prototype has a _Finalizer\n\t * property (happens in some test cases), the garbage gets queued to\n\t * finalize_list.  This still won't cause an infinite loop because\n\t * the torture finalizer is called once per finalize_list run and\n\t * the garbage gets handled in the same run.  (If the garbage needs\n\t * mark-and-sweep collection, an infinite loop might ensue.)\n\t */\n\treturn 0;\n}\n\nDUK_LOCAL void duk__run_global_torture_finalizer(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Avoid fake finalization when callstack limit is near.  Otherwise\n\t * a callstack limit error will be created, then refzero'ed.  The\n\t * +5 headroom is conservative.\n\t */\n\tif (thr->heap->call_recursion_depth + 5 >= thr->heap->call_recursion_limit ||\n\t    thr->callstack_top + 5 >= DUK_USE_CALLSTACK_LIMIT) {\n\t\tDUK_D(DUK_DPRINT(\"skip global torture finalizer, too little headroom for call recursion or call stack size\"));\n\t\treturn;\n\t}\n\n\t/* Run fake finalizer.  Avoid creating unnecessary garbage. */\n\tduk_push_c_function(thr, duk__fake_global_finalizer, 0 /*nargs*/);\n\t(void) duk_pcall(thr, 0 /*nargs*/);\n\tduk_pop(thr);\n}\n#endif  /* DUK_USE_FINALIZER_TORTURE */\n\n/*\n *  Process the finalize_list to completion.\n *\n *  An object may be placed on finalize_list by either refcounting or\n *  mark-and-sweep.  The refcount of objects placed by refcounting will be\n *  zero; the refcount of objects placed by mark-and-sweep is > 0.  In both\n *  cases the refcount is bumped by 1 artificially so that a REFZERO event\n *  can never happen while an object is waiting for finalization.  Without\n *  this bump a REFZERO could now happen because user code may call\n *  duk_push_heapptr() and then pop a value even when it's on finalize_list.\n *\n *  List processing assumes refcounts are kept up-to-date at all times, so\n *  that once the finalizer returns, a zero refcount is a reliable reason to\n *  free the object immediately rather than place it back to the heap.  This\n *  is the case because we run outside of refzero_list processing so that\n *  DECREF cascades are handled fully inline.\n *\n *  For mark-and-sweep queued objects (had_zero_refcount false) the object\n *  may be freed immediately if its refcount is zero after the finalizer call\n *  (i.e. finalizer removed the reference loop for the object).  If not, the\n *  next mark-and-sweep will collect the object unless it has become reachable\n *  (i.e. rescued) by that time and its refcount hasn't fallen to zero before\n *  that.  Mark-and-sweep detects these objects because their FINALIZED flag\n *  is set.\n *\n *  There's an inherent limitation for mark-and-sweep finalizer rescuing: an\n *  object won't get refinalized if (1) it's rescued, but (2) becomes\n *  unreachable before mark-and-sweep has had time to notice it.  The next\n *  mark-and-sweep round simply doesn't have any information of whether the\n *  object has been unreachable the whole time or not (the only way to get\n *  that information would be a mark-and-sweep pass for *every finalized\n *  object*).  This is awkward for the application because the mark-and-sweep\n *  round is not generally visible or under full application control.\n *\n *  For refcount queued objects (had_zero_refcount true) the object is either\n *  immediately freed or rescued, and waiting for a mark-and-sweep round is not\n *  necessary (or desirable); FINALIZED is cleared when a rescued object is\n *  queued back to heap_allocated.  The object is eligible for finalization\n *  again (either via refcounting or mark-and-sweep) immediately after being\n *  rescued.  If a refcount finalized object is placed into an unreachable\n *  reference loop by its finalizer, it will get collected by mark-and-sweep\n *  and currently the finalizer will execute again.\n *\n *  There's a special case where:\n *\n *    - Mark-and-sweep queues an object to finalize_list for finalization.\n *    - The finalizer is executed, FINALIZED is set, and object is queued\n *      back to heap_allocated, waiting for a new mark-and-sweep round.\n *    - The object's refcount drops to zero before mark-and-sweep has a\n *      chance to run another round and make a rescue/free decision.\n *\n *  This is now handled by refzero code: if an object has a finalizer but\n *  FINALIZED is already set, the object is freed without finalizer processing.\n *  The outcome is the same as if mark-and-sweep was executed at that point;\n *  mark-and-sweep would also free the object without another finalizer run.\n *  This could also be changed so that the refzero-triggered finalizer *IS*\n *  executed: being refzero collected implies someone has operated on the\n *  object so it hasn't been totally unreachable the whole time.  This would\n *  risk a finalizer loop however.\n */\n\nDUK_INTERNAL void duk_heap_process_finalize_list(duk_heap *heap) {\n\tduk_heaphdr *curr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count = 0;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk_heap_process_finalize_list: %p\", (void *) heap));\n\n\tif (heap->pf_prevent_count != 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"skip finalize_list processing: pf_prevent_count != 0\"));\n\t\treturn;\n\t}\n\n\t/* Heap alloc prevents mark-and-sweep before heap_thread is ready. */\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(heap->heap_thread->valstack != NULL);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);\n#endif\n\n\tDUK_ASSERT(heap->pf_prevent_count == 0);\n\theap->pf_prevent_count = 1;\n\n\t/* Mark-and-sweep no longer needs to be prevented when running\n\t * finalizers: mark-and-sweep skips any rescue decisions if there\n\t * are any objects in finalize_list when mark-and-sweep is entered.\n\t * This protects finalized objects from incorrect rescue decisions\n\t * caused by finalize_list being a reachability root and only\n\t * partially processed.  Freeing decisions are not postponed.\n\t */\n\n\t/* When finalizer torture is enabled, make a fake finalizer call with\n\t * maximum side effects regardless of whether finalize_list is empty.\n\t */\n#if defined(DUK_USE_FINALIZER_TORTURE)\n\tduk__run_global_torture_finalizer(heap->heap_thread);\n#endif\n\n\t/* Process finalize_list until it becomes empty.  There's currently no\n\t * protection against a finalizer always creating more garbage.\n\t */\n\twhile ((curr = heap->finalize_list) != NULL) {\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tduk_bool_t queue_back;\n#endif\n\n\t\tDUK_DD(DUK_DDPRINT(\"processing finalize_list entry: %p -> %!iO\", (void *) curr, curr));\n\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);  /* Only objects have finalizers. */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(curr));\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(curr));\n\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZABLE(curr));  /* All objects on finalize_list will have this flag (except object being finalized right now). */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));   /* Queueing code ensures. */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(curr));  /* ROM objects never get freed (or finalized). */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\tDUK_ASSERT(heap->currently_finalizing == NULL);\n\t\theap->currently_finalizing = curr;\n#endif\n\n\t\t/* Clear FINALIZABLE for object being finalized, so that\n\t\t * duk_push_heapptr() can properly ignore the object.\n\t\t */\n\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\n\t\tif (DUK_LIKELY(!heap->pf_skip_finalizers)) {\n\t\t\t/* Run the finalizer, duk_heap_run_finalizer() sets\n\t\t\t * and checks for FINALIZED to prevent the finalizer\n\t\t\t * from executing multiple times per finalization cycle.\n\t\t\t * (This safeguard shouldn't be actually needed anymore).\n\t\t\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tduk_bool_t had_zero_refcount;\n#endif\n\n\t\t\t/* The object's refcount is >0 throughout so it won't be\n\t\t\t * refzero processed prematurely.\n\t\t\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) >= 1);\n\t\t\thad_zero_refcount = (DUK_HEAPHDR_GET_REFCOUNT(curr) == 1);  /* Preincremented on finalize_list insert. */\n#endif\n\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));\n\t\t\tduk_heap_run_finalizer(heap, (duk_hobject *) curr);  /* must never longjmp */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZED(curr));\n\t\t\t/* XXX: assert that object is still in finalize_list\n\t\t\t * when duk_push_heapptr() allows automatic rescue.\n\t\t\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tDUK_DD(DUK_DDPRINT(\"refcount after finalizer (includes bump): %ld\", (long) DUK_HEAPHDR_GET_REFCOUNT(curr)));\n\t\t\tif (DUK_HEAPHDR_GET_REFCOUNT(curr) == 1) {  /* Only artificial bump in refcount? */\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tif (had_zero_refcount) {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"finalized object's refcount is zero -> free immediately (refcount queued)\"));\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"finalized object's refcount is zero -> free immediately (mark-and-sweep queued)\"));\n\t\t\t\t}\n#endif\n\t\t\t\tqueue_back = 0;\n\t\t\t} else\n#endif\n\t\t\t{\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t\tqueue_back = 1;\n\t\t\t\tif (had_zero_refcount) {\n\t\t\t\t\t/* When finalization is triggered\n\t\t\t\t\t * by refzero and we queue the object\n\t\t\t\t\t * back, clear FINALIZED right away\n\t\t\t\t\t * so that the object can be refinalized\n\t\t\t\t\t * immediately if necessary.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_HEAPHDR_CLEAR_FINALIZED(curr);\n\t\t\t\t}\n#endif\n\t\t\t}\n\t\t} else {\n\t\t\t/* Used during heap destruction: don't actually run finalizers\n\t\t\t * because we're heading into forced finalization.  Instead,\n\t\t\t * queue finalizable objects back to the heap_allocated list.\n\t\t\t */\n\t\t\tDUK_D(DUK_DPRINT(\"skip finalizers flag set, queue object to heap_allocated without finalizing\"));\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tqueue_back = 1;\n#endif\n\t\t}\n\n\t\t/* Dequeue object from finalize_list.  Note that 'curr' may no\n\t\t * longer be finalize_list head because new objects may have\n\t\t * been queued to the list.  As a result we can't optimize for\n\t\t * the single-linked heap case and must scan the list for\n\t\t * removal, typically the scan is very short however.\n\t\t */\n\t\tDUK_HEAP_REMOVE_FROM_FINALIZE_LIST(heap, curr);\n\n\t\t/* Queue back to heap_allocated or free immediately. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tif (queue_back) {\n\t\t\t/* FINALIZED is only cleared if object originally\n\t\t\t * queued for finalization by refcounting.  For\n\t\t\t * mark-and-sweep FINALIZED is left set, so that\n\t\t\t * next mark-and-sweep round can make a rescue/free\n\t\t\t * decision.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) >= 1);\n\t\t\tDUK_HEAPHDR_PREDEC_REFCOUNT(curr);  /* Remove artificial refcount bump. */\n\t\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\t\t\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, curr);\n\t\t} else {\n\t\t\t/* No need to remove the refcount bump here. */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);  /* currently, always the case */\n\t\t\tDUK_DD(DUK_DDPRINT(\"refcount finalize after finalizer call: %!O\", curr));\n\t\t\tduk_hobject_refcount_finalize_norz(heap, (duk_hobject *) curr);\n\t\t\tduk_free_hobject(heap, (duk_hobject *) curr);\n\t\t\tDUK_DD(DUK_DDPRINT(\"freed hobject after finalization: %p\", (void *) curr));\n\t\t}\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\t\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, curr);\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_DEBUG)\n\t\tcount++;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\tDUK_ASSERT(heap->currently_finalizing != NULL);\n\t\theap->currently_finalizing = NULL;\n#endif\n\t}\n\n\t/* finalize_list will always be processed completely. */\n\tDUK_ASSERT(heap->finalize_list == NULL);\n\n#if 0\n\t/* While NORZ macros are used above, this is unnecessary because the\n\t * only pending side effects are now finalizers, and finalize_list is\n\t * empty.\n\t */\n\tDUK_REFZERO_CHECK_SLOW(heap->heap_thread);\n#endif\n\n\t/* Prevent count may be bumped while finalizers run, but should always\n\t * be reliably unbumped by the time we get here.\n\t */\n\tDUK_ASSERT(heap->pf_prevent_count == 1);\n\theap->pf_prevent_count = 0;\n\n#if defined(DUK_USE_DEBUG)\n\tDUK_DD(DUK_DDPRINT(\"duk_heap_process_finalize_list: %ld finalizers called\", (long) count));\n#endif\n}\n\n/*\n *  Run an duk_hobject finalizer.  Must never throw an uncaught error\n *  (but may throw caught errors).\n *\n *  There is no return value.  Any return value or error thrown by\n *  the finalizer is ignored (although errors are debug logged).\n *\n *  Notes:\n *\n *    - The finalizer thread 'top' assertions are there because it is\n *      critical that strict stack policy is observed (i.e. no cruft\n *      left on the finalizer stack).\n */\n\nDUK_LOCAL duk_ret_t duk__finalize_helper(duk_hthread *thr, void *udata) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_UNREF(udata);\n\n\tDUK_DDD(DUK_DDDPRINT(\"protected finalization helper running\"));\n\n\t/* [... obj] */\n\n\t/* _Finalizer property is read without checking if the value is\n\t * callable or even exists.  This is intentional, and handled\n\t * by throwing an error which is caught by the safe call wrapper.\n\t *\n\t * XXX: Finalizer lookup should traverse the prototype chain (to allow\n\t * inherited finalizers) but should not invoke accessors or proxy object\n\t * behavior.  At the moment this lookup will invoke proxy behavior, so\n\t * caller must ensure that this function is not called if the target is\n\t * a Proxy.\n\t */\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_FINALIZER);  /* -> [... obj finalizer] */\n\tduk_dup_m2(thr);\n\tduk_push_boolean(thr, DUK_HEAP_HAS_FINALIZER_NORESCUE(thr->heap));\n\tDUK_DDD(DUK_DDDPRINT(\"calling finalizer\"));\n\tduk_call(thr, 2);  /* [ ... obj finalizer obj heapDestruct ]  -> [ ... obj retval ] */\n\tDUK_DDD(DUK_DDDPRINT(\"finalizer returned successfully\"));\n\treturn 0;\n\n\t/* Note: we rely on duk_safe_call() to fix up the stack for the caller,\n\t * so we don't need to pop stuff here.  There is no return value;\n\t * caller determines rescued status based on object refcount.\n\t */\n}\n\nDUK_INTERNAL void duk_heap_run_finalizer(duk_heap *heap, duk_hobject *obj) {\n\tduk_hthread *thr;\n\tduk_ret_t rc;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"running duk_hobject finalizer for object: %p\", (void *) obj));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tthr = heap->heap_thread;\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(heap->heap_thread, 1);\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\t/*\n\t *  Get and call the finalizer.  All of this must be wrapped\n\t *  in a protected call, because even getting the finalizer\n\t *  may trigger an error (getter may throw one, for instance).\n\t */\n\n\t/* ROM objects could inherit a finalizer, but they are never deemed\n\t * unreachable by mark-and-sweep, and their refcount never falls to 0.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\n\t/* Duktape 2.1: finalize_list never contains objects with FINALIZED\n\t * set, so no need to check here.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) obj));\n#if 0\n\tif (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) obj)) {\n\t\tDUK_D(DUK_DPRINT(\"object already finalized, avoid running finalizer twice: %!O\", obj));\n\t\treturn;\n\t}\n#endif\n\tDUK_HEAPHDR_SET_FINALIZED((duk_heaphdr *) obj);  /* ensure never re-entered until rescue cycle complete */\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (DUK_HOBJECT_IS_PROXY(obj)) {\n\t\t/* This may happen if duk_set_finalizer() or Duktape.fin() is\n\t\t * called for a Proxy object.  In such cases the fast finalizer\n\t\t * flag will be set on the Proxy, not the target, and neither\n\t\t * will be finalized.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"object is a Proxy, skip finalizer call\"));\n\t\treturn;\n\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\tduk_push_hobject(thr, obj);  /* this also increases refcount by one */\n\trc = duk_safe_call(thr, duk__finalize_helper, NULL /*udata*/, 0 /*nargs*/, 1 /*nrets*/);  /* -> [... obj retval/error] */\n\tDUK_ASSERT_TOP(thr, entry_top + 2);  /* duk_safe_call discipline */\n\n\tif (rc != DUK_EXEC_SUCCESS) {\n\t\t/* Note: we ask for one return value from duk_safe_call to get this\n\t\t * error debugging here.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"wrapped finalizer call failed for object %p (ignored); error: %!T\",\n\t\t                 (void *) obj, (duk_tval *) duk_get_tval(thr, -1)));\n\t}\n\tduk_pop_2(thr);  /* -> [...] */\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n}\n\n#else  /* DUK_USE_FINALIZER_SUPPORT */\n\n/* nothing */\n\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n#line 1 \"duk_heap_hashstring.c\"\n/*\n *  String hash computation (interning).\n *\n *  String hashing is performance critical because a string hash is computed\n *  for all new strings which are candidates to be added to the string table.\n *  However, strings actually added to the string table go through a codepoint\n *  length calculation which dominates performance because it goes through\n *  every byte of the input string (but only for strings added).\n *\n *  The string hash algorithm should be fast, but on the other hand provide\n *  good enough hashes to ensure both string table and object property table\n *  hash tables work reasonably well (i.e., there aren't too many collisions\n *  with real world inputs).  Unless the hash is cryptographic, it's always\n *  possible to craft inputs with maximal hash collisions.\n *\n *  NOTE: The hash algorithms must match tools/dukutil.py:duk_heap_hashstring()\n *  for ROM string support!\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_STRHASH_DENSE)\n/* Constants for duk_hashstring(). */\n#define DUK__STRHASH_SHORTSTRING   4096L\n#define DUK__STRHASH_MEDIUMSTRING  (256L * 1024L)\n#define DUK__STRHASH_BLOCKSIZE     256L\n\nDUK_INTERNAL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len) {\n\tduk_uint32_t hash;\n\n\t/* Use Murmurhash2 directly for short strings, and use \"block skipping\"\n\t * for long strings: hash an initial part and then sample the rest of\n\t * the string with reasonably sized chunks.  An initial offset for the\n\t * sampling is computed based on a hash of the initial part of the string;\n\t * this is done to (usually) avoid the case where all long strings have\n\t * certain offset ranges which are never sampled.\n\t *\n\t * Skip should depend on length and bound the total time to roughly\n\t * logarithmic.  With current values:\n\t *\n\t *   1M string => 256 * 241 = 61696 bytes (0.06M) of hashing\n\t *   1G string => 256 * 16321 = 4178176 bytes (3.98M) of hashing\n\t *\n\t * XXX: It would be better to compute the skip offset more \"smoothly\"\n\t * instead of having a few boundary values.\n\t */\n\n\t/* note: mixing len into seed improves hashing when skipping */\n\tduk_uint32_t str_seed = heap->hash_seed ^ ((duk_uint32_t) len);\n\n\tif (len <= DUK__STRHASH_SHORTSTRING) {\n\t\thash = duk_util_hashbytes(str, len, str_seed);\n\t} else {\n\t\tduk_size_t off;\n\t\tduk_size_t skip;\n\n\t\tif (len <= DUK__STRHASH_MEDIUMSTRING) {\n\t\t\tskip = (duk_size_t) (16 * DUK__STRHASH_BLOCKSIZE + DUK__STRHASH_BLOCKSIZE);\n\t\t} else {\n\t\t\tskip = (duk_size_t) (256 * DUK__STRHASH_BLOCKSIZE + DUK__STRHASH_BLOCKSIZE);\n\t\t}\n\n\t\thash = duk_util_hashbytes(str, (duk_size_t) DUK__STRHASH_SHORTSTRING, str_seed);\n\t\toff = DUK__STRHASH_SHORTSTRING + (skip * (hash % 256)) / 256;\n\n\t\t/* XXX: inefficient loop */\n\t\twhile (off < len) {\n\t\t\tduk_size_t left = len - off;\n\t\t\tduk_size_t now = (duk_size_t) (left > DUK__STRHASH_BLOCKSIZE ? DUK__STRHASH_BLOCKSIZE : left);\n\t\t\thash ^= duk_util_hashbytes(str + off, now, str_seed);\n\t\t\toff += skip;\n\t\t}\n\t}\n\n#if defined(DUK_USE_STRHASH16)\n\t/* Truncate to 16 bits here, so that a computed hash can be compared\n\t * against a hash stored in a 16-bit field.\n\t */\n\thash &= 0x0000ffffUL;\n#endif\n\treturn hash;\n}\n#else  /* DUK_USE_STRHASH_DENSE */\nDUK_INTERNAL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len) {\n\tduk_uint32_t hash;\n\tduk_size_t step;\n\tduk_size_t off;\n\n\t/* Slightly modified \"Bernstein hash\" from:\n\t *\n\t *     http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx\n\t *\n\t * Modifications: string skipping and reverse direction similar to\n\t * Lua 5.1.5, and different hash initializer.\n\t *\n\t * The reverse direction ensures last byte it always included in the\n\t * hash which is a good default as changing parts of the string are\n\t * more often in the suffix than in the prefix.\n\t */\n\n\thash = heap->hash_seed ^ ((duk_uint32_t) len);  /* Bernstein hash init value is normally 5381 */\n\tstep = (len >> DUK_USE_STRHASH_SKIP_SHIFT) + 1;\n\tfor (off = len; off >= step; off -= step) {\n\t\tDUK_ASSERT(off >= 1);  /* off >= step, and step >= 1 */\n\t\thash = (hash * 33) + str[off - 1];\n\t}\n\n#if defined(DUK_USE_STRHASH16)\n\t/* Truncate to 16 bits here, so that a computed hash can be compared\n\t * against a hash stored in a 16-bit field.\n\t */\n\thash &= 0x0000ffffUL;\n#endif\n\treturn hash;\n}\n#endif  /* DUK_USE_STRHASH_DENSE */\n\n/* automatic undefs */\n#undef DUK__STRHASH_BLOCKSIZE\n#undef DUK__STRHASH_MEDIUMSTRING\n#undef DUK__STRHASH_SHORTSTRING\n#line 1 \"duk_heap_markandsweep.c\"\n/*\n *  Mark-and-sweep garbage collection.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_LOCAL_DECL void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__mark_heaphdr_nonnull(duk_heap *heap, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__mark_tval(duk_heap *heap, duk_tval *tv);\nDUK_LOCAL_DECL void duk__mark_tvals(duk_heap *heap, duk_tval *tv, duk_idx_t count);\n\n/*\n *  Marking functions for heap types: mark children recursively.\n */\n\nDUK_LOCAL void duk__mark_hstring(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\tDUK_UNREF(h);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_hstring: %p\", (void *) h));\n\tDUK_ASSERT(h);\n\tDUK_HSTRING_ASSERT_VALID(h);\n\n\t/* nothing to process */\n}\n\nDUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {\n\tduk_uint_fast32_t i;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_hobject: %p\", (void *) h));\n\n\tDUK_ASSERT(h);\n\tDUK_HOBJECT_ASSERT_VALID(h);\n\n\t/* XXX: use advancing pointers instead of index macros -> faster and smaller? */\n\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\tduk_hstring *key = DUK_HOBJECT_E_GET_KEY(heap, h, i);\n\t\tif (key == NULL) {\n\t\t\tcontinue;\n\t\t}\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) key);\n\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)) {\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.get);\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.set);\n\t\t} else {\n\t\t\tduk__mark_tval(heap, &DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->v);\n\t\t}\n\t}\n\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(h); i++) {\n\t\tduk__mark_tval(heap, DUK_HOBJECT_A_GET_VALUE_PTR(heap, h, i));\n\t}\n\n\t/* Hash part is a 'weak reference' and does not contribute. */\n\n\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(heap, h));\n\n\t/* Fast path for objects which don't have a subclass struct, or have a\n\t * subclass struct but nothing that needs marking in the subclass struct.\n\t */\n\tif (DUK_HOBJECT_HAS_FASTREFS(h)) {\n\t\tDUK_ASSERT(DUK_HOBJECT_ALLOWS_FASTREFS(h));\n\t\treturn;\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_PROHIBITS_FASTREFS(h));\n\n\t/* XXX: reorg, more common first */\n\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tduk_tval *tv, *tv_end;\n\t\tduk_hobject **fn, **fn_end;\n\n\t\tDUK_HCOMPFUNC_ASSERT_VALID(f);\n\n\t\t/* 'data' is reachable through every compiled function which\n\t\t * contains a reference.\n\t\t */\n\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_DATA(heap, f));\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_LEXENV(heap, f));\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_VARENV(heap, f));\n\n\t\tif (DUK_HCOMPFUNC_GET_DATA(heap, f) != NULL) {\n\t\t\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, f);\n\t\t\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(heap, f);\n\t\t\twhile (tv < tv_end) {\n\t\t\t\tduk__mark_tval(heap, tv);\n\t\t\t\ttv++;\n\t\t\t}\n\n\t\t\tfn = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, f);\n\t\t\tfn_end = DUK_HCOMPFUNC_GET_FUNCS_END(heap, f);\n\t\t\twhile (fn < fn_end) {\n\t\t\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) *fn);\n\t\t\t\tfn++;\n\t\t\t}\n\t\t} else {\n\t\t\t/* May happen in some out-of-memory corner cases. */\n\t\t\tDUK_D(DUK_DPRINT(\"duk_hcompfunc 'data' is NULL, skipping marking\"));\n\t\t}\n\t} else if (DUK_HOBJECT_IS_DECENV(h)) {\n\t\tduk_hdecenv *e = (duk_hdecenv *) h;\n\t\tDUK_HDECENV_ASSERT_VALID(e);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) e->thread);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) e->varmap);\n\t} else if (DUK_HOBJECT_IS_OBJENV(h)) {\n\t\tduk_hobjenv *e = (duk_hobjenv *) h;\n\t\tDUK_HOBJENV_ASSERT_VALID(e);\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) e->target);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\tduk_hbufobj *b = (duk_hbufobj *) h;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(b);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) b->buf);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) b->buf_prop);\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {\n\t\tduk_hboundfunc *f = (duk_hboundfunc *) (void *) h;\n\t\tDUK_HBOUNDFUNC_ASSERT_VALID(f);\n\t\tduk__mark_tval(heap, &f->target);\n\t\tduk__mark_tval(heap, &f->this_binding);\n\t\tduk__mark_tvals(heap, f->args, f->nargs);\n#if defined(DUK_USE_ES6_PROXY)\n\t} else if (DUK_HOBJECT_IS_PROXY(h)) {\n\t\tduk_hproxy *p = (duk_hproxy *) h;\n\t\tDUK_HPROXY_ASSERT_VALID(p);\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) p->target);\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) p->handler);\n#endif  /* DUK_USE_ES6_PROXY */\n\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tduk_activation *act;\n\t\tduk_tval *tv;\n\n\t\tDUK_HTHREAD_ASSERT_VALID(t);\n\n\t\ttv = t->valstack;\n\t\twhile (tv < t->valstack_top) {\n\t\t\tduk__mark_tval(heap, tv);\n\t\t\ttv++;\n\t\t}\n\n\t\tfor (act = t->callstack_curr; act != NULL; act = act->parent) {\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_ACT_GET_FUNC(act));\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) act->var_env);\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) act->lex_env);\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) act->prev_caller);\n#endif\n#if 0  /* nothing now */\n\t\t\tfor (cat = act->cat; cat != NULL; cat = cat->parent) {\n\t\t\t}\n#endif\n\t\t}\n\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) t->resumer);\n\n\t\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) t->builtins[i]);\n\t\t}\n\t} else {\n\t\t/* We may come here if the object should have a FASTREFS flag\n\t\t * but it's missing for some reason.  Assert for never getting\n\t\t * here; however, other than performance, this is harmless.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"missing FASTREFS flag for: %!iO\", h));\n\t\tDUK_ASSERT(0);\n\t}\n}\n\n/* Mark any duk_heaphdr type.  Recursion tracking happens only here. */\nDUK_LOCAL void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_heaphdr %p, type %ld\",\n\t                     (void *) h,\n\t                     (h != NULL ? (long) DUK_HEAPHDR_GET_TYPE(h) : (long) -1)));\n\n\t/* XXX: add non-null variant? */\n\tif (h == NULL) {\n\t\treturn;\n\t}\n\n\tDUK_HEAPHDR_ASSERT_VALID(h);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(h) || DUK_HEAPHDR_HAS_REACHABLE(h));\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\tif (!DUK_HEAPHDR_HAS_READONLY(h)) {\n\t\th->h_assert_refcount++;  /* Comparison refcount: bump even if already reachable. */\n\t}\n#endif\n\tif (DUK_HEAPHDR_HAS_REACHABLE(h)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"already marked reachable, skip\"));\n\t\treturn;\n\t}\n#if defined(DUK_USE_ROM_OBJECTS)\n\t/* READONLY objects always have REACHABLE set, so the check above\n\t * will prevent READONLY objects from being marked here.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(h));\n#endif\n\n\tDUK_HEAPHDR_SET_REACHABLE(h);\n\n\tif (heap->ms_recursion_depth >= DUK_USE_MARK_AND_SWEEP_RECLIMIT) {\n\t\tDUK_D(DUK_DPRINT(\"mark-and-sweep recursion limit reached, marking as temproot: %p\", (void *) h));\n\t\tDUK_HEAP_SET_MARKANDSWEEP_RECLIMIT_REACHED(heap);\n\t\tDUK_HEAPHDR_SET_TEMPROOT(h);\n\t\treturn;\n\t}\n\n\theap->ms_recursion_depth++;\n\tDUK_ASSERT(heap->ms_recursion_depth != 0);  /* Wrap. */\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING:\n\t\tduk__mark_hstring(heap, (duk_hstring *) h);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tduk__mark_hobject(heap, (duk_hobject *) h);\n\t\tbreak;\n\tcase DUK_HTYPE_BUFFER:\n\t\t/* nothing to mark */\n\t\tbreak;\n\tdefault:\n\t\tDUK_D(DUK_DPRINT(\"attempt to mark heaphdr %p with invalid htype %ld\", (void *) h, (long) DUK_HEAPHDR_GET_TYPE(h)));\n\t\tDUK_UNREACHABLE();\n\t}\n\n\tDUK_ASSERT(heap->ms_recursion_depth > 0);\n\theap->ms_recursion_depth--;\n}\n\nDUK_LOCAL void duk__mark_tval(duk_heap *heap, duk_tval *tv) {\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_tval %p\", (void *) tv));\n\tif (tv == NULL) {\n\t\treturn;\n\t}\n\tDUK_TVAL_ASSERT_VALID(tv);\n\tif (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\tduk_heaphdr *h;\n\t\th = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tduk__mark_heaphdr_nonnull(heap, h);\n\t}\n}\n\nDUK_LOCAL void duk__mark_tvals(duk_heap *heap, duk_tval *tv, duk_idx_t count) {\n\tDUK_ASSERT(count == 0 || tv != NULL);\n\n\twhile (count-- > 0) {\n\t\tDUK_TVAL_ASSERT_VALID(tv);\n\t\tif (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\t\tduk_heaphdr *h;\n\t\t\th = DUK_TVAL_GET_HEAPHDR(tv);\n\t\t\tDUK_ASSERT(h != NULL);\n\t\t\tduk__mark_heaphdr_nonnull(heap, h);\n\t\t}\n\t\ttv++;\n\t}\n}\n\n/* Mark any duk_heaphdr type, caller guarantees a non-NULL pointer. */\nDUK_LOCAL void duk__mark_heaphdr_nonnull(duk_heap *heap, duk_heaphdr *h) {\n\t/* For now, just call the generic handler.  Change when call sites\n\t * are changed too.\n\t */\n\tduk__mark_heaphdr(heap, h);\n}\n\n/*\n *  Mark the heap.\n */\n\nDUK_LOCAL void duk__mark_roots_heap(duk_heap *heap) {\n\tduk_small_uint_t i;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_roots_heap: %p\", (void *) heap));\n\n\tduk__mark_heaphdr(heap, (duk_heaphdr *) heap->heap_thread);\n\tduk__mark_heaphdr(heap, (duk_heaphdr *) heap->heap_object);\n\n\tfor (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) {\n\t\tduk_hstring *h = DUK_HEAP_GET_STRING(heap, i);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) h);\n\t}\n\n\tduk__mark_tval(heap, &heap->lj.value1);\n\tduk__mark_tval(heap, &heap->lj.value2);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tfor (i = 0; i < heap->dbg_breakpoint_count; i++) {\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) heap->dbg_breakpoints[i].filename);\n\t}\n#endif\n}\n\n/*\n *  Mark unreachable, finalizable objects.\n *\n *  Such objects will be moved aside and their finalizers run later.  They\n *  have to be treated as reachability roots for their properties etc to\n *  remain allocated.  This marking is only done for unreachable values which\n *  would be swept later.\n *\n *  Objects are first marked FINALIZABLE and only then marked as reachability\n *  roots; otherwise circular references might be handled inconsistently.\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__mark_finalizable(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\tduk_size_t count_finalizable = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_finalizable: %p\", (void *) heap));\n\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\n\thdr = heap->heap_allocated;\n\twhile (hdr != NULL) {\n\t\t/* A finalizer is looked up from the object and up its\n\t\t * prototype chain (which allows inherited finalizers).\n\t\t * The finalizer is checked for using a duk_hobject flag\n\t\t * which is kept in sync with the presence and callability\n\t\t * of a _Finalizer hidden symbol.\n\t\t */\n\n\t\tif (!DUK_HEAPHDR_HAS_REACHABLE(hdr) &&\n\t\t    DUK_HEAPHDR_IS_OBJECT(hdr) &&\n\t\t    !DUK_HEAPHDR_HAS_FINALIZED(hdr) &&\n\t\t    DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) hdr)) {\n\t\t\t/* heaphdr:\n\t\t\t *  - is not reachable\n\t\t\t *  - is an object\n\t\t\t *  - is not a finalized object waiting for rescue/keep decision\n\t\t\t *  - has a finalizer\n\t\t\t */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"unreachable heap object will be \"\n\t\t\t                   \"finalized -> mark as finalizable \"\n\t\t\t                   \"and treat as a reachability root: %p\",\n\t\t\t                   (void *) hdr));\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(hdr));\n\t\t\tDUK_HEAPHDR_SET_FINALIZABLE(hdr);\n\t\t\tcount_finalizable++;\n\t\t}\n\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n\n\tif (count_finalizable == 0) {\n\t\treturn;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"marked %ld heap objects as finalizable, now mark them reachable\",\n\t                   (long) count_finalizable));\n\n\thdr = heap->heap_allocated;\n\twhile (hdr != NULL) {\n\t\tif (DUK_HEAPHDR_HAS_FINALIZABLE(hdr)) {\n\t\t\tduk__mark_heaphdr_nonnull(heap, hdr);\n\t\t}\n\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n\n\t/* Caller will finish the marking process if we hit a recursion limit. */\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Mark objects on finalize_list.\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__mark_finalize_list(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_finalize_list = 0;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_finalize_list: %p\", (void *) heap));\n\n\thdr = heap->finalize_list;\n\twhile (hdr != NULL) {\n\t\tduk__mark_heaphdr_nonnull(heap, hdr);\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n#if defined(DUK_USE_DEBUG)\n\t\tcount_finalize_list++;\n#endif\n\t}\n\n#if defined(DUK_USE_DEBUG)\n\tif (count_finalize_list > 0) {\n\t\tDUK_D(DUK_DPRINT(\"marked %ld objects on the finalize_list as reachable (previous finalizer run skipped)\",\n\t\t                 (long) count_finalize_list));\n\t}\n#endif\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Fallback marking handler if recursion limit is reached.\n *\n *  Iterates 'temproots' until recursion limit is no longer hit.  Temproots\n *  can be in heap_allocated or finalize_list; refzero_list is now always\n *  empty for mark-and-sweep.  A temproot may occur in finalize_list now if\n *  there are objects on the finalize_list and user code creates a reference\n *  from an object in heap_allocated to the object in finalize_list (which is\n *  now allowed), and it happened to coincide with the recursion depth limit.\n *\n *  This is a slow scan, but guarantees that we finish with a bounded C stack.\n *\n *  Note that nodes may have been marked as temproots before this scan begun,\n *  OR they may have been marked during the scan (as we process nodes\n *  recursively also during the scan).  This is intended behavior.\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__handle_temproot(duk_heap *heap, duk_heaphdr *hdr, duk_size_t *count) {\n#else\nDUK_LOCAL void duk__handle_temproot(duk_heap *heap, duk_heaphdr *hdr) {\n#endif\n\tDUK_ASSERT(hdr != NULL);\n\n\tif (!DUK_HEAPHDR_HAS_TEMPROOT(hdr)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"not a temp root: %p\", (void *) hdr));\n\t\treturn;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"found a temp root: %p\", (void *) hdr));\n\tDUK_HEAPHDR_CLEAR_TEMPROOT(hdr);\n\tDUK_HEAPHDR_CLEAR_REACHABLE(hdr);  /* Done so that duk__mark_heaphdr() works correctly. */\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\thdr->h_assert_refcount--;  /* Same node visited twice. */\n#endif\n\tduk__mark_heaphdr_nonnull(heap, hdr);\n\n#if defined(DUK_USE_DEBUG)\n\t(*count)++;\n#endif\n}\n\nDUK_LOCAL void duk__mark_temproots_by_heap_scan(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_temproots_by_heap_scan: %p\", (void *) heap));\n\n\twhile (DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap)) {\n\t\tDUK_DD(DUK_DDPRINT(\"recursion limit reached, doing heap scan to continue from temproots\"));\n\n#if defined(DUK_USE_DEBUG)\n\t\tcount = 0;\n#endif\n\t\tDUK_HEAP_CLEAR_MARKANDSWEEP_RECLIMIT_REACHED(heap);\n\n\t\thdr = heap->heap_allocated;\n\t\twhile (hdr) {\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk__handle_temproot(heap, hdr, &count);\n#else\n\t\t\tduk__handle_temproot(heap, hdr);\n#endif\n\t\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t\t}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\thdr = heap->finalize_list;\n\t\twhile (hdr) {\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk__handle_temproot(heap, hdr, &count);\n#else\n\t\t\tduk__handle_temproot(heap, hdr);\n#endif\n\t\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t\t}\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\t\tDUK_DD(DUK_DDPRINT(\"temproot mark heap scan processed %ld temp roots\", (long) count));\n#endif\n\t}\n}\n\n/*\n *  Finalize refcounts for heap elements just about to be freed.\n *  This must be done for all objects before freeing to avoid any\n *  stale pointer dereferences.\n *\n *  Note that this must deduce the set of objects to be freed\n *  identically to duk__sweep_heap().\n */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_LOCAL void duk__finalize_refcounts(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"duk__finalize_refcounts: heap=%p\", (void *) heap));\n\n\thdr = heap->heap_allocated;\n\twhile (hdr) {\n\t\tif (!DUK_HEAPHDR_HAS_REACHABLE(hdr)) {\n\t\t\t/*\n\t\t\t *  Unreachable object about to be swept.  Finalize target refcounts\n\t\t\t *  (objects which the unreachable object points to) without doing\n\t\t\t *  refzero processing.  Recursive decrefs are also prevented when\n\t\t\t *  refzero processing is disabled.\n\t\t\t *\n\t\t\t *  Value cannot be a finalizable object, as they have been made\n\t\t\t *  temporarily reachable for this round.\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"unreachable object, refcount finalize before sweeping: %p\", (void *) hdr));\n\n\t\t\t/* Finalize using heap->heap_thread; DECREF has a\n\t\t\t * suppress check for mark-and-sweep which is based\n\t\t\t * on heap->ms_running.\n\t\t\t */\n\t\t\tduk_heaphdr_refcount_finalize_norz(heap, hdr);\n\t\t}\n\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/*\n *  Clear (reachable) flags of finalize_list.\n *\n *  We could mostly do in the sweep phase when we move objects from the\n *  heap into the finalize_list.  However, if a finalizer run is skipped\n *  during a mark-and-sweep, the objects on the finalize_list will be marked\n *  reachable during the next mark-and-sweep.  Since they're already on the\n *  finalize_list, no-one will be clearing their REACHABLE flag so we do it\n *  here.  (This now overlaps with the sweep handling in a harmless way.)\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__clear_finalize_list_flags(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__clear_finalize_list_flags: %p\", (void *) heap));\n\n\thdr = heap->finalize_list;\n\twhile (hdr) {\n\t\tDUK_HEAPHDR_CLEAR_REACHABLE(hdr);\n#if defined(DUK_USE_ASSERTIONS)\n\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZABLE(hdr) || \\\n\t\t           (heap->currently_finalizing == hdr));\n#endif\n\t\t/* DUK_HEAPHDR_FLAG_FINALIZED may be set. */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(hdr));\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Sweep stringtable.\n */\n\nDUK_LOCAL void duk__sweep_stringtable(duk_heap *heap, duk_size_t *out_count_keep) {\n\tduk_hstring *h;\n\tduk_hstring *prev;\n\tduk_uint32_t i;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_free = 0;\n#endif\n\tduk_size_t count_keep = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__sweep_stringtable: %p\", (void *) heap));\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tif (heap->strtable16 == NULL) {\n#else\n\tif (heap->strtable == NULL) {\n#endif\n\t\tgoto done;\n\t}\n\n\tfor (i = 0; i < heap->st_size; i++) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\th = DUK_USE_HEAPPTR_DEC16(heap->heap_udata, heap->strtable16[i]);\n#else\n\t\th = heap->strtable[i];\n#endif\n\t\tprev = NULL;\n\t\twhile (h != NULL) {\n\t\t\tduk_hstring *next;\n\t\t\tnext = h->hdr.h_next;\n\n\t\t\tif (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h))\n\t\t\t{\n\t\t\t\tDUK_HEAPHDR_CLEAR_REACHABLE((duk_heaphdr *) h);\n\t\t\t\tcount_keep++;\n\t\t\t\tprev = h;\n\t\t\t} else {\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tcount_free++;\n#endif\n\n\t\t\t\t/* For pinned strings the refcount has been\n\t\t\t\t * bumped.  We could unbump it here before\n\t\t\t\t * freeing, but that's actually not necessary\n\t\t\t\t * except for assertions.\n\t\t\t\t */\n#if 0\n\t\t\t\tif (DUK_HSTRING_HAS_PINNED_LITERAL(h)) {\n\t\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) > 0U);\n\t\t\t\t\tDUK_HSTRING_DECREF_NORZ(heap->heap_thread, h);\n\t\t\t\t\tDUK_HSTRING_CLEAR_PINNED_LITERAL(h);\n\t\t\t\t}\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t\t/* Non-zero refcounts should not happen for unreachable strings,\n\t\t\t\t * because we refcount finalize all unreachable objects which\n\t\t\t\t * should have decreased unreachable string refcounts to zero\n\t\t\t\t * (even for cycles).  However, pinned strings have a +1 bump.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) ==\n\t\t\t\t           DUK_HSTRING_HAS_PINNED_LITERAL(h) ? 1U : 0U);\n#endif\n\n\t\t\t\t/* Deal with weak references first. */\n\t\t\t\tduk_heap_strcache_string_remove(heap, (duk_hstring *) h);\n\n\t\t\t\t/* Remove the string from the string table. */\n\t\t\t\tduk_heap_strtable_unlink_prev(heap, (duk_hstring *) h, (duk_hstring *) prev);\n\n\t\t\t\t/* Free inner references (these exist e.g. when external\n\t\t\t\t * strings are enabled) and the struct itself.\n\t\t\t\t */\n\t\t\t\tduk_free_hstring(heap, (duk_hstring *) h);\n\n\t\t\t\t/* Don't update 'prev'; it should be last string kept. */\n\t\t\t}\n\n\t\t\th = next;\n\t\t}\n\t}\n\n done:\n#if defined(DUK_USE_DEBUG)\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep sweep stringtable: %ld freed, %ld kept\",\n\t                 (long) count_free, (long) count_keep));\n#endif\n\t*out_count_keep = count_keep;\n}\n\n/*\n *  Sweep heap.\n */\n\nDUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_small_uint_t flags, duk_size_t *out_count_keep) {\n\tduk_heaphdr *prev;  /* last element that was left in the heap */\n\tduk_heaphdr *curr;\n\tduk_heaphdr *next;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_free = 0;\n\tduk_size_t count_finalize = 0;\n\tduk_size_t count_rescue = 0;\n#endif\n\tduk_size_t count_keep = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__sweep_heap: %p\", (void *) heap));\n\n\tprev = NULL;\n\tcurr = heap->heap_allocated;\n\theap->heap_allocated = NULL;\n\twhile (curr) {\n\t\t/* Strings and ROM objects are never placed on the heap allocated list. */\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) != DUK_HTYPE_STRING);\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(curr));\n\n\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\n\t\tif (DUK_HEAPHDR_HAS_REACHABLE(curr)) {\n\t\t\t/*\n\t\t\t *  Reachable object:\n\t\t\t *    - If FINALIZABLE -> actually unreachable (but marked\n\t\t\t *      artificially reachable), queue to finalize_list.\n\t\t\t *    - If !FINALIZABLE but FINALIZED -> rescued after\n\t\t\t *      finalizer execution.\n\t\t\t *    - Otherwise just a normal, reachable object.\n\t\t\t *\n\t\t\t *  Objects which are kept are queued to heap_allocated\n\t\t\t *  tail (we're essentially filtering heap_allocated in\n\t\t\t *  practice).\n\t\t\t */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\t\tif (DUK_UNLIKELY(DUK_HEAPHDR_HAS_FINALIZABLE(curr))) {\n\t\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));\n\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable, finalizable --> move to finalize_list: %p\", (void *) curr));\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(curr);  /* Bump refcount so that refzero never occurs when pending a finalizer call. */\n#endif\n\t\t\t\tDUK_HEAP_INSERT_INTO_FINALIZE_LIST(heap, curr);\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tcount_finalize++;\n#endif\n\t\t\t}\n\t\t\telse\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\t\t\t{\n\t\t\t\tif (DUK_UNLIKELY(DUK_HEAPHDR_HAS_FINALIZED(curr))) {\n\t\t\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(curr));\n\t\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);\n\n\t\t\t\t\tif (flags & DUK_MS_FLAG_POSTPONE_RESCUE) {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable, finalized, but postponing rescue decisions --> keep object (with FINALIZED set): %!iO\", curr));\n\t\t\t\t\t\tcount_keep++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable, finalized --> rescued after finalization: %p\", (void *) curr));\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\t\t\t\t\tDUK_HEAPHDR_CLEAR_FINALIZED(curr);\n#endif\n#if defined(DUK_USE_DEBUG)\n\t\t\t\t\t\tcount_rescue++;\n#endif\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable --> keep: %!iO\", curr));\n\t\t\t\t\tcount_keep++;\n\t\t\t\t}\n\n\t\t\t\tif (prev != NULL) {\n\t\t\t\t\tDUK_ASSERT(heap->heap_allocated != NULL);\n\t\t\t\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, curr);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(heap->heap_allocated == NULL);\n\t\t\t\t\theap->heap_allocated = curr;\n\t\t\t\t}\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\t\t\t\tDUK_HEAPHDR_SET_PREV(heap, curr, prev);\n#endif\n\t\t\t\tDUK_HEAPHDR_ASSERT_LINKS(heap, prev);\n\t\t\t\tDUK_HEAPHDR_ASSERT_LINKS(heap, curr);\n\t\t\t\tprev = curr;\n\t\t\t}\n\n\t\t\t/*\n\t\t\t *  Shrink check for value stacks here.  We're inside\n\t\t\t *  ms_prevent_count protection which prevents recursive\n\t\t\t *  mark-and-sweep and refzero finalizers, so there are\n\t\t\t *  no side effects that would affect the heap lists.\n\t\t\t */\n\t\t\tif (DUK_HEAPHDR_IS_OBJECT(curr) && DUK_HOBJECT_IS_THREAD((duk_hobject *) curr)) {\n\t\t\t\tduk_hthread *thr_curr = (duk_hthread *) curr;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"value stack shrink check for thread: %!O\", curr));\n\t\t\t\tduk_valstack_shrink_check_nothrow(thr_curr, flags & DUK_MS_FLAG_EMERGENCY /*snug*/);\n\t\t\t}\n\n\t\t\tDUK_HEAPHDR_CLEAR_REACHABLE(curr);\n\t\t\t/* Keep FINALIZED if set, used if rescue decisions are postponed. */\n\t\t\t/* Keep FINALIZABLE for objects on finalize_list. */\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(curr));\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Unreachable object:\n\t\t\t *    - If FINALIZED, object was finalized but not\n\t\t\t *      rescued.  This doesn't affect freeing.\n\t\t\t *    - Otherwise normal unreachable object.\n\t\t\t *\n\t\t\t *  There's no guard preventing a FINALIZED object\n\t\t\t *  from being freed while finalizers execute: the\n\t\t\t *  artificial finalize_list reachability roots can't\n\t\t\t *  cause an incorrect free decision (but can cause\n\t\t\t *  an incorrect rescue decision).\n\t\t\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t/* Non-zero refcounts should not happen because we refcount\n\t\t\t * finalize all unreachable objects which should cancel out\n\t\t\t * refcounts (even for cycles).\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) == 0);\n#endif\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(curr));\n\n#if defined(DUK_USE_DEBUG)\n\t\t\tif (DUK_HEAPHDR_HAS_FINALIZED(curr)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; unreachable, finalized --> finalized object not rescued: %p\", (void *) curr));\n\t\t\t} else {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; not reachable --> free: %p\", (void *) curr));\n\t\t\t}\n\n#endif\n\n\t\t\t/* Note: object cannot be a finalizable unreachable object, as\n\t\t\t * they have been marked temporarily reachable for this round,\n\t\t\t * and are handled above.\n\t\t\t */\n\n#if defined(DUK_USE_DEBUG)\n\t\t\tcount_free++;\n#endif\n\n\t\t\t/* Weak refs should be handled here, but no weak refs for\n\t\t\t * any non-string objects exist right now.\n\t\t\t */\n\n\t\t\t/* Free object and all auxiliary (non-heap) allocs. */\n\t\t\tduk_heap_free_heaphdr_raw(heap, curr);\n\t\t}\n\n\t\tcurr = next;\n\t}\n\n\tif (prev != NULL) {\n\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, NULL);\n\t}\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, prev);\n\n#if defined(DUK_USE_DEBUG)\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep sweep objects (non-string): %ld freed, %ld kept, %ld rescued, %ld queued for finalization\",\n\t                 (long) count_free, (long) count_keep, (long) count_rescue, (long) count_finalize));\n#endif\n\t*out_count_keep = count_keep;\n}\n\n/*\n *  Litcache helpers.\n */\n\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_LOCAL void duk__wipe_litcache(duk_heap *heap) {\n\tduk_uint_t i;\n\tduk_litcache_entry *e;\n\n\te = heap->litcache;\n\tfor (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) {\n\t\te->addr = NULL;\n\t\t/* e->h does not need to be invalidated: when e->addr is\n\t\t * NULL, e->h is considered garbage.\n\t\t */\n\t\te++;\n\t}\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n\n/*\n *  Object compaction.\n *\n *  Compaction is assumed to never throw an error.\n */\n\nDUK_LOCAL int duk__protected_compact_object(duk_hthread *thr, void *udata) {\n\tduk_hobject *obj;\n\t/* XXX: for threads, compact stacks? */\n\n\tDUK_UNREF(udata);\n\tobj = duk_known_hobject(thr, -1);\n\tduk_hobject_compact_props(thr, obj);\n\treturn 0;\n}\n\n#if defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__compact_object_list(duk_heap *heap, duk_hthread *thr, duk_heaphdr *start, duk_size_t *p_count_check, duk_size_t *p_count_compact, duk_size_t *p_count_bytes_saved) {\n#else\nDUK_LOCAL void duk__compact_object_list(duk_heap *heap, duk_hthread *thr, duk_heaphdr *start) {\n#endif\n\tduk_heaphdr *curr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t old_size, new_size;\n#endif\n\tduk_hobject *obj;\n\n\tDUK_UNREF(heap);\n\n\tcurr = start;\n\twhile (curr) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"mark-and-sweep compact: %p\", (void *) curr));\n\n\t\tif (DUK_HEAPHDR_GET_TYPE(curr) != DUK_HTYPE_OBJECT) {\n\t\t\tgoto next;\n\t\t}\n\t\tobj = (duk_hobject *) curr;\n\n#if defined(DUK_USE_DEBUG)\n\t\told_size = DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_ASIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_HSIZE(obj));\n#endif\n\n\t\tDUK_DD(DUK_DDPRINT(\"compact object: %p\", (void *) obj));\n\t\tduk_push_hobject(thr, obj);\n\t\t/* XXX: disable error handlers for duration of compaction? */\n\t\tduk_safe_call(thr, duk__protected_compact_object, NULL, 1, 0);\n\n#if defined(DUK_USE_DEBUG)\n\t\tnew_size = DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_ASIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_HSIZE(obj));\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\t\t(*p_count_compact)++;\n\t\t(*p_count_bytes_saved) += (duk_size_t) (old_size - new_size);\n#endif\n\n\t next:\n\t\tcurr = DUK_HEAPHDR_GET_NEXT(heap, curr);\n#if defined(DUK_USE_DEBUG)\n\t\t(*p_count_check)++;\n#endif\n\t}\n}\n\nDUK_LOCAL void duk__compact_objects(duk_heap *heap) {\n\t/* XXX: which lists should participate?  to be finalized? */\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_check = 0;\n\tduk_size_t count_compact = 0;\n\tduk_size_t count_bytes_saved = 0;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"duk__compact_objects: %p\", (void *) heap));\n\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\n#if defined(DUK_USE_DEBUG)\n\tduk__compact_object_list(heap, heap->heap_thread, heap->heap_allocated, &count_check, &count_compact, &count_bytes_saved);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__compact_object_list(heap, heap->heap_thread, heap->finalize_list, &count_check, &count_compact, &count_bytes_saved);\n#endif\n#else\n\tduk__compact_object_list(heap, heap->heap_thread, heap->heap_allocated);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__compact_object_list(heap, heap->heap_thread, heap->finalize_list);\n#endif\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always handled to completion inline in DECREF. */\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep compact objects: %ld checked, %ld compaction attempts, %ld bytes saved by compaction\",\n\t                 (long) count_check, (long) count_compact, (long) count_bytes_saved));\n#endif\n}\n\n/*\n *  Assertion helpers.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\ntypedef void (*duk__gc_heaphdr_assert)(duk_heap *heap, duk_heaphdr *h);\ntypedef void (*duk__gc_hstring_assert)(duk_heap *heap, duk_hstring *h);\n\nDUK_LOCAL void duk__assert_walk_list(duk_heap *heap, duk_heaphdr *start, duk__gc_heaphdr_assert func) {\n\tduk_heaphdr *curr;\n\tfor (curr = start; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) {\n\t\tfunc(heap, curr);\n\t}\n}\n\nDUK_LOCAL void duk__assert_walk_strtable(duk_heap *heap, duk__gc_hstring_assert func) {\n\tduk_uint32_t i;\n\n\tfor (i = 0; i < heap->st_size; i++) {\n\t\tduk_hstring *h;\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\th = DUK_USE_HEAPPTR_DEC16(heap->heap_udata, heap->strtable16[i]);\n#else\n\t\th = heap->strtable[i];\n#endif\n\t\twhile (h != NULL) {\n\t\t\tfunc(heap, h);\n\t\t\th = h->hdr.h_next;\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__assert_heaphdr_flags_cb(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(h));\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(h));\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(h));\n\t/* may have FINALIZED */\n}\nDUK_LOCAL void duk__assert_heaphdr_flags(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__assert_heaphdr_flags_cb);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always handled to completion inline in DECREF. */\n#endif\n\t/* XXX: Assertions for finalize_list? */\n}\n\nDUK_LOCAL void duk__assert_validity_cb1(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tDUK_ASSERT(DUK_HEAPHDR_IS_OBJECT(h) || DUK_HEAPHDR_IS_BUFFER(h));\n\tduk_heaphdr_assert_valid_subclassed(h);\n}\nDUK_LOCAL void duk__assert_validity_cb2(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\tDUK_ASSERT(DUK_HEAPHDR_IS_STRING((duk_heaphdr *) h));\n\tduk_heaphdr_assert_valid_subclassed((duk_heaphdr *) h);\n}\nDUK_LOCAL void duk__assert_validity(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__assert_validity_cb1);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__assert_walk_list(heap, heap->finalize_list, duk__assert_validity_cb1);\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__assert_walk_list(heap, heap->refzero_list, duk__assert_validity_cb1);\n#endif\n\tduk__assert_walk_strtable(heap, duk__assert_validity_cb2);\n}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_LOCAL void duk__assert_valid_refcounts_cb(duk_heap *heap, duk_heaphdr *h) {\n\t/* Cannot really assert much w.r.t. refcounts now. */\n\n\tDUK_UNREF(heap);\n\tif (DUK_HEAPHDR_GET_REFCOUNT(h) == 0 &&\n\t    DUK_HEAPHDR_HAS_FINALIZED(h)) {\n\t\t/* An object may be in heap_allocated list with a zero\n\t\t * refcount if it has just been finalized and is waiting\n\t\t * to be collected by the next cycle.\n\t\t * (This doesn't currently happen however.)\n\t\t */\n\t} else if (DUK_HEAPHDR_GET_REFCOUNT(h) == 0) {\n\t\t/* An object may be in heap_allocated list with a zero\n\t\t * refcount also if it is a temporary object created\n\t\t * during debugger paused state.  It will get collected\n\t\t * by mark-and-sweep based on its reachability status\n\t\t * (presumably not reachable because refcount is 0).\n\t\t */\n\t}\n\tDUK_ASSERT_DISABLE(DUK_HEAPHDR_GET_REFCOUNT(h) >= 0);  /* Unsigned. */\n}\nDUK_LOCAL void duk__assert_valid_refcounts(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__assert_valid_refcounts_cb);\n}\n\nDUK_LOCAL void duk__clear_assert_refcounts_cb1(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\th->h_assert_refcount = 0;\n}\nDUK_LOCAL void duk__clear_assert_refcounts_cb2(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\t((duk_heaphdr *) h)->h_assert_refcount = 0;\n}\nDUK_LOCAL void duk__clear_assert_refcounts(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__clear_assert_refcounts_cb1);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__assert_walk_list(heap, heap->finalize_list, duk__clear_assert_refcounts_cb1);\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__assert_walk_list(heap, heap->refzero_list, duk__clear_assert_refcounts_cb1);\n#endif\n\tduk__assert_walk_strtable(heap, duk__clear_assert_refcounts_cb2);\n}\n\nDUK_LOCAL void duk__check_refcount_heaphdr(duk_heaphdr *hdr) {\n\tduk_bool_t count_ok;\n\tduk_size_t expect_refc;\n\n\t/* The refcount check only makes sense for reachable objects on\n\t * heap_allocated or string table, after the sweep phase.  Prior to\n\t * sweep phase refcounts will include references that are not visible\n\t * via reachability roots.\n\t *\n\t * Because we're called after the sweep phase, all heap objects on\n\t * heap_allocated are reachable.  REACHABLE flags have already been\n\t * cleared so we can't check them.\n\t */\n\n\t/* ROM objects have intentionally incorrect refcount (1), but we won't\n\t * check them.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(hdr));\n\n\texpect_refc = hdr->h_assert_refcount;\n\tif (DUK_HEAPHDR_IS_STRING(hdr) && DUK_HSTRING_HAS_PINNED_LITERAL((duk_hstring *) hdr)) {\n\t\texpect_refc++;\n\t}\n\tcount_ok = ((duk_size_t) DUK_HEAPHDR_GET_REFCOUNT(hdr) == expect_refc);\n\tif (!count_ok) {\n\t\tDUK_D(DUK_DPRINT(\"refcount mismatch for: %p: header=%ld counted=%ld --> %!iO\",\n\t\t                 (void *) hdr, (long) DUK_HEAPHDR_GET_REFCOUNT(hdr),\n\t\t                 (long) hdr->h_assert_refcount, hdr));\n\t\tDUK_ASSERT(0);\n\t}\n}\n\nDUK_LOCAL void duk__check_assert_refcounts_cb1(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tduk__check_refcount_heaphdr(h);\n}\nDUK_LOCAL void duk__check_assert_refcounts_cb2(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\tduk__check_refcount_heaphdr((duk_heaphdr *) h);\n}\nDUK_LOCAL void duk__check_assert_refcounts(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__check_assert_refcounts_cb1);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__assert_walk_list(heap, heap->finalize_list, duk__check_assert_refcounts_cb1);\n#endif\n\t/* XXX: Assert anything for refzero_list? */\n\tduk__assert_walk_strtable(heap, duk__check_assert_refcounts_cb2);\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_LOCAL void duk__assert_litcache_nulls(duk_heap *heap) {\n\tduk_uint_t i;\n\tduk_litcache_entry *e;\n\n\te = heap->litcache;\n\tfor (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) {\n\t\t/* Entry addresses were NULLed before mark-and-sweep, check\n\t\t * that they're still NULL afterwards to ensure no pointers\n\t\t * were recorded through any side effects.\n\t\t */\n\t\tDUK_ASSERT(e->addr == NULL);\n\t}\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n#endif  /* DUK_USE_ASSERTIONS */\n\n/*\n *  Stats dump.\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__dump_stats(duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"stats executor: opcodes=%ld, interrupt=%ld, throw=%ld\",\n\t                 (long) heap->stats_exec_opcodes, (long) heap->stats_exec_interrupt,\n\t                 (long) heap->stats_exec_throw));\n\tDUK_D(DUK_DPRINT(\"stats call: all=%ld, tailcall=%ld, ecmatoecma=%ld\",\n\t                 (long) heap->stats_call_all, (long) heap->stats_call_tailcall,\n\t                 (long) heap->stats_call_ecmatoecma));\n\tDUK_D(DUK_DPRINT(\"stats safecall: all=%ld, nothrow=%ld, throw=%ld\",\n\t                 (long) heap->stats_safecall_all, (long) heap->stats_safecall_nothrow,\n\t                 (long) heap->stats_safecall_throw));\n\tDUK_D(DUK_DPRINT(\"stats mark-and-sweep: try_count=%ld, skip_count=%ld, emergency_count=%ld\",\n\t                 (long) heap->stats_ms_try_count, (long) heap->stats_ms_skip_count,\n\t                 (long) heap->stats_ms_emergency_count));\n\tDUK_D(DUK_DPRINT(\"stats stringtable: intern_hit=%ld, intern_miss=%ld, \"\n\t                 \"resize_check=%ld, resize_grow=%ld, resize_shrink=%ld, \"\n\t                 \"litcache_hit=%ld, litcache_miss=%ld, litcache_pin=%ld\",\n\t                 (long) heap->stats_strtab_intern_hit, (long) heap->stats_strtab_intern_miss,\n\t                 (long) heap->stats_strtab_resize_check, (long) heap->stats_strtab_resize_grow,\n\t                 (long) heap->stats_strtab_resize_shrink, (long) heap->stats_strtab_litcache_hit,\n\t                 (long) heap->stats_strtab_litcache_miss, (long) heap->stats_strtab_litcache_pin));\n\tDUK_D(DUK_DPRINT(\"stats object: realloc_props=%ld, abandon_array=%ld\",\n\t                 (long) heap->stats_object_realloc_props, (long) heap->stats_object_abandon_array));\n\tDUK_D(DUK_DPRINT(\"stats getownpropdesc: count=%ld, hit=%ld, miss=%ld\",\n\t                 (long) heap->stats_getownpropdesc_count, (long) heap->stats_getownpropdesc_hit,\n\t                 (long) heap->stats_getownpropdesc_miss));\n\tDUK_D(DUK_DPRINT(\"stats getpropdesc: count=%ld, hit=%ld, miss=%ld\",\n\t                 (long) heap->stats_getpropdesc_count, (long) heap->stats_getpropdesc_hit,\n\t                 (long) heap->stats_getpropdesc_miss));\n\tDUK_D(DUK_DPRINT(\"stats getprop: all=%ld, arrayidx=%ld, bufobjidx=%ld, \"\n\t                 \"bufferidx=%ld, bufferlen=%ld, stringidx=%ld, stringlen=%ld, \"\n\t                 \"proxy=%ld, arguments=%ld\",\n\t                 (long) heap->stats_getprop_all, (long) heap->stats_getprop_arrayidx,\n\t                 (long) heap->stats_getprop_bufobjidx, (long) heap->stats_getprop_bufferidx,\n\t                 (long) heap->stats_getprop_bufferlen, (long) heap->stats_getprop_stringidx,\n\t                 (long) heap->stats_getprop_stringlen, (long) heap->stats_getprop_proxy,\n\t                 (long) heap->stats_getprop_arguments));\n\tDUK_D(DUK_DPRINT(\"stats putprop: all=%ld, arrayidx=%ld, bufobjidx=%ld, \"\n\t                 \"bufferidx=%ld, proxy=%ld\",\n\t                 (long) heap->stats_putprop_all, (long) heap->stats_putprop_arrayidx,\n\t                 (long) heap->stats_putprop_bufobjidx, (long) heap->stats_putprop_bufferidx,\n\t                 (long) heap->stats_putprop_proxy));\n\tDUK_D(DUK_DPRINT(\"stats getvar: all=%ld\",\n\t                 (long) heap->stats_getvar_all));\n\tDUK_D(DUK_DPRINT(\"stats putvar: all=%ld\",\n\t                 (long) heap->stats_putvar_all));\n\tDUK_D(DUK_DPRINT(\"stats envrec: delayedcreate=%ld, create=%ld, newenv=%ld, oldenv=%ld, pushclosure=%ld\",\n\t                 (long) heap->stats_envrec_delayedcreate,\n\t                 (long) heap->stats_envrec_create,\n\t                 (long) heap->stats_envrec_newenv,\n\t                 (long) heap->stats_envrec_oldenv,\n\t                 (long) heap->stats_envrec_pushclosure));\n}\n#endif  /* DUK_USE_DEBUG */\n\n/*\n *  Main mark-and-sweep function.\n *\n *  'flags' represents the features requested by the caller.  The current\n *  heap->ms_base_flags is ORed automatically into the flags; the base flags\n *  mask typically prevents certain mark-and-sweep operation to avoid trouble.\n */\n\nDUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags) {\n\tduk_size_t count_keep_obj;\n\tduk_size_t count_keep_str;\n#if defined(DUK_USE_VOLUNTARY_GC)\n\tduk_size_t tmp;\n#endif\n\n\tDUK_STATS_INC(heap, stats_ms_try_count);\n#if defined(DUK_USE_DEBUG)\n\tif (flags & DUK_MS_FLAG_EMERGENCY) {\n\t\tDUK_STATS_INC(heap, stats_ms_emergency_count);\n\t}\n#endif\n\n\t/* If debugger is paused, garbage collection is disabled by default.\n\t * This is achieved by bumping ms_prevent_count when becoming paused.\n\t */\n\tDUK_ASSERT(!DUK_HEAP_HAS_DEBUGGER_PAUSED(heap) || heap->ms_prevent_count > 0);\n\n\t/* Prevention/recursion check as soon as possible because we may\n\t * be called a number of times when voluntary mark-and-sweep is\n\t * pending.\n\t */\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject recursive mark-and-sweep\"));\n\t\tDUK_STATS_INC(heap, stats_ms_skip_count);\n\t\treturn;\n\t}\n\tDUK_ASSERT(heap->ms_running == 0);  /* ms_prevent_count is bumped when ms_running is set */\n\n\t/* Heap_thread is used during mark-and-sweep for refcount finalization\n\t * (it's also used for finalizer execution once mark-and-sweep is\n\t * complete).  Heap allocation code ensures heap_thread is set and\n\t * properly initialized before setting ms_prevent_count to 0.\n\t */\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(heap->heap_thread->valstack != NULL);\n\n\tDUK_D(DUK_DPRINT(\"garbage collect (mark-and-sweep) starting, requested flags: 0x%08lx, effective flags: 0x%08lx\",\n\t                 (unsigned long) flags, (unsigned long) (flags | heap->ms_base_flags)));\n\n\tflags |= heap->ms_base_flags;\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tif (heap->finalize_list != NULL) {\n\t\tflags |= DUK_MS_FLAG_POSTPONE_RESCUE;\n\t}\n#endif\n\n\t/*\n\t *  Assertions before\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\tDUK_ASSERT(heap->ms_running == 0);\n\tDUK_ASSERT(!DUK_HEAP_HAS_DEBUGGER_PAUSED(heap));\n\tDUK_ASSERT(!DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap));\n\tDUK_ASSERT(heap->ms_recursion_depth == 0);\n\tduk__assert_heaphdr_flags(heap);\n\tduk__assert_validity(heap);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* Note: heap->refzero_free_running may be true; a refcount\n\t * finalizer may trigger a mark-and-sweep.\n\t */\n\tduk__assert_valid_refcounts(heap);\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n#endif  /* DUK_USE_ASSERTIONS */\n\n\t/*\n\t *  Begin\n\t */\n\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\tDUK_ASSERT(heap->ms_running == 0);\n\theap->ms_prevent_count = 1;\n\theap->ms_running = 1;\n\n\t/*\n\t *  Free activation/catcher freelists on every mark-and-sweep for now.\n\t *  This is an initial rough draft; ideally we'd keep count of the\n\t *  freelist size and free only excess entries.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"freeing temporary freelists\"));\n\tduk_heap_free_freelists(heap);\n\n\t/*\n\t *  Mark roots, hoping that recursion limit is not normally hit.\n\t *  If recursion limit is hit, run additional reachability rounds\n\t *  starting from \"temproots\" until marking is complete.\n\t *\n\t *  Marking happens in two phases: first we mark actual reachability\n\t *  roots (and run \"temproots\" to complete the process).  Then we\n\t *  check which objects are unreachable and are finalizable; such\n\t *  objects are marked as FINALIZABLE and marked as reachability\n\t *  (and \"temproots\" is run again to complete the process).\n\t *\n\t *  The heap finalize_list must also be marked as a reachability root.\n\t *  There may be objects on the list from a previous round if the\n\t *  previous run had finalizer skip flag.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__clear_assert_refcounts(heap);\n#endif\n#if defined(DUK_USE_LITCACHE_SIZE)\n\tduk__wipe_litcache(heap);\n#endif\n\tduk__mark_roots_heap(heap);               /* Mark main reachability roots. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);   /* Always handled to completion inline in DECREF. */\n#endif\n\tduk__mark_temproots_by_heap_scan(heap);   /* Temproots. */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__mark_finalizable(heap);              /* Mark finalizable as reachability roots. */\n\tduk__mark_finalize_list(heap);            /* Mark finalizer work list as reachability roots. */\n#endif\n\tduk__mark_temproots_by_heap_scan(heap);   /* Temproots. */\n\n\t/*\n\t *  Sweep garbage and remove marking flags, and move objects with\n\t *  finalizers to the finalizer work list.\n\t *\n\t *  Objects to be swept need to get their refcounts finalized before\n\t *  they are swept.  In other words, their target object refcounts\n\t *  need to be decreased.  This has to be done before freeing any\n\t *  objects to avoid decref'ing dangling pointers (which may happen\n\t *  even without bugs, e.g. with reference loops)\n\t *\n\t *  Because strings don't point to other heap objects, similar\n\t *  finalization is not necessary for strings.\n\t */\n\n\t/* XXX: more emergency behavior, e.g. find smaller hash sizes etc */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__finalize_refcounts(heap);\n#endif\n\tduk__sweep_heap(heap, flags, &count_keep_obj);\n\tduk__sweep_stringtable(heap, &count_keep_str);\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__check_assert_refcounts(heap);\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);   /* Always handled to completion inline in DECREF. */\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__clear_finalize_list_flags(heap);\n#endif\n\n\t/*\n\t *  Object compaction (emergency only).\n\t *\n\t *  Object compaction is a separate step after sweeping, as there is\n\t *  more free memory for it to work with.  Also, currently compaction\n\t *  may insert new objects into the heap allocated list and the string\n\t *  table which we don't want to do during a sweep (the reachability\n\t *  flags of such objects would be incorrect).  The objects inserted\n\t *  are currently:\n\t *\n\t *    - a temporary duk_hbuffer for a new properties allocation\n\t *    - if array part is abandoned, string keys are interned\n\t *\n\t *  The object insertions go to the front of the list, so they do not\n\t *  cause an infinite loop (they are not compacted).\n\t *\n\t *  At present compaction is not allowed when mark-and-sweep runs\n\t *  during error handling because it involves a duk_safe_call()\n\t *  interfering with error state.\n\t */\n\n\tif ((flags & DUK_MS_FLAG_EMERGENCY) &&\n\t    !(flags & DUK_MS_FLAG_NO_OBJECT_COMPACTION)) {\n\t\tif (heap->lj.type != DUK_LJ_TYPE_UNKNOWN) {\n\t\t\tDUK_D(DUK_DPRINT(\"lj.type (%ld) not DUK_LJ_TYPE_UNKNOWN, skip object compaction\", (long) heap->lj.type));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"object compaction\"));\n\t\t\tduk__compact_objects(heap);\n\t\t}\n\t}\n\n\t/*\n\t *  String table resize check.\n\t *\n\t *  This is mainly useful in emergency GC: if the string table load\n\t *  factor is really low for some reason, we can shrink the string\n\t *  table to a smaller size and free some memory in the process.\n\t *  Only execute in emergency GC.  String table has internal flags\n\t *  to protect against recursive resizing if this mark-and-sweep pass\n\t *  was triggered by a string table resize.\n\t */\n\n\tif (flags & DUK_MS_FLAG_EMERGENCY) {\n\t\tDUK_D(DUK_DPRINT(\"stringtable resize check in emergency gc\"));\n\t\tduk_heap_strtable_force_resize(heap);\n\t}\n\n\t/*\n\t *  Finish\n\t */\n\n\tDUK_ASSERT(heap->ms_prevent_count == 1);\n\tDUK_ASSERT(heap->ms_running == 1);\n\theap->ms_prevent_count = 0;\n\theap->ms_running = 0;\n\n\t/*\n\t *  Assertions after\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\tDUK_ASSERT(!DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap));\n\tDUK_ASSERT(heap->ms_recursion_depth == 0);\n\tduk__assert_heaphdr_flags(heap);\n\tduk__assert_validity(heap);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* Note: heap->refzero_free_running may be true; a refcount\n\t * finalizer may trigger a mark-and-sweep.\n\t */\n\tduk__assert_valid_refcounts(heap);\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n#if defined(DUK_USE_LITCACHE_SIZE)\n\tduk__assert_litcache_nulls(heap);\n#endif  /* DUK_USE_LITCACHE_SIZE */\n#endif  /* DUK_USE_ASSERTIONS */\n\n\t/*\n\t *  Reset trigger counter\n\t */\n\n#if defined(DUK_USE_VOLUNTARY_GC)\n\ttmp = (count_keep_obj + count_keep_str) / 256;\n\theap->ms_trigger_counter = (duk_int_t) (\n\t    (tmp * DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT) +\n\t    DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD);\n\tDUK_D(DUK_DPRINT(\"garbage collect (mark-and-sweep) finished: %ld objects kept, %ld strings kept, trigger reset to %ld\",\n\t                 (long) count_keep_obj, (long) count_keep_str, (long) heap->ms_trigger_counter));\n#else\n\tDUK_D(DUK_DPRINT(\"garbage collect (mark-and-sweep) finished: %ld objects kept, %ld strings kept, no voluntary trigger\",\n\t                 (long) count_keep_obj, (long) count_keep_str));\n#endif\n\n\t/*\n\t *  Stats dump\n\t */\n\n#if defined(DUK_USE_DEBUG)\n\tduk__dump_stats(heap);\n#endif\n\n\t/*\n\t *  Finalize objects in the finalization work list.  Finalized\n\t *  objects are queued back to heap_allocated with FINALIZED set.\n\t *\n\t *  Since finalizers may cause arbitrary side effects, they are\n\t *  prevented e.g. during string table and object property allocation\n\t *  resizing using heap->pf_prevent_count.  In this case the objects\n\t *  remain in the finalization work list after mark-and-sweep exits\n\t *  and they may be finalized on the next pass or any DECREF checking\n\t *  for finalize_list.\n\t *\n\t *  As of Duktape 2.1 finalization happens outside mark-and-sweep\n\t *  protection.  Mark-and-sweep is allowed while the finalize_list\n\t *  is being processed, but no rescue decisions are done while the\n\t *  process is on-going.  This avoids incorrect rescue decisions\n\t *  if an object is considered reachable (and thus rescued) because\n\t *  of a reference via finalize_list (which is considered a reachability\n\t *  root).  When finalize_list is being processed, reachable objects\n\t *  with FINALIZED set will just keep their FINALIZED flag for later\n\t *  mark-and-sweep processing.\n\t *\n\t *  This could also be handled (a bit better) by having a more refined\n\t *  notion of reachability for rescue/free decisions.\n\t *\n\t *  XXX: avoid finalizer execution when doing emergency GC?\n\t */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t/* Attempt to process finalize_list, pf_prevent_count check\n\t * is inside the target.\n\t */\n\tduk_heap_process_finalize_list(heap);\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n}\n#line 1 \"duk_heap_memory.c\"\n/*\n *  Memory allocation handling.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Voluntary GC check\n */\n\n#if defined(DUK_USE_VOLUNTARY_GC)\nDUK_LOCAL DUK_INLINE void duk__check_voluntary_gc(duk_heap *heap) {\n\tif (DUK_UNLIKELY(--(heap)->ms_trigger_counter < 0)) {\n#if defined(DUK_USE_DEBUG)\n\t\tif (heap->ms_prevent_count == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"triggering voluntary mark-and-sweep\"));\n\t\t} else {\n\t\t\tDUK_DD(DUK_DDPRINT(\"gc blocked -> skip voluntary mark-and-sweep now\"));\n\t\t}\n#endif\n\n\t\t/* Prevention checks in the call target handle cases where\n\t\t * voluntary GC is not allowed.  The voluntary GC trigger\n\t\t * counter is only rewritten if mark-and-sweep actually runs.\n\t\t */\n\t\tduk_heap_mark_and_sweep(heap, DUK_MS_FLAG_VOLUNTARY /*flags*/);\n\t}\n}\n#define DUK__VOLUNTARY_PERIODIC_GC(heap)  do { duk__check_voluntary_gc((heap)); } while (0)\n#else\n#define DUK__VOLUNTARY_PERIODIC_GC(heap)  /* no voluntary gc */\n#endif  /* DUK_USE_VOLUNTARY_GC */\n\n/*\n *  Allocate memory with garbage collection\n */\n\nDUK_INTERNAL void *duk_heap_mem_alloc(duk_heap *heap, duk_size_t size) {\n\tvoid *res;\n\tduk_small_int_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT_DISABLE(size >= 0);\n\n\t/*\n\t *  Voluntary periodic GC (if enabled)\n\t */\n\n\tDUK__VOLUNTARY_PERIODIC_GC(heap);\n\n\t/*\n\t *  First attempt\n\t */\n\n#if defined(DUK_USE_GC_TORTURE)\n\t/* Simulate alloc failure on every alloc, except when mark-and-sweep\n\t * is running.\n\t */\n\tif (heap->ms_prevent_count == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"gc torture enabled, pretend that first alloc attempt fails\"));\n\t\tres = NULL;\n\t\tDUK_UNREF(res);\n\t\tgoto skip_attempt;\n\t}\n#endif\n\tres = heap->alloc_func(heap->heap_udata, size);\n\tif (DUK_LIKELY(res || size == 0)) {\n\t\t/* For zero size allocations NULL is allowed. */\n\t\treturn res;\n\t}\n#if defined(DUK_USE_GC_TORTURE)\n skip_attempt:\n#endif\n\n\tDUK_D(DUK_DPRINT(\"first alloc attempt failed, attempt to gc and retry\"));\n\n#if 0\n\t/*\n\t *  Avoid a GC if GC is already running.  This can happen at a late\n\t *  stage in a GC when we try to e.g. resize the stringtable\n\t *  or compact objects.\n\t *\n\t *  NOTE: explicit handling isn't actually be needed: if the GC is\n\t *  not allowed, duk_heap_mark_and_sweep() will reject it for every\n\t *  attempt in the loop below, resulting in a NULL same as here.\n\t */\n\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_alloc() failed, gc in progress (gc skipped), alloc size %ld\", (long) size));\n\t\treturn NULL;\n\t}\n#endif\n\n\t/*\n\t *  Retry with several GC attempts.  Initial attempts are made without\n\t *  emergency mode; later attempts use emergency mode which minimizes\n\t *  memory allocations forcibly.\n\t */\n\n\tfor (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) {\n\t\tduk_small_uint_t flags;\n\n\t\tflags = 0;\n\t\tif (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) {\n\t\t\tflags |= DUK_MS_FLAG_EMERGENCY;\n\t\t}\n\n\t\tduk_heap_mark_and_sweep(heap, flags);\n\n\t\tres = heap->alloc_func(heap->heap_udata, size);\n\t\tif (res) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_alloc() succeeded after gc (pass %ld), alloc size %ld\",\n\t\t\t                 (long) (i + 1), (long) size));\n\t\t\treturn res;\n\t\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"duk_heap_mem_alloc() failed even after gc, alloc size %ld\", (long) size));\n\treturn NULL;\n}\n\nDUK_INTERNAL void *duk_heap_mem_alloc_zeroed(duk_heap *heap, duk_size_t size) {\n\tvoid *res;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT_DISABLE(size >= 0);\n\n\tres = DUK_ALLOC(heap, size);\n\tif (DUK_LIKELY(res != NULL)) {\n\t\tduk_memzero(res, size);\n\t}\n\treturn res;\n}\n\nDUK_INTERNAL void *duk_heap_mem_alloc_checked(duk_hthread *thr, duk_size_t size) {\n\tvoid *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tres = duk_heap_mem_alloc(thr->heap, size);\n\tif (DUK_LIKELY(res != NULL || size == 0)) {\n\t\treturn res;\n\t}\n\tDUK_ERROR_ALLOC_FAILED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_INTERNAL void *duk_heap_mem_alloc_checked_zeroed(duk_hthread *thr, duk_size_t size) {\n\tvoid *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tres = duk_heap_mem_alloc_zeroed(thr->heap, size);\n\tif (DUK_LIKELY(res != NULL || size == 0)) {\n\t\treturn res;\n\t}\n\tDUK_ERROR_ALLOC_FAILED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Reallocate memory with garbage collection\n */\n\nDUK_INTERNAL void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, duk_size_t newsize) {\n\tvoid *res;\n\tduk_small_int_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\t/* ptr may be NULL */\n\tDUK_ASSERT_DISABLE(newsize >= 0);\n\n\t/*\n\t *  Voluntary periodic GC (if enabled)\n\t */\n\n\tDUK__VOLUNTARY_PERIODIC_GC(heap);\n\n\t/*\n\t *  First attempt\n\t */\n\n#if defined(DUK_USE_GC_TORTURE)\n\t/* Simulate alloc failure on every realloc, except when mark-and-sweep\n\t * is running.\n\t */\n\tif (heap->ms_prevent_count == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"gc torture enabled, pretend that first realloc attempt fails\"));\n\t\tres = NULL;\n\t\tDUK_UNREF(res);\n\t\tgoto skip_attempt;\n\t}\n#endif\n\tres = heap->realloc_func(heap->heap_udata, ptr, newsize);\n\tif (DUK_LIKELY(res || newsize == 0)) {\n\t\t/* For zero size allocations NULL is allowed. */\n\t\treturn res;\n\t}\n#if defined(DUK_USE_GC_TORTURE)\n skip_attempt:\n#endif\n\n\tDUK_D(DUK_DPRINT(\"first realloc attempt failed, attempt to gc and retry\"));\n\n#if 0\n\t/*\n\t *  Avoid a GC if GC is already running.  See duk_heap_mem_alloc().\n\t */\n\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc() failed, gc in progress (gc skipped), alloc size %ld\", (long) newsize));\n\t\treturn NULL;\n\t}\n#endif\n\n\t/*\n\t *  Retry with several GC attempts.  Initial attempts are made without\n\t *  emergency mode; later attempts use emergency mode which minimizes\n\t *  memory allocations forcibly.\n\t */\n\n\tfor (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) {\n\t\tduk_small_uint_t flags;\n\n\t\tflags = 0;\n\t\tif (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) {\n\t\t\tflags |= DUK_MS_FLAG_EMERGENCY;\n\t\t}\n\n\t\tduk_heap_mark_and_sweep(heap, flags);\n\n\t\tres = heap->realloc_func(heap->heap_udata, ptr, newsize);\n\t\tif (res || newsize == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc() succeeded after gc (pass %ld), alloc size %ld\",\n\t\t\t                 (long) (i + 1), (long) newsize));\n\t\t\treturn res;\n\t\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc() failed even after gc, alloc size %ld\", (long) newsize));\n\treturn NULL;\n}\n\n/*\n *  Reallocate memory with garbage collection, using a callback to provide\n *  the current allocated pointer.  This variant is used when a mark-and-sweep\n *  (e.g. finalizers) might change the original pointer.\n */\n\nDUK_INTERNAL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize) {\n\tvoid *res;\n\tduk_small_int_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT_DISABLE(newsize >= 0);\n\n\t/*\n\t *  Voluntary periodic GC (if enabled)\n\t */\n\n\tDUK__VOLUNTARY_PERIODIC_GC(heap);\n\n\t/*\n\t *  First attempt\n\t */\n\n#if defined(DUK_USE_GC_TORTURE)\n\t/* Simulate alloc failure on every realloc, except when mark-and-sweep\n\t * is running.\n\t */\n\tif (heap->ms_prevent_count == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"gc torture enabled, pretend that first indirect realloc attempt fails\"));\n\t\tres = NULL;\n\t\tDUK_UNREF(res);\n\t\tgoto skip_attempt;\n\t}\n#endif\n\tres = heap->realloc_func(heap->heap_udata, cb(heap, ud), newsize);\n\tif (DUK_LIKELY(res || newsize == 0)) {\n\t\t/* For zero size allocations NULL is allowed. */\n\t\treturn res;\n\t}\n#if defined(DUK_USE_GC_TORTURE)\n skip_attempt:\n#endif\n\n\tDUK_D(DUK_DPRINT(\"first indirect realloc attempt failed, attempt to gc and retry\"));\n\n#if 0\n\t/*\n\t *  Avoid a GC if GC is already running.  See duk_heap_mem_alloc().\n\t */\n\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc_indirect() failed, gc in progress (gc skipped), alloc size %ld\", (long) newsize));\n\t\treturn NULL;\n\t}\n#endif\n\n\t/*\n\t *  Retry with several GC attempts.  Initial attempts are made without\n\t *  emergency mode; later attempts use emergency mode which minimizes\n\t *  memory allocations forcibly.\n\t */\n\n\tfor (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) {\n\t\tduk_small_uint_t flags;\n\n#if defined(DUK_USE_DEBUG)\n\t\tvoid *ptr_pre;\n\t\tvoid *ptr_post;\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\t\tptr_pre = cb(heap, ud);\n#endif\n\t\tflags = 0;\n\t\tif (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) {\n\t\t\tflags |= DUK_MS_FLAG_EMERGENCY;\n\t\t}\n\n\t\tduk_heap_mark_and_sweep(heap, flags);\n#if defined(DUK_USE_DEBUG)\n\t\tptr_post = cb(heap, ud);\n\t\tif (ptr_pre != ptr_post) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"realloc base pointer changed by mark-and-sweep: %p -> %p\",\n\t\t\t                   (void *) ptr_pre, (void *) ptr_post));\n\t\t}\n#endif\n\n\t\t/* Note: key issue here is to re-lookup the base pointer on every attempt.\n\t\t * The pointer being reallocated may change after every mark-and-sweep.\n\t\t */\n\n\t\tres = heap->realloc_func(heap->heap_udata, cb(heap, ud), newsize);\n\t\tif (res || newsize == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc_indirect() succeeded after gc (pass %ld), alloc size %ld\",\n\t\t\t                 (long) (i + 1), (long) newsize));\n\t\t\treturn res;\n\t\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc_indirect() failed even after gc, alloc size %ld\", (long) newsize));\n\treturn NULL;\n}\n\n/*\n *  Free memory\n */\n\nDUK_INTERNAL void duk_heap_mem_free(duk_heap *heap, void *ptr) {\n\tDUK_ASSERT(heap != NULL);\n\t/* ptr may be NULL */\n\n\t/* Must behave like a no-op with NULL and any pointer returned from\n\t * malloc/realloc with zero size.\n\t */\n\theap->free_func(heap->heap_udata, ptr);\n\n\t/* Never perform a GC (even voluntary) in a memory free, otherwise\n\t * all call sites doing frees would need to deal with the side effects.\n\t * No need to update voluntary GC counter either.\n\t */\n}\n\n/* automatic undefs */\n#undef DUK__VOLUNTARY_PERIODIC_GC\n#line 1 \"duk_heap_misc.c\"\n/*\n *  Support functions for duk_heap.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphdr *hdr) {\n\tduk_heaphdr *root;\n\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) != DUK_HTYPE_STRING);\n\n\troot = heap->heap_allocated;\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tif (root != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, root) == NULL);\n\t\tDUK_HEAPHDR_SET_PREV(heap, root, hdr);\n\t}\n\tDUK_HEAPHDR_SET_PREV(heap, hdr, NULL);\n#endif\n\tDUK_HEAPHDR_SET_NEXT(heap, hdr, root);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, hdr);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, root);\n\theap->heap_allocated = hdr;\n}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL void duk_heap_remove_from_heap_allocated(duk_heap *heap, duk_heaphdr *hdr) {\n\tduk_heaphdr *prev;\n\tduk_heaphdr *next;\n\n\t/* Strings are in string table. */\n\tDUK_ASSERT(hdr != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) != DUK_HTYPE_STRING);\n\n\t/* Target 'hdr' must be in heap_allocated (not e.g. finalize_list).\n\t * If not, heap lists will become corrupted so assert early for it.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\t{\n\t\tduk_heaphdr *tmp;\n\t\tfor (tmp = heap->heap_allocated; tmp != NULL; tmp = DUK_HEAPHDR_GET_NEXT(heap, tmp)) {\n\t\t\tif (tmp == hdr) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(tmp == hdr);\n\t}\n#endif\n\n\t/* Read/write only once to minimize pointer compression calls. */\n\tprev = DUK_HEAPHDR_GET_PREV(heap, hdr);\n\tnext = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\n\tif (prev != NULL) {\n\t\tDUK_ASSERT(heap->heap_allocated != hdr);\n\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, next);\n\t} else {\n\t\tDUK_ASSERT(heap->heap_allocated == hdr);\n\t\theap->heap_allocated = next;\n\t}\n\tif (next != NULL) {\n\t\tDUK_HEAPHDR_SET_PREV(heap, next, prev);\n\t} else {\n\t\t;\n\t}\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL void duk_heap_insert_into_finalize_list(duk_heap *heap, duk_heaphdr *hdr) {\n\tduk_heaphdr *root;\n\n\troot = heap->finalize_list;\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tDUK_HEAPHDR_SET_PREV(heap, hdr, NULL);\n\tif (root != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, root) == NULL);\n\t\tDUK_HEAPHDR_SET_PREV(heap, root, hdr);\n\t}\n#endif\n\tDUK_HEAPHDR_SET_NEXT(heap, hdr, root);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, hdr);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, root);\n\theap->finalize_list = hdr;\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL void duk_heap_remove_from_finalize_list(duk_heap *heap, duk_heaphdr *hdr) {\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tduk_heaphdr *next;\n\tduk_heaphdr *prev;\n\n\tnext = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\tprev = DUK_HEAPHDR_GET_PREV(heap, hdr);\n\tif (next != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, next) == hdr);\n\t\tDUK_HEAPHDR_SET_PREV(heap, next, prev);\n\t}\n\tif (prev == NULL) {\n\t\tDUK_ASSERT(hdr == heap->finalize_list);\n\t\theap->finalize_list = next;\n\t} else {\n\t\tDUK_ASSERT(hdr != heap->finalize_list);\n\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, next);\n\t}\n#else\n\tduk_heaphdr *next;\n\tduk_heaphdr *curr;\n\n\t/* Random removal is expensive: we need to locate the previous element\n\t * because we don't have a 'prev' pointer.\n\t */\n\tcurr = heap->finalize_list;\n\tif (curr == hdr) {\n\t\theap->finalize_list = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t} else {\n\t\tDUK_ASSERT(hdr != heap->finalize_list);\n\t\tfor (;;) {\n\t\t\tDUK_ASSERT(curr != NULL);  /* Caller responsibility. */\n\n\t\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\t\tif (next == hdr) {\n\t\t\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t\t\t\tDUK_HEAPHDR_SET_NEXT(heap, curr, next);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n#endif\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL duk_bool_t duk_heap_in_heap_allocated(duk_heap *heap, duk_heaphdr *ptr) {\n\tduk_heaphdr *curr;\n\tDUK_ASSERT(heap != NULL);\n\n\tfor (curr = heap->heap_allocated; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) {\n\t\tif (curr == ptr) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\nDUK_INTERNAL void duk_heap_switch_thread(duk_heap *heap, duk_hthread *new_thr) {\n\tduk_hthread *curr_thr;\n\n\tDUK_ASSERT(heap != NULL);\n\n\tif (new_thr != NULL) {\n\t\tcurr_thr = heap->curr_thread;\n\t\tif (curr_thr == NULL) {\n\t\t\t/* For initial entry use default value; zero forces an\n\t\t\t * interrupt before executing the first insturction.\n\t\t\t */\n\t\t\tDUK_DD(DUK_DDPRINT(\"switch thread, initial entry, init default interrupt counter\"));\n\t\t\tnew_thr->interrupt_counter = 0;\n\t\t\tnew_thr->interrupt_init = 0;\n\t\t} else {\n\t\t\t/* Copy interrupt counter/init value state to new thread (if any).\n\t\t\t * It's OK for new_thr to be the same as curr_thr.\n\t\t\t */\n#if defined(DUK_USE_DEBUG)\n\t\t\tif (new_thr != curr_thr) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"switch thread, not initial entry, copy interrupt counter\"));\n\t\t\t}\n#endif\n\t\t\tnew_thr->interrupt_counter = curr_thr->interrupt_counter;\n\t\t\tnew_thr->interrupt_init = curr_thr->interrupt_init;\n\t\t}\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"switch thread, new thread is NULL, no interrupt counter changes\"));\n\t}\n\n\theap->curr_thread = new_thr;  /* may be NULL */\n}\n#endif  /* DUK_USE_INTERRUPT_COUNTER */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL void duk_heap_assert_valid(duk_heap *heap) {\n\tDUK_ASSERT(heap != NULL);\n}\n#endif\n#line 1 \"duk_heap_refcount.c\"\n/*\n *  Reference counting implementation.\n *\n *  INCREF/DECREF, finalization and freeing of objects whose refcount reaches\n *  zero (refzero).  These operations are very performance sensitive, so\n *  various small tricks are used in an attempt to maximize speed.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\n#if !defined(DUK_USE_DOUBLE_LINKED_HEAP)\n#error internal error, reference counting requires a double linked heap\n#endif\n\n/*\n *  Heap object refcount finalization.\n *\n *  When an object is about to be freed, all other objects it refers to must\n *  be decref'd.  Refcount finalization does NOT free the object or its inner\n *  allocations (mark-and-sweep shares these helpers), it just manipulates\n *  the refcounts.\n *\n *  Note that any of the DECREFs may cause a refcount to drop to zero.  If so,\n *  the object won't be refzero processed inline, but will just be queued to\n *  refzero_list and processed by an earlier caller working on refzero_list,\n *  eliminating C recursion from even long refzero cascades.  If refzero\n *  finalization is triggered by mark-and-sweep, refzero conditions are ignored\n *  (objects are not even queued to refzero_list) because mark-and-sweep deals\n *  with them; refcounts are still updated so that they remain in sync with\n *  actual references.\n */\n\nDUK_LOCAL void duk__decref_tvals_norz(duk_hthread *thr, duk_tval *tv, duk_idx_t count) {\n\tDUK_ASSERT(count == 0 || tv != NULL);\n\n\twhile (count-- > 0) {\n\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t\ttv++;\n\t}\n}\n\nDUK_INTERNAL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject *h) {\n\tduk_hthread *thr;\n\tduk_uint_fast32_t i;\n\tduk_uint_fast32_t n;\n\tduk_propvalue *p_val;\n\tduk_tval *p_tv;\n\tduk_hstring **p_key;\n\tduk_uint8_t *p_flag;\n\tduk_hobject *h_proto;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(h);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h) == DUK_HTYPE_OBJECT);\n\n\tthr = heap->heap_thread;\n\tDUK_ASSERT(thr != NULL);\n\n\tp_key = DUK_HOBJECT_E_GET_KEY_BASE(heap, h);\n\tp_val = DUK_HOBJECT_E_GET_VALUE_BASE(heap, h);\n\tp_flag = DUK_HOBJECT_E_GET_FLAGS_BASE(heap, h);\n\tn = DUK_HOBJECT_GET_ENEXT(h);\n\twhile (n-- > 0) {\n\t\tduk_hstring *key;\n\n\t\tkey = p_key[n];\n\t\tif (DUK_UNLIKELY(key == NULL)) {\n\t\t\tcontinue;\n\t\t}\n\t\tDUK_HSTRING_DECREF_NORZ(thr, key);\n\t\tif (DUK_UNLIKELY(p_flag[n] & DUK_PROPDESC_FLAG_ACCESSOR)) {\n\t\t\tduk_hobject *h_getset;\n\t\t\th_getset = p_val[n].a.get;\n\t\t\tDUK_ASSERT(h_getset == NULL || DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_getset));\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h_getset);\n\t\t\th_getset = p_val[n].a.set;\n\t\t\tDUK_ASSERT(h_getset == NULL || DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_getset));\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h_getset);\n\t\t} else {\n\t\t\tduk_tval *tv_val;\n\t\t\ttv_val = &p_val[n].v;\n\t\t\tDUK_TVAL_DECREF_NORZ(thr, tv_val);\n\t\t}\n\t}\n\n\tp_tv = DUK_HOBJECT_A_GET_BASE(heap, h);\n\tn = DUK_HOBJECT_GET_ASIZE(h);\n\twhile (n-- > 0) {\n\t\tduk_tval *tv_val;\n\t\ttv_val = p_tv + n;\n\t\tDUK_TVAL_DECREF_NORZ(thr, tv_val);\n\t}\n\n\t/* Hash part is a 'weak reference' and doesn't contribute to refcounts. */\n\n\th_proto = (duk_hobject *) DUK_HOBJECT_GET_PROTOTYPE(heap, h);\n\tDUK_ASSERT(h_proto == NULL || DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_proto));\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h_proto);\n\n\t/* XXX: Object subclass tests are quite awkward at present, ideally\n\t * we should be able to switch-case here with a dense index (subtype\n\t * number or something).  For now, fast path plain objects and arrays\n\t * and bit test the rest individually.\n\t */\n\n\tif (DUK_HOBJECT_HAS_FASTREFS(h)) {\n\t\t/* Plain object or array, nothing more to do.  While a\n\t\t * duk_harray has additional fields, none of them need\n\t\t * DECREF updates.\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_ALLOWS_FASTREFS(h));\n\t\treturn;\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_PROHIBITS_FASTREFS(h));\n\n\t/* Slow path: special object, start bit checks from most likely. */\n\n\t/* XXX: reorg, more common first */\n\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tduk_tval *tv, *tv_end;\n\t\tduk_hobject **funcs, **funcs_end;\n\n\t\tDUK_HCOMPFUNC_ASSERT_VALID(f);\n\n\t\tif (DUK_LIKELY(DUK_HCOMPFUNC_GET_DATA(heap, f) != NULL)) {\n\t\t\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, f);\n\t\t\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(heap, f);\n\t\t\twhile (tv < tv_end) {\n\t\t\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t\t\t\ttv++;\n\t\t\t}\n\n\t\t\tfuncs = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, f);\n\t\t\tfuncs_end = DUK_HCOMPFUNC_GET_FUNCS_END(heap, f);\n\t\t\twhile (funcs < funcs_end) {\n\t\t\t\tduk_hobject *h_func;\n\t\t\t\th_func = *funcs;\n\t\t\t\tDUK_ASSERT(h_func != NULL);\n\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_func));\n\t\t\t\tDUK_HCOMPFUNC_DECREF_NORZ(thr, (duk_hcompfunc *) h_func);\n\t\t\t\tfuncs++;\n\t\t\t}\n\t\t} else {\n\t\t\t/* May happen in some out-of-memory corner cases. */\n\t\t\tDUK_D(DUK_DPRINT(\"duk_hcompfunc 'data' is NULL, skipping decref\"));\n\t\t}\n\n\t\tDUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_heaphdr *) DUK_HCOMPFUNC_GET_LEXENV(heap, f));\n\t\tDUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_heaphdr *) DUK_HCOMPFUNC_GET_VARENV(heap, f));\n\t\tDUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(heap, f));\n\t} else if (DUK_HOBJECT_IS_DECENV(h)) {\n\t\tduk_hdecenv *e = (duk_hdecenv *) h;\n\t\tDUK_HDECENV_ASSERT_VALID(e);\n\t\tDUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr, e->thread);\n\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, e->varmap);\n\t} else if (DUK_HOBJECT_IS_OBJENV(h)) {\n\t\tduk_hobjenv *e = (duk_hobjenv *) h;\n\t\tDUK_HOBJENV_ASSERT_VALID(e);\n\t\tDUK_ASSERT(e->target != NULL);  /* Required for object environments. */\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, e->target);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\tduk_hbufobj *b = (duk_hbufobj *) h;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(b);\n\t\tDUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr, (duk_hbuffer *) b->buf);\n\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) b->buf_prop);\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {\n\t\tduk_hboundfunc *f = (duk_hboundfunc *) (void *) h;\n\t\tDUK_HBOUNDFUNC_ASSERT_VALID(f);\n\t\tDUK_TVAL_DECREF_NORZ(thr, &f->target);\n\t\tDUK_TVAL_DECREF_NORZ(thr, &f->this_binding);\n\t\tduk__decref_tvals_norz(thr, f->args, f->nargs);\n#if defined(DUK_USE_ES6_PROXY)\n\t} else if (DUK_HOBJECT_IS_PROXY(h)) {\n\t\tduk_hproxy *p = (duk_hproxy *) h;\n\t\tDUK_HPROXY_ASSERT_VALID(p);\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, p->target);\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, p->handler);\n#endif  /* DUK_USE_ES6_PROXY */\n\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tduk_activation *act;\n\t\tduk_tval *tv;\n\n\t\tDUK_HTHREAD_ASSERT_VALID(t);\n\n\t\ttv = t->valstack;\n\t\twhile (tv < t->valstack_top) {\n\t\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t\t\ttv++;\n\t\t}\n\n\t\tfor (act = t->callstack_curr; act != NULL; act = act->parent) {\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) DUK_ACT_GET_FUNC(act));\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->var_env);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->lex_env);\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->prev_caller);\n#endif\n#if 0  /* nothing now */\n\t\t\tfor (cat = act->cat; cat != NULL; cat = cat->parent) {\n\t\t\t}\n#endif\n\t\t}\n\n\n\t\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) t->builtins[i]);\n\t\t}\n\n\t\tDUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr, (duk_hthread *) t->resumer);\n\t} else {\n\t\t/* We may come here if the object should have a FASTREFS flag\n\t\t * but it's missing for some reason.  Assert for never getting\n\t\t * here; however, other than performance, this is harmless.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"missing FASTREFS flag for: %!iO\", h));\n\t\tDUK_ASSERT(0);\n\t}\n}\n\nDUK_INTERNAL void duk_heaphdr_refcount_finalize_norz(duk_heap *heap, duk_heaphdr *hdr) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(hdr != NULL);\n\n\tif (DUK_HEAPHDR_IS_OBJECT(hdr)) {\n\t\tduk_hobject_refcount_finalize_norz(heap, (duk_hobject *) hdr);\n\t}\n\t/* DUK_HTYPE_BUFFER: nothing to finalize */\n\t/* DUK_HTYPE_STRING: nothing to finalize */\n}\n\n/*\n *  Refzero processing for duk_hobject: queue a refzero'ed object to either\n *  finalize_list or refzero_list and process the relevent list(s) if\n *  necessary.\n *\n *  Refzero_list is single linked, with only 'prev' pointers set and valid.\n *  All 'next' pointers are intentionally left as garbage.  This doesn't\n *  matter because refzero_list is processed to completion before any other\n *  code (like mark-and-sweep) might walk the list.\n *\n *  In more detail:\n *\n *  - On first insert refzero_list is NULL and the new object becomes the\n *    first and only element on the list; duk__refcount_free_pending() is\n *    called and it starts processing the list from the initial element,\n *    i.e. the list tail.\n *\n *  - As each object is refcount finalized, new objects may be queued to\n *    refzero_list head.  Their 'next' pointers are left as garbage, but\n *    'prev' points are set correctly, with the element at refzero_list\n *    having a NULL 'prev' pointer.  The fact that refzero_list is non-NULL\n *    is used to reject (1) recursive duk__refcount_free_pending() and\n *    (2) finalize_list processing calls.\n *\n *  - When we're done with the current object, read its 'prev' pointer and\n *    free the object.  If 'prev' is NULL, we've reached head of list and are\n *    done: set refzero_list to NULL and process pending finalizers.  Otherwise\n *    continue processing the list.\n *\n *  A refzero cascade is free of side effects because it only involves\n *  queueing more objects and freeing memory; finalizer execution is blocked\n *  in the code path queueing objects to finalize_list.  As a result the\n *  initial refzero call (which triggers duk__refcount_free_pending()) must\n *  check finalize_list so that finalizers are executed snappily.\n *\n *  If finalize_list processing starts first, refzero may occur while we're\n *  processing finalizers.  That's fine: that particular refzero cascade is\n *  handled to completion without side effects.  Once the cascade is complete,\n *  we'll run pending finalizers but notice that we're already doing that and\n *  return.\n *\n *  This could be expanded to allow incremental freeing: just bail out\n *  early and resume at a future alloc/decref/refzero.  However, if that\n *  were done, the list structure would need to be kept consistent at all\n *  times, mark-and-sweep would need to handle refzero_list, etc.\n */\n\nDUK_LOCAL void duk__refcount_free_pending(duk_heap *heap) {\n\tduk_heaphdr *curr;\n#if defined(DUK_USE_DEBUG)\n\tduk_int_t count = 0;\n#endif\n\n\tDUK_ASSERT(heap != NULL);\n\n\tcurr = heap->refzero_list;\n\tDUK_ASSERT(curr != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, curr) == NULL);  /* We're called on initial insert only. */\n\t/* curr->next is GARBAGE. */\n\n\tdo {\n\t\tduk_heaphdr *prev;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"refzero processing %p: %!O\", (void *) curr, (duk_heaphdr *) curr));\n\n#if defined(DUK_USE_DEBUG)\n\t\tcount++;\n#endif\n\n\t\tDUK_ASSERT(curr != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);  /* currently, always the case */\n\t\t/* FINALIZED may be set; don't care about flags here. */\n\n\t\t/* Refcount finalize 'curr'.  Refzero_list must be non-NULL\n\t\t * here to prevent recursive entry to duk__refcount_free_pending().\n\t\t */\n\t\tDUK_ASSERT(heap->refzero_list != NULL);\n\t\tduk_hobject_refcount_finalize_norz(heap, (duk_hobject *) curr);\n\n\t\tprev = DUK_HEAPHDR_GET_PREV(heap, curr);\n\t\tDUK_ASSERT((prev == NULL && heap->refzero_list == curr) || \\\n\t\t           (prev != NULL && heap->refzero_list != curr));\n\t\t/* prev->next is intentionally not updated and is garbage. */\n\n\t\tduk_free_hobject(heap, (duk_hobject *) curr);  /* Invalidates 'curr'. */\n\n\t\tcurr = prev;\n\t} while (curr != NULL);\n\n\theap->refzero_list = NULL;\n\n\tDUK_DD(DUK_DDPRINT(\"refzero processed %ld objects\", (long) count));\n}\n\nDUK_LOCAL DUK_INLINE void duk__refcount_refzero_hobject(duk_heap *heap, duk_hobject *obj, duk_bool_t skip_free_pending) {\n\tduk_heaphdr *hdr;\n\tduk_heaphdr *root;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) obj) == DUK_HTYPE_OBJECT);\n\n\thdr = (duk_heaphdr *) obj;\n\n\t/* Refzero'd objects must be in heap_allocated.  They can't be in\n\t * finalize_list because all objects on finalize_list have an\n\t * artificial +1 refcount bump.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(duk_heap_in_heap_allocated(heap, (duk_heaphdr *) obj));\n#endif\n\n\tDUK_HEAP_REMOVE_FROM_HEAP_ALLOCATED(heap, hdr);\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t/* This finalizer check MUST BE side effect free.  It should also be\n\t * as fast as possible because it's applied to every object freed.\n\t */\n\tif (DUK_UNLIKELY(DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) hdr) != 0U)) {\n\t\t/* Special case: FINALIZED may be set if mark-and-sweep queued\n\t\t * object for finalization, the finalizer was executed (and\n\t\t * FINALIZED set), mark-and-sweep hasn't yet processed the\n\t\t * object again, but its refcount drops to zero.  Free without\n\t\t * running the finalizer again.\n\t\t */\n\t\tif (DUK_HEAPHDR_HAS_FINALIZED(hdr)) {\n\t\t\tDUK_D(DUK_DPRINT(\"refzero'd object has finalizer and FINALIZED is set -> free\"));\n\t\t} else {\n\t\t\t/* Set FINALIZABLE flag so that all objects on finalize_list\n\t\t\t * will have it set and are thus detectable based on the\n\t\t\t * flag alone.\n\t\t\t */\n\t\t\tDUK_HEAPHDR_SET_FINALIZABLE(hdr);\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(hdr));\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t/* Bump refcount on finalize_list insert so that a\n\t\t\t * refzero can never occur when an object is waiting\n\t\t\t * for its finalizer call.  Refzero might otherwise\n\t\t\t * now happen because we allow duk_push_heapptr() for\n\t\t\t * objects pending finalization.\n\t\t\t */\n\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(hdr);\n#endif\n\t\t\tDUK_HEAP_INSERT_INTO_FINALIZE_LIST(heap, hdr);\n\n\t\t\t/* Process finalizers unless skipping is explicitly\n\t\t\t * requested (NORZ) or refzero_list is being processed\n\t\t\t * (avoids side effects during a refzero cascade).\n\t\t\t * If refzero_list is processed, the initial refzero\n\t\t\t * call will run pending finalizers when refzero_list\n\t\t\t * is done.\n\t\t\t */\n\t\t\tif (!skip_free_pending && heap->refzero_list == NULL) {\n\t\t\t\tduk_heap_process_finalize_list(heap);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n\t/* No need to finalize, free object via refzero_list. */\n\n\troot = heap->refzero_list;\n\n\tDUK_HEAPHDR_SET_PREV(heap, hdr, NULL);\n\t/* 'next' is left as GARBAGE. */\n\theap->refzero_list = hdr;\n\n\tif (root == NULL) {\n\t\t/* Object is now queued.  Refzero_list was NULL so\n\t\t * no-one is currently processing it; do it here.\n\t\t * With refzero processing just doing a cascade of\n\t\t * free calls, we can process it directly even when\n\t\t * NORZ macros are used: there are no side effects.\n\t\t */\n\t\tduk__refcount_free_pending(heap);\n\t\tDUK_ASSERT(heap->refzero_list == NULL);\n\n\t\t/* Process finalizers only after the entire cascade\n\t\t * is finished.  In most cases there's nothing to\n\t\t * finalize, so fast path check to avoid a call.\n\t\t */\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\tif (!skip_free_pending && DUK_UNLIKELY(heap->finalize_list != NULL)) {\n\t\t\tduk_heap_process_finalize_list(heap);\n\t\t}\n#endif\n\t} else {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, root) == NULL);\n\t\tDUK_HEAPHDR_SET_PREV(heap, root, hdr);\n\n\t\t/* Object is now queued.  Because refzero_list was\n\t\t * non-NULL, it's already being processed by someone\n\t\t * in the C call stack, so we're done.\n\t\t */\n\t}\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_refzero_check_fast(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->heap->refzero_list == NULL);  /* Processed to completion inline. */\n\n\tif (DUK_UNLIKELY(thr->heap->finalize_list != NULL)) {\n\t\tduk_heap_process_finalize_list(thr->heap);\n\t}\n}\n\nDUK_INTERNAL void duk_refzero_check_slow(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->heap->refzero_list == NULL);  /* Processed to completion inline. */\n\n\tif (DUK_UNLIKELY(thr->heap->finalize_list != NULL)) {\n\t\tduk_heap_process_finalize_list(thr->heap);\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Refzero processing for duk_hstring.\n */\n\nDUK_LOCAL DUK_INLINE void duk__refcount_refzero_hstring(duk_heap *heap, duk_hstring *str) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(str != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) str) == DUK_HTYPE_STRING);\n\n\tduk_heap_strcache_string_remove(heap, str);\n\tduk_heap_strtable_unlink(heap, str);\n\tduk_free_hstring(heap, str);\n}\n\n/*\n *  Refzero processing for duk_hbuffer.\n */\n\nDUK_LOCAL DUK_INLINE void duk__refcount_refzero_hbuffer(duk_heap *heap, duk_hbuffer *buf) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) buf) == DUK_HTYPE_BUFFER);\n\n\tDUK_HEAP_REMOVE_FROM_HEAP_ALLOCATED(heap, (duk_heaphdr *) buf);\n\tduk_free_hbuffer(heap, buf);\n}\n\n/*\n *  Incref and decref functions.\n *\n *  Decref may trigger immediate refzero handling, which may free and finalize\n *  an arbitrary number of objects (a \"DECREF cascade\").\n *\n *  Refzero handling is skipped entirely if (1) mark-and-sweep is running or\n *  (2) execution is paused in the debugger.  The objects are left in the heap,\n *  and will be freed by mark-and-sweep or eventual heap destruction.\n *\n *  This is necessary during mark-and-sweep because refcounts are also updated\n *  during the sweep phase (otherwise objects referenced by a swept object\n *  would have incorrect refcounts) which then calls here.  This could be\n *  avoided by using separate decref macros in mark-and-sweep; however,\n *  mark-and-sweep also calls finalizers which would use the ordinary decref\n *  macros anyway.\n *\n *  We can't process refzeros (= free objects) when the debugger is running\n *  as the debugger might make an object unreachable but still continue\n *  inspecting it (or even cause it to be pushed back).  So we must rely on\n *  mark-and-sweep to collect them.\n *\n *  The DUK__RZ_SUPPRESS_CHECK() condition is also used in heap destruction\n *  when running finalizers for remaining objects: the flag prevents objects\n *  from being moved around in heap linked lists while that's being done.\n *\n *  The suppress condition is important to performance.\n */\n\n#define DUK__RZ_SUPPRESS_ASSERT1() do { \\\n\t\tDUK_ASSERT(thr != NULL); \\\n\t\tDUK_ASSERT(thr->heap != NULL); \\\n\t\t/* When mark-and-sweep runs, heap_thread must exist. */ \\\n\t\tDUK_ASSERT(thr->heap->ms_running == 0 || thr->heap->heap_thread != NULL); \\\n\t\t/* In normal operation finalizers are executed with ms_running == 0 \\\n\t\t * so we should never see ms_running == 1 and thr != heap_thread. \\\n\t\t * In heap destruction finalizers are executed with ms_running != 0 \\\n\t\t * to e.g. prevent refzero; a special value ms_running == 2 is used \\\n\t\t * in that case so it can be distinguished from the normal runtime \\\n\t\t * case, and allows a stronger assertion here (GH-2030). \\\n\t\t */ \\\n\t\tDUK_ASSERT(!(thr->heap->ms_running == 1 && thr != thr->heap->heap_thread)); \\\n\t\t/* We may be called when the heap is initializing and we process \\\n\t\t * refzeros normally, but mark-and-sweep and finalizers are prevented \\\n\t\t * if that's the case. \\\n\t\t */ \\\n\t\tDUK_ASSERT(thr->heap->heap_initializing == 0 || thr->heap->ms_prevent_count > 0); \\\n\t\tDUK_ASSERT(thr->heap->heap_initializing == 0 || thr->heap->pf_prevent_count > 0); \\\n\t} while (0)\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n#define DUK__RZ_SUPPRESS_ASSERT2() do { \\\n\t\t/* When debugger is paused, ms_running is set. */ \\\n\t\tDUK_ASSERT(!DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || thr->heap->ms_running != 0); \\\n\t} while (0)\n#define DUK__RZ_SUPPRESS_COND()  (heap->ms_running != 0)\n#else\n#define DUK__RZ_SUPPRESS_ASSERT2() do { } while (0)\n#define DUK__RZ_SUPPRESS_COND()  (heap->ms_running != 0)\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n#define DUK__RZ_SUPPRESS_CHECK() do { \\\n\t\tDUK__RZ_SUPPRESS_ASSERT1(); \\\n\t\tDUK__RZ_SUPPRESS_ASSERT2(); \\\n\t\tif (DUK_UNLIKELY(DUK__RZ_SUPPRESS_COND())) { \\\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"refzero handling suppressed (not even queued) when mark-and-sweep running, object: %p\", (void *) h)); \\\n\t\t\treturn; \\\n\t\t} \\\n\t} while (0)\n\n#define DUK__RZ_STRING() do { \\\n\t\tduk__refcount_refzero_hstring(heap, (duk_hstring *) h); \\\n\t} while (0)\n#define DUK__RZ_BUFFER() do { \\\n\t\tduk__refcount_refzero_hbuffer(heap, (duk_hbuffer *) h); \\\n\t} while (0)\n#define DUK__RZ_OBJECT() do { \\\n\t\tduk__refcount_refzero_hobject(heap, (duk_hobject *) h, skip_free_pending); \\\n\t} while (0)\n\n/* XXX: test the effect of inlining here vs. NOINLINE in refzero helpers */\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n#define DUK__RZ_INLINE DUK_ALWAYS_INLINE\n#else\n#define DUK__RZ_INLINE /*nop*/\n#endif\n\nDUK_LOCAL DUK__RZ_INLINE void duk__hstring_refzero_helper(duk_hthread *thr, duk_hstring *h) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\tDUK__RZ_SUPPRESS_CHECK();\n\tDUK__RZ_STRING();\n}\n\nDUK_LOCAL DUK__RZ_INLINE void duk__hbuffer_refzero_helper(duk_hthread *thr, duk_hbuffer *h) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\tDUK__RZ_SUPPRESS_CHECK();\n\tDUK__RZ_BUFFER();\n}\n\nDUK_LOCAL DUK__RZ_INLINE void duk__hobject_refzero_helper(duk_hthread *thr, duk_hobject *h, duk_bool_t skip_free_pending) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\tDUK__RZ_SUPPRESS_CHECK();\n\tDUK__RZ_OBJECT();\n}\n\nDUK_LOCAL DUK__RZ_INLINE void duk__heaphdr_refzero_helper(duk_hthread *thr, duk_heaphdr *h, duk_bool_t skip_free_pending) {\n\tduk_heap *heap;\n\tduk_small_uint_t htype;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\thtype = (duk_small_uint_t) DUK_HEAPHDR_GET_TYPE(h);\n\tDUK_DDD(DUK_DDDPRINT(\"ms_running=%ld, heap_thread=%p\", (long) thr->heap->ms_running, thr->heap->heap_thread));\n\tDUK__RZ_SUPPRESS_CHECK();\n\n\tswitch (htype) {\n\tcase DUK_HTYPE_STRING:\n\t\t/* Strings have no internal references but do have \"weak\"\n\t\t * references in the string cache.  Also note that strings\n\t\t * are not on the heap_allocated list like other heap\n\t\t * elements.\n\t\t */\n\n\t\tDUK__RZ_STRING();\n\t\tbreak;\n\n\tcase DUK_HTYPE_OBJECT:\n\t\t/* Objects have internal references.  Must finalize through\n\t\t * the \"refzero\" work list.\n\t\t */\n\n\t\tDUK__RZ_OBJECT();\n\t\tbreak;\n\n\tdefault:\n\t\t/* Buffers have no internal references.  However, a dynamic\n\t\t * buffer has a separate allocation for the buffer.  This is\n\t\t * freed by duk_heap_free_heaphdr_raw().\n\t\t */\n\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(h) == DUK_HTYPE_BUFFER);\n\t\tDUK__RZ_BUFFER();\n\t\tbreak;\n\t}\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h) {\n\tduk__heaphdr_refzero_helper(thr, h, 0 /*skip_free_pending*/);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_heaphdr_refzero_norz(duk_hthread *thr, duk_heaphdr *h) {\n\tduk__heaphdr_refzero_helper(thr, h, 1 /*skip_free_pending*/);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hstring_refzero(duk_hthread *thr, duk_hstring *h) {\n\tduk__hstring_refzero_helper(thr, h);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hbuffer_refzero(duk_hthread *thr, duk_hbuffer *h) {\n\tduk__hbuffer_refzero_helper(thr, h);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hobject_refzero(duk_hthread *thr, duk_hobject *h) {\n\tduk__hobject_refzero_helper(thr, h, 0 /*skip_free_pending*/);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hobject_refzero_norz(duk_hthread *thr, duk_hobject *h) {\n\tduk__hobject_refzero_helper(thr, h, 1 /*skip_free_pending*/);\n}\n\n#if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\nDUK_INTERNAL void duk_tval_incref(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\t\tDUK_ASSERT_DISABLE(h->h_refcount >= 0);\n\t\tDUK_HEAPHDR_PREINC_REFCOUNT(h);\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) != 0);  /* No wrapping. */\n\t}\n}\n\nDUK_INTERNAL void duk_tval_decref(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) >= 1);\n#if 0\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(h) != 0) {\n\t\t\treturn;\n\t\t}\n\t\tduk_heaphdr_refzero(thr, h);\n#else\n\t\tduk_heaphdr_decref(thr, h);\n#endif\n\t}\n}\n\nDUK_INTERNAL void duk_tval_decref_norz(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) >= 1);\n#if 0\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(h) != 0) {\n\t\t\treturn;\n\t\t}\n\t\tduk_heaphdr_refzero_norz(thr, h);\n#else\n\t\tduk_heaphdr_decref_norz(thr, h);\n#endif\n\t}\n}\n#endif  /* !DUK_USE_FAST_REFCOUNT_DEFAULT */\n\n#define DUK__DECREF_ASSERTS() do { \\\n\t\tDUK_ASSERT(thr != NULL); \\\n\t\tDUK_ASSERT(thr->heap != NULL); \\\n\t\tDUK_ASSERT(h != NULL); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID((duk_heaphdr *) h)); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) >= 1); \\\n\t} while (0)\n#if defined(DUK_USE_ROM_OBJECTS)\n#define DUK__INCREF_SHARED() do { \\\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t\tDUK_HEAPHDR_PREINC_REFCOUNT((duk_heaphdr *) h); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) != 0);  /* No wrapping. */ \\\n\t} while (0)\n#define DUK__DECREF_SHARED() do { \\\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT((duk_heaphdr *) h) != 0) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t} while (0)\n#else\n#define DUK__INCREF_SHARED() do { \\\n\t\tDUK_HEAPHDR_PREINC_REFCOUNT((duk_heaphdr *) h); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) != 0);  /* No wrapping. */ \\\n\t} while (0)\n#define DUK__DECREF_SHARED() do { \\\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT((duk_heaphdr *) h) != 0) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t} while (0)\n#endif\n\n#if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n/* This will in practice be inlined because it's just an INC instructions\n * and a bit test + INC when ROM objects are enabled.\n */\nDUK_INTERNAL void duk_heaphdr_incref(duk_heaphdr *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\tDUK_ASSERT_DISABLE(DUK_HEAPHDR_GET_REFCOUNT(h) >= 0);\n\n\tDUK__INCREF_SHARED();\n}\n\nDUK_INTERNAL void duk_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_heaphdr_refzero(thr, h);\n\n\t/* Forced mark-and-sweep when GC torture enabled; this could happen\n\t * on any DECREF (but not DECREF_NORZ).\n\t */\n\tDUK_GC_TORTURE(thr->heap);\n}\nDUK_INTERNAL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_heaphdr_refzero_norz(thr, h);\n}\n#endif  /* !DUK_USE_FAST_REFCOUNT_DEFAULT */\n\n#if 0  /* Not needed. */\nDUK_INTERNAL void duk_hstring_decref(duk_hthread *thr, duk_hstring *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hstring_refzero(thr, h);\n}\nDUK_INTERNAL void duk_hstring_decref_norz(duk_hthread *thr, duk_hstring *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hstring_refzero_norz(thr, h);\n}\nDUK_INTERNAL void duk_hbuffer_decref(duk_hthread *thr, duk_hbuffer *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hbuffer_refzero(thr, h);\n}\nDUK_INTERNAL void duk_hbuffer_decref_norz(duk_hthread *thr, duk_hbuffer *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hbuffer_refzero_norz(thr, h);\n}\nDUK_INTERNAL void duk_hobject_decref(duk_hthread *thr, duk_hobject *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hobject_refzero(thr, h);\n}\nDUK_INTERNAL void duk_hobject_decref_norz(duk_hthread *thr, duk_hobject *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hobject_refzero_norz(thr, h);\n}\n#endif\n\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\n/* no refcounting */\n\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/* automatic undefs */\n#undef DUK__DECREF_ASSERTS\n#undef DUK__DECREF_SHARED\n#undef DUK__INCREF_SHARED\n#undef DUK__RZ_BUFFER\n#undef DUK__RZ_INLINE\n#undef DUK__RZ_OBJECT\n#undef DUK__RZ_STRING\n#undef DUK__RZ_SUPPRESS_ASSERT1\n#undef DUK__RZ_SUPPRESS_ASSERT2\n#undef DUK__RZ_SUPPRESS_CHECK\n#undef DUK__RZ_SUPPRESS_COND\n#line 1 \"duk_heap_stringcache.c\"\n/*\n *  String cache.\n *\n *  Provides a cache to optimize indexed string lookups.  The cache keeps\n *  track of (byte offset, char offset) states for a fixed number of strings.\n *  Otherwise we'd need to scan from either end of the string, as we store\n *  strings in (extended) UTF-8.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Delete references to given hstring from the heap string cache.\n *\n *  String cache references are 'weak': they are not counted towards\n *  reference counts, nor serve as roots for mark-and-sweep.  When an\n *  object is about to be freed, such references need to be removed.\n */\n\nDUK_INTERNAL void duk_heap_strcache_string_remove(duk_heap *heap, duk_hstring *h) {\n\tduk_uint_t i;\n\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\tduk_strcache_entry *c = heap->strcache + i;\n\t\tif (c->h == h) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"deleting weak strcache reference to hstring %p from heap %p\",\n\t\t\t                   (void *) h, (void *) heap));\n\t\t\tc->h = NULL;\n\n\t\t\t/* XXX: the string shouldn't appear twice, but we now loop to the\n\t\t\t * end anyway; if fixed, add a looping assertion to ensure there\n\t\t\t * is no duplicate.\n\t\t\t */\n\t\t}\n\t}\n}\n\n/*\n *  String scanning helpers\n *\n *  All bytes other than UTF-8 continuation bytes ([0x80,0xbf]) are\n *  considered to contribute a character.  This must match how string\n *  character length is computed.\n */\n\nDUK_LOCAL const duk_uint8_t *duk__scan_forwards(const duk_uint8_t *p, const duk_uint8_t *q, duk_uint_fast32_t n) {\n\twhile (n > 0) {\n\t\tfor (;;) {\n\t\t\tp++;\n\t\t\tif (p >= q) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\tif ((*p & 0xc0) != 0x80) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tn--;\n\t}\n\treturn p;\n}\n\nDUK_LOCAL const duk_uint8_t *duk__scan_backwards(const duk_uint8_t *p, const duk_uint8_t *q, duk_uint_fast32_t n) {\n\twhile (n > 0) {\n\t\tfor (;;) {\n\t\t\tp--;\n\t\t\tif (p < q) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\tif ((*p & 0xc0) != 0x80) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tn--;\n\t}\n\treturn p;\n}\n\n/*\n *  Convert char offset to byte offset\n *\n *  Avoid using the string cache if possible: for ASCII strings byte and\n *  char offsets are equal and for short strings direct scanning may be\n *  better than using the string cache (which may evict a more important\n *  entry).\n *\n *  Typing now assumes 32-bit string byte/char offsets (duk_uint_fast32_t).\n *  Better typing might be to use duk_size_t.\n *\n *  Caller should ensure 'char_offset' is within the string bounds [0,charlen]\n *  (endpoint is inclusive).  If this is not the case, no memory unsafe\n *  behavior will happen but an error will be thrown.\n */\n\nDUK_INTERNAL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *thr, duk_hstring *h, duk_uint_fast32_t char_offset) {\n\tduk_heap *heap;\n\tduk_strcache_entry *sce;\n\tduk_uint_fast32_t byte_offset;\n\tduk_uint_t i;\n\tduk_bool_t use_cache;\n\tduk_uint_fast32_t dist_start, dist_end, dist_sce;\n\tduk_uint_fast32_t char_length;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint8_t *p_found;\n\n\t/*\n\t *  For ASCII strings, the answer is simple.\n\t */\n\n\tif (DUK_LIKELY(DUK_HSTRING_IS_ASCII(h))) {\n\t\treturn char_offset;\n\t}\n\n\tchar_length = (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h);\n\tDUK_ASSERT(char_offset <= char_length);\n\n\tif (DUK_LIKELY(DUK_HSTRING_IS_ASCII(h))) {\n\t\t/* Must recheck because the 'is ascii' flag may be set\n\t\t * lazily.  Alternatively, we could just compare charlen\n\t\t * to bytelen.\n\t\t */\n\t\treturn char_offset;\n\t}\n\n\t/*\n\t *  For non-ASCII strings, we need to scan forwards or backwards\n\t *  from some starting point.  The starting point may be the start\n\t *  or end of the string, or some cached midpoint in the string\n\t *  cache.\n\t *\n\t *  For \"short\" strings we simply scan without checking or updating\n\t *  the cache.  For longer strings we check and update the cache as\n\t *  necessary, inserting a new cache entry if none exists.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string %p, char_offset=%ld, clen=%ld, blen=%ld\",\n\t                     (void *) h, (long) char_offset,\n\t                     (long) DUK_HSTRING_GET_CHARLEN(h),\n\t                     (long) DUK_HSTRING_GET_BYTELEN(h)));\n\n\theap = thr->heap;\n\tsce = NULL;\n\tuse_cache = (char_length > DUK_HEAP_STRINGCACHE_NOCACHE_LIMIT);\n\n\tif (use_cache) {\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t\tDUK_DDD(DUK_DDDPRINT(\"stringcache before char2byte (using cache):\"));\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tduk_strcache_entry *c = heap->strcache + i;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"  [%ld] -> h=%p, cidx=%ld, bidx=%ld\",\n\t\t\t                     (long) i, (void *) c->h, (long) c->cidx, (long) c->bidx));\n\t\t}\n#endif\n\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tduk_strcache_entry *c = heap->strcache + i;\n\n\t\t\tif (c->h == h) {\n\t\t\t\tsce = c;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t/*\n\t *  Scan from shortest distance:\n\t *    - start of string\n\t *    - end of string\n\t *    - cache entry (if exists)\n\t */\n\n\tDUK_ASSERT(DUK_HSTRING_GET_CHARLEN(h) >= char_offset);\n\tdist_start = char_offset;\n\tdist_end = char_length - char_offset;\n\tdist_sce = 0; DUK_UNREF(dist_sce);  /* initialize for debug prints, needed if sce==NULL */\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tp_end = (const duk_uint8_t *) (p_start + DUK_HSTRING_GET_BYTELEN(h));\n\tp_found = NULL;\n\n\tif (sce) {\n\t\tif (char_offset >= sce->cidx) {\n\t\t\tdist_sce = char_offset - sce->cidx;\n\t\t\tif ((dist_sce <= dist_start) && (dist_sce <= dist_end)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t\t\t                     \"scan forwards from sce\",\n\t\t\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\t\t\tp_found = duk__scan_forwards(p_start + sce->bidx,\n\t\t\t\t                             p_end,\n\t\t\t\t                             dist_sce);\n\t\t\t\tgoto scan_done;\n\t\t\t}\n\t\t} else {\n\t\t\tdist_sce = sce->cidx - char_offset;\n\t\t\tif ((dist_sce <= dist_start) && (dist_sce <= dist_end)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t\t\t                     \"scan backwards from sce\",\n\t\t\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\t\t\tp_found = duk__scan_backwards(p_start + sce->bidx,\n\t\t\t\t                              p_start,\n\t\t\t\t                              dist_sce);\n\t\t\t\tgoto scan_done;\n\t\t\t}\n\t\t}\n\t}\n\n\t/* no sce, or sce scan not best */\n\n\tif (dist_start <= dist_end) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t                     \"scan forwards from string start\",\n\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\tp_found = duk__scan_forwards(p_start,\n\t\t                             p_end,\n\t\t                             dist_start);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t                     \"scan backwards from string end\",\n\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\tp_found = duk__scan_backwards(p_end,\n\t\t                              p_start,\n\t\t                              dist_end);\n\t}\n\n scan_done:\n\n\tif (DUK_UNLIKELY(p_found == NULL)) {\n\t\t/* Scan error: this shouldn't normally happen; it could happen if\n\t\t * string is not valid UTF-8 data, and clen/blen are not consistent\n\t\t * with the scanning algorithm.\n\t\t */\n\t\tgoto scan_error;\n\t}\n\n\tDUK_ASSERT(p_found >= p_start);\n\tDUK_ASSERT(p_found <= p_end);  /* may be equal */\n\tbyte_offset = (duk_uint32_t) (p_found - p_start);\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> string %p, cidx %ld -> bidx %ld\",\n\t                     (void *) h, (long) char_offset, (long) byte_offset));\n\n\t/*\n\t *  Update cache entry (allocating if necessary), and move the\n\t *  cache entry to the first place (in an \"LRU\" policy).\n\t */\n\n\tif (use_cache) {\n\t\t/* update entry, allocating if necessary */\n\t\tif (!sce) {\n\t\t\tsce = heap->strcache + DUK_HEAP_STRCACHE_SIZE - 1;  /* take last entry */\n\t\t\tsce->h = h;\n\t\t}\n\t\tDUK_ASSERT(sce != NULL);\n\t\tsce->bidx = (duk_uint32_t) (p_found - p_start);\n\t\tsce->cidx = (duk_uint32_t) char_offset;\n\n\t\t/* LRU: move our entry to first */\n\t\tif (sce > &heap->strcache[0]) {\n\t\t\t/*\n\t\t\t *   A                  C\n\t\t\t *   B                  A\n\t\t\t *   C <- sce    ==>    B\n\t\t\t *   D                  D\n\t\t\t */\n\t\t\tduk_strcache_entry tmp;\n\n\t\t\ttmp = *sce;\n\t\t\tduk_memmove((void *) (&heap->strcache[1]),\n\t\t\t            (const void *) (&heap->strcache[0]),\n\t\t\t            (size_t) (((char *) sce) - ((char *) &heap->strcache[0])));\n\t\t\theap->strcache[0] = tmp;\n\n\t\t\t/* 'sce' points to the wrong entry here, but is no longer used */\n\t\t}\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t\tDUK_DDD(DUK_DDDPRINT(\"stringcache after char2byte (using cache):\"));\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tduk_strcache_entry *c = heap->strcache + i;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"  [%ld] -> h=%p, cidx=%ld, bidx=%ld\",\n\t\t\t                     (long) i, (void *) c->h, (long) c->cidx, (long) c->bidx));\n\t\t}\n#endif\n\t}\n\n\treturn byte_offset;\n\n scan_error:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n#line 1 \"duk_heap_stringtable.c\"\n/*\n *  Heap string table handling, string interning.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Resize checks not needed if minsize == maxsize, typical for low memory\n * targets.\n */\n#define DUK__STRTAB_RESIZE_CHECK\n#if (DUK_USE_STRTAB_MINSIZE == DUK_USE_STRTAB_MAXSIZE)\n#undef DUK__STRTAB_RESIZE_CHECK\n#endif\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n#define DUK__HEAPPTR_ENC16(heap,ptr)    DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (ptr))\n#define DUK__HEAPPTR_DEC16(heap,val)    DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (val))\n#define DUK__GET_STRTABLE(heap)         ((heap)->strtable16)\n#else\n#define DUK__HEAPPTR_ENC16(heap,ptr)    (ptr)\n#define DUK__HEAPPTR_DEC16(heap,val)    (val)\n#define DUK__GET_STRTABLE(heap)         ((heap)->strtable)\n#endif\n\n#define DUK__STRTAB_U32_MAX_STRLEN      10               /* 4'294'967'295 */\n\n/*\n *  Debug dump stringtable.\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_INTERNAL void duk_heap_strtable_dump(duk_heap *heap) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable;\n#else\n\tduk_hstring **strtable;\n#endif\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_size_t count_total = 0;\n\tduk_size_t count_chain;\n\tduk_size_t count_chain_min = DUK_SIZE_MAX;\n\tduk_size_t count_chain_max = 0;\n\tduk_size_t count_len[8];  /* chain lengths from 0 to 7 */\n\n\tif (heap == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"string table, heap=NULL\"));\n\t\treturn;\n\t}\n\n\tstrtable = DUK__GET_STRTABLE(heap);\n\tif (strtable == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"string table, strtab=NULL\"));\n\t\treturn;\n\t}\n\n\tduk_memzero((void *) count_len, sizeof(count_len));\n\tfor (i = 0; i < heap->st_size; i++) {\n\t\th = DUK__HEAPPTR_DEC16(heap, strtable[i]);\n\t\tcount_chain = 0;\n\t\twhile (h != NULL) {\n\t\t\tcount_chain++;\n\t\t\th = h->hdr.h_next;\n\t\t}\n\t\tif (count_chain < sizeof(count_len) / sizeof(duk_size_t)) {\n\t\t\tcount_len[count_chain]++;\n\t\t}\n\t\tcount_chain_max = (count_chain > count_chain_max ? count_chain : count_chain_max);\n\t\tcount_chain_min = (count_chain < count_chain_min ? count_chain : count_chain_min);\n\t\tcount_total += count_chain;\n\t}\n\n\tDUK_D(DUK_DPRINT(\"string table, strtab=%p, count=%lu, chain min=%lu max=%lu avg=%lf: \"\n\t                 \"counts: %lu %lu %lu %lu %lu %lu %lu %lu ...\",\n\t                 (void *) heap->strtable, (unsigned long) count_total,\n\t                 (unsigned long) count_chain_min, (unsigned long) count_chain_max,\n\t                 (double) count_total / (double) heap->st_size,\n\t                 (unsigned long) count_len[0], (unsigned long) count_len[1],\n\t                 (unsigned long) count_len[2], (unsigned long) count_len[3],\n\t                 (unsigned long) count_len[4], (unsigned long) count_len[5],\n\t                 (unsigned long) count_len[6], (unsigned long) count_len[7]));\n}\n#endif  /* DUK_USE_DEBUG */\n\n/*\n *  Assertion helper to ensure strtable is populated correctly.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_LOCAL void duk__strtable_assert_checks(duk_heap *heap) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable;\n#else\n\tduk_hstring **strtable;\n#endif\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_size_t count = 0;\n\n\tDUK_ASSERT(heap != NULL);\n\n\tstrtable = DUK__GET_STRTABLE(heap);\n\tif (strtable != NULL) {\n\t\tDUK_ASSERT(heap->st_size != 0);\n\t\tDUK_ASSERT(heap->st_mask == heap->st_size - 1);\n\n\t\tfor (i = 0; i < heap->st_size; i++) {\n\t\t\th = DUK__HEAPPTR_DEC16(heap, strtable[i]);\n\t\t\twhile (h != NULL) {\n\t\t\t\tDUK_ASSERT((DUK_HSTRING_GET_HASH(h) & heap->st_mask) == i);\n\t\t\t\tcount++;\n\t\t\t\th = h->hdr.h_next;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_ASSERT(heap->st_size == 0);\n\t\tDUK_ASSERT(heap->st_mask == 0);\n\t}\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tDUK_ASSERT(count == (duk_size_t) heap->st_count);\n#endif\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\n/*\n *  Allocate and initialize a duk_hstring.\n *\n *  Returns a NULL if allocation or initialization fails for some reason.\n *\n *  The string won't be inserted into the string table and isn't tracked in\n *  any way (link pointers will be NULL).  The caller must place the string\n *  into the string table without any risk of a longjmp, otherwise the string\n *  is leaked.\n */\n\nDUK_LOCAL duk_hstring *duk__strtable_alloc_hstring(duk_heap *heap,\n                                                   const duk_uint8_t *str,\n                                                   duk_uint32_t blen,\n                                                   duk_uint32_t strhash,\n                                                   const duk_uint8_t *extdata) {\n\tduk_hstring *res;\n\tconst duk_uint8_t *data;\n#if !defined(DUK_USE_HSTRING_ARRIDX)\n\tduk_uarridx_t dummy;\n#endif\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_UNREF(extdata);\n\n#if defined(DUK_USE_STRLEN16)\n\t/* If blen <= 0xffffUL, clen is also guaranteed to be <= 0xffffUL. */\n\tif (blen > 0xffffUL) {\n\t\tDUK_D(DUK_DPRINT(\"16-bit string blen/clen active and blen over 16 bits, reject intern\"));\n\t\tgoto alloc_error;\n\t}\n#endif\n\n\t/* XXX: Memzeroing the allocated structure is not really necessary\n\t * because we could just initialize all fields explicitly (almost\n\t * all fields are initialized explicitly anyway).\n\t */\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK)\n\tif (extdata) {\n\t\tres = (duk_hstring *) DUK_ALLOC(heap, sizeof(duk_hstring_external));\n\t\tif (DUK_UNLIKELY(res == NULL)) {\n\t\t\tgoto alloc_error;\n\t\t}\n\t\tduk_memzero(res, sizeof(duk_hstring_external));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\tDUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr);\n#endif\n\t\tDUK_HEAPHDR_SET_TYPE_AND_FLAGS(&res->hdr, DUK_HTYPE_STRING, DUK_HSTRING_FLAG_EXTDATA);\n\n\t\tDUK_ASSERT(extdata[blen] == 0);  /* Application responsibility. */\n\t\tdata = extdata;\n\t\t((duk_hstring_external *) res)->extdata = extdata;\n\t} else\n#endif  /* DUK_USE_HSTRING_EXTDATA && DUK_USE_EXTSTR_INTERN_CHECK */\n\t{\n\t\tduk_uint8_t *data_tmp;\n\n\t\t/* NUL terminate for convenient C access */\n\t\tDUK_ASSERT(sizeof(duk_hstring) + blen + 1 > blen);  /* No wrap, limits ensure. */\n\t\tres = (duk_hstring *) DUK_ALLOC(heap, sizeof(duk_hstring) + blen + 1);\n\t\tif (DUK_UNLIKELY(res == NULL)) {\n\t\t\tgoto alloc_error;\n\t\t}\n\t\tduk_memzero(res, sizeof(duk_hstring));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\tDUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr);\n#endif\n\t\tDUK_HEAPHDR_SET_TYPE_AND_FLAGS(&res->hdr, DUK_HTYPE_STRING, 0);\n\n\t\tdata_tmp = (duk_uint8_t *) (res + 1);\n\t\tduk_memcpy(data_tmp, str, blen);\n\t\tdata_tmp[blen] = (duk_uint8_t) 0;\n\t\tdata = (const duk_uint8_t *) data_tmp;\n\t}\n\n\tDUK_HSTRING_SET_BYTELEN(res, blen);\n\tDUK_HSTRING_SET_HASH(res, strhash);\n\n\tDUK_ASSERT(!DUK_HSTRING_HAS_ARRIDX(res));\n#if defined(DUK_USE_HSTRING_ARRIDX)\n\tres->arridx = duk_js_to_arrayindex_string(data, blen);\n\tif (res->arridx != DUK_HSTRING_NO_ARRAY_INDEX) {\n#else\n\tdummy = duk_js_to_arrayindex_string(data, blen);\n\tif (dummy != DUK_HSTRING_NO_ARRAY_INDEX) {\n#endif\n\t\t/* Array index strings cannot be symbol strings,\n\t\t * and they're always pure ASCII so blen == clen.\n\t\t */\n\t\tDUK_HSTRING_SET_ARRIDX(res);\n\t\tDUK_HSTRING_SET_ASCII(res);\n\t\tDUK_ASSERT(duk_unicode_unvalidated_utf8_length(data, (duk_size_t) blen) == blen);\n\t} else {\n\t\t/* Because 'data' is NUL-terminated, we don't need a\n\t\t * blen > 0 check here.  For NUL (0x00) the symbol\n\t\t * checks will be false.\n\t\t */\n\t\tif (DUK_UNLIKELY(data[0] >= 0x80U)) {\n\t\t\tif (data[0] <= 0x81) {\n\t\t\t\tDUK_HSTRING_SET_SYMBOL(res);\n\t\t\t} else if (data[0] == 0x82U || data[0] == 0xffU) {\n\t\t\t\tDUK_HSTRING_SET_HIDDEN(res);\n\t\t\t\tDUK_HSTRING_SET_SYMBOL(res);\n\t\t\t}\n\t\t}\n\n\t\t/* Using an explicit 'ASCII' flag has larger footprint (one call site\n\t\t * only) but is quite useful for the case when there's no explicit\n\t\t * 'clen' in duk_hstring.\n\t\t *\n\t\t * The flag is set lazily for RAM strings.\n\t\t */\n\t\tDUK_ASSERT(!DUK_HSTRING_HAS_ASCII(res));\n\n#if defined(DUK_USE_HSTRING_LAZY_CLEN)\n\t\t/* Charlen initialized to 0, updated on-the-fly. */\n#else\n\t\tduk_hstring_init_charlen(res);  /* Also sets ASCII flag. */\n#endif\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"interned string, hash=0x%08lx, blen=%ld, has_arridx=%ld, has_extdata=%ld\",\n\t                     (unsigned long) DUK_HSTRING_GET_HASH(res),\n\t                     (long) DUK_HSTRING_GET_BYTELEN(res),\n\t                     (long) (DUK_HSTRING_HAS_ARRIDX(res) ? 1 : 0),\n\t                     (long) (DUK_HSTRING_HAS_EXTDATA(res) ? 1 : 0)));\n\n\tDUK_ASSERT(res != NULL);\n\treturn res;\n\n alloc_error:\n\treturn NULL;\n}\n\n/*\n *  Grow strtable allocation in-place.\n */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL void duk__strtable_grow_inplace(duk_heap *heap) {\n\tduk_uint32_t new_st_size;\n\tduk_uint32_t old_st_size;\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_hstring *next;\n\tduk_hstring *prev;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *new_ptr;\n\tduk_uint16_t *new_ptr_high;\n#else\n\tduk_hstring **new_ptr;\n\tduk_hstring **new_ptr_high;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"grow in-place: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size * 2));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->st_resizing == 1);\n\tDUK_ASSERT(heap->st_size >= 2);\n\tDUK_ASSERT((heap->st_size & (heap->st_size - 1)) == 0);  /* 2^N */\n\tDUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL);\n\n\tDUK_STATS_INC(heap, stats_strtab_resize_grow);\n\n\tnew_st_size = heap->st_size << 1U;\n\tDUK_ASSERT(new_st_size > heap->st_size);  /* No overflow. */\n\n\t/* Reallocate the strtable first and then work in-place to rehash\n\t * strings.  We don't need an indirect allocation here: even if GC\n\t * is triggered to satisfy the allocation, recursive strtable resize\n\t * is prevented by flags.  This is also why we don't need to use\n\t * DUK_REALLOC_INDIRECT().\n\t */\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tnew_ptr = (duk_uint16_t *) DUK_REALLOC(heap, heap->strtable16, sizeof(duk_uint16_t) * new_st_size);\n#else\n\tnew_ptr = (duk_hstring **) DUK_REALLOC(heap, heap->strtable, sizeof(duk_hstring *) * new_st_size);\n#endif\n\tif (DUK_UNLIKELY(new_ptr == NULL)) {\n\t\t/* If realloc fails we can continue normally: the string table\n\t\t * won't \"fill up\" although chains will gradually get longer.\n\t\t * When string insertions continue, we'll quite soon try again\n\t\t * with no special handling.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"string table grow failed, ignoring\"));\n\t\treturn;\n\t}\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\theap->strtable16 = new_ptr;\n#else\n\theap->strtable = new_ptr;\n#endif\n\n\t/* Rehash a single bucket into two separate ones.  When we grow\n\t * by x2 the highest 'new' bit determines whether a string remains\n\t * in its old position (bit is 0) or goes to a new one (bit is 1).\n\t */\n\n\told_st_size = heap->st_size;\n\tnew_ptr_high = new_ptr + old_st_size;\n\tfor (i = 0; i < old_st_size; i++) {\n\t\tduk_hstring *new_root;\n\t\tduk_hstring *new_root_high;\n\n\t\th = DUK__HEAPPTR_DEC16(heap, new_ptr[i]);\n\t\tnew_root = h;\n\t\tnew_root_high = NULL;\n\n\t\tprev = NULL;\n\t\twhile (h != NULL) {\n\t\t\tduk_uint32_t mask;\n\n\t\t\tDUK_ASSERT((DUK_HSTRING_GET_HASH(h) & heap->st_mask) == i);\n\t\t\tnext = h->hdr.h_next;\n\n\t\t\t/* Example: if previous size was 256, previous mask is 0xFF\n\t\t\t * and size is 0x100 which corresponds to the new bit that\n\t\t\t * comes into play.\n\t\t\t */\n\t\t\tDUK_ASSERT(heap->st_mask == old_st_size - 1);\n\t\t\tmask = old_st_size;\n\t\t\tif (DUK_HSTRING_GET_HASH(h) & mask) {\n\t\t\t\tif (prev != NULL) {\n\t\t\t\t\tprev->hdr.h_next = h->hdr.h_next;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(h == new_root);\n\t\t\t\t\tnew_root = h->hdr.h_next;\n\t\t\t\t}\n\n\t\t\t\th->hdr.h_next = new_root_high;\n\t\t\t\tnew_root_high = h;\n\t\t\t} else {\n\t\t\t\tprev = h;\n\t\t\t}\n\t\t\th = next;\n\t\t}\n\n\t\tnew_ptr[i] = DUK__HEAPPTR_ENC16(heap, new_root);\n\t\tnew_ptr_high[i] = DUK__HEAPPTR_ENC16(heap, new_root_high);\n\t}\n\n\theap->st_size = new_st_size;\n\theap->st_mask = new_st_size - 1;\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__strtable_assert_checks(heap);\n#endif\n}\n#endif  /* DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Shrink strtable allocation in-place.\n */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL void duk__strtable_shrink_inplace(duk_heap *heap) {\n\tduk_uint32_t new_st_size;\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_hstring *other;\n\tduk_hstring *root;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *old_ptr;\n\tduk_uint16_t *old_ptr_high;\n\tduk_uint16_t *new_ptr;\n#else\n\tduk_hstring **old_ptr;\n\tduk_hstring **old_ptr_high;\n\tduk_hstring **new_ptr;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"shrink in-place: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size / 2));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->st_resizing == 1);\n\tDUK_ASSERT(heap->st_size >= 2);\n\tDUK_ASSERT((heap->st_size & (heap->st_size - 1)) == 0);  /* 2^N */\n\tDUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL);\n\n\tDUK_STATS_INC(heap, stats_strtab_resize_shrink);\n\n\tnew_st_size = heap->st_size >> 1U;\n\n\t/* Combine two buckets into a single one.  When we shrink, one hash\n\t * bit (highest) disappears.\n\t */\n\told_ptr = DUK__GET_STRTABLE(heap);\n\told_ptr_high = old_ptr + new_st_size;\n\tfor (i = 0; i < new_st_size; i++) {\n\t\th = DUK__HEAPPTR_DEC16(heap, old_ptr[i]);\n\t\tother = DUK__HEAPPTR_DEC16(heap, old_ptr_high[i]);\n\n\t\tif (h == NULL) {\n\t\t\t/* First chain is empty, so use second one as is. */\n\t\t\troot = other;\n\t\t} else {\n\t\t\t/* Find end of first chain, and link in the second. */\n\t\t\troot = h;\n\t\t\twhile (h->hdr.h_next != NULL) {\n\t\t\t\th = h->hdr.h_next;\n\t\t\t}\n\t\t\th->hdr.h_next = other;\n\t\t}\n\n\t\told_ptr[i] = DUK__HEAPPTR_ENC16(heap, root);\n\t}\n\n\theap->st_size = new_st_size;\n\theap->st_mask = new_st_size - 1;\n\n\t/* The strtable is now consistent and we can realloc safely.  Even\n\t * if side effects cause string interning or removal the strtable\n\t * updates are safe.  Recursive resize has been prevented by caller.\n\t * This is also why we don't need to use DUK_REALLOC_INDIRECT().\n\t *\n\t * We assume a realloc() to a smaller size is guaranteed to succeed.\n\t * It would be relatively straightforward to handle the error by\n\t * essentially performing a \"grow\" step to recover.\n\t */\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tnew_ptr = (duk_uint16_t *) DUK_REALLOC(heap, heap->strtable16, sizeof(duk_uint16_t) * new_st_size);\n\tDUK_ASSERT(new_ptr != NULL);\n\theap->strtable16 = new_ptr;\n#else\n\tnew_ptr = (duk_hstring **) DUK_REALLOC(heap, heap->strtable, sizeof(duk_hstring *) * new_st_size);\n\tDUK_ASSERT(new_ptr != NULL);\n\theap->strtable = new_ptr;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__strtable_assert_checks(heap);\n#endif\n}\n#endif  /* DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Grow/shrink check.\n */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL DUK_COLD DUK_NOINLINE void duk__strtable_resize_check(duk_heap *heap) {\n\tduk_uint32_t load_factor;  /* fixed point */\n\n\tDUK_ASSERT(heap != NULL);\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tDUK_ASSERT(heap->strtable16 != NULL);\n#else\n\tDUK_ASSERT(heap->strtable != NULL);\n#endif\n\n\tDUK_STATS_INC(heap, stats_strtab_resize_check);\n\n\t/* Prevent recursive resizing. */\n\tif (DUK_UNLIKELY(heap->st_resizing != 0U)) {\n\t\tDUK_D(DUK_DPRINT(\"prevent recursive strtable resize\"));\n\t\treturn;\n\t}\n\n\theap->st_resizing = 1;\n\n\tDUK_ASSERT(heap->st_size >= 16U);\n\tDUK_ASSERT((heap->st_size >> 4U) >= 1);\n\tload_factor = heap->st_count / (heap->st_size >> 4U);\n\n\tDUK_DD(DUK_DDPRINT(\"resize check string table: size=%lu, count=%lu, load_factor=%lu (fixed point .4; float %lf)\",\n\t                   (unsigned long) heap->st_size, (unsigned long) heap->st_count,\n\t                   (unsigned long) load_factor,\n\t                   (double) heap->st_count / (double) heap->st_size));\n\n\tif (load_factor >= DUK_USE_STRTAB_GROW_LIMIT) {\n\t\tif (heap->st_size >= DUK_USE_STRTAB_MAXSIZE) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"want to grow strtable (based on load factor) but already maximum size\"));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"grow string table: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size * 2));\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk_heap_strtable_dump(heap);\n#endif\n\t\t\tduk__strtable_grow_inplace(heap);\n\t\t}\n\t} else if (load_factor <= DUK_USE_STRTAB_SHRINK_LIMIT) {\n\t\tif (heap->st_size <= DUK_USE_STRTAB_MINSIZE) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"want to shrink strtable (based on load factor) but already minimum size\"));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"shrink string table: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size / 2));\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk_heap_strtable_dump(heap);\n#endif\n\t\t\tduk__strtable_shrink_inplace(heap);\n\t\t}\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"no need for strtable resize\"));\n\t}\n\n\theap->st_resizing = 0;\n}\n#endif  /* DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Torture grow/shrink: unconditionally grow and shrink back.\n */\n\n#if defined(DUK_USE_STRTAB_TORTURE) && defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL void duk__strtable_resize_torture(duk_heap *heap) {\n\tduk_uint32_t old_st_size;\n\n\tDUK_ASSERT(heap != NULL);\n\n\told_st_size = heap->st_size;\n\tif (old_st_size >= DUK_USE_STRTAB_MAXSIZE) {\n\t\treturn;\n\t}\n\n\theap->st_resizing = 1;\n\tduk__strtable_grow_inplace(heap);\n\tif (heap->st_size > old_st_size) {\n\t\tduk__strtable_shrink_inplace(heap);\n\t}\n\theap->st_resizing = 0;\n}\n#endif  /* DUK_USE_STRTAB_TORTURE && DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Raw intern; string already checked not to be present.\n */\n\nDUK_LOCAL duk_hstring *duk__strtable_do_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen, duk_uint32_t strhash) {\n\tduk_hstring *res;\n\tconst duk_uint8_t *extdata;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *slot;\n#else\n\tduk_hstring **slot;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"do_intern: heap=%p, str=%p, blen=%lu, strhash=%lx, st_size=%lu, st_count=%lu, load=%lf\",\n\t                     (void *) heap, (const void *) str, (unsigned long) blen, (unsigned long) strhash,\n\t                     (unsigned long) heap->st_size, (unsigned long) heap->st_count,\n\t                     (double) heap->st_count / (double) heap->st_size));\n\n\tDUK_ASSERT(heap != NULL);\n\n\t/* Prevent any side effects on the string table and the caller provided\n\t * str/blen arguments while interning is in progress.  For example, if\n\t * the caller provided str/blen from a dynamic buffer, a finalizer\n\t * might resize or modify that dynamic buffer, invalidating the call\n\t * arguments.\n\t *\n\t * While finalizers must be prevented, mark-and-sweep itself is fine.\n\t * Recursive string table resize is prevented explicitly here.\n\t */\n\n\theap->pf_prevent_count++;\n\tDUK_ASSERT(heap->pf_prevent_count != 0);  /* Wrap. */\n\n#if defined(DUK_USE_STRTAB_TORTURE) && defined(DUK__STRTAB_RESIZE_CHECK)\n\tduk__strtable_resize_torture(heap);\n#endif\n\n\t/* String table grow/shrink check.  Because of chaining (and no\n\t * accumulation issues as with hash probe chains and DELETED\n\t * markers) there's never a mandatory need to resize right now.\n\t * Check for the resize only periodically, based on st_count\n\t * bit pattern.  Because string table removal doesn't do a shrink\n\t * check, we do that also here.\n\t *\n\t * Do the resize and possible grow/shrink before the new duk_hstring\n\t * has been allocated.  Otherwise we may trigger a GC when the result\n\t * duk_hstring is not yet strongly referenced.\n\t */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tif (DUK_UNLIKELY((heap->st_count & DUK_USE_STRTAB_RESIZE_CHECK_MASK) == 0)) {\n\t\tduk__strtable_resize_check(heap);\n\t}\n#endif\n\n\t/* External string check (low memory optimization). */\n\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK)\n\textdata = (const duk_uint8_t *) DUK_USE_EXTSTR_INTERN_CHECK(heap->heap_udata, (void *) DUK_LOSE_CONST(str), (duk_size_t) blen);\n#else\n\textdata = (const duk_uint8_t *) NULL;\n#endif\n\n\t/* Allocate and initialize string, not yet linked.  This may cause a\n\t * GC which may cause other strings to be interned and inserted into\n\t * the string table before we insert our string.  Finalizer execution\n\t * is disabled intentionally to avoid a finalizer from e.g. resizing\n\t * a buffer used as a data area for 'str'.\n\t */\n\n\tres = duk__strtable_alloc_hstring(heap, str, blen, strhash, extdata);\n\n\t/* Allow side effects again: GC must be avoided until duk_hstring\n\t * result (if successful) has been INCREF'd.\n\t */\n\tDUK_ASSERT(heap->pf_prevent_count > 0);\n\theap->pf_prevent_count--;\n\n\t/* Alloc error handling. */\n\n\tif (DUK_UNLIKELY(res == NULL)) {\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK)\n\t\tif (extdata != NULL) {\n\t\t\tDUK_USE_EXTSTR_FREE(heap->heap_udata, (const void *) extdata);\n\t\t}\n#endif\n\t\treturn NULL;\n\t}\n\n\t/* Insert into string table. */\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tslot = heap->strtable16 + (strhash & heap->st_mask);\n#else\n\tslot = heap->strtable + (strhash & heap->st_mask);\n#endif\n\tDUK_ASSERT(res->hdr.h_next == NULL);  /* This is the case now, but unnecessary zeroing/NULLing. */\n\tres->hdr.h_next = DUK__HEAPPTR_DEC16(heap, *slot);\n\t*slot = DUK__HEAPPTR_ENC16(heap, res);\n\n\t/* Update string count only for successful inserts. */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\theap->st_count++;\n#endif\n\n\t/* The duk_hstring is in the string table but is not yet strongly\n\t * reachable.  Calling code MUST NOT make any allocations or other\n\t * side effects before the duk_hstring has been INCREF'd and made\n\t * reachable.\n\t */\n\n\treturn res;\n}\n\n/*\n *  Intern a string from str/blen, returning either an existing duk_hstring\n *  or adding a new one into the string table.  The input string does -not-\n *  need to be NUL terminated.\n *\n *  The input 'str' argument may point to a Duktape managed data area such as\n *  the data area of a dynamic buffer.  It's crucial to avoid any side effects\n *  that might affect the data area (e.g. resize the dynamic buffer, or write\n *  to the buffer) before the string is fully interned.\n */\n\n#if defined(DUK_USE_ROM_STRINGS)\nDUK_LOCAL duk_hstring *duk__strtab_romstring_lookup(duk_heap *heap, const duk_uint8_t *str, duk_size_t blen, duk_uint32_t strhash) {\n\tduk_size_t lookup_hash;\n\tduk_hstring *curr;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_UNREF(heap);\n\n\tlookup_hash = (blen << 4);\n\tif (blen > 0) {\n\t\tlookup_hash += str[0];\n\t}\n\tlookup_hash &= 0xff;\n\n\tcurr = (duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_lookup[lookup_hash]);\n\twhile (curr != NULL) {\n\t\t/* Unsafe memcmp() because for zero blen, str may be NULL. */\n\t\tif (strhash == DUK_HSTRING_GET_HASH(curr) &&\n\t\t    blen == DUK_HSTRING_GET_BYTELEN(curr) &&\n\t\t    duk_memcmp_unsafe((const void *) str, (const void *) DUK_HSTRING_GET_DATA(curr), blen) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"intern check: rom string: %!O, computed hash 0x%08lx, rom hash 0x%08lx\",\n\t\t\t                     curr, (unsigned long) strhash, (unsigned long) DUK_HSTRING_GET_HASH(curr)));\n\t\t\treturn curr;\n\t\t}\n\t\tcurr = curr->hdr.h_next;\n\t}\n\n\treturn NULL;\n}\n#endif  /* DUK_USE_ROM_STRINGS */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uint32_t strhash;\n\tduk_hstring *h;\n\n\tDUK_DDD(DUK_DDDPRINT(\"intern check: heap=%p, str=%p, blen=%lu\", (void *) heap, (const void *) str, (unsigned long) blen));\n\n\t/* Preliminaries. */\n\n\t/* XXX: maybe just require 'str != NULL' even for zero size? */\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(blen == 0 || str != NULL);\n\tDUK_ASSERT(blen <= DUK_HSTRING_MAX_BYTELEN);  /* Caller is responsible for ensuring this. */\n\tstrhash = duk_heap_hashstring(heap, str, (duk_size_t) blen);\n\n\t/* String table lookup. */\n\n\tDUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL);\n\tDUK_ASSERT(heap->st_size > 0);\n\tDUK_ASSERT(heap->st_size == heap->st_mask + 1);\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\th = DUK__HEAPPTR_DEC16(heap, heap->strtable16[strhash & heap->st_mask]);\n#else\n\th = heap->strtable[strhash & heap->st_mask];\n#endif\n\twhile (h != NULL) {\n\t\tif (DUK_HSTRING_GET_HASH(h) == strhash &&\n\t\t    DUK_HSTRING_GET_BYTELEN(h) == blen &&\n\t\t    duk_memcmp_unsafe((const void *) str, (const void *) DUK_HSTRING_GET_DATA(h), (size_t) blen) == 0) {\n\t\t\t/* Found existing entry. */\n\t\t\tDUK_STATS_INC(heap, stats_strtab_intern_hit);\n\t\t\treturn h;\n\t\t}\n\t\th = h->hdr.h_next;\n\t}\n\n\t/* ROM table lookup.  Because this lookup is slower, do it only after\n\t * RAM lookup.  This works because no ROM string is ever interned into\n\t * the RAM string table.\n\t */\n\n#if defined(DUK_USE_ROM_STRINGS)\n\th = duk__strtab_romstring_lookup(heap, str, blen, strhash);\n\tif (h != NULL) {\n\t\tDUK_STATS_INC(heap, stats_strtab_intern_hit);\n\t\treturn h;\n\t}\n#endif\n\n\t/* Not found in string table; insert. */\n\n\tDUK_STATS_INC(heap, stats_strtab_intern_miss);\n\th = duk__strtable_do_intern(heap, str, blen, strhash);\n\treturn h;  /* may be NULL */\n}\n\n/*\n *  Intern a string from u32.\n */\n\n/* XXX: Could arrange some special handling because we know that the result\n * will have an arridx flag and an ASCII flag, won't need a clen check, etc.\n */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_u32(duk_heap *heap, duk_uint32_t val) {\n\tduk_uint8_t buf[DUK__STRTAB_U32_MAX_STRLEN];\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT(heap != NULL);\n\n\t/* This is smaller and faster than a %lu sprintf. */\n\tp = buf + sizeof(buf);\n\tdo {\n\t\tp--;\n\t\t*p = duk_lc_digits[val % 10];\n\t\tval = val / 10;\n\t} while (val != 0);  /* For val == 0, emit exactly one '0'. */\n\tDUK_ASSERT(p >= buf);\n\n\treturn duk_heap_strtable_intern(heap, (const duk_uint8_t *) p, (duk_uint32_t) ((buf + sizeof(buf)) - p));\n}\n\n/*\n *  Checked convenience variants.\n *\n *  XXX: Because the main use case is for the checked variants, make them the\n *  main functionality and provide a safe variant separately (it is only needed\n *  during heap init).  The problem with that is that longjmp state and error\n *  creation must already be possible to throw.\n */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_hstring *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(blen == 0 || str != NULL);\n\n\tres = duk_heap_strtable_intern(thr->heap, str, blen);\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn res;\n}\n\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_LOCAL duk_uint_t duk__strtable_litcache_key(const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uintptr_t key;\n\n\tDUK_ASSERT(DUK_USE_LITCACHE_SIZE > 0);\n\tDUK_ASSERT(DUK_IS_POWER_OF_TWO((duk_uint_t) DUK_USE_LITCACHE_SIZE));\n\n\tkey = (duk_uintptr_t) blen ^ (duk_uintptr_t) str;\n\tkey &= (duk_uintptr_t) (DUK_USE_LITCACHE_SIZE - 1);  /* Assumes size is power of 2. */\n\t/* Due to masking, cast is in 32-bit range. */\n\tDUK_ASSERT(key <= DUK_UINT_MAX);\n\treturn (duk_uint_t) key;\n}\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_literal_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uint_t key;\n\tduk_litcache_entry *ent;\n\tduk_hstring *h;\n\n\t/* Fast path check: literal exists in literal cache. */\n\tkey = duk__strtable_litcache_key(str, blen);\n\tent = thr->heap->litcache + key;\n\tif (ent->addr == str) {\n\t\tDUK_DD(DUK_DDPRINT(\"intern check for cached, pinned literal: str=%p, blen=%ld -> duk_hstring %!O\",\n\t\t                   (const void *) str, (long) blen, (duk_heaphdr *) ent->h));\n\t\tDUK_ASSERT(ent->h != NULL);\n\t\tDUK_ASSERT(DUK_HSTRING_HAS_PINNED_LITERAL(ent->h));\n\t\tDUK_STATS_INC(thr->heap, stats_strtab_litcache_hit);\n\t\treturn ent->h;\n\t}\n\n\t/* Intern and update (overwrite) cache entry. */\n\th = duk_heap_strtable_intern_checked(thr, str, blen);\n\tent->addr = str;\n\tent->h = h;\n\tDUK_STATS_INC(thr->heap, stats_strtab_litcache_miss);\n\n\t/* Pin the duk_hstring until the next mark-and-sweep.  This means\n\t * litcache entries don't need to be invalidated until the next\n\t * mark-and-sweep as their target duk_hstring is not freed before\n\t * the mark-and-sweep happens.  The pin remains even if the literal\n\t * cache entry is overwritten, and is still useful to avoid string\n\t * table traffic.\n\t */\n\tif (!DUK_HSTRING_HAS_PINNED_LITERAL(h)) {\n\t\tDUK_DD(DUK_DDPRINT(\"pin duk_hstring because it is a literal: %!O\", (duk_heaphdr *) h));\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h));\n\t\tDUK_HSTRING_INCREF(thr, h);\n\t\tDUK_HSTRING_SET_PINNED_LITERAL(h);\n\t\tDUK_STATS_INC(thr->heap, stats_strtab_litcache_pin);\n\t}\n\n\treturn h;\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_u32_checked(duk_hthread *thr, duk_uint32_t val) {\n\tduk_hstring *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tres = duk_heap_strtable_intern_u32(thr->heap, val);\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn res;\n}\n\n/*\n *  Remove (unlink) a string from the string table.\n *\n *  Just unlinks the duk_hstring, leaving link pointers as garbage.\n *  Caller must free the string itself.\n */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n/* Unlink without a 'prev' pointer. */\nDUK_INTERNAL void duk_heap_strtable_unlink(duk_heap *heap, duk_hstring *h) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *slot;\n#else\n\tduk_hstring **slot;\n#endif\n\tduk_hstring *other;\n\tduk_hstring *prev;\n\n\tDUK_DDD(DUK_DDDPRINT(\"remove: heap=%p, h=%p, blen=%lu, strhash=%lx\",\n\t                     (void *) heap, (void *) h,\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_BYTELEN(h) : 0),\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_HASH(h) : 0)));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tDUK_ASSERT(heap->st_count > 0);\n\theap->st_count--;\n#endif\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tslot = heap->strtable16 + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#else\n\tslot = heap->strtable + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#endif\n\tother = DUK__HEAPPTR_DEC16(heap, *slot);\n\tDUK_ASSERT(other != NULL);  /* At least argument string is in the chain. */\n\n\tprev = NULL;\n\twhile (other != h) {\n\t\tprev = other;\n\t\tother = other->hdr.h_next;\n\t\tDUK_ASSERT(other != NULL);  /* We'll eventually find 'h'. */\n\t}\n\tif (prev != NULL) {\n\t\t/* Middle of list. */\n\t\tprev->hdr.h_next = h->hdr.h_next;\n\t} else {\n\t\t/* Head of list. */\n\t\t*slot = DUK__HEAPPTR_ENC16(heap, h->hdr.h_next);\n\t}\n\n\t/* There's no resize check on a string free.  The next string\n\t * intern will do one.\n\t */\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/* Unlink with a 'prev' pointer. */\nDUK_INTERNAL void duk_heap_strtable_unlink_prev(duk_heap *heap, duk_hstring *h, duk_hstring *prev) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *slot;\n#else\n\tduk_hstring **slot;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"remove: heap=%p, prev=%p, h=%p, blen=%lu, strhash=%lx\",\n\t                     (void *) heap, (void *) prev, (void *) h,\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_BYTELEN(h) : 0),\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_HASH(h) : 0)));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(prev == NULL || prev->hdr.h_next == h);\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tDUK_ASSERT(heap->st_count > 0);\n\theap->st_count--;\n#endif\n\n\tif (prev != NULL) {\n\t\t/* Middle of list. */\n\t\tprev->hdr.h_next = h->hdr.h_next;\n\t} else {\n\t\t/* Head of list. */\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\tslot = heap->strtable16 + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#else\n\t\tslot = heap->strtable + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#endif\n\t\tDUK_ASSERT(DUK__HEAPPTR_DEC16(heap, *slot) == h);\n\t\t*slot = DUK__HEAPPTR_ENC16(heap, h->hdr.h_next);\n\t}\n}\n\n/*\n *  Force string table resize check in mark-and-sweep.\n */\n\nDUK_INTERNAL void duk_heap_strtable_force_resize(duk_heap *heap) {\n\t/* Does only one grow/shrink step if needed.  The heap->st_resizing\n\t * flag protects against recursive resizing.\n\t */\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_UNREF(heap);\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tif (heap->strtable16 != NULL) {\n#else\n\tif (heap->strtable != NULL) {\n#endif\n\t\tduk__strtable_resize_check(heap);\n\t}\n#endif\n}\n\n/*\n *  Free strings in the string table and the string table itself.\n */\n\nDUK_INTERNAL void duk_heap_strtable_free(duk_heap *heap) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable;\n\tduk_uint16_t *st;\n#else\n\tduk_hstring **strtable;\n\tduk_hstring **st;\n#endif\n\tduk_hstring *h;\n\n\tDUK_ASSERT(heap != NULL);\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__strtable_assert_checks(heap);\n#endif\n\n\t/* Strtable can be NULL if heap init fails.  However, in that case\n\t * heap->st_size is 0, so strtable == strtable_end and we skip the\n\t * loop without a special check.\n\t */\n\tstrtable = DUK__GET_STRTABLE(heap);\n\tst = strtable + heap->st_size;\n\tDUK_ASSERT(strtable != NULL || heap->st_size == 0);\n\n\twhile (strtable != st) {\n\t\t--st;\n\t\th = DUK__HEAPPTR_DEC16(heap, *st);\n\t\twhile (h) {\n\t\t\tduk_hstring *h_next;\n\t\t\th_next = h->hdr.h_next;\n\n\t\t\t/* Strings may have inner refs (extdata) in some cases. */\n\t\t\tduk_free_hstring(heap, h);\n\n\t\t\th = h_next;\n\t\t}\n\t}\n\n\tDUK_FREE(heap, strtable);\n}\n\n/* automatic undefs */\n#undef DUK__GET_STRTABLE\n#undef DUK__HEAPPTR_DEC16\n#undef DUK__HEAPPTR_ENC16\n#undef DUK__STRTAB_U32_MAX_STRLEN\n#line 1 \"duk_heaphdr_assert.c\"\n/*\n *  duk_heaphdr assertion helpers\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ASSERTIONS)\n\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\nDUK_INTERNAL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tif (h != NULL) {\n\t\tduk_heaphdr *h_prev, *h_next;\n\t\th_prev = DUK_HEAPHDR_GET_PREV(heap, h);\n\t\th_next = DUK_HEAPHDR_GET_NEXT(heap, h);\n\t\tDUK_ASSERT(h_prev == NULL || (DUK_HEAPHDR_GET_NEXT(heap, h_prev) == h));\n\t\tDUK_ASSERT(h_next == NULL || (DUK_HEAPHDR_GET_PREV(heap, h_next) == h));\n\t}\n}\n#else\nDUK_INTERNAL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tDUK_UNREF(h);\n}\n#endif\n\nDUK_INTERNAL void duk_heaphdr_assert_valid(duk_heaphdr *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n}\n\n/* Assert validity of a heaphdr, including all subclasses. */\nDUK_INTERNAL void duk_heaphdr_assert_valid_subclassed(duk_heaphdr *h) {\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h_obj = (duk_hobject *) h;\n\t\tDUK_HOBJECT_ASSERT_VALID(h_obj);\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tDUK_HCOMPFUNC_ASSERT_VALID((duk_hcompfunc *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h_obj)) {\n\t\t\tDUK_HNATFUNC_ASSERT_VALID((duk_hnatfunc *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_DECENV(h_obj)) {\n\t\t\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_OBJENV(h_obj)) {\n\t\t\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID((duk_hbufobj *) h_obj);\n#endif\n\t\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h_obj)) {\n\t\t\tDUK_HBOUNDFUNC_ASSERT_VALID((duk_hboundfunc *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_PROXY(h_obj)) {\n\t\t\tDUK_HPROXY_ASSERT_VALID((duk_hproxy *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_THREAD(h_obj)) {\n\t\t\tDUK_HTHREAD_ASSERT_VALID((duk_hthread *) h_obj);\n\t\t} else {\n\t\t\t/* Just a plain object. */\n\t\t\t;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h_str = (duk_hstring *) h;\n\t\tDUK_HSTRING_ASSERT_VALID(h_str);\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h_buf = (duk_hbuffer *) h;\n\t\tDUK_HBUFFER_ASSERT_VALID(h_buf);\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tDUK_ASSERT(0);\n\t}\n\t}\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n#line 1 \"duk_hobject_alloc.c\"\n/*\n *  Hobject allocation.\n *\n *  Provides primitive allocation functions for all object types (plain object,\n *  compiled function, native function, thread).  The object return is not yet\n *  in \"heap allocated\" list and has a refcount of zero, so caller must careful.\n */\n\n/* XXX: In most cases there's no need for plain allocation without pushing\n * to the value stack.  Maybe rework contract?\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Helpers.\n */\n\nDUK_LOCAL void duk__init_object_parts(duk_heap *heap, duk_uint_t hobject_flags, duk_hobject *obj) {\n\tDUK_ASSERT(obj != NULL);\n\t/* Zeroed by caller. */\n\n\tobj->hdr.h_flags = hobject_flags | DUK_HTYPE_OBJECT;\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(&obj->hdr) == DUK_HTYPE_OBJECT);  /* Assume zero shift. */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tDUK_HOBJECT_SET_PROTOTYPE(heap, obj, NULL);\n\tDUK_HOBJECT_SET_PROPS(heap, obj, NULL);\n#endif\n#if defined(DUK_USE_HEAPPTR16)\n\t/* Zero encoded pointer is required to match NULL. */\n\tDUK_HEAPHDR_SET_NEXT(heap, &obj->hdr, NULL);\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tDUK_HEAPHDR_SET_PREV(heap, &obj->hdr, NULL);\n#endif\n#endif\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, &obj->hdr);\n\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &obj->hdr);\n\n\t/* obj->props is intentionally left as NULL, and duk_hobject_props.c must deal\n\t * with this properly.  This is intentional: empty objects consume a minimum\n\t * amount of memory.  Further, an initial allocation might fail and cause\n\t * 'obj' to \"leak\" (require a mark-and-sweep) since it is not reachable yet.\n\t */\n}\n\nDUK_LOCAL void *duk__hobject_alloc_init(duk_hthread *thr, duk_uint_t hobject_flags, duk_size_t size) {\n\tvoid *res;\n\n\tres = (void *) DUK_ALLOC_CHECKED_ZEROED(thr, size);\n\tDUK_ASSERT(res != NULL);\n\tduk__init_object_parts(thr->heap, hobject_flags, (duk_hobject *) res);\n\treturn res;\n}\n\n/*\n *  Allocate an duk_hobject.\n *\n *  The allocated object has no allocation for properties; the caller may\n *  want to force a resize if a desired size is known.\n *\n *  The allocated object has zero reference count and is not reachable.\n *  The caller MUST make the object reachable and increase its reference\n *  count before invoking any operation that might require memory allocation.\n */\n\nDUK_INTERNAL duk_hobject *duk_hobject_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags) {\n\tduk_hobject *res;\n\n\tDUK_ASSERT(heap != NULL);\n\n\t/* different memory layout, alloc size, and init */\n\tDUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_COMPFUNC) == 0);\n\tDUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_NATFUNC) == 0);\n\tDUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_BOUNDFUNC) == 0);\n\n\tres = (duk_hobject *) DUK_ALLOC_ZEROED(heap, sizeof(duk_hobject));\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\treturn NULL;\n\t}\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(res));\n\n\tduk__init_object_parts(heap, hobject_flags, res);\n\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(res));\n\treturn res;\n}\n\nDUK_INTERNAL duk_hobject *duk_hobject_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hobject *res;\n\n\tres = (duk_hobject *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hobject));\n\treturn res;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_hcompfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hcompfunc *res;\n\n\tres = (duk_hcompfunc *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hcompfunc));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_HEAPPTR16)\n\t/* NULL pointer is required to encode to zero, so memset is enough. */\n#else\n\tres->data = NULL;\n\tres->funcs = NULL;\n\tres->bytecode = NULL;\n#endif\n\tres->lex_env = NULL;\n\tres->var_env = NULL;\n#endif\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_hnatfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hnatfunc *res;\n\n\tres = (duk_hnatfunc *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hnatfunc));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->func = NULL;\n#endif\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hboundfunc *duk_hboundfunc_alloc(duk_heap *heap, duk_uint_t hobject_flags) {\n\tduk_hboundfunc *res;\n\n\tres = (duk_hboundfunc *) DUK_ALLOC(heap, sizeof(duk_hboundfunc));\n\tif (!res) {\n\t\treturn NULL;\n\t}\n\tduk_memzero(res, sizeof(duk_hboundfunc));\n\n\tduk__init_object_parts(heap, hobject_flags, &res->obj);\n\n\tDUK_TVAL_SET_UNDEFINED(&res->target);\n\tDUK_TVAL_SET_UNDEFINED(&res->this_binding);\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->args = NULL;\n#endif\n\n\treturn res;\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_hbufobj *duk_hbufobj_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hbufobj *res;\n\n\tres = (duk_hbufobj *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hbufobj));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->buf = NULL;\n\tres->buf_prop = NULL;\n#endif\n\n\tDUK_HBUFOBJ_ASSERT_VALID(res);\n\treturn res;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* Allocate a new thread.\n *\n * Leaves the built-ins array uninitialized.  The caller must either\n * initialize a new global context or share existing built-ins from\n * another thread.\n */\nDUK_INTERNAL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags) {\n\tduk_hthread *res;\n\n\tres = (duk_hthread *) DUK_ALLOC(heap, sizeof(duk_hthread));\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\treturn NULL;\n\t}\n\tduk_memzero(res, sizeof(duk_hthread));\n\n\tduk__init_object_parts(heap, hobject_flags, &res->obj);\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->ptr_curr_pc = NULL;\n\tres->heap = NULL;\n\tres->valstack = NULL;\n\tres->valstack_end = NULL;\n\tres->valstack_alloc_end = NULL;\n\tres->valstack_bottom = NULL;\n\tres->valstack_top = NULL;\n\tres->callstack_curr = NULL;\n\tres->resumer = NULL;\n\tres->compile_ctx = NULL,\n#if defined(DUK_USE_HEAPPTR16)\n\tres->strs16 = NULL;\n#else\n\tres->strs = NULL;\n#endif\n\t{\n\t\tduk_small_uint_t i;\n\t\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\t\tres->builtins[i] = NULL;\n\t\t}\n\t}\n#endif\n\t/* When nothing is running, API calls are in non-strict mode. */\n\tDUK_ASSERT(res->strict == 0);\n\n\tres->heap = heap;\n\n\t/* XXX: Any reason not to merge duk_hthread_alloc.c here? */\n\treturn res;\n}\n\nDUK_INTERNAL duk_hthread *duk_hthread_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hthread *res;\n\n\tres = duk_hthread_alloc_unchecked(thr->heap, hobject_flags);\n\tif (res == NULL) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn res;\n}\n\nDUK_INTERNAL duk_harray *duk_harray_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_harray *res;\n\n\tres = (duk_harray *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_harray));\n\n\tDUK_ASSERT(res->length == 0);\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hdecenv *duk_hdecenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hdecenv *res;\n\n\tres = (duk_hdecenv *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hdecenv));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->thread = NULL;\n\tres->varmap = NULL;\n#endif\n\n\tDUK_ASSERT(res->thread == NULL);\n\tDUK_ASSERT(res->varmap == NULL);\n\tDUK_ASSERT(res->regbase_byteoff == 0);\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hobjenv *duk_hobjenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hobjenv *res;\n\n\tres = (duk_hobjenv *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hobjenv));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->target = NULL;\n#endif\n\n\tDUK_ASSERT(res->target == NULL);\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hproxy *duk_hproxy_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hproxy *res;\n\n\tres = (duk_hproxy *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hproxy));\n\n\t/* Leave ->target and ->handler uninitialized, as caller will always\n\t * explicitly initialize them before any side effects are possible.\n\t */\n\n\treturn res;\n}\n#line 1 \"duk_hobject_assert.c\"\n/*\n *  duk_hobject and subclass assertion helpers\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ASSERTIONS)\n\nDUK_INTERNAL void duk_hobject_assert_valid(duk_hobject *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE(h) ||\n\t           DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FUNCTION);\n\tDUK_ASSERT(!DUK_HOBJECT_IS_BUFOBJ(h) ||\n\t           (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAYBUFFER ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_DATAVIEW ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT8ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT8ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT16ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT16ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT32ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT32ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FLOAT32ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FLOAT64ARRAY));\n\t/* Object is an Array <=> object has exotic array behavior */\n\tDUK_ASSERT((DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY && DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)) ||\n\t           (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_ARRAY && !DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)));\n}\n\nDUK_INTERNAL void duk_harray_assert_valid(duk_harray *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) h));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY((duk_hobject *) h));\n}\n\nDUK_INTERNAL void duk_hboundfunc_assert_valid(duk_hboundfunc *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_BOUNDFUNC((duk_hobject *) h));\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(&h->target) ||\n\t           (DUK_TVAL_IS_OBJECT(&h->target) &&\n\t            DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(&h->target))));\n\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(&h->this_binding));\n\tDUK_ASSERT(h->nargs == 0 || h->args != NULL);\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL void duk_hbufobj_assert_valid(duk_hbufobj *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(h->shift <= 3);\n\tDUK_ASSERT(h->elem_type <= DUK_HBUFOBJ_ELEM_MAX);\n\tDUK_ASSERT((h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT8) ||\n\t           (h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT8CLAMPED) ||\n\t           (h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_INT8) ||\n\t           (h->shift == 1 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT16) ||\n\t           (h->shift == 1 && h->elem_type == DUK_HBUFOBJ_ELEM_INT16) ||\n\t           (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT32) ||\n\t           (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_INT32) ||\n\t           (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_FLOAT32) ||\n\t           (h->shift == 3 && h->elem_type == DUK_HBUFOBJ_ELEM_FLOAT64));\n\tDUK_ASSERT(h->is_typedarray == 0 || h->is_typedarray == 1);\n\tDUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h));\n\tif (h->buf == NULL) {\n\t\tDUK_ASSERT(h->offset == 0);\n\t\tDUK_ASSERT(h->length == 0);\n\t} else {\n\t\t/* No assertions for offset or length; in particular,\n\t\t * it's OK for length to be longer than underlying\n\t\t * buffer.  Just ensure they don't wrap when added.\n\t\t */\n\t\tDUK_ASSERT(h->offset + h->length >= h->offset);\n\t}\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_INTERNAL void duk_hcompfunc_assert_valid(duk_hcompfunc *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\nDUK_INTERNAL void duk_hnatfunc_assert_valid(duk_hnatfunc *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\nDUK_INTERNAL void duk_hdecenv_assert_valid(duk_hdecenv *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_DECENV((duk_hobject *) h));\n\tDUK_ASSERT(h->thread == NULL || h->varmap != NULL);\n}\n\nDUK_INTERNAL void duk_hobjenv_assert_valid(duk_hobjenv *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_OBJENV((duk_hobject *) h));\n\tDUK_ASSERT(h->target != NULL);\n\tDUK_ASSERT(h->has_this == 0 || h->has_this == 1);\n}\n\nDUK_INTERNAL void duk_hproxy_assert_valid(duk_hproxy *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(h->target != NULL);\n\tDUK_ASSERT(h->handler != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ((duk_hobject *) h));\n}\n\nDUK_INTERNAL void duk_hthread_assert_valid(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) thr) == DUK_HTYPE_OBJECT);\n\tDUK_ASSERT(DUK_HOBJECT_IS_THREAD((duk_hobject *) thr));\n\tDUK_ASSERT(thr->unused1 == 0);\n\tDUK_ASSERT(thr->unused2 == 0);\n}\n\nDUK_INTERNAL void duk_ctx_assert_valid(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_HTHREAD_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack != NULL);\n\tDUK_ASSERT(thr->valstack_bottom != NULL);\n\tDUK_ASSERT(thr->valstack_top != NULL);\n\tDUK_ASSERT(thr->valstack_end != NULL);\n\tDUK_ASSERT(thr->valstack_alloc_end != NULL);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n#line 1 \"duk_hobject_enum.c\"\n/*\n *  Object enumeration support.\n *\n *  Creates an internal enumeration state object to be used e.g. with for-in\n *  enumeration.  The state object contains a snapshot of target object keys\n *  and internal control state for enumeration.  Enumerator flags allow caller\n *  to e.g. request internal/non-enumerable properties, and to enumerate only\n *  \"own\" properties.\n *\n *  Also creates the result value for e.g. Object.keys() based on the same\n *  internal structure.\n *\n *  This snapshot-based enumeration approach is used to simplify enumeration:\n *  non-snapshot-based approaches are difficult to reconcile with mutating\n *  the enumeration target, running multiple long-lived enumerators at the\n *  same time, garbage collection details, etc.  The downside is that the\n *  enumerator object is memory inefficient especially for iterating arrays.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* XXX: identify enumeration target with an object index (not top of stack) */\n\n/* First enumerated key index in enumerator object, must match exactly the\n * number of control properties inserted to the enumerator.\n */\n#define DUK__ENUM_START_INDEX  2\n\n/* Current implementation suffices for ES2015 for now because there's no symbol\n * sorting, so commented out for now.\n */\n\n/*\n *  Helper to sort enumeration keys using a callback for pairwise duk_hstring\n *  comparisons.  The keys are in the enumeration object entry part, starting\n *  from DUK__ENUM_START_INDEX, and the entry part is dense.  Entry part values\n *  are all \"true\", e.g. \"1\" -> true, \"3\" -> true, \"foo\" -> true, \"2\" -> true,\n *  so it suffices to just switch keys without switching values.\n *\n *  ES2015 [[OwnPropertyKeys]] enumeration order for ordinary objects:\n *  (1) array indices in ascending order,\n *  (2) non-array-index keys in insertion order, and\n *  (3) symbols in insertion order.\n *  http://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys.\n *\n *  This rule is applied to \"own properties\" at each inheritance level;\n *  non-duplicate parent keys always follow child keys.  For example,\n *  an inherited array index will enumerate -after- a symbol in the\n *  child.\n *\n *  Insertion sort is used because (1) it's simple and compact, (2) works\n *  in-place, (3) minimizes operations if data is already nearly sorted,\n *  (4) doesn't reorder elements considered equal.\n *  http://en.wikipedia.org/wiki/Insertion_sort\n */\n\n/* Sort key, must hold array indices, \"not array index\" marker, and one more\n * higher value for symbols.\n */\n#if !defined(DUK_USE_SYMBOL_BUILTIN)\ntypedef duk_uint32_t duk__sort_key_t;\n#elif defined(DUK_USE_64BIT_OPS)\ntypedef duk_uint64_t duk__sort_key_t;\n#else\ntypedef duk_double_t duk__sort_key_t;\n#endif\n\n/* Get sort key for a duk_hstring. */\nDUK_LOCAL duk__sort_key_t duk__hstring_sort_key(duk_hstring *x) {\n\tduk__sort_key_t val;\n\n\t/* For array indices [0,0xfffffffe] use the array index as is.\n\t * For strings, use 0xffffffff, the marker 'arridx' already in\n\t * duk_hstring.  For symbols, any value above 0xffffffff works,\n\t * as long as it is the same for all symbols; currently just add\n\t * the masked flag field into the arridx temporary.\n\t */\n\tDUK_ASSERT(x != NULL);\n\tDUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(x) || DUK_HSTRING_GET_ARRIDX_FAST(x) == DUK_HSTRING_NO_ARRAY_INDEX);\n\n\tval = (duk__sort_key_t) DUK_HSTRING_GET_ARRIDX_FAST(x);\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\tval = val + (duk__sort_key_t) (DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) x) & DUK_HSTRING_FLAG_SYMBOL);\n#endif\n\n\treturn (duk__sort_key_t) val;\n}\n\n/* Insert element 'b' after element 'a'? */\nDUK_LOCAL duk_bool_t duk__sort_compare_es6(duk_hstring *a, duk_hstring *b, duk__sort_key_t val_b) {\n\tduk__sort_key_t val_a;\n\n\tDUK_ASSERT(a != NULL);\n\tDUK_ASSERT(b != NULL);\n\tDUK_UNREF(b);  /* Not actually needed now, val_b suffices. */\n\n\tval_a = duk__hstring_sort_key(a);\n\n\tif (val_a > val_b) {\n\t\treturn 0;\n\t} else {\n\t\treturn 1;\n\t}\n}\n\nDUK_LOCAL void duk__sort_enum_keys_es6(duk_hthread *thr, duk_hobject *h_obj, duk_int_fast32_t idx_start, duk_int_fast32_t idx_end) {\n\tduk_hstring **keys;\n\tduk_int_fast32_t idx;\n\n\tDUK_ASSERT(h_obj != NULL);\n\tDUK_ASSERT(idx_start >= DUK__ENUM_START_INDEX);\n\tDUK_ASSERT(idx_end >= idx_start);\n\tDUK_UNREF(thr);\n\n\tif (idx_end <= idx_start + 1) {\n\t\treturn;  /* Zero or one element(s). */\n\t}\n\n\tkeys = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, h_obj);\n\n\tfor (idx = idx_start + 1; idx < idx_end; idx++) {\n\t\tduk_hstring *h_curr;\n\t\tduk_int_fast32_t idx_insert;\n\t\tduk__sort_key_t val_curr;\n\n\t\th_curr = keys[idx];\n\t\tDUK_ASSERT(h_curr != NULL);\n\n\t\t/* Scan backwards for insertion place.  This works very well\n\t\t * when the elements are nearly in order which is the common\n\t\t * (and optimized for) case.\n\t\t */\n\n\t\tval_curr = duk__hstring_sort_key(h_curr);  /* Remains same during scanning. */\n\t\tfor (idx_insert = idx - 1; idx_insert >= idx_start; idx_insert--) {\n\t\t\tduk_hstring *h_insert;\n\t\t\th_insert = keys[idx_insert];\n\t\t\tDUK_ASSERT(h_insert != NULL);\n\n\t\t\tif (duk__sort_compare_es6(h_insert, h_curr, val_curr)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t/* If we're out of indices, idx_insert == idx_start - 1 and idx_insert++\n\t\t * brings us back to idx_start.\n\t\t */\n\t\tidx_insert++;\n\t\tDUK_ASSERT(idx_insert >= 0 && idx_insert <= idx);\n\n\t\t/*        .-- p_insert   .-- p_curr\n\t\t *        v              v\n\t\t *  | ... | insert | ... | curr\n\t\t */\n\n\t\t/* This could also done when the keys are in order, i.e.\n\t\t * idx_insert == idx.  The result would be an unnecessary\n\t\t * memmove() but we use an explicit check because the keys\n\t\t * are very often in order already.\n\t\t */\n\t\tif (idx != idx_insert) {\n\t\t\tduk_memmove((void *) (keys + idx_insert + 1),\n\t\t\t            (const void *) (keys + idx_insert),\n\t\t\t            ((size_t) (idx - idx_insert) * sizeof(duk_hstring *)));\n\t\t\tkeys[idx_insert] = h_curr;\n\t\t}\n\t}\n}\n\n/*\n *  Create an internal enumerator object E, which has its keys ordered\n *  to match desired enumeration ordering.  Also initialize internal control\n *  properties for enumeration.\n *\n *  Note: if an array was used to hold enumeration keys instead, an array\n *  scan would be needed to eliminate duplicates found in the prototype chain.\n */\n\nDUK_LOCAL void duk__add_enum_key(duk_hthread *thr, duk_hstring *k) {\n\t/* 'k' may be unreachable on entry so must push without any\n\t * potential for GC.\n\t */\n\tduk_push_hstring(thr, k);\n\tduk_push_true(thr);\n\tduk_put_prop(thr, -3);\n}\n\nDUK_LOCAL void duk__add_enum_key_stridx(duk_hthread *thr, duk_small_uint_t stridx) {\n\tduk__add_enum_key(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n}\n\nDUK_INTERNAL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint_t enum_flags) {\n\tduk_hobject *enum_target;\n\tduk_hobject *curr;\n\tduk_hobject *res;\n#if defined(DUK_USE_ES6_PROXY)\n\tduk_hobject *h_proxy_target;\n\tduk_hobject *h_proxy_handler;\n\tduk_hobject *h_trap_result;\n#endif\n\tduk_uint_fast32_t i, len;  /* used for array, stack, and entry indices */\n\tduk_uint_fast32_t sort_start_index;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tenum_target = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(enum_target != NULL);\n\n\tduk_push_bare_object(thr);\n\tres = duk_known_hobject(thr, -1);\n\n\t/* [enum_target res] */\n\n\t/* Target must be stored so that we can recheck whether or not\n\t * keys still exist when we enumerate.  This is not done if the\n\t * enumeration result comes from a proxy trap as there is no\n\t * real object to check against.\n\t */\n\tduk_push_hobject(thr, enum_target);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_TARGET);  /* Target is bare, plain put OK. */\n\n\t/* Initialize index so that we skip internal control keys. */\n\tduk_push_int(thr, DUK__ENUM_START_INDEX);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_NEXT);  /* Target is bare, plain put OK. */\n\n\t/*\n\t *  Proxy object handling\n\t */\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (DUK_LIKELY((enum_flags & DUK_ENUM_NO_PROXY_BEHAVIOR) != 0)) {\n\t\tgoto skip_proxy;\n\t}\n\tif (DUK_LIKELY(!duk_hobject_proxy_check(enum_target,\n\t                                        &h_proxy_target,\n\t                                        &h_proxy_handler))) {\n\t\tgoto skip_proxy;\n\t}\n\n\t/* XXX: share code with Object.keys() Proxy handling */\n\n\t/* In ES2015 for-in invoked the \"enumerate\" trap; in ES2016 \"enumerate\"\n\t * has been obsoleted and \"ownKeys\" is used instead.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"proxy enumeration\"));\n\tduk_push_hobject(thr, h_proxy_handler);\n\tif (!duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_OWN_KEYS)) {\n\t\t/* No need to replace the 'enum_target' value in stack, only the\n\t\t * enum_target reference.  This also ensures that the original\n\t\t * enum target is reachable, which keeps the proxy and the proxy\n\t\t * target reachable.  We do need to replace the internal _Target.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"no ownKeys trap, enumerate proxy target instead\"));\n\t\tDUK_DDD(DUK_DDDPRINT(\"h_proxy_target=%!O\", (duk_heaphdr *) h_proxy_target));\n\t\tenum_target = h_proxy_target;\n\n\t\tduk_push_hobject(thr, enum_target);  /* -> [ ... enum_target res handler undefined target ] */\n\t\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_INT_TARGET);  /* Target is bare, plain put OK. */\n\n\t\tduk_pop_2(thr);  /* -> [ ... enum_target res ] */\n\t\tgoto skip_proxy;\n\t}\n\n\t/* [ ... enum_target res handler trap ] */\n\tduk_insert(thr, -2);\n\tduk_push_hobject(thr, h_proxy_target);    /* -> [ ... enum_target res trap handler target ] */\n\tduk_call_method(thr, 1 /*nargs*/);        /* -> [ ... enum_target res trap_result ] */\n\th_trap_result = duk_require_hobject(thr, -1);\n\tDUK_UNREF(h_trap_result);\n\n\tduk_proxy_ownkeys_postprocess(thr, h_proxy_target, enum_flags);\n\t/* -> [ ... enum_target res trap_result keys_array ] */\n\n\t/* Copy cleaned up trap result keys into the enumerator object. */\n\t/* XXX: result is a dense array; could make use of that. */\n\tDUK_ASSERT(duk_is_array(thr, -1));\n\tlen = (duk_uint_fast32_t) duk_get_length(thr, -1);\n\tfor (i = 0; i < len; i++) {\n\t\t(void) duk_get_prop_index(thr, -1, (duk_uarridx_t) i);\n\t\tDUK_ASSERT(duk_is_string(thr, -1));  /* postprocess cleaned up */\n\t\t/* [ ... enum_target res trap_result keys_array val ] */\n\t\tduk_push_true(thr);\n\t\t/* [ ... enum_target res trap_result keys_array val true ] */\n\t\tduk_put_prop(thr, -5);\n\t}\n\t/* [ ... enum_target res trap_result keys_array ] */\n\tduk_pop_2(thr);\n\tduk_remove_m2(thr);\n\n\t/* [ ... res ] */\n\n\t/* The internal _Target property is kept pointing to the original\n\t * enumeration target (the proxy object), so that the enumerator\n\t * 'next' operation can read property values if so requested.  The\n\t * fact that the _Target is a proxy disables key existence check\n\t * during enumeration.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"proxy enumeration, final res: %!O\", (duk_heaphdr *) res));\n\tgoto compact_and_return;\n\n skip_proxy:\n#endif  /* DUK_USE_ES6_PROXY */\n\n\tcurr = enum_target;\n\tsort_start_index = DUK__ENUM_START_INDEX;\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(res) == DUK__ENUM_START_INDEX);\n\twhile (curr) {\n\t\tduk_uint_fast32_t sort_end_index;\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\tduk_bool_t need_sort = 0;\n#endif\n\t\tduk_bool_t cond;\n\n\t\t/* Enumeration proceeds by inheritance level.  Virtual\n\t\t * properties need to be handled specially, followed by\n\t\t * array part, and finally entry part.\n\t\t *\n\t\t * If there are array index keys in the entry part or any\n\t\t * other risk of the ES2015 [[OwnPropertyKeys]] order being\n\t\t * violated, need_sort is set and an explicit ES2015 sort is\n\t\t * done for the inheritance level.\n\t\t */\n\n\t\t/* XXX: inheriting from proxy */\n\n\t\t/*\n\t\t *  Virtual properties.\n\t\t *\n\t\t *  String and buffer indices are virtual and always enumerable,\n\t\t *  'length' is virtual and non-enumerable.  Array and arguments\n\t\t *  object props have special behavior but are concrete.\n\t\t *\n\t\t *  String and buffer objects don't have an array part so as long\n\t\t *  as virtual array index keys are enumerated first, we don't\n\t\t *  need to set need_sort.\n\t\t */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tcond = DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr) || DUK_HOBJECT_IS_BUFOBJ(curr);\n#else\n\t\tcond = DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr);\n#endif\n\t\tcond = cond && !(enum_flags & DUK_ENUM_EXCLUDE_STRINGS);\n\t\tif (cond) {\n\t\t\tduk_bool_t have_length = 1;\n\n\t\t\t/* String and buffer enumeration behavior is identical now,\n\t\t\t * so use shared handler.\n\t\t\t */\n\t\t\tif (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr)) {\n\t\t\t\tduk_hstring *h_val;\n\t\t\t\th_val = duk_hobject_get_internal_value_string(thr->heap, curr);\n\t\t\t\tDUK_ASSERT(h_val != NULL);  /* string objects must not created without internal value */\n\t\t\t\tlen = (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h_val);\n\t\t\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t\telse {\n\t\t\t\tduk_hbufobj *h_bufobj;\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ(curr));\n\t\t\t\th_bufobj = (duk_hbufobj *) curr;\n\n\t\t\t\tif (h_bufobj == NULL || !h_bufobj->is_typedarray) {\n\t\t\t\t\t/* Zero length seems like a good behavior for neutered buffers.\n\t\t\t\t\t * ArrayBuffer (non-view) and DataView don't have index properties\n\t\t\t\t\t * or .length property.\n\t\t\t\t\t */\n\t\t\t\t\tlen = 0;\n\t\t\t\t\thave_length = 0;\n\t\t\t\t} else {\n\t\t\t\t\t/* There's intentionally no check for\n\t\t\t\t\t * current underlying buffer length.\n\t\t\t\t\t */\n\t\t\t\t\tlen = (duk_uint_fast32_t) (h_bufobj->length >> h_bufobj->shift);\n\t\t\t\t}\n\t\t\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\tduk_hstring *k;\n\n\t\t\t\t/* This is a bit fragile: the string is not\n\t\t\t\t * reachable until it is pushed by the helper.\n\t\t\t\t */\n\t\t\t\tk = duk_heap_strtable_intern_u32_checked(thr, (duk_uint32_t) i);\n\t\t\t\tDUK_ASSERT(k);\n\n\t\t\t\tduk__add_enum_key(thr, k);\n\n\t\t\t\t/* [enum_target res] */\n\t\t\t}\n\n\t\t\t/* 'length' and other virtual properties are not\n\t\t\t * enumerable, but are included if non-enumerable\n\t\t\t * properties are requested.\n\t\t\t */\n\n\t\t\tif (have_length && (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE)) {\n\t\t\t\tduk__add_enum_key_stridx(thr, DUK_STRIDX_LENGTH);\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t *  Array part\n\t\t */\n\n\t\tcond = !(enum_flags & DUK_ENUM_EXCLUDE_STRINGS);\n\t\tif (cond) {\n\t\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(curr); i++) {\n\t\t\t\tduk_hstring *k;\n\t\t\t\tduk_tval *tv;\n\n\t\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, curr, i);\n\t\t\t\tif (DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tk = duk_heap_strtable_intern_u32_checked(thr, (duk_uint32_t) i);  /* Fragile reachability. */\n\t\t\t\tDUK_ASSERT(k);\n\n\t\t\t\tduk__add_enum_key(thr, k);\n\n\t\t\t\t/* [enum_target res] */\n\t\t\t}\n\n\t\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(curr)) {\n\t\t\t\t/* Array .length comes after numeric indices. */\n\t\t\t\tif (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) {\n\t\t\t\t\tduk__add_enum_key_stridx(thr, DUK_STRIDX_LENGTH);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t *  Entries part\n\t\t */\n\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(curr); i++) {\n\t\t\tduk_hstring *k;\n\n\t\t\tk = DUK_HOBJECT_E_GET_KEY(thr->heap, curr, i);\n\t\t\tif (!k) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!(enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) &&\n\t\t\t    !DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(thr->heap, curr, i)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(k))) {\n\t\t\t\tif (!(enum_flags & DUK_ENUM_INCLUDE_HIDDEN) &&\n\t\t\t\t    DUK_HSTRING_HAS_HIDDEN(k)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!(enum_flags & DUK_ENUM_INCLUDE_SYMBOLS)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t\tneed_sort = 1;\n#endif\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(!DUK_HSTRING_HAS_HIDDEN(k));  /* would also have symbol flag */\n\t\t\t\tif (enum_flags & DUK_ENUM_EXCLUDE_STRINGS) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (DUK_HSTRING_HAS_ARRIDX(k)) {\n\t\t\t\t/* This in currently only possible if the\n\t\t\t\t * object has no array part: the array part\n\t\t\t\t * is exhaustive when it is present.\n\t\t\t\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t\tneed_sort = 1;\n#endif\n\t\t\t} else {\n\t\t\t\tif (enum_flags & DUK_ENUM_ARRAY_INDICES_ONLY) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, curr, i) ||\n\t\t\t           !DUK_TVAL_IS_UNUSED(&DUK_HOBJECT_E_GET_VALUE_PTR(thr->heap, curr, i)->v));\n\n\t\t\tduk__add_enum_key(thr, k);\n\n\t\t\t/* [enum_target res] */\n\t\t}\n\n\t\t/* Sort enumerated keys according to ES2015 requirements for\n\t\t * the \"inheritance level\" just processed.  This is far from\n\t\t * optimal, ES2015 semantics could be achieved more efficiently\n\t\t * by handling array index string keys (and symbol keys)\n\t\t * specially above in effect doing the sort inline.\n\t\t *\n\t\t * Skip the sort if array index sorting is requested because\n\t\t * we must consider all keys, also inherited, so an explicit\n\t\t * sort is done for the whole result after we're done with the\n\t\t * prototype chain.\n\t\t *\n\t\t * Also skip the sort if need_sort == 0, i.e. we know for\n\t\t * certain that the enumerated order is already correct.\n\t\t */\n\t\tsort_end_index = DUK_HOBJECT_GET_ENEXT(res);\n\n\t\tif (!(enum_flags & DUK_ENUM_SORT_ARRAY_INDICES)) {\n#if defined(DUK_USE_PREFER_SIZE)\n\t\t\tduk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) sort_start_index, (duk_int_fast32_t) sort_end_index);\n#else\n\t\t\tif (need_sort) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"need to sort\"));\n\t\t\t\tduk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) sort_start_index, (duk_int_fast32_t) sort_end_index);\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"no need to sort\"));\n\t\t\t}\n#endif\n\t\t}\n\n\t\tsort_start_index = sort_end_index;\n\n\t\tif (enum_flags & DUK_ENUM_OWN_PROPERTIES_ONLY) {\n\t\t\tbreak;\n\t\t}\n\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t}\n\n\t/* [enum_target res] */\n\n\tduk_remove_m2(thr);\n\n\t/* [res] */\n\n\tif (enum_flags & DUK_ENUM_SORT_ARRAY_INDICES) {\n\t\t/* Some E5/E5.1 algorithms require that array indices are iterated\n\t\t * in a strictly ascending order.  This is the case for e.g.\n\t\t * Array.prototype.forEach() and JSON.stringify() PropertyList\n\t\t * handling.  The caller can request an explicit sort in these\n\t\t * cases.\n\t\t */\n\n\t\t/* Sort to ES2015 order which works for pure array incides but\n\t\t * also for mixed keys.\n\t\t */\n\t\tduk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) DUK__ENUM_START_INDEX, (duk_int_fast32_t) DUK_HOBJECT_GET_ENEXT(res));\n\t}\n\n#if defined(DUK_USE_ES6_PROXY)\n compact_and_return:\n#endif\n\t/* compact; no need to seal because object is internal */\n\tduk_hobject_compact_props(thr, res);\n\n\tDUK_DDD(DUK_DDDPRINT(\"created enumerator object: %!iT\", (duk_tval *) duk_get_tval(thr, -1)));\n}\n\n/*\n *  Returns non-zero if a key and/or value was enumerated, and:\n *\n *   [enum] -> [key]        (get_value == 0)\n *   [enum] -> [key value]  (get_value == 1)\n *\n *  Returns zero without pushing anything on the stack otherwise.\n */\nDUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_hthread *thr, duk_bool_t get_value) {\n\tduk_hobject *e;\n\tduk_hobject *enum_target;\n\tduk_hstring *res = NULL;\n\tduk_uint_fast32_t idx;\n\tduk_bool_t check_existence;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* [... enum] */\n\n\te = duk_require_hobject(thr, -1);\n\n\t/* XXX use get tval ptr, more efficient */\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_NEXT);\n\tidx = (duk_uint_fast32_t) duk_require_uint(thr, -1);\n\tduk_pop(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"enumeration: index is: %ld\", (long) idx));\n\n\t/* Enumeration keys are checked against the enumeration target (to see\n\t * that they still exist).  In the proxy enumeration case _Target will\n\t * be the proxy, and checking key existence against the proxy is not\n\t * required (or sensible, as the keys may be fully virtual).\n\t */\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_TARGET);\n\tenum_target = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(enum_target != NULL);\n#if defined(DUK_USE_ES6_PROXY)\n\tcheck_existence = (!DUK_HOBJECT_IS_PROXY(enum_target));\n#else\n\tcheck_existence = 1;\n#endif\n\tduk_pop(thr);  /* still reachable */\n\n\tDUK_DDD(DUK_DDDPRINT(\"getting next enum value, enum_target=%!iO, enumerator=%!iT\",\n\t                     (duk_heaphdr *) enum_target, (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* no array part */\n\tfor (;;) {\n\t\tduk_hstring *k;\n\n\t\tif (idx >= DUK_HOBJECT_GET_ENEXT(e)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"enumeration: ran out of elements\"));\n\t\t\tbreak;\n\t\t}\n\n\t\t/* we know these because enum objects are internally created */\n\t\tk = DUK_HOBJECT_E_GET_KEY(thr->heap, e, idx);\n\t\tDUK_ASSERT(k != NULL);\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, e, idx));\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(&DUK_HOBJECT_E_GET_VALUE(thr->heap, e, idx).v));\n\n\t\tidx++;\n\n\t\t/* recheck that the property still exists */\n\t\tif (check_existence && !duk_hobject_hasprop_raw(thr, enum_target, k)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property deleted during enumeration, skip\"));\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"enumeration: found element, key: %!O\", (duk_heaphdr *) k));\n\t\tres = k;\n\t\tbreak;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"enumeration: updating next index to %ld\", (long) idx));\n\n\tduk_push_u32(thr, (duk_uint32_t) idx);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_NEXT);\n\n\t/* [... enum] */\n\n\tif (res) {\n\t\tduk_push_hstring(thr, res);\n\t\tif (get_value) {\n\t\t\tduk_push_hobject(thr, enum_target);\n\t\t\tduk_dup_m2(thr);       /* -> [... enum key enum_target key] */\n\t\t\tduk_get_prop(thr, -2); /* -> [... enum key enum_target val] */\n\t\t\tduk_remove_m2(thr);    /* -> [... enum key val] */\n\t\t\tduk_remove(thr, -3);   /* -> [... key val] */\n\t\t} else {\n\t\t\tduk_remove_m2(thr);    /* -> [... key] */\n\t\t}\n\t\treturn 1;\n\t} else {\n\t\tduk_pop(thr);  /* -> [...] */\n\t\treturn 0;\n\t}\n}\n\n/*\n *  Get enumerated keys in an ECMAScript array.  Matches Object.keys() behavior\n *  described in E5 Section 15.2.3.14.\n */\n\nDUK_INTERNAL duk_ret_t duk_hobject_get_enumerated_keys(duk_hthread *thr, duk_small_uint_t enum_flags) {\n\tduk_hobject *e;\n\tduk_hstring **keys;\n\tduk_tval *tv;\n\tduk_uint_fast32_t count;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(duk_get_hobject(thr, -1) != NULL);\n\n\t/* Create a temporary enumerator to get the (non-duplicated) key list;\n\t * the enumerator state is initialized without being needed, but that\n\t * has little impact.\n\t */\n\n\tduk_hobject_enumerator_create(thr, enum_flags);\n\te = duk_known_hobject(thr, -1);\n\n\t/* [enum_target enum res] */\n\n\t/* Create dense result array to exact size. */\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(e) >= DUK__ENUM_START_INDEX);\n\tcount = (duk_uint32_t) (DUK_HOBJECT_GET_ENEXT(e) - DUK__ENUM_START_INDEX);\n\n\t/* XXX: uninit would be OK */\n\ttv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) count);\n\tDUK_ASSERT(count == 0 || tv != NULL);\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\t/* Fill result array, no side effects. */\n\n\tkeys = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, e);\n\tkeys += DUK__ENUM_START_INDEX;\n\n\twhile (count-- > 0) {\n\t\tduk_hstring *k;\n\n\t\tk = *keys++;\n\t\tDUK_ASSERT(k != NULL);  /* enumerator must have no keys deleted */\n\n\t\tDUK_TVAL_SET_STRING(tv, k);\n\t\ttv++;\n\t\tDUK_HSTRING_INCREF(thr, k);\n\t}\n\n\t/* [enum_target enum res] */\n\tduk_remove_m2(thr);\n\n\t/* [enum_target res] */\n\n\treturn 1;  /* return 1 to allow callers to tail call */\n}\n\n/* automatic undefs */\n#undef DUK__ENUM_START_INDEX\n#line 1 \"duk_hobject_misc.c\"\n/*\n *  Misc support functions\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, duk_hobject *h, duk_hobject *p, duk_bool_t ignore_loop) {\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* False if the object is NULL or the prototype 'p' is NULL.\n\t * In particular, false if both are NULL (don't compare equal).\n\t */\n\tif (h == NULL || p == NULL) {\n\t\treturn 0;\n\t}\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (h == p) {\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (sanity-- == 0) {\n\t\t\tif (ignore_loop) {\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\t\th = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t} while (h);\n\n\treturn 0;\n}\n\nDUK_INTERNAL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject *h, duk_hobject *p) {\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_hobject *tmp;\n\n\tDUK_ASSERT(h);\n\ttmp = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, h, p);\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, p);  /* avoid problems if p == h->prototype */\n\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);\n#else\n\tDUK_ASSERT(h);\n\tDUK_UNREF(thr);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, h, p);\n#endif\n}\n#line 1 \"duk_hobject_pc2line.c\"\n/*\n *  Helpers for creating and querying pc2line debug data, which\n *  converts a bytecode program counter to a source line number.\n *\n *  The run-time pc2line data is bit-packed, and documented in:\n *\n *    doc/function-objects.rst\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_PC2LINE)\n\n/* Generate pc2line data for an instruction sequence, leaving a buffer on stack top. */\nDUK_INTERNAL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr *instrs, duk_uint_fast32_t length) {\n\tduk_hbuffer_dynamic *h_buf;\n\tduk_bitencoder_ctx be_ctx_alloc;\n\tduk_bitencoder_ctx *be_ctx = &be_ctx_alloc;\n\tduk_uint32_t *hdr;\n\tduk_size_t new_size;\n\tduk_uint_fast32_t num_header_entries;\n\tduk_uint_fast32_t curr_offset;\n\tduk_int_fast32_t curr_line, next_line, diff_line;\n\tduk_uint_fast32_t curr_pc;\n\tduk_uint_fast32_t hdr_index;\n\n\tDUK_ASSERT(length <= DUK_COMPILER_MAX_BYTECODE_LENGTH);\n\n\tnum_header_entries = (length + DUK_PC2LINE_SKIP - 1) / DUK_PC2LINE_SKIP;\n\tcurr_offset = (duk_uint_fast32_t) (sizeof(duk_uint32_t) + num_header_entries * sizeof(duk_uint32_t) * 2);\n\n\tduk_push_dynamic_buffer(thr, (duk_size_t) curr_offset);\n\th_buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, -1);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h_buf) && !DUK_HBUFFER_HAS_EXTERNAL(h_buf));\n\n\thdr = (duk_uint32_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h_buf);\n\tDUK_ASSERT(hdr != NULL);\n\thdr[0] = (duk_uint32_t) length;  /* valid pc range is [0, length[ */\n\n\tcurr_pc = 0U;\n\twhile (curr_pc < length) {\n\t\tnew_size = (duk_size_t) (curr_offset + DUK_PC2LINE_MAX_DIFF_LENGTH);\n\t\tduk_hbuffer_resize(thr, h_buf, new_size);\n\n\t\thdr = (duk_uint32_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h_buf);\n\t\tDUK_ASSERT(hdr != NULL);\n\t\tDUK_ASSERT(curr_pc < length);\n\t\thdr_index = 1 + (curr_pc / DUK_PC2LINE_SKIP) * 2;\n\t\tcurr_line = (duk_int_fast32_t) instrs[curr_pc].line;\n\t\thdr[hdr_index + 0] = (duk_uint32_t) curr_line;\n\t\thdr[hdr_index + 1] = (duk_uint32_t) curr_offset;\n\n#if 0\n\t\tDUK_DDD(DUK_DDDPRINT(\"hdr[%ld]: pc=%ld line=%ld offset=%ld\",\n\t\t                     (long) (curr_pc / DUK_PC2LINE_SKIP),\n\t\t                     (long) curr_pc,\n\t\t                     (long) hdr[hdr_index + 0],\n\t\t                     (long) hdr[hdr_index + 1]));\n#endif\n\n\t\tduk_memzero(be_ctx, sizeof(*be_ctx));\n\t\tbe_ctx->data = ((duk_uint8_t *) hdr) + curr_offset;\n\t\tbe_ctx->length = (duk_size_t) DUK_PC2LINE_MAX_DIFF_LENGTH;\n\n\t\tfor (;;) {\n\t\t\tcurr_pc++;\n\t\t\tif ( ((curr_pc % DUK_PC2LINE_SKIP) == 0) ||  /* end of diff run */\n\t\t\t     (curr_pc >= length) ) {                 /* end of bytecode */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_ASSERT(curr_pc < length);\n\t\t\tnext_line = (duk_int32_t) instrs[curr_pc].line;\n\t\t\tdiff_line = next_line - curr_line;\n\n#if 0\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"curr_line=%ld, next_line=%ld -> diff_line=%ld\",\n\t\t\t                     (long) curr_line, (long) next_line, (long) diff_line));\n#endif\n\n\t\t\tif (diff_line == 0) {\n\t\t\t\t/* 0 */\n\t\t\t\tduk_be_encode(be_ctx, 0, 1);\n\t\t\t} else if (diff_line >= 1 && diff_line <= 4) {\n\t\t\t\t/* 1 0 <2 bits> */\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) ((0x02 << 2) + (diff_line - 1)), 4);\n\t\t\t} else if (diff_line >= -0x80 && diff_line <= 0x7f) {\n\t\t\t\t/* 1 1 0 <8 bits> */\n\t\t\t\tDUK_ASSERT(diff_line + 0x80 >= 0 && diff_line + 0x80 <= 0xff);\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) ((0x06 << 8) + (diff_line + 0x80)), 11);\n\t\t\t} else {\n\t\t\t\t/* 1 1 1 <32 bits>\n\t\t\t\t * Encode in two parts to avoid bitencode 24-bit limitation\n\t\t\t\t */\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) ((0x07 << 16) + ((next_line >> 16) & 0xffff)), 19);\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) (next_line & 0xffff), 16);\n\t\t\t}\n\n\t\t\tcurr_line = next_line;\n\t\t}\n\n\t\tduk_be_finish(be_ctx);\n\t\tDUK_ASSERT(!be_ctx->truncated);\n\n\t\t/* be_ctx->offset == length of encoded bitstream */\n\t\tcurr_offset += (duk_uint_fast32_t) be_ctx->offset;\n\t}\n\n\t/* compact */\n\tnew_size = (duk_size_t) curr_offset;\n\tduk_hbuffer_resize(thr, h_buf, new_size);\n\n\t(void) duk_to_fixed_buffer(thr, -1, NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"final pc2line data: pc_limit=%ld, length=%ld, %lf bits/opcode --> %!ixT\",\n\t                     (long) length, (long) new_size, (double) new_size * 8.0 / (double) length,\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n}\n\n/* PC is unsigned.  If caller does PC arithmetic and gets a negative result,\n * it will map to a large PC which is out of bounds and causes a zero to be\n * returned.\n */\nDUK_LOCAL duk_uint_fast32_t duk__hobject_pc2line_query_raw(duk_hthread *thr, duk_hbuffer_fixed *buf, duk_uint_fast32_t pc) {\n\tduk_bitdecoder_ctx bd_ctx_alloc;\n\tduk_bitdecoder_ctx *bd_ctx = &bd_ctx_alloc;\n\tduk_uint32_t *hdr;\n\tduk_uint_fast32_t start_offset;\n\tduk_uint_fast32_t pc_limit;\n\tduk_uint_fast32_t hdr_index;\n\tduk_uint_fast32_t pc_base;\n\tduk_uint_fast32_t n;\n\tduk_uint_fast32_t curr_line;\n\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) buf) && !DUK_HBUFFER_HAS_EXTERNAL((duk_hbuffer *) buf));\n\tDUK_UNREF(thr);\n\n\t/*\n\t *  Use the index in the header to find the right starting point\n\t */\n\n\thdr_index = pc / DUK_PC2LINE_SKIP;\n\tpc_base = hdr_index * DUK_PC2LINE_SKIP;\n\tn = pc - pc_base;\n\n\tif (DUK_HBUFFER_FIXED_GET_SIZE(buf) <= sizeof(duk_uint32_t)) {\n\t\tDUK_DD(DUK_DDPRINT(\"pc2line lookup failed: buffer is smaller than minimal header\"));\n\t\tgoto pc2line_error;\n\t}\n\n\thdr = (duk_uint32_t *) (void *) DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, buf);\n\tpc_limit = hdr[0];\n\tif (pc >= pc_limit) {\n\t\t/* Note: pc is unsigned and cannot be negative */\n\t\tDUK_DD(DUK_DDPRINT(\"pc2line lookup failed: pc out of bounds (pc=%ld, limit=%ld)\",\n\t\t                   (long) pc, (long) pc_limit));\n\t\tgoto pc2line_error;\n\t}\n\n\tcurr_line = hdr[1 + hdr_index * 2];\n\tstart_offset = hdr[1 + hdr_index * 2 + 1];\n\tif ((duk_size_t) start_offset > DUK_HBUFFER_FIXED_GET_SIZE(buf)) {\n\t\tDUK_DD(DUK_DDPRINT(\"pc2line lookup failed: start_offset out of bounds (start_offset=%ld, buffer_size=%ld)\",\n\t\t                   (long) start_offset, (long) DUK_HBUFFER_GET_SIZE((duk_hbuffer *) buf)));\n\t\tgoto pc2line_error;\n\t}\n\n\t/*\n\t *  Iterate the bitstream (line diffs) until PC is reached\n\t */\n\n\tduk_memzero(bd_ctx, sizeof(*bd_ctx));\n\tbd_ctx->data = ((duk_uint8_t *) hdr) + start_offset;\n\tbd_ctx->length = (duk_size_t) (DUK_HBUFFER_FIXED_GET_SIZE(buf) - start_offset);\n\n#if 0\n\tDUK_DDD(DUK_DDDPRINT(\"pc2line lookup: pc=%ld -> hdr_index=%ld, pc_base=%ld, n=%ld, start_offset=%ld\",\n\t                     (long) pc, (long) hdr_index, (long) pc_base, (long) n, (long) start_offset));\n#endif\n\n\twhile (n > 0) {\n#if 0\n\t\tDUK_DDD(DUK_DDDPRINT(\"lookup: n=%ld, curr_line=%ld\", (long) n, (long) curr_line));\n#endif\n\n\t\tif (duk_bd_decode_flag(bd_ctx)) {\n\t\t\tif (duk_bd_decode_flag(bd_ctx)) {\n\t\t\t\tif (duk_bd_decode_flag(bd_ctx)) {\n\t\t\t\t\t/* 1 1 1 <32 bits> */\n\t\t\t\t\tduk_uint_fast32_t t;\n\t\t\t\t\tt = duk_bd_decode(bd_ctx, 16);  /* workaround: max nbits = 24 now */\n\t\t\t\t\tt = (t << 16) + duk_bd_decode(bd_ctx, 16);\n\t\t\t\t\tcurr_line = t;\n\t\t\t\t} else {\n\t\t\t\t\t/* 1 1 0 <8 bits> */\n\t\t\t\t\tduk_uint_fast32_t t;\n\t\t\t\t\tt = duk_bd_decode(bd_ctx, 8);\n\t\t\t\t\tcurr_line = curr_line + t - 0x80;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* 1 0 <2 bits> */\n\t\t\t\tduk_uint_fast32_t t;\n\t\t\t\tt = duk_bd_decode(bd_ctx, 2);\n\t\t\t\tcurr_line = curr_line + t + 1;\n\t\t\t}\n\t\t} else {\n\t\t\t/* 0: no change */\n\t\t}\n\n\t\tn--;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"pc2line lookup result: pc %ld -> line %ld\", (long) pc, (long) curr_line));\n\treturn curr_line;\n\n pc2line_error:\n\tDUK_D(DUK_DPRINT(\"pc2line conversion failed for pc=%ld\", (long) pc));\n\treturn 0;\n}\n\nDUK_INTERNAL duk_uint_fast32_t duk_hobject_pc2line_query(duk_hthread *thr, duk_idx_t idx_func, duk_uint_fast32_t pc) {\n\tduk_hbuffer_fixed *pc2line;\n\tduk_uint_fast32_t line;\n\n\t/* XXX: now that pc2line is used by the debugger quite heavily in\n\t * checked execution, this should be optimized to avoid value stack\n\t * and perhaps also implement some form of pc2line caching (see\n\t * future work in debugger.rst).\n\t */\n\n\tduk_xget_owndataprop_stridx_short(thr, idx_func, DUK_STRIDX_INT_PC2LINE);\n\tpc2line = (duk_hbuffer_fixed *) (void *) duk_get_hbuffer(thr, -1);\n\tif (pc2line != NULL) {\n\t\tDUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) pc2line) && !DUK_HBUFFER_HAS_EXTERNAL((duk_hbuffer *) pc2line));\n\t\tline = duk__hobject_pc2line_query_raw(thr, pc2line, (duk_uint_fast32_t) pc);\n\t} else {\n\t\tline = 0;\n\t}\n\tduk_pop(thr);\n\n\treturn line;\n}\n\n#endif  /* DUK_USE_PC2LINE */\n#line 1 \"duk_hobject_props.c\"\n/*\n *  duk_hobject property access functionality.\n *\n *  This is very central functionality for size, performance, and compliance.\n *  It is also rather intricate; see hobject-algorithms.rst for discussion on\n *  the algorithms and memory-management.rst for discussion on refcounts and\n *  side effect issues.\n *\n *  Notes:\n *\n *    - It might be tempting to assert \"refcount nonzero\" for objects\n *      being operated on, but that's not always correct: objects with\n *      a zero refcount may be operated on by the refcount implementation\n *      (finalization) for instance.  Hence, no refcount assertions are made.\n *\n *    - Many operations (memory allocation, identifier operations, etc)\n *      may cause arbitrary side effects (e.g. through GC and finalization).\n *      These side effects may invalidate duk_tval pointers which point to\n *      areas subject to reallocation (like value stack).  Heap objects\n *      themselves have stable pointers.  Holding heap object pointers or\n *      duk_tval copies is not problematic with respect to side effects;\n *      care must be taken when holding and using argument duk_tval pointers.\n *\n *    - If a finalizer is executed, it may operate on the the same object\n *      we're currently dealing with.  For instance, the finalizer might\n *      delete a certain property which has already been looked up and\n *      confirmed to exist.  Ideally finalizers would be disabled if GC\n *      happens during property access.  At the moment property table realloc\n *      disables finalizers, and all DECREFs may cause arbitrary changes so\n *      handle DECREF carefully.\n *\n *    - The order of operations for a DECREF matters.  When DECREF is executed,\n *      the entire object graph must be consistent; note that a refzero may\n *      lead to a mark-and-sweep through a refcount finalizer.  Use NORZ macros\n *      and an explicit DUK_REFZERO_CHECK_xxx() if achieving correct order is hard.\n */\n\n/*\n *  XXX: array indices are mostly typed as duk_uint32_t here; duk_uarridx_t\n *  might be more appropriate.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Local defines\n */\n\n#define DUK__NO_ARRAY_INDEX             DUK_HSTRING_NO_ARRAY_INDEX\n\n/* Marker values for hash part. */\n#define DUK__HASH_UNUSED                DUK_HOBJECT_HASHIDX_UNUSED\n#define DUK__HASH_DELETED               DUK_HOBJECT_HASHIDX_DELETED\n\n/* Valstack space that suffices for all local calls, excluding any recursion\n * into ECMAScript or Duktape/C calls (Proxy, getters, etc).\n */\n#define DUK__VALSTACK_SPACE             10\n\n/* Valstack space allocated especially for proxy lookup which does a\n * recursive property lookup.\n */\n#define DUK__VALSTACK_PROXY_LOOKUP      20\n\n/*\n *  Local prototypes\n */\n\nDUK_LOCAL_DECL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc);\nDUK_LOCAL_DECL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc, duk_bool_t throw_flag);\nDUK_LOCAL_DECL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc);\n\nDUK_LOCAL_DECL duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr, duk_hobject *obj, duk_uint32_t old_len, duk_uint32_t new_len, duk_bool_t force_flag, duk_uint32_t *out_result_len);\nDUK_LOCAL_DECL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject *obj);\n\nDUK_LOCAL_DECL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags);\nDUK_LOCAL_DECL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_uint32_t arr_idx, duk_propdesc *out_desc, duk_small_uint_t flags);\n\nDUK_LOCAL_DECL void duk__abandon_array_part(duk_hthread *thr, duk_hobject *obj);\nDUK_LOCAL_DECL void duk__grow_props_for_array_item(duk_hthread *thr, duk_hobject *obj, duk_uint32_t highest_arr_idx);\n\n/*\n *  Misc helpers\n */\n\n/* Convert a duk_tval number (caller checks) to a 32-bit index.  Returns\n * DUK__NO_ARRAY_INDEX if the number is not whole or not a valid array\n * index.\n */\n/* XXX: for fastints, could use a variant which assumes a double duk_tval\n * (and doesn't need to check for fastint again).\n */\nDUK_LOCAL duk_uint32_t duk__tval_number_to_arr_idx(duk_tval *tv) {\n\tduk_double_t dbl;\n\tduk_uint32_t idx;\n\n\tDUK_ASSERT(tv != NULL);\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\n\t/* -0 is accepted here as index 0 because ToString(-0) == \"0\" which is\n\t * in canonical form and thus an array index.\n\t */\n\tdbl = DUK_TVAL_GET_NUMBER(tv);\n\tidx = (duk_uint32_t) dbl;\n\tif ((duk_double_t) idx == dbl) {\n\t        /* Is whole and within 32 bit range.  If the value happens to be 0xFFFFFFFF,\n\t\t * it's not a valid array index but will then match DUK__NO_ARRAY_INDEX.\n\t\t */\n\t\treturn idx;\n\t}\n\treturn DUK__NO_ARRAY_INDEX;\n}\n\n#if defined(DUK_USE_FASTINT)\n/* Convert a duk_tval fastint (caller checks) to a 32-bit index. */\nDUK_LOCAL duk_uint32_t duk__tval_fastint_to_arr_idx(duk_tval *tv) {\n\tduk_int64_t t;\n\n\tDUK_ASSERT(tv != NULL);\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\n\tt = DUK_TVAL_GET_FASTINT(tv);\n\tif (((duk_uint64_t) t & ~DUK_U64_CONSTANT(0xffffffff)) != 0) {\n\t\t/* Catches >0x100000000 and negative values. */\n\t\treturn DUK__NO_ARRAY_INDEX;\n\t}\n\n\t/* If the value happens to be 0xFFFFFFFF, it's not a valid array index\n\t * but will then match DUK__NO_ARRAY_INDEX.\n\t */\n\treturn (duk_uint32_t) t;\n}\n#endif  /* DUK_USE_FASTINT */\n\n/* Convert a duk_tval on the value stack (in a trusted index we don't validate)\n * to a string or symbol using ES2015 ToPropertyKey():\n * http://www.ecma-international.org/ecma-262/6.0/#sec-topropertykey.\n *\n * Also check if it's a valid array index and return that (or DUK__NO_ARRAY_INDEX\n * if not).\n */\nDUK_LOCAL duk_uint32_t duk__to_property_key(duk_hthread *thr, duk_idx_t idx, duk_hstring **out_h) {\n\tduk_uint32_t arr_idx;\n\tduk_hstring *h;\n\tduk_tval *tv_dst;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(out_h != NULL);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx));\n\tDUK_ASSERT(idx < 0);\n\n\t/* XXX: The revised ES2015 ToPropertyKey() handling (ES5.1 was just\n\t * ToString()) involves a ToPrimitive(), a symbol check, and finally\n\t * a ToString().  Figure out the best way to have a good fast path\n\t * but still be compliant and share code.\n\t */\n\n\ttv_dst = DUK_GET_TVAL_NEGIDX(thr, idx);  /* intentionally unvalidated */\n\tif (DUK_TVAL_IS_STRING(tv_dst)) {\n\t\t/* Most important path: strings and plain symbols are used as\n\t\t * is.  For symbols the array index check below is unnecessary\n\t\t * (they're never valid array indices) but checking that the\n\t\t * string is a symbol would make the plain string path slower\n\t\t * unnecessarily.\n\t\t */\n\t\th = DUK_TVAL_GET_STRING(tv_dst);\n\t} else {\n\t\th = duk_to_property_key_hstring(thr, idx);\n\t}\n\tDUK_ASSERT(h != NULL);\n\t*out_h = h;\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_FAST(h);\n\treturn arr_idx;\n}\n\nDUK_LOCAL duk_uint32_t duk__push_tval_to_property_key(duk_hthread *thr, duk_tval *tv_key, duk_hstring **out_h) {\n\tduk_push_tval(thr, tv_key);  /* XXX: could use an unsafe push here */\n\treturn duk__to_property_key(thr, -1, out_h);\n}\n\n/* String is an own (virtual) property of a plain buffer. */\nDUK_LOCAL duk_bool_t duk__key_is_plain_buf_ownprop(duk_hthread *thr, duk_hbuffer *buf, duk_hstring *key, duk_uint32_t arr_idx) {\n\tDUK_UNREF(thr);\n\n\t/* Virtual index properties.  Checking explicitly for\n\t * 'arr_idx != DUK__NO_ARRAY_INDEX' is not necessary\n\t * because DUK__NO_ARRAY_INDEXi is always larger than\n\t * maximum allowed buffer size.\n\t */\n\tDUK_ASSERT(DUK__NO_ARRAY_INDEX >= DUK_HBUFFER_GET_SIZE(buf));\n\tif (arr_idx < DUK_HBUFFER_GET_SIZE(buf)) {\n\t\treturn 1;\n\t}\n\n\t/* Other virtual properties. */\n\treturn (key == DUK_HTHREAD_STRING_LENGTH(thr));\n}\n\n/*\n *  Helpers for managing property storage size\n */\n\n/* Get default hash part size for a certain entry part size. */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\nDUK_LOCAL duk_uint32_t duk__get_default_h_size(duk_uint32_t e_size) {\n\tDUK_ASSERT(e_size <= DUK_HOBJECT_MAX_PROPERTIES);\n\n\tif (e_size >= DUK_USE_HOBJECT_HASH_PROP_LIMIT) {\n\t\tduk_uint32_t res;\n\t\tduk_uint32_t tmp;\n\n\t\t/* Hash size should be 2^N where N is chosen so that 2^N is\n\t\t * larger than e_size.  Extra shifting is used to ensure hash\n\t\t * is relatively sparse.\n\t\t */\n\t\ttmp = e_size;\n\t\tres = 2;  /* Result will be 2 ** (N + 1). */\n\t\twhile (tmp >= 0x40) {\n\t\t\ttmp >>= 6;\n\t\t\tres <<= 6;\n\t\t}\n\t\twhile (tmp != 0) {\n\t\t\ttmp >>= 1;\n\t\t\tres <<= 1;\n\t\t}\n\t\tDUK_ASSERT((DUK_HOBJECT_MAX_PROPERTIES << 2U) > DUK_HOBJECT_MAX_PROPERTIES);  /* Won't wrap, even shifted by 2. */\n\t\tDUK_ASSERT(res > e_size);\n\t\treturn res;\n\t} else {\n\t\treturn 0;\n\t}\n}\n#endif  /* USE_PROP_HASH_PART */\n\n/* Get minimum entry part growth for a certain size. */\nDUK_LOCAL duk_uint32_t duk__get_min_grow_e(duk_uint32_t e_size) {\n\tduk_uint32_t res;\n\n\tres = (e_size + DUK_USE_HOBJECT_ENTRY_MINGROW_ADD) / DUK_USE_HOBJECT_ENTRY_MINGROW_DIVISOR;\n\tDUK_ASSERT(res >= 1);  /* important for callers */\n\treturn res;\n}\n\n/* Get minimum array part growth for a certain size. */\nDUK_LOCAL duk_uint32_t duk__get_min_grow_a(duk_uint32_t a_size) {\n\tduk_uint32_t res;\n\n\tres = (a_size + DUK_USE_HOBJECT_ARRAY_MINGROW_ADD) / DUK_USE_HOBJECT_ARRAY_MINGROW_DIVISOR;\n\tDUK_ASSERT(res >= 1);  /* important for callers */\n\treturn res;\n}\n\n/* Count actually used entry part entries (non-NULL keys). */\nDUK_LOCAL duk_uint32_t duk__count_used_e_keys(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint_fast32_t i;\n\tduk_uint_fast32_t n = 0;\n\tduk_hstring **e;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(thr);\n\n\te = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, obj);\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tif (*e++) {\n\t\t\tn++;\n\t\t}\n\t}\n\treturn (duk_uint32_t) n;\n}\n\n/* Count actually used array part entries and array minimum size.\n * NOTE: 'out_min_size' can be computed much faster by starting from the\n * end and breaking out early when finding first used entry, but this is\n * not needed now.\n */\nDUK_LOCAL void duk__compute_a_stats(duk_hthread *thr, duk_hobject *obj, duk_uint32_t *out_used, duk_uint32_t *out_min_size) {\n\tduk_uint_fast32_t i;\n\tduk_uint_fast32_t used = 0;\n\tduk_uint_fast32_t highest_idx = (duk_uint_fast32_t) -1;  /* see below */\n\tduk_tval *a;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(out_used != NULL);\n\tDUK_ASSERT(out_min_size != NULL);\n\tDUK_UNREF(thr);\n\n\ta = DUK_HOBJECT_A_GET_BASE(thr->heap, obj);\n\tfor (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\tduk_tval *tv = a++;\n\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\tused++;\n\t\t\thighest_idx = i;\n\t\t}\n\t}\n\n\t/* Initial value for highest_idx is -1 coerced to unsigned.  This\n\t * is a bit odd, but (highest_idx + 1) will then wrap to 0 below\n\t * for out_min_size as intended.\n\t */\n\n\t*out_used = (duk_uint32_t) used;\n\t*out_min_size = (duk_uint32_t) (highest_idx + 1);  /* 0 if no used entries */\n}\n\n/* Check array density and indicate whether or not the array part should be abandoned. */\nDUK_LOCAL duk_bool_t duk__abandon_array_density_check(duk_uint32_t a_used, duk_uint32_t a_size) {\n\t/*\n\t *  Array abandon check; abandon if:\n\t *\n\t *    new_used / new_size < limit\n\t *    new_used < limit * new_size        || limit is 3 bits fixed point\n\t *    new_used < limit' / 8 * new_size   || *8\n\t *    8*new_used < limit' * new_size     || :8\n\t *    new_used < limit' * (new_size / 8)\n\t *\n\t *  Here, new_used = a_used, new_size = a_size.\n\t *\n\t *  Note: some callers use approximate values for a_used and/or a_size\n\t *  (e.g. dropping a '+1' term).  This doesn't affect the usefulness\n\t *  of the check, but may confuse debugging.\n\t */\n\n\treturn (a_used < DUK_USE_HOBJECT_ARRAY_ABANDON_LIMIT * (a_size >> 3));\n}\n\n/* Fast check for extending array: check whether or not a slow density check is required. */\nDUK_LOCAL duk_bool_t duk__abandon_array_slow_check_required(duk_uint32_t arr_idx, duk_uint32_t old_size) {\n\t/*\n\t *  In a fast check we assume old_size equals old_used (i.e., existing\n\t *  array is fully dense).\n\t *\n\t *  Slow check if:\n\t *\n\t *    (new_size - old_size) / old_size > limit\n\t *    new_size - old_size > limit * old_size\n\t *    new_size > (1 + limit) * old_size        || limit' is 3 bits fixed point\n\t *    new_size > (1 + (limit' / 8)) * old_size || * 8\n\t *    8 * new_size > (8 + limit') * old_size   || : 8\n\t *    new_size > (8 + limit') * (old_size / 8)\n\t *    new_size > limit'' * (old_size / 8)      || limit'' = 9 -> max 25% increase\n\t *    arr_idx + 1 > limit'' * (old_size / 8)\n\t *\n\t *  This check doesn't work well for small values, so old_size is rounded\n\t *  up for the check (and the '+ 1' of arr_idx can be ignored in practice):\n\t *\n\t *    arr_idx > limit'' * ((old_size + 7) / 8)\n\t */\n\n\treturn (arr_idx > DUK_USE_HOBJECT_ARRAY_FAST_RESIZE_LIMIT * ((old_size + 7) >> 3));\n}\n\nDUK_LOCAL duk_bool_t duk__abandon_array_check(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) {\n\tduk_uint32_t min_size;\n\tduk_uint32_t old_used;\n\tduk_uint32_t old_size;\n\n\tif (!duk__abandon_array_slow_check_required(arr_idx, DUK_HOBJECT_GET_ASIZE(obj))) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"=> fast resize is OK\"));\n\t\treturn 0;\n\t}\n\n\tduk__compute_a_stats(thr, obj, &old_used, &old_size);\n\n\tDUK_DDD(DUK_DDDPRINT(\"abandon check, array stats: old_used=%ld, old_size=%ld, arr_idx=%ld\",\n\t                     (long) old_used, (long) old_size, (long) arr_idx));\n\n\tmin_size = arr_idx + 1;\n#if defined(DUK_USE_OBJSIZES16)\n\tif (min_size > DUK_UINT16_MAX) {\n\t\tgoto do_abandon;\n\t}\n#endif\n\tDUK_UNREF(min_size);\n\n\t/* Note: intentionally use approximations to shave a few instructions:\n\t *   a_used = old_used  (accurate: old_used + 1)\n\t *   a_size = arr_idx   (accurate: arr_idx + 1)\n\t */\n\tif (duk__abandon_array_density_check(old_used, arr_idx)) {\n\t\tDUK_DD(DUK_DDPRINT(\"write to new array entry beyond current length, \"\n\t\t                   \"decided to abandon array part (would become too sparse)\"));\n\n\t\t/* Abandoning requires a props allocation resize and\n\t\t * 'rechecks' the valstack, invalidating any existing\n\t\t * valstack value pointers.\n\t\t */\n\t\tgoto do_abandon;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"=> decided to keep array part\"));\n\treturn 0;\n\n do_abandon:\n\tduk__abandon_array_part(thr, obj);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\treturn 1;\n}\n\nDUK_LOCAL duk_tval *duk__obtain_arridx_slot_slowpath(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) {\n\t/*\n\t *  Array needs to grow, but we don't want it becoming too sparse.\n\t *  If it were to become sparse, abandon array part, moving all\n\t *  array entries into the entries part (for good).\n\t *\n\t *  Since we don't keep track of actual density (used vs. size) of\n\t *  the array part, we need to estimate somehow.  The check is made\n\t *  in two parts:\n\t *\n\t *    - Check whether the resize need is small compared to the\n\t *      current size (relatively); if so, resize without further\n\t *      checking (essentially we assume that the original part is\n\t *      \"dense\" so that the result would be dense enough).\n\t *\n\t *    - Otherwise, compute the resize using an actual density\n\t *      measurement based on counting the used array entries.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"write to new array requires array resize, decide whether to do a \"\n\t                     \"fast resize without abandon check (arr_idx=%ld, old_size=%ld)\",\n\t                     (long) arr_idx, (long) DUK_HOBJECT_GET_ASIZE(obj)));\n\n\tif (DUK_UNLIKELY(duk__abandon_array_check(thr, arr_idx, obj) != 0)) {\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\treturn NULL;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"write to new array entry beyond current length, \"\n\t                   \"decided to extend current allocation\"));\n\n\t/* In principle it's possible to run out of memory extending the\n\t * array but with the allocation going through if we were to abandon\n\t * the array part and try again.  In practice this should be rare\n\t * because abandoned arrays have a higher per-entry footprint.\n\t */\n\n\tduk__grow_props_for_array_item(thr, obj, arr_idx);\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\tDUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(obj));\n\treturn DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n}\n\nDUK_LOCAL DUK_INLINE duk_tval *duk__obtain_arridx_slot(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) {\n\tif (DUK_LIKELY(arr_idx < DUK_HOBJECT_GET_ASIZE(obj))) {\n\t\treturn DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n\t} else {\n\t\treturn duk__obtain_arridx_slot_slowpath(thr, arr_idx, obj);\n\t}\n}\n\n/*\n *  Proxy helpers\n */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL duk_bool_t duk_hobject_proxy_check(duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler) {\n\tduk_hproxy *h_proxy;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(out_target != NULL);\n\tDUK_ASSERT(out_handler != NULL);\n\n\t/* Caller doesn't need to check exotic proxy behavior (but does so for\n\t * some fast paths).\n\t */\n\tif (DUK_LIKELY(!DUK_HOBJECT_IS_PROXY(obj))) {\n\t\treturn 0;\n\t}\n\th_proxy = (duk_hproxy *) obj;\n\tDUK_HPROXY_ASSERT_VALID(h_proxy);\n\n\tDUK_ASSERT(h_proxy->handler != NULL);\n\tDUK_ASSERT(h_proxy->target != NULL);\n\t*out_handler = h_proxy->handler;\n\t*out_target = h_proxy->target;\n\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n/* Get Proxy target object.  If the argument is not a Proxy, return it as is.\n * If a Proxy is revoked, an error is thrown.\n */\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL duk_hobject *duk_hobject_resolve_proxy_target(duk_hobject *obj) {\n\tDUK_ASSERT(obj != NULL);\n\n\t/* Resolve Proxy targets until Proxy chain ends.  No explicit check for\n\t * a Proxy loop: user code cannot create such a loop (it would only be\n\t * possible by editing duk_hproxy references directly).\n\t */\n\n\twhile (DUK_HOBJECT_IS_PROXY(obj)) {\n\t\tduk_hproxy *h_proxy;\n\n\t\th_proxy = (duk_hproxy *) obj;\n\t\tDUK_HPROXY_ASSERT_VALID(h_proxy);\n\t\tobj = h_proxy->target;\n\t\tDUK_ASSERT(obj != NULL);\n\t}\n\n\tDUK_ASSERT(obj != NULL);\n\treturn obj;\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_LOCAL duk_bool_t duk__proxy_check_prop(duk_hthread *thr, duk_hobject *obj, duk_small_uint_t stridx_trap, duk_tval *tv_key, duk_hobject **out_target) {\n\tduk_hobject *h_handler;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\tDUK_ASSERT(out_target != NULL);\n\n\tif (!duk_hobject_proxy_check(obj, out_target, &h_handler)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(*out_target != NULL);\n\tDUK_ASSERT(h_handler != NULL);\n\n\t/* XXX: At the moment Duktape accesses internal keys like _Finalizer using a\n\t * normal property set/get which would allow a proxy handler to interfere with\n\t * such behavior and to get access to internal key strings.  This is not a problem\n\t * as such because internal key strings can be created in other ways too (e.g.\n\t * through buffers).  The best fix is to change Duktape internal lookups to\n\t * skip proxy behavior.  Until that, internal property accesses bypass the\n\t * proxy and are applied to the target (as if the handler did not exist).\n\t * This has some side effects, see test-bi-proxy-internal-keys.js.\n\t */\n\n\tif (DUK_TVAL_IS_STRING(tv_key)) {\n\t\tduk_hstring *h_key = (duk_hstring *) DUK_TVAL_GET_STRING(tv_key);\n\t\tDUK_ASSERT(h_key != NULL);\n\t\tif (DUK_HSTRING_HAS_HIDDEN(h_key)) {\n\t\t\t/* Symbol accesses must go through proxy lookup in ES2015.\n\t\t\t * Hidden symbols behave like Duktape 1.x internal keys\n\t\t\t * and currently won't.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"hidden key, skip proxy handler and apply to target\"));\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* The handler is looked up with a normal property lookup; it may be an\n\t * accessor or the handler object itself may be a proxy object.  If the\n\t * handler is a proxy, we need to extend the valstack as we make a\n\t * recursive proxy check without a function call in between (in fact\n\t * there is no limit to the potential recursion here).\n\t *\n\t * (For sanity, proxy creation rejects another proxy object as either\n\t * the handler or the target at the moment so recursive proxy cases\n\t * are not realized now.)\n\t */\n\n\t/* XXX: C recursion limit if proxies are allowed as handler/target values */\n\n\tduk_require_stack(thr, DUK__VALSTACK_PROXY_LOOKUP);\n\tduk_push_hobject(thr, h_handler);\n\tif (duk_get_prop_stridx_short(thr, -1, stridx_trap)) {\n\t\t/* -> [ ... handler trap ] */\n\t\tduk_insert(thr, -2);  /* -> [ ... trap handler ] */\n\n\t\t/* stack prepped for func call: [ ... trap handler ] */\n\t\treturn 1;\n\t} else {\n\t\tduk_pop_2_unsafe(thr);\n\t\treturn 0;\n\t}\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n/*\n *  Reallocate property allocation, moving properties to the new allocation.\n *\n *  Includes key compaction, rehashing, and can also optionally abandon\n *  the array part, 'migrating' array entries into the beginning of the\n *  new entry part.\n *\n *  There is no support for in-place reallocation or just compacting keys\n *  without resizing the property allocation.  This is intentional to keep\n *  code size minimal, but would be useful future work.\n *\n *  The implementation is relatively straightforward, except for the array\n *  abandonment process.  Array abandonment requires that new string keys\n *  are interned, which may trigger GC.  All keys interned so far must be\n *  reachable for GC at all times and correctly refcounted for; valstack is\n *  used for that now.\n *\n *  Also, a GC triggered during this reallocation process must not interfere\n *  with the object being resized.  This is currently controlled by preventing\n *  finalizers (as they may affect ANY object) and object compaction in\n *  mark-and-sweep.  It would suffice to protect only this particular object\n *  from compaction, however.  DECREF refzero cascades are side effect free\n *  and OK.\n *\n *  Note: because we need to potentially resize the valstack (as part\n *  of abandoning the array part), any tval pointers to the valstack\n *  will become invalid after this call.\n */\n\nDUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,\n                                            duk_hobject *obj,\n                                            duk_uint32_t new_e_size,\n                                            duk_uint32_t new_a_size,\n                                            duk_uint32_t new_h_size,\n                                            duk_bool_t abandon_array) {\n\tduk_small_uint_t prev_ms_base_flags;\n\tduk_uint32_t new_alloc_size;\n\tduk_uint32_t new_e_size_adjusted;\n\tduk_uint8_t *new_p;\n\tduk_hstring **new_e_k;\n\tduk_propvalue *new_e_pv;\n\tduk_uint8_t *new_e_f;\n\tduk_tval *new_a;\n\tduk_uint32_t *new_h;\n\tduk_uint32_t new_e_next;\n\tduk_uint_fast32_t i;\n\tduk_size_t array_copy_size;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_bool_t prev_error_not_allowed;\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(!abandon_array || new_a_size == 0);  /* if abandon_array, new_a_size must be 0 */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL || (DUK_HOBJECT_GET_ESIZE(obj) == 0 && DUK_HOBJECT_GET_ASIZE(obj) == 0));\n\tDUK_ASSERT(new_h_size == 0 || new_h_size >= new_e_size);  /* required to guarantee success of rehashing,\n\t                                                           * intentionally use unadjusted new_e_size\n\t                                                           */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_object_realloc_props);\n\n\t/*\n\t *  Pre resize assertions.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* XXX: pre-checks (such as no duplicate keys) */\n#endif\n\n\t/*\n\t *  For property layout 1, tweak e_size to ensure that the whole entry\n\t *  part (key + val + flags) is a suitable multiple for alignment\n\t *  (platform specific).\n\t *\n\t *  Property layout 2 does not require this tweaking and is preferred\n\t *  on low RAM platforms requiring alignment.\n\t */\n\n#if defined(DUK_USE_HOBJECT_LAYOUT_2) || defined(DUK_USE_HOBJECT_LAYOUT_3)\n\tDUK_DDD(DUK_DDDPRINT(\"using layout 2 or 3, no need to pad e_size: %ld\", (long) new_e_size));\n\tnew_e_size_adjusted = new_e_size;\n#elif defined(DUK_USE_HOBJECT_LAYOUT_1) && (DUK_HOBJECT_ALIGN_TARGET == 1)\n\tDUK_DDD(DUK_DDDPRINT(\"using layout 1, but no need to pad e_size: %ld\", (long) new_e_size));\n\tnew_e_size_adjusted = new_e_size;\n#elif defined(DUK_USE_HOBJECT_LAYOUT_1) && ((DUK_HOBJECT_ALIGN_TARGET == 4) || (DUK_HOBJECT_ALIGN_TARGET == 8))\n\tnew_e_size_adjusted = (new_e_size + (duk_uint32_t) DUK_HOBJECT_ALIGN_TARGET - 1U) &\n\t                      (~((duk_uint32_t) DUK_HOBJECT_ALIGN_TARGET - 1U));\n\tDUK_DDD(DUK_DDDPRINT(\"using layout 1, and alignment target is %ld, adjusted e_size: %ld -> %ld\",\n\t                     (long) DUK_HOBJECT_ALIGN_TARGET, (long) new_e_size, (long) new_e_size_adjusted));\n\tDUK_ASSERT(new_e_size_adjusted >= new_e_size);\n#else\n#error invalid hobject layout defines\n#endif\n\n\t/*\n\t *  Debug logging after adjustment.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"attempt to resize hobject %p props (%ld -> %ld bytes), from {p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld} to \"\n\t                     \"{e_size=%ld,a_size=%ld,h_size=%ld}, abandon_array=%ld, unadjusted new_e_size=%ld\",\n\t                     (void *) obj,\n\t                     (long) DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t                                                       DUK_HOBJECT_GET_ASIZE(obj),\n\t                                                       DUK_HOBJECT_GET_HSIZE(obj)),\n\t                     (long) DUK_HOBJECT_P_COMPUTE_SIZE(new_e_size_adjusted, new_a_size, new_h_size),\n\t                     (void *) DUK_HOBJECT_GET_PROPS(thr->heap, obj),\n\t                     (long) DUK_HOBJECT_GET_ESIZE(obj),\n\t                     (long) DUK_HOBJECT_GET_ENEXT(obj),\n\t                     (long) DUK_HOBJECT_GET_ASIZE(obj),\n\t                     (long) DUK_HOBJECT_GET_HSIZE(obj),\n\t                     (long) new_e_size_adjusted,\n\t                     (long) new_a_size,\n\t                     (long) new_h_size,\n\t                     (long) abandon_array,\n\t                     (long) new_e_size));\n\n\t/*\n\t *  Property count check.  This is the only point where we ensure that\n\t *  we don't get more (allocated) property space that we can handle.\n\t *  There aren't hard limits as such, but some algorithms may fail\n\t *  if we get too close to the 4G property limit.\n\t *\n\t *  Since this works based on allocation size (not actually used size),\n\t *  the limit is a bit approximate but good enough in practice.\n\t */\n\n\tif (new_e_size_adjusted + new_a_size > DUK_HOBJECT_MAX_PROPERTIES) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size_adjusted > DUK_UINT16_MAX || new_a_size > DUK_UINT16_MAX) {\n\t\t/* If caller gave us sizes larger than what we can store,\n\t\t * fail memory safely with an internal error rather than\n\t\t * truncating the sizes.\n\t\t */\n\t\tDUK_ERROR_INTERNAL(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\t/*\n\t *  Compute new alloc size and alloc new area.\n\t *\n\t *  The new area is not tracked in the heap at all, so it's critical\n\t *  we get to free/keep it in a controlled manner.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Whole path must be error throw free, but we may be called from\n\t * within error handling so can't assert for error_not_allowed == 0.\n\t */\n\tprev_error_not_allowed = thr->heap->error_not_allowed;\n\tthr->heap->error_not_allowed = 1;\n#endif\n\tprev_ms_base_flags = thr->heap->ms_base_flags;\n\tthr->heap->ms_base_flags |=\n\t        DUK_MS_FLAG_NO_OBJECT_COMPACTION;      /* Avoid attempt to compact the current object (all objects really). */\n\tthr->heap->pf_prevent_count++;                 /* Avoid finalizers. */\n\tDUK_ASSERT(thr->heap->pf_prevent_count != 0);  /* Wrap. */\n\n\tnew_alloc_size = DUK_HOBJECT_P_COMPUTE_SIZE(new_e_size_adjusted, new_a_size, new_h_size);\n\tDUK_DDD(DUK_DDDPRINT(\"new hobject allocation size is %ld\", (long) new_alloc_size));\n\tif (new_alloc_size == 0) {\n\t\tDUK_ASSERT(new_e_size_adjusted == 0);\n\t\tDUK_ASSERT(new_a_size == 0);\n\t\tDUK_ASSERT(new_h_size == 0);\n\t\tnew_p = NULL;\n\t} else {\n\t\t/* Alloc may trigger mark-and-sweep but no compaction, and\n\t\t * cannot throw.\n\t\t */\n#if 0  /* XXX: inject test */\n\t\tif (1) {\n\t\t\tnew_p = NULL;\n\t\t\tgoto alloc_failed;\n\t\t}\n#endif\n\t\tnew_p = (duk_uint8_t *) DUK_ALLOC(thr->heap, new_alloc_size);\n\t\tif (new_p == NULL) {\n\t\t\t/* NULL always indicates alloc failure because\n\t\t\t * new_alloc_size > 0.\n\t\t\t */\n\t\t\tgoto alloc_failed;\n\t\t}\n\t}\n\n\t/* Set up pointers to the new property area: this is hidden behind a macro\n\t * because it is memory layout specific.\n\t */\n\tDUK_HOBJECT_P_SET_REALLOC_PTRS(new_p, new_e_k, new_e_pv, new_e_f, new_a, new_h,\n\t                               new_e_size_adjusted, new_a_size, new_h_size);\n\tDUK_UNREF(new_h);  /* happens when hash part dropped */\n\tnew_e_next = 0;\n\n\t/* if new_p == NULL, all of these pointers are NULL */\n\tDUK_ASSERT((new_p != NULL) ||\n\t           (new_e_k == NULL && new_e_pv == NULL && new_e_f == NULL &&\n\t            new_a == NULL && new_h == NULL));\n\n\tDUK_DDD(DUK_DDDPRINT(\"new alloc size %ld, new_e_k=%p, new_e_pv=%p, new_e_f=%p, new_a=%p, new_h=%p\",\n\t                     (long) new_alloc_size, (void *) new_e_k, (void *) new_e_pv, (void *) new_e_f,\n\t                     (void *) new_a, (void *) new_h));\n\n\t/*\n\t *  Migrate array part to start of entries if requested.\n\t *\n\t *  Note: from an enumeration perspective the order of entry keys matters.\n\t *  Array keys should appear wherever they appeared before the array abandon\n\t *  operation.  (This no longer matters much because keys are ES2015 sorted.)\n\t */\n\n\tif (abandon_array) {\n\t\t/* Assuming new_a_size == 0, and that entry part contains\n\t\t * no conflicting keys, refcounts do not need to be adjusted for\n\t\t * the values, as they remain exactly the same.\n\t\t *\n\t\t * The keys, however, need to be interned, incref'd, and be\n\t\t * reachable for GC.  Any intern attempt may trigger a GC and\n\t\t * claim any non-reachable strings, so every key must be reachable\n\t\t * at all times.  Refcounts must be correct to satisfy refcount\n\t\t * assertions.\n\t\t *\n\t\t * A longjmp must not occur here, as the new_p allocation would\n\t\t * leak.  Refcounts would come out correctly as the interned\n\t\t * strings are valstack tracked.\n\t\t */\n\t\tDUK_ASSERT(new_a_size == 0);\n\n\t\tDUK_STATS_INC(thr->heap, stats_object_abandon_array);\n\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_tval *tv2;\n\t\t\tduk_hstring *key;\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);\n\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\t\tif (DUK_TVAL_IS_UNUSED(tv1)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(new_p != NULL && new_e_k != NULL &&\n\t\t\t           new_e_pv != NULL && new_e_f != NULL);\n\n\t\t\t/*\n\t\t\t *  Intern key via the valstack to ensure reachability behaves\n\t\t\t *  properly.  We must avoid longjmp's here so use non-checked\n\t\t\t *  primitives.\n\t\t\t *\n\t\t\t *  Note: duk_check_stack() potentially reallocs the valstack,\n\t\t\t *  invalidating any duk_tval pointers to valstack.  Callers\n\t\t\t *  must be careful.\n\t\t\t */\n\n#if 0  /* XXX: inject test */\n\t\t\tif (1) {\n\t\t\t\tgoto abandon_error;\n\t\t\t}\n#endif\n\t\t\t/* Never shrinks; auto-adds DUK_VALSTACK_INTERNAL_EXTRA, which\n\t\t\t * is generous.\n\t\t\t */\n\t\t\tif (!duk_check_stack(thr, 1)) {\n\t\t\t\tgoto abandon_error;\n\t\t\t}\n\t\t\tDUK_ASSERT_VALSTACK_SPACE(thr, 1);\n\t\t\tkey = duk_heap_strtable_intern_u32(thr->heap, (duk_uint32_t) i);\n\t\t\tif (key == NULL) {\n\t\t\t\tgoto abandon_error;\n\t\t\t}\n\t\t\tduk_push_hstring(thr, key);  /* keep key reachable for GC etc; guaranteed not to fail */\n\n\t\t\t/* Key is now reachable in the valstack, don't INCREF\n\t\t\t * the new allocation yet (we'll steal the refcounts\n\t\t\t * from the value stack once all keys are done).\n\t\t\t */\n\n\t\t\tnew_e_k[new_e_next] = key;\n\t\t\ttv2 = &new_e_pv[new_e_next].v;  /* array entries are all plain values */\n\t\t\tDUK_TVAL_SET_TVAL(tv2, tv1);\n\t\t\tnew_e_f[new_e_next] = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t                      DUK_PROPDESC_FLAG_ENUMERABLE |\n\t\t\t                      DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\tnew_e_next++;\n\n\t\t\t/* Note: new_e_next matches pushed temp key count, and nothing can\n\t\t\t * fail above between the push and this point.\n\t\t\t */\n\t\t}\n\n\t\t/* Steal refcounts from value stack. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"abandon array: pop %ld key temps from valstack\", (long) new_e_next));\n\t\tduk_pop_n_nodecref_unsafe(thr, (duk_idx_t) new_e_next);\n\t}\n\n\t/*\n\t *  Copy keys and values in the entry part (compacting them at the same time).\n\t */\n\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tduk_hstring *key;\n\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);\n\n\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);\n\t\tif (key == NULL) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_ASSERT(new_p != NULL && new_e_k != NULL &&\n\t\t           new_e_pv != NULL && new_e_f != NULL);\n\n\t\tnew_e_k[new_e_next] = key;\n\t\tnew_e_pv[new_e_next] = DUK_HOBJECT_E_GET_VALUE(thr->heap, obj, i);\n\t\tnew_e_f[new_e_next] = DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, i);\n\t\tnew_e_next++;\n\t}\n\t/* the entries [new_e_next, new_e_size_adjusted[ are left uninitialized on purpose (ok, not gc reachable) */\n\n\t/*\n\t *  Copy array elements to new array part.  If the new array part is\n\t *  larger, initialize the unused entries as UNUSED because they are\n\t *  GC reachable.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Caller must have decref'd values above new_a_size (if that is necessary). */\n\tif (!abandon_array) {\n\t\tfor (i = new_a_size; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\t\tduk_tval *tv;\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv));\n\t\t}\n\t}\n#endif\n\tif (new_a_size > DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\tarray_copy_size = sizeof(duk_tval) * DUK_HOBJECT_GET_ASIZE(obj);\n\t} else {\n\t\tarray_copy_size = sizeof(duk_tval) * new_a_size;\n\t}\n\n\tDUK_ASSERT(new_a != NULL || array_copy_size == 0U);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL || array_copy_size == 0U);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) > 0 || array_copy_size == 0U);\n\tduk_memcpy_unsafe((void *) new_a,\n\t                  (const void *) DUK_HOBJECT_A_GET_BASE(thr->heap, obj),\n\t                  array_copy_size);\n\n\tfor (i = DUK_HOBJECT_GET_ASIZE(obj); i < new_a_size; i++) {\n\t\tduk_tval *tv = &new_a[i];\n\t\tDUK_TVAL_SET_UNUSED(tv);\n\t}\n\n\t/*\n\t *  Rebuild the hash part always from scratch (guaranteed to finish\n\t *  as long as caller gave consistent parameters).\n\t *\n\t *  Any resize of hash part requires rehashing.  In addition, by rehashing\n\t *  get rid of any elements marked deleted (DUK__HASH_DELETED) which is critical\n\t *  to ensuring the hash part never fills up.\n\t */\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (new_h_size == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"no hash part, no rehash\"));\n\t} else {\n\t\tduk_uint32_t mask;\n\n\t\tDUK_ASSERT(new_h != NULL);\n\n\t\t/* fill new_h with u32 0xff = UNUSED */\n\t\tDUK_ASSERT(new_h_size > 0);\n\t\tduk_memset(new_h, 0xff, sizeof(duk_uint32_t) * new_h_size);\n\n\t\tDUK_ASSERT(new_e_next <= new_h_size);  /* equality not actually possible */\n\n\t\tmask = new_h_size - 1;\n\t\tfor (i = 0; i < new_e_next; i++) {\n\t\t\tduk_hstring *key = new_e_k[i];\n\t\t\tduk_uint32_t j, step;\n\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tj = DUK_HSTRING_GET_HASH(key) & mask;\n\t\t\tstep = 1;  /* Cache friendly but clustering prone. */\n\n\t\t\tfor (;;) {\n\t\t\t\tDUK_ASSERT(new_h[j] != DUK__HASH_DELETED);  /* should never happen */\n\t\t\t\tif (new_h[j] == DUK__HASH_UNUSED) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rebuild hit %ld -> %ld\", (long) j, (long) i));\n\t\t\t\t\tnew_h[j] = (duk_uint32_t) i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rebuild miss %ld, step %ld\", (long) j, (long) step));\n\t\t\t\tj = (j + step) & mask;\n\n\t\t\t\t/* Guaranteed to finish (hash is larger than #props). */\n\t\t\t}\n\t\t}\n\t}\n#endif  /* DUK_USE_HOBJECT_HASH_PART */\n\n\t/*\n\t *  Nice debug log.\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"resized hobject %p props (%ld -> %ld bytes), from {p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld} to \"\n\t                   \"{p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld}, abandon_array=%ld, unadjusted new_e_size=%ld\",\n\t                   (void *) obj,\n\t                   (long) DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t                                                     DUK_HOBJECT_GET_ASIZE(obj),\n\t                                                     DUK_HOBJECT_GET_HSIZE(obj)),\n\t                   (long) new_alloc_size,\n\t                   (void *) DUK_HOBJECT_GET_PROPS(thr->heap, obj),\n\t                   (long) DUK_HOBJECT_GET_ESIZE(obj),\n\t                   (long) DUK_HOBJECT_GET_ENEXT(obj),\n\t                   (long) DUK_HOBJECT_GET_ASIZE(obj),\n\t                   (long) DUK_HOBJECT_GET_HSIZE(obj),\n\t                   (void *) new_p,\n\t                   (long) new_e_size_adjusted,\n\t                   (long) new_e_next,\n\t                   (long) new_a_size,\n\t                   (long) new_h_size,\n\t                   (long) abandon_array,\n\t                   (long) new_e_size));\n\n\t/*\n\t *  All done, switch properties ('p') allocation to new one.\n\t */\n\n\tDUK_FREE_CHECKED(thr, DUK_HOBJECT_GET_PROPS(thr->heap, obj));  /* NULL obj->p is OK */\n\tDUK_HOBJECT_SET_PROPS(thr->heap, obj, new_p);\n\tDUK_HOBJECT_SET_ESIZE(obj, new_e_size_adjusted);\n\tDUK_HOBJECT_SET_ENEXT(obj, new_e_next);\n\tDUK_HOBJECT_SET_ASIZE(obj, new_a_size);\n\tDUK_HOBJECT_SET_HSIZE(obj, new_h_size);\n\n\t/* Clear array part flag only after switching. */\n\tif (abandon_array) {\n\t\tDUK_HOBJECT_CLEAR_ARRAY_PART(obj);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"resize result: %!O\", (duk_heaphdr *) obj));\n\n\tDUK_ASSERT(thr->heap->pf_prevent_count > 0);\n\tthr->heap->pf_prevent_count--;\n\tthr->heap->ms_base_flags = prev_ms_base_flags;\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->heap->error_not_allowed == 1);\n\tthr->heap->error_not_allowed = prev_error_not_allowed;\n#endif\n\n\t/*\n\t *  Post resize assertions.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* XXX: post-checks (such as no duplicate keys) */\n#endif\n\treturn;\n\n\t/*\n\t *  Abandon array failed.  We don't need to DECREF anything\n\t *  because the references in the new allocation are not\n\t *  INCREF'd until abandon is complete.  The string interned\n\t *  keys are on the value stack and are handled normally by\n\t *  unwind.\n\t */\n\n abandon_error:\n alloc_failed:\n\tDUK_D(DUK_DPRINT(\"object property table resize failed\"));\n\n\tDUK_FREE_CHECKED(thr, new_p);  /* OK for NULL. */\n\n\tthr->heap->pf_prevent_count--;\n\tthr->heap->ms_base_flags = prev_ms_base_flags;\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->heap->error_not_allowed == 1);\n\tthr->heap->error_not_allowed = prev_error_not_allowed;\n#endif\n\n\tDUK_ERROR_ALLOC_FAILED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Helpers to resize properties allocation on specific needs.\n */\n\nDUK_INTERNAL void duk_hobject_resize_entrypart(duk_hthread *thr,\n                                               duk_hobject *obj,\n                                               duk_uint32_t new_e_size) {\n\tduk_uint32_t old_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_h_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\told_e_size = DUK_HOBJECT_GET_ESIZE(obj);\n\tif (old_e_size > new_e_size) {\n\t\tnew_e_size = old_e_size;\n\t}\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tnew_h_size = duk__get_default_h_size(new_e_size);\n#else\n\tnew_h_size = 0;\n#endif\n\tnew_a_size = DUK_HOBJECT_GET_ASIZE(obj);\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);\n}\n\n/* Grow entry part allocation for one additional entry. */\nDUK_LOCAL void duk__grow_props_for_new_entry_item(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint32_t old_e_used;  /* actually used, non-NULL entries */\n\tduk_uint32_t new_e_size_minimum;\n\tduk_uint32_t new_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_h_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\t/* Duktape 0.11.0 and prior tried to optimize the resize by not\n\t * counting the number of actually used keys prior to the resize.\n\t * This worked mostly well but also caused weird leak-like behavior\n\t * as in: test-bug-object-prop-alloc-unbounded.js.  So, now we count\n\t * the keys explicitly to compute the new entry part size.\n\t */\n\n\told_e_used = duk__count_used_e_keys(thr, obj);\n\tnew_e_size_minimum = old_e_used + 1;\n\tnew_e_size = old_e_used + duk__get_min_grow_e(old_e_used);\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tnew_h_size = duk__get_default_h_size(new_e_size);\n#else\n\tnew_h_size = 0;\n#endif\n\tnew_a_size = DUK_HOBJECT_GET_ASIZE(obj);\n\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size > DUK_UINT16_MAX) {\n\t\tnew_e_size = DUK_UINT16_MAX;\n\t}\n\tif (new_h_size > DUK_UINT16_MAX) {\n\t\tnew_h_size = DUK_UINT16_MAX;\n\t}\n\tif (new_a_size > DUK_UINT16_MAX) {\n\t\tnew_a_size = DUK_UINT16_MAX;\n\t}\n#endif\n\tDUK_ASSERT(new_h_size == 0 || new_h_size >= new_e_size);\n\n\tif (!(new_e_size >= new_e_size_minimum)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);\n}\n\n/* Grow array part for a new highest array index. */\nDUK_LOCAL void duk__grow_props_for_array_item(duk_hthread *thr, duk_hobject *obj, duk_uint32_t highest_arr_idx) {\n\tduk_uint32_t new_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_a_size_minimum;\n\tduk_uint32_t new_h_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(highest_arr_idx >= DUK_HOBJECT_GET_ASIZE(obj));\n\n\tnew_e_size = DUK_HOBJECT_GET_ESIZE(obj);\n\tnew_h_size = DUK_HOBJECT_GET_HSIZE(obj);\n\tnew_a_size_minimum = highest_arr_idx + 1;\n\tnew_a_size = highest_arr_idx + duk__get_min_grow_a(highest_arr_idx);\n\tDUK_ASSERT(new_a_size >= highest_arr_idx + 1);  /* duk__get_min_grow_a() is always >= 1 */\n\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size > DUK_UINT16_MAX) {\n\t\tnew_e_size = DUK_UINT16_MAX;\n\t}\n\tif (new_h_size > DUK_UINT16_MAX) {\n\t\tnew_h_size = DUK_UINT16_MAX;\n\t}\n\tif (new_a_size > DUK_UINT16_MAX) {\n\t\tnew_a_size = DUK_UINT16_MAX;\n\t}\n#endif\n\n\tif (!(new_a_size >= new_a_size_minimum)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);\n}\n\n/* Abandon array part, moving array entries into entries part.\n * This requires a props resize, which is a heavy operation.\n * We also compact the entries part while we're at it, although\n * this is not strictly required.\n */\nDUK_LOCAL void duk__abandon_array_part(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint32_t new_e_size_minimum;\n\tduk_uint32_t new_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_h_size;\n\tduk_uint32_t e_used;  /* actually used, non-NULL keys */\n\tduk_uint32_t a_used;\n\tduk_uint32_t a_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\te_used = duk__count_used_e_keys(thr, obj);\n\tduk__compute_a_stats(thr, obj, &a_used, &a_size);\n\n\t/*\n\t *  Must guarantee all actually used array entries will fit into\n\t *  new entry part.  Add one growth step to ensure we don't run out\n\t *  of space right away.\n\t */\n\n\tnew_e_size_minimum = e_used + a_used;\n\tnew_e_size = new_e_size_minimum + duk__get_min_grow_e(new_e_size_minimum);\n\tnew_a_size = 0;\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tnew_h_size = duk__get_default_h_size(new_e_size);\n#else\n\tnew_h_size = 0;\n#endif\n\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size > DUK_UINT16_MAX) {\n\t\tnew_e_size = DUK_UINT16_MAX;\n\t}\n\tif (new_h_size > DUK_UINT16_MAX) {\n\t\tnew_h_size = DUK_UINT16_MAX;\n\t}\n\tif (new_a_size > DUK_UINT16_MAX) {\n\t\tnew_a_size = DUK_UINT16_MAX;\n\t}\n#endif\n\n\tif (!(new_e_size >= new_e_size_minimum)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"abandon array part for hobject %p, \"\n\t                   \"array stats before: e_used=%ld, a_used=%ld, a_size=%ld; \"\n\t                   \"resize to e_size=%ld, a_size=%ld, h_size=%ld\",\n\t                   (void *) obj, (long) e_used, (long) a_used, (long) a_size,\n\t                   (long) new_e_size, (long) new_a_size, (long) new_h_size));\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 1);\n}\n\n/*\n *  Compact an object.  Minimizes allocation size for objects which are\n *  not likely to be extended.  This is useful for internal and non-\n *  extensible objects, but can also be called for non-extensible objects.\n *  May abandon the array part if it is computed to be too sparse.\n *\n *  This call is relatively expensive, as it needs to scan both the\n *  entries and the array part.\n *\n *  The call may fail due to allocation error.\n */\n\nDUK_INTERNAL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint32_t e_size;       /* currently used -> new size */\n\tduk_uint32_t a_size;       /* currently required */\n\tduk_uint32_t a_used;       /* actually used */\n\tduk_uint32_t h_size;\n\tduk_bool_t abandon_array;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"ignore attempt to compact a rom object\"));\n\t\treturn;\n\t}\n#endif\n\n\te_size = duk__count_used_e_keys(thr, obj);\n\tduk__compute_a_stats(thr, obj, &a_used, &a_size);\n\n\tDUK_DD(DUK_DDPRINT(\"compacting hobject, used e keys %ld, used a keys %ld, min a size %ld, \"\n\t                   \"resized array density would be: %ld/%ld = %lf\",\n\t                   (long) e_size, (long) a_used, (long) a_size,\n\t                   (long) a_used, (long) a_size,\n\t                   (double) a_used / (double) a_size));\n\n\tif (duk__abandon_array_density_check(a_used, a_size)) {\n\t\tDUK_DD(DUK_DDPRINT(\"decided to abandon array during compaction, a_used=%ld, a_size=%ld\",\n\t\t                   (long) a_used, (long) a_size));\n\t\tabandon_array = 1;\n\t\te_size += a_used;\n\t\ta_size = 0;\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"decided to keep array during compaction\"));\n\t\tabandon_array = 0;\n\t}\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (e_size >= DUK_USE_HOBJECT_HASH_PROP_LIMIT) {\n\t\th_size = duk__get_default_h_size(e_size);\n\t} else {\n\t\th_size = 0;\n\t}\n#else\n\th_size = 0;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"compacting hobject -> new e_size %ld, new a_size=%ld, new h_size=%ld, abandon_array=%ld\",\n\t                   (long) e_size, (long) a_size, (long) h_size, (long) abandon_array));\n\n\tduk_hobject_realloc_props(thr, obj, e_size, a_size, h_size, abandon_array);\n}\n\n/*\n *  Find an existing key from entry part either by linear scan or by\n *  using the hash index (if it exists).\n *\n *  Sets entry index (and possibly the hash index) to output variables,\n *  which allows the caller to update the entry and hash entries in-place.\n *  If entry is not found, both values are set to -1.  If entry is found\n *  but there is no hash part, h_idx is set to -1.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_find_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx) {\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(e_idx != NULL);\n\tDUK_ASSERT(h_idx != NULL);\n\tDUK_UNREF(heap);\n\n\tif (DUK_LIKELY(DUK_HOBJECT_GET_HSIZE(obj) == 0))\n\t{\n\t\t/* Linear scan: more likely because most objects are small.\n\t\t * This is an important fast path.\n\t\t *\n\t\t * XXX: this might be worth inlining for property lookups.\n\t\t */\n\t\tduk_uint_fast32_t i;\n\t\tduk_uint_fast32_t n;\n\t\tduk_hstring **h_keys_base;\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk_hobject_find_entry() using linear scan for lookup\"));\n\n\t\th_keys_base = DUK_HOBJECT_E_GET_KEY_BASE(heap, obj);\n\t\tn = DUK_HOBJECT_GET_ENEXT(obj);\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tif (h_keys_base[i] == key) {\n\t\t\t\t*e_idx = (duk_int_t) i;\n\t\t\t\t*h_idx = -1;\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t}\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\telse\n\t{\n\t\t/* hash lookup */\n\t\tduk_uint32_t n;\n\t\tduk_uint32_t i, step;\n\t\tduk_uint32_t *h_base;\n\t\tduk_uint32_t mask;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk_hobject_find_entry() using hash part for lookup\"));\n\n\t\th_base = DUK_HOBJECT_H_GET_BASE(heap, obj);\n\t\tn = DUK_HOBJECT_GET_HSIZE(obj);\n\t\tmask = n - 1;\n\t\ti = DUK_HSTRING_GET_HASH(key) & mask;\n\t\tstep = 1;  /* Cache friendly but clustering prone. */\n\n\t\tfor (;;) {\n\t\t\tduk_uint32_t t;\n\n\t\t\tDUK_ASSERT_DISABLE(i >= 0);  /* unsigned */\n\t\t\tDUK_ASSERT(i < DUK_HOBJECT_GET_HSIZE(obj));\n\t\t\tt = h_base[i];\n\t\t\tDUK_ASSERT(t == DUK__HASH_UNUSED || t == DUK__HASH_DELETED ||\n\t\t\t           (t < DUK_HOBJECT_GET_ESIZE(obj)));  /* t >= 0 always true, unsigned */\n\n\t\t\tif (t == DUK__HASH_UNUSED) {\n\t\t\t\tbreak;\n\t\t\t} else if (t == DUK__HASH_DELETED) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"lookup miss (deleted) i=%ld, t=%ld\",\n\t\t\t\t                     (long) i, (long) t));\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(t < DUK_HOBJECT_GET_ESIZE(obj));\n\t\t\t\tif (DUK_HOBJECT_E_GET_KEY(heap, obj, t) == key) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"lookup hit i=%ld, t=%ld -> key %p\",\n\t\t\t\t\t                     (long) i, (long) t, (void *) key));\n\t\t\t\t\t*e_idx = (duk_int_t) t;\n\t\t\t\t\t*h_idx = (duk_int_t) i;\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"lookup miss i=%ld, t=%ld\",\n\t\t\t\t                     (long) i, (long) t));\n\t\t\t}\n\t\t\ti = (i + step) & mask;\n\n\t\t\t/* Guaranteed to finish (hash is larger than #props). */\n\t\t}\n\t}\n#endif  /* DUK_USE_HOBJECT_HASH_PART */\n\n\t/* Not found, leave e_idx and h_idx unset. */\n\treturn 0;\n}\n\n/* For internal use: get non-accessor entry value */\nDUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key) {\n\tduk_int_t e_idx;\n\tduk_int_t h_idx;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_UNREF(heap);\n\n\tif (duk_hobject_find_entry(heap, obj, key, &e_idx, &h_idx)) {\n\t\tDUK_ASSERT(e_idx >= 0);\n\t\tif (!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {\n\t\t\treturn DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);\n\t\t}\n\t}\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx) {\n\treturn duk_hobject_find_entry_tval_ptr(heap, obj, DUK_HEAP_GET_STRING(heap, stridx));\n}\n\n/* For internal use: get non-accessor entry value and attributes */\nDUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs) {\n\tduk_int_t e_idx;\n\tduk_int_t h_idx;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_attrs != NULL);\n\tDUK_UNREF(heap);\n\n\tif (duk_hobject_find_entry(heap, obj, key, &e_idx, &h_idx)) {\n\t\tDUK_ASSERT(e_idx >= 0);\n\t\tif (!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {\n\t\t\t*out_attrs = DUK_HOBJECT_E_GET_FLAGS(heap, obj, e_idx);\n\t\t\treturn DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);\n\t\t}\n\t}\n\t/* If not found, out_attrs is left unset. */\n\treturn NULL;\n}\n\n/* For internal use: get array part value */\nDUK_INTERNAL duk_tval *duk_hobject_find_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(heap);\n\n\tif (!DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\treturn NULL;\n\t}\n\tif (i >= DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\treturn NULL;\n\t}\n\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(heap, obj, i);\n\treturn tv;\n}\n\n/*\n *  Allocate and initialize a new entry, resizing the properties allocation\n *  if necessary.  Returns entry index (e_idx) or throws an error if alloc fails.\n *\n *  Sets the key of the entry (increasing the key's refcount), and updates\n *  the hash part if it exists.  Caller must set value and flags, and update\n *  the entry value refcount.  A decref for the previous value is not necessary.\n */\n\nDUK_LOCAL duk_int_t duk__hobject_alloc_entry_checked(duk_hthread *thr, duk_hobject *obj, duk_hstring *key) {\n\tduk_uint32_t idx;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(obj) <= DUK_HOBJECT_GET_ESIZE(obj));\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* key must not already exist in entry part */\n\t{\n\t\tduk_uint_fast32_t i;\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != key);\n\t\t}\n\t}\n#endif\n\n\tif (DUK_HOBJECT_GET_ENEXT(obj) >= DUK_HOBJECT_GET_ESIZE(obj)) {\n\t\t/* only need to guarantee 1 more slot, but allocation growth is in chunks */\n\t\tDUK_DDD(DUK_DDDPRINT(\"entry part full, allocate space for one more entry\"));\n\t\tduk__grow_props_for_new_entry_item(thr, obj);\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(obj) < DUK_HOBJECT_GET_ESIZE(obj));\n\tidx = DUK_HOBJECT_POSTINC_ENEXT(obj);\n\n\t/* previous value is assumed to be garbage, so don't touch it */\n\tDUK_HOBJECT_E_SET_KEY(thr->heap, obj, idx, key);\n\tDUK_HSTRING_INCREF(thr, key);\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (DUK_UNLIKELY(DUK_HOBJECT_GET_HSIZE(obj) > 0)) {\n\t\tduk_uint32_t n, mask;\n\t\tduk_uint32_t i, step;\n\t\tduk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(thr->heap, obj);\n\n\t\tn = DUK_HOBJECT_GET_HSIZE(obj);\n\t\tmask = n - 1;\n\t\ti = DUK_HSTRING_GET_HASH(key) & mask;\n\t\tstep = 1;  /* Cache friendly but clustering prone. */\n\n\t\tfor (;;) {\n\t\t\tduk_uint32_t t = h_base[i];\n\t\t\tif (t == DUK__HASH_UNUSED || t == DUK__HASH_DELETED) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__hobject_alloc_entry_checked() inserted key into hash part, %ld -> %ld\",\n\t\t\t\t                     (long) i, (long) idx));\n\t\t\t\tDUK_ASSERT_DISABLE(i >= 0);  /* unsigned */\n\t\t\t\tDUK_ASSERT(i < DUK_HOBJECT_GET_HSIZE(obj));\n\t\t\t\tDUK_ASSERT_DISABLE(idx >= 0);\n\t\t\t\tDUK_ASSERT(idx < DUK_HOBJECT_GET_ESIZE(obj));\n\t\t\t\th_base[i] = idx;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__hobject_alloc_entry_checked() miss %ld\", (long) i));\n\t\t\ti = (i + step) & mask;\n\n\t\t\t/* Guaranteed to finish (hash is larger than #props). */\n\t\t}\n\t}\n#endif  /* DUK_USE_HOBJECT_HASH_PART */\n\n\t/* Note: we could return the hash index here too, but it's not\n\t * needed right now.\n\t */\n\n\tDUK_ASSERT_DISABLE(idx >= 0);\n\tDUK_ASSERT(idx < DUK_HOBJECT_GET_ESIZE(obj));\n\tDUK_ASSERT(idx < DUK_HOBJECT_GET_ENEXT(obj));\n\treturn (duk_int_t) idx;\n}\n\n/*\n *  Object internal value\n *\n *  Returned value is guaranteed to be reachable / incref'd, caller does not need\n *  to incref OR decref.  No proxies or accessors are invoked, no prototype walk.\n */\n\nDUK_INTERNAL duk_tval *duk_hobject_get_internal_value_tval_ptr(duk_heap *heap, duk_hobject *obj) {\n\treturn duk_hobject_find_entry_tval_ptr_stridx(heap, obj, DUK_STRIDX_INT_VALUE);\n}\n\nDUK_LOCAL duk_heaphdr *duk_hobject_get_internal_value_heaphdr(duk_heap *heap, duk_hobject *obj) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\ttv = duk_hobject_get_internal_value_tval_ptr(heap, obj);\n\tif (tv != NULL) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn h;\n\t}\n\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *heap, duk_hobject *obj) {\n\tduk_hstring *h;\n\n\th = (duk_hstring *) duk_hobject_get_internal_value_heaphdr(heap, obj);\n\tif (h != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_IS_STRING((duk_heaphdr *) h));\n\t}\n\treturn h;\n}\n\nDUK_LOCAL duk_hobject *duk__hobject_get_entry_object_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(heap, obj, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn h;\n\t}\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_harray *duk_hobject_get_formals(duk_hthread *thr, duk_hobject *obj) {\n\tduk_harray *h;\n\n\th = (duk_harray *) duk__hobject_get_entry_object_stridx(thr->heap, obj, DUK_STRIDX_INT_FORMALS);\n\tif (h != NULL) {\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) h));\n\t\tDUK_ASSERT(h->length <= DUK_HOBJECT_GET_ASIZE((duk_hobject *) h));\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_hobject_get_varmap(duk_hthread *thr, duk_hobject *obj) {\n\tduk_hobject *h;\n\n\th = duk__hobject_get_entry_object_stridx(thr->heap, obj, DUK_STRIDX_INT_VARMAP);\n\treturn h;\n}\n\n/*\n *  Arguments handling helpers (argument map mainly).\n *\n *  An arguments object has exotic behavior for some numeric indices.\n *  Accesses may translate to identifier operations which may have\n *  arbitrary side effects (potentially invalidating any duk_tval\n *  pointers).\n */\n\n/* Lookup 'key' from arguments internal 'map', perform a variable lookup\n * if mapped, and leave the result on top of stack (and return non-zero).\n * Used in E5 Section 10.6 algorithms [[Get]] and [[GetOwnProperty]].\n */\nDUK_LOCAL\nduk_bool_t duk__lookup_arguments_map(duk_hthread *thr,\n                                     duk_hobject *obj,\n                                     duk_hstring *key,\n                                     duk_propdesc *temp_desc,\n                                     duk_hobject **out_map,\n                                     duk_hobject **out_varenv) {\n\tduk_hobject *map;\n\tduk_hobject *varenv;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments map lookup: thr=%p, obj=%p, key=%p, temp_desc=%p \"\n\t                     \"(obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (void *) temp_desc,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tif (!duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_MAP(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> no 'map'\"));\n\t\treturn 0;\n\t}\n\n\tmap = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(map != NULL);\n\tduk_pop_unsafe(thr);  /* map is reachable through obj */\n\n\tif (!duk_hobject_get_own_propdesc(thr, map, key, temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> 'map' exists, but key not in map\"));\n\t\treturn 0;\n\t}\n\n\t/* [... varname] */\n\tDUK_DDD(DUK_DDDPRINT(\"-> 'map' exists, and contains key, key is mapped to argument/variable binding %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\tDUK_ASSERT(duk_is_string(thr, -1));  /* guaranteed when building arguments */\n\n\t/* get varenv for varname (callee's declarative lexical environment) */\n\trc = duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_VARENV(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE);\n\tDUK_UNREF(rc);\n\tDUK_ASSERT(rc != 0);  /* arguments MUST have an initialized lexical environment reference */\n\tvarenv = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(varenv != NULL);\n\tduk_pop_unsafe(thr);  /* varenv remains reachable through 'obj' */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments varenv is: %!dO\", (duk_heaphdr *) varenv));\n\n\t/* success: leave varname in stack */\n\t*out_map = map;\n\t*out_varenv = varenv;\n\treturn 1;  /* [... varname] */\n}\n\n/* Lookup 'key' from arguments internal 'map', and leave replacement value\n * on stack top if mapped (and return non-zero).\n * Used in E5 Section 10.6 algorithm for [[GetOwnProperty]] (used by [[Get]]).\n */\nDUK_LOCAL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc) {\n\tduk_hobject *map;\n\tduk_hobject *varenv;\n\tduk_hstring *varname;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk__lookup_arguments_map(thr, obj, key, temp_desc, &map, &varenv)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arguments: key not mapped, no exotic get behavior\"));\n\t\treturn 0;\n\t}\n\n\t/* [... varname] */\n\n\tvarname = duk_require_hstring(thr, -1);\n\tDUK_ASSERT(varname != NULL);\n\tduk_pop_unsafe(thr);  /* varname is still reachable */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments object automatic getvar for a bound variable; \"\n\t                     \"key=%!O, varname=%!O\",\n\t                     (duk_heaphdr *) key,\n\t                     (duk_heaphdr *) varname));\n\n\t(void) duk_js_getvar_envrec(thr, varenv, varname, 1 /*throw*/);\n\n\t/* [... value this_binding] */\n\n\tduk_pop_unsafe(thr);\n\n\t/* leave result on stack top */\n\treturn 1;\n}\n\n/* Lookup 'key' from arguments internal 'map', perform a variable write if mapped.\n * Used in E5 Section 10.6 algorithm for [[DefineOwnProperty]] (used by [[Put]]).\n * Assumes stack top contains 'put' value (which is NOT popped).\n */\nDUK_LOCAL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc, duk_bool_t throw_flag) {\n\tduk_hobject *map;\n\tduk_hobject *varenv;\n\tduk_hstring *varname;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk__lookup_arguments_map(thr, obj, key, temp_desc, &map, &varenv)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arguments: key not mapped, no exotic put behavior\"));\n\t\treturn;\n\t}\n\n\t/* [... put_value varname] */\n\n\tvarname = duk_require_hstring(thr, -1);\n\tDUK_ASSERT(varname != NULL);\n\tduk_pop_unsafe(thr);  /* varname is still reachable */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments object automatic putvar for a bound variable; \"\n\t                     \"key=%!O, varname=%!O, value=%!T\",\n\t                     (duk_heaphdr *) key,\n\t                     (duk_heaphdr *) varname,\n\t                     (duk_tval *) duk_require_tval(thr, -1)));\n\n\t/* [... put_value] */\n\n\t/*\n\t *  Note: although arguments object variable mappings are only established\n\t *  for non-strict functions (and a call to a non-strict function created\n\t *  the arguments object in question), an inner strict function may be doing\n\t *  the actual property write.  Hence the throw_flag applied here comes from\n\t *  the property write call.\n\t */\n\n\tduk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(thr, -1), throw_flag);\n\n\t/* [... put_value] */\n}\n\n/* Lookup 'key' from arguments internal 'map', delete mapping if found.\n * Used in E5 Section 10.6 algorithm for [[Delete]].  Note that the\n * variable/argument itself (where the map points) is not deleted.\n */\nDUK_LOCAL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc) {\n\tduk_hobject *map;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_MAP(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arguments: key not mapped, no exotic delete behavior\"));\n\t\treturn;\n\t}\n\n\tmap = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(map != NULL);\n\tduk_pop_unsafe(thr);  /* map is reachable through obj */\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> have 'map', delete key %!O from map (if exists)); ignore result\",\n\t                     (duk_heaphdr *) key));\n\n\t/* Note: no recursion issue, we can trust 'map' to behave */\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR(map));\n\tDUK_DDD(DUK_DDDPRINT(\"map before deletion: %!O\", (duk_heaphdr *) map));\n\t(void) duk_hobject_delprop_raw(thr, map, key, 0);  /* ignore result */\n\tDUK_DDD(DUK_DDDPRINT(\"map after deletion: %!O\", (duk_heaphdr *) map));\n}\n\n/*\n *  ECMAScript compliant [[GetOwnProperty]](P), for internal use only.\n *\n *  If property is found:\n *    - Fills descriptor fields to 'out_desc'\n *    - If DUK_GETDESC_FLAG_PUSH_VALUE is set, pushes a value related to the\n *      property onto the stack ('undefined' for accessor properties).\n *    - Returns non-zero\n *\n *  If property is not found:\n *    - 'out_desc' is left in untouched state (possibly garbage)\n *    - Nothing is pushed onto the stack (not even with DUK_GETDESC_FLAG_PUSH_VALUE\n *      set)\n *    - Returns zero\n *\n *  Notes:\n *\n *    - Getting a property descriptor may cause an allocation (and hence\n *      GC) to take place, hence reachability and refcount of all related\n *      values matter.  Reallocation of value stack, properties, etc may\n *      invalidate many duk_tval pointers (concretely, those which reside\n *      in memory areas subject to reallocation).  However, heap object\n *      pointers are never affected (heap objects have stable pointers).\n *\n *    - The value of a plain property is always reachable and has a non-zero\n *      reference count.\n *\n *    - The value of a virtual property is not necessarily reachable from\n *      elsewhere and may have a refcount of zero.  Hence we push it onto\n *      the valstack for the caller, which ensures it remains reachable\n *      while it is needed.\n *\n *    - There are no virtual accessor properties.  Hence, all getters and\n *      setters are always related to concretely stored properties, which\n *      ensures that the get/set functions in the resulting descriptor are\n *      reachable and have non-zero refcounts.  Should there be virtual\n *      accessor properties later, this would need to change.\n */\n\nDUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_uint32_t arr_idx, duk_propdesc *out_desc, duk_small_uint_t flags) {\n\tduk_tval *tv;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk_hobject_get_own_propdesc: thr=%p, obj=%p, key=%p, out_desc=%p, flags=%lx, \"\n\t                     \"arr_idx=%ld (obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (void *) out_desc,\n\t                     (long) flags, (long) arr_idx,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_desc != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_getownpropdesc_count);\n\n\t/* Each code path returning 1 (= found) must fill in all the output\n\t * descriptor fields.  We don't do it beforehand because it'd be\n\t * unnecessary work if the property isn't found and would happen\n\t * multiple times for an inheritance chain.\n\t */\n\tDUK_ASSERT_SET_GARBAGE(out_desc, sizeof(*out_desc));\n#if 0\n\tout_desc->flags = 0;\n\tout_desc->get = NULL;\n\tout_desc->set = NULL;\n\tout_desc->e_idx = -1;\n\tout_desc->h_idx = -1;\n\tout_desc->a_idx = -1;\n#endif\n\n\t/*\n\t *  Try entries part first because it's the common case.\n\t *\n\t *  Array part lookups are usually handled by the array fast path, and\n\t *  are not usually inherited.  Array and entry parts never contain the\n\t *  same keys so the entry part vs. array part order doesn't matter.\n\t */\n\n\tif (duk_hobject_find_entry(thr->heap, obj, key, &out_desc->e_idx, &out_desc->h_idx)) {\n\t\tduk_int_t e_idx = out_desc->e_idx;\n\t\tDUK_ASSERT(out_desc->e_idx >= 0);\n\t\tout_desc->a_idx = -1;\n\t\tout_desc->flags = DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, e_idx);\n\t\tout_desc->get = NULL;\n\t\tout_desc->set = NULL;\n\t\tif (DUK_UNLIKELY(out_desc->flags & DUK_PROPDESC_FLAG_ACCESSOR)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found accessor property in entry part\"));\n\t\t\tout_desc->get = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, e_idx);\n\t\t\tout_desc->set = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, e_idx);\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t/* a dummy undefined value is pushed to make valstack\n\t\t\t\t * behavior uniform for caller\n\t\t\t\t */\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t}\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found plain property in entry part\"));\n\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\tduk_push_tval(thr, tv);\n\t\t\t}\n\t\t}\n\t\tgoto prop_found;\n\t}\n\n\t/*\n\t *  Try array part.\n\t */\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj) && arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\tif (arr_idx < DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n\t\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found in array part\"));\n\t\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t\tduk_push_tval(thr, tv);\n\t\t\t\t}\n\t\t\t\t/* implicit attributes */\n\t\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t\t                  DUK_PROPDESC_FLAG_CONFIGURABLE |\n\t\t\t\t                  DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t\tout_desc->get = NULL;\n\t\t\t\tout_desc->set = NULL;\n\t\t\t\tout_desc->e_idx = -1;\n\t\t\t\tout_desc->h_idx = -1;\n\t\t\t\tout_desc->a_idx = (duk_int_t) arr_idx;  /* XXX: limit 2G due to being signed */\n\t\t\t\tgoto prop_found;\n\t\t\t}\n\t\t}\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> not found as a concrete property\"));\n\n\t/*\n\t *  Not found as a concrete property, check for virtual properties.\n\t */\n\n\tif (!DUK_HOBJECT_HAS_VIRTUAL_PROPERTIES(obj)) {\n\t\t/* Quick skip. */\n\t\tgoto prop_not_found;\n\t}\n\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\tduk_harray *a;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array object exotic property get for key: %!O, arr_idx: %ld\",\n\t\t                     (duk_heaphdr *) key, (long) arr_idx));\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, key is 'length', length exotic behavior\"));\n\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) a->length);\n\t\t\t}\n\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\tif (DUK_HARRAY_LENGTH_WRITABLE(a)) {\n\t\t\t\tout_desc->flags |= DUK_PROPDESC_FLAG_WRITABLE;\n\t\t\t}\n\t\t\tout_desc->get = NULL;\n\t\t\tout_desc->set = NULL;\n\t\t\tout_desc->e_idx = -1;\n\t\t\tout_desc->h_idx = -1;\n\t\t\tout_desc->a_idx = -1;\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t}\n\t} else if (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"string object exotic property get for key: %!O, arr_idx: %ld\",\n\t\t                     (duk_heaphdr *) key, (long) arr_idx));\n\n\t\t/* XXX: charlen; avoid multiple lookups? */\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t\tduk_hstring *h_val;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index exists\"));\n\n\t\t\th_val = duk_hobject_get_internal_value_string(thr->heap, obj);\n\t\t\tDUK_ASSERT(h_val);\n\t\t\tif (arr_idx < DUK_HSTRING_GET_CHARLEN(h_val)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, array index inside string\"));\n\t\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t\tduk_push_hstring(thr, h_val);\n\t\t\t\t\tduk_substring(thr, -1, arr_idx, arr_idx + 1);  /* [str] -> [substr] */\n\t\t\t\t}\n\t\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_ENUMERABLE |  /* E5 Section 15.5.5.2 */\n\t\t\t\t                  DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\t\tout_desc->get = NULL;\n\t\t\t\tout_desc->set = NULL;\n\t\t\t\tout_desc->e_idx = -1;\n\t\t\t\tout_desc->h_idx = -1;\n\t\t\t\tout_desc->a_idx = -1;\n\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t\t} else {\n\t\t\t\t/* index is above internal string length -> property is fully normal */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index outside string -> normal property\"));\n\t\t\t}\n\t\t} else if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tduk_hstring *h_val;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, key is 'length', length exotic behavior\"));\n\n\t\t\th_val = duk_hobject_get_internal_value_string(thr->heap, obj);\n\t\t\tDUK_ASSERT(h_val != NULL);\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h_val));\n\t\t\t}\n\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;  /* E5 Section 15.5.5.1 */\n\t\t\tout_desc->get = NULL;\n\t\t\tout_desc->set = NULL;\n\t\t\tout_desc->e_idx = -1;\n\t\t\tout_desc->h_idx = -1;\n\t\t\tout_desc->a_idx = -1;\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t}\n\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\telse if (DUK_HOBJECT_IS_BUFOBJ(obj)) {\n\t\tduk_hbufobj *h_bufobj;\n\t\tduk_uint_t byte_off;\n\t\tduk_small_uint_t elem_size;\n\n\t\th_bufobj = (duk_hbufobj *) obj;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\t\tDUK_DDD(DUK_DDDPRINT(\"bufobj property get for key: %!O, arr_idx: %ld\",\n\t\t                     (duk_heaphdr *) key, (long) arr_idx));\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index exists\"));\n\n\t\t\t/* Careful with wrapping: arr_idx upshift may easily wrap, whereas\n\t\t\t * length downshift won't.\n\t\t\t */\n\t\t\tif (arr_idx < (h_bufobj->length >> h_bufobj->shift)) {\n\t\t\t\tbyte_off = arr_idx << h_bufobj->shift;  /* no wrap assuming h_bufobj->length is valid */\n\t\t\t\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\t\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t\tduk_uint8_t *data;\n\n\t\t\t\t\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\t\t\t\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\t\t\t\t\tduk_hbufobj_push_validated_read(thr, h_bufobj, data, elem_size);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (read zero)\"));\n\t\t\t\t\t\tduk_push_uint(thr, 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t\t                  DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(obj) != DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\t\t\t\t/* ArrayBuffer indices are non-standard and are\n\t\t\t\t\t * non-enumerable to avoid their serialization.\n\t\t\t\t\t */\n\t\t\t\t\tout_desc->flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t\t}\n\t\t\t\tout_desc->get = NULL;\n\t\t\t\tout_desc->set = NULL;\n\t\t\t\tout_desc->e_idx = -1;\n\t\t\t\tout_desc->h_idx = -1;\n\t\t\t\tout_desc->a_idx = -1;\n\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\t\tgoto prop_found_noexotic;  /* cannot be e.g. arguments exotic, since exotic 'traits' are mutually exclusive */\n\t\t\t} else {\n\t\t\t\t/* index is above internal buffer length -> property is fully normal */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index outside buffer -> normal property\"));\n\t\t\t}\n\t\t} else if (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, key is 'length', length exotic behavior\"));\n\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t/* Length in elements: take into account shift, but\n\t\t\t\t * intentionally don't check the underlying buffer here.\n\t\t\t\t */\n\t\t\t\tduk_push_uint(thr, h_bufobj->length >> h_bufobj->shift);\n\t\t\t}\n\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\tout_desc->get = NULL;\n\t\t\tout_desc->set = NULL;\n\t\t\tout_desc->e_idx = -1;\n\t\t\tout_desc->h_idx = -1;\n\t\t\tout_desc->a_idx = -1;\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t}\n\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\t/* Array properties have exotic behavior but they are concrete,\n\t * so no special handling here.\n\t *\n\t * Arguments exotic behavior (E5 Section 10.6, [[GetOwnProperty]]\n\t * is only relevant as a post-check implemented below; hence no\n\t * check here.\n\t */\n\n\t/*\n\t *  Not found as concrete or virtual.\n\t */\n\n prop_not_found:\n\tDUK_DDD(DUK_DDDPRINT(\"-> not found (virtual, entry part, or array part)\"));\n\tDUK_STATS_INC(thr->heap, stats_getownpropdesc_miss);\n\treturn 0;\n\n\t/*\n\t *  Found.\n\t *\n\t *  Arguments object has exotic post-processing, see E5 Section 10.6,\n\t *  description of [[GetOwnProperty]] variant for arguments.\n\t */\n\n prop_found:\n\tDUK_DDD(DUK_DDDPRINT(\"-> property found, checking for arguments exotic post-behavior\"));\n\n\t/* Notes:\n\t *  - Only numbered indices are relevant, so arr_idx fast reject is good\n\t *    (this is valid unless there are more than 4**32-1 arguments).\n\t *  - Since variable lookup has no side effects, this can be skipped if\n\t *    DUK_GETDESC_FLAG_PUSH_VALUE is not set.\n\t */\n\n\tif (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) &&\n\t                 arr_idx != DUK__NO_ARRAY_INDEX &&\n\t                 (flags & DUK_GETDESC_FLAG_PUSH_VALUE))) {\n\t\tduk_propdesc temp_desc;\n\n\t\t/* Magically bound variable cannot be an accessor.  However,\n\t\t * there may be an accessor property (or a plain property) in\n\t\t * place with magic behavior removed.  This happens e.g. when\n\t\t * a magic property is redefined with defineProperty().\n\t\t * Cannot assert for \"not accessor\" here.\n\t\t */\n\n\t\t/* replaces top of stack with new value if necessary */\n\t\tDUK_ASSERT((flags & DUK_GETDESC_FLAG_PUSH_VALUE) != 0);\n\n\t\t/* This can perform a variable lookup but only into a declarative\n\t\t * environment which has no side effects.\n\t\t */\n\t\tif (duk__check_arguments_map_for_get(thr, obj, key, &temp_desc)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> arguments exotic behavior overrides result: %!T -> %!T\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\t/* [... old_result result] -> [... result] */\n\t\t\tduk_remove_m2(thr);\n\t\t}\n\t}\n\n prop_found_noexotic:\n\tDUK_STATS_INC(thr->heap, stats_getownpropdesc_hit);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_bool_t duk_hobject_get_own_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_desc != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\treturn duk__get_own_propdesc_raw(thr, obj, key, DUK_HSTRING_GET_ARRIDX_SLOW(key), out_desc, flags);\n}\n\n/*\n *  ECMAScript compliant [[GetProperty]](P), for internal use only.\n *\n *  If property is found:\n *    - Fills descriptor fields to 'out_desc'\n *    - If DUK_GETDESC_FLAG_PUSH_VALUE is set, pushes a value related to the\n *      property onto the stack ('undefined' for accessor properties).\n *    - Returns non-zero\n *\n *  If property is not found:\n *    - 'out_desc' is left in untouched state (possibly garbage)\n *    - Nothing is pushed onto the stack (not even with DUK_GETDESC_FLAG_PUSH_VALUE\n *      set)\n *    - Returns zero\n *\n *  May cause arbitrary side effects and invalidate (most) duk_tval\n *  pointers.\n */\n\nDUK_LOCAL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags) {\n\tduk_hobject *curr;\n\tduk_uint32_t arr_idx;\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_desc != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_getpropdesc_count);\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__get_propdesc: thr=%p, obj=%p, key=%p, out_desc=%p, flags=%lx, \"\n\t                     \"arr_idx=%ld (obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (void *) out_desc,\n\t                     (long) flags, (long) arr_idx,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tcurr = obj;\n\tDUK_ASSERT(curr != NULL);\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (duk__get_own_propdesc_raw(thr, curr, key, arr_idx, out_desc, flags)) {\n\t\t\t/* stack contains value (if requested), 'out_desc' is set */\n\t\t\tDUK_STATS_INC(thr->heap, stats_getpropdesc_hit);\n\t\t\treturn 1;\n\t\t}\n\n\t\t/* not found in 'curr', next in prototype chain; impose max depth */\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tif (flags & DUK_GETDESC_FLAG_IGNORE_PROTOLOOP) {\n\t\t\t\t/* treat like property not found */\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t} while (curr != NULL);\n\n\t/* out_desc is left untouched (possibly garbage), caller must use return\n\t * value to determine whether out_desc can be looked up\n\t */\n\n\tDUK_STATS_INC(thr->heap, stats_getpropdesc_miss);\n\treturn 0;\n}\n\n/*\n *  Shallow fast path checks for accessing array elements with numeric\n *  indices.  The goal is to try to avoid coercing an array index to an\n *  (interned) string for the most common lookups, in particular, for\n *  standard Array objects.\n *\n *  Interning is avoided but only for a very narrow set of cases:\n *    - Object has array part, index is within array allocation, and\n *      value is not unused (= key exists)\n *    - Object has no interfering exotic behavior (e.g. arguments or\n *      string object exotic behaviors interfere, array exotic\n *      behavior does not).\n *\n *  Current shortcoming: if key does not exist (even if it is within\n *  the array allocation range) a slow path lookup with interning is\n *  always required.  This can probably be fixed so that there is a\n *  quick fast path for non-existent elements as well, at least for\n *  standard Array objects.\n */\n\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\nDUK_LOCAL duk_tval *duk__getprop_shallow_fastpath_array_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key) {\n\tduk_tval *tv;\n\tduk_uint32_t idx;\n\n\tDUK_UNREF(thr);\n\n\tif (!(DUK_HOBJECT_HAS_ARRAY_PART(obj) &&\n\t     !DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) &&\n\t     !DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj) &&\n\t     !DUK_HOBJECT_IS_BUFOBJ(obj) &&\n\t     !DUK_HOBJECT_IS_PROXY(obj))) {\n\t\t/* Must have array part and no conflicting exotic behaviors.\n\t\t * Doesn't need to have array special behavior, e.g. Arguments\n\t\t * object has array part.\n\t\t */\n\t\treturn NULL;\n\t}\n\n\t/* Arrays never have other exotic behaviors. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"fast path attempt (no exotic string/arguments/buffer \"\n\t                     \"behavior, object has array part)\"));\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"key is not a number\"));\n\t\treturn NULL;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside object 'a_size'.\n\t */\n\n\tif (idx >= DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"key is not an array index or outside array part\"));\n\t\treturn NULL;\n\t}\n\tDUK_ASSERT(idx != 0xffffffffUL);\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\t/* XXX: for array instances we could take a shortcut here and assume\n\t * Array.prototype doesn't contain an array index property.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"key is a valid array index and inside array part\"));\n\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, idx);\n\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> fast path successful\"));\n\t\treturn tv;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"fast path attempt failed, fall back to slow path\"));\n\treturn NULL;\n}\n\nDUK_LOCAL duk_bool_t duk__putprop_shallow_fastpath_array_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val) {\n\tduk_tval *tv;\n\tduk_harray *a;\n\tduk_uint32_t idx;\n\tduk_uint32_t old_len, new_len;\n\n\tif (!(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj) &&\n\t      DUK_HOBJECT_HAS_ARRAY_PART(obj) &&\n\t      DUK_HOBJECT_HAS_EXTENSIBLE(obj))) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));  /* caller ensures */\n\n\ta = (duk_harray *) obj;\n\tDUK_HARRAY_ASSERT_VALID(a);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"key is not a number\"));\n\t\treturn 0;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside object 'a_size'.\n\t */\n\n\tif (idx >= DUK_HOBJECT_GET_ASIZE(obj)) {  /* for resizing of array part, use slow path */\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(idx != 0xffffffffUL);\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\told_len = a->length;\n\n\tif (idx >= old_len) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"write new array entry requires length update \"\n\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t                     (long) idx, (long) old_len));\n\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a)) {\n\t\t\t/* The correct behavior here is either a silent error\n\t\t\t * or a TypeError, depending on strictness.  Fall back\n\t\t\t * to the slow path to handle the situation.\n\t\t\t */\n\t\t\treturn 0;\n\t\t}\n\t\tnew_len = idx + 1;\n\n\t\t((duk_harray *) obj)->length = new_len;\n\t}\n\n\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, idx);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val);  /* side effects */\n\n\tDUK_DDD(DUK_DDDPRINT(\"array fast path success for index %ld\", (long) idx));\n\treturn 1;\n}\n#endif  /* DUK_USE_ARRAY_PROP_FASTPATH */\n\n/*\n *  Fast path for bufobj getprop/putprop\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL duk_bool_t duk__getprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key) {\n\tduk_uint32_t idx;\n\tduk_hbufobj *h_bufobj;\n\tduk_uint_t byte_off;\n\tduk_small_uint_t elem_size;\n\tduk_uint8_t *data;\n\n\tif (!DUK_HOBJECT_IS_BUFOBJ(obj)) {\n\t\treturn 0;\n\t}\n\th_bufobj = (duk_hbufobj *) obj;\n\tif (!DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\treturn 0;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\treturn 0;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside bufobj length.\n\t */\n\n\t/* Careful with wrapping (left shifting idx would be unsafe). */\n\tif (idx >= (h_bufobj->length >> h_bufobj->shift)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\tbyte_off = idx << h_bufobj->shift;  /* no wrap assuming h_bufobj->length is valid */\n\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\n\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\tduk_hbufobj_push_validated_read(thr, h_bufobj, data, elem_size);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (read zero)\"));\n\t\tduk_push_uint(thr, 0);\n\t}\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL duk_bool_t duk__putprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val) {\n\tduk_uint32_t idx;\n\tduk_hbufobj *h_bufobj;\n\tduk_uint_t byte_off;\n\tduk_small_uint_t elem_size;\n\tduk_uint8_t *data;\n\n\tif (!(DUK_HOBJECT_IS_BUFOBJ(obj) &&\n\t      DUK_TVAL_IS_NUMBER(tv_val))) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));  /* caller ensures; rom objects are never bufobjs now */\n\n\th_bufobj = (duk_hbufobj *) obj;\n\tif (!DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\treturn 0;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\treturn 0;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside bufobj length.\n\t */\n\n\t/* Careful with wrapping (left shifting idx would be unsafe). */\n\tif (idx >= (h_bufobj->length >> h_bufobj->shift)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\tbyte_off = idx << h_bufobj->shift;  /* no wrap assuming h_bufobj->length is valid */\n\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\n\t/* Value is required to be a number in the fast path so there\n\t * are no side effects in write coercion.\n\t */\n\tduk_push_tval(thr, tv_val);\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\n\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\tduk_hbufobj_validated_write(thr, h_bufobj, data, elem_size);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (write skipped)\"));\n\t}\n\n\tduk_pop_unsafe(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  GETPROP: ECMAScript property read.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) {\n\tduk_tval tv_obj_copy;\n\tduk_tval tv_key_copy;\n\tduk_hobject *curr = NULL;\n\tduk_hstring *key = NULL;\n\tduk_uint32_t arr_idx = DUK__NO_ARRAY_INDEX;\n\tduk_propdesc desc;\n\tduk_uint_t sanity;\n\n\tDUK_DDD(DUK_DDDPRINT(\"getprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key,\n\t                     (duk_tval *) tv_obj, (duk_tval *) tv_key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_getprop_all);\n\n\t/*\n\t *  Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of\n\t *  them being invalidated by a valstack resize.\n\t *\n\t *  XXX: this is now an overkill for many fast paths.  Rework this\n\t *  to be faster (although switching to a valstack discipline might\n\t *  be a better solution overall).\n\t */\n\n\tDUK_TVAL_SET_TVAL(&tv_obj_copy, tv_obj);\n\tDUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);\n\ttv_obj = &tv_obj_copy;\n\ttv_key = &tv_key_copy;\n\n\t/*\n\t *  Coercion and fast path processing\n\t */\n\n\tswitch (DUK_TVAL_GET_TAG(tv_obj)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL: {\n\t\t/* Note: unconditional throw */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is undefined or null -> reject\"));\n#if defined(DUK_USE_PARANOID_ERRORS)\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\t\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot read property %s of %s\",\n\t\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\t\tDUK_WO_NORETURN(return 0;);\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a boolean, start lookup from boolean prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);\n\t\tduk_int_t pop_count;\n\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\t/* Symbols (ES2015 or hidden) don't have virtual properties. */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a symbol, start lookup from symbol prototype\"));\n\t\t\tcurr = thr->builtins[DUK_BIDX_SYMBOL_PROTOTYPE];\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_FASTINT)\n\t\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\t\tarr_idx = duk__tval_fastint_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a fast-path fastint; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else\n#endif\n\t\tif (DUK_TVAL_IS_NUMBER(tv_key)) {\n\t\t\tarr_idx = duk__tval_number_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a fast-path number; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t\tpop_count = 1;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {\n\t\t\tduk_pop_n_unsafe(thr, pop_count);\n\t\t\tduk_push_hstring(thr, h);\n\t\t\tduk_substring(thr, -1, arr_idx, arr_idx + 1);  /* [str] -> [substr] */\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_stringidx);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is string, key is an index inside string length \"\n\t\t\t                     \"after coercion -> return char)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (pop_count == 0) {\n\t\t\t/* This is a pretty awkward control flow, but we need to recheck the\n\t\t\t * key coercion here.\n\t\t\t */\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tduk_pop_unsafe(thr);  /* [key] -> [] */\n\t\t\tduk_push_uint(thr, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h));  /* [] -> [res] */\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_stringlen);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is string, key is 'length' after coercion -> \"\n\t\t\t                     \"return string length)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a string, start lookup from string prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_STRING_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_OBJECT: {\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\n\t\tduk_tval *tmp;\n#endif\n\n\t\tcurr = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(curr != NULL);\n\n\t\t/* XXX: array .length fast path (important in e.g. loops)? */\n\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\n\t\ttmp = duk__getprop_shallow_fastpath_array_tval(thr, curr, tv_key);\n\t\tif (tmp) {\n\t\t\tduk_push_tval(thr, tmp);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is object, key is a number, array part \"\n\t\t\t                     \"fast path)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_arrayidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (duk__getprop_fastpath_bufobj_tval(thr, curr, tv_key) != 0) {\n\t\t\t/* Read value pushed on stack. */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is bufobj, key is a number, bufobj \"\n\t\t\t                     \"fast path)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_bufobjidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(curr))) {\n\t\t\tduk_hobject *h_target;\n\n\t\t\tif (duk__proxy_check_prop(thr, curr, DUK_STRIDX_GET, tv_key, &h_target)) {\n\t\t\t\t/* -> [ ... trap handler ] */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'get' for key %!T\", (duk_tval *) tv_key));\n\t\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_proxy);\n\t\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\t\tduk_push_tval(thr, tv_key);       /* P */\n\t\t\t\tduk_push_tval(thr, tv_obj);       /* Receiver: Proxy object */\n\t\t\t\tduk_call_method(thr, 3 /*nargs*/);\n\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\t\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\t\t\t\tduk_tval *tv_hook = duk_require_tval(thr, -3);  /* value from hook */\n\t\t\t\t\tduk_tval *tv_targ = duk_require_tval(thr, -1);  /* value from target */\n\t\t\t\t\tduk_bool_t datadesc_reject;\n\t\t\t\t\tduk_bool_t accdesc_reject;\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'get': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; tv_hook=%!T, tv_targ=%!T, desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (duk_tval *) tv_hook, (duk_tval *) tv_targ,\n\t\t\t\t\t                     (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\n\t\t\t\t\tdatadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) &&\n\t\t\t\t\t                  !duk_js_samevalue(tv_hook, tv_targ);\n\t\t\t\t\taccdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                 !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                 (desc.get == NULL) &&\n\t\t\t\t\t                 !DUK_TVAL_IS_UNDEFINED(tv_hook);\n\t\t\t\t\tif (datadesc_reject || accdesc_reject) {\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\n\t\t\t\t\tduk_pop_2_unsafe(thr);\n\t\t\t\t} else {\n\t\t\t\t\tduk_pop_unsafe(thr);\n\t\t\t\t}\n\t\t\t\treturn 1;  /* return value */\n\t\t\t}\n\n\t\t\tcurr = h_target;  /* resume lookup from target */\n\t\t\tDUK_TVAL_SET_OBJECT(tv_obj, curr);\n\t\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(curr)) {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_arguments);\n\t\t\tif (duk__check_arguments_map_for_get(thr, curr, key, &desc)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is object with arguments exotic behavior, \"\n\t\t\t\t                     \"key matches magically bound property -> skip standard \"\n\t\t\t\t                     \"Get with replacement value)\",\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t\t/* no need for 'caller' post-check, because 'key' must be an array index */\n\n\t\t\t\tduk_remove_m2(thr);  /* [key result] -> [result] */\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tgoto lookup;  /* avoid double coercion */\n\t\t}\n\t\tbreak;\n\t}\n\n\t/* Buffer has virtual properties similar to string, but indexed values\n\t * are numbers, not 1-byte buffers/strings which would perform badly.\n\t */\n\tcase DUK_TAG_BUFFER: {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);\n\t\tduk_int_t pop_count;\n\n\t\t/*\n\t\t *  Because buffer values are often looped over, a number fast path\n\t\t *  is important.\n\t\t */\n\n#if defined(DUK_USE_FASTINT)\n\t\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\t\tarr_idx = duk__tval_fastint_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path fastint; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t}\n\t\telse\n#endif\n\t\tif (DUK_TVAL_IS_NUMBER(tv_key)) {\n\t\t\tarr_idx = duk__tval_number_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path number; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t\tpop_count = 1;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HBUFFER_GET_SIZE(h)) {\n\t\t\tduk_pop_n_unsafe(thr, pop_count);\n\t\t\tduk_push_uint(thr, ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h))[arr_idx]);\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_bufferidx);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is buffer, key is an index inside buffer length \"\n\t\t\t                     \"after coercion -> return byte as number)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (pop_count == 0) {\n\t\t\t/* This is a pretty awkward control flow, but we need to recheck the\n\t\t\t * key coercion here.\n\t\t\t */\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tduk_pop_unsafe(thr);  /* [key] -> [] */\n\t\t\tduk_push_uint(thr, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h));  /* [] -> [res] */\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_bufferlen);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is buffer, key is 'length' \"\n\t\t\t                     \"after coercion -> return buffer length)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a buffer, start lookup from Uint8Array prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_POINTER: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a pointer, start lookup from pointer prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Lightfuncs inherit getter .name and .length from %NativeFunctionPrototype%. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a lightfunc, start lookup from function prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE];\n\t\tbreak;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a number, start lookup from number prototype\"));\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_obj));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_obj));\n\t\tcurr = thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE];\n\t\tbreak;\n\t}\n\t}\n\n\t/* key coercion (unless already coerced above) */\n\tDUK_ASSERT(key == NULL);\n\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\tDUK_ASSERT(key != NULL);\n\t/*\n\t *  Property lookup\n\t */\n\n lookup:\n\t/* [key] (coerced) */\n\tDUK_ASSERT(curr != NULL);\n\tDUK_ASSERT(key != NULL);\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (!duk__get_own_propdesc_raw(thr, curr, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\t\tgoto next_in_chain;\n\t\t}\n\n\t\tif (desc.get != NULL) {\n\t\t\t/* accessor with defined getter */\n\t\t\tDUK_ASSERT((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0);\n\n\t\t\tduk_pop_unsafe(thr);              /* [key undefined] -> [key] */\n\t\t\tduk_push_hobject(thr, desc.get);\n\t\t\tduk_push_tval(thr, tv_obj);       /* note: original, uncoerced base */\n#if defined(DUK_USE_NONSTD_GETTER_KEY_ARGUMENT)\n\t\t\tduk_dup_m3(thr);\n\t\t\tduk_call_method(thr, 1);          /* [key getter this key] -> [key retval] */\n#else\n\t\t\tduk_call_method(thr, 0);          /* [key getter this] -> [key retval] */\n#endif\n\t\t} else {\n\t\t\t/* [key value] or [key undefined] */\n\n\t\t\t/* data property or accessor without getter */\n\t\t\tDUK_ASSERT(((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) == 0) ||\n\t\t\t           (desc.get == NULL));\n\n\t\t\t/* if accessor without getter, return value is undefined */\n\t\t\tDUK_ASSERT(((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) == 0) ||\n\t\t\t           duk_is_undefined(thr, -1));\n\n\t\t\t/* Note: for an accessor without getter, falling through to\n\t\t\t * check for \"caller\" exotic behavior is unnecessary as\n\t\t\t * \"undefined\" will never activate the behavior.  But it does\n\t\t\t * no harm, so we'll do it anyway.\n\t\t\t */\n\t\t}\n\n\t\tgoto found;  /* [key result] */\n\n\t next_in_chain:\n\t\t/* XXX: option to pretend property doesn't exist if sanity limit is\n\t\t * hit might be useful.\n\t\t */\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t} while (curr != NULL);\n\n\t/*\n\t *  Not found\n\t */\n\n\tduk_to_undefined(thr, -1);  /* [key] -> [undefined] (default value) */\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (not found)\", (duk_tval *) duk_get_tval(thr, -1)));\n\treturn 0;\n\n\t/*\n\t *  Found; post-processing (Function and arguments objects)\n\t */\n\n found:\n\t/* [key result] */\n\n#if !defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t/* Special behavior for 'caller' property of (non-bound) function objects\n\t * and non-strict Arguments objects: if 'caller' -value- (!) is a strict\n\t * mode function, throw a TypeError (E5 Sections 15.3.5.4, 10.6).\n\t * Quite interestingly, a non-strict function with no formal arguments\n\t * will get an arguments object -without- special 'caller' behavior!\n\t *\n\t * The E5.1 spec is a bit ambiguous if this special behavior applies when\n\t * a bound function is the base value (not the 'caller' value): Section\n\t * 15.3.4.5 (describing bind()) states that [[Get]] for bound functions\n\t * matches that of Section 15.3.5.4 ([[Get]] for Function instances).\n\t * However, Section 13.3.5.4 has \"NOTE: Function objects created using\n\t * Function.prototype.bind use the default [[Get]] internal method.\"\n\t * The current implementation assumes this means that bound functions\n\t * should not have the special [[Get]] behavior.\n\t *\n\t * The E5.1 spec is also a bit unclear if the TypeError throwing is\n\t * applied if the 'caller' value is a strict bound function.  The\n\t * current implementation will throw even for both strict non-bound\n\t * and strict bound functions.\n\t *\n\t * See test-dev-strict-func-as-caller-prop-value.js for quite extensive\n\t * tests.\n\t *\n\t * This exotic behavior is disabled when the non-standard 'caller' property\n\t * is enabled, as it conflicts with the free use of 'caller'.\n\t */\n\tif (key == DUK_HTHREAD_STRING_CALLER(thr) &&\n\t    DUK_TVAL_IS_OBJECT(tv_obj)) {\n\t\tduk_hobject *orig = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(orig != NULL);\n\n\t\tif (DUK_HOBJECT_IS_NONBOUND_FUNCTION(orig) ||\n\t\t    DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(orig)) {\n\t\t\tduk_hobject *h;\n\n\t\t\t/* XXX: The TypeError is currently not applied to bound\n\t\t\t * functions because the 'strict' flag is not copied by\n\t\t\t * bind().  This may or may not be correct, the specification\n\t\t\t * only refers to the value being a \"strict mode Function\n\t\t\t * object\" which is ambiguous.\n\t\t\t */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(orig));\n\n\t\t\th = duk_get_hobject(thr, -1);  /* NULL if not an object */\n\t\t\tif (h &&\n\t\t\t    DUK_HOBJECT_IS_FUNCTION(h) &&\n\t\t\t    DUK_HOBJECT_HAS_STRICT(h)) {\n\t\t\t\t/* XXX: sufficient to check 'strict', assert for 'is function' */\n\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_STRICT_CALLER_READ);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\t}\n#endif   /* !DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */\n\n\tduk_remove_m2(thr);  /* [key result] -> [result] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (found)\", (duk_tval *) duk_get_tval(thr, -1)));\n\treturn 1;\n}\n\n/*\n *  HASPROP: ECMAScript property existence check (\"in\" operator).\n *\n *  Interestingly, the 'in' operator does not do any coercion of\n *  the target object.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) {\n\tduk_tval tv_key_copy;\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_uint32_t arr_idx;\n\tduk_bool_t rc;\n\tduk_propdesc desc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"hasprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key,\n\t                     (duk_tval *) tv_obj, (duk_tval *) tv_key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);\n\ttv_key = &tv_key_copy;\n\n\t/*\n\t *  The 'in' operator requires an object as its right hand side,\n\t *  throwing a TypeError unconditionally if this is not the case.\n\t *\n\t *  However, lightfuncs need to behave like fully fledged objects\n\t *  here to be maximally transparent, so we need to handle them\n\t *  here.  Same goes for plain buffers which behave like ArrayBuffers.\n\t */\n\n\t/* XXX: Refactor key coercion so that it's only called once.  It can't\n\t * be trivially lifted here because the object must be type checked\n\t * first.\n\t */\n\n\tif (DUK_TVAL_IS_OBJECT(tv_obj)) {\n\t\tobj = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(obj != NULL);\n\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t} else if (DUK_TVAL_IS_BUFFER(tv_obj)) {\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\tif (duk__key_is_plain_buf_ownprop(thr, DUK_TVAL_GET_BUFFER(tv_obj), key, arr_idx)) {\n\t\t\trc = 1;\n\t\t\tgoto pop_and_return;\n\t\t}\n\t\tobj = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) {\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\n\t\t/* If not found, resume existence check from %NativeFunctionPrototype%.\n\t\t * We can just substitute the value in this case; nothing will\n\t\t * need the original base value (as would be the case with e.g.\n\t\t * setters/getters.\n\t\t */\n\t\tobj = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE];\n\t} else {\n\t\t/* Note: unconditional throw */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is not an object -> reject\"));\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* XXX: fast path for arrays? */\n\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(arr_idx);\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(obj))) {\n\t\tduk_hobject *h_target;\n\t\tduk_bool_t tmp_bool;\n\n\t\t/* XXX: the key in 'key in obj' is string coerced before we're called\n\t\t * (which is the required behavior in E5/E5.1/E6) so the key is a string\n\t\t * here already.\n\t\t */\n\n\t\tif (duk__proxy_check_prop(thr, obj, DUK_STRIDX_HAS, tv_key, &h_target)) {\n\t\t\t/* [ ... key trap handler ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'has' for key %!T\", (duk_tval *) tv_key));\n\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\tduk_push_tval(thr, tv_key);       /* P */\n\t\t\tduk_call_method(thr, 2 /*nargs*/);\n\t\t\ttmp_bool = duk_to_boolean_top_pop(thr);\n\t\t\tif (!tmp_bool) {\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'has': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\t\t\t\t\t/* XXX: Extensibility check for target uses IsExtensible().  If we\n\t\t\t\t\t * implemented the isExtensible trap and didn't reject proxies as\n\t\t\t\t\t * proxy targets, it should be respected here.\n\t\t\t\t\t */\n\t\t\t\t\tif (!((desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&  /* property is configurable and */\n\t\t\t\t\t      DUK_HOBJECT_HAS_EXTENSIBLE(h_target))) {          /* ... target is extensible */\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_pop_unsafe(thr);  /* [ key ] -> [] */\n\t\t\treturn tmp_bool;\n\t\t}\n\n\t\tobj = h_target;  /* resume check from proxy target */\n\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t/* XXX: inline into a prototype walking loop? */\n\n\trc = duk__get_propdesc(thr, obj, key, &desc, 0 /*flags*/);  /* don't push value */\n\t/* fall through */\n\n pop_and_return:\n\tduk_pop_unsafe(thr);  /* [ key ] -> [] */\n\treturn rc;\n}\n\n/*\n *  HASPROP variant used internally.\n *\n *  This primitive must never throw an error, callers rely on this.\n *  In particular, don't throw an error for prototype loops; instead,\n *  pretend like the property doesn't exist if a prototype sanity limit\n *  is reached.\n *\n *  Does not implement proxy behavior: if applied to a proxy object,\n *  returns key existence on the proxy object itself.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key) {\n\tduk_propdesc dummy;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\treturn duk__get_propdesc(thr, obj, key, &dummy, DUK_GETDESC_FLAG_IGNORE_PROTOLOOP);  /* don't push value */\n}\n\n/*\n *  Helper: handle Array object 'length' write which automatically\n *  deletes properties, see E5 Section 15.4.5.1, step 3.  This is\n *  quite tricky to get right.\n *\n *  Used by duk_hobject_putprop().\n */\n\n/* Coerce a new .length candidate to a number and check that it's a valid\n * .length.\n */\nDUK_LOCAL duk_uint32_t duk__to_new_array_length_checked(duk_hthread *thr, duk_tval *tv) {\n\tduk_uint32_t res;\n\tduk_double_t d;\n\n#if !defined(DUK_USE_PREFER_SIZE)\n#if defined(DUK_USE_FASTINT)\n\t/* When fastints are enabled, the most interesting case is assigning\n\t * a fastint to .length (e.g. arr.length = 0).\n\t */\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\t/* Very common case. */\n\t\tduk_int64_t fi;\n\t\tfi = DUK_TVAL_GET_FASTINT(tv);\n\t\tif (fi < 0 || fi > DUK_I64_CONSTANT(0xffffffff)) {\n\t\t\tgoto fail_range;\n\t\t}\n\t\treturn (duk_uint32_t) fi;\n\t}\n#else  /* DUK_USE_FASTINT */\n\t/* When fastints are not enabled, the most interesting case is any\n\t * number.\n\t */\n\tif (DUK_TVAL_IS_DOUBLE(tv)) {\n\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t}\n#endif  /* DUK_USE_FASTINT */\n\telse\n#endif  /* !DUK_USE_PREFER_SIZE */\n\t{\n\t\t/* In all other cases, and when doing a size optimized build,\n\t\t * fall back to the comprehensive handler.\n\t\t */\n\t\td = duk_js_tonumber(thr, tv);\n\t}\n\n\t/* Refuse to update an Array's 'length' to a value outside the\n\t * 32-bit range.  Negative zero is accepted as zero.\n\t */\n\tres = duk_double_to_uint32_t(d);\n\tif ((duk_double_t) res != d) {\n\t\tgoto fail_range;\n\t}\n\n\treturn res;\n\n fail_range:\n\tDUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARRAY_LENGTH);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Delete elements required by a smaller length, taking into account\n * potentially non-configurable elements.  Returns non-zero if all\n * elements could be deleted, and zero if all or some elements could\n * not be deleted.  Also writes final \"target length\" to 'out_result_len'.\n * This is the length value that should go into the 'length' property\n * (must be set by the caller).  Never throws an error.\n */\nDUK_LOCAL\nduk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr,\n                                                duk_hobject *obj,\n                                                duk_uint32_t old_len,\n                                                duk_uint32_t new_len,\n                                                duk_bool_t force_flag,\n                                                duk_uint32_t *out_result_len) {\n\tduk_uint32_t target_len;\n\tduk_uint_fast32_t i;\n\tduk_uint32_t arr_idx;\n\tduk_hstring *key;\n\tduk_tval *tv;\n\tduk_bool_t rc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"new array length smaller than old (%ld -> %ld), \"\n\t                     \"probably need to remove elements\",\n\t                     (long) old_len, (long) new_len));\n\n\t/*\n\t *  New length is smaller than old length, need to delete properties above\n\t *  the new length.\n\t *\n\t *  If array part exists, this is straightforward: array entries cannot\n\t *  be non-configurable so this is guaranteed to work.\n\t *\n\t *  If array part does not exist, array-indexed values are scattered\n\t *  in the entry part, and some may not be configurable (preventing length\n\t *  from becoming lower than their index + 1).  To handle the algorithm\n\t *  in E5 Section 15.4.5.1, step l correctly, we scan the entire property\n\t *  set twice.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(new_len < old_len);\n\tDUK_ASSERT(out_result_len != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj));\n\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY(obj));\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t/*\n\t\t *  All defined array-indexed properties are in the array part\n\t\t *  (we assume the array part is comprehensive), and all array\n\t\t *  entries are writable, configurable, and enumerable.  Thus,\n\t\t *  nothing can prevent array entries from being deleted.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"have array part, easy case\"));\n\n\t\tif (old_len < DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\t\t/* XXX: assertion that entries >= old_len are already unused */\n\t\t\ti = old_len;\n\t\t} else {\n\t\t\ti = DUK_HOBJECT_GET_ASIZE(obj);\n\t\t}\n\t\tDUK_ASSERT(i <= DUK_HOBJECT_GET_ASIZE(obj));\n\n\t\twhile (i > new_len) {\n\t\t\ti--;\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\t\tDUK_TVAL_SET_UNUSED_UPDREF(thr, tv);  /* side effects */\n\t\t}\n\n\t\t*out_result_len = new_len;\n\t\treturn 1;\n\t} else {\n\t\t/*\n\t\t *  Entries part is a bit more complex.\n\t\t */\n\n\t\t/* Stage 1: find highest preventing non-configurable entry (if any).\n\t\t * When forcing, ignore non-configurability.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"no array part, slow case\"));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part, stage 1: find target_len \"\n\t\t                     \"(highest preventing non-configurable entry (if any))\"));\n\n\t\ttarget_len = new_len;\n\t\tif (force_flag) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part; force flag -> skip stage 1\"));\n\t\t\tgoto skip_stage1;\n\t\t}\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);\n\t\t\tif (!key) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: null key\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!DUK_HSTRING_HAS_ARRIDX(key)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key not an array index\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(key));  /* XXX: macro checks for array index flag, which is unnecessary here */\n\t\t\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\t\t\tDUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX);\n\t\t\tDUK_ASSERT(arr_idx < old_len);  /* consistency requires this */\n\n\t\t\tif (arr_idx < new_len) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key is array index %ld, below new_len\",\n\t\t\t\t                     (long) i, (long) arr_idx));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(thr->heap, obj, i)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key is a relevant array index %ld, but configurable\",\n\t\t\t\t                     (long) i, (long) arr_idx));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* relevant array index is non-configurable, blocks write */\n\t\t\tif (arr_idx >= target_len) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"entry at index %ld has arr_idx %ld, is not configurable, \"\n\t\t\t\t                     \"update target_len %ld -> %ld\",\n\t\t\t\t                     (long) i, (long) arr_idx, (long) target_len,\n\t\t\t\t                     (long) (arr_idx + 1)));\n\t\t\t\ttarget_len = arr_idx + 1;\n\t\t\t}\n\t\t}\n\t skip_stage1:\n\n\t\t/* stage 2: delete configurable entries above target length */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"old_len=%ld, new_len=%ld, target_len=%ld\",\n\t\t                     (long) old_len, (long) new_len, (long) target_len));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part, stage 2: remove \"\n\t\t                     \"entries >= target_len\"));\n\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);\n\t\t\tif (!key) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: null key\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!DUK_HSTRING_HAS_ARRIDX(key)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key not an array index\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(key));  /* XXX: macro checks for array index flag, which is unnecessary here */\n\t\t\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\t\t\tDUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX);\n\t\t\tDUK_ASSERT(arr_idx < old_len);  /* consistency requires this */\n\n\t\t\tif (arr_idx < target_len) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key is array index %ld, below target_len\",\n\t\t\t\t                     (long) i, (long) arr_idx));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tDUK_ASSERT(force_flag || DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(thr->heap, obj, i));  /* stage 1 guarantees */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"delete entry index %ld: key is array index %ld\",\n\t\t\t                     (long) i, (long) arr_idx));\n\n\t\t\t/*\n\t\t\t *  Slow delete, but we don't care as we're already in a very slow path.\n\t\t\t *  The delete always succeeds: key has no exotic behavior, property\n\t\t\t *  is configurable, and no resize occurs.\n\t\t\t */\n\t\t\trc = duk_hobject_delprop_raw(thr, obj, key, force_flag ? DUK_DELPROP_FLAG_FORCE : 0);\n\t\t\tDUK_UNREF(rc);\n\t\t\tDUK_ASSERT(rc != 0);\n\t\t}\n\n\t\t/* stage 3: update length (done by caller), decide return code */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part, stage 3: update length (done by caller)\"));\n\n\t\t*out_result_len = target_len;\n\n\t\tif (target_len == new_len) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"target_len matches new_len, return success\"));\n\t\t\treturn 1;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"target_len does not match new_len (some entry prevented \"\n\t\t                     \"full length adjustment), return error\"));\n\t\treturn 0;\n\t}\n\n\tDUK_UNREACHABLE();\n}\n\n/* XXX: is valstack top best place for argument? */\nDUK_LOCAL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject *obj) {\n\tduk_harray *a;\n\tduk_uint32_t old_len;\n\tduk_uint32_t new_len;\n\tduk_uint32_t result_len;\n\tduk_bool_t rc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"handling a put operation to array 'length' exotic property, \"\n\t                     \"new val: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj));\n\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY(obj));\n\ta = (duk_harray *) obj;\n\tDUK_HARRAY_ASSERT_VALID(a);\n\n\tDUK_ASSERT(duk_is_valid_index(thr, -1));\n\n\t/*\n\t *  Get old and new length\n\t */\n\n\told_len = a->length;\n\tnew_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_NEGIDX(thr, -1));\n\tDUK_DDD(DUK_DDDPRINT(\"old_len=%ld, new_len=%ld\", (long) old_len, (long) new_len));\n\n\t/*\n\t *  Writability check\n\t */\n\n\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"length is not writable, fail\"));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  New length not lower than old length => no changes needed\n\t *  (not even array allocation).\n\t */\n\n\tif (new_len >= old_len) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"new length is same or higher than old length, just update length, no deletions\"));\n\t\ta->length = new_len;\n\t\treturn 1;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"new length is lower than old length, probably must delete entries\"));\n\n\t/*\n\t *  New length lower than old length => delete elements, then\n\t *  update length.\n\t *\n\t *  Note: even though a bunch of elements have been deleted, the 'desc' is\n\t *  still valid as properties haven't been resized (and entries compacted).\n\t */\n\n\trc = duk__handle_put_array_length_smaller(thr, obj, old_len, new_len, 0 /*force_flag*/, &result_len);\n\tDUK_ASSERT(result_len >= new_len && result_len <= old_len);\n\n\ta->length = result_len;\n\n\t/* XXX: shrink array allocation or entries compaction here? */\n\n\treturn rc;\n}\n\n/*\n *  PUTPROP: ECMAScript property write.\n *\n *  Unlike ECMAScript primitive which returns nothing, returns 1 to indicate\n *  success and 0 to indicate failure (assuming throw is not set).\n *\n *  This is an extremely tricky function.  Some examples:\n *\n *    * Currently a decref may trigger a GC, which may compact an object's\n *      property allocation.  Consequently, any entry indices (e_idx) will\n *      be potentially invalidated by a decref.\n *\n *    * Exotic behaviors (strings, arrays, arguments object) require,\n *      among other things:\n *\n *      - Preprocessing before and postprocessing after an actual property\n *        write.  For example, array index write requires pre-checking the\n *        array 'length' property for access control, and may require an\n *        array 'length' update after the actual write has succeeded (but\n *        not if it fails).\n *\n *      - Deletion of multiple entries, as a result of array 'length' write.\n *\n *    * Input values are taken as pointers which may point to the valstack.\n *      If valstack is resized because of the put (this may happen at least\n *      when the array part is abandoned), the pointers can be invalidated.\n *      (We currently make a copy of all of the input values to avoid issues.)\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_tval *tv_val, duk_bool_t throw_flag) {\n\tduk_tval tv_obj_copy;\n\tduk_tval tv_key_copy;\n\tduk_tval tv_val_copy;\n\tduk_hobject *orig = NULL;  /* NULL if tv_obj is primitive */\n\tduk_hobject *curr;\n\tduk_hstring *key = NULL;\n\tduk_propdesc desc;\n\tduk_tval *tv;\n\tduk_uint32_t arr_idx;\n\tduk_bool_t rc;\n\tduk_int_t e_idx;\n\tduk_uint_t sanity;\n\tduk_uint32_t new_array_length = 0;  /* 0 = no update */\n\n\tDUK_DDD(DUK_DDDPRINT(\"putprop: thr=%p, obj=%p, key=%p, val=%p, throw=%ld \"\n\t                     \"(obj -> %!T, key -> %!T, val -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key, (void *) tv_val,\n\t                     (long) throw_flag, (duk_tval *) tv_obj, (duk_tval *) tv_key, (duk_tval *) tv_val));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\tDUK_ASSERT(tv_val != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_putprop_all);\n\n\t/*\n\t *  Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of\n\t *  them being invalidated by a valstack resize.\n\t *\n\t *  XXX: this is an overkill for some paths, so optimize this later\n\t *  (or maybe switch to a stack arguments model entirely).\n\t */\n\n\tDUK_TVAL_SET_TVAL(&tv_obj_copy, tv_obj);\n\tDUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);\n\tDUK_TVAL_SET_TVAL(&tv_val_copy, tv_val);\n\ttv_obj = &tv_obj_copy;\n\ttv_key = &tv_key_copy;\n\ttv_val = &tv_val_copy;\n\n\t/*\n\t *  Coercion and fast path processing.\n\t */\n\n\tswitch (DUK_TVAL_GET_TAG(tv_obj)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL: {\n\t\t/* Note: unconditional throw */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is undefined or null -> reject (object=%!iT)\",\n\t\t                     (duk_tval *) tv_obj));\n#if defined(DUK_USE_PARANOID_ERRORS)\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\t\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot write property %s of %s\",\n\t\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\t\tDUK_WO_NORETURN(return 0;);\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a boolean, start lookup from boolean prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);\n\n\t\t/*\n\t\t *  Note: currently no fast path for array index writes.\n\t\t *  They won't be possible anyway as strings are immutable.\n\t\t */\n\n\t\tDUK_ASSERT(key == NULL);\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\t/* Symbols (ES2015 or hidden) don't have virtual properties. */\n\t\t\tcurr = thr->builtins[DUK_BIDX_SYMBOL_PROTOTYPE];\n\t\t\tgoto lookup;\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_writable;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {\n\t\t\tgoto fail_not_writable;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a string, start lookup from string prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_STRING_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_OBJECT: {\n\t\torig = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(orig != NULL);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\t\t/* With this check in place fast paths won't need read-only\n\t\t * object checks.  This is technically incorrect if there are\n\t\t * setters that cause no writes to ROM objects, but current\n\t\t * built-ins don't have such setters.\n\t\t */\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"attempt to putprop on read-only target object\"));\n\t\t\tgoto fail_not_writable_no_pop;  /* Must avoid duk_pop() in exit path */\n\t\t}\n#endif\n\n\t\t/* The fast path for array property put is not fully compliant:\n\t\t * If one places conflicting number-indexed properties into\n\t\t * Array.prototype (for example, a non-writable Array.prototype[7])\n\t\t * the fast path will incorrectly ignore them.\n\t\t *\n\t\t * This fast path could be made compliant by falling through\n\t\t * to the slow path if the previous value was UNUSED.  This would\n\t\t * also remove the need to check for extensibility.  Right now a\n\t\t * non-extensible array is slower than an extensible one as far\n\t\t * as writes are concerned.\n\t\t *\n\t\t * The fast path behavior is documented in more detail here:\n\t\t * tests/ecmascript/test-misc-array-fast-write.js\n\t\t */\n\n\t\t/* XXX: array .length? */\n\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\n\t\tif (duk__putprop_shallow_fastpath_array_tval(thr, orig, tv_key, tv_val) != 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array fast path success\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_arrayidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (duk__putprop_fastpath_bufobj_tval(thr, orig, tv_key, tv_val) != 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base is bufobj, key is a number, bufobj fast path\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_bufobjidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(orig))) {\n\t\t\tduk_hobject *h_target;\n\t\t\tduk_bool_t tmp_bool;\n\n\t\t\tif (duk__proxy_check_prop(thr, orig, DUK_STRIDX_SET, tv_key, &h_target)) {\n\t\t\t\t/* -> [ ... trap handler ] */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'set' for key %!T\", (duk_tval *) tv_key));\n\t\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_proxy);\n\t\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\t\tduk_push_tval(thr, tv_key);       /* P */\n\t\t\t\tduk_push_tval(thr, tv_val);       /* V */\n\t\t\t\tduk_push_tval(thr, tv_obj);       /* Receiver: Proxy object */\n\t\t\t\tduk_call_method(thr, 4 /*nargs*/);\n\t\t\t\ttmp_bool = duk_to_boolean_top_pop(thr);\n\t\t\t\tif (!tmp_bool) {\n\t\t\t\t\tgoto fail_proxy_rejected;\n\t\t\t\t}\n\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\t\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\t\t\t\tduk_tval *tv_targ = duk_require_tval(thr, -1);\n\t\t\t\t\tduk_bool_t datadesc_reject;\n\t\t\t\t\tduk_bool_t accdesc_reject;\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'set': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; tv_val=%!T, tv_targ=%!T, desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (duk_tval *) tv_val, (duk_tval *) tv_targ,\n\t\t\t\t\t                     (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\n\t\t\t\t\tdatadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) &&\n\t\t\t\t\t                  !duk_js_samevalue(tv_val, tv_targ);\n\t\t\t\t\taccdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                 !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                 (desc.set == NULL);\n\t\t\t\t\tif (datadesc_reject || accdesc_reject) {\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\n\t\t\t\t\tduk_pop_2_unsafe(thr);\n\t\t\t\t} else {\n\t\t\t\t\tduk_pop_unsafe(thr);\n\t\t\t\t}\n\t\t\t\treturn 1;  /* success */\n\t\t\t}\n\n\t\t\torig = h_target;  /* resume write to target */\n\t\t\tDUK_TVAL_SET_OBJECT(tv_obj, orig);\n\t\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t\tcurr = orig;\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_BUFFER: {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);\n\t\tduk_int_t pop_count = 0;\n\n\t\t/*\n\t\t *  Because buffer values may be looped over and read/written\n\t\t *  from, an array index fast path is important.\n\t\t */\n\n#if defined(DUK_USE_FASTINT)\n\t\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\t\tarr_idx = duk__tval_fastint_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path fastint; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else\n#endif\n\t\tif (DUK_TVAL_IS_NUMBER(tv_key)) {\n\t\t\tarr_idx = duk__tval_number_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path number; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t\tpop_count = 1;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HBUFFER_GET_SIZE(h)) {\n\t\t\tduk_uint8_t *data;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"writing to buffer data at index %ld\", (long) arr_idx));\n\t\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);\n\n\t\t\t/* XXX: duk_to_int() ensures we'll get 8 lowest bits as\n\t\t\t * as input is within duk_int_t range (capped outside it).\n\t\t\t */\n#if defined(DUK_USE_FASTINT)\n\t\t\t/* Buffer writes are often integers. */\n\t\t\tif (DUK_TVAL_IS_FASTINT(tv_val)) {\n\t\t\t\tdata[arr_idx] = (duk_uint8_t) DUK_TVAL_GET_FASTINT_U32(tv_val);\n\t\t\t}\n\t\t\telse\n#endif\n\t\t\t{\n\t\t\t\tduk_push_tval(thr, tv_val);\n\t\t\t\tdata[arr_idx] = (duk_uint8_t) duk_to_uint32(thr, -1);\n\t\t\t\tpop_count++;\n\t\t\t}\n\n\t\t\tduk_pop_n_unsafe(thr, pop_count);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"result: success (buffer data write)\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_bufferidx);\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (pop_count == 0) {\n\t\t\t/* This is a pretty awkward control flow, but we need to recheck the\n\t\t\t * key coercion here.\n\t\t\t */\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_writable;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a buffer, start lookup from Uint8Array prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_POINTER: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a pointer, start lookup from pointer prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Lightfuncs have no own properties and are considered non-extensible.\n\t\t * However, the write may be captured by an inherited setter which\n\t\t * means we can't stop the lookup here.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a lightfunc, start lookup from function prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE];\n\t\tbreak;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a number, start lookup from number prototype\"));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_obj));\n\t\tcurr = thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE];\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_ASSERT(key == NULL);\n\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\tDUK_ASSERT(key != NULL);\n\n lookup:\n\n\t/*\n\t *  Check whether the property already exists in the prototype chain.\n\t *  Note that the actual write goes into the original base object\n\t *  (except if an accessor property captures the write).\n\t */\n\n\t/* [key] */\n\n\tDUK_ASSERT(curr != NULL);\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (!duk__get_own_propdesc_raw(thr, curr, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\t\tgoto next_in_chain;\n\t\t}\n\n\t\tif (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t/*\n\t\t\t *  Found existing accessor property (own or inherited).\n\t\t\t *  Call setter with 'this' set to orig, and value as the only argument.\n\t\t\t *  Setter calls are OK even for ROM objects.\n\t\t\t *\n\t\t\t *  Note: no exotic arguments object behavior, because [[Put]] never\n\t\t\t *  calls [[DefineOwnProperty]] (E5 Section 8.12.5, step 5.b).\n\t\t\t */\n\n\t\t\tduk_hobject *setter;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"put to an own or inherited accessor, calling setter\"));\n\n\t\t\tsetter = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, curr, desc.e_idx);\n\t\t\tif (!setter) {\n\t\t\t\tgoto fail_no_setter;\n\t\t\t}\n\t\t\tduk_push_hobject(thr, setter);\n\t\t\tduk_push_tval(thr, tv_obj);  /* note: original, uncoerced base */\n\t\t\tduk_push_tval(thr, tv_val);  /* [key setter this val] */\n#if defined(DUK_USE_NONSTD_SETTER_KEY_ARGUMENT)\n\t\t\tduk_dup_m4(thr);\n\t\t\tduk_call_method(thr, 2);     /* [key setter this val key] -> [key retval] */\n#else\n\t\t\tduk_call_method(thr, 1);     /* [key setter this val] -> [key retval] */\n#endif\n\t\t\tduk_pop_unsafe(thr);         /* ignore retval -> [key] */\n\t\t\tgoto success_no_arguments_exotic;\n\t\t}\n\n\t\tif (orig == NULL) {\n\t\t\t/*\n\t\t\t *  Found existing own or inherited plain property, but original\n\t\t\t *  base is a primitive value.\n\t\t\t */\n\t\t\tDUK_DD(DUK_DDPRINT(\"attempt to create a new property in a primitive base object\"));\n\t\t\tgoto fail_base_primitive;\n\t\t}\n\n\t\tif (curr != orig) {\n\t\t\t/*\n\t\t\t *  Found existing inherited plain property.\n\t\t\t *  Do an access control check, and if OK, write\n\t\t\t *  new property to 'orig'.\n\t\t\t */\n\t\t\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(orig)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing inherited plain property, but original object is not extensible\"));\n\t\t\t\tgoto fail_not_extensible;\n\t\t\t}\n\t\t\tif (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing inherited plain property, original object is extensible, but inherited property is not writable\"));\n\t\t\t\tgoto fail_not_writable;\n\t\t\t}\n\t\t\tDUK_DD(DUK_DDPRINT(\"put to new property, object extensible, inherited property found and is writable\"));\n\t\t\tgoto create_new;\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Found existing own (non-inherited) plain property.\n\t\t\t *  Do an access control check and update in place.\n\t\t\t */\n\n\t\t\tif (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing own (non-inherited) plain property, but property is not writable\"));\n\t\t\t\tgoto fail_not_writable;\n\t\t\t}\n\t\t\tif (desc.flags & DUK_PROPDESC_FLAG_VIRTUAL) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing own (non-inherited) virtual property, property is writable\"));\n\n\t\t\t\tif (DUK_HOBJECT_IS_ARRAY(curr)) {\n\t\t\t\t\t/*\n\t\t\t\t\t *  Write to 'length' of an array is a very complex case\n\t\t\t\t\t *  handled in a helper which updates both the array elements\n\t\t\t\t\t *  and writes the new 'length'.  The write may result in an\n\t\t\t\t\t *  unconditional RangeError or a partial write (indicated\n\t\t\t\t\t *  by a return code).\n\t\t\t\t\t *\n\t\t\t\t\t *  Note: the helper has an unnecessary writability check\n\t\t\t\t\t *  for 'length', we already know it is writable.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_ASSERT(key == DUK_HTHREAD_STRING_LENGTH(thr));  /* only virtual array property */\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"writing existing 'length' property to array exotic, invoke complex helper\"));\n\n\t\t\t\t\t/* XXX: the helper currently assumes stack top contains new\n\t\t\t\t\t * 'length' value and the whole calling convention is not very\n\t\t\t\t\t * compatible with what we need.\n\t\t\t\t\t */\n\n\t\t\t\t\tduk_push_tval(thr, tv_val);  /* [key val] */\n\t\t\t\t\trc = duk__handle_put_array_length(thr, orig);\n\t\t\t\t\tduk_pop_unsafe(thr);  /* [key val] -> [key] */\n\t\t\t\t\tif (!rc) {\n\t\t\t\t\t\tgoto fail_array_length_partial;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* key is 'length', cannot match argument exotic behavior */\n\t\t\t\t\tgoto success_no_arguments_exotic;\n\t\t\t\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t\t\telse if (DUK_HOBJECT_IS_BUFOBJ(curr)) {\n\t\t\t\t\tduk_hbufobj *h_bufobj;\n\t\t\t\t\tduk_uint_t byte_off;\n\t\t\t\t\tduk_small_uint_t elem_size;\n\n\t\t\t\t\th_bufobj = (duk_hbufobj *) curr;\n\t\t\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"writable virtual property is in buffer object\"));\n\n\t\t\t\t\t/* Careful with wrapping: arr_idx upshift may easily wrap, whereas\n\t\t\t\t\t * length downshift won't.\n\t\t\t\t\t */\n\t\t\t\t\tif (arr_idx < (h_bufobj->length >> h_bufobj->shift) && DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\t\t\t\t\tduk_uint8_t *data;\n\t\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"writing to buffer data at index %ld\", (long) arr_idx));\n\n\t\t\t\t\t\tDUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX);  /* index/length check guarantees */\n\t\t\t\t\t\tbyte_off = arr_idx << h_bufobj->shift;       /* no wrap assuming h_bufobj->length is valid */\n\t\t\t\t\t\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\n\t\t\t\t\t\t/* Coerce to number before validating pointers etc so that the\n\t\t\t\t\t\t * number coercions in duk_hbufobj_validated_write() are\n\t\t\t\t\t\t * guaranteed to be side effect free and not invalidate the\n\t\t\t\t\t\t * pointer checks we do here.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk_push_tval(thr, tv_val);\n\t\t\t\t\t\t(void) duk_to_number_m1(thr);\n\n\t\t\t\t\t\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\t\t\t\t\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\t\t\t\t\t\tduk_hbufobj_validated_write(thr, h_bufobj, data, elem_size);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (write skipped)\"));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tduk_pop_unsafe(thr);\n\t\t\t\t\t\tgoto success_no_arguments_exotic;\n\t\t\t\t\t}\n\t\t\t\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\t\t\t\tDUK_D(DUK_DPRINT(\"should not happen, key %!O\", key));\n\t\t\t\tgoto fail_internal;  /* should not happen */\n\t\t\t}\n\t\t\tDUK_DD(DUK_DDPRINT(\"put to existing own plain property, property is writable\"));\n\t\t\tgoto update_old;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\n\t next_in_chain:\n\t\t/* XXX: option to pretend property doesn't exist if sanity limit is\n\t\t * hit might be useful.\n\t\t */\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t} while (curr != NULL);\n\n\t/*\n\t *  Property not found in prototype chain.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"property not found in prototype chain\"));\n\n\tif (orig == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to create a new property in a primitive base object\"));\n\t\tgoto fail_base_primitive;\n\t}\n\n\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(orig)) {\n\t\tDUK_DD(DUK_DDPRINT(\"put to a new property (not found in prototype chain), but original object not extensible\"));\n\t\tgoto fail_not_extensible;\n\t}\n\n\tgoto create_new;\n\n update_old:\n\n\t/*\n\t *  Update an existing property of the base object.\n\t */\n\n\t/* [key] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"update an existing property of the original object\"));\n\n\tDUK_ASSERT(orig != NULL);\n#if defined(DUK_USE_ROM_OBJECTS)\n\t/* This should not happen because DUK_TAG_OBJECT case checks\n\t * for this already, but check just in case.\n\t */\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {\n\t\tgoto fail_not_writable;\n\t}\n#endif\n\n\t/* Although there are writable virtual properties (e.g. plain buffer\n\t * and buffer object number indices), they are handled before we come\n\t * here.\n\t */\n\tDUK_ASSERT((desc.flags & DUK_PROPDESC_FLAG_VIRTUAL) == 0);\n\tDUK_ASSERT(desc.a_idx >= 0 || desc.e_idx >= 0);\n\n\t/* Array own property .length is handled above. */\n\tDUK_ASSERT(!(DUK_HOBJECT_IS_ARRAY(orig) && key == DUK_HTHREAD_STRING_LENGTH(thr)));\n\n\tif (desc.e_idx >= 0) {\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, desc.e_idx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"previous entry value: %!iT\", (duk_tval *) tv));\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val);  /* side effects; e_idx may be invalidated */\n\t\t/* don't touch property attributes or hash part */\n\t\tDUK_DD(DUK_DDPRINT(\"put to an existing entry at index %ld -> new value %!iT\",\n\t\t                   (long) desc.e_idx, (duk_tval *) tv));\n\t} else {\n\t\t/* Note: array entries are always writable, so the writability check\n\t\t * above is pointless for them.  The check could be avoided with some\n\t\t * refactoring but is probably not worth it.\n\t\t */\n\n\t\tDUK_ASSERT(desc.a_idx >= 0);\n\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, orig, desc.a_idx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"previous array value: %!iT\", (duk_tval *) tv));\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val);  /* side effects; a_idx may be invalidated */\n\t\tDUK_DD(DUK_DDPRINT(\"put to an existing array entry at index %ld -> new value %!iT\",\n\t\t                   (long) desc.a_idx, (duk_tval *) tv));\n\t}\n\n\t/* Regardless of whether property is found in entry or array part,\n\t * it may have arguments exotic behavior (array indices may reside\n\t * in entry part for abandoned / non-existent array parts).\n\t */\n\tgoto success_with_arguments_exotic;\n\n create_new:\n\n\t/*\n\t *  Create a new property in the original object.\n\t *\n\t *  Exotic properties need to be reconsidered here from a write\n\t *  perspective (not just property attributes perspective).\n\t *  However, the property does not exist in the object already,\n\t *  so this limits the kind of exotic properties that apply.\n\t */\n\n\t/* [key] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"create new property to original object\"));\n\n\tDUK_ASSERT(orig != NULL);\n\n\t/* Array own property .length is handled above. */\n\tDUK_ASSERT(!(DUK_HOBJECT_IS_ARRAY(orig) && key == DUK_HTHREAD_STRING_LENGTH(thr)));\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\t/* This should not happen because DUK_TAG_OBJECT case checks\n\t * for this already, but check just in case.\n\t */\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {\n\t\tgoto fail_not_writable;\n\t}\n#endif\n\n\t/* Not possible because array object 'length' is present\n\t * from its creation and cannot be deleted, and is thus\n\t * caught as an existing property above.\n\t */\n\tDUK_ASSERT(!(DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig) &&\n\t             key == DUK_HTHREAD_STRING_LENGTH(thr)));\n\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig) &&\n\t    arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t/* automatic length update */\n\t\tduk_uint32_t old_len;\n\t\tduk_harray *a;\n\n\t\ta = (duk_harray *) orig;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\told_len = a->length;\n\n\t\tif (arr_idx >= old_len) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"write new array entry requires length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\n\t\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"attempt to extend array, but array 'length' is not writable\"));\n\t\t\t\tgoto fail_not_writable;\n\t\t\t}\n\n\t\t\t/* Note: actual update happens once write has been completed\n\t\t\t * without error below.  The write should always succeed\n\t\t\t * from a specification viewpoint, but we may e.g. run out\n\t\t\t * of memory.  It's safer in this order.\n\t\t\t */\n\n\t\t\tDUK_ASSERT(arr_idx != 0xffffffffUL);\n\t\t\tnew_array_length = arr_idx + 1;  /* flag for later write */\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"write new array entry does not require length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\t\t}\n\t}\n\n /* write_to_array_part: */\n\n\t/*\n\t *  Write to array part?\n\t *\n\t *  Note: array abandonding requires a property resize which uses\n\t *  'rechecks' valstack for temporaries and may cause any existing\n\t *  valstack pointers to be invalidated.  To protect against this,\n\t *  tv_obj, tv_key, and tv_val are copies of the original inputs.\n\t */\n\n\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(orig)) {\n\t\ttv = duk__obtain_arridx_slot(thr, arr_idx, orig);\n\t\tif (tv == NULL) {\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(orig));\n\t\t\tgoto write_to_entry_part;\n\t\t}\n\n\t\t/* prev value must be unused, no decref */\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_TVAL_SET_TVAL(tv, tv_val);\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\tDUK_DD(DUK_DDPRINT(\"put to new array entry: %ld -> %!T\",\n\t\t                   (long) arr_idx, (duk_tval *) tv));\n\n\t\t/* Note: array part values are [[Writable]], [[Enumerable]],\n\t\t * and [[Configurable]] which matches the required attributes\n\t\t * here.\n\t\t */\n\t\tgoto entry_updated;\n\t}\n\n write_to_entry_part:\n\n\t/*\n\t *  Write to entry part\n\t */\n\n\t/* entry allocation updates hash part and increases the key\n\t * refcount; may need a props allocation resize but doesn't\n\t * 'recheck' the valstack.\n\t */\n\te_idx = duk__hobject_alloc_entry_checked(thr, orig, key);\n\tDUK_ASSERT(e_idx >= 0);\n\n\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, e_idx);\n\t/* prev value can be garbage, no decref */\n\tDUK_TVAL_SET_TVAL(tv, tv_val);\n\tDUK_TVAL_INCREF(thr, tv);\n\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, orig, e_idx, DUK_PROPDESC_FLAGS_WEC);\n\tgoto entry_updated;\n\n entry_updated:\n\n\t/*\n\t *  Possible pending array length update, which must only be done\n\t *  if the actual entry write succeeded.\n\t */\n\n\tif (new_array_length > 0) {\n\t\t/* Note: zero works as a \"no update\" marker because the new length\n\t\t * can never be zero after a new property is written.\n\t\t */\n\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"write successful, pending array length update to: %ld\",\n\t\t                     (long) new_array_length));\n\n\t\t((duk_harray *) orig)->length = new_array_length;\n\t}\n\n\t/*\n\t *  Arguments exotic behavior not possible for new properties: all\n\t *  magically bound properties are initially present in the arguments\n\t *  object, and if they are deleted, the binding is also removed from\n\t *  parameter map.\n\t */\n\n\tgoto success_no_arguments_exotic;\n\n success_with_arguments_exotic:\n\n\t/*\n\t *  Arguments objects have exotic [[DefineOwnProperty]] which updates\n\t *  the internal 'map' of arguments for writes to currently mapped\n\t *  arguments.  More conretely, writes to mapped arguments generate\n\t *  a write to a bound variable.\n\t *\n\t *  The [[Put]] algorithm invokes [[DefineOwnProperty]] for existing\n\t *  data properties and new properties, but not for existing accessors.\n\t *  Hence, in E5 Section 10.6 ([[DefinedOwnProperty]] algorithm), we\n\t *  have a Desc with 'Value' (and possibly other properties too), and\n\t *  we end up in step 5.b.i.\n\t */\n\n\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t    DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(orig)) {\n\t\t/* Note: only numbered indices are relevant, so arr_idx fast reject\n\t\t * is good (this is valid unless there are more than 4**32-1 arguments).\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"putprop successful, arguments exotic behavior needed\"));\n\n\t\t/* Note: we can reuse 'desc' here */\n\n\t\t/* XXX: top of stack must contain value, which helper doesn't touch,\n\t\t * rework to use tv_val directly?\n\t\t */\n\n\t\tduk_push_tval(thr, tv_val);\n\t\t(void) duk__check_arguments_map_for_put(thr, orig, key, &desc, throw_flag);\n\t\tduk_pop_unsafe(thr);\n\t}\n\t/* fall thru */\n\n success_no_arguments_exotic:\n\t/* shared exit path now */\n\tDUK_DDD(DUK_DDDPRINT(\"result: success\"));\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 1;\n\n#if defined(DUK_USE_ES6_PROXY)\n fail_proxy_rejected:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, proxy rejects\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\t/* Note: no key on stack */\n\treturn 0;\n#endif\n\n fail_base_primitive:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, base primitive\"));\n\tif (throw_flag) {\n#if defined(DUK_USE_PARANOID_ERRORS)\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\t\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot write property %s of %s\",\n\t\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_not_extensible:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, not extensible\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_not_writable:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, not writable\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n#if defined(DUK_USE_ROM_OBJECTS)\n fail_not_writable_no_pop:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, not writable\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n#endif\n\n fail_array_length_partial:\n\tDUK_DD(DUK_DDPRINT(\"result: error, array length write only partially successful\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_no_setter:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, accessor property without setter\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_SETTER_UNDEFINED);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_internal:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, internal\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_INTERNAL(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n}\n\n/*\n *  ECMAScript compliant [[Delete]](P, Throw).\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags) {\n\tduk_propdesc desc;\n\tduk_tval *tv;\n\tduk_uint32_t arr_idx;\n\tduk_bool_t throw_flag;\n\tduk_bool_t force_flag;\n\n\tthrow_flag = (flags & DUK_DELPROP_FLAG_THROW);\n\tforce_flag = (flags & DUK_DELPROP_FLAG_FORCE);\n\n\tDUK_DDD(DUK_DDDPRINT(\"delprop_raw: thr=%p, obj=%p, key=%p, throw=%ld, force=%ld (obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (long) throw_flag, (long) force_flag,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);\n\n\t/* 0 = don't push current value */\n\tif (!duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\tDUK_DDD(DUK_DDDPRINT(\"property not found, succeed always\"));\n\t\tgoto success;\n\t}\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to delprop on read-only target object\"));\n\t\tgoto fail_not_configurable;\n\t}\n#endif\n\n\tif ((desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) == 0 && !force_flag) {\n\t\tgoto fail_not_configurable;\n\t}\n\tif (desc.a_idx < 0 && desc.e_idx < 0) {\n\t\t/* Currently there are no deletable virtual properties, but\n\t\t * with force_flag we might attempt to delete one.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"delete failed: property found, force flag, but virtual (and implicitly non-configurable)\"));\n\t\tgoto fail_virtual;\n\t}\n\n\tif (desc.a_idx >= 0) {\n\t\tDUK_ASSERT(desc.e_idx < 0);\n\n\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx);\n\t\tDUK_TVAL_SET_UNUSED_UPDREF(thr, tv);  /* side effects */\n\t\tgoto success;\n\t} else {\n\t\tDUK_ASSERT(desc.a_idx < 0);\n\n\t\t/* remove hash entry (no decref) */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\t\tif (desc.h_idx >= 0) {\n\t\t\tduk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(thr->heap, obj);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"removing hash entry at h_idx %ld\", (long) desc.h_idx));\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) > 0);\n\t\t\tDUK_ASSERT((duk_uint32_t) desc.h_idx < DUK_HOBJECT_GET_HSIZE(obj));\n\t\t\th_base[desc.h_idx] = DUK__HASH_DELETED;\n\t\t} else {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) == 0);\n\t\t}\n#else\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) == 0);\n#endif\n\n\t\t/* Remove value.  This requires multiple writes so avoid side\n\t\t * effects via no-refzero macros so that e_idx is not\n\t\t * invalidated.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"before removing value, e_idx %ld, key %p, key at slot %p\",\n\t\t                     (long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)));\n\t\tDUK_DDD(DUK_DDDPRINT(\"removing value at e_idx %ld\", (long) desc.e_idx));\n\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx)) {\n\t\t\tduk_hobject *tmp;\n\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, desc.e_idx);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, desc.e_idx, NULL);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, desc.e_idx);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, desc.e_idx, NULL);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\t\t} else {\n\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t\t}\n#if 0\n\t\t/* Not strictly necessary because if key == NULL, flag MUST be ignored. */\n\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, 0);\n#endif\n\n\t\t/* Remove key. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"before removing key, e_idx %ld, key %p, key at slot %p\",\n\t\t                     (long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)));\n\t\tDUK_DDD(DUK_DDDPRINT(\"removing key at e_idx %ld\", (long) desc.e_idx));\n\t\tDUK_ASSERT(key == DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx));\n\t\tDUK_HOBJECT_E_SET_KEY(thr->heap, obj, desc.e_idx, NULL);\n\t\tDUK_HSTRING_DECREF_NORZ(thr, key);\n\n\t\t/* Trigger refzero side effects only when we're done as a\n\t\t * finalizer might operate on the object and affect the\n\t\t * e_idx we're supposed to use.\n\t\t */\n\t\tDUK_REFZERO_CHECK_SLOW(thr);\n\t\tgoto success;\n\t}\n\n\tDUK_UNREACHABLE();\n\n success:\n\t/*\n\t *  Argument exotic [[Delete]] behavior (E5 Section 10.6) is\n\t *  a post-check, keeping arguments internal 'map' in sync with\n\t *  any successful deletes (note that property does not need to\n\t *  exist for delete to 'succeed').\n\t *\n\t *  Delete key from 'map'.  Since 'map' only contains array index\n\t *  keys, we can use arr_idx for a fast skip.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"delete successful, check for arguments exotic behavior\"));\n\n\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)) {\n\t\t/* Note: only numbered indices are relevant, so arr_idx fast reject\n\t\t * is good (this is valid unless there are more than 4**32-1 arguments).\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"delete successful, arguments exotic behavior needed\"));\n\n\t\t/* Note: we can reuse 'desc' here */\n\t\t(void) duk__check_arguments_map_for_delete(thr, obj, key, &desc);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"delete successful\"));\n\treturn 1;\n\n fail_virtual:  /* just use the same \"not configurable\" error message */\n fail_not_configurable:\n\tDUK_DDD(DUK_DDDPRINT(\"delete failed: property found, not configurable\"));\n\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n}\n\n/*\n *  DELPROP: ECMAScript property deletion.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_bool_t throw_flag) {\n\tduk_hstring *key = NULL;\n#if defined(DUK_USE_ES6_PROXY)\n\tduk_propdesc desc;\n#endif\n\tduk_int_t entry_top;\n\tduk_uint32_t arr_idx = DUK__NO_ARRAY_INDEX;\n\tduk_bool_t rc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"delprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key,\n\t                     (duk_tval *) tv_obj, (duk_tval *) tv_key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\t/* Storing the entry top is cheaper here to ensure stack is correct at exit,\n\t * as there are several paths out.\n\t */\n\tentry_top = duk_get_top(thr);\n\n\tif (DUK_TVAL_IS_UNDEFINED(tv_obj) ||\n\t    DUK_TVAL_IS_NULL(tv_obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is undefined or null -> reject\"));\n\t\tgoto fail_invalid_base_uncond;\n\t}\n\n\tduk_push_tval(thr, tv_obj);\n\tduk_push_tval(thr, tv_key);\n\n\ttv_obj = DUK_GET_TVAL_NEGIDX(thr, -2);\n\tif (DUK_TVAL_IS_OBJECT(tv_obj)) {\n\t\tduk_hobject *obj = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(obj != NULL);\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(obj))) {\n\t\t\tduk_hobject *h_target;\n\t\t\tduk_bool_t tmp_bool;\n\n\t\t\t/* Note: proxy handling must happen before key is string coerced. */\n\n\t\t\tif (duk__proxy_check_prop(thr, obj, DUK_STRIDX_DELETE_PROPERTY, tv_key, &h_target)) {\n\t\t\t\t/* -> [ ... obj key trap handler ] */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'deleteProperty' for key %!T\", (duk_tval *) tv_key));\n\t\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\t\tduk_dup_m4(thr);  /* P */\n\t\t\t\tduk_call_method(thr, 2 /*nargs*/);\n\t\t\t\ttmp_bool = duk_to_boolean_top_pop(thr);\n\t\t\t\tif (!tmp_bool) {\n\t\t\t\t\tgoto fail_proxy_rejected;  /* retval indicates delete failed */\n\t\t\t\t}\n\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\t\t\t\ttv_key = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\t\t\t\tduk_small_int_t desc_reject;\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'deleteProperty': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\n\t\t\t\t\tdesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE);\n\t\t\t\t\tif (desc_reject) {\n\t\t\t\t\t\t/* unconditional */\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\trc = 1;  /* success */\n\t\t\t\tgoto done_rc;\n\t\t\t}\n\n\t\t\tobj = h_target;  /* resume delete to target */\n\t\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\trc = duk_hobject_delprop_raw(thr, obj, key, throw_flag ? DUK_DELPROP_FLAG_THROW : 0);\n\t\tgoto done_rc;\n\t} else if (DUK_TVAL_IS_STRING(tv_obj)) {\n\t\t/* String has .length and array index virtual properties\n\t\t * which can't be deleted.  No need for a symbol check;\n\t\t * no offending virtual symbols exist.\n\t\t */\n\t\t/* XXX: unnecessary string coercion for array indices,\n\t\t * intentional to keep small.\n\t\t */\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\t} else if (DUK_TVAL_IS_BUFFER(tv_obj)) {\n\t\t/* XXX: unnecessary string coercion for array indices,\n\t\t * intentional to keep small; some overlap with string\n\t\t * handling.\n\t\t */\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HBUFFER_GET_SIZE(h)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) {\n\t\t/* Lightfunc has no virtual properties since Duktape 2.2\n\t\t * so success.  Still must coerce key for side effects.\n\t\t */\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\t\tDUK_UNREF(key);\n\t}\n\n\t/* non-object base, no offending virtual property */\n\trc = 1;\n\tgoto done_rc;\n\n done_rc:\n\tduk_set_top_unsafe(thr, entry_top);\n\treturn rc;\n\n fail_invalid_base_uncond:\n\t/* Note: unconditional throw */\n\tDUK_ASSERT(duk_get_top(thr) == entry_top);\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot delete property %s of %s\",\n\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\tDUK_WO_NORETURN(return 0;);\n\n#if defined(DUK_USE_ES6_PROXY)\n fail_proxy_rejected:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_set_top_unsafe(thr, entry_top);\n\treturn 0;\n#endif\n\n fail_not_configurable:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_set_top_unsafe(thr, entry_top);\n\treturn 0;\n}\n\n/*\n *  Internal helper to define a property with specific flags, ignoring\n *  normal semantics such as extensibility, write protection etc.\n *  Overwrites any existing value and attributes unless caller requests\n *  that value only be updated if it doesn't already exists.\n *\n *  Does not support:\n *    - virtual properties (error if write attempted)\n *    - getter/setter properties (error if write attempted)\n *    - non-default (!= WEC) attributes for array entries (error if attempted)\n *    - array abandoning: if array part exists, it is always extended\n *    - array 'length' updating\n *\n *  Stack: [... in_val] -> []\n *\n *  Used for e.g. built-in initialization and environment record\n *  operations.\n */\n\nDUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags) {\n\tduk_propdesc desc;\n\tduk_uint32_t arr_idx;\n\tduk_int_t e_idx;\n\tduk_tval *tv1 = NULL;\n\tduk_tval *tv2 = NULL;\n\tduk_small_uint_t propflags = flags & DUK_PROPDESC_FLAGS_MASK;  /* mask out flags not actually stored */\n\n\tDUK_DDD(DUK_DDDPRINT(\"define new property (internal): thr=%p, obj=%!O, key=%!O, flags=0x%02lx, val=%!T\",\n\t                     (void *) thr, (duk_heaphdr *) obj, (duk_heaphdr *) key,\n\t                     (unsigned long) flags, (duk_tval *) duk_get_tval(thr, -1)));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\tDUK_ASSERT(duk_is_valid_index(thr, -1));  /* contains value */\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\n\tif (duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\tif (desc.e_idx >= 0) {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the entry part -> skip as requested\"));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the entry part -> update value and attributes\"));\n\t\t\tif (DUK_UNLIKELY(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx))) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"existing property is an accessor, not supported\"));\n\t\t\t\tgoto error_internal;\n\t\t\t}\n\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, propflags);\n\t\t\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);\n\t\t} else if (desc.a_idx >= 0) {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the array part -> skip as requested\"));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the array part -> update value (assert attributes)\"));\n\t\t\tif (propflags != DUK_PROPDESC_FLAGS_WEC) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"existing property in array part, but propflags not WEC (0x%02lx)\",\n\t\t\t\t                 (unsigned long) propflags));\n\t\t\t\tgoto error_internal;\n\t\t\t}\n\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx);\n\t\t} else {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists but is virtual -> skip as requested\"));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\t\t\tduk_uint32_t new_len;\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tduk_uint32_t prev_len;\n\t\t\t\tprev_len = ((duk_harray *) obj)->length;\n#endif\n\t\t\t\tnew_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_NEGIDX(thr, -1));\n\t\t\t\t((duk_harray *) obj)->length = new_len;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"internal define property for array .length: %ld -> %ld\",\n\t\t\t\t                   (long) prev_len, (long) ((duk_harray *) obj)->length));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tDUK_DD(DUK_DDPRINT(\"property already exists but is virtual -> failure\"));\n\t\t\tgoto error_virtual;\n\t\t}\n\n\t\tgoto write_value;\n\t}\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property does not exist, object has array part -> possibly extend array part and write value (assert attributes)\"));\n\t\t\tDUK_ASSERT(propflags == DUK_PROPDESC_FLAGS_WEC);\n\n\t\t\ttv1 = duk__obtain_arridx_slot(thr, arr_idx, obj);\n\t\t\tif (tv1 == NULL) {\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\t\t\tgoto write_to_entry_part;\n\t\t\t}\n\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n\t\t\tgoto write_value;\n\t\t}\n\t}\n\n write_to_entry_part:\n\tDUK_DDD(DUK_DDDPRINT(\"property does not exist, object belongs in entry part -> allocate new entry and write value and attributes\"));\n\te_idx = duk__hobject_alloc_entry_checked(thr, obj, key);  /* increases key refcount */\n\tDUK_ASSERT(e_idx >= 0);\n\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, propflags);\n\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);\n\t/* new entry: previous value is garbage; set to undefined to share write_value */\n\tDUK_TVAL_SET_UNDEFINED(tv1);\n\tgoto write_value;\n\n write_value:\n\t/* tv1 points to value storage */\n\n\ttv2 = duk_require_tval(thr, -1);  /* late lookup, avoid side effects */\n\tDUK_DDD(DUK_DDDPRINT(\"writing/updating value: %!T -> %!T\",\n\t                     (duk_tval *) tv1, (duk_tval *) tv2));\n\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\tgoto pop_exit;\n\n pop_exit:\n\tduk_pop_unsafe(thr);  /* remove in_val */\n\treturn;\n\n error_virtual:  /* share error message */\n error_internal:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Fast path for defining array indexed values without interning the key.\n *  This is used by e.g. code for Array prototype and traceback creation so\n *  must avoid interning.\n */\n\nDUK_INTERNAL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags) {\n\tduk_hstring *key;\n\tduk_tval *tv1, *tv2;\n\n\tDUK_DDD(DUK_DDDPRINT(\"define new property (internal) arr_idx fast path: thr=%p, obj=%!O, \"\n\t                     \"arr_idx=%ld, flags=0x%02lx, val=%!T\",\n\t                     (void *) thr, obj, (long) arr_idx, (unsigned long) flags,\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj) &&\n\t    arr_idx != DUK__NO_ARRAY_INDEX &&\n\t    flags == DUK_PROPDESC_FLAGS_WEC) {\n\t\tDUK_ASSERT((flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) == 0);  /* covered by comparison */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"define property to array part (property may or may not exist yet)\"));\n\n\t\ttv1 = duk__obtain_arridx_slot(thr, arr_idx, obj);\n\t\tif (tv1 == NULL) {\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\t\tgoto write_slow;\n\t\t}\n\t\ttv2 = duk_require_tval(thr, -1);\n\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\n\t\tduk_pop_unsafe(thr);  /* [ ...val ] -> [ ... ] */\n\t\treturn;\n\t}\n\n write_slow:\n\tDUK_DDD(DUK_DDDPRINT(\"define property fast path didn't work, use slow path\"));\n\n\tkey = duk_push_uint_to_hstring(thr, (duk_uint_t) arr_idx);\n\tDUK_ASSERT(key != NULL);\n\tduk_insert(thr, -2);  /* [ ... val key ] -> [ ... key val ] */\n\n\tduk_hobject_define_property_internal(thr, obj, key, flags);\n\n\tduk_pop_unsafe(thr);  /* [ ... key ] -> [ ... ] */\n}\n\n/*\n *  Internal helpers for managing object 'length'\n */\n\nDUK_INTERNAL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj) {\n\tduk_double_t val;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(obj != NULL);\n\n\t/* Fast path for Arrays. */\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\treturn ((duk_harray *) obj)->length;\n\t}\n\n\t/* Slow path, .length can be e.g. accessor, obj can be a Proxy, etc. */\n\tduk_push_hobject(thr, obj);\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_LENGTH);\n\t(void) duk_hobject_getprop(thr,\n\t                           DUK_GET_TVAL_NEGIDX(thr, -2),\n\t                           DUK_GET_TVAL_NEGIDX(thr, -1));\n\tval = duk_to_number_m1(thr);\n\tduk_pop_3_unsafe(thr);\n\n\t/* This isn't part of ECMAScript semantics; return a value within\n\t * duk_size_t range, or 0 otherwise.\n\t */\n\tif (val >= 0.0 && val <= (duk_double_t) DUK_SIZE_MAX) {\n\t\treturn (duk_size_t) val;\n\t}\n\treturn 0;\n}\n\n/*\n *  Fast finalizer check for an object.  Walks the prototype chain, checking\n *  for finalizer presence using DUK_HOBJECT_FLAG_HAVE_FINALIZER which is kept\n *  in sync with the actual property when setting/removing the finalizer.\n */\n\n#if defined(DUK_USE_HEAPPTR16)\nDUK_INTERNAL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_heap *heap, duk_hobject *obj) {\n#else\nDUK_INTERNAL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_hobject *obj) {\n#endif\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(obj != NULL);\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_HAS_HAVE_FINALIZER(obj))) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_D(DUK_DPRINT(\"prototype loop when checking for finalizer existence; returning false\"));\n\t\t\treturn 0;\n\t\t}\n#if defined(DUK_USE_HEAPPTR16)\n\t\tDUK_ASSERT(heap != NULL);\n\t\tobj = DUK_HOBJECT_GET_PROTOTYPE(heap, obj);\n#else\n\t\tobj = DUK_HOBJECT_GET_PROTOTYPE(NULL, obj);  /* 'heap' arg ignored */\n#endif\n\t} while (obj != NULL);\n\n\treturn 0;\n}\n\n/*\n *  Object.getOwnPropertyDescriptor()  (E5 Sections 15.2.3.3, 8.10.4)\n *\n *  [ ... key ] -> [ ... desc/undefined ]\n */\n\nDUK_INTERNAL void duk_hobject_object_get_own_property_descriptor(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_propdesc pd;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tobj = duk_require_hobject_promote_mask(thr, obj_idx, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tkey = duk_to_property_key_hstring(thr, -1);\n\tDUK_ASSERT(key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk_hobject_get_own_propdesc(thr, obj, key, &pd, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tduk_push_undefined(thr);\n\t\tduk_remove_m2(thr);\n\t\treturn;\n\t}\n\n\tduk_push_object(thr);\n\n\t/* [ ... key value desc ] */\n\n\tif (DUK_PROPDESC_IS_ACCESSOR(&pd)) {\n\t\t/* If a setter/getter is missing (undefined), the descriptor must\n\t\t * still have the property present with the value 'undefined'.\n\t\t */\n\t\tif (pd.get) {\n\t\t\tduk_push_hobject(thr, pd.get);\n\t\t} else {\n\t\t\tduk_push_undefined(thr);\n\t\t}\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_GET);\n\t\tif (pd.set) {\n\t\t\tduk_push_hobject(thr, pd.set);\n\t\t} else {\n\t\t\tduk_push_undefined(thr);\n\t\t}\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_SET);\n\t} else {\n\t\tduk_dup_m2(thr);\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_VALUE);\n\t\tduk_push_boolean(thr, DUK_PROPDESC_IS_WRITABLE(&pd));\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_WRITABLE);\n\t}\n\tduk_push_boolean(thr, DUK_PROPDESC_IS_ENUMERABLE(&pd));\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_ENUMERABLE);\n\tduk_push_boolean(thr, DUK_PROPDESC_IS_CONFIGURABLE(&pd));\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_CONFIGURABLE);\n\n\t/* [ ... key value desc ] */\n\n\tduk_replace(thr, -3);\n\tduk_pop_unsafe(thr);  /* -> [ ... desc ] */\n}\n\n/*\n *  NormalizePropertyDescriptor() related helper.\n *\n *  Internal helper which validates and normalizes a property descriptor\n *  represented as an ECMAScript object (e.g. argument to defineProperty()).\n *  The output of this conversion is a set of defprop_flags and possibly\n *  some values pushed on the value stack to (1) ensure borrowed pointers\n *  remain valid, and (2) avoid unnecessary pops for footprint reasons.\n *  Caller must manage stack top carefully because the number of values\n *  pushed depends on the input property descriptor.\n *\n *  The original descriptor object must not be altered in the process.\n */\n\n/* XXX: very basic optimization -> duk_get_prop_stridx_top */\n\nDUK_INTERNAL\nvoid duk_hobject_prepare_property_descriptor(duk_hthread *thr,\n                                             duk_idx_t idx_in,\n                                             duk_uint_t *out_defprop_flags,\n                                             duk_idx_t *out_idx_value,\n                                             duk_hobject **out_getter,\n                                             duk_hobject **out_setter) {\n\tduk_idx_t idx_value = -1;\n\tduk_hobject *getter = NULL;\n\tduk_hobject *setter = NULL;\n\tduk_bool_t is_data_desc = 0;\n\tduk_bool_t is_acc_desc = 0;\n\tduk_uint_t defprop_flags = 0;\n\n\tDUK_ASSERT(out_defprop_flags != NULL);\n\tDUK_ASSERT(out_idx_value != NULL);\n\tDUK_ASSERT(out_getter != NULL);\n\tDUK_ASSERT(out_setter != NULL);\n\tDUK_ASSERT(idx_in <= 0x7fffL);  /* short variants would be OK, but not used to avoid shifts */\n\n\t/* Must be an object, otherwise TypeError (E5.1 Section 8.10.5, step 1). */\n\tidx_in = duk_require_normalize_index(thr, idx_in);\n\t(void) duk_require_hobject(thr, idx_in);\n\n\t/* The coercion order must match the ToPropertyDescriptor() algorithm\n\t * so that side effects in coercion happen in the correct order.\n\t * (This order also happens to be compatible with duk_def_prop(),\n\t * although it doesn't matter in practice.)\n\t */\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_VALUE)) {\n\t\tis_data_desc = 1;\n\t\tdefprop_flags |= DUK_DEFPROP_HAVE_VALUE;\n\t\tidx_value = duk_get_top_index(thr);\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_WRITABLE)) {\n\t\tis_data_desc = 1;\n\t\tif (duk_to_boolean_top_pop(thr)) {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE;\n\t\t} else {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_WRITABLE;\n\t\t}\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_GET)) {\n\t\tduk_tval *tv = duk_require_tval(thr, -1);\n\t\tduk_hobject *h_get;\n\n\t\tif (DUK_TVAL_IS_UNDEFINED(tv)) {\n\t\t\t/* undefined is accepted */\n\t\t\tDUK_ASSERT(getter == NULL);\n\t\t} else {\n\t\t\t/* NOTE: lightfuncs are coerced to full functions because\n\t\t\t * lightfuncs don't fit into a property value slot.  This\n\t\t\t * has some side effects, see test-dev-lightfunc-accessor.js.\n\t\t\t */\n\t\t\th_get = duk_get_hobject_promote_lfunc(thr, -1);\n\t\t\tif (h_get == NULL || !DUK_HOBJECT_IS_CALLABLE(h_get)) {\n\t\t\t\tgoto type_error;\n\t\t\t}\n\t\t\tgetter = h_get;\n\t\t}\n\t\tis_acc_desc = 1;\n\t\tdefprop_flags |= DUK_DEFPROP_HAVE_GETTER;\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_SET)) {\n\t\tduk_tval *tv = duk_require_tval(thr, -1);\n\t\tduk_hobject *h_set;\n\n\t\tif (DUK_TVAL_IS_UNDEFINED(tv)) {\n\t\t\t/* undefined is accepted */\n\t\t\tDUK_ASSERT(setter == NULL);\n\t\t}  else {\n\t\t\t/* NOTE: lightfuncs are coerced to full functions because\n\t\t\t * lightfuncs don't fit into a property value slot.  This\n\t\t\t * has some side effects, see test-dev-lightfunc-accessor.js.\n\t\t\t */\n\t\t\th_set = duk_get_hobject_promote_lfunc(thr, -1);\n\t\t\tif (h_set == NULL || !DUK_HOBJECT_IS_CALLABLE(h_set)) {\n\t\t\t\tgoto type_error;\n\t\t\t}\n\t\t\tsetter = h_set;\n\t\t}\n\t\tis_acc_desc = 1;\n\t\tdefprop_flags |= DUK_DEFPROP_HAVE_SETTER;\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_ENUMERABLE)) {\n\t\tif (duk_to_boolean_top_pop(thr)) {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE;\n\t\t} else {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE;\n\t\t}\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_CONFIGURABLE)) {\n\t\tif (duk_to_boolean_top_pop(thr)) {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE;\n\t\t} else {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE;\n\t\t}\n\t}\n\n\tif (is_data_desc && is_acc_desc) {\n\t\tgoto type_error;\n\t}\n\n\t*out_defprop_flags = defprop_flags;\n\t*out_idx_value = idx_value;\n\t*out_getter = getter;\n\t*out_setter = setter;\n\n\t/* [ ... [multiple values] ] */\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_DESCRIPTOR);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Object.defineProperty() related helper (E5 Section 15.2.3.6).\n *  Also handles ES2015 Reflect.defineProperty().\n *\n *  Inlines all [[DefineOwnProperty]] exotic behaviors.\n *\n *  Note: ECMAScript compliant [[DefineOwnProperty]](P, Desc, Throw) is not\n *  implemented directly, but Object.defineProperty() serves its purpose.\n *  We don't need the [[DefineOwnProperty]] internally and we don't have a\n *  property descriptor with 'missing values' so it's easier to avoid it\n *  entirely.\n *\n *  Note: this is only called for actual objects, not primitive values.\n *  This must support virtual properties for full objects (e.g. Strings)\n *  but not for plain values (e.g. strings).  Lightfuncs, even though\n *  primitive in a sense, are treated like objects and accepted as target\n *  values.\n */\n\n/* XXX: this is a major target for size optimization */\nDUK_INTERNAL\nduk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,\n                                              duk_uint_t defprop_flags,\n                                              duk_hobject *obj,\n                                              duk_hstring *key,\n                                              duk_idx_t idx_value,\n                                              duk_hobject *get,\n                                              duk_hobject *set,\n                                              duk_bool_t throw_flag) {\n\tduk_uint32_t arr_idx;\n\tduk_tval tv;\n\tduk_bool_t has_enumerable;\n\tduk_bool_t has_configurable;\n\tduk_bool_t has_writable;\n\tduk_bool_t has_value;\n\tduk_bool_t has_get;\n\tduk_bool_t has_set;\n\tduk_bool_t is_enumerable;\n\tduk_bool_t is_configurable;\n\tduk_bool_t is_writable;\n\tduk_bool_t force_flag;\n\tduk_small_uint_t new_flags;\n\tduk_propdesc curr;\n\tduk_uint32_t arridx_new_array_length;  /* != 0 => post-update for array 'length' (used when key is an array index) */\n\tduk_uint32_t arrlen_old_len;\n\tduk_uint32_t arrlen_new_len;\n\tduk_bool_t pending_write_protect;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\t/* idx_value may be < 0 (no value), set and get may be NULL */\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\t/* All the flags fit in 16 bits, so will fit into duk_bool_t. */\n\n\thas_writable = (defprop_flags & DUK_DEFPROP_HAVE_WRITABLE);\n\thas_enumerable = (defprop_flags & DUK_DEFPROP_HAVE_ENUMERABLE);\n\thas_configurable = (defprop_flags & DUK_DEFPROP_HAVE_CONFIGURABLE);\n\thas_value = (defprop_flags & DUK_DEFPROP_HAVE_VALUE);\n\thas_get = (defprop_flags & DUK_DEFPROP_HAVE_GETTER);\n\thas_set = (defprop_flags & DUK_DEFPROP_HAVE_SETTER);\n\tis_writable = (defprop_flags & DUK_DEFPROP_WRITABLE);\n\tis_enumerable = (defprop_flags & DUK_DEFPROP_ENUMERABLE);\n\tis_configurable = (defprop_flags & DUK_DEFPROP_CONFIGURABLE);\n\tforce_flag = (defprop_flags & DUK_DEFPROP_FORCE);\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\n\tarridx_new_array_length = 0;\n\tpending_write_protect = 0;\n\tarrlen_old_len = 0;\n\tarrlen_new_len = 0;\n\n\tDUK_DDD(DUK_DDDPRINT(\"has_enumerable=%ld is_enumerable=%ld \"\n\t                     \"has_configurable=%ld is_configurable=%ld \"\n\t                     \"has_writable=%ld is_writable=%ld \"\n\t                     \"has_value=%ld value=%!T \"\n\t                     \"has_get=%ld get=%p=%!O \"\n\t                     \"has_set=%ld set=%p=%!O \"\n\t                     \"arr_idx=%ld throw_flag=!%ld\",\n\t                     (long) has_enumerable, (long) is_enumerable,\n\t                     (long) has_configurable, (long) is_configurable,\n\t                     (long) has_writable, (long) is_writable,\n\t                     (long) has_value, (duk_tval *) (idx_value >= 0 ? duk_get_tval(thr, idx_value) : NULL),\n\t                     (long) has_get, (void *) get, (duk_heaphdr *) get,\n\t                     (long) has_set, (void *) set, (duk_heaphdr *) set,\n\t                     (long) arr_idx, (long) throw_flag));\n\n\t/*\n\t *  Array exotic behaviors can be implemented at this point.  The local variables\n\t *  are essentially a 'value copy' of the input descriptor (Desc), which is modified\n\t *  by the Array [[DefineOwnProperty]] (E5 Section 15.4.5.1).\n\t */\n\n\tif (!DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\tgoto skip_array_exotic;\n\t}\n\n\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\tduk_harray *a;\n\n\t\t/* E5 Section 15.4.5.1, step 3, steps a - i are implemented here, j - n at the end */\n\t\tif (!has_value) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"exotic array behavior for 'length', but no value in descriptor -> normal behavior\"));\n\t\t\tgoto skip_array_exotic;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"exotic array behavior for 'length', value present in descriptor -> exotic behavior\"));\n\n\t\t/*\n\t\t *  Get old and new length\n\t\t */\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\t\tarrlen_old_len = a->length;\n\n\t\tDUK_ASSERT(idx_value >= 0);\n\t\tarrlen_new_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_POSIDX(thr, idx_value));\n\t\tduk_push_u32(thr, arrlen_new_len);\n\t\tduk_replace(thr, idx_value);  /* step 3.e: replace 'Desc.[[Value]]' */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"old_len=%ld, new_len=%ld\", (long) arrlen_old_len, (long) arrlen_new_len));\n\n\t\tif (arrlen_new_len >= arrlen_old_len) {\n\t\t\t/* standard behavior, step 3.f.i */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new length is same or higher as previous => standard behavior\"));\n\t\t\tgoto skip_array_exotic;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"new length is smaller than previous => exotic post behavior\"));\n\n\t\t/* XXX: consolidated algorithm step 15.f -> redundant? */\n\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a) && !force_flag) {\n\t\t\t/* Array .length is always non-configurable; if it's also\n\t\t\t * non-writable, don't allow it to be written.\n\t\t\t */\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\n\t\t/* steps 3.h and 3.i */\n\t\tif (has_writable && !is_writable) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"desc writable is false, force it back to true, and flag pending write protect\"));\n\t\t\tis_writable = 1;\n\t\t\tpending_write_protect = 1;\n\t\t}\n\n\t\t/* remaining actual steps are carried out if standard DefineOwnProperty succeeds */\n\t} else if (arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t/* XXX: any chance of unifying this with the 'length' key handling? */\n\n\t\t/* E5 Section 15.4.5.1, step 4 */\n\t\tduk_uint32_t old_len;\n\t\tduk_harray *a;\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\told_len = a->length;\n\n\t\tif (arr_idx >= old_len) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty requires array length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\n\t\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a) && !force_flag) {\n\t\t\t\t/* Array .length is always non-configurable, so\n\t\t\t\t * if it's also non-writable, don't allow a value\n\t\t\t\t * write.  With force flag allow writing.\n\t\t\t\t */\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\n\t\t\t/* actual update happens once write has been completed without\n\t\t\t * error below.\n\t\t\t */\n\t\t\tDUK_ASSERT(arr_idx != 0xffffffffUL);\n\t\t\tarridx_new_array_length = arr_idx + 1;\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty does not require length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld) -> standard behavior\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\t\t}\n\t}\n skip_array_exotic:\n\n\t/* XXX: There is currently no support for writing buffer object\n\t * indexed elements here.  Attempt to do so will succeed and\n\t * write a concrete property into the buffer object.  This should\n\t * be fixed at some point but because buffers are a custom feature\n\t * anyway, this is relatively unimportant.\n\t */\n\n\t/*\n\t *  Actual Object.defineProperty() default algorithm.\n\t */\n\n\t/*\n\t *  First check whether property exists; if not, simple case.  This covers\n\t *  steps 1-4.\n\t */\n\n\tif (!duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"property does not exist\"));\n\n\t\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(obj) && !force_flag) {\n\t\t\tgoto fail_not_extensible;\n\t\t}\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\t\t/* ROM objects are never extensible but force flag may\n\t\t * allow us to come here anyway.\n\t\t */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj) || !DUK_HOBJECT_HAS_EXTENSIBLE(obj));\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\t\tDUK_D(DUK_DPRINT(\"attempt to define property on a read-only target object\"));\n\t\t\tgoto fail_not_configurable;\n\t\t}\n#endif\n\n\t\t/* XXX: share final setting code for value and flags?  difficult because\n\t\t * refcount code is different.  Share entry allocation?  But can't allocate\n\t\t * until array index checked.\n\t\t */\n\n\t\t/* steps 4.a and 4.b are tricky */\n\t\tif (has_set || has_get) {\n\t\t\tduk_int_t e_idx;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"create new accessor property\"));\n\n\t\t\tDUK_ASSERT(has_set || set == NULL);\n\t\t\tDUK_ASSERT(has_get || get == NULL);\n\t\t\tDUK_ASSERT(!has_value);\n\t\t\tDUK_ASSERT(!has_writable);\n\n\t\t\tnew_flags = DUK_PROPDESC_FLAG_ACCESSOR;  /* defaults, E5 Section 8.6.1, Table 7 */\n\t\t\tif (has_enumerable && is_enumerable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t}\n\t\t\tif (has_configurable && is_configurable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t}\n\n\t\t\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"accessor cannot go to array part, abandon array\"));\n\t\t\t\tduk__abandon_array_part(thr, obj);\n\t\t\t}\n\n\t\t\t/* write to entry part */\n\t\t\te_idx = duk__hobject_alloc_entry_checked(thr, obj, key);\n\t\t\tDUK_ASSERT(e_idx >= 0);\n\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, e_idx, get);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, e_idx, set);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, get);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, set);\n\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags);\n\t\t\tgoto success_exotics;\n\t\t} else {\n\t\t\tduk_int_t e_idx;\n\t\t\tduk_tval *tv2;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"create new data property\"));\n\n\t\t\tDUK_ASSERT(!has_set);\n\t\t\tDUK_ASSERT(!has_get);\n\n\t\t\tnew_flags = 0;  /* defaults, E5 Section 8.6.1, Table 7 */\n\t\t\tif (has_writable && is_writable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_WRITABLE;\n\t\t\t}\n\t\t\tif (has_enumerable && is_enumerable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t}\n\t\t\tif (has_configurable && is_configurable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t}\n\t\t\tif (has_value) {\n\t\t\t\tduk_tval *tv_tmp = duk_require_tval(thr, idx_value);\n\t\t\t\tDUK_TVAL_SET_TVAL(&tv, tv_tmp);\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_UNDEFINED(&tv);  /* default value */\n\t\t\t}\n\n\t\t\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tif (new_flags == DUK_PROPDESC_FLAGS_WEC) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"new data property attributes match array defaults, attempt to write to array part\"));\n\t\t\t\t\ttv2 = duk__obtain_arridx_slot(thr, arr_idx, obj);\n\t\t\t\t\tif (tv2 == NULL) {\n\t\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"failed writing to array part, abandoned array\"));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"success in writing to array part\"));\n\t\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\t\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv2));\n\t\t\t\t\t\tDUK_TVAL_SET_TVAL(tv2, &tv);\n\t\t\t\t\t\tDUK_TVAL_INCREF(thr, tv2);\n\t\t\t\t\t\tgoto success_exotics;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"new data property cannot go to array part, abandon array\"));\n\t\t\t\t\tduk__abandon_array_part(thr, obj);\n\t\t\t\t}\n\t\t\t\t/* fall through */\n\t\t\t}\n\n\t\t\t/* write to entry part */\n\t\t\te_idx = duk__hobject_alloc_entry_checked(thr, obj, key);\n\t\t\tDUK_ASSERT(e_idx >= 0);\n\t\t\ttv2 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);\n\t\t\tDUK_TVAL_SET_TVAL(tv2, &tv);\n\t\t\tDUK_TVAL_INCREF(thr, tv2);\n\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags);\n\t\t\tgoto success_exotics;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\t}\n\n\t/* we currently assume virtual properties are not configurable (as none of them are) */\n\tDUK_ASSERT((curr.e_idx >= 0 || curr.a_idx >= 0) || !(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE));\n\n\t/* [obj key desc value get set curr_value] */\n\n\t/*\n\t *  Property already exists.  Steps 5-6 detect whether any changes need\n\t *  to be made.\n\t */\n\n\tif (has_enumerable) {\n\t\tif (is_enumerable) {\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE)) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t}\n\t}\n\tif (has_configurable) {\n\t\tif (is_configurable) {\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE)) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t}\n\t}\n\tif (has_value) {\n\t\tduk_tval *tmp1;\n\t\tduk_tval *tmp2;\n\n\t\t/* attempt to change from accessor to data property */\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tgoto need_check;\n\t\t}\n\n\t\ttmp1 = duk_require_tval(thr, -1);         /* curr value */\n\t\ttmp2 = duk_require_tval(thr, idx_value);  /* new value */\n\t\tif (!duk_js_samevalue(tmp1, tmp2)) {\n\t\t\tgoto need_check;\n\t\t}\n\t}\n\tif (has_writable) {\n\t\t/* attempt to change from accessor to data property */\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tgoto need_check;\n\t\t}\n\n\t\tif (is_writable) {\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_WRITABLE) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t}\n\t}\n\tif (has_set) {\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tif (set != curr.set) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tgoto need_check;\n\t\t}\n\t}\n\tif (has_get) {\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tif (get != curr.get) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tgoto need_check;\n\t\t}\n\t}\n\n\t/* property exists, either 'desc' is empty, or all values\n\t * match (SameValue)\n\t */\n\tgoto success_no_exotics;\n\n need_check:\n\n\t/*\n\t *  Some change(s) need to be made.  Steps 7-11.\n\t */\n\n\t/* shared checks for all descriptor types */\n\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\tif (has_configurable && is_configurable) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\t\tif (has_enumerable) {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE) {\n\t\t\t\tif (!is_enumerable) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (is_enumerable) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Virtual properties don't have backing so they can't mostly be\n\t * edited.  Some virtual properties are, however, writable: for\n\t * example, virtual index properties of buffer objects and Array\n\t * instance .length.  These are not configurable so the checks\n\t * above mostly cover attempts to change them, except when the\n\t * duk_def_prop() call is used with DUK_DEFPROP_FORCE; even in\n\t * that case we can't forcibly change the property attributes\n\t * because they don't have concrete backing.\n\t */\n\n\t/* XXX: for ROM objects too it'd be best if value modify was\n\t * allowed if the value matches SameValue.\n\t */\n\t/* Reject attempt to change a read-only object. */\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to define property on read-only target object\"));\n\t\tgoto fail_not_configurable;\n\t}\n#endif\n\n\t/* descriptor type specific checks */\n\tif (has_set || has_get) {\n\t\t/* IsAccessorDescriptor(desc) == true */\n\t\tDUK_ASSERT(!has_writable);\n\t\tDUK_ASSERT(!has_value);\n\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t/* curr and desc are accessors */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tif (has_set && set != curr.set) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t\tif (has_get && get != curr.get) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tduk_bool_t rc;\n\t\t\tduk_tval *tv1;\n\n\t\t\t/* curr is data, desc is accessor */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"convert property to accessor property\"));\n\t\t\tif (curr.a_idx >= 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property to convert is stored in an array entry, abandon array and re-lookup\"));\n\t\t\t\tduk__abandon_array_part(thr, obj);\n\t\t\t\tduk_pop_unsafe(thr);  /* remove old value */\n\t\t\t\trc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);\n\t\t\t\tDUK_UNREF(rc);\n\t\t\t\tDUK_ASSERT(rc != 0);\n\t\t\t\tDUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);\n\t\t\t}\n\t\t\tif (curr.e_idx < 0) {\n\t\t\t\tDUK_ASSERT(curr.a_idx < 0 && curr.e_idx < 0);\n\t\t\t\tgoto fail_virtual;  /* safeguard for virtual property */\n\t\t\t}\n\n\t\t\tDUK_ASSERT(curr.e_idx >= 0);\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\n\t\t\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv1);  /* XXX: just decref */\n\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_HOBJECT_E_SLOT_SET_ACCESSOR(thr->heap, obj, curr.e_idx);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"flags after data->accessor conversion: 0x%02lx\",\n\t\t\t                     (unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));\n\t\t\t/* Update curr.flags; faster than a re-lookup. */\n\t\t\tcurr.flags &= ~DUK_PROPDESC_FLAG_WRITABLE;\n\t\t\tcurr.flags |= DUK_PROPDESC_FLAG_ACCESSOR;\n\t\t}\n\t} else if (has_value || has_writable) {\n\t\t/* IsDataDescriptor(desc) == true */\n\t\tDUK_ASSERT(!has_set);\n\t\tDUK_ASSERT(!has_get);\n\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tduk_hobject *tmp;\n\n\t\t\t/* curr is accessor, desc is data */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\n\t\t\t/* curr is accessor -> cannot be in array part. */\n\t\t\tDUK_ASSERT(curr.a_idx < 0);\n\t\t\tif (curr.e_idx < 0) {\n\t\t\t\tgoto fail_virtual;  /* safeguard; no virtual accessors now */\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"convert property to data property\"));\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\n\t\t\tDUK_TVAL_SET_UNDEFINED(DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx));\n\t\t\tDUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(thr->heap, obj, curr.e_idx);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"flags after accessor->data conversion: 0x%02lx\",\n\t\t\t                     (unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));\n\n\t\t\t/* Update curr.flags; faster than a re-lookup. */\n\t\t\tcurr.flags &= ~(DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ACCESSOR);\n\t\t} else {\n\t\t\t/* curr and desc are data */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && has_writable && is_writable) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t\t/* Note: changing from writable to non-writable is OK */\n\t\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && has_value) {\n\t\t\t\t\tduk_tval *tmp1 = duk_require_tval(thr, -1);         /* curr value */\n\t\t\t\t\tduk_tval *tmp2 = duk_require_tval(thr, idx_value);  /* new value */\n\t\t\t\t\tif (!duk_js_samevalue(tmp1, tmp2)) {\n\t\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\t/* IsGenericDescriptor(desc) == true; this means in practice that 'desc'\n\t\t * only has [[Enumerable]] or [[Configurable]] flag updates, which are\n\t\t * allowed at this point.\n\t\t */\n\n\t\tDUK_ASSERT(!has_value && !has_writable && !has_get && !has_set);\n\t}\n\n\t/*\n\t *  Start doing property attributes updates.  Steps 12-13.\n\t *\n\t *  Start by computing new attribute flags without writing yet.\n\t *  Property type conversion is done above if necessary.\n\t */\n\n\tnew_flags = curr.flags;\n\n\tif (has_enumerable) {\n\t\tif (is_enumerable) {\n\t\t\tnew_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t} else {\n\t\t\tnew_flags &= ~DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t}\n\t}\n\tif (has_configurable) {\n\t\tif (is_configurable) {\n\t\t\tnew_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t} else {\n\t\t\tnew_flags &= ~DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t}\n\t}\n\tif (has_writable) {\n\t\tif (is_writable) {\n\t\t\tnew_flags |= DUK_PROPDESC_FLAG_WRITABLE;\n\t\t} else {\n\t\t\tnew_flags &= ~DUK_PROPDESC_FLAG_WRITABLE;\n\t\t}\n\t}\n\n\t/* XXX: write protect after flag? -> any chance of handling it here? */\n\n\tDUK_DDD(DUK_DDDPRINT(\"new flags that we want to write: 0x%02lx\",\n\t                     (unsigned long) new_flags));\n\n\t/*\n\t *  Check whether we need to abandon an array part (if it exists)\n\t */\n\n\tif (curr.a_idx >= 0) {\n\t\tduk_bool_t rc;\n\n\t\tDUK_ASSERT(curr.e_idx < 0);\n\n\t\tif (new_flags == DUK_PROPDESC_FLAGS_WEC) {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index, new property attributes match array defaults, update in-place\"));\n\n\t\t\tDUK_ASSERT(curr.flags == DUK_PROPDESC_FLAGS_WEC);  /* must have been, since in array part */\n\t\t\tDUK_ASSERT(!has_set);\n\t\t\tDUK_ASSERT(!has_get);\n\t\t\tDUK_ASSERT(idx_value >= 0);  /* must be: if attributes match and we get here the value must differ (otherwise no change) */\n\n\t\t\ttv2 = duk_require_tval(thr, idx_value);\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, curr.a_idx);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects; may invalidate a_idx */\n\t\t\tgoto success_exotics;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array index, new property attributes do not match array defaults, abandon array and re-lookup\"));\n\t\tduk__abandon_array_part(thr, obj);\n\t\tduk_pop_unsafe(thr);  /* remove old value */\n\t\trc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);\n\t\tDUK_UNREF(rc);\n\t\tDUK_ASSERT(rc != 0);\n\t\tDUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"updating existing property in entry part\"));\n\n\t/* Array case is handled comprehensively above: either in entry\n\t * part or a virtual property.\n\t */\n\tDUK_ASSERT(curr.a_idx < 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"update existing property attributes\"));\n\tif (curr.e_idx >= 0) {\n\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, curr.e_idx, new_flags);\n\t} else {\n\t\t/* For Array .length the only allowed transition is for .length\n\t\t * to become non-writable.\n\t\t */\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\t\tduk_harray *a;\n\t\t\ta = (duk_harray *) obj;\n\t\t\tDUK_DD(DUK_DDPRINT(\"Object.defineProperty() attribute update for duk_harray .length -> %02lx\", (unsigned long) new_flags));\n\t\t\tDUK_HARRAY_ASSERT_VALID(a);\n\t\t\tif ((new_flags & DUK_PROPDESC_FLAGS_EC) != (curr.flags & DUK_PROPDESC_FLAGS_EC)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"Object.defineProperty() attempt to change virtual array .length enumerable or configurable attribute, fail\"));\n\t\t\t\tgoto fail_virtual;\n\t\t\t}\n\t\t\tif (new_flags & DUK_PROPDESC_FLAG_WRITABLE) {\n\t\t\t\tDUK_HARRAY_SET_LENGTH_WRITABLE(a);\n\t\t\t} else {\n\t\t\t\tDUK_HARRAY_SET_LENGTH_NONWRITABLE(a);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (has_set) {\n\t\tduk_hobject *tmp;\n\n\t\t/* Virtual properties are non-configurable but with a 'force'\n\t\t * flag we might come here so check explicitly for virtual.\n\t\t */\n\t\tif (curr.e_idx < 0) {\n\t\t\tgoto fail_virtual;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"update existing property setter\"));\n\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\n\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);\n\t\tDUK_UNREF(tmp);\n\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, set);\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, set);\n\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);  /* side effects; may invalidate e_idx */\n\t}\n\tif (has_get) {\n\t\tduk_hobject *tmp;\n\n\t\tif (curr.e_idx < 0) {\n\t\t\tgoto fail_virtual;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"update existing property getter\"));\n\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\n\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);\n\t\tDUK_UNREF(tmp);\n\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, get);\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, get);\n\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);  /* side effects; may invalidate e_idx */\n\t}\n\tif (has_value) {\n\t\tduk_tval *tv1, *tv2;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"update existing property value\"));\n\n\t\tif (curr.e_idx >= 0) {\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\t\t\ttv2 = duk_require_tval(thr, idx_value);\n\t\t\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects; may invalidate e_idx */\n\t\t} else {\n\t\t\tDUK_ASSERT(curr.a_idx < 0);  /* array part case handled comprehensively previously */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"Object.defineProperty(), value update for virtual property\"));\n\t\t\t/* XXX: Uint8Array and other typed array virtual writes not currently\n\t\t\t * handled.\n\t\t\t */\n\t\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\t\t\tduk_harray *a;\n\t\t\t\ta = (duk_harray *) obj;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"Object.defineProperty() value update for duk_harray .length -> %ld\", (long) arrlen_new_len));\n\t\t\t\tDUK_HARRAY_ASSERT_VALID(a);\n\t\t\t\ta->length = arrlen_new_len;\n\t\t\t} else {\n\t\t\t\tgoto fail_virtual;  /* should not happen */\n\t\t\t}\n\t\t}\n\t}\n\n\t/*\n\t *  Standard algorithm succeeded without errors, check for exotic post-behaviors.\n\t *\n\t *  Arguments exotic behavior in E5 Section 10.6 occurs after the standard\n\t *  [[DefineOwnProperty]] has completed successfully.\n\t *\n\t *  Array exotic behavior in E5 Section 15.4.5.1 is implemented partly\n\t *  prior to the default [[DefineOwnProperty]], but:\n\t *    - for an array index key (e.g. \"10\") the final 'length' update occurs here\n\t *    - for 'length' key the element deletion and 'length' update occurs here\n\t */\n\n success_exotics:\n\n\t/* curr.a_idx or curr.e_idx may have been invalidated by side effects\n\t * above.\n\t */\n\n\t/* [obj key desc value get set curr_value] */\n\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\tduk_harray *a;\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\tif (arridx_new_array_length > 0) {\n\t\t\t/*\n\t\t\t *  Note: zero works as a \"no update\" marker because the new length\n\t\t\t *  can never be zero after a new property is written.\n\t\t\t */\n\n\t\t\t/* E5 Section 15.4.5.1, steps 4.e.i - 4.e.ii */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, pending array length update to: %ld\",\n\t\t\t                     (long) arridx_new_array_length));\n\n\t\t\ta->length = arridx_new_array_length;\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && arrlen_new_len < arrlen_old_len) {\n\t\t\t/*\n\t\t\t *  E5 Section 15.4.5.1, steps 3.k - 3.n.  The order at the end combines\n\t\t\t *  the error case 3.l.iii and the success case 3.m-3.n.\n\t\t\t */\n\n\t\t\t/* XXX: investigate whether write protect can be handled above, if we\n\t\t\t * just update length here while ignoring its protected status\n\t\t\t */\n\n\t\t\tduk_uint32_t result_len;\n\t\t\tduk_bool_t rc;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key is 'length', exotic array behavior, \"\n\t\t\t                     \"doing array element deletion and length update\"));\n\n\t\t\trc = duk__handle_put_array_length_smaller(thr, obj, arrlen_old_len, arrlen_new_len, force_flag, &result_len);\n\n\t\t\t/* update length (curr points to length, and we assume it's still valid) */\n\t\t\tDUK_ASSERT(result_len >= arrlen_new_len && result_len <= arrlen_old_len);\n\n\t\t\ta->length = result_len;\n\n\t\t\tif (pending_write_protect) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"setting array length non-writable (pending writability update)\"));\n\t\t\t\tDUK_HARRAY_SET_LENGTH_NONWRITABLE(a);\n\t\t\t}\n\n\t\t\t/* XXX: shrink array allocation or entries compaction here? */\n\t\t\tif (!rc) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"array length write only partially successful\"));\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\t\t}\n\t} else if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)) {\n\t\tduk_hobject *map;\n\t\tduk_hobject *varenv;\n\n\t\tDUK_ASSERT(arridx_new_array_length == 0);\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj));  /* traits are separate; in particular, arguments not an array */\n\n\t\tmap = NULL;\n\t\tvarenv = NULL;\n\t\tif (!duk__lookup_arguments_map(thr, obj, key, &curr, &map, &varenv)) {\n\t\t\tgoto success_no_exotics;\n\t\t}\n\t\tDUK_ASSERT(map != NULL);\n\t\tDUK_ASSERT(varenv != NULL);\n\n\t\t/* [obj key desc value get set curr_value varname] */\n\n\t\tif (has_set || has_get) {\n\t\t\t/* = IsAccessorDescriptor(Desc) */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map' \"\n\t\t\t                     \"changed to an accessor, delete arguments binding\"));\n\n\t\t\t(void) duk_hobject_delprop_raw(thr, map, key, 0);  /* ignore result */\n\t\t} else {\n\t\t\t/* Note: this order matters (final value before deleting map entry must be done) */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map', \"\n\t\t\t                     \"check for value update / binding deletion\"));\n\n\t\t\tif (has_value) {\n\t\t\t\tduk_hstring *varname;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map', \"\n\t\t\t\t                     \"update bound value (variable/argument)\"));\n\n\t\t\t\tvarname = duk_require_hstring(thr, -1);\n\t\t\t\tDUK_ASSERT(varname != NULL);\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"arguments object automatic putvar for a bound variable; \"\n\t\t\t\t                     \"key=%!O, varname=%!O, value=%!T\",\n\t\t\t\t                     (duk_heaphdr *) key,\n\t\t\t\t                     (duk_heaphdr *) varname,\n\t\t\t\t                     (duk_tval *) duk_require_tval(thr, idx_value)));\n\n\t\t\t\t/* strict flag for putvar comes from our caller (currently: fixed) */\n\t\t\t\tduk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(thr, idx_value), 1 /*throw_flag*/);\n\t\t\t}\n\t\t\tif (has_writable && !is_writable) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map', \"\n\t\t\t\t                     \"changed to non-writable, delete arguments binding\"));\n\n\t\t\t\t(void) duk_hobject_delprop_raw(thr, map, key, 0);  /* ignore result */\n\t\t\t}\n\t\t}\n\n\t\t/* 'varname' is in stack in this else branch, leaving an unbalanced stack below,\n\t\t * but this doesn't matter now.\n\t\t */\n\t}\n\n success_no_exotics:\n\t/* Some code paths use NORZ macros for simplicity, ensure refzero\n\t * handling is completed.\n\t */\n\tDUK_REFZERO_CHECK_SLOW(thr);\n\treturn 1;\n\n fail_not_extensible:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n\n fail_virtual:  /* just use the same \"not configurable\" error message\" */\n fail_not_configurable:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n}\n\n/*\n *  Object.prototype.hasOwnProperty() and Object.prototype.propertyIsEnumerable().\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_object_ownprop_helper(duk_hthread *thr, duk_small_uint_t required_desc_flags) {\n\tduk_hstring *h_v;\n\tduk_hobject *h_obj;\n\tduk_propdesc desc;\n\tduk_bool_t ret;\n\n\t/* coercion order matters */\n\th_v = duk_to_hstring_acceptsymbol(thr, 0);\n\tDUK_ASSERT(h_v != NULL);\n\n\th_obj = duk_push_this_coercible_to_object(thr);\n\tDUK_ASSERT(h_obj != NULL);\n\n\tret = duk_hobject_get_own_propdesc(thr, h_obj, h_v, &desc, 0 /*flags*/);  /* don't push value */\n\n\tduk_push_boolean(thr, ret && ((desc.flags & required_desc_flags) == required_desc_flags));\n\treturn 1;\n}\n\n/*\n *  Object.seal() and Object.freeze()  (E5 Sections 15.2.3.8 and 15.2.3.9)\n *\n *  Since the algorithms are similar, a helper provides both functions.\n *  Freezing is essentially sealing + making plain properties non-writable.\n *\n *  Note: virtual (non-concrete) properties which are non-configurable but\n *  writable would pose some problems, but such properties do not currently\n *  exist (all virtual properties are non-configurable and non-writable).\n *  If they did exist, the non-configurability does NOT prevent them from\n *  becoming non-writable.  However, this change should be recorded somehow\n *  so that it would turn up (e.g. when getting the property descriptor),\n *  requiring some additional flags in the object.\n */\n\nDUK_INTERNAL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze) {\n\tduk_uint_fast32_t i;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to seal/freeze a readonly object, reject\"));\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\t/*\n\t *  Abandon array part because all properties must become non-configurable.\n\t *  Note that this is now done regardless of whether this is always the case\n\t *  (skips check, but performance problem if caller would do this many times\n\t *  for the same object; not likely).\n\t */\n\n\tduk__abandon_array_part(thr, obj);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) == 0);\n\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tduk_uint8_t *fp;\n\n\t\t/* since duk__abandon_array_part() causes a resize, there should be no gaps in keys */\n\t\tDUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != NULL);\n\n\t\t/* avoid multiple computations of flags address; bypasses macros */\n\t\tfp = DUK_HOBJECT_E_GET_FLAGS_PTR(thr->heap, obj, i);\n\t\tif (is_freeze && !((*fp) & DUK_PROPDESC_FLAG_ACCESSOR)) {\n\t\t\t*fp &= ~(DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE);\n\t\t} else {\n\t\t\t*fp &= ~DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t}\n\t}\n\n\tDUK_HOBJECT_CLEAR_EXTENSIBLE(obj);\n\n\t/* no need to compact since we already did that in duk__abandon_array_part()\n\t * (regardless of whether an array part existed or not.\n\t */\n\n\treturn;\n}\n\n/*\n *  Object.isSealed() and Object.isFrozen()  (E5 Sections 15.2.3.11, 15.2.3.13)\n *\n *  Since the algorithms are similar, a helper provides both functions.\n *  Freezing is essentially sealing + making plain properties non-writable.\n *\n *  Note: all virtual (non-concrete) properties are currently non-configurable\n *  and non-writable (and there are no accessor virtual properties), so they don't\n *  need to be considered here now.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen) {\n\tduk_uint_fast32_t i;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(thr);\n\n\t/* Note: no allocation pressure, no need to check refcounts etc */\n\n\t/* must not be extensible */\n\tif (DUK_HOBJECT_HAS_EXTENSIBLE(obj)) {\n\t\treturn 0;\n\t}\n\n\t/* all virtual properties are non-configurable and non-writable */\n\n\t/* entry part must not contain any configurable properties, or\n\t * writable properties (if is_frozen).\n\t */\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tduk_small_uint_t flags;\n\n\t\tif (!DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* avoid multiple computations of flags address; bypasses macros */\n\t\tflags = (duk_small_uint_t) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, i);\n\n\t\tif (flags & DUK_PROPDESC_FLAG_CONFIGURABLE) {\n\t\t\treturn 0;\n\t\t}\n\t\tif (is_frozen &&\n\t\t    !(flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t    (flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* array part must not contain any non-unused properties, as they would\n\t * be configurable and writable.\n\t */\n\tfor (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\tduk_tval *tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\treturn 1;\n}\n\n/*\n *  Object.preventExtensions() and Object.isExtensible()  (E5 Sections 15.2.3.10, 15.2.3.13)\n *\n *  Not needed, implemented by macros DUK_HOBJECT_{HAS,CLEAR,SET}_EXTENSIBLE\n *  and the Object built-in bindings.\n */\n\n/* automatic undefs */\n#undef DUK__HASH_DELETED\n#undef DUK__HASH_UNUSED\n#undef DUK__NO_ARRAY_INDEX\n#undef DUK__VALSTACK_PROXY_LOOKUP\n#undef DUK__VALSTACK_SPACE\n#line 1 \"duk_hstring_assert.c\"\n/*\n *  duk_hstring assertion helpers.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ASSERTIONS)\n\nDUK_INTERNAL void duk_hstring_assert_valid(duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n#line 1 \"duk_hstring_misc.c\"\n/*\n *  Misc support functions\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  duk_hstring charCodeAt, with and without surrogate awareness\n */\n\nDUK_INTERNAL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, duk_uint_t pos, duk_bool_t surrogate_aware) {\n\tduk_uint32_t boff;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_ucodepoint_t cp1;\n\tduk_ucodepoint_t cp2;\n\n\t/* Caller must check character offset to be inside the string. */\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT_DISABLE(pos >= 0);  /* unsigned */\n\tDUK_ASSERT(pos < (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h));\n\n\tboff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint32_t) pos);\n\tDUK_DDD(DUK_DDDPRINT(\"charCodeAt: pos=%ld -> boff=%ld, str=%!O\",\n\t                     (long) pos, (long) boff, (duk_heaphdr *) h));\n\tDUK_ASSERT_DISABLE(boff >= 0);\n\tDUK_ASSERT(boff < DUK_HSTRING_GET_BYTELEN(h));\n\n\tp_start = DUK_HSTRING_GET_DATA(h);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h);\n\tp = p_start + boff;\n\tDUK_DDD(DUK_DDDPRINT(\"p_start=%p, p_end=%p, p=%p\",\n\t                     (const void *) p_start, (const void *) p_end,\n\t                     (const void *) p));\n\n\t/* For invalid UTF-8 (never happens for standard ECMAScript strings)\n\t * return U+FFFD replacement character.\n\t */\n\tif (duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp1)) {\n\t\tif (surrogate_aware && cp1 >= 0xd800UL && cp1 <= 0xdbffUL) {\n\t\t\t/* The decode helper is memory safe even if 'cp1' was\n\t\t\t * decoded at the end of the string and 'p' is no longer\n\t\t\t * within string memory range.\n\t\t\t */\n\t\t\tcp2 = 0;  /* If call fails, this is left untouched and won't match cp2 check. */\n\t\t\t(void) duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp2);\n\t\t\tif (cp2 >= 0xdc00UL && cp2 <= 0xdfffUL) {\n\t\t\t\tcp1 = (duk_ucodepoint_t) (((cp1 - 0xd800UL) << 10) + (cp2 - 0xdc00UL) + 0x10000UL);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tcp1 = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t}\n\n\treturn cp1;\n}\n\n/*\n *  duk_hstring charlen, when lazy charlen disabled\n */\n\n#if !defined(DUK_USE_HSTRING_LAZY_CLEN)\n#if !defined(DUK_USE_HSTRING_CLEN)\n#error non-lazy duk_hstring charlen but DUK_USE_HSTRING_CLEN not set\n#endif\nDUK_INTERNAL void duk_hstring_init_charlen(duk_hstring *h) {\n\tduk_uint32_t clen;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(!DUK_HSTRING_HAS_ASCII(h));\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h));\n\n\tclen = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n#if defined(DUK_USE_STRLEN16)\n\tDUK_ASSERT(clen <= 0xffffUL);  /* Bytelength checked during interning. */\n\th->clen16 = (duk_uint16_t) clen;\n#else\n\th->clen = (duk_uint32_t) clen;\n#endif\n\tif (DUK_LIKELY(clen == DUK_HSTRING_GET_BYTELEN(h))) {\n\t\tDUK_HSTRING_SET_ASCII(h);\n\t}\n}\n\nDUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {\n#if defined(DUK_USE_STRLEN16)\n\treturn h->clen16;\n#else\n\treturn h->clen;\n#endif\n}\n#endif  /* !DUK_USE_HSTRING_LAZY_CLEN */\n\n/*\n *  duk_hstring charlen, when lazy charlen enabled\n */\n\n#if defined(DUK_USE_HSTRING_LAZY_CLEN)\n#if defined(DUK_USE_HSTRING_CLEN)\nDUK_LOCAL DUK_COLD duk_size_t duk__hstring_get_charlen_slowpath(duk_hstring *h) {\n\tduk_size_t res;\n\n\tDUK_ASSERT(h->clen == 0);  /* Checked by caller. */\n\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* ROM strings have precomputed clen, but if the computed clen is zero\n\t * we can still come here and can't write anything.\n\t */\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) {\n\t\treturn 0;\n\t}\n#endif\n\n\tres = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n#if defined(DUK_USE_STRLEN16)\n\tDUK_ASSERT(res <= 0xffffUL);  /* Bytelength checked during interning. */\n\th->clen16 = (duk_uint16_t) res;\n#else\n\th->clen = (duk_uint32_t) res;\n#endif\n\tif (DUK_LIKELY(res == DUK_HSTRING_GET_BYTELEN(h))) {\n\t\tDUK_HSTRING_SET_ASCII(h);\n\t}\n\treturn res;\n}\n#else  /* DUK_USE_HSTRING_CLEN */\nDUK_LOCAL duk_size_t duk__hstring_get_charlen_slowpath(duk_hstring *h) {\n\tif (DUK_LIKELY(DUK_HSTRING_HAS_ASCII(h))) {\n\t\t/* Most practical strings will go here. */\n\t\treturn DUK_HSTRING_GET_BYTELEN(h);\n\t} else {\n\t\t/* ASCII flag is lazy, so set it here. */\n\t\tduk_size_t res;\n\n\t\t/* XXX: here we could use the strcache to speed up the\n\t\t * computation (matters for 'i < str.length' loops).\n\t\t */\n\n\t\tres = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\n#if defined(DUK_USE_ROM_STRINGS)\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) {\n\t\t\t/* For ROM strings, can't write anything; ASCII flag\n\t\t\t * is preset so we don't need to update it.\n\t\t\t */\n\t\t\treturn res;\n\t\t}\n#endif\n\t\tif (DUK_LIKELY(res == DUK_HSTRING_GET_BYTELEN(h))) {\n\t\t\tDUK_HSTRING_SET_ASCII(h);\n\t\t}\n\t\treturn res;\n\t}\n}\n#endif  /* DUK_USE_HSTRING_CLEN */\n\n#if defined(DUK_USE_HSTRING_CLEN)\nDUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {\n#if defined(DUK_USE_STRLEN16)\n\tif (DUK_LIKELY(h->clen16 != 0)) {\n\t\treturn h->clen16;\n\t}\n#else\n\tif (DUK_LIKELY(h->clen != 0)) {\n\t\treturn h->clen;\n\t}\n#endif\n\treturn duk__hstring_get_charlen_slowpath(h);\n}\n#else  /* DUK_USE_HSTRING_CLEN */\nDUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {\n\t/* Always use slow path. */\n\treturn duk__hstring_get_charlen_slowpath(h);\n}\n#endif  /* DUK_USE_HSTRING_CLEN */\n#endif  /* DUK_USE_HSTRING_LAZY_CLEN */\n\n/*\n *  Compare duk_hstring to an ASCII cstring.\n */\n\nDUK_INTERNAL duk_bool_t duk_hstring_equals_ascii_cstring(duk_hstring *h, const char *cstr) {\n\tduk_size_t len;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(cstr != NULL);\n\n\tlen = DUK_STRLEN(cstr);\n\tif (len != DUK_HSTRING_GET_BYTELEN(h)) {\n\t\treturn 0;\n\t}\n\tif (duk_memcmp((const void *) cstr, (const void *) DUK_HSTRING_GET_DATA(h), len) == 0) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n#line 1 \"duk_hthread_alloc.c\"\n/*\n *  duk_hthread allocation and freeing.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Allocate initial stacks for a thread.  Note that 'thr' must be reachable\n *  as a garbage collection may be triggered by the allocation attempts.\n *  Returns zero (without leaking memory) if init fails.\n */\n\nDUK_INTERNAL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr) {\n\tduk_size_t alloc_size;\n\tduk_size_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->valstack == NULL);\n\tDUK_ASSERT(thr->valstack_end == NULL);\n\tDUK_ASSERT(thr->valstack_alloc_end == NULL);\n\tDUK_ASSERT(thr->valstack_bottom == NULL);\n\tDUK_ASSERT(thr->valstack_top == NULL);\n\tDUK_ASSERT(thr->callstack_curr == NULL);\n\n\t/* valstack */\n\tDUK_ASSERT(DUK_VALSTACK_API_ENTRY_MINIMUM <= DUK_VALSTACK_INITIAL_SIZE);\n\talloc_size = sizeof(duk_tval) * DUK_VALSTACK_INITIAL_SIZE;\n\tthr->valstack = (duk_tval *) DUK_ALLOC(heap, alloc_size);\n\tif (!thr->valstack) {\n\t\tgoto fail;\n\t}\n\tduk_memzero(thr->valstack, alloc_size);\n\tthr->valstack_end = thr->valstack + DUK_VALSTACK_API_ENTRY_MINIMUM;\n\tthr->valstack_alloc_end = thr->valstack + DUK_VALSTACK_INITIAL_SIZE;\n\tthr->valstack_bottom = thr->valstack;\n\tthr->valstack_top = thr->valstack;\n\n\tfor (i = 0; i < DUK_VALSTACK_INITIAL_SIZE; i++) {\n\t\tDUK_TVAL_SET_UNDEFINED(&thr->valstack[i]);\n\t}\n\n\treturn 1;\n\n fail:\n\tDUK_FREE(heap, thr->valstack);\n\tDUK_ASSERT(thr->callstack_curr == NULL);\n\n\tthr->valstack = NULL;\n\treturn 0;\n}\n\n/* For indirect allocs. */\n\nDUK_INTERNAL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud) {\n\tduk_hthread *thr = (duk_hthread *) ud;\n\tDUK_UNREF(heap);\n\treturn (void *) thr->valstack;\n}\n#line 1 \"duk_hthread_builtins.c\"\n/*\n *  Initialize built-in objects.  Current thread must have a valstack\n *  and initialization errors may longjmp, so a setjmp() catch point\n *  must exist.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Encoding constants, must match genbuiltins.py\n */\n\n#define DUK__PROP_FLAGS_BITS             3\n#define DUK__LENGTH_PROP_BITS            3\n#define DUK__NARGS_BITS                  3\n#define DUK__PROP_TYPE_BITS              3\n\n#define DUK__NARGS_VARARGS_MARKER        0x07\n\n#define DUK__PROP_TYPE_DOUBLE            0\n#define DUK__PROP_TYPE_STRING            1\n#define DUK__PROP_TYPE_STRIDX            2\n#define DUK__PROP_TYPE_BUILTIN           3\n#define DUK__PROP_TYPE_UNDEFINED         4\n#define DUK__PROP_TYPE_BOOLEAN_TRUE      5\n#define DUK__PROP_TYPE_BOOLEAN_FALSE     6\n#define DUK__PROP_TYPE_ACCESSOR          7\n\n/*\n *  Create built-in objects by parsing an init bitstream generated\n *  by genbuiltins.py.\n */\n\n#if defined(DUK_USE_ROM_OBJECTS)\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) || defined(DUK_USE_ROM_GLOBAL_INHERIT)\nDUK_LOCAL void duk__duplicate_ram_global_object(duk_hthread *thr) {\n\tduk_hobject *h_global;\n#if defined(DUK_USE_ROM_GLOBAL_CLONE)\n\tduk_hobject *h_oldglobal;\n\tduk_uint8_t *props;\n\tduk_size_t alloc_size;\n#endif\n\tduk_hobject *h_objenv;\n\n\t/* XXX: refactor into internal helper, duk_clone_hobject() */\n\n#if defined(DUK_USE_ROM_GLOBAL_INHERIT)\n\t/* Inherit from ROM-based global object: less RAM usage, less transparent. */\n\th_global = duk_push_object_helper(thr,\n\t                                  DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                  DUK_HOBJECT_FLAG_FASTREFS |\n\t                                  DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL),\n\t                                  DUK_BIDX_GLOBAL);\n\tDUK_ASSERT(h_global != NULL);\n#elif defined(DUK_USE_ROM_GLOBAL_CLONE)\n\t/* Clone the properties of the ROM-based global object to create a\n\t * fully RAM-based global object.  Uses more memory than the inherit\n\t * model but more compliant.\n\t */\n\th_global = duk_push_object_helper(thr,\n\t                                  DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                  DUK_HOBJECT_FLAG_FASTREFS |\n\t                                  DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL),\n\t                                  DUK_BIDX_OBJECT_PROTOTYPE);\n\tDUK_ASSERT(h_global != NULL);\n\th_oldglobal = thr->builtins[DUK_BIDX_GLOBAL];\n\tDUK_ASSERT(h_oldglobal != NULL);\n\n\t/* Copy the property table verbatim; this handles attributes etc.\n\t * For ROM objects it's not necessary (or possible) to update\n\t * refcounts so leave them as is.\n\t */\n\talloc_size = DUK_HOBJECT_P_ALLOC_SIZE(h_oldglobal);\n\tDUK_ASSERT(alloc_size > 0);\n\tprops = DUK_ALLOC_CHECKED(thr, alloc_size);\n\tDUK_ASSERT(props != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, h_oldglobal) != NULL);\n\tduk_memcpy((void *) props, (const void *) DUK_HOBJECT_GET_PROPS(thr->heap, h_oldglobal), alloc_size);\n\n\t/* XXX: keep property attributes or tweak them here?\n\t * Properties will now be non-configurable even when they're\n\t * normally configurable for the global object.\n\t */\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, h_global) == NULL);\n\tDUK_HOBJECT_SET_PROPS(thr->heap, h_global, props);\n\tDUK_HOBJECT_SET_ESIZE(h_global, DUK_HOBJECT_GET_ESIZE(h_oldglobal));\n\tDUK_HOBJECT_SET_ENEXT(h_global, DUK_HOBJECT_GET_ENEXT(h_oldglobal));\n\tDUK_HOBJECT_SET_ASIZE(h_global, DUK_HOBJECT_GET_ASIZE(h_oldglobal));\n\tDUK_HOBJECT_SET_HSIZE(h_global, DUK_HOBJECT_GET_HSIZE(h_oldglobal));\n#else\n#error internal error in config defines\n#endif\n\n\tduk_hobject_compact_props(thr, h_global);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE((duk_heaphdr *) thr->builtins[DUK_BIDX_GLOBAL]));  /* no need to decref: ROM object */\n\tthr->builtins[DUK_BIDX_GLOBAL] = h_global;\n\tDUK_HOBJECT_INCREF(thr, h_global);\n\tDUK_D(DUK_DPRINT(\"duplicated global object: %!O\", h_global));\n\n\t/* Create a fresh object environment for the global scope.  This is\n\t * needed so that the global scope points to the newly created RAM-based\n\t * global object.\n\t */\n\th_objenv = (duk_hobject *) duk_hobjenv_alloc(thr,\n\t                                             DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                             DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\tDUK_ASSERT(h_objenv != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_objenv) == NULL);\n\tduk_push_hobject(thr, h_objenv);\n\n\tDUK_ASSERT(h_global != NULL);\n\t((duk_hobjenv *) h_objenv)->target = h_global;\n\tDUK_HOBJECT_INCREF(thr, h_global);\n\tDUK_ASSERT(((duk_hobjenv *) h_objenv)->has_this == 0);\n\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL_ENV] != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE((duk_heaphdr *) thr->builtins[DUK_BIDX_GLOBAL_ENV]));  /* no need to decref: ROM object */\n\tthr->builtins[DUK_BIDX_GLOBAL_ENV] = h_objenv;\n\tDUK_HOBJECT_INCREF(thr, h_objenv);\n\tDUK_D(DUK_DPRINT(\"duplicated global env: %!O\", h_objenv));\n\n\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) h_objenv);\n\n\tduk_pop_2(thr);  /* Pop global object and global env. */\n}\n#endif  /* DUK_USE_ROM_GLOBAL_CLONE || DUK_USE_ROM_GLOBAL_INHERIT */\n\nDUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {\n\t/* Setup builtins from ROM objects.  All heaps/threads will share\n\t * the same readonly objects.\n\t */\n\tduk_small_uint_t i;\n\n\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\tduk_hobject *h;\n\t\th = (duk_hobject *) DUK_LOSE_CONST(duk_rom_builtins_bidx[i]);\n\t\tDUK_ASSERT(h != NULL);\n\t\tthr->builtins[i] = h;\n\t}\n\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) || defined(DUK_USE_ROM_GLOBAL_INHERIT)\n\t/* By default the global object is read-only which is often much\n\t * more of an issue than having read-only built-in objects (like\n\t * RegExp, Date, etc).  Use a RAM-based copy of the global object\n\t * and the global environment object for convenience.\n\t */\n\tduk__duplicate_ram_global_object(thr);\n#endif\n}\n#else  /* DUK_USE_ROM_OBJECTS */\nDUK_LOCAL void duk__push_stridx(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\tduk_small_uint_t n;\n\n\tn = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\tDUK_ASSERT_DISABLE(n >= 0);  /* unsigned */\n\tDUK_ASSERT(n < DUK_HEAP_NUM_STRINGS);\n\tduk_push_hstring_stridx(thr, n);\n}\nDUK_LOCAL void duk__push_string(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\t/* XXX: built-ins data could provide a maximum length that is\n\t * actually needed; bitpacked max length is now 256 bytes.\n\t */\n\tduk_uint8_t tmp[DUK_BD_BITPACKED_STRING_MAXLEN];\n\tduk_small_uint_t len;\n\n\tlen = duk_bd_decode_bitpacked_string(bd, tmp);\n\tduk_push_lstring(thr, (const char *) tmp, (duk_size_t) len);\n}\nDUK_LOCAL void duk__push_stridx_or_string(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\tduk_small_uint_t n;\n\n\tn = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\tif (n == 0) {\n\t\tduk__push_string(thr, bd);\n\t} else {\n\t\tn--;\n\t\tDUK_ASSERT(n < DUK_HEAP_NUM_STRINGS);\n\t\tduk_push_hstring_stridx(thr, n);\n\t}\n}\nDUK_LOCAL void duk__push_double(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\tduk_double_union du;\n\tduk_small_uint_t i;\n\n\tfor (i = 0; i < 8; i++) {\n\t\t/* Encoding endianness must match target memory layout,\n\t\t * build scripts and genbuiltins.py must ensure this.\n\t\t */\n\t\tdu.uc[i] = (duk_uint8_t) duk_bd_decode(bd, 8);\n\t}\n\n\tduk_push_number(thr, du.d);  /* push operation normalizes NaNs */\n}\n\nDUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {\n\tduk_bitdecoder_ctx bd_ctx;\n\tduk_bitdecoder_ctx *bd = &bd_ctx;  /* convenience */\n\tduk_hobject *h;\n\tduk_small_uint_t i, j;\n\n\tDUK_D(DUK_DPRINT(\"INITBUILTINS BEGIN: DUK_NUM_BUILTINS=%d, DUK_NUM_BUILTINS_ALL=%d\", (int) DUK_NUM_BUILTINS, (int) DUK_NUM_ALL_BUILTINS));\n\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tbd->data = (const duk_uint8_t *) duk_builtins_data;\n\tbd->length = (duk_size_t) DUK_BUILTINS_DATA_LENGTH;\n\n\t/*\n\t *  First create all built-in bare objects on the empty valstack.\n\t *\n\t *  Built-ins in the index range [0,DUK_NUM_BUILTINS-1] have value\n\t *  stack indices matching their eventual thr->builtins[] index.\n\t *\n\t *  Built-ins in the index range [DUK_NUM_BUILTINS,DUK_NUM_ALL_BUILTINS]\n\t *  will exist on the value stack during init but won't be placed\n\t *  into thr->builtins[].  These are objects referenced in some way\n\t *  from thr->builtins[] roots but which don't need to be indexed by\n\t *  Duktape through thr->builtins[] (e.g. user custom objects).\n\t *\n\t *  Internal prototypes will be incorrect (NULL) at this stage.\n\t */\n\n\tduk_require_stack(thr, DUK_NUM_ALL_BUILTINS);\n\n\tDUK_DD(DUK_DDPRINT(\"create empty built-ins\"));\n\tDUK_ASSERT_TOP(thr, 0);\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tduk_small_uint_t class_num;\n\t\tduk_small_int_t len = -1;  /* must be signed */\n\n\t\tclass_num = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tlen = (duk_small_int_t) duk_bd_decode_flagged_signed(bd, DUK__LENGTH_PROP_BITS, (duk_int32_t) -1 /*def_value*/);\n\n\t\tif (class_num == DUK_HOBJECT_CLASS_FUNCTION) {\n\t\t\tduk_small_uint_t natidx;\n\t\t\tduk_small_int_t c_nargs;  /* must hold DUK_VARARGS */\n\t\t\tduk_c_function c_func;\n\t\t\tduk_int16_t magic;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"len=%ld\", (long) len));\n\t\t\tDUK_ASSERT(len >= 0);\n\n\t\t\tnatidx = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\tDUK_ASSERT(natidx != 0);\n\t\t\tc_func = duk_bi_native_functions[natidx];\n\t\t\tDUK_ASSERT(c_func != NULL);\n\n\t\t\tc_nargs = (duk_small_int_t) duk_bd_decode_flagged_signed(bd, DUK__NARGS_BITS, len /*def_value*/);\n\t\t\tif (c_nargs == DUK__NARGS_VARARGS_MARKER) {\n\t\t\t\tc_nargs = DUK_VARARGS;\n\t\t\t}\n\n\t\t\t/* XXX: set magic directly here? (it could share the c_nargs arg) */\n\t\t\t(void) duk_push_c_function_builtin(thr, c_func, c_nargs);\n\t\t\th = duk_known_hobject(thr, -1);\n\n\t\t\t/* Currently all built-in native functions are strict.\n\t\t\t * duk_push_c_function() now sets strict flag, so\n\t\t\t * assert for it.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_STRICT(h));\n\n\t\t\t/* XXX: function properties */\n\n\t\t\tduk__push_stridx_or_string(thr, bd);\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\t\t\tduk_xdef_prop_stridx_short(thr,\n\t\t\t                           -2,\n\t\t\t                           DUK_STRIDX_NAME,\n\t\t\t                           DUK_PROPDESC_FLAGS_C);\n#else\n\t\t\tduk_pop(thr);  /* Not very ideal but good enough for now. */\n#endif\n\n\t\t\t/* Almost all global level Function objects are constructable\n\t\t\t * but not all: Function.prototype is a non-constructable,\n\t\t\t * callable Function.\n\t\t\t */\n\t\t\tif (duk_bd_decode_flag(bd)) {\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_CONSTRUCTABLE(h));\n\t\t\t} else {\n\t\t\t\tDUK_HOBJECT_CLEAR_CONSTRUCTABLE(h);\n\t\t\t}\n\n\t\t\t/* Cast converts magic to 16-bit signed value */\n\t\t\tmagic = (duk_int16_t) duk_bd_decode_varuint(bd);\n\t\t\t((duk_hnatfunc *) h)->magic = magic;\n\t\t} else if (class_num == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tduk_push_array(thr);\n\t\t} else if (class_num == DUK_HOBJECT_CLASS_OBJENV) {\n\t\t\tduk_hobjenv *env;\n\t\t\tduk_hobject *global;\n\n\t\t\tDUK_ASSERT(i == DUK_BIDX_GLOBAL_ENV);\n\t\t\tDUK_ASSERT(DUK_BIDX_GLOBAL_ENV > DUK_BIDX_GLOBAL);\n\n\t\t\tenv = duk_hobjenv_alloc(thr,\n\t                                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\t\t\tDUK_ASSERT(env->target == NULL);\n\t\t\tduk_push_hobject(thr, (duk_hobject *) env);\n\n\t\t\tglobal = duk_known_hobject(thr, DUK_BIDX_GLOBAL);\n\t\t\tDUK_ASSERT(global != NULL);\n\t\t\tenv->target = global;\n\t\t\tDUK_HOBJECT_INCREF(thr, global);\n\t\t\tDUK_ASSERT(env->has_this == 0);\n\n\t\t\tDUK_HOBJENV_ASSERT_VALID(env);\n\t\t} else {\n\t\t\tDUK_ASSERT(class_num != DUK_HOBJECT_CLASS_DECENV);\n\n\t\t\t(void) duk_push_object_helper(thr,\n\t\t\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t\t\t                              DUK_HOBJECT_FLAG_EXTENSIBLE,\n\t\t\t                              -1);  /* no prototype or class yet */\n\n\t\t}\n\n\t\th = duk_known_hobject(thr, -1);\n\t\tDUK_HOBJECT_SET_CLASS_NUMBER(h, class_num);\n\n\t\tif (i < DUK_NUM_BUILTINS) {\n\t\t\tthr->builtins[i] = h;\n\t\t\tDUK_HOBJECT_INCREF(thr, &h->hdr);\n\t\t}\n\n\t\tif (len >= 0) {\n\t\t\t/* In ES2015+ built-in function object .length property\n\t\t\t * has property attributes C (configurable only):\n\t\t\t * http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-standard-built-in-objects\n\t\t\t *\n\t\t\t * Array.prototype remains an Array instance in ES2015+\n\t\t\t * and its length has attributes W (writable only).\n\t\t\t * Because .length is now virtual for duk_harray, it is\n\t\t\t * not encoded explicitly in init data.\n\t\t\t */\n\n\t\t\tDUK_ASSERT(class_num != DUK_HOBJECT_CLASS_ARRAY);  /* .length is virtual */\n\t\t\tduk_push_int(thr, len);\n\t\t\tduk_xdef_prop_stridx_short(thr,\n\t\t\t                           -2,\n\t\t\t                           DUK_STRIDX_LENGTH,\n\t\t\t                           DUK_PROPDESC_FLAGS_C);\n\t\t}\n\n\t\t/* enable exotic behaviors last */\n\n\t\tif (class_num == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(h));  /* set by duk_push_array() */\n\t\t}\n\t\tif (class_num == DUK_HOBJECT_CLASS_STRING) {\n\t\t\tDUK_HOBJECT_SET_EXOTIC_STRINGOBJ(h);\n\t\t}\n\n\t\t/* some assertions */\n\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h));\n\t\t/* DUK_HOBJECT_FLAG_CONSTRUCTABLE varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_COMPFUNC(h));\n\t\t/* DUK_HOBJECT_FLAG_NATFUNC varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_IS_PROXY(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(h) || class_num == DUK_HOBJECT_CLASS_ARRAY);\n\t\t/* DUK_HOBJECT_FLAG_STRICT varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(h) ||  /* all native functions have NEWENV */\n\t\t           DUK_HOBJECT_HAS_NEWENV(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NAMEBINDING(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(h));\n\t\t/* DUK_HOBJECT_FLAG_EXOTIC_ARRAY varies */\n\t\t/* DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"created built-in %ld, class=%ld, length=%ld\", (long) i, (long) class_num, (long) len));\n\t}\n\n\t/*\n\t *  Then decode the builtins init data (see genbuiltins.py) to\n\t *  init objects.  Internal prototypes are set at this stage,\n\t *  with thr->builtins[] populated.\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"initialize built-in object properties\"));\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tduk_small_uint_t t;\n\t\tduk_small_uint_t num;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"initializing built-in object at index %ld\", (long) i));\n\t\th = duk_known_hobject(thr, (duk_idx_t) i);\n\n\t\tt = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tif (t > 0) {\n\t\t\tt--;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"set internal prototype: built-in %ld\", (long) t));\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, duk_known_hobject(thr, (duk_idx_t) t));\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\t\t/* Standard native built-ins cannot inherit from\n\t\t\t * %NativeFunctionPrototype%, they are required to\n\t\t\t * inherit from Function.prototype directly.\n\t\t\t */\n\t\t\tDUK_ASSERT(thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE] != NULL);\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\t\t}\n\n\t\tt = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tif (t > 0) {\n\t\t\t/* 'prototype' property for all built-in objects (which have it) has attributes:\n\t\t\t *  [[Writable]] = false,\n\t\t\t *  [[Enumerable]] = false,\n\t\t\t *  [[Configurable]] = false\n\t\t\t */\n\t\t\tt--;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"set external prototype: built-in %ld\", (long) t));\n\t\t\tduk_dup(thr, (duk_idx_t) t);\n\t\t\tduk_xdef_prop_stridx(thr, (duk_idx_t) i, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_NONE);\n\t\t}\n\n\t\tt = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tif (t > 0) {\n\t\t\t/* 'constructor' property for all built-in objects (which have it) has attributes:\n\t\t\t *  [[Writable]] = true,\n\t\t\t *  [[Enumerable]] = false,\n\t\t\t *  [[Configurable]] = true\n\t\t\t */\n\t\t\tt--;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"set external constructor: built-in %ld\", (long) t));\n\t\t\tduk_dup(thr, (duk_idx_t) t);\n\t\t\tduk_xdef_prop_stridx(thr, (duk_idx_t) i, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC);\n\t\t}\n\n\t\t/* normal valued properties */\n\t\tnum = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tDUK_DDD(DUK_DDDPRINT(\"built-in object %ld, %ld normal valued properties\", (long) i, (long) num));\n\t\tfor (j = 0; j < num; j++) {\n\t\t\tduk_small_uint_t defprop_flags;\n\n\t\t\tduk__push_stridx_or_string(thr, bd);\n\n\t\t\t/*\n\t\t\t *  Property attribute defaults are defined in E5 Section 15 (first\n\t\t\t *  few pages); there is a default for all properties and a special\n\t\t\t *  default for 'length' properties.  Variation from the defaults is\n\t\t\t *  signaled using a single flag bit in the bitstream.\n\t\t\t */\n\n\t\t\tdefprop_flags = (duk_small_uint_t) duk_bd_decode_flagged(bd,\n\t\t\t                                                         DUK__PROP_FLAGS_BITS,\n\t\t\t                                                         (duk_uint32_t) DUK_PROPDESC_FLAGS_WC);\n\t\t\tdefprop_flags |= DUK_DEFPROP_FORCE |\n\t\t\t                 DUK_DEFPROP_HAVE_VALUE |\n\t\t\t                 DUK_DEFPROP_HAVE_WRITABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_ENUMERABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_CONFIGURABLE;  /* Defaults for data properties. */\n\n\t\t\t/* The writable, enumerable, configurable flags in prop_flags\n\t\t\t * match both duk_def_prop() and internal property flags.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_WRITABLE == DUK_DEFPROP_WRITABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_ENUMERABLE == DUK_DEFPROP_ENUMERABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_CONFIGURABLE == DUK_DEFPROP_CONFIGURABLE);\n\n\t\t\tt = (duk_small_uint_t) duk_bd_decode(bd, DUK__PROP_TYPE_BITS);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"built-in %ld, normal-valued property %ld, key %!T, flags 0x%02lx, type %ld\",\n\t\t\t                     (long) i, (long) j, duk_get_tval(thr, -1), (unsigned long) defprop_flags, (long) t));\n\n\t\t\tswitch (t) {\n\t\t\tcase DUK__PROP_TYPE_DOUBLE: {\n\t\t\t\tduk__push_double(thr, bd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_STRING: {\n\t\t\t\tduk__push_string(thr, bd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_STRIDX: {\n\t\t\t\tduk__push_stridx(thr, bd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_BUILTIN: {\n\t\t\t\tduk_small_uint_t bidx;\n\n\t\t\t\tbidx = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_dup(thr, (duk_idx_t) bidx);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_UNDEFINED: {\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_BOOLEAN_TRUE: {\n\t\t\t\tduk_push_true(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_BOOLEAN_FALSE: {\n\t\t\t\tduk_push_false(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_ACCESSOR: {\n\t\t\t\tduk_small_uint_t natidx_getter = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_small_uint_t natidx_setter = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_small_uint_t accessor_magic = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_c_function c_func_getter;\n\t\t\t\tduk_c_function c_func_setter;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"built-in accessor property: objidx=%ld, key=%!T, getteridx=%ld, setteridx=%ld, flags=0x%04lx\",\n\t\t\t\t                     (long) i, duk_get_tval(thr, -1), (long) natidx_getter, (long) natidx_setter, (unsigned long) defprop_flags));\n\n\t\t\t\tc_func_getter = duk_bi_native_functions[natidx_getter];\n\t\t\t\tif (c_func_getter != NULL) {\n\t\t\t\t\tduk_push_c_function_builtin_noconstruct(thr, c_func_getter, 0);  /* always 0 args */\n\t\t\t\t\tduk_set_magic(thr, -1, (duk_int_t) accessor_magic);\n\t\t\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_GETTER;\n\t\t\t\t}\n\t\t\t\tc_func_setter = duk_bi_native_functions[natidx_setter];\n\t\t\t\tif (c_func_setter != NULL) {\n\t\t\t\t\tduk_push_c_function_builtin_noconstruct(thr, c_func_setter, 1);  /* always 1 arg */\n\t\t\t\t\tduk_set_magic(thr, -1, (duk_int_t) accessor_magic);\n\t\t\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_SETTER;\n\t\t\t\t}\n\n\t\t\t\t/* Writable flag doesn't make sense for an accessor. */\n\t\t\t\tDUK_ASSERT((defprop_flags & DUK_PROPDESC_FLAG_WRITABLE) == 0);  /* genbuiltins.py ensures */\n\n\t\t\t\tdefprop_flags &= ~(DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE);\n\t\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t/* exhaustive */\n\t\t\t\tDUK_UNREACHABLE();\n\t\t\t}\n\t\t\t}\n\n\t\t\tduk_def_prop(thr, (duk_idx_t) i, defprop_flags);\n\t\t\tDUK_ASSERT_TOP(thr, DUK_NUM_ALL_BUILTINS);\n\t\t}\n\n\t\t/* native function properties */\n\t\tnum = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tDUK_DDD(DUK_DDDPRINT(\"built-in object %ld, %ld function valued properties\", (long) i, (long) num));\n\t\tfor (j = 0; j < num; j++) {\n\t\t\tduk_hstring *h_key;\n\t\t\tduk_small_uint_t natidx;\n\t\t\tduk_int_t c_nargs;  /* must hold DUK_VARARGS */\n\t\t\tduk_small_uint_t c_length;\n\t\t\tduk_int16_t magic;\n\t\t\tduk_c_function c_func;\n\t\t\tduk_hnatfunc *h_func;\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t\tduk_small_int_t lightfunc_eligible;\n#endif\n\t\t\tduk_small_uint_t defprop_flags;\n\n\t\t\tduk__push_stridx_or_string(thr, bd);\n\t\t\th_key = duk_known_hstring(thr, -1);\n\t\t\tDUK_UNREF(h_key);\n\t\t\tnatidx = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\n\t\t\tc_length = (duk_small_uint_t) duk_bd_decode(bd, DUK__LENGTH_PROP_BITS);\n\t\t\tc_nargs = (duk_int_t) duk_bd_decode_flagged(bd, DUK__NARGS_BITS, (duk_uint32_t) c_length /*def_value*/);\n\t\t\tif (c_nargs == DUK__NARGS_VARARGS_MARKER) {\n\t\t\t\tc_nargs = DUK_VARARGS;\n\t\t\t}\n\n\t\t\tc_func = duk_bi_native_functions[natidx];\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"built-in %ld, function-valued property %ld, key %!O, natidx %ld, length %ld, nargs %ld\",\n\t\t\t                     (long) i, (long) j, (duk_heaphdr *) h_key, (long) natidx, (long) c_length,\n\t\t\t                     (c_nargs == DUK_VARARGS ? (long) -1 : (long) c_nargs)));\n\n\t\t\t/* Cast converts magic to 16-bit signed value */\n\t\t\tmagic = (duk_int16_t) duk_bd_decode_varuint(bd);\n\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t\tlightfunc_eligible =\n\t\t\t\t((c_nargs >= DUK_LFUNC_NARGS_MIN && c_nargs <= DUK_LFUNC_NARGS_MAX) || (c_nargs == DUK_VARARGS)) &&\n\t\t\t\t(c_length <= DUK_LFUNC_LENGTH_MAX) &&\n\t\t\t\t(magic >= DUK_LFUNC_MAGIC_MIN && magic <= DUK_LFUNC_MAGIC_MAX);\n\n\t\t\t/* These functions have trouble working as lightfuncs.\n\t\t\t * Some of them have specific asserts and some may have\n\t\t         * additional properties (e.g. 'require.id' may be written).\n\t\t\t */\n\t\t\tif (c_func == duk_bi_global_object_eval) {\n\t\t\t\tlightfunc_eligible = 0;\n\t\t\t}\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\t\t\tif (c_func == duk_bi_thread_yield ||\n\t\t\t    c_func == duk_bi_thread_resume) {\n\t\t\t\tlightfunc_eligible = 0;\n\t\t\t}\n#endif\n\t\t\tif (c_func == duk_bi_function_prototype_call ||\n\t\t\t    c_func == duk_bi_function_prototype_apply ||\n\t\t\t    c_func == duk_bi_reflect_apply ||\n\t\t\t    c_func == duk_bi_reflect_construct) {\n\t\t\t\tlightfunc_eligible = 0;\n\t\t\t}\n\n\t\t\tif (lightfunc_eligible) {\n\t\t\t\tduk_tval tv_lfunc;\n\t\t\t\tduk_small_uint_t lf_nargs = (duk_small_uint_t) (c_nargs == DUK_VARARGS ? DUK_LFUNC_NARGS_VARARGS : c_nargs);\n\t\t\t\tduk_small_uint_t lf_flags = DUK_LFUNC_FLAGS_PACK(magic, c_length, lf_nargs);\n\t\t\t\tDUK_TVAL_SET_LIGHTFUNC(&tv_lfunc, c_func, lf_flags);\n\t\t\t\tduk_push_tval(thr, &tv_lfunc);\n\t\t\t\tDUK_D(DUK_DPRINT(\"built-in function eligible as light function: i=%d, j=%d c_length=%ld, c_nargs=%ld, magic=%ld -> %!iT\", (int) i, (int) j, (long) c_length, (long) c_nargs, (long) magic, duk_get_tval(thr, -1)));\n\t\t\t\tgoto lightfunc_skip;\n\t\t\t}\n\n\t\t\tDUK_D(DUK_DPRINT(\"built-in function NOT ELIGIBLE as light function: i=%d, j=%d c_length=%ld, c_nargs=%ld, magic=%ld\", (int) i, (int) j, (long) c_length, (long) c_nargs, (long) magic));\n#endif  /* DUK_USE_LIGHTFUNC_BUILTINS */\n\n\t\t\t/* [ (builtin objects) name ] */\n\n\t\t\tduk_push_c_function_builtin_noconstruct(thr, c_func, c_nargs);\n\t\t\th_func = duk_known_hnatfunc(thr, -1);\n\t\t\tDUK_UNREF(h_func);\n\n\t\t\t/* XXX: add into init data? */\n\n\t\t\t/* Special call handling, not described in init data. */\n\t\t\tif (c_func == duk_bi_global_object_eval ||\n\t\t\t    c_func == duk_bi_function_prototype_call ||\n\t\t\t    c_func == duk_bi_function_prototype_apply ||\n\t\t\t    c_func == duk_bi_reflect_apply ||\n\t\t\t    c_func == duk_bi_reflect_construct) {\n\t\t\t\tDUK_HOBJECT_SET_SPECIAL_CALL((duk_hobject *) h_func);\n\t\t\t}\n\n\t\t\t/* Currently all built-in native functions are strict.\n\t\t\t * This doesn't matter for many functions, but e.g.\n\t\t\t * String.prototype.charAt (and other string functions)\n\t\t\t * rely on being strict so that their 'this' binding is\n\t\t\t * not automatically coerced.\n\t\t\t */\n\t\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_func);\n\n\t\t\t/* No built-in functions are constructable except the top\n\t\t\t * level ones (Number, etc).\n\t\t\t */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) h_func));\n\n\t\t\t/* XXX: any way to avoid decoding magic bit; there are quite\n\t\t\t * many function properties and relatively few with magic values.\n\t\t\t */\n\t\t\th_func->magic = magic;\n\n\t\t\t/* [ (builtin objects) name func ] */\n\n\t\t\tduk_push_uint(thr, c_length);\n\t\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);\n\n\t\t\tduk_dup_m2(thr);\n\t\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n\n\t\t\t/* XXX: other properties of function instances; 'arguments', 'caller'. */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"built-in object %ld, function property %ld -> %!T\",\n\t\t\t                   (long) i, (long) j, (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t/* [ (builtin objects) name func ] */\n\n\t\t\t/*\n\t\t\t *  The default property attributes are correct for all\n\t\t\t *  function valued properties of built-in objects now.\n\t\t\t */\n\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t lightfunc_skip:\n#endif\n\n\t\t\tdefprop_flags = (duk_small_uint_t) duk_bd_decode_flagged(bd,\n\t\t\t                                                         DUK__PROP_FLAGS_BITS,\n\t\t\t                                                         (duk_uint32_t) DUK_PROPDESC_FLAGS_WC);\n\t\t\tdefprop_flags |= DUK_DEFPROP_FORCE |\n\t\t\t                 DUK_DEFPROP_HAVE_VALUE |\n\t\t\t                 DUK_DEFPROP_HAVE_WRITABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_ENUMERABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_CONFIGURABLE;\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_WRITABLE == DUK_DEFPROP_WRITABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_ENUMERABLE == DUK_DEFPROP_ENUMERABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_CONFIGURABLE == DUK_DEFPROP_CONFIGURABLE);\n\n\t\t\tduk_def_prop(thr, (duk_idx_t) i, defprop_flags);\n\n\t\t\t/* [ (builtin objects) ] */\n\t\t}\n\t}\n\n\t/*\n\t *  Special post-tweaks, for cases not covered by the init data format.\n\t *\n\t *  - Set Date.prototype.toGMTString to Date.prototype.toUTCString.\n\t *    toGMTString is required to have the same Function object as\n\t *    toUTCString in E5 Section B.2.6.  Note that while Smjs respects\n\t *    this, V8 does not (the Function objects are distinct).\n\t *\n\t *  - Make DoubleError non-extensible.\n\t *\n\t *  - Add info about most important effective compile options to Duktape.\n\t *\n\t *  - Possibly remove some properties (values or methods) which are not\n\t *    desirable with current feature options but are not currently\n\t *    conditional in init data.\n\t */\n\n#if defined(DUK_USE_DATE_BUILTIN)\n\tduk_get_prop_stridx_short(thr, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_UTC_STRING);\n\tduk_xdef_prop_stridx_short(thr, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_GMT_STRING, DUK_PROPDESC_FLAGS_WC);\n#endif\n\n\th = duk_known_hobject(thr, DUK_BIDX_DOUBLE_ERROR);\n\tDUK_HOBJECT_CLEAR_EXTENSIBLE(h);\n\n#if !defined(DUK_USE_ES6_OBJECT_PROTO_PROPERTY)\n\tDUK_DD(DUK_DDPRINT(\"delete Object.prototype.__proto__ built-in which is not enabled in features\"));\n\t(void) duk_hobject_delprop_raw(thr, thr->builtins[DUK_BIDX_OBJECT_PROTOTYPE], DUK_HTHREAD_STRING___PROTO__(thr), DUK_DELPROP_FLAG_THROW);\n#endif\n\n#if !defined(DUK_USE_ES6_OBJECT_SETPROTOTYPEOF)\n\tDUK_DD(DUK_DDPRINT(\"delete Object.setPrototypeOf built-in which is not enabled in features\"));\n\t(void) duk_hobject_delprop_raw(thr, thr->builtins[DUK_BIDX_OBJECT_CONSTRUCTOR], DUK_HTHREAD_STRING_SET_PROTOTYPE_OF(thr), DUK_DELPROP_FLAG_THROW);\n#endif\n\n\t/* XXX: relocate */\n\tduk_push_string(thr,\n\t\t\t/* Endianness indicator */\n#if defined(DUK_USE_INTEGER_LE)\n\t                \"l\"\n#elif defined(DUK_USE_INTEGER_BE)\n\t                \"b\"\n#elif defined(DUK_USE_INTEGER_ME)  /* integer mixed endian not really used now */\n\t                \"m\"\n#else\n\t                \"?\"\n#endif\n#if defined(DUK_USE_DOUBLE_LE)\n\t                \"l\"\n#elif defined(DUK_USE_DOUBLE_BE)\n\t                \"b\"\n#elif defined(DUK_USE_DOUBLE_ME)\n\t                \"m\"\n#else\n\t                \"?\"\n#endif\n\t                \" \"\n\t\t\t/* Packed or unpacked tval */\n#if defined(DUK_USE_PACKED_TVAL)\n\t                \"p\"\n#else\n\t                \"u\"\n#endif\n#if defined(DUK_USE_FASTINT)\n\t\t\t\"f\"\n#endif\n\t\t\t\" \"\n\t\t\t/* Low memory/performance options */\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\t\t\"s\"\n#endif\n#if !defined(DUK_USE_HEAPPTR16) && !defined(DUK_DATAPTR16) && !defined(DUK_FUNCPTR16)\n\t\t\t\"n\"\n#endif\n#if defined(DUK_USE_HEAPPTR16)\n\t\t\t\"h\"\n#endif\n#if defined(DUK_USE_DATAPTR16)\n\t\t\t\"d\"\n#endif\n#if defined(DUK_USE_FUNCPTR16)\n\t\t\t\"f\"\n#endif\n#if defined(DUK_USE_REFCOUNT16)\n\t\t\t\"R\"\n#endif\n#if defined(DUK_USE_STRHASH16)\n\t\t\t\"H\"\n#endif\n#if defined(DUK_USE_STRLEN16)\n\t\t\t\"S\"\n#endif\n#if defined(DUK_USE_BUFLEN16)\n\t\t\t\"B\"\n#endif\n#if defined(DUK_USE_OBJSIZES16)\n\t\t\t\"O\"\n#endif\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t\t\"L\"\n#endif\n#if defined(DUK_USE_ROM_STRINGS) || defined(DUK_USE_ROM_OBJECTS)\n\t\t\t/* XXX: This won't be shown in practice now\n\t\t\t * because this code is not run when builtins\n\t\t\t * are in ROM.\n\t\t\t */\n\t\t\t\"Z\"\n#endif\n#if defined(DUK_USE_LITCACHE_SIZE)\n\t\t\t\"l\"\n#endif\n\t                \" \"\n\t\t\t/* Object property allocation layout */\n#if defined(DUK_USE_HOBJECT_LAYOUT_1)\n\t\t\t\"p1\"\n#elif defined(DUK_USE_HOBJECT_LAYOUT_2)\n\t\t\t\"p2\"\n#elif defined(DUK_USE_HOBJECT_LAYOUT_3)\n\t\t\t\"p3\"\n#else\n\t\t\t\"p?\"\n#endif\n\t\t\t\" \"\n\t\t\t/* Alignment guarantee */\n#if (DUK_USE_ALIGN_BY == 4)\n\t\t\t\"a4\"\n#elif (DUK_USE_ALIGN_BY == 8)\n\t\t\t\"a8\"\n#elif (DUK_USE_ALIGN_BY == 1)\n\t\t\t\"a1\"\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\t\t\t\" \"\n\t\t\t/* Architecture, OS, and compiler strings */\n\t                DUK_USE_ARCH_STRING\n\t\t\t\" \"\n\t                DUK_USE_OS_STRING\n\t\t\t\" \"\n\t                DUK_USE_COMPILER_STRING);\n\tduk_xdef_prop_stridx_short(thr, DUK_BIDX_DUKTAPE, DUK_STRIDX_ENV, DUK_PROPDESC_FLAGS_WC);\n\n\t/*\n\t *  Since built-ins are not often extended, compact them.\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"compact built-ins\"));\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tduk_hobject_compact_props(thr, duk_known_hobject(thr, (duk_idx_t) i));\n\t}\n\n\tDUK_D(DUK_DPRINT(\"INITBUILTINS END\"));\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tDUK_DD(DUK_DDPRINT(\"built-in object %ld after initialization and compacting: %!@iO\",\n\t\t                   (long) i, (duk_heaphdr *) duk_require_hobject(thr, (duk_idx_t) i)));\n\t}\n#endif\n\n\t/*\n\t *  Pop built-ins from stack: they are now INCREF'd and\n\t *  reachable from the builtins[] array or indirectly\n\t *  through builtins[].\n\t */\n\n\tduk_set_top(thr, 0);\n\tDUK_ASSERT_TOP(thr, 0);\n}\n#endif  /* DUK_USE_ROM_OBJECTS */\n\nDUK_INTERNAL void duk_hthread_copy_builtin_objects(duk_hthread *thr_from, duk_hthread *thr_to) {\n\tduk_small_uint_t i;\n\n\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\tthr_to->builtins[i] = thr_from->builtins[i];\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr_to, thr_to->builtins[i]);  /* side effect free */\n\t}\n}\n\n/* automatic undefs */\n#undef DUK__LENGTH_PROP_BITS\n#undef DUK__NARGS_BITS\n#undef DUK__NARGS_VARARGS_MARKER\n#undef DUK__PROP_FLAGS_BITS\n#undef DUK__PROP_TYPE_ACCESSOR\n#undef DUK__PROP_TYPE_BITS\n#undef DUK__PROP_TYPE_BOOLEAN_FALSE\n#undef DUK__PROP_TYPE_BOOLEAN_TRUE\n#undef DUK__PROP_TYPE_BUILTIN\n#undef DUK__PROP_TYPE_DOUBLE\n#undef DUK__PROP_TYPE_STRIDX\n#undef DUK__PROP_TYPE_STRING\n#undef DUK__PROP_TYPE_UNDEFINED\n#line 1 \"duk_hthread_misc.c\"\n/*\n *  Thread support.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL void duk_hthread_terminate(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\twhile (thr->callstack_curr != NULL) {\n\t\tduk_hthread_activation_unwind_norz(thr);\n\t}\n\n\tthr->valstack_bottom = thr->valstack;\n\tduk_set_top(thr, 0);  /* unwinds valstack, updating refcounts */\n\n\tthr->state = DUK_HTHREAD_STATE_TERMINATED;\n\n\t/* Here we could remove references to built-ins, but it may not be\n\t * worth the effort because built-ins are quite likely to be shared\n\t * with another (unterminated) thread, and terminated threads are also\n\t * usually garbage collected quite quickly.\n\t *\n\t * We could also shrink the value stack here, but that also may not\n\t * be worth the effort for the same reason.\n\t */\n\n\tDUK_REFZERO_CHECK_SLOW(thr);\n}\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_curr_pc(duk_hthread *thr, duk_activation *act) {\n\tduk_instr_t *bcode;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_UNREF(thr);\n\n\t/* XXX: store 'bcode' pointer to activation for faster lookup? */\n\tif (act->func && DUK_HOBJECT_IS_COMPFUNC(act->func)) {\n\t\tbcode = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) (act->func));\n\t\treturn (duk_uint_fast32_t) (act->curr_pc - bcode);\n\t}\n\treturn 0;\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\nDUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_prev_pc(duk_hthread *thr, duk_activation *act) {\n\tduk_instr_t *bcode;\n\tduk_uint_fast32_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_UNREF(thr);\n\n\tif (act->func && DUK_HOBJECT_IS_COMPFUNC(act->func)) {\n\t\tbcode = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) (act->func));\n\t\tret = (duk_uint_fast32_t) (act->curr_pc - bcode);\n\t\tif (ret > 0) {\n\t\t\tret--;\n\t\t}\n\t\treturn ret;\n\t}\n\treturn 0;\n}\n\n/* Write bytecode executor's curr_pc back to topmost activation (if any). */\nDUK_INTERNAL void duk_hthread_sync_currpc(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tif (thr->ptr_curr_pc != NULL) {\n\t\t/* ptr_curr_pc != NULL only when bytecode executor is active. */\n\t\tDUK_ASSERT(thr->callstack_top > 0);\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tact = thr->callstack_curr;\n\t\tDUK_ASSERT(act != NULL);\n\t\tact->curr_pc = *thr->ptr_curr_pc;\n\t}\n}\n\nDUK_INTERNAL void duk_hthread_sync_and_null_currpc(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tif (thr->ptr_curr_pc != NULL) {\n\t\t/* ptr_curr_pc != NULL only when bytecode executor is active. */\n\t\tDUK_ASSERT(thr->callstack_top > 0);\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tact = thr->callstack_curr;\n\t\tDUK_ASSERT(act != NULL);\n\t\tact->curr_pc = *thr->ptr_curr_pc;\n\t\tthr->ptr_curr_pc = NULL;\n\t}\n}\n#line 1 \"duk_hthread_stacks.c\"\n/*\n *  Thread stack (mainly call stack) primitives: allocation of activations,\n *  unwinding catchers and activations, etc.\n *\n *  Value stack handling is a part of the API implementation.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Unwind the topmost catcher of the current activation (caller must check that\n * both exist) without side effects.\n */\nDUK_INTERNAL void duk_hthread_catcher_unwind_norz(duk_hthread *thr, duk_activation *act) {\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(act->cat != NULL);  /* caller must check */\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"unwinding catch stack entry %p (lexenv check is done)\", (void *) cat));\n\n\tif (DUK_CAT_HAS_LEXENV_ACTIVE(cat)) {\n\t\tduk_hobject *env;\n\n\t\tenv = act->lex_env;             /* current lex_env of the activation (created for catcher) */\n\t\tDUK_ASSERT(env != NULL);        /* must be, since env was created when catcher was created */\n\t\tact->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, env);  /* prototype is lex_env before catcher created */\n\t\tDUK_HOBJECT_INCREF(thr, act->lex_env);\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, env);\n\n\t\t/* There is no need to decref anything else than 'env': if 'env'\n\t\t * becomes unreachable, refzero will handle decref'ing its prototype.\n\t\t */\n\t}\n\n\tact->cat = cat->parent;\n\tduk_hthread_catcher_free(thr, cat);\n}\n\n/* Same as above, but caller is certain no catcher-related lexenv may exist. */\nDUK_INTERNAL void duk_hthread_catcher_unwind_nolexenv_norz(duk_hthread *thr, duk_activation *act) {\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(act->cat != NULL);  /* caller must check */\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"unwinding catch stack entry %p (lexenv check is not done)\", (void *) cat));\n\n\tDUK_ASSERT(!DUK_CAT_HAS_LEXENV_ACTIVE(cat));\n\n\tact->cat = cat->parent;\n\tduk_hthread_catcher_free(thr, cat);\n}\n\nDUK_LOCAL\n#if defined(DUK_USE_CACHE_CATCHER)\nDUK_NOINLINE\n#endif\nduk_catcher *duk__hthread_catcher_alloc_slow(duk_hthread *thr) {\n\tduk_catcher *cat;\n\n\tcat = (duk_catcher *) DUK_ALLOC_CHECKED(thr, sizeof(duk_catcher));\n\tDUK_ASSERT(cat != NULL);\n\treturn cat;\n}\n\n#if defined(DUK_USE_CACHE_CATCHER)\nDUK_INTERNAL DUK_INLINE duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr) {\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tcat = thr->heap->catcher_free;\n\tif (DUK_LIKELY(cat != NULL)) {\n\t\tthr->heap->catcher_free = cat->parent;\n\t\treturn cat;\n\t}\n\n\treturn duk__hthread_catcher_alloc_slow(thr);\n}\n#else  /* DUK_USE_CACHE_CATCHER */\nDUK_INTERNAL duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr) {\n\treturn duk__hthread_catcher_alloc_slow(thr);\n}\n#endif  /* DUK_USE_CACHE_CATCHER */\n\nDUK_INTERNAL void duk_hthread_catcher_free(duk_hthread *thr, duk_catcher *cat) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(cat != NULL);\n\n#if defined(DUK_USE_CACHE_CATCHER)\n\t/* Unconditional caching for now; freed in mark-and-sweep. */\n\tcat->parent = thr->heap->catcher_free;\n\tthr->heap->catcher_free = cat;\n#else\n\tDUK_FREE_CHECKED(thr, (void *) cat);\n#endif\n}\n\nDUK_LOCAL\n#if defined(DUK_USE_CACHE_ACTIVATION)\nDUK_NOINLINE\n#endif\nduk_activation *duk__hthread_activation_alloc_slow(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tact = (duk_activation *) DUK_ALLOC_CHECKED(thr, sizeof(duk_activation));\n\tDUK_ASSERT(act != NULL);\n\treturn act;\n}\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\nDUK_INTERNAL DUK_INLINE duk_activation *duk_hthread_activation_alloc(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tact = thr->heap->activation_free;\n\tif (DUK_LIKELY(act != NULL)) {\n\t\tthr->heap->activation_free = act->parent;\n\t\treturn act;\n\t}\n\n\treturn duk__hthread_activation_alloc_slow(thr);\n}\n#else  /* DUK_USE_CACHE_ACTIVATION */\nDUK_INTERNAL duk_activation *duk_hthread_activation_alloc(duk_hthread *thr) {\n\treturn duk__hthread_activation_alloc_slow(thr);\n}\n#endif  /* DUK_USE_CACHE_ACTIVATION */\n\n\nDUK_INTERNAL void duk_hthread_activation_free(duk_hthread *thr, duk_activation *act) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\t/* Unconditional caching for now; freed in mark-and-sweep. */\n\tact->parent = thr->heap->activation_free;\n\tthr->heap->activation_free = act;\n#else\n\tDUK_FREE_CHECKED(thr, (void *) act);\n#endif\n}\n\n/* Internal helper: process the unwind for the topmost activation of a thread,\n * but leave the duk_activation in place for possible tailcall reuse.\n */\nDUK_LOCAL void duk__activation_unwind_nofree_norz(duk_hthread *thr) {\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_heap *heap;\n#endif\n\tduk_activation *act;\n\tduk_hobject *func;\n\tduk_hobject *tmp;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->callstack_curr != NULL);  /* caller must check */\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\t/* With lightfuncs, act 'func' may be NULL. */\n\n\t/* With duk_activation records allocated separately, 'act' is a stable\n\t * pointer and not affected by side effects.\n\t */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t/*\n\t *  Restore 'caller' property for non-strict callee functions.\n\t */\n\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tif (func != NULL && !DUK_HOBJECT_HAS_STRICT(func)) {\n\t\tduk_tval *tv_caller;\n\t\tduk_tval tv_tmp;\n\t\tduk_hobject *h_tmp;\n\n\t\ttv_caller = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, func, DUK_STRIDX_CALLER);\n\n\t\t/* The act->prev_caller should only be set if the entry for 'caller'\n\t\t * exists (as it is only set in that case, and the property is not\n\t\t * configurable), but handle all the cases anyway.\n\t\t */\n\n\t\tif (tv_caller) {\n\t\t\tDUK_TVAL_SET_TVAL(&tv_tmp, tv_caller);\n\t\t\tif (act->prev_caller) {\n\t\t\t\t/* Just transfer the refcount from act->prev_caller to tv_caller,\n\t\t\t\t * so no need for a refcount update.  This is the expected case.\n\t\t\t\t */\n\t\t\t\tDUK_TVAL_SET_OBJECT(tv_caller, act->prev_caller);\n\t\t\t\tact->prev_caller = NULL;\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_NULL(tv_caller);   /* no incref needed */\n\t\t\t\tDUK_ASSERT(act->prev_caller == NULL);\n\t\t\t}\n\t\t\tDUK_TVAL_DECREF_NORZ(thr, &tv_tmp);\n\t\t} else {\n\t\t\th_tmp = act->prev_caller;\n\t\t\tif (h_tmp) {\n\t\t\t\tact->prev_caller = NULL;\n\t\t\t\tDUK_HOBJECT_DECREF_NORZ(thr, h_tmp);\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(act->prev_caller == NULL);\n\t}\n#endif\n\n\t/*\n\t *  Unwind debugger state.  If we unwind while stepping\n\t *  (for any step type), pause execution.  This is the\n\t *  only place explicitly handling a step out.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\theap = thr->heap;\n\tif (heap->dbg_pause_act == thr->callstack_curr) {\n\t\tif (heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_EXIT) {\n\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by function exit\"));\n\t\t\tduk_debug_set_paused(heap);\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"unwound past dbg_pause_act, set to NULL\"));\n\t\t\theap->dbg_pause_act = NULL;  /* avoid stale pointers */\n\t\t}\n\t\tDUK_ASSERT(heap->dbg_pause_act == NULL);\n\t}\n#endif\n\n\t/*\n\t *  Unwind catchers.\n\t *\n\t *  Since there are no references in the catcher structure,\n\t *  unwinding is quite simple.  The only thing we need to\n\t *  look out for is popping a possible lexical environment\n\t *  established for an active catch clause.\n\t */\n\n\twhile (act->cat != NULL) {\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t}\n\n\t/*\n\t *  Close environment record(s) if they exist.\n\t *\n\t *  Only variable environments are closed.  If lex_env != var_env, it\n\t *  cannot currently contain any register bound declarations.\n\t *\n\t *  Only environments created for a NEWENV function are closed.  If an\n\t *  environment is created for e.g. an eval call, it must not be closed.\n\t */\n\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tif (func != NULL && !DUK_HOBJECT_HAS_NEWENV(func)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"skip closing environments, envs not owned by this activation\"));\n\t\tgoto skip_env_close;\n\t}\n\t/* func is NULL for lightfunc */\n\n\t/* Catch sites are required to clean up their environments\n\t * in FINALLY part before propagating, so this should\n\t * always hold here.\n\t */\n\tDUK_ASSERT(act->lex_env == act->var_env);\n\n\t/* XXX: Closing the environment record copies values from registers\n\t * into the scope object.  It's side effect free as such, but may\n\t * currently run out of memory which causes an error throw.  This is\n\t * an actual sandboxing problem for error unwinds, and needs to be\n\t * fixed e.g. by preallocating the scope property slots.\n\t */\n\tif (act->var_env != NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"closing var_env record %p -> %!O\",\n\t\t                     (void *) act->var_env, (duk_heaphdr *) act->var_env));\n\t\tduk_js_close_environment_record(thr, act->var_env);\n\t}\n\n skip_env_close:\n\n\t/*\n\t *  Update preventcount\n\t */\n\n\tif (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) {\n\t\tDUK_ASSERT(thr->callstack_preventcount >= 1);\n\t\tthr->callstack_preventcount--;\n\t}\n\n\t/*\n\t *  Reference count updates, using NORZ macros so we don't\n\t *  need to handle side effects.\n\t *\n\t *  duk_activation pointers like act->var_env are intentionally\n\t *  left as garbage and not NULLed.  Without side effects they\n\t *  can't be used when the values are dangling/garbage.\n\t */\n\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, act->var_env);\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, act->lex_env);\n\ttmp = DUK_ACT_GET_FUNC(act);\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\tDUK_UNREF(tmp);\n}\n\n/* Unwind topmost duk_activation of a thread, caller must ensure that an\n * activation exists.  The call is side effect free, except that scope\n * closure may currently throw an out-of-memory error.\n */\nDUK_INTERNAL void duk_hthread_activation_unwind_norz(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tduk__activation_unwind_nofree_norz(thr);\n\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tact = thr->callstack_curr;\n\tthr->callstack_curr = act->parent;\n\tthr->callstack_top--;\n\n\t/* Ideally we'd restore value stack reserve here to caller's value.\n\t * This doesn't work for current unwind call sites however, because\n\t * the current (unwound) value stack top may be above the reserve.\n\t * Thus value stack reserve is restored by the call sites.\n\t */\n\n\t/* XXX: inline for performance builds? */\n\tduk_hthread_activation_free(thr, act);\n\n\t/* We could clear the book-keeping variables like retval_byteoff for\n\t * the topmost activation, but don't do so now as it's not necessary.\n\t */\n}\n\nDUK_INTERNAL void duk_hthread_activation_unwind_reuse_norz(duk_hthread *thr) {\n\tduk__activation_unwind_nofree_norz(thr);\n}\n\n/* Get duk_activation for given callstack level or NULL if level is invalid\n * or deeper than the call stack.  Level -1 refers to current activation, -2\n * to its caller, etc.  Starting from Duktape 2.2 finding the activation is\n * a linked list scan which gets more expensive the deeper the lookup is.\n */\nDUK_INTERNAL duk_activation *duk_hthread_get_activation_for_level(duk_hthread *thr, duk_int_t level) {\n\tduk_activation *act;\n\n\tif (level >= 0) {\n\t\treturn NULL;\n\t}\n\tact = thr->callstack_curr;\n\tfor (;;) {\n\t\tif (act == NULL) {\n\t\t\treturn act;\n\t\t}\n\t\tif (level == -1) {\n\t\t\treturn act;\n\t\t}\n\t\tlevel++;\n\t\tact = act->parent;\n\t}\n\t/* never here */\n}\n\n#if defined(DUK_USE_FINALIZER_TORTURE)\nDUK_INTERNAL void duk_hthread_valstack_torture_realloc(duk_hthread *thr) {\n\tduk_size_t alloc_size;\n\tduk_tval *new_ptr;\n\tduk_ptrdiff_t alloc_end_off;\n\tduk_ptrdiff_t end_off;\n\tduk_ptrdiff_t bottom_off;\n\tduk_ptrdiff_t top_off;\n\n\tif (thr->valstack == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"skip valstack torture realloc, valstack is NULL\"));\n\t\treturn;\n\t}\n\n\talloc_end_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_alloc_end - (duk_uint8_t *) thr->valstack);\n\tend_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tbottom_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);\n\ttop_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack);\n\talloc_size = (duk_size_t) alloc_end_off;\n\tif (alloc_size == 0) {\n\t\tDUK_D(DUK_DPRINT(\"skip valstack torture realloc, alloc_size is zero\"));\n\t\treturn;\n\t}\n\n\t/* Use DUK_ALLOC_RAW() to avoid side effects. */\n\tnew_ptr = (duk_tval *) DUK_ALLOC_RAW(thr->heap, alloc_size);\n\tif (new_ptr != NULL) {\n\t\tduk_memcpy((void *) new_ptr, (const void *) thr->valstack, alloc_size);\n\t\tduk_memset((void *) thr->valstack, 0x55, alloc_size);\n\t\tDUK_FREE_CHECKED(thr, (void *) thr->valstack);\n\t\tthr->valstack = new_ptr;\n\t\tthr->valstack_alloc_end = (duk_tval *) ((duk_uint8_t *) new_ptr + alloc_end_off);\n\t\tthr->valstack_end = (duk_tval *) ((duk_uint8_t *) new_ptr + end_off);\n\t\tthr->valstack_bottom = (duk_tval *) ((duk_uint8_t *) new_ptr + bottom_off);\n\t\tthr->valstack_top = (duk_tval *) ((duk_uint8_t *) new_ptr + top_off);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"failed to realloc valstack for torture, ignore\"));\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_TORTURE */\n#line 1 \"duk_js_arith.c\"\n/*\n *  Shared helpers for arithmetic operations\n */\n\n/* #include duk_internal.h -> already included */\n\n/* ECMAScript modulus ('%') does not match IEEE 754 \"remainder\" operation\n * (implemented by remainder() in C99) but does seem to match ANSI C fmod().\n * Compare E5 Section 11.5.3 and \"man fmod\".\n */\nDUK_INTERNAL double duk_js_arith_mod(double d1, double d2) {\n#if defined(DUK_USE_POW_WORKAROUNDS)\n\t/* Specific fixes to common fmod() implementation issues:\n\t * - test-bug-mingw-math-issues.js\n\t */\n\tif (DUK_ISINF(d2)) {\n\t\tif (DUK_ISINF(d1)) {\n\t\t\treturn DUK_DOUBLE_NAN;\n\t\t} else {\n\t\t\treturn d1;\n\t\t}\n\t} else if (d1 == 0.0) {\n\t\t/* d1 +/-0 is returned as is (preserving sign) except when\n\t\t * d2 is zero or NaN.\n\t\t */\n\t\tif (d2 == 0.0 || DUK_ISNAN(d2)) {\n\t\t\treturn DUK_DOUBLE_NAN;\n\t\t} else {\n\t\t\treturn d1;\n\t\t}\n\t}\n#else\n\t/* Some ISO C assumptions. */\n\tDUK_ASSERT(DUK_FMOD(1.0, DUK_DOUBLE_INFINITY) == 1.0);\n\tDUK_ASSERT(DUK_FMOD(-1.0, DUK_DOUBLE_INFINITY) == -1.0);\n\tDUK_ASSERT(DUK_FMOD(1.0, -DUK_DOUBLE_INFINITY) == 1.0);\n\tDUK_ASSERT(DUK_FMOD(-1.0, -DUK_DOUBLE_INFINITY) == -1.0);\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_FMOD(0.0, 1.0) == 0.0 && DUK_SIGNBIT(DUK_FMOD(0.0, 1.0)) == 0);\n\tDUK_ASSERT(DUK_FMOD(-0.0, 1.0) == 0.0 && DUK_SIGNBIT(DUK_FMOD(-0.0, 1.0)) != 0);\n\tDUK_ASSERT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY)) == 0);\n\tDUK_ASSERT(DUK_FMOD(-0.0, DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(-0.0, DUK_DOUBLE_INFINITY)) != 0);\n\tDUK_ASSERT(DUK_FMOD(0.0, -DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY)) == 0);\n\tDUK_ASSERT(DUK_FMOD(-0.0, -DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(-0.0, -DUK_DOUBLE_INFINITY)) != 0);\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, 0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, 0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, -0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, -0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, DUK_DOUBLE_NAN)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, DUK_DOUBLE_NAN)));\n#endif\n\n\treturn (duk_double_t) DUK_FMOD((double) d1, (double) d2);\n}\n\n/* Shared helper for Math.pow() and exponentiation operator. */\nDUK_INTERNAL double duk_js_arith_pow(double x, double y) {\n\t/* The ANSI C pow() semantics differ from ECMAScript.\n\t *\n\t * E.g. when x==1 and y is +/- infinite, the ECMAScript required\n\t * result is NaN, while at least Linux pow() returns 1.\n\t */\n\n\tduk_small_int_t cx, cy, sx;\n\n\tDUK_UNREF(cx);\n\tDUK_UNREF(sx);\n\tcy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\n\tif (cy == DUK_FP_NAN) {\n\t\tgoto ret_nan;\n\t}\n\tif (DUK_FABS(x) == 1.0 && cy == DUK_FP_INFINITE) {\n\t\tgoto ret_nan;\n\t}\n\n#if defined(DUK_USE_POW_WORKAROUNDS)\n\t/* Specific fixes to common pow() implementation issues:\n\t *   - test-bug-netbsd-math-pow.js: NetBSD 6.0 on x86 (at least)\n\t *   - test-bug-mingw-math-issues.js\n\t */\n\tcx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (cx == DUK_FP_ZERO && y < 0.0) {\n\t\tsx = (duk_small_int_t) DUK_SIGNBIT(x);\n\t\tif (sx == 0) {\n\t\t\t/* Math.pow(+0,y) should be Infinity when y<0.  NetBSD pow()\n\t\t\t * returns -Infinity instead when y is <0 and finite.  The\n\t\t\t * if-clause also catches y == -Infinity (which works even\n\t\t\t * without the fix).\n\t\t\t */\n\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t} else {\n\t\t\t/* Math.pow(-0,y) where y<0 should be:\n\t\t\t *   - -Infinity if y<0 and an odd integer\n\t\t\t *   - Infinity if y<0 but not an odd integer\n\t\t\t * NetBSD pow() returns -Infinity for all finite y<0.  The\n\t\t\t * if-clause also catches y == -Infinity (which works even\n\t\t\t * without the fix).\n\t\t\t */\n\n\t\t\t/* fmod() return value has same sign as input (negative) so\n\t\t\t * the result here will be in the range ]-2,0], -1 indicates\n\t\t\t * odd.  If x is -Infinity, NaN is returned and the odd check\n\t\t\t * always concludes \"not odd\" which results in desired outcome.\n\t\t\t */\n\t\t\tdouble tmp = DUK_FMOD(y, 2);\n\t\t\tif (tmp == -1.0) {\n\t\t\t\treturn -DUK_DOUBLE_INFINITY;\n\t\t\t} else {\n\t\t\t\t/* Not odd, or y == -Infinity */\n\t\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t\t}\n\t\t}\n\t} else if (cx == DUK_FP_NAN) {\n\t\tif (y == 0.0) {\n\t\t\t/* NaN ** +/- 0 should always be 1, but is NaN on\n\t\t\t * at least some Cygwin/MinGW versions.\n\t\t\t */\n\t\t\treturn 1.0;\n\t\t}\n\t}\n#else\n\t/* Some ISO C assumptions. */\n\tDUK_ASSERT(DUK_POW(DUK_DOUBLE_NAN, 0.0) == 1.0);\n\tDUK_ASSERT(DUK_ISINF(DUK_POW(0.0, -1.0)) && DUK_SIGNBIT(DUK_POW(0.0, -1.0)) == 0);\n\tDUK_ASSERT(DUK_ISINF(DUK_POW(-0.0, -2.0)) && DUK_SIGNBIT(DUK_POW(-0.0, -2.0)) == 0);\n\tDUK_ASSERT(DUK_ISINF(DUK_POW(-0.0, -3.0)) && DUK_SIGNBIT(DUK_POW(-0.0, -3.0)) != 0);\n#endif\n\n\treturn DUK_POW(x, y);\n\n ret_nan:\n\treturn DUK_DOUBLE_NAN;\n}\n#line 1 \"duk_js_call.c\"\n/*\n *  Call handling.\n *\n *  duk_handle_call_unprotected():\n *\n *    - Unprotected call to ECMAScript or Duktape/C function, from native\n *      code or bytecode executor.\n *\n *    - Also handles Ecma-to-Ecma calls which reuses a currently running\n *      executor instance to avoid native recursion.  Call setup is done\n *      normally, but just before calling the bytecode executor a special\n *      return code is used to indicate that a calling executor is reused.\n *\n *    - Also handles tailcalls, i.e. reuse of current duk_activation.\n *\n *    - Also handles setup for initial Duktape.Thread.resume().\n *\n *  duk_handle_safe_call():\n *\n *    - Protected C call within current activation.\n *\n *  setjmp() and local variables have a nasty interaction, see execution.rst;\n *  non-volatile locals modified after setjmp() call are not guaranteed to\n *  keep their value and can cause compiler or compiler version specific\n *  difficult to replicate issues.\n *\n *  See 'execution.rst'.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* XXX: heap->error_not_allowed for success path too? */\n\n/*\n *  Limit check helpers.\n */\n\n/* Check native stack space if DUK_USE_NATIVE_STACK_CHECK() defined. */\nDUK_INTERNAL void duk_native_stack_check(duk_hthread *thr) {\n#if defined(DUK_USE_NATIVE_STACK_CHECK)\n\tif (DUK_USE_NATIVE_STACK_CHECK() != 0) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_NATIVE_STACK_LIMIT);\n\t}\n#else\n\tDUK_UNREF(thr);\n#endif\n}\n\n/* Allow headroom for calls during error augmentation (see GH-191).\n * We allow space for 10 additional recursions, with one extra\n * for, e.g. a print() call at the deepest level, and an extra\n * +1 for protected call wrapping.\n */\n#define DUK__AUGMENT_CALL_RELAX_COUNT  (10 + 2)\n\n/* Stack space required by call handling entry. */\n#define DUK__CALL_HANDLING_REQUIRE_STACK  8\n\nDUK_LOCAL DUK_NOINLINE void duk__call_c_recursion_limit_check_slowpath(duk_hthread *thr) {\n\t/* When augmenting an error, the effective limit is a bit higher.\n\t * Check for it only if the fast path check fails.\n\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tif (thr->heap->augmenting_error) {\n\t\tif (thr->heap->call_recursion_depth < thr->heap->call_recursion_limit + DUK__AUGMENT_CALL_RELAX_COUNT) {\n\t\t\tDUK_D(DUK_DPRINT(\"C recursion limit reached but augmenting error and within relaxed limit\"));\n\t\t\treturn;\n\t\t}\n\t}\n#endif\n\n\tDUK_D(DUK_DPRINT(\"call prevented because C recursion limit reached\"));\n\tDUK_ERROR_RANGE(thr, DUK_STR_NATIVE_STACK_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__call_c_recursion_limit_check(duk_hthread *thr) {\n\tDUK_ASSERT(thr->heap->call_recursion_depth >= 0);\n\tDUK_ASSERT(thr->heap->call_recursion_depth <= thr->heap->call_recursion_limit);\n\n\tduk_native_stack_check(thr);\n\n\t/* This check is forcibly inlined because it's very cheap and almost\n\t * always passes.  The slow path is forcibly noinline.\n\t */\n\tif (DUK_LIKELY(thr->heap->call_recursion_depth < thr->heap->call_recursion_limit)) {\n\t\treturn;\n\t}\n\n\tduk__call_c_recursion_limit_check_slowpath(thr);\n}\n\nDUK_LOCAL DUK_NOINLINE void duk__call_callstack_limit_check_slowpath(duk_hthread *thr) {\n\t/* When augmenting an error, the effective limit is a bit higher.\n\t * Check for it only if the fast path check fails.\n\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tif (thr->heap->augmenting_error) {\n\t\tif (thr->callstack_top < DUK_USE_CALLSTACK_LIMIT + DUK__AUGMENT_CALL_RELAX_COUNT) {\n\t\t\tDUK_D(DUK_DPRINT(\"call stack limit reached but augmenting error and within relaxed limit\"));\n\t\t\treturn;\n\t\t}\n\t}\n#endif\n\n\t/* XXX: error message is a bit misleading: we reached a recursion\n\t * limit which is also essentially the same as a C callstack limit\n\t * (except perhaps with some relaxed threading assumptions).\n\t */\n\tDUK_D(DUK_DPRINT(\"call prevented because call stack limit reached\"));\n\tDUK_ERROR_RANGE(thr, DUK_STR_CALLSTACK_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__call_callstack_limit_check(duk_hthread *thr) {\n\t/* This check is forcibly inlined because it's very cheap and almost\n\t * always passes.  The slow path is forcibly noinline.\n\t */\n\tif (DUK_LIKELY(thr->callstack_top < DUK_USE_CALLSTACK_LIMIT)) {\n\t\treturn;\n\t}\n\n\tduk__call_callstack_limit_check_slowpath(thr);\n}\n\n/*\n *  Interrupt counter fixup (for development only).\n */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__interrupt_fixup(duk_hthread *thr, duk_hthread *entry_curr_thread) {\n\t/* Currently the bytecode executor and executor interrupt\n\t * instruction counts are off because we don't execute the\n\t * interrupt handler when we're about to exit from the initial\n\t * user call into Duktape.\n\t *\n\t * If we were to execute the interrupt handler here, the counts\n\t * would match.  You can enable this block manually to check\n\t * that this is the case.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n#if defined(DUK_USE_INTERRUPT_DEBUG_FIXUP)\n\tif (entry_curr_thread == NULL) {\n\t\tthr->interrupt_init = thr->interrupt_init - thr->interrupt_counter;\n\t\tthr->heap->inst_count_interrupt += thr->interrupt_init;\n\t\tDUK_DD(DUK_DDPRINT(\"debug test: updated interrupt count on exit to \"\n\t\t                   \"user code, instruction counts: executor=%ld, interrupt=%ld\",\n\t\t                   (long) thr->heap->inst_count_exec, (long) thr->heap->inst_count_interrupt));\n\t\tDUK_ASSERT(thr->heap->inst_count_exec == thr->heap->inst_count_interrupt);\n\t}\n#else\n\tDUK_UNREF(thr);\n\tDUK_UNREF(entry_curr_thread);\n#endif\n}\n#endif\n\n/*\n *  Arguments object creation.\n *\n *  Creating arguments objects involves many small details, see E5 Section\n *  10.6 for the specific requirements.  Much of the arguments object exotic\n *  behavior is implemented in duk_hobject_props.c, and is enabled by the\n *  object flag DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS.\n */\n\nDUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,\n                                            duk_hobject *func,\n                                            duk_hobject *varenv,\n                                            duk_idx_t idx_args) {\n\tduk_hobject *arg;          /* 'arguments' */\n\tduk_hobject *formals;      /* formals for 'func' (may be NULL if func is a C function) */\n\tduk_idx_t i_arg;\n\tduk_idx_t i_map;\n\tduk_idx_t i_mappednames;\n\tduk_idx_t i_formals;\n\tduk_idx_t i_argbase;\n\tduk_idx_t n_formals;\n\tduk_idx_t idx;\n\tduk_idx_t num_stack_args;\n\tduk_bool_t need_map;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_NONBOUND_FUNCTION(func));\n\tDUK_ASSERT(varenv != NULL);\n\n\t/* [ ... func this arg1(@idx_args) ... argN envobj ]\n\t * [ arg1(@idx_args) ... argN envobj ] (for tailcalls)\n\t */\n\n\tneed_map = 0;\n\n\ti_argbase = idx_args;\n\tnum_stack_args = duk_get_top(thr) - i_argbase - 1;\n\tDUK_ASSERT(i_argbase >= 0);\n\tDUK_ASSERT(num_stack_args >= 0);\n\n\tformals = (duk_hobject *) duk_hobject_get_formals(thr, (duk_hobject *) func);\n\tif (formals) {\n\t\tn_formals = (duk_idx_t) ((duk_harray *) formals)->length;\n\t\tduk_push_hobject(thr, formals);\n\t} else {\n\t\t/* This shouldn't happen without tampering of internal\n\t\t * properties: if a function accesses 'arguments', _Formals\n\t\t * is kept.  Check for the case anyway in case internal\n\t\t * properties have been modified manually.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"_Formals is undefined when creating arguments, use n_formals == 0\"));\n\t\tn_formals = 0;\n\t\tduk_push_undefined(thr);\n\t}\n\ti_formals = duk_require_top_index(thr);\n\n\tDUK_ASSERT(n_formals >= 0);\n\tDUK_ASSERT(formals != NULL || n_formals == 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"func=%!O, formals=%!O, n_formals=%ld\",\n\t                     (duk_heaphdr *) func, (duk_heaphdr *) formals,\n\t                     (long) n_formals));\n\n\t/* [ ... formals ] */\n\n\t/*\n\t *  Create required objects:\n\t *    - 'arguments' object: array-like, but not an array\n\t *    - 'map' object: internal object, tied to 'arguments' (bare)\n\t *    - 'mappedNames' object: temporary value used during construction (bare)\n\t */\n\n\targ = duk_push_object_helper(thr,\n\t                             DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                             DUK_HOBJECT_FLAG_FASTREFS |\n\t                             DUK_HOBJECT_FLAG_ARRAY_PART |\n\t                             DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARGUMENTS),\n\t                             DUK_BIDX_OBJECT_PROTOTYPE);\n\tDUK_ASSERT(arg != NULL);\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              -1);  /* no prototype */\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              -1);  /* no prototype */\n\ti_arg = duk_get_top(thr) - 3;\n\ti_map = i_arg + 1;\n\ti_mappednames = i_arg + 2;\n\tDUK_ASSERT(!duk_is_bare_object(thr, -3));  /* arguments */\n\tDUK_ASSERT(duk_is_bare_object(thr, -2));  /* map */\n\tDUK_ASSERT(duk_is_bare_object(thr, -1));  /* mappedNames */\n\n\t/* [ ... formals arguments map mappedNames ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"created arguments related objects: \"\n\t                     \"arguments at index %ld -> %!O \"\n\t                     \"map at index %ld -> %!O \"\n\t                     \"mappednames at index %ld -> %!O\",\n\t                     (long) i_arg, (duk_heaphdr *) duk_get_hobject(thr, i_arg),\n\t                     (long) i_map, (duk_heaphdr *) duk_get_hobject(thr, i_map),\n\t                     (long) i_mappednames, (duk_heaphdr *) duk_get_hobject(thr, i_mappednames)));\n\n\t/*\n\t *  Init arguments properties, map, etc.\n\t */\n\n\tduk_push_int(thr, num_stack_args);\n\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_WC);\n\n\t/*\n\t *  Init argument related properties.\n\t */\n\n\t/* step 11 */\n\tidx = num_stack_args - 1;\n\twhile (idx >= 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arg idx %ld, argbase=%ld, argidx=%ld\",\n\t\t                     (long) idx, (long) i_argbase, (long) (i_argbase + idx)));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"define arguments[%ld]=arg\", (long) idx));\n\t\tduk_dup(thr, i_argbase + idx);\n\t\tduk_xdef_prop_index_wec(thr, i_arg, (duk_uarridx_t) idx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"defined arguments[%ld]=arg\", (long) idx));\n\n\t\t/* step 11.c is relevant only if non-strict (checked in 11.c.ii) */\n\t\tif (!DUK_HOBJECT_HAS_STRICT(func) && idx < n_formals) {\n\t\t\tDUK_ASSERT(formals != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"strict function, index within formals (%ld < %ld)\",\n\t\t\t                     (long) idx, (long) n_formals));\n\n\t\t\tduk_get_prop_index(thr, i_formals, (duk_uarridx_t) idx);\n\t\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\n\t\t\tduk_dup_top(thr);  /* [ ... name name ] */\n\n\t\t\tif (!duk_has_prop(thr, i_mappednames)) {\n\t\t\t\t/* steps 11.c.ii.1 - 11.c.ii.4, but our internal book-keeping\n\t\t\t\t * differs from the reference model\n\t\t\t\t */\n\n\t\t\t\t/* [ ... name ] */\n\n\t\t\t\tneed_map = 1;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"set mappednames[%s]=%ld\",\n\t\t\t\t                     (const char *) duk_get_string(thr, -1),\n\t\t\t\t                     (long) idx));\n\t\t\t\tduk_dup_top(thr);                      /* name */\n\t\t\t\t(void) duk_push_uint_to_hstring(thr, (duk_uint_t) idx);  /* index */\n\t\t\t\tduk_xdef_prop_wec(thr, i_mappednames);  /* out of spec, must be configurable */\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"set map[%ld]=%s\",\n\t\t\t\t                     (long) idx,\n\t\t\t\t                     duk_get_string(thr, -1)));\n\t\t\t\tduk_dup_top(thr);         /* name */\n\t\t\t\tduk_xdef_prop_index_wec(thr, i_map, (duk_uarridx_t) idx);  /* out of spec, must be configurable */\n\t\t\t} else {\n\t\t\t\t/* duk_has_prop() popped the second 'name' */\n\t\t\t}\n\n\t\t\t/* [ ... name ] */\n\t\t\tduk_pop(thr);  /* pop 'name' */\n\t\t}\n\n\t\tidx--;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"actual arguments processed\"));\n\n\t/* step 12 */\n\tif (need_map) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"adding 'map' and 'varenv' to arguments object\"));\n\n\t\t/* should never happen for a strict callee */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(func));\n\n\t\tduk_dup(thr, i_map);\n\t\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_INT_MAP, DUK_PROPDESC_FLAGS_NONE);  /* out of spec, don't care */\n\n\t\t/* The variable environment for magic variable bindings needs to be\n\t\t * given by the caller and recorded in the arguments object.\n\t\t *\n\t\t * See E5 Section 10.6, the creation of setters/getters.\n\t\t *\n\t\t * The variable environment also provides access to the callee, so\n\t\t * an explicit (internal) callee property is not needed.\n\t\t */\n\n\t\tduk_push_hobject(thr, varenv);\n\t\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_INT_VARENV, DUK_PROPDESC_FLAGS_NONE);  /* out of spec, don't care */\n\t}\n\n\t/* steps 13-14 */\n\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t/* Callee/caller are throwers and are not deletable etc.  They\n\t\t * could be implemented as virtual properties, but currently\n\t\t * there is no support for virtual properties which are accessors\n\t\t * (only plain virtual properties).  This would not be difficult\n\t\t * to change in duk_hobject_props, but we can make the throwers\n\t\t * normal, concrete properties just as easily.\n\t\t *\n\t\t * Note that the specification requires that the *same* thrower\n\t\t * built-in object is used here!  See E5 Section 10.6 main\n\t\t * algoritm, step 14, and Section 13.2.3 which describes the\n\t\t * thrower.  See test case test-arguments-throwers.js.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"strict function, setting caller/callee to throwers\"));\n\n\t\t/* In ES2017 .caller is no longer set at all. */\n\t\tduk_xdef_prop_stridx_thrower(thr, i_arg, DUK_STRIDX_CALLEE);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-strict function, setting callee to actual value\"));\n\t\tduk_push_hobject(thr, func);\n\t\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_CALLEE, DUK_PROPDESC_FLAGS_WC);\n\t}\n\n\t/* set exotic behavior only after we're done */\n\tif (need_map) {\n\t\t/* Exotic behaviors are only enabled for arguments objects\n\t\t * which have a parameter map (see E5 Section 10.6 main\n\t\t * algorithm, step 12).\n\t\t *\n\t\t * In particular, a non-strict arguments object with no\n\t\t * mapped formals does *NOT* get exotic behavior, even\n\t\t * for e.g. \"caller\" property.  This seems counterintuitive\n\t\t * but seems to be the case.\n\t\t */\n\n\t\t/* cannot be strict (never mapped variables) */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(func));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"enabling exotic behavior for arguments object\"));\n\t\tDUK_HOBJECT_SET_EXOTIC_ARGUMENTS(arg);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"not enabling exotic behavior for arguments object\"));\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"final arguments related objects: \"\n\t                     \"arguments at index %ld -> %!O \"\n\t                     \"map at index %ld -> %!O \"\n\t                     \"mappednames at index %ld -> %!O\",\n\t                     (long) i_arg, (duk_heaphdr *) duk_get_hobject(thr, i_arg),\n\t                     (long) i_map, (duk_heaphdr *) duk_get_hobject(thr, i_map),\n\t                     (long) i_mappednames, (duk_heaphdr *) duk_get_hobject(thr, i_mappednames)));\n\n\t/* [ args(n) envobj formals arguments map mappednames ] */\n\n\tduk_pop_2(thr);\n\tduk_remove_m2(thr);\n\n\t/* [ args(n) envobj arguments ] */\n}\n\n/* Helper for creating the arguments object and adding it to the env record\n * on top of the value stack.\n */\nDUK_LOCAL void duk__handle_createargs_for_call(duk_hthread *thr,\n                                               duk_hobject *func,\n                                               duk_hobject *env,\n                                               duk_idx_t idx_args) {\n\tDUK_DDD(DUK_DDDPRINT(\"creating arguments object for function call\"));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_CREATEARGS(func));\n\n\t/* [ ... arg1 ... argN envobj ] */\n\n\tduk__create_arguments_object(thr,\n\t                             func,\n\t                             env,\n\t                             idx_args);\n\n\t/* [ ... arg1 ... argN envobj argobj ] */\n\n\tduk_xdef_prop_stridx_short(thr,\n\t                           -2,\n\t                           DUK_STRIDX_LC_ARGUMENTS,\n\t                           DUK_HOBJECT_HAS_STRICT(func) ? DUK_PROPDESC_FLAGS_E :   /* strict: non-deletable, non-writable */\n\t                                                          DUK_PROPDESC_FLAGS_WE);  /* non-strict: non-deletable, writable */\n\t/* [ ... arg1 ... argN envobj ] */\n}\n\n/*\n *  Helpers for constructor call handling.\n *\n *  There are two [[Construct]] operations in the specification:\n *\n *    - E5 Section 13.2.2: for Function objects\n *    - E5 Section 15.3.4.5.2: for \"bound\" Function objects\n *\n *  The chain of bound functions is resolved in Section 15.3.4.5.2,\n *  with arguments \"piling up\" until the [[Construct]] internal\n *  method is called on the final, actual Function object.  Note\n *  that the \"prototype\" property is looked up *only* from the\n *  final object, *before* calling the constructor.\n *\n *  Since Duktape 2.2 bound functions are represented with the\n *  duk_hboundfunc internal type, and bound function chains are\n *  collapsed when a bound function is created.  As a result, the\n *  direct target of a duk_hboundfunc is always non-bound and the\n *  this/argument lists have been resolved.\n *\n *  When constructing new Array instances, an unnecessary object is\n *  created and discarded now: the standard [[Construct]] creates an\n *  object, and calls the Array constructor.  The Array constructor\n *  returns an Array instance, which is used as the result value for\n *  the \"new\" operation; the object created before the Array constructor\n *  call is discarded.\n *\n *  This would be easy to fix, e.g. by knowing that the Array constructor\n *  will always create a replacement object and skip creating the fallback\n *  object in that case.\n */\n\n/* Update default instance prototype for constructor call. */\nDUK_LOCAL void duk__update_default_instance_proto(duk_hthread *thr, duk_idx_t idx_func) {\n\tduk_hobject *proto;\n\tduk_hobject *fallback;\n\n\tDUK_ASSERT(duk_is_constructable(thr, idx_func));\n\n\tduk_get_prop_stridx_short(thr, idx_func, DUK_STRIDX_PROTOTYPE);\n\tproto = duk_get_hobject(thr, -1);\n\tif (proto == NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"constructor has no 'prototype' property, or value not an object \"\n\t\t                     \"-> leave standard Object prototype as fallback prototype\"));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"constructor has 'prototype' property with object value \"\n\t\t                     \"-> set fallback prototype to that value: %!iO\", (duk_heaphdr *) proto));\n\t\t/* Original fallback (default instance) is untouched when\n\t\t * resolving bound functions etc.\n\t\t */\n\t\tfallback = duk_known_hobject(thr, idx_func + 1);\n\t\tDUK_ASSERT(fallback != NULL);\n\t\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, fallback, proto);\n\t}\n\tduk_pop(thr);\n}\n\n/* Postprocess: return value special handling, error augmentation. */\nDUK_INTERNAL void duk_call_construct_postprocess(duk_hthread *thr, duk_small_uint_t proxy_invariant) {\n\t/* Use either fallback (default instance) or retval depending\n\t * on retval type.  Needs to be called before unwind because\n\t * the default instance is read from the current (immutable)\n\t * 'this' binding.\n\t *\n\t * For Proxy 'construct' calls the return value must be an\n\t * Object (we accept object-like values like buffers and\n\t * lightfuncs too).  If not, TypeError.\n\t */\n\tif (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT |\n\t                                 DUK_TYPE_MASK_BUFFER |\n\t                                 DUK_TYPE_MASK_LIGHTFUNC)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"replacement value\"));\n\t} else {\n\t\tif (DUK_UNLIKELY(proxy_invariant != 0U)) {\n\t\t\t/* Proxy 'construct' return value invariant violated. */\n\t\t\tDUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\t/* XXX: direct value stack access */\n\t\tduk_pop(thr);\n\t\tduk_push_this(thr);\n\t}\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\t/* Augment created errors upon creation, not when they are thrown or\n\t * rethrown.  __FILE__ and __LINE__ are not desirable here; the call\n\t * stack reflects the caller which is correct.  Skip topmost, unwound\n\t * activation when creating a traceback.  If thr->ptr_curr_pc was !=\n\t * NULL we'd need to sync the current PC so that the traceback comes\n\t * out right; however it is always synced here so just assert for it.\n\t */\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\tduk_err_augment_error_create(thr, thr, NULL, 0, DUK_AUGMENT_FLAG_NOBLAME_FILELINE |\n\t                                                DUK_AUGMENT_FLAG_SKIP_ONE);\n#endif\n}\n\n/*\n *  Helper for handling a bound function when a call is being made.\n *\n *  Assumes that bound function chains have been \"collapsed\" so that either\n *  the target is non-bound or there is one bound function that points to a\n *  nonbound target.\n *\n *  Prepends the bound arguments to the value stack (at idx_func + 2).\n *  The 'this' binding is also updated if necessary (at idx_func + 1).\n *  Note that for constructor calls the 'this' binding is never updated by\n *  [[BoundThis]].\n */\n\nDUK_LOCAL void duk__handle_bound_chain_for_call(duk_hthread *thr,\n                                                duk_idx_t idx_func,\n                                                duk_bool_t is_constructor_call) {\n\tduk_tval *tv_func;\n\tduk_hobject *func;\n\tduk_idx_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* On entry, item at idx_func is a bound, non-lightweight function,\n\t * but we don't rely on that below.\n\t */\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\ttv_func = duk_require_tval(thr, idx_func);\n\tDUK_ASSERT(tv_func != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\n\t\t/* XXX: separate helper function, out of fast path? */\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {\n\t\t\tduk_hboundfunc *h_bound;\n\t\t\tduk_tval *tv_args;\n\t\t\tduk_tval *tv_gap;\n\n\t\t\th_bound = (duk_hboundfunc *) (void *) func;\n\t\t\ttv_args = h_bound->args;\n\t\t\tlen = h_bound->nargs;\n\t\t\tDUK_ASSERT(len == 0 || tv_args != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"bound function encountered, ptr=%p: %!T\",\n\t\t\t                     (void *) DUK_TVAL_GET_OBJECT(tv_func), tv_func));\n\n\t\t\t/* [ ... func this arg1 ... argN ] */\n\n\t\t\tif (is_constructor_call) {\n\t\t\t\t/* See: tests/ecmascript/test-spec-bound-constructor.js */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"constructor call: don't update this binding\"));\n\t\t\t} else {\n\t\t\t\t/* XXX: duk_replace_tval */\n\t\t\t\tduk_push_tval(thr, &h_bound->this_binding);\n\t\t\t\tduk_replace(thr, idx_func + 1);  /* idx_this = idx_func + 1 */\n\t\t\t}\n\n\t\t\t/* [ ... func this arg1 ... argN ] */\n\n\t\t\tduk_require_stack(thr, len);\n\n\t\t\ttv_gap = duk_reserve_gap(thr, idx_func + 2, len);\n\t\t\tduk_copy_tvals_incref(thr, tv_gap, tv_args, (duk_size_t) len);\n\n\t\t\t/* [ ... func this <bound args> arg1 ... argN ] */\n\n\t\t\tduk_push_tval(thr, &h_bound->target);\n\t\t\tduk_replace(thr, idx_func);  /* replace in stack */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"bound function handled, idx_func=%ld, curr func=%!T\",\n\t\t\t                     (long) idx_func, duk_get_tval(thr, idx_func)));\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {\n\t\t/* Lightweight function: never bound, so terminate. */\n\t\t;\n\t} else {\n\t\t/* Shouldn't happen, so ugly error is enough. */\n\t\tDUK_ERROR_INTERNAL(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\tDUK_DDD(DUK_DDDPRINT(\"final non-bound function is: %!T\", duk_get_tval(thr, idx_func)));\n\n#if defined(DUK_USE_ASSERTIONS)\n\ttv_func = duk_require_tval(thr, idx_func);\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func) || DUK_TVAL_IS_OBJECT(tv_func));\n\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func) ||\n\t\t           DUK_HOBJECT_HAS_NATFUNC(func) ||\n\t\t           DUK_HOBJECT_IS_PROXY(func));\n\t}\n#endif\n}\n\n/*\n *  Helper for inline handling of .call(), .apply(), and .construct().\n */\n\nDUK_LOCAL duk_bool_t duk__handle_specialfuncs_for_call(duk_hthread *thr, duk_idx_t idx_func, duk_hobject *func, duk_small_uint_t *call_flags, duk_bool_t first) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_c_function natfunc;\n#endif\n\tduk_tval *tv_args;\n\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT((*call_flags & DUK_CALL_FLAG_CONSTRUCT) == 0);  /* Caller. */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tnatfunc = ((duk_hnatfunc *) func)->func;\n\tDUK_ASSERT(natfunc != NULL);\n#endif\n\n\t/* On every round of function resolution at least target function and\n\t * 'this' binding are set.  We can assume that here, and must guarantee\n\t * it on exit.  Value stack reserve is extended for bound function and\n\t * .apply() unpacking so we don't need to extend it here when we need a\n\t * few slots.\n\t */\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\t/* Handle native 'eval' specially.  A direct eval check is only made\n\t * for the first resolution attempt; e.g. a bound eval call is -not-\n\t * a direct eval call.\n\t */\n\tif (DUK_UNLIKELY(((duk_hnatfunc *) func)->magic == 15)) {\n\t\t/* For now no special handling except for direct eval\n\t\t * detection.\n\t\t */\n\t\tDUK_ASSERT(((duk_hnatfunc *) func)->func == duk_bi_global_object_eval);\n\t\tif (first && (*call_flags & DUK_CALL_FLAG_CALLED_AS_EVAL)) {\n\t\t\t*call_flags = (*call_flags & ~DUK_CALL_FLAG_CALLED_AS_EVAL) | DUK_CALL_FLAG_DIRECT_EVAL;\n\t\t}\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\t\treturn 1;  /* stop resolving */\n\t}\n\n\t/* Handle special functions based on the DUK_HOBJECT_FLAG_SPECIAL_CALL\n\t * flag; their magic value is used for switch-case.\n\t *\n\t * NOTE: duk_unpack_array_like() reserves value stack space\n\t * for the result values (unlike most other value stack calls).\n\t */\n\tswitch (((duk_hnatfunc *) func)->magic) {\n\tcase 0: {  /* 0=Function.prototype.call() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Function.prototype.call()  [removed]\n\t\t * idx_func + 1: this binding for .call (target function)\n\t\t * idx_func + 2: 1st argument to .call, desired 'this' binding\n\t\t * idx_func + 3: 2nd argument to .call, desired 1st argument for ultimate target\n\t\t * ...\n\t\t *\n\t\t * Remove idx_func + 0 to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding\n\t\t * idx_func + 2: call arguments\n\t\t * ...\n\t\t */\n\t\tDUK_ASSERT(natfunc == duk_bi_function_prototype_call);\n\t\tduk_remove_unsafe(thr, idx_func);\n\t\ttv_args = thr->valstack_bottom + idx_func + 2;\n\t\tif (thr->valstack_top < tv_args) {\n\t\t\tDUK_ASSERT(tv_args <= thr->valstack_end);\n\t\t\tthr->valstack_top = tv_args;  /* at least target function and 'this' binding present */\n\t\t}\n\t\tbreak;\n\t}\n\tcase 1: {  /* 1=Function.prototype.apply() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Function.prototype.apply()  [removed]\n\t\t * idx_func + 1: this binding for .apply (target function)\n\t\t * idx_func + 2: 1st argument to .apply, desired 'this' binding\n\t\t * idx_func + 3: 2nd argument to .apply, argArray\n\t\t * [anything after this MUST be ignored]\n\t\t *\n\t\t * Remove idx_func + 0 and unpack the argArray to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding\n\t\t * idx_func + 2: call arguments\n\t\t * ...\n\t\t */\n\t\tDUK_ASSERT(natfunc == duk_bi_function_prototype_apply);\n\t\tduk_remove_unsafe(thr, idx_func);\n\t\tgoto apply_shared;\n\t}\n#if defined(DUK_USE_REFLECT_BUILTIN)\n\tcase 2: {  /* 2=Reflect.apply() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Reflect.apply()  [removed]\n\t\t * idx_func + 1: this binding for .apply (ignored, usually Reflect)  [removed]\n\t\t * idx_func + 2: 1st argument to .apply, target function\n\t\t * idx_func + 3: 2nd argument to .apply, desired 'this' binding\n\t\t * idx_func + 4: 3rd argument to .apply, argArray\n\t\t * [anything after this MUST be ignored]\n\t\t *\n\t\t * Remove idx_func + 0 and idx_func + 1, and unpack the argArray to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding\n\t\t * idx_func + 2: call arguments\n\t\t * ...\n\t\t */\n\t\tDUK_ASSERT(natfunc == duk_bi_reflect_apply);\n\t\tduk_remove_n_unsafe(thr, idx_func, 2);\n\t\tgoto apply_shared;\n\t}\n\tcase 3: {  /* 3=Reflect.construct() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Reflect.construct()  [removed]\n\t\t * idx_func + 1: this binding for .construct (ignored, usually Reflect)  [removed]\n\t\t * idx_func + 2: 1st argument to .construct, target function\n\t\t * idx_func + 3: 2nd argument to .construct, argArray\n\t\t * idx_func + 4: 3rd argument to .construct, newTarget\n\t\t * [anything after this MUST be ignored]\n\t\t *\n\t\t * Remove idx_func + 0 and idx_func + 1, unpack the argArray,\n\t\t * and insert default instance (prototype not yet updated), to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding (default instance)\n\t\t * idx_func + 2: constructor call arguments\n\t\t * ...\n\t\t *\n\t\t * Call flags must be updated to reflect the fact that we're\n\t\t * now dealing with a constructor call, and e.g. the 'this'\n\t\t * binding cannot be overwritten if the target is bound.\n\t\t *\n\t\t * newTarget is checked but not yet passed onwards.\n\t\t */\n\n\t\tduk_idx_t top;\n\n\t\tDUK_ASSERT(natfunc == duk_bi_reflect_construct);\n\t\t*call_flags |= DUK_CALL_FLAG_CONSTRUCT;\n\t\tduk_remove_n_unsafe(thr, idx_func, 2);\n\t\ttop = duk_get_top(thr);\n\t\tif (!duk_is_constructable(thr, idx_func)) {\n\t\t\t/* Target constructability must be checked before\n\t\t\t * unpacking argArray (which may cause side effects).\n\t\t\t * Just return; caller will throw the error.\n\t\t\t */\n\t\t\tduk_set_top_unsafe(thr, idx_func + 2);  /* satisfy asserts */\n\t\t\tbreak;\n\t\t}\n\t\tduk_push_object(thr);\n\t\tduk_insert(thr, idx_func + 1);  /* default instance */\n\n\t\t/* [ ... func default_instance argArray newTarget? ] */\n\n\t\ttop = duk_get_top(thr);\n\t\tif (top < idx_func + 3) {\n\t\t\t/* argArray is a mandatory argument for Reflect.construct(). */\n\t\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tif (top > idx_func + 3) {\n\t\t\tif (!duk_strict_equals(thr, idx_func, idx_func + 3)) {\n\t\t\t\t/* XXX: [[Construct]] newTarget currently unsupported */\n\t\t\t\tDUK_ERROR_UNSUPPORTED(thr);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t\tduk_set_top_unsafe(thr, idx_func + 3);  /* remove any args beyond argArray */\n\t\t}\n\t\tDUK_ASSERT(duk_get_top(thr) == idx_func + 3);\n\t\tDUK_ASSERT(duk_is_valid_index(thr, idx_func + 2));\n\t\t(void) duk_unpack_array_like(thr, idx_func + 2);  /* XXX: should also remove target to be symmetric with duk_pack()? */\n\t\tduk_remove(thr, idx_func + 2);\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\t\tbreak;\n\t}\n#endif  /* DUK_USE_REFLECT_BUILTIN */\n\tdefault: {\n\t\tDUK_ASSERT(0);\n\t\tDUK_UNREACHABLE();\n\t}\n\t}\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\treturn 0;  /* keep resolving */\n\n apply_shared:\n\ttv_args = thr->valstack_bottom + idx_func + 2;\n\tif (thr->valstack_top <= tv_args) {\n\t\tDUK_ASSERT(tv_args <= thr->valstack_end);\n\t\tthr->valstack_top = tv_args;  /* at least target func and 'this' binding present */\n\t\t/* No need to check for argArray. */\n\t} else {\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 3);  /* idx_func + 2 covered above */\n\t\tif (thr->valstack_top > tv_args + 1) {\n\t\t\tduk_set_top_unsafe(thr, idx_func + 3);  /* remove any args beyond argArray */\n\t\t}\n\t\tDUK_ASSERT(duk_is_valid_index(thr, idx_func + 2));\n\t\tif (!duk_is_callable(thr, idx_func)) {\n\t\t\t/* Avoid unpack side effects if the target isn't callable.\n\t\t\t * Calling code will throw the actual error.\n\t\t\t */\n\t\t} else {\n\t\t\t(void) duk_unpack_array_like(thr, idx_func + 2);\n\t\t\tduk_remove(thr, idx_func + 2);\n\t\t}\n\t}\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\treturn 0;  /* keep resolving */\n}\n\n/*\n *  Helper for Proxy handling.\n */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_LOCAL void duk__handle_proxy_for_call(duk_hthread *thr, duk_idx_t idx_func, duk_hproxy *h_proxy, duk_small_uint_t *call_flags) {\n\tduk_bool_t rc;\n\n\t/* Value stack:\n\t * idx_func + 0: Proxy object\n\t * idx_func + 1: this binding for call\n\t * idx_func + 2: 1st argument for call\n\t * idx_func + 3: 2nd argument for call\n\t * ...\n\t *\n\t * If Proxy doesn't have a trap for the call ('apply' or 'construct'),\n\t * replace Proxy object with target object.\n\t *\n\t * If we're dealing with a normal call and the Proxy has an 'apply'\n\t * trap, manipulate value stack to:\n\t *\n\t * idx_func + 0: trap\n\t * idx_func + 1: Proxy's handler\n\t * idx_func + 2: Proxy's target\n\t * idx_func + 3: this binding for call (from idx_func + 1)\n\t * idx_func + 4: call arguments packed to an array\n\t *\n\t * If we're dealing with a constructor call and the Proxy has a\n\t * 'construct' trap, manipulate value stack to:\n\t *\n\t * idx_func + 0: trap\n\t * idx_func + 1: Proxy's handler\n\t * idx_func + 2: Proxy's target\n\t * idx_func + 3: call arguments packed to an array\n\t * idx_func + 4: newTarget == Proxy object here\n\t *\n\t * As we don't yet have proper newTarget support, the newTarget at\n\t * idx_func + 3 is just the original constructor being called, i.e.\n\t * the Proxy object (not the target).  Note that the default instance\n\t * (original 'this' binding) is dropped and ignored.\n\t */\n\n\tduk_push_hobject(thr, h_proxy->handler);\n\trc = duk_get_prop_stridx_short(thr, -1, (*call_flags & DUK_CALL_FLAG_CONSTRUCT) ? DUK_STRIDX_CONSTRUCT : DUK_STRIDX_APPLY);\n\tif (rc == 0) {\n\t\t/* Not found, continue to target.  If this is a construct\n\t\t * call, update default instance prototype using the Proxy,\n\t\t * not the target.\n\t\t */\n\t\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\t\tif (!(*call_flags & DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED)) {\n\t\t\t\t*call_flags |= DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED;\n\t\t\t\tduk__update_default_instance_proto(thr, idx_func);\n\t\t\t}\n\t\t}\n\t\tduk_pop_2(thr);\n\t\tduk_push_hobject(thr, h_proxy->target);\n\t\tduk_replace(thr, idx_func);\n\t\treturn;\n\t}\n\n\t/* Here we must be careful not to replace idx_func while\n\t * h_proxy is still needed, otherwise h_proxy may become\n\t * dangling.  This could be improved e.g. using a\n\t * duk_pack_slice() with a freeform slice.\n\t */\n\n\t/* Here:\n\t * idx_func + 0: Proxy object\n\t * idx_func + 1: this binding for call\n\t * idx_func + 2: 1st argument for call\n\t * idx_func + 3: 2nd argument for call\n\t * ...\n\t * idx_func + N: handler\n\t * idx_func + N + 1: trap\n\t */\n\n\tduk_insert(thr, idx_func + 1);\n\tduk_insert(thr, idx_func + 2);\n\tduk_push_hobject(thr, h_proxy->target);\n\tduk_insert(thr, idx_func + 3);\n\tduk_pack(thr, duk_get_top(thr) - (idx_func + 5));\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\t/* Here:\n\t * idx_func + 0: Proxy object\n\t * idx_func + 1: trap\n\t * idx_func + 2: Proxy's handler\n\t * idx_func + 3: Proxy's target\n\t * idx_func + 4: this binding for call\n\t * idx_func + 5: arguments array\n\t */\n\tDUK_ASSERT(duk_get_top(thr) == idx_func + 6);\n\n\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\t*call_flags |= DUK_CALL_FLAG_CONSTRUCT_PROXY;  /* Enable 'construct' trap return invariant check. */\n\t\t*call_flags &= ~(DUK_CALL_FLAG_CONSTRUCT);     /* Resume as non-constructor call to the trap. */\n\n\t\t/* 'apply' args: target, thisArg, argArray\n\t\t * 'construct' args: target, argArray, newTarget\n\t\t */\n\t\tduk_remove(thr, idx_func + 4);\n\t\tduk_push_hobject(thr, (duk_hobject *) h_proxy);\n\t}\n\n\t/* Finalize value stack layout by removing Proxy reference. */\n\tduk_remove(thr, idx_func);\n\th_proxy = NULL;  /* invalidated */\n\tDUK_ASSERT(duk_get_top(thr) == idx_func + 5);\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n/*\n *  Helper for setting up var_env and lex_env of an activation,\n *  assuming it does NOT have the DUK_HOBJECT_FLAG_NEWENV flag.\n */\n\nDUK_LOCAL void duk__handle_oldenv_for_call(duk_hthread *thr,\n                                           duk_hobject *func,\n                                           duk_activation *act) {\n\tduk_hcompfunc *f;\n\tduk_hobject *h_lex;\n\tduk_hobject *h_var;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV(func));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(func));\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(func));\n\tDUK_UNREF(thr);\n\n\tf = (duk_hcompfunc *) func;\n\th_lex = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f);\n\th_var = DUK_HCOMPFUNC_GET_VARENV(thr->heap, f);\n\tDUK_ASSERT(h_lex != NULL);  /* Always true for closures (not for templates) */\n\tDUK_ASSERT(h_var != NULL);\n\tact->lex_env = h_lex;\n\tact->var_env = h_var;\n\tDUK_HOBJECT_INCREF(thr, h_lex);\n\tDUK_HOBJECT_INCREF(thr, h_var);\n}\n\n/*\n *  Helper for updating callee 'caller' property.\n */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\nDUK_LOCAL void duk__update_func_caller_prop(duk_hthread *thr, duk_hobject *func) {\n\tduk_tval *tv_caller;\n\tduk_hobject *h_tmp;\n\tduk_activation *act_callee;\n\tduk_activation *act_caller;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));  /* bound chain resolved */\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\n\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t/* Strict functions don't get their 'caller' updated. */\n\t\treturn;\n\t}\n\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tact_callee = thr->callstack_curr;\n\tDUK_ASSERT(act_callee != NULL);\n\tact_caller = (thr->callstack_top >= 2 ? act_callee->parent : NULL);\n\n\t/* XXX: check .caller writability? */\n\n\t/* Backup 'caller' property and update its value. */\n\ttv_caller = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, func, DUK_STRIDX_CALLER);\n\tif (tv_caller) {\n\t\t/* If caller is global/eval code, 'caller' should be set to\n\t\t * 'null'.\n\t\t *\n\t\t * XXX: there is no exotic flag to infer this correctly now.\n\t\t * The NEWENV flag is used now which works as intended for\n\t\t * everything (global code, non-strict eval code, and functions)\n\t\t * except strict eval code.  Bound functions are never an issue\n\t\t * because 'func' has been resolved to a non-bound function.\n\t\t */\n\n\t\tif (act_caller != NULL) {\n\t\t\t/* act_caller->func may be NULL in some finalization cases,\n\t\t\t * just treat like we don't know the caller.\n\t\t\t */\n\t\t\tif (act_caller->func && !DUK_HOBJECT_HAS_NEWENV(act_caller->func)) {\n\t\t\t\t/* Setting to NULL causes 'caller' to be set to\n\t\t\t\t * 'null' as desired.\n\t\t\t\t */\n\t\t\t\tact_caller = NULL;\n\t\t\t}\n\t\t}\n\n\t\tif (DUK_TVAL_IS_OBJECT(tv_caller)) {\n\t\t\th_tmp = DUK_TVAL_GET_OBJECT(tv_caller);\n\t\t\tDUK_ASSERT(h_tmp != NULL);\n\t\t\tact_callee->prev_caller = h_tmp;\n\n\t\t\t/* Previous value doesn't need refcount changes because its ownership\n\t\t\t * is transferred to prev_caller.\n\t\t\t */\n\n\t\t\tif (act_caller != NULL) {\n\t\t\t\tDUK_ASSERT(act_caller->func != NULL);\n\t\t\t\tDUK_TVAL_SET_OBJECT(tv_caller, act_caller->func);\n\t\t\t\tDUK_TVAL_INCREF(thr, tv_caller);\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_NULL(tv_caller);  /* no incref */\n\t\t\t}\n\t\t} else {\n\t\t\t/* 'caller' must only take on 'null' or function value */\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_caller));\n\t\t\tDUK_ASSERT(act_callee->prev_caller == NULL);\n\t\t\tif (act_caller != NULL && act_caller->func) {\n\t\t\t\t/* Tolerate act_caller->func == NULL which happens in\n\t\t\t\t * some finalization cases; treat like unknown caller.\n\t\t\t\t */\n\t\t\t\tDUK_TVAL_SET_OBJECT(tv_caller, act_caller->func);\n\t\t\t\tDUK_TVAL_INCREF(thr, tv_caller);\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_NULL(tv_caller);  /* no incref */\n\t\t\t}\n\t\t}\n\t}\n}\n#endif  /* DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */\n\n/*\n *  Shared helpers for resolving the final, non-bound target function of the\n *  call and the effective 'this' binding.  Resolves bound functions and\n *  applies .call(), .apply(), and .construct() inline.\n *\n *  Proxy traps are also handled inline so that if the target is a Proxy with\n *  a 'call' or 'construct' trap, the trap handler is called with a modified\n *  argument list.\n *\n *  Once the bound function / .call() / .apply() / .construct() sequence has\n *  been resolved, the value at idx_func + 1 may need coercion described in\n *  E5 Section 10.4.3.\n *\n *  A call that begins as a non-constructor call may be converted into a\n *  constructor call during the resolution process if Reflect.construct()\n *  is invoked.  This is handled by updating the caller's call_flags.\n *\n *  For global and eval code (E5 Sections 10.4.1 and 10.4.2), we assume\n *  that the caller has provided the correct 'this' binding explicitly\n *  when calling, i.e.:\n *\n *    - global code: this=global object\n *    - direct eval: this=copy from eval() caller's this binding\n *    - other eval:  this=global object\n *\n *  The 'this' coercion may cause a recursive function call with arbitrary\n *  side effects, because ToObject() may be called.\n */\n\nDUK_LOCAL DUK_INLINE void duk__coerce_nonstrict_this_binding(duk_hthread *thr, duk_idx_t idx_this) {\n\tduk_tval *tv_this;\n\tduk_hobject *obj_global;\n\n\ttv_this = thr->valstack_bottom + idx_this;\n\tswitch (DUK_TVAL_GET_TAG(tv_this)) {\n\tcase DUK_TAG_OBJECT:\n\t\tDUK_DDD(DUK_DDDPRINT(\"this binding: non-strict, object -> use directly\"));\n\t\tbreak;\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\t\tDUK_DDD(DUK_DDDPRINT(\"this binding: non-strict, undefined/null -> use global object\"));\n\t\tobj_global = thr->builtins[DUK_BIDX_GLOBAL];\n\t\t/* XXX: avoid this check somehow */\n\t\tif (DUK_LIKELY(obj_global != NULL)) {\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_this));  /* no need to decref previous value */\n\t\t\tDUK_TVAL_SET_OBJECT(tv_this, obj_global);\n\t\t\tDUK_HOBJECT_INCREF(thr, obj_global);\n\t\t} else {\n\t\t\t/* This may only happen if built-ins are being \"torn down\".\n\t\t\t * This behavior is out of specification scope.\n\t\t\t */\n\t\t\tDUK_D(DUK_DPRINT(\"this binding: wanted to use global object, but it is NULL -> using undefined instead\"));\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_this));  /* no need to decref previous value */\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv_this);  /* nothing to incref */\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\t/* Plain buffers and lightfuncs are object coerced.  Lightfuncs\n\t\t * very rarely come here however, because the call target would\n\t\t * need to be a non-strict non-lightfunc (lightfuncs are considered\n\t\t * strict) with an explicit lightfunc 'this' binding.\n\t\t */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_this));\n\t\tDUK_DDD(DUK_DDDPRINT(\"this binding: non-strict, not object/undefined/null -> use ToObject(value)\"));\n\t\tduk_to_object(thr, idx_this);  /* may have side effects */\n\t\tbreak;\n\t}\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_bool_t duk__resolve_target_fastpath_check(duk_hthread *thr, duk_idx_t idx_func, duk_hobject **out_func, duk_small_uint_t call_flags) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tDUK_UNREF(thr);\n\tDUK_UNREF(idx_func);\n\tDUK_UNREF(out_func);\n\tDUK_UNREF(call_flags);\n#else  /* DUK_USE_PREFER_SIZE */\n\tduk_tval *tv_func;\n\tduk_hobject *func;\n\n\tif (DUK_UNLIKELY(call_flags & DUK_CALL_FLAG_CONSTRUCT)) {\n\t\treturn 0;\n\t}\n\n\ttv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);\n\tDUK_ASSERT(tv_func != NULL);\n\n\tif (DUK_LIKELY(DUK_TVAL_IS_OBJECT(tv_func))) {\n\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\t\tif (DUK_HOBJECT_IS_CALLABLE(func) &&\n\t\t    !DUK_HOBJECT_HAS_BOUNDFUNC(func) &&\n\t\t    !DUK_HOBJECT_HAS_SPECIAL_CALL(func)) {\n\t\t\t*out_func = func;\n\n\t\t\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t\t\t/* Strict function: no 'this' coercion. */\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tduk__coerce_nonstrict_this_binding(thr, idx_func + 1);\n\t\t\treturn 1;\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {\n\t\t*out_func = NULL;\n\n\t\t/* Lightfuncs are considered strict, so 'this' binding is\n\t\t * used as is.  They're never bound, always constructable,\n\t\t * and never special functions.\n\t\t */\n\t\treturn 1;\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\treturn 0;  /* let slow path deal with it */\n}\n\nDUK_LOCAL duk_hobject *duk__resolve_target_func_and_this_binding(duk_hthread *thr,\n                                                                 duk_idx_t idx_func,\n                                                                 duk_small_uint_t *call_flags) {\n\tduk_tval *tv_func;\n\tduk_hobject *func;\n\tduk_bool_t first;\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\tfor (first = 1;; first = 0) {\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\t\ttv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);\n\t\tDUK_ASSERT(tv_func != NULL);\n\n\t\tDUK_DD(DUK_DDPRINT(\"target func: %!iT\", tv_func));\n\n\t\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\n\t\t\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\t\t\tif (DUK_UNLIKELY(!DUK_HOBJECT_HAS_CONSTRUCTABLE(func))) {\n\t\t\t\t\tgoto not_constructable;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (DUK_UNLIKELY(!DUK_HOBJECT_IS_CALLABLE(func))) {\n\t\t\t\t\tgoto not_callable;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (DUK_LIKELY(!DUK_HOBJECT_HAS_BOUNDFUNC(func) &&\n\t\t\t               !DUK_HOBJECT_HAS_SPECIAL_CALL(func) &&\n\t\t\t               !DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(func))) {\n\t\t\t\t/* Common case, so test for using a single bitfield test.\n\t\t\t\t * Break out to handle this coercion etc.\n\t\t\t\t */\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/* XXX: could set specialcall for boundfuncs too, simplify check above */\n\n\t\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_SPECIAL_CALL(func));\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_IS_NATFUNC(func));\n\n\t\t\t\t/* Callable/constructable flags are the same\n\t\t\t\t * for the bound function and its target, so\n\t\t\t\t * we don't need to check them here, we can\n\t\t\t\t * check them from the target only.\n\t\t\t\t */\n\t\t\t\tduk__handle_bound_chain_for_call(thr, idx_func, *call_flags & DUK_CALL_FLAG_CONSTRUCT);\n\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(duk_require_tval(thr, idx_func)) ||\n\t\t\t\t           DUK_TVAL_IS_LIGHTFUNC(duk_require_tval(thr, idx_func)));\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_SPECIAL_CALL(func));\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\t\t\tif (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(func)) {\n\t\t\t\t\t/* If no trap, resume processing from Proxy trap.\n\t\t\t\t\t * If trap exists, helper converts call into a trap\n\t\t\t\t\t * call; this may change a constructor call into a\n\t\t\t\t\t * normal (non-constructor) trap call.  We must\n\t\t\t\t\t * continue processing even when a trap is found as\n\t\t\t\t\t * the trap may be bound.\n\t\t\t\t\t */\n\t\t\t\t\tduk__handle_proxy_for_call(thr, idx_func, (duk_hproxy *) func, call_flags);\n\t\t\t\t}\n\t\t\t\telse\n#endif\n\t\t\t\t{\n\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(func));\n\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_CALLABLE(func));\n\t\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CONSTRUCTABLE(func));\n\t\t\t\t\t/* Constructable check already done above. */\n\n\t\t\t\t\tif (duk__handle_specialfuncs_for_call(thr, idx_func, func, call_flags, first) != 0) {\n\t\t\t\t\t\t/* Encountered native eval call, normal call\n\t\t\t\t\t\t * context.  Break out, handle this coercion etc.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* Retry loop. */\n\t\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {\n\t\t\t/* Lightfuncs are:\n\t\t\t *   - Always strict, so no 'this' coercion.\n\t\t\t *   - Always callable.\n\t\t\t *   - Always constructable.\n\t\t\t *   - Never specialfuncs.\n\t\t\t */\n\t\t\tfunc = NULL;\n\t\t\tgoto finished;\n\t\t} else {\n\t\t\tgoto not_callable;\n\t\t}\n\t}\n\n\tDUK_ASSERT(func != NULL);\n\n\tif (!DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t/* Non-strict target needs 'this' coercion.\n\t\t * This has potential side effects invalidating\n\t\t * 'tv_func'.\n\t\t */\n\t\tduk__coerce_nonstrict_this_binding(thr, idx_func + 1);\n\t}\n\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tif (!(*call_flags & DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED)) {\n\t\t\t*call_flags |= DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED;\n\t\t\tduk__update_default_instance_proto(thr, idx_func);\n\t\t}\n\t}\n\n finished:\n\n#if defined(DUK_USE_ASSERTIONS)\n\t{\n\t\tduk_tval *tv_tmp;\n\n\t\ttv_tmp = duk_get_tval(thr, idx_func);\n\t\tDUK_ASSERT(tv_tmp != NULL);\n\n\t\tDUK_ASSERT((DUK_TVAL_IS_OBJECT(tv_tmp) && DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(tv_tmp))) ||\n\t\t           DUK_TVAL_IS_LIGHTFUNC(tv_tmp));\n\t\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\t\tDUK_ASSERT(func == NULL || (DUK_HOBJECT_IS_COMPFUNC(func) ||\n\t\t                            DUK_HOBJECT_IS_NATFUNC(func)));\n\t\tDUK_ASSERT(func == NULL || (DUK_HOBJECT_HAS_CONSTRUCTABLE(func) ||\n\t\t                            (*call_flags & DUK_CALL_FLAG_CONSTRUCT) == 0));\n\t}\n#endif\n\n\treturn func;\n\n not_callable:\n\tDUK_ASSERT(tv_func != NULL);\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t/* GETPROPC delayed error handling: when target is not callable,\n\t * GETPROPC replaces idx_func+0 with a non-callable wrapper object\n\t * with a hidden Symbol to signify it's to be handled here.  If\n\t * found, unwrap the original Error and throw it as is here.  The\n\t * hidden Symbol is only checked as an own property, not inherited\n\t * (which would be dangerous).\n\t */\n\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\tduk_tval *tv_wrap = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, DUK_TVAL_GET_OBJECT(tv_func), DUK_STRIDX_INT_TARGET);\n\t\tif (tv_wrap != NULL) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"delayed error from GETPROPC: %!T\", tv_wrap));\n\t\t\tduk_push_tval(thr, tv_wrap);\n\t\t\t(void) duk_throw(thr);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t}\n#endif\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not callable\", duk_get_type_name(thr, idx_func));\n#else\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not callable\", duk_push_string_tval_readable(thr, tv_func));\n#endif\n#else\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);\n#endif\n\tDUK_WO_NORETURN(return NULL;);\n\n not_constructable:\n\t/* For now GETPROPC delayed error not needed for constructor calls. */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not constructable\", duk_get_type_name(thr, idx_func));\n#else\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not constructable\", duk_push_string_tval_readable(thr, tv_func));\n#endif\n#else\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONSTRUCTABLE);\n#endif\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Manipulate value stack so that exactly 'num_stack_rets' return\n *  values are at 'idx_retbase' in every case, assuming there are\n *  'rc' return values on top of stack.\n *\n *  This is a bit tricky, because the called C function operates in\n *  the same activation record and may have e.g. popped the stack\n *  empty (below idx_retbase).\n */\n\nDUK_LOCAL void duk__safe_call_adjust_valstack(duk_hthread *thr, duk_idx_t idx_retbase, duk_idx_t num_stack_rets, duk_idx_t num_actual_rets) {\n\tduk_idx_t idx_rcbase;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(idx_retbase >= 0);\n\tDUK_ASSERT(num_stack_rets >= 0);\n\tDUK_ASSERT(num_actual_rets >= 0);\n\n\tidx_rcbase = duk_get_top(thr) - num_actual_rets;  /* base of known return values */\n\tif (DUK_UNLIKELY(idx_rcbase < 0)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_CFUNC_RC);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"adjust valstack after func call: \"\n\t                     \"num_stack_rets=%ld, num_actual_rets=%ld, stack_top=%ld, idx_retbase=%ld, idx_rcbase=%ld\",\n\t                     (long) num_stack_rets, (long) num_actual_rets, (long) duk_get_top(thr),\n\t                     (long) idx_retbase, (long) idx_rcbase));\n\n\tDUK_ASSERT(idx_rcbase >= 0);  /* caller must check */\n\n\t/* Space for num_stack_rets was reserved before the safe call.\n\t * Because value stack reserve cannot shrink except in call returns,\n\t * the reserve is still in place.  Adjust valstack, carefully\n\t * ensuring we don't overstep the reserve.\n\t */\n\n\t/* Match idx_rcbase with idx_retbase so that the return values\n\t * start at the correct index.\n\t */\n\tif (idx_rcbase > idx_retbase) {\n\t\tduk_idx_t count = idx_rcbase - idx_retbase;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"elements at/after idx_retbase have enough to cover func retvals \"\n\t\t                     \"(idx_retbase=%ld, idx_rcbase=%ld)\", (long) idx_retbase, (long) idx_rcbase));\n\n\t\t/* Remove values between irc_rcbase (start of intended return\n\t\t * values) and idx_retbase to lower return values to idx_retbase.\n\t\t */\n\t\tDUK_ASSERT(count > 0);\n\t\tduk_remove_n(thr, idx_retbase, count);  /* may be NORZ */\n\t} else {\n\t\tduk_idx_t count = idx_retbase - idx_rcbase;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"not enough elements at/after idx_retbase to cover func retvals \"\n\t\t                     \"(idx_retbase=%ld, idx_rcbase=%ld)\", (long) idx_retbase, (long) idx_rcbase));\n\n\t\t/* Insert 'undefined' at idx_rcbase (start of intended return\n\t\t * values) to lift return values to idx_retbase.\n\t\t */\n\t\tDUK_ASSERT(count >= 0);\n\t\tDUK_ASSERT(thr->valstack_end - thr->valstack_top >= count);  /* reserve cannot shrink */\n\t\tduk_insert_undefined_n(thr, idx_rcbase, count);\n\t}\n\n\t/* Chop extra retvals away / extend with undefined. */\n\tduk_set_top_unsafe(thr, idx_retbase + num_stack_rets);\n}\n\n/*\n *  Activation setup for tailcalls and non-tailcalls.\n */\n\n#if defined(DUK_USE_TAILCALL)\nDUK_LOCAL duk_small_uint_t duk__call_setup_act_attempt_tailcall(duk_hthread *thr,\n                                                                duk_small_uint_t call_flags,\n                                                                duk_idx_t idx_func,\n                                                                duk_hobject *func,\n                                                                duk_size_t entry_valstack_bottom_byteoff,\n                                                                duk_size_t entry_valstack_end_byteoff,\n                                                                duk_idx_t *out_nargs,\n                                                                duk_idx_t *out_nregs,\n                                                                duk_size_t *out_vs_min_bytes,\n                                                                duk_activation **out_act) {\n\tduk_activation *act;\n\tduk_tval *tv1, *tv2;\n\tduk_idx_t idx_args;\n\tduk_small_uint_t flags1, flags2;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_activation *prev_pause_act;\n#endif\n\n\tDUK_UNREF(entry_valstack_end_byteoff);\n\n\t/* Tailcall cannot be flagged to resume calls, and a\n\t * previous frame must exist.\n\t */\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\t*out_act = act;\n\n\tif (func == NULL || !DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by target not being ecma function\"));\n\t\treturn 0;\n\t}\n\tif (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by current activation having DUK_ACT_FLAG_PREVENT_YIELD\"));\n\t\treturn 0;\n\t}\n\t/* Tailcall is only allowed if current and candidate\n\t * function have identical return value handling.  There\n\t * are three possible return value handling cases:\n\t *   1. Normal function call, no special return value handling.\n\t *   2. Constructor call, return value replacement object check.\n\t *   3. Proxy 'construct' trap call, return value invariant check.\n\t */\n\tflags1 = (duk_small_uint_t) ((act->flags & DUK_ACT_FLAG_CONSTRUCT) ? 1 : 0)\n#if defined(DUK_USE_ES6_PROXY)\n\t         | (duk_small_uint_t) ((act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) ? 2 : 0)\n#endif\n\t         ;\n\tflags2 = (duk_small_uint_t) ((call_flags & DUK_CALL_FLAG_CONSTRUCT) ? 1 : 0)\n#if defined(DUK_USE_ES6_PROXY)\n\t         | (duk_small_uint_t) ((call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) ? 2 : 0);\n#endif\n\t         ;\n\tif (flags1 != flags2) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by incompatible return value handling\"));\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(((act->flags & DUK_ACT_FLAG_CONSTRUCT) && (call_flags & DUK_CALL_FLAG_CONSTRUCT)) ||\n\t           (!(act->flags & DUK_ACT_FLAG_CONSTRUCT) && !(call_flags & DUK_CALL_FLAG_CONSTRUCT)));\n\tDUK_ASSERT(((act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) && (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY)) ||\n\t           (!(act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) && !(call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY)));\n\tif (DUK_HOBJECT_HAS_NOTAIL(func)) {\n\t\t/* See: test-bug-tailcall-preventyield-assert.c. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by function having a notail flag\"));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  Tailcall handling\n\t *\n\t *  Although the callstack entry is reused, we need to explicitly unwind\n\t *  the current activation (or simulate an unwind).  In particular, the\n\t *  current activation must be closed, otherwise something like\n\t *  test-bug-reduce-judofyr.js results.  Also catchers need to be unwound\n\t *  because there may be non-error-catching label entries in valid tail calls.\n\t *\n\t *  Special attention is needed for debugger and pause behavior when\n\t *  reusing an activation.\n\t *    - Disable StepOut processing for the activation unwind because\n\t *      we reuse the activation, see:\n\t *      https://github.com/svaarala/duktape/issues/1684.\n\t *    - Disable line change pause flag permanently if act == dbg_pause_act\n\t *      (if set) because it would no longer be relevant, see:\n\t *      https://github.com/svaarala/duktape/issues/1726,\n\t *      https://github.com/svaarala/duktape/issues/1786.\n\t *    - Check for function entry (e.g. StepInto) pause flag here, because\n\t *      the executor pause check won't trigger due to shared activation, see:\n\t *      https://github.com/svaarala/duktape/issues/1726.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"is tail call, reusing activation at callstack top, at index %ld\",\n                             (long) (thr->callstack_top - 1)));\n\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(func));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));\n\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\tDUK_ASSERT(call_flags & DUK_CALL_FLAG_ALLOW_ECMATOECMA);\n\n\t/* Unwind the topmost callstack entry before reusing it.  This\n\t * also unwinds the catchers related to the topmost entry.\n\t */\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (act == thr->heap->dbg_pause_act) {\n\t\tthr->heap->dbg_pause_flags &= ~DUK_PAUSE_FLAG_LINE_CHANGE;\n\t}\n\n\tprev_pause_act = thr->heap->dbg_pause_act;\n\tthr->heap->dbg_pause_act = NULL;\n\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_ENTRY) {\n\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by function entry (tailcall)\"));\n\t\tduk_debug_set_paused(thr->heap);\n\t}\n#endif\n\tduk_hthread_activation_unwind_reuse_norz(thr);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tthr->heap->dbg_pause_act = prev_pause_act;\n#endif\n\tDUK_ASSERT(act == thr->callstack_curr);\n\n\t/* XXX: We could restore the caller's value stack reserve\n\t * here, as if we did an actual unwind-and-call.  Without\n\t * the restoration, value stack reserve may remain higher\n\t * than would otherwise be possible until we return to a\n\t * non-tailcall.\n\t */\n\n\t/* Then reuse the unwound activation. */\n\tact->cat = NULL;\n\tact->var_env = NULL;\n\tact->lex_env = NULL;\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));\n\tact->func = func;  /* don't want an intermediate exposed state with func == NULL */\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\tact->prev_caller = NULL;\n#endif\n\t/* don't want an intermediate exposed state with invalid pc */\n\tact->curr_pc = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) func);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tact->prev_line = 0;\n#endif\n\tDUK_TVAL_SET_OBJECT(&act->tv_func, func);  /* borrowed, no refcount */\n\tDUK_HOBJECT_INCREF(thr, func);\n\n\tact->flags = DUK_ACT_FLAG_TAILCALLED;\n\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\tact->flags |= DUK_ACT_FLAG_STRICT;\n\t}\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT;\n\t}\n#if defined(DUK_USE_ES6_PROXY)\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT_PROXY;\n\t}\n#endif\n\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) == func);      /* already updated */\n\tDUK_ASSERT(act->var_env == NULL);\n\tDUK_ASSERT(act->lex_env == NULL);\n\tact->bottom_byteoff = entry_valstack_bottom_byteoff;  /* tail call -> reuse current \"frame\" */\n#if 0\n\t/* Topmost activation retval_byteoff is considered garbage, no need to init. */\n\tact->retval_byteoff = 0;\n#endif\n\t/* Filled in when final reserve is known, dummy value doesn't matter\n\t * even in error unwind because reserve_byteoff is only used when\n\t * returning to -this- activation.\n\t */\n\tact->reserve_byteoff = 0;\n\n\t/*\n\t *  Manipulate valstack so that args are on the current bottom and the\n\t *  previous caller's 'this' binding (which is the value preceding the\n\t *  current bottom) is replaced with the new 'this' binding:\n\t *\n\t *       [ ... this_old | (crud) func this_new arg1 ... argN ]\n\t *  -->  [ ... this_new | arg1 ... argN ]\n\t *\n\t *  For tail calling to work properly, the valstack bottom must not grow\n\t *  here; otherwise crud would accumulate on the valstack.\n\t */\n\n\ttv1 = thr->valstack_bottom - 1;\n\ttv2 = thr->valstack_bottom + idx_func + 1;\n\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);  /* tv1 is -below- valstack_bottom */\n\tDUK_ASSERT(tv2 >= thr->valstack_bottom && tv2 < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\n\tidx_args = idx_func + 2;\n\tduk_remove_n(thr, 0, idx_args);  /* may be NORZ */\n\n\tidx_func = 0; DUK_UNREF(idx_func);  /* really 'not applicable' anymore, should not be referenced after this */\n\tidx_args = 0;\n\n\t*out_nargs = ((duk_hcompfunc *) func)->nargs;\n\t*out_nregs = ((duk_hcompfunc *) func)->nregs;\n\tDUK_ASSERT(*out_nregs >= 0);\n\tDUK_ASSERT(*out_nregs >= *out_nargs);\n\t*out_vs_min_bytes = entry_valstack_bottom_byteoff + sizeof(duk_tval) * ((duk_size_t) *out_nregs + DUK_VALSTACK_INTERNAL_EXTRA);\n\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n#if defined(DUK_USE_TAILCALL)\n#error incorrect options: tail calls enabled with function caller property\n#endif\n\t/* XXX: This doesn't actually work properly for tail calls, so\n\t * tail calls are disabled when DUK_USE_NONSTD_FUNC_CALLER_PROPERTY\n\t * is in use.\n\t */\n\tduk__update_func_caller_prop(thr, func);\n#endif\n\n\t/* [ ... this_new | arg1 ... argN ] */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_TAILCALL */\n\nDUK_LOCAL void duk__call_setup_act_not_tailcall(duk_hthread *thr,\n                                                duk_small_uint_t call_flags,\n                                                duk_idx_t idx_func,\n                                                duk_hobject *func,\n                                                duk_size_t entry_valstack_bottom_byteoff,\n                                                duk_size_t entry_valstack_end_byteoff,\n                                                duk_idx_t *out_nargs,\n                                                duk_idx_t *out_nregs,\n                                                duk_size_t *out_vs_min_bytes,\n                                                duk_activation **out_act) {\n\tduk_activation *act;\n\tduk_activation *new_act;\n\n\tDUK_UNREF(entry_valstack_end_byteoff);\n\n\tDUK_DDD(DUK_DDDPRINT(\"not a tail call, pushing a new activation to callstack, to index %ld\",\n\t                     (long) (thr->callstack_top)));\n\n\tduk__call_callstack_limit_check(thr);\n\tnew_act = duk_hthread_activation_alloc(thr);\n\tDUK_ASSERT(new_act != NULL);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\t/*\n\t\t *  Update return value stack index of current activation (if any).\n\t\t *\n\t\t *  Although it might seem this is not necessary (bytecode executor\n\t\t *  does this for ECMAScript-to-ECMAScript calls; other calls are\n\t\t *  handled here), this turns out to be necessary for handling yield\n\t\t *  and resume.  For them, an ECMAScript-to-native call happens, and\n\t\t *  the ECMAScript call's retval_byteoff must be set for things to work.\n\t\t */\n\n\t\tact->retval_byteoff = entry_valstack_bottom_byteoff + (duk_size_t) idx_func * sizeof(duk_tval);\n\t}\n\n\tnew_act->parent = act;\n\tthr->callstack_curr = new_act;\n\tthr->callstack_top++;\n\tact = new_act;\n\t*out_act = act;\n\n\tDUK_ASSERT(thr->valstack_top > thr->valstack_bottom);  /* at least effective 'this' */\n\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\n\tact->cat = NULL;\n\n\tact->flags = 0;\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT;\n\t}\n#if defined(DUK_USE_ES6_PROXY)\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT_PROXY;\n\t}\n#endif\n\tif (call_flags & DUK_CALL_FLAG_DIRECT_EVAL) {\n\t\tact->flags |= DUK_ACT_FLAG_DIRECT_EVAL;\n\t}\n\n\t/* start of arguments: idx_func + 2. */\n\tact->func = func;  /* NULL for lightfunc */\n\tif (DUK_LIKELY(func != NULL)) {\n\t\tDUK_TVAL_SET_OBJECT(&act->tv_func, func);  /* borrowed, no refcount */\n\t\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t\tact->flags |= DUK_ACT_FLAG_STRICT;\n\t\t}\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\t\t*out_nargs = ((duk_hcompfunc *) func)->nargs;\n\t\t\t*out_nregs = ((duk_hcompfunc *) func)->nregs;\n\t\t\tDUK_ASSERT(*out_nregs >= 0);\n\t\t\tDUK_ASSERT(*out_nregs >= *out_nargs);\n\t\t\t*out_vs_min_bytes = entry_valstack_bottom_byteoff +\n\t\t\t\tsizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nregs + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t} else {\n\t\t\t/* True because of call target lookup checks. */\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(func));\n\n\t\t\t*out_nargs = ((duk_hnatfunc *) func)->nargs;\n\t\t\t*out_nregs = *out_nargs;\n\t\t\tif (*out_nargs >= 0) {\n\t\t\t\t*out_vs_min_bytes = entry_valstack_bottom_byteoff +\n\t\t\t\t\tsizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nregs + DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t\t} else {\n\t\t\t\t/* Vararg function. */\n\t\t\t\tduk_size_t valstack_top_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - ((duk_uint8_t *) thr->valstack));\n\t\t\t\t*out_vs_min_bytes = valstack_top_byteoff +\n\t\t\t\t\tsizeof(duk_tval) * (DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tduk_small_uint_t lf_flags;\n\t\tduk_tval *tv_func;\n\n\t\tact->flags |= DUK_ACT_FLAG_STRICT;\n\n\t\ttv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);\n\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func));\n\t\tDUK_TVAL_SET_TVAL(&act->tv_func, tv_func);  /* borrowed, no refcount */\n\n\t\tlf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv_func);\n\t\t*out_nargs = DUK_LFUNC_FLAGS_GET_NARGS(lf_flags);\n\t\tif (*out_nargs != DUK_LFUNC_NARGS_VARARGS) {\n\t\t\t*out_vs_min_bytes = entry_valstack_bottom_byteoff +\n\t\t\t\tsizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nargs + DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t} else {\n\t\t\tduk_size_t valstack_top_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - ((duk_uint8_t *) thr->valstack));\n\t\t\t*out_vs_min_bytes = valstack_top_byteoff +\n\t\t\t\tsizeof(duk_tval) * (DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t\t*out_nargs = -1;  /* vararg */\n\t\t}\n\t\t*out_nregs = *out_nargs;\n\t}\n\n\tact->var_env = NULL;\n\tact->lex_env = NULL;\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\tact->prev_caller = NULL;\n#endif\n\tact->curr_pc = NULL;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tact->prev_line = 0;\n#endif\n\tact->bottom_byteoff = entry_valstack_bottom_byteoff + sizeof(duk_tval) * ((duk_size_t) idx_func + 2U);\n#if 0\n\tact->retval_byteoff = 0;   /* topmost activation retval_byteoff is considered garbage, no need to init */\n#endif\n\t/* Filled in when final reserve is known, dummy value doesn't matter\n\t * even in error unwind because reserve_byteoff is only used when\n\t * returning to -this- activation.\n\t */\n\tact->reserve_byteoff = 0;  /* filled in by caller */\n\n\t/* XXX: Is this INCREF necessary? 'func' is always a borrowed\n\t * reference reachable through the value stack?  If changed, stack\n\t * unwind code also needs to be fixed to match.\n\t */\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, func);  /* act->func */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\tif (func) {\n\t\tduk__update_func_caller_prop(thr, func);\n\t}\n#endif\n}\n\n/*\n *  Environment setup.\n */\n\nDUK_LOCAL void duk__call_env_setup(duk_hthread *thr, duk_hobject *func, duk_activation *act, duk_idx_t idx_args) {\n\tduk_hobject *env;\n\n\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));  /* bound function has already been resolved */\n\n\tif (DUK_LIKELY(func != NULL)) {\n\t\tif (DUK_LIKELY(DUK_HOBJECT_HAS_NEWENV(func))) {\n\t\t\tDUK_STATS_INC(thr->heap, stats_envrec_newenv);\n\t\t\tif (DUK_LIKELY(!DUK_HOBJECT_HAS_CREATEARGS(func))) {\n\t\t\t\t/* Use a new environment but there's no 'arguments' object;\n\t\t\t\t * delayed environment initialization.  This is the most\n\t\t\t\t * common case.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(act->lex_env == NULL);\n\t\t\t\tDUK_ASSERT(act->var_env == NULL);\n\t\t\t} else {\n\t\t\t\t/* Use a new environment and there's an 'arguments' object.\n\t\t\t\t * We need to initialize it right now.\n\t\t\t\t */\n\n\t\t\t\t/* third arg: absolute index (to entire valstack) of bottom_byteoff of new activation */\n\t\t\t\tenv = duk_create_activation_environment_record(thr, func, act->bottom_byteoff);\n\t\t\t\tDUK_ASSERT(env != NULL);\n\n\t\t\t\t/* [ ... func this arg1 ... argN envobj ] */\n\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_CREATEARGS(func));\n\t\t\t\tduk__handle_createargs_for_call(thr, func, env, idx_args);\n\n\t\t\t\t/* [ ... func this arg1 ... argN envobj ] */\n\n\t\t\t\tact->lex_env = env;\n\t\t\t\tact->var_env = env;\n\t\t\t\tDUK_HOBJECT_INCREF(thr, env);\n\t\t\t\tDUK_HOBJECT_INCREF(thr, env);  /* XXX: incref by count (2) directly */\n\t\t\t\tduk_pop(thr);\n\t\t\t}\n\t\t} else {\n\t\t\t/* Use existing env (e.g. for non-strict eval); cannot have\n\t\t\t * an own 'arguments' object (but can refer to an existing one).\n\t\t\t */\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(func));\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_envrec_oldenv);\n\t\t\tduk__handle_oldenv_for_call(thr, func, act);\n\n\t\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\t\tDUK_ASSERT(act->var_env != NULL);\n\t\t}\n\t} else {\n\t\t/* Lightfuncs are always native functions and have \"newenv\". */\n\t\tDUK_ASSERT(act->lex_env == NULL);\n\t\tDUK_ASSERT(act->var_env == NULL);\n\t\tDUK_STATS_INC(thr->heap, stats_envrec_newenv);\n\t}\n}\n\n/*\n *  Misc shared helpers.\n */\n\n/* Check thread state, update current thread. */\nDUK_LOCAL void duk__call_thread_state_update(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\tif (DUK_LIKELY(thr == thr->heap->curr_thread)) {\n\t\tif (DUK_UNLIKELY(thr->state != DUK_HTHREAD_STATE_RUNNING)) {\n\t\t\t/* Should actually never happen, but check anyway. */\n\t\t\tgoto thread_state_error;\n\t\t}\n\t} else {\n\t\tDUK_ASSERT(thr->heap->curr_thread == NULL ||\n\t\t           thr->heap->curr_thread->state == DUK_HTHREAD_STATE_RUNNING);\n\t\tif (DUK_UNLIKELY(thr->state != DUK_HTHREAD_STATE_INACTIVE)) {\n\t\t\tgoto thread_state_error;\n\t\t}\n\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, thr);\n\t\tthr->state = DUK_HTHREAD_STATE_RUNNING;\n\n\t\t/* Multiple threads may be simultaneously in the RUNNING\n\t\t * state, but not in the same \"resume chain\".\n\t\t */\n\t}\n\tDUK_ASSERT(thr->heap->curr_thread == thr);\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\treturn;\n\n thread_state_error:\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"invalid thread state (%ld)\", (long) thr->state);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Main unprotected call handler, handles:\n *\n *    - All combinations of native/ECMAScript caller and native/ECMAScript\n *      target.\n *\n *    - Optimized ECMAScript-to-ECMAScript call where call handling only\n *      sets up a new duk_activation but reuses an existing bytecode executor\n *      (the caller) without native recursion.\n *\n *    - Tailcalls, where an activation is reused without increasing call\n *      stack (duk_activation) depth.\n *\n *    - Setup for an initial Duktape.Thread.resume().\n *\n *  The call handler doesn't provide any protection guarantees, protected calls\n *  must be implemented e.g. by wrapping the call in a duk_safe_call().\n *  Call setup may fail at any stage, even when the new activation is in\n *  place; the only guarantee is that the state is consistent for unwinding.\n */\n\nDUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,\n                                         duk_idx_t idx_func,\n                                         duk_small_uint_t call_flags) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_activation *entry_act;\n\tduk_size_t entry_callstack_top;\n#endif\n\tduk_size_t entry_valstack_bottom_byteoff;\n\tduk_size_t entry_valstack_end_byteoff;\n\tduk_int_t entry_call_recursion_depth;\n\tduk_hthread *entry_curr_thread;\n\tduk_uint_fast8_t entry_thread_state;\n\tduk_instr_t **entry_ptr_curr_pc;\n\tduk_idx_t idx_args;\n\tduk_idx_t nargs;            /* # argument registers target function wants (< 0 => \"as is\") */\n\tduk_idx_t nregs;            /* # total registers target function wants on entry (< 0 => \"as is\") */\n\tduk_size_t vs_min_bytes;    /* minimum value stack size (bytes) for handling call */\n\tduk_hobject *func;          /* 'func' on stack (borrowed reference) */\n\tduk_activation *act;\n\tduk_ret_t rc;\n\tduk_small_uint_t use_tailcall;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\t/* Asserts for heap->curr_thread omitted: it may be NULL, 'thr', or\n\t * any other thread (e.g. when heap thread is used to run finalizers).\n\t */\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\tDUK_ASSERT(idx_func >= 0);\n\n\tDUK_STATS_INC(thr->heap, stats_call_all);\n\n\t/* If a tail call:\n\t *   - an ECMAScript activation must be on top of the callstack\n\t *   - there cannot be any catch stack entries that would catch\n\t *     a return\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tif (call_flags & DUK_CALL_FLAG_TAILCALL) {\n\t\tduk_activation *tmp_act;\n\t\tduk_catcher *tmp_cat;\n\n\t\tDUK_ASSERT(thr->callstack_top >= 1);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\t\t/* No entry in the catch stack which would actually catch a\n\t\t * throw can refer to the callstack entry being reused.\n\t\t * There *can* be catch stack entries referring to the current\n\t\t * callstack entry as long as they don't catch (e.g. label sites).\n\t\t */\n\n\t\ttmp_act = thr->callstack_curr;\n\t\tfor (tmp_cat = tmp_act->cat; tmp_cat != NULL; tmp_cat = tmp_cat->parent) {\n\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(tmp_cat) == DUK_CAT_TYPE_LABEL); /* a non-catching entry */\n\t\t}\n\t}\n#endif  /* DUK_USE_ASSERTIONS */\n\n\t/*\n\t *  Store entry state.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_act = thr->callstack_curr;\n\tentry_callstack_top = thr->callstack_top;\n#endif\n\tentry_valstack_bottom_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);\n\tentry_valstack_end_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tentry_call_recursion_depth = thr->heap->call_recursion_depth;\n\tentry_curr_thread = thr->heap->curr_thread;  /* may be NULL if first call */\n\tentry_thread_state = thr->state;\n\tentry_ptr_curr_pc = thr->ptr_curr_pc;  /* may be NULL */\n\n\t/* If thr->ptr_curr_pc is set, sync curr_pc to act->pc.  Then NULL\n\t * thr->ptr_curr_pc so that it's not accidentally used with an incorrect\n\t * activation when side effects occur.\n\t */\n\tduk_hthread_sync_and_null_currpc(thr);\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"duk__handle_call_raw: thr=%p, idx_func=%ld, \"\n\t                   \"call_flags=0x%08lx (constructor=%ld), \"\n\t                   \"valstack_top=%ld, idx_func=%ld, idx_args=%ld, rec_depth=%ld/%ld, \"\n\t                   \"entry_valstack_bottom_byteoff=%ld, entry_valstack_end_byteoff=%ld, \"\n\t                   \"entry_call_recursion_depth=%ld, \"\n\t                   \"entry_curr_thread=%p, entry_thread_state=%ld\",\n\t                   (void *) thr,\n\t                   (long) idx_func,\n\t                   (unsigned long) call_flags,\n\t                   (long) ((call_flags & DUK_CALL_FLAG_CONSTRUCT) != 0 ? 1 : 0),\n\t                   (long) duk_get_top(thr),\n\t                   (long) idx_func,\n\t                   (long) (idx_func + 2),\n\t                   (long) thr->heap->call_recursion_depth,\n\t                   (long) thr->heap->call_recursion_limit,\n\t                   (long) entry_valstack_bottom_byteoff,\n\t                   (long) entry_valstack_end_byteoff,\n\t                   (long) entry_call_recursion_depth,\n\t                   (void *) entry_curr_thread,\n\t                   (long) entry_thread_state));\n\n\t/*\n\t *  Thread state check and book-keeping.\n\t */\n\n\tduk__call_thread_state_update(thr);\n\n\t/*\n\t *  Increase call recursion depth as early as possible so that if we\n\t *  enter a recursive call for any reason there's a backstop to native\n\t *  recursion.  This can happen e.g. for almost any property read\n\t *  because it may cause a getter call or a Proxy trap (GC and finalizers\n\t *  are not an issue because they are not recursive).  If we end up\n\t *  doing an Ecma-to-Ecma call, revert the increase.  (See GH-2032.)\n\t *\n\t *  For similar reasons, ensure there is a known value stack spare\n\t *  even before we actually prepare the value stack for the target\n\t *  function.  If this isn't done, early recursion may consume the\n\t *  value stack space.\n\t *\n\t *  XXX: Should bump yield preventcount early, for the same reason.\n\t */\n\n\tduk__call_c_recursion_limit_check(thr);\n\tthr->heap->call_recursion_depth++;\n\tduk_require_stack(thr, DUK__CALL_HANDLING_REQUIRE_STACK);\n\n\t/*\n\t *  Resolve final target function; handle bound functions and special\n\t *  functions like .call() and .apply().  Also figure out the effective\n\t *  'this' binding, which replaces the current value at idx_func + 1.\n\t */\n\n\tif (DUK_LIKELY(duk__resolve_target_fastpath_check(thr, idx_func, &func, call_flags) != 0U)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"fast path target resolve\"));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"slow path target resolve\"));\n\t\tfunc = duk__resolve_target_func_and_this_binding(thr, idx_func, &call_flags);\n\t}\n\tDUK_ASSERT(duk_get_top(thr) - idx_func >= 2);  /* at least func and this present */\n\n\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\tDUK_ASSERT(func == NULL || (DUK_HOBJECT_IS_COMPFUNC(func) ||\n\t                            DUK_HOBJECT_IS_NATFUNC(func)));\n\n\t/* [ ... func this arg1 ... argN ] */\n\n\t/*\n\t *  Setup a preliminary activation and figure out nargs/nregs and\n\t *  value stack minimum size.\n\t *\n\t *  Don't touch valstack_bottom or valstack_top yet so that Duktape API\n\t *  calls work normally.\n\t *\n\t *  Because 'act' is not zeroed, all fields must be filled in.\n\t */\n\n\t/* Should not be necessary, but initialize to silence warnings. */\n\tact = NULL;\n\tnargs = 0;\n\tnregs = 0;\n\tvs_min_bytes = 0;\n\n#if defined(DUK_USE_TAILCALL)\n\tuse_tailcall = (call_flags & DUK_CALL_FLAG_TAILCALL);\n\tif (use_tailcall) {\n\t\tuse_tailcall = duk__call_setup_act_attempt_tailcall(thr,\n\t\t                                                    call_flags,\n\t\t                                                    idx_func,\n\t\t                                                    func,\n\t\t                                                    entry_valstack_bottom_byteoff,\n\t\t                                                    entry_valstack_end_byteoff,\n\t\t                                                    &nargs,\n\t\t                                                    &nregs,\n\t\t                                                    &vs_min_bytes,\n\t\t                                                    &act);\n\t}\n#else\n\tDUK_ASSERT((call_flags & DUK_CALL_FLAG_TAILCALL) == 0);  /* compiler ensures this */\n\tuse_tailcall = 0;\n#endif\n\n\tif (use_tailcall) {\n\t\tidx_args = 0;\n\t\tDUK_STATS_INC(thr->heap, stats_call_tailcall);\n\t} else {\n\t\tduk__call_setup_act_not_tailcall(thr,\n\t\t                                 call_flags,\n\t\t                                 idx_func,\n\t\t                                 func,\n\t\t                                 entry_valstack_bottom_byteoff,\n\t\t                                 entry_valstack_end_byteoff,\n\t\t                                 &nargs,\n\t\t                                 &nregs,\n\t\t                                 &vs_min_bytes,\n\t\t                                 &act);\n\t\tidx_args = idx_func + 2;\n\t}\n\t/* After this point idx_func is no longer valid for tailcalls. */\n\n\tDUK_ASSERT(act != NULL);\n\n\t/* [ ... func this arg1 ... argN ] */\n\n\t/*\n\t *  Environment record creation and 'arguments' object creation.\n\t *  Named function expression name binding is handled by the\n\t *  compiler; the compiled function's parent env will contain\n\t *  the (immutable) binding already.\n\t *\n\t *  This handling is now identical for C and ECMAScript functions.\n\t *  C functions always have the 'NEWENV' flag set, so their\n\t *  environment record initialization is delayed (which is good).\n\t *\n\t *  Delayed creation (on demand) is handled in duk_js_var.c.\n\t */\n\n\tduk__call_env_setup(thr, func, act, idx_args);\n\n\t/* [ ... func this arg1 ... argN ] */\n\n\t/*\n\t *  Setup value stack: clamp to 'nargs', fill up to 'nregs',\n\t *  ensure value stack size matches target requirements, and\n\t *  switch value stack bottom.  Valstack top is kept.\n\t *\n\t *  Value stack can only grow here.\n\t */\n\n\tduk_valstack_grow_check_throw(thr, vs_min_bytes);\n\tact->reserve_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\n\tif (use_tailcall) {\n\t\tDUK_ASSERT(nregs >= 0);\n\t\tDUK_ASSERT(nregs >= nargs);\n\t\tduk_set_top_and_wipe(thr, nregs, nargs);\n\t} else {\n\t\tif (nregs >= 0) {\n\t\t\tDUK_ASSERT(nregs >= nargs);\n\t\t\tduk_set_top_and_wipe(thr, idx_func + 2 + nregs, idx_func + 2 + nargs);\n\t\t} else {\n\t\t\t;\n\t\t}\n\t\tthr->valstack_bottom = thr->valstack_bottom + idx_func + 2;\n\t}\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\n\t/*\n\t *  Make the actual call.  For Ecma-to-Ecma calls detect that\n\t *  setup is complete, then return with a status code that allows\n\t *  the caller to reuse the running executor.\n\t */\n\n\tif (func != NULL && DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\t/*\n\t\t *  ECMAScript call.\n\t\t */\n\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));\n\t\tact->curr_pc = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) func);\n\n\t\tif (call_flags & DUK_CALL_FLAG_ALLOW_ECMATOECMA) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"avoid native call, use existing executor\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_call_ecmatoecma);\n\t\t\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\t\t\tDUK_REFZERO_CHECK_FAST(thr);\n\t\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\t\tthr->heap->call_recursion_depth--;  /* No recursion increase for this case. */\n\t\t\treturn 1;  /* 1=reuse executor */\n\t\t}\n\t\tDUK_ASSERT(use_tailcall == 0);\n\n\t\t/* duk_hthread_activation_unwind_norz() will decrease this on unwind */\n\t\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\t\tact->flags |= DUK_ACT_FLAG_PREVENT_YIELD;\n\t\tthr->callstack_preventcount++;\n\n\t\t/* [ ... func this | arg1 ... argN ] ('this' must precede new bottom) */\n\n\t\t/*\n\t\t *  Bytecode executor call.\n\t\t *\n\t\t *  Execute bytecode, handling any recursive function calls and\n\t\t *  thread resumptions.  Returns when execution would return from\n\t\t *  the entry level activation.  When the executor returns, a\n\t\t *  single return value is left on the stack top.\n\t\t *\n\t\t *  The only possible longjmp() is an error (DUK_LJ_TYPE_THROW),\n\t\t *  other types are handled internally by the executor.\n\t\t */\n\n\t\t/* thr->ptr_curr_pc is set by bytecode executor early on entry */\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"entering bytecode execution\"));\n\t\tduk_js_execute_bytecode(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"returned from bytecode execution\"));\n\t} else {\n\t\t/*\n\t\t *  Native call.\n\t\t */\n\n\t\tDUK_ASSERT(func == NULL || ((duk_hnatfunc *) func)->func != NULL);\n\t\tDUK_ASSERT(use_tailcall == 0);\n\n\t\t/* [ ... func this | arg1 ... argN ] ('this' must precede new bottom) */\n\n\t\t/* duk_hthread_activation_unwind_norz() will decrease this on unwind */\n\t\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\t\tact->flags |= DUK_ACT_FLAG_PREVENT_YIELD;\n\t\tthr->callstack_preventcount++;\n\n\t\t/* For native calls must be NULL so we don't sync back */\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\n\t\t/* XXX: native funcptr could come out of call setup. */\n\t\tif (func) {\n\t\t\trc = ((duk_hnatfunc *) func)->func(thr);\n\t\t} else {\n\t\t\tduk_tval *tv_func;\n\t\t\tduk_c_function funcptr;\n\n\t\t\ttv_func = &act->tv_func;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func));\n\t\t\tfuncptr = DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv_func);\n\t\t\trc = funcptr(thr);\n\t\t}\n\n\t\t/* Automatic error throwing, retval check. */\n\n\t\tif (rc == 0) {\n\t\t\tDUK_ASSERT(thr->valstack < thr->valstack_end);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));\n\t\t\tthr->valstack_top++;\n\t\t} else if (rc == 1) {\n\t\t\t;\n\t\t} else if (rc < 0) {\n\t\t\tduk_error_throw_from_negative_rc(thr, rc);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t} else {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_CFUNC_RC);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t}\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\tDUK_ASSERT(use_tailcall == 0);\n\n\t/*\n\t *  Constructor call post processing.\n\t */\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (call_flags & (DUK_CALL_FLAG_CONSTRUCT | DUK_CALL_FLAG_CONSTRUCT_PROXY)) {\n\t\tduk_call_construct_postprocess(thr, call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY);\n\t}\n#else\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tduk_call_construct_postprocess(thr, 0);\n\t}\n#endif\n\n\t/*\n\t *  Unwind, restore valstack bottom and other book-keeping.\n\t */\n\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_curr->parent == entry_act);\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top + 1);\n\tduk_hthread_activation_unwind_norz(thr);\n\tDUK_ASSERT(thr->callstack_curr == entry_act);\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_bottom_byteoff);\n\t/* keep current valstack_top */\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_top - thr->valstack_bottom >= idx_func + 1);\n\n\t/* Return value handling. */\n\n\t/* [ ... func this (crud) retval ] */\n\n\t{\n\t\tduk_tval *tv_ret;\n\t\tduk_tval *tv_funret;\n\n\t\ttv_ret = thr->valstack_bottom + idx_func;\n\t\ttv_funret = thr->valstack_top - 1;\n#if defined(DUK_USE_FASTINT)\n\t\t/* Explicit check for fastint downgrade. */\n\t\tDUK_TVAL_CHKFAST_INPLACE_FAST(tv_funret);\n#endif\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv_ret, tv_funret);  /* side effects */\n\t}\n\n\tduk_set_top_unsafe(thr, idx_func + 1);\n\n\t/* [ ... retval ] */\n\n\t/* Restore caller's value stack reserve (cannot fail). */\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff >= (duk_uint8_t *) thr->valstack_top);\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff <= (duk_uint8_t *) thr->valstack_alloc_end);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff);\n\n\t/* XXX: Trial value stack shrink would be OK here, but we'd need\n\t * to prevent side effects of the potential realloc.\n\t */\n\n\t/* Restore entry thread executor curr_pc stack frame pointer. */\n\tthr->ptr_curr_pc = entry_ptr_curr_pc;\n\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread);  /* may be NULL */\n\tthr->state = (duk_uint8_t) entry_thread_state;\n\n\t/* Disabled assert: triggered with some torture tests. */\n#if 0\n\tDUK_ASSERT((thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread == NULL) ||  /* first call */\n\t           (thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread != NULL) ||  /* other call */\n\t           (thr->state == DUK_HTHREAD_STATE_RUNNING && thr->heap->curr_thread == thr));     /* current thread */\n#endif\n\n\tthr->heap->call_recursion_depth = entry_call_recursion_depth;\n\n\t/* If the debugger is active we need to force an interrupt so that\n\t * debugger breakpoints are rechecked.  This is important for function\n\t * calls caused by side effects (e.g. when doing a DUK_OP_GETPROP), see\n\t * GH-303.  Only needed for success path, error path always causes a\n\t * breakpoint recheck in the executor.  It would be enough to set this\n\t * only when returning to an ECMAScript activation, but setting the flag\n\t * on every return should have no ill effect.\n\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tDUK_DD(DUK_DDPRINT(\"returning with debugger enabled, force interrupt\"));\n\t\tDUK_ASSERT(thr->interrupt_counter <= thr->interrupt_init);\n\t\tthr->interrupt_init -= thr->interrupt_counter;\n\t\tthr->interrupt_counter = 0;\n\t\tthr->heap->dbg_force_restart = 1;\n\t}\n#endif\n\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\tduk__interrupt_fixup(thr, entry_curr_thread);\n#endif\n\n\t/* Restored by success path. */\n\tDUK_ASSERT(thr->heap->call_recursion_depth == entry_call_recursion_depth);\n\tDUK_ASSERT(thr->ptr_curr_pc == entry_ptr_curr_pc);\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\tDUK_REFZERO_CHECK_FAST(thr);\n\n\treturn 0;  /* 0=call handled inline */\n}\n\nDUK_INTERNAL duk_int_t duk_handle_call_unprotected_nargs(duk_hthread *thr,\n                                                         duk_idx_t nargs,\n                                                         duk_small_uint_t call_flags) {\n\tduk_idx_t idx_func;\n\tDUK_ASSERT(duk_get_top(thr) >= nargs + 2);\n\tidx_func = duk_get_top(thr) - (nargs + 2);\n\tDUK_ASSERT(idx_func >= 0);\n\treturn duk_handle_call_unprotected(thr, idx_func, call_flags);\n}\n\nDUK_INTERNAL duk_int_t duk_handle_call_unprotected(duk_hthread *thr,\n                                                   duk_idx_t idx_func,\n                                                   duk_small_uint_t call_flags) {\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\tDUK_ASSERT(idx_func >= 0);\n\treturn duk__handle_call_raw(thr, idx_func, call_flags);\n}\n\n/*\n *  duk_handle_safe_call(): make a \"C protected call\" within the\n *  current activation.\n *\n *  The allowed thread states for making a call are the same as for\n *  duk_handle_call_protected().\n *\n *  Even though this call is protected, errors are thrown for insane arguments\n *  and may result in a fatal error unless there's another protected call which\n *  catches such errors.\n *\n *  The error handling path should be error free, even for out-of-memory\n *  errors, to ensure safe sandboxing.  (As of Duktape 2.2.0 this is not\n *  yet the case for environment closing which may run out of memory, see\n *  XXX notes below.)\n */\n\nDUK_LOCAL void duk__handle_safe_call_inner(duk_hthread *thr,\n                                           duk_safe_call_function func,\n                                           void *udata,\n#if defined(DUK_USE_ASSERTIONS)\n                                           duk_size_t entry_valstack_bottom_byteoff,\n                                           duk_size_t entry_callstack_top,\n#endif\n                                           duk_hthread *entry_curr_thread,\n                                           duk_uint_fast8_t entry_thread_state,\n                                           duk_idx_t idx_retbase,\n                                           duk_idx_t num_stack_rets) {\n\tduk_ret_t rc;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\t/*\n\t *  Thread state check and book-keeping.\n\t */\n\n\tduk__call_thread_state_update(thr);\n\n\t/*\n\t *  Recursion limit check.\n\t */\n\n\tduk__call_c_recursion_limit_check(thr);\n\tthr->heap->call_recursion_depth++;\n\n\t/*\n\t *  Make the C call.\n\t */\n\n\trc = func(thr, udata);\n\n\tDUK_DDD(DUK_DDDPRINT(\"safe_call, func rc=%ld\", (long) rc));\n\n\t/*\n\t *  Valstack manipulation for results.\n\t */\n\n\t/* we're running inside the caller's activation, so no change in call/catch stack or valstack bottom */\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) == entry_valstack_bottom_byteoff);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\n\tif (DUK_UNLIKELY(rc < 0)) {\n\t\tduk_error_throw_from_negative_rc(thr, rc);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(rc >= 0);\n\n\tduk__safe_call_adjust_valstack(thr, idx_retbase, num_stack_rets, rc);  /* throws for insane rc */\n\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread);  /* may be NULL */\n\tthr->state = (duk_uint8_t) entry_thread_state;\n}\n\nDUK_LOCAL void duk__handle_safe_call_error(duk_hthread *thr,\n                                           duk_activation *entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n                                           duk_size_t entry_callstack_top,\n#endif\n                                           duk_hthread *entry_curr_thread,\n                                           duk_uint_fast8_t entry_thread_state,\n                                           duk_idx_t idx_retbase,\n                                           duk_idx_t num_stack_rets,\n                                           duk_size_t entry_valstack_bottom_byteoff,\n                                           duk_jmpbuf *old_jmpbuf_ptr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\t/*\n\t *  Error during call.  The error value is at heap->lj.value1.\n\t *\n\t *  The very first thing we do is restore the previous setjmp catcher.\n\t *  This means that any error in error handling will propagate outwards\n\t *  instead of causing a setjmp() re-entry above.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"error caught during protected duk_handle_safe_call()\"));\n\n\t/* Other longjmp types are handled by executor before propagating\n\t * the error here.\n\t */\n\tDUK_ASSERT(thr->heap->lj.type == DUK_LJ_TYPE_THROW);\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\n\t/* Either pointer may be NULL (at entry), so don't assert. */\n\tthr->heap->lj.jmpbuf_ptr = old_jmpbuf_ptr;\n\n\t/* XXX: callstack unwind may now throw an error when closing\n\t * scopes; this is a sandboxing issue, described in:\n\t * https://github.com/svaarala/duktape/issues/476\n\t */\n\t/* XXX: \"unwind to\" primitive? */\n\n\tDUK_ASSERT(thr->callstack_top >= entry_callstack_top);\n\twhile (thr->callstack_curr != entry_act) {\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tduk_hthread_activation_unwind_norz(thr);\n\t}\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\n\t/* Switch active thread before any side effects to avoid a\n\t * dangling curr_thread pointer.\n\t */\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread);  /* may be NULL */\n\tthr->state = (duk_uint8_t) entry_thread_state;\n\n\tDUK_ASSERT(thr->heap->curr_thread == entry_curr_thread);\n\tDUK_ASSERT(thr->state == entry_thread_state);\n\n\t/* Restore valstack bottom. */\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_bottom_byteoff);\n\n\t/* [ ... | (crud) ] */\n\n\t/* XXX: ensure space in valstack (now relies on internal reserve)? */\n\tduk_push_tval(thr, &thr->heap->lj.value1);\n\n\t/* [ ... | (crud) errobj ] */\n\n\tDUK_ASSERT(duk_get_top(thr) >= 1);  /* at least errobj must be on stack */\n\n\tduk__safe_call_adjust_valstack(thr, idx_retbase, num_stack_rets, 1);  /* 1 = num actual 'return values' */\n\n\t/* [ ... | ] or [ ... | errobj (M * undefined)] where M = num_stack_rets - 1 */\n\n\t/* Reset longjmp state. */\n\tthr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;\n\tthr->heap->lj.iserror = 0;\n\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, &thr->heap->lj.value1);\n\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, &thr->heap->lj.value2);\n\n\t/* Error handling complete, remove side effect protections.  Caller\n\t * will process pending finalizers.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->heap->error_not_allowed == 1);\n\tthr->heap->error_not_allowed = 0;\n#endif\n\tDUK_ASSERT(thr->heap->pf_prevent_count > 0);\n\tthr->heap->pf_prevent_count--;\n\tDUK_DD(DUK_DDPRINT(\"safe call error handled, pf_prevent_count updated to %ld\", (long) thr->heap->pf_prevent_count));\n\n\t/* thr->ptr_curr_pc is restored by\n\t * duk__handle_safe_call_shared_unwind() which is also used for\n\t * success path.\n\t */\n}\n\nDUK_LOCAL void duk__handle_safe_call_shared_unwind(duk_hthread *thr,\n                                                   duk_idx_t idx_retbase,\n                                                   duk_idx_t num_stack_rets,\n#if defined(DUK_USE_ASSERTIONS)\n                                                   duk_size_t entry_callstack_top,\n#endif\n                                                   duk_int_t entry_call_recursion_depth,\n                                                   duk_hthread *entry_curr_thread,\n                                                   duk_instr_t **entry_ptr_curr_pc) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(idx_retbase);\n\tDUK_UNREF(num_stack_rets);\n\tDUK_UNREF(entry_curr_thread);\n\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\n\t/* Restore entry thread executor curr_pc stack frame pointer.\n\t * XXX: would be enough to do in error path only, should nest\n\t * cleanly in success path.\n\t */\n\tthr->ptr_curr_pc = entry_ptr_curr_pc;\n\n\tthr->heap->call_recursion_depth = entry_call_recursion_depth;\n\n\t/* stack discipline consistency check */\n\tDUK_ASSERT(duk_get_top(thr) == idx_retbase + num_stack_rets);\n\n\t/* A debugger forced interrupt check is not needed here, as\n\t * problematic safe calls are not caused by side effects.\n\t */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\tduk__interrupt_fixup(thr, entry_curr_thread);\n#endif\n}\n\nDUK_INTERNAL duk_int_t duk_handle_safe_call(duk_hthread *thr,\n                                            duk_safe_call_function func,\n                                            void *udata,\n                                            duk_idx_t num_stack_args,\n                                            duk_idx_t num_stack_rets) {\n\tduk_activation *entry_act;\n\tduk_size_t entry_valstack_bottom_byteoff;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_size_t entry_valstack_end_byteoff;\n\tduk_size_t entry_callstack_top;\n\tduk_size_t entry_callstack_preventcount;\n#endif\n\tduk_int_t entry_call_recursion_depth;\n\tduk_hthread *entry_curr_thread;\n\tduk_uint_fast8_t entry_thread_state;\n\tduk_instr_t **entry_ptr_curr_pc;\n\tduk_jmpbuf *old_jmpbuf_ptr = NULL;\n\tduk_jmpbuf our_jmpbuf;\n\tduk_idx_t idx_retbase;\n\tduk_int_t retval;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(duk_get_top(thr) >= num_stack_args);  /* Caller ensures. */\n\n\tDUK_STATS_INC(thr->heap, stats_safecall_all);\n\n\t/* Value stack reserve handling: safe call assumes caller has reserved\n\t * space for nrets (assuming optimal unwind processing).  Value stack\n\t * reserve is not stored/restored as for normal calls because a safe\n\t * call conceptually happens in the same activation.\n\t */\n\n\t/* Careful with indices like '-x'; if 'x' is zero, it refers to bottom */\n\tentry_act = thr->callstack_curr;\n\tentry_valstack_bottom_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_valstack_end_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tentry_callstack_top = thr->callstack_top;\n\tentry_callstack_preventcount = thr->callstack_preventcount;\n#endif\n\tentry_call_recursion_depth = thr->heap->call_recursion_depth;\n\tentry_curr_thread = thr->heap->curr_thread;  /* may be NULL if first call */\n\tentry_thread_state = thr->state;\n\tentry_ptr_curr_pc = thr->ptr_curr_pc;  /* may be NULL */\n\tidx_retbase = duk_get_top(thr) - num_stack_args;  /* not a valid stack index if num_stack_args == 0 */\n\tDUK_ASSERT(idx_retbase >= 0);\n\n\tDUK_ASSERT((duk_idx_t) (thr->valstack_top - thr->valstack_bottom) >= num_stack_args);  /* Caller ensures. */\n\tDUK_ASSERT((duk_idx_t) (thr->valstack_end - (thr->valstack_bottom + idx_retbase)) >= num_stack_rets);  /* Caller ensures. */\n\n\t/* Cannot portably debug print a function pointer, hence 'func' not printed! */\n\tDUK_DD(DUK_DDPRINT(\"duk_handle_safe_call: thr=%p, num_stack_args=%ld, num_stack_rets=%ld, \"\n\t                   \"valstack_top=%ld, idx_retbase=%ld, rec_depth=%ld/%ld, \"\n\t                   \"entry_act=%p, entry_valstack_bottom_byteoff=%ld, entry_call_recursion_depth=%ld, \"\n\t                   \"entry_curr_thread=%p, entry_thread_state=%ld\",\n\t                   (void *) thr,\n\t                   (long) num_stack_args,\n\t                   (long) num_stack_rets,\n\t                   (long) duk_get_top(thr),\n\t                   (long) idx_retbase,\n\t                   (long) thr->heap->call_recursion_depth,\n\t                   (long) thr->heap->call_recursion_limit,\n\t                   (void *) entry_act,\n\t                   (long) entry_valstack_bottom_byteoff,\n\t                   (long) entry_call_recursion_depth,\n\t                   (void *) entry_curr_thread,\n\t                   (long) entry_thread_state));\n\n\t/* Setjmp catchpoint setup. */\n\told_jmpbuf_ptr = thr->heap->lj.jmpbuf_ptr;\n\tthr->heap->lj.jmpbuf_ptr = &our_jmpbuf;\n\n\t/* Prevent yields for the duration of the safe call.  This only\n\t * matters if the executor makes safe calls to functions that\n\t * yield, this doesn't currently happen.\n\t */\n\tthr->callstack_preventcount++;\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\ttry {\n#else\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr == &our_jmpbuf);\n\tif (DUK_SETJMP(our_jmpbuf.jb) == 0) {\n\t\t/* Success path. */\n#endif\n\t\tDUK_DDD(DUK_DDDPRINT(\"safe_call setjmp catchpoint setup complete\"));\n\n\t\tduk__handle_safe_call_inner(thr,\n\t\t                            func,\n\t\t                            udata,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t                            entry_valstack_bottom_byteoff,\n\t\t                            entry_callstack_top,\n#endif\n\t\t                            entry_curr_thread,\n\t\t                            entry_thread_state,\n\t\t                            idx_retbase,\n\t\t                            num_stack_rets);\n\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_nothrow);\n\n\t\t/* Either pointer may be NULL (at entry), so don't assert */\n\t\tthr->heap->lj.jmpbuf_ptr = old_jmpbuf_ptr;\n\n\t\t/* If calls happen inside the safe call, these are restored by\n\t\t * whatever calls are made.  Reserve cannot decrease.\n\t\t */\n\t\tDUK_ASSERT(thr->callstack_curr == entry_act);\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\n\t\tretval = DUK_EXEC_SUCCESS;\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t} catch (duk_internal_exception &exc) {\n\t\tDUK_UNREF(exc);\n#else\n\t} else {\n\t\t/* Error path. */\n#endif\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_throw);\n\n\t\tduk__handle_safe_call_error(thr,\n\t\t                            entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t                            entry_callstack_top,\n#endif\n\t\t                            entry_curr_thread,\n\t\t                            entry_thread_state,\n\t\t                            idx_retbase,\n\t\t                            num_stack_rets,\n\t\t                            entry_valstack_bottom_byteoff,\n\t\t                            old_jmpbuf_ptr);\n\n\t\tretval = DUK_EXEC_ERROR;\n\t}\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\tcatch (duk_fatal_exception &exc) {\n\t\tDUK_D(DUK_DPRINT(\"rethrow duk_fatal_exception\"));\n\t\tthrow;\n\t} catch (std::exception &exc) {\n\t\tconst char *what = exc.what();\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_throw);\n\t\tif (!what) {\n\t\t\twhat = \"unknown\";\n\t\t}\n\t\tDUK_D(DUK_DPRINT(\"unexpected c++ std::exception (perhaps thrown by user code)\"));\n\t\ttry {\n\t\t\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"caught invalid c++ std::exception '%s' (perhaps thrown by user code)\", what);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t} catch (duk_internal_exception exc) {\n\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ std::exception\"));\n\t\t\tDUK_UNREF(exc);\n\t\t\tduk__handle_safe_call_error(thr,\n\t\t\t                            entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t                            entry_callstack_top,\n#endif\n\t\t\t                            entry_curr_thread,\n\t\t\t                            entry_thread_state,\n\t\t\t                            idx_retbase,\n\t\t\t                            num_stack_rets,\n\t\t\t                            entry_valstack_bottom_byteoff,\n\t\t\t                            old_jmpbuf_ptr);\n\t\t\tretval = DUK_EXEC_ERROR;\n\t\t}\n\t} catch (...) {\n\t\tDUK_D(DUK_DPRINT(\"unexpected c++ exception (perhaps thrown by user code)\"));\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_throw);\n\t\ttry {\n\t\t\tDUK_ERROR_TYPE(thr, \"caught invalid c++ exception (perhaps thrown by user code)\");\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t} catch (duk_internal_exception exc) {\n\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ exception\"));\n\t\t\tDUK_UNREF(exc);\n\t\t\tduk__handle_safe_call_error(thr,\n\t\t\t                            entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t                            entry_callstack_top,\n#endif\n\t\t\t                            entry_curr_thread,\n\t\t\t                            entry_thread_state,\n\t\t\t                            idx_retbase,\n\t\t\t                            num_stack_rets,\n\t\t\t                            entry_valstack_bottom_byteoff,\n\t\t\t                            old_jmpbuf_ptr);\n\t\t\tretval = DUK_EXEC_ERROR;\n\t\t}\n\t}\n#endif\n\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr == old_jmpbuf_ptr);  /* success/error path both do this */\n\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\tduk__handle_safe_call_shared_unwind(thr,\n\t                                    idx_retbase,\n\t                                    num_stack_rets,\n#if defined(DUK_USE_ASSERTIONS)\n\t                                    entry_callstack_top,\n#endif\n\t                                    entry_call_recursion_depth,\n\t                                    entry_curr_thread,\n\t                                    entry_ptr_curr_pc);\n\n\t/* Restore preventcount. */\n\tthr->callstack_preventcount--;\n\tDUK_ASSERT(thr->callstack_preventcount == entry_callstack_preventcount);\n\n\t/* Final asserts. */\n\tDUK_ASSERT(thr->callstack_curr == entry_act);\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) == entry_valstack_bottom_byteoff);\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\tDUK_ASSERT(thr->heap->call_recursion_depth == entry_call_recursion_depth);\n\tDUK_ASSERT(thr->heap->curr_thread == entry_curr_thread);\n\tDUK_ASSERT(thr->state == entry_thread_state);\n\tDUK_ASSERT(thr->ptr_curr_pc == entry_ptr_curr_pc);\n\tDUK_ASSERT(duk_get_top(thr) == idx_retbase + num_stack_rets);\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\t/* Pending side effects. */\n\tDUK_REFZERO_CHECK_FAST(thr);\n\n\treturn retval;\n}\n\n/*\n *  Property-based call (foo.noSuch()) error setup: replace target function\n *  on stack top with a hidden Symbol tagged non-callable wrapper object\n *  holding the error.  The error gets thrown in call handling at the\n *  proper spot to follow ECMAScript semantics.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_INTERNAL DUK_NOINLINE DUK_COLD void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_base, duk_tval *tv_key) {\n\tconst char *str_targ, *str_key, *str_base;\n\tduk_idx_t entry_top;\n\n\tentry_top = duk_get_top(thr);\n\n\t/* [ <nargs> target ] */\n\n\t/* Must stabilize pointers first.  tv_targ is already on stack top. */\n\tduk_push_tval(thr, tv_base);\n\tduk_push_tval(thr, tv_key);\n\n\tDUK_GC_TORTURE(thr->heap);\n\n\tduk_push_bare_object(thr);\n\n\t/* [ <nargs> target base key {} ] */\n\n\t/* We only push a wrapped error, replacing the call target (at\n\t * idx_func) with the error to ensure side effects come out\n\t * correctly:\n\t * - Property read\n\t * - Call argument evaluation\n\t * - Callability check and error thrown\n\t *\n\t * A hidden Symbol on the wrapper object pushed above is used by\n\t * call handling to figure out the error is to be thrown as is.\n\t * It is CRITICAL that the hidden Symbol can never occur on a\n\t * user visible object that may get thrown.\n\t */\n\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tstr_targ = duk_get_type_name(thr, -4);\n\tstr_key = duk_get_type_name(thr, -2);\n\tstr_base = duk_get_type_name(thr, -3);\n\tduk_push_error_object(thr,\n\t                      DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t                      \"%s not callable (property %s of %s)\", str_targ, str_key, str_base);\n\tduk_xdef_prop_stridx(thr, -2, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE);  /* Marker property, reuse _Target. */\n\t/* [ <nargs> target base key { _Target: error } ] */\n\tduk_replace(thr, entry_top - 1);\n#else\n\tstr_targ = duk_push_string_readable(thr, -4);\n\tstr_key = duk_push_string_readable(thr, -3);\n\tstr_base = duk_push_string_readable(thr, -5);\n\tduk_push_error_object(thr,\n\t                      DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t                      \"%s not callable (property %s of %s)\", str_targ, str_key, str_base);\n\t/* [ <nargs> target base key {} str_targ str_key str_base error ] */\n\tduk_xdef_prop_stridx(thr, -5, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE);  /* Marker property, reuse _Target. */\n\t/* [ <nargs> target base key { _Target: error } str_targ str_key str_base ] */\n\tduk_swap(thr, -4, entry_top - 1);\n\t/* [ <nargs> { _Target: error } base key target str_targ str_key str_base ] */\n#endif\n\n\t/* [ <nregs> { _Target: error } <variable> */\n\tduk_set_top(thr, entry_top);\n\n\t/* [ <nregs> { _Target: error } */\n\tDUK_ASSERT(!duk_is_callable(thr, -1));  /* Critical so that call handling will throw the error. */\n}\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n/* automatic undefs */\n#undef DUK__AUGMENT_CALL_RELAX_COUNT\n#undef DUK__CALL_HANDLING_REQUIRE_STACK\n#line 1 \"duk_js_compiler.c\"\n/*\n *  ECMAScript compiler.\n *\n *  Parses an input string and generates a function template result.\n *  Compilation may happen in multiple contexts (global code, eval\n *  code, function code).\n *\n *  The parser uses a traditional top-down recursive parsing for the\n *  statement level, and an operator precedence based top-down approach\n *  for the expression level.  The attempt is to minimize the C stack\n *  depth.  Bytecode is generated directly without an intermediate\n *  representation (tree), at the cost of needing two (and sometimes\n *  three) passes over each function.\n *\n *  The top-down recursive parser functions are named \"duk__parse_XXX\".\n *\n *  Recursion limits are in key functions to prevent arbitrary C recursion:\n *  function body parsing, statement parsing, and expression parsing.\n *\n *  See doc/compiler.rst for discussion on the design.\n *\n *  A few typing notes:\n *\n *    - duk_regconst_t: signed, highest bit set (< 0) means constant,\n *      some call sites use -1 for \"none\" (equivalent to constant 0x7fffffff)\n *    - PC values: duk_int_t, negative values used as markers\n */\n\n/* #include duk_internal.h -> already included */\n\n/* If highest bit of a register number is set, it refers to a constant instead.\n * When interpreted as a signed value, this means const values are always\n * negative (when interpreted as two's complement).  For example DUK__ISREG_TEMP()\n * uses this approach to avoid an explicit DUK__ISREG() check (the condition is\n * logically \"'x' is a register AND 'x' >= temp_first\").\n */\n#define DUK__CONST_MARKER                   DUK_REGCONST_CONST_MARKER\n#define DUK__REMOVECONST(x)                 ((x) & ~DUK__CONST_MARKER)\n#define DUK__ISREG(x)                       ((x) >= 0)\n#define DUK__ISCONST(x)                     ((x) < 0)\n#define DUK__ISREG_TEMP(comp_ctx,x)         ((duk_int32_t) (x) >= (duk_int32_t) ((comp_ctx)->curr_func.temp_first))   /* Check for x >= temp_first && x >= 0 by comparing as signed. */\n#define DUK__ISREG_NOTTEMP(comp_ctx,x)      ((duk_uint32_t) (x) < (duk_uint32_t) ((comp_ctx)->curr_func.temp_first))  /* Check for x >= 0 && x < temp_first by interpreting as unsigned. */\n#define DUK__GETTEMP(comp_ctx)              ((comp_ctx)->curr_func.temp_next)\n#define DUK__SETTEMP(comp_ctx,x)            ((comp_ctx)->curr_func.temp_next = (x))  /* dangerous: must only lower (temp_max not updated) */\n#define DUK__SETTEMP_CHECKMAX(comp_ctx,x)   duk__settemp_checkmax((comp_ctx),(x))\n#define DUK__ALLOCTEMP(comp_ctx)            duk__alloctemp((comp_ctx))\n#define DUK__ALLOCTEMPS(comp_ctx,count)     duk__alloctemps((comp_ctx),(count))\n\n/* Init value set size for array and object literals. */\n#define DUK__MAX_ARRAY_INIT_VALUES        20\n#define DUK__MAX_OBJECT_INIT_PAIRS        10\n\n/* XXX: hack, remove when const lookup is not O(n) */\n#define DUK__GETCONST_MAX_CONSTS_CHECK    256\n\n/* These limits are based on bytecode limits.  Max temps is limited\n * by duk_hcompfunc nargs/nregs fields being 16 bits.\n */\n#define DUK__MAX_CONSTS                   DUK_BC_BC_MAX\n#define DUK__MAX_FUNCS                    DUK_BC_BC_MAX\n#define DUK__MAX_TEMPS                    0xffffL\n\n/* Initial bytecode size allocation. */\n#if defined(DUK_USE_PREFER_SIZE)\n#define DUK__BC_INITIAL_INSTS             16\n#else\n#define DUK__BC_INITIAL_INSTS             256\n#endif\n\n#define DUK__RECURSION_INCREASE(comp_ctx,thr)  do { \\\n\t\tDUK_DDD(DUK_DDDPRINT(\"RECURSION INCREASE: %s:%ld\", (const char *) DUK_FILE_MACRO, (long) DUK_LINE_MACRO)); \\\n\t\tduk__comp_recursion_increase((comp_ctx)); \\\n\t} while (0)\n\n#define DUK__RECURSION_DECREASE(comp_ctx,thr)  do { \\\n\t\tDUK_DDD(DUK_DDDPRINT(\"RECURSION DECREASE: %s:%ld\", (const char *) DUK_FILE_MACRO, (long) DUK_LINE_MACRO)); \\\n\t\tduk__comp_recursion_decrease((comp_ctx)); \\\n\t} while (0)\n\n/* Value stack slot limits: these are quite approximate right now, and\n * because they overlap in control flow, some could be eliminated.\n */\n#define DUK__COMPILE_ENTRY_SLOTS          8\n#define DUK__FUNCTION_INIT_REQUIRE_SLOTS  16\n#define DUK__FUNCTION_BODY_REQUIRE_SLOTS  16\n#define DUK__PARSE_STATEMENTS_SLOTS       16\n#define DUK__PARSE_EXPR_SLOTS             16\n\n/* Temporary structure used to pass a stack allocated region through\n * duk_safe_call().\n */\ntypedef struct {\n\tduk_small_uint_t flags;\n\tduk_compiler_ctx comp_ctx_alloc;\n\tduk_lexer_point lex_pt_alloc;\n} duk__compiler_stkstate;\n\n/*\n *  Prototypes\n */\n\n/* lexing */\nDUK_LOCAL_DECL void duk__advance_helper(duk_compiler_ctx *comp_ctx, duk_small_int_t expect);\nDUK_LOCAL_DECL void duk__advance_expect(duk_compiler_ctx *comp_ctx, duk_small_int_t expect);\nDUK_LOCAL_DECL void duk__advance(duk_compiler_ctx *ctx);\n\n/* function helpers */\nDUK_LOCAL_DECL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ctx, duk_regconst_t *out_stmt_value_reg);\nDUK_LOCAL_DECL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx);\n\n/* code emission */\nDUK_LOCAL_DECL duk_int_t duk__get_current_pc(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_compiler_instr *duk__get_instr_ptr(duk_compiler_ctx *comp_ctx, duk_int_t pc);\nDUK_LOCAL_DECL void duk__emit(duk_compiler_ctx *comp_ctx, duk_instr_t ins);\nDUK_LOCAL_DECL void duk__emit_op_only(duk_compiler_ctx *comp_ctx, duk_small_uint_t op);\nDUK_LOCAL_DECL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b, duk_regconst_t c);\nDUK_LOCAL_DECL void duk__emit_a_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b);\nDUK_LOCAL_DECL void duk__emit_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b, duk_regconst_t c);\n#if 0  /* unused */\nDUK_LOCAL_DECL void duk__emit_a(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a);\nDUK_LOCAL_DECL void duk__emit_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b);\n#endif\nDUK_LOCAL_DECL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t bc);\nDUK_LOCAL_DECL void duk__emit_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t bc);\nDUK_LOCAL_DECL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t abc);\nDUK_LOCAL_DECL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val);\nDUK_LOCAL_DECL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val);\nDUK_LOCAL_DECL void duk__emit_jump(duk_compiler_ctx *comp_ctx, duk_int_t target_pc);\nDUK_LOCAL_DECL duk_int_t duk__emit_jump_empty(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc);\nDUK_LOCAL_DECL void duk__patch_jump(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc, duk_int_t target_pc);\nDUK_LOCAL_DECL void duk__patch_jump_here(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc);\nDUK_LOCAL_DECL void duk__patch_trycatch(duk_compiler_ctx *comp_ctx, duk_int_t ldconst_pc, duk_int_t trycatch_pc, duk_regconst_t reg_catch, duk_regconst_t const_varname, duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__emit_if_false_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst);\nDUK_LOCAL_DECL void duk__emit_if_true_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst);\nDUK_LOCAL_DECL void duk__emit_invalid(duk_compiler_ctx *comp_ctx);\n\n/* ivalue/ispec helpers */\nDUK_LOCAL_DECL void duk__ivalue_regconst(duk_ivalue *x, duk_regconst_t regconst);\nDUK_LOCAL_DECL void duk__ivalue_plain_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL void duk__ivalue_var_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL void duk__ivalue_var_hstring(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_hstring *h);\nDUK_LOCAL_DECL void duk__copy_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *src, duk_ispec *dst);\nDUK_LOCAL_DECL void duk__copy_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *src, duk_ivalue *dst);\nDUK_LOCAL_DECL duk_regconst_t duk__alloctemps(duk_compiler_ctx *comp_ctx, duk_small_int_t num);\nDUK_LOCAL_DECL duk_regconst_t duk__alloctemp(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, duk_regconst_t temp_next);\nDUK_LOCAL_DECL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL\nduk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                         duk_ispec *x,\n                                         duk_regconst_t forced_reg,\n                                         duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ispec *x, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL void duk__ivalue_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL void duk__ivalue_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL\nduk_regconst_t duk__ivalue_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                          duk_ivalue *x,\n                                          duk_regconst_t forced_reg,\n                                          duk_small_uint_t flags);\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\n#endif\nDUK_LOCAL_DECL void duk__ivalue_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_int_t forced_reg);\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\n\n/* identifier handling */\nDUK_LOCAL_DECL duk_regconst_t duk__lookup_active_register_binding(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *ctx, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname);\n\n/* label handling */\nDUK_LOCAL_DECL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_int_t pc_label, duk_int_t label_id);\nDUK_LOCAL_DECL void duk__update_label_flags(duk_compiler_ctx *comp_ctx, duk_int_t label_id, duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_bool_t is_break, duk_int_t *out_label_id, duk_int_t *out_label_catch_depth, duk_int_t *out_label_pc, duk_bool_t *out_is_closest);\nDUK_LOCAL_DECL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, duk_size_t len);\n\n/* top-down expression parser */\nDUK_LOCAL_DECL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_ivalue *res);\nDUK_LOCAL_DECL duk_small_uint_t duk__expr_lbp(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_bool_t duk__expr_is_empty(duk_compiler_ctx *comp_ctx);\n\n/* exprtop is the top level variant which resets nud/led counts */\nDUK_LOCAL_DECL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\nDUK_LOCAL_DECL void duk__exprtop(duk_compiler_ctx *ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n\n/* convenience helpers */\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__expr_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__expr_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\nDUK_LOCAL_DECL void duk__expr_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL duk_regconst_t duk__expr_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__expr_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\nDUK_LOCAL_DECL void duk__expr_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\nDUK_LOCAL_DECL void duk__expr_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\nDUK_LOCAL_DECL duk_regconst_t duk__exprtop_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__exprtop_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\nDUK_LOCAL_DECL void duk__exprtop_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL duk_regconst_t duk__exprtop_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#if 0  /* unused */\nDUK_LOCAL_DECL void duk__exprtop_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\n\n/* expression parsing helpers */\nDUK_LOCAL_DECL duk_int_t duk__parse_arguments(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\n\n/* statement parsing */\nDUK_LOCAL_DECL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname);\nDUK_LOCAL_DECL void duk__parse_var_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags);\nDUK_LOCAL_DECL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_if_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_do_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_while_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_break_or_continue_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_throw_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_bool_t allow_source_elem);\nDUK_LOCAL_DECL duk_int_t duk__stmt_label_site(duk_compiler_ctx *comp_ctx, duk_int_t label_id);\nDUK_LOCAL_DECL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_source_elem, duk_bool_t expect_eof, duk_bool_t regexp_after);\n\nDUK_LOCAL_DECL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expect_eof, duk_bool_t implicit_return_value, duk_bool_t regexp_after, duk_small_int_t expect_token);\nDUK_LOCAL_DECL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags);\nDUK_LOCAL_DECL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags);\n\n#define DUK__FUNC_FLAG_DECL            (1 << 0)   /* Parsing a function declaration. */\n#define DUK__FUNC_FLAG_GETSET          (1 << 1)   /* Parsing an object literal getter/setter. */\n#define DUK__FUNC_FLAG_METDEF          (1 << 2)   /* Parsing an object literal method definition shorthand. */\n#define DUK__FUNC_FLAG_PUSHNAME_PASS1  (1 << 3)   /* Push function name when creating template (first pass only). */\n#define DUK__FUNC_FLAG_USE_PREVTOKEN   (1 << 4)   /* Use prev_token to start function parsing (workaround for object literal). */\n\n/*\n *  Parser control values for tokens.  The token table is ordered by the\n *  DUK_TOK_XXX defines.\n *\n *  The binding powers are for lbp() use (i.e. for use in led() context).\n *  Binding powers are positive for typing convenience, and bits at the\n *  top should be reserved for flags.  Binding power step must be higher\n *  than 1 so that binding power \"lbp - 1\" can be used for right associative\n *  operators.  Currently a step of 2 is used (which frees one more bit for\n *  flags).\n */\n\n/* XXX: actually single step levels would work just fine, clean up */\n\n/* binding power \"levels\" (see doc/compiler.rst) */\n#define DUK__BP_INVALID                0             /* always terminates led() */\n#define DUK__BP_EOF                    2\n#define DUK__BP_CLOSING                4             /* token closes expression, e.g. ')', ']' */\n#define DUK__BP_FOR_EXPR               DUK__BP_CLOSING    /* bp to use when parsing a top level Expression */\n#define DUK__BP_COMMA                  6\n#define DUK__BP_ASSIGNMENT             8\n#define DUK__BP_CONDITIONAL            10\n#define DUK__BP_LOR                    12\n#define DUK__BP_LAND                   14\n#define DUK__BP_BOR                    16\n#define DUK__BP_BXOR                   18\n#define DUK__BP_BAND                   20\n#define DUK__BP_EQUALITY               22\n#define DUK__BP_RELATIONAL             24\n#define DUK__BP_SHIFT                  26\n#define DUK__BP_ADDITIVE               28\n#define DUK__BP_MULTIPLICATIVE         30\n#define DUK__BP_EXPONENTIATION         32\n#define DUK__BP_POSTFIX                34\n#define DUK__BP_CALL                   36\n#define DUK__BP_MEMBER                 38\n\n#define DUK__TOKEN_LBP_BP_MASK         0x1f\n#define DUK__TOKEN_LBP_FLAG_NO_REGEXP  (1 << 5)   /* regexp literal must not follow this token */\n#define DUK__TOKEN_LBP_FLAG_TERMINATES (1 << 6)   /* terminates expression; e.g. post-increment/-decrement */\n#define DUK__TOKEN_LBP_FLAG_UNUSED     (1 << 7)   /* unused */\n\n#define DUK__TOKEN_LBP_GET_BP(x)       ((duk_small_uint_t) (((x) & DUK__TOKEN_LBP_BP_MASK) * 2))\n\n#define DUK__MK_LBP(bp)                ((bp) >> 1)    /* bp is assumed to be even */\n#define DUK__MK_LBP_FLAGS(bp,flags)    (((bp) >> 1) | (flags))\n\nDUK_LOCAL const duk_uint8_t duk__token_lbp[] = {\n\tDUK__MK_LBP(DUK__BP_EOF),                                 /* DUK_TOK_EOF */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_IDENTIFIER */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_BREAK */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CASE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CATCH */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CONTINUE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DEBUGGER */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DEFAULT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DELETE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DO */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_ELSE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_FINALLY */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_FOR */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_FUNCTION */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_IF */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_IN */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_INSTANCEOF */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_NEW */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_RETURN */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SWITCH */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_THIS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_THROW */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_TRY */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_TYPEOF */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_VAR */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CONST */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_VOID */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_WHILE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_WITH */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CLASS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_ENUM */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_EXPORT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_EXTENDS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_IMPORT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SUPER */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_NULL */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_TRUE */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_FALSE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_GET */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SET */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_IMPLEMENTS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_INTERFACE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_LET */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PACKAGE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PRIVATE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PROTECTED */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PUBLIC */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_STATIC */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_YIELD */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_LCURLY */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_RCURLY */\n\tDUK__MK_LBP(DUK__BP_MEMBER),                              /* DUK_TOK_LBRACKET */\n\tDUK__MK_LBP_FLAGS(DUK__BP_CLOSING, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_RBRACKET */\n\tDUK__MK_LBP(DUK__BP_CALL),                                /* DUK_TOK_LPAREN */\n\tDUK__MK_LBP_FLAGS(DUK__BP_CLOSING, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_RPAREN */\n\tDUK__MK_LBP(DUK__BP_MEMBER),                              /* DUK_TOK_PERIOD */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SEMICOLON */\n\tDUK__MK_LBP(DUK__BP_COMMA),                               /* DUK_TOK_COMMA */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_LT */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_GT */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_LE */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_GE */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_EQ */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_NEQ */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_SEQ */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_SNEQ */\n\tDUK__MK_LBP(DUK__BP_ADDITIVE),                            /* DUK_TOK_ADD */\n\tDUK__MK_LBP(DUK__BP_ADDITIVE),                            /* DUK_TOK_SUB */\n\tDUK__MK_LBP(DUK__BP_MULTIPLICATIVE),                      /* DUK_TOK_MUL */\n\tDUK__MK_LBP(DUK__BP_MULTIPLICATIVE),                      /* DUK_TOK_DIV */\n\tDUK__MK_LBP(DUK__BP_MULTIPLICATIVE),                      /* DUK_TOK_MOD */\n\tDUK__MK_LBP(DUK__BP_EXPONENTIATION),                      /* DUK_TOK_EXP */\n\tDUK__MK_LBP_FLAGS(DUK__BP_POSTFIX, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_INCREMENT */\n\tDUK__MK_LBP_FLAGS(DUK__BP_POSTFIX, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_DECREMENT */\n\tDUK__MK_LBP(DUK__BP_SHIFT),                               /* DUK_TOK_ALSHIFT */\n\tDUK__MK_LBP(DUK__BP_SHIFT),                               /* DUK_TOK_ARSHIFT */\n\tDUK__MK_LBP(DUK__BP_SHIFT),                               /* DUK_TOK_RSHIFT */\n\tDUK__MK_LBP(DUK__BP_BAND),                                /* DUK_TOK_BAND */\n\tDUK__MK_LBP(DUK__BP_BOR),                                 /* DUK_TOK_BOR */\n\tDUK__MK_LBP(DUK__BP_BXOR),                                /* DUK_TOK_BXOR */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_LNOT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_BNOT */\n\tDUK__MK_LBP(DUK__BP_LAND),                                /* DUK_TOK_LAND */\n\tDUK__MK_LBP(DUK__BP_LOR),                                 /* DUK_TOK_LOR */\n\tDUK__MK_LBP(DUK__BP_CONDITIONAL),                         /* DUK_TOK_QUESTION */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_COLON */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_EQUALSIGN */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_ADD_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_SUB_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_MUL_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_DIV_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_MOD_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_EXP_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_ALSHIFT_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_ARSHIFT_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_RSHIFT_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_BAND_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_BOR_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_BXOR_EQ */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_NUMBER */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_STRING */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_REGEXP */\n};\n\n/*\n *  Misc helpers\n */\n\nDUK_LOCAL void duk__comp_recursion_increase(duk_compiler_ctx *comp_ctx) {\n\tDUK_ASSERT(comp_ctx != NULL);\n\tDUK_ASSERT(comp_ctx->recursion_depth >= 0);\n\tif (comp_ctx->recursion_depth >= comp_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_COMPILER_RECURSION_LIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tcomp_ctx->recursion_depth++;\n}\n\nDUK_LOCAL void duk__comp_recursion_decrease(duk_compiler_ctx *comp_ctx) {\n\tDUK_ASSERT(comp_ctx != NULL);\n\tDUK_ASSERT(comp_ctx->recursion_depth > 0);\n\tcomp_ctx->recursion_depth--;\n}\n\nDUK_LOCAL duk_bool_t duk__hstring_is_eval_or_arguments(duk_compiler_ctx *comp_ctx, duk_hstring *h) {\n\tDUK_UNREF(comp_ctx);\n\tDUK_ASSERT(h != NULL);\n\treturn DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(h);\n}\n\nDUK_LOCAL duk_bool_t duk__hstring_is_eval_or_arguments_in_strict_mode(duk_compiler_ctx *comp_ctx, duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n\treturn (comp_ctx->curr_func.is_strict &&\n\t        DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(h));\n}\n\n/*\n *  Parser duk__advance() token eating functions\n */\n\n/* XXX: valstack handling is awkward.  Add a valstack helper which\n * avoids dup():ing; valstack_copy(src, dst)?\n */\n\nDUK_LOCAL void duk__advance_helper(duk_compiler_ctx *comp_ctx, duk_small_int_t expect) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t regexp;\n\n\tDUK_ASSERT_DISABLE(comp_ctx->curr_token.t >= 0);  /* unsigned */\n\tDUK_ASSERT(comp_ctx->curr_token.t <= DUK_TOK_MAXVAL);  /* MAXVAL is inclusive */\n\n\t/*\n\t *  Use current token to decide whether a RegExp can follow.\n\t *\n\t *  We can use either 't' or 't_nores'; the latter would not\n\t *  recognize keywords.  Some keywords can be followed by a\n\t *  RegExp (e.g. \"return\"), so using 't' is better.  This is\n\t *  not trivial, see doc/compiler.rst.\n\t */\n\n\tregexp = 1;\n\tif (duk__token_lbp[comp_ctx->curr_token.t] & DUK__TOKEN_LBP_FLAG_NO_REGEXP) {\n\t\tregexp = 0;\n\t}\n\tif (comp_ctx->curr_func.reject_regexp_in_adv) {\n\t\tcomp_ctx->curr_func.reject_regexp_in_adv = 0;\n\t\tregexp = 0;\n\t}\n\tif (comp_ctx->curr_func.allow_regexp_in_adv) {\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 0;\n\t\tregexp = 1;\n\t}\n\n\tif (expect >= 0 && comp_ctx->curr_token.t != (duk_small_uint_t) expect) {\n\t\tDUK_D(DUK_DPRINT(\"parse error: expect=%ld, got=%ld\",\n\t\t                 (long) expect, (long) comp_ctx->curr_token.t));\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* make current token the previous; need to fiddle with valstack \"backing store\" */\n\tduk_memcpy(&comp_ctx->prev_token, &comp_ctx->curr_token, sizeof(duk_token));\n\tduk_copy(thr, comp_ctx->tok11_idx, comp_ctx->tok21_idx);\n\tduk_copy(thr, comp_ctx->tok12_idx, comp_ctx->tok22_idx);\n\n\t/* parse new token */\n\tduk_lexer_parse_js_input_element(&comp_ctx->lex,\n\t                                 &comp_ctx->curr_token,\n\t                                 comp_ctx->curr_func.is_strict,\n\t                                 regexp);\n\n\tDUK_DDD(DUK_DDDPRINT(\"advance: curr: tok=%ld/%ld,%ld,term=%ld,%!T,%!T \"\n\t                     \"prev: tok=%ld/%ld,%ld,term=%ld,%!T,%!T\",\n\t                     (long) comp_ctx->curr_token.t,\n\t                     (long) comp_ctx->curr_token.t_nores,\n\t                     (long) comp_ctx->curr_token.start_line,\n\t                     (long) comp_ctx->curr_token.lineterm,\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok11_idx),\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok12_idx),\n\t                     (long) comp_ctx->prev_token.t,\n\t                     (long) comp_ctx->prev_token.t_nores,\n\t                     (long) comp_ctx->prev_token.start_line,\n\t                     (long) comp_ctx->prev_token.lineterm,\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok21_idx),\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok22_idx)));\n}\n\n/* advance, expecting current token to be a specific token; parse next token in regexp context */\nDUK_LOCAL void duk__advance_expect(duk_compiler_ctx *comp_ctx, duk_small_int_t expect) {\n\tduk__advance_helper(comp_ctx, expect);\n}\n\n/* advance, whatever the current token is; parse next token in regexp context */\nDUK_LOCAL void duk__advance(duk_compiler_ctx *comp_ctx) {\n\tduk__advance_helper(comp_ctx, -1);\n}\n\n/*\n *  Helpers for duk_compiler_func.\n */\n\n/* init function state: inits valstack allocations */\nDUK_LOCAL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func = &comp_ctx->curr_func;\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_idx_t entry_top;\n\n\tentry_top = duk_get_top(thr);\n\n\tduk_memzero(func, sizeof(*func));  /* intentional overlap with earlier memzero */\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tfunc->h_name = NULL;\n\tfunc->h_consts = NULL;\n\tfunc->h_funcs = NULL;\n\tfunc->h_decls = NULL;\n\tfunc->h_labelnames = NULL;\n\tfunc->h_labelinfos = NULL;\n\tfunc->h_argnames = NULL;\n\tfunc->h_varmap = NULL;\n#endif\n\n\tduk_require_stack(thr, DUK__FUNCTION_INIT_REQUIRE_SLOTS);\n\n\tDUK_BW_INIT_PUSHBUF(thr, &func->bw_code, DUK__BC_INITIAL_INSTS * sizeof(duk_compiler_instr));\n\t/* code_idx = entry_top + 0 */\n\n\tduk_push_bare_array(thr);\n\tfunc->consts_idx = entry_top + 1;\n\tfunc->h_consts = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 1);\n\tDUK_ASSERT(func->h_consts != NULL);\n\n\tduk_push_bare_array(thr);\n\tfunc->funcs_idx = entry_top + 2;\n\tfunc->h_funcs = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 2);\n\tDUK_ASSERT(func->h_funcs != NULL);\n\tDUK_ASSERT(func->fnum_next == 0);\n\n\tduk_push_bare_array(thr);\n\tfunc->decls_idx = entry_top + 3;\n\tfunc->h_decls = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 3);\n\tDUK_ASSERT(func->h_decls != NULL);\n\n\tduk_push_bare_array(thr);\n\tfunc->labelnames_idx = entry_top + 4;\n\tfunc->h_labelnames = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 4);\n\tDUK_ASSERT(func->h_labelnames != NULL);\n\n\tduk_push_dynamic_buffer(thr, 0);\n\tfunc->labelinfos_idx = entry_top + 5;\n\tfunc->h_labelinfos = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, entry_top + 5);\n\tDUK_ASSERT(func->h_labelinfos != NULL);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(func->h_labelinfos) && !DUK_HBUFFER_HAS_EXTERNAL(func->h_labelinfos));\n\n\tduk_push_bare_array(thr);\n\tfunc->argnames_idx = entry_top + 6;\n\tfunc->h_argnames = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 6);\n\tDUK_ASSERT(func->h_argnames != NULL);\n\n\tduk_push_bare_object(thr);\n\tfunc->varmap_idx = entry_top + 7;\n\tfunc->h_varmap = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 7);\n\tDUK_ASSERT(func->h_varmap != NULL);\n}\n\n/* reset function state (prepare for pass 2) */\nDUK_LOCAL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func = &comp_ctx->curr_func;\n\tduk_hthread *thr = comp_ctx->thr;\n\n\t/* reset bytecode buffer but keep current size; pass 2 will\n\t * require same amount or more.\n\t */\n\tDUK_BW_RESET_SIZE(thr, &func->bw_code);\n\n\tduk_set_length(thr, func->consts_idx, 0);\n\t/* keep func->h_funcs; inner functions are not reparsed to avoid O(depth^2) parsing */\n\tfunc->fnum_next = 0;\n\t/* duk_set_length(thr, func->funcs_idx, 0); */\n\tduk_set_length(thr, func->labelnames_idx, 0);\n\tduk_hbuffer_reset(thr, func->h_labelinfos);\n\t/* keep func->h_argnames; it is fixed for all passes */\n\n\t/* truncated in case pass 3 needed */\n\tduk_push_bare_object(thr);\n\tduk_replace(thr, func->varmap_idx);\n\tfunc->h_varmap = DUK_GET_HOBJECT_POSIDX(thr, func->varmap_idx);\n\tDUK_ASSERT(func->h_varmap != NULL);\n}\n\n/* cleanup varmap from any null entries, compact it, etc; returns number\n * of final entries after cleanup.\n */\nDUK_LOCAL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hobject *h_varmap;\n\tduk_hstring *h_key;\n\tduk_tval *tv;\n\tduk_uint32_t i, e_next;\n\tduk_int_t ret;\n\n\t/* [ ... varmap ] */\n\n\th_varmap = DUK_GET_HOBJECT_NEGIDX(thr, -1);\n\tDUK_ASSERT(h_varmap != NULL);\n\n\tret = 0;\n\te_next = DUK_HOBJECT_GET_ENEXT(h_varmap);\n\tfor (i = 0; i < e_next; i++) {\n\t\th_key = DUK_HOBJECT_E_GET_KEY(thr->heap, h_varmap, i);\n\t\tif (!h_key) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, h_varmap, i));\n\n\t\t/* The entries can either be register numbers or 'null' values.\n\t\t * Thus, no need to DECREF them and get side effects.  DECREF'ing\n\t\t * the keys (strings) can cause memory to be freed but no side\n\t\t * effects as strings don't have finalizers.  This is why we can\n\t\t * rely on the object properties not changing from underneath us.\n\t\t */\n\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, h_varmap, i);\n\t\tif (!DUK_TVAL_IS_NUMBER(tv)) {\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv));\n\t\t\tDUK_HOBJECT_E_SET_KEY(thr->heap, h_varmap, i, NULL);\n\t\t\tDUK_HSTRING_DECREF(thr, h_key);\n\t\t\t/* when key is NULL, value is garbage so no need to set */\n\t\t} else {\n\t\t\tret++;\n\t\t}\n\t}\n\n\tduk_compact_m1(thr);\n\n\treturn ret;\n}\n\n/* Convert duk_compiler_func into a function template, leaving the result\n * on top of stack.\n */\n/* XXX: awkward and bloated asm -- use faster internal accesses */\nDUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func = &comp_ctx->curr_func;\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hcompfunc *h_res;\n\tduk_hbuffer_fixed *h_data;\n\tduk_size_t consts_count;\n\tduk_size_t funcs_count;\n\tduk_size_t code_count;\n\tduk_size_t code_size;\n\tduk_size_t data_size;\n\tduk_size_t i;\n\tduk_tval *p_const;\n\tduk_hobject **p_func;\n\tduk_instr_t *p_instr;\n\tduk_compiler_instr *q_instr;\n\tduk_tval *tv;\n\tduk_bool_t keep_varmap;\n\tduk_bool_t keep_formals;\n#if !defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_size_t formals_length;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"converting duk_compiler_func to function/template\"));\n\n\t/*\n\t *  Push result object and init its flags\n\t */\n\n\t/* Valstack should suffice here, required on function valstack init */\n\n\th_res = duk_push_hcompfunc(thr);\n\tDUK_ASSERT(h_res != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_res) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, (duk_hobject *) h_res, NULL);  /* Function templates are \"bare objects\". */\n\n\tif (func->is_function) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function -> set NEWENV\"));\n\t\tDUK_HOBJECT_SET_NEWENV((duk_hobject *) h_res);\n\n\t\tif (!func->is_arguments_shadowed) {\n\t\t\t/* arguments object would be accessible; note that shadowing\n\t\t\t * bindings are arguments or function declarations, neither\n\t\t\t * of which are deletable, so this is safe.\n\t\t\t */\n\n\t\t\tif (func->id_access_arguments || func->may_direct_eval) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"function may access 'arguments' object directly or \"\n\t\t\t\t                     \"indirectly -> set CREATEARGS\"));\n\t\t\t\tDUK_HOBJECT_SET_CREATEARGS((duk_hobject *) h_res);\n\t\t\t}\n\t\t}\n\t} else if (func->is_eval && func->is_strict) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"strict eval code -> set NEWENV\"));\n\t\tDUK_HOBJECT_SET_NEWENV((duk_hobject *) h_res);\n\t} else {\n\t\t/* non-strict eval: env is caller's env or global env (direct vs. indirect call)\n\t\t * global code: env is is global env\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-strict eval code or global code -> no NEWENV\"));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV((duk_hobject *) h_res));\n\t}\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tif (func->is_function && func->is_namebinding && func->h_name != NULL) {\n\t\t/* Object literal set/get functions have a name (property\n\t\t * name) but must not have a lexical name binding, see\n\t\t * test-bug-getset-func-name.js.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"function expression with a name -> set NAMEBINDING\"));\n\t\tDUK_HOBJECT_SET_NAMEBINDING((duk_hobject *) h_res);\n\t}\n#endif\n\n\tif (func->is_strict) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is strict -> set STRICT\"));\n\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_res);\n\t}\n\n\tif (func->is_notail) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is notail -> set NOTAIL\"));\n\t\tDUK_HOBJECT_SET_NOTAIL((duk_hobject *) h_res);\n\t}\n\n\tif (func->is_constructable) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is constructable -> set CONSTRUCTABLE\"));\n\t\tDUK_HOBJECT_SET_CONSTRUCTABLE((duk_hobject *) h_res);\n\t}\n\n\t/*\n\t *  Build function fixed size 'data' buffer, which contains bytecode,\n\t *  constants, and inner function references.\n\t *\n\t *  During the building phase 'data' is reachable but incomplete.\n\t *  Only incref's occur during building (no refzero or GC happens),\n\t *  so the building process is atomic.\n\t */\n\n\tconsts_count = duk_hobject_get_length(thr, func->h_consts);\n\tfuncs_count = duk_hobject_get_length(thr, func->h_funcs) / 3;\n\tcode_count = DUK_BW_GET_SIZE(thr, &func->bw_code) / sizeof(duk_compiler_instr);\n\tcode_size = code_count * sizeof(duk_instr_t);\n\n\tdata_size = consts_count * sizeof(duk_tval) +\n\t            funcs_count * sizeof(duk_hobject *) +\n\t            code_size;\n\n\tDUK_DDD(DUK_DDDPRINT(\"consts_count=%ld, funcs_count=%ld, code_size=%ld -> \"\n\t                     \"data_size=%ld*%ld + %ld*%ld + %ld = %ld\",\n\t                     (long) consts_count, (long) funcs_count, (long) code_size,\n\t                     (long) consts_count, (long) sizeof(duk_tval),\n\t                     (long) funcs_count, (long) sizeof(duk_hobject *),\n\t                     (long) code_size, (long) data_size));\n\n\tduk_push_fixed_buffer_nozero(thr, data_size);\n\th_data = (duk_hbuffer_fixed *) (void *) duk_known_hbuffer(thr, -1);\n\n\tDUK_HCOMPFUNC_SET_DATA(thr->heap, h_res, (duk_hbuffer *) h_data);\n\tDUK_HEAPHDR_INCREF(thr, h_data);\n\n\tp_const = (duk_tval *) (void *) DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, h_data);\n\tfor (i = 0; i < consts_count; i++) {\n\t\tDUK_ASSERT(i <= DUK_UARRIDX_MAX);  /* const limits */\n\t\ttv = duk_hobject_find_array_entry_tval_ptr(thr->heap, func->h_consts, (duk_uarridx_t) i);\n\t\tDUK_ASSERT(tv != NULL);\n\t\tDUK_TVAL_SET_TVAL(p_const, tv);\n\t\tp_const++;\n\t\tDUK_TVAL_INCREF(thr, tv);  /* may be a string constant */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"constant: %!T\", (duk_tval *) tv));\n\t}\n\n\tp_func = (duk_hobject **) p_const;\n\tDUK_HCOMPFUNC_SET_FUNCS(thr->heap, h_res, p_func);\n\tfor (i = 0; i < funcs_count; i++) {\n\t\tduk_hobject *h;\n\t\tDUK_ASSERT(i * 3 <= DUK_UARRIDX_MAX);  /* func limits */\n\t\ttv = duk_hobject_find_array_entry_tval_ptr(thr->heap, func->h_funcs, (duk_uarridx_t) (i * 3));\n\t\tDUK_ASSERT(tv != NULL);\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(h));\n\t\t*p_func++ = h;\n\t\tDUK_HOBJECT_INCREF(thr, h);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"inner function: %p -> %!iO\",\n\t\t                     (void *) h, (duk_heaphdr *) h));\n\t}\n\n\tp_instr = (duk_instr_t *) p_func;\n\tDUK_HCOMPFUNC_SET_BYTECODE(thr->heap, h_res, p_instr);\n\n\t/* copy bytecode instructions one at a time */\n\tq_instr = (duk_compiler_instr *) (void *) DUK_BW_GET_BASEPTR(thr, &func->bw_code);\n\tfor (i = 0; i < code_count; i++) {\n\t\tp_instr[i] = q_instr[i].ins;\n\t}\n\t/* Note: 'q_instr' is still used below */\n\n\tDUK_ASSERT((duk_uint8_t *) (p_instr + code_count) == DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, h_data) + data_size);\n\n\tduk_pop(thr);  /* 'data' (and everything in it) is reachable through h_res now */\n\n\t/*\n\t *  Init non-property result fields\n\t *\n\t *  'nregs' controls how large a register frame is allocated.\n\t *\n\t *  'nargs' controls how many formal arguments are written to registers:\n\t *  r0, ... r(nargs-1).  The remaining registers are initialized to\n\t *  undefined.\n\t */\n\n\tDUK_ASSERT(func->temp_max >= 0);\n\th_res->nregs = (duk_uint16_t) func->temp_max;\n\th_res->nargs = (duk_uint16_t) duk_hobject_get_length(thr, func->h_argnames);\n\tDUK_ASSERT(h_res->nregs >= h_res->nargs);  /* pass2 allocation handles this */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\th_res->start_line = (duk_uint32_t) func->min_line;\n\th_res->end_line = (duk_uint32_t) func->max_line;\n#endif\n\n\t/*\n\t *  Init object properties\n\t *\n\t *  Properties should be added in decreasing order of access frequency.\n\t *  (Not very critical for function templates.)\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"init function properties\"));\n\n\t/* [ ... res ] */\n\n\t/* _Varmap: omitted if function is guaranteed not to do a slow path\n\t * identifier access that might be caught by locally declared variables.\n\t * The varmap can also be omitted if it turns out empty of actual\n\t * register mappings after a cleanup.  When debugging is enabled, we\n\t * always need the varmap to be able to lookup variables at any point.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tDUK_DD(DUK_DDPRINT(\"keeping _Varmap because debugger support is enabled\"));\n\tkeep_varmap = 1;\n#else\n\tif (func->id_access_slow_own ||   /* directly uses slow accesses that may match own variables */\n\t    func->id_access_arguments ||  /* accesses 'arguments' directly */\n\t    func->may_direct_eval ||      /* may indirectly slow access through a direct eval */\n\t    funcs_count > 0) {            /* has inner functions which may slow access (XXX: this can be optimized by looking at the inner functions) */\n\t\tDUK_DD(DUK_DDPRINT(\"keeping _Varmap because of direct eval, slow path access that may match local variables, or presence of inner functions\"));\n\t\tkeep_varmap = 1;\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"dropping _Varmap\"));\n\t\tkeep_varmap = 0;\n\t}\n#endif\n\n\tif (keep_varmap) {\n\t\tduk_int_t num_used;\n\t\tduk_dup(thr, func->varmap_idx);\n\t\tnum_used = duk__cleanup_varmap(comp_ctx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"cleaned up varmap: %!T (num_used=%ld)\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) num_used));\n\n\t\tif (num_used > 0) {\n\t\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VARMAP, DUK_PROPDESC_FLAGS_NONE);\n\t\t} else {\n\t\t\tDUK_DD(DUK_DDPRINT(\"varmap is empty after cleanup -> no need to add\"));\n\t\t\tduk_pop(thr);\n\t\t}\n\t}\n\n\t/* _Formals: omitted if function is guaranteed not to need a (non-strict)\n\t * arguments object, and _Formals.length matches nargs exactly.\n\t *\n\t * Non-arrow functions can't see an outer function's 'argument' binding\n\t * (because they have their own), but arrow functions can.  When arrow\n\t * functions are added, this condition would need to be added:\n\t *     inner_arrow_funcs_count > 0   inner arrow functions may access 'arguments'\n\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tDUK_DD(DUK_DDPRINT(\"keeping _Formals because debugger support is enabled\"));\n\tkeep_formals = 1;\n#else\n\tformals_length = duk_get_length(thr, func->argnames_idx);\n\tif (formals_length != (duk_size_t) h_res->nargs) {\n\t\t/* Nargs not enough for closure .length: keep _Formals regardless\n\t\t * of its length.  Shouldn't happen in practice at the moment.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"keeping _Formals because _Formals.length != nargs\"));\n\t\tkeep_formals = 1;\n\t} else if ((func->id_access_arguments || func->may_direct_eval) &&\n\t           (formals_length > 0)) {\n\t\t/* Direct eval (may access 'arguments') or accesses 'arguments'\n\t\t * explicitly: keep _Formals unless it is zero length.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"keeping _Formals because of direct eval or explicit access to 'arguments', and _Formals.length != 0\"));\n\t\tkeep_formals = 1;\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"omitting _Formals, nargs matches _Formals.length, so no properties added\"));\n\t\tkeep_formals = 0;\n\t}\n#endif\n\n\tif (keep_formals) {\n\t\tduk_dup(thr, func->argnames_idx);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_FORMALS, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\n\t/* name */\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tif (func->h_name) {\n\t\tduk_push_hstring(thr, func->h_name);\n\t\tDUK_DD(DUK_DDPRINT(\"setting function template .name to %!T\", duk_get_tval(thr, -1)));\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_NONE);\n\t}\n#endif  /* DUK_USE_FUNC_NAME_PROPERTY */\n\n\t/* _Source */\n#if defined(DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY)\n\tif (0) {\n\t\t/* XXX: Currently function source code is not stored, as it is not\n\t\t * required by the standard.  Source code should not be stored by\n\t\t * default (user should enable it explicitly), and the source should\n\t\t * probably be compressed with a trivial text compressor; average\n\t\t * compression of 20-30% is quite easy to achieve even with a trivial\n\t\t * compressor (RLE + backwards lookup).\n\t\t *\n\t\t * Debugging needs source code to be useful: sometimes input code is\n\t\t * not found in files as it may be generated and then eval()'d, given\n\t\t * by dynamic C code, etc.\n\t\t *\n\t\t * Other issues:\n\t\t *\n\t\t *   - Need tokenizer indices for start and end to substring\n\t\t *   - Always normalize function declaration part?\n\t\t *   - If we keep _Formals, only need to store body\n\t\t */\n\n\t\t/*\n\t\t *  For global or eval code this is straightforward.  For functions\n\t\t *  created with the Function constructor we only get the source for\n\t\t *  the body and must manufacture the \"function ...\" part.\n\t\t *\n\t\t *  For instance, for constructed functions (v8):\n\t\t *\n\t\t *    > a = new Function(\"foo\", \"bar\", \"print(foo)\");\n\t\t *    [Function]\n\t\t *    > a.toString()\n\t\t *    'function anonymous(foo,bar) {\\nprint(foo)\\n}'\n\t\t *\n\t\t *  Similarly for e.g. getters (v8):\n\t\t *\n\t\t *    > x = { get a(foo,bar) { print(foo); } }\n\t\t *    { a: [Getter] }\n\t\t *    > Object.getOwnPropertyDescriptor(x, 'a').get.toString()\n\t\t *    'function a(foo,bar) { print(foo); }'\n\t\t */\n\n#if 0\n\t\tduk_push_literal(thr, \"XXX\");\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_SOURCE, DUK_PROPDESC_FLAGS_NONE);\n#endif\n\t}\n#endif  /* DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY */\n\n\t/* _Pc2line */\n#if defined(DUK_USE_PC2LINE)\n\tif (1) {\n\t\t/*\n\t\t *  Size-optimized pc->line mapping.\n\t\t */\n\n\t\tDUK_ASSERT(code_count <= DUK_COMPILER_MAX_BYTECODE_LENGTH);\n\t\tduk_hobject_pc2line_pack(thr, q_instr, (duk_uint_fast32_t) code_count);  /* -> pushes fixed buffer */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_NONE);\n\n\t\t/* XXX: if assertions enabled, walk through all valid PCs\n\t\t * and check line mapping.\n\t\t */\n\t}\n#endif  /* DUK_USE_PC2LINE */\n\n\t/* fileName */\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tif (comp_ctx->h_filename) {\n\t\t/*\n\t\t *  Source filename (or equivalent), for identifying thrown errors.\n\t\t */\n\n\t\tduk_push_hstring(thr, comp_ctx->h_filename);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_NONE);\n\t}\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"converted function: %!ixT\",\n\t                   (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/*\n\t *  Compact the function template.\n\t */\n\n\tduk_compact_m1(thr);\n\n\t/*\n\t *  Debug dumping\n\t */\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t{\n\t\tduk_hcompfunc *h;\n\t\tduk_instr_t *p, *p_start, *p_end;\n\n\t\th = (duk_hcompfunc *) duk_get_hobject(thr, -1);\n\t\tp_start = (duk_instr_t *) DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, h);\n\t\tp_end = (duk_instr_t *) DUK_HCOMPFUNC_GET_CODE_END(thr->heap, h);\n\n\t\tp = p_start;\n\t\twhile (p < p_end) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"BC %04ld: %!I        ; 0x%08lx op=%ld (%!X) a=%ld b=%ld c=%ld\",\n\t\t\t                     (long) (p - p_start),\n\t\t\t                     (duk_instr_t) (*p),\n\t\t\t                     (unsigned long) (*p),\n\t\t\t                     (long) DUK_DEC_OP(*p),\n\t\t\t                     (long) DUK_DEC_OP(*p),\n\t\t\t                     (long) DUK_DEC_A(*p),\n\t\t\t                     (long) DUK_DEC_B(*p),\n\t\t\t                     (long) DUK_DEC_C(*p)));\n\t\t\tp++;\n\t\t}\n\t}\n#endif\n}\n\n/*\n *  Code emission helpers\n *\n *  Some emission helpers understand the range of target and source reg/const\n *  values and automatically emit shuffling code if necessary.  This is the\n *  case when the slot in question (A, B, C) is used in the standard way and\n *  for opcodes the emission helpers explicitly understand (like DUK_OP_MPUTOBJ).\n *\n *  The standard way is that:\n *    - slot A is a target register\n *    - slot B is a source register/constant\n *    - slot C is a source register/constant\n *\n *  If a slot is used in a non-standard way the caller must indicate this\n *  somehow.  If a slot is used as a target instead of a source (or vice\n *  versa), this can be indicated with a flag to trigger proper shuffling\n *  (e.g. DUK__EMIT_FLAG_B_IS_TARGET).  If the value in the slot is not\n *  register/const related at all, the caller must ensure that the raw value\n *  fits into the corresponding slot so as to not trigger shuffling.  The\n *  caller must set a \"no shuffle\" flag to ensure compilation fails if\n *  shuffling were to be triggered because of an internal error.\n *\n *  For slots B and C the raw slot size is 9 bits but one bit is reserved for\n *  the reg/const indicator.  To use the full 9-bit range for a raw value,\n *  shuffling must be disabled with the DUK__EMIT_FLAG_NO_SHUFFLE_{B,C} flag.\n *  Shuffling is only done for A, B, and C slots, not the larger BC or ABC slots.\n *\n *  There is call handling specific understanding in the A-B-C emitter to\n *  convert call setup and call instructions into indirect ones if necessary.\n */\n\n/* Code emission flags, passed in the 'opcode' field.  Opcode + flags\n * fit into 16 bits for now, so use duk_small_uint_t.\n */\n#define DUK__EMIT_FLAG_NO_SHUFFLE_A      (1 << 8)\n#define DUK__EMIT_FLAG_NO_SHUFFLE_B      (1 << 9)\n#define DUK__EMIT_FLAG_NO_SHUFFLE_C      (1 << 10)\n#define DUK__EMIT_FLAG_A_IS_SOURCE       (1 << 11)  /* slot A is a source (default: target) */\n#define DUK__EMIT_FLAG_B_IS_TARGET       (1 << 12)  /* slot B is a target (default: source) */\n#define DUK__EMIT_FLAG_C_IS_TARGET       (1 << 13)  /* slot C is a target (default: source) */\n#define DUK__EMIT_FLAG_BC_REGCONST       (1 << 14)  /* slots B and C are reg/const */\n#define DUK__EMIT_FLAG_RESERVE_JUMPSLOT  (1 << 15)  /* reserve a jumpslot after instr before target spilling, used for NEXTENUM */\n\n/* XXX: macro smaller than call? */\nDUK_LOCAL duk_int_t duk__get_current_pc(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func;\n\tfunc = &comp_ctx->curr_func;\n\treturn (duk_int_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &func->bw_code) / sizeof(duk_compiler_instr));\n}\n\nDUK_LOCAL duk_compiler_instr *duk__get_instr_ptr(duk_compiler_ctx *comp_ctx, duk_int_t pc) {\n\tDUK_ASSERT(pc >= 0);\n\tDUK_ASSERT((duk_size_t) pc < (duk_size_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr)));\n\treturn ((duk_compiler_instr *) (void *) DUK_BW_GET_BASEPTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code)) + pc;\n}\n\n/* emit instruction; could return PC but that's not needed in the majority\n * of cases.\n */\nDUK_LOCAL void duk__emit(duk_compiler_ctx *comp_ctx, duk_instr_t ins) {\n#if defined(DUK_USE_PC2LINE)\n\tduk_int_t line;\n#endif\n\tduk_compiler_instr *instr;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__emit: 0x%08lx curr_token.start_line=%ld prev_token.start_line=%ld pc=%ld --> %!I\",\n\t                     (unsigned long) ins,\n\t                     (long) comp_ctx->curr_token.start_line,\n\t                     (long) comp_ctx->prev_token.start_line,\n\t                     (long) duk__get_current_pc(comp_ctx),\n\t                     (duk_instr_t) ins));\n\n\tinstr = (duk_compiler_instr *) (void *) DUK_BW_ENSURE_GETPTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, sizeof(duk_compiler_instr));\n\tDUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, sizeof(duk_compiler_instr));\n\n#if defined(DUK_USE_PC2LINE)\n\t/* The line number tracking is a bit inconsistent right now, which\n\t * affects debugger accuracy.  Mostly call sites emit opcodes when\n\t * they have parsed a token (say a terminating semicolon) and called\n\t * duk__advance().  In this case the line number of the previous\n\t * token is the most accurate one (except in prologue where\n\t * prev_token.start_line is 0).  This is probably not 100% correct\n\t * right now.\n\t */\n\t/* approximation, close enough */\n\tline = comp_ctx->prev_token.start_line;\n\tif (line == 0) {\n\t\tline = comp_ctx->curr_token.start_line;\n\t}\n#endif\n\n\tinstr->ins = ins;\n#if defined(DUK_USE_PC2LINE)\n\tinstr->line = (duk_uint32_t) line;\n#endif\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (line < comp_ctx->curr_func.min_line) {\n\t\tcomp_ctx->curr_func.min_line = line;\n\t}\n\tif (line > comp_ctx->curr_func.max_line) {\n\t\tcomp_ctx->curr_func.max_line = line;\n\t}\n#endif\n\n\t/* Limit checks for bytecode byte size and line number. */\n\tif (DUK_UNLIKELY(DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) > DUK_USE_ESBC_MAX_BYTES)) {\n\t\tgoto fail_bc_limit;\n\t}\n#if defined(DUK_USE_PC2LINE) && defined(DUK_USE_ESBC_LIMITS)\n#if defined(DUK_USE_BUFLEN16)\n\t/* Buffer length is bounded to 0xffff automatically, avoid compile warning. */\n\tif (DUK_UNLIKELY(line > DUK_USE_ESBC_MAX_LINENUMBER)) {\n\t\tgoto fail_bc_limit;\n\t}\n#else\n\tif (DUK_UNLIKELY(line > DUK_USE_ESBC_MAX_LINENUMBER)) {\n\t\tgoto fail_bc_limit;\n\t}\n#endif\n#endif\n\n\treturn;\n\n  fail_bc_limit:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_BYTECODE_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Update function min/max line from current token.  Needed to improve\n * function line range information for debugging, so that e.g. opening\n * curly brace is covered by line range even when no opcodes are emitted\n * for the line containing the brace.\n */\nDUK_LOCAL void duk__update_lineinfo_currtoken(duk_compiler_ctx *comp_ctx) {\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_int_t line;\n\n\tline = comp_ctx->curr_token.start_line;\n\tif (line == 0) {\n\t\treturn;\n\t}\n\tif (line < comp_ctx->curr_func.min_line) {\n\t\tcomp_ctx->curr_func.min_line = line;\n\t}\n\tif (line > comp_ctx->curr_func.max_line) {\n\t\tcomp_ctx->curr_func.max_line = line;\n\t}\n#else\n\tDUK_UNREF(comp_ctx);\n#endif\n}\n\nDUK_LOCAL void duk__emit_op_only(duk_compiler_ctx *comp_ctx, duk_small_uint_t op) {\n\tduk__emit(comp_ctx, DUK_ENC_OP_ABC(op, 0));\n}\n\n/* Important main primitive. */\nDUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b, duk_regconst_t c) {\n\tduk_instr_t ins = 0;\n\tduk_int_t a_out = -1;\n\tduk_int_t b_out = -1;\n\tduk_int_t c_out = -1;\n\tduk_int_t tmp;\n\tduk_small_uint_t op = op_flags & 0xffU;\n\n\tDUK_DDD(DUK_DDDPRINT(\"emit: op_flags=%04lx, a=%ld, b=%ld, c=%ld\",\n\t                     (unsigned long) op_flags, (long) a, (long) b, (long) c));\n\n\t/* We could rely on max temp/const checks: if they don't exceed BC\n\t * limit, nothing here can either (just asserts would be enough).\n\t * Currently we check for the limits, which provides additional\n\t * protection against creating invalid bytecode due to compiler\n\t * bugs.\n\t */\n\n\tDUK_ASSERT_DISABLE((op_flags & 0xff) >= DUK_BC_OP_MIN);  /* unsigned */\n\tDUK_ASSERT((op_flags & 0xff) <= DUK_BC_OP_MAX);\n\tDUK_ASSERT(DUK__ISREG(a));\n\tDUK_ASSERT(b != -1);  /* Not 'none'. */\n\tDUK_ASSERT(c != -1);  /* Not 'none'. */\n\n\t/* Input shuffling happens before the actual operation, while output\n\t * shuffling happens afterwards.  Output shuffling decisions are still\n\t * made at the same time to reduce branch clutter; output shuffle decisions\n\t * are recorded into X_out variables.\n\t */\n\n\t/* Slot A: currently no support for reg/const. */\n\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\tif (a <= DUK_BC_A_MAX && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A)) {\n#else\n\tif (a <= DUK_BC_A_MAX) {\n#endif\n\t\t;\n\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A) {\n\t\tDUK_D(DUK_DPRINT(\"out of regs: 'a' (reg) needs shuffling but shuffle prohibited, a: %ld\", (long) a));\n\t\tgoto error_outofregs;\n\t} else if (a <= DUK_BC_BC_MAX) {\n\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\ttmp = comp_ctx->curr_func.shuffle1;\n\t\tif (op_flags & DUK__EMIT_FLAG_A_IS_SOURCE) {\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, a));\n\t\t} else {\n\t\t\t/* Output shuffle needed after main operation */\n\t\t\ta_out = a;\n\n\t\t\t/* The DUK_OP_CSVAR output shuffle assumes shuffle registers are\n\t\t\t * consecutive.\n\t\t\t */\n\t\t\tDUK_ASSERT((comp_ctx->curr_func.shuffle1 == 0 && comp_ctx->curr_func.shuffle2 == 0) ||\n\t\t\t           (comp_ctx->curr_func.shuffle2 == comp_ctx->curr_func.shuffle1 + 1));\n\t\t\tif (op == DUK_OP_CSVAR) {\n\t\t\t\t/* For CSVAR the limit is one smaller because output shuffle\n\t\t\t\t * must be able to express 'a + 1' in BC.\n\t\t\t\t */\n\t\t\t\tif (a + 1 > DUK_BC_BC_MAX) {\n\t\t\t\t\tgoto error_outofregs;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ta = tmp;\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"out of regs: 'a' (reg) needs shuffling but does not fit into BC, a: %ld\", (long) a));\n\t\tgoto error_outofregs;\n\t}\n\n\t/* Slot B: reg/const support, mapped to bit 0 of opcode. */\n\n\tif ((b & DUK__CONST_MARKER) != 0) {\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B) == 0);\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_B_IS_TARGET) == 0);\n\t\tb = b & ~DUK__CONST_MARKER;\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (0) {\n#else\n\t\tif (b <= 0xff) {\n#endif\n\t\t\tif (op_flags & DUK__EMIT_FLAG_BC_REGCONST) {\n\t\t\t\t/* Opcode follows B/C reg/const convention. */\n\t\t\t\tDUK_ASSERT((op & 0x01) == 0);\n\t\t\t\tins |= DUK_ENC_OP_A_B_C(0x01, 0, 0, 0);  /* const flag for B */\n\t\t\t} else {\n\t\t\t\tDUK_D(DUK_DPRINT(\"B is const, opcode is not B/C reg/const: %x\", op_flags));\n\t\t\t}\n\t\t} else if (b <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle2;\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDCONST, tmp, b));\n\t\t\tb = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'b' (const) needs shuffling but does not fit into BC, b: %ld\", (long) b));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t} else {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (b <= 0xff && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B)) {\n#else\n\t\tif (b <= 0xff) {\n#endif\n\t\t\t;\n\t\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B) {\n\t\t\tif (b > DUK_BC_B_MAX) {\n\t\t\t\t/* Note: 0xff != DUK_BC_B_MAX */\n\t\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'b' (reg) needs shuffling but shuffle prohibited, b: %ld\", (long) b));\n\t\t\t\tgoto error_outofregs;\n\t\t\t}\n\t\t} else if (b <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle2;\n\t\t\tif (op_flags & DUK__EMIT_FLAG_B_IS_TARGET) {\n\t\t\t\t/* Output shuffle needed after main operation */\n\t\t\t\tb_out = b;\n\t\t\t}\n\t\t\tif (!(op_flags & DUK__EMIT_FLAG_B_IS_TARGET)) {\n\t\t\t\tif (op == DUK_OP_MPUTOBJ || op == DUK_OP_MPUTARR) {\n\t\t\t\t\t/* Special handling for MPUTOBJ/MPUTARR shuffling.\n\t\t\t\t\t * For each, slot B identifies the first register of a range\n\t\t\t\t\t * of registers, so normal shuffling won't work.  Instead,\n\t\t\t\t\t * an indirect version of the opcode is used.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_B_IS_TARGET) == 0);\n\t\t\t\t\tduk__emit_load_int32_noshuffle(comp_ctx, tmp, b);\n\t\t\t\t\tDUK_ASSERT(DUK_OP_MPUTOBJI == DUK_OP_MPUTOBJ + 1);\n\t\t\t\t\tDUK_ASSERT(DUK_OP_MPUTARRI == DUK_OP_MPUTARR + 1);\n\t\t\t\t\top_flags++;  /* indirect opcode follows direct */\n\t\t\t\t} else {\n\t\t\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, b));\n\t\t\t\t}\n\t\t\t}\n\t\t\tb = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'b' (reg) needs shuffling but does not fit into BC, b: %ld\", (long) b));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t}\n\n\t/* Slot C: reg/const support, mapped to bit 1 of opcode. */\n\n\tif ((c & DUK__CONST_MARKER) != 0) {\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C) == 0);\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_C_IS_TARGET) == 0);\n\t\tc = c & ~DUK__CONST_MARKER;\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (0) {\n#else\n\t\tif (c <= 0xff) {\n#endif\n\t\t\tif (op_flags & DUK__EMIT_FLAG_BC_REGCONST) {\n\t\t\t\t/* Opcode follows B/C reg/const convention. */\n\t\t\t\tDUK_ASSERT((op & 0x02) == 0);\n\t\t\t\tins |= DUK_ENC_OP_A_B_C(0x02, 0, 0, 0);  /* const flag for C */\n\t\t\t} else {\n\t\t\t\tDUK_D(DUK_DPRINT(\"C is const, opcode is not B/C reg/const: %x\", op_flags));\n\t\t\t}\n\t\t} else if (c <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle3;\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDCONST, tmp, c));\n\t\t\tc = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'c' (const) needs shuffling but does not fit into BC, c: %ld\", (long) c));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t} else {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (c <= 0xff && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C)) {\n#else\n\t\tif (c <= 0xff) {\n#endif\n\t\t\t;\n\t\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C) {\n\t\t\tif (c > DUK_BC_C_MAX) {\n\t\t\t\t/* Note: 0xff != DUK_BC_C_MAX */\n\t\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'c' (reg) needs shuffling but shuffle prohibited, c: %ld\", (long) c));\n\t\t\t\tgoto error_outofregs;\n\t\t\t}\n\t\t} else if (c <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle3;\n\t\t\tif (op_flags & DUK__EMIT_FLAG_C_IS_TARGET) {\n\t\t\t\t/* Output shuffle needed after main operation */\n\t\t\t\tc_out = c;\n\t\t\t} else {\n\t\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, c));\n\t\t\t}\n\t\t\tc = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'c' (reg) needs shuffling but does not fit into BC, c: %ld\", (long) c));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t}\n\n\t/* Main operation */\n\n\tDUK_ASSERT(a >= DUK_BC_A_MIN);\n\tDUK_ASSERT(a <= DUK_BC_A_MAX);\n\tDUK_ASSERT(b >= DUK_BC_B_MIN);\n\tDUK_ASSERT(b <= DUK_BC_B_MAX);\n\tDUK_ASSERT(c >= DUK_BC_C_MIN);\n\tDUK_ASSERT(c <= DUK_BC_C_MAX);\n\n\tins |= DUK_ENC_OP_A_B_C(op_flags & 0xff, a, b, c);\n\tduk__emit(comp_ctx, ins);\n\n\t/* NEXTENUM needs a jump slot right after the main instruction.\n\t * When the JUMP is taken, output spilling is not needed so this\n\t * workaround is possible.  The jump slot PC is exceptionally\n\t * plumbed through comp_ctx to minimize call sites.\n\t */\n\tif (op_flags & DUK__EMIT_FLAG_RESERVE_JUMPSLOT) {\n\t\tcomp_ctx->emit_jumpslot_pc = duk__get_current_pc(comp_ctx);\n\t\tduk__emit_abc(comp_ctx, DUK_OP_JUMP, 0);\n\t}\n\n\t/* Output shuffling: only one output register is realistically possible.\n\t *\n\t * (Zero would normally be an OK marker value: if the target register\n\t * was zero, it would never be shuffled.  But with DUK_USE_SHUFFLE_TORTURE\n\t * this is no longer true, so use -1 as a marker instead.)\n\t */\n\n\tif (a_out >= 0) {\n\t\tDUK_ASSERT(b_out < 0);\n\t\tDUK_ASSERT(c_out < 0);\n\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, a, a_out));\n\n\t\tif (op == DUK_OP_CSVAR) {\n\t\t\t/* Special handling for CSVAR shuffling.  The variable lookup\n\t\t\t * results in a <value, this binding> pair in successive\n\t\t\t * registers so use two shuffle registers and two output\n\t\t\t * loads.  (In practice this is dead code because temp/const\n\t\t\t * limit is reached first.)\n\t\t\t */\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, a + 1, a_out + 1));\n\t\t}\n\t} else if (b_out >= 0) {\n\t\tDUK_ASSERT(a_out < 0);\n\t\tDUK_ASSERT(c_out < 0);\n\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, b, b_out));\n\t} else if (c_out >= 0) {\n\t\tDUK_ASSERT(b_out < 0);\n\t\tDUK_ASSERT(c_out < 0);\n\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, c, c_out));\n\t}\n\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* For many of the helpers below it'd be technically correct to add\n * \"no shuffle\" flags for parameters passed in as zero.  For example,\n * duk__emit_a_b() should call duk__emit_a_b_c() with C set to 0, and\n * DUK__EMIT_FLAG_NO_SHUFFLE_C added to op_flags.  However, since the\n * C value is 0, it'll never get shuffled so adding the flag is just\n * unnecessary additional code.  This is unfortunately not true for\n * \"shuffle torture\" mode which needs special handling.\n */\n\nDUK_LOCAL void duk__emit_a_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_C;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, a, b, 0);\n}\n\nDUK_LOCAL void duk__emit_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b, duk_regconst_t c) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_A;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, 0, b, c);\n}\n\n#if 0  /* unused */\nDUK_LOCAL void duk__emit_a(duk_compiler_ctx *comp_ctx, int op_flags, int a) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_B | DUK__EMIT_FLAG_NO_SHUFFLE_C;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, a, 0, 0);\n}\n#endif\n\n#if 0  /* unused */\nDUK_LOCAL void duk__emit_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_NO_SHUFFLE_C;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, 0, b, 0);\n}\n#endif\n\nDUK_LOCAL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t bc) {\n\tduk_instr_t ins;\n\tduk_int_t tmp;\n\n\t/* allow caller to give a const number with the DUK__CONST_MARKER */\n\tDUK_ASSERT(bc != -1);  /* Not 'none'. */\n\tbc = bc & (~DUK__CONST_MARKER);\n\n\tDUK_ASSERT_DISABLE((op_flags & 0xff) >= DUK_BC_OP_MIN);  /* unsigned */\n\tDUK_ASSERT((op_flags & 0xff) <= DUK_BC_OP_MAX);\n\tDUK_ASSERT(bc >= DUK_BC_BC_MIN);\n\tDUK_ASSERT(bc <= DUK_BC_BC_MAX);\n\tDUK_ASSERT((bc & DUK__CONST_MARKER) == 0);\n\n\tif (bc <= DUK_BC_BC_MAX) {\n\t\t;\n\t} else {\n\t\t/* No BC shuffling now. */\n\t\tgoto error_outofregs;\n\t}\n\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\tif (a <= DUK_BC_A_MAX && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A)) {\n#else\n\tif (a <= DUK_BC_A_MAX) {\n#endif\n\t\tins = DUK_ENC_OP_A_BC(op_flags & 0xff, a, bc);\n\t\tduk__emit(comp_ctx, ins);\n\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A) {\n\t\tgoto error_outofregs;\n\t} else if ((op_flags & 0xf0U) == DUK_OP_CALL0) {\n\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\ttmp = comp_ctx->curr_func.shuffle1;\n\t\tduk__emit_load_int32_noshuffle(comp_ctx, tmp, a);\n\t\top_flags |= DUK_BC_CALL_FLAG_INDIRECT;\n\t\tins = DUK_ENC_OP_A_BC(op_flags & 0xff, tmp, bc);\n\t\tduk__emit(comp_ctx, ins);\n\t} else if (a <= DUK_BC_BC_MAX) {\n\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\ttmp = comp_ctx->curr_func.shuffle1;\n\t\tins = DUK_ENC_OP_A_BC(op_flags & 0xff, tmp, bc);\n\t\tif (op_flags & DUK__EMIT_FLAG_A_IS_SOURCE) {\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, a));\n\t\t\tduk__emit(comp_ctx, ins);\n\t\t} else {\n\t\t\tduk__emit(comp_ctx, ins);\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, tmp, a));\n\t\t}\n\t} else {\n\t\tgoto error_outofregs;\n\t}\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__emit_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t bc) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top |= DUK__EMIT_FLAG_NO_SHUFFLE_A;\n#endif\n\tduk__emit_a_bc(comp_ctx, op, 0, bc);\n}\n\nDUK_LOCAL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t abc) {\n\tduk_instr_t ins;\n\n\tDUK_ASSERT_DISABLE(op >= DUK_BC_OP_MIN);  /* unsigned */\n\tDUK_ASSERT(op <= DUK_BC_OP_MAX);\n\tDUK_ASSERT_DISABLE(abc >= DUK_BC_ABC_MIN);  /* unsigned */\n\tDUK_ASSERT(abc <= DUK_BC_ABC_MAX);\n\tDUK_ASSERT((abc & DUK__CONST_MARKER) == 0);\n\tDUK_ASSERT(abc != -1);  /* Not 'none'. */\n\n\tif (abc <= DUK_BC_ABC_MAX) {\n\t\t;\n\t} else {\n\t\tgoto error_outofregs;\n\t}\n\tins = DUK_ENC_OP_ABC(op, abc);\n\tDUK_DDD(DUK_DDDPRINT(\"duk__emit_abc: 0x%08lx line=%ld pc=%ld op=%ld (%!X) abc=%ld (%!I)\",\n\t                     (unsigned long) ins, (long) comp_ctx->curr_token.start_line,\n\t                     (long) duk__get_current_pc(comp_ctx), (long) op, (long) op,\n\t                     (long) abc, (duk_instr_t) ins));\n\tduk__emit(comp_ctx, ins);\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__emit_load_int32_raw(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val, duk_small_uint_t op_flags) {\n\t/* XXX: Shuffling support could be implemented here so that LDINT+LDINTX\n\t * would only shuffle once (instead of twice).  The current code works\n\t * though, and has a smaller compiler footprint.\n\t */\n\n\tif ((val >= (duk_int32_t) DUK_BC_BC_MIN - (duk_int32_t) DUK_BC_LDINT_BIAS) &&\n\t    (val <= (duk_int32_t) DUK_BC_BC_MAX - (duk_int32_t) DUK_BC_LDINT_BIAS)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"emit LDINT to reg %ld for %ld\", (long) reg, (long) val));\n\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDINT | op_flags, reg, (duk_regconst_t) (val + (duk_int32_t) DUK_BC_LDINT_BIAS));\n\t} else {\n\t\tduk_int32_t hi = val >> DUK_BC_LDINTX_SHIFT;\n\t\tduk_int32_t lo = val & ((((duk_int32_t) 1) << DUK_BC_LDINTX_SHIFT) - 1);\n\t\tDUK_ASSERT(lo >= 0);\n\t\tDUK_DDD(DUK_DDDPRINT(\"emit LDINT+LDINTX to reg %ld for %ld -> hi %ld, lo %ld\",\n\t\t                     (long) reg, (long) val, (long) hi, (long) lo));\n\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDINT | op_flags, reg, (duk_regconst_t) (hi + (duk_int32_t) DUK_BC_LDINT_BIAS));\n\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDINTX | op_flags, reg, (duk_regconst_t) lo);\n\t}\n}\n\nDUK_LOCAL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val) {\n\tduk__emit_load_int32_raw(comp_ctx, reg, val, 0 /*op_flags*/);\n}\n\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n/* Used by duk__emit*() calls so that we don't shuffle the loadints that\n * are needed to handle indirect opcodes.\n */\nDUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val) {\n\tduk__emit_load_int32_raw(comp_ctx, reg, val, DUK__EMIT_FLAG_NO_SHUFFLE_A /*op_flags*/);\n}\n#else\nDUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val) {\n\t/* When torture not enabled, can just use the same helper because\n\t * 'reg' won't get spilled.\n\t */\n\tDUK_ASSERT(reg <= DUK_BC_A_MAX);\n\tduk__emit_load_int32(comp_ctx, reg, val);\n}\n#endif\n\nDUK_LOCAL void duk__emit_jump(duk_compiler_ctx *comp_ctx, duk_int_t target_pc) {\n\tduk_int_t curr_pc;\n\tduk_int_t offset;\n\n\tcurr_pc = (duk_int_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr));\n\toffset = (duk_int_t) target_pc - (duk_int_t) curr_pc - 1;\n\tDUK_ASSERT(offset + DUK_BC_JUMP_BIAS >= DUK_BC_ABC_MIN);\n\tDUK_ASSERT(offset + DUK_BC_JUMP_BIAS <= DUK_BC_ABC_MAX);\n\tduk__emit_abc(comp_ctx, DUK_OP_JUMP, (duk_regconst_t) (offset + DUK_BC_JUMP_BIAS));\n}\n\nDUK_LOCAL duk_int_t duk__emit_jump_empty(duk_compiler_ctx *comp_ctx) {\n\tduk_int_t ret;\n\n\tret = duk__get_current_pc(comp_ctx);  /* useful for patching jumps later */\n\tduk__emit_op_only(comp_ctx, DUK_OP_JUMP);\n\treturn ret;\n}\n\n/* Insert an empty jump in the middle of code emitted earlier.  This is\n * currently needed for compiling for-in.\n */\nDUK_LOCAL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc) {\n#if defined(DUK_USE_PC2LINE)\n\tduk_int_t line;\n#endif\n\tduk_compiler_instr *instr;\n\tduk_size_t offset;\n\n\tDUK_ASSERT(jump_pc >= 0);\n\toffset = (duk_size_t) jump_pc * sizeof(duk_compiler_instr);\n\tinstr = (duk_compiler_instr *) (void *)\n\t        DUK_BW_INSERT_ENSURE_AREA(comp_ctx->thr,\n\t                                  &comp_ctx->curr_func.bw_code,\n\t                                  offset,\n\t                                  sizeof(duk_compiler_instr));\n\n#if defined(DUK_USE_PC2LINE)\n\tline = comp_ctx->curr_token.start_line;  /* approximation, close enough */\n#endif\n\tinstr->ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, 0);\n#if defined(DUK_USE_PC2LINE)\n\tinstr->line = (duk_uint32_t) line;\n#endif\n\n\tDUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, sizeof(duk_compiler_instr));\n\tif (DUK_UNLIKELY(DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) > DUK_USE_ESBC_MAX_BYTES)) {\n\t\tgoto fail_bc_limit;\n\t}\n\treturn;\n\n  fail_bc_limit:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_BYTECODE_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Does not assume that jump_pc contains a DUK_OP_JUMP previously; this is intentional\n * to allow e.g. an INVALID opcode be overwritten with a JUMP (label management uses this).\n */\nDUK_LOCAL void duk__patch_jump(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc, duk_int_t target_pc) {\n\tduk_compiler_instr *instr;\n\tduk_int_t offset;\n\n\t/* allow negative PCs, behave as a no-op */\n\tif (jump_pc < 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__patch_jump(): nop call, jump_pc=%ld (<0), target_pc=%ld\",\n\t\t                     (long) jump_pc, (long) target_pc));\n\t\treturn;\n\t}\n\tDUK_ASSERT(jump_pc >= 0);\n\n\t/* XXX: range assert */\n\tinstr = duk__get_instr_ptr(comp_ctx, jump_pc);\n\tDUK_ASSERT(instr != NULL);\n\n\t/* XXX: range assert */\n\toffset = target_pc - jump_pc - 1;\n\n\tinstr->ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, offset + DUK_BC_JUMP_BIAS);\n\tDUK_DDD(DUK_DDDPRINT(\"duk__patch_jump(): jump_pc=%ld, target_pc=%ld, offset=%ld\",\n\t                     (long) jump_pc, (long) target_pc, (long) offset));\n}\n\nDUK_LOCAL void duk__patch_jump_here(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc) {\n\tduk__patch_jump(comp_ctx, jump_pc, duk__get_current_pc(comp_ctx));\n}\n\nDUK_LOCAL void duk__patch_trycatch(duk_compiler_ctx *comp_ctx, duk_int_t ldconst_pc, duk_int_t trycatch_pc, duk_regconst_t reg_catch, duk_regconst_t const_varname, duk_small_uint_t flags) {\n\tduk_compiler_instr *instr;\n\n\tDUK_ASSERT(DUK__ISREG(reg_catch));\n\n\tinstr = duk__get_instr_ptr(comp_ctx, ldconst_pc);\n\tDUK_ASSERT(DUK_DEC_OP(instr->ins) == DUK_OP_LDCONST);\n\tDUK_ASSERT(instr != NULL);\n\tif (const_varname & DUK__CONST_MARKER) {\n\t\t/* Have a catch variable. */\n\t\tconst_varname = const_varname & (~DUK__CONST_MARKER);\n\t\tif (reg_catch > DUK_BC_BC_MAX || const_varname > DUK_BC_BC_MAX) {\n\t\t\t/* Catch attempts to use out-of-range reg/const.  Without this\n\t\t\t * check Duktape 0.12.0 could generate invalid code which caused\n\t\t\t * an assert failure on execution.  This error is triggered e.g.\n\t\t\t * for functions with a lot of constants and a try-catch statement.\n\t\t\t * Shuffling or opcode semantics change is needed to fix the issue.\n\t\t\t * See: test-bug-trycatch-many-constants.js.\n\t\t\t */\n\t\t\tDUK_D(DUK_DPRINT(\"failed to patch trycatch: flags=%ld, reg_catch=%ld, const_varname=%ld (0x%08lx)\",\n\t\t\t                 (long) flags, (long) reg_catch, (long) const_varname, (long) const_varname));\n\t\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tinstr->ins |= DUK_ENC_OP_A_BC(0, 0, const_varname);\n\t} else {\n\t\t/* No catch variable, e.g. a try-finally; replace LDCONST with\n\t\t * NOP to avoid a bogus LDCONST.\n\t\t */\n\t\tinstr->ins = DUK_ENC_OP(DUK_OP_NOP);\n\t}\n\n\tinstr = duk__get_instr_ptr(comp_ctx, trycatch_pc);\n\tDUK_ASSERT(instr != NULL);\n\tDUK_ASSERT_DISABLE(flags >= DUK_BC_A_MIN);\n\tDUK_ASSERT(flags <= DUK_BC_A_MAX);\n\tinstr->ins = DUK_ENC_OP_A_BC(DUK_OP_TRYCATCH, flags, reg_catch);\n}\n\nDUK_LOCAL void duk__emit_if_false_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst) {\n\tduk_small_uint_t op;\n\n\top = DUK__ISREG(regconst) ? DUK_OP_IFFALSE_R : DUK_OP_IFFALSE_C;\n\tduk__emit_bc(comp_ctx, op, regconst);  /* helper will remove const flag */\n}\n\nDUK_LOCAL void duk__emit_if_true_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst) {\n\tduk_small_uint_t op;\n\n\top = DUK__ISREG(regconst) ? DUK_OP_IFTRUE_R : DUK_OP_IFTRUE_C;\n\tduk__emit_bc(comp_ctx, op, regconst);  /* helper will remove const flag */\n}\n\nDUK_LOCAL void duk__emit_invalid(duk_compiler_ctx *comp_ctx) {\n\tduk__emit_op_only(comp_ctx, DUK_OP_INVALID);\n}\n\n/*\n *  Peephole optimizer for finished bytecode.\n *\n *  Does not remove opcodes; currently only straightens out unconditional\n *  jump chains which are generated by several control structures.\n */\n\nDUK_LOCAL void duk__peephole_optimize_bytecode(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_instr *bc;\n\tduk_small_uint_t iter;\n\tduk_int_t i, n;\n\tduk_int_t count_opt;\n\n\tbc = (duk_compiler_instr *) (void *) DUK_BW_GET_BASEPTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code);\n#if defined(DUK_USE_BUFLEN16)\n\t/* No need to assert, buffer size maximum is 0xffff. */\n#else\n\tDUK_ASSERT((duk_size_t) DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr) <= (duk_size_t) DUK_INT_MAX);  /* bytecode limits */\n#endif\n\tn = (duk_int_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr));\n\n\tfor (iter = 0; iter < DUK_COMPILER_PEEPHOLE_MAXITER; iter++) {\n\t\tcount_opt = 0;\n\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk_instr_t ins;\n\t\t\tduk_int_t target_pc1;\n\t\t\tduk_int_t target_pc2;\n\n\t\t\tins = bc[i].ins;\n\t\t\tif (DUK_DEC_OP(ins) != DUK_OP_JUMP) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttarget_pc1 = i + 1 + (duk_int_t) DUK_DEC_ABC(ins) - (duk_int_t) DUK_BC_JUMP_BIAS;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"consider jump at pc %ld; target_pc=%ld\", (long) i, (long) target_pc1));\n\t\t\tDUK_ASSERT(target_pc1 >= 0);\n\t\t\tDUK_ASSERT(target_pc1 < n);\n\n\t\t\t/* Note: if target_pc1 == i, we'll optimize a jump to itself.\n\t\t\t * This does not need to be checked for explicitly; the case\n\t\t\t * is rare and max iter breaks us out.\n\t\t\t */\n\n\t\t\tins = bc[target_pc1].ins;\n\t\t\tif (DUK_DEC_OP(ins) != DUK_OP_JUMP) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttarget_pc2 = target_pc1 + 1 + (duk_int_t) DUK_DEC_ABC(ins) - (duk_int_t) DUK_BC_JUMP_BIAS;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"optimizing jump at pc %ld; old target is %ld -> new target is %ld\",\n\t\t\t                     (long) i, (long) target_pc1, (long) target_pc2));\n\n\t\t\tbc[i].ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, target_pc2 - (i + 1) + DUK_BC_JUMP_BIAS);\n\n\t\t\tcount_opt++;\n\t\t}\n\n\t\tDUK_DD(DUK_DDPRINT(\"optimized %ld jumps on peephole round %ld\", (long) count_opt, (long) (iter + 1)));\n\n\t\tif (count_opt == 0) {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/*\n *  Intermediate value helpers\n */\n\n/* Flags for intermediate value coercions.  A flag for using a forced reg\n * is not needed, the forced_reg argument suffices and generates better\n * code (it is checked as it is used).\n */\n/* XXX: DUK__IVAL_FLAG_REQUIRE_SHORT is passed but not currently implemented\n * by ispec/ivalue operations.\n */\n#define DUK__IVAL_FLAG_ALLOW_CONST          (1 << 0)  /* allow a constant to be returned */\n#define DUK__IVAL_FLAG_REQUIRE_TEMP         (1 << 1)  /* require a (mutable) temporary as a result (or a const if allowed) */\n#define DUK__IVAL_FLAG_REQUIRE_SHORT        (1 << 2)  /* require a short (8-bit) reg/const which fits into bytecode B/C slot */\n\n/* XXX: some code might benefit from DUK__SETTEMP_IFTEMP(thr,x) */\n\n#if 0  /* enable manually for dumping */\n#define DUK__DUMP_ISPEC(compctx,ispec) do { duk__dump_ispec((compctx), (ispec)); } while (0)\n#define DUK__DUMP_IVALUE(compctx,ivalue) do { duk__dump_ivalue((compctx), (ivalue)); } while (0)\n\nDUK_LOCAL void duk__dump_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *x) {\n\tDUK_D(DUK_DPRINT(\"ispec dump: t=%ld regconst=0x%08lx, valstack_idx=%ld, value=%!T\",\n\t                 (long) x->t, (unsigned long) x->regconst, (long) x->valstack_idx,\n\t                 duk_get_tval(comp_ctx->thr, x->valstack_idx)));\n}\nDUK_LOCAL void duk__dump_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tDUK_D(DUK_DPRINT(\"ivalue dump: t=%ld op=%ld \"\n\t                 \"x1={t=%ld regconst=0x%08lx valstack_idx=%ld value=%!T} \"\n\t                 \"x2={t=%ld regconst=0x%08lx valstack_idx=%ld value=%!T}\",\n\t\t         (long) x->t, (long) x->op,\n\t                 (long) x->x1.t, (unsigned long) x->x1.regconst, (long) x->x1.valstack_idx,\n\t                 duk_get_tval(comp_ctx->thr, x->x1.valstack_idx),\n\t                 (long) x->x2.t, (unsigned long) x->x2.regconst, (long) x->x2.valstack_idx,\n\t                 duk_get_tval(comp_ctx->thr, x->x2.valstack_idx)));\n}\n#else\n#define DUK__DUMP_ISPEC(comp_ctx,x) do {} while (0)\n#define DUK__DUMP_IVALUE(comp_ctx,x) do {} while (0)\n#endif\n\nDUK_LOCAL void duk__ivalue_regconst(duk_ivalue *x, duk_regconst_t regconst) {\n\tx->t = DUK_IVAL_PLAIN;\n\tx->x1.t = DUK_ISPEC_REGCONST;\n\tx->x1.regconst = regconst;\n}\n\nDUK_LOCAL void duk__ivalue_plain_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tx->t = DUK_IVAL_PLAIN;\n\tx->x1.t = DUK_ISPEC_VALUE;\n\tduk_replace(comp_ctx->thr, x->x1.valstack_idx);\n}\n\nDUK_LOCAL void duk__ivalue_var_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tx->t = DUK_IVAL_VAR;\n\tx->x1.t = DUK_ISPEC_VALUE;\n\tduk_replace(comp_ctx->thr, x->x1.valstack_idx);\n}\n\nDUK_LOCAL_DECL void duk__ivalue_var_hstring(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n\tduk_push_hstring(comp_ctx->thr, h);\n\tduk__ivalue_var_fromstack(comp_ctx, x);\n}\n\nDUK_LOCAL void duk__copy_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *src, duk_ispec *dst) {\n\tdst->t = src->t;\n\tdst->regconst = src->regconst;\n\tduk_copy(comp_ctx->thr, src->valstack_idx, dst->valstack_idx);\n}\n\nDUK_LOCAL void duk__copy_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *src, duk_ivalue *dst) {\n\tdst->t = src->t;\n\tdst->op = src->op;\n\tdst->x1.t = src->x1.t;\n\tdst->x1.regconst = src->x1.regconst;\n\tdst->x2.t = src->x2.t;\n\tdst->x2.regconst = src->x2.regconst;\n\tduk_copy(comp_ctx->thr, src->x1.valstack_idx, dst->x1.valstack_idx);\n\tduk_copy(comp_ctx->thr, src->x2.valstack_idx, dst->x2.valstack_idx);\n}\n\nDUK_LOCAL duk_regconst_t duk__alloctemps(duk_compiler_ctx *comp_ctx, duk_small_int_t num) {\n\tduk_regconst_t res;\n\n\tres = comp_ctx->curr_func.temp_next;\n\tcomp_ctx->curr_func.temp_next += num;\n\n\tif (comp_ctx->curr_func.temp_next > DUK__MAX_TEMPS) {  /* == DUK__MAX_TEMPS is OK */\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_TEMP_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* maintain highest 'used' temporary, needed to figure out nregs of function */\n\tif (comp_ctx->curr_func.temp_next > comp_ctx->curr_func.temp_max) {\n\t\tcomp_ctx->curr_func.temp_max = comp_ctx->curr_func.temp_next;\n\t}\n\n\treturn res;\n}\n\nDUK_LOCAL duk_regconst_t duk__alloctemp(duk_compiler_ctx *comp_ctx) {\n\treturn duk__alloctemps(comp_ctx, 1);\n}\n\nDUK_LOCAL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, duk_regconst_t temp_next) {\n\tcomp_ctx->curr_func.temp_next = temp_next;\n\tif (temp_next > comp_ctx->curr_func.temp_max) {\n\t\tcomp_ctx->curr_func.temp_max = temp_next;\n\t}\n}\n\n/* get const for value at valstack top */\nDUK_LOCAL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_compiler_func *f = &comp_ctx->curr_func;\n\tduk_tval *tv1;\n\tduk_int_t i, n, n_check;\n\n\tn = (duk_int_t) duk_get_length(thr, f->consts_idx);\n\n\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(tv1 != NULL);\n\n#if defined(DUK_USE_FASTINT)\n\t/* Explicit check for fastint downgrade. */\n\tDUK_TVAL_CHKFAST_INPLACE_SLOW(tv1);\n#endif\n\n\t/* Sanity workaround for handling functions with a large number of\n\t * constants at least somewhat reasonably.  Otherwise checking whether\n\t * we already have the constant would grow very slow (as it is O(N^2)).\n\t */\n\tn_check = (n > DUK__GETCONST_MAX_CONSTS_CHECK ? DUK__GETCONST_MAX_CONSTS_CHECK : n);\n\tfor (i = 0; i < n_check; i++) {\n\t\tduk_tval *tv2 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, f->h_consts, i);\n\n\t\t/* Strict equality is NOT enough, because we cannot use the same\n\t\t * constant for e.g. +0 and -0.\n\t\t */\n\t\tif (duk_js_samevalue(tv1, tv2)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"reused existing constant for %!T -> const index %ld\",\n\t\t\t                     (duk_tval *) tv1, (long) i));\n\t\t\tduk_pop(thr);\n\t\t\treturn (duk_regconst_t) i | (duk_regconst_t) DUK__CONST_MARKER;\n\t\t}\n\t}\n\n\tif (n > DUK__MAX_CONSTS) {\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_CONST_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"allocating new constant for %!T -> const index %ld\",\n\t                     (duk_tval *) tv1, (long) n));\n\t(void) duk_put_prop_index(thr, f->consts_idx, (duk_uarridx_t) n);  /* invalidates tv1, tv2 */\n\treturn (duk_regconst_t) n | (duk_regconst_t) DUK__CONST_MARKER;\n}\n\nDUK_LOCAL duk_bool_t duk__const_needs_refcount(duk_compiler_ctx *comp_ctx, duk_regconst_t rc) {\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_compiler_func *f = &comp_ctx->curr_func;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT((rc & DUK__CONST_MARKER) == 0);  /* caller removes const marker */\n\t(void) duk_get_prop_index(comp_ctx->thr, f->consts_idx, (duk_uarridx_t) rc);\n\tret = !duk_is_number(comp_ctx->thr, -1);  /* now only number/string, so conservative check */\n\tduk_pop(comp_ctx->thr);\n\treturn ret;\n#else\n\tDUK_UNREF(comp_ctx);\n\tDUK_UNREF(rc);\n\tDUK_ASSERT((rc & DUK__CONST_MARKER) == 0);  /* caller removes const marker */\n\treturn 0;\n#endif\n}\n\n/* Get the value represented by an duk_ispec to a register or constant.\n * The caller can control the result by indicating whether or not:\n *\n *   (1) a constant is allowed (sometimes the caller needs the result to\n *       be in a register)\n *\n *   (2) a temporary register is required (usually when caller requires\n *       the register to be safely mutable; normally either a bound\n *       register or a temporary register are both OK)\n *\n *   (3) a forced register target needs to be used\n *\n * Bytecode may be emitted to generate the necessary value.  The return\n * value is either a register or a constant.\n */\n\nDUK_LOCAL\nduk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                         duk_ispec *x,\n                                         duk_regconst_t forced_reg,\n                                         duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__ispec_toregconst_raw(): x={%ld:%ld:%!T}, \"\n\t                     \"forced_reg=%ld, flags 0x%08lx: allow_const=%ld require_temp=%ld require_short=%ld\",\n\t                     (long) x->t,\n\t                     (long) x->regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->valstack_idx),\n\t                     (long) forced_reg,\n\t                     (unsigned long) flags,\n\t                     (long) ((flags & DUK__IVAL_FLAG_ALLOW_CONST) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_SHORT) ? 1 : 0)));\n\n\tswitch (x->t) {\n\tcase DUK_ISPEC_VALUE: {\n\t\tduk_tval *tv;\n\n\t\ttv = DUK_GET_TVAL_POSIDX(thr, x->valstack_idx);\n\t\tDUK_ASSERT(tv != NULL);\n\n\t\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\t\tcase DUK_TAG_UNDEFINED: {\n\t\t\t/* Note: although there is no 'undefined' literal, undefined\n\t\t\t * values can occur during compilation as a result of e.g.\n\t\t\t * the 'void' operator.\n\t\t\t */\n\t\t\tduk_regconst_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_LDUNDEF, dest);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_NULL: {\n\t\t\tduk_regconst_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_LDNULL, dest);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_BOOLEAN: {\n\t\t\tduk_regconst_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             (DUK_TVAL_GET_BOOLEAN(tv) ? DUK_OP_LDTRUE : DUK_OP_LDFALSE),\n\t\t\t             dest);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_POINTER: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_STRING: {\n\t\t\tduk_hstring *h;\n\t\t\tduk_regconst_t dest;\n\t\t\tduk_regconst_t constidx;\n\n\t\t\th = DUK_TVAL_GET_STRING(tv);\n\t\t\tDUK_UNREF(h);\n\t\t\tDUK_ASSERT(h != NULL);\n\n#if 0  /* XXX: to be implemented? */\n\t\t\t/* Use special opcodes to load short strings */\n\t\t\tif (DUK_HSTRING_GET_BYTELEN(h) <= 2) {\n\t\t\t\t/* Encode into a single opcode (18 bits can encode 1-2 bytes + length indicator) */\n\t\t\t} else if (DUK_HSTRING_GET_BYTELEN(h) <= 6) {\n\t\t\t\t/* Encode into a double constant (53 bits can encode 6*8 = 48 bits + 3-bit length */\n\t\t\t}\n#endif\n\t\t\tduk_dup(thr, x->valstack_idx);\n\t\t\tconstidx = duk__getconst(comp_ctx);\n\n\t\t\tif (flags & DUK__IVAL_FLAG_ALLOW_CONST) {\n\t\t\t\treturn constidx;\n\t\t\t}\n\n\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, constidx);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_OBJECT: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_BUFFER: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_LIGHTFUNC: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_FASTINT)\n\t\tcase DUK_TAG_FASTINT:\n#endif\n\t\tdefault: {\n\t\t\t/* number */\n\t\t\tduk_regconst_t dest;\n\t\t\tduk_regconst_t constidx;\n\t\t\tduk_double_t dval;\n\t\t\tduk_int32_t ival;\n\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\t\tdval = DUK_TVAL_GET_NUMBER(tv);\n\n\t\t\tif (!(flags & DUK__IVAL_FLAG_ALLOW_CONST)) {\n\t\t\t\t/* A number can be loaded either through a constant, using\n\t\t\t\t * LDINT, or using LDINT+LDINTX.  LDINT is always a size win,\n\t\t\t\t * LDINT+LDINTX is not if the constant is used multiple times.\n\t\t\t\t * Currently always prefer LDINT+LDINTX over a double constant.\n\t\t\t\t */\n\n\t\t\t\tif (duk_is_whole_get_int32_nonegzero(dval, &ival)) {\n\t\t\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\t\t\tduk__emit_load_int32(comp_ctx, dest, ival);\n\t\t\t\t\treturn dest;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_dup(thr, x->valstack_idx);\n\t\t\tconstidx = duk__getconst(comp_ctx);\n\n\t\t\tif (flags & DUK__IVAL_FLAG_ALLOW_CONST) {\n\t\t\t\treturn constidx;\n\t\t\t} else {\n\t\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, constidx);\n\t\t\t\treturn dest;\n\t\t\t}\n\t\t}\n\t\t}  /* end switch */\n\t\tgoto fail_internal;  /* never here */\n\t}\n\tcase DUK_ISPEC_REGCONST: {\n\t\tif (forced_reg >= 0) {\n\t\t\tif (DUK__ISCONST(x->regconst)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, forced_reg, x->regconst);\n\t\t\t} else if (x->regconst != forced_reg) {\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDREG, forced_reg, x->regconst);\n\t\t\t} else {\n\t\t\t\t; /* already in correct reg */\n\t\t\t}\n\t\t\treturn forced_reg;\n\t\t}\n\n\t\tDUK_ASSERT(forced_reg < 0);\n\t\tif (DUK__ISCONST(x->regconst)) {\n\t\t\tif (!(flags & DUK__IVAL_FLAG_ALLOW_CONST)) {\n\t\t\t\tduk_regconst_t dest = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, x->regconst);\n\t\t\t\treturn dest;\n\t\t\t}\n\t\t\treturn x->regconst;\n\t\t}\n\n\t\tDUK_ASSERT(forced_reg < 0 && !DUK__ISCONST(x->regconst));\n\t\tif ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) && !DUK__ISREG_TEMP(comp_ctx, x->regconst)) {\n\t\t\tduk_regconst_t dest = DUK__ALLOCTEMP(comp_ctx);\n\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDREG, dest, x->regconst);\n\t\t\treturn dest;\n\t\t}\n\t\treturn x->regconst;\n\t}\n\tdefault: {\n\t\tbreak;  /* never here */\n\t}\n\t}\n\n fail_internal:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_LOCAL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ispec *x, duk_regconst_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\t(void) duk__ispec_toregconst_raw(comp_ctx, x, forced_reg, 0 /*flags*/);\n}\n\n/* Coerce an duk_ivalue to a 'plain' value by generating the necessary\n * arithmetic operations, property access, or variable access bytecode.\n * The duk_ivalue argument ('x') is converted into a plain value as a\n * side effect.\n */\nDUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_regconst_t forced_reg) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__ivalue_toplain_raw(): x={t=%ld,op=%ld,x1={%ld:%ld:%!T},x2={%ld:%ld:%!T}}, \"\n\t                     \"forced_reg=%ld\",\n\t                     (long) x->t, (long) x->op,\n\t                     (long) x->x1.t, (long) x->x1.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x1.valstack_idx),\n\t                     (long) x->x2.t, (long) x->x2.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x2.valstack_idx),\n\t                     (long) forced_reg));\n\n\tswitch (x->t) {\n\tcase DUK_IVAL_PLAIN: {\n\t\treturn;\n\t}\n\t/* XXX: support unary arithmetic ivalues (useful?) */\n\tcase DUK_IVAL_ARITH: {\n\t\tduk_regconst_t arg1;\n\t\tduk_regconst_t arg2;\n\t\tduk_regconst_t dest;\n\t\tduk_tval *tv1;\n\t\tduk_tval *tv2;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"arith to plain conversion\"));\n\n\t\t/* inline arithmetic check for constant values */\n\t\t/* XXX: use the exactly same arithmetic function here as in executor */\n\t\tif (x->x1.t == DUK_ISPEC_VALUE && x->x2.t == DUK_ISPEC_VALUE && x->t == DUK_IVAL_ARITH) {\n\t\t\ttv1 = DUK_GET_TVAL_POSIDX(thr, x->x1.valstack_idx);\n\t\t\ttv2 = DUK_GET_TVAL_POSIDX(thr, x->x2.valstack_idx);\n\t\t\tDUK_ASSERT(tv1 != NULL);\n\t\t\tDUK_ASSERT(tv2 != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"arith: tv1=%!T, tv2=%!T\",\n\t\t\t                     (duk_tval *) tv1,\n\t\t\t                     (duk_tval *) tv2));\n\n\t\t\tif (DUK_TVAL_IS_NUMBER(tv1) && DUK_TVAL_IS_NUMBER(tv2)) {\n\t\t\t\tduk_double_t d1 = DUK_TVAL_GET_NUMBER(tv1);\n\t\t\t\tduk_double_t d2 = DUK_TVAL_GET_NUMBER(tv2);\n\t\t\t\tduk_double_t d3;\n\t\t\t\tduk_bool_t accept_fold = 1;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"arith inline check: d1=%lf, d2=%lf, op=%ld\",\n\t\t\t\t                     (double) d1, (double) d2, (long) x->op));\n\t\t\t\tswitch (x->op) {\n\t\t\t\tcase DUK_OP_ADD: {\n\t\t\t\t\td3 = d1 + d2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_SUB: {\n\t\t\t\t\td3 = d1 - d2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_MUL: {\n\t\t\t\t\td3 = d1 * d2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_DIV: {\n\t\t\t\t\t/* Division-by-zero is undefined\n\t\t\t\t\t * behavior, so rely on a helper.\n\t\t\t\t\t */\n\t\t\t\t\td3 = duk_double_div(d1, d2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_EXP: {\n\t\t\t\t\td3 = (duk_double_t) duk_js_arith_pow((double) d1, (double) d2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\td3 = 0.0;  /* Won't be used, but silence MSVC /W4 warning. */\n\t\t\t\t\taccept_fold = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (accept_fold) {\n\t\t\t\t\tduk_double_union du;\n\t\t\t\t\tdu.d = d3;\n\t\t\t\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\t\t\t\t\td3 = du.d;\n\n\t\t\t\t\tx->t = DUK_IVAL_PLAIN;\n\t\t\t\t\tDUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE);\n\t\t\t\t\tDUK_TVAL_SET_NUMBER(tv1, d3);  /* old value is number: no refcount */\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else if (x->op == DUK_OP_ADD && DUK_TVAL_IS_STRING(tv1) && DUK_TVAL_IS_STRING(tv2)) {\n\t\t\t\t/* Inline string concatenation.  No need to check for\n\t\t\t\t * symbols, as all inputs are valid ECMAScript strings.\n\t\t\t\t */\n\t\t\t\tduk_dup(thr, x->x1.valstack_idx);\n\t\t\t\tduk_dup(thr, x->x2.valstack_idx);\n\t\t\t\tduk_concat(thr, 2);\n\t\t\t\tduk_replace(thr, x->x1.valstack_idx);\n\t\t\t\tx->t = DUK_IVAL_PLAIN;\n\t\t\t\tDUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\targ1 = duk__ispec_toregconst_raw(comp_ctx, &x->x1, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\t\targ2 = duk__ispec_toregconst_raw(comp_ctx, &x->x2, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\n\t\t/* If forced reg, use it as destination.  Otherwise try to\n\t\t * use either coerced ispec if it is a temporary.\n\t\t */\n\t\tif (forced_reg >= 0) {\n\t\t\tdest = forced_reg;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg1)) {\n\t\t\tdest = arg1;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg2)) {\n\t\t\tdest = arg2;\n\t\t} else {\n\t\t\tdest = DUK__ALLOCTEMP(comp_ctx);\n\t\t}\n\n\t\tDUK_ASSERT(DUK__ISREG(dest));\n\t\tduk__emit_a_b_c(comp_ctx, x->op | DUK__EMIT_FLAG_BC_REGCONST, dest, arg1, arg2);\n\n\t\tduk__ivalue_regconst(x, dest);\n\t\treturn;\n\t}\n\tcase DUK_IVAL_PROP: {\n\t\t/* XXX: very similar to DUK_IVAL_ARITH - merge? */\n\t\tduk_regconst_t arg1;\n\t\tduk_regconst_t arg2;\n\t\tduk_regconst_t dest;\n\n\t\t/* Need a short reg/const, does not have to be a mutable temp. */\n\t\targ1 = duk__ispec_toregconst_raw(comp_ctx, &x->x1, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\t\targ2 = duk__ispec_toregconst_raw(comp_ctx, &x->x2, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\n\t\t/* Pick a destination register.  If either base value or key\n\t\t * happens to be a temp value, reuse it as the destination.\n\t\t *\n\t\t * XXX: The temp must be a \"mutable\" one, i.e. such that no\n\t\t * other expression is using it anymore.  Here this should be\n\t\t * the case because the value of a property access expression\n\t\t * is neither the base nor the key, but the lookup result.\n\t\t */\n\n\t\tif (forced_reg >= 0) {\n\t\t\tdest = forced_reg;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg1)) {\n\t\t\tdest = arg1;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg2)) {\n\t\t\tdest = arg2;\n\t\t} else {\n\t\t\tdest = DUK__ALLOCTEMP(comp_ctx);\n\t\t}\n\n\t\tduk__emit_a_b_c(comp_ctx,\n\t\t                DUK_OP_GETPROP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t                dest,\n\t\t                arg1,\n\t\t                arg2);\n\n\t\tduk__ivalue_regconst(x, dest);\n\t\treturn;\n\t}\n\tcase DUK_IVAL_VAR: {\n\t\t/* x1 must be a string */\n\t\tduk_regconst_t dest;\n\t\tduk_regconst_t reg_varbind;\n\t\tduk_regconst_t rc_varname;\n\n\t\tDUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE);\n\n\t\tduk_dup(thr, x->x1.valstack_idx);\n\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\tduk__ivalue_regconst(x, reg_varbind);\n\t\t} else {\n\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_GETVAR, dest, rc_varname);\n\t\t\tduk__ivalue_regconst(x, dest);\n\t\t}\n\t\treturn;\n\t}\n\tcase DUK_IVAL_NONE:\n\tdefault: {\n\t\tDUK_D(DUK_DPRINT(\"invalid ivalue type: %ld\", (long) x->t));\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* evaluate to plain value, no forced register (temp/bound reg both ok) */\nDUK_LOCAL void duk__ivalue_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tduk__ivalue_toplain_raw(comp_ctx, x, -1 /*forced_reg*/);\n}\n\n/* evaluate to final form (e.g. coerce GETPROP to code), throw away temp */\nDUK_LOCAL void duk__ivalue_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tduk_regconst_t temp;\n\n\t/* If duk__ivalue_toplain_raw() allocates a temp, forget it and\n\t * restore next temp state.\n\t */\n\ttemp = DUK__GETTEMP(comp_ctx);\n\tduk__ivalue_toplain_raw(comp_ctx, x, -1 /*forced_reg*/);\n\tDUK__SETTEMP(comp_ctx, temp);\n}\n\n/* Coerce an duk_ivalue to a register or constant; result register may\n * be a temp or a bound register.\n *\n * The duk_ivalue argument ('x') is converted into a regconst as a\n * side effect.\n */\nDUK_LOCAL\nduk_regconst_t duk__ivalue_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                          duk_ivalue *x,\n                                          duk_regconst_t forced_reg,\n                                          duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg;\n\tDUK_UNREF(thr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__ivalue_toregconst_raw(): x={t=%ld,op=%ld,x1={%ld:%ld:%!T},x2={%ld:%ld:%!T}}, \"\n\t                     \"forced_reg=%ld, flags 0x%08lx: allow_const=%ld require_temp=%ld require_short=%ld\",\n\t                     (long) x->t, (long) x->op,\n\t                     (long) x->x1.t, (long) x->x1.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x1.valstack_idx),\n\t                     (long) x->x2.t, (long) x->x2.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x2.valstack_idx),\n\t                     (long) forced_reg,\n\t                     (unsigned long) flags,\n\t                     (long) ((flags & DUK__IVAL_FLAG_ALLOW_CONST) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_SHORT) ? 1 : 0)));\n\n\t/* first coerce to a plain value */\n\tduk__ivalue_toplain_raw(comp_ctx, x, forced_reg);\n\tDUK_ASSERT(x->t == DUK_IVAL_PLAIN);\n\n\t/* then to a register */\n\treg = duk__ispec_toregconst_raw(comp_ctx, &x->x1, forced_reg, flags);\n\tduk__ivalue_regconst(x, reg);\n\n\treturn reg;\n}\n\nDUK_LOCAL duk_regconst_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, 0 /*flags*/);\n}\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__ivalue_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/);\n}\n#endif\n\nDUK_LOCAL void duk__ivalue_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_int_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\t(void) duk__ivalue_toregconst_raw(comp_ctx, x, forced_reg, 0 /*flags*/);\n}\n\nDUK_LOCAL duk_regconst_t duk__ivalue_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n}\n\nDUK_LOCAL duk_regconst_t duk__ivalue_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/);\n}\n\n/* The issues below can be solved with better flags */\n\n/* XXX: many operations actually want toforcedtemp() -- brand new temp? */\n/* XXX: need a toplain_ignore() which will only coerce a value to a temp\n * register if it might have a side effect.  Side-effect free values do not\n * need to be coerced.\n */\n\n/*\n *  Identifier handling\n */\n\nDUK_LOCAL duk_regconst_t duk__lookup_active_register_binding(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hstring *h_varname;\n\tduk_regconst_t ret;\n\n\tDUK_DDD(DUK_DDDPRINT(\"resolving identifier reference to '%!T'\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/*\n\t *  Special name handling\n\t */\n\n\th_varname = duk_known_hstring(thr, -1);\n\n\tif (h_varname == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"flagging function as accessing 'arguments'\"));\n\t\tcomp_ctx->curr_func.id_access_arguments = 1;\n\t}\n\n\t/*\n\t *  Inside one or more 'with' statements fall back to slow path always.\n\t *  (See e.g. test-stmt-with.js.)\n\t */\n\n\tif (comp_ctx->curr_func.with_depth > 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup inside a 'with' -> fall back to slow path\"));\n\t\tgoto slow_path_own;\n\t}\n\n\t/*\n\t *  Any catch bindings (\"catch (e)\") also affect identifier binding.\n\t *\n\t *  Currently, the varmap is modified for the duration of the catch\n\t *  clause to ensure any identifier accesses with the catch variable\n\t *  name will use slow path.\n\t */\n\n\tduk_get_prop(thr, comp_ctx->curr_func.varmap_idx);\n\tif (duk_is_number(thr, -1)) {\n\t\tret = duk_to_int(thr, -1);\n\t\tduk_pop(thr);\n\t} else {\n\t\tduk_pop(thr);\n\t\tif (comp_ctx->curr_func.catch_depth > 0 || comp_ctx->curr_func.with_depth > 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slow path access from inside a try-catch or with needs _Varmap\"));\n\t\t\tgoto slow_path_own;\n\t\t} else {\n\t\t\t/* In this case we're doing a variable lookup that doesn't\n\t\t\t * match our own variables, so _Varmap won't be needed at\n\t\t\t * run time.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slow path access outside of try-catch and with, no need for _Varmap\"));\n\t\t\tgoto slow_path_notown;\n\t\t}\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup -> reg %ld\", (long) ret));\n\treturn ret;\n\n slow_path_notown:\n\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup -> slow path, not own variable\"));\n\n\tcomp_ctx->curr_func.id_access_slow = 1;\n\treturn (duk_regconst_t) -1;\n\n slow_path_own:\n\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup -> slow path, may be own variable\"));\n\n\tcomp_ctx->curr_func.id_access_slow = 1;\n\tcomp_ctx->curr_func.id_access_slow_own = 1;\n\treturn (duk_regconst_t) -1;\n}\n\n/* Lookup an identifier name in the current varmap, indicating whether the\n * identifier is register-bound and if not, allocating a constant for the\n * identifier name.  Returns 1 if register-bound, 0 otherwise.  Caller can\n * also check (out_reg_varbind >= 0) to check whether or not identifier is\n * register bound.  The caller must NOT use out_rc_varname at all unless\n * return code is 0 or out_reg_varbind is < 0; this is becuase out_rc_varname\n * is unsigned and doesn't have a \"unused\" / none value.\n */\nDUK_LOCAL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *comp_ctx, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg_varbind;\n\tduk_regconst_t rc_varname;\n\n\t/* [ ... varname ] */\n\n\tduk_dup_top(thr);\n\treg_varbind = duk__lookup_active_register_binding(comp_ctx);\n\n\tif (reg_varbind >= 0) {\n\t\t*out_reg_varbind = reg_varbind;\n\t\t*out_rc_varname = 0;  /* duk_regconst_t is unsigned, so use 0 as dummy value (ignored by caller) */\n\t\tduk_pop(thr);\n\t\treturn 1;\n\t} else {\n\t\trc_varname = duk__getconst(comp_ctx);\n\t\t*out_reg_varbind = -1;\n\t\t*out_rc_varname = rc_varname;\n\t\treturn 0;\n\t}\n}\n\n/*\n *  Label handling\n *\n *  Labels are initially added with flags prohibiting both break and continue.\n *  When the statement type is finally uncovered (after potentially multiple\n *  labels), all the labels are updated to allow/prohibit break and continue.\n */\n\nDUK_LOCAL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_int_t pc_label, duk_int_t label_id) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_size_t n;\n\tduk_size_t new_size;\n\tduk_uint8_t *p;\n\tduk_labelinfo *li_start, *li;\n\n\t/* Duplicate (shadowing) labels are not allowed, except for the empty\n\t * labels (which are used as default labels for switch and iteration\n\t * statements).\n\t *\n\t * We could also allow shadowing of non-empty pending labels without any\n\t * other issues than breaking the required label shadowing requirements\n\t * of the E5 specification, see Section 12.12.\n\t */\n\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tli = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\tn = (duk_size_t) (li - li_start);\n\n\twhile (li > li_start) {\n\t\tli--;\n\n\t\tif (li->h_label == h_label && h_label != DUK_HTHREAD_STRING_EMPTY_STRING(thr)) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_DUPLICATE_LABEL);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t}\n\n\tduk_push_hstring(thr, h_label);\n\tDUK_ASSERT(n <= DUK_UARRIDX_MAX);  /* label limits */\n\t(void) duk_put_prop_index(thr, comp_ctx->curr_func.labelnames_idx, (duk_uarridx_t) n);\n\n\tnew_size = (n + 1) * sizeof(duk_labelinfo);\n\tduk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, new_size);\n\t/* XXX: slack handling, slow now */\n\n\t/* relookup after possible realloc */\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tDUK_UNREF(li_start);  /* silence scan-build warning */\n\tli = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\tli--;\n\n\t/* Labels can be used for iteration statements but also for other statements,\n\t * in particular a label can be used for a block statement.  All cases of a\n\t * named label accept a 'break' so that flag is set here.  Iteration statements\n\t * also allow 'continue', so that flag is updated when we figure out the\n\t * statement type.\n\t */\n\n\tli->flags = DUK_LABEL_FLAG_ALLOW_BREAK;\n\tli->label_id = label_id;\n\tli->h_label = h_label;\n\tli->catch_depth = comp_ctx->curr_func.catch_depth;   /* catch depth from current func */\n\tli->pc_label = pc_label;\n\n\tDUK_DDD(DUK_DDDPRINT(\"registered label: flags=0x%08lx, id=%ld, name=%!O, catch_depth=%ld, pc_label=%ld\",\n\t                     (unsigned long) li->flags, (long) li->label_id, (duk_heaphdr *) li->h_label,\n\t                     (long) li->catch_depth, (long) li->pc_label));\n}\n\n/* Update all labels with matching label_id. */\nDUK_LOCAL void duk__update_label_flags(duk_compiler_ctx *comp_ctx, duk_int_t label_id, duk_small_uint_t flags) {\n\tduk_uint8_t *p;\n\tduk_labelinfo *li_start, *li;\n\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(comp_ctx->thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tli = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\n\t/* Match labels starting from latest; once label_id no longer matches, we can\n\t * safely exit without checking the rest of the labels (only the topmost labels\n\t * are ever updated).\n\t */\n\twhile (li > li_start) {\n\t\tli--;\n\n\t\tif (li->label_id != label_id) {\n\t\t\tbreak;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"updating (overwriting) label flags for li=%p, label_id=%ld, flags=%ld\",\n\t\t                     (void *) li, (long) label_id, (long) flags));\n\n\t\tli->flags = flags;\n\t}\n}\n\n/* Lookup active label information.  Break/continue distinction is necessary to handle switch\n * statement related labels correctly: a switch will only catch a 'break', not a 'continue'.\n *\n * An explicit label cannot appear multiple times in the active set, but empty labels (unlabelled\n * iteration and switch statements) can.  A break will match the closest unlabelled or labelled\n * statement.  A continue will match the closest unlabelled or labelled iteration statement.  It is\n * a syntax error if a continue matches a labelled switch statement; because an explicit label cannot\n * be duplicated, the continue cannot match any valid label outside the switch.\n *\n * A side effect of these rules is that a LABEL statement related to a switch should never actually\n * catch a continue abrupt completion at run-time.  Hence an INVALID opcode can be placed in the\n * continue slot of the switch's LABEL statement.\n */\n\n/* XXX: awkward, especially the bunch of separate output values -> output struct? */\nDUK_LOCAL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_bool_t is_break, duk_int_t *out_label_id, duk_int_t *out_label_catch_depth, duk_int_t *out_label_pc, duk_bool_t *out_is_closest) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_uint8_t *p;\n\tduk_labelinfo *li_start, *li_end, *li;\n\tduk_bool_t match = 0;\n\n\tDUK_DDD(DUK_DDDPRINT(\"looking up active label: label='%!O', is_break=%ld\",\n\t                     (duk_heaphdr *) h_label, (long) is_break));\n\n\tDUK_UNREF(thr);\n\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tli_end = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\tli = li_end;\n\n\t/* Match labels starting from latest label because there can be duplicate empty\n\t * labels in the label set.\n\t */\n\twhile (li > li_start) {\n\t\tli--;\n\n\t\tif (li->h_label != h_label) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"labelinfo[%ld] ->'%!O' != %!O\",\n\t\t\t                     (long) (li - li_start),\n\t\t\t                     (duk_heaphdr *) li->h_label,\n\t\t\t                     (duk_heaphdr *) h_label));\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"labelinfo[%ld] -> '%!O' label name matches (still need to check type)\",\n\t\t                     (long) (li - li_start), (duk_heaphdr *) h_label));\n\n\t\t/* currently all labels accept a break, so no explicit check for it now */\n\t\tDUK_ASSERT(li->flags & DUK_LABEL_FLAG_ALLOW_BREAK);\n\n\t\tif (is_break) {\n\t\t\t/* break matches always */\n\t\t\tmatch = 1;\n\t\t\tbreak;\n\t\t} else if (li->flags & DUK_LABEL_FLAG_ALLOW_CONTINUE) {\n\t\t\t/* iteration statements allow continue */\n\t\t\tmatch = 1;\n\t\t\tbreak;\n\t\t} else {\n\t\t\t/* continue matched this label -- we can only continue if this is the empty\n\t\t\t * label, for which duplication is allowed, and thus there is hope of\n\t\t\t * finding a match deeper in the label stack.\n\t\t\t */\n\t\t\tif (h_label != DUK_HTHREAD_STRING_EMPTY_STRING(thr)) {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LABEL);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"continue matched an empty label which does not \"\n\t\t\t\t                     \"allow a continue -> continue lookup deeper in label stack\"));\n\t\t\t}\n\t\t}\n\t}\n\t/* XXX: match flag is awkward, rework */\n\tif (!match) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LABEL);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"label match: %!O -> label_id %ld, catch_depth=%ld, pc_label=%ld\",\n\t                     (duk_heaphdr *) h_label, (long) li->label_id,\n\t                     (long) li->catch_depth, (long) li->pc_label));\n\n\t*out_label_id = li->label_id;\n\t*out_label_catch_depth = li->catch_depth;\n\t*out_label_pc = li->pc_label;\n\t*out_is_closest = (li == li_end - 1);\n}\n\nDUK_LOCAL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, duk_size_t len) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\tduk_set_length(thr, comp_ctx->curr_func.labelnames_idx, len);\n\tduk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, sizeof(duk_labelinfo) * len);\n}\n\n/*\n *  Expression parsing: duk__expr_nud(), duk__expr_led(), duk__expr_lbp(), and helpers.\n *\n *  - duk__expr_nud(): (\"null denotation\"): process prev_token as a \"start\" of an expression (e.g. literal)\n *  - duk__expr_led(): (\"left denotation\"): process prev_token in the \"middle\" of an expression (e.g. operator)\n *  - duk__expr_lbp(): (\"left-binding power\"): return left-binding power of curr_token\n */\n\n/* object literal key tracking flags */\n#define DUK__OBJ_LIT_KEY_PLAIN  (1 << 0)  /* key encountered as a plain property */\n#define DUK__OBJ_LIT_KEY_GET    (1 << 1)  /* key encountered as a getter */\n#define DUK__OBJ_LIT_KEY_SET    (1 << 2)  /* key encountered as a setter */\n\nDUK_LOCAL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg_obj;                 /* result reg */\n\tduk_regconst_t reg_temp;                /* temp reg */\n\tduk_regconst_t temp_start;              /* temp reg value for start of loop */\n\tduk_small_uint_t max_init_values;  /* max # of values initialized in one MPUTARR set */\n\tduk_small_uint_t num_values;       /* number of values in current MPUTARR set */\n\tduk_uarridx_t curr_idx;            /* current (next) array index */\n\tduk_uarridx_t start_idx;           /* start array index of current MPUTARR set */\n\tduk_uarridx_t init_idx;            /* last array index explicitly initialized, +1 */\n\tduk_bool_t require_comma;          /* next loop requires a comma */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tduk_int_t pc_newarr;\n\tduk_compiler_instr *instr;\n#endif\n\n\t/* DUK_TOK_LBRACKET already eaten, current token is right after that */\n\tDUK_ASSERT(comp_ctx->prev_token.t == DUK_TOK_LBRACKET);\n\n\tmax_init_values = DUK__MAX_ARRAY_INIT_VALUES;  /* XXX: depend on available temps? */\n\n\treg_obj = DUK__ALLOCTEMP(comp_ctx);\n#if !defined(DUK_USE_PREFER_SIZE)\n\tpc_newarr = duk__get_current_pc(comp_ctx);\n#endif\n\tduk__emit_bc(comp_ctx, DUK_OP_NEWARR, reg_obj);  /* XXX: patch initial size hint afterwards? */\n\ttemp_start = DUK__GETTEMP(comp_ctx);\n\n\t/*\n\t *  Emit initializers in sets of maximum max_init_values.\n\t *  Corner cases such as single value initializers do not have\n\t *  special handling now.\n\t *\n\t *  Elided elements must not be emitted as 'undefined' values,\n\t *  because such values would be enumerable (which is incorrect).\n\t *  Also note that trailing elisions must be reflected in the\n\t *  length of the final array but cause no elements to be actually\n\t *  inserted.\n\t */\n\n\tcurr_idx = 0;\n\tinit_idx = 0;         /* tracks maximum initialized index + 1 */\n\tstart_idx = 0;\n\trequire_comma = 0;\n\n\tfor (;;) {\n\t\tnum_values = 0;\n\t\tDUK__SETTEMP(comp_ctx, temp_start);\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RBRACKET) {\n\t\t\tbreak;\n\t\t}\n\n\t\tfor (;;) {\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_RBRACKET) {\n\t\t\t\t/* the outer loop will recheck and exit */\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/* comma check */\n\t\t\tif (require_comma) {\n\t\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_COMMA) {\n\t\t\t\t\t/* comma after a value, expected */\n\t\t\t\t\tduk__advance(comp_ctx);\n\t\t\t\t\trequire_comma = 0;\n\t\t\t\t\tcontinue;\n\t\t\t\t} else {\n\t\t\t\t\tgoto syntax_error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_COMMA) {\n\t\t\t\t\t/* elision - flush */\n\t\t\t\t\tcurr_idx++;\n\t\t\t\t\tduk__advance(comp_ctx);\n\t\t\t\t\t/* if num_values > 0, MPUTARR emitted by outer loop after break */\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* else an array initializer element */\n\n\t\t\t/* initial index */\n\t\t\tif (num_values == 0) {\n\t\t\t\tstart_idx = curr_idx;\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_load_int32(comp_ctx, reg_temp, (duk_int32_t) start_idx);\n\t\t\t}\n\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);   /* alloc temp just in case, to update max temp */\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp);\n\t\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp /*forced_reg*/);\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\n\t\t\tnum_values++;\n\t\t\tcurr_idx++;\n\t\t\trequire_comma = 1;\n\n\t\t\tif (num_values >= max_init_values) {\n\t\t\t\t/* MPUTARR emitted by outer loop */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (num_values > 0) {\n\t\t\t/* - A is a source register (it's not a write target, but used\n\t\t\t *   to identify the target object) but can be shuffled.\n\t\t\t * - B cannot be shuffled normally because it identifies a range\n\t\t\t *   of registers, the emitter has special handling for this\n\t\t\t *   (the \"no shuffle\" flag must not be set).\n\t\t\t * - C is a non-register number and cannot be shuffled, but\n\t\t\t *   never needs to be.\n\t\t\t */\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_MPUTARR |\n\t\t\t                    DUK__EMIT_FLAG_NO_SHUFFLE_C |\n\t\t\t                    DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t                reg_obj,\n\t\t\t                temp_start,\n\t\t\t                (duk_regconst_t) (num_values + 1));\n\t\t\tinit_idx = start_idx + num_values;\n\n\t\t\t/* num_values and temp_start reset at top of outer loop */\n\t\t}\n\t}\n\n\t/* Update initil size for NEWARR, doesn't need to be exact and is\n\t * capped at A field limit.\n\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tinstr = duk__get_instr_ptr(comp_ctx, pc_newarr);\n\tinstr->ins |= DUK_ENC_OP_A(0, curr_idx > DUK_BC_A_MAX ? DUK_BC_A_MAX : curr_idx);\n#endif\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RBRACKET);\n\tduk__advance(comp_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"array literal done, curridx=%ld, initidx=%ld\",\n\t                     (long) curr_idx, (long) init_idx));\n\n\t/* trailing elisions? */\n\tif (curr_idx > init_idx) {\n\t\t/* yes, must set array length explicitly */\n\t\tDUK_DDD(DUK_DDDPRINT(\"array literal has trailing elisions which affect its length\"));\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk__emit_load_int32(comp_ctx, reg_temp, (duk_int_t) curr_idx);\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               DUK_OP_SETALEN | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t               reg_obj,\n\t\t               reg_temp);\n\t}\n\n\tDUK__SETTEMP(comp_ctx, temp_start);\n\n\tduk__ivalue_regconst(res, reg_obj);\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_ARRAY_LITERAL);\n\tDUK_WO_NORETURN(return;);\n}\n\ntypedef struct {\n\tduk_regconst_t reg_obj;\n\tduk_regconst_t temp_start;\n\tduk_small_uint_t num_pairs;\n\tduk_small_uint_t num_total_pairs;\n} duk__objlit_state;\n\nDUK_LOCAL void duk__objlit_flush_keys(duk_compiler_ctx *comp_ctx, duk__objlit_state *st) {\n\tif (st->num_pairs > 0) {\n\t\t/* - A is a source register (it's not a write target, but used\n\t\t *   to identify the target object) but can be shuffled.\n\t\t * - B cannot be shuffled normally because it identifies a range\n\t\t *   of registers, the emitter has special handling for this\n\t\t *   (the \"no shuffle\" flag must not be set).\n\t\t * - C is a non-register number and cannot be shuffled, but\n\t\t *   never needs to be.\n\t\t */\n\t\tDUK_ASSERT(st->num_pairs > 0);\n\t\tduk__emit_a_b_c(comp_ctx,\n\t\t                DUK_OP_MPUTOBJ |\n\t\t                    DUK__EMIT_FLAG_NO_SHUFFLE_C |\n\t\t                    DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t                st->reg_obj,\n\t\t                st->temp_start,\n\t\t                (duk_regconst_t) (st->num_pairs * 2));\n\t\tst->num_total_pairs += st->num_pairs;\n\t\tst->num_pairs = 0;\n\t}\n\tDUK__SETTEMP(comp_ctx, st->temp_start);\n}\n\nDUK_LOCAL duk_bool_t duk__objlit_load_key(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_token *tok, duk_regconst_t reg_temp) {\n\tif (tok->t_nores == DUK_TOK_IDENTIFIER || tok->t_nores == DUK_TOK_STRING) {\n\t\t/* same handling for identifiers and strings */\n\t\tDUK_ASSERT(tok->str1 != NULL);\n\t\tduk_push_hstring(comp_ctx->thr, tok->str1);\n\t} else if (tok->t == DUK_TOK_NUMBER) {\n\t\t/* numbers can be loaded as numbers and coerced on the fly */\n\t\tduk_push_number(comp_ctx->thr, tok->num);\n\t} else {\n\t\treturn 1;  /* error */\n\t}\n\n\tduk__ivalue_plain_fromstack(comp_ctx, res);\n\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\tduk__ivalue_toforcedreg(comp_ctx, res, reg_temp);\n\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\treturn 0;\n}\n\nDUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk__objlit_state st;\n\tduk_regconst_t reg_temp;          /* temp reg */\n\tduk_small_uint_t max_init_pairs;  /* max # of key-value pairs initialized in one MPUTOBJ set */\n\tduk_bool_t first;                 /* first value: comma must not precede the value */\n\tduk_bool_t is_set, is_get;        /* temps */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tduk_int_t pc_newobj;\n\tduk_compiler_instr *instr;\n#endif\n\n\tDUK_ASSERT(comp_ctx->prev_token.t == DUK_TOK_LCURLY);\n\n\tmax_init_pairs = DUK__MAX_OBJECT_INIT_PAIRS;  /* XXX: depend on available temps? */\n\n\tst.reg_obj = DUK__ALLOCTEMP(comp_ctx);    /* target object */\n\tst.temp_start = DUK__GETTEMP(comp_ctx);   /* start of MPUTOBJ argument list */\n\tst.num_pairs = 0;                         /* number of key/value pairs emitted for current MPUTOBJ set */\n\tst.num_total_pairs = 0;                   /* number of key/value pairs emitted overall */\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\tpc_newobj = duk__get_current_pc(comp_ctx);\n#endif\n\tduk__emit_bc(comp_ctx, DUK_OP_NEWOBJ, st.reg_obj);\n\n\t/*\n\t *  Emit initializers in sets of maximum max_init_pairs keys.\n\t *  Setter/getter is handled separately and terminates the\n\t *  current set of initializer values.  Corner cases such as\n\t *  single value initializers do not have special handling now.\n\t */\n\n\tfirst = 1;\n\tfor (;;) {\n\t\t/*\n\t\t *  ES5 and ES2015+ provide a lot of different PropertyDefinition\n\t\t *  formats, see http://www.ecma-international.org/ecma-262/6.0/#sec-object-initializer.\n\t\t *\n\t\t *  PropertyName can be IdentifierName (includes reserved words), a string\n\t\t *  literal, or a number literal.  Note that IdentifierName allows 'get' and\n\t\t *  'set' too, so we need to look ahead to the next token to distinguish:\n\t\t *\n\t\t *     { get : 1 }\n\t\t *\n\t\t *  and\n\t\t *\n\t\t *     { get foo() { return 1 } }\n\t\t *     { get get() { return 1 } }    // 'get' as getter propertyname\n\t\t *\n\t\t *  Finally, a trailing comma is allowed.\n\t\t *\n\t\t *  Key name is coerced to string at compile time (and ends up as a\n\t\t *  a string constant) even for numeric keys (e.g. \"{1:'foo'}\").\n\t\t *  These could be emitted using e.g. LDINT, but that seems hardly\n\t\t *  worth the effort and would increase code size.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"object literal loop, curr_token->t = %ld\",\n\t\t                     (long) comp_ctx->curr_token.t));\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (first) {\n\t\t\tfirst = 0;\n\t\t} else {\n\t\t\tif (comp_ctx->curr_token.t != DUK_TOK_COMMA) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t\tduk__advance(comp_ctx);\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\t\t/* trailing comma followed by rcurly */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* Advance to get one step of lookup. */\n\t\tduk__advance(comp_ctx);\n\n\t\t/* Flush current MPUTOBJ if enough many pairs gathered. */\n\t\tif (st.num_pairs >= max_init_pairs) {\n\t\t\tduk__objlit_flush_keys(comp_ctx, &st);\n\t\t\tDUK_ASSERT(st.num_pairs == 0);\n\t\t}\n\n\t\t/* Reset temp register state and reserve reg_temp and\n\t\t * reg_temp + 1 for handling the current property.\n\t\t */\n\t\tDUK__SETTEMP(comp_ctx, st.temp_start + 2 * (duk_regconst_t) st.num_pairs);\n\t\treg_temp = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\t\t/* NOTE: \"get\" and \"set\" are not officially ReservedWords and the lexer\n\t\t * currently treats them always like ordinary identifiers (DUK_TOK_GET\n\t\t * and DUK_TOK_SET are unused).  They need to be detected based on the\n\t\t * identifier string content.\n\t\t */\n\n\t\tis_get = (comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t          comp_ctx->prev_token.str1 == DUK_HTHREAD_STRING_GET(thr));\n\t\tis_set = (comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t          comp_ctx->prev_token.str1 == DUK_HTHREAD_STRING_SET(thr));\n\t\tif ((is_get || is_set) && comp_ctx->curr_token.t != DUK_TOK_COLON) {\n\t\t\t/* getter/setter */\n\t\t\tduk_int_t fnum;\n\n\t\t\tduk__objlit_flush_keys(comp_ctx, &st);\n\t\t\tDUK_ASSERT(DUK__GETTEMP(comp_ctx) == st.temp_start);  /* 2 regs are guaranteed to be allocated w.r.t. temp_max */\n\t\t\treg_temp = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\t\t\tif (duk__objlit_load_key(comp_ctx, res, &comp_ctx->curr_token, reg_temp) != 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\t/* curr_token = get/set name */\n\t\t\tfnum = duk__parse_func_like_fnum(comp_ctx, DUK__FUNC_FLAG_GETSET);\n\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CLOSURE,\n\t\t\t               st.temp_start + 1,\n\t\t\t               (duk_regconst_t) fnum);\n\n\t\t\t/* Slot C is used in a non-standard fashion (range of regs),\n\t\t\t * emitter code has special handling for it (must not set the\n\t\t\t * \"no shuffle\" flag).\n\t\t\t */\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t              (is_get ? DUK_OP_INITGET : DUK_OP_INITSET) | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t              st.reg_obj,\n\t\t\t              st.temp_start);   /* temp_start+0 = key, temp_start+1 = closure */\n\n\t\t\tDUK_ASSERT(st.num_pairs == 0);  /* temp state is reset on next loop */\n#if defined(DUK_USE_ES6)\n\t\t} else if (comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t           (comp_ctx->curr_token.t == DUK_TOK_COMMA || comp_ctx->curr_token.t == DUK_TOK_RCURLY)) {\n\t\t\tduk_bool_t load_rc;\n\n\t\t\tload_rc = duk__objlit_load_key(comp_ctx, res, &comp_ctx->prev_token, reg_temp);\n\t\t\tDUK_UNREF(load_rc);\n\t\t\tDUK_ASSERT(load_rc == 0);  /* always succeeds because token is identifier */\n\n\t\t\tduk__ivalue_var_hstring(comp_ctx, res, comp_ctx->prev_token.str1);\n\t\t\tDUK_ASSERT(DUK__GETTEMP(comp_ctx) == reg_temp + 1);\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_temp + 1);\n\n\t\t\tst.num_pairs++;\n\t\t} else if ((comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER ||\n\t\t            comp_ctx->prev_token.t == DUK_TOK_STRING ||\n\t\t            comp_ctx->prev_token.t == DUK_TOK_NUMBER) &&\n\t\t           comp_ctx->curr_token.t == DUK_TOK_LPAREN) {\n\t\t\tduk_int_t fnum;\n\n\t\t\t/* Parsing-wise there's a small hickup here: the token parsing\n\t\t\t * state is one step too advanced for the function parse helper\n\t\t\t * compared to other cases.  The current solution is an extra\n\t\t\t * flag to indicate whether function parsing should use the\n\t\t\t * current or the previous token to starting parsing from.\n\t\t\t */\n\n\t\t\tif (duk__objlit_load_key(comp_ctx, res, &comp_ctx->prev_token, reg_temp) != 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\tfnum = duk__parse_func_like_fnum(comp_ctx, DUK__FUNC_FLAG_USE_PREVTOKEN | DUK__FUNC_FLAG_METDEF);\n\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CLOSURE,\n\t\t\t               reg_temp + 1,\n\t\t\t               (duk_regconst_t) fnum);\n\n\t\t\tst.num_pairs++;\n#endif  /* DUK_USE_ES6 */\n\t\t} else {\n#if defined(DUK_USE_ES6)\n\t\t\tif (comp_ctx->prev_token.t == DUK_TOK_LBRACKET) {\n\t\t\t\t/* ES2015 computed property name.  Executor ToPropertyKey()\n\t\t\t\t * coerces the key at runtime.\n\t\t\t\t */\n\t\t\t\tDUK__SETTEMP(comp_ctx, reg_temp);\n\t\t\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_FOR_EXPR, reg_temp);\n\t\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_RBRACKET);\n\n\t\t\t\t/* XXX: If next token is '(' we're dealing with\n\t\t\t\t * the method shorthand with a computed name,\n\t\t\t\t * e.g. { [Symbol.for('foo')](a,b) {} }.  This\n\t\t\t\t * form is not yet supported and causes a\n\t\t\t\t * SyntaxError on the DUK_TOK_COLON check below.\n\t\t\t\t */\n\t\t\t}\n\t\t\telse\n#endif  /* DUK_USE_ES6 */\n\t\t\t{\n\t\t\t\tif (duk__objlit_load_key(comp_ctx, res, &comp_ctx->prev_token, reg_temp) != 0) {\n\t\t\t\t\tgoto syntax_error;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\t\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp + 1 /*forced_reg*/);\n\n\t\t\tst.num_pairs++;\n\t\t}\n\t}  /* property loop */\n\n\t/* Flush remaining properties. */\n\tduk__objlit_flush_keys(comp_ctx, &st);\n\tDUK_ASSERT(st.num_pairs == 0);\n\tDUK_ASSERT(DUK__GETTEMP(comp_ctx) == st.temp_start);\n\n\t/* Update initial size for NEWOBJ.  The init size doesn't need to be\n\t * exact as the purpose is just to avoid object resizes in common\n\t * cases.  The size is capped to field A limit, and will be too high\n\t * if the object literal contains duplicate keys (this is harmless but\n\t * increases memory traffic if the object is compacted later on).\n\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tinstr = duk__get_instr_ptr(comp_ctx, pc_newobj);\n\tinstr->ins |= DUK_ENC_OP_A(0, st.num_total_pairs > DUK_BC_A_MAX ? DUK_BC_A_MAX : st.num_total_pairs);\n#endif\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RCURLY);\n\tduk__advance(comp_ctx);  /* No RegExp after object literal. */\n\n\tduk__ivalue_regconst(res, st.reg_obj);\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_OBJECT_LITERAL);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Parse argument list.  Arguments are written to temps starting from\n * \"next temp\".  Returns number of arguments parsed.  Expects left paren\n * to be already eaten, and eats the right paren before returning.\n */\nDUK_LOCAL duk_int_t duk__parse_arguments(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_int_t nargs = 0;\n\tduk_regconst_t reg_temp;\n\n\t/* Note: expect that caller has already eaten the left paren */\n\n\tDUK_DDD(DUK_DDDPRINT(\"start parsing arguments, prev_token.t=%ld, curr_token.t=%ld\",\n\t                     (long) comp_ctx->prev_token.t, (long) comp_ctx->curr_token.t));\n\n\tfor (;;) {\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RPAREN) {\n\t\t\tbreak;\n\t\t}\n\t\tif (nargs > 0) {\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COMMA);\n\t\t}\n\n\t\t/* We want the argument expression value to go to \"next temp\"\n\t\t * without additional moves.  That should almost always be the\n\t\t * case, but we double check after expression parsing.\n\t\t *\n\t\t * This is not the cleanest possible approach.\n\t\t */\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);  /* bump up \"allocated\" reg count, just in case */\n\t\tDUK__SETTEMP(comp_ctx, reg_temp);\n\n\t\t/* binding power must be high enough to NOT allow comma expressions directly */\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp);  /* always allow 'in', coerce to 'tr' just in case */\n\n\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\t\tnargs++;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"argument #%ld written into reg %ld\", (long) nargs, (long) reg_temp));\n\t}\n\n\t/* eat the right paren */\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* RegExp mode does not matter. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing arguments\"));\n\n\treturn nargs;\n}\n\nDUK_LOCAL duk_bool_t duk__expr_is_empty(duk_compiler_ctx *comp_ctx) {\n\t/* empty expressions can be detected conveniently with nud/led counts */\n\treturn (comp_ctx->curr_func.nud_count == 0) &&\n\t       (comp_ctx->curr_func.led_count == 0);\n}\n\nDUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_token *tk;\n\tduk_regconst_t temp_at_entry;\n\tduk_small_uint_t tok;\n\tduk_uint32_t args;  /* temp variable to pass constants and flags to shared code */\n\n\t/*\n\t *  ctx->prev_token     token to process with duk__expr_nud()\n\t *  ctx->curr_token     updated by caller\n\t *\n\t *  Note: the token in the switch below has already been eaten.\n\t */\n\n\ttemp_at_entry = DUK__GETTEMP(comp_ctx);\n\n\tcomp_ctx->curr_func.nud_count++;\n\n\ttk = &comp_ctx->prev_token;\n\ttok = tk->t;\n\tres->t = DUK_IVAL_NONE;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__expr_nud(), prev_token.t=%ld, allow_in=%ld, paren_level=%ld\",\n\t                     (long) tk->t, (long) comp_ctx->curr_func.allow_in, (long) comp_ctx->curr_func.paren_level));\n\n\tswitch (tok) {\n\n\t/* PRIMARY EXPRESSIONS */\n\n\tcase DUK_TOK_THIS: {\n\t\tduk_regconst_t reg_temp;\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk__emit_bc(comp_ctx,\n\t\t             DUK_OP_LDTHIS,\n\t\t             reg_temp);\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\tcase DUK_TOK_IDENTIFIER: {\n\t\tduk__ivalue_var_hstring(comp_ctx, res, tk->str1);\n\t\treturn;\n\t}\n\tcase DUK_TOK_NULL: {\n\t\tduk_push_null(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_TRUE: {\n\t\tduk_push_true(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_FALSE: {\n\t\tduk_push_false(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_NUMBER: {\n\t\tduk_push_number(thr, tk->num);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_STRING: {\n\t\tDUK_ASSERT(tk->str1 != NULL);\n\t\tduk_push_hstring(thr, tk->str1);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_REGEXP: {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tduk_regconst_t reg_temp;\n\t\tduk_regconst_t rc_re_bytecode;  /* const */\n\t\tduk_regconst_t rc_re_source;    /* const */\n\n\t\tDUK_ASSERT(tk->str1 != NULL);\n\t\tDUK_ASSERT(tk->str2 != NULL);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"emitting regexp op, str1=%!O, str2=%!O\",\n\t\t                     (duk_heaphdr *) tk->str1,\n\t\t                     (duk_heaphdr *) tk->str2));\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk_push_hstring(thr, tk->str1);\n\t\tduk_push_hstring(thr, tk->str2);\n\n\t\t/* [ ... pattern flags ] */\n\n\t\tduk_regexp_compile(thr);\n\n\t\t/* [ ... escaped_source bytecode ] */\n\n\t\trc_re_bytecode = duk__getconst(comp_ctx);\n\t\trc_re_source = duk__getconst(comp_ctx);\n\n\t\tduk__emit_a_b_c(comp_ctx,\n\t\t                DUK_OP_REGEXP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t                reg_temp /*a*/,\n\t\t                rc_re_bytecode /*b*/,\n\t\t                rc_re_source /*c*/);\n\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\tgoto syntax_error;\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t}\n\tcase DUK_TOK_LBRACKET: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsing array literal\"));\n\t\tduk__nud_array_literal(comp_ctx, res);\n\t\treturn;\n\t}\n\tcase DUK_TOK_LCURLY: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsing object literal\"));\n\t\tduk__nud_object_literal(comp_ctx, res);\n\t\treturn;\n\t}\n\tcase DUK_TOK_LPAREN: {\n\t\tduk_bool_t prev_allow_in;\n\n\t\tcomp_ctx->curr_func.paren_level++;\n\t\tprev_allow_in = comp_ctx->curr_func.allow_in;\n\t\tcomp_ctx->curr_func.allow_in = 1; /* reset 'allow_in' for parenthesized expression */\n\n\t\tduk__expr(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);  /* Expression, terminates at a ')' */\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* No RegExp after parenthesized expression. */\n\t\tcomp_ctx->curr_func.allow_in = prev_allow_in;\n\t\tcomp_ctx->curr_func.paren_level--;\n\t\treturn;\n\t}\n\n\t/* MEMBER/NEW/CALL EXPRESSIONS */\n\n\tcase DUK_TOK_NEW: {\n\t\t/*\n\t\t *  Parsing an expression starting with 'new' is tricky because\n\t\t *  there are multiple possible productions deriving from\n\t\t *  LeftHandSideExpression which begin with 'new'.\n\t\t *\n\t\t *  We currently resort to one-token lookahead to distinguish the\n\t\t *  cases.  Hopefully this is correct.  The binding power must be\n\t\t *  such that parsing ends at an LPAREN (CallExpression) but not at\n\t\t *  a PERIOD or LBRACKET (MemberExpression).\n\t\t *\n\t\t *  See doc/compiler.rst for discussion on the parsing approach,\n\t\t *  and testcases/test-dev-new.js for a bunch of documented tests.\n\t\t */\n\n\t\tduk_regconst_t reg_target;\n\t\tduk_int_t nargs;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"begin parsing new expression\"));\n\n\t\treg_target = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n#if defined(DUK_USE_ES6)\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_PERIOD) {\n\t\t\t/* new.target */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new.target\"));\n\t\t\tduk__advance(comp_ctx);\n\t\t\tif (comp_ctx->curr_token.t_nores != DUK_TOK_IDENTIFIER ||\n\t\t\t    !duk_hstring_equals_ascii_cstring(comp_ctx->curr_token.str1, \"target\")) {\n\t\t\t\tgoto syntax_error_newtarget;\n\t\t\t}\n\t\t\tif (comp_ctx->curr_func.is_global) {\n\t\t\t\tgoto syntax_error_newtarget;\n\t\t\t}\n\t\t\tduk__advance(comp_ctx);\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_NEWTARGET,\n\t\t\t             reg_target);\n\t\t\tduk__ivalue_regconst(res, reg_target);\n\t\t\treturn;\n\t\t}\n#endif  /* DUK_USE_ES6 */\n\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_CALL /*rbp_flags*/, reg_target /*forced_reg*/);\n\t\tduk__emit_bc(comp_ctx, DUK_OP_NEWOBJ, reg_target + 1);  /* default instance */\n\t\tDUK__SETTEMP(comp_ctx, reg_target + 2);\n\n\t\t/* XXX: 'new obj.noSuch()' doesn't use GETPROPC now which\n\t\t * makes the error message worse than for obj.noSuch().\n\t\t */\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_LPAREN) {\n\t\t\t/* 'new' MemberExpression Arguments */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new expression has argument list\"));\n\t\t\tduk__advance(comp_ctx);\n\t\t\tnargs = duk__parse_arguments(comp_ctx, res);  /* parse args starting from \"next temp\", reg_target + 1 */\n\t\t\t/* right paren eaten */\n\t\t} else {\n\t\t\t/* 'new' MemberExpression */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new expression has no argument list\"));\n\t\t\tnargs = 0;\n\t\t}\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t              DUK_OP_CALL0 | DUK_BC_CALL_FLAG_CONSTRUCT,\n\t\t              nargs /*num_args*/,\n\t\t              reg_target /*target*/);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"end parsing new expression\"));\n\n\t\tduk__ivalue_regconst(res, reg_target);\n\t\treturn;\n\t}\n\n\t/* FUNCTION EXPRESSIONS */\n\n\tcase DUK_TOK_FUNCTION: {\n\t\t/* Function expression.  Note that any statement beginning with 'function'\n\t\t * is handled by the statement parser as a function declaration, or a\n\t\t * non-standard function expression/statement (or a SyntaxError).  We only\n\t\t * handle actual function expressions (occurring inside an expression) here.\n\t\t *\n\t\t * O(depth^2) parse count for inner functions is handled by recording a\n\t\t * lexer offset on the first compilation pass, so that the function can\n\t\t * be efficiently skipped on the second pass.  This is encapsulated into\n\t\t * duk__parse_func_like_fnum().\n\t\t */\n\n\t\tduk_regconst_t reg_temp;\n\t\tduk_int_t fnum;\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t/* curr_token follows 'function' */\n\t\tfnum = duk__parse_func_like_fnum(comp_ctx, 0 /*flags*/);\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsed inner function -> fnum %ld\", (long) fnum));\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               DUK_OP_CLOSURE,\n\t\t               reg_temp /*a*/,\n\t\t               (duk_regconst_t) fnum /*bc*/);\n\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\n\t/* UNARY EXPRESSIONS */\n\n\tcase DUK_TOK_DELETE: {\n\t\t/* Delete semantics are a bit tricky.  The description in E5 specification\n\t\t * is kind of confusing, because it distinguishes between resolvability of\n\t\t * a reference (which is only known at runtime) seemingly at compile time\n\t\t * (= SyntaxError throwing).\n\t\t */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\t/* not allowed in strict mode, regardless of whether resolves;\n\t\t\t * in non-strict mode DELVAR handles both non-resolving and\n\t\t\t * resolving cases (the specification description is a bit confusing).\n\t\t\t */\n\n\t\t\tduk_regconst_t reg_temp;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\tif (comp_ctx->curr_func.is_strict) {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_CANNOT_DELETE_IDENTIFIER);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\n\t\t\tDUK__SETTEMP(comp_ctx, temp_at_entry);\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\t/* register bound variables are non-configurable -> always false */\n\t\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t\t             DUK_OP_LDFALSE,\n\t\t\t\t             reg_temp);\n\t\t\t} else {\n\t\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\t\trc_varname = duk__getconst(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_DELVAR,\n\t\t\t\t               reg_temp,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\t\t\tduk__ivalue_regconst(res, reg_temp);\n\t\t} else if (res->t == DUK_IVAL_PROP) {\n\t\t\tduk_regconst_t reg_temp;\n\t\t\tduk_regconst_t reg_obj;\n\t\t\tduk_regconst_t rc_key;\n\n\t\t\tDUK__SETTEMP(comp_ctx, temp_at_entry);\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_DELPROP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_temp,\n\t\t\t                reg_obj,\n\t\t\t                rc_key);\n\n\t\t\tduk__ivalue_regconst(res, reg_temp);\n\t\t} else {\n\t\t\t/* non-Reference deletion is always 'true', even in strict mode */\n\t\t\tduk_push_true(thr);\n\t\t\tgoto plain_value;\n\t\t}\n\t\treturn;\n\t}\n\tcase DUK_TOK_VOID: {\n\t\tduk__expr_toplain_ignore(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tduk_push_undefined(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_TYPEOF: {\n\t\t/* 'typeof' must handle unresolvable references without throwing\n\t\t * a ReferenceError (E5 Section 11.4.3).  Register mapped values\n\t\t * will never be unresolvable so special handling is only required\n\t\t * when an identifier is a \"slow path\" one.\n\t\t */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\n\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\t\t\tduk_regconst_t reg_temp;\n\n\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\tif (!duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"typeof for an identifier name which could not be resolved \"\n\t\t\t\t                     \"at compile time, need to use special run-time handling\"));\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_TYPEOFID,\n\t\t\t\t               reg_temp,\n\t\t\t\t               rc_varname);\n\t\t\t\tduk__ivalue_regconst(res, reg_temp);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\targs = DUK_OP_TYPEOF;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_INCREMENT: {\n\t\targs = (DUK_OP_PREINCP << 8) + DUK_OP_PREINCR;\n\t\tgoto preincdec;\n\t}\n\tcase DUK_TOK_DECREMENT: {\n\t\targs = (DUK_OP_PREDECP << 8) + DUK_OP_PREDECR;\n\t\tgoto preincdec;\n\t}\n\tcase DUK_TOK_ADD: {\n\t\t/* unary plus */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE &&\n\t\t    duk_is_number(thr, res->x1.valstack_idx)) {\n\t\t\t/* unary plus of a number is identity */\n\t\t\treturn;\n\t\t}\n\t\targs = DUK_OP_UNP;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_SUB: {\n\t\t/* unary minus */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE &&\n\t\t    duk_is_number(thr, res->x1.valstack_idx)) {\n\t\t\t/* this optimization is important to handle negative literals\n\t\t\t * (which are not directly provided by the lexical grammar)\n\t\t\t */\n\t\t\tduk_tval *tv_num;\n\t\t\tduk_double_union du;\n\n\t\t\ttv_num = DUK_GET_TVAL_POSIDX(thr, res->x1.valstack_idx);\n\t\t\tDUK_ASSERT(tv_num != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_num));\n\t\t\tdu.d = DUK_TVAL_GET_NUMBER(tv_num);\n\t\t\tdu.d = -du.d;\n\t\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\t\t\tDUK_TVAL_SET_NUMBER(tv_num, du.d);\n\t\t\treturn;\n\t\t}\n\t\targs = DUK_OP_UNM;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_BNOT: {\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\targs = DUK_OP_BNOT;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_LNOT: {\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE) {\n\t\t\t/* Very minimal inlining to handle common idioms '!0' and '!1',\n\t\t\t * and also boolean arguments like '!false' and '!true'.\n\t\t\t */\n\t\t\tduk_tval *tv_val;\n\n\t\t\ttv_val = DUK_GET_TVAL_POSIDX(thr, res->x1.valstack_idx);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tif (DUK_TVAL_IS_NUMBER(tv_val)) {\n\t\t\t\tduk_double_t d;\n\t\t\t\td = DUK_TVAL_GET_NUMBER(tv_val);\n\t\t\t\tif (d == 0.0) {\n\t\t\t\t\t/* Matches both +0 and -0 on purpose. */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"inlined lnot: !0 -> true\"));\n\t\t\t\t\tDUK_TVAL_SET_BOOLEAN_TRUE(tv_val);\n\t\t\t\t\treturn;\n\t\t\t\t} else if (d == 1.0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"inlined lnot: !1 -> false\"));\n\t\t\t\t\tDUK_TVAL_SET_BOOLEAN_FALSE(tv_val);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else if (DUK_TVAL_IS_BOOLEAN(tv_val)) {\n\t\t\t\tduk_small_uint_t v;\n\t\t\t\tv = DUK_TVAL_GET_BOOLEAN(tv_val);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"inlined lnot boolean: %ld\", (long) v));\n\t\t\t\tDUK_ASSERT(v == 0 || v == 1);\n\t\t\t\tDUK_TVAL_SET_BOOLEAN(tv_val, v ^ 0x01);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\targs = DUK_OP_LNOT;\n\t\tgoto unary;\n\t}\n\n\t}  /* end switch */\n\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);\n\tDUK_WO_NORETURN(return;);\n\n unary:\n\t{\n\t\t/* Unary opcodes use just the 'BC' register source because it\n\t\t * matches current shuffle limits, and maps cleanly to 16 high\n\t\t * bits of the opcode.\n\t\t */\n\n\t\tduk_regconst_t reg_src, reg_res;\n\n\t\treg_src = duk__ivalue_toregconst_raw(comp_ctx, res, -1 /*forced_reg*/, 0 /*flags*/);\n\t\tif (DUK__ISREG_TEMP(comp_ctx, reg_src)) {\n\t\t\treg_res = reg_src;\n\t\t} else {\n\t\t\treg_res = DUK__ALLOCTEMP(comp_ctx);\n\t\t}\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t             args,\n\t\t             reg_res,\n\t\t             reg_src);\n\t\tduk__ivalue_regconst(res, reg_res);\n\t\treturn;\n\t}\n\n preincdec:\n\t{\n\t\t/* preincrement and predecrement */\n\t\tduk_regconst_t reg_res;\n\t\tduk_small_uint_t args_op1 = args & 0xff;  /* DUK_OP_PREINCR/DUK_OP_PREDECR */\n\t\tduk_small_uint_t args_op2 = args >> 8;    /* DUK_OP_PREINCP_RR/DUK_OP_PREDECP_RR */\n\n\t\t/* Specific assumptions for opcode numbering. */\n\t\tDUK_ASSERT(DUK_OP_PREINCR + 4 == DUK_OP_PREINCV);\n\t\tDUK_ASSERT(DUK_OP_PREDECR + 4 == DUK_OP_PREDECV);\n\n\t\treg_res = DUK__ALLOCTEMP(comp_ctx);\n\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\th_varname = duk_known_hstring(thr, res->x1.valstack_idx);\n\n\t\t\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               args_op1,  /* e.g. DUK_OP_PREINCR */\n\t\t\t\t               reg_res,\n\t\t\t\t               reg_varbind);\n\t\t\t} else {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t                args_op1 + 4,  /* e.g. DUK_OP_PREINCV */\n\t\t\t\t                reg_res,\n\t\t\t\t                rc_varname);\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"preincdec to '%!O' -> reg_varbind=%ld, rc_varname=%ld\",\n\t\t\t                     (duk_heaphdr *) h_varname, (long) reg_varbind, (long) rc_varname));\n\t\t} else if (res->t == DUK_IVAL_PROP) {\n\t\t\tduk_regconst_t reg_obj;  /* allocate to reg only (not const) */\n\t\t\tduk_regconst_t rc_key;\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                args_op2 | DUK__EMIT_FLAG_BC_REGCONST,  /* e.g. DUK_OP_PREINCP */\n\t\t\t                reg_res,\n\t\t\t                reg_obj,\n\t\t\t                rc_key);\n\t\t} else {\n\t\t\t/* Technically return value is not needed because INVLHS will\n\t\t\t * unconditially throw a ReferenceError.  Coercion is necessary\n\t\t\t * for proper semantics (consider ToNumber() called for an object).\n\t\t\t * Use DUK_OP_UNP with a dummy register to get ToNumber().\n\t\t\t */\n\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_res);\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_UNP,\n\t\t\t             reg_res);  /* for side effects, result ignored */\n\t\t\tduk__emit_op_only(comp_ctx,\n\t\t\t                  DUK_OP_INVLHS);\n\t\t}\n\t\tDUK__SETTEMP(comp_ctx, reg_res + 1);\n\t\tduk__ivalue_regconst(res, reg_res);\n\t\treturn;\n\t}\n\n plain_value:\n\t{\n\t\t/* Stack top contains plain value */\n\t\tduk__ivalue_plain_fromstack(comp_ctx, res);\n\t\treturn;\n\t}\n\n#if defined(DUK_USE_ES6)\n syntax_error_newtarget:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_NEWTARGET);\n\tDUK_WO_NORETURN(return;);\n#endif\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_EXPRESSION);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* XXX: add flag to indicate whether caller cares about return value; this\n * affects e.g. handling of assignment expressions.  This change needs API\n * changes elsewhere too.\n */\nDUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_token *tk;\n\tduk_small_uint_t tok;\n\tduk_uint32_t args;  /* temp variable to pass constants and flags to shared code */\n\n\t/*\n\t *  ctx->prev_token     token to process with duk__expr_led()\n\t *  ctx->curr_token     updated by caller\n\t */\n\n\tcomp_ctx->curr_func.led_count++;\n\n\t/* The token in the switch has already been eaten here */\n\ttk = &comp_ctx->prev_token;\n\ttok = tk->t;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__expr_led(), prev_token.t=%ld, allow_in=%ld, paren_level=%ld\",\n\t                     (long) tk->t, (long) comp_ctx->curr_func.allow_in, (long) comp_ctx->curr_func.paren_level));\n\n\t/* XXX: default priority for infix operators is duk__expr_lbp(tok) -> get it here? */\n\n\tswitch (tok) {\n\n\t/* PRIMARY EXPRESSIONS */\n\n\tcase DUK_TOK_PERIOD: {\n\t\t/* Property access expressions are critical for correct LHS ordering,\n\t\t * see comments in duk__expr()!\n\t\t *\n\t\t * A conservative approach would be to use duk__ivalue_totempconst()\n\t\t * for 'left'.  However, allowing a reg-bound variable seems safe here\n\t\t * and is nice because \"foo.bar\" is a common expression.  If the ivalue\n\t\t * is used in an expression a GETPROP will occur before any changes to\n\t\t * the base value can occur.  If the ivalue is used as an assignment\n\t\t * LHS, the assignment code will ensure the base value is safe from\n\t\t * RHS mutation.\n\t\t */\n\n\t\t/* XXX: This now coerces an identifier into a GETVAR to a temp, which\n\t\t * causes an extra LDREG in call setup.  It's sufficient to coerce to a\n\t\t * unary ivalue?\n\t\t */\n\t\tduk__ivalue_toplain(comp_ctx, left);\n\n\t\t/* NB: must accept reserved words as property name */\n\t\tif (comp_ctx->curr_token.t_nores != DUK_TOK_IDENTIFIER) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EXPECTED_IDENTIFIER);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\n\t\tres->t = DUK_IVAL_PROP;\n\t\tduk__copy_ispec(comp_ctx, &left->x1, &res->x1);  /* left.x1 -> res.x1 */\n\t\tDUK_ASSERT(comp_ctx->curr_token.str1 != NULL);\n\t\tduk_push_hstring(thr, comp_ctx->curr_token.str1);\n\t\tduk_replace(thr, res->x2.valstack_idx);\n\t\tres->x2.t = DUK_ISPEC_VALUE;\n\n\t\t/* special RegExp literal handling after IdentifierName */\n\t\tcomp_ctx->curr_func.reject_regexp_in_adv = 1;\n\n\t\tduk__advance(comp_ctx);\n\t\treturn;\n\t}\n\tcase DUK_TOK_LBRACKET: {\n\t\t/* Property access expressions are critical for correct LHS ordering,\n\t\t * see comments in duk__expr()!\n\t\t */\n\n\t\t/* XXX: optimize temp reg use */\n\t\t/* XXX: similar coercion issue as in DUK_TOK_PERIOD */\n\t\t/* XXX: coerce to regs? it might be better for enumeration use, where the\n\t\t * same PROP ivalue is used multiple times.  Or perhaps coerce PROP further\n\t\t * there?\n\t\t */\n\t\t/* XXX: for simple cases like x['y'] an unnecessary LDREG is\n\t\t * emitted for the base value; could avoid it if we knew that\n\t\t * the key expression is safe (e.g. just a single literal).\n\t\t */\n\n\t\t/* The 'left' value must not be a register bound variable\n\t\t * because it may be mutated during the rest of the expression\n\t\t * and E5.1 Section 11.2.1 specifies the order of evaluation\n\t\t * so that the base value is evaluated first.\n\t\t * See: test-bug-nested-prop-mutate.js.\n\t\t */\n\t\tduk__ivalue_totempconst(comp_ctx, left);\n\t\tduk__expr_toplain(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);  /* Expression, ']' terminates */\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RBRACKET);\n\n\t\tres->t = DUK_IVAL_PROP;\n\t\tduk__copy_ispec(comp_ctx, &res->x1, &res->x2);   /* res.x1 -> res.x2 */\n\t\tduk__copy_ispec(comp_ctx, &left->x1, &res->x1);  /* left.x1 -> res.x1 */\n\t\treturn;\n\t}\n\tcase DUK_TOK_LPAREN: {\n\t\t/* function call */\n\t\tduk_regconst_t reg_cs = DUK__ALLOCTEMPS(comp_ctx, 2);\n\t\tduk_int_t nargs;\n\t\tduk_small_uint_t call_op = DUK_OP_CALL0;\n\n\t\t/* XXX: attempt to get the call result to \"next temp\" whenever\n\t\t * possible to avoid unnecessary register shuffles.\n\t\t */\n\n\t\t/*\n\t\t *  Setup call: target and 'this' binding.  Three cases:\n\t\t *\n\t\t *    1. Identifier base (e.g. \"foo()\")\n\t\t *    2. Property base (e.g. \"foo.bar()\")\n\t\t *    3. Register base (e.g. \"foo()()\"; i.e. when a return value is a function)\n\t\t */\n\n\t\tif (left->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with identifier base\"));\n\n\t\t\th_varname = duk_known_hstring(thr, left->x1.valstack_idx);\n\t\t\tif (h_varname == DUK_HTHREAD_STRING_EVAL(thr)) {\n\t\t\t\t/* Potential direct eval call detected, flag the CALL\n\t\t\t\t * so that a run-time \"direct eval\" check is made and\n\t\t\t\t * special behavior may be triggered.  Note that this\n\t\t\t\t * does not prevent 'eval' from being register bound.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with identifier 'eval' \"\n\t\t\t\t                     \"-> using EVALCALL, marking function \"\n\t\t\t\t                     \"as may_direct_eval\"));\n\t\t\t\tcall_op |= DUK_BC_CALL_FLAG_CALLED_AS_EVAL;\n\t\t\t\tcomp_ctx->curr_func.may_direct_eval = 1;\n\t\t\t}\n\n\t\t\tduk_dup(thr, left->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t              DUK_OP_CSREG | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t              reg_varbind,\n\t\t\t\t              reg_cs + 0);\n\t\t\t} else {\n\t\t\t\t/* XXX: expand target register or constant field to\n\t\t\t\t * reduce shuffling.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(DUK__ISCONST(rc_varname));\n\t\t\t\tduk__emit_a_b(comp_ctx,\n\t\t\t\t              DUK_OP_CSVAR | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t              reg_cs + 0,\n\t\t\t\t              rc_varname);\n\t\t\t}\n\t\t} else if (left->t == DUK_IVAL_PROP) {\n\t\t\t/* Call through a property lookup, E5 Section 11.2.3, step 6.a.i,\n\t\t\t * E5 Section 10.4.3.  There used to be a separate CSPROP opcode\n\t\t\t * but a typical call setup took 3 opcodes (e.g. LDREG, LDCONST,\n\t\t\t * CSPROP) and the same can be achieved with ordinary loads.\n\t\t\t */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\t\tduk_regconst_t reg_key;\n#endif\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with property base\"));\n\n\t\t\t/* XXX: For Math.sin() this generates: LDCONST + LDREG +\n\t\t\t * GETPROPC + call.  The LDREG is unnecessary because LDCONST\n\t\t\t * could be loaded directly into reg_cs + 1.  This doesn't\n\t\t\t * happen now because a variable cannot be in left->x1 of a\n\t\t\t * DUK_IVAL_PROP.  We could notice that left->x1 is a temp\n\t\t\t * and reuse, but it would still be in the wrong position\n\t\t\t * (reg_cs + 0 rather than reg_cs + 1).\n\t\t\t */\n\t\t\tduk__ispec_toforcedreg(comp_ctx, &left->x1, reg_cs + 1);  /* base */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\t\treg_key = duk__ispec_toregconst_raw(comp_ctx, &left->x2, -1, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_GETPROPC | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_cs + 0,\n\t\t\t                reg_cs + 1,\n\t\t\t                reg_key);\n#else\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_cs + 0);  /* base[key] */\n#endif\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with register base\"));\n\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_cs + 0);\n#if 0\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CSREG | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t               reg_cs + 0,\n\t\t\t               reg_cs + 0);  /* in-place setup */\n#endif\n\t\t\t/* Because of in-place setup, REGCS is equivalent to\n\t\t\t * just this LDUNDEF.\n\t\t\t */\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_LDUNDEF, reg_cs + 1);\n\t\t}\n\n\t\tDUK__SETTEMP(comp_ctx, reg_cs + 2);\n\t\tnargs = duk__parse_arguments(comp_ctx, res);  /* parse args starting from \"next temp\" */\n\n\t\t/* Tailcalls are handled by back-patching the already emitted opcode\n\t\t * later in return statement parser.\n\t\t */\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               call_op,\n\t\t               (duk_regconst_t) nargs /*numargs*/,\n\t\t               reg_cs /*basereg*/);\n\t\tDUK__SETTEMP(comp_ctx, reg_cs + 1);    /* result in csreg */\n\n\t\tduk__ivalue_regconst(res, reg_cs);\n\t\treturn;\n\t}\n\n\t/* POSTFIX EXPRESSION */\n\n\tcase DUK_TOK_INCREMENT: {\n\t\targs = (DUK_OP_POSTINCP_RR << 16) + (DUK_OP_POSTINCR << 8) + 0;\n\t\tgoto postincdec;\n\t}\n\tcase DUK_TOK_DECREMENT: {\n\t\targs = (DUK_OP_POSTDECP_RR << 16) + (DUK_OP_POSTDECR << 8) + 0;\n\t\tgoto postincdec;\n\t}\n\n\t/* EXPONENTIATION EXPRESSION */\n\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\tcase DUK_TOK_EXP: {\n\t\targs = (DUK_OP_EXP << 8) + DUK__BP_EXPONENTIATION - 1;  /* UnaryExpression */\n\t\tgoto binary;\n\t}\n#endif\n\n\t/* MULTIPLICATIVE EXPRESSION */\n\n\tcase DUK_TOK_MUL: {\n\t\targs = (DUK_OP_MUL << 8) + DUK__BP_MULTIPLICATIVE;  /* ExponentiationExpression */\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_DIV: {\n\t\targs = (DUK_OP_DIV << 8) + DUK__BP_MULTIPLICATIVE;  /* ExponentiationExpression */\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_MOD: {\n\t\targs = (DUK_OP_MOD << 8) + DUK__BP_MULTIPLICATIVE;  /* ExponentiationExpression */\n\t\tgoto binary;\n\t}\n\n\t/* ADDITIVE EXPRESSION */\n\n\tcase DUK_TOK_ADD: {\n\t\targs = (DUK_OP_ADD << 8) + DUK__BP_ADDITIVE;  /* MultiplicativeExpression */\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_SUB: {\n\t\targs = (DUK_OP_SUB << 8) + DUK__BP_ADDITIVE;  /* MultiplicativeExpression */\n\t\tgoto binary;\n\t}\n\n\t/* SHIFT EXPRESSION */\n\n\tcase DUK_TOK_ALSHIFT: {\n\t\t/* << */\n\t\targs = (DUK_OP_BASL << 8) + DUK__BP_SHIFT;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_ARSHIFT: {\n\t\t/* >> */\n\t\targs = (DUK_OP_BASR << 8) + DUK__BP_SHIFT;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_RSHIFT: {\n\t\t/* >>> */\n\t\targs = (DUK_OP_BLSR << 8) + DUK__BP_SHIFT;\n\t\tgoto binary;\n\t}\n\n\t/* RELATIONAL EXPRESSION */\n\n\tcase DUK_TOK_LT: {\n\t\t/* < */\n\t\targs = (DUK_OP_LT << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_GT: {\n\t\targs = (DUK_OP_GT << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_LE: {\n\t\targs = (DUK_OP_LE << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_GE: {\n\t\targs = (DUK_OP_GE << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_INSTANCEOF: {\n\t\targs = (DUK_OP_INSTOF << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_IN: {\n\t\targs = (DUK_OP_IN << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\n\t/* EQUALITY EXPRESSION */\n\n\tcase DUK_TOK_EQ: {\n\t\targs = (DUK_OP_EQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_NEQ: {\n\t\targs = (DUK_OP_NEQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_SEQ: {\n\t\targs = (DUK_OP_SEQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_SNEQ: {\n\t\targs = (DUK_OP_SNEQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\n\t/* BITWISE EXPRESSIONS */\n\n\tcase DUK_TOK_BAND: {\n\t\targs = (DUK_OP_BAND << 8) + DUK__BP_BAND;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_BXOR: {\n\t\targs = (DUK_OP_BXOR << 8) + DUK__BP_BXOR;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_BOR: {\n\t\targs = (DUK_OP_BOR << 8) + DUK__BP_BOR;\n\t\tgoto binary;\n\t}\n\n\t/* LOGICAL EXPRESSIONS */\n\n\tcase DUK_TOK_LAND: {\n\t\t/* syntactically left-associative but parsed as right-associative */\n\t\targs = (1 << 8) + DUK__BP_LAND - 1;\n\t\tgoto binary_logical;\n\t}\n\tcase DUK_TOK_LOR: {\n\t\t/* syntactically left-associative but parsed as right-associative */\n\t\targs = (0 << 8) + DUK__BP_LOR - 1;\n\t\tgoto binary_logical;\n\t}\n\n\t/* CONDITIONAL EXPRESSION */\n\n\tcase DUK_TOK_QUESTION: {\n\t\t/* XXX: common reg allocation need is to reuse a sub-expression's temp reg,\n\t\t * but only if it really is a temp.  Nothing fancy here now.\n\t\t */\n\t\tduk_regconst_t reg_temp;\n\t\tduk_int_t pc_jump1;\n\t\tduk_int_t pc_jump2;\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_temp);\n\t\tduk__emit_if_true_skip(comp_ctx, reg_temp);\n\t\tpc_jump1 = duk__emit_jump_empty(comp_ctx);  /* jump to false */\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp /*forced_reg*/);  /* AssignmentExpression */\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\t\tpc_jump2 = duk__emit_jump_empty(comp_ctx);  /* jump to end */\n\t\tduk__patch_jump_here(comp_ctx, pc_jump1);\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp /*forced_reg*/);  /* AssignmentExpression */\n\t\tduk__patch_jump_here(comp_ctx, pc_jump2);\n\n\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\n\t/* ASSIGNMENT EXPRESSION */\n\n\tcase DUK_TOK_EQUALSIGN: {\n\t\t/*\n\t\t *  Assignments are right associative, allows e.g.\n\t\t *    a = 5;\n\t\t *    a += b = 9;   // same as a += (b = 9)\n\t\t *  -> expression value 14, a = 14, b = 9\n\t\t *\n\t\t *  Right associativiness is reflected in the BP for recursion,\n\t\t *  \"-1\" ensures assignment operations are allowed.\n\t\t *\n\t\t *  XXX: just use DUK__BP_COMMA (i.e. no need for 2-step bp levels)?\n\t\t */\n\t\targs = (DUK_OP_NONE << 8) + DUK__BP_ASSIGNMENT - 1;   /* DUK_OP_NONE marks a 'plain' assignment */\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_ADD_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_ADD << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_SUB_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_SUB << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_MUL_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_MUL << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_DIV_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_DIV << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_MOD_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_MOD << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\tcase DUK_TOK_EXP_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_EXP << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n#endif\n\tcase DUK_TOK_ALSHIFT_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BASL << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_ARSHIFT_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BASR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_RSHIFT_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BLSR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_BAND_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BAND << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_BOR_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BOR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_BXOR_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BXOR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\n\t/* COMMA */\n\n\tcase DUK_TOK_COMMA: {\n\t\t/* right associative */\n\n\t\tduk__ivalue_toplain_ignore(comp_ctx, left);  /* need side effects, not value */\n\t\tduk__expr_toplain(comp_ctx, res, DUK__BP_COMMA - 1 /*rbp_flags*/);\n\n\t\t/* return 'res' (of right part) as our result */\n\t\treturn;\n\t}\n\n\tdefault: {\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"parse error: unexpected token: %ld\", (long) tok));\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);\n\tDUK_WO_NORETURN(return;);\n\n#if 0\n\t/* XXX: shared handling for 'duk__expr_lhs'? */\n\tif (comp_ctx->curr_func.paren_level == 0 && XXX) {\n\t\tcomp_ctx->curr_func.duk__expr_lhs = 0;\n\t}\n#endif\n\n binary:\n\t/*\n\t *  Shared handling of binary operations\n\t *\n\t *  args = (opcode << 8) + rbp\n\t */\n\t{\n\t\tduk__ivalue_toplain(comp_ctx, left);\n\t\tduk__expr_toplain(comp_ctx, res, args & 0xff /*rbp_flags*/);\n\n\t\t/* combine left->x1 and res->x1 (right->x1, really) -> (left->x1 OP res->x1) */\n\t\tDUK_ASSERT(left->t == DUK_IVAL_PLAIN);\n\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN);\n\n\t\tres->t = DUK_IVAL_ARITH;\n\t\tres->op = (args >> 8) & 0xff;\n\n\t\tres->x2.t = res->x1.t;\n\t\tres->x2.regconst = res->x1.regconst;\n\t\tduk_copy(thr, res->x1.valstack_idx, res->x2.valstack_idx);\n\n\t\tres->x1.t = left->x1.t;\n\t\tres->x1.regconst = left->x1.regconst;\n\t\tduk_copy(thr, left->x1.valstack_idx, res->x1.valstack_idx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"binary op, res: t=%ld, x1.t=%ld, x1.regconst=0x%08lx, x2.t=%ld, x2.regconst=0x%08lx\",\n\t\t                     (long) res->t, (long) res->x1.t, (unsigned long) res->x1.regconst, (long) res->x2.t, (unsigned long) res->x2.regconst));\n\t\treturn;\n\t}\n\n binary_logical:\n\t/*\n\t *  Shared handling for logical AND and logical OR.\n\t *\n\t *  args = (truthval << 8) + rbp\n\t *\n\t *  Truthval determines when to skip right-hand-side.\n\t *  For logical AND truthval=1, for logical OR truthval=0.\n\t *\n\t *  See doc/compiler.rst for discussion on compiling logical\n\t *  AND and OR expressions.  The approach here is very simplistic,\n\t *  generating extra jumps and multiple evaluations of truth values,\n\t *  but generates code on-the-fly with only local back-patching.\n\t *\n\t *  Both logical AND and OR are syntactically left-associated.\n\t *  However, logical ANDs are compiled as right associative\n\t *  expressions, i.e. \"A && B && C\" as \"A && (B && C)\", to allow\n\t *  skip jumps to skip over the entire tail.  Similarly for logical OR.\n\t */\n\n\t{\n\t\tduk_regconst_t reg_temp;\n\t\tduk_int_t pc_jump;\n\t\tduk_small_uint_t args_truthval = args >> 8;\n\t\tduk_small_uint_t args_rbp = args & 0xff;\n\n\t\t/* XXX: unoptimal use of temps, resetting */\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_temp);\n\t\tDUK_ASSERT(DUK__ISREG(reg_temp));\n\t\tduk__emit_bc(comp_ctx,\n\t\t            (args_truthval ? DUK_OP_IFTRUE_R : DUK_OP_IFFALSE_R),\n\t\t            reg_temp);  /* skip jump conditionally */\n\t\tpc_jump = duk__emit_jump_empty(comp_ctx);\n\t\tduk__expr_toforcedreg(comp_ctx, res, args_rbp /*rbp_flags*/, reg_temp /*forced_reg*/);\n\t\tduk__patch_jump_here(comp_ctx, pc_jump);\n\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\n assign:\n\t/*\n\t *  Shared assignment expression handling\n\t *\n\t *  args = (opcode << 8) + rbp\n\t *\n\t *  If 'opcode' is DUK_OP_NONE, plain assignment without arithmetic.\n\t *  Syntactically valid left-hand-side forms which are not accepted as\n\t *  left-hand-side values (e.g. as in \"f() = 1\") must NOT cause a\n\t *  SyntaxError, but rather a run-time ReferenceError.\n\t *\n\t *  When evaluating X <op>= Y, the LHS (X) is conceptually evaluated\n\t *  to a temporary first.  The RHS is then evaluated.  Finally, the\n\t *  <op> is applied to the initial value of RHS (not the value after\n\t *  RHS evaluation), and written to X.  Doing so concretely generates\n\t *  inefficient code so we'd like to avoid the temporary when possible.\n\t *  See: https://github.com/svaarala/duktape/pull/992.\n\t *\n\t *  The expression value (final LHS value, written to RHS) is\n\t *  conceptually copied into a fresh temporary so that it won't\n\t *  change even if the LHS/RHS values change in outer expressions.\n\t *  For example, it'd be generally incorrect for the expression value\n\t *  to be the RHS register binding, unless there's a guarantee that it\n\t *  won't change during further expression evaluation.  Using the\n\t *  temporary concretely produces inefficient bytecode, so we try to\n\t *  avoid the extra temporary for some known-to-be-safe cases.\n\t *  Currently the only safe case we detect is a \"top level assignment\",\n\t *  for example \"x = y + z;\", where the assignment expression value is\n\t *  ignored.\n\t *  See: test-dev-assign-expr.js and test-bug-assign-mutate-gh381.js.\n\t */\n\n\t{\n\t\tduk_small_uint_t args_op = args >> 8;\n\t\tduk_small_uint_t args_rbp = args & 0xff;\n\t\tduk_bool_t toplevel_assign;\n\n\t\t/* XXX: here we need to know if 'left' is left-hand-side compatible.\n\t\t * That information is no longer available from current expr parsing\n\t\t * state; it would need to be carried into the 'left' ivalue or by\n\t\t * some other means.\n\t\t */\n\n\t\t/* A top-level assignment is e.g. \"x = y;\".  For these it's safe\n\t\t * to use the RHS as-is as the expression value, even if the RHS\n\t\t * is a reg-bound identifier.  The RHS ('res') is right associative\n\t\t * so it has consumed all other assignment level operations; the\n\t\t * only relevant lower binding power construct is comma operator\n\t\t * which will ignore the expression value provided here.  Usually\n\t\t * the top level assignment expression value is ignored, but it\n\t\t * is relevant for e.g. eval code.\n\t\t */\n\t\ttoplevel_assign = (comp_ctx->curr_func.nud_count == 1 && /* one token before */\n\t\t                   comp_ctx->curr_func.led_count == 1);  /* one operator (= assign) */\n\t\tDUK_DDD(DUK_DDDPRINT(\"assignment: nud_count=%ld, led_count=%ld, toplevel_assign=%ld\",\n\t\t                     (long) comp_ctx->curr_func.nud_count,\n\t\t                     (long) comp_ctx->curr_func.led_count,\n\t\t                     (long) toplevel_assign));\n\n\t\tif (left->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\tDUK_ASSERT(left->x1.t == DUK_ISPEC_VALUE);  /* LHS is already side effect free */\n\n\t\t\th_varname = duk_known_hstring(thr, left->x1.valstack_idx);\n\t\t\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\t\t\t/* E5 Section 11.13.1 (and others for other assignments), step 4. */\n\t\t\t\tgoto syntax_error_lvalue;\n\t\t\t}\n\t\t\tduk_dup(thr, left->x1.valstack_idx);\n\t\t\t(void) duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname);\n\n\t\t\tif (args_op == DUK_OP_NONE) {\n\t\t\t\tduk__expr(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\tif (toplevel_assign) {\n\t\t\t\t\t/* Any 'res' will do. */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"plain assignment, toplevel assign, use as is\"));\n\t\t\t\t} else {\n\t\t\t\t\t/* 'res' must be a plain ivalue, and not register-bound variable. */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"plain assignment, not toplevel assign, ensure not a reg-bound identifier\"));\n\t\t\t\t\tif (res->t != DUK_IVAL_PLAIN || (res->x1.t == DUK_ISPEC_REGCONST &&\n\t\t\t\t\t                                 DUK__ISREG_NOTTEMP(comp_ctx, res->x1.regconst))) {\n\t\t\t\t\t\tduk__ivalue_totempconst(comp_ctx, res);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* For X <op>= Y we need to evaluate the pre-op\n\t\t\t\t * value of X before evaluating the RHS: the RHS\n\t\t\t\t * can change X, but when we do <op> we must use\n\t\t\t\t * the pre-op value.\n\t\t\t\t */\n\t\t\t\tduk_regconst_t reg_temp;\n\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t\t\tif (reg_varbind >= 0) {\n\t\t\t\t\tduk_regconst_t reg_res;\n\t\t\t\t\tduk_regconst_t reg_src;\n\t\t\t\t\tduk_int_t pc_temp_load;\n\t\t\t\t\tduk_int_t pc_before_rhs;\n\t\t\t\t\tduk_int_t pc_after_rhs;\n\n\t\t\t\t\tif (toplevel_assign) {\n\t\t\t\t\t\t/* 'reg_varbind' is the operation result and can also\n\t\t\t\t\t\t * become the expression value for top level assignments\n\t\t\t\t\t\t * such as: \"var x; x += y;\".\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"<op>= expression is top level, write directly to reg_varbind\"));\n\t\t\t\t\t\treg_res = reg_varbind;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t/* Not safe to use 'reg_varbind' as assignment expression\n\t\t\t\t\t\t * value, so go through a temp.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"<op>= expression is not top level, write to reg_temp\"));\n\t\t\t\t\t\treg_res = reg_temp;  /* reg_res should be smallest possible */\n\t\t\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\t\t}\n\n\t\t\t\t\t/* Try to optimize X <op>= Y for reg-bound\n\t\t\t\t\t * variables.  Detect side-effect free RHS\n\t\t\t\t\t * narrowly by seeing whether it emits code.\n\t\t\t\t\t * If not, rewind the code emitter and overwrite\n\t\t\t\t\t * the unnecessary temp reg load.\n\t\t\t\t\t */\n\n\t\t\t\t\tpc_temp_load = duk__get_current_pc(comp_ctx);\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_LDREG,\n\t\t\t\t\t               reg_temp,\n\t\t\t\t\t               reg_varbind);\n\n\t\t\t\t\tpc_before_rhs = duk__get_current_pc(comp_ctx);\n\t\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\t\t\t\t\tpc_after_rhs = duk__get_current_pc(comp_ctx);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"pc_temp_load=%ld, pc_before_rhs=%ld, pc_after_rhs=%ld\",\n\t\t\t\t\t                   (long) pc_temp_load, (long) pc_before_rhs,\n\t\t\t\t\t                   (long) pc_after_rhs));\n\n\t\t\t\t\tif (pc_after_rhs == pc_before_rhs) {\n\t\t\t\t\t\t/* Note: if the reg_temp load generated shuffling\n\t\t\t\t\t\t * instructions, we may need to rewind more than\n\t\t\t\t\t\t * one instruction, so use explicit PC computation.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"rhs is side effect free, rewind and avoid unnecessary temp for reg-based <op>=\"));\n\t\t\t\t\t\tDUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, (pc_temp_load - pc_before_rhs) * (duk_int_t) sizeof(duk_compiler_instr));\n\t\t\t\t\t\treg_src = reg_varbind;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"rhs evaluation emitted code, not sure if rhs is side effect free; use temp reg for LHS\"));\n\t\t\t\t\t\treg_src = reg_temp;\n\t\t\t\t\t}\n\n\t\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t\t                args_op | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t\t                reg_res,\n\t\t\t\t\t                reg_src,\n\t\t\t\t\t                res->x1.regconst);\n\n\t\t\t\t\tres->x1.regconst = reg_res;\n\n\t\t\t\t\t/* Ensure compact use of temps. */\n\t\t\t\t\tif (DUK__ISREG_TEMP(comp_ctx, reg_res)) {\n\t\t\t\t\t\tDUK__SETTEMP(comp_ctx, reg_res + 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t/* When LHS is not register bound, always go through a\n\t\t\t\t\t * temporary.  No optimization for top level assignment.\n\t\t\t\t\t */\n\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_GETVAR,\n\t\t\t\t\t               reg_temp,\n\t\t\t\t\t               rc_varname);\n\n\t\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\n\t\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t\t                args_op | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t\t                reg_temp,\n\t\t\t\t\t                reg_temp,\n\t\t\t\t\t                res->x1.regconst);\n\t\t\t\t\tres->x1.regconst = reg_temp;\n\t\t\t\t}\n\n\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\t\t\t}\n\n\t\t\t/* At this point 'res' holds the potential expression value.\n\t\t\t * It can be basically any ivalue here, including a reg-bound\n\t\t\t * identifier (if code above deems it safe) or a unary/binary\n\t\t\t * operation.  Operations must be resolved to a side effect free\n\t\t\t * plain value, and the side effects must happen exactly once.\n\t\t\t */\n\n\t\t\tif (reg_varbind >= 0) {\n\t\t\t\tif (res->t != DUK_IVAL_PLAIN) {\n\t\t\t\t\t/* Resolve 'res' directly into the LHS binding, and use\n\t\t\t\t\t * that as the expression value if safe.  If not safe,\n\t\t\t\t\t * resolve to a temp/const and copy to LHS.\n\t\t\t\t\t */\n\t\t\t\t\tif (toplevel_assign) {\n\t\t\t\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, (duk_int_t) reg_varbind);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk__ivalue_totempconst(comp_ctx, res);\n\t\t\t\t\t\tduk__copy_ivalue(comp_ctx, res, left);  /* use 'left' as a temp */\n\t\t\t\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, (duk_int_t) reg_varbind);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t/* Use 'res' as the expression value (it's side effect\n\t\t\t\t\t * free and may be a plain value, a register, or a\n\t\t\t\t\t * constant) and write it to the LHS binding too.\n\t\t\t\t\t */\n\t\t\t\t\tduk__copy_ivalue(comp_ctx, res, left);  /* use 'left' as a temp */\n\t\t\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, (duk_int_t) reg_varbind);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* Only a reg fits into 'A' so coerce 'res' into a register\n\t\t\t\t * for PUTVAR.\n\t\t\t\t *\n\t\t\t\t * XXX: here the current A/B/C split is suboptimal: we could\n\t\t\t\t * just use 9 bits for reg_res (and support constants) and 17\n\t\t\t\t * instead of 18 bits for the varname const index.\n\t\t\t\t */\n\n\t\t\t\tduk__ivalue_toreg(comp_ctx, res);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t               res->x1.regconst,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\n\t\t\t/* 'res' contains expression value */\n\t\t} else if (left->t == DUK_IVAL_PROP) {\n\t\t\t/* E5 Section 11.13.1 (and others) step 4 never matches for prop writes -> no check */\n\t\t\tduk_regconst_t reg_obj;\n\t\t\tduk_regconst_t rc_key;\n\t\t\tduk_regconst_t rc_res;\n\t\t\tduk_regconst_t reg_temp;\n\n\t\t\t/* Property access expressions ('a[b]') are critical to correct\n\t\t\t * LHS evaluation ordering, see test-dev-assign-eval-order*.js.\n\t\t\t * We must make sure that the LHS target slot (base object and\n\t\t\t * key) don't change during RHS evaluation.  The only concrete\n\t\t\t * problem is a register reference to a variable-bound register\n\t\t\t * (i.e., non-temp).  Require temp regs for both key and base.\n\t\t\t *\n\t\t\t * Don't allow a constant for the object (even for a number\n\t\t\t * etc), as it goes into the 'A' field of the opcode.\n\t\t\t */\n\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx,\n\t\t\t                                    &left->x1,\n\t\t\t                                    -1 /*forced_reg*/,\n\t\t\t                                    DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/);\n\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx,\n\t\t\t                                   &left->x2,\n\t\t\t                                   -1 /*forced_reg*/,\n\t\t\t                                   DUK__IVAL_FLAG_REQUIRE_TEMP | DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\n\t\t\t/* Evaluate RHS only when LHS is safe. */\n\n\t\t\tif (args_op == DUK_OP_NONE) {\n\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\t\t\t\trc_res = res->x1.regconst;\n\t\t\t} else {\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                DUK_OP_GETPROP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                reg_temp,\n\t\t\t\t                reg_obj,\n\t\t\t\t                rc_key);\n\n\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                args_op | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                reg_temp,\n\t\t\t\t                reg_temp,\n\t\t\t\t                res->x1.regconst);\n\t\t\t\trc_res = reg_temp;\n\t\t\t}\n\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_obj,\n\t\t\t                rc_key,\n\t\t\t                rc_res);\n\n\t\t\tduk__ivalue_regconst(res, rc_res);\n\t\t} else {\n\t\t\t/* No support for lvalues returned from new or function call expressions.\n\t\t\t * However, these must NOT cause compile-time SyntaxErrors, but run-time\n\t\t\t * ReferenceErrors.  Both left and right sides of the assignment must be\n\t\t\t * evaluated before throwing a ReferenceError.  For instance:\n\t\t\t *\n\t\t\t *     f() = g();\n\t\t\t *\n\t\t\t * must result in f() being evaluated, then g() being evaluated, and\n\t\t\t * finally, a ReferenceError being thrown.  See E5 Section 11.13.1.\n\t\t\t */\n\n\t\t\tduk_regconst_t rc_res;\n\n\t\t\t/* First evaluate LHS fully to ensure all side effects are out. */\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, left);\n\n\t\t\t/* Then evaluate RHS fully (its value becomes the expression value too).\n\t\t\t * Technically we'd need the side effect safety check here too, but because\n\t\t\t * we always throw using INVLHS the result doesn't matter.\n\t\t\t */\n\t\t\trc_res = duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\n\t\t\tduk__emit_op_only(comp_ctx, DUK_OP_INVLHS);\n\n\t\t\tduk__ivalue_regconst(res, rc_res);\n\t\t}\n\n\t\treturn;\n\t}\n\n postincdec:\n\t{\n\t\t/*\n\t\t *  Post-increment/decrement will return the original value as its\n\t\t *  result value.  However, even that value will be coerced using\n\t\t *  ToNumber() which is quite awkward.  Specific bytecode opcodes\n\t\t *  are used to handle these semantics.\n\t\t *\n\t\t *  Note that post increment/decrement has a \"no LineTerminator here\"\n\t\t *  restriction.  This is handled by duk__expr_lbp(), which forcibly terminates\n\t\t *  the previous expression if a LineTerminator occurs before '++'/'--'.\n\t\t */\n\n\t\tduk_regconst_t reg_res;\n\t\tduk_small_uint_t args_op1 = (args >> 8) & 0xff;  /* DUK_OP_POSTINCR/DUK_OP_POSTDECR */\n\t\tduk_small_uint_t args_op2 = args >> 16;          /* DUK_OP_POSTINCP_RR/DUK_OP_POSTDECP_RR */\n\n\t\t/* Specific assumptions for opcode numbering. */\n\t\tDUK_ASSERT(DUK_OP_POSTINCR + 4 == DUK_OP_POSTINCV);\n\t\tDUK_ASSERT(DUK_OP_POSTDECR + 4 == DUK_OP_POSTDECV);\n\n\t\treg_res = DUK__ALLOCTEMP(comp_ctx);\n\n\t\tif (left->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\th_varname = duk_known_hstring(thr, left->x1.valstack_idx);\n\n\t\t\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\tduk_dup(thr, left->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               args_op1,  /* e.g. DUK_OP_POSTINCR */\n\t\t\t\t               reg_res,\n\t\t\t\t               reg_varbind);\n\t\t\t} else {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               args_op1 + 4,  /* e.g. DUK_OP_POSTINCV */\n\t\t\t\t               reg_res,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"postincdec to '%!O' -> reg_varbind=%ld, rc_varname=%ld\",\n\t\t\t                     (duk_heaphdr *) h_varname, (long) reg_varbind, (long) rc_varname));\n\t\t} else if (left->t == DUK_IVAL_PROP) {\n\t\t\tduk_regconst_t reg_obj;  /* allocate to reg only (not const) */\n\t\t\tduk_regconst_t rc_key;\n\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &left->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &left->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                args_op2 | DUK__EMIT_FLAG_BC_REGCONST,  /* e.g. DUK_OP_POSTINCP */\n\t\t\t                reg_res,\n\t\t\t                reg_obj,\n\t\t\t                rc_key);\n\t\t} else {\n\t\t\t/* Technically return value is not needed because INVLHS will\n\t\t\t * unconditially throw a ReferenceError.  Coercion is necessary\n\t\t\t * for proper semantics (consider ToNumber() called for an object).\n\t\t\t * Use DUK_OP_UNP with a dummy register to get ToNumber().\n\t\t\t */\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_res);\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_UNP,\n\t\t\t             reg_res);  /* for side effects, result ignored */\n\t\t\tduk__emit_op_only(comp_ctx,\n\t\t\t                  DUK_OP_INVLHS);\n\t\t}\n\n\t\tDUK__SETTEMP(comp_ctx, reg_res + 1);\n\t\tduk__ivalue_regconst(res, reg_res);\n\t\treturn;\n\t}\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_EXPRESSION);\n\tDUK_WO_NORETURN(return;);\n\n syntax_error_lvalue:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LVALUE);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL duk_small_uint_t duk__expr_lbp(duk_compiler_ctx *comp_ctx) {\n\tduk_small_uint_t tok = comp_ctx->curr_token.t;\n\n\tDUK_ASSERT_DISABLE(tok >= DUK_TOK_MINVAL);  /* unsigned */\n\tDUK_ASSERT(tok <= DUK_TOK_MAXVAL);\n\tDUK_ASSERT(sizeof(duk__token_lbp) == DUK_TOK_MAXVAL + 1);\n\n\t/* XXX: integrate support for this into led() instead?\n\t * Similar issue as post-increment/post-decrement.\n\t */\n\n\t/* prevent duk__expr_led() by using a binding power less than anything valid */\n\tif (tok == DUK_TOK_IN && !comp_ctx->curr_func.allow_in) {\n\t\treturn 0;\n\t}\n\n\tif ((tok == DUK_TOK_DECREMENT || tok == DUK_TOK_INCREMENT) &&\n\t    (comp_ctx->curr_token.lineterm)) {\n\t\t/* '++' or '--' in a post-increment/decrement position,\n\t\t * and a LineTerminator occurs between the operator and\n\t\t * the preceding expression.  Force the previous expr\n\t\t * to terminate, in effect treating e.g. \"a,b\\n++\" as\n\t\t * \"a,b;++\" (= SyntaxError).\n\t\t */\n\t\treturn 0;\n\t}\n\n\treturn DUK__TOKEN_LBP_GET_BP(duk__token_lbp[tok]);  /* format is bit packed */\n}\n\n/*\n *  Expression parsing.\n *\n *  Upon entry to 'expr' and its variants, 'curr_tok' is assumed to be the\n *  first token of the expression.  Upon exit, 'curr_tok' will be the first\n *  token not part of the expression (e.g. semicolon terminating an expression\n *  statement).\n */\n\n#define DUK__EXPR_RBP_MASK           0xff\n#define DUK__EXPR_FLAG_REJECT_IN     (1 << 8)   /* reject 'in' token (used for for-in) */\n#define DUK__EXPR_FLAG_ALLOW_EMPTY   (1 << 9)   /* allow empty expression */\n#define DUK__EXPR_FLAG_REQUIRE_INIT  (1 << 10)  /* require initializer for var/const */\n\n/* main expression parser function */\nDUK_LOCAL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_ivalue tmp_alloc;   /* 'res' is used for \"left\", and 'tmp' for \"right\" */\n\tduk_ivalue *tmp = &tmp_alloc;\n\tduk_small_uint_t rbp;\n\n\tDUK__RECURSION_INCREASE(comp_ctx, thr);\n\n\tduk_require_stack(thr, DUK__PARSE_EXPR_SLOTS);\n\n\t/* filter out flags from exprtop rbp_flags here to save space */\n\trbp = rbp_flags & DUK__EXPR_RBP_MASK;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__expr(), rbp_flags=%ld, rbp=%ld, allow_in=%ld, paren_level=%ld\",\n\t                     (long) rbp_flags, (long) rbp, (long) comp_ctx->curr_func.allow_in,\n\t                     (long) comp_ctx->curr_func.paren_level));\n\n\tduk_memzero(&tmp_alloc, sizeof(tmp_alloc));\n\ttmp->x1.valstack_idx = duk_get_top(thr);\n\ttmp->x2.valstack_idx = tmp->x1.valstack_idx + 1;\n\tduk_push_undefined(thr);\n\tduk_push_undefined(thr);\n\n\t/* XXX: where to release temp regs in intermediate expressions?\n\t * e.g. 1+2+3 -> don't inflate temp register count when parsing this.\n\t * that particular expression temp regs can be forced here.\n\t */\n\n\t/* XXX: increase ctx->expr_tokens here for every consumed token\n\t * (this would be a nice statistic)?\n\t */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON || comp_ctx->curr_token.t == DUK_TOK_RPAREN) {\n\t\t/* XXX: possibly incorrect handling of empty expression */\n\t\tDUK_DDD(DUK_DDDPRINT(\"empty expression\"));\n\t\tif (!(rbp_flags & DUK__EXPR_FLAG_ALLOW_EMPTY)) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EMPTY_EXPR_NOT_ALLOWED);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tduk_push_undefined(thr);\n\t\tduk__ivalue_plain_fromstack(comp_ctx, res);\n\t\tgoto cleanup;\n\t}\n\n\tduk__advance(comp_ctx);\n\tduk__expr_nud(comp_ctx, res);  /* reuse 'res' as 'left' */\n\twhile (rbp < duk__expr_lbp(comp_ctx)) {\n\t\tduk__advance(comp_ctx);\n\t\tduk__expr_led(comp_ctx, res, tmp);\n\t\tduk__copy_ivalue(comp_ctx, tmp, res);  /* tmp -> res */\n\t}\n\n cleanup:\n\t/* final result is already in 'res' */\n\n\tduk_pop_2(thr);\n\n\tDUK__RECURSION_DECREASE(comp_ctx, thr);\n}\n\nDUK_LOCAL void duk__exprtop(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\t/* Note: these variables must reside in 'curr_func' instead of the global\n\t * context: when parsing function expressions, expression parsing is nested.\n\t */\n\tcomp_ctx->curr_func.nud_count = 0;\n\tcomp_ctx->curr_func.led_count = 0;\n\tcomp_ctx->curr_func.paren_level = 0;\n\tcomp_ctx->curr_func.expr_lhs = 1;\n\tcomp_ctx->curr_func.allow_in = (rbp_flags & DUK__EXPR_FLAG_REJECT_IN ? 0 : 1);\n\n\tduk__expr(comp_ctx, res, rbp_flags);\n\n\tif (!(rbp_flags & DUK__EXPR_FLAG_ALLOW_EMPTY) && duk__expr_is_empty(comp_ctx)) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EMPTY_EXPR_NOT_ALLOWED);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\n/* A bunch of helpers (for size optimization) that combine duk__expr()/duk__exprtop()\n * and result conversions.\n *\n * Each helper needs at least 2-3 calls to make it worth while to wrap.\n */\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__expr_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toreg(comp_ctx, res);\n}\n#endif\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__expr_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_totemp(comp_ctx, res);\n}\n#endif\n\nDUK_LOCAL void duk__expr_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\tduk__expr(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toforcedreg(comp_ctx, res, forced_reg);\n}\n\nDUK_LOCAL duk_regconst_t duk__expr_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toregconst(comp_ctx, res);\n}\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__expr_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_totempconst(comp_ctx, res);\n}\n#endif\n\nDUK_LOCAL void duk__expr_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toplain(comp_ctx, res);\n}\n\nDUK_LOCAL void duk__expr_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toplain_ignore(comp_ctx, res);\n}\n\nDUK_LOCAL duk_regconst_t duk__exprtop_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toreg(comp_ctx, res);\n}\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__exprtop_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_totemp(comp_ctx, res);\n}\n#endif\n\nDUK_LOCAL void duk__exprtop_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toforcedreg(comp_ctx, res, forced_reg);\n}\n\nDUK_LOCAL duk_regconst_t duk__exprtop_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toregconst(comp_ctx, res);\n}\n\n#if 0  /* unused */\nDUK_LOCAL void duk__exprtop_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, int rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toplain_ignore(comp_ctx, res);\n}\n#endif\n\n/*\n *  Parse an individual source element (top level statement) or a statement.\n *\n *  Handles labeled statements automatically (peeling away labels before\n *  parsing an expression that follows the label(s)).\n *\n *  Upon entry, 'curr_tok' contains the first token of the statement (parsed\n *  in \"allow regexp literal\" mode).  Upon exit, 'curr_tok' contains the first\n *  token following the statement (if the statement has a terminator, this is\n *  the token after the terminator).\n */\n\n#define DUK__HAS_VAL                  (1 << 0)  /* stmt has non-empty value */\n#define DUK__HAS_TERM                 (1 << 1)  /* stmt has explicit/implicit semicolon terminator */\n#define DUK__ALLOW_AUTO_SEMI_ALWAYS   (1 << 2)  /* allow automatic semicolon even without lineterm (compatibility) */\n#define DUK__STILL_PROLOGUE           (1 << 3)  /* statement does not terminate directive prologue */\n#define DUK__IS_TERMINAL              (1 << 4)  /* statement is guaranteed to be terminal (control doesn't flow to next statement) */\n\n/* Parse a single variable declaration (e.g. \"i\" or \"i=10\").  A leading 'var'\n * has already been eaten.  These is no return value in 'res', it is used only\n * as a temporary.\n *\n * When called from 'for-in' statement parser, the initializer expression must\n * not allow the 'in' token.  The caller supply additional expression parsing\n * flags (like DUK__EXPR_FLAG_REJECT_IN) in 'expr_flags'.\n *\n * Finally, out_rc_varname and out_reg_varbind are updated to reflect where\n * the identifier is bound:\n *\n *    If register bound:      out_reg_varbind >= 0, out_rc_varname == 0 (ignore)\n *    If not register bound:  out_reg_varbind < 0, out_rc_varname >= 0\n *\n * These allow the caller to use the variable for further assignment, e.g.\n * as is done in 'for-in' parsing.\n */\n\nDUK_LOCAL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hstring *h_varname;\n\tduk_regconst_t reg_varbind;\n\tduk_regconst_t rc_varname;\n\n\t/* assume 'var' has been eaten */\n\n\t/* Note: Identifier rejects reserved words */\n\tif (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) {\n\t\tgoto syntax_error;\n\t}\n\th_varname = comp_ctx->curr_token.str1;\n\n\tDUK_ASSERT(h_varname != NULL);\n\n\t/* strict mode restrictions (E5 Section 12.2.1) */\n\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\tgoto syntax_error;\n\t}\n\n\t/* register declarations in first pass */\n\tif (comp_ctx->curr_func.in_scanning) {\n\t\tduk_uarridx_t n;\n\t\tDUK_DDD(DUK_DDDPRINT(\"register variable declaration %!O in pass 1\",\n\t\t                     (duk_heaphdr *) h_varname));\n\t\tn = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.decls_idx);\n\t\tduk_push_hstring(thr, h_varname);\n\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n);\n\t\tduk_push_int(thr, DUK_DECL_TYPE_VAR + (0 << 8));\n\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n + 1);\n\t}\n\n\tduk_push_hstring(thr, h_varname);  /* push before advancing to keep reachable */\n\n\t/* register binding lookup is based on varmap (even in first pass) */\n\tduk_dup_top(thr);\n\t(void) duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname);\n\n\tduk__advance(comp_ctx);  /* eat identifier */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_EQUALSIGN) {\n\t\tduk__advance(comp_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"vardecl, assign to '%!O' -> reg_varbind=%ld, rc_varname=%ld\",\n\t\t                     (duk_heaphdr *) h_varname, (long) reg_varbind, (long) rc_varname));\n\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_COMMA | expr_flags /*rbp_flags*/);  /* AssignmentExpression */\n\n\t\tif (reg_varbind >= 0) {\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_varbind);\n\t\t} else {\n\t\t\tduk_regconst_t reg_val;\n\t\t\treg_val = duk__ivalue_toreg(comp_ctx, res);\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t               reg_val,\n\t\t\t               rc_varname);\n\t\t}\n\t} else {\n\t\tif (expr_flags & DUK__EXPR_FLAG_REQUIRE_INIT) {\n\t\t\t/* Used for minimal 'const': initializer required. */\n\t\t\tgoto syntax_error;\n\t\t}\n\t}\n\n\tduk_pop(thr);  /* pop varname */\n\n\t*out_rc_varname = rc_varname;\n\t*out_reg_varbind = reg_varbind;\n\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_VAR_DECLARATION);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_var_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags) {\n\tduk_regconst_t reg_varbind;\n\tduk_regconst_t rc_varname;\n\n\tduk__advance(comp_ctx);  /* eat 'var' */\n\n\tfor (;;) {\n\t\t/* rc_varname and reg_varbind are ignored here */\n\t\tduk__parse_var_decl(comp_ctx, res, 0 | expr_flags, &reg_varbind, &rc_varname);\n\n\t\tif (comp_ctx->curr_token.t != DUK_TOK_COMMA) {\n\t\t\tbreak;\n\t\t}\n\t\tduk__advance(comp_ctx);\n\t}\n}\n\nDUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_int_t pc_v34_lhs;         /* start variant 3/4 left-hand-side code (L1 in doc/compiler.rst example) */\n\tduk_regconst_t temp_reset;    /* knock back \"next temp\" to this whenever possible */\n\tduk_regconst_t reg_temps;     /* preallocated temporaries (2) for variants 3 and 4 */\n\n\tDUK_DDD(DUK_DDDPRINT(\"start parsing a for/for-in statement\"));\n\n\t/* Two temporaries are preallocated here for variants 3 and 4 which need\n\t * registers which are never clobbered by expressions in the loop\n\t * (concretely: for the enumerator object and the next enumerated value).\n\t * Variants 1 and 2 \"release\" these temps.\n\t */\n\n\treg_temps = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\ttemp_reset = DUK__GETTEMP(comp_ctx);\n\n\t/*\n\t *  For/for-in main variants are:\n\t *\n\t *    1. for (ExpressionNoIn_opt; Expression_opt; Expression_opt) Statement\n\t *    2. for (var VariableDeclarationNoIn; Expression_opt; Expression_opt) Statement\n\t *    3. for (LeftHandSideExpression in Expression) Statement\n\t *    4. for (var VariableDeclarationNoIn in Expression) Statement\n\t *\n\t *  Parsing these without arbitrary lookahead or backtracking is relatively\n\t *  tricky but we manage to do so for now.\n\t *\n\t *  See doc/compiler.rst for a detailed discussion of control flow\n\t *  issues, evaluation order issues, etc.\n\t */\n\n\tduk__advance(comp_ctx);  /* eat 'for' */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\tDUK_DDD(DUK_DDDPRINT(\"detecting for/for-in loop variant, pc=%ld\", (long) duk__get_current_pc(comp_ctx)));\n\n\t/* a label site has been emitted by duk__parse_stmt() automatically\n\t * (it will also emit the ENDLABEL).\n\t */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_VAR) {\n\t\t/*\n\t\t *  Variant 2 or 4\n\t\t */\n\n\t\tduk_regconst_t reg_varbind;  /* variable binding register if register-bound (otherwise < 0) */\n\t\tduk_regconst_t rc_varname;   /* variable name reg/const, if variable not register-bound */\n\n\t\tduk__advance(comp_ctx);  /* eat 'var' */\n\t\tduk__parse_var_decl(comp_ctx, res, DUK__EXPR_FLAG_REJECT_IN, &reg_varbind, &rc_varname);\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_IN) {\n\t\t\t/*\n\t\t\t *  Variant 4\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 4: for (var VariableDeclarationNoIn in Expression) Statement\"));\n\t\t\tpc_v34_lhs = duk__get_current_pc(comp_ctx);  /* jump is inserted here */\n\t\t\tif (reg_varbind >= 0) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_LDREG,\n\t\t\t\t               reg_varbind,\n\t\t\t\t               reg_temps + 0);\n\t\t\t} else {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t               reg_temps + 0,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\t\t\tgoto parse_3_or_4;\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Variant 2\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 2: for (var VariableDeclarationNoIn; Expression_opt; Expression_opt) Statement\"));\n\t\t\tfor (;;) {\n\t\t\t\t/* more initializers */\n\t\t\t\tif (comp_ctx->curr_token.t != DUK_TOK_COMMA) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"variant 2 has another variable initializer\"));\n\n\t\t\t\tduk__advance(comp_ctx);  /* eat comma */\n\t\t\t\tduk__parse_var_decl(comp_ctx, res, DUK__EXPR_FLAG_REJECT_IN, &reg_varbind, &rc_varname);\n\t\t\t}\n\t\t\tgoto parse_1_or_2;\n\t\t}\n\t} else {\n\t\t/*\n\t\t *  Variant 1 or 3\n\t\t */\n\n\t\tpc_v34_lhs = duk__get_current_pc(comp_ctx);  /* jump is inserted here (variant 3) */\n\n\t\t/* Note that duk__exprtop() here can clobber any reg above current temp_next,\n\t\t * so any loop variables (e.g. enumerator) must be \"preallocated\".\n\t\t */\n\n\t\t/* don't coerce yet to a plain value (variant 3 needs special handling) */\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR | DUK__EXPR_FLAG_REJECT_IN | DUK__EXPR_FLAG_ALLOW_EMPTY /*rbp_flags*/);  /* Expression */\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_IN) {\n\t\t\t/*\n\t\t\t *  Variant 3\n\t\t\t */\n\n\t\t\t/* XXX: need to determine LHS type, and check that it is LHS compatible */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 3: for (LeftHandSideExpression in Expression) Statement\"));\n\t\t\tif (duk__expr_is_empty(comp_ctx)) {\n\t\t\t\tgoto syntax_error;  /* LeftHandSideExpression does not allow empty expression */\n\t\t\t}\n\n\t\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\t\tduk_regconst_t reg_varbind;\n\t\t\t\tduk_regconst_t rc_varname;\n\n\t\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_LDREG,\n\t\t\t\t\t               reg_varbind,\n\t\t\t\t\t               reg_temps + 0);\n\t\t\t\t} else {\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t\t               reg_temps + 0,\n\t\t\t\t\t               rc_varname);\n\t\t\t\t}\n\t\t\t} else if (res->t == DUK_IVAL_PROP) {\n\t\t\t\t/* Don't allow a constant for the object (even for a number etc), as\n\t\t\t\t * it goes into the 'A' field of the opcode.\n\t\t\t\t */\n\t\t\t\tduk_regconst_t reg_obj;\n\t\t\t\tduk_regconst_t rc_key;\n\t\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                reg_obj,\n\t\t\t\t                rc_key,\n\t\t\t\t                reg_temps + 0);\n\t\t\t} else {\n\t\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);  /* just in case */\n\t\t\t\tduk__emit_op_only(comp_ctx,\n\t\t\t\t                  DUK_OP_INVLHS);\n\t\t\t}\n\t\t\tgoto parse_3_or_4;\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Variant 1\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 1: for (ExpressionNoIn_opt; Expression_opt; Expression_opt) Statement\"));\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);\n\t\t\tgoto parse_1_or_2;\n\t\t}\n\t}\n\n parse_1_or_2:\n\t/*\n\t *  Parse variant 1 or 2.  The first part expression (which differs\n\t *  in the variants) has already been parsed and its code emitted.\n\t *\n\t *  reg_temps + 0: unused\n\t *  reg_temps + 1: unused\n\t */\n\t{\n\t\tduk_regconst_t rc_cond;\n\t\tduk_int_t pc_l1, pc_l2, pc_l3, pc_l4;\n\t\tduk_int_t pc_jumpto_l3, pc_jumpto_l4;\n\t\tduk_bool_t expr_c_empty;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"shared code for parsing variants 1 and 2\"));\n\n\t\t/* \"release\" preallocated temps since we won't need them */\n\t\ttemp_reset = reg_temps + 0;\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_SEMICOLON);\n\n\t\tpc_l1 = duk__get_current_pc(comp_ctx);\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR | DUK__EXPR_FLAG_ALLOW_EMPTY /*rbp_flags*/);  /* Expression_opt */\n\t\tif (duk__expr_is_empty(comp_ctx)) {\n\t\t\t/* no need to coerce */\n\t\t\tpc_jumpto_l3 = duk__emit_jump_empty(comp_ctx);  /* to body */\n\t\t\tpc_jumpto_l4 = -1;  /* omitted */\n\t\t} else {\n\t\t\trc_cond = duk__ivalue_toregconst(comp_ctx, res);\n\t\t\tduk__emit_if_false_skip(comp_ctx, rc_cond);\n\t\t\tpc_jumpto_l3 = duk__emit_jump_empty(comp_ctx);  /* to body */\n\t\t\tpc_jumpto_l4 = duk__emit_jump_empty(comp_ctx);  /* to exit */\n\t\t}\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_SEMICOLON);\n\n\t\tpc_l2 = duk__get_current_pc(comp_ctx);\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR | DUK__EXPR_FLAG_ALLOW_EMPTY /*rbp_flags*/);  /* Expression_opt */\n\t\tif (duk__expr_is_empty(comp_ctx)) {\n\t\t\t/* no need to coerce */\n\t\t\texpr_c_empty = 1;\n\t\t\t/* JUMP L1 omitted */\n\t\t} else {\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);\n\t\t\texpr_c_empty = 0;\n\t\t\tduk__emit_jump(comp_ctx, pc_l1);\n\t\t}\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\t\tpc_l3 = duk__get_current_pc(comp_ctx);\n\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\t\tif (expr_c_empty) {\n\t\t\tduk__emit_jump(comp_ctx, pc_l1);\n\t\t} else {\n\t\t\tduk__emit_jump(comp_ctx, pc_l2);\n\t\t}\n\t\t/* temp reset is not necessary after duk__parse_stmt(), which already does it */\n\n\t\tpc_l4 = duk__get_current_pc(comp_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"patching jumps: jumpto_l3: %ld->%ld, jumpto_l4: %ld->%ld, \"\n\t\t                     \"break: %ld->%ld, continue: %ld->%ld\",\n\t\t\t             (long) pc_jumpto_l3, (long) pc_l3, (long) pc_jumpto_l4, (long) pc_l4,\n\t\t                     (long) (pc_label_site + 1), (long) pc_l4, (long) (pc_label_site + 2), (long) pc_l2));\n\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l3, pc_l3);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l4, pc_l4);\n\t\tduk__patch_jump(comp_ctx,\n\t\t                pc_label_site + 1,\n\t\t                pc_l4);                         /* break jump */\n\t\tduk__patch_jump(comp_ctx,\n\t\t                pc_label_site + 2,\n\t\t                expr_c_empty ? pc_l1 : pc_l2);  /* continue jump */\n\t}\n\tgoto finished;\n\n parse_3_or_4:\n\t/*\n\t *  Parse variant 3 or 4.\n\t *\n\t *  For variant 3 (e.g. \"for (A in C) D;\") the code for A (except the\n\t *  final property/variable write) has already been emitted.  The first\n\t *  instruction of that code is at pc_v34_lhs; a JUMP needs to be inserted\n\t *  there to satisfy control flow needs.\n\t *\n\t *  For variant 4, if the variable declaration had an initializer\n\t *  (e.g. \"for (var A = B in C) D;\") the code for the assignment\n\t *  (B) has already been emitted.\n\t *\n\t *  Variables set before entering here:\n\t *\n\t *    pc_v34_lhs:    insert a \"JUMP L2\" here (see doc/compiler.rst example).\n\t *    reg_temps + 0: iteration target value (written to LHS)\n\t *    reg_temps + 1: enumerator object\n\t */\n\t{\n\t\tduk_int_t pc_l1, pc_l2, pc_l3, pc_l4, pc_l5;\n\t\tduk_int_t pc_jumpto_l2, pc_jumpto_l3, pc_jumpto_l4, pc_jumpto_l5;\n\t\tduk_regconst_t reg_target;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"shared code for parsing variants 3 and 4, pc_v34_lhs=%ld\", (long) pc_v34_lhs));\n\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\t/* First we need to insert a jump in the middle of previously\n\t\t * emitted code to get the control flow right.  No jumps can\n\t\t * cross the position where the jump is inserted.  See doc/compiler.rst\n\t\t * for discussion on the intricacies of control flow and side effects\n\t\t * for variants 3 and 4.\n\t\t */\n\n\t\tduk__insert_jump_entry(comp_ctx, pc_v34_lhs);\n\t\tpc_jumpto_l2 = pc_v34_lhs;  /* inserted jump */\n\t\tpc_l1 = pc_v34_lhs + 1;     /* +1, right after inserted jump */\n\n\t\t/* The code for writing reg_temps + 0 to the left hand side has already\n\t\t * been emitted.\n\t\t */\n\n\t\tpc_jumpto_l3 = duk__emit_jump_empty(comp_ctx);  /* -> loop body */\n\n\t\tduk__advance(comp_ctx);  /* eat 'in' */\n\n\t\t/* Parse enumeration target and initialize enumerator.  For 'null' and 'undefined',\n\t\t * INITENUM will creates a 'null' enumerator which works like an empty enumerator\n\t\t * (E5 Section 12.6.4, step 3).  Note that INITENUM requires the value to be in a\n\t\t * register (constant not allowed).\n\t\t */\n\n\t\tpc_l2 = duk__get_current_pc(comp_ctx);\n\t\treg_target = duk__exprtop_toreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);  /* Expression */\n\t\tduk__emit_b_c(comp_ctx,\n\t\t              DUK_OP_INITENUM | DUK__EMIT_FLAG_B_IS_TARGET,\n\t\t              reg_temps + 1,\n\t\t              reg_target);\n\t\tpc_jumpto_l4 = duk__emit_jump_empty(comp_ctx);\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\t\tpc_l3 = duk__get_current_pc(comp_ctx);\n\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\t\t/* temp reset is not necessary after duk__parse_stmt(), which already does it */\n\n\t\t/* NEXTENUM needs a jump slot right after the main opcode.\n\t\t * We need the code emitter to reserve the slot: if there's\n\t\t * target shuffling, the target shuffle opcodes must happen\n\t\t * after the jump slot (for NEXTENUM the shuffle opcodes are\n\t\t * not needed if the enum is finished).\n\t\t */\n\t\tpc_l4 = duk__get_current_pc(comp_ctx);\n\t\tduk__emit_b_c(comp_ctx,\n\t\t              DUK_OP_NEXTENUM | DUK__EMIT_FLAG_B_IS_TARGET | DUK__EMIT_FLAG_RESERVE_JUMPSLOT,\n\t\t              reg_temps + 0,\n\t\t              reg_temps + 1);\n\t\tpc_jumpto_l5 = comp_ctx->emit_jumpslot_pc;  /* NEXTENUM jump slot: executed when enum finished */\n\t\tduk__emit_jump(comp_ctx, pc_l1);  /* jump to next loop, using reg_v34_iter as iterated value */\n\n\t\tpc_l5 = duk__get_current_pc(comp_ctx);\n\n\t\t/* XXX: since the enumerator may be a memory expensive object,\n\t\t * perhaps clear it explicitly here?  If so, break jump must\n\t\t * go through this clearing operation.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"patching jumps: jumpto_l2: %ld->%ld, jumpto_l3: %ld->%ld, \"\n\t\t                     \"jumpto_l4: %ld->%ld, jumpto_l5: %ld->%ld, \"\n\t\t                     \"break: %ld->%ld, continue: %ld->%ld\",\n\t\t\t             (long) pc_jumpto_l2, (long) pc_l2, (long) pc_jumpto_l3, (long) pc_l3,\n\t\t\t             (long) pc_jumpto_l4, (long) pc_l4, (long) pc_jumpto_l5, (long) pc_l5,\n\t\t                     (long) (pc_label_site + 1), (long) pc_l5, (long) (pc_label_site + 2), (long) pc_l4));\n\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l2, pc_l2);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l3, pc_l3);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l4, pc_l4);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l5, pc_l5);\n\t\tduk__patch_jump(comp_ctx, pc_label_site + 1, pc_l5);  /* break jump */\n\t\tduk__patch_jump(comp_ctx, pc_label_site + 2, pc_l4);  /* continue jump */\n\t}\n\tgoto finished;\n\n finished:\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing a for/for-in statement\"));\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_FOR);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t temp_at_loop;\n\tduk_regconst_t rc_switch;    /* reg/const for switch value */\n\tduk_regconst_t rc_case;      /* reg/const for case value */\n\tduk_regconst_t reg_temp;     /* general temp register */\n\tduk_int_t pc_prevcase = -1;\n\tduk_int_t pc_prevstmt = -1;\n\tduk_int_t pc_default = -1;   /* -1 == not set, -2 == pending (next statement list) */\n\n\t/* Note: negative pc values are ignored when patching jumps, so no explicit checks needed */\n\n\t/*\n\t *  Switch is pretty complicated because of several conflicting concerns:\n\t *\n\t *    - Want to generate code without an intermediate representation,\n\t *      i.e., in one go\n\t *\n\t *    - Case selectors are expressions, not values, and may thus e.g. throw\n\t *      exceptions (which causes evaluation order concerns)\n\t *\n\t *    - Evaluation semantics of case selectors and default clause need to be\n\t *      carefully implemented to provide correct behavior even with case value\n\t *      side effects\n\t *\n\t *    - Fall through case and default clauses; avoiding dead JUMPs if case\n\t *      ends with an unconditional jump (a break or a continue)\n\t *\n\t *    - The same case value may occur multiple times, but evaluation rules\n\t *      only process the first match before switching to a \"propagation\" mode\n\t *      where case values are no longer evaluated\n\t *\n\t *  See E5 Section 12.11.  Also see doc/compiler.rst for compilation\n\t *  discussion.\n\t */\n\n\tduk__advance(comp_ctx);\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\trc_switch = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* RegExp mode does not matter. */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\n\tDUK_DDD(DUK_DDDPRINT(\"switch value in register %ld\", (long) rc_switch));\n\n\ttemp_at_loop = DUK__GETTEMP(comp_ctx);\n\n\tfor (;;) {\n\t\tduk_int_t num_stmts;\n\t\tduk_small_uint_t tok;\n\n\t\t/* sufficient for keeping temp reg numbers in check */\n\t\tDUK__SETTEMP(comp_ctx, temp_at_loop);\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\tbreak;\n\t\t}\n\n\t\t/*\n\t\t *  Parse a case or default clause.\n\t\t */\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_CASE) {\n\t\t\t/*\n\t\t\t *  Case clause.\n\t\t\t *\n\t\t\t *  Note: cannot use reg_case as a temp register (for SEQ target)\n\t\t\t *  because it may be a constant.\n\t\t\t */\n\n\t\t\tduk__patch_jump_here(comp_ctx, pc_prevcase);  /* chain jumps for case\n\t\t\t                                               * evaluation and checking\n\t\t\t                                               */\n\n\t\t\tduk__advance(comp_ctx);\n\t\t\trc_case = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_SEQ | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_temp,\n\t\t\t                rc_switch,\n\t\t\t                rc_case);\n\t\t\tduk__emit_if_true_skip(comp_ctx, reg_temp);\n\n\t\t\t/* jump to next case clause */\n\t\t\tpc_prevcase = duk__emit_jump_empty(comp_ctx);  /* no match, next case */\n\n\t\t\t/* statements go here (if any) on next loop */\n\t\t} else if (comp_ctx->curr_token.t == DUK_TOK_DEFAULT) {\n\t\t\t/*\n\t\t\t *  Default clause.\n\t\t\t */\n\n\t\t\tif (pc_default >= 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t\tduk__advance(comp_ctx);\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\n\t\t\t/* Fix for https://github.com/svaarala/duktape/issues/155:\n\t\t\t * If 'default' is first clause (detected by pc_prevcase < 0)\n\t\t\t * we need to ensure we stay in the matching chain.\n\t\t\t */\n\t\t\tif (pc_prevcase < 0) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"default clause is first, emit prevcase jump\"));\n\t\t\t\tpc_prevcase = duk__emit_jump_empty(comp_ctx);\n\t\t\t}\n\n\t\t\t/* default clause matches next statement list (if any) */\n\t\t\tpc_default = -2;\n\t\t} else {\n\t\t\t/* Code is not accepted before the first case/default clause */\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/*\n\t\t *  Parse code after the clause.  Possible terminators are\n\t\t *  'case', 'default', and '}'.\n\t\t *\n\t\t *  Note that there may be no code at all, not even an empty statement,\n\t\t *  between case clauses.  This must be handled just like an empty statement\n\t\t *  (omitting seemingly pointless JUMPs), to avoid situations like\n\t\t *  test-bug-case-fallthrough.js.\n\t\t */\n\n\t\tnum_stmts = 0;\n\t\tif (pc_default == -2) {\n\t\t\tpc_default = duk__get_current_pc(comp_ctx);\n\t\t}\n\n\t\t/* Note: this is correct even for default clause statements:\n\t\t * they participate in 'fall-through' behavior even if the\n\t\t * default clause is in the middle.\n\t\t */\n\t\tduk__patch_jump_here(comp_ctx, pc_prevstmt);  /* chain jumps for 'fall-through'\n\t\t                                               * after a case matches.\n\t\t                                               */\n\n\t\tfor (;;) {\n\t\t\ttok = comp_ctx->curr_token.t;\n\t\t\tif (tok == DUK_TOK_CASE || tok == DUK_TOK_DEFAULT ||\n\t\t\t    tok == DUK_TOK_RCURLY) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tnum_stmts++;\n\t\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\t\t}\n\n\t\t/* fall-through jump to next code of next case (backpatched) */\n\t\tpc_prevstmt = duk__emit_jump_empty(comp_ctx);\n\n\t\t/* XXX: would be nice to omit this jump when the jump is not\n\t\t * reachable, at least in the obvious cases (such as the case\n\t\t * ending with a 'break'.\n\t\t *\n\t\t * Perhaps duk__parse_stmt() could provide some info on whether\n\t\t * the statement is a \"dead end\"?\n\t\t *\n\t\t * If implemented, just set pc_prevstmt to -1 when not needed.\n\t\t */\n\t}\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RCURLY);\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance(comp_ctx);  /* Allow RegExp as part of next stmt. */\n\n\t/* default case control flow patchup; note that if pc_prevcase < 0\n\t * (i.e. no case clauses), control enters default case automatically.\n\t */\n\tif (pc_default >= 0) {\n\t\t/* default case exists: go there if no case matches */\n\t\tduk__patch_jump(comp_ctx, pc_prevcase, pc_default);\n\t} else {\n\t\t/* default case does not exist, or no statements present\n\t\t * after default case: finish case evaluation\n\t\t */\n\t\tduk__patch_jump_here(comp_ctx, pc_prevcase);\n\t}\n\n\t/* fall-through control flow patchup; note that pc_prevstmt may be\n\t * < 0 (i.e. no case clauses), in which case this is a no-op.\n\t */\n\tduk__patch_jump_here(comp_ctx, pc_prevstmt);\n\n\t/* continue jump not patched, an INVALID opcode remains there */\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 1);  /* break jump */\n\n\t/* Note: 'fast' breaks will jump to pc_label_site + 1, which will\n\t * then jump here.  The double jump will be eliminated by a\n\t * peephole pass, resulting in an optimal jump here.  The label\n\t * site jumps will remain in bytecode and will waste code size.\n\t */\n\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_SWITCH);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_if_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_regconst_t temp_reset;\n\tduk_regconst_t rc_cond;\n\tduk_int_t pc_jump_false;\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin parsing if statement\"));\n\n\ttemp_reset = DUK__GETTEMP(comp_ctx);\n\n\tduk__advance(comp_ctx);  /* eat 'if' */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\trc_cond = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_if_true_skip(comp_ctx, rc_cond);\n\tpc_jump_false = duk__emit_jump_empty(comp_ctx);  /* jump to end or else part */\n\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\n\t/* The 'else' ambiguity is resolved by 'else' binding to the innermost\n\t * construct, so greedy matching is correct here.\n\t */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_ELSE) {\n\t\tduk_int_t pc_jump_end;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"if has else part\"));\n\n\t\tduk__advance(comp_ctx);\n\n\t\tpc_jump_end = duk__emit_jump_empty(comp_ctx);  /* jump from true part to end */\n\t\tduk__patch_jump_here(comp_ctx, pc_jump_false);\n\n\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\n\t\tduk__patch_jump_here(comp_ctx, pc_jump_end);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"if does not have else part\"));\n\n\t\tduk__patch_jump_here(comp_ctx, pc_jump_false);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing if statement\"));\n}\n\nDUK_LOCAL void duk__parse_do_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_regconst_t rc_cond;\n\tduk_int_t pc_start;\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin parsing do statement\"));\n\n\tduk__advance(comp_ctx);  /* Eat 'do'; allow RegExp as part of next stmt. */\n\n\tpc_start = duk__get_current_pc(comp_ctx);\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 2);  /* continue jump */\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_WHILE);\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\trc_cond = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_if_false_skip(comp_ctx, rc_cond);\n\tduk__emit_jump(comp_ctx, pc_start);\n\t/* no need to reset temps, as we're finished emitting code */\n\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;  /* Allow RegExp as part of next stmt. */\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);\n\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 1);  /* break jump */\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing do statement\"));\n}\n\nDUK_LOCAL void duk__parse_while_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_regconst_t temp_reset;\n\tduk_regconst_t rc_cond;\n\tduk_int_t pc_start;\n\tduk_int_t pc_jump_false;\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin parsing while statement\"));\n\n\ttemp_reset = DUK__GETTEMP(comp_ctx);\n\n\tduk__advance(comp_ctx);  /* eat 'while' */\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\tpc_start = duk__get_current_pc(comp_ctx);\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 2);  /* continue jump */\n\n\trc_cond = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_if_true_skip(comp_ctx, rc_cond);\n\tpc_jump_false = duk__emit_jump_empty(comp_ctx);\n\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\tduk__emit_jump(comp_ctx, pc_start);\n\n\tduk__patch_jump_here(comp_ctx, pc_jump_false);\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 1);  /* break jump */\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing while statement\"));\n}\n\nDUK_LOCAL void duk__parse_break_or_continue_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t is_break = (comp_ctx->curr_token.t == DUK_TOK_BREAK);\n\tduk_int_t label_id;\n\tduk_int_t label_catch_depth;\n\tduk_int_t label_pc;  /* points to LABEL; pc+1 = jump site for break; pc+2 = jump site for continue */\n\tduk_bool_t label_is_closest;\n\n\tDUK_UNREF(res);\n\n\tduk__advance(comp_ctx);  /* eat 'break' or 'continue' */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON ||  /* explicit semi follows */\n\t    comp_ctx->curr_token.lineterm ||                /* automatic semi will be inserted */\n\t    comp_ctx->curr_token.allow_auto_semi) {         /* automatic semi will be inserted */\n\t\t/* break/continue without label */\n\n\t\tduk__lookup_active_label(comp_ctx, DUK_HTHREAD_STRING_EMPTY_STRING(thr), is_break, &label_id, &label_catch_depth, &label_pc, &label_is_closest);\n\t} else if (comp_ctx->curr_token.t == DUK_TOK_IDENTIFIER) {\n\t\t/* break/continue with label (label cannot be a reserved word, production is 'Identifier' */\n\t\tDUK_ASSERT(comp_ctx->curr_token.str1 != NULL);\n\t\tduk__lookup_active_label(comp_ctx, comp_ctx->curr_token.str1, is_break, &label_id, &label_catch_depth, &label_pc, &label_is_closest);\n\t\tduk__advance(comp_ctx);\n\t} else {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_BREAK_CONT_LABEL);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* Use a fast break/continue when possible.  A fast break/continue is\n\t * just a jump to the LABEL break/continue jump slot, which then jumps\n\t * to an appropriate place (for break, going through ENDLABEL correctly).\n\t * The peephole optimizer will optimize the jump to a direct one.\n\t */\n\n\tif (label_catch_depth == comp_ctx->curr_func.catch_depth &&\n\t    label_is_closest) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"break/continue: is_break=%ld, label_id=%ld, label_is_closest=%ld, \"\n\t\t                     \"label_catch_depth=%ld, catch_depth=%ld \"\n\t\t                     \"-> use fast variant (direct jump)\",\n\t\t                     (long) is_break, (long) label_id, (long) label_is_closest,\n\t\t                     (long) label_catch_depth, (long) comp_ctx->curr_func.catch_depth));\n\n\t\tduk__emit_jump(comp_ctx, label_pc + (is_break ? 1 : 2));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"break/continue: is_break=%ld, label_id=%ld, label_is_closest=%ld, \"\n\t\t                     \"label_catch_depth=%ld, catch_depth=%ld \"\n\t\t                     \"-> use slow variant (longjmp)\",\n\t\t                     (long) is_break, (long) label_id, (long) label_is_closest,\n\t\t                     (long) label_catch_depth, (long) comp_ctx->curr_func.catch_depth));\n\n\t\tduk__emit_bc(comp_ctx,\n\t\t             is_break ? DUK_OP_BREAK : DUK_OP_CONTINUE,\n\t\t             (duk_regconst_t) label_id);\n\t}\n}\n\nDUK_LOCAL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t rc_val;\n\n\tduk__advance(comp_ctx);  /* eat 'return' */\n\n\t/* A 'return' statement is only allowed inside an actual function body,\n\t * not as part of eval or global code.\n\t */\n\tif (!comp_ctx->curr_func.is_function) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_RETURN);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON ||  /* explicit semi follows */\n\t    comp_ctx->curr_token.lineterm ||                /* automatic semi will be inserted */\n\t    comp_ctx->curr_token.allow_auto_semi) {         /* automatic semi will be inserted */\n\t\tDUK_DDD(DUK_DDDPRINT(\"empty return value -> undefined\"));\n\t\tduk__emit_op_only(comp_ctx, DUK_OP_RETUNDEF);\n\t} else {\n\t\tduk_int_t pc_before_expr;\n\t\tduk_int_t pc_after_expr;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"return with a value\"));\n\n\t\tDUK_UNREF(pc_before_expr);\n\t\tDUK_UNREF(pc_after_expr);\n\n\t\tpc_before_expr = duk__get_current_pc(comp_ctx);\n\t\trc_val = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\t\tpc_after_expr = duk__get_current_pc(comp_ctx);\n\n\t\t/* Tail call check: if last opcode emitted was CALL, and\n\t\t * the context allows it, add a tailcall flag to the CALL.\n\t\t * This doesn't guarantee that a tail call will be allowed at\n\t\t * runtime, so the RETURN must still be emitted.  (Duktape\n\t\t * 0.10.0 avoided this and simulated a RETURN if a tail call\n\t\t * couldn't be used at runtime; but this didn't work\n\t\t * correctly with a thread yield/resume, see\n\t\t * test-bug-tailcall-thread-yield-resume.js for discussion.)\n\t\t *\n\t\t * In addition to the last opcode being CALL, we also need to\n\t\t * be sure that 'rc_val' is the result register of the CALL.\n\t\t * For instance, for the expression 'return 0, (function ()\n\t\t * { return 1; }), 2' the last opcode emitted is CALL (no\n\t\t * bytecode is emitted for '2') but 'rc_val' indicates\n\t\t * constant '2'.  Similarly if '2' is replaced by a register\n\t\t * bound variable, no opcodes are emitted but tail call would\n\t\t * be incorrect.\n\t\t *\n\t\t * This is tricky and easy to get wrong.  It would be best to\n\t\t * track enough expression metadata to check that 'rc_val' came\n\t\t * from that last CALL instruction.  We don't have that metadata\n\t\t * now, so we check that 'rc_val' is a temporary register result\n\t\t * (not a constant or a register bound variable).  There should\n\t\t * be no way currently for 'rc_val' to be a temporary for an\n\t\t * expression following the CALL instruction without emitting\n\t\t * some opcodes following the CALL.  This proxy check is used\n\t\t * below.\n\t\t *\n\t\t * See: test-bug-comma-expr-gh131.js.\n\t\t *\n\t\t * The non-standard 'caller' property disables tail calls\n\t\t * because they pose some special cases which haven't been\n\t\t * fixed yet.\n\t\t */\n\n#if defined(DUK_USE_TAILCALL)\n\t\tif (comp_ctx->curr_func.catch_depth == 0 &&   /* no catchers */\n\t\t    pc_after_expr > pc_before_expr) {         /* at least one opcode emitted */\n\t\t\tduk_compiler_instr *instr;\n\t\t\tduk_instr_t ins;\n\t\t\tduk_small_uint_t op;\n\n\t\t\tinstr = duk__get_instr_ptr(comp_ctx, pc_after_expr - 1);\n\t\t\tDUK_ASSERT(instr != NULL);\n\n\t\t\tins = instr->ins;\n\t\t\top = (duk_small_uint_t) DUK_DEC_OP(ins);\n\t\t\tif ((op & ~0x0fU) == DUK_OP_CALL0 &&\n\t\t\t    DUK__ISREG_TEMP(comp_ctx, rc_val) /* see above */) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"return statement detected a tail call opportunity: \"\n\t\t\t\t                     \"catch depth is 0, duk__exprtop() emitted >= 1 instructions, \"\n\t\t\t\t                     \"and last instruction is a CALL \"\n\t\t\t\t                     \"-> change to TAILCALL\"));\n\t\t\t\tins |= DUK_ENC_OP(DUK_BC_CALL_FLAG_TAILCALL);\n\t\t\t\tinstr->ins = ins;\n\t\t\t}\n\t\t}\n#endif  /* DUK_USE_TAILCALL */\n\n\t\tif (DUK__ISREG(rc_val)) {\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_RETREG, rc_val);\n\t\t} else {\n\t\t\trc_val = DUK__REMOVECONST(rc_val);\n\t\t\tif (duk__const_needs_refcount(comp_ctx, rc_val)) {\n\t\t\t\tduk__emit_bc(comp_ctx, DUK_OP_RETCONST, rc_val);\n\t\t\t} else {\n\t\t\t\tduk__emit_bc(comp_ctx, DUK_OP_RETCONSTN, rc_val);\n\t\t\t}\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__parse_throw_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_regconst_t reg_val;\n\n\tduk__advance(comp_ctx);  /* eat 'throw' */\n\n\t/* Unlike break/continue, throw statement does not allow an empty value. */\n\n\tif (comp_ctx->curr_token.lineterm) {\n\t\tDUK_ERROR_SYNTAX(comp_ctx->thr, DUK_STR_INVALID_THROW);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\treg_val = duk__exprtop_toreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_bc(comp_ctx,\n\t             DUK_OP_THROW,\n\t             reg_val);\n}\n\nDUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg_catch;      /* reg_catch+0 and reg_catch+1 are reserved for TRYCATCH */\n\tduk_regconst_t rc_varname = 0;\n\tduk_small_uint_t trycatch_flags = 0;\n\tduk_int_t pc_ldconst = -1;\n\tduk_int_t pc_trycatch = -1;\n\tduk_int_t pc_catch = -1;\n\tduk_int_t pc_finally = -1;\n\n\tDUK_UNREF(res);\n\n\t/*\n\t *  See the following documentation for discussion:\n\t *\n\t *    doc/execution.rst: control flow details\n\t *\n\t *  Try, catch, and finally \"parts\" are Blocks, not Statements, so\n\t *  they must always be delimited by curly braces.  This is unlike e.g.\n\t *  the if statement, which accepts any Statement.  This eliminates any\n\t *  questions of matching parts of nested try statements.  The Block\n\t *  parsing is implemented inline here (instead of calling out).\n\t *\n\t *  Finally part has a 'let scoped' variable, which requires a few kinks\n\t *  here.\n\t */\n\n\tcomp_ctx->curr_func.catch_depth++;\n\n\tduk__advance(comp_ctx);  /* eat 'try' */\n\n\treg_catch = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\t/* The target for this LDCONST may need output shuffling, but we assume\n\t * that 'pc_ldconst' will be the LDCONST that we can patch later.  This\n\t * should be the case because there's no input shuffling.  (If there's\n\t * no catch clause, this LDCONST will be replaced with a NOP.)\n\t */\n\tpc_ldconst = duk__get_current_pc(comp_ctx);\n\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, reg_catch, 0 /*patched later*/);\n\n\tpc_trycatch = duk__get_current_pc(comp_ctx);\n\tduk__emit_invalid(comp_ctx);  /* TRYCATCH, cannot emit now (not enough info) */\n\tduk__emit_invalid(comp_ctx);  /* jump for 'catch' case */\n\tduk__emit_invalid(comp_ctx);  /* jump for 'finally' case or end (if no finally) */\n\n\t/* try part */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\tduk__emit_op_only(comp_ctx, DUK_OP_ENDTRY);\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_CATCH) {\n\t\t/*\n\t\t *  The catch variable must be updated to reflect the new allocated\n\t\t *  register for the duration of the catch clause.  We need to store\n\t\t *  and restore the original value for the varmap entry (if any).\n\t\t */\n\n\t\t/*\n\t\t *  Note: currently register bindings must be fixed for the entire\n\t\t *  function.  So, even though the catch variable is in a register\n\t\t *  we know, we must use an explicit environment record and slow path\n\t\t *  accesses to read/write the catch binding to make closures created\n\t\t *  within the catch clause work correctly.  This restriction should\n\t\t *  be fixable (at least in common cases) later.\n\t\t *\n\t\t *  See: test-bug-catch-binding-2.js.\n\t\t *\n\t\t *  XXX: improve to get fast path access to most catch clauses.\n\t\t */\n\n\t\tduk_hstring *h_var;\n\t\tduk_int_t varmap_value;  /* for storing/restoring the varmap binding for catch variable */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"stack top at start of catch clause: %ld\", (long) duk_get_top(thr)));\n\n\t\ttrycatch_flags |= DUK_BC_TRYCATCH_FLAG_HAVE_CATCH;\n\n\t\tpc_catch = duk__get_current_pc(comp_ctx);\n\n\t\tduk__advance(comp_ctx);\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\t\tif (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) {\n\t\t\t/* Identifier, i.e. don't allow reserved words */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\th_var = comp_ctx->curr_token.str1;\n\t\tDUK_ASSERT(h_var != NULL);\n\n\t\tduk_push_hstring(thr, h_var);  /* keep in on valstack, use borrowed ref below */\n\n\t\tif (comp_ctx->curr_func.is_strict &&\n\t\t    ((h_var == DUK_HTHREAD_STRING_EVAL(thr)) ||\n\t\t     (h_var == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)))) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"catch identifier 'eval' or 'arguments' in strict mode -> SyntaxError\"));\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\tduk_dup_top(thr);\n\t\trc_varname = duk__getconst(comp_ctx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"catch clause, rc_varname=0x%08lx (%ld)\",\n\t\t                     (unsigned long) rc_varname, (long) rc_varname));\n\n\t\tduk__advance(comp_ctx);\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"varmap before modifying for catch clause: %!iT\",\n\t\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));\n\n\t\tduk_dup_top(thr);\n\t\tduk_get_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\tvarmap_value = -2;\n\t\t} else if (duk_is_null(thr, -1)) {\n\t\t\tvarmap_value = -1;\n\t\t} else {\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tvarmap_value = duk_get_int(thr, -1);\n\t\t\tDUK_ASSERT(varmap_value >= 0);\n\t\t}\n\t\tduk_pop(thr);\n\n#if 0\n\t\t/* It'd be nice to do something like this - but it doesn't\n\t\t * work for closures created inside the catch clause.\n\t\t */\n\t\tduk_dup_top(thr);\n\t\tduk_push_int(thr, (duk_int_t) (reg_catch + 0));\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);\n#endif\n\t\tduk_dup_top(thr);\n\t\tduk_push_null(thr);\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t               reg_catch + 0 /*value*/,\n\t\t               rc_varname /*varname*/);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"varmap before parsing catch clause: %!iT\",\n\t\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));\n\n\t\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\n\t\tif (varmap_value == -2) {\n\t\t\t/* not present */\n\t\t\tduk_del_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\t} else {\n\t\t\tif (varmap_value == -1) {\n\t\t\t\tduk_push_null(thr);\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(varmap_value >= 0);\n\t\t\t\tduk_push_int(thr, varmap_value);\n\t\t\t}\n\t\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\t}\n\t\t/* varname is popped by above code */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"varmap after restore catch clause: %!iT\",\n\t\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));\n\n\t\tduk__emit_op_only(comp_ctx,\n\t\t                  DUK_OP_ENDCATCH);\n\n\t\t/*\n\t\t *  XXX: for now, indicate that an expensive catch binding\n\t\t *  declarative environment is always needed.  If we don't\n\t\t *  need it, we don't need the const_varname either.\n\t\t */\n\n\t\ttrycatch_flags |= DUK_BC_TRYCATCH_FLAG_CATCH_BINDING;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"stack top at end of catch clause: %ld\", (long) duk_get_top(thr)));\n\t}\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_FINALLY) {\n\t\ttrycatch_flags |= DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY;\n\n\t\tpc_finally = duk__get_current_pc(comp_ctx);\n\n\t\tduk__advance(comp_ctx);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\t\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\t\tduk__emit_abc(comp_ctx,\n\t\t              DUK_OP_ENDFIN,\n\t\t              reg_catch);  /* rethrow */\n\t}\n\n\tif (!(trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) &&\n\t    !(trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY)) {\n\t\t/* must have catch and/or finally */\n\t\tgoto syntax_error;\n\t}\n\n\t/* If there's no catch block, rc_varname will be 0 and duk__patch_trycatch()\n\t * will replace the LDCONST with a NOP.  For any actual constant (including\n\t * constant 0) the DUK__CONST_MARKER flag will be set in rc_varname.\n\t */\n\n\tduk__patch_trycatch(comp_ctx,\n\t                    pc_ldconst,\n\t                    pc_trycatch,\n\t                    reg_catch,\n\t                    rc_varname,\n\t                    trycatch_flags);\n\n\tif (trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) {\n\t\tDUK_ASSERT(pc_catch >= 0);\n\t\tduk__patch_jump(comp_ctx, pc_trycatch + 1, pc_catch);\n\t}\n\n\tif (trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY) {\n\t\tDUK_ASSERT(pc_finally >= 0);\n\t\tduk__patch_jump(comp_ctx, pc_trycatch + 2, pc_finally);\n\t} else {\n\t\t/* without finally, the second jump slot is used to jump to end of stmt */\n\t\tduk__patch_jump_here(comp_ctx, pc_trycatch + 2);\n\t}\n\n\tcomp_ctx->curr_func.catch_depth--;\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_TRY);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_int_t pc_trycatch;\n\tduk_int_t pc_finished;\n\tduk_regconst_t reg_catch;\n\tduk_small_uint_t trycatch_flags;\n\n\tif (comp_ctx->curr_func.is_strict) {\n\t\tDUK_ERROR_SYNTAX(comp_ctx->thr, DUK_STR_WITH_IN_STRICT_MODE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tcomp_ctx->curr_func.catch_depth++;\n\n\tduk__advance(comp_ctx);  /* eat 'with' */\n\n\treg_catch = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\tduk__exprtop_toforcedreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/, reg_catch);\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\tpc_trycatch = duk__get_current_pc(comp_ctx);\n\ttrycatch_flags = DUK_BC_TRYCATCH_FLAG_WITH_BINDING;\n\tduk__emit_a_bc(comp_ctx,\n\t                DUK_OP_TRYCATCH | DUK__EMIT_FLAG_NO_SHUFFLE_A,\n\t                (duk_regconst_t) trycatch_flags /*a*/,\n\t                reg_catch /*bc*/);\n\tduk__emit_invalid(comp_ctx);  /* catch jump */\n\tduk__emit_invalid(comp_ctx);  /* finished jump */\n\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\tduk__emit_op_only(comp_ctx, DUK_OP_ENDTRY);\n\n\tpc_finished = duk__get_current_pc(comp_ctx);\n\n\tduk__patch_jump(comp_ctx, pc_trycatch + 2, pc_finished);\n\n\tcomp_ctx->curr_func.catch_depth--;\n}\n\nDUK_LOCAL duk_int_t duk__stmt_label_site(duk_compiler_ctx *comp_ctx, duk_int_t label_id) {\n\t/* if a site already exists, nop: max one label site per statement */\n\tif (label_id >= 0) {\n\t\treturn label_id;\n\t}\n\n\tlabel_id = comp_ctx->curr_func.label_next++;\n\tDUK_DDD(DUK_DDDPRINT(\"allocated new label id for label site: %ld\", (long) label_id));\n\n\tduk__emit_bc(comp_ctx,\n\t             DUK_OP_LABEL,\n\t             (duk_regconst_t) label_id);\n\tduk__emit_invalid(comp_ctx);\n\tduk__emit_invalid(comp_ctx);\n\n\treturn label_id;\n}\n\n/* Parse a single statement.\n *\n * Creates a label site (with an empty label) automatically for iteration\n * statements.  Also \"peels off\" any label statements for explicit labels.\n */\nDUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_bool_t allow_source_elem) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t dir_prol_at_entry;    /* directive prologue status at entry */\n\tduk_regconst_t temp_at_entry;\n\tduk_size_t labels_len_at_entry;\n\tduk_int_t pc_at_entry;           /* assumed to also be PC of \"LABEL\" */\n\tduk_int_t stmt_id;\n\tduk_small_uint_t stmt_flags = 0;\n\tduk_int_t label_id = -1;\n\tduk_small_uint_t tok;\n\tduk_bool_t test_func_decl;\n\n\tDUK__RECURSION_INCREASE(comp_ctx, thr);\n\n\ttemp_at_entry = DUK__GETTEMP(comp_ctx);\n\tpc_at_entry = duk__get_current_pc(comp_ctx);\n\tlabels_len_at_entry = duk_get_length(thr, comp_ctx->curr_func.labelnames_idx);\n\tstmt_id = comp_ctx->curr_func.stmt_next++;\n\tdir_prol_at_entry = comp_ctx->curr_func.in_directive_prologue;\n\n\tDUK_UNREF(stmt_id);\n\n\tDUK_DDD(DUK_DDDPRINT(\"parsing a statement, stmt_id=%ld, temp_at_entry=%ld, labels_len_at_entry=%ld, \"\n\t                     \"is_strict=%ld, in_directive_prologue=%ld, catch_depth=%ld\",\n\t                     (long) stmt_id, (long) temp_at_entry, (long) labels_len_at_entry,\n\t                     (long) comp_ctx->curr_func.is_strict, (long) comp_ctx->curr_func.in_directive_prologue,\n\t                     (long) comp_ctx->curr_func.catch_depth));\n\n\t/* The directive prologue flag is cleared by default so that it is\n\t * unset for any recursive statement parsing.  It is only \"revived\"\n\t * if a directive is detected.  (We could also make directives only\n\t * allowed if 'allow_source_elem' was true.)\n\t */\n\tcomp_ctx->curr_func.in_directive_prologue = 0;\n\n retry_parse:\n\n\tDUK_DDD(DUK_DDDPRINT(\"try stmt parse, stmt_id=%ld, label_id=%ld, allow_source_elem=%ld, catch_depth=%ld\",\n\t                     (long) stmt_id, (long) label_id, (long) allow_source_elem,\n\t                     (long) comp_ctx->curr_func.catch_depth));\n\n\t/*\n\t *  Detect iteration statements; if encountered, establish an\n\t *  empty label.\n\t */\n\n\ttok = comp_ctx->curr_token.t;\n\tif (tok == DUK_TOK_FOR || tok == DUK_TOK_DO || tok == DUK_TOK_WHILE ||\n\t    tok == DUK_TOK_SWITCH) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"iteration/switch statement -> add empty label\"));\n\n\t\tlabel_id = duk__stmt_label_site(comp_ctx, label_id);\n\t\tduk__add_label(comp_ctx,\n\t\t               DUK_HTHREAD_STRING_EMPTY_STRING(thr),\n\t\t               pc_at_entry /*pc_label*/,\n\t\t               label_id);\n\t}\n\n\t/*\n\t *  Main switch for statement / source element type.\n\t */\n\n\tswitch (comp_ctx->curr_token.t) {\n\tcase DUK_TOK_FUNCTION: {\n\t\t/*\n\t\t *  Function declaration, function expression, or (non-standard)\n\t\t *  function statement.\n\t\t *\n\t\t *  The E5 specification only allows function declarations at\n\t\t *  the top level (in \"source elements\").  An ExpressionStatement\n\t\t *  is explicitly not allowed to begin with a \"function\" keyword\n\t\t *  (E5 Section 12.4).  Hence any non-error semantics for such\n\t\t *  non-top-level statements are non-standard.  Duktape semantics\n\t\t *  for function statements are modelled after V8, see\n\t\t *  test-dev-func-decl-outside-top.js.\n\t\t */\n\t\ttest_func_decl = allow_source_elem;\n#if defined(DUK_USE_NONSTD_FUNC_STMT)\n\t\t/* Lenient: allow function declarations outside top level in\n\t\t * non-strict mode but reject them in strict mode.\n\t\t */\n\t\ttest_func_decl = test_func_decl || !comp_ctx->curr_func.is_strict;\n#endif  /* DUK_USE_NONSTD_FUNC_STMT */\n\t\t/* Strict: never allow function declarations outside top level. */\n\t\tif (test_func_decl) {\n\t\t\t/* FunctionDeclaration: not strictly a statement but handled as such.\n\t\t\t *\n\t\t\t * O(depth^2) parse count for inner functions is handled by recording a\n\t\t\t * lexer offset on the first compilation pass, so that the function can\n\t\t\t * be efficiently skipped on the second pass.  This is encapsulated into\n\t\t\t * duk__parse_func_like_fnum().\n\t\t\t */\n\n\t\t\tduk_int_t fnum;\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\tduk_idx_t top_before;\n#endif\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function declaration statement\"));\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\ttop_before = duk_get_top(thr);\n#endif\n\n\t\t\tduk__advance(comp_ctx);  /* eat 'function' */\n\t\t\tfnum = duk__parse_func_like_fnum(comp_ctx, DUK__FUNC_FLAG_DECL | DUK__FUNC_FLAG_PUSHNAME_PASS1);\n\n\t\t\t/* The value stack convention here is a bit odd: the function\n\t\t\t * name is only pushed on pass 1 (in_scanning), and is needed\n\t\t\t * to process function declarations.\n\t\t\t */\n\t\t\tif (comp_ctx->curr_func.in_scanning) {\n\t\t\t\tduk_uarridx_t n;\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t\tDUK_ASSERT(duk_get_top(thr) == top_before + 1);\n#endif\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"register function declaration %!T in pass 1, fnum %ld\",\n\t\t\t\t                     duk_get_tval(thr, -1), (long) fnum));\n\t\t\t\tn = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.decls_idx);\n\t\t\t\t/* funcname is at index -1 */\n\t\t\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n);\n\t\t\t\tduk_push_int(thr, (duk_int_t) (DUK_DECL_TYPE_FUNC + (fnum << 8)));\n\t\t\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n + 1);\n\t\t\t} else {\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t\tDUK_ASSERT(duk_get_top(thr) == top_before);\n#endif\n\t\t\t}\n\n\t\t\t/* no statement value (unlike function expression) */\n\t\t\tstmt_flags = 0;\n\t\t\tbreak;\n\t\t} else {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_FUNC_STMT_NOT_ALLOWED);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TOK_LCURLY: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"block statement\"));\n\t\tduk__advance(comp_ctx);\n\t\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\t\tif (label_id >= 0) {\n\t\t\tduk__patch_jump_here(comp_ctx, pc_at_entry + 1);  /* break jump */\n\t\t}\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_CONST: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"constant declaration statement\"));\n\t\tduk__parse_var_stmt(comp_ctx, res, DUK__EXPR_FLAG_REQUIRE_INIT /*expr_flags*/);\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_VAR: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"variable declaration statement\"));\n\t\tduk__parse_var_stmt(comp_ctx, res, 0 /*expr_flags*/);\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_SEMICOLON: {\n\t\t/* empty statement with an explicit semicolon */\n\t\tDUK_DDD(DUK_DDDPRINT(\"empty statement\"));\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_IF: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"if statement\"));\n\t\tduk__parse_if_stmt(comp_ctx, res);\n\t\tif (label_id >= 0) {\n\t\t\tduk__patch_jump_here(comp_ctx, pc_at_entry + 1);  /* break jump */\n\t\t}\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_DO: {\n\t\t/*\n\t\t *  Do-while statement is mostly trivial, but there is special\n\t\t *  handling for automatic semicolon handling (triggered by the\n\t\t *  DUK__ALLOW_AUTO_SEMI_ALWAYS) flag related to a bug filed at:\n\t\t *\n\t\t *    https://bugs.ecmascript.org/show_bug.cgi?id=8\n\t\t *\n\t\t *  See doc/compiler.rst for details.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"do statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK | DUK_LABEL_FLAG_ALLOW_CONTINUE);\n\t\tduk__parse_do_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__ALLOW_AUTO_SEMI_ALWAYS;  /* DUK__ALLOW_AUTO_SEMI_ALWAYS workaround */\n\t\tbreak;\n\t}\n\tcase DUK_TOK_WHILE: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"while statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK | DUK_LABEL_FLAG_ALLOW_CONTINUE);\n\t\tduk__parse_while_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_FOR: {\n\t\t/*\n\t\t *  For/for-in statement is complicated to parse because\n\t\t *  determining the statement type (three-part for vs. a\n\t\t *  for-in) requires potential backtracking.\n\t\t *\n\t\t *  See the helper for the messy stuff.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"for/for-in statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK | DUK_LABEL_FLAG_ALLOW_CONTINUE);\n\t\tduk__parse_for_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_CONTINUE:\n\tcase DUK_TOK_BREAK: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"break/continue statement\"));\n\t\tduk__parse_break_or_continue_stmt(comp_ctx, res);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__IS_TERMINAL;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_RETURN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"return statement\"));\n\t\tduk__parse_return_stmt(comp_ctx, res);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__IS_TERMINAL;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_WITH: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"with statement\"));\n\t\tcomp_ctx->curr_func.with_depth++;\n\t\tduk__parse_with_stmt(comp_ctx, res);\n\t\tif (label_id >= 0) {\n\t\t\tduk__patch_jump_here(comp_ctx, pc_at_entry + 1);  /* break jump */\n\t\t}\n\t\tcomp_ctx->curr_func.with_depth--;\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_SWITCH: {\n\t\t/*\n\t\t *  The switch statement is pretty messy to compile.\n\t\t *  See the helper for details.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"switch statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK);  /* don't allow continue */\n\t\tduk__parse_switch_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_THROW: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"throw statement\"));\n\t\tduk__parse_throw_stmt(comp_ctx, res);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__IS_TERMINAL;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_TRY: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"try statement\"));\n\t\tduk__parse_try_stmt(comp_ctx, res);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_DEBUGGER: {\n\t\tduk__advance(comp_ctx);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tDUK_DDD(DUK_DDDPRINT(\"debugger statement: debugging enabled, emit debugger opcode\"));\n\t\tduk__emit_op_only(comp_ctx, DUK_OP_DEBUGGER);\n#else\n\t\tDUK_DDD(DUK_DDDPRINT(\"debugger statement: ignored\"));\n#endif\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tdefault: {\n\t\t/*\n\t\t *  Else, must be one of:\n\t\t *    - ExpressionStatement, possibly a directive (String)\n\t\t *    - LabelledStatement (Identifier followed by ':')\n\t\t *\n\t\t *  Expressions beginning with 'function' keyword are covered by a case\n\t\t *  above (such expressions are not allowed in standard E5 anyway).\n\t\t *  Also expressions starting with '{' are interpreted as block\n\t\t *  statements.  See E5 Section 12.4.\n\t\t *\n\t\t *  Directive detection is tricky; see E5 Section 14.1 on directive\n\t\t *  prologue.  A directive is an expression statement with a single\n\t\t *  string literal and an explicit or automatic semicolon.  Escape\n\t\t *  characters are significant and no parens etc are allowed:\n\t\t *\n\t\t *    'use strict';          // valid 'use strict' directive\n\t\t *    'use\\u0020strict';     // valid directive, not a 'use strict' directive\n\t\t *    ('use strict');        // not a valid directive\n\t\t *\n\t\t *  The expression is determined to consist of a single string literal\n\t\t *  based on duk__expr_nud() and duk__expr_led() call counts.  The string literal\n\t\t *  of a 'use strict' directive is determined to lack any escapes based\n\t\t *  num_escapes count from the lexer.  Note that other directives may be\n\t\t *  allowed to contain escapes, so a directive with escapes does not\n\t\t *  terminate a directive prologue.\n\t\t *\n\t\t *  We rely on the fact that the expression parser will not emit any\n\t\t *  code for a single token expression.  However, it will generate an\n\t\t *  intermediate value which we will then successfully ignore.\n\t\t *\n\t\t *  A similar approach is used for labels.\n\t\t */\n\n\t\tduk_bool_t single_token;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"expression statement\"));\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\n\t\tsingle_token = (comp_ctx->curr_func.nud_count == 1 &&  /* one token */\n\t\t                comp_ctx->curr_func.led_count == 0);   /* no operators */\n\n\t\tif (single_token &&\n\t\t    comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t    comp_ctx->curr_token.t == DUK_TOK_COLON) {\n\t\t\t/*\n\t\t\t *  Detected label\n\t\t\t */\n\n\t\t\tduk_hstring *h_lab;\n\n\t\t\t/* expected ival */\n\t\t\tDUK_ASSERT(res->t == DUK_IVAL_VAR);\n\t\t\tDUK_ASSERT(res->x1.t == DUK_ISPEC_VALUE);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(duk_get_tval(thr, res->x1.valstack_idx)));\n\t\t\th_lab = comp_ctx->prev_token.str1;\n\t\t\tDUK_ASSERT(h_lab != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"explicit label site for label '%!O'\",\n\t\t\t                     (duk_heaphdr *) h_lab));\n\n\t\t\tduk__advance(comp_ctx);  /* eat colon */\n\n\t\t\tlabel_id = duk__stmt_label_site(comp_ctx, label_id);\n\n\t\t\tduk__add_label(comp_ctx,\n\t\t\t               h_lab,\n\t\t\t               pc_at_entry /*pc_label*/,\n\t\t\t               label_id);\n\n\t\t\t/* a statement following a label cannot be a source element\n\t\t\t * (a function declaration).\n\t\t\t */\n\t\t\tallow_source_elem = 0;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"label handled, retry statement parsing\"));\n\t\t\tgoto retry_parse;\n\t\t}\n\n\t\tstmt_flags = 0;\n\n\t\tif (dir_prol_at_entry &&                           /* still in prologue */\n\t\t    single_token &&                                /* single string token */\n\t\t    comp_ctx->prev_token.t == DUK_TOK_STRING) {\n\t\t\t/*\n\t\t\t *  Detected a directive\n\t\t\t */\n\t\t\tduk_hstring *h_dir;\n\n\t\t\t/* expected ival */\n\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN);\n\t\t\tDUK_ASSERT(res->x1.t == DUK_ISPEC_VALUE);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(duk_get_tval(thr, res->x1.valstack_idx)));\n\t\t\th_dir = comp_ctx->prev_token.str1;\n\t\t\tDUK_ASSERT(h_dir != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"potential directive: %!O\", h_dir));\n\n\t\t\tstmt_flags |= DUK__STILL_PROLOGUE;\n\n\t\t\t/* Note: escaped characters differentiate directives */\n\n\t\t\tif (comp_ctx->prev_token.num_escapes > 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"directive contains escapes: valid directive \"\n\t\t\t\t                     \"but we ignore such directives\"));\n\t\t\t} else {\n\t\t\t\t/*\n\t\t\t\t * The length comparisons are present to handle\n\t\t\t\t * strings like \"use strict\\u0000foo\" as required.\n\t\t\t\t */\n\n\t\t\t\tif (DUK_HSTRING_GET_BYTELEN(h_dir) == 10 &&\n\t\t\t\t    DUK_STRCMP((const char *) DUK_HSTRING_GET_DATA(h_dir), \"use strict\") == 0) {\n#if defined(DUK_USE_STRICT_DECL)\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"use strict directive detected: strict flag %ld -> %ld\",\n\t\t\t\t\t                     (long) comp_ctx->curr_func.is_strict, (long) 1));\n\t\t\t\t\tcomp_ctx->curr_func.is_strict = 1;\n#else\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"use strict detected but strict declarations disabled, ignoring\"));\n#endif\n\t\t\t\t} else if (DUK_HSTRING_GET_BYTELEN(h_dir) == 14 &&\n\t\t\t\t           DUK_STRCMP((const char *) DUK_HSTRING_GET_DATA(h_dir), \"use duk notail\") == 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"use duk notail directive detected: notail flag %ld -> %ld\",\n\t\t\t\t\t                     (long) comp_ctx->curr_func.is_notail, (long) 1));\n\t\t\t\t\tcomp_ctx->curr_func.is_notail = 1;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"unknown directive: '%!O', ignoring but not terminating \"\n\t\t\t\t\t                   \"directive prologue\", (duk_hobject *) h_dir));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-directive expression statement or no longer in prologue; \"\n\t\t\t                     \"prologue terminated if still active\"));\n                }\n\n\t\tstmt_flags |= DUK__HAS_VAL | DUK__HAS_TERM;\n\t}\n\t}  /* end switch (tok) */\n\n\t/*\n\t *  Statement value handling.\n\t *\n\t *  Global code and eval code has an implicit return value\n\t *  which comes from the last statement with a value\n\t *  (technically a non-\"empty\" continuation, which is\n\t *  different from an empty statement).\n\t *\n\t *  Since we don't know whether a later statement will\n\t *  override the value of the current statement, we need\n\t *  to coerce the statement value to a register allocated\n\t *  for implicit return values.  In other cases we need\n\t *  to coerce the statement value to a plain value to get\n\t *  any side effects out (consider e.g. \"foo.bar;\").\n\t */\n\n\t/* XXX: what about statements which leave a half-cooked value in 'res'\n\t * but have no stmt value?  Any such statements?\n\t */\n\n\tif (stmt_flags & DUK__HAS_VAL) {\n\t\tduk_regconst_t reg_stmt_value = comp_ctx->curr_func.reg_stmt_value;\n\t\tif (reg_stmt_value >= 0) {\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_stmt_value);\n\t\t} else {\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);\n\t\t}\n\t} else {\n\t\t;\n\t}\n\n\t/*\n\t *  Statement terminator check, including automatic semicolon\n\t *  handling.  After this step, 'curr_tok' should be the first\n\t *  token after a possible statement terminator.\n\t */\n\n\tif (stmt_flags & DUK__HAS_TERM) {\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"explicit semicolon terminates statement\"));\n\t\t\tduk__advance(comp_ctx);\n\t\t} else {\n\t\t\tif (comp_ctx->curr_token.allow_auto_semi) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"automatic semicolon terminates statement\"));\n\t\t\t} else if (stmt_flags & DUK__ALLOW_AUTO_SEMI_ALWAYS) {\n\t\t\t\t/* XXX: make this lenience dependent on flags or strictness? */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"automatic semicolon terminates statement (allowed for compatibility \"\n\t\t\t\t                     \"even though no lineterm present before next token)\"));\n\t\t\t} else {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_UNTERMINATED_STMT);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"statement has no terminator\"));\n\t}\n\n\t/*\n\t *  Directive prologue tracking.\n\t */\n\n\tif (stmt_flags & DUK__STILL_PROLOGUE) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"setting in_directive_prologue\"));\n\t\tcomp_ctx->curr_func.in_directive_prologue = 1;\n\t}\n\n\t/*\n\t *  Cleanups (all statement parsing flows through here).\n\t *\n\t *  Pop label site and reset labels.  Reset 'next temp' to value at\n\t *  entry to reuse temps.\n\t */\n\n\tif (label_id >= 0) {\n\t\tduk__emit_bc(comp_ctx,\n\t\t             DUK_OP_ENDLABEL,\n\t\t             (duk_regconst_t) label_id);\n\t}\n\n\tDUK__SETTEMP(comp_ctx, temp_at_entry);\n\n\tduk__reset_labels_to_length(comp_ctx, labels_len_at_entry);\n\n\t/* XXX: return indication of \"terminalness\" (e.g. a 'throw' is terminal) */\n\n\tDUK__RECURSION_DECREASE(comp_ctx, thr);\n}\n\n/*\n *  Parse a statement list.\n *\n *  Handles automatic semicolon insertion and implicit return value.\n *\n *  Upon entry, 'curr_tok' should contain the first token of the first\n *  statement (parsed in the \"allow regexp literal\" mode).  Upon exit,\n *  'curr_tok' contains the token following the statement list terminator\n *  (EOF or closing brace).\n */\n\nDUK_LOCAL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_source_elem, duk_bool_t expect_eof, duk_bool_t regexp_after) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_ivalue res_alloc;\n\tduk_ivalue *res = &res_alloc;\n\n\t/* Setup state.  Initial ivalue is 'undefined'. */\n\n\tduk_require_stack(thr, DUK__PARSE_STATEMENTS_SLOTS);\n\n\t/* XXX: 'res' setup can be moved to function body level; in fact, two 'res'\n\t * intermediate values suffice for parsing of each function.  Nesting is needed\n\t * for nested functions (which may occur inside expressions).\n\t */\n\n\tduk_memzero(&res_alloc, sizeof(res_alloc));\n\tres->t = DUK_IVAL_PLAIN;\n\tres->x1.t = DUK_ISPEC_VALUE;\n\tres->x1.valstack_idx = duk_get_top(thr);\n\tres->x2.valstack_idx = res->x1.valstack_idx + 1;\n\tduk_push_undefined(thr);\n\tduk_push_undefined(thr);\n\n\t/* Parse statements until a closing token (EOF or '}') is found. */\n\n\tfor (;;) {\n\t\t/* Check whether statement list ends. */\n\n\t\tif (expect_eof) {\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_EOF) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* Check statement type based on the first token type.\n\t\t *\n\t\t * Note: expression parsing helpers expect 'curr_tok' to\n\t\t * contain the first token of the expression upon entry.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"TOKEN %ld (non-whitespace, non-comment)\", (long) comp_ctx->curr_token.t));\n\n\t\tduk__parse_stmt(comp_ctx, res, allow_source_elem);\n\t}\n\n\t/* RegExp is allowed / not allowed depending on context.  For function\n\t * declarations RegExp is allowed because it follows a function\n\t * declaration statement and may appear as part of the next statement.\n\t * For function expressions RegExp is not allowed, and it's possible\n\t * to do something like '(function () {} / 123)'.\n\t */\n\tif (regexp_after) {\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t}\n\tduk__advance(comp_ctx);\n\n\t/* Tear down state. */\n\n\tduk_pop_2(thr);\n}\n\n/*\n *  Declaration binding instantiation conceptually happens when calling a\n *  function; for us it essentially means that function prologue.  The\n *  conceptual process is described in E5 Section 10.5.\n *\n *  We need to keep track of all encountered identifiers to (1) create an\n *  identifier-to-register map (\"varmap\"); and (2) detect duplicate\n *  declarations.  Identifiers which are not bound to registers still need\n *  to be tracked for detecting duplicates.  Currently such identifiers\n *  are put into the varmap with a 'null' value, which is later cleaned up.\n *\n *  To support functions with a large number of variable and function\n *  declarations, registers are not allocated beyond a certain limit;\n *  after that limit, variables and functions need slow path access.\n *  Arguments are currently always register bound, which imposes a hard\n *  (and relatively small) argument count limit.\n *\n *  Some bindings in E5 are not configurable (= deletable) and almost all\n *  are mutable (writable).  Exceptions are:\n *\n *    - The 'arguments' binding, established only if no shadowing argument\n *      or function declaration exists.  We handle 'arguments' creation\n *      and binding through an explicit slow path environment record.\n *\n *    - The \"name\" binding for a named function expression.  This is also\n *      handled through an explicit slow path environment record.\n */\n\n/* XXX: add support for variables to not be register bound always, to\n * handle cases with a very large number of variables?\n */\n\nDUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ctx, duk_regconst_t *out_stmt_value_reg) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hstring *h_name;\n\tduk_bool_t configurable_bindings;\n\tduk_uarridx_t num_args;\n\tduk_uarridx_t num_decls;\n\tduk_regconst_t rc_name;\n\tduk_small_uint_t declvar_flags;\n\tduk_uarridx_t i;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\n\t/*\n\t *  Preliminaries\n\t */\n\n\tconfigurable_bindings = comp_ctx->curr_func.is_eval;\n\tDUK_DDD(DUK_DDDPRINT(\"configurable_bindings=%ld\", (long) configurable_bindings));\n\n\t/* varmap is already in comp_ctx->curr_func.varmap_idx */\n\n\t/*\n\t *  Function formal arguments, always bound to registers\n\t *  (there's no support for shuffling them now).\n\t */\n\n\tnum_args = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.argnames_idx);\n\tDUK_DDD(DUK_DDDPRINT(\"num_args=%ld\", (long) num_args));\n\t/* XXX: check num_args */\n\n\tfor (i = 0; i < num_args; i++) {\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.argnames_idx, i);\n\t\th_name = duk_known_hstring(thr, -1);\n\n\t\tif (comp_ctx->curr_func.is_strict) {\n\t\t\tif (duk__hstring_is_eval_or_arguments(comp_ctx, h_name)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"arg named 'eval' or 'arguments' in strict mode -> SyntaxError\"));\n\t\t\t\tgoto error_argname;\n\t\t\t}\n\t\t\tduk_dup_top(thr);\n\t\t\tif (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duplicate arg name in strict mode -> SyntaxError\"));\n\t\t\t\tgoto error_argname;\n\t\t\t}\n\n\t\t\t/* Ensure argument name is not a reserved word in current\n\t\t\t * (final) strictness.  Formal argument parsing may not\n\t\t\t * catch reserved names if strictness changes during\n\t\t\t * parsing.\n\t\t\t *\n\t\t\t * We only need to do this in strict mode because non-strict\n\t\t\t * keyword are always detected in formal argument parsing.\n\t\t\t */\n\n\t\t\tif (DUK_HSTRING_HAS_STRICT_RESERVED_WORD(h_name)) {\n\t\t\t\tgoto error_argname;\n\t\t\t}\n\t\t}\n\n\t\t/* overwrite any previous binding of the same name; the effect is\n\t\t * that last argument of a certain name wins.\n\t\t */\n\n\t\t/* only functions can have arguments */\n\t\tDUK_ASSERT(comp_ctx->curr_func.is_function);\n\t\tduk_push_uarridx(thr, i);  /* -> [ ... name index ] */\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx); /* -> [ ... ] */\n\n\t\t/* no code needs to be emitted, the regs already have values */\n\t}\n\n\t/* use temp_next for tracking register allocations */\n\tDUK__SETTEMP_CHECKMAX(comp_ctx, (duk_regconst_t) num_args);\n\n\t/*\n\t *  After arguments, allocate special registers (like shuffling temps)\n\t */\n\n\tif (out_stmt_value_reg) {\n\t\t*out_stmt_value_reg = DUK__ALLOCTEMP(comp_ctx);\n\t}\n\tif (comp_ctx->curr_func.needs_shuffle) {\n\t\tduk_regconst_t shuffle_base = DUK__ALLOCTEMPS(comp_ctx, 3);\n\t\tcomp_ctx->curr_func.shuffle1 = shuffle_base;\n\t\tcomp_ctx->curr_func.shuffle2 = shuffle_base + 1;\n\t\tcomp_ctx->curr_func.shuffle3 = shuffle_base + 2;\n\t\tDUK_D(DUK_DPRINT(\"shuffle registers needed by function, allocated: %ld %ld %ld\",\n\t\t                 (long) comp_ctx->curr_func.shuffle1,\n\t\t                 (long) comp_ctx->curr_func.shuffle2,\n\t\t                 (long) comp_ctx->curr_func.shuffle3));\n\t}\n\tif (comp_ctx->curr_func.temp_next > 0x100) {\n\t\tDUK_D(DUK_DPRINT(\"not enough 8-bit regs: temp_next=%ld\", (long) comp_ctx->curr_func.temp_next));\n\t\tgoto error_outofregs;\n\t}\n\n\t/*\n\t *  Function declarations\n\t */\n\n\tnum_decls = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.decls_idx);\n\tDUK_DDD(DUK_DDDPRINT(\"num_decls=%ld -> %!T\",\n\t                     (long) num_decls,\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.decls_idx)));\n\tfor (i = 0; i < num_decls; i += 2) {\n\t\tduk_int_t decl_type;\n\t\tduk_int_t fnum;\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i + 1);  /* decl type */\n\t\tdecl_type = duk_to_int(thr, -1);\n\t\tfnum = decl_type >> 8;  /* XXX: macros */\n\t\tdecl_type = decl_type & 0xff;\n\t\tduk_pop(thr);\n\n\t\tif (decl_type != DUK_DECL_TYPE_FUNC) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i);  /* decl name */\n\n\t\t/* XXX: spilling */\n\t\tif (comp_ctx->curr_func.is_function) {\n\t\t\tduk_regconst_t reg_bind;\n\t\t\tduk_dup_top(thr);\n\t\t\tif (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) {\n\t\t\t\t/* shadowed; update value */\n\t\t\t\tduk_dup_top(thr);\n\t\t\t\tduk_get_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\t\t\treg_bind = duk_to_int(thr, -1);  /* [ ... name reg_bind ] */\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_CLOSURE,\n\t\t\t\t               reg_bind,\n\t\t\t\t               (duk_regconst_t) fnum);\n\t\t\t} else {\n\t\t\t\t/* function: always register bound */\n\t\t\t\treg_bind = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_CLOSURE,\n\t\t\t\t               reg_bind,\n\t\t\t\t               (duk_regconst_t) fnum);\n\t\t\t\tduk_push_int(thr, (duk_int_t) reg_bind);\n\t\t\t}\n\t\t} else {\n\t\t\t/* Function declaration for global/eval code is emitted even\n\t\t\t * for duplicates, because of E5 Section 10.5, step 5.e of\n\t\t\t * E5.1 (special behavior for variable bound to global object).\n\t\t\t *\n\t\t\t * DECLVAR will not re-declare a variable as such, but will\n\t\t\t * update the binding value.\n\t\t\t */\n\n\t\t\tduk_regconst_t reg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\tduk_dup_top(thr);\n\t\t\trc_name = duk__getconst(comp_ctx);\n\t\t\tduk_push_null(thr);\n\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CLOSURE,\n\t\t\t               reg_temp,\n\t\t\t               (duk_regconst_t) fnum);\n\n\t\t\tdeclvar_flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t                DUK_PROPDESC_FLAG_ENUMERABLE |\n\t\t\t                DUK_BC_DECLVAR_FLAG_FUNC_DECL;\n\n\t\t\tif (configurable_bindings) {\n\t\t\t\tdeclvar_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t}\n\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_DECLVAR | DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                (duk_regconst_t) declvar_flags /*flags*/,\n\t\t\t                rc_name /*name*/,\n\t\t\t                reg_temp /*value*/);\n\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp);  /* forget temp */\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"function declaration to varmap: %!T -> %!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n#if defined(DUK_USE_FASTINT)\n\t\tDUK_ASSERT(DUK_TVAL_IS_NULL(duk_get_tval(thr, -1)) || DUK_TVAL_IS_FASTINT(duk_get_tval(thr, -1)));\n#endif\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);  /* [ ... name reg/null ] -> [ ... ] */\n\t}\n\n\t/*\n\t *  'arguments' binding is special; if a shadowing argument or\n\t *  function declaration exists, an arguments object will\n\t *  definitely not be needed, regardless of whether the identifier\n\t *  'arguments' is referenced inside the function body.\n\t */\n\n\tif (duk_has_prop_stridx(thr, comp_ctx->curr_func.varmap_idx, DUK_STRIDX_LC_ARGUMENTS)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"'arguments' is shadowed by argument or function declaration \"\n\t\t                     \"-> arguments object creation can be skipped\"));\n\t\tcomp_ctx->curr_func.is_arguments_shadowed = 1;\n\t}\n\n\t/*\n\t *  Variable declarations.\n\t *\n\t *  Unlike function declarations, variable declaration values don't get\n\t *  assigned on entry.  If a binding of the same name already exists, just\n\t *  ignore it silently.\n\t */\n\n\tfor (i = 0; i < num_decls; i += 2) {\n\t\tduk_int_t decl_type;\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i + 1);  /* decl type */\n\t\tdecl_type = duk_to_int(thr, -1);\n\t\tdecl_type = decl_type & 0xff;\n\t\tduk_pop(thr);\n\n\t\tif (decl_type != DUK_DECL_TYPE_VAR) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i);  /* decl name */\n\n\t\tif (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) {\n\t\t\t/* shadowed, ignore */\n\t\t} else {\n\t\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i);  /* decl name */\n\t\t\th_name = duk_known_hstring(thr, -1);\n\n\t\t\tif (h_name == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr) &&\n\t\t\t    !comp_ctx->curr_func.is_arguments_shadowed) {\n\t\t\t\t/* E5 Section steps 7-8 */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"'arguments' not shadowed by a function declaration, \"\n\t\t\t\t                     \"but appears as a variable declaration -> treat as \"\n\t\t\t\t                     \"a no-op for variable declaration purposes\"));\n\t\t\t\tduk_pop(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* XXX: spilling */\n\t\t\tif (comp_ctx->curr_func.is_function) {\n\t\t\t\tduk_regconst_t reg_bind = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\t/* no need to init reg, it will be undefined on entry */\n\t\t\t\tduk_push_int(thr, (duk_int_t) reg_bind);\n\t\t\t} else {\n\t\t\t\tduk_dup_top(thr);\n\t\t\t\trc_name = duk__getconst(comp_ctx);\n\t\t\t\tduk_push_null(thr);\n\n\t\t\t\tdeclvar_flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t                        DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t\tif (configurable_bindings) {\n\t\t\t\t\tdeclvar_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t\t}\n\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                DUK_OP_DECLVAR | DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                (duk_regconst_t) declvar_flags /*flags*/,\n\t\t\t\t                rc_name /*name*/,\n\t\t\t\t                0 /*value*/);\n\t\t\t}\n\n\t\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);  /* [ ... name reg/null ] -> [ ... ] */\n\t\t}\n\t}\n\n\t/*\n\t *  Wrap up\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"varmap: %!T, is_arguments_shadowed=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx),\n\t                     (long) comp_ctx->curr_func.is_arguments_shadowed));\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n\n error_argname:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_ARG_NAME);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Parse a function-body-like expression (FunctionBody or Program\n *  in E5 grammar) using a two-pass parse.  The productions appear\n *  in the following contexts:\n *\n *    - function expression\n *    - function statement\n *    - function declaration\n *    - getter in object literal\n *    - setter in object literal\n *    - global code\n *    - eval code\n *    - Function constructor body\n *\n *  This function only parses the statement list of the body; the argument\n *  list and possible function name must be initialized by the caller.\n *  For instance, for Function constructor, the argument names are originally\n *  on the value stack.  The parsing of statements ends either at an EOF or\n *  a closing brace; this is controlled by an input flag.\n *\n *  Note that there are many differences affecting parsing and even code\n *  generation:\n *\n *    - Global and eval code have an implicit return value generated\n *      by the last statement; function code does not\n *\n *    - Global code, eval code, and Function constructor body end in\n *      an EOF, other bodies in a closing brace ('}')\n *\n *  Upon entry, 'curr_tok' is ignored and the function will pull in the\n *  first token on its own.  Upon exit, 'curr_tok' is the terminating\n *  token (EOF or closing brace).\n */\n\nDUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expect_eof, duk_bool_t implicit_return_value, duk_bool_t regexp_after, duk_small_int_t expect_token) {\n\tduk_compiler_func *func;\n\tduk_hthread *thr;\n\tduk_regconst_t reg_stmt_value = -1;\n\tduk_lexer_point lex_pt;\n\tduk_regconst_t temp_first;\n\tduk_small_int_t compile_round = 1;\n\n\tDUK_ASSERT(comp_ctx != NULL);\n\n\tthr = comp_ctx->thr;\n\tDUK_ASSERT(thr != NULL);\n\n\tfunc = &comp_ctx->curr_func;\n\tDUK_ASSERT(func != NULL);\n\n\tDUK__RECURSION_INCREASE(comp_ctx, thr);\n\n\tduk_require_stack(thr, DUK__FUNCTION_BODY_REQUIRE_SLOTS);\n\n\t/*\n\t *  Store lexer position for a later rewind\n\t */\n\n\tDUK_LEXER_GETPOINT(&comp_ctx->lex, &lex_pt);\n\n\t/*\n\t *  Program code (global and eval code) has an implicit return value\n\t *  from the last statement value (e.g. eval(\"1; 2+3;\") returns 3).\n\t *  This is not the case with functions.  If implicit statement return\n\t *  value is requested, all statements are coerced to a register\n\t *  allocated here, and used in the implicit return statement below.\n\t */\n\n\t/* XXX: this is pointless here because pass 1 is throw-away */\n\tif (implicit_return_value) {\n\t\treg_stmt_value = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t/* If an implicit return value is needed by caller, it must be\n\t\t * initialized to 'undefined' because we don't know whether any\n\t\t * non-empty (where \"empty\" is a continuation type, and different\n\t\t * from an empty statement) statements will be executed.\n\t\t *\n\t\t * However, since 1st pass is a throwaway one, no need to emit\n\t\t * it here.\n\t\t */\n#if 0\n\t\tduk__emit_bc(comp_ctx,\n\t\t             DUK_OP_LDUNDEF,\n\t\t             0);\n#endif\n\t}\n\n\t/*\n\t *  First pass.\n\t *\n\t *  Gather variable/function declarations needed for second pass.\n\t *  Code generated is dummy and discarded.\n\t */\n\n\tfunc->in_directive_prologue = 1;\n\tfunc->in_scanning = 1;\n\tfunc->may_direct_eval = 0;\n\tfunc->id_access_arguments = 0;\n\tfunc->id_access_slow = 0;\n\tfunc->id_access_slow_own = 0;\n\tfunc->reg_stmt_value = reg_stmt_value;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tfunc->min_line = DUK_INT_MAX;\n\tfunc->max_line = 0;\n#endif\n\n\t/* duk__parse_stmts() expects curr_tok to be set; parse in \"allow\n\t * regexp literal\" mode with current strictness.\n\t */\n\tif (expect_token >= 0) {\n\t\t/* Eating a left curly; regexp mode is allowed by left curly\n\t\t * based on duk__token_lbp[] automatically.\n\t\t */\n\t\tDUK_ASSERT(expect_token == DUK_TOK_LCURLY);\n\t\tduk__update_lineinfo_currtoken(comp_ctx);\n\t\tduk__advance_expect(comp_ctx, expect_token);\n\t} else {\n\t\t/* Need to set curr_token.t because lexing regexp mode depends on current\n\t\t * token type.  Zero value causes \"allow regexp\" mode.\n\t\t */\n\t\tcomp_ctx->curr_token.t = 0;\n\t\tduk__advance(comp_ctx);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin 1st pass\"));\n\tduk__parse_stmts(comp_ctx,\n\t                 1,             /* allow source elements */\n\t                 expect_eof,    /* expect EOF instead of } */\n\t                 regexp_after); /* regexp after */\n\tDUK_DDD(DUK_DDDPRINT(\"end 1st pass\"));\n\n\t/*\n\t *  Second (and possibly third) pass.\n\t *\n\t *  Generate actual code.  In most cases the need for shuffle\n\t *  registers is detected during pass 1, but in some corner cases\n\t *  we'll only detect it during pass 2 and a third pass is then\n\t *  needed (see GH-115).\n\t */\n\n\tfor (;;) {\n\t\tduk_bool_t needs_shuffle_before = comp_ctx->curr_func.needs_shuffle;\n\t\tcompile_round++;\n\n\t\t/*\n\t\t *  Rewind lexer.\n\t\t *\n\t\t *  duk__parse_stmts() expects curr_tok to be set; parse in \"allow regexp\n\t\t *  literal\" mode with current strictness.\n\t\t *\n\t\t *  curr_token line number info should be initialized for pass 2 before\n\t\t *  generating prologue, to ensure prologue bytecode gets nice line numbers.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"rewind lexer\"));\n\t\tDUK_LEXER_SETPOINT(&comp_ctx->lex, &lex_pt);\n\t\tcomp_ctx->curr_token.t = 0;  /* this is needed for regexp mode */\n\t\tcomp_ctx->curr_token.start_line = 0;  /* needed for line number tracking (becomes prev_token.start_line) */\n\t\tduk__advance(comp_ctx);\n\n\t\t/*\n\t\t *  Reset function state and perform register allocation, which creates\n\t\t *  'varmap' for second pass.  Function prologue for variable declarations,\n\t\t *  binding value initializations etc is emitted as a by-product.\n\t\t *\n\t\t *  Strict mode restrictions for duplicate and invalid argument\n\t\t *  names are checked here now that we know whether the function\n\t\t *  is actually strict.  See: test-dev-strict-mode-boundary.js.\n\t\t *\n\t\t *  Inner functions are compiled during pass 1 and are not reset.\n\t\t */\n\n\t\tduk__reset_func_for_pass2(comp_ctx);\n\t\tfunc->in_directive_prologue = 1;\n\t\tfunc->in_scanning = 0;\n\n\t\t/* must be able to emit code, alloc consts, etc. */\n\n\t\tduk__init_varmap_and_prologue_for_pass2(comp_ctx,\n\t\t                                        (implicit_return_value ? &reg_stmt_value : NULL));\n\t\tfunc->reg_stmt_value = reg_stmt_value;\n\n\t\ttemp_first = DUK__GETTEMP(comp_ctx);\n\n\t\tfunc->temp_first = temp_first;\n\t\tfunc->temp_next = temp_first;\n\t\tfunc->stmt_next = 0;\n\t\tfunc->label_next = 0;\n\n\t\t/* XXX: init or assert catch depth etc -- all values */\n\t\tfunc->id_access_arguments = 0;\n\t\tfunc->id_access_slow = 0;\n\t\tfunc->id_access_slow_own = 0;\n\n\t\t/*\n\t\t *  Check function name validity now that we know strictness.\n\t\t *  This only applies to function declarations and expressions,\n\t\t *  not setter/getter name.\n\t\t *\n\t\t *  See: test-dev-strict-mode-boundary.js\n\t\t */\n\n\t\tif (func->is_function && !func->is_setget && func->h_name != NULL) {\n\t\t\tif (func->is_strict) {\n\t\t\t\tif (duk__hstring_is_eval_or_arguments(comp_ctx, func->h_name)) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"func name is 'eval' or 'arguments' in strict mode\"));\n\t\t\t\t\tgoto error_funcname;\n\t\t\t\t}\n\t\t\t\tif (DUK_HSTRING_HAS_STRICT_RESERVED_WORD(func->h_name)) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"func name is a reserved word in strict mode\"));\n\t\t\t\t\tgoto error_funcname;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (DUK_HSTRING_HAS_RESERVED_WORD(func->h_name) &&\n\t\t\t\t    !DUK_HSTRING_HAS_STRICT_RESERVED_WORD(func->h_name)) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"func name is a reserved word in non-strict mode\"));\n\t\t\t\t\tgoto error_funcname;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t *  Second pass parsing.\n\t\t */\n\n\t\tif (implicit_return_value) {\n\t\t\t/* Default implicit return value. */\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_LDUNDEF,\n\t\t\t             0);\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"begin 2nd pass\"));\n\t\tduk__parse_stmts(comp_ctx,\n\t\t                 1,             /* allow source elements */\n\t\t                 expect_eof,    /* expect EOF instead of } */\n\t\t                 regexp_after); /* regexp after */\n\t\tDUK_DDD(DUK_DDDPRINT(\"end 2nd pass\"));\n\n\t\tduk__update_lineinfo_currtoken(comp_ctx);\n\n\t\tif (needs_shuffle_before == comp_ctx->curr_func.needs_shuffle) {\n\t\t\t/* Shuffle decision not changed. */\n\t\t\tbreak;\n\t\t}\n\t\tif (compile_round >= 3) {\n\t\t\t/* Should never happen but avoid infinite loop just in case. */\n\t\t\tDUK_D(DUK_DPRINT(\"more than 3 compile passes needed, should never happen\"));\n\t\t\tDUK_ERROR_INTERNAL(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tDUK_D(DUK_DPRINT(\"need additional round to compile function, round now %d\", (int) compile_round));\n\t}\n\n\t/*\n\t *  Emit a final RETURN.\n\t *\n\t *  It would be nice to avoid emitting an unnecessary \"return\" opcode\n\t *  if the current PC is not reachable.  However, this cannot be reliably\n\t *  detected; even if the previous instruction is an unconditional jump,\n\t *  there may be a previous jump which jumps to current PC (which is the\n\t *  case for iteration and conditional statements, for instance).\n\t */\n\n\t/* XXX: request a \"last statement is terminal\" from duk__parse_stmt() and duk__parse_stmts();\n\t * we could avoid the last RETURN if we could ensure there is no way to get here\n\t * (directly or via a jump)\n\t */\n\n\tDUK_ASSERT(comp_ctx->curr_func.catch_depth == 0);\n\tif (reg_stmt_value >= 0) {\n\t\tDUK_ASSERT(DUK__ISREG(reg_stmt_value));\n\t\tduk__emit_bc(comp_ctx, DUK_OP_RETREG, reg_stmt_value /*reg*/);\n\t} else {\n\t\tduk__emit_op_only(comp_ctx, DUK_OP_RETUNDEF);\n\t}\n\n\t/*\n\t *  Peephole optimize JUMP chains.\n\t */\n\n\tduk__peephole_optimize_bytecode(comp_ctx);\n\n\t/*\n\t *  comp_ctx->curr_func is now ready to be converted into an actual\n\t *  function template.\n\t */\n\n\tDUK__RECURSION_DECREASE(comp_ctx, thr);\n\treturn;\n\n error_funcname:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_FUNC_NAME);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Parse a function-like expression:\n *\n *    - function expression\n *    - function declaration\n *    - function statement (non-standard)\n *    - setter/getter\n *\n *  Adds the function to comp_ctx->curr_func function table and returns the\n *  function number.\n *\n *  On entry, curr_token points to:\n *\n *    - the token after 'function' for function expression/declaration/statement\n *    - the token after 'set' or 'get' for setter/getter\n */\n\n/* Parse formals. */\nDUK_LOCAL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t first = 1;\n\tduk_uarridx_t n;\n\n\tfor (;;) {\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RPAREN) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (first) {\n\t\t\t/* no comma */\n\t\t\tfirst = 0;\n\t\t} else {\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COMMA);\n\t\t}\n\n\t\t/* Note: when parsing a formal list in non-strict context, e.g.\n\t\t * \"implements\" is parsed as an identifier.  When the function is\n\t\t * later detected to be strict, the argument list must be rechecked\n\t\t * against a larger set of reserved words (that of strict mode).\n\t\t * This is handled by duk__parse_func_body().  Here we recognize\n\t\t * whatever tokens are considered reserved in current strictness\n\t\t * (which is not always enough).\n\t\t */\n\n\t\tif (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EXPECTED_IDENTIFIER);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_IDENTIFIER);\n\t\tDUK_ASSERT(comp_ctx->curr_token.str1 != NULL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"formal argument: %!O\",\n\t\t                     (duk_heaphdr *) comp_ctx->curr_token.str1));\n\n\t\t/* XXX: append primitive */\n\t\tduk_push_hstring(thr, comp_ctx->curr_token.str1);\n\t\tn = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.argnames_idx);\n\t\tduk_put_prop_index(thr, comp_ctx->curr_func.argnames_idx, n);\n\n\t\tduk__advance(comp_ctx);  /* eat identifier */\n\t}\n}\n\n/* Parse a function-like expression, assuming that 'comp_ctx->curr_func' is\n * correctly set up.  Assumes that curr_token is just after 'function' (or\n * 'set'/'get' etc).\n */\nDUK_LOCAL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_token *tok;\n\tduk_bool_t no_advance;\n\n\tDUK_ASSERT(comp_ctx->curr_func.num_formals == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_function == 1);\n\tDUK_ASSERT(comp_ctx->curr_func.is_eval == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_global == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_setget == ((flags & DUK__FUNC_FLAG_GETSET) != 0));\n\n\tduk__update_lineinfo_currtoken(comp_ctx);\n\n\t/*\n\t *  Function name (if any)\n\t *\n\t *  We don't check for prohibited names here, because we don't\n\t *  yet know whether the function will be strict.  Function body\n\t *  parsing handles this retroactively.\n\t *\n\t *  For function expressions and declarations function name must\n\t *  be an Identifer (excludes reserved words).  For setter/getter\n\t *  it is a PropertyName which allows reserved words and also\n\t *  strings and numbers (e.g. \"{ get 1() { ... } }\").\n\t *\n\t *  Function parsing may start either from prev_token or curr_token\n\t *  (object literal method definition uses prev_token for example).\n\t *  This is dealt with for the initial token.\n\t */\n\n\tno_advance = (flags & DUK__FUNC_FLAG_USE_PREVTOKEN);\n\tif (no_advance) {\n\t\ttok = &comp_ctx->prev_token;\n\t} else {\n\t\ttok = &comp_ctx->curr_token;\n\t}\n\n\tif (flags & DUK__FUNC_FLAG_GETSET) {\n\t\t/* PropertyName -> IdentifierName | StringLiteral | NumericLiteral */\n\t\tif (tok->t_nores == DUK_TOK_IDENTIFIER || tok->t == DUK_TOK_STRING) {\n\t\t\tduk_push_hstring(thr, tok->str1);       /* keep in valstack */\n\t\t} else if (tok->t == DUK_TOK_NUMBER) {\n\t\t\tduk_push_number(thr, tok->num);\n\t\t\tduk_to_string(thr, -1);\n\t\t} else {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_GETSET_NAME);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tcomp_ctx->curr_func.h_name = duk_known_hstring(thr, -1);  /* borrowed reference */\n\t} else {\n\t\t/* Function name is an Identifier (not IdentifierName), but we get\n\t\t * the raw name (not recognizing keywords) here and perform the name\n\t\t * checks only after pass 1.\n\t\t */\n\t\tif (tok->t_nores == DUK_TOK_IDENTIFIER) {\n\t\t\tduk_push_hstring(thr, tok->str1);       /* keep in valstack */\n\t\t\tcomp_ctx->curr_func.h_name = duk_known_hstring(thr, -1);  /* borrowed reference */\n\t\t} else {\n\t\t\t/* valstack will be unbalanced, which is OK */\n\t\t\tDUK_ASSERT((flags & DUK__FUNC_FLAG_GETSET) == 0);\n\t\t\tDUK_ASSERT(comp_ctx->curr_func.h_name == NULL);\n\t\t\tno_advance = 1;\n\t\t\tif (flags & DUK__FUNC_FLAG_DECL) {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_FUNC_NAME_REQUIRED);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t}\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"function name: %!O\",\n\t                   (duk_heaphdr *) comp_ctx->curr_func.h_name));\n\n\tif (!no_advance) {\n\t\tduk__advance(comp_ctx);\n\t}\n\n\t/*\n\t *  Formal argument list\n\t *\n\t *  We don't check for prohibited names or for duplicate argument\n\t *  names here, becase we don't yet know whether the function will\n\t *  be strict.  Function body parsing handles this retroactively.\n\t */\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\tduk__parse_func_formals(comp_ctx);\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RPAREN);\n\tduk__advance(comp_ctx);\n\n\t/*\n\t *  Parse function body\n\t */\n\n\tduk__parse_func_body(comp_ctx,\n\t                     0,   /* expect_eof */\n\t                     0,   /* implicit_return_value */\n\t                     flags & DUK__FUNC_FLAG_DECL, /* regexp_after */\n\t                     DUK_TOK_LCURLY);  /* expect_token */\n\n\t/*\n\t *  Convert duk_compiler_func to a function template and add it\n\t *  to the parent function table.\n\t */\n\n\tduk__convert_to_func_template(comp_ctx);  /* -> [ ... func ] */\n}\n\n/* Parse an inner function, adding the function template to the current function's\n * function table.  Return a function number to be used by the outer function.\n *\n * Avoiding O(depth^2) inner function parsing is handled here.  On the first pass,\n * compile and register the function normally into the 'funcs' array, also recording\n * a lexer point (offset/line) to the closing brace of the function.  On the second\n * pass, skip the function and return the same 'fnum' as on the first pass by using\n * a running counter.\n *\n * An unfortunate side effect of this is that when parsing the inner function, almost\n * nothing is known of the outer function, i.e. the inner function's scope.  We don't\n * need that information at the moment, but it would allow some optimizations if it\n * were used.\n */\nDUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_compiler_func old_func;\n\tduk_idx_t entry_top;\n\tduk_int_t fnum;\n\n\t/*\n\t *  On second pass, skip the function.\n\t */\n\n\tif (!comp_ctx->curr_func.in_scanning) {\n\t\tduk_lexer_point lex_pt;\n\n\t\tfnum = comp_ctx->curr_func.fnum_next++;\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 1));\n\t\tlex_pt.offset = (duk_size_t) duk_to_uint(thr, -1);\n\t\tduk_pop(thr);\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 2));\n\t\tlex_pt.line = duk_to_int(thr, -1);\n\t\tduk_pop(thr);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"second pass of an inner func, skip the function, reparse closing brace; lex offset=%ld, line=%ld\",\n\t\t                     (long) lex_pt.offset, (long) lex_pt.line));\n\n\t\tDUK_LEXER_SETPOINT(&comp_ctx->lex, &lex_pt);\n\t\tcomp_ctx->curr_token.t = 0;  /* this is needed for regexp mode */\n\t\tcomp_ctx->curr_token.start_line = 0;  /* needed for line number tracking (becomes prev_token.start_line) */\n\t\tduk__advance(comp_ctx);\n\n\t\t/* RegExp is not allowed after a function expression, e.g. in\n\t\t * (function () {} / 123).  A RegExp *is* allowed after a\n\t\t * function declaration!\n\t\t */\n\t\tif (flags & DUK__FUNC_FLAG_DECL) {\n\t\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t\t}\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RCURLY);\n\n\t\treturn fnum;\n\t}\n\n\t/*\n\t *  On first pass, perform actual parsing.  Remember valstack top on entry\n\t *  to restore it later, and switch to using a new function in comp_ctx.\n\t */\n\n\tentry_top = duk_get_top(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"before func: entry_top=%ld, curr_tok.start_offset=%ld\",\n\t                     (long) entry_top, (long) comp_ctx->curr_token.start_offset));\n\n\tduk_memcpy(&old_func, &comp_ctx->curr_func, sizeof(duk_compiler_func));\n\n\tduk_memzero(&comp_ctx->curr_func, sizeof(duk_compiler_func));\n\tduk__init_func_valstack_slots(comp_ctx);\n\tDUK_ASSERT(comp_ctx->curr_func.num_formals == 0);\n\n\t/* inherit initial strictness from parent */\n\tcomp_ctx->curr_func.is_strict = old_func.is_strict;\n\n\t/* XXX: It might be better to just store the flags into the curr_func\n\t * struct and use them as is without this flag interpretation step\n\t * here.\n\t */\n\tDUK_ASSERT(comp_ctx->curr_func.is_notail == 0);\n\tcomp_ctx->curr_func.is_function = 1;\n\tDUK_ASSERT(comp_ctx->curr_func.is_eval == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_global == 0);\n\tcomp_ctx->curr_func.is_setget = ((flags & DUK__FUNC_FLAG_GETSET) != 0);\n\tcomp_ctx->curr_func.is_namebinding = !(flags & (DUK__FUNC_FLAG_GETSET |\n\t                                                DUK__FUNC_FLAG_METDEF |\n\t                                                DUK__FUNC_FLAG_DECL));  /* no name binding for: declarations, objlit getset, objlit method def */\n\tcomp_ctx->curr_func.is_constructable = !(flags & (DUK__FUNC_FLAG_GETSET |\n\t                                                  DUK__FUNC_FLAG_METDEF));  /* not constructable: objlit getset, objlit method def */\n\n\t/*\n\t *  Parse inner function\n\t */\n\n\tduk__parse_func_like_raw(comp_ctx, flags);  /* pushes function template */\n\n\t/* prev_token.start_offset points to the closing brace here; when skipping\n\t * we're going to reparse the closing brace to ensure semicolon insertion\n\t * etc work as expected.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"after func: prev_tok.start_offset=%ld, curr_tok.start_offset=%ld\",\n\t                     (long) comp_ctx->prev_token.start_offset, (long) comp_ctx->curr_token.start_offset));\n\tDUK_ASSERT(comp_ctx->lex.input[comp_ctx->prev_token.start_offset] == (duk_uint8_t) DUK_ASC_RCURLY);\n\n\t/* XXX: append primitive */\n\tDUK_ASSERT(duk_get_length(thr, old_func.funcs_idx) == (duk_size_t) (old_func.fnum_next * 3));\n\tfnum = old_func.fnum_next++;\n\n\tif (fnum > DUK__MAX_FUNCS) {\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_FUNC_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* array writes autoincrement length */\n\t(void) duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3));\n\tduk_push_size_t(thr, comp_ctx->prev_token.start_offset);\n\t(void) duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 1));\n\tduk_push_int(thr, comp_ctx->prev_token.start_line);\n\t(void) duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 2));\n\n\t/*\n\t *  Cleanup: restore original function, restore valstack state.\n\t *\n\t *  Function declaration handling needs the function name to be pushed\n\t *  on the value stack.\n\t */\n\n\tif (flags & DUK__FUNC_FLAG_PUSHNAME_PASS1) {\n\t\tDUK_ASSERT(comp_ctx->curr_func.h_name != NULL);\n\t\tduk_push_hstring(thr, comp_ctx->curr_func.h_name);\n\t\tduk_replace(thr, entry_top);\n\t\tduk_set_top(thr, entry_top + 1);\n\t} else {\n\t\tduk_set_top(thr, entry_top);\n\t}\n\tduk_memcpy((void *) &comp_ctx->curr_func, (void *) &old_func, sizeof(duk_compiler_func));\n\n\treturn fnum;\n}\n\n/*\n *  Compile input string into an executable function template without\n *  arguments.\n *\n *  The string is parsed as the \"Program\" production of ECMAScript E5.\n *  Compilation context can be either global code or eval code (see E5\n *  Sections 14 and 15.1.2.1).\n *\n *  Input stack:  [ ... filename ]\n *  Output stack: [ ... func_template ]\n */\n\n/* XXX: source code property */\n\nDUK_LOCAL duk_ret_t duk__js_compile_raw(duk_hthread *thr, void *udata) {\n\tduk_hstring *h_filename;\n\tduk__compiler_stkstate *comp_stk;\n\tduk_compiler_ctx *comp_ctx;\n\tduk_lexer_point *lex_pt;\n\tduk_compiler_func *func;\n\tduk_idx_t entry_top;\n\tduk_bool_t is_strict;\n\tduk_bool_t is_eval;\n\tduk_bool_t is_funcexpr;\n\tduk_small_uint_t flags;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(udata != NULL);\n\n\t/*\n\t *  Arguments check\n\t */\n\n\tentry_top = duk_get_top(thr);\n\tDUK_ASSERT(entry_top >= 1);\n\n\tcomp_stk = (duk__compiler_stkstate *) udata;\n\tcomp_ctx = &comp_stk->comp_ctx_alloc;\n\tlex_pt = &comp_stk->lex_pt_alloc;\n\tDUK_ASSERT(comp_ctx != NULL);\n\tDUK_ASSERT(lex_pt != NULL);\n\n\tflags = comp_stk->flags;\n\tis_eval = (flags & DUK_COMPILE_EVAL ? 1 : 0);\n\tis_strict = (flags & DUK_COMPILE_STRICT ? 1 : 0);\n\tis_funcexpr = (flags & DUK_COMPILE_FUNCEXPR ? 1 : 0);\n\n\th_filename = duk_get_hstring(thr, -1);  /* may be undefined */\n\n\t/*\n\t *  Init compiler and lexer contexts\n\t */\n\n\tfunc = &comp_ctx->curr_func;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tcomp_ctx->thr = NULL;\n\tcomp_ctx->h_filename = NULL;\n\tcomp_ctx->prev_token.str1 = NULL;\n\tcomp_ctx->prev_token.str2 = NULL;\n\tcomp_ctx->curr_token.str1 = NULL;\n\tcomp_ctx->curr_token.str2 = NULL;\n#endif\n\n\tduk_require_stack(thr, DUK__COMPILE_ENTRY_SLOTS);\n\n\tduk_push_dynamic_buffer(thr, 0);       /* entry_top + 0 */\n\tduk_push_undefined(thr);               /* entry_top + 1 */\n\tduk_push_undefined(thr);               /* entry_top + 2 */\n\tduk_push_undefined(thr);               /* entry_top + 3 */\n\tduk_push_undefined(thr);               /* entry_top + 4 */\n\n\tcomp_ctx->thr = thr;\n\tcomp_ctx->h_filename = h_filename;\n\tcomp_ctx->tok11_idx = entry_top + 1;\n\tcomp_ctx->tok12_idx = entry_top + 2;\n\tcomp_ctx->tok21_idx = entry_top + 3;\n\tcomp_ctx->tok22_idx = entry_top + 4;\n\tcomp_ctx->recursion_limit = DUK_USE_COMPILER_RECLIMIT;\n\n\t/* comp_ctx->lex has been pre-initialized by caller: it has been\n\t * zeroed and input/input_length has been set.\n\t */\n\tcomp_ctx->lex.thr = thr;\n\t/* comp_ctx->lex.input and comp_ctx->lex.input_length filled by caller */\n\tcomp_ctx->lex.slot1_idx = comp_ctx->tok11_idx;\n\tcomp_ctx->lex.slot2_idx = comp_ctx->tok12_idx;\n\tcomp_ctx->lex.buf_idx = entry_top + 0;\n\tcomp_ctx->lex.buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, entry_top + 0);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(comp_ctx->lex.buf) && !DUK_HBUFFER_HAS_EXTERNAL(comp_ctx->lex.buf));\n\tcomp_ctx->lex.token_limit = DUK_COMPILER_TOKEN_LIMIT;\n\n\tlex_pt->offset = 0;\n\tlex_pt->line = 1;\n\tDUK_LEXER_SETPOINT(&comp_ctx->lex, lex_pt);    /* fills window */\n\tcomp_ctx->curr_token.start_line = 0;  /* needed for line number tracking (becomes prev_token.start_line) */\n\n\t/*\n\t *  Initialize function state for a zero-argument function\n\t */\n\n\tduk__init_func_valstack_slots(comp_ctx);\n\tDUK_ASSERT(func->num_formals == 0);\n\n\tif (is_funcexpr) {\n\t\t/* Name will be filled from function expression, not by caller.\n\t\t * This case is used by Function constructor and duk_compile()\n\t\t * API with the DUK_COMPILE_FUNCTION option.\n\t\t */\n\t\tDUK_ASSERT(func->h_name == NULL);\n\t} else {\n\t\tduk_push_hstring_stridx(thr, (is_eval ? DUK_STRIDX_EVAL :\n\t\t                                        DUK_STRIDX_GLOBAL));\n\t\tfunc->h_name = duk_get_hstring(thr, -1);\n\t}\n\n\t/*\n\t *  Parse a function body or a function-like expression, depending\n\t *  on flags.\n\t */\n\n\tDUK_ASSERT(func->is_setget == 0);\n\tfunc->is_strict = (duk_uint8_t) is_strict;\n\tDUK_ASSERT(func->is_notail == 0);\n\n\tif (is_funcexpr) {\n\t\tfunc->is_function = 1;\n\t\tDUK_ASSERT(func->is_eval == 0);\n\t\tDUK_ASSERT(func->is_global == 0);\n\t\tfunc->is_namebinding = 1;\n\t\tfunc->is_constructable = 1;\n\n\t\tduk__advance(comp_ctx);  /* init 'curr_token' */\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_FUNCTION);\n\t\t(void) duk__parse_func_like_raw(comp_ctx, 0 /*flags*/);\n\t} else {\n\t\tDUK_ASSERT(func->is_function == 0);\n\t\tDUK_ASSERT(is_eval == 0 || is_eval == 1);\n\t\tfunc->is_eval = (duk_uint8_t) is_eval;\n\t\tfunc->is_global = (duk_uint8_t) !is_eval;\n\t\tDUK_ASSERT(func->is_namebinding == 0);\n\t\tDUK_ASSERT(func->is_constructable == 0);\n\n\t\tduk__parse_func_body(comp_ctx,\n\t\t                     1,             /* expect_eof */\n\t\t                     1,             /* implicit_return_value */\n\t\t                     1,             /* regexp_after (does not matter) */\n\t\t                     -1);           /* expect_token */\n\t}\n\n\t/*\n\t *  Convert duk_compiler_func to a function template\n\t */\n\n\tduk__convert_to_func_template(comp_ctx);\n\n\t/*\n\t *  Wrapping duk_safe_call() will mangle the stack, just return stack top\n\t */\n\n\t/* [ ... filename (temps) func ] */\n\n\treturn 1;\n}\n\nDUK_INTERNAL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer, duk_size_t src_length, duk_small_uint_t flags) {\n\tduk__compiler_stkstate comp_stk;\n\tduk_compiler_ctx *prev_ctx;\n\tduk_ret_t safe_rc;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(src_buffer != NULL);\n\n\t/* preinitialize lexer state partially */\n\tduk_memzero(&comp_stk, sizeof(comp_stk));\n\tcomp_stk.flags = flags;\n\tDUK_LEXER_INITCTX(&comp_stk.comp_ctx_alloc.lex);\n\tcomp_stk.comp_ctx_alloc.lex.input = src_buffer;\n\tcomp_stk.comp_ctx_alloc.lex.input_length = src_length;\n\tcomp_stk.comp_ctx_alloc.lex.flags = flags;  /* Forward flags directly for now. */\n\n\t/* [ ... filename ] */\n\n\tprev_ctx = thr->compile_ctx;\n\tthr->compile_ctx = &comp_stk.comp_ctx_alloc;  /* for duk_error_augment.c */\n\tsafe_rc = duk_safe_call(thr, duk__js_compile_raw, (void *) &comp_stk /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\tthr->compile_ctx = prev_ctx;  /* must restore reliably before returning */\n\n\tif (safe_rc != DUK_EXEC_SUCCESS) {\n\t\tDUK_D(DUK_DPRINT(\"compilation failed: %!T\", duk_get_tval(thr, -1)));\n\t\t(void) duk_throw(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* [ ... template ] */\n}\n\n/* automatic undefs */\n#undef DUK__ALLOCTEMP\n#undef DUK__ALLOCTEMPS\n#undef DUK__ALLOW_AUTO_SEMI_ALWAYS\n#undef DUK__BC_INITIAL_INSTS\n#undef DUK__BP_ADDITIVE\n#undef DUK__BP_ASSIGNMENT\n#undef DUK__BP_BAND\n#undef DUK__BP_BOR\n#undef DUK__BP_BXOR\n#undef DUK__BP_CALL\n#undef DUK__BP_CLOSING\n#undef DUK__BP_COMMA\n#undef DUK__BP_CONDITIONAL\n#undef DUK__BP_EOF\n#undef DUK__BP_EQUALITY\n#undef DUK__BP_EXPONENTIATION\n#undef DUK__BP_FOR_EXPR\n#undef DUK__BP_INVALID\n#undef DUK__BP_LAND\n#undef DUK__BP_LOR\n#undef DUK__BP_MEMBER\n#undef DUK__BP_MULTIPLICATIVE\n#undef DUK__BP_POSTFIX\n#undef DUK__BP_RELATIONAL\n#undef DUK__BP_SHIFT\n#undef DUK__COMPILE_ENTRY_SLOTS\n#undef DUK__CONST_MARKER\n#undef DUK__DUMP_ISPEC\n#undef DUK__DUMP_IVALUE\n#undef DUK__EMIT_FLAG_A_IS_SOURCE\n#undef DUK__EMIT_FLAG_BC_REGCONST\n#undef DUK__EMIT_FLAG_B_IS_TARGET\n#undef DUK__EMIT_FLAG_C_IS_TARGET\n#undef DUK__EMIT_FLAG_NO_SHUFFLE_A\n#undef DUK__EMIT_FLAG_NO_SHUFFLE_B\n#undef DUK__EMIT_FLAG_NO_SHUFFLE_C\n#undef DUK__EMIT_FLAG_RESERVE_JUMPSLOT\n#undef DUK__EXPR_FLAG_ALLOW_EMPTY\n#undef DUK__EXPR_FLAG_REJECT_IN\n#undef DUK__EXPR_FLAG_REQUIRE_INIT\n#undef DUK__EXPR_RBP_MASK\n#undef DUK__FUNCTION_BODY_REQUIRE_SLOTS\n#undef DUK__FUNCTION_INIT_REQUIRE_SLOTS\n#undef DUK__FUNC_FLAG_DECL\n#undef DUK__FUNC_FLAG_GETSET\n#undef DUK__FUNC_FLAG_METDEF\n#undef DUK__FUNC_FLAG_PUSHNAME_PASS1\n#undef DUK__FUNC_FLAG_USE_PREVTOKEN\n#undef DUK__GETCONST_MAX_CONSTS_CHECK\n#undef DUK__GETTEMP\n#undef DUK__HAS_TERM\n#undef DUK__HAS_VAL\n#undef DUK__ISCONST\n#undef DUK__ISREG\n#undef DUK__ISREG_NOTTEMP\n#undef DUK__ISREG_TEMP\n#undef DUK__IS_TERMINAL\n#undef DUK__IVAL_FLAG_ALLOW_CONST\n#undef DUK__IVAL_FLAG_REQUIRE_SHORT\n#undef DUK__IVAL_FLAG_REQUIRE_TEMP\n#undef DUK__MAX_ARRAY_INIT_VALUES\n#undef DUK__MAX_CONSTS\n#undef DUK__MAX_FUNCS\n#undef DUK__MAX_OBJECT_INIT_PAIRS\n#undef DUK__MAX_TEMPS\n#undef DUK__MK_LBP\n#undef DUK__MK_LBP_FLAGS\n#undef DUK__OBJ_LIT_KEY_GET\n#undef DUK__OBJ_LIT_KEY_PLAIN\n#undef DUK__OBJ_LIT_KEY_SET\n#undef DUK__PARSE_EXPR_SLOTS\n#undef DUK__PARSE_STATEMENTS_SLOTS\n#undef DUK__RECURSION_DECREASE\n#undef DUK__RECURSION_INCREASE\n#undef DUK__REMOVECONST\n#undef DUK__SETTEMP\n#undef DUK__SETTEMP_CHECKMAX\n#undef DUK__STILL_PROLOGUE\n#undef DUK__TOKEN_LBP_BP_MASK\n#undef DUK__TOKEN_LBP_FLAG_NO_REGEXP\n#undef DUK__TOKEN_LBP_FLAG_TERMINATES\n#undef DUK__TOKEN_LBP_FLAG_UNUSED\n#undef DUK__TOKEN_LBP_GET_BP\n#line 1 \"duk_js_executor.c\"\n/*\n *  ECMAScript bytecode executor.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Local declarations.\n */\n\nDUK_LOCAL_DECL void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, duk_activation *entry_act);\n\n/*\n *  Misc helpers.\n */\n\n/* Forced inline declaration, only applied for performance oriented build. */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n#define DUK__INLINE_PERF\n#define DUK__NOINLINE_PERF\n#else\n#define DUK__INLINE_PERF DUK_ALWAYS_INLINE\n#define DUK__NOINLINE_PERF DUK_NOINLINE\n#endif\n\n/* Replace value stack top to value at 'tv_ptr'.  Optimize for\n * performance by only applying the net refcount change.\n */\n#define DUK__REPLACE_TO_TVPTR(thr,tv_ptr) do { \\\n\t\tduk_hthread *duk__thr; \\\n\t\tduk_tval *duk__tvsrc; \\\n\t\tduk_tval *duk__tvdst; \\\n\t\tduk_tval duk__tvtmp; \\\n\t\tduk__thr = (thr); \\\n\t\tduk__tvsrc = DUK_GET_TVAL_NEGIDX(duk__thr, -1); \\\n\t\tduk__tvdst = (tv_ptr); \\\n\t\tDUK_TVAL_SET_TVAL(&duk__tvtmp, duk__tvdst); \\\n\t\tDUK_TVAL_SET_TVAL(duk__tvdst, duk__tvsrc); \\\n\t\tDUK_TVAL_SET_UNDEFINED(duk__tvsrc);  /* value stack init policy */ \\\n\t\tduk__thr->valstack_top = duk__tvsrc; \\\n\t\tDUK_TVAL_DECREF(duk__thr, &duk__tvtmp); \\\n\t} while (0)\n\n/* XXX: candidate of being an internal shared API call */\n#if 0  /* unused */\nDUK_LOCAL void duk__push_tvals_incref_only(duk_hthread *thr, duk_tval *tv_src, duk_small_uint_fast_t count) {\n\tduk_tval *tv_dst;\n\tduk_size_t copy_size;\n\tduk_size_t i;\n\n\ttv_dst = thr->valstack_top;\n\tcopy_size = sizeof(duk_tval) * count;\n\tduk_memcpy((void *) tv_dst, (const void *) tv_src, copy_size);\n\tfor (i = 0; i < count; i++) {\n\t\tDUK_TVAL_INCREF(thr, tv_dst);\n\t\ttv_dst++;\n\t}\n\tthr->valstack_top = tv_dst;\n}\n#endif\n\n/*\n *  Arithmetic, binary, and logical helpers.\n *\n *  Note: there is no opcode for logical AND or logical OR; this is on\n *  purpose, because the evalution order semantics for them make such\n *  opcodes pretty pointless: short circuiting means they are most\n *  comfortably implemented as jumps.  However, a logical NOT opcode\n *  is useful.\n *\n *  Note: careful with duk_tval pointers here: they are potentially\n *  invalidated by any DECREF and almost any API call.  It's still\n *  preferable to work without making a copy but that's not always\n *  possible.\n */\n\nDUK_LOCAL DUK__INLINE_PERF duk_double_t duk__compute_mod(duk_double_t d1, duk_double_t d2) {\n\treturn (duk_double_t) duk_js_arith_mod((double) d1, (double) d2);\n}\n\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\nDUK_LOCAL DUK__INLINE_PERF duk_double_t duk__compute_exp(duk_double_t d1, duk_double_t d2) {\n\treturn (duk_double_t) duk_js_arith_pow((double) d1, (double) d2);\n}\n#endif\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_add(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_fast_t idx_z) {\n\t/*\n\t *  Addition operator is different from other arithmetic\n\t *  operations in that it also provides string concatenation.\n\t *  Hence it is implemented separately.\n\t *\n\t *  There is a fast path for number addition.  Other cases go\n\t *  through potentially multiple coercions as described in the\n\t *  E5 specification.  It may be possible to reduce the number\n\t *  of coercions, but this must be done carefully to preserve\n\t *  the exact semantics.\n\t *\n\t *  E5 Section 11.6.1.\n\t *\n\t *  Custom types also have special behavior implemented here.\n\t */\n\n\tduk_double_union du;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_x != NULL);  /* may be reg or const */\n\tDUK_ASSERT(tv_y != NULL);  /* may be reg or const */\n\tDUK_ASSERT_DISABLE(idx_z >= 0);  /* unsigned */\n\tDUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr));\n\n\t/*\n\t *  Fast paths\n\t */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\tduk_int64_t v1, v2, v3;\n\t\tduk_int32_t v3_hi;\n\t\tduk_tval *tv_z;\n\n\t\t/* Input values are signed 48-bit so we can detect overflow\n\t\t * reliably from high bits or just a comparison.\n\t\t */\n\n\t\tv1 = DUK_TVAL_GET_FASTINT(tv_x);\n\t\tv2 = DUK_TVAL_GET_FASTINT(tv_y);\n\t\tv3 = v1 + v2;\n\t\tv3_hi = (duk_int32_t) (v3 >> 32);\n\t\tif (DUK_LIKELY(v3_hi >= DUK_I64_CONSTANT(-0x8000) && v3_hi <= DUK_I64_CONSTANT(0x7fff))) {\n\t\t\ttv_z = thr->valstack_bottom + idx_z;\n\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, v3);  /* side effects */\n\t\t\treturn;\n\t\t} else {\n\t\t\t/* overflow, fall through */\n\t\t\t;\n\t\t}\n\t}\n#endif  /* DUK_USE_FASTINT */\n\n\tif (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) {\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tduk_tval *tv_z;\n#endif\n\n\t\tdu.d = DUK_TVAL_GET_NUMBER(tv_x) + DUK_TVAL_GET_NUMBER(tv_y);\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tduk_push_number(thr, du.d);  /* will NaN normalize result */\n\t\tduk_replace(thr, (duk_idx_t) idx_z);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\t\ttv_z = thr->valstack_bottom + idx_z;\n\t\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, du.d);  /* side effects */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\treturn;\n\t}\n\n\t/*\n\t *  Slow path: potentially requires function calls for coercion\n\t */\n\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\tduk_to_primitive(thr, -2, DUK_HINT_NONE);  /* side effects -> don't use tv_x, tv_y after */\n\tduk_to_primitive(thr, -1, DUK_HINT_NONE);\n\n\t/* Since Duktape 2.x plain buffers are treated like ArrayBuffer. */\n\tif (duk_is_string(thr, -2) || duk_is_string(thr, -1)) {\n\t\t/* Symbols shouldn't technically be handled here, but should\n\t\t * go into the default ToNumber() coercion path instead and\n\t\t * fail there with a TypeError.  However, there's a ToString()\n\t\t * in duk_concat_2() which also fails with TypeError so no\n\t\t * explicit check is needed.\n\t\t */\n\t\tduk_concat_2(thr);  /* [... s1 s2] -> [... s1+s2] */\n\t} else {\n\t\tduk_double_t d1, d2;\n\n\t\td1 = duk_to_number_m2(thr);\n\t\td2 = duk_to_number_m1(thr);\n\t\tDUK_ASSERT(duk_is_number(thr, -2));\n\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d1);\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d2);\n\n\t\tdu.d = d1 + d2;\n\t\tduk_pop_2_unsafe(thr);\n\t\tduk_push_number(thr, du.d);  /* will NaN normalize result */\n\t}\n\tduk_replace(thr, (duk_idx_t) idx_z);  /* side effects */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_binary_op(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_uint_fast_t idx_z, duk_small_uint_fast_t opcode) {\n\t/*\n\t *  Arithmetic operations other than '+' have number-only semantics\n\t *  and are implemented here.  The separate switch-case here means a\n\t *  \"double dispatch\" of the arithmetic opcode, but saves code space.\n\t *\n\t *  E5 Sections 11.5, 11.5.1, 11.5.2, 11.5.3, 11.6, 11.6.1, 11.6.2, 11.6.3.\n\t */\n\n\tduk_double_t d1, d2;\n\tduk_double_union du;\n\tduk_small_uint_fast_t opcode_shifted;\n#if defined(DUK_USE_FASTINT) || !defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_tval *tv_z;\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_x != NULL);  /* may be reg or const */\n\tDUK_ASSERT(tv_y != NULL);  /* may be reg or const */\n\tDUK_ASSERT_DISABLE(idx_z >= 0);  /* unsigned */\n\tDUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr));\n\n\topcode_shifted = opcode >> 2;  /* Get base opcode without reg/const modifiers. */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\tduk_int64_t v1, v2, v3;\n\t\tduk_int32_t v3_hi;\n\n\t\tv1 = DUK_TVAL_GET_FASTINT(tv_x);\n\t\tv2 = DUK_TVAL_GET_FASTINT(tv_y);\n\n\t\tswitch (opcode_shifted) {\n\t\tcase DUK_OP_SUB >> 2: {\n\t\t\tv3 = v1 - v2;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL >> 2: {\n\t\t\t/* Must ensure result is 64-bit (no overflow); a\n\t\t\t * simple and sufficient fast path is to allow only\n\t\t\t * 32-bit inputs.  Avoid zero inputs to avoid\n\t\t\t * negative zero issues (-1 * 0 = -0, for instance).\n\t\t\t */\n\t\t\tif (v1 >= DUK_I64_CONSTANT(-0x80000000) && v1 <= DUK_I64_CONSTANT(0x7fffffff) && v1 != 0 &&\n\t\t\t    v2 >= DUK_I64_CONSTANT(-0x80000000) && v2 <= DUK_I64_CONSTANT(0x7fffffff) && v2 != 0) {\n\t\t\t\tv3 = v1 * v2;\n\t\t\t} else {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV >> 2: {\n\t\t\t/* Don't allow a zero divisor.  Fast path check by\n\t\t\t * \"verifying\" with multiplication.  Also avoid zero\n\t\t\t * dividend to avoid negative zero issues (0 / -1 = -0\n\t\t\t * for instance).\n\t\t\t */\n\t\t\tif (v1 == 0 || v2 == 0) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tv3 = v1 / v2;\n\t\t\tif (v3 * v2 != v1) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD >> 2: {\n\t\t\t/* Don't allow a zero divisor.  Restrict both v1 and\n\t\t\t * v2 to positive values to avoid compiler specific\n\t\t\t * behavior.\n\t\t\t */\n\t\t\tif (v1 < 1 || v2 < 1) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tv3 = v1 % v2;\n\t\t\tDUK_ASSERT(v3 >= 0);\n\t\t\tDUK_ASSERT(v3 < v2);\n\t\t\tDUK_ASSERT(v1 - (v1 / v2) * v2 == v3);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\t/* Possible with DUK_OP_EXP. */\n\t\t\tgoto skip_fastint;\n\t\t}\n\t\t}\n\n\t\tv3_hi = (duk_int32_t) (v3 >> 32);\n\t\tif (DUK_LIKELY(v3_hi >= DUK_I64_CONSTANT(-0x8000) && v3_hi <= DUK_I64_CONSTANT(0x7fff))) {\n\t\t\ttv_z = thr->valstack_bottom + idx_z;\n\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, v3);  /* side effects */\n\t\t\treturn;\n\t\t}\n\t\t/* fall through if overflow etc */\n\t}\n skip_fastint:\n#endif  /* DUK_USE_FASTINT */\n\n\tif (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) {\n\t\t/* fast path */\n\t\td1 = DUK_TVAL_GET_NUMBER(tv_x);\n\t\td2 = DUK_TVAL_GET_NUMBER(tv_y);\n\t} else {\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\td1 = duk_to_number_m2(thr);  /* side effects */\n\t\td2 = duk_to_number_m1(thr);\n\t\tDUK_ASSERT(duk_is_number(thr, -2));\n\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d1);\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d2);\n\t\tduk_pop_2_unsafe(thr);\n\t}\n\n\tswitch (opcode_shifted) {\n\tcase DUK_OP_SUB >> 2: {\n\t\tdu.d = d1 - d2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_MUL >> 2: {\n\t\tdu.d = d1 * d2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_DIV >> 2: {\n\t\t/* Division-by-zero is undefined behavior, so\n\t\t * rely on a helper.\n\t\t */\n\t\tdu.d = duk_double_div(d1, d2);\n\t\tbreak;\n\t}\n\tcase DUK_OP_MOD >> 2: {\n\t\tdu.d = duk__compute_mod(d1, d2);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\tcase DUK_OP_EXP >> 2: {\n\t\tdu.d = duk__compute_exp(d1, d2);\n\t\tbreak;\n\t}\n#endif\n\tdefault: {\n\t\tDUK_UNREACHABLE();\n\t\tdu.d = DUK_DOUBLE_NAN;  /* should not happen */\n\t\tbreak;\n\t}\n\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_push_number(thr, du.d);  /* will NaN normalize result */\n\tduk_replace(thr, (duk_idx_t) idx_z);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t/* important to use normalized NaN with 8-byte tagged types */\n\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\ttv_z = thr->valstack_bottom + idx_z;\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, du.d);  /* side effects */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_bitwise_binary_op(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_fast_t idx_z, duk_small_uint_fast_t opcode) {\n\t/*\n\t *  Binary bitwise operations use different coercions (ToInt32, ToUint32)\n\t *  depending on the operation.  We coerce the arguments first using\n\t *  ToInt32(), and then cast to an 32-bit value if necessary.  Note that\n\t *  such casts must be correct even if there is no native 32-bit type\n\t *  (e.g., duk_int32_t and duk_uint32_t are 64-bit).\n\t *\n\t *  E5 Sections 11.10, 11.7.1, 11.7.2, 11.7.3\n\t */\n\n\tduk_int32_t i1, i2, i3;\n\tduk_uint32_t u1, u2, u3;\n#if defined(DUK_USE_FASTINT)\n\tduk_int64_t fi3;\n#else\n\tduk_double_t d3;\n#endif\n\tduk_small_uint_fast_t opcode_shifted;\n#if defined(DUK_USE_FASTINT) || !defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_tval *tv_z;\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_x != NULL);  /* may be reg or const */\n\tDUK_ASSERT(tv_y != NULL);  /* may be reg or const */\n\tDUK_ASSERT_DISABLE(idx_z >= 0);  /* unsigned */\n\tDUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr));\n\n\topcode_shifted = opcode >> 2;  /* Get base opcode without reg/const modifiers. */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\ti1 = (duk_int32_t) DUK_TVAL_GET_FASTINT_I32(tv_x);\n\t\ti2 = (duk_int32_t) DUK_TVAL_GET_FASTINT_I32(tv_y);\n\t}\n\telse\n#endif  /* DUK_USE_FASTINT */\n\t{\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\ti1 = duk_to_int32(thr, -2);\n\t\ti2 = duk_to_int32(thr, -1);\n\t\tduk_pop_2_unsafe(thr);\n\t}\n\n\tswitch (opcode_shifted) {\n\tcase DUK_OP_BAND >> 2: {\n\t\ti3 = i1 & i2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_BOR >> 2: {\n\t\ti3 = i1 | i2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_BXOR >> 2: {\n\t\ti3 = i1 ^ i2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_BASL >> 2: {\n\t\t/* Signed shift, named \"arithmetic\" (asl) because the result\n\t\t * is signed, e.g. 4294967295 << 1 -> -2.  Note that result\n\t\t * must be masked.\n\t\t */\n\n\t\tu2 = ((duk_uint32_t) i2) & 0xffffffffUL;\n\t\ti3 = (duk_int32_t) (((duk_uint32_t) i1) << (u2 & 0x1fUL));  /* E5 Section 11.7.1, steps 7 and 8 */\n\t\ti3 = i3 & ((duk_int32_t) 0xffffffffUL);                     /* Note: left shift, should mask */\n\t\tbreak;\n\t}\n\tcase DUK_OP_BASR >> 2: {\n\t\t/* signed shift */\n\n\t\tu2 = ((duk_uint32_t) i2) & 0xffffffffUL;\n\t\ti3 = i1 >> (u2 & 0x1fUL);                      /* E5 Section 11.7.2, steps 7 and 8 */\n\t\tbreak;\n\t}\n\tcase DUK_OP_BLSR >> 2: {\n\t\t/* unsigned shift */\n\n\t\tu1 = ((duk_uint32_t) i1) & 0xffffffffUL;\n\t\tu2 = ((duk_uint32_t) i2) & 0xffffffffUL;\n\n\t\t/* special result value handling */\n\t\tu3 = u1 >> (u2 & 0x1fUL);     /* E5 Section 11.7.2, steps 7 and 8 */\n#if defined(DUK_USE_FASTINT)\n\t\tfi3 = (duk_int64_t) u3;\n\t\tgoto fastint_result_set;\n#else\n\t\td3 = (duk_double_t) u3;\n\t\tgoto result_set;\n#endif\n\t}\n\tdefault: {\n\t\tDUK_UNREACHABLE();\n\t\ti3 = 0;  /* should not happen */\n\t\tbreak;\n\t}\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\t/* Result is always fastint compatible. */\n\t/* XXX: Set 32-bit result (but must then handle signed and\n\t * unsigned results separately).\n\t */\n\tfi3 = (duk_int64_t) i3;\n\n fastint_result_set:\n\ttv_z = thr->valstack_bottom + idx_z;\n\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, fi3);  /* side effects */\n#else  /* DUK_USE_FASTINT */\n\td3 = (duk_double_t) i3;\n\n result_set:\n\tDUK_ASSERT(!DUK_ISNAN(d3));            /* 'd3' is never NaN, so no need to normalize */\n\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d3);   /* always normalized */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_push_number(thr, d3);  /* would NaN normalize result, but unnecessary */\n\tduk_replace(thr, (duk_idx_t) idx_z);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\ttv_z = thr->valstack_bottom + idx_z;\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, d3);  /* side effects */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n#endif  /* DUK_USE_FASTINT */\n}\n\n/* In-place unary operation. */\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_unary_op(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst, duk_small_uint_fast_t opcode) {\n\t/*\n\t *  Arithmetic operations other than '+' have number-only semantics\n\t *  and are implemented here.  The separate switch-case here means a\n\t *  \"double dispatch\" of the arithmetic opcode, but saves code space.\n\t *\n\t *  E5 Sections 11.5, 11.5.1, 11.5.2, 11.5.3, 11.6, 11.6.1, 11.6.2, 11.6.3.\n\t */\n\n\tduk_tval *tv;\n\tduk_double_t d1;\n\tduk_double_union du;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(opcode == DUK_OP_UNM || opcode == DUK_OP_UNP);\n\tDUK_ASSERT_DISABLE(idx_src >= 0);\n\tDUK_ASSERT_DISABLE(idx_dst >= 0);\n\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tduk_int64_t v1, v2;\n\n\t\tv1 = DUK_TVAL_GET_FASTINT(tv);\n\t\tif (opcode == DUK_OP_UNM) {\n\t\t\t/* The smallest fastint is no longer 48-bit when\n\t\t\t * negated.  Positive zero becames negative zero\n\t\t\t * (cannot be represented) when negated.\n\t\t\t */\n\t\t\tif (DUK_LIKELY(v1 != DUK_FASTINT_MIN && v1 != 0)) {\n\t\t\t\tv2 = -v1;\n\t\t\t\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv, v2);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\t/* ToNumber() for a fastint is a no-op. */\n\t\t\tDUK_ASSERT(opcode == DUK_OP_UNP);\n\t\t\tv2 = v1;\n\t\t\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv, v2);\n\t\t\treturn;\n\t\t}\n\t\t/* fall through if overflow etc */\n\t}\n#endif  /* DUK_USE_FASTINT */\n\n\tif (DUK_TVAL_IS_NUMBER(tv)) {\n\t\td1 = DUK_TVAL_GET_NUMBER(tv);\n\t} else {\n\t\td1 = duk_to_number_tval(thr, tv);  /* side effects */\n\t}\n\n\tif (opcode == DUK_OP_UNP) {\n\t\t/* ToNumber() for a double is a no-op, but unary plus is\n\t\t * used to force a fastint check so do that here.\n\t\t */\n\t\tdu.d = d1;\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n#if defined(DUK_USE_FASTINT)\n\t\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t\tDUK_TVAL_SET_NUMBER_CHKFAST_UPDREF(thr, tv, du.d);  /* always 'fast', i.e. inlined */\n\t\treturn;\n#endif\n\t} else {\n\t\tDUK_ASSERT(opcode == DUK_OP_UNM);\n\t\tdu.d = -d1;\n\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);  /* mandatory if du.d is a NaN */\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\t}\n\n\t/* XXX: size optimize: push+replace? */\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv, du.d);\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_bitwise_not(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst) {\n\t/*\n\t *  E5 Section 11.4.8\n\t */\n\n\tduk_tval *tv;\n\tduk_int32_t i1, i2;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT_DISABLE(idx_src >= 0);\n\tDUK_ASSERT_DISABLE(idx_dst >= 0);\n\tDUK_ASSERT((duk_uint_t) idx_src < (duk_uint_t) duk_get_top(thr));\n\tDUK_ASSERT((duk_uint_t) idx_dst < (duk_uint_t) duk_get_top(thr));\n\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\ti1 = (duk_int32_t) DUK_TVAL_GET_FASTINT_I32(tv);\n\t}\n\telse\n#endif  /* DUK_USE_FASTINT */\n\t{\n\t\tduk_push_tval(thr, tv);\n\t\ti1 = duk_to_int32(thr, -1);  /* side effects */\n\t\tduk_pop_unsafe(thr);\n\t}\n\n\t/* Result is always fastint compatible. */\n\ti2 = ~i1;\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\tDUK_TVAL_SET_I32_UPDREF(thr, tv, i2);  /* side effects */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_logical_not(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst) {\n\t/*\n\t *  E5 Section 11.4.9\n\t */\n\n\tduk_tval *tv;\n\tduk_bool_t res;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT_DISABLE(idx_src >= 0);\n\tDUK_ASSERT_DISABLE(idx_dst >= 0);\n\tDUK_ASSERT((duk_uint_t) idx_src < (duk_uint_t) duk_get_top(thr));\n\tDUK_ASSERT((duk_uint_t) idx_dst < (duk_uint_t) duk_get_top(thr));\n\n\t/* ToBoolean() does not require any operations with side effects so\n\t * we can do it efficiently.  For footprint it would be better to use\n\t * duk_js_toboolean() and then push+replace to the result slot.\n\t */\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src);\n\tres = duk_js_toboolean(tv);  /* does not modify 'tv' */\n\tDUK_ASSERT(res == 0 || res == 1);\n\tres ^= 1;\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t/* XXX: size optimize: push+replace? */\n\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv, res);  /* side effects */\n}\n\n/* XXX: size optimized variant */\nDUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_reg_helper(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_small_uint_t op) {\n\tduk_double_t x, y, z;\n\n\t/* Two lowest bits of opcode are used to distinguish\n\t * variants.  Bit 0 = inc(0)/dec(1), bit 1 = pre(0)/post(1).\n\t */\n\tDUK_ASSERT((DUK_OP_PREINCR & 0x03) == 0x00);\n\tDUK_ASSERT((DUK_OP_PREDECR & 0x03) == 0x01);\n\tDUK_ASSERT((DUK_OP_POSTINCR & 0x03) == 0x02);\n\tDUK_ASSERT((DUK_OP_POSTDECR & 0x03) == 0x03);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_src)) {\n\t\tduk_int64_t x_fi, y_fi, z_fi;\n\t\tx_fi = DUK_TVAL_GET_FASTINT(tv_src);\n\t\tif (op & 0x01) {\n\t\t\tif (DUK_UNLIKELY(x_fi == DUK_FASTINT_MIN)) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\ty_fi = x_fi - 1;\n\t\t} else {\n\t\t\tif (DUK_UNLIKELY(x_fi == DUK_FASTINT_MAX)) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\ty_fi = x_fi + 1;\n\t\t}\n\n\t\tDUK_TVAL_SET_FASTINT(tv_src, y_fi);  /* no need for refcount update */\n\n\t\tz_fi = (op & 0x02) ? x_fi : y_fi;\n\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_dst, z_fi);  /* side effects */\n\t\treturn;\n\t}\n skip_fastint:\n#endif\n\tif (DUK_TVAL_IS_NUMBER(tv_src)) {\n\t\t/* Fast path for the case where the register\n\t\t * is a number (e.g. loop counter).\n\t\t */\n\n\t\tx = DUK_TVAL_GET_NUMBER(tv_src);\n\t\tif (op & 0x01) {\n\t\t\ty = x - 1.0;\n\t\t} else {\n\t\t\ty = x + 1.0;\n\t\t}\n\n\t\tDUK_TVAL_SET_NUMBER(tv_src, y);  /* no need for refcount update */\n\t} else {\n\t\t/* Preserve duk_tval pointer(s) across a potential valstack\n\t\t * resize by converting them into offsets temporarily.\n\t\t */\n\t\tduk_idx_t bc;\n\t\tduk_size_t off_dst;\n\n\t\toff_dst = (duk_size_t) ((duk_uint8_t *) tv_dst - (duk_uint8_t *) thr->valstack_bottom);\n\t\tbc = (duk_idx_t) (tv_src - thr->valstack_bottom);  /* XXX: pass index explicitly? */\n\t\ttv_src = NULL;  /* no longer referenced */\n\n\t\tx = duk_to_number(thr, bc);\n\t\tif (op & 0x01) {\n\t\t\ty = x - 1.0;\n\t\t} else {\n\t\t\ty = x + 1.0;\n\t\t}\n\n\t\tduk_push_number(thr, y);\n\t\tduk_replace(thr, bc);\n\n\t\ttv_dst = (duk_tval *) (void *) (((duk_uint8_t *) thr->valstack_bottom) + off_dst);\n\t}\n\n\tz = (op & 0x02) ? x : y;\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_dst, z);  /* side effects */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_var_helper(duk_hthread *thr, duk_small_uint_t idx_dst, duk_tval *tv_id, duk_small_uint_t op, duk_small_uint_t is_strict) {\n\tduk_activation *act;\n\tduk_double_t x, y;\n\tduk_hstring *name;\n\n\t/* XXX: The pre/post inc/dec for an identifier lookup is\n\t * missing the important fast path where the identifier\n\t * has a storage location e.g. in a scope object so that\n\t * it can be updated in-place.  In particular, the case\n\t * where the identifier has a storage location AND the\n\t * previous value is a number should be optimized because\n\t * it's side effect free.\n\t */\n\n\t/* Two lowest bits of opcode are used to distinguish\n\t * variants.  Bit 0 = inc(0)/dec(1), bit 1 = pre(0)/post(1).\n\t */\n\tDUK_ASSERT((DUK_OP_PREINCV & 0x03) == 0x00);\n\tDUK_ASSERT((DUK_OP_PREDECV & 0x03) == 0x01);\n\tDUK_ASSERT((DUK_OP_POSTINCV & 0x03) == 0x02);\n\tDUK_ASSERT((DUK_OP_POSTDECV & 0x03) == 0x03);\n\n\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_id));\n\tname = DUK_TVAL_GET_STRING(tv_id);\n\tDUK_ASSERT(name != NULL);\n\tact = thr->callstack_curr;\n\t(void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/);  /* -> [ ... val this ] */\n\n\t/* XXX: Fastint fast path would be useful here.  Also fastints\n\t * now lose their fastint status in current handling which is\n\t * not intuitive.\n\t */\n\n\tx = duk_to_number_m2(thr);\n\tif (op & 0x01) {\n\t\ty = x - 1.0;\n\t} else {\n\t\ty = x + 1.0;\n\t}\n\n\t/* [... x this] */\n\n\tif (op & 0x02) {\n\t\tduk_push_number(thr, y);  /* -> [ ... x this y ] */\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tduk_js_putvar_activation(thr, act, name, DUK_GET_TVAL_NEGIDX(thr, -1), is_strict);\n\t\tduk_pop_2_unsafe(thr);  /* -> [ ... x ] */\n\t} else {\n\t\tduk_pop_2_unsafe(thr);  /* -> [ ... ] */\n\t\tduk_push_number(thr, y);  /* -> [ ... y ] */\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tduk_js_putvar_activation(thr, act, name, DUK_GET_TVAL_NEGIDX(thr, -1), is_strict);\n\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_replace(thr, (duk_idx_t) idx_dst);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\tDUK__REPLACE_TO_TVPTR(thr, DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n}\n\n/*\n *  Longjmp and other control flow transfer for the bytecode executor.\n *\n *  The longjmp handler can handle all longjmp types: error, yield, and\n *  resume (pseudotypes are never actually thrown).\n *\n *  Error policy for longjmp: should not ordinarily throw errors; if errors\n *  occur (e.g. due to out-of-memory) they bubble outwards rather than being\n *  handled recursively.\n */\n\n#define DUK__LONGJMP_RESTART   0  /* state updated, restart bytecode execution */\n#define DUK__LONGJMP_RETHROW   1  /* exit bytecode executor by rethrowing an error to caller */\n\n#define DUK__RETHAND_RESTART   0  /* state updated, restart bytecode execution */\n#define DUK__RETHAND_FINISHED  1  /* exit bytecode execution with return value */\n\n/* XXX: optimize reconfig valstack operations so that resize, clamp, and setting\n * top are combined into one pass.\n */\n\n/* Reconfigure value stack for return to an ECMAScript function at\n * callstack top (caller unwinds).\n */\nDUK_LOCAL void duk__reconfig_valstack_ecma_return(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_hcompfunc *h_func;\n\tduk_idx_t clamp_top;\n\n\tDUK_ASSERT(thr != NULL);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act)));\n\n\t/* Clamp so that values at 'clamp_top' and above are wiped and won't\n\t * retain reachable garbage.  Then extend to 'nregs' because we're\n\t * returning to an ECMAScript function.\n\t */\n\n\th_func = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff);\n\tDUK_ASSERT(act->retval_byteoff >= act->bottom_byteoff);\n\tclamp_top = (duk_idx_t) ((act->retval_byteoff - act->bottom_byteoff + sizeof(duk_tval)) / sizeof(duk_tval));  /* +1 = one retval */\n\tduk_set_top_and_wipe(thr, h_func->nregs, clamp_top);\n\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack_end >= (duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\n\t/* XXX: a best effort shrink check would be OK here */\n}\n\n/* Reconfigure value stack for an ECMAScript catcher.  Use topmost catcher\n * in 'act'.\n */\nDUK_LOCAL void duk__reconfig_valstack_ecma_catcher(duk_hthread *thr, duk_activation *act) {\n\tduk_catcher *cat;\n\tduk_hcompfunc *h_func;\n\tduk_size_t idx_bottom;\n\tduk_idx_t clamp_top;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act)));\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\th_func = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff);\n\tidx_bottom = (duk_size_t) (thr->valstack_bottom - thr->valstack);\n\tDUK_ASSERT(cat->idx_base >= idx_bottom);\n\tclamp_top = (duk_idx_t) (cat->idx_base - idx_bottom + 2);  /* +2 = catcher value, catcher lj_type */\n\tduk_set_top_and_wipe(thr, h_func->nregs, clamp_top);\n\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack_end >= (duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\n\t/* XXX: a best effort shrink check would be OK here */\n}\n\n/* Set catcher regs: idx_base+0 = value, idx_base+1 = lj_type.\n * No side effects.\n */\nDUK_LOCAL void duk__set_catcher_regs_norz(duk_hthread *thr, duk_catcher *cat, duk_tval *tv_val_unstable, duk_small_uint_t lj_type) {\n\tduk_tval *tv1;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\n\ttv1 = thr->valstack + cat->idx_base;\n\tDUK_ASSERT(tv1 < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF_NORZ(thr, tv1, tv_val_unstable);\n\n\ttv1++;\n\tDUK_ASSERT(tv1 == thr->valstack + cat->idx_base + 1);\n\tDUK_ASSERT(tv1 < thr->valstack_top);\n\tDUK_TVAL_SET_U32_UPDREF_NORZ(thr, tv1, (duk_uint32_t) lj_type);\n}\n\nDUK_LOCAL void duk__handle_catch_part1(duk_hthread *thr, duk_tval *tv_val_unstable, duk_small_uint_t lj_type, volatile duk_bool_t *out_delayed_catch_setup) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_DD(DUK_DDPRINT(\"handle catch, part 1; act=%!A, cat=%!C\", act, act->cat));\n\n\tDUK_ASSERT(act->cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);\n\n\t/* The part1/part2 split could also be made here at the very top\n\t * of catch handling.  Value stack would be reconfigured inside\n\t * part2's protection.  Value stack reconfiguration should be free\n\t * of allocs, however.\n\t */\n\n\tduk__set_catcher_regs_norz(thr, act->cat, tv_val_unstable, lj_type);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tduk__reconfig_valstack_ecma_catcher(thr, act);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tact->curr_pc = cat->pc_base + 0;  /* +0 = catch */\n\n\t/*\n\t *  If the catch block has an automatic catch variable binding,\n\t *  we need to create a lexical environment for it which requires\n\t *  allocations.  Move out of \"error handling state\" before the\n\t *  allocations to avoid e.g. out-of-memory errors (leading to\n\t *  GH-2022 or similar).\n\t */\n\n\tif (DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"catcher has an automatic catch binding, handle in part 2\"));\n\t\t*out_delayed_catch_setup = 1;\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"catcher has no catch binding\"));\n\t}\n\n\tDUK_CAT_CLEAR_CATCH_ENABLED(cat);\n}\n\nDUK_LOCAL void duk__handle_catch_part2(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_hdecenv *new_env;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_DD(DUK_DDPRINT(\"handle catch, part 2; act=%!A, cat=%!C\", act, act->cat));\n\n\tDUK_ASSERT(act->cat != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);\n\tDUK_ASSERT(DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat));\n\tDUK_ASSERT(thr->valstack + cat->idx_base < thr->valstack_top);\n\n\t/*\n\t *  Create lexical environment for the catch clause, containing\n\t *  a binding for the caught value.\n\t *\n\t *  The binding is mutable (= writable) but not deletable.\n\t *  Step 4 for the catch production in E5 Section 12.14;\n\t *  no value is given for CreateMutableBinding 'D' argument,\n\t *  which implies the binding is not deletable.\n\t */\n\n\tif (act->lex_env == NULL) {\n\t\tDUK_ASSERT(act->var_env == NULL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"delayed environment initialization\"));\n\n\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t}\n\tDUK_ASSERT(act->lex_env != NULL);\n\tDUK_ASSERT(act->var_env != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\n\tnew_env = duk_hdecenv_alloc(thr,\n\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\tDUK_ASSERT(new_env != NULL);\n\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\tDUK_DDD(DUK_DDDPRINT(\"new_env allocated: %!iO\", (duk_heaphdr *) new_env));\n\n\t/* Note: currently the catch binding is handled without a register\n\t * binding because we don't support dynamic register bindings (they\n\t * must be fixed for an entire function).  So, there is no need to\n\t * record regbases etc.\n\t */\n\n\t/* [ ...env ] */\n\n\tDUK_ASSERT(cat->h_varname != NULL);\n\tduk_push_hstring(thr, cat->h_varname);\n\tDUK_ASSERT(thr->valstack + cat->idx_base < thr->valstack_top);\n\tduk_push_tval(thr, thr->valstack + cat->idx_base);\n\tduk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_W);  /* writable, not configurable */\n\n\t/* [ ... env ] */\n\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, act->lex_env);\n\tact->lex_env = (duk_hobject *) new_env;\n\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env);  /* reachable through activation */\n\t/* Net refcount change to act->lex_env is 0: incref for new_env's\n\t * prototype, decref for act->lex_env overwrite.\n\t */\n\n\tDUK_CAT_SET_LEXENV_ACTIVE(cat);\n\n\tduk_pop_unsafe(thr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"new_env finished: %!iO\", (duk_heaphdr *) new_env));\n}\n\nDUK_LOCAL void duk__handle_finally(duk_hthread *thr, duk_tval *tv_val_unstable, duk_small_uint_t lj_type) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(act->cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);\n\n\tduk__set_catcher_regs_norz(thr, act->cat, tv_val_unstable, lj_type);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tduk__reconfig_valstack_ecma_catcher(thr, act);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tact->curr_pc = cat->pc_base + 1;  /* +1 = finally */\n\n\tDUK_CAT_CLEAR_FINALLY_ENABLED(cat);\n}\n\nDUK_LOCAL void duk__handle_label(duk_hthread *thr, duk_small_uint_t lj_type) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(DUK_ACT_GET_FUNC(act)));\n\n\t/* +0 = break, +1 = continue */\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_LABEL);\n\n\tact->curr_pc = cat->pc_base + (lj_type == DUK_LJ_TYPE_CONTINUE ? 1 : 0);\n\n\t/* valstack should not need changes */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) ==\n\t           (duk_size_t) ((duk_hcompfunc *) DUK_ACT_GET_FUNC(act))->nregs);\n#endif\n}\n\n/* Called for handling both a longjmp() with type DUK_LJ_TYPE_YIELD and\n * when a RETURN opcode terminates a thread and yields to the resumer.\n * Caller unwinds so that top of callstack is the activation we return to.\n */\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_LOCAL void duk__handle_yield(duk_hthread *thr, duk_hthread *resumer, duk_tval *tv_val_unstable) {\n\tduk_activation *act_resumer;\n\tduk_tval *tv1;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(resumer != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\tact_resumer = resumer->callstack_curr;\n\tDUK_ASSERT(act_resumer != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act_resumer) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act_resumer)));  /* resume caller must be an ECMAScript func */\n\n\ttv1 = (duk_tval *) (void *) ((duk_uint8_t *) resumer->valstack + act_resumer->retval_byteoff);  /* return value from Duktape.Thread.resume() */\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv_val_unstable);  /* side effects */  /* XXX: avoid side effects */\n\n\tduk__reconfig_valstack_ecma_return(resumer);\n\n\t/* caller must change active thread, and set thr->resumer to NULL */\n}\n#endif  /* DUK_USE_COROUTINE_SUPPORT */\n\nDUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation *entry_act, volatile duk_bool_t *out_delayed_catch_setup) {\n\tduk_small_uint_t retval = DUK__LONGJMP_RESTART;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(entry_act != NULL);\n\n\t/* 'thr' is the current thread, as no-one resumes except us and we\n\t * switch 'thr' in that case.\n\t */\n\tDUK_ASSERT(thr == thr->heap->curr_thread);\n\n\t/*\n\t *  (Re)try handling the longjmp.\n\t *\n\t *  A longjmp handler may convert the longjmp to a different type and\n\t *  \"virtually\" rethrow by goto'ing to 'check_longjmp'.  Before the goto,\n\t *  the following must be updated:\n\t *    - the heap 'lj' state\n\t *    - 'thr' must reflect the \"throwing\" thread\n\t */\n\n check_longjmp:\n\n\tDUK_DD(DUK_DDPRINT(\"handling longjmp: type=%ld, value1=%!T, value2=%!T, iserror=%ld, top=%ld\",\n\t                   (long) thr->heap->lj.type,\n\t                   (duk_tval *) &thr->heap->lj.value1,\n\t                   (duk_tval *) &thr->heap->lj.value2,\n\t                   (long) thr->heap->lj.iserror,\n\t\t\t   (long) duk_get_top(thr)));\n\n\tswitch (thr->heap->lj.type) {\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\tcase DUK_LJ_TYPE_RESUME: {\n\t\t/*\n\t\t *  Note: lj.value1 is 'value', lj.value2 is 'resumee'.\n\t\t *  This differs from YIELD.\n\t\t */\n\n\t\tduk_tval *tv;\n\t\tduk_tval *tv2;\n\t\tduk_hthread *resumee;\n\n\t\t/* duk_bi_duk_object_yield() and duk_bi_duk_object_resume() ensure all of these are met */\n\n\t\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);                                                         /* unchanged by Duktape.Thread.resume() */\n\t\tDUK_ASSERT(thr->callstack_top >= 2);                                                                         /* ECMAScript activation + Duktape.Thread.resume() activation */\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL &&\n\t\t           DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)) &&\n\t\t           ((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->callstack_curr))->func == duk_bi_thread_resume);\n\n\t\ttv = &thr->heap->lj.value2;  /* resumee */\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));\n\t\tDUK_ASSERT(DUK_TVAL_GET_OBJECT(tv) != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_THREAD(DUK_TVAL_GET_OBJECT(tv)));\n\t\tresumee = (duk_hthread *) DUK_TVAL_GET_OBJECT(tv);\n\n\t\tDUK_ASSERT(resumee != NULL);\n\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\tDUK_ASSERT(resumee->state == DUK_HTHREAD_STATE_INACTIVE ||\n\t\t           resumee->state == DUK_HTHREAD_STATE_YIELDED);                                                     /* checked by Duktape.Thread.resume() */\n\t\tDUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_YIELDED ||\n\t\t           resumee->callstack_top >= 2);                                                                     /* YIELDED: ECMAScript activation + Duktape.Thread.yield() activation */\n\t\tDUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_YIELDED ||\n\t\t           (DUK_ACT_GET_FUNC(resumee->callstack_curr) != NULL &&\n\t\t            DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(resumee->callstack_curr)) &&\n\t\t            ((duk_hnatfunc *) DUK_ACT_GET_FUNC(resumee->callstack_curr))->func == duk_bi_thread_yield));\n\t\tDUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_INACTIVE ||\n\t\t           resumee->callstack_top == 0);                                                                     /* INACTIVE: no activation, single function value on valstack */\n\n\t\tif (thr->heap->lj.iserror) {\n\t\t\t/*\n\t\t\t *  Throw the error in the resumed thread's context; the\n\t\t\t *  error value is pushed onto the resumee valstack.\n\t\t\t *\n\t\t\t *  Note: the callstack of the target may empty in this case\n\t\t\t *  too (i.e. the target thread has never been resumed).  The\n\t\t\t *  value stack will contain the initial function in that case,\n\t\t\t *  which we simply ignore.\n\t\t\t */\n\n\t\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\t\tresumee->resumer = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tresumee->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tthr->state = DUK_HTHREAD_STATE_RESUMED;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumee);\n\t\t\tthr = resumee;\n\n\t\t\tthr->heap->lj.type = DUK_LJ_TYPE_THROW;\n\n\t\t\t/* thr->heap->lj.value1 is already the value to throw */\n\t\t\t/* thr->heap->lj.value2 is 'thread', will be wiped out at the end */\n\n\t\t\tDUK_ASSERT(thr->heap->lj.iserror);  /* already set */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> resume with an error, converted to a throw in the resumee, propagate\"));\n\t\t\tgoto check_longjmp;\n\t\t} else if (resumee->state == DUK_HTHREAD_STATE_YIELDED) {\n\t\t\t/* Unwind previous Duktape.Thread.yield() call.  The\n\t\t\t * activation remaining must always be an ECMAScript\n\t\t\t * call now (yield() accepts calls from ECMAScript\n\t\t\t * only).\n\t\t\t */\n\t\t\tduk_activation *act_resumee;\n\n\t\t\tDUK_ASSERT(resumee->callstack_top >= 2);\n\t\t\tact_resumee = resumee->callstack_curr;  /* Duktape.Thread.yield() */\n\t\t\tDUK_ASSERT(act_resumee != NULL);\n\t\t\tact_resumee = act_resumee->parent;      /* ECMAScript call site for yield() */\n\t\t\tDUK_ASSERT(act_resumee != NULL);\n\n\t\t\ttv = (duk_tval *) (void *) ((duk_uint8_t *) resumee->valstack + act_resumee->retval_byteoff);  /* return value from Duktape.Thread.yield() */\n\t\t\tDUK_ASSERT(tv >= resumee->valstack && tv < resumee->valstack_top);\n\t\t\ttv2 = &thr->heap->lj.value1;\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv2);  /* side effects */  /* XXX: avoid side effects */\n\n\t\t\tduk_hthread_activation_unwind_norz(resumee);  /* unwind to 'yield' caller */\n\t\t\t/* no need to unwind catch stack */\n\n\t\t\tduk__reconfig_valstack_ecma_return(resumee);\n\n\t\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\t\tresumee->resumer = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tresumee->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tthr->state = DUK_HTHREAD_STATE_RESUMED;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumee);\n#if 0\n\t\t\tthr = resumee;  /* not needed, as we exit right away */\n#endif\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> resume with a value, restart execution in resumee\"));\n\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\tgoto wipe_and_return;\n\t\t} else {\n\t\t\t/* Initial resume call. */\n\t\t\tduk_small_uint_t call_flags;\n\t\t\tduk_int_t setup_rc;\n\n\t\t\t/* resumee: [... initial_func]  (currently actually: [initial_func]) */\n\n\t\t\tduk_push_undefined(resumee);\n\t\t\ttv = &thr->heap->lj.value1;\n\t\t\tduk_push_tval(resumee, tv);\n\n\t\t\t/* resumee: [... initial_func undefined(= this) resume_value ] */\n\n\t\t\tcall_flags = DUK_CALL_FLAG_ALLOW_ECMATOECMA;  /* not tailcall, ecma-to-ecma (assumed to succeed) */\n\n\t\t\tsetup_rc = duk_handle_call_unprotected_nargs(resumee, 1 /*nargs*/, call_flags);\n\t\t\tif (setup_rc == 0) {\n\t\t\t\t/* This shouldn't happen; Duktape.Thread.resume()\n\t\t\t\t * should make sure of that.  If it does happen\n\t\t\t\t * this internal error will propagate out of the\n\t\t\t\t * executor which can be quite misleading.\n\t\t\t\t */\n\t\t\t\tDUK_ERROR_INTERNAL(thr);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\n\t\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\t\tresumee->resumer = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tresumee->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tthr->state = DUK_HTHREAD_STATE_RESUMED;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumee);\n#if 0\n\t\t\tthr = resumee;  /* not needed, as we exit right away */\n#endif\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> resume with a value, restart execution in resumee\"));\n\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\tgoto wipe_and_return;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\t\tbreak;  /* never here */\n\t}\n\n\tcase DUK_LJ_TYPE_YIELD: {\n\t\t/*\n\t\t *  Currently only allowed only if yielding thread has only\n\t\t *  ECMAScript activations (except for the Duktape.Thread.yield()\n\t\t *  call at the callstack top) and none of them constructor\n\t\t *  calls.\n\t\t *\n\t\t *  This excludes the 'entry' thread which will always have\n\t\t *  a preventcount > 0.\n\t\t */\n\n\t\tduk_hthread *resumer;\n\n\t\t/* duk_bi_duk_object_yield() and duk_bi_duk_object_resume() ensure all of these are met */\n\n#if 0  /* entry_thread not available for assert */\n\t\tDUK_ASSERT(thr != entry_thread);                                                                             /* Duktape.Thread.yield() should prevent */\n#endif\n\t\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);                                                         /* unchanged from Duktape.Thread.yield() */\n\t\tDUK_ASSERT(thr->callstack_top >= 2);                                                                         /* ECMAScript activation + Duktape.Thread.yield() activation */\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL &&\n\t\t           DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)) &&\n\t\t           ((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->callstack_curr))->func == duk_bi_thread_yield);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL &&\n\t\t           DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent)));                              /* an ECMAScript function */\n\n\t\tresumer = thr->resumer;\n\n\t\tDUK_ASSERT(resumer != NULL);\n\t\tDUK_ASSERT(resumer->state == DUK_HTHREAD_STATE_RESUMED);                                                     /* written by a previous RESUME handling */\n\t\tDUK_ASSERT(resumer->callstack_top >= 2);                                                                     /* ECMAScript activation + Duktape.Thread.resume() activation */\n\t\tDUK_ASSERT(resumer->callstack_curr != NULL);\n\t\tDUK_ASSERT(resumer->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack_curr) != NULL &&\n\t\t           DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr)) &&\n\t\t           ((duk_hnatfunc *) DUK_ACT_GET_FUNC(resumer->callstack_curr))->func == duk_bi_thread_resume);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack_curr->parent) != NULL &&\n\t\t           DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr->parent)));                            /* an ECMAScript function */\n\n\t\tif (thr->heap->lj.iserror) {\n\t\t\tthr->state = DUK_HTHREAD_STATE_YIELDED;\n\t\t\tthr->resumer = NULL;\n\t\t\tDUK_HTHREAD_DECREF_NORZ(thr, resumer);\n\t\t\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n\t\t\tthr = resumer;\n\n\t\t\tthr->heap->lj.type = DUK_LJ_TYPE_THROW;\n\t\t\t/* lj.value1 is already set */\n\t\t\tDUK_ASSERT(thr->heap->lj.iserror);  /* already set */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> yield an error, converted to a throw in the resumer, propagate\"));\n\t\t\tgoto check_longjmp;\n\t\t} else {\n\t\t\tduk_hthread_activation_unwind_norz(resumer);\n\t\t\tduk__handle_yield(thr, resumer, &thr->heap->lj.value1);\n\n\t\t\tthr->state = DUK_HTHREAD_STATE_YIELDED;\n\t\t\tthr->resumer = NULL;\n\t\t\tDUK_HTHREAD_DECREF_NORZ(thr, resumer);\n\t\t\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n#if 0\n\t\t\tthr = resumer;  /* not needed, as we exit right away */\n#endif\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> yield a value, restart execution in resumer\"));\n\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\tgoto wipe_and_return;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\t\tbreak;  /* never here */\n\t}\n#endif  /* DUK_USE_COROUTINE_SUPPORT */\n\n\tcase DUK_LJ_TYPE_THROW: {\n\t\t/*\n\t\t *  Three possible outcomes:\n\t\t *    * A try or finally catcher is found => resume there.\n\t\t *      (or)\n\t\t *    * The error propagates to the bytecode executor entry\n\t\t *      level (and we're in the entry thread) => rethrow\n\t\t *      with a new longjmp(), after restoring the previous\n\t\t *      catchpoint.\n\t\t *    * The error is not caught in the current thread, so\n\t\t *      the thread finishes with an error.  This works like\n\t\t *      a yielded error, except that the thread is finished\n\t\t *      and can no longer be resumed.  (There is always a\n\t\t *      resumer in this case.)\n\t\t *\n\t\t *  Note: until we hit the entry level, there can only be\n\t\t *  ECMAScript activations.\n\t\t */\n\n\t\tduk_activation *act;\n\t\tduk_catcher *cat;\n\t\tduk_hthread *resumer;\n\n\t\tfor (;;) {\n\t\t\tact = thr->callstack_curr;\n\t\t\tif (act == NULL) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tfor (;;) {\n\t\t\t\tcat = act->cat;\n\t\t\t\tif (cat == NULL) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (DUK_CAT_HAS_CATCH_ENABLED(cat)) {\n\t\t\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"before catch part 1: thr=%p, act=%p, cat=%p\",\n\t\t\t\t\t                     (void *) thr, (void *) act, (void *) act->cat));\n\t\t\t\t\tduk__handle_catch_part1(thr,\n\t\t\t\t\t                        &thr->heap->lj.value1,\n\t\t\t\t\t                        DUK_LJ_TYPE_THROW,\n\t\t\t\t\t\t\t        out_delayed_catch_setup);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"-> throw caught by a 'catch' clause, restart execution\"));\n\t\t\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\t\t\tgoto wipe_and_return;\n\t\t\t\t}\n\n\t\t\t\tif (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\t\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);\n\t\t\t\t\tDUK_ASSERT(!DUK_CAT_HAS_CATCH_ENABLED(cat));\n\n\t\t\t\t\tduk__handle_finally(thr,\n\t\t\t\t\t                    &thr->heap->lj.value1,\n\t\t\t\t\t                    DUK_LJ_TYPE_THROW);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"-> throw caught by a 'finally' clause, restart execution\"));\n\t\t\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\t\t\tgoto wipe_and_return;\n\t\t\t\t}\n\n\t\t\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t\t\t}\n\n\t\t\tif (act == entry_act) {\n\t\t\t\t/* Not caught by anything before entry level; rethrow and let the\n\t\t\t\t * final catcher finish unwinding (esp. value stack).\n\t\t\t\t */\n\t\t\t\tDUK_D(DUK_DPRINT(\"-> throw propagated up to entry level, rethrow and exit bytecode executor\"));\n\t\t\t\tretval = DUK__LONGJMP_RETHROW;\n\t\t\t\tgoto just_return;\n\t\t\t}\n\n\t\t\tduk_hthread_activation_unwind_norz(thr);\n\t\t}\n\n\t\tDUK_DD(DUK_DDPRINT(\"-> throw not caught by current thread, yield error to resumer and recheck longjmp\"));\n\n\t\t/* Not caught by current thread, thread terminates (yield error to resumer);\n\t\t * note that this may cause a cascade if the resumer terminates with an uncaught\n\t\t * exception etc (this is OK, but needs careful testing).\n\t\t */\n\n\t\tDUK_ASSERT(thr->resumer != NULL);\n\t\tDUK_ASSERT(thr->resumer->callstack_top >= 2);  /* ECMAScript activation + Duktape.Thread.resume() activation */\n\t\tDUK_ASSERT(thr->resumer->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->resumer->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent) != NULL &&\n\t\t           DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent)));  /* an ECMAScript function */\n\n\t\tresumer = thr->resumer;\n\n\t\t/* reset longjmp */\n\n\t\tDUK_ASSERT(thr->heap->lj.type == DUK_LJ_TYPE_THROW);  /* already set */\n\t\t/* lj.value1 already set */\n\n\t\tduk_hthread_terminate(thr);  /* updates thread state, minimizes its allocations */\n\t\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_TERMINATED);\n\n\t\tthr->resumer = NULL;\n\t\tDUK_HTHREAD_DECREF_NORZ(thr, resumer);\n\t\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n\t\tthr = resumer;\n\t\tgoto check_longjmp;\n\t}\n\n\tcase DUK_LJ_TYPE_BREAK:  /* pseudotypes, not used in actual longjmps */\n\tcase DUK_LJ_TYPE_CONTINUE:\n\tcase DUK_LJ_TYPE_RETURN:\n\tcase DUK_LJ_TYPE_NORMAL:\n\tdefault: {\n\t\t/* should never happen, but be robust */\n\t\tDUK_D(DUK_DPRINT(\"caught unknown longjmp type %ld, treat as internal error\", (long) thr->heap->lj.type));\n\t\tgoto convert_to_internal_error;\n\t}\n\n\t}  /* end switch */\n\n\tDUK_UNREACHABLE();\n\n wipe_and_return:\n\tDUK_DD(DUK_DDPRINT(\"handling longjmp done, wipe-and-return, top=%ld\",\n\t                   (long) duk_get_top(thr)));\n\tthr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;\n\tthr->heap->lj.iserror = 0;\n\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value1);  /* side effects */\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value2);  /* side effects */\n\n\tDUK_GC_TORTURE(thr->heap);\n\n just_return:\n\treturn retval;\n\n convert_to_internal_error:\n\t/* This could also be thrown internally (set the error, goto check_longjmp),\n\t * but it's better for internal errors to bubble outwards so that we won't\n\t * infinite loop in this catchpoint.\n\t */\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Handle a BREAK/CONTINUE opcode.  Avoid using longjmp() for BREAK/CONTINUE\n * handling because it has a measurable performance impact in ordinary\n * environments and an extreme impact in Emscripten (GH-342).\n */\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_break_or_continue(duk_hthread *thr,\n                                                                duk_uint_t label_id,\n                                                                duk_small_uint_t lj_type) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Find a matching label catcher or 'finally' catcher in\n\t * the same function, unwinding catchers as we go.\n\t *\n\t * A label catcher must always exist and will match unless\n\t * a 'finally' captures the break/continue first.  It is the\n\t * compiler's responsibility to ensure that labels are used\n\t * correctly.\n\t */\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\tfor (;;) {\n\t\tcat = act->cat;\n\t\tif (cat == NULL) {\n\t\t\tbreak;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"considering catcher %p: type=%ld label=%ld\",\n\t\t                     (void *) cat,\n\t\t                     (long) DUK_CAT_GET_TYPE(cat),\n\t\t                     (long) DUK_CAT_GET_LABEL(cat)));\n\n\t\t/* XXX: bit mask test; FINALLY <-> TCF, single bit mask would suffice? */\n\n\t\tif (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF &&\n\t\t    DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\t\tduk_tval tv_tmp;\n\n\t\t\tDUK_TVAL_SET_U32(&tv_tmp, (duk_uint32_t) label_id);\n\t\t\tduk__handle_finally(thr, &tv_tmp, lj_type);\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> break/continue caught by 'finally', restart execution\"));\n\t\t\treturn;\n\t\t}\n\t\tif (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_LABEL &&\n\t\t    (duk_uint_t) DUK_CAT_GET_LABEL(cat) == label_id) {\n\t\t\tduk__handle_label(thr, lj_type);\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> break/continue caught by a label catcher (in the same function), restart execution\"));\n\t\t\treturn;\n\t\t}\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t}\n\n\t/* Should never happen, but be robust. */\n\tDUK_D(DUK_DPRINT(\"-> break/continue not caught by anything in the current function (should never happen), throw internal error\"));\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Handle a RETURN opcode.  Avoid using longjmp() for return handling because\n * it has a measurable performance impact in ordinary environments and an extreme\n * impact in Emscripten (GH-342).  Return value is on value stack top.\n */\nDUK_LOCAL duk_small_uint_t duk__handle_return(duk_hthread *thr, duk_activation *entry_act) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\tduk_hthread *resumer;\n#endif\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\t/* We can directly access value stack here. */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(entry_act != NULL);\n\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\ttv1 = thr->valstack_top - 1;\n\tDUK_TVAL_CHKFAST_INPLACE_FAST(tv1);  /* fastint downgrade check for return values */\n\n\t/*\n\t *  Four possible outcomes:\n\t *\n\t *    1. A 'finally' in the same function catches the 'return'.\n\t *       It may continue to propagate when 'finally' is finished,\n\t *       or it may be neutralized by 'finally' (both handled by\n\t *       ENDFIN).\n\t *\n\t *    2. The return happens at the entry level of the bytecode\n\t *       executor, so return from the executor (in C stack).\n\t *\n\t *    3. There is a calling (ECMAScript) activation in the call\n\t *       stack => return to it, in the same executor instance.\n\t *\n\t *    4. There is no calling activation, and the thread is\n\t *       terminated.  There is always a resumer in this case,\n\t *       which gets the return value similarly to a 'yield'\n\t *       (except that the current thread can no longer be\n\t *       resumed).\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\tfor (;;) {\n\t\tcat = act->cat;\n\t\tif (cat == NULL) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF &&\n\t\t    DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\t\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\t\t\tduk__handle_finally(thr, thr->valstack_top - 1, DUK_LJ_TYPE_RETURN);\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> return caught by 'finally', restart execution\"));\n\t\t\treturn DUK__RETHAND_RESTART;\n\t\t}\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t}\n\n\tif (act == entry_act) {\n\t\t/* Return to the bytecode executor caller who will unwind stacks\n\t\t * and handle constructor post-processing.\n\t\t * Return value is already on the stack top: [ ... retval ].\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> return propagated up to entry level, exit bytecode executor\"));\n\t\treturn DUK__RETHAND_FINISHED;\n\t}\n\n\tif (thr->callstack_top >= 2) {\n\t\t/* There is a caller; it MUST be an ECMAScript caller (otherwise it would\n\t\t * match entry_act check).\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"return to ECMAScript caller, retval_byteoff=%ld, lj_value1=%!T\",\n\t\t                     (long) (thr->callstack_curr->parent->retval_byteoff),\n\t\t                     (duk_tval *) &thr->heap->lj.value1));\n\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent)));   /* must be ECMAScript */\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (thr->callstack_curr->flags & (DUK_ACT_FLAG_CONSTRUCT | DUK_ACT_FLAG_CONSTRUCT_PROXY)) {\n\t\t\tduk_call_construct_postprocess(thr, thr->callstack_curr->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY);  /* side effects */\n\t\t}\n#else\n\t\tif (thr->callstack_curr->flags & DUK_ACT_FLAG_CONSTRUCT) {\n\t\t\tduk_call_construct_postprocess(thr, 0);  /* side effects */\n\t\t}\n#endif\n\n\t\ttv1 = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + thr->callstack_curr->parent->retval_byteoff);\n\t\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\t\ttv2 = thr->valstack_top - 1;\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\n\t\t/* Catch stack unwind happens inline in callstack unwind. */\n\t\tduk_hthread_activation_unwind_norz(thr);\n\n\t\tduk__reconfig_valstack_ecma_return(thr);\n\n\t\tDUK_DD(DUK_DDPRINT(\"-> return not intercepted, restart execution in caller\"));\n\t\treturn DUK__RETHAND_RESTART;\n\t}\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\tDUK_DD(DUK_DDPRINT(\"no calling activation, thread finishes (similar to yield)\"));\n\n\tDUK_ASSERT(thr->resumer != NULL);\n\tDUK_ASSERT(thr->resumer->callstack_top >= 2);  /* ECMAScript activation + Duktape.Thread.resume() activation */\n\tDUK_ASSERT(thr->resumer->callstack_curr != NULL);\n\tDUK_ASSERT(thr->resumer->callstack_curr->parent != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr) != NULL &&\n\t\t\tDUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr)) &&\n\t\t\t((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->resumer->callstack_curr))->func == duk_bi_thread_resume);  /* Duktape.Thread.resume() */\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent) != NULL &&\n\t\t\tDUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent)));  /* an ECMAScript function */\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\tDUK_ASSERT(thr->resumer->state == DUK_HTHREAD_STATE_RESUMED);\n\n\tresumer = thr->resumer;\n\n\t/* Share yield longjmp handler.\n\t *\n\t * This sequence of steps is a bit fragile (see GH-1845):\n\t * - We need the return value from 'thr' (resumed thread) value stack.\n\t *   The termination unwinds its value stack, losing the value.\n\t * - We need a refcounted reference for 'thr', which may only exist\n\t *   in the caller value stack.  We can't unwind or reconfigure the\n\t *   caller's value stack without potentially freeing 'thr'.\n\t *\n\t * Current approach is to capture the 'thr' return value and store\n\t * a reference to 'thr' in the caller value stack temporarily.  This\n\t * keeps 'thr' reachable until final yield/return handling which\n\t * removes the references atomatically.\n\t */\n\n\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\tduk_hthread_activation_unwind_norz(resumer);  /* May remove last reference to 'thr', but is NORZ. */\n\tduk_push_tval(resumer, thr->valstack_top - 1);  /* Capture return value, side effect free. */\n\tduk_push_hthread(resumer, thr);  /* Make 'thr' reachable again, before side effects. */\n\n\tduk_hthread_terminate(thr);  /* Updates thread state, minimizes its allocations. */\n\tthr->resumer = NULL;\n\tDUK_HTHREAD_DECREF(thr, resumer);\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_TERMINATED);\n\n\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n\n\tDUK_ASSERT(resumer->valstack_top - 2 >= resumer->valstack_bottom);\n\tduk__handle_yield(thr, resumer, resumer->valstack_top - 2);\n\tthr = NULL;  /* 'thr' invalidated by call */\n\n#if 0\n\tthr = resumer;  /* not needed */\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"-> return not caught, thread terminated; handle like yield, restart execution in resumer\"));\n\treturn DUK__RETHAND_RESTART;\n#else\n\t/* Without coroutine support this case should never happen. */\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n#endif\n}\n\n/*\n *  Executor interrupt handling\n *\n *  The handler is called whenever the interrupt countdown reaches zero\n *  (or below).  The handler must perform whatever checks are activated,\n *  e.g. check for cumulative step count to impose an execution step\n *  limit or check for breakpoints or other debugger interaction.\n *\n *  When the actions are done, the handler must reinit the interrupt\n *  init and counter values.  The 'init' value must indicate how many\n *  bytecode instructions are executed before the next interrupt.  The\n *  counter must interface with the bytecode executor loop.  Concretely,\n *  the new init value is normally one higher than the new counter value.\n *  For instance, to execute exactly one bytecode instruction the init\n *  value is set to 1 and the counter to 0.  If an error is thrown by the\n *  interrupt handler, the counters are set to the same value (e.g. both\n *  to 0 to cause an interrupt when the next bytecode instruction is about\n *  to be executed after error handling).\n *\n *  Maintaining the init/counter value properly is important for accurate\n *  behavior.  For instance, executor step limit needs a cumulative step\n *  count which is simply computed as a sum of 'init' values.  This must\n *  work accurately even when single stepping.\n */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\n#define DUK__INT_NOACTION    0    /* no specific action, resume normal execution */\n#define DUK__INT_RESTART     1    /* must \"goto restart_execution\", e.g. breakpoints changed */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_immediate, duk_small_uint_t *out_interrupt_retval) {\n\tduk_activation *act;\n\tduk_breakpoint *bp;\n\tduk_breakpoint **bp_active;\n\tduk_uint_fast32_t line = 0;\n\tduk_bool_t process_messages;\n\tduk_bool_t processed_messages = 0;\n\n\tDUK_ASSERT(thr->heap->dbg_processing == 0);  /* don't re-enter e.g. during Eval */\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\t/* It might seem that replacing 'thr->heap' with just 'heap' below\n\t * might be a good idea, but it increases code size slightly\n\t * (probably due to unnecessary spilling) at least on x64.\n\t */\n\n\t/*\n\t *  Single opcode step check\n\t */\n\n\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE) {\n\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by one opcode step\"));\n\t\tduk_debug_set_paused(thr->heap);\n\t}\n\n\t/*\n\t *  Breakpoint and step state checks\n\t */\n\n\tif (act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE ||\n\t    (thr->heap->dbg_pause_act == thr->callstack_curr)) {\n\t\tline = duk_debug_curr_line(thr);\n\n\t\tif (act->prev_line != line) {\n\t\t\t/* Stepped?  Step out is handled by callstack unwind. */\n\t\t\tif ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) &&\n\t\t\t    (thr->heap->dbg_pause_act == thr->callstack_curr) &&\n\t\t\t    (line != thr->heap->dbg_pause_startline)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by line change, at line %ld\",\n\t\t\t\t                 (long) line));\n\t\t\t\tduk_debug_set_paused(thr->heap);\n\t\t\t}\n\n\t\t\t/* Check for breakpoints only on line transition.\n\t\t\t * Breakpoint is triggered when we enter the target\n\t\t\t * line from a different line, and the previous line\n\t\t\t * was within the same function.\n\t\t\t *\n\t\t\t * This condition is tricky: the condition used to be\n\t\t\t * that transition to -or across- the breakpoint line\n\t\t\t * triggered the breakpoint.  This seems intuitively\n\t\t\t * better because it handles breakpoints on lines with\n\t\t\t * no emitted opcodes; but this leads to the issue\n\t\t\t * described in: https://github.com/svaarala/duktape/issues/263.\n\t\t\t */\n\t\t\tbp_active = thr->heap->dbg_breakpoints_active;\n\t\t\tfor (;;) {\n\t\t\t\tbp = *bp_active++;\n\t\t\t\tif (bp == NULL) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tDUK_ASSERT(bp->filename != NULL);\n\t\t\t\tif (act->prev_line != bp->line && line == bp->line) {\n\t\t\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by breakpoint at %!O:%ld\",\n\t\t\t\t\t                 (duk_heaphdr *) bp->filename, (long) bp->line));\n\t\t\t\t\tduk_debug_set_paused(thr->heap);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t;\n\t\t}\n\n\t\tact->prev_line = (duk_uint32_t) line;\n\t}\n\n\t/*\n\t *  Rate limit check for sending status update or peeking into\n\t *  the debug transport.  Both can be expensive operations that\n\t *  we don't want to do on every opcode.\n\t *\n\t *  Making sure the interval remains reasonable on a wide variety\n\t *  of targets and bytecode is difficult without a timestamp, so\n\t *  we use a Date-provided timestamp for the rate limit check.\n\t *  But since it's also expensive to get a timestamp, a bytecode\n\t *  counter is used to rate limit getting timestamps.\n\t */\n\n\tprocess_messages = 0;\n\tif (thr->heap->dbg_state_dirty || DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || thr->heap->dbg_detaching) {\n\t\t/* Enter message processing loop for sending Status notifys and\n\t\t * to finish a pending detach.\n\t\t */\n\t\tprocess_messages = 1;\n\t}\n\n\t/* XXX: remove heap->dbg_exec_counter, use heap->inst_count_interrupt instead? */\n\tDUK_ASSERT(thr->interrupt_init >= 0);\n\tthr->heap->dbg_exec_counter += (duk_uint_t) thr->interrupt_init;\n\tif (thr->heap->dbg_exec_counter - thr->heap->dbg_last_counter >= DUK_HEAP_DBG_RATELIMIT_OPCODES) {\n\t\t/* Overflow of the execution counter is fine and doesn't break\n\t\t * anything here.\n\t\t */\n\n\t\tduk_double_t now, diff_last;\n\n\t\tthr->heap->dbg_last_counter = thr->heap->dbg_exec_counter;\n\t\tnow = duk_time_get_monotonic_time(thr);\n\n\t\tdiff_last = now - thr->heap->dbg_last_time;\n\t\tif (diff_last < 0.0 || diff_last >= (duk_double_t) DUK_HEAP_DBG_RATELIMIT_MILLISECS) {\n\t\t\t/* Monotonic time should not experience time jumps,\n\t\t\t * but the provider may be missing and we're actually\n\t\t\t * using ECMAScript time.  So, tolerate negative values\n\t\t\t * so that a time jump works reasonably.\n\t\t\t *\n\t\t\t * Same interval is now used for status sending and\n\t\t\t * peeking.\n\t\t\t */\n\n\t\t\tthr->heap->dbg_last_time = now;\n\t\t\tthr->heap->dbg_state_dirty = 1;\n\t\t\tprocess_messages = 1;\n\t\t}\n\t}\n\n\t/*\n\t *  Process messages and send status if necessary.\n\t *\n\t *  If we're paused, we'll block for new messages.  If we're not\n\t *  paused, we'll process anything we can peek but won't block\n\t *  for more.  Detach (and re-attach) handling is all localized\n\t *  to duk_debug_process_messages() too.\n\t *\n\t *  Debugger writes outside the message loop may cause debugger\n\t *  detach1 phase to run, after which dbg_read_cb == NULL and\n\t *  dbg_detaching != 0.  The message loop will finish the detach\n\t *  by running detach2 phase, so enter the message loop also when\n\t *  detaching.\n\t */\n\n\tif (process_messages) {\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\t\tprocessed_messages = duk_debug_process_messages(thr, 0 /*no_block*/);\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\t}\n\n\t/* Continue checked execution if there are breakpoints or we're stepping.\n\t * Also use checked execution if paused flag is active - it shouldn't be\n\t * because the debug message loop shouldn't terminate if it was.  Step out\n\t * is handled by callstack unwind and doesn't need checked execution.\n\t * Note that debugger may have detached due to error or explicit request\n\t * above, so we must recheck attach status.\n\t */\n\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t\tif (act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE ||\n\t\t    (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE) ||\n\t\t    ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) &&\n\t\t     thr->heap->dbg_pause_act == thr->callstack_curr) ||\n\t\t     DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap)) {\n\t\t\t*out_immediate = 1;\n\t\t}\n\n\t\t/* If we processed any debug messages breakpoints may have\n\t\t * changed; restart execution to re-check active breakpoints.\n\t\t */\n\t\tif (processed_messages) {\n\t\t\tDUK_D(DUK_DPRINT(\"processed debug messages, restart execution to recheck possibly changed breakpoints\"));\n\t\t\t*out_interrupt_retval = DUK__INT_RESTART;\n\t\t} else {\n\t\t\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE) {\n\t\t\t\t/* Set 'pause after one opcode' active only when we're\n\t\t\t\t * actually just about to execute code.\n\t\t\t\t */\n\t\t\t\tthr->heap->dbg_pause_flags |= DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"debugger became detached, resume normal execution\"));\n\t}\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\nDUK_LOCAL DUK__NOINLINE_PERF DUK_COLD duk_small_uint_t duk__executor_interrupt(duk_hthread *thr) {\n\tduk_int_t ctr;\n\tduk_activation *act;\n\tduk_hcompfunc *fun;\n\tduk_bool_t immediate = 0;\n\tduk_small_uint_t retval;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->callstack_top > 0);\n\n#if defined(DUK_USE_DEBUG)\n\tthr->heap->inst_count_interrupt += thr->interrupt_init;\n\tDUK_DD(DUK_DDPRINT(\"execution interrupt, counter=%ld, init=%ld, \"\n\t                   \"instruction counts: executor=%ld, interrupt=%ld\",\n\t                   (long) thr->interrupt_counter, (long) thr->interrupt_init,\n\t                   (long) thr->heap->inst_count_exec, (long) thr->heap->inst_count_interrupt));\n#endif\n\n\tretval = DUK__INT_NOACTION;\n\tctr = DUK_HTHREAD_INTCTR_DEFAULT;\n\n\t/*\n\t *  Avoid nested calls.  Concretely this happens during debugging, e.g.\n\t *  when we eval() an expression.\n\t *\n\t *  Also don't interrupt if we're currently doing debug processing\n\t *  (which can be initiated outside the bytecode executor) as this\n\t *  may cause the debugger to be called recursively.  Check required\n\t *  for correct operation of throw intercept and other \"exotic\" halting\n\t * scenarios.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (DUK_HEAP_HAS_INTERRUPT_RUNNING(thr->heap) || thr->heap->dbg_processing) {\n#else\n\tif (DUK_HEAP_HAS_INTERRUPT_RUNNING(thr->heap)) {\n#endif\n\t\tDUK_DD(DUK_DDPRINT(\"nested executor interrupt, ignoring\"));\n\n\t\t/* Set a high interrupt counter; the original executor\n\t\t * interrupt invocation will rewrite before exiting.\n\t\t */\n\t\tthr->interrupt_init = ctr;\n\t\tthr->interrupt_counter = ctr - 1;\n\t\treturn DUK__INT_NOACTION;\n\t}\n\tDUK_HEAP_SET_INTERRUPT_RUNNING(thr->heap);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC((duk_hobject *) fun));\n\n\tDUK_UNREF(fun);\n\n#if defined(DUK_USE_EXEC_TIMEOUT_CHECK)\n\t/*\n\t *  Execution timeout check\n\t */\n\n\tif (DUK_USE_EXEC_TIMEOUT_CHECK(thr->heap->heap_udata)) {\n\t\t/* Keep throwing an error whenever we get here.  The unusual values\n\t\t * are set this way because no instruction is ever executed, we just\n\t\t * throw an error until all try/catch/finally and other catchpoints\n\t\t * have been exhausted.  Duktape/C code gets control at each protected\n\t\t * call but whenever it enters back into Duktape the RangeError gets\n\t\t * raised.  User exec timeout check must consistently indicate a timeout\n\t\t * until we've fully bubbled out of Duktape.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"execution timeout, throwing a RangeError\"));\n\t\tthr->interrupt_init = 0;\n\t\tthr->interrupt_counter = 0;\n\t\tDUK_HEAP_CLEAR_INTERRUPT_RUNNING(thr->heap);\n\t\tDUK_ERROR_RANGE(thr, \"execution timeout\");\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n#endif  /* DUK_USE_EXEC_TIMEOUT_CHECK */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (!thr->heap->dbg_processing &&\n\t    (thr->heap->dbg_read_cb != NULL || thr->heap->dbg_detaching)) {\n\t\t/* Avoid recursive re-entry; enter when we're attached or\n\t\t * detaching (to finish off the pending detach).\n\t\t */\n\t\tduk__interrupt_handle_debugger(thr, &immediate, &retval);\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n\t/*\n\t *  Update the interrupt counter\n\t */\n\n\tif (immediate) {\n\t\t/* Cause an interrupt after executing one instruction. */\n\t\tctr = 1;\n\t}\n\n\t/* The counter value is one less than the init value: init value should\n\t * indicate how many instructions are executed before interrupt.  To\n\t * execute 1 instruction (after interrupt handler return), counter must\n\t * be 0.\n\t */\n\tDUK_ASSERT(ctr >= 1);\n\tthr->interrupt_init = ctr;\n\tthr->interrupt_counter = ctr - 1;\n\tDUK_HEAP_CLEAR_INTERRUPT_RUNNING(thr->heap);\n\n\treturn retval;\n}\n#endif  /* DUK_USE_INTERRUPT_COUNTER */\n\n/*\n *  Debugger handling for executor restart\n *\n *  Check for breakpoints, stepping, etc, and figure out if we should execute\n *  in checked or normal mode.  Note that we can't do this when an activation\n *  is created, because breakpoint status (and stepping status) may change\n *  later, so we must recheck every time we're executing an activation.\n *  This primitive should be side effect free to avoid changes during check.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_LOCAL void duk__executor_recheck_debugger(duk_hthread *thr, duk_activation *act, duk_hcompfunc *fun) {\n\tduk_heap *heap;\n\tduk_tval *tv_tmp;\n\tduk_hstring *filename;\n\tduk_small_uint_t bp_idx;\n\tduk_breakpoint **bp_active;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(fun != NULL);\n\n\theap = thr->heap;\n\tbp_active = heap->dbg_breakpoints_active;\n\tact->flags &= ~DUK_ACT_FLAG_BREAKPOINT_ACTIVE;\n\n\ttv_tmp = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) fun, DUK_STRIDX_FILE_NAME);\n\tif (tv_tmp && DUK_TVAL_IS_STRING(tv_tmp)) {\n\t\tfilename = DUK_TVAL_GET_STRING(tv_tmp);\n\n\t\t/* Figure out all active breakpoints.  A breakpoint is\n\t\t * considered active if the current function's fileName\n\t\t * matches the breakpoint's fileName, AND there is no\n\t\t * inner function that has matching line numbers\n\t\t * (otherwise a breakpoint would be triggered both\n\t\t * inside and outside of the inner function which would\n\t\t * be confusing).  Example:\n\t\t *\n\t\t *     function foo() {\n\t\t *         print('foo');\n\t\t *         function bar() {    <-.  breakpoints in these\n\t\t *             print('bar');     |  lines should not affect\n\t\t *         }                   <-'  foo() execution\n\t\t *         bar();\n\t\t *     }\n\t\t *\n\t\t * We need a few things that are only available when\n\t\t * debugger support is enabled: (1) a line range for\n\t\t * each function, and (2) access to the function\n\t\t * template to access the inner functions (and their\n\t\t * line ranges).\n\t\t *\n\t\t * It's important to have a narrow match for active\n\t\t * breakpoints so that we don't enter checked execution\n\t\t * when that's not necessary.  For instance, if we're\n\t\t * running inside a certain function and there's\n\t\t * breakpoint outside in (after the call site), we\n\t\t * don't want to slow down execution of the function.\n\t\t */\n\n\t\tfor (bp_idx = 0; bp_idx < heap->dbg_breakpoint_count; bp_idx++) {\n\t\t\tduk_breakpoint *bp = heap->dbg_breakpoints + bp_idx;\n\t\t\tduk_hobject **funcs, **funcs_end;\n\t\t\tduk_hcompfunc *inner_fun;\n\t\t\tduk_bool_t bp_match;\n\n\t\t\tif (bp->filename == filename &&\n\t\t\t    bp->line >= fun->start_line && bp->line <= fun->end_line) {\n\t\t\t\tbp_match = 1;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"breakpoint filename and line match: \"\n\t\t\t\t                   \"%s:%ld vs. %s (line %ld vs. %ld-%ld)\",\n\t\t\t\t                   DUK_HSTRING_GET_DATA(bp->filename),\n\t\t\t\t                   (long) bp->line,\n\t\t\t\t                   DUK_HSTRING_GET_DATA(filename),\n\t\t\t\t                   (long) bp->line,\n\t\t\t\t                   (long) fun->start_line,\n\t\t\t\t                   (long) fun->end_line));\n\n\t\t\t\tfuncs = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, fun);\n\t\t\t\tfuncs_end = DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, fun);\n\t\t\t\twhile (funcs != funcs_end) {\n\t\t\t\t\tinner_fun = (duk_hcompfunc *) *funcs;\n\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) inner_fun));\n\t\t\t\t\tif (bp->line >= inner_fun->start_line && bp->line <= inner_fun->end_line) {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"inner function masks ('captures') breakpoint\"));\n\t\t\t\t\t\tbp_match = 0;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tfuncs++;\n\t\t\t\t}\n\n\t\t\t\tif (bp_match) {\n\t\t\t\t\t/* No need to check for size of bp_active list,\n\t\t\t\t\t * it's always larger than maximum number of\n\t\t\t\t\t * breakpoints.\n\t\t\t\t\t */\n\t\t\t\t\tact->flags |= DUK_ACT_FLAG_BREAKPOINT_ACTIVE;\n\t\t\t\t\t*bp_active = heap->dbg_breakpoints + bp_idx;\n\t\t\t\t\tbp_active++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t*bp_active = NULL;  /* terminate */\n\n\tDUK_DD(DUK_DDPRINT(\"ACTIVE BREAKPOINTS: %ld\", (long) (bp_active - thr->heap->dbg_breakpoints_active)));\n\n\t/* Force pause if we were doing \"step into\" in another activation. */\n\tif ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_ENTRY) &&\n\t    thr->heap->dbg_pause_act != thr->callstack_curr) {\n\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by function entry\"));\n\t\tduk_debug_set_paused(thr->heap);\n\t}\n\n\t/* Force interrupt right away if we're paused or in \"checked mode\".\n\t * Step out is handled by callstack unwind.\n\t */\n\tif ((act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE) ||\n\t    DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) ||\n\t    ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) &&\n\t     thr->heap->dbg_pause_act == thr->callstack_curr)) {\n\t\t/* We'll need to interrupt early so recompute the init\n\t\t * counter to reflect the number of bytecode instructions\n\t\t * executed so that step counts for e.g. debugger rate\n\t\t * limiting are accurate.\n\t\t */\n\t\tDUK_ASSERT(thr->interrupt_counter <= thr->interrupt_init);\n\t\tthr->interrupt_init = thr->interrupt_init - thr->interrupt_counter;\n\t\tthr->interrupt_counter = 0;\n\t}\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/*\n *  Opcode handlers for opcodes with a lot of code and which are relatively\n *  rare; NOINLINE to reduce amount of code in main bytecode dispatcher.\n */\n\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_initset_initget(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_bool_t is_set = (DUK_DEC_OP(ins) == DUK_OP_INITSET);\n\tduk_uint_fast_t idx;\n\tduk_uint_t defprop_flags;\n\n\t/* A -> object register (acts as a source)\n\t * BC -> BC+0 contains key, BC+1 closure (value)\n\t */\n\n\t/* INITSET/INITGET are only used to initialize object literal keys.\n\t * There may be a previous propery in ES2015 because duplicate property\n\t * names are allowed.\n\t */\n\n\t/* This could be made more optimal by accessing internals directly. */\n\n\tidx = (duk_uint_fast_t) DUK_DEC_BC(ins);\n\tduk_dup(thr, (duk_idx_t) (idx + 0));  /* key */\n\tduk_dup(thr, (duk_idx_t) (idx + 1));  /* getter/setter */\n\tif (is_set) {\n\t        defprop_flags = DUK_DEFPROP_HAVE_SETTER |\n\t                        DUK_DEFPROP_FORCE |\n\t                        DUK_DEFPROP_SET_ENUMERABLE |\n\t                        DUK_DEFPROP_SET_CONFIGURABLE;\n\t} else {\n\t        defprop_flags = DUK_DEFPROP_HAVE_GETTER |\n\t                        DUK_DEFPROP_FORCE |\n\t                        DUK_DEFPROP_SET_ENUMERABLE |\n\t                        DUK_DEFPROP_SET_CONFIGURABLE;\n\t}\n\tduk_def_prop(thr, (duk_idx_t) DUK_DEC_A(ins), defprop_flags);\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_trycatch(duk_hthread *thr, duk_uint_fast32_t ins, duk_instr_t *curr_pc) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_tval *tv1;\n\tduk_small_uint_fast_t a;\n\tduk_small_uint_fast_t bc;\n\n\t/* A -> flags\n\t * BC -> reg_catch; base register for two registers used both during\n\t *       trycatch setup and when catch is triggered\n\t *\n\t *      If DUK_BC_TRYCATCH_FLAG_CATCH_BINDING set:\n\t *          reg_catch + 0: catch binding variable name (string).\n\t *          Automatic declarative environment is established for\n\t *          the duration of the 'catch' clause.\n\t *\n\t *      If DUK_BC_TRYCATCH_FLAG_WITH_BINDING set:\n\t *          reg_catch + 0: with 'target value', which is coerced to\n\t *          an object and then used as a bindind object for an\n\t *          environment record.  The binding is initialized here, for\n\t *          the 'try' clause.\n\t *\n\t * Note that a TRYCATCH generated for a 'with' statement has no\n\t * catch or finally parts.\n\t */\n\n\t/* XXX: TRYCATCH handling should be reworked to avoid creating\n\t * an explicit scope unless it is actually needed (e.g. function\n\t * instances or eval is executed inside the catch block).  This\n\t * rework is not trivial because the compiler doesn't have an\n\t * intermediate representation.  When the rework is done, the\n\t * opcode format can also be made more straightforward.\n\t */\n\n\t/* XXX: side effect handling is quite awkward here */\n\n\tDUK_DDD(DUK_DDDPRINT(\"TRYCATCH: reg_catch=%ld, have_catch=%ld, \"\n\t                     \"have_finally=%ld, catch_binding=%ld, with_binding=%ld (flags=0x%02lx)\",\n\t                     (long) DUK_DEC_BC(ins),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH ? 1 : 0),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY ? 1 : 0),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_CATCH_BINDING ? 1 : 0),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_WITH_BINDING ? 1 : 0),\n\t                     (unsigned long) DUK_DEC_A(ins)));\n\n\ta = DUK_DEC_A(ins);\n\tbc = DUK_DEC_BC(ins);\n\n\t/* Registers 'bc' and 'bc + 1' are written in longjmp handling\n\t * and if their previous values (which are temporaries) become\n\t * unreachable -and- have a finalizer, there'll be a function\n\t * call during error handling which is not supported now (GH-287).\n\t * Ensure that both 'bc' and 'bc + 1' have primitive values to\n\t * guarantee no finalizer calls in error handling.  Scrubbing also\n\t * ensures finalizers for the previous values run here rather than\n\t * later.  Error handling related values are also written to 'bc'\n\t * and 'bc + 1' but those values never become unreachable during\n\t * error handling, so there's no side effect problem even if the\n\t * error value has a finalizer.\n\t */\n\tduk_dup(thr, (duk_idx_t) bc);  /* Stabilize value. */\n\tduk_to_undefined(thr, (duk_idx_t) bc);\n\tduk_to_undefined(thr, (duk_idx_t) (bc + 1));\n\n\t/* Allocate catcher and populate it.  Doesn't have to\n\t * be fully atomic, but the catcher must be in a\n\t * consistent state if side effects (such as finalizer\n\t * calls) occur.\n\t */\n\n\tcat = duk_hthread_catcher_alloc(thr);\n\tDUK_ASSERT(cat != NULL);\n\n\tcat->flags = DUK_CAT_TYPE_TCF;\n\tcat->h_varname = NULL;\n\tcat->pc_base = (duk_instr_t *) curr_pc;  /* pre-incremented, points to first jump slot */\n\tcat->idx_base = (duk_size_t) (thr->valstack_bottom - thr->valstack) + bc;\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tcat->parent = act->cat;\n\tact->cat = cat;\n\n\tif (a & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) {\n\t\tcat->flags |= DUK_CAT_FLAG_CATCH_ENABLED;\n\t}\n\tif (a & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY) {\n\t\tcat->flags |= DUK_CAT_FLAG_FINALLY_ENABLED;\n\t}\n\tif (a & DUK_BC_TRYCATCH_FLAG_CATCH_BINDING) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"catch binding flag set to catcher\"));\n\t\tcat->flags |= DUK_CAT_FLAG_CATCH_BINDING_ENABLED;\n\t\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\n\t\t/* borrowed reference; although 'tv1' comes from a register,\n\t\t * its value was loaded using LDCONST so the constant will\n\t\t * also exist and be reachable.\n\t\t */\n\t\tcat->h_varname = DUK_TVAL_GET_STRING(tv1);\n\t} else if (a & DUK_BC_TRYCATCH_FLAG_WITH_BINDING) {\n\t\tduk_hobjenv *env;\n\t\tduk_hobject *target;\n\n\t\t/* Delayed env initialization for activation (if needed). */\n\t\tDUK_ASSERT(thr->callstack_top >= 1);\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t\tif (act->lex_env == NULL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"delayed environment initialization\"));\n\t\t\tDUK_ASSERT(act->var_env == NULL);\n\n\t\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\t\tDUK_UNREF(act);  /* 'act' is no longer accessed, scanbuild fix */\n\t\t}\n\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\tDUK_ASSERT(act->var_env != NULL);\n\n\t\t/* Coerce 'with' target. */\n\t\ttarget = duk_to_hobject(thr, -1);\n\t\tDUK_ASSERT(target != NULL);\n\n\t\t/* Create an object environment; it is not pushed\n\t\t * so avoid side effects very carefully until it is\n\t\t * referenced.\n\t\t */\n\t\tenv = duk_hobjenv_alloc(thr,\n\t\t                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\t\tDUK_ASSERT(env != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);\n\t\tenv->target = target;  /* always provideThis=true */\n\t\tDUK_HOBJECT_INCREF(thr, target);\n\t\tenv->has_this = 1;\n\t\tDUK_HOBJENV_ASSERT_VALID(env);\n\t\tDUK_DDD(DUK_DDDPRINT(\"environment for with binding: %!iO\", env));\n\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);\n\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) env, act->lex_env);\n\t\tact->lex_env = (duk_hobject *) env;  /* Now reachable. */\n\t\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) env);\n\t\t/* Net refcount change to act->lex_env is 0: incref for env's\n\t\t * prototype, decref for act->lex_env overwrite.\n\t\t */\n\n\t\t/* Set catcher lex_env active (affects unwind)\n\t\t * only when the whole setup is complete.\n\t\t */\n\t\tcat = act->cat;  /* XXX: better to relookup? not mandatory because 'cat' is stable */\n\t\tcat->flags |= DUK_CAT_FLAG_LEXENV_ACTIVE;\n\t} else {\n\t\t;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"TRYCATCH catcher: flags=0x%08lx, pc_base=%ld, \"\n\t                     \"idx_base=%ld, h_varname=%!O\",\n\t                     (unsigned long) cat->flags,\n\t                     (long) cat->pc_base, (long) cat->idx_base, (duk_heaphdr *) cat->h_varname));\n\n\tduk_pop_unsafe(thr);\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_instr_t *duk__handle_op_endtry(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_tval *tv1;\n\tduk_instr_t *pc_base;\n\n\tDUK_UNREF(ins);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);\n\n\tDUK_DDD(DUK_DDDPRINT(\"ENDTRY: clearing catch active flag (regardless of whether it was set or not)\"));\n\tDUK_CAT_CLEAR_CATCH_ENABLED(cat);\n\n\tpc_base = cat->pc_base;\n\n\tif (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDTRY: finally part is active, jump through 2nd jump slot with 'normal continuation'\"));\n\n\t\ttv1 = thr->valstack + cat->idx_base;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\ttv1 = thr->valstack + cat->idx_base + 1;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_U32_UPDREF(thr, tv1, (duk_uint32_t) DUK_LJ_TYPE_NORMAL);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\tDUK_CAT_CLEAR_FINALLY_ENABLED(cat);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDTRY: no finally part, dismantle catcher, jump through 2nd jump slot (to end of statement)\"));\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);  /* lexenv may be set for 'with' binding */\n\t\t/* no need to unwind callstack */\n\t}\n\n\treturn pc_base + 1;  /* new curr_pc value */\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_instr_t *duk__handle_op_endcatch(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_tval *tv1;\n\tduk_instr_t *pc_base;\n\n\tDUK_UNREF(ins);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(!DUK_CAT_HAS_CATCH_ENABLED(cat));  /* cleared before entering catch part */\n\n\tif (DUK_CAT_HAS_LEXENV_ACTIVE(cat)) {\n\t\tduk_hobject *prev_env;\n\n\t\t/* 'with' binding has no catch clause, so can't be here unless a normal try-catch */\n\t\tDUK_ASSERT(DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat));\n\t\tDUK_ASSERT(act->lex_env != NULL);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDCATCH: popping catcher part lexical environment\"));\n\n\t\tprev_env = act->lex_env;\n\t\tDUK_ASSERT(prev_env != NULL);\n\t\tact->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, prev_env);\n\t\tDUK_CAT_CLEAR_LEXENV_ACTIVE(cat);\n\t\tDUK_HOBJECT_INCREF(thr, act->lex_env);\n\t\tDUK_HOBJECT_DECREF(thr, prev_env);  /* side effects */\n\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t}\n\n\tpc_base = cat->pc_base;\n\n\tif (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDCATCH: finally part is active, jump through 2nd jump slot with 'normal continuation'\"));\n\n\t\ttv1 = thr->valstack + cat->idx_base;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\ttv1 = thr->valstack + cat->idx_base + 1;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_U32_UPDREF(thr, tv1, (duk_uint32_t) DUK_LJ_TYPE_NORMAL);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\tDUK_CAT_CLEAR_FINALLY_ENABLED(cat);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDCATCH: no finally part, dismantle catcher, jump through 2nd jump slot (to end of statement)\"));\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t\t/* no need to unwind callstack */\n\t}\n\n\treturn pc_base + 1;  /* new curr_pc value */\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_small_uint_t duk__handle_op_endfin(duk_hthread *thr, duk_uint_fast32_t ins, duk_activation *entry_act) {\n\tduk_activation *act;\n\tduk_tval *tv1;\n\tduk_uint_t reg_catch;\n\tduk_small_uint_t cont_type;\n\tduk_small_uint_t ret_result;\n\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\treg_catch = DUK_DEC_ABC(ins);\n\n\t/* CATCH flag may be enabled or disabled here; it may be enabled if\n\t * the statement has a catch block but the try block does not throw\n\t * an error.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: completion value=%!T, type=%!T\",\n\t                     (duk_tval *) (thr->valstack_bottom + reg_catch + 0),\n\t                     (duk_tval *) (thr->valstack_bottom + reg_catch + 1)));\n\n\ttv1 = thr->valstack_bottom + reg_catch + 1;  /* type */\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\tcont_type = (duk_small_uint_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\tcont_type = (duk_small_uint_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\n\ttv1--;  /* value */\n\n\tswitch (cont_type) {\n\tcase DUK_LJ_TYPE_NORMAL: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: finally part finishing with 'normal' (non-abrupt) completion -> \"\n\t\t                     \"dismantle catcher, resume execution after ENDFIN\"));\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t\t/* no need to unwind callstack */\n\t\treturn 0;  /* restart execution */\n\t}\n\tcase DUK_LJ_TYPE_RETURN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: finally part finishing with 'return' complation -> dismantle \"\n\t\t                     \"catcher, handle return, lj.value1=%!T\", tv1));\n\n\t\t/* Not necessary to unwind catch stack: return handling will\n\t\t * do it.  The finally flag of 'cat' is no longer set.  The\n\t\t * catch flag may be set, but it's not checked by return handling.\n\t\t */\n\n\t\tduk_push_tval(thr, tv1);\n\t\tret_result = duk__handle_return(thr, entry_act);\n\t\tif (ret_result == DUK__RETHAND_RESTART) {\n\t\t\treturn 0;  /* restart execution */\n\t\t}\n\t\tDUK_ASSERT(ret_result == DUK__RETHAND_FINISHED);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"exiting executor after ENDFIN and RETURN (pseudo) longjmp type\"));\n\t\treturn 1;  /* exit executor */\n\t}\n\tcase DUK_LJ_TYPE_BREAK:\n\tcase DUK_LJ_TYPE_CONTINUE: {\n\t\tduk_uint_t label_id;\n\t\tduk_small_uint_t lj_type;\n\n\t\t/* Not necessary to unwind catch stack: break/continue\n\t\t * handling will do it.  The finally flag of 'cat' is\n\t\t * no longer set.  The catch flag may be set, but it's\n\t\t * not checked by break/continue handling.\n\t\t */\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\tlabel_id = (duk_small_uint_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\t\tlabel_id = (duk_small_uint_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\tlj_type = cont_type;\n\t\tduk__handle_break_or_continue(thr, label_id, lj_type);\n\t\treturn 0;  /* restart execution */\n\t}\n\tdefault: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: finally part finishing with abrupt completion, lj_type=%ld -> \"\n\t\t                     \"dismantle catcher, re-throw error\",\n\t\t                     (long) cont_type));\n\n\t\tduk_err_setup_ljstate1(thr, (duk_small_uint_t) cont_type, tv1);\n\t\t/* No debugger Throw notify check on purpose (rethrow). */\n\n\t\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* always in executor */\n\t\tduk_err_longjmp(thr);\n\t\tDUK_UNREACHABLE();\n\t}\n\t}\n\n\tDUK_UNREACHABLE();\n\treturn 0;\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_initenum(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_small_uint_t b;\n\tduk_small_uint_t c;\n\n\t/*\n\t *  Enumeration semantics come from for-in statement, E5 Section 12.6.4.\n\t *  If called with 'null' or 'undefined', this opcode returns 'null' as\n\t *  the enumerator, which is special cased in NEXTENUM.  This simplifies\n\t *  the compiler part\n\t */\n\n\t/* B -> register for writing enumerator object\n\t * C -> value to be enumerated (register)\n\t */\n\tb = DUK_DEC_B(ins);\n\tc = DUK_DEC_C(ins);\n\n\tif (duk_is_null_or_undefined(thr, (duk_idx_t) c)) {\n\t\tduk_push_null(thr);\n\t\tduk_replace(thr, (duk_idx_t) b);\n\t} else {\n\t\tduk_dup(thr, (duk_idx_t) c);\n\t\tduk_to_object(thr, -1);\n\t\tduk_hobject_enumerator_create(thr, 0 /*enum_flags*/);  /* [ ... val ] --> [ ... enum ] */\n\t\tduk_replace(thr, (duk_idx_t) b);\n\t}\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_small_uint_t duk__handle_op_nextenum(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_small_uint_t b;\n\tduk_small_uint_t c;\n\tduk_small_uint_t pc_skip = 0;\n\n\t/*\n\t *  NEXTENUM checks whether the enumerator still has unenumerated\n\t *  keys.  If so, the next key is loaded to the target register\n\t *  and the next instruction is skipped.  Otherwise the next instruction\n\t *  will be executed, jumping out of the enumeration loop.\n\t */\n\n\t/* B -> target register for next key\n\t * C -> enum register\n\t */\n\tb = DUK_DEC_B(ins);\n\tc = DUK_DEC_C(ins);\n\n\tDUK_DDD(DUK_DDDPRINT(\"NEXTENUM: b->%!T, c->%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, (duk_idx_t) b),\n\t                     (duk_tval *) duk_get_tval(thr, (duk_idx_t) c)));\n\n\tif (duk_is_object(thr, (duk_idx_t) c)) {\n\t\t/* XXX: assert 'c' is an enumerator */\n\t\tduk_dup(thr, (duk_idx_t) c);\n\t\tif (duk_hobject_enumerator_next(thr, 0 /*get_value*/)) {\n\t\t\t/* [ ... enum ] -> [ ... next_key ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"enum active, next key is %!T, skip jump slot \",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tpc_skip = 1;\n\t\t} else {\n\t\t\t/* [ ... enum ] -> [ ... ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"enum finished, execute jump slot\"));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* valstack policy */\n\t\t\tthr->valstack_top++;\n\t\t}\n\t\tduk_replace(thr, (duk_idx_t) b);\n\t} else {\n\t\t/* 'null' enumerator case -> behave as with an empty enumerator */\n\t\tDUK_ASSERT(duk_is_null(thr, (duk_idx_t) c));\n\t\tDUK_DDD(DUK_DDDPRINT(\"enum is null, execute jump slot\"));\n\t}\n\n\treturn pc_skip;\n}\n\n/*\n *  Call handling helpers.\n */\n\nDUK_LOCAL duk_bool_t duk__executor_handle_call(duk_hthread *thr, duk_idx_t idx, duk_idx_t nargs, duk_small_uint_t call_flags) {\n\tduk_bool_t rc;\n\n\tduk_set_top_unsafe(thr, (duk_idx_t) (idx + nargs + 2));   /* [ ... func this arg1 ... argN ] */\n\n\t/* Attempt an Ecma-to-Ecma call setup.  If the call\n\t * target is (directly or indirectly) Reflect.construct(),\n\t * the call may change into a constructor call on the fly.\n\t */\n\trc = (duk_bool_t) duk_handle_call_unprotected(thr, idx, call_flags);\n\tif (rc != 0) {\n\t\t/* Ecma-to-ecma call possible, may or may not\n\t\t * be a tail call.  Avoid C recursion by\n\t\t * reusing current executor instance.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"ecma-to-ecma call setup possible, restart execution\"));\n\t\t/* curr_pc synced by duk_handle_call_unprotected() */\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\treturn rc;\n\t} else {\n\t\t/* Call was handled inline. */\n\t}\n\tDUK_ASSERT(thr->ptr_curr_pc != NULL);\n\treturn rc;\n}\n\n/*\n *  ECMAScript bytecode executor.\n *\n *  Resume execution for the current thread from its current activation.\n *  Returns when execution would return from the entry level activation,\n *  leaving a single return value on top of the stack.  Function calls\n *  and thread resumptions are handled internally.  If an error occurs,\n *  a longjmp() with type DUK_LJ_TYPE_THROW is called on the entry level\n *  setjmp() jmpbuf.\n *\n *  ECMAScript function calls and coroutine resumptions are handled\n *  internally (by the outer executor function) without recursive C calls.\n *  Other function calls are handled using duk_handle_call(), increasing\n *  C recursion depth.\n *\n *  Abrupt completions (= long control tranfers) are handled either\n *  directly by reconfiguring relevant stacks and restarting execution,\n *  or via a longjmp.  Longjmp-free handling is preferable for performance\n *  (especially Emscripten performance), and is used for: break, continue,\n *  and return.\n *\n *  For more detailed notes, see doc/execution.rst.\n *\n *  Also see doc/code-issues.rst for discussion of setjmp(), longjmp(),\n *  and volatile.\n */\n\n/* Presence of 'fun' is config based, there's a marginal performance\n * difference and the best option is architecture dependent.\n */\n#if defined(DUK_USE_EXEC_FUN_LOCAL)\n#define DUK__FUN()          fun\n#else\n#define DUK__FUN()          ((duk_hcompfunc *) DUK_ACT_GET_FUNC((thr)->callstack_curr))\n#endif\n\n/* Strict flag. */\n#define DUK__STRICT()       ((duk_small_uint_t) DUK_HOBJECT_HAS_STRICT((duk_hobject *) DUK__FUN()))\n\n/* Reg/const access macros: these are very footprint and performance sensitive\n * so modify with care.  Arguments are sometimes evaluated multiple times which\n * is not ideal.\n */\n#define DUK__REG(x)         (*(thr->valstack_bottom + (x)))\n#define DUK__REGP(x)        (thr->valstack_bottom + (x))\n#define DUK__CONST(x)       (*(consts + (x)))\n#define DUK__CONSTP(x)      (consts + (x))\n\n/* Reg/const access macros which take the 32-bit instruction and avoid an\n * explicit field decoding step by using shifts and masks.  These must be\n * kept in sync with duk_js_bytecode.h.  The shift/mask values are chosen\n * so that 'ins' can be shifted and masked and used as a -byte- offset\n * instead of a duk_tval offset which needs further shifting (which is an\n * issue on some, but not all, CPUs).\n */\n#define DUK__RCBIT_B           DUK_BC_REGCONST_B\n#define DUK__RCBIT_C           DUK_BC_REGCONST_C\n#if defined(DUK_USE_EXEC_REGCONST_OPTIMIZE)\n#if defined(DUK_USE_PACKED_TVAL)\n#define DUK__TVAL_SHIFT        3  /* sizeof(duk_tval) == 8 */\n#else\n#define DUK__TVAL_SHIFT        4  /* sizeof(duk_tval) == 16; not always the case so also asserted for */\n#endif\n#define DUK__SHIFT_A           (DUK_BC_SHIFT_A - DUK__TVAL_SHIFT)\n#define DUK__SHIFT_B           (DUK_BC_SHIFT_B - DUK__TVAL_SHIFT)\n#define DUK__SHIFT_C           (DUK_BC_SHIFT_C - DUK__TVAL_SHIFT)\n#define DUK__SHIFT_BC          (DUK_BC_SHIFT_BC - DUK__TVAL_SHIFT)\n#define DUK__MASK_A            (DUK_BC_UNSHIFTED_MASK_A << DUK__TVAL_SHIFT)\n#define DUK__MASK_B            (DUK_BC_UNSHIFTED_MASK_B << DUK__TVAL_SHIFT)\n#define DUK__MASK_C            (DUK_BC_UNSHIFTED_MASK_C << DUK__TVAL_SHIFT)\n#define DUK__MASK_BC           (DUK_BC_UNSHIFTED_MASK_BC << DUK__TVAL_SHIFT)\n#define DUK__BYTEOFF_A(ins)    (((ins) >> DUK__SHIFT_A) & DUK__MASK_A)\n#define DUK__BYTEOFF_B(ins)    (((ins) >> DUK__SHIFT_B) & DUK__MASK_B)\n#define DUK__BYTEOFF_C(ins)    (((ins) >> DUK__SHIFT_C) & DUK__MASK_C)\n#define DUK__BYTEOFF_BC(ins)   (((ins) >> DUK__SHIFT_BC) & DUK__MASK_BC)\n\n#define DUK__REGP_A(ins)       ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_A((ins))))\n#define DUK__REGP_B(ins)       ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_B((ins))))\n#define DUK__REGP_C(ins)       ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_C((ins))))\n#define DUK__REGP_BC(ins)      ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_BC((ins))))\n#define DUK__CONSTP_A(ins)     ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_A((ins))))\n#define DUK__CONSTP_B(ins)     ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_B((ins))))\n#define DUK__CONSTP_C(ins)     ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_C((ins))))\n#define DUK__CONSTP_BC(ins)    ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_BC((ins))))\n#define DUK__REGCONSTP_B(ins)  ((duk_tval *) (void *) ((duk_uint8_t *) (((ins) & DUK__RCBIT_B) ? consts : thr->valstack_bottom) + DUK__BYTEOFF_B((ins))))\n#define DUK__REGCONSTP_C(ins)  ((duk_tval *) (void *) ((duk_uint8_t *) (((ins) & DUK__RCBIT_C) ? consts : thr->valstack_bottom) + DUK__BYTEOFF_C((ins))))\n#else  /* DUK_USE_EXEC_REGCONST_OPTIMIZE */\n/* Safe alternatives, no assumption about duk_tval size. */\n#define DUK__REGP_A(ins)       DUK__REGP(DUK_DEC_A((ins)))\n#define DUK__REGP_B(ins)       DUK__REGP(DUK_DEC_B((ins)))\n#define DUK__REGP_C(ins)       DUK__REGP(DUK_DEC_C((ins)))\n#define DUK__REGP_BC(ins)      DUK__REGP(DUK_DEC_BC((ins)))\n#define DUK__CONSTP_A(ins)     DUK__CONSTP(DUK_DEC_A((ins)))\n#define DUK__CONSTP_B(ins)     DUK__CONSTP(DUK_DEC_B((ins)))\n#define DUK__CONSTP_C(ins)     DUK__CONSTP(DUK_DEC_C((ins)))\n#define DUK__CONSTP_BC(ins)    DUK__CONSTP(DUK_DEC_BC((ins)))\n#define DUK__REGCONSTP_B(ins)  ((((ins) & DUK__RCBIT_B) ? consts : thr->valstack_bottom) + DUK_DEC_B((ins)))\n#define DUK__REGCONSTP_C(ins)  ((((ins) & DUK__RCBIT_C) ? consts : thr->valstack_bottom) + DUK_DEC_C((ins)))\n#endif  /* DUK_USE_EXEC_REGCONST_OPTIMIZE */\n\n#if defined(DUK_USE_VERBOSE_EXECUTOR_ERRORS)\n#define DUK__INTERNAL_ERROR(msg)  do { \\\n\t\tDUK_ERROR_ERROR(thr, (msg)); \\\n\t\tDUK_WO_NORETURN(return;); \\\n\t} while (0)\n#else\n#define DUK__INTERNAL_ERROR(msg)  do { \\\n\t\tgoto internal_error; \\\n\t} while (0)\n#endif\n\n#define DUK__SYNC_CURR_PC()  do { \\\n\t\tduk_activation *duk__act; \\\n\t\tduk__act = thr->callstack_curr; \\\n\t\tduk__act->curr_pc = curr_pc; \\\n\t} while (0)\n#define DUK__SYNC_AND_NULL_CURR_PC()  do { \\\n\t\tduk_activation *duk__act; \\\n\t\tduk__act = thr->callstack_curr; \\\n\t\tduk__act->curr_pc = curr_pc; \\\n\t\tthr->ptr_curr_pc = NULL; \\\n\t} while (0)\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n#define DUK__LOOKUP_INDIRECT(idx) do { \\\n\t\t(idx) = (duk_uint_fast_t) duk_get_uint(thr, (duk_idx_t) (idx)); \\\n\t} while (0)\n#elif defined(DUK_USE_FASTINT)\n#define DUK__LOOKUP_INDIRECT(idx) do { \\\n\t\tduk_tval *tv_ind; \\\n\t\ttv_ind = DUK__REGP((idx)); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_ind)); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv_ind));  /* compiler guarantees */ \\\n\t\t(idx) = (duk_uint_fast_t) DUK_TVAL_GET_FASTINT_U32(tv_ind); \\\n\t} while (0)\n#else\n#define DUK__LOOKUP_INDIRECT(idx) do { \\\n\t\tduk_tval *tv_ind; \\\n\t\ttv_ind = DUK__REGP(idx); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_ind)); \\\n\t\tidx = (duk_uint_fast_t) DUK_TVAL_GET_NUMBER(tv_ind); \\\n\t} while (0)\n#endif\n\nDUK_LOCAL void duk__handle_executor_error(duk_heap *heap,\n                                          duk_activation *entry_act,\n                                          duk_int_t entry_call_recursion_depth,\n                                          duk_jmpbuf *entry_jmpbuf_ptr,\n                                          volatile duk_bool_t *out_delayed_catch_setup) {\n\tduk_small_uint_t lj_ret;\n\n\t/* Longjmp callers are required to sync-and-null thr->ptr_curr_pc\n\t * before longjmp.\n\t */\n\tDUK_ASSERT(heap->curr_thread != NULL);\n\tDUK_ASSERT(heap->curr_thread->ptr_curr_pc == NULL);\n\n\t/* XXX: signalling the need to shrink check (only if unwound) */\n\n\t/* Must be restored here to handle e.g. yields properly. */\n\theap->call_recursion_depth = entry_call_recursion_depth;\n\n\t/* Switch to caller's setjmp() catcher so that if an error occurs\n\t * during error handling, it is always propagated outwards instead\n\t * of causing an infinite loop in our own handler.\n\t */\n\theap->lj.jmpbuf_ptr = (duk_jmpbuf *) entry_jmpbuf_ptr;\n\n\tlj_ret = duk__handle_longjmp(heap->curr_thread, entry_act, out_delayed_catch_setup);\n\n\t/* Error handling complete, remove side effect protections.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(heap->error_not_allowed == 1);\n\theap->error_not_allowed = 0;\n#endif\n\tDUK_ASSERT(heap->pf_prevent_count > 0);\n\theap->pf_prevent_count--;\n\tDUK_DD(DUK_DDPRINT(\"executor error handled, pf_prevent_count updated to %ld\", (long) heap->pf_prevent_count));\n\n\tif (lj_ret == DUK__LONGJMP_RESTART) {\n\t\t/* Restart bytecode execution, possibly with a changed thread. */\n\t\tDUK_REFZERO_CHECK_SLOW(heap->curr_thread);\n\t} else {\n\t\t/* If an error is propagated, don't run refzero checks here.\n\t\t * The next catcher will deal with that.  Pf_prevent_count\n\t\t * will be re-bumped by the longjmp.\n\t\t */\n\n\t\tDUK_ASSERT(lj_ret == DUK__LONGJMP_RETHROW);  /* Rethrow error to calling state. */\n\t\tDUK_ASSERT(heap->lj.jmpbuf_ptr == entry_jmpbuf_ptr);  /* Longjmp handling has restored jmpbuf_ptr. */\n\n\t\t/* Thread may have changed, e.g. YIELD converted to THROW. */\n\t\tduk_err_longjmp(heap->curr_thread);\n\t\tDUK_UNREACHABLE();\n\t}\n}\n\n/* Outer executor with setjmp/longjmp handling. */\nDUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {\n\t/* Entry level info. */\n\tduk_hthread *entry_thread;\n\tduk_activation *entry_act;\n\tduk_int_t entry_call_recursion_depth;\n\tduk_jmpbuf *entry_jmpbuf_ptr;\n\tduk_jmpbuf our_jmpbuf;\n\tduk_heap *heap;\n\tvolatile duk_bool_t delayed_catch_setup = 0;\n\n\tDUK_ASSERT(exec_thr != NULL);\n\tDUK_ASSERT(exec_thr->heap != NULL);\n\tDUK_ASSERT(exec_thr->heap->curr_thread != NULL);\n\tDUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR((duk_heaphdr *) exec_thr);\n\tDUK_ASSERT(exec_thr->callstack_top >= 1);  /* at least one activation, ours */\n\tDUK_ASSERT(exec_thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(exec_thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(exec_thr->callstack_curr)));\n\n\tDUK_GC_TORTURE(exec_thr->heap);\n\n\tentry_thread = exec_thr;\n\theap = entry_thread->heap;\n\tentry_act = entry_thread->callstack_curr;\n\tDUK_ASSERT(entry_act != NULL);\n\tentry_call_recursion_depth = entry_thread->heap->call_recursion_depth;\n\tentry_jmpbuf_ptr = entry_thread->heap->lj.jmpbuf_ptr;\n\n\t/*\n\t *  Note: we currently assume that the setjmp() catchpoint is\n\t *  not re-entrant (longjmp() cannot be called more than once\n\t *  for a single setjmp()).\n\t *\n\t *  See doc/code-issues.rst for notes on variable assignment\n\t *  before and after setjmp().\n\t */\n\n\tfor (;;) {\n\t\theap->lj.jmpbuf_ptr = &our_jmpbuf;\n\t\tDUK_ASSERT(heap->lj.jmpbuf_ptr != NULL);\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\ttry {\n#else\n\t\tDUK_ASSERT(heap->lj.jmpbuf_ptr == &our_jmpbuf);\n\t\tif (DUK_SETJMP(our_jmpbuf.jb) == 0) {\n#endif\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"after setjmp, delayed catch setup: %ld\\n\", (long) delayed_catch_setup));\n\n\t\t\tif (DUK_UNLIKELY(delayed_catch_setup != 0)) {\n\t\t\t\tduk_hthread *thr = entry_thread->heap->curr_thread;\n\n\t\t\t\tdelayed_catch_setup = 0;\n\t\t\t\tduk__handle_catch_part2(thr);\n\t\t\t\tDUK_ASSERT(delayed_catch_setup == 0);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"top after delayed catch setup: %ld\", (long) duk_get_top(entry_thread)));\n\t\t\t}\n\n\t\t\t/* Execute bytecode until returned or longjmp(). */\n\t\t\tduk__js_execute_bytecode_inner(entry_thread, entry_act);\n\n\t\t\t/* Successful return: restore jmpbuf and return to caller. */\n\t\t\theap->lj.jmpbuf_ptr = entry_jmpbuf_ptr;\n\n\t\t\treturn;\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\t} catch (duk_internal_exception &exc) {\n#else\n\t\t} else {\n#endif\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\t\tDUK_UNREF(exc);\n#endif\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"longjmp caught by bytecode executor\"));\n\t\t\tDUK_STATS_INC(exec_thr->heap, stats_exec_throw);\n\n\t\t\tduk__handle_executor_error(heap,\n\t\t\t                           entry_act,\n\t\t\t                           entry_call_recursion_depth,\n\t\t\t                           entry_jmpbuf_ptr,\n\t\t\t\t\t\t   &delayed_catch_setup);\n\t\t}\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\tcatch (duk_fatal_exception &exc) {\n\t\t\tDUK_D(DUK_DPRINT(\"rethrow duk_fatal_exception\"));\n\t\t\tthrow;\n\t\t} catch (std::exception &exc) {\n\t\t\tconst char *what = exc.what();\n\t\t\tif (!what) {\n\t\t\t\twhat = \"unknown\";\n\t\t\t}\n\t\t\tDUK_D(DUK_DPRINT(\"unexpected c++ std::exception (perhaps thrown by user code)\"));\n\t\t\tDUK_STATS_INC(exec_thr->heap, stats_exec_throw);\n\t\t\ttry {\n\t\t\t\tDUK_ASSERT(heap->curr_thread != NULL);\n\t\t\t\tDUK_ERROR_FMT1(heap->curr_thread, DUK_ERR_TYPE_ERROR, \"caught invalid c++ std::exception '%s' (perhaps thrown by user code)\", what);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t} catch (duk_internal_exception exc) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ std::exception\"));\n\t\t\t\tDUK_UNREF(exc);\n\t\t\t\tduk__handle_executor_error(heap,\n\t\t\t\t                           entry_act,\n\t\t\t\t                           entry_call_recursion_depth,\n\t\t\t\t                           entry_jmpbuf_ptr,\n\t\t\t\t\t\t\t   &delayed_catch_setup);\n\t\t\t}\n\t\t} catch (...) {\n\t\t\tDUK_D(DUK_DPRINT(\"unexpected c++ exception (perhaps thrown by user code)\"));\n\t\t\tDUK_STATS_INC(exec_thr->heap, stats_exec_throw);\n\t\t\ttry {\n\t\t\t\tDUK_ASSERT(heap->curr_thread != NULL);\n\t\t\t\tDUK_ERROR_TYPE(heap->curr_thread, \"caught invalid c++ exception (perhaps thrown by user code)\");\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t} catch (duk_internal_exception exc) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ exception\"));\n\t\t\t\tDUK_UNREF(exc);\n\t\t\t\tduk__handle_executor_error(heap,\n\t\t\t\t                           entry_act,\n\t\t\t\t                           entry_call_recursion_depth,\n\t\t\t\t                           entry_jmpbuf_ptr,\n\t\t\t\t\t\t\t   &delayed_catch_setup);\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Inner executor, performance critical. */\nDUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, duk_activation *entry_act) {\n\t/* Current PC, accessed by other functions through thr->ptr_to_curr_pc.\n\t * Critical for performance.  It would be safest to make this volatile,\n\t * but that eliminates performance benefits; aliasing guarantees\n\t * should be enough though.\n\t */\n\tduk_instr_t *curr_pc;         /* bytecode has a stable pointer */\n\n\t/* Hot variables for interpretation.  Critical for performance,\n\t * but must add sparingly to minimize register shuffling.\n\t */\n\tduk_hthread *thr;             /* stable */\n\tduk_tval *consts;             /* stable */\n\tduk_uint_fast32_t ins;\n\t/* 'funcs' is quite rarely used, so no local for it */\n#if defined(DUK_USE_EXEC_FUN_LOCAL)\n\tduk_hcompfunc *fun;\n#else\n\t/* 'fun' is quite rarely used, so no local for it */\n#endif\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\tduk_int_t int_ctr;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_size_t valstack_top_base;    /* valstack top, should match before interpreting each op (no leftovers) */\n#endif\n\n\t/* Optimized reg/const access macros assume sizeof(duk_tval) to be\n\t * either 8 or 16.  Heap allocation checks this even without asserts\n\t * enabled now because it can't be autodetected in duk_config.h.\n\t */\n#if 1\n#if defined(DUK_USE_PACKED_TVAL)\n\tDUK_ASSERT(sizeof(duk_tval) == 8);\n#else\n\tDUK_ASSERT(sizeof(duk_tval) == 16);\n#endif\n#endif\n\n\tDUK_GC_TORTURE(entry_thread->heap);\n\n\t/*\n\t *  Restart execution by reloading thread state.\n\t *\n\t *  Note that 'thr' and any thread configuration may have changed,\n\t *  so all local variables are suspect and we need to reinitialize.\n\t *\n\t *  The number of local variables should be kept to a minimum: if\n\t *  the variables are spilled, they will need to be loaded from\n\t *  memory anyway.\n\t *\n\t *  Any 'goto restart_execution;' code path in opcode dispatch must\n\t *  ensure 'curr_pc' is synced back to act->curr_pc before the goto\n\t *  takes place.\n\t *\n\t *  The interpreter must be very careful with memory pointers, as\n\t *  many pointers are not guaranteed to be 'stable' and may be\n\t *  reallocated and relocated on-the-fly quite easily (e.g. by a\n\t *  memory allocation or a property access).\n\t *\n\t *  The following are assumed to have stable pointers:\n\t *    - the current thread\n\t *    - the current function\n\t *    - the bytecode, constant table, inner function table of the\n\t *      current function (as they are a part of the function allocation)\n\t *\n\t *  The following are assumed to have semi-stable pointers:\n\t *    - the current activation entry: stable as long as callstack\n\t *      is not changed (reallocated by growing or shrinking), or\n\t *      by any garbage collection invocation (through finalizers)\n\t *    - Note in particular that ANY DECREF can invalidate the\n\t *      activation pointer, so for the most part a fresh lookup\n\t *      is required\n\t *\n\t *  The following are not assumed to have stable pointers at all:\n\t *    - the value stack (registers) of the current thread\n\t *\n\t *  See execution.rst for discussion.\n\t */\n\n restart_execution:\n\n\t/* Lookup current thread; use the stable 'entry_thread' for this to\n\t * avoid clobber warnings.  Any valid, reachable 'thr' value would be\n\t * fine for this, so using 'entry_thread' is just to silence warnings.\n\t */\n\tthr = entry_thread->heap->curr_thread;\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\tDUK_GC_TORTURE(thr->heap);\n\n\tthr->ptr_curr_pc = &curr_pc;\n\n\t/* Relookup and initialize dispatch loop variables.  Debugger check. */\n\t{\n\t\tduk_activation *act;\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\tduk_hcompfunc *fun;\n#endif\n\n\t\t/* Assume interrupt init/counter are properly initialized here. */\n\t\t/* Assume that thr->valstack_bottom has been set-up before getting here. */\n\n\t\tact = thr->callstack_curr;\n\t\tDUK_ASSERT(act != NULL);\n\t\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\t\tDUK_ASSERT(fun != NULL);\n\t\tDUK_ASSERT(thr->valstack_top - thr->valstack_bottom == fun->nregs);\n\t\tconsts = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, fun);\n\t\tDUK_ASSERT(consts != NULL);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tif (DUK_UNLIKELY(duk_debug_is_attached(thr->heap) && !thr->heap->dbg_processing)) {\n\t\t\tduk__executor_recheck_debugger(thr, act, fun);\n\t\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\tvalstack_top_base = (duk_size_t) (thr->valstack_top - thr->valstack);\n#endif\n\n\t\t/* Set up curr_pc for opcode dispatch. */\n\t\tcurr_pc = act->curr_pc;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"restarting execution, thr %p, act idx %ld, fun %p,\"\n\t                   \"consts %p, funcs %p, lev %ld, regbot %ld, regtop %ld, \"\n\t                   \"preventcount=%ld\",\n\t                   (void *) thr,\n\t                   (long) (thr->callstack_top - 1),\n\t                   (void *) DUK__FUN(),\n\t                   (void *) DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, DUK__FUN()),\n\t                   (void *) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, DUK__FUN()),\n\t                   (long) (thr->callstack_top - 1),\n\t                   (long) (thr->valstack_bottom - thr->valstack),\n\t                   (long) (thr->valstack_top - thr->valstack),\n\t                   (long) thr->callstack_preventcount));\n\n\t/* Dispatch loop. */\n\n\tfor (;;) {\n\t\tduk_uint8_t op;\n\n\t\tDUK_ASSERT(thr->callstack_top >= 1);\n\t\tDUK_ASSERT(thr->valstack_top - thr->valstack_bottom == DUK__FUN()->nregs);\n\t\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack) == valstack_top_base);\n\n\t\t/* Executor interrupt counter check, used to implement breakpoints,\n\t\t * debugging interface, execution timeouts, etc.  The counter is heap\n\t\t * specific but is maintained in the current thread to make the check\n\t\t * as fast as possible.  The counter is copied back to the heap struct\n\t\t * whenever a thread switch occurs by the DUK_HEAP_SWITCH_THREAD() macro.\n\t\t */\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\t\tint_ctr = thr->interrupt_counter;\n\t\tif (DUK_LIKELY(int_ctr > 0)) {\n\t\t\tthr->interrupt_counter = int_ctr - 1;\n\t\t} else {\n\t\t\t/* Trigger at zero or below */\n\t\t\tduk_small_uint_t exec_int_ret;\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_exec_interrupt);\n\n\t\t\t/* Write curr_pc back for the debugger. */\n\t\t\t{\n\t\t\t\tduk_activation *act;\n\t\t\t\tDUK_ASSERT(thr->callstack_top > 0);\n\t\t\t\tact = thr->callstack_curr;\n\t\t\t\tDUK_ASSERT(act != NULL);\n\t\t\t\tact->curr_pc = (duk_instr_t *) curr_pc;\n\t\t\t}\n\n\t\t\t/* Forced restart caused by a function return; must recheck\n\t\t\t * debugger breakpoints before checking line transitions,\n\t\t\t * see GH-303.  Restart and then handle interrupt_counter\n\t\t\t * zero again.\n\t\t\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\t\tif (thr->heap->dbg_force_restart) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"dbg_force_restart flag forced restart execution\"));  /* GH-303 */\n\t\t\t\tthr->heap->dbg_force_restart = 0;\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n#endif\n\n\t\t\texec_int_ret = duk__executor_interrupt(thr);\n\t\t\tif (exec_int_ret == DUK__INT_RESTART) {\n\t\t\t\t/* curr_pc synced back above */\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n\t\t}\n#endif  /* DUK_USE_INTERRUPT_COUNTER */\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\t\t/* For cross-checking during development: ensure dispatch count\n\t\t * matches cumulative interrupt counter init value sums.\n\t\t */\n\t\tthr->heap->inst_count_exec++;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS) || defined(DUK_USE_DEBUG)\n\t\t{\n\t\t\tduk_activation *act;\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(curr_pc >= DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, DUK__FUN()));\n\t\t\tDUK_ASSERT(curr_pc < DUK_HCOMPFUNC_GET_CODE_END(thr->heap, DUK__FUN()));\n\t\t\tDUK_UNREF(act);  /* if debugging disabled */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"executing bytecode: pc=%ld, ins=0x%08lx, op=%ld, valstack_top=%ld/%ld, nregs=%ld  -->  %!I\",\n\t\t\t                     (long) (curr_pc - DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, DUK__FUN())),\n\t\t\t                     (unsigned long) *curr_pc,\n\t\t\t                     (long) DUK_DEC_OP(*curr_pc),\n\t\t\t                     (long) (thr->valstack_top - thr->valstack),\n\t\t\t                     (long) (thr->valstack_end - thr->valstack),\n\t\t\t                     (long) (DUK__FUN() ? DUK__FUN()->nregs : -1),\n\t\t\t                     (duk_instr_t) *curr_pc));\n\t\t}\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\t/* Quite heavy assert: check valstack policy.  Improper\n\t\t * shuffle instructions can write beyond valstack_top/end\n\t\t * so this check catches them in the act.\n\t\t */\n\t\t{\n\t\t\tduk_tval *tv;\n\t\t\ttv = thr->valstack_top;\n\t\t\twhile (tv != thr->valstack_end) {\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\t\t\ttv++;\n\t\t\t}\n\t\t}\n#endif\n\n\t\tins = *curr_pc++;\n\t\tDUK_STATS_INC(thr->heap, stats_exec_opcodes);\n\n\t\t/* Typing: use duk_small_(u)int_fast_t when decoding small\n\t\t * opcode fields (op, A, B, C, BC) which fit into 16 bits\n\t\t * and duk_(u)int_fast_t when decoding larger fields (e.g.\n\t\t * ABC).  Use unsigned variant by default, signed when the\n\t\t * value is used in signed arithmetic.  Using variable names\n\t\t * such as 'a', 'b', 'c', 'bc', etc makes it easier to spot\n\t\t * typing mismatches.\n\t\t */\n\n\t\t/* Switch based on opcode.  Cast to 8-bit unsigned value and\n\t\t * use a fully populated case clauses so that the compiler\n\t\t * will (at least usually) omit a bounds check.\n\t\t */\n\t\top = (duk_uint8_t) DUK_DEC_OP(ins);\n\t\tswitch (op) {\n\n\t\t/* Some useful macros.  These access inner executor variables\n\t\t * directly so they only apply within the executor.\n\t\t */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n#define DUK__REPLACE_TOP_A_BREAK() { goto replace_top_a; }\n#define DUK__REPLACE_TOP_BC_BREAK() { goto replace_top_bc; }\n#define DUK__REPLACE_BOOL_A_BREAK(bval) { \\\n\t\tduk_bool_t duk__bval; \\\n\t\tduk__bval = (bval); \\\n\t\tDUK_ASSERT(duk__bval == 0 || duk__bval == 1); \\\n\t\tduk_push_boolean(thr, duk__bval); \\\n\t\tDUK__REPLACE_TOP_A_BREAK(); \\\n\t}\n#else\n#define DUK__REPLACE_TOP_A_BREAK() { DUK__REPLACE_TO_TVPTR(thr, DUK__REGP_A(ins)); break; }\n#define DUK__REPLACE_TOP_BC_BREAK() { DUK__REPLACE_TO_TVPTR(thr, DUK__REGP_BC(ins)); break; }\n#define DUK__REPLACE_BOOL_A_BREAK(bval) { \\\n\t\tduk_bool_t duk__bval; \\\n\t\tduk_tval *duk__tvdst; \\\n\t\tduk__bval = (bval); \\\n\t\tDUK_ASSERT(duk__bval == 0 || duk__bval == 1); \\\n\t\tduk__tvdst = DUK__REGP_A(ins); \\\n\t\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, duk__tvdst, duk__bval); \\\n\t\tbreak; \\\n\t}\n#endif\n\n\t\t/* XXX: 12 + 12 bit variant might make sense too, for both reg and\n\t\t * const loads.\n\t\t */\n\n\t\t/* For LDREG, STREG, LDCONST footprint optimized variants would just\n\t\t * duk_dup() + duk_replace(), but because they're used quite a lot\n\t\t * they're currently intentionally not size optimized.\n\t\t */\n\t\tcase DUK_OP_LDREG: {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\ttv2 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv1, tv2);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_STREG: {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\ttv2 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv2, tv1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_LDCONST: {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\ttv2 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv1, tv2);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\n\t\t/* LDINT and LDINTX are intended to load an arbitrary signed\n\t\t * 32-bit value.  Only an LDINT+LDINTX sequence is supported.\n\t\t * This also guarantees all values remain fastints.\n\t\t */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_LDINT: {\n\t\t\tduk_int32_t val;\n\n\t\t\tval = (duk_int32_t) DUK_DEC_BC(ins) - (duk_int32_t) DUK_BC_LDINT_BIAS;\n\t\t\tduk_push_int(thr, val);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n\t\tcase DUK_OP_LDINTX: {\n\t\t\tduk_int32_t val;\n\n\t\t\tval = (duk_int32_t) duk_get_int(thr, DUK_DEC_A(ins));\n\t\t\tval = (val << DUK_BC_LDINTX_SHIFT) + (duk_int32_t) DUK_DEC_BC(ins);  /* no bias */\n\t\t\tduk_push_int(thr, val);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_LDINT: {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_int32_t val;\n\n\t\t\tval = (duk_int32_t) DUK_DEC_BC(ins) - (duk_int32_t) DUK_BC_LDINT_BIAS;\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_I32_UPDREF(thr, tv1, val);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDINTX: {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_int32_t val;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\t\tval = DUK_TVAL_GET_FASTINT_I32(tv1);\n#else\n\t\t\t/* XXX: fast double-to-int conversion, we know number is integer in [-0x80000000,0xffffffff]. */\n\t\t\tval = (duk_int32_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\t\tval = (duk_int32_t) ((duk_uint32_t) val << DUK_BC_LDINTX_SHIFT) + (duk_int32_t) DUK_DEC_BC(ins);  /* no bias */\n\t\t\tDUK_TVAL_SET_I32_UPDREF(thr, tv1, val);  /* side effects */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_LDTHIS: {\n\t\t\tduk_push_this(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\t\tcase DUK_OP_LDUNDEF: {\n\t\t\tduk_to_undefined(thr, (duk_idx_t) DUK_DEC_BC(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDNULL: {\n\t\t\tduk_to_null(thr, (duk_idx_t) DUK_DEC_BC(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDTRUE: {\n\t\t\tduk_push_true(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\t\tcase DUK_OP_LDFALSE: {\n\t\t\tduk_push_false(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_LDTHIS: {\n\t\t\t/* Note: 'this' may be bound to any value, not just an object */\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\ttv2 = thr->valstack_bottom - 1;  /* 'this binding' is just under bottom */\n\t\t\tDUK_ASSERT(tv2 >= thr->valstack);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv1, tv2);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDUNDEF: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDNULL: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_NULL_UPDREF(thr, tv1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDTRUE: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv1, 1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDFALSE: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv1, 0);  /* side effects */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\tcase DUK_OP_BNOT: {\n\t\t\tduk__vm_bitwise_not(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_LNOT: {\n\t\t\tduk__vm_logical_not(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_UNM:\n\t\tcase DUK_OP_UNP: {\n\t\t\tduk__vm_arith_unary_op(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins), op);\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_UNM: {\n\t\t\tduk__vm_arith_unary_op(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins), DUK_OP_UNM);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_UNP: {\n\t\t\tduk__vm_arith_unary_op(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins), DUK_OP_UNP);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_TYPEOF: {\n\t\t\tduk_small_uint_t stridx;\n\n\t\t\tstridx = duk_js_typeof_stridx(DUK__REGP_BC(ins));\n\t\t\tDUK_ASSERT_STRIDX_VALID(stridx);\n\t\t\tduk_push_hstring_stridx(thr, stridx);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_TYPEOF: {\n\t\t\tduk_tval *tv;\n\t\t\tduk_small_uint_t stridx;\n\t\t\tduk_hstring *h_str;\n\n\t\t\ttv = DUK__REGP_BC(ins);\n\t\t\tstridx = duk_js_typeof_stridx(tv);\n\t\t\tDUK_ASSERT_STRIDX_VALID(stridx);\n\t\t\th_str = DUK_HTHREAD_GET_STRING(thr, stridx);\n\t\t\ttv = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_STRING_UPDREF(thr, tv, h_str);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\tcase DUK_OP_TYPEOFID: {\n\t\t\tduk_small_uint_t stridx;\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_hstring *h_str;\n#endif\n\t\t\tduk_activation *act;\n\t\t\tduk_hstring *name;\n\t\t\tduk_tval *tv;\n\n\t\t\t/* A -> target register\n\t\t\t * BC -> constant index of identifier name\n\t\t\t */\n\n\t\t\ttv = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv));\n\t\t\tname = DUK_TVAL_GET_STRING(tv);\n\t\t\ttv = NULL;  /* lookup has side effects */\n\t\t\tact = thr->callstack_curr;\n\t\t\tif (duk_js_getvar_activation(thr, act, name, 0 /*throw*/)) {\n\t\t\t\t/* -> [... val this] */\n\t\t\t\ttv = DUK_GET_TVAL_NEGIDX(thr, -2);\n\t\t\t\tstridx = duk_js_typeof_stridx(tv);\n\t\t\t\ttv = NULL;  /* no longer needed */\n\t\t\t\tduk_pop_2_unsafe(thr);\n\t\t\t} else {\n\t\t\t\t/* unresolvable, no stack changes */\n\t\t\t\tstridx = DUK_STRIDX_LC_UNDEFINED;\n\t\t\t}\n\t\t\tDUK_ASSERT_STRIDX_VALID(stridx);\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_push_hstring_stridx(thr, stridx);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\t\th_str = DUK_HTHREAD_GET_STRING(thr, stridx);\n\t\t\ttv = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_STRING_UPDREF(thr, tv, h_str);\n\t\t\tbreak;\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\t}\n\n\t\t/* Equality: E5 Sections 11.9.1, 11.9.3 */\n\n#define DUK__EQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_equals(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__NEQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_equals(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\ttmp ^= 1; \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__SEQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_strict_equals((barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__SNEQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_strict_equals((barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\ttmp ^= 1; \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_EQ_RR:\n\t\tcase DUK_OP_EQ_CR:\n\t\tcase DUK_OP_EQ_RC:\n\t\tcase DUK_OP_EQ_CC:\n\t\t\tDUK__EQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_NEQ_RR:\n\t\tcase DUK_OP_NEQ_CR:\n\t\tcase DUK_OP_NEQ_RC:\n\t\tcase DUK_OP_NEQ_CC:\n\t\t\tDUK__NEQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_SEQ_RR:\n\t\tcase DUK_OP_SEQ_CR:\n\t\tcase DUK_OP_SEQ_RC:\n\t\tcase DUK_OP_SEQ_CC:\n\t\t\tDUK__SEQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_SNEQ_RR:\n\t\tcase DUK_OP_SNEQ_CR:\n\t\tcase DUK_OP_SNEQ_RC:\n\t\tcase DUK_OP_SNEQ_CC:\n\t\t\tDUK__SNEQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_EQ_RR:\n\t\t\tDUK__EQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_EQ_CR:\n\t\t\tDUK__EQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_EQ_RC:\n\t\t\tDUK__EQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_EQ_CC:\n\t\t\tDUK__EQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_NEQ_RR:\n\t\t\tDUK__NEQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_NEQ_CR:\n\t\t\tDUK__NEQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_NEQ_RC:\n\t\t\tDUK__NEQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_NEQ_CC:\n\t\t\tDUK__NEQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SEQ_RR:\n\t\t\tDUK__SEQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SEQ_CR:\n\t\t\tDUK__SEQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SEQ_RC:\n\t\t\tDUK__SEQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SEQ_CC:\n\t\t\tDUK__SEQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SNEQ_RR:\n\t\t\tDUK__SNEQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SNEQ_CR:\n\t\t\tDUK__SNEQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SNEQ_RC:\n\t\t\tDUK__SNEQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SNEQ_CC:\n\t\t\tDUK__SNEQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#define DUK__COMPARE_BODY(arg1,arg2,flags) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_compare_helper(thr, (arg1), (arg2), (flags)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__GT_BODY(barg,carg) DUK__COMPARE_BODY((carg), (barg), 0)\n#define DUK__GE_BODY(barg,carg) DUK__COMPARE_BODY((barg), (carg), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST | DUK_COMPARE_FLAG_NEGATE)\n#define DUK__LT_BODY(barg,carg) DUK__COMPARE_BODY((barg), (carg), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST)\n#define DUK__LE_BODY(barg,carg) DUK__COMPARE_BODY((carg), (barg), DUK_COMPARE_FLAG_NEGATE)\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_GT_RR:\n\t\tcase DUK_OP_GT_CR:\n\t\tcase DUK_OP_GT_RC:\n\t\tcase DUK_OP_GT_CC:\n\t\t\tDUK__GT_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_GE_RR:\n\t\tcase DUK_OP_GE_CR:\n\t\tcase DUK_OP_GE_RC:\n\t\tcase DUK_OP_GE_CC:\n\t\t\tDUK__GE_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_LT_RR:\n\t\tcase DUK_OP_LT_CR:\n\t\tcase DUK_OP_LT_RC:\n\t\tcase DUK_OP_LT_CC:\n\t\t\tDUK__LT_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_LE_RR:\n\t\tcase DUK_OP_LE_CR:\n\t\tcase DUK_OP_LE_RC:\n\t\tcase DUK_OP_LE_CC:\n\t\t\tDUK__LE_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_GT_RR:\n\t\t\tDUK__GT_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GT_CR:\n\t\t\tDUK__GT_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GT_RC:\n\t\t\tDUK__GT_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GT_CC:\n\t\t\tDUK__GT_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GE_RR:\n\t\t\tDUK__GE_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GE_CR:\n\t\t\tDUK__GE_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GE_RC:\n\t\t\tDUK__GE_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GE_CC:\n\t\t\tDUK__GE_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LT_RR:\n\t\t\tDUK__LT_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LT_CR:\n\t\t\tDUK__LT_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LT_RC:\n\t\t\tDUK__LT_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LT_CC:\n\t\t\tDUK__LT_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LE_RR:\n\t\t\tDUK__LE_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LE_CR:\n\t\t\tDUK__LE_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LE_RC:\n\t\t\tDUK__LE_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LE_CC:\n\t\t\tDUK__LE_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* No size optimized variant at present for IF. */\n\t\tcase DUK_OP_IFTRUE_R: {\n\t\t\tif (duk_js_toboolean(DUK__REGP_BC(ins)) != 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_IFTRUE_C: {\n\t\t\tif (duk_js_toboolean(DUK__CONSTP_BC(ins)) != 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_IFFALSE_R: {\n\t\t\tif (duk_js_toboolean(DUK__REGP_BC(ins)) == 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_IFFALSE_C: {\n\t\t\tif (duk_js_toboolean(DUK__CONSTP_BC(ins)) == 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_ADD_RR:\n\t\tcase DUK_OP_ADD_CR:\n\t\tcase DUK_OP_ADD_RC:\n\t\tcase DUK_OP_ADD_CC: {\n\t\t\t/* XXX: could leave value on stack top and goto replace_top_a; */\n\t\t\tduk__vm_arith_add(thr, DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_ADD_RR: {\n\t\t\tduk__vm_arith_add(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_ADD_CR: {\n\t\t\tduk__vm_arith_add(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_ADD_RC: {\n\t\t\tduk__vm_arith_add(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_ADD_CC: {\n\t\t\tduk__vm_arith_add(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_SUB_RR:\n\t\tcase DUK_OP_SUB_CR:\n\t\tcase DUK_OP_SUB_RC:\n\t\tcase DUK_OP_SUB_CC:\n\t\tcase DUK_OP_MUL_RR:\n\t\tcase DUK_OP_MUL_CR:\n\t\tcase DUK_OP_MUL_RC:\n\t\tcase DUK_OP_MUL_CC:\n\t\tcase DUK_OP_DIV_RR:\n\t\tcase DUK_OP_DIV_CR:\n\t\tcase DUK_OP_DIV_RC:\n\t\tcase DUK_OP_DIV_CC:\n\t\tcase DUK_OP_MOD_RR:\n\t\tcase DUK_OP_MOD_CR:\n\t\tcase DUK_OP_MOD_RC:\n\t\tcase DUK_OP_MOD_CC:\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tcase DUK_OP_EXP_RR:\n\t\tcase DUK_OP_EXP_CR:\n\t\tcase DUK_OP_EXP_RC:\n\t\tcase DUK_OP_EXP_CC:\n#endif  /* DUK_USE_ES7_EXP_OPERATOR */\n\t\t{\n\t\t\t/* XXX: could leave value on stack top and goto replace_top_a; */\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins), DUK_DEC_A(ins), op);\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_SUB_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_SUB_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_SUB_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_SUB_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tcase DUK_OP_EXP_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_EXP_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_EXP_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_EXP_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_ES7_EXP_OPERATOR */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_BAND_RR:\n\t\tcase DUK_OP_BAND_CR:\n\t\tcase DUK_OP_BAND_RC:\n\t\tcase DUK_OP_BAND_CC:\n\t\tcase DUK_OP_BOR_RR:\n\t\tcase DUK_OP_BOR_CR:\n\t\tcase DUK_OP_BOR_RC:\n\t\tcase DUK_OP_BOR_CC:\n\t\tcase DUK_OP_BXOR_RR:\n\t\tcase DUK_OP_BXOR_CR:\n\t\tcase DUK_OP_BXOR_RC:\n\t\tcase DUK_OP_BXOR_CC:\n\t\tcase DUK_OP_BASL_RR:\n\t\tcase DUK_OP_BASL_CR:\n\t\tcase DUK_OP_BASL_RC:\n\t\tcase DUK_OP_BASL_CC:\n\t\tcase DUK_OP_BLSR_RR:\n\t\tcase DUK_OP_BLSR_CR:\n\t\tcase DUK_OP_BLSR_RC:\n\t\tcase DUK_OP_BLSR_CC:\n\t\tcase DUK_OP_BASR_RR:\n\t\tcase DUK_OP_BASR_CR:\n\t\tcase DUK_OP_BASR_RC:\n\t\tcase DUK_OP_BASR_CC: {\n\t\t\t/* XXX: could leave value on stack top and goto replace_top_a; */\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins), DUK_DEC_A(ins), op);\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_BAND_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BAND_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BAND_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BAND_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* For INSTOF and IN, B is always a register. */\n#define DUK__INSTOF_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_instanceof(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__IN_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_in(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_INSTOF_RR:\n\t\tcase DUK_OP_INSTOF_CR:\n\t\tcase DUK_OP_INSTOF_RC:\n\t\tcase DUK_OP_INSTOF_CC:\n\t\t\tDUK__INSTOF_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_IN_RR:\n\t\tcase DUK_OP_IN_CR:\n\t\tcase DUK_OP_IN_RC:\n\t\tcase DUK_OP_IN_CC:\n\t\t\tDUK__IN_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_INSTOF_RR:\n\t\t\tDUK__INSTOF_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_INSTOF_CR:\n\t\t\tDUK__INSTOF_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_INSTOF_RC:\n\t\t\tDUK__INSTOF_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_INSTOF_CC:\n\t\t\tDUK__INSTOF_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_IN_RR:\n\t\t\tDUK__IN_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_IN_CR:\n\t\t\tDUK__IN_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_IN_RC:\n\t\t\tDUK__IN_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_IN_CC:\n\t\t\tDUK__IN_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* Pre/post inc/dec for register variables, important for loops. */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_PREINCR:\n\t\tcase DUK_OP_PREDECR:\n\t\tcase DUK_OP_POSTINCR:\n\t\tcase DUK_OP_POSTDECR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), op);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREINCV:\n\t\tcase DUK_OP_PREDECV:\n\t\tcase DUK_OP_POSTINCV:\n\t\tcase DUK_OP_POSTDECV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), op, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_PREINCR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_PREINCR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREDECR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_PREDECR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTINCR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_POSTINCR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTDECR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_POSTDECR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREINCV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_PREINCV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREDECV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_PREDECV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTINCV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_POSTINCV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTDECV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_POSTDECV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* XXX: Move to separate helper, optimize for perf/size separately. */\n\t\t/* Preinc/predec for object properties. */\n\t\tcase DUK_OP_PREINCP_RR:\n\t\tcase DUK_OP_PREINCP_CR:\n\t\tcase DUK_OP_PREINCP_RC:\n\t\tcase DUK_OP_PREINCP_CC:\n\t\tcase DUK_OP_PREDECP_RR:\n\t\tcase DUK_OP_PREDECP_CR:\n\t\tcase DUK_OP_PREDECP_RC:\n\t\tcase DUK_OP_PREDECP_CC:\n\t\tcase DUK_OP_POSTINCP_RR:\n\t\tcase DUK_OP_POSTINCP_CR:\n\t\tcase DUK_OP_POSTINCP_RC:\n\t\tcase DUK_OP_POSTINCP_CC:\n\t\tcase DUK_OP_POSTDECP_RR:\n\t\tcase DUK_OP_POSTDECP_CR:\n\t\tcase DUK_OP_POSTDECP_RC:\n\t\tcase DUK_OP_POSTDECP_CC: {\n\t\t\tduk_tval *tv_obj;\n\t\t\tduk_tval *tv_key;\n\t\t\tduk_tval *tv_val;\n\t\t\tduk_bool_t rc;\n\t\t\tduk_double_t x, y, z;\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_tval *tv_dst;\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t\t/* A -> target reg\n\t\t\t * B -> object reg/const (may be const e.g. in \"'foo'[1]\")\n\t\t\t * C -> key reg/const\n\t\t\t */\n\n\t\t\t/* Opcode bits 0-1 are used to distinguish reg/const variants.\n\t\t\t * Opcode bits 2-3 are used to distinguish inc/dec variants:\n\t\t\t * Bit 2 = inc(0)/dec(1), bit 3 = pre(0)/post(1).\n\t\t\t */\n\t\t\tDUK_ASSERT((DUK_OP_PREINCP_RR & 0x0c) == 0x00);\n\t\t\tDUK_ASSERT((DUK_OP_PREDECP_RR & 0x0c) == 0x04);\n\t\t\tDUK_ASSERT((DUK_OP_POSTINCP_RR & 0x0c) == 0x08);\n\t\t\tDUK_ASSERT((DUK_OP_POSTDECP_RR & 0x0c) == 0x0c);\n\n\t\t\ttv_obj = DUK__REGCONSTP_B(ins);\n\t\t\ttv_key = DUK__REGCONSTP_C(ins);\n\t\t\trc = duk_hobject_getprop(thr, tv_obj, tv_key);  /* -> [val] */\n\t\t\tDUK_UNREF(rc);  /* ignore */\n\t\t\ttv_obj = NULL;  /* invalidated */\n\t\t\ttv_key = NULL;  /* invalidated */\n\n\t\t\t/* XXX: Fastint fast path would be useful here.  Also fastints\n\t\t\t * now lose their fastint status in current handling which is\n\t\t\t * not intuitive.\n\t\t\t */\n\n\t\t\tx = duk_to_number_m1(thr);\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tif (ins & DUK_BC_INCDECP_FLAG_DEC) {\n\t\t\t\ty = x - 1.0;\n\t\t\t} else {\n\t\t\t\ty = x + 1.0;\n\t\t\t}\n\n\t\t\tduk_push_number(thr, y);\n\t\t\ttv_val = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\ttv_obj = DUK__REGCONSTP_B(ins);\n\t\t\ttv_key = DUK__REGCONSTP_C(ins);\n\t\t\trc = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, DUK__STRICT());\n\t\t\tDUK_UNREF(rc);  /* ignore */\n\t\t\ttv_obj = NULL;  /* invalidated */\n\t\t\ttv_key = NULL;  /* invalidated */\n\t\t\tduk_pop_unsafe(thr);\n\n\t\t\tz = (ins & DUK_BC_INCDECP_FLAG_POST) ? x : y;\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_push_number(thr, z);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n#else\n\t\t\ttv_dst = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_dst, z);\n\t\t\tbreak;\n#endif\n\t\t}\n\n\t\t/* XXX: GETPROP where object is 'this', GETPROPT?\n\t\t * Occurs relatively often in object oriented code.\n\t\t */\n\n#define DUK__GETPROP_BODY(barg,carg) { \\\n\t\t/* A -> target reg \\\n\t\t * B -> object reg/const (may be const e.g. in \"'foo'[1]\") \\\n\t\t * C -> key reg/const \\\n\t\t */ \\\n\t\t(void) duk_hobject_getprop(thr, (barg), (carg)); \\\n\t\tDUK__REPLACE_TOP_A_BREAK(); \\\n\t}\n#define DUK__GETPROPC_BODY(barg,carg) { \\\n\t\t/* Same as GETPROP but callability check for property-based calls. */ \\\n\t\tduk_tval *tv__targ; \\\n\t\t(void) duk_hobject_getprop(thr, (barg), (carg)); \\\n\t\tDUK_GC_TORTURE(thr->heap); \\\n\t\ttv__targ = DUK_GET_TVAL_NEGIDX(thr, -1); \\\n\t\tif (DUK_UNLIKELY(!duk_is_callable_tval(thr, tv__targ))) { \\\n\t\t\t/* Here we intentionally re-evaluate the macro \\\n\t\t\t * arguments to deal with potentially changed \\\n\t\t\t * valstack base pointer! \\\n\t\t\t */ \\\n\t\t\tduk_call_setup_propcall_error(thr, (barg), (carg)); \\\n\t\t} \\\n\t\tDUK__REPLACE_TOP_A_BREAK(); \\\n\t}\n#define DUK__PUTPROP_BODY(aarg,barg,carg) { \\\n\t\t/* A -> object reg \\\n\t\t * B -> key reg/const \\\n\t\t * C -> value reg/const \\\n\t\t * \\\n\t\t * Note: intentional difference to register arrangement \\\n\t\t * of e.g. GETPROP; 'A' must contain a register-only value. \\\n\t\t */ \\\n\t\t(void) duk_hobject_putprop(thr, (aarg), (barg), (carg), DUK__STRICT()); \\\n\t\tbreak; \\\n\t}\n#define DUK__DELPROP_BODY(barg,carg) { \\\n\t\t/* A -> result reg \\\n\t\t * B -> object reg \\\n\t\t * C -> key reg/const \\\n\t\t */ \\\n\t\tduk_bool_t rc; \\\n\t\trc = duk_hobject_delprop(thr, (barg), (carg), DUK__STRICT()); \\\n\t\tDUK_ASSERT(rc == 0 || rc == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(rc); \\\n\t}\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_GETPROP_RR:\n\t\tcase DUK_OP_GETPROP_CR:\n\t\tcase DUK_OP_GETPROP_RC:\n\t\tcase DUK_OP_GETPROP_CC:\n\t\t\tDUK__GETPROP_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\tcase DUK_OP_GETPROPC_RR:\n\t\tcase DUK_OP_GETPROPC_CR:\n\t\tcase DUK_OP_GETPROPC_RC:\n\t\tcase DUK_OP_GETPROPC_CC:\n\t\t\tDUK__GETPROPC_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#endif\n\t\tcase DUK_OP_PUTPROP_RR:\n\t\tcase DUK_OP_PUTPROP_CR:\n\t\tcase DUK_OP_PUTPROP_RC:\n\t\tcase DUK_OP_PUTPROP_CC:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_DELPROP_RR:\n\t\tcase DUK_OP_DELPROP_RC:  /* B is always reg */\n\t\t\tDUK__DELPROP_BODY(DUK__REGP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_GETPROP_RR:\n\t\t\tDUK__GETPROP_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROP_CR:\n\t\t\tDUK__GETPROP_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROP_RC:\n\t\t\tDUK__GETPROP_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GETPROP_CC:\n\t\t\tDUK__GETPROP_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\tcase DUK_OP_GETPROPC_RR:\n\t\t\tDUK__GETPROPC_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROPC_CR:\n\t\t\tDUK__GETPROPC_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROPC_RC:\n\t\t\tDUK__GETPROPC_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GETPROPC_CC:\n\t\t\tDUK__GETPROPC_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif\n\t\tcase DUK_OP_PUTPROP_RR:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_PUTPROP_CR:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_PUTPROP_RC:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_PUTPROP_CC:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_DELPROP_RR:  /* B is always reg */\n\t\t\tDUK__DELPROP_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_DELPROP_RC:\n\t\t\tDUK__DELPROP_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* No fast path for DECLVAR now, it's quite a rare instruction. */\n\t\tcase DUK_OP_DECLVAR_RR:\n\t\tcase DUK_OP_DECLVAR_CR:\n\t\tcase DUK_OP_DECLVAR_RC:\n\t\tcase DUK_OP_DECLVAR_CC: {\n\t\t\tduk_activation *act;\n\t\t\tduk_small_uint_fast_t a = DUK_DEC_A(ins);\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\t\t\tduk_small_uint_t prop_flags;\n\t\t\tduk_bool_t is_func_decl;\n\n\t\t\ttv1 = DUK__REGCONSTP_B(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\n\t\t\tis_func_decl = ((a & DUK_BC_DECLVAR_FLAG_FUNC_DECL) != 0);\n\n\t\t\t/* XXX: declvar takes an duk_tval pointer, which is awkward and\n\t\t\t * should be reworked.\n\t\t\t */\n\n\t\t\t/* Compiler is responsible for selecting property flags (configurability,\n\t\t\t * writability, etc).\n\t\t\t */\n\t\t\tprop_flags = a & DUK_PROPDESC_FLAGS_MASK;\n\n\t\t\tif (is_func_decl) {\n\t\t\t\tduk_push_tval(thr, DUK__REGCONSTP_C(ins));\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* valstack policy */\n\t\t\t\tthr->valstack_top++;\n\t\t\t}\n\t\t\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tif (duk_js_declvar_activation(thr, act, name, tv1, prop_flags, is_func_decl)) {\n\t\t\t\tif (is_func_decl) {\n\t\t\t\t\t/* Already declared, update value. */\n\t\t\t\t\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\t\t\t\tduk_js_putvar_activation(thr, act, name, tv1, DUK__STRICT());\n\t\t\t\t} else {\n\t\t\t\t\t/* Already declared but no initializer value\n\t\t\t\t\t * (e.g. 'var xyz;'), no-op.\n\t\t\t\t\t */\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t/* The compiler should never emit DUK_OP_REGEXP if there is no\n\t\t * regexp support.\n\t\t */\n\t\tcase DUK_OP_REGEXP_RR:\n\t\tcase DUK_OP_REGEXP_CR:\n\t\tcase DUK_OP_REGEXP_RC:\n\t\tcase DUK_OP_REGEXP_CC: {\n\t\t\t/* A -> target register\n\t\t\t * B -> bytecode (also contains flags)\n\t\t\t * C -> escaped source\n\t\t\t */\n\n\t\t\tduk_push_tval(thr, DUK__REGCONSTP_C(ins));\n\t\t\tduk_push_tval(thr, DUK__REGCONSTP_B(ins));  /* -> [ ... escaped_source bytecode ] */\n\t\t\tduk_regexp_create_instance(thr);   /* -> [ ... regexp_instance ] */\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n\t\t/* XXX: 'c' is unused, use whole BC, etc. */\n\t\tcase DUK_OP_CSVAR_RR:\n\t\tcase DUK_OP_CSVAR_CR:\n\t\tcase DUK_OP_CSVAR_RC:\n\t\tcase DUK_OP_CSVAR_CC: {\n\t\t\t/* The speciality of calling through a variable binding is that the\n\t\t\t * 'this' value may be provided by the variable lookup: E5 Section 6.b.i.\n\t\t\t *\n\t\t\t * The only (standard) case where the 'this' binding is non-null is when\n\t\t\t *   (1) the variable is found in an object environment record, and\n\t\t\t *   (2) that object environment record is a 'with' block.\n\t\t\t */\n\n\t\t\tduk_activation *act;\n\t\t\tduk_uint_fast_t idx;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\n\t\t\t/* A -> target registers (A, A + 1) for call setup\n\t\t\t * B -> identifier name, usually constant but can be a register due to shuffling\n\t\t\t */\n\n\t\t\ttv1 = DUK__REGCONSTP_B(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\t\t\tact = thr->callstack_curr;\n\t\t\t(void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/);  /* -> [... val this] */\n\n\t\t\tidx = (duk_uint_fast_t) DUK_DEC_A(ins);\n\n\t\t\t/* Could add direct value stack handling. */\n\t\t\tduk_replace(thr, (duk_idx_t) (idx + 1));  /* 'this' binding */\n\t\t\tduk_replace(thr, (duk_idx_t) idx);        /* variable value (function, we hope, not checked here) */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_CLOSURE: {\n\t\t\tduk_activation *act;\n\t\t\tduk_hcompfunc *fun_act;\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\t\t\tduk_hobject *fun_temp;\n\n\t\t\t/* A -> target reg\n\t\t\t * BC -> inner function index\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"CLOSURE to target register %ld, fnum %ld (count %ld)\",\n\t\t\t                     (long) DUK_DEC_A(ins), (long) DUK_DEC_BC(ins), (long) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, DUK__FUN())));\n\n\t\t\tDUK_ASSERT_DISABLE(bc >= 0); /* unsigned */\n\t\t\tDUK_ASSERT((duk_uint_t) bc < (duk_uint_t) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, DUK__FUN()));\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tfun_act = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\t\t\tfun_temp = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, fun_act)[bc];\n\t\t\tDUK_ASSERT(fun_temp != NULL);\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(fun_temp));\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"CLOSURE: function template is: %p -> %!O\",\n\t\t\t                     (void *) fun_temp, (duk_heaphdr *) fun_temp));\n\n\t\t\tif (act->lex_env == NULL) {\n\t\t\t\tDUK_ASSERT(act->var_env == NULL);\n\t\t\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\t\t\tact = thr->callstack_curr;\n\t\t\t}\n\t\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\t\tDUK_ASSERT(act->var_env != NULL);\n\n\t\t\t/* functions always have a NEWENV flag, i.e. they get a\n\t\t\t * new variable declaration environment, so only lex_env\n\t\t\t * matters here.\n\t\t\t */\n\t\t\tduk_js_push_closure(thr,\n\t\t\t                    (duk_hcompfunc *) fun_temp,\n\t\t\t                    act->var_env,\n\t\t\t                    act->lex_env,\n\t\t\t                    1 /*add_auto_proto*/);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_GETVAR: {\n\t\t\tduk_activation *act;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\n\t\t\ttv1 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\t(void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/);  /* -> [... val this] */\n\t\t\tduk_pop_unsafe(thr);  /* 'this' binding is not needed here */\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_PUTVAR: {\n\t\t\tduk_activation *act;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\n\t\t\ttv1 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\n\t\t\t/* XXX: putvar takes a duk_tval pointer, which is awkward and\n\t\t\t * should be reworked.\n\t\t\t */\n\n\t\t\ttv1 = DUK__REGP_A(ins);  /* val */\n\t\t\tact = thr->callstack_curr;\n\t\t\tduk_js_putvar_activation(thr, act, name, tv1, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_DELVAR: {\n\t\t\tduk_activation *act;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\t\t\tduk_bool_t rc;\n\n\t\t\ttv1 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\t\t\tact = thr->callstack_curr;\n\t\t\trc = duk_js_delvar_activation(thr, act, name);\n\t\t\tDUK__REPLACE_BOOL_A_BREAK(rc);\n\t\t}\n\n\t\tcase DUK_OP_JUMP: {\n\t\t\t/* Note: without explicit cast to signed, MSVC will\n\t\t\t * apparently generate a large positive jump when the\n\t\t\t * bias-corrected value would normally be negative.\n\t\t\t */\n\t\t\tcurr_pc += (duk_int_fast_t) DUK_DEC_ABC(ins) - (duk_int_fast_t) DUK_BC_JUMP_BIAS;\n\t\t\tbreak;\n\t\t}\n\n#define DUK__RETURN_SHARED() do { \\\n\t\tduk_small_uint_t ret_result; \\\n\t\t/* duk__handle_return() is guaranteed never to throw, except \\\n\t\t * for potential out-of-memory situations which will then \\\n\t\t * propagate out of the executor longjmp handler. \\\n\t\t */ \\\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL); \\\n\t\tret_result = duk__handle_return(thr, entry_act); \\\n\t\tif (ret_result == DUK__RETHAND_RESTART) { \\\n\t\t\tgoto restart_execution; \\\n\t\t} \\\n\t\tDUK_ASSERT(ret_result == DUK__RETHAND_FINISHED); \\\n\t\treturn; \\\n\t} while (0)\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_RETREG:\n\t\tcase DUK_OP_RETCONST:\n\t\tcase DUK_OP_RETCONSTN:\n\t\tcase DUK_OP_RETUNDEF: {\n\t\t\t /* BC -> return value reg/const */\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\n\t\t\tif (op == DUK_OP_RETREG) {\n\t\t\t\tduk_push_tval(thr, DUK__REGP_BC(ins));\n\t\t\t} else if (op == DUK_OP_RETUNDEF) {\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* valstack policy */\n\t\t\t\tthr->valstack_top++;\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(op == DUK_OP_RETCONST || op == DUK_OP_RETCONSTN);\n\t\t\t\tduk_push_tval(thr, DUK__CONSTP_BC(ins));\n\t\t\t}\n\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_RETREG: {\n\t\t\tduk_tval *tv;\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\ttv = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tthr->valstack_top++;\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n\t\t/* This will be unused without refcounting. */\n\t\tcase DUK_OP_RETCONST: {\n\t\t\tduk_tval *tv;\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\ttv = DUK__CONSTP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tthr->valstack_top++;\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n\t\tcase DUK_OP_RETCONSTN: {\n\t\t\tduk_tval *tv;\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\ttv = DUK__CONSTP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t/* Without refcounting only RETCONSTN is used. */\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv));  /* no INCREF for this constant */\n#endif\n\t\t\tthr->valstack_top++;\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n\t\tcase DUK_OP_RETUNDEF: {\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\tthr->valstack_top++;  /* value at valstack top is already undefined by valstack policy */\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\tcase DUK_OP_LABEL: {\n\t\t\tduk_activation *act;\n\t\t\tduk_catcher *cat;\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\t/* Allocate catcher and populate it (must be atomic). */\n\n\t\t\tcat = duk_hthread_catcher_alloc(thr);\n\t\t\tDUK_ASSERT(cat != NULL);\n\n\t\t\tcat->flags = (duk_uint32_t) (DUK_CAT_TYPE_LABEL | (bc << DUK_CAT_LABEL_SHIFT));\n\t\t\tcat->pc_base = (duk_instr_t *) curr_pc;  /* pre-incremented, points to first jump slot */\n\t\t\tcat->idx_base = 0;  /* unused for label */\n\t\t\tcat->h_varname = NULL;\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\tcat->parent = act->cat;\n\t\t\tact->cat = cat;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"LABEL catcher: flags=0x%08lx, pc_base=%ld, \"\n\t\t\t                     \"idx_base=%ld, h_varname=%!O, label_id=%ld\",\n\t\t\t                     (long) cat->flags, (long) cat->pc_base,\n\t\t\t                     (long) cat->idx_base, (duk_heaphdr *) cat->h_varname, (long) DUK_CAT_GET_LABEL(cat)));\n\n\t\t\tcurr_pc += 2;  /* skip jump slots */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDLABEL: {\n\t\t\tduk_activation *act;\n#if (defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)) || defined(DUK_USE_ASSERTIONS)\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n#endif\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"ENDLABEL %ld\", (long) bc));\n#endif\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(act->cat != NULL);\n\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_LABEL);\n\t\t\tDUK_ASSERT((duk_uint_fast_t) DUK_CAT_GET_LABEL(act->cat) == bc);\n\t\t\tduk_hthread_catcher_unwind_nolexenv_norz(thr, act);\n\n\t\t\t/* no need to unwind callstack */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_BREAK: {\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\tduk__handle_break_or_continue(thr, (duk_uint_t) bc, DUK_LJ_TYPE_BREAK);\n\t\t\tgoto restart_execution;\n\t\t}\n\n\t\tcase DUK_OP_CONTINUE: {\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\tduk__handle_break_or_continue(thr, (duk_uint_t) bc, DUK_LJ_TYPE_CONTINUE);\n\t\t\tgoto restart_execution;\n\t\t}\n\n\t\t/* XXX: move to helper, too large to be inline here */\n\t\tcase DUK_OP_TRYCATCH: {\n\t\t\tduk__handle_op_trycatch(thr, ins, curr_pc);\n\t\t\tcurr_pc += 2;  /* skip jump slots */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDTRY: {\n\t\t\tcurr_pc = duk__handle_op_endtry(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDCATCH: {\n\t\t\tduk__handle_op_endcatch(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDFIN: {\n\t\t\t/* Sync and NULL early. */\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\n\t\t\tif (duk__handle_op_endfin(thr, ins, entry_act) != 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t/* Must restart because we NULLed out curr_pc. */\n\t\t\tgoto restart_execution;\n\t\t}\n\n\t\tcase DUK_OP_THROW: {\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\t/* Note: errors are augmented when they are created, not\n\t\t\t * when they are thrown.  So, don't augment here, it would\n\t\t\t * break re-throwing for instance.\n\t\t\t */\n\n\t\t\t/* Sync so that augmentation sees up-to-date activations, NULL\n\t\t\t * thr->ptr_curr_pc so that it's not used if side effects occur\n\t\t\t * in augmentation or longjmp handling.\n\t\t\t */\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\n\t\t\tduk_dup(thr, (duk_idx_t) bc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (BYTECODE): %!dT (before throw augment)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\t\t\tduk_err_augment_error_throw(thr);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (BYTECODE): %!dT (after throw augment)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n#endif\n\n\t\t\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, DUK_GET_TVAL_NEGIDX(thr, -1));\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\t\tduk_err_check_debugger_integration(thr);\n#endif\n\n\t\t\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* always in executor */\n\t\t\tduk_err_longjmp(thr);\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_CSREG: {\n\t\t\t/*\n\t\t\t *  Assuming a register binds to a variable declared within this\n\t\t\t *  function (a declarative binding), the 'this' for the call\n\t\t\t *  setup is always 'undefined'.  E5 Section 10.2.1.1.6.\n\t\t\t */\n\n\t\t\tduk_small_uint_fast_t a = DUK_DEC_A(ins);\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\t/* A -> register containing target function (not type checked here)\n\t\t\t * BC -> target registers (BC, BC + 1) for call setup\n\t\t\t */\n\n#if defined(DUK_USE_PREFER_SIZE)\n\t\t\tduk_dup(thr, (duk_idx_t) a);\n\t\t\tduk_replace(thr, (duk_idx_t) bc);\n\t\t\tduk_to_undefined(thr, (duk_idx_t) (bc + 1));\n#else\n\t\t\tduk_tval *tv1;\n\t\t\tduk_tval *tv2;\n\t\t\tduk_tval *tv3;\n\t\t\tduk_tval tv_tmp1;\n\t\t\tduk_tval tv_tmp2;\n\n\t\t\ttv1 = DUK__REGP(bc);\n\t\t\ttv2 = tv1 + 1;\n\t\t\tDUK_TVAL_SET_TVAL(&tv_tmp1, tv1);\n\t\t\tDUK_TVAL_SET_TVAL(&tv_tmp2, tv2);\n\t\t\ttv3 = DUK__REGP(a);\n\t\t\tDUK_TVAL_SET_TVAL(tv1, tv3);\n\t\t\tDUK_TVAL_INCREF(thr, tv1);  /* no side effects */\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv2);  /* no need for incref */\n\t\t\tDUK_TVAL_DECREF(thr, &tv_tmp1);\n\t\t\tDUK_TVAL_DECREF(thr, &tv_tmp2);\n#endif\n\t\t\tbreak;\n\t\t}\n\n\n\t\t/* XXX: in some cases it's faster NOT to reuse the value\n\t\t * stack but rather copy the arguments on top of the stack\n\t\t * (mainly when the calling value stack is large and the value\n\t\t * stack resize would be large).\n\t\t */\n\n\t\tcase DUK_OP_CALL0:\n\t\tcase DUK_OP_CALL1:\n\t\tcase DUK_OP_CALL2:\n\t\tcase DUK_OP_CALL3:\n\t\tcase DUK_OP_CALL4:\n\t\tcase DUK_OP_CALL5:\n\t\tcase DUK_OP_CALL6:\n\t\tcase DUK_OP_CALL7: {\n\t\t\t/* Opcode packs 4 flag bits: 1 for indirect, 3 map\n\t\t\t * 1:1 to three lowest call handling flags.\n\t\t\t *\n\t\t\t * A -> nargs or register with nargs (indirect)\n\t\t\t * BC -> base register for call (base -> func, base+1 -> this, base+2 -> arg1 ... base+2+N-1 -> argN)\n\t\t\t */\n\n\t\t\tduk_idx_t nargs;\n\t\t\tduk_idx_t idx;\n\t\t\tduk_small_uint_t call_flags;\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tduk_hcompfunc *fun;\n#endif\n\n\t\t\tDUK_ASSERT((DUK_OP_CALL0 & 0x0fU) == 0);\n\t\t\tDUK_ASSERT((ins & DUK_BC_CALL_FLAG_INDIRECT) == 0);\n\n\t\t\tnargs = (duk_idx_t) DUK_DEC_A(ins);\n\t\t\tcall_flags = (ins & 0x07U) | DUK_CALL_FLAG_ALLOW_ECMATOECMA;\n\t\t\tidx = (duk_idx_t) DUK_DEC_BC(ins);\n\n\t\t\tif (duk__executor_handle_call(thr, idx, nargs, call_flags)) {\n\t\t\t\t/* curr_pc synced by duk_handle_call_unprotected() */\n\t\t\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n\t\t\tDUK_ASSERT(thr->ptr_curr_pc != NULL);\n\n\t\t\t/* duk_js_call.c is required to restore the stack reserve\n\t\t\t * so we only need to reset the top.\n\t\t\t */\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tfun = DUK__FUN();\n#endif\n\t\t\tduk_set_top_unsafe(thr, (duk_idx_t) fun->nregs);\n\n\t\t\t/* No need to reinit setjmp() catchpoint, as call handling\n\t\t\t * will store and restore our state.\n\t\t\t *\n\t\t\t * When debugger is enabled, we need to recheck the activation\n\t\t\t * status after returning.  This is now handled by call handling\n\t\t\t * and heap->dbg_force_restart.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_CALL8:\n\t\tcase DUK_OP_CALL9:\n\t\tcase DUK_OP_CALL10:\n\t\tcase DUK_OP_CALL11:\n\t\tcase DUK_OP_CALL12:\n\t\tcase DUK_OP_CALL13:\n\t\tcase DUK_OP_CALL14:\n\t\tcase DUK_OP_CALL15: {\n\t\t\t/* Indirect variant. */\n\t\t\tduk_uint_fast_t nargs;\n\t\t\tduk_idx_t idx;\n\t\t\tduk_small_uint_t call_flags;\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tduk_hcompfunc *fun;\n#endif\n\n\t\t\tDUK_ASSERT((DUK_OP_CALL0 & 0x0fU) == 0);\n\t\t\tDUK_ASSERT((ins & DUK_BC_CALL_FLAG_INDIRECT) != 0);\n\n\t\t\tnargs = (duk_uint_fast_t) DUK_DEC_A(ins);\n\t\t\tDUK__LOOKUP_INDIRECT(nargs);\n\t\t\tcall_flags = (ins & 0x07U) | DUK_CALL_FLAG_ALLOW_ECMATOECMA;\n\t\t\tidx = (duk_idx_t) DUK_DEC_BC(ins);\n\n\t\t\tif (duk__executor_handle_call(thr, idx, (duk_idx_t) nargs, call_flags)) {\n\t\t\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n\t\t\tDUK_ASSERT(thr->ptr_curr_pc != NULL);\n\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tfun = DUK__FUN();\n#endif\n\t\t\tduk_set_top_unsafe(thr, (duk_idx_t) fun->nregs);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_NEWOBJ: {\n\t\t\tduk_push_object(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t{\n\t\t\t\tduk_hobject *h;\n\t\t\t\th = duk_require_hobject(thr, -1);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ESIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(h) == 0);\n\t\t\t}\n#endif\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t/* XXX: could do a direct props realloc, but need hash size */\n\t\t\tduk_hobject_resize_entrypart(thr, duk_known_hobject(thr, -1), DUK_DEC_A(ins));\n#endif\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_NEWARR: {\n\t\t\tduk_push_array(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t{\n\t\t\t\tduk_hobject *h;\n\t\t\t\th = duk_require_hobject(thr, -1);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ESIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(h));\n\t\t\t}\n#endif\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\tduk_hobject_realloc_props(thr,\n\t\t\t                          duk_known_hobject(thr, -1),\n\t\t\t                          0 /*new_e_size*/,\n\t\t\t                          DUK_DEC_A(ins) /*new_a_size*/,\n\t\t\t                          0 /*new_h_size*/,\n\t\t\t                          0 /*abandon_array*/);\n#if 0\n\t\t\tduk_hobject_resize_arraypart(thr, duk_known_hobject(thr, -1), DUK_DEC_A(ins));\n#endif\n#endif\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_MPUTOBJ:\n\t\tcase DUK_OP_MPUTOBJI: {\n\t\t\tduk_idx_t obj_idx;\n\t\t\tduk_uint_fast_t idx, idx_end;\n\t\t\tduk_small_uint_fast_t count;\n\n\t\t\t/* A -> register of target object\n\t\t\t * B -> first register of key/value pair list\n\t\t\t *      or register containing first register number if indirect\n\t\t\t * C -> number of key/value pairs * 2\n\t\t\t *      (= number of value stack indices used starting from 'B')\n\t\t\t */\n\n\t\t\tobj_idx = DUK_DEC_A(ins);\n\t\t\tDUK_ASSERT(duk_is_object(thr, obj_idx));\n\n\t\t\tidx = (duk_uint_fast_t) DUK_DEC_B(ins);\n\t\t\tif (DUK_DEC_OP(ins) == DUK_OP_MPUTOBJI) {\n\t\t\t\tDUK__LOOKUP_INDIRECT(idx);\n\t\t\t}\n\n\t\t\tcount = (duk_small_uint_fast_t) DUK_DEC_C(ins);\n\t\t\tDUK_ASSERT(count > 0);  /* compiler guarantees */\n\t\t\tidx_end = idx + count;\n\n#if defined(DUK_USE_EXEC_INDIRECT_BOUND_CHECK)\n\t\t\tif (DUK_UNLIKELY(idx_end > (duk_uint_fast_t) duk_get_top(thr))) {\n\t\t\t\t/* XXX: use duk_is_valid_index() instead? */\n\t\t\t\t/* XXX: improve check; check against nregs, not against top */\n\t\t\t\tDUK__INTERNAL_ERROR(\"MPUTOBJ out of bounds\");\n\t\t\t}\n#endif\n\n\t\t\t/* Use 'force' flag to duk_def_prop() to ensure that any\n\t\t\t * inherited properties don't prevent the operation.\n\t\t\t * With ES2015 duplicate properties are allowed, so that we\n\t\t\t * must overwrite any previous data or accessor property.\n\t\t\t *\n\t\t\t * With ES2015 computed property names the literal keys\n\t\t\t * may be arbitrary values and need to be ToPropertyKey()\n\t\t\t * coerced at runtime.\n\t\t\t */\n\t\t\tdo {\n\t\t\t\t/* XXX: faster initialization (direct access or better primitives) */\n\t\t\t\tduk_dup(thr, (duk_idx_t) idx);\n\t\t\t\tduk_dup(thr, (duk_idx_t) (idx + 1));\n\t\t\t\tduk_def_prop(thr, obj_idx, DUK_DEFPROP_HAVE_VALUE |\n\t\t\t\t                           DUK_DEFPROP_FORCE |\n\t\t\t\t                           DUK_DEFPROP_SET_WRITABLE |\n\t\t\t\t                           DUK_DEFPROP_SET_ENUMERABLE |\n\t\t\t\t                           DUK_DEFPROP_SET_CONFIGURABLE);\n\t\t\t\tidx += 2;\n\t\t\t} while (idx < idx_end);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INITSET:\n\t\tcase DUK_OP_INITGET: {\n\t\t\tduk__handle_op_initset_initget(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_MPUTARR:\n\t\tcase DUK_OP_MPUTARRI: {\n\t\t\tduk_idx_t obj_idx;\n\t\t\tduk_uint_fast_t idx, idx_end;\n\t\t\tduk_small_uint_fast_t count;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_uint32_t arr_idx;\n\n\t\t\t/* A -> register of target object\n\t\t\t * B -> first register of value data (start_index, value1, value2, ..., valueN)\n\t\t\t *      or register containing first register number if indirect\n\t\t\t * C -> number of key/value pairs (N)\n\t\t\t */\n\n\t\t\tobj_idx = DUK_DEC_A(ins);\n\t\t\tDUK_ASSERT(duk_is_object(thr, obj_idx));\n\n\t\t\tidx = (duk_uint_fast_t) DUK_DEC_B(ins);\n\t\t\tif (DUK_DEC_OP(ins) == DUK_OP_MPUTARRI) {\n\t\t\t\tDUK__LOOKUP_INDIRECT(idx);\n\t\t\t}\n\n\t\t\tcount = (duk_small_uint_fast_t) DUK_DEC_C(ins);\n\t\t\tDUK_ASSERT(count > 0 + 1);  /* compiler guarantees */\n\t\t\tidx_end = idx + count;\n\n#if defined(DUK_USE_EXEC_INDIRECT_BOUND_CHECK)\n\t\t\tif (idx_end > (duk_uint_fast_t) duk_get_top(thr)) {\n\t\t\t\t/* XXX: use duk_is_valid_index() instead? */\n\t\t\t\t/* XXX: improve check; check against nregs, not against top */\n\t\t\t\tDUK__INTERNAL_ERROR(\"MPUTARR out of bounds\");\n\t\t\t}\n#endif\n\n\t\t\ttv1 = DUK__REGP(idx);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\t\tarr_idx = (duk_uint32_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\t\t\tarr_idx = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\t\tidx++;\n\n\t\t\tdo {\n\t\t\t\t/* duk_xdef_prop() will define an own property without any array\n\t\t\t\t * special behaviors.  We'll need to set the array length explicitly\n\t\t\t\t * in the end.  For arrays with elisions, the compiler will emit an\n\t\t\t\t * explicit SETALEN which will update the length.\n\t\t\t\t */\n\n\t\t\t\t/* XXX: because we're dealing with 'own' properties of a fresh array,\n\t\t\t\t * the array initializer should just ensure that the array has a large\n\t\t\t\t * enough array part and write the values directly into array part,\n\t\t\t\t * and finally set 'length' manually in the end (as already happens now).\n\t\t\t\t */\n\n\t\t\t\tduk_dup(thr, (duk_idx_t) idx);\n\t\t\t\tduk_xdef_prop_index_wec(thr, obj_idx, arr_idx);\n\n\t\t\t\tidx++;\n\t\t\t\tarr_idx++;\n\t\t\t} while (idx < idx_end);\n\n\t\t\t/* XXX: E5.1 Section 11.1.4 coerces the final length through\n\t\t\t * ToUint32() which is odd but happens now as a side effect of\n\t\t\t * 'arr_idx' type.\n\t\t\t */\n\t\t\tduk_set_length(thr, obj_idx, (duk_size_t) (duk_uarridx_t) arr_idx);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_SETALEN: {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hobject *h;\n\t\t\tduk_uint32_t len;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv1));\n\t\t\th = DUK_TVAL_GET_OBJECT(tv1);\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY(h));\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\t\tlen = (duk_uint32_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\t\t\tlen = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\t\t((duk_harray *) h)->length = len;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INITENUM: {\n\t\t\tduk__handle_op_initenum(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_NEXTENUM: {\n\t\t\tcurr_pc += duk__handle_op_nextenum(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INVLHS: {\n\t\t\tDUK_ERROR_REFERENCE(thr, DUK_STR_INVALID_LVALUE);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_DEBUGGER: {\n\t\t\t/* Opcode only emitted by compiler when debugger\n\t\t\t * support is enabled.  Ignore it silently without\n\t\t\t * debugger support, in case it has been loaded\n\t\t\t * from precompiled bytecode.\n\t\t\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\t\tif (duk_debug_is_attached(thr->heap)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement encountered, halt execution\"));\n\t\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\t\tduk_debug_halt_execution(thr, 1 /*use_prev_pc*/);\n\t\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement finished, resume execution\"));\n\t\t\t\tgoto restart_execution;\n\t\t\t} else {\n\t\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement ignored, debugger not attached\"));\n\t\t\t}\n#else\n\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement ignored, no debugger support\"));\n#endif\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_NOP: {\n\t\t\t/* Nop, ignored, but ABC fields may carry a value e.g.\n\t\t\t * for indirect opcode handling.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INVALID: {\n\t\t\tDUK_ERROR_FMT1(thr, DUK_ERR_ERROR, \"INVALID opcode (%ld)\", (long) DUK_DEC_ABC(ins));\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_ES6)\n\t\tcase DUK_OP_NEWTARGET: {\n\t\t\tduk_push_new_target(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n#endif  /* DUK_USE_ES6 */\n\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n#if !defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tcase DUK_OP_EXP_RR:\n\t\tcase DUK_OP_EXP_CR:\n\t\tcase DUK_OP_EXP_RC:\n\t\tcase DUK_OP_EXP_CC:\n#endif\n#if !defined(DUK_USE_ES6)\n\t\tcase DUK_OP_NEWTARGET:\n#endif\n#if !defined(DUK_USE_VERBOSE_ERRORS)\n\t\tcase DUK_OP_GETPROPC_RR:\n\t\tcase DUK_OP_GETPROPC_CR:\n\t\tcase DUK_OP_GETPROPC_RC:\n\t\tcase DUK_OP_GETPROPC_CC:\n#endif\n\t\tcase DUK_OP_UNUSED207:\n\t\tcase DUK_OP_UNUSED212:\n\t\tcase DUK_OP_UNUSED213:\n\t\tcase DUK_OP_UNUSED214:\n\t\tcase DUK_OP_UNUSED215:\n\t\tcase DUK_OP_UNUSED216:\n\t\tcase DUK_OP_UNUSED217:\n\t\tcase DUK_OP_UNUSED218:\n\t\tcase DUK_OP_UNUSED219:\n\t\tcase DUK_OP_UNUSED220:\n\t\tcase DUK_OP_UNUSED221:\n\t\tcase DUK_OP_UNUSED222:\n\t\tcase DUK_OP_UNUSED223:\n\t\tcase DUK_OP_UNUSED224:\n\t\tcase DUK_OP_UNUSED225:\n\t\tcase DUK_OP_UNUSED226:\n\t\tcase DUK_OP_UNUSED227:\n\t\tcase DUK_OP_UNUSED228:\n\t\tcase DUK_OP_UNUSED229:\n\t\tcase DUK_OP_UNUSED230:\n\t\tcase DUK_OP_UNUSED231:\n\t\tcase DUK_OP_UNUSED232:\n\t\tcase DUK_OP_UNUSED233:\n\t\tcase DUK_OP_UNUSED234:\n\t\tcase DUK_OP_UNUSED235:\n\t\tcase DUK_OP_UNUSED236:\n\t\tcase DUK_OP_UNUSED237:\n\t\tcase DUK_OP_UNUSED238:\n\t\tcase DUK_OP_UNUSED239:\n\t\tcase DUK_OP_UNUSED240:\n\t\tcase DUK_OP_UNUSED241:\n\t\tcase DUK_OP_UNUSED242:\n\t\tcase DUK_OP_UNUSED243:\n\t\tcase DUK_OP_UNUSED244:\n\t\tcase DUK_OP_UNUSED245:\n\t\tcase DUK_OP_UNUSED246:\n\t\tcase DUK_OP_UNUSED247:\n\t\tcase DUK_OP_UNUSED248:\n\t\tcase DUK_OP_UNUSED249:\n\t\tcase DUK_OP_UNUSED250:\n\t\tcase DUK_OP_UNUSED251:\n\t\tcase DUK_OP_UNUSED252:\n\t\tcase DUK_OP_UNUSED253:\n\t\tcase DUK_OP_UNUSED254:\n\t\tcase DUK_OP_UNUSED255:\n\t\t/* Force all case clauses to map to an actual handler\n\t\t * so that the compiler can emit a jump without a bounds\n\t\t * check: the switch argument is a duk_uint8_t so that\n\t\t * the compiler may be able to figure it out.  This is\n\t\t * a small detail and obviously compiler dependent.\n\t\t */\n\t\t/* default: clause omitted on purpose */\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tdefault:\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\t{\n\t\t\t/* Default case catches invalid/unsupported opcodes. */\n\t\t\tDUK_D(DUK_DPRINT(\"invalid opcode: %ld - %!I\", (long) op, ins));\n\t\t\tDUK__INTERNAL_ERROR(\"invalid opcode\");\n\t\t\tbreak;\n\t\t}\n\n\t\t}  /* end switch */\n\n\t\tcontinue;\n\n\t\t/* Some shared exit paths for opcode handling below.  These\n\t\t * are mostly useful to reduce code footprint when multiple\n\t\t * opcodes have a similar epilogue (like replacing stack top\n\t\t * with index 'a').\n\t\t */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t replace_top_a:\n\t\tDUK__REPLACE_TO_TVPTR(thr, DUK__REGP_A(ins));\n\t\tcontinue;\n\t replace_top_bc:\n\t\tDUK__REPLACE_TO_TVPTR(thr, DUK__REGP_BC(ins));\n\t\tcontinue;\n#endif\n\t}\n\tDUK_WO_NORETURN(return;);\n\n#if !defined(DUK_USE_VERBOSE_EXECUTOR_ERRORS)\n internal_error:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n#endif\n}\n\n/* automatic undefs */\n#undef DUK__BYTEOFF_A\n#undef DUK__BYTEOFF_B\n#undef DUK__BYTEOFF_BC\n#undef DUK__BYTEOFF_C\n#undef DUK__COMPARE_BODY\n#undef DUK__CONST\n#undef DUK__CONSTP\n#undef DUK__CONSTP_A\n#undef DUK__CONSTP_B\n#undef DUK__CONSTP_BC\n#undef DUK__CONSTP_C\n#undef DUK__DELPROP_BODY\n#undef DUK__EQ_BODY\n#undef DUK__FUN\n#undef DUK__GETPROPC_BODY\n#undef DUK__GETPROP_BODY\n#undef DUK__GE_BODY\n#undef DUK__GT_BODY\n#undef DUK__INLINE_PERF\n#undef DUK__INSTOF_BODY\n#undef DUK__INTERNAL_ERROR\n#undef DUK__INT_NOACTION\n#undef DUK__INT_RESTART\n#undef DUK__IN_BODY\n#undef DUK__LE_BODY\n#undef DUK__LONGJMP_RESTART\n#undef DUK__LONGJMP_RETHROW\n#undef DUK__LOOKUP_INDIRECT\n#undef DUK__LT_BODY\n#undef DUK__MASK_A\n#undef DUK__MASK_B\n#undef DUK__MASK_BC\n#undef DUK__MASK_C\n#undef DUK__NEQ_BODY\n#undef DUK__NOINLINE_PERF\n#undef DUK__PUTPROP_BODY\n#undef DUK__RCBIT_B\n#undef DUK__RCBIT_C\n#undef DUK__REG\n#undef DUK__REGCONSTP_B\n#undef DUK__REGCONSTP_C\n#undef DUK__REGP\n#undef DUK__REGP_A\n#undef DUK__REGP_B\n#undef DUK__REGP_BC\n#undef DUK__REGP_C\n#undef DUK__REPLACE_BOOL_A_BREAK\n#undef DUK__REPLACE_TOP_A_BREAK\n#undef DUK__REPLACE_TOP_BC_BREAK\n#undef DUK__REPLACE_TO_TVPTR\n#undef DUK__RETHAND_FINISHED\n#undef DUK__RETHAND_RESTART\n#undef DUK__RETURN_SHARED\n#undef DUK__SEQ_BODY\n#undef DUK__SHIFT_A\n#undef DUK__SHIFT_B\n#undef DUK__SHIFT_BC\n#undef DUK__SHIFT_C\n#undef DUK__SNEQ_BODY\n#undef DUK__STRICT\n#undef DUK__SYNC_AND_NULL_CURR_PC\n#undef DUK__SYNC_CURR_PC\n#undef DUK__TVAL_SHIFT\n#line 1 \"duk_js_ops.c\"\n/*\n *  ECMAScript specification algorithm and conversion helpers.\n *\n *  These helpers encapsulate the primitive ECMAScript operation semantics,\n *  and are used by the bytecode executor and the API (among other places).\n *  Some primitives are only implemented as part of the API and have no\n *  \"internal\" helper.  This is the case when an internal helper would not\n *  really be useful; e.g. the operation is rare, uses value stack heavily,\n *  etc.\n *\n *  The operation arguments depend on what is required to implement\n *  the operation:\n *\n *    - If an operation is simple and stateless, and has no side\n *      effects, it won't take an duk_hthread argument and its\n *      arguments may be duk_tval pointers (which are safe as long\n *      as no side effects take place).\n *\n *    - If complex coercions are required (e.g. a \"ToNumber\" coercion)\n *      or errors may be thrown, the operation takes an duk_hthread\n *      argument.  This also implies that the operation may have\n *      arbitrary side effects, invalidating any duk_tval pointers.\n *\n *    - For operations with potential side effects, arguments can be\n *      taken in several ways:\n *\n *      a) as duk_tval pointers, which makes sense if the \"common case\"\n *         can be resolved without side effects (e.g. coercion); the\n *         arguments are pushed to the valstack for coercion if\n *         necessary\n *\n *      b) as duk_tval values\n *\n *      c) implicitly on value stack top\n *\n *      d) as indices to the value stack\n *\n *  Future work:\n *\n *     - Argument styles may not be the most sensible in every case now.\n *\n *     - In-place coercions might be useful for several operations, if\n *       in-place coercion is OK for the bytecode executor and the API.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  ToPrimitive()  (E5 Section 9.1)\n *\n *  ==> implemented in the API.\n */\n\n/*\n *  ToBoolean()  (E5 Section 9.2)\n */\n\nDUK_INTERNAL duk_bool_t duk_js_toboolean(duk_tval *tv) {\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\t\treturn 0;\n\tcase DUK_TAG_BOOLEAN:\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv) == 0 || DUK_TVAL_GET_BOOLEAN(tv) == 1);\n\t\treturn DUK_TVAL_GET_BOOLEAN(tv);\n\tcase DUK_TAG_STRING: {\n\t\t/* Symbols ToBoolean() coerce to true, regardless of their\n\t\t * description.  This happens with no explicit check because\n\t\t * of the symbol representation byte prefix.\n\t\t */\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HSTRING_GET_BYTELEN(h) > 0 ? 1 : 0);\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\treturn 1;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\t/* Mimic Uint8Array semantics: objects coerce true, regardless\n\t\t * of buffer length (zero or not) or context.\n\t\t */\n\t\treturn 1;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tvoid *p = DUK_TVAL_GET_POINTER(tv);\n\t\treturn (p != NULL ? 1 : 0);\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\treturn 1;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\tif (DUK_TVAL_GET_FASTINT(tv) != 0) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tduk_double_t d;\n#if defined(DUK_USE_PREFER_SIZE)\n\t\tint c;\n#endif\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\t\td = DUK_TVAL_GET_DOUBLE(tv);\n#if defined(DUK_USE_PREFER_SIZE)\n\t\tc = DUK_FPCLASSIFY((double) d);\n\t\tif (c == DUK_FP_ZERO || c == DUK_FP_NAN) {\n\t\t\treturn 0;\n\t\t} else {\n\t\t\treturn 1;\n\t\t}\n#else\n\t\tDUK_ASSERT(duk_double_is_nan_or_zero(d) == 0 || duk_double_is_nan_or_zero(d) == 1);\n\t\treturn duk_double_is_nan_or_zero(d) ^ 1;\n#endif\n\t}\n\t}\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  ToNumber()  (E5 Section 9.3)\n *\n *  Value to convert must be on stack top, and is popped before exit.\n *\n *  See: http://www.cs.indiana.edu/~burger/FP-Printing-PLDI96.pdf\n *       http://www.cs.indiana.edu/~burger/fp/index.html\n *\n *  Notes on the conversion:\n *\n *    - There are specific requirements on the accuracy of the conversion\n *      through a \"Mathematical Value\" (MV), so this conversion is not\n *      trivial.\n *\n *    - Quick rejects (e.g. based on first char) are difficult because\n *      the grammar allows leading and trailing white space.\n *\n *    - Quick reject based on string length is difficult even after\n *      accounting for white space; there may be arbitrarily many\n *      decimal digits.\n *\n *    - Standard grammar allows decimal values (\"123\"), hex values\n *      (\"0x123\") and infinities\n *\n *    - Unlike source code literals, ToNumber() coerces empty strings\n *      and strings with only whitespace to zero (not NaN).  However,\n *      while '' coerces to 0, '+' and '-' coerce to NaN.\n */\n\n/* E5 Section 9.3.1 */\nDUK_LOCAL duk_double_t duk__tonumber_string_raw(duk_hthread *thr) {\n\tduk_small_uint_t s2n_flags;\n\tduk_double_t d;\n\n\tDUK_ASSERT(duk_is_string(thr, -1));\n\n\t/* Quite lenient, e.g. allow empty as zero, but don't allow trailing\n\t * garbage.\n\t */\n\ts2n_flags = DUK_S2N_FLAG_TRIM_WHITE |\n\t            DUK_S2N_FLAG_ALLOW_EXP |\n\t            DUK_S2N_FLAG_ALLOW_PLUS |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |\n\t            DUK_S2N_FLAG_ALLOW_INF |\n\t            DUK_S2N_FLAG_ALLOW_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO |\n\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT;\n\n\tduk_numconv_parse(thr, 10 /*radix*/, s2n_flags);\n\n#if defined(DUK_USE_PREFER_SIZE)\n\td = duk_get_number(thr, -1);\n\tduk_pop_unsafe(thr);\n#else\n\tthr->valstack_top--;\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(thr->valstack_top));\n\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(thr->valstack_top));  /* no fastint conversion in numconv now */\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(thr->valstack_top));\n\td = DUK_TVAL_GET_DOUBLE(thr->valstack_top);  /* assumes not a fastint */\n\tDUK_TVAL_SET_UNDEFINED(thr->valstack_top);\n#endif\n\n\treturn d;\n}\n\nDUK_INTERNAL duk_double_t duk_js_tonumber(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\t/* return a specific NaN (although not strictly necessary) */\n\t\tduk_double_union du;\n\t\tDUK_DBLUNION_SET_NAN(&du);\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\t\treturn du.d;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\t/* +0.0 */\n\t\treturn 0.0;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tif (DUK_TVAL_IS_BOOLEAN_TRUE(tv)) {\n\t\t\treturn 1.0;\n\t\t}\n\t\treturn 0.0;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\t/* For Symbols ToNumber() is always a TypeError. */\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CANNOT_NUMBER_COERCE_SYMBOL);\n\t\t\tDUK_WO_NORETURN(return 0.0;);\n\t\t}\n\t\tduk_push_hstring(thr, h);\n\t\treturn duk__tonumber_string_raw(thr);\n\t}\n\tcase DUK_TAG_BUFFER:  /* plain buffer treated like object */\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_double_t d;\n\t\tduk_push_tval(thr, tv);\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);  /* 'tv' becomes invalid */\n\n\t\t/* recursive call for a primitive value (guaranteed not to cause second\n\t\t * recursion).\n\t\t */\n\t\tDUK_ASSERT(duk_get_tval(thr, -1) != NULL);\n\t\td = duk_js_tonumber(thr, duk_get_tval(thr, -1));\n\n\t\tduk_pop_unsafe(thr);\n\t\treturn d;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\t/* Coerce like boolean */\n\t\tvoid *p = DUK_TVAL_GET_POINTER(tv);\n\t\treturn (p != NULL ? 1.0 : 0.0);\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* +(function(){}) -> NaN */\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\treturn (duk_double_t) DUK_TVAL_GET_FASTINT(tv);\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\t\treturn DUK_TVAL_GET_DOUBLE(tv);\n\t}\n\t}\n\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  ToInteger()  (E5 Section 9.4)\n */\n\n/* exposed, used by e.g. duk_bi_date.c */\nDUK_INTERNAL duk_double_t duk_js_tointeger_number(duk_double_t x) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\n\tif (DUK_UNLIKELY(c == DUK_FP_NAN)) {\n\t\treturn 0.0;\n\t} else if (DUK_UNLIKELY(c == DUK_FP_INFINITE)) {\n\t\treturn x;\n\t} else {\n\t\t/* Finite, including neg/pos zero.  Neg zero sign must be\n\t\t * preserved.\n\t\t */\n\t\treturn duk_double_trunc_towards_zero(x);\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\t/* NaN and Infinity have the same exponent so it's a cheap\n\t * initial check for the rare path.\n\t */\n\tif (DUK_UNLIKELY(duk_double_is_nan_or_inf(x) != 0U)) {\n\t\tif (duk_double_is_nan(x)) {\n\t\t\treturn 0.0;\n\t\t} else {\n\t\t\treturn x;\n\t\t}\n\t} else {\n\t\treturn duk_double_trunc_towards_zero(x);\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n}\n\nDUK_INTERNAL duk_double_t duk_js_tointeger(duk_hthread *thr, duk_tval *tv) {\n\t/* XXX: fastint */\n\tduk_double_t d = duk_js_tonumber(thr, tv);  /* invalidates tv */\n\treturn duk_js_tointeger_number(d);\n}\n\n/*\n *  ToInt32(), ToUint32(), ToUint16()  (E5 Sections 9.5, 9.6, 9.7)\n */\n\n/* combined algorithm matching E5 Sections 9.5 and 9.6 */\nDUK_LOCAL duk_double_t duk__toint32_touint32_helper(duk_double_t x, duk_bool_t is_toint32) {\n#if defined (DUK_USE_PREFER_SIZE)\n\tduk_small_int_t c;\n#endif\n\n#if defined (DUK_USE_PREFER_SIZE)\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (c == DUK_FP_NAN || c == DUK_FP_ZERO || c == DUK_FP_INFINITE) {\n\t\treturn 0.0;\n\t}\n#else\n\tif (duk_double_is_nan_zero_inf(x)) {\n\t\treturn 0.0;\n\t}\n#endif\n\n\t/* x = sign(x) * floor(abs(x)), i.e. truncate towards zero, keep sign */\n\tx = duk_double_trunc_towards_zero(x);\n\n\t/* NOTE: fmod(x) result sign is same as sign of x, which\n\t * differs from what Javascript wants (see Section 9.6).\n\t */\n\n\tx = DUK_FMOD(x, DUK_DOUBLE_2TO32);    /* -> x in ]-2**32, 2**32[ */\n\n\tif (x < 0.0) {\n\t\tx += DUK_DOUBLE_2TO32;\n\t}\n\tDUK_ASSERT(x >= 0 && x < DUK_DOUBLE_2TO32);  /* -> x in [0, 2**32[ */\n\n\tif (is_toint32) {\n\t\tif (x >= DUK_DOUBLE_2TO31) {\n\t\t\t/* x in [2**31, 2**32[ */\n\n\t\t\tx -= DUK_DOUBLE_2TO32;  /* -> x in [-2**31,2**31[ */\n\t\t}\n\t}\n\n\treturn x;\n}\n\nDUK_INTERNAL duk_int32_t duk_js_toint32(duk_hthread *thr, duk_tval *tv) {\n\tduk_double_t d;\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\treturn DUK_TVAL_GET_FASTINT_I32(tv);\n\t}\n#endif\n\n\td = duk_js_tonumber(thr, tv);  /* invalidates tv */\n\td = duk__toint32_touint32_helper(d, 1);\n\tDUK_ASSERT(DUK_FPCLASSIFY(d) == DUK_FP_ZERO || DUK_FPCLASSIFY(d) == DUK_FP_NORMAL);\n\tDUK_ASSERT(d >= -2147483648.0 && d <= 2147483647.0);  /* [-0x80000000,0x7fffffff] */\n\tDUK_ASSERT(d == ((duk_double_t) ((duk_int32_t) d)));  /* whole, won't clip */\n\treturn (duk_int32_t) d;\n}\n\n\nDUK_INTERNAL duk_uint32_t duk_js_touint32(duk_hthread *thr, duk_tval *tv) {\n\tduk_double_t d;\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\treturn DUK_TVAL_GET_FASTINT_U32(tv);\n\t}\n#endif\n\n\td = duk_js_tonumber(thr, tv);  /* invalidates tv */\n\td = duk__toint32_touint32_helper(d, 0);\n\tDUK_ASSERT(DUK_FPCLASSIFY(d) == DUK_FP_ZERO || DUK_FPCLASSIFY(d) == DUK_FP_NORMAL);\n\tDUK_ASSERT(d >= 0.0 && d <= 4294967295.0);  /* [0x00000000, 0xffffffff] */\n\tDUK_ASSERT(d == ((duk_double_t) ((duk_uint32_t) d)));  /* whole, won't clip */\n\treturn (duk_uint32_t) d;\n\n}\n\nDUK_INTERNAL duk_uint16_t duk_js_touint16(duk_hthread *thr, duk_tval *tv) {\n\t/* should be a safe way to compute this */\n\treturn (duk_uint16_t) (duk_js_touint32(thr, tv) & 0x0000ffffU);\n}\n\n/*\n *  ToString()  (E5 Section 9.8)\n *  ToObject()  (E5 Section 9.9)\n *  CheckObjectCoercible()  (E5 Section 9.10)\n *  IsCallable()  (E5 Section 9.11)\n *\n *  ==> implemented in the API.\n */\n\n/*\n *  Loose equality, strict equality, and SameValue (E5 Sections 11.9.1, 11.9.4,\n *  9.12).  These have much in common so they can share some helpers.\n *\n *  Future work notes:\n *\n *    - Current implementation (and spec definition) has recursion; this should\n *      be fixed if possible.\n *\n *    - String-to-number coercion should be possible without going through the\n *      value stack (and be more compact) if a shared helper is invoked.\n */\n\n/* Note that this is the same operation for strict and loose equality:\n *  - E5 Section 11.9.3, step 1.c (loose)\n *  - E5 Section 11.9.6, step 4 (strict)\n */\n\nDUK_LOCAL duk_bool_t duk__js_equals_number(duk_double_t x, duk_double_t y) {\n#if defined(DUK_USE_PARANOID_MATH)\n\t/* Straightforward algorithm, makes fewer compiler assumptions. */\n\tduk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tduk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\tif (cx == DUK_FP_NAN || cy == DUK_FP_NAN) {\n\t\treturn 0;\n\t}\n\tif (cx == DUK_FP_ZERO && cy == DUK_FP_ZERO) {\n\t\treturn 1;\n\t}\n\tif (x == y) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else  /* DUK_USE_PARANOID_MATH */\n\t/* Better equivalent algorithm.  If the compiler is compliant, C and\n\t * ECMAScript semantics are identical for this particular comparison.\n\t * In particular, NaNs must never compare equal and zeroes must compare\n\t * equal regardless of sign.  Could also use a macro, but this inlines\n\t * already nicely (no difference on gcc, for instance).\n\t */\n\tif (x == y) {\n\t\t/* IEEE requires that NaNs compare false */\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(x) != DUK_FP_NAN);\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(y) != DUK_FP_NAN);\n\t\treturn 1;\n\t} else {\n\t\t/* IEEE requires that zeros compare the same regardless\n\t\t * of their signed, so if both x and y are zeroes, they\n\t\t * are caught above.\n\t\t */\n\t\tDUK_ASSERT(!(DUK_FPCLASSIFY(x) == DUK_FP_ZERO && DUK_FPCLASSIFY(y) == DUK_FP_ZERO));\n\t\treturn 0;\n\t}\n#endif  /* DUK_USE_PARANOID_MATH */\n}\n\nDUK_LOCAL duk_bool_t duk__js_samevalue_number(duk_double_t x, duk_double_t y) {\n#if defined(DUK_USE_PARANOID_MATH)\n\tduk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tduk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\n\tif (cx == DUK_FP_NAN && cy == DUK_FP_NAN) {\n\t\t/* SameValue(NaN, NaN) = true, regardless of NaN sign or extra bits */\n\t\treturn 1;\n\t}\n\tif (cx == DUK_FP_ZERO && cy == DUK_FP_ZERO) {\n\t\t/* Note: cannot assume that a non-zero return value of signbit() would\n\t\t * always be the same -- hence cannot (portably) use something like:\n\t\t *\n\t\t *     signbit(x) == signbit(y)\n\t\t */\n\t\tduk_small_int_t sx = DUK_SIGNBIT(x) ? 1 : 0;\n\t\tduk_small_int_t sy = DUK_SIGNBIT(y) ? 1 : 0;\n\t\treturn (sx == sy);\n\t}\n\n\t/* normal comparison; known:\n\t *   - both x and y are not NaNs (but one of them can be)\n\t *   - both x and y are not zero (but one of them can be)\n\t *   - x and y may be denormal or infinite\n\t */\n\n\treturn (x == y);\n#else  /* DUK_USE_PARANOID_MATH */\n\tduk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tduk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\n\tif (x == y) {\n\t\t/* IEEE requires that NaNs compare false */\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(x) != DUK_FP_NAN);\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(y) != DUK_FP_NAN);\n\n\t\t/* Using classification has smaller footprint than direct comparison. */\n\t\tif (DUK_UNLIKELY(cx == DUK_FP_ZERO && cy == DUK_FP_ZERO)) {\n\t\t\t/* Note: cannot assume that a non-zero return value of signbit() would\n\t\t\t * always be the same -- hence cannot (portably) use something like:\n\t\t\t *\n\t\t\t *     signbit(x) == signbit(y)\n\t\t\t */\n\t\t\treturn duk_double_same_sign(x, y);\n\t\t}\n\t\treturn 1;\n\t} else {\n\t\t/* IEEE requires that zeros compare the same regardless\n\t\t * of their sign, so if both x and y are zeroes, they\n\t\t * are caught above.\n\t\t */\n\t\tDUK_ASSERT(!(DUK_FPCLASSIFY(x) == DUK_FP_ZERO && DUK_FPCLASSIFY(y) == DUK_FP_ZERO));\n\n\t\t/* Difference to non-strict/strict comparison is that NaNs compare\n\t\t * equal and signed zero signs matter.\n\t\t */\n\t\tif (DUK_UNLIKELY(cx == DUK_FP_NAN && cy == DUK_FP_NAN)) {\n\t\t\t/* SameValue(NaN, NaN) = true, regardless of NaN sign or extra bits */\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t}\n#endif  /* DUK_USE_PARANOID_MATH */\n}\n\nDUK_INTERNAL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags) {\n\tduk_uint_t type_mask_x;\n\tduk_uint_t type_mask_y;\n\n\t/* If flags != 0 (strict or SameValue), thr can be NULL.  For loose\n\t * equals comparison it must be != NULL.\n\t */\n\tDUK_ASSERT(flags != 0 || thr != NULL);\n\n\t/*\n\t *  Same type?\n\t *\n\t *  Note: since number values have no explicit tag in the 8-byte\n\t *  representation, need the awkward if + switch.\n\t */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\tif (DUK_TVAL_GET_FASTINT(tv_x) == DUK_TVAL_GET_FASTINT(tv_y)) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}\n\telse\n#endif\n\tif (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) {\n\t\tduk_double_t d1, d2;\n\n\t\t/* Catches both doubles and cases where only one argument is\n\t\t * a fastint so can't assume a double.\n\t\t */\n\t\td1 = DUK_TVAL_GET_NUMBER(tv_x);\n\t\td2 = DUK_TVAL_GET_NUMBER(tv_y);\n\t\tif (DUK_UNLIKELY((flags & DUK_EQUALS_FLAG_SAMEVALUE) != 0)) {\n\t\t\t/* SameValue */\n\t\t\treturn duk__js_samevalue_number(d1, d2);\n\t\t} else {\n\t\t\t/* equals and strict equals */\n\t\t\treturn duk__js_equals_number(d1, d2);\n\t\t}\n\t} else if (DUK_TVAL_GET_TAG(tv_x) == DUK_TVAL_GET_TAG(tv_y)) {\n\t\tswitch (DUK_TVAL_GET_TAG(tv_x)) {\n\t\tcase DUK_TAG_UNDEFINED:\n\t\tcase DUK_TAG_NULL: {\n\t\t\treturn 1;\n\t\t}\n\t\tcase DUK_TAG_BOOLEAN: {\n\t\t\treturn DUK_TVAL_GET_BOOLEAN(tv_x) == DUK_TVAL_GET_BOOLEAN(tv_y);\n\t\t}\n\t\tcase DUK_TAG_POINTER: {\n\t\t\treturn DUK_TVAL_GET_POINTER(tv_x) == DUK_TVAL_GET_POINTER(tv_y);\n\t\t}\n\t\tcase DUK_TAG_STRING:\n\t\tcase DUK_TAG_OBJECT: {\n\t\t\t/* Heap pointer comparison suffices for strings and objects.\n\t\t\t * Symbols compare equal if they have the same internal\n\t\t\t * representation; again heap pointer comparison suffices.\n\t\t\t */\n\t\t\treturn DUK_TVAL_GET_HEAPHDR(tv_x) == DUK_TVAL_GET_HEAPHDR(tv_y);\n\t\t}\n\t\tcase DUK_TAG_BUFFER: {\n\t\t\t/* In Duktape 2.x plain buffers mimic Uint8Array objects\n\t\t\t * so always compare by heap pointer.  In Duktape 1.x\n\t\t\t * strict comparison would compare heap pointers and\n\t\t\t * non-strict would compare contents.\n\t\t\t */\n\t\t\treturn DUK_TVAL_GET_HEAPHDR(tv_x) == DUK_TVAL_GET_HEAPHDR(tv_y);\n\t\t}\n\t\tcase DUK_TAG_LIGHTFUNC: {\n\t\t\t/* At least 'magic' has a significant impact on function\n\t\t\t * identity.\n\t\t\t */\n\t\t\tduk_small_uint_t lf_flags_x;\n\t\t\tduk_small_uint_t lf_flags_y;\n\t\t\tduk_c_function func_x;\n\t\t\tduk_c_function func_y;\n\n\t\t\tDUK_TVAL_GET_LIGHTFUNC(tv_x, func_x, lf_flags_x);\n\t\t\tDUK_TVAL_GET_LIGHTFUNC(tv_y, func_y, lf_flags_y);\n\t\t\treturn ((func_x == func_y) && (lf_flags_x == lf_flags_y)) ? 1 : 0;\n\t\t}\n#if defined(DUK_USE_FASTINT)\n\t\tcase DUK_TAG_FASTINT:\n#endif\n\t\tdefault: {\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_x));\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_y));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_x));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_y));\n\t\t\tDUK_UNREACHABLE();\n\t\t\treturn 0;\n\t\t}\n\t\t}\n\t}\n\n\tif ((flags & (DUK_EQUALS_FLAG_STRICT | DUK_EQUALS_FLAG_SAMEVALUE)) != 0) {\n\t\treturn 0;\n\t}\n\n\tDUK_ASSERT(flags == 0);  /* non-strict equality from here on */\n\n\t/*\n\t *  Types are different; various cases for non-strict comparison\n\t *\n\t *  Since comparison is symmetric, we use a \"swap trick\" to reduce\n\t *  code size.\n\t */\n\n\ttype_mask_x = duk_get_type_mask_tval(tv_x);\n\ttype_mask_y = duk_get_type_mask_tval(tv_y);\n\n\t/* Undefined/null are considered equal (e.g. \"null == undefined\" -> true). */\n\tif ((type_mask_x & (DUK_TYPE_MASK_UNDEFINED | DUK_TYPE_MASK_NULL)) &&\n\t    (type_mask_y & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED))) {\n\t\treturn 1;\n\t}\n\n\t/* Number/string -> coerce string to number (e.g. \"'1.5' == 1.5\" -> true). */\n\tif ((type_mask_x & DUK_TYPE_MASK_NUMBER) && (type_mask_y & DUK_TYPE_MASK_STRING)) {\n\t\tif (!DUK_TVAL_STRING_IS_SYMBOL(tv_y)) {\n\t\t\tduk_double_t d1, d2;\n\t\t\td1 = DUK_TVAL_GET_NUMBER(tv_x);\n\t\t\td2 = duk_to_number_tval(thr, tv_y);\n\t\t\treturn duk__js_equals_number(d1, d2);\n\t\t}\n\t}\n\tif ((type_mask_x & DUK_TYPE_MASK_STRING) && (type_mask_y & DUK_TYPE_MASK_NUMBER)) {\n\t\tif (!DUK_TVAL_STRING_IS_SYMBOL(tv_x)) {\n\t\t\tduk_double_t d1, d2;\n\t\t\td1 = DUK_TVAL_GET_NUMBER(tv_y);\n\t\t\td2 = duk_to_number_tval(thr, tv_x);\n\t\t\treturn duk__js_equals_number(d1, d2);\n\t\t}\n\t}\n\n\t/* Boolean/any -> coerce boolean to number and try again.  If boolean is\n\t * compared to a pointer, the final comparison after coercion now always\n\t * yields false (as pointer vs. number compares to false), but this is\n\t * not special cased.\n\t *\n\t * ToNumber(bool) is +1.0 or 0.0.  Tagged boolean value is always 0 or 1.\n\t */\n\tif (type_mask_x & DUK_TYPE_MASK_BOOLEAN) {\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv_x) == 0 || DUK_TVAL_GET_BOOLEAN(tv_x) == 1);\n\t\tduk_push_uint(thr, DUK_TVAL_GET_BOOLEAN(tv_x));\n\t\tduk_push_tval(thr, tv_y);\n\t\tgoto recursive_call;\n\t}\n\tif (type_mask_y & DUK_TYPE_MASK_BOOLEAN) {\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv_y) == 0 || DUK_TVAL_GET_BOOLEAN(tv_y) == 1);\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_uint(thr, DUK_TVAL_GET_BOOLEAN(tv_y));\n\t\tgoto recursive_call;\n\t}\n\n\t/* String-number-symbol/object -> coerce object to primitive (apparently without hint), then try again. */\n\tif ((type_mask_x & (DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_NUMBER)) &&\n\t    (type_mask_y & DUK_TYPE_MASK_OBJECT)) {\n\t\t/* No symbol check needed because symbols and strings are accepted. */\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NONE);  /* apparently no hint? */\n\t\tgoto recursive_call;\n\t}\n\tif ((type_mask_x & DUK_TYPE_MASK_OBJECT) &&\n\t    (type_mask_y & (DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_NUMBER))) {\n\t\t/* No symbol check needed because symbols and strings are accepted. */\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\tduk_to_primitive(thr, -2, DUK_HINT_NONE);  /* apparently no hint? */\n\t\tgoto recursive_call;\n\t}\n\n\t/* Nothing worked -> not equal. */\n\treturn 0;\n\n recursive_call:\n\t/* Shared code path to call the helper again with arguments on stack top. */\n\t{\n\t\tduk_bool_t rc;\n\t\trc = duk_js_equals_helper(thr,\n\t\t                          DUK_GET_TVAL_NEGIDX(thr, -2),\n\t\t                          DUK_GET_TVAL_NEGIDX(thr, -1),\n\t\t                          0 /*flags:nonstrict*/);\n\t\tduk_pop_2_unsafe(thr);\n\t\treturn rc;\n\t}\n}\n\n/*\n *  Comparisons (x >= y, x > y, x <= y, x < y)\n *\n *  E5 Section 11.8.5: implement 'x < y' and then use negate and eval_left_first\n *  flags to get the rest.\n */\n\n/* XXX: this should probably just operate on the stack top, because it\n * needs to push stuff on the stack anyway...\n */\n\nDUK_INTERNAL duk_small_int_t duk_js_data_compare(const duk_uint8_t *buf1, const duk_uint8_t *buf2, duk_size_t len1, duk_size_t len2) {\n\tduk_size_t prefix_len;\n\tduk_small_int_t rc;\n\n\tprefix_len = (len1 <= len2 ? len1 : len2);\n\n\t/* duk_memcmp() is guaranteed to return zero (equal) for zero length\n\t * inputs.\n\t */\n\trc = duk_memcmp_unsafe((const void *) buf1,\n\t                       (const void *) buf2,\n\t                       (size_t) prefix_len);\n\n\tif (rc < 0) {\n\t\treturn -1;\n\t} else if (rc > 0) {\n\t\treturn 1;\n\t}\n\n\t/* prefix matches, lengths matter now */\n\tif (len1 < len2) {\n\t\t/* e.g. \"x\" < \"xx\" */\n\t\treturn -1;\n\t} else if (len1 > len2) {\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\nDUK_INTERNAL duk_small_int_t duk_js_string_compare(duk_hstring *h1, duk_hstring *h2) {\n\t/*\n\t *  String comparison (E5 Section 11.8.5, step 4), which\n\t *  needs to compare codepoint by codepoint.\n\t *\n\t *  However, UTF-8 allows us to use strcmp directly: the shared\n\t *  prefix will be encoded identically (UTF-8 has unique encoding)\n\t *  and the first differing character can be compared with a simple\n\t *  unsigned byte comparison (which strcmp does).\n\t *\n\t *  This will not work properly for non-xutf-8 strings, but this\n\t *  is not an issue for compliance.\n\t */\n\n\tDUK_ASSERT(h1 != NULL);\n\tDUK_ASSERT(h2 != NULL);\n\n\treturn duk_js_data_compare((const duk_uint8_t *) DUK_HSTRING_GET_DATA(h1),\n\t                           (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h2),\n\t                           (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1),\n\t                           (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2));\n}\n\n#if 0  /* unused */\nDUK_INTERNAL duk_small_int_t duk_js_buffer_compare(duk_heap *heap, duk_hbuffer *h1, duk_hbuffer *h2) {\n\t/* Similar to String comparison. */\n\n\tDUK_ASSERT(h1 != NULL);\n\tDUK_ASSERT(h2 != NULL);\n\tDUK_UNREF(heap);\n\n\treturn duk_js_data_compare((const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(heap, h1),\n\t                           (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(heap, h2),\n\t                           (duk_size_t) DUK_HBUFFER_GET_SIZE(h1),\n\t                           (duk_size_t) DUK_HBUFFER_GET_SIZE(h2));\n}\n#endif\n\n#if defined(DUK_USE_FASTINT)\nDUK_LOCAL duk_bool_t duk__compare_fastint(duk_bool_t retval, duk_int64_t v1, duk_int64_t v2) {\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\tif (v1 < v2) {\n\t\treturn retval ^ 1;\n\t} else {\n\t\treturn retval;\n\t}\n}\n#endif\n\n#if defined(DUK_USE_PARANOID_MATH)\nDUK_LOCAL duk_bool_t duk__compare_number(duk_bool_t retval, duk_double_t d1, duk_double_t d2) {\n\tduk_small_int_t c1, s1, c2, s2;\n\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\tc1 = (duk_small_int_t) DUK_FPCLASSIFY(d1);\n\ts1 = (duk_small_int_t) DUK_SIGNBIT(d1);\n\tc2 = (duk_small_int_t) DUK_FPCLASSIFY(d2);\n\ts2 = (duk_small_int_t) DUK_SIGNBIT(d2);\n\n\tif (c1 == DUK_FP_NAN || c2 == DUK_FP_NAN) {\n\t\treturn 0;  /* Always false, regardless of negation. */\n\t}\n\n\tif (c1 == DUK_FP_ZERO && c2 == DUK_FP_ZERO) {\n\t\t/* For all combinations: +0 < +0, +0 < -0, -0 < +0, -0 < -0,\n\t\t * steps e, f, and g.\n\t\t */\n\t\treturn retval;  /* false */\n\t}\n\n\tif (d1 == d2) {\n\t\treturn retval;  /* false */\n\t}\n\n\tif (c1 == DUK_FP_INFINITE && s1 == 0) {\n\t\t/* x == +Infinity */\n\t\treturn retval;  /* false */\n\t}\n\n\tif (c2 == DUK_FP_INFINITE && s2 == 0) {\n\t\t/* y == +Infinity */\n\t\treturn retval ^ 1;  /* true */\n\t}\n\n\tif (c2 == DUK_FP_INFINITE && s2 != 0) {\n\t\t/* y == -Infinity */\n\t\treturn retval;  /* false */\n\t}\n\n\tif (c1 == DUK_FP_INFINITE && s1 != 0) {\n\t\t/* x == -Infinity */\n\t\treturn retval ^ 1;  /* true */\n\t}\n\n\tif (d1 < d2) {\n\t\treturn retval ^ 1;  /* true */\n\t}\n\n\treturn retval;  /* false */\n}\n#else  /* DUK_USE_PARANOID_MATH */\nDUK_LOCAL duk_bool_t duk__compare_number(duk_bool_t retval, duk_double_t d1, duk_double_t d2) {\n\t/* This comparison tree relies doesn't match the exact steps in\n\t * E5 Section 11.8.5 but should produce the same results.  The\n\t * steps rely on exact IEEE semantics for NaNs, etc.\n\t */\n\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\tif (d1 < d2) {\n\t\t/* In no case should both (d1 < d2) and (d2 < d1) be true.\n\t\t * It's possible that neither is true though, and that's\n\t\t * handled below.\n\t\t */\n\t\tDUK_ASSERT(!(d2 < d1));\n\n\t\t/* - d1 < d2, both d1/d2 are normals (not Infinity, not NaN)\n\t\t * - d2 is +Infinity, d1 != +Infinity and NaN\n\t\t * - d1 is -Infinity, d2 != -Infinity and NaN\n\t\t */\n\t\treturn retval ^ 1;\n\t} else {\n\t\tif (d2 < d1) {\n\t\t\t/* - !(d1 < d2), both d1/d2 are normals (not Infinity, not NaN)\n\t\t\t * - d1 is +Infinity, d2 != +Infinity and NaN\n\t\t\t * - d2 is -Infinity, d1 != -Infinity and NaN\n\t\t\t */\n\t\t\treturn retval;\n\t\t} else {\n\t\t\t/* - d1 and/or d2 is NaN\n\t\t\t * - d1 and d2 are both +/- 0\n\t\t\t * - d1 == d2 (including infinities)\n\t\t\t */\n\t\t\tif (duk_double_is_nan(d1) || duk_double_is_nan(d2)) {\n\t\t\t\t/* Note: undefined from Section 11.8.5 always\n\t\t\t\t * results in false return (see e.g. Section\n\t\t\t\t * 11.8.3) - hence special treatment here.\n\t\t\t\t */\n\t\t\t\treturn 0;  /* zero regardless of negation */\n\t\t\t} else {\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\t}\n}\n#endif  /* DUK_USE_PARANOID_MATH */\n\nDUK_INTERNAL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags) {\n\tduk_double_t d1, d2;\n\tduk_small_int_t rc;\n\tduk_bool_t retval;\n\n\tDUK_ASSERT(DUK_COMPARE_FLAG_NEGATE == 1);  /* Rely on this flag being lowest. */\n\tretval = flags & DUK_COMPARE_FLAG_NEGATE;\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\n\t/* Fast path for fastints */\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_LIKELY(DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y))) {\n\t\treturn duk__compare_fastint(retval,\n\t\t                            DUK_TVAL_GET_FASTINT(tv_x),\n\t\t                            DUK_TVAL_GET_FASTINT(tv_y));\n\t}\n#endif  /* DUK_USE_FASTINT */\n\n\t/* Fast path for numbers (one of which may be a fastint) */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tif (DUK_LIKELY(DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y))) {\n\t\treturn duk__compare_number(retval,\n\t\t                           DUK_TVAL_GET_NUMBER(tv_x),\n\t\t                           DUK_TVAL_GET_NUMBER(tv_y));\n\t}\n#endif\n\n\t/* Slow path */\n\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\n\tif (flags & DUK_COMPARE_FLAG_EVAL_LEFT_FIRST) {\n\t\tduk_to_primitive(thr, -2, DUK_HINT_NUMBER);\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);\n\t} else {\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);\n\t\tduk_to_primitive(thr, -2, DUK_HINT_NUMBER);\n\t}\n\n\t/* Note: reuse variables */\n\ttv_x = DUK_GET_TVAL_NEGIDX(thr, -2);\n\ttv_y = DUK_GET_TVAL_NEGIDX(thr, -1);\n\n\tif (DUK_TVAL_IS_STRING(tv_x) && DUK_TVAL_IS_STRING(tv_y)) {\n\t\tduk_hstring *h1 = DUK_TVAL_GET_STRING(tv_x);\n\t\tduk_hstring *h2 = DUK_TVAL_GET_STRING(tv_y);\n\t\tDUK_ASSERT(h1 != NULL);\n\t\tDUK_ASSERT(h2 != NULL);\n\n\t\tif (DUK_LIKELY(!DUK_HSTRING_HAS_SYMBOL(h1) && !DUK_HSTRING_HAS_SYMBOL(h2))) {\n\t\t\trc = duk_js_string_compare(h1, h2);\n\t\t\tduk_pop_2_unsafe(thr);\n\t\t\tif (rc < 0) {\n\t\t\t\treturn retval ^ 1;\n\t\t\t} else {\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\n\t\t/* One or both are Symbols: fall through to handle in the\n\t\t * generic path.  Concretely, ToNumber() will fail.\n\t\t */\n\t}\n\n\t/* Ordering should not matter (E5 Section 11.8.5, step 3.a). */\n#if 0\n\tif (flags & DUK_COMPARE_FLAG_EVAL_LEFT_FIRST) {\n\t\td1 = duk_to_number_m2(thr);\n\t\td2 = duk_to_number_m1(thr);\n\t} else {\n\t\td2 = duk_to_number_m1(thr);\n\t\td1 = duk_to_number_m2(thr);\n\t}\n#endif\n\td1 = duk_to_number_m2(thr);\n\td2 = duk_to_number_m1(thr);\n\n\t/* We want to duk_pop_2_unsafe(thr); because the values are numbers\n\t * no decref check is needed.\n\t */\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_pop_2_nodecref_unsafe(thr);\n#else\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk_get_tval(thr, -2)));\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk_get_tval(thr, -1)));\n\tDUK_ASSERT(duk_get_top(thr) >= 2);\n\tthr->valstack_top -= 2;\n\ttv_x = thr->valstack_top;\n\ttv_y = tv_x + 1;\n\tDUK_TVAL_SET_UNDEFINED(tv_x);  /* Value stack policy */\n\tDUK_TVAL_SET_UNDEFINED(tv_y);\n#endif\n\n\treturn duk__compare_number(retval, d1, d2);\n}\n\n/*\n *  instanceof\n */\n\n/*\n *  ES2015 Section 7.3.19 describes the OrdinaryHasInstance() algorithm\n *  which covers both bound and non-bound functions; in effect the algorithm\n *  includes E5 Sections 11.8.6, 15.3.5.3, and 15.3.4.5.3.\n *\n *  ES2015 Section 12.9.4 describes the instanceof operator which first\n *  checks @@hasInstance well-known symbol and falls back to\n *  OrdinaryHasInstance().\n *\n *  Limited Proxy support: don't support 'getPrototypeOf' trap but\n *  continue lookup in Proxy target if the value is a Proxy.\n */\n\nDUK_LOCAL duk_bool_t duk__js_instanceof_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_bool_t skip_sym_check) {\n\tduk_hobject *func;\n\tduk_hobject *val;\n\tduk_hobject *proto;\n\tduk_tval *tv;\n\tduk_bool_t skip_first;\n\tduk_uint_t sanity;\n\n\t/*\n\t *  Get the values onto the stack first.  It would be possible to cover\n\t *  some normal cases without resorting to the value stack.\n\t *\n\t *  The right hand side could be a light function (as they generally\n\t *  behave like objects).  Light functions never have a 'prototype'\n\t *  property so E5.1 Section 15.3.5.3 step 3 always throws a TypeError.\n\t *  Using duk_require_hobject() is thus correct (except for error msg).\n\t */\n\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\tfunc = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(func != NULL);\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t/*\n\t *  @@hasInstance check, ES2015 Section 12.9.4, Steps 2-4.\n\t */\n\tif (!skip_sym_check) {\n\t\tif (duk_get_method_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE)) {\n\t\t\t/* [ ... lhs rhs func ] */\n\t\t\tduk_insert(thr, -3);    /* -> [ ... func lhs rhs ] */\n\t\t\tduk_swap_top(thr, -2);  /* -> [ ... func rhs(this) lhs ] */\n\t\t\tduk_call_method(thr, 1);\n\t\t\treturn duk_to_boolean_top_pop(thr);\n\t\t}\n\t}\n#else\n\tDUK_UNREF(skip_sym_check);\n#endif\n\n\t/*\n\t *  For bound objects, [[HasInstance]] just calls the target function\n\t *  [[HasInstance]].  If that is again a bound object, repeat until\n\t *  we find a non-bound Function object.\n\t *\n\t *  The bound function chain is now \"collapsed\" so there can be only\n\t *  one bound function in the chain.\n\t */\n\n\tif (!DUK_HOBJECT_IS_CALLABLE(func)) {\n\t\t/*\n\t\t *  Note: of native ECMAScript objects, only Function instances\n\t\t *  have a [[HasInstance]] internal property.  Custom objects might\n\t\t *  also have it, but not in current implementation.\n\t\t *\n\t\t *  XXX: add a separate flag, DUK_HOBJECT_FLAG_ALLOW_INSTANCEOF?\n\t\t */\n\t\tgoto error_invalid_rval;\n\t}\n\n\tif (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {\n\t\tduk_push_tval(thr, &((duk_hboundfunc *) (void *) func)->target);\n\t\tduk_replace(thr, -2);\n\t\tfunc = duk_require_hobject(thr, -1);  /* lightfunc throws */\n\n\t\t/* Rely on Function.prototype.bind() never creating bound\n\t\t * functions whose target is not proper.\n\t\t */\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(func));\n\t}\n\n\t/*\n\t *  'func' is now a non-bound object which supports [[HasInstance]]\n\t *  (which here just means DUK_HOBJECT_FLAG_CALLABLE).  Move on\n\t *  to execute E5 Section 15.3.5.3.\n\t */\n\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\tDUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(func));\n\n\t/* [ ... lval rval(func) ] */\n\n\t/* For lightfuncs, buffers, and pointers start the comparison directly\n\t * from the virtual prototype object.\n\t */\n\tskip_first = 0;\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -2);\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_LIGHTFUNC:\n\t\tval = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tcase DUK_TAG_BUFFER:\n\t\tval = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tcase DUK_TAG_POINTER:\n\t\tval = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\tskip_first = 1;  /* Ignore object itself on first round. */\n\t\tval = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tdefault:\n\t\tgoto pop2_and_false;\n\t}\n\tDUK_ASSERT(val != NULL);  /* Loop doesn't actually rely on this. */\n\n\t/* Look up .prototype of rval.  Leave it on the value stack in case it\n\t * has been virtualized (e.g. getter, Proxy trap).\n\t */\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_PROTOTYPE);  /* -> [ ... lval rval rval.prototype ] */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\tproto = duk_get_hobject(thr, -1);\n\tif (proto == NULL) {\n\t\tgoto error_invalid_rval_noproto;\n\t}\n#else\n\tproto = duk_require_hobject(thr, -1);\n#endif\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\t/*\n\t\t *  Note: prototype chain is followed BEFORE first comparison.  This\n\t\t *  means that the instanceof lval is never itself compared to the\n\t\t *  rval.prototype property.  This is apparently intentional, see E5\n\t\t *  Section 15.3.5.3, step 4.a.\n\t\t *\n\t\t *  Also note:\n\t\t *\n\t\t *      js> (function() {}) instanceof Function\n\t\t *      true\n\t\t *      js> Function instanceof Function\n\t\t *      true\n\t\t *\n\t\t *  For the latter, h_proto will be Function.prototype, which is the\n\t\t *  built-in Function prototype.  Because Function.[[Prototype]] is\n\t\t *  also the built-in Function prototype, the result is true.\n\t\t */\n\n\t\tif (!val) {\n\t\t\tgoto pop3_and_false;\n\t\t}\n\n\t\tDUK_ASSERT(val != NULL);\n#if defined(DUK_USE_ES6_PROXY)\n\t\tval = duk_hobject_resolve_proxy_target(val);\n#endif\n\n\t\tif (skip_first) {\n\t\t\tskip_first = 0;\n\t\t} else if (val == proto) {\n\t\t\tgoto pop3_and_true;\n\t\t}\n\n\t\tDUK_ASSERT(val != NULL);\n\t\tval = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, val);\n\t} while (--sanity > 0);\n\n\tif (DUK_UNLIKELY(sanity == 0)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tDUK_UNREACHABLE();\n\n pop2_and_false:\n\tduk_pop_2_unsafe(thr);\n\treturn 0;\n\n pop3_and_false:\n\tduk_pop_3_unsafe(thr);\n\treturn 0;\n\n pop3_and_true:\n\tduk_pop_3_unsafe(thr);\n\treturn 1;\n\n error_invalid_rval:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_INSTANCEOF_RVAL);\n\tDUK_WO_NORETURN(return 0;);\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n error_invalid_rval_noproto:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_INSTANCEOF_RVAL_NOPROTO);\n\tDUK_WO_NORETURN(return 0;);\n#endif\n}\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL duk_bool_t duk_js_instanceof_ordinary(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {\n\treturn duk__js_instanceof_helper(thr, tv_x, tv_y, 1 /*skip_sym_check*/);\n}\n#endif\n\nDUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {\n\treturn duk__js_instanceof_helper(thr, tv_x, tv_y, 0 /*skip_sym_check*/);\n}\n\n/*\n *  in\n */\n\n/*\n *  E5 Sections 11.8.7, 8.12.6.\n *\n *  Basically just a property existence check using [[HasProperty]].\n */\n\nDUK_INTERNAL duk_bool_t duk_js_in(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {\n\tduk_bool_t retval;\n\n\t/*\n\t *  Get the values onto the stack first.  It would be possible to cover\n\t *  some normal cases without resorting to the value stack (e.g. if\n\t *  lval is already a string).\n\t */\n\n\t/* XXX: The ES5/5.1/6 specifications require that the key in 'key in obj'\n\t * must be string coerced before the internal HasProperty() algorithm is\n\t * invoked.  A fast path skipping coercion could be safely implemented for\n\t * numbers (as number-to-string coercion has no side effects).  For ES2015\n\t * proxy behavior, the trap 'key' argument must be in a string coerced\n\t * form (which is a shame).\n\t */\n\n\t/* TypeError if rval is not an object or object like (e.g. lightfunc\n\t * or plain buffer).\n\t */\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\tduk_require_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT | DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\n\t(void) duk_to_property_key_hstring(thr, -2);\n\n\tretval = duk_hobject_hasprop(thr,\n\t                             DUK_GET_TVAL_NEGIDX(thr, -1),\n\t                             DUK_GET_TVAL_NEGIDX(thr, -2));\n\n\tduk_pop_2_unsafe(thr);\n\treturn retval;\n}\n\n/*\n *  typeof\n *\n *  E5 Section 11.4.3.\n *\n *  Very straightforward.  The only question is what to return for our\n *  non-standard tag / object types.\n *\n *  There is an unfortunate string constant define naming problem with\n *  typeof return values for e.g. \"Object\" and \"object\"; careful with\n *  the built-in string defines.  The LC_XXX defines are used for the\n *  lowercase variants now.\n */\n\nDUK_INTERNAL duk_small_uint_t duk_js_typeof_stridx(duk_tval *tv_x) {\n\tduk_small_uint_t stridx = 0;\n\n\tswitch (DUK_TVAL_GET_TAG(tv_x)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\tstridx = DUK_STRIDX_LC_UNDEFINED;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\t/* Note: not a typo, \"object\" is returned for a null value. */\n\t\tstridx = DUK_STRIDX_LC_OBJECT;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tstridx = DUK_STRIDX_LC_BOOLEAN;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\t/* Implementation specific. */\n\t\tstridx = DUK_STRIDX_LC_POINTER;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *str;\n\n\t\t/* All internal keys are identified as Symbols. */\n\t\tstr = DUK_TVAL_GET_STRING(tv_x);\n\t\tDUK_ASSERT(str != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(str))) {\n\t\t\tstridx = DUK_STRIDX_LC_SYMBOL;\n\t\t} else {\n\t\t\tstridx = DUK_STRIDX_LC_STRING;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *obj = DUK_TVAL_GET_OBJECT(tv_x);\n\t\tDUK_ASSERT(obj != NULL);\n\t\tif (DUK_HOBJECT_IS_CALLABLE(obj)) {\n\t\t\tstridx = DUK_STRIDX_LC_FUNCTION;\n\t\t} else {\n\t\t\tstridx = DUK_STRIDX_LC_OBJECT;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\t/* Implementation specific.  In Duktape 1.x this would be\n\t\t * 'buffer', in Duktape 2.x changed to 'object' because plain\n\t\t * buffers now mimic Uint8Array objects.\n\t\t */\n\t\tstridx = DUK_STRIDX_LC_OBJECT;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tstridx = DUK_STRIDX_LC_FUNCTION;\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_x));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_x));\n\t\tstridx = DUK_STRIDX_LC_NUMBER;\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\treturn stridx;\n}\n\n/*\n *  Array index and length\n *\n *  Array index: E5 Section 15.4\n *  Array length: E5 Section 15.4.5.1 steps 3.c - 3.d (array length write)\n */\n\n/* Compure array index from string context, or return a \"not array index\"\n * indicator.\n */\nDUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_string(const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uarridx_t res;\n\n\t/* Only strings with byte length 1-10 can be 32-bit array indices.\n\t * Leading zeroes (except '0' alone), plus/minus signs are not allowed.\n\t * We could do a lot of prechecks here, but since most strings won't\n\t * start with any digits, it's simpler to just parse the number and\n\t * fail quickly.\n\t */\n\n\tres = 0;\n\tif (blen == 0) {\n\t\tgoto parse_fail;\n\t}\n\tdo {\n\t\tduk_uarridx_t dig;\n\t\tdig = (duk_uarridx_t) (*str++) - DUK_ASC_0;\n\n\t\tif (dig <= 9U) {\n\t\t\t/* Careful overflow handling.  When multiplying by 10:\n\t\t\t * - 0x19999998 x 10 = 0xfffffff0: no overflow, and adding\n\t\t\t *   0...9 is safe.\n\t\t\t * - 0x19999999 x 10 = 0xfffffffa: no overflow, adding\n\t\t\t *   0...5 is safe, 6...9 overflows.\n\t\t\t * - 0x1999999a x 10 = 0x100000004: always overflow.\n\t\t\t */\n\t\t\tif (DUK_UNLIKELY(res >= 0x19999999UL)) {\n\t\t\t\tif (res >= 0x1999999aUL) {\n\t\t\t\t\t/* Always overflow. */\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(res == 0x19999999UL);\n\t\t\t\tif (dig >= 6U) {\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t\tres = 0xfffffffaUL + dig;\n\t\t\t\tDUK_ASSERT(res >= 0xfffffffaUL);\n\t\t\t\tDUK_ASSERT_DISABLE(res <= 0xffffffffUL);  /* range */\n\t\t\t} else {\n\t\t\t\tres = res * 10U + dig;\n\t\t\t\tif (DUK_UNLIKELY(res == 0)) {\n\t\t\t\t\t/* If 'res' is 0, previous 'res' must\n\t\t\t\t\t * have been 0 and we scanned in a zero.\n\t\t\t\t\t * This is only allowed if blen == 1,\n\t\t\t\t\t * i.e. the exact string '0'.\n\t\t\t\t\t */\n\t\t\t\t\tif (blen == (duk_uint32_t) 1) {\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\t}\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t/* Because 'dig' is unsigned, catches both values\n\t\t\t * above '9' and below '0'.\n\t\t\t */\n\t\t\tgoto parse_fail;\n\t\t}\n\t} while (--blen > 0);\n\n\treturn res;\n\n parse_fail:\n\treturn DUK_HSTRING_NO_ARRAY_INDEX;\n}\n\n#if !defined(DUK_USE_HSTRING_ARRIDX)\n/* Get array index for a string which is known to be an array index.  This helper\n * is needed when duk_hstring doesn't concretely store the array index, but strings\n * are flagged as array indices at intern time.\n */\nDUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_hstring_fast_known(duk_hstring *h) {\n\tconst duk_uint8_t *p;\n\tduk_uarridx_t res;\n\tduk_uint8_t t;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(h));\n\n\tp = DUK_HSTRING_GET_DATA(h);\n\tres = 0;\n\tfor (;;) {\n\t\tt = *p++;\n\t\tif (DUK_UNLIKELY(t == 0)) {\n\t\t\t/* Scanning to NUL is always safe for interned strings. */\n\t\t\tbreak;\n\t\t}\n\t\tDUK_ASSERT(t >= (duk_uint8_t) DUK_ASC_0 && t <= (duk_uint8_t) DUK_ASC_9);\n\t\tres = res * 10U + (duk_uarridx_t) t - (duk_uarridx_t) DUK_ASC_0;\n\t}\n\treturn res;\n}\n\nDUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_hstring_fast(duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n\tif (!DUK_HSTRING_HAS_ARRIDX(h)) {\n\t\treturn DUK_HSTRING_NO_ARRAY_INDEX;\n\t}\n\treturn duk_js_to_arrayindex_hstring_fast_known(h);\n}\n#endif  /* DUK_USE_HSTRING_ARRIDX */\n#line 1 \"duk_js_var.c\"\n/*\n *  Identifier access and function closure handling.\n *\n *  Provides the primitives for slow path identifier accesses: GETVAR,\n *  PUTVAR, DELVAR, etc.  The fast path, direct register accesses, should\n *  be used for most identifier accesses.  Consequently, these slow path\n *  primitives should be optimized for maximum compactness.\n *\n *  ECMAScript environment records (declarative and object) are represented\n *  as internal objects with control keys.  Environment records have a\n *  parent record (\"outer environment reference\") which is represented by\n *  the implicit prototype for technical reasons (in other words, it is a\n *  convenient field).  The prototype chain is not followed in the ordinary\n *  sense for variable lookups.\n *\n *  See identifier-handling.rst for more details on the identifier algorithms\n *  and the internal representation.  See function-objects.rst for details on\n *  what function templates and instances are expected to look like.\n *\n *  Care must be taken to avoid duk_tval pointer invalidation caused by\n *  e.g. value stack or object resizing.\n *\n *  TODO: properties for function instances could be initialized much more\n *  efficiently by creating a property allocation for a certain size and\n *  filling in keys and values directly (and INCREFing both with \"bulk incref\"\n *  primitives.\n *\n *  XXX: duk_hobject_getprop() and duk_hobject_putprop() calls are a bit\n *  awkward (especially because they follow the prototype chain); rework\n *  if \"raw\" own property helpers are added.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Local result type for duk__get_identifier_reference() lookup.\n */\n\ntypedef struct {\n\tduk_hobject *env;\n\tduk_hobject *holder;      /* for object-bound identifiers */\n\tduk_tval *value;          /* for register-bound and declarative env identifiers */\n\tduk_uint_t attrs;         /* property attributes for identifier (relevant if value != NULL) */\n\tduk_bool_t has_this;      /* for object-bound identifiers: provide 'this' binding */\n} duk__id_lookup_result;\n\n/*\n *  Create a new function object based on a \"template function\" which contains\n *  compiled bytecode, constants, etc, but lacks a lexical environment.\n *\n *  ECMAScript requires that each created closure is a separate object, with\n *  its own set of editable properties.  However, structured property values\n *  (such as the formal arguments list and the variable map) are shared.\n *  Also the bytecode, constants, and inner functions are shared.\n *\n *  See E5 Section 13.2 for detailed requirements on the function objects;\n *  there are no similar requirements for function \"templates\" which are an\n *  implementation dependent internal feature.  Also see function-objects.rst\n *  for a discussion on the function instance properties provided by this\n *  implementation.\n *\n *  Notes:\n *\n *   * Order of internal properties should match frequency of use, since the\n *     properties will be linearly scanned on lookup (functions usually don't\n *     have enough properties to warrant a hash part).\n *\n *   * The created closure is independent of its template; they do share the\n *     same 'data' buffer object, but the template object itself can be freed\n *     even if the closure object remains reachable.\n */\n\nDUK_LOCAL void duk__inc_data_inner_refcounts(duk_hthread *thr, duk_hcompfunc *f) {\n\tduk_tval *tv, *tv_end;\n\tduk_hobject **funcs, **funcs_end;\n\n\tDUK_UNREF(thr);\n\n\t/* If function creation fails due to out-of-memory, the data buffer\n\t * pointer may be NULL in some cases.  That's actually possible for\n\t * GC code, but shouldn't be possible here because the incomplete\n\t * function will be unwound from the value stack and never instantiated.\n\t */\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, f) != NULL);\n\n\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, f);\n\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, f);\n\twhile (tv < tv_end) {\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\ttv++;\n\t}\n\n\tfuncs = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, f);\n\tfuncs_end = DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, f);\n\twhile (funcs < funcs_end) {\n\t\tDUK_HEAPHDR_INCREF(thr, (duk_heaphdr *) *funcs);\n\t\tfuncs++;\n\t}\n}\n\n/* Push a new closure on the stack.\n *\n * Note: if fun_temp has NEWENV, i.e. a new lexical and variable declaration\n * is created when the function is called, only outer_lex_env matters\n * (outer_var_env is ignored and may or may not be same as outer_lex_env).\n */\n\nDUK_LOCAL const duk_uint16_t duk__closure_copy_proplist[] = {\n\t/* order: most frequent to least frequent */\n\tDUK_STRIDX_INT_VARMAP,\n\tDUK_STRIDX_INT_FORMALS,\n#if defined(DUK_USE_PC2LINE)\n\tDUK_STRIDX_INT_PC2LINE,\n#endif\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tDUK_STRIDX_FILE_NAME,\n#endif\n#if defined(DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY)\n\tDUK_STRIDX_INT_SOURCE\n#endif\n};\n\nDUK_INTERNAL\nvoid duk_js_push_closure(duk_hthread *thr,\n                         duk_hcompfunc *fun_temp,\n                         duk_hobject *outer_var_env,\n                         duk_hobject *outer_lex_env,\n                         duk_bool_t add_auto_proto) {\n\tduk_hcompfunc *fun_clos;\n\tduk_harray *formals;\n\tduk_small_uint_t i;\n\tduk_uint_t len_value;\n\n\tDUK_ASSERT(fun_temp != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_temp) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_temp) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_temp) != NULL);\n\tDUK_ASSERT(outer_var_env != NULL);\n\tDUK_ASSERT(outer_lex_env != NULL);\n\tDUK_UNREF(len_value);\n\n\tDUK_STATS_INC(thr->heap, stats_envrec_pushclosure);\n\n\tfun_clos = duk_push_hcompfunc(thr);\n\tDUK_ASSERT(fun_clos != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) fun_clos) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\n\tduk_push_hobject(thr, &fun_temp->obj);  /* -> [ ... closure template ] */\n\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun_clos));\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_clos) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_clos) == NULL);\n\n\tDUK_HCOMPFUNC_SET_DATA(thr->heap, fun_clos, DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_temp));\n\tDUK_HCOMPFUNC_SET_FUNCS(thr->heap, fun_clos, DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_temp));\n\tDUK_HCOMPFUNC_SET_BYTECODE(thr->heap, fun_clos, DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_temp));\n\n\t/* Note: all references inside 'data' need to get their refcounts\n\t * upped too.  This is the case because refcounts are decreased\n\t * through every function referencing 'data' independently.\n\t */\n\n\tDUK_HBUFFER_INCREF(thr, DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos));\n\tduk__inc_data_inner_refcounts(thr, fun_temp);\n\n\tfun_clos->nregs = fun_temp->nregs;\n\tfun_clos->nargs = fun_temp->nargs;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tfun_clos->start_line = fun_temp->start_line;\n\tfun_clos->end_line = fun_temp->end_line;\n#endif\n\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_clos) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_clos) != NULL);\n\n\t/* XXX: Could also copy from template, but there's no way to have any\n\t * other value here now (used code has no access to the template).\n\t * Prototype is set by duk_push_hcompfunc().\n\t */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, &fun_clos->obj) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#if 0\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, &fun_clos->obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#endif\n\n\t/* Copy duk_hobject flags as is from the template using a mask.\n\t * Leave out duk_heaphdr owned flags just in case (e.g. if there's\n\t * some GC flag or similar).  Some flags can then be adjusted\n\t * separately if necessary.\n\t */\n\n\t/* DUK_HEAPHDR_SET_FLAGS() masks changes to non-duk_heaphdr flags only. */\n\tDUK_HEAPHDR_SET_FLAGS((duk_heaphdr *) fun_clos, DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) fun_temp));\n\tDUK_DD(DUK_DDPRINT(\"fun_temp heaphdr flags: 0x%08lx, fun_clos heaphdr flags: 0x%08lx\",\n\t                   (unsigned long) DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) fun_temp),\n\t                   (unsigned long) DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) fun_clos)));\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&fun_clos->obj));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(&fun_clos->obj));\n\t/* DUK_HOBJECT_FLAG_ARRAY_PART: don't care */\n\t/* DUK_HOBJECT_FLAG_NEWENV: handled below */\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(&fun_clos->obj));\n\n\tif (!DUK_HOBJECT_HAS_CONSTRUCTABLE(&fun_clos->obj)) {\n\t\t/* If the template is not constructable don't add an automatic\n\t\t * .prototype property.  This is the case for e.g. ES2015 object\n\t\t * literal getters/setters and method definitions.\n\t\t */\n\t\tadd_auto_proto = 0;\n\t}\n\n\t/*\n\t *  Setup environment record properties based on the template and\n\t *  its flags.\n\t *\n\t *  If DUK_HOBJECT_HAS_NEWENV(fun_temp) is true, the environment\n\t *  records represent identifiers \"outside\" the function; the\n\t *  \"inner\" environment records are created on demand.  Otherwise,\n\t *  the environment records are those that will be directly used\n\t *  (e.g. for declarations).\n\t *\n\t *  _Lexenv is always set; _Varenv defaults to _Lexenv if missing,\n\t *  so _Varenv is only set if _Lexenv != _Varenv.\n\t *\n\t *  This is relatively complex, see doc/identifier-handling.rst.\n\t */\n\n\tif (DUK_HOBJECT_HAS_NEWENV(&fun_clos->obj)) {\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\t\tif (DUK_HOBJECT_HAS_NAMEBINDING(&fun_clos->obj)) {\n\t\t\tduk_hobject *proto;\n\t\t\tduk_hdecenv *new_env;\n\n\t\t\t/*\n\t\t\t *  Named function expression, name needs to be bound\n\t\t\t *  in an intermediate environment record.  The \"outer\"\n\t\t\t *  lexical/variable environment will thus be:\n\t\t\t *\n\t\t\t *  a) { funcname: <func>, __prototype: outer_lex_env }\n\t\t\t *  b) { funcname: <func>, __prototype:  <globalenv> }  (if outer_lex_env missing)\n\t\t\t */\n\n\t\t\tif (outer_lex_env) {\n\t\t\t\tproto = outer_lex_env;\n\t\t\t} else {\n\t\t\t\tproto = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t\t\t}\n\n\t\t\t/* -> [ ... closure template env ] */\n\t\t\tnew_env = duk_hdecenv_alloc(thr,\n\t\t\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\t\t\tDUK_ASSERT(new_env != NULL);\n\t\t\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, proto);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, proto);\n\n\t\t\tDUK_ASSERT(new_env->thread == NULL);  /* Closed. */\n\t\t\tDUK_ASSERT(new_env->varmap == NULL);\n\n\t\t\t/* It's important that duk_xdef_prop() is a 'raw define' so that any\n\t\t\t * properties in an ancestor are never an issue (they should never be\n\t\t\t * e.g. non-writable, but just in case).\n\t\t\t *\n\t\t\t * Because template objects are not visible to user code, the case\n\t\t\t * where .name is missing shouldn't happen in practice.  It it does,\n\t\t\t * the name 'undefined' gets bound and maps to the closure (which is\n\t\t\t * a bit odd, but safe).\n\t\t\t */\n\t\t\t(void) duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME);\n\t\t\t/* -> [ ... closure template env funcname ] */\n\t\t\tduk_dup_m4(thr);                                           /* -> [ ... closure template env funcname closure ] */\n\t\t\tduk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_NONE);           /* -> [ ... closure template env ] */\n\t\t\t/* env[funcname] = closure */\n\n\t\t\t/* [ ... closure template env ] */\n\n\t\t\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, fun_clos, (duk_hobject *) new_env);\n\t\t\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, (duk_hobject *) new_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env);\n\t\t\tduk_pop_unsafe(thr);\n\n\t\t\t/* [ ... closure template ] */\n\t\t}\n\t\telse\n#endif  /* DUK_USE_FUNC_NAME_PROPERTY */\n\t\t{\n\t\t\t/*\n\t\t\t *  Other cases (function declaration, anonymous function expression,\n\t\t\t *  strict direct eval code).  The \"outer\" environment will be whatever\n\t\t\t *  the caller gave us.\n\t\t\t */\n\n\t\t\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, fun_clos, outer_lex_env);\n\t\t\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, outer_lex_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, outer_lex_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, outer_lex_env);\n\n\t\t\t/* [ ... closure template ] */\n\t\t}\n\t} else {\n\t\t/*\n\t\t *  Function gets no new environment when called.  This is the\n\t\t *  case for global code, indirect eval code, and non-strict\n\t\t *  direct eval code.  There is no direct correspondence to the\n\t\t *  E5 specification, as global/eval code is not exposed as a\n\t\t *  function.\n\t\t */\n\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NAMEBINDING(&fun_temp->obj));\n\n\t\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, fun_clos, outer_lex_env);\n\t\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, outer_var_env);\n\t\tDUK_HOBJECT_INCREF(thr, outer_lex_env);  /* NULLs not allowed; asserted on entry */\n\t\tDUK_HOBJECT_INCREF(thr, outer_var_env);\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"closure varenv -> %!ipO, lexenv -> %!ipO\",\n\t                     (duk_heaphdr *) fun_clos->var_env,\n\t                     (duk_heaphdr *) fun_clos->lex_env));\n\n\t/* Call handling assumes this for all callable closures. */\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_LEXENV(thr->heap, fun_clos) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_VARENV(thr->heap, fun_clos) != NULL);\n\n\t/*\n\t *  Copy some internal properties directly\n\t *\n\t *  The properties will be non-writable and non-enumerable, but\n\t *  configurable.\n\t *\n\t *  Function templates are bare objects, so inheritance of internal\n\t *  Symbols is not an issue here even when using ordinary property\n\t *  reads.  The function instance created is not bare, so internal\n\t *  Symbols must be defined without inheritance checks.\n\t */\n\n\t/* [ ... closure template ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"copying properties: closure=%!iT, template=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tfor (i = 0; i < (duk_small_uint_t) (sizeof(duk__closure_copy_proplist) / sizeof(duk_uint16_t)); i++) {\n\t\tduk_small_int_t stridx = (duk_small_int_t) duk__closure_copy_proplist[i];\n\t\tif (duk_xget_owndataprop_stridx_short(thr, -1, stridx)) {\n\t\t\t/* [ ... closure template val ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copying property, stridx=%ld -> found\", (long) stridx));\n\t\t\tduk_xdef_prop_stridx_short(thr, -3, stridx, DUK_PROPDESC_FLAGS_C);\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copying property, stridx=%ld -> not found\", (long) stridx));\n\t\t\tduk_pop_unsafe(thr);\n\t\t}\n\t}\n\n\t/*\n\t *  \"length\" maps to number of formals (E5 Section 13.2) for function\n\t *  declarations/expressions (non-bound functions).  Note that 'nargs'\n\t *  is NOT necessarily equal to the number of arguments.  Use length\n\t *  of _Formals; if missing, assume nargs matches .length.\n\t */\n\n\t/* [ ... closure template ] */\n\n\tformals = duk_hobject_get_formals(thr, (duk_hobject *) fun_temp);\n\tif (formals) {\n\t\tlen_value = (duk_uint_t) formals->length;\n\t\tDUK_DD(DUK_DDPRINT(\"closure length from _Formals -> %ld\", (long) len_value));\n\t} else {\n\t\tlen_value = fun_temp->nargs;\n\t\tDUK_DD(DUK_DDPRINT(\"closure length defaulted from nargs -> %ld\", (long) len_value));\n\t}\n\n\tduk_push_uint(thr, len_value);  /* [ ... closure template len_value ] */\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);\n\n\t/*\n\t *  \"prototype\" is, by default, a fresh object with the \"constructor\"\n\t *  property.\n\t *\n\t *  Note that this creates a circular reference for every function\n\t *  instance (closure) which prevents refcount-based collection of\n\t *  function instances.\n\t *\n\t *  XXX: Try to avoid creating the default prototype object, because\n\t *  many functions are not used as constructors and the default\n\t *  prototype is unnecessary.  Perhaps it could be created on-demand\n\t *  when it is first accessed?\n\t */\n\n\t/* [ ... closure template ] */\n\n\tif (add_auto_proto) {\n\t\tduk_push_object(thr);  /* -> [ ... closure template newobj ] */\n\t\tduk_dup_m3(thr);       /* -> [ ... closure template newobj closure ] */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC);  /* -> [ ... closure template newobj ] */\n\t\tduk_compact(thr, -1);  /* compact the prototype */\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W);     /* -> [ ... closure template ] */\n\t}\n\n\t/*\n\t *  \"arguments\" and \"caller\" must be mapped to throwers for strict\n\t *  mode and bound functions (E5 Section 15.3.5).\n\t *\n\t *  XXX: This is expensive to have for every strict function instance.\n\t *  Try to implement as virtual properties or on-demand created properties.\n\t */\n\n\t/* [ ... closure template ] */\n\n\tif (DUK_HOBJECT_HAS_STRICT(&fun_clos->obj)) {\n\t\tduk_xdef_prop_stridx_thrower(thr, -2, DUK_STRIDX_CALLER);\n\t\tduk_xdef_prop_stridx_thrower(thr, -2, DUK_STRIDX_LC_ARGUMENTS);\n\t} else {\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is non-strict and non-standard 'caller' property in use, add initial 'null' value\"));\n\t\tduk_push_null(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_CALLER, DUK_PROPDESC_FLAGS_NONE);\n#else\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is non-strict and non-standard 'caller' property not used\"));\n#endif\n\t}\n\n\t/*\n\t *  \"name\" used to be non-standard but is now defined by ES2015.\n\t *  In ES2015/ES2016 the .name property is configurable.\n\t */\n\n\t/* [ ... closure template ] */\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\t/* XXX: Look for own property only; doesn't matter much because\n\t * templates are bare objects.\n\t */\n\tif (duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME)) {\n\t\t/* [ ... closure template name ] */\n\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\t\tDUK_DD(DUK_DDPRINT(\"setting function instance name to %!T\", duk_get_tval(thr, -1)));\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);  /* -> [ ... closure template ] */\n\t} else {\n\t\t/* Anonymous functions don't have a .name in ES2015, so don't set\n\t\t * it on the instance either.  The instance will then inherit\n\t\t * it from Function.prototype.name.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"not setting function instance .name\"));\n\t\tduk_pop_unsafe(thr);\n\t}\n#endif\n\n\t/*\n\t *  Compact the closure, in most cases no properties will be added later.\n\t *  Also, without this the closures end up having unused property slots\n\t *  (e.g. in Duktape 0.9.0, 8 slots would be allocated and only 7 used).\n\t *  A better future solution would be to allocate the closure directly\n\t *  to correct size (and setup the properties directly without going\n\t *  through the API).\n\t */\n\n\tduk_compact(thr, -2);\n\n\t/*\n\t *  Some assertions (E5 Section 13.2).\n\t */\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(&fun_clos->obj) == DUK_HOBJECT_CLASS_FUNCTION);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, &fun_clos->obj) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(&fun_clos->obj));\n\tDUK_ASSERT(duk_has_prop_stridx(thr, -2, DUK_STRIDX_LENGTH) != 0);\n\tDUK_ASSERT(add_auto_proto == 0 || duk_has_prop_stridx(thr, -2, DUK_STRIDX_PROTOTYPE) != 0);\n\t/* May be missing .name */\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(&fun_clos->obj) ||\n\t           duk_has_prop_stridx(thr, -2, DUK_STRIDX_CALLER) != 0);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(&fun_clos->obj) ||\n\t           duk_has_prop_stridx(thr, -2, DUK_STRIDX_LC_ARGUMENTS) != 0);\n\n\t/*\n\t *  Finish\n\t */\n\n\t/* [ ... closure template ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"created function instance: template=%!iT -> closure=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (duk_tval *) duk_get_tval(thr, -2)));\n\n\tduk_pop_unsafe(thr);\n\n\t/* [ ... closure ] */\n}\n\n/*\n *  Delayed activation environment record initialization (for functions\n *  with NEWENV).\n *\n *  The non-delayed initialization is handled by duk_handle_call().\n */\n\nDUK_LOCAL void duk__preallocate_env_entries(duk_hthread *thr, duk_hobject *varmap, duk_hobject *env) {\n\tduk_uint_fast32_t i;\n\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(varmap); i++) {\n\t\tduk_hstring *key;\n\n\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, varmap, i);\n\t\tDUK_ASSERT(key != NULL);   /* assume keys are compact in _Varmap */\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, varmap, i));  /* assume plain values */\n\n\t\t/* Predefine as 'undefined' to reserve a property slot.\n\t\t * This makes the unwind process (where register values\n\t\t * are copied to the env object) safe against throwing.\n\t\t *\n\t\t * XXX: This could be made much faster by creating the\n\t\t * property table directly.\n\t\t */\n\t\tduk_push_undefined(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"preallocate env entry for key %!O\", key));\n\t\tduk_hobject_define_property_internal(thr, env, key, DUK_PROPDESC_FLAGS_WE);\n\t}\n}\n\n/* shared helper */\nDUK_INTERNAL\nduk_hobject *duk_create_activation_environment_record(duk_hthread *thr,\n                                                      duk_hobject *func,\n                                                      duk_size_t bottom_byteoff) {\n\tduk_hdecenv *env;\n\tduk_hobject *parent;\n\tduk_hcompfunc *f;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\n\tDUK_STATS_INC(thr->heap, stats_envrec_create);\n\n\tf = (duk_hcompfunc *) func;\n\tparent = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f);\n\tif (!parent) {\n\t\tparent = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t}\n\n\tenv = duk_hdecenv_alloc(thr,\n\t                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\tDUK_ASSERT(env != NULL);\n\tduk_push_hobject(thr, (duk_hobject *) env);\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) env, parent);\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, parent);  /* parent env is the prototype */\n\n\t/* open scope information, for compiled functions only */\n\n\tDUK_ASSERT(env->thread == NULL);\n\tDUK_ASSERT(env->varmap == NULL);\n\tDUK_ASSERT(env->regbase_byteoff == 0);\n\tif (DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\tduk_hobject *varmap;\n\n\t\tvarmap = duk_hobject_get_varmap(thr, func);\n\t\tif (varmap != NULL) {\n\t\t\tenv->varmap = varmap;\n\t\t\tDUK_HOBJECT_INCREF(thr, varmap);\n\t\t\tenv->thread = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tenv->regbase_byteoff = bottom_byteoff;\n\n\t\t\t/* Preallocate env property table to avoid potential\n\t\t\t * for out-of-memory on unwind when the env is closed.\n\t\t\t */\n\t\t\tduk__preallocate_env_entries(thr, varmap, (duk_hobject *) env);\n\t\t} else {\n\t\t\t/* If function has no _Varmap, leave the environment closed. */\n\t\t\tDUK_ASSERT(env->thread == NULL);\n\t\t\tDUK_ASSERT(env->varmap == NULL);\n\t\t\tDUK_ASSERT(env->regbase_byteoff == 0);\n\t\t}\n\t}\n\n\treturn (duk_hobject *) env;\n}\n\nDUK_INTERNAL\nvoid duk_js_init_activation_environment_records_delayed(duk_hthread *thr,\n                                                        duk_activation *act) {\n\tduk_hobject *func;\n\tduk_hobject *env;\n\n\tDUK_ASSERT(thr != NULL);\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));  /* bound functions are never in act 'func' */\n\n\t/*\n\t *  Delayed initialization only occurs for 'NEWENV' functions.\n\t */\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func));\n\tDUK_ASSERT(act->lex_env == NULL);\n\tDUK_ASSERT(act->var_env == NULL);\n\n\tDUK_STATS_INC(thr->heap, stats_envrec_delayedcreate);\n\n\tenv = duk_create_activation_environment_record(thr, func, act->bottom_byteoff);\n\tDUK_ASSERT(env != NULL);\n\t/* 'act' is a stable pointer, so still OK. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"created delayed fresh env: %!ipO\", (duk_heaphdr *) env));\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t{\n\t\tduk_hobject *p = env;\n\t\twhile (p) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"  -> %!ipO\", (duk_heaphdr *) p));\n\t\t\tp = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, p);\n\t\t}\n\t}\n#endif\n\n\tact->lex_env = env;\n\tact->var_env = env;\n\tDUK_HOBJECT_INCREF(thr, env);  /* XXX: incref by count (here 2 times) */\n\tDUK_HOBJECT_INCREF(thr, env);\n\n\tduk_pop_unsafe(thr);\n}\n\n/*\n *  Closing environment records.\n *\n *  The environment record MUST be closed with the thread where its activation\n *  is; i.e. if 'env' is open, 'thr' must match env->thread, and the regbase\n *  and varmap must still be valid.  On entry, 'env' must be reachable.\n */\n\nDUK_INTERNAL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject *env) {\n\tduk_uint_fast32_t i;\n\tduk_hobject *varmap;\n\tduk_hstring *key;\n\tduk_tval *tv;\n\tduk_uint_t regnum;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL);\n\n\tif (DUK_UNLIKELY(!DUK_HOBJECT_IS_DECENV(env))) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"env not a declarative record: %!iO\", (duk_heaphdr *) env));\n\t\treturn;\n\t}\n\n\tvarmap = ((duk_hdecenv *) env)->varmap;\n\tif (varmap == NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"env already closed: %!iO\", (duk_heaphdr *) env));\n\n\t\treturn;\n\t}\n\tDUK_ASSERT(((duk_hdecenv *) env)->thread != NULL);\n\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env);\n\n\tDUK_DDD(DUK_DDDPRINT(\"closing env: %!iO\", (duk_heaphdr *) env));\n\tDUK_DDD(DUK_DDDPRINT(\"varmap: %!O\", (duk_heaphdr *) varmap));\n\n\t/* Env must be closed in the same thread as where it runs. */\n\tDUK_ASSERT(((duk_hdecenv *) env)->thread == thr);\n\n\t/* XXX: additional conditions when to close variables? we don't want to do it\n\t * unless the environment may have \"escaped\" (referenced in a function closure).\n\t * With delayed environments, the existence is probably good enough of a check.\n\t */\n\n\t/* Note: we rely on the _Varmap having a bunch of nice properties, like:\n\t *  - being compacted and unmodified during this process\n\t *  - not containing an array part\n\t *  - having correct value types\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"copying bound register values, %ld bound regs\", (long) DUK_HOBJECT_GET_ENEXT(varmap)));\n\n\t/* Copy over current variable values from value stack to the\n\t * environment record.  The scope object is empty but may\n\t * inherit from another scope which has conflicting names.\n\t */\n\n\t/* XXX: Do this using a once allocated entry area, no side effects.\n\t * Hash part would need special treatment however (maybe copy, and\n\t * then realloc with hash part if large enough).\n\t */\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(varmap); i++) {\n\t\tduk_size_t regbase_byteoff;\n\n\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, varmap, i);\n\t\tDUK_ASSERT(key != NULL);   /* assume keys are compact in _Varmap */\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, varmap, i));  /* assume plain values */\n\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, varmap, i);\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tDUK_ASSERT(DUK_TVAL_GET_NUMBER(tv) <= (duk_double_t) DUK_UINT32_MAX);  /* limits */\n#if defined(DUK_USE_FASTINT)\n\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\t\tregnum = (duk_uint_t) DUK_TVAL_GET_FASTINT_U32(tv);\n#else\n\t\tregnum = (duk_uint_t) DUK_TVAL_GET_NUMBER(tv);\n#endif\n\n\t\tregbase_byteoff = ((duk_hdecenv *) env)->regbase_byteoff;\n\t\tDUK_ASSERT((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum >= (duk_uint8_t *) thr->valstack);\n\t\tDUK_ASSERT((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum < (duk_uint8_t *) thr->valstack_top);\n\n\t\t/* Write register value into env as named properties.\n\t\t * If property already exists, overwrites silently.\n\t\t * Property is writable, but not deletable (not configurable\n\t\t * in terms of property attributes).\n\t\t *\n\t\t * This property write must not throw because we're unwinding\n\t\t * and unwind code is not allowed to throw at present.  The\n\t\t * call itself has no such guarantees, but we've preallocated\n\t\t * entries for each property when the env was created, so no\n\t\t * out-of-memory error should be possible.  If this guarantee\n\t\t * is not provided, problems like GH-476 may happen.\n\t\t */\n\t\tduk_push_tval(thr, (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum));\n\t\tDUK_DDD(DUK_DDDPRINT(\"closing identifier %!O -> reg %ld, value %!T\",\n\t\t                     (duk_heaphdr *) key,\n\t\t                     (long) regnum,\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\tduk_hobject_define_property_internal(thr, env, key, DUK_PROPDESC_FLAGS_WE);\n\t}\n\n\t/* NULL atomically to avoid inconsistent state + side effects. */\n\tDUK_HOBJECT_DECREF_NORZ(thr, ((duk_hdecenv *) env)->thread);\n\tDUK_HOBJECT_DECREF_NORZ(thr, ((duk_hdecenv *) env)->varmap);\n\t((duk_hdecenv *) env)->thread = NULL;\n\t((duk_hdecenv *) env)->varmap = NULL;\n\n\tDUK_DDD(DUK_DDDPRINT(\"env after closing: %!O\", (duk_heaphdr *) env));\n}\n\n/*\n *  GETIDREF: a GetIdentifierReference-like helper.\n *\n *  Provides a parent traversing lookup and a single level lookup\n *  (for HasBinding).\n *\n *  Instead of returning the value, returns a bunch of values allowing\n *  the caller to read, write, or delete the binding.  Value pointers\n *  are duk_tval pointers which can be mutated directly as long as\n *  refcounts are properly updated.  Note that any operation which may\n *  reallocate valstacks or compact objects may invalidate the returned\n *  duk_tval (but not object) pointers, so caller must be very careful.\n *\n *  If starting environment record 'env' is given, 'act' is ignored.\n *  However, if 'env' is NULL, the caller may identify, in 'act', an\n *  activation which hasn't had its declarative environment initialized\n *  yet.  The activation registers are then looked up, and its parent\n *  traversed normally.\n *\n *  The 'out' structure values are only valid if the function returns\n *  success (non-zero).\n */\n\n/* lookup name from an open declarative record's registers */\nDUK_LOCAL\nduk_bool_t duk__getid_open_decl_env_regs(duk_hthread *thr,\n                                         duk_hstring *name,\n                                         duk_hdecenv *env,\n                                         duk__id_lookup_result *out) {\n\tduk_tval *tv;\n\tduk_size_t reg_rel;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(out != NULL);\n\n\tDUK_ASSERT(DUK_HOBJECT_IS_DECENV((duk_hobject *) env));\n\tDUK_HDECENV_ASSERT_VALID(env);\n\n\tif (env->thread == NULL) {\n\t\t/* already closed */\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(env->varmap != NULL);\n\n\ttv = duk_hobject_find_entry_tval_ptr(thr->heap, env->varmap, name);\n\tif (DUK_UNLIKELY(tv == NULL)) {\n\t\treturn 0;\n\t}\n\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\tDUK_ASSERT(DUK_TVAL_GET_NUMBER(tv) <= (duk_double_t) DUK_UINT32_MAX);  /* limits */\n#if defined(DUK_USE_FASTINT)\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\treg_rel = (duk_size_t) DUK_TVAL_GET_FASTINT_U32(tv);\n#else\n\treg_rel = (duk_size_t) DUK_TVAL_GET_NUMBER(tv);\n#endif\n\tDUK_ASSERT_DISABLE(reg_rel >= 0);  /* unsigned */\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) env->thread->valstack + env->regbase_byteoff + sizeof(duk_tval) * reg_rel);\n\tDUK_ASSERT(tv >= env->thread->valstack && tv < env->thread->valstack_end);  /* XXX: more accurate? */\n\n\tout->value = tv;\n\tout->attrs = DUK_PROPDESC_FLAGS_W;  /* registers are mutable, non-deletable */\n\tout->env = (duk_hobject *) env;\n\tout->holder = NULL;\n\tout->has_this = 0;\n\treturn 1;\n}\n\n/* lookup name from current activation record's functions' registers */\nDUK_LOCAL\nduk_bool_t duk__getid_activation_regs(duk_hthread *thr,\n                                      duk_hstring *name,\n                                      duk_activation *act,\n                                      duk__id_lookup_result *out) {\n\tduk_tval *tv;\n\tduk_hobject *func;\n\tduk_hobject *varmap;\n\tduk_size_t reg_rel;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(out != NULL);\n\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func));\n\n\tif (!DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\treturn 0;\n\t}\n\n\t/* XXX: move varmap to duk_hcompfunc struct field? */\n\tvarmap = duk_hobject_get_varmap(thr, func);\n\tif (!varmap) {\n\t\treturn 0;\n\t}\n\n\ttv = duk_hobject_find_entry_tval_ptr(thr->heap, varmap, name);\n\tif (!tv) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\treg_rel = (duk_size_t) DUK_TVAL_GET_NUMBER(tv);\n\tDUK_ASSERT_DISABLE(reg_rel >= 0);\n\tDUK_ASSERT(reg_rel < ((duk_hcompfunc *) func)->nregs);\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff);\n\ttv += reg_rel;\n\n\tout->value = tv;\n\tout->attrs = DUK_PROPDESC_FLAGS_W;  /* registers are mutable, non-deletable */\n\tout->env = NULL;\n\tout->holder = NULL;\n\tout->has_this = 0;\n\treturn 1;\n}\n\nDUK_LOCAL\nduk_bool_t duk__get_identifier_reference(duk_hthread *thr,\n                                         duk_hobject *env,\n                                         duk_hstring *name,\n                                         duk_activation *act,\n                                         duk_bool_t parents,\n                                         duk__id_lookup_result *out) {\n\tduk_tval *tv;\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL || act != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(out != NULL);\n\n\tDUK_ASSERT(!env || DUK_HOBJECT_IS_ENV(env));\n\tDUK_ASSERT(!env || !DUK_HOBJECT_HAS_ARRAY_PART(env));\n\n\t/*\n\t *  Conceptually, we look for the identifier binding by starting from\n\t *  'env' and following to chain of environment records (represented\n\t *  by the prototype chain).\n\t *\n\t *  If 'env' is NULL, the current activation does not yet have an\n\t *  allocated declarative environment record; this should be treated\n\t *  exactly as if the environment record existed but had no bindings\n\t *  other than register bindings.\n\t *\n\t *  Note: we assume that with the DUK_HOBJECT_FLAG_NEWENV cleared\n\t *  the environment will always be initialized immediately; hence\n\t *  a NULL 'env' should only happen with the flag set.  This is the\n\t *  case for: (1) function calls, and (2) strict, direct eval calls.\n\t */\n\n\tif (env == NULL && act != NULL) {\n\t\tduk_hobject *func;\n\t\tduk_hcompfunc *f;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference: env is NULL, activation is non-NULL -> \"\n\t\t                     \"delayed env case, look up activation regs first\"));\n\n\t\t/*\n\t\t *  Try registers\n\t\t */\n\n\t\tif (duk__getid_activation_regs(thr, name, act, out)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t                     \"(found from register bindings when env=NULL)\",\n\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\treturn 1;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"not found in current activation regs\"));\n\n\t\t/*\n\t\t *  Not found in registers, proceed to the parent record.\n\t\t *  Here we need to determine what the parent would be,\n\t\t *  if 'env' was not NULL (i.e. same logic as when initializing\n\t\t *  the record).\n\t\t *\n\t\t *  Note that environment initialization is only deferred when\n\t\t *  DUK_HOBJECT_HAS_NEWENV is set, and this only happens for:\n\t\t *    - Function code\n\t\t *    - Strict eval code\n\t\t *\n\t\t *  We only need to check _Lexenv here; _Varenv exists only if it\n\t\t *  differs from _Lexenv (and thus _Lexenv will also be present).\n\t\t */\n\n\t\tif (!parents) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference failed, no parent traversal \"\n\t\t\t                     \"(not found from register bindings when env=NULL)\"));\n\t\t\tgoto fail_not_found;\n\t\t}\n\n\t\tfunc = DUK_ACT_GET_FUNC(act);\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func));\n\t\tf = (duk_hcompfunc *) func;\n\n\t\tenv = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f);\n\t\tif (!env) {\n\t\t\tenv = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"continue lookup from env: %!iO\",\n\t\t                     (duk_heaphdr *) env));\n\t}\n\n\t/*\n\t *  Prototype walking starting from 'env'.\n\t *\n\t *  ('act' is not needed anywhere here.)\n\t */\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\twhile (env != NULL) {\n\t\tduk_small_uint_t cl;\n\t\tduk_uint_t attrs;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference, name=%!O, considering env=%p -> %!iO\",\n\t\t                     (duk_heaphdr *) name,\n\t\t                     (void *) env,\n\t\t                     (duk_heaphdr *) env));\n\n\t\tDUK_ASSERT(env != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_ENV(env));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(env));\n\n\t\tcl = DUK_HOBJECT_GET_CLASS_NUMBER(env);\n\t\tDUK_ASSERT(cl == DUK_HOBJECT_CLASS_OBJENV || cl == DUK_HOBJECT_CLASS_DECENV);\n\t\tif (cl == DUK_HOBJECT_CLASS_DECENV) {\n\t\t\t/*\n\t\t\t *  Declarative environment record.\n\t\t\t *\n\t\t\t *  Identifiers can never be stored in ancestors and are\n\t\t\t *  always plain values, so we can use an internal helper\n\t\t\t *  and access the value directly with an duk_tval ptr.\n\t\t\t *\n\t\t\t *  A closed environment is only indicated by it missing\n\t\t\t *  the \"book-keeping\" properties required for accessing\n\t\t\t *  register-bound variables.\n\t\t\t */\n\n\t\t\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env);\n\t\t\tif (duk__getid_open_decl_env_regs(thr, name, (duk_hdecenv *) env, out)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t\t                     \"(declarative environment record, scope open, found in regs)\",\n\t\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\ttv = duk_hobject_find_entry_tval_ptr_and_attrs(thr->heap, env, name, &attrs);\n\t\t\tif (tv) {\n\t\t\t\tout->value = tv;\n\t\t\t\tout->attrs = attrs;\n\t\t\t\tout->env = env;\n\t\t\t\tout->holder = env;\n\t\t\t\tout->has_this = 0;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t\t                     \"(declarative environment record, found in properties)\",\n\t\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Object environment record.\n\t\t\t *\n\t\t\t *  Binding (target) object is an external, uncontrolled object.\n\t\t\t *  Identifier may be bound in an ancestor property, and may be\n\t\t\t *  an accessor.  Target can also be a Proxy which we must support\n\t\t\t *  here.\n\t\t\t */\n\n\t\t\t/* XXX: we could save space by using _Target OR _This.  If _Target, assume\n\t\t\t * this binding is undefined.  If _This, assumes this binding is _This, and\n\t\t\t * target is also _This.  One property would then be enough.\n\t\t\t */\n\n\t\t\tduk_hobject *target;\n\t\t\tduk_bool_t found;\n\n\t\t\tDUK_ASSERT(cl == DUK_HOBJECT_CLASS_OBJENV);\n\t\t\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) env);\n\n\t\t\ttarget = ((duk_hobjenv *) env)->target;\n\t\t\tDUK_ASSERT(target != NULL);\n\n\t\t\t/* Target may be a Proxy or property may be an accessor, so we must\n\t\t\t * use an actual, Proxy-aware hasprop check here.\n\t\t\t *\n\t\t\t * out->holder is NOT set to the actual duk_hobject where the\n\t\t\t * property is found, but rather the object binding target object.\n\t\t\t */\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(target))) {\n\t\t\t\tduk_tval tv_name;\n\t\t\t\tduk_tval tv_target_tmp;\n\n\t\t\t\tDUK_ASSERT(name != NULL);\n\t\t\t\tDUK_TVAL_SET_STRING(&tv_name, name);\n\t\t\t\tDUK_TVAL_SET_OBJECT(&tv_target_tmp, target);\n\n\t\t\t\tfound = duk_hobject_hasprop(thr, &tv_target_tmp, &tv_name);\n\t\t\t} else\n#endif  /* DUK_USE_ES6_PROXY */\n\t\t\t{\n\t\t\t\t/* XXX: duk_hobject_hasprop() would be correct for\n\t\t\t\t * non-Proxy objects too, but it is about ~20-25%\n\t\t\t\t * slower at present so separate code paths for\n\t\t\t\t * Proxy and non-Proxy now.\n\t\t\t\t */\n\t\t\t\tfound = duk_hobject_hasprop_raw(thr, target, name);\n\t\t\t}\n\n\t\t\tif (found) {\n\t\t\t\tout->value = NULL;  /* can't get value, may be accessor */\n\t\t\t\tout->attrs = 0;     /* irrelevant when out->value == NULL */\n\t\t\t\tout->env = env;\n\t\t\t\tout->holder = target;\n\t\t\t\tout->has_this = ((duk_hobjenv *) env)->has_this;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t\t                     \"(object environment record)\",\n\t\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\tif (!parents) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference failed, no parent traversal \"\n\t\t\t                     \"(not found from first traversed env)\"));\n\t\t\tgoto fail_not_found;\n\t\t}\n\n                if (DUK_UNLIKELY(sanity-- == 0)) {\n                        DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n                }\n\t\tenv = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, env);\n\t}\n\n\t/*\n\t *  Not found (even in global object)\n\t */\n\n fail_not_found:\n\treturn 0;\n}\n\n/*\n *  HASVAR: check identifier binding from a given environment record\n *  without traversing its parents.\n *\n *  This primitive is not exposed to user code as such, but is used\n *  internally for e.g. declaration binding instantiation.\n *\n *  See E5 Sections:\n *    10.2.1.1.1 HasBinding(N)\n *    10.2.1.2.1 HasBinding(N)\n *\n *  Note: strictness has no bearing on this check.  Hence we don't take\n *  a 'strict' parameter.\n */\n\n#if 0  /*unused*/\nDUK_INTERNAL\nduk_bool_t duk_js_hasvar_envrec(duk_hthread *thr,\n                                duk_hobject *env,\n                                duk_hstring *name) {\n\tduk__id_lookup_result ref;\n\tduk_bool_t parents;\n\n\tDUK_DDD(DUK_DDDPRINT(\"hasvar: thr=%p, env=%p, name=%!O \"\n\t                     \"(env -> %!dO)\",\n\t                     (void *) thr, (void *) env, (duk_heaphdr *) name,\n\t                     (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(name != NULL);\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\n\tDUK_ASSERT(DUK_HOBJECT_IS_ENV(env));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(env));\n\n\t/* lookup results is ignored */\n\tparents = 0;\n\treturn duk__get_identifier_reference(thr, env, name, NULL, parents, &ref);\n}\n#endif\n\n/*\n *  GETVAR\n *\n *  See E5 Sections:\n *    11.1.2 Identifier Reference\n *    10.3.1 Identifier Resolution\n *    11.13.1 Simple Assignment  [example of where the Reference is GetValue'd]\n *    8.7.1 GetValue (V)\n *    8.12.1 [[GetOwnProperty]] (P)\n *    8.12.2 [[GetProperty]] (P)\n *    8.12.3 [[Get]] (P)\n *\n *  If 'throw' is true, always leaves two values on top of stack: [val this].\n *\n *  If 'throw' is false, returns 0 if identifier cannot be resolved, and the\n *  stack will be unaffected in this case.  If identifier is resolved, returns\n *  1 and leaves [val this] on top of stack.\n *\n *  Note: the 'strict' flag of a reference returned by GetIdentifierReference\n *  is ignored by GetValue.  Hence we don't take a 'strict' parameter.\n *\n *  The 'throw' flag is needed for implementing 'typeof' for an unreferenced\n *  identifier.  An unreference identifier in other contexts generates a\n *  ReferenceError.\n */\n\nDUK_LOCAL\nduk_bool_t duk__getvar_helper(duk_hthread *thr,\n                              duk_hobject *env,\n                              duk_activation *act,\n                              duk_hstring *name,\n                              duk_bool_t throw_flag) {\n\tduk__id_lookup_result ref;\n\tduk_tval tv_tmp_obj;\n\tduk_tval tv_tmp_key;\n\tduk_bool_t parents;\n\n\tDUK_DDD(DUK_DDDPRINT(\"getvar: thr=%p, env=%p, act=%p, name=%!O \"\n\t                     \"(env -> %!dO)\",\n\t                     (void *) thr, (void *) env, (void *) act,\n\t                     (duk_heaphdr *) name, (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\t/* env and act may be NULL */\n\n\tDUK_STATS_INC(thr->heap, stats_getvar_all);\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\n\tparents = 1;     /* follow parent chain */\n\tif (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) {\n\t\tif (ref.value) {\n\t\t\tduk_push_tval(thr, ref.value);\n\t\t\tduk_push_undefined(thr);\n\t\t} else {\n\t\t\tDUK_ASSERT(ref.holder != NULL);\n\n\t\t\t/* ref.holder is safe across the getprop call (even\n\t\t\t * with side effects) because 'env' is reachable and\n\t\t\t * ref.holder is a direct heap pointer.\n\t\t\t */\n\n\t\t\tDUK_TVAL_SET_OBJECT(&tv_tmp_obj, ref.holder);\n\t\t\tDUK_TVAL_SET_STRING(&tv_tmp_key, name);\n\t\t\t(void) duk_hobject_getprop(thr, &tv_tmp_obj, &tv_tmp_key);  /* [value] */\n\n\t\t\tif (ref.has_this) {\n\t\t\t\tduk_push_hobject(thr, ref.holder);\n\t\t\t} else {\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t}\n\n\t\t\t/* [value this] */\n\t\t}\n\n\t\treturn 1;\n\t} else {\n\t\tif (throw_flag) {\n\t\t\tDUK_ERROR_FMT1(thr, DUK_ERR_REFERENCE_ERROR,\n\t\t\t               \"identifier '%s' undefined\",\n\t\t\t               (const char *) DUK_HSTRING_GET_DATA(name));\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\n\t\treturn 0;\n\t}\n}\n\nDUK_INTERNAL\nduk_bool_t duk_js_getvar_envrec(duk_hthread *thr,\n                                duk_hobject *env,\n                                duk_hstring *name,\n                                duk_bool_t throw_flag) {\n\treturn duk__getvar_helper(thr, env, NULL, name, throw_flag);\n}\n\nDUK_INTERNAL\nduk_bool_t duk_js_getvar_activation(duk_hthread *thr,\n                                    duk_activation *act,\n                                    duk_hstring *name,\n                                    duk_bool_t throw_flag) {\n\tDUK_ASSERT(act != NULL);\n\treturn duk__getvar_helper(thr, act->lex_env, act, name, throw_flag);\n}\n\n/*\n *  PUTVAR\n *\n *  See E5 Sections:\n *    11.1.2 Identifier Reference\n *    10.3.1 Identifier Resolution\n *    11.13.1 Simple Assignment  [example of where the Reference is PutValue'd]\n *    8.7.2 PutValue (V,W)  [see especially step 3.b, undefined -> automatic global in non-strict mode]\n *    8.12.4 [[CanPut]] (P)\n *    8.12.5 [[Put]] (P)\n *\n *  Note: may invalidate any valstack (or object) duk_tval pointers because\n *  putting a value may reallocate any object or any valstack.  Caller beware.\n */\n\nDUK_LOCAL\nvoid duk__putvar_helper(duk_hthread *thr,\n                        duk_hobject *env,\n                        duk_activation *act,\n                        duk_hstring *name,\n                        duk_tval *val,\n                        duk_bool_t strict) {\n\tduk__id_lookup_result ref;\n\tduk_tval tv_tmp_obj;\n\tduk_tval tv_tmp_key;\n\tduk_bool_t parents;\n\n\tDUK_STATS_INC(thr->heap, stats_putvar_all);\n\n\tDUK_DDD(DUK_DDDPRINT(\"putvar: thr=%p, env=%p, act=%p, name=%!O, val=%p, strict=%ld \"\n\t                     \"(env -> %!dO, val -> %!T)\",\n\t                     (void *) thr, (void *) env, (void *) act,\n\t                     (duk_heaphdr *) name, (void *) val, (long) strict,\n\t                     (duk_heaphdr *) env, (duk_tval *) val));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(val != NULL);\n\t/* env and act may be NULL */\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\tDUK_ASSERT_REFCOUNT_NONZERO_TVAL(val);\n\n\t/*\n\t *  In strict mode E5 protects 'eval' and 'arguments' from being\n\t *  assigned to (or even declared anywhere).  Attempt to do so\n\t *  should result in a compile time SyntaxError.  See the internal\n\t *  design documentation for details.\n\t *\n\t *  Thus, we should never come here, run-time, for strict code,\n\t *  and name 'eval' or 'arguments'.\n\t */\n\n\tDUK_ASSERT(!strict ||\n\t           (name != DUK_HTHREAD_STRING_EVAL(thr) &&\n\t            name != DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)));\n\n\t/*\n\t *  Lookup variable and update in-place if found.\n\t */\n\n\tparents = 1;     /* follow parent chain */\n\n\tif (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) {\n\t\tif (ref.value && (ref.attrs & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t/* Update duk_tval in-place if pointer provided and the\n\t\t\t * property is writable.  If the property is not writable\n\t\t\t * (immutable binding), use duk_hobject_putprop() which\n\t\t\t * will respect mutability.\n\t\t\t */\n\t\t\tduk_tval *tv_val;\n\n\t\t\ttv_val = ref.value;\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv_val, val);  /* side effects */\n\n\t\t\t/* ref.value invalidated here */\n\t\t} else {\n\t\t\tDUK_ASSERT(ref.holder != NULL);\n\n\t\t\tDUK_TVAL_SET_OBJECT(&tv_tmp_obj, ref.holder);\n\t\t\tDUK_TVAL_SET_STRING(&tv_tmp_key, name);\n\t\t\t(void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, strict);\n\n\t\t\t/* ref.value invalidated here */\n\t\t}\n\n\t\treturn;\n\t}\n\n\t/*\n\t *  Not found: write to global object (non-strict) or ReferenceError\n\t *  (strict); see E5 Section 8.7.2, step 3.\n\t */\n\n\tif (strict) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"identifier binding not found, strict => reference error\"));\n\t\tDUK_ERROR_FMT1(thr, DUK_ERR_REFERENCE_ERROR,\n\t\t               \"identifier '%s' undefined\",\n\t\t               (const char *) DUK_HSTRING_GET_DATA(name));\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"identifier binding not found, not strict => set to global\"));\n\n\tDUK_TVAL_SET_OBJECT(&tv_tmp_obj, thr->builtins[DUK_BIDX_GLOBAL]);\n\tDUK_TVAL_SET_STRING(&tv_tmp_key, name);\n\t(void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, 0);  /* 0 = no throw */\n\n\t/* NB: 'val' may be invalidated here because put_value may realloc valstack,\n\t * caller beware.\n\t */\n}\n\nDUK_INTERNAL\nvoid duk_js_putvar_envrec(duk_hthread *thr,\n                          duk_hobject *env,\n                          duk_hstring *name,\n                          duk_tval *val,\n                          duk_bool_t strict) {\n\tduk__putvar_helper(thr, env, NULL, name, val, strict);\n}\n\nDUK_INTERNAL\nvoid duk_js_putvar_activation(duk_hthread *thr,\n                              duk_activation *act,\n                              duk_hstring *name,\n                              duk_tval *val,\n                              duk_bool_t strict) {\n\tDUK_ASSERT(act != NULL);\n\tduk__putvar_helper(thr, act->lex_env, act, name, val, strict);\n}\n\n/*\n *  DELVAR\n *\n *  See E5 Sections:\n *    11.4.1 The delete operator\n *    10.2.1.1.5 DeleteBinding (N)  [declarative environment record]\n *    10.2.1.2.5 DeleteBinding (N)  [object environment record]\n *\n *  Variable bindings established inside eval() are deletable (configurable),\n *  other bindings are not, including variables declared in global level.\n *  Registers are always non-deletable, and the deletion of other bindings\n *  is controlled by the configurable flag.\n *\n *  For strict mode code, the 'delete' operator should fail with a compile\n *  time SyntaxError if applied to identifiers.  Hence, no strict mode\n *  run-time deletion of identifiers should ever happen.  This function\n *  should never be called from strict mode code!\n */\n\nDUK_LOCAL\nduk_bool_t duk__delvar_helper(duk_hthread *thr,\n                              duk_hobject *env,\n                              duk_activation *act,\n                              duk_hstring *name) {\n\tduk__id_lookup_result ref;\n\tduk_bool_t parents;\n\n\tDUK_DDD(DUK_DDDPRINT(\"delvar: thr=%p, env=%p, act=%p, name=%!O \"\n\t                     \"(env -> %!dO)\",\n\t                     (void *) thr, (void *) env, (void *) act,\n\t                     (duk_heaphdr *) name, (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\t/* env and act may be NULL */\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\n\tparents = 1;     /* follow parent chain */\n\n\tif (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) {\n\t\tif (ref.value && !(ref.attrs & DUK_PROPDESC_FLAG_CONFIGURABLE)) {\n\t\t\t/* Identifier found in registers (always non-deletable)\n\t\t\t * or declarative environment record and non-configurable.\n\t\t\t */\n\t\t\treturn 0;\n\t\t}\n\t\tDUK_ASSERT(ref.holder != NULL);\n\n\t\treturn duk_hobject_delprop_raw(thr, ref.holder, name, 0);\n\t}\n\n\t/*\n\t *  Not found (even in global object).\n\t *\n\t *  In non-strict mode this is a silent SUCCESS (!), see E5 Section 11.4.1,\n\t *  step 3.b.  In strict mode this case is a compile time SyntaxError so\n\t *  we should not come here.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"identifier to be deleted not found: name=%!O \"\n\t                     \"(treated as silent success)\",\n\t                     (duk_heaphdr *) name));\n\treturn 1;\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL\nduk_bool_t duk_js_delvar_envrec(duk_hthread *thr,\n                                duk_hobject *env,\n                                duk_hstring *name) {\n\treturn duk__delvar_helper(thr, env, NULL, name);\n}\n#endif\n\nDUK_INTERNAL\nduk_bool_t duk_js_delvar_activation(duk_hthread *thr,\n                                    duk_activation *act,\n                                    duk_hstring *name) {\n\tDUK_ASSERT(act != NULL);\n\treturn duk__delvar_helper(thr, act->lex_env, act, name);\n}\n\n/*\n *  DECLVAR\n *\n *  See E5 Sections:\n *    10.4.3 Entering Function Code\n *    10.5 Declaration Binding Instantion\n *    12.2 Variable Statement\n *    11.1.2 Identifier Reference\n *    10.3.1 Identifier Resolution\n *\n *  Variable declaration behavior is mainly discussed in Section 10.5,\n *  and is not discussed in the execution semantics (Sections 11-13).\n *\n *  Conceptually declarations happen when code (global, eval, function)\n *  is entered, before any user code is executed.  In practice, register-\n *  bound identifiers are 'declared' automatically (by virtue of being\n *  allocated to registers with the initial value 'undefined').  Other\n *  identifiers are declared in the function prologue with this primitive.\n *\n *  Since non-register bindings eventually back to an internal object's\n *  properties, the 'prop_flags' argument is used to specify binding\n *  type:\n *\n *    - Immutable binding: set DUK_PROPDESC_FLAG_WRITABLE to false\n *    - Non-deletable binding: set DUK_PROPDESC_FLAG_CONFIGURABLE to false\n *    - The flag DUK_PROPDESC_FLAG_ENUMERABLE should be set, although it\n *      doesn't really matter for internal objects\n *\n *  All bindings are non-deletable mutable bindings except:\n *\n *    - Declarations in eval code (mutable, deletable)\n *    - 'arguments' binding in strict function code (immutable)\n *    - Function name binding of a function expression (immutable)\n *\n *  Declarations may go to declarative environment records (always\n *  so for functions), but may also go to object environment records\n *  (e.g. global code).  The global object environment has special\n *  behavior when re-declaring a function (but not a variable); see\n *  E5.1 specification, Section 10.5, step 5.e.\n *\n *  Declarations always go to the 'top-most' environment record, i.e.\n *  we never check the record chain.  It's not an error even if a\n *  property (even an immutable or non-deletable one) of the same name\n *  already exists.\n *\n *  If a declared variable already exists, its value needs to be updated\n *  (if possible).  Returns 1 if a PUTVAR needs to be done by the caller;\n *  otherwise returns 0.\n */\n\nDUK_LOCAL\nduk_bool_t duk__declvar_helper(duk_hthread *thr,\n                               duk_hobject *env,\n                               duk_hstring *name,\n                               duk_tval *val,\n                               duk_small_uint_t prop_flags,\n                               duk_bool_t is_func_decl) {\n\tduk_hobject *holder;\n\tduk_bool_t parents;\n\tduk__id_lookup_result ref;\n\tduk_tval *tv;\n\n\tDUK_DDD(DUK_DDDPRINT(\"declvar: thr=%p, env=%p, name=%!O, val=%!T, prop_flags=0x%08lx, is_func_decl=%ld \"\n\t                     \"(env -> %!iO)\",\n\t                     (void *) thr, (void *) env, (duk_heaphdr *) name,\n\t                     (duk_tval *) val, (unsigned long) prop_flags,\n\t                     (unsigned int) is_func_decl, (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(val != NULL);\n\n\t/* Note: in strict mode the compiler should reject explicit\n\t * declaration of 'eval' or 'arguments'.  However, internal\n\t * bytecode may declare 'arguments' in the function prologue.\n\t * We don't bother checking (or asserting) for these now.\n\t */\n\n\t/* Note: val is a stable duk_tval pointer.  The caller makes\n\t * a value copy into its stack frame, so 'tv_val' is not subject\n\t * to side effects here.\n\t */\n\n\t/*\n\t *  Check whether already declared.\n\t *\n\t *  We need to check whether the binding exists in the environment\n\t *  without walking its parents.  However, we still need to check\n\t *  register-bound identifiers and the prototype chain of an object\n\t *  environment target object.\n\t */\n\n\tparents = 0;  /* just check 'env' */\n\tif (duk__get_identifier_reference(thr, env, name, NULL, parents, &ref)) {\n\t\tduk_int_t e_idx;\n\t\tduk_int_t h_idx;\n\t\tduk_small_uint_t flags;\n\n\t\t/*\n\t\t *  Variable already declared, ignore re-declaration.\n\t\t *  The only exception is the updated behavior of E5.1 for\n\t\t *  global function declarations, E5.1 Section 10.5, step 5.e.\n\t\t *  This behavior does not apply to global variable declarations.\n\t\t */\n\n\t\tif (!(is_func_decl && env == thr->builtins[DUK_BIDX_GLOBAL_ENV])) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"re-declare a binding, ignoring\"));\n\t\t\treturn 1;  /* 1 -> needs a PUTVAR */\n\t\t}\n\n\t\t/*\n\t\t *  Special behavior in E5.1.\n\t\t *\n\t\t *  Note that even though parents == 0, the conflicting property\n\t\t *  may be an inherited property (currently our global object's\n\t\t *  prototype is Object.prototype).  Step 5.e first operates on\n\t\t *  the existing property (which is potentially in an ancestor)\n\t\t *  and then defines a new property in the global object (and\n\t\t *  never modifies the ancestor).\n\t\t *\n\t\t *  Also note that this logic would become even more complicated\n\t\t *  if the conflicting property might be a virtual one.  Object\n\t\t *  prototype has no virtual properties, though.\n\t\t *\n\t\t *  XXX: this is now very awkward, rework.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"re-declare a function binding in global object, \"\n\t\t                     \"updated E5.1 processing\"));\n\n\t\tDUK_ASSERT(ref.holder != NULL);\n\t\tholder = ref.holder;\n\n\t\t/* holder will be set to the target object, not the actual object\n\t\t * where the property was found (see duk__get_identifier_reference()).\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(holder) == DUK_HOBJECT_CLASS_GLOBAL);\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(holder));  /* global object doesn't have array part */\n\n\t\t/* XXX: use a helper for prototype traversal; no loop check here */\n\t\t/* must be found: was found earlier, and cannot be inherited */\n\t\tfor (;;) {\n\t\t\tDUK_ASSERT(holder != NULL);\n\t\t\tif (duk_hobject_find_entry(thr->heap, holder, name, &e_idx, &h_idx)) {\n\t\t\t\tDUK_ASSERT(e_idx >= 0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t/* SCANBUILD: NULL pointer dereference, doesn't actually trigger,\n\t\t\t * asserted above.\n\t\t\t */\n\t\t\tholder = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, holder);\n\t\t}\n\t\tDUK_ASSERT(holder != NULL);\n\t\tDUK_ASSERT(e_idx >= 0);\n\t\t/* SCANBUILD: scan-build produces a NULL pointer dereference warning\n\t\t * below; it never actually triggers because holder is actually never\n\t\t * NULL.\n\t\t */\n\n\t\t/* ref.holder is global object, holder is the object with the\n\t\t * conflicting property.\n\t\t */\n\n\t\tflags = DUK_HOBJECT_E_GET_FLAGS(thr->heap, holder, e_idx);\n\t\tif (!(flags & DUK_PROPDESC_FLAG_CONFIGURABLE)) {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"existing property is a non-configurable \"\n\t\t\t\t                     \"accessor -> reject\"));\n\t\t\t\tgoto fail_existing_attributes;\n\t\t\t}\n\t\t\tif (!((flags & DUK_PROPDESC_FLAG_WRITABLE) &&\n\t\t\t      (flags & DUK_PROPDESC_FLAG_ENUMERABLE))) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"existing property is a non-configurable \"\n\t\t\t\t                     \"plain property which is not writable and \"\n\t\t\t\t                     \"enumerable -> reject\"));\n\t\t\t\tgoto fail_existing_attributes;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"existing property is not configurable but \"\n\t\t\t                     \"is plain, enumerable, and writable -> \"\n\t\t\t                     \"allow redeclaration\"));\n\t\t}\n\n\t\tif (holder == ref.holder) {\n\t\t\t/* XXX: if duk_hobject_define_property_internal() was updated\n\t\t\t * to handle a pre-existing accessor property, this would be\n\t\t\t * a simple call (like for the ancestor case).\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"redefine, offending property in global object itself\"));\n\n\t\t\tif (flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t\tduk_hobject *tmp;\n\n\t\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, holder, e_idx);\n\t\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, holder, e_idx, NULL);\n\t\t\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);\n\t\t\t\tDUK_UNREF(tmp);\n\t\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, holder, e_idx);\n\t\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, holder, e_idx, NULL);\n\t\t\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);\n\t\t\t\tDUK_UNREF(tmp);\n\t\t\t} else {\n\t\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx);\n\t\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);\n\t\t\t}\n\n\t\t\t/* Here val would be potentially invalid if we didn't make\n\t\t\t * a value copy at the caller.\n\t\t\t */\n\n\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx);\n\t\t\tDUK_TVAL_SET_TVAL(tv, val);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, holder, e_idx, prop_flags);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"updated global binding, final result: \"\n\t\t\t                     \"value -> %!T, prop_flags=0x%08lx\",\n\t\t\t                     (duk_tval *) DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx),\n\t\t\t                     (unsigned long) prop_flags));\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"redefine, offending property in ancestor\"));\n\n\t\t\tDUK_ASSERT(ref.holder == thr->builtins[DUK_BIDX_GLOBAL]);\n\t\t\tduk_push_tval(thr, val);\n\t\t\tduk_hobject_define_property_internal(thr, ref.holder, name, prop_flags);\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  Not found (in registers or record objects).  Declare\n\t *  to current variable environment.\n\t */\n\n\t/*\n\t *  Get holder object\n\t */\n\n\tif (DUK_HOBJECT_IS_DECENV(env)) {\n\t\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env);\n\t\tholder = env;\n\t} else {\n\t\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) env);\n\t\tholder = ((duk_hobjenv *) env)->target;\n\t\tDUK_ASSERT(holder != NULL);\n\t}\n\n\t/*\n\t *  Define new property\n\t *\n\t *  Note: this may fail if the holder is not extensible.\n\t */\n\n\t/* XXX: this is awkward as we use an internal method which doesn't handle\n\t * extensibility etc correctly.  Basically we'd want to do a [[DefineOwnProperty]]\n\t * or Object.defineProperty() here.\n\t */\n\n\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(holder)) {\n\t\tgoto fail_not_extensible;\n\t}\n\n\tduk_push_hobject(thr, holder);\n\tduk_push_hstring(thr, name);\n\tduk_push_tval(thr, val);\n\tduk_xdef_prop(thr, -3, prop_flags);  /* [holder name val] -> [holder] */\n\tduk_pop_unsafe(thr);\n\n\treturn 0;\n\n fail_existing_attributes:\n fail_not_extensible:\n\tDUK_ERROR_TYPE(thr, \"declaration failed\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL\nduk_bool_t duk_js_declvar_activation(duk_hthread *thr,\n                                     duk_activation *act,\n                                     duk_hstring *name,\n                                     duk_tval *val,\n                                     duk_small_uint_t prop_flags,\n                                     duk_bool_t is_func_decl) {\n\tduk_hobject *env;\n\tduk_tval tv_val_copy;\n\n\tDUK_ASSERT(act != NULL);\n\n\t/*\n\t *  Make a value copy of the input val.  This ensures that\n\t *  side effects cannot invalidate the pointer.\n\t */\n\n\tDUK_TVAL_SET_TVAL(&tv_val_copy, val);\n\tval = &tv_val_copy;\n\n\t/*\n\t *  Delayed env creation check\n\t */\n\n\tif (!act->var_env) {\n\t\tDUK_ASSERT(act->lex_env == NULL);\n\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\t/* 'act' is a stable pointer, so still OK. */\n\t}\n\tDUK_ASSERT(act->lex_env != NULL);\n\tDUK_ASSERT(act->var_env != NULL);\n\n\tenv = act->var_env;\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_ENV(env));\n\n\treturn duk__declvar_helper(thr, env, name, val, prop_flags, is_func_decl);\n}\n#line 1 \"duk_lexer.c\"\n/*\n *  Lexer for source files, ToNumber() string conversions, RegExp expressions,\n *  and JSON.\n *\n *  Provides a stream of ECMAScript tokens from an UTF-8/CESU-8 buffer.  The\n *  caller can also rewind the token stream into a certain position which is\n *  needed by the compiler part for multi-pass scanning.  Tokens are\n *  represented as duk_token structures, and contain line number information.\n *  Token types are identified with DUK_TOK_* defines.\n *\n *  Characters are decoded into a fixed size lookup window consisting of\n *  decoded Unicode code points, with window positions past the end of the\n *  input filled with an invalid codepoint (-1).  The tokenizer can thus\n *  perform multiple character lookups efficiently and with few sanity\n *  checks (such as access outside the end of the input), which keeps the\n *  tokenization code small at the cost of performance.\n *\n *  Character data in tokens, such as identifier names and string literals,\n *  is encoded into CESU-8 format on-the-fly while parsing the token in\n *  question.  The string data is made reachable to garbage collection by\n *  placing the token-related values in value stack entries allocated for\n *  this purpose by the caller.  The characters exist in Unicode code point\n *  form only in the fixed size lookup window, which keeps character data\n *  expansion (of especially ASCII data) low.\n *\n *  Token parsing supports the full range of Unicode characters as described\n *  in the E5 specification.  Parsing has been optimized for ASCII characters\n *  because ordinary ECMAScript code consists almost entirely of ASCII\n *  characters.  Matching of complex Unicode codepoint sets (such as in the\n *  IdentifierStart and IdentifierPart productions) is optimized for size,\n *  and is done using a linear scan of a bit-packed list of ranges.  This is\n *  very slow, but should never be entered unless the source code actually\n *  contains Unicode characters.\n *\n *  ECMAScript tokenization is partially context sensitive.  First,\n *  additional future reserved words are recognized in strict mode (see E5\n *  Section 7.6.1.2).  Second, a forward slash character ('/') can be\n *  recognized either as starting a RegExp literal or as a division operator,\n *  depending on context.  The caller must provide necessary context flags\n *  when requesting a new token.\n *\n *  Future work:\n *\n *    * Make line number tracking optional, as it consumes space.\n *\n *    * Add a feature flag for disabling UTF-8 decoding of input, as most\n *      source code is ASCII.  Because of Unicode escapes written in ASCII,\n *      this does not allow Unicode support to be removed from e.g.\n *      duk_unicode_is_identifier_start() nor does it allow removal of CESU-8\n *      encoding of e.g. string literals.\n *\n *    * Add a feature flag for disabling Unicode compliance of e.g. identifier\n *      names.  This allows for a build more than a kilobyte smaller, because\n *      Unicode ranges needed by duk_unicode_is_identifier_start() and\n *      duk_unicode_is_identifier_part() can be dropped.  String literals\n *      should still be allowed to contain escaped Unicode, so this still does\n *      not allow removal of CESU-8 encoding of e.g. string literals.\n *\n *    * Character lookup tables for codepoints above BMP could be stripped.\n *\n *    * Strictly speaking, E5 specification requires that source code consists\n *      of 16-bit code units, and if not, must be conceptually converted to\n *      that format first.  The current lexer processes Unicode code points\n *      and allows characters outside the BMP.  These should be converted to\n *      surrogate pairs while reading the source characters into the window,\n *      not after tokens have been formed (as is done now).  However, the fix\n *      is not trivial because two characters are decoded from one codepoint.\n *\n *    * Optimize for speed as well as size.  Large if-else ladders are (at\n *      least potentially) slow.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Various defines and file specific helper macros\n */\n\n#define DUK__MAX_RE_DECESC_DIGITS     9\n#define DUK__MAX_RE_QUANT_DIGITS      9   /* Does not allow e.g. 2**31-1, but one more would allow overflows of u32. */\n\n/* whether to use macros or helper function depends on call count */\n#define DUK__ISDIGIT(x)          ((x) >= DUK_ASC_0 && (x) <= DUK_ASC_9)\n#define DUK__ISHEXDIGIT(x)       duk__is_hex_digit((x))\n#define DUK__ISOCTDIGIT(x)       ((x) >= DUK_ASC_0 && (x) <= DUK_ASC_7)\n#define DUK__ISDIGIT03(x)        ((x) >= DUK_ASC_0 && (x) <= DUK_ASC_3)\n#define DUK__ISDIGIT47(x)        ((x) >= DUK_ASC_4 && (x) <= DUK_ASC_7)\n\n/* lexer character window helpers */\n#define DUK__LOOKUP(lex_ctx,idx)            ((lex_ctx)->window[(idx)].codepoint)\n#define DUK__ADVANCECHARS(lex_ctx,count)    duk__advance_chars((lex_ctx), (count))\n#define DUK__ADVANCEBYTES(lex_ctx,count)    duk__advance_bytes((lex_ctx), (count))\n#define DUK__INITBUFFER(lex_ctx)            duk__initbuffer((lex_ctx))\n#define DUK__APPENDBUFFER(lex_ctx,x)        duk__appendbuffer((lex_ctx), (duk_codepoint_t) (x))\n#define DUK__APPENDBUFFER_ASCII(lex_ctx,x)  duk__appendbuffer_ascii((lex_ctx), (duk_codepoint_t) (x))\n\n/* lookup shorthands (note: assume context variable is named 'lex_ctx') */\n#define DUK__L0()  DUK__LOOKUP(lex_ctx, 0)\n#define DUK__L1()  DUK__LOOKUP(lex_ctx, 1)\n#define DUK__L2()  DUK__LOOKUP(lex_ctx, 2)\n#define DUK__L3()  DUK__LOOKUP(lex_ctx, 3)\n#define DUK__L4()  DUK__LOOKUP(lex_ctx, 4)\n#define DUK__L5()  DUK__LOOKUP(lex_ctx, 5)\n\n/* packed advance/token number macro used by multiple functions */\n#define DUK__ADVTOK(advbytes,tok)  ((((advbytes) * sizeof(duk_lexer_codepoint)) << 8) + (tok))\n\n/*\n *  Advance lookup window by N characters, filling in new characters as\n *  necessary.  After returning caller is guaranteed a character window of\n *  at least DUK_LEXER_WINDOW_SIZE characters.\n *\n *  The main function duk__advance_bytes() is called at least once per every\n *  token so it has a major lexer/compiler performance impact.  There are two\n *  variants for the main duk__advance_bytes() algorithm: a sliding window\n *  approach which is slightly faster at the cost of larger code footprint,\n *  and a simple copying one.\n *\n *  Decoding directly from the source string would be another lexing option.\n *  But the lookup window based approach has the advantage of hiding the\n *  source string and its encoding effectively which gives more flexibility\n *  going forward to e.g. support chunked streaming of source from flash.\n *\n *  Decodes UTF-8/CESU-8 leniently with support for code points from U+0000 to\n *  U+10FFFF, causing an error if the input is unparseable.  Leniency means:\n *\n *    * Unicode code point validation is intentionally not performed,\n *      except to check that the codepoint does not exceed 0x10ffff.\n *\n *    * In particular, surrogate pairs are allowed and not combined, which\n *      allows source files to represent all SourceCharacters with CESU-8.\n *      Broken surrogate pairs are allowed, as ECMAScript does not mandate\n *      their validation.\n *\n *    * Allow non-shortest UTF-8 encodings.\n *\n *  Leniency here causes few security concerns because all character data is\n *  decoded into Unicode codepoints before lexer processing, and is then\n *  re-encoded into CESU-8.  The source can be parsed as strict UTF-8 with\n *  a compiler option.  However, ECMAScript source characters include -all-\n *  16-bit unsigned integer codepoints, so leniency seems to be appropriate.\n *\n *  Note that codepoints above the BMP are not strictly SourceCharacters,\n *  but the lexer still accepts them as such.  Before ending up in a string\n *  or an identifier name, codepoints above BMP are converted into surrogate\n *  pairs and then CESU-8 encoded, resulting in 16-bit Unicode data as\n *  expected by ECMAScript.\n *\n *  An alternative approach to dealing with invalid or partial sequences\n *  would be to skip them and replace them with e.g. the Unicode replacement\n *  character U+FFFD.  This has limited utility because a replacement character\n *  will most likely cause a parse error, unless it occurs inside a string.\n *  Further, ECMAScript source is typically pure ASCII.\n *\n *  See:\n *\n *     http://en.wikipedia.org/wiki/UTF-8\n *     http://en.wikipedia.org/wiki/CESU-8\n *     http://tools.ietf.org/html/rfc3629\n *     http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences\n *\n *  Future work:\n *\n *    * Reject other invalid Unicode sequences (see Wikipedia entry for examples)\n *      in strict UTF-8 mode.\n *\n *    * Size optimize.  An attempt to use a 16-byte lookup table for the first\n *      byte resulted in a code increase though.\n *\n *    * Is checking against maximum 0x10ffff really useful?  4-byte encoding\n *      imposes a certain limit anyway.\n *\n *    * Support chunked streaming of source code.  Can be implemented either\n *      by streaming chunks of bytes or chunks of codepoints.\n */\n\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\nDUK_LOCAL void duk__fill_lexer_buffer(duk_lexer_ctx *lex_ctx, duk_small_uint_t start_offset_bytes) {\n\tduk_lexer_codepoint *cp, *cp_end;\n\tduk_ucodepoint_t x;\n\tduk_small_uint_t contlen;\n\tconst duk_uint8_t *p, *p_end;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\tduk_ucodepoint_t mincp;\n#endif\n\tduk_int_t input_line;\n\n\t/* Use temporaries and update lex_ctx only when finished. */\n\tinput_line = lex_ctx->input_line;\n\tp = lex_ctx->input + lex_ctx->input_offset;\n\tp_end = lex_ctx->input + lex_ctx->input_length;\n\n\tcp = (duk_lexer_codepoint *) (void *) ((duk_uint8_t *) lex_ctx->buffer + start_offset_bytes);\n\tcp_end = lex_ctx->buffer + DUK_LEXER_BUFFER_SIZE;\n\n\tfor (; cp != cp_end; cp++) {\n\t\tcp->offset = (duk_size_t) (p - lex_ctx->input);\n\t\tcp->line = input_line;\n\n\t\t/* XXX: potential issue with signed pointers, p_end < p. */\n\t\tif (DUK_UNLIKELY(p >= p_end)) {\n\t\t\t/* If input_offset were assigned a negative value, it would\n\t\t\t * result in a large positive value.  Most likely it would be\n\t\t\t * larger than input_length and be caught here.  In any case\n\t\t\t * no memory unsafe behavior would happen.\n\t\t\t */\n\t\t\tcp->codepoint = -1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tx = (duk_ucodepoint_t) (*p++);\n\n\t\t/* Fast path. */\n\n\t\tif (DUK_LIKELY(x < 0x80UL)) {\n\t\t\tDUK_ASSERT(x != 0x2028UL && x != 0x2029UL);  /* not LS/PS */\n\t\t\tif (DUK_UNLIKELY(x <= 0x000dUL)) {\n\t\t\t\tif ((x == 0x000aUL) ||\n\t\t\t\t    ((x == 0x000dUL) && (p >= p_end || *p != 0x000aUL))) {\n\t\t\t\t\t/* lookup for 0x000a above assumes shortest encoding now */\n\n\t\t\t\t\t/* E5 Section 7.3, treat the following as newlines:\n\t\t\t\t\t *   LF\n\t\t\t\t\t *   CR [not followed by LF]\n\t\t\t\t\t *   LS\n\t\t\t\t\t *   PS\n\t\t\t\t\t *\n\t\t\t\t\t * For CR LF, CR is ignored if it is followed by LF, and the LF will bump\n\t\t\t\t\t * the line number.\n\t\t\t\t\t */\n\t\t\t\t\tinput_line++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcp->codepoint = (duk_codepoint_t) x;\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Slow path. */\n\n\t\tif (x < 0xc0UL) {\n\t\t\t/* 10xx xxxx -> invalid */\n\t\t\tgoto error_encoding;\n\t\t} else if (x < 0xe0UL) {\n\t\t\t/* 110x xxxx   10xx xxxx  */\n\t\t\tcontlen = 1;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\t\tmincp = 0x80UL;\n#endif\n\t\t\tx = x & 0x1fUL;\n\t\t} else if (x < 0xf0UL) {\n\t\t\t/* 1110 xxxx   10xx xxxx   10xx xxxx */\n\t\t\tcontlen = 2;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\t\tmincp = 0x800UL;\n#endif\n\t\t\tx = x & 0x0fUL;\n\t\t} else if (x < 0xf8UL) {\n\t\t\t/* 1111 0xxx   10xx xxxx   10xx xxxx   10xx xxxx */\n\t\t\tcontlen = 3;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\t\tmincp = 0x10000UL;\n#endif\n\t\t\tx = x & 0x07UL;\n\t\t} else {\n\t\t\t/* no point in supporting encodings of 5 or more bytes */\n\t\t\tgoto error_encoding;\n\t\t}\n\n\t\tDUK_ASSERT(p_end >= p);\n\t\tif ((duk_size_t) contlen > (duk_size_t) (p_end - p)) {\n\t\t\tgoto error_clipped;\n\t\t}\n\n\t\twhile (contlen > 0) {\n\t\t\tduk_small_uint_t y;\n\t\t\ty = *p++;\n\t\t\tif ((y & 0xc0U) != 0x80U) {\n\t\t\t\t/* check that byte has the form 10xx xxxx */\n\t\t\t\tgoto error_encoding;\n\t\t\t}\n\t\t\tx = x << 6;\n\t\t\tx += y & 0x3fUL;\n\t\t\tcontlen--;\n\t\t}\n\n\t\t/* check final character validity */\n\n\t\tif (x > 0x10ffffUL) {\n\t\t\tgoto error_encoding;\n\t\t}\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tif (x < mincp || (x >= 0xd800UL && x <= 0xdfffUL) || x == 0xfffeUL) {\n\t\t\tgoto error_encoding;\n\t\t}\n#endif\n\n\t\tDUK_ASSERT(x != 0x000aUL && x != 0x000dUL);\n\t\tif ((x == 0x2028UL) || (x == 0x2029UL)) {\n\t\t\tinput_line++;\n\t\t}\n\n\t\tcp->codepoint = (duk_codepoint_t) x;\n\t}\n\n\tlex_ctx->input_offset = (duk_size_t) (p - lex_ctx->input);\n\tlex_ctx->input_line = input_line;\n\treturn;\n\n error_clipped:   /* clipped codepoint */\n error_encoding:  /* invalid codepoint encoding or codepoint */\n\tlex_ctx->input_offset = (duk_size_t) (p - lex_ctx->input);\n\tlex_ctx->input_line = input_line;\n\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_SOURCE_DECODE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__advance_bytes(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_bytes) {\n\tduk_small_uint_t used_bytes, avail_bytes;\n\n\tDUK_ASSERT_DISABLE(count_bytes >= 0);  /* unsigned */\n\tDUK_ASSERT(count_bytes <= (duk_small_uint_t) (DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint)));\n\tDUK_ASSERT(lex_ctx->window >= lex_ctx->buffer);\n\tDUK_ASSERT(lex_ctx->window < lex_ctx->buffer + DUK_LEXER_BUFFER_SIZE);\n\tDUK_ASSERT((duk_uint8_t *) lex_ctx->window + count_bytes <= (duk_uint8_t *) lex_ctx->buffer + DUK_LEXER_BUFFER_SIZE * sizeof(duk_lexer_codepoint));\n\n\t/* Zero 'count' is also allowed to make call sites easier.\n\t * Arithmetic in bytes generates better code in GCC.\n\t */\n\n\tlex_ctx->window = (duk_lexer_codepoint *) (void *) ((duk_uint8_t *) lex_ctx->window + count_bytes);  /* avoid multiply */\n\tused_bytes = (duk_small_uint_t) ((duk_uint8_t *) lex_ctx->window - (duk_uint8_t *) lex_ctx->buffer);\n\tavail_bytes = DUK_LEXER_BUFFER_SIZE * sizeof(duk_lexer_codepoint) - used_bytes;\n\tif (avail_bytes < (duk_small_uint_t) (DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint))) {\n\t\t/* Not enough data to provide a full window, so \"scroll\" window to\n\t\t * start of buffer and fill up the rest.\n\t\t */\n\t\tduk_memmove((void *) lex_ctx->buffer,\n\t\t            (const void *) lex_ctx->window,\n\t\t            (size_t) avail_bytes);\n\t\tlex_ctx->window = lex_ctx->buffer;\n\t\tduk__fill_lexer_buffer(lex_ctx, avail_bytes);\n\t}\n}\n\nDUK_LOCAL void duk__init_lexer_window(duk_lexer_ctx *lex_ctx) {\n\tlex_ctx->window = lex_ctx->buffer;\n\tduk__fill_lexer_buffer(lex_ctx, 0);\n}\n#else  /* DUK_USE_LEXER_SLIDING_WINDOW */\nDUK_LOCAL duk_codepoint_t duk__read_char(duk_lexer_ctx *lex_ctx) {\n\tduk_ucodepoint_t x;\n\tduk_small_uint_t len;\n\tduk_small_uint_t i;\n\tconst duk_uint8_t *p;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\tduk_ucodepoint_t mincp;\n#endif\n\tduk_size_t input_offset;\n\n\tinput_offset = lex_ctx->input_offset;\n\tif (DUK_UNLIKELY(input_offset >= lex_ctx->input_length)) {\n\t\t/* If input_offset were assigned a negative value, it would\n\t\t * result in a large positive value.  Most likely it would be\n\t\t * larger than input_length and be caught here.  In any case\n\t\t * no memory unsafe behavior would happen.\n\t\t */\n\t\treturn -1;\n\t}\n\n\tp = lex_ctx->input + input_offset;\n\tx = (duk_ucodepoint_t) (*p);\n\n\tif (DUK_LIKELY(x < 0x80UL)) {\n\t\t/* 0xxx xxxx -> fast path */\n\n\t\t/* input offset tracking */\n\t\tlex_ctx->input_offset++;\n\n\t\tDUK_ASSERT(x != 0x2028UL && x != 0x2029UL);  /* not LS/PS */\n\t\tif (DUK_UNLIKELY(x <= 0x000dUL)) {\n\t\t\tif ((x == 0x000aUL) ||\n\t\t\t    ((x == 0x000dUL) && (lex_ctx->input_offset >= lex_ctx->input_length ||\n\t\t\t                         lex_ctx->input[lex_ctx->input_offset] != 0x000aUL))) {\n\t\t\t\t/* lookup for 0x000a above assumes shortest encoding now */\n\n\t\t\t\t/* E5 Section 7.3, treat the following as newlines:\n\t\t\t\t *   LF\n\t\t\t\t *   CR [not followed by LF]\n\t\t\t\t *   LS\n\t\t\t\t *   PS\n\t\t\t\t *\n\t\t\t\t * For CR LF, CR is ignored if it is followed by LF, and the LF will bump\n\t\t\t\t * the line number.\n\t\t\t\t */\n\t\t\t\tlex_ctx->input_line++;\n\t\t\t}\n\t\t}\n\n\t\treturn (duk_codepoint_t) x;\n\t}\n\n\t/* Slow path. */\n\n\tif (x < 0xc0UL) {\n\t\t/* 10xx xxxx -> invalid */\n\t\tgoto error_encoding;\n\t} else if (x < 0xe0UL) {\n\t\t/* 110x xxxx   10xx xxxx  */\n\t\tlen = 2;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tmincp = 0x80UL;\n#endif\n\t\tx = x & 0x1fUL;\n\t} else if (x < 0xf0UL) {\n\t\t/* 1110 xxxx   10xx xxxx   10xx xxxx */\n\t\tlen = 3;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tmincp = 0x800UL;\n#endif\n\t\tx = x & 0x0fUL;\n\t} else if (x < 0xf8UL) {\n\t\t/* 1111 0xxx   10xx xxxx   10xx xxxx   10xx xxxx */\n\t\tlen = 4;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tmincp = 0x10000UL;\n#endif\n\t\tx = x & 0x07UL;\n\t} else {\n\t\t/* no point in supporting encodings of 5 or more bytes */\n\t\tgoto error_encoding;\n\t}\n\n\tDUK_ASSERT(lex_ctx->input_length >= lex_ctx->input_offset);\n\tif ((duk_size_t) len > (duk_size_t) (lex_ctx->input_length - lex_ctx->input_offset)) {\n\t\tgoto error_clipped;\n\t}\n\n\tp++;\n\tfor (i = 1; i < len; i++) {\n\t\tduk_small_uint_t y;\n\t\ty = *p++;\n\t\tif ((y & 0xc0U) != 0x80U) {\n\t\t\t/* check that byte has the form 10xx xxxx */\n\t\t\tgoto error_encoding;\n\t\t}\n\t\tx = x << 6;\n\t\tx += y & 0x3fUL;\n\t}\n\n\t/* check final character validity */\n\n\tif (x > 0x10ffffUL) {\n\t\tgoto error_encoding;\n\t}\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\tif (x < mincp || (x >= 0xd800UL && x <= 0xdfffUL) || x == 0xfffeUL) {\n\t\tgoto error_encoding;\n\t}\n#endif\n\n\t/* input offset tracking */\n\tlex_ctx->input_offset += len;\n\n\t/* line tracking */\n\tDUK_ASSERT(x != 0x000aUL && x != 0x000dUL);\n\tif ((x == 0x2028UL) || (x == 0x2029UL)) {\n\t\tlex_ctx->input_line++;\n\t}\n\n\treturn (duk_codepoint_t) x;\n\n error_clipped:   /* clipped codepoint */\n error_encoding:  /* invalid codepoint encoding or codepoint */\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_SOURCE_DECODE_FAILED);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_LOCAL void duk__advance_bytes(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_bytes) {\n\tduk_small_uint_t keep_bytes;\n\tduk_lexer_codepoint *cp, *cp_end;\n\n\tDUK_ASSERT_DISABLE(count_bytes >= 0);  /* unsigned */\n\tDUK_ASSERT(count_bytes <= (duk_small_uint_t) (DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint)));\n\n\t/* Zero 'count' is also allowed to make call sites easier. */\n\n\tkeep_bytes = DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint) - count_bytes;\n\tduk_memmove((void *) lex_ctx->window,\n\t            (const void *) ((duk_uint8_t *) lex_ctx->window + count_bytes),\n\t            (size_t) keep_bytes);\n\n\tcp = (duk_lexer_codepoint *) ((duk_uint8_t *) lex_ctx->window + keep_bytes);\n\tcp_end = lex_ctx->window + DUK_LEXER_WINDOW_SIZE;\n\tfor (; cp != cp_end; cp++) {\n\t\tcp->offset = lex_ctx->input_offset;\n\t\tcp->line = lex_ctx->input_line;\n\t\tcp->codepoint = duk__read_char(lex_ctx);\n\t}\n}\n\nDUK_LOCAL void duk__init_lexer_window(duk_lexer_ctx *lex_ctx) {\n\t/* Call with count == DUK_LEXER_WINDOW_SIZE to fill buffer initially. */\n\tduk__advance_bytes(lex_ctx, DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint));  /* fill window */\n}\n#endif  /* DUK_USE_LEXER_SLIDING_WINDOW */\n\nDUK_LOCAL void duk__advance_chars(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_chars) {\n\tduk__advance_bytes(lex_ctx, count_chars * sizeof(duk_lexer_codepoint));\n}\n\n/*\n *  (Re)initialize the temporary byte buffer.  May be called extra times\n *  with little impact.\n */\n\nDUK_LOCAL void duk__initbuffer(duk_lexer_ctx *lex_ctx) {\n\t/* Reuse buffer as is unless buffer has grown large. */\n\tif (DUK_HBUFFER_DYNAMIC_GET_SIZE(lex_ctx->buf) < DUK_LEXER_TEMP_BUF_LIMIT) {\n\t\t/* Keep current size */\n\t} else {\n\t\tduk_hbuffer_resize(lex_ctx->thr, lex_ctx->buf, DUK_LEXER_TEMP_BUF_LIMIT);\n\t}\n\n\tDUK_BW_INIT_WITHBUF(lex_ctx->thr, &lex_ctx->bw, lex_ctx->buf);\n}\n\n/*\n *  Append a Unicode codepoint to the temporary byte buffer.  Performs\n *  CESU-8 surrogate pair encoding for codepoints above the BMP.\n *  Existing surrogate pairs are allowed and also encoded into CESU-8.\n */\n\nDUK_LOCAL void duk__appendbuffer(duk_lexer_ctx *lex_ctx, duk_codepoint_t x) {\n\t/*\n\t *  Since character data is only generated by decoding the source or by\n\t *  the compiler itself, we rely on the input codepoints being correct\n\t *  and avoid a check here.\n\t *\n\t *  Character data can also come here through decoding of Unicode\n\t *  escapes (\"\\udead\\ubeef\") so all 16-but unsigned values can be\n\t *  present, even when the source file itself is strict UTF-8.\n\t */\n\tDUK_ASSERT(x >= 0 && x <= 0x10ffffL);\n\n\tDUK_BW_WRITE_ENSURE_CESU8(lex_ctx->thr, &lex_ctx->bw, (duk_ucodepoint_t) x);\n}\n\nDUK_LOCAL void duk__appendbuffer_ascii(duk_lexer_ctx *lex_ctx, duk_codepoint_t x) {\n\t/* ASCII characters can be emitted as a single byte without encoding\n\t * which matters for some fast paths.\n\t */\n\tDUK_ASSERT(x >= 0 && x <= 0x7f);\n\n\tDUK_BW_WRITE_ENSURE_U8(lex_ctx->thr, &lex_ctx->bw, (duk_uint8_t) x);\n}\n\n/*\n *  Intern the temporary byte buffer into a valstack slot\n *  (in practice, slot1 or slot2).\n */\n\nDUK_LOCAL duk_hstring *duk__internbuffer(duk_lexer_ctx *lex_ctx, duk_idx_t valstack_idx) {\n\tDUK_ASSERT(valstack_idx == lex_ctx->slot1_idx || valstack_idx == lex_ctx->slot2_idx);\n\n\tDUK_BW_PUSH_AS_STRING(lex_ctx->thr, &lex_ctx->bw);\n\tduk_replace(lex_ctx->thr, valstack_idx);\n\treturn duk_known_hstring(lex_ctx->thr, valstack_idx);\n}\n\n/*\n *  Init lexer context\n */\n\nDUK_INTERNAL void duk_lexer_initctx(duk_lexer_ctx *lex_ctx) {\n\tDUK_ASSERT(lex_ctx != NULL);\n\n\tduk_memzero(lex_ctx, sizeof(*lex_ctx));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\n\tlex_ctx->window = NULL;\n#endif\n\tlex_ctx->thr = NULL;\n\tlex_ctx->input = NULL;\n\tlex_ctx->buf = NULL;\n#endif\n}\n\n/*\n *  Set lexer input position and reinitialize lookup window.\n */\n\nDUK_INTERNAL void duk_lexer_getpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt) {\n\tpt->offset = lex_ctx->window[0].offset;\n\tpt->line = lex_ctx->window[0].line;\n}\n\nDUK_INTERNAL void duk_lexer_setpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt) {\n\tDUK_ASSERT_DISABLE(pt->offset >= 0);  /* unsigned */\n\tDUK_ASSERT(pt->line >= 1);\n\tlex_ctx->input_offset = pt->offset;\n\tlex_ctx->input_line = pt->line;\n\tduk__init_lexer_window(lex_ctx);\n}\n\n/*\n *  Lexing helpers\n */\n\n/* Numeric value of a hex digit (also covers octal and decimal digits) or\n * -1 if not a valid hex digit.\n */\nDUK_LOCAL duk_codepoint_t duk__hexval_validate(duk_codepoint_t x) {\n\tduk_small_int_t t;\n\n\t/* Here 'x' is a Unicode codepoint */\n\tif (DUK_LIKELY(x >= 0 && x <= 0xff)) {\n\t\tt = duk_hex_dectab[x];\n\t\tif (DUK_LIKELY(t >= 0)) {\n\t\t\treturn t;\n\t\t}\n\t}\n\n\treturn -1;\n}\n\n/* Just a wrapper for call sites where 'x' is known to be valid so\n * we assert for it before decoding.\n */\nDUK_LOCAL duk_codepoint_t duk__hexval(duk_codepoint_t x) {\n\tduk_codepoint_t ret;\n\n\tDUK_ASSERT((x >= DUK_ASC_0 && x <= DUK_ASC_9) ||\n\t           (x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_F) ||\n\t           (x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_F));\n\tret = duk__hexval_validate(x);\n\tDUK_ASSERT(ret >= 0 && ret <= 15);\n\treturn ret;\n}\n\n/* having this as a separate function provided a size benefit */\nDUK_LOCAL duk_bool_t duk__is_hex_digit(duk_codepoint_t x) {\n\tif (DUK_LIKELY(x >= 0 && x <= 0xff)) {\n\t\treturn (duk_hex_dectab[x] >= 0);\n\t}\n\treturn 0;\n}\n\n/* Parse a Unicode escape of the form \\xHH, \\uHHHH, or \\u{H+}.  Shared by\n * source and RegExp parsing.\n */\nDUK_LOCAL duk_codepoint_t duk__lexer_parse_escape(duk_lexer_ctx *lex_ctx, duk_bool_t allow_es6) {\n\tduk_small_int_t digits;  /* Initial value 2 or 4 for fixed length escapes, 0 for ES2015 \\u{H+}. */\n\tduk_codepoint_t escval;\n\tduk_codepoint_t x;\n\tduk_small_uint_t adv;\n\n\tDUK_ASSERT(DUK__L0() == DUK_ASC_BACKSLASH);  /* caller responsibilities */\n\tDUK_ASSERT(DUK__L1() == DUK_ASC_LC_X || DUK__L1() == DUK_ASC_LC_U);\n\tDUK_UNREF(allow_es6);\n\n\tadv = 2;\n\tdigits = 2;\n\tif (DUK__L1() == DUK_ASC_LC_U) {\n\t\tdigits = 4;\n#if defined(DUK_USE_ES6_UNICODE_ESCAPE)\n\t\tif (DUK__L2() == DUK_ASC_LCURLY && allow_es6) {\n\t\t\tdigits = 0;\n\t\t\tadv = 3;\n\t\t}\n#endif\n\t}\n\tDUK__ADVANCECHARS(lex_ctx, adv);\n\n\tescval = 0;\n\tfor (;;) {\n\t\t/* One of the escape forms: \\xHH, \\uHHHH, \\u{H+}.\n\t\t * The 'digits' variable tracks parsing state and is\n\t\t * initialized to:\n\t\t *\n\t\t *   \\xHH     2\n\t\t *   \\uHH     4\n\t\t *   \\u{H+}   0 first time, updated to -1 to indicate\n\t\t *            at least one digit has been parsed\n\t\t *\n\t\t * Octal parsing is handled separately because it can be\n\t\t * done with fixed lookahead and also has validation\n\t\t * rules which depend on the escape length (which is\n\t\t * variable).\n\t\t *\n\t\t * We don't need a specific check for x < 0 (end of\n\t\t * input) or duk_unicode_is_line_terminator(x)\n\t\t * because the 'dig' decode will fail and lead to a\n\t\t * SyntaxError.\n\t\t */\n\t\tduk_codepoint_t dig;\n\n\t\tx = DUK__L0();\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\n\t\tdig = duk__hexval_validate(x);\n\t\tif (digits > 0) {\n\t\t\tdigits--;\n\t\t\tif (dig < 0) {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t\tDUK_ASSERT(dig >= 0x00 && dig <= 0x0f);\n\t\t\tescval = (escval << 4) + dig;\n\t\t\tif (digits == 0) {\n\t\t\t\tDUK_ASSERT(escval >= 0 && escval <= 0xffffL);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n#if defined(DUK_USE_ES6_UNICODE_ESCAPE)\n\t\t\tDUK_ASSERT(digits == 0 /* first time */ || digits == -1 /* others */);\n\t\t\tif (dig >= 0) {\n\t\t\t\tDUK_ASSERT(dig >= 0x00 && dig <= 0x0f);\n\t\t\t\tescval = (escval << 4) + dig;\n\t\t\t\tif (escval > 0x10ffffL) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_RCURLY) {\n\t\t\t\tif (digits == 0) {\n\t\t\t\t\t/* Empty escape, \\u{}. */\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(escval >= 0 && escval <= 0x10ffffL);\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t\tdigits = -1;  /* Indicate we have at least one digit. */\n#else  /* DUK_USE_ES6_UNICODE_ESCAPE */\n\t\t\tDUK_ASSERT(0);  /* Never happens if \\u{H+} support disabled. */\n#endif  /* DUK_USE_ES6_UNICODE_ESCAPE */\n\t\t}\n\t}\n\n\treturn escval;\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Parse legacy octal escape of the form \\N{1,3}, e.g. \\0, \\5, \\0377.  Maximum\n * allowed value is \\0377 (U+00FF), longest match is used.  Used for both string\n * RegExp octal escape parsing.  Window[0] must be the slash '\\' and the first\n * digit must already be validated to be in [0-9] by the caller.\n */\nDUK_LOCAL duk_codepoint_t duk__lexer_parse_legacy_octal(duk_lexer_ctx *lex_ctx, duk_small_uint_t *out_adv, duk_bool_t reject_annex_b) {\n\tduk_codepoint_t cp;\n\tduk_small_uint_t lookup_idx;\n\tduk_small_uint_t adv;\n\tduk_codepoint_t tmp;\n\n\tDUK_ASSERT(out_adv != NULL);\n\tDUK_ASSERT(DUK__LOOKUP(lex_ctx, 0) == DUK_ASC_BACKSLASH);\n\tDUK_ASSERT(DUK__LOOKUP(lex_ctx, 1) >= DUK_ASC_0 && DUK__LOOKUP(lex_ctx, 1) <= DUK_ASC_9);\n\n\tcp = 0;\n\ttmp = 0;\n\tfor (lookup_idx = 1; lookup_idx <= 3; lookup_idx++) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"lookup_idx=%ld, cp=%ld\", (long) lookup_idx, (long) cp));\n\t\ttmp = DUK__LOOKUP(lex_ctx, lookup_idx);\n\t\tif (tmp < DUK_ASC_0 || tmp > DUK_ASC_7) {\n\t\t\t/* No more valid digits. */\n\t\t\tbreak;\n\t\t}\n\t\ttmp = (cp << 3) + (tmp - DUK_ASC_0);\n\t\tif (tmp > 0xff) {\n\t\t\t/* Three digit octal escapes above \\377 (= 0xff)\n\t\t\t * are not allowed.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\t\tcp = tmp;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"final lookup_idx=%ld, cp=%ld\", (long) lookup_idx, (long) cp));\n\n\tadv = lookup_idx;\n\tif (lookup_idx == 1) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"\\\\8 or \\\\9 -> treat as literal, accept in strict mode too\"));\n\t\tDUK_ASSERT(tmp == DUK_ASC_8 || tmp == DUK_ASC_9);\n\t\tcp = tmp;\n\t\tadv++;  /* correction to above, eat offending character */\n\t} else if (lookup_idx == 2 && cp == 0) {\n\t\t/* Note: 'foo\\0bar' is OK in strict mode, but 'foo\\00bar' is not.\n\t\t * It won't be interpreted as 'foo\\u{0}0bar' but as a SyntaxError.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"\\\\0 -> accept in strict mode too\"));\n\t} else {\n\t\t/* This clause also handles non-shortest zero, e.g. \\00. */\n\t\tif (reject_annex_b) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-zero octal literal %ld -> reject in strict-mode\", (long) cp));\n\t\t\tcp = -1;\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-zero octal literal %ld -> accepted\", (long) cp));\n\t\t\tDUK_ASSERT(cp >= 0 && cp <= 0xff);\n\t\t}\n\t}\n\n\t*out_adv = adv;\n\n\tDUK_ASSERT((cp >= 0 && cp <= 0xff) || (cp == -1 && reject_annex_b));\n\treturn cp;\n}\n\n/* XXX: move strict mode to lex_ctx? */\nDUK_LOCAL void duk__lexer_parse_string_literal(duk_lexer_ctx *lex_ctx, duk_token *out_token, duk_small_int_t quote, duk_bool_t strict_mode) {\n\tduk_small_uint_t adv;\n\n\tfor (adv = 1 /* initial quote */ ;;) {\n\t\tduk_codepoint_t x;\n\n\t\tDUK__ADVANCECHARS(lex_ctx, adv);  /* eat opening quote on first loop */\n\t\tx = DUK__L0();\n\n\t\tadv = 1;\n\t\tif (x == quote) {\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat closing quote */\n\t\t\tbreak;\n\t\t} else if (x == '\\\\') {\n\t\t\t/* DUK__L0        -> '\\' char\n\t\t\t * DUK__L1 ... DUK__L5 -> more lookup\n\t\t\t */\n\t\t\tduk_small_int_t emitcp = -1;\n\n\t\t\tx = DUK__L1();\n\n\t\t\t/* How much to advance before next loop. */\n\t\t\tadv = 2;  /* note: long live range */\n\n\t\t\tswitch (x) {\n\t\t\tcase '\\'':\n\t\t\t\temitcp = 0x0027;\n\t\t\t\tbreak;\n\t\t\tcase '\"':\n\t\t\t\temitcp = 0x0022;\n\t\t\t\tbreak;\n\t\t\tcase '\\\\':\n\t\t\t\temitcp = 0x005c;\n\t\t\t\tbreak;\n\t\t\tcase 'b':\n\t\t\t\temitcp = 0x0008;\n\t\t\t\tbreak;\n\t\t\tcase 'f':\n\t\t\t\temitcp = 0x000c;\n\t\t\t\tbreak;\n\t\t\tcase 'n':\n\t\t\t\temitcp = 0x000a;\n\t\t\t\tbreak;\n\t\t\tcase 'r':\n\t\t\t\temitcp = 0x000d;\n\t\t\t\tbreak;\n\t\t\tcase 't':\n\t\t\t\temitcp = 0x0009;\n\t\t\t\tbreak;\n\t\t\tcase 'v':\n\t\t\t\temitcp = 0x000b;\n\t\t\t\tbreak;\n\t\t\tcase 'x':\n\t\t\tcase 'u': {\n\t\t\t\tduk_codepoint_t esc_cp;\n\t\t\t\tesc_cp = duk__lexer_parse_escape(lex_ctx, 1 /*allow_es6*/);\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, esc_cp);\n\t\t\t\tadv = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tif (duk_unicode_is_line_terminator(x)) {\n\t\t\t\t\t/* line continuation */\n\t\t\t\t\tif (x == 0x000d && DUK__L2() == 0x000a) {\n\t\t\t\t\t\t/* CR LF again a special case */\n\t\t\t\t\t\tadv = 3;  /* line terminator, CR, LF */\n\t\t\t\t\t}\n\t\t\t\t} else if (DUK__ISDIGIT(x)) {\n\t\t\t\t\t/*\n\t\t\t\t\t *  Octal escape or zero escape:\n\t\t\t\t\t *    \\0                                     (lookahead not OctalDigit)\n\t\t\t\t\t *    \\1 ... \\7                              (lookahead not OctalDigit)\n\t\t\t\t\t *    \\ZeroToThree OctalDigit                (lookahead not OctalDigit)\n\t\t\t\t\t *    \\FourToSeven OctalDigit                (no lookahead restrictions)\n\t\t\t\t\t *    \\ZeroToThree OctalDigit OctalDigit     (no lookahead restrictions)\n\t\t\t\t\t *\n\t\t\t\t\t *  Zero escape is part of the standard syntax.  Octal escapes are\n\t\t\t\t\t *  defined in E5 Section B.1.2, and are only allowed in non-strict mode.\n\t\t\t\t\t *  Any other productions starting with a decimal digit are invalid\n\t\t\t\t\t *  but are in practice treated like identity escapes.\n\t\t\t\t\t *\n\t\t\t\t\t *  Parse octal (up to 3 digits) from the lookup window.\n\t\t\t\t\t */\n\n\t\t\t\t\temitcp = duk__lexer_parse_legacy_octal(lex_ctx, &adv, strict_mode /*reject_annex_b*/);\n\t\t\t\t\tif (emitcp < 0) {\n\t\t\t\t\t\tgoto fail_escape;\n\t\t\t\t\t}\n\t\t\t\t} else if (x < 0) {\n\t\t\t\t\tgoto fail_unterminated;\n\t\t\t\t} else {\n\t\t\t\t\t/* escaped NonEscapeCharacter */\n\t\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t\t}\n\t\t\t}  /* end default clause */\n\t\t\t}  /* end switch */\n\n\t\t\t/* Shared handling for single codepoint escapes. */\n\t\t\tif (emitcp >= 0) {\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, emitcp);\n\t\t\t}\n\n\t\t\t/* Track number of escapes; count not really needed but directive\n\t\t\t * prologues need to detect whether there were any escapes or line\n\t\t\t * continuations or not.\n\t\t\t */\n\t\t\tout_token->num_escapes++;\n\t\t} else if (x >= 0x20 && x <= 0x7f) {\n\t\t\t/* Fast path for ASCII case, avoids line terminator\n\t\t\t * check and CESU-8 encoding.\n\t\t\t */\n\t\t\tDUK_ASSERT(x >= 0);\n\t\t\tDUK_ASSERT(!duk_unicode_is_line_terminator(x));\n\t\t\tDUK_ASSERT(x != quote);\n\t\t\tDUK_ASSERT(x != DUK_ASC_BACKSLASH);\n\t\t\tDUK__APPENDBUFFER_ASCII(lex_ctx, x);\n\t\t} else if (x < 0 || duk_unicode_is_line_terminator(x)) {\n\t\t\tgoto fail_unterminated;\n\t\t} else {\n\t\t\t/* Character which is part of the string but wasn't handled\n\t\t\t * by the fast path.\n\t\t\t */\n\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t}\n\t} /* string parse loop */\n\n\treturn;\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterminated:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_STRING);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Skip to end-of-line (or end-of-file), used for single line comments. */\nDUK_LOCAL void duk__lexer_skip_to_endofline(duk_lexer_ctx *lex_ctx) {\n\tfor (;;) {\n\t\tduk_codepoint_t x;\n\n\t\tx = DUK__L0();\n\t\tif (x < 0 || duk_unicode_is_line_terminator(x)) {\n\t\t\tbreak;\n\t\t}\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t}\n}\n\n/*\n *  Parse ECMAScript source InputElementDiv or InputElementRegExp\n *  (E5 Section 7), skipping whitespace, comments, and line terminators.\n *\n *  Possible results are:\n *    (1) a token\n *    (2) a line terminator (skipped)\n *    (3) a comment (skipped)\n *    (4) EOF\n *\n *  White space is automatically skipped from the current position (but\n *  not after the input element).  If input has already ended, returns\n *  DUK_TOK_EOF indefinitely.  If a parse error occurs, uses an DUK_ERROR()\n *  macro call (and hence a longjmp through current heap longjmp context).\n *  Comments and line terminator tokens are automatically skipped.\n *\n *  The input element being matched is determined by regexp_mode; if set,\n *  parses a InputElementRegExp, otherwise a InputElementDiv.  The\n *  difference between these are handling of productions starting with a\n *  forward slash.\n *\n *  If strict_mode is set, recognizes additional future reserved words\n *  specific to strict mode, and refuses to parse octal literals.\n *\n *  The matching strategy below is to (currently) use a six character\n *  lookup window to quickly determine which production is the -longest-\n *  matching one, and then parse that.  The top-level if-else clauses\n *  match the first character, and the code blocks for each clause\n *  handle -all- alternatives for that first character.  ECMAScript\n *  specification uses the \"longest match wins\" semantics, so the order\n *  of the if-clauses matters.\n *\n *  Misc notes:\n *\n *    * ECMAScript numeric literals do not accept a sign character.\n *      Consequently e.g. \"-1.0\" is parsed as two tokens: a negative\n *      sign and a positive numeric literal.  The compiler performs\n *      the negation during compilation, so this has no adverse impact.\n *\n *    * There is no token for \"undefined\": it is just a value available\n *      from the global object (or simply established by doing a reference\n *      to an undefined value).\n *\n *    * Some contexts want Identifier tokens, which are IdentifierNames\n *      excluding reserved words, while some contexts want IdentifierNames\n *      directly.  In the latter case e.g. \"while\" is interpreted as an\n *      identifier name, not a DUK_TOK_WHILE token.  The solution here is\n *      to provide both token types: DUK_TOK_WHILE goes to 't' while\n *      DUK_TOK_IDENTIFIER goes to 't_nores', and 'slot1' always contains\n *      the identifier / keyword name.\n *\n *    * Directive prologue needs to identify string literals such as\n *      \"use strict\" and 'use strict', which are sensitive to line\n *      continuations and escape sequences.  For instance, \"use\\u0020strict\"\n *      is a valid directive but is distinct from \"use strict\".  The solution\n *      here is to decode escapes while tokenizing, but to keep track of the\n *      number of escapes.  Directive detection can then check that the\n *      number of escapes is zero.\n *\n *    * Multi-line comments with one or more internal LineTerminator are\n *      treated like a line terminator to comply with automatic semicolon\n *      insertion.\n */\n\nDUK_INTERNAL\nvoid duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,\n                                      duk_token *out_token,\n                                      duk_bool_t strict_mode,\n                                      duk_bool_t regexp_mode) {\n\tduk_codepoint_t x;           /* temporary, must be signed and 32-bit to hold Unicode code points */\n\tduk_small_uint_t advtok = 0; /* (advance << 8) + token_type, updated at function end,\n\t                              * init is unnecessary but suppresses \"may be used uninitialized\" warnings.\n\t                              */\n\tduk_bool_t got_lineterm = 0;  /* got lineterm preceding non-whitespace, non-lineterm token */\n\n\tif (++lex_ctx->token_count >= lex_ctx->token_limit) {\n\t\tgoto fail_token_limit;\n\t}\n\n\tout_token->t = DUK_TOK_EOF;\n\tout_token->t_nores = DUK_TOK_INVALID;  /* marker: copy t if not changed */\n#if 0  /* not necessary to init, disabled for faster parsing */\n\tout_token->num = DUK_DOUBLE_NAN;\n\tout_token->str1 = NULL;\n\tout_token->str2 = NULL;\n#endif\n\tout_token->num_escapes = 0;\n\t/* out_token->lineterm set by caller */\n\n\t/* This would be nice, but parsing is faster without resetting the\n\t * value slots.  The only side effect is that references to temporary\n\t * string values may linger until lexing is finished; they're then\n\t * freed normally.\n\t */\n#if 0\n\tduk_to_undefined(lex_ctx->thr, lex_ctx->slot1_idx);\n\tduk_to_undefined(lex_ctx->thr, lex_ctx->slot2_idx);\n#endif\n\n\t/* 'advtok' indicates how much to advance and which token id to assign\n\t * at the end.  This shared functionality minimizes code size.  All\n\t * code paths are required to set 'advtok' to some value, so no default\n\t * init value is used.  Code paths calling DUK_ERROR() never return so\n\t * they don't need to set advtok.\n\t */\n\n\t/*\n\t *  Matching order:\n\t *\n\t *    Punctuator first chars, also covers comments, regexps\n\t *    LineTerminator\n\t *    Identifier or reserved word, also covers null/true/false literals\n\t *    NumericLiteral\n\t *    StringLiteral\n\t *    EOF\n\t *\n\t *  The order does not matter as long as the longest match is\n\t *  always correctly identified.  There are order dependencies\n\t *  in the clauses, so it's not trivial to convert to a switch.\n\t */\n\n restart_lineupdate:\n\tout_token->start_line = lex_ctx->window[0].line;\n\n restart:\n\tout_token->start_offset = lex_ctx->window[0].offset;\n\n\tx = DUK__L0();\n\n\tswitch (x) {\n\tcase DUK_ASC_SPACE:\n\tcase DUK_ASC_HT:  /* fast paths for space and tab */\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\tgoto restart;\n\tcase DUK_ASC_LF:  /* LF line terminator; CR LF and Unicode lineterms are handled in slow path */\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\tgot_lineterm = 1;\n\t\tgoto restart_lineupdate;\n#if defined(DUK_USE_SHEBANG_COMMENTS)\n\tcase DUK_ASC_HASH:  /* '#' */\n\t\tif (DUK__L1() == DUK_ASC_EXCLAMATION && lex_ctx->window[0].offset == 0 &&\n\t\t    (lex_ctx->flags & DUK_COMPILE_SHEBANG)) {\n\t\t\t/* \"Shebang\" comment ('#! ...') on first line. */\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 2) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t}\n\t\tgoto fail_token;\n#endif  /* DUK_USE_SHEBANG_COMMENTS */\n\tcase DUK_ASC_SLASH:  /* '/' */\n\t\tif (DUK__L1() == DUK_ASC_SLASH) {\n\t\t\t/*\n\t\t\t *  E5 Section 7.4, allow SourceCharacter (which is any 16-bit\n\t\t\t *  code point).\n\t\t\t */\n\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 2) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t} else if (DUK__L1() == DUK_ASC_STAR) {\n\t\t\t/*\n\t\t\t *  E5 Section 7.4.  If the multi-line comment contains a newline,\n\t\t\t *  it is treated like a single line terminator for automatic\n\t\t\t *  semicolon insertion.\n\t\t\t */\n\n\t\t\tduk_bool_t last_asterisk = 0;\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 2);\n\t\t\tfor (;;) {\n\t\t\t\tx = DUK__L0();\n\t\t\t\tif (x < 0) {\n\t\t\t\t\tgoto fail_unterm_comment;\n\t\t\t\t}\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t\tif (last_asterisk && x == DUK_ASC_SLASH) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (duk_unicode_is_line_terminator(x)) {\n\t\t\t\t\tgot_lineterm = 1;\n\t\t\t\t}\n\t\t\t\tlast_asterisk = (x == DUK_ASC_STAR);\n\t\t\t}\n\t\t\tgoto restart_lineupdate;\n\t\t} else if (regexp_mode) {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t/*\n\t\t\t *  \"/\" followed by something in regexp mode.  See E5 Section 7.8.5.\n\t\t\t *\n\t\t\t *  RegExp parsing is a bit complex.  First, the regexp body is delimited\n\t\t\t *  by forward slashes, but the body may also contain forward slashes as\n\t\t\t *  part of an escape sequence or inside a character class (delimited by\n\t\t\t *  square brackets).  A mini state machine is used to implement these.\n\t\t\t *\n\t\t\t *  Further, an early (parse time) error must be thrown if the regexp\n\t\t\t *  would cause a run-time error when used in the expression new RegExp(...).\n\t\t\t *  Parsing here simply extracts the (candidate) regexp, and also accepts\n\t\t\t *  invalid regular expressions (which are delimited properly).  The caller\n\t\t\t *  (compiler) must perform final validation and regexp compilation.\n\t\t\t *\n\t\t\t *  RegExp first char may not be '/' (single line comment) or '*' (multi-\n\t\t\t *  line comment).  These have already been checked above, so there is no\n\t\t\t *  need below for special handling of the first regexp character as in\n\t\t\t *  the E5 productions.\n\t\t\t *\n\t\t\t *  About unicode escapes within regexp literals:\n\t\t\t *\n\t\t\t *      E5 Section 7.8.5 grammar does NOT accept \\uHHHH escapes.\n\t\t\t *      However, Section 6 states that regexps accept the escapes,\n\t\t\t *      see paragraph starting with \"In string literals...\".\n\t\t\t *      The regexp grammar, which sees the decoded regexp literal\n\t\t\t *      (after lexical parsing) DOES have a \\uHHHH unicode escape.\n\t\t\t *      So, for instance:\n\t\t\t *\n\t\t\t *          /\\u1234/\n\t\t\t *\n\t\t\t *      should first be parsed by the lexical grammar as:\n\t\t\t *\n\t\t\t *          '\\' 'u'      RegularExpressionBackslashSequence\n\t\t\t *          '1'          RegularExpressionNonTerminator\n\t\t\t *          '2'          RegularExpressionNonTerminator\n\t\t\t *          '3'          RegularExpressionNonTerminator\n\t\t\t *          '4'          RegularExpressionNonTerminator\n\t\t\t *\n\t\t\t *      and the escape itself is then parsed by the regexp engine.\n\t\t\t *      This is the current implementation.\n\t\t\t *\n\t\t\t *  Minor spec inconsistency:\n\t\t\t *\n\t\t\t *      E5 Section 7.8.5 RegularExpressionBackslashSequence is:\n\t\t\t *\n\t\t\t *         \\ RegularExpressionNonTerminator\n\t\t\t *\n\t\t\t *      while Section A.1 RegularExpressionBackslashSequence is:\n\t\t\t *\n\t\t\t *         \\ NonTerminator\n\t\t\t *\n\t\t\t *      The latter is not normative and a typo.\n\t\t\t *\n\t\t\t */\n\n\t\t\t/* first, parse regexp body roughly */\n\n\t\t\tduk_small_int_t state = 0;  /* 0=base, 1=esc, 2=class, 3=class+esc */\n\n\t\t\tDUK__INITBUFFER(lex_ctx);\n\t\t\tfor (;;) {\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* skip opening slash on first loop */\n\t\t\t\tx = DUK__L0();\n\t\t\t\tif (x < 0 || duk_unicode_is_line_terminator(x)) {\n\t\t\t\t\tgoto fail_unterm_regexp;\n\t\t\t\t}\n\t\t\t\tx = DUK__L0();  /* re-read to avoid spill / fetch */\n\t\t\t\tif (state == 0) {\n\t\t\t\t\tif (x == DUK_ASC_SLASH) {\n\t\t\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat closing slash */\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\t\t\t\tstate = 1;\n\t\t\t\t\t} else if (x == DUK_ASC_LBRACKET) {\n\t\t\t\t\t\tstate = 2;\n\t\t\t\t\t}\n\t\t\t\t} else if (state == 1) {\n\t\t\t\t\tstate = 0;\n\t\t\t\t} else if (state == 2) {\n\t\t\t\t\tif (x == DUK_ASC_RBRACKET) {\n\t\t\t\t\t\tstate = 0;\n\t\t\t\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\t\t\t\tstate = 3;\n\t\t\t\t\t}\n\t\t\t\t} else { /* state == 3 */\n\t\t\t\t\tstate = 2;\n\t\t\t\t}\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t}\n\t\t\tout_token->str1 = duk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\n\t\t\t/* second, parse flags */\n\n\t\t\tDUK__INITBUFFER(lex_ctx);\n\t\t\tfor (;;) {\n\t\t\t\tx = DUK__L0();\n\t\t\t\tif (!duk_unicode_is_identifier_part(x)) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tx = DUK__L0();  /* re-read to avoid spill / fetch */\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t}\n\t\t\tout_token->str2 = duk__internbuffer(lex_ctx, lex_ctx->slot2_idx);\n\n\t\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\t\t/* validation of the regexp is caller's responsibility */\n\n\t\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_REGEXP);\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\tgoto fail_regexp_support;\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\t/* \"/=\" and not in regexp mode */\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_DIV_EQ);\n\t\t} else {\n\t\t\t/* \"/\" and not in regexp mode */\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_DIV);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_LCURLY:  /* '{' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LCURLY);\n\t\tbreak;\n\tcase DUK_ASC_RCURLY:  /* '}' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_RCURLY);\n\t\tbreak;\n\tcase DUK_ASC_LPAREN:  /* '(' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LPAREN);\n\t\tbreak;\n\tcase DUK_ASC_RPAREN:  /* ')' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_RPAREN);\n\t\tbreak;\n\tcase DUK_ASC_LBRACKET:  /* '[' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LBRACKET);\n\t\tbreak;\n\tcase DUK_ASC_RBRACKET:  /* ']' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_RBRACKET);\n\t\tbreak;\n\tcase DUK_ASC_PERIOD:  /* '.' */\n\t\tif (DUK__ISDIGIT(DUK__L1())) {\n\t\t\t/* Period followed by a digit can only start DecimalLiteral\n\t\t\t * (handled in slow path).  We could jump straight into the\n\t\t\t * DecimalLiteral handling but should avoid goto to inside\n\t\t\t * a block.\n\t\t\t */\n\t\t\tgoto slow_path;\n\t\t}\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_PERIOD);\n\t\tbreak;\n\tcase DUK_ASC_SEMICOLON:  /* ';' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_SEMICOLON);\n\t\tbreak;\n\tcase DUK_ASC_COMMA:  /* ',' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_COMMA);\n\t\tbreak;\n\tcase DUK_ASC_LANGLE:  /* '<' */\n#if defined(DUK_USE_HTML_COMMENTS)\n\t\tif (DUK__L1() == DUK_ASC_EXCLAMATION && DUK__L2() == DUK_ASC_MINUS && DUK__L3() == DUK_ASC_MINUS) {\n\t\t\t/*\n\t\t\t *  ES2015: B.1.3, handle \"<!--\" SingleLineHTMLOpenComment\n\t\t\t */\n\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 4) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t}\n\t\telse\n#endif  /* DUK_USE_HTML_COMMENTS */\n\t\tif (DUK__L1() == DUK_ASC_LANGLE && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_ALSHIFT_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_LE);\n\t\t} else if (DUK__L1() == DUK_ASC_LANGLE) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_ALSHIFT);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LT);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_RANGLE:  /* '>' */\n\t\tif (DUK__L1() == DUK_ASC_RANGLE && DUK__L2() == DUK_ASC_RANGLE && DUK__L3() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(4, DUK_TOK_RSHIFT_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_RANGLE && DUK__L2() == DUK_ASC_RANGLE) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_RSHIFT);\n\t\t} else if (DUK__L1() == DUK_ASC_RANGLE && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_ARSHIFT_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_GE);\n\t\t} else if (DUK__L1() == DUK_ASC_RANGLE) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_ARSHIFT);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_GT);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_EQUALS:  /* '=' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_SEQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_EQUALSIGN);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_EXCLAMATION:  /* '!' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_SNEQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_NEQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LNOT);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_PLUS:  /* '+' */\n\t\tif (DUK__L1() == DUK_ASC_PLUS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_INCREMENT);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_ADD_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_ADD);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_MINUS:  /* '-' */\n#if defined(DUK_USE_HTML_COMMENTS)\n\t\tif (got_lineterm && DUK__L1() == DUK_ASC_MINUS && DUK__L2() == DUK_ASC_RANGLE) {\n\t\t\t/*\n\t\t\t *  ES2015: B.1.3, handle \"-->\" SingleLineHTMLCloseComment\n\t\t\t *  Only allowed:\n\t\t\t *  - on new line\n\t\t\t *  - preceded only by whitespace\n\t\t\t *  - preceded by end of multiline comment and optional whitespace\n\t\t\t *\n\t\t\t * Since whitespace generates no tokens, and multiline comments\n\t\t\t * are treated as a line ending, consulting `got_lineterm` is\n\t\t\t * sufficient to test for these three options.\n\t\t\t */\n\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 3) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t} else\n#endif  /* DUK_USE_HTML_COMMENTS */\n\t\tif (DUK__L1() == DUK_ASC_MINUS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_DECREMENT);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_SUB_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_SUB);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_STAR:  /* '*' */\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tif (DUK__L1() == DUK_ASC_STAR && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_EXP_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_STAR) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_EXP);\n\t\t} else\n#endif\n\t\tif (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_MUL_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_MUL);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_PERCENT:  /* '%' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_MOD_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_MOD);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_AMP:  /* '&' */\n\t\tif (DUK__L1() == DUK_ASC_AMP) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_LAND);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_BAND_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BAND);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_PIPE:  /* '|' */\n\t\tif (DUK__L1() == DUK_ASC_PIPE) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_LOR);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_BOR_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BOR);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_CARET:  /* '^' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_BXOR_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BXOR);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_TILDE:  /* '~' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BNOT);\n\t\tbreak;\n\tcase DUK_ASC_QUESTION:  /* '?' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_QUESTION);\n\t\tbreak;\n\tcase DUK_ASC_COLON:  /* ':' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_COLON);\n\t\tbreak;\n\tcase DUK_ASC_DOUBLEQUOTE:    /* '\"' */\n\tcase DUK_ASC_SINGLEQUOTE: {  /* '\\'' */\n\t\tDUK__INITBUFFER(lex_ctx);\n\t\tduk__lexer_parse_string_literal(lex_ctx, out_token, x /*quote*/, strict_mode);\n\t\tduk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\t\tout_token->str1 = duk_known_hstring(lex_ctx->thr, lex_ctx->slot1_idx);\n\n\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_STRING);\n\t\tbreak;\n\t}\n\tdefault:\n\t\tgoto slow_path;\n\t}  /* switch */\n\n\tgoto skip_slow_path;\n\n slow_path:\n\tif (duk_unicode_is_line_terminator(x)) {\n\t\tif (x == 0x000d && DUK__L1() == 0x000a) {\n\t\t\t/*\n\t\t\t *  E5 Section 7.3: CR LF is detected as a single line terminator for\n\t\t\t *  line numbers.  Here we also detect it as a single line terminator\n\t\t\t *  token.\n\t\t\t */\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 2);\n\t\t} else {\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t}\n\t\tgot_lineterm = 1;\n\t\tgoto restart_lineupdate;\n\t} else if (duk_unicode_is_identifier_start(x) || x == DUK_ASC_BACKSLASH) {\n\t\t/*\n\t\t *  Parse an identifier and then check whether it is:\n\t\t *    - reserved word (keyword or other reserved word)\n\t\t *    - \"null\"  (NullLiteral)\n\t\t *    - \"true\"  (BooleanLiteral)\n\t\t *    - \"false\" (BooleanLiteral)\n\t\t *    - anything else => identifier\n\t\t *\n\t\t *  This does not follow the E5 productions cleanly, but is\n\t\t *  useful and compact.\n\t\t *\n\t\t *  Note that identifiers may contain Unicode escapes,\n\t\t *  see E5 Sections 6 and 7.6.  They must be decoded first,\n\t\t *  and the result checked against allowed characters.\n\t\t *  The above if-clause accepts an identifier start and an\n\t\t *  '\\' character -- no other token can begin with a '\\'.\n\t\t *\n\t\t *  Note that \"get\" and \"set\" are not reserved words in E5\n\t\t *  specification so they are recognized as plain identifiers\n\t\t *  (the tokens DUK_TOK_GET and DUK_TOK_SET are actually not\n\t\t *  used now).  The compiler needs to work around this.\n\t\t *\n\t\t *  Strictly speaking, following ECMAScript longest match\n\t\t *  specification, an invalid escape for the first character\n\t\t *  should cause a syntax error.  However, an invalid escape\n\t\t *  for IdentifierParts should just terminate the identifier\n\t\t *  early (longest match), and let the next tokenization\n\t\t *  fail.  For instance Rhino croaks with 'foo\\z' when\n\t\t *  parsing the identifier.  This has little practical impact.\n\t\t */\n\n\t\tduk_small_uint_t i, i_end;\n\t\tduk_bool_t first = 1;\n\t\tduk_hstring *str;\n\n\t\tDUK__INITBUFFER(lex_ctx);\n\t\tfor (;;) {\n\t\t\t/* re-lookup first char on first loop */\n\t\t\tif (DUK__L0() == DUK_ASC_BACKSLASH) {\n\t\t\t\tduk_codepoint_t esc_cp;\n\t\t\t\tif (DUK__L1() != DUK_ASC_LC_U) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t\tesc_cp = duk__lexer_parse_escape(lex_ctx, 1 /*allow_es6*/);\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, esc_cp);\n\n\t\t\t\t/* IdentifierStart is stricter than IdentifierPart, so if the first\n\t\t\t\t * character is escaped, must have a stricter check here.\n\t\t\t\t */\n\t\t\t\tif (!(first ? duk_unicode_is_identifier_start(esc_cp) : duk_unicode_is_identifier_part(esc_cp))) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\n\t\t\t\t/* Track number of escapes: necessary for proper keyword\n\t\t\t\t * detection.\n\t\t\t\t */\n\t\t\t\tout_token->num_escapes++;\n\t\t\t} else {\n\t\t\t\t/* Note: first character is checked against this.  But because\n\t\t\t\t * IdentifierPart includes all IdentifierStart characters, and\n\t\t\t\t * the first character (if unescaped) has already been checked\n\t\t\t\t * in the if condition, this is OK.\n\t\t\t\t */\n\t\t\t\tif (!duk_unicode_is_identifier_part(DUK__L0())) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, DUK__L0());\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t}\n\t\t\tfirst = 0;\n\t\t}\n\n\t\tout_token->str1 = duk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\t\tstr = out_token->str1;\n\t\tout_token->t_nores = DUK_TOK_IDENTIFIER;\n\n\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\t/*\n\t\t *  Interned identifier is compared against reserved words, which are\n\t\t *  currently interned into the heap context.  See genbuiltins.py.\n\t\t *\n\t\t *  Note that an escape in the identifier disables recognition of\n\t\t *  keywords; e.g. \"\\u0069f = 1;\" is a valid statement (assigns to\n\t\t *  identifier named \"if\").  This is not necessarily compliant,\n\t\t *  see test-dec-escaped-char-in-keyword.js.\n\t\t *\n\t\t *  Note: \"get\" and \"set\" are awkward.  They are not officially\n\t\t *  ReservedWords (and indeed e.g. \"var set = 1;\" is valid), and\n\t\t *  must come out as DUK_TOK_IDENTIFIER.  The compiler needs to\n\t\t *  work around this a bit.\n\t\t */\n\n\t\t/* XXX: optimize by adding the token numbers directly into the\n\t\t * always interned duk_hstring objects (there should be enough\n\t\t * flag bits free for that)?\n\t\t */\n\n\t\ti_end = (strict_mode ? DUK_STRIDX_END_RESERVED : DUK_STRIDX_START_STRICT_RESERVED);\n\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_IDENTIFIER);\n\t\tif (out_token->num_escapes == 0) {\n\t\t\tfor (i = DUK_STRIDX_START_RESERVED; i < i_end; i++) {\n\t\t\t\tDUK_ASSERT_DISABLE(i >= 0);  /* unsigned */\n\t\t\t\tDUK_ASSERT(i < DUK_HEAP_NUM_STRINGS);\n\t\t\t\tif (DUK_HTHREAD_GET_STRING(lex_ctx->thr, i) == str) {\n\t\t\t\t\tadvtok = DUK__ADVTOK(0, DUK_STRIDX_TO_TOK(i));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if (DUK__ISDIGIT(x) || (x == DUK_ASC_PERIOD)) {\n\t\t/* Note: decimal number may start with a period, but must be followed by a digit */\n\n\t\t/*\n\t\t *  Pre-parsing for decimal, hex, octal (both legacy and ES2015),\n\t\t *  and binary literals, followed by an actual parser step\n\t\t *  provided by numconv.\n\t\t *\n\t\t *  Note: the leading sign character ('+' or '-') is -not- part of\n\t\t *  the production in E5 grammar, and that the a DecimalLiteral\n\t\t *  starting with a '0' must be followed by a non-digit.\n\t\t *\n\t\t *  XXX: the two step parsing process is quite awkward, it would\n\t\t *  be more straightforward to allow numconv to parse the longest\n\t\t *  valid prefix (it already does that, it only needs to indicate\n\t\t *  where the input ended).  However, the lexer decodes characters\n\t\t *  using a limited lookup window, so this is not a trivial change.\n\t\t */\n\n\t\t/* XXX: because of the final check below (that the literal is not\n\t\t * followed by a digit), this could maybe be simplified, if we bail\n\t\t * out early from a leading zero (and if there are no periods etc).\n\t\t * Maybe too complex.\n\t\t */\n\n\t\tduk_double_t val;\n\t\tduk_bool_t legacy_oct = 0;\n\t\tduk_small_int_t state;  /* 0=before period/exp,\n\t\t                         * 1=after period, before exp\n\t\t                         * 2=after exp, allow '+' or '-'\n\t\t                         * 3=after exp and exp sign\n\t\t                         */\n\t\tduk_small_uint_t s2n_flags;\n\t\tduk_codepoint_t y, z;\n\t\tduk_small_int_t s2n_radix = 10;\n\t\tduk_small_uint_t pre_adv = 0;\n\n\t\tDUK__INITBUFFER(lex_ctx);\n\t\ty = DUK__L1();\n\n\t\tif (x == DUK_ASC_0) {\n\t\t\tz = DUK_LOWERCASE_CHAR_ASCII(y);\n\n\t\t\tpre_adv = 2;  /* default for 0xNNN, 0oNNN, 0bNNN. */\n\t\t\tif (z == DUK_ASC_LC_X) {\n\t\t\t\ts2n_radix = 16;\n\t\t\t} else if (z == DUK_ASC_LC_O) {\n\t\t\t\ts2n_radix = 8;\n\t\t\t} else if (z == DUK_ASC_LC_B) {\n\t\t\t\ts2n_radix = 2;\n\t\t\t} else {\n\t\t\t\tpre_adv = 0;\n\t\t\t\tif (DUK__ISDIGIT(y)) {\n\t\t\t\t\tif (strict_mode) {\n\t\t\t\t\t\t/* Reject octal like \\07 but also octal-lookalike\n\t\t\t\t\t\t * decimal like \\08 in strict mode.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tgoto fail_number_literal;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t/* Legacy OctalIntegerLiteral or octal-lookalice\n\t\t\t\t\t\t * decimal.  Deciding between the two happens below\n\t\t\t\t\t\t * in digit scanning.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t\t\t\tpre_adv = 1;\n\t\t\t\t\t\tlegacy_oct = 1;\n\t\t\t\t\t\ts2n_radix = 8;  /* tentative unless conflicting digits found */\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tDUK__ADVANCECHARS(lex_ctx, pre_adv);\n\n\t\t/* XXX: we could parse integers here directly, and fall back\n\t\t * to numconv only when encountering a fractional expression\n\t\t * or when an octal literal turned out to be decimal (0778 etc).\n\t\t */\n\t\tstate = 0;\n\t\tfor (;;) {\n\t\t\tx = DUK__L0();  /* re-lookup curr char on first round */\n\t\t\tif (DUK__ISDIGIT(x)) {\n\t\t\t\t/* Note: intentionally allow leading zeroes here, as the\n\t\t\t\t * actual parser will check for them.\n\t\t\t\t */\n\t\t\t\tif (state == 0 && legacy_oct && (x == DUK_ASC_8 || x == DUK_ASC_9)) {\n\t\t\t\t\t/* Started out as an octal-lookalike\n\t\t\t\t\t * but interpreted as decimal, e.g.\n\t\t\t\t\t * '0779' -> 779.  This also means\n\t\t\t\t\t * that fractions are allowed, e.g.\n\t\t\t\t\t * '0779.123' is allowed but '0777.123'\n\t\t\t\t\t * is not!\n\t\t\t\t\t */\n\t\t\t\t\ts2n_radix = 10;\n\t\t\t\t}\n\t\t\t\tif (state == 2) {\n\t\t\t\t\tstate = 3;\n\t\t\t\t}\n\t\t\t} else if (s2n_radix == 16 && DUK__ISHEXDIGIT(x)) {\n\t\t\t\t/* Note: 'e' and 'E' are also accepted here. */\n\t\t\t\t;\n\t\t\t} else if (x == DUK_ASC_PERIOD) {\n\t\t\t\tif (state >= 1 || s2n_radix != 10) {\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tstate = 1;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_LC_E || x == DUK_ASC_UC_E) {\n\t\t\t\tif (state >= 2 || s2n_radix != 10) {\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tstate = 2;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_MINUS || x == DUK_ASC_PLUS) {\n\t\t\t\tif (state != 2) {\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tstate = 3;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t}\n\n\t\t/* XXX: better coercion */\n\t\t(void) duk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\n\t\tif (s2n_radix != 10) {\n\t\t\t/* For bases other than 10, integer only. */\n\t\t\ts2n_flags = DUK_S2N_FLAG_ALLOW_LEADING_ZERO;\n\t\t} else {\n\t\t\ts2n_flags = DUK_S2N_FLAG_ALLOW_EXP |\n\t\t\t            DUK_S2N_FLAG_ALLOW_FRAC |\n\t\t\t            DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t\t\t            DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t\t\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO;\n\t\t}\n\n\t\tduk_dup(lex_ctx->thr, lex_ctx->slot1_idx);\n\t\tduk_numconv_parse(lex_ctx->thr, s2n_radix, s2n_flags);\n\t\tval = duk_to_number_m1(lex_ctx->thr);\n\t\tif (DUK_ISNAN(val)) {\n\t\t\tgoto fail_number_literal;\n\t\t}\n\t\tduk_replace(lex_ctx->thr, lex_ctx->slot1_idx);  /* could also just pop? */\n\n\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\t/* Section 7.8.3 (note): NumericLiteral must be followed by something other than\n\t\t * IdentifierStart or DecimalDigit.\n\t\t */\n\n\t\tif (DUK__ISDIGIT(DUK__L0()) || duk_unicode_is_identifier_start(DUK__L0())) {\n\t\t\tgoto fail_number_literal;\n\t\t}\n\n\t\tout_token->num = val;\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_NUMBER);\n\t} else if (duk_unicode_is_whitespace(DUK__LOOKUP(lex_ctx, 0))) {\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\tgoto restart;\n\t} else if (x < 0) {\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_EOF);\n\t} else {\n\t\tgoto fail_token;\n\t}\n skip_slow_path:\n\n\t/*\n\t *  Shared exit path\n\t */\n\n\tDUK__ADVANCEBYTES(lex_ctx, advtok >> 8);\n\tout_token->t = advtok & 0xff;\n\tif (out_token->t_nores == DUK_TOK_INVALID) {\n\t\tout_token->t_nores = out_token->t;\n\t}\n\tout_token->lineterm = got_lineterm;\n\n\t/* Automatic semicolon insertion is allowed if a token is preceded\n\t * by line terminator(s), or terminates a statement list (right curly\n\t * or EOF).\n\t */\n\tif (got_lineterm || out_token->t == DUK_TOK_RCURLY || out_token->t == DUK_TOK_EOF) {\n\t\tout_token->allow_auto_semi = 1;\n\t} else {\n\t\tout_token->allow_auto_semi = 0;\n\t}\n\n\treturn;\n\n fail_token_limit:\n\tDUK_ERROR_RANGE(lex_ctx->thr, DUK_STR_TOKEN_LIMIT);\n\tDUK_WO_NORETURN(return;);\n\n fail_token:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_TOKEN);\n\tDUK_WO_NORETURN(return;);\n\n fail_number_literal:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_NUMBER_LITERAL);\n\tDUK_WO_NORETURN(return;);\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterm_regexp:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_REGEXP);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterm_comment:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_COMMENT);\n\tDUK_WO_NORETURN(return;);\n\n#if !defined(DUK_USE_REGEXP_SUPPORT)\n fail_regexp_support:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_REGEXP_SUPPORT_DISABLED);\n\tDUK_WO_NORETURN(return;);\n#endif\n}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Parse a RegExp token.  The grammar is described in E5 Section 15.10.\n *  Terminal constructions (such as quantifiers) are parsed directly here.\n *\n *  0xffffffffU is used as a marker for \"infinity\" in quantifiers.  Further,\n *  DUK__MAX_RE_QUANT_DIGITS limits the maximum number of digits that\n *  will be accepted for a quantifier.\n */\n\nDUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token *out_token) {\n\tduk_small_uint_t advtok = 0;  /* init is unnecessary but suppresses \"may be used uninitialized\" warnings */\n\tduk_codepoint_t x, y;\n\n\tif (++lex_ctx->token_count >= lex_ctx->token_limit) {\n\t\tgoto fail_token_limit;\n\t}\n\n\tduk_memzero(out_token, sizeof(*out_token));\n\n\tx = DUK__L0();\n\ty = DUK__L1();\n\n\tDUK_DDD(DUK_DDDPRINT(\"parsing regexp token, L0=%ld, L1=%ld\", (long) x, (long) y));\n\n\tswitch (x) {\n\tcase DUK_ASC_PIPE: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_DISJUNCTION);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_CARET: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ASSERT_START);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_DOLLAR: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ASSERT_END);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_QUESTION: {\n\t\tout_token->qmin = 0;\n\t\tout_token->qmax = 1;\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 0;\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_STAR: {\n\t\tout_token->qmin = 0;\n\t\tout_token->qmax = DUK_RE_QUANTIFIER_INFINITE;\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 0;\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_PLUS: {\n\t\tout_token->qmin = 1;\n\t\tout_token->qmax = DUK_RE_QUANTIFIER_INFINITE;\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 0;\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LCURLY: {\n\t\t/* Production allows 'DecimalDigits', including leading zeroes */\n\t\tduk_uint32_t val1 = 0;\n\t\tduk_uint32_t val2 = DUK_RE_QUANTIFIER_INFINITE;\n\t\tduk_small_int_t digits = 0;\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\tduk_lexer_point lex_pt;\n#endif\n\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t/* Store lexer position, restoring if quantifier is invalid. */\n\t\tDUK_LEXER_GETPOINT(lex_ctx, &lex_pt);\n#endif\n\n\t\tfor (;;) {\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat '{' on entry */\n\t\t\tx = DUK__L0();\n\t\t\tif (DUK__ISDIGIT(x)) {\n\t\t\t\tdigits++;\n\t\t\t\tval1 = val1 * 10 + (duk_uint32_t) duk__hexval(x);\n\t\t\t} else if (x == DUK_ASC_COMMA) {\n\t\t\t\tif (digits > DUK__MAX_RE_QUANT_DIGITS) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (val2 != DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (DUK__L1() == DUK_ASC_RCURLY) {\n\t\t\t\t\t/* form: { DecimalDigits , }, val1 = min count */\n\t\t\t\t\tif (digits == 0) {\n\t\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t\t}\n\t\t\t\t\tout_token->qmin = val1;\n\t\t\t\t\tout_token->qmax = DUK_RE_QUANTIFIER_INFINITE;\n\t\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tval2 = val1;\n\t\t\t\tval1 = 0;\n\t\t\t\tdigits = 0;  /* not strictly necessary because of lookahead '}' above */\n\t\t\t} else if (x == DUK_ASC_RCURLY) {\n\t\t\t\tif (digits > DUK__MAX_RE_QUANT_DIGITS) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (digits == 0) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (val2 != DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\t/* val2 = min count, val1 = max count */\n\t\t\t\t\tout_token->qmin = val2;\n\t\t\t\t\tout_token->qmax = val1;\n\t\t\t\t} else {\n\t\t\t\t\t/* val1 = count */\n\t\t\t\t\tout_token->qmin = val1;\n\t\t\t\t\tout_token->qmax = val1;\n\t\t\t\t}\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tgoto invalid_quantifier;\n\t\t\t}\n\t\t}\n\t\tif (DUK__L0() == DUK_ASC_QUESTION) {\n\t\t\tout_token->greedy = 0;\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t} else {\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tadvtok = DUK__ADVTOK(0, DUK_RETOK_QUANTIFIER);\n\t\tbreak;\n invalid_quantifier:\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t/* Failed to match the quantifier, restore lexer and parse\n\t\t * opening brace as a literal.\n\t\t */\n\t\tDUK_LEXER_SETPOINT(lex_ctx, &lex_pt);\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_CHAR);\n\t\tout_token->num = DUK_ASC_LCURLY;\n#else\n\t\tgoto fail_quantifier;\n#endif\n\t\tbreak;\n\t}\n\tcase DUK_ASC_PERIOD: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_PERIOD);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_BACKSLASH: {\n\t\t/* The E5.1 specification does not seem to allow IdentifierPart characters\n\t\t * to be used as identity escapes.  Unfortunately this includes '$', which\n\t\t * cannot be escaped as '\\$'; it needs to be escaped e.g. as '\\u0024'.\n\t\t * Many other implementations (including V8 and Rhino, for instance) do\n\t\t * accept '\\$' as a valid identity escape, which is quite pragmatic, and\n\t\t * ES2015 Annex B relaxes the rules to allow these (and other) real world forms.\n\t\t */\n\n\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_CHAR);  /* default: char escape (two chars) */\n\t\tif (y == DUK_ASC_LC_B) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ASSERT_WORD_BOUNDARY);\n\t\t} else if (y == DUK_ASC_UC_B) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY);\n\t\t} else if (y == DUK_ASC_LC_F) {\n\t\t\tout_token->num = 0x000c;\n\t\t} else if (y == DUK_ASC_LC_N) {\n\t\t\tout_token->num = 0x000a;\n\t\t} else if (y == DUK_ASC_LC_T) {\n\t\t\tout_token->num = 0x0009;\n\t\t} else if (y == DUK_ASC_LC_R) {\n\t\t\tout_token->num = 0x000d;\n\t\t} else if (y == DUK_ASC_LC_V) {\n\t\t\tout_token->num = 0x000b;\n\t\t} else if (y == DUK_ASC_LC_C) {\n\t\t\tx = DUK__L2();\n\t\t\tif ((x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_Z) ||\n\t\t\t    (x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_Z)) {\n\t\t\t\tout_token->num = (duk_uint32_t) (x % 32);\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ATOM_CHAR);\n\t\t\t} else {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t} else if (y == DUK_ASC_LC_X || y == DUK_ASC_LC_U) {\n\t\t\t/* The token value is the Unicode codepoint without\n\t\t\t * it being decode into surrogate pair characters\n\t\t\t * here.  The \\u{H+} is only allowed in Unicode mode\n\t\t\t * which we don't support yet.\n\t\t\t */\n\t\t\tout_token->num = (duk_uint32_t) duk__lexer_parse_escape(lex_ctx, 0 /*allow_es6*/);\n\t\t\tadvtok = DUK__ADVTOK(0, DUK_RETOK_ATOM_CHAR);\n\t\t} else if (y == DUK_ASC_LC_D) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_DIGIT);\n\t\t} else if (y == DUK_ASC_UC_D) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_NOT_DIGIT);\n\t\t} else if (y == DUK_ASC_LC_S) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_WHITE);\n\t\t} else if (y == DUK_ASC_UC_S) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_NOT_WHITE);\n\t\t} else if (y == DUK_ASC_LC_W) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_WORD_CHAR);\n\t\t} else if (y == DUK_ASC_UC_W) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_NOT_WORD_CHAR);\n\t\t} else if (DUK__ISDIGIT(y)) {\n\t\t\t/* E5 Section 15.10.2.11 */\n\t\t\tif (y == DUK_ASC_0) {\n\t\t\t\tif (DUK__ISDIGIT(DUK__L2())) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t\tout_token->num = 0x0000;\n\t\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_CHAR);\n\t\t\t} else {\n\t\t\t\t/* XXX: shared parsing? */\n\t\t\t\tduk_uint32_t val = 0;\n\t\t\t\tduk_small_int_t i;\n\t\t\t\tfor (i = 0; ; i++) {\n\t\t\t\t\tif (i >= DUK__MAX_RE_DECESC_DIGITS) {\n\t\t\t\t\t\tgoto fail_escape;\n\t\t\t\t\t}\n\t\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat backslash on entry */\n\t\t\t\t\tx = DUK__L0();\n\t\t\t\t\tif (!DUK__ISDIGIT(x)) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tval = val * 10 + (duk_uint32_t) duk__hexval(x);\n\t\t\t\t}\n\t\t\t\t/* DUK__L0() cannot be a digit, because the loop doesn't terminate if it is */\n\t\t\t\tadvtok = DUK__ADVTOK(0, DUK_RETOK_ATOM_BACKREFERENCE);\n\t\t\t\tout_token->num = val;\n\t\t\t}\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t} else if (y >= 0) {\n\t\t\t/* For ES2015 Annex B, accept any source character as identity\n\t\t\t * escape except 'c' which is used for control characters.\n\t\t\t * http://www.ecma-international.org/ecma-262/6.0/#sec-regular-expressions-patterns\n\t\t\t * Careful not to match end-of-buffer (<0) here.\n\t\t\t * This is not yet full ES2015 Annex B because cases above\n\t\t\t * (like hex escape) won't backtrack.\n\t\t\t */\n\t\t\tDUK_ASSERT(y != DUK_ASC_LC_C);  /* covered above */\n#else  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t} else if ((y >= 0 && !duk_unicode_is_identifier_part(y)) ||\n\t\t           y == DUK_UNICODE_CP_ZWNJ ||\n\t\t           y == DUK_UNICODE_CP_ZWJ) {\n\t\t\t/* For ES5.1 identity escapes are not allowed for identifier\n\t\t\t * parts.  This conflicts with a lot of real world code as this\n\t\t\t * doesn't e.g. allow escaping a dollar sign as /\\$/, see\n\t\t\t * test-regexp-identity-escape-dollar.js.\n\t\t\t */\n#endif  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t\tout_token->num = (duk_uint32_t) y;\n\t\t} else {\n\t\t\tgoto fail_escape;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LPAREN: {\n\t\t/* XXX: naming is inconsistent: ATOM_END_GROUP ends an ASSERT_START_LOOKAHEAD */\n\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tif (DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\t\t/* (?= */\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ASSERT_START_POS_LOOKAHEAD);\n\t\t\t} else if (DUK__L2() == DUK_ASC_EXCLAMATION) {\n\t\t\t\t/* (?! */\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD);\n\t\t\t} else if (DUK__L2() == DUK_ASC_COLON) {\n\t\t\t\t/* (?: */\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ATOM_START_NONCAPTURE_GROUP);\n\t\t\t} else {\n\t\t\t\tgoto fail_group;\n\t\t\t}\n\t\t} else {\n\t\t\t/* ( */\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_START_CAPTURE_GROUP);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_RPAREN: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_END_GROUP);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LBRACKET: {\n\t\t/*\n\t\t *  To avoid creating a heavy intermediate value for the list of ranges,\n\t\t *  only the start token ('[' or '[^') is parsed here.  The regexp\n\t\t *  compiler parses the ranges itself.\n\t\t */\n\n\t\t/* XXX: with DUK_USE_ES6_REGEXP_SYNTAX we should allow left bracket\n\t\t * literal too, but it's not easy to parse without backtracking.\n\t\t */\n\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_START_CHARCLASS);\n\t\tif (y == DUK_ASC_CARET) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_START_CHARCLASS_INVERTED);\n\t\t}\n\t\tbreak;\n\t}\n#if !defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\tcase DUK_ASC_RCURLY:\n\tcase DUK_ASC_RBRACKET: {\n\t\t/* Although these could be parsed as PatternCharacters unambiguously (here),\n\t\t * E5 Section 15.10.1 grammar explicitly forbids these as PatternCharacters.\n\t\t */\n\t\tgoto fail_invalid_char;\n\t\tbreak;\n\t}\n#endif\n\tcase -1: {\n\t\t/* EOF */\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_EOF);\n\t\tbreak;\n\t}\n\tdefault: {\n\t\t/* PatternCharacter, all excluded characters are matched by cases above */\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_CHAR);\n\t\tout_token->num = (duk_uint32_t) x;\n\t\tbreak;\n\t}\n\t}\n\n\t/*\n\t *  Shared exit path\n\t */\n\n\tDUK__ADVANCEBYTES(lex_ctx, advtok >> 8);\n\tout_token->t = advtok & 0xff;\n\treturn;\n\n fail_token_limit:\n\tDUK_ERROR_RANGE(lex_ctx->thr, DUK_STR_TOKEN_LIMIT);\n\tDUK_WO_NORETURN(return;);\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_group:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_GROUP);\n\tDUK_WO_NORETURN(return;);\n\n#if !defined(DUK_USE_ES6_REGEXP_SYNTAX)\n fail_invalid_char:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_CHARACTER);\n\tDUK_WO_NORETURN(return;);\n\n fail_quantifier:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_QUANTIFIER);\n\tDUK_WO_NORETURN(return;);\n#endif\n}\n\n/*\n *  Special parser for character classes; calls callback for every\n *  range parsed and returns the number of ranges present.\n */\n\n/* XXX: this duplicates functionality in duk_regexp.c where a similar loop is\n * required anyway.  We could use that BUT we need to update the regexp compiler\n * 'nranges' too.  Work this out a bit more cleanly to save space.\n */\n\n/* XXX: the handling of character range detection is a bit convoluted.\n * Try to simplify and make smaller.\n */\n\n/* XXX: logic for handling character ranges is now incorrect, it will accept\n * e.g. [\\d-z] whereas it should croak from it?  SMJS accepts this too, though.\n *\n * Needs a read through and a lot of additional tests.\n */\n\nDUK_LOCAL\nvoid duk__emit_u16_direct_ranges(duk_lexer_ctx *lex_ctx,\n                                 duk_re_range_callback gen_range,\n                                 void *userdata,\n                                 const duk_uint16_t *ranges,\n                                 duk_small_int_t num) {\n\tconst duk_uint16_t *ranges_end;\n\n\tDUK_UNREF(lex_ctx);\n\n\tranges_end = ranges + num;\n\twhile (ranges < ranges_end) {\n\t\t/* mark range 'direct', bypass canonicalization (see Wiki) */\n\t\tgen_range(userdata, (duk_codepoint_t) ranges[0], (duk_codepoint_t) ranges[1], 1);\n\t\tranges += 2;\n\t}\n}\n\nDUK_INTERNAL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_range_callback gen_range, void *userdata) {\n\tduk_codepoint_t start = -1;\n\tduk_codepoint_t ch;\n\tduk_codepoint_t x;\n\tduk_bool_t dash = 0;\n\tduk_small_uint_t adv = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"parsing regexp ranges\"));\n\n\tfor (;;) {\n\t\tDUK__ADVANCECHARS(lex_ctx, adv);\n\t\tadv = 1;\n\n\t\tx = DUK__L0();\n\n\t\tch = -1;  /* not strictly necessary, but avoids \"uninitialized variable\" warnings */\n\t\tDUK_UNREF(ch);\n\n\t\tif (x < 0) {\n\t\t\tgoto fail_unterm_charclass;\n\t\t} else if (x == DUK_ASC_RBRACKET) {\n\t\t\tif (start >= 0) {\n\t\t\t\tgen_range(userdata, start, start, 0);\n\t\t\t}\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat ']' before finishing */\n\t\t\tbreak;\n\t\t} else if (x == DUK_ASC_MINUS) {\n\t\t\tif (start >= 0 && !dash && DUK__L1() != DUK_ASC_RBRACKET) {\n\t\t\t\t/* '-' as a range indicator */\n\t\t\t\tdash = 1;\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\t/* '-' verbatim */\n\t\t\t\tch = x;\n\t\t\t}\n\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\t/*\n\t\t\t *  The escapes are same as outside a character class, except that \\b has a\n\t\t\t *  different meaning, and \\B and backreferences are prohibited (see E5\n\t\t\t *  Section 15.10.2.19).  However, it's difficult to share code because we\n\t\t\t *  handle e.g. \"\\n\" very differently: here we generate a single character\n\t\t\t *  range for it.\n\t\t\t */\n\n\t\t\t/* XXX: ES2015 surrogate pair handling. */\n\n\t\t\tx = DUK__L1();\n\n\t\t\tadv = 2;\n\n\t\t\tif (x == DUK_ASC_LC_B) {\n\t\t\t\t/* Note: '\\b' in char class is different than outside (assertion),\n\t\t\t\t * '\\B' is not allowed and is caught by the duk_unicode_is_identifier_part()\n\t\t\t\t * check below.\n\t\t\t\t */\n\t\t\t\tch = 0x0008;\n\t\t\t} else if (x == DUK_ASC_LC_F) {\n\t\t\t\tch = 0x000c;\n\t\t\t} else if (x == DUK_ASC_LC_N) {\n\t\t\t\tch = 0x000a;\n\t\t\t} else if (x == DUK_ASC_LC_T) {\n\t\t\t\tch = 0x0009;\n\t\t\t} else if (x == DUK_ASC_LC_R) {\n\t\t\t\tch = 0x000d;\n\t\t\t} else if (x == DUK_ASC_LC_V) {\n\t\t\t\tch = 0x000b;\n\t\t\t} else if (x == DUK_ASC_LC_C) {\n\t\t\t\tx = DUK__L2();\n\t\t\t\tadv = 3;\n\t\t\t\tif ((x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_Z) ||\n\t\t\t\t    (x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_Z)) {\n\t\t\t\t\tch = (x % 32);\n\t\t\t\t} else {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_LC_X || x == DUK_ASC_LC_U) {\n\t\t\t\t/* The \\u{H+} form is only allowed in Unicode mode which\n\t\t\t\t * we don't support yet.\n\t\t\t\t */\n\t\t\t\tch = duk__lexer_parse_escape(lex_ctx, 0 /*allow_es6*/);\n\t\t\t\tadv = 0;\n\t\t\t} else if (x == DUK_ASC_LC_D) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_digit,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_digit) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_UC_D) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_not_digit,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_not_digit) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_LC_S) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_white,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_white) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_UC_S) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_not_white,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_not_white) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_LC_W) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_wordchar,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_wordchar) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_UC_W) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_not_wordchar,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_not_wordchar) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (DUK__ISDIGIT(x)) {\n\t\t\t\t/* DecimalEscape, only \\0 is allowed, no leading\n\t\t\t\t * zeroes are allowed.\n\t\t\t\t *\n\t\t\t\t * ES2015 Annex B also allows (maximal match) legacy\n\t\t\t\t * octal escapes up to \\377 and \\8 and \\9 are\n\t\t\t\t * accepted as literal '8' and '9', also in strict mode.\n\t\t\t\t */\n\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t\t\tch = duk__lexer_parse_legacy_octal(lex_ctx, &adv, 0 /*reject_annex_b*/);\n\t\t\t\tDUK_ASSERT(ch >= 0);  /* no rejections */\n#else\n\t\t\t\tif (x == DUK_ASC_0 && !DUK__ISDIGIT(DUK__L2())) {\n\t\t\t\t\tch = 0x0000;\n\t\t\t\t} else {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n#endif\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t\t} else if (x >= 0) {\n\t\t\t\t/* IdentityEscape: ES2015 Annex B allows almost all\n\t\t\t\t * source characters here.  Match anything except\n\t\t\t\t * EOF here.\n\t\t\t\t */\n\t\t\t\tch = x;\n#else  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t\t} else if (!duk_unicode_is_identifier_part(x)) {\n\t\t\t\t/* IdentityEscape: ES5.1 doesn't allow identity escape\n\t\t\t\t * for identifier part characters, which conflicts with\n\t\t\t\t * some real world code.  For example, it doesn't allow\n\t\t\t\t * /[\\$]/ which is awkward.\n\t\t\t\t */\n\t\t\t\tch = x;\n#endif  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t\t} else {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t} else {\n\t\t\t/* character represents itself */\n\t\t\tch = x;\n\t\t}\n\n\t\t/* ch is a literal character here or -1 if parsed entity was\n\t\t * an escape such as \"\\s\".\n\t\t */\n\n\t\tif (ch < 0) {\n\t\t\t/* multi-character sets not allowed as part of ranges, see\n\t\t\t * E5 Section 15.10.2.15, abstract operation CharacterRange.\n\t\t\t */\n\t\t\tif (start >= 0) {\n\t\t\t\tif (dash) {\n\t\t\t\t\tgoto fail_range;\n\t\t\t\t} else {\n\t\t\t\t\tgen_range(userdata, start, start, 0);\n\t\t\t\t\tstart = -1;\n\t\t\t\t\t/* dash is already 0 */\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (start >= 0) {\n\t\t\t\tif (dash) {\n\t\t\t\t\tif (start > ch) {\n\t\t\t\t\t\tgoto fail_range;\n\t\t\t\t\t}\n\t\t\t\t\tgen_range(userdata, start, ch, 0);\n\t\t\t\t\tstart = -1;\n\t\t\t\t\tdash = 0;\n\t\t\t\t} else {\n\t\t\t\t\tgen_range(userdata, start, start, 0);\n\t\t\t\t\tstart = ch;\n\t\t\t\t\t/* dash is already 0 */\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstart = ch;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn;\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_range:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_RANGE);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterm_charclass:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_CHARCLASS);\n\tDUK_WO_NORETURN(return;);\n}\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n/* automatic undefs */\n#undef DUK__ADVANCEBYTES\n#undef DUK__ADVANCECHARS\n#undef DUK__ADVTOK\n#undef DUK__APPENDBUFFER\n#undef DUK__APPENDBUFFER_ASCII\n#undef DUK__INITBUFFER\n#undef DUK__ISDIGIT\n#undef DUK__ISDIGIT03\n#undef DUK__ISDIGIT47\n#undef DUK__ISHEXDIGIT\n#undef DUK__ISOCTDIGIT\n#undef DUK__L0\n#undef DUK__L1\n#undef DUK__L2\n#undef DUK__L3\n#undef DUK__L4\n#undef DUK__L5\n#undef DUK__LOOKUP\n#undef DUK__MAX_RE_DECESC_DIGITS\n#undef DUK__MAX_RE_QUANT_DIGITS\n#line 1 \"duk_numconv.c\"\n/*\n *  Number-to-string and string-to-number conversions.\n *\n *  Slow path number-to-string and string-to-number conversion is based on\n *  a Dragon4 variant, with fast paths for small integers.  Big integer\n *  arithmetic is needed for guaranteeing that the conversion is correct\n *  and uses a minimum number of digits.  The big number arithmetic has a\n *  fixed maximum size and does not require dynamic allocations.\n *\n *  See: doc/number-conversion.rst.\n */\n\n/* #include duk_internal.h -> already included */\n\n#define DUK__IEEE_DOUBLE_EXP_BIAS  1023\n#define DUK__IEEE_DOUBLE_EXP_MIN   (-1022)   /* biased exp == 0 -> denormal, exp -1022 */\n\n#define DUK__DIGITCHAR(x)  duk_lc_digits[(x)]\n\n/*\n *  Tables generated with util/gennumdigits.py.\n *\n *  duk__str2num_digits_for_radix indicates, for each radix, how many input\n *  digits should be considered significant for string-to-number conversion.\n *  The input is also padded to this many digits to give the Dragon4\n *  conversion enough (apparent) precision to work with.\n *\n *  duk__str2num_exp_limits indicates, for each radix, the radix-specific\n *  minimum/maximum exponent values (for a Dragon4 integer mantissa)\n *  below and above which the number is guaranteed to underflow to zero\n *  or overflow to Infinity.  This allows parsing to keep bigint values\n *  bounded.\n */\n\nDUK_LOCAL const duk_uint8_t duk__str2num_digits_for_radix[] = {\n\t69, 44, 35, 30, 27, 25, 23, 22, 20, 20,    /* 2 to 11 */\n\t20, 19, 19, 18, 18, 17, 17, 17, 16, 16,    /* 12 to 21 */\n\t16, 16, 16, 15, 15, 15, 15, 15, 15, 14,    /* 22 to 31 */\n\t14, 14, 14, 14, 14                         /* 31 to 36 */\n};\n\ntypedef struct {\n\tduk_int16_t upper;\n\tduk_int16_t lower;\n} duk__exp_limits;\n\nDUK_LOCAL const duk__exp_limits duk__str2num_exp_limits[] = {\n\t{ 957, -1147 }, { 605, -725 },  { 479, -575 },  { 414, -496 },\n\t{ 372, -446 },  { 342, -411 },  { 321, -384 },  { 304, -364 },\n\t{ 291, -346 },  { 279, -334 },  { 268, -323 },  { 260, -312 },\n\t{ 252, -304 },  { 247, -296 },  { 240, -289 },  { 236, -283 },\n\t{ 231, -278 },  { 227, -273 },  { 223, -267 },  { 220, -263 },\n\t{ 216, -260 },  { 213, -256 },  { 210, -253 },  { 208, -249 },\n\t{ 205, -246 },  { 203, -244 },  { 201, -241 },  { 198, -239 },\n\t{ 196, -237 },  { 195, -234 },  { 193, -232 },  { 191, -230 },\n\t{ 190, -228 },  { 188, -226 },  { 187, -225 },\n};\n\n/*\n *  Limited functionality bigint implementation.\n *\n *  Restricted to non-negative numbers with less than 32 * DUK__BI_MAX_PARTS bits,\n *  with the caller responsible for ensuring this is never exceeded.  No memory\n *  allocation (except stack) is needed for bigint computation.  Operations\n *  have been tailored for number conversion needs.\n *\n *  Argument order is \"assignment order\", i.e. target first, then arguments:\n *  x <- y * z  -->  duk__bi_mul(x, y, z);\n */\n\n/* This upper value has been experimentally determined; debug build will check\n * bigint size with assertions.\n */\n#define DUK__BI_MAX_PARTS  37  /* 37x32 = 1184 bits */\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK__BI_PRINT(name,x)  duk__bi_print((name),(x))\n#else\n#define DUK__BI_PRINT(name,x)\n#endif\n\n/* Current size is about 152 bytes. */\ntypedef struct {\n\tduk_small_int_t n;\n\tduk_uint32_t v[DUK__BI_MAX_PARTS];  /* low to high */\n} duk__bigint;\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\nDUK_LOCAL void duk__bi_print(const char *name, duk__bigint *x) {\n\t/* Overestimate required size; debug code so not critical to be tight. */\n\tchar buf[DUK__BI_MAX_PARTS * 9 + 64];\n\tchar *p = buf;\n\tduk_small_int_t i;\n\n\t/* No NUL term checks in this debug code. */\n\tp += DUK_SPRINTF(p, \"%p n=%ld\", (void *) x, (long) x->n);\n\tif (x->n == 0) {\n\t\tp += DUK_SPRINTF(p, \" 0\");\n\t}\n\tfor (i = x->n - 1; i >= 0; i--) {\n\t\tp += DUK_SPRINTF(p, \" %08lx\", (unsigned long) x->v[i]);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"%s: %s\", (const char *) name, (const char *) buf));\n}\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_LOCAL duk_small_int_t duk__bi_is_valid(duk__bigint *x) {\n\treturn (duk_small_int_t)\n\t       ( ((x->n >= 0) && (x->n <= DUK__BI_MAX_PARTS)) /* is valid size */ &&\n\t         ((x->n == 0) || (x->v[x->n - 1] != 0)) /* is normalized */ );\n}\n#endif\n\nDUK_LOCAL void duk__bi_normalize(duk__bigint *x) {\n\tduk_small_int_t i;\n\n\tfor (i = x->n - 1; i >= 0; i--) {\n\t\tif (x->v[i] != 0) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* Note: if 'x' is zero, x->n becomes 0 here */\n\tx->n = i + 1;\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* x <- y */\nDUK_LOCAL void duk__bi_copy(duk__bigint *x, duk__bigint *y) {\n\tduk_small_int_t n;\n\n\tn = y->n;\n\tx->n = n;\n\t/* No need to special case n == 0. */\n\tduk_memcpy((void *) x->v, (const void *) y->v, (size_t) (sizeof(duk_uint32_t) * (size_t) n));\n}\n\nDUK_LOCAL void duk__bi_set_small(duk__bigint *x, duk_uint32_t v) {\n\tif (v == 0U) {\n\t\tx->n = 0;\n\t} else {\n\t\tx->n = 1;\n\t\tx->v[0] = v;\n\t}\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* Return value: <0  <=>  x < y\n *                0  <=>  x == y\n *               >0  <=>  x > y\n */\nDUK_LOCAL int duk__bi_compare(duk__bigint *x, duk__bigint *y) {\n\tduk_small_int_t i, nx, ny;\n\tduk_uint32_t tx, ty;\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\tnx = x->n;\n\tny = y->n;\n\tif (nx > ny) {\n\t\tgoto ret_gt;\n\t}\n\tif (nx < ny) {\n\t\tgoto ret_lt;\n\t}\n\tfor (i = nx - 1; i >= 0; i--) {\n\t\ttx = x->v[i];\n\t\tty = y->v[i];\n\n\t\tif (tx > ty) {\n\t\t\tgoto ret_gt;\n\t\t}\n\t\tif (tx < ty) {\n\t\t\tgoto ret_lt;\n\t\t}\n\t}\n\n\treturn 0;\n\n ret_gt:\n\treturn 1;\n\n ret_lt:\n\treturn -1;\n}\n\n/* x <- y + z */\n#if defined(DUK_USE_64BIT_OPS)\nDUK_LOCAL void duk__bi_add(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_uint64_t tmp;\n\tduk_small_int_t i, ny, nz;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\n\tif (z->n > y->n) {\n\t\tduk__bigint *t;\n\t\tt = y; y = z; z = t;\n\t}\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\ttmp = 0U;\n\tfor (i = 0; i < ny; i++) {\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\ttmp += y->v[i];\n\t\tif (i < nz) {\n\t\t\ttmp += z->v[i];\n\t\t}\n\t\tx->v[i] = (duk_uint32_t) (tmp & 0xffffffffUL);\n\t\ttmp = tmp >> 32;\n\t}\n\tif (tmp != 0U) {\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\tx->v[i++] = (duk_uint32_t) tmp;\n\t}\n\tx->n = i;\n\tDUK_ASSERT(x->n <= DUK__BI_MAX_PARTS);\n\n\t/* no need to normalize */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#else  /* DUK_USE_64BIT_OPS */\nDUK_LOCAL void duk__bi_add(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_uint32_t carry, tmp1, tmp2;\n\tduk_small_int_t i, ny, nz;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\n\tif (z->n > y->n) {\n\t\tduk__bigint *t;\n\t\tt = y; y = z; z = t;\n\t}\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\tcarry = 0U;\n\tfor (i = 0; i < ny; i++) {\n\t\t/* Carry is detected based on wrapping which relies on exact 32-bit\n\t\t * types.\n\t\t */\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\ttmp1 = y->v[i];\n\t\ttmp2 = tmp1;\n\t\tif (i < nz) {\n\t\t\ttmp2 += z->v[i];\n\t\t}\n\n\t\t/* Careful with carry condition:\n\t\t *  - If carry not added: 0x12345678 + 0 + 0xffffffff = 0x12345677 (< 0x12345678)\n\t\t *  - If carry added:     0x12345678 + 1 + 0xffffffff = 0x12345678 (== 0x12345678)\n\t\t */\n\t\tif (carry) {\n\t\t\ttmp2++;\n\t\t\tcarry = (tmp2 <= tmp1 ? 1U : 0U);\n\t\t} else {\n\t\t\tcarry = (tmp2 < tmp1 ? 1U : 0U);\n\t\t}\n\n\t\tx->v[i] = tmp2;\n\t}\n\tif (carry) {\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\tDUK_ASSERT(carry == 1U);\n\t\tx->v[i++] = carry;\n\t}\n\tx->n = i;\n\tDUK_ASSERT(x->n <= DUK__BI_MAX_PARTS);\n\n\t/* no need to normalize */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#endif  /* DUK_USE_64BIT_OPS */\n\n/* x <- y + z */\nDUK_LOCAL void duk__bi_add_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) {\n\tduk__bigint tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\t/* XXX: this could be optimized; there is only one call site now though */\n\tduk__bi_set_small(&tmp, z);\n\tduk__bi_add(x, y, &tmp);\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n#if 0  /* unused */\n/* x <- x + y, use t as temp */\nDUK_LOCAL void duk__bi_add_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) {\n\tduk__bi_add(t, x, y);\n\tduk__bi_copy(x, t);\n}\n#endif\n\n/* x <- y - z, require x >= y => z >= 0, i.e. y >= z */\n#if defined(DUK_USE_64BIT_OPS)\nDUK_LOCAL void duk__bi_sub(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_small_int_t i, ny, nz;\n\tduk_uint32_t ty, tz;\n\tduk_int64_t tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\tDUK_ASSERT(duk__bi_compare(y, z) >= 0);\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\ttmp = 0;\n\tfor (i = 0; i < ny; i++) {\n\t\tty = y->v[i];\n\t\tif (i < nz) {\n\t\t\ttz = z->v[i];\n\t\t} else {\n\t\t\ttz = 0;\n\t\t}\n\t\ttmp = (duk_int64_t) ty - (duk_int64_t) tz + tmp;\n\t\tx->v[i] = (duk_uint32_t) ((duk_uint64_t) tmp & 0xffffffffUL);\n\t\ttmp = tmp >> 32;  /* 0 or -1 */\n\t}\n\tDUK_ASSERT(tmp == 0);\n\n\tx->n = i;\n\tduk__bi_normalize(x);  /* need to normalize, may even cancel to 0 */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#else\nDUK_LOCAL void duk__bi_sub(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_small_int_t i, ny, nz;\n\tduk_uint32_t tmp1, tmp2, borrow;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\tDUK_ASSERT(duk__bi_compare(y, z) >= 0);\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\tborrow = 0U;\n\tfor (i = 0; i < ny; i++) {\n\t\t/* Borrow is detected based on wrapping which relies on exact 32-bit\n\t\t * types.\n\t\t */\n\t\ttmp1 = y->v[i];\n\t\ttmp2 = tmp1;\n\t\tif (i < nz) {\n\t\t\ttmp2 -= z->v[i];\n\t\t}\n\n\t\t/* Careful with borrow condition:\n\t\t *  - If borrow not subtracted: 0x12345678 - 0 - 0xffffffff = 0x12345679 (> 0x12345678)\n\t\t *  - If borrow subtracted:     0x12345678 - 1 - 0xffffffff = 0x12345678 (== 0x12345678)\n\t\t */\n\t\tif (borrow) {\n\t\t\ttmp2--;\n\t\t\tborrow = (tmp2 >= tmp1 ? 1U : 0U);\n\t\t} else {\n\t\t\tborrow = (tmp2 > tmp1 ? 1U : 0U);\n\t\t}\n\n\t\tx->v[i] = tmp2;\n\t}\n\tDUK_ASSERT(borrow == 0U);\n\n\tx->n = i;\n\tduk__bi_normalize(x);  /* need to normalize, may even cancel to 0 */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#endif\n\n#if 0  /* unused */\n/* x <- y - z */\nDUK_LOCAL void duk__bi_sub_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) {\n\tduk__bigint tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\t/* XXX: this could be optimized */\n\tduk__bi_set_small(&tmp, z);\n\tduk__bi_sub(x, y, &tmp);\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#endif\n\n/* x <- x - y, use t as temp */\nDUK_LOCAL void duk__bi_sub_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) {\n\tduk__bi_sub(t, x, y);\n\tduk__bi_copy(x, t);\n}\n\n/* x <- y * z */\nDUK_LOCAL void duk__bi_mul(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_small_int_t i, j, nx, nz;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\n\tnx = y->n + z->n;  /* max possible */\n\tDUK_ASSERT(nx <= DUK__BI_MAX_PARTS);\n\n\tif (nx == 0) {\n\t\t/* Both inputs are zero; cases where only one is zero can go\n\t\t * through main algorithm.\n\t\t */\n\t\tx->n = 0;\n\t\treturn;\n\t}\n\n\tduk_memzero((void *) x->v, (size_t) (sizeof(duk_uint32_t) * (size_t) nx));\n\tx->n = nx;\n\n\tnz = z->n;\n\tfor (i = 0; i < y->n; i++) {\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_uint64_t tmp = 0U;\n\t\tfor (j = 0; j < nz; j++) {\n\t\t\ttmp += (duk_uint64_t) y->v[i] * (duk_uint64_t) z->v[j] + x->v[i+j];\n\t\t\tx->v[i+j] = (duk_uint32_t) (tmp & 0xffffffffUL);\n\t\t\ttmp = tmp >> 32;\n\t\t}\n\t\tif (tmp > 0) {\n\t\t\tDUK_ASSERT(i + j < nx);\n\t\t\tDUK_ASSERT(i + j < DUK__BI_MAX_PARTS);\n\t\t\tDUK_ASSERT(x->v[i+j] == 0U);\n\t\t\tx->v[i+j] = (duk_uint32_t) tmp;\n\t\t}\n#else\n\t\t/*\n\t\t *  Multiply + add + carry for 32-bit components using only 16x16->32\n\t\t *  multiplies and carry detection based on unsigned overflow.\n\t\t *\n\t\t *    1st mult, 32-bit: (A*2^16 + B)\n\t\t *    2nd mult, 32-bit: (C*2^16 + D)\n\t\t *    3rd add, 32-bit: E\n\t\t *    4th add, 32-bit: F\n\t\t *\n\t\t *      (AC*2^16 + B) * (C*2^16 + D) + E + F\n\t\t *    = AC*2^32 + AD*2^16 + BC*2^16 + BD + E + F\n\t\t *    = AC*2^32 + (AD + BC)*2^16 + (BD + E + F)\n\t\t *    = AC*2^32 + AD*2^16 + BC*2^16 + (BD + E + F)\n\t\t */\n\t\tduk_uint32_t a, b, c, d, e, f;\n\t\tduk_uint32_t r, s, t;\n\n\t\ta = y->v[i]; b = a & 0xffffUL; a = a >> 16;\n\n\t\tf = 0;\n\t\tfor (j = 0; j < nz; j++) {\n\t\t\tc = z->v[j]; d = c & 0xffffUL; c = c >> 16;\n\t\t\te = x->v[i+j];\n\n\t\t\t/* build result as: (r << 32) + s: start with (BD + E + F) */\n\t\t\tr = 0;\n\t\t\ts = b * d;\n\n\t\t\t/* add E */\n\t\t\tt = s + e;\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add F */\n\t\t\tt = s + f;\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add BC*2^16 */\n\t\t\tt = b * c;\n\t\t\tr += (t >> 16);\n\t\t\tt = s + ((t & 0xffffUL) << 16);\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add AD*2^16 */\n\t\t\tt = a * d;\n\t\t\tr += (t >> 16);\n\t\t\tt = s + ((t & 0xffffUL) << 16);\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add AC*2^32 */\n\t\t\tt = a * c;\n\t\t\tr += t;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"ab=%08lx cd=%08lx ef=%08lx -> rs=%08lx %08lx\",\n\t\t\t                     (unsigned long) y->v[i], (unsigned long) z->v[j],\n\t\t\t                     (unsigned long) x->v[i+j], (unsigned long) r,\n\t\t\t                     (unsigned long) s));\n\n\t\t\tx->v[i+j] = s;\n\t\t\tf = r;\n\t\t}\n\t\tif (f > 0U) {\n\t\t\tDUK_ASSERT(i + j < nx);\n\t\t\tDUK_ASSERT(i + j < DUK__BI_MAX_PARTS);\n\t\t\tDUK_ASSERT(x->v[i+j] == 0U);\n\t\t\tx->v[i+j] = (duk_uint32_t) f;\n\t\t}\n#endif  /* DUK_USE_64BIT_OPS */\n\t}\n\n\tduk__bi_normalize(x);\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* x <- y * z */\nDUK_LOCAL void duk__bi_mul_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) {\n\tduk__bigint tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\t/* XXX: this could be optimized */\n\tduk__bi_set_small(&tmp, z);\n\tduk__bi_mul(x, y, &tmp);\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* x <- x * y, use t as temp */\nDUK_LOCAL void duk__bi_mul_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) {\n\tduk__bi_mul(t, x, y);\n\tduk__bi_copy(x, t);\n}\n\n/* x <- x * y, use t as temp */\nDUK_LOCAL void duk__bi_mul_small_copy(duk__bigint *x, duk_uint32_t y, duk__bigint *t) {\n\tduk__bi_mul_small(t, x, y);\n\tduk__bi_copy(x, t);\n}\n\nDUK_LOCAL int duk__bi_is_even(duk__bigint *x) {\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\treturn (x->n == 0) || ((x->v[0] & 0x01) == 0);\n}\n\nDUK_LOCAL int duk__bi_is_zero(duk__bigint *x) {\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\treturn (x->n == 0);  /* this is the case for normalized numbers */\n}\n\n/* Bigint is 2^52.  Used to detect normalized IEEE double mantissa values\n * which are at the lowest edge (next floating point value downwards has\n * a different exponent).  The lowest mantissa has the form:\n *\n *     1000........000    (52 zeroes; only \"hidden bit\" is set)\n */\nDUK_LOCAL duk_small_int_t duk__bi_is_2to52(duk__bigint *x) {\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\treturn (duk_small_int_t)\n\t        (x->n == 2) && (x->v[0] == 0U) && (x->v[1] == (1U << (52-32)));\n}\n\n/* x <- (1<<y) */\nDUK_LOCAL void duk__bi_twoexp(duk__bigint *x, duk_small_int_t y) {\n\tduk_small_int_t n, r;\n\n\tn = (y / 32) + 1;\n\tDUK_ASSERT(n > 0);\n\tr = y % 32;\n\tduk_memzero((void *) x->v, sizeof(duk_uint32_t) * (size_t) n);\n\tx->n = n;\n\tx->v[n - 1] = (((duk_uint32_t) 1) << r);\n}\n\n/* x <- b^y; use t1 and t2 as temps */\nDUK_LOCAL void duk__bi_exp_small(duk__bigint *x, duk_small_int_t b, duk_small_int_t y, duk__bigint *t1, duk__bigint *t2) {\n\t/* Fast path the binary case */\n\n\tDUK_ASSERT(x != t1 && x != t2 && t1 != t2);  /* distinct bignums, easy mistake to make */\n\tDUK_ASSERT(b >= 0);\n\tDUK_ASSERT(y >= 0);\n\n\tif (b == 2) {\n\t\tduk__bi_twoexp(x, y);\n\t\treturn;\n\t}\n\n\t/* http://en.wikipedia.org/wiki/Exponentiation_by_squaring */\n\n\tDUK_DDD(DUK_DDDPRINT(\"exp_small: b=%ld, y=%ld\", (long) b, (long) y));\n\n\tduk__bi_set_small(x, 1);\n\tduk__bi_set_small(t1, (duk_uint32_t) b);\n\tfor (;;) {\n\t\t/* Loop structure ensures that we don't compute t1^2 unnecessarily\n\t\t * on the final round, as that might create a bignum exceeding the\n\t\t * current DUK__BI_MAX_PARTS limit.\n\t\t */\n\t\tif (y & 0x01) {\n\t\t\tduk__bi_mul_copy(x, t1, t2);\n\t\t}\n\t\ty = y >> 1;\n\t\tif (y == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tduk__bi_mul_copy(t1, t1, t2);\n\t}\n\n\tDUK__BI_PRINT(\"exp_small result\", x);\n}\n\n/*\n *  A Dragon4 number-to-string variant, based on:\n *\n *    Guy L. Steele Jr., Jon L. White: \"How to Print Floating-Point Numbers\n *    Accurately\"\n *\n *    Robert G. Burger, R. Kent Dybvig: \"Printing Floating-Point Numbers\n *    Quickly and Accurately\"\n *\n *  The current algorithm is based on Figure 1 of the Burger-Dybvig paper,\n *  i.e. the base implementation without logarithm estimation speedups\n *  (these would increase code footprint considerably).  Fixed-format output\n *  does not follow the suggestions in the paper; instead, we generate an\n *  extra digit and round-with-carry.\n *\n *  The same algorithm is used for number parsing (with b=10 and B=2)\n *  by generating one extra digit and doing rounding manually.\n *\n *  See doc/number-conversion.rst for limitations.\n */\n\n/* Maximum number of digits generated. */\n#define DUK__MAX_OUTPUT_DIGITS          1040  /* (Number.MAX_VALUE).toString(2).length == 1024, + slack */\n\n/* Maximum number of characters in formatted value. */\n#define DUK__MAX_FORMATTED_LENGTH       1040  /* (-Number.MAX_VALUE).toString(2).length == 1025, + slack */\n\n/* Number and (minimum) size of bigints in the nc_ctx structure. */\n#define DUK__NUMCONV_CTX_NUM_BIGINTS    7\n#define DUK__NUMCONV_CTX_BIGINTS_SIZE   (sizeof(duk__bigint) * DUK__NUMCONV_CTX_NUM_BIGINTS)\n\ntypedef struct {\n\t/* Currently about 7*152 = 1064 bytes.  The space for these\n\t * duk__bigints is used also as a temporary buffer for generating\n\t * the final string.  This is a bit awkard; a union would be\n\t * more correct.\n\t */\n\tduk__bigint f, r, s, mp, mm, t1, t2;\n\n\tduk_small_int_t is_s2n;        /* if 1, doing a string-to-number; else doing a number-to-string */\n\tduk_small_int_t is_fixed;      /* if 1, doing a fixed format output (not free format) */\n\tduk_small_int_t req_digits;    /* requested number of output digits; 0 = free-format */\n\tduk_small_int_t abs_pos;       /* digit position is absolute, not relative */\n\tduk_small_int_t e;             /* exponent for 'f' */\n\tduk_small_int_t b;             /* input radix */\n\tduk_small_int_t B;             /* output radix */\n\tduk_small_int_t k;             /* see algorithm */\n\tduk_small_int_t low_ok;        /* see algorithm */\n\tduk_small_int_t high_ok;       /* see algorithm */\n\tduk_small_int_t unequal_gaps;  /* m+ != m- (very rarely) */\n\n\t/* Buffer used for generated digits, values are in the range [0,B-1]. */\n\tduk_uint8_t digits[DUK__MAX_OUTPUT_DIGITS];\n\tduk_small_int_t count;  /* digit count */\n} duk__numconv_stringify_ctx;\n\n/* Note: computes with 'idx' in assertions, so caller beware.\n * 'idx' is preincremented, i.e. '1' on first call, because it\n * is more convenient for the caller.\n */\n#define DUK__DRAGON4_OUTPUT_PREINC(nc_ctx,preinc_idx,x)  do { \\\n\t\tDUK_ASSERT((preinc_idx) - 1 >= 0); \\\n\t\tDUK_ASSERT((preinc_idx) - 1 < DUK__MAX_OUTPUT_DIGITS); \\\n\t\t((nc_ctx)->digits[(preinc_idx) - 1]) = (duk_uint8_t) (x); \\\n\t} while (0)\n\nDUK_LOCAL duk_size_t duk__dragon4_format_uint32(duk_uint8_t *buf, duk_uint32_t x, duk_small_int_t radix) {\n\tduk_uint8_t *p;\n\tduk_size_t len;\n\tduk_small_int_t dig;\n\tduk_uint32_t t;\n\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(radix >= 2 && radix <= 36);\n\n\t/* A 32-bit unsigned integer formats to at most 32 digits (the\n\t * worst case happens with radix == 2).  Output the digits backwards,\n\t * and use a memmove() to get them in the right place.\n\t */\n\n\tp = buf + 32;\n\tfor (;;) {\n\t\tt = x / (duk_uint32_t) radix;\n\t\tdig = (duk_small_int_t) (x - t * (duk_uint32_t) radix);\n\t\tx = t;\n\n\t\tDUK_ASSERT(dig >= 0 && dig < 36);\n\t\t*(--p) = DUK__DIGITCHAR(dig);\n\n\t\tif (x == 0) {\n\t\t\tbreak;\n\t\t}\n\t}\n\tlen = (duk_size_t) ((buf + 32) - p);\n\n\tduk_memmove((void *) buf, (const void *) p, (size_t) len);\n\n\treturn len;\n}\n\nDUK_LOCAL void duk__dragon4_prepare(duk__numconv_stringify_ctx *nc_ctx) {\n\tduk_small_int_t lowest_mantissa;\n\n#if 1\n\t/* Assume IEEE round-to-even, so that shorter encoding can be used\n\t * when round-to-even would produce correct result.  By removing\n\t * this check (and having low_ok == high_ok == 0) the results would\n\t * still be accurate but in some cases longer than necessary.\n\t */\n\tif (duk__bi_is_even(&nc_ctx->f)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"f is even\"));\n\t\tnc_ctx->low_ok = 1;\n\t\tnc_ctx->high_ok = 1;\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"f is odd\"));\n\t\tnc_ctx->low_ok = 0;\n\t\tnc_ctx->high_ok = 0;\n\t}\n#else\n\t/* Note: not honoring round-to-even should work but now generates incorrect\n\t * results.  For instance, 1e23 serializes to \"a000...\", i.e. the first digit\n\t * equals the radix (10).  Scaling stops one step too early in this case.\n\t * Don't know why this is the case, but since this code path is unused, it\n\t * doesn't matter.\n\t */\n\tnc_ctx->low_ok = 0;\n\tnc_ctx->high_ok = 0;\n#endif\n\n\t/* For string-to-number, pretend we never have the lowest mantissa as there\n\t * is no natural \"precision\" for inputs.  Having lowest_mantissa == 0, we'll\n\t * fall into the base cases for both e >= 0 and e < 0.\n\t */\n\tif (nc_ctx->is_s2n) {\n\t\tlowest_mantissa = 0;\n\t} else {\n\t\tlowest_mantissa = duk__bi_is_2to52(&nc_ctx->f);\n\t}\n\n\tnc_ctx->unequal_gaps = 0;\n\tif (nc_ctx->e >= 0) {\n\t\t/* exponent non-negative (and thus not minimum exponent) */\n\n\t\tif (lowest_mantissa) {\n\t\t\t/* (>= e 0) AND (= f (expt b (- p 1)))\n\t\t\t *\n\t\t\t * be <- (expt b e) == b^e\n\t\t\t * be1 <- (* be b) == (expt b (+ e 1)) == b^(e+1)\n\t\t\t * r <- (* f be1 2) == 2 * f * b^(e+1)    [if b==2 -> f * b^(e+2)]\n\t\t\t * s <- (* b 2)                           [if b==2 -> 4]\n\t\t\t * m+ <- be1 == b^(e+1)\n\t\t\t * m- <- be == b^e\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-negative exponent (not smallest exponent); \"\n\t\t\t                     \"lowest mantissa value for this exponent -> \"\n\t\t\t                     \"unequal gaps\"));\n\n\t\t\tduk__bi_exp_small(&nc_ctx->mm, nc_ctx->b, nc_ctx->e, &nc_ctx->t1, &nc_ctx->t2);  /* mm <- b^e */\n\t\t\tduk__bi_mul_small(&nc_ctx->mp, &nc_ctx->mm, (duk_uint32_t) nc_ctx->b);           /* mp <- b^(e+1) */\n\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, 2);\n\t\t\tduk__bi_mul(&nc_ctx->r, &nc_ctx->t1, &nc_ctx->mp);              /* r <- (2 * f) * b^(e+1) */\n\t\t\tduk__bi_set_small(&nc_ctx->s, (duk_uint32_t) (nc_ctx->b * 2));  /* s <- 2 * b */\n\t\t\tnc_ctx->unequal_gaps = 1;\n\t\t} else {\n\t\t\t/* (>= e 0) AND (not (= f (expt b (- p 1))))\n\t\t\t *\n\t\t\t * be <- (expt b e) == b^e\n\t\t\t * r <- (* f be 2) == 2 * f * b^e    [if b==2 -> f * b^(e+1)]\n\t\t\t * s <- 2\n\t\t\t * m+ <- be == b^e\n\t\t\t * m- <- be == b^e\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-negative exponent (not smallest exponent); \"\n\t\t\t                     \"not lowest mantissa for this exponent -> \"\n\t\t\t                     \"equal gaps\"));\n\n\t\t\tduk__bi_exp_small(&nc_ctx->mm, nc_ctx->b, nc_ctx->e, &nc_ctx->t1, &nc_ctx->t2);  /* mm <- b^e */\n\t\t\tduk__bi_copy(&nc_ctx->mp, &nc_ctx->mm);                /* mp <- b^e */\n\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, 2);\n\t\t\tduk__bi_mul(&nc_ctx->r, &nc_ctx->t1, &nc_ctx->mp);     /* r <- (2 * f) * b^e */\n\t\t\tduk__bi_set_small(&nc_ctx->s, 2);                      /* s <- 2 */\n\t\t}\n\t} else {\n\t\t/* When doing string-to-number, lowest_mantissa is always 0 so\n\t\t * the exponent check, while incorrect, won't matter.\n\t\t */\n\t\tif (nc_ctx->e > DUK__IEEE_DOUBLE_EXP_MIN /*not minimum exponent*/ &&\n\t\t    lowest_mantissa /* lowest mantissa for this exponent*/) {\n\t\t\t/* r <- (* f b 2)                                [if b==2 -> (* f 4)]\n\t\t\t * s <- (* (expt b (- 1 e)) 2) == b^(1-e) * 2    [if b==2 -> b^(2-e)]\n\t\t\t * m+ <- b == 2\n\t\t\t * m- <- 1\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"negative exponent; not minimum exponent and \"\n\t\t\t                     \"lowest mantissa for this exponent -> \"\n\t\t\t                     \"unequal gaps\"));\n\n\t\t\tduk__bi_mul_small(&nc_ctx->r, &nc_ctx->f, (duk_uint32_t) (nc_ctx->b * 2));  /* r <- (2 * b) * f */\n\t\t\tduk__bi_exp_small(&nc_ctx->t1, nc_ctx->b, 1 - nc_ctx->e, &nc_ctx->s, &nc_ctx->t2);  /* NB: use 's' as temp on purpose */\n\t\t\tduk__bi_mul_small(&nc_ctx->s, &nc_ctx->t1, 2);             /* s <- b^(1-e) * 2 */\n\t\t\tduk__bi_set_small(&nc_ctx->mp, 2);\n\t\t\tduk__bi_set_small(&nc_ctx->mm, 1);\n\t\t\tnc_ctx->unequal_gaps = 1;\n\t\t} else {\n\t\t\t/* r <- (* f 2)\n\t\t\t * s <- (* (expt b (- e)) 2) == b^(-e) * 2    [if b==2 -> b^(1-e)]\n\t\t\t * m+ <- 1\n\t\t\t * m- <- 1\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"negative exponent; minimum exponent or not \"\n\t\t\t                     \"lowest mantissa for this exponent -> \"\n\t\t\t                     \"equal gaps\"));\n\n\t\t\tduk__bi_mul_small(&nc_ctx->r, &nc_ctx->f, 2);            /* r <- 2 * f */\n\t\t\tduk__bi_exp_small(&nc_ctx->t1, nc_ctx->b, -nc_ctx->e, &nc_ctx->s, &nc_ctx->t2);  /* NB: use 's' as temp on purpose */\n\t\t\tduk__bi_mul_small(&nc_ctx->s, &nc_ctx->t1, 2);           /* s <- b^(-e) * 2 */\n\t\t\tduk__bi_set_small(&nc_ctx->mp, 1);\n\t\t\tduk__bi_set_small(&nc_ctx->mm, 1);\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__dragon4_scale(duk__numconv_stringify_ctx *nc_ctx) {\n\tduk_small_int_t k = 0;\n\n\t/* This is essentially the 'scale' algorithm, with recursion removed.\n\t * Note that 'k' is either correct immediately, or will move in one\n\t * direction in the loop.  There's no need to do the low/high checks\n\t * on every round (like the Scheme algorithm does).\n\t *\n\t * The scheme algorithm finds 'k' and updates 's' simultaneously,\n\t * while the logical algorithm finds 'k' with 's' having its initial\n\t * value, after which 's' is updated separately (see the Burger-Dybvig\n\t * paper, Section 3.1, steps 2 and 3).\n\t *\n\t * The case where m+ == m- (almost always) is optimized for, because\n\t * it reduces the bigint operations considerably and almost always\n\t * applies.  The scale loop only needs to work with m+, so this works.\n\t */\n\n\t/* XXX: this algorithm could be optimized quite a lot by using e.g.\n\t * a logarithm based estimator for 'k' and performing B^n multiplication\n\t * using a lookup table or using some bit-representation based exp\n\t * algorithm.  Currently we just loop, with significant performance\n\t * impact for very large and very small numbers.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"scale: B=%ld, low_ok=%ld, high_ok=%ld\",\n\t                     (long) nc_ctx->B, (long) nc_ctx->low_ok, (long) nc_ctx->high_ok));\n\tDUK__BI_PRINT(\"r(init)\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s(init)\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp(init)\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm(init)\", &nc_ctx->mm);\n\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"scale loop (inc k), k=%ld\", (long) k));\n\t\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\t\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\t\tDUK__BI_PRINT(\"m+\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"m-\", &nc_ctx->mm);\n\n\t\tduk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp);  /* t1 = (+ r m+) */\n\t\tif (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) >= (nc_ctx->high_ok ? 0 : 1)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"k is too low\"));\n\t\t\t/* r <- r\n\t\t\t * s <- (* s B)\n\t\t\t * m+ <- m+\n\t\t\t * m- <- m-\n\t\t\t * k <- (+ k 1)\n\t\t\t */\n\n\t\t\tduk__bi_mul_small_copy(&nc_ctx->s, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\tk++;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* k > 0 -> k was too low, and cannot be too high */\n\tif (k > 0) {\n\t\tgoto skip_dec_k;\n\t}\n\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"scale loop (dec k), k=%ld\", (long) k));\n\t\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\t\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\t\tDUK__BI_PRINT(\"m+\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"m-\", &nc_ctx->mm);\n\n\t\tduk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp);  /* t1 = (+ r m+) */\n\t\tduk__bi_mul_small(&nc_ctx->t2, &nc_ctx->t1, (duk_uint32_t) nc_ctx->B);   /* t2 = (* (+ r m+) B) */\n\t\tif (duk__bi_compare(&nc_ctx->t2, &nc_ctx->s) <= (nc_ctx->high_ok ? -1 : 0)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"k is too high\"));\n\t\t\t/* r <- (* r B)\n\t\t\t * s <- s\n\t\t\t * m+ <- (* m+ B)\n\t\t\t * m- <- (* m- B)\n\t\t\t * k <- (- k 1)\n\t\t\t */\n\t\t\tduk__bi_mul_small_copy(&nc_ctx->r, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\tduk__bi_mul_small_copy(&nc_ctx->mp, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\tif (nc_ctx->unequal_gaps) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"m+ != m- -> need to update m- too\"));\n\t\t\t\tduk__bi_mul_small_copy(&nc_ctx->mm, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\t}\n\t\t\tk--;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n skip_dec_k:\n\n\tif (!nc_ctx->unequal_gaps) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"equal gaps, copy m- from m+\"));\n\t\tduk__bi_copy(&nc_ctx->mm, &nc_ctx->mp);  /* mm <- mp */\n\t}\n\tnc_ctx->k = k;\n\n\tDUK_DDD(DUK_DDDPRINT(\"final k: %ld\", (long) k));\n\tDUK__BI_PRINT(\"r(final)\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s(final)\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp(final)\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm(final)\", &nc_ctx->mm);\n}\n\nDUK_LOCAL void duk__dragon4_generate(duk__numconv_stringify_ctx *nc_ctx) {\n\tduk_small_int_t tc1, tc2;    /* terminating conditions */\n\tduk_small_int_t d;           /* current digit */\n\tduk_small_int_t count = 0;   /* digit count */\n\n\t/*\n\t *  Digit generation loop.\n\t *\n\t *  Different termination conditions:\n\t *\n\t *    1. Free format output.  Terminate when shortest accurate\n\t *       representation found.\n\t *\n\t *    2. Fixed format output, with specific number of digits.\n\t *       Ignore termination conditions, terminate when digits\n\t *       generated.  Caller requests an extra digit and rounds.\n\t *\n\t *    3. Fixed format output, with a specific absolute cut-off\n\t *       position (e.g. 10 digits after decimal point).  Note\n\t *       that we always generate at least one digit, even if\n\t *       the digit is below the cut-off point already.\n\t */\n\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"generate loop, count=%ld, k=%ld, B=%ld, low_ok=%ld, high_ok=%ld\",\n\t\t                     (long) count, (long) nc_ctx->k, (long) nc_ctx->B,\n\t\t                     (long) nc_ctx->low_ok, (long) nc_ctx->high_ok));\n\t\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\t\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\t\tDUK__BI_PRINT(\"m+\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"m-\", &nc_ctx->mm);\n\n\t\t/* (quotient-remainder (* r B) s) using a dummy subtraction loop */\n\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->r, (duk_uint32_t) nc_ctx->B);       /* t1 <- (* r B) */\n\t\td = 0;\n\t\tfor (;;) {\n\t\t\tif (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) < 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tduk__bi_sub_copy(&nc_ctx->t1, &nc_ctx->s, &nc_ctx->t2);  /* t1 <- t1 - s */\n\t\t\td++;\n\t\t}\n\t\tduk__bi_copy(&nc_ctx->r, &nc_ctx->t1);  /* r <- (remainder (* r B) s) */\n\t\t                                        /* d <- (quotient (* r B) s)   (in range 0...B-1) */\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> d(quot)=%ld\", (long) d));\n\t\tDUK__BI_PRINT(\"r(rem)\", &nc_ctx->r);\n\n\t\tduk__bi_mul_small_copy(&nc_ctx->mp, (duk_uint32_t) nc_ctx->B, &nc_ctx->t2); /* m+ <- (* m+ B) */\n\t\tduk__bi_mul_small_copy(&nc_ctx->mm, (duk_uint32_t) nc_ctx->B, &nc_ctx->t2); /* m- <- (* m- B) */\n\t\tDUK__BI_PRINT(\"mp(upd)\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"mm(upd)\", &nc_ctx->mm);\n\n\t\t/* Terminating conditions.  For fixed width output, we just ignore the\n\t\t * terminating conditions (and pretend that tc1 == tc2 == false).  The\n\t\t * the current shortcut for fixed-format output is to generate a few\n\t\t * extra digits and use rounding (with carry) to finish the output.\n\t\t */\n\n\t\tif (nc_ctx->is_fixed == 0) {\n\t\t\t/* free-form */\n\t\t\ttc1 = (duk__bi_compare(&nc_ctx->r, &nc_ctx->mm) <= (nc_ctx->low_ok ? 0 : -1));\n\n\t\t\tduk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp);  /* t1 <- (+ r m+) */\n\t\t\ttc2 = (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) >= (nc_ctx->high_ok ? 0 : 1));\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=%ld, tc2=%ld\", (long) tc1, (long) tc2));\n\t\t} else {\n\t\t\t/* fixed-format */\n\t\t\ttc1 = 0;\n\t\t\ttc2 = 0;\n\t\t}\n\n\t\t/* Count is incremented before DUK__DRAGON4_OUTPUT_PREINC() call\n\t\t * on purpose, which is taken into account by the macro.\n\t\t */\n\t\tcount++;\n\n\t\tif (tc1) {\n\t\t\tif (tc2) {\n\t\t\t\t/* tc1 = true, tc2 = true */\n\t\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->r, 2);\n\t\t\t\tif (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) < 0) {  /* (< (* r 2) s) */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=true, tc2=true, 2r > s: output d --> %ld (k=%ld)\",\n\t\t\t\t\t                     (long) d, (long) nc_ctx->k));\n\t\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=true, tc2=true, 2r <= s: output d+1 --> %ld (k=%ld)\",\n\t\t\t\t\t                     (long) (d + 1), (long) nc_ctx->k));\n\t\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d + 1);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t/* tc1 = true, tc2 = false */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=true, tc2=false: output d --> %ld (k=%ld)\",\n\t\t\t\t                     (long) d, (long) nc_ctx->k));\n\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (tc2) {\n\t\t\t\t/* tc1 = false, tc2 = true */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=false, tc2=true: output d+1 --> %ld (k=%ld)\",\n\t\t\t\t                     (long) (d + 1), (long) nc_ctx->k));\n\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d + 1);\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t/* tc1 = false, tc2 = false */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=false, tc2=false: output d --> %ld (k=%ld)\",\n\t\t\t\t                     (long) d, (long) nc_ctx->k));\n\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d);\n\n\t\t\t\t/* r <- r    (updated above: r <- (remainder (* r B) s)\n\t\t\t\t * s <- s\n\t\t\t\t * m+ <- m+  (updated above: m+ <- (* m+ B)\n\t\t\t\t * m- <- m-  (updated above: m- <- (* m- B)\n\t\t\t\t * B, low_ok, high_ok are fixed\n\t\t\t\t */\n\n\t\t\t\t/* fall through and continue for-loop */\n\t\t\t}\n\t\t}\n\n\t\t/* fixed-format termination conditions */\n\t\tif (nc_ctx->is_fixed) {\n\t\t\tif (nc_ctx->abs_pos) {\n\t\t\t\tint pos = nc_ctx->k - count + 1;  /* count is already incremented, take into account */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fixed format, absolute: abs pos=%ld, k=%ld, count=%ld, req=%ld\",\n\t\t\t\t                     (long) pos, (long) nc_ctx->k, (long) count, (long) nc_ctx->req_digits));\n\t\t\t\tif (pos <= nc_ctx->req_digits) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"digit position reached req_digits, end generate loop\"));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fixed format, relative: k=%ld, count=%ld, req=%ld\",\n\t\t\t\t                     (long) nc_ctx->k, (long) count, (long) nc_ctx->req_digits));\n\t\t\t\tif (count >= nc_ctx->req_digits) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"digit count reached req_digits, end generate loop\"));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}  /* for */\n\n\tnc_ctx->count = count;\n\n\tDUK_DDD(DUK_DDDPRINT(\"generate finished\"));\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t{\n\t\tduk_uint8_t buf[2048];\n\t\tduk_small_int_t i, t;\n\t\tduk_memzero(buf, sizeof(buf));\n\t\tfor (i = 0; i < nc_ctx->count; i++) {\n\t\t\tt = nc_ctx->digits[i];\n\t\t\tif (t < 0 || t > 36) {\n\t\t\t\tbuf[i] = (duk_uint8_t) '?';\n\t\t\t} else {\n\t\t\t\tbuf[i] = (duk_uint8_t) DUK__DIGITCHAR(t);\n\t\t\t}\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> generated digits; k=%ld, digits='%s'\",\n\t\t                     (long) nc_ctx->k, (const char *) buf));\n\t}\n#endif\n}\n\n/* Round up digits to a given position.  If position is out-of-bounds,\n * does nothing.  If carry propagates over the first digit, a '1' is\n * prepended to digits and 'k' will be updated.  Return value indicates\n * whether carry propagated over the first digit.\n *\n * Note that nc_ctx->count is NOT updated based on the rounding position\n * (it is updated only if carry overflows over the first digit and an\n * extra digit is prepended).\n */\nDUK_LOCAL duk_small_int_t duk__dragon4_fixed_format_round(duk__numconv_stringify_ctx *nc_ctx, duk_small_int_t round_idx) {\n\tduk_small_int_t t;\n\tduk_uint8_t *p;\n\tduk_uint8_t roundup_limit;\n\tduk_small_int_t ret = 0;\n\n\t/*\n\t *  round_idx points to the digit which is considered for rounding; the\n\t *  digit to its left is the final digit of the rounded value.  If round_idx\n\t *  is zero, rounding will be performed; the result will either be an empty\n\t *  rounded value or if carry happens a '1' digit is generated.\n\t */\n\n\tif (round_idx >= nc_ctx->count) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"round_idx out of bounds (%ld >= %ld (count)) -> no rounding\",\n\t\t                     (long) round_idx, (long) nc_ctx->count));\n\t\treturn 0;\n\t} else if (round_idx < 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"round_idx out of bounds (%ld < 0) -> no rounding\",\n\t\t                     (long) round_idx));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  Round-up limit.\n\t *\n\t *  For even values, divides evenly, e.g. 10 -> roundup_limit=5.\n\t *\n\t *  For odd values, rounds up, e.g. 3 -> roundup_limit=2.\n\t *  If radix is 3, 0/3 -> down, 1/3 -> down, 2/3 -> up.\n\t */\n\troundup_limit = (duk_uint8_t) ((nc_ctx->B + 1) / 2);\n\n\tp = &nc_ctx->digits[round_idx];\n\tif (*p >= roundup_limit) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"fixed-format rounding carry required\"));\n\t\t/* carry */\n\t\tfor (;;) {\n\t\t\t*p = 0;\n\t\t\tif (p == &nc_ctx->digits[0]) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"carry propagated to first digit -> special case handling\"));\n\t\t\t\tduk_memmove((void *) (&nc_ctx->digits[1]),\n\t\t\t\t            (const void *) (&nc_ctx->digits[0]),\n\t\t\t\t            (size_t) (sizeof(char) * (size_t) nc_ctx->count));\n\t\t\t\tnc_ctx->digits[0] = 1;  /* don't increase 'count' */\n\t\t\t\tnc_ctx->k++;  /* position of highest digit changed */\n\t\t\t\tnc_ctx->count++;  /* number of digits changed */\n\t\t\t\tret = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fixed-format rounding carry: B=%ld, roundup_limit=%ld, p=%p, digits=%p\",\n\t\t\t                     (long) nc_ctx->B, (long) roundup_limit, (void *) p, (void *) nc_ctx->digits));\n\t\t\tp--;\n\t\t\tt = *p;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"digit before carry: %ld\", (long) t));\n\t\t\tif (++t < nc_ctx->B) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rounding carry terminated\"));\n\t\t\t\t*p = (duk_uint8_t) t;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"wraps, carry to next digit\"));\n\t\t}\n\t}\n\n\treturn ret;\n}\n\n#define DUK__NO_EXP  (65536)  /* arbitrary marker, outside valid exp range */\n\nDUK_LOCAL void duk__dragon4_convert_and_push(duk__numconv_stringify_ctx *nc_ctx,\n                                             duk_hthread *thr,\n                                             duk_small_int_t radix,\n                                             duk_small_int_t digits,\n                                             duk_small_uint_t flags,\n                                             duk_small_int_t neg) {\n\tduk_small_int_t k;\n\tduk_small_int_t pos, pos_end;\n\tduk_small_int_t expt;\n\tduk_small_int_t dig;\n\tduk_uint8_t *q;\n\tduk_uint8_t *buf;\n\n\t/*\n\t *  The string conversion here incorporates all the necessary ECMAScript\n\t *  semantics without attempting to be generic.  nc_ctx->digits contains\n\t *  nc_ctx->count digits (>= 1), with the topmost digit's 'position'\n\t *  indicated by nc_ctx->k as follows:\n\t *\n\t *    digits=\"123\" count=3 k=0   -->   0.123\n\t *    digits=\"123\" count=3 k=1   -->   1.23\n\t *    digits=\"123\" count=3 k=5   -->   12300\n\t *    digits=\"123\" count=3 k=-1  -->   0.0123\n\t *\n\t *  Note that the identifier names used for format selection are different\n\t *  in Burger-Dybvig paper and ECMAScript specification (quite confusingly\n\t *  so, because e.g. 'k' has a totally different meaning in each).  See\n\t *  documentation for discussion.\n\t *\n\t *  ECMAScript doesn't specify any specific behavior for format selection\n\t *  (e.g. when to use exponent notation) for non-base-10 numbers.\n\t *\n\t *  The bigint space in the context is reused for string output, as there\n\t *  is more than enough space for that (>1kB at the moment), and we avoid\n\t *  allocating even more stack.\n\t */\n\n\tDUK_ASSERT(DUK__NUMCONV_CTX_BIGINTS_SIZE >= DUK__MAX_FORMATTED_LENGTH);\n\tDUK_ASSERT(nc_ctx->count >= 1);\n\n\tk = nc_ctx->k;\n\tbuf = (duk_uint8_t *) &nc_ctx->f;  /* XXX: union would be more correct */\n\tq = buf;\n\n\t/* Exponent handling: if exponent format is used, record exponent value and\n\t * fake k such that one leading digit is generated (e.g. digits=123 -> \"1.23\").\n\t *\n\t * toFixed() prevents exponent use; otherwise apply a set of criteria to\n\t * match the other API calls (toString(), toPrecision, etc).\n\t */\n\n\texpt = DUK__NO_EXP;\n\tif (!nc_ctx->abs_pos /* toFixed() */) {\n\t\tif ((flags & DUK_N2S_FLAG_FORCE_EXP) ||             /* exponential notation forced */\n\t\t    ((flags & DUK_N2S_FLAG_NO_ZERO_PAD) &&          /* fixed precision and zero padding would be required */\n\t             (k - digits >= 1)) ||                          /* (e.g. k=3, digits=2 -> \"12X\") */\n\t\t    ((k > 21 || k <= -6) && (radix == 10))) {       /* toString() conditions */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"use exponential notation: k=%ld -> expt=%ld\",\n\t\t\t                     (long) k, (long) (k - 1)));\n\t\t\texpt = k - 1;  /* e.g. 12.3 -> digits=\"123\" k=2 -> 1.23e1 */\n\t\t\tk = 1;  /* generate mantissa with a single leading whole number digit */\n\t\t}\n\t}\n\n\tif (neg) {\n\t\t*q++ = '-';\n\t}\n\n\t/* Start position (inclusive) and end position (exclusive) */\n\tpos = (k >= 1 ? k : 1);\n\tif (nc_ctx->is_fixed) {\n\t\tif (nc_ctx->abs_pos) {\n\t\t\t/* toFixed() */\n\t\t\tpos_end = -digits;\n\t\t} else {\n\t\t\tpos_end = k - digits;\n\t\t}\n\t} else {\n\t\tpos_end = k - nc_ctx->count;\n\t}\n\tif (pos_end > 0) {\n\t\tpos_end = 0;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"expt=%ld, k=%ld, count=%ld, pos=%ld, pos_end=%ld, is_fixed=%ld, \"\n\t                     \"digits=%ld, abs_pos=%ld\",\n\t                     (long) expt, (long) k, (long) nc_ctx->count, (long) pos, (long) pos_end,\n\t                     (long) nc_ctx->is_fixed, (long) digits, (long) nc_ctx->abs_pos));\n\n\t/* Digit generation */\n\twhile (pos > pos_end) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"digit generation: pos=%ld, pos_end=%ld\",\n\t\t                     (long) pos, (long) pos_end));\n\t\tif (pos == 0) {\n\t\t\t*q++ = (duk_uint8_t) '.';\n\t\t}\n\t\tif (pos > k) {\n\t\t\t*q++ = (duk_uint8_t) '0';\n\t\t} else if (pos <= k - nc_ctx->count) {\n\t\t\t*q++ = (duk_uint8_t) '0';\n\t\t} else {\n\t\t\tdig = nc_ctx->digits[k - pos];\n\t\t\tDUK_ASSERT(dig >= 0 && dig < nc_ctx->B);\n\t\t\t*q++ = (duk_uint8_t) DUK__DIGITCHAR(dig);\n\t\t}\n\n\t\tpos--;\n\t}\n\tDUK_ASSERT(pos <= 1);\n\n\t/* Exponent */\n\tif (expt != DUK__NO_EXP) {\n\t\t/*\n\t\t *  Exponent notation for non-base-10 numbers isn't specified in ECMAScript\n\t\t *  specification, as it never explicitly turns up: non-decimal numbers can\n\t\t *  only be formatted with Number.prototype.toString([radix]) and for that,\n\t\t *  behavior is not explicitly specified.\n\t\t *\n\t\t *  Logical choices include formatting the exponent as decimal (e.g. binary\n\t\t *  100000 as 1e+5) or in current radix (e.g. binary 100000 as 1e+101).\n\t\t *  The Dragon4 algorithm (in the original paper) prints the exponent value\n\t\t *  in the target radix B.  However, for radix values 15 and above, the\n\t\t *  exponent separator 'e' is no longer easily parseable.  Consider, for\n\t\t *  instance, the number \"1.faecee+1c\".\n\t\t */\n\n\t\tduk_size_t len;\n\t\tchar expt_sign;\n\n\t\t*q++ = 'e';\n\t\tif (expt >= 0) {\n\t\t\texpt_sign = '+';\n\t\t} else {\n\t\t\texpt_sign = '-';\n\t\t\texpt = -expt;\n\t\t}\n\t\t*q++ = (duk_uint8_t) expt_sign;\n\t\tlen = duk__dragon4_format_uint32(q, (duk_uint32_t) expt, radix);\n\t\tq += len;\n\t}\n\n\tduk_push_lstring(thr, (const char *) buf, (size_t) (q - buf));\n}\n\n/*\n *  Conversion helpers\n */\n\nDUK_LOCAL void duk__dragon4_double_to_ctx(duk__numconv_stringify_ctx *nc_ctx, duk_double_t x) {\n\tduk_double_union u;\n\tduk_uint32_t tmp;\n\tduk_small_int_t expt;\n\n\t/*\n\t *    seeeeeee eeeeffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n\t *       A        B        C        D        E        F        G        H\n\t *\n\t *    s       sign bit\n\t *    eee...  exponent field\n\t *    fff...  fraction\n\t *\n\t *    ieee value = 1.ffff... * 2^(e - 1023)  (normal)\n\t *               = 0.ffff... * 2^(-1022)     (denormal)\n\t *\n\t *    algorithm v = f * b^e\n\t */\n\n\tDUK_DBLUNION_SET_DOUBLE(&u, x);\n\n\tnc_ctx->f.n = 2;\n\n\ttmp = DUK_DBLUNION_GET_LOW32(&u);\n\tnc_ctx->f.v[0] = tmp;\n\ttmp = DUK_DBLUNION_GET_HIGH32(&u);\n\tnc_ctx->f.v[1] = tmp & 0x000fffffUL;\n\texpt = (duk_small_int_t) ((tmp >> 20) & 0x07ffUL);\n\n\tif (expt == 0) {\n\t\t/* denormal */\n\t\texpt = DUK__IEEE_DOUBLE_EXP_MIN - 52;\n\t\tduk__bi_normalize(&nc_ctx->f);\n\t} else {\n\t\t/* normal: implicit leading 1-bit */\n\t\tnc_ctx->f.v[1] |= 0x00100000UL;\n\t\texpt = expt - DUK__IEEE_DOUBLE_EXP_BIAS - 52;\n\t\tDUK_ASSERT(duk__bi_is_valid(&nc_ctx->f));  /* true, because v[1] has at least one bit set */\n\t}\n\n\tDUK_ASSERT(duk__bi_is_valid(&nc_ctx->f));\n\n\tnc_ctx->e = expt;\n}\n\nDUK_LOCAL void duk__dragon4_ctx_to_double(duk__numconv_stringify_ctx *nc_ctx, duk_double_t *x) {\n\tduk_double_union u;\n\tduk_small_int_t expt;\n\tduk_small_int_t i;\n\tduk_small_int_t bitstart;\n\tduk_small_int_t bitround;\n\tduk_small_int_t bitidx;\n\tduk_small_int_t skip_round;\n\tduk_uint32_t t, v;\n\n\tDUK_ASSERT(nc_ctx->count == 53 + 1);\n\n\t/* Sometimes this assert is not true right now; it will be true after\n\t * rounding.  See: test-bug-numconv-mantissa-assert.js.\n\t */\n\tDUK_ASSERT_DISABLE(nc_ctx->digits[0] == 1);  /* zero handled by caller */\n\n\t/* Should not be required because the code below always sets both high\n\t * and low parts, but at least gcc-4.4.5 fails to deduce this correctly\n\t * (perhaps because the low part is set (seemingly) conditionally in a\n\t * loop), so this is here to avoid the bogus warning.\n\t */\n\tduk_memzero((void *) &u, sizeof(u));\n\n\t/*\n\t *  Figure out how generated digits match up with the mantissa,\n\t *  and then perform rounding.  If mantissa overflows, need to\n\t *  recompute the exponent (it is bumped and may overflow to\n\t *  infinity).\n\t *\n\t *  For normal numbers the leading '1' is hidden and ignored,\n\t *  and the last bit is used for rounding:\n\t *\n\t *                          rounding pt\n\t *       <--------52------->|\n\t *     1 x x x x ... x x x x|y  ==>  x x x x ... x x x x\n\t *\n\t *  For denormals, the leading '1' is included in the number,\n\t *  and the rounding point is different:\n\t *\n\t *                      rounding pt\n\t *     <--52 or less--->|\n\t *     1 x x x x ... x x|x x y  ==>  0 0 ... 1 x x ... x x\n\t *\n\t *  The largest denormals will have a mantissa beginning with\n\t *  a '1' (the explicit leading bit); smaller denormals will\n\t *  have leading zero bits.\n\t *\n\t *  If the exponent would become too high, the result becomes\n\t *  Infinity.  If the exponent is so small that the entire\n\t *  mantissa becomes zero, the result becomes zero.\n\t *\n\t *  Note: the Dragon4 'k' is off-by-one with respect to the IEEE\n\t *  exponent.  For instance, k==0 indicates that the leading '1'\n\t *  digit is at the first binary fraction position (0.1xxx...);\n\t *  the corresponding IEEE exponent would be -1.\n\t */\n\n\tskip_round = 0;\n\n recheck_exp:\n\n\texpt = nc_ctx->k - 1;   /* IEEE exp without bias */\n\tif (expt > 1023) {\n\t\t/* Infinity */\n\t\tbitstart = -255;  /* needed for inf: causes mantissa to become zero,\n\t\t                   * and rounding to be skipped.\n\t\t                   */\n\t\texpt = 2047;\n\t} else if (expt >= -1022) {\n\t\t/* normal */\n\t\tbitstart = 1;  /* skip leading digit */\n\t\texpt += DUK__IEEE_DOUBLE_EXP_BIAS;\n\t\tDUK_ASSERT(expt >= 1 && expt <= 2046);\n\t} else {\n\t\t/* denormal or zero */\n\t\tbitstart = 1023 + expt;  /* expt==-1023 -> bitstart=0 (leading 1);\n\t\t                          * expt==-1024 -> bitstart=-1 (one left of leading 1), etc\n\t\t                          */\n\t\texpt = 0;\n\t}\n\tbitround = bitstart + 52;\n\n\tDUK_DDD(DUK_DDDPRINT(\"ieee expt=%ld, bitstart=%ld, bitround=%ld\",\n\t                     (long) expt, (long) bitstart, (long) bitround));\n\n\tif (!skip_round) {\n\t\tif (duk__dragon4_fixed_format_round(nc_ctx, bitround)) {\n\t\t\t/* Corner case: see test-numconv-parse-mant-carry.js.  We could\n\t\t\t * just bump the exponent and update bitstart, but it's more robust\n\t\t\t * to recompute (but avoid rounding twice).\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"rounding caused exponent to be bumped, recheck exponent\"));\n\t\t\tskip_round = 1;\n\t\t\tgoto recheck_exp;\n\t\t}\n\t}\n\n\t/*\n\t *  Create mantissa\n\t */\n\n\tt = 0;\n\tfor (i = 0; i < 52; i++) {\n\t\tbitidx = bitstart + 52 - 1 - i;\n\t\tif (bitidx >= nc_ctx->count) {\n\t\t\tv = 0;\n\t\t} else if (bitidx < 0) {\n\t\t\tv = 0;\n\t\t} else {\n\t\t\tv = nc_ctx->digits[bitidx];\n\t\t}\n\t\tDUK_ASSERT(v == 0 || v == 1);\n\t\tt += v << (i % 32);\n\t\tif (i == 31) {\n\t\t\t/* low 32 bits is complete */\n\t\t\tDUK_DBLUNION_SET_LOW32(&u, t);\n\t\t\tt = 0;\n\t\t}\n\t}\n\t/* t has high mantissa */\n\n\tDUK_DDD(DUK_DDDPRINT(\"mantissa is complete: %08lx %08lx\",\n\t                     (unsigned long) t,\n\t                     (unsigned long) DUK_DBLUNION_GET_LOW32(&u)));\n\n\tDUK_ASSERT(expt >= 0 && expt <= 0x7ffL);\n\tt += ((duk_uint32_t) expt) << 20;\n#if 0  /* caller handles sign change */\n\tif (negative) {\n\t\tt |= 0x80000000U;\n\t}\n#endif\n\tDUK_DBLUNION_SET_HIGH32(&u, t);\n\n\tDUK_DDD(DUK_DDDPRINT(\"number is complete: %08lx %08lx\",\n\t                     (unsigned long) DUK_DBLUNION_GET_HIGH32(&u),\n\t                     (unsigned long) DUK_DBLUNION_GET_LOW32(&u)));\n\n\t*x = DUK_DBLUNION_GET_DOUBLE(&u);\n}\n\n/*\n *  Exposed number-to-string API\n *\n *  Input: [ number ]\n *  Output: [ string ]\n */\n\nDUK_LOCAL DUK_NOINLINE void duk__numconv_stringify_raw(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) {\n\tduk_double_t x;\n\tduk_small_int_t c;\n\tduk_small_int_t neg;\n\tduk_uint32_t uval;\n\tduk__numconv_stringify_ctx nc_ctx_alloc;  /* large context; around 2kB now */\n\tduk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;\n\n\tx = (duk_double_t) duk_require_number(thr, -1);\n\tduk_pop(thr);\n\n\t/*\n\t *  Handle special cases (NaN, infinity, zero).\n\t */\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (DUK_SIGNBIT((double) x)) {\n\t\tx = -x;\n\t\tneg = 1;\n\t} else {\n\t\tneg = 0;\n\t}\n\n\t/* NaN sign bit is platform specific with unpacked, un-normalized NaNs */\n\tDUK_ASSERT(c == DUK_FP_NAN || DUK_SIGNBIT((double) x) == 0);\n\n\tif (c == DUK_FP_NAN) {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_NAN);\n\t\treturn;\n\t} else if (c == DUK_FP_INFINITE) {\n\t\tif (neg) {\n\t\t\t/* -Infinity */\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_MINUS_INFINITY);\n\t\t} else {\n\t\t\t/* Infinity */\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_INFINITY);\n\t\t}\n\t\treturn;\n\t} else if (c == DUK_FP_ZERO) {\n\t\t/* We can't shortcut zero here if it goes through special formatting\n\t\t * (such as forced exponential notation).\n\t\t */\n\t\t;\n\t}\n\n\t/*\n\t *  Handle integers in 32-bit range (that is, [-(2**32-1),2**32-1])\n\t *  specially, as they're very likely for embedded programs.  This\n\t *  is now done for all radix values.  We must be careful not to use\n\t *  the fast path when special formatting (e.g. forced exponential)\n\t *  is in force.\n\t *\n\t *  XXX: could save space by supporting radix 10 only and using\n\t *  sprintf \"%lu\" for the fast path and for exponent formatting.\n\t */\n\n\tuval = duk_double_to_uint32_t(x);\n\tif (((double) uval) == x &&  /* integer number in range */\n\t    flags == 0) {            /* no special formatting */\n\t\t/* use bigint area as a temp */\n\t\tduk_uint8_t *buf = (duk_uint8_t *) (&nc_ctx->f);\n\t\tduk_uint8_t *p = buf;\n\n\t\tDUK_ASSERT(DUK__NUMCONV_CTX_BIGINTS_SIZE >= 32 + 1);  /* max size: radix=2 + sign */\n\t\tif (neg && uval != 0) {\n\t\t\t/* no negative sign for zero */\n\t\t\t*p++ = (duk_uint8_t) '-';\n\t\t}\n\t\tp += duk__dragon4_format_uint32(p, uval, radix);\n\t\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) (p - buf));\n\t\treturn;\n\t}\n\n\t/*\n\t *  Dragon4 setup.\n\t *\n\t *  Convert double from IEEE representation for conversion;\n\t *  normal finite values have an implicit leading 1-bit.  The\n\t *  slow path algorithm doesn't handle zero, so zero is special\n\t *  cased here but still creates a valid nc_ctx, and goes\n\t *  through normal formatting in case special formatting has\n\t *  been requested (e.g. forced exponential format: 0 -> \"0e+0\").\n\t */\n\n\t/* Would be nice to bulk clear the allocation, but the context\n\t * is 1-2 kilobytes and nothing should rely on it being zeroed.\n\t */\n#if 0\n\tduk_memzero((void *) nc_ctx, sizeof(*nc_ctx));  /* slow init, do only for slow path cases */\n#endif\n\n\tnc_ctx->is_s2n = 0;\n\tnc_ctx->b = 2;\n\tnc_ctx->B = radix;\n\tnc_ctx->abs_pos = 0;\n\tif (flags & DUK_N2S_FLAG_FIXED_FORMAT) {\n\t\tnc_ctx->is_fixed = 1;\n\t\tif (flags & DUK_N2S_FLAG_FRACTION_DIGITS) {\n\t\t\t/* absolute req_digits; e.g. digits = 1 -> last digit is 0,\n\t\t\t * but add an extra digit for rounding.\n\t\t\t */\n\t\t\tnc_ctx->abs_pos = 1;\n\t\t\tnc_ctx->req_digits = (-digits + 1) - 1;\n\t\t} else {\n\t\t\tnc_ctx->req_digits = digits + 1;\n\t\t}\n\t} else {\n\t\tnc_ctx->is_fixed = 0;\n\t\tnc_ctx->req_digits = 0;\n\t}\n\n\tif (c == DUK_FP_ZERO) {\n\t\t/* Zero special case: fake requested number of zero digits; ensure\n\t\t * no sign bit is printed.  Relative and absolute fixed format\n\t\t * require separate handling.\n\t\t */\n\t\tduk_small_int_t count;\n\t\tif (nc_ctx->is_fixed) {\n\t\t\tif (nc_ctx->abs_pos) {\n\t\t\t\tcount = digits + 2;  /* lead zero + 'digits' fractions + 1 for rounding */\n\t\t\t} else {\n\t\t\t\tcount = digits + 1;  /* + 1 for rounding */\n\t\t\t}\n\t\t} else {\n\t\t\tcount = 1;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"count=%ld\", (long) count));\n\t\tDUK_ASSERT(count >= 1);\n\t\tduk_memzero((void *) nc_ctx->digits, (size_t) count);\n\t\tnc_ctx->count = count;\n\t\tnc_ctx->k = 1;  /* 0.000... */\n\t\tneg = 0;\n\t\tgoto zero_skip;\n\t}\n\n\tduk__dragon4_double_to_ctx(nc_ctx, x);   /* -> sets 'f' and 'e' */\n\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\tDUK_DDD(DUK_DDDPRINT(\"e=%ld\", (long) nc_ctx->e));\n\n\t/*\n\t *  Dragon4 slow path digit generation.\n\t */\n\n\tduk__dragon4_prepare(nc_ctx);  /* setup many variables in nc_ctx */\n\n\tDUK_DDD(DUK_DDDPRINT(\"after prepare:\"));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_scale(nc_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"after scale; k=%ld\", (long) nc_ctx->k));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_generate(nc_ctx);\n\n\t/*\n\t *  Convert and push final string.\n\t */\n\n zero_skip:\n\n\tif (flags & DUK_N2S_FLAG_FIXED_FORMAT) {\n\t\t/* Perform fixed-format rounding. */\n\t\tduk_small_int_t roundpos;\n\t\tif (flags & DUK_N2S_FLAG_FRACTION_DIGITS) {\n\t\t\t/* 'roundpos' is relative to nc_ctx->k and increases to the right\n\t\t\t * (opposite of how 'k' changes).\n\t\t\t */\n\t\t\troundpos = -digits;  /* absolute position for digit considered for rounding */\n\t\t\troundpos = nc_ctx->k - roundpos;\n\t\t} else {\n\t\t\troundpos = digits;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"rounding: k=%ld, count=%ld, digits=%ld, roundpos=%ld\",\n\t\t                     (long) nc_ctx->k, (long) nc_ctx->count, (long) digits, (long) roundpos));\n\t\t(void) duk__dragon4_fixed_format_round(nc_ctx, roundpos);\n\n\t\t/* Note: 'count' is currently not adjusted by rounding (i.e. the\n\t\t * digits are not \"chopped off\".  That shouldn't matter because\n\t\t * the digit position (absolute or relative) is passed on to the\n\t\t * convert-and-push function.\n\t\t */\n\t}\n\n\tduk__dragon4_convert_and_push(nc_ctx, thr, radix, digits, flags, neg);\n}\n\nDUK_INTERNAL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) {\n\tduk_native_stack_check(thr);\n\tduk__numconv_stringify_raw(thr, radix, digits, flags);\n}\n\n/*\n *  Exposed string-to-number API\n *\n *  Input: [ string ]\n *  Output: [ number ]\n *\n *  If number parsing fails, a NaN is pushed as the result.  If number parsing\n *  fails due to an internal error, an InternalError is thrown.\n */\n\nDUK_LOCAL DUK_NOINLINE void duk__numconv_parse_raw(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags) {\n\tduk__numconv_stringify_ctx nc_ctx_alloc;  /* large context; around 2kB now */\n\tduk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;\n\tduk_double_t res;\n\tduk_hstring *h_str;\n\tduk_int_t expt;\n\tduk_bool_t expt_neg;\n\tduk_small_int_t expt_adj;\n\tduk_small_int_t neg;\n\tduk_small_int_t dig;\n\tduk_small_int_t dig_whole;\n\tduk_small_int_t dig_lzero;\n\tduk_small_int_t dig_frac;\n\tduk_small_int_t dig_expt;\n\tduk_small_int_t dig_prec;\n\tconst duk__exp_limits *explim;\n\tconst duk_uint8_t *p;\n\tduk_small_int_t ch;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse number: %!T, radix=%ld, flags=0x%08lx\",\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (long) radix, (unsigned long) flags));\n\n\tDUK_ASSERT(radix >= 2 && radix <= 36);\n\tDUK_ASSERT(radix - 2 < (duk_small_int_t) sizeof(duk__str2num_digits_for_radix));\n\n\t/*\n\t *  Preliminaries: trim, sign, Infinity check\n\t *\n\t *  We rely on the interned string having a NUL terminator, which will\n\t *  cause a parse failure wherever it is encountered.  As a result, we\n\t *  don't need separate pointer checks.\n\t *\n\t *  There is no special parsing for 'NaN' in the specification although\n\t *  'Infinity' (with an optional sign) is allowed in some contexts.\n\t *  Some contexts allow plus/minus sign, while others only allow the\n\t *  minus sign (like JSON.parse()).\n\t *\n\t *  Automatic hex number detection (leading '0x' or '0X') and octal\n\t *  number detection (leading '0' followed by at least one octal digit)\n\t *  is done here too.\n\t *\n\t *  Symbols are not explicitly rejected here (that's up to the caller).\n\t *  If a symbol were passed here, it should ultimately safely fail\n\t *  parsing due to a syntax error.\n\t */\n\n\tif (flags & DUK_S2N_FLAG_TRIM_WHITE) {\n\t\t/* Leading / trailing whitespace is sometimes accepted and\n\t\t * sometimes not.  After white space trimming, all valid input\n\t\t * characters are pure ASCII.\n\t\t */\n\t\tduk_trim(thr, -1);\n\t}\n\th_str = duk_require_hstring(thr, -1);\n\tDUK_ASSERT(h_str != NULL);\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_str);\n\n\tneg = 0;\n\tch = *p;\n\tif (ch == (duk_small_int_t) '+') {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_PLUS) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: leading plus sign not allowed\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t\tp++;\n\t} else if (ch == (duk_small_int_t) '-') {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_MINUS) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: leading minus sign not allowed\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t\tp++;\n\t\tneg = 1;\n\t}\n\n\tif ((flags & DUK_S2N_FLAG_ALLOW_INF) && DUK_STRNCMP((const char *) p, \"Infinity\", 8) == 0) {\n\t\t/* Don't check for Infinity unless the context allows it.\n\t\t * 'Infinity' is a valid integer literal in e.g. base-36:\n\t\t *\n\t\t *   parseInt('Infinity', 36)\n\t\t *   1461559270678\n\t\t */\n\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_GARBAGE) == 0 && p[8] != DUK_ASC_NUL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: trailing garbage after matching 'Infinity' not allowed\"));\n\t\t\tgoto parse_fail;\n\t\t} else {\n\t\t\tres = DUK_DOUBLE_INFINITY;\n\t\t\tgoto negcheck_and_ret;\n\t\t}\n\t}\n\tch = *p;\n\tif (ch == (duk_small_int_t) '0') {\n\t\tduk_small_int_t detect_radix = 0;\n\t\tch = DUK_LOWERCASE_CHAR_ASCII(p[1]);  /* 'x' or 'X' -> 'x' */\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT) && ch == DUK_ASC_LC_X) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0x/0X hex prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 16;\n#if 0\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_LEGACY_OCT_INT) &&\n\t\t           (ch >= (duk_small_int_t) '0' && ch <= (duk_small_int_t) '9')) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0n oct prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 8;\n\n\t\t\t/* NOTE: if this legacy octal case is added back, it has\n\t\t\t * different flags and 'p' advance so this needs to be\n\t\t\t * reworked.\n\t\t\t */\n\t\t\tflags |= DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO;  /* interpret e.g. '09' as '0', not NaN */\n\t\t\tp += 1;\n#endif\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT) && ch == DUK_ASC_LC_O) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0o oct prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 8;\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT) && ch == DUK_ASC_LC_B) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0b bin prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 2;\n\t\t}\n\t\tif (detect_radix > 0) {\n\t\t\tradix = detect_radix;\n\t\t\t/* Clear empty as zero flag: interpret e.g. '0x' and '0xg' as a NaN (= parse error) */\n\t\t\tflags &= ~(DUK_S2N_FLAG_ALLOW_EXP | DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t\t\t           DUK_S2N_FLAG_ALLOW_FRAC | DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t\t\t           DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO);\n\t\t\tflags |= DUK_S2N_FLAG_ALLOW_LEADING_ZERO;  /* allow e.g. '0x0009' and '0b00010001' */\n\t\t\tp += 2;\n\t\t}\n\t}\n\n\t/*\n\t *  Scan number and setup for Dragon4.\n\t *\n\t *  The fast path case is detected during setup: an integer which\n\t *  can be converted without rounding, no net exponent.  The fast\n\t *  path could be implemented as a separate scan, but may not really\n\t *  be worth it: the multiplications for building 'f' are not\n\t *  expensive when 'f' is small.\n\t *\n\t *  The significand ('f') must contain enough bits of (apparent)\n\t *  accuracy, so that Dragon4 will generate enough binary output digits.\n\t *  For decimal numbers, this means generating a 20-digit significand,\n\t *  which should yield enough practical accuracy to parse IEEE doubles.\n\t *  In fact, the ECMAScript specification explicitly allows an\n\t *  implementation to treat digits beyond 20 as zeroes (and even\n\t *  to round the 20th digit upwards).  For non-decimal numbers, the\n\t *  appropriate number of digits has been precomputed for comparable\n\t *  accuracy.\n\t *\n\t *  Digit counts:\n\t *\n\t *    [ dig_lzero ]\n\t *      |\n\t *     .+-..---[ dig_prec ]----.\n\t *     |  ||                   |\n\t *     0000123.456789012345678901234567890e+123456\n\t *     |     | |                         |  |    |\n\t *     `--+--' `------[ dig_frac ]-------'  `-+--'\n\t *        |                                   |\n\t *    [ dig_whole ]                       [ dig_expt ]\n\t *\n\t *    dig_frac and dig_expt are -1 if not present\n\t *    dig_lzero is only computed for whole number part\n\t *\n\t *  Parsing state\n\t *\n\t *     Parsing whole part      dig_frac < 0 AND dig_expt < 0\n\t *     Parsing fraction part   dig_frac >= 0 AND dig_expt < 0\n\t *     Parsing exponent part   dig_expt >= 0   (dig_frac may be < 0 or >= 0)\n\t *\n\t *  Note: in case we hit an implementation limit (like exponent range),\n\t *  we should throw an error, NOT return NaN or Infinity.  Even with\n\t *  very large exponent (or significand) values the final result may be\n\t *  finite, so NaN/Infinity would be incorrect.\n\t */\n\n\tduk__bi_set_small(&nc_ctx->f, 0);\n\tdig_prec = 0;\n\tdig_lzero = 0;\n\tdig_whole = 0;\n\tdig_frac = -1;\n\tdig_expt = -1;\n\texpt = 0;\n\texpt_adj = 0;  /* essentially tracks digit position of lowest 'f' digit */\n\texpt_neg = 0;\n\tfor (;;) {\n\t\tch = *p++;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse digits: p=%p, ch='%c' (%ld), expt=%ld, expt_adj=%ld, \"\n\t\t                     \"dig_whole=%ld, dig_frac=%ld, dig_expt=%ld, dig_lzero=%ld, dig_prec=%ld\",\n\t\t                     (const void *) p, (int) ((ch >= 0x20 && ch <= 0x7e) ? ch : '?'), (long) ch,\n\t\t                     (long) expt, (long) expt_adj, (long) dig_whole, (long) dig_frac,\n\t\t                     (long) dig_expt, (long) dig_lzero, (long) dig_prec));\n\t\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\n\t\t/* Most common cases first. */\n\t\tif (ch >= (duk_small_int_t) '0' && ch <= (duk_small_int_t) '9') {\n\t\t\tdig = (duk_small_int_t) ch - '0' + 0;\n\t\t} else if (ch == (duk_small_int_t) '.') {\n\t\t\t/* A leading digit is not required in some cases, e.g. accept \".123\".\n\t\t\t * In other cases (JSON.parse()) a leading digit is required.  This\n\t\t\t * is checked for after the loop.\n\t\t\t */\n\t\t\tif (dig_frac >= 0 || dig_expt >= 0) {\n\t\t\t\tif (flags & DUK_S2N_FLAG_ALLOW_GARBAGE) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"garbage termination (invalid period)\"));\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: period not allowed\"));\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_FRAC) == 0) {\n\t\t\t\t/* Some contexts don't allow fractions at all; this can't be a\n\t\t\t\t * post-check because the state ('f' and expt) would be incorrect.\n\t\t\t\t */\n\t\t\t\tif (flags & DUK_S2N_FLAG_ALLOW_GARBAGE) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"garbage termination (invalid first period)\"));\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: fraction part not allowed\"));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"start fraction part\"));\n\t\t\tdig_frac = 0;\n\t\t\tcontinue;\n\t\t} else if (ch == (duk_small_int_t) 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"NUL termination\"));\n\t\t\tbreak;\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_EXP) &&\n\t\t           dig_expt < 0 && (ch == (duk_small_int_t) 'e' || ch == (duk_small_int_t) 'E')) {\n\t\t\t/* Note: we don't parse back exponent notation for anything else\n\t\t\t * than radix 10, so this is not an ambiguous check (e.g. hex\n\t\t\t * exponent values may have 'e' either as a significand digit\n\t\t\t * or as an exponent separator).\n\t\t\t *\n\t\t\t * If the exponent separator occurs twice, 'e' will be interpreted\n\t\t\t * as a digit (= 14) and will be rejected as an invalid decimal\n\t\t\t * digit.\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"start exponent part\"));\n\n\t\t\t/* Exponent without a sign or with a +/- sign is accepted\n\t\t\t * by all call sites (even JSON.parse()).\n\t\t\t */\n\t\t\tch = *p;\n\t\t\tif (ch == (duk_small_int_t) '-') {\n\t\t\t\texpt_neg = 1;\n\t\t\t\tp++;\n\t\t\t} else if (ch == (duk_small_int_t) '+') {\n\t\t\t\tp++;\n\t\t\t}\n\t\t\tdig_expt = 0;\n\t\t\tcontinue;\n\t\t} else if (ch >= (duk_small_int_t) 'a' && ch <= (duk_small_int_t) 'z') {\n\t\t\tdig = (duk_small_int_t) (ch - (duk_small_int_t) 'a' + 0x0a);\n\t\t} else if (ch >= (duk_small_int_t) 'A' && ch <= (duk_small_int_t) 'Z') {\n\t\t\tdig = (duk_small_int_t) (ch - (duk_small_int_t) 'A' + 0x0a);\n\t\t} else {\n\t\t\tdig = 255;  /* triggers garbage digit check below */\n\t\t}\n\t\tDUK_ASSERT((dig >= 0 && dig <= 35) || dig == 255);\n\n\t\tif (dig >= radix) {\n\t\t\tif (flags & DUK_S2N_FLAG_ALLOW_GARBAGE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"garbage termination\"));\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: trailing garbage or invalid digit\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t}\n\n\t\tif (dig_expt < 0) {\n\t\t\t/* whole or fraction digit */\n\n\t\t\tif (dig_prec < duk__str2num_digits_for_radix[radix - 2]) {\n\t\t\t\t/* significant from precision perspective */\n\n\t\t\t\tduk_small_int_t f_zero = duk__bi_is_zero(&nc_ctx->f);\n\t\t\t\tif (f_zero && dig == 0) {\n\t\t\t\t\t/* Leading zero is not counted towards precision digits; not\n\t\t\t\t\t * in the integer part, nor in the fraction part.\n\t\t\t\t\t */\n\t\t\t\t\tif (dig_frac < 0) {\n\t\t\t\t\t\tdig_lzero++;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t/* XXX: join these ops (multiply-accumulate), but only if\n\t\t\t\t\t * code footprint decreases.\n\t\t\t\t\t */\n\t\t\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, (duk_uint32_t) radix);\n\t\t\t\t\tduk__bi_add_small(&nc_ctx->f, &nc_ctx->t1, (duk_uint32_t) dig);\n\t\t\t\t\tdig_prec++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* Ignore digits beyond a radix-specific limit, but note them\n\t\t\t\t * in expt_adj.\n\t\t\t\t */\n\t\t\t\texpt_adj++;\n\t\t\t}\n\n\t\t\tif (dig_frac >= 0) {\n\t\t\t\tdig_frac++;\n\t\t\t\texpt_adj--;\n\t\t\t} else {\n\t\t\t\tdig_whole++;\n\t\t\t}\n\t\t} else {\n\t\t\t/* exponent digit */\n\n\t\t\tDUK_ASSERT(radix == 10);\n\t\t\texpt = expt * radix + dig;\n\t\t\tif (expt > DUK_S2N_MAX_EXPONENT) {\n\t\t\t\t/* Impose a reasonable exponent limit, so that exp\n\t\t\t\t * doesn't need to get tracked using a bigint.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: exponent too large\"));\n\t\t\t\tgoto parse_explimit_error;\n\t\t\t}\n\t\t\tdig_expt++;\n\t\t}\n\t}\n\n\t/* Leading zero. */\n\n\tif (dig_lzero > 0 && dig_whole > 1) {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_LEADING_ZERO) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: leading zeroes not allowed in integer part\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t}\n\n\t/* Validity checks for various fraction formats (\"0.1\", \".1\", \"1.\", \".\"). */\n\n\tif (dig_whole == 0) {\n\t\tif (dig_frac == 0) {\n\t\t\t/* \".\" is not accepted in any format */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: plain period without leading or trailing digits\"));\n\t\t\tgoto parse_fail;\n\t\t} else if (dig_frac > 0) {\n\t\t\t/* \".123\" */\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_NAKED_FRAC) == 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: fraction part not allowed without \"\n\t\t\t\t                     \"leading integer digit(s)\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t} else {\n\t\t\t/* Empty (\"\") is allowed in some formats (e.g. Number(''), as zero,\n\t\t\t * but it must not have a leading +/- sign (GH-2019).  Note that\n\t\t\t * for Number(), h_str is already trimmed so we can check for zero\n\t\t\t * length and still get Number('  +  ') == NaN.\n\t\t\t */\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO) == 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: empty string not allowed (as zero)\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t} else if (DUK_HSTRING_GET_BYTELEN(h_str) != 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: no digits, but not empty (had a +/- sign)\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif (dig_frac == 0) {\n\t\t\t/* \"123.\" is allowed in some formats */\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_EMPTY_FRAC) == 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: empty fractions\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t} else if (dig_frac > 0) {\n\t\t\t/* \"123.456\" */\n\t\t\t;\n\t\t} else {\n\t\t\t/* \"123\" */\n\t\t\t;\n\t\t}\n\t}\n\n\t/* Exponent without digits (e.g. \"1e\" or \"1e+\").  If trailing garbage is\n\t * allowed, ignore exponent part as garbage (= parse as \"1\", i.e. exp 0).\n\t */\n\n\tif (dig_expt == 0) {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_GARBAGE) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: empty exponent\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t\tDUK_ASSERT(expt == 0);\n\t}\n\n\tif (expt_neg) {\n\t\texpt = -expt;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"expt=%ld, expt_adj=%ld, net exponent -> %ld\",\n\t                     (long) expt, (long) expt_adj, (long) (expt + expt_adj)));\n\texpt += expt_adj;\n\n\t/* Fast path check. */\n\n\tif (nc_ctx->f.n <= 1 &&   /* 32-bit value */\n\t    expt == 0    /* no net exponent */) {\n\t\t/* Fast path is triggered for no exponent and also for balanced exponent\n\t\t * and fraction parts, e.g. for \"1.23e2\" == \"123\".  Remember to respect\n\t\t * zero sign.\n\t\t */\n\n\t\t/* XXX: could accept numbers larger than 32 bits, e.g. up to 53 bits? */\n\t\tDUK_DDD(DUK_DDDPRINT(\"fast path number parse\"));\n\t\tif (nc_ctx->f.n == 1) {\n\t\t\tres = (double) nc_ctx->f.v[0];\n\t\t} else {\n\t\t\tres = 0.0;\n\t\t}\n\t\tgoto negcheck_and_ret;\n\t}\n\n\t/* Significand ('f') padding. */\n\n\twhile (dig_prec < duk__str2num_digits_for_radix[radix - 2]) {\n\t\t/* Pad significand with \"virtual\" zero digits so that Dragon4 will\n\t\t * have enough (apparent) precision to work with.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"dig_prec=%ld, pad significand with zero\", (long) dig_prec));\n\t\tduk__bi_mul_small_copy(&nc_ctx->f, (duk_uint32_t) radix, &nc_ctx->t1);\n\t\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\t\texpt--;\n\t\tdig_prec++;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"final exponent: %ld\", (long) expt));\n\n\t/* Detect zero special case. */\n\n\tif (nc_ctx->f.n == 0) {\n\t\t/* This may happen even after the fast path check, if exponent is\n\t\t * not balanced (e.g. \"0e1\").  Remember to respect zero sign.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"significand is zero\"));\n\t\tres = 0.0;\n\t\tgoto negcheck_and_ret;\n\t}\n\n\n\t/* Quick reject of too large or too small exponents.  This check\n\t * would be incorrect for zero (e.g. \"0e1000\" is zero, not Infinity)\n\t * so zero check must be above.\n\t */\n\n\texplim = &duk__str2num_exp_limits[radix - 2];\n\tif (expt > explim->upper) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"exponent too large -> infinite\"));\n\t\tres = (duk_double_t) DUK_DOUBLE_INFINITY;\n\t\tgoto negcheck_and_ret;\n\t} else if (expt < explim->lower) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"exponent too small -> zero\"));\n\t\tres = (duk_double_t) 0.0;\n\t\tgoto negcheck_and_ret;\n\t}\n\n\tnc_ctx->is_s2n = 1;\n\tnc_ctx->e = expt;\n\tnc_ctx->b = radix;\n\tnc_ctx->B = 2;\n\tnc_ctx->is_fixed = 1;\n\tnc_ctx->abs_pos = 0;\n\tnc_ctx->req_digits = 53 + 1;\n\n\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\tDUK_DDD(DUK_DDDPRINT(\"e=%ld\", (long) nc_ctx->e));\n\n\t/*\n\t *  Dragon4 slow path (binary) digit generation.\n\t *  An extra digit is generated for rounding.\n\t */\n\n\tduk__dragon4_prepare(nc_ctx);  /* setup many variables in nc_ctx */\n\n\tDUK_DDD(DUK_DDDPRINT(\"after prepare:\"));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_scale(nc_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"after scale; k=%ld\", (long) nc_ctx->k));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_generate(nc_ctx);\n\n\tDUK_ASSERT(nc_ctx->count == 53 + 1);\n\n\t/*\n\t *  Convert binary digits into an IEEE double.  Need to handle\n\t *  denormals and rounding correctly.\n\t *\n\t *  Some call sites currently assume the result is always a\n\t *  non-fastint double.  If this is changed, check all call\n\t *  sites.\n\t */\n\n\tduk__dragon4_ctx_to_double(nc_ctx, &res);\n\tgoto negcheck_and_ret;\n\n negcheck_and_ret:\n\tif (neg) {\n\t\tres = -res;\n\t}\n\tduk_pop(thr);\n\tduk_push_number(thr, (double) res);\n\tDUK_DDD(DUK_DDDPRINT(\"result: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\treturn;\n\n parse_fail:\n\tDUK_DDD(DUK_DDDPRINT(\"parse failed\"));\n\tduk_pop(thr);\n\tduk_push_nan(thr);\n\treturn;\n\n parse_explimit_error:\n\tDUK_DDD(DUK_DDDPRINT(\"parse failed, internal error, can't return a value\"));\n\tDUK_ERROR_RANGE(thr, \"exponent too large\");\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_INTERNAL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags) {\n\tduk_native_stack_check(thr);\n\tduk__numconv_parse_raw(thr, radix, flags);\n}\n\n/* automatic undefs */\n#undef DUK__BI_MAX_PARTS\n#undef DUK__BI_PRINT\n#undef DUK__DIGITCHAR\n#undef DUK__DRAGON4_OUTPUT_PREINC\n#undef DUK__IEEE_DOUBLE_EXP_BIAS\n#undef DUK__IEEE_DOUBLE_EXP_MIN\n#undef DUK__MAX_FORMATTED_LENGTH\n#undef DUK__MAX_OUTPUT_DIGITS\n#undef DUK__NO_EXP\n#undef DUK__NUMCONV_CTX_BIGINTS_SIZE\n#undef DUK__NUMCONV_CTX_NUM_BIGINTS\n#line 1 \"duk_regexp_compiler.c\"\n/*\n *  Regexp compilation.\n *\n *  See doc/regexp.rst for a discussion of the compilation approach and\n *  current limitations.\n *\n *  Regexp bytecode assumes jumps can be expressed with signed 32-bit\n *  integers.  Consequently the bytecode size must not exceed 0x7fffffffL.\n *  The implementation casts duk_size_t (buffer size) to duk_(u)int32_t\n *  in many places.  Although this could be changed, the bytecode format\n *  limit would still prevent regexps exceeding the signed 32-bit limit\n *  from working.\n *\n *  XXX: The implementation does not prevent bytecode from exceeding the\n *  maximum supported size.  This could be done by limiting the maximum\n *  input string size (assuming an upper bound can be computed for number\n *  of bytecode bytes emitted per input byte) or checking buffer maximum\n *  size when emitting bytecode (slower).\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Helper macros\n */\n\n#define DUK__RE_INITIAL_BUFSIZE 64\n\n#define DUK__RE_BUFLEN(re_ctx) \\\n\tDUK_BW_GET_SIZE(re_ctx->thr, &re_ctx->bw)\n\n/*\n *  Disjunction struct: result of parsing a disjunction\n */\n\ntypedef struct {\n\t/* Number of characters that the atom matches (e.g. 3 for 'abc'),\n\t * -1 if atom is complex and number of matched characters either\n\t * varies or is not known.\n\t */\n\tduk_int32_t charlen;\n\n#if 0\n\t/* These are not needed to implement quantifier capture handling,\n\t * but might be needed at some point.\n\t */\n\n\t/* re_ctx->captures at start and end of atom parsing.\n\t * Since 'captures' indicates highest capture number emitted\n\t * so far in a DUK_REOP_SAVE, the captures numbers saved by\n\t * the atom are: ]start_captures,end_captures].\n\t */\n\tduk_uint32_t start_captures;\n\tduk_uint32_t end_captures;\n#endif\n} duk__re_disjunction_info;\n\n/*\n *  Encoding helpers\n *\n *  Some of the typing is bytecode based, e.g. slice sizes are unsigned 32-bit\n *  even though the buffer operations will use duk_size_t.\n */\n\n/* XXX: the insert helpers should ensure that the bytecode result is not\n * larger than expected (or at least assert for it).  Many things in the\n * bytecode, like skip offsets, won't work correctly if the bytecode is\n * larger than say 2G.\n */\n\nDUK_LOCAL duk_uint32_t duk__encode_i32(duk_int32_t x) {\n\tif (x < 0) {\n\t\treturn ((duk_uint32_t) (-x)) * 2 + 1;\n\t} else {\n\t\treturn ((duk_uint32_t) x) * 2;\n\t}\n}\n\n/* XXX: return type should probably be duk_size_t, or explicit checks are needed for\n * maximum size.\n */\nDUK_LOCAL duk_uint32_t duk__insert_u32(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_uint32_t x) {\n\tduk_uint8_t buf[DUK_UNICODE_MAX_XUTF8_LENGTH];\n\tduk_small_int_t len;\n\n\tlen = duk_unicode_encode_xutf8((duk_ucodepoint_t) x, buf);\n\tDUK_ASSERT(len >= 0);\n\tDUK_BW_INSERT_ENSURE_BYTES(re_ctx->thr, &re_ctx->bw, offset, buf, (duk_size_t) len);\n\treturn (duk_uint32_t) len;\n}\n\nDUK_LOCAL void duk__append_u32(duk_re_compiler_ctx *re_ctx, duk_uint32_t x) {\n\tDUK_BW_WRITE_ENSURE_XUTF8(re_ctx->thr, &re_ctx->bw, x);\n}\n\nDUK_LOCAL void duk__append_7bit(duk_re_compiler_ctx *re_ctx, duk_uint32_t x) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk__append_u32(re_ctx, x);\n#else\n\tDUK_ASSERT(x <= 0x7fU);\n\tDUK_BW_WRITE_ENSURE_U8(re_ctx->thr, &re_ctx->bw, (duk_uint8_t) x);\n#endif\n}\n\n#if 0\nDUK_LOCAL void duk__append_2bytes(duk_re_compiler_ctx *re_ctx, duk_uint8_t x, duk_uint8_t y) {\n\tDUK_BW_WRITE_ENSURE_U8_2(re_ctx->thr, &re_ctx->bw, x, y);\n}\n#endif\n\nDUK_LOCAL duk_uint32_t duk__insert_i32(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_int32_t x) {\n\treturn duk__insert_u32(re_ctx, offset, duk__encode_i32(x));\n}\n\nDUK_LOCAL void duk__append_reop(duk_re_compiler_ctx *re_ctx, duk_uint32_t reop) {\n\tDUK_ASSERT(reop <= 0x7fU);\n\t(void) duk__append_7bit(re_ctx, reop);\n}\n\n#if 0  /* unused */\nDUK_LOCAL void duk__append_i32(duk_re_compiler_ctx *re_ctx, duk_int32_t x) {\n\tduk__append_u32(re_ctx, duk__encode_i32(x));\n}\n#endif\n\n/* special helper for emitting u16 lists (used for character ranges for built-in char classes) */\nDUK_LOCAL void duk__append_u16_list(duk_re_compiler_ctx *re_ctx, const duk_uint16_t *values, duk_uint32_t count) {\n\t/* Call sites don't need the result length so it's not accumulated. */\n\twhile (count-- > 0) {\n\t\tduk__append_u32(re_ctx, (duk_uint32_t) (*values++));\n\t}\n}\n\nDUK_LOCAL void duk__insert_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_uint32_t data_offset, duk_uint32_t data_length) {\n\tDUK_BW_INSERT_ENSURE_SLICE(re_ctx->thr, &re_ctx->bw, offset, data_offset, data_length);\n}\n\nDUK_LOCAL void duk__append_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t data_offset, duk_uint32_t data_length) {\n\tDUK_BW_WRITE_ENSURE_SLICE(re_ctx->thr, &re_ctx->bw, data_offset, data_length);\n}\n\nDUK_LOCAL void duk__remove_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t data_offset, duk_uint32_t data_length) {\n\tDUK_BW_REMOVE_ENSURE_SLICE(re_ctx->thr, &re_ctx->bw, data_offset, data_length);\n}\n\n/*\n *  Insert a jump offset at 'offset' to complete an instruction\n *  (the jump offset is always the last component of an instruction).\n *  The 'skip' argument must be computed relative to 'offset',\n *  -without- taking into account the skip field being inserted.\n *\n *       ... A B C ins X Y Z ...   (ins may be a JUMP, SPLIT1/SPLIT2, etc)\n *   =>  ... A B C ins SKIP X Y Z\n *\n *  Computing the final (adjusted) skip value, which is relative to the\n *  first byte of the next instruction, is a bit tricky because of the\n *  variable length UTF-8 encoding.  See doc/regexp.rst for discussion.\n */\nDUK_LOCAL duk_uint32_t duk__insert_jump_offset(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_int32_t skip) {\n#if 0\n\t/* Iterative solution. */\n\tif (skip < 0) {\n\t\tduk_small_int_t len;\n\t\t/* two encoding attempts suffices */\n\t\tlen = duk_unicode_get_xutf8_length((duk_codepoint_t) duk__encode_i32(skip));\n\t\tlen = duk_unicode_get_xutf8_length((duk_codepoint_t) duk__encode_i32(skip - (duk_int32_t) len));\n\t\tDUK_ASSERT(duk_unicode_get_xutf8_length(duk__encode_i32(skip - (duk_int32_t) len)) == len);  /* no change */\n\t\tskip -= (duk_int32_t) len;\n\t}\n#endif\n\n#if defined(DUK_USE_PREFER_SIZE)\n\t/* Closed form solution, this produces smallest code.\n\t * See re_neg_jump_offset (closed2).\n\t */\n\tif (skip < 0) {\n\t\tskip--;\n\t\tif (skip < -0x3fL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x3ffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x7fffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0xfffffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x1ffffffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x3fffffffL) {\n\t\t\tskip--;\n\t\t}\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\t/* Closed form solution, this produces fastest code.\n\t * See re_neg_jump_offset (closed1).\n\t */\n\tif (skip < 0) {\n\t\tif (skip >= -0x3eL) {\n\t\t\tskip -= 1;\n\t\t} else if (skip >= -0x3fdL) {\n\t\t\tskip -= 2;\n\t\t} else if (skip >= -0x7ffcL) {\n\t\t\tskip -= 3;\n\t\t} else if (skip >= -0xffffbL) {\n\t\t\tskip -= 4;\n\t\t} else if (skip >= -0x1fffffaL) {\n\t\t\tskip -= 5;\n\t\t} else if (skip >= -0x3ffffff9L) {\n\t\t\tskip -= 6;\n\t\t} else {\n\t\t\tskip -= 7;\n\t\t}\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n\treturn duk__insert_i32(re_ctx, offset, skip);\n}\n\nDUK_LOCAL duk_uint32_t duk__append_jump_offset(duk_re_compiler_ctx *re_ctx, duk_int32_t skip) {\n\treturn (duk_uint32_t) duk__insert_jump_offset(re_ctx, (duk_uint32_t) DUK__RE_BUFLEN(re_ctx), skip);\n}\n\n/*\n *  duk_re_range_callback for generating character class ranges.\n *\n *  When ignoreCase is false, the range is simply emitted as is.  We don't,\n *  for instance, eliminate duplicates or overlapping ranges in a character\n *  class.\n *\n *  When ignoreCase is true but the 'direct' flag is set, the caller knows\n *  that the range canonicalizes to itself for case insensitive matching,\n *  so the range is emitted as is.  This is mainly useful for built-in ranges\n *  like \\W.\n *\n *  Otherwise, when ignoreCase is true, the range needs to be normalized\n *  through canonicalization.  Unfortunately a canonicalized version of a\n *  continuous range is not necessarily continuous (e.g. [x-{] is continuous\n *  but [X-{] is not).  As a result, a single input range may expand to a lot\n *  of output ranges.  The current algorithm creates the canonicalized ranges\n *  footprint efficiently at the cost of compile time execution time; see\n *  doc/regexp.rst for discussion, and some more details below.\n *\n *  Note that the ctx->nranges is a context-wide temporary value.  This is OK\n *  because there cannot be multiple character classes being parsed\n *  simultaneously.\n *\n *  More detail on canonicalization:\n *\n *  Conceptually, a range is canonicalized by scanning the entire range,\n *  normalizing each codepoint by converting it to uppercase, and generating\n *  a set of result ranges.\n *\n *  Ideally a minimal set of output ranges would be emitted by merging all\n *  possible ranges even if they're emitted out of sequence.  Because the\n *  input string is also case normalized during matching, some codepoints\n *  never occur at runtime; these \"don't care\" codepoints can be included or\n *  excluded from ranges when merging/optimizing ranges.\n *\n *  The current algorithm does not do optimal range merging.  Rather, output\n *  codepoints are generated in sequence, and when the output codepoints are\n *  continuous (CP, CP+1, CP+2, ...), they are merged locally into as large a\n *  range as possible.  A small canonicalization bitmap is used to reduce\n *  actual codepoint canonicalizations which are quite slow at present.  The\n *  bitmap provides a \"codepoint block is continuous with respect to\n *  canonicalization\" for N-codepoint blocks.  This allows blocks to be\n *  skipped quickly.\n *\n *  There are a number of shortcomings and future work here:\n *\n *    - Individual codepoint normalizations are slow because they involve\n *      walking bit-packed rules without a lookup index.\n *\n *    - The conceptual algorithm needs to canonicalize every codepoint in the\n *      input range to figure out the output range(s).  Even with the small\n *      canonicalization bitmap the algorithm runs quite slowly for worst case\n *      inputs.  There are many data structure alternatives to improve this.\n *\n *    - While the current algorithm generates maximal output ranges when the\n *      output codepoints are emitted linearly, output ranges are not sorted or\n *      merged otherwise.  In the worst case a lot of ranges are emitted when\n *      most of the ranges could be merged.  In this process one could take\n *      advantage of \"don't care\" codepoints, which are never matched against at\n *      runtime due to canonicalization of input codepoints before comparison,\n *      to merge otherwise discontinuous output ranges.\n *\n *    - The runtime data structure is just a linear list of ranges to match\n *      against.  This can be quite slow if there are a lot of output ranges.\n *      There are various ways to make matching against the ranges faster,\n *      e.g. sorting the ranges and using a binary search; skip lists; tree\n *      based representations; full or approximate codepoint bitmaps, etc.\n *\n *    - Only BMP is supported, codepoints above BMP are assumed to canonicalize\n *      to themselves.  For now this is one place where we don't want to\n *      support chars outside the BMP, because the exhaustive search would be\n *      massively larger.  It would be possible to support non-BMP with a\n *      different algorithm, or perhaps doing case normalization only at match\n *      time.\n */\n\nDUK_LOCAL void duk__regexp_emit_range(duk_re_compiler_ctx *re_ctx, duk_codepoint_t r1, duk_codepoint_t r2) {\n\tDUK_ASSERT(r2 >= r1);\n\tduk__append_u32(re_ctx, (duk_uint32_t) r1);\n\tduk__append_u32(re_ctx, (duk_uint32_t) r2);\n\tre_ctx->nranges++;\n}\n\n#if defined(DUK_USE_REGEXP_CANON_BITMAP)\n/* Find next canonicalization discontinuity (conservative estimate) starting\n * from 'start', not exceeding 'end'.  If continuity is fine up to 'end'\n * inclusive, returns end.  Minimum possible return value is start.\n */\nDUK_LOCAL duk_codepoint_t duk__re_canon_next_discontinuity(duk_codepoint_t start, duk_codepoint_t end) {\n\tduk_uint_t start_blk;\n\tduk_uint_t end_blk;\n\tduk_uint_t blk;\n\tduk_uint_t offset;\n\tduk_uint8_t mask;\n\n\t/* Inclusive block range. */\n\tDUK_ASSERT(start >= 0);\n\tDUK_ASSERT(end >= 0);\n\tDUK_ASSERT(end >= start);\n\tstart_blk = (duk_uint_t) (start >> DUK_CANON_BITMAP_BLKSHIFT);\n\tend_blk = (duk_uint_t) (end >> DUK_CANON_BITMAP_BLKSHIFT);\n\n\tfor (blk = start_blk; blk <= end_blk; blk++) {\n\t\toffset = blk >> 3;\n\t\tmask = 1U << (blk & 0x07);\n\t\tif (offset >= sizeof(duk_unicode_re_canon_bitmap)) {\n\t\t\t/* Reached non-BMP range which is assumed continuous. */\n\t\t\treturn end;\n\t\t}\n\t\tDUK_ASSERT(offset < sizeof(duk_unicode_re_canon_bitmap));\n\t\tif ((duk_unicode_re_canon_bitmap[offset] & mask) == 0) {\n\t\t\t/* Block is discontinuous, continuity is guaranteed\n\t\t\t * only up to end of previous block (+1 for exclusive\n\t\t\t * return value => start of current block).  Start\n\t\t\t * block requires special handling.\n\t\t\t */\n\t\t\tif (blk > start_blk) {\n\t\t\t\treturn (duk_codepoint_t) (blk << DUK_CANON_BITMAP_BLKSHIFT);\n\t\t\t} else {\n\t\t\t\treturn start;\n\t\t\t}\n\t\t}\n\t}\n\tDUK_ASSERT(blk == end_blk + 1);  /* Reached end block which is continuous. */\n\treturn end;\n}\n#else  /* DUK_USE_REGEXP_CANON_BITMAP */\nDUK_LOCAL duk_codepoint_t duk__re_canon_next_discontinuity(duk_codepoint_t start, duk_codepoint_t end) {\n\tDUK_ASSERT(start >= 0);\n\tDUK_ASSERT(end >= 0);\n\tDUK_ASSERT(end >= start);\n\tif (start >= 0x10000) {\n\t\t/* Even without the bitmap, treat non-BMP as continuous. */\n\t\treturn end;\n\t}\n\treturn start;\n}\n#endif  /* DUK_USE_REGEXP_CANON_BITMAP */\n\nDUK_LOCAL void duk__regexp_generate_ranges(void *userdata, duk_codepoint_t r1, duk_codepoint_t r2, duk_bool_t direct) {\n\tduk_re_compiler_ctx *re_ctx = (duk_re_compiler_ctx *) userdata;\n\tduk_codepoint_t r_start;\n\tduk_codepoint_t r_end;\n\tduk_codepoint_t i;\n\tduk_codepoint_t t;\n\tduk_codepoint_t r_disc;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__regexp_generate_ranges(): re_ctx=%p, range=[%ld,%ld] direct=%ld\",\n\t                   (void *) re_ctx, (long) r1, (long) r2, (long) direct));\n\n\tDUK_ASSERT(r2 >= r1);  /* SyntaxError for out of order range. */\n\n\tif (direct || (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) == 0) {\n\t\tDUK_DD(DUK_DDPRINT(\"direct or not case sensitive, emit range: [%ld,%ld]\", (long) r1, (long) r2));\n\t\tduk__regexp_emit_range(re_ctx, r1, r2);\n\t\treturn;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"case sensitive, process range: [%ld,%ld]\", (long) r1, (long) r2));\n\n\tr_start = duk_unicode_re_canonicalize_char(re_ctx->thr, r1);\n\tr_end = r_start;\n\n\tfor (i = r1 + 1; i <= r2;) {\n\t\t/* Input codepoint space processed up to i-1, and\n\t\t * current range in r_{start,end} is up-to-date\n\t\t * (inclusive) and may either break or continue.\n\t\t */\n\t\tr_disc = duk__re_canon_next_discontinuity(i, r2);\n\t\tDUK_ASSERT(r_disc >= i);\n\t\tDUK_ASSERT(r_disc <= r2);\n\n\t\tr_end += r_disc - i;  /* May be zero. */\n\t\tt = duk_unicode_re_canonicalize_char(re_ctx->thr, r_disc);\n\t\tif (t == r_end + 1) {\n\t\t\t/* Not actually a discontinuity, continue range\n\t\t\t * to r_disc and recheck.\n\t\t\t */\n\t\t\tr_end = t;\n\t\t} else {\n\t\t\tduk__regexp_emit_range(re_ctx, r_start, r_end);\n\t\t\tr_start = t;\n\t\t\tr_end = t;\n\t\t}\n\t\ti = r_disc + 1;  /* Guarantees progress. */\n\t}\n\tduk__regexp_emit_range(re_ctx, r_start, r_end);\n\n#if 0  /* Exhaustive search, very slow. */\n\tr_start = duk_unicode_re_canonicalize_char(re_ctx->thr, r1);\n\tr_end = r_start;\n\tfor (i = r1 + 1; i <= r2; i++) {\n\t\tt = duk_unicode_re_canonicalize_char(re_ctx->thr, i);\n\t\tif (t == r_end + 1) {\n\t\t\tr_end = t;\n\t\t} else {\n\t\t\tDUK_DD(DUK_DDPRINT(\"canonicalized, emit range: [%ld,%ld]\", (long) r_start, (long) r_end));\n\t\t\tduk__append_u32(re_ctx, (duk_uint32_t) r_start);\n\t\t\tduk__append_u32(re_ctx, (duk_uint32_t) r_end);\n\t\t\tre_ctx->nranges++;\n\t\t\tr_start = t;\n\t\t\tr_end = t;\n\t\t}\n\t}\n\tDUK_DD(DUK_DDPRINT(\"canonicalized, emit range: [%ld,%ld]\", (long) r_start, (long) r_end));\n\tduk__append_u32(re_ctx, (duk_uint32_t) r_start);\n\tduk__append_u32(re_ctx, (duk_uint32_t) r_end);\n\tre_ctx->nranges++;\n#endif\n}\n\n/*\n *  Parse regexp Disjunction.  Most of regexp compilation happens here.\n *\n *  Handles Disjunction, Alternative, and Term productions directly without\n *  recursion.  The only constructs requiring recursion are positive/negative\n *  lookaheads, capturing parentheses, and non-capturing parentheses.\n *\n *  The function determines whether the entire disjunction is a 'simple atom'\n *  (see doc/regexp.rst discussion on 'simple quantifiers') and if so,\n *  returns the atom character length which is needed by the caller to keep\n *  track of its own atom character length.  A disjunction with more than one\n *  alternative is never considered a simple atom (although in some cases\n *  that might be the case).\n *\n *  Return value: simple atom character length or < 0 if not a simple atom.\n *  Appends the bytecode for the disjunction matcher to the end of the temp\n *  buffer.\n *\n *  Regexp top level structure is:\n *\n *    Disjunction = Term*\n *                | Term* | Disjunction\n *\n *    Term = Assertion\n *         | Atom\n *         | Atom Quantifier\n *\n *  An empty Term sequence is a valid disjunction alternative (e.g. /|||c||/).\n *\n *  Notes:\n *\n *    * Tracking of the 'simple-ness' of the current atom vs. the entire\n *      disjunction are separate matters.  For instance, the disjunction\n *      may be complex, but individual atoms may be simple.  Furthermore,\n *      simple quantifiers are used whenever possible, even if the\n *      disjunction as a whole is complex.\n *\n *    * The estimate of whether an atom is simple is conservative now,\n *      and it would be possible to expand it.  For instance, captures\n *      cause the disjunction to be marked complex, even though captures\n *      -can- be handled by simple quantifiers with some minor modifications.\n *\n *    * Disjunction 'tainting' as 'complex' is handled at the end of the\n *      main for loop collectively for atoms.  Assertions, quantifiers,\n *      and '|' tokens need to taint the result manually if necessary.\n *      Assertions cannot add to result char length, only atoms (and\n *      quantifiers) can; currently quantifiers will taint the result\n *      as complex though.\n */\n\nDUK_LOCAL const duk_uint16_t * const duk__re_range_lookup1[3] = {\n\tduk_unicode_re_ranges_digit,\n\tduk_unicode_re_ranges_white,\n\tduk_unicode_re_ranges_wordchar\n};\nDUK_LOCAL const duk_uint8_t duk__re_range_lookup2[3] = {\n\tsizeof(duk_unicode_re_ranges_digit) / (2 * sizeof(duk_uint16_t)),\n\tsizeof(duk_unicode_re_ranges_white) / (2 * sizeof(duk_uint16_t)),\n\tsizeof(duk_unicode_re_ranges_wordchar) / (2 * sizeof(duk_uint16_t))\n};\n\nDUK_LOCAL void duk__append_range_atom_matcher(duk_re_compiler_ctx *re_ctx, duk_small_uint_t re_op, const duk_uint16_t *ranges, duk_small_uint_t count) {\n#if 0\n\tDUK_ASSERT(re_op <= 0x7fUL);\n\tDUK_ASSERT(count <= 0x7fUL);\n\tduk__append_2bytes(re_ctx, (duk_uint8_t) re_op, (duk_uint8_t) count);\n#endif\n\tduk__append_reop(re_ctx, re_op);\n\tduk__append_7bit(re_ctx, count);\n\tduk__append_u16_list(re_ctx, ranges, count * 2);\n}\n\nDUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t expect_eof, duk__re_disjunction_info *out_atom_info) {\n\tduk_int32_t atom_start_offset = -1;                   /* negative -> no atom matched on previous round */\n\tduk_int32_t atom_char_length = 0;                     /* negative -> complex atom */\n\tduk_uint32_t atom_start_captures = re_ctx->captures;  /* value of re_ctx->captures at start of atom */\n\tduk_int32_t unpatched_disjunction_split = -1;\n\tduk_int32_t unpatched_disjunction_jump = -1;\n\tduk_uint32_t entry_offset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);\n\tduk_int32_t res_charlen = 0;  /* -1 if disjunction is complex, char length if simple */\n\tduk__re_disjunction_info tmp_disj;\n\n\tDUK_ASSERT(out_atom_info != NULL);\n\n\tduk_native_stack_check(re_ctx->thr);\n\tif (re_ctx->recursion_depth >= re_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_COMPILER_RECURSION_LIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tre_ctx->recursion_depth++;\n\n#if 0\n\tout_atom_info->start_captures = re_ctx->captures;\n#endif\n\n\tfor (;;) {\n\t\t/* atom_char_length, atom_start_offset, atom_start_offset reflect the\n\t\t * atom matched on the previous loop.  If a quantifier is encountered\n\t\t * on this loop, these are needed to handle the quantifier correctly.\n\t\t * new_atom_char_length etc are for the atom parsed on this round;\n\t\t * they're written to atom_char_length etc at the end of the round.\n\t\t */\n\t\tduk_int32_t new_atom_char_length;   /* char length of the atom parsed in this loop */\n\t\tduk_int32_t new_atom_start_offset;  /* bytecode start offset of the atom parsed in this loop\n\t\t                                     * (allows quantifiers to copy the atom bytecode)\n\t\t                                     */\n\t\tduk_uint32_t new_atom_start_captures;  /* re_ctx->captures at the start of the atom parsed in this loop */\n\n\t\tduk_lexer_parse_re_token(&re_ctx->lex, &re_ctx->curr_token);\n\n\t\tDUK_DD(DUK_DDPRINT(\"re token: %ld (num=%ld, char=%c)\",\n\t\t                   (long) re_ctx->curr_token.t,\n\t\t                   (long) re_ctx->curr_token.num,\n\t\t                   (re_ctx->curr_token.num >= 0x20 && re_ctx->curr_token.num <= 0x7e) ?\n\t\t                   (int) re_ctx->curr_token.num : (int) '?'));\n\n\t\t/* set by atom case clauses */\n\t\tnew_atom_start_offset = -1;\n\t\tnew_atom_char_length = -1;\n\t\tnew_atom_start_captures = re_ctx->captures;\n\n\t\tswitch (re_ctx->curr_token.t) {\n\t\tcase DUK_RETOK_DISJUNCTION: {\n\t\t\t/*\n\t\t\t *  The handling here is a bit tricky.  If a previous '|' has been processed,\n\t\t\t *  we have a pending split1 and a pending jump (for a previous match).  These\n\t\t\t *  need to be back-patched carefully.  See docs for a detailed example.\n\t\t\t */\n\n\t\t\t/* patch pending jump and split */\n\t\t\tif (unpatched_disjunction_jump >= 0) {\n\t\t\t\tduk_uint32_t offset;\n\n\t\t\t\tDUK_ASSERT(unpatched_disjunction_split >= 0);\n\t\t\t\toffset = (duk_uint32_t) unpatched_disjunction_jump;\n\t\t\t\toffset += duk__insert_jump_offset(re_ctx,\n\t\t\t\t                                  offset,\n\t\t\t\t                                  (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - offset));\n\t\t\t\t/* offset is now target of the pending split (right after jump) */\n\t\t\t\tduk__insert_jump_offset(re_ctx,\n\t\t\t\t                        (duk_uint32_t) unpatched_disjunction_split,\n\t\t\t\t                        (duk_int32_t) offset - unpatched_disjunction_split);\n\t\t\t}\n\n\t\t\t/* add a new pending split to the beginning of the entire disjunction */\n\t\t\t(void) duk__insert_u32(re_ctx,\n\t\t\t                       entry_offset,\n\t\t\t                       DUK_REOP_SPLIT1);   /* prefer direct execution */\n\t\t\tunpatched_disjunction_split = (duk_int32_t) (entry_offset + 1);   /* +1 for opcode */\n\n\t\t\t/* add a new pending match jump for latest finished alternative */\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_JUMP);\n\t\t\tunpatched_disjunction_jump = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\n\t\t\t/* 'taint' result as complex */\n\t\t\tres_charlen = -1;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_QUANTIFIER: {\n\t\t\tif (atom_start_offset < 0) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_INVALID_QUANTIFIER_NO_ATOM);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tif (re_ctx->curr_token.qmin > re_ctx->curr_token.qmax) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_INVALID_QUANTIFIER_VALUES);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tif (atom_char_length >= 0) {\n\t\t\t\t/*\n\t\t\t\t *  Simple atom\n\t\t\t\t *\n\t\t\t\t *  If atom_char_length is zero, we'll have unbounded execution time for e.g.\n\t\t\t\t *  /()*x/.exec('x').  We can't just skip the match because it might have some\n\t\t\t\t *  side effects (for instance, if we allowed captures in simple atoms, the\n\t\t\t\t *  capture needs to happen).  The simple solution below is to force the\n\t\t\t\t *  quantifier to match at most once, since the additional matches have no effect.\n\t\t\t\t *\n\t\t\t\t *  With a simple atom there can be no capture groups, so no captures need\n\t\t\t\t *  to be reset.\n\t\t\t\t */\n\t\t\t\tduk_int32_t atom_code_length;\n\t\t\t\tduk_uint32_t offset;\n\t\t\t\tduk_uint32_t qmin, qmax;\n\n\t\t\t\tqmin = re_ctx->curr_token.qmin;\n\t\t\t\tqmax = re_ctx->curr_token.qmax;\n\t\t\t\tif (atom_char_length == 0) {\n\t\t\t\t\t/* qmin and qmax will be 0 or 1 */\n\t\t\t\t\tif (qmin > 1) {\n\t\t\t\t\t\tqmin = 1;\n\t\t\t\t\t}\n\t\t\t\t\tif (qmax > 1) {\n\t\t\t\t\t\tqmax = 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_MATCH);   /* complete 'sub atom' */\n\t\t\t\tatom_code_length = (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (duk_size_t) atom_start_offset);\n\n\t\t\t\toffset = (duk_uint32_t) atom_start_offset;\n\t\t\t\tif (re_ctx->curr_token.greedy) {\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, DUK_REOP_SQGREEDY);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmin);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmax);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, (duk_uint32_t) atom_char_length);\n\t\t\t\t\toffset += duk__insert_jump_offset(re_ctx, offset, atom_code_length);\n\t\t\t\t} else {\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, DUK_REOP_SQMINIMAL);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmin);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmax);\n\t\t\t\t\toffset += duk__insert_jump_offset(re_ctx, offset, atom_code_length);\n\t\t\t\t}\n\t\t\t\tDUK_UNREF(offset);  /* silence scan-build warning */\n\t\t\t} else {\n\t\t\t\t/*\n\t\t\t\t *  Complex atom\n\t\t\t\t *\n\t\t\t\t *  The original code is used as a template, and removed at the end\n\t\t\t\t *  (this differs from the handling of simple quantifiers).\n\t\t\t\t *\n\t\t\t\t *  NOTE: there is no current solution for empty atoms in complex\n\t\t\t\t *  quantifiers.  This would need some sort of a 'progress' instruction.\n\t\t\t\t *\n\t\t\t\t *  XXX: impose limit on maximum result size, i.e. atom_code_len * atom_copies?\n\t\t\t\t */\n\t\t\t\tduk_int32_t atom_code_length;\n\t\t\t\tduk_uint32_t atom_copies;\n\t\t\t\tduk_uint32_t tmp_qmin, tmp_qmax;\n\n\t\t\t\t/* pre-check how many atom copies we're willing to make (atom_copies not needed below) */\n\t\t\t\tatom_copies = (re_ctx->curr_token.qmax == DUK_RE_QUANTIFIER_INFINITE) ?\n\t\t\t\t              re_ctx->curr_token.qmin : re_ctx->curr_token.qmax;\n\t\t\t\tif (atom_copies > DUK_RE_MAX_ATOM_COPIES) {\n\t\t\t\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_QUANTIFIER_TOO_MANY_COPIES);\n\t\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t\t}\n\n\t\t\t\t/* wipe the capture range made by the atom (if any) */\n\t\t\t\tDUK_ASSERT(atom_start_captures <= re_ctx->captures);\n\t\t\t\tif (atom_start_captures != re_ctx->captures) {\n\t\t\t\t\tDUK_ASSERT(atom_start_captures < re_ctx->captures);\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"must wipe ]atom_start_captures,re_ctx->captures]: ]%ld,%ld]\",\n\t\t\t\t\t                     (long) atom_start_captures, (long) re_ctx->captures));\n\n\t\t\t\t\t/* insert (DUK_REOP_WIPERANGE, start, count) in reverse order so the order ends up right */\n\t\t\t\t\tduk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, (re_ctx->captures - atom_start_captures) * 2U);\n\t\t\t\t\tduk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, (atom_start_captures + 1) * 2);\n\t\t\t\t\tduk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, DUK_REOP_WIPERANGE);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"no need to wipe captures: atom_start_captures == re_ctx->captures == %ld\",\n\t\t\t\t\t                     (long) atom_start_captures));\n\t\t\t\t}\n\n\t\t\t\tatom_code_length = (duk_int32_t) DUK__RE_BUFLEN(re_ctx) - atom_start_offset;\n\n\t\t\t\t/* insert the required matches (qmin) by copying the atom */\n\t\t\t\ttmp_qmin = re_ctx->curr_token.qmin;\n\t\t\t\ttmp_qmax = re_ctx->curr_token.qmax;\n\t\t\t\twhile (tmp_qmin > 0) {\n\t\t\t\t\tduk__append_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t\t\ttmp_qmin--;\n\t\t\t\t\tif (tmp_qmax != DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\t\ttmp_qmax--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(tmp_qmin == 0);\n\n\t\t\t\t/* insert code for matching the remainder - infinite or finite */\n\t\t\t\tif (tmp_qmax == DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\t/* reuse last emitted atom for remaining 'infinite' quantifier */\n\n\t\t\t\t\tif (re_ctx->curr_token.qmin == 0) {\n\t\t\t\t\t\t/* Special case: original qmin was zero so there is nothing\n\t\t\t\t\t\t * to repeat.  Emit an atom copy but jump over it here.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_JUMP);\n\t\t\t\t\t\tduk__append_jump_offset(re_ctx, atom_code_length);\n\t\t\t\t\t\tduk__append_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t\t\t}\n\t\t\t\t\tif (re_ctx->curr_token.greedy) {\n\t\t\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_SPLIT2);   /* prefer jump */\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_SPLIT1);   /* prefer direct */\n\t\t\t\t\t}\n\t\t\t\t\tduk__append_jump_offset(re_ctx, -atom_code_length - 1);  /* -1 for opcode */\n\t\t\t\t} else {\n\t\t\t\t\t/*\n\t\t\t\t\t *  The remaining matches are emitted as sequence of SPLITs and atom\n\t\t\t\t\t *  copies; the SPLITs skip the remaining copies and match the sequel.\n\t\t\t\t\t *  This sequence needs to be emitted starting from the last copy\n\t\t\t\t\t *  because the SPLITs are variable length due to the variable length\n\t\t\t\t\t *  skip offset.  This causes a lot of memory copying now.\n\t\t\t\t\t *\n\t\t\t\t\t *  Example structure (greedy, match maximum # atoms):\n\t\t\t\t\t *\n\t\t\t\t\t *      SPLIT1 LSEQ\n\t\t\t\t\t *      (atom)\n\t\t\t\t\t *      SPLIT1 LSEQ    ; <- the byte length of this instruction is needed\n\t\t\t\t\t *      (atom)         ; to encode the above SPLIT1 correctly\n\t\t\t\t\t *      ...\n\t\t\t\t\t *   LSEQ:\n\t\t\t\t\t */\n\t\t\t\t\tduk_uint32_t offset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\t\t\twhile (tmp_qmax > 0) {\n\t\t\t\t\t\tduk__insert_slice(re_ctx, offset, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t\t\t\tif (re_ctx->curr_token.greedy) {\n\t\t\t\t\t\t\tduk__insert_u32(re_ctx, offset, DUK_REOP_SPLIT1);   /* prefer direct */\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tduk__insert_u32(re_ctx, offset, DUK_REOP_SPLIT2);   /* prefer jump */\n\t\t\t\t\t\t}\n\t\t\t\t\t\tduk__insert_jump_offset(re_ctx,\n\t\t\t\t\t\t                        offset + 1,   /* +1 for opcode */\n\t\t\t\t\t\t                        (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (offset + 1)));\n\t\t\t\t\t\ttmp_qmax--;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* remove the original 'template' atom */\n\t\t\t\tduk__remove_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t}\n\n\t\t\t/* 'taint' result as complex */\n\t\t\tres_charlen = -1;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_START: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_START);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_END: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_END);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_WORD_BOUNDARY: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_WORD_BOUNDARY);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_NOT_WORD_BOUNDARY);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_START_POS_LOOKAHEAD:\n\t\tcase DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD: {\n\t\t\tduk_uint32_t offset;\n\t\t\tduk_uint32_t opcode = (re_ctx->curr_token.t == DUK_RETOK_ASSERT_START_POS_LOOKAHEAD) ?\n\t\t\t                      DUK_REOP_LOOKPOS : DUK_REOP_LOOKNEG;\n\n\t\t\toffset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__parse_disjunction(re_ctx, 0, &tmp_disj);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_MATCH);\n\n\t\t\t(void) duk__insert_u32(re_ctx, offset, opcode);\n\t\t\t(void) duk__insert_jump_offset(re_ctx,\n\t\t\t                               offset + 1,   /* +1 for opcode */\n\t\t\t                               (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (offset + 1)));\n\n\t\t\t/* 'taint' result as complex -- this is conservative,\n\t\t\t * as lookaheads do not backtrack.\n\t\t\t */\n\t\t\tres_charlen = -1;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_PERIOD: {\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_PERIOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_CHAR: {\n\t\t\t/* Note: successive characters could be joined into string matches\n\t\t\t * but this is not trivial (consider e.g. '/xyz+/); see docs for\n\t\t\t * more discussion.\n\t\t\t *\n\t\t\t * No support for \\u{H+} yet.  While only BMP Unicode escapes are\n\t\t\t * supported for RegExps at present, 'ch' may still be a non-BMP\n\t\t\t * codepoint if it is decoded straight from source text UTF-8.\n\t\t\t * There's no non-BMP support yet so this is handled simply by\n\t\t\t * matching the non-BMP character (which is custom behavior).\n\t\t\t */\n\t\t\tduk_uint32_t ch;\n\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_CHAR);\n\t\t\tch = re_ctx->curr_token.num;\n\t\t\tif (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) {\n\t\t\t\tch = (duk_uint32_t) duk_unicode_re_canonicalize_char(re_ctx->thr, (duk_codepoint_t) ch);\n\t\t\t}\n\t\t\tduk__append_u32(re_ctx, ch);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_DIGIT:\n\t\tcase DUK_RETOK_ATOM_NOT_DIGIT:\n\t\tcase DUK_RETOK_ATOM_WHITE:\n\t\tcase DUK_RETOK_ATOM_NOT_WHITE:\n\t\tcase DUK_RETOK_ATOM_WORD_CHAR:\n\t\tcase DUK_RETOK_ATOM_NOT_WORD_CHAR: {\n\t\t\tduk_small_uint_t re_op;\n\t\t\tduk_small_uint_t idx;\n\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_DIGIT & 0x01) != 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_WHITE & 0x01) != 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_WORD_CHAR & 0x01) != 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_NOT_DIGIT & 0x01) == 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_NOT_WHITE & 0x01) == 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_NOT_WORD_CHAR & 0x01) == 0);\n\t\t\tre_op = (re_ctx->curr_token.t & 0x01) ? DUK_REOP_RANGES : DUK_REOP_INVRANGES;\n\n\t\t\tDUK_ASSERT(DUK_RETOK_ATOM_WHITE == DUK_RETOK_ATOM_DIGIT + 2);\n\t\t\tDUK_ASSERT(DUK_RETOK_ATOM_WORD_CHAR == DUK_RETOK_ATOM_DIGIT + 4);\n\t\t\tidx = (duk_small_uint_t) ((re_ctx->curr_token.t - DUK_RETOK_ATOM_DIGIT) >> 1U);\n\t\t\tDUK_ASSERT(idx <= 2U);  /* Assume continuous token numbers; also checks negative underflow. */\n\n\t\t\tduk__append_range_atom_matcher(re_ctx, re_op, duk__re_range_lookup1[idx], duk__re_range_lookup2[idx]);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_BACKREFERENCE: {\n\t\t\tduk_uint32_t backref = (duk_uint32_t) re_ctx->curr_token.num;\n\t\t\tif (backref > re_ctx->highest_backref) {\n\t\t\t\tre_ctx->highest_backref = backref;\n\t\t\t}\n\t\t\tnew_atom_char_length = -1;   /* mark as complex */\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_BACKREFERENCE);\n\t\t\tduk__append_u32(re_ctx, backref);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_START_CAPTURE_GROUP: {\n\t\t\tduk_uint32_t cap;\n\n\t\t\tnew_atom_char_length = -1;   /* mark as complex (capture handling) */\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tcap = ++re_ctx->captures;\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_SAVE);\n\t\t\tduk__append_u32(re_ctx, cap * 2);\n\t\t\tduk__parse_disjunction(re_ctx, 0, &tmp_disj);  /* retval (sub-atom char length) unused, tainted as complex above */\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_SAVE);\n\t\t\tduk__append_u32(re_ctx, cap * 2 + 1);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_START_NONCAPTURE_GROUP: {\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__parse_disjunction(re_ctx, 0, &tmp_disj);\n\t\t\tnew_atom_char_length = tmp_disj.charlen;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_START_CHARCLASS:\n\t\tcase DUK_RETOK_ATOM_START_CHARCLASS_INVERTED: {\n\t\t\t/*\n\t\t\t *  Range parsing is done with a special lexer function which calls\n\t\t\t *  us for every range parsed.  This is different from how rest of\n\t\t\t *  the parsing works, but avoids a heavy, arbitrary size intermediate\n\t\t\t *  value type to hold the ranges.\n\t\t\t *\n\t\t\t *  Another complication is the handling of character ranges when\n\t\t\t *  case insensitive matching is used (see docs for discussion).\n\t\t\t *  The range handler callback given to the lexer takes care of this\n\t\t\t *  as well.\n\t\t\t *\n\t\t\t *  Note that duplicate ranges are not eliminated when parsing character\n\t\t\t *  classes, so that canonicalization of\n\t\t\t *\n\t\t\t *    [0-9a-fA-Fx-{]\n\t\t\t *\n\t\t\t *  creates the result (note the duplicate ranges):\n\t\t\t *\n\t\t\t *    [0-9A-FA-FX-Z{-{]\n\t\t\t *\n\t\t\t *  where [x-{] is split as a result of canonicalization.  The duplicate\n\t\t\t *  ranges are not a semantics issue: they work correctly.\n\t\t\t */\n\n\t\t\tduk_uint32_t offset;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"character class\"));\n\n\t\t\t/* insert ranges instruction, range count patched in later */\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx,\n\t\t\t                 (re_ctx->curr_token.t == DUK_RETOK_ATOM_START_CHARCLASS) ?\n\t\t\t                 DUK_REOP_RANGES : DUK_REOP_INVRANGES);\n\t\t\toffset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);    /* patch in range count later */\n\n\t\t\t/* parse ranges until character class ends */\n\t\t\tre_ctx->nranges = 0;    /* note: ctx-wide temporary */\n\t\t\tduk_lexer_parse_re_ranges(&re_ctx->lex, duk__regexp_generate_ranges, (void *) re_ctx);\n\n\t\t\t/* insert range count */\n\t\t\tduk__insert_u32(re_ctx, offset, re_ctx->nranges);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_END_GROUP: {\n\t\t\tif (expect_eof) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_CLOSING_PAREN);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tgoto done;\n\t\t}\n\t\tcase DUK_RETOK_EOF: {\n\t\t\tif (!expect_eof) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_END_OF_PATTERN);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tgoto done;\n\t\t}\n\t\tdefault: {\n\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_REGEXP_TOKEN);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\t}\n\n\t\t/* a complex (new) atom taints the result */\n\t\tif (new_atom_start_offset >= 0) {\n\t\t\tif (new_atom_char_length < 0) {\n\t\t\t\tres_charlen = -1;\n\t\t\t} else if (res_charlen >= 0) {\n\t\t\t\t/* only advance if not tainted */\n\t\t\t\tres_charlen += new_atom_char_length;\n\t\t\t}\n\t\t}\n\n\t\t/* record previous atom info in case next token is a quantifier */\n\t\tatom_start_offset = new_atom_start_offset;\n\t\tatom_char_length = new_atom_char_length;\n\t\tatom_start_captures = new_atom_start_captures;\n\t}\n\n done:\n\n\t/* finish up pending jump and split for last alternative */\n\tif (unpatched_disjunction_jump >= 0) {\n\t\tduk_uint32_t offset;\n\n\t\tDUK_ASSERT(unpatched_disjunction_split >= 0);\n\t\toffset = (duk_uint32_t) unpatched_disjunction_jump;\n\t\toffset += duk__insert_jump_offset(re_ctx,\n\t\t                                  offset,\n\t\t                                  (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - offset));\n\t\t/* offset is now target of the pending split (right after jump) */\n\t\tduk__insert_jump_offset(re_ctx,\n\t\t                        (duk_uint32_t) unpatched_disjunction_split,\n\t\t                        (duk_int32_t) offset - unpatched_disjunction_split);\n\t}\n\n#if 0\n\tout_atom_info->end_captures = re_ctx->captures;\n#endif\n\tout_atom_info->charlen = res_charlen;\n\tDUK_DDD(DUK_DDDPRINT(\"parse disjunction finished: charlen=%ld\",\n\t                     (long) out_atom_info->charlen));\n\n\tre_ctx->recursion_depth--;\n}\n\n/*\n *  Flags parsing (see E5 Section 15.10.4.1).\n */\n\nDUK_LOCAL duk_uint32_t duk__parse_regexp_flags(duk_hthread *thr, duk_hstring *h) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint32_t flags = 0;\n\n\tp = DUK_HSTRING_GET_DATA(h);\n\tp_end = p + DUK_HSTRING_GET_BYTELEN(h);\n\n\t/* Note: can be safely scanned as bytes (undecoded) */\n\n\twhile (p < p_end) {\n\t\tduk_uint8_t c = *p++;\n\t\tswitch (c) {\n\t\tcase (duk_uint8_t) 'g': {\n\t\t\tif (flags & DUK_RE_FLAG_GLOBAL) {\n\t\t\t\tgoto flags_error;\n\t\t\t}\n\t\t\tflags |= DUK_RE_FLAG_GLOBAL;\n\t\t\tbreak;\n\t\t}\n\t\tcase (duk_uint8_t) 'i': {\n\t\t\tif (flags & DUK_RE_FLAG_IGNORE_CASE) {\n\t\t\t\tgoto flags_error;\n\t\t\t}\n\t\t\tflags |= DUK_RE_FLAG_IGNORE_CASE;\n\t\t\tbreak;\n\t\t}\n\t\tcase (duk_uint8_t) 'm': {\n\t\t\tif (flags & DUK_RE_FLAG_MULTILINE) {\n\t\t\t\tgoto flags_error;\n\t\t\t}\n\t\t\tflags |= DUK_RE_FLAG_MULTILINE;\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tgoto flags_error;\n\t\t}\n\t\t}\n\t}\n\n\treturn flags;\n\n flags_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_REGEXP_FLAGS);\n\tDUK_WO_NORETURN(return 0U;);\n}\n\n/*\n *  Create escaped RegExp source (E5 Section 15.10.3).\n *\n *  The current approach is to special case the empty RegExp\n *  ('' -> '(?:)') and otherwise replace unescaped '/' characters\n *  with '\\/' regardless of where they occur in the regexp.\n *\n *  Note that normalization does not seem to be necessary for\n *  RegExp literals (e.g. '/foo/') because to be acceptable as\n *  a RegExp literal, the text between forward slashes must\n *  already match the escaping requirements (e.g. must not contain\n *  unescaped forward slashes or be empty).  Escaping IS needed\n *  for expressions like 'new Regexp(\"...\", \"\")' however.\n *  Currently, we re-escape in either case.\n *\n *  Also note that we process the source here in UTF-8 encoded\n *  form.  This is correct, because any non-ASCII characters are\n *  passed through without change.\n */\n\nDUK_LOCAL void duk__create_escaped_source(duk_hthread *thr, int idx_pattern) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tduk_uint8_t *q;\n\tduk_size_t i, n;\n\tduk_uint_fast8_t c_prev, c;\n\n\th = duk_known_hstring(thr, idx_pattern);\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tn = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);\n\n\tif (n == 0) {\n\t\tduk_push_literal(thr, \"(?:)\");\n\t\treturn;\n\t}\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, n);\n\tq = DUK_BW_GET_PTR(thr, bw);\n\n\tc_prev = (duk_uint_fast8_t) 0;\n\n\tfor (i = 0; i < n; i++) {\n\t\tc = p[i];\n\n\t\tq = DUK_BW_ENSURE_RAW(thr, bw, 2, q);\n\n\t\tif (c == (duk_uint_fast8_t) '/' && c_prev != (duk_uint_fast8_t) '\\\\') {\n\t\t\t/* Unescaped '/' ANYWHERE in the regexp (in disjunction,\n\t\t\t * inside a character class, ...) => same escape works.\n\t\t\t */\n\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t}\n\t\t*q++ = (duk_uint8_t) c;\n\n\t\tc_prev = c;\n\t}\n\n\tDUK_BW_SETPTR_AND_COMPACT(thr, bw, q);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if input is safe. */\n\n\t/* [ ... escaped_source ] */\n}\n\n/*\n *  Exposed regexp compilation primitive.\n *\n *  Sets up a regexp compilation context, and calls duk__parse_disjunction() to do the\n *  actual parsing.  Handles generation of the compiled regexp header and the\n *  \"boilerplate\" capture of the matching substring (save 0 and 1).  Also does some\n *  global level regexp checks after recursive compilation has finished.\n *\n *  An escaped version of the regexp source, suitable for use as a RegExp instance\n *  'source' property (see E5 Section 15.10.3), is also left on the stack.\n *\n *  Input stack:  [ pattern flags ]\n *  Output stack: [ bytecode escaped_source ]  (both as strings)\n */\n\nDUK_INTERNAL void duk_regexp_compile(duk_hthread *thr) {\n\tduk_re_compiler_ctx re_ctx;\n\tduk_lexer_point lex_point;\n\tduk_hstring *h_pattern;\n\tduk_hstring *h_flags;\n\tduk__re_disjunction_info ign_disj;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/*\n\t *  Args validation\n\t */\n\n\t/* TypeError if fails */\n\th_pattern = duk_require_hstring_notsymbol(thr, -2);\n\th_flags = duk_require_hstring_notsymbol(thr, -1);\n\n\t/*\n\t *  Create normalized 'source' property (E5 Section 15.10.3).\n\t */\n\n\t/* [ ... pattern flags ] */\n\n\tduk__create_escaped_source(thr, -2);\n\n\t/* [ ... pattern flags escaped_source ] */\n\n\t/*\n\t *  Init compilation context\n\t */\n\n\t/* [ ... pattern flags escaped_source buffer ] */\n\n\tduk_memzero(&re_ctx, sizeof(re_ctx));\n\tDUK_LEXER_INITCTX(&re_ctx.lex);  /* duplicate zeroing, expect for (possible) NULL inits */\n\tre_ctx.thr = thr;\n\tre_ctx.lex.thr = thr;\n\tre_ctx.lex.input = DUK_HSTRING_GET_DATA(h_pattern);\n\tre_ctx.lex.input_length = DUK_HSTRING_GET_BYTELEN(h_pattern);\n\tre_ctx.lex.token_limit = DUK_RE_COMPILE_TOKEN_LIMIT;\n\tre_ctx.recursion_limit = DUK_USE_REGEXP_COMPILER_RECLIMIT;\n\tre_ctx.re_flags = duk__parse_regexp_flags(thr, h_flags);\n\n\tDUK_BW_INIT_PUSHBUF(thr, &re_ctx.bw, DUK__RE_INITIAL_BUFSIZE);\n\n\tDUK_DD(DUK_DDPRINT(\"regexp compiler ctx initialized, flags=0x%08lx, recursion_limit=%ld\",\n\t                   (unsigned long) re_ctx.re_flags, (long) re_ctx.recursion_limit));\n\n\t/*\n\t *  Init lexer\n\t */\n\n\tlex_point.offset = 0;  /* expensive init, just want to fill window */\n\tlex_point.line = 1;\n\tDUK_LEXER_SETPOINT(&re_ctx.lex, &lex_point);\n\n\t/*\n\t *  Compilation\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"starting regexp compilation\"));\n\n\tduk__append_reop(&re_ctx, DUK_REOP_SAVE);\n\tduk__append_7bit(&re_ctx, 0);\n\tduk__parse_disjunction(&re_ctx, 1 /*expect_eof*/, &ign_disj);\n\tduk__append_reop(&re_ctx, DUK_REOP_SAVE);\n\tduk__append_7bit(&re_ctx, 1);\n\tduk__append_reop(&re_ctx, DUK_REOP_MATCH);\n\n\t/*\n\t *  Check for invalid backreferences; note that it is NOT an error\n\t *  to back-reference a capture group which has not yet been introduced\n\t *  in the pattern (as in /\\1(foo)/); in fact, the backreference will\n\t *  always match!  It IS an error to back-reference a capture group\n\t *  which will never be introduced in the pattern.  Thus, we can check\n\t *  for such references only after parsing is complete.\n\t */\n\n\tif (re_ctx.highest_backref > re_ctx.captures) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_BACKREFS);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/*\n\t *  Emit compiled regexp header: flags, ncaptures\n\t *  (insertion order inverted on purpose)\n\t */\n\n\tduk__insert_u32(&re_ctx, 0, (re_ctx.captures + 1) * 2);\n\tduk__insert_u32(&re_ctx, 0, re_ctx.re_flags);\n\n\t/* [ ... pattern flags escaped_source buffer ] */\n\n\tDUK_BW_COMPACT(thr, &re_ctx.bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe because flags is at most 7 bit. */\n\n\t/* [ ... pattern flags escaped_source bytecode ] */\n\n\t/*\n\t *  Finalize stack\n\t */\n\n\tduk_remove(thr, -4);     /* -> [ ... flags escaped_source bytecode ] */\n\tduk_remove(thr, -3);     /* -> [ ... escaped_source bytecode ] */\n\n\tDUK_DD(DUK_DDPRINT(\"regexp compilation successful, bytecode: %!T, escaped source: %!T\",\n\t                   (duk_tval *) duk_get_tval(thr, -1), (duk_tval *) duk_get_tval(thr, -2)));\n}\n\n/*\n *  Create a RegExp instance (E5 Section 15.10.7).\n *\n *  Note: the output stack left by duk_regexp_compile() is directly compatible\n *  with the input here.\n *\n *  Input stack:  [ escaped_source bytecode ]  (both as strings)\n *  Output stack: [ RegExp ]\n */\n\nDUK_INTERNAL void duk_regexp_create_instance(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\t/* [ ... escaped_source bytecode ] */\n\n\tduk_push_object(thr);\n\th = duk_known_hobject(thr, -1);\n\tduk_insert(thr, -3);\n\n\t/* [ ... regexp_object escaped_source bytecode ] */\n\n\tDUK_HOBJECT_SET_CLASS_NUMBER(h, DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[DUK_BIDX_REGEXP_PROTOTYPE]);\n\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_BYTECODE, DUK_PROPDESC_FLAGS_NONE);\n\n\t/* [ ... regexp_object escaped_source ] */\n\n\t/* In ES2015 .source, and the .global, .multiline, etc flags are\n\t * inherited getters.  Store the escaped source as an internal\n\t * property for the getter.\n\t */\n\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_SOURCE, DUK_PROPDESC_FLAGS_NONE);\n\n\t/* [ ... regexp_object ] */\n\n\tduk_push_int(thr, 0);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LAST_INDEX, DUK_PROPDESC_FLAGS_W);\n\n\t/* [ ... regexp_object ] */\n}\n\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\n/* regexp support disabled */\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n/* automatic undefs */\n#undef DUK__RE_BUFLEN\n#undef DUK__RE_INITIAL_BUFSIZE\n#line 1 \"duk_regexp_executor.c\"\n/*\n *  Regexp executor.\n *\n *  Safety: the ECMAScript executor should prevent user from reading and\n *  replacing regexp bytecode.  Even so, the executor must validate all\n *  memory accesses etc.  When an invalid access is detected (e.g. a 'save'\n *  opcode to invalid, unallocated index) it should fail with an internal\n *  error but not cause a segmentation fault.\n *\n *  Notes:\n *\n *    - Backtrack counts are limited to unsigned 32 bits but should\n *      technically be duk_size_t for strings longer than 4G chars.\n *      This also requires a regexp bytecode change.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Helpers for UTF-8 handling\n *\n *  For bytecode readers the duk_uint32_t and duk_int32_t types are correct\n *  because they're used for more than just codepoints.\n */\n\nDUK_LOCAL duk_uint32_t duk__bc_get_u32(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **pc) {\n\treturn (duk_uint32_t) duk_unicode_decode_xutf8_checked(re_ctx->thr, pc, re_ctx->bytecode, re_ctx->bytecode_end);\n}\n\nDUK_LOCAL duk_int32_t duk__bc_get_i32(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **pc) {\n\tduk_uint32_t t;\n\n\t/* signed integer encoding needed to work with UTF-8 */\n\tt = (duk_uint32_t) duk_unicode_decode_xutf8_checked(re_ctx->thr, pc, re_ctx->bytecode, re_ctx->bytecode_end);\n\tif (t & 1) {\n\t\treturn -((duk_int32_t) (t >> 1));\n\t} else {\n\t\treturn (duk_int32_t) (t >> 1);\n\t}\n}\n\nDUK_LOCAL const duk_uint8_t *duk__utf8_backtrack(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_uint_fast32_t count) {\n\tconst duk_uint8_t *p;\n\n\t/* Note: allow backtracking from p == ptr_end */\n\tp = *ptr;\n\tif (p < ptr_start || p > ptr_end) {\n\t\tgoto fail;\n\t}\n\n\twhile (count > 0) {\n\t\tfor (;;) {\n\t\t\tp--;\n\t\t\tif (p < ptr_start) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tif ((*p & 0xc0) != 0x80) {\n\t\t\t\t/* utf-8 continuation bytes have the form 10xx xxxx */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcount--;\n\t}\n\t*ptr = p;\n\treturn p;\n\n fail:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_LOCAL const duk_uint8_t *duk__utf8_advance(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_uint_fast32_t count) {\n\tconst duk_uint8_t *p;\n\n\tp = *ptr;\n\tif (p < ptr_start || p >= ptr_end) {\n\t\tgoto fail;\n\t}\n\n\twhile (count > 0) {\n\t\tfor (;;) {\n\t\t\tp++;\n\n\t\t\t/* Note: if encoding ends by hitting end of input, we don't check that\n\t\t\t * the encoding is valid, we just assume it is.\n\t\t\t */\n\t\t\tif (p >= ptr_end || ((*p & 0xc0) != 0x80)) {\n\t\t\t\t/* utf-8 continuation bytes have the form 10xx xxxx */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcount--;\n\t}\n\n\t*ptr = p;\n\treturn p;\n\n fail:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Helpers for dealing with the input string\n */\n\n/* Get a (possibly canonicalized) input character from current sp.  The input\n * itself is never modified, and captures always record non-canonicalized\n * characters even in case-insensitive matching.  Return <0 if out of input.\n */\nDUK_LOCAL duk_codepoint_t duk__inp_get_cp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **sp) {\n\tduk_codepoint_t res;\n\n\tif (*sp >= re_ctx->input_end) {\n\t\treturn -1;\n\t}\n\tres = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(re_ctx->thr, sp, re_ctx->input, re_ctx->input_end);\n\tif (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) {\n\t\tres = duk_unicode_re_canonicalize_char(re_ctx->thr, res);\n\t}\n\treturn res;\n}\n\nDUK_LOCAL const duk_uint8_t *duk__inp_backtrack(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **sp, duk_uint_fast32_t count) {\n\treturn duk__utf8_backtrack(re_ctx->thr, sp, re_ctx->input, re_ctx->input_end, count);\n}\n\n/* Backtrack utf-8 input and return a (possibly canonicalized) input character. */\nDUK_LOCAL duk_codepoint_t duk__inp_get_prev_cp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t *sp) {\n\t/* note: caller 'sp' is intentionally not updated here */\n\t(void) duk__inp_backtrack(re_ctx, &sp, (duk_uint_fast32_t) 1);\n\treturn duk__inp_get_cp(re_ctx, &sp);\n}\n\n/*\n *  Regexp recursive matching function.\n *\n *  Returns 'sp' on successful match (points to character after last matched one),\n *  NULL otherwise.\n *\n *  The C recursion depth limit check is only performed in this function, this\n *  suffices because the function is present in all true recursion required by\n *  regexp execution.\n */\n\nDUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t *pc, const duk_uint8_t *sp) {\n\tduk_native_stack_check(re_ctx->thr);\n\tif (re_ctx->recursion_depth >= re_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_EXECUTOR_RECURSION_LIMIT);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\tre_ctx->recursion_depth++;\n\n\tfor (;;) {\n\t\tduk_small_int_t op;\n\n\t\tif (re_ctx->steps_count >= re_ctx->steps_limit) {\n\t\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_EXECUTOR_STEP_LIMIT);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t\tre_ctx->steps_count++;\n\n\t\t/* Opcodes are at most 7 bits now so they encode to one byte.  If this\n\t\t * were not the case or 'pc' is invalid here (due to a bug etc) we'll\n\t\t * still fail safely through the switch default case.\n\t\t */\n\t\tDUK_ASSERT(pc[0] <= 0x7fU);\n#if 0\n\t\top = (duk_small_int_t) duk__bc_get_u32(re_ctx, &pc);\n#endif\n\t\top = *pc++;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"match: rec=%ld, steps=%ld, pc (after op)=%ld, sp=%ld, op=%ld\",\n\t\t                     (long) re_ctx->recursion_depth,\n\t\t                     (long) re_ctx->steps_count,\n\t\t                     (long) (pc - re_ctx->bytecode),\n\t\t                     (long) (sp - re_ctx->input),\n\t\t                     (long) op));\n\n\t\tswitch (op) {\n\t\tcase DUK_REOP_MATCH: {\n\t\t\tgoto match;\n\t\t}\n\t\tcase DUK_REOP_CHAR: {\n\t\t\t/*\n\t\t\t *  Byte-based matching would be possible for case-sensitive\n\t\t\t *  matching but not for case-insensitive matching.  So, we\n\t\t\t *  match by decoding the input and bytecode character normally.\n\t\t\t *\n\t\t\t *  Bytecode characters are assumed to be already canonicalized.\n\t\t\t *  Input characters are canonicalized automatically by\n\t\t\t *  duk__inp_get_cp() if necessary.\n\t\t\t *\n\t\t\t *  There is no opcode for matching multiple characters.  The\n\t\t\t *  regexp compiler has trouble joining strings efficiently\n\t\t\t *  during compilation.  See doc/regexp.rst for more discussion.\n\t\t\t */\n\t\t\tduk_codepoint_t c1, c2;\n\n\t\t\tc1 = (duk_codepoint_t) duk__bc_get_u32(re_ctx, &pc);\n\t\t\tDUK_ASSERT(!(re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) ||\n\t\t\t           c1 == duk_unicode_re_canonicalize_char(re_ctx->thr, c1));  /* canonicalized by compiler */\n\t\t\tc2 = duk__inp_get_cp(re_ctx, &sp);\n\t\t\t/* No need to check for c2 < 0 (end of input): because c1 >= 0, it\n\t\t\t * will fail the match below automatically and cause goto fail.\n\t\t\t */\n#if 0\n\t\t\tif (c2 < 0) {\n\t\t\t\tgoto fail;\n\t\t\t}\n#endif\n\t\t\tDUK_ASSERT(c1 >= 0);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"char match, c1=%ld, c2=%ld\", (long) c1, (long) c2));\n\t\t\tif (c1 != c2) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_PERIOD: {\n\t\t\tduk_codepoint_t c;\n\n\t\t\tc = duk__inp_get_cp(re_ctx, &sp);\n\t\t\tif (c < 0 || duk_unicode_is_line_terminator(c)) {\n\t\t\t\t/* E5 Sections 15.10.2.8, 7.3 */\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_RANGES:\n\t\tcase DUK_REOP_INVRANGES: {\n\t\t\tduk_uint32_t n;\n\t\t\tduk_codepoint_t c;\n\t\t\tduk_small_int_t match;\n\n\t\t\tn = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tc = duk__inp_get_cp(re_ctx, &sp);\n\t\t\tif (c < 0) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\n\t\t\tmatch = 0;\n\t\t\twhile (n) {\n\t\t\t\tduk_codepoint_t r1, r2;\n\t\t\t\tr1 = (duk_codepoint_t) duk__bc_get_u32(re_ctx, &pc);\n\t\t\t\tr2 = (duk_codepoint_t) duk__bc_get_u32(re_ctx, &pc);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"matching ranges/invranges, n=%ld, r1=%ld, r2=%ld, c=%ld\",\n\t\t\t\t                     (long) n, (long) r1, (long) r2, (long) c));\n\t\t\t\tif (c >= r1 && c <= r2) {\n\t\t\t\t\t/* Note: don't bail out early, we must read all the ranges from\n\t\t\t\t\t * bytecode.  Another option is to skip them efficiently after\n\t\t\t\t\t * breaking out of here.  Prefer smallest code.\n\t\t\t\t\t */\n\t\t\t\t\tmatch = 1;\n\t\t\t\t}\n\t\t\t\tn--;\n\t\t\t}\n\n\t\t\tif (op == DUK_REOP_RANGES) {\n\t\t\t\tif (!match) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(op == DUK_REOP_INVRANGES);\n\t\t\t\tif (match) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_ASSERT_START: {\n\t\t\tduk_codepoint_t c;\n\n\t\t\tif (sp <= re_ctx->input) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!(re_ctx->re_flags & DUK_RE_FLAG_MULTILINE)) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tc = duk__inp_get_prev_cp(re_ctx, sp);\n\t\t\tif (duk_unicode_is_line_terminator(c)) {\n\t\t\t\t/* E5 Sections 15.10.2.8, 7.3 */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_ASSERT_END: {\n\t\t\tduk_codepoint_t c;\n\t\t\tconst duk_uint8_t *tmp_sp;\n\n\t\t\ttmp_sp = sp;\n\t\t\tc = duk__inp_get_cp(re_ctx, &tmp_sp);\n\t\t\tif (c < 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!(re_ctx->re_flags & DUK_RE_FLAG_MULTILINE)) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tif (duk_unicode_is_line_terminator(c)) {\n\t\t\t\t/* E5 Sections 15.10.2.8, 7.3 */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_ASSERT_WORD_BOUNDARY:\n\t\tcase DUK_REOP_ASSERT_NOT_WORD_BOUNDARY: {\n\t\t\t/*\n\t\t\t *  E5 Section 15.10.2.6.  The previous and current character\n\t\t\t *  should -not- be canonicalized as they are now.  However,\n\t\t\t *  canonicalization does not affect the result of IsWordChar()\n\t\t\t *  (which depends on Unicode characters never canonicalizing\n\t\t\t *  into ASCII characters) so this does not matter.\n\t\t\t */\n\t\t\tduk_small_int_t w1, w2;\n\n\t\t\tif (sp <= re_ctx->input) {\n\t\t\t\tw1 = 0;  /* not a wordchar */\n\t\t\t} else {\n\t\t\t\tduk_codepoint_t c;\n\t\t\t\tc = duk__inp_get_prev_cp(re_ctx, sp);\n\t\t\t\tw1 = duk_unicode_re_is_wordchar(c);\n\t\t\t}\n\t\t\tif (sp >= re_ctx->input_end) {\n\t\t\t\tw2 = 0;  /* not a wordchar */\n\t\t\t} else {\n\t\t\t\tconst duk_uint8_t *tmp_sp = sp;  /* dummy so sp won't get updated */\n\t\t\t\tduk_codepoint_t c;\n\t\t\t\tc = duk__inp_get_cp(re_ctx, &tmp_sp);\n\t\t\t\tw2 = duk_unicode_re_is_wordchar(c);\n\t\t\t}\n\n\t\t\tif (op == DUK_REOP_ASSERT_WORD_BOUNDARY) {\n\t\t\t\tif (w1 == w2) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(op == DUK_REOP_ASSERT_NOT_WORD_BOUNDARY);\n\t\t\t\tif (w1 != w2) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_JUMP: {\n\t\t\tduk_int32_t skip;\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tpc += skip;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_SPLIT1: {\n\t\t\t/* split1: prefer direct execution (no jump) */\n\t\t\tconst duk_uint8_t *sub_sp;\n\t\t\tduk_int32_t skip;\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\t\t\tpc += skip;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_SPLIT2: {\n\t\t\t/* split2: prefer jump execution (not direct) */\n\t\t\tconst duk_uint8_t *sub_sp;\n\t\t\tduk_int32_t skip;\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_SQMINIMAL: {\n\t\t\tduk_uint32_t q, qmin, qmax;\n\t\t\tduk_int32_t skip;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tqmin = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tqmax = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"minimal quantifier, qmin=%lu, qmax=%lu, skip=%ld\",\n\t\t\t                     (unsigned long) qmin, (unsigned long) qmax, (long) skip));\n\n\t\t\tq = 0;\n\t\t\twhile (q <= qmax) {\n\t\t\t\tif (q >= qmin) {\n\t\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\t\t\tif (sub_sp) {\n\t\t\t\t\t\tsp = sub_sp;\n\t\t\t\t\t\tgoto match;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\t\tif (!sub_sp) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tsp = sub_sp;\n\t\t\t\tq++;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_SQGREEDY: {\n\t\t\tduk_uint32_t q, qmin, qmax, atomlen;\n\t\t\tduk_int32_t skip;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tqmin = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tqmax = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tatomlen = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"greedy quantifier, qmin=%lu, qmax=%lu, atomlen=%lu, skip=%ld\",\n\t\t\t                     (unsigned long) qmin, (unsigned long) qmax, (unsigned long) atomlen, (long) skip));\n\n\t\t\tq = 0;\n\t\t\twhile (q < qmax) {\n\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\t\tif (!sub_sp) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tsp = sub_sp;\n\t\t\t\tq++;\n\t\t\t}\n\t\t\twhile (q >= qmin) {\n\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\t\tif (sub_sp) {\n\t\t\t\t\tsp = sub_sp;\n\t\t\t\t\tgoto match;\n\t\t\t\t}\n\t\t\t\tif (q == qmin) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t/* Note: if atom were to contain e.g. captures, we would need to\n\t\t\t\t * re-match the atom to get correct captures.  Simply quantifiers\n\t\t\t\t * do not allow captures in their atom now, so this is not an issue.\n\t\t\t\t */\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"greedy quantifier, backtrack %ld characters (atomlen)\",\n\t\t\t\t                     (long) atomlen));\n\t\t\t\tsp = duk__inp_backtrack(re_ctx, &sp, (duk_uint_fast32_t) atomlen);\n\t\t\t\tq--;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_SAVE: {\n\t\t\tduk_uint32_t idx;\n\t\t\tconst duk_uint8_t *old;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tidx = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tif (idx >= re_ctx->nsaved) {\n\t\t\t\t/* idx is unsigned, < 0 check is not necessary */\n\t\t\t\tDUK_D(DUK_DPRINT(\"internal error, regexp save index insane: idx=%ld\", (long) idx));\n\t\t\t\tgoto internal_error;\n\t\t\t}\n\t\t\told = re_ctx->saved[idx];\n\t\t\tre_ctx->saved[idx] = sp;\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\t\t\tre_ctx->saved[idx] = old;\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_WIPERANGE: {\n\t\t\t/* Wipe capture range and save old values for backtracking.\n\t\t\t *\n\t\t\t * XXX: this typically happens with a relatively small idx_count.\n\t\t\t * It might be useful to handle cases where the count is small\n\t\t\t * (say <= 8) by saving the values in stack instead.  This would\n\t\t\t * reduce memory churn and improve performance, at the cost of a\n\t\t\t * slightly higher code footprint.\n\t\t\t */\n\t\t\tduk_uint32_t idx_start, idx_count;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\t\tduk_uint32_t idx_end, idx;\n#endif\n\t\t\tduk_uint8_t **range_save;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tidx_start = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tidx_count = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"wipe saved range: start=%ld, count=%ld -> [%ld,%ld] (captures [%ld,%ld])\",\n\t\t\t                     (long) idx_start, (long) idx_count,\n\t\t\t                     (long) idx_start, (long) (idx_start + idx_count - 1),\n\t\t\t                     (long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2)));\n\t\t\tif (idx_start + idx_count > re_ctx->nsaved || idx_count == 0) {\n\t\t\t\t/* idx is unsigned, < 0 check is not necessary */\n\t\t\t\tDUK_D(DUK_DPRINT(\"internal error, regexp wipe indices insane: idx_start=%ld, idx_count=%ld\",\n\t\t\t\t                 (long) idx_start, (long) idx_count));\n\t\t\t\tgoto internal_error;\n\t\t\t}\n\t\t\tDUK_ASSERT(idx_count > 0);\n\n\t\t\tduk_require_stack(re_ctx->thr, 1);\n\t\t\trange_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero(re_ctx->thr,\n\t\t\t                                                           sizeof(duk_uint8_t *) * idx_count);\n\t\t\tDUK_ASSERT(range_save != NULL);\n\t\t\tduk_memcpy(range_save, re_ctx->saved + idx_start, sizeof(duk_uint8_t *) * idx_count);\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\t\tidx_end = idx_start + idx_count;\n\t\t\tfor (idx = idx_start; idx < idx_end; idx++) {\n\t\t\t\tre_ctx->saved[idx] = NULL;\n\t\t\t}\n#else\n\t\t\tduk_memzero((void *) (re_ctx->saved + idx_start), sizeof(duk_uint8_t *) * idx_count);\n#endif\n\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\t/* match: keep wiped/resaved values */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"match: keep wiped/resaved values [%ld,%ld] (captures [%ld,%ld])\",\n\t\t\t\t                     (long) idx_start, (long) (idx_start + idx_count - 1),\n\t\t\t                             (long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2)));\n\t\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\n\t\t\t/* fail: restore saves */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fail: restore wiped/resaved values [%ld,%ld] (captures [%ld,%ld])\",\n\t\t\t                     (long) idx_start, (long) (idx_start + idx_count - 1),\n\t\t\t                     (long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2)));\n\t\t\tduk_memcpy((void *) (re_ctx->saved + idx_start),\n\t\t\t           (const void *) range_save,\n\t\t\t           sizeof(duk_uint8_t *) * idx_count);\n\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_LOOKPOS:\n\t\tcase DUK_REOP_LOOKNEG: {\n\t\t\t/*\n\t\t\t *  Needs a save of multiple saved[] entries depending on what range\n\t\t\t *  may be overwritten.  Because the regexp parser does no such analysis,\n\t\t\t *  we currently save the entire saved array here.  Lookaheads are thus\n\t\t\t *  a bit expensive.  Note that the saved array is not needed for just\n\t\t\t *  the lookahead sub-match, but for the matching of the entire sequel.\n\t\t\t *\n\t\t\t *  The temporary save buffer is pushed on to the valstack to handle\n\t\t\t *  errors correctly.  Each lookahead causes a C recursion and pushes\n\t\t\t *  more stuff on the value stack.  If the C recursion limit is less\n\t\t\t *  than the value stack slack, there is no need to check the stack.\n\t\t\t *  We do so regardless, just in case.\n\t\t\t */\n\n\t\t\tduk_int32_t skip;\n\t\t\tduk_uint8_t **full_save;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tDUK_ASSERT(re_ctx->nsaved > 0);\n\n\t\t\tduk_require_stack(re_ctx->thr, 1);\n\t\t\tfull_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero(re_ctx->thr,\n\t\t\t                                                          sizeof(duk_uint8_t *) * re_ctx->nsaved);\n\t\t\tDUK_ASSERT(full_save != NULL);\n\t\t\tduk_memcpy(full_save, re_ctx->saved, sizeof(duk_uint8_t *) * re_ctx->nsaved);\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (op == DUK_REOP_LOOKPOS) {\n\t\t\t\tif (!sub_sp) {\n\t\t\t\t\tgoto lookahead_fail;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (sub_sp) {\n\t\t\t\t\tgoto lookahead_fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\t/* match: keep saves */\n\t\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\n\t\t\t/* fall through */\n\n\t\t lookahead_fail:\n\t\t\t/* fail: restore saves */\n\t\t\tduk_memcpy((void *) re_ctx->saved,\n\t\t\t           (const void *) full_save,\n\t\t\t           sizeof(duk_uint8_t *) * re_ctx->nsaved);\n\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_BACKREFERENCE: {\n\t\t\t/*\n\t\t\t *  Byte matching for back-references would be OK in case-\n\t\t\t *  sensitive matching.  In case-insensitive matching we need\n\t\t\t *  to canonicalize characters, so back-reference matching needs\n\t\t\t *  to be done with codepoints instead.  So, we just decode\n\t\t\t *  everything normally here, too.\n\t\t\t *\n\t\t\t *  Note: back-reference index which is 0 or higher than\n\t\t\t *  NCapturingParens (= number of capturing parens in the\n\t\t\t *  -entire- regexp) is a compile time error.  However, a\n\t\t\t *  backreference referring to a valid capture which has\n\t\t\t *  not matched anything always succeeds!  See E5 Section\n\t\t\t *  15.10.2.9, step 5, sub-step 3.\n\t\t\t */\n\t\t\tduk_uint32_t idx;\n\t\t\tconst duk_uint8_t *p;\n\n\t\t\tidx = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tidx = idx << 1;  /* backref n -> saved indices [n*2, n*2+1] */\n\t\t\tif (idx < 2 || idx + 1 >= re_ctx->nsaved) {\n\t\t\t\t/* regexp compiler should catch these */\n\t\t\t\tDUK_D(DUK_DPRINT(\"internal error, backreference index insane\"));\n\t\t\t\tgoto internal_error;\n\t\t\t}\n\t\t\tif (!re_ctx->saved[idx] || !re_ctx->saved[idx+1]) {\n\t\t\t\t/* capture is 'undefined', always matches! */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"backreference: saved[%ld,%ld] not complete, always match\",\n\t\t\t\t                     (long) idx, (long) (idx + 1)));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"backreference: match saved[%ld,%ld]\", (long) idx, (long) (idx + 1)));\n\n\t\t\tp = re_ctx->saved[idx];\n\t\t\twhile (p < re_ctx->saved[idx+1]) {\n\t\t\t\tduk_codepoint_t c1, c2;\n\n\t\t\t\t/* Note: not necessary to check p against re_ctx->input_end:\n\t\t\t\t * the memory access is checked by duk__inp_get_cp(), while\n\t\t\t\t * valid compiled regexps cannot write a saved[] entry\n\t\t\t\t * which points to outside the string.\n\t\t\t\t */\n\t\t\t\tc1 = duk__inp_get_cp(re_ctx, &p);\n\t\t\t\tDUK_ASSERT(c1 >= 0);\n\t\t\t\tc2 = duk__inp_get_cp(re_ctx, &sp);\n\t\t\t\t/* No need for an explicit c2 < 0 check: because c1 >= 0,\n\t\t\t\t * the comparison will always fail if c2 < 0.\n\t\t\t\t */\n#if 0\n\t\t\t\tif (c2 < 0) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n#endif\n\t\t\t\tif (c1 != c2) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tDUK_D(DUK_DPRINT(\"internal error, regexp opcode error: %ld\", (long) op));\n\t\t\tgoto internal_error;\n\t\t}\n\t\t}\n\t}\n\n match:\n\tre_ctx->recursion_depth--;\n\treturn sp;\n\n fail:\n\tre_ctx->recursion_depth--;\n\treturn NULL;\n\n internal_error:\n\tDUK_ERROR_INTERNAL(re_ctx->thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Exposed matcher function which provides the semantics of RegExp.prototype.exec().\n *\n *  RegExp.prototype.test() has the same semantics as exec() but does not return the\n *  result object (which contains the matching string and capture groups).  Currently\n *  there is no separate test() helper, so a temporary result object is created and\n *  discarded if test() is needed.  This is intentional, to save code space.\n *\n *  Input stack:  [ ... re_obj input ]\n *  Output stack: [ ... result ]\n */\n\nDUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_global) {\n\tduk_re_matcher_ctx re_ctx;\n\tduk_hobject *h_regexp;\n\tduk_hstring *h_bytecode;\n\tduk_hstring *h_input;\n\tduk_uint8_t *p_buf;\n\tconst duk_uint8_t *pc;\n\tconst duk_uint8_t *sp;\n\tduk_small_int_t match = 0;\n\tduk_small_int_t global;\n\tduk_uint_fast32_t i;\n\tdouble d;\n\tduk_uint32_t char_offset;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"regexp match: regexp=%!T, input=%!T\",\n\t                   (duk_tval *) duk_get_tval(thr, -2),\n\t                   (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/*\n\t *  Regexp instance check, bytecode check, input coercion.\n\t *\n\t *  See E5 Section 15.10.6.\n\t */\n\n\t/* TypeError if wrong; class check, see E5 Section 15.10.6 */\n\th_regexp = duk_require_hobject_with_class(thr, -2, DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_ASSERT(h_regexp != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_regexp) == DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_UNREF(h_regexp);\n\n\th_input = duk_to_hstring(thr, -1);\n\tDUK_ASSERT(h_input != NULL);\n\n\tduk_xget_owndataprop_stridx_short(thr, -2, DUK_STRIDX_INT_BYTECODE);  /* [ ... re_obj input ] -> [ ... re_obj input bc ] */\n\th_bytecode = duk_require_hstring(thr, -1);  /* no regexp instance should exist without a non-configurable bytecode property */\n\tDUK_ASSERT(h_bytecode != NULL);\n\n\t/*\n\t *  Basic context initialization.\n\t *\n\t *  Some init values are read from the bytecode header\n\t *  whose format is (UTF-8 codepoints):\n\t *\n\t *    uint   flags\n\t *    uint   nsaved (even, 2n+2 where n = num captures)\n\t */\n\n\t/* [ ... re_obj input bc ] */\n\n\tduk_memzero(&re_ctx, sizeof(re_ctx));\n\n\tre_ctx.thr = thr;\n\tre_ctx.input = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tre_ctx.input_end = re_ctx.input + DUK_HSTRING_GET_BYTELEN(h_input);\n\tre_ctx.bytecode = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_bytecode);\n\tre_ctx.bytecode_end = re_ctx.bytecode + DUK_HSTRING_GET_BYTELEN(h_bytecode);\n\tre_ctx.saved = NULL;\n\tre_ctx.recursion_limit = DUK_USE_REGEXP_EXECUTOR_RECLIMIT;\n\tre_ctx.steps_limit = DUK_RE_EXECUTE_STEPS_LIMIT;\n\n\t/* read header */\n\tpc = re_ctx.bytecode;\n\tre_ctx.re_flags = duk__bc_get_u32(&re_ctx, &pc);\n\tre_ctx.nsaved = duk__bc_get_u32(&re_ctx, &pc);\n\tre_ctx.bytecode = pc;\n\n\tDUK_ASSERT(DUK_RE_FLAG_GLOBAL < 0x10000UL);  /* must fit into duk_small_int_t */\n\tglobal = (duk_small_int_t) (force_global | (duk_small_int_t) (re_ctx.re_flags & DUK_RE_FLAG_GLOBAL));\n\n\tDUK_ASSERT(re_ctx.nsaved >= 2);\n\tDUK_ASSERT((re_ctx.nsaved % 2) == 0);\n\n\tp_buf = (duk_uint8_t *) duk_push_fixed_buffer(thr, sizeof(duk_uint8_t *) * re_ctx.nsaved);  /* rely on zeroing */\n\tDUK_UNREF(p_buf);\n\tre_ctx.saved = (const duk_uint8_t **) duk_get_buffer(thr, -1, NULL);\n\tDUK_ASSERT(re_ctx.saved != NULL);\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tfor (i = 0; i < re_ctx.nsaved; i++) {\n\t\tre_ctx.saved[i] = (duk_uint8_t *) NULL;\n\t}\n#elif defined(DUK_USE_ZERO_BUFFER_DATA)\n\t/* buffer is automatically zeroed */\n#else\n\tduk_memzero((void *) p_buf, sizeof(duk_uint8_t *) * re_ctx.nsaved);\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"regexp ctx initialized, flags=0x%08lx, nsaved=%ld, recursion_limit=%ld, steps_limit=%ld\",\n\t                     (unsigned long) re_ctx.re_flags, (long) re_ctx.nsaved, (long) re_ctx.recursion_limit,\n\t                     (long) re_ctx.steps_limit));\n\n\t/*\n\t *  Get starting character offset for match, and initialize 'sp' based on it.\n\t *\n\t *  Note: lastIndex is non-configurable so it must be present (we check the\n\t *  internal class of the object above, so we know it is).  User code can set\n\t *  its value to an arbitrary (garbage) value though; E5 requires that lastIndex\n\t *  be coerced to a number before using.  The code below works even if the\n\t *  property is missing: the value will then be coerced to zero.\n\t *\n\t *  Note: lastIndex may be outside Uint32 range even after ToInteger() coercion.\n\t *  For instance, ToInteger(+Infinity) = +Infinity.  We track the match offset\n\t *  as an integer, but pre-check it to be inside the 32-bit range before the loop.\n\t *  If not, the check in E5 Section 15.10.6.2, step 9.a applies.\n\t */\n\n\t/* XXX: lastIndex handling produces a lot of asm */\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n\tduk_get_prop_stridx_short(thr, -4, DUK_STRIDX_LAST_INDEX);  /* -> [ ... re_obj input bc saved_buf lastIndex ] */\n\t(void) duk_to_int(thr, -1);  /* ToInteger(lastIndex) */\n\td = duk_get_number(thr, -1);  /* integer, but may be +/- Infinite, +/- zero (not NaN, though) */\n\tduk_pop_nodecref_unsafe(thr);\n\n\tif (global) {\n\t\tif (d < 0.0 || d > (double) DUK_HSTRING_GET_CHARLEN(h_input)) {\n\t\t\t/* match fail */\n\t\t\tchar_offset = 0;   /* not really necessary */\n\t\t\tDUK_ASSERT(match == 0);\n\t\t\tgoto match_over;\n\t\t}\n\t\tchar_offset = (duk_uint32_t) d;\n\t} else {\n\t\t/* lastIndex must be ignored for non-global regexps, but get the\n\t\t * value for (theoretical) side effects.  No side effects can\n\t\t * really occur, because lastIndex is a normal property and is\n\t\t * always non-configurable for RegExp instances.\n\t\t */\n\t\tchar_offset = (duk_uint32_t) 0;\n\t}\n\n\tDUK_ASSERT(char_offset <= DUK_HSTRING_GET_CHARLEN(h_input));\n\tsp = re_ctx.input + duk_heap_strcache_offset_char2byte(thr, h_input, char_offset);\n\n\t/*\n\t *  Match loop.\n\t *\n\t *  Try matching at different offsets until match found or input exhausted.\n\t */\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n\tDUK_ASSERT(match == 0);\n\n\tfor (;;) {\n\t\t/* char offset in [0, h_input->clen] (both ends inclusive), checked before entry */\n\t\tDUK_ASSERT_DISABLE(char_offset >= 0);\n\t\tDUK_ASSERT(char_offset <= DUK_HSTRING_GET_CHARLEN(h_input));\n\n\t\t/* Note: re_ctx.steps is intentionally not reset, it applies to the entire unanchored match */\n\t\tDUK_ASSERT(re_ctx.recursion_depth == 0);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"attempt match at char offset %ld; %p [%p,%p]\",\n\t\t                     (long) char_offset, (const void *) sp,\n\t\t                     (const void *) re_ctx.input, (const void *) re_ctx.input_end));\n\n\t\t/*\n\t\t *  Note:\n\t\t *\n\t\t *    - duk__match_regexp() is required not to longjmp() in ordinary \"non-match\"\n\t\t *      conditions; a longjmp() will terminate the entire matching process.\n\t\t *\n\t\t *    - Clearing saved[] is not necessary because backtracking does it\n\t\t *\n\t\t *    - Backtracking also rewinds re_ctx.recursion back to zero, unless an\n\t\t *      internal/limit error occurs (which causes a longjmp())\n\t\t *\n\t\t *    - If we supported anchored matches, we would break out here\n\t\t *      unconditionally; however, ECMAScript regexps don't have anchored\n\t\t *      matches.  It might make sense to implement a fast bail-out if\n\t\t *      the regexp begins with '^' and sp is not 0: currently we'll just\n\t\t *      run through the entire input string, trivially failing the match\n\t\t *      at every non-zero offset.\n\t\t */\n\n\t\tif (duk__match_regexp(&re_ctx, re_ctx.bytecode, sp) != NULL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"match at offset %ld\", (long) char_offset));\n\t\t\tmatch = 1;\n\t\t\tbreak;\n\t\t}\n\n\t\t/* advance by one character (code point) and one char_offset */\n\t\tchar_offset++;\n\t\tif (char_offset > DUK_HSTRING_GET_CHARLEN(h_input)) {\n\t\t\t/*\n\t\t\t *  Note:\n\t\t\t *\n\t\t\t *    - Intentionally attempt (empty) match at char_offset == k_input->clen\n\t\t\t *\n\t\t\t *    - Negative char_offsets have been eliminated and char_offset is duk_uint32_t\n\t\t\t *      -> no need or use for a negative check\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"no match after trying all sp offsets\"));\n\t\t\tbreak;\n\t\t}\n\n\t\t/* avoid calling at end of input, will DUK_ERROR (above check suffices to avoid this) */\n\t\t(void) duk__utf8_advance(thr, &sp, re_ctx.input, re_ctx.input_end, (duk_uint_fast32_t) 1);\n\t}\n\n match_over:\n\n\t/*\n\t *  Matching complete, create result array or return a 'null'.  Update lastIndex\n\t *  if necessary.  See E5 Section 15.10.6.2.\n\t *\n\t *  Because lastIndex is a character (not byte) offset, we need the character\n\t *  length of the match which we conveniently get as a side effect of interning\n\t *  the matching substring (0th index of result array).\n\t *\n\t *  saved[0]         start pointer (~ byte offset) of current match\n\t *  saved[1]         end pointer (~ byte offset) of current match (exclusive)\n\t *  char_offset      start character offset of current match (-> .index of result)\n\t *  char_end_offset  end character offset (computed below)\n\t */\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n\tif (match) {\n#if defined(DUK_USE_ASSERTIONS)\n\t\tduk_hobject *h_res;\n#endif\n\t\tduk_uint32_t char_end_offset = 0;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"regexp matches at char_offset %ld\", (long) char_offset));\n\n\t\tDUK_ASSERT(re_ctx.nsaved >= 2);        /* must have start and end */\n\t\tDUK_ASSERT((re_ctx.nsaved % 2) == 0);  /* and even number */\n\n\t\t/* XXX: Array size is known before and (2 * re_ctx.nsaved) but not taken\n\t\t * advantage of now.  The array is not compacted either, as regexp match\n\t\t * objects are usually short lived.\n\t\t */\n\n\t\tduk_push_array(thr);\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\th_res = duk_require_hobject(thr, -1);\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_res));\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(h_res));\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_res) == DUK_HOBJECT_CLASS_ARRAY);\n#endif\n\n\t\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\t\tduk_push_u32(thr, char_offset);\n\t\tduk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INDEX);\n\n\t\tduk_dup_m4(thr);\n\t\tduk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INPUT);\n\n\t\tfor (i = 0; i < re_ctx.nsaved; i += 2) {\n\t\t\t/* Captures which are undefined have NULL pointers and are returned\n\t\t\t * as 'undefined'.  The same is done when saved[] pointers are insane\n\t\t\t * (this should, of course, never happen in practice).\n\t\t\t */\n\t\t\tif (re_ctx.saved[i] && re_ctx.saved[i + 1] && re_ctx.saved[i + 1] >= re_ctx.saved[i]) {\n\t\t\t\tduk_push_lstring(thr,\n\t\t\t\t                 (const char *) re_ctx.saved[i],\n\t\t\t\t                 (duk_size_t) (re_ctx.saved[i+1] - re_ctx.saved[i]));\n\t\t\t\tif (i == 0) {\n\t\t\t\t\t/* Assumes that saved[0] and saved[1] are always\n\t\t\t\t\t * set by regexp bytecode (if not, char_end_offset\n\t\t\t\t\t * will be zero).  Also assumes clen reflects the\n\t\t\t\t\t * correct char length.\n\t\t\t\t\t */\n\t\t\t\t\tchar_end_offset = char_offset + (duk_uint32_t) duk_get_length(thr, -1);  /* add charlen */\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t}\n\n\t\t\t/* [ ... re_obj input bc saved_buf res_obj val ] */\n\t\t\tduk_put_prop_index(thr, -2, (duk_uarridx_t) (i / 2));\n\t\t}\n\n\t\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\t\t/* NB: 'length' property is automatically updated by the array setup loop */\n\n\t\tif (global) {\n\t\t\t/* global regexp: lastIndex updated on match */\n\t\t\tduk_push_u32(thr, char_end_offset);\n\t\t\tduk_put_prop_stridx_short(thr, -6, DUK_STRIDX_LAST_INDEX);\n\t\t} else {\n\t\t\t/* non-global regexp: lastIndex never updated on match */\n\t\t\t;\n\t\t}\n\t} else {\n\t\t/*\n\t\t *  No match, E5 Section 15.10.6.2, step 9.a.i - 9.a.ii apply, regardless\n\t\t *  of 'global' flag of the RegExp.  In particular, if lastIndex is invalid\n\t\t *  initially, it is reset to zero.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"regexp does not match\"));\n\n\t\tduk_push_null(thr);\n\n\t\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\t\tduk_push_int(thr, 0);\n\t\tduk_put_prop_stridx_short(thr, -6, DUK_STRIDX_LAST_INDEX);\n\t}\n\n\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\tduk_insert(thr, -5);\n\n\t/* [ ... res_obj re_obj input bc saved_buf ] */\n\n\tduk_pop_n_unsafe(thr, 4);\n\n\t/* [ ... res_obj ] */\n\n\t/* XXX: these last tricks are unnecessary if the function is made\n\t * a genuine native function.\n\t */\n}\n\nDUK_INTERNAL void duk_regexp_match(duk_hthread *thr) {\n\tduk__regexp_match_helper(thr, 0 /*force_global*/);\n}\n\n/* This variant is needed by String.prototype.split(); it needs to perform\n * global-style matching on a cloned RegExp which is potentially non-global.\n */\nDUK_INTERNAL void duk_regexp_match_force_global(duk_hthread *thr) {\n\tduk__regexp_match_helper(thr, 1 /*force_global*/);\n}\n\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\n/* regexp support disabled */\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n#line 1 \"duk_selftest.c\"\n/*\n *  Self tests to ensure execution environment is sane.  Intended to catch\n *  compiler/platform problems which cannot be detected at compile time.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_SELF_TESTS)\n\n/*\n *  Unions and structs for self tests\n */\n\ntypedef union {\n\tdouble d;\n\tduk_uint8_t x[8];\n} duk__test_double_union;\n\n/* Self test failed.  Expects a local variable 'error_count' to exist. */\n#define DUK__FAILED(msg)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"self test failed: \" #msg \" at \" DUK_FILE_MACRO \":\" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO))); \\\n\t\terror_count++; \\\n\t} while (0)\n\n#define DUK__DBLUNION_CMP_TRUE(a,b)  do { \\\n\t\tif (duk_memcmp((const void *) (a), (const void *) (b), sizeof(duk__test_double_union)) != 0) { \\\n\t\t\tDUK__FAILED(\"double union compares false (expected true)\"); \\\n\t\t} \\\n\t} while (0)\n\n#define DUK__DBLUNION_CMP_FALSE(a,b)  do { \\\n\t\tif (duk_memcmp((const void *) (a), (const void *) (b), sizeof(duk__test_double_union)) == 0) { \\\n\t\t\tDUK__FAILED(\"double union compares true (expected false)\"); \\\n\t\t} \\\n\t} while (0)\n\ntypedef union {\n\tduk_uint32_t i;\n\tduk_uint8_t x[8];\n} duk__test_u32_union;\n\n#if defined(DUK_USE_INTEGER_LE)\n#define DUK__U32_INIT(u, a, b, c, d) do { \\\n\t\t(u)->x[0] = (d); (u)->x[1] = (c); (u)->x[2] = (b); (u)->x[3] = (a); \\\n\t} while (0)\n#elif defined(DUK_USE_INTEGER_ME)\n#error integer mixed endian not supported now\n#elif defined(DUK_USE_INTEGER_BE)\n#define DUK__U32_INIT(u, a, b, c, d) do { \\\n\t\t(u)->x[0] = (a); (u)->x[1] = (b); (u)->x[2] = (c); (u)->x[3] = (d); \\\n\t} while (0)\n#else\n#error unknown integer endianness\n#endif\n\n#if defined(DUK_USE_DOUBLE_LE)\n#define DUK__DOUBLE_INIT(u, a, b, c, d, e, f, g, h) do { \\\n\t\t(u)->x[0] = (h); (u)->x[1] = (g); (u)->x[2] = (f); (u)->x[3] = (e); \\\n\t\t(u)->x[4] = (d); (u)->x[5] = (c); (u)->x[6] = (b); (u)->x[7] = (a); \\\n\t} while (0)\n#define DUK__DOUBLE_COMPARE(u, a, b, c, d, e, f, g, h) \\\n\t((u)->x[0] == (h) && (u)->x[1] == (g) && (u)->x[2] == (f) && (u)->x[3] == (e) && \\\n\t (u)->x[4] == (d) && (u)->x[5] == (c) && (u)->x[6] == (b) && (u)->x[7] == (a))\n#elif defined(DUK_USE_DOUBLE_ME)\n#define DUK__DOUBLE_INIT(u, a, b, c, d, e, f, g, h) do { \\\n\t\t(u)->x[0] = (d); (u)->x[1] = (c); (u)->x[2] = (b); (u)->x[3] = (a); \\\n\t\t(u)->x[4] = (h); (u)->x[5] = (g); (u)->x[6] = (f); (u)->x[7] = (e); \\\n\t} while (0)\n#define DUK__DOUBLE_COMPARE(u, a, b, c, d, e, f, g, h) \\\n\t((u)->x[0] == (d) && (u)->x[1] == (c) && (u)->x[2] == (b) && (u)->x[3] == (a) && \\\n\t (u)->x[4] == (h) && (u)->x[5] == (g) && (u)->x[6] == (f) && (u)->x[7] == (e))\n#elif defined(DUK_USE_DOUBLE_BE)\n#define DUK__DOUBLE_INIT(u, a, b, c, d, e, f, g, h) do { \\\n\t\t(u)->x[0] = (a); (u)->x[1] = (b); (u)->x[2] = (c); (u)->x[3] = (d); \\\n\t\t(u)->x[4] = (e); (u)->x[5] = (f); (u)->x[6] = (g); (u)->x[7] = (h); \\\n\t} while (0)\n#define DUK__DOUBLE_COMPARE(u, a, b, c, d, e, f, g, h) \\\n\t((u)->x[0] == (a) && (u)->x[1] == (b) && (u)->x[2] == (c) && (u)->x[3] == (d) && \\\n\t (u)->x[4] == (e) && (u)->x[5] == (f) && (u)->x[6] == (g) && (u)->x[7] == (h))\n#else\n#error unknown double endianness\n#endif\n\n/*\n *  Various sanity checks for typing\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_types(void) {\n\tduk_uint_t error_count = 0;\n\n\tif (!(sizeof(duk_int8_t) == 1 &&\n\t      sizeof(duk_uint8_t) == 1 &&\n\t      sizeof(duk_int16_t) == 2 &&\n\t      sizeof(duk_uint16_t) == 2 &&\n\t      sizeof(duk_int32_t) == 4 &&\n\t      sizeof(duk_uint32_t) == 4)) {\n\t\tDUK__FAILED(\"duk_(u)int{8,16,32}_t size\");\n\t}\n#if defined(DUK_USE_64BIT_OPS)\n\tif (!(sizeof(duk_int64_t) == 8 &&\n\t      sizeof(duk_uint64_t) == 8)) {\n\t\tDUK__FAILED(\"duk_(u)int64_t size\");\n\t}\n#endif\n\n\tif (!(sizeof(duk_size_t) >= sizeof(duk_uint_t))) {\n\t\t/* Some internal code now assumes that all duk_uint_t values\n\t\t * can be expressed with a duk_size_t.\n\t\t */\n\t\tDUK__FAILED(\"duk_size_t is smaller than duk_uint_t\");\n\t}\n\tif (!(sizeof(duk_int_t) >= 4)) {\n\t\tDUK__FAILED(\"duk_int_t is not 32 bits\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Packed tval sanity\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_packed_tval(void) {\n\tduk_uint_t error_count = 0;\n\n#if defined(DUK_USE_PACKED_TVAL)\n\tif (sizeof(void *) > 4) {\n\t\tDUK__FAILED(\"packed duk_tval in use but sizeof(void *) > 4\");\n\t}\n#endif\n\n\treturn error_count;\n}\n\n/*\n *  Two's complement arithmetic.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_twos_complement(void) {\n\tduk_uint_t error_count = 0;\n\tvolatile int test;\n\ttest = -1;\n\n\t/* Note that byte order doesn't affect this test: all bytes in\n\t * 'test' will be 0xFF for two's complement.\n\t */\n\tif (((volatile duk_uint8_t *) &test)[0] != (duk_uint8_t) 0xff) {\n\t\tDUK__FAILED(\"two's complement arithmetic\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Byte order.  Important to self check, because on some exotic platforms\n *  there is no actual detection but rather assumption based on platform\n *  defines.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_byte_order(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_u32_union u1;\n\tduk__test_double_union u2;\n\n\t/*\n\t *  >>> struct.pack('>d', 102030405060).encode('hex')\n\t *  '4237c17c6dc40000'\n\t */\n\n\tDUK__U32_INIT(&u1, 0xde, 0xad, 0xbe, 0xef);\n\tDUK__DOUBLE_INIT(&u2, 0x42, 0x37, 0xc1, 0x7c, 0x6d, 0xc4, 0x00, 0x00);\n\n\tif (u1.i != (duk_uint32_t) 0xdeadbeefUL) {\n\t\tDUK__FAILED(\"duk_uint32_t byte order\");\n\t}\n\n\tif (u2.d != (double) 102030405060.0) {\n\t\tDUK__FAILED(\"double byte order\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  DUK_BSWAP macros\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_bswap_macros(void) {\n\tduk_uint_t error_count = 0;\n\tvolatile duk_uint32_t x32_input, x32_output;\n\tduk_uint32_t x32;\n\tvolatile duk_uint16_t x16_input, x16_output;\n\tduk_uint16_t x16;\n\tduk_double_union du;\n\tduk_double_t du_diff;\n#if defined(DUK_BSWAP64)\n\tvolatile duk_uint64_t x64_input, x64_output;\n\tduk_uint64_t x64;\n#endif\n\n\t/* Cover both compile time and runtime bswap operations, as these\n\t * may have different bugs.\n\t */\n\n\tx16_input = 0xbeefUL;\n\tx16 = x16_input;\n\tx16 = DUK_BSWAP16(x16);\n\tx16_output = x16;\n\tif (x16_output != (duk_uint16_t) 0xefbeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP16\");\n\t}\n\n\tx16 = 0xbeefUL;\n\tx16 = DUK_BSWAP16(x16);\n\tif (x16 != (duk_uint16_t) 0xefbeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP16\");\n\t}\n\n\tx32_input = 0xdeadbeefUL;\n\tx32 = x32_input;\n\tx32 = DUK_BSWAP32(x32);\n\tx32_output = x32;\n\tif (x32_output != (duk_uint32_t) 0xefbeaddeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP32\");\n\t}\n\n\tx32 = 0xdeadbeefUL;\n\tx32 = DUK_BSWAP32(x32);\n\tif (x32 != (duk_uint32_t) 0xefbeaddeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP32\");\n\t}\n\n#if defined(DUK_BSWAP64)\n\tx64_input = DUK_U64_CONSTANT(0x8899aabbccddeeff);\n\tx64 = x64_input;\n\tx64 = DUK_BSWAP64(x64);\n\tx64_output = x64;\n\tif (x64_output != (duk_uint64_t) DUK_U64_CONSTANT(0xffeeddccbbaa9988)) {\n\t\tDUK__FAILED(\"DUK_BSWAP64\");\n\t}\n\n\tx64 = DUK_U64_CONSTANT(0x8899aabbccddeeff);\n\tx64 = DUK_BSWAP64(x64);\n\tif (x64 != (duk_uint64_t) DUK_U64_CONSTANT(0xffeeddccbbaa9988)) {\n\t\tDUK__FAILED(\"DUK_BSWAP64\");\n\t}\n#endif\n\n\t/* >>> struct.unpack('>d', '4000112233445566'.decode('hex'))\n\t * (2.008366013071895,)\n\t */\n\n\tdu.uc[0] = 0x40; du.uc[1] = 0x00; du.uc[2] = 0x11; du.uc[3] = 0x22;\n\tdu.uc[4] = 0x33; du.uc[5] = 0x44; du.uc[6] = 0x55; du.uc[7] = 0x66;\n\tDUK_DBLUNION_DOUBLE_NTOH(&du);\n\tdu_diff = du.d - 2.008366013071895;\n#if 0\n\tDUK_D(DUK_DPRINT(\"du_diff: %lg\\n\", (double) du_diff));\n#endif\n\tif (du_diff > 1e-15) {\n\t\t/* Allow very small lenience because some compilers won't parse\n\t\t * exact IEEE double constants (happened in matrix testing with\n\t\t * Linux gcc-4.8 -m32 at least).\n\t\t */\n#if 0\n\t\tDUK_D(DUK_DPRINT(\"Result of DUK_DBLUNION_DOUBLE_NTOH: %02x %02x %02x %02x %02x %02x %02x %02x\\n\",\n\t\t            (unsigned int) du.uc[0], (unsigned int) du.uc[1],\n\t\t            (unsigned int) du.uc[2], (unsigned int) du.uc[3],\n\t\t            (unsigned int) du.uc[4], (unsigned int) du.uc[5],\n\t\t            (unsigned int) du.uc[6], (unsigned int) du.uc[7]));\n#endif\n\t\tDUK__FAILED(\"DUK_DBLUNION_DOUBLE_NTOH\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Basic double / byte union memory layout.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_union_size(void) {\n\tduk_uint_t error_count = 0;\n\n\tif (sizeof(duk__test_double_union) != 8) {\n\t\tDUK__FAILED(\"invalid union size\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Union aliasing, see misc/clang_aliasing.c.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_aliasing(void) {\n\t/* This testcase fails when Emscripten-generated code runs on Firefox.\n\t * It's not an issue because the failure should only affect packed\n\t * duk_tval representation, which is not used with Emscripten.\n\t */\n#if defined(DUK_USE_PACKED_TVAL)\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union a, b;\n\n\t/* Test signaling NaN and alias assignment in all endianness combinations.\n\t */\n\n\t/* little endian */\n\ta.x[0] = 0x11; a.x[1] = 0x22; a.x[2] = 0x33; a.x[3] = 0x44;\n\ta.x[4] = 0x00; a.x[5] = 0x00; a.x[6] = 0xf1; a.x[7] = 0xff;\n\tb = a;\n\tDUK__DBLUNION_CMP_TRUE(&a, &b);\n\n\t/* big endian */\n\ta.x[0] = 0xff; a.x[1] = 0xf1; a.x[2] = 0x00; a.x[3] = 0x00;\n\ta.x[4] = 0x44; a.x[5] = 0x33; a.x[6] = 0x22; a.x[7] = 0x11;\n\tb = a;\n\tDUK__DBLUNION_CMP_TRUE(&a, &b);\n\n\t/* mixed endian */\n\ta.x[0] = 0x00; a.x[1] = 0x00; a.x[2] = 0xf1; a.x[3] = 0xff;\n\ta.x[4] = 0x11; a.x[5] = 0x22; a.x[6] = 0x33; a.x[7] = 0x44;\n\tb = a;\n\tDUK__DBLUNION_CMP_TRUE(&a, &b);\n\n\treturn error_count;\n#else\n\tDUK_D(DUK_DPRINT(\"skip double aliasing self test when duk_tval is not packed\"));\n\treturn 0;\n#endif\n}\n\n/*\n *  Zero sign, see misc/tcc_zerosign2.c.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_zero_sign(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union a, b;\n\n\ta.d = 0.0;\n\tb.d = -a.d;\n\tDUK__DBLUNION_CMP_FALSE(&a, &b);\n\n\treturn error_count;\n}\n\n/*\n *  Rounding mode: Duktape assumes round-to-nearest, check that this is true.\n *  If we had C99 fenv.h we could check that fegetround() == FE_TONEAREST,\n *  but we don't want to rely on that header; and even if we did, it's good\n *  to ensure the rounding actually works.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_rounding(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union a, b, c;\n\n#if 0\n\t/* Include <fenv.h> and test manually; these trigger failures: */\n\tfesetround(FE_UPWARD);\n\tfesetround(FE_DOWNWARD);\n\tfesetround(FE_TOWARDZERO);\n\n\t/* This is the default and passes. */\n\tfesetround(FE_TONEAREST);\n#endif\n\n\t/* Rounding tests check that none of the other modes (round to\n\t * +Inf, round to -Inf, round to zero) can be active:\n\t * http://www.gnu.org/software/libc/manual/html_node/Rounding.html\n\t */\n\n\t/* 1.0 + 2^(-53): result is midway between 1.0 and 1.0 + ulp.\n\t * Round to nearest: 1.0\n\t * Round to +Inf:    1.0 + ulp\n\t * Round to -Inf:    1.0\n\t * Round to zero:    1.0\n\t * => Correct result eliminates round to +Inf.\n\t */\n\tDUK__DOUBLE_INIT(&a, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);\n\tDUK__DOUBLE_INIT(&b, 0x3c, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);\n\tduk_memset((void *) &c, 0, sizeof(c));\n\tc.d = a.d + b.d;\n\tif (!DUK__DOUBLE_COMPARE(&c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)) {\n\t\tDUK_D(DUK_DPRINT(\"broken result (native endiannesss): %02x %02x %02x %02x %02x %02x %02x %02x\",\n\t\t                 (unsigned int) c.x[0], (unsigned int) c.x[1],\n\t\t                 (unsigned int) c.x[2], (unsigned int) c.x[3],\n\t\t                 (unsigned int) c.x[4], (unsigned int) c.x[5],\n\t\t                 (unsigned int) c.x[6], (unsigned int) c.x[7]));\n\t\tDUK__FAILED(\"invalid result from 1.0 + 0.5ulp\");\n\t}\n\n\t/* (1.0 + ulp) + 2^(-53): result is midway between 1.0 + ulp and 1.0 + 2*ulp.\n\t * Round to nearest: 1.0 + 2*ulp (round to even mantissa)\n\t * Round to +Inf:    1.0 + 2*ulp\n\t * Round to -Inf:    1.0 + ulp\n\t * Round to zero:    1.0 + ulp\n\t * => Correct result eliminates round to -Inf and round to zero.\n\t */\n\tDUK__DOUBLE_INIT(&a, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01);\n\tDUK__DOUBLE_INIT(&b, 0x3c, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);\n\tduk_memset((void *) &c, 0, sizeof(c));\n\tc.d = a.d + b.d;\n\tif (!DUK__DOUBLE_COMPARE(&c, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02)) {\n\t\tDUK_D(DUK_DPRINT(\"broken result (native endiannesss): %02x %02x %02x %02x %02x %02x %02x %02x\",\n\t\t                 (unsigned int) c.x[0], (unsigned int) c.x[1],\n\t\t                 (unsigned int) c.x[2], (unsigned int) c.x[3],\n\t\t                 (unsigned int) c.x[4], (unsigned int) c.x[5],\n\t\t                 (unsigned int) c.x[6], (unsigned int) c.x[7]));\n\t\tDUK__FAILED(\"invalid result from (1.0 + ulp) + 0.5ulp\");\n\t}\n\n\t/* Could do negative number testing too, but the tests above should\n\t * differentiate between IEEE 754 rounding modes.\n\t */\n\treturn error_count;\n}\n\n/*\n *  fmod(): often a portability issue in embedded or bare platform targets.\n *  Check for at least minimally correct behavior.  Unlike some other math\n *  functions (like cos()) Duktape relies on fmod() internally too.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_fmod(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union u1, u2;\n\tvolatile duk_double_t t1, t2, t3;\n\n\t/* fmod() with integer argument and exponent 2^32 is used by e.g.\n\t * ToUint32() and some Duktape internals.\n\t */\n\tu1.d = DUK_FMOD(10.0, 4294967296.0);\n\tu2.d = 10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(4294967306.0, 4294967296.0);\n\tu2.d = 10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(73014444042.0, 4294967296.0);\n\tu2.d = 10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\t/* 52-bit integer split into two parts:\n\t * >>> 0x1fedcba9876543\n\t * 8987183256397123\n\t * >>> float(0x1fedcba9876543) / float(2**53)\n\t * 0.9977777777777778\n\t */\n\tu1.d = DUK_FMOD(8987183256397123.0, 4294967296.0);\n\tu2.d = (duk_double_t) 0xa9876543UL;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\tt1 = 8987183256397123.0;\n\tt2 = 4294967296.0;\n\tt3 = t1 / t2;\n\tu1.d = DUK_FLOOR(t3);\n\tu2.d = (duk_double_t) 0x1fedcbUL;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\t/* C99 behavior is for fmod() result sign to mathc argument sign. */\n\tu1.d = DUK_FMOD(-10.0, 4294967296.0);\n\tu2.d = -10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(-4294967306.0, 4294967296.0);\n\tu2.d = -10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(-73014444042.0, 4294967296.0);\n\tu2.d = -10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\treturn error_count;\n}\n\n/*\n *  Struct size/alignment if platform requires it\n *\n *  There are some compiler specific struct padding pragmas etc in use, this\n *  selftest ensures they're correctly detected and used.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_struct_align(void) {\n\tduk_uint_t error_count = 0;\n\n#if (DUK_USE_ALIGN_BY == 4)\n\tif ((sizeof(duk_hbuffer_fixed) % 4) != 0) {\n\t\tDUK__FAILED(\"sizeof(duk_hbuffer_fixed) not aligned to 4\");\n\t}\n#elif (DUK_USE_ALIGN_BY == 8)\n\tif ((sizeof(duk_hbuffer_fixed) % 8) != 0) {\n\t\tDUK__FAILED(\"sizeof(duk_hbuffer_fixed) not aligned to 8\");\n\t}\n#elif (DUK_USE_ALIGN_BY == 1)\n\t/* no check */\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\treturn error_count;\n}\n\n/*\n *  64-bit arithmetic\n *\n *  There are some platforms/compilers where 64-bit types are available\n *  but don't work correctly.  Test for known cases.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_64bit_arithmetic(void) {\n\tduk_uint_t error_count = 0;\n#if defined(DUK_USE_64BIT_OPS)\n\tvolatile duk_int64_t i;\n\tvolatile duk_double_t d;\n\n\t/* Catch a double-to-int64 cast issue encountered in practice. */\n\td = 2147483648.0;\n\ti = (duk_int64_t) d;\n\tif (i != DUK_I64_CONSTANT(0x80000000)) {\n\t\tDUK__FAILED(\"casting 2147483648.0 to duk_int64_t failed\");\n\t}\n#else\n\t/* nop */\n#endif\n\treturn error_count;\n}\n\n/*\n *  Casting\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_cast_double_to_small_uint(void) {\n\t/*\n\t *  https://github.com/svaarala/duktape/issues/127#issuecomment-77863473\n\t */\n\n\tduk_uint_t error_count = 0;\n\n\tduk_double_t d1, d2;\n\tduk_small_uint_t u;\n\n\tduk_double_t d1v, d2v;\n\tduk_small_uint_t uv;\n\n\t/* Test without volatiles */\n\n\td1 = 1.0;\n\tu = (duk_small_uint_t) d1;\n\td2 = (duk_double_t) u;\n\n\tif (!(d1 == 1.0 && u == 1 && d2 == 1.0 && d1 == d2)) {\n\t\tDUK__FAILED(\"double to duk_small_uint_t cast failed\");\n\t}\n\n\t/* Same test with volatiles */\n\n\td1v = 1.0;\n\tuv = (duk_small_uint_t) d1v;\n\td2v = (duk_double_t) uv;\n\n\tif (!(d1v == 1.0 && uv == 1 && d2v == 1.0 && d1v == d2v)) {\n\t\tDUK__FAILED(\"double to duk_small_uint_t cast failed\");\n\t}\n\n\treturn error_count;\n}\n\nDUK_LOCAL duk_uint_t duk__selftest_cast_double_to_uint32(void) {\n\t/*\n\t *  This test fails on an exotic ARM target; double-to-uint\n\t *  cast is incorrectly clamped to -signed- int highest value.\n\t *\n\t *  https://github.com/svaarala/duktape/issues/336\n\t */\n\n\tduk_uint_t error_count = 0;\n\tduk_double_t dv;\n\tduk_uint32_t uv;\n\n\tdv = 3735928559.0;  /* 0xdeadbeef in decimal */\n\tuv = (duk_uint32_t) dv;\n\n\tif (uv != 0xdeadbeefUL) {\n\t\tDUK__FAILED(\"double to duk_uint32_t cast failed\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Minimal test of user supplied allocation functions\n *\n *    - Basic alloc + realloc + free cycle\n *\n *    - Realloc to significantly larger size to (hopefully) trigger a\n *      relocation and check that relocation copying works\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_alloc_funcs(duk_alloc_function alloc_func,\n                                               duk_realloc_function realloc_func,\n                                               duk_free_function free_func,\n                                               void *udata) {\n\tduk_uint_t error_count = 0;\n\tvoid *ptr;\n\tvoid *new_ptr;\n\tduk_small_int_t i, j;\n\tunsigned char x;\n\n\tif (alloc_func == NULL || realloc_func == NULL || free_func == NULL) {\n\t\treturn 0;\n\t}\n\n\tfor (i = 1; i <= 256; i++) {\n\t\tptr = alloc_func(udata, (duk_size_t) i);\n\t\tif (ptr == NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"alloc failed, ignore\"));\n\t\t\tcontinue;  /* alloc failed, ignore */\n\t\t}\n\t\tfor (j = 0; j < i; j++) {\n\t\t\t((unsigned char *) ptr)[j] = (unsigned char) (0x80 + j);\n\t\t}\n\t\tnew_ptr = realloc_func(udata, ptr, 1024);\n\t\tif (new_ptr == NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"realloc failed, ignore\"));\n\t\t\tfree_func(udata, ptr);\n\t\t\tcontinue;  /* realloc failed, ignore */\n\t\t}\n\t\tptr = new_ptr;\n\t\tfor (j = 0; j < i; j++) {\n\t\t\tx = ((unsigned char *) ptr)[j];\n\t\t\tif (x != (unsigned char) (0x80 + j)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"byte at index %ld doesn't match after realloc: %02lx\",\n\t\t\t\t                 (long) j, (unsigned long) x));\n\t\t\t\tDUK__FAILED(\"byte compare after realloc\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tfree_func(udata, ptr);\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Self test main\n */\n\nDUK_INTERNAL duk_uint_t duk_selftest_run_tests(duk_alloc_function alloc_func,\n                                               duk_realloc_function realloc_func,\n                                               duk_free_function free_func,\n                                               void *udata) {\n\tduk_uint_t error_count = 0;\n\n\tDUK_D(DUK_DPRINT(\"self test starting\"));\n\n\terror_count += duk__selftest_types();\n\terror_count += duk__selftest_packed_tval();\n\terror_count += duk__selftest_twos_complement();\n\terror_count += duk__selftest_byte_order();\n\terror_count += duk__selftest_bswap_macros();\n\terror_count += duk__selftest_double_union_size();\n\terror_count += duk__selftest_double_aliasing();\n\terror_count += duk__selftest_double_zero_sign();\n\terror_count += duk__selftest_double_rounding();\n\terror_count += duk__selftest_fmod();\n\terror_count += duk__selftest_struct_align();\n\terror_count += duk__selftest_64bit_arithmetic();\n\terror_count += duk__selftest_cast_double_to_small_uint();\n\terror_count += duk__selftest_cast_double_to_uint32();\n\terror_count += duk__selftest_alloc_funcs(alloc_func, realloc_func, free_func, udata);\n\n\tDUK_D(DUK_DPRINT(\"self test complete, total error count: %ld\", (long) error_count));\n\n\treturn error_count;\n}\n\n#endif  /* DUK_USE_SELF_TESTS */\n\n/* automatic undefs */\n#undef DUK__DBLUNION_CMP_FALSE\n#undef DUK__DBLUNION_CMP_TRUE\n#undef DUK__DOUBLE_COMPARE\n#undef DUK__DOUBLE_INIT\n#undef DUK__FAILED\n#undef DUK__U32_INIT\n/* #include duk_internal.h -> already included */\n#line 2 \"duk_tval.c\"\n\n#if defined(DUK_USE_FASTINT)\n\n/*\n *  Manually optimized double-to-fastint downgrade check.\n *\n *  This check has a large impact on performance, especially for fastint\n *  slow paths, so must be changed carefully.  The code should probably be\n *  optimized for the case where the result does not fit into a fastint,\n *  to minimize the penalty for \"slow path code\" dealing with fractions etc.\n *\n *  At least on one tested soft float ARM platform double-to-int64 coercion\n *  is very slow (and sometimes produces incorrect results, see self tests).\n *  This algorithm combines a fastint compatibility check and extracting the\n *  integer value from an IEEE double for setting the tagged fastint.  For\n *  other platforms a more naive approach might be better.\n *\n *  See doc/fastint.rst for details.\n */\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_tval_set_number_chkfast_fast(duk_tval *tv, duk_double_t x) {\n\tduk_double_union du;\n\tduk_int64_t i;\n\tduk_small_int_t expt;\n\tduk_small_int_t shift;\n\n\t/* XXX: optimize for packed duk_tval directly? */\n\n\tdu.d = x;\n\ti = (duk_int64_t) DUK_DBLUNION_GET_INT64(&du);\n\texpt = (duk_small_int_t) ((i >> 52) & 0x07ff);\n\tshift = expt - 1023;\n\n\tif (shift >= 0 && shift <= 46) {  /* exponents 1023 to 1069 */\n\t\tduk_int64_t t;\n\n\t\tif (((DUK_I64_CONSTANT(0x000fffffffffffff) >> shift) & i) == 0) {\n\t\t\tt = i | DUK_I64_CONSTANT(0x0010000000000000);  /* implicit leading one */\n\t\t\tt = t & DUK_I64_CONSTANT(0x001fffffffffffff);\n\t\t\tt = t >> (52 - shift);\n\t\t\tif (i < 0) {\n\t\t\t\tt = -t;\n\t\t\t}\n\t\t\tDUK_TVAL_SET_FASTINT(tv, t);\n\t\t\treturn;\n\t\t}\n\t} else if (shift == -1023) {  /* exponent 0 */\n\t\tif (i >= 0 && (i & DUK_I64_CONSTANT(0x000fffffffffffff)) == 0) {\n\t\t\t/* Note: reject negative zero. */\n\t\t\tDUK_TVAL_SET_FASTINT(tv, (duk_int64_t) 0);\n\t\t\treturn;\n\t\t}\n\t} else if (shift == 47) {  /* exponent 1070 */\n\t\tif (i < 0 && (i & DUK_I64_CONSTANT(0x000fffffffffffff)) == 0) {\n\t\t\tDUK_TVAL_SET_FASTINT(tv, (duk_int64_t) DUK_FASTINT_MIN);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tDUK_TVAL_SET_DOUBLE(tv, x);\n\treturn;\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_tval_set_number_chkfast_slow(duk_tval *tv, duk_double_t x) {\n\tduk_tval_set_number_chkfast_fast(tv, x);\n}\n\n/*\n *  Manually optimized number-to-double conversion\n */\n\n#if defined(DUK_USE_FASTINT) && defined(DUK_USE_PACKED_TVAL)\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_packed(duk_tval *tv) {\n\tduk_double_union du;\n\tduk_uint64_t t;\n\n\tt = (duk_uint64_t) DUK_DBLUNION_GET_UINT64(tv);\n\tif ((t >> 48) != DUK_TAG_FASTINT) {\n\t\treturn tv->d;\n\t} else if (t & DUK_U64_CONSTANT(0x0000800000000000)) {\n\t\tt = (duk_uint64_t) (-((duk_int64_t) t));  /* avoid unary minus on unsigned */\n\t\tt = t & DUK_U64_CONSTANT(0x0000ffffffffffff);  /* negative */\n\t\tt |= DUK_U64_CONSTANT(0xc330000000000000);\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d + 4503599627370496.0;  /* 1 << 52 */\n\t} else if (t != 0) {\n\t\tt &= DUK_U64_CONSTANT(0x0000ffffffffffff);  /* positive */\n\t\tt |= DUK_U64_CONSTANT(0x4330000000000000);\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d - 4503599627370496.0;  /* 1 << 52 */\n\t} else {\n\t\treturn 0.0;  /* zero */\n\t}\n}\n#endif  /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */\n\n#if 0  /* unused */\n#if defined(DUK_USE_FASTINT) && !defined(DUK_USE_PACKED_TVAL)\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked(duk_tval *tv) {\n\tduk_double_union du;\n\tduk_uint64_t t;\n\n\tDUK_ASSERT(tv->t == DUK_TAG_NUMBER || tv->t == DUK_TAG_FASTINT);\n\n\tif (tv->t == DUK_TAG_FASTINT) {\n\t\tif (tv->v.fi >= 0) {\n\t\t\tt = DUK_U64_CONSTANT(0x4330000000000000) | (duk_uint64_t) tv->v.fi;\n\t\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\t\treturn du.d - 4503599627370496.0;  /* 1 << 52 */\n\t\t} else {\n\t\t\tt = DUK_U64_CONSTANT(0xc330000000000000) | (duk_uint64_t) (-tv->v.fi);\n\t\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\t\treturn du.d + 4503599627370496.0;  /* 1 << 52 */\n\t\t}\n\t} else {\n\t\treturn tv->v.d;\n\t}\n}\n#endif  /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */\n#endif  /* 0 */\n\n#if defined(DUK_USE_FASTINT) && !defined(DUK_USE_PACKED_TVAL)\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked_fastint(duk_tval *tv) {\n\tduk_double_union du;\n\tduk_uint64_t t;\n\n\tDUK_ASSERT(tv->t == DUK_TAG_FASTINT);\n\n\tif (tv->v.fi >= 0) {\n\t\tt = DUK_U64_CONSTANT(0x4330000000000000) | (duk_uint64_t) tv->v.fi;\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d - 4503599627370496.0;  /* 1 << 52 */\n\t} else {\n\t\tt = DUK_U64_CONSTANT(0xc330000000000000) | (duk_uint64_t) (-tv->v.fi);\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d + 4503599627370496.0;  /* 1 << 52 */\n\t}\n}\n#endif  /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */\n\n#endif  /* DUK_USE_FASTINT */\n\n/*\n *  Assertion helpers.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL void duk_tval_assert_valid(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n}\n#endif\n#line 1 \"duk_unicode_tables.c\"\n/*\n *  Unicode support tables automatically generated during build.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Unicode tables containing ranges of Unicode characters in a\n *  packed format.  These tables are used to match non-ASCII\n *  characters of complex productions by resorting to a linear\n *  range-by-range comparison.  This is very slow, but is expected\n *  to be very rare in practical ECMAScript source code, and thus\n *  compactness is most important.\n *\n *  The tables are matched using uni_range_match() and the format\n *  is described in tools/extract_chars.py.\n */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/* IdentifierStart production with ASCII excluded */\n/* duk_unicode_ids_noa[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_ids_noa[1116] = {\n249,176,176,80,111,7,47,15,47,254,11,197,191,0,72,2,15,115,66,19,50,7,2,34,\n2,240,66,244,50,247,185,249,98,241,99,7,241,159,57,240,181,63,31,241,191,\n21,18,245,50,15,1,24,27,35,15,2,2,240,239,15,244,156,15,10,241,26,21,6,240,\n101,10,4,15,9,240,152,175,39,240,82,127,56,242,100,15,4,8,159,1,240,5,115,\n19,240,98,98,4,52,15,2,14,18,47,0,27,9,85,19,240,98,98,18,18,31,17,50,15,5,\n47,2,130,34,240,98,98,18,68,15,4,15,1,31,9,12,115,19,240,98,98,18,68,15,16,\n18,47,1,15,3,2,84,34,52,18,2,20,20,36,191,8,15,38,114,34,240,114,240,4,15,\n12,38,31,16,5,114,34,240,114,146,68,15,18,2,31,1,31,4,114,34,241,147,15,2,\n6,41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,2,66,240,130,\n2,146,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,2,85,52,4,\n24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,35,63,17,35,\n54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,227,240,18,240,\n166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,21,5,15,53,244,\n152,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,175,40,240,122,\n242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,79,27,43,241,67,\n136,241,179,47,27,50,82,20,6,251,15,50,255,224,8,53,63,22,53,55,32,32,32,\n47,15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,32,\n68,112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,87,\n52,29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,254,\n12,146,240,184,132,52,95,70,114,47,74,35,111,27,47,78,240,63,11,242,127,0,\n255,224,244,255,240,0,138,143,60,255,240,4,14,47,2,255,227,127,243,95,30,\n63,253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,37,52,242,42,\n34,35,47,7,240,255,36,240,15,34,243,5,64,33,207,12,191,7,240,191,13,143,31,\n240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,48,32,\n240,162,58,130,213,53,53,166,38,47,27,43,159,99,240,255,255,0,26,150,223,7,\n95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,18,245,\n207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,127,10,\n207,73,69,53,53,50,241,91,47,10,47,3,33,46,61,241,79,107,243,127,37,255,\n223,13,79,33,242,31,16,239,14,111,22,191,14,63,20,87,36,241,207,142,240,79,\n20,95,20,95,24,159,36,248,239,254,2,154,240,107,127,138,83,2,241,194,20,3,\n240,123,240,122,240,255,51,240,50,27,240,107,240,175,56,242,135,31,50,15,1,\n50,34,240,223,28,240,212,240,223,21,114,240,207,13,242,107,240,107,240,62,\n240,47,96,243,159,41,242,62,242,62,241,79,254,13,15,13,176,159,6,248,207,7,\n223,37,243,223,29,241,47,9,240,207,20,240,240,207,19,64,223,32,240,3,240,\n112,32,241,95,2,47,9,244,102,32,35,46,41,143,31,241,135,49,63,6,38,33,36,\n64,240,64,212,249,15,37,240,67,240,96,241,47,32,240,97,32,250,175,31,241,\n179,241,111,32,240,96,242,223,27,224,243,159,11,253,127,28,246,111,48,241,\n16,249,39,63,23,240,32,32,240,224,191,24,128,240,112,207,30,240,80,241,79,\n41,255,152,47,21,240,48,242,63,14,246,38,33,47,22,240,112,240,181,33,47,16,\n240,0,255,224,59,240,63,254,0,31,254,40,207,88,245,255,3,251,79,254,155,15,\n254,50,31,254,236,95,254,19,159,255,0,16,173,255,225,43,143,15,246,63,14,\n240,79,32,240,35,241,31,5,111,3,255,225,164,243,15,114,243,182,15,52,207,\n50,18,15,14,255,240,0,110,169,255,225,229,255,240,1,64,31,254,1,31,35,47,3,\n57,255,224,126,255,231,248,245,182,196,136,159,255,0,6,90,244,82,243,114,\n19,3,19,50,178,2,98,243,18,51,114,98,240,194,50,66,4,98,255,224,70,63,9,47,\n9,47,15,47,9,47,15,47,9,47,15,47,9,47,15,47,9,39,255,232,40,241,219,111,2,\n15,254,6,95,28,255,228,8,251,95,45,243,72,15,254,58,131,47,11,33,32,48,41,\n35,32,32,112,80,32,32,34,33,32,48,32,32,32,32,33,32,51,38,35,35,32,41,47,1,\n98,36,47,1,255,240,0,3,143,255,0,149,201,241,191,254,242,124,252,227,255,\n240,0,87,79,0,255,240,0,194,63,254,177,63,254,17,0,\n};\n#else\n/* IdentifierStart production with ASCII and non-BMP excluded */\n/* duk_unicode_ids_noabmp[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_ids_noabmp[625] = {\n249,176,176,80,111,7,47,15,47,254,11,197,191,0,72,2,15,115,66,19,50,7,2,34,\n2,240,66,244,50,247,185,249,98,241,99,7,241,159,57,240,181,63,31,241,191,\n21,18,245,50,15,1,24,27,35,15,2,2,240,239,15,244,156,15,10,241,26,21,6,240,\n101,10,4,15,9,240,152,175,39,240,82,127,56,242,100,15,4,8,159,1,240,5,115,\n19,240,98,98,4,52,15,2,14,18,47,0,27,9,85,19,240,98,98,18,18,31,17,50,15,5,\n47,2,130,34,240,98,98,18,68,15,4,15,1,31,9,12,115,19,240,98,98,18,68,15,16,\n18,47,1,15,3,2,84,34,52,18,2,20,20,36,191,8,15,38,114,34,240,114,240,4,15,\n12,38,31,16,5,114,34,240,114,146,68,15,18,2,31,1,31,4,114,34,241,147,15,2,\n6,41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,2,66,240,130,\n2,146,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,2,85,52,4,\n24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,35,63,17,35,\n54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,227,240,18,240,\n166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,21,5,15,53,244,\n152,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,175,40,240,122,\n242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,79,27,43,241,67,\n136,241,179,47,27,50,82,20,6,251,15,50,255,224,8,53,63,22,53,55,32,32,32,\n47,15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,32,\n68,112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,87,\n52,29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,254,\n12,146,240,184,132,52,95,70,114,47,74,35,111,27,47,78,240,63,11,242,127,0,\n255,224,244,255,240,0,138,143,60,255,240,4,14,47,2,255,227,127,243,95,30,\n63,253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,37,52,242,42,\n34,35,47,7,240,255,36,240,15,34,243,5,64,33,207,12,191,7,240,191,13,143,31,\n240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,48,32,\n240,162,58,130,213,53,53,166,38,47,27,43,159,99,240,255,255,0,26,150,223,7,\n95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,18,245,\n207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,127,10,\n207,73,69,53,53,50,0,\n};\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/* IdentifierStart production with Letter and ASCII excluded */\n/* duk_unicode_ids_m_let_noa[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_ids_m_let_noa[42] = {\n255,240,0,94,18,255,233,99,241,51,63,254,215,32,240,184,240,2,255,240,6,89,\n249,255,240,4,148,79,37,255,224,192,9,15,120,79,255,0,15,30,245,240,\n};\n#else\n/* IdentifierStart production with Letter, ASCII, and non-BMP excluded */\n/* duk_unicode_ids_m_let_noabmp[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_ids_m_let_noabmp[24] = {\n255,240,0,94,18,255,233,99,241,51,63,254,215,32,240,184,240,2,255,240,6,89,\n249,0,\n};\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/* IdentifierPart production with IdentifierStart and ASCII excluded */\n/* duk_unicode_idp_m_ids_noa[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_idp_m_ids_noa[576] = {\n255,225,243,246,15,254,0,116,255,191,29,32,33,33,32,243,170,242,47,15,112,\n245,118,53,49,35,57,240,144,241,15,11,244,218,240,25,241,56,160,240,163,40,\n34,36,241,210,246,158,47,17,242,130,47,2,38,177,57,240,50,242,160,38,49,50,\n160,177,57,240,0,50,242,160,36,81,50,64,240,107,64,194,242,160,39,34,34,\n240,97,57,181,34,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240,\n9,240,36,242,182,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240,\n35,242,145,38,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54,\n215,41,244,144,56,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160,\n245,111,4,41,211,82,34,54,67,235,46,255,225,179,47,254,42,98,240,242,240,\n241,241,1,243,47,16,160,57,241,50,57,245,209,241,64,246,139,91,185,247,41,\n242,244,242,185,47,13,58,121,240,141,243,68,242,31,1,201,240,56,210,241,12,\n57,241,237,242,47,4,153,121,246,130,47,5,80,112,50,251,143,42,36,255,225,0,\n31,35,31,5,15,109,197,4,191,254,175,34,247,240,245,47,16,255,225,30,95,91,\n31,255,0,100,121,159,55,5,159,18,31,66,31,254,0,64,64,80,240,148,244,161,\n242,79,2,185,127,2,234,240,231,240,188,241,227,242,29,240,25,192,185,242,\n29,208,145,57,241,50,242,64,34,49,97,32,241,180,97,253,231,33,57,255,240,3,\n225,128,255,225,213,240,15,2,240,4,31,10,47,178,159,23,15,254,27,16,253,64,\n248,116,255,224,25,159,254,68,178,33,99,241,162,80,249,113,255,225,49,57,\n159,254,16,10,250,18,242,126,241,25,240,19,241,250,242,121,114,241,109,41,\n97,241,224,210,242,45,147,73,244,75,112,249,43,105,115,242,145,38,49,50,\n160,177,54,68,251,47,2,169,80,244,63,4,217,252,118,56,240,209,244,79,1,240,\n25,244,60,153,244,94,89,254,78,249,121,253,150,54,64,240,233,241,166,35,\n144,170,242,15,0,255,224,137,114,127,2,159,42,240,98,223,108,84,2,18,98,9,\n159,34,66,18,73,159,254,3,211,255,240,3,165,217,247,132,242,214,240,185,\n255,226,233,2,242,120,63,255,0,59,254,31,255,0,3,186,68,89,115,111,16,63,\n134,47,254,71,223,34,255,224,244,242,117,242,41,15,0,15,8,66,239,254,68,70,\n47,1,54,33,36,255,118,169,255,224,150,223,254,76,166,245,246,105,255,240,\n192,105,175,224,0,\n};\n#else\n/* IdentifierPart production with IdentifierStart, ASCII, and non-BMP excluded */\n/* duk_unicode_idp_m_ids_noabmp[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_idp_m_ids_noabmp[358] = {\n255,225,243,246,15,254,0,116,255,191,29,32,33,33,32,243,170,242,47,15,112,\n245,118,53,49,35,57,240,144,241,15,11,244,218,240,25,241,56,160,240,163,40,\n34,36,241,210,246,158,47,17,242,130,47,2,38,177,57,240,50,242,160,38,49,50,\n160,177,57,240,0,50,242,160,36,81,50,64,240,107,64,194,242,160,39,34,34,\n240,97,57,181,34,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240,\n9,240,36,242,182,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240,\n35,242,145,38,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54,\n215,41,244,144,56,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160,\n245,111,4,41,211,82,34,54,67,235,46,255,225,179,47,254,42,98,240,242,240,\n241,241,1,243,47,16,160,57,241,50,57,245,209,241,64,246,139,91,185,247,41,\n242,244,242,185,47,13,58,121,240,141,243,68,242,31,1,201,240,56,210,241,12,\n57,241,237,242,47,4,153,121,246,130,47,5,80,112,50,251,143,42,36,255,225,0,\n31,35,31,5,15,109,197,4,191,254,175,34,247,240,245,47,16,255,225,30,95,91,\n31,255,0,100,121,159,55,5,159,18,31,66,31,254,0,64,64,80,240,148,244,161,\n242,79,2,185,127,2,234,240,231,240,188,241,227,242,29,240,25,192,185,242,\n29,208,145,57,241,50,242,64,34,49,97,32,241,180,97,253,231,33,57,255,240,3,\n225,128,255,225,213,240,15,2,240,4,31,10,47,178,159,23,0,\n};\n#endif\n\n/*\n *  Case conversion tables generated using tools/extract_caseconv.py.\n */\n\n/* duk_unicode_caseconv_uc[] */\n/* duk_unicode_caseconv_lc[] */\n\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_caseconv_uc[1411] = {\n152,3,128,3,0,184,7,192,6,192,112,35,242,199,224,64,74,192,49,32,128,162,\n128,108,65,1,189,129,254,131,3,173,3,136,6,7,98,7,34,68,15,12,14,140,72,30,\n104,28,112,32,67,0,65,4,0,138,0,128,4,1,88,65,76,83,8,104,14,72,43,16,253,\n28,189,6,39,240,39,224,24,114,12,16,132,16,248,0,248,64,129,241,1,241,128,\n195,228,3,229,2,7,204,7,206,4,15,160,15,164,6,31,96,31,104,16,62,224,63,\n116,8,125,200,127,32,32,251,176,254,208,33,247,129,255,128,67,239,67,253,\n64,135,223,7,254,129,15,216,15,220,2,31,208,31,216,4,63,192,63,208,8,133,\n192,133,128,129,38,129,37,177,162,195,2,192,5,229,160,2,20,9,170,220,4,232,\n40,127,160,255,144,154,136,4,4,4,0,192,9,152,9,144,48,19,160,19,145,0,41,\n96,41,69,192,94,128,94,65,128,193,128,193,2,1,161,1,160,6,3,104,3,102,8,7,\n56,7,52,64,14,248,14,240,144,31,144,31,130,128,68,96,68,66,64,145,192,145,\n130,129,184,129,184,2,3,217,3,216,24,8,194,8,192,68,18,44,18,40,216,38,16,\n38,8,112,77,16,77,6,3,192,35,192,18,199,168,71,168,24,15,168,143,172,132,\n44,104,44,103,6,89,2,89,0,200,179,176,179,172,21,50,13,50,1,122,104,26,104,\n1,212,228,116,228,65,233,204,233,204,143,211,189,83,188,130,167,127,167,\n126,11,79,35,79,32,10,158,94,158,88,85,61,173,61,160,97,192,107,64,107,1,0,\n226,128,226,3,1,198,1,196,6,3,228,3,226,8,10,0,6,152,16,31,192,31,184,34,\n199,50,199,32,65,128,196,0,195,130,1,185,1,184,4,4,205,79,84,8,0,192,143,0,\n142,193,1,52,128,203,2,45,39,16,199,5,253,0,11,80,57,192,15,240,23,128,19,\n16,4,144,23,240,5,48,24,0,36,48,25,32,25,16,25,80,31,96,25,144,25,128,25,\n160,35,208,25,224,34,0,26,128,26,112,27,240,31,112,29,208,24,224,31,48,31,\n16,37,2,198,240,37,18,198,208,37,34,199,0,37,48,24,16,37,64,24,96,37,144,\n24,240,37,176,25,0,37,202,122,176,38,0,25,48,38,26,122,192,38,48,25,64,38,\n90,120,208,38,128,25,112,38,178,198,32,38,202,122,208,39,18,198,224,39,32,\n25,208,39,80,25,240,39,210,198,64,40,42,124,80,40,122,123,16,40,128,26,224,\n40,144,36,64,40,192,36,80,41,32,27,112,41,218,123,32,41,234,123,0,52,80,57,\n144,55,112,55,96,58,192,56,96,60,32,58,48,60,192,56,192,61,0,57,32,61,16,\n57,128,61,80,58,96,61,96,58,0,61,112,60,240,63,0,57,160,63,16,58,16,63,32,\n63,144,63,48,55,240,63,80,57,80,76,240,76,1,200,0,65,33,200,16,65,65,200,\n32,65,225,200,80,66,33,200,96,66,161,200,112,70,33,200,138,100,161,215,154,\n119,209,215,210,198,49,216,234,124,97,233,177,230,1,251,224,57,145,254,81,\n254,194,20,226,19,34,24,66,24,50,198,18,198,2,198,80,35,162,198,96,35,226,\n207,50,207,42,120,202,120,186,121,74,124,74,124,58,124,42,181,58,123,60,\n192,27,240,2,152,2,152,10,76,5,120,0,156,3,225,0,37,1,134,1,200,96,115,32,\n97,0,96,32,118,24,29,40,24,64,24,8,44,60,10,106,10,164,61,45,0,36,1,152,\n143,75,192,10,128,97,3,211,16,2,184,24,80,244,204,0,178,6,20,61,53,0,32,\n129,95,15,168,64,116,160,98,99,234,88,29,40,24,152,24,0,250,166,7,74,6,38,\n6,2,62,173,129,210,129,137,129,161,15,192,67,225,0,115,35,240,48,248,72,28,\n200,252,20,62,20,7,50,63,7,15,133,129,204,143,194,67,225,128,115,35,240,\n176,248,104,28,200,252,52,62,28,7,50,63,15,15,135,129,204,143,196,67,225,0,\n115,35,241,48,248,72,28,200,252,84,62,20,7,50,63,23,15,133,129,204,143,198,\n67,225,128,115,35,241,176,248,104,28,200,252,116,62,28,7,50,63,31,15,135,\n129,204,143,200,67,229,0,115,35,242,48,249,72,28,200,252,148,62,84,7,50,63,\n39,15,149,129,204,143,202,67,229,128,115,35,242,176,249,104,28,200,252,180,\n62,92,7,50,63,47,15,151,129,204,143,204,67,229,0,115,35,243,48,249,72,28,\n200,252,212,62,84,7,50,63,55,15,149,129,204,143,206,67,229,128,115,35,243,\n176,249,104,28,200,252,244,62,92,7,50,63,63,15,151,129,204,143,208,67,237,\n0,115,35,244,48,251,72,28,200,253,20,62,212,7,50,63,71,15,181,129,204,143,\n210,67,237,128,115,35,244,176,251,104,28,200,253,52,62,220,7,50,63,79,15,\n183,129,204,143,212,67,237,0,115,35,245,48,251,72,28,200,253,84,62,212,7,\n50,63,87,15,181,129,204,143,214,67,237,128,115,35,245,176,251,104,28,200,\n253,116,62,220,7,50,63,95,15,183,129,204,143,217,67,247,64,115,35,246,112,\n28,136,28,200,253,164,7,12,7,50,63,109,1,200,129,161,15,219,224,114,32,104,\n64,115,35,247,144,28,136,28,200,254,20,63,148,7,50,63,135,1,203,129,204,\n143,226,64,113,32,115,35,248,208,28,184,26,16,254,62,7,46,6,132,7,50,63,\n153,1,203,129,204,143,233,96,115,32,97,0,96,3,250,120,28,200,24,64,24,8,\n254,180,7,50,6,132,63,175,129,204,129,132,1,161,15,241,96,116,160,97,0,96,\n3,252,120,29,40,24,64,24,8,255,36,7,66,6,38,63,205,1,210,129,161,15,243,\n224,116,160,97,0,104,67,254,80,255,208,28,200,255,156,7,82,7,50,63,233,1,\n199,129,204,143,251,64,117,32,104,67,254,248,29,72,26,16,28,200,255,228,7,\n82,7,51,246,1,0,35,0,35,125,128,192,8,192,9,63,96,80,2,48,2,103,216,30,0,\n140,0,140,0,147,246,9,128,35,0,35,0,38,125,130,192,10,96,10,159,96,208,2,\n152,2,167,216,156,10,136,10,141,246,41,2,162,2,154,253,138,192,168,128,167,\n127,98,208,42,112,42,55,216,188,10,136,10,122,\n};\nconst duk_uint8_t duk_unicode_caseconv_lc[706] = {\n160,3,0,3,128,184,6,192,7,192,112,24,144,37,96,64,54,32,81,64,128,226,0,\n235,65,129,199,1,230,130,3,145,3,177,34,7,70,7,134,36,15,244,13,236,24,32,\n0,34,129,0,65,0,67,4,0,166,32,172,41,132,40,11,64,19,9,208,85,184,80,19,\n240,19,248,12,57,32,33,160,172,114,244,67,244,24,248,64,248,0,129,241,129,\n241,0,195,229,3,228,2,7,206,7,204,4,15,164,15,160,6,31,104,31,96,16,63,16,\n63,0,32,126,96,126,64,64,253,64,253,0,129,251,129,251,0,67,247,67,238,0,\n135,242,7,220,130,15,236,15,232,2,31,218,31,118,4,63,208,63,192,8,127,168,\n125,232,16,255,192,251,192,33,255,161,247,192,68,44,4,46,4,9,45,137,52,13,\n22,0,22,24,47,44,126,2,63,5,254,67,254,130,106,48,16,0,16,19,0,38,64,38,96,\n192,78,64,78,132,0,165,0,165,151,1,121,1,122,6,3,4,3,6,8,6,128,6,132,24,13,\n152,13,160,32,28,176,28,193,32,59,192,59,226,64,124,128,124,193,0,252,0,\n252,148,2,34,2,35,18,4,140,4,142,20,13,192,13,196,16,30,192,30,200,192,70,\n0,70,18,32,145,64,145,102,193,48,65,48,131,130,104,2,104,176,30,0,30,1,150,\n61,64,61,66,192,125,100,125,68,33,99,57,99,64,50,200,2,200,22,69,157,101,\n157,128,169,144,41,144,75,211,64,83,64,142,167,34,167,35,15,78,101,78,102,\n126,157,230,157,232,21,59,245,59,248,90,121,10,121,16,84,242,212,242,226,\n169,237,41,237,67,12,3,76,5,0,8,6,176,6,180,16,14,32,14,48,48,28,80,28,96,\n64,126,224,127,0,139,28,139,28,193,6,3,14,3,16,8,6,224,6,228,21,61,80,19,\n48,32,3,1,150,2,105,4,4,118,4,120,8,67,28,180,156,23,240,192,94,0,63,192,\n96,64,148,192,97,128,149,0,99,128,119,64,99,192,150,64,100,0,150,192,100,\n64,100,128,100,192,152,0,101,0,152,192,101,192,154,0,102,0,102,64,103,64,\n156,128,103,192,157,64,105,192,106,0,107,128,162,0,109,192,164,128,124,64,\n124,192,125,128,101,64,125,192,111,192,136,0,103,128,142,139,25,64,143,64,\n102,128,143,139,25,128,144,192,96,0,145,0,162,64,145,64,163,0,221,128,221,\n192,223,192,252,192,225,128,235,0,227,0,243,0,243,192,245,192,253,0,238,0,\n254,64,252,129,48,1,51,199,167,128,55,199,239,7,236,199,243,7,240,199,251,\n7,249,71,255,7,252,200,73,128,242,72,74,128,26,200,74,192,57,72,76,136,83,\n136,96,200,97,11,24,11,24,75,24,128,154,203,24,199,95,75,25,0,159,75,27,64,\n148,75,27,128,156,75,27,192,148,11,28,0,148,139,60,139,60,233,223,71,94,\n105,226,233,227,41,227,64,153,105,234,192,151,41,235,0,152,105,235,64,155,\n41,236,0,167,169,236,64,161,233,236,128,167,105,236,234,212,233,240,169,\n240,233,241,41,229,41,241,64,160,169,241,135,99,128,128,152,64,13,32,96,\n224,\n};\n\n#if defined(DUK_USE_REGEXP_CANON_WORKAROUND)\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\nconst duk_uint16_t duk_unicode_re_canon_lookup[65536] = {\n0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,\n28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,\n53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,\n78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,65,66,67,68,69,70,\n71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,123,124,125,\n126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,\n144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,\n162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,\n180,924,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,\n198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,\n216,217,218,219,220,221,222,223,192,193,194,195,196,197,198,199,200,201,\n202,203,204,205,206,207,208,209,210,211,212,213,214,247,216,217,218,219,\n220,221,222,376,256,256,258,258,260,260,262,262,264,264,266,266,268,268,\n270,270,272,272,274,274,276,276,278,278,280,280,282,282,284,284,286,286,\n288,288,290,290,292,292,294,294,296,296,298,298,300,300,302,302,304,305,\n306,306,308,308,310,310,312,313,313,315,315,317,317,319,319,321,321,323,\n323,325,325,327,327,329,330,330,332,332,334,334,336,336,338,338,340,340,\n342,342,344,344,346,346,348,348,350,350,352,352,354,354,356,356,358,358,\n360,360,362,362,364,364,366,366,368,368,370,370,372,372,374,374,376,377,\n377,379,379,381,381,383,579,385,386,386,388,388,390,391,391,393,394,395,\n395,397,398,399,400,401,401,403,404,502,406,407,408,408,573,411,412,413,\n544,415,416,416,418,418,420,420,422,423,423,425,426,427,428,428,430,431,\n431,433,434,435,435,437,437,439,440,440,442,443,444,444,446,503,448,449,\n450,451,452,452,452,455,455,455,458,458,458,461,461,463,463,465,465,467,\n467,469,469,471,471,473,473,475,475,398,478,478,480,480,482,482,484,484,\n486,486,488,488,490,490,492,492,494,494,496,497,497,497,500,500,502,503,\n504,504,506,506,508,508,510,510,512,512,514,514,516,516,518,518,520,520,\n522,522,524,524,526,526,528,528,530,530,532,532,534,534,536,536,538,538,\n540,540,542,542,544,545,546,546,548,548,550,550,552,552,554,554,556,556,\n558,558,560,560,562,562,564,565,566,567,568,569,570,571,571,573,574,11390,\n11391,577,577,579,580,581,582,582,584,584,586,586,588,588,590,590,11375,\n11373,11376,385,390,597,393,394,600,399,602,400,42923L,605,606,607,403,\n42924L,610,404,612,42893L,42922L,615,407,406,42926L,11362,42925L,621,622,\n412,624,11374,413,627,628,415,630,631,632,633,634,635,636,11364,638,639,\n422,641,42949L,425,644,645,646,42929L,430,580,433,434,581,653,654,655,656,\n657,439,659,660,661,662,663,664,665,666,667,668,42930L,42928L,671,672,673,\n674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,\n692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,\n710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,\n728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,\n746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,\n764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,\n782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,\n800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,\n818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,\n836,921,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,\n854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,\n872,873,874,875,876,877,878,879,880,880,882,882,884,885,886,886,888,889,\n890,1021,1022,1023,894,895,896,897,898,899,900,901,902,903,904,905,906,907,\n908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,\n926,927,928,929,930,931,932,933,934,935,936,937,938,939,902,904,905,906,\n944,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,\n931,931,932,933,934,935,936,937,938,939,908,910,911,975,914,920,978,979,\n980,934,928,975,984,984,986,986,988,988,990,990,992,992,994,994,996,996,\n998,998,1000,1000,1002,1002,1004,1004,1006,1006,922,929,1017,895,1012,917,\n1014,1015,1015,1017,1018,1018,1020,1021,1022,1023,1024,1025,1026,1027,1028,\n1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,\n1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,\n1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1040,1041,\n1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,\n1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,\n1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,\n1039,1120,1120,1122,1122,1124,1124,1126,1126,1128,1128,1130,1130,1132,1132,\n1134,1134,1136,1136,1138,1138,1140,1140,1142,1142,1144,1144,1146,1146,1148,\n1148,1150,1150,1152,1152,1154,1155,1156,1157,1158,1159,1160,1161,1162,1162,\n1164,1164,1166,1166,1168,1168,1170,1170,1172,1172,1174,1174,1176,1176,1178,\n1178,1180,1180,1182,1182,1184,1184,1186,1186,1188,1188,1190,1190,1192,1192,\n1194,1194,1196,1196,1198,1198,1200,1200,1202,1202,1204,1204,1206,1206,1208,\n1208,1210,1210,1212,1212,1214,1214,1216,1217,1217,1219,1219,1221,1221,1223,\n1223,1225,1225,1227,1227,1229,1229,1216,1232,1232,1234,1234,1236,1236,1238,\n1238,1240,1240,1242,1242,1244,1244,1246,1246,1248,1248,1250,1250,1252,1252,\n1254,1254,1256,1256,1258,1258,1260,1260,1262,1262,1264,1264,1266,1266,1268,\n1268,1270,1270,1272,1272,1274,1274,1276,1276,1278,1278,1280,1280,1282,1282,\n1284,1284,1286,1286,1288,1288,1290,1290,1292,1292,1294,1294,1296,1296,1298,\n1298,1300,1300,1302,1302,1304,1304,1306,1306,1308,1308,1310,1310,1312,1312,\n1314,1314,1316,1316,1318,1318,1320,1320,1322,1322,1324,1324,1326,1326,1328,\n1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,\n1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,\n1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,\n1374,1375,1376,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,\n1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,\n1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1415,1416,1417,1418,\n1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,\n1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,\n1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,\n1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,\n1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,\n1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,\n1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,\n1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,\n1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,\n1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,\n1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,\n1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,\n1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,\n1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,\n1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,\n1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,\n1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,\n1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,\n1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,\n1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,\n1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,\n1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,\n1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,\n1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,\n1779,1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,\n1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808,\n1809,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,\n1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,\n1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,\n1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1867,1868,\n1869,1870,1871,1872,1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,\n1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,1898,\n1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,\n1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,\n1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,\n1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,\n1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,\n1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,\n1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,\n2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,\n2019,2020,2021,2022,2023,2024,2025,2026,2027,2028,2029,2030,2031,2032,2033,\n2034,2035,2036,2037,2038,2039,2040,2041,2042,2043,2044,2045,2046,2047,2048,\n2049,2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063,\n2064,2065,2066,2067,2068,2069,2070,2071,2072,2073,2074,2075,2076,2077,2078,\n2079,2080,2081,2082,2083,2084,2085,2086,2087,2088,2089,2090,2091,2092,2093,\n2094,2095,2096,2097,2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108,\n2109,2110,2111,2112,2113,2114,2115,2116,2117,2118,2119,2120,2121,2122,2123,\n2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2137,2138,\n2139,2140,2141,2142,2143,2144,2145,2146,2147,2148,2149,2150,2151,2152,2153,\n2154,2155,2156,2157,2158,2159,2160,2161,2162,2163,2164,2165,2166,2167,2168,\n2169,2170,2171,2172,2173,2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,\n2184,2185,2186,2187,2188,2189,2190,2191,2192,2193,2194,2195,2196,2197,2198,\n2199,2200,2201,2202,2203,2204,2205,2206,2207,2208,2209,2210,2211,2212,2213,\n2214,2215,2216,2217,2218,2219,2220,2221,2222,2223,2224,2225,2226,2227,2228,\n2229,2230,2231,2232,2233,2234,2235,2236,2237,2238,2239,2240,2241,2242,2243,\n2244,2245,2246,2247,2248,2249,2250,2251,2252,2253,2254,2255,2256,2257,2258,\n2259,2260,2261,2262,2263,2264,2265,2266,2267,2268,2269,2270,2271,2272,2273,\n2274,2275,2276,2277,2278,2279,2280,2281,2282,2283,2284,2285,2286,2287,2288,\n2289,2290,2291,2292,2293,2294,2295,2296,2297,2298,2299,2300,2301,2302,2303,\n2304,2305,2306,2307,2308,2309,2310,2311,2312,2313,2314,2315,2316,2317,2318,\n2319,2320,2321,2322,2323,2324,2325,2326,2327,2328,2329,2330,2331,2332,2333,\n2334,2335,2336,2337,2338,2339,2340,2341,2342,2343,2344,2345,2346,2347,2348,\n2349,2350,2351,2352,2353,2354,2355,2356,2357,2358,2359,2360,2361,2362,2363,\n2364,2365,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,\n2379,2380,2381,2382,2383,2384,2385,2386,2387,2388,2389,2390,2391,2392,2393,\n2394,2395,2396,2397,2398,2399,2400,2401,2402,2403,2404,2405,2406,2407,2408,\n2409,2410,2411,2412,2413,2414,2415,2416,2417,2418,2419,2420,2421,2422,2423,\n2424,2425,2426,2427,2428,2429,2430,2431,2432,2433,2434,2435,2436,2437,2438,\n2439,2440,2441,2442,2443,2444,2445,2446,2447,2448,2449,2450,2451,2452,2453,\n2454,2455,2456,2457,2458,2459,2460,2461,2462,2463,2464,2465,2466,2467,2468,\n2469,2470,2471,2472,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,\n2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2495,2496,2497,2498,\n2499,2500,2501,2502,2503,2504,2505,2506,2507,2508,2509,2510,2511,2512,2513,\n2514,2515,2516,2517,2518,2519,2520,2521,2522,2523,2524,2525,2526,2527,2528,\n2529,2530,2531,2532,2533,2534,2535,2536,2537,2538,2539,2540,2541,2542,2543,\n2544,2545,2546,2547,2548,2549,2550,2551,2552,2553,2554,2555,2556,2557,2558,\n2559,2560,2561,2562,2563,2564,2565,2566,2567,2568,2569,2570,2571,2572,2573,\n2574,2575,2576,2577,2578,2579,2580,2581,2582,2583,2584,2585,2586,2587,2588,\n2589,2590,2591,2592,2593,2594,2595,2596,2597,2598,2599,2600,2601,2602,2603,\n2604,2605,2606,2607,2608,2609,2610,2611,2612,2613,2614,2615,2616,2617,2618,\n2619,2620,2621,2622,2623,2624,2625,2626,2627,2628,2629,2630,2631,2632,2633,\n2634,2635,2636,2637,2638,2639,2640,2641,2642,2643,2644,2645,2646,2647,2648,\n2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,2659,2660,2661,2662,2663,\n2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2674,2675,2676,2677,2678,\n2679,2680,2681,2682,2683,2684,2685,2686,2687,2688,2689,2690,2691,2692,2693,\n2694,2695,2696,2697,2698,2699,2700,2701,2702,2703,2704,2705,2706,2707,2708,\n2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720,2721,2722,2723,\n2724,2725,2726,2727,2728,2729,2730,2731,2732,2733,2734,2735,2736,2737,2738,\n2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750,2751,2752,2753,\n2754,2755,2756,2757,2758,2759,2760,2761,2762,2763,2764,2765,2766,2767,2768,\n2769,2770,2771,2772,2773,2774,2775,2776,2777,2778,2779,2780,2781,2782,2783,\n2784,2785,2786,2787,2788,2789,2790,2791,2792,2793,2794,2795,2796,2797,2798,\n2799,2800,2801,2802,2803,2804,2805,2806,2807,2808,2809,2810,2811,2812,2813,\n2814,2815,2816,2817,2818,2819,2820,2821,2822,2823,2824,2825,2826,2827,2828,\n2829,2830,2831,2832,2833,2834,2835,2836,2837,2838,2839,2840,2841,2842,2843,\n2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856,2857,2858,\n2859,2860,2861,2862,2863,2864,2865,2866,2867,2868,2869,2870,2871,2872,2873,\n2874,2875,2876,2877,2878,2879,2880,2881,2882,2883,2884,2885,2886,2887,2888,\n2889,2890,2891,2892,2893,2894,2895,2896,2897,2898,2899,2900,2901,2902,2903,\n2904,2905,2906,2907,2908,2909,2910,2911,2912,2913,2914,2915,2916,2917,2918,\n2919,2920,2921,2922,2923,2924,2925,2926,2927,2928,2929,2930,2931,2932,2933,\n2934,2935,2936,2937,2938,2939,2940,2941,2942,2943,2944,2945,2946,2947,2948,\n2949,2950,2951,2952,2953,2954,2955,2956,2957,2958,2959,2960,2961,2962,2963,\n2964,2965,2966,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976,2977,2978,\n2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2989,2990,2991,2992,2993,\n2994,2995,2996,2997,2998,2999,3000,3001,3002,3003,3004,3005,3006,3007,3008,\n3009,3010,3011,3012,3013,3014,3015,3016,3017,3018,3019,3020,3021,3022,3023,\n3024,3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037,3038,\n3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,3051,3052,3053,\n3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066,3067,3068,\n3069,3070,3071,3072,3073,3074,3075,3076,3077,3078,3079,3080,3081,3082,3083,\n3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095,3096,3097,3098,\n3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,3109,3110,3111,3112,3113,\n3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3124,3125,3126,3127,3128,\n3129,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140,3141,3142,3143,\n3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156,3157,3158,\n3159,3160,3161,3162,3163,3164,3165,3166,3167,3168,3169,3170,3171,3172,3173,\n3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186,3187,3188,\n3189,3190,3191,3192,3193,3194,3195,3196,3197,3198,3199,3200,3201,3202,3203,\n3204,3205,3206,3207,3208,3209,3210,3211,3212,3213,3214,3215,3216,3217,3218,\n3219,3220,3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3232,3233,\n3234,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248,\n3249,3250,3251,3252,3253,3254,3255,3256,3257,3258,3259,3260,3261,3262,3263,\n3264,3265,3266,3267,3268,3269,3270,3271,3272,3273,3274,3275,3276,3277,3278,\n3279,3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293,\n3294,3295,3296,3297,3298,3299,3300,3301,3302,3303,3304,3305,3306,3307,3308,\n3309,3310,3311,3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323,\n3324,3325,3326,3327,3328,3329,3330,3331,3332,3333,3334,3335,3336,3337,3338,\n3339,3340,3341,3342,3343,3344,3345,3346,3347,3348,3349,3350,3351,3352,3353,\n3354,3355,3356,3357,3358,3359,3360,3361,3362,3363,3364,3365,3366,3367,3368,\n3369,3370,3371,3372,3373,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383,\n3384,3385,3386,3387,3388,3389,3390,3391,3392,3393,3394,3395,3396,3397,3398,\n3399,3400,3401,3402,3403,3404,3405,3406,3407,3408,3409,3410,3411,3412,3413,\n3414,3415,3416,3417,3418,3419,3420,3421,3422,3423,3424,3425,3426,3427,3428,\n3429,3430,3431,3432,3433,3434,3435,3436,3437,3438,3439,3440,3441,3442,3443,\n3444,3445,3446,3447,3448,3449,3450,3451,3452,3453,3454,3455,3456,3457,3458,\n3459,3460,3461,3462,3463,3464,3465,3466,3467,3468,3469,3470,3471,3472,3473,\n3474,3475,3476,3477,3478,3479,3480,3481,3482,3483,3484,3485,3486,3487,3488,\n3489,3490,3491,3492,3493,3494,3495,3496,3497,3498,3499,3500,3501,3502,3503,\n3504,3505,3506,3507,3508,3509,3510,3511,3512,3513,3514,3515,3516,3517,3518,\n3519,3520,3521,3522,3523,3524,3525,3526,3527,3528,3529,3530,3531,3532,3533,\n3534,3535,3536,3537,3538,3539,3540,3541,3542,3543,3544,3545,3546,3547,3548,\n3549,3550,3551,3552,3553,3554,3555,3556,3557,3558,3559,3560,3561,3562,3563,\n3564,3565,3566,3567,3568,3569,3570,3571,3572,3573,3574,3575,3576,3577,3578,\n3579,3580,3581,3582,3583,3584,3585,3586,3587,3588,3589,3590,3591,3592,3593,\n3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607,3608,\n3609,3610,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,3621,3622,3623,\n3624,3625,3626,3627,3628,3629,3630,3631,3632,3633,3634,3635,3636,3637,3638,\n3639,3640,3641,3642,3643,3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,\n3654,3655,3656,3657,3658,3659,3660,3661,3662,3663,3664,3665,3666,3667,3668,\n3669,3670,3671,3672,3673,3674,3675,3676,3677,3678,3679,3680,3681,3682,3683,\n3684,3685,3686,3687,3688,3689,3690,3691,3692,3693,3694,3695,3696,3697,3698,\n3699,3700,3701,3702,3703,3704,3705,3706,3707,3708,3709,3710,3711,3712,3713,\n3714,3715,3716,3717,3718,3719,3720,3721,3722,3723,3724,3725,3726,3727,3728,\n3729,3730,3731,3732,3733,3734,3735,3736,3737,3738,3739,3740,3741,3742,3743,\n3744,3745,3746,3747,3748,3749,3750,3751,3752,3753,3754,3755,3756,3757,3758,\n3759,3760,3761,3762,3763,3764,3765,3766,3767,3768,3769,3770,3771,3772,3773,\n3774,3775,3776,3777,3778,3779,3780,3781,3782,3783,3784,3785,3786,3787,3788,\n3789,3790,3791,3792,3793,3794,3795,3796,3797,3798,3799,3800,3801,3802,3803,\n3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,3814,3815,3816,3817,3818,\n3819,3820,3821,3822,3823,3824,3825,3826,3827,3828,3829,3830,3831,3832,3833,\n3834,3835,3836,3837,3838,3839,3840,3841,3842,3843,3844,3845,3846,3847,3848,\n3849,3850,3851,3852,3853,3854,3855,3856,3857,3858,3859,3860,3861,3862,3863,\n3864,3865,3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877,3878,\n3879,3880,3881,3882,3883,3884,3885,3886,3887,3888,3889,3890,3891,3892,3893,\n3894,3895,3896,3897,3898,3899,3900,3901,3902,3903,3904,3905,3906,3907,3908,\n3909,3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,3920,3921,3922,3923,\n3924,3925,3926,3927,3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,\n3939,3940,3941,3942,3943,3944,3945,3946,3947,3948,3949,3950,3951,3952,3953,\n3954,3955,3956,3957,3958,3959,3960,3961,3962,3963,3964,3965,3966,3967,3968,\n3969,3970,3971,3972,3973,3974,3975,3976,3977,3978,3979,3980,3981,3982,3983,\n3984,3985,3986,3987,3988,3989,3990,3991,3992,3993,3994,3995,3996,3997,3998,\n3999,4000,4001,4002,4003,4004,4005,4006,4007,4008,4009,4010,4011,4012,4013,\n4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,\n4029,4030,4031,4032,4033,4034,4035,4036,4037,4038,4039,4040,4041,4042,4043,\n4044,4045,4046,4047,4048,4049,4050,4051,4052,4053,4054,4055,4056,4057,4058,\n4059,4060,4061,4062,4063,4064,4065,4066,4067,4068,4069,4070,4071,4072,4073,\n4074,4075,4076,4077,4078,4079,4080,4081,4082,4083,4084,4085,4086,4087,4088,\n4089,4090,4091,4092,4093,4094,4095,4096,4097,4098,4099,4100,4101,4102,4103,\n4104,4105,4106,4107,4108,4109,4110,4111,4112,4113,4114,4115,4116,4117,4118,\n4119,4120,4121,4122,4123,4124,4125,4126,4127,4128,4129,4130,4131,4132,4133,\n4134,4135,4136,4137,4138,4139,4140,4141,4142,4143,4144,4145,4146,4147,4148,\n4149,4150,4151,4152,4153,4154,4155,4156,4157,4158,4159,4160,4161,4162,4163,\n4164,4165,4166,4167,4168,4169,4170,4171,4172,4173,4174,4175,4176,4177,4178,\n4179,4180,4181,4182,4183,4184,4185,4186,4187,4188,4189,4190,4191,4192,4193,\n4194,4195,4196,4197,4198,4199,4200,4201,4202,4203,4204,4205,4206,4207,4208,\n4209,4210,4211,4212,4213,4214,4215,4216,4217,4218,4219,4220,4221,4222,4223,\n4224,4225,4226,4227,4228,4229,4230,4231,4232,4233,4234,4235,4236,4237,4238,\n4239,4240,4241,4242,4243,4244,4245,4246,4247,4248,4249,4250,4251,4252,4253,\n4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265,4266,4267,4268,\n4269,4270,4271,4272,4273,4274,4275,4276,4277,4278,4279,4280,4281,4282,4283,\n4284,4285,4286,4287,4288,4289,4290,4291,4292,4293,4294,4295,4296,4297,4298,\n4299,4300,4301,4302,4303,7312,7313,7314,7315,7316,7317,7318,7319,7320,7321,\n7322,7323,7324,7325,7326,7327,7328,7329,7330,7331,7332,7333,7334,7335,7336,\n7337,7338,7339,7340,7341,7342,7343,7344,7345,7346,7347,7348,7349,7350,7351,\n7352,7353,7354,4347,4348,7357,7358,7359,4352,4353,4354,4355,4356,4357,4358,\n4359,4360,4361,4362,4363,4364,4365,4366,4367,4368,4369,4370,4371,4372,4373,\n4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,4387,4388,\n4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403,\n4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,4417,4418,\n4419,4420,4421,4422,4423,4424,4425,4426,4427,4428,4429,4430,4431,4432,4433,\n4434,4435,4436,4437,4438,4439,4440,4441,4442,4443,4444,4445,4446,4447,4448,\n4449,4450,4451,4452,4453,4454,4455,4456,4457,4458,4459,4460,4461,4462,4463,\n4464,4465,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475,4476,4477,4478,\n4479,4480,4481,4482,4483,4484,4485,4486,4487,4488,4489,4490,4491,4492,4493,\n4494,4495,4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507,4508,\n4509,4510,4511,4512,4513,4514,4515,4516,4517,4518,4519,4520,4521,4522,4523,\n4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,4536,4537,4538,\n4539,4540,4541,4542,4543,4544,4545,4546,4547,4548,4549,4550,4551,4552,4553,\n4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567,4568,\n4569,4570,4571,4572,4573,4574,4575,4576,4577,4578,4579,4580,4581,4582,4583,\n4584,4585,4586,4587,4588,4589,4590,4591,4592,4593,4594,4595,4596,4597,4598,\n4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609,4610,4611,4612,4613,\n4614,4615,4616,4617,4618,4619,4620,4621,4622,4623,4624,4625,4626,4627,4628,\n4629,4630,4631,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,4643,\n4644,4645,4646,4647,4648,4649,4650,4651,4652,4653,4654,4655,4656,4657,4658,\n4659,4660,4661,4662,4663,4664,4665,4666,4667,4668,4669,4670,4671,4672,4673,\n4674,4675,4676,4677,4678,4679,4680,4681,4682,4683,4684,4685,4686,4687,4688,\n4689,4690,4691,4692,4693,4694,4695,4696,4697,4698,4699,4700,4701,4702,4703,\n4704,4705,4706,4707,4708,4709,4710,4711,4712,4713,4714,4715,4716,4717,4718,\n4719,4720,4721,4722,4723,4724,4725,4726,4727,4728,4729,4730,4731,4732,4733,\n4734,4735,4736,4737,4738,4739,4740,4741,4742,4743,4744,4745,4746,4747,4748,\n4749,4750,4751,4752,4753,4754,4755,4756,4757,4758,4759,4760,4761,4762,4763,\n4764,4765,4766,4767,4768,4769,4770,4771,4772,4773,4774,4775,4776,4777,4778,\n4779,4780,4781,4782,4783,4784,4785,4786,4787,4788,4789,4790,4791,4792,4793,\n4794,4795,4796,4797,4798,4799,4800,4801,4802,4803,4804,4805,4806,4807,4808,\n4809,4810,4811,4812,4813,4814,4815,4816,4817,4818,4819,4820,4821,4822,4823,\n4824,4825,4826,4827,4828,4829,4830,4831,4832,4833,4834,4835,4836,4837,4838,\n4839,4840,4841,4842,4843,4844,4845,4846,4847,4848,4849,4850,4851,4852,4853,\n4854,4855,4856,4857,4858,4859,4860,4861,4862,4863,4864,4865,4866,4867,4868,\n4869,4870,4871,4872,4873,4874,4875,4876,4877,4878,4879,4880,4881,4882,4883,\n4884,4885,4886,4887,4888,4889,4890,4891,4892,4893,4894,4895,4896,4897,4898,\n4899,4900,4901,4902,4903,4904,4905,4906,4907,4908,4909,4910,4911,4912,4913,\n4914,4915,4916,4917,4918,4919,4920,4921,4922,4923,4924,4925,4926,4927,4928,\n4929,4930,4931,4932,4933,4934,4935,4936,4937,4938,4939,4940,4941,4942,4943,\n4944,4945,4946,4947,4948,4949,4950,4951,4952,4953,4954,4955,4956,4957,4958,\n4959,4960,4961,4962,4963,4964,4965,4966,4967,4968,4969,4970,4971,4972,4973,\n4974,4975,4976,4977,4978,4979,4980,4981,4982,4983,4984,4985,4986,4987,4988,\n4989,4990,4991,4992,4993,4994,4995,4996,4997,4998,4999,5000,5001,5002,5003,\n5004,5005,5006,5007,5008,5009,5010,5011,5012,5013,5014,5015,5016,5017,5018,\n5019,5020,5021,5022,5023,5024,5025,5026,5027,5028,5029,5030,5031,5032,5033,\n5034,5035,5036,5037,5038,5039,5040,5041,5042,5043,5044,5045,5046,5047,5048,\n5049,5050,5051,5052,5053,5054,5055,5056,5057,5058,5059,5060,5061,5062,5063,\n5064,5065,5066,5067,5068,5069,5070,5071,5072,5073,5074,5075,5076,5077,5078,\n5079,5080,5081,5082,5083,5084,5085,5086,5087,5088,5089,5090,5091,5092,5093,\n5094,5095,5096,5097,5098,5099,5100,5101,5102,5103,5104,5105,5106,5107,5108,\n5109,5110,5111,5104,5105,5106,5107,5108,5109,5118,5119,5120,5121,5122,5123,\n5124,5125,5126,5127,5128,5129,5130,5131,5132,5133,5134,5135,5136,5137,5138,\n5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149,5150,5151,5152,5153,\n5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164,5165,5166,5167,5168,\n5169,5170,5171,5172,5173,5174,5175,5176,5177,5178,5179,5180,5181,5182,5183,\n5184,5185,5186,5187,5188,5189,5190,5191,5192,5193,5194,5195,5196,5197,5198,\n5199,5200,5201,5202,5203,5204,5205,5206,5207,5208,5209,5210,5211,5212,5213,\n5214,5215,5216,5217,5218,5219,5220,5221,5222,5223,5224,5225,5226,5227,5228,\n5229,5230,5231,5232,5233,5234,5235,5236,5237,5238,5239,5240,5241,5242,5243,\n5244,5245,5246,5247,5248,5249,5250,5251,5252,5253,5254,5255,5256,5257,5258,\n5259,5260,5261,5262,5263,5264,5265,5266,5267,5268,5269,5270,5271,5272,5273,\n5274,5275,5276,5277,5278,5279,5280,5281,5282,5283,5284,5285,5286,5287,5288,\n5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,\n5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,\n5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5332,5333,\n5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347,5348,\n5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363,\n5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,\n5379,5380,5381,5382,5383,5384,5385,5386,5387,5388,5389,5390,5391,5392,5393,\n5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408,\n5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,\n5424,5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,\n5439,5440,5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,\n5454,5455,5456,5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,\n5469,5470,5471,5472,5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,\n5484,5485,5486,5487,5488,5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,\n5499,5500,5501,5502,5503,5504,5505,5506,5507,5508,5509,5510,5511,5512,5513,\n5514,5515,5516,5517,5518,5519,5520,5521,5522,5523,5524,5525,5526,5527,5528,\n5529,5530,5531,5532,5533,5534,5535,5536,5537,5538,5539,5540,5541,5542,5543,\n5544,5545,5546,5547,5548,5549,5550,5551,5552,5553,5554,5555,5556,5557,5558,\n5559,5560,5561,5562,5563,5564,5565,5566,5567,5568,5569,5570,5571,5572,5573,\n5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584,5585,5586,5587,5588,\n5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600,5601,5602,5603,\n5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616,5617,5618,\n5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632,5633,\n5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648,\n5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,\n5664,5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,\n5679,5680,5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,\n5694,5695,5696,5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,\n5709,5710,5711,5712,5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,\n5724,5725,5726,5727,5728,5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,\n5739,5740,5741,5742,5743,5744,5745,5746,5747,5748,5749,5750,5751,5752,5753,\n5754,5755,5756,5757,5758,5759,5760,5761,5762,5763,5764,5765,5766,5767,5768,\n5769,5770,5771,5772,5773,5774,5775,5776,5777,5778,5779,5780,5781,5782,5783,\n5784,5785,5786,5787,5788,5789,5790,5791,5792,5793,5794,5795,5796,5797,5798,\n5799,5800,5801,5802,5803,5804,5805,5806,5807,5808,5809,5810,5811,5812,5813,\n5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828,\n5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,\n5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856,5857,5858,\n5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872,5873,\n5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888,\n5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,\n5904,5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,\n5919,5920,5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,\n5934,5935,5936,5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,\n5949,5950,5951,5952,5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,\n5964,5965,5966,5967,5968,5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,\n5979,5980,5981,5982,5983,5984,5985,5986,5987,5988,5989,5990,5991,5992,5993,\n5994,5995,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008,\n6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,\n6024,6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036,6037,6038,\n6039,6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052,6053,\n6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068,\n6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,\n6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,\n6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,\n6114,6115,6116,6117,6118,6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,\n6129,6130,6131,6132,6133,6134,6135,6136,6137,6138,6139,6140,6141,6142,6143,\n6144,6145,6146,6147,6148,6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,\n6159,6160,6161,6162,6163,6164,6165,6166,6167,6168,6169,6170,6171,6172,6173,\n6174,6175,6176,6177,6178,6179,6180,6181,6182,6183,6184,6185,6186,6187,6188,\n6189,6190,6191,6192,6193,6194,6195,6196,6197,6198,6199,6200,6201,6202,6203,\n6204,6205,6206,6207,6208,6209,6210,6211,6212,6213,6214,6215,6216,6217,6218,\n6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229,6230,6231,6232,6233,\n6234,6235,6236,6237,6238,6239,6240,6241,6242,6243,6244,6245,6246,6247,6248,\n6249,6250,6251,6252,6253,6254,6255,6256,6257,6258,6259,6260,6261,6262,6263,\n6264,6265,6266,6267,6268,6269,6270,6271,6272,6273,6274,6275,6276,6277,6278,\n6279,6280,6281,6282,6283,6284,6285,6286,6287,6288,6289,6290,6291,6292,6293,\n6294,6295,6296,6297,6298,6299,6300,6301,6302,6303,6304,6305,6306,6307,6308,\n6309,6310,6311,6312,6313,6314,6315,6316,6317,6318,6319,6320,6321,6322,6323,\n6324,6325,6326,6327,6328,6329,6330,6331,6332,6333,6334,6335,6336,6337,6338,\n6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349,6350,6351,6352,6353,\n6354,6355,6356,6357,6358,6359,6360,6361,6362,6363,6364,6365,6366,6367,6368,\n6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380,6381,6382,6383,\n6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,6396,6397,6398,\n6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,\n6414,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,6426,6427,6428,\n6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443,\n6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,6455,6456,6457,6458,\n6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472,6473,\n6474,6475,6476,6477,6478,6479,6480,6481,6482,6483,6484,6485,6486,6487,6488,\n6489,6490,6491,6492,6493,6494,6495,6496,6497,6498,6499,6500,6501,6502,6503,\n6504,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516,6517,6518,\n6519,6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532,6533,\n6534,6535,6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548,\n6549,6550,6551,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563,\n6564,6565,6566,6567,6568,6569,6570,6571,6572,6573,6574,6575,6576,6577,6578,\n6579,6580,6581,6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593,\n6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604,6605,6606,6607,6608,\n6609,6610,6611,6612,6613,6614,6615,6616,6617,6618,6619,6620,6621,6622,6623,\n6624,6625,6626,6627,6628,6629,6630,6631,6632,6633,6634,6635,6636,6637,6638,\n6639,6640,6641,6642,6643,6644,6645,6646,6647,6648,6649,6650,6651,6652,6653,\n6654,6655,6656,6657,6658,6659,6660,6661,6662,6663,6664,6665,6666,6667,6668,\n6669,6670,6671,6672,6673,6674,6675,6676,6677,6678,6679,6680,6681,6682,6683,\n6684,6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,6698,\n6699,6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711,6712,6713,\n6714,6715,6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,\n6729,6730,6731,6732,6733,6734,6735,6736,6737,6738,6739,6740,6741,6742,6743,\n6744,6745,6746,6747,6748,6749,6750,6751,6752,6753,6754,6755,6756,6757,6758,\n6759,6760,6761,6762,6763,6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,\n6774,6775,6776,6777,6778,6779,6780,6781,6782,6783,6784,6785,6786,6787,6788,\n6789,6790,6791,6792,6793,6794,6795,6796,6797,6798,6799,6800,6801,6802,6803,\n6804,6805,6806,6807,6808,6809,6810,6811,6812,6813,6814,6815,6816,6817,6818,\n6819,6820,6821,6822,6823,6824,6825,6826,6827,6828,6829,6830,6831,6832,6833,\n6834,6835,6836,6837,6838,6839,6840,6841,6842,6843,6844,6845,6846,6847,6848,\n6849,6850,6851,6852,6853,6854,6855,6856,6857,6858,6859,6860,6861,6862,6863,\n6864,6865,6866,6867,6868,6869,6870,6871,6872,6873,6874,6875,6876,6877,6878,\n6879,6880,6881,6882,6883,6884,6885,6886,6887,6888,6889,6890,6891,6892,6893,\n6894,6895,6896,6897,6898,6899,6900,6901,6902,6903,6904,6905,6906,6907,6908,\n6909,6910,6911,6912,6913,6914,6915,6916,6917,6918,6919,6920,6921,6922,6923,\n6924,6925,6926,6927,6928,6929,6930,6931,6932,6933,6934,6935,6936,6937,6938,\n6939,6940,6941,6942,6943,6944,6945,6946,6947,6948,6949,6950,6951,6952,6953,\n6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966,6967,6968,\n6969,6970,6971,6972,6973,6974,6975,6976,6977,6978,6979,6980,6981,6982,6983,\n6984,6985,6986,6987,6988,6989,6990,6991,6992,6993,6994,6995,6996,6997,6998,\n6999,7000,7001,7002,7003,7004,7005,7006,7007,7008,7009,7010,7011,7012,7013,\n7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027,7028,\n7029,7030,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,7043,\n7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058,\n7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7073,\n7074,7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7086,7087,7088,\n7089,7090,7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,\n7104,7105,7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,\n7119,7120,7121,7122,7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,\n7134,7135,7136,7137,7138,7139,7140,7141,7142,7143,7144,7145,7146,7147,7148,\n7149,7150,7151,7152,7153,7154,7155,7156,7157,7158,7159,7160,7161,7162,7163,\n7164,7165,7166,7167,7168,7169,7170,7171,7172,7173,7174,7175,7176,7177,7178,\n7179,7180,7181,7182,7183,7184,7185,7186,7187,7188,7189,7190,7191,7192,7193,\n7194,7195,7196,7197,7198,7199,7200,7201,7202,7203,7204,7205,7206,7207,7208,\n7209,7210,7211,7212,7213,7214,7215,7216,7217,7218,7219,7220,7221,7222,7223,\n7224,7225,7226,7227,7228,7229,7230,7231,7232,7233,7234,7235,7236,7237,7238,\n7239,7240,7241,7242,7243,7244,7245,7246,7247,7248,7249,7250,7251,7252,7253,\n7254,7255,7256,7257,7258,7259,7260,7261,7262,7263,7264,7265,7266,7267,7268,\n7269,7270,7271,7272,7273,7274,7275,7276,7277,7278,7279,7280,7281,7282,7283,\n7284,7285,7286,7287,7288,7289,7290,7291,7292,7293,7294,7295,1042,1044,1054,\n1057,1058,1058,1066,1122,42570L,7305,7306,7307,7308,7309,7310,7311,7312,\n7313,7314,7315,7316,7317,7318,7319,7320,7321,7322,7323,7324,7325,7326,7327,\n7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339,7340,7341,7342,\n7343,7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,7354,7355,7356,7357,\n7358,7359,7360,7361,7362,7363,7364,7365,7366,7367,7368,7369,7370,7371,7372,\n7373,7374,7375,7376,7377,7378,7379,7380,7381,7382,7383,7384,7385,7386,7387,\n7388,7389,7390,7391,7392,7393,7394,7395,7396,7397,7398,7399,7400,7401,7402,\n7403,7404,7405,7406,7407,7408,7409,7410,7411,7412,7413,7414,7415,7416,7417,\n7418,7419,7420,7421,7422,7423,7424,7425,7426,7427,7428,7429,7430,7431,7432,\n7433,7434,7435,7436,7437,7438,7439,7440,7441,7442,7443,7444,7445,7446,7447,\n7448,7449,7450,7451,7452,7453,7454,7455,7456,7457,7458,7459,7460,7461,7462,\n7463,7464,7465,7466,7467,7468,7469,7470,7471,7472,7473,7474,7475,7476,7477,\n7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491,7492,\n7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,7503,7504,7505,7506,7507,\n7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,7520,7521,7522,\n7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537,\n7538,7539,7540,7541,7542,7543,7544,42877L,7546,7547,7548,11363,7550,7551,\n7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,\n42950L,7567,7568,7569,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,\n7580,7581,7582,7583,7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,\n7595,7596,7597,7598,7599,7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,\n7610,7611,7612,7613,7614,7615,7616,7617,7618,7619,7620,7621,7622,7623,7624,\n7625,7626,7627,7628,7629,7630,7631,7632,7633,7634,7635,7636,7637,7638,7639,\n7640,7641,7642,7643,7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654,\n7655,7656,7657,7658,7659,7660,7661,7662,7663,7664,7665,7666,7667,7668,7669,\n7670,7671,7672,7673,7674,7675,7676,7677,7678,7679,7680,7680,7682,7682,7684,\n7684,7686,7686,7688,7688,7690,7690,7692,7692,7694,7694,7696,7696,7698,7698,\n7700,7700,7702,7702,7704,7704,7706,7706,7708,7708,7710,7710,7712,7712,7714,\n7714,7716,7716,7718,7718,7720,7720,7722,7722,7724,7724,7726,7726,7728,7728,\n7730,7730,7732,7732,7734,7734,7736,7736,7738,7738,7740,7740,7742,7742,7744,\n7744,7746,7746,7748,7748,7750,7750,7752,7752,7754,7754,7756,7756,7758,7758,\n7760,7760,7762,7762,7764,7764,7766,7766,7768,7768,7770,7770,7772,7772,7774,\n7774,7776,7776,7778,7778,7780,7780,7782,7782,7784,7784,7786,7786,7788,7788,\n7790,7790,7792,7792,7794,7794,7796,7796,7798,7798,7800,7800,7802,7802,7804,\n7804,7806,7806,7808,7808,7810,7810,7812,7812,7814,7814,7816,7816,7818,7818,\n7820,7820,7822,7822,7824,7824,7826,7826,7828,7828,7830,7831,7832,7833,7834,\n7776,7836,7837,7838,7839,7840,7840,7842,7842,7844,7844,7846,7846,7848,7848,\n7850,7850,7852,7852,7854,7854,7856,7856,7858,7858,7860,7860,7862,7862,7864,\n7864,7866,7866,7868,7868,7870,7870,7872,7872,7874,7874,7876,7876,7878,7878,\n7880,7880,7882,7882,7884,7884,7886,7886,7888,7888,7890,7890,7892,7892,7894,\n7894,7896,7896,7898,7898,7900,7900,7902,7902,7904,7904,7906,7906,7908,7908,\n7910,7910,7912,7912,7914,7914,7916,7916,7918,7918,7920,7920,7922,7922,7924,\n7924,7926,7926,7928,7928,7930,7930,7932,7932,7934,7934,7944,7945,7946,7947,\n7948,7949,7950,7951,7944,7945,7946,7947,7948,7949,7950,7951,7960,7961,7962,\n7963,7964,7965,7958,7959,7960,7961,7962,7963,7964,7965,7966,7967,7976,7977,\n7978,7979,7980,7981,7982,7983,7976,7977,7978,7979,7980,7981,7982,7983,7992,\n7993,7994,7995,7996,7997,7998,7999,7992,7993,7994,7995,7996,7997,7998,7999,\n8008,8009,8010,8011,8012,8013,8006,8007,8008,8009,8010,8011,8012,8013,8014,\n8015,8016,8025,8018,8027,8020,8029,8022,8031,8024,8025,8026,8027,8028,8029,\n8030,8031,8040,8041,8042,8043,8044,8045,8046,8047,8040,8041,8042,8043,8044,\n8045,8046,8047,8122,8123,8136,8137,8138,8139,8154,8155,8184,8185,8170,8171,\n8186,8187,8062,8063,8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,\n8075,8076,8077,8078,8079,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,\n8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8102,8103,8104,\n8105,8106,8107,8108,8109,8110,8111,8120,8121,8114,8115,8116,8117,8118,8119,\n8120,8121,8122,8123,8124,8125,921,8127,8128,8129,8130,8131,8132,8133,8134,\n8135,8136,8137,8138,8139,8140,8141,8142,8143,8152,8153,8146,8147,8148,8149,\n8150,8151,8152,8153,8154,8155,8156,8157,8158,8159,8168,8169,8162,8163,8164,\n8172,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175,8176,8177,8178,8179,\n8180,8181,8182,8183,8184,8185,8186,8187,8188,8189,8190,8191,8192,8193,8194,\n8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207,8208,8209,\n8210,8211,8212,8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223,8224,\n8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239,\n8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,\n8255,8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,\n8270,8271,8272,8273,8274,8275,8276,8277,8278,8279,8280,8281,8282,8283,8284,\n8285,8286,8287,8288,8289,8290,8291,8292,8293,8294,8295,8296,8297,8298,8299,\n8300,8301,8302,8303,8304,8305,8306,8307,8308,8309,8310,8311,8312,8313,8314,\n8315,8316,8317,8318,8319,8320,8321,8322,8323,8324,8325,8326,8327,8328,8329,\n8330,8331,8332,8333,8334,8335,8336,8337,8338,8339,8340,8341,8342,8343,8344,\n8345,8346,8347,8348,8349,8350,8351,8352,8353,8354,8355,8356,8357,8358,8359,\n8360,8361,8362,8363,8364,8365,8366,8367,8368,8369,8370,8371,8372,8373,8374,\n8375,8376,8377,8378,8379,8380,8381,8382,8383,8384,8385,8386,8387,8388,8389,\n8390,8391,8392,8393,8394,8395,8396,8397,8398,8399,8400,8401,8402,8403,8404,\n8405,8406,8407,8408,8409,8410,8411,8412,8413,8414,8415,8416,8417,8418,8419,\n8420,8421,8422,8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,8433,8434,\n8435,8436,8437,8438,8439,8440,8441,8442,8443,8444,8445,8446,8447,8448,8449,\n8450,8451,8452,8453,8454,8455,8456,8457,8458,8459,8460,8461,8462,8463,8464,\n8465,8466,8467,8468,8469,8470,8471,8472,8473,8474,8475,8476,8477,8478,8479,\n8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490,8491,8492,8493,8494,\n8495,8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8506,8507,8508,8509,\n8510,8511,8512,8513,8514,8515,8516,8517,8518,8519,8520,8521,8522,8523,8524,\n8525,8498,8527,8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538,8539,\n8540,8541,8542,8543,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,\n8555,8556,8557,8558,8559,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,\n8554,8555,8556,8557,8558,8559,8576,8577,8578,8579,8579,8581,8582,8583,8584,\n8585,8586,8587,8588,8589,8590,8591,8592,8593,8594,8595,8596,8597,8598,8599,\n8600,8601,8602,8603,8604,8605,8606,8607,8608,8609,8610,8611,8612,8613,8614,\n8615,8616,8617,8618,8619,8620,8621,8622,8623,8624,8625,8626,8627,8628,8629,\n8630,8631,8632,8633,8634,8635,8636,8637,8638,8639,8640,8641,8642,8643,8644,\n8645,8646,8647,8648,8649,8650,8651,8652,8653,8654,8655,8656,8657,8658,8659,\n8660,8661,8662,8663,8664,8665,8666,8667,8668,8669,8670,8671,8672,8673,8674,\n8675,8676,8677,8678,8679,8680,8681,8682,8683,8684,8685,8686,8687,8688,8689,\n8690,8691,8692,8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703,8704,\n8705,8706,8707,8708,8709,8710,8711,8712,8713,8714,8715,8716,8717,8718,8719,\n8720,8721,8722,8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,8734,\n8735,8736,8737,8738,8739,8740,8741,8742,8743,8744,8745,8746,8747,8748,8749,\n8750,8751,8752,8753,8754,8755,8756,8757,8758,8759,8760,8761,8762,8763,8764,\n8765,8766,8767,8768,8769,8770,8771,8772,8773,8774,8775,8776,8777,8778,8779,\n8780,8781,8782,8783,8784,8785,8786,8787,8788,8789,8790,8791,8792,8793,8794,\n8795,8796,8797,8798,8799,8800,8801,8802,8803,8804,8805,8806,8807,8808,8809,\n8810,8811,8812,8813,8814,8815,8816,8817,8818,8819,8820,8821,8822,8823,8824,\n8825,8826,8827,8828,8829,8830,8831,8832,8833,8834,8835,8836,8837,8838,8839,\n8840,8841,8842,8843,8844,8845,8846,8847,8848,8849,8850,8851,8852,8853,8854,\n8855,8856,8857,8858,8859,8860,8861,8862,8863,8864,8865,8866,8867,8868,8869,\n8870,8871,8872,8873,8874,8875,8876,8877,8878,8879,8880,8881,8882,8883,8884,\n8885,8886,8887,8888,8889,8890,8891,8892,8893,8894,8895,8896,8897,8898,8899,\n8900,8901,8902,8903,8904,8905,8906,8907,8908,8909,8910,8911,8912,8913,8914,\n8915,8916,8917,8918,8919,8920,8921,8922,8923,8924,8925,8926,8927,8928,8929,\n8930,8931,8932,8933,8934,8935,8936,8937,8938,8939,8940,8941,8942,8943,8944,\n8945,8946,8947,8948,8949,8950,8951,8952,8953,8954,8955,8956,8957,8958,8959,\n8960,8961,8962,8963,8964,8965,8966,8967,8968,8969,8970,8971,8972,8973,8974,\n8975,8976,8977,8978,8979,8980,8981,8982,8983,8984,8985,8986,8987,8988,8989,\n8990,8991,8992,8993,8994,8995,8996,8997,8998,8999,9000,9001,9002,9003,9004,\n9005,9006,9007,9008,9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019,\n9020,9021,9022,9023,9024,9025,9026,9027,9028,9029,9030,9031,9032,9033,9034,\n9035,9036,9037,9038,9039,9040,9041,9042,9043,9044,9045,9046,9047,9048,9049,\n9050,9051,9052,9053,9054,9055,9056,9057,9058,9059,9060,9061,9062,9063,9064,\n9065,9066,9067,9068,9069,9070,9071,9072,9073,9074,9075,9076,9077,9078,9079,\n9080,9081,9082,9083,9084,9085,9086,9087,9088,9089,9090,9091,9092,9093,9094,\n9095,9096,9097,9098,9099,9100,9101,9102,9103,9104,9105,9106,9107,9108,9109,\n9110,9111,9112,9113,9114,9115,9116,9117,9118,9119,9120,9121,9122,9123,9124,\n9125,9126,9127,9128,9129,9130,9131,9132,9133,9134,9135,9136,9137,9138,9139,\n9140,9141,9142,9143,9144,9145,9146,9147,9148,9149,9150,9151,9152,9153,9154,\n9155,9156,9157,9158,9159,9160,9161,9162,9163,9164,9165,9166,9167,9168,9169,\n9170,9171,9172,9173,9174,9175,9176,9177,9178,9179,9180,9181,9182,9183,9184,\n9185,9186,9187,9188,9189,9190,9191,9192,9193,9194,9195,9196,9197,9198,9199,\n9200,9201,9202,9203,9204,9205,9206,9207,9208,9209,9210,9211,9212,9213,9214,\n9215,9216,9217,9218,9219,9220,9221,9222,9223,9224,9225,9226,9227,9228,9229,\n9230,9231,9232,9233,9234,9235,9236,9237,9238,9239,9240,9241,9242,9243,9244,\n9245,9246,9247,9248,9249,9250,9251,9252,9253,9254,9255,9256,9257,9258,9259,\n9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273,9274,\n9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288,9289,\n9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,9303,9304,\n9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,9318,9319,\n9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,9332,9333,9334,\n9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,9346,9347,9348,9349,\n9350,9351,9352,9353,9354,9355,9356,9357,9358,9359,9360,9361,9362,9363,9364,\n9365,9366,9367,9368,9369,9370,9371,9372,9373,9374,9375,9376,9377,9378,9379,\n9380,9381,9382,9383,9384,9385,9386,9387,9388,9389,9390,9391,9392,9393,9394,\n9395,9396,9397,9398,9399,9400,9401,9402,9403,9404,9405,9406,9407,9408,9409,\n9410,9411,9412,9413,9414,9415,9416,9417,9418,9419,9420,9421,9422,9423,9398,\n9399,9400,9401,9402,9403,9404,9405,9406,9407,9408,9409,9410,9411,9412,9413,\n9414,9415,9416,9417,9418,9419,9420,9421,9422,9423,9450,9451,9452,9453,9454,\n9455,9456,9457,9458,9459,9460,9461,9462,9463,9464,9465,9466,9467,9468,9469,\n9470,9471,9472,9473,9474,9475,9476,9477,9478,9479,9480,9481,9482,9483,9484,\n9485,9486,9487,9488,9489,9490,9491,9492,9493,9494,9495,9496,9497,9498,9499,\n9500,9501,9502,9503,9504,9505,9506,9507,9508,9509,9510,9511,9512,9513,9514,\n9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525,9526,9527,9528,9529,\n9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541,9542,9543,9544,\n9545,9546,9547,9548,9549,9550,9551,9552,9553,9554,9555,9556,9557,9558,9559,\n9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,\n9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9588,9589,\n9590,9591,9592,9593,9594,9595,9596,9597,9598,9599,9600,9601,9602,9603,9604,\n9605,9606,9607,9608,9609,9610,9611,9612,9613,9614,9615,9616,9617,9618,9619,\n9620,9621,9622,9623,9624,9625,9626,9627,9628,9629,9630,9631,9632,9633,9634,\n9635,9636,9637,9638,9639,9640,9641,9642,9643,9644,9645,9646,9647,9648,9649,\n9650,9651,9652,9653,9654,9655,9656,9657,9658,9659,9660,9661,9662,9663,9664,\n9665,9666,9667,9668,9669,9670,9671,9672,9673,9674,9675,9676,9677,9678,9679,\n9680,9681,9682,9683,9684,9685,9686,9687,9688,9689,9690,9691,9692,9693,9694,\n9695,9696,9697,9698,9699,9700,9701,9702,9703,9704,9705,9706,9707,9708,9709,\n9710,9711,9712,9713,9714,9715,9716,9717,9718,9719,9720,9721,9722,9723,9724,\n9725,9726,9727,9728,9729,9730,9731,9732,9733,9734,9735,9736,9737,9738,9739,\n9740,9741,9742,9743,9744,9745,9746,9747,9748,9749,9750,9751,9752,9753,9754,\n9755,9756,9757,9758,9759,9760,9761,9762,9763,9764,9765,9766,9767,9768,9769,\n9770,9771,9772,9773,9774,9775,9776,9777,9778,9779,9780,9781,9782,9783,9784,\n9785,9786,9787,9788,9789,9790,9791,9792,9793,9794,9795,9796,9797,9798,9799,\n9800,9801,9802,9803,9804,9805,9806,9807,9808,9809,9810,9811,9812,9813,9814,\n9815,9816,9817,9818,9819,9820,9821,9822,9823,9824,9825,9826,9827,9828,9829,\n9830,9831,9832,9833,9834,9835,9836,9837,9838,9839,9840,9841,9842,9843,9844,\n9845,9846,9847,9848,9849,9850,9851,9852,9853,9854,9855,9856,9857,9858,9859,\n9860,9861,9862,9863,9864,9865,9866,9867,9868,9869,9870,9871,9872,9873,9874,\n9875,9876,9877,9878,9879,9880,9881,9882,9883,9884,9885,9886,9887,9888,9889,\n9890,9891,9892,9893,9894,9895,9896,9897,9898,9899,9900,9901,9902,9903,9904,\n9905,9906,9907,9908,9909,9910,9911,9912,9913,9914,9915,9916,9917,9918,9919,\n9920,9921,9922,9923,9924,9925,9926,9927,9928,9929,9930,9931,9932,9933,9934,\n9935,9936,9937,9938,9939,9940,9941,9942,9943,9944,9945,9946,9947,9948,9949,\n9950,9951,9952,9953,9954,9955,9956,9957,9958,9959,9960,9961,9962,9963,9964,\n9965,9966,9967,9968,9969,9970,9971,9972,9973,9974,9975,9976,9977,9978,9979,\n9980,9981,9982,9983,9984,9985,9986,9987,9988,9989,9990,9991,9992,9993,9994,\n9995,9996,9997,9998,9999,10000,10001,10002,10003,10004,10005,10006,10007,\n10008,10009,10010,10011,10012,10013,10014,10015,10016,10017,10018,10019,\n10020,10021,10022,10023,10024,10025,10026,10027,10028,10029,10030,10031,\n10032,10033,10034,10035,10036,10037,10038,10039,10040,10041,10042,10043,\n10044,10045,10046,10047,10048,10049,10050,10051,10052,10053,10054,10055,\n10056,10057,10058,10059,10060,10061,10062,10063,10064,10065,10066,10067,\n10068,10069,10070,10071,10072,10073,10074,10075,10076,10077,10078,10079,\n10080,10081,10082,10083,10084,10085,10086,10087,10088,10089,10090,10091,\n10092,10093,10094,10095,10096,10097,10098,10099,10100,10101,10102,10103,\n10104,10105,10106,10107,10108,10109,10110,10111,10112,10113,10114,10115,\n10116,10117,10118,10119,10120,10121,10122,10123,10124,10125,10126,10127,\n10128,10129,10130,10131,10132,10133,10134,10135,10136,10137,10138,10139,\n10140,10141,10142,10143,10144,10145,10146,10147,10148,10149,10150,10151,\n10152,10153,10154,10155,10156,10157,10158,10159,10160,10161,10162,10163,\n10164,10165,10166,10167,10168,10169,10170,10171,10172,10173,10174,10175,\n10176,10177,10178,10179,10180,10181,10182,10183,10184,10185,10186,10187,\n10188,10189,10190,10191,10192,10193,10194,10195,10196,10197,10198,10199,\n10200,10201,10202,10203,10204,10205,10206,10207,10208,10209,10210,10211,\n10212,10213,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,\n10224,10225,10226,10227,10228,10229,10230,10231,10232,10233,10234,10235,\n10236,10237,10238,10239,10240,10241,10242,10243,10244,10245,10246,10247,\n10248,10249,10250,10251,10252,10253,10254,10255,10256,10257,10258,10259,\n10260,10261,10262,10263,10264,10265,10266,10267,10268,10269,10270,10271,\n10272,10273,10274,10275,10276,10277,10278,10279,10280,10281,10282,10283,\n10284,10285,10286,10287,10288,10289,10290,10291,10292,10293,10294,10295,\n10296,10297,10298,10299,10300,10301,10302,10303,10304,10305,10306,10307,\n10308,10309,10310,10311,10312,10313,10314,10315,10316,10317,10318,10319,\n10320,10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,10331,\n10332,10333,10334,10335,10336,10337,10338,10339,10340,10341,10342,10343,\n10344,10345,10346,10347,10348,10349,10350,10351,10352,10353,10354,10355,\n10356,10357,10358,10359,10360,10361,10362,10363,10364,10365,10366,10367,\n10368,10369,10370,10371,10372,10373,10374,10375,10376,10377,10378,10379,\n10380,10381,10382,10383,10384,10385,10386,10387,10388,10389,10390,10391,\n10392,10393,10394,10395,10396,10397,10398,10399,10400,10401,10402,10403,\n10404,10405,10406,10407,10408,10409,10410,10411,10412,10413,10414,10415,\n10416,10417,10418,10419,10420,10421,10422,10423,10424,10425,10426,10427,\n10428,10429,10430,10431,10432,10433,10434,10435,10436,10437,10438,10439,\n10440,10441,10442,10443,10444,10445,10446,10447,10448,10449,10450,10451,\n10452,10453,10454,10455,10456,10457,10458,10459,10460,10461,10462,10463,\n10464,10465,10466,10467,10468,10469,10470,10471,10472,10473,10474,10475,\n10476,10477,10478,10479,10480,10481,10482,10483,10484,10485,10486,10487,\n10488,10489,10490,10491,10492,10493,10494,10495,10496,10497,10498,10499,\n10500,10501,10502,10503,10504,10505,10506,10507,10508,10509,10510,10511,\n10512,10513,10514,10515,10516,10517,10518,10519,10520,10521,10522,10523,\n10524,10525,10526,10527,10528,10529,10530,10531,10532,10533,10534,10535,\n10536,10537,10538,10539,10540,10541,10542,10543,10544,10545,10546,10547,\n10548,10549,10550,10551,10552,10553,10554,10555,10556,10557,10558,10559,\n10560,10561,10562,10563,10564,10565,10566,10567,10568,10569,10570,10571,\n10572,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,10583,\n10584,10585,10586,10587,10588,10589,10590,10591,10592,10593,10594,10595,\n10596,10597,10598,10599,10600,10601,10602,10603,10604,10605,10606,10607,\n10608,10609,10610,10611,10612,10613,10614,10615,10616,10617,10618,10619,\n10620,10621,10622,10623,10624,10625,10626,10627,10628,10629,10630,10631,\n10632,10633,10634,10635,10636,10637,10638,10639,10640,10641,10642,10643,\n10644,10645,10646,10647,10648,10649,10650,10651,10652,10653,10654,10655,\n10656,10657,10658,10659,10660,10661,10662,10663,10664,10665,10666,10667,\n10668,10669,10670,10671,10672,10673,10674,10675,10676,10677,10678,10679,\n10680,10681,10682,10683,10684,10685,10686,10687,10688,10689,10690,10691,\n10692,10693,10694,10695,10696,10697,10698,10699,10700,10701,10702,10703,\n10704,10705,10706,10707,10708,10709,10710,10711,10712,10713,10714,10715,\n10716,10717,10718,10719,10720,10721,10722,10723,10724,10725,10726,10727,\n10728,10729,10730,10731,10732,10733,10734,10735,10736,10737,10738,10739,\n10740,10741,10742,10743,10744,10745,10746,10747,10748,10749,10750,10751,\n10752,10753,10754,10755,10756,10757,10758,10759,10760,10761,10762,10763,\n10764,10765,10766,10767,10768,10769,10770,10771,10772,10773,10774,10775,\n10776,10777,10778,10779,10780,10781,10782,10783,10784,10785,10786,10787,\n10788,10789,10790,10791,10792,10793,10794,10795,10796,10797,10798,10799,\n10800,10801,10802,10803,10804,10805,10806,10807,10808,10809,10810,10811,\n10812,10813,10814,10815,10816,10817,10818,10819,10820,10821,10822,10823,\n10824,10825,10826,10827,10828,10829,10830,10831,10832,10833,10834,10835,\n10836,10837,10838,10839,10840,10841,10842,10843,10844,10845,10846,10847,\n10848,10849,10850,10851,10852,10853,10854,10855,10856,10857,10858,10859,\n10860,10861,10862,10863,10864,10865,10866,10867,10868,10869,10870,10871,\n10872,10873,10874,10875,10876,10877,10878,10879,10880,10881,10882,10883,\n10884,10885,10886,10887,10888,10889,10890,10891,10892,10893,10894,10895,\n10896,10897,10898,10899,10900,10901,10902,10903,10904,10905,10906,10907,\n10908,10909,10910,10911,10912,10913,10914,10915,10916,10917,10918,10919,\n10920,10921,10922,10923,10924,10925,10926,10927,10928,10929,10930,10931,\n10932,10933,10934,10935,10936,10937,10938,10939,10940,10941,10942,10943,\n10944,10945,10946,10947,10948,10949,10950,10951,10952,10953,10954,10955,\n10956,10957,10958,10959,10960,10961,10962,10963,10964,10965,10966,10967,\n10968,10969,10970,10971,10972,10973,10974,10975,10976,10977,10978,10979,\n10980,10981,10982,10983,10984,10985,10986,10987,10988,10989,10990,10991,\n10992,10993,10994,10995,10996,10997,10998,10999,11000,11001,11002,11003,\n11004,11005,11006,11007,11008,11009,11010,11011,11012,11013,11014,11015,\n11016,11017,11018,11019,11020,11021,11022,11023,11024,11025,11026,11027,\n11028,11029,11030,11031,11032,11033,11034,11035,11036,11037,11038,11039,\n11040,11041,11042,11043,11044,11045,11046,11047,11048,11049,11050,11051,\n11052,11053,11054,11055,11056,11057,11058,11059,11060,11061,11062,11063,\n11064,11065,11066,11067,11068,11069,11070,11071,11072,11073,11074,11075,\n11076,11077,11078,11079,11080,11081,11082,11083,11084,11085,11086,11087,\n11088,11089,11090,11091,11092,11093,11094,11095,11096,11097,11098,11099,\n11100,11101,11102,11103,11104,11105,11106,11107,11108,11109,11110,11111,\n11112,11113,11114,11115,11116,11117,11118,11119,11120,11121,11122,11123,\n11124,11125,11126,11127,11128,11129,11130,11131,11132,11133,11134,11135,\n11136,11137,11138,11139,11140,11141,11142,11143,11144,11145,11146,11147,\n11148,11149,11150,11151,11152,11153,11154,11155,11156,11157,11158,11159,\n11160,11161,11162,11163,11164,11165,11166,11167,11168,11169,11170,11171,\n11172,11173,11174,11175,11176,11177,11178,11179,11180,11181,11182,11183,\n11184,11185,11186,11187,11188,11189,11190,11191,11192,11193,11194,11195,\n11196,11197,11198,11199,11200,11201,11202,11203,11204,11205,11206,11207,\n11208,11209,11210,11211,11212,11213,11214,11215,11216,11217,11218,11219,\n11220,11221,11222,11223,11224,11225,11226,11227,11228,11229,11230,11231,\n11232,11233,11234,11235,11236,11237,11238,11239,11240,11241,11242,11243,\n11244,11245,11246,11247,11248,11249,11250,11251,11252,11253,11254,11255,\n11256,11257,11258,11259,11260,11261,11262,11263,11264,11265,11266,11267,\n11268,11269,11270,11271,11272,11273,11274,11275,11276,11277,11278,11279,\n11280,11281,11282,11283,11284,11285,11286,11287,11288,11289,11290,11291,\n11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,\n11304,11305,11306,11307,11308,11309,11310,11311,11264,11265,11266,11267,\n11268,11269,11270,11271,11272,11273,11274,11275,11276,11277,11278,11279,\n11280,11281,11282,11283,11284,11285,11286,11287,11288,11289,11290,11291,\n11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,\n11304,11305,11306,11307,11308,11309,11310,11359,11360,11360,11362,11363,\n11364,570,574,11367,11367,11369,11369,11371,11371,11373,11374,11375,11376,\n11377,11378,11378,11380,11381,11381,11383,11384,11385,11386,11387,11388,\n11389,11390,11391,11392,11392,11394,11394,11396,11396,11398,11398,11400,\n11400,11402,11402,11404,11404,11406,11406,11408,11408,11410,11410,11412,\n11412,11414,11414,11416,11416,11418,11418,11420,11420,11422,11422,11424,\n11424,11426,11426,11428,11428,11430,11430,11432,11432,11434,11434,11436,\n11436,11438,11438,11440,11440,11442,11442,11444,11444,11446,11446,11448,\n11448,11450,11450,11452,11452,11454,11454,11456,11456,11458,11458,11460,\n11460,11462,11462,11464,11464,11466,11466,11468,11468,11470,11470,11472,\n11472,11474,11474,11476,11476,11478,11478,11480,11480,11482,11482,11484,\n11484,11486,11486,11488,11488,11490,11490,11492,11493,11494,11495,11496,\n11497,11498,11499,11499,11501,11501,11503,11504,11505,11506,11506,11508,\n11509,11510,11511,11512,11513,11514,11515,11516,11517,11518,11519,4256,\n4257,4258,4259,4260,4261,4262,4263,4264,4265,4266,4267,4268,4269,4270,4271,\n4272,4273,4274,4275,4276,4277,4278,4279,4280,4281,4282,4283,4284,4285,4286,\n4287,4288,4289,4290,4291,4292,4293,11558,4295,11560,11561,11562,11563,\n11564,4301,11566,11567,11568,11569,11570,11571,11572,11573,11574,11575,\n11576,11577,11578,11579,11580,11581,11582,11583,11584,11585,11586,11587,\n11588,11589,11590,11591,11592,11593,11594,11595,11596,11597,11598,11599,\n11600,11601,11602,11603,11604,11605,11606,11607,11608,11609,11610,11611,\n11612,11613,11614,11615,11616,11617,11618,11619,11620,11621,11622,11623,\n11624,11625,11626,11627,11628,11629,11630,11631,11632,11633,11634,11635,\n11636,11637,11638,11639,11640,11641,11642,11643,11644,11645,11646,11647,\n11648,11649,11650,11651,11652,11653,11654,11655,11656,11657,11658,11659,\n11660,11661,11662,11663,11664,11665,11666,11667,11668,11669,11670,11671,\n11672,11673,11674,11675,11676,11677,11678,11679,11680,11681,11682,11683,\n11684,11685,11686,11687,11688,11689,11690,11691,11692,11693,11694,11695,\n11696,11697,11698,11699,11700,11701,11702,11703,11704,11705,11706,11707,\n11708,11709,11710,11711,11712,11713,11714,11715,11716,11717,11718,11719,\n11720,11721,11722,11723,11724,11725,11726,11727,11728,11729,11730,11731,\n11732,11733,11734,11735,11736,11737,11738,11739,11740,11741,11742,11743,\n11744,11745,11746,11747,11748,11749,11750,11751,11752,11753,11754,11755,\n11756,11757,11758,11759,11760,11761,11762,11763,11764,11765,11766,11767,\n11768,11769,11770,11771,11772,11773,11774,11775,11776,11777,11778,11779,\n11780,11781,11782,11783,11784,11785,11786,11787,11788,11789,11790,11791,\n11792,11793,11794,11795,11796,11797,11798,11799,11800,11801,11802,11803,\n11804,11805,11806,11807,11808,11809,11810,11811,11812,11813,11814,11815,\n11816,11817,11818,11819,11820,11821,11822,11823,11824,11825,11826,11827,\n11828,11829,11830,11831,11832,11833,11834,11835,11836,11837,11838,11839,\n11840,11841,11842,11843,11844,11845,11846,11847,11848,11849,11850,11851,\n11852,11853,11854,11855,11856,11857,11858,11859,11860,11861,11862,11863,\n11864,11865,11866,11867,11868,11869,11870,11871,11872,11873,11874,11875,\n11876,11877,11878,11879,11880,11881,11882,11883,11884,11885,11886,11887,\n11888,11889,11890,11891,11892,11893,11894,11895,11896,11897,11898,11899,\n11900,11901,11902,11903,11904,11905,11906,11907,11908,11909,11910,11911,\n11912,11913,11914,11915,11916,11917,11918,11919,11920,11921,11922,11923,\n11924,11925,11926,11927,11928,11929,11930,11931,11932,11933,11934,11935,\n11936,11937,11938,11939,11940,11941,11942,11943,11944,11945,11946,11947,\n11948,11949,11950,11951,11952,11953,11954,11955,11956,11957,11958,11959,\n11960,11961,11962,11963,11964,11965,11966,11967,11968,11969,11970,11971,\n11972,11973,11974,11975,11976,11977,11978,11979,11980,11981,11982,11983,\n11984,11985,11986,11987,11988,11989,11990,11991,11992,11993,11994,11995,\n11996,11997,11998,11999,12000,12001,12002,12003,12004,12005,12006,12007,\n12008,12009,12010,12011,12012,12013,12014,12015,12016,12017,12018,12019,\n12020,12021,12022,12023,12024,12025,12026,12027,12028,12029,12030,12031,\n12032,12033,12034,12035,12036,12037,12038,12039,12040,12041,12042,12043,\n12044,12045,12046,12047,12048,12049,12050,12051,12052,12053,12054,12055,\n12056,12057,12058,12059,12060,12061,12062,12063,12064,12065,12066,12067,\n12068,12069,12070,12071,12072,12073,12074,12075,12076,12077,12078,12079,\n12080,12081,12082,12083,12084,12085,12086,12087,12088,12089,12090,12091,\n12092,12093,12094,12095,12096,12097,12098,12099,12100,12101,12102,12103,\n12104,12105,12106,12107,12108,12109,12110,12111,12112,12113,12114,12115,\n12116,12117,12118,12119,12120,12121,12122,12123,12124,12125,12126,12127,\n12128,12129,12130,12131,12132,12133,12134,12135,12136,12137,12138,12139,\n12140,12141,12142,12143,12144,12145,12146,12147,12148,12149,12150,12151,\n12152,12153,12154,12155,12156,12157,12158,12159,12160,12161,12162,12163,\n12164,12165,12166,12167,12168,12169,12170,12171,12172,12173,12174,12175,\n12176,12177,12178,12179,12180,12181,12182,12183,12184,12185,12186,12187,\n12188,12189,12190,12191,12192,12193,12194,12195,12196,12197,12198,12199,\n12200,12201,12202,12203,12204,12205,12206,12207,12208,12209,12210,12211,\n12212,12213,12214,12215,12216,12217,12218,12219,12220,12221,12222,12223,\n12224,12225,12226,12227,12228,12229,12230,12231,12232,12233,12234,12235,\n12236,12237,12238,12239,12240,12241,12242,12243,12244,12245,12246,12247,\n12248,12249,12250,12251,12252,12253,12254,12255,12256,12257,12258,12259,\n12260,12261,12262,12263,12264,12265,12266,12267,12268,12269,12270,12271,\n12272,12273,12274,12275,12276,12277,12278,12279,12280,12281,12282,12283,\n12284,12285,12286,12287,12288,12289,12290,12291,12292,12293,12294,12295,\n12296,12297,12298,12299,12300,12301,12302,12303,12304,12305,12306,12307,\n12308,12309,12310,12311,12312,12313,12314,12315,12316,12317,12318,12319,\n12320,12321,12322,12323,12324,12325,12326,12327,12328,12329,12330,12331,\n12332,12333,12334,12335,12336,12337,12338,12339,12340,12341,12342,12343,\n12344,12345,12346,12347,12348,12349,12350,12351,12352,12353,12354,12355,\n12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,\n12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,\n12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,\n12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,\n12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,\n12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,\n12428,12429,12430,12431,12432,12433,12434,12435,12436,12437,12438,12439,\n12440,12441,12442,12443,12444,12445,12446,12447,12448,12449,12450,12451,\n12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,12463,\n12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,\n12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,\n12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,\n12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,\n12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,\n12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,12535,\n12536,12537,12538,12539,12540,12541,12542,12543,12544,12545,12546,12547,\n12548,12549,12550,12551,12552,12553,12554,12555,12556,12557,12558,12559,\n12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570,12571,\n12572,12573,12574,12575,12576,12577,12578,12579,12580,12581,12582,12583,\n12584,12585,12586,12587,12588,12589,12590,12591,12592,12593,12594,12595,\n12596,12597,12598,12599,12600,12601,12602,12603,12604,12605,12606,12607,\n12608,12609,12610,12611,12612,12613,12614,12615,12616,12617,12618,12619,\n12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,12631,\n12632,12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643,\n12644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654,12655,\n12656,12657,12658,12659,12660,12661,12662,12663,12664,12665,12666,12667,\n12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679,\n12680,12681,12682,12683,12684,12685,12686,12687,12688,12689,12690,12691,\n12692,12693,12694,12695,12696,12697,12698,12699,12700,12701,12702,12703,\n12704,12705,12706,12707,12708,12709,12710,12711,12712,12713,12714,12715,\n12716,12717,12718,12719,12720,12721,12722,12723,12724,12725,12726,12727,\n12728,12729,12730,12731,12732,12733,12734,12735,12736,12737,12738,12739,\n12740,12741,12742,12743,12744,12745,12746,12747,12748,12749,12750,12751,\n12752,12753,12754,12755,12756,12757,12758,12759,12760,12761,12762,12763,\n12764,12765,12766,12767,12768,12769,12770,12771,12772,12773,12774,12775,\n12776,12777,12778,12779,12780,12781,12782,12783,12784,12785,12786,12787,\n12788,12789,12790,12791,12792,12793,12794,12795,12796,12797,12798,12799,\n12800,12801,12802,12803,12804,12805,12806,12807,12808,12809,12810,12811,\n12812,12813,12814,12815,12816,12817,12818,12819,12820,12821,12822,12823,\n12824,12825,12826,12827,12828,12829,12830,12831,12832,12833,12834,12835,\n12836,12837,12838,12839,12840,12841,12842,12843,12844,12845,12846,12847,\n12848,12849,12850,12851,12852,12853,12854,12855,12856,12857,12858,12859,\n12860,12861,12862,12863,12864,12865,12866,12867,12868,12869,12870,12871,\n12872,12873,12874,12875,12876,12877,12878,12879,12880,12881,12882,12883,\n12884,12885,12886,12887,12888,12889,12890,12891,12892,12893,12894,12895,\n12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906,12907,\n12908,12909,12910,12911,12912,12913,12914,12915,12916,12917,12918,12919,\n12920,12921,12922,12923,12924,12925,12926,12927,12928,12929,12930,12931,\n12932,12933,12934,12935,12936,12937,12938,12939,12940,12941,12942,12943,\n12944,12945,12946,12947,12948,12949,12950,12951,12952,12953,12954,12955,\n12956,12957,12958,12959,12960,12961,12962,12963,12964,12965,12966,12967,\n12968,12969,12970,12971,12972,12973,12974,12975,12976,12977,12978,12979,\n12980,12981,12982,12983,12984,12985,12986,12987,12988,12989,12990,12991,\n12992,12993,12994,12995,12996,12997,12998,12999,13000,13001,13002,13003,\n13004,13005,13006,13007,13008,13009,13010,13011,13012,13013,13014,13015,\n13016,13017,13018,13019,13020,13021,13022,13023,13024,13025,13026,13027,\n13028,13029,13030,13031,13032,13033,13034,13035,13036,13037,13038,13039,\n13040,13041,13042,13043,13044,13045,13046,13047,13048,13049,13050,13051,\n13052,13053,13054,13055,13056,13057,13058,13059,13060,13061,13062,13063,\n13064,13065,13066,13067,13068,13069,13070,13071,13072,13073,13074,13075,\n13076,13077,13078,13079,13080,13081,13082,13083,13084,13085,13086,13087,\n13088,13089,13090,13091,13092,13093,13094,13095,13096,13097,13098,13099,\n13100,13101,13102,13103,13104,13105,13106,13107,13108,13109,13110,13111,\n13112,13113,13114,13115,13116,13117,13118,13119,13120,13121,13122,13123,\n13124,13125,13126,13127,13128,13129,13130,13131,13132,13133,13134,13135,\n13136,13137,13138,13139,13140,13141,13142,13143,13144,13145,13146,13147,\n13148,13149,13150,13151,13152,13153,13154,13155,13156,13157,13158,13159,\n13160,13161,13162,13163,13164,13165,13166,13167,13168,13169,13170,13171,\n13172,13173,13174,13175,13176,13177,13178,13179,13180,13181,13182,13183,\n13184,13185,13186,13187,13188,13189,13190,13191,13192,13193,13194,13195,\n13196,13197,13198,13199,13200,13201,13202,13203,13204,13205,13206,13207,\n13208,13209,13210,13211,13212,13213,13214,13215,13216,13217,13218,13219,\n13220,13221,13222,13223,13224,13225,13226,13227,13228,13229,13230,13231,\n13232,13233,13234,13235,13236,13237,13238,13239,13240,13241,13242,13243,\n13244,13245,13246,13247,13248,13249,13250,13251,13252,13253,13254,13255,\n13256,13257,13258,13259,13260,13261,13262,13263,13264,13265,13266,13267,\n13268,13269,13270,13271,13272,13273,13274,13275,13276,13277,13278,13279,\n13280,13281,13282,13283,13284,13285,13286,13287,13288,13289,13290,13291,\n13292,13293,13294,13295,13296,13297,13298,13299,13300,13301,13302,13303,\n13304,13305,13306,13307,13308,13309,13310,13311,13312,13313,13314,13315,\n13316,13317,13318,13319,13320,13321,13322,13323,13324,13325,13326,13327,\n13328,13329,13330,13331,13332,13333,13334,13335,13336,13337,13338,13339,\n13340,13341,13342,13343,13344,13345,13346,13347,13348,13349,13350,13351,\n13352,13353,13354,13355,13356,13357,13358,13359,13360,13361,13362,13363,\n13364,13365,13366,13367,13368,13369,13370,13371,13372,13373,13374,13375,\n13376,13377,13378,13379,13380,13381,13382,13383,13384,13385,13386,13387,\n13388,13389,13390,13391,13392,13393,13394,13395,13396,13397,13398,13399,\n13400,13401,13402,13403,13404,13405,13406,13407,13408,13409,13410,13411,\n13412,13413,13414,13415,13416,13417,13418,13419,13420,13421,13422,13423,\n13424,13425,13426,13427,13428,13429,13430,13431,13432,13433,13434,13435,\n13436,13437,13438,13439,13440,13441,13442,13443,13444,13445,13446,13447,\n13448,13449,13450,13451,13452,13453,13454,13455,13456,13457,13458,13459,\n13460,13461,13462,13463,13464,13465,13466,13467,13468,13469,13470,13471,\n13472,13473,13474,13475,13476,13477,13478,13479,13480,13481,13482,13483,\n13484,13485,13486,13487,13488,13489,13490,13491,13492,13493,13494,13495,\n13496,13497,13498,13499,13500,13501,13502,13503,13504,13505,13506,13507,\n13508,13509,13510,13511,13512,13513,13514,13515,13516,13517,13518,13519,\n13520,13521,13522,13523,13524,13525,13526,13527,13528,13529,13530,13531,\n13532,13533,13534,13535,13536,13537,13538,13539,13540,13541,13542,13543,\n13544,13545,13546,13547,13548,13549,13550,13551,13552,13553,13554,13555,\n13556,13557,13558,13559,13560,13561,13562,13563,13564,13565,13566,13567,\n13568,13569,13570,13571,13572,13573,13574,13575,13576,13577,13578,13579,\n13580,13581,13582,13583,13584,13585,13586,13587,13588,13589,13590,13591,\n13592,13593,13594,13595,13596,13597,13598,13599,13600,13601,13602,13603,\n13604,13605,13606,13607,13608,13609,13610,13611,13612,13613,13614,13615,\n13616,13617,13618,13619,13620,13621,13622,13623,13624,13625,13626,13627,\n13628,13629,13630,13631,13632,13633,13634,13635,13636,13637,13638,13639,\n13640,13641,13642,13643,13644,13645,13646,13647,13648,13649,13650,13651,\n13652,13653,13654,13655,13656,13657,13658,13659,13660,13661,13662,13663,\n13664,13665,13666,13667,13668,13669,13670,13671,13672,13673,13674,13675,\n13676,13677,13678,13679,13680,13681,13682,13683,13684,13685,13686,13687,\n13688,13689,13690,13691,13692,13693,13694,13695,13696,13697,13698,13699,\n13700,13701,13702,13703,13704,13705,13706,13707,13708,13709,13710,13711,\n13712,13713,13714,13715,13716,13717,13718,13719,13720,13721,13722,13723,\n13724,13725,13726,13727,13728,13729,13730,13731,13732,13733,13734,13735,\n13736,13737,13738,13739,13740,13741,13742,13743,13744,13745,13746,13747,\n13748,13749,13750,13751,13752,13753,13754,13755,13756,13757,13758,13759,\n13760,13761,13762,13763,13764,13765,13766,13767,13768,13769,13770,13771,\n13772,13773,13774,13775,13776,13777,13778,13779,13780,13781,13782,13783,\n13784,13785,13786,13787,13788,13789,13790,13791,13792,13793,13794,13795,\n13796,13797,13798,13799,13800,13801,13802,13803,13804,13805,13806,13807,\n13808,13809,13810,13811,13812,13813,13814,13815,13816,13817,13818,13819,\n13820,13821,13822,13823,13824,13825,13826,13827,13828,13829,13830,13831,\n13832,13833,13834,13835,13836,13837,13838,13839,13840,13841,13842,13843,\n13844,13845,13846,13847,13848,13849,13850,13851,13852,13853,13854,13855,\n13856,13857,13858,13859,13860,13861,13862,13863,13864,13865,13866,13867,\n13868,13869,13870,13871,13872,13873,13874,13875,13876,13877,13878,13879,\n13880,13881,13882,13883,13884,13885,13886,13887,13888,13889,13890,13891,\n13892,13893,13894,13895,13896,13897,13898,13899,13900,13901,13902,13903,\n13904,13905,13906,13907,13908,13909,13910,13911,13912,13913,13914,13915,\n13916,13917,13918,13919,13920,13921,13922,13923,13924,13925,13926,13927,\n13928,13929,13930,13931,13932,13933,13934,13935,13936,13937,13938,13939,\n13940,13941,13942,13943,13944,13945,13946,13947,13948,13949,13950,13951,\n13952,13953,13954,13955,13956,13957,13958,13959,13960,13961,13962,13963,\n13964,13965,13966,13967,13968,13969,13970,13971,13972,13973,13974,13975,\n13976,13977,13978,13979,13980,13981,13982,13983,13984,13985,13986,13987,\n13988,13989,13990,13991,13992,13993,13994,13995,13996,13997,13998,13999,\n14000,14001,14002,14003,14004,14005,14006,14007,14008,14009,14010,14011,\n14012,14013,14014,14015,14016,14017,14018,14019,14020,14021,14022,14023,\n14024,14025,14026,14027,14028,14029,14030,14031,14032,14033,14034,14035,\n14036,14037,14038,14039,14040,14041,14042,14043,14044,14045,14046,14047,\n14048,14049,14050,14051,14052,14053,14054,14055,14056,14057,14058,14059,\n14060,14061,14062,14063,14064,14065,14066,14067,14068,14069,14070,14071,\n14072,14073,14074,14075,14076,14077,14078,14079,14080,14081,14082,14083,\n14084,14085,14086,14087,14088,14089,14090,14091,14092,14093,14094,14095,\n14096,14097,14098,14099,14100,14101,14102,14103,14104,14105,14106,14107,\n14108,14109,14110,14111,14112,14113,14114,14115,14116,14117,14118,14119,\n14120,14121,14122,14123,14124,14125,14126,14127,14128,14129,14130,14131,\n14132,14133,14134,14135,14136,14137,14138,14139,14140,14141,14142,14143,\n14144,14145,14146,14147,14148,14149,14150,14151,14152,14153,14154,14155,\n14156,14157,14158,14159,14160,14161,14162,14163,14164,14165,14166,14167,\n14168,14169,14170,14171,14172,14173,14174,14175,14176,14177,14178,14179,\n14180,14181,14182,14183,14184,14185,14186,14187,14188,14189,14190,14191,\n14192,14193,14194,14195,14196,14197,14198,14199,14200,14201,14202,14203,\n14204,14205,14206,14207,14208,14209,14210,14211,14212,14213,14214,14215,\n14216,14217,14218,14219,14220,14221,14222,14223,14224,14225,14226,14227,\n14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14238,14239,\n14240,14241,14242,14243,14244,14245,14246,14247,14248,14249,14250,14251,\n14252,14253,14254,14255,14256,14257,14258,14259,14260,14261,14262,14263,\n14264,14265,14266,14267,14268,14269,14270,14271,14272,14273,14274,14275,\n14276,14277,14278,14279,14280,14281,14282,14283,14284,14285,14286,14287,\n14288,14289,14290,14291,14292,14293,14294,14295,14296,14297,14298,14299,\n14300,14301,14302,14303,14304,14305,14306,14307,14308,14309,14310,14311,\n14312,14313,14314,14315,14316,14317,14318,14319,14320,14321,14322,14323,\n14324,14325,14326,14327,14328,14329,14330,14331,14332,14333,14334,14335,\n14336,14337,14338,14339,14340,14341,14342,14343,14344,14345,14346,14347,\n14348,14349,14350,14351,14352,14353,14354,14355,14356,14357,14358,14359,\n14360,14361,14362,14363,14364,14365,14366,14367,14368,14369,14370,14371,\n14372,14373,14374,14375,14376,14377,14378,14379,14380,14381,14382,14383,\n14384,14385,14386,14387,14388,14389,14390,14391,14392,14393,14394,14395,\n14396,14397,14398,14399,14400,14401,14402,14403,14404,14405,14406,14407,\n14408,14409,14410,14411,14412,14413,14414,14415,14416,14417,14418,14419,\n14420,14421,14422,14423,14424,14425,14426,14427,14428,14429,14430,14431,\n14432,14433,14434,14435,14436,14437,14438,14439,14440,14441,14442,14443,\n14444,14445,14446,14447,14448,14449,14450,14451,14452,14453,14454,14455,\n14456,14457,14458,14459,14460,14461,14462,14463,14464,14465,14466,14467,\n14468,14469,14470,14471,14472,14473,14474,14475,14476,14477,14478,14479,\n14480,14481,14482,14483,14484,14485,14486,14487,14488,14489,14490,14491,\n14492,14493,14494,14495,14496,14497,14498,14499,14500,14501,14502,14503,\n14504,14505,14506,14507,14508,14509,14510,14511,14512,14513,14514,14515,\n14516,14517,14518,14519,14520,14521,14522,14523,14524,14525,14526,14527,\n14528,14529,14530,14531,14532,14533,14534,14535,14536,14537,14538,14539,\n14540,14541,14542,14543,14544,14545,14546,14547,14548,14549,14550,14551,\n14552,14553,14554,14555,14556,14557,14558,14559,14560,14561,14562,14563,\n14564,14565,14566,14567,14568,14569,14570,14571,14572,14573,14574,14575,\n14576,14577,14578,14579,14580,14581,14582,14583,14584,14585,14586,14587,\n14588,14589,14590,14591,14592,14593,14594,14595,14596,14597,14598,14599,\n14600,14601,14602,14603,14604,14605,14606,14607,14608,14609,14610,14611,\n14612,14613,14614,14615,14616,14617,14618,14619,14620,14621,14622,14623,\n14624,14625,14626,14627,14628,14629,14630,14631,14632,14633,14634,14635,\n14636,14637,14638,14639,14640,14641,14642,14643,14644,14645,14646,14647,\n14648,14649,14650,14651,14652,14653,14654,14655,14656,14657,14658,14659,\n14660,14661,14662,14663,14664,14665,14666,14667,14668,14669,14670,14671,\n14672,14673,14674,14675,14676,14677,14678,14679,14680,14681,14682,14683,\n14684,14685,14686,14687,14688,14689,14690,14691,14692,14693,14694,14695,\n14696,14697,14698,14699,14700,14701,14702,14703,14704,14705,14706,14707,\n14708,14709,14710,14711,14712,14713,14714,14715,14716,14717,14718,14719,\n14720,14721,14722,14723,14724,14725,14726,14727,14728,14729,14730,14731,\n14732,14733,14734,14735,14736,14737,14738,14739,14740,14741,14742,14743,\n14744,14745,14746,14747,14748,14749,14750,14751,14752,14753,14754,14755,\n14756,14757,14758,14759,14760,14761,14762,14763,14764,14765,14766,14767,\n14768,14769,14770,14771,14772,14773,14774,14775,14776,14777,14778,14779,\n14780,14781,14782,14783,14784,14785,14786,14787,14788,14789,14790,14791,\n14792,14793,14794,14795,14796,14797,14798,14799,14800,14801,14802,14803,\n14804,14805,14806,14807,14808,14809,14810,14811,14812,14813,14814,14815,\n14816,14817,14818,14819,14820,14821,14822,14823,14824,14825,14826,14827,\n14828,14829,14830,14831,14832,14833,14834,14835,14836,14837,14838,14839,\n14840,14841,14842,14843,14844,14845,14846,14847,14848,14849,14850,14851,\n14852,14853,14854,14855,14856,14857,14858,14859,14860,14861,14862,14863,\n14864,14865,14866,14867,14868,14869,14870,14871,14872,14873,14874,14875,\n14876,14877,14878,14879,14880,14881,14882,14883,14884,14885,14886,14887,\n14888,14889,14890,14891,14892,14893,14894,14895,14896,14897,14898,14899,\n14900,14901,14902,14903,14904,14905,14906,14907,14908,14909,14910,14911,\n14912,14913,14914,14915,14916,14917,14918,14919,14920,14921,14922,14923,\n14924,14925,14926,14927,14928,14929,14930,14931,14932,14933,14934,14935,\n14936,14937,14938,14939,14940,14941,14942,14943,14944,14945,14946,14947,\n14948,14949,14950,14951,14952,14953,14954,14955,14956,14957,14958,14959,\n14960,14961,14962,14963,14964,14965,14966,14967,14968,14969,14970,14971,\n14972,14973,14974,14975,14976,14977,14978,14979,14980,14981,14982,14983,\n14984,14985,14986,14987,14988,14989,14990,14991,14992,14993,14994,14995,\n14996,14997,14998,14999,15000,15001,15002,15003,15004,15005,15006,15007,\n15008,15009,15010,15011,15012,15013,15014,15015,15016,15017,15018,15019,\n15020,15021,15022,15023,15024,15025,15026,15027,15028,15029,15030,15031,\n15032,15033,15034,15035,15036,15037,15038,15039,15040,15041,15042,15043,\n15044,15045,15046,15047,15048,15049,15050,15051,15052,15053,15054,15055,\n15056,15057,15058,15059,15060,15061,15062,15063,15064,15065,15066,15067,\n15068,15069,15070,15071,15072,15073,15074,15075,15076,15077,15078,15079,\n15080,15081,15082,15083,15084,15085,15086,15087,15088,15089,15090,15091,\n15092,15093,15094,15095,15096,15097,15098,15099,15100,15101,15102,15103,\n15104,15105,15106,15107,15108,15109,15110,15111,15112,15113,15114,15115,\n15116,15117,15118,15119,15120,15121,15122,15123,15124,15125,15126,15127,\n15128,15129,15130,15131,15132,15133,15134,15135,15136,15137,15138,15139,\n15140,15141,15142,15143,15144,15145,15146,15147,15148,15149,15150,15151,\n15152,15153,15154,15155,15156,15157,15158,15159,15160,15161,15162,15163,\n15164,15165,15166,15167,15168,15169,15170,15171,15172,15173,15174,15175,\n15176,15177,15178,15179,15180,15181,15182,15183,15184,15185,15186,15187,\n15188,15189,15190,15191,15192,15193,15194,15195,15196,15197,15198,15199,\n15200,15201,15202,15203,15204,15205,15206,15207,15208,15209,15210,15211,\n15212,15213,15214,15215,15216,15217,15218,15219,15220,15221,15222,15223,\n15224,15225,15226,15227,15228,15229,15230,15231,15232,15233,15234,15235,\n15236,15237,15238,15239,15240,15241,15242,15243,15244,15245,15246,15247,\n15248,15249,15250,15251,15252,15253,15254,15255,15256,15257,15258,15259,\n15260,15261,15262,15263,15264,15265,15266,15267,15268,15269,15270,15271,\n15272,15273,15274,15275,15276,15277,15278,15279,15280,15281,15282,15283,\n15284,15285,15286,15287,15288,15289,15290,15291,15292,15293,15294,15295,\n15296,15297,15298,15299,15300,15301,15302,15303,15304,15305,15306,15307,\n15308,15309,15310,15311,15312,15313,15314,15315,15316,15317,15318,15319,\n15320,15321,15322,15323,15324,15325,15326,15327,15328,15329,15330,15331,\n15332,15333,15334,15335,15336,15337,15338,15339,15340,15341,15342,15343,\n15344,15345,15346,15347,15348,15349,15350,15351,15352,15353,15354,15355,\n15356,15357,15358,15359,15360,15361,15362,15363,15364,15365,15366,15367,\n15368,15369,15370,15371,15372,15373,15374,15375,15376,15377,15378,15379,\n15380,15381,15382,15383,15384,15385,15386,15387,15388,15389,15390,15391,\n15392,15393,15394,15395,15396,15397,15398,15399,15400,15401,15402,15403,\n15404,15405,15406,15407,15408,15409,15410,15411,15412,15413,15414,15415,\n15416,15417,15418,15419,15420,15421,15422,15423,15424,15425,15426,15427,\n15428,15429,15430,15431,15432,15433,15434,15435,15436,15437,15438,15439,\n15440,15441,15442,15443,15444,15445,15446,15447,15448,15449,15450,15451,\n15452,15453,15454,15455,15456,15457,15458,15459,15460,15461,15462,15463,\n15464,15465,15466,15467,15468,15469,15470,15471,15472,15473,15474,15475,\n15476,15477,15478,15479,15480,15481,15482,15483,15484,15485,15486,15487,\n15488,15489,15490,15491,15492,15493,15494,15495,15496,15497,15498,15499,\n15500,15501,15502,15503,15504,15505,15506,15507,15508,15509,15510,15511,\n15512,15513,15514,15515,15516,15517,15518,15519,15520,15521,15522,15523,\n15524,15525,15526,15527,15528,15529,15530,15531,15532,15533,15534,15535,\n15536,15537,15538,15539,15540,15541,15542,15543,15544,15545,15546,15547,\n15548,15549,15550,15551,15552,15553,15554,15555,15556,15557,15558,15559,\n15560,15561,15562,15563,15564,15565,15566,15567,15568,15569,15570,15571,\n15572,15573,15574,15575,15576,15577,15578,15579,15580,15581,15582,15583,\n15584,15585,15586,15587,15588,15589,15590,15591,15592,15593,15594,15595,\n15596,15597,15598,15599,15600,15601,15602,15603,15604,15605,15606,15607,\n15608,15609,15610,15611,15612,15613,15614,15615,15616,15617,15618,15619,\n15620,15621,15622,15623,15624,15625,15626,15627,15628,15629,15630,15631,\n15632,15633,15634,15635,15636,15637,15638,15639,15640,15641,15642,15643,\n15644,15645,15646,15647,15648,15649,15650,15651,15652,15653,15654,15655,\n15656,15657,15658,15659,15660,15661,15662,15663,15664,15665,15666,15667,\n15668,15669,15670,15671,15672,15673,15674,15675,15676,15677,15678,15679,\n15680,15681,15682,15683,15684,15685,15686,15687,15688,15689,15690,15691,\n15692,15693,15694,15695,15696,15697,15698,15699,15700,15701,15702,15703,\n15704,15705,15706,15707,15708,15709,15710,15711,15712,15713,15714,15715,\n15716,15717,15718,15719,15720,15721,15722,15723,15724,15725,15726,15727,\n15728,15729,15730,15731,15732,15733,15734,15735,15736,15737,15738,15739,\n15740,15741,15742,15743,15744,15745,15746,15747,15748,15749,15750,15751,\n15752,15753,15754,15755,15756,15757,15758,15759,15760,15761,15762,15763,\n15764,15765,15766,15767,15768,15769,15770,15771,15772,15773,15774,15775,\n15776,15777,15778,15779,15780,15781,15782,15783,15784,15785,15786,15787,\n15788,15789,15790,15791,15792,15793,15794,15795,15796,15797,15798,15799,\n15800,15801,15802,15803,15804,15805,15806,15807,15808,15809,15810,15811,\n15812,15813,15814,15815,15816,15817,15818,15819,15820,15821,15822,15823,\n15824,15825,15826,15827,15828,15829,15830,15831,15832,15833,15834,15835,\n15836,15837,15838,15839,15840,15841,15842,15843,15844,15845,15846,15847,\n15848,15849,15850,15851,15852,15853,15854,15855,15856,15857,15858,15859,\n15860,15861,15862,15863,15864,15865,15866,15867,15868,15869,15870,15871,\n15872,15873,15874,15875,15876,15877,15878,15879,15880,15881,15882,15883,\n15884,15885,15886,15887,15888,15889,15890,15891,15892,15893,15894,15895,\n15896,15897,15898,15899,15900,15901,15902,15903,15904,15905,15906,15907,\n15908,15909,15910,15911,15912,15913,15914,15915,15916,15917,15918,15919,\n15920,15921,15922,15923,15924,15925,15926,15927,15928,15929,15930,15931,\n15932,15933,15934,15935,15936,15937,15938,15939,15940,15941,15942,15943,\n15944,15945,15946,15947,15948,15949,15950,15951,15952,15953,15954,15955,\n15956,15957,15958,15959,15960,15961,15962,15963,15964,15965,15966,15967,\n15968,15969,15970,15971,15972,15973,15974,15975,15976,15977,15978,15979,\n15980,15981,15982,15983,15984,15985,15986,15987,15988,15989,15990,15991,\n15992,15993,15994,15995,15996,15997,15998,15999,16000,16001,16002,16003,\n16004,16005,16006,16007,16008,16009,16010,16011,16012,16013,16014,16015,\n16016,16017,16018,16019,16020,16021,16022,16023,16024,16025,16026,16027,\n16028,16029,16030,16031,16032,16033,16034,16035,16036,16037,16038,16039,\n16040,16041,16042,16043,16044,16045,16046,16047,16048,16049,16050,16051,\n16052,16053,16054,16055,16056,16057,16058,16059,16060,16061,16062,16063,\n16064,16065,16066,16067,16068,16069,16070,16071,16072,16073,16074,16075,\n16076,16077,16078,16079,16080,16081,16082,16083,16084,16085,16086,16087,\n16088,16089,16090,16091,16092,16093,16094,16095,16096,16097,16098,16099,\n16100,16101,16102,16103,16104,16105,16106,16107,16108,16109,16110,16111,\n16112,16113,16114,16115,16116,16117,16118,16119,16120,16121,16122,16123,\n16124,16125,16126,16127,16128,16129,16130,16131,16132,16133,16134,16135,\n16136,16137,16138,16139,16140,16141,16142,16143,16144,16145,16146,16147,\n16148,16149,16150,16151,16152,16153,16154,16155,16156,16157,16158,16159,\n16160,16161,16162,16163,16164,16165,16166,16167,16168,16169,16170,16171,\n16172,16173,16174,16175,16176,16177,16178,16179,16180,16181,16182,16183,\n16184,16185,16186,16187,16188,16189,16190,16191,16192,16193,16194,16195,\n16196,16197,16198,16199,16200,16201,16202,16203,16204,16205,16206,16207,\n16208,16209,16210,16211,16212,16213,16214,16215,16216,16217,16218,16219,\n16220,16221,16222,16223,16224,16225,16226,16227,16228,16229,16230,16231,\n16232,16233,16234,16235,16236,16237,16238,16239,16240,16241,16242,16243,\n16244,16245,16246,16247,16248,16249,16250,16251,16252,16253,16254,16255,\n16256,16257,16258,16259,16260,16261,16262,16263,16264,16265,16266,16267,\n16268,16269,16270,16271,16272,16273,16274,16275,16276,16277,16278,16279,\n16280,16281,16282,16283,16284,16285,16286,16287,16288,16289,16290,16291,\n16292,16293,16294,16295,16296,16297,16298,16299,16300,16301,16302,16303,\n16304,16305,16306,16307,16308,16309,16310,16311,16312,16313,16314,16315,\n16316,16317,16318,16319,16320,16321,16322,16323,16324,16325,16326,16327,\n16328,16329,16330,16331,16332,16333,16334,16335,16336,16337,16338,16339,\n16340,16341,16342,16343,16344,16345,16346,16347,16348,16349,16350,16351,\n16352,16353,16354,16355,16356,16357,16358,16359,16360,16361,16362,16363,\n16364,16365,16366,16367,16368,16369,16370,16371,16372,16373,16374,16375,\n16376,16377,16378,16379,16380,16381,16382,16383,16384,16385,16386,16387,\n16388,16389,16390,16391,16392,16393,16394,16395,16396,16397,16398,16399,\n16400,16401,16402,16403,16404,16405,16406,16407,16408,16409,16410,16411,\n16412,16413,16414,16415,16416,16417,16418,16419,16420,16421,16422,16423,\n16424,16425,16426,16427,16428,16429,16430,16431,16432,16433,16434,16435,\n16436,16437,16438,16439,16440,16441,16442,16443,16444,16445,16446,16447,\n16448,16449,16450,16451,16452,16453,16454,16455,16456,16457,16458,16459,\n16460,16461,16462,16463,16464,16465,16466,16467,16468,16469,16470,16471,\n16472,16473,16474,16475,16476,16477,16478,16479,16480,16481,16482,16483,\n16484,16485,16486,16487,16488,16489,16490,16491,16492,16493,16494,16495,\n16496,16497,16498,16499,16500,16501,16502,16503,16504,16505,16506,16507,\n16508,16509,16510,16511,16512,16513,16514,16515,16516,16517,16518,16519,\n16520,16521,16522,16523,16524,16525,16526,16527,16528,16529,16530,16531,\n16532,16533,16534,16535,16536,16537,16538,16539,16540,16541,16542,16543,\n16544,16545,16546,16547,16548,16549,16550,16551,16552,16553,16554,16555,\n16556,16557,16558,16559,16560,16561,16562,16563,16564,16565,16566,16567,\n16568,16569,16570,16571,16572,16573,16574,16575,16576,16577,16578,16579,\n16580,16581,16582,16583,16584,16585,16586,16587,16588,16589,16590,16591,\n16592,16593,16594,16595,16596,16597,16598,16599,16600,16601,16602,16603,\n16604,16605,16606,16607,16608,16609,16610,16611,16612,16613,16614,16615,\n16616,16617,16618,16619,16620,16621,16622,16623,16624,16625,16626,16627,\n16628,16629,16630,16631,16632,16633,16634,16635,16636,16637,16638,16639,\n16640,16641,16642,16643,16644,16645,16646,16647,16648,16649,16650,16651,\n16652,16653,16654,16655,16656,16657,16658,16659,16660,16661,16662,16663,\n16664,16665,16666,16667,16668,16669,16670,16671,16672,16673,16674,16675,\n16676,16677,16678,16679,16680,16681,16682,16683,16684,16685,16686,16687,\n16688,16689,16690,16691,16692,16693,16694,16695,16696,16697,16698,16699,\n16700,16701,16702,16703,16704,16705,16706,16707,16708,16709,16710,16711,\n16712,16713,16714,16715,16716,16717,16718,16719,16720,16721,16722,16723,\n16724,16725,16726,16727,16728,16729,16730,16731,16732,16733,16734,16735,\n16736,16737,16738,16739,16740,16741,16742,16743,16744,16745,16746,16747,\n16748,16749,16750,16751,16752,16753,16754,16755,16756,16757,16758,16759,\n16760,16761,16762,16763,16764,16765,16766,16767,16768,16769,16770,16771,\n16772,16773,16774,16775,16776,16777,16778,16779,16780,16781,16782,16783,\n16784,16785,16786,16787,16788,16789,16790,16791,16792,16793,16794,16795,\n16796,16797,16798,16799,16800,16801,16802,16803,16804,16805,16806,16807,\n16808,16809,16810,16811,16812,16813,16814,16815,16816,16817,16818,16819,\n16820,16821,16822,16823,16824,16825,16826,16827,16828,16829,16830,16831,\n16832,16833,16834,16835,16836,16837,16838,16839,16840,16841,16842,16843,\n16844,16845,16846,16847,16848,16849,16850,16851,16852,16853,16854,16855,\n16856,16857,16858,16859,16860,16861,16862,16863,16864,16865,16866,16867,\n16868,16869,16870,16871,16872,16873,16874,16875,16876,16877,16878,16879,\n16880,16881,16882,16883,16884,16885,16886,16887,16888,16889,16890,16891,\n16892,16893,16894,16895,16896,16897,16898,16899,16900,16901,16902,16903,\n16904,16905,16906,16907,16908,16909,16910,16911,16912,16913,16914,16915,\n16916,16917,16918,16919,16920,16921,16922,16923,16924,16925,16926,16927,\n16928,16929,16930,16931,16932,16933,16934,16935,16936,16937,16938,16939,\n16940,16941,16942,16943,16944,16945,16946,16947,16948,16949,16950,16951,\n16952,16953,16954,16955,16956,16957,16958,16959,16960,16961,16962,16963,\n16964,16965,16966,16967,16968,16969,16970,16971,16972,16973,16974,16975,\n16976,16977,16978,16979,16980,16981,16982,16983,16984,16985,16986,16987,\n16988,16989,16990,16991,16992,16993,16994,16995,16996,16997,16998,16999,\n17000,17001,17002,17003,17004,17005,17006,17007,17008,17009,17010,17011,\n17012,17013,17014,17015,17016,17017,17018,17019,17020,17021,17022,17023,\n17024,17025,17026,17027,17028,17029,17030,17031,17032,17033,17034,17035,\n17036,17037,17038,17039,17040,17041,17042,17043,17044,17045,17046,17047,\n17048,17049,17050,17051,17052,17053,17054,17055,17056,17057,17058,17059,\n17060,17061,17062,17063,17064,17065,17066,17067,17068,17069,17070,17071,\n17072,17073,17074,17075,17076,17077,17078,17079,17080,17081,17082,17083,\n17084,17085,17086,17087,17088,17089,17090,17091,17092,17093,17094,17095,\n17096,17097,17098,17099,17100,17101,17102,17103,17104,17105,17106,17107,\n17108,17109,17110,17111,17112,17113,17114,17115,17116,17117,17118,17119,\n17120,17121,17122,17123,17124,17125,17126,17127,17128,17129,17130,17131,\n17132,17133,17134,17135,17136,17137,17138,17139,17140,17141,17142,17143,\n17144,17145,17146,17147,17148,17149,17150,17151,17152,17153,17154,17155,\n17156,17157,17158,17159,17160,17161,17162,17163,17164,17165,17166,17167,\n17168,17169,17170,17171,17172,17173,17174,17175,17176,17177,17178,17179,\n17180,17181,17182,17183,17184,17185,17186,17187,17188,17189,17190,17191,\n17192,17193,17194,17195,17196,17197,17198,17199,17200,17201,17202,17203,\n17204,17205,17206,17207,17208,17209,17210,17211,17212,17213,17214,17215,\n17216,17217,17218,17219,17220,17221,17222,17223,17224,17225,17226,17227,\n17228,17229,17230,17231,17232,17233,17234,17235,17236,17237,17238,17239,\n17240,17241,17242,17243,17244,17245,17246,17247,17248,17249,17250,17251,\n17252,17253,17254,17255,17256,17257,17258,17259,17260,17261,17262,17263,\n17264,17265,17266,17267,17268,17269,17270,17271,17272,17273,17274,17275,\n17276,17277,17278,17279,17280,17281,17282,17283,17284,17285,17286,17287,\n17288,17289,17290,17291,17292,17293,17294,17295,17296,17297,17298,17299,\n17300,17301,17302,17303,17304,17305,17306,17307,17308,17309,17310,17311,\n17312,17313,17314,17315,17316,17317,17318,17319,17320,17321,17322,17323,\n17324,17325,17326,17327,17328,17329,17330,17331,17332,17333,17334,17335,\n17336,17337,17338,17339,17340,17341,17342,17343,17344,17345,17346,17347,\n17348,17349,17350,17351,17352,17353,17354,17355,17356,17357,17358,17359,\n17360,17361,17362,17363,17364,17365,17366,17367,17368,17369,17370,17371,\n17372,17373,17374,17375,17376,17377,17378,17379,17380,17381,17382,17383,\n17384,17385,17386,17387,17388,17389,17390,17391,17392,17393,17394,17395,\n17396,17397,17398,17399,17400,17401,17402,17403,17404,17405,17406,17407,\n17408,17409,17410,17411,17412,17413,17414,17415,17416,17417,17418,17419,\n17420,17421,17422,17423,17424,17425,17426,17427,17428,17429,17430,17431,\n17432,17433,17434,17435,17436,17437,17438,17439,17440,17441,17442,17443,\n17444,17445,17446,17447,17448,17449,17450,17451,17452,17453,17454,17455,\n17456,17457,17458,17459,17460,17461,17462,17463,17464,17465,17466,17467,\n17468,17469,17470,17471,17472,17473,17474,17475,17476,17477,17478,17479,\n17480,17481,17482,17483,17484,17485,17486,17487,17488,17489,17490,17491,\n17492,17493,17494,17495,17496,17497,17498,17499,17500,17501,17502,17503,\n17504,17505,17506,17507,17508,17509,17510,17511,17512,17513,17514,17515,\n17516,17517,17518,17519,17520,17521,17522,17523,17524,17525,17526,17527,\n17528,17529,17530,17531,17532,17533,17534,17535,17536,17537,17538,17539,\n17540,17541,17542,17543,17544,17545,17546,17547,17548,17549,17550,17551,\n17552,17553,17554,17555,17556,17557,17558,17559,17560,17561,17562,17563,\n17564,17565,17566,17567,17568,17569,17570,17571,17572,17573,17574,17575,\n17576,17577,17578,17579,17580,17581,17582,17583,17584,17585,17586,17587,\n17588,17589,17590,17591,17592,17593,17594,17595,17596,17597,17598,17599,\n17600,17601,17602,17603,17604,17605,17606,17607,17608,17609,17610,17611,\n17612,17613,17614,17615,17616,17617,17618,17619,17620,17621,17622,17623,\n17624,17625,17626,17627,17628,17629,17630,17631,17632,17633,17634,17635,\n17636,17637,17638,17639,17640,17641,17642,17643,17644,17645,17646,17647,\n17648,17649,17650,17651,17652,17653,17654,17655,17656,17657,17658,17659,\n17660,17661,17662,17663,17664,17665,17666,17667,17668,17669,17670,17671,\n17672,17673,17674,17675,17676,17677,17678,17679,17680,17681,17682,17683,\n17684,17685,17686,17687,17688,17689,17690,17691,17692,17693,17694,17695,\n17696,17697,17698,17699,17700,17701,17702,17703,17704,17705,17706,17707,\n17708,17709,17710,17711,17712,17713,17714,17715,17716,17717,17718,17719,\n17720,17721,17722,17723,17724,17725,17726,17727,17728,17729,17730,17731,\n17732,17733,17734,17735,17736,17737,17738,17739,17740,17741,17742,17743,\n17744,17745,17746,17747,17748,17749,17750,17751,17752,17753,17754,17755,\n17756,17757,17758,17759,17760,17761,17762,17763,17764,17765,17766,17767,\n17768,17769,17770,17771,17772,17773,17774,17775,17776,17777,17778,17779,\n17780,17781,17782,17783,17784,17785,17786,17787,17788,17789,17790,17791,\n17792,17793,17794,17795,17796,17797,17798,17799,17800,17801,17802,17803,\n17804,17805,17806,17807,17808,17809,17810,17811,17812,17813,17814,17815,\n17816,17817,17818,17819,17820,17821,17822,17823,17824,17825,17826,17827,\n17828,17829,17830,17831,17832,17833,17834,17835,17836,17837,17838,17839,\n17840,17841,17842,17843,17844,17845,17846,17847,17848,17849,17850,17851,\n17852,17853,17854,17855,17856,17857,17858,17859,17860,17861,17862,17863,\n17864,17865,17866,17867,17868,17869,17870,17871,17872,17873,17874,17875,\n17876,17877,17878,17879,17880,17881,17882,17883,17884,17885,17886,17887,\n17888,17889,17890,17891,17892,17893,17894,17895,17896,17897,17898,17899,\n17900,17901,17902,17903,17904,17905,17906,17907,17908,17909,17910,17911,\n17912,17913,17914,17915,17916,17917,17918,17919,17920,17921,17922,17923,\n17924,17925,17926,17927,17928,17929,17930,17931,17932,17933,17934,17935,\n17936,17937,17938,17939,17940,17941,17942,17943,17944,17945,17946,17947,\n17948,17949,17950,17951,17952,17953,17954,17955,17956,17957,17958,17959,\n17960,17961,17962,17963,17964,17965,17966,17967,17968,17969,17970,17971,\n17972,17973,17974,17975,17976,17977,17978,17979,17980,17981,17982,17983,\n17984,17985,17986,17987,17988,17989,17990,17991,17992,17993,17994,17995,\n17996,17997,17998,17999,18000,18001,18002,18003,18004,18005,18006,18007,\n18008,18009,18010,18011,18012,18013,18014,18015,18016,18017,18018,18019,\n18020,18021,18022,18023,18024,18025,18026,18027,18028,18029,18030,18031,\n18032,18033,18034,18035,18036,18037,18038,18039,18040,18041,18042,18043,\n18044,18045,18046,18047,18048,18049,18050,18051,18052,18053,18054,18055,\n18056,18057,18058,18059,18060,18061,18062,18063,18064,18065,18066,18067,\n18068,18069,18070,18071,18072,18073,18074,18075,18076,18077,18078,18079,\n18080,18081,18082,18083,18084,18085,18086,18087,18088,18089,18090,18091,\n18092,18093,18094,18095,18096,18097,18098,18099,18100,18101,18102,18103,\n18104,18105,18106,18107,18108,18109,18110,18111,18112,18113,18114,18115,\n18116,18117,18118,18119,18120,18121,18122,18123,18124,18125,18126,18127,\n18128,18129,18130,18131,18132,18133,18134,18135,18136,18137,18138,18139,\n18140,18141,18142,18143,18144,18145,18146,18147,18148,18149,18150,18151,\n18152,18153,18154,18155,18156,18157,18158,18159,18160,18161,18162,18163,\n18164,18165,18166,18167,18168,18169,18170,18171,18172,18173,18174,18175,\n18176,18177,18178,18179,18180,18181,18182,18183,18184,18185,18186,18187,\n18188,18189,18190,18191,18192,18193,18194,18195,18196,18197,18198,18199,\n18200,18201,18202,18203,18204,18205,18206,18207,18208,18209,18210,18211,\n18212,18213,18214,18215,18216,18217,18218,18219,18220,18221,18222,18223,\n18224,18225,18226,18227,18228,18229,18230,18231,18232,18233,18234,18235,\n18236,18237,18238,18239,18240,18241,18242,18243,18244,18245,18246,18247,\n18248,18249,18250,18251,18252,18253,18254,18255,18256,18257,18258,18259,\n18260,18261,18262,18263,18264,18265,18266,18267,18268,18269,18270,18271,\n18272,18273,18274,18275,18276,18277,18278,18279,18280,18281,18282,18283,\n18284,18285,18286,18287,18288,18289,18290,18291,18292,18293,18294,18295,\n18296,18297,18298,18299,18300,18301,18302,18303,18304,18305,18306,18307,\n18308,18309,18310,18311,18312,18313,18314,18315,18316,18317,18318,18319,\n18320,18321,18322,18323,18324,18325,18326,18327,18328,18329,18330,18331,\n18332,18333,18334,18335,18336,18337,18338,18339,18340,18341,18342,18343,\n18344,18345,18346,18347,18348,18349,18350,18351,18352,18353,18354,18355,\n18356,18357,18358,18359,18360,18361,18362,18363,18364,18365,18366,18367,\n18368,18369,18370,18371,18372,18373,18374,18375,18376,18377,18378,18379,\n18380,18381,18382,18383,18384,18385,18386,18387,18388,18389,18390,18391,\n18392,18393,18394,18395,18396,18397,18398,18399,18400,18401,18402,18403,\n18404,18405,18406,18407,18408,18409,18410,18411,18412,18413,18414,18415,\n18416,18417,18418,18419,18420,18421,18422,18423,18424,18425,18426,18427,\n18428,18429,18430,18431,18432,18433,18434,18435,18436,18437,18438,18439,\n18440,18441,18442,18443,18444,18445,18446,18447,18448,18449,18450,18451,\n18452,18453,18454,18455,18456,18457,18458,18459,18460,18461,18462,18463,\n18464,18465,18466,18467,18468,18469,18470,18471,18472,18473,18474,18475,\n18476,18477,18478,18479,18480,18481,18482,18483,18484,18485,18486,18487,\n18488,18489,18490,18491,18492,18493,18494,18495,18496,18497,18498,18499,\n18500,18501,18502,18503,18504,18505,18506,18507,18508,18509,18510,18511,\n18512,18513,18514,18515,18516,18517,18518,18519,18520,18521,18522,18523,\n18524,18525,18526,18527,18528,18529,18530,18531,18532,18533,18534,18535,\n18536,18537,18538,18539,18540,18541,18542,18543,18544,18545,18546,18547,\n18548,18549,18550,18551,18552,18553,18554,18555,18556,18557,18558,18559,\n18560,18561,18562,18563,18564,18565,18566,18567,18568,18569,18570,18571,\n18572,18573,18574,18575,18576,18577,18578,18579,18580,18581,18582,18583,\n18584,18585,18586,18587,18588,18589,18590,18591,18592,18593,18594,18595,\n18596,18597,18598,18599,18600,18601,18602,18603,18604,18605,18606,18607,\n18608,18609,18610,18611,18612,18613,18614,18615,18616,18617,18618,18619,\n18620,18621,18622,18623,18624,18625,18626,18627,18628,18629,18630,18631,\n18632,18633,18634,18635,18636,18637,18638,18639,18640,18641,18642,18643,\n18644,18645,18646,18647,18648,18649,18650,18651,18652,18653,18654,18655,\n18656,18657,18658,18659,18660,18661,18662,18663,18664,18665,18666,18667,\n18668,18669,18670,18671,18672,18673,18674,18675,18676,18677,18678,18679,\n18680,18681,18682,18683,18684,18685,18686,18687,18688,18689,18690,18691,\n18692,18693,18694,18695,18696,18697,18698,18699,18700,18701,18702,18703,\n18704,18705,18706,18707,18708,18709,18710,18711,18712,18713,18714,18715,\n18716,18717,18718,18719,18720,18721,18722,18723,18724,18725,18726,18727,\n18728,18729,18730,18731,18732,18733,18734,18735,18736,18737,18738,18739,\n18740,18741,18742,18743,18744,18745,18746,18747,18748,18749,18750,18751,\n18752,18753,18754,18755,18756,18757,18758,18759,18760,18761,18762,18763,\n18764,18765,18766,18767,18768,18769,18770,18771,18772,18773,18774,18775,\n18776,18777,18778,18779,18780,18781,18782,18783,18784,18785,18786,18787,\n18788,18789,18790,18791,18792,18793,18794,18795,18796,18797,18798,18799,\n18800,18801,18802,18803,18804,18805,18806,18807,18808,18809,18810,18811,\n18812,18813,18814,18815,18816,18817,18818,18819,18820,18821,18822,18823,\n18824,18825,18826,18827,18828,18829,18830,18831,18832,18833,18834,18835,\n18836,18837,18838,18839,18840,18841,18842,18843,18844,18845,18846,18847,\n18848,18849,18850,18851,18852,18853,18854,18855,18856,18857,18858,18859,\n18860,18861,18862,18863,18864,18865,18866,18867,18868,18869,18870,18871,\n18872,18873,18874,18875,18876,18877,18878,18879,18880,18881,18882,18883,\n18884,18885,18886,18887,18888,18889,18890,18891,18892,18893,18894,18895,\n18896,18897,18898,18899,18900,18901,18902,18903,18904,18905,18906,18907,\n18908,18909,18910,18911,18912,18913,18914,18915,18916,18917,18918,18919,\n18920,18921,18922,18923,18924,18925,18926,18927,18928,18929,18930,18931,\n18932,18933,18934,18935,18936,18937,18938,18939,18940,18941,18942,18943,\n18944,18945,18946,18947,18948,18949,18950,18951,18952,18953,18954,18955,\n18956,18957,18958,18959,18960,18961,18962,18963,18964,18965,18966,18967,\n18968,18969,18970,18971,18972,18973,18974,18975,18976,18977,18978,18979,\n18980,18981,18982,18983,18984,18985,18986,18987,18988,18989,18990,18991,\n18992,18993,18994,18995,18996,18997,18998,18999,19000,19001,19002,19003,\n19004,19005,19006,19007,19008,19009,19010,19011,19012,19013,19014,19015,\n19016,19017,19018,19019,19020,19021,19022,19023,19024,19025,19026,19027,\n19028,19029,19030,19031,19032,19033,19034,19035,19036,19037,19038,19039,\n19040,19041,19042,19043,19044,19045,19046,19047,19048,19049,19050,19051,\n19052,19053,19054,19055,19056,19057,19058,19059,19060,19061,19062,19063,\n19064,19065,19066,19067,19068,19069,19070,19071,19072,19073,19074,19075,\n19076,19077,19078,19079,19080,19081,19082,19083,19084,19085,19086,19087,\n19088,19089,19090,19091,19092,19093,19094,19095,19096,19097,19098,19099,\n19100,19101,19102,19103,19104,19105,19106,19107,19108,19109,19110,19111,\n19112,19113,19114,19115,19116,19117,19118,19119,19120,19121,19122,19123,\n19124,19125,19126,19127,19128,19129,19130,19131,19132,19133,19134,19135,\n19136,19137,19138,19139,19140,19141,19142,19143,19144,19145,19146,19147,\n19148,19149,19150,19151,19152,19153,19154,19155,19156,19157,19158,19159,\n19160,19161,19162,19163,19164,19165,19166,19167,19168,19169,19170,19171,\n19172,19173,19174,19175,19176,19177,19178,19179,19180,19181,19182,19183,\n19184,19185,19186,19187,19188,19189,19190,19191,19192,19193,19194,19195,\n19196,19197,19198,19199,19200,19201,19202,19203,19204,19205,19206,19207,\n19208,19209,19210,19211,19212,19213,19214,19215,19216,19217,19218,19219,\n19220,19221,19222,19223,19224,19225,19226,19227,19228,19229,19230,19231,\n19232,19233,19234,19235,19236,19237,19238,19239,19240,19241,19242,19243,\n19244,19245,19246,19247,19248,19249,19250,19251,19252,19253,19254,19255,\n19256,19257,19258,19259,19260,19261,19262,19263,19264,19265,19266,19267,\n19268,19269,19270,19271,19272,19273,19274,19275,19276,19277,19278,19279,\n19280,19281,19282,19283,19284,19285,19286,19287,19288,19289,19290,19291,\n19292,19293,19294,19295,19296,19297,19298,19299,19300,19301,19302,19303,\n19304,19305,19306,19307,19308,19309,19310,19311,19312,19313,19314,19315,\n19316,19317,19318,19319,19320,19321,19322,19323,19324,19325,19326,19327,\n19328,19329,19330,19331,19332,19333,19334,19335,19336,19337,19338,19339,\n19340,19341,19342,19343,19344,19345,19346,19347,19348,19349,19350,19351,\n19352,19353,19354,19355,19356,19357,19358,19359,19360,19361,19362,19363,\n19364,19365,19366,19367,19368,19369,19370,19371,19372,19373,19374,19375,\n19376,19377,19378,19379,19380,19381,19382,19383,19384,19385,19386,19387,\n19388,19389,19390,19391,19392,19393,19394,19395,19396,19397,19398,19399,\n19400,19401,19402,19403,19404,19405,19406,19407,19408,19409,19410,19411,\n19412,19413,19414,19415,19416,19417,19418,19419,19420,19421,19422,19423,\n19424,19425,19426,19427,19428,19429,19430,19431,19432,19433,19434,19435,\n19436,19437,19438,19439,19440,19441,19442,19443,19444,19445,19446,19447,\n19448,19449,19450,19451,19452,19453,19454,19455,19456,19457,19458,19459,\n19460,19461,19462,19463,19464,19465,19466,19467,19468,19469,19470,19471,\n19472,19473,19474,19475,19476,19477,19478,19479,19480,19481,19482,19483,\n19484,19485,19486,19487,19488,19489,19490,19491,19492,19493,19494,19495,\n19496,19497,19498,19499,19500,19501,19502,19503,19504,19505,19506,19507,\n19508,19509,19510,19511,19512,19513,19514,19515,19516,19517,19518,19519,\n19520,19521,19522,19523,19524,19525,19526,19527,19528,19529,19530,19531,\n19532,19533,19534,19535,19536,19537,19538,19539,19540,19541,19542,19543,\n19544,19545,19546,19547,19548,19549,19550,19551,19552,19553,19554,19555,\n19556,19557,19558,19559,19560,19561,19562,19563,19564,19565,19566,19567,\n19568,19569,19570,19571,19572,19573,19574,19575,19576,19577,19578,19579,\n19580,19581,19582,19583,19584,19585,19586,19587,19588,19589,19590,19591,\n19592,19593,19594,19595,19596,19597,19598,19599,19600,19601,19602,19603,\n19604,19605,19606,19607,19608,19609,19610,19611,19612,19613,19614,19615,\n19616,19617,19618,19619,19620,19621,19622,19623,19624,19625,19626,19627,\n19628,19629,19630,19631,19632,19633,19634,19635,19636,19637,19638,19639,\n19640,19641,19642,19643,19644,19645,19646,19647,19648,19649,19650,19651,\n19652,19653,19654,19655,19656,19657,19658,19659,19660,19661,19662,19663,\n19664,19665,19666,19667,19668,19669,19670,19671,19672,19673,19674,19675,\n19676,19677,19678,19679,19680,19681,19682,19683,19684,19685,19686,19687,\n19688,19689,19690,19691,19692,19693,19694,19695,19696,19697,19698,19699,\n19700,19701,19702,19703,19704,19705,19706,19707,19708,19709,19710,19711,\n19712,19713,19714,19715,19716,19717,19718,19719,19720,19721,19722,19723,\n19724,19725,19726,19727,19728,19729,19730,19731,19732,19733,19734,19735,\n19736,19737,19738,19739,19740,19741,19742,19743,19744,19745,19746,19747,\n19748,19749,19750,19751,19752,19753,19754,19755,19756,19757,19758,19759,\n19760,19761,19762,19763,19764,19765,19766,19767,19768,19769,19770,19771,\n19772,19773,19774,19775,19776,19777,19778,19779,19780,19781,19782,19783,\n19784,19785,19786,19787,19788,19789,19790,19791,19792,19793,19794,19795,\n19796,19797,19798,19799,19800,19801,19802,19803,19804,19805,19806,19807,\n19808,19809,19810,19811,19812,19813,19814,19815,19816,19817,19818,19819,\n19820,19821,19822,19823,19824,19825,19826,19827,19828,19829,19830,19831,\n19832,19833,19834,19835,19836,19837,19838,19839,19840,19841,19842,19843,\n19844,19845,19846,19847,19848,19849,19850,19851,19852,19853,19854,19855,\n19856,19857,19858,19859,19860,19861,19862,19863,19864,19865,19866,19867,\n19868,19869,19870,19871,19872,19873,19874,19875,19876,19877,19878,19879,\n19880,19881,19882,19883,19884,19885,19886,19887,19888,19889,19890,19891,\n19892,19893,19894,19895,19896,19897,19898,19899,19900,19901,19902,19903,\n19904,19905,19906,19907,19908,19909,19910,19911,19912,19913,19914,19915,\n19916,19917,19918,19919,19920,19921,19922,19923,19924,19925,19926,19927,\n19928,19929,19930,19931,19932,19933,19934,19935,19936,19937,19938,19939,\n19940,19941,19942,19943,19944,19945,19946,19947,19948,19949,19950,19951,\n19952,19953,19954,19955,19956,19957,19958,19959,19960,19961,19962,19963,\n19964,19965,19966,19967,19968,19969,19970,19971,19972,19973,19974,19975,\n19976,19977,19978,19979,19980,19981,19982,19983,19984,19985,19986,19987,\n19988,19989,19990,19991,19992,19993,19994,19995,19996,19997,19998,19999,\n20000,20001,20002,20003,20004,20005,20006,20007,20008,20009,20010,20011,\n20012,20013,20014,20015,20016,20017,20018,20019,20020,20021,20022,20023,\n20024,20025,20026,20027,20028,20029,20030,20031,20032,20033,20034,20035,\n20036,20037,20038,20039,20040,20041,20042,20043,20044,20045,20046,20047,\n20048,20049,20050,20051,20052,20053,20054,20055,20056,20057,20058,20059,\n20060,20061,20062,20063,20064,20065,20066,20067,20068,20069,20070,20071,\n20072,20073,20074,20075,20076,20077,20078,20079,20080,20081,20082,20083,\n20084,20085,20086,20087,20088,20089,20090,20091,20092,20093,20094,20095,\n20096,20097,20098,20099,20100,20101,20102,20103,20104,20105,20106,20107,\n20108,20109,20110,20111,20112,20113,20114,20115,20116,20117,20118,20119,\n20120,20121,20122,20123,20124,20125,20126,20127,20128,20129,20130,20131,\n20132,20133,20134,20135,20136,20137,20138,20139,20140,20141,20142,20143,\n20144,20145,20146,20147,20148,20149,20150,20151,20152,20153,20154,20155,\n20156,20157,20158,20159,20160,20161,20162,20163,20164,20165,20166,20167,\n20168,20169,20170,20171,20172,20173,20174,20175,20176,20177,20178,20179,\n20180,20181,20182,20183,20184,20185,20186,20187,20188,20189,20190,20191,\n20192,20193,20194,20195,20196,20197,20198,20199,20200,20201,20202,20203,\n20204,20205,20206,20207,20208,20209,20210,20211,20212,20213,20214,20215,\n20216,20217,20218,20219,20220,20221,20222,20223,20224,20225,20226,20227,\n20228,20229,20230,20231,20232,20233,20234,20235,20236,20237,20238,20239,\n20240,20241,20242,20243,20244,20245,20246,20247,20248,20249,20250,20251,\n20252,20253,20254,20255,20256,20257,20258,20259,20260,20261,20262,20263,\n20264,20265,20266,20267,20268,20269,20270,20271,20272,20273,20274,20275,\n20276,20277,20278,20279,20280,20281,20282,20283,20284,20285,20286,20287,\n20288,20289,20290,20291,20292,20293,20294,20295,20296,20297,20298,20299,\n20300,20301,20302,20303,20304,20305,20306,20307,20308,20309,20310,20311,\n20312,20313,20314,20315,20316,20317,20318,20319,20320,20321,20322,20323,\n20324,20325,20326,20327,20328,20329,20330,20331,20332,20333,20334,20335,\n20336,20337,20338,20339,20340,20341,20342,20343,20344,20345,20346,20347,\n20348,20349,20350,20351,20352,20353,20354,20355,20356,20357,20358,20359,\n20360,20361,20362,20363,20364,20365,20366,20367,20368,20369,20370,20371,\n20372,20373,20374,20375,20376,20377,20378,20379,20380,20381,20382,20383,\n20384,20385,20386,20387,20388,20389,20390,20391,20392,20393,20394,20395,\n20396,20397,20398,20399,20400,20401,20402,20403,20404,20405,20406,20407,\n20408,20409,20410,20411,20412,20413,20414,20415,20416,20417,20418,20419,\n20420,20421,20422,20423,20424,20425,20426,20427,20428,20429,20430,20431,\n20432,20433,20434,20435,20436,20437,20438,20439,20440,20441,20442,20443,\n20444,20445,20446,20447,20448,20449,20450,20451,20452,20453,20454,20455,\n20456,20457,20458,20459,20460,20461,20462,20463,20464,20465,20466,20467,\n20468,20469,20470,20471,20472,20473,20474,20475,20476,20477,20478,20479,\n20480,20481,20482,20483,20484,20485,20486,20487,20488,20489,20490,20491,\n20492,20493,20494,20495,20496,20497,20498,20499,20500,20501,20502,20503,\n20504,20505,20506,20507,20508,20509,20510,20511,20512,20513,20514,20515,\n20516,20517,20518,20519,20520,20521,20522,20523,20524,20525,20526,20527,\n20528,20529,20530,20531,20532,20533,20534,20535,20536,20537,20538,20539,\n20540,20541,20542,20543,20544,20545,20546,20547,20548,20549,20550,20551,\n20552,20553,20554,20555,20556,20557,20558,20559,20560,20561,20562,20563,\n20564,20565,20566,20567,20568,20569,20570,20571,20572,20573,20574,20575,\n20576,20577,20578,20579,20580,20581,20582,20583,20584,20585,20586,20587,\n20588,20589,20590,20591,20592,20593,20594,20595,20596,20597,20598,20599,\n20600,20601,20602,20603,20604,20605,20606,20607,20608,20609,20610,20611,\n20612,20613,20614,20615,20616,20617,20618,20619,20620,20621,20622,20623,\n20624,20625,20626,20627,20628,20629,20630,20631,20632,20633,20634,20635,\n20636,20637,20638,20639,20640,20641,20642,20643,20644,20645,20646,20647,\n20648,20649,20650,20651,20652,20653,20654,20655,20656,20657,20658,20659,\n20660,20661,20662,20663,20664,20665,20666,20667,20668,20669,20670,20671,\n20672,20673,20674,20675,20676,20677,20678,20679,20680,20681,20682,20683,\n20684,20685,20686,20687,20688,20689,20690,20691,20692,20693,20694,20695,\n20696,20697,20698,20699,20700,20701,20702,20703,20704,20705,20706,20707,\n20708,20709,20710,20711,20712,20713,20714,20715,20716,20717,20718,20719,\n20720,20721,20722,20723,20724,20725,20726,20727,20728,20729,20730,20731,\n20732,20733,20734,20735,20736,20737,20738,20739,20740,20741,20742,20743,\n20744,20745,20746,20747,20748,20749,20750,20751,20752,20753,20754,20755,\n20756,20757,20758,20759,20760,20761,20762,20763,20764,20765,20766,20767,\n20768,20769,20770,20771,20772,20773,20774,20775,20776,20777,20778,20779,\n20780,20781,20782,20783,20784,20785,20786,20787,20788,20789,20790,20791,\n20792,20793,20794,20795,20796,20797,20798,20799,20800,20801,20802,20803,\n20804,20805,20806,20807,20808,20809,20810,20811,20812,20813,20814,20815,\n20816,20817,20818,20819,20820,20821,20822,20823,20824,20825,20826,20827,\n20828,20829,20830,20831,20832,20833,20834,20835,20836,20837,20838,20839,\n20840,20841,20842,20843,20844,20845,20846,20847,20848,20849,20850,20851,\n20852,20853,20854,20855,20856,20857,20858,20859,20860,20861,20862,20863,\n20864,20865,20866,20867,20868,20869,20870,20871,20872,20873,20874,20875,\n20876,20877,20878,20879,20880,20881,20882,20883,20884,20885,20886,20887,\n20888,20889,20890,20891,20892,20893,20894,20895,20896,20897,20898,20899,\n20900,20901,20902,20903,20904,20905,20906,20907,20908,20909,20910,20911,\n20912,20913,20914,20915,20916,20917,20918,20919,20920,20921,20922,20923,\n20924,20925,20926,20927,20928,20929,20930,20931,20932,20933,20934,20935,\n20936,20937,20938,20939,20940,20941,20942,20943,20944,20945,20946,20947,\n20948,20949,20950,20951,20952,20953,20954,20955,20956,20957,20958,20959,\n20960,20961,20962,20963,20964,20965,20966,20967,20968,20969,20970,20971,\n20972,20973,20974,20975,20976,20977,20978,20979,20980,20981,20982,20983,\n20984,20985,20986,20987,20988,20989,20990,20991,20992,20993,20994,20995,\n20996,20997,20998,20999,21000,21001,21002,21003,21004,21005,21006,21007,\n21008,21009,21010,21011,21012,21013,21014,21015,21016,21017,21018,21019,\n21020,21021,21022,21023,21024,21025,21026,21027,21028,21029,21030,21031,\n21032,21033,21034,21035,21036,21037,21038,21039,21040,21041,21042,21043,\n21044,21045,21046,21047,21048,21049,21050,21051,21052,21053,21054,21055,\n21056,21057,21058,21059,21060,21061,21062,21063,21064,21065,21066,21067,\n21068,21069,21070,21071,21072,21073,21074,21075,21076,21077,21078,21079,\n21080,21081,21082,21083,21084,21085,21086,21087,21088,21089,21090,21091,\n21092,21093,21094,21095,21096,21097,21098,21099,21100,21101,21102,21103,\n21104,21105,21106,21107,21108,21109,21110,21111,21112,21113,21114,21115,\n21116,21117,21118,21119,21120,21121,21122,21123,21124,21125,21126,21127,\n21128,21129,21130,21131,21132,21133,21134,21135,21136,21137,21138,21139,\n21140,21141,21142,21143,21144,21145,21146,21147,21148,21149,21150,21151,\n21152,21153,21154,21155,21156,21157,21158,21159,21160,21161,21162,21163,\n21164,21165,21166,21167,21168,21169,21170,21171,21172,21173,21174,21175,\n21176,21177,21178,21179,21180,21181,21182,21183,21184,21185,21186,21187,\n21188,21189,21190,21191,21192,21193,21194,21195,21196,21197,21198,21199,\n21200,21201,21202,21203,21204,21205,21206,21207,21208,21209,21210,21211,\n21212,21213,21214,21215,21216,21217,21218,21219,21220,21221,21222,21223,\n21224,21225,21226,21227,21228,21229,21230,21231,21232,21233,21234,21235,\n21236,21237,21238,21239,21240,21241,21242,21243,21244,21245,21246,21247,\n21248,21249,21250,21251,21252,21253,21254,21255,21256,21257,21258,21259,\n21260,21261,21262,21263,21264,21265,21266,21267,21268,21269,21270,21271,\n21272,21273,21274,21275,21276,21277,21278,21279,21280,21281,21282,21283,\n21284,21285,21286,21287,21288,21289,21290,21291,21292,21293,21294,21295,\n21296,21297,21298,21299,21300,21301,21302,21303,21304,21305,21306,21307,\n21308,21309,21310,21311,21312,21313,21314,21315,21316,21317,21318,21319,\n21320,21321,21322,21323,21324,21325,21326,21327,21328,21329,21330,21331,\n21332,21333,21334,21335,21336,21337,21338,21339,21340,21341,21342,21343,\n21344,21345,21346,21347,21348,21349,21350,21351,21352,21353,21354,21355,\n21356,21357,21358,21359,21360,21361,21362,21363,21364,21365,21366,21367,\n21368,21369,21370,21371,21372,21373,21374,21375,21376,21377,21378,21379,\n21380,21381,21382,21383,21384,21385,21386,21387,21388,21389,21390,21391,\n21392,21393,21394,21395,21396,21397,21398,21399,21400,21401,21402,21403,\n21404,21405,21406,21407,21408,21409,21410,21411,21412,21413,21414,21415,\n21416,21417,21418,21419,21420,21421,21422,21423,21424,21425,21426,21427,\n21428,21429,21430,21431,21432,21433,21434,21435,21436,21437,21438,21439,\n21440,21441,21442,21443,21444,21445,21446,21447,21448,21449,21450,21451,\n21452,21453,21454,21455,21456,21457,21458,21459,21460,21461,21462,21463,\n21464,21465,21466,21467,21468,21469,21470,21471,21472,21473,21474,21475,\n21476,21477,21478,21479,21480,21481,21482,21483,21484,21485,21486,21487,\n21488,21489,21490,21491,21492,21493,21494,21495,21496,21497,21498,21499,\n21500,21501,21502,21503,21504,21505,21506,21507,21508,21509,21510,21511,\n21512,21513,21514,21515,21516,21517,21518,21519,21520,21521,21522,21523,\n21524,21525,21526,21527,21528,21529,21530,21531,21532,21533,21534,21535,\n21536,21537,21538,21539,21540,21541,21542,21543,21544,21545,21546,21547,\n21548,21549,21550,21551,21552,21553,21554,21555,21556,21557,21558,21559,\n21560,21561,21562,21563,21564,21565,21566,21567,21568,21569,21570,21571,\n21572,21573,21574,21575,21576,21577,21578,21579,21580,21581,21582,21583,\n21584,21585,21586,21587,21588,21589,21590,21591,21592,21593,21594,21595,\n21596,21597,21598,21599,21600,21601,21602,21603,21604,21605,21606,21607,\n21608,21609,21610,21611,21612,21613,21614,21615,21616,21617,21618,21619,\n21620,21621,21622,21623,21624,21625,21626,21627,21628,21629,21630,21631,\n21632,21633,21634,21635,21636,21637,21638,21639,21640,21641,21642,21643,\n21644,21645,21646,21647,21648,21649,21650,21651,21652,21653,21654,21655,\n21656,21657,21658,21659,21660,21661,21662,21663,21664,21665,21666,21667,\n21668,21669,21670,21671,21672,21673,21674,21675,21676,21677,21678,21679,\n21680,21681,21682,21683,21684,21685,21686,21687,21688,21689,21690,21691,\n21692,21693,21694,21695,21696,21697,21698,21699,21700,21701,21702,21703,\n21704,21705,21706,21707,21708,21709,21710,21711,21712,21713,21714,21715,\n21716,21717,21718,21719,21720,21721,21722,21723,21724,21725,21726,21727,\n21728,21729,21730,21731,21732,21733,21734,21735,21736,21737,21738,21739,\n21740,21741,21742,21743,21744,21745,21746,21747,21748,21749,21750,21751,\n21752,21753,21754,21755,21756,21757,21758,21759,21760,21761,21762,21763,\n21764,21765,21766,21767,21768,21769,21770,21771,21772,21773,21774,21775,\n21776,21777,21778,21779,21780,21781,21782,21783,21784,21785,21786,21787,\n21788,21789,21790,21791,21792,21793,21794,21795,21796,21797,21798,21799,\n21800,21801,21802,21803,21804,21805,21806,21807,21808,21809,21810,21811,\n21812,21813,21814,21815,21816,21817,21818,21819,21820,21821,21822,21823,\n21824,21825,21826,21827,21828,21829,21830,21831,21832,21833,21834,21835,\n21836,21837,21838,21839,21840,21841,21842,21843,21844,21845,21846,21847,\n21848,21849,21850,21851,21852,21853,21854,21855,21856,21857,21858,21859,\n21860,21861,21862,21863,21864,21865,21866,21867,21868,21869,21870,21871,\n21872,21873,21874,21875,21876,21877,21878,21879,21880,21881,21882,21883,\n21884,21885,21886,21887,21888,21889,21890,21891,21892,21893,21894,21895,\n21896,21897,21898,21899,21900,21901,21902,21903,21904,21905,21906,21907,\n21908,21909,21910,21911,21912,21913,21914,21915,21916,21917,21918,21919,\n21920,21921,21922,21923,21924,21925,21926,21927,21928,21929,21930,21931,\n21932,21933,21934,21935,21936,21937,21938,21939,21940,21941,21942,21943,\n21944,21945,21946,21947,21948,21949,21950,21951,21952,21953,21954,21955,\n21956,21957,21958,21959,21960,21961,21962,21963,21964,21965,21966,21967,\n21968,21969,21970,21971,21972,21973,21974,21975,21976,21977,21978,21979,\n21980,21981,21982,21983,21984,21985,21986,21987,21988,21989,21990,21991,\n21992,21993,21994,21995,21996,21997,21998,21999,22000,22001,22002,22003,\n22004,22005,22006,22007,22008,22009,22010,22011,22012,22013,22014,22015,\n22016,22017,22018,22019,22020,22021,22022,22023,22024,22025,22026,22027,\n22028,22029,22030,22031,22032,22033,22034,22035,22036,22037,22038,22039,\n22040,22041,22042,22043,22044,22045,22046,22047,22048,22049,22050,22051,\n22052,22053,22054,22055,22056,22057,22058,22059,22060,22061,22062,22063,\n22064,22065,22066,22067,22068,22069,22070,22071,22072,22073,22074,22075,\n22076,22077,22078,22079,22080,22081,22082,22083,22084,22085,22086,22087,\n22088,22089,22090,22091,22092,22093,22094,22095,22096,22097,22098,22099,\n22100,22101,22102,22103,22104,22105,22106,22107,22108,22109,22110,22111,\n22112,22113,22114,22115,22116,22117,22118,22119,22120,22121,22122,22123,\n22124,22125,22126,22127,22128,22129,22130,22131,22132,22133,22134,22135,\n22136,22137,22138,22139,22140,22141,22142,22143,22144,22145,22146,22147,\n22148,22149,22150,22151,22152,22153,22154,22155,22156,22157,22158,22159,\n22160,22161,22162,22163,22164,22165,22166,22167,22168,22169,22170,22171,\n22172,22173,22174,22175,22176,22177,22178,22179,22180,22181,22182,22183,\n22184,22185,22186,22187,22188,22189,22190,22191,22192,22193,22194,22195,\n22196,22197,22198,22199,22200,22201,22202,22203,22204,22205,22206,22207,\n22208,22209,22210,22211,22212,22213,22214,22215,22216,22217,22218,22219,\n22220,22221,22222,22223,22224,22225,22226,22227,22228,22229,22230,22231,\n22232,22233,22234,22235,22236,22237,22238,22239,22240,22241,22242,22243,\n22244,22245,22246,22247,22248,22249,22250,22251,22252,22253,22254,22255,\n22256,22257,22258,22259,22260,22261,22262,22263,22264,22265,22266,22267,\n22268,22269,22270,22271,22272,22273,22274,22275,22276,22277,22278,22279,\n22280,22281,22282,22283,22284,22285,22286,22287,22288,22289,22290,22291,\n22292,22293,22294,22295,22296,22297,22298,22299,22300,22301,22302,22303,\n22304,22305,22306,22307,22308,22309,22310,22311,22312,22313,22314,22315,\n22316,22317,22318,22319,22320,22321,22322,22323,22324,22325,22326,22327,\n22328,22329,22330,22331,22332,22333,22334,22335,22336,22337,22338,22339,\n22340,22341,22342,22343,22344,22345,22346,22347,22348,22349,22350,22351,\n22352,22353,22354,22355,22356,22357,22358,22359,22360,22361,22362,22363,\n22364,22365,22366,22367,22368,22369,22370,22371,22372,22373,22374,22375,\n22376,22377,22378,22379,22380,22381,22382,22383,22384,22385,22386,22387,\n22388,22389,22390,22391,22392,22393,22394,22395,22396,22397,22398,22399,\n22400,22401,22402,22403,22404,22405,22406,22407,22408,22409,22410,22411,\n22412,22413,22414,22415,22416,22417,22418,22419,22420,22421,22422,22423,\n22424,22425,22426,22427,22428,22429,22430,22431,22432,22433,22434,22435,\n22436,22437,22438,22439,22440,22441,22442,22443,22444,22445,22446,22447,\n22448,22449,22450,22451,22452,22453,22454,22455,22456,22457,22458,22459,\n22460,22461,22462,22463,22464,22465,22466,22467,22468,22469,22470,22471,\n22472,22473,22474,22475,22476,22477,22478,22479,22480,22481,22482,22483,\n22484,22485,22486,22487,22488,22489,22490,22491,22492,22493,22494,22495,\n22496,22497,22498,22499,22500,22501,22502,22503,22504,22505,22506,22507,\n22508,22509,22510,22511,22512,22513,22514,22515,22516,22517,22518,22519,\n22520,22521,22522,22523,22524,22525,22526,22527,22528,22529,22530,22531,\n22532,22533,22534,22535,22536,22537,22538,22539,22540,22541,22542,22543,\n22544,22545,22546,22547,22548,22549,22550,22551,22552,22553,22554,22555,\n22556,22557,22558,22559,22560,22561,22562,22563,22564,22565,22566,22567,\n22568,22569,22570,22571,22572,22573,22574,22575,22576,22577,22578,22579,\n22580,22581,22582,22583,22584,22585,22586,22587,22588,22589,22590,22591,\n22592,22593,22594,22595,22596,22597,22598,22599,22600,22601,22602,22603,\n22604,22605,22606,22607,22608,22609,22610,22611,22612,22613,22614,22615,\n22616,22617,22618,22619,22620,22621,22622,22623,22624,22625,22626,22627,\n22628,22629,22630,22631,22632,22633,22634,22635,22636,22637,22638,22639,\n22640,22641,22642,22643,22644,22645,22646,22647,22648,22649,22650,22651,\n22652,22653,22654,22655,22656,22657,22658,22659,22660,22661,22662,22663,\n22664,22665,22666,22667,22668,22669,22670,22671,22672,22673,22674,22675,\n22676,22677,22678,22679,22680,22681,22682,22683,22684,22685,22686,22687,\n22688,22689,22690,22691,22692,22693,22694,22695,22696,22697,22698,22699,\n22700,22701,22702,22703,22704,22705,22706,22707,22708,22709,22710,22711,\n22712,22713,22714,22715,22716,22717,22718,22719,22720,22721,22722,22723,\n22724,22725,22726,22727,22728,22729,22730,22731,22732,22733,22734,22735,\n22736,22737,22738,22739,22740,22741,22742,22743,22744,22745,22746,22747,\n22748,22749,22750,22751,22752,22753,22754,22755,22756,22757,22758,22759,\n22760,22761,22762,22763,22764,22765,22766,22767,22768,22769,22770,22771,\n22772,22773,22774,22775,22776,22777,22778,22779,22780,22781,22782,22783,\n22784,22785,22786,22787,22788,22789,22790,22791,22792,22793,22794,22795,\n22796,22797,22798,22799,22800,22801,22802,22803,22804,22805,22806,22807,\n22808,22809,22810,22811,22812,22813,22814,22815,22816,22817,22818,22819,\n22820,22821,22822,22823,22824,22825,22826,22827,22828,22829,22830,22831,\n22832,22833,22834,22835,22836,22837,22838,22839,22840,22841,22842,22843,\n22844,22845,22846,22847,22848,22849,22850,22851,22852,22853,22854,22855,\n22856,22857,22858,22859,22860,22861,22862,22863,22864,22865,22866,22867,\n22868,22869,22870,22871,22872,22873,22874,22875,22876,22877,22878,22879,\n22880,22881,22882,22883,22884,22885,22886,22887,22888,22889,22890,22891,\n22892,22893,22894,22895,22896,22897,22898,22899,22900,22901,22902,22903,\n22904,22905,22906,22907,22908,22909,22910,22911,22912,22913,22914,22915,\n22916,22917,22918,22919,22920,22921,22922,22923,22924,22925,22926,22927,\n22928,22929,22930,22931,22932,22933,22934,22935,22936,22937,22938,22939,\n22940,22941,22942,22943,22944,22945,22946,22947,22948,22949,22950,22951,\n22952,22953,22954,22955,22956,22957,22958,22959,22960,22961,22962,22963,\n22964,22965,22966,22967,22968,22969,22970,22971,22972,22973,22974,22975,\n22976,22977,22978,22979,22980,22981,22982,22983,22984,22985,22986,22987,\n22988,22989,22990,22991,22992,22993,22994,22995,22996,22997,22998,22999,\n23000,23001,23002,23003,23004,23005,23006,23007,23008,23009,23010,23011,\n23012,23013,23014,23015,23016,23017,23018,23019,23020,23021,23022,23023,\n23024,23025,23026,23027,23028,23029,23030,23031,23032,23033,23034,23035,\n23036,23037,23038,23039,23040,23041,23042,23043,23044,23045,23046,23047,\n23048,23049,23050,23051,23052,23053,23054,23055,23056,23057,23058,23059,\n23060,23061,23062,23063,23064,23065,23066,23067,23068,23069,23070,23071,\n23072,23073,23074,23075,23076,23077,23078,23079,23080,23081,23082,23083,\n23084,23085,23086,23087,23088,23089,23090,23091,23092,23093,23094,23095,\n23096,23097,23098,23099,23100,23101,23102,23103,23104,23105,23106,23107,\n23108,23109,23110,23111,23112,23113,23114,23115,23116,23117,23118,23119,\n23120,23121,23122,23123,23124,23125,23126,23127,23128,23129,23130,23131,\n23132,23133,23134,23135,23136,23137,23138,23139,23140,23141,23142,23143,\n23144,23145,23146,23147,23148,23149,23150,23151,23152,23153,23154,23155,\n23156,23157,23158,23159,23160,23161,23162,23163,23164,23165,23166,23167,\n23168,23169,23170,23171,23172,23173,23174,23175,23176,23177,23178,23179,\n23180,23181,23182,23183,23184,23185,23186,23187,23188,23189,23190,23191,\n23192,23193,23194,23195,23196,23197,23198,23199,23200,23201,23202,23203,\n23204,23205,23206,23207,23208,23209,23210,23211,23212,23213,23214,23215,\n23216,23217,23218,23219,23220,23221,23222,23223,23224,23225,23226,23227,\n23228,23229,23230,23231,23232,23233,23234,23235,23236,23237,23238,23239,\n23240,23241,23242,23243,23244,23245,23246,23247,23248,23249,23250,23251,\n23252,23253,23254,23255,23256,23257,23258,23259,23260,23261,23262,23263,\n23264,23265,23266,23267,23268,23269,23270,23271,23272,23273,23274,23275,\n23276,23277,23278,23279,23280,23281,23282,23283,23284,23285,23286,23287,\n23288,23289,23290,23291,23292,23293,23294,23295,23296,23297,23298,23299,\n23300,23301,23302,23303,23304,23305,23306,23307,23308,23309,23310,23311,\n23312,23313,23314,23315,23316,23317,23318,23319,23320,23321,23322,23323,\n23324,23325,23326,23327,23328,23329,23330,23331,23332,23333,23334,23335,\n23336,23337,23338,23339,23340,23341,23342,23343,23344,23345,23346,23347,\n23348,23349,23350,23351,23352,23353,23354,23355,23356,23357,23358,23359,\n23360,23361,23362,23363,23364,23365,23366,23367,23368,23369,23370,23371,\n23372,23373,23374,23375,23376,23377,23378,23379,23380,23381,23382,23383,\n23384,23385,23386,23387,23388,23389,23390,23391,23392,23393,23394,23395,\n23396,23397,23398,23399,23400,23401,23402,23403,23404,23405,23406,23407,\n23408,23409,23410,23411,23412,23413,23414,23415,23416,23417,23418,23419,\n23420,23421,23422,23423,23424,23425,23426,23427,23428,23429,23430,23431,\n23432,23433,23434,23435,23436,23437,23438,23439,23440,23441,23442,23443,\n23444,23445,23446,23447,23448,23449,23450,23451,23452,23453,23454,23455,\n23456,23457,23458,23459,23460,23461,23462,23463,23464,23465,23466,23467,\n23468,23469,23470,23471,23472,23473,23474,23475,23476,23477,23478,23479,\n23480,23481,23482,23483,23484,23485,23486,23487,23488,23489,23490,23491,\n23492,23493,23494,23495,23496,23497,23498,23499,23500,23501,23502,23503,\n23504,23505,23506,23507,23508,23509,23510,23511,23512,23513,23514,23515,\n23516,23517,23518,23519,23520,23521,23522,23523,23524,23525,23526,23527,\n23528,23529,23530,23531,23532,23533,23534,23535,23536,23537,23538,23539,\n23540,23541,23542,23543,23544,23545,23546,23547,23548,23549,23550,23551,\n23552,23553,23554,23555,23556,23557,23558,23559,23560,23561,23562,23563,\n23564,23565,23566,23567,23568,23569,23570,23571,23572,23573,23574,23575,\n23576,23577,23578,23579,23580,23581,23582,23583,23584,23585,23586,23587,\n23588,23589,23590,23591,23592,23593,23594,23595,23596,23597,23598,23599,\n23600,23601,23602,23603,23604,23605,23606,23607,23608,23609,23610,23611,\n23612,23613,23614,23615,23616,23617,23618,23619,23620,23621,23622,23623,\n23624,23625,23626,23627,23628,23629,23630,23631,23632,23633,23634,23635,\n23636,23637,23638,23639,23640,23641,23642,23643,23644,23645,23646,23647,\n23648,23649,23650,23651,23652,23653,23654,23655,23656,23657,23658,23659,\n23660,23661,23662,23663,23664,23665,23666,23667,23668,23669,23670,23671,\n23672,23673,23674,23675,23676,23677,23678,23679,23680,23681,23682,23683,\n23684,23685,23686,23687,23688,23689,23690,23691,23692,23693,23694,23695,\n23696,23697,23698,23699,23700,23701,23702,23703,23704,23705,23706,23707,\n23708,23709,23710,23711,23712,23713,23714,23715,23716,23717,23718,23719,\n23720,23721,23722,23723,23724,23725,23726,23727,23728,23729,23730,23731,\n23732,23733,23734,23735,23736,23737,23738,23739,23740,23741,23742,23743,\n23744,23745,23746,23747,23748,23749,23750,23751,23752,23753,23754,23755,\n23756,23757,23758,23759,23760,23761,23762,23763,23764,23765,23766,23767,\n23768,23769,23770,23771,23772,23773,23774,23775,23776,23777,23778,23779,\n23780,23781,23782,23783,23784,23785,23786,23787,23788,23789,23790,23791,\n23792,23793,23794,23795,23796,23797,23798,23799,23800,23801,23802,23803,\n23804,23805,23806,23807,23808,23809,23810,23811,23812,23813,23814,23815,\n23816,23817,23818,23819,23820,23821,23822,23823,23824,23825,23826,23827,\n23828,23829,23830,23831,23832,23833,23834,23835,23836,23837,23838,23839,\n23840,23841,23842,23843,23844,23845,23846,23847,23848,23849,23850,23851,\n23852,23853,23854,23855,23856,23857,23858,23859,23860,23861,23862,23863,\n23864,23865,23866,23867,23868,23869,23870,23871,23872,23873,23874,23875,\n23876,23877,23878,23879,23880,23881,23882,23883,23884,23885,23886,23887,\n23888,23889,23890,23891,23892,23893,23894,23895,23896,23897,23898,23899,\n23900,23901,23902,23903,23904,23905,23906,23907,23908,23909,23910,23911,\n23912,23913,23914,23915,23916,23917,23918,23919,23920,23921,23922,23923,\n23924,23925,23926,23927,23928,23929,23930,23931,23932,23933,23934,23935,\n23936,23937,23938,23939,23940,23941,23942,23943,23944,23945,23946,23947,\n23948,23949,23950,23951,23952,23953,23954,23955,23956,23957,23958,23959,\n23960,23961,23962,23963,23964,23965,23966,23967,23968,23969,23970,23971,\n23972,23973,23974,23975,23976,23977,23978,23979,23980,23981,23982,23983,\n23984,23985,23986,23987,23988,23989,23990,23991,23992,23993,23994,23995,\n23996,23997,23998,23999,24000,24001,24002,24003,24004,24005,24006,24007,\n24008,24009,24010,24011,24012,24013,24014,24015,24016,24017,24018,24019,\n24020,24021,24022,24023,24024,24025,24026,24027,24028,24029,24030,24031,\n24032,24033,24034,24035,24036,24037,24038,24039,24040,24041,24042,24043,\n24044,24045,24046,24047,24048,24049,24050,24051,24052,24053,24054,24055,\n24056,24057,24058,24059,24060,24061,24062,24063,24064,24065,24066,24067,\n24068,24069,24070,24071,24072,24073,24074,24075,24076,24077,24078,24079,\n24080,24081,24082,24083,24084,24085,24086,24087,24088,24089,24090,24091,\n24092,24093,24094,24095,24096,24097,24098,24099,24100,24101,24102,24103,\n24104,24105,24106,24107,24108,24109,24110,24111,24112,24113,24114,24115,\n24116,24117,24118,24119,24120,24121,24122,24123,24124,24125,24126,24127,\n24128,24129,24130,24131,24132,24133,24134,24135,24136,24137,24138,24139,\n24140,24141,24142,24143,24144,24145,24146,24147,24148,24149,24150,24151,\n24152,24153,24154,24155,24156,24157,24158,24159,24160,24161,24162,24163,\n24164,24165,24166,24167,24168,24169,24170,24171,24172,24173,24174,24175,\n24176,24177,24178,24179,24180,24181,24182,24183,24184,24185,24186,24187,\n24188,24189,24190,24191,24192,24193,24194,24195,24196,24197,24198,24199,\n24200,24201,24202,24203,24204,24205,24206,24207,24208,24209,24210,24211,\n24212,24213,24214,24215,24216,24217,24218,24219,24220,24221,24222,24223,\n24224,24225,24226,24227,24228,24229,24230,24231,24232,24233,24234,24235,\n24236,24237,24238,24239,24240,24241,24242,24243,24244,24245,24246,24247,\n24248,24249,24250,24251,24252,24253,24254,24255,24256,24257,24258,24259,\n24260,24261,24262,24263,24264,24265,24266,24267,24268,24269,24270,24271,\n24272,24273,24274,24275,24276,24277,24278,24279,24280,24281,24282,24283,\n24284,24285,24286,24287,24288,24289,24290,24291,24292,24293,24294,24295,\n24296,24297,24298,24299,24300,24301,24302,24303,24304,24305,24306,24307,\n24308,24309,24310,24311,24312,24313,24314,24315,24316,24317,24318,24319,\n24320,24321,24322,24323,24324,24325,24326,24327,24328,24329,24330,24331,\n24332,24333,24334,24335,24336,24337,24338,24339,24340,24341,24342,24343,\n24344,24345,24346,24347,24348,24349,24350,24351,24352,24353,24354,24355,\n24356,24357,24358,24359,24360,24361,24362,24363,24364,24365,24366,24367,\n24368,24369,24370,24371,24372,24373,24374,24375,24376,24377,24378,24379,\n24380,24381,24382,24383,24384,24385,24386,24387,24388,24389,24390,24391,\n24392,24393,24394,24395,24396,24397,24398,24399,24400,24401,24402,24403,\n24404,24405,24406,24407,24408,24409,24410,24411,24412,24413,24414,24415,\n24416,24417,24418,24419,24420,24421,24422,24423,24424,24425,24426,24427,\n24428,24429,24430,24431,24432,24433,24434,24435,24436,24437,24438,24439,\n24440,24441,24442,24443,24444,24445,24446,24447,24448,24449,24450,24451,\n24452,24453,24454,24455,24456,24457,24458,24459,24460,24461,24462,24463,\n24464,24465,24466,24467,24468,24469,24470,24471,24472,24473,24474,24475,\n24476,24477,24478,24479,24480,24481,24482,24483,24484,24485,24486,24487,\n24488,24489,24490,24491,24492,24493,24494,24495,24496,24497,24498,24499,\n24500,24501,24502,24503,24504,24505,24506,24507,24508,24509,24510,24511,\n24512,24513,24514,24515,24516,24517,24518,24519,24520,24521,24522,24523,\n24524,24525,24526,24527,24528,24529,24530,24531,24532,24533,24534,24535,\n24536,24537,24538,24539,24540,24541,24542,24543,24544,24545,24546,24547,\n24548,24549,24550,24551,24552,24553,24554,24555,24556,24557,24558,24559,\n24560,24561,24562,24563,24564,24565,24566,24567,24568,24569,24570,24571,\n24572,24573,24574,24575,24576,24577,24578,24579,24580,24581,24582,24583,\n24584,24585,24586,24587,24588,24589,24590,24591,24592,24593,24594,24595,\n24596,24597,24598,24599,24600,24601,24602,24603,24604,24605,24606,24607,\n24608,24609,24610,24611,24612,24613,24614,24615,24616,24617,24618,24619,\n24620,24621,24622,24623,24624,24625,24626,24627,24628,24629,24630,24631,\n24632,24633,24634,24635,24636,24637,24638,24639,24640,24641,24642,24643,\n24644,24645,24646,24647,24648,24649,24650,24651,24652,24653,24654,24655,\n24656,24657,24658,24659,24660,24661,24662,24663,24664,24665,24666,24667,\n24668,24669,24670,24671,24672,24673,24674,24675,24676,24677,24678,24679,\n24680,24681,24682,24683,24684,24685,24686,24687,24688,24689,24690,24691,\n24692,24693,24694,24695,24696,24697,24698,24699,24700,24701,24702,24703,\n24704,24705,24706,24707,24708,24709,24710,24711,24712,24713,24714,24715,\n24716,24717,24718,24719,24720,24721,24722,24723,24724,24725,24726,24727,\n24728,24729,24730,24731,24732,24733,24734,24735,24736,24737,24738,24739,\n24740,24741,24742,24743,24744,24745,24746,24747,24748,24749,24750,24751,\n24752,24753,24754,24755,24756,24757,24758,24759,24760,24761,24762,24763,\n24764,24765,24766,24767,24768,24769,24770,24771,24772,24773,24774,24775,\n24776,24777,24778,24779,24780,24781,24782,24783,24784,24785,24786,24787,\n24788,24789,24790,24791,24792,24793,24794,24795,24796,24797,24798,24799,\n24800,24801,24802,24803,24804,24805,24806,24807,24808,24809,24810,24811,\n24812,24813,24814,24815,24816,24817,24818,24819,24820,24821,24822,24823,\n24824,24825,24826,24827,24828,24829,24830,24831,24832,24833,24834,24835,\n24836,24837,24838,24839,24840,24841,24842,24843,24844,24845,24846,24847,\n24848,24849,24850,24851,24852,24853,24854,24855,24856,24857,24858,24859,\n24860,24861,24862,24863,24864,24865,24866,24867,24868,24869,24870,24871,\n24872,24873,24874,24875,24876,24877,24878,24879,24880,24881,24882,24883,\n24884,24885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24895,\n24896,24897,24898,24899,24900,24901,24902,24903,24904,24905,24906,24907,\n24908,24909,24910,24911,24912,24913,24914,24915,24916,24917,24918,24919,\n24920,24921,24922,24923,24924,24925,24926,24927,24928,24929,24930,24931,\n24932,24933,24934,24935,24936,24937,24938,24939,24940,24941,24942,24943,\n24944,24945,24946,24947,24948,24949,24950,24951,24952,24953,24954,24955,\n24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,24967,\n24968,24969,24970,24971,24972,24973,24974,24975,24976,24977,24978,24979,\n24980,24981,24982,24983,24984,24985,24986,24987,24988,24989,24990,24991,\n24992,24993,24994,24995,24996,24997,24998,24999,25000,25001,25002,25003,\n25004,25005,25006,25007,25008,25009,25010,25011,25012,25013,25014,25015,\n25016,25017,25018,25019,25020,25021,25022,25023,25024,25025,25026,25027,\n25028,25029,25030,25031,25032,25033,25034,25035,25036,25037,25038,25039,\n25040,25041,25042,25043,25044,25045,25046,25047,25048,25049,25050,25051,\n25052,25053,25054,25055,25056,25057,25058,25059,25060,25061,25062,25063,\n25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074,25075,\n25076,25077,25078,25079,25080,25081,25082,25083,25084,25085,25086,25087,\n25088,25089,25090,25091,25092,25093,25094,25095,25096,25097,25098,25099,\n25100,25101,25102,25103,25104,25105,25106,25107,25108,25109,25110,25111,\n25112,25113,25114,25115,25116,25117,25118,25119,25120,25121,25122,25123,\n25124,25125,25126,25127,25128,25129,25130,25131,25132,25133,25134,25135,\n25136,25137,25138,25139,25140,25141,25142,25143,25144,25145,25146,25147,\n25148,25149,25150,25151,25152,25153,25154,25155,25156,25157,25158,25159,\n25160,25161,25162,25163,25164,25165,25166,25167,25168,25169,25170,25171,\n25172,25173,25174,25175,25176,25177,25178,25179,25180,25181,25182,25183,\n25184,25185,25186,25187,25188,25189,25190,25191,25192,25193,25194,25195,\n25196,25197,25198,25199,25200,25201,25202,25203,25204,25205,25206,25207,\n25208,25209,25210,25211,25212,25213,25214,25215,25216,25217,25218,25219,\n25220,25221,25222,25223,25224,25225,25226,25227,25228,25229,25230,25231,\n25232,25233,25234,25235,25236,25237,25238,25239,25240,25241,25242,25243,\n25244,25245,25246,25247,25248,25249,25250,25251,25252,25253,25254,25255,\n25256,25257,25258,25259,25260,25261,25262,25263,25264,25265,25266,25267,\n25268,25269,25270,25271,25272,25273,25274,25275,25276,25277,25278,25279,\n25280,25281,25282,25283,25284,25285,25286,25287,25288,25289,25290,25291,\n25292,25293,25294,25295,25296,25297,25298,25299,25300,25301,25302,25303,\n25304,25305,25306,25307,25308,25309,25310,25311,25312,25313,25314,25315,\n25316,25317,25318,25319,25320,25321,25322,25323,25324,25325,25326,25327,\n25328,25329,25330,25331,25332,25333,25334,25335,25336,25337,25338,25339,\n25340,25341,25342,25343,25344,25345,25346,25347,25348,25349,25350,25351,\n25352,25353,25354,25355,25356,25357,25358,25359,25360,25361,25362,25363,\n25364,25365,25366,25367,25368,25369,25370,25371,25372,25373,25374,25375,\n25376,25377,25378,25379,25380,25381,25382,25383,25384,25385,25386,25387,\n25388,25389,25390,25391,25392,25393,25394,25395,25396,25397,25398,25399,\n25400,25401,25402,25403,25404,25405,25406,25407,25408,25409,25410,25411,\n25412,25413,25414,25415,25416,25417,25418,25419,25420,25421,25422,25423,\n25424,25425,25426,25427,25428,25429,25430,25431,25432,25433,25434,25435,\n25436,25437,25438,25439,25440,25441,25442,25443,25444,25445,25446,25447,\n25448,25449,25450,25451,25452,25453,25454,25455,25456,25457,25458,25459,\n25460,25461,25462,25463,25464,25465,25466,25467,25468,25469,25470,25471,\n25472,25473,25474,25475,25476,25477,25478,25479,25480,25481,25482,25483,\n25484,25485,25486,25487,25488,25489,25490,25491,25492,25493,25494,25495,\n25496,25497,25498,25499,25500,25501,25502,25503,25504,25505,25506,25507,\n25508,25509,25510,25511,25512,25513,25514,25515,25516,25517,25518,25519,\n25520,25521,25522,25523,25524,25525,25526,25527,25528,25529,25530,25531,\n25532,25533,25534,25535,25536,25537,25538,25539,25540,25541,25542,25543,\n25544,25545,25546,25547,25548,25549,25550,25551,25552,25553,25554,25555,\n25556,25557,25558,25559,25560,25561,25562,25563,25564,25565,25566,25567,\n25568,25569,25570,25571,25572,25573,25574,25575,25576,25577,25578,25579,\n25580,25581,25582,25583,25584,25585,25586,25587,25588,25589,25590,25591,\n25592,25593,25594,25595,25596,25597,25598,25599,25600,25601,25602,25603,\n25604,25605,25606,25607,25608,25609,25610,25611,25612,25613,25614,25615,\n25616,25617,25618,25619,25620,25621,25622,25623,25624,25625,25626,25627,\n25628,25629,25630,25631,25632,25633,25634,25635,25636,25637,25638,25639,\n25640,25641,25642,25643,25644,25645,25646,25647,25648,25649,25650,25651,\n25652,25653,25654,25655,25656,25657,25658,25659,25660,25661,25662,25663,\n25664,25665,25666,25667,25668,25669,25670,25671,25672,25673,25674,25675,\n25676,25677,25678,25679,25680,25681,25682,25683,25684,25685,25686,25687,\n25688,25689,25690,25691,25692,25693,25694,25695,25696,25697,25698,25699,\n25700,25701,25702,25703,25704,25705,25706,25707,25708,25709,25710,25711,\n25712,25713,25714,25715,25716,25717,25718,25719,25720,25721,25722,25723,\n25724,25725,25726,25727,25728,25729,25730,25731,25732,25733,25734,25735,\n25736,25737,25738,25739,25740,25741,25742,25743,25744,25745,25746,25747,\n25748,25749,25750,25751,25752,25753,25754,25755,25756,25757,25758,25759,\n25760,25761,25762,25763,25764,25765,25766,25767,25768,25769,25770,25771,\n25772,25773,25774,25775,25776,25777,25778,25779,25780,25781,25782,25783,\n25784,25785,25786,25787,25788,25789,25790,25791,25792,25793,25794,25795,\n25796,25797,25798,25799,25800,25801,25802,25803,25804,25805,25806,25807,\n25808,25809,25810,25811,25812,25813,25814,25815,25816,25817,25818,25819,\n25820,25821,25822,25823,25824,25825,25826,25827,25828,25829,25830,25831,\n25832,25833,25834,25835,25836,25837,25838,25839,25840,25841,25842,25843,\n25844,25845,25846,25847,25848,25849,25850,25851,25852,25853,25854,25855,\n25856,25857,25858,25859,25860,25861,25862,25863,25864,25865,25866,25867,\n25868,25869,25870,25871,25872,25873,25874,25875,25876,25877,25878,25879,\n25880,25881,25882,25883,25884,25885,25886,25887,25888,25889,25890,25891,\n25892,25893,25894,25895,25896,25897,25898,25899,25900,25901,25902,25903,\n25904,25905,25906,25907,25908,25909,25910,25911,25912,25913,25914,25915,\n25916,25917,25918,25919,25920,25921,25922,25923,25924,25925,25926,25927,\n25928,25929,25930,25931,25932,25933,25934,25935,25936,25937,25938,25939,\n25940,25941,25942,25943,25944,25945,25946,25947,25948,25949,25950,25951,\n25952,25953,25954,25955,25956,25957,25958,25959,25960,25961,25962,25963,\n25964,25965,25966,25967,25968,25969,25970,25971,25972,25973,25974,25975,\n25976,25977,25978,25979,25980,25981,25982,25983,25984,25985,25986,25987,\n25988,25989,25990,25991,25992,25993,25994,25995,25996,25997,25998,25999,\n26000,26001,26002,26003,26004,26005,26006,26007,26008,26009,26010,26011,\n26012,26013,26014,26015,26016,26017,26018,26019,26020,26021,26022,26023,\n26024,26025,26026,26027,26028,26029,26030,26031,26032,26033,26034,26035,\n26036,26037,26038,26039,26040,26041,26042,26043,26044,26045,26046,26047,\n26048,26049,26050,26051,26052,26053,26054,26055,26056,26057,26058,26059,\n26060,26061,26062,26063,26064,26065,26066,26067,26068,26069,26070,26071,\n26072,26073,26074,26075,26076,26077,26078,26079,26080,26081,26082,26083,\n26084,26085,26086,26087,26088,26089,26090,26091,26092,26093,26094,26095,\n26096,26097,26098,26099,26100,26101,26102,26103,26104,26105,26106,26107,\n26108,26109,26110,26111,26112,26113,26114,26115,26116,26117,26118,26119,\n26120,26121,26122,26123,26124,26125,26126,26127,26128,26129,26130,26131,\n26132,26133,26134,26135,26136,26137,26138,26139,26140,26141,26142,26143,\n26144,26145,26146,26147,26148,26149,26150,26151,26152,26153,26154,26155,\n26156,26157,26158,26159,26160,26161,26162,26163,26164,26165,26166,26167,\n26168,26169,26170,26171,26172,26173,26174,26175,26176,26177,26178,26179,\n26180,26181,26182,26183,26184,26185,26186,26187,26188,26189,26190,26191,\n26192,26193,26194,26195,26196,26197,26198,26199,26200,26201,26202,26203,\n26204,26205,26206,26207,26208,26209,26210,26211,26212,26213,26214,26215,\n26216,26217,26218,26219,26220,26221,26222,26223,26224,26225,26226,26227,\n26228,26229,26230,26231,26232,26233,26234,26235,26236,26237,26238,26239,\n26240,26241,26242,26243,26244,26245,26246,26247,26248,26249,26250,26251,\n26252,26253,26254,26255,26256,26257,26258,26259,26260,26261,26262,26263,\n26264,26265,26266,26267,26268,26269,26270,26271,26272,26273,26274,26275,\n26276,26277,26278,26279,26280,26281,26282,26283,26284,26285,26286,26287,\n26288,26289,26290,26291,26292,26293,26294,26295,26296,26297,26298,26299,\n26300,26301,26302,26303,26304,26305,26306,26307,26308,26309,26310,26311,\n26312,26313,26314,26315,26316,26317,26318,26319,26320,26321,26322,26323,\n26324,26325,26326,26327,26328,26329,26330,26331,26332,26333,26334,26335,\n26336,26337,26338,26339,26340,26341,26342,26343,26344,26345,26346,26347,\n26348,26349,26350,26351,26352,26353,26354,26355,26356,26357,26358,26359,\n26360,26361,26362,26363,26364,26365,26366,26367,26368,26369,26370,26371,\n26372,26373,26374,26375,26376,26377,26378,26379,26380,26381,26382,26383,\n26384,26385,26386,26387,26388,26389,26390,26391,26392,26393,26394,26395,\n26396,26397,26398,26399,26400,26401,26402,26403,26404,26405,26406,26407,\n26408,26409,26410,26411,26412,26413,26414,26415,26416,26417,26418,26419,\n26420,26421,26422,26423,26424,26425,26426,26427,26428,26429,26430,26431,\n26432,26433,26434,26435,26436,26437,26438,26439,26440,26441,26442,26443,\n26444,26445,26446,26447,26448,26449,26450,26451,26452,26453,26454,26455,\n26456,26457,26458,26459,26460,26461,26462,26463,26464,26465,26466,26467,\n26468,26469,26470,26471,26472,26473,26474,26475,26476,26477,26478,26479,\n26480,26481,26482,26483,26484,26485,26486,26487,26488,26489,26490,26491,\n26492,26493,26494,26495,26496,26497,26498,26499,26500,26501,26502,26503,\n26504,26505,26506,26507,26508,26509,26510,26511,26512,26513,26514,26515,\n26516,26517,26518,26519,26520,26521,26522,26523,26524,26525,26526,26527,\n26528,26529,26530,26531,26532,26533,26534,26535,26536,26537,26538,26539,\n26540,26541,26542,26543,26544,26545,26546,26547,26548,26549,26550,26551,\n26552,26553,26554,26555,26556,26557,26558,26559,26560,26561,26562,26563,\n26564,26565,26566,26567,26568,26569,26570,26571,26572,26573,26574,26575,\n26576,26577,26578,26579,26580,26581,26582,26583,26584,26585,26586,26587,\n26588,26589,26590,26591,26592,26593,26594,26595,26596,26597,26598,26599,\n26600,26601,26602,26603,26604,26605,26606,26607,26608,26609,26610,26611,\n26612,26613,26614,26615,26616,26617,26618,26619,26620,26621,26622,26623,\n26624,26625,26626,26627,26628,26629,26630,26631,26632,26633,26634,26635,\n26636,26637,26638,26639,26640,26641,26642,26643,26644,26645,26646,26647,\n26648,26649,26650,26651,26652,26653,26654,26655,26656,26657,26658,26659,\n26660,26661,26662,26663,26664,26665,26666,26667,26668,26669,26670,26671,\n26672,26673,26674,26675,26676,26677,26678,26679,26680,26681,26682,26683,\n26684,26685,26686,26687,26688,26689,26690,26691,26692,26693,26694,26695,\n26696,26697,26698,26699,26700,26701,26702,26703,26704,26705,26706,26707,\n26708,26709,26710,26711,26712,26713,26714,26715,26716,26717,26718,26719,\n26720,26721,26722,26723,26724,26725,26726,26727,26728,26729,26730,26731,\n26732,26733,26734,26735,26736,26737,26738,26739,26740,26741,26742,26743,\n26744,26745,26746,26747,26748,26749,26750,26751,26752,26753,26754,26755,\n26756,26757,26758,26759,26760,26761,26762,26763,26764,26765,26766,26767,\n26768,26769,26770,26771,26772,26773,26774,26775,26776,26777,26778,26779,\n26780,26781,26782,26783,26784,26785,26786,26787,26788,26789,26790,26791,\n26792,26793,26794,26795,26796,26797,26798,26799,26800,26801,26802,26803,\n26804,26805,26806,26807,26808,26809,26810,26811,26812,26813,26814,26815,\n26816,26817,26818,26819,26820,26821,26822,26823,26824,26825,26826,26827,\n26828,26829,26830,26831,26832,26833,26834,26835,26836,26837,26838,26839,\n26840,26841,26842,26843,26844,26845,26846,26847,26848,26849,26850,26851,\n26852,26853,26854,26855,26856,26857,26858,26859,26860,26861,26862,26863,\n26864,26865,26866,26867,26868,26869,26870,26871,26872,26873,26874,26875,\n26876,26877,26878,26879,26880,26881,26882,26883,26884,26885,26886,26887,\n26888,26889,26890,26891,26892,26893,26894,26895,26896,26897,26898,26899,\n26900,26901,26902,26903,26904,26905,26906,26907,26908,26909,26910,26911,\n26912,26913,26914,26915,26916,26917,26918,26919,26920,26921,26922,26923,\n26924,26925,26926,26927,26928,26929,26930,26931,26932,26933,26934,26935,\n26936,26937,26938,26939,26940,26941,26942,26943,26944,26945,26946,26947,\n26948,26949,26950,26951,26952,26953,26954,26955,26956,26957,26958,26959,\n26960,26961,26962,26963,26964,26965,26966,26967,26968,26969,26970,26971,\n26972,26973,26974,26975,26976,26977,26978,26979,26980,26981,26982,26983,\n26984,26985,26986,26987,26988,26989,26990,26991,26992,26993,26994,26995,\n26996,26997,26998,26999,27000,27001,27002,27003,27004,27005,27006,27007,\n27008,27009,27010,27011,27012,27013,27014,27015,27016,27017,27018,27019,\n27020,27021,27022,27023,27024,27025,27026,27027,27028,27029,27030,27031,\n27032,27033,27034,27035,27036,27037,27038,27039,27040,27041,27042,27043,\n27044,27045,27046,27047,27048,27049,27050,27051,27052,27053,27054,27055,\n27056,27057,27058,27059,27060,27061,27062,27063,27064,27065,27066,27067,\n27068,27069,27070,27071,27072,27073,27074,27075,27076,27077,27078,27079,\n27080,27081,27082,27083,27084,27085,27086,27087,27088,27089,27090,27091,\n27092,27093,27094,27095,27096,27097,27098,27099,27100,27101,27102,27103,\n27104,27105,27106,27107,27108,27109,27110,27111,27112,27113,27114,27115,\n27116,27117,27118,27119,27120,27121,27122,27123,27124,27125,27126,27127,\n27128,27129,27130,27131,27132,27133,27134,27135,27136,27137,27138,27139,\n27140,27141,27142,27143,27144,27145,27146,27147,27148,27149,27150,27151,\n27152,27153,27154,27155,27156,27157,27158,27159,27160,27161,27162,27163,\n27164,27165,27166,27167,27168,27169,27170,27171,27172,27173,27174,27175,\n27176,27177,27178,27179,27180,27181,27182,27183,27184,27185,27186,27187,\n27188,27189,27190,27191,27192,27193,27194,27195,27196,27197,27198,27199,\n27200,27201,27202,27203,27204,27205,27206,27207,27208,27209,27210,27211,\n27212,27213,27214,27215,27216,27217,27218,27219,27220,27221,27222,27223,\n27224,27225,27226,27227,27228,27229,27230,27231,27232,27233,27234,27235,\n27236,27237,27238,27239,27240,27241,27242,27243,27244,27245,27246,27247,\n27248,27249,27250,27251,27252,27253,27254,27255,27256,27257,27258,27259,\n27260,27261,27262,27263,27264,27265,27266,27267,27268,27269,27270,27271,\n27272,27273,27274,27275,27276,27277,27278,27279,27280,27281,27282,27283,\n27284,27285,27286,27287,27288,27289,27290,27291,27292,27293,27294,27295,\n27296,27297,27298,27299,27300,27301,27302,27303,27304,27305,27306,27307,\n27308,27309,27310,27311,27312,27313,27314,27315,27316,27317,27318,27319,\n27320,27321,27322,27323,27324,27325,27326,27327,27328,27329,27330,27331,\n27332,27333,27334,27335,27336,27337,27338,27339,27340,27341,27342,27343,\n27344,27345,27346,27347,27348,27349,27350,27351,27352,27353,27354,27355,\n27356,27357,27358,27359,27360,27361,27362,27363,27364,27365,27366,27367,\n27368,27369,27370,27371,27372,27373,27374,27375,27376,27377,27378,27379,\n27380,27381,27382,27383,27384,27385,27386,27387,27388,27389,27390,27391,\n27392,27393,27394,27395,27396,27397,27398,27399,27400,27401,27402,27403,\n27404,27405,27406,27407,27408,27409,27410,27411,27412,27413,27414,27415,\n27416,27417,27418,27419,27420,27421,27422,27423,27424,27425,27426,27427,\n27428,27429,27430,27431,27432,27433,27434,27435,27436,27437,27438,27439,\n27440,27441,27442,27443,27444,27445,27446,27447,27448,27449,27450,27451,\n27452,27453,27454,27455,27456,27457,27458,27459,27460,27461,27462,27463,\n27464,27465,27466,27467,27468,27469,27470,27471,27472,27473,27474,27475,\n27476,27477,27478,27479,27480,27481,27482,27483,27484,27485,27486,27487,\n27488,27489,27490,27491,27492,27493,27494,27495,27496,27497,27498,27499,\n27500,27501,27502,27503,27504,27505,27506,27507,27508,27509,27510,27511,\n27512,27513,27514,27515,27516,27517,27518,27519,27520,27521,27522,27523,\n27524,27525,27526,27527,27528,27529,27530,27531,27532,27533,27534,27535,\n27536,27537,27538,27539,27540,27541,27542,27543,27544,27545,27546,27547,\n27548,27549,27550,27551,27552,27553,27554,27555,27556,27557,27558,27559,\n27560,27561,27562,27563,27564,27565,27566,27567,27568,27569,27570,27571,\n27572,27573,27574,27575,27576,27577,27578,27579,27580,27581,27582,27583,\n27584,27585,27586,27587,27588,27589,27590,27591,27592,27593,27594,27595,\n27596,27597,27598,27599,27600,27601,27602,27603,27604,27605,27606,27607,\n27608,27609,27610,27611,27612,27613,27614,27615,27616,27617,27618,27619,\n27620,27621,27622,27623,27624,27625,27626,27627,27628,27629,27630,27631,\n27632,27633,27634,27635,27636,27637,27638,27639,27640,27641,27642,27643,\n27644,27645,27646,27647,27648,27649,27650,27651,27652,27653,27654,27655,\n27656,27657,27658,27659,27660,27661,27662,27663,27664,27665,27666,27667,\n27668,27669,27670,27671,27672,27673,27674,27675,27676,27677,27678,27679,\n27680,27681,27682,27683,27684,27685,27686,27687,27688,27689,27690,27691,\n27692,27693,27694,27695,27696,27697,27698,27699,27700,27701,27702,27703,\n27704,27705,27706,27707,27708,27709,27710,27711,27712,27713,27714,27715,\n27716,27717,27718,27719,27720,27721,27722,27723,27724,27725,27726,27727,\n27728,27729,27730,27731,27732,27733,27734,27735,27736,27737,27738,27739,\n27740,27741,27742,27743,27744,27745,27746,27747,27748,27749,27750,27751,\n27752,27753,27754,27755,27756,27757,27758,27759,27760,27761,27762,27763,\n27764,27765,27766,27767,27768,27769,27770,27771,27772,27773,27774,27775,\n27776,27777,27778,27779,27780,27781,27782,27783,27784,27785,27786,27787,\n27788,27789,27790,27791,27792,27793,27794,27795,27796,27797,27798,27799,\n27800,27801,27802,27803,27804,27805,27806,27807,27808,27809,27810,27811,\n27812,27813,27814,27815,27816,27817,27818,27819,27820,27821,27822,27823,\n27824,27825,27826,27827,27828,27829,27830,27831,27832,27833,27834,27835,\n27836,27837,27838,27839,27840,27841,27842,27843,27844,27845,27846,27847,\n27848,27849,27850,27851,27852,27853,27854,27855,27856,27857,27858,27859,\n27860,27861,27862,27863,27864,27865,27866,27867,27868,27869,27870,27871,\n27872,27873,27874,27875,27876,27877,27878,27879,27880,27881,27882,27883,\n27884,27885,27886,27887,27888,27889,27890,27891,27892,27893,27894,27895,\n27896,27897,27898,27899,27900,27901,27902,27903,27904,27905,27906,27907,\n27908,27909,27910,27911,27912,27913,27914,27915,27916,27917,27918,27919,\n27920,27921,27922,27923,27924,27925,27926,27927,27928,27929,27930,27931,\n27932,27933,27934,27935,27936,27937,27938,27939,27940,27941,27942,27943,\n27944,27945,27946,27947,27948,27949,27950,27951,27952,27953,27954,27955,\n27956,27957,27958,27959,27960,27961,27962,27963,27964,27965,27966,27967,\n27968,27969,27970,27971,27972,27973,27974,27975,27976,27977,27978,27979,\n27980,27981,27982,27983,27984,27985,27986,27987,27988,27989,27990,27991,\n27992,27993,27994,27995,27996,27997,27998,27999,28000,28001,28002,28003,\n28004,28005,28006,28007,28008,28009,28010,28011,28012,28013,28014,28015,\n28016,28017,28018,28019,28020,28021,28022,28023,28024,28025,28026,28027,\n28028,28029,28030,28031,28032,28033,28034,28035,28036,28037,28038,28039,\n28040,28041,28042,28043,28044,28045,28046,28047,28048,28049,28050,28051,\n28052,28053,28054,28055,28056,28057,28058,28059,28060,28061,28062,28063,\n28064,28065,28066,28067,28068,28069,28070,28071,28072,28073,28074,28075,\n28076,28077,28078,28079,28080,28081,28082,28083,28084,28085,28086,28087,\n28088,28089,28090,28091,28092,28093,28094,28095,28096,28097,28098,28099,\n28100,28101,28102,28103,28104,28105,28106,28107,28108,28109,28110,28111,\n28112,28113,28114,28115,28116,28117,28118,28119,28120,28121,28122,28123,\n28124,28125,28126,28127,28128,28129,28130,28131,28132,28133,28134,28135,\n28136,28137,28138,28139,28140,28141,28142,28143,28144,28145,28146,28147,\n28148,28149,28150,28151,28152,28153,28154,28155,28156,28157,28158,28159,\n28160,28161,28162,28163,28164,28165,28166,28167,28168,28169,28170,28171,\n28172,28173,28174,28175,28176,28177,28178,28179,28180,28181,28182,28183,\n28184,28185,28186,28187,28188,28189,28190,28191,28192,28193,28194,28195,\n28196,28197,28198,28199,28200,28201,28202,28203,28204,28205,28206,28207,\n28208,28209,28210,28211,28212,28213,28214,28215,28216,28217,28218,28219,\n28220,28221,28222,28223,28224,28225,28226,28227,28228,28229,28230,28231,\n28232,28233,28234,28235,28236,28237,28238,28239,28240,28241,28242,28243,\n28244,28245,28246,28247,28248,28249,28250,28251,28252,28253,28254,28255,\n28256,28257,28258,28259,28260,28261,28262,28263,28264,28265,28266,28267,\n28268,28269,28270,28271,28272,28273,28274,28275,28276,28277,28278,28279,\n28280,28281,28282,28283,28284,28285,28286,28287,28288,28289,28290,28291,\n28292,28293,28294,28295,28296,28297,28298,28299,28300,28301,28302,28303,\n28304,28305,28306,28307,28308,28309,28310,28311,28312,28313,28314,28315,\n28316,28317,28318,28319,28320,28321,28322,28323,28324,28325,28326,28327,\n28328,28329,28330,28331,28332,28333,28334,28335,28336,28337,28338,28339,\n28340,28341,28342,28343,28344,28345,28346,28347,28348,28349,28350,28351,\n28352,28353,28354,28355,28356,28357,28358,28359,28360,28361,28362,28363,\n28364,28365,28366,28367,28368,28369,28370,28371,28372,28373,28374,28375,\n28376,28377,28378,28379,28380,28381,28382,28383,28384,28385,28386,28387,\n28388,28389,28390,28391,28392,28393,28394,28395,28396,28397,28398,28399,\n28400,28401,28402,28403,28404,28405,28406,28407,28408,28409,28410,28411,\n28412,28413,28414,28415,28416,28417,28418,28419,28420,28421,28422,28423,\n28424,28425,28426,28427,28428,28429,28430,28431,28432,28433,28434,28435,\n28436,28437,28438,28439,28440,28441,28442,28443,28444,28445,28446,28447,\n28448,28449,28450,28451,28452,28453,28454,28455,28456,28457,28458,28459,\n28460,28461,28462,28463,28464,28465,28466,28467,28468,28469,28470,28471,\n28472,28473,28474,28475,28476,28477,28478,28479,28480,28481,28482,28483,\n28484,28485,28486,28487,28488,28489,28490,28491,28492,28493,28494,28495,\n28496,28497,28498,28499,28500,28501,28502,28503,28504,28505,28506,28507,\n28508,28509,28510,28511,28512,28513,28514,28515,28516,28517,28518,28519,\n28520,28521,28522,28523,28524,28525,28526,28527,28528,28529,28530,28531,\n28532,28533,28534,28535,28536,28537,28538,28539,28540,28541,28542,28543,\n28544,28545,28546,28547,28548,28549,28550,28551,28552,28553,28554,28555,\n28556,28557,28558,28559,28560,28561,28562,28563,28564,28565,28566,28567,\n28568,28569,28570,28571,28572,28573,28574,28575,28576,28577,28578,28579,\n28580,28581,28582,28583,28584,28585,28586,28587,28588,28589,28590,28591,\n28592,28593,28594,28595,28596,28597,28598,28599,28600,28601,28602,28603,\n28604,28605,28606,28607,28608,28609,28610,28611,28612,28613,28614,28615,\n28616,28617,28618,28619,28620,28621,28622,28623,28624,28625,28626,28627,\n28628,28629,28630,28631,28632,28633,28634,28635,28636,28637,28638,28639,\n28640,28641,28642,28643,28644,28645,28646,28647,28648,28649,28650,28651,\n28652,28653,28654,28655,28656,28657,28658,28659,28660,28661,28662,28663,\n28664,28665,28666,28667,28668,28669,28670,28671,28672,28673,28674,28675,\n28676,28677,28678,28679,28680,28681,28682,28683,28684,28685,28686,28687,\n28688,28689,28690,28691,28692,28693,28694,28695,28696,28697,28698,28699,\n28700,28701,28702,28703,28704,28705,28706,28707,28708,28709,28710,28711,\n28712,28713,28714,28715,28716,28717,28718,28719,28720,28721,28722,28723,\n28724,28725,28726,28727,28728,28729,28730,28731,28732,28733,28734,28735,\n28736,28737,28738,28739,28740,28741,28742,28743,28744,28745,28746,28747,\n28748,28749,28750,28751,28752,28753,28754,28755,28756,28757,28758,28759,\n28760,28761,28762,28763,28764,28765,28766,28767,28768,28769,28770,28771,\n28772,28773,28774,28775,28776,28777,28778,28779,28780,28781,28782,28783,\n28784,28785,28786,28787,28788,28789,28790,28791,28792,28793,28794,28795,\n28796,28797,28798,28799,28800,28801,28802,28803,28804,28805,28806,28807,\n28808,28809,28810,28811,28812,28813,28814,28815,28816,28817,28818,28819,\n28820,28821,28822,28823,28824,28825,28826,28827,28828,28829,28830,28831,\n28832,28833,28834,28835,28836,28837,28838,28839,28840,28841,28842,28843,\n28844,28845,28846,28847,28848,28849,28850,28851,28852,28853,28854,28855,\n28856,28857,28858,28859,28860,28861,28862,28863,28864,28865,28866,28867,\n28868,28869,28870,28871,28872,28873,28874,28875,28876,28877,28878,28879,\n28880,28881,28882,28883,28884,28885,28886,28887,28888,28889,28890,28891,\n28892,28893,28894,28895,28896,28897,28898,28899,28900,28901,28902,28903,\n28904,28905,28906,28907,28908,28909,28910,28911,28912,28913,28914,28915,\n28916,28917,28918,28919,28920,28921,28922,28923,28924,28925,28926,28927,\n28928,28929,28930,28931,28932,28933,28934,28935,28936,28937,28938,28939,\n28940,28941,28942,28943,28944,28945,28946,28947,28948,28949,28950,28951,\n28952,28953,28954,28955,28956,28957,28958,28959,28960,28961,28962,28963,\n28964,28965,28966,28967,28968,28969,28970,28971,28972,28973,28974,28975,\n28976,28977,28978,28979,28980,28981,28982,28983,28984,28985,28986,28987,\n28988,28989,28990,28991,28992,28993,28994,28995,28996,28997,28998,28999,\n29000,29001,29002,29003,29004,29005,29006,29007,29008,29009,29010,29011,\n29012,29013,29014,29015,29016,29017,29018,29019,29020,29021,29022,29023,\n29024,29025,29026,29027,29028,29029,29030,29031,29032,29033,29034,29035,\n29036,29037,29038,29039,29040,29041,29042,29043,29044,29045,29046,29047,\n29048,29049,29050,29051,29052,29053,29054,29055,29056,29057,29058,29059,\n29060,29061,29062,29063,29064,29065,29066,29067,29068,29069,29070,29071,\n29072,29073,29074,29075,29076,29077,29078,29079,29080,29081,29082,29083,\n29084,29085,29086,29087,29088,29089,29090,29091,29092,29093,29094,29095,\n29096,29097,29098,29099,29100,29101,29102,29103,29104,29105,29106,29107,\n29108,29109,29110,29111,29112,29113,29114,29115,29116,29117,29118,29119,\n29120,29121,29122,29123,29124,29125,29126,29127,29128,29129,29130,29131,\n29132,29133,29134,29135,29136,29137,29138,29139,29140,29141,29142,29143,\n29144,29145,29146,29147,29148,29149,29150,29151,29152,29153,29154,29155,\n29156,29157,29158,29159,29160,29161,29162,29163,29164,29165,29166,29167,\n29168,29169,29170,29171,29172,29173,29174,29175,29176,29177,29178,29179,\n29180,29181,29182,29183,29184,29185,29186,29187,29188,29189,29190,29191,\n29192,29193,29194,29195,29196,29197,29198,29199,29200,29201,29202,29203,\n29204,29205,29206,29207,29208,29209,29210,29211,29212,29213,29214,29215,\n29216,29217,29218,29219,29220,29221,29222,29223,29224,29225,29226,29227,\n29228,29229,29230,29231,29232,29233,29234,29235,29236,29237,29238,29239,\n29240,29241,29242,29243,29244,29245,29246,29247,29248,29249,29250,29251,\n29252,29253,29254,29255,29256,29257,29258,29259,29260,29261,29262,29263,\n29264,29265,29266,29267,29268,29269,29270,29271,29272,29273,29274,29275,\n29276,29277,29278,29279,29280,29281,29282,29283,29284,29285,29286,29287,\n29288,29289,29290,29291,29292,29293,29294,29295,29296,29297,29298,29299,\n29300,29301,29302,29303,29304,29305,29306,29307,29308,29309,29310,29311,\n29312,29313,29314,29315,29316,29317,29318,29319,29320,29321,29322,29323,\n29324,29325,29326,29327,29328,29329,29330,29331,29332,29333,29334,29335,\n29336,29337,29338,29339,29340,29341,29342,29343,29344,29345,29346,29347,\n29348,29349,29350,29351,29352,29353,29354,29355,29356,29357,29358,29359,\n29360,29361,29362,29363,29364,29365,29366,29367,29368,29369,29370,29371,\n29372,29373,29374,29375,29376,29377,29378,29379,29380,29381,29382,29383,\n29384,29385,29386,29387,29388,29389,29390,29391,29392,29393,29394,29395,\n29396,29397,29398,29399,29400,29401,29402,29403,29404,29405,29406,29407,\n29408,29409,29410,29411,29412,29413,29414,29415,29416,29417,29418,29419,\n29420,29421,29422,29423,29424,29425,29426,29427,29428,29429,29430,29431,\n29432,29433,29434,29435,29436,29437,29438,29439,29440,29441,29442,29443,\n29444,29445,29446,29447,29448,29449,29450,29451,29452,29453,29454,29455,\n29456,29457,29458,29459,29460,29461,29462,29463,29464,29465,29466,29467,\n29468,29469,29470,29471,29472,29473,29474,29475,29476,29477,29478,29479,\n29480,29481,29482,29483,29484,29485,29486,29487,29488,29489,29490,29491,\n29492,29493,29494,29495,29496,29497,29498,29499,29500,29501,29502,29503,\n29504,29505,29506,29507,29508,29509,29510,29511,29512,29513,29514,29515,\n29516,29517,29518,29519,29520,29521,29522,29523,29524,29525,29526,29527,\n29528,29529,29530,29531,29532,29533,29534,29535,29536,29537,29538,29539,\n29540,29541,29542,29543,29544,29545,29546,29547,29548,29549,29550,29551,\n29552,29553,29554,29555,29556,29557,29558,29559,29560,29561,29562,29563,\n29564,29565,29566,29567,29568,29569,29570,29571,29572,29573,29574,29575,\n29576,29577,29578,29579,29580,29581,29582,29583,29584,29585,29586,29587,\n29588,29589,29590,29591,29592,29593,29594,29595,29596,29597,29598,29599,\n29600,29601,29602,29603,29604,29605,29606,29607,29608,29609,29610,29611,\n29612,29613,29614,29615,29616,29617,29618,29619,29620,29621,29622,29623,\n29624,29625,29626,29627,29628,29629,29630,29631,29632,29633,29634,29635,\n29636,29637,29638,29639,29640,29641,29642,29643,29644,29645,29646,29647,\n29648,29649,29650,29651,29652,29653,29654,29655,29656,29657,29658,29659,\n29660,29661,29662,29663,29664,29665,29666,29667,29668,29669,29670,29671,\n29672,29673,29674,29675,29676,29677,29678,29679,29680,29681,29682,29683,\n29684,29685,29686,29687,29688,29689,29690,29691,29692,29693,29694,29695,\n29696,29697,29698,29699,29700,29701,29702,29703,29704,29705,29706,29707,\n29708,29709,29710,29711,29712,29713,29714,29715,29716,29717,29718,29719,\n29720,29721,29722,29723,29724,29725,29726,29727,29728,29729,29730,29731,\n29732,29733,29734,29735,29736,29737,29738,29739,29740,29741,29742,29743,\n29744,29745,29746,29747,29748,29749,29750,29751,29752,29753,29754,29755,\n29756,29757,29758,29759,29760,29761,29762,29763,29764,29765,29766,29767,\n29768,29769,29770,29771,29772,29773,29774,29775,29776,29777,29778,29779,\n29780,29781,29782,29783,29784,29785,29786,29787,29788,29789,29790,29791,\n29792,29793,29794,29795,29796,29797,29798,29799,29800,29801,29802,29803,\n29804,29805,29806,29807,29808,29809,29810,29811,29812,29813,29814,29815,\n29816,29817,29818,29819,29820,29821,29822,29823,29824,29825,29826,29827,\n29828,29829,29830,29831,29832,29833,29834,29835,29836,29837,29838,29839,\n29840,29841,29842,29843,29844,29845,29846,29847,29848,29849,29850,29851,\n29852,29853,29854,29855,29856,29857,29858,29859,29860,29861,29862,29863,\n29864,29865,29866,29867,29868,29869,29870,29871,29872,29873,29874,29875,\n29876,29877,29878,29879,29880,29881,29882,29883,29884,29885,29886,29887,\n29888,29889,29890,29891,29892,29893,29894,29895,29896,29897,29898,29899,\n29900,29901,29902,29903,29904,29905,29906,29907,29908,29909,29910,29911,\n29912,29913,29914,29915,29916,29917,29918,29919,29920,29921,29922,29923,\n29924,29925,29926,29927,29928,29929,29930,29931,29932,29933,29934,29935,\n29936,29937,29938,29939,29940,29941,29942,29943,29944,29945,29946,29947,\n29948,29949,29950,29951,29952,29953,29954,29955,29956,29957,29958,29959,\n29960,29961,29962,29963,29964,29965,29966,29967,29968,29969,29970,29971,\n29972,29973,29974,29975,29976,29977,29978,29979,29980,29981,29982,29983,\n29984,29985,29986,29987,29988,29989,29990,29991,29992,29993,29994,29995,\n29996,29997,29998,29999,30000,30001,30002,30003,30004,30005,30006,30007,\n30008,30009,30010,30011,30012,30013,30014,30015,30016,30017,30018,30019,\n30020,30021,30022,30023,30024,30025,30026,30027,30028,30029,30030,30031,\n30032,30033,30034,30035,30036,30037,30038,30039,30040,30041,30042,30043,\n30044,30045,30046,30047,30048,30049,30050,30051,30052,30053,30054,30055,\n30056,30057,30058,30059,30060,30061,30062,30063,30064,30065,30066,30067,\n30068,30069,30070,30071,30072,30073,30074,30075,30076,30077,30078,30079,\n30080,30081,30082,30083,30084,30085,30086,30087,30088,30089,30090,30091,\n30092,30093,30094,30095,30096,30097,30098,30099,30100,30101,30102,30103,\n30104,30105,30106,30107,30108,30109,30110,30111,30112,30113,30114,30115,\n30116,30117,30118,30119,30120,30121,30122,30123,30124,30125,30126,30127,\n30128,30129,30130,30131,30132,30133,30134,30135,30136,30137,30138,30139,\n30140,30141,30142,30143,30144,30145,30146,30147,30148,30149,30150,30151,\n30152,30153,30154,30155,30156,30157,30158,30159,30160,30161,30162,30163,\n30164,30165,30166,30167,30168,30169,30170,30171,30172,30173,30174,30175,\n30176,30177,30178,30179,30180,30181,30182,30183,30184,30185,30186,30187,\n30188,30189,30190,30191,30192,30193,30194,30195,30196,30197,30198,30199,\n30200,30201,30202,30203,30204,30205,30206,30207,30208,30209,30210,30211,\n30212,30213,30214,30215,30216,30217,30218,30219,30220,30221,30222,30223,\n30224,30225,30226,30227,30228,30229,30230,30231,30232,30233,30234,30235,\n30236,30237,30238,30239,30240,30241,30242,30243,30244,30245,30246,30247,\n30248,30249,30250,30251,30252,30253,30254,30255,30256,30257,30258,30259,\n30260,30261,30262,30263,30264,30265,30266,30267,30268,30269,30270,30271,\n30272,30273,30274,30275,30276,30277,30278,30279,30280,30281,30282,30283,\n30284,30285,30286,30287,30288,30289,30290,30291,30292,30293,30294,30295,\n30296,30297,30298,30299,30300,30301,30302,30303,30304,30305,30306,30307,\n30308,30309,30310,30311,30312,30313,30314,30315,30316,30317,30318,30319,\n30320,30321,30322,30323,30324,30325,30326,30327,30328,30329,30330,30331,\n30332,30333,30334,30335,30336,30337,30338,30339,30340,30341,30342,30343,\n30344,30345,30346,30347,30348,30349,30350,30351,30352,30353,30354,30355,\n30356,30357,30358,30359,30360,30361,30362,30363,30364,30365,30366,30367,\n30368,30369,30370,30371,30372,30373,30374,30375,30376,30377,30378,30379,\n30380,30381,30382,30383,30384,30385,30386,30387,30388,30389,30390,30391,\n30392,30393,30394,30395,30396,30397,30398,30399,30400,30401,30402,30403,\n30404,30405,30406,30407,30408,30409,30410,30411,30412,30413,30414,30415,\n30416,30417,30418,30419,30420,30421,30422,30423,30424,30425,30426,30427,\n30428,30429,30430,30431,30432,30433,30434,30435,30436,30437,30438,30439,\n30440,30441,30442,30443,30444,30445,30446,30447,30448,30449,30450,30451,\n30452,30453,30454,30455,30456,30457,30458,30459,30460,30461,30462,30463,\n30464,30465,30466,30467,30468,30469,30470,30471,30472,30473,30474,30475,\n30476,30477,30478,30479,30480,30481,30482,30483,30484,30485,30486,30487,\n30488,30489,30490,30491,30492,30493,30494,30495,30496,30497,30498,30499,\n30500,30501,30502,30503,30504,30505,30506,30507,30508,30509,30510,30511,\n30512,30513,30514,30515,30516,30517,30518,30519,30520,30521,30522,30523,\n30524,30525,30526,30527,30528,30529,30530,30531,30532,30533,30534,30535,\n30536,30537,30538,30539,30540,30541,30542,30543,30544,30545,30546,30547,\n30548,30549,30550,30551,30552,30553,30554,30555,30556,30557,30558,30559,\n30560,30561,30562,30563,30564,30565,30566,30567,30568,30569,30570,30571,\n30572,30573,30574,30575,30576,30577,30578,30579,30580,30581,30582,30583,\n30584,30585,30586,30587,30588,30589,30590,30591,30592,30593,30594,30595,\n30596,30597,30598,30599,30600,30601,30602,30603,30604,30605,30606,30607,\n30608,30609,30610,30611,30612,30613,30614,30615,30616,30617,30618,30619,\n30620,30621,30622,30623,30624,30625,30626,30627,30628,30629,30630,30631,\n30632,30633,30634,30635,30636,30637,30638,30639,30640,30641,30642,30643,\n30644,30645,30646,30647,30648,30649,30650,30651,30652,30653,30654,30655,\n30656,30657,30658,30659,30660,30661,30662,30663,30664,30665,30666,30667,\n30668,30669,30670,30671,30672,30673,30674,30675,30676,30677,30678,30679,\n30680,30681,30682,30683,30684,30685,30686,30687,30688,30689,30690,30691,\n30692,30693,30694,30695,30696,30697,30698,30699,30700,30701,30702,30703,\n30704,30705,30706,30707,30708,30709,30710,30711,30712,30713,30714,30715,\n30716,30717,30718,30719,30720,30721,30722,30723,30724,30725,30726,30727,\n30728,30729,30730,30731,30732,30733,30734,30735,30736,30737,30738,30739,\n30740,30741,30742,30743,30744,30745,30746,30747,30748,30749,30750,30751,\n30752,30753,30754,30755,30756,30757,30758,30759,30760,30761,30762,30763,\n30764,30765,30766,30767,30768,30769,30770,30771,30772,30773,30774,30775,\n30776,30777,30778,30779,30780,30781,30782,30783,30784,30785,30786,30787,\n30788,30789,30790,30791,30792,30793,30794,30795,30796,30797,30798,30799,\n30800,30801,30802,30803,30804,30805,30806,30807,30808,30809,30810,30811,\n30812,30813,30814,30815,30816,30817,30818,30819,30820,30821,30822,30823,\n30824,30825,30826,30827,30828,30829,30830,30831,30832,30833,30834,30835,\n30836,30837,30838,30839,30840,30841,30842,30843,30844,30845,30846,30847,\n30848,30849,30850,30851,30852,30853,30854,30855,30856,30857,30858,30859,\n30860,30861,30862,30863,30864,30865,30866,30867,30868,30869,30870,30871,\n30872,30873,30874,30875,30876,30877,30878,30879,30880,30881,30882,30883,\n30884,30885,30886,30887,30888,30889,30890,30891,30892,30893,30894,30895,\n30896,30897,30898,30899,30900,30901,30902,30903,30904,30905,30906,30907,\n30908,30909,30910,30911,30912,30913,30914,30915,30916,30917,30918,30919,\n30920,30921,30922,30923,30924,30925,30926,30927,30928,30929,30930,30931,\n30932,30933,30934,30935,30936,30937,30938,30939,30940,30941,30942,30943,\n30944,30945,30946,30947,30948,30949,30950,30951,30952,30953,30954,30955,\n30956,30957,30958,30959,30960,30961,30962,30963,30964,30965,30966,30967,\n30968,30969,30970,30971,30972,30973,30974,30975,30976,30977,30978,30979,\n30980,30981,30982,30983,30984,30985,30986,30987,30988,30989,30990,30991,\n30992,30993,30994,30995,30996,30997,30998,30999,31000,31001,31002,31003,\n31004,31005,31006,31007,31008,31009,31010,31011,31012,31013,31014,31015,\n31016,31017,31018,31019,31020,31021,31022,31023,31024,31025,31026,31027,\n31028,31029,31030,31031,31032,31033,31034,31035,31036,31037,31038,31039,\n31040,31041,31042,31043,31044,31045,31046,31047,31048,31049,31050,31051,\n31052,31053,31054,31055,31056,31057,31058,31059,31060,31061,31062,31063,\n31064,31065,31066,31067,31068,31069,31070,31071,31072,31073,31074,31075,\n31076,31077,31078,31079,31080,31081,31082,31083,31084,31085,31086,31087,\n31088,31089,31090,31091,31092,31093,31094,31095,31096,31097,31098,31099,\n31100,31101,31102,31103,31104,31105,31106,31107,31108,31109,31110,31111,\n31112,31113,31114,31115,31116,31117,31118,31119,31120,31121,31122,31123,\n31124,31125,31126,31127,31128,31129,31130,31131,31132,31133,31134,31135,\n31136,31137,31138,31139,31140,31141,31142,31143,31144,31145,31146,31147,\n31148,31149,31150,31151,31152,31153,31154,31155,31156,31157,31158,31159,\n31160,31161,31162,31163,31164,31165,31166,31167,31168,31169,31170,31171,\n31172,31173,31174,31175,31176,31177,31178,31179,31180,31181,31182,31183,\n31184,31185,31186,31187,31188,31189,31190,31191,31192,31193,31194,31195,\n31196,31197,31198,31199,31200,31201,31202,31203,31204,31205,31206,31207,\n31208,31209,31210,31211,31212,31213,31214,31215,31216,31217,31218,31219,\n31220,31221,31222,31223,31224,31225,31226,31227,31228,31229,31230,31231,\n31232,31233,31234,31235,31236,31237,31238,31239,31240,31241,31242,31243,\n31244,31245,31246,31247,31248,31249,31250,31251,31252,31253,31254,31255,\n31256,31257,31258,31259,31260,31261,31262,31263,31264,31265,31266,31267,\n31268,31269,31270,31271,31272,31273,31274,31275,31276,31277,31278,31279,\n31280,31281,31282,31283,31284,31285,31286,31287,31288,31289,31290,31291,\n31292,31293,31294,31295,31296,31297,31298,31299,31300,31301,31302,31303,\n31304,31305,31306,31307,31308,31309,31310,31311,31312,31313,31314,31315,\n31316,31317,31318,31319,31320,31321,31322,31323,31324,31325,31326,31327,\n31328,31329,31330,31331,31332,31333,31334,31335,31336,31337,31338,31339,\n31340,31341,31342,31343,31344,31345,31346,31347,31348,31349,31350,31351,\n31352,31353,31354,31355,31356,31357,31358,31359,31360,31361,31362,31363,\n31364,31365,31366,31367,31368,31369,31370,31371,31372,31373,31374,31375,\n31376,31377,31378,31379,31380,31381,31382,31383,31384,31385,31386,31387,\n31388,31389,31390,31391,31392,31393,31394,31395,31396,31397,31398,31399,\n31400,31401,31402,31403,31404,31405,31406,31407,31408,31409,31410,31411,\n31412,31413,31414,31415,31416,31417,31418,31419,31420,31421,31422,31423,\n31424,31425,31426,31427,31428,31429,31430,31431,31432,31433,31434,31435,\n31436,31437,31438,31439,31440,31441,31442,31443,31444,31445,31446,31447,\n31448,31449,31450,31451,31452,31453,31454,31455,31456,31457,31458,31459,\n31460,31461,31462,31463,31464,31465,31466,31467,31468,31469,31470,31471,\n31472,31473,31474,31475,31476,31477,31478,31479,31480,31481,31482,31483,\n31484,31485,31486,31487,31488,31489,31490,31491,31492,31493,31494,31495,\n31496,31497,31498,31499,31500,31501,31502,31503,31504,31505,31506,31507,\n31508,31509,31510,31511,31512,31513,31514,31515,31516,31517,31518,31519,\n31520,31521,31522,31523,31524,31525,31526,31527,31528,31529,31530,31531,\n31532,31533,31534,31535,31536,31537,31538,31539,31540,31541,31542,31543,\n31544,31545,31546,31547,31548,31549,31550,31551,31552,31553,31554,31555,\n31556,31557,31558,31559,31560,31561,31562,31563,31564,31565,31566,31567,\n31568,31569,31570,31571,31572,31573,31574,31575,31576,31577,31578,31579,\n31580,31581,31582,31583,31584,31585,31586,31587,31588,31589,31590,31591,\n31592,31593,31594,31595,31596,31597,31598,31599,31600,31601,31602,31603,\n31604,31605,31606,31607,31608,31609,31610,31611,31612,31613,31614,31615,\n31616,31617,31618,31619,31620,31621,31622,31623,31624,31625,31626,31627,\n31628,31629,31630,31631,31632,31633,31634,31635,31636,31637,31638,31639,\n31640,31641,31642,31643,31644,31645,31646,31647,31648,31649,31650,31651,\n31652,31653,31654,31655,31656,31657,31658,31659,31660,31661,31662,31663,\n31664,31665,31666,31667,31668,31669,31670,31671,31672,31673,31674,31675,\n31676,31677,31678,31679,31680,31681,31682,31683,31684,31685,31686,31687,\n31688,31689,31690,31691,31692,31693,31694,31695,31696,31697,31698,31699,\n31700,31701,31702,31703,31704,31705,31706,31707,31708,31709,31710,31711,\n31712,31713,31714,31715,31716,31717,31718,31719,31720,31721,31722,31723,\n31724,31725,31726,31727,31728,31729,31730,31731,31732,31733,31734,31735,\n31736,31737,31738,31739,31740,31741,31742,31743,31744,31745,31746,31747,\n31748,31749,31750,31751,31752,31753,31754,31755,31756,31757,31758,31759,\n31760,31761,31762,31763,31764,31765,31766,31767,31768,31769,31770,31771,\n31772,31773,31774,31775,31776,31777,31778,31779,31780,31781,31782,31783,\n31784,31785,31786,31787,31788,31789,31790,31791,31792,31793,31794,31795,\n31796,31797,31798,31799,31800,31801,31802,31803,31804,31805,31806,31807,\n31808,31809,31810,31811,31812,31813,31814,31815,31816,31817,31818,31819,\n31820,31821,31822,31823,31824,31825,31826,31827,31828,31829,31830,31831,\n31832,31833,31834,31835,31836,31837,31838,31839,31840,31841,31842,31843,\n31844,31845,31846,31847,31848,31849,31850,31851,31852,31853,31854,31855,\n31856,31857,31858,31859,31860,31861,31862,31863,31864,31865,31866,31867,\n31868,31869,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879,\n31880,31881,31882,31883,31884,31885,31886,31887,31888,31889,31890,31891,\n31892,31893,31894,31895,31896,31897,31898,31899,31900,31901,31902,31903,\n31904,31905,31906,31907,31908,31909,31910,31911,31912,31913,31914,31915,\n31916,31917,31918,31919,31920,31921,31922,31923,31924,31925,31926,31927,\n31928,31929,31930,31931,31932,31933,31934,31935,31936,31937,31938,31939,\n31940,31941,31942,31943,31944,31945,31946,31947,31948,31949,31950,31951,\n31952,31953,31954,31955,31956,31957,31958,31959,31960,31961,31962,31963,\n31964,31965,31966,31967,31968,31969,31970,31971,31972,31973,31974,31975,\n31976,31977,31978,31979,31980,31981,31982,31983,31984,31985,31986,31987,\n31988,31989,31990,31991,31992,31993,31994,31995,31996,31997,31998,31999,\n32000,32001,32002,32003,32004,32005,32006,32007,32008,32009,32010,32011,\n32012,32013,32014,32015,32016,32017,32018,32019,32020,32021,32022,32023,\n32024,32025,32026,32027,32028,32029,32030,32031,32032,32033,32034,32035,\n32036,32037,32038,32039,32040,32041,32042,32043,32044,32045,32046,32047,\n32048,32049,32050,32051,32052,32053,32054,32055,32056,32057,32058,32059,\n32060,32061,32062,32063,32064,32065,32066,32067,32068,32069,32070,32071,\n32072,32073,32074,32075,32076,32077,32078,32079,32080,32081,32082,32083,\n32084,32085,32086,32087,32088,32089,32090,32091,32092,32093,32094,32095,\n32096,32097,32098,32099,32100,32101,32102,32103,32104,32105,32106,32107,\n32108,32109,32110,32111,32112,32113,32114,32115,32116,32117,32118,32119,\n32120,32121,32122,32123,32124,32125,32126,32127,32128,32129,32130,32131,\n32132,32133,32134,32135,32136,32137,32138,32139,32140,32141,32142,32143,\n32144,32145,32146,32147,32148,32149,32150,32151,32152,32153,32154,32155,\n32156,32157,32158,32159,32160,32161,32162,32163,32164,32165,32166,32167,\n32168,32169,32170,32171,32172,32173,32174,32175,32176,32177,32178,32179,\n32180,32181,32182,32183,32184,32185,32186,32187,32188,32189,32190,32191,\n32192,32193,32194,32195,32196,32197,32198,32199,32200,32201,32202,32203,\n32204,32205,32206,32207,32208,32209,32210,32211,32212,32213,32214,32215,\n32216,32217,32218,32219,32220,32221,32222,32223,32224,32225,32226,32227,\n32228,32229,32230,32231,32232,32233,32234,32235,32236,32237,32238,32239,\n32240,32241,32242,32243,32244,32245,32246,32247,32248,32249,32250,32251,\n32252,32253,32254,32255,32256,32257,32258,32259,32260,32261,32262,32263,\n32264,32265,32266,32267,32268,32269,32270,32271,32272,32273,32274,32275,\n32276,32277,32278,32279,32280,32281,32282,32283,32284,32285,32286,32287,\n32288,32289,32290,32291,32292,32293,32294,32295,32296,32297,32298,32299,\n32300,32301,32302,32303,32304,32305,32306,32307,32308,32309,32310,32311,\n32312,32313,32314,32315,32316,32317,32318,32319,32320,32321,32322,32323,\n32324,32325,32326,32327,32328,32329,32330,32331,32332,32333,32334,32335,\n32336,32337,32338,32339,32340,32341,32342,32343,32344,32345,32346,32347,\n32348,32349,32350,32351,32352,32353,32354,32355,32356,32357,32358,32359,\n32360,32361,32362,32363,32364,32365,32366,32367,32368,32369,32370,32371,\n32372,32373,32374,32375,32376,32377,32378,32379,32380,32381,32382,32383,\n32384,32385,32386,32387,32388,32389,32390,32391,32392,32393,32394,32395,\n32396,32397,32398,32399,32400,32401,32402,32403,32404,32405,32406,32407,\n32408,32409,32410,32411,32412,32413,32414,32415,32416,32417,32418,32419,\n32420,32421,32422,32423,32424,32425,32426,32427,32428,32429,32430,32431,\n32432,32433,32434,32435,32436,32437,32438,32439,32440,32441,32442,32443,\n32444,32445,32446,32447,32448,32449,32450,32451,32452,32453,32454,32455,\n32456,32457,32458,32459,32460,32461,32462,32463,32464,32465,32466,32467,\n32468,32469,32470,32471,32472,32473,32474,32475,32476,32477,32478,32479,\n32480,32481,32482,32483,32484,32485,32486,32487,32488,32489,32490,32491,\n32492,32493,32494,32495,32496,32497,32498,32499,32500,32501,32502,32503,\n32504,32505,32506,32507,32508,32509,32510,32511,32512,32513,32514,32515,\n32516,32517,32518,32519,32520,32521,32522,32523,32524,32525,32526,32527,\n32528,32529,32530,32531,32532,32533,32534,32535,32536,32537,32538,32539,\n32540,32541,32542,32543,32544,32545,32546,32547,32548,32549,32550,32551,\n32552,32553,32554,32555,32556,32557,32558,32559,32560,32561,32562,32563,\n32564,32565,32566,32567,32568,32569,32570,32571,32572,32573,32574,32575,\n32576,32577,32578,32579,32580,32581,32582,32583,32584,32585,32586,32587,\n32588,32589,32590,32591,32592,32593,32594,32595,32596,32597,32598,32599,\n32600,32601,32602,32603,32604,32605,32606,32607,32608,32609,32610,32611,\n32612,32613,32614,32615,32616,32617,32618,32619,32620,32621,32622,32623,\n32624,32625,32626,32627,32628,32629,32630,32631,32632,32633,32634,32635,\n32636,32637,32638,32639,32640,32641,32642,32643,32644,32645,32646,32647,\n32648,32649,32650,32651,32652,32653,32654,32655,32656,32657,32658,32659,\n32660,32661,32662,32663,32664,32665,32666,32667,32668,32669,32670,32671,\n32672,32673,32674,32675,32676,32677,32678,32679,32680,32681,32682,32683,\n32684,32685,32686,32687,32688,32689,32690,32691,32692,32693,32694,32695,\n32696,32697,32698,32699,32700,32701,32702,32703,32704,32705,32706,32707,\n32708,32709,32710,32711,32712,32713,32714,32715,32716,32717,32718,32719,\n32720,32721,32722,32723,32724,32725,32726,32727,32728,32729,32730,32731,\n32732,32733,32734,32735,32736,32737,32738,32739,32740,32741,32742,32743,\n32744,32745,32746,32747,32748,32749,32750,32751,32752,32753,32754,32755,\n32756,32757,32758,32759,32760,32761,32762,32763,32764,32765,32766,32767,\n32768L,32769L,32770L,32771L,32772L,32773L,32774L,32775L,32776L,32777L,\n32778L,32779L,32780L,32781L,32782L,32783L,32784L,32785L,32786L,32787L,\n32788L,32789L,32790L,32791L,32792L,32793L,32794L,32795L,32796L,32797L,\n32798L,32799L,32800L,32801L,32802L,32803L,32804L,32805L,32806L,32807L,\n32808L,32809L,32810L,32811L,32812L,32813L,32814L,32815L,32816L,32817L,\n32818L,32819L,32820L,32821L,32822L,32823L,32824L,32825L,32826L,32827L,\n32828L,32829L,32830L,32831L,32832L,32833L,32834L,32835L,32836L,32837L,\n32838L,32839L,32840L,32841L,32842L,32843L,32844L,32845L,32846L,32847L,\n32848L,32849L,32850L,32851L,32852L,32853L,32854L,32855L,32856L,32857L,\n32858L,32859L,32860L,32861L,32862L,32863L,32864L,32865L,32866L,32867L,\n32868L,32869L,32870L,32871L,32872L,32873L,32874L,32875L,32876L,32877L,\n32878L,32879L,32880L,32881L,32882L,32883L,32884L,32885L,32886L,32887L,\n32888L,32889L,32890L,32891L,32892L,32893L,32894L,32895L,32896L,32897L,\n32898L,32899L,32900L,32901L,32902L,32903L,32904L,32905L,32906L,32907L,\n32908L,32909L,32910L,32911L,32912L,32913L,32914L,32915L,32916L,32917L,\n32918L,32919L,32920L,32921L,32922L,32923L,32924L,32925L,32926L,32927L,\n32928L,32929L,32930L,32931L,32932L,32933L,32934L,32935L,32936L,32937L,\n32938L,32939L,32940L,32941L,32942L,32943L,32944L,32945L,32946L,32947L,\n32948L,32949L,32950L,32951L,32952L,32953L,32954L,32955L,32956L,32957L,\n32958L,32959L,32960L,32961L,32962L,32963L,32964L,32965L,32966L,32967L,\n32968L,32969L,32970L,32971L,32972L,32973L,32974L,32975L,32976L,32977L,\n32978L,32979L,32980L,32981L,32982L,32983L,32984L,32985L,32986L,32987L,\n32988L,32989L,32990L,32991L,32992L,32993L,32994L,32995L,32996L,32997L,\n32998L,32999L,33000L,33001L,33002L,33003L,33004L,33005L,33006L,33007L,\n33008L,33009L,33010L,33011L,33012L,33013L,33014L,33015L,33016L,33017L,\n33018L,33019L,33020L,33021L,33022L,33023L,33024L,33025L,33026L,33027L,\n33028L,33029L,33030L,33031L,33032L,33033L,33034L,33035L,33036L,33037L,\n33038L,33039L,33040L,33041L,33042L,33043L,33044L,33045L,33046L,33047L,\n33048L,33049L,33050L,33051L,33052L,33053L,33054L,33055L,33056L,33057L,\n33058L,33059L,33060L,33061L,33062L,33063L,33064L,33065L,33066L,33067L,\n33068L,33069L,33070L,33071L,33072L,33073L,33074L,33075L,33076L,33077L,\n33078L,33079L,33080L,33081L,33082L,33083L,33084L,33085L,33086L,33087L,\n33088L,33089L,33090L,33091L,33092L,33093L,33094L,33095L,33096L,33097L,\n33098L,33099L,33100L,33101L,33102L,33103L,33104L,33105L,33106L,33107L,\n33108L,33109L,33110L,33111L,33112L,33113L,33114L,33115L,33116L,33117L,\n33118L,33119L,33120L,33121L,33122L,33123L,33124L,33125L,33126L,33127L,\n33128L,33129L,33130L,33131L,33132L,33133L,33134L,33135L,33136L,33137L,\n33138L,33139L,33140L,33141L,33142L,33143L,33144L,33145L,33146L,33147L,\n33148L,33149L,33150L,33151L,33152L,33153L,33154L,33155L,33156L,33157L,\n33158L,33159L,33160L,33161L,33162L,33163L,33164L,33165L,33166L,33167L,\n33168L,33169L,33170L,33171L,33172L,33173L,33174L,33175L,33176L,33177L,\n33178L,33179L,33180L,33181L,33182L,33183L,33184L,33185L,33186L,33187L,\n33188L,33189L,33190L,33191L,33192L,33193L,33194L,33195L,33196L,33197L,\n33198L,33199L,33200L,33201L,33202L,33203L,33204L,33205L,33206L,33207L,\n33208L,33209L,33210L,33211L,33212L,33213L,33214L,33215L,33216L,33217L,\n33218L,33219L,33220L,33221L,33222L,33223L,33224L,33225L,33226L,33227L,\n33228L,33229L,33230L,33231L,33232L,33233L,33234L,33235L,33236L,33237L,\n33238L,33239L,33240L,33241L,33242L,33243L,33244L,33245L,33246L,33247L,\n33248L,33249L,33250L,33251L,33252L,33253L,33254L,33255L,33256L,33257L,\n33258L,33259L,33260L,33261L,33262L,33263L,33264L,33265L,33266L,33267L,\n33268L,33269L,33270L,33271L,33272L,33273L,33274L,33275L,33276L,33277L,\n33278L,33279L,33280L,33281L,33282L,33283L,33284L,33285L,33286L,33287L,\n33288L,33289L,33290L,33291L,33292L,33293L,33294L,33295L,33296L,33297L,\n33298L,33299L,33300L,33301L,33302L,33303L,33304L,33305L,33306L,33307L,\n33308L,33309L,33310L,33311L,33312L,33313L,33314L,33315L,33316L,33317L,\n33318L,33319L,33320L,33321L,33322L,33323L,33324L,33325L,33326L,33327L,\n33328L,33329L,33330L,33331L,33332L,33333L,33334L,33335L,33336L,33337L,\n33338L,33339L,33340L,33341L,33342L,33343L,33344L,33345L,33346L,33347L,\n33348L,33349L,33350L,33351L,33352L,33353L,33354L,33355L,33356L,33357L,\n33358L,33359L,33360L,33361L,33362L,33363L,33364L,33365L,33366L,33367L,\n33368L,33369L,33370L,33371L,33372L,33373L,33374L,33375L,33376L,33377L,\n33378L,33379L,33380L,33381L,33382L,33383L,33384L,33385L,33386L,33387L,\n33388L,33389L,33390L,33391L,33392L,33393L,33394L,33395L,33396L,33397L,\n33398L,33399L,33400L,33401L,33402L,33403L,33404L,33405L,33406L,33407L,\n33408L,33409L,33410L,33411L,33412L,33413L,33414L,33415L,33416L,33417L,\n33418L,33419L,33420L,33421L,33422L,33423L,33424L,33425L,33426L,33427L,\n33428L,33429L,33430L,33431L,33432L,33433L,33434L,33435L,33436L,33437L,\n33438L,33439L,33440L,33441L,33442L,33443L,33444L,33445L,33446L,33447L,\n33448L,33449L,33450L,33451L,33452L,33453L,33454L,33455L,33456L,33457L,\n33458L,33459L,33460L,33461L,33462L,33463L,33464L,33465L,33466L,33467L,\n33468L,33469L,33470L,33471L,33472L,33473L,33474L,33475L,33476L,33477L,\n33478L,33479L,33480L,33481L,33482L,33483L,33484L,33485L,33486L,33487L,\n33488L,33489L,33490L,33491L,33492L,33493L,33494L,33495L,33496L,33497L,\n33498L,33499L,33500L,33501L,33502L,33503L,33504L,33505L,33506L,33507L,\n33508L,33509L,33510L,33511L,33512L,33513L,33514L,33515L,33516L,33517L,\n33518L,33519L,33520L,33521L,33522L,33523L,33524L,33525L,33526L,33527L,\n33528L,33529L,33530L,33531L,33532L,33533L,33534L,33535L,33536L,33537L,\n33538L,33539L,33540L,33541L,33542L,33543L,33544L,33545L,33546L,33547L,\n33548L,33549L,33550L,33551L,33552L,33553L,33554L,33555L,33556L,33557L,\n33558L,33559L,33560L,33561L,33562L,33563L,33564L,33565L,33566L,33567L,\n33568L,33569L,33570L,33571L,33572L,33573L,33574L,33575L,33576L,33577L,\n33578L,33579L,33580L,33581L,33582L,33583L,33584L,33585L,33586L,33587L,\n33588L,33589L,33590L,33591L,33592L,33593L,33594L,33595L,33596L,33597L,\n33598L,33599L,33600L,33601L,33602L,33603L,33604L,33605L,33606L,33607L,\n33608L,33609L,33610L,33611L,33612L,33613L,33614L,33615L,33616L,33617L,\n33618L,33619L,33620L,33621L,33622L,33623L,33624L,33625L,33626L,33627L,\n33628L,33629L,33630L,33631L,33632L,33633L,33634L,33635L,33636L,33637L,\n33638L,33639L,33640L,33641L,33642L,33643L,33644L,33645L,33646L,33647L,\n33648L,33649L,33650L,33651L,33652L,33653L,33654L,33655L,33656L,33657L,\n33658L,33659L,33660L,33661L,33662L,33663L,33664L,33665L,33666L,33667L,\n33668L,33669L,33670L,33671L,33672L,33673L,33674L,33675L,33676L,33677L,\n33678L,33679L,33680L,33681L,33682L,33683L,33684L,33685L,33686L,33687L,\n33688L,33689L,33690L,33691L,33692L,33693L,33694L,33695L,33696L,33697L,\n33698L,33699L,33700L,33701L,33702L,33703L,33704L,33705L,33706L,33707L,\n33708L,33709L,33710L,33711L,33712L,33713L,33714L,33715L,33716L,33717L,\n33718L,33719L,33720L,33721L,33722L,33723L,33724L,33725L,33726L,33727L,\n33728L,33729L,33730L,33731L,33732L,33733L,33734L,33735L,33736L,33737L,\n33738L,33739L,33740L,33741L,33742L,33743L,33744L,33745L,33746L,33747L,\n33748L,33749L,33750L,33751L,33752L,33753L,33754L,33755L,33756L,33757L,\n33758L,33759L,33760L,33761L,33762L,33763L,33764L,33765L,33766L,33767L,\n33768L,33769L,33770L,33771L,33772L,33773L,33774L,33775L,33776L,33777L,\n33778L,33779L,33780L,33781L,33782L,33783L,33784L,33785L,33786L,33787L,\n33788L,33789L,33790L,33791L,33792L,33793L,33794L,33795L,33796L,33797L,\n33798L,33799L,33800L,33801L,33802L,33803L,33804L,33805L,33806L,33807L,\n33808L,33809L,33810L,33811L,33812L,33813L,33814L,33815L,33816L,33817L,\n33818L,33819L,33820L,33821L,33822L,33823L,33824L,33825L,33826L,33827L,\n33828L,33829L,33830L,33831L,33832L,33833L,33834L,33835L,33836L,33837L,\n33838L,33839L,33840L,33841L,33842L,33843L,33844L,33845L,33846L,33847L,\n33848L,33849L,33850L,33851L,33852L,33853L,33854L,33855L,33856L,33857L,\n33858L,33859L,33860L,33861L,33862L,33863L,33864L,33865L,33866L,33867L,\n33868L,33869L,33870L,33871L,33872L,33873L,33874L,33875L,33876L,33877L,\n33878L,33879L,33880L,33881L,33882L,33883L,33884L,33885L,33886L,33887L,\n33888L,33889L,33890L,33891L,33892L,33893L,33894L,33895L,33896L,33897L,\n33898L,33899L,33900L,33901L,33902L,33903L,33904L,33905L,33906L,33907L,\n33908L,33909L,33910L,33911L,33912L,33913L,33914L,33915L,33916L,33917L,\n33918L,33919L,33920L,33921L,33922L,33923L,33924L,33925L,33926L,33927L,\n33928L,33929L,33930L,33931L,33932L,33933L,33934L,33935L,33936L,33937L,\n33938L,33939L,33940L,33941L,33942L,33943L,33944L,33945L,33946L,33947L,\n33948L,33949L,33950L,33951L,33952L,33953L,33954L,33955L,33956L,33957L,\n33958L,33959L,33960L,33961L,33962L,33963L,33964L,33965L,33966L,33967L,\n33968L,33969L,33970L,33971L,33972L,33973L,33974L,33975L,33976L,33977L,\n33978L,33979L,33980L,33981L,33982L,33983L,33984L,33985L,33986L,33987L,\n33988L,33989L,33990L,33991L,33992L,33993L,33994L,33995L,33996L,33997L,\n33998L,33999L,34000L,34001L,34002L,34003L,34004L,34005L,34006L,34007L,\n34008L,34009L,34010L,34011L,34012L,34013L,34014L,34015L,34016L,34017L,\n34018L,34019L,34020L,34021L,34022L,34023L,34024L,34025L,34026L,34027L,\n34028L,34029L,34030L,34031L,34032L,34033L,34034L,34035L,34036L,34037L,\n34038L,34039L,34040L,34041L,34042L,34043L,34044L,34045L,34046L,34047L,\n34048L,34049L,34050L,34051L,34052L,34053L,34054L,34055L,34056L,34057L,\n34058L,34059L,34060L,34061L,34062L,34063L,34064L,34065L,34066L,34067L,\n34068L,34069L,34070L,34071L,34072L,34073L,34074L,34075L,34076L,34077L,\n34078L,34079L,34080L,34081L,34082L,34083L,34084L,34085L,34086L,34087L,\n34088L,34089L,34090L,34091L,34092L,34093L,34094L,34095L,34096L,34097L,\n34098L,34099L,34100L,34101L,34102L,34103L,34104L,34105L,34106L,34107L,\n34108L,34109L,34110L,34111L,34112L,34113L,34114L,34115L,34116L,34117L,\n34118L,34119L,34120L,34121L,34122L,34123L,34124L,34125L,34126L,34127L,\n34128L,34129L,34130L,34131L,34132L,34133L,34134L,34135L,34136L,34137L,\n34138L,34139L,34140L,34141L,34142L,34143L,34144L,34145L,34146L,34147L,\n34148L,34149L,34150L,34151L,34152L,34153L,34154L,34155L,34156L,34157L,\n34158L,34159L,34160L,34161L,34162L,34163L,34164L,34165L,34166L,34167L,\n34168L,34169L,34170L,34171L,34172L,34173L,34174L,34175L,34176L,34177L,\n34178L,34179L,34180L,34181L,34182L,34183L,34184L,34185L,34186L,34187L,\n34188L,34189L,34190L,34191L,34192L,34193L,34194L,34195L,34196L,34197L,\n34198L,34199L,34200L,34201L,34202L,34203L,34204L,34205L,34206L,34207L,\n34208L,34209L,34210L,34211L,34212L,34213L,34214L,34215L,34216L,34217L,\n34218L,34219L,34220L,34221L,34222L,34223L,34224L,34225L,34226L,34227L,\n34228L,34229L,34230L,34231L,34232L,34233L,34234L,34235L,34236L,34237L,\n34238L,34239L,34240L,34241L,34242L,34243L,34244L,34245L,34246L,34247L,\n34248L,34249L,34250L,34251L,34252L,34253L,34254L,34255L,34256L,34257L,\n34258L,34259L,34260L,34261L,34262L,34263L,34264L,34265L,34266L,34267L,\n34268L,34269L,34270L,34271L,34272L,34273L,34274L,34275L,34276L,34277L,\n34278L,34279L,34280L,34281L,34282L,34283L,34284L,34285L,34286L,34287L,\n34288L,34289L,34290L,34291L,34292L,34293L,34294L,34295L,34296L,34297L,\n34298L,34299L,34300L,34301L,34302L,34303L,34304L,34305L,34306L,34307L,\n34308L,34309L,34310L,34311L,34312L,34313L,34314L,34315L,34316L,34317L,\n34318L,34319L,34320L,34321L,34322L,34323L,34324L,34325L,34326L,34327L,\n34328L,34329L,34330L,34331L,34332L,34333L,34334L,34335L,34336L,34337L,\n34338L,34339L,34340L,34341L,34342L,34343L,34344L,34345L,34346L,34347L,\n34348L,34349L,34350L,34351L,34352L,34353L,34354L,34355L,34356L,34357L,\n34358L,34359L,34360L,34361L,34362L,34363L,34364L,34365L,34366L,34367L,\n34368L,34369L,34370L,34371L,34372L,34373L,34374L,34375L,34376L,34377L,\n34378L,34379L,34380L,34381L,34382L,34383L,34384L,34385L,34386L,34387L,\n34388L,34389L,34390L,34391L,34392L,34393L,34394L,34395L,34396L,34397L,\n34398L,34399L,34400L,34401L,34402L,34403L,34404L,34405L,34406L,34407L,\n34408L,34409L,34410L,34411L,34412L,34413L,34414L,34415L,34416L,34417L,\n34418L,34419L,34420L,34421L,34422L,34423L,34424L,34425L,34426L,34427L,\n34428L,34429L,34430L,34431L,34432L,34433L,34434L,34435L,34436L,34437L,\n34438L,34439L,34440L,34441L,34442L,34443L,34444L,34445L,34446L,34447L,\n34448L,34449L,34450L,34451L,34452L,34453L,34454L,34455L,34456L,34457L,\n34458L,34459L,34460L,34461L,34462L,34463L,34464L,34465L,34466L,34467L,\n34468L,34469L,34470L,34471L,34472L,34473L,34474L,34475L,34476L,34477L,\n34478L,34479L,34480L,34481L,34482L,34483L,34484L,34485L,34486L,34487L,\n34488L,34489L,34490L,34491L,34492L,34493L,34494L,34495L,34496L,34497L,\n34498L,34499L,34500L,34501L,34502L,34503L,34504L,34505L,34506L,34507L,\n34508L,34509L,34510L,34511L,34512L,34513L,34514L,34515L,34516L,34517L,\n34518L,34519L,34520L,34521L,34522L,34523L,34524L,34525L,34526L,34527L,\n34528L,34529L,34530L,34531L,34532L,34533L,34534L,34535L,34536L,34537L,\n34538L,34539L,34540L,34541L,34542L,34543L,34544L,34545L,34546L,34547L,\n34548L,34549L,34550L,34551L,34552L,34553L,34554L,34555L,34556L,34557L,\n34558L,34559L,34560L,34561L,34562L,34563L,34564L,34565L,34566L,34567L,\n34568L,34569L,34570L,34571L,34572L,34573L,34574L,34575L,34576L,34577L,\n34578L,34579L,34580L,34581L,34582L,34583L,34584L,34585L,34586L,34587L,\n34588L,34589L,34590L,34591L,34592L,34593L,34594L,34595L,34596L,34597L,\n34598L,34599L,34600L,34601L,34602L,34603L,34604L,34605L,34606L,34607L,\n34608L,34609L,34610L,34611L,34612L,34613L,34614L,34615L,34616L,34617L,\n34618L,34619L,34620L,34621L,34622L,34623L,34624L,34625L,34626L,34627L,\n34628L,34629L,34630L,34631L,34632L,34633L,34634L,34635L,34636L,34637L,\n34638L,34639L,34640L,34641L,34642L,34643L,34644L,34645L,34646L,34647L,\n34648L,34649L,34650L,34651L,34652L,34653L,34654L,34655L,34656L,34657L,\n34658L,34659L,34660L,34661L,34662L,34663L,34664L,34665L,34666L,34667L,\n34668L,34669L,34670L,34671L,34672L,34673L,34674L,34675L,34676L,34677L,\n34678L,34679L,34680L,34681L,34682L,34683L,34684L,34685L,34686L,34687L,\n34688L,34689L,34690L,34691L,34692L,34693L,34694L,34695L,34696L,34697L,\n34698L,34699L,34700L,34701L,34702L,34703L,34704L,34705L,34706L,34707L,\n34708L,34709L,34710L,34711L,34712L,34713L,34714L,34715L,34716L,34717L,\n34718L,34719L,34720L,34721L,34722L,34723L,34724L,34725L,34726L,34727L,\n34728L,34729L,34730L,34731L,34732L,34733L,34734L,34735L,34736L,34737L,\n34738L,34739L,34740L,34741L,34742L,34743L,34744L,34745L,34746L,34747L,\n34748L,34749L,34750L,34751L,34752L,34753L,34754L,34755L,34756L,34757L,\n34758L,34759L,34760L,34761L,34762L,34763L,34764L,34765L,34766L,34767L,\n34768L,34769L,34770L,34771L,34772L,34773L,34774L,34775L,34776L,34777L,\n34778L,34779L,34780L,34781L,34782L,34783L,34784L,34785L,34786L,34787L,\n34788L,34789L,34790L,34791L,34792L,34793L,34794L,34795L,34796L,34797L,\n34798L,34799L,34800L,34801L,34802L,34803L,34804L,34805L,34806L,34807L,\n34808L,34809L,34810L,34811L,34812L,34813L,34814L,34815L,34816L,34817L,\n34818L,34819L,34820L,34821L,34822L,34823L,34824L,34825L,34826L,34827L,\n34828L,34829L,34830L,34831L,34832L,34833L,34834L,34835L,34836L,34837L,\n34838L,34839L,34840L,34841L,34842L,34843L,34844L,34845L,34846L,34847L,\n34848L,34849L,34850L,34851L,34852L,34853L,34854L,34855L,34856L,34857L,\n34858L,34859L,34860L,34861L,34862L,34863L,34864L,34865L,34866L,34867L,\n34868L,34869L,34870L,34871L,34872L,34873L,34874L,34875L,34876L,34877L,\n34878L,34879L,34880L,34881L,34882L,34883L,34884L,34885L,34886L,34887L,\n34888L,34889L,34890L,34891L,34892L,34893L,34894L,34895L,34896L,34897L,\n34898L,34899L,34900L,34901L,34902L,34903L,34904L,34905L,34906L,34907L,\n34908L,34909L,34910L,34911L,34912L,34913L,34914L,34915L,34916L,34917L,\n34918L,34919L,34920L,34921L,34922L,34923L,34924L,34925L,34926L,34927L,\n34928L,34929L,34930L,34931L,34932L,34933L,34934L,34935L,34936L,34937L,\n34938L,34939L,34940L,34941L,34942L,34943L,34944L,34945L,34946L,34947L,\n34948L,34949L,34950L,34951L,34952L,34953L,34954L,34955L,34956L,34957L,\n34958L,34959L,34960L,34961L,34962L,34963L,34964L,34965L,34966L,34967L,\n34968L,34969L,34970L,34971L,34972L,34973L,34974L,34975L,34976L,34977L,\n34978L,34979L,34980L,34981L,34982L,34983L,34984L,34985L,34986L,34987L,\n34988L,34989L,34990L,34991L,34992L,34993L,34994L,34995L,34996L,34997L,\n34998L,34999L,35000L,35001L,35002L,35003L,35004L,35005L,35006L,35007L,\n35008L,35009L,35010L,35011L,35012L,35013L,35014L,35015L,35016L,35017L,\n35018L,35019L,35020L,35021L,35022L,35023L,35024L,35025L,35026L,35027L,\n35028L,35029L,35030L,35031L,35032L,35033L,35034L,35035L,35036L,35037L,\n35038L,35039L,35040L,35041L,35042L,35043L,35044L,35045L,35046L,35047L,\n35048L,35049L,35050L,35051L,35052L,35053L,35054L,35055L,35056L,35057L,\n35058L,35059L,35060L,35061L,35062L,35063L,35064L,35065L,35066L,35067L,\n35068L,35069L,35070L,35071L,35072L,35073L,35074L,35075L,35076L,35077L,\n35078L,35079L,35080L,35081L,35082L,35083L,35084L,35085L,35086L,35087L,\n35088L,35089L,35090L,35091L,35092L,35093L,35094L,35095L,35096L,35097L,\n35098L,35099L,35100L,35101L,35102L,35103L,35104L,35105L,35106L,35107L,\n35108L,35109L,35110L,35111L,35112L,35113L,35114L,35115L,35116L,35117L,\n35118L,35119L,35120L,35121L,35122L,35123L,35124L,35125L,35126L,35127L,\n35128L,35129L,35130L,35131L,35132L,35133L,35134L,35135L,35136L,35137L,\n35138L,35139L,35140L,35141L,35142L,35143L,35144L,35145L,35146L,35147L,\n35148L,35149L,35150L,35151L,35152L,35153L,35154L,35155L,35156L,35157L,\n35158L,35159L,35160L,35161L,35162L,35163L,35164L,35165L,35166L,35167L,\n35168L,35169L,35170L,35171L,35172L,35173L,35174L,35175L,35176L,35177L,\n35178L,35179L,35180L,35181L,35182L,35183L,35184L,35185L,35186L,35187L,\n35188L,35189L,35190L,35191L,35192L,35193L,35194L,35195L,35196L,35197L,\n35198L,35199L,35200L,35201L,35202L,35203L,35204L,35205L,35206L,35207L,\n35208L,35209L,35210L,35211L,35212L,35213L,35214L,35215L,35216L,35217L,\n35218L,35219L,35220L,35221L,35222L,35223L,35224L,35225L,35226L,35227L,\n35228L,35229L,35230L,35231L,35232L,35233L,35234L,35235L,35236L,35237L,\n35238L,35239L,35240L,35241L,35242L,35243L,35244L,35245L,35246L,35247L,\n35248L,35249L,35250L,35251L,35252L,35253L,35254L,35255L,35256L,35257L,\n35258L,35259L,35260L,35261L,35262L,35263L,35264L,35265L,35266L,35267L,\n35268L,35269L,35270L,35271L,35272L,35273L,35274L,35275L,35276L,35277L,\n35278L,35279L,35280L,35281L,35282L,35283L,35284L,35285L,35286L,35287L,\n35288L,35289L,35290L,35291L,35292L,35293L,35294L,35295L,35296L,35297L,\n35298L,35299L,35300L,35301L,35302L,35303L,35304L,35305L,35306L,35307L,\n35308L,35309L,35310L,35311L,35312L,35313L,35314L,35315L,35316L,35317L,\n35318L,35319L,35320L,35321L,35322L,35323L,35324L,35325L,35326L,35327L,\n35328L,35329L,35330L,35331L,35332L,35333L,35334L,35335L,35336L,35337L,\n35338L,35339L,35340L,35341L,35342L,35343L,35344L,35345L,35346L,35347L,\n35348L,35349L,35350L,35351L,35352L,35353L,35354L,35355L,35356L,35357L,\n35358L,35359L,35360L,35361L,35362L,35363L,35364L,35365L,35366L,35367L,\n35368L,35369L,35370L,35371L,35372L,35373L,35374L,35375L,35376L,35377L,\n35378L,35379L,35380L,35381L,35382L,35383L,35384L,35385L,35386L,35387L,\n35388L,35389L,35390L,35391L,35392L,35393L,35394L,35395L,35396L,35397L,\n35398L,35399L,35400L,35401L,35402L,35403L,35404L,35405L,35406L,35407L,\n35408L,35409L,35410L,35411L,35412L,35413L,35414L,35415L,35416L,35417L,\n35418L,35419L,35420L,35421L,35422L,35423L,35424L,35425L,35426L,35427L,\n35428L,35429L,35430L,35431L,35432L,35433L,35434L,35435L,35436L,35437L,\n35438L,35439L,35440L,35441L,35442L,35443L,35444L,35445L,35446L,35447L,\n35448L,35449L,35450L,35451L,35452L,35453L,35454L,35455L,35456L,35457L,\n35458L,35459L,35460L,35461L,35462L,35463L,35464L,35465L,35466L,35467L,\n35468L,35469L,35470L,35471L,35472L,35473L,35474L,35475L,35476L,35477L,\n35478L,35479L,35480L,35481L,35482L,35483L,35484L,35485L,35486L,35487L,\n35488L,35489L,35490L,35491L,35492L,35493L,35494L,35495L,35496L,35497L,\n35498L,35499L,35500L,35501L,35502L,35503L,35504L,35505L,35506L,35507L,\n35508L,35509L,35510L,35511L,35512L,35513L,35514L,35515L,35516L,35517L,\n35518L,35519L,35520L,35521L,35522L,35523L,35524L,35525L,35526L,35527L,\n35528L,35529L,35530L,35531L,35532L,35533L,35534L,35535L,35536L,35537L,\n35538L,35539L,35540L,35541L,35542L,35543L,35544L,35545L,35546L,35547L,\n35548L,35549L,35550L,35551L,35552L,35553L,35554L,35555L,35556L,35557L,\n35558L,35559L,35560L,35561L,35562L,35563L,35564L,35565L,35566L,35567L,\n35568L,35569L,35570L,35571L,35572L,35573L,35574L,35575L,35576L,35577L,\n35578L,35579L,35580L,35581L,35582L,35583L,35584L,35585L,35586L,35587L,\n35588L,35589L,35590L,35591L,35592L,35593L,35594L,35595L,35596L,35597L,\n35598L,35599L,35600L,35601L,35602L,35603L,35604L,35605L,35606L,35607L,\n35608L,35609L,35610L,35611L,35612L,35613L,35614L,35615L,35616L,35617L,\n35618L,35619L,35620L,35621L,35622L,35623L,35624L,35625L,35626L,35627L,\n35628L,35629L,35630L,35631L,35632L,35633L,35634L,35635L,35636L,35637L,\n35638L,35639L,35640L,35641L,35642L,35643L,35644L,35645L,35646L,35647L,\n35648L,35649L,35650L,35651L,35652L,35653L,35654L,35655L,35656L,35657L,\n35658L,35659L,35660L,35661L,35662L,35663L,35664L,35665L,35666L,35667L,\n35668L,35669L,35670L,35671L,35672L,35673L,35674L,35675L,35676L,35677L,\n35678L,35679L,35680L,35681L,35682L,35683L,35684L,35685L,35686L,35687L,\n35688L,35689L,35690L,35691L,35692L,35693L,35694L,35695L,35696L,35697L,\n35698L,35699L,35700L,35701L,35702L,35703L,35704L,35705L,35706L,35707L,\n35708L,35709L,35710L,35711L,35712L,35713L,35714L,35715L,35716L,35717L,\n35718L,35719L,35720L,35721L,35722L,35723L,35724L,35725L,35726L,35727L,\n35728L,35729L,35730L,35731L,35732L,35733L,35734L,35735L,35736L,35737L,\n35738L,35739L,35740L,35741L,35742L,35743L,35744L,35745L,35746L,35747L,\n35748L,35749L,35750L,35751L,35752L,35753L,35754L,35755L,35756L,35757L,\n35758L,35759L,35760L,35761L,35762L,35763L,35764L,35765L,35766L,35767L,\n35768L,35769L,35770L,35771L,35772L,35773L,35774L,35775L,35776L,35777L,\n35778L,35779L,35780L,35781L,35782L,35783L,35784L,35785L,35786L,35787L,\n35788L,35789L,35790L,35791L,35792L,35793L,35794L,35795L,35796L,35797L,\n35798L,35799L,35800L,35801L,35802L,35803L,35804L,35805L,35806L,35807L,\n35808L,35809L,35810L,35811L,35812L,35813L,35814L,35815L,35816L,35817L,\n35818L,35819L,35820L,35821L,35822L,35823L,35824L,35825L,35826L,35827L,\n35828L,35829L,35830L,35831L,35832L,35833L,35834L,35835L,35836L,35837L,\n35838L,35839L,35840L,35841L,35842L,35843L,35844L,35845L,35846L,35847L,\n35848L,35849L,35850L,35851L,35852L,35853L,35854L,35855L,35856L,35857L,\n35858L,35859L,35860L,35861L,35862L,35863L,35864L,35865L,35866L,35867L,\n35868L,35869L,35870L,35871L,35872L,35873L,35874L,35875L,35876L,35877L,\n35878L,35879L,35880L,35881L,35882L,35883L,35884L,35885L,35886L,35887L,\n35888L,35889L,35890L,35891L,35892L,35893L,35894L,35895L,35896L,35897L,\n35898L,35899L,35900L,35901L,35902L,35903L,35904L,35905L,35906L,35907L,\n35908L,35909L,35910L,35911L,35912L,35913L,35914L,35915L,35916L,35917L,\n35918L,35919L,35920L,35921L,35922L,35923L,35924L,35925L,35926L,35927L,\n35928L,35929L,35930L,35931L,35932L,35933L,35934L,35935L,35936L,35937L,\n35938L,35939L,35940L,35941L,35942L,35943L,35944L,35945L,35946L,35947L,\n35948L,35949L,35950L,35951L,35952L,35953L,35954L,35955L,35956L,35957L,\n35958L,35959L,35960L,35961L,35962L,35963L,35964L,35965L,35966L,35967L,\n35968L,35969L,35970L,35971L,35972L,35973L,35974L,35975L,35976L,35977L,\n35978L,35979L,35980L,35981L,35982L,35983L,35984L,35985L,35986L,35987L,\n35988L,35989L,35990L,35991L,35992L,35993L,35994L,35995L,35996L,35997L,\n35998L,35999L,36000L,36001L,36002L,36003L,36004L,36005L,36006L,36007L,\n36008L,36009L,36010L,36011L,36012L,36013L,36014L,36015L,36016L,36017L,\n36018L,36019L,36020L,36021L,36022L,36023L,36024L,36025L,36026L,36027L,\n36028L,36029L,36030L,36031L,36032L,36033L,36034L,36035L,36036L,36037L,\n36038L,36039L,36040L,36041L,36042L,36043L,36044L,36045L,36046L,36047L,\n36048L,36049L,36050L,36051L,36052L,36053L,36054L,36055L,36056L,36057L,\n36058L,36059L,36060L,36061L,36062L,36063L,36064L,36065L,36066L,36067L,\n36068L,36069L,36070L,36071L,36072L,36073L,36074L,36075L,36076L,36077L,\n36078L,36079L,36080L,36081L,36082L,36083L,36084L,36085L,36086L,36087L,\n36088L,36089L,36090L,36091L,36092L,36093L,36094L,36095L,36096L,36097L,\n36098L,36099L,36100L,36101L,36102L,36103L,36104L,36105L,36106L,36107L,\n36108L,36109L,36110L,36111L,36112L,36113L,36114L,36115L,36116L,36117L,\n36118L,36119L,36120L,36121L,36122L,36123L,36124L,36125L,36126L,36127L,\n36128L,36129L,36130L,36131L,36132L,36133L,36134L,36135L,36136L,36137L,\n36138L,36139L,36140L,36141L,36142L,36143L,36144L,36145L,36146L,36147L,\n36148L,36149L,36150L,36151L,36152L,36153L,36154L,36155L,36156L,36157L,\n36158L,36159L,36160L,36161L,36162L,36163L,36164L,36165L,36166L,36167L,\n36168L,36169L,36170L,36171L,36172L,36173L,36174L,36175L,36176L,36177L,\n36178L,36179L,36180L,36181L,36182L,36183L,36184L,36185L,36186L,36187L,\n36188L,36189L,36190L,36191L,36192L,36193L,36194L,36195L,36196L,36197L,\n36198L,36199L,36200L,36201L,36202L,36203L,36204L,36205L,36206L,36207L,\n36208L,36209L,36210L,36211L,36212L,36213L,36214L,36215L,36216L,36217L,\n36218L,36219L,36220L,36221L,36222L,36223L,36224L,36225L,36226L,36227L,\n36228L,36229L,36230L,36231L,36232L,36233L,36234L,36235L,36236L,36237L,\n36238L,36239L,36240L,36241L,36242L,36243L,36244L,36245L,36246L,36247L,\n36248L,36249L,36250L,36251L,36252L,36253L,36254L,36255L,36256L,36257L,\n36258L,36259L,36260L,36261L,36262L,36263L,36264L,36265L,36266L,36267L,\n36268L,36269L,36270L,36271L,36272L,36273L,36274L,36275L,36276L,36277L,\n36278L,36279L,36280L,36281L,36282L,36283L,36284L,36285L,36286L,36287L,\n36288L,36289L,36290L,36291L,36292L,36293L,36294L,36295L,36296L,36297L,\n36298L,36299L,36300L,36301L,36302L,36303L,36304L,36305L,36306L,36307L,\n36308L,36309L,36310L,36311L,36312L,36313L,36314L,36315L,36316L,36317L,\n36318L,36319L,36320L,36321L,36322L,36323L,36324L,36325L,36326L,36327L,\n36328L,36329L,36330L,36331L,36332L,36333L,36334L,36335L,36336L,36337L,\n36338L,36339L,36340L,36341L,36342L,36343L,36344L,36345L,36346L,36347L,\n36348L,36349L,36350L,36351L,36352L,36353L,36354L,36355L,36356L,36357L,\n36358L,36359L,36360L,36361L,36362L,36363L,36364L,36365L,36366L,36367L,\n36368L,36369L,36370L,36371L,36372L,36373L,36374L,36375L,36376L,36377L,\n36378L,36379L,36380L,36381L,36382L,36383L,36384L,36385L,36386L,36387L,\n36388L,36389L,36390L,36391L,36392L,36393L,36394L,36395L,36396L,36397L,\n36398L,36399L,36400L,36401L,36402L,36403L,36404L,36405L,36406L,36407L,\n36408L,36409L,36410L,36411L,36412L,36413L,36414L,36415L,36416L,36417L,\n36418L,36419L,36420L,36421L,36422L,36423L,36424L,36425L,36426L,36427L,\n36428L,36429L,36430L,36431L,36432L,36433L,36434L,36435L,36436L,36437L,\n36438L,36439L,36440L,36441L,36442L,36443L,36444L,36445L,36446L,36447L,\n36448L,36449L,36450L,36451L,36452L,36453L,36454L,36455L,36456L,36457L,\n36458L,36459L,36460L,36461L,36462L,36463L,36464L,36465L,36466L,36467L,\n36468L,36469L,36470L,36471L,36472L,36473L,36474L,36475L,36476L,36477L,\n36478L,36479L,36480L,36481L,36482L,36483L,36484L,36485L,36486L,36487L,\n36488L,36489L,36490L,36491L,36492L,36493L,36494L,36495L,36496L,36497L,\n36498L,36499L,36500L,36501L,36502L,36503L,36504L,36505L,36506L,36507L,\n36508L,36509L,36510L,36511L,36512L,36513L,36514L,36515L,36516L,36517L,\n36518L,36519L,36520L,36521L,36522L,36523L,36524L,36525L,36526L,36527L,\n36528L,36529L,36530L,36531L,36532L,36533L,36534L,36535L,36536L,36537L,\n36538L,36539L,36540L,36541L,36542L,36543L,36544L,36545L,36546L,36547L,\n36548L,36549L,36550L,36551L,36552L,36553L,36554L,36555L,36556L,36557L,\n36558L,36559L,36560L,36561L,36562L,36563L,36564L,36565L,36566L,36567L,\n36568L,36569L,36570L,36571L,36572L,36573L,36574L,36575L,36576L,36577L,\n36578L,36579L,36580L,36581L,36582L,36583L,36584L,36585L,36586L,36587L,\n36588L,36589L,36590L,36591L,36592L,36593L,36594L,36595L,36596L,36597L,\n36598L,36599L,36600L,36601L,36602L,36603L,36604L,36605L,36606L,36607L,\n36608L,36609L,36610L,36611L,36612L,36613L,36614L,36615L,36616L,36617L,\n36618L,36619L,36620L,36621L,36622L,36623L,36624L,36625L,36626L,36627L,\n36628L,36629L,36630L,36631L,36632L,36633L,36634L,36635L,36636L,36637L,\n36638L,36639L,36640L,36641L,36642L,36643L,36644L,36645L,36646L,36647L,\n36648L,36649L,36650L,36651L,36652L,36653L,36654L,36655L,36656L,36657L,\n36658L,36659L,36660L,36661L,36662L,36663L,36664L,36665L,36666L,36667L,\n36668L,36669L,36670L,36671L,36672L,36673L,36674L,36675L,36676L,36677L,\n36678L,36679L,36680L,36681L,36682L,36683L,36684L,36685L,36686L,36687L,\n36688L,36689L,36690L,36691L,36692L,36693L,36694L,36695L,36696L,36697L,\n36698L,36699L,36700L,36701L,36702L,36703L,36704L,36705L,36706L,36707L,\n36708L,36709L,36710L,36711L,36712L,36713L,36714L,36715L,36716L,36717L,\n36718L,36719L,36720L,36721L,36722L,36723L,36724L,36725L,36726L,36727L,\n36728L,36729L,36730L,36731L,36732L,36733L,36734L,36735L,36736L,36737L,\n36738L,36739L,36740L,36741L,36742L,36743L,36744L,36745L,36746L,36747L,\n36748L,36749L,36750L,36751L,36752L,36753L,36754L,36755L,36756L,36757L,\n36758L,36759L,36760L,36761L,36762L,36763L,36764L,36765L,36766L,36767L,\n36768L,36769L,36770L,36771L,36772L,36773L,36774L,36775L,36776L,36777L,\n36778L,36779L,36780L,36781L,36782L,36783L,36784L,36785L,36786L,36787L,\n36788L,36789L,36790L,36791L,36792L,36793L,36794L,36795L,36796L,36797L,\n36798L,36799L,36800L,36801L,36802L,36803L,36804L,36805L,36806L,36807L,\n36808L,36809L,36810L,36811L,36812L,36813L,36814L,36815L,36816L,36817L,\n36818L,36819L,36820L,36821L,36822L,36823L,36824L,36825L,36826L,36827L,\n36828L,36829L,36830L,36831L,36832L,36833L,36834L,36835L,36836L,36837L,\n36838L,36839L,36840L,36841L,36842L,36843L,36844L,36845L,36846L,36847L,\n36848L,36849L,36850L,36851L,36852L,36853L,36854L,36855L,36856L,36857L,\n36858L,36859L,36860L,36861L,36862L,36863L,36864L,36865L,36866L,36867L,\n36868L,36869L,36870L,36871L,36872L,36873L,36874L,36875L,36876L,36877L,\n36878L,36879L,36880L,36881L,36882L,36883L,36884L,36885L,36886L,36887L,\n36888L,36889L,36890L,36891L,36892L,36893L,36894L,36895L,36896L,36897L,\n36898L,36899L,36900L,36901L,36902L,36903L,36904L,36905L,36906L,36907L,\n36908L,36909L,36910L,36911L,36912L,36913L,36914L,36915L,36916L,36917L,\n36918L,36919L,36920L,36921L,36922L,36923L,36924L,36925L,36926L,36927L,\n36928L,36929L,36930L,36931L,36932L,36933L,36934L,36935L,36936L,36937L,\n36938L,36939L,36940L,36941L,36942L,36943L,36944L,36945L,36946L,36947L,\n36948L,36949L,36950L,36951L,36952L,36953L,36954L,36955L,36956L,36957L,\n36958L,36959L,36960L,36961L,36962L,36963L,36964L,36965L,36966L,36967L,\n36968L,36969L,36970L,36971L,36972L,36973L,36974L,36975L,36976L,36977L,\n36978L,36979L,36980L,36981L,36982L,36983L,36984L,36985L,36986L,36987L,\n36988L,36989L,36990L,36991L,36992L,36993L,36994L,36995L,36996L,36997L,\n36998L,36999L,37000L,37001L,37002L,37003L,37004L,37005L,37006L,37007L,\n37008L,37009L,37010L,37011L,37012L,37013L,37014L,37015L,37016L,37017L,\n37018L,37019L,37020L,37021L,37022L,37023L,37024L,37025L,37026L,37027L,\n37028L,37029L,37030L,37031L,37032L,37033L,37034L,37035L,37036L,37037L,\n37038L,37039L,37040L,37041L,37042L,37043L,37044L,37045L,37046L,37047L,\n37048L,37049L,37050L,37051L,37052L,37053L,37054L,37055L,37056L,37057L,\n37058L,37059L,37060L,37061L,37062L,37063L,37064L,37065L,37066L,37067L,\n37068L,37069L,37070L,37071L,37072L,37073L,37074L,37075L,37076L,37077L,\n37078L,37079L,37080L,37081L,37082L,37083L,37084L,37085L,37086L,37087L,\n37088L,37089L,37090L,37091L,37092L,37093L,37094L,37095L,37096L,37097L,\n37098L,37099L,37100L,37101L,37102L,37103L,37104L,37105L,37106L,37107L,\n37108L,37109L,37110L,37111L,37112L,37113L,37114L,37115L,37116L,37117L,\n37118L,37119L,37120L,37121L,37122L,37123L,37124L,37125L,37126L,37127L,\n37128L,37129L,37130L,37131L,37132L,37133L,37134L,37135L,37136L,37137L,\n37138L,37139L,37140L,37141L,37142L,37143L,37144L,37145L,37146L,37147L,\n37148L,37149L,37150L,37151L,37152L,37153L,37154L,37155L,37156L,37157L,\n37158L,37159L,37160L,37161L,37162L,37163L,37164L,37165L,37166L,37167L,\n37168L,37169L,37170L,37171L,37172L,37173L,37174L,37175L,37176L,37177L,\n37178L,37179L,37180L,37181L,37182L,37183L,37184L,37185L,37186L,37187L,\n37188L,37189L,37190L,37191L,37192L,37193L,37194L,37195L,37196L,37197L,\n37198L,37199L,37200L,37201L,37202L,37203L,37204L,37205L,37206L,37207L,\n37208L,37209L,37210L,37211L,37212L,37213L,37214L,37215L,37216L,37217L,\n37218L,37219L,37220L,37221L,37222L,37223L,37224L,37225L,37226L,37227L,\n37228L,37229L,37230L,37231L,37232L,37233L,37234L,37235L,37236L,37237L,\n37238L,37239L,37240L,37241L,37242L,37243L,37244L,37245L,37246L,37247L,\n37248L,37249L,37250L,37251L,37252L,37253L,37254L,37255L,37256L,37257L,\n37258L,37259L,37260L,37261L,37262L,37263L,37264L,37265L,37266L,37267L,\n37268L,37269L,37270L,37271L,37272L,37273L,37274L,37275L,37276L,37277L,\n37278L,37279L,37280L,37281L,37282L,37283L,37284L,37285L,37286L,37287L,\n37288L,37289L,37290L,37291L,37292L,37293L,37294L,37295L,37296L,37297L,\n37298L,37299L,37300L,37301L,37302L,37303L,37304L,37305L,37306L,37307L,\n37308L,37309L,37310L,37311L,37312L,37313L,37314L,37315L,37316L,37317L,\n37318L,37319L,37320L,37321L,37322L,37323L,37324L,37325L,37326L,37327L,\n37328L,37329L,37330L,37331L,37332L,37333L,37334L,37335L,37336L,37337L,\n37338L,37339L,37340L,37341L,37342L,37343L,37344L,37345L,37346L,37347L,\n37348L,37349L,37350L,37351L,37352L,37353L,37354L,37355L,37356L,37357L,\n37358L,37359L,37360L,37361L,37362L,37363L,37364L,37365L,37366L,37367L,\n37368L,37369L,37370L,37371L,37372L,37373L,37374L,37375L,37376L,37377L,\n37378L,37379L,37380L,37381L,37382L,37383L,37384L,37385L,37386L,37387L,\n37388L,37389L,37390L,37391L,37392L,37393L,37394L,37395L,37396L,37397L,\n37398L,37399L,37400L,37401L,37402L,37403L,37404L,37405L,37406L,37407L,\n37408L,37409L,37410L,37411L,37412L,37413L,37414L,37415L,37416L,37417L,\n37418L,37419L,37420L,37421L,37422L,37423L,37424L,37425L,37426L,37427L,\n37428L,37429L,37430L,37431L,37432L,37433L,37434L,37435L,37436L,37437L,\n37438L,37439L,37440L,37441L,37442L,37443L,37444L,37445L,37446L,37447L,\n37448L,37449L,37450L,37451L,37452L,37453L,37454L,37455L,37456L,37457L,\n37458L,37459L,37460L,37461L,37462L,37463L,37464L,37465L,37466L,37467L,\n37468L,37469L,37470L,37471L,37472L,37473L,37474L,37475L,37476L,37477L,\n37478L,37479L,37480L,37481L,37482L,37483L,37484L,37485L,37486L,37487L,\n37488L,37489L,37490L,37491L,37492L,37493L,37494L,37495L,37496L,37497L,\n37498L,37499L,37500L,37501L,37502L,37503L,37504L,37505L,37506L,37507L,\n37508L,37509L,37510L,37511L,37512L,37513L,37514L,37515L,37516L,37517L,\n37518L,37519L,37520L,37521L,37522L,37523L,37524L,37525L,37526L,37527L,\n37528L,37529L,37530L,37531L,37532L,37533L,37534L,37535L,37536L,37537L,\n37538L,37539L,37540L,37541L,37542L,37543L,37544L,37545L,37546L,37547L,\n37548L,37549L,37550L,37551L,37552L,37553L,37554L,37555L,37556L,37557L,\n37558L,37559L,37560L,37561L,37562L,37563L,37564L,37565L,37566L,37567L,\n37568L,37569L,37570L,37571L,37572L,37573L,37574L,37575L,37576L,37577L,\n37578L,37579L,37580L,37581L,37582L,37583L,37584L,37585L,37586L,37587L,\n37588L,37589L,37590L,37591L,37592L,37593L,37594L,37595L,37596L,37597L,\n37598L,37599L,37600L,37601L,37602L,37603L,37604L,37605L,37606L,37607L,\n37608L,37609L,37610L,37611L,37612L,37613L,37614L,37615L,37616L,37617L,\n37618L,37619L,37620L,37621L,37622L,37623L,37624L,37625L,37626L,37627L,\n37628L,37629L,37630L,37631L,37632L,37633L,37634L,37635L,37636L,37637L,\n37638L,37639L,37640L,37641L,37642L,37643L,37644L,37645L,37646L,37647L,\n37648L,37649L,37650L,37651L,37652L,37653L,37654L,37655L,37656L,37657L,\n37658L,37659L,37660L,37661L,37662L,37663L,37664L,37665L,37666L,37667L,\n37668L,37669L,37670L,37671L,37672L,37673L,37674L,37675L,37676L,37677L,\n37678L,37679L,37680L,37681L,37682L,37683L,37684L,37685L,37686L,37687L,\n37688L,37689L,37690L,37691L,37692L,37693L,37694L,37695L,37696L,37697L,\n37698L,37699L,37700L,37701L,37702L,37703L,37704L,37705L,37706L,37707L,\n37708L,37709L,37710L,37711L,37712L,37713L,37714L,37715L,37716L,37717L,\n37718L,37719L,37720L,37721L,37722L,37723L,37724L,37725L,37726L,37727L,\n37728L,37729L,37730L,37731L,37732L,37733L,37734L,37735L,37736L,37737L,\n37738L,37739L,37740L,37741L,37742L,37743L,37744L,37745L,37746L,37747L,\n37748L,37749L,37750L,37751L,37752L,37753L,37754L,37755L,37756L,37757L,\n37758L,37759L,37760L,37761L,37762L,37763L,37764L,37765L,37766L,37767L,\n37768L,37769L,37770L,37771L,37772L,37773L,37774L,37775L,37776L,37777L,\n37778L,37779L,37780L,37781L,37782L,37783L,37784L,37785L,37786L,37787L,\n37788L,37789L,37790L,37791L,37792L,37793L,37794L,37795L,37796L,37797L,\n37798L,37799L,37800L,37801L,37802L,37803L,37804L,37805L,37806L,37807L,\n37808L,37809L,37810L,37811L,37812L,37813L,37814L,37815L,37816L,37817L,\n37818L,37819L,37820L,37821L,37822L,37823L,37824L,37825L,37826L,37827L,\n37828L,37829L,37830L,37831L,37832L,37833L,37834L,37835L,37836L,37837L,\n37838L,37839L,37840L,37841L,37842L,37843L,37844L,37845L,37846L,37847L,\n37848L,37849L,37850L,37851L,37852L,37853L,37854L,37855L,37856L,37857L,\n37858L,37859L,37860L,37861L,37862L,37863L,37864L,37865L,37866L,37867L,\n37868L,37869L,37870L,37871L,37872L,37873L,37874L,37875L,37876L,37877L,\n37878L,37879L,37880L,37881L,37882L,37883L,37884L,37885L,37886L,37887L,\n37888L,37889L,37890L,37891L,37892L,37893L,37894L,37895L,37896L,37897L,\n37898L,37899L,37900L,37901L,37902L,37903L,37904L,37905L,37906L,37907L,\n37908L,37909L,37910L,37911L,37912L,37913L,37914L,37915L,37916L,37917L,\n37918L,37919L,37920L,37921L,37922L,37923L,37924L,37925L,37926L,37927L,\n37928L,37929L,37930L,37931L,37932L,37933L,37934L,37935L,37936L,37937L,\n37938L,37939L,37940L,37941L,37942L,37943L,37944L,37945L,37946L,37947L,\n37948L,37949L,37950L,37951L,37952L,37953L,37954L,37955L,37956L,37957L,\n37958L,37959L,37960L,37961L,37962L,37963L,37964L,37965L,37966L,37967L,\n37968L,37969L,37970L,37971L,37972L,37973L,37974L,37975L,37976L,37977L,\n37978L,37979L,37980L,37981L,37982L,37983L,37984L,37985L,37986L,37987L,\n37988L,37989L,37990L,37991L,37992L,37993L,37994L,37995L,37996L,37997L,\n37998L,37999L,38000L,38001L,38002L,38003L,38004L,38005L,38006L,38007L,\n38008L,38009L,38010L,38011L,38012L,38013L,38014L,38015L,38016L,38017L,\n38018L,38019L,38020L,38021L,38022L,38023L,38024L,38025L,38026L,38027L,\n38028L,38029L,38030L,38031L,38032L,38033L,38034L,38035L,38036L,38037L,\n38038L,38039L,38040L,38041L,38042L,38043L,38044L,38045L,38046L,38047L,\n38048L,38049L,38050L,38051L,38052L,38053L,38054L,38055L,38056L,38057L,\n38058L,38059L,38060L,38061L,38062L,38063L,38064L,38065L,38066L,38067L,\n38068L,38069L,38070L,38071L,38072L,38073L,38074L,38075L,38076L,38077L,\n38078L,38079L,38080L,38081L,38082L,38083L,38084L,38085L,38086L,38087L,\n38088L,38089L,38090L,38091L,38092L,38093L,38094L,38095L,38096L,38097L,\n38098L,38099L,38100L,38101L,38102L,38103L,38104L,38105L,38106L,38107L,\n38108L,38109L,38110L,38111L,38112L,38113L,38114L,38115L,38116L,38117L,\n38118L,38119L,38120L,38121L,38122L,38123L,38124L,38125L,38126L,38127L,\n38128L,38129L,38130L,38131L,38132L,38133L,38134L,38135L,38136L,38137L,\n38138L,38139L,38140L,38141L,38142L,38143L,38144L,38145L,38146L,38147L,\n38148L,38149L,38150L,38151L,38152L,38153L,38154L,38155L,38156L,38157L,\n38158L,38159L,38160L,38161L,38162L,38163L,38164L,38165L,38166L,38167L,\n38168L,38169L,38170L,38171L,38172L,38173L,38174L,38175L,38176L,38177L,\n38178L,38179L,38180L,38181L,38182L,38183L,38184L,38185L,38186L,38187L,\n38188L,38189L,38190L,38191L,38192L,38193L,38194L,38195L,38196L,38197L,\n38198L,38199L,38200L,38201L,38202L,38203L,38204L,38205L,38206L,38207L,\n38208L,38209L,38210L,38211L,38212L,38213L,38214L,38215L,38216L,38217L,\n38218L,38219L,38220L,38221L,38222L,38223L,38224L,38225L,38226L,38227L,\n38228L,38229L,38230L,38231L,38232L,38233L,38234L,38235L,38236L,38237L,\n38238L,38239L,38240L,38241L,38242L,38243L,38244L,38245L,38246L,38247L,\n38248L,38249L,38250L,38251L,38252L,38253L,38254L,38255L,38256L,38257L,\n38258L,38259L,38260L,38261L,38262L,38263L,38264L,38265L,38266L,38267L,\n38268L,38269L,38270L,38271L,38272L,38273L,38274L,38275L,38276L,38277L,\n38278L,38279L,38280L,38281L,38282L,38283L,38284L,38285L,38286L,38287L,\n38288L,38289L,38290L,38291L,38292L,38293L,38294L,38295L,38296L,38297L,\n38298L,38299L,38300L,38301L,38302L,38303L,38304L,38305L,38306L,38307L,\n38308L,38309L,38310L,38311L,38312L,38313L,38314L,38315L,38316L,38317L,\n38318L,38319L,38320L,38321L,38322L,38323L,38324L,38325L,38326L,38327L,\n38328L,38329L,38330L,38331L,38332L,38333L,38334L,38335L,38336L,38337L,\n38338L,38339L,38340L,38341L,38342L,38343L,38344L,38345L,38346L,38347L,\n38348L,38349L,38350L,38351L,38352L,38353L,38354L,38355L,38356L,38357L,\n38358L,38359L,38360L,38361L,38362L,38363L,38364L,38365L,38366L,38367L,\n38368L,38369L,38370L,38371L,38372L,38373L,38374L,38375L,38376L,38377L,\n38378L,38379L,38380L,38381L,38382L,38383L,38384L,38385L,38386L,38387L,\n38388L,38389L,38390L,38391L,38392L,38393L,38394L,38395L,38396L,38397L,\n38398L,38399L,38400L,38401L,38402L,38403L,38404L,38405L,38406L,38407L,\n38408L,38409L,38410L,38411L,38412L,38413L,38414L,38415L,38416L,38417L,\n38418L,38419L,38420L,38421L,38422L,38423L,38424L,38425L,38426L,38427L,\n38428L,38429L,38430L,38431L,38432L,38433L,38434L,38435L,38436L,38437L,\n38438L,38439L,38440L,38441L,38442L,38443L,38444L,38445L,38446L,38447L,\n38448L,38449L,38450L,38451L,38452L,38453L,38454L,38455L,38456L,38457L,\n38458L,38459L,38460L,38461L,38462L,38463L,38464L,38465L,38466L,38467L,\n38468L,38469L,38470L,38471L,38472L,38473L,38474L,38475L,38476L,38477L,\n38478L,38479L,38480L,38481L,38482L,38483L,38484L,38485L,38486L,38487L,\n38488L,38489L,38490L,38491L,38492L,38493L,38494L,38495L,38496L,38497L,\n38498L,38499L,38500L,38501L,38502L,38503L,38504L,38505L,38506L,38507L,\n38508L,38509L,38510L,38511L,38512L,38513L,38514L,38515L,38516L,38517L,\n38518L,38519L,38520L,38521L,38522L,38523L,38524L,38525L,38526L,38527L,\n38528L,38529L,38530L,38531L,38532L,38533L,38534L,38535L,38536L,38537L,\n38538L,38539L,38540L,38541L,38542L,38543L,38544L,38545L,38546L,38547L,\n38548L,38549L,38550L,38551L,38552L,38553L,38554L,38555L,38556L,38557L,\n38558L,38559L,38560L,38561L,38562L,38563L,38564L,38565L,38566L,38567L,\n38568L,38569L,38570L,38571L,38572L,38573L,38574L,38575L,38576L,38577L,\n38578L,38579L,38580L,38581L,38582L,38583L,38584L,38585L,38586L,38587L,\n38588L,38589L,38590L,38591L,38592L,38593L,38594L,38595L,38596L,38597L,\n38598L,38599L,38600L,38601L,38602L,38603L,38604L,38605L,38606L,38607L,\n38608L,38609L,38610L,38611L,38612L,38613L,38614L,38615L,38616L,38617L,\n38618L,38619L,38620L,38621L,38622L,38623L,38624L,38625L,38626L,38627L,\n38628L,38629L,38630L,38631L,38632L,38633L,38634L,38635L,38636L,38637L,\n38638L,38639L,38640L,38641L,38642L,38643L,38644L,38645L,38646L,38647L,\n38648L,38649L,38650L,38651L,38652L,38653L,38654L,38655L,38656L,38657L,\n38658L,38659L,38660L,38661L,38662L,38663L,38664L,38665L,38666L,38667L,\n38668L,38669L,38670L,38671L,38672L,38673L,38674L,38675L,38676L,38677L,\n38678L,38679L,38680L,38681L,38682L,38683L,38684L,38685L,38686L,38687L,\n38688L,38689L,38690L,38691L,38692L,38693L,38694L,38695L,38696L,38697L,\n38698L,38699L,38700L,38701L,38702L,38703L,38704L,38705L,38706L,38707L,\n38708L,38709L,38710L,38711L,38712L,38713L,38714L,38715L,38716L,38717L,\n38718L,38719L,38720L,38721L,38722L,38723L,38724L,38725L,38726L,38727L,\n38728L,38729L,38730L,38731L,38732L,38733L,38734L,38735L,38736L,38737L,\n38738L,38739L,38740L,38741L,38742L,38743L,38744L,38745L,38746L,38747L,\n38748L,38749L,38750L,38751L,38752L,38753L,38754L,38755L,38756L,38757L,\n38758L,38759L,38760L,38761L,38762L,38763L,38764L,38765L,38766L,38767L,\n38768L,38769L,38770L,38771L,38772L,38773L,38774L,38775L,38776L,38777L,\n38778L,38779L,38780L,38781L,38782L,38783L,38784L,38785L,38786L,38787L,\n38788L,38789L,38790L,38791L,38792L,38793L,38794L,38795L,38796L,38797L,\n38798L,38799L,38800L,38801L,38802L,38803L,38804L,38805L,38806L,38807L,\n38808L,38809L,38810L,38811L,38812L,38813L,38814L,38815L,38816L,38817L,\n38818L,38819L,38820L,38821L,38822L,38823L,38824L,38825L,38826L,38827L,\n38828L,38829L,38830L,38831L,38832L,38833L,38834L,38835L,38836L,38837L,\n38838L,38839L,38840L,38841L,38842L,38843L,38844L,38845L,38846L,38847L,\n38848L,38849L,38850L,38851L,38852L,38853L,38854L,38855L,38856L,38857L,\n38858L,38859L,38860L,38861L,38862L,38863L,38864L,38865L,38866L,38867L,\n38868L,38869L,38870L,38871L,38872L,38873L,38874L,38875L,38876L,38877L,\n38878L,38879L,38880L,38881L,38882L,38883L,38884L,38885L,38886L,38887L,\n38888L,38889L,38890L,38891L,38892L,38893L,38894L,38895L,38896L,38897L,\n38898L,38899L,38900L,38901L,38902L,38903L,38904L,38905L,38906L,38907L,\n38908L,38909L,38910L,38911L,38912L,38913L,38914L,38915L,38916L,38917L,\n38918L,38919L,38920L,38921L,38922L,38923L,38924L,38925L,38926L,38927L,\n38928L,38929L,38930L,38931L,38932L,38933L,38934L,38935L,38936L,38937L,\n38938L,38939L,38940L,38941L,38942L,38943L,38944L,38945L,38946L,38947L,\n38948L,38949L,38950L,38951L,38952L,38953L,38954L,38955L,38956L,38957L,\n38958L,38959L,38960L,38961L,38962L,38963L,38964L,38965L,38966L,38967L,\n38968L,38969L,38970L,38971L,38972L,38973L,38974L,38975L,38976L,38977L,\n38978L,38979L,38980L,38981L,38982L,38983L,38984L,38985L,38986L,38987L,\n38988L,38989L,38990L,38991L,38992L,38993L,38994L,38995L,38996L,38997L,\n38998L,38999L,39000L,39001L,39002L,39003L,39004L,39005L,39006L,39007L,\n39008L,39009L,39010L,39011L,39012L,39013L,39014L,39015L,39016L,39017L,\n39018L,39019L,39020L,39021L,39022L,39023L,39024L,39025L,39026L,39027L,\n39028L,39029L,39030L,39031L,39032L,39033L,39034L,39035L,39036L,39037L,\n39038L,39039L,39040L,39041L,39042L,39043L,39044L,39045L,39046L,39047L,\n39048L,39049L,39050L,39051L,39052L,39053L,39054L,39055L,39056L,39057L,\n39058L,39059L,39060L,39061L,39062L,39063L,39064L,39065L,39066L,39067L,\n39068L,39069L,39070L,39071L,39072L,39073L,39074L,39075L,39076L,39077L,\n39078L,39079L,39080L,39081L,39082L,39083L,39084L,39085L,39086L,39087L,\n39088L,39089L,39090L,39091L,39092L,39093L,39094L,39095L,39096L,39097L,\n39098L,39099L,39100L,39101L,39102L,39103L,39104L,39105L,39106L,39107L,\n39108L,39109L,39110L,39111L,39112L,39113L,39114L,39115L,39116L,39117L,\n39118L,39119L,39120L,39121L,39122L,39123L,39124L,39125L,39126L,39127L,\n39128L,39129L,39130L,39131L,39132L,39133L,39134L,39135L,39136L,39137L,\n39138L,39139L,39140L,39141L,39142L,39143L,39144L,39145L,39146L,39147L,\n39148L,39149L,39150L,39151L,39152L,39153L,39154L,39155L,39156L,39157L,\n39158L,39159L,39160L,39161L,39162L,39163L,39164L,39165L,39166L,39167L,\n39168L,39169L,39170L,39171L,39172L,39173L,39174L,39175L,39176L,39177L,\n39178L,39179L,39180L,39181L,39182L,39183L,39184L,39185L,39186L,39187L,\n39188L,39189L,39190L,39191L,39192L,39193L,39194L,39195L,39196L,39197L,\n39198L,39199L,39200L,39201L,39202L,39203L,39204L,39205L,39206L,39207L,\n39208L,39209L,39210L,39211L,39212L,39213L,39214L,39215L,39216L,39217L,\n39218L,39219L,39220L,39221L,39222L,39223L,39224L,39225L,39226L,39227L,\n39228L,39229L,39230L,39231L,39232L,39233L,39234L,39235L,39236L,39237L,\n39238L,39239L,39240L,39241L,39242L,39243L,39244L,39245L,39246L,39247L,\n39248L,39249L,39250L,39251L,39252L,39253L,39254L,39255L,39256L,39257L,\n39258L,39259L,39260L,39261L,39262L,39263L,39264L,39265L,39266L,39267L,\n39268L,39269L,39270L,39271L,39272L,39273L,39274L,39275L,39276L,39277L,\n39278L,39279L,39280L,39281L,39282L,39283L,39284L,39285L,39286L,39287L,\n39288L,39289L,39290L,39291L,39292L,39293L,39294L,39295L,39296L,39297L,\n39298L,39299L,39300L,39301L,39302L,39303L,39304L,39305L,39306L,39307L,\n39308L,39309L,39310L,39311L,39312L,39313L,39314L,39315L,39316L,39317L,\n39318L,39319L,39320L,39321L,39322L,39323L,39324L,39325L,39326L,39327L,\n39328L,39329L,39330L,39331L,39332L,39333L,39334L,39335L,39336L,39337L,\n39338L,39339L,39340L,39341L,39342L,39343L,39344L,39345L,39346L,39347L,\n39348L,39349L,39350L,39351L,39352L,39353L,39354L,39355L,39356L,39357L,\n39358L,39359L,39360L,39361L,39362L,39363L,39364L,39365L,39366L,39367L,\n39368L,39369L,39370L,39371L,39372L,39373L,39374L,39375L,39376L,39377L,\n39378L,39379L,39380L,39381L,39382L,39383L,39384L,39385L,39386L,39387L,\n39388L,39389L,39390L,39391L,39392L,39393L,39394L,39395L,39396L,39397L,\n39398L,39399L,39400L,39401L,39402L,39403L,39404L,39405L,39406L,39407L,\n39408L,39409L,39410L,39411L,39412L,39413L,39414L,39415L,39416L,39417L,\n39418L,39419L,39420L,39421L,39422L,39423L,39424L,39425L,39426L,39427L,\n39428L,39429L,39430L,39431L,39432L,39433L,39434L,39435L,39436L,39437L,\n39438L,39439L,39440L,39441L,39442L,39443L,39444L,39445L,39446L,39447L,\n39448L,39449L,39450L,39451L,39452L,39453L,39454L,39455L,39456L,39457L,\n39458L,39459L,39460L,39461L,39462L,39463L,39464L,39465L,39466L,39467L,\n39468L,39469L,39470L,39471L,39472L,39473L,39474L,39475L,39476L,39477L,\n39478L,39479L,39480L,39481L,39482L,39483L,39484L,39485L,39486L,39487L,\n39488L,39489L,39490L,39491L,39492L,39493L,39494L,39495L,39496L,39497L,\n39498L,39499L,39500L,39501L,39502L,39503L,39504L,39505L,39506L,39507L,\n39508L,39509L,39510L,39511L,39512L,39513L,39514L,39515L,39516L,39517L,\n39518L,39519L,39520L,39521L,39522L,39523L,39524L,39525L,39526L,39527L,\n39528L,39529L,39530L,39531L,39532L,39533L,39534L,39535L,39536L,39537L,\n39538L,39539L,39540L,39541L,39542L,39543L,39544L,39545L,39546L,39547L,\n39548L,39549L,39550L,39551L,39552L,39553L,39554L,39555L,39556L,39557L,\n39558L,39559L,39560L,39561L,39562L,39563L,39564L,39565L,39566L,39567L,\n39568L,39569L,39570L,39571L,39572L,39573L,39574L,39575L,39576L,39577L,\n39578L,39579L,39580L,39581L,39582L,39583L,39584L,39585L,39586L,39587L,\n39588L,39589L,39590L,39591L,39592L,39593L,39594L,39595L,39596L,39597L,\n39598L,39599L,39600L,39601L,39602L,39603L,39604L,39605L,39606L,39607L,\n39608L,39609L,39610L,39611L,39612L,39613L,39614L,39615L,39616L,39617L,\n39618L,39619L,39620L,39621L,39622L,39623L,39624L,39625L,39626L,39627L,\n39628L,39629L,39630L,39631L,39632L,39633L,39634L,39635L,39636L,39637L,\n39638L,39639L,39640L,39641L,39642L,39643L,39644L,39645L,39646L,39647L,\n39648L,39649L,39650L,39651L,39652L,39653L,39654L,39655L,39656L,39657L,\n39658L,39659L,39660L,39661L,39662L,39663L,39664L,39665L,39666L,39667L,\n39668L,39669L,39670L,39671L,39672L,39673L,39674L,39675L,39676L,39677L,\n39678L,39679L,39680L,39681L,39682L,39683L,39684L,39685L,39686L,39687L,\n39688L,39689L,39690L,39691L,39692L,39693L,39694L,39695L,39696L,39697L,\n39698L,39699L,39700L,39701L,39702L,39703L,39704L,39705L,39706L,39707L,\n39708L,39709L,39710L,39711L,39712L,39713L,39714L,39715L,39716L,39717L,\n39718L,39719L,39720L,39721L,39722L,39723L,39724L,39725L,39726L,39727L,\n39728L,39729L,39730L,39731L,39732L,39733L,39734L,39735L,39736L,39737L,\n39738L,39739L,39740L,39741L,39742L,39743L,39744L,39745L,39746L,39747L,\n39748L,39749L,39750L,39751L,39752L,39753L,39754L,39755L,39756L,39757L,\n39758L,39759L,39760L,39761L,39762L,39763L,39764L,39765L,39766L,39767L,\n39768L,39769L,39770L,39771L,39772L,39773L,39774L,39775L,39776L,39777L,\n39778L,39779L,39780L,39781L,39782L,39783L,39784L,39785L,39786L,39787L,\n39788L,39789L,39790L,39791L,39792L,39793L,39794L,39795L,39796L,39797L,\n39798L,39799L,39800L,39801L,39802L,39803L,39804L,39805L,39806L,39807L,\n39808L,39809L,39810L,39811L,39812L,39813L,39814L,39815L,39816L,39817L,\n39818L,39819L,39820L,39821L,39822L,39823L,39824L,39825L,39826L,39827L,\n39828L,39829L,39830L,39831L,39832L,39833L,39834L,39835L,39836L,39837L,\n39838L,39839L,39840L,39841L,39842L,39843L,39844L,39845L,39846L,39847L,\n39848L,39849L,39850L,39851L,39852L,39853L,39854L,39855L,39856L,39857L,\n39858L,39859L,39860L,39861L,39862L,39863L,39864L,39865L,39866L,39867L,\n39868L,39869L,39870L,39871L,39872L,39873L,39874L,39875L,39876L,39877L,\n39878L,39879L,39880L,39881L,39882L,39883L,39884L,39885L,39886L,39887L,\n39888L,39889L,39890L,39891L,39892L,39893L,39894L,39895L,39896L,39897L,\n39898L,39899L,39900L,39901L,39902L,39903L,39904L,39905L,39906L,39907L,\n39908L,39909L,39910L,39911L,39912L,39913L,39914L,39915L,39916L,39917L,\n39918L,39919L,39920L,39921L,39922L,39923L,39924L,39925L,39926L,39927L,\n39928L,39929L,39930L,39931L,39932L,39933L,39934L,39935L,39936L,39937L,\n39938L,39939L,39940L,39941L,39942L,39943L,39944L,39945L,39946L,39947L,\n39948L,39949L,39950L,39951L,39952L,39953L,39954L,39955L,39956L,39957L,\n39958L,39959L,39960L,39961L,39962L,39963L,39964L,39965L,39966L,39967L,\n39968L,39969L,39970L,39971L,39972L,39973L,39974L,39975L,39976L,39977L,\n39978L,39979L,39980L,39981L,39982L,39983L,39984L,39985L,39986L,39987L,\n39988L,39989L,39990L,39991L,39992L,39993L,39994L,39995L,39996L,39997L,\n39998L,39999L,40000L,40001L,40002L,40003L,40004L,40005L,40006L,40007L,\n40008L,40009L,40010L,40011L,40012L,40013L,40014L,40015L,40016L,40017L,\n40018L,40019L,40020L,40021L,40022L,40023L,40024L,40025L,40026L,40027L,\n40028L,40029L,40030L,40031L,40032L,40033L,40034L,40035L,40036L,40037L,\n40038L,40039L,40040L,40041L,40042L,40043L,40044L,40045L,40046L,40047L,\n40048L,40049L,40050L,40051L,40052L,40053L,40054L,40055L,40056L,40057L,\n40058L,40059L,40060L,40061L,40062L,40063L,40064L,40065L,40066L,40067L,\n40068L,40069L,40070L,40071L,40072L,40073L,40074L,40075L,40076L,40077L,\n40078L,40079L,40080L,40081L,40082L,40083L,40084L,40085L,40086L,40087L,\n40088L,40089L,40090L,40091L,40092L,40093L,40094L,40095L,40096L,40097L,\n40098L,40099L,40100L,40101L,40102L,40103L,40104L,40105L,40106L,40107L,\n40108L,40109L,40110L,40111L,40112L,40113L,40114L,40115L,40116L,40117L,\n40118L,40119L,40120L,40121L,40122L,40123L,40124L,40125L,40126L,40127L,\n40128L,40129L,40130L,40131L,40132L,40133L,40134L,40135L,40136L,40137L,\n40138L,40139L,40140L,40141L,40142L,40143L,40144L,40145L,40146L,40147L,\n40148L,40149L,40150L,40151L,40152L,40153L,40154L,40155L,40156L,40157L,\n40158L,40159L,40160L,40161L,40162L,40163L,40164L,40165L,40166L,40167L,\n40168L,40169L,40170L,40171L,40172L,40173L,40174L,40175L,40176L,40177L,\n40178L,40179L,40180L,40181L,40182L,40183L,40184L,40185L,40186L,40187L,\n40188L,40189L,40190L,40191L,40192L,40193L,40194L,40195L,40196L,40197L,\n40198L,40199L,40200L,40201L,40202L,40203L,40204L,40205L,40206L,40207L,\n40208L,40209L,40210L,40211L,40212L,40213L,40214L,40215L,40216L,40217L,\n40218L,40219L,40220L,40221L,40222L,40223L,40224L,40225L,40226L,40227L,\n40228L,40229L,40230L,40231L,40232L,40233L,40234L,40235L,40236L,40237L,\n40238L,40239L,40240L,40241L,40242L,40243L,40244L,40245L,40246L,40247L,\n40248L,40249L,40250L,40251L,40252L,40253L,40254L,40255L,40256L,40257L,\n40258L,40259L,40260L,40261L,40262L,40263L,40264L,40265L,40266L,40267L,\n40268L,40269L,40270L,40271L,40272L,40273L,40274L,40275L,40276L,40277L,\n40278L,40279L,40280L,40281L,40282L,40283L,40284L,40285L,40286L,40287L,\n40288L,40289L,40290L,40291L,40292L,40293L,40294L,40295L,40296L,40297L,\n40298L,40299L,40300L,40301L,40302L,40303L,40304L,40305L,40306L,40307L,\n40308L,40309L,40310L,40311L,40312L,40313L,40314L,40315L,40316L,40317L,\n40318L,40319L,40320L,40321L,40322L,40323L,40324L,40325L,40326L,40327L,\n40328L,40329L,40330L,40331L,40332L,40333L,40334L,40335L,40336L,40337L,\n40338L,40339L,40340L,40341L,40342L,40343L,40344L,40345L,40346L,40347L,\n40348L,40349L,40350L,40351L,40352L,40353L,40354L,40355L,40356L,40357L,\n40358L,40359L,40360L,40361L,40362L,40363L,40364L,40365L,40366L,40367L,\n40368L,40369L,40370L,40371L,40372L,40373L,40374L,40375L,40376L,40377L,\n40378L,40379L,40380L,40381L,40382L,40383L,40384L,40385L,40386L,40387L,\n40388L,40389L,40390L,40391L,40392L,40393L,40394L,40395L,40396L,40397L,\n40398L,40399L,40400L,40401L,40402L,40403L,40404L,40405L,40406L,40407L,\n40408L,40409L,40410L,40411L,40412L,40413L,40414L,40415L,40416L,40417L,\n40418L,40419L,40420L,40421L,40422L,40423L,40424L,40425L,40426L,40427L,\n40428L,40429L,40430L,40431L,40432L,40433L,40434L,40435L,40436L,40437L,\n40438L,40439L,40440L,40441L,40442L,40443L,40444L,40445L,40446L,40447L,\n40448L,40449L,40450L,40451L,40452L,40453L,40454L,40455L,40456L,40457L,\n40458L,40459L,40460L,40461L,40462L,40463L,40464L,40465L,40466L,40467L,\n40468L,40469L,40470L,40471L,40472L,40473L,40474L,40475L,40476L,40477L,\n40478L,40479L,40480L,40481L,40482L,40483L,40484L,40485L,40486L,40487L,\n40488L,40489L,40490L,40491L,40492L,40493L,40494L,40495L,40496L,40497L,\n40498L,40499L,40500L,40501L,40502L,40503L,40504L,40505L,40506L,40507L,\n40508L,40509L,40510L,40511L,40512L,40513L,40514L,40515L,40516L,40517L,\n40518L,40519L,40520L,40521L,40522L,40523L,40524L,40525L,40526L,40527L,\n40528L,40529L,40530L,40531L,40532L,40533L,40534L,40535L,40536L,40537L,\n40538L,40539L,40540L,40541L,40542L,40543L,40544L,40545L,40546L,40547L,\n40548L,40549L,40550L,40551L,40552L,40553L,40554L,40555L,40556L,40557L,\n40558L,40559L,40560L,40561L,40562L,40563L,40564L,40565L,40566L,40567L,\n40568L,40569L,40570L,40571L,40572L,40573L,40574L,40575L,40576L,40577L,\n40578L,40579L,40580L,40581L,40582L,40583L,40584L,40585L,40586L,40587L,\n40588L,40589L,40590L,40591L,40592L,40593L,40594L,40595L,40596L,40597L,\n40598L,40599L,40600L,40601L,40602L,40603L,40604L,40605L,40606L,40607L,\n40608L,40609L,40610L,40611L,40612L,40613L,40614L,40615L,40616L,40617L,\n40618L,40619L,40620L,40621L,40622L,40623L,40624L,40625L,40626L,40627L,\n40628L,40629L,40630L,40631L,40632L,40633L,40634L,40635L,40636L,40637L,\n40638L,40639L,40640L,40641L,40642L,40643L,40644L,40645L,40646L,40647L,\n40648L,40649L,40650L,40651L,40652L,40653L,40654L,40655L,40656L,40657L,\n40658L,40659L,40660L,40661L,40662L,40663L,40664L,40665L,40666L,40667L,\n40668L,40669L,40670L,40671L,40672L,40673L,40674L,40675L,40676L,40677L,\n40678L,40679L,40680L,40681L,40682L,40683L,40684L,40685L,40686L,40687L,\n40688L,40689L,40690L,40691L,40692L,40693L,40694L,40695L,40696L,40697L,\n40698L,40699L,40700L,40701L,40702L,40703L,40704L,40705L,40706L,40707L,\n40708L,40709L,40710L,40711L,40712L,40713L,40714L,40715L,40716L,40717L,\n40718L,40719L,40720L,40721L,40722L,40723L,40724L,40725L,40726L,40727L,\n40728L,40729L,40730L,40731L,40732L,40733L,40734L,40735L,40736L,40737L,\n40738L,40739L,40740L,40741L,40742L,40743L,40744L,40745L,40746L,40747L,\n40748L,40749L,40750L,40751L,40752L,40753L,40754L,40755L,40756L,40757L,\n40758L,40759L,40760L,40761L,40762L,40763L,40764L,40765L,40766L,40767L,\n40768L,40769L,40770L,40771L,40772L,40773L,40774L,40775L,40776L,40777L,\n40778L,40779L,40780L,40781L,40782L,40783L,40784L,40785L,40786L,40787L,\n40788L,40789L,40790L,40791L,40792L,40793L,40794L,40795L,40796L,40797L,\n40798L,40799L,40800L,40801L,40802L,40803L,40804L,40805L,40806L,40807L,\n40808L,40809L,40810L,40811L,40812L,40813L,40814L,40815L,40816L,40817L,\n40818L,40819L,40820L,40821L,40822L,40823L,40824L,40825L,40826L,40827L,\n40828L,40829L,40830L,40831L,40832L,40833L,40834L,40835L,40836L,40837L,\n40838L,40839L,40840L,40841L,40842L,40843L,40844L,40845L,40846L,40847L,\n40848L,40849L,40850L,40851L,40852L,40853L,40854L,40855L,40856L,40857L,\n40858L,40859L,40860L,40861L,40862L,40863L,40864L,40865L,40866L,40867L,\n40868L,40869L,40870L,40871L,40872L,40873L,40874L,40875L,40876L,40877L,\n40878L,40879L,40880L,40881L,40882L,40883L,40884L,40885L,40886L,40887L,\n40888L,40889L,40890L,40891L,40892L,40893L,40894L,40895L,40896L,40897L,\n40898L,40899L,40900L,40901L,40902L,40903L,40904L,40905L,40906L,40907L,\n40908L,40909L,40910L,40911L,40912L,40913L,40914L,40915L,40916L,40917L,\n40918L,40919L,40920L,40921L,40922L,40923L,40924L,40925L,40926L,40927L,\n40928L,40929L,40930L,40931L,40932L,40933L,40934L,40935L,40936L,40937L,\n40938L,40939L,40940L,40941L,40942L,40943L,40944L,40945L,40946L,40947L,\n40948L,40949L,40950L,40951L,40952L,40953L,40954L,40955L,40956L,40957L,\n40958L,40959L,40960L,40961L,40962L,40963L,40964L,40965L,40966L,40967L,\n40968L,40969L,40970L,40971L,40972L,40973L,40974L,40975L,40976L,40977L,\n40978L,40979L,40980L,40981L,40982L,40983L,40984L,40985L,40986L,40987L,\n40988L,40989L,40990L,40991L,40992L,40993L,40994L,40995L,40996L,40997L,\n40998L,40999L,41000L,41001L,41002L,41003L,41004L,41005L,41006L,41007L,\n41008L,41009L,41010L,41011L,41012L,41013L,41014L,41015L,41016L,41017L,\n41018L,41019L,41020L,41021L,41022L,41023L,41024L,41025L,41026L,41027L,\n41028L,41029L,41030L,41031L,41032L,41033L,41034L,41035L,41036L,41037L,\n41038L,41039L,41040L,41041L,41042L,41043L,41044L,41045L,41046L,41047L,\n41048L,41049L,41050L,41051L,41052L,41053L,41054L,41055L,41056L,41057L,\n41058L,41059L,41060L,41061L,41062L,41063L,41064L,41065L,41066L,41067L,\n41068L,41069L,41070L,41071L,41072L,41073L,41074L,41075L,41076L,41077L,\n41078L,41079L,41080L,41081L,41082L,41083L,41084L,41085L,41086L,41087L,\n41088L,41089L,41090L,41091L,41092L,41093L,41094L,41095L,41096L,41097L,\n41098L,41099L,41100L,41101L,41102L,41103L,41104L,41105L,41106L,41107L,\n41108L,41109L,41110L,41111L,41112L,41113L,41114L,41115L,41116L,41117L,\n41118L,41119L,41120L,41121L,41122L,41123L,41124L,41125L,41126L,41127L,\n41128L,41129L,41130L,41131L,41132L,41133L,41134L,41135L,41136L,41137L,\n41138L,41139L,41140L,41141L,41142L,41143L,41144L,41145L,41146L,41147L,\n41148L,41149L,41150L,41151L,41152L,41153L,41154L,41155L,41156L,41157L,\n41158L,41159L,41160L,41161L,41162L,41163L,41164L,41165L,41166L,41167L,\n41168L,41169L,41170L,41171L,41172L,41173L,41174L,41175L,41176L,41177L,\n41178L,41179L,41180L,41181L,41182L,41183L,41184L,41185L,41186L,41187L,\n41188L,41189L,41190L,41191L,41192L,41193L,41194L,41195L,41196L,41197L,\n41198L,41199L,41200L,41201L,41202L,41203L,41204L,41205L,41206L,41207L,\n41208L,41209L,41210L,41211L,41212L,41213L,41214L,41215L,41216L,41217L,\n41218L,41219L,41220L,41221L,41222L,41223L,41224L,41225L,41226L,41227L,\n41228L,41229L,41230L,41231L,41232L,41233L,41234L,41235L,41236L,41237L,\n41238L,41239L,41240L,41241L,41242L,41243L,41244L,41245L,41246L,41247L,\n41248L,41249L,41250L,41251L,41252L,41253L,41254L,41255L,41256L,41257L,\n41258L,41259L,41260L,41261L,41262L,41263L,41264L,41265L,41266L,41267L,\n41268L,41269L,41270L,41271L,41272L,41273L,41274L,41275L,41276L,41277L,\n41278L,41279L,41280L,41281L,41282L,41283L,41284L,41285L,41286L,41287L,\n41288L,41289L,41290L,41291L,41292L,41293L,41294L,41295L,41296L,41297L,\n41298L,41299L,41300L,41301L,41302L,41303L,41304L,41305L,41306L,41307L,\n41308L,41309L,41310L,41311L,41312L,41313L,41314L,41315L,41316L,41317L,\n41318L,41319L,41320L,41321L,41322L,41323L,41324L,41325L,41326L,41327L,\n41328L,41329L,41330L,41331L,41332L,41333L,41334L,41335L,41336L,41337L,\n41338L,41339L,41340L,41341L,41342L,41343L,41344L,41345L,41346L,41347L,\n41348L,41349L,41350L,41351L,41352L,41353L,41354L,41355L,41356L,41357L,\n41358L,41359L,41360L,41361L,41362L,41363L,41364L,41365L,41366L,41367L,\n41368L,41369L,41370L,41371L,41372L,41373L,41374L,41375L,41376L,41377L,\n41378L,41379L,41380L,41381L,41382L,41383L,41384L,41385L,41386L,41387L,\n41388L,41389L,41390L,41391L,41392L,41393L,41394L,41395L,41396L,41397L,\n41398L,41399L,41400L,41401L,41402L,41403L,41404L,41405L,41406L,41407L,\n41408L,41409L,41410L,41411L,41412L,41413L,41414L,41415L,41416L,41417L,\n41418L,41419L,41420L,41421L,41422L,41423L,41424L,41425L,41426L,41427L,\n41428L,41429L,41430L,41431L,41432L,41433L,41434L,41435L,41436L,41437L,\n41438L,41439L,41440L,41441L,41442L,41443L,41444L,41445L,41446L,41447L,\n41448L,41449L,41450L,41451L,41452L,41453L,41454L,41455L,41456L,41457L,\n41458L,41459L,41460L,41461L,41462L,41463L,41464L,41465L,41466L,41467L,\n41468L,41469L,41470L,41471L,41472L,41473L,41474L,41475L,41476L,41477L,\n41478L,41479L,41480L,41481L,41482L,41483L,41484L,41485L,41486L,41487L,\n41488L,41489L,41490L,41491L,41492L,41493L,41494L,41495L,41496L,41497L,\n41498L,41499L,41500L,41501L,41502L,41503L,41504L,41505L,41506L,41507L,\n41508L,41509L,41510L,41511L,41512L,41513L,41514L,41515L,41516L,41517L,\n41518L,41519L,41520L,41521L,41522L,41523L,41524L,41525L,41526L,41527L,\n41528L,41529L,41530L,41531L,41532L,41533L,41534L,41535L,41536L,41537L,\n41538L,41539L,41540L,41541L,41542L,41543L,41544L,41545L,41546L,41547L,\n41548L,41549L,41550L,41551L,41552L,41553L,41554L,41555L,41556L,41557L,\n41558L,41559L,41560L,41561L,41562L,41563L,41564L,41565L,41566L,41567L,\n41568L,41569L,41570L,41571L,41572L,41573L,41574L,41575L,41576L,41577L,\n41578L,41579L,41580L,41581L,41582L,41583L,41584L,41585L,41586L,41587L,\n41588L,41589L,41590L,41591L,41592L,41593L,41594L,41595L,41596L,41597L,\n41598L,41599L,41600L,41601L,41602L,41603L,41604L,41605L,41606L,41607L,\n41608L,41609L,41610L,41611L,41612L,41613L,41614L,41615L,41616L,41617L,\n41618L,41619L,41620L,41621L,41622L,41623L,41624L,41625L,41626L,41627L,\n41628L,41629L,41630L,41631L,41632L,41633L,41634L,41635L,41636L,41637L,\n41638L,41639L,41640L,41641L,41642L,41643L,41644L,41645L,41646L,41647L,\n41648L,41649L,41650L,41651L,41652L,41653L,41654L,41655L,41656L,41657L,\n41658L,41659L,41660L,41661L,41662L,41663L,41664L,41665L,41666L,41667L,\n41668L,41669L,41670L,41671L,41672L,41673L,41674L,41675L,41676L,41677L,\n41678L,41679L,41680L,41681L,41682L,41683L,41684L,41685L,41686L,41687L,\n41688L,41689L,41690L,41691L,41692L,41693L,41694L,41695L,41696L,41697L,\n41698L,41699L,41700L,41701L,41702L,41703L,41704L,41705L,41706L,41707L,\n41708L,41709L,41710L,41711L,41712L,41713L,41714L,41715L,41716L,41717L,\n41718L,41719L,41720L,41721L,41722L,41723L,41724L,41725L,41726L,41727L,\n41728L,41729L,41730L,41731L,41732L,41733L,41734L,41735L,41736L,41737L,\n41738L,41739L,41740L,41741L,41742L,41743L,41744L,41745L,41746L,41747L,\n41748L,41749L,41750L,41751L,41752L,41753L,41754L,41755L,41756L,41757L,\n41758L,41759L,41760L,41761L,41762L,41763L,41764L,41765L,41766L,41767L,\n41768L,41769L,41770L,41771L,41772L,41773L,41774L,41775L,41776L,41777L,\n41778L,41779L,41780L,41781L,41782L,41783L,41784L,41785L,41786L,41787L,\n41788L,41789L,41790L,41791L,41792L,41793L,41794L,41795L,41796L,41797L,\n41798L,41799L,41800L,41801L,41802L,41803L,41804L,41805L,41806L,41807L,\n41808L,41809L,41810L,41811L,41812L,41813L,41814L,41815L,41816L,41817L,\n41818L,41819L,41820L,41821L,41822L,41823L,41824L,41825L,41826L,41827L,\n41828L,41829L,41830L,41831L,41832L,41833L,41834L,41835L,41836L,41837L,\n41838L,41839L,41840L,41841L,41842L,41843L,41844L,41845L,41846L,41847L,\n41848L,41849L,41850L,41851L,41852L,41853L,41854L,41855L,41856L,41857L,\n41858L,41859L,41860L,41861L,41862L,41863L,41864L,41865L,41866L,41867L,\n41868L,41869L,41870L,41871L,41872L,41873L,41874L,41875L,41876L,41877L,\n41878L,41879L,41880L,41881L,41882L,41883L,41884L,41885L,41886L,41887L,\n41888L,41889L,41890L,41891L,41892L,41893L,41894L,41895L,41896L,41897L,\n41898L,41899L,41900L,41901L,41902L,41903L,41904L,41905L,41906L,41907L,\n41908L,41909L,41910L,41911L,41912L,41913L,41914L,41915L,41916L,41917L,\n41918L,41919L,41920L,41921L,41922L,41923L,41924L,41925L,41926L,41927L,\n41928L,41929L,41930L,41931L,41932L,41933L,41934L,41935L,41936L,41937L,\n41938L,41939L,41940L,41941L,41942L,41943L,41944L,41945L,41946L,41947L,\n41948L,41949L,41950L,41951L,41952L,41953L,41954L,41955L,41956L,41957L,\n41958L,41959L,41960L,41961L,41962L,41963L,41964L,41965L,41966L,41967L,\n41968L,41969L,41970L,41971L,41972L,41973L,41974L,41975L,41976L,41977L,\n41978L,41979L,41980L,41981L,41982L,41983L,41984L,41985L,41986L,41987L,\n41988L,41989L,41990L,41991L,41992L,41993L,41994L,41995L,41996L,41997L,\n41998L,41999L,42000L,42001L,42002L,42003L,42004L,42005L,42006L,42007L,\n42008L,42009L,42010L,42011L,42012L,42013L,42014L,42015L,42016L,42017L,\n42018L,42019L,42020L,42021L,42022L,42023L,42024L,42025L,42026L,42027L,\n42028L,42029L,42030L,42031L,42032L,42033L,42034L,42035L,42036L,42037L,\n42038L,42039L,42040L,42041L,42042L,42043L,42044L,42045L,42046L,42047L,\n42048L,42049L,42050L,42051L,42052L,42053L,42054L,42055L,42056L,42057L,\n42058L,42059L,42060L,42061L,42062L,42063L,42064L,42065L,42066L,42067L,\n42068L,42069L,42070L,42071L,42072L,42073L,42074L,42075L,42076L,42077L,\n42078L,42079L,42080L,42081L,42082L,42083L,42084L,42085L,42086L,42087L,\n42088L,42089L,42090L,42091L,42092L,42093L,42094L,42095L,42096L,42097L,\n42098L,42099L,42100L,42101L,42102L,42103L,42104L,42105L,42106L,42107L,\n42108L,42109L,42110L,42111L,42112L,42113L,42114L,42115L,42116L,42117L,\n42118L,42119L,42120L,42121L,42122L,42123L,42124L,42125L,42126L,42127L,\n42128L,42129L,42130L,42131L,42132L,42133L,42134L,42135L,42136L,42137L,\n42138L,42139L,42140L,42141L,42142L,42143L,42144L,42145L,42146L,42147L,\n42148L,42149L,42150L,42151L,42152L,42153L,42154L,42155L,42156L,42157L,\n42158L,42159L,42160L,42161L,42162L,42163L,42164L,42165L,42166L,42167L,\n42168L,42169L,42170L,42171L,42172L,42173L,42174L,42175L,42176L,42177L,\n42178L,42179L,42180L,42181L,42182L,42183L,42184L,42185L,42186L,42187L,\n42188L,42189L,42190L,42191L,42192L,42193L,42194L,42195L,42196L,42197L,\n42198L,42199L,42200L,42201L,42202L,42203L,42204L,42205L,42206L,42207L,\n42208L,42209L,42210L,42211L,42212L,42213L,42214L,42215L,42216L,42217L,\n42218L,42219L,42220L,42221L,42222L,42223L,42224L,42225L,42226L,42227L,\n42228L,42229L,42230L,42231L,42232L,42233L,42234L,42235L,42236L,42237L,\n42238L,42239L,42240L,42241L,42242L,42243L,42244L,42245L,42246L,42247L,\n42248L,42249L,42250L,42251L,42252L,42253L,42254L,42255L,42256L,42257L,\n42258L,42259L,42260L,42261L,42262L,42263L,42264L,42265L,42266L,42267L,\n42268L,42269L,42270L,42271L,42272L,42273L,42274L,42275L,42276L,42277L,\n42278L,42279L,42280L,42281L,42282L,42283L,42284L,42285L,42286L,42287L,\n42288L,42289L,42290L,42291L,42292L,42293L,42294L,42295L,42296L,42297L,\n42298L,42299L,42300L,42301L,42302L,42303L,42304L,42305L,42306L,42307L,\n42308L,42309L,42310L,42311L,42312L,42313L,42314L,42315L,42316L,42317L,\n42318L,42319L,42320L,42321L,42322L,42323L,42324L,42325L,42326L,42327L,\n42328L,42329L,42330L,42331L,42332L,42333L,42334L,42335L,42336L,42337L,\n42338L,42339L,42340L,42341L,42342L,42343L,42344L,42345L,42346L,42347L,\n42348L,42349L,42350L,42351L,42352L,42353L,42354L,42355L,42356L,42357L,\n42358L,42359L,42360L,42361L,42362L,42363L,42364L,42365L,42366L,42367L,\n42368L,42369L,42370L,42371L,42372L,42373L,42374L,42375L,42376L,42377L,\n42378L,42379L,42380L,42381L,42382L,42383L,42384L,42385L,42386L,42387L,\n42388L,42389L,42390L,42391L,42392L,42393L,42394L,42395L,42396L,42397L,\n42398L,42399L,42400L,42401L,42402L,42403L,42404L,42405L,42406L,42407L,\n42408L,42409L,42410L,42411L,42412L,42413L,42414L,42415L,42416L,42417L,\n42418L,42419L,42420L,42421L,42422L,42423L,42424L,42425L,42426L,42427L,\n42428L,42429L,42430L,42431L,42432L,42433L,42434L,42435L,42436L,42437L,\n42438L,42439L,42440L,42441L,42442L,42443L,42444L,42445L,42446L,42447L,\n42448L,42449L,42450L,42451L,42452L,42453L,42454L,42455L,42456L,42457L,\n42458L,42459L,42460L,42461L,42462L,42463L,42464L,42465L,42466L,42467L,\n42468L,42469L,42470L,42471L,42472L,42473L,42474L,42475L,42476L,42477L,\n42478L,42479L,42480L,42481L,42482L,42483L,42484L,42485L,42486L,42487L,\n42488L,42489L,42490L,42491L,42492L,42493L,42494L,42495L,42496L,42497L,\n42498L,42499L,42500L,42501L,42502L,42503L,42504L,42505L,42506L,42507L,\n42508L,42509L,42510L,42511L,42512L,42513L,42514L,42515L,42516L,42517L,\n42518L,42519L,42520L,42521L,42522L,42523L,42524L,42525L,42526L,42527L,\n42528L,42529L,42530L,42531L,42532L,42533L,42534L,42535L,42536L,42537L,\n42538L,42539L,42540L,42541L,42542L,42543L,42544L,42545L,42546L,42547L,\n42548L,42549L,42550L,42551L,42552L,42553L,42554L,42555L,42556L,42557L,\n42558L,42559L,42560L,42560L,42562L,42562L,42564L,42564L,42566L,42566L,\n42568L,42568L,42570L,42570L,42572L,42572L,42574L,42574L,42576L,42576L,\n42578L,42578L,42580L,42580L,42582L,42582L,42584L,42584L,42586L,42586L,\n42588L,42588L,42590L,42590L,42592L,42592L,42594L,42594L,42596L,42596L,\n42598L,42598L,42600L,42600L,42602L,42602L,42604L,42604L,42606L,42607L,\n42608L,42609L,42610L,42611L,42612L,42613L,42614L,42615L,42616L,42617L,\n42618L,42619L,42620L,42621L,42622L,42623L,42624L,42624L,42626L,42626L,\n42628L,42628L,42630L,42630L,42632L,42632L,42634L,42634L,42636L,42636L,\n42638L,42638L,42640L,42640L,42642L,42642L,42644L,42644L,42646L,42646L,\n42648L,42648L,42650L,42650L,42652L,42653L,42654L,42655L,42656L,42657L,\n42658L,42659L,42660L,42661L,42662L,42663L,42664L,42665L,42666L,42667L,\n42668L,42669L,42670L,42671L,42672L,42673L,42674L,42675L,42676L,42677L,\n42678L,42679L,42680L,42681L,42682L,42683L,42684L,42685L,42686L,42687L,\n42688L,42689L,42690L,42691L,42692L,42693L,42694L,42695L,42696L,42697L,\n42698L,42699L,42700L,42701L,42702L,42703L,42704L,42705L,42706L,42707L,\n42708L,42709L,42710L,42711L,42712L,42713L,42714L,42715L,42716L,42717L,\n42718L,42719L,42720L,42721L,42722L,42723L,42724L,42725L,42726L,42727L,\n42728L,42729L,42730L,42731L,42732L,42733L,42734L,42735L,42736L,42737L,\n42738L,42739L,42740L,42741L,42742L,42743L,42744L,42745L,42746L,42747L,\n42748L,42749L,42750L,42751L,42752L,42753L,42754L,42755L,42756L,42757L,\n42758L,42759L,42760L,42761L,42762L,42763L,42764L,42765L,42766L,42767L,\n42768L,42769L,42770L,42771L,42772L,42773L,42774L,42775L,42776L,42777L,\n42778L,42779L,42780L,42781L,42782L,42783L,42784L,42785L,42786L,42786L,\n42788L,42788L,42790L,42790L,42792L,42792L,42794L,42794L,42796L,42796L,\n42798L,42798L,42800L,42801L,42802L,42802L,42804L,42804L,42806L,42806L,\n42808L,42808L,42810L,42810L,42812L,42812L,42814L,42814L,42816L,42816L,\n42818L,42818L,42820L,42820L,42822L,42822L,42824L,42824L,42826L,42826L,\n42828L,42828L,42830L,42830L,42832L,42832L,42834L,42834L,42836L,42836L,\n42838L,42838L,42840L,42840L,42842L,42842L,42844L,42844L,42846L,42846L,\n42848L,42848L,42850L,42850L,42852L,42852L,42854L,42854L,42856L,42856L,\n42858L,42858L,42860L,42860L,42862L,42862L,42864L,42865L,42866L,42867L,\n42868L,42869L,42870L,42871L,42872L,42873L,42873L,42875L,42875L,42877L,\n42878L,42878L,42880L,42880L,42882L,42882L,42884L,42884L,42886L,42886L,\n42888L,42889L,42890L,42891L,42891L,42893L,42894L,42895L,42896L,42896L,\n42898L,42898L,42948L,42901L,42902L,42902L,42904L,42904L,42906L,42906L,\n42908L,42908L,42910L,42910L,42912L,42912L,42914L,42914L,42916L,42916L,\n42918L,42918L,42920L,42920L,42922L,42923L,42924L,42925L,42926L,42927L,\n42928L,42929L,42930L,42931L,42932L,42932L,42934L,42934L,42936L,42936L,\n42938L,42938L,42940L,42940L,42942L,42942L,42944L,42945L,42946L,42946L,\n42948L,42949L,42950L,42951L,42952L,42953L,42954L,42955L,42956L,42957L,\n42958L,42959L,42960L,42961L,42962L,42963L,42964L,42965L,42966L,42967L,\n42968L,42969L,42970L,42971L,42972L,42973L,42974L,42975L,42976L,42977L,\n42978L,42979L,42980L,42981L,42982L,42983L,42984L,42985L,42986L,42987L,\n42988L,42989L,42990L,42991L,42992L,42993L,42994L,42995L,42996L,42997L,\n42998L,42999L,43000L,43001L,43002L,43003L,43004L,43005L,43006L,43007L,\n43008L,43009L,43010L,43011L,43012L,43013L,43014L,43015L,43016L,43017L,\n43018L,43019L,43020L,43021L,43022L,43023L,43024L,43025L,43026L,43027L,\n43028L,43029L,43030L,43031L,43032L,43033L,43034L,43035L,43036L,43037L,\n43038L,43039L,43040L,43041L,43042L,43043L,43044L,43045L,43046L,43047L,\n43048L,43049L,43050L,43051L,43052L,43053L,43054L,43055L,43056L,43057L,\n43058L,43059L,43060L,43061L,43062L,43063L,43064L,43065L,43066L,43067L,\n43068L,43069L,43070L,43071L,43072L,43073L,43074L,43075L,43076L,43077L,\n43078L,43079L,43080L,43081L,43082L,43083L,43084L,43085L,43086L,43087L,\n43088L,43089L,43090L,43091L,43092L,43093L,43094L,43095L,43096L,43097L,\n43098L,43099L,43100L,43101L,43102L,43103L,43104L,43105L,43106L,43107L,\n43108L,43109L,43110L,43111L,43112L,43113L,43114L,43115L,43116L,43117L,\n43118L,43119L,43120L,43121L,43122L,43123L,43124L,43125L,43126L,43127L,\n43128L,43129L,43130L,43131L,43132L,43133L,43134L,43135L,43136L,43137L,\n43138L,43139L,43140L,43141L,43142L,43143L,43144L,43145L,43146L,43147L,\n43148L,43149L,43150L,43151L,43152L,43153L,43154L,43155L,43156L,43157L,\n43158L,43159L,43160L,43161L,43162L,43163L,43164L,43165L,43166L,43167L,\n43168L,43169L,43170L,43171L,43172L,43173L,43174L,43175L,43176L,43177L,\n43178L,43179L,43180L,43181L,43182L,43183L,43184L,43185L,43186L,43187L,\n43188L,43189L,43190L,43191L,43192L,43193L,43194L,43195L,43196L,43197L,\n43198L,43199L,43200L,43201L,43202L,43203L,43204L,43205L,43206L,43207L,\n43208L,43209L,43210L,43211L,43212L,43213L,43214L,43215L,43216L,43217L,\n43218L,43219L,43220L,43221L,43222L,43223L,43224L,43225L,43226L,43227L,\n43228L,43229L,43230L,43231L,43232L,43233L,43234L,43235L,43236L,43237L,\n43238L,43239L,43240L,43241L,43242L,43243L,43244L,43245L,43246L,43247L,\n43248L,43249L,43250L,43251L,43252L,43253L,43254L,43255L,43256L,43257L,\n43258L,43259L,43260L,43261L,43262L,43263L,43264L,43265L,43266L,43267L,\n43268L,43269L,43270L,43271L,43272L,43273L,43274L,43275L,43276L,43277L,\n43278L,43279L,43280L,43281L,43282L,43283L,43284L,43285L,43286L,43287L,\n43288L,43289L,43290L,43291L,43292L,43293L,43294L,43295L,43296L,43297L,\n43298L,43299L,43300L,43301L,43302L,43303L,43304L,43305L,43306L,43307L,\n43308L,43309L,43310L,43311L,43312L,43313L,43314L,43315L,43316L,43317L,\n43318L,43319L,43320L,43321L,43322L,43323L,43324L,43325L,43326L,43327L,\n43328L,43329L,43330L,43331L,43332L,43333L,43334L,43335L,43336L,43337L,\n43338L,43339L,43340L,43341L,43342L,43343L,43344L,43345L,43346L,43347L,\n43348L,43349L,43350L,43351L,43352L,43353L,43354L,43355L,43356L,43357L,\n43358L,43359L,43360L,43361L,43362L,43363L,43364L,43365L,43366L,43367L,\n43368L,43369L,43370L,43371L,43372L,43373L,43374L,43375L,43376L,43377L,\n43378L,43379L,43380L,43381L,43382L,43383L,43384L,43385L,43386L,43387L,\n43388L,43389L,43390L,43391L,43392L,43393L,43394L,43395L,43396L,43397L,\n43398L,43399L,43400L,43401L,43402L,43403L,43404L,43405L,43406L,43407L,\n43408L,43409L,43410L,43411L,43412L,43413L,43414L,43415L,43416L,43417L,\n43418L,43419L,43420L,43421L,43422L,43423L,43424L,43425L,43426L,43427L,\n43428L,43429L,43430L,43431L,43432L,43433L,43434L,43435L,43436L,43437L,\n43438L,43439L,43440L,43441L,43442L,43443L,43444L,43445L,43446L,43447L,\n43448L,43449L,43450L,43451L,43452L,43453L,43454L,43455L,43456L,43457L,\n43458L,43459L,43460L,43461L,43462L,43463L,43464L,43465L,43466L,43467L,\n43468L,43469L,43470L,43471L,43472L,43473L,43474L,43475L,43476L,43477L,\n43478L,43479L,43480L,43481L,43482L,43483L,43484L,43485L,43486L,43487L,\n43488L,43489L,43490L,43491L,43492L,43493L,43494L,43495L,43496L,43497L,\n43498L,43499L,43500L,43501L,43502L,43503L,43504L,43505L,43506L,43507L,\n43508L,43509L,43510L,43511L,43512L,43513L,43514L,43515L,43516L,43517L,\n43518L,43519L,43520L,43521L,43522L,43523L,43524L,43525L,43526L,43527L,\n43528L,43529L,43530L,43531L,43532L,43533L,43534L,43535L,43536L,43537L,\n43538L,43539L,43540L,43541L,43542L,43543L,43544L,43545L,43546L,43547L,\n43548L,43549L,43550L,43551L,43552L,43553L,43554L,43555L,43556L,43557L,\n43558L,43559L,43560L,43561L,43562L,43563L,43564L,43565L,43566L,43567L,\n43568L,43569L,43570L,43571L,43572L,43573L,43574L,43575L,43576L,43577L,\n43578L,43579L,43580L,43581L,43582L,43583L,43584L,43585L,43586L,43587L,\n43588L,43589L,43590L,43591L,43592L,43593L,43594L,43595L,43596L,43597L,\n43598L,43599L,43600L,43601L,43602L,43603L,43604L,43605L,43606L,43607L,\n43608L,43609L,43610L,43611L,43612L,43613L,43614L,43615L,43616L,43617L,\n43618L,43619L,43620L,43621L,43622L,43623L,43624L,43625L,43626L,43627L,\n43628L,43629L,43630L,43631L,43632L,43633L,43634L,43635L,43636L,43637L,\n43638L,43639L,43640L,43641L,43642L,43643L,43644L,43645L,43646L,43647L,\n43648L,43649L,43650L,43651L,43652L,43653L,43654L,43655L,43656L,43657L,\n43658L,43659L,43660L,43661L,43662L,43663L,43664L,43665L,43666L,43667L,\n43668L,43669L,43670L,43671L,43672L,43673L,43674L,43675L,43676L,43677L,\n43678L,43679L,43680L,43681L,43682L,43683L,43684L,43685L,43686L,43687L,\n43688L,43689L,43690L,43691L,43692L,43693L,43694L,43695L,43696L,43697L,\n43698L,43699L,43700L,43701L,43702L,43703L,43704L,43705L,43706L,43707L,\n43708L,43709L,43710L,43711L,43712L,43713L,43714L,43715L,43716L,43717L,\n43718L,43719L,43720L,43721L,43722L,43723L,43724L,43725L,43726L,43727L,\n43728L,43729L,43730L,43731L,43732L,43733L,43734L,43735L,43736L,43737L,\n43738L,43739L,43740L,43741L,43742L,43743L,43744L,43745L,43746L,43747L,\n43748L,43749L,43750L,43751L,43752L,43753L,43754L,43755L,43756L,43757L,\n43758L,43759L,43760L,43761L,43762L,43763L,43764L,43765L,43766L,43767L,\n43768L,43769L,43770L,43771L,43772L,43773L,43774L,43775L,43776L,43777L,\n43778L,43779L,43780L,43781L,43782L,43783L,43784L,43785L,43786L,43787L,\n43788L,43789L,43790L,43791L,43792L,43793L,43794L,43795L,43796L,43797L,\n43798L,43799L,43800L,43801L,43802L,43803L,43804L,43805L,43806L,43807L,\n43808L,43809L,43810L,43811L,43812L,43813L,43814L,43815L,43816L,43817L,\n43818L,43819L,43820L,43821L,43822L,43823L,43824L,43825L,43826L,43827L,\n43828L,43829L,43830L,43831L,43832L,43833L,43834L,43835L,43836L,43837L,\n43838L,43839L,43840L,43841L,43842L,43843L,43844L,43845L,43846L,43847L,\n43848L,43849L,43850L,43851L,43852L,43853L,43854L,43855L,43856L,43857L,\n43858L,42931L,43860L,43861L,43862L,43863L,43864L,43865L,43866L,43867L,\n43868L,43869L,43870L,43871L,43872L,43873L,43874L,43875L,43876L,43877L,\n43878L,43879L,43880L,43881L,43882L,43883L,43884L,43885L,43886L,43887L,5024,\n5025,5026,5027,5028,5029,5030,5031,5032,5033,5034,5035,5036,5037,5038,5039,\n5040,5041,5042,5043,5044,5045,5046,5047,5048,5049,5050,5051,5052,5053,5054,\n5055,5056,5057,5058,5059,5060,5061,5062,5063,5064,5065,5066,5067,5068,5069,\n5070,5071,5072,5073,5074,5075,5076,5077,5078,5079,5080,5081,5082,5083,5084,\n5085,5086,5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,\n5100,5101,5102,5103,43968L,43969L,43970L,43971L,43972L,43973L,43974L,\n43975L,43976L,43977L,43978L,43979L,43980L,43981L,43982L,43983L,43984L,\n43985L,43986L,43987L,43988L,43989L,43990L,43991L,43992L,43993L,43994L,\n43995L,43996L,43997L,43998L,43999L,44000L,44001L,44002L,44003L,44004L,\n44005L,44006L,44007L,44008L,44009L,44010L,44011L,44012L,44013L,44014L,\n44015L,44016L,44017L,44018L,44019L,44020L,44021L,44022L,44023L,44024L,\n44025L,44026L,44027L,44028L,44029L,44030L,44031L,44032L,44033L,44034L,\n44035L,44036L,44037L,44038L,44039L,44040L,44041L,44042L,44043L,44044L,\n44045L,44046L,44047L,44048L,44049L,44050L,44051L,44052L,44053L,44054L,\n44055L,44056L,44057L,44058L,44059L,44060L,44061L,44062L,44063L,44064L,\n44065L,44066L,44067L,44068L,44069L,44070L,44071L,44072L,44073L,44074L,\n44075L,44076L,44077L,44078L,44079L,44080L,44081L,44082L,44083L,44084L,\n44085L,44086L,44087L,44088L,44089L,44090L,44091L,44092L,44093L,44094L,\n44095L,44096L,44097L,44098L,44099L,44100L,44101L,44102L,44103L,44104L,\n44105L,44106L,44107L,44108L,44109L,44110L,44111L,44112L,44113L,44114L,\n44115L,44116L,44117L,44118L,44119L,44120L,44121L,44122L,44123L,44124L,\n44125L,44126L,44127L,44128L,44129L,44130L,44131L,44132L,44133L,44134L,\n44135L,44136L,44137L,44138L,44139L,44140L,44141L,44142L,44143L,44144L,\n44145L,44146L,44147L,44148L,44149L,44150L,44151L,44152L,44153L,44154L,\n44155L,44156L,44157L,44158L,44159L,44160L,44161L,44162L,44163L,44164L,\n44165L,44166L,44167L,44168L,44169L,44170L,44171L,44172L,44173L,44174L,\n44175L,44176L,44177L,44178L,44179L,44180L,44181L,44182L,44183L,44184L,\n44185L,44186L,44187L,44188L,44189L,44190L,44191L,44192L,44193L,44194L,\n44195L,44196L,44197L,44198L,44199L,44200L,44201L,44202L,44203L,44204L,\n44205L,44206L,44207L,44208L,44209L,44210L,44211L,44212L,44213L,44214L,\n44215L,44216L,44217L,44218L,44219L,44220L,44221L,44222L,44223L,44224L,\n44225L,44226L,44227L,44228L,44229L,44230L,44231L,44232L,44233L,44234L,\n44235L,44236L,44237L,44238L,44239L,44240L,44241L,44242L,44243L,44244L,\n44245L,44246L,44247L,44248L,44249L,44250L,44251L,44252L,44253L,44254L,\n44255L,44256L,44257L,44258L,44259L,44260L,44261L,44262L,44263L,44264L,\n44265L,44266L,44267L,44268L,44269L,44270L,44271L,44272L,44273L,44274L,\n44275L,44276L,44277L,44278L,44279L,44280L,44281L,44282L,44283L,44284L,\n44285L,44286L,44287L,44288L,44289L,44290L,44291L,44292L,44293L,44294L,\n44295L,44296L,44297L,44298L,44299L,44300L,44301L,44302L,44303L,44304L,\n44305L,44306L,44307L,44308L,44309L,44310L,44311L,44312L,44313L,44314L,\n44315L,44316L,44317L,44318L,44319L,44320L,44321L,44322L,44323L,44324L,\n44325L,44326L,44327L,44328L,44329L,44330L,44331L,44332L,44333L,44334L,\n44335L,44336L,44337L,44338L,44339L,44340L,44341L,44342L,44343L,44344L,\n44345L,44346L,44347L,44348L,44349L,44350L,44351L,44352L,44353L,44354L,\n44355L,44356L,44357L,44358L,44359L,44360L,44361L,44362L,44363L,44364L,\n44365L,44366L,44367L,44368L,44369L,44370L,44371L,44372L,44373L,44374L,\n44375L,44376L,44377L,44378L,44379L,44380L,44381L,44382L,44383L,44384L,\n44385L,44386L,44387L,44388L,44389L,44390L,44391L,44392L,44393L,44394L,\n44395L,44396L,44397L,44398L,44399L,44400L,44401L,44402L,44403L,44404L,\n44405L,44406L,44407L,44408L,44409L,44410L,44411L,44412L,44413L,44414L,\n44415L,44416L,44417L,44418L,44419L,44420L,44421L,44422L,44423L,44424L,\n44425L,44426L,44427L,44428L,44429L,44430L,44431L,44432L,44433L,44434L,\n44435L,44436L,44437L,44438L,44439L,44440L,44441L,44442L,44443L,44444L,\n44445L,44446L,44447L,44448L,44449L,44450L,44451L,44452L,44453L,44454L,\n44455L,44456L,44457L,44458L,44459L,44460L,44461L,44462L,44463L,44464L,\n44465L,44466L,44467L,44468L,44469L,44470L,44471L,44472L,44473L,44474L,\n44475L,44476L,44477L,44478L,44479L,44480L,44481L,44482L,44483L,44484L,\n44485L,44486L,44487L,44488L,44489L,44490L,44491L,44492L,44493L,44494L,\n44495L,44496L,44497L,44498L,44499L,44500L,44501L,44502L,44503L,44504L,\n44505L,44506L,44507L,44508L,44509L,44510L,44511L,44512L,44513L,44514L,\n44515L,44516L,44517L,44518L,44519L,44520L,44521L,44522L,44523L,44524L,\n44525L,44526L,44527L,44528L,44529L,44530L,44531L,44532L,44533L,44534L,\n44535L,44536L,44537L,44538L,44539L,44540L,44541L,44542L,44543L,44544L,\n44545L,44546L,44547L,44548L,44549L,44550L,44551L,44552L,44553L,44554L,\n44555L,44556L,44557L,44558L,44559L,44560L,44561L,44562L,44563L,44564L,\n44565L,44566L,44567L,44568L,44569L,44570L,44571L,44572L,44573L,44574L,\n44575L,44576L,44577L,44578L,44579L,44580L,44581L,44582L,44583L,44584L,\n44585L,44586L,44587L,44588L,44589L,44590L,44591L,44592L,44593L,44594L,\n44595L,44596L,44597L,44598L,44599L,44600L,44601L,44602L,44603L,44604L,\n44605L,44606L,44607L,44608L,44609L,44610L,44611L,44612L,44613L,44614L,\n44615L,44616L,44617L,44618L,44619L,44620L,44621L,44622L,44623L,44624L,\n44625L,44626L,44627L,44628L,44629L,44630L,44631L,44632L,44633L,44634L,\n44635L,44636L,44637L,44638L,44639L,44640L,44641L,44642L,44643L,44644L,\n44645L,44646L,44647L,44648L,44649L,44650L,44651L,44652L,44653L,44654L,\n44655L,44656L,44657L,44658L,44659L,44660L,44661L,44662L,44663L,44664L,\n44665L,44666L,44667L,44668L,44669L,44670L,44671L,44672L,44673L,44674L,\n44675L,44676L,44677L,44678L,44679L,44680L,44681L,44682L,44683L,44684L,\n44685L,44686L,44687L,44688L,44689L,44690L,44691L,44692L,44693L,44694L,\n44695L,44696L,44697L,44698L,44699L,44700L,44701L,44702L,44703L,44704L,\n44705L,44706L,44707L,44708L,44709L,44710L,44711L,44712L,44713L,44714L,\n44715L,44716L,44717L,44718L,44719L,44720L,44721L,44722L,44723L,44724L,\n44725L,44726L,44727L,44728L,44729L,44730L,44731L,44732L,44733L,44734L,\n44735L,44736L,44737L,44738L,44739L,44740L,44741L,44742L,44743L,44744L,\n44745L,44746L,44747L,44748L,44749L,44750L,44751L,44752L,44753L,44754L,\n44755L,44756L,44757L,44758L,44759L,44760L,44761L,44762L,44763L,44764L,\n44765L,44766L,44767L,44768L,44769L,44770L,44771L,44772L,44773L,44774L,\n44775L,44776L,44777L,44778L,44779L,44780L,44781L,44782L,44783L,44784L,\n44785L,44786L,44787L,44788L,44789L,44790L,44791L,44792L,44793L,44794L,\n44795L,44796L,44797L,44798L,44799L,44800L,44801L,44802L,44803L,44804L,\n44805L,44806L,44807L,44808L,44809L,44810L,44811L,44812L,44813L,44814L,\n44815L,44816L,44817L,44818L,44819L,44820L,44821L,44822L,44823L,44824L,\n44825L,44826L,44827L,44828L,44829L,44830L,44831L,44832L,44833L,44834L,\n44835L,44836L,44837L,44838L,44839L,44840L,44841L,44842L,44843L,44844L,\n44845L,44846L,44847L,44848L,44849L,44850L,44851L,44852L,44853L,44854L,\n44855L,44856L,44857L,44858L,44859L,44860L,44861L,44862L,44863L,44864L,\n44865L,44866L,44867L,44868L,44869L,44870L,44871L,44872L,44873L,44874L,\n44875L,44876L,44877L,44878L,44879L,44880L,44881L,44882L,44883L,44884L,\n44885L,44886L,44887L,44888L,44889L,44890L,44891L,44892L,44893L,44894L,\n44895L,44896L,44897L,44898L,44899L,44900L,44901L,44902L,44903L,44904L,\n44905L,44906L,44907L,44908L,44909L,44910L,44911L,44912L,44913L,44914L,\n44915L,44916L,44917L,44918L,44919L,44920L,44921L,44922L,44923L,44924L,\n44925L,44926L,44927L,44928L,44929L,44930L,44931L,44932L,44933L,44934L,\n44935L,44936L,44937L,44938L,44939L,44940L,44941L,44942L,44943L,44944L,\n44945L,44946L,44947L,44948L,44949L,44950L,44951L,44952L,44953L,44954L,\n44955L,44956L,44957L,44958L,44959L,44960L,44961L,44962L,44963L,44964L,\n44965L,44966L,44967L,44968L,44969L,44970L,44971L,44972L,44973L,44974L,\n44975L,44976L,44977L,44978L,44979L,44980L,44981L,44982L,44983L,44984L,\n44985L,44986L,44987L,44988L,44989L,44990L,44991L,44992L,44993L,44994L,\n44995L,44996L,44997L,44998L,44999L,45000L,45001L,45002L,45003L,45004L,\n45005L,45006L,45007L,45008L,45009L,45010L,45011L,45012L,45013L,45014L,\n45015L,45016L,45017L,45018L,45019L,45020L,45021L,45022L,45023L,45024L,\n45025L,45026L,45027L,45028L,45029L,45030L,45031L,45032L,45033L,45034L,\n45035L,45036L,45037L,45038L,45039L,45040L,45041L,45042L,45043L,45044L,\n45045L,45046L,45047L,45048L,45049L,45050L,45051L,45052L,45053L,45054L,\n45055L,45056L,45057L,45058L,45059L,45060L,45061L,45062L,45063L,45064L,\n45065L,45066L,45067L,45068L,45069L,45070L,45071L,45072L,45073L,45074L,\n45075L,45076L,45077L,45078L,45079L,45080L,45081L,45082L,45083L,45084L,\n45085L,45086L,45087L,45088L,45089L,45090L,45091L,45092L,45093L,45094L,\n45095L,45096L,45097L,45098L,45099L,45100L,45101L,45102L,45103L,45104L,\n45105L,45106L,45107L,45108L,45109L,45110L,45111L,45112L,45113L,45114L,\n45115L,45116L,45117L,45118L,45119L,45120L,45121L,45122L,45123L,45124L,\n45125L,45126L,45127L,45128L,45129L,45130L,45131L,45132L,45133L,45134L,\n45135L,45136L,45137L,45138L,45139L,45140L,45141L,45142L,45143L,45144L,\n45145L,45146L,45147L,45148L,45149L,45150L,45151L,45152L,45153L,45154L,\n45155L,45156L,45157L,45158L,45159L,45160L,45161L,45162L,45163L,45164L,\n45165L,45166L,45167L,45168L,45169L,45170L,45171L,45172L,45173L,45174L,\n45175L,45176L,45177L,45178L,45179L,45180L,45181L,45182L,45183L,45184L,\n45185L,45186L,45187L,45188L,45189L,45190L,45191L,45192L,45193L,45194L,\n45195L,45196L,45197L,45198L,45199L,45200L,45201L,45202L,45203L,45204L,\n45205L,45206L,45207L,45208L,45209L,45210L,45211L,45212L,45213L,45214L,\n45215L,45216L,45217L,45218L,45219L,45220L,45221L,45222L,45223L,45224L,\n45225L,45226L,45227L,45228L,45229L,45230L,45231L,45232L,45233L,45234L,\n45235L,45236L,45237L,45238L,45239L,45240L,45241L,45242L,45243L,45244L,\n45245L,45246L,45247L,45248L,45249L,45250L,45251L,45252L,45253L,45254L,\n45255L,45256L,45257L,45258L,45259L,45260L,45261L,45262L,45263L,45264L,\n45265L,45266L,45267L,45268L,45269L,45270L,45271L,45272L,45273L,45274L,\n45275L,45276L,45277L,45278L,45279L,45280L,45281L,45282L,45283L,45284L,\n45285L,45286L,45287L,45288L,45289L,45290L,45291L,45292L,45293L,45294L,\n45295L,45296L,45297L,45298L,45299L,45300L,45301L,45302L,45303L,45304L,\n45305L,45306L,45307L,45308L,45309L,45310L,45311L,45312L,45313L,45314L,\n45315L,45316L,45317L,45318L,45319L,45320L,45321L,45322L,45323L,45324L,\n45325L,45326L,45327L,45328L,45329L,45330L,45331L,45332L,45333L,45334L,\n45335L,45336L,45337L,45338L,45339L,45340L,45341L,45342L,45343L,45344L,\n45345L,45346L,45347L,45348L,45349L,45350L,45351L,45352L,45353L,45354L,\n45355L,45356L,45357L,45358L,45359L,45360L,45361L,45362L,45363L,45364L,\n45365L,45366L,45367L,45368L,45369L,45370L,45371L,45372L,45373L,45374L,\n45375L,45376L,45377L,45378L,45379L,45380L,45381L,45382L,45383L,45384L,\n45385L,45386L,45387L,45388L,45389L,45390L,45391L,45392L,45393L,45394L,\n45395L,45396L,45397L,45398L,45399L,45400L,45401L,45402L,45403L,45404L,\n45405L,45406L,45407L,45408L,45409L,45410L,45411L,45412L,45413L,45414L,\n45415L,45416L,45417L,45418L,45419L,45420L,45421L,45422L,45423L,45424L,\n45425L,45426L,45427L,45428L,45429L,45430L,45431L,45432L,45433L,45434L,\n45435L,45436L,45437L,45438L,45439L,45440L,45441L,45442L,45443L,45444L,\n45445L,45446L,45447L,45448L,45449L,45450L,45451L,45452L,45453L,45454L,\n45455L,45456L,45457L,45458L,45459L,45460L,45461L,45462L,45463L,45464L,\n45465L,45466L,45467L,45468L,45469L,45470L,45471L,45472L,45473L,45474L,\n45475L,45476L,45477L,45478L,45479L,45480L,45481L,45482L,45483L,45484L,\n45485L,45486L,45487L,45488L,45489L,45490L,45491L,45492L,45493L,45494L,\n45495L,45496L,45497L,45498L,45499L,45500L,45501L,45502L,45503L,45504L,\n45505L,45506L,45507L,45508L,45509L,45510L,45511L,45512L,45513L,45514L,\n45515L,45516L,45517L,45518L,45519L,45520L,45521L,45522L,45523L,45524L,\n45525L,45526L,45527L,45528L,45529L,45530L,45531L,45532L,45533L,45534L,\n45535L,45536L,45537L,45538L,45539L,45540L,45541L,45542L,45543L,45544L,\n45545L,45546L,45547L,45548L,45549L,45550L,45551L,45552L,45553L,45554L,\n45555L,45556L,45557L,45558L,45559L,45560L,45561L,45562L,45563L,45564L,\n45565L,45566L,45567L,45568L,45569L,45570L,45571L,45572L,45573L,45574L,\n45575L,45576L,45577L,45578L,45579L,45580L,45581L,45582L,45583L,45584L,\n45585L,45586L,45587L,45588L,45589L,45590L,45591L,45592L,45593L,45594L,\n45595L,45596L,45597L,45598L,45599L,45600L,45601L,45602L,45603L,45604L,\n45605L,45606L,45607L,45608L,45609L,45610L,45611L,45612L,45613L,45614L,\n45615L,45616L,45617L,45618L,45619L,45620L,45621L,45622L,45623L,45624L,\n45625L,45626L,45627L,45628L,45629L,45630L,45631L,45632L,45633L,45634L,\n45635L,45636L,45637L,45638L,45639L,45640L,45641L,45642L,45643L,45644L,\n45645L,45646L,45647L,45648L,45649L,45650L,45651L,45652L,45653L,45654L,\n45655L,45656L,45657L,45658L,45659L,45660L,45661L,45662L,45663L,45664L,\n45665L,45666L,45667L,45668L,45669L,45670L,45671L,45672L,45673L,45674L,\n45675L,45676L,45677L,45678L,45679L,45680L,45681L,45682L,45683L,45684L,\n45685L,45686L,45687L,45688L,45689L,45690L,45691L,45692L,45693L,45694L,\n45695L,45696L,45697L,45698L,45699L,45700L,45701L,45702L,45703L,45704L,\n45705L,45706L,45707L,45708L,45709L,45710L,45711L,45712L,45713L,45714L,\n45715L,45716L,45717L,45718L,45719L,45720L,45721L,45722L,45723L,45724L,\n45725L,45726L,45727L,45728L,45729L,45730L,45731L,45732L,45733L,45734L,\n45735L,45736L,45737L,45738L,45739L,45740L,45741L,45742L,45743L,45744L,\n45745L,45746L,45747L,45748L,45749L,45750L,45751L,45752L,45753L,45754L,\n45755L,45756L,45757L,45758L,45759L,45760L,45761L,45762L,45763L,45764L,\n45765L,45766L,45767L,45768L,45769L,45770L,45771L,45772L,45773L,45774L,\n45775L,45776L,45777L,45778L,45779L,45780L,45781L,45782L,45783L,45784L,\n45785L,45786L,45787L,45788L,45789L,45790L,45791L,45792L,45793L,45794L,\n45795L,45796L,45797L,45798L,45799L,45800L,45801L,45802L,45803L,45804L,\n45805L,45806L,45807L,45808L,45809L,45810L,45811L,45812L,45813L,45814L,\n45815L,45816L,45817L,45818L,45819L,45820L,45821L,45822L,45823L,45824L,\n45825L,45826L,45827L,45828L,45829L,45830L,45831L,45832L,45833L,45834L,\n45835L,45836L,45837L,45838L,45839L,45840L,45841L,45842L,45843L,45844L,\n45845L,45846L,45847L,45848L,45849L,45850L,45851L,45852L,45853L,45854L,\n45855L,45856L,45857L,45858L,45859L,45860L,45861L,45862L,45863L,45864L,\n45865L,45866L,45867L,45868L,45869L,45870L,45871L,45872L,45873L,45874L,\n45875L,45876L,45877L,45878L,45879L,45880L,45881L,45882L,45883L,45884L,\n45885L,45886L,45887L,45888L,45889L,45890L,45891L,45892L,45893L,45894L,\n45895L,45896L,45897L,45898L,45899L,45900L,45901L,45902L,45903L,45904L,\n45905L,45906L,45907L,45908L,45909L,45910L,45911L,45912L,45913L,45914L,\n45915L,45916L,45917L,45918L,45919L,45920L,45921L,45922L,45923L,45924L,\n45925L,45926L,45927L,45928L,45929L,45930L,45931L,45932L,45933L,45934L,\n45935L,45936L,45937L,45938L,45939L,45940L,45941L,45942L,45943L,45944L,\n45945L,45946L,45947L,45948L,45949L,45950L,45951L,45952L,45953L,45954L,\n45955L,45956L,45957L,45958L,45959L,45960L,45961L,45962L,45963L,45964L,\n45965L,45966L,45967L,45968L,45969L,45970L,45971L,45972L,45973L,45974L,\n45975L,45976L,45977L,45978L,45979L,45980L,45981L,45982L,45983L,45984L,\n45985L,45986L,45987L,45988L,45989L,45990L,45991L,45992L,45993L,45994L,\n45995L,45996L,45997L,45998L,45999L,46000L,46001L,46002L,46003L,46004L,\n46005L,46006L,46007L,46008L,46009L,46010L,46011L,46012L,46013L,46014L,\n46015L,46016L,46017L,46018L,46019L,46020L,46021L,46022L,46023L,46024L,\n46025L,46026L,46027L,46028L,46029L,46030L,46031L,46032L,46033L,46034L,\n46035L,46036L,46037L,46038L,46039L,46040L,46041L,46042L,46043L,46044L,\n46045L,46046L,46047L,46048L,46049L,46050L,46051L,46052L,46053L,46054L,\n46055L,46056L,46057L,46058L,46059L,46060L,46061L,46062L,46063L,46064L,\n46065L,46066L,46067L,46068L,46069L,46070L,46071L,46072L,46073L,46074L,\n46075L,46076L,46077L,46078L,46079L,46080L,46081L,46082L,46083L,46084L,\n46085L,46086L,46087L,46088L,46089L,46090L,46091L,46092L,46093L,46094L,\n46095L,46096L,46097L,46098L,46099L,46100L,46101L,46102L,46103L,46104L,\n46105L,46106L,46107L,46108L,46109L,46110L,46111L,46112L,46113L,46114L,\n46115L,46116L,46117L,46118L,46119L,46120L,46121L,46122L,46123L,46124L,\n46125L,46126L,46127L,46128L,46129L,46130L,46131L,46132L,46133L,46134L,\n46135L,46136L,46137L,46138L,46139L,46140L,46141L,46142L,46143L,46144L,\n46145L,46146L,46147L,46148L,46149L,46150L,46151L,46152L,46153L,46154L,\n46155L,46156L,46157L,46158L,46159L,46160L,46161L,46162L,46163L,46164L,\n46165L,46166L,46167L,46168L,46169L,46170L,46171L,46172L,46173L,46174L,\n46175L,46176L,46177L,46178L,46179L,46180L,46181L,46182L,46183L,46184L,\n46185L,46186L,46187L,46188L,46189L,46190L,46191L,46192L,46193L,46194L,\n46195L,46196L,46197L,46198L,46199L,46200L,46201L,46202L,46203L,46204L,\n46205L,46206L,46207L,46208L,46209L,46210L,46211L,46212L,46213L,46214L,\n46215L,46216L,46217L,46218L,46219L,46220L,46221L,46222L,46223L,46224L,\n46225L,46226L,46227L,46228L,46229L,46230L,46231L,46232L,46233L,46234L,\n46235L,46236L,46237L,46238L,46239L,46240L,46241L,46242L,46243L,46244L,\n46245L,46246L,46247L,46248L,46249L,46250L,46251L,46252L,46253L,46254L,\n46255L,46256L,46257L,46258L,46259L,46260L,46261L,46262L,46263L,46264L,\n46265L,46266L,46267L,46268L,46269L,46270L,46271L,46272L,46273L,46274L,\n46275L,46276L,46277L,46278L,46279L,46280L,46281L,46282L,46283L,46284L,\n46285L,46286L,46287L,46288L,46289L,46290L,46291L,46292L,46293L,46294L,\n46295L,46296L,46297L,46298L,46299L,46300L,46301L,46302L,46303L,46304L,\n46305L,46306L,46307L,46308L,46309L,46310L,46311L,46312L,46313L,46314L,\n46315L,46316L,46317L,46318L,46319L,46320L,46321L,46322L,46323L,46324L,\n46325L,46326L,46327L,46328L,46329L,46330L,46331L,46332L,46333L,46334L,\n46335L,46336L,46337L,46338L,46339L,46340L,46341L,46342L,46343L,46344L,\n46345L,46346L,46347L,46348L,46349L,46350L,46351L,46352L,46353L,46354L,\n46355L,46356L,46357L,46358L,46359L,46360L,46361L,46362L,46363L,46364L,\n46365L,46366L,46367L,46368L,46369L,46370L,46371L,46372L,46373L,46374L,\n46375L,46376L,46377L,46378L,46379L,46380L,46381L,46382L,46383L,46384L,\n46385L,46386L,46387L,46388L,46389L,46390L,46391L,46392L,46393L,46394L,\n46395L,46396L,46397L,46398L,46399L,46400L,46401L,46402L,46403L,46404L,\n46405L,46406L,46407L,46408L,46409L,46410L,46411L,46412L,46413L,46414L,\n46415L,46416L,46417L,46418L,46419L,46420L,46421L,46422L,46423L,46424L,\n46425L,46426L,46427L,46428L,46429L,46430L,46431L,46432L,46433L,46434L,\n46435L,46436L,46437L,46438L,46439L,46440L,46441L,46442L,46443L,46444L,\n46445L,46446L,46447L,46448L,46449L,46450L,46451L,46452L,46453L,46454L,\n46455L,46456L,46457L,46458L,46459L,46460L,46461L,46462L,46463L,46464L,\n46465L,46466L,46467L,46468L,46469L,46470L,46471L,46472L,46473L,46474L,\n46475L,46476L,46477L,46478L,46479L,46480L,46481L,46482L,46483L,46484L,\n46485L,46486L,46487L,46488L,46489L,46490L,46491L,46492L,46493L,46494L,\n46495L,46496L,46497L,46498L,46499L,46500L,46501L,46502L,46503L,46504L,\n46505L,46506L,46507L,46508L,46509L,46510L,46511L,46512L,46513L,46514L,\n46515L,46516L,46517L,46518L,46519L,46520L,46521L,46522L,46523L,46524L,\n46525L,46526L,46527L,46528L,46529L,46530L,46531L,46532L,46533L,46534L,\n46535L,46536L,46537L,46538L,46539L,46540L,46541L,46542L,46543L,46544L,\n46545L,46546L,46547L,46548L,46549L,46550L,46551L,46552L,46553L,46554L,\n46555L,46556L,46557L,46558L,46559L,46560L,46561L,46562L,46563L,46564L,\n46565L,46566L,46567L,46568L,46569L,46570L,46571L,46572L,46573L,46574L,\n46575L,46576L,46577L,46578L,46579L,46580L,46581L,46582L,46583L,46584L,\n46585L,46586L,46587L,46588L,46589L,46590L,46591L,46592L,46593L,46594L,\n46595L,46596L,46597L,46598L,46599L,46600L,46601L,46602L,46603L,46604L,\n46605L,46606L,46607L,46608L,46609L,46610L,46611L,46612L,46613L,46614L,\n46615L,46616L,46617L,46618L,46619L,46620L,46621L,46622L,46623L,46624L,\n46625L,46626L,46627L,46628L,46629L,46630L,46631L,46632L,46633L,46634L,\n46635L,46636L,46637L,46638L,46639L,46640L,46641L,46642L,46643L,46644L,\n46645L,46646L,46647L,46648L,46649L,46650L,46651L,46652L,46653L,46654L,\n46655L,46656L,46657L,46658L,46659L,46660L,46661L,46662L,46663L,46664L,\n46665L,46666L,46667L,46668L,46669L,46670L,46671L,46672L,46673L,46674L,\n46675L,46676L,46677L,46678L,46679L,46680L,46681L,46682L,46683L,46684L,\n46685L,46686L,46687L,46688L,46689L,46690L,46691L,46692L,46693L,46694L,\n46695L,46696L,46697L,46698L,46699L,46700L,46701L,46702L,46703L,46704L,\n46705L,46706L,46707L,46708L,46709L,46710L,46711L,46712L,46713L,46714L,\n46715L,46716L,46717L,46718L,46719L,46720L,46721L,46722L,46723L,46724L,\n46725L,46726L,46727L,46728L,46729L,46730L,46731L,46732L,46733L,46734L,\n46735L,46736L,46737L,46738L,46739L,46740L,46741L,46742L,46743L,46744L,\n46745L,46746L,46747L,46748L,46749L,46750L,46751L,46752L,46753L,46754L,\n46755L,46756L,46757L,46758L,46759L,46760L,46761L,46762L,46763L,46764L,\n46765L,46766L,46767L,46768L,46769L,46770L,46771L,46772L,46773L,46774L,\n46775L,46776L,46777L,46778L,46779L,46780L,46781L,46782L,46783L,46784L,\n46785L,46786L,46787L,46788L,46789L,46790L,46791L,46792L,46793L,46794L,\n46795L,46796L,46797L,46798L,46799L,46800L,46801L,46802L,46803L,46804L,\n46805L,46806L,46807L,46808L,46809L,46810L,46811L,46812L,46813L,46814L,\n46815L,46816L,46817L,46818L,46819L,46820L,46821L,46822L,46823L,46824L,\n46825L,46826L,46827L,46828L,46829L,46830L,46831L,46832L,46833L,46834L,\n46835L,46836L,46837L,46838L,46839L,46840L,46841L,46842L,46843L,46844L,\n46845L,46846L,46847L,46848L,46849L,46850L,46851L,46852L,46853L,46854L,\n46855L,46856L,46857L,46858L,46859L,46860L,46861L,46862L,46863L,46864L,\n46865L,46866L,46867L,46868L,46869L,46870L,46871L,46872L,46873L,46874L,\n46875L,46876L,46877L,46878L,46879L,46880L,46881L,46882L,46883L,46884L,\n46885L,46886L,46887L,46888L,46889L,46890L,46891L,46892L,46893L,46894L,\n46895L,46896L,46897L,46898L,46899L,46900L,46901L,46902L,46903L,46904L,\n46905L,46906L,46907L,46908L,46909L,46910L,46911L,46912L,46913L,46914L,\n46915L,46916L,46917L,46918L,46919L,46920L,46921L,46922L,46923L,46924L,\n46925L,46926L,46927L,46928L,46929L,46930L,46931L,46932L,46933L,46934L,\n46935L,46936L,46937L,46938L,46939L,46940L,46941L,46942L,46943L,46944L,\n46945L,46946L,46947L,46948L,46949L,46950L,46951L,46952L,46953L,46954L,\n46955L,46956L,46957L,46958L,46959L,46960L,46961L,46962L,46963L,46964L,\n46965L,46966L,46967L,46968L,46969L,46970L,46971L,46972L,46973L,46974L,\n46975L,46976L,46977L,46978L,46979L,46980L,46981L,46982L,46983L,46984L,\n46985L,46986L,46987L,46988L,46989L,46990L,46991L,46992L,46993L,46994L,\n46995L,46996L,46997L,46998L,46999L,47000L,47001L,47002L,47003L,47004L,\n47005L,47006L,47007L,47008L,47009L,47010L,47011L,47012L,47013L,47014L,\n47015L,47016L,47017L,47018L,47019L,47020L,47021L,47022L,47023L,47024L,\n47025L,47026L,47027L,47028L,47029L,47030L,47031L,47032L,47033L,47034L,\n47035L,47036L,47037L,47038L,47039L,47040L,47041L,47042L,47043L,47044L,\n47045L,47046L,47047L,47048L,47049L,47050L,47051L,47052L,47053L,47054L,\n47055L,47056L,47057L,47058L,47059L,47060L,47061L,47062L,47063L,47064L,\n47065L,47066L,47067L,47068L,47069L,47070L,47071L,47072L,47073L,47074L,\n47075L,47076L,47077L,47078L,47079L,47080L,47081L,47082L,47083L,47084L,\n47085L,47086L,47087L,47088L,47089L,47090L,47091L,47092L,47093L,47094L,\n47095L,47096L,47097L,47098L,47099L,47100L,47101L,47102L,47103L,47104L,\n47105L,47106L,47107L,47108L,47109L,47110L,47111L,47112L,47113L,47114L,\n47115L,47116L,47117L,47118L,47119L,47120L,47121L,47122L,47123L,47124L,\n47125L,47126L,47127L,47128L,47129L,47130L,47131L,47132L,47133L,47134L,\n47135L,47136L,47137L,47138L,47139L,47140L,47141L,47142L,47143L,47144L,\n47145L,47146L,47147L,47148L,47149L,47150L,47151L,47152L,47153L,47154L,\n47155L,47156L,47157L,47158L,47159L,47160L,47161L,47162L,47163L,47164L,\n47165L,47166L,47167L,47168L,47169L,47170L,47171L,47172L,47173L,47174L,\n47175L,47176L,47177L,47178L,47179L,47180L,47181L,47182L,47183L,47184L,\n47185L,47186L,47187L,47188L,47189L,47190L,47191L,47192L,47193L,47194L,\n47195L,47196L,47197L,47198L,47199L,47200L,47201L,47202L,47203L,47204L,\n47205L,47206L,47207L,47208L,47209L,47210L,47211L,47212L,47213L,47214L,\n47215L,47216L,47217L,47218L,47219L,47220L,47221L,47222L,47223L,47224L,\n47225L,47226L,47227L,47228L,47229L,47230L,47231L,47232L,47233L,47234L,\n47235L,47236L,47237L,47238L,47239L,47240L,47241L,47242L,47243L,47244L,\n47245L,47246L,47247L,47248L,47249L,47250L,47251L,47252L,47253L,47254L,\n47255L,47256L,47257L,47258L,47259L,47260L,47261L,47262L,47263L,47264L,\n47265L,47266L,47267L,47268L,47269L,47270L,47271L,47272L,47273L,47274L,\n47275L,47276L,47277L,47278L,47279L,47280L,47281L,47282L,47283L,47284L,\n47285L,47286L,47287L,47288L,47289L,47290L,47291L,47292L,47293L,47294L,\n47295L,47296L,47297L,47298L,47299L,47300L,47301L,47302L,47303L,47304L,\n47305L,47306L,47307L,47308L,47309L,47310L,47311L,47312L,47313L,47314L,\n47315L,47316L,47317L,47318L,47319L,47320L,47321L,47322L,47323L,47324L,\n47325L,47326L,47327L,47328L,47329L,47330L,47331L,47332L,47333L,47334L,\n47335L,47336L,47337L,47338L,47339L,47340L,47341L,47342L,47343L,47344L,\n47345L,47346L,47347L,47348L,47349L,47350L,47351L,47352L,47353L,47354L,\n47355L,47356L,47357L,47358L,47359L,47360L,47361L,47362L,47363L,47364L,\n47365L,47366L,47367L,47368L,47369L,47370L,47371L,47372L,47373L,47374L,\n47375L,47376L,47377L,47378L,47379L,47380L,47381L,47382L,47383L,47384L,\n47385L,47386L,47387L,47388L,47389L,47390L,47391L,47392L,47393L,47394L,\n47395L,47396L,47397L,47398L,47399L,47400L,47401L,47402L,47403L,47404L,\n47405L,47406L,47407L,47408L,47409L,47410L,47411L,47412L,47413L,47414L,\n47415L,47416L,47417L,47418L,47419L,47420L,47421L,47422L,47423L,47424L,\n47425L,47426L,47427L,47428L,47429L,47430L,47431L,47432L,47433L,47434L,\n47435L,47436L,47437L,47438L,47439L,47440L,47441L,47442L,47443L,47444L,\n47445L,47446L,47447L,47448L,47449L,47450L,47451L,47452L,47453L,47454L,\n47455L,47456L,47457L,47458L,47459L,47460L,47461L,47462L,47463L,47464L,\n47465L,47466L,47467L,47468L,47469L,47470L,47471L,47472L,47473L,47474L,\n47475L,47476L,47477L,47478L,47479L,47480L,47481L,47482L,47483L,47484L,\n47485L,47486L,47487L,47488L,47489L,47490L,47491L,47492L,47493L,47494L,\n47495L,47496L,47497L,47498L,47499L,47500L,47501L,47502L,47503L,47504L,\n47505L,47506L,47507L,47508L,47509L,47510L,47511L,47512L,47513L,47514L,\n47515L,47516L,47517L,47518L,47519L,47520L,47521L,47522L,47523L,47524L,\n47525L,47526L,47527L,47528L,47529L,47530L,47531L,47532L,47533L,47534L,\n47535L,47536L,47537L,47538L,47539L,47540L,47541L,47542L,47543L,47544L,\n47545L,47546L,47547L,47548L,47549L,47550L,47551L,47552L,47553L,47554L,\n47555L,47556L,47557L,47558L,47559L,47560L,47561L,47562L,47563L,47564L,\n47565L,47566L,47567L,47568L,47569L,47570L,47571L,47572L,47573L,47574L,\n47575L,47576L,47577L,47578L,47579L,47580L,47581L,47582L,47583L,47584L,\n47585L,47586L,47587L,47588L,47589L,47590L,47591L,47592L,47593L,47594L,\n47595L,47596L,47597L,47598L,47599L,47600L,47601L,47602L,47603L,47604L,\n47605L,47606L,47607L,47608L,47609L,47610L,47611L,47612L,47613L,47614L,\n47615L,47616L,47617L,47618L,47619L,47620L,47621L,47622L,47623L,47624L,\n47625L,47626L,47627L,47628L,47629L,47630L,47631L,47632L,47633L,47634L,\n47635L,47636L,47637L,47638L,47639L,47640L,47641L,47642L,47643L,47644L,\n47645L,47646L,47647L,47648L,47649L,47650L,47651L,47652L,47653L,47654L,\n47655L,47656L,47657L,47658L,47659L,47660L,47661L,47662L,47663L,47664L,\n47665L,47666L,47667L,47668L,47669L,47670L,47671L,47672L,47673L,47674L,\n47675L,47676L,47677L,47678L,47679L,47680L,47681L,47682L,47683L,47684L,\n47685L,47686L,47687L,47688L,47689L,47690L,47691L,47692L,47693L,47694L,\n47695L,47696L,47697L,47698L,47699L,47700L,47701L,47702L,47703L,47704L,\n47705L,47706L,47707L,47708L,47709L,47710L,47711L,47712L,47713L,47714L,\n47715L,47716L,47717L,47718L,47719L,47720L,47721L,47722L,47723L,47724L,\n47725L,47726L,47727L,47728L,47729L,47730L,47731L,47732L,47733L,47734L,\n47735L,47736L,47737L,47738L,47739L,47740L,47741L,47742L,47743L,47744L,\n47745L,47746L,47747L,47748L,47749L,47750L,47751L,47752L,47753L,47754L,\n47755L,47756L,47757L,47758L,47759L,47760L,47761L,47762L,47763L,47764L,\n47765L,47766L,47767L,47768L,47769L,47770L,47771L,47772L,47773L,47774L,\n47775L,47776L,47777L,47778L,47779L,47780L,47781L,47782L,47783L,47784L,\n47785L,47786L,47787L,47788L,47789L,47790L,47791L,47792L,47793L,47794L,\n47795L,47796L,47797L,47798L,47799L,47800L,47801L,47802L,47803L,47804L,\n47805L,47806L,47807L,47808L,47809L,47810L,47811L,47812L,47813L,47814L,\n47815L,47816L,47817L,47818L,47819L,47820L,47821L,47822L,47823L,47824L,\n47825L,47826L,47827L,47828L,47829L,47830L,47831L,47832L,47833L,47834L,\n47835L,47836L,47837L,47838L,47839L,47840L,47841L,47842L,47843L,47844L,\n47845L,47846L,47847L,47848L,47849L,47850L,47851L,47852L,47853L,47854L,\n47855L,47856L,47857L,47858L,47859L,47860L,47861L,47862L,47863L,47864L,\n47865L,47866L,47867L,47868L,47869L,47870L,47871L,47872L,47873L,47874L,\n47875L,47876L,47877L,47878L,47879L,47880L,47881L,47882L,47883L,47884L,\n47885L,47886L,47887L,47888L,47889L,47890L,47891L,47892L,47893L,47894L,\n47895L,47896L,47897L,47898L,47899L,47900L,47901L,47902L,47903L,47904L,\n47905L,47906L,47907L,47908L,47909L,47910L,47911L,47912L,47913L,47914L,\n47915L,47916L,47917L,47918L,47919L,47920L,47921L,47922L,47923L,47924L,\n47925L,47926L,47927L,47928L,47929L,47930L,47931L,47932L,47933L,47934L,\n47935L,47936L,47937L,47938L,47939L,47940L,47941L,47942L,47943L,47944L,\n47945L,47946L,47947L,47948L,47949L,47950L,47951L,47952L,47953L,47954L,\n47955L,47956L,47957L,47958L,47959L,47960L,47961L,47962L,47963L,47964L,\n47965L,47966L,47967L,47968L,47969L,47970L,47971L,47972L,47973L,47974L,\n47975L,47976L,47977L,47978L,47979L,47980L,47981L,47982L,47983L,47984L,\n47985L,47986L,47987L,47988L,47989L,47990L,47991L,47992L,47993L,47994L,\n47995L,47996L,47997L,47998L,47999L,48000L,48001L,48002L,48003L,48004L,\n48005L,48006L,48007L,48008L,48009L,48010L,48011L,48012L,48013L,48014L,\n48015L,48016L,48017L,48018L,48019L,48020L,48021L,48022L,48023L,48024L,\n48025L,48026L,48027L,48028L,48029L,48030L,48031L,48032L,48033L,48034L,\n48035L,48036L,48037L,48038L,48039L,48040L,48041L,48042L,48043L,48044L,\n48045L,48046L,48047L,48048L,48049L,48050L,48051L,48052L,48053L,48054L,\n48055L,48056L,48057L,48058L,48059L,48060L,48061L,48062L,48063L,48064L,\n48065L,48066L,48067L,48068L,48069L,48070L,48071L,48072L,48073L,48074L,\n48075L,48076L,48077L,48078L,48079L,48080L,48081L,48082L,48083L,48084L,\n48085L,48086L,48087L,48088L,48089L,48090L,48091L,48092L,48093L,48094L,\n48095L,48096L,48097L,48098L,48099L,48100L,48101L,48102L,48103L,48104L,\n48105L,48106L,48107L,48108L,48109L,48110L,48111L,48112L,48113L,48114L,\n48115L,48116L,48117L,48118L,48119L,48120L,48121L,48122L,48123L,48124L,\n48125L,48126L,48127L,48128L,48129L,48130L,48131L,48132L,48133L,48134L,\n48135L,48136L,48137L,48138L,48139L,48140L,48141L,48142L,48143L,48144L,\n48145L,48146L,48147L,48148L,48149L,48150L,48151L,48152L,48153L,48154L,\n48155L,48156L,48157L,48158L,48159L,48160L,48161L,48162L,48163L,48164L,\n48165L,48166L,48167L,48168L,48169L,48170L,48171L,48172L,48173L,48174L,\n48175L,48176L,48177L,48178L,48179L,48180L,48181L,48182L,48183L,48184L,\n48185L,48186L,48187L,48188L,48189L,48190L,48191L,48192L,48193L,48194L,\n48195L,48196L,48197L,48198L,48199L,48200L,48201L,48202L,48203L,48204L,\n48205L,48206L,48207L,48208L,48209L,48210L,48211L,48212L,48213L,48214L,\n48215L,48216L,48217L,48218L,48219L,48220L,48221L,48222L,48223L,48224L,\n48225L,48226L,48227L,48228L,48229L,48230L,48231L,48232L,48233L,48234L,\n48235L,48236L,48237L,48238L,48239L,48240L,48241L,48242L,48243L,48244L,\n48245L,48246L,48247L,48248L,48249L,48250L,48251L,48252L,48253L,48254L,\n48255L,48256L,48257L,48258L,48259L,48260L,48261L,48262L,48263L,48264L,\n48265L,48266L,48267L,48268L,48269L,48270L,48271L,48272L,48273L,48274L,\n48275L,48276L,48277L,48278L,48279L,48280L,48281L,48282L,48283L,48284L,\n48285L,48286L,48287L,48288L,48289L,48290L,48291L,48292L,48293L,48294L,\n48295L,48296L,48297L,48298L,48299L,48300L,48301L,48302L,48303L,48304L,\n48305L,48306L,48307L,48308L,48309L,48310L,48311L,48312L,48313L,48314L,\n48315L,48316L,48317L,48318L,48319L,48320L,48321L,48322L,48323L,48324L,\n48325L,48326L,48327L,48328L,48329L,48330L,48331L,48332L,48333L,48334L,\n48335L,48336L,48337L,48338L,48339L,48340L,48341L,48342L,48343L,48344L,\n48345L,48346L,48347L,48348L,48349L,48350L,48351L,48352L,48353L,48354L,\n48355L,48356L,48357L,48358L,48359L,48360L,48361L,48362L,48363L,48364L,\n48365L,48366L,48367L,48368L,48369L,48370L,48371L,48372L,48373L,48374L,\n48375L,48376L,48377L,48378L,48379L,48380L,48381L,48382L,48383L,48384L,\n48385L,48386L,48387L,48388L,48389L,48390L,48391L,48392L,48393L,48394L,\n48395L,48396L,48397L,48398L,48399L,48400L,48401L,48402L,48403L,48404L,\n48405L,48406L,48407L,48408L,48409L,48410L,48411L,48412L,48413L,48414L,\n48415L,48416L,48417L,48418L,48419L,48420L,48421L,48422L,48423L,48424L,\n48425L,48426L,48427L,48428L,48429L,48430L,48431L,48432L,48433L,48434L,\n48435L,48436L,48437L,48438L,48439L,48440L,48441L,48442L,48443L,48444L,\n48445L,48446L,48447L,48448L,48449L,48450L,48451L,48452L,48453L,48454L,\n48455L,48456L,48457L,48458L,48459L,48460L,48461L,48462L,48463L,48464L,\n48465L,48466L,48467L,48468L,48469L,48470L,48471L,48472L,48473L,48474L,\n48475L,48476L,48477L,48478L,48479L,48480L,48481L,48482L,48483L,48484L,\n48485L,48486L,48487L,48488L,48489L,48490L,48491L,48492L,48493L,48494L,\n48495L,48496L,48497L,48498L,48499L,48500L,48501L,48502L,48503L,48504L,\n48505L,48506L,48507L,48508L,48509L,48510L,48511L,48512L,48513L,48514L,\n48515L,48516L,48517L,48518L,48519L,48520L,48521L,48522L,48523L,48524L,\n48525L,48526L,48527L,48528L,48529L,48530L,48531L,48532L,48533L,48534L,\n48535L,48536L,48537L,48538L,48539L,48540L,48541L,48542L,48543L,48544L,\n48545L,48546L,48547L,48548L,48549L,48550L,48551L,48552L,48553L,48554L,\n48555L,48556L,48557L,48558L,48559L,48560L,48561L,48562L,48563L,48564L,\n48565L,48566L,48567L,48568L,48569L,48570L,48571L,48572L,48573L,48574L,\n48575L,48576L,48577L,48578L,48579L,48580L,48581L,48582L,48583L,48584L,\n48585L,48586L,48587L,48588L,48589L,48590L,48591L,48592L,48593L,48594L,\n48595L,48596L,48597L,48598L,48599L,48600L,48601L,48602L,48603L,48604L,\n48605L,48606L,48607L,48608L,48609L,48610L,48611L,48612L,48613L,48614L,\n48615L,48616L,48617L,48618L,48619L,48620L,48621L,48622L,48623L,48624L,\n48625L,48626L,48627L,48628L,48629L,48630L,48631L,48632L,48633L,48634L,\n48635L,48636L,48637L,48638L,48639L,48640L,48641L,48642L,48643L,48644L,\n48645L,48646L,48647L,48648L,48649L,48650L,48651L,48652L,48653L,48654L,\n48655L,48656L,48657L,48658L,48659L,48660L,48661L,48662L,48663L,48664L,\n48665L,48666L,48667L,48668L,48669L,48670L,48671L,48672L,48673L,48674L,\n48675L,48676L,48677L,48678L,48679L,48680L,48681L,48682L,48683L,48684L,\n48685L,48686L,48687L,48688L,48689L,48690L,48691L,48692L,48693L,48694L,\n48695L,48696L,48697L,48698L,48699L,48700L,48701L,48702L,48703L,48704L,\n48705L,48706L,48707L,48708L,48709L,48710L,48711L,48712L,48713L,48714L,\n48715L,48716L,48717L,48718L,48719L,48720L,48721L,48722L,48723L,48724L,\n48725L,48726L,48727L,48728L,48729L,48730L,48731L,48732L,48733L,48734L,\n48735L,48736L,48737L,48738L,48739L,48740L,48741L,48742L,48743L,48744L,\n48745L,48746L,48747L,48748L,48749L,48750L,48751L,48752L,48753L,48754L,\n48755L,48756L,48757L,48758L,48759L,48760L,48761L,48762L,48763L,48764L,\n48765L,48766L,48767L,48768L,48769L,48770L,48771L,48772L,48773L,48774L,\n48775L,48776L,48777L,48778L,48779L,48780L,48781L,48782L,48783L,48784L,\n48785L,48786L,48787L,48788L,48789L,48790L,48791L,48792L,48793L,48794L,\n48795L,48796L,48797L,48798L,48799L,48800L,48801L,48802L,48803L,48804L,\n48805L,48806L,48807L,48808L,48809L,48810L,48811L,48812L,48813L,48814L,\n48815L,48816L,48817L,48818L,48819L,48820L,48821L,48822L,48823L,48824L,\n48825L,48826L,48827L,48828L,48829L,48830L,48831L,48832L,48833L,48834L,\n48835L,48836L,48837L,48838L,48839L,48840L,48841L,48842L,48843L,48844L,\n48845L,48846L,48847L,48848L,48849L,48850L,48851L,48852L,48853L,48854L,\n48855L,48856L,48857L,48858L,48859L,48860L,48861L,48862L,48863L,48864L,\n48865L,48866L,48867L,48868L,48869L,48870L,48871L,48872L,48873L,48874L,\n48875L,48876L,48877L,48878L,48879L,48880L,48881L,48882L,48883L,48884L,\n48885L,48886L,48887L,48888L,48889L,48890L,48891L,48892L,48893L,48894L,\n48895L,48896L,48897L,48898L,48899L,48900L,48901L,48902L,48903L,48904L,\n48905L,48906L,48907L,48908L,48909L,48910L,48911L,48912L,48913L,48914L,\n48915L,48916L,48917L,48918L,48919L,48920L,48921L,48922L,48923L,48924L,\n48925L,48926L,48927L,48928L,48929L,48930L,48931L,48932L,48933L,48934L,\n48935L,48936L,48937L,48938L,48939L,48940L,48941L,48942L,48943L,48944L,\n48945L,48946L,48947L,48948L,48949L,48950L,48951L,48952L,48953L,48954L,\n48955L,48956L,48957L,48958L,48959L,48960L,48961L,48962L,48963L,48964L,\n48965L,48966L,48967L,48968L,48969L,48970L,48971L,48972L,48973L,48974L,\n48975L,48976L,48977L,48978L,48979L,48980L,48981L,48982L,48983L,48984L,\n48985L,48986L,48987L,48988L,48989L,48990L,48991L,48992L,48993L,48994L,\n48995L,48996L,48997L,48998L,48999L,49000L,49001L,49002L,49003L,49004L,\n49005L,49006L,49007L,49008L,49009L,49010L,49011L,49012L,49013L,49014L,\n49015L,49016L,49017L,49018L,49019L,49020L,49021L,49022L,49023L,49024L,\n49025L,49026L,49027L,49028L,49029L,49030L,49031L,49032L,49033L,49034L,\n49035L,49036L,49037L,49038L,49039L,49040L,49041L,49042L,49043L,49044L,\n49045L,49046L,49047L,49048L,49049L,49050L,49051L,49052L,49053L,49054L,\n49055L,49056L,49057L,49058L,49059L,49060L,49061L,49062L,49063L,49064L,\n49065L,49066L,49067L,49068L,49069L,49070L,49071L,49072L,49073L,49074L,\n49075L,49076L,49077L,49078L,49079L,49080L,49081L,49082L,49083L,49084L,\n49085L,49086L,49087L,49088L,49089L,49090L,49091L,49092L,49093L,49094L,\n49095L,49096L,49097L,49098L,49099L,49100L,49101L,49102L,49103L,49104L,\n49105L,49106L,49107L,49108L,49109L,49110L,49111L,49112L,49113L,49114L,\n49115L,49116L,49117L,49118L,49119L,49120L,49121L,49122L,49123L,49124L,\n49125L,49126L,49127L,49128L,49129L,49130L,49131L,49132L,49133L,49134L,\n49135L,49136L,49137L,49138L,49139L,49140L,49141L,49142L,49143L,49144L,\n49145L,49146L,49147L,49148L,49149L,49150L,49151L,49152L,49153L,49154L,\n49155L,49156L,49157L,49158L,49159L,49160L,49161L,49162L,49163L,49164L,\n49165L,49166L,49167L,49168L,49169L,49170L,49171L,49172L,49173L,49174L,\n49175L,49176L,49177L,49178L,49179L,49180L,49181L,49182L,49183L,49184L,\n49185L,49186L,49187L,49188L,49189L,49190L,49191L,49192L,49193L,49194L,\n49195L,49196L,49197L,49198L,49199L,49200L,49201L,49202L,49203L,49204L,\n49205L,49206L,49207L,49208L,49209L,49210L,49211L,49212L,49213L,49214L,\n49215L,49216L,49217L,49218L,49219L,49220L,49221L,49222L,49223L,49224L,\n49225L,49226L,49227L,49228L,49229L,49230L,49231L,49232L,49233L,49234L,\n49235L,49236L,49237L,49238L,49239L,49240L,49241L,49242L,49243L,49244L,\n49245L,49246L,49247L,49248L,49249L,49250L,49251L,49252L,49253L,49254L,\n49255L,49256L,49257L,49258L,49259L,49260L,49261L,49262L,49263L,49264L,\n49265L,49266L,49267L,49268L,49269L,49270L,49271L,49272L,49273L,49274L,\n49275L,49276L,49277L,49278L,49279L,49280L,49281L,49282L,49283L,49284L,\n49285L,49286L,49287L,49288L,49289L,49290L,49291L,49292L,49293L,49294L,\n49295L,49296L,49297L,49298L,49299L,49300L,49301L,49302L,49303L,49304L,\n49305L,49306L,49307L,49308L,49309L,49310L,49311L,49312L,49313L,49314L,\n49315L,49316L,49317L,49318L,49319L,49320L,49321L,49322L,49323L,49324L,\n49325L,49326L,49327L,49328L,49329L,49330L,49331L,49332L,49333L,49334L,\n49335L,49336L,49337L,49338L,49339L,49340L,49341L,49342L,49343L,49344L,\n49345L,49346L,49347L,49348L,49349L,49350L,49351L,49352L,49353L,49354L,\n49355L,49356L,49357L,49358L,49359L,49360L,49361L,49362L,49363L,49364L,\n49365L,49366L,49367L,49368L,49369L,49370L,49371L,49372L,49373L,49374L,\n49375L,49376L,49377L,49378L,49379L,49380L,49381L,49382L,49383L,49384L,\n49385L,49386L,49387L,49388L,49389L,49390L,49391L,49392L,49393L,49394L,\n49395L,49396L,49397L,49398L,49399L,49400L,49401L,49402L,49403L,49404L,\n49405L,49406L,49407L,49408L,49409L,49410L,49411L,49412L,49413L,49414L,\n49415L,49416L,49417L,49418L,49419L,49420L,49421L,49422L,49423L,49424L,\n49425L,49426L,49427L,49428L,49429L,49430L,49431L,49432L,49433L,49434L,\n49435L,49436L,49437L,49438L,49439L,49440L,49441L,49442L,49443L,49444L,\n49445L,49446L,49447L,49448L,49449L,49450L,49451L,49452L,49453L,49454L,\n49455L,49456L,49457L,49458L,49459L,49460L,49461L,49462L,49463L,49464L,\n49465L,49466L,49467L,49468L,49469L,49470L,49471L,49472L,49473L,49474L,\n49475L,49476L,49477L,49478L,49479L,49480L,49481L,49482L,49483L,49484L,\n49485L,49486L,49487L,49488L,49489L,49490L,49491L,49492L,49493L,49494L,\n49495L,49496L,49497L,49498L,49499L,49500L,49501L,49502L,49503L,49504L,\n49505L,49506L,49507L,49508L,49509L,49510L,49511L,49512L,49513L,49514L,\n49515L,49516L,49517L,49518L,49519L,49520L,49521L,49522L,49523L,49524L,\n49525L,49526L,49527L,49528L,49529L,49530L,49531L,49532L,49533L,49534L,\n49535L,49536L,49537L,49538L,49539L,49540L,49541L,49542L,49543L,49544L,\n49545L,49546L,49547L,49548L,49549L,49550L,49551L,49552L,49553L,49554L,\n49555L,49556L,49557L,49558L,49559L,49560L,49561L,49562L,49563L,49564L,\n49565L,49566L,49567L,49568L,49569L,49570L,49571L,49572L,49573L,49574L,\n49575L,49576L,49577L,49578L,49579L,49580L,49581L,49582L,49583L,49584L,\n49585L,49586L,49587L,49588L,49589L,49590L,49591L,49592L,49593L,49594L,\n49595L,49596L,49597L,49598L,49599L,49600L,49601L,49602L,49603L,49604L,\n49605L,49606L,49607L,49608L,49609L,49610L,49611L,49612L,49613L,49614L,\n49615L,49616L,49617L,49618L,49619L,49620L,49621L,49622L,49623L,49624L,\n49625L,49626L,49627L,49628L,49629L,49630L,49631L,49632L,49633L,49634L,\n49635L,49636L,49637L,49638L,49639L,49640L,49641L,49642L,49643L,49644L,\n49645L,49646L,49647L,49648L,49649L,49650L,49651L,49652L,49653L,49654L,\n49655L,49656L,49657L,49658L,49659L,49660L,49661L,49662L,49663L,49664L,\n49665L,49666L,49667L,49668L,49669L,49670L,49671L,49672L,49673L,49674L,\n49675L,49676L,49677L,49678L,49679L,49680L,49681L,49682L,49683L,49684L,\n49685L,49686L,49687L,49688L,49689L,49690L,49691L,49692L,49693L,49694L,\n49695L,49696L,49697L,49698L,49699L,49700L,49701L,49702L,49703L,49704L,\n49705L,49706L,49707L,49708L,49709L,49710L,49711L,49712L,49713L,49714L,\n49715L,49716L,49717L,49718L,49719L,49720L,49721L,49722L,49723L,49724L,\n49725L,49726L,49727L,49728L,49729L,49730L,49731L,49732L,49733L,49734L,\n49735L,49736L,49737L,49738L,49739L,49740L,49741L,49742L,49743L,49744L,\n49745L,49746L,49747L,49748L,49749L,49750L,49751L,49752L,49753L,49754L,\n49755L,49756L,49757L,49758L,49759L,49760L,49761L,49762L,49763L,49764L,\n49765L,49766L,49767L,49768L,49769L,49770L,49771L,49772L,49773L,49774L,\n49775L,49776L,49777L,49778L,49779L,49780L,49781L,49782L,49783L,49784L,\n49785L,49786L,49787L,49788L,49789L,49790L,49791L,49792L,49793L,49794L,\n49795L,49796L,49797L,49798L,49799L,49800L,49801L,49802L,49803L,49804L,\n49805L,49806L,49807L,49808L,49809L,49810L,49811L,49812L,49813L,49814L,\n49815L,49816L,49817L,49818L,49819L,49820L,49821L,49822L,49823L,49824L,\n49825L,49826L,49827L,49828L,49829L,49830L,49831L,49832L,49833L,49834L,\n49835L,49836L,49837L,49838L,49839L,49840L,49841L,49842L,49843L,49844L,\n49845L,49846L,49847L,49848L,49849L,49850L,49851L,49852L,49853L,49854L,\n49855L,49856L,49857L,49858L,49859L,49860L,49861L,49862L,49863L,49864L,\n49865L,49866L,49867L,49868L,49869L,49870L,49871L,49872L,49873L,49874L,\n49875L,49876L,49877L,49878L,49879L,49880L,49881L,49882L,49883L,49884L,\n49885L,49886L,49887L,49888L,49889L,49890L,49891L,49892L,49893L,49894L,\n49895L,49896L,49897L,49898L,49899L,49900L,49901L,49902L,49903L,49904L,\n49905L,49906L,49907L,49908L,49909L,49910L,49911L,49912L,49913L,49914L,\n49915L,49916L,49917L,49918L,49919L,49920L,49921L,49922L,49923L,49924L,\n49925L,49926L,49927L,49928L,49929L,49930L,49931L,49932L,49933L,49934L,\n49935L,49936L,49937L,49938L,49939L,49940L,49941L,49942L,49943L,49944L,\n49945L,49946L,49947L,49948L,49949L,49950L,49951L,49952L,49953L,49954L,\n49955L,49956L,49957L,49958L,49959L,49960L,49961L,49962L,49963L,49964L,\n49965L,49966L,49967L,49968L,49969L,49970L,49971L,49972L,49973L,49974L,\n49975L,49976L,49977L,49978L,49979L,49980L,49981L,49982L,49983L,49984L,\n49985L,49986L,49987L,49988L,49989L,49990L,49991L,49992L,49993L,49994L,\n49995L,49996L,49997L,49998L,49999L,50000L,50001L,50002L,50003L,50004L,\n50005L,50006L,50007L,50008L,50009L,50010L,50011L,50012L,50013L,50014L,\n50015L,50016L,50017L,50018L,50019L,50020L,50021L,50022L,50023L,50024L,\n50025L,50026L,50027L,50028L,50029L,50030L,50031L,50032L,50033L,50034L,\n50035L,50036L,50037L,50038L,50039L,50040L,50041L,50042L,50043L,50044L,\n50045L,50046L,50047L,50048L,50049L,50050L,50051L,50052L,50053L,50054L,\n50055L,50056L,50057L,50058L,50059L,50060L,50061L,50062L,50063L,50064L,\n50065L,50066L,50067L,50068L,50069L,50070L,50071L,50072L,50073L,50074L,\n50075L,50076L,50077L,50078L,50079L,50080L,50081L,50082L,50083L,50084L,\n50085L,50086L,50087L,50088L,50089L,50090L,50091L,50092L,50093L,50094L,\n50095L,50096L,50097L,50098L,50099L,50100L,50101L,50102L,50103L,50104L,\n50105L,50106L,50107L,50108L,50109L,50110L,50111L,50112L,50113L,50114L,\n50115L,50116L,50117L,50118L,50119L,50120L,50121L,50122L,50123L,50124L,\n50125L,50126L,50127L,50128L,50129L,50130L,50131L,50132L,50133L,50134L,\n50135L,50136L,50137L,50138L,50139L,50140L,50141L,50142L,50143L,50144L,\n50145L,50146L,50147L,50148L,50149L,50150L,50151L,50152L,50153L,50154L,\n50155L,50156L,50157L,50158L,50159L,50160L,50161L,50162L,50163L,50164L,\n50165L,50166L,50167L,50168L,50169L,50170L,50171L,50172L,50173L,50174L,\n50175L,50176L,50177L,50178L,50179L,50180L,50181L,50182L,50183L,50184L,\n50185L,50186L,50187L,50188L,50189L,50190L,50191L,50192L,50193L,50194L,\n50195L,50196L,50197L,50198L,50199L,50200L,50201L,50202L,50203L,50204L,\n50205L,50206L,50207L,50208L,50209L,50210L,50211L,50212L,50213L,50214L,\n50215L,50216L,50217L,50218L,50219L,50220L,50221L,50222L,50223L,50224L,\n50225L,50226L,50227L,50228L,50229L,50230L,50231L,50232L,50233L,50234L,\n50235L,50236L,50237L,50238L,50239L,50240L,50241L,50242L,50243L,50244L,\n50245L,50246L,50247L,50248L,50249L,50250L,50251L,50252L,50253L,50254L,\n50255L,50256L,50257L,50258L,50259L,50260L,50261L,50262L,50263L,50264L,\n50265L,50266L,50267L,50268L,50269L,50270L,50271L,50272L,50273L,50274L,\n50275L,50276L,50277L,50278L,50279L,50280L,50281L,50282L,50283L,50284L,\n50285L,50286L,50287L,50288L,50289L,50290L,50291L,50292L,50293L,50294L,\n50295L,50296L,50297L,50298L,50299L,50300L,50301L,50302L,50303L,50304L,\n50305L,50306L,50307L,50308L,50309L,50310L,50311L,50312L,50313L,50314L,\n50315L,50316L,50317L,50318L,50319L,50320L,50321L,50322L,50323L,50324L,\n50325L,50326L,50327L,50328L,50329L,50330L,50331L,50332L,50333L,50334L,\n50335L,50336L,50337L,50338L,50339L,50340L,50341L,50342L,50343L,50344L,\n50345L,50346L,50347L,50348L,50349L,50350L,50351L,50352L,50353L,50354L,\n50355L,50356L,50357L,50358L,50359L,50360L,50361L,50362L,50363L,50364L,\n50365L,50366L,50367L,50368L,50369L,50370L,50371L,50372L,50373L,50374L,\n50375L,50376L,50377L,50378L,50379L,50380L,50381L,50382L,50383L,50384L,\n50385L,50386L,50387L,50388L,50389L,50390L,50391L,50392L,50393L,50394L,\n50395L,50396L,50397L,50398L,50399L,50400L,50401L,50402L,50403L,50404L,\n50405L,50406L,50407L,50408L,50409L,50410L,50411L,50412L,50413L,50414L,\n50415L,50416L,50417L,50418L,50419L,50420L,50421L,50422L,50423L,50424L,\n50425L,50426L,50427L,50428L,50429L,50430L,50431L,50432L,50433L,50434L,\n50435L,50436L,50437L,50438L,50439L,50440L,50441L,50442L,50443L,50444L,\n50445L,50446L,50447L,50448L,50449L,50450L,50451L,50452L,50453L,50454L,\n50455L,50456L,50457L,50458L,50459L,50460L,50461L,50462L,50463L,50464L,\n50465L,50466L,50467L,50468L,50469L,50470L,50471L,50472L,50473L,50474L,\n50475L,50476L,50477L,50478L,50479L,50480L,50481L,50482L,50483L,50484L,\n50485L,50486L,50487L,50488L,50489L,50490L,50491L,50492L,50493L,50494L,\n50495L,50496L,50497L,50498L,50499L,50500L,50501L,50502L,50503L,50504L,\n50505L,50506L,50507L,50508L,50509L,50510L,50511L,50512L,50513L,50514L,\n50515L,50516L,50517L,50518L,50519L,50520L,50521L,50522L,50523L,50524L,\n50525L,50526L,50527L,50528L,50529L,50530L,50531L,50532L,50533L,50534L,\n50535L,50536L,50537L,50538L,50539L,50540L,50541L,50542L,50543L,50544L,\n50545L,50546L,50547L,50548L,50549L,50550L,50551L,50552L,50553L,50554L,\n50555L,50556L,50557L,50558L,50559L,50560L,50561L,50562L,50563L,50564L,\n50565L,50566L,50567L,50568L,50569L,50570L,50571L,50572L,50573L,50574L,\n50575L,50576L,50577L,50578L,50579L,50580L,50581L,50582L,50583L,50584L,\n50585L,50586L,50587L,50588L,50589L,50590L,50591L,50592L,50593L,50594L,\n50595L,50596L,50597L,50598L,50599L,50600L,50601L,50602L,50603L,50604L,\n50605L,50606L,50607L,50608L,50609L,50610L,50611L,50612L,50613L,50614L,\n50615L,50616L,50617L,50618L,50619L,50620L,50621L,50622L,50623L,50624L,\n50625L,50626L,50627L,50628L,50629L,50630L,50631L,50632L,50633L,50634L,\n50635L,50636L,50637L,50638L,50639L,50640L,50641L,50642L,50643L,50644L,\n50645L,50646L,50647L,50648L,50649L,50650L,50651L,50652L,50653L,50654L,\n50655L,50656L,50657L,50658L,50659L,50660L,50661L,50662L,50663L,50664L,\n50665L,50666L,50667L,50668L,50669L,50670L,50671L,50672L,50673L,50674L,\n50675L,50676L,50677L,50678L,50679L,50680L,50681L,50682L,50683L,50684L,\n50685L,50686L,50687L,50688L,50689L,50690L,50691L,50692L,50693L,50694L,\n50695L,50696L,50697L,50698L,50699L,50700L,50701L,50702L,50703L,50704L,\n50705L,50706L,50707L,50708L,50709L,50710L,50711L,50712L,50713L,50714L,\n50715L,50716L,50717L,50718L,50719L,50720L,50721L,50722L,50723L,50724L,\n50725L,50726L,50727L,50728L,50729L,50730L,50731L,50732L,50733L,50734L,\n50735L,50736L,50737L,50738L,50739L,50740L,50741L,50742L,50743L,50744L,\n50745L,50746L,50747L,50748L,50749L,50750L,50751L,50752L,50753L,50754L,\n50755L,50756L,50757L,50758L,50759L,50760L,50761L,50762L,50763L,50764L,\n50765L,50766L,50767L,50768L,50769L,50770L,50771L,50772L,50773L,50774L,\n50775L,50776L,50777L,50778L,50779L,50780L,50781L,50782L,50783L,50784L,\n50785L,50786L,50787L,50788L,50789L,50790L,50791L,50792L,50793L,50794L,\n50795L,50796L,50797L,50798L,50799L,50800L,50801L,50802L,50803L,50804L,\n50805L,50806L,50807L,50808L,50809L,50810L,50811L,50812L,50813L,50814L,\n50815L,50816L,50817L,50818L,50819L,50820L,50821L,50822L,50823L,50824L,\n50825L,50826L,50827L,50828L,50829L,50830L,50831L,50832L,50833L,50834L,\n50835L,50836L,50837L,50838L,50839L,50840L,50841L,50842L,50843L,50844L,\n50845L,50846L,50847L,50848L,50849L,50850L,50851L,50852L,50853L,50854L,\n50855L,50856L,50857L,50858L,50859L,50860L,50861L,50862L,50863L,50864L,\n50865L,50866L,50867L,50868L,50869L,50870L,50871L,50872L,50873L,50874L,\n50875L,50876L,50877L,50878L,50879L,50880L,50881L,50882L,50883L,50884L,\n50885L,50886L,50887L,50888L,50889L,50890L,50891L,50892L,50893L,50894L,\n50895L,50896L,50897L,50898L,50899L,50900L,50901L,50902L,50903L,50904L,\n50905L,50906L,50907L,50908L,50909L,50910L,50911L,50912L,50913L,50914L,\n50915L,50916L,50917L,50918L,50919L,50920L,50921L,50922L,50923L,50924L,\n50925L,50926L,50927L,50928L,50929L,50930L,50931L,50932L,50933L,50934L,\n50935L,50936L,50937L,50938L,50939L,50940L,50941L,50942L,50943L,50944L,\n50945L,50946L,50947L,50948L,50949L,50950L,50951L,50952L,50953L,50954L,\n50955L,50956L,50957L,50958L,50959L,50960L,50961L,50962L,50963L,50964L,\n50965L,50966L,50967L,50968L,50969L,50970L,50971L,50972L,50973L,50974L,\n50975L,50976L,50977L,50978L,50979L,50980L,50981L,50982L,50983L,50984L,\n50985L,50986L,50987L,50988L,50989L,50990L,50991L,50992L,50993L,50994L,\n50995L,50996L,50997L,50998L,50999L,51000L,51001L,51002L,51003L,51004L,\n51005L,51006L,51007L,51008L,51009L,51010L,51011L,51012L,51013L,51014L,\n51015L,51016L,51017L,51018L,51019L,51020L,51021L,51022L,51023L,51024L,\n51025L,51026L,51027L,51028L,51029L,51030L,51031L,51032L,51033L,51034L,\n51035L,51036L,51037L,51038L,51039L,51040L,51041L,51042L,51043L,51044L,\n51045L,51046L,51047L,51048L,51049L,51050L,51051L,51052L,51053L,51054L,\n51055L,51056L,51057L,51058L,51059L,51060L,51061L,51062L,51063L,51064L,\n51065L,51066L,51067L,51068L,51069L,51070L,51071L,51072L,51073L,51074L,\n51075L,51076L,51077L,51078L,51079L,51080L,51081L,51082L,51083L,51084L,\n51085L,51086L,51087L,51088L,51089L,51090L,51091L,51092L,51093L,51094L,\n51095L,51096L,51097L,51098L,51099L,51100L,51101L,51102L,51103L,51104L,\n51105L,51106L,51107L,51108L,51109L,51110L,51111L,51112L,51113L,51114L,\n51115L,51116L,51117L,51118L,51119L,51120L,51121L,51122L,51123L,51124L,\n51125L,51126L,51127L,51128L,51129L,51130L,51131L,51132L,51133L,51134L,\n51135L,51136L,51137L,51138L,51139L,51140L,51141L,51142L,51143L,51144L,\n51145L,51146L,51147L,51148L,51149L,51150L,51151L,51152L,51153L,51154L,\n51155L,51156L,51157L,51158L,51159L,51160L,51161L,51162L,51163L,51164L,\n51165L,51166L,51167L,51168L,51169L,51170L,51171L,51172L,51173L,51174L,\n51175L,51176L,51177L,51178L,51179L,51180L,51181L,51182L,51183L,51184L,\n51185L,51186L,51187L,51188L,51189L,51190L,51191L,51192L,51193L,51194L,\n51195L,51196L,51197L,51198L,51199L,51200L,51201L,51202L,51203L,51204L,\n51205L,51206L,51207L,51208L,51209L,51210L,51211L,51212L,51213L,51214L,\n51215L,51216L,51217L,51218L,51219L,51220L,51221L,51222L,51223L,51224L,\n51225L,51226L,51227L,51228L,51229L,51230L,51231L,51232L,51233L,51234L,\n51235L,51236L,51237L,51238L,51239L,51240L,51241L,51242L,51243L,51244L,\n51245L,51246L,51247L,51248L,51249L,51250L,51251L,51252L,51253L,51254L,\n51255L,51256L,51257L,51258L,51259L,51260L,51261L,51262L,51263L,51264L,\n51265L,51266L,51267L,51268L,51269L,51270L,51271L,51272L,51273L,51274L,\n51275L,51276L,51277L,51278L,51279L,51280L,51281L,51282L,51283L,51284L,\n51285L,51286L,51287L,51288L,51289L,51290L,51291L,51292L,51293L,51294L,\n51295L,51296L,51297L,51298L,51299L,51300L,51301L,51302L,51303L,51304L,\n51305L,51306L,51307L,51308L,51309L,51310L,51311L,51312L,51313L,51314L,\n51315L,51316L,51317L,51318L,51319L,51320L,51321L,51322L,51323L,51324L,\n51325L,51326L,51327L,51328L,51329L,51330L,51331L,51332L,51333L,51334L,\n51335L,51336L,51337L,51338L,51339L,51340L,51341L,51342L,51343L,51344L,\n51345L,51346L,51347L,51348L,51349L,51350L,51351L,51352L,51353L,51354L,\n51355L,51356L,51357L,51358L,51359L,51360L,51361L,51362L,51363L,51364L,\n51365L,51366L,51367L,51368L,51369L,51370L,51371L,51372L,51373L,51374L,\n51375L,51376L,51377L,51378L,51379L,51380L,51381L,51382L,51383L,51384L,\n51385L,51386L,51387L,51388L,51389L,51390L,51391L,51392L,51393L,51394L,\n51395L,51396L,51397L,51398L,51399L,51400L,51401L,51402L,51403L,51404L,\n51405L,51406L,51407L,51408L,51409L,51410L,51411L,51412L,51413L,51414L,\n51415L,51416L,51417L,51418L,51419L,51420L,51421L,51422L,51423L,51424L,\n51425L,51426L,51427L,51428L,51429L,51430L,51431L,51432L,51433L,51434L,\n51435L,51436L,51437L,51438L,51439L,51440L,51441L,51442L,51443L,51444L,\n51445L,51446L,51447L,51448L,51449L,51450L,51451L,51452L,51453L,51454L,\n51455L,51456L,51457L,51458L,51459L,51460L,51461L,51462L,51463L,51464L,\n51465L,51466L,51467L,51468L,51469L,51470L,51471L,51472L,51473L,51474L,\n51475L,51476L,51477L,51478L,51479L,51480L,51481L,51482L,51483L,51484L,\n51485L,51486L,51487L,51488L,51489L,51490L,51491L,51492L,51493L,51494L,\n51495L,51496L,51497L,51498L,51499L,51500L,51501L,51502L,51503L,51504L,\n51505L,51506L,51507L,51508L,51509L,51510L,51511L,51512L,51513L,51514L,\n51515L,51516L,51517L,51518L,51519L,51520L,51521L,51522L,51523L,51524L,\n51525L,51526L,51527L,51528L,51529L,51530L,51531L,51532L,51533L,51534L,\n51535L,51536L,51537L,51538L,51539L,51540L,51541L,51542L,51543L,51544L,\n51545L,51546L,51547L,51548L,51549L,51550L,51551L,51552L,51553L,51554L,\n51555L,51556L,51557L,51558L,51559L,51560L,51561L,51562L,51563L,51564L,\n51565L,51566L,51567L,51568L,51569L,51570L,51571L,51572L,51573L,51574L,\n51575L,51576L,51577L,51578L,51579L,51580L,51581L,51582L,51583L,51584L,\n51585L,51586L,51587L,51588L,51589L,51590L,51591L,51592L,51593L,51594L,\n51595L,51596L,51597L,51598L,51599L,51600L,51601L,51602L,51603L,51604L,\n51605L,51606L,51607L,51608L,51609L,51610L,51611L,51612L,51613L,51614L,\n51615L,51616L,51617L,51618L,51619L,51620L,51621L,51622L,51623L,51624L,\n51625L,51626L,51627L,51628L,51629L,51630L,51631L,51632L,51633L,51634L,\n51635L,51636L,51637L,51638L,51639L,51640L,51641L,51642L,51643L,51644L,\n51645L,51646L,51647L,51648L,51649L,51650L,51651L,51652L,51653L,51654L,\n51655L,51656L,51657L,51658L,51659L,51660L,51661L,51662L,51663L,51664L,\n51665L,51666L,51667L,51668L,51669L,51670L,51671L,51672L,51673L,51674L,\n51675L,51676L,51677L,51678L,51679L,51680L,51681L,51682L,51683L,51684L,\n51685L,51686L,51687L,51688L,51689L,51690L,51691L,51692L,51693L,51694L,\n51695L,51696L,51697L,51698L,51699L,51700L,51701L,51702L,51703L,51704L,\n51705L,51706L,51707L,51708L,51709L,51710L,51711L,51712L,51713L,51714L,\n51715L,51716L,51717L,51718L,51719L,51720L,51721L,51722L,51723L,51724L,\n51725L,51726L,51727L,51728L,51729L,51730L,51731L,51732L,51733L,51734L,\n51735L,51736L,51737L,51738L,51739L,51740L,51741L,51742L,51743L,51744L,\n51745L,51746L,51747L,51748L,51749L,51750L,51751L,51752L,51753L,51754L,\n51755L,51756L,51757L,51758L,51759L,51760L,51761L,51762L,51763L,51764L,\n51765L,51766L,51767L,51768L,51769L,51770L,51771L,51772L,51773L,51774L,\n51775L,51776L,51777L,51778L,51779L,51780L,51781L,51782L,51783L,51784L,\n51785L,51786L,51787L,51788L,51789L,51790L,51791L,51792L,51793L,51794L,\n51795L,51796L,51797L,51798L,51799L,51800L,51801L,51802L,51803L,51804L,\n51805L,51806L,51807L,51808L,51809L,51810L,51811L,51812L,51813L,51814L,\n51815L,51816L,51817L,51818L,51819L,51820L,51821L,51822L,51823L,51824L,\n51825L,51826L,51827L,51828L,51829L,51830L,51831L,51832L,51833L,51834L,\n51835L,51836L,51837L,51838L,51839L,51840L,51841L,51842L,51843L,51844L,\n51845L,51846L,51847L,51848L,51849L,51850L,51851L,51852L,51853L,51854L,\n51855L,51856L,51857L,51858L,51859L,51860L,51861L,51862L,51863L,51864L,\n51865L,51866L,51867L,51868L,51869L,51870L,51871L,51872L,51873L,51874L,\n51875L,51876L,51877L,51878L,51879L,51880L,51881L,51882L,51883L,51884L,\n51885L,51886L,51887L,51888L,51889L,51890L,51891L,51892L,51893L,51894L,\n51895L,51896L,51897L,51898L,51899L,51900L,51901L,51902L,51903L,51904L,\n51905L,51906L,51907L,51908L,51909L,51910L,51911L,51912L,51913L,51914L,\n51915L,51916L,51917L,51918L,51919L,51920L,51921L,51922L,51923L,51924L,\n51925L,51926L,51927L,51928L,51929L,51930L,51931L,51932L,51933L,51934L,\n51935L,51936L,51937L,51938L,51939L,51940L,51941L,51942L,51943L,51944L,\n51945L,51946L,51947L,51948L,51949L,51950L,51951L,51952L,51953L,51954L,\n51955L,51956L,51957L,51958L,51959L,51960L,51961L,51962L,51963L,51964L,\n51965L,51966L,51967L,51968L,51969L,51970L,51971L,51972L,51973L,51974L,\n51975L,51976L,51977L,51978L,51979L,51980L,51981L,51982L,51983L,51984L,\n51985L,51986L,51987L,51988L,51989L,51990L,51991L,51992L,51993L,51994L,\n51995L,51996L,51997L,51998L,51999L,52000L,52001L,52002L,52003L,52004L,\n52005L,52006L,52007L,52008L,52009L,52010L,52011L,52012L,52013L,52014L,\n52015L,52016L,52017L,52018L,52019L,52020L,52021L,52022L,52023L,52024L,\n52025L,52026L,52027L,52028L,52029L,52030L,52031L,52032L,52033L,52034L,\n52035L,52036L,52037L,52038L,52039L,52040L,52041L,52042L,52043L,52044L,\n52045L,52046L,52047L,52048L,52049L,52050L,52051L,52052L,52053L,52054L,\n52055L,52056L,52057L,52058L,52059L,52060L,52061L,52062L,52063L,52064L,\n52065L,52066L,52067L,52068L,52069L,52070L,52071L,52072L,52073L,52074L,\n52075L,52076L,52077L,52078L,52079L,52080L,52081L,52082L,52083L,52084L,\n52085L,52086L,52087L,52088L,52089L,52090L,52091L,52092L,52093L,52094L,\n52095L,52096L,52097L,52098L,52099L,52100L,52101L,52102L,52103L,52104L,\n52105L,52106L,52107L,52108L,52109L,52110L,52111L,52112L,52113L,52114L,\n52115L,52116L,52117L,52118L,52119L,52120L,52121L,52122L,52123L,52124L,\n52125L,52126L,52127L,52128L,52129L,52130L,52131L,52132L,52133L,52134L,\n52135L,52136L,52137L,52138L,52139L,52140L,52141L,52142L,52143L,52144L,\n52145L,52146L,52147L,52148L,52149L,52150L,52151L,52152L,52153L,52154L,\n52155L,52156L,52157L,52158L,52159L,52160L,52161L,52162L,52163L,52164L,\n52165L,52166L,52167L,52168L,52169L,52170L,52171L,52172L,52173L,52174L,\n52175L,52176L,52177L,52178L,52179L,52180L,52181L,52182L,52183L,52184L,\n52185L,52186L,52187L,52188L,52189L,52190L,52191L,52192L,52193L,52194L,\n52195L,52196L,52197L,52198L,52199L,52200L,52201L,52202L,52203L,52204L,\n52205L,52206L,52207L,52208L,52209L,52210L,52211L,52212L,52213L,52214L,\n52215L,52216L,52217L,52218L,52219L,52220L,52221L,52222L,52223L,52224L,\n52225L,52226L,52227L,52228L,52229L,52230L,52231L,52232L,52233L,52234L,\n52235L,52236L,52237L,52238L,52239L,52240L,52241L,52242L,52243L,52244L,\n52245L,52246L,52247L,52248L,52249L,52250L,52251L,52252L,52253L,52254L,\n52255L,52256L,52257L,52258L,52259L,52260L,52261L,52262L,52263L,52264L,\n52265L,52266L,52267L,52268L,52269L,52270L,52271L,52272L,52273L,52274L,\n52275L,52276L,52277L,52278L,52279L,52280L,52281L,52282L,52283L,52284L,\n52285L,52286L,52287L,52288L,52289L,52290L,52291L,52292L,52293L,52294L,\n52295L,52296L,52297L,52298L,52299L,52300L,52301L,52302L,52303L,52304L,\n52305L,52306L,52307L,52308L,52309L,52310L,52311L,52312L,52313L,52314L,\n52315L,52316L,52317L,52318L,52319L,52320L,52321L,52322L,52323L,52324L,\n52325L,52326L,52327L,52328L,52329L,52330L,52331L,52332L,52333L,52334L,\n52335L,52336L,52337L,52338L,52339L,52340L,52341L,52342L,52343L,52344L,\n52345L,52346L,52347L,52348L,52349L,52350L,52351L,52352L,52353L,52354L,\n52355L,52356L,52357L,52358L,52359L,52360L,52361L,52362L,52363L,52364L,\n52365L,52366L,52367L,52368L,52369L,52370L,52371L,52372L,52373L,52374L,\n52375L,52376L,52377L,52378L,52379L,52380L,52381L,52382L,52383L,52384L,\n52385L,52386L,52387L,52388L,52389L,52390L,52391L,52392L,52393L,52394L,\n52395L,52396L,52397L,52398L,52399L,52400L,52401L,52402L,52403L,52404L,\n52405L,52406L,52407L,52408L,52409L,52410L,52411L,52412L,52413L,52414L,\n52415L,52416L,52417L,52418L,52419L,52420L,52421L,52422L,52423L,52424L,\n52425L,52426L,52427L,52428L,52429L,52430L,52431L,52432L,52433L,52434L,\n52435L,52436L,52437L,52438L,52439L,52440L,52441L,52442L,52443L,52444L,\n52445L,52446L,52447L,52448L,52449L,52450L,52451L,52452L,52453L,52454L,\n52455L,52456L,52457L,52458L,52459L,52460L,52461L,52462L,52463L,52464L,\n52465L,52466L,52467L,52468L,52469L,52470L,52471L,52472L,52473L,52474L,\n52475L,52476L,52477L,52478L,52479L,52480L,52481L,52482L,52483L,52484L,\n52485L,52486L,52487L,52488L,52489L,52490L,52491L,52492L,52493L,52494L,\n52495L,52496L,52497L,52498L,52499L,52500L,52501L,52502L,52503L,52504L,\n52505L,52506L,52507L,52508L,52509L,52510L,52511L,52512L,52513L,52514L,\n52515L,52516L,52517L,52518L,52519L,52520L,52521L,52522L,52523L,52524L,\n52525L,52526L,52527L,52528L,52529L,52530L,52531L,52532L,52533L,52534L,\n52535L,52536L,52537L,52538L,52539L,52540L,52541L,52542L,52543L,52544L,\n52545L,52546L,52547L,52548L,52549L,52550L,52551L,52552L,52553L,52554L,\n52555L,52556L,52557L,52558L,52559L,52560L,52561L,52562L,52563L,52564L,\n52565L,52566L,52567L,52568L,52569L,52570L,52571L,52572L,52573L,52574L,\n52575L,52576L,52577L,52578L,52579L,52580L,52581L,52582L,52583L,52584L,\n52585L,52586L,52587L,52588L,52589L,52590L,52591L,52592L,52593L,52594L,\n52595L,52596L,52597L,52598L,52599L,52600L,52601L,52602L,52603L,52604L,\n52605L,52606L,52607L,52608L,52609L,52610L,52611L,52612L,52613L,52614L,\n52615L,52616L,52617L,52618L,52619L,52620L,52621L,52622L,52623L,52624L,\n52625L,52626L,52627L,52628L,52629L,52630L,52631L,52632L,52633L,52634L,\n52635L,52636L,52637L,52638L,52639L,52640L,52641L,52642L,52643L,52644L,\n52645L,52646L,52647L,52648L,52649L,52650L,52651L,52652L,52653L,52654L,\n52655L,52656L,52657L,52658L,52659L,52660L,52661L,52662L,52663L,52664L,\n52665L,52666L,52667L,52668L,52669L,52670L,52671L,52672L,52673L,52674L,\n52675L,52676L,52677L,52678L,52679L,52680L,52681L,52682L,52683L,52684L,\n52685L,52686L,52687L,52688L,52689L,52690L,52691L,52692L,52693L,52694L,\n52695L,52696L,52697L,52698L,52699L,52700L,52701L,52702L,52703L,52704L,\n52705L,52706L,52707L,52708L,52709L,52710L,52711L,52712L,52713L,52714L,\n52715L,52716L,52717L,52718L,52719L,52720L,52721L,52722L,52723L,52724L,\n52725L,52726L,52727L,52728L,52729L,52730L,52731L,52732L,52733L,52734L,\n52735L,52736L,52737L,52738L,52739L,52740L,52741L,52742L,52743L,52744L,\n52745L,52746L,52747L,52748L,52749L,52750L,52751L,52752L,52753L,52754L,\n52755L,52756L,52757L,52758L,52759L,52760L,52761L,52762L,52763L,52764L,\n52765L,52766L,52767L,52768L,52769L,52770L,52771L,52772L,52773L,52774L,\n52775L,52776L,52777L,52778L,52779L,52780L,52781L,52782L,52783L,52784L,\n52785L,52786L,52787L,52788L,52789L,52790L,52791L,52792L,52793L,52794L,\n52795L,52796L,52797L,52798L,52799L,52800L,52801L,52802L,52803L,52804L,\n52805L,52806L,52807L,52808L,52809L,52810L,52811L,52812L,52813L,52814L,\n52815L,52816L,52817L,52818L,52819L,52820L,52821L,52822L,52823L,52824L,\n52825L,52826L,52827L,52828L,52829L,52830L,52831L,52832L,52833L,52834L,\n52835L,52836L,52837L,52838L,52839L,52840L,52841L,52842L,52843L,52844L,\n52845L,52846L,52847L,52848L,52849L,52850L,52851L,52852L,52853L,52854L,\n52855L,52856L,52857L,52858L,52859L,52860L,52861L,52862L,52863L,52864L,\n52865L,52866L,52867L,52868L,52869L,52870L,52871L,52872L,52873L,52874L,\n52875L,52876L,52877L,52878L,52879L,52880L,52881L,52882L,52883L,52884L,\n52885L,52886L,52887L,52888L,52889L,52890L,52891L,52892L,52893L,52894L,\n52895L,52896L,52897L,52898L,52899L,52900L,52901L,52902L,52903L,52904L,\n52905L,52906L,52907L,52908L,52909L,52910L,52911L,52912L,52913L,52914L,\n52915L,52916L,52917L,52918L,52919L,52920L,52921L,52922L,52923L,52924L,\n52925L,52926L,52927L,52928L,52929L,52930L,52931L,52932L,52933L,52934L,\n52935L,52936L,52937L,52938L,52939L,52940L,52941L,52942L,52943L,52944L,\n52945L,52946L,52947L,52948L,52949L,52950L,52951L,52952L,52953L,52954L,\n52955L,52956L,52957L,52958L,52959L,52960L,52961L,52962L,52963L,52964L,\n52965L,52966L,52967L,52968L,52969L,52970L,52971L,52972L,52973L,52974L,\n52975L,52976L,52977L,52978L,52979L,52980L,52981L,52982L,52983L,52984L,\n52985L,52986L,52987L,52988L,52989L,52990L,52991L,52992L,52993L,52994L,\n52995L,52996L,52997L,52998L,52999L,53000L,53001L,53002L,53003L,53004L,\n53005L,53006L,53007L,53008L,53009L,53010L,53011L,53012L,53013L,53014L,\n53015L,53016L,53017L,53018L,53019L,53020L,53021L,53022L,53023L,53024L,\n53025L,53026L,53027L,53028L,53029L,53030L,53031L,53032L,53033L,53034L,\n53035L,53036L,53037L,53038L,53039L,53040L,53041L,53042L,53043L,53044L,\n53045L,53046L,53047L,53048L,53049L,53050L,53051L,53052L,53053L,53054L,\n53055L,53056L,53057L,53058L,53059L,53060L,53061L,53062L,53063L,53064L,\n53065L,53066L,53067L,53068L,53069L,53070L,53071L,53072L,53073L,53074L,\n53075L,53076L,53077L,53078L,53079L,53080L,53081L,53082L,53083L,53084L,\n53085L,53086L,53087L,53088L,53089L,53090L,53091L,53092L,53093L,53094L,\n53095L,53096L,53097L,53098L,53099L,53100L,53101L,53102L,53103L,53104L,\n53105L,53106L,53107L,53108L,53109L,53110L,53111L,53112L,53113L,53114L,\n53115L,53116L,53117L,53118L,53119L,53120L,53121L,53122L,53123L,53124L,\n53125L,53126L,53127L,53128L,53129L,53130L,53131L,53132L,53133L,53134L,\n53135L,53136L,53137L,53138L,53139L,53140L,53141L,53142L,53143L,53144L,\n53145L,53146L,53147L,53148L,53149L,53150L,53151L,53152L,53153L,53154L,\n53155L,53156L,53157L,53158L,53159L,53160L,53161L,53162L,53163L,53164L,\n53165L,53166L,53167L,53168L,53169L,53170L,53171L,53172L,53173L,53174L,\n53175L,53176L,53177L,53178L,53179L,53180L,53181L,53182L,53183L,53184L,\n53185L,53186L,53187L,53188L,53189L,53190L,53191L,53192L,53193L,53194L,\n53195L,53196L,53197L,53198L,53199L,53200L,53201L,53202L,53203L,53204L,\n53205L,53206L,53207L,53208L,53209L,53210L,53211L,53212L,53213L,53214L,\n53215L,53216L,53217L,53218L,53219L,53220L,53221L,53222L,53223L,53224L,\n53225L,53226L,53227L,53228L,53229L,53230L,53231L,53232L,53233L,53234L,\n53235L,53236L,53237L,53238L,53239L,53240L,53241L,53242L,53243L,53244L,\n53245L,53246L,53247L,53248L,53249L,53250L,53251L,53252L,53253L,53254L,\n53255L,53256L,53257L,53258L,53259L,53260L,53261L,53262L,53263L,53264L,\n53265L,53266L,53267L,53268L,53269L,53270L,53271L,53272L,53273L,53274L,\n53275L,53276L,53277L,53278L,53279L,53280L,53281L,53282L,53283L,53284L,\n53285L,53286L,53287L,53288L,53289L,53290L,53291L,53292L,53293L,53294L,\n53295L,53296L,53297L,53298L,53299L,53300L,53301L,53302L,53303L,53304L,\n53305L,53306L,53307L,53308L,53309L,53310L,53311L,53312L,53313L,53314L,\n53315L,53316L,53317L,53318L,53319L,53320L,53321L,53322L,53323L,53324L,\n53325L,53326L,53327L,53328L,53329L,53330L,53331L,53332L,53333L,53334L,\n53335L,53336L,53337L,53338L,53339L,53340L,53341L,53342L,53343L,53344L,\n53345L,53346L,53347L,53348L,53349L,53350L,53351L,53352L,53353L,53354L,\n53355L,53356L,53357L,53358L,53359L,53360L,53361L,53362L,53363L,53364L,\n53365L,53366L,53367L,53368L,53369L,53370L,53371L,53372L,53373L,53374L,\n53375L,53376L,53377L,53378L,53379L,53380L,53381L,53382L,53383L,53384L,\n53385L,53386L,53387L,53388L,53389L,53390L,53391L,53392L,53393L,53394L,\n53395L,53396L,53397L,53398L,53399L,53400L,53401L,53402L,53403L,53404L,\n53405L,53406L,53407L,53408L,53409L,53410L,53411L,53412L,53413L,53414L,\n53415L,53416L,53417L,53418L,53419L,53420L,53421L,53422L,53423L,53424L,\n53425L,53426L,53427L,53428L,53429L,53430L,53431L,53432L,53433L,53434L,\n53435L,53436L,53437L,53438L,53439L,53440L,53441L,53442L,53443L,53444L,\n53445L,53446L,53447L,53448L,53449L,53450L,53451L,53452L,53453L,53454L,\n53455L,53456L,53457L,53458L,53459L,53460L,53461L,53462L,53463L,53464L,\n53465L,53466L,53467L,53468L,53469L,53470L,53471L,53472L,53473L,53474L,\n53475L,53476L,53477L,53478L,53479L,53480L,53481L,53482L,53483L,53484L,\n53485L,53486L,53487L,53488L,53489L,53490L,53491L,53492L,53493L,53494L,\n53495L,53496L,53497L,53498L,53499L,53500L,53501L,53502L,53503L,53504L,\n53505L,53506L,53507L,53508L,53509L,53510L,53511L,53512L,53513L,53514L,\n53515L,53516L,53517L,53518L,53519L,53520L,53521L,53522L,53523L,53524L,\n53525L,53526L,53527L,53528L,53529L,53530L,53531L,53532L,53533L,53534L,\n53535L,53536L,53537L,53538L,53539L,53540L,53541L,53542L,53543L,53544L,\n53545L,53546L,53547L,53548L,53549L,53550L,53551L,53552L,53553L,53554L,\n53555L,53556L,53557L,53558L,53559L,53560L,53561L,53562L,53563L,53564L,\n53565L,53566L,53567L,53568L,53569L,53570L,53571L,53572L,53573L,53574L,\n53575L,53576L,53577L,53578L,53579L,53580L,53581L,53582L,53583L,53584L,\n53585L,53586L,53587L,53588L,53589L,53590L,53591L,53592L,53593L,53594L,\n53595L,53596L,53597L,53598L,53599L,53600L,53601L,53602L,53603L,53604L,\n53605L,53606L,53607L,53608L,53609L,53610L,53611L,53612L,53613L,53614L,\n53615L,53616L,53617L,53618L,53619L,53620L,53621L,53622L,53623L,53624L,\n53625L,53626L,53627L,53628L,53629L,53630L,53631L,53632L,53633L,53634L,\n53635L,53636L,53637L,53638L,53639L,53640L,53641L,53642L,53643L,53644L,\n53645L,53646L,53647L,53648L,53649L,53650L,53651L,53652L,53653L,53654L,\n53655L,53656L,53657L,53658L,53659L,53660L,53661L,53662L,53663L,53664L,\n53665L,53666L,53667L,53668L,53669L,53670L,53671L,53672L,53673L,53674L,\n53675L,53676L,53677L,53678L,53679L,53680L,53681L,53682L,53683L,53684L,\n53685L,53686L,53687L,53688L,53689L,53690L,53691L,53692L,53693L,53694L,\n53695L,53696L,53697L,53698L,53699L,53700L,53701L,53702L,53703L,53704L,\n53705L,53706L,53707L,53708L,53709L,53710L,53711L,53712L,53713L,53714L,\n53715L,53716L,53717L,53718L,53719L,53720L,53721L,53722L,53723L,53724L,\n53725L,53726L,53727L,53728L,53729L,53730L,53731L,53732L,53733L,53734L,\n53735L,53736L,53737L,53738L,53739L,53740L,53741L,53742L,53743L,53744L,\n53745L,53746L,53747L,53748L,53749L,53750L,53751L,53752L,53753L,53754L,\n53755L,53756L,53757L,53758L,53759L,53760L,53761L,53762L,53763L,53764L,\n53765L,53766L,53767L,53768L,53769L,53770L,53771L,53772L,53773L,53774L,\n53775L,53776L,53777L,53778L,53779L,53780L,53781L,53782L,53783L,53784L,\n53785L,53786L,53787L,53788L,53789L,53790L,53791L,53792L,53793L,53794L,\n53795L,53796L,53797L,53798L,53799L,53800L,53801L,53802L,53803L,53804L,\n53805L,53806L,53807L,53808L,53809L,53810L,53811L,53812L,53813L,53814L,\n53815L,53816L,53817L,53818L,53819L,53820L,53821L,53822L,53823L,53824L,\n53825L,53826L,53827L,53828L,53829L,53830L,53831L,53832L,53833L,53834L,\n53835L,53836L,53837L,53838L,53839L,53840L,53841L,53842L,53843L,53844L,\n53845L,53846L,53847L,53848L,53849L,53850L,53851L,53852L,53853L,53854L,\n53855L,53856L,53857L,53858L,53859L,53860L,53861L,53862L,53863L,53864L,\n53865L,53866L,53867L,53868L,53869L,53870L,53871L,53872L,53873L,53874L,\n53875L,53876L,53877L,53878L,53879L,53880L,53881L,53882L,53883L,53884L,\n53885L,53886L,53887L,53888L,53889L,53890L,53891L,53892L,53893L,53894L,\n53895L,53896L,53897L,53898L,53899L,53900L,53901L,53902L,53903L,53904L,\n53905L,53906L,53907L,53908L,53909L,53910L,53911L,53912L,53913L,53914L,\n53915L,53916L,53917L,53918L,53919L,53920L,53921L,53922L,53923L,53924L,\n53925L,53926L,53927L,53928L,53929L,53930L,53931L,53932L,53933L,53934L,\n53935L,53936L,53937L,53938L,53939L,53940L,53941L,53942L,53943L,53944L,\n53945L,53946L,53947L,53948L,53949L,53950L,53951L,53952L,53953L,53954L,\n53955L,53956L,53957L,53958L,53959L,53960L,53961L,53962L,53963L,53964L,\n53965L,53966L,53967L,53968L,53969L,53970L,53971L,53972L,53973L,53974L,\n53975L,53976L,53977L,53978L,53979L,53980L,53981L,53982L,53983L,53984L,\n53985L,53986L,53987L,53988L,53989L,53990L,53991L,53992L,53993L,53994L,\n53995L,53996L,53997L,53998L,53999L,54000L,54001L,54002L,54003L,54004L,\n54005L,54006L,54007L,54008L,54009L,54010L,54011L,54012L,54013L,54014L,\n54015L,54016L,54017L,54018L,54019L,54020L,54021L,54022L,54023L,54024L,\n54025L,54026L,54027L,54028L,54029L,54030L,54031L,54032L,54033L,54034L,\n54035L,54036L,54037L,54038L,54039L,54040L,54041L,54042L,54043L,54044L,\n54045L,54046L,54047L,54048L,54049L,54050L,54051L,54052L,54053L,54054L,\n54055L,54056L,54057L,54058L,54059L,54060L,54061L,54062L,54063L,54064L,\n54065L,54066L,54067L,54068L,54069L,54070L,54071L,54072L,54073L,54074L,\n54075L,54076L,54077L,54078L,54079L,54080L,54081L,54082L,54083L,54084L,\n54085L,54086L,54087L,54088L,54089L,54090L,54091L,54092L,54093L,54094L,\n54095L,54096L,54097L,54098L,54099L,54100L,54101L,54102L,54103L,54104L,\n54105L,54106L,54107L,54108L,54109L,54110L,54111L,54112L,54113L,54114L,\n54115L,54116L,54117L,54118L,54119L,54120L,54121L,54122L,54123L,54124L,\n54125L,54126L,54127L,54128L,54129L,54130L,54131L,54132L,54133L,54134L,\n54135L,54136L,54137L,54138L,54139L,54140L,54141L,54142L,54143L,54144L,\n54145L,54146L,54147L,54148L,54149L,54150L,54151L,54152L,54153L,54154L,\n54155L,54156L,54157L,54158L,54159L,54160L,54161L,54162L,54163L,54164L,\n54165L,54166L,54167L,54168L,54169L,54170L,54171L,54172L,54173L,54174L,\n54175L,54176L,54177L,54178L,54179L,54180L,54181L,54182L,54183L,54184L,\n54185L,54186L,54187L,54188L,54189L,54190L,54191L,54192L,54193L,54194L,\n54195L,54196L,54197L,54198L,54199L,54200L,54201L,54202L,54203L,54204L,\n54205L,54206L,54207L,54208L,54209L,54210L,54211L,54212L,54213L,54214L,\n54215L,54216L,54217L,54218L,54219L,54220L,54221L,54222L,54223L,54224L,\n54225L,54226L,54227L,54228L,54229L,54230L,54231L,54232L,54233L,54234L,\n54235L,54236L,54237L,54238L,54239L,54240L,54241L,54242L,54243L,54244L,\n54245L,54246L,54247L,54248L,54249L,54250L,54251L,54252L,54253L,54254L,\n54255L,54256L,54257L,54258L,54259L,54260L,54261L,54262L,54263L,54264L,\n54265L,54266L,54267L,54268L,54269L,54270L,54271L,54272L,54273L,54274L,\n54275L,54276L,54277L,54278L,54279L,54280L,54281L,54282L,54283L,54284L,\n54285L,54286L,54287L,54288L,54289L,54290L,54291L,54292L,54293L,54294L,\n54295L,54296L,54297L,54298L,54299L,54300L,54301L,54302L,54303L,54304L,\n54305L,54306L,54307L,54308L,54309L,54310L,54311L,54312L,54313L,54314L,\n54315L,54316L,54317L,54318L,54319L,54320L,54321L,54322L,54323L,54324L,\n54325L,54326L,54327L,54328L,54329L,54330L,54331L,54332L,54333L,54334L,\n54335L,54336L,54337L,54338L,54339L,54340L,54341L,54342L,54343L,54344L,\n54345L,54346L,54347L,54348L,54349L,54350L,54351L,54352L,54353L,54354L,\n54355L,54356L,54357L,54358L,54359L,54360L,54361L,54362L,54363L,54364L,\n54365L,54366L,54367L,54368L,54369L,54370L,54371L,54372L,54373L,54374L,\n54375L,54376L,54377L,54378L,54379L,54380L,54381L,54382L,54383L,54384L,\n54385L,54386L,54387L,54388L,54389L,54390L,54391L,54392L,54393L,54394L,\n54395L,54396L,54397L,54398L,54399L,54400L,54401L,54402L,54403L,54404L,\n54405L,54406L,54407L,54408L,54409L,54410L,54411L,54412L,54413L,54414L,\n54415L,54416L,54417L,54418L,54419L,54420L,54421L,54422L,54423L,54424L,\n54425L,54426L,54427L,54428L,54429L,54430L,54431L,54432L,54433L,54434L,\n54435L,54436L,54437L,54438L,54439L,54440L,54441L,54442L,54443L,54444L,\n54445L,54446L,54447L,54448L,54449L,54450L,54451L,54452L,54453L,54454L,\n54455L,54456L,54457L,54458L,54459L,54460L,54461L,54462L,54463L,54464L,\n54465L,54466L,54467L,54468L,54469L,54470L,54471L,54472L,54473L,54474L,\n54475L,54476L,54477L,54478L,54479L,54480L,54481L,54482L,54483L,54484L,\n54485L,54486L,54487L,54488L,54489L,54490L,54491L,54492L,54493L,54494L,\n54495L,54496L,54497L,54498L,54499L,54500L,54501L,54502L,54503L,54504L,\n54505L,54506L,54507L,54508L,54509L,54510L,54511L,54512L,54513L,54514L,\n54515L,54516L,54517L,54518L,54519L,54520L,54521L,54522L,54523L,54524L,\n54525L,54526L,54527L,54528L,54529L,54530L,54531L,54532L,54533L,54534L,\n54535L,54536L,54537L,54538L,54539L,54540L,54541L,54542L,54543L,54544L,\n54545L,54546L,54547L,54548L,54549L,54550L,54551L,54552L,54553L,54554L,\n54555L,54556L,54557L,54558L,54559L,54560L,54561L,54562L,54563L,54564L,\n54565L,54566L,54567L,54568L,54569L,54570L,54571L,54572L,54573L,54574L,\n54575L,54576L,54577L,54578L,54579L,54580L,54581L,54582L,54583L,54584L,\n54585L,54586L,54587L,54588L,54589L,54590L,54591L,54592L,54593L,54594L,\n54595L,54596L,54597L,54598L,54599L,54600L,54601L,54602L,54603L,54604L,\n54605L,54606L,54607L,54608L,54609L,54610L,54611L,54612L,54613L,54614L,\n54615L,54616L,54617L,54618L,54619L,54620L,54621L,54622L,54623L,54624L,\n54625L,54626L,54627L,54628L,54629L,54630L,54631L,54632L,54633L,54634L,\n54635L,54636L,54637L,54638L,54639L,54640L,54641L,54642L,54643L,54644L,\n54645L,54646L,54647L,54648L,54649L,54650L,54651L,54652L,54653L,54654L,\n54655L,54656L,54657L,54658L,54659L,54660L,54661L,54662L,54663L,54664L,\n54665L,54666L,54667L,54668L,54669L,54670L,54671L,54672L,54673L,54674L,\n54675L,54676L,54677L,54678L,54679L,54680L,54681L,54682L,54683L,54684L,\n54685L,54686L,54687L,54688L,54689L,54690L,54691L,54692L,54693L,54694L,\n54695L,54696L,54697L,54698L,54699L,54700L,54701L,54702L,54703L,54704L,\n54705L,54706L,54707L,54708L,54709L,54710L,54711L,54712L,54713L,54714L,\n54715L,54716L,54717L,54718L,54719L,54720L,54721L,54722L,54723L,54724L,\n54725L,54726L,54727L,54728L,54729L,54730L,54731L,54732L,54733L,54734L,\n54735L,54736L,54737L,54738L,54739L,54740L,54741L,54742L,54743L,54744L,\n54745L,54746L,54747L,54748L,54749L,54750L,54751L,54752L,54753L,54754L,\n54755L,54756L,54757L,54758L,54759L,54760L,54761L,54762L,54763L,54764L,\n54765L,54766L,54767L,54768L,54769L,54770L,54771L,54772L,54773L,54774L,\n54775L,54776L,54777L,54778L,54779L,54780L,54781L,54782L,54783L,54784L,\n54785L,54786L,54787L,54788L,54789L,54790L,54791L,54792L,54793L,54794L,\n54795L,54796L,54797L,54798L,54799L,54800L,54801L,54802L,54803L,54804L,\n54805L,54806L,54807L,54808L,54809L,54810L,54811L,54812L,54813L,54814L,\n54815L,54816L,54817L,54818L,54819L,54820L,54821L,54822L,54823L,54824L,\n54825L,54826L,54827L,54828L,54829L,54830L,54831L,54832L,54833L,54834L,\n54835L,54836L,54837L,54838L,54839L,54840L,54841L,54842L,54843L,54844L,\n54845L,54846L,54847L,54848L,54849L,54850L,54851L,54852L,54853L,54854L,\n54855L,54856L,54857L,54858L,54859L,54860L,54861L,54862L,54863L,54864L,\n54865L,54866L,54867L,54868L,54869L,54870L,54871L,54872L,54873L,54874L,\n54875L,54876L,54877L,54878L,54879L,54880L,54881L,54882L,54883L,54884L,\n54885L,54886L,54887L,54888L,54889L,54890L,54891L,54892L,54893L,54894L,\n54895L,54896L,54897L,54898L,54899L,54900L,54901L,54902L,54903L,54904L,\n54905L,54906L,54907L,54908L,54909L,54910L,54911L,54912L,54913L,54914L,\n54915L,54916L,54917L,54918L,54919L,54920L,54921L,54922L,54923L,54924L,\n54925L,54926L,54927L,54928L,54929L,54930L,54931L,54932L,54933L,54934L,\n54935L,54936L,54937L,54938L,54939L,54940L,54941L,54942L,54943L,54944L,\n54945L,54946L,54947L,54948L,54949L,54950L,54951L,54952L,54953L,54954L,\n54955L,54956L,54957L,54958L,54959L,54960L,54961L,54962L,54963L,54964L,\n54965L,54966L,54967L,54968L,54969L,54970L,54971L,54972L,54973L,54974L,\n54975L,54976L,54977L,54978L,54979L,54980L,54981L,54982L,54983L,54984L,\n54985L,54986L,54987L,54988L,54989L,54990L,54991L,54992L,54993L,54994L,\n54995L,54996L,54997L,54998L,54999L,55000L,55001L,55002L,55003L,55004L,\n55005L,55006L,55007L,55008L,55009L,55010L,55011L,55012L,55013L,55014L,\n55015L,55016L,55017L,55018L,55019L,55020L,55021L,55022L,55023L,55024L,\n55025L,55026L,55027L,55028L,55029L,55030L,55031L,55032L,55033L,55034L,\n55035L,55036L,55037L,55038L,55039L,55040L,55041L,55042L,55043L,55044L,\n55045L,55046L,55047L,55048L,55049L,55050L,55051L,55052L,55053L,55054L,\n55055L,55056L,55057L,55058L,55059L,55060L,55061L,55062L,55063L,55064L,\n55065L,55066L,55067L,55068L,55069L,55070L,55071L,55072L,55073L,55074L,\n55075L,55076L,55077L,55078L,55079L,55080L,55081L,55082L,55083L,55084L,\n55085L,55086L,55087L,55088L,55089L,55090L,55091L,55092L,55093L,55094L,\n55095L,55096L,55097L,55098L,55099L,55100L,55101L,55102L,55103L,55104L,\n55105L,55106L,55107L,55108L,55109L,55110L,55111L,55112L,55113L,55114L,\n55115L,55116L,55117L,55118L,55119L,55120L,55121L,55122L,55123L,55124L,\n55125L,55126L,55127L,55128L,55129L,55130L,55131L,55132L,55133L,55134L,\n55135L,55136L,55137L,55138L,55139L,55140L,55141L,55142L,55143L,55144L,\n55145L,55146L,55147L,55148L,55149L,55150L,55151L,55152L,55153L,55154L,\n55155L,55156L,55157L,55158L,55159L,55160L,55161L,55162L,55163L,55164L,\n55165L,55166L,55167L,55168L,55169L,55170L,55171L,55172L,55173L,55174L,\n55175L,55176L,55177L,55178L,55179L,55180L,55181L,55182L,55183L,55184L,\n55185L,55186L,55187L,55188L,55189L,55190L,55191L,55192L,55193L,55194L,\n55195L,55196L,55197L,55198L,55199L,55200L,55201L,55202L,55203L,55204L,\n55205L,55206L,55207L,55208L,55209L,55210L,55211L,55212L,55213L,55214L,\n55215L,55216L,55217L,55218L,55219L,55220L,55221L,55222L,55223L,55224L,\n55225L,55226L,55227L,55228L,55229L,55230L,55231L,55232L,55233L,55234L,\n55235L,55236L,55237L,55238L,55239L,55240L,55241L,55242L,55243L,55244L,\n55245L,55246L,55247L,55248L,55249L,55250L,55251L,55252L,55253L,55254L,\n55255L,55256L,55257L,55258L,55259L,55260L,55261L,55262L,55263L,55264L,\n55265L,55266L,55267L,55268L,55269L,55270L,55271L,55272L,55273L,55274L,\n55275L,55276L,55277L,55278L,55279L,55280L,55281L,55282L,55283L,55284L,\n55285L,55286L,55287L,55288L,55289L,55290L,55291L,55292L,55293L,55294L,\n55295L,55296L,55297L,55298L,55299L,55300L,55301L,55302L,55303L,55304L,\n55305L,55306L,55307L,55308L,55309L,55310L,55311L,55312L,55313L,55314L,\n55315L,55316L,55317L,55318L,55319L,55320L,55321L,55322L,55323L,55324L,\n55325L,55326L,55327L,55328L,55329L,55330L,55331L,55332L,55333L,55334L,\n55335L,55336L,55337L,55338L,55339L,55340L,55341L,55342L,55343L,55344L,\n55345L,55346L,55347L,55348L,55349L,55350L,55351L,55352L,55353L,55354L,\n55355L,55356L,55357L,55358L,55359L,55360L,55361L,55362L,55363L,55364L,\n55365L,55366L,55367L,55368L,55369L,55370L,55371L,55372L,55373L,55374L,\n55375L,55376L,55377L,55378L,55379L,55380L,55381L,55382L,55383L,55384L,\n55385L,55386L,55387L,55388L,55389L,55390L,55391L,55392L,55393L,55394L,\n55395L,55396L,55397L,55398L,55399L,55400L,55401L,55402L,55403L,55404L,\n55405L,55406L,55407L,55408L,55409L,55410L,55411L,55412L,55413L,55414L,\n55415L,55416L,55417L,55418L,55419L,55420L,55421L,55422L,55423L,55424L,\n55425L,55426L,55427L,55428L,55429L,55430L,55431L,55432L,55433L,55434L,\n55435L,55436L,55437L,55438L,55439L,55440L,55441L,55442L,55443L,55444L,\n55445L,55446L,55447L,55448L,55449L,55450L,55451L,55452L,55453L,55454L,\n55455L,55456L,55457L,55458L,55459L,55460L,55461L,55462L,55463L,55464L,\n55465L,55466L,55467L,55468L,55469L,55470L,55471L,55472L,55473L,55474L,\n55475L,55476L,55477L,55478L,55479L,55480L,55481L,55482L,55483L,55484L,\n55485L,55486L,55487L,55488L,55489L,55490L,55491L,55492L,55493L,55494L,\n55495L,55496L,55497L,55498L,55499L,55500L,55501L,55502L,55503L,55504L,\n55505L,55506L,55507L,55508L,55509L,55510L,55511L,55512L,55513L,55514L,\n55515L,55516L,55517L,55518L,55519L,55520L,55521L,55522L,55523L,55524L,\n55525L,55526L,55527L,55528L,55529L,55530L,55531L,55532L,55533L,55534L,\n55535L,55536L,55537L,55538L,55539L,55540L,55541L,55542L,55543L,55544L,\n55545L,55546L,55547L,55548L,55549L,55550L,55551L,55552L,55553L,55554L,\n55555L,55556L,55557L,55558L,55559L,55560L,55561L,55562L,55563L,55564L,\n55565L,55566L,55567L,55568L,55569L,55570L,55571L,55572L,55573L,55574L,\n55575L,55576L,55577L,55578L,55579L,55580L,55581L,55582L,55583L,55584L,\n55585L,55586L,55587L,55588L,55589L,55590L,55591L,55592L,55593L,55594L,\n55595L,55596L,55597L,55598L,55599L,55600L,55601L,55602L,55603L,55604L,\n55605L,55606L,55607L,55608L,55609L,55610L,55611L,55612L,55613L,55614L,\n55615L,55616L,55617L,55618L,55619L,55620L,55621L,55622L,55623L,55624L,\n55625L,55626L,55627L,55628L,55629L,55630L,55631L,55632L,55633L,55634L,\n55635L,55636L,55637L,55638L,55639L,55640L,55641L,55642L,55643L,55644L,\n55645L,55646L,55647L,55648L,55649L,55650L,55651L,55652L,55653L,55654L,\n55655L,55656L,55657L,55658L,55659L,55660L,55661L,55662L,55663L,55664L,\n55665L,55666L,55667L,55668L,55669L,55670L,55671L,55672L,55673L,55674L,\n55675L,55676L,55677L,55678L,55679L,55680L,55681L,55682L,55683L,55684L,\n55685L,55686L,55687L,55688L,55689L,55690L,55691L,55692L,55693L,55694L,\n55695L,55696L,55697L,55698L,55699L,55700L,55701L,55702L,55703L,55704L,\n55705L,55706L,55707L,55708L,55709L,55710L,55711L,55712L,55713L,55714L,\n55715L,55716L,55717L,55718L,55719L,55720L,55721L,55722L,55723L,55724L,\n55725L,55726L,55727L,55728L,55729L,55730L,55731L,55732L,55733L,55734L,\n55735L,55736L,55737L,55738L,55739L,55740L,55741L,55742L,55743L,55744L,\n55745L,55746L,55747L,55748L,55749L,55750L,55751L,55752L,55753L,55754L,\n55755L,55756L,55757L,55758L,55759L,55760L,55761L,55762L,55763L,55764L,\n55765L,55766L,55767L,55768L,55769L,55770L,55771L,55772L,55773L,55774L,\n55775L,55776L,55777L,55778L,55779L,55780L,55781L,55782L,55783L,55784L,\n55785L,55786L,55787L,55788L,55789L,55790L,55791L,55792L,55793L,55794L,\n55795L,55796L,55797L,55798L,55799L,55800L,55801L,55802L,55803L,55804L,\n55805L,55806L,55807L,55808L,55809L,55810L,55811L,55812L,55813L,55814L,\n55815L,55816L,55817L,55818L,55819L,55820L,55821L,55822L,55823L,55824L,\n55825L,55826L,55827L,55828L,55829L,55830L,55831L,55832L,55833L,55834L,\n55835L,55836L,55837L,55838L,55839L,55840L,55841L,55842L,55843L,55844L,\n55845L,55846L,55847L,55848L,55849L,55850L,55851L,55852L,55853L,55854L,\n55855L,55856L,55857L,55858L,55859L,55860L,55861L,55862L,55863L,55864L,\n55865L,55866L,55867L,55868L,55869L,55870L,55871L,55872L,55873L,55874L,\n55875L,55876L,55877L,55878L,55879L,55880L,55881L,55882L,55883L,55884L,\n55885L,55886L,55887L,55888L,55889L,55890L,55891L,55892L,55893L,55894L,\n55895L,55896L,55897L,55898L,55899L,55900L,55901L,55902L,55903L,55904L,\n55905L,55906L,55907L,55908L,55909L,55910L,55911L,55912L,55913L,55914L,\n55915L,55916L,55917L,55918L,55919L,55920L,55921L,55922L,55923L,55924L,\n55925L,55926L,55927L,55928L,55929L,55930L,55931L,55932L,55933L,55934L,\n55935L,55936L,55937L,55938L,55939L,55940L,55941L,55942L,55943L,55944L,\n55945L,55946L,55947L,55948L,55949L,55950L,55951L,55952L,55953L,55954L,\n55955L,55956L,55957L,55958L,55959L,55960L,55961L,55962L,55963L,55964L,\n55965L,55966L,55967L,55968L,55969L,55970L,55971L,55972L,55973L,55974L,\n55975L,55976L,55977L,55978L,55979L,55980L,55981L,55982L,55983L,55984L,\n55985L,55986L,55987L,55988L,55989L,55990L,55991L,55992L,55993L,55994L,\n55995L,55996L,55997L,55998L,55999L,56000L,56001L,56002L,56003L,56004L,\n56005L,56006L,56007L,56008L,56009L,56010L,56011L,56012L,56013L,56014L,\n56015L,56016L,56017L,56018L,56019L,56020L,56021L,56022L,56023L,56024L,\n56025L,56026L,56027L,56028L,56029L,56030L,56031L,56032L,56033L,56034L,\n56035L,56036L,56037L,56038L,56039L,56040L,56041L,56042L,56043L,56044L,\n56045L,56046L,56047L,56048L,56049L,56050L,56051L,56052L,56053L,56054L,\n56055L,56056L,56057L,56058L,56059L,56060L,56061L,56062L,56063L,56064L,\n56065L,56066L,56067L,56068L,56069L,56070L,56071L,56072L,56073L,56074L,\n56075L,56076L,56077L,56078L,56079L,56080L,56081L,56082L,56083L,56084L,\n56085L,56086L,56087L,56088L,56089L,56090L,56091L,56092L,56093L,56094L,\n56095L,56096L,56097L,56098L,56099L,56100L,56101L,56102L,56103L,56104L,\n56105L,56106L,56107L,56108L,56109L,56110L,56111L,56112L,56113L,56114L,\n56115L,56116L,56117L,56118L,56119L,56120L,56121L,56122L,56123L,56124L,\n56125L,56126L,56127L,56128L,56129L,56130L,56131L,56132L,56133L,56134L,\n56135L,56136L,56137L,56138L,56139L,56140L,56141L,56142L,56143L,56144L,\n56145L,56146L,56147L,56148L,56149L,56150L,56151L,56152L,56153L,56154L,\n56155L,56156L,56157L,56158L,56159L,56160L,56161L,56162L,56163L,56164L,\n56165L,56166L,56167L,56168L,56169L,56170L,56171L,56172L,56173L,56174L,\n56175L,56176L,56177L,56178L,56179L,56180L,56181L,56182L,56183L,56184L,\n56185L,56186L,56187L,56188L,56189L,56190L,56191L,56192L,56193L,56194L,\n56195L,56196L,56197L,56198L,56199L,56200L,56201L,56202L,56203L,56204L,\n56205L,56206L,56207L,56208L,56209L,56210L,56211L,56212L,56213L,56214L,\n56215L,56216L,56217L,56218L,56219L,56220L,56221L,56222L,56223L,56224L,\n56225L,56226L,56227L,56228L,56229L,56230L,56231L,56232L,56233L,56234L,\n56235L,56236L,56237L,56238L,56239L,56240L,56241L,56242L,56243L,56244L,\n56245L,56246L,56247L,56248L,56249L,56250L,56251L,56252L,56253L,56254L,\n56255L,56256L,56257L,56258L,56259L,56260L,56261L,56262L,56263L,56264L,\n56265L,56266L,56267L,56268L,56269L,56270L,56271L,56272L,56273L,56274L,\n56275L,56276L,56277L,56278L,56279L,56280L,56281L,56282L,56283L,56284L,\n56285L,56286L,56287L,56288L,56289L,56290L,56291L,56292L,56293L,56294L,\n56295L,56296L,56297L,56298L,56299L,56300L,56301L,56302L,56303L,56304L,\n56305L,56306L,56307L,56308L,56309L,56310L,56311L,56312L,56313L,56314L,\n56315L,56316L,56317L,56318L,56319L,56320L,56321L,56322L,56323L,56324L,\n56325L,56326L,56327L,56328L,56329L,56330L,56331L,56332L,56333L,56334L,\n56335L,56336L,56337L,56338L,56339L,56340L,56341L,56342L,56343L,56344L,\n56345L,56346L,56347L,56348L,56349L,56350L,56351L,56352L,56353L,56354L,\n56355L,56356L,56357L,56358L,56359L,56360L,56361L,56362L,56363L,56364L,\n56365L,56366L,56367L,56368L,56369L,56370L,56371L,56372L,56373L,56374L,\n56375L,56376L,56377L,56378L,56379L,56380L,56381L,56382L,56383L,56384L,\n56385L,56386L,56387L,56388L,56389L,56390L,56391L,56392L,56393L,56394L,\n56395L,56396L,56397L,56398L,56399L,56400L,56401L,56402L,56403L,56404L,\n56405L,56406L,56407L,56408L,56409L,56410L,56411L,56412L,56413L,56414L,\n56415L,56416L,56417L,56418L,56419L,56420L,56421L,56422L,56423L,56424L,\n56425L,56426L,56427L,56428L,56429L,56430L,56431L,56432L,56433L,56434L,\n56435L,56436L,56437L,56438L,56439L,56440L,56441L,56442L,56443L,56444L,\n56445L,56446L,56447L,56448L,56449L,56450L,56451L,56452L,56453L,56454L,\n56455L,56456L,56457L,56458L,56459L,56460L,56461L,56462L,56463L,56464L,\n56465L,56466L,56467L,56468L,56469L,56470L,56471L,56472L,56473L,56474L,\n56475L,56476L,56477L,56478L,56479L,56480L,56481L,56482L,56483L,56484L,\n56485L,56486L,56487L,56488L,56489L,56490L,56491L,56492L,56493L,56494L,\n56495L,56496L,56497L,56498L,56499L,56500L,56501L,56502L,56503L,56504L,\n56505L,56506L,56507L,56508L,56509L,56510L,56511L,56512L,56513L,56514L,\n56515L,56516L,56517L,56518L,56519L,56520L,56521L,56522L,56523L,56524L,\n56525L,56526L,56527L,56528L,56529L,56530L,56531L,56532L,56533L,56534L,\n56535L,56536L,56537L,56538L,56539L,56540L,56541L,56542L,56543L,56544L,\n56545L,56546L,56547L,56548L,56549L,56550L,56551L,56552L,56553L,56554L,\n56555L,56556L,56557L,56558L,56559L,56560L,56561L,56562L,56563L,56564L,\n56565L,56566L,56567L,56568L,56569L,56570L,56571L,56572L,56573L,56574L,\n56575L,56576L,56577L,56578L,56579L,56580L,56581L,56582L,56583L,56584L,\n56585L,56586L,56587L,56588L,56589L,56590L,56591L,56592L,56593L,56594L,\n56595L,56596L,56597L,56598L,56599L,56600L,56601L,56602L,56603L,56604L,\n56605L,56606L,56607L,56608L,56609L,56610L,56611L,56612L,56613L,56614L,\n56615L,56616L,56617L,56618L,56619L,56620L,56621L,56622L,56623L,56624L,\n56625L,56626L,56627L,56628L,56629L,56630L,56631L,56632L,56633L,56634L,\n56635L,56636L,56637L,56638L,56639L,56640L,56641L,56642L,56643L,56644L,\n56645L,56646L,56647L,56648L,56649L,56650L,56651L,56652L,56653L,56654L,\n56655L,56656L,56657L,56658L,56659L,56660L,56661L,56662L,56663L,56664L,\n56665L,56666L,56667L,56668L,56669L,56670L,56671L,56672L,56673L,56674L,\n56675L,56676L,56677L,56678L,56679L,56680L,56681L,56682L,56683L,56684L,\n56685L,56686L,56687L,56688L,56689L,56690L,56691L,56692L,56693L,56694L,\n56695L,56696L,56697L,56698L,56699L,56700L,56701L,56702L,56703L,56704L,\n56705L,56706L,56707L,56708L,56709L,56710L,56711L,56712L,56713L,56714L,\n56715L,56716L,56717L,56718L,56719L,56720L,56721L,56722L,56723L,56724L,\n56725L,56726L,56727L,56728L,56729L,56730L,56731L,56732L,56733L,56734L,\n56735L,56736L,56737L,56738L,56739L,56740L,56741L,56742L,56743L,56744L,\n56745L,56746L,56747L,56748L,56749L,56750L,56751L,56752L,56753L,56754L,\n56755L,56756L,56757L,56758L,56759L,56760L,56761L,56762L,56763L,56764L,\n56765L,56766L,56767L,56768L,56769L,56770L,56771L,56772L,56773L,56774L,\n56775L,56776L,56777L,56778L,56779L,56780L,56781L,56782L,56783L,56784L,\n56785L,56786L,56787L,56788L,56789L,56790L,56791L,56792L,56793L,56794L,\n56795L,56796L,56797L,56798L,56799L,56800L,56801L,56802L,56803L,56804L,\n56805L,56806L,56807L,56808L,56809L,56810L,56811L,56812L,56813L,56814L,\n56815L,56816L,56817L,56818L,56819L,56820L,56821L,56822L,56823L,56824L,\n56825L,56826L,56827L,56828L,56829L,56830L,56831L,56832L,56833L,56834L,\n56835L,56836L,56837L,56838L,56839L,56840L,56841L,56842L,56843L,56844L,\n56845L,56846L,56847L,56848L,56849L,56850L,56851L,56852L,56853L,56854L,\n56855L,56856L,56857L,56858L,56859L,56860L,56861L,56862L,56863L,56864L,\n56865L,56866L,56867L,56868L,56869L,56870L,56871L,56872L,56873L,56874L,\n56875L,56876L,56877L,56878L,56879L,56880L,56881L,56882L,56883L,56884L,\n56885L,56886L,56887L,56888L,56889L,56890L,56891L,56892L,56893L,56894L,\n56895L,56896L,56897L,56898L,56899L,56900L,56901L,56902L,56903L,56904L,\n56905L,56906L,56907L,56908L,56909L,56910L,56911L,56912L,56913L,56914L,\n56915L,56916L,56917L,56918L,56919L,56920L,56921L,56922L,56923L,56924L,\n56925L,56926L,56927L,56928L,56929L,56930L,56931L,56932L,56933L,56934L,\n56935L,56936L,56937L,56938L,56939L,56940L,56941L,56942L,56943L,56944L,\n56945L,56946L,56947L,56948L,56949L,56950L,56951L,56952L,56953L,56954L,\n56955L,56956L,56957L,56958L,56959L,56960L,56961L,56962L,56963L,56964L,\n56965L,56966L,56967L,56968L,56969L,56970L,56971L,56972L,56973L,56974L,\n56975L,56976L,56977L,56978L,56979L,56980L,56981L,56982L,56983L,56984L,\n56985L,56986L,56987L,56988L,56989L,56990L,56991L,56992L,56993L,56994L,\n56995L,56996L,56997L,56998L,56999L,57000L,57001L,57002L,57003L,57004L,\n57005L,57006L,57007L,57008L,57009L,57010L,57011L,57012L,57013L,57014L,\n57015L,57016L,57017L,57018L,57019L,57020L,57021L,57022L,57023L,57024L,\n57025L,57026L,57027L,57028L,57029L,57030L,57031L,57032L,57033L,57034L,\n57035L,57036L,57037L,57038L,57039L,57040L,57041L,57042L,57043L,57044L,\n57045L,57046L,57047L,57048L,57049L,57050L,57051L,57052L,57053L,57054L,\n57055L,57056L,57057L,57058L,57059L,57060L,57061L,57062L,57063L,57064L,\n57065L,57066L,57067L,57068L,57069L,57070L,57071L,57072L,57073L,57074L,\n57075L,57076L,57077L,57078L,57079L,57080L,57081L,57082L,57083L,57084L,\n57085L,57086L,57087L,57088L,57089L,57090L,57091L,57092L,57093L,57094L,\n57095L,57096L,57097L,57098L,57099L,57100L,57101L,57102L,57103L,57104L,\n57105L,57106L,57107L,57108L,57109L,57110L,57111L,57112L,57113L,57114L,\n57115L,57116L,57117L,57118L,57119L,57120L,57121L,57122L,57123L,57124L,\n57125L,57126L,57127L,57128L,57129L,57130L,57131L,57132L,57133L,57134L,\n57135L,57136L,57137L,57138L,57139L,57140L,57141L,57142L,57143L,57144L,\n57145L,57146L,57147L,57148L,57149L,57150L,57151L,57152L,57153L,57154L,\n57155L,57156L,57157L,57158L,57159L,57160L,57161L,57162L,57163L,57164L,\n57165L,57166L,57167L,57168L,57169L,57170L,57171L,57172L,57173L,57174L,\n57175L,57176L,57177L,57178L,57179L,57180L,57181L,57182L,57183L,57184L,\n57185L,57186L,57187L,57188L,57189L,57190L,57191L,57192L,57193L,57194L,\n57195L,57196L,57197L,57198L,57199L,57200L,57201L,57202L,57203L,57204L,\n57205L,57206L,57207L,57208L,57209L,57210L,57211L,57212L,57213L,57214L,\n57215L,57216L,57217L,57218L,57219L,57220L,57221L,57222L,57223L,57224L,\n57225L,57226L,57227L,57228L,57229L,57230L,57231L,57232L,57233L,57234L,\n57235L,57236L,57237L,57238L,57239L,57240L,57241L,57242L,57243L,57244L,\n57245L,57246L,57247L,57248L,57249L,57250L,57251L,57252L,57253L,57254L,\n57255L,57256L,57257L,57258L,57259L,57260L,57261L,57262L,57263L,57264L,\n57265L,57266L,57267L,57268L,57269L,57270L,57271L,57272L,57273L,57274L,\n57275L,57276L,57277L,57278L,57279L,57280L,57281L,57282L,57283L,57284L,\n57285L,57286L,57287L,57288L,57289L,57290L,57291L,57292L,57293L,57294L,\n57295L,57296L,57297L,57298L,57299L,57300L,57301L,57302L,57303L,57304L,\n57305L,57306L,57307L,57308L,57309L,57310L,57311L,57312L,57313L,57314L,\n57315L,57316L,57317L,57318L,57319L,57320L,57321L,57322L,57323L,57324L,\n57325L,57326L,57327L,57328L,57329L,57330L,57331L,57332L,57333L,57334L,\n57335L,57336L,57337L,57338L,57339L,57340L,57341L,57342L,57343L,57344L,\n57345L,57346L,57347L,57348L,57349L,57350L,57351L,57352L,57353L,57354L,\n57355L,57356L,57357L,57358L,57359L,57360L,57361L,57362L,57363L,57364L,\n57365L,57366L,57367L,57368L,57369L,57370L,57371L,57372L,57373L,57374L,\n57375L,57376L,57377L,57378L,57379L,57380L,57381L,57382L,57383L,57384L,\n57385L,57386L,57387L,57388L,57389L,57390L,57391L,57392L,57393L,57394L,\n57395L,57396L,57397L,57398L,57399L,57400L,57401L,57402L,57403L,57404L,\n57405L,57406L,57407L,57408L,57409L,57410L,57411L,57412L,57413L,57414L,\n57415L,57416L,57417L,57418L,57419L,57420L,57421L,57422L,57423L,57424L,\n57425L,57426L,57427L,57428L,57429L,57430L,57431L,57432L,57433L,57434L,\n57435L,57436L,57437L,57438L,57439L,57440L,57441L,57442L,57443L,57444L,\n57445L,57446L,57447L,57448L,57449L,57450L,57451L,57452L,57453L,57454L,\n57455L,57456L,57457L,57458L,57459L,57460L,57461L,57462L,57463L,57464L,\n57465L,57466L,57467L,57468L,57469L,57470L,57471L,57472L,57473L,57474L,\n57475L,57476L,57477L,57478L,57479L,57480L,57481L,57482L,57483L,57484L,\n57485L,57486L,57487L,57488L,57489L,57490L,57491L,57492L,57493L,57494L,\n57495L,57496L,57497L,57498L,57499L,57500L,57501L,57502L,57503L,57504L,\n57505L,57506L,57507L,57508L,57509L,57510L,57511L,57512L,57513L,57514L,\n57515L,57516L,57517L,57518L,57519L,57520L,57521L,57522L,57523L,57524L,\n57525L,57526L,57527L,57528L,57529L,57530L,57531L,57532L,57533L,57534L,\n57535L,57536L,57537L,57538L,57539L,57540L,57541L,57542L,57543L,57544L,\n57545L,57546L,57547L,57548L,57549L,57550L,57551L,57552L,57553L,57554L,\n57555L,57556L,57557L,57558L,57559L,57560L,57561L,57562L,57563L,57564L,\n57565L,57566L,57567L,57568L,57569L,57570L,57571L,57572L,57573L,57574L,\n57575L,57576L,57577L,57578L,57579L,57580L,57581L,57582L,57583L,57584L,\n57585L,57586L,57587L,57588L,57589L,57590L,57591L,57592L,57593L,57594L,\n57595L,57596L,57597L,57598L,57599L,57600L,57601L,57602L,57603L,57604L,\n57605L,57606L,57607L,57608L,57609L,57610L,57611L,57612L,57613L,57614L,\n57615L,57616L,57617L,57618L,57619L,57620L,57621L,57622L,57623L,57624L,\n57625L,57626L,57627L,57628L,57629L,57630L,57631L,57632L,57633L,57634L,\n57635L,57636L,57637L,57638L,57639L,57640L,57641L,57642L,57643L,57644L,\n57645L,57646L,57647L,57648L,57649L,57650L,57651L,57652L,57653L,57654L,\n57655L,57656L,57657L,57658L,57659L,57660L,57661L,57662L,57663L,57664L,\n57665L,57666L,57667L,57668L,57669L,57670L,57671L,57672L,57673L,57674L,\n57675L,57676L,57677L,57678L,57679L,57680L,57681L,57682L,57683L,57684L,\n57685L,57686L,57687L,57688L,57689L,57690L,57691L,57692L,57693L,57694L,\n57695L,57696L,57697L,57698L,57699L,57700L,57701L,57702L,57703L,57704L,\n57705L,57706L,57707L,57708L,57709L,57710L,57711L,57712L,57713L,57714L,\n57715L,57716L,57717L,57718L,57719L,57720L,57721L,57722L,57723L,57724L,\n57725L,57726L,57727L,57728L,57729L,57730L,57731L,57732L,57733L,57734L,\n57735L,57736L,57737L,57738L,57739L,57740L,57741L,57742L,57743L,57744L,\n57745L,57746L,57747L,57748L,57749L,57750L,57751L,57752L,57753L,57754L,\n57755L,57756L,57757L,57758L,57759L,57760L,57761L,57762L,57763L,57764L,\n57765L,57766L,57767L,57768L,57769L,57770L,57771L,57772L,57773L,57774L,\n57775L,57776L,57777L,57778L,57779L,57780L,57781L,57782L,57783L,57784L,\n57785L,57786L,57787L,57788L,57789L,57790L,57791L,57792L,57793L,57794L,\n57795L,57796L,57797L,57798L,57799L,57800L,57801L,57802L,57803L,57804L,\n57805L,57806L,57807L,57808L,57809L,57810L,57811L,57812L,57813L,57814L,\n57815L,57816L,57817L,57818L,57819L,57820L,57821L,57822L,57823L,57824L,\n57825L,57826L,57827L,57828L,57829L,57830L,57831L,57832L,57833L,57834L,\n57835L,57836L,57837L,57838L,57839L,57840L,57841L,57842L,57843L,57844L,\n57845L,57846L,57847L,57848L,57849L,57850L,57851L,57852L,57853L,57854L,\n57855L,57856L,57857L,57858L,57859L,57860L,57861L,57862L,57863L,57864L,\n57865L,57866L,57867L,57868L,57869L,57870L,57871L,57872L,57873L,57874L,\n57875L,57876L,57877L,57878L,57879L,57880L,57881L,57882L,57883L,57884L,\n57885L,57886L,57887L,57888L,57889L,57890L,57891L,57892L,57893L,57894L,\n57895L,57896L,57897L,57898L,57899L,57900L,57901L,57902L,57903L,57904L,\n57905L,57906L,57907L,57908L,57909L,57910L,57911L,57912L,57913L,57914L,\n57915L,57916L,57917L,57918L,57919L,57920L,57921L,57922L,57923L,57924L,\n57925L,57926L,57927L,57928L,57929L,57930L,57931L,57932L,57933L,57934L,\n57935L,57936L,57937L,57938L,57939L,57940L,57941L,57942L,57943L,57944L,\n57945L,57946L,57947L,57948L,57949L,57950L,57951L,57952L,57953L,57954L,\n57955L,57956L,57957L,57958L,57959L,57960L,57961L,57962L,57963L,57964L,\n57965L,57966L,57967L,57968L,57969L,57970L,57971L,57972L,57973L,57974L,\n57975L,57976L,57977L,57978L,57979L,57980L,57981L,57982L,57983L,57984L,\n57985L,57986L,57987L,57988L,57989L,57990L,57991L,57992L,57993L,57994L,\n57995L,57996L,57997L,57998L,57999L,58000L,58001L,58002L,58003L,58004L,\n58005L,58006L,58007L,58008L,58009L,58010L,58011L,58012L,58013L,58014L,\n58015L,58016L,58017L,58018L,58019L,58020L,58021L,58022L,58023L,58024L,\n58025L,58026L,58027L,58028L,58029L,58030L,58031L,58032L,58033L,58034L,\n58035L,58036L,58037L,58038L,58039L,58040L,58041L,58042L,58043L,58044L,\n58045L,58046L,58047L,58048L,58049L,58050L,58051L,58052L,58053L,58054L,\n58055L,58056L,58057L,58058L,58059L,58060L,58061L,58062L,58063L,58064L,\n58065L,58066L,58067L,58068L,58069L,58070L,58071L,58072L,58073L,58074L,\n58075L,58076L,58077L,58078L,58079L,58080L,58081L,58082L,58083L,58084L,\n58085L,58086L,58087L,58088L,58089L,58090L,58091L,58092L,58093L,58094L,\n58095L,58096L,58097L,58098L,58099L,58100L,58101L,58102L,58103L,58104L,\n58105L,58106L,58107L,58108L,58109L,58110L,58111L,58112L,58113L,58114L,\n58115L,58116L,58117L,58118L,58119L,58120L,58121L,58122L,58123L,58124L,\n58125L,58126L,58127L,58128L,58129L,58130L,58131L,58132L,58133L,58134L,\n58135L,58136L,58137L,58138L,58139L,58140L,58141L,58142L,58143L,58144L,\n58145L,58146L,58147L,58148L,58149L,58150L,58151L,58152L,58153L,58154L,\n58155L,58156L,58157L,58158L,58159L,58160L,58161L,58162L,58163L,58164L,\n58165L,58166L,58167L,58168L,58169L,58170L,58171L,58172L,58173L,58174L,\n58175L,58176L,58177L,58178L,58179L,58180L,58181L,58182L,58183L,58184L,\n58185L,58186L,58187L,58188L,58189L,58190L,58191L,58192L,58193L,58194L,\n58195L,58196L,58197L,58198L,58199L,58200L,58201L,58202L,58203L,58204L,\n58205L,58206L,58207L,58208L,58209L,58210L,58211L,58212L,58213L,58214L,\n58215L,58216L,58217L,58218L,58219L,58220L,58221L,58222L,58223L,58224L,\n58225L,58226L,58227L,58228L,58229L,58230L,58231L,58232L,58233L,58234L,\n58235L,58236L,58237L,58238L,58239L,58240L,58241L,58242L,58243L,58244L,\n58245L,58246L,58247L,58248L,58249L,58250L,58251L,58252L,58253L,58254L,\n58255L,58256L,58257L,58258L,58259L,58260L,58261L,58262L,58263L,58264L,\n58265L,58266L,58267L,58268L,58269L,58270L,58271L,58272L,58273L,58274L,\n58275L,58276L,58277L,58278L,58279L,58280L,58281L,58282L,58283L,58284L,\n58285L,58286L,58287L,58288L,58289L,58290L,58291L,58292L,58293L,58294L,\n58295L,58296L,58297L,58298L,58299L,58300L,58301L,58302L,58303L,58304L,\n58305L,58306L,58307L,58308L,58309L,58310L,58311L,58312L,58313L,58314L,\n58315L,58316L,58317L,58318L,58319L,58320L,58321L,58322L,58323L,58324L,\n58325L,58326L,58327L,58328L,58329L,58330L,58331L,58332L,58333L,58334L,\n58335L,58336L,58337L,58338L,58339L,58340L,58341L,58342L,58343L,58344L,\n58345L,58346L,58347L,58348L,58349L,58350L,58351L,58352L,58353L,58354L,\n58355L,58356L,58357L,58358L,58359L,58360L,58361L,58362L,58363L,58364L,\n58365L,58366L,58367L,58368L,58369L,58370L,58371L,58372L,58373L,58374L,\n58375L,58376L,58377L,58378L,58379L,58380L,58381L,58382L,58383L,58384L,\n58385L,58386L,58387L,58388L,58389L,58390L,58391L,58392L,58393L,58394L,\n58395L,58396L,58397L,58398L,58399L,58400L,58401L,58402L,58403L,58404L,\n58405L,58406L,58407L,58408L,58409L,58410L,58411L,58412L,58413L,58414L,\n58415L,58416L,58417L,58418L,58419L,58420L,58421L,58422L,58423L,58424L,\n58425L,58426L,58427L,58428L,58429L,58430L,58431L,58432L,58433L,58434L,\n58435L,58436L,58437L,58438L,58439L,58440L,58441L,58442L,58443L,58444L,\n58445L,58446L,58447L,58448L,58449L,58450L,58451L,58452L,58453L,58454L,\n58455L,58456L,58457L,58458L,58459L,58460L,58461L,58462L,58463L,58464L,\n58465L,58466L,58467L,58468L,58469L,58470L,58471L,58472L,58473L,58474L,\n58475L,58476L,58477L,58478L,58479L,58480L,58481L,58482L,58483L,58484L,\n58485L,58486L,58487L,58488L,58489L,58490L,58491L,58492L,58493L,58494L,\n58495L,58496L,58497L,58498L,58499L,58500L,58501L,58502L,58503L,58504L,\n58505L,58506L,58507L,58508L,58509L,58510L,58511L,58512L,58513L,58514L,\n58515L,58516L,58517L,58518L,58519L,58520L,58521L,58522L,58523L,58524L,\n58525L,58526L,58527L,58528L,58529L,58530L,58531L,58532L,58533L,58534L,\n58535L,58536L,58537L,58538L,58539L,58540L,58541L,58542L,58543L,58544L,\n58545L,58546L,58547L,58548L,58549L,58550L,58551L,58552L,58553L,58554L,\n58555L,58556L,58557L,58558L,58559L,58560L,58561L,58562L,58563L,58564L,\n58565L,58566L,58567L,58568L,58569L,58570L,58571L,58572L,58573L,58574L,\n58575L,58576L,58577L,58578L,58579L,58580L,58581L,58582L,58583L,58584L,\n58585L,58586L,58587L,58588L,58589L,58590L,58591L,58592L,58593L,58594L,\n58595L,58596L,58597L,58598L,58599L,58600L,58601L,58602L,58603L,58604L,\n58605L,58606L,58607L,58608L,58609L,58610L,58611L,58612L,58613L,58614L,\n58615L,58616L,58617L,58618L,58619L,58620L,58621L,58622L,58623L,58624L,\n58625L,58626L,58627L,58628L,58629L,58630L,58631L,58632L,58633L,58634L,\n58635L,58636L,58637L,58638L,58639L,58640L,58641L,58642L,58643L,58644L,\n58645L,58646L,58647L,58648L,58649L,58650L,58651L,58652L,58653L,58654L,\n58655L,58656L,58657L,58658L,58659L,58660L,58661L,58662L,58663L,58664L,\n58665L,58666L,58667L,58668L,58669L,58670L,58671L,58672L,58673L,58674L,\n58675L,58676L,58677L,58678L,58679L,58680L,58681L,58682L,58683L,58684L,\n58685L,58686L,58687L,58688L,58689L,58690L,58691L,58692L,58693L,58694L,\n58695L,58696L,58697L,58698L,58699L,58700L,58701L,58702L,58703L,58704L,\n58705L,58706L,58707L,58708L,58709L,58710L,58711L,58712L,58713L,58714L,\n58715L,58716L,58717L,58718L,58719L,58720L,58721L,58722L,58723L,58724L,\n58725L,58726L,58727L,58728L,58729L,58730L,58731L,58732L,58733L,58734L,\n58735L,58736L,58737L,58738L,58739L,58740L,58741L,58742L,58743L,58744L,\n58745L,58746L,58747L,58748L,58749L,58750L,58751L,58752L,58753L,58754L,\n58755L,58756L,58757L,58758L,58759L,58760L,58761L,58762L,58763L,58764L,\n58765L,58766L,58767L,58768L,58769L,58770L,58771L,58772L,58773L,58774L,\n58775L,58776L,58777L,58778L,58779L,58780L,58781L,58782L,58783L,58784L,\n58785L,58786L,58787L,58788L,58789L,58790L,58791L,58792L,58793L,58794L,\n58795L,58796L,58797L,58798L,58799L,58800L,58801L,58802L,58803L,58804L,\n58805L,58806L,58807L,58808L,58809L,58810L,58811L,58812L,58813L,58814L,\n58815L,58816L,58817L,58818L,58819L,58820L,58821L,58822L,58823L,58824L,\n58825L,58826L,58827L,58828L,58829L,58830L,58831L,58832L,58833L,58834L,\n58835L,58836L,58837L,58838L,58839L,58840L,58841L,58842L,58843L,58844L,\n58845L,58846L,58847L,58848L,58849L,58850L,58851L,58852L,58853L,58854L,\n58855L,58856L,58857L,58858L,58859L,58860L,58861L,58862L,58863L,58864L,\n58865L,58866L,58867L,58868L,58869L,58870L,58871L,58872L,58873L,58874L,\n58875L,58876L,58877L,58878L,58879L,58880L,58881L,58882L,58883L,58884L,\n58885L,58886L,58887L,58888L,58889L,58890L,58891L,58892L,58893L,58894L,\n58895L,58896L,58897L,58898L,58899L,58900L,58901L,58902L,58903L,58904L,\n58905L,58906L,58907L,58908L,58909L,58910L,58911L,58912L,58913L,58914L,\n58915L,58916L,58917L,58918L,58919L,58920L,58921L,58922L,58923L,58924L,\n58925L,58926L,58927L,58928L,58929L,58930L,58931L,58932L,58933L,58934L,\n58935L,58936L,58937L,58938L,58939L,58940L,58941L,58942L,58943L,58944L,\n58945L,58946L,58947L,58948L,58949L,58950L,58951L,58952L,58953L,58954L,\n58955L,58956L,58957L,58958L,58959L,58960L,58961L,58962L,58963L,58964L,\n58965L,58966L,58967L,58968L,58969L,58970L,58971L,58972L,58973L,58974L,\n58975L,58976L,58977L,58978L,58979L,58980L,58981L,58982L,58983L,58984L,\n58985L,58986L,58987L,58988L,58989L,58990L,58991L,58992L,58993L,58994L,\n58995L,58996L,58997L,58998L,58999L,59000L,59001L,59002L,59003L,59004L,\n59005L,59006L,59007L,59008L,59009L,59010L,59011L,59012L,59013L,59014L,\n59015L,59016L,59017L,59018L,59019L,59020L,59021L,59022L,59023L,59024L,\n59025L,59026L,59027L,59028L,59029L,59030L,59031L,59032L,59033L,59034L,\n59035L,59036L,59037L,59038L,59039L,59040L,59041L,59042L,59043L,59044L,\n59045L,59046L,59047L,59048L,59049L,59050L,59051L,59052L,59053L,59054L,\n59055L,59056L,59057L,59058L,59059L,59060L,59061L,59062L,59063L,59064L,\n59065L,59066L,59067L,59068L,59069L,59070L,59071L,59072L,59073L,59074L,\n59075L,59076L,59077L,59078L,59079L,59080L,59081L,59082L,59083L,59084L,\n59085L,59086L,59087L,59088L,59089L,59090L,59091L,59092L,59093L,59094L,\n59095L,59096L,59097L,59098L,59099L,59100L,59101L,59102L,59103L,59104L,\n59105L,59106L,59107L,59108L,59109L,59110L,59111L,59112L,59113L,59114L,\n59115L,59116L,59117L,59118L,59119L,59120L,59121L,59122L,59123L,59124L,\n59125L,59126L,59127L,59128L,59129L,59130L,59131L,59132L,59133L,59134L,\n59135L,59136L,59137L,59138L,59139L,59140L,59141L,59142L,59143L,59144L,\n59145L,59146L,59147L,59148L,59149L,59150L,59151L,59152L,59153L,59154L,\n59155L,59156L,59157L,59158L,59159L,59160L,59161L,59162L,59163L,59164L,\n59165L,59166L,59167L,59168L,59169L,59170L,59171L,59172L,59173L,59174L,\n59175L,59176L,59177L,59178L,59179L,59180L,59181L,59182L,59183L,59184L,\n59185L,59186L,59187L,59188L,59189L,59190L,59191L,59192L,59193L,59194L,\n59195L,59196L,59197L,59198L,59199L,59200L,59201L,59202L,59203L,59204L,\n59205L,59206L,59207L,59208L,59209L,59210L,59211L,59212L,59213L,59214L,\n59215L,59216L,59217L,59218L,59219L,59220L,59221L,59222L,59223L,59224L,\n59225L,59226L,59227L,59228L,59229L,59230L,59231L,59232L,59233L,59234L,\n59235L,59236L,59237L,59238L,59239L,59240L,59241L,59242L,59243L,59244L,\n59245L,59246L,59247L,59248L,59249L,59250L,59251L,59252L,59253L,59254L,\n59255L,59256L,59257L,59258L,59259L,59260L,59261L,59262L,59263L,59264L,\n59265L,59266L,59267L,59268L,59269L,59270L,59271L,59272L,59273L,59274L,\n59275L,59276L,59277L,59278L,59279L,59280L,59281L,59282L,59283L,59284L,\n59285L,59286L,59287L,59288L,59289L,59290L,59291L,59292L,59293L,59294L,\n59295L,59296L,59297L,59298L,59299L,59300L,59301L,59302L,59303L,59304L,\n59305L,59306L,59307L,59308L,59309L,59310L,59311L,59312L,59313L,59314L,\n59315L,59316L,59317L,59318L,59319L,59320L,59321L,59322L,59323L,59324L,\n59325L,59326L,59327L,59328L,59329L,59330L,59331L,59332L,59333L,59334L,\n59335L,59336L,59337L,59338L,59339L,59340L,59341L,59342L,59343L,59344L,\n59345L,59346L,59347L,59348L,59349L,59350L,59351L,59352L,59353L,59354L,\n59355L,59356L,59357L,59358L,59359L,59360L,59361L,59362L,59363L,59364L,\n59365L,59366L,59367L,59368L,59369L,59370L,59371L,59372L,59373L,59374L,\n59375L,59376L,59377L,59378L,59379L,59380L,59381L,59382L,59383L,59384L,\n59385L,59386L,59387L,59388L,59389L,59390L,59391L,59392L,59393L,59394L,\n59395L,59396L,59397L,59398L,59399L,59400L,59401L,59402L,59403L,59404L,\n59405L,59406L,59407L,59408L,59409L,59410L,59411L,59412L,59413L,59414L,\n59415L,59416L,59417L,59418L,59419L,59420L,59421L,59422L,59423L,59424L,\n59425L,59426L,59427L,59428L,59429L,59430L,59431L,59432L,59433L,59434L,\n59435L,59436L,59437L,59438L,59439L,59440L,59441L,59442L,59443L,59444L,\n59445L,59446L,59447L,59448L,59449L,59450L,59451L,59452L,59453L,59454L,\n59455L,59456L,59457L,59458L,59459L,59460L,59461L,59462L,59463L,59464L,\n59465L,59466L,59467L,59468L,59469L,59470L,59471L,59472L,59473L,59474L,\n59475L,59476L,59477L,59478L,59479L,59480L,59481L,59482L,59483L,59484L,\n59485L,59486L,59487L,59488L,59489L,59490L,59491L,59492L,59493L,59494L,\n59495L,59496L,59497L,59498L,59499L,59500L,59501L,59502L,59503L,59504L,\n59505L,59506L,59507L,59508L,59509L,59510L,59511L,59512L,59513L,59514L,\n59515L,59516L,59517L,59518L,59519L,59520L,59521L,59522L,59523L,59524L,\n59525L,59526L,59527L,59528L,59529L,59530L,59531L,59532L,59533L,59534L,\n59535L,59536L,59537L,59538L,59539L,59540L,59541L,59542L,59543L,59544L,\n59545L,59546L,59547L,59548L,59549L,59550L,59551L,59552L,59553L,59554L,\n59555L,59556L,59557L,59558L,59559L,59560L,59561L,59562L,59563L,59564L,\n59565L,59566L,59567L,59568L,59569L,59570L,59571L,59572L,59573L,59574L,\n59575L,59576L,59577L,59578L,59579L,59580L,59581L,59582L,59583L,59584L,\n59585L,59586L,59587L,59588L,59589L,59590L,59591L,59592L,59593L,59594L,\n59595L,59596L,59597L,59598L,59599L,59600L,59601L,59602L,59603L,59604L,\n59605L,59606L,59607L,59608L,59609L,59610L,59611L,59612L,59613L,59614L,\n59615L,59616L,59617L,59618L,59619L,59620L,59621L,59622L,59623L,59624L,\n59625L,59626L,59627L,59628L,59629L,59630L,59631L,59632L,59633L,59634L,\n59635L,59636L,59637L,59638L,59639L,59640L,59641L,59642L,59643L,59644L,\n59645L,59646L,59647L,59648L,59649L,59650L,59651L,59652L,59653L,59654L,\n59655L,59656L,59657L,59658L,59659L,59660L,59661L,59662L,59663L,59664L,\n59665L,59666L,59667L,59668L,59669L,59670L,59671L,59672L,59673L,59674L,\n59675L,59676L,59677L,59678L,59679L,59680L,59681L,59682L,59683L,59684L,\n59685L,59686L,59687L,59688L,59689L,59690L,59691L,59692L,59693L,59694L,\n59695L,59696L,59697L,59698L,59699L,59700L,59701L,59702L,59703L,59704L,\n59705L,59706L,59707L,59708L,59709L,59710L,59711L,59712L,59713L,59714L,\n59715L,59716L,59717L,59718L,59719L,59720L,59721L,59722L,59723L,59724L,\n59725L,59726L,59727L,59728L,59729L,59730L,59731L,59732L,59733L,59734L,\n59735L,59736L,59737L,59738L,59739L,59740L,59741L,59742L,59743L,59744L,\n59745L,59746L,59747L,59748L,59749L,59750L,59751L,59752L,59753L,59754L,\n59755L,59756L,59757L,59758L,59759L,59760L,59761L,59762L,59763L,59764L,\n59765L,59766L,59767L,59768L,59769L,59770L,59771L,59772L,59773L,59774L,\n59775L,59776L,59777L,59778L,59779L,59780L,59781L,59782L,59783L,59784L,\n59785L,59786L,59787L,59788L,59789L,59790L,59791L,59792L,59793L,59794L,\n59795L,59796L,59797L,59798L,59799L,59800L,59801L,59802L,59803L,59804L,\n59805L,59806L,59807L,59808L,59809L,59810L,59811L,59812L,59813L,59814L,\n59815L,59816L,59817L,59818L,59819L,59820L,59821L,59822L,59823L,59824L,\n59825L,59826L,59827L,59828L,59829L,59830L,59831L,59832L,59833L,59834L,\n59835L,59836L,59837L,59838L,59839L,59840L,59841L,59842L,59843L,59844L,\n59845L,59846L,59847L,59848L,59849L,59850L,59851L,59852L,59853L,59854L,\n59855L,59856L,59857L,59858L,59859L,59860L,59861L,59862L,59863L,59864L,\n59865L,59866L,59867L,59868L,59869L,59870L,59871L,59872L,59873L,59874L,\n59875L,59876L,59877L,59878L,59879L,59880L,59881L,59882L,59883L,59884L,\n59885L,59886L,59887L,59888L,59889L,59890L,59891L,59892L,59893L,59894L,\n59895L,59896L,59897L,59898L,59899L,59900L,59901L,59902L,59903L,59904L,\n59905L,59906L,59907L,59908L,59909L,59910L,59911L,59912L,59913L,59914L,\n59915L,59916L,59917L,59918L,59919L,59920L,59921L,59922L,59923L,59924L,\n59925L,59926L,59927L,59928L,59929L,59930L,59931L,59932L,59933L,59934L,\n59935L,59936L,59937L,59938L,59939L,59940L,59941L,59942L,59943L,59944L,\n59945L,59946L,59947L,59948L,59949L,59950L,59951L,59952L,59953L,59954L,\n59955L,59956L,59957L,59958L,59959L,59960L,59961L,59962L,59963L,59964L,\n59965L,59966L,59967L,59968L,59969L,59970L,59971L,59972L,59973L,59974L,\n59975L,59976L,59977L,59978L,59979L,59980L,59981L,59982L,59983L,59984L,\n59985L,59986L,59987L,59988L,59989L,59990L,59991L,59992L,59993L,59994L,\n59995L,59996L,59997L,59998L,59999L,60000L,60001L,60002L,60003L,60004L,\n60005L,60006L,60007L,60008L,60009L,60010L,60011L,60012L,60013L,60014L,\n60015L,60016L,60017L,60018L,60019L,60020L,60021L,60022L,60023L,60024L,\n60025L,60026L,60027L,60028L,60029L,60030L,60031L,60032L,60033L,60034L,\n60035L,60036L,60037L,60038L,60039L,60040L,60041L,60042L,60043L,60044L,\n60045L,60046L,60047L,60048L,60049L,60050L,60051L,60052L,60053L,60054L,\n60055L,60056L,60057L,60058L,60059L,60060L,60061L,60062L,60063L,60064L,\n60065L,60066L,60067L,60068L,60069L,60070L,60071L,60072L,60073L,60074L,\n60075L,60076L,60077L,60078L,60079L,60080L,60081L,60082L,60083L,60084L,\n60085L,60086L,60087L,60088L,60089L,60090L,60091L,60092L,60093L,60094L,\n60095L,60096L,60097L,60098L,60099L,60100L,60101L,60102L,60103L,60104L,\n60105L,60106L,60107L,60108L,60109L,60110L,60111L,60112L,60113L,60114L,\n60115L,60116L,60117L,60118L,60119L,60120L,60121L,60122L,60123L,60124L,\n60125L,60126L,60127L,60128L,60129L,60130L,60131L,60132L,60133L,60134L,\n60135L,60136L,60137L,60138L,60139L,60140L,60141L,60142L,60143L,60144L,\n60145L,60146L,60147L,60148L,60149L,60150L,60151L,60152L,60153L,60154L,\n60155L,60156L,60157L,60158L,60159L,60160L,60161L,60162L,60163L,60164L,\n60165L,60166L,60167L,60168L,60169L,60170L,60171L,60172L,60173L,60174L,\n60175L,60176L,60177L,60178L,60179L,60180L,60181L,60182L,60183L,60184L,\n60185L,60186L,60187L,60188L,60189L,60190L,60191L,60192L,60193L,60194L,\n60195L,60196L,60197L,60198L,60199L,60200L,60201L,60202L,60203L,60204L,\n60205L,60206L,60207L,60208L,60209L,60210L,60211L,60212L,60213L,60214L,\n60215L,60216L,60217L,60218L,60219L,60220L,60221L,60222L,60223L,60224L,\n60225L,60226L,60227L,60228L,60229L,60230L,60231L,60232L,60233L,60234L,\n60235L,60236L,60237L,60238L,60239L,60240L,60241L,60242L,60243L,60244L,\n60245L,60246L,60247L,60248L,60249L,60250L,60251L,60252L,60253L,60254L,\n60255L,60256L,60257L,60258L,60259L,60260L,60261L,60262L,60263L,60264L,\n60265L,60266L,60267L,60268L,60269L,60270L,60271L,60272L,60273L,60274L,\n60275L,60276L,60277L,60278L,60279L,60280L,60281L,60282L,60283L,60284L,\n60285L,60286L,60287L,60288L,60289L,60290L,60291L,60292L,60293L,60294L,\n60295L,60296L,60297L,60298L,60299L,60300L,60301L,60302L,60303L,60304L,\n60305L,60306L,60307L,60308L,60309L,60310L,60311L,60312L,60313L,60314L,\n60315L,60316L,60317L,60318L,60319L,60320L,60321L,60322L,60323L,60324L,\n60325L,60326L,60327L,60328L,60329L,60330L,60331L,60332L,60333L,60334L,\n60335L,60336L,60337L,60338L,60339L,60340L,60341L,60342L,60343L,60344L,\n60345L,60346L,60347L,60348L,60349L,60350L,60351L,60352L,60353L,60354L,\n60355L,60356L,60357L,60358L,60359L,60360L,60361L,60362L,60363L,60364L,\n60365L,60366L,60367L,60368L,60369L,60370L,60371L,60372L,60373L,60374L,\n60375L,60376L,60377L,60378L,60379L,60380L,60381L,60382L,60383L,60384L,\n60385L,60386L,60387L,60388L,60389L,60390L,60391L,60392L,60393L,60394L,\n60395L,60396L,60397L,60398L,60399L,60400L,60401L,60402L,60403L,60404L,\n60405L,60406L,60407L,60408L,60409L,60410L,60411L,60412L,60413L,60414L,\n60415L,60416L,60417L,60418L,60419L,60420L,60421L,60422L,60423L,60424L,\n60425L,60426L,60427L,60428L,60429L,60430L,60431L,60432L,60433L,60434L,\n60435L,60436L,60437L,60438L,60439L,60440L,60441L,60442L,60443L,60444L,\n60445L,60446L,60447L,60448L,60449L,60450L,60451L,60452L,60453L,60454L,\n60455L,60456L,60457L,60458L,60459L,60460L,60461L,60462L,60463L,60464L,\n60465L,60466L,60467L,60468L,60469L,60470L,60471L,60472L,60473L,60474L,\n60475L,60476L,60477L,60478L,60479L,60480L,60481L,60482L,60483L,60484L,\n60485L,60486L,60487L,60488L,60489L,60490L,60491L,60492L,60493L,60494L,\n60495L,60496L,60497L,60498L,60499L,60500L,60501L,60502L,60503L,60504L,\n60505L,60506L,60507L,60508L,60509L,60510L,60511L,60512L,60513L,60514L,\n60515L,60516L,60517L,60518L,60519L,60520L,60521L,60522L,60523L,60524L,\n60525L,60526L,60527L,60528L,60529L,60530L,60531L,60532L,60533L,60534L,\n60535L,60536L,60537L,60538L,60539L,60540L,60541L,60542L,60543L,60544L,\n60545L,60546L,60547L,60548L,60549L,60550L,60551L,60552L,60553L,60554L,\n60555L,60556L,60557L,60558L,60559L,60560L,60561L,60562L,60563L,60564L,\n60565L,60566L,60567L,60568L,60569L,60570L,60571L,60572L,60573L,60574L,\n60575L,60576L,60577L,60578L,60579L,60580L,60581L,60582L,60583L,60584L,\n60585L,60586L,60587L,60588L,60589L,60590L,60591L,60592L,60593L,60594L,\n60595L,60596L,60597L,60598L,60599L,60600L,60601L,60602L,60603L,60604L,\n60605L,60606L,60607L,60608L,60609L,60610L,60611L,60612L,60613L,60614L,\n60615L,60616L,60617L,60618L,60619L,60620L,60621L,60622L,60623L,60624L,\n60625L,60626L,60627L,60628L,60629L,60630L,60631L,60632L,60633L,60634L,\n60635L,60636L,60637L,60638L,60639L,60640L,60641L,60642L,60643L,60644L,\n60645L,60646L,60647L,60648L,60649L,60650L,60651L,60652L,60653L,60654L,\n60655L,60656L,60657L,60658L,60659L,60660L,60661L,60662L,60663L,60664L,\n60665L,60666L,60667L,60668L,60669L,60670L,60671L,60672L,60673L,60674L,\n60675L,60676L,60677L,60678L,60679L,60680L,60681L,60682L,60683L,60684L,\n60685L,60686L,60687L,60688L,60689L,60690L,60691L,60692L,60693L,60694L,\n60695L,60696L,60697L,60698L,60699L,60700L,60701L,60702L,60703L,60704L,\n60705L,60706L,60707L,60708L,60709L,60710L,60711L,60712L,60713L,60714L,\n60715L,60716L,60717L,60718L,60719L,60720L,60721L,60722L,60723L,60724L,\n60725L,60726L,60727L,60728L,60729L,60730L,60731L,60732L,60733L,60734L,\n60735L,60736L,60737L,60738L,60739L,60740L,60741L,60742L,60743L,60744L,\n60745L,60746L,60747L,60748L,60749L,60750L,60751L,60752L,60753L,60754L,\n60755L,60756L,60757L,60758L,60759L,60760L,60761L,60762L,60763L,60764L,\n60765L,60766L,60767L,60768L,60769L,60770L,60771L,60772L,60773L,60774L,\n60775L,60776L,60777L,60778L,60779L,60780L,60781L,60782L,60783L,60784L,\n60785L,60786L,60787L,60788L,60789L,60790L,60791L,60792L,60793L,60794L,\n60795L,60796L,60797L,60798L,60799L,60800L,60801L,60802L,60803L,60804L,\n60805L,60806L,60807L,60808L,60809L,60810L,60811L,60812L,60813L,60814L,\n60815L,60816L,60817L,60818L,60819L,60820L,60821L,60822L,60823L,60824L,\n60825L,60826L,60827L,60828L,60829L,60830L,60831L,60832L,60833L,60834L,\n60835L,60836L,60837L,60838L,60839L,60840L,60841L,60842L,60843L,60844L,\n60845L,60846L,60847L,60848L,60849L,60850L,60851L,60852L,60853L,60854L,\n60855L,60856L,60857L,60858L,60859L,60860L,60861L,60862L,60863L,60864L,\n60865L,60866L,60867L,60868L,60869L,60870L,60871L,60872L,60873L,60874L,\n60875L,60876L,60877L,60878L,60879L,60880L,60881L,60882L,60883L,60884L,\n60885L,60886L,60887L,60888L,60889L,60890L,60891L,60892L,60893L,60894L,\n60895L,60896L,60897L,60898L,60899L,60900L,60901L,60902L,60903L,60904L,\n60905L,60906L,60907L,60908L,60909L,60910L,60911L,60912L,60913L,60914L,\n60915L,60916L,60917L,60918L,60919L,60920L,60921L,60922L,60923L,60924L,\n60925L,60926L,60927L,60928L,60929L,60930L,60931L,60932L,60933L,60934L,\n60935L,60936L,60937L,60938L,60939L,60940L,60941L,60942L,60943L,60944L,\n60945L,60946L,60947L,60948L,60949L,60950L,60951L,60952L,60953L,60954L,\n60955L,60956L,60957L,60958L,60959L,60960L,60961L,60962L,60963L,60964L,\n60965L,60966L,60967L,60968L,60969L,60970L,60971L,60972L,60973L,60974L,\n60975L,60976L,60977L,60978L,60979L,60980L,60981L,60982L,60983L,60984L,\n60985L,60986L,60987L,60988L,60989L,60990L,60991L,60992L,60993L,60994L,\n60995L,60996L,60997L,60998L,60999L,61000L,61001L,61002L,61003L,61004L,\n61005L,61006L,61007L,61008L,61009L,61010L,61011L,61012L,61013L,61014L,\n61015L,61016L,61017L,61018L,61019L,61020L,61021L,61022L,61023L,61024L,\n61025L,61026L,61027L,61028L,61029L,61030L,61031L,61032L,61033L,61034L,\n61035L,61036L,61037L,61038L,61039L,61040L,61041L,61042L,61043L,61044L,\n61045L,61046L,61047L,61048L,61049L,61050L,61051L,61052L,61053L,61054L,\n61055L,61056L,61057L,61058L,61059L,61060L,61061L,61062L,61063L,61064L,\n61065L,61066L,61067L,61068L,61069L,61070L,61071L,61072L,61073L,61074L,\n61075L,61076L,61077L,61078L,61079L,61080L,61081L,61082L,61083L,61084L,\n61085L,61086L,61087L,61088L,61089L,61090L,61091L,61092L,61093L,61094L,\n61095L,61096L,61097L,61098L,61099L,61100L,61101L,61102L,61103L,61104L,\n61105L,61106L,61107L,61108L,61109L,61110L,61111L,61112L,61113L,61114L,\n61115L,61116L,61117L,61118L,61119L,61120L,61121L,61122L,61123L,61124L,\n61125L,61126L,61127L,61128L,61129L,61130L,61131L,61132L,61133L,61134L,\n61135L,61136L,61137L,61138L,61139L,61140L,61141L,61142L,61143L,61144L,\n61145L,61146L,61147L,61148L,61149L,61150L,61151L,61152L,61153L,61154L,\n61155L,61156L,61157L,61158L,61159L,61160L,61161L,61162L,61163L,61164L,\n61165L,61166L,61167L,61168L,61169L,61170L,61171L,61172L,61173L,61174L,\n61175L,61176L,61177L,61178L,61179L,61180L,61181L,61182L,61183L,61184L,\n61185L,61186L,61187L,61188L,61189L,61190L,61191L,61192L,61193L,61194L,\n61195L,61196L,61197L,61198L,61199L,61200L,61201L,61202L,61203L,61204L,\n61205L,61206L,61207L,61208L,61209L,61210L,61211L,61212L,61213L,61214L,\n61215L,61216L,61217L,61218L,61219L,61220L,61221L,61222L,61223L,61224L,\n61225L,61226L,61227L,61228L,61229L,61230L,61231L,61232L,61233L,61234L,\n61235L,61236L,61237L,61238L,61239L,61240L,61241L,61242L,61243L,61244L,\n61245L,61246L,61247L,61248L,61249L,61250L,61251L,61252L,61253L,61254L,\n61255L,61256L,61257L,61258L,61259L,61260L,61261L,61262L,61263L,61264L,\n61265L,61266L,61267L,61268L,61269L,61270L,61271L,61272L,61273L,61274L,\n61275L,61276L,61277L,61278L,61279L,61280L,61281L,61282L,61283L,61284L,\n61285L,61286L,61287L,61288L,61289L,61290L,61291L,61292L,61293L,61294L,\n61295L,61296L,61297L,61298L,61299L,61300L,61301L,61302L,61303L,61304L,\n61305L,61306L,61307L,61308L,61309L,61310L,61311L,61312L,61313L,61314L,\n61315L,61316L,61317L,61318L,61319L,61320L,61321L,61322L,61323L,61324L,\n61325L,61326L,61327L,61328L,61329L,61330L,61331L,61332L,61333L,61334L,\n61335L,61336L,61337L,61338L,61339L,61340L,61341L,61342L,61343L,61344L,\n61345L,61346L,61347L,61348L,61349L,61350L,61351L,61352L,61353L,61354L,\n61355L,61356L,61357L,61358L,61359L,61360L,61361L,61362L,61363L,61364L,\n61365L,61366L,61367L,61368L,61369L,61370L,61371L,61372L,61373L,61374L,\n61375L,61376L,61377L,61378L,61379L,61380L,61381L,61382L,61383L,61384L,\n61385L,61386L,61387L,61388L,61389L,61390L,61391L,61392L,61393L,61394L,\n61395L,61396L,61397L,61398L,61399L,61400L,61401L,61402L,61403L,61404L,\n61405L,61406L,61407L,61408L,61409L,61410L,61411L,61412L,61413L,61414L,\n61415L,61416L,61417L,61418L,61419L,61420L,61421L,61422L,61423L,61424L,\n61425L,61426L,61427L,61428L,61429L,61430L,61431L,61432L,61433L,61434L,\n61435L,61436L,61437L,61438L,61439L,61440L,61441L,61442L,61443L,61444L,\n61445L,61446L,61447L,61448L,61449L,61450L,61451L,61452L,61453L,61454L,\n61455L,61456L,61457L,61458L,61459L,61460L,61461L,61462L,61463L,61464L,\n61465L,61466L,61467L,61468L,61469L,61470L,61471L,61472L,61473L,61474L,\n61475L,61476L,61477L,61478L,61479L,61480L,61481L,61482L,61483L,61484L,\n61485L,61486L,61487L,61488L,61489L,61490L,61491L,61492L,61493L,61494L,\n61495L,61496L,61497L,61498L,61499L,61500L,61501L,61502L,61503L,61504L,\n61505L,61506L,61507L,61508L,61509L,61510L,61511L,61512L,61513L,61514L,\n61515L,61516L,61517L,61518L,61519L,61520L,61521L,61522L,61523L,61524L,\n61525L,61526L,61527L,61528L,61529L,61530L,61531L,61532L,61533L,61534L,\n61535L,61536L,61537L,61538L,61539L,61540L,61541L,61542L,61543L,61544L,\n61545L,61546L,61547L,61548L,61549L,61550L,61551L,61552L,61553L,61554L,\n61555L,61556L,61557L,61558L,61559L,61560L,61561L,61562L,61563L,61564L,\n61565L,61566L,61567L,61568L,61569L,61570L,61571L,61572L,61573L,61574L,\n61575L,61576L,61577L,61578L,61579L,61580L,61581L,61582L,61583L,61584L,\n61585L,61586L,61587L,61588L,61589L,61590L,61591L,61592L,61593L,61594L,\n61595L,61596L,61597L,61598L,61599L,61600L,61601L,61602L,61603L,61604L,\n61605L,61606L,61607L,61608L,61609L,61610L,61611L,61612L,61613L,61614L,\n61615L,61616L,61617L,61618L,61619L,61620L,61621L,61622L,61623L,61624L,\n61625L,61626L,61627L,61628L,61629L,61630L,61631L,61632L,61633L,61634L,\n61635L,61636L,61637L,61638L,61639L,61640L,61641L,61642L,61643L,61644L,\n61645L,61646L,61647L,61648L,61649L,61650L,61651L,61652L,61653L,61654L,\n61655L,61656L,61657L,61658L,61659L,61660L,61661L,61662L,61663L,61664L,\n61665L,61666L,61667L,61668L,61669L,61670L,61671L,61672L,61673L,61674L,\n61675L,61676L,61677L,61678L,61679L,61680L,61681L,61682L,61683L,61684L,\n61685L,61686L,61687L,61688L,61689L,61690L,61691L,61692L,61693L,61694L,\n61695L,61696L,61697L,61698L,61699L,61700L,61701L,61702L,61703L,61704L,\n61705L,61706L,61707L,61708L,61709L,61710L,61711L,61712L,61713L,61714L,\n61715L,61716L,61717L,61718L,61719L,61720L,61721L,61722L,61723L,61724L,\n61725L,61726L,61727L,61728L,61729L,61730L,61731L,61732L,61733L,61734L,\n61735L,61736L,61737L,61738L,61739L,61740L,61741L,61742L,61743L,61744L,\n61745L,61746L,61747L,61748L,61749L,61750L,61751L,61752L,61753L,61754L,\n61755L,61756L,61757L,61758L,61759L,61760L,61761L,61762L,61763L,61764L,\n61765L,61766L,61767L,61768L,61769L,61770L,61771L,61772L,61773L,61774L,\n61775L,61776L,61777L,61778L,61779L,61780L,61781L,61782L,61783L,61784L,\n61785L,61786L,61787L,61788L,61789L,61790L,61791L,61792L,61793L,61794L,\n61795L,61796L,61797L,61798L,61799L,61800L,61801L,61802L,61803L,61804L,\n61805L,61806L,61807L,61808L,61809L,61810L,61811L,61812L,61813L,61814L,\n61815L,61816L,61817L,61818L,61819L,61820L,61821L,61822L,61823L,61824L,\n61825L,61826L,61827L,61828L,61829L,61830L,61831L,61832L,61833L,61834L,\n61835L,61836L,61837L,61838L,61839L,61840L,61841L,61842L,61843L,61844L,\n61845L,61846L,61847L,61848L,61849L,61850L,61851L,61852L,61853L,61854L,\n61855L,61856L,61857L,61858L,61859L,61860L,61861L,61862L,61863L,61864L,\n61865L,61866L,61867L,61868L,61869L,61870L,61871L,61872L,61873L,61874L,\n61875L,61876L,61877L,61878L,61879L,61880L,61881L,61882L,61883L,61884L,\n61885L,61886L,61887L,61888L,61889L,61890L,61891L,61892L,61893L,61894L,\n61895L,61896L,61897L,61898L,61899L,61900L,61901L,61902L,61903L,61904L,\n61905L,61906L,61907L,61908L,61909L,61910L,61911L,61912L,61913L,61914L,\n61915L,61916L,61917L,61918L,61919L,61920L,61921L,61922L,61923L,61924L,\n61925L,61926L,61927L,61928L,61929L,61930L,61931L,61932L,61933L,61934L,\n61935L,61936L,61937L,61938L,61939L,61940L,61941L,61942L,61943L,61944L,\n61945L,61946L,61947L,61948L,61949L,61950L,61951L,61952L,61953L,61954L,\n61955L,61956L,61957L,61958L,61959L,61960L,61961L,61962L,61963L,61964L,\n61965L,61966L,61967L,61968L,61969L,61970L,61971L,61972L,61973L,61974L,\n61975L,61976L,61977L,61978L,61979L,61980L,61981L,61982L,61983L,61984L,\n61985L,61986L,61987L,61988L,61989L,61990L,61991L,61992L,61993L,61994L,\n61995L,61996L,61997L,61998L,61999L,62000L,62001L,62002L,62003L,62004L,\n62005L,62006L,62007L,62008L,62009L,62010L,62011L,62012L,62013L,62014L,\n62015L,62016L,62017L,62018L,62019L,62020L,62021L,62022L,62023L,62024L,\n62025L,62026L,62027L,62028L,62029L,62030L,62031L,62032L,62033L,62034L,\n62035L,62036L,62037L,62038L,62039L,62040L,62041L,62042L,62043L,62044L,\n62045L,62046L,62047L,62048L,62049L,62050L,62051L,62052L,62053L,62054L,\n62055L,62056L,62057L,62058L,62059L,62060L,62061L,62062L,62063L,62064L,\n62065L,62066L,62067L,62068L,62069L,62070L,62071L,62072L,62073L,62074L,\n62075L,62076L,62077L,62078L,62079L,62080L,62081L,62082L,62083L,62084L,\n62085L,62086L,62087L,62088L,62089L,62090L,62091L,62092L,62093L,62094L,\n62095L,62096L,62097L,62098L,62099L,62100L,62101L,62102L,62103L,62104L,\n62105L,62106L,62107L,62108L,62109L,62110L,62111L,62112L,62113L,62114L,\n62115L,62116L,62117L,62118L,62119L,62120L,62121L,62122L,62123L,62124L,\n62125L,62126L,62127L,62128L,62129L,62130L,62131L,62132L,62133L,62134L,\n62135L,62136L,62137L,62138L,62139L,62140L,62141L,62142L,62143L,62144L,\n62145L,62146L,62147L,62148L,62149L,62150L,62151L,62152L,62153L,62154L,\n62155L,62156L,62157L,62158L,62159L,62160L,62161L,62162L,62163L,62164L,\n62165L,62166L,62167L,62168L,62169L,62170L,62171L,62172L,62173L,62174L,\n62175L,62176L,62177L,62178L,62179L,62180L,62181L,62182L,62183L,62184L,\n62185L,62186L,62187L,62188L,62189L,62190L,62191L,62192L,62193L,62194L,\n62195L,62196L,62197L,62198L,62199L,62200L,62201L,62202L,62203L,62204L,\n62205L,62206L,62207L,62208L,62209L,62210L,62211L,62212L,62213L,62214L,\n62215L,62216L,62217L,62218L,62219L,62220L,62221L,62222L,62223L,62224L,\n62225L,62226L,62227L,62228L,62229L,62230L,62231L,62232L,62233L,62234L,\n62235L,62236L,62237L,62238L,62239L,62240L,62241L,62242L,62243L,62244L,\n62245L,62246L,62247L,62248L,62249L,62250L,62251L,62252L,62253L,62254L,\n62255L,62256L,62257L,62258L,62259L,62260L,62261L,62262L,62263L,62264L,\n62265L,62266L,62267L,62268L,62269L,62270L,62271L,62272L,62273L,62274L,\n62275L,62276L,62277L,62278L,62279L,62280L,62281L,62282L,62283L,62284L,\n62285L,62286L,62287L,62288L,62289L,62290L,62291L,62292L,62293L,62294L,\n62295L,62296L,62297L,62298L,62299L,62300L,62301L,62302L,62303L,62304L,\n62305L,62306L,62307L,62308L,62309L,62310L,62311L,62312L,62313L,62314L,\n62315L,62316L,62317L,62318L,62319L,62320L,62321L,62322L,62323L,62324L,\n62325L,62326L,62327L,62328L,62329L,62330L,62331L,62332L,62333L,62334L,\n62335L,62336L,62337L,62338L,62339L,62340L,62341L,62342L,62343L,62344L,\n62345L,62346L,62347L,62348L,62349L,62350L,62351L,62352L,62353L,62354L,\n62355L,62356L,62357L,62358L,62359L,62360L,62361L,62362L,62363L,62364L,\n62365L,62366L,62367L,62368L,62369L,62370L,62371L,62372L,62373L,62374L,\n62375L,62376L,62377L,62378L,62379L,62380L,62381L,62382L,62383L,62384L,\n62385L,62386L,62387L,62388L,62389L,62390L,62391L,62392L,62393L,62394L,\n62395L,62396L,62397L,62398L,62399L,62400L,62401L,62402L,62403L,62404L,\n62405L,62406L,62407L,62408L,62409L,62410L,62411L,62412L,62413L,62414L,\n62415L,62416L,62417L,62418L,62419L,62420L,62421L,62422L,62423L,62424L,\n62425L,62426L,62427L,62428L,62429L,62430L,62431L,62432L,62433L,62434L,\n62435L,62436L,62437L,62438L,62439L,62440L,62441L,62442L,62443L,62444L,\n62445L,62446L,62447L,62448L,62449L,62450L,62451L,62452L,62453L,62454L,\n62455L,62456L,62457L,62458L,62459L,62460L,62461L,62462L,62463L,62464L,\n62465L,62466L,62467L,62468L,62469L,62470L,62471L,62472L,62473L,62474L,\n62475L,62476L,62477L,62478L,62479L,62480L,62481L,62482L,62483L,62484L,\n62485L,62486L,62487L,62488L,62489L,62490L,62491L,62492L,62493L,62494L,\n62495L,62496L,62497L,62498L,62499L,62500L,62501L,62502L,62503L,62504L,\n62505L,62506L,62507L,62508L,62509L,62510L,62511L,62512L,62513L,62514L,\n62515L,62516L,62517L,62518L,62519L,62520L,62521L,62522L,62523L,62524L,\n62525L,62526L,62527L,62528L,62529L,62530L,62531L,62532L,62533L,62534L,\n62535L,62536L,62537L,62538L,62539L,62540L,62541L,62542L,62543L,62544L,\n62545L,62546L,62547L,62548L,62549L,62550L,62551L,62552L,62553L,62554L,\n62555L,62556L,62557L,62558L,62559L,62560L,62561L,62562L,62563L,62564L,\n62565L,62566L,62567L,62568L,62569L,62570L,62571L,62572L,62573L,62574L,\n62575L,62576L,62577L,62578L,62579L,62580L,62581L,62582L,62583L,62584L,\n62585L,62586L,62587L,62588L,62589L,62590L,62591L,62592L,62593L,62594L,\n62595L,62596L,62597L,62598L,62599L,62600L,62601L,62602L,62603L,62604L,\n62605L,62606L,62607L,62608L,62609L,62610L,62611L,62612L,62613L,62614L,\n62615L,62616L,62617L,62618L,62619L,62620L,62621L,62622L,62623L,62624L,\n62625L,62626L,62627L,62628L,62629L,62630L,62631L,62632L,62633L,62634L,\n62635L,62636L,62637L,62638L,62639L,62640L,62641L,62642L,62643L,62644L,\n62645L,62646L,62647L,62648L,62649L,62650L,62651L,62652L,62653L,62654L,\n62655L,62656L,62657L,62658L,62659L,62660L,62661L,62662L,62663L,62664L,\n62665L,62666L,62667L,62668L,62669L,62670L,62671L,62672L,62673L,62674L,\n62675L,62676L,62677L,62678L,62679L,62680L,62681L,62682L,62683L,62684L,\n62685L,62686L,62687L,62688L,62689L,62690L,62691L,62692L,62693L,62694L,\n62695L,62696L,62697L,62698L,62699L,62700L,62701L,62702L,62703L,62704L,\n62705L,62706L,62707L,62708L,62709L,62710L,62711L,62712L,62713L,62714L,\n62715L,62716L,62717L,62718L,62719L,62720L,62721L,62722L,62723L,62724L,\n62725L,62726L,62727L,62728L,62729L,62730L,62731L,62732L,62733L,62734L,\n62735L,62736L,62737L,62738L,62739L,62740L,62741L,62742L,62743L,62744L,\n62745L,62746L,62747L,62748L,62749L,62750L,62751L,62752L,62753L,62754L,\n62755L,62756L,62757L,62758L,62759L,62760L,62761L,62762L,62763L,62764L,\n62765L,62766L,62767L,62768L,62769L,62770L,62771L,62772L,62773L,62774L,\n62775L,62776L,62777L,62778L,62779L,62780L,62781L,62782L,62783L,62784L,\n62785L,62786L,62787L,62788L,62789L,62790L,62791L,62792L,62793L,62794L,\n62795L,62796L,62797L,62798L,62799L,62800L,62801L,62802L,62803L,62804L,\n62805L,62806L,62807L,62808L,62809L,62810L,62811L,62812L,62813L,62814L,\n62815L,62816L,62817L,62818L,62819L,62820L,62821L,62822L,62823L,62824L,\n62825L,62826L,62827L,62828L,62829L,62830L,62831L,62832L,62833L,62834L,\n62835L,62836L,62837L,62838L,62839L,62840L,62841L,62842L,62843L,62844L,\n62845L,62846L,62847L,62848L,62849L,62850L,62851L,62852L,62853L,62854L,\n62855L,62856L,62857L,62858L,62859L,62860L,62861L,62862L,62863L,62864L,\n62865L,62866L,62867L,62868L,62869L,62870L,62871L,62872L,62873L,62874L,\n62875L,62876L,62877L,62878L,62879L,62880L,62881L,62882L,62883L,62884L,\n62885L,62886L,62887L,62888L,62889L,62890L,62891L,62892L,62893L,62894L,\n62895L,62896L,62897L,62898L,62899L,62900L,62901L,62902L,62903L,62904L,\n62905L,62906L,62907L,62908L,62909L,62910L,62911L,62912L,62913L,62914L,\n62915L,62916L,62917L,62918L,62919L,62920L,62921L,62922L,62923L,62924L,\n62925L,62926L,62927L,62928L,62929L,62930L,62931L,62932L,62933L,62934L,\n62935L,62936L,62937L,62938L,62939L,62940L,62941L,62942L,62943L,62944L,\n62945L,62946L,62947L,62948L,62949L,62950L,62951L,62952L,62953L,62954L,\n62955L,62956L,62957L,62958L,62959L,62960L,62961L,62962L,62963L,62964L,\n62965L,62966L,62967L,62968L,62969L,62970L,62971L,62972L,62973L,62974L,\n62975L,62976L,62977L,62978L,62979L,62980L,62981L,62982L,62983L,62984L,\n62985L,62986L,62987L,62988L,62989L,62990L,62991L,62992L,62993L,62994L,\n62995L,62996L,62997L,62998L,62999L,63000L,63001L,63002L,63003L,63004L,\n63005L,63006L,63007L,63008L,63009L,63010L,63011L,63012L,63013L,63014L,\n63015L,63016L,63017L,63018L,63019L,63020L,63021L,63022L,63023L,63024L,\n63025L,63026L,63027L,63028L,63029L,63030L,63031L,63032L,63033L,63034L,\n63035L,63036L,63037L,63038L,63039L,63040L,63041L,63042L,63043L,63044L,\n63045L,63046L,63047L,63048L,63049L,63050L,63051L,63052L,63053L,63054L,\n63055L,63056L,63057L,63058L,63059L,63060L,63061L,63062L,63063L,63064L,\n63065L,63066L,63067L,63068L,63069L,63070L,63071L,63072L,63073L,63074L,\n63075L,63076L,63077L,63078L,63079L,63080L,63081L,63082L,63083L,63084L,\n63085L,63086L,63087L,63088L,63089L,63090L,63091L,63092L,63093L,63094L,\n63095L,63096L,63097L,63098L,63099L,63100L,63101L,63102L,63103L,63104L,\n63105L,63106L,63107L,63108L,63109L,63110L,63111L,63112L,63113L,63114L,\n63115L,63116L,63117L,63118L,63119L,63120L,63121L,63122L,63123L,63124L,\n63125L,63126L,63127L,63128L,63129L,63130L,63131L,63132L,63133L,63134L,\n63135L,63136L,63137L,63138L,63139L,63140L,63141L,63142L,63143L,63144L,\n63145L,63146L,63147L,63148L,63149L,63150L,63151L,63152L,63153L,63154L,\n63155L,63156L,63157L,63158L,63159L,63160L,63161L,63162L,63163L,63164L,\n63165L,63166L,63167L,63168L,63169L,63170L,63171L,63172L,63173L,63174L,\n63175L,63176L,63177L,63178L,63179L,63180L,63181L,63182L,63183L,63184L,\n63185L,63186L,63187L,63188L,63189L,63190L,63191L,63192L,63193L,63194L,\n63195L,63196L,63197L,63198L,63199L,63200L,63201L,63202L,63203L,63204L,\n63205L,63206L,63207L,63208L,63209L,63210L,63211L,63212L,63213L,63214L,\n63215L,63216L,63217L,63218L,63219L,63220L,63221L,63222L,63223L,63224L,\n63225L,63226L,63227L,63228L,63229L,63230L,63231L,63232L,63233L,63234L,\n63235L,63236L,63237L,63238L,63239L,63240L,63241L,63242L,63243L,63244L,\n63245L,63246L,63247L,63248L,63249L,63250L,63251L,63252L,63253L,63254L,\n63255L,63256L,63257L,63258L,63259L,63260L,63261L,63262L,63263L,63264L,\n63265L,63266L,63267L,63268L,63269L,63270L,63271L,63272L,63273L,63274L,\n63275L,63276L,63277L,63278L,63279L,63280L,63281L,63282L,63283L,63284L,\n63285L,63286L,63287L,63288L,63289L,63290L,63291L,63292L,63293L,63294L,\n63295L,63296L,63297L,63298L,63299L,63300L,63301L,63302L,63303L,63304L,\n63305L,63306L,63307L,63308L,63309L,63310L,63311L,63312L,63313L,63314L,\n63315L,63316L,63317L,63318L,63319L,63320L,63321L,63322L,63323L,63324L,\n63325L,63326L,63327L,63328L,63329L,63330L,63331L,63332L,63333L,63334L,\n63335L,63336L,63337L,63338L,63339L,63340L,63341L,63342L,63343L,63344L,\n63345L,63346L,63347L,63348L,63349L,63350L,63351L,63352L,63353L,63354L,\n63355L,63356L,63357L,63358L,63359L,63360L,63361L,63362L,63363L,63364L,\n63365L,63366L,63367L,63368L,63369L,63370L,63371L,63372L,63373L,63374L,\n63375L,63376L,63377L,63378L,63379L,63380L,63381L,63382L,63383L,63384L,\n63385L,63386L,63387L,63388L,63389L,63390L,63391L,63392L,63393L,63394L,\n63395L,63396L,63397L,63398L,63399L,63400L,63401L,63402L,63403L,63404L,\n63405L,63406L,63407L,63408L,63409L,63410L,63411L,63412L,63413L,63414L,\n63415L,63416L,63417L,63418L,63419L,63420L,63421L,63422L,63423L,63424L,\n63425L,63426L,63427L,63428L,63429L,63430L,63431L,63432L,63433L,63434L,\n63435L,63436L,63437L,63438L,63439L,63440L,63441L,63442L,63443L,63444L,\n63445L,63446L,63447L,63448L,63449L,63450L,63451L,63452L,63453L,63454L,\n63455L,63456L,63457L,63458L,63459L,63460L,63461L,63462L,63463L,63464L,\n63465L,63466L,63467L,63468L,63469L,63470L,63471L,63472L,63473L,63474L,\n63475L,63476L,63477L,63478L,63479L,63480L,63481L,63482L,63483L,63484L,\n63485L,63486L,63487L,63488L,63489L,63490L,63491L,63492L,63493L,63494L,\n63495L,63496L,63497L,63498L,63499L,63500L,63501L,63502L,63503L,63504L,\n63505L,63506L,63507L,63508L,63509L,63510L,63511L,63512L,63513L,63514L,\n63515L,63516L,63517L,63518L,63519L,63520L,63521L,63522L,63523L,63524L,\n63525L,63526L,63527L,63528L,63529L,63530L,63531L,63532L,63533L,63534L,\n63535L,63536L,63537L,63538L,63539L,63540L,63541L,63542L,63543L,63544L,\n63545L,63546L,63547L,63548L,63549L,63550L,63551L,63552L,63553L,63554L,\n63555L,63556L,63557L,63558L,63559L,63560L,63561L,63562L,63563L,63564L,\n63565L,63566L,63567L,63568L,63569L,63570L,63571L,63572L,63573L,63574L,\n63575L,63576L,63577L,63578L,63579L,63580L,63581L,63582L,63583L,63584L,\n63585L,63586L,63587L,63588L,63589L,63590L,63591L,63592L,63593L,63594L,\n63595L,63596L,63597L,63598L,63599L,63600L,63601L,63602L,63603L,63604L,\n63605L,63606L,63607L,63608L,63609L,63610L,63611L,63612L,63613L,63614L,\n63615L,63616L,63617L,63618L,63619L,63620L,63621L,63622L,63623L,63624L,\n63625L,63626L,63627L,63628L,63629L,63630L,63631L,63632L,63633L,63634L,\n63635L,63636L,63637L,63638L,63639L,63640L,63641L,63642L,63643L,63644L,\n63645L,63646L,63647L,63648L,63649L,63650L,63651L,63652L,63653L,63654L,\n63655L,63656L,63657L,63658L,63659L,63660L,63661L,63662L,63663L,63664L,\n63665L,63666L,63667L,63668L,63669L,63670L,63671L,63672L,63673L,63674L,\n63675L,63676L,63677L,63678L,63679L,63680L,63681L,63682L,63683L,63684L,\n63685L,63686L,63687L,63688L,63689L,63690L,63691L,63692L,63693L,63694L,\n63695L,63696L,63697L,63698L,63699L,63700L,63701L,63702L,63703L,63704L,\n63705L,63706L,63707L,63708L,63709L,63710L,63711L,63712L,63713L,63714L,\n63715L,63716L,63717L,63718L,63719L,63720L,63721L,63722L,63723L,63724L,\n63725L,63726L,63727L,63728L,63729L,63730L,63731L,63732L,63733L,63734L,\n63735L,63736L,63737L,63738L,63739L,63740L,63741L,63742L,63743L,63744L,\n63745L,63746L,63747L,63748L,63749L,63750L,63751L,63752L,63753L,63754L,\n63755L,63756L,63757L,63758L,63759L,63760L,63761L,63762L,63763L,63764L,\n63765L,63766L,63767L,63768L,63769L,63770L,63771L,63772L,63773L,63774L,\n63775L,63776L,63777L,63778L,63779L,63780L,63781L,63782L,63783L,63784L,\n63785L,63786L,63787L,63788L,63789L,63790L,63791L,63792L,63793L,63794L,\n63795L,63796L,63797L,63798L,63799L,63800L,63801L,63802L,63803L,63804L,\n63805L,63806L,63807L,63808L,63809L,63810L,63811L,63812L,63813L,63814L,\n63815L,63816L,63817L,63818L,63819L,63820L,63821L,63822L,63823L,63824L,\n63825L,63826L,63827L,63828L,63829L,63830L,63831L,63832L,63833L,63834L,\n63835L,63836L,63837L,63838L,63839L,63840L,63841L,63842L,63843L,63844L,\n63845L,63846L,63847L,63848L,63849L,63850L,63851L,63852L,63853L,63854L,\n63855L,63856L,63857L,63858L,63859L,63860L,63861L,63862L,63863L,63864L,\n63865L,63866L,63867L,63868L,63869L,63870L,63871L,63872L,63873L,63874L,\n63875L,63876L,63877L,63878L,63879L,63880L,63881L,63882L,63883L,63884L,\n63885L,63886L,63887L,63888L,63889L,63890L,63891L,63892L,63893L,63894L,\n63895L,63896L,63897L,63898L,63899L,63900L,63901L,63902L,63903L,63904L,\n63905L,63906L,63907L,63908L,63909L,63910L,63911L,63912L,63913L,63914L,\n63915L,63916L,63917L,63918L,63919L,63920L,63921L,63922L,63923L,63924L,\n63925L,63926L,63927L,63928L,63929L,63930L,63931L,63932L,63933L,63934L,\n63935L,63936L,63937L,63938L,63939L,63940L,63941L,63942L,63943L,63944L,\n63945L,63946L,63947L,63948L,63949L,63950L,63951L,63952L,63953L,63954L,\n63955L,63956L,63957L,63958L,63959L,63960L,63961L,63962L,63963L,63964L,\n63965L,63966L,63967L,63968L,63969L,63970L,63971L,63972L,63973L,63974L,\n63975L,63976L,63977L,63978L,63979L,63980L,63981L,63982L,63983L,63984L,\n63985L,63986L,63987L,63988L,63989L,63990L,63991L,63992L,63993L,63994L,\n63995L,63996L,63997L,63998L,63999L,64000L,64001L,64002L,64003L,64004L,\n64005L,64006L,64007L,64008L,64009L,64010L,64011L,64012L,64013L,64014L,\n64015L,64016L,64017L,64018L,64019L,64020L,64021L,64022L,64023L,64024L,\n64025L,64026L,64027L,64028L,64029L,64030L,64031L,64032L,64033L,64034L,\n64035L,64036L,64037L,64038L,64039L,64040L,64041L,64042L,64043L,64044L,\n64045L,64046L,64047L,64048L,64049L,64050L,64051L,64052L,64053L,64054L,\n64055L,64056L,64057L,64058L,64059L,64060L,64061L,64062L,64063L,64064L,\n64065L,64066L,64067L,64068L,64069L,64070L,64071L,64072L,64073L,64074L,\n64075L,64076L,64077L,64078L,64079L,64080L,64081L,64082L,64083L,64084L,\n64085L,64086L,64087L,64088L,64089L,64090L,64091L,64092L,64093L,64094L,\n64095L,64096L,64097L,64098L,64099L,64100L,64101L,64102L,64103L,64104L,\n64105L,64106L,64107L,64108L,64109L,64110L,64111L,64112L,64113L,64114L,\n64115L,64116L,64117L,64118L,64119L,64120L,64121L,64122L,64123L,64124L,\n64125L,64126L,64127L,64128L,64129L,64130L,64131L,64132L,64133L,64134L,\n64135L,64136L,64137L,64138L,64139L,64140L,64141L,64142L,64143L,64144L,\n64145L,64146L,64147L,64148L,64149L,64150L,64151L,64152L,64153L,64154L,\n64155L,64156L,64157L,64158L,64159L,64160L,64161L,64162L,64163L,64164L,\n64165L,64166L,64167L,64168L,64169L,64170L,64171L,64172L,64173L,64174L,\n64175L,64176L,64177L,64178L,64179L,64180L,64181L,64182L,64183L,64184L,\n64185L,64186L,64187L,64188L,64189L,64190L,64191L,64192L,64193L,64194L,\n64195L,64196L,64197L,64198L,64199L,64200L,64201L,64202L,64203L,64204L,\n64205L,64206L,64207L,64208L,64209L,64210L,64211L,64212L,64213L,64214L,\n64215L,64216L,64217L,64218L,64219L,64220L,64221L,64222L,64223L,64224L,\n64225L,64226L,64227L,64228L,64229L,64230L,64231L,64232L,64233L,64234L,\n64235L,64236L,64237L,64238L,64239L,64240L,64241L,64242L,64243L,64244L,\n64245L,64246L,64247L,64248L,64249L,64250L,64251L,64252L,64253L,64254L,\n64255L,64256L,64257L,64258L,64259L,64260L,64261L,64262L,64263L,64264L,\n64265L,64266L,64267L,64268L,64269L,64270L,64271L,64272L,64273L,64274L,\n64275L,64276L,64277L,64278L,64279L,64280L,64281L,64282L,64283L,64284L,\n64285L,64286L,64287L,64288L,64289L,64290L,64291L,64292L,64293L,64294L,\n64295L,64296L,64297L,64298L,64299L,64300L,64301L,64302L,64303L,64304L,\n64305L,64306L,64307L,64308L,64309L,64310L,64311L,64312L,64313L,64314L,\n64315L,64316L,64317L,64318L,64319L,64320L,64321L,64322L,64323L,64324L,\n64325L,64326L,64327L,64328L,64329L,64330L,64331L,64332L,64333L,64334L,\n64335L,64336L,64337L,64338L,64339L,64340L,64341L,64342L,64343L,64344L,\n64345L,64346L,64347L,64348L,64349L,64350L,64351L,64352L,64353L,64354L,\n64355L,64356L,64357L,64358L,64359L,64360L,64361L,64362L,64363L,64364L,\n64365L,64366L,64367L,64368L,64369L,64370L,64371L,64372L,64373L,64374L,\n64375L,64376L,64377L,64378L,64379L,64380L,64381L,64382L,64383L,64384L,\n64385L,64386L,64387L,64388L,64389L,64390L,64391L,64392L,64393L,64394L,\n64395L,64396L,64397L,64398L,64399L,64400L,64401L,64402L,64403L,64404L,\n64405L,64406L,64407L,64408L,64409L,64410L,64411L,64412L,64413L,64414L,\n64415L,64416L,64417L,64418L,64419L,64420L,64421L,64422L,64423L,64424L,\n64425L,64426L,64427L,64428L,64429L,64430L,64431L,64432L,64433L,64434L,\n64435L,64436L,64437L,64438L,64439L,64440L,64441L,64442L,64443L,64444L,\n64445L,64446L,64447L,64448L,64449L,64450L,64451L,64452L,64453L,64454L,\n64455L,64456L,64457L,64458L,64459L,64460L,64461L,64462L,64463L,64464L,\n64465L,64466L,64467L,64468L,64469L,64470L,64471L,64472L,64473L,64474L,\n64475L,64476L,64477L,64478L,64479L,64480L,64481L,64482L,64483L,64484L,\n64485L,64486L,64487L,64488L,64489L,64490L,64491L,64492L,64493L,64494L,\n64495L,64496L,64497L,64498L,64499L,64500L,64501L,64502L,64503L,64504L,\n64505L,64506L,64507L,64508L,64509L,64510L,64511L,64512L,64513L,64514L,\n64515L,64516L,64517L,64518L,64519L,64520L,64521L,64522L,64523L,64524L,\n64525L,64526L,64527L,64528L,64529L,64530L,64531L,64532L,64533L,64534L,\n64535L,64536L,64537L,64538L,64539L,64540L,64541L,64542L,64543L,64544L,\n64545L,64546L,64547L,64548L,64549L,64550L,64551L,64552L,64553L,64554L,\n64555L,64556L,64557L,64558L,64559L,64560L,64561L,64562L,64563L,64564L,\n64565L,64566L,64567L,64568L,64569L,64570L,64571L,64572L,64573L,64574L,\n64575L,64576L,64577L,64578L,64579L,64580L,64581L,64582L,64583L,64584L,\n64585L,64586L,64587L,64588L,64589L,64590L,64591L,64592L,64593L,64594L,\n64595L,64596L,64597L,64598L,64599L,64600L,64601L,64602L,64603L,64604L,\n64605L,64606L,64607L,64608L,64609L,64610L,64611L,64612L,64613L,64614L,\n64615L,64616L,64617L,64618L,64619L,64620L,64621L,64622L,64623L,64624L,\n64625L,64626L,64627L,64628L,64629L,64630L,64631L,64632L,64633L,64634L,\n64635L,64636L,64637L,64638L,64639L,64640L,64641L,64642L,64643L,64644L,\n64645L,64646L,64647L,64648L,64649L,64650L,64651L,64652L,64653L,64654L,\n64655L,64656L,64657L,64658L,64659L,64660L,64661L,64662L,64663L,64664L,\n64665L,64666L,64667L,64668L,64669L,64670L,64671L,64672L,64673L,64674L,\n64675L,64676L,64677L,64678L,64679L,64680L,64681L,64682L,64683L,64684L,\n64685L,64686L,64687L,64688L,64689L,64690L,64691L,64692L,64693L,64694L,\n64695L,64696L,64697L,64698L,64699L,64700L,64701L,64702L,64703L,64704L,\n64705L,64706L,64707L,64708L,64709L,64710L,64711L,64712L,64713L,64714L,\n64715L,64716L,64717L,64718L,64719L,64720L,64721L,64722L,64723L,64724L,\n64725L,64726L,64727L,64728L,64729L,64730L,64731L,64732L,64733L,64734L,\n64735L,64736L,64737L,64738L,64739L,64740L,64741L,64742L,64743L,64744L,\n64745L,64746L,64747L,64748L,64749L,64750L,64751L,64752L,64753L,64754L,\n64755L,64756L,64757L,64758L,64759L,64760L,64761L,64762L,64763L,64764L,\n64765L,64766L,64767L,64768L,64769L,64770L,64771L,64772L,64773L,64774L,\n64775L,64776L,64777L,64778L,64779L,64780L,64781L,64782L,64783L,64784L,\n64785L,64786L,64787L,64788L,64789L,64790L,64791L,64792L,64793L,64794L,\n64795L,64796L,64797L,64798L,64799L,64800L,64801L,64802L,64803L,64804L,\n64805L,64806L,64807L,64808L,64809L,64810L,64811L,64812L,64813L,64814L,\n64815L,64816L,64817L,64818L,64819L,64820L,64821L,64822L,64823L,64824L,\n64825L,64826L,64827L,64828L,64829L,64830L,64831L,64832L,64833L,64834L,\n64835L,64836L,64837L,64838L,64839L,64840L,64841L,64842L,64843L,64844L,\n64845L,64846L,64847L,64848L,64849L,64850L,64851L,64852L,64853L,64854L,\n64855L,64856L,64857L,64858L,64859L,64860L,64861L,64862L,64863L,64864L,\n64865L,64866L,64867L,64868L,64869L,64870L,64871L,64872L,64873L,64874L,\n64875L,64876L,64877L,64878L,64879L,64880L,64881L,64882L,64883L,64884L,\n64885L,64886L,64887L,64888L,64889L,64890L,64891L,64892L,64893L,64894L,\n64895L,64896L,64897L,64898L,64899L,64900L,64901L,64902L,64903L,64904L,\n64905L,64906L,64907L,64908L,64909L,64910L,64911L,64912L,64913L,64914L,\n64915L,64916L,64917L,64918L,64919L,64920L,64921L,64922L,64923L,64924L,\n64925L,64926L,64927L,64928L,64929L,64930L,64931L,64932L,64933L,64934L,\n64935L,64936L,64937L,64938L,64939L,64940L,64941L,64942L,64943L,64944L,\n64945L,64946L,64947L,64948L,64949L,64950L,64951L,64952L,64953L,64954L,\n64955L,64956L,64957L,64958L,64959L,64960L,64961L,64962L,64963L,64964L,\n64965L,64966L,64967L,64968L,64969L,64970L,64971L,64972L,64973L,64974L,\n64975L,64976L,64977L,64978L,64979L,64980L,64981L,64982L,64983L,64984L,\n64985L,64986L,64987L,64988L,64989L,64990L,64991L,64992L,64993L,64994L,\n64995L,64996L,64997L,64998L,64999L,65000L,65001L,65002L,65003L,65004L,\n65005L,65006L,65007L,65008L,65009L,65010L,65011L,65012L,65013L,65014L,\n65015L,65016L,65017L,65018L,65019L,65020L,65021L,65022L,65023L,65024L,\n65025L,65026L,65027L,65028L,65029L,65030L,65031L,65032L,65033L,65034L,\n65035L,65036L,65037L,65038L,65039L,65040L,65041L,65042L,65043L,65044L,\n65045L,65046L,65047L,65048L,65049L,65050L,65051L,65052L,65053L,65054L,\n65055L,65056L,65057L,65058L,65059L,65060L,65061L,65062L,65063L,65064L,\n65065L,65066L,65067L,65068L,65069L,65070L,65071L,65072L,65073L,65074L,\n65075L,65076L,65077L,65078L,65079L,65080L,65081L,65082L,65083L,65084L,\n65085L,65086L,65087L,65088L,65089L,65090L,65091L,65092L,65093L,65094L,\n65095L,65096L,65097L,65098L,65099L,65100L,65101L,65102L,65103L,65104L,\n65105L,65106L,65107L,65108L,65109L,65110L,65111L,65112L,65113L,65114L,\n65115L,65116L,65117L,65118L,65119L,65120L,65121L,65122L,65123L,65124L,\n65125L,65126L,65127L,65128L,65129L,65130L,65131L,65132L,65133L,65134L,\n65135L,65136L,65137L,65138L,65139L,65140L,65141L,65142L,65143L,65144L,\n65145L,65146L,65147L,65148L,65149L,65150L,65151L,65152L,65153L,65154L,\n65155L,65156L,65157L,65158L,65159L,65160L,65161L,65162L,65163L,65164L,\n65165L,65166L,65167L,65168L,65169L,65170L,65171L,65172L,65173L,65174L,\n65175L,65176L,65177L,65178L,65179L,65180L,65181L,65182L,65183L,65184L,\n65185L,65186L,65187L,65188L,65189L,65190L,65191L,65192L,65193L,65194L,\n65195L,65196L,65197L,65198L,65199L,65200L,65201L,65202L,65203L,65204L,\n65205L,65206L,65207L,65208L,65209L,65210L,65211L,65212L,65213L,65214L,\n65215L,65216L,65217L,65218L,65219L,65220L,65221L,65222L,65223L,65224L,\n65225L,65226L,65227L,65228L,65229L,65230L,65231L,65232L,65233L,65234L,\n65235L,65236L,65237L,65238L,65239L,65240L,65241L,65242L,65243L,65244L,\n65245L,65246L,65247L,65248L,65249L,65250L,65251L,65252L,65253L,65254L,\n65255L,65256L,65257L,65258L,65259L,65260L,65261L,65262L,65263L,65264L,\n65265L,65266L,65267L,65268L,65269L,65270L,65271L,65272L,65273L,65274L,\n65275L,65276L,65277L,65278L,65279L,65280L,65281L,65282L,65283L,65284L,\n65285L,65286L,65287L,65288L,65289L,65290L,65291L,65292L,65293L,65294L,\n65295L,65296L,65297L,65298L,65299L,65300L,65301L,65302L,65303L,65304L,\n65305L,65306L,65307L,65308L,65309L,65310L,65311L,65312L,65313L,65314L,\n65315L,65316L,65317L,65318L,65319L,65320L,65321L,65322L,65323L,65324L,\n65325L,65326L,65327L,65328L,65329L,65330L,65331L,65332L,65333L,65334L,\n65335L,65336L,65337L,65338L,65339L,65340L,65341L,65342L,65343L,65344L,\n65313L,65314L,65315L,65316L,65317L,65318L,65319L,65320L,65321L,65322L,\n65323L,65324L,65325L,65326L,65327L,65328L,65329L,65330L,65331L,65332L,\n65333L,65334L,65335L,65336L,65337L,65338L,65371L,65372L,65373L,65374L,\n65375L,65376L,65377L,65378L,65379L,65380L,65381L,65382L,65383L,65384L,\n65385L,65386L,65387L,65388L,65389L,65390L,65391L,65392L,65393L,65394L,\n65395L,65396L,65397L,65398L,65399L,65400L,65401L,65402L,65403L,65404L,\n65405L,65406L,65407L,65408L,65409L,65410L,65411L,65412L,65413L,65414L,\n65415L,65416L,65417L,65418L,65419L,65420L,65421L,65422L,65423L,65424L,\n65425L,65426L,65427L,65428L,65429L,65430L,65431L,65432L,65433L,65434L,\n65435L,65436L,65437L,65438L,65439L,65440L,65441L,65442L,65443L,65444L,\n65445L,65446L,65447L,65448L,65449L,65450L,65451L,65452L,65453L,65454L,\n65455L,65456L,65457L,65458L,65459L,65460L,65461L,65462L,65463L,65464L,\n65465L,65466L,65467L,65468L,65469L,65470L,65471L,65472L,65473L,65474L,\n65475L,65476L,65477L,65478L,65479L,65480L,65481L,65482L,65483L,65484L,\n65485L,65486L,65487L,65488L,65489L,65490L,65491L,65492L,65493L,65494L,\n65495L,65496L,65497L,65498L,65499L,65500L,65501L,65502L,65503L,65504L,\n65505L,65506L,65507L,65508L,65509L,65510L,65511L,65512L,65513L,65514L,\n65515L,65516L,65517L,65518L,65519L,65520L,65521L,65522L,65523L,65524L,\n65525L,65526L,65527L,65528L,65529L,65530L,65531L,65532L,65533L,65534L,\n65535L,\n};\n#endif\n\n#if defined(DUK_USE_REGEXP_CANON_BITMAP)\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_re_canon_bitmap[256] = {\n23,0,224,19,1,228,255,255,255,255,255,255,255,255,255,255,63,254,255,127,\n255,255,255,255,255,255,255,255,231,231,0,16,255,227,255,255,63,255,255,\n255,255,255,255,255,1,252,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n227,129,255,255,255,147,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,251,\n};\n#endif\n#line 1 \"duk_util_bitdecoder.c\"\n/*\n *  Bitstream decoder.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Decode 'bits' bits from the input stream (bits must be 1...24).\n * When reading past bitstream end, zeroes are shifted in.  The result\n * is signed to match duk_bd_decode_flagged.\n */\nDUK_INTERNAL duk_uint32_t duk_bd_decode(duk_bitdecoder_ctx *ctx, duk_small_int_t bits) {\n\tduk_small_int_t shift;\n\tduk_uint32_t mask;\n\tduk_uint32_t tmp;\n\n\t/* Note: cannot read more than 24 bits without possibly shifting top bits out.\n\t * Fixable, but adds complexity.\n\t */\n\tDUK_ASSERT(bits >= 1 && bits <= 24);\n\n\twhile (ctx->currbits < bits) {\n#if 0\n\t\tDUK_DDD(DUK_DDDPRINT(\"decode_bits: shift more data (bits=%ld, currbits=%ld)\",\n\t\t                     (long) bits, (long) ctx->currbits));\n#endif\n\t\tctx->currval <<= 8;\n\t\tif (ctx->offset < ctx->length) {\n\t\t\t/* If ctx->offset >= ctx->length, we \"shift zeroes in\"\n\t\t\t * instead of croaking.\n\t\t\t */\n\t\t\tctx->currval |= ctx->data[ctx->offset++];\n\t\t}\n\t\tctx->currbits += 8;\n\t}\n#if 0\n\tDUK_DDD(DUK_DDDPRINT(\"decode_bits: bits=%ld, currbits=%ld, currval=0x%08lx\",\n\t                     (long) bits, (long) ctx->currbits, (unsigned long) ctx->currval));\n#endif\n\n\t/* Extract 'top' bits of currval; note that the extracted bits do not need\n\t * to be cleared, we just ignore them on next round.\n\t */\n\tshift = ctx->currbits - bits;\n\tmask = (((duk_uint32_t) 1U) << bits) - 1U;\n\ttmp = (ctx->currval >> shift) & mask;\n\tctx->currbits = shift;  /* remaining */\n\n#if 0\n\tDUK_DDD(DUK_DDDPRINT(\"decode_bits: %ld bits -> 0x%08lx (%ld), currbits=%ld, currval=0x%08lx\",\n\t                     (long) bits, (unsigned long) tmp, (long) tmp, (long) ctx->currbits, (unsigned long) ctx->currval));\n#endif\n\n\treturn tmp;\n}\n\nDUK_INTERNAL duk_small_uint_t duk_bd_decode_flag(duk_bitdecoder_ctx *ctx) {\n\treturn (duk_small_uint_t) duk_bd_decode(ctx, 1);\n}\n\n/* Decode a one-bit flag, and if set, decode a value of 'bits', otherwise return\n * default value.\n */\nDUK_INTERNAL duk_uint32_t duk_bd_decode_flagged(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_uint32_t def_value) {\n\tif (duk_bd_decode_flag(ctx)) {\n\t\treturn duk_bd_decode(ctx, bits);\n\t} else {\n\t\treturn def_value;\n\t}\n}\n\n/* Signed variant, allows negative marker value. */\nDUK_INTERNAL duk_int32_t duk_bd_decode_flagged_signed(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_int32_t def_value) {\n\treturn (duk_int32_t) duk_bd_decode_flagged(ctx, bits, (duk_uint32_t) def_value);\n}\n\n/* Shared varint encoding.  Match dukutil.py BitEncode.varuint(). */\nDUK_INTERNAL duk_uint32_t duk_bd_decode_varuint(duk_bitdecoder_ctx *ctx) {\n\tduk_small_uint_t t;\n\n\t/* The bit encoding choices here are based on manual testing against\n\t * the actual varuints generated by genbuiltins.py.\n\t */\n\tswitch (duk_bd_decode(ctx, 2)) {\n\tcase 0:\n\t\treturn 0;  /* [0,0] */\n\tcase 1:\n\t\treturn duk_bd_decode(ctx, 2) + 1;  /* [1,4] */\n\tcase 2:\n\t\treturn duk_bd_decode(ctx, 5) + 5;  /* [5,36] */\n\tdefault:\n\t\tt = duk_bd_decode(ctx, 7);\n\t\tif (t == 0) {\n\t\t\treturn duk_bd_decode(ctx, 20);\n\t\t}\n\t\treturn (t - 1) + 37;  /* [37,163] */\n\t}\n}\n\n/* Decode a bit packed string from a custom format used by genbuiltins.py.\n * This function is here because it's used for both heap and thread inits.\n * Caller must supply the output buffer whose size is NOT checked!\n */\n\n#define DUK__BITPACK_LETTER_LIMIT  26\n#define DUK__BITPACK_LOOKUP1       26\n#define DUK__BITPACK_LOOKUP2       27\n#define DUK__BITPACK_SWITCH1       28\n#define DUK__BITPACK_SWITCH        29\n#define DUK__BITPACK_UNUSED1       30\n#define DUK__BITPACK_EIGHTBIT      31\n\nDUK_LOCAL const duk_uint8_t duk__bitpacked_lookup[16] = {\n\tDUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3,\n\tDUK_ASC_4, DUK_ASC_5, DUK_ASC_6, DUK_ASC_7,\n\tDUK_ASC_8, DUK_ASC_9, DUK_ASC_UNDERSCORE, DUK_ASC_SPACE,\n\t0x82, 0x80, DUK_ASC_DOUBLEQUOTE, DUK_ASC_LCURLY\n};\n\nDUK_INTERNAL duk_small_uint_t duk_bd_decode_bitpacked_string(duk_bitdecoder_ctx *bd, duk_uint8_t *out) {\n\tduk_small_uint_t len;\n\tduk_small_uint_t mode;\n\tduk_small_uint_t t;\n\tduk_small_uint_t i;\n\n\tlen = duk_bd_decode(bd, 5);\n\tif (len == 31) {\n\t\tlen = duk_bd_decode(bd, 8);  /* Support up to 256 bytes; rare. */\n\t}\n\n\tmode = 32;  /* 0 = uppercase, 32 = lowercase (= 'a' - 'A') */\n\tfor (i = 0; i < len; i++) {\n\t\tt = duk_bd_decode(bd, 5);\n\t\tif (t < DUK__BITPACK_LETTER_LIMIT) {\n\t\t\tt = t + DUK_ASC_UC_A + mode;\n\t\t} else if (t == DUK__BITPACK_LOOKUP1) {\n\t\t\tt = duk__bitpacked_lookup[duk_bd_decode(bd, 3)];\n\t\t} else if (t == DUK__BITPACK_LOOKUP2) {\n\t\t\tt = duk__bitpacked_lookup[8 + duk_bd_decode(bd, 3)];\n\t\t} else if (t == DUK__BITPACK_SWITCH1) {\n\t\t\tt = duk_bd_decode(bd, 5);\n\t\t\tDUK_ASSERT_DISABLE(t >= 0);  /* unsigned */\n\t\t\tDUK_ASSERT(t <= 25);\n\t\t\tt = t + DUK_ASC_UC_A + (mode ^ 32);\n\t\t} else if (t == DUK__BITPACK_SWITCH) {\n\t\t\tmode = mode ^ 32;\n\t\t\tt = duk_bd_decode(bd, 5);\n\t\t\tDUK_ASSERT_DISABLE(t >= 0);\n\t\t\tDUK_ASSERT(t <= 25);\n\t\t\tt = t + DUK_ASC_UC_A + mode;\n\t\t} else if (t == DUK__BITPACK_EIGHTBIT) {\n\t\t\tt = duk_bd_decode(bd, 8);\n\t\t}\n\t\tout[i] = (duk_uint8_t) t;\n\t}\n\n\treturn len;\n}\n\n/* automatic undefs */\n#undef DUK__BITPACK_EIGHTBIT\n#undef DUK__BITPACK_LETTER_LIMIT\n#undef DUK__BITPACK_LOOKUP1\n#undef DUK__BITPACK_LOOKUP2\n#undef DUK__BITPACK_SWITCH\n#undef DUK__BITPACK_SWITCH1\n#undef DUK__BITPACK_UNUSED1\n#line 1 \"duk_util_bitencoder.c\"\n/*\n *  Bitstream encoder.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL void duk_be_encode(duk_bitencoder_ctx *ctx, duk_uint32_t data, duk_small_int_t bits) {\n\tduk_uint8_t tmp;\n\n\tDUK_ASSERT(ctx != NULL);\n\tDUK_ASSERT(ctx->currbits < 8);\n\n\t/* This limitation would be fixable but adds unnecessary complexity. */\n\tDUK_ASSERT(bits >= 1 && bits <= 24);\n\n\tctx->currval = (ctx->currval << bits) | data;\n\tctx->currbits += bits;\n\n\twhile (ctx->currbits >= 8) {\n\t\tif (ctx->offset < ctx->length) {\n\t\t\ttmp = (duk_uint8_t) ((ctx->currval >> (ctx->currbits - 8)) & 0xff);\n\t\t\tctx->data[ctx->offset++] = tmp;\n\t\t} else {\n\t\t\t/* If buffer has been exhausted, truncate bitstream */\n\t\t\tctx->truncated = 1;\n\t\t}\n\n\t\tctx->currbits -= 8;\n\t}\n}\n\nDUK_INTERNAL void duk_be_finish(duk_bitencoder_ctx *ctx) {\n\tduk_small_int_t npad;\n\n\tDUK_ASSERT(ctx != NULL);\n\tDUK_ASSERT(ctx->currbits < 8);\n\n\tnpad = (duk_small_int_t) (8 - ctx->currbits);\n\tif (npad > 0) {\n\t\tduk_be_encode(ctx, 0, npad);\n\t}\n\tDUK_ASSERT(ctx->currbits == 0);\n}\n#line 1 \"duk_util_bufwriter.c\"\n/*\n *  Fast buffer writer with slack management.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* XXX: Avoid duk_{memcmp,memmove}_unsafe() by imposing a minimum length of\n * >0 for the underlying dynamic buffer.\n */\n\n/*\n *  Macro support functions (use only macros in calling code)\n */\n\nDUK_LOCAL void duk__bw_update_ptrs(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t curr_offset, duk_size_t new_length) {\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_UNREF(thr);\n\n\t/* 'p' might be NULL when the underlying buffer is zero size.  If so,\n\t * the resulting pointers are not used unsafely.\n\t */\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, bw_ctx->buf);\n\tDUK_ASSERT(p != NULL || (DUK_HBUFFER_DYNAMIC_GET_SIZE(bw_ctx->buf) == 0 && curr_offset == 0 && new_length == 0));\n\tbw_ctx->p = p + curr_offset;\n\tbw_ctx->p_base = p;\n\tbw_ctx->p_limit = p + new_length;\n}\n\nDUK_INTERNAL void duk_bw_init(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_hbuffer_dynamic *h_buf) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_ASSERT(h_buf != NULL);\n\n\tbw_ctx->buf = h_buf;\n\tduk__bw_update_ptrs(thr, bw_ctx, 0, DUK_HBUFFER_DYNAMIC_GET_SIZE(h_buf));\n}\n\nDUK_INTERNAL void duk_bw_init_pushbuf(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t buf_size) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\n\t(void) duk_push_dynamic_buffer(thr, buf_size);\n\tbw_ctx->buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, -1);\n\tDUK_ASSERT(bw_ctx->buf != NULL);\n\tduk__bw_update_ptrs(thr, bw_ctx, 0, buf_size);\n}\n\n/* Resize target buffer for requested size.  Called by the macro only when the\n * fast path test (= there is space) fails.\n */\nDUK_INTERNAL duk_uint8_t *duk_bw_resize(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t sz) {\n\tduk_size_t curr_off;\n\tduk_size_t add_sz;\n\tduk_size_t new_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\n\t/* We could do this operation without caller updating bw_ctx->ptr,\n\t * but by writing it back here we can share code better.\n\t */\n\n\tcurr_off = (duk_size_t) (bw_ctx->p - bw_ctx->p_base);\n\tadd_sz = (curr_off >> DUK_BW_SLACK_SHIFT) + DUK_BW_SLACK_ADD;\n\tnew_sz = curr_off + sz + add_sz;\n\tif (DUK_UNLIKELY(new_sz < curr_off)) {\n\t\t/* overflow */\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_BUFFER_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n#if 0  /* for manual torture testing: tight allocation, useful with valgrind */\n\tnew_sz = curr_off + sz;\n#endif\n\n\t/* This is important to ensure dynamic buffer data pointer is not\n\t * NULL (which is possible if buffer size is zero), which in turn\n\t * causes portability issues with e.g. memmove() and memcpy().\n\t */\n\tDUK_ASSERT(new_sz >= 1);\n\n\tDUK_DD(DUK_DDPRINT(\"resize bufferwriter from %ld to %ld (add_sz=%ld)\", (long) curr_off, (long) new_sz, (long) add_sz));\n\n\tduk_hbuffer_resize(thr, bw_ctx->buf, new_sz);\n\tduk__bw_update_ptrs(thr, bw_ctx, curr_off, new_sz);\n\treturn bw_ctx->p;\n}\n\n/* Make buffer compact, matching current written size. */\nDUK_INTERNAL void duk_bw_compact(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx) {\n\tduk_size_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_UNREF(thr);\n\n\tlen = (duk_size_t) (bw_ctx->p - bw_ctx->p_base);\n\tduk_hbuffer_resize(thr, bw_ctx->buf, len);\n\tduk__bw_update_ptrs(thr, bw_ctx, len, len);\n}\n\nDUK_INTERNAL void duk_bw_write_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len) {\n\tduk_uint8_t *p_base;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tduk_memcpy_unsafe((void *) bw->p,\n\t                  (const void *) (p_base + src_off),\n\t                  (size_t) len);\n\tbw->p += len;\n}\n\nDUK_INTERNAL void duk_bw_write_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\tduk_bw_write_raw_slice(thr, bw, src_off, len);\n}\n\nDUK_INTERNAL void duk_bw_insert_raw_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len) {\n\tduk_uint8_t *p_base;\n\tduk_size_t buf_sz, move_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(buf != NULL);\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tbuf_sz = (duk_size_t) (bw->p - p_base);  /* constrained by maximum buffer size */\n\tmove_sz = buf_sz - dst_off;\n\n\tDUK_ASSERT(p_base != NULL);  /* buffer size is >= 1 */\n\tduk_memmove_unsafe((void *) (p_base + dst_off + len),\n\t                   (const void *) (p_base + dst_off),\n\t                   (size_t) move_sz);\n\tduk_memcpy_unsafe((void *) (p_base + dst_off),\n\t                  (const void *) buf,\n\t                  (size_t) len);\n\tbw->p += len;\n}\n\nDUK_INTERNAL void duk_bw_insert_ensure_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(buf != NULL);\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\tduk_bw_insert_raw_bytes(thr, bw, dst_off, buf, len);\n}\n\nDUK_INTERNAL void duk_bw_insert_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len) {\n\tduk_uint8_t *p_base;\n\tduk_size_t buf_sz, move_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\n\t/* Don't support \"straddled\" source now. */\n\tDUK_ASSERT(dst_off <= src_off || dst_off >= src_off + len);\n\n\tif (dst_off <= src_off) {\n\t\t/* Target is before source.  Source offset is expressed as\n\t\t * a \"before change\" offset.  Account for the memmove.\n\t\t */\n\t\tsrc_off += len;\n\t}\n\n\tbuf_sz = (duk_size_t) (bw->p - p_base);\n\tmove_sz = buf_sz - dst_off;\n\n\tDUK_ASSERT(p_base != NULL);  /* buffer size is >= 1 */\n\tduk_memmove_unsafe((void *) (p_base + dst_off + len),\n\t                   (const void *) (p_base + dst_off),\n\t                   (size_t) move_sz);\n\tduk_memcpy_unsafe((void *) (p_base + dst_off),\n\t                  (const void *) (p_base + src_off),\n\t                  (size_t) len);\n\tbw->p += len;\n}\n\nDUK_INTERNAL void duk_bw_insert_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\n\t/* Don't support \"straddled\" source now. */\n\tDUK_ASSERT(dst_off <= src_off || dst_off >= src_off + len);\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\tduk_bw_insert_raw_slice(thr, bw, dst_off, src_off, len);\n}\n\nDUK_INTERNAL duk_uint8_t *duk_bw_insert_raw_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len) {\n\tduk_uint8_t *p_base, *p_dst, *p_src;\n\tduk_size_t buf_sz, move_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tbuf_sz = (duk_size_t) (bw->p - p_base);\n\tmove_sz = buf_sz - off;\n\tp_dst = p_base + off + len;\n\tp_src = p_base + off;\n\tduk_memmove_unsafe((void *) p_dst, (const void *) p_src, (size_t) move_sz);\n\treturn p_src;  /* point to start of 'reserved area' */\n}\n\nDUK_INTERNAL duk_uint8_t *duk_bw_insert_ensure_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw));\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\treturn duk_bw_insert_raw_area(thr, bw, off, len);\n}\n\nDUK_INTERNAL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len) {\n\tduk_size_t move_sz;\n\n\tduk_uint8_t *p_base;\n\tduk_uint8_t *p_src;\n\tduk_uint8_t *p_dst;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(off + len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tp_dst = p_base + off;\n\tp_src = p_dst + len;\n\tmove_sz = (duk_size_t) (bw->p - p_src);\n\tduk_memmove_unsafe((void *) p_dst,\n\t                   (const void *) p_src,\n\t                   (size_t) move_sz);\n\tbw->p -= len;\n}\n\n/*\n *  Macro support functions for reading/writing raw data.\n *\n *  These are done using mempcy to ensure they're valid even for unaligned\n *  reads/writes on platforms where alignment counts.  On x86 at least gcc\n *  is able to compile these into a bswap+mov.  \"Always inline\" is used to\n *  ensure these macros compile to minimal code.\n *\n *  Not really bufwriter related, but currently used together.\n */\n\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p) {\n\tunion {\n\t\tduk_uint8_t b[2];\n\t\tduk_uint16_t x;\n\t} u;\n\n\tduk_memcpy((void *) u.b, (const void *) (*p), (size_t) 2);\n\tu.x = DUK_NTOH16(u.x);\n\t*p += 2;\n\treturn u.x;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p) {\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tduk_memcpy((void *) u.b, (const void *) (*p), (size_t) 4);\n\tu.x = DUK_NTOH32(u.x);\n\t*p += 4;\n\treturn u.x;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_raw_read_double_be(duk_uint8_t **p) {\n\tduk_double_union du;\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tduk_memcpy((void *) u.b, (const void *) (*p), (size_t) 4);\n\tu.x = DUK_NTOH32(u.x);\n\tdu.ui[DUK_DBL_IDX_UI0] = u.x;\n\tduk_memcpy((void *) u.b, (const void *) (*p + 4), (size_t) 4);\n\tu.x = DUK_NTOH32(u.x);\n\tdu.ui[DUK_DBL_IDX_UI1] = u.x;\n\t*p += 8;\n\n\treturn du.d;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u16_be(duk_uint8_t **p, duk_uint16_t val) {\n\tunion {\n\t\tduk_uint8_t b[2];\n\t\tduk_uint16_t x;\n\t} u;\n\n\tu.x = DUK_HTON16(val);\n\tduk_memcpy((void *) (*p), (const void *) u.b, (size_t) 2);\n\t*p += 2;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u32_be(duk_uint8_t **p, duk_uint32_t val) {\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tu.x = DUK_HTON32(val);\n\tduk_memcpy((void *) (*p), (const void *) u.b, (size_t) 4);\n\t*p += 4;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_double_be(duk_uint8_t **p, duk_double_t val) {\n\tduk_double_union du;\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tdu.d = val;\n\tu.x = du.ui[DUK_DBL_IDX_UI0];\n\tu.x = DUK_HTON32(u.x);\n\tduk_memcpy((void *) (*p), (const void *) u.b, (size_t) 4);\n\tu.x = du.ui[DUK_DBL_IDX_UI1];\n\tu.x = DUK_HTON32(u.x);\n\tduk_memcpy((void *) (*p + 4), (const void *) u.b, (size_t) 4);\n\t*p += 8;\n}\n\n/*\n *  Assertion helpers\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL void duk_bw_assert_valid(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx) {\n\tDUK_UNREF(thr);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_ASSERT(bw_ctx->buf != NULL);\n\tDUK_ASSERT((DUK_HBUFFER_DYNAMIC_GET_SIZE(bw_ctx->buf) == 0) ||\n\t           (bw_ctx->p != NULL &&\n\t            bw_ctx->p_base != NULL &&\n\t            bw_ctx->p_limit != NULL &&\n\t            bw_ctx->p_limit >= bw_ctx->p_base &&\n\t            bw_ctx->p >= bw_ctx->p_base &&\n\t            bw_ctx->p <= bw_ctx->p_limit));\n}\n#endif\n#line 1 \"duk_util_cast.c\"\n/*\n *  Cast helpers.\n *\n *  C99+ coercion is challenging portability-wise because out-of-range casts\n *  may invoke implementation defined or even undefined behavior.  See e.g.\n *  http://blog.frama-c.com/index.php?post/2013/10/09/Overflow-float-integer.\n *\n *  Provide explicit cast helpers which try to avoid implementation defined\n *  or undefined behavior.  These helpers can then be simplified in the vast\n *  majority of cases where the implementation defined or undefined behavior\n *  is not problematic.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Portable double-to-integer cast which avoids undefined behavior and avoids\n * relying on fmin(), fmax(), or other intrinsics.  Out-of-range results are\n * not assumed by caller, but here value is clamped, NaN converts to minval.\n */\n#define DUK__DOUBLE_INT_CAST1(tname,minval,maxval)  do { \\\n\t\tif (DUK_LIKELY(x >= (duk_double_t) (minval))) { \\\n\t\t\tDUK_ASSERT(!DUK_ISNAN(x)); \\\n\t\t\tif (DUK_LIKELY(x <= (duk_double_t) (maxval))) { \\\n\t\t\t\treturn (tname) x; \\\n\t\t\t} else { \\\n\t\t\t\treturn (tname) (maxval); \\\n\t\t\t} \\\n\t\t} else { \\\n\t\t\t/* NaN or below minval.  Since we don't care about the result \\\n\t\t\t * for out-of-range values, just return the minimum value for \\\n\t\t\t * both. \\\n\t\t\t */ \\\n\t\t\treturn (tname) (minval); \\\n\t\t} \\\n\t} while (0)\n\n/* Rely on specific NaN behavior for duk_double_{fmin,fmax}(): if either\n * argument is a NaN, return the second argument.  This avoids a\n * NaN-to-integer cast which is undefined behavior.\n */\n#define DUK__DOUBLE_INT_CAST2(tname,minval,maxval)  do { \\\n\t\treturn (tname) duk_double_fmin(duk_double_fmax(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \\\n\t} while (0)\n\n/* Another solution which doesn't need C99+ behavior for fmin() and fmax(). */\n#define DUK__DOUBLE_INT_CAST3(tname,minval,maxval)  do { \\\n\t\tif (DUK_ISNAN(x)) { \\\n\t\t\t/* 0 or any other value is fine. */ \\\n\t\t\treturn (tname) 0; \\\n\t\t} else \\\n\t\t\treturn (tname) DUK_FMIN(DUK_FMAX(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \\\n\t\t} \\\n\t} while (0)\n\n/* C99+ solution: relies on specific fmin() and fmax() behavior in C99: if\n * one argument is NaN but the other isn't, the non-NaN argument is returned.\n * Because the limits are non-NaN values, explicit NaN check is not needed.\n * This may not work on all legacy platforms, and also doesn't seem to inline\n * the fmin() and fmax() calls (unless one uses -ffast-math which we don't\n * support).\n */\n#define DUK__DOUBLE_INT_CAST4(tname,minval,maxval)  do { \\\n\t\treturn (tname) DUK_FMIN(DUK_FMAX(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \\\n\t} while (0)\n\nDUK_INTERNAL duk_int_t duk_double_to_int_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\t/* Real world solution: almost any practical platform will provide\n\t * an integer value without any guarantees what it is (which is fine).\n\t */\n\treturn (duk_int_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_int_t, DUK_INT_MIN, DUK_INT_MAX);\n#endif\n}\n\nDUK_INTERNAL duk_uint_t duk_double_to_uint_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_uint_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_uint_t, DUK_UINT_MIN, DUK_UINT_MAX);\n#endif\n}\n\nDUK_INTERNAL duk_int32_t duk_double_to_int32_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_int32_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_int32_t, DUK_INT32_MIN, DUK_INT32_MAX);\n#endif\n}\n\nDUK_INTERNAL duk_uint32_t duk_double_to_uint32_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_uint32_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_uint32_t, DUK_UINT32_MIN, DUK_UINT32_MAX);\n#endif\n}\n\n/* Largest IEEE double that doesn't round to infinity in the default rounding\n * mode.  The exact midpoint between (1 - 2^(-24)) * 2^128 and 2^128 rounds to\n * infinity, at least on x64.  This number is one double unit below that\n * midpoint.  See misc/float_cast.c.\n */\n#define DUK__FLOAT_ROUND_LIMIT      340282356779733623858607532500980858880.0\n\n/* Maximum IEEE float.  Double-to-float conversion above this would be out of\n * range and thus technically undefined behavior.\n */\n#define DUK__FLOAT_MAX              340282346638528859811704183484516925440.0\n\nDUK_INTERNAL duk_float_t duk_double_to_float_t(duk_double_t x) {\n\t/* Even a double-to-float cast is technically undefined behavior if\n\t * the double is out-of-range.  C99 Section 6.3.1.5:\n\t *\n\t *   If the value being converted is in the range of values that can\n\t *   be represented but cannot be represented exactly, the result is\n\t *   either the nearest higher or nearest lower representable value,\n\t *   chosen in an implementation-defined manner.  If the value being\n\t *   converted is outside the range of values that can be represented,\n\t *   the behavior is undefined.\n\t */\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_float_t) x;\n#else\n\tduk_double_t t;\n\n\tt = DUK_FABS(x);\n\tDUK_ASSERT((DUK_ISNAN(x) && DUK_ISNAN(t)) ||\n\t           (!DUK_ISNAN(x) && !DUK_ISNAN(t)));\n\n\tif (DUK_LIKELY(t <= DUK__FLOAT_MAX)) {\n\t\t/* Standard in-range case, try to get here with a minimum\n\t\t * number of checks and branches.\n\t\t */\n\t\tDUK_ASSERT(!DUK_ISNAN(x));\n\t\treturn (duk_float_t) x;\n\t} else if (t <= DUK__FLOAT_ROUND_LIMIT) {\n\t\t/* Out-of-range, but rounds to min/max float. */\n\t\tDUK_ASSERT(!DUK_ISNAN(x));\n\t\tif (x < 0.0) {\n\t\t\treturn (duk_float_t) -DUK__FLOAT_MAX;\n\t\t} else {\n\t\t\treturn (duk_float_t) DUK__FLOAT_MAX;\n\t\t}\n\t} else if (DUK_ISNAN(x)) {\n\t\t/* Assumes double NaN -> float NaN considered \"in range\". */\n\t\tDUK_ASSERT(DUK_ISNAN(x));\n\t\treturn (duk_float_t) x;\n\t} else {\n\t\t/* Out-of-range, rounds to +/- Infinity. */\n\t\tif (x < 0.0) {\n\t\t\treturn (duk_float_t) -DUK_DOUBLE_INFINITY;\n\t\t} else {\n\t\t\treturn (duk_float_t) DUK_DOUBLE_INFINITY;\n\t\t}\n\t}\n#endif\n}\n\n/* automatic undefs */\n#undef DUK__DOUBLE_INT_CAST1\n#undef DUK__DOUBLE_INT_CAST2\n#undef DUK__DOUBLE_INT_CAST3\n#undef DUK__DOUBLE_INT_CAST4\n#undef DUK__FLOAT_MAX\n#undef DUK__FLOAT_ROUND_LIMIT\n#line 1 \"duk_util_double.c\"\n/*\n *  IEEE double helpers.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL duk_bool_t duk_double_is_anyinf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn DUK_DBLUNION_IS_ANYINF(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_posinf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn DUK_DBLUNION_IS_POSINF(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_neginf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn DUK_DBLUNION_IS_NEGINF(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\t/* Assumes we're dealing with a Duktape internal NaN which is\n\t * NaN normalized if duk_tval requires it.\n\t */\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\treturn DUK_DBLUNION_IS_NAN(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan_or_zero(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\t/* Assumes we're dealing with a Duktape internal NaN which is\n\t * NaN normalized if duk_tval requires it.\n\t */\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\treturn DUK_DBLUNION_IS_NAN(&du) || DUK_DBLUNION_IS_ANYZERO(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan_or_inf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\t/* If exponent is 0x7FF the argument is either a NaN or an\n\t * infinity.  We don't need to check any other fields.\n\t */\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n\treturn (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000);\n#else\n\treturn (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000);\n#endif\n#else\n\treturn (du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL;\n#endif\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan_zero_inf(duk_double_t x) {\n\tduk_double_union du;\n#if defined(DUK_USE_64BIT_OPS)\n\tduk_uint64_t t;\n#else\n\tduk_uint32_t t;\n#endif\n\tdu.d = x;\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000);\n\tif (t == DUK_U64_CONSTANT(0x0000000000000000)) {\n\t\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x0000000080000000);\n\t\treturn t == 0;\n\t}\n\tif (t == DUK_U64_CONSTANT(0x000000007ff00000)) {\n\t\treturn 1;\n\t}\n#else\n\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000);\n\tif (t == DUK_U64_CONSTANT(0x0000000000000000)) {\n\t\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x8000000000000000);\n\t\treturn t == 0;\n\t}\n\tif (t == DUK_U64_CONSTANT(0x7ff0000000000000)) {\n\t\treturn 1;\n\t}\n#endif\n#else\n\tt = du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL;\n\tif (t == 0x00000000UL) {\n\t\treturn DUK_DBLUNION_IS_ANYZERO(&du);\n\t}\n\tif (t == 0x7ff00000UL) {\n\t\treturn 1;\n\t}\n#endif\n\treturn 0;\n}\n\nDUK_INTERNAL duk_small_uint_t duk_double_signbit(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn (duk_small_uint_t) DUK_DBLUNION_GET_SIGNBIT(&du);\n}\n\nDUK_INTERNAL duk_double_t duk_double_trunc_towards_zero(duk_double_t x) {\n\t/* XXX: optimize */\n\tduk_small_uint_t s = duk_double_signbit(x);\n\tx = DUK_FLOOR(DUK_FABS(x));  /* truncate towards zero */\n\tif (s) {\n\t\tx = -x;\n\t}\n\treturn x;\n}\n\nDUK_INTERNAL duk_bool_t duk_double_same_sign(duk_double_t x, duk_double_t y) {\n\tduk_double_union du1;\n\tduk_double_union du2;\n\tdu1.d = x;\n\tdu2.d = y;\n\n\treturn (((du1.ui[DUK_DBL_IDX_UI0] ^ du2.ui[DUK_DBL_IDX_UI0]) & 0x80000000UL) == 0);\n}\n\nDUK_INTERNAL duk_double_t duk_double_fmin(duk_double_t x, duk_double_t y) {\n\t/* Doesn't replicate fmin() behavior exactly: for fmin() if one\n\t * argument is a NaN, the other argument should be returned.\n\t * Duktape doesn't rely on this behavior so the replacement can\n\t * be simplified.\n\t */\n\treturn (x < y ? x : y);\n}\n\nDUK_INTERNAL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y) {\n\t/* Doesn't replicate fmax() behavior exactly: for fmax() if one\n\t * argument is a NaN, the other argument should be returned.\n\t * Duktape doesn't rely on this behavior so the replacement can\n\t * be simplified.\n\t */\n\treturn (x > y ? x : y);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_finite(duk_double_t x) {\n\treturn !duk_double_is_nan_or_inf(x);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_integer(duk_double_t x) {\n\tif (duk_double_is_nan_or_inf(x)) {\n\t\treturn 0;\n\t} else {\n\t\treturn duk_js_tointeger_number(x) == x;\n\t}\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_safe_integer(duk_double_t x) {\n\t/* >>> 2**53-1\n\t * 9007199254740991\n\t */\n\treturn duk_double_is_integer(x) && DUK_FABS(x) <= 9007199254740991.0;\n}\n\n/* Check whether a duk_double_t is a whole number in the 32-bit range (reject\n * negative zero), and if so, return a duk_int32_t.\n * For compiler use: don't allow negative zero as it will cause trouble with\n * LDINT+LDINTX, positive zero is OK.\n */\nDUK_INTERNAL duk_bool_t duk_is_whole_get_int32_nonegzero(duk_double_t x, duk_int32_t *ival) {\n\tduk_int32_t t;\n\n\tt = duk_double_to_int32_t(x);\n\tif (!((duk_double_t) t == x)) {\n\t\treturn 0;\n\t}\n\tif (t == 0) {\n\t\tduk_double_union du;\n\t\tdu.d = x;\n\t\tif (DUK_DBLUNION_HAS_SIGNBIT(&du)) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\t*ival = t;\n\treturn 1;\n}\n\n/* Check whether a duk_double_t is a whole number in the 32-bit range, and if\n * so, return a duk_int32_t.\n */\nDUK_INTERNAL duk_bool_t duk_is_whole_get_int32(duk_double_t x, duk_int32_t *ival) {\n\tduk_int32_t t;\n\n\tt = duk_double_to_int32_t(x);\n\tif (!((duk_double_t) t == x)) {\n\t\treturn 0;\n\t}\n\t*ival = t;\n\treturn 1;\n}\n\n/* Division: division by zero is undefined behavior (and may in fact trap)\n * so it needs special handling for portability.\n */\n\nDUK_INTERNAL DUK_INLINE duk_double_t duk_double_div(duk_double_t x, duk_double_t y) {\n#if !defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\tif (DUK_UNLIKELY(y == 0.0)) {\n\t\t/* In C99+ division by zero is undefined behavior so\n\t\t * avoid it entirely.  Hopefully the compiler is\n\t\t * smart enough to avoid emitting any actual code\n\t\t * because almost all practical platforms behave as\n\t\t * expected.\n\t\t */\n\t\tif (x > 0.0) {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn -DUK_DOUBLE_INFINITY;\n\t\t\t} else {\n\t\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t\t}\n\t\t} else if (x < 0.0) {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t\t} else {\n\t\t\t\treturn -DUK_DOUBLE_INFINITY;\n\t\t\t}\n\t\t} else {\n\t\t\t/* +/- 0, NaN */\n\t\t\treturn DUK_DOUBLE_NAN;\n\t\t}\n\t}\n#endif\n\n\treturn x / y;\n}\n#line 1 \"duk_util_hashbytes.c\"\n/*\n *  Hash function duk_util_hashbytes().\n *\n *  Currently, 32-bit MurmurHash2.\n *\n *  Don't rely on specific hash values; hash function may be endianness\n *  dependent, for instance.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_STRHASH_DENSE)\n/* 'magic' constants for Murmurhash2 */\n#define DUK__MAGIC_M  ((duk_uint32_t) 0x5bd1e995UL)\n#define DUK__MAGIC_R  24\n\nDUK_INTERNAL duk_uint32_t duk_util_hashbytes(const duk_uint8_t *data, duk_size_t len, duk_uint32_t seed) {\n\tduk_uint32_t h = seed ^ ((duk_uint32_t) len);\n\n\twhile (len >= 4) {\n\t\t/* Portability workaround is required for platforms without\n\t\t * unaligned access.  The replacement code emulates little\n\t\t * endian access even on big endian architectures, which is\n\t\t * OK as long as it is consistent for a build.\n\t\t */\n#if defined(DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS)\n\t\tduk_uint32_t k = *((const duk_uint32_t *) (const void *) data);\n#else\n\t\tduk_uint32_t k = ((duk_uint32_t) data[0]) |\n\t\t                 (((duk_uint32_t) data[1]) << 8) |\n\t\t                 (((duk_uint32_t) data[2]) << 16) |\n\t\t                 (((duk_uint32_t) data[3]) << 24);\n#endif\n\n\t\tk *= DUK__MAGIC_M;\n\t\tk ^= k >> DUK__MAGIC_R;\n\t\tk *= DUK__MAGIC_M;\n\t\th *= DUK__MAGIC_M;\n\t\th ^= k;\n\t\tdata += 4;\n\t\tlen -= 4;\n\t}\n\n\tswitch (len) {\n\tcase 3: h ^= data[2] << 16;\n\tcase 2: h ^= data[1] << 8;\n\tcase 1: h ^= data[0];\n\t        h *= DUK__MAGIC_M;\n        }\n\n\th ^= h >> 13;\n\th *= DUK__MAGIC_M;\n\th ^= h >> 15;\n\n\treturn h;\n}\n#endif  /* DUK_USE_STRHASH_DENSE */\n\n/* automatic undefs */\n#undef DUK__MAGIC_M\n#undef DUK__MAGIC_R\n#line 1 \"duk_util_memory.c\"\n/*\n *  Memory utils.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL || len == 0U);\n\tDUK_ASSERT(s2 != NULL || len == 0U);\n\treturn DUK_MEMCMP(s1, s2, (size_t) len);\n}\n\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL);\n\tDUK_ASSERT(s2 != NULL);\n\treturn DUK_MEMCMP(s1, s2, (size_t) len);\n}\n#else  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL || len == 0U);\n\tDUK_ASSERT(s2 != NULL || len == 0U);\n\tif (DUK_UNLIKELY(len == 0U)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(s1 != NULL);\n\tDUK_ASSERT(s2 != NULL);\n\treturn duk_memcmp(s1, s2, len);\n}\n\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL);\n\tDUK_ASSERT(s2 != NULL);\n\treturn DUK_MEMCMP(s1, s2, (size_t) len);\n}\n#endif  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\n#line 1 \"duk_util_tinyrandom.c\"\n/*\n *  A tiny random number generator used for Math.random() and other internals.\n *\n *  Default algorithm is xoroshiro128+: http://xoroshiro.di.unimi.it/xoroshiro128plus.c\n *  with SplitMix64 seed preparation: http://xorshift.di.unimi.it/splitmix64.c.\n *\n *  Low memory targets and targets without 64-bit types use a slightly smaller\n *  (but slower) algorithm by Adi Shamir:\n *  http://www.woodmann.com/forum/archive/index.php/t-3100.html.\n *\n */\n\n/* #include duk_internal.h -> already included */\n\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\n\n#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS)\n#define DUK__RANDOM_SHAMIR3OP\n#else\n#define DUK__RANDOM_XOROSHIRO128PLUS\n#endif\n\n#if defined(DUK__RANDOM_SHAMIR3OP)\n#define DUK__UPDATE_RND(rnd) do { \\\n\t\t(rnd) += ((rnd) * (rnd)) | 0x05UL; \\\n\t\t(rnd) = ((rnd) & 0xffffffffUL);       /* if duk_uint32_t is exactly 32 bits, this is a NOP */ \\\n\t} while (0)\n\n#define DUK__RND_BIT(rnd)  ((rnd) >> 31)  /* only use the highest bit */\n\nDUK_INTERNAL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr) {\n\tDUK_UNREF(thr);  /* Nothing now. */\n}\n\nDUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) {\n\tduk_double_t t;\n\tduk_small_int_t n;\n\tduk_uint32_t rnd;\n\n\trnd = thr->heap->rnd_state;\n\n\tn = 53;  /* enough to cover the whole mantissa */\n\tt = 0.0;\n\n\tdo {\n\t\tDUK__UPDATE_RND(rnd);\n\t\tt += DUK__RND_BIT(rnd);\n\t\tt /= 2.0;\n\t} while (--n);\n\n\tthr->heap->rnd_state = rnd;\n\n\tDUK_ASSERT(t >= (duk_double_t) 0.0);\n\tDUK_ASSERT(t < (duk_double_t) 1.0);\n\n\treturn t;\n}\n#endif  /* DUK__RANDOM_SHAMIR3OP */\n\n#if defined(DUK__RANDOM_XOROSHIRO128PLUS)\nDUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__rnd_splitmix64(duk_uint64_t *x) {\n\tduk_uint64_t z;\n\tz = (*x += DUK_U64_CONSTANT(0x9E3779B97F4A7C15));\n\tz = (z ^ (z >> 30U)) * DUK_U64_CONSTANT(0xBF58476D1CE4E5B9);\n\tz = (z ^ (z >> 27U)) * DUK_U64_CONSTANT(0x94D049BB133111EB);\n\treturn z ^ (z >> 31U);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__rnd_rotl(const duk_uint64_t x, duk_small_uint_t k) {\n\treturn (x << k) | (x >> (64U - k));\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__xoroshiro128plus(duk_uint64_t *s) {\n\tduk_uint64_t s0;\n\tduk_uint64_t s1;\n\tduk_uint64_t res;\n\n\ts0 = s[0];\n\ts1 = s[1];\n\tres = s0 + s1;\n\ts1 ^= s0;\n\ts[0] = duk__rnd_rotl(s0, 55) ^ s1 ^ (s1 << 14U);\n\ts[1] = duk__rnd_rotl(s1, 36);\n\n\treturn res;\n}\n\nDUK_INTERNAL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr) {\n\tduk_small_uint_t i;\n\tduk_uint64_t x;\n\n\t/* Mix both halves of the initial seed with SplitMix64.  The intent\n\t * is to ensure that very similar raw seeds (which is usually the case\n\t * because current seed is Date.now()) result in different xoroshiro128+\n\t * seeds.\n\t */\n\tx = thr->heap->rnd_state[0];  /* Only [0] is used as input here. */\n\tfor (i = 0; i < 64; i++) {\n\t\tthr->heap->rnd_state[i & 0x01] = duk__rnd_splitmix64(&x);  /* Keep last 2 values. */\n\t}\n}\n\nDUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) {\n\tduk_uint64_t v;\n\tduk_double_union du;\n\n\t/* For big and little endian the integer and IEEE double byte order\n\t * is the same so a direct assignment works.  For mixed endian the\n\t * 32-bit parts must be swapped.\n\t */\n\tv = (DUK_U64_CONSTANT(0x3ff) << 52U) | (duk__xoroshiro128plus((duk_uint64_t *) thr->heap->rnd_state) >> 12U);\n\tdu.ull[0] = v;\n#if defined(DUK_USE_DOUBLE_ME)\n\tdo {\n\t\tduk_uint32_t tmp;\n\t\ttmp = du.ui[0];\n\t\tdu.ui[0] = du.ui[1];\n\t\tdu.ui[1] = tmp;\n\t} while (0);\n#endif\n\treturn du.d - 1.0;\n}\n#endif  /* DUK__RANDOM_XOROSHIRO128PLUS */\n\n#endif  /* !DUK_USE_GET_RANDOM_DOUBLE */\n\n/* automatic undefs */\n#undef DUK__RANDOM_SHAMIR3OP\n#undef DUK__RANDOM_XOROSHIRO128PLUS\n#undef DUK__RND_BIT\n#undef DUK__UPDATE_RND\n"
  },
  {
    "path": "react_juce/duktape/src/duktape.h",
    "content": "/*\n *  Duktape public API for Duktape 2.4.0.\n *\n *  See the API reference for documentation on call semantics.  The exposed,\n *  supported API is between the \"BEGIN PUBLIC API\" and \"END PUBLIC API\"\n *  comments.  Other parts of the header are Duktape internal and related to\n *  e.g. platform/compiler/feature detection.\n *\n *  Git commit d4f2cff1c592d70f58bab8e1bd85705174c02a58 (v2.4.0).\n *  Git branch master.\n *\n *  See Duktape AUTHORS.rst and LICENSE.txt for copyright and\n *  licensing information.\n */\n\n/* LICENSE.txt */\n/*\n *  ===============\n *  Duktape license\n *  ===============\n *  \n *  (http://opensource.org/licenses/MIT)\n *  \n *  Copyright (c) 2013-2019 by Duktape authors (see AUTHORS.rst)\n *  \n *  Permission is hereby granted, free of charge, to any person obtaining a copy\n *  of this software and associated documentation files (the \"Software\"), to deal\n *  in the Software without restriction, including without limitation the rights\n *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n *  copies of the Software, and to permit persons to whom the Software is\n *  furnished to do so, subject to the following conditions:\n *  \n *  The above copyright notice and this permission notice shall be included in\n *  all copies or substantial portions of the Software.\n *  \n *  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n *  THE SOFTWARE.\n */\n\n/* AUTHORS.rst */\n/*\n *  ===============\n *  Duktape authors\n *  ===============\n *  \n *  Copyright\n *  =========\n *  \n *  Duktape copyrights are held by its authors.  Each author has a copyright\n *  to their contribution, and agrees to irrevocably license the contribution\n *  under the Duktape ``LICENSE.txt``.\n *  \n *  Authors\n *  =======\n *  \n *  Please include an e-mail address, a link to your GitHub profile, or something\n *  similar to allow your contribution to be identified accurately.\n *  \n *  The following people have contributed code, website contents, or Wiki contents,\n *  and agreed to irrevocably license their contributions under the Duktape\n *  ``LICENSE.txt`` (in order of appearance):\n *  \n *  * Sami Vaarala <sami.vaarala@iki.fi>\n *  * Niki Dobrev\n *  * Andreas \\u00d6man <andreas@lonelycoder.com>\n *  * L\\u00e1szl\\u00f3 Lang\\u00f3 <llango.u-szeged@partner.samsung.com>\n *  * Legimet <legimet.calc@gmail.com>\n *  * Karl Skomski <karl@skomski.com>\n *  * Bruce Pascoe <fatcerberus1@gmail.com>\n *  * Ren\\u00e9 Hollander <rene@rene8888.at>\n *  * Julien Hamaide (https://github.com/crazyjul)\n *  * Sebastian G\\u00f6tte (https://github.com/jaseg)\n *  * Tomasz Magulski (https://github.com/magul)\n *  * \\D. Bohdan (https://github.com/dbohdan)\n *  * Ond\\u0159ej Jirman (https://github.com/megous)\n *  * Sa\\u00fal Ibarra Corretg\\u00e9 <saghul@gmail.com>\n *  * Jeremy HU <huxingyi@msn.com>\n *  * Ole Andr\\u00e9 Vadla Ravn\\u00e5s (https://github.com/oleavr)\n *  * Harold Brenes (https://github.com/harold-b)\n *  * Oliver Crow (https://github.com/ocrow)\n *  * Jakub Ch\\u0142api\\u0144ski (https://github.com/jchlapinski)\n *  * Brett Vickers (https://github.com/beevik)\n *  * Dominik Okwieka (https://github.com/okitec)\n *  * Remko Tron\\u00e7on (https://el-tramo.be)\n *  * Romero Malaquias (rbsm@ic.ufal.br)\n *  * Michael Drake <michael.drake@codethink.co.uk>\n *  * Steven Don (https://github.com/shdon)\n *  * Simon Stone (https://github.com/sstone1)\n *  * \\J. McC. (https://github.com/jmhmccr)\n *  * Jakub Nowakowski (https://github.com/jimvonmoon)\n *  * Tommy Nguyen (https://github.com/tn0502)\n *  * Fabrice Fontaine (https://github.com/ffontaine)\n *  * Christopher Hiller (https://github.com/boneskull)\n *  * Gonzalo Diethelm (https://github.com/gonzus)\n *  * Michal Kasperek (https://github.com/michalkas)\n *  * Andrew Janke (https://github.com/apjanke)\n *  * Steve Fan (https://github.com/stevefan1999)\n *  * Edward Betts (https://github.com/edwardbetts)\n *  * Ozhan Duz (https://github.com/webfolderio)\n *  * Akos Kiss (https://github.com/akosthekiss)\n *  * TheBrokenRail (https://github.com/TheBrokenRail)\n *  * Jesse Doyle (https://github.com/jessedoyle)\n *  * Gero Kuehn (https://github.com/dc6jgk)\n *  * James Swift (https://github.com/phraemer)\n *  * Luis de Bethencourt (https://github.com/luisbg)\n *  * Ian Whyman (https://github.com/v00d00)\n *  \n *  Other contributions\n *  ===================\n *  \n *  The following people have contributed something other than code (e.g. reported\n *  bugs, provided ideas, etc; roughly in order of appearance):\n *  \n *  * Greg Burns\n *  * Anthony Rabine\n *  * Carlos Costa\n *  * Aur\\u00e9lien Bouilland\n *  * Preet Desai (Pris Matic)\n *  * judofyr (http://www.reddit.com/user/judofyr)\n *  * Jason Woofenden\n *  * Micha\\u0142 Przyby\\u015b\n *  * Anthony Howe\n *  * Conrad Pankoff\n *  * Jim Schimpf\n *  * Rajaran Gaunker (https://github.com/zimbabao)\n *  * Andreas \\u00d6man\n *  * Doug Sanden\n *  * Josh Engebretson (https://github.com/JoshEngebretson)\n *  * Remo Eichenberger (https://github.com/remoe)\n *  * Mamod Mehyar (https://github.com/mamod)\n *  * David Demelier (https://github.com/markand)\n *  * Tim Caswell (https://github.com/creationix)\n *  * Mitchell Blank Jr (https://github.com/mitchblank)\n *  * https://github.com/yushli\n *  * Seo Sanghyeon (https://github.com/sanxiyn)\n *  * Han ChoongWoo (https://github.com/tunz)\n *  * Joshua Peek (https://github.com/josh)\n *  * Bruce E. Pascoe (https://github.com/fatcerberus)\n *  * https://github.com/Kelledin\n *  * https://github.com/sstruchtrup\n *  * Michael Drake (https://github.com/tlsa)\n *  * https://github.com/chris-y\n *  * Laurent Zubiaur (https://github.com/lzubiaur)\n *  * Neil Kolban (https://github.com/nkolban)\n *  * Wilhelm Wanecek (https://github.com/wanecek)\n *  * Andrew Janke (https://github.com/apjanke)\n *  * Unamer (https://github.com/unamer)\n *  * Karl Dahlke (eklhad@gmail.com)\n *  \n *  If you are accidentally missing from this list, send me an e-mail\n *  (``sami.vaarala@iki.fi``) and I'll fix the omission.\n */\n\n#if !defined(DUKTAPE_H_INCLUDED)\n#define DUKTAPE_H_INCLUDED\n\n#define DUK_SINGLE_FILE\n\n/*\n *  BEGIN PUBLIC API\n */\n\n/*\n *  Version and Git commit identification\n */\n\n/* Duktape version, (major * 10000) + (minor * 100) + patch.  Allows C code\n * to #if (DUK_VERSION >= NNN) against Duktape API version.  The same value\n * is also available to ECMAScript code in Duktape.version.  Unofficial\n * development snapshots have 99 for patch level (e.g. 0.10.99 would be a\n * development version after 0.10.0 but before the next official release).\n */\n#define DUK_VERSION                       20400L\n\n/* Git commit, describe, and branch for Duktape build.  Useful for\n * non-official snapshot builds so that application code can easily log\n * which Duktape snapshot was used.  Not available in the ECMAScript\n * environment.\n */\n#define DUK_GIT_COMMIT                    \"d4f2cff1c592d70f58bab8e1bd85705174c02a58\"\n#define DUK_GIT_DESCRIBE                  \"v2.4.0\"\n#define DUK_GIT_BRANCH                    \"master\"\n\n/* External duk_config.h provides platform/compiler/OS dependent\n * typedefs and macros, and DUK_USE_xxx config options so that\n * the rest of Duktape doesn't need to do any feature detection.\n * DUK_VERSION is defined before including so that configuration\n * snippets can react to it.\n */\n#include \"duk_config.h\"\n\n/*\n *  Avoid C++ name mangling\n */\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/*\n *  Some defines forwarded from feature detection\n */\n\n#undef DUK_API_VARIADIC_MACROS\n#if defined(DUK_USE_VARIADIC_MACROS)\n#define DUK_API_VARIADIC_MACROS\n#endif\n\n#define DUK_API_NORETURN(decl) DUK_NORETURN(decl)\n\n/*\n *  Public API specific typedefs\n *\n *  Many types are wrapped by Duktape for portability to rare platforms\n *  where e.g. 'int' is a 16-bit type.  See practical typing discussion\n *  in Duktape web documentation.\n */\n\nstruct duk_thread_state;\nstruct duk_memory_functions;\nstruct duk_function_list_entry;\nstruct duk_number_list_entry;\nstruct duk_time_components;\n\n/* duk_context is now defined in duk_config.h because it may also be\n * referenced there by prototypes.\n */\ntypedef struct duk_thread_state duk_thread_state;\ntypedef struct duk_memory_functions duk_memory_functions;\ntypedef struct duk_function_list_entry duk_function_list_entry;\ntypedef struct duk_number_list_entry duk_number_list_entry;\ntypedef struct duk_time_components duk_time_components;\n\ntypedef duk_ret_t (*duk_c_function)(duk_context *ctx);\ntypedef void *(*duk_alloc_function) (void *udata, duk_size_t size);\ntypedef void *(*duk_realloc_function) (void *udata, void *ptr, duk_size_t size);\ntypedef void (*duk_free_function) (void *udata, void *ptr);\ntypedef void (*duk_fatal_function) (void *udata, const char *msg);\ntypedef void (*duk_decode_char_function) (void *udata, duk_codepoint_t codepoint);\ntypedef duk_codepoint_t (*duk_map_char_function) (void *udata, duk_codepoint_t codepoint);\ntypedef duk_ret_t (*duk_safe_call_function) (duk_context *ctx, void *udata);\ntypedef duk_size_t (*duk_debug_read_function) (void *udata, char *buffer, duk_size_t length);\ntypedef duk_size_t (*duk_debug_write_function) (void *udata, const char *buffer, duk_size_t length);\ntypedef duk_size_t (*duk_debug_peek_function) (void *udata);\ntypedef void (*duk_debug_read_flush_function) (void *udata);\ntypedef void (*duk_debug_write_flush_function) (void *udata);\ntypedef duk_idx_t (*duk_debug_request_function) (duk_context *ctx, void *udata, duk_idx_t nvalues);\ntypedef void (*duk_debug_detached_function) (duk_context *ctx, void *udata);\n\nstruct duk_thread_state {\n\t/* XXX: Enough space to hold internal suspend/resume structure.\n\t * This is rather awkward and to be fixed when the internal\n\t * structure is visible for the public API header.\n\t */\n\tchar data[128];\n};\n\nstruct duk_memory_functions {\n\tduk_alloc_function alloc_func;\n\tduk_realloc_function realloc_func;\n\tduk_free_function free_func;\n\tvoid *udata;\n};\n\nstruct duk_function_list_entry {\n\tconst char *key;\n\tduk_c_function value;\n\tduk_idx_t nargs;\n};\n\nstruct duk_number_list_entry {\n\tconst char *key;\n\tduk_double_t value;\n};\n\nstruct duk_time_components {\n\tduk_double_t year;          /* year, e.g. 2016, ECMAScript year range */\n\tduk_double_t month;         /* month: 1-12 */\n\tduk_double_t day;           /* day: 1-31 */\n\tduk_double_t hours;         /* hour: 0-59 */\n\tduk_double_t minutes;       /* minute: 0-59 */\n\tduk_double_t seconds;       /* second: 0-59 (in POSIX time no leap second) */\n\tduk_double_t milliseconds;  /* may contain sub-millisecond fractions */\n\tduk_double_t weekday;       /* weekday: 0-6, 0=Sunday, 1=Monday, ..., 6=Saturday */\n};\n\n/*\n *  Constants\n */\n\n/* Duktape debug protocol version used by this build. */\n#define DUK_DEBUG_PROTOCOL_VERSION        2\n\n/* Used to represent invalid index; if caller uses this without checking,\n * this index will map to a non-existent stack entry.  Also used in some\n * API calls as a marker to denote \"no value\".\n */\n#define DUK_INVALID_INDEX                 DUK_IDX_MIN\n\n/* Indicates that a native function does not have a fixed number of args,\n * and the argument stack should not be capped/extended at all.\n */\n#define DUK_VARARGS                       ((duk_int_t) (-1))\n\n/* Number of value stack entries (in addition to actual call arguments)\n * guaranteed to be allocated on entry to a Duktape/C function.\n */\n#define DUK_API_ENTRY_STACK               64U\n\n/* Value types, used by e.g. duk_get_type() */\n#define DUK_TYPE_MIN                      0U\n#define DUK_TYPE_NONE                     0U    /* no value, e.g. invalid index */\n#define DUK_TYPE_UNDEFINED                1U    /* ECMAScript undefined */\n#define DUK_TYPE_NULL                     2U    /* ECMAScript null */\n#define DUK_TYPE_BOOLEAN                  3U    /* ECMAScript boolean: 0 or 1 */\n#define DUK_TYPE_NUMBER                   4U    /* ECMAScript number: double */\n#define DUK_TYPE_STRING                   5U    /* ECMAScript string: CESU-8 / extended UTF-8 encoded */\n#define DUK_TYPE_OBJECT                   6U    /* ECMAScript object: includes objects, arrays, functions, threads */\n#define DUK_TYPE_BUFFER                   7U    /* fixed or dynamic, garbage collected byte buffer */\n#define DUK_TYPE_POINTER                  8U    /* raw void pointer */\n#define DUK_TYPE_LIGHTFUNC                9U    /* lightweight function pointer */\n#define DUK_TYPE_MAX                      9U\n\n/* Value mask types, used by e.g. duk_get_type_mask() */\n#define DUK_TYPE_MASK_NONE                (1U << DUK_TYPE_NONE)\n#define DUK_TYPE_MASK_UNDEFINED           (1U << DUK_TYPE_UNDEFINED)\n#define DUK_TYPE_MASK_NULL                (1U << DUK_TYPE_NULL)\n#define DUK_TYPE_MASK_BOOLEAN             (1U << DUK_TYPE_BOOLEAN)\n#define DUK_TYPE_MASK_NUMBER              (1U << DUK_TYPE_NUMBER)\n#define DUK_TYPE_MASK_STRING              (1U << DUK_TYPE_STRING)\n#define DUK_TYPE_MASK_OBJECT              (1U << DUK_TYPE_OBJECT)\n#define DUK_TYPE_MASK_BUFFER              (1U << DUK_TYPE_BUFFER)\n#define DUK_TYPE_MASK_POINTER             (1U << DUK_TYPE_POINTER)\n#define DUK_TYPE_MASK_LIGHTFUNC           (1U << DUK_TYPE_LIGHTFUNC)\n#define DUK_TYPE_MASK_THROW               (1U << 10)  /* internal flag value: throw if mask doesn't match */\n#define DUK_TYPE_MASK_PROMOTE             (1U << 11)  /* internal flag value: promote to object if mask matches */\n\n/* Coercion hints */\n#define DUK_HINT_NONE                     0    /* prefer number, unless input is a Date, in which\n                                                * case prefer string (E5 Section 8.12.8)\n                                                */\n#define DUK_HINT_STRING                   1    /* prefer string */\n#define DUK_HINT_NUMBER                   2    /* prefer number */\n\n/* Enumeration flags for duk_enum() */\n#define DUK_ENUM_INCLUDE_NONENUMERABLE    (1U << 0)    /* enumerate non-numerable properties in addition to enumerable */\n#define DUK_ENUM_INCLUDE_HIDDEN           (1U << 1)    /* enumerate hidden symbols too (in Duktape 1.x called internal properties) */\n#define DUK_ENUM_INCLUDE_SYMBOLS          (1U << 2)    /* enumerate symbols */\n#define DUK_ENUM_EXCLUDE_STRINGS          (1U << 3)    /* exclude strings */\n#define DUK_ENUM_OWN_PROPERTIES_ONLY      (1U << 4)    /* don't walk prototype chain, only check own properties */\n#define DUK_ENUM_ARRAY_INDICES_ONLY       (1U << 5)    /* only enumerate array indices */\n/* XXX: misleading name */\n#define DUK_ENUM_SORT_ARRAY_INDICES       (1U << 6)    /* sort array indices (applied to full enumeration result, including inherited array indices); XXX: misleading name */\n#define DUK_ENUM_NO_PROXY_BEHAVIOR        (1U << 7)    /* enumerate a proxy object itself without invoking proxy behavior */\n\n/* Compilation flags for duk_compile() and duk_eval() */\n/* DUK_COMPILE_xxx bits 0-2 are reserved for an internal 'nargs' argument.\n */\n#define DUK_COMPILE_EVAL                  (1U << 3)    /* compile eval code (instead of global code) */\n#define DUK_COMPILE_FUNCTION              (1U << 4)    /* compile function code (instead of global code) */\n#define DUK_COMPILE_STRICT                (1U << 5)    /* use strict (outer) context for global, eval, or function code */\n#define DUK_COMPILE_SHEBANG               (1U << 6)    /* allow shebang ('#! ...') comment on first line of source */\n#define DUK_COMPILE_SAFE                  (1U << 7)    /* (internal) catch compilation errors */\n#define DUK_COMPILE_NORESULT              (1U << 8)    /* (internal) omit eval result */\n#define DUK_COMPILE_NOSOURCE              (1U << 9)    /* (internal) no source string on stack */\n#define DUK_COMPILE_STRLEN                (1U << 10)   /* (internal) take strlen() of src_buffer (avoids double evaluation in macro) */\n#define DUK_COMPILE_NOFILENAME            (1U << 11)   /* (internal) no filename on stack */\n#define DUK_COMPILE_FUNCEXPR              (1U << 12)   /* (internal) source is a function expression (used for Function constructor) */\n\n/* Flags for duk_def_prop() and its variants; base flags + a lot of convenience shorthands */\n#define DUK_DEFPROP_WRITABLE              (1U << 0)    /* set writable (effective if DUK_DEFPROP_HAVE_WRITABLE set) */\n#define DUK_DEFPROP_ENUMERABLE            (1U << 1)    /* set enumerable (effective if DUK_DEFPROP_HAVE_ENUMERABLE set) */\n#define DUK_DEFPROP_CONFIGURABLE          (1U << 2)    /* set configurable (effective if DUK_DEFPROP_HAVE_CONFIGURABLE set) */\n#define DUK_DEFPROP_HAVE_WRITABLE         (1U << 3)    /* set/clear writable */\n#define DUK_DEFPROP_HAVE_ENUMERABLE       (1U << 4)    /* set/clear enumerable */\n#define DUK_DEFPROP_HAVE_CONFIGURABLE     (1U << 5)    /* set/clear configurable */\n#define DUK_DEFPROP_HAVE_VALUE            (1U << 6)    /* set value (given on value stack) */\n#define DUK_DEFPROP_HAVE_GETTER           (1U << 7)    /* set getter (given on value stack) */\n#define DUK_DEFPROP_HAVE_SETTER           (1U << 8)    /* set setter (given on value stack) */\n#define DUK_DEFPROP_FORCE                 (1U << 9)    /* force change if possible, may still fail for e.g. virtual properties */\n#define DUK_DEFPROP_SET_WRITABLE          (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE)\n#define DUK_DEFPROP_CLEAR_WRITABLE        DUK_DEFPROP_HAVE_WRITABLE\n#define DUK_DEFPROP_SET_ENUMERABLE        (DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE)\n#define DUK_DEFPROP_CLEAR_ENUMERABLE      DUK_DEFPROP_HAVE_ENUMERABLE\n#define DUK_DEFPROP_SET_CONFIGURABLE      (DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE)\n#define DUK_DEFPROP_CLEAR_CONFIGURABLE    DUK_DEFPROP_HAVE_CONFIGURABLE\n#define DUK_DEFPROP_W                     DUK_DEFPROP_WRITABLE\n#define DUK_DEFPROP_E                     DUK_DEFPROP_ENUMERABLE\n#define DUK_DEFPROP_C                     DUK_DEFPROP_CONFIGURABLE\n#define DUK_DEFPROP_WE                    (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_ENUMERABLE)\n#define DUK_DEFPROP_WC                    (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_CONFIGURABLE)\n#define DUK_DEFPROP_WEC                   (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_CONFIGURABLE)\n#define DUK_DEFPROP_HAVE_W                DUK_DEFPROP_HAVE_WRITABLE\n#define DUK_DEFPROP_HAVE_E                DUK_DEFPROP_HAVE_ENUMERABLE\n#define DUK_DEFPROP_HAVE_C                DUK_DEFPROP_HAVE_CONFIGURABLE\n#define DUK_DEFPROP_HAVE_WE               (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE)\n#define DUK_DEFPROP_HAVE_WC               (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_CONFIGURABLE)\n#define DUK_DEFPROP_HAVE_WEC              (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE)\n#define DUK_DEFPROP_SET_W                 DUK_DEFPROP_SET_WRITABLE\n#define DUK_DEFPROP_SET_E                 DUK_DEFPROP_SET_ENUMERABLE\n#define DUK_DEFPROP_SET_C                 DUK_DEFPROP_SET_CONFIGURABLE\n#define DUK_DEFPROP_SET_WE                (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_ENUMERABLE)\n#define DUK_DEFPROP_SET_WC                (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_CONFIGURABLE)\n#define DUK_DEFPROP_SET_WEC               (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_ENUMERABLE | DUK_DEFPROP_SET_CONFIGURABLE)\n#define DUK_DEFPROP_CLEAR_W               DUK_DEFPROP_CLEAR_WRITABLE\n#define DUK_DEFPROP_CLEAR_E               DUK_DEFPROP_CLEAR_ENUMERABLE\n#define DUK_DEFPROP_CLEAR_C               DUK_DEFPROP_CLEAR_CONFIGURABLE\n#define DUK_DEFPROP_CLEAR_WE              (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_ENUMERABLE)\n#define DUK_DEFPROP_CLEAR_WC              (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_CONFIGURABLE)\n#define DUK_DEFPROP_CLEAR_WEC             (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_ENUMERABLE | DUK_DEFPROP_CLEAR_CONFIGURABLE)\n#define DUK_DEFPROP_ATTR_W                (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_W)\n#define DUK_DEFPROP_ATTR_E                (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_E)\n#define DUK_DEFPROP_ATTR_C                (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_C)\n#define DUK_DEFPROP_ATTR_WE               (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WE)\n#define DUK_DEFPROP_ATTR_WC               (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WC)\n#define DUK_DEFPROP_ATTR_WEC              (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WEC)\n\n/* Flags for duk_push_thread_raw() */\n#define DUK_THREAD_NEW_GLOBAL_ENV         (1U << 0)    /* create a new global environment */\n\n/* Flags for duk_gc() */\n#define DUK_GC_COMPACT                    (1U << 0)    /* compact heap objects */\n\n/* Error codes (must be 8 bits at most, see duk_error.h) */\n#define DUK_ERR_NONE                      0    /* no error (e.g. from duk_get_error_code()) */\n#define DUK_ERR_ERROR                     1    /* Error */\n#define DUK_ERR_EVAL_ERROR                2    /* EvalError */\n#define DUK_ERR_RANGE_ERROR               3    /* RangeError */\n#define DUK_ERR_REFERENCE_ERROR           4    /* ReferenceError */\n#define DUK_ERR_SYNTAX_ERROR              5    /* SyntaxError */\n#define DUK_ERR_TYPE_ERROR                6    /* TypeError */\n#define DUK_ERR_URI_ERROR                 7    /* URIError */\n\n/* Return codes for C functions (shortcut for throwing an error) */\n#define DUK_RET_ERROR                     (-DUK_ERR_ERROR)\n#define DUK_RET_EVAL_ERROR                (-DUK_ERR_EVAL_ERROR)\n#define DUK_RET_RANGE_ERROR               (-DUK_ERR_RANGE_ERROR)\n#define DUK_RET_REFERENCE_ERROR           (-DUK_ERR_REFERENCE_ERROR)\n#define DUK_RET_SYNTAX_ERROR              (-DUK_ERR_SYNTAX_ERROR)\n#define DUK_RET_TYPE_ERROR                (-DUK_ERR_TYPE_ERROR)\n#define DUK_RET_URI_ERROR                 (-DUK_ERR_URI_ERROR)\n\n/* Return codes for protected calls (duk_safe_call(), duk_pcall()) */\n#define DUK_EXEC_SUCCESS                  0\n#define DUK_EXEC_ERROR                    1\n\n/* Debug levels for DUK_USE_DEBUG_WRITE(). */\n#define DUK_LEVEL_DEBUG                   0\n#define DUK_LEVEL_DDEBUG                  1\n#define DUK_LEVEL_DDDEBUG                 2\n\n/*\n *  Macros to create Symbols as C statically constructed strings.\n *\n *  Call e.g. as DUK_HIDDEN_SYMBOL(\"myProperty\") <=> (\"\\xFF\" \"myProperty\").\n *\n *  Local symbols have a unique suffix, caller should take care to avoid\n *  conflicting with the Duktape internal representation by e.g. prepending\n *  a '!' character: DUK_LOCAL_SYMBOL(\"myLocal\", \"!123\").\n *\n *  Note that these can only be used for string constants, not dynamically\n *  created strings.\n *\n *  You shouldn't normally use DUK_INTERNAL_SYMBOL() at all.  It is reserved\n *  for Duktape internal symbols only.  There are no versioning guarantees\n *  for internal symbols.\n */\n\n#define DUK_HIDDEN_SYMBOL(x)     (\"\\xFF\" x)\n#define DUK_GLOBAL_SYMBOL(x)     (\"\\x80\" x)\n#define DUK_LOCAL_SYMBOL(x,uniq) (\"\\x81\" x \"\\xff\" uniq)\n#define DUK_WELLKNOWN_SYMBOL(x)  (\"\\x81\" x \"\\xff\")\n#define DUK_INTERNAL_SYMBOL(x)   (\"\\x82\" x)\n\n/*\n *  If no variadic macros, __FILE__ and __LINE__ are passed through globals\n *  which is ugly and not thread safe.\n */\n\n#if !defined(DUK_API_VARIADIC_MACROS)\nDUK_EXTERNAL_DECL const char *duk_api_global_filename;\nDUK_EXTERNAL_DECL duk_int_t duk_api_global_line;\n#endif\n\n/*\n *  Context management\n */\n\nDUK_EXTERNAL_DECL\nduk_context *duk_create_heap(duk_alloc_function alloc_func,\n                             duk_realloc_function realloc_func,\n                             duk_free_function free_func,\n                             void *heap_udata,\n                             duk_fatal_function fatal_handler);\nDUK_EXTERNAL_DECL void duk_destroy_heap(duk_context *ctx);\n\nDUK_EXTERNAL_DECL void duk_suspend(duk_context *ctx, duk_thread_state *state);\nDUK_EXTERNAL_DECL void duk_resume(duk_context *ctx, const duk_thread_state *state);\n\n#define duk_create_heap_default() \\\n\tduk_create_heap(NULL, NULL, NULL, NULL, NULL)\n\n/*\n *  Memory management\n *\n *  Raw functions have no side effects (cannot trigger GC).\n */\n\nDUK_EXTERNAL_DECL void *duk_alloc_raw(duk_context *ctx, duk_size_t size);\nDUK_EXTERNAL_DECL void duk_free_raw(duk_context *ctx, void *ptr);\nDUK_EXTERNAL_DECL void *duk_realloc_raw(duk_context *ctx, void *ptr, duk_size_t size);\nDUK_EXTERNAL_DECL void *duk_alloc(duk_context *ctx, duk_size_t size);\nDUK_EXTERNAL_DECL void duk_free(duk_context *ctx, void *ptr);\nDUK_EXTERNAL_DECL void *duk_realloc(duk_context *ctx, void *ptr, duk_size_t size);\nDUK_EXTERNAL_DECL void duk_get_memory_functions(duk_context *ctx, duk_memory_functions *out_funcs);\nDUK_EXTERNAL_DECL void duk_gc(duk_context *ctx, duk_uint_t flags);\n\n/*\n *  Error handling\n */\n\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_throw_raw(duk_context *ctx));\n#define duk_throw(ctx) \\\n\t(duk_throw_raw((ctx)), (duk_ret_t) 0)\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_fatal_raw(duk_context *ctx, const char *err_msg));\n#define duk_fatal(ctx,err_msg) \\\n\t(duk_fatal_raw((ctx), (err_msg)), (duk_ret_t) 0)\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...));\n\n#if defined(DUK_API_VARIADIC_MACROS)\n#define duk_error(ctx,err_code,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_generic_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_eval_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_EVAL_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_range_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_RANGE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_reference_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_REFERENCE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_syntax_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_SYNTAX_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_type_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_TYPE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_uri_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_URI_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#else  /* DUK_API_VARIADIC_MACROS */\n/* For legacy compilers without variadic macros a macro hack is used to allow\n * variable arguments.  While the macro allows \"return duk_error(...)\", it\n * will fail with e.g. \"(void) duk_error(...)\".  The calls are noreturn but\n * with a return value to allow the \"return duk_error(...)\" idiom.  This may\n * cause some compiler warnings, but without noreturn the generated code is\n * often worse.  The same approach as with variadic macros (using\n * \"(duk_error(...), 0)\") won't work due to the macro hack structure.\n */\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_error_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_generic_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_eval_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_range_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_reference_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_syntax_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_type_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_uri_error_stash(duk_context *ctx, const char *fmt, ...));\n#define duk_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_error_stash)  /* last value is func pointer, arguments follow in parens */\n#define duk_generic_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_generic_error_stash)\n#define duk_eval_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_eval_error_stash)\n#define duk_range_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_range_error_stash)\n#define duk_reference_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_reference_error_stash)\n#define duk_syntax_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_syntax_error_stash)\n#define duk_type_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_type_error_stash)\n#define duk_uri_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_uri_error_stash)\n#endif  /* DUK_API_VARIADIC_MACROS */\n\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_va_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap));\n\n#define duk_error_va(ctx,err_code,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_generic_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_eval_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_EVAL_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_range_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_RANGE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_reference_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_REFERENCE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_syntax_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_SYNTAX_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_type_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_TYPE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_uri_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_URI_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n\n/*\n *  Other state related functions\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_strict_call(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_constructor_call(duk_context *ctx);\n\n/*\n *  Stack management\n */\n\nDUK_EXTERNAL_DECL duk_idx_t duk_normalize_index(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_valid_index(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_require_valid_index(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL duk_idx_t duk_get_top(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_set_top(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_idx_t duk_get_top_index(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_require_top_index(duk_context *ctx);\n\n/* Although extra/top could be an unsigned type here, using a signed type\n * makes the API more robust to calling code calculation errors or corner\n * cases (where caller might occasionally come up with negative values).\n * Negative values are treated as zero, which is better than casting them\n * to a large unsigned number.  (This principle is used elsewhere in the\n * API too.)\n */\nDUK_EXTERNAL_DECL duk_bool_t duk_check_stack(duk_context *ctx, duk_idx_t extra);\nDUK_EXTERNAL_DECL void duk_require_stack(duk_context *ctx, duk_idx_t extra);\nDUK_EXTERNAL_DECL duk_bool_t duk_check_stack_top(duk_context *ctx, duk_idx_t top);\nDUK_EXTERNAL_DECL void duk_require_stack_top(duk_context *ctx, duk_idx_t top);\n\n/*\n *  Stack manipulation (other than push/pop)\n */\n\nDUK_EXTERNAL_DECL void duk_swap(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL void duk_swap_top(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_dup(duk_context *ctx, duk_idx_t from_idx);\nDUK_EXTERNAL_DECL void duk_dup_top(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_insert(duk_context *ctx, duk_idx_t to_idx);\nDUK_EXTERNAL_DECL void duk_replace(duk_context *ctx, duk_idx_t to_idx);\nDUK_EXTERNAL_DECL void duk_copy(duk_context *ctx, duk_idx_t from_idx, duk_idx_t to_idx);\nDUK_EXTERNAL_DECL void duk_remove(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_xcopymove_raw(duk_context *to_ctx, duk_context *from_ctx, duk_idx_t count, duk_bool_t is_copy);\n\n#define duk_xmove_top(to_ctx,from_ctx,count) \\\n\tduk_xcopymove_raw((to_ctx), (from_ctx), (count), 0 /*is_copy*/)\n#define duk_xcopy_top(to_ctx,from_ctx,count) \\\n\tduk_xcopymove_raw((to_ctx), (from_ctx), (count), 1 /*is_copy*/)\n\n/*\n *  Push operations\n *\n *  Push functions return the absolute (relative to bottom of frame)\n *  position of the pushed value for convenience.\n *\n *  Note: duk_dup() is technically a push.\n */\n\nDUK_EXTERNAL_DECL void duk_push_undefined(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_null(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_boolean(duk_context *ctx, duk_bool_t val);\nDUK_EXTERNAL_DECL void duk_push_true(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_false(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_number(duk_context *ctx, duk_double_t val);\nDUK_EXTERNAL_DECL void duk_push_nan(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_int(duk_context *ctx, duk_int_t val);\nDUK_EXTERNAL_DECL void duk_push_uint(duk_context *ctx, duk_uint_t val);\nDUK_EXTERNAL_DECL const char *duk_push_string(duk_context *ctx, const char *str);\nDUK_EXTERNAL_DECL const char *duk_push_lstring(duk_context *ctx, const char *str, duk_size_t len);\nDUK_EXTERNAL_DECL void duk_push_pointer(duk_context *ctx, void *p);\nDUK_EXTERNAL_DECL const char *duk_push_sprintf(duk_context *ctx, const char *fmt, ...);\nDUK_EXTERNAL_DECL const char *duk_push_vsprintf(duk_context *ctx, const char *fmt, va_list ap);\n\n/* duk_push_literal() may evaluate its argument (a C string literal) more than\n * once on purpose.  When speed is preferred, sizeof() avoids an unnecessary\n * strlen() at runtime.  Sizeof(\"foo\") == 4, so subtract 1.  The argument\n * must be non-NULL and should not contain internal NUL characters as the\n * behavior will then depend on config options.\n */\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_push_literal(ctx,cstring)  duk_push_string((ctx), (cstring))\n#else\nDUK_EXTERNAL_DECL const char *duk_push_literal_raw(duk_context *ctx, const char *str, duk_size_t len);\n#define duk_push_literal(ctx,cstring)  duk_push_literal_raw((ctx), (cstring), sizeof((cstring)) - 1U)\n#endif\n\nDUK_EXTERNAL_DECL void duk_push_this(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_new_target(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_current_function(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_current_thread(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_global_object(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_heap_stash(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_global_stash(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_thread_stash(duk_context *ctx, duk_context *target_ctx);\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_object(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_bare_object(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_array(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_bare_array(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_c_function(duk_context *ctx, duk_c_function func, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_c_lightfunc(duk_context *ctx, duk_c_function func, duk_idx_t nargs, duk_idx_t length, duk_int_t magic);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_thread_raw(duk_context *ctx, duk_uint_t flags);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_proxy(duk_context *ctx, duk_uint_t proxy_flags);\n\n#define duk_push_thread(ctx) \\\n\tduk_push_thread_raw((ctx), 0 /*flags*/)\n\n#define duk_push_thread_new_globalenv(ctx) \\\n\tduk_push_thread_raw((ctx), DUK_THREAD_NEW_GLOBAL_ENV /*flags*/)\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...);\n\n#if defined(DUK_API_VARIADIC_MACROS)\n#define duk_push_error_object(ctx,err_code,...)  \\\n\tduk_push_error_object_raw((ctx), (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__)\n#else\nDUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...);\n/* Note: parentheses are required so that the comma expression works in assignments. */\n#define duk_push_error_object  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_push_error_object_stash)  /* last value is func pointer, arguments follow in parens */\n#endif\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_va_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap);\n#define duk_push_error_object_va(ctx,err_code,fmt,ap)  \\\n\tduk_push_error_object_va_raw((ctx), (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap))\n\n#define DUK_BUF_FLAG_DYNAMIC   (1 << 0)    /* internal flag: dynamic buffer */\n#define DUK_BUF_FLAG_EXTERNAL  (1 << 1)    /* internal flag: external buffer */\n#define DUK_BUF_FLAG_NOZERO    (1 << 2)    /* internal flag: don't zero allocated buffer */\n\nDUK_EXTERNAL_DECL void *duk_push_buffer_raw(duk_context *ctx, duk_size_t size, duk_small_uint_t flags);\n\n#define duk_push_buffer(ctx,size,dynamic) \\\n\tduk_push_buffer_raw((ctx), (size), (dynamic) ? DUK_BUF_FLAG_DYNAMIC : 0)\n#define duk_push_fixed_buffer(ctx,size) \\\n\tduk_push_buffer_raw((ctx), (size), 0 /*flags*/)\n#define duk_push_dynamic_buffer(ctx,size) \\\n\tduk_push_buffer_raw((ctx), (size), DUK_BUF_FLAG_DYNAMIC /*flags*/)\n#define duk_push_external_buffer(ctx) \\\n\t((void) duk_push_buffer_raw((ctx), 0, DUK_BUF_FLAG_DYNAMIC | DUK_BUF_FLAG_EXTERNAL))\n\n#define DUK_BUFOBJ_ARRAYBUFFER         0\n#define DUK_BUFOBJ_NODEJS_BUFFER       1\n#define DUK_BUFOBJ_DATAVIEW            2\n#define DUK_BUFOBJ_INT8ARRAY           3\n#define DUK_BUFOBJ_UINT8ARRAY          4\n#define DUK_BUFOBJ_UINT8CLAMPEDARRAY   5\n#define DUK_BUFOBJ_INT16ARRAY          6\n#define DUK_BUFOBJ_UINT16ARRAY         7\n#define DUK_BUFOBJ_INT32ARRAY          8\n#define DUK_BUFOBJ_UINT32ARRAY         9\n#define DUK_BUFOBJ_FLOAT32ARRAY        10\n#define DUK_BUFOBJ_FLOAT64ARRAY        11\n\nDUK_EXTERNAL_DECL void duk_push_buffer_object(duk_context *ctx, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags);\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_heapptr(duk_context *ctx, void *ptr);\n\n/*\n *  Pop operations\n */\n\nDUK_EXTERNAL_DECL void duk_pop(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_pop_n(duk_context *ctx, duk_idx_t count);\nDUK_EXTERNAL_DECL void duk_pop_2(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_pop_3(duk_context *ctx);\n\n/*\n *  Type checks\n *\n *  duk_is_none(), which would indicate whether index it outside of stack,\n *  is not needed; duk_is_valid_index() gives the same information.\n */\n\nDUK_EXTERNAL_DECL duk_int_t duk_get_type(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_check_type(duk_context *ctx, duk_idx_t idx, duk_int_t type);\nDUK_EXTERNAL_DECL duk_uint_t duk_get_type_mask(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_check_type_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t mask);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_undefined(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_null(duk_context *ctx, duk_idx_t idx);\n#define duk_is_null_or_undefined(ctx, idx) \\\n\t((duk_get_type_mask((ctx), (idx)) & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED)) ? 1 : 0)\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_nan(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_object(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_buffer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_buffer_data(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_lightfunc(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_symbol(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_array(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_c_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_ecmascript_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_bound_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_thread(duk_context *ctx, duk_idx_t idx);\n\n#define duk_is_callable(ctx,idx) \\\n\tduk_is_function((ctx), (idx))\nDUK_EXTERNAL_DECL duk_bool_t duk_is_constructable(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_fixed_buffer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_external_buffer(duk_context *ctx, duk_idx_t idx);\n\n/* Buffers and lightfuncs are not considered primitive because they mimic\n * objects and e.g. duk_to_primitive() will coerce them instead of returning\n * them as is.  Symbols are represented as strings internally.\n */\n#define duk_is_primitive(ctx,idx) \\\n\tduk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_UNDEFINED | \\\n\t                                  DUK_TYPE_MASK_NULL | \\\n\t                                  DUK_TYPE_MASK_BOOLEAN | \\\n\t                                  DUK_TYPE_MASK_NUMBER | \\\n\t                                  DUK_TYPE_MASK_STRING | \\\n\t                                  DUK_TYPE_MASK_POINTER)\n\n/* Symbols are object coercible, covered by DUK_TYPE_MASK_STRING. */\n#define duk_is_object_coercible(ctx,idx) \\\n\tduk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_BOOLEAN | \\\n\t                                  DUK_TYPE_MASK_NUMBER | \\\n\t                                  DUK_TYPE_MASK_STRING | \\\n\t                                  DUK_TYPE_MASK_OBJECT | \\\n\t                                  DUK_TYPE_MASK_BUFFER | \\\n\t                                  DUK_TYPE_MASK_POINTER | \\\n\t                                  DUK_TYPE_MASK_LIGHTFUNC)\n\nDUK_EXTERNAL_DECL duk_errcode_t duk_get_error_code(duk_context *ctx, duk_idx_t idx);\n#define duk_is_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) != 0)\n#define duk_is_eval_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_EVAL_ERROR)\n#define duk_is_range_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_RANGE_ERROR)\n#define duk_is_reference_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_REFERENCE_ERROR)\n#define duk_is_syntax_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_SYNTAX_ERROR)\n#define duk_is_type_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_TYPE_ERROR)\n#define duk_is_uri_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_URI_ERROR)\n\n/*\n *  Get operations: no coercion, returns default value for invalid\n *  indices and invalid value types.\n *\n *  duk_get_undefined() and duk_get_null() would be pointless and\n *  are not included.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_double_t duk_get_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int_t duk_get_int(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint_t duk_get_uint(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_get_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_get_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL void *duk_get_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_get_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_get_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_c_function duk_get_c_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_context *duk_get_context(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void *duk_get_heapptr(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Get-with-explicit default operations: like get operations but with an\n *  explicit default value.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_boolean_default(duk_context *ctx, duk_idx_t idx, duk_bool_t def_value);\nDUK_EXTERNAL_DECL duk_double_t duk_get_number_default(duk_context *ctx, duk_idx_t idx, duk_double_t def_value);\nDUK_EXTERNAL_DECL duk_int_t duk_get_int_default(duk_context *ctx, duk_idx_t idx, duk_int_t def_value);\nDUK_EXTERNAL_DECL duk_uint_t duk_get_uint_default(duk_context *ctx, duk_idx_t idx, duk_uint_t def_value);\nDUK_EXTERNAL_DECL const char *duk_get_string_default(duk_context *ctx, duk_idx_t idx, const char *def_value);\nDUK_EXTERNAL_DECL const char *duk_get_lstring_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_get_buffer_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_get_buffer_data_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_get_pointer_default(duk_context *ctx, duk_idx_t idx, void *def_value);\nDUK_EXTERNAL_DECL duk_c_function duk_get_c_function_default(duk_context *ctx, duk_idx_t idx, duk_c_function def_value);\nDUK_EXTERNAL_DECL duk_context *duk_get_context_default(duk_context *ctx, duk_idx_t idx, duk_context *def_value);\nDUK_EXTERNAL_DECL void *duk_get_heapptr_default(duk_context *ctx, duk_idx_t idx, void *def_value);\n\n/*\n *  Opt operations: like require operations but with an explicit default value\n *  when value is undefined or index is invalid, null and non-matching types\n *  cause a TypeError.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_opt_boolean(duk_context *ctx, duk_idx_t idx, duk_bool_t def_value);\nDUK_EXTERNAL_DECL duk_double_t duk_opt_number(duk_context *ctx, duk_idx_t idx, duk_double_t def_value);\nDUK_EXTERNAL_DECL duk_int_t duk_opt_int(duk_context *ctx, duk_idx_t idx, duk_int_t def_value);\nDUK_EXTERNAL_DECL duk_uint_t duk_opt_uint(duk_context *ctx, duk_idx_t idx, duk_uint_t def_value);\nDUK_EXTERNAL_DECL const char *duk_opt_string(duk_context *ctx, duk_idx_t idx, const char *def_ptr);\nDUK_EXTERNAL_DECL const char *duk_opt_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_opt_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size);\nDUK_EXTERNAL_DECL void *duk_opt_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size);\nDUK_EXTERNAL_DECL void *duk_opt_pointer(duk_context *ctx, duk_idx_t idx, void *def_value);\nDUK_EXTERNAL_DECL duk_c_function duk_opt_c_function(duk_context *ctx, duk_idx_t idx, duk_c_function def_value);\nDUK_EXTERNAL_DECL duk_context *duk_opt_context(duk_context *ctx, duk_idx_t idx, duk_context *def_value);\nDUK_EXTERNAL_DECL void *duk_opt_heapptr(duk_context *ctx, duk_idx_t idx, void *def_value);\n\n/*\n *  Require operations: no coercion, throw error if index or type\n *  is incorrect.  No defaulting.\n */\n\n#define duk_require_type_mask(ctx,idx,mask) \\\n\t((void) duk_check_type_mask((ctx), (idx), (mask) | DUK_TYPE_MASK_THROW))\n\nDUK_EXTERNAL_DECL void duk_require_undefined(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_require_null(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_require_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_double_t duk_require_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int_t duk_require_int(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint_t duk_require_uint(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_require_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_require_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL void duk_require_object(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void *duk_require_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_require_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_require_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_c_function duk_require_c_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_context *duk_require_context(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_require_function(duk_context *ctx, duk_idx_t idx);\n#define duk_require_callable(ctx,idx) \\\n\tduk_require_function((ctx), (idx))\nDUK_EXTERNAL_DECL void duk_require_constructor_call(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_require_constructable(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void *duk_require_heapptr(duk_context *ctx, duk_idx_t idx);\n\n/* Symbols are object coercible and covered by DUK_TYPE_MASK_STRING. */\n#define duk_require_object_coercible(ctx,idx) \\\n\t((void) duk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_BOOLEAN | \\\n\t                                            DUK_TYPE_MASK_NUMBER | \\\n\t                                            DUK_TYPE_MASK_STRING | \\\n\t                                            DUK_TYPE_MASK_OBJECT | \\\n\t                                            DUK_TYPE_MASK_BUFFER | \\\n\t                                            DUK_TYPE_MASK_POINTER | \\\n\t                                            DUK_TYPE_MASK_LIGHTFUNC | \\\n\t                                            DUK_TYPE_MASK_THROW))\n\n/*\n *  Coercion operations: in-place coercion, return coerced value where\n *  applicable.  If index is invalid, throw error.  Some coercions may\n *  throw an expected error (e.g. from a toString() or valueOf() call)\n *  or an internal error (e.g. from out of memory).\n */\n\nDUK_EXTERNAL_DECL void duk_to_undefined(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_to_null(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_to_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_double_t duk_to_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int_t duk_to_int(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint_t duk_to_uint(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int32_t duk_to_int32(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint32_t duk_to_uint32(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint16_t duk_to_uint16(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_to_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, duk_uint_t flags);\nDUK_EXTERNAL_DECL void *duk_to_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_to_object(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_to_primitive(duk_context *ctx, duk_idx_t idx, duk_int_t hint);\n\n#define DUK_BUF_MODE_FIXED      0   /* internal: request fixed buffer result */\n#define DUK_BUF_MODE_DYNAMIC    1   /* internal: request dynamic buffer result */\n#define DUK_BUF_MODE_DONTCARE   2   /* internal: don't care about fixed/dynamic nature */\n\n#define duk_to_buffer(ctx,idx,out_size) \\\n\tduk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_DONTCARE)\n#define duk_to_fixed_buffer(ctx,idx,out_size) \\\n\tduk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_FIXED)\n#define duk_to_dynamic_buffer(ctx,idx,out_size) \\\n\tduk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_DYNAMIC)\n\n/* safe variants of a few coercion operations */\nDUK_EXTERNAL_DECL const char *duk_safe_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL const char *duk_to_stacktrace(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_safe_to_stacktrace(duk_context *ctx, duk_idx_t idx);\n#define duk_safe_to_string(ctx,idx) \\\n\tduk_safe_to_lstring((ctx), (idx), NULL)\n\n/*\n *  Value length\n */\n\nDUK_EXTERNAL_DECL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t idx, duk_size_t len);\n#if 0\n/* duk_require_length()? */\n/* duk_opt_length()? */\n#endif\n\n/*\n *  Misc conversion\n */\n\nDUK_EXTERNAL_DECL const char *duk_base64_encode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_base64_decode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_hex_encode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_hex_decode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_json_encode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_json_decode(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL const char *duk_buffer_to_string(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Buffer\n */\n\nDUK_EXTERNAL_DECL void *duk_resize_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t new_size);\nDUK_EXTERNAL_DECL void *duk_steal_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void duk_config_buffer(duk_context *ctx, duk_idx_t idx, void *ptr, duk_size_t len);\n\n/*\n *  Property access\n *\n *  The basic function assumes key is on stack.  The _(l)string variant takes\n *  a C string as a property name; the _literal variant takes a C literal.\n *  The _index variant takes an array index as a property name (e.g. 123 is\n *  equivalent to the key \"123\").  The _heapptr variant takes a raw, borrowed\n *  heap pointer.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_get_prop_literal(ctx,obj_idx,key)  duk_get_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_get_prop_literal(ctx,obj_idx,key)  duk_get_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_put_prop_literal(ctx,obj_idx,key)  duk_put_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_put_prop_literal(ctx,obj_idx,key)  duk_put_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_del_prop_literal(ctx,obj_idx,key)  duk_del_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_del_prop_literal(ctx,obj_idx,key)  duk_del_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_has_prop_literal(ctx,obj_idx,key)  duk_has_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_has_prop_literal(ctx,obj_idx,key)  duk_has_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\n\nDUK_EXTERNAL_DECL void duk_get_prop_desc(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags);\nDUK_EXTERNAL_DECL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_string(duk_context *ctx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_get_global_literal(ctx,key)  duk_get_global_string((ctx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_literal_raw(duk_context *ctx, const char *key, duk_size_t key_len);\n#define duk_get_global_literal(ctx,key)  duk_get_global_literal_raw((ctx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_heapptr(duk_context *ctx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_string(duk_context *ctx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_put_global_literal(ctx,key)  duk_put_global_string((ctx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_literal_raw(duk_context *ctx, const char *key, duk_size_t key_len);\n#define duk_put_global_literal(ctx,key)  duk_put_global_literal_raw((ctx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_heapptr(duk_context *ctx, void *ptr);\n\n/*\n *  Inspection\n */\n\nDUK_EXTERNAL_DECL void duk_inspect_value(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_inspect_callstack_entry(duk_context *ctx, duk_int_t level);\n\n/*\n *  Object prototype\n */\n\nDUK_EXTERNAL_DECL void duk_get_prototype(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_prototype(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Object finalizer\n */\n\nDUK_EXTERNAL_DECL void duk_get_finalizer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_finalizer(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Global object\n */\n\nDUK_EXTERNAL_DECL void duk_set_global_object(duk_context *ctx);\n\n/*\n *  Duktape/C function magic value\n */\n\nDUK_EXTERNAL_DECL duk_int_t duk_get_magic(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_magic(duk_context *ctx, duk_idx_t idx, duk_int_t magic);\nDUK_EXTERNAL_DECL duk_int_t duk_get_current_magic(duk_context *ctx);\n\n/*\n *  Module helpers: put multiple function or constant properties\n */\n\nDUK_EXTERNAL_DECL void duk_put_function_list(duk_context *ctx, duk_idx_t obj_idx, const duk_function_list_entry *funcs);\nDUK_EXTERNAL_DECL void duk_put_number_list(duk_context *ctx, duk_idx_t obj_idx, const duk_number_list_entry *numbers);\n\n/*\n *  Object operations\n */\n\nDUK_EXTERNAL_DECL void duk_compact(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL void duk_enum(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t enum_flags);\nDUK_EXTERNAL_DECL duk_bool_t duk_next(duk_context *ctx, duk_idx_t enum_idx, duk_bool_t get_value);\nDUK_EXTERNAL_DECL void duk_seal(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL void duk_freeze(duk_context *ctx, duk_idx_t obj_idx);\n\n/*\n *  String manipulation\n */\n\nDUK_EXTERNAL_DECL void duk_concat(duk_context *ctx, duk_idx_t count);\nDUK_EXTERNAL_DECL void duk_join(duk_context *ctx, duk_idx_t count);\nDUK_EXTERNAL_DECL void duk_decode_string(duk_context *ctx, duk_idx_t idx, duk_decode_char_function callback, void *udata);\nDUK_EXTERNAL_DECL void duk_map_string(duk_context *ctx, duk_idx_t idx, duk_map_char_function callback, void *udata);\nDUK_EXTERNAL_DECL void duk_substring(duk_context *ctx, duk_idx_t idx, duk_size_t start_char_offset, duk_size_t end_char_offset);\nDUK_EXTERNAL_DECL void duk_trim(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_codepoint_t duk_char_code_at(duk_context *ctx, duk_idx_t idx, duk_size_t char_offset);\n\n/*\n *  ECMAScript operators\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL duk_bool_t duk_strict_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL duk_bool_t duk_samevalue(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL duk_bool_t duk_instanceof(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\n\n/*\n *  Random\n */\n\nDUK_EXTERNAL_DECL duk_double_t duk_random(duk_context *ctx);\n\n/*\n *  Function (method) calls\n */\n\nDUK_EXTERNAL_DECL void duk_call(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL void duk_call_method(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL void duk_call_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pcall(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pcall_method(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pcall_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL void duk_new(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pnew(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets);\n\n/*\n *  Thread management\n */\n\n/* There are currently no native functions to yield/resume, due to the internal\n * limitations on coroutine handling.  These will be added later.\n */\n\n/*\n *  Compilation and evaluation\n */\n\nDUK_EXTERNAL_DECL duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags);\nDUK_EXTERNAL_DECL duk_int_t duk_compile_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags);\n\n/* plain */\n#define duk_eval(ctx)  \\\n\t((void) duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOFILENAME))\n\n#define duk_eval_noresult(ctx)  \\\n\t((void) duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval(ctx)  \\\n\t(duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_noresult(ctx)  \\\n\t(duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile(ctx,flags)  \\\n\t((void) duk_compile_raw((ctx), NULL, 0, 2 /*args*/ | (flags)))\n\n#define duk_pcompile(ctx,flags)  \\\n\t(duk_compile_raw((ctx), NULL, 0, 2 /*args*/ | (flags) | DUK_COMPILE_SAFE))\n\n/* string */\n#define duk_eval_string(ctx,src)  \\\n\t((void) duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_eval_string_noresult(ctx,src)  \\\n\t((void) duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_string(ctx,src)  \\\n\t(duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_string_noresult(ctx,src)  \\\n\t(duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_string(ctx,flags,src)  \\\n\t((void) duk_compile_raw((ctx), (src), 0, 0 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_string_filename(ctx,flags,src)  \\\n\t((void) duk_compile_raw((ctx), (src), 0, 1 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN))\n\n#define duk_pcompile_string(ctx,flags,src)  \\\n\t(duk_compile_raw((ctx), (src), 0, 0 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_pcompile_string_filename(ctx,flags,src)  \\\n\t(duk_compile_raw((ctx), (src), 0, 1 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN))\n\n/* lstring */\n#define duk_eval_lstring(ctx,buf,len)  \\\n\t((void) duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME))\n\n#define duk_eval_lstring_noresult(ctx,buf,len)  \\\n\t((void) duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_lstring(ctx,buf,len)  \\\n\t(duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_SAFE | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_lstring_noresult(ctx,buf,len)  \\\n\t(duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_lstring(ctx,flags,buf,len)  \\\n\t((void) duk_compile_raw((ctx), buf, len, 0 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_lstring_filename(ctx,flags,buf,len)  \\\n\t((void) duk_compile_raw((ctx), buf, len, 1 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE))\n\n#define duk_pcompile_lstring(ctx,flags,buf,len)  \\\n\t(duk_compile_raw((ctx), buf, len, 0 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME))\n\n#define duk_pcompile_lstring_filename(ctx,flags,buf,len)  \\\n\t(duk_compile_raw((ctx), buf, len, 1 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE))\n\n/*\n *  Bytecode load/dump\n */\n\nDUK_EXTERNAL_DECL void duk_dump_function(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_load_function(duk_context *ctx);\n\n/*\n *  Debugging\n */\n\nDUK_EXTERNAL_DECL void duk_push_context_dump(duk_context *ctx);\n\n/*\n *  Debugger (debug protocol)\n */\n\nDUK_EXTERNAL_DECL void duk_debugger_attach(duk_context *ctx,\n                                           duk_debug_read_function read_cb,\n                                           duk_debug_write_function write_cb,\n                                           duk_debug_peek_function peek_cb,\n                                           duk_debug_read_flush_function read_flush_cb,\n                                           duk_debug_write_flush_function write_flush_cb,\n                                           duk_debug_request_function request_cb,\n                                           duk_debug_detached_function detached_cb,\n                                           void *udata);\nDUK_EXTERNAL_DECL void duk_debugger_detach(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_debugger_cooperate(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_bool_t duk_debugger_notify(duk_context *ctx, duk_idx_t nvalues);\nDUK_EXTERNAL_DECL void duk_debugger_pause(duk_context *ctx);\n\n/*\n *  Time handling\n */\n\nDUK_EXTERNAL_DECL duk_double_t duk_get_now(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_time_to_components(duk_context *ctx, duk_double_t timeval, duk_time_components *comp);\nDUK_EXTERNAL_DECL duk_double_t duk_components_to_time(duk_context *ctx, duk_time_components *comp);\n\n/*\n *  Date provider related constants\n *\n *  NOTE: These are \"semi public\" - you should only use these if you write\n *  your own platform specific Date provider, see doc/datetime.rst.\n */\n\n/* Millisecond count constants. */\n#define DUK_DATE_MSEC_SECOND          1000L\n#define DUK_DATE_MSEC_MINUTE          (60L * 1000L)\n#define DUK_DATE_MSEC_HOUR            (60L * 60L * 1000L)\n#define DUK_DATE_MSEC_DAY             (24L * 60L * 60L * 1000L)\n\n/* ECMAScript date range is 100 million days from Epoch:\n * > 100e6 * 24 * 60 * 60 * 1000  // 100M days in millisecs\n * 8640000000000000\n * (= 8.64e15)\n */\n#define DUK_DATE_MSEC_100M_DAYS         (8.64e15)\n#define DUK_DATE_MSEC_100M_DAYS_LEEWAY  (8.64e15 + 24 * 3600e3)\n\n/* ECMAScript year range:\n * > new Date(100e6 * 24 * 3600e3).toISOString()\n * '+275760-09-13T00:00:00.000Z'\n * > new Date(-100e6 * 24 * 3600e3).toISOString()\n * '-271821-04-20T00:00:00.000Z'\n */\n#define DUK_DATE_MIN_ECMA_YEAR     (-271821L)\n#define DUK_DATE_MAX_ECMA_YEAR     275760L\n\n/* Part indices for internal breakdowns.  Part order from DUK_DATE_IDX_YEAR\n * to DUK_DATE_IDX_MILLISECOND matches argument ordering of ECMAScript API\n * calls (like Date constructor call).  Some functions in duk_bi_date.c\n * depend on the specific ordering, so change with care.  16 bits are not\n * enough for all parts (year, specifically).\n *\n * Must be in-sync with genbuiltins.py.\n */\n#define DUK_DATE_IDX_YEAR           0  /* year */\n#define DUK_DATE_IDX_MONTH          1  /* month: 0 to 11 */\n#define DUK_DATE_IDX_DAY            2  /* day within month: 0 to 30 */\n#define DUK_DATE_IDX_HOUR           3\n#define DUK_DATE_IDX_MINUTE         4\n#define DUK_DATE_IDX_SECOND         5\n#define DUK_DATE_IDX_MILLISECOND    6\n#define DUK_DATE_IDX_WEEKDAY        7  /* weekday: 0 to 6, 0=sunday, 1=monday, etc */\n#define DUK_DATE_IDX_NUM_PARTS      8\n\n/* Internal API call flags, used for various functions in duk_bi_date.c.\n * Certain flags are used by only certain functions, but since the flags\n * don't overlap, a single flags value can be passed around to multiple\n * functions.\n *\n * The unused top bits of the flags field are also used to pass values\n * to helpers (duk__get_part_helper() and duk__set_part_helper()).\n *\n * Must be in-sync with genbuiltins.py.\n */\n\n/* NOTE: when writing a Date provider you only need a few specific\n * flags from here, the rest are internal.  Avoid using anything you\n * don't need.\n */\n\n#define DUK_DATE_FLAG_NAN_TO_ZERO          (1 << 0)  /* timeval breakdown: internal time value NaN -> zero */\n#define DUK_DATE_FLAG_NAN_TO_RANGE_ERROR   (1 << 1)  /* timeval breakdown: internal time value NaN -> RangeError (toISOString) */\n#define DUK_DATE_FLAG_ONEBASED             (1 << 2)  /* timeval breakdown: convert month and day-of-month parts to one-based (default is zero-based) */\n#define DUK_DATE_FLAG_EQUIVYEAR            (1 << 3)  /* timeval breakdown: replace year with equivalent year in the [1971,2037] range for DST calculations */\n#define DUK_DATE_FLAG_LOCALTIME            (1 << 4)  /* convert time value to local time */\n#define DUK_DATE_FLAG_SUB1900              (1 << 5)  /* getter: subtract 1900 from year when getting year part */\n#define DUK_DATE_FLAG_TOSTRING_DATE        (1 << 6)  /* include date part in string conversion result */\n#define DUK_DATE_FLAG_TOSTRING_TIME        (1 << 7)  /* include time part in string conversion result */\n#define DUK_DATE_FLAG_TOSTRING_LOCALE      (1 << 8)  /* use locale specific formatting if available */\n#define DUK_DATE_FLAG_TIMESETTER           (1 << 9)  /* setter: call is a time setter (affects hour, min, sec, ms); otherwise date setter (affects year, month, day-in-month) */\n#define DUK_DATE_FLAG_YEAR_FIXUP           (1 << 10) /* setter: perform 2-digit year fixup (00...99 -> 1900...1999) */\n#define DUK_DATE_FLAG_SEP_T                (1 << 11) /* string conversion: use 'T' instead of ' ' as a separator */\n#define DUK_DATE_FLAG_VALUE_SHIFT          12        /* additional values begin at bit 12 */\n\n/*\n *  ROM pointer compression\n */\n\n/* Support array for ROM pointer compression.  Only declared when ROM\n * pointer compression is active.\n */\n#if defined(DUK_USE_ROM_OBJECTS) && defined(DUK_USE_HEAPPTR16)\nDUK_EXTERNAL_DECL const void * const duk_rom_compressed_pointers[];\n#endif\n\n/*\n *  C++ name mangling\n */\n\n#if defined(__cplusplus)\n/* end 'extern \"C\"' wrapper */\n}\n#endif\n\n/*\n *  END PUBLIC API\n */\n\n#endif  /* DUKTAPE_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/SpecialCasing-8bit.txt",
    "content": "00DF; 00DF; 0053 0073; 0053 0053; # LATIN SMALL LETTER SHARP S\n"
  },
  {
    "path": "react_juce/duktape/src-input/SpecialCasing.txt",
    "content": "# SpecialCasing-12.1.0.txt\n# Date: 2019-03-10, 10:53:28 GMT\n# © 2019 Unicode®, Inc.\n# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.\n# For terms of use, see http://www.unicode.org/terms_of_use.html\n#\n# Unicode Character Database\n#   For documentation, see http://www.unicode.org/reports/tr44/\n#\n# Special Casing\n#\n# This file is a supplement to the UnicodeData.txt file. It does not define any\n# properties, but rather provides additional information about the casing of\n# Unicode characters, for situations when casing incurs a change in string length\n# or is dependent on context or locale. For compatibility, the UnicodeData.txt\n# file only contains simple case mappings for characters where they are one-to-one\n# and independent of context and language. The data in this file, combined with\n# the simple case mappings in UnicodeData.txt, defines the full case mappings\n# Lowercase_Mapping (lc), Titlecase_Mapping (tc), and Uppercase_Mapping (uc).\n#\n# Note that the preferred mechanism for defining tailored casing operations is\n# the Unicode Common Locale Data Repository (CLDR). For more information, see the\n# discussion of case mappings and case algorithms in the Unicode Standard.\n#\n# All code points not listed in this file that do not have a simple case mappings\n# in UnicodeData.txt map to themselves.\n# ================================================================================\n# Format\n# ================================================================================\n# The entries in this file are in the following machine-readable format:\n#\n# <code>; <lower>; <title>; <upper>; (<condition_list>;)? # <comment>\n#\n# <code>, <lower>, <title>, and <upper> provide the respective full case mappings\n# of <code>, expressed as character values in hex. If there is more than one character,\n# they are separated by spaces. Other than as used to separate elements, spaces are\n# to be ignored.\n#\n# The <condition_list> is optional. Where present, it consists of one or more language IDs\n# or casing contexts, separated by spaces. In these conditions:\n# - A condition list overrides the normal behavior if all of the listed conditions are true.\n# - The casing context is always the context of the characters in the original string,\n#   NOT in the resulting string.\n# - Case distinctions in the condition list are not significant.\n# - Conditions preceded by \"Not_\" represent the negation of the condition.\n# The condition list is not represented in the UCD as a formal property.\n#\n# A language ID is defined by BCP 47, with '-' and '_' treated equivalently.\n#\n# A casing context for a character is defined by Section 3.13 Default Case Algorithms\n# of The Unicode Standard.\n#\n# Parsers of this file must be prepared to deal with future additions to this format:\n#  * Additional contexts\n#  * Additional fields\n# ================================================================================\n\n# ================================================================================\n# Unconditional mappings\n# ================================================================================\n\n# The German es-zed is special--the normal mapping is to SS.\n# Note: the titlecase should never occur in practice. It is equal to titlecase(uppercase(<es-zed>))\n\n00DF; 00DF; 0053 0073; 0053 0053; # LATIN SMALL LETTER SHARP S\n\n# Preserve canonical equivalence for I with dot. Turkic is handled below.\n\n0130; 0069 0307; 0130; 0130; # LATIN CAPITAL LETTER I WITH DOT ABOVE\n\n# Ligatures\n\nFB00; FB00; 0046 0066; 0046 0046; # LATIN SMALL LIGATURE FF\nFB01; FB01; 0046 0069; 0046 0049; # LATIN SMALL LIGATURE FI\nFB02; FB02; 0046 006C; 0046 004C; # LATIN SMALL LIGATURE FL\nFB03; FB03; 0046 0066 0069; 0046 0046 0049; # LATIN SMALL LIGATURE FFI\nFB04; FB04; 0046 0066 006C; 0046 0046 004C; # LATIN SMALL LIGATURE FFL\nFB05; FB05; 0053 0074; 0053 0054; # LATIN SMALL LIGATURE LONG S T\nFB06; FB06; 0053 0074; 0053 0054; # LATIN SMALL LIGATURE ST\n\n0587; 0587; 0535 0582; 0535 0552; # ARMENIAN SMALL LIGATURE ECH YIWN\nFB13; FB13; 0544 0576; 0544 0546; # ARMENIAN SMALL LIGATURE MEN NOW\nFB14; FB14; 0544 0565; 0544 0535; # ARMENIAN SMALL LIGATURE MEN ECH\nFB15; FB15; 0544 056B; 0544 053B; # ARMENIAN SMALL LIGATURE MEN INI\nFB16; FB16; 054E 0576; 054E 0546; # ARMENIAN SMALL LIGATURE VEW NOW\nFB17; FB17; 0544 056D; 0544 053D; # ARMENIAN SMALL LIGATURE MEN XEH\n\n# No corresponding uppercase precomposed character\n\n0149; 0149; 02BC 004E; 02BC 004E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE\n0390; 0390; 0399 0308 0301; 0399 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS\n03B0; 03B0; 03A5 0308 0301; 03A5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS\n01F0; 01F0; 004A 030C; 004A 030C; # LATIN SMALL LETTER J WITH CARON\n1E96; 1E96; 0048 0331; 0048 0331; # LATIN SMALL LETTER H WITH LINE BELOW\n1E97; 1E97; 0054 0308; 0054 0308; # LATIN SMALL LETTER T WITH DIAERESIS\n1E98; 1E98; 0057 030A; 0057 030A; # LATIN SMALL LETTER W WITH RING ABOVE\n1E99; 1E99; 0059 030A; 0059 030A; # LATIN SMALL LETTER Y WITH RING ABOVE\n1E9A; 1E9A; 0041 02BE; 0041 02BE; # LATIN SMALL LETTER A WITH RIGHT HALF RING\n1F50; 1F50; 03A5 0313; 03A5 0313; # GREEK SMALL LETTER UPSILON WITH PSILI\n1F52; 1F52; 03A5 0313 0300; 03A5 0313 0300; # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA\n1F54; 1F54; 03A5 0313 0301; 03A5 0313 0301; # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA\n1F56; 1F56; 03A5 0313 0342; 03A5 0313 0342; # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI\n1FB6; 1FB6; 0391 0342; 0391 0342; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI\n1FC6; 1FC6; 0397 0342; 0397 0342; # GREEK SMALL LETTER ETA WITH PERISPOMENI\n1FD2; 1FD2; 0399 0308 0300; 0399 0308 0300; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA\n1FD3; 1FD3; 0399 0308 0301; 0399 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA\n1FD6; 1FD6; 0399 0342; 0399 0342; # GREEK SMALL LETTER IOTA WITH PERISPOMENI\n1FD7; 1FD7; 0399 0308 0342; 0399 0308 0342; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI\n1FE2; 1FE2; 03A5 0308 0300; 03A5 0308 0300; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA\n1FE3; 1FE3; 03A5 0308 0301; 03A5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA\n1FE4; 1FE4; 03A1 0313; 03A1 0313; # GREEK SMALL LETTER RHO WITH PSILI\n1FE6; 1FE6; 03A5 0342; 03A5 0342; # GREEK SMALL LETTER UPSILON WITH PERISPOMENI\n1FE7; 1FE7; 03A5 0308 0342; 03A5 0308 0342; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI\n1FF6; 1FF6; 03A9 0342; 03A9 0342; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI\n\n# IMPORTANT-when iota-subscript (0345) is uppercased or titlecased,\n#  the result will be incorrect unless the iota-subscript is moved to the end\n#  of any sequence of combining marks. Otherwise, the accents will go on the capital iota.\n#  This process can be achieved by first transforming the text to NFC before casing.\n#  E.g. <alpha><iota_subscript><acute> is uppercased to <ALPHA><acute><IOTA>\n\n# The following cases are already in the UnicodeData.txt file, so are only commented here.\n\n# 0345; 0345; 0399; 0399; # COMBINING GREEK YPOGEGRAMMENI\n\n# All letters with YPOGEGRAMMENI (iota-subscript) or PROSGEGRAMMENI (iota adscript)\n# have special uppercases.\n# Note: characters with PROSGEGRAMMENI are actually titlecase, not uppercase!\n\n1F80; 1F80; 1F88; 1F08 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI\n1F81; 1F81; 1F89; 1F09 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI\n1F82; 1F82; 1F8A; 1F0A 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI\n1F83; 1F83; 1F8B; 1F0B 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI\n1F84; 1F84; 1F8C; 1F0C 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI\n1F85; 1F85; 1F8D; 1F0D 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI\n1F86; 1F86; 1F8E; 1F0E 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI\n1F87; 1F87; 1F8F; 1F0F 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI\n1F88; 1F80; 1F88; 1F08 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI\n1F89; 1F81; 1F89; 1F09 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI\n1F8A; 1F82; 1F8A; 1F0A 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI\n1F8B; 1F83; 1F8B; 1F0B 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI\n1F8C; 1F84; 1F8C; 1F0C 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI\n1F8D; 1F85; 1F8D; 1F0D 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI\n1F8E; 1F86; 1F8E; 1F0E 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI\n1F8F; 1F87; 1F8F; 1F0F 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI\n1F90; 1F90; 1F98; 1F28 0399; # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI\n1F91; 1F91; 1F99; 1F29 0399; # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI\n1F92; 1F92; 1F9A; 1F2A 0399; # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI\n1F93; 1F93; 1F9B; 1F2B 0399; # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI\n1F94; 1F94; 1F9C; 1F2C 0399; # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI\n1F95; 1F95; 1F9D; 1F2D 0399; # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI\n1F96; 1F96; 1F9E; 1F2E 0399; # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI\n1F97; 1F97; 1F9F; 1F2F 0399; # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI\n1F98; 1F90; 1F98; 1F28 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI\n1F99; 1F91; 1F99; 1F29 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI\n1F9A; 1F92; 1F9A; 1F2A 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI\n1F9B; 1F93; 1F9B; 1F2B 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI\n1F9C; 1F94; 1F9C; 1F2C 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI\n1F9D; 1F95; 1F9D; 1F2D 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI\n1F9E; 1F96; 1F9E; 1F2E 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI\n1F9F; 1F97; 1F9F; 1F2F 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI\n1FA0; 1FA0; 1FA8; 1F68 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI\n1FA1; 1FA1; 1FA9; 1F69 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI\n1FA2; 1FA2; 1FAA; 1F6A 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI\n1FA3; 1FA3; 1FAB; 1F6B 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI\n1FA4; 1FA4; 1FAC; 1F6C 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI\n1FA5; 1FA5; 1FAD; 1F6D 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI\n1FA6; 1FA6; 1FAE; 1F6E 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI\n1FA7; 1FA7; 1FAF; 1F6F 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI\n1FA8; 1FA0; 1FA8; 1F68 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI\n1FA9; 1FA1; 1FA9; 1F69 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI\n1FAA; 1FA2; 1FAA; 1F6A 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI\n1FAB; 1FA3; 1FAB; 1F6B 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI\n1FAC; 1FA4; 1FAC; 1F6C 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI\n1FAD; 1FA5; 1FAD; 1F6D 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI\n1FAE; 1FA6; 1FAE; 1F6E 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI\n1FAF; 1FA7; 1FAF; 1F6F 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI\n1FB3; 1FB3; 1FBC; 0391 0399; # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI\n1FBC; 1FB3; 1FBC; 0391 0399; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI\n1FC3; 1FC3; 1FCC; 0397 0399; # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI\n1FCC; 1FC3; 1FCC; 0397 0399; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI\n1FF3; 1FF3; 1FFC; 03A9 0399; # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI\n1FFC; 1FF3; 1FFC; 03A9 0399; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI\n\n# Some characters with YPOGEGRAMMENI also have no corresponding titlecases\n\n1FB2; 1FB2; 1FBA 0345; 1FBA 0399; # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI\n1FB4; 1FB4; 0386 0345; 0386 0399; # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI\n1FC2; 1FC2; 1FCA 0345; 1FCA 0399; # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI\n1FC4; 1FC4; 0389 0345; 0389 0399; # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI\n1FF2; 1FF2; 1FFA 0345; 1FFA 0399; # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI\n1FF4; 1FF4; 038F 0345; 038F 0399; # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI\n\n1FB7; 1FB7; 0391 0342 0345; 0391 0342 0399; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI\n1FC7; 1FC7; 0397 0342 0345; 0397 0342 0399; # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI\n1FF7; 1FF7; 03A9 0342 0345; 03A9 0342 0399; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI\n\n# ================================================================================\n# Conditional Mappings\n# The remainder of this file provides conditional casing data used to produce\n# full case mappings.\n# ================================================================================\n# Language-Insensitive Mappings\n# These are characters whose full case mappings do not depend on language, but do\n# depend on context (which characters come before or after). For more information\n# see the header of this file and the Unicode Standard.\n# ================================================================================\n\n# Special case for final form of sigma\n\n03A3; 03C2; 03A3; 03A3; Final_Sigma; # GREEK CAPITAL LETTER SIGMA\n\n# Note: the following cases for non-final are already in the UnicodeData.txt file.\n\n# 03A3; 03C3; 03A3; 03A3; # GREEK CAPITAL LETTER SIGMA\n# 03C3; 03C3; 03A3; 03A3; # GREEK SMALL LETTER SIGMA\n# 03C2; 03C2; 03A3; 03A3; # GREEK SMALL LETTER FINAL SIGMA\n\n# Note: the following cases are not included, since they would case-fold in lowercasing\n\n# 03C3; 03C2; 03A3; 03A3; Final_Sigma; # GREEK SMALL LETTER SIGMA\n# 03C2; 03C3; 03A3; 03A3; Not_Final_Sigma; # GREEK SMALL LETTER FINAL SIGMA\n\n# ================================================================================\n# Language-Sensitive Mappings\n# These are characters whose full case mappings depend on language and perhaps also\n# context (which characters come before or after). For more information\n# see the header of this file and the Unicode Standard.\n# ================================================================================\n\n# Lithuanian\n\n# Lithuanian retains the dot in a lowercase i when followed by accents.\n\n# Remove DOT ABOVE after \"i\" with upper or titlecase\n\n0307; 0307; ; ; lt After_Soft_Dotted; # COMBINING DOT ABOVE\n\n# Introduce an explicit dot above when lowercasing capital I's and J's\n# whenever there are more accents above.\n# (of the accents used in Lithuanian: grave, acute, tilde above, and ogonek)\n\n0049; 0069 0307; 0049; 0049; lt More_Above; # LATIN CAPITAL LETTER I\n004A; 006A 0307; 004A; 004A; lt More_Above; # LATIN CAPITAL LETTER J\n012E; 012F 0307; 012E; 012E; lt More_Above; # LATIN CAPITAL LETTER I WITH OGONEK\n00CC; 0069 0307 0300; 00CC; 00CC; lt; # LATIN CAPITAL LETTER I WITH GRAVE\n00CD; 0069 0307 0301; 00CD; 00CD; lt; # LATIN CAPITAL LETTER I WITH ACUTE\n0128; 0069 0307 0303; 0128; 0128; lt; # LATIN CAPITAL LETTER I WITH TILDE\n\n# ================================================================================\n\n# Turkish and Azeri\n\n# I and i-dotless; I-dot and i are case pairs in Turkish and Azeri\n# The following rules handle those cases.\n\n0130; 0069; 0130; 0130; tr; # LATIN CAPITAL LETTER I WITH DOT ABOVE\n0130; 0069; 0130; 0130; az; # LATIN CAPITAL LETTER I WITH DOT ABOVE\n\n# When lowercasing, remove dot_above in the sequence I + dot_above, which will turn into i.\n# This matches the behavior of the canonically equivalent I-dot_above\n\n0307; ; 0307; 0307; tr After_I; # COMBINING DOT ABOVE\n0307; ; 0307; 0307; az After_I; # COMBINING DOT ABOVE\n\n# When lowercasing, unless an I is before a dot_above, it turns into a dotless i.\n\n0049; 0131; 0049; 0049; tr Not_Before_Dot; # LATIN CAPITAL LETTER I\n0049; 0131; 0049; 0049; az Not_Before_Dot; # LATIN CAPITAL LETTER I\n\n# When uppercasing, i turns into a dotted capital I\n\n0069; 0069; 0130; 0130; tr; # LATIN SMALL LETTER I\n0069; 0069; 0130; 0130; az; # LATIN SMALL LETTER I\n\n# Note: the following case is already in the UnicodeData.txt file.\n\n# 0131; 0131; 0049; 0049; tr; # LATIN SMALL LETTER DOTLESS I\n\n# EOF\n\n"
  },
  {
    "path": "react_juce/duktape/src-input/UnicodeData-8bit.txt",
    "content": "0000;<control>;Cc;0;BN;;;;;N;NULL;;;;\n0001;<control>;Cc;0;BN;;;;;N;START OF HEADING;;;;\n0002;<control>;Cc;0;BN;;;;;N;START OF TEXT;;;;\n0003;<control>;Cc;0;BN;;;;;N;END OF TEXT;;;;\n0004;<control>;Cc;0;BN;;;;;N;END OF TRANSMISSION;;;;\n0005;<control>;Cc;0;BN;;;;;N;ENQUIRY;;;;\n0006;<control>;Cc;0;BN;;;;;N;ACKNOWLEDGE;;;;\n0007;<control>;Cc;0;BN;;;;;N;BELL;;;;\n0008;<control>;Cc;0;BN;;;;;N;BACKSPACE;;;;\n0009;<control>;Cc;0;S;;;;;N;CHARACTER TABULATION;;;;\n000A;<control>;Cc;0;B;;;;;N;LINE FEED (LF);;;;\n000B;<control>;Cc;0;S;;;;;N;LINE TABULATION;;;;\n000C;<control>;Cc;0;WS;;;;;N;FORM FEED (FF);;;;\n000D;<control>;Cc;0;B;;;;;N;CARRIAGE RETURN (CR);;;;\n000E;<control>;Cc;0;BN;;;;;N;SHIFT OUT;;;;\n000F;<control>;Cc;0;BN;;;;;N;SHIFT IN;;;;\n0010;<control>;Cc;0;BN;;;;;N;DATA LINK ESCAPE;;;;\n0011;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL ONE;;;;\n0012;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL TWO;;;;\n0013;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL THREE;;;;\n0014;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL FOUR;;;;\n0015;<control>;Cc;0;BN;;;;;N;NEGATIVE ACKNOWLEDGE;;;;\n0016;<control>;Cc;0;BN;;;;;N;SYNCHRONOUS IDLE;;;;\n0017;<control>;Cc;0;BN;;;;;N;END OF TRANSMISSION BLOCK;;;;\n0018;<control>;Cc;0;BN;;;;;N;CANCEL;;;;\n0019;<control>;Cc;0;BN;;;;;N;END OF MEDIUM;;;;\n001A;<control>;Cc;0;BN;;;;;N;SUBSTITUTE;;;;\n001B;<control>;Cc;0;BN;;;;;N;ESCAPE;;;;\n001C;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR FOUR;;;;\n001D;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR THREE;;;;\n001E;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR TWO;;;;\n001F;<control>;Cc;0;S;;;;;N;INFORMATION SEPARATOR ONE;;;;\n0020;SPACE;Zs;0;WS;;;;;N;;;;;\n0021;EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;\n0022;QUOTATION MARK;Po;0;ON;;;;;N;;;;;\n0023;NUMBER SIGN;Po;0;ET;;;;;N;;;;;\n0024;DOLLAR SIGN;Sc;0;ET;;;;;N;;;;;\n0025;PERCENT SIGN;Po;0;ET;;;;;N;;;;;\n0026;AMPERSAND;Po;0;ON;;;;;N;;;;;\n0027;APOSTROPHE;Po;0;ON;;;;;N;APOSTROPHE-QUOTE;;;;\n0028;LEFT PARENTHESIS;Ps;0;ON;;;;;Y;OPENING PARENTHESIS;;;;\n0029;RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;CLOSING PARENTHESIS;;;;\n002A;ASTERISK;Po;0;ON;;;;;N;;;;;\n002B;PLUS SIGN;Sm;0;ES;;;;;N;;;;;\n002C;COMMA;Po;0;CS;;;;;N;;;;;\n002D;HYPHEN-MINUS;Pd;0;ES;;;;;N;;;;;\n002E;FULL STOP;Po;0;CS;;;;;N;PERIOD;;;;\n002F;SOLIDUS;Po;0;CS;;;;;N;SLASH;;;;\n0030;DIGIT ZERO;Nd;0;EN;;0;0;0;N;;;;;\n0031;DIGIT ONE;Nd;0;EN;;1;1;1;N;;;;;\n0032;DIGIT TWO;Nd;0;EN;;2;2;2;N;;;;;\n0033;DIGIT THREE;Nd;0;EN;;3;3;3;N;;;;;\n0034;DIGIT FOUR;Nd;0;EN;;4;4;4;N;;;;;\n0035;DIGIT FIVE;Nd;0;EN;;5;5;5;N;;;;;\n0036;DIGIT SIX;Nd;0;EN;;6;6;6;N;;;;;\n0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;;\n0038;DIGIT EIGHT;Nd;0;EN;;8;8;8;N;;;;;\n0039;DIGIT NINE;Nd;0;EN;;9;9;9;N;;;;;\n003A;COLON;Po;0;CS;;;;;N;;;;;\n003B;SEMICOLON;Po;0;ON;;;;;N;;;;;\n003C;LESS-THAN SIGN;Sm;0;ON;;;;;Y;;;;;\n003D;EQUALS SIGN;Sm;0;ON;;;;;N;;;;;\n003E;GREATER-THAN SIGN;Sm;0;ON;;;;;Y;;;;;\n003F;QUESTION MARK;Po;0;ON;;;;;N;;;;;\n0040;COMMERCIAL AT;Po;0;ON;;;;;N;;;;;\n0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061;\n0042;LATIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;0062;\n0043;LATIN CAPITAL LETTER C;Lu;0;L;;;;;N;;;;0063;\n0044;LATIN CAPITAL LETTER D;Lu;0;L;;;;;N;;;;0064;\n0045;LATIN CAPITAL LETTER E;Lu;0;L;;;;;N;;;;0065;\n0046;LATIN CAPITAL LETTER F;Lu;0;L;;;;;N;;;;0066;\n0047;LATIN CAPITAL LETTER G;Lu;0;L;;;;;N;;;;0067;\n0048;LATIN CAPITAL LETTER H;Lu;0;L;;;;;N;;;;0068;\n0049;LATIN CAPITAL LETTER I;Lu;0;L;;;;;N;;;;0069;\n004A;LATIN CAPITAL LETTER J;Lu;0;L;;;;;N;;;;006A;\n004B;LATIN CAPITAL LETTER K;Lu;0;L;;;;;N;;;;006B;\n004C;LATIN CAPITAL LETTER L;Lu;0;L;;;;;N;;;;006C;\n004D;LATIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;006D;\n004E;LATIN CAPITAL LETTER N;Lu;0;L;;;;;N;;;;006E;\n004F;LATIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;006F;\n0050;LATIN CAPITAL LETTER P;Lu;0;L;;;;;N;;;;0070;\n0051;LATIN CAPITAL LETTER Q;Lu;0;L;;;;;N;;;;0071;\n0052;LATIN CAPITAL LETTER R;Lu;0;L;;;;;N;;;;0072;\n0053;LATIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;0073;\n0054;LATIN CAPITAL LETTER T;Lu;0;L;;;;;N;;;;0074;\n0055;LATIN CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0075;\n0056;LATIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;0076;\n0057;LATIN CAPITAL LETTER W;Lu;0;L;;;;;N;;;;0077;\n0058;LATIN CAPITAL LETTER X;Lu;0;L;;;;;N;;;;0078;\n0059;LATIN CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;0079;\n005A;LATIN CAPITAL LETTER Z;Lu;0;L;;;;;N;;;;007A;\n005B;LEFT SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING SQUARE BRACKET;;;;\n005C;REVERSE SOLIDUS;Po;0;ON;;;;;N;BACKSLASH;;;;\n005D;RIGHT SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING SQUARE BRACKET;;;;\n005E;CIRCUMFLEX ACCENT;Sk;0;ON;;;;;N;SPACING CIRCUMFLEX;;;;\n005F;LOW LINE;Pc;0;ON;;;;;N;SPACING UNDERSCORE;;;;\n0060;GRAVE ACCENT;Sk;0;ON;;;;;N;SPACING GRAVE;;;;\n0061;LATIN SMALL LETTER A;Ll;0;L;;;;;N;;;0041;;0041\n0062;LATIN SMALL LETTER B;Ll;0;L;;;;;N;;;0042;;0042\n0063;LATIN SMALL LETTER C;Ll;0;L;;;;;N;;;0043;;0043\n0064;LATIN SMALL LETTER D;Ll;0;L;;;;;N;;;0044;;0044\n0065;LATIN SMALL LETTER E;Ll;0;L;;;;;N;;;0045;;0045\n0066;LATIN SMALL LETTER F;Ll;0;L;;;;;N;;;0046;;0046\n0067;LATIN SMALL LETTER G;Ll;0;L;;;;;N;;;0047;;0047\n0068;LATIN SMALL LETTER H;Ll;0;L;;;;;N;;;0048;;0048\n0069;LATIN SMALL LETTER I;Ll;0;L;;;;;N;;;0049;;0049\n006A;LATIN SMALL LETTER J;Ll;0;L;;;;;N;;;004A;;004A\n006B;LATIN SMALL LETTER K;Ll;0;L;;;;;N;;;004B;;004B\n006C;LATIN SMALL LETTER L;Ll;0;L;;;;;N;;;004C;;004C\n006D;LATIN SMALL LETTER M;Ll;0;L;;;;;N;;;004D;;004D\n006E;LATIN SMALL LETTER N;Ll;0;L;;;;;N;;;004E;;004E\n006F;LATIN SMALL LETTER O;Ll;0;L;;;;;N;;;004F;;004F\n0070;LATIN SMALL LETTER P;Ll;0;L;;;;;N;;;0050;;0050\n0071;LATIN SMALL LETTER Q;Ll;0;L;;;;;N;;;0051;;0051\n0072;LATIN SMALL LETTER R;Ll;0;L;;;;;N;;;0052;;0052\n0073;LATIN SMALL LETTER S;Ll;0;L;;;;;N;;;0053;;0053\n0074;LATIN SMALL LETTER T;Ll;0;L;;;;;N;;;0054;;0054\n0075;LATIN SMALL LETTER U;Ll;0;L;;;;;N;;;0055;;0055\n0076;LATIN SMALL LETTER V;Ll;0;L;;;;;N;;;0056;;0056\n0077;LATIN SMALL LETTER W;Ll;0;L;;;;;N;;;0057;;0057\n0078;LATIN SMALL LETTER X;Ll;0;L;;;;;N;;;0058;;0058\n0079;LATIN SMALL LETTER Y;Ll;0;L;;;;;N;;;0059;;0059\n007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A\n007B;LEFT CURLY BRACKET;Ps;0;ON;;;;;Y;OPENING CURLY BRACKET;;;;\n007C;VERTICAL LINE;Sm;0;ON;;;;;N;VERTICAL BAR;;;;\n007D;RIGHT CURLY BRACKET;Pe;0;ON;;;;;Y;CLOSING CURLY BRACKET;;;;\n007E;TILDE;Sm;0;ON;;;;;N;;;;;\n007F;<control>;Cc;0;BN;;;;;N;DELETE;;;;\n0080;<control>;Cc;0;BN;;;;;N;;;;;\n0081;<control>;Cc;0;BN;;;;;N;;;;;\n0082;<control>;Cc;0;BN;;;;;N;BREAK PERMITTED HERE;;;;\n0083;<control>;Cc;0;BN;;;;;N;NO BREAK HERE;;;;\n0084;<control>;Cc;0;BN;;;;;N;;;;;\n0085;<control>;Cc;0;B;;;;;N;NEXT LINE (NEL);;;;\n0086;<control>;Cc;0;BN;;;;;N;START OF SELECTED AREA;;;;\n0087;<control>;Cc;0;BN;;;;;N;END OF SELECTED AREA;;;;\n0088;<control>;Cc;0;BN;;;;;N;CHARACTER TABULATION SET;;;;\n0089;<control>;Cc;0;BN;;;;;N;CHARACTER TABULATION WITH JUSTIFICATION;;;;\n008A;<control>;Cc;0;BN;;;;;N;LINE TABULATION SET;;;;\n008B;<control>;Cc;0;BN;;;;;N;PARTIAL LINE FORWARD;;;;\n008C;<control>;Cc;0;BN;;;;;N;PARTIAL LINE BACKWARD;;;;\n008D;<control>;Cc;0;BN;;;;;N;REVERSE LINE FEED;;;;\n008E;<control>;Cc;0;BN;;;;;N;SINGLE SHIFT TWO;;;;\n008F;<control>;Cc;0;BN;;;;;N;SINGLE SHIFT THREE;;;;\n0090;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL STRING;;;;\n0091;<control>;Cc;0;BN;;;;;N;PRIVATE USE ONE;;;;\n0092;<control>;Cc;0;BN;;;;;N;PRIVATE USE TWO;;;;\n0093;<control>;Cc;0;BN;;;;;N;SET TRANSMIT STATE;;;;\n0094;<control>;Cc;0;BN;;;;;N;CANCEL CHARACTER;;;;\n0095;<control>;Cc;0;BN;;;;;N;MESSAGE WAITING;;;;\n0096;<control>;Cc;0;BN;;;;;N;START OF GUARDED AREA;;;;\n0097;<control>;Cc;0;BN;;;;;N;END OF GUARDED AREA;;;;\n0098;<control>;Cc;0;BN;;;;;N;START OF STRING;;;;\n0099;<control>;Cc;0;BN;;;;;N;;;;;\n009A;<control>;Cc;0;BN;;;;;N;SINGLE CHARACTER INTRODUCER;;;;\n009B;<control>;Cc;0;BN;;;;;N;CONTROL SEQUENCE INTRODUCER;;;;\n009C;<control>;Cc;0;BN;;;;;N;STRING TERMINATOR;;;;\n009D;<control>;Cc;0;BN;;;;;N;OPERATING SYSTEM COMMAND;;;;\n009E;<control>;Cc;0;BN;;;;;N;PRIVACY MESSAGE;;;;\n009F;<control>;Cc;0;BN;;;;;N;APPLICATION PROGRAM COMMAND;;;;\n00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;\n00A1;INVERTED EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;\n00A2;CENT SIGN;Sc;0;ET;;;;;N;;;;;\n00A3;POUND SIGN;Sc;0;ET;;;;;N;;;;;\n00A4;CURRENCY SIGN;Sc;0;ET;;;;;N;;;;;\n00A5;YEN SIGN;Sc;0;ET;;;;;N;;;;;\n00A6;BROKEN BAR;So;0;ON;;;;;N;BROKEN VERTICAL BAR;;;;\n00A7;SECTION SIGN;Po;0;ON;;;;;N;;;;;\n00A8;DIAERESIS;Sk;0;ON;<compat> 0020 0308;;;;N;SPACING DIAERESIS;;;;\n00A9;COPYRIGHT SIGN;So;0;ON;;;;;N;;;;;\n00AA;FEMININE ORDINAL INDICATOR;Lo;0;L;<super> 0061;;;;N;;;;;\n00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;;;;\n00AC;NOT SIGN;Sm;0;ON;;;;;N;;;;;\n00AD;SOFT HYPHEN;Cf;0;BN;;;;;N;;;;;\n00AE;REGISTERED SIGN;So;0;ON;;;;;N;REGISTERED TRADE MARK SIGN;;;;\n00AF;MACRON;Sk;0;ON;<compat> 0020 0304;;;;N;SPACING MACRON;;;;\n00B0;DEGREE SIGN;So;0;ET;;;;;N;;;;;\n00B1;PLUS-MINUS SIGN;Sm;0;ET;;;;;N;PLUS-OR-MINUS SIGN;;;;\n00B2;SUPERSCRIPT TWO;No;0;EN;<super> 0032;;2;2;N;SUPERSCRIPT DIGIT TWO;;;;\n00B3;SUPERSCRIPT THREE;No;0;EN;<super> 0033;;3;3;N;SUPERSCRIPT DIGIT THREE;;;;\n00B4;ACUTE ACCENT;Sk;0;ON;<compat> 0020 0301;;;;N;SPACING ACUTE;;;;\n00B5;MICRO SIGN;Ll;0;L;<compat> 03BC;;;;N;;;039C;;039C\n00B6;PILCROW SIGN;Po;0;ON;;;;;N;PARAGRAPH SIGN;;;;\n00B7;MIDDLE DOT;Po;0;ON;;;;;N;;;;;\n00B8;CEDILLA;Sk;0;ON;<compat> 0020 0327;;;;N;SPACING CEDILLA;;;;\n00B9;SUPERSCRIPT ONE;No;0;EN;<super> 0031;;1;1;N;SUPERSCRIPT DIGIT ONE;;;;\n00BA;MASCULINE ORDINAL INDICATOR;Lo;0;L;<super> 006F;;;;N;;;;;\n00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;;;;\n00BC;VULGAR FRACTION ONE QUARTER;No;0;ON;<fraction> 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;;\n00BD;VULGAR FRACTION ONE HALF;No;0;ON;<fraction> 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;;\n00BE;VULGAR FRACTION THREE QUARTERS;No;0;ON;<fraction> 0033 2044 0034;;;3/4;N;FRACTION THREE QUARTERS;;;;\n00BF;INVERTED QUESTION MARK;Po;0;ON;;;;;N;;;;;\n00C0;LATIN CAPITAL LETTER A WITH GRAVE;Lu;0;L;0041 0300;;;;N;LATIN CAPITAL LETTER A GRAVE;;;00E0;\n00C1;LATIN CAPITAL LETTER A WITH ACUTE;Lu;0;L;0041 0301;;;;N;LATIN CAPITAL LETTER A ACUTE;;;00E1;\n00C2;LATIN CAPITAL LETTER A WITH CIRCUMFLEX;Lu;0;L;0041 0302;;;;N;LATIN CAPITAL LETTER A CIRCUMFLEX;;;00E2;\n00C3;LATIN CAPITAL LETTER A WITH TILDE;Lu;0;L;0041 0303;;;;N;LATIN CAPITAL LETTER A TILDE;;;00E3;\n00C4;LATIN CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0041 0308;;;;N;LATIN CAPITAL LETTER A DIAERESIS;;;00E4;\n00C5;LATIN CAPITAL LETTER A WITH RING ABOVE;Lu;0;L;0041 030A;;;;N;LATIN CAPITAL LETTER A RING;;;00E5;\n00C6;LATIN CAPITAL LETTER AE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER A E;;;00E6;\n00C7;LATIN CAPITAL LETTER C WITH CEDILLA;Lu;0;L;0043 0327;;;;N;LATIN CAPITAL LETTER C CEDILLA;;;00E7;\n00C8;LATIN CAPITAL LETTER E WITH GRAVE;Lu;0;L;0045 0300;;;;N;LATIN CAPITAL LETTER E GRAVE;;;00E8;\n00C9;LATIN CAPITAL LETTER E WITH ACUTE;Lu;0;L;0045 0301;;;;N;LATIN CAPITAL LETTER E ACUTE;;;00E9;\n00CA;LATIN CAPITAL LETTER E WITH CIRCUMFLEX;Lu;0;L;0045 0302;;;;N;LATIN CAPITAL LETTER E CIRCUMFLEX;;;00EA;\n00CB;LATIN CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;0045 0308;;;;N;LATIN CAPITAL LETTER E DIAERESIS;;;00EB;\n00CC;LATIN CAPITAL LETTER I WITH GRAVE;Lu;0;L;0049 0300;;;;N;LATIN CAPITAL LETTER I GRAVE;;;00EC;\n00CD;LATIN CAPITAL LETTER I WITH ACUTE;Lu;0;L;0049 0301;;;;N;LATIN CAPITAL LETTER I ACUTE;;;00ED;\n00CE;LATIN CAPITAL LETTER I WITH CIRCUMFLEX;Lu;0;L;0049 0302;;;;N;LATIN CAPITAL LETTER I CIRCUMFLEX;;;00EE;\n00CF;LATIN CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0049 0308;;;;N;LATIN CAPITAL LETTER I DIAERESIS;;;00EF;\n00D0;LATIN CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;00F0;\n00D1;LATIN CAPITAL LETTER N WITH TILDE;Lu;0;L;004E 0303;;;;N;LATIN CAPITAL LETTER N TILDE;;;00F1;\n00D2;LATIN CAPITAL LETTER O WITH GRAVE;Lu;0;L;004F 0300;;;;N;LATIN CAPITAL LETTER O GRAVE;;;00F2;\n00D3;LATIN CAPITAL LETTER O WITH ACUTE;Lu;0;L;004F 0301;;;;N;LATIN CAPITAL LETTER O ACUTE;;;00F3;\n00D4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX;Lu;0;L;004F 0302;;;;N;LATIN CAPITAL LETTER O CIRCUMFLEX;;;00F4;\n00D5;LATIN CAPITAL LETTER O WITH TILDE;Lu;0;L;004F 0303;;;;N;LATIN CAPITAL LETTER O TILDE;;;00F5;\n00D6;LATIN CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;004F 0308;;;;N;LATIN CAPITAL LETTER O DIAERESIS;;;00F6;\n00D7;MULTIPLICATION SIGN;Sm;0;ON;;;;;N;;;;;\n00D8;LATIN CAPITAL LETTER O WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O SLASH;;;00F8;\n00D9;LATIN CAPITAL LETTER U WITH GRAVE;Lu;0;L;0055 0300;;;;N;LATIN CAPITAL LETTER U GRAVE;;;00F9;\n00DA;LATIN CAPITAL LETTER U WITH ACUTE;Lu;0;L;0055 0301;;;;N;LATIN CAPITAL LETTER U ACUTE;;;00FA;\n00DB;LATIN CAPITAL LETTER U WITH CIRCUMFLEX;Lu;0;L;0055 0302;;;;N;LATIN CAPITAL LETTER U CIRCUMFLEX;;;00FB;\n00DC;LATIN CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0055 0308;;;;N;LATIN CAPITAL LETTER U DIAERESIS;;;00FC;\n00DD;LATIN CAPITAL LETTER Y WITH ACUTE;Lu;0;L;0059 0301;;;;N;LATIN CAPITAL LETTER Y ACUTE;;;00FD;\n00DE;LATIN CAPITAL LETTER THORN;Lu;0;L;;;;;N;;;;00FE;\n00DF;LATIN SMALL LETTER SHARP S;Ll;0;L;;;;;N;;;;;\n00E0;LATIN SMALL LETTER A WITH GRAVE;Ll;0;L;0061 0300;;;;N;LATIN SMALL LETTER A GRAVE;;00C0;;00C0\n00E1;LATIN SMALL LETTER A WITH ACUTE;Ll;0;L;0061 0301;;;;N;LATIN SMALL LETTER A ACUTE;;00C1;;00C1\n00E2;LATIN SMALL LETTER A WITH CIRCUMFLEX;Ll;0;L;0061 0302;;;;N;LATIN SMALL LETTER A CIRCUMFLEX;;00C2;;00C2\n00E3;LATIN SMALL LETTER A WITH TILDE;Ll;0;L;0061 0303;;;;N;LATIN SMALL LETTER A TILDE;;00C3;;00C3\n00E4;LATIN SMALL LETTER A WITH DIAERESIS;Ll;0;L;0061 0308;;;;N;LATIN SMALL LETTER A DIAERESIS;;00C4;;00C4\n00E5;LATIN SMALL LETTER A WITH RING ABOVE;Ll;0;L;0061 030A;;;;N;LATIN SMALL LETTER A RING;;00C5;;00C5\n00E6;LATIN SMALL LETTER AE;Ll;0;L;;;;;N;LATIN SMALL LETTER A E;;00C6;;00C6\n00E7;LATIN SMALL LETTER C WITH CEDILLA;Ll;0;L;0063 0327;;;;N;LATIN SMALL LETTER C CEDILLA;;00C7;;00C7\n00E8;LATIN SMALL LETTER E WITH GRAVE;Ll;0;L;0065 0300;;;;N;LATIN SMALL LETTER E GRAVE;;00C8;;00C8\n00E9;LATIN SMALL LETTER E WITH ACUTE;Ll;0;L;0065 0301;;;;N;LATIN SMALL LETTER E ACUTE;;00C9;;00C9\n00EA;LATIN SMALL LETTER E WITH CIRCUMFLEX;Ll;0;L;0065 0302;;;;N;LATIN SMALL LETTER E CIRCUMFLEX;;00CA;;00CA\n00EB;LATIN SMALL LETTER E WITH DIAERESIS;Ll;0;L;0065 0308;;;;N;LATIN SMALL LETTER E DIAERESIS;;00CB;;00CB\n00EC;LATIN SMALL LETTER I WITH GRAVE;Ll;0;L;0069 0300;;;;N;LATIN SMALL LETTER I GRAVE;;00CC;;00CC\n00ED;LATIN SMALL LETTER I WITH ACUTE;Ll;0;L;0069 0301;;;;N;LATIN SMALL LETTER I ACUTE;;00CD;;00CD\n00EE;LATIN SMALL LETTER I WITH CIRCUMFLEX;Ll;0;L;0069 0302;;;;N;LATIN SMALL LETTER I CIRCUMFLEX;;00CE;;00CE\n00EF;LATIN SMALL LETTER I WITH DIAERESIS;Ll;0;L;0069 0308;;;;N;LATIN SMALL LETTER I DIAERESIS;;00CF;;00CF\n00F0;LATIN SMALL LETTER ETH;Ll;0;L;;;;;N;;;00D0;;00D0\n00F1;LATIN SMALL LETTER N WITH TILDE;Ll;0;L;006E 0303;;;;N;LATIN SMALL LETTER N TILDE;;00D1;;00D1\n00F2;LATIN SMALL LETTER O WITH GRAVE;Ll;0;L;006F 0300;;;;N;LATIN SMALL LETTER O GRAVE;;00D2;;00D2\n00F3;LATIN SMALL LETTER O WITH ACUTE;Ll;0;L;006F 0301;;;;N;LATIN SMALL LETTER O ACUTE;;00D3;;00D3\n00F4;LATIN SMALL LETTER O WITH CIRCUMFLEX;Ll;0;L;006F 0302;;;;N;LATIN SMALL LETTER O CIRCUMFLEX;;00D4;;00D4\n00F5;LATIN SMALL LETTER O WITH TILDE;Ll;0;L;006F 0303;;;;N;LATIN SMALL LETTER O TILDE;;00D5;;00D5\n00F6;LATIN SMALL LETTER O WITH DIAERESIS;Ll;0;L;006F 0308;;;;N;LATIN SMALL LETTER O DIAERESIS;;00D6;;00D6\n00F7;DIVISION SIGN;Sm;0;ON;;;;;N;;;;;\n00F8;LATIN SMALL LETTER O WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER O SLASH;;00D8;;00D8\n00F9;LATIN SMALL LETTER U WITH GRAVE;Ll;0;L;0075 0300;;;;N;LATIN SMALL LETTER U GRAVE;;00D9;;00D9\n00FA;LATIN SMALL LETTER U WITH ACUTE;Ll;0;L;0075 0301;;;;N;LATIN SMALL LETTER U ACUTE;;00DA;;00DA\n00FB;LATIN SMALL LETTER U WITH CIRCUMFLEX;Ll;0;L;0075 0302;;;;N;LATIN SMALL LETTER U CIRCUMFLEX;;00DB;;00DB\n00FC;LATIN SMALL LETTER U WITH DIAERESIS;Ll;0;L;0075 0308;;;;N;LATIN SMALL LETTER U DIAERESIS;;00DC;;00DC\n00FD;LATIN SMALL LETTER Y WITH ACUTE;Ll;0;L;0079 0301;;;;N;LATIN SMALL LETTER Y ACUTE;;00DD;;00DD\n00FE;LATIN SMALL LETTER THORN;Ll;0;L;;;;;N;;;00DE;;00DE\n00FF;LATIN SMALL LETTER Y WITH DIAERESIS;Ll;0;L;0079 0308;;;;N;LATIN SMALL LETTER Y DIAERESIS;;0178;;0178\n"
  },
  {
    "path": "react_juce/duktape/src-input/UnicodeData.txt",
    "content": "0000;<control>;Cc;0;BN;;;;;N;NULL;;;;\n0001;<control>;Cc;0;BN;;;;;N;START OF HEADING;;;;\n0002;<control>;Cc;0;BN;;;;;N;START OF TEXT;;;;\n0003;<control>;Cc;0;BN;;;;;N;END OF TEXT;;;;\n0004;<control>;Cc;0;BN;;;;;N;END OF TRANSMISSION;;;;\n0005;<control>;Cc;0;BN;;;;;N;ENQUIRY;;;;\n0006;<control>;Cc;0;BN;;;;;N;ACKNOWLEDGE;;;;\n0007;<control>;Cc;0;BN;;;;;N;BELL;;;;\n0008;<control>;Cc;0;BN;;;;;N;BACKSPACE;;;;\n0009;<control>;Cc;0;S;;;;;N;CHARACTER TABULATION;;;;\n000A;<control>;Cc;0;B;;;;;N;LINE FEED (LF);;;;\n000B;<control>;Cc;0;S;;;;;N;LINE TABULATION;;;;\n000C;<control>;Cc;0;WS;;;;;N;FORM FEED (FF);;;;\n000D;<control>;Cc;0;B;;;;;N;CARRIAGE RETURN (CR);;;;\n000E;<control>;Cc;0;BN;;;;;N;SHIFT OUT;;;;\n000F;<control>;Cc;0;BN;;;;;N;SHIFT IN;;;;\n0010;<control>;Cc;0;BN;;;;;N;DATA LINK ESCAPE;;;;\n0011;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL ONE;;;;\n0012;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL TWO;;;;\n0013;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL THREE;;;;\n0014;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL FOUR;;;;\n0015;<control>;Cc;0;BN;;;;;N;NEGATIVE ACKNOWLEDGE;;;;\n0016;<control>;Cc;0;BN;;;;;N;SYNCHRONOUS IDLE;;;;\n0017;<control>;Cc;0;BN;;;;;N;END OF TRANSMISSION BLOCK;;;;\n0018;<control>;Cc;0;BN;;;;;N;CANCEL;;;;\n0019;<control>;Cc;0;BN;;;;;N;END OF MEDIUM;;;;\n001A;<control>;Cc;0;BN;;;;;N;SUBSTITUTE;;;;\n001B;<control>;Cc;0;BN;;;;;N;ESCAPE;;;;\n001C;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR FOUR;;;;\n001D;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR THREE;;;;\n001E;<control>;Cc;0;B;;;;;N;INFORMATION SEPARATOR TWO;;;;\n001F;<control>;Cc;0;S;;;;;N;INFORMATION SEPARATOR ONE;;;;\n0020;SPACE;Zs;0;WS;;;;;N;;;;;\n0021;EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;\n0022;QUOTATION MARK;Po;0;ON;;;;;N;;;;;\n0023;NUMBER SIGN;Po;0;ET;;;;;N;;;;;\n0024;DOLLAR SIGN;Sc;0;ET;;;;;N;;;;;\n0025;PERCENT SIGN;Po;0;ET;;;;;N;;;;;\n0026;AMPERSAND;Po;0;ON;;;;;N;;;;;\n0027;APOSTROPHE;Po;0;ON;;;;;N;APOSTROPHE-QUOTE;;;;\n0028;LEFT PARENTHESIS;Ps;0;ON;;;;;Y;OPENING PARENTHESIS;;;;\n0029;RIGHT PARENTHESIS;Pe;0;ON;;;;;Y;CLOSING PARENTHESIS;;;;\n002A;ASTERISK;Po;0;ON;;;;;N;;;;;\n002B;PLUS SIGN;Sm;0;ES;;;;;N;;;;;\n002C;COMMA;Po;0;CS;;;;;N;;;;;\n002D;HYPHEN-MINUS;Pd;0;ES;;;;;N;;;;;\n002E;FULL STOP;Po;0;CS;;;;;N;PERIOD;;;;\n002F;SOLIDUS;Po;0;CS;;;;;N;SLASH;;;;\n0030;DIGIT ZERO;Nd;0;EN;;0;0;0;N;;;;;\n0031;DIGIT ONE;Nd;0;EN;;1;1;1;N;;;;;\n0032;DIGIT TWO;Nd;0;EN;;2;2;2;N;;;;;\n0033;DIGIT THREE;Nd;0;EN;;3;3;3;N;;;;;\n0034;DIGIT FOUR;Nd;0;EN;;4;4;4;N;;;;;\n0035;DIGIT FIVE;Nd;0;EN;;5;5;5;N;;;;;\n0036;DIGIT SIX;Nd;0;EN;;6;6;6;N;;;;;\n0037;DIGIT SEVEN;Nd;0;EN;;7;7;7;N;;;;;\n0038;DIGIT EIGHT;Nd;0;EN;;8;8;8;N;;;;;\n0039;DIGIT NINE;Nd;0;EN;;9;9;9;N;;;;;\n003A;COLON;Po;0;CS;;;;;N;;;;;\n003B;SEMICOLON;Po;0;ON;;;;;N;;;;;\n003C;LESS-THAN SIGN;Sm;0;ON;;;;;Y;;;;;\n003D;EQUALS SIGN;Sm;0;ON;;;;;N;;;;;\n003E;GREATER-THAN SIGN;Sm;0;ON;;;;;Y;;;;;\n003F;QUESTION MARK;Po;0;ON;;;;;N;;;;;\n0040;COMMERCIAL AT;Po;0;ON;;;;;N;;;;;\n0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061;\n0042;LATIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;0062;\n0043;LATIN CAPITAL LETTER C;Lu;0;L;;;;;N;;;;0063;\n0044;LATIN CAPITAL LETTER D;Lu;0;L;;;;;N;;;;0064;\n0045;LATIN CAPITAL LETTER E;Lu;0;L;;;;;N;;;;0065;\n0046;LATIN CAPITAL LETTER F;Lu;0;L;;;;;N;;;;0066;\n0047;LATIN CAPITAL LETTER G;Lu;0;L;;;;;N;;;;0067;\n0048;LATIN CAPITAL LETTER H;Lu;0;L;;;;;N;;;;0068;\n0049;LATIN CAPITAL LETTER I;Lu;0;L;;;;;N;;;;0069;\n004A;LATIN CAPITAL LETTER J;Lu;0;L;;;;;N;;;;006A;\n004B;LATIN CAPITAL LETTER K;Lu;0;L;;;;;N;;;;006B;\n004C;LATIN CAPITAL LETTER L;Lu;0;L;;;;;N;;;;006C;\n004D;LATIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;006D;\n004E;LATIN CAPITAL LETTER N;Lu;0;L;;;;;N;;;;006E;\n004F;LATIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;006F;\n0050;LATIN CAPITAL LETTER P;Lu;0;L;;;;;N;;;;0070;\n0051;LATIN CAPITAL LETTER Q;Lu;0;L;;;;;N;;;;0071;\n0052;LATIN CAPITAL LETTER R;Lu;0;L;;;;;N;;;;0072;\n0053;LATIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;0073;\n0054;LATIN CAPITAL LETTER T;Lu;0;L;;;;;N;;;;0074;\n0055;LATIN CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0075;\n0056;LATIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;0076;\n0057;LATIN CAPITAL LETTER W;Lu;0;L;;;;;N;;;;0077;\n0058;LATIN CAPITAL LETTER X;Lu;0;L;;;;;N;;;;0078;\n0059;LATIN CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;0079;\n005A;LATIN CAPITAL LETTER Z;Lu;0;L;;;;;N;;;;007A;\n005B;LEFT SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING SQUARE BRACKET;;;;\n005C;REVERSE SOLIDUS;Po;0;ON;;;;;N;BACKSLASH;;;;\n005D;RIGHT SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING SQUARE BRACKET;;;;\n005E;CIRCUMFLEX ACCENT;Sk;0;ON;;;;;N;SPACING CIRCUMFLEX;;;;\n005F;LOW LINE;Pc;0;ON;;;;;N;SPACING UNDERSCORE;;;;\n0060;GRAVE ACCENT;Sk;0;ON;;;;;N;SPACING GRAVE;;;;\n0061;LATIN SMALL LETTER A;Ll;0;L;;;;;N;;;0041;;0041\n0062;LATIN SMALL LETTER B;Ll;0;L;;;;;N;;;0042;;0042\n0063;LATIN SMALL LETTER C;Ll;0;L;;;;;N;;;0043;;0043\n0064;LATIN SMALL LETTER D;Ll;0;L;;;;;N;;;0044;;0044\n0065;LATIN SMALL LETTER E;Ll;0;L;;;;;N;;;0045;;0045\n0066;LATIN SMALL LETTER F;Ll;0;L;;;;;N;;;0046;;0046\n0067;LATIN SMALL LETTER G;Ll;0;L;;;;;N;;;0047;;0047\n0068;LATIN SMALL LETTER H;Ll;0;L;;;;;N;;;0048;;0048\n0069;LATIN SMALL LETTER I;Ll;0;L;;;;;N;;;0049;;0049\n006A;LATIN SMALL LETTER J;Ll;0;L;;;;;N;;;004A;;004A\n006B;LATIN SMALL LETTER K;Ll;0;L;;;;;N;;;004B;;004B\n006C;LATIN SMALL LETTER L;Ll;0;L;;;;;N;;;004C;;004C\n006D;LATIN SMALL LETTER M;Ll;0;L;;;;;N;;;004D;;004D\n006E;LATIN SMALL LETTER N;Ll;0;L;;;;;N;;;004E;;004E\n006F;LATIN SMALL LETTER O;Ll;0;L;;;;;N;;;004F;;004F\n0070;LATIN SMALL LETTER P;Ll;0;L;;;;;N;;;0050;;0050\n0071;LATIN SMALL LETTER Q;Ll;0;L;;;;;N;;;0051;;0051\n0072;LATIN SMALL LETTER R;Ll;0;L;;;;;N;;;0052;;0052\n0073;LATIN SMALL LETTER S;Ll;0;L;;;;;N;;;0053;;0053\n0074;LATIN SMALL LETTER T;Ll;0;L;;;;;N;;;0054;;0054\n0075;LATIN SMALL LETTER U;Ll;0;L;;;;;N;;;0055;;0055\n0076;LATIN SMALL LETTER V;Ll;0;L;;;;;N;;;0056;;0056\n0077;LATIN SMALL LETTER W;Ll;0;L;;;;;N;;;0057;;0057\n0078;LATIN SMALL LETTER X;Ll;0;L;;;;;N;;;0058;;0058\n0079;LATIN SMALL LETTER Y;Ll;0;L;;;;;N;;;0059;;0059\n007A;LATIN SMALL LETTER Z;Ll;0;L;;;;;N;;;005A;;005A\n007B;LEFT CURLY BRACKET;Ps;0;ON;;;;;Y;OPENING CURLY BRACKET;;;;\n007C;VERTICAL LINE;Sm;0;ON;;;;;N;VERTICAL BAR;;;;\n007D;RIGHT CURLY BRACKET;Pe;0;ON;;;;;Y;CLOSING CURLY BRACKET;;;;\n007E;TILDE;Sm;0;ON;;;;;N;;;;;\n007F;<control>;Cc;0;BN;;;;;N;DELETE;;;;\n0080;<control>;Cc;0;BN;;;;;N;;;;;\n0081;<control>;Cc;0;BN;;;;;N;;;;;\n0082;<control>;Cc;0;BN;;;;;N;BREAK PERMITTED HERE;;;;\n0083;<control>;Cc;0;BN;;;;;N;NO BREAK HERE;;;;\n0084;<control>;Cc;0;BN;;;;;N;;;;;\n0085;<control>;Cc;0;B;;;;;N;NEXT LINE (NEL);;;;\n0086;<control>;Cc;0;BN;;;;;N;START OF SELECTED AREA;;;;\n0087;<control>;Cc;0;BN;;;;;N;END OF SELECTED AREA;;;;\n0088;<control>;Cc;0;BN;;;;;N;CHARACTER TABULATION SET;;;;\n0089;<control>;Cc;0;BN;;;;;N;CHARACTER TABULATION WITH JUSTIFICATION;;;;\n008A;<control>;Cc;0;BN;;;;;N;LINE TABULATION SET;;;;\n008B;<control>;Cc;0;BN;;;;;N;PARTIAL LINE FORWARD;;;;\n008C;<control>;Cc;0;BN;;;;;N;PARTIAL LINE BACKWARD;;;;\n008D;<control>;Cc;0;BN;;;;;N;REVERSE LINE FEED;;;;\n008E;<control>;Cc;0;BN;;;;;N;SINGLE SHIFT TWO;;;;\n008F;<control>;Cc;0;BN;;;;;N;SINGLE SHIFT THREE;;;;\n0090;<control>;Cc;0;BN;;;;;N;DEVICE CONTROL STRING;;;;\n0091;<control>;Cc;0;BN;;;;;N;PRIVATE USE ONE;;;;\n0092;<control>;Cc;0;BN;;;;;N;PRIVATE USE TWO;;;;\n0093;<control>;Cc;0;BN;;;;;N;SET TRANSMIT STATE;;;;\n0094;<control>;Cc;0;BN;;;;;N;CANCEL CHARACTER;;;;\n0095;<control>;Cc;0;BN;;;;;N;MESSAGE WAITING;;;;\n0096;<control>;Cc;0;BN;;;;;N;START OF GUARDED AREA;;;;\n0097;<control>;Cc;0;BN;;;;;N;END OF GUARDED AREA;;;;\n0098;<control>;Cc;0;BN;;;;;N;START OF STRING;;;;\n0099;<control>;Cc;0;BN;;;;;N;;;;;\n009A;<control>;Cc;0;BN;;;;;N;SINGLE CHARACTER INTRODUCER;;;;\n009B;<control>;Cc;0;BN;;;;;N;CONTROL SEQUENCE INTRODUCER;;;;\n009C;<control>;Cc;0;BN;;;;;N;STRING TERMINATOR;;;;\n009D;<control>;Cc;0;BN;;;;;N;OPERATING SYSTEM COMMAND;;;;\n009E;<control>;Cc;0;BN;;;;;N;PRIVACY MESSAGE;;;;\n009F;<control>;Cc;0;BN;;;;;N;APPLICATION PROGRAM COMMAND;;;;\n00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;\n00A1;INVERTED EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;\n00A2;CENT SIGN;Sc;0;ET;;;;;N;;;;;\n00A3;POUND SIGN;Sc;0;ET;;;;;N;;;;;\n00A4;CURRENCY SIGN;Sc;0;ET;;;;;N;;;;;\n00A5;YEN SIGN;Sc;0;ET;;;;;N;;;;;\n00A6;BROKEN BAR;So;0;ON;;;;;N;BROKEN VERTICAL BAR;;;;\n00A7;SECTION SIGN;Po;0;ON;;;;;N;;;;;\n00A8;DIAERESIS;Sk;0;ON;<compat> 0020 0308;;;;N;SPACING DIAERESIS;;;;\n00A9;COPYRIGHT SIGN;So;0;ON;;;;;N;;;;;\n00AA;FEMININE ORDINAL INDICATOR;Lo;0;L;<super> 0061;;;;N;;;;;\n00AB;LEFT-POINTING DOUBLE ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING GUILLEMET;;;;\n00AC;NOT SIGN;Sm;0;ON;;;;;N;;;;;\n00AD;SOFT HYPHEN;Cf;0;BN;;;;;N;;;;;\n00AE;REGISTERED SIGN;So;0;ON;;;;;N;REGISTERED TRADE MARK SIGN;;;;\n00AF;MACRON;Sk;0;ON;<compat> 0020 0304;;;;N;SPACING MACRON;;;;\n00B0;DEGREE SIGN;So;0;ET;;;;;N;;;;;\n00B1;PLUS-MINUS SIGN;Sm;0;ET;;;;;N;PLUS-OR-MINUS SIGN;;;;\n00B2;SUPERSCRIPT TWO;No;0;EN;<super> 0032;;2;2;N;SUPERSCRIPT DIGIT TWO;;;;\n00B3;SUPERSCRIPT THREE;No;0;EN;<super> 0033;;3;3;N;SUPERSCRIPT DIGIT THREE;;;;\n00B4;ACUTE ACCENT;Sk;0;ON;<compat> 0020 0301;;;;N;SPACING ACUTE;;;;\n00B5;MICRO SIGN;Ll;0;L;<compat> 03BC;;;;N;;;039C;;039C\n00B6;PILCROW SIGN;Po;0;ON;;;;;N;PARAGRAPH SIGN;;;;\n00B7;MIDDLE DOT;Po;0;ON;;;;;N;;;;;\n00B8;CEDILLA;Sk;0;ON;<compat> 0020 0327;;;;N;SPACING CEDILLA;;;;\n00B9;SUPERSCRIPT ONE;No;0;EN;<super> 0031;;1;1;N;SUPERSCRIPT DIGIT ONE;;;;\n00BA;MASCULINE ORDINAL INDICATOR;Lo;0;L;<super> 006F;;;;N;;;;;\n00BB;RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING GUILLEMET;;;;\n00BC;VULGAR FRACTION ONE QUARTER;No;0;ON;<fraction> 0031 2044 0034;;;1/4;N;FRACTION ONE QUARTER;;;;\n00BD;VULGAR FRACTION ONE HALF;No;0;ON;<fraction> 0031 2044 0032;;;1/2;N;FRACTION ONE HALF;;;;\n00BE;VULGAR FRACTION THREE QUARTERS;No;0;ON;<fraction> 0033 2044 0034;;;3/4;N;FRACTION THREE QUARTERS;;;;\n00BF;INVERTED QUESTION MARK;Po;0;ON;;;;;N;;;;;\n00C0;LATIN CAPITAL LETTER A WITH GRAVE;Lu;0;L;0041 0300;;;;N;LATIN CAPITAL LETTER A GRAVE;;;00E0;\n00C1;LATIN CAPITAL LETTER A WITH ACUTE;Lu;0;L;0041 0301;;;;N;LATIN CAPITAL LETTER A ACUTE;;;00E1;\n00C2;LATIN CAPITAL LETTER A WITH CIRCUMFLEX;Lu;0;L;0041 0302;;;;N;LATIN CAPITAL LETTER A CIRCUMFLEX;;;00E2;\n00C3;LATIN CAPITAL LETTER A WITH TILDE;Lu;0;L;0041 0303;;;;N;LATIN CAPITAL LETTER A TILDE;;;00E3;\n00C4;LATIN CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0041 0308;;;;N;LATIN CAPITAL LETTER A DIAERESIS;;;00E4;\n00C5;LATIN CAPITAL LETTER A WITH RING ABOVE;Lu;0;L;0041 030A;;;;N;LATIN CAPITAL LETTER A RING;;;00E5;\n00C6;LATIN CAPITAL LETTER AE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER A E;;;00E6;\n00C7;LATIN CAPITAL LETTER C WITH CEDILLA;Lu;0;L;0043 0327;;;;N;LATIN CAPITAL LETTER C CEDILLA;;;00E7;\n00C8;LATIN CAPITAL LETTER E WITH GRAVE;Lu;0;L;0045 0300;;;;N;LATIN CAPITAL LETTER E GRAVE;;;00E8;\n00C9;LATIN CAPITAL LETTER E WITH ACUTE;Lu;0;L;0045 0301;;;;N;LATIN CAPITAL LETTER E ACUTE;;;00E9;\n00CA;LATIN CAPITAL LETTER E WITH CIRCUMFLEX;Lu;0;L;0045 0302;;;;N;LATIN CAPITAL LETTER E CIRCUMFLEX;;;00EA;\n00CB;LATIN CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;0045 0308;;;;N;LATIN CAPITAL LETTER E DIAERESIS;;;00EB;\n00CC;LATIN CAPITAL LETTER I WITH GRAVE;Lu;0;L;0049 0300;;;;N;LATIN CAPITAL LETTER I GRAVE;;;00EC;\n00CD;LATIN CAPITAL LETTER I WITH ACUTE;Lu;0;L;0049 0301;;;;N;LATIN CAPITAL LETTER I ACUTE;;;00ED;\n00CE;LATIN CAPITAL LETTER I WITH CIRCUMFLEX;Lu;0;L;0049 0302;;;;N;LATIN CAPITAL LETTER I CIRCUMFLEX;;;00EE;\n00CF;LATIN CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0049 0308;;;;N;LATIN CAPITAL LETTER I DIAERESIS;;;00EF;\n00D0;LATIN CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;00F0;\n00D1;LATIN CAPITAL LETTER N WITH TILDE;Lu;0;L;004E 0303;;;;N;LATIN CAPITAL LETTER N TILDE;;;00F1;\n00D2;LATIN CAPITAL LETTER O WITH GRAVE;Lu;0;L;004F 0300;;;;N;LATIN CAPITAL LETTER O GRAVE;;;00F2;\n00D3;LATIN CAPITAL LETTER O WITH ACUTE;Lu;0;L;004F 0301;;;;N;LATIN CAPITAL LETTER O ACUTE;;;00F3;\n00D4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX;Lu;0;L;004F 0302;;;;N;LATIN CAPITAL LETTER O CIRCUMFLEX;;;00F4;\n00D5;LATIN CAPITAL LETTER O WITH TILDE;Lu;0;L;004F 0303;;;;N;LATIN CAPITAL LETTER O TILDE;;;00F5;\n00D6;LATIN CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;004F 0308;;;;N;LATIN CAPITAL LETTER O DIAERESIS;;;00F6;\n00D7;MULTIPLICATION SIGN;Sm;0;ON;;;;;N;;;;;\n00D8;LATIN CAPITAL LETTER O WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O SLASH;;;00F8;\n00D9;LATIN CAPITAL LETTER U WITH GRAVE;Lu;0;L;0055 0300;;;;N;LATIN CAPITAL LETTER U GRAVE;;;00F9;\n00DA;LATIN CAPITAL LETTER U WITH ACUTE;Lu;0;L;0055 0301;;;;N;LATIN CAPITAL LETTER U ACUTE;;;00FA;\n00DB;LATIN CAPITAL LETTER U WITH CIRCUMFLEX;Lu;0;L;0055 0302;;;;N;LATIN CAPITAL LETTER U CIRCUMFLEX;;;00FB;\n00DC;LATIN CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0055 0308;;;;N;LATIN CAPITAL LETTER U DIAERESIS;;;00FC;\n00DD;LATIN CAPITAL LETTER Y WITH ACUTE;Lu;0;L;0059 0301;;;;N;LATIN CAPITAL LETTER Y ACUTE;;;00FD;\n00DE;LATIN CAPITAL LETTER THORN;Lu;0;L;;;;;N;;;;00FE;\n00DF;LATIN SMALL LETTER SHARP S;Ll;0;L;;;;;N;;;;;\n00E0;LATIN SMALL LETTER A WITH GRAVE;Ll;0;L;0061 0300;;;;N;LATIN SMALL LETTER A GRAVE;;00C0;;00C0\n00E1;LATIN SMALL LETTER A WITH ACUTE;Ll;0;L;0061 0301;;;;N;LATIN SMALL LETTER A ACUTE;;00C1;;00C1\n00E2;LATIN SMALL LETTER A WITH CIRCUMFLEX;Ll;0;L;0061 0302;;;;N;LATIN SMALL LETTER A CIRCUMFLEX;;00C2;;00C2\n00E3;LATIN SMALL LETTER A WITH TILDE;Ll;0;L;0061 0303;;;;N;LATIN SMALL LETTER A TILDE;;00C3;;00C3\n00E4;LATIN SMALL LETTER A WITH DIAERESIS;Ll;0;L;0061 0308;;;;N;LATIN SMALL LETTER A DIAERESIS;;00C4;;00C4\n00E5;LATIN SMALL LETTER A WITH RING ABOVE;Ll;0;L;0061 030A;;;;N;LATIN SMALL LETTER A RING;;00C5;;00C5\n00E6;LATIN SMALL LETTER AE;Ll;0;L;;;;;N;LATIN SMALL LETTER A E;;00C6;;00C6\n00E7;LATIN SMALL LETTER C WITH CEDILLA;Ll;0;L;0063 0327;;;;N;LATIN SMALL LETTER C CEDILLA;;00C7;;00C7\n00E8;LATIN SMALL LETTER E WITH GRAVE;Ll;0;L;0065 0300;;;;N;LATIN SMALL LETTER E GRAVE;;00C8;;00C8\n00E9;LATIN SMALL LETTER E WITH ACUTE;Ll;0;L;0065 0301;;;;N;LATIN SMALL LETTER E ACUTE;;00C9;;00C9\n00EA;LATIN SMALL LETTER E WITH CIRCUMFLEX;Ll;0;L;0065 0302;;;;N;LATIN SMALL LETTER E CIRCUMFLEX;;00CA;;00CA\n00EB;LATIN SMALL LETTER E WITH DIAERESIS;Ll;0;L;0065 0308;;;;N;LATIN SMALL LETTER E DIAERESIS;;00CB;;00CB\n00EC;LATIN SMALL LETTER I WITH GRAVE;Ll;0;L;0069 0300;;;;N;LATIN SMALL LETTER I GRAVE;;00CC;;00CC\n00ED;LATIN SMALL LETTER I WITH ACUTE;Ll;0;L;0069 0301;;;;N;LATIN SMALL LETTER I ACUTE;;00CD;;00CD\n00EE;LATIN SMALL LETTER I WITH CIRCUMFLEX;Ll;0;L;0069 0302;;;;N;LATIN SMALL LETTER I CIRCUMFLEX;;00CE;;00CE\n00EF;LATIN SMALL LETTER I WITH DIAERESIS;Ll;0;L;0069 0308;;;;N;LATIN SMALL LETTER I DIAERESIS;;00CF;;00CF\n00F0;LATIN SMALL LETTER ETH;Ll;0;L;;;;;N;;;00D0;;00D0\n00F1;LATIN SMALL LETTER N WITH TILDE;Ll;0;L;006E 0303;;;;N;LATIN SMALL LETTER N TILDE;;00D1;;00D1\n00F2;LATIN SMALL LETTER O WITH GRAVE;Ll;0;L;006F 0300;;;;N;LATIN SMALL LETTER O GRAVE;;00D2;;00D2\n00F3;LATIN SMALL LETTER O WITH ACUTE;Ll;0;L;006F 0301;;;;N;LATIN SMALL LETTER O ACUTE;;00D3;;00D3\n00F4;LATIN SMALL LETTER O WITH CIRCUMFLEX;Ll;0;L;006F 0302;;;;N;LATIN SMALL LETTER O CIRCUMFLEX;;00D4;;00D4\n00F5;LATIN SMALL LETTER O WITH TILDE;Ll;0;L;006F 0303;;;;N;LATIN SMALL LETTER O TILDE;;00D5;;00D5\n00F6;LATIN SMALL LETTER O WITH DIAERESIS;Ll;0;L;006F 0308;;;;N;LATIN SMALL LETTER O DIAERESIS;;00D6;;00D6\n00F7;DIVISION SIGN;Sm;0;ON;;;;;N;;;;;\n00F8;LATIN SMALL LETTER O WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER O SLASH;;00D8;;00D8\n00F9;LATIN SMALL LETTER U WITH GRAVE;Ll;0;L;0075 0300;;;;N;LATIN SMALL LETTER U GRAVE;;00D9;;00D9\n00FA;LATIN SMALL LETTER U WITH ACUTE;Ll;0;L;0075 0301;;;;N;LATIN SMALL LETTER U ACUTE;;00DA;;00DA\n00FB;LATIN SMALL LETTER U WITH CIRCUMFLEX;Ll;0;L;0075 0302;;;;N;LATIN SMALL LETTER U CIRCUMFLEX;;00DB;;00DB\n00FC;LATIN SMALL LETTER U WITH DIAERESIS;Ll;0;L;0075 0308;;;;N;LATIN SMALL LETTER U DIAERESIS;;00DC;;00DC\n00FD;LATIN SMALL LETTER Y WITH ACUTE;Ll;0;L;0079 0301;;;;N;LATIN SMALL LETTER Y ACUTE;;00DD;;00DD\n00FE;LATIN SMALL LETTER THORN;Ll;0;L;;;;;N;;;00DE;;00DE\n00FF;LATIN SMALL LETTER Y WITH DIAERESIS;Ll;0;L;0079 0308;;;;N;LATIN SMALL LETTER Y DIAERESIS;;0178;;0178\n0100;LATIN CAPITAL LETTER A WITH MACRON;Lu;0;L;0041 0304;;;;N;LATIN CAPITAL LETTER A MACRON;;;0101;\n0101;LATIN SMALL LETTER A WITH MACRON;Ll;0;L;0061 0304;;;;N;LATIN SMALL LETTER A MACRON;;0100;;0100\n0102;LATIN CAPITAL LETTER A WITH BREVE;Lu;0;L;0041 0306;;;;N;LATIN CAPITAL LETTER A BREVE;;;0103;\n0103;LATIN SMALL LETTER A WITH BREVE;Ll;0;L;0061 0306;;;;N;LATIN SMALL LETTER A BREVE;;0102;;0102\n0104;LATIN CAPITAL LETTER A WITH OGONEK;Lu;0;L;0041 0328;;;;N;LATIN CAPITAL LETTER A OGONEK;;;0105;\n0105;LATIN SMALL LETTER A WITH OGONEK;Ll;0;L;0061 0328;;;;N;LATIN SMALL LETTER A OGONEK;;0104;;0104\n0106;LATIN CAPITAL LETTER C WITH ACUTE;Lu;0;L;0043 0301;;;;N;LATIN CAPITAL LETTER C ACUTE;;;0107;\n0107;LATIN SMALL LETTER C WITH ACUTE;Ll;0;L;0063 0301;;;;N;LATIN SMALL LETTER C ACUTE;;0106;;0106\n0108;LATIN CAPITAL LETTER C WITH CIRCUMFLEX;Lu;0;L;0043 0302;;;;N;LATIN CAPITAL LETTER C CIRCUMFLEX;;;0109;\n0109;LATIN SMALL LETTER C WITH CIRCUMFLEX;Ll;0;L;0063 0302;;;;N;LATIN SMALL LETTER C CIRCUMFLEX;;0108;;0108\n010A;LATIN CAPITAL LETTER C WITH DOT ABOVE;Lu;0;L;0043 0307;;;;N;LATIN CAPITAL LETTER C DOT;;;010B;\n010B;LATIN SMALL LETTER C WITH DOT ABOVE;Ll;0;L;0063 0307;;;;N;LATIN SMALL LETTER C DOT;;010A;;010A\n010C;LATIN CAPITAL LETTER C WITH CARON;Lu;0;L;0043 030C;;;;N;LATIN CAPITAL LETTER C HACEK;;;010D;\n010D;LATIN SMALL LETTER C WITH CARON;Ll;0;L;0063 030C;;;;N;LATIN SMALL LETTER C HACEK;;010C;;010C\n010E;LATIN CAPITAL LETTER D WITH CARON;Lu;0;L;0044 030C;;;;N;LATIN CAPITAL LETTER D HACEK;;;010F;\n010F;LATIN SMALL LETTER D WITH CARON;Ll;0;L;0064 030C;;;;N;LATIN SMALL LETTER D HACEK;;010E;;010E\n0110;LATIN CAPITAL LETTER D WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D BAR;;;0111;\n0111;LATIN SMALL LETTER D WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER D BAR;;0110;;0110\n0112;LATIN CAPITAL LETTER E WITH MACRON;Lu;0;L;0045 0304;;;;N;LATIN CAPITAL LETTER E MACRON;;;0113;\n0113;LATIN SMALL LETTER E WITH MACRON;Ll;0;L;0065 0304;;;;N;LATIN SMALL LETTER E MACRON;;0112;;0112\n0114;LATIN CAPITAL LETTER E WITH BREVE;Lu;0;L;0045 0306;;;;N;LATIN CAPITAL LETTER E BREVE;;;0115;\n0115;LATIN SMALL LETTER E WITH BREVE;Ll;0;L;0065 0306;;;;N;LATIN SMALL LETTER E BREVE;;0114;;0114\n0116;LATIN CAPITAL LETTER E WITH DOT ABOVE;Lu;0;L;0045 0307;;;;N;LATIN CAPITAL LETTER E DOT;;;0117;\n0117;LATIN SMALL LETTER E WITH DOT ABOVE;Ll;0;L;0065 0307;;;;N;LATIN SMALL LETTER E DOT;;0116;;0116\n0118;LATIN CAPITAL LETTER E WITH OGONEK;Lu;0;L;0045 0328;;;;N;LATIN CAPITAL LETTER E OGONEK;;;0119;\n0119;LATIN SMALL LETTER E WITH OGONEK;Ll;0;L;0065 0328;;;;N;LATIN SMALL LETTER E OGONEK;;0118;;0118\n011A;LATIN CAPITAL LETTER E WITH CARON;Lu;0;L;0045 030C;;;;N;LATIN CAPITAL LETTER E HACEK;;;011B;\n011B;LATIN SMALL LETTER E WITH CARON;Ll;0;L;0065 030C;;;;N;LATIN SMALL LETTER E HACEK;;011A;;011A\n011C;LATIN CAPITAL LETTER G WITH CIRCUMFLEX;Lu;0;L;0047 0302;;;;N;LATIN CAPITAL LETTER G CIRCUMFLEX;;;011D;\n011D;LATIN SMALL LETTER G WITH CIRCUMFLEX;Ll;0;L;0067 0302;;;;N;LATIN SMALL LETTER G CIRCUMFLEX;;011C;;011C\n011E;LATIN CAPITAL LETTER G WITH BREVE;Lu;0;L;0047 0306;;;;N;LATIN CAPITAL LETTER G BREVE;;;011F;\n011F;LATIN SMALL LETTER G WITH BREVE;Ll;0;L;0067 0306;;;;N;LATIN SMALL LETTER G BREVE;;011E;;011E\n0120;LATIN CAPITAL LETTER G WITH DOT ABOVE;Lu;0;L;0047 0307;;;;N;LATIN CAPITAL LETTER G DOT;;;0121;\n0121;LATIN SMALL LETTER G WITH DOT ABOVE;Ll;0;L;0067 0307;;;;N;LATIN SMALL LETTER G DOT;;0120;;0120\n0122;LATIN CAPITAL LETTER G WITH CEDILLA;Lu;0;L;0047 0327;;;;N;LATIN CAPITAL LETTER G CEDILLA;;;0123;\n0123;LATIN SMALL LETTER G WITH CEDILLA;Ll;0;L;0067 0327;;;;N;LATIN SMALL LETTER G CEDILLA;;0122;;0122\n0124;LATIN CAPITAL LETTER H WITH CIRCUMFLEX;Lu;0;L;0048 0302;;;;N;LATIN CAPITAL LETTER H CIRCUMFLEX;;;0125;\n0125;LATIN SMALL LETTER H WITH CIRCUMFLEX;Ll;0;L;0068 0302;;;;N;LATIN SMALL LETTER H CIRCUMFLEX;;0124;;0124\n0126;LATIN CAPITAL LETTER H WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER H BAR;;;0127;\n0127;LATIN SMALL LETTER H WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER H BAR;;0126;;0126\n0128;LATIN CAPITAL LETTER I WITH TILDE;Lu;0;L;0049 0303;;;;N;LATIN CAPITAL LETTER I TILDE;;;0129;\n0129;LATIN SMALL LETTER I WITH TILDE;Ll;0;L;0069 0303;;;;N;LATIN SMALL LETTER I TILDE;;0128;;0128\n012A;LATIN CAPITAL LETTER I WITH MACRON;Lu;0;L;0049 0304;;;;N;LATIN CAPITAL LETTER I MACRON;;;012B;\n012B;LATIN SMALL LETTER I WITH MACRON;Ll;0;L;0069 0304;;;;N;LATIN SMALL LETTER I MACRON;;012A;;012A\n012C;LATIN CAPITAL LETTER I WITH BREVE;Lu;0;L;0049 0306;;;;N;LATIN CAPITAL LETTER I BREVE;;;012D;\n012D;LATIN SMALL LETTER I WITH BREVE;Ll;0;L;0069 0306;;;;N;LATIN SMALL LETTER I BREVE;;012C;;012C\n012E;LATIN CAPITAL LETTER I WITH OGONEK;Lu;0;L;0049 0328;;;;N;LATIN CAPITAL LETTER I OGONEK;;;012F;\n012F;LATIN SMALL LETTER I WITH OGONEK;Ll;0;L;0069 0328;;;;N;LATIN SMALL LETTER I OGONEK;;012E;;012E\n0130;LATIN CAPITAL LETTER I WITH DOT ABOVE;Lu;0;L;0049 0307;;;;N;LATIN CAPITAL LETTER I DOT;;;0069;\n0131;LATIN SMALL LETTER DOTLESS I;Ll;0;L;;;;;N;;;0049;;0049\n0132;LATIN CAPITAL LIGATURE IJ;Lu;0;L;<compat> 0049 004A;;;;N;LATIN CAPITAL LETTER I J;;;0133;\n0133;LATIN SMALL LIGATURE IJ;Ll;0;L;<compat> 0069 006A;;;;N;LATIN SMALL LETTER I J;;0132;;0132\n0134;LATIN CAPITAL LETTER J WITH CIRCUMFLEX;Lu;0;L;004A 0302;;;;N;LATIN CAPITAL LETTER J CIRCUMFLEX;;;0135;\n0135;LATIN SMALL LETTER J WITH CIRCUMFLEX;Ll;0;L;006A 0302;;;;N;LATIN SMALL LETTER J CIRCUMFLEX;;0134;;0134\n0136;LATIN CAPITAL LETTER K WITH CEDILLA;Lu;0;L;004B 0327;;;;N;LATIN CAPITAL LETTER K CEDILLA;;;0137;\n0137;LATIN SMALL LETTER K WITH CEDILLA;Ll;0;L;006B 0327;;;;N;LATIN SMALL LETTER K CEDILLA;;0136;;0136\n0138;LATIN SMALL LETTER KRA;Ll;0;L;;;;;N;;;;;\n0139;LATIN CAPITAL LETTER L WITH ACUTE;Lu;0;L;004C 0301;;;;N;LATIN CAPITAL LETTER L ACUTE;;;013A;\n013A;LATIN SMALL LETTER L WITH ACUTE;Ll;0;L;006C 0301;;;;N;LATIN SMALL LETTER L ACUTE;;0139;;0139\n013B;LATIN CAPITAL LETTER L WITH CEDILLA;Lu;0;L;004C 0327;;;;N;LATIN CAPITAL LETTER L CEDILLA;;;013C;\n013C;LATIN SMALL LETTER L WITH CEDILLA;Ll;0;L;006C 0327;;;;N;LATIN SMALL LETTER L CEDILLA;;013B;;013B\n013D;LATIN CAPITAL LETTER L WITH CARON;Lu;0;L;004C 030C;;;;N;LATIN CAPITAL LETTER L HACEK;;;013E;\n013E;LATIN SMALL LETTER L WITH CARON;Ll;0;L;006C 030C;;;;N;LATIN SMALL LETTER L HACEK;;013D;;013D\n013F;LATIN CAPITAL LETTER L WITH MIDDLE DOT;Lu;0;L;<compat> 004C 00B7;;;;N;;;;0140;\n0140;LATIN SMALL LETTER L WITH MIDDLE DOT;Ll;0;L;<compat> 006C 00B7;;;;N;;;013F;;013F\n0141;LATIN CAPITAL LETTER L WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER L SLASH;;;0142;\n0142;LATIN SMALL LETTER L WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER L SLASH;;0141;;0141\n0143;LATIN CAPITAL LETTER N WITH ACUTE;Lu;0;L;004E 0301;;;;N;LATIN CAPITAL LETTER N ACUTE;;;0144;\n0144;LATIN SMALL LETTER N WITH ACUTE;Ll;0;L;006E 0301;;;;N;LATIN SMALL LETTER N ACUTE;;0143;;0143\n0145;LATIN CAPITAL LETTER N WITH CEDILLA;Lu;0;L;004E 0327;;;;N;LATIN CAPITAL LETTER N CEDILLA;;;0146;\n0146;LATIN SMALL LETTER N WITH CEDILLA;Ll;0;L;006E 0327;;;;N;LATIN SMALL LETTER N CEDILLA;;0145;;0145\n0147;LATIN CAPITAL LETTER N WITH CARON;Lu;0;L;004E 030C;;;;N;LATIN CAPITAL LETTER N HACEK;;;0148;\n0148;LATIN SMALL LETTER N WITH CARON;Ll;0;L;006E 030C;;;;N;LATIN SMALL LETTER N HACEK;;0147;;0147\n0149;LATIN SMALL LETTER N PRECEDED BY APOSTROPHE;Ll;0;L;<compat> 02BC 006E;;;;N;LATIN SMALL LETTER APOSTROPHE N;;;;\n014A;LATIN CAPITAL LETTER ENG;Lu;0;L;;;;;N;;;;014B;\n014B;LATIN SMALL LETTER ENG;Ll;0;L;;;;;N;;;014A;;014A\n014C;LATIN CAPITAL LETTER O WITH MACRON;Lu;0;L;004F 0304;;;;N;LATIN CAPITAL LETTER O MACRON;;;014D;\n014D;LATIN SMALL LETTER O WITH MACRON;Ll;0;L;006F 0304;;;;N;LATIN SMALL LETTER O MACRON;;014C;;014C\n014E;LATIN CAPITAL LETTER O WITH BREVE;Lu;0;L;004F 0306;;;;N;LATIN CAPITAL LETTER O BREVE;;;014F;\n014F;LATIN SMALL LETTER O WITH BREVE;Ll;0;L;006F 0306;;;;N;LATIN SMALL LETTER O BREVE;;014E;;014E\n0150;LATIN CAPITAL LETTER O WITH DOUBLE ACUTE;Lu;0;L;004F 030B;;;;N;LATIN CAPITAL LETTER O DOUBLE ACUTE;;;0151;\n0151;LATIN SMALL LETTER O WITH DOUBLE ACUTE;Ll;0;L;006F 030B;;;;N;LATIN SMALL LETTER O DOUBLE ACUTE;;0150;;0150\n0152;LATIN CAPITAL LIGATURE OE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O E;;;0153;\n0153;LATIN SMALL LIGATURE OE;Ll;0;L;;;;;N;LATIN SMALL LETTER O E;;0152;;0152\n0154;LATIN CAPITAL LETTER R WITH ACUTE;Lu;0;L;0052 0301;;;;N;LATIN CAPITAL LETTER R ACUTE;;;0155;\n0155;LATIN SMALL LETTER R WITH ACUTE;Ll;0;L;0072 0301;;;;N;LATIN SMALL LETTER R ACUTE;;0154;;0154\n0156;LATIN CAPITAL LETTER R WITH CEDILLA;Lu;0;L;0052 0327;;;;N;LATIN CAPITAL LETTER R CEDILLA;;;0157;\n0157;LATIN SMALL LETTER R WITH CEDILLA;Ll;0;L;0072 0327;;;;N;LATIN SMALL LETTER R CEDILLA;;0156;;0156\n0158;LATIN CAPITAL LETTER R WITH CARON;Lu;0;L;0052 030C;;;;N;LATIN CAPITAL LETTER R HACEK;;;0159;\n0159;LATIN SMALL LETTER R WITH CARON;Ll;0;L;0072 030C;;;;N;LATIN SMALL LETTER R HACEK;;0158;;0158\n015A;LATIN CAPITAL LETTER S WITH ACUTE;Lu;0;L;0053 0301;;;;N;LATIN CAPITAL LETTER S ACUTE;;;015B;\n015B;LATIN SMALL LETTER S WITH ACUTE;Ll;0;L;0073 0301;;;;N;LATIN SMALL LETTER S ACUTE;;015A;;015A\n015C;LATIN CAPITAL LETTER S WITH CIRCUMFLEX;Lu;0;L;0053 0302;;;;N;LATIN CAPITAL LETTER S CIRCUMFLEX;;;015D;\n015D;LATIN SMALL LETTER S WITH CIRCUMFLEX;Ll;0;L;0073 0302;;;;N;LATIN SMALL LETTER S CIRCUMFLEX;;015C;;015C\n015E;LATIN CAPITAL LETTER S WITH CEDILLA;Lu;0;L;0053 0327;;;;N;LATIN CAPITAL LETTER S CEDILLA;;;015F;\n015F;LATIN SMALL LETTER S WITH CEDILLA;Ll;0;L;0073 0327;;;;N;LATIN SMALL LETTER S CEDILLA;;015E;;015E\n0160;LATIN CAPITAL LETTER S WITH CARON;Lu;0;L;0053 030C;;;;N;LATIN CAPITAL LETTER S HACEK;;;0161;\n0161;LATIN SMALL LETTER S WITH CARON;Ll;0;L;0073 030C;;;;N;LATIN SMALL LETTER S HACEK;;0160;;0160\n0162;LATIN CAPITAL LETTER T WITH CEDILLA;Lu;0;L;0054 0327;;;;N;LATIN CAPITAL LETTER T CEDILLA;;;0163;\n0163;LATIN SMALL LETTER T WITH CEDILLA;Ll;0;L;0074 0327;;;;N;LATIN SMALL LETTER T CEDILLA;;0162;;0162\n0164;LATIN CAPITAL LETTER T WITH CARON;Lu;0;L;0054 030C;;;;N;LATIN CAPITAL LETTER T HACEK;;;0165;\n0165;LATIN SMALL LETTER T WITH CARON;Ll;0;L;0074 030C;;;;N;LATIN SMALL LETTER T HACEK;;0164;;0164\n0166;LATIN CAPITAL LETTER T WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T BAR;;;0167;\n0167;LATIN SMALL LETTER T WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER T BAR;;0166;;0166\n0168;LATIN CAPITAL LETTER U WITH TILDE;Lu;0;L;0055 0303;;;;N;LATIN CAPITAL LETTER U TILDE;;;0169;\n0169;LATIN SMALL LETTER U WITH TILDE;Ll;0;L;0075 0303;;;;N;LATIN SMALL LETTER U TILDE;;0168;;0168\n016A;LATIN CAPITAL LETTER U WITH MACRON;Lu;0;L;0055 0304;;;;N;LATIN CAPITAL LETTER U MACRON;;;016B;\n016B;LATIN SMALL LETTER U WITH MACRON;Ll;0;L;0075 0304;;;;N;LATIN SMALL LETTER U MACRON;;016A;;016A\n016C;LATIN CAPITAL LETTER U WITH BREVE;Lu;0;L;0055 0306;;;;N;LATIN CAPITAL LETTER U BREVE;;;016D;\n016D;LATIN SMALL LETTER U WITH BREVE;Ll;0;L;0075 0306;;;;N;LATIN SMALL LETTER U BREVE;;016C;;016C\n016E;LATIN CAPITAL LETTER U WITH RING ABOVE;Lu;0;L;0055 030A;;;;N;LATIN CAPITAL LETTER U RING;;;016F;\n016F;LATIN SMALL LETTER U WITH RING ABOVE;Ll;0;L;0075 030A;;;;N;LATIN SMALL LETTER U RING;;016E;;016E\n0170;LATIN CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0055 030B;;;;N;LATIN CAPITAL LETTER U DOUBLE ACUTE;;;0171;\n0171;LATIN SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0075 030B;;;;N;LATIN SMALL LETTER U DOUBLE ACUTE;;0170;;0170\n0172;LATIN CAPITAL LETTER U WITH OGONEK;Lu;0;L;0055 0328;;;;N;LATIN CAPITAL LETTER U OGONEK;;;0173;\n0173;LATIN SMALL LETTER U WITH OGONEK;Ll;0;L;0075 0328;;;;N;LATIN SMALL LETTER U OGONEK;;0172;;0172\n0174;LATIN CAPITAL LETTER W WITH CIRCUMFLEX;Lu;0;L;0057 0302;;;;N;LATIN CAPITAL LETTER W CIRCUMFLEX;;;0175;\n0175;LATIN SMALL LETTER W WITH CIRCUMFLEX;Ll;0;L;0077 0302;;;;N;LATIN SMALL LETTER W CIRCUMFLEX;;0174;;0174\n0176;LATIN CAPITAL LETTER Y WITH CIRCUMFLEX;Lu;0;L;0059 0302;;;;N;LATIN CAPITAL LETTER Y CIRCUMFLEX;;;0177;\n0177;LATIN SMALL LETTER Y WITH CIRCUMFLEX;Ll;0;L;0079 0302;;;;N;LATIN SMALL LETTER Y CIRCUMFLEX;;0176;;0176\n0178;LATIN CAPITAL LETTER Y WITH DIAERESIS;Lu;0;L;0059 0308;;;;N;LATIN CAPITAL LETTER Y DIAERESIS;;;00FF;\n0179;LATIN CAPITAL LETTER Z WITH ACUTE;Lu;0;L;005A 0301;;;;N;LATIN CAPITAL LETTER Z ACUTE;;;017A;\n017A;LATIN SMALL LETTER Z WITH ACUTE;Ll;0;L;007A 0301;;;;N;LATIN SMALL LETTER Z ACUTE;;0179;;0179\n017B;LATIN CAPITAL LETTER Z WITH DOT ABOVE;Lu;0;L;005A 0307;;;;N;LATIN CAPITAL LETTER Z DOT;;;017C;\n017C;LATIN SMALL LETTER Z WITH DOT ABOVE;Ll;0;L;007A 0307;;;;N;LATIN SMALL LETTER Z DOT;;017B;;017B\n017D;LATIN CAPITAL LETTER Z WITH CARON;Lu;0;L;005A 030C;;;;N;LATIN CAPITAL LETTER Z HACEK;;;017E;\n017E;LATIN SMALL LETTER Z WITH CARON;Ll;0;L;007A 030C;;;;N;LATIN SMALL LETTER Z HACEK;;017D;;017D\n017F;LATIN SMALL LETTER LONG S;Ll;0;L;<compat> 0073;;;;N;;;0053;;0053\n0180;LATIN SMALL LETTER B WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER B BAR;;0243;;0243\n0181;LATIN CAPITAL LETTER B WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B HOOK;;;0253;\n0182;LATIN CAPITAL LETTER B WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER B TOPBAR;;;0183;\n0183;LATIN SMALL LETTER B WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER B TOPBAR;;0182;;0182\n0184;LATIN CAPITAL LETTER TONE SIX;Lu;0;L;;;;;N;;;;0185;\n0185;LATIN SMALL LETTER TONE SIX;Ll;0;L;;;;;N;;;0184;;0184\n0186;LATIN CAPITAL LETTER OPEN O;Lu;0;L;;;;;N;;;;0254;\n0187;LATIN CAPITAL LETTER C WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER C HOOK;;;0188;\n0188;LATIN SMALL LETTER C WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER C HOOK;;0187;;0187\n0189;LATIN CAPITAL LETTER AFRICAN D;Lu;0;L;;;;;N;;;;0256;\n018A;LATIN CAPITAL LETTER D WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D HOOK;;;0257;\n018B;LATIN CAPITAL LETTER D WITH TOPBAR;Lu;0;L;;;;;N;LATIN CAPITAL LETTER D TOPBAR;;;018C;\n018C;LATIN SMALL LETTER D WITH TOPBAR;Ll;0;L;;;;;N;LATIN SMALL LETTER D TOPBAR;;018B;;018B\n018D;LATIN SMALL LETTER TURNED DELTA;Ll;0;L;;;;;N;;;;;\n018E;LATIN CAPITAL LETTER REVERSED E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER TURNED E;;;01DD;\n018F;LATIN CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;0259;\n0190;LATIN CAPITAL LETTER OPEN E;Lu;0;L;;;;;N;LATIN CAPITAL LETTER EPSILON;;;025B;\n0191;LATIN CAPITAL LETTER F WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER F HOOK;;;0192;\n0192;LATIN SMALL LETTER F WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT F;;0191;;0191\n0193;LATIN CAPITAL LETTER G WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G HOOK;;;0260;\n0194;LATIN CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;0263;\n0195;LATIN SMALL LETTER HV;Ll;0;L;;;;;N;LATIN SMALL LETTER H V;;01F6;;01F6\n0196;LATIN CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;0269;\n0197;LATIN CAPITAL LETTER I WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED I;;;0268;\n0198;LATIN CAPITAL LETTER K WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER K HOOK;;;0199;\n0199;LATIN SMALL LETTER K WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER K HOOK;;0198;;0198\n019A;LATIN SMALL LETTER L WITH BAR;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED L;;023D;;023D\n019B;LATIN SMALL LETTER LAMBDA WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED LAMBDA;;;;\n019C;LATIN CAPITAL LETTER TURNED M;Lu;0;L;;;;;N;;;;026F;\n019D;LATIN CAPITAL LETTER N WITH LEFT HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER N HOOK;;;0272;\n019E;LATIN SMALL LETTER N WITH LONG RIGHT LEG;Ll;0;L;;;;;N;;;0220;;0220\n019F;LATIN CAPITAL LETTER O WITH MIDDLE TILDE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER BARRED O;;;0275;\n01A0;LATIN CAPITAL LETTER O WITH HORN;Lu;0;L;004F 031B;;;;N;LATIN CAPITAL LETTER O HORN;;;01A1;\n01A1;LATIN SMALL LETTER O WITH HORN;Ll;0;L;006F 031B;;;;N;LATIN SMALL LETTER O HORN;;01A0;;01A0\n01A2;LATIN CAPITAL LETTER OI;Lu;0;L;;;;;N;LATIN CAPITAL LETTER O I;;;01A3;\n01A3;LATIN SMALL LETTER OI;Ll;0;L;;;;;N;LATIN SMALL LETTER O I;;01A2;;01A2\n01A4;LATIN CAPITAL LETTER P WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER P HOOK;;;01A5;\n01A5;LATIN SMALL LETTER P WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER P HOOK;;01A4;;01A4\n01A6;LATIN LETTER YR;Lu;0;L;;;;;N;LATIN LETTER Y R;;;0280;\n01A7;LATIN CAPITAL LETTER TONE TWO;Lu;0;L;;;;;N;;;;01A8;\n01A8;LATIN SMALL LETTER TONE TWO;Ll;0;L;;;;;N;;;01A7;;01A7\n01A9;LATIN CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;0283;\n01AA;LATIN LETTER REVERSED ESH LOOP;Ll;0;L;;;;;N;;;;;\n01AB;LATIN SMALL LETTER T WITH PALATAL HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T PALATAL HOOK;;;;\n01AC;LATIN CAPITAL LETTER T WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T HOOK;;;01AD;\n01AD;LATIN SMALL LETTER T WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T HOOK;;01AC;;01AC\n01AE;LATIN CAPITAL LETTER T WITH RETROFLEX HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER T RETROFLEX HOOK;;;0288;\n01AF;LATIN CAPITAL LETTER U WITH HORN;Lu;0;L;0055 031B;;;;N;LATIN CAPITAL LETTER U HORN;;;01B0;\n01B0;LATIN SMALL LETTER U WITH HORN;Ll;0;L;0075 031B;;;;N;LATIN SMALL LETTER U HORN;;01AF;;01AF\n01B1;LATIN CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;028A;\n01B2;LATIN CAPITAL LETTER V WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER SCRIPT V;;;028B;\n01B3;LATIN CAPITAL LETTER Y WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Y HOOK;;;01B4;\n01B4;LATIN SMALL LETTER Y WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Y HOOK;;01B3;;01B3\n01B5;LATIN CAPITAL LETTER Z WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER Z BAR;;;01B6;\n01B6;LATIN SMALL LETTER Z WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER Z BAR;;01B5;;01B5\n01B7;LATIN CAPITAL LETTER EZH;Lu;0;L;;;;;N;LATIN CAPITAL LETTER YOGH;;;0292;\n01B8;LATIN CAPITAL LETTER EZH REVERSED;Lu;0;L;;;;;N;LATIN CAPITAL LETTER REVERSED YOGH;;;01B9;\n01B9;LATIN SMALL LETTER EZH REVERSED;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED YOGH;;01B8;;01B8\n01BA;LATIN SMALL LETTER EZH WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH WITH TAIL;;;;\n01BB;LATIN LETTER TWO WITH STROKE;Lo;0;L;;;;;N;LATIN LETTER TWO BAR;;;;\n01BC;LATIN CAPITAL LETTER TONE FIVE;Lu;0;L;;;;;N;;;;01BD;\n01BD;LATIN SMALL LETTER TONE FIVE;Ll;0;L;;;;;N;;;01BC;;01BC\n01BE;LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER INVERTED GLOTTAL STOP BAR;;;;\n01BF;LATIN LETTER WYNN;Ll;0;L;;;;;N;;;01F7;;01F7\n01C0;LATIN LETTER DENTAL CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE;;;;\n01C1;LATIN LETTER LATERAL CLICK;Lo;0;L;;;;;N;LATIN LETTER DOUBLE PIPE;;;;\n01C2;LATIN LETTER ALVEOLAR CLICK;Lo;0;L;;;;;N;LATIN LETTER PIPE DOUBLE BAR;;;;\n01C3;LATIN LETTER RETROFLEX CLICK;Lo;0;L;;;;;N;LATIN LETTER EXCLAMATION MARK;;;;\n01C4;LATIN CAPITAL LETTER DZ WITH CARON;Lu;0;L;<compat> 0044 017D;;;;N;LATIN CAPITAL LETTER D Z HACEK;;;01C6;01C5\n01C5;LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON;Lt;0;L;<compat> 0044 017E;;;;N;LATIN LETTER CAPITAL D SMALL Z HACEK;;01C4;01C6;01C5\n01C6;LATIN SMALL LETTER DZ WITH CARON;Ll;0;L;<compat> 0064 017E;;;;N;LATIN SMALL LETTER D Z HACEK;;01C4;;01C5\n01C7;LATIN CAPITAL LETTER LJ;Lu;0;L;<compat> 004C 004A;;;;N;LATIN CAPITAL LETTER L J;;;01C9;01C8\n01C8;LATIN CAPITAL LETTER L WITH SMALL LETTER J;Lt;0;L;<compat> 004C 006A;;;;N;LATIN LETTER CAPITAL L SMALL J;;01C7;01C9;01C8\n01C9;LATIN SMALL LETTER LJ;Ll;0;L;<compat> 006C 006A;;;;N;LATIN SMALL LETTER L J;;01C7;;01C8\n01CA;LATIN CAPITAL LETTER NJ;Lu;0;L;<compat> 004E 004A;;;;N;LATIN CAPITAL LETTER N J;;;01CC;01CB\n01CB;LATIN CAPITAL LETTER N WITH SMALL LETTER J;Lt;0;L;<compat> 004E 006A;;;;N;LATIN LETTER CAPITAL N SMALL J;;01CA;01CC;01CB\n01CC;LATIN SMALL LETTER NJ;Ll;0;L;<compat> 006E 006A;;;;N;LATIN SMALL LETTER N J;;01CA;;01CB\n01CD;LATIN CAPITAL LETTER A WITH CARON;Lu;0;L;0041 030C;;;;N;LATIN CAPITAL LETTER A HACEK;;;01CE;\n01CE;LATIN SMALL LETTER A WITH CARON;Ll;0;L;0061 030C;;;;N;LATIN SMALL LETTER A HACEK;;01CD;;01CD\n01CF;LATIN CAPITAL LETTER I WITH CARON;Lu;0;L;0049 030C;;;;N;LATIN CAPITAL LETTER I HACEK;;;01D0;\n01D0;LATIN SMALL LETTER I WITH CARON;Ll;0;L;0069 030C;;;;N;LATIN SMALL LETTER I HACEK;;01CF;;01CF\n01D1;LATIN CAPITAL LETTER O WITH CARON;Lu;0;L;004F 030C;;;;N;LATIN CAPITAL LETTER O HACEK;;;01D2;\n01D2;LATIN SMALL LETTER O WITH CARON;Ll;0;L;006F 030C;;;;N;LATIN SMALL LETTER O HACEK;;01D1;;01D1\n01D3;LATIN CAPITAL LETTER U WITH CARON;Lu;0;L;0055 030C;;;;N;LATIN CAPITAL LETTER U HACEK;;;01D4;\n01D4;LATIN SMALL LETTER U WITH CARON;Ll;0;L;0075 030C;;;;N;LATIN SMALL LETTER U HACEK;;01D3;;01D3\n01D5;LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON;Lu;0;L;00DC 0304;;;;N;LATIN CAPITAL LETTER U DIAERESIS MACRON;;;01D6;\n01D6;LATIN SMALL LETTER U WITH DIAERESIS AND MACRON;Ll;0;L;00FC 0304;;;;N;LATIN SMALL LETTER U DIAERESIS MACRON;;01D5;;01D5\n01D7;LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE;Lu;0;L;00DC 0301;;;;N;LATIN CAPITAL LETTER U DIAERESIS ACUTE;;;01D8;\n01D8;LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE;Ll;0;L;00FC 0301;;;;N;LATIN SMALL LETTER U DIAERESIS ACUTE;;01D7;;01D7\n01D9;LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON;Lu;0;L;00DC 030C;;;;N;LATIN CAPITAL LETTER U DIAERESIS HACEK;;;01DA;\n01DA;LATIN SMALL LETTER U WITH DIAERESIS AND CARON;Ll;0;L;00FC 030C;;;;N;LATIN SMALL LETTER U DIAERESIS HACEK;;01D9;;01D9\n01DB;LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE;Lu;0;L;00DC 0300;;;;N;LATIN CAPITAL LETTER U DIAERESIS GRAVE;;;01DC;\n01DC;LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE;Ll;0;L;00FC 0300;;;;N;LATIN SMALL LETTER U DIAERESIS GRAVE;;01DB;;01DB\n01DD;LATIN SMALL LETTER TURNED E;Ll;0;L;;;;;N;;;018E;;018E\n01DE;LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON;Lu;0;L;00C4 0304;;;;N;LATIN CAPITAL LETTER A DIAERESIS MACRON;;;01DF;\n01DF;LATIN SMALL LETTER A WITH DIAERESIS AND MACRON;Ll;0;L;00E4 0304;;;;N;LATIN SMALL LETTER A DIAERESIS MACRON;;01DE;;01DE\n01E0;LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON;Lu;0;L;0226 0304;;;;N;LATIN CAPITAL LETTER A DOT MACRON;;;01E1;\n01E1;LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON;Ll;0;L;0227 0304;;;;N;LATIN SMALL LETTER A DOT MACRON;;01E0;;01E0\n01E2;LATIN CAPITAL LETTER AE WITH MACRON;Lu;0;L;00C6 0304;;;;N;LATIN CAPITAL LETTER A E MACRON;;;01E3;\n01E3;LATIN SMALL LETTER AE WITH MACRON;Ll;0;L;00E6 0304;;;;N;LATIN SMALL LETTER A E MACRON;;01E2;;01E2\n01E4;LATIN CAPITAL LETTER G WITH STROKE;Lu;0;L;;;;;N;LATIN CAPITAL LETTER G BAR;;;01E5;\n01E5;LATIN SMALL LETTER G WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER G BAR;;01E4;;01E4\n01E6;LATIN CAPITAL LETTER G WITH CARON;Lu;0;L;0047 030C;;;;N;LATIN CAPITAL LETTER G HACEK;;;01E7;\n01E7;LATIN SMALL LETTER G WITH CARON;Ll;0;L;0067 030C;;;;N;LATIN SMALL LETTER G HACEK;;01E6;;01E6\n01E8;LATIN CAPITAL LETTER K WITH CARON;Lu;0;L;004B 030C;;;;N;LATIN CAPITAL LETTER K HACEK;;;01E9;\n01E9;LATIN SMALL LETTER K WITH CARON;Ll;0;L;006B 030C;;;;N;LATIN SMALL LETTER K HACEK;;01E8;;01E8\n01EA;LATIN CAPITAL LETTER O WITH OGONEK;Lu;0;L;004F 0328;;;;N;LATIN CAPITAL LETTER O OGONEK;;;01EB;\n01EB;LATIN SMALL LETTER O WITH OGONEK;Ll;0;L;006F 0328;;;;N;LATIN SMALL LETTER O OGONEK;;01EA;;01EA\n01EC;LATIN CAPITAL LETTER O WITH OGONEK AND MACRON;Lu;0;L;01EA 0304;;;;N;LATIN CAPITAL LETTER O OGONEK MACRON;;;01ED;\n01ED;LATIN SMALL LETTER O WITH OGONEK AND MACRON;Ll;0;L;01EB 0304;;;;N;LATIN SMALL LETTER O OGONEK MACRON;;01EC;;01EC\n01EE;LATIN CAPITAL LETTER EZH WITH CARON;Lu;0;L;01B7 030C;;;;N;LATIN CAPITAL LETTER YOGH HACEK;;;01EF;\n01EF;LATIN SMALL LETTER EZH WITH CARON;Ll;0;L;0292 030C;;;;N;LATIN SMALL LETTER YOGH HACEK;;01EE;;01EE\n01F0;LATIN SMALL LETTER J WITH CARON;Ll;0;L;006A 030C;;;;N;LATIN SMALL LETTER J HACEK;;;;\n01F1;LATIN CAPITAL LETTER DZ;Lu;0;L;<compat> 0044 005A;;;;N;;;;01F3;01F2\n01F2;LATIN CAPITAL LETTER D WITH SMALL LETTER Z;Lt;0;L;<compat> 0044 007A;;;;N;;;01F1;01F3;01F2\n01F3;LATIN SMALL LETTER DZ;Ll;0;L;<compat> 0064 007A;;;;N;;;01F1;;01F2\n01F4;LATIN CAPITAL LETTER G WITH ACUTE;Lu;0;L;0047 0301;;;;N;;;;01F5;\n01F5;LATIN SMALL LETTER G WITH ACUTE;Ll;0;L;0067 0301;;;;N;;;01F4;;01F4\n01F6;LATIN CAPITAL LETTER HWAIR;Lu;0;L;;;;;N;;;;0195;\n01F7;LATIN CAPITAL LETTER WYNN;Lu;0;L;;;;;N;;;;01BF;\n01F8;LATIN CAPITAL LETTER N WITH GRAVE;Lu;0;L;004E 0300;;;;N;;;;01F9;\n01F9;LATIN SMALL LETTER N WITH GRAVE;Ll;0;L;006E 0300;;;;N;;;01F8;;01F8\n01FA;LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE;Lu;0;L;00C5 0301;;;;N;;;;01FB;\n01FB;LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE;Ll;0;L;00E5 0301;;;;N;;;01FA;;01FA\n01FC;LATIN CAPITAL LETTER AE WITH ACUTE;Lu;0;L;00C6 0301;;;;N;;;;01FD;\n01FD;LATIN SMALL LETTER AE WITH ACUTE;Ll;0;L;00E6 0301;;;;N;;;01FC;;01FC\n01FE;LATIN CAPITAL LETTER O WITH STROKE AND ACUTE;Lu;0;L;00D8 0301;;;;N;;;;01FF;\n01FF;LATIN SMALL LETTER O WITH STROKE AND ACUTE;Ll;0;L;00F8 0301;;;;N;;;01FE;;01FE\n0200;LATIN CAPITAL LETTER A WITH DOUBLE GRAVE;Lu;0;L;0041 030F;;;;N;;;;0201;\n0201;LATIN SMALL LETTER A WITH DOUBLE GRAVE;Ll;0;L;0061 030F;;;;N;;;0200;;0200\n0202;LATIN CAPITAL LETTER A WITH INVERTED BREVE;Lu;0;L;0041 0311;;;;N;;;;0203;\n0203;LATIN SMALL LETTER A WITH INVERTED BREVE;Ll;0;L;0061 0311;;;;N;;;0202;;0202\n0204;LATIN CAPITAL LETTER E WITH DOUBLE GRAVE;Lu;0;L;0045 030F;;;;N;;;;0205;\n0205;LATIN SMALL LETTER E WITH DOUBLE GRAVE;Ll;0;L;0065 030F;;;;N;;;0204;;0204\n0206;LATIN CAPITAL LETTER E WITH INVERTED BREVE;Lu;0;L;0045 0311;;;;N;;;;0207;\n0207;LATIN SMALL LETTER E WITH INVERTED BREVE;Ll;0;L;0065 0311;;;;N;;;0206;;0206\n0208;LATIN CAPITAL LETTER I WITH DOUBLE GRAVE;Lu;0;L;0049 030F;;;;N;;;;0209;\n0209;LATIN SMALL LETTER I WITH DOUBLE GRAVE;Ll;0;L;0069 030F;;;;N;;;0208;;0208\n020A;LATIN CAPITAL LETTER I WITH INVERTED BREVE;Lu;0;L;0049 0311;;;;N;;;;020B;\n020B;LATIN SMALL LETTER I WITH INVERTED BREVE;Ll;0;L;0069 0311;;;;N;;;020A;;020A\n020C;LATIN CAPITAL LETTER O WITH DOUBLE GRAVE;Lu;0;L;004F 030F;;;;N;;;;020D;\n020D;LATIN SMALL LETTER O WITH DOUBLE GRAVE;Ll;0;L;006F 030F;;;;N;;;020C;;020C\n020E;LATIN CAPITAL LETTER O WITH INVERTED BREVE;Lu;0;L;004F 0311;;;;N;;;;020F;\n020F;LATIN SMALL LETTER O WITH INVERTED BREVE;Ll;0;L;006F 0311;;;;N;;;020E;;020E\n0210;LATIN CAPITAL LETTER R WITH DOUBLE GRAVE;Lu;0;L;0052 030F;;;;N;;;;0211;\n0211;LATIN SMALL LETTER R WITH DOUBLE GRAVE;Ll;0;L;0072 030F;;;;N;;;0210;;0210\n0212;LATIN CAPITAL LETTER R WITH INVERTED BREVE;Lu;0;L;0052 0311;;;;N;;;;0213;\n0213;LATIN SMALL LETTER R WITH INVERTED BREVE;Ll;0;L;0072 0311;;;;N;;;0212;;0212\n0214;LATIN CAPITAL LETTER U WITH DOUBLE GRAVE;Lu;0;L;0055 030F;;;;N;;;;0215;\n0215;LATIN SMALL LETTER U WITH DOUBLE GRAVE;Ll;0;L;0075 030F;;;;N;;;0214;;0214\n0216;LATIN CAPITAL LETTER U WITH INVERTED BREVE;Lu;0;L;0055 0311;;;;N;;;;0217;\n0217;LATIN SMALL LETTER U WITH INVERTED BREVE;Ll;0;L;0075 0311;;;;N;;;0216;;0216\n0218;LATIN CAPITAL LETTER S WITH COMMA BELOW;Lu;0;L;0053 0326;;;;N;;;;0219;\n0219;LATIN SMALL LETTER S WITH COMMA BELOW;Ll;0;L;0073 0326;;;;N;;;0218;;0218\n021A;LATIN CAPITAL LETTER T WITH COMMA BELOW;Lu;0;L;0054 0326;;;;N;;;;021B;\n021B;LATIN SMALL LETTER T WITH COMMA BELOW;Ll;0;L;0074 0326;;;;N;;;021A;;021A\n021C;LATIN CAPITAL LETTER YOGH;Lu;0;L;;;;;N;;;;021D;\n021D;LATIN SMALL LETTER YOGH;Ll;0;L;;;;;N;;;021C;;021C\n021E;LATIN CAPITAL LETTER H WITH CARON;Lu;0;L;0048 030C;;;;N;;;;021F;\n021F;LATIN SMALL LETTER H WITH CARON;Ll;0;L;0068 030C;;;;N;;;021E;;021E\n0220;LATIN CAPITAL LETTER N WITH LONG RIGHT LEG;Lu;0;L;;;;;N;;;;019E;\n0221;LATIN SMALL LETTER D WITH CURL;Ll;0;L;;;;;N;;;;;\n0222;LATIN CAPITAL LETTER OU;Lu;0;L;;;;;N;;;;0223;\n0223;LATIN SMALL LETTER OU;Ll;0;L;;;;;N;;;0222;;0222\n0224;LATIN CAPITAL LETTER Z WITH HOOK;Lu;0;L;;;;;N;;;;0225;\n0225;LATIN SMALL LETTER Z WITH HOOK;Ll;0;L;;;;;N;;;0224;;0224\n0226;LATIN CAPITAL LETTER A WITH DOT ABOVE;Lu;0;L;0041 0307;;;;N;;;;0227;\n0227;LATIN SMALL LETTER A WITH DOT ABOVE;Ll;0;L;0061 0307;;;;N;;;0226;;0226\n0228;LATIN CAPITAL LETTER E WITH CEDILLA;Lu;0;L;0045 0327;;;;N;;;;0229;\n0229;LATIN SMALL LETTER E WITH CEDILLA;Ll;0;L;0065 0327;;;;N;;;0228;;0228\n022A;LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON;Lu;0;L;00D6 0304;;;;N;;;;022B;\n022B;LATIN SMALL LETTER O WITH DIAERESIS AND MACRON;Ll;0;L;00F6 0304;;;;N;;;022A;;022A\n022C;LATIN CAPITAL LETTER O WITH TILDE AND MACRON;Lu;0;L;00D5 0304;;;;N;;;;022D;\n022D;LATIN SMALL LETTER O WITH TILDE AND MACRON;Ll;0;L;00F5 0304;;;;N;;;022C;;022C\n022E;LATIN CAPITAL LETTER O WITH DOT ABOVE;Lu;0;L;004F 0307;;;;N;;;;022F;\n022F;LATIN SMALL LETTER O WITH DOT ABOVE;Ll;0;L;006F 0307;;;;N;;;022E;;022E\n0230;LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON;Lu;0;L;022E 0304;;;;N;;;;0231;\n0231;LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON;Ll;0;L;022F 0304;;;;N;;;0230;;0230\n0232;LATIN CAPITAL LETTER Y WITH MACRON;Lu;0;L;0059 0304;;;;N;;;;0233;\n0233;LATIN SMALL LETTER Y WITH MACRON;Ll;0;L;0079 0304;;;;N;;;0232;;0232\n0234;LATIN SMALL LETTER L WITH CURL;Ll;0;L;;;;;N;;;;;\n0235;LATIN SMALL LETTER N WITH CURL;Ll;0;L;;;;;N;;;;;\n0236;LATIN SMALL LETTER T WITH CURL;Ll;0;L;;;;;N;;;;;\n0237;LATIN SMALL LETTER DOTLESS J;Ll;0;L;;;;;N;;;;;\n0238;LATIN SMALL LETTER DB DIGRAPH;Ll;0;L;;;;;N;;;;;\n0239;LATIN SMALL LETTER QP DIGRAPH;Ll;0;L;;;;;N;;;;;\n023A;LATIN CAPITAL LETTER A WITH STROKE;Lu;0;L;;;;;N;;;;2C65;\n023B;LATIN CAPITAL LETTER C WITH STROKE;Lu;0;L;;;;;N;;;;023C;\n023C;LATIN SMALL LETTER C WITH STROKE;Ll;0;L;;;;;N;;;023B;;023B\n023D;LATIN CAPITAL LETTER L WITH BAR;Lu;0;L;;;;;N;;;;019A;\n023E;LATIN CAPITAL LETTER T WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;2C66;\n023F;LATIN SMALL LETTER S WITH SWASH TAIL;Ll;0;L;;;;;N;;;2C7E;;2C7E\n0240;LATIN SMALL LETTER Z WITH SWASH TAIL;Ll;0;L;;;;;N;;;2C7F;;2C7F\n0241;LATIN CAPITAL LETTER GLOTTAL STOP;Lu;0;L;;;;;N;;;;0242;\n0242;LATIN SMALL LETTER GLOTTAL STOP;Ll;0;L;;;;;N;;;0241;;0241\n0243;LATIN CAPITAL LETTER B WITH STROKE;Lu;0;L;;;;;N;;;;0180;\n0244;LATIN CAPITAL LETTER U BAR;Lu;0;L;;;;;N;;;;0289;\n0245;LATIN CAPITAL LETTER TURNED V;Lu;0;L;;;;;N;;;;028C;\n0246;LATIN CAPITAL LETTER E WITH STROKE;Lu;0;L;;;;;N;;;;0247;\n0247;LATIN SMALL LETTER E WITH STROKE;Ll;0;L;;;;;N;;;0246;;0246\n0248;LATIN CAPITAL LETTER J WITH STROKE;Lu;0;L;;;;;N;;;;0249;\n0249;LATIN SMALL LETTER J WITH STROKE;Ll;0;L;;;;;N;;;0248;;0248\n024A;LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL;Lu;0;L;;;;;N;;;;024B;\n024B;LATIN SMALL LETTER Q WITH HOOK TAIL;Ll;0;L;;;;;N;;;024A;;024A\n024C;LATIN CAPITAL LETTER R WITH STROKE;Lu;0;L;;;;;N;;;;024D;\n024D;LATIN SMALL LETTER R WITH STROKE;Ll;0;L;;;;;N;;;024C;;024C\n024E;LATIN CAPITAL LETTER Y WITH STROKE;Lu;0;L;;;;;N;;;;024F;\n024F;LATIN SMALL LETTER Y WITH STROKE;Ll;0;L;;;;;N;;;024E;;024E\n0250;LATIN SMALL LETTER TURNED A;Ll;0;L;;;;;N;;;2C6F;;2C6F\n0251;LATIN SMALL LETTER ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT A;;2C6D;;2C6D\n0252;LATIN SMALL LETTER TURNED ALPHA;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED SCRIPT A;;2C70;;2C70\n0253;LATIN SMALL LETTER B WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER B HOOK;;0181;;0181\n0254;LATIN SMALL LETTER OPEN O;Ll;0;L;;;;;N;;;0186;;0186\n0255;LATIN SMALL LETTER C WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER C CURL;;;;\n0256;LATIN SMALL LETTER D WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER D RETROFLEX HOOK;;0189;;0189\n0257;LATIN SMALL LETTER D WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER D HOOK;;018A;;018A\n0258;LATIN SMALL LETTER REVERSED E;Ll;0;L;;;;;N;;;;;\n0259;LATIN SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;018F;;018F\n025A;LATIN SMALL LETTER SCHWA WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCHWA HOOK;;;;\n025B;LATIN SMALL LETTER OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER EPSILON;;0190;;0190\n025C;LATIN SMALL LETTER REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON;;A7AB;;A7AB\n025D;LATIN SMALL LETTER REVERSED OPEN E WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED EPSILON HOOK;;;;\n025E;LATIN SMALL LETTER CLOSED REVERSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED REVERSED EPSILON;;;;\n025F;LATIN SMALL LETTER DOTLESS J WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR;;;;\n0260;LATIN SMALL LETTER G WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER G HOOK;;0193;;0193\n0261;LATIN SMALL LETTER SCRIPT G;Ll;0;L;;;;;N;;;A7AC;;A7AC\n0262;LATIN LETTER SMALL CAPITAL G;Ll;0;L;;;;;N;;;;;\n0263;LATIN SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0194;;0194\n0264;LATIN SMALL LETTER RAMS HORN;Ll;0;L;;;;;N;LATIN SMALL LETTER BABY GAMMA;;;;\n0265;LATIN SMALL LETTER TURNED H;Ll;0;L;;;;;N;;;A78D;;A78D\n0266;LATIN SMALL LETTER H WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER H HOOK;;A7AA;;A7AA\n0267;LATIN SMALL LETTER HENG WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER HENG HOOK;;;;\n0268;LATIN SMALL LETTER I WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED I;;0197;;0197\n0269;LATIN SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0196;;0196\n026A;LATIN LETTER SMALL CAPITAL I;Ll;0;L;;;;;N;;;A7AE;;A7AE\n026B;LATIN SMALL LETTER L WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;2C62;;2C62\n026C;LATIN SMALL LETTER L WITH BELT;Ll;0;L;;;;;N;LATIN SMALL LETTER L BELT;;A7AD;;A7AD\n026D;LATIN SMALL LETTER L WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER L RETROFLEX HOOK;;;;\n026E;LATIN SMALL LETTER LEZH;Ll;0;L;;;;;N;LATIN SMALL LETTER L YOGH;;;;\n026F;LATIN SMALL LETTER TURNED M;Ll;0;L;;;;;N;;;019C;;019C\n0270;LATIN SMALL LETTER TURNED M WITH LONG LEG;Ll;0;L;;;;;N;;;;;\n0271;LATIN SMALL LETTER M WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER M HOOK;;2C6E;;2C6E\n0272;LATIN SMALL LETTER N WITH LEFT HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N HOOK;;019D;;019D\n0273;LATIN SMALL LETTER N WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER N RETROFLEX HOOK;;;;\n0274;LATIN LETTER SMALL CAPITAL N;Ll;0;L;;;;;N;;;;;\n0275;LATIN SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;019F;;019F\n0276;LATIN LETTER SMALL CAPITAL OE;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL O E;;;;\n0277;LATIN SMALL LETTER CLOSED OMEGA;Ll;0;L;;;;;N;;;;;\n0278;LATIN SMALL LETTER PHI;Ll;0;L;;;;;N;;;;;\n0279;LATIN SMALL LETTER TURNED R;Ll;0;L;;;;;N;;;;;\n027A;LATIN SMALL LETTER TURNED R WITH LONG LEG;Ll;0;L;;;;;N;;;;;\n027B;LATIN SMALL LETTER TURNED R WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER TURNED R HOOK;;;;\n027C;LATIN SMALL LETTER R WITH LONG LEG;Ll;0;L;;;;;N;;;;;\n027D;LATIN SMALL LETTER R WITH TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER R HOOK;;2C64;;2C64\n027E;LATIN SMALL LETTER R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER FISHHOOK R;;;;\n027F;LATIN SMALL LETTER REVERSED R WITH FISHHOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER REVERSED FISHHOOK R;;;;\n0280;LATIN LETTER SMALL CAPITAL R;Ll;0;L;;;;;N;;;01A6;;01A6\n0281;LATIN LETTER SMALL CAPITAL INVERTED R;Ll;0;L;;;;;N;;;;;\n0282;LATIN SMALL LETTER S WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER S HOOK;;A7C5;;A7C5\n0283;LATIN SMALL LETTER ESH;Ll;0;L;;;;;N;;;01A9;;01A9\n0284;LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER DOTLESS J BAR HOOK;;;;\n0285;LATIN SMALL LETTER SQUAT REVERSED ESH;Ll;0;L;;;;;N;;;;;\n0286;LATIN SMALL LETTER ESH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER ESH CURL;;;;\n0287;LATIN SMALL LETTER TURNED T;Ll;0;L;;;;;N;;;A7B1;;A7B1\n0288;LATIN SMALL LETTER T WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER T RETROFLEX HOOK;;01AE;;01AE\n0289;LATIN SMALL LETTER U BAR;Ll;0;L;;;;;N;;;0244;;0244\n028A;LATIN SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;01B1;;01B1\n028B;LATIN SMALL LETTER V WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER SCRIPT V;;01B2;;01B2\n028C;LATIN SMALL LETTER TURNED V;Ll;0;L;;;;;N;;;0245;;0245\n028D;LATIN SMALL LETTER TURNED W;Ll;0;L;;;;;N;;;;;\n028E;LATIN SMALL LETTER TURNED Y;Ll;0;L;;;;;N;;;;;\n028F;LATIN LETTER SMALL CAPITAL Y;Ll;0;L;;;;;N;;;;;\n0290;LATIN SMALL LETTER Z WITH RETROFLEX HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Z RETROFLEX HOOK;;;;\n0291;LATIN SMALL LETTER Z WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER Z CURL;;;;\n0292;LATIN SMALL LETTER EZH;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH;;01B7;;01B7\n0293;LATIN SMALL LETTER EZH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER YOGH CURL;;;;\n0294;LATIN LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;;\n0295;LATIN LETTER PHARYNGEAL VOICED FRICATIVE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP;;;;\n0296;LATIN LETTER INVERTED GLOTTAL STOP;Ll;0;L;;;;;N;;;;;\n0297;LATIN LETTER STRETCHED C;Ll;0;L;;;;;N;;;;;\n0298;LATIN LETTER BILABIAL CLICK;Ll;0;L;;;;;N;LATIN LETTER BULLSEYE;;;;\n0299;LATIN LETTER SMALL CAPITAL B;Ll;0;L;;;;;N;;;;;\n029A;LATIN SMALL LETTER CLOSED OPEN E;Ll;0;L;;;;;N;LATIN SMALL LETTER CLOSED EPSILON;;;;\n029B;LATIN LETTER SMALL CAPITAL G WITH HOOK;Ll;0;L;;;;;N;LATIN LETTER SMALL CAPITAL G HOOK;;;;\n029C;LATIN LETTER SMALL CAPITAL H;Ll;0;L;;;;;N;;;;;\n029D;LATIN SMALL LETTER J WITH CROSSED-TAIL;Ll;0;L;;;;;N;LATIN SMALL LETTER CROSSED-TAIL J;;A7B2;;A7B2\n029E;LATIN SMALL LETTER TURNED K;Ll;0;L;;;;;N;;;A7B0;;A7B0\n029F;LATIN LETTER SMALL CAPITAL L;Ll;0;L;;;;;N;;;;;\n02A0;LATIN SMALL LETTER Q WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER Q HOOK;;;;\n02A1;LATIN LETTER GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER GLOTTAL STOP BAR;;;;\n02A2;LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE;Ll;0;L;;;;;N;LATIN LETTER REVERSED GLOTTAL STOP BAR;;;;\n02A3;LATIN SMALL LETTER DZ DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z;;;;\n02A4;LATIN SMALL LETTER DEZH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER D YOGH;;;;\n02A5;LATIN SMALL LETTER DZ DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER D Z CURL;;;;\n02A6;LATIN SMALL LETTER TS DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T S;;;;\n02A7;LATIN SMALL LETTER TESH DIGRAPH;Ll;0;L;;;;;N;LATIN SMALL LETTER T ESH;;;;\n02A8;LATIN SMALL LETTER TC DIGRAPH WITH CURL;Ll;0;L;;;;;N;LATIN SMALL LETTER T C CURL;;;;\n02A9;LATIN SMALL LETTER FENG DIGRAPH;Ll;0;L;;;;;N;;;;;\n02AA;LATIN SMALL LETTER LS DIGRAPH;Ll;0;L;;;;;N;;;;;\n02AB;LATIN SMALL LETTER LZ DIGRAPH;Ll;0;L;;;;;N;;;;;\n02AC;LATIN LETTER BILABIAL PERCUSSIVE;Ll;0;L;;;;;N;;;;;\n02AD;LATIN LETTER BIDENTAL PERCUSSIVE;Ll;0;L;;;;;N;;;;;\n02AE;LATIN SMALL LETTER TURNED H WITH FISHHOOK;Ll;0;L;;;;;N;;;;;\n02AF;LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL;Ll;0;L;;;;;N;;;;;\n02B0;MODIFIER LETTER SMALL H;Lm;0;L;<super> 0068;;;;N;;;;;\n02B1;MODIFIER LETTER SMALL H WITH HOOK;Lm;0;L;<super> 0266;;;;N;MODIFIER LETTER SMALL H HOOK;;;;\n02B2;MODIFIER LETTER SMALL J;Lm;0;L;<super> 006A;;;;N;;;;;\n02B3;MODIFIER LETTER SMALL R;Lm;0;L;<super> 0072;;;;N;;;;;\n02B4;MODIFIER LETTER SMALL TURNED R;Lm;0;L;<super> 0279;;;;N;;;;;\n02B5;MODIFIER LETTER SMALL TURNED R WITH HOOK;Lm;0;L;<super> 027B;;;;N;MODIFIER LETTER SMALL TURNED R HOOK;;;;\n02B6;MODIFIER LETTER SMALL CAPITAL INVERTED R;Lm;0;L;<super> 0281;;;;N;;;;;\n02B7;MODIFIER LETTER SMALL W;Lm;0;L;<super> 0077;;;;N;;;;;\n02B8;MODIFIER LETTER SMALL Y;Lm;0;L;<super> 0079;;;;N;;;;;\n02B9;MODIFIER LETTER PRIME;Lm;0;ON;;;;;N;;;;;\n02BA;MODIFIER LETTER DOUBLE PRIME;Lm;0;ON;;;;;N;;;;;\n02BB;MODIFIER LETTER TURNED COMMA;Lm;0;L;;;;;N;;;;;\n02BC;MODIFIER LETTER APOSTROPHE;Lm;0;L;;;;;N;;;;;\n02BD;MODIFIER LETTER REVERSED COMMA;Lm;0;L;;;;;N;;;;;\n02BE;MODIFIER LETTER RIGHT HALF RING;Lm;0;L;;;;;N;;;;;\n02BF;MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;;\n02C0;MODIFIER LETTER GLOTTAL STOP;Lm;0;L;;;;;N;;;;;\n02C1;MODIFIER LETTER REVERSED GLOTTAL STOP;Lm;0;L;;;;;N;;;;;\n02C2;MODIFIER LETTER LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;;\n02C3;MODIFIER LETTER RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;;\n02C4;MODIFIER LETTER UP ARROWHEAD;Sk;0;ON;;;;;N;;;;;\n02C5;MODIFIER LETTER DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;;\n02C6;MODIFIER LETTER CIRCUMFLEX ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER CIRCUMFLEX;;;;\n02C7;CARON;Lm;0;ON;;;;;N;MODIFIER LETTER HACEK;;;;\n02C8;MODIFIER LETTER VERTICAL LINE;Lm;0;ON;;;;;N;;;;;\n02C9;MODIFIER LETTER MACRON;Lm;0;ON;;;;;N;;;;;\n02CA;MODIFIER LETTER ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER ACUTE;;;;\n02CB;MODIFIER LETTER GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER GRAVE;;;;\n02CC;MODIFIER LETTER LOW VERTICAL LINE;Lm;0;ON;;;;;N;;;;;\n02CD;MODIFIER LETTER LOW MACRON;Lm;0;ON;;;;;N;;;;;\n02CE;MODIFIER LETTER LOW GRAVE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER LOW GRAVE;;;;\n02CF;MODIFIER LETTER LOW ACUTE ACCENT;Lm;0;ON;;;;;N;MODIFIER LETTER LOW ACUTE;;;;\n02D0;MODIFIER LETTER TRIANGULAR COLON;Lm;0;L;;;;;N;;;;;\n02D1;MODIFIER LETTER HALF TRIANGULAR COLON;Lm;0;L;;;;;N;;;;;\n02D2;MODIFIER LETTER CENTRED RIGHT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED RIGHT HALF RING;;;;\n02D3;MODIFIER LETTER CENTRED LEFT HALF RING;Sk;0;ON;;;;;N;MODIFIER LETTER CENTERED LEFT HALF RING;;;;\n02D4;MODIFIER LETTER UP TACK;Sk;0;ON;;;;;N;;;;;\n02D5;MODIFIER LETTER DOWN TACK;Sk;0;ON;;;;;N;;;;;\n02D6;MODIFIER LETTER PLUS SIGN;Sk;0;ON;;;;;N;;;;;\n02D7;MODIFIER LETTER MINUS SIGN;Sk;0;ON;;;;;N;;;;;\n02D8;BREVE;Sk;0;ON;<compat> 0020 0306;;;;N;SPACING BREVE;;;;\n02D9;DOT ABOVE;Sk;0;ON;<compat> 0020 0307;;;;N;SPACING DOT ABOVE;;;;\n02DA;RING ABOVE;Sk;0;ON;<compat> 0020 030A;;;;N;SPACING RING ABOVE;;;;\n02DB;OGONEK;Sk;0;ON;<compat> 0020 0328;;;;N;SPACING OGONEK;;;;\n02DC;SMALL TILDE;Sk;0;ON;<compat> 0020 0303;;;;N;SPACING TILDE;;;;\n02DD;DOUBLE ACUTE ACCENT;Sk;0;ON;<compat> 0020 030B;;;;N;SPACING DOUBLE ACUTE;;;;\n02DE;MODIFIER LETTER RHOTIC HOOK;Sk;0;ON;;;;;N;;;;;\n02DF;MODIFIER LETTER CROSS ACCENT;Sk;0;ON;;;;;N;;;;;\n02E0;MODIFIER LETTER SMALL GAMMA;Lm;0;L;<super> 0263;;;;N;;;;;\n02E1;MODIFIER LETTER SMALL L;Lm;0;L;<super> 006C;;;;N;;;;;\n02E2;MODIFIER LETTER SMALL S;Lm;0;L;<super> 0073;;;;N;;;;;\n02E3;MODIFIER LETTER SMALL X;Lm;0;L;<super> 0078;;;;N;;;;;\n02E4;MODIFIER LETTER SMALL REVERSED GLOTTAL STOP;Lm;0;L;<super> 0295;;;;N;;;;;\n02E5;MODIFIER LETTER EXTRA-HIGH TONE BAR;Sk;0;ON;;;;;N;;;;;\n02E6;MODIFIER LETTER HIGH TONE BAR;Sk;0;ON;;;;;N;;;;;\n02E7;MODIFIER LETTER MID TONE BAR;Sk;0;ON;;;;;N;;;;;\n02E8;MODIFIER LETTER LOW TONE BAR;Sk;0;ON;;;;;N;;;;;\n02E9;MODIFIER LETTER EXTRA-LOW TONE BAR;Sk;0;ON;;;;;N;;;;;\n02EA;MODIFIER LETTER YIN DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;;\n02EB;MODIFIER LETTER YANG DEPARTING TONE MARK;Sk;0;ON;;;;;N;;;;;\n02EC;MODIFIER LETTER VOICING;Lm;0;ON;;;;;N;;;;;\n02ED;MODIFIER LETTER UNASPIRATED;Sk;0;ON;;;;;N;;;;;\n02EE;MODIFIER LETTER DOUBLE APOSTROPHE;Lm;0;L;;;;;N;;;;;\n02EF;MODIFIER LETTER LOW DOWN ARROWHEAD;Sk;0;ON;;;;;N;;;;;\n02F0;MODIFIER LETTER LOW UP ARROWHEAD;Sk;0;ON;;;;;N;;;;;\n02F1;MODIFIER LETTER LOW LEFT ARROWHEAD;Sk;0;ON;;;;;N;;;;;\n02F2;MODIFIER LETTER LOW RIGHT ARROWHEAD;Sk;0;ON;;;;;N;;;;;\n02F3;MODIFIER LETTER LOW RING;Sk;0;ON;;;;;N;;;;;\n02F4;MODIFIER LETTER MIDDLE GRAVE ACCENT;Sk;0;ON;;;;;N;;;;;\n02F5;MODIFIER LETTER MIDDLE DOUBLE GRAVE ACCENT;Sk;0;ON;;;;;N;;;;;\n02F6;MODIFIER LETTER MIDDLE DOUBLE ACUTE ACCENT;Sk;0;ON;;;;;N;;;;;\n02F7;MODIFIER LETTER LOW TILDE;Sk;0;ON;;;;;N;;;;;\n02F8;MODIFIER LETTER RAISED COLON;Sk;0;ON;;;;;N;;;;;\n02F9;MODIFIER LETTER BEGIN HIGH TONE;Sk;0;ON;;;;;N;;;;;\n02FA;MODIFIER LETTER END HIGH TONE;Sk;0;ON;;;;;N;;;;;\n02FB;MODIFIER LETTER BEGIN LOW TONE;Sk;0;ON;;;;;N;;;;;\n02FC;MODIFIER LETTER END LOW TONE;Sk;0;ON;;;;;N;;;;;\n02FD;MODIFIER LETTER SHELF;Sk;0;ON;;;;;N;;;;;\n02FE;MODIFIER LETTER OPEN SHELF;Sk;0;ON;;;;;N;;;;;\n02FF;MODIFIER LETTER LOW LEFT ARROW;Sk;0;ON;;;;;N;;;;;\n0300;COMBINING GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING GRAVE;;;;\n0301;COMBINING ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING ACUTE;;;;\n0302;COMBINING CIRCUMFLEX ACCENT;Mn;230;NSM;;;;;N;NON-SPACING CIRCUMFLEX;;;;\n0303;COMBINING TILDE;Mn;230;NSM;;;;;N;NON-SPACING TILDE;;;;\n0304;COMBINING MACRON;Mn;230;NSM;;;;;N;NON-SPACING MACRON;;;;\n0305;COMBINING OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING OVERSCORE;;;;\n0306;COMBINING BREVE;Mn;230;NSM;;;;;N;NON-SPACING BREVE;;;;\n0307;COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOT ABOVE;;;;\n0308;COMBINING DIAERESIS;Mn;230;NSM;;;;;N;NON-SPACING DIAERESIS;;;;\n0309;COMBINING HOOK ABOVE;Mn;230;NSM;;;;;N;NON-SPACING HOOK ABOVE;;;;\n030A;COMBINING RING ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RING ABOVE;;;;\n030B;COMBINING DOUBLE ACUTE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE ACUTE;;;;\n030C;COMBINING CARON;Mn;230;NSM;;;;;N;NON-SPACING HACEK;;;;\n030D;COMBINING VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL LINE ABOVE;;;;\n030E;COMBINING DOUBLE VERTICAL LINE ABOVE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE VERTICAL LINE ABOVE;;;;\n030F;COMBINING DOUBLE GRAVE ACCENT;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE GRAVE;;;;\n0310;COMBINING CANDRABINDU;Mn;230;NSM;;;;;N;NON-SPACING CANDRABINDU;;;;\n0311;COMBINING INVERTED BREVE;Mn;230;NSM;;;;;N;NON-SPACING INVERTED BREVE;;;;\n0312;COMBINING TURNED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING TURNED COMMA ABOVE;;;;\n0313;COMBINING COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING COMMA ABOVE;;;;\n0314;COMBINING REVERSED COMMA ABOVE;Mn;230;NSM;;;;;N;NON-SPACING REVERSED COMMA ABOVE;;;;\n0315;COMBINING COMMA ABOVE RIGHT;Mn;232;NSM;;;;;N;NON-SPACING COMMA ABOVE RIGHT;;;;\n0316;COMBINING GRAVE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING GRAVE BELOW;;;;\n0317;COMBINING ACUTE ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING ACUTE BELOW;;;;\n0318;COMBINING LEFT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT TACK BELOW;;;;\n0319;COMBINING RIGHT TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT TACK BELOW;;;;\n031A;COMBINING LEFT ANGLE ABOVE;Mn;232;NSM;;;;;N;NON-SPACING LEFT ANGLE ABOVE;;;;\n031B;COMBINING HORN;Mn;216;NSM;;;;;N;NON-SPACING HORN;;;;\n031C;COMBINING LEFT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING LEFT HALF RING BELOW;;;;\n031D;COMBINING UP TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING UP TACK BELOW;;;;\n031E;COMBINING DOWN TACK BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOWN TACK BELOW;;;;\n031F;COMBINING PLUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING PLUS SIGN BELOW;;;;\n0320;COMBINING MINUS SIGN BELOW;Mn;220;NSM;;;;;N;NON-SPACING MINUS SIGN BELOW;;;;\n0321;COMBINING PALATALIZED HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING PALATALIZED HOOK BELOW;;;;\n0322;COMBINING RETROFLEX HOOK BELOW;Mn;202;NSM;;;;;N;NON-SPACING RETROFLEX HOOK BELOW;;;;\n0323;COMBINING DOT BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOT BELOW;;;;\n0324;COMBINING DIAERESIS BELOW;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE DOT BELOW;;;;\n0325;COMBINING RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RING BELOW;;;;\n0326;COMBINING COMMA BELOW;Mn;220;NSM;;;;;N;NON-SPACING COMMA BELOW;;;;\n0327;COMBINING CEDILLA;Mn;202;NSM;;;;;N;NON-SPACING CEDILLA;;;;\n0328;COMBINING OGONEK;Mn;202;NSM;;;;;N;NON-SPACING OGONEK;;;;\n0329;COMBINING VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;NON-SPACING VERTICAL LINE BELOW;;;;\n032A;COMBINING BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BRIDGE BELOW;;;;\n032B;COMBINING INVERTED DOUBLE ARCH BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED DOUBLE ARCH BELOW;;;;\n032C;COMBINING CARON BELOW;Mn;220;NSM;;;;;N;NON-SPACING HACEK BELOW;;;;\n032D;COMBINING CIRCUMFLEX ACCENT BELOW;Mn;220;NSM;;;;;N;NON-SPACING CIRCUMFLEX BELOW;;;;\n032E;COMBINING BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING BREVE BELOW;;;;\n032F;COMBINING INVERTED BREVE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BREVE BELOW;;;;\n0330;COMBINING TILDE BELOW;Mn;220;NSM;;;;;N;NON-SPACING TILDE BELOW;;;;\n0331;COMBINING MACRON BELOW;Mn;220;NSM;;;;;N;NON-SPACING MACRON BELOW;;;;\n0332;COMBINING LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING UNDERSCORE;;;;\n0333;COMBINING DOUBLE LOW LINE;Mn;220;NSM;;;;;N;NON-SPACING DOUBLE UNDERSCORE;;;;\n0334;COMBINING TILDE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING TILDE OVERLAY;;;;\n0335;COMBINING SHORT STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT BAR OVERLAY;;;;\n0336;COMBINING LONG STROKE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG BAR OVERLAY;;;;\n0337;COMBINING SHORT SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT SLASH OVERLAY;;;;\n0338;COMBINING LONG SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG SLASH OVERLAY;;;;\n0339;COMBINING RIGHT HALF RING BELOW;Mn;220;NSM;;;;;N;NON-SPACING RIGHT HALF RING BELOW;;;;\n033A;COMBINING INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;NON-SPACING INVERTED BRIDGE BELOW;;;;\n033B;COMBINING SQUARE BELOW;Mn;220;NSM;;;;;N;NON-SPACING SQUARE BELOW;;;;\n033C;COMBINING SEAGULL BELOW;Mn;220;NSM;;;;;N;NON-SPACING SEAGULL BELOW;;;;\n033D;COMBINING X ABOVE;Mn;230;NSM;;;;;N;NON-SPACING X ABOVE;;;;\n033E;COMBINING VERTICAL TILDE;Mn;230;NSM;;;;;N;NON-SPACING VERTICAL TILDE;;;;\n033F;COMBINING DOUBLE OVERLINE;Mn;230;NSM;;;;;N;NON-SPACING DOUBLE OVERSCORE;;;;\n0340;COMBINING GRAVE TONE MARK;Mn;230;NSM;0300;;;;N;NON-SPACING GRAVE TONE MARK;;;;\n0341;COMBINING ACUTE TONE MARK;Mn;230;NSM;0301;;;;N;NON-SPACING ACUTE TONE MARK;;;;\n0342;COMBINING GREEK PERISPOMENI;Mn;230;NSM;;;;;N;;;;;\n0343;COMBINING GREEK KORONIS;Mn;230;NSM;0313;;;;N;;;;;\n0344;COMBINING GREEK DIALYTIKA TONOS;Mn;230;NSM;0308 0301;;;;N;GREEK NON-SPACING DIAERESIS TONOS;;;;\n0345;COMBINING GREEK YPOGEGRAMMENI;Mn;240;NSM;;;;;N;GREEK NON-SPACING IOTA BELOW;;0399;;0399\n0346;COMBINING BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;;\n0347;COMBINING EQUALS SIGN BELOW;Mn;220;NSM;;;;;N;;;;;\n0348;COMBINING DOUBLE VERTICAL LINE BELOW;Mn;220;NSM;;;;;N;;;;;\n0349;COMBINING LEFT ANGLE BELOW;Mn;220;NSM;;;;;N;;;;;\n034A;COMBINING NOT TILDE ABOVE;Mn;230;NSM;;;;;N;;;;;\n034B;COMBINING HOMOTHETIC ABOVE;Mn;230;NSM;;;;;N;;;;;\n034C;COMBINING ALMOST EQUAL TO ABOVE;Mn;230;NSM;;;;;N;;;;;\n034D;COMBINING LEFT RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;;\n034E;COMBINING UPWARDS ARROW BELOW;Mn;220;NSM;;;;;N;;;;;\n034F;COMBINING GRAPHEME JOINER;Mn;0;NSM;;;;;N;;;;;\n0350;COMBINING RIGHT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;\n0351;COMBINING LEFT HALF RING ABOVE;Mn;230;NSM;;;;;N;;;;;\n0352;COMBINING FERMATA;Mn;230;NSM;;;;;N;;;;;\n0353;COMBINING X BELOW;Mn;220;NSM;;;;;N;;;;;\n0354;COMBINING LEFT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;\n0355;COMBINING RIGHT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;\n0356;COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;\n0357;COMBINING RIGHT HALF RING ABOVE;Mn;230;NSM;;;;;N;;;;;\n0358;COMBINING DOT ABOVE RIGHT;Mn;232;NSM;;;;;N;;;;;\n0359;COMBINING ASTERISK BELOW;Mn;220;NSM;;;;;N;;;;;\n035A;COMBINING DOUBLE RING BELOW;Mn;220;NSM;;;;;N;;;;;\n035B;COMBINING ZIGZAG ABOVE;Mn;230;NSM;;;;;N;;;;;\n035C;COMBINING DOUBLE BREVE BELOW;Mn;233;NSM;;;;;N;;;;;\n035D;COMBINING DOUBLE BREVE;Mn;234;NSM;;;;;N;;;;;\n035E;COMBINING DOUBLE MACRON;Mn;234;NSM;;;;;N;;;;;\n035F;COMBINING DOUBLE MACRON BELOW;Mn;233;NSM;;;;;N;;;;;\n0360;COMBINING DOUBLE TILDE;Mn;234;NSM;;;;;N;;;;;\n0361;COMBINING DOUBLE INVERTED BREVE;Mn;234;NSM;;;;;N;;;;;\n0362;COMBINING DOUBLE RIGHTWARDS ARROW BELOW;Mn;233;NSM;;;;;N;;;;;\n0363;COMBINING LATIN SMALL LETTER A;Mn;230;NSM;;;;;N;;;;;\n0364;COMBINING LATIN SMALL LETTER E;Mn;230;NSM;;;;;N;;;;;\n0365;COMBINING LATIN SMALL LETTER I;Mn;230;NSM;;;;;N;;;;;\n0366;COMBINING LATIN SMALL LETTER O;Mn;230;NSM;;;;;N;;;;;\n0367;COMBINING LATIN SMALL LETTER U;Mn;230;NSM;;;;;N;;;;;\n0368;COMBINING LATIN SMALL LETTER C;Mn;230;NSM;;;;;N;;;;;\n0369;COMBINING LATIN SMALL LETTER D;Mn;230;NSM;;;;;N;;;;;\n036A;COMBINING LATIN SMALL LETTER H;Mn;230;NSM;;;;;N;;;;;\n036B;COMBINING LATIN SMALL LETTER M;Mn;230;NSM;;;;;N;;;;;\n036C;COMBINING LATIN SMALL LETTER R;Mn;230;NSM;;;;;N;;;;;\n036D;COMBINING LATIN SMALL LETTER T;Mn;230;NSM;;;;;N;;;;;\n036E;COMBINING LATIN SMALL LETTER V;Mn;230;NSM;;;;;N;;;;;\n036F;COMBINING LATIN SMALL LETTER X;Mn;230;NSM;;;;;N;;;;;\n0370;GREEK CAPITAL LETTER HETA;Lu;0;L;;;;;N;;;;0371;\n0371;GREEK SMALL LETTER HETA;Ll;0;L;;;;;N;;;0370;;0370\n0372;GREEK CAPITAL LETTER ARCHAIC SAMPI;Lu;0;L;;;;;N;;;;0373;\n0373;GREEK SMALL LETTER ARCHAIC SAMPI;Ll;0;L;;;;;N;;;0372;;0372\n0374;GREEK NUMERAL SIGN;Lm;0;ON;02B9;;;;N;GREEK UPPER NUMERAL SIGN;;;;\n0375;GREEK LOWER NUMERAL SIGN;Sk;0;ON;;;;;N;;;;;\n0376;GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA;Lu;0;L;;;;;N;;;;0377;\n0377;GREEK SMALL LETTER PAMPHYLIAN DIGAMMA;Ll;0;L;;;;;N;;;0376;;0376\n037A;GREEK YPOGEGRAMMENI;Lm;0;L;<compat> 0020 0345;;;;N;GREEK SPACING IOTA BELOW;;;;\n037B;GREEK SMALL REVERSED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FD;;03FD\n037C;GREEK SMALL DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FE;;03FE\n037D;GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL;Ll;0;L;;;;;N;;;03FF;;03FF\n037E;GREEK QUESTION MARK;Po;0;ON;003B;;;;N;;;;;\n037F;GREEK CAPITAL LETTER YOT;Lu;0;L;;;;;N;;;;03F3;\n0384;GREEK TONOS;Sk;0;ON;<compat> 0020 0301;;;;N;GREEK SPACING TONOS;;;;\n0385;GREEK DIALYTIKA TONOS;Sk;0;ON;00A8 0301;;;;N;GREEK SPACING DIAERESIS TONOS;;;;\n0386;GREEK CAPITAL LETTER ALPHA WITH TONOS;Lu;0;L;0391 0301;;;;N;GREEK CAPITAL LETTER ALPHA TONOS;;;03AC;\n0387;GREEK ANO TELEIA;Po;0;ON;00B7;;;;N;;;;;\n0388;GREEK CAPITAL LETTER EPSILON WITH TONOS;Lu;0;L;0395 0301;;;;N;GREEK CAPITAL LETTER EPSILON TONOS;;;03AD;\n0389;GREEK CAPITAL LETTER ETA WITH TONOS;Lu;0;L;0397 0301;;;;N;GREEK CAPITAL LETTER ETA TONOS;;;03AE;\n038A;GREEK CAPITAL LETTER IOTA WITH TONOS;Lu;0;L;0399 0301;;;;N;GREEK CAPITAL LETTER IOTA TONOS;;;03AF;\n038C;GREEK CAPITAL LETTER OMICRON WITH TONOS;Lu;0;L;039F 0301;;;;N;GREEK CAPITAL LETTER OMICRON TONOS;;;03CC;\n038E;GREEK CAPITAL LETTER UPSILON WITH TONOS;Lu;0;L;03A5 0301;;;;N;GREEK CAPITAL LETTER UPSILON TONOS;;;03CD;\n038F;GREEK CAPITAL LETTER OMEGA WITH TONOS;Lu;0;L;03A9 0301;;;;N;GREEK CAPITAL LETTER OMEGA TONOS;;;03CE;\n0390;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS;Ll;0;L;03CA 0301;;;;N;GREEK SMALL LETTER IOTA DIAERESIS TONOS;;;;\n0391;GREEK CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;03B1;\n0392;GREEK CAPITAL LETTER BETA;Lu;0;L;;;;;N;;;;03B2;\n0393;GREEK CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;03B3;\n0394;GREEK CAPITAL LETTER DELTA;Lu;0;L;;;;;N;;;;03B4;\n0395;GREEK CAPITAL LETTER EPSILON;Lu;0;L;;;;;N;;;;03B5;\n0396;GREEK CAPITAL LETTER ZETA;Lu;0;L;;;;;N;;;;03B6;\n0397;GREEK CAPITAL LETTER ETA;Lu;0;L;;;;;N;;;;03B7;\n0398;GREEK CAPITAL LETTER THETA;Lu;0;L;;;;;N;;;;03B8;\n0399;GREEK CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;03B9;\n039A;GREEK CAPITAL LETTER KAPPA;Lu;0;L;;;;;N;;;;03BA;\n039B;GREEK CAPITAL LETTER LAMDA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER LAMBDA;;;03BB;\n039C;GREEK CAPITAL LETTER MU;Lu;0;L;;;;;N;;;;03BC;\n039D;GREEK CAPITAL LETTER NU;Lu;0;L;;;;;N;;;;03BD;\n039E;GREEK CAPITAL LETTER XI;Lu;0;L;;;;;N;;;;03BE;\n039F;GREEK CAPITAL LETTER OMICRON;Lu;0;L;;;;;N;;;;03BF;\n03A0;GREEK CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;03C0;\n03A1;GREEK CAPITAL LETTER RHO;Lu;0;L;;;;;N;;;;03C1;\n03A3;GREEK CAPITAL LETTER SIGMA;Lu;0;L;;;;;N;;;;03C3;\n03A4;GREEK CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;03C4;\n03A5;GREEK CAPITAL LETTER UPSILON;Lu;0;L;;;;;N;;;;03C5;\n03A6;GREEK CAPITAL LETTER PHI;Lu;0;L;;;;;N;;;;03C6;\n03A7;GREEK CAPITAL LETTER CHI;Lu;0;L;;;;;N;;;;03C7;\n03A8;GREEK CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;03C8;\n03A9;GREEK CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;03C9;\n03AA;GREEK CAPITAL LETTER IOTA WITH DIALYTIKA;Lu;0;L;0399 0308;;;;N;GREEK CAPITAL LETTER IOTA DIAERESIS;;;03CA;\n03AB;GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA;Lu;0;L;03A5 0308;;;;N;GREEK CAPITAL LETTER UPSILON DIAERESIS;;;03CB;\n03AC;GREEK SMALL LETTER ALPHA WITH TONOS;Ll;0;L;03B1 0301;;;;N;GREEK SMALL LETTER ALPHA TONOS;;0386;;0386\n03AD;GREEK SMALL LETTER EPSILON WITH TONOS;Ll;0;L;03B5 0301;;;;N;GREEK SMALL LETTER EPSILON TONOS;;0388;;0388\n03AE;GREEK SMALL LETTER ETA WITH TONOS;Ll;0;L;03B7 0301;;;;N;GREEK SMALL LETTER ETA TONOS;;0389;;0389\n03AF;GREEK SMALL LETTER IOTA WITH TONOS;Ll;0;L;03B9 0301;;;;N;GREEK SMALL LETTER IOTA TONOS;;038A;;038A\n03B0;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS;Ll;0;L;03CB 0301;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS TONOS;;;;\n03B1;GREEK SMALL LETTER ALPHA;Ll;0;L;;;;;N;;;0391;;0391\n03B2;GREEK SMALL LETTER BETA;Ll;0;L;;;;;N;;;0392;;0392\n03B3;GREEK SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0393;;0393\n03B4;GREEK SMALL LETTER DELTA;Ll;0;L;;;;;N;;;0394;;0394\n03B5;GREEK SMALL LETTER EPSILON;Ll;0;L;;;;;N;;;0395;;0395\n03B6;GREEK SMALL LETTER ZETA;Ll;0;L;;;;;N;;;0396;;0396\n03B7;GREEK SMALL LETTER ETA;Ll;0;L;;;;;N;;;0397;;0397\n03B8;GREEK SMALL LETTER THETA;Ll;0;L;;;;;N;;;0398;;0398\n03B9;GREEK SMALL LETTER IOTA;Ll;0;L;;;;;N;;;0399;;0399\n03BA;GREEK SMALL LETTER KAPPA;Ll;0;L;;;;;N;;;039A;;039A\n03BB;GREEK SMALL LETTER LAMDA;Ll;0;L;;;;;N;GREEK SMALL LETTER LAMBDA;;039B;;039B\n03BC;GREEK SMALL LETTER MU;Ll;0;L;;;;;N;;;039C;;039C\n03BD;GREEK SMALL LETTER NU;Ll;0;L;;;;;N;;;039D;;039D\n03BE;GREEK SMALL LETTER XI;Ll;0;L;;;;;N;;;039E;;039E\n03BF;GREEK SMALL LETTER OMICRON;Ll;0;L;;;;;N;;;039F;;039F\n03C0;GREEK SMALL LETTER PI;Ll;0;L;;;;;N;;;03A0;;03A0\n03C1;GREEK SMALL LETTER RHO;Ll;0;L;;;;;N;;;03A1;;03A1\n03C2;GREEK SMALL LETTER FINAL SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3\n03C3;GREEK SMALL LETTER SIGMA;Ll;0;L;;;;;N;;;03A3;;03A3\n03C4;GREEK SMALL LETTER TAU;Ll;0;L;;;;;N;;;03A4;;03A4\n03C5;GREEK SMALL LETTER UPSILON;Ll;0;L;;;;;N;;;03A5;;03A5\n03C6;GREEK SMALL LETTER PHI;Ll;0;L;;;;;N;;;03A6;;03A6\n03C7;GREEK SMALL LETTER CHI;Ll;0;L;;;;;N;;;03A7;;03A7\n03C8;GREEK SMALL LETTER PSI;Ll;0;L;;;;;N;;;03A8;;03A8\n03C9;GREEK SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;03A9;;03A9\n03CA;GREEK SMALL LETTER IOTA WITH DIALYTIKA;Ll;0;L;03B9 0308;;;;N;GREEK SMALL LETTER IOTA DIAERESIS;;03AA;;03AA\n03CB;GREEK SMALL LETTER UPSILON WITH DIALYTIKA;Ll;0;L;03C5 0308;;;;N;GREEK SMALL LETTER UPSILON DIAERESIS;;03AB;;03AB\n03CC;GREEK SMALL LETTER OMICRON WITH TONOS;Ll;0;L;03BF 0301;;;;N;GREEK SMALL LETTER OMICRON TONOS;;038C;;038C\n03CD;GREEK SMALL LETTER UPSILON WITH TONOS;Ll;0;L;03C5 0301;;;;N;GREEK SMALL LETTER UPSILON TONOS;;038E;;038E\n03CE;GREEK SMALL LETTER OMEGA WITH TONOS;Ll;0;L;03C9 0301;;;;N;GREEK SMALL LETTER OMEGA TONOS;;038F;;038F\n03CF;GREEK CAPITAL KAI SYMBOL;Lu;0;L;;;;;N;;;;03D7;\n03D0;GREEK BETA SYMBOL;Ll;0;L;<compat> 03B2;;;;N;GREEK SMALL LETTER CURLED BETA;;0392;;0392\n03D1;GREEK THETA SYMBOL;Ll;0;L;<compat> 03B8;;;;N;GREEK SMALL LETTER SCRIPT THETA;;0398;;0398\n03D2;GREEK UPSILON WITH HOOK SYMBOL;Lu;0;L;<compat> 03A5;;;;N;GREEK CAPITAL LETTER UPSILON HOOK;;;;\n03D3;GREEK UPSILON WITH ACUTE AND HOOK SYMBOL;Lu;0;L;03D2 0301;;;;N;GREEK CAPITAL LETTER UPSILON HOOK TONOS;;;;\n03D4;GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL;Lu;0;L;03D2 0308;;;;N;GREEK CAPITAL LETTER UPSILON HOOK DIAERESIS;;;;\n03D5;GREEK PHI SYMBOL;Ll;0;L;<compat> 03C6;;;;N;GREEK SMALL LETTER SCRIPT PHI;;03A6;;03A6\n03D6;GREEK PI SYMBOL;Ll;0;L;<compat> 03C0;;;;N;GREEK SMALL LETTER OMEGA PI;;03A0;;03A0\n03D7;GREEK KAI SYMBOL;Ll;0;L;;;;;N;;;03CF;;03CF\n03D8;GREEK LETTER ARCHAIC KOPPA;Lu;0;L;;;;;N;;;;03D9;\n03D9;GREEK SMALL LETTER ARCHAIC KOPPA;Ll;0;L;;;;;N;;;03D8;;03D8\n03DA;GREEK LETTER STIGMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER STIGMA;;;03DB;\n03DB;GREEK SMALL LETTER STIGMA;Ll;0;L;;;;;N;;;03DA;;03DA\n03DC;GREEK LETTER DIGAMMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DIGAMMA;;;03DD;\n03DD;GREEK SMALL LETTER DIGAMMA;Ll;0;L;;;;;N;;;03DC;;03DC\n03DE;GREEK LETTER KOPPA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KOPPA;;;03DF;\n03DF;GREEK SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;03DE;;03DE\n03E0;GREEK LETTER SAMPI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SAMPI;;;03E1;\n03E1;GREEK SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;03E0;;03E0\n03E2;COPTIC CAPITAL LETTER SHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHEI;;;03E3;\n03E3;COPTIC SMALL LETTER SHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER SHEI;;03E2;;03E2\n03E4;COPTIC CAPITAL LETTER FEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER FEI;;;03E5;\n03E5;COPTIC SMALL LETTER FEI;Ll;0;L;;;;;N;GREEK SMALL LETTER FEI;;03E4;;03E4\n03E6;COPTIC CAPITAL LETTER KHEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER KHEI;;;03E7;\n03E7;COPTIC SMALL LETTER KHEI;Ll;0;L;;;;;N;GREEK SMALL LETTER KHEI;;03E6;;03E6\n03E8;COPTIC CAPITAL LETTER HORI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER HORI;;;03E9;\n03E9;COPTIC SMALL LETTER HORI;Ll;0;L;;;;;N;GREEK SMALL LETTER HORI;;03E8;;03E8\n03EA;COPTIC CAPITAL LETTER GANGIA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER GANGIA;;;03EB;\n03EB;COPTIC SMALL LETTER GANGIA;Ll;0;L;;;;;N;GREEK SMALL LETTER GANGIA;;03EA;;03EA\n03EC;COPTIC CAPITAL LETTER SHIMA;Lu;0;L;;;;;N;GREEK CAPITAL LETTER SHIMA;;;03ED;\n03ED;COPTIC SMALL LETTER SHIMA;Ll;0;L;;;;;N;GREEK SMALL LETTER SHIMA;;03EC;;03EC\n03EE;COPTIC CAPITAL LETTER DEI;Lu;0;L;;;;;N;GREEK CAPITAL LETTER DEI;;;03EF;\n03EF;COPTIC SMALL LETTER DEI;Ll;0;L;;;;;N;GREEK SMALL LETTER DEI;;03EE;;03EE\n03F0;GREEK KAPPA SYMBOL;Ll;0;L;<compat> 03BA;;;;N;GREEK SMALL LETTER SCRIPT KAPPA;;039A;;039A\n03F1;GREEK RHO SYMBOL;Ll;0;L;<compat> 03C1;;;;N;GREEK SMALL LETTER TAILED RHO;;03A1;;03A1\n03F2;GREEK LUNATE SIGMA SYMBOL;Ll;0;L;<compat> 03C2;;;;N;GREEK SMALL LETTER LUNATE SIGMA;;03F9;;03F9\n03F3;GREEK LETTER YOT;Ll;0;L;;;;;N;;;037F;;037F\n03F4;GREEK CAPITAL THETA SYMBOL;Lu;0;L;<compat> 0398;;;;N;;;;03B8;\n03F5;GREEK LUNATE EPSILON SYMBOL;Ll;0;L;<compat> 03B5;;;;N;;;0395;;0395\n03F6;GREEK REVERSED LUNATE EPSILON SYMBOL;Sm;0;ON;;;;;N;;;;;\n03F7;GREEK CAPITAL LETTER SHO;Lu;0;L;;;;;N;;;;03F8;\n03F8;GREEK SMALL LETTER SHO;Ll;0;L;;;;;N;;;03F7;;03F7\n03F9;GREEK CAPITAL LUNATE SIGMA SYMBOL;Lu;0;L;<compat> 03A3;;;;N;;;;03F2;\n03FA;GREEK CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;03FB;\n03FB;GREEK SMALL LETTER SAN;Ll;0;L;;;;;N;;;03FA;;03FA\n03FC;GREEK RHO WITH STROKE SYMBOL;Ll;0;L;;;;;N;;;;;\n03FD;GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037B;\n03FE;GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037C;\n03FF;GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL;Lu;0;L;;;;;N;;;;037D;\n0400;CYRILLIC CAPITAL LETTER IE WITH GRAVE;Lu;0;L;0415 0300;;;;N;;;;0450;\n0401;CYRILLIC CAPITAL LETTER IO;Lu;0;L;0415 0308;;;;N;;;;0451;\n0402;CYRILLIC CAPITAL LETTER DJE;Lu;0;L;;;;;N;;;;0452;\n0403;CYRILLIC CAPITAL LETTER GJE;Lu;0;L;0413 0301;;;;N;;;;0453;\n0404;CYRILLIC CAPITAL LETTER UKRAINIAN IE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER E;;;0454;\n0405;CYRILLIC CAPITAL LETTER DZE;Lu;0;L;;;;;N;;;;0455;\n0406;CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER I;;;0456;\n0407;CYRILLIC CAPITAL LETTER YI;Lu;0;L;0406 0308;;;;N;;;;0457;\n0408;CYRILLIC CAPITAL LETTER JE;Lu;0;L;;;;;N;;;;0458;\n0409;CYRILLIC CAPITAL LETTER LJE;Lu;0;L;;;;;N;;;;0459;\n040A;CYRILLIC CAPITAL LETTER NJE;Lu;0;L;;;;;N;;;;045A;\n040B;CYRILLIC CAPITAL LETTER TSHE;Lu;0;L;;;;;N;;;;045B;\n040C;CYRILLIC CAPITAL LETTER KJE;Lu;0;L;041A 0301;;;;N;;;;045C;\n040D;CYRILLIC CAPITAL LETTER I WITH GRAVE;Lu;0;L;0418 0300;;;;N;;;;045D;\n040E;CYRILLIC CAPITAL LETTER SHORT U;Lu;0;L;0423 0306;;;;N;;;;045E;\n040F;CYRILLIC CAPITAL LETTER DZHE;Lu;0;L;;;;;N;;;;045F;\n0410;CYRILLIC CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0430;\n0411;CYRILLIC CAPITAL LETTER BE;Lu;0;L;;;;;N;;;;0431;\n0412;CYRILLIC CAPITAL LETTER VE;Lu;0;L;;;;;N;;;;0432;\n0413;CYRILLIC CAPITAL LETTER GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE;;;0433;\n0414;CYRILLIC CAPITAL LETTER DE;Lu;0;L;;;;;N;;;;0434;\n0415;CYRILLIC CAPITAL LETTER IE;Lu;0;L;;;;;N;;;;0435;\n0416;CYRILLIC CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;0436;\n0417;CYRILLIC CAPITAL LETTER ZE;Lu;0;L;;;;;N;;;;0437;\n0418;CYRILLIC CAPITAL LETTER I;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER II;;;0438;\n0419;CYRILLIC CAPITAL LETTER SHORT I;Lu;0;L;0418 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT II;;;0439;\n041A;CYRILLIC CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;043A;\n041B;CYRILLIC CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;043B;\n041C;CYRILLIC CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;043C;\n041D;CYRILLIC CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;043D;\n041E;CYRILLIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;043E;\n041F;CYRILLIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;043F;\n0420;CYRILLIC CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;0440;\n0421;CYRILLIC CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;0441;\n0422;CYRILLIC CAPITAL LETTER TE;Lu;0;L;;;;;N;;;;0442;\n0423;CYRILLIC CAPITAL LETTER U;Lu;0;L;;;;;N;;;;0443;\n0424;CYRILLIC CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;0444;\n0425;CYRILLIC CAPITAL LETTER HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA;;;0445;\n0426;CYRILLIC CAPITAL LETTER TSE;Lu;0;L;;;;;N;;;;0446;\n0427;CYRILLIC CAPITAL LETTER CHE;Lu;0;L;;;;;N;;;;0447;\n0428;CYRILLIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0448;\n0429;CYRILLIC CAPITAL LETTER SHCHA;Lu;0;L;;;;;N;;;;0449;\n042A;CYRILLIC CAPITAL LETTER HARD SIGN;Lu;0;L;;;;;N;;;;044A;\n042B;CYRILLIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER YERI;;;044B;\n042C;CYRILLIC CAPITAL LETTER SOFT SIGN;Lu;0;L;;;;;N;;;;044C;\n042D;CYRILLIC CAPITAL LETTER E;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED E;;;044D;\n042E;CYRILLIC CAPITAL LETTER YU;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IU;;;044E;\n042F;CYRILLIC CAPITAL LETTER YA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IA;;;044F;\n0430;CYRILLIC SMALL LETTER A;Ll;0;L;;;;;N;;;0410;;0410\n0431;CYRILLIC SMALL LETTER BE;Ll;0;L;;;;;N;;;0411;;0411\n0432;CYRILLIC SMALL LETTER VE;Ll;0;L;;;;;N;;;0412;;0412\n0433;CYRILLIC SMALL LETTER GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE;;0413;;0413\n0434;CYRILLIC SMALL LETTER DE;Ll;0;L;;;;;N;;;0414;;0414\n0435;CYRILLIC SMALL LETTER IE;Ll;0;L;;;;;N;;;0415;;0415\n0436;CYRILLIC SMALL LETTER ZHE;Ll;0;L;;;;;N;;;0416;;0416\n0437;CYRILLIC SMALL LETTER ZE;Ll;0;L;;;;;N;;;0417;;0417\n0438;CYRILLIC SMALL LETTER I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER II;;0418;;0418\n0439;CYRILLIC SMALL LETTER SHORT I;Ll;0;L;0438 0306;;;;N;CYRILLIC SMALL LETTER SHORT II;;0419;;0419\n043A;CYRILLIC SMALL LETTER KA;Ll;0;L;;;;;N;;;041A;;041A\n043B;CYRILLIC SMALL LETTER EL;Ll;0;L;;;;;N;;;041B;;041B\n043C;CYRILLIC SMALL LETTER EM;Ll;0;L;;;;;N;;;041C;;041C\n043D;CYRILLIC SMALL LETTER EN;Ll;0;L;;;;;N;;;041D;;041D\n043E;CYRILLIC SMALL LETTER O;Ll;0;L;;;;;N;;;041E;;041E\n043F;CYRILLIC SMALL LETTER PE;Ll;0;L;;;;;N;;;041F;;041F\n0440;CYRILLIC SMALL LETTER ER;Ll;0;L;;;;;N;;;0420;;0420\n0441;CYRILLIC SMALL LETTER ES;Ll;0;L;;;;;N;;;0421;;0421\n0442;CYRILLIC SMALL LETTER TE;Ll;0;L;;;;;N;;;0422;;0422\n0443;CYRILLIC SMALL LETTER U;Ll;0;L;;;;;N;;;0423;;0423\n0444;CYRILLIC SMALL LETTER EF;Ll;0;L;;;;;N;;;0424;;0424\n0445;CYRILLIC SMALL LETTER HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA;;0425;;0425\n0446;CYRILLIC SMALL LETTER TSE;Ll;0;L;;;;;N;;;0426;;0426\n0447;CYRILLIC SMALL LETTER CHE;Ll;0;L;;;;;N;;;0427;;0427\n0448;CYRILLIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;0428;;0428\n0449;CYRILLIC SMALL LETTER SHCHA;Ll;0;L;;;;;N;;;0429;;0429\n044A;CYRILLIC SMALL LETTER HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A\n044B;CYRILLIC SMALL LETTER YERU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER YERI;;042B;;042B\n044C;CYRILLIC SMALL LETTER SOFT SIGN;Ll;0;L;;;;;N;;;042C;;042C\n044D;CYRILLIC SMALL LETTER E;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED E;;042D;;042D\n044E;CYRILLIC SMALL LETTER YU;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IU;;042E;;042E\n044F;CYRILLIC SMALL LETTER YA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IA;;042F;;042F\n0450;CYRILLIC SMALL LETTER IE WITH GRAVE;Ll;0;L;0435 0300;;;;N;;;0400;;0400\n0451;CYRILLIC SMALL LETTER IO;Ll;0;L;0435 0308;;;;N;;;0401;;0401\n0452;CYRILLIC SMALL LETTER DJE;Ll;0;L;;;;;N;;;0402;;0402\n0453;CYRILLIC SMALL LETTER GJE;Ll;0;L;0433 0301;;;;N;;;0403;;0403\n0454;CYRILLIC SMALL LETTER UKRAINIAN IE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER E;;0404;;0404\n0455;CYRILLIC SMALL LETTER DZE;Ll;0;L;;;;;N;;;0405;;0405\n0456;CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER I;;0406;;0406\n0457;CYRILLIC SMALL LETTER YI;Ll;0;L;0456 0308;;;;N;;;0407;;0407\n0458;CYRILLIC SMALL LETTER JE;Ll;0;L;;;;;N;;;0408;;0408\n0459;CYRILLIC SMALL LETTER LJE;Ll;0;L;;;;;N;;;0409;;0409\n045A;CYRILLIC SMALL LETTER NJE;Ll;0;L;;;;;N;;;040A;;040A\n045B;CYRILLIC SMALL LETTER TSHE;Ll;0;L;;;;;N;;;040B;;040B\n045C;CYRILLIC SMALL LETTER KJE;Ll;0;L;043A 0301;;;;N;;;040C;;040C\n045D;CYRILLIC SMALL LETTER I WITH GRAVE;Ll;0;L;0438 0300;;;;N;;;040D;;040D\n045E;CYRILLIC SMALL LETTER SHORT U;Ll;0;L;0443 0306;;;;N;;;040E;;040E\n045F;CYRILLIC SMALL LETTER DZHE;Ll;0;L;;;;;N;;;040F;;040F\n0460;CYRILLIC CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;0461;\n0461;CYRILLIC SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;0460;;0460\n0462;CYRILLIC CAPITAL LETTER YAT;Lu;0;L;;;;;N;;;;0463;\n0463;CYRILLIC SMALL LETTER YAT;Ll;0;L;;;;;N;;;0462;;0462\n0464;CYRILLIC CAPITAL LETTER IOTIFIED E;Lu;0;L;;;;;N;;;;0465;\n0465;CYRILLIC SMALL LETTER IOTIFIED E;Ll;0;L;;;;;N;;;0464;;0464\n0466;CYRILLIC CAPITAL LETTER LITTLE YUS;Lu;0;L;;;;;N;;;;0467;\n0467;CYRILLIC SMALL LETTER LITTLE YUS;Ll;0;L;;;;;N;;;0466;;0466\n0468;CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS;Lu;0;L;;;;;N;;;;0469;\n0469;CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS;Ll;0;L;;;;;N;;;0468;;0468\n046A;CYRILLIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;046B;\n046B;CYRILLIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;046A;;046A\n046C;CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS;Lu;0;L;;;;;N;;;;046D;\n046D;CYRILLIC SMALL LETTER IOTIFIED BIG YUS;Ll;0;L;;;;;N;;;046C;;046C\n046E;CYRILLIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;046F;\n046F;CYRILLIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;046E;;046E\n0470;CYRILLIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;0471;\n0471;CYRILLIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;0470;;0470\n0472;CYRILLIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;0473;\n0473;CYRILLIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;0472;;0472\n0474;CYRILLIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;0475;\n0475;CYRILLIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;0474;;0474\n0476;CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Lu;0;L;0474 030F;;;;N;CYRILLIC CAPITAL LETTER IZHITSA DOUBLE GRAVE;;;0477;\n0477;CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT;Ll;0;L;0475 030F;;;;N;CYRILLIC SMALL LETTER IZHITSA DOUBLE GRAVE;;0476;;0476\n0478;CYRILLIC CAPITAL LETTER UK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER UK DIGRAPH;;;0479;\n0479;CYRILLIC SMALL LETTER UK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER UK DIGRAPH;;0478;;0478\n047A;CYRILLIC CAPITAL LETTER ROUND OMEGA;Lu;0;L;;;;;N;;;;047B;\n047B;CYRILLIC SMALL LETTER ROUND OMEGA;Ll;0;L;;;;;N;;;047A;;047A\n047C;CYRILLIC CAPITAL LETTER OMEGA WITH TITLO;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER OMEGA TITLO;;;047D;\n047D;CYRILLIC SMALL LETTER OMEGA WITH TITLO;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER OMEGA TITLO;;047C;;047C\n047E;CYRILLIC CAPITAL LETTER OT;Lu;0;L;;;;;N;;;;047F;\n047F;CYRILLIC SMALL LETTER OT;Ll;0;L;;;;;N;;;047E;;047E\n0480;CYRILLIC CAPITAL LETTER KOPPA;Lu;0;L;;;;;N;;;;0481;\n0481;CYRILLIC SMALL LETTER KOPPA;Ll;0;L;;;;;N;;;0480;;0480\n0482;CYRILLIC THOUSANDS SIGN;So;0;L;;;;;N;;;;;\n0483;COMBINING CYRILLIC TITLO;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING TITLO;;;;\n0484;COMBINING CYRILLIC PALATALIZATION;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PALATALIZATION;;;;\n0485;COMBINING CYRILLIC DASIA PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING DASIA PNEUMATA;;;;\n0486;COMBINING CYRILLIC PSILI PNEUMATA;Mn;230;NSM;;;;;N;CYRILLIC NON-SPACING PSILI PNEUMATA;;;;\n0487;COMBINING CYRILLIC POKRYTIE;Mn;230;NSM;;;;;N;;;;;\n0488;COMBINING CYRILLIC HUNDRED THOUSANDS SIGN;Me;0;NSM;;;;;N;;;;;\n0489;COMBINING CYRILLIC MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;\n048A;CYRILLIC CAPITAL LETTER SHORT I WITH TAIL;Lu;0;L;;;;;N;;;;048B;\n048B;CYRILLIC SMALL LETTER SHORT I WITH TAIL;Ll;0;L;;;;;N;;;048A;;048A\n048C;CYRILLIC CAPITAL LETTER SEMISOFT SIGN;Lu;0;L;;;;;N;;;;048D;\n048D;CYRILLIC SMALL LETTER SEMISOFT SIGN;Ll;0;L;;;;;N;;;048C;;048C\n048E;CYRILLIC CAPITAL LETTER ER WITH TICK;Lu;0;L;;;;;N;;;;048F;\n048F;CYRILLIC SMALL LETTER ER WITH TICK;Ll;0;L;;;;;N;;;048E;;048E\n0490;CYRILLIC CAPITAL LETTER GHE WITH UPTURN;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE WITH UPTURN;;;0491;\n0491;CYRILLIC SMALL LETTER GHE WITH UPTURN;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE WITH UPTURN;;0490;;0490\n0492;CYRILLIC CAPITAL LETTER GHE WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE BAR;;;0493;\n0493;CYRILLIC SMALL LETTER GHE WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE BAR;;0492;;0492\n0494;CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER GE HOOK;;;0495;\n0495;CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER GE HOOK;;0494;;0494\n0496;CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZHE WITH RIGHT DESCENDER;;;0497;\n0497;CYRILLIC SMALL LETTER ZHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZHE WITH RIGHT DESCENDER;;0496;;0496\n0498;CYRILLIC CAPITAL LETTER ZE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ZE CEDILLA;;;0499;\n0499;CYRILLIC SMALL LETTER ZE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ZE CEDILLA;;0498;;0498\n049A;CYRILLIC CAPITAL LETTER KA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA WITH RIGHT DESCENDER;;;049B;\n049B;CYRILLIC SMALL LETTER KA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA WITH RIGHT DESCENDER;;049A;;049A\n049C;CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA VERTICAL BAR;;;049D;\n049D;CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA VERTICAL BAR;;049C;;049C\n049E;CYRILLIC CAPITAL LETTER KA WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA BAR;;;049F;\n049F;CYRILLIC SMALL LETTER KA WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA BAR;;049E;;049E\n04A0;CYRILLIC CAPITAL LETTER BASHKIR KA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER REVERSED GE KA;;;04A1;\n04A1;CYRILLIC SMALL LETTER BASHKIR KA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER REVERSED GE KA;;04A0;;04A0\n04A2;CYRILLIC CAPITAL LETTER EN WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN WITH RIGHT DESCENDER;;;04A3;\n04A3;CYRILLIC SMALL LETTER EN WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN WITH RIGHT DESCENDER;;04A2;;04A2\n04A4;CYRILLIC CAPITAL LIGATURE EN GHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN GE;;;04A5;\n04A5;CYRILLIC SMALL LIGATURE EN GHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN GE;;04A4;;04A4\n04A6;CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER PE HOOK;;;04A7;\n04A7;CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER PE HOOK;;04A6;;04A6\n04A8;CYRILLIC CAPITAL LETTER ABKHASIAN HA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER O HOOK;;;04A9;\n04A9;CYRILLIC SMALL LETTER ABKHASIAN HA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER O HOOK;;04A8;;04A8\n04AA;CYRILLIC CAPITAL LETTER ES WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER ES CEDILLA;;;04AB;\n04AB;CYRILLIC SMALL LETTER ES WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER ES CEDILLA;;04AA;;04AA\n04AC;CYRILLIC CAPITAL LETTER TE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE WITH RIGHT DESCENDER;;;04AD;\n04AD;CYRILLIC SMALL LETTER TE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE WITH RIGHT DESCENDER;;04AC;;04AC\n04AE;CYRILLIC CAPITAL LETTER STRAIGHT U;Lu;0;L;;;;;N;;;;04AF;\n04AF;CYRILLIC SMALL LETTER STRAIGHT U;Ll;0;L;;;;;N;;;04AE;;04AE\n04B0;CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER STRAIGHT U BAR;;;04B1;\n04B1;CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER STRAIGHT U BAR;;04B0;;04B0\n04B2;CYRILLIC CAPITAL LETTER HA WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KHA WITH RIGHT DESCENDER;;;04B3;\n04B3;CYRILLIC SMALL LETTER HA WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KHA WITH RIGHT DESCENDER;;04B2;;04B2\n04B4;CYRILLIC CAPITAL LIGATURE TE TSE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER TE TSE;;;04B5;\n04B5;CYRILLIC SMALL LIGATURE TE TSE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER TE TSE;;04B4;;04B4\n04B6;CYRILLIC CAPITAL LETTER CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH RIGHT DESCENDER;;;04B7;\n04B7;CYRILLIC SMALL LETTER CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH RIGHT DESCENDER;;04B6;;04B6\n04B8;CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE VERTICAL BAR;;;04B9;\n04B9;CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE VERTICAL BAR;;04B8;;04B8\n04BA;CYRILLIC CAPITAL LETTER SHHA;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER H;;;04BB;\n04BB;CYRILLIC SMALL LETTER SHHA;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER H;;04BA;;04BA\n04BC;CYRILLIC CAPITAL LETTER ABKHASIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK;;;04BD;\n04BD;CYRILLIC SMALL LETTER ABKHASIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK;;04BC;;04BC\n04BE;CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER IE HOOK OGONEK;;;04BF;\n04BF;CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER IE HOOK OGONEK;;04BE;;04BE\n04C0;CYRILLIC LETTER PALOCHKA;Lu;0;L;;;;;N;CYRILLIC LETTER I;;;04CF;\n04C1;CYRILLIC CAPITAL LETTER ZHE WITH BREVE;Lu;0;L;0416 0306;;;;N;CYRILLIC CAPITAL LETTER SHORT ZHE;;;04C2;\n04C2;CYRILLIC SMALL LETTER ZHE WITH BREVE;Ll;0;L;0436 0306;;;;N;CYRILLIC SMALL LETTER SHORT ZHE;;04C1;;04C1\n04C3;CYRILLIC CAPITAL LETTER KA WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER KA HOOK;;;04C4;\n04C4;CYRILLIC SMALL LETTER KA WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER KA HOOK;;04C3;;04C3\n04C5;CYRILLIC CAPITAL LETTER EL WITH TAIL;Lu;0;L;;;;;N;;;;04C6;\n04C6;CYRILLIC SMALL LETTER EL WITH TAIL;Ll;0;L;;;;;N;;;04C5;;04C5\n04C7;CYRILLIC CAPITAL LETTER EN WITH HOOK;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER EN HOOK;;;04C8;\n04C8;CYRILLIC SMALL LETTER EN WITH HOOK;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER EN HOOK;;04C7;;04C7\n04C9;CYRILLIC CAPITAL LETTER EN WITH TAIL;Lu;0;L;;;;;N;;;;04CA;\n04CA;CYRILLIC SMALL LETTER EN WITH TAIL;Ll;0;L;;;;;N;;;04C9;;04C9\n04CB;CYRILLIC CAPITAL LETTER KHAKASSIAN CHE;Lu;0;L;;;;;N;CYRILLIC CAPITAL LETTER CHE WITH LEFT DESCENDER;;;04CC;\n04CC;CYRILLIC SMALL LETTER KHAKASSIAN CHE;Ll;0;L;;;;;N;CYRILLIC SMALL LETTER CHE WITH LEFT DESCENDER;;04CB;;04CB\n04CD;CYRILLIC CAPITAL LETTER EM WITH TAIL;Lu;0;L;;;;;N;;;;04CE;\n04CE;CYRILLIC SMALL LETTER EM WITH TAIL;Ll;0;L;;;;;N;;;04CD;;04CD\n04CF;CYRILLIC SMALL LETTER PALOCHKA;Ll;0;L;;;;;N;;;04C0;;04C0\n04D0;CYRILLIC CAPITAL LETTER A WITH BREVE;Lu;0;L;0410 0306;;;;N;;;;04D1;\n04D1;CYRILLIC SMALL LETTER A WITH BREVE;Ll;0;L;0430 0306;;;;N;;;04D0;;04D0\n04D2;CYRILLIC CAPITAL LETTER A WITH DIAERESIS;Lu;0;L;0410 0308;;;;N;;;;04D3;\n04D3;CYRILLIC SMALL LETTER A WITH DIAERESIS;Ll;0;L;0430 0308;;;;N;;;04D2;;04D2\n04D4;CYRILLIC CAPITAL LIGATURE A IE;Lu;0;L;;;;;N;;;;04D5;\n04D5;CYRILLIC SMALL LIGATURE A IE;Ll;0;L;;;;;N;;;04D4;;04D4\n04D6;CYRILLIC CAPITAL LETTER IE WITH BREVE;Lu;0;L;0415 0306;;;;N;;;;04D7;\n04D7;CYRILLIC SMALL LETTER IE WITH BREVE;Ll;0;L;0435 0306;;;;N;;;04D6;;04D6\n04D8;CYRILLIC CAPITAL LETTER SCHWA;Lu;0;L;;;;;N;;;;04D9;\n04D9;CYRILLIC SMALL LETTER SCHWA;Ll;0;L;;;;;N;;;04D8;;04D8\n04DA;CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS;Lu;0;L;04D8 0308;;;;N;;;;04DB;\n04DB;CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS;Ll;0;L;04D9 0308;;;;N;;;04DA;;04DA\n04DC;CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS;Lu;0;L;0416 0308;;;;N;;;;04DD;\n04DD;CYRILLIC SMALL LETTER ZHE WITH DIAERESIS;Ll;0;L;0436 0308;;;;N;;;04DC;;04DC\n04DE;CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS;Lu;0;L;0417 0308;;;;N;;;;04DF;\n04DF;CYRILLIC SMALL LETTER ZE WITH DIAERESIS;Ll;0;L;0437 0308;;;;N;;;04DE;;04DE\n04E0;CYRILLIC CAPITAL LETTER ABKHASIAN DZE;Lu;0;L;;;;;N;;;;04E1;\n04E1;CYRILLIC SMALL LETTER ABKHASIAN DZE;Ll;0;L;;;;;N;;;04E0;;04E0\n04E2;CYRILLIC CAPITAL LETTER I WITH MACRON;Lu;0;L;0418 0304;;;;N;;;;04E3;\n04E3;CYRILLIC SMALL LETTER I WITH MACRON;Ll;0;L;0438 0304;;;;N;;;04E2;;04E2\n04E4;CYRILLIC CAPITAL LETTER I WITH DIAERESIS;Lu;0;L;0418 0308;;;;N;;;;04E5;\n04E5;CYRILLIC SMALL LETTER I WITH DIAERESIS;Ll;0;L;0438 0308;;;;N;;;04E4;;04E4\n04E6;CYRILLIC CAPITAL LETTER O WITH DIAERESIS;Lu;0;L;041E 0308;;;;N;;;;04E7;\n04E7;CYRILLIC SMALL LETTER O WITH DIAERESIS;Ll;0;L;043E 0308;;;;N;;;04E6;;04E6\n04E8;CYRILLIC CAPITAL LETTER BARRED O;Lu;0;L;;;;;N;;;;04E9;\n04E9;CYRILLIC SMALL LETTER BARRED O;Ll;0;L;;;;;N;;;04E8;;04E8\n04EA;CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS;Lu;0;L;04E8 0308;;;;N;;;;04EB;\n04EB;CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS;Ll;0;L;04E9 0308;;;;N;;;04EA;;04EA\n04EC;CYRILLIC CAPITAL LETTER E WITH DIAERESIS;Lu;0;L;042D 0308;;;;N;;;;04ED;\n04ED;CYRILLIC SMALL LETTER E WITH DIAERESIS;Ll;0;L;044D 0308;;;;N;;;04EC;;04EC\n04EE;CYRILLIC CAPITAL LETTER U WITH MACRON;Lu;0;L;0423 0304;;;;N;;;;04EF;\n04EF;CYRILLIC SMALL LETTER U WITH MACRON;Ll;0;L;0443 0304;;;;N;;;04EE;;04EE\n04F0;CYRILLIC CAPITAL LETTER U WITH DIAERESIS;Lu;0;L;0423 0308;;;;N;;;;04F1;\n04F1;CYRILLIC SMALL LETTER U WITH DIAERESIS;Ll;0;L;0443 0308;;;;N;;;04F0;;04F0\n04F2;CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE;Lu;0;L;0423 030B;;;;N;;;;04F3;\n04F3;CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE;Ll;0;L;0443 030B;;;;N;;;04F2;;04F2\n04F4;CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS;Lu;0;L;0427 0308;;;;N;;;;04F5;\n04F5;CYRILLIC SMALL LETTER CHE WITH DIAERESIS;Ll;0;L;0447 0308;;;;N;;;04F4;;04F4\n04F6;CYRILLIC CAPITAL LETTER GHE WITH DESCENDER;Lu;0;L;;;;;N;;;;04F7;\n04F7;CYRILLIC SMALL LETTER GHE WITH DESCENDER;Ll;0;L;;;;;N;;;04F6;;04F6\n04F8;CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS;Lu;0;L;042B 0308;;;;N;;;;04F9;\n04F9;CYRILLIC SMALL LETTER YERU WITH DIAERESIS;Ll;0;L;044B 0308;;;;N;;;04F8;;04F8\n04FA;CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK;Lu;0;L;;;;;N;;;;04FB;\n04FB;CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK;Ll;0;L;;;;;N;;;04FA;;04FA\n04FC;CYRILLIC CAPITAL LETTER HA WITH HOOK;Lu;0;L;;;;;N;;;;04FD;\n04FD;CYRILLIC SMALL LETTER HA WITH HOOK;Ll;0;L;;;;;N;;;04FC;;04FC\n04FE;CYRILLIC CAPITAL LETTER HA WITH STROKE;Lu;0;L;;;;;N;;;;04FF;\n04FF;CYRILLIC SMALL LETTER HA WITH STROKE;Ll;0;L;;;;;N;;;04FE;;04FE\n0500;CYRILLIC CAPITAL LETTER KOMI DE;Lu;0;L;;;;;N;;;;0501;\n0501;CYRILLIC SMALL LETTER KOMI DE;Ll;0;L;;;;;N;;;0500;;0500\n0502;CYRILLIC CAPITAL LETTER KOMI DJE;Lu;0;L;;;;;N;;;;0503;\n0503;CYRILLIC SMALL LETTER KOMI DJE;Ll;0;L;;;;;N;;;0502;;0502\n0504;CYRILLIC CAPITAL LETTER KOMI ZJE;Lu;0;L;;;;;N;;;;0505;\n0505;CYRILLIC SMALL LETTER KOMI ZJE;Ll;0;L;;;;;N;;;0504;;0504\n0506;CYRILLIC CAPITAL LETTER KOMI DZJE;Lu;0;L;;;;;N;;;;0507;\n0507;CYRILLIC SMALL LETTER KOMI DZJE;Ll;0;L;;;;;N;;;0506;;0506\n0508;CYRILLIC CAPITAL LETTER KOMI LJE;Lu;0;L;;;;;N;;;;0509;\n0509;CYRILLIC SMALL LETTER KOMI LJE;Ll;0;L;;;;;N;;;0508;;0508\n050A;CYRILLIC CAPITAL LETTER KOMI NJE;Lu;0;L;;;;;N;;;;050B;\n050B;CYRILLIC SMALL LETTER KOMI NJE;Ll;0;L;;;;;N;;;050A;;050A\n050C;CYRILLIC CAPITAL LETTER KOMI SJE;Lu;0;L;;;;;N;;;;050D;\n050D;CYRILLIC SMALL LETTER KOMI SJE;Ll;0;L;;;;;N;;;050C;;050C\n050E;CYRILLIC CAPITAL LETTER KOMI TJE;Lu;0;L;;;;;N;;;;050F;\n050F;CYRILLIC SMALL LETTER KOMI TJE;Ll;0;L;;;;;N;;;050E;;050E\n0510;CYRILLIC CAPITAL LETTER REVERSED ZE;Lu;0;L;;;;;N;;;;0511;\n0511;CYRILLIC SMALL LETTER REVERSED ZE;Ll;0;L;;;;;N;;;0510;;0510\n0512;CYRILLIC CAPITAL LETTER EL WITH HOOK;Lu;0;L;;;;;N;;;;0513;\n0513;CYRILLIC SMALL LETTER EL WITH HOOK;Ll;0;L;;;;;N;;;0512;;0512\n0514;CYRILLIC CAPITAL LETTER LHA;Lu;0;L;;;;;N;;;;0515;\n0515;CYRILLIC SMALL LETTER LHA;Ll;0;L;;;;;N;;;0514;;0514\n0516;CYRILLIC CAPITAL LETTER RHA;Lu;0;L;;;;;N;;;;0517;\n0517;CYRILLIC SMALL LETTER RHA;Ll;0;L;;;;;N;;;0516;;0516\n0518;CYRILLIC CAPITAL LETTER YAE;Lu;0;L;;;;;N;;;;0519;\n0519;CYRILLIC SMALL LETTER YAE;Ll;0;L;;;;;N;;;0518;;0518\n051A;CYRILLIC CAPITAL LETTER QA;Lu;0;L;;;;;N;;;;051B;\n051B;CYRILLIC SMALL LETTER QA;Ll;0;L;;;;;N;;;051A;;051A\n051C;CYRILLIC CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;051D;\n051D;CYRILLIC SMALL LETTER WE;Ll;0;L;;;;;N;;;051C;;051C\n051E;CYRILLIC CAPITAL LETTER ALEUT KA;Lu;0;L;;;;;N;;;;051F;\n051F;CYRILLIC SMALL LETTER ALEUT KA;Ll;0;L;;;;;N;;;051E;;051E\n0520;CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;0521;\n0521;CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0520;;0520\n0522;CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;0523;\n0523;CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;0522;;0522\n0524;CYRILLIC CAPITAL LETTER PE WITH DESCENDER;Lu;0;L;;;;;N;;;;0525;\n0525;CYRILLIC SMALL LETTER PE WITH DESCENDER;Ll;0;L;;;;;N;;;0524;;0524\n0526;CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER;Lu;0;L;;;;;N;;;;0527;\n0527;CYRILLIC SMALL LETTER SHHA WITH DESCENDER;Ll;0;L;;;;;N;;;0526;;0526\n0528;CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK;Lu;0;L;;;;;N;;;;0529;\n0529;CYRILLIC SMALL LETTER EN WITH LEFT HOOK;Ll;0;L;;;;;N;;;0528;;0528\n052A;CYRILLIC CAPITAL LETTER DZZHE;Lu;0;L;;;;;N;;;;052B;\n052B;CYRILLIC SMALL LETTER DZZHE;Ll;0;L;;;;;N;;;052A;;052A\n052C;CYRILLIC CAPITAL LETTER DCHE;Lu;0;L;;;;;N;;;;052D;\n052D;CYRILLIC SMALL LETTER DCHE;Ll;0;L;;;;;N;;;052C;;052C\n052E;CYRILLIC CAPITAL LETTER EL WITH DESCENDER;Lu;0;L;;;;;N;;;;052F;\n052F;CYRILLIC SMALL LETTER EL WITH DESCENDER;Ll;0;L;;;;;N;;;052E;;052E\n0531;ARMENIAN CAPITAL LETTER AYB;Lu;0;L;;;;;N;;;;0561;\n0532;ARMENIAN CAPITAL LETTER BEN;Lu;0;L;;;;;N;;;;0562;\n0533;ARMENIAN CAPITAL LETTER GIM;Lu;0;L;;;;;N;;;;0563;\n0534;ARMENIAN CAPITAL LETTER DA;Lu;0;L;;;;;N;;;;0564;\n0535;ARMENIAN CAPITAL LETTER ECH;Lu;0;L;;;;;N;;;;0565;\n0536;ARMENIAN CAPITAL LETTER ZA;Lu;0;L;;;;;N;;;;0566;\n0537;ARMENIAN CAPITAL LETTER EH;Lu;0;L;;;;;N;;;;0567;\n0538;ARMENIAN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;0568;\n0539;ARMENIAN CAPITAL LETTER TO;Lu;0;L;;;;;N;;;;0569;\n053A;ARMENIAN CAPITAL LETTER ZHE;Lu;0;L;;;;;N;;;;056A;\n053B;ARMENIAN CAPITAL LETTER INI;Lu;0;L;;;;;N;;;;056B;\n053C;ARMENIAN CAPITAL LETTER LIWN;Lu;0;L;;;;;N;;;;056C;\n053D;ARMENIAN CAPITAL LETTER XEH;Lu;0;L;;;;;N;;;;056D;\n053E;ARMENIAN CAPITAL LETTER CA;Lu;0;L;;;;;N;;;;056E;\n053F;ARMENIAN CAPITAL LETTER KEN;Lu;0;L;;;;;N;;;;056F;\n0540;ARMENIAN CAPITAL LETTER HO;Lu;0;L;;;;;N;;;;0570;\n0541;ARMENIAN CAPITAL LETTER JA;Lu;0;L;;;;;N;;;;0571;\n0542;ARMENIAN CAPITAL LETTER GHAD;Lu;0;L;;;;;N;ARMENIAN CAPITAL LETTER LAD;;;0572;\n0543;ARMENIAN CAPITAL LETTER CHEH;Lu;0;L;;;;;N;;;;0573;\n0544;ARMENIAN CAPITAL LETTER MEN;Lu;0;L;;;;;N;;;;0574;\n0545;ARMENIAN CAPITAL LETTER YI;Lu;0;L;;;;;N;;;;0575;\n0546;ARMENIAN CAPITAL LETTER NOW;Lu;0;L;;;;;N;;;;0576;\n0547;ARMENIAN CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;0577;\n0548;ARMENIAN CAPITAL LETTER VO;Lu;0;L;;;;;N;;;;0578;\n0549;ARMENIAN CAPITAL LETTER CHA;Lu;0;L;;;;;N;;;;0579;\n054A;ARMENIAN CAPITAL LETTER PEH;Lu;0;L;;;;;N;;;;057A;\n054B;ARMENIAN CAPITAL LETTER JHEH;Lu;0;L;;;;;N;;;;057B;\n054C;ARMENIAN CAPITAL LETTER RA;Lu;0;L;;;;;N;;;;057C;\n054D;ARMENIAN CAPITAL LETTER SEH;Lu;0;L;;;;;N;;;;057D;\n054E;ARMENIAN CAPITAL LETTER VEW;Lu;0;L;;;;;N;;;;057E;\n054F;ARMENIAN CAPITAL LETTER TIWN;Lu;0;L;;;;;N;;;;057F;\n0550;ARMENIAN CAPITAL LETTER REH;Lu;0;L;;;;;N;;;;0580;\n0551;ARMENIAN CAPITAL LETTER CO;Lu;0;L;;;;;N;;;;0581;\n0552;ARMENIAN CAPITAL LETTER YIWN;Lu;0;L;;;;;N;;;;0582;\n0553;ARMENIAN CAPITAL LETTER PIWR;Lu;0;L;;;;;N;;;;0583;\n0554;ARMENIAN CAPITAL LETTER KEH;Lu;0;L;;;;;N;;;;0584;\n0555;ARMENIAN CAPITAL LETTER OH;Lu;0;L;;;;;N;;;;0585;\n0556;ARMENIAN CAPITAL LETTER FEH;Lu;0;L;;;;;N;;;;0586;\n0559;ARMENIAN MODIFIER LETTER LEFT HALF RING;Lm;0;L;;;;;N;;;;;\n055A;ARMENIAN APOSTROPHE;Po;0;L;;;;;N;ARMENIAN MODIFIER LETTER RIGHT HALF RING;;;;\n055B;ARMENIAN EMPHASIS MARK;Po;0;L;;;;;N;;;;;\n055C;ARMENIAN EXCLAMATION MARK;Po;0;L;;;;;N;;;;;\n055D;ARMENIAN COMMA;Po;0;L;;;;;N;;;;;\n055E;ARMENIAN QUESTION MARK;Po;0;L;;;;;N;;;;;\n055F;ARMENIAN ABBREVIATION MARK;Po;0;L;;;;;N;;;;;\n0560;ARMENIAN SMALL LETTER TURNED AYB;Ll;0;L;;;;;N;;;;;\n0561;ARMENIAN SMALL LETTER AYB;Ll;0;L;;;;;N;;;0531;;0531\n0562;ARMENIAN SMALL LETTER BEN;Ll;0;L;;;;;N;;;0532;;0532\n0563;ARMENIAN SMALL LETTER GIM;Ll;0;L;;;;;N;;;0533;;0533\n0564;ARMENIAN SMALL LETTER DA;Ll;0;L;;;;;N;;;0534;;0534\n0565;ARMENIAN SMALL LETTER ECH;Ll;0;L;;;;;N;;;0535;;0535\n0566;ARMENIAN SMALL LETTER ZA;Ll;0;L;;;;;N;;;0536;;0536\n0567;ARMENIAN SMALL LETTER EH;Ll;0;L;;;;;N;;;0537;;0537\n0568;ARMENIAN SMALL LETTER ET;Ll;0;L;;;;;N;;;0538;;0538\n0569;ARMENIAN SMALL LETTER TO;Ll;0;L;;;;;N;;;0539;;0539\n056A;ARMENIAN SMALL LETTER ZHE;Ll;0;L;;;;;N;;;053A;;053A\n056B;ARMENIAN SMALL LETTER INI;Ll;0;L;;;;;N;;;053B;;053B\n056C;ARMENIAN SMALL LETTER LIWN;Ll;0;L;;;;;N;;;053C;;053C\n056D;ARMENIAN SMALL LETTER XEH;Ll;0;L;;;;;N;;;053D;;053D\n056E;ARMENIAN SMALL LETTER CA;Ll;0;L;;;;;N;;;053E;;053E\n056F;ARMENIAN SMALL LETTER KEN;Ll;0;L;;;;;N;;;053F;;053F\n0570;ARMENIAN SMALL LETTER HO;Ll;0;L;;;;;N;;;0540;;0540\n0571;ARMENIAN SMALL LETTER JA;Ll;0;L;;;;;N;;;0541;;0541\n0572;ARMENIAN SMALL LETTER GHAD;Ll;0;L;;;;;N;ARMENIAN SMALL LETTER LAD;;0542;;0542\n0573;ARMENIAN SMALL LETTER CHEH;Ll;0;L;;;;;N;;;0543;;0543\n0574;ARMENIAN SMALL LETTER MEN;Ll;0;L;;;;;N;;;0544;;0544\n0575;ARMENIAN SMALL LETTER YI;Ll;0;L;;;;;N;;;0545;;0545\n0576;ARMENIAN SMALL LETTER NOW;Ll;0;L;;;;;N;;;0546;;0546\n0577;ARMENIAN SMALL LETTER SHA;Ll;0;L;;;;;N;;;0547;;0547\n0578;ARMENIAN SMALL LETTER VO;Ll;0;L;;;;;N;;;0548;;0548\n0579;ARMENIAN SMALL LETTER CHA;Ll;0;L;;;;;N;;;0549;;0549\n057A;ARMENIAN SMALL LETTER PEH;Ll;0;L;;;;;N;;;054A;;054A\n057B;ARMENIAN SMALL LETTER JHEH;Ll;0;L;;;;;N;;;054B;;054B\n057C;ARMENIAN SMALL LETTER RA;Ll;0;L;;;;;N;;;054C;;054C\n057D;ARMENIAN SMALL LETTER SEH;Ll;0;L;;;;;N;;;054D;;054D\n057E;ARMENIAN SMALL LETTER VEW;Ll;0;L;;;;;N;;;054E;;054E\n057F;ARMENIAN SMALL LETTER TIWN;Ll;0;L;;;;;N;;;054F;;054F\n0580;ARMENIAN SMALL LETTER REH;Ll;0;L;;;;;N;;;0550;;0550\n0581;ARMENIAN SMALL LETTER CO;Ll;0;L;;;;;N;;;0551;;0551\n0582;ARMENIAN SMALL LETTER YIWN;Ll;0;L;;;;;N;;;0552;;0552\n0583;ARMENIAN SMALL LETTER PIWR;Ll;0;L;;;;;N;;;0553;;0553\n0584;ARMENIAN SMALL LETTER KEH;Ll;0;L;;;;;N;;;0554;;0554\n0585;ARMENIAN SMALL LETTER OH;Ll;0;L;;;;;N;;;0555;;0555\n0586;ARMENIAN SMALL LETTER FEH;Ll;0;L;;;;;N;;;0556;;0556\n0587;ARMENIAN SMALL LIGATURE ECH YIWN;Ll;0;L;<compat> 0565 0582;;;;N;;;;;\n0588;ARMENIAN SMALL LETTER YI WITH STROKE;Ll;0;L;;;;;N;;;;;\n0589;ARMENIAN FULL STOP;Po;0;L;;;;;N;ARMENIAN PERIOD;;;;\n058A;ARMENIAN HYPHEN;Pd;0;ON;;;;;N;;;;;\n058D;RIGHT-FACING ARMENIAN ETERNITY SIGN;So;0;ON;;;;;N;;;;;\n058E;LEFT-FACING ARMENIAN ETERNITY SIGN;So;0;ON;;;;;N;;;;;\n058F;ARMENIAN DRAM SIGN;Sc;0;ET;;;;;N;;;;;\n0591;HEBREW ACCENT ETNAHTA;Mn;220;NSM;;;;;N;;;;;\n0592;HEBREW ACCENT SEGOL;Mn;230;NSM;;;;;N;;;;;\n0593;HEBREW ACCENT SHALSHELET;Mn;230;NSM;;;;;N;;;;;\n0594;HEBREW ACCENT ZAQEF QATAN;Mn;230;NSM;;;;;N;;;;;\n0595;HEBREW ACCENT ZAQEF GADOL;Mn;230;NSM;;;;;N;;;;;\n0596;HEBREW ACCENT TIPEHA;Mn;220;NSM;;;;;N;;;;;\n0597;HEBREW ACCENT REVIA;Mn;230;NSM;;;;;N;;;;;\n0598;HEBREW ACCENT ZARQA;Mn;230;NSM;;;;;N;;;;;\n0599;HEBREW ACCENT PASHTA;Mn;230;NSM;;;;;N;;;;;\n059A;HEBREW ACCENT YETIV;Mn;222;NSM;;;;;N;;;;;\n059B;HEBREW ACCENT TEVIR;Mn;220;NSM;;;;;N;;;;;\n059C;HEBREW ACCENT GERESH;Mn;230;NSM;;;;;N;;;;;\n059D;HEBREW ACCENT GERESH MUQDAM;Mn;230;NSM;;;;;N;;;;;\n059E;HEBREW ACCENT GERSHAYIM;Mn;230;NSM;;;;;N;;;;;\n059F;HEBREW ACCENT QARNEY PARA;Mn;230;NSM;;;;;N;;;;;\n05A0;HEBREW ACCENT TELISHA GEDOLA;Mn;230;NSM;;;;;N;;;;;\n05A1;HEBREW ACCENT PAZER;Mn;230;NSM;;;;;N;;;;;\n05A2;HEBREW ACCENT ATNAH HAFUKH;Mn;220;NSM;;;;;N;;;;;\n05A3;HEBREW ACCENT MUNAH;Mn;220;NSM;;;;;N;;;;;\n05A4;HEBREW ACCENT MAHAPAKH;Mn;220;NSM;;;;;N;;;;;\n05A5;HEBREW ACCENT MERKHA;Mn;220;NSM;;;;;N;;;;;\n05A6;HEBREW ACCENT MERKHA KEFULA;Mn;220;NSM;;;;;N;;;;;\n05A7;HEBREW ACCENT DARGA;Mn;220;NSM;;;;;N;;;;;\n05A8;HEBREW ACCENT QADMA;Mn;230;NSM;;;;;N;;;;;\n05A9;HEBREW ACCENT TELISHA QETANA;Mn;230;NSM;;;;;N;;;;;\n05AA;HEBREW ACCENT YERAH BEN YOMO;Mn;220;NSM;;;;;N;;;;;\n05AB;HEBREW ACCENT OLE;Mn;230;NSM;;;;;N;;;;;\n05AC;HEBREW ACCENT ILUY;Mn;230;NSM;;;;;N;;;;;\n05AD;HEBREW ACCENT DEHI;Mn;222;NSM;;;;;N;;;;;\n05AE;HEBREW ACCENT ZINOR;Mn;228;NSM;;;;;N;;;;;\n05AF;HEBREW MARK MASORA CIRCLE;Mn;230;NSM;;;;;N;;;;;\n05B0;HEBREW POINT SHEVA;Mn;10;NSM;;;;;N;;;;;\n05B1;HEBREW POINT HATAF SEGOL;Mn;11;NSM;;;;;N;;;;;\n05B2;HEBREW POINT HATAF PATAH;Mn;12;NSM;;;;;N;;;;;\n05B3;HEBREW POINT HATAF QAMATS;Mn;13;NSM;;;;;N;;;;;\n05B4;HEBREW POINT HIRIQ;Mn;14;NSM;;;;;N;;;;;\n05B5;HEBREW POINT TSERE;Mn;15;NSM;;;;;N;;;;;\n05B6;HEBREW POINT SEGOL;Mn;16;NSM;;;;;N;;;;;\n05B7;HEBREW POINT PATAH;Mn;17;NSM;;;;;N;;;;;\n05B8;HEBREW POINT QAMATS;Mn;18;NSM;;;;;N;;;;;\n05B9;HEBREW POINT HOLAM;Mn;19;NSM;;;;;N;;;;;\n05BA;HEBREW POINT HOLAM HASER FOR VAV;Mn;19;NSM;;;;;N;;;;;\n05BB;HEBREW POINT QUBUTS;Mn;20;NSM;;;;;N;;;;;\n05BC;HEBREW POINT DAGESH OR MAPIQ;Mn;21;NSM;;;;;N;HEBREW POINT DAGESH;;;;\n05BD;HEBREW POINT METEG;Mn;22;NSM;;;;;N;;;;;\n05BE;HEBREW PUNCTUATION MAQAF;Pd;0;R;;;;;N;;;;;\n05BF;HEBREW POINT RAFE;Mn;23;NSM;;;;;N;;;;;\n05C0;HEBREW PUNCTUATION PASEQ;Po;0;R;;;;;N;HEBREW POINT PASEQ;;;;\n05C1;HEBREW POINT SHIN DOT;Mn;24;NSM;;;;;N;;;;;\n05C2;HEBREW POINT SIN DOT;Mn;25;NSM;;;;;N;;;;;\n05C3;HEBREW PUNCTUATION SOF PASUQ;Po;0;R;;;;;N;;;;;\n05C4;HEBREW MARK UPPER DOT;Mn;230;NSM;;;;;N;;;;;\n05C5;HEBREW MARK LOWER DOT;Mn;220;NSM;;;;;N;;;;;\n05C6;HEBREW PUNCTUATION NUN HAFUKHA;Po;0;R;;;;;N;;;;;\n05C7;HEBREW POINT QAMATS QATAN;Mn;18;NSM;;;;;N;;;;;\n05D0;HEBREW LETTER ALEF;Lo;0;R;;;;;N;;;;;\n05D1;HEBREW LETTER BET;Lo;0;R;;;;;N;;;;;\n05D2;HEBREW LETTER GIMEL;Lo;0;R;;;;;N;;;;;\n05D3;HEBREW LETTER DALET;Lo;0;R;;;;;N;;;;;\n05D4;HEBREW LETTER HE;Lo;0;R;;;;;N;;;;;\n05D5;HEBREW LETTER VAV;Lo;0;R;;;;;N;;;;;\n05D6;HEBREW LETTER ZAYIN;Lo;0;R;;;;;N;;;;;\n05D7;HEBREW LETTER HET;Lo;0;R;;;;;N;;;;;\n05D8;HEBREW LETTER TET;Lo;0;R;;;;;N;;;;;\n05D9;HEBREW LETTER YOD;Lo;0;R;;;;;N;;;;;\n05DA;HEBREW LETTER FINAL KAF;Lo;0;R;;;;;N;;;;;\n05DB;HEBREW LETTER KAF;Lo;0;R;;;;;N;;;;;\n05DC;HEBREW LETTER LAMED;Lo;0;R;;;;;N;;;;;\n05DD;HEBREW LETTER FINAL MEM;Lo;0;R;;;;;N;;;;;\n05DE;HEBREW LETTER MEM;Lo;0;R;;;;;N;;;;;\n05DF;HEBREW LETTER FINAL NUN;Lo;0;R;;;;;N;;;;;\n05E0;HEBREW LETTER NUN;Lo;0;R;;;;;N;;;;;\n05E1;HEBREW LETTER SAMEKH;Lo;0;R;;;;;N;;;;;\n05E2;HEBREW LETTER AYIN;Lo;0;R;;;;;N;;;;;\n05E3;HEBREW LETTER FINAL PE;Lo;0;R;;;;;N;;;;;\n05E4;HEBREW LETTER PE;Lo;0;R;;;;;N;;;;;\n05E5;HEBREW LETTER FINAL TSADI;Lo;0;R;;;;;N;;;;;\n05E6;HEBREW LETTER TSADI;Lo;0;R;;;;;N;;;;;\n05E7;HEBREW LETTER QOF;Lo;0;R;;;;;N;;;;;\n05E8;HEBREW LETTER RESH;Lo;0;R;;;;;N;;;;;\n05E9;HEBREW LETTER SHIN;Lo;0;R;;;;;N;;;;;\n05EA;HEBREW LETTER TAV;Lo;0;R;;;;;N;;;;;\n05EF;HEBREW YOD TRIANGLE;Lo;0;R;;;;;N;;;;;\n05F0;HEBREW LIGATURE YIDDISH DOUBLE VAV;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE VAV;;;;\n05F1;HEBREW LIGATURE YIDDISH VAV YOD;Lo;0;R;;;;;N;HEBREW LETTER VAV YOD;;;;\n05F2;HEBREW LIGATURE YIDDISH DOUBLE YOD;Lo;0;R;;;;;N;HEBREW LETTER DOUBLE YOD;;;;\n05F3;HEBREW PUNCTUATION GERESH;Po;0;R;;;;;N;;;;;\n05F4;HEBREW PUNCTUATION GERSHAYIM;Po;0;R;;;;;N;;;;;\n0600;ARABIC NUMBER SIGN;Cf;0;AN;;;;;N;;;;;\n0601;ARABIC SIGN SANAH;Cf;0;AN;;;;;N;;;;;\n0602;ARABIC FOOTNOTE MARKER;Cf;0;AN;;;;;N;;;;;\n0603;ARABIC SIGN SAFHA;Cf;0;AN;;;;;N;;;;;\n0604;ARABIC SIGN SAMVAT;Cf;0;AN;;;;;N;;;;;\n0605;ARABIC NUMBER MARK ABOVE;Cf;0;AN;;;;;N;;;;;\n0606;ARABIC-INDIC CUBE ROOT;Sm;0;ON;;;;;N;;;;;\n0607;ARABIC-INDIC FOURTH ROOT;Sm;0;ON;;;;;N;;;;;\n0608;ARABIC RAY;Sm;0;AL;;;;;N;;;;;\n0609;ARABIC-INDIC PER MILLE SIGN;Po;0;ET;;;;;N;;;;;\n060A;ARABIC-INDIC PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;;\n060B;AFGHANI SIGN;Sc;0;AL;;;;;N;;;;;\n060C;ARABIC COMMA;Po;0;CS;;;;;N;;;;;\n060D;ARABIC DATE SEPARATOR;Po;0;AL;;;;;N;;;;;\n060E;ARABIC POETIC VERSE SIGN;So;0;ON;;;;;N;;;;;\n060F;ARABIC SIGN MISRA;So;0;ON;;;;;N;;;;;\n0610;ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM;Mn;230;NSM;;;;;N;;;;;\n0611;ARABIC SIGN ALAYHE ASSALLAM;Mn;230;NSM;;;;;N;;;;;\n0612;ARABIC SIGN RAHMATULLAH ALAYHE;Mn;230;NSM;;;;;N;;;;;\n0613;ARABIC SIGN RADI ALLAHOU ANHU;Mn;230;NSM;;;;;N;;;;;\n0614;ARABIC SIGN TAKHALLUS;Mn;230;NSM;;;;;N;;;;;\n0615;ARABIC SMALL HIGH TAH;Mn;230;NSM;;;;;N;;;;;\n0616;ARABIC SMALL HIGH LIGATURE ALEF WITH LAM WITH YEH;Mn;230;NSM;;;;;N;;;;;\n0617;ARABIC SMALL HIGH ZAIN;Mn;230;NSM;;;;;N;;;;;\n0618;ARABIC SMALL FATHA;Mn;30;NSM;;;;;N;;;;;\n0619;ARABIC SMALL DAMMA;Mn;31;NSM;;;;;N;;;;;\n061A;ARABIC SMALL KASRA;Mn;32;NSM;;;;;N;;;;;\n061B;ARABIC SEMICOLON;Po;0;AL;;;;;N;;;;;\n061C;ARABIC LETTER MARK;Cf;0;AL;;;;;N;;;;;\n061E;ARABIC TRIPLE DOT PUNCTUATION MARK;Po;0;AL;;;;;N;;;;;\n061F;ARABIC QUESTION MARK;Po;0;AL;;;;;N;;;;;\n0620;ARABIC LETTER KASHMIRI YEH;Lo;0;AL;;;;;N;;;;;\n0621;ARABIC LETTER HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH;;;;\n0622;ARABIC LETTER ALEF WITH MADDA ABOVE;Lo;0;AL;0627 0653;;;;N;ARABIC LETTER MADDAH ON ALEF;;;;\n0623;ARABIC LETTER ALEF WITH HAMZA ABOVE;Lo;0;AL;0627 0654;;;;N;ARABIC LETTER HAMZAH ON ALEF;;;;\n0624;ARABIC LETTER WAW WITH HAMZA ABOVE;Lo;0;AL;0648 0654;;;;N;ARABIC LETTER HAMZAH ON WAW;;;;\n0625;ARABIC LETTER ALEF WITH HAMZA BELOW;Lo;0;AL;0627 0655;;;;N;ARABIC LETTER HAMZAH UNDER ALEF;;;;\n0626;ARABIC LETTER YEH WITH HAMZA ABOVE;Lo;0;AL;064A 0654;;;;N;ARABIC LETTER HAMZAH ON YA;;;;\n0627;ARABIC LETTER ALEF;Lo;0;AL;;;;;N;;;;;\n0628;ARABIC LETTER BEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA;;;;\n0629;ARABIC LETTER TEH MARBUTA;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH;;;;\n062A;ARABIC LETTER TEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA;;;;\n062B;ARABIC LETTER THEH;Lo;0;AL;;;;;N;ARABIC LETTER THAA;;;;\n062C;ARABIC LETTER JEEM;Lo;0;AL;;;;;N;;;;;\n062D;ARABIC LETTER HAH;Lo;0;AL;;;;;N;ARABIC LETTER HAA;;;;\n062E;ARABIC LETTER KHAH;Lo;0;AL;;;;;N;ARABIC LETTER KHAA;;;;\n062F;ARABIC LETTER DAL;Lo;0;AL;;;;;N;;;;;\n0630;ARABIC LETTER THAL;Lo;0;AL;;;;;N;;;;;\n0631;ARABIC LETTER REH;Lo;0;AL;;;;;N;ARABIC LETTER RA;;;;\n0632;ARABIC LETTER ZAIN;Lo;0;AL;;;;;N;;;;;\n0633;ARABIC LETTER SEEN;Lo;0;AL;;;;;N;;;;;\n0634;ARABIC LETTER SHEEN;Lo;0;AL;;;;;N;;;;;\n0635;ARABIC LETTER SAD;Lo;0;AL;;;;;N;;;;;\n0636;ARABIC LETTER DAD;Lo;0;AL;;;;;N;;;;;\n0637;ARABIC LETTER TAH;Lo;0;AL;;;;;N;;;;;\n0638;ARABIC LETTER ZAH;Lo;0;AL;;;;;N;ARABIC LETTER DHAH;;;;\n0639;ARABIC LETTER AIN;Lo;0;AL;;;;;N;;;;;\n063A;ARABIC LETTER GHAIN;Lo;0;AL;;;;;N;;;;;\n063B;ARABIC LETTER KEHEH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n063C;ARABIC LETTER KEHEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;\n063D;ARABIC LETTER FARSI YEH WITH INVERTED V;Lo;0;AL;;;;;N;;;;;\n063E;ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n063F;ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n0640;ARABIC TATWEEL;Lm;0;AL;;;;;N;;;;;\n0641;ARABIC LETTER FEH;Lo;0;AL;;;;;N;ARABIC LETTER FA;;;;\n0642;ARABIC LETTER QAF;Lo;0;AL;;;;;N;;;;;\n0643;ARABIC LETTER KAF;Lo;0;AL;;;;;N;ARABIC LETTER CAF;;;;\n0644;ARABIC LETTER LAM;Lo;0;AL;;;;;N;;;;;\n0645;ARABIC LETTER MEEM;Lo;0;AL;;;;;N;;;;;\n0646;ARABIC LETTER NOON;Lo;0;AL;;;;;N;;;;;\n0647;ARABIC LETTER HEH;Lo;0;AL;;;;;N;ARABIC LETTER HA;;;;\n0648;ARABIC LETTER WAW;Lo;0;AL;;;;;N;;;;;\n0649;ARABIC LETTER ALEF MAKSURA;Lo;0;AL;;;;;N;ARABIC LETTER ALEF MAQSURAH;;;;\n064A;ARABIC LETTER YEH;Lo;0;AL;;;;;N;ARABIC LETTER YA;;;;\n064B;ARABIC FATHATAN;Mn;27;NSM;;;;;N;;;;;\n064C;ARABIC DAMMATAN;Mn;28;NSM;;;;;N;;;;;\n064D;ARABIC KASRATAN;Mn;29;NSM;;;;;N;;;;;\n064E;ARABIC FATHA;Mn;30;NSM;;;;;N;ARABIC FATHAH;;;;\n064F;ARABIC DAMMA;Mn;31;NSM;;;;;N;ARABIC DAMMAH;;;;\n0650;ARABIC KASRA;Mn;32;NSM;;;;;N;ARABIC KASRAH;;;;\n0651;ARABIC SHADDA;Mn;33;NSM;;;;;N;ARABIC SHADDAH;;;;\n0652;ARABIC SUKUN;Mn;34;NSM;;;;;N;;;;;\n0653;ARABIC MADDAH ABOVE;Mn;230;NSM;;;;;N;;;;;\n0654;ARABIC HAMZA ABOVE;Mn;230;NSM;;;;;N;;;;;\n0655;ARABIC HAMZA BELOW;Mn;220;NSM;;;;;N;;;;;\n0656;ARABIC SUBSCRIPT ALEF;Mn;220;NSM;;;;;N;;;;;\n0657;ARABIC INVERTED DAMMA;Mn;230;NSM;;;;;N;;;;;\n0658;ARABIC MARK NOON GHUNNA;Mn;230;NSM;;;;;N;;;;;\n0659;ARABIC ZWARAKAY;Mn;230;NSM;;;;;N;;;;;\n065A;ARABIC VOWEL SIGN SMALL V ABOVE;Mn;230;NSM;;;;;N;;;;;\n065B;ARABIC VOWEL SIGN INVERTED SMALL V ABOVE;Mn;230;NSM;;;;;N;;;;;\n065C;ARABIC VOWEL SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;;\n065D;ARABIC REVERSED DAMMA;Mn;230;NSM;;;;;N;;;;;\n065E;ARABIC FATHA WITH TWO DOTS;Mn;230;NSM;;;;;N;;;;;\n065F;ARABIC WAVY HAMZA BELOW;Mn;220;NSM;;;;;N;;;;;\n0660;ARABIC-INDIC DIGIT ZERO;Nd;0;AN;;0;0;0;N;;;;;\n0661;ARABIC-INDIC DIGIT ONE;Nd;0;AN;;1;1;1;N;;;;;\n0662;ARABIC-INDIC DIGIT TWO;Nd;0;AN;;2;2;2;N;;;;;\n0663;ARABIC-INDIC DIGIT THREE;Nd;0;AN;;3;3;3;N;;;;;\n0664;ARABIC-INDIC DIGIT FOUR;Nd;0;AN;;4;4;4;N;;;;;\n0665;ARABIC-INDIC DIGIT FIVE;Nd;0;AN;;5;5;5;N;;;;;\n0666;ARABIC-INDIC DIGIT SIX;Nd;0;AN;;6;6;6;N;;;;;\n0667;ARABIC-INDIC DIGIT SEVEN;Nd;0;AN;;7;7;7;N;;;;;\n0668;ARABIC-INDIC DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;;\n0669;ARABIC-INDIC DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;;\n066A;ARABIC PERCENT SIGN;Po;0;ET;;;;;N;;;;;\n066B;ARABIC DECIMAL SEPARATOR;Po;0;AN;;;;;N;;;;;\n066C;ARABIC THOUSANDS SEPARATOR;Po;0;AN;;;;;N;;;;;\n066D;ARABIC FIVE POINTED STAR;Po;0;AL;;;;;N;;;;;\n066E;ARABIC LETTER DOTLESS BEH;Lo;0;AL;;;;;N;;;;;\n066F;ARABIC LETTER DOTLESS QAF;Lo;0;AL;;;;;N;;;;;\n0670;ARABIC LETTER SUPERSCRIPT ALEF;Mn;35;NSM;;;;;N;ARABIC ALEF ABOVE;;;;\n0671;ARABIC LETTER ALEF WASLA;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAT WASL ON ALEF;;;;\n0672;ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH ON ALEF;;;;\n0673;ARABIC LETTER ALEF WITH WAVY HAMZA BELOW;Lo;0;AL;;;;;N;ARABIC LETTER WAVY HAMZAH UNDER ALEF;;;;\n0674;ARABIC LETTER HIGH HAMZA;Lo;0;AL;;;;;N;ARABIC LETTER HIGH HAMZAH;;;;\n0675;ARABIC LETTER HIGH HAMZA ALEF;Lo;0;AL;<compat> 0627 0674;;;;N;ARABIC LETTER HIGH HAMZAH ALEF;;;;\n0676;ARABIC LETTER HIGH HAMZA WAW;Lo;0;AL;<compat> 0648 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW;;;;\n0677;ARABIC LETTER U WITH HAMZA ABOVE;Lo;0;AL;<compat> 06C7 0674;;;;N;ARABIC LETTER HIGH HAMZAH WAW WITH DAMMAH;;;;\n0678;ARABIC LETTER HIGH HAMZA YEH;Lo;0;AL;<compat> 064A 0674;;;;N;ARABIC LETTER HIGH HAMZAH YA;;;;\n0679;ARABIC LETTER TTEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH SMALL TAH;;;;\n067A;ARABIC LETTER TTEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH TWO DOTS VERTICAL ABOVE;;;;\n067B;ARABIC LETTER BEEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH TWO DOTS VERTICAL BELOW;;;;\n067C;ARABIC LETTER TEH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH RING;;;;\n067D;ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS ABOVE DOWNWARD;;;;\n067E;ARABIC LETTER PEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH THREE DOTS BELOW;;;;\n067F;ARABIC LETTER TEHEH;Lo;0;AL;;;;;N;ARABIC LETTER TAA WITH FOUR DOTS ABOVE;;;;\n0680;ARABIC LETTER BEHEH;Lo;0;AL;;;;;N;ARABIC LETTER BAA WITH FOUR DOTS BELOW;;;;\n0681;ARABIC LETTER HAH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAMZAH ON HAA;;;;\n0682;ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH TWO DOTS VERTICAL ABOVE;;;;\n0683;ARABIC LETTER NYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS;;;;\n0684;ARABIC LETTER DYEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE TWO DOTS VERTICAL;;;;\n0685;ARABIC LETTER HAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH THREE DOTS ABOVE;;;;\n0686;ARABIC LETTER TCHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE THREE DOTS DOWNWARD;;;;\n0687;ARABIC LETTER TCHEHEH;Lo;0;AL;;;;;N;ARABIC LETTER HAA WITH MIDDLE FOUR DOTS;;;;\n0688;ARABIC LETTER DDAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH SMALL TAH;;;;\n0689;ARABIC LETTER DAL WITH RING;Lo;0;AL;;;;;N;;;;;\n068A;ARABIC LETTER DAL WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;\n068B;ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;;\n068C;ARABIC LETTER DAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS ABOVE;;;;\n068D;ARABIC LETTER DDAHAL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH TWO DOTS BELOW;;;;\n068E;ARABIC LETTER DUL;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE;;;;\n068F;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS;Lo;0;AL;;;;;N;ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARD;;;;\n0690;ARABIC LETTER DAL WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n0691;ARABIC LETTER RREH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL TAH;;;;\n0692;ARABIC LETTER REH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V;;;;\n0693;ARABIC LETTER REH WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH RING;;;;\n0694;ARABIC LETTER REH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW;;;;\n0695;ARABIC LETTER REH WITH SMALL V BELOW;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH SMALL V BELOW;;;;\n0696;ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH DOT BELOW AND DOT ABOVE;;;;\n0697;ARABIC LETTER REH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH TWO DOTS ABOVE;;;;\n0698;ARABIC LETTER JEH;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH THREE DOTS ABOVE;;;;\n0699;ARABIC LETTER REH WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER RA WITH FOUR DOTS ABOVE;;;;\n069A;ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;\n069B;ARABIC LETTER SEEN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;\n069C;ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n069D;ARABIC LETTER SAD WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;\n069E;ARABIC LETTER SAD WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n069F;ARABIC LETTER TAH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n06A0;ARABIC LETTER AIN WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n06A1;ARABIC LETTER DOTLESS FEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS FA;;;;\n06A2;ARABIC LETTER FEH WITH DOT MOVED BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT MOVED BELOW;;;;\n06A3;ARABIC LETTER FEH WITH DOT BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH DOT BELOW;;;;\n06A4;ARABIC LETTER VEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS ABOVE;;;;\n06A5;ARABIC LETTER FEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH THREE DOTS BELOW;;;;\n06A6;ARABIC LETTER PEHEH;Lo;0;AL;;;;;N;ARABIC LETTER FA WITH FOUR DOTS ABOVE;;;;\n06A7;ARABIC LETTER QAF WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;\n06A8;ARABIC LETTER QAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n06A9;ARABIC LETTER KEHEH;Lo;0;AL;;;;;N;ARABIC LETTER OPEN CAF;;;;\n06AA;ARABIC LETTER SWASH KAF;Lo;0;AL;;;;;N;ARABIC LETTER SWASH CAF;;;;\n06AB;ARABIC LETTER KAF WITH RING;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH RING;;;;\n06AC;ARABIC LETTER KAF WITH DOT ABOVE;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH DOT ABOVE;;;;\n06AD;ARABIC LETTER NG;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS ABOVE;;;;\n06AE;ARABIC LETTER KAF WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER CAF WITH THREE DOTS BELOW;;;;\n06AF;ARABIC LETTER GAF;Lo;0;AL;;;;;N;;;;;\n06B0;ARABIC LETTER GAF WITH RING;Lo;0;AL;;;;;N;;;;;\n06B1;ARABIC LETTER NGOEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS ABOVE;;;;\n06B2;ARABIC LETTER GAF WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;\n06B3;ARABIC LETTER GUEH;Lo;0;AL;;;;;N;ARABIC LETTER GAF WITH TWO DOTS VERTICAL BELOW;;;;\n06B4;ARABIC LETTER GAF WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n06B5;ARABIC LETTER LAM WITH SMALL V;Lo;0;AL;;;;;N;;;;;\n06B6;ARABIC LETTER LAM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;\n06B7;ARABIC LETTER LAM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n06B8;ARABIC LETTER LAM WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;\n06B9;ARABIC LETTER NOON WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;\n06BA;ARABIC LETTER NOON GHUNNA;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON;;;;\n06BB;ARABIC LETTER RNOON;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS NOON WITH SMALL TAH;;;;\n06BC;ARABIC LETTER NOON WITH RING;Lo;0;AL;;;;;N;;;;;\n06BD;ARABIC LETTER NOON WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n06BE;ARABIC LETTER HEH DOACHASHMEE;Lo;0;AL;;;;;N;ARABIC LETTER KNOTTED HA;;;;\n06BF;ARABIC LETTER TCHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;\n06C0;ARABIC LETTER HEH WITH YEH ABOVE;Lo;0;AL;06D5 0654;;;;N;ARABIC LETTER HAMZAH ON HA;;;;\n06C1;ARABIC LETTER HEH GOAL;Lo;0;AL;;;;;N;ARABIC LETTER HA GOAL;;;;\n06C2;ARABIC LETTER HEH GOAL WITH HAMZA ABOVE;Lo;0;AL;06C1 0654;;;;N;ARABIC LETTER HAMZAH ON HA GOAL;;;;\n06C3;ARABIC LETTER TEH MARBUTA GOAL;Lo;0;AL;;;;;N;ARABIC LETTER TAA MARBUTAH GOAL;;;;\n06C4;ARABIC LETTER WAW WITH RING;Lo;0;AL;;;;;N;;;;;\n06C5;ARABIC LETTER KIRGHIZ OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH BAR;;;;\n06C6;ARABIC LETTER OE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH SMALL V;;;;\n06C7;ARABIC LETTER U;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH DAMMAH;;;;\n06C8;ARABIC LETTER YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH ALEF ABOVE;;;;\n06C9;ARABIC LETTER KIRGHIZ YU;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH INVERTED SMALL V;;;;\n06CA;ARABIC LETTER WAW WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n06CB;ARABIC LETTER VE;Lo;0;AL;;;;;N;ARABIC LETTER WAW WITH THREE DOTS ABOVE;;;;\n06CC;ARABIC LETTER FARSI YEH;Lo;0;AL;;;;;N;ARABIC LETTER DOTLESS YA;;;;\n06CD;ARABIC LETTER YEH WITH TAIL;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TAIL;;;;\n06CE;ARABIC LETTER YEH WITH SMALL V;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH SMALL V;;;;\n06CF;ARABIC LETTER WAW WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;\n06D0;ARABIC LETTER E;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH TWO DOTS VERTICAL BELOW;;;;\n06D1;ARABIC LETTER YEH WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;ARABIC LETTER YA WITH THREE DOTS BELOW;;;;\n06D2;ARABIC LETTER YEH BARREE;Lo;0;AL;;;;;N;ARABIC LETTER YA BARREE;;;;\n06D3;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE;Lo;0;AL;06D2 0654;;;;N;ARABIC LETTER HAMZAH ON YA BARREE;;;;\n06D4;ARABIC FULL STOP;Po;0;AL;;;;;N;ARABIC PERIOD;;;;\n06D5;ARABIC LETTER AE;Lo;0;AL;;;;;N;;;;;\n06D6;ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;;\n06D7;ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA;Mn;230;NSM;;;;;N;;;;;\n06D8;ARABIC SMALL HIGH MEEM INITIAL FORM;Mn;230;NSM;;;;;N;;;;;\n06D9;ARABIC SMALL HIGH LAM ALEF;Mn;230;NSM;;;;;N;;;;;\n06DA;ARABIC SMALL HIGH JEEM;Mn;230;NSM;;;;;N;;;;;\n06DB;ARABIC SMALL HIGH THREE DOTS;Mn;230;NSM;;;;;N;;;;;\n06DC;ARABIC SMALL HIGH SEEN;Mn;230;NSM;;;;;N;;;;;\n06DD;ARABIC END OF AYAH;Cf;0;AN;;;;;N;;;;;\n06DE;ARABIC START OF RUB EL HIZB;So;0;ON;;;;;N;;;;;\n06DF;ARABIC SMALL HIGH ROUNDED ZERO;Mn;230;NSM;;;;;N;;;;;\n06E0;ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO;Mn;230;NSM;;;;;N;;;;;\n06E1;ARABIC SMALL HIGH DOTLESS HEAD OF KHAH;Mn;230;NSM;;;;;N;;;;;\n06E2;ARABIC SMALL HIGH MEEM ISOLATED FORM;Mn;230;NSM;;;;;N;;;;;\n06E3;ARABIC SMALL LOW SEEN;Mn;220;NSM;;;;;N;;;;;\n06E4;ARABIC SMALL HIGH MADDA;Mn;230;NSM;;;;;N;;;;;\n06E5;ARABIC SMALL WAW;Lm;0;AL;;;;;N;;;;;\n06E6;ARABIC SMALL YEH;Lm;0;AL;;;;;N;;;;;\n06E7;ARABIC SMALL HIGH YEH;Mn;230;NSM;;;;;N;;;;;\n06E8;ARABIC SMALL HIGH NOON;Mn;230;NSM;;;;;N;;;;;\n06E9;ARABIC PLACE OF SAJDAH;So;0;ON;;;;;N;;;;;\n06EA;ARABIC EMPTY CENTRE LOW STOP;Mn;220;NSM;;;;;N;;;;;\n06EB;ARABIC EMPTY CENTRE HIGH STOP;Mn;230;NSM;;;;;N;;;;;\n06EC;ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE;Mn;230;NSM;;;;;N;;;;;\n06ED;ARABIC SMALL LOW MEEM;Mn;220;NSM;;;;;N;;;;;\n06EE;ARABIC LETTER DAL WITH INVERTED V;Lo;0;AL;;;;;N;;;;;\n06EF;ARABIC LETTER REH WITH INVERTED V;Lo;0;AL;;;;;N;;;;;\n06F0;EXTENDED ARABIC-INDIC DIGIT ZERO;Nd;0;EN;;0;0;0;N;EASTERN ARABIC-INDIC DIGIT ZERO;;;;\n06F1;EXTENDED ARABIC-INDIC DIGIT ONE;Nd;0;EN;;1;1;1;N;EASTERN ARABIC-INDIC DIGIT ONE;;;;\n06F2;EXTENDED ARABIC-INDIC DIGIT TWO;Nd;0;EN;;2;2;2;N;EASTERN ARABIC-INDIC DIGIT TWO;;;;\n06F3;EXTENDED ARABIC-INDIC DIGIT THREE;Nd;0;EN;;3;3;3;N;EASTERN ARABIC-INDIC DIGIT THREE;;;;\n06F4;EXTENDED ARABIC-INDIC DIGIT FOUR;Nd;0;EN;;4;4;4;N;EASTERN ARABIC-INDIC DIGIT FOUR;;;;\n06F5;EXTENDED ARABIC-INDIC DIGIT FIVE;Nd;0;EN;;5;5;5;N;EASTERN ARABIC-INDIC DIGIT FIVE;;;;\n06F6;EXTENDED ARABIC-INDIC DIGIT SIX;Nd;0;EN;;6;6;6;N;EASTERN ARABIC-INDIC DIGIT SIX;;;;\n06F7;EXTENDED ARABIC-INDIC DIGIT SEVEN;Nd;0;EN;;7;7;7;N;EASTERN ARABIC-INDIC DIGIT SEVEN;;;;\n06F8;EXTENDED ARABIC-INDIC DIGIT EIGHT;Nd;0;EN;;8;8;8;N;EASTERN ARABIC-INDIC DIGIT EIGHT;;;;\n06F9;EXTENDED ARABIC-INDIC DIGIT NINE;Nd;0;EN;;9;9;9;N;EASTERN ARABIC-INDIC DIGIT NINE;;;;\n06FA;ARABIC LETTER SHEEN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;\n06FB;ARABIC LETTER DAD WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;\n06FC;ARABIC LETTER GHAIN WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;\n06FD;ARABIC SIGN SINDHI AMPERSAND;So;0;AL;;;;;N;;;;;\n06FE;ARABIC SIGN SINDHI POSTPOSITION MEN;So;0;AL;;;;;N;;;;;\n06FF;ARABIC LETTER HEH WITH INVERTED V;Lo;0;AL;;;;;N;;;;;\n0700;SYRIAC END OF PARAGRAPH;Po;0;AL;;;;;N;;;;;\n0701;SYRIAC SUPRALINEAR FULL STOP;Po;0;AL;;;;;N;;;;;\n0702;SYRIAC SUBLINEAR FULL STOP;Po;0;AL;;;;;N;;;;;\n0703;SYRIAC SUPRALINEAR COLON;Po;0;AL;;;;;N;;;;;\n0704;SYRIAC SUBLINEAR COLON;Po;0;AL;;;;;N;;;;;\n0705;SYRIAC HORIZONTAL COLON;Po;0;AL;;;;;N;;;;;\n0706;SYRIAC COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;;\n0707;SYRIAC COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;;\n0708;SYRIAC SUPRALINEAR COLON SKEWED LEFT;Po;0;AL;;;;;N;;;;;\n0709;SYRIAC SUBLINEAR COLON SKEWED RIGHT;Po;0;AL;;;;;N;;;;;\n070A;SYRIAC CONTRACTION;Po;0;AL;;;;;N;;;;;\n070B;SYRIAC HARKLEAN OBELUS;Po;0;AL;;;;;N;;;;;\n070C;SYRIAC HARKLEAN METOBELUS;Po;0;AL;;;;;N;;;;;\n070D;SYRIAC HARKLEAN ASTERISCUS;Po;0;AL;;;;;N;;;;;\n070F;SYRIAC ABBREVIATION MARK;Cf;0;AL;;;;;N;;;;;\n0710;SYRIAC LETTER ALAPH;Lo;0;AL;;;;;N;;;;;\n0711;SYRIAC LETTER SUPERSCRIPT ALAPH;Mn;36;NSM;;;;;N;;;;;\n0712;SYRIAC LETTER BETH;Lo;0;AL;;;;;N;;;;;\n0713;SYRIAC LETTER GAMAL;Lo;0;AL;;;;;N;;;;;\n0714;SYRIAC LETTER GAMAL GARSHUNI;Lo;0;AL;;;;;N;;;;;\n0715;SYRIAC LETTER DALATH;Lo;0;AL;;;;;N;;;;;\n0716;SYRIAC LETTER DOTLESS DALATH RISH;Lo;0;AL;;;;;N;;;;;\n0717;SYRIAC LETTER HE;Lo;0;AL;;;;;N;;;;;\n0718;SYRIAC LETTER WAW;Lo;0;AL;;;;;N;;;;;\n0719;SYRIAC LETTER ZAIN;Lo;0;AL;;;;;N;;;;;\n071A;SYRIAC LETTER HETH;Lo;0;AL;;;;;N;;;;;\n071B;SYRIAC LETTER TETH;Lo;0;AL;;;;;N;;;;;\n071C;SYRIAC LETTER TETH GARSHUNI;Lo;0;AL;;;;;N;;;;;\n071D;SYRIAC LETTER YUDH;Lo;0;AL;;;;;N;;;;;\n071E;SYRIAC LETTER YUDH HE;Lo;0;AL;;;;;N;;;;;\n071F;SYRIAC LETTER KAPH;Lo;0;AL;;;;;N;;;;;\n0720;SYRIAC LETTER LAMADH;Lo;0;AL;;;;;N;;;;;\n0721;SYRIAC LETTER MIM;Lo;0;AL;;;;;N;;;;;\n0722;SYRIAC LETTER NUN;Lo;0;AL;;;;;N;;;;;\n0723;SYRIAC LETTER SEMKATH;Lo;0;AL;;;;;N;;;;;\n0724;SYRIAC LETTER FINAL SEMKATH;Lo;0;AL;;;;;N;;;;;\n0725;SYRIAC LETTER E;Lo;0;AL;;;;;N;;;;;\n0726;SYRIAC LETTER PE;Lo;0;AL;;;;;N;;;;;\n0727;SYRIAC LETTER REVERSED PE;Lo;0;AL;;;;;N;;;;;\n0728;SYRIAC LETTER SADHE;Lo;0;AL;;;;;N;;;;;\n0729;SYRIAC LETTER QAPH;Lo;0;AL;;;;;N;;;;;\n072A;SYRIAC LETTER RISH;Lo;0;AL;;;;;N;;;;;\n072B;SYRIAC LETTER SHIN;Lo;0;AL;;;;;N;;;;;\n072C;SYRIAC LETTER TAW;Lo;0;AL;;;;;N;;;;;\n072D;SYRIAC LETTER PERSIAN BHETH;Lo;0;AL;;;;;N;;;;;\n072E;SYRIAC LETTER PERSIAN GHAMAL;Lo;0;AL;;;;;N;;;;;\n072F;SYRIAC LETTER PERSIAN DHALATH;Lo;0;AL;;;;;N;;;;;\n0730;SYRIAC PTHAHA ABOVE;Mn;230;NSM;;;;;N;;;;;\n0731;SYRIAC PTHAHA BELOW;Mn;220;NSM;;;;;N;;;;;\n0732;SYRIAC PTHAHA DOTTED;Mn;230;NSM;;;;;N;;;;;\n0733;SYRIAC ZQAPHA ABOVE;Mn;230;NSM;;;;;N;;;;;\n0734;SYRIAC ZQAPHA BELOW;Mn;220;NSM;;;;;N;;;;;\n0735;SYRIAC ZQAPHA DOTTED;Mn;230;NSM;;;;;N;;;;;\n0736;SYRIAC RBASA ABOVE;Mn;230;NSM;;;;;N;;;;;\n0737;SYRIAC RBASA BELOW;Mn;220;NSM;;;;;N;;;;;\n0738;SYRIAC DOTTED ZLAMA HORIZONTAL;Mn;220;NSM;;;;;N;;;;;\n0739;SYRIAC DOTTED ZLAMA ANGULAR;Mn;220;NSM;;;;;N;;;;;\n073A;SYRIAC HBASA ABOVE;Mn;230;NSM;;;;;N;;;;;\n073B;SYRIAC HBASA BELOW;Mn;220;NSM;;;;;N;;;;;\n073C;SYRIAC HBASA-ESASA DOTTED;Mn;220;NSM;;;;;N;;;;;\n073D;SYRIAC ESASA ABOVE;Mn;230;NSM;;;;;N;;;;;\n073E;SYRIAC ESASA BELOW;Mn;220;NSM;;;;;N;;;;;\n073F;SYRIAC RWAHA;Mn;230;NSM;;;;;N;;;;;\n0740;SYRIAC FEMININE DOT;Mn;230;NSM;;;;;N;;;;;\n0741;SYRIAC QUSHSHAYA;Mn;230;NSM;;;;;N;;;;;\n0742;SYRIAC RUKKAKHA;Mn;220;NSM;;;;;N;;;;;\n0743;SYRIAC TWO VERTICAL DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;\n0744;SYRIAC TWO VERTICAL DOTS BELOW;Mn;220;NSM;;;;;N;;;;;\n0745;SYRIAC THREE DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;\n0746;SYRIAC THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;;\n0747;SYRIAC OBLIQUE LINE ABOVE;Mn;230;NSM;;;;;N;;;;;\n0748;SYRIAC OBLIQUE LINE BELOW;Mn;220;NSM;;;;;N;;;;;\n0749;SYRIAC MUSIC;Mn;230;NSM;;;;;N;;;;;\n074A;SYRIAC BARREKH;Mn;230;NSM;;;;;N;;;;;\n074D;SYRIAC LETTER SOGDIAN ZHAIN;Lo;0;AL;;;;;N;;;;;\n074E;SYRIAC LETTER SOGDIAN KHAPH;Lo;0;AL;;;;;N;;;;;\n074F;SYRIAC LETTER SOGDIAN FE;Lo;0;AL;;;;;N;;;;;\n0750;ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW;Lo;0;AL;;;;;N;;;;;\n0751;ARABIC LETTER BEH WITH DOT BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n0752;ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;\n0753;ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW AND TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n0754;ARABIC LETTER BEH WITH TWO DOTS BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;\n0755;ARABIC LETTER BEH WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;;\n0756;ARABIC LETTER BEH WITH SMALL V;Lo;0;AL;;;;;N;;;;;\n0757;ARABIC LETTER HAH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n0758;ARABIC LETTER HAH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;\n0759;ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW AND SMALL TAH;Lo;0;AL;;;;;N;;;;;\n075A;ARABIC LETTER DAL WITH INVERTED SMALL V BELOW;Lo;0;AL;;;;;N;;;;;\n075B;ARABIC LETTER REH WITH STROKE;Lo;0;AL;;;;;N;;;;;\n075C;ARABIC LETTER SEEN WITH FOUR DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n075D;ARABIC LETTER AIN WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n075E;ARABIC LETTER AIN WITH THREE DOTS POINTING DOWNWARDS ABOVE;Lo;0;AL;;;;;N;;;;;\n075F;ARABIC LETTER AIN WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;;\n0760;ARABIC LETTER FEH WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;\n0761;ARABIC LETTER FEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;\n0762;ARABIC LETTER KEHEH WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;\n0763;ARABIC LETTER KEHEH WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n0764;ARABIC LETTER KEHEH WITH THREE DOTS POINTING UPWARDS BELOW;Lo;0;AL;;;;;N;;;;;\n0765;ARABIC LETTER MEEM WITH DOT ABOVE;Lo;0;AL;;;;;N;;;;;\n0766;ARABIC LETTER MEEM WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;\n0767;ARABIC LETTER NOON WITH TWO DOTS BELOW;Lo;0;AL;;;;;N;;;;;\n0768;ARABIC LETTER NOON WITH SMALL TAH;Lo;0;AL;;;;;N;;;;;\n0769;ARABIC LETTER NOON WITH SMALL V;Lo;0;AL;;;;;N;;;;;\n076A;ARABIC LETTER LAM WITH BAR;Lo;0;AL;;;;;N;;;;;\n076B;ARABIC LETTER REH WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;;\n076C;ARABIC LETTER REH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;;\n076D;ARABIC LETTER SEEN WITH TWO DOTS VERTICALLY ABOVE;Lo;0;AL;;;;;N;;;;;\n076E;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH BELOW;Lo;0;AL;;;;;N;;;;;\n076F;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;;\n0770;ARABIC LETTER SEEN WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;;\n0771;ARABIC LETTER REH WITH SMALL ARABIC LETTER TAH AND TWO DOTS;Lo;0;AL;;;;;N;;;;;\n0772;ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH ABOVE;Lo;0;AL;;;;;N;;;;;\n0773;ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;\n0774;ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;\n0775;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;\n0776;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;\n0777;ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW;Lo;0;AL;;;;;N;;;;;\n0778;ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;\n0779;ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;\n077A;ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE;Lo;0;AL;;;;;N;;;;;\n077B;ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE;Lo;0;AL;;;;;N;;;;;\n077C;ARABIC LETTER HAH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW;Lo;0;AL;;;;;N;;;;;\n077D;ARABIC LETTER SEEN WITH EXTENDED ARABIC-INDIC DIGIT FOUR ABOVE;Lo;0;AL;;;;;N;;;;;\n077E;ARABIC LETTER SEEN WITH INVERTED V;Lo;0;AL;;;;;N;;;;;\n077F;ARABIC LETTER KAF WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n0780;THAANA LETTER HAA;Lo;0;AL;;;;;N;;;;;\n0781;THAANA LETTER SHAVIYANI;Lo;0;AL;;;;;N;;;;;\n0782;THAANA LETTER NOONU;Lo;0;AL;;;;;N;;;;;\n0783;THAANA LETTER RAA;Lo;0;AL;;;;;N;;;;;\n0784;THAANA LETTER BAA;Lo;0;AL;;;;;N;;;;;\n0785;THAANA LETTER LHAVIYANI;Lo;0;AL;;;;;N;;;;;\n0786;THAANA LETTER KAAFU;Lo;0;AL;;;;;N;;;;;\n0787;THAANA LETTER ALIFU;Lo;0;AL;;;;;N;;;;;\n0788;THAANA LETTER VAAVU;Lo;0;AL;;;;;N;;;;;\n0789;THAANA LETTER MEEMU;Lo;0;AL;;;;;N;;;;;\n078A;THAANA LETTER FAAFU;Lo;0;AL;;;;;N;;;;;\n078B;THAANA LETTER DHAALU;Lo;0;AL;;;;;N;;;;;\n078C;THAANA LETTER THAA;Lo;0;AL;;;;;N;;;;;\n078D;THAANA LETTER LAAMU;Lo;0;AL;;;;;N;;;;;\n078E;THAANA LETTER GAAFU;Lo;0;AL;;;;;N;;;;;\n078F;THAANA LETTER GNAVIYANI;Lo;0;AL;;;;;N;;;;;\n0790;THAANA LETTER SEENU;Lo;0;AL;;;;;N;;;;;\n0791;THAANA LETTER DAVIYANI;Lo;0;AL;;;;;N;;;;;\n0792;THAANA LETTER ZAVIYANI;Lo;0;AL;;;;;N;;;;;\n0793;THAANA LETTER TAVIYANI;Lo;0;AL;;;;;N;;;;;\n0794;THAANA LETTER YAA;Lo;0;AL;;;;;N;;;;;\n0795;THAANA LETTER PAVIYANI;Lo;0;AL;;;;;N;;;;;\n0796;THAANA LETTER JAVIYANI;Lo;0;AL;;;;;N;;;;;\n0797;THAANA LETTER CHAVIYANI;Lo;0;AL;;;;;N;;;;;\n0798;THAANA LETTER TTAA;Lo;0;AL;;;;;N;;;;;\n0799;THAANA LETTER HHAA;Lo;0;AL;;;;;N;;;;;\n079A;THAANA LETTER KHAA;Lo;0;AL;;;;;N;;;;;\n079B;THAANA LETTER THAALU;Lo;0;AL;;;;;N;;;;;\n079C;THAANA LETTER ZAA;Lo;0;AL;;;;;N;;;;;\n079D;THAANA LETTER SHEENU;Lo;0;AL;;;;;N;;;;;\n079E;THAANA LETTER SAADHU;Lo;0;AL;;;;;N;;;;;\n079F;THAANA LETTER DAADHU;Lo;0;AL;;;;;N;;;;;\n07A0;THAANA LETTER TO;Lo;0;AL;;;;;N;;;;;\n07A1;THAANA LETTER ZO;Lo;0;AL;;;;;N;;;;;\n07A2;THAANA LETTER AINU;Lo;0;AL;;;;;N;;;;;\n07A3;THAANA LETTER GHAINU;Lo;0;AL;;;;;N;;;;;\n07A4;THAANA LETTER QAAFU;Lo;0;AL;;;;;N;;;;;\n07A5;THAANA LETTER WAAVU;Lo;0;AL;;;;;N;;;;;\n07A6;THAANA ABAFILI;Mn;0;NSM;;;;;N;;;;;\n07A7;THAANA AABAAFILI;Mn;0;NSM;;;;;N;;;;;\n07A8;THAANA IBIFILI;Mn;0;NSM;;;;;N;;;;;\n07A9;THAANA EEBEEFILI;Mn;0;NSM;;;;;N;;;;;\n07AA;THAANA UBUFILI;Mn;0;NSM;;;;;N;;;;;\n07AB;THAANA OOBOOFILI;Mn;0;NSM;;;;;N;;;;;\n07AC;THAANA EBEFILI;Mn;0;NSM;;;;;N;;;;;\n07AD;THAANA EYBEYFILI;Mn;0;NSM;;;;;N;;;;;\n07AE;THAANA OBOFILI;Mn;0;NSM;;;;;N;;;;;\n07AF;THAANA OABOAFILI;Mn;0;NSM;;;;;N;;;;;\n07B0;THAANA SUKUN;Mn;0;NSM;;;;;N;;;;;\n07B1;THAANA LETTER NAA;Lo;0;AL;;;;;N;;;;;\n07C0;NKO DIGIT ZERO;Nd;0;R;;0;0;0;N;;;;;\n07C1;NKO DIGIT ONE;Nd;0;R;;1;1;1;N;;;;;\n07C2;NKO DIGIT TWO;Nd;0;R;;2;2;2;N;;;;;\n07C3;NKO DIGIT THREE;Nd;0;R;;3;3;3;N;;;;;\n07C4;NKO DIGIT FOUR;Nd;0;R;;4;4;4;N;;;;;\n07C5;NKO DIGIT FIVE;Nd;0;R;;5;5;5;N;;;;;\n07C6;NKO DIGIT SIX;Nd;0;R;;6;6;6;N;;;;;\n07C7;NKO DIGIT SEVEN;Nd;0;R;;7;7;7;N;;;;;\n07C8;NKO DIGIT EIGHT;Nd;0;R;;8;8;8;N;;;;;\n07C9;NKO DIGIT NINE;Nd;0;R;;9;9;9;N;;;;;\n07CA;NKO LETTER A;Lo;0;R;;;;;N;;;;;\n07CB;NKO LETTER EE;Lo;0;R;;;;;N;;;;;\n07CC;NKO LETTER I;Lo;0;R;;;;;N;;;;;\n07CD;NKO LETTER E;Lo;0;R;;;;;N;;;;;\n07CE;NKO LETTER U;Lo;0;R;;;;;N;;;;;\n07CF;NKO LETTER OO;Lo;0;R;;;;;N;;;;;\n07D0;NKO LETTER O;Lo;0;R;;;;;N;;;;;\n07D1;NKO LETTER DAGBASINNA;Lo;0;R;;;;;N;;;;;\n07D2;NKO LETTER N;Lo;0;R;;;;;N;;;;;\n07D3;NKO LETTER BA;Lo;0;R;;;;;N;;;;;\n07D4;NKO LETTER PA;Lo;0;R;;;;;N;;;;;\n07D5;NKO LETTER TA;Lo;0;R;;;;;N;;;;;\n07D6;NKO LETTER JA;Lo;0;R;;;;;N;;;;;\n07D7;NKO LETTER CHA;Lo;0;R;;;;;N;;;;;\n07D8;NKO LETTER DA;Lo;0;R;;;;;N;;;;;\n07D9;NKO LETTER RA;Lo;0;R;;;;;N;;;;;\n07DA;NKO LETTER RRA;Lo;0;R;;;;;N;;;;;\n07DB;NKO LETTER SA;Lo;0;R;;;;;N;;;;;\n07DC;NKO LETTER GBA;Lo;0;R;;;;;N;;;;;\n07DD;NKO LETTER FA;Lo;0;R;;;;;N;;;;;\n07DE;NKO LETTER KA;Lo;0;R;;;;;N;;;;;\n07DF;NKO LETTER LA;Lo;0;R;;;;;N;;;;;\n07E0;NKO LETTER NA WOLOSO;Lo;0;R;;;;;N;;;;;\n07E1;NKO LETTER MA;Lo;0;R;;;;;N;;;;;\n07E2;NKO LETTER NYA;Lo;0;R;;;;;N;;;;;\n07E3;NKO LETTER NA;Lo;0;R;;;;;N;;;;;\n07E4;NKO LETTER HA;Lo;0;R;;;;;N;;;;;\n07E5;NKO LETTER WA;Lo;0;R;;;;;N;;;;;\n07E6;NKO LETTER YA;Lo;0;R;;;;;N;;;;;\n07E7;NKO LETTER NYA WOLOSO;Lo;0;R;;;;;N;;;;;\n07E8;NKO LETTER JONA JA;Lo;0;R;;;;;N;;;;;\n07E9;NKO LETTER JONA CHA;Lo;0;R;;;;;N;;;;;\n07EA;NKO LETTER JONA RA;Lo;0;R;;;;;N;;;;;\n07EB;NKO COMBINING SHORT HIGH TONE;Mn;230;NSM;;;;;N;;;;;\n07EC;NKO COMBINING SHORT LOW TONE;Mn;230;NSM;;;;;N;;;;;\n07ED;NKO COMBINING SHORT RISING TONE;Mn;230;NSM;;;;;N;;;;;\n07EE;NKO COMBINING LONG DESCENDING TONE;Mn;230;NSM;;;;;N;;;;;\n07EF;NKO COMBINING LONG HIGH TONE;Mn;230;NSM;;;;;N;;;;;\n07F0;NKO COMBINING LONG LOW TONE;Mn;230;NSM;;;;;N;;;;;\n07F1;NKO COMBINING LONG RISING TONE;Mn;230;NSM;;;;;N;;;;;\n07F2;NKO COMBINING NASALIZATION MARK;Mn;220;NSM;;;;;N;;;;;\n07F3;NKO COMBINING DOUBLE DOT ABOVE;Mn;230;NSM;;;;;N;;;;;\n07F4;NKO HIGH TONE APOSTROPHE;Lm;0;R;;;;;N;;;;;\n07F5;NKO LOW TONE APOSTROPHE;Lm;0;R;;;;;N;;;;;\n07F6;NKO SYMBOL OO DENNEN;So;0;ON;;;;;N;;;;;\n07F7;NKO SYMBOL GBAKURUNEN;Po;0;ON;;;;;N;;;;;\n07F8;NKO COMMA;Po;0;ON;;;;;N;;;;;\n07F9;NKO EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;\n07FA;NKO LAJANYALAN;Lm;0;R;;;;;N;;;;;\n07FD;NKO DANTAYALAN;Mn;220;NSM;;;;;N;;;;;\n07FE;NKO DOROME SIGN;Sc;0;R;;;;;N;;;;;\n07FF;NKO TAMAN SIGN;Sc;0;R;;;;;N;;;;;\n0800;SAMARITAN LETTER ALAF;Lo;0;R;;;;;N;;;;;\n0801;SAMARITAN LETTER BIT;Lo;0;R;;;;;N;;;;;\n0802;SAMARITAN LETTER GAMAN;Lo;0;R;;;;;N;;;;;\n0803;SAMARITAN LETTER DALAT;Lo;0;R;;;;;N;;;;;\n0804;SAMARITAN LETTER IY;Lo;0;R;;;;;N;;;;;\n0805;SAMARITAN LETTER BAA;Lo;0;R;;;;;N;;;;;\n0806;SAMARITAN LETTER ZEN;Lo;0;R;;;;;N;;;;;\n0807;SAMARITAN LETTER IT;Lo;0;R;;;;;N;;;;;\n0808;SAMARITAN LETTER TIT;Lo;0;R;;;;;N;;;;;\n0809;SAMARITAN LETTER YUT;Lo;0;R;;;;;N;;;;;\n080A;SAMARITAN LETTER KAAF;Lo;0;R;;;;;N;;;;;\n080B;SAMARITAN LETTER LABAT;Lo;0;R;;;;;N;;;;;\n080C;SAMARITAN LETTER MIM;Lo;0;R;;;;;N;;;;;\n080D;SAMARITAN LETTER NUN;Lo;0;R;;;;;N;;;;;\n080E;SAMARITAN LETTER SINGAAT;Lo;0;R;;;;;N;;;;;\n080F;SAMARITAN LETTER IN;Lo;0;R;;;;;N;;;;;\n0810;SAMARITAN LETTER FI;Lo;0;R;;;;;N;;;;;\n0811;SAMARITAN LETTER TSAADIY;Lo;0;R;;;;;N;;;;;\n0812;SAMARITAN LETTER QUF;Lo;0;R;;;;;N;;;;;\n0813;SAMARITAN LETTER RISH;Lo;0;R;;;;;N;;;;;\n0814;SAMARITAN LETTER SHAN;Lo;0;R;;;;;N;;;;;\n0815;SAMARITAN LETTER TAAF;Lo;0;R;;;;;N;;;;;\n0816;SAMARITAN MARK IN;Mn;230;NSM;;;;;N;;;;;\n0817;SAMARITAN MARK IN-ALAF;Mn;230;NSM;;;;;N;;;;;\n0818;SAMARITAN MARK OCCLUSION;Mn;230;NSM;;;;;N;;;;;\n0819;SAMARITAN MARK DAGESH;Mn;230;NSM;;;;;N;;;;;\n081A;SAMARITAN MODIFIER LETTER EPENTHETIC YUT;Lm;0;R;;;;;N;;;;;\n081B;SAMARITAN MARK EPENTHETIC YUT;Mn;230;NSM;;;;;N;;;;;\n081C;SAMARITAN VOWEL SIGN LONG E;Mn;230;NSM;;;;;N;;;;;\n081D;SAMARITAN VOWEL SIGN E;Mn;230;NSM;;;;;N;;;;;\n081E;SAMARITAN VOWEL SIGN OVERLONG AA;Mn;230;NSM;;;;;N;;;;;\n081F;SAMARITAN VOWEL SIGN LONG AA;Mn;230;NSM;;;;;N;;;;;\n0820;SAMARITAN VOWEL SIGN AA;Mn;230;NSM;;;;;N;;;;;\n0821;SAMARITAN VOWEL SIGN OVERLONG A;Mn;230;NSM;;;;;N;;;;;\n0822;SAMARITAN VOWEL SIGN LONG A;Mn;230;NSM;;;;;N;;;;;\n0823;SAMARITAN VOWEL SIGN A;Mn;230;NSM;;;;;N;;;;;\n0824;SAMARITAN MODIFIER LETTER SHORT A;Lm;0;R;;;;;N;;;;;\n0825;SAMARITAN VOWEL SIGN SHORT A;Mn;230;NSM;;;;;N;;;;;\n0826;SAMARITAN VOWEL SIGN LONG U;Mn;230;NSM;;;;;N;;;;;\n0827;SAMARITAN VOWEL SIGN U;Mn;230;NSM;;;;;N;;;;;\n0828;SAMARITAN MODIFIER LETTER I;Lm;0;R;;;;;N;;;;;\n0829;SAMARITAN VOWEL SIGN LONG I;Mn;230;NSM;;;;;N;;;;;\n082A;SAMARITAN VOWEL SIGN I;Mn;230;NSM;;;;;N;;;;;\n082B;SAMARITAN VOWEL SIGN O;Mn;230;NSM;;;;;N;;;;;\n082C;SAMARITAN VOWEL SIGN SUKUN;Mn;230;NSM;;;;;N;;;;;\n082D;SAMARITAN MARK NEQUDAA;Mn;230;NSM;;;;;N;;;;;\n0830;SAMARITAN PUNCTUATION NEQUDAA;Po;0;R;;;;;N;;;;;\n0831;SAMARITAN PUNCTUATION AFSAAQ;Po;0;R;;;;;N;;;;;\n0832;SAMARITAN PUNCTUATION ANGED;Po;0;R;;;;;N;;;;;\n0833;SAMARITAN PUNCTUATION BAU;Po;0;R;;;;;N;;;;;\n0834;SAMARITAN PUNCTUATION ATMAAU;Po;0;R;;;;;N;;;;;\n0835;SAMARITAN PUNCTUATION SHIYYAALAA;Po;0;R;;;;;N;;;;;\n0836;SAMARITAN ABBREVIATION MARK;Po;0;R;;;;;N;;;;;\n0837;SAMARITAN PUNCTUATION MELODIC QITSA;Po;0;R;;;;;N;;;;;\n0838;SAMARITAN PUNCTUATION ZIQAA;Po;0;R;;;;;N;;;;;\n0839;SAMARITAN PUNCTUATION QITSA;Po;0;R;;;;;N;;;;;\n083A;SAMARITAN PUNCTUATION ZAEF;Po;0;R;;;;;N;;;;;\n083B;SAMARITAN PUNCTUATION TURU;Po;0;R;;;;;N;;;;;\n083C;SAMARITAN PUNCTUATION ARKAANU;Po;0;R;;;;;N;;;;;\n083D;SAMARITAN PUNCTUATION SOF MASHFAAT;Po;0;R;;;;;N;;;;;\n083E;SAMARITAN PUNCTUATION ANNAAU;Po;0;R;;;;;N;;;;;\n0840;MANDAIC LETTER HALQA;Lo;0;R;;;;;N;;;;;\n0841;MANDAIC LETTER AB;Lo;0;R;;;;;N;;;;;\n0842;MANDAIC LETTER AG;Lo;0;R;;;;;N;;;;;\n0843;MANDAIC LETTER AD;Lo;0;R;;;;;N;;;;;\n0844;MANDAIC LETTER AH;Lo;0;R;;;;;N;;;;;\n0845;MANDAIC LETTER USHENNA;Lo;0;R;;;;;N;;;;;\n0846;MANDAIC LETTER AZ;Lo;0;R;;;;;N;;;;;\n0847;MANDAIC LETTER IT;Lo;0;R;;;;;N;;;;;\n0848;MANDAIC LETTER ATT;Lo;0;R;;;;;N;;;;;\n0849;MANDAIC LETTER AKSA;Lo;0;R;;;;;N;;;;;\n084A;MANDAIC LETTER AK;Lo;0;R;;;;;N;;;;;\n084B;MANDAIC LETTER AL;Lo;0;R;;;;;N;;;;;\n084C;MANDAIC LETTER AM;Lo;0;R;;;;;N;;;;;\n084D;MANDAIC LETTER AN;Lo;0;R;;;;;N;;;;;\n084E;MANDAIC LETTER AS;Lo;0;R;;;;;N;;;;;\n084F;MANDAIC LETTER IN;Lo;0;R;;;;;N;;;;;\n0850;MANDAIC LETTER AP;Lo;0;R;;;;;N;;;;;\n0851;MANDAIC LETTER ASZ;Lo;0;R;;;;;N;;;;;\n0852;MANDAIC LETTER AQ;Lo;0;R;;;;;N;;;;;\n0853;MANDAIC LETTER AR;Lo;0;R;;;;;N;;;;;\n0854;MANDAIC LETTER ASH;Lo;0;R;;;;;N;;;;;\n0855;MANDAIC LETTER AT;Lo;0;R;;;;;N;;;;;\n0856;MANDAIC LETTER DUSHENNA;Lo;0;R;;;;;N;;;;;\n0857;MANDAIC LETTER KAD;Lo;0;R;;;;;N;;;;;\n0858;MANDAIC LETTER AIN;Lo;0;R;;;;;N;;;;;\n0859;MANDAIC AFFRICATION MARK;Mn;220;NSM;;;;;N;;;;;\n085A;MANDAIC VOCALIZATION MARK;Mn;220;NSM;;;;;N;;;;;\n085B;MANDAIC GEMINATION MARK;Mn;220;NSM;;;;;N;;;;;\n085E;MANDAIC PUNCTUATION;Po;0;R;;;;;N;;;;;\n0860;SYRIAC LETTER MALAYALAM NGA;Lo;0;AL;;;;;N;;;;;\n0861;SYRIAC LETTER MALAYALAM JA;Lo;0;AL;;;;;N;;;;;\n0862;SYRIAC LETTER MALAYALAM NYA;Lo;0;AL;;;;;N;;;;;\n0863;SYRIAC LETTER MALAYALAM TTA;Lo;0;AL;;;;;N;;;;;\n0864;SYRIAC LETTER MALAYALAM NNA;Lo;0;AL;;;;;N;;;;;\n0865;SYRIAC LETTER MALAYALAM NNNA;Lo;0;AL;;;;;N;;;;;\n0866;SYRIAC LETTER MALAYALAM BHA;Lo;0;AL;;;;;N;;;;;\n0867;SYRIAC LETTER MALAYALAM RA;Lo;0;AL;;;;;N;;;;;\n0868;SYRIAC LETTER MALAYALAM LLA;Lo;0;AL;;;;;N;;;;;\n0869;SYRIAC LETTER MALAYALAM LLLA;Lo;0;AL;;;;;N;;;;;\n086A;SYRIAC LETTER MALAYALAM SSA;Lo;0;AL;;;;;N;;;;;\n08A0;ARABIC LETTER BEH WITH SMALL V BELOW;Lo;0;AL;;;;;N;;;;;\n08A1;ARABIC LETTER BEH WITH HAMZA ABOVE;Lo;0;AL;;;;;N;;;;;\n08A2;ARABIC LETTER JEEM WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n08A3;ARABIC LETTER TAH WITH TWO DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n08A4;ARABIC LETTER FEH WITH DOT BELOW AND THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n08A5;ARABIC LETTER QAF WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;\n08A6;ARABIC LETTER LAM WITH DOUBLE BAR;Lo;0;AL;;;;;N;;;;;\n08A7;ARABIC LETTER MEEM WITH THREE DOTS ABOVE;Lo;0;AL;;;;;N;;;;;\n08A8;ARABIC LETTER YEH WITH TWO DOTS BELOW AND HAMZA ABOVE;Lo;0;AL;;;;;N;;;;;\n08A9;ARABIC LETTER YEH WITH TWO DOTS BELOW AND DOT ABOVE;Lo;0;AL;;;;;N;;;;;\n08AA;ARABIC LETTER REH WITH LOOP;Lo;0;AL;;;;;N;;;;;\n08AB;ARABIC LETTER WAW WITH DOT WITHIN;Lo;0;AL;;;;;N;;;;;\n08AC;ARABIC LETTER ROHINGYA YEH;Lo;0;AL;;;;;N;;;;;\n08AD;ARABIC LETTER LOW ALEF;Lo;0;AL;;;;;N;;;;;\n08AE;ARABIC LETTER DAL WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;\n08AF;ARABIC LETTER SAD WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;\n08B0;ARABIC LETTER GAF WITH INVERTED STROKE;Lo;0;AL;;;;;N;;;;;\n08B1;ARABIC LETTER STRAIGHT WAW;Lo;0;AL;;;;;N;;;;;\n08B2;ARABIC LETTER ZAIN WITH INVERTED V ABOVE;Lo;0;AL;;;;;N;;;;;\n08B3;ARABIC LETTER AIN WITH THREE DOTS BELOW;Lo;0;AL;;;;;N;;;;;\n08B4;ARABIC LETTER KAF WITH DOT BELOW;Lo;0;AL;;;;;N;;;;;\n08B6;ARABIC LETTER BEH WITH SMALL MEEM ABOVE;Lo;0;AL;;;;;N;;;;;\n08B7;ARABIC LETTER PEH WITH SMALL MEEM ABOVE;Lo;0;AL;;;;;N;;;;;\n08B8;ARABIC LETTER TEH WITH SMALL TEH ABOVE;Lo;0;AL;;;;;N;;;;;\n08B9;ARABIC LETTER REH WITH SMALL NOON ABOVE;Lo;0;AL;;;;;N;;;;;\n08BA;ARABIC LETTER YEH WITH TWO DOTS BELOW AND SMALL NOON ABOVE;Lo;0;AL;;;;;N;;;;;\n08BB;ARABIC LETTER AFRICAN FEH;Lo;0;AL;;;;;N;;;;;\n08BC;ARABIC LETTER AFRICAN QAF;Lo;0;AL;;;;;N;;;;;\n08BD;ARABIC LETTER AFRICAN NOON;Lo;0;AL;;;;;N;;;;;\n08D3;ARABIC SMALL LOW WAW;Mn;220;NSM;;;;;N;;;;;\n08D4;ARABIC SMALL HIGH WORD AR-RUB;Mn;230;NSM;;;;;N;;;;;\n08D5;ARABIC SMALL HIGH SAD;Mn;230;NSM;;;;;N;;;;;\n08D6;ARABIC SMALL HIGH AIN;Mn;230;NSM;;;;;N;;;;;\n08D7;ARABIC SMALL HIGH QAF;Mn;230;NSM;;;;;N;;;;;\n08D8;ARABIC SMALL HIGH NOON WITH KASRA;Mn;230;NSM;;;;;N;;;;;\n08D9;ARABIC SMALL LOW NOON WITH KASRA;Mn;230;NSM;;;;;N;;;;;\n08DA;ARABIC SMALL HIGH WORD ATH-THALATHA;Mn;230;NSM;;;;;N;;;;;\n08DB;ARABIC SMALL HIGH WORD AS-SAJDA;Mn;230;NSM;;;;;N;;;;;\n08DC;ARABIC SMALL HIGH WORD AN-NISF;Mn;230;NSM;;;;;N;;;;;\n08DD;ARABIC SMALL HIGH WORD SAKTA;Mn;230;NSM;;;;;N;;;;;\n08DE;ARABIC SMALL HIGH WORD QIF;Mn;230;NSM;;;;;N;;;;;\n08DF;ARABIC SMALL HIGH WORD WAQFA;Mn;230;NSM;;;;;N;;;;;\n08E0;ARABIC SMALL HIGH FOOTNOTE MARKER;Mn;230;NSM;;;;;N;;;;;\n08E1;ARABIC SMALL HIGH SIGN SAFHA;Mn;230;NSM;;;;;N;;;;;\n08E2;ARABIC DISPUTED END OF AYAH;Cf;0;AN;;;;;N;;;;;\n08E3;ARABIC TURNED DAMMA BELOW;Mn;220;NSM;;;;;N;;;;;\n08E4;ARABIC CURLY FATHA;Mn;230;NSM;;;;;N;;;;;\n08E5;ARABIC CURLY DAMMA;Mn;230;NSM;;;;;N;;;;;\n08E6;ARABIC CURLY KASRA;Mn;220;NSM;;;;;N;;;;;\n08E7;ARABIC CURLY FATHATAN;Mn;230;NSM;;;;;N;;;;;\n08E8;ARABIC CURLY DAMMATAN;Mn;230;NSM;;;;;N;;;;;\n08E9;ARABIC CURLY KASRATAN;Mn;220;NSM;;;;;N;;;;;\n08EA;ARABIC TONE ONE DOT ABOVE;Mn;230;NSM;;;;;N;;;;;\n08EB;ARABIC TONE TWO DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;\n08EC;ARABIC TONE LOOP ABOVE;Mn;230;NSM;;;;;N;;;;;\n08ED;ARABIC TONE ONE DOT BELOW;Mn;220;NSM;;;;;N;;;;;\n08EE;ARABIC TONE TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;;\n08EF;ARABIC TONE LOOP BELOW;Mn;220;NSM;;;;;N;;;;;\n08F0;ARABIC OPEN FATHATAN;Mn;27;NSM;;;;;N;;;;;\n08F1;ARABIC OPEN DAMMATAN;Mn;28;NSM;;;;;N;;;;;\n08F2;ARABIC OPEN KASRATAN;Mn;29;NSM;;;;;N;;;;;\n08F3;ARABIC SMALL HIGH WAW;Mn;230;NSM;;;;;N;;;;;\n08F4;ARABIC FATHA WITH RING;Mn;230;NSM;;;;;N;;;;;\n08F5;ARABIC FATHA WITH DOT ABOVE;Mn;230;NSM;;;;;N;;;;;\n08F6;ARABIC KASRA WITH DOT BELOW;Mn;220;NSM;;;;;N;;;;;\n08F7;ARABIC LEFT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;\n08F8;ARABIC RIGHT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;\n08F9;ARABIC LEFT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;\n08FA;ARABIC RIGHT ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;\n08FB;ARABIC DOUBLE RIGHT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;\n08FC;ARABIC DOUBLE RIGHT ARROWHEAD ABOVE WITH DOT;Mn;230;NSM;;;;;N;;;;;\n08FD;ARABIC RIGHT ARROWHEAD ABOVE WITH DOT;Mn;230;NSM;;;;;N;;;;;\n08FE;ARABIC DAMMA WITH DOT;Mn;230;NSM;;;;;N;;;;;\n08FF;ARABIC MARK SIDEWAYS NOON GHUNNA;Mn;230;NSM;;;;;N;;;;;\n0900;DEVANAGARI SIGN INVERTED CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n0901;DEVANAGARI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n0902;DEVANAGARI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n0903;DEVANAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n0904;DEVANAGARI LETTER SHORT A;Lo;0;L;;;;;N;;;;;\n0905;DEVANAGARI LETTER A;Lo;0;L;;;;;N;;;;;\n0906;DEVANAGARI LETTER AA;Lo;0;L;;;;;N;;;;;\n0907;DEVANAGARI LETTER I;Lo;0;L;;;;;N;;;;;\n0908;DEVANAGARI LETTER II;Lo;0;L;;;;;N;;;;;\n0909;DEVANAGARI LETTER U;Lo;0;L;;;;;N;;;;;\n090A;DEVANAGARI LETTER UU;Lo;0;L;;;;;N;;;;;\n090B;DEVANAGARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n090C;DEVANAGARI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n090D;DEVANAGARI LETTER CANDRA E;Lo;0;L;;;;;N;;;;;\n090E;DEVANAGARI LETTER SHORT E;Lo;0;L;;;;;N;;;;;\n090F;DEVANAGARI LETTER E;Lo;0;L;;;;;N;;;;;\n0910;DEVANAGARI LETTER AI;Lo;0;L;;;;;N;;;;;\n0911;DEVANAGARI LETTER CANDRA O;Lo;0;L;;;;;N;;;;;\n0912;DEVANAGARI LETTER SHORT O;Lo;0;L;;;;;N;;;;;\n0913;DEVANAGARI LETTER O;Lo;0;L;;;;;N;;;;;\n0914;DEVANAGARI LETTER AU;Lo;0;L;;;;;N;;;;;\n0915;DEVANAGARI LETTER KA;Lo;0;L;;;;;N;;;;;\n0916;DEVANAGARI LETTER KHA;Lo;0;L;;;;;N;;;;;\n0917;DEVANAGARI LETTER GA;Lo;0;L;;;;;N;;;;;\n0918;DEVANAGARI LETTER GHA;Lo;0;L;;;;;N;;;;;\n0919;DEVANAGARI LETTER NGA;Lo;0;L;;;;;N;;;;;\n091A;DEVANAGARI LETTER CA;Lo;0;L;;;;;N;;;;;\n091B;DEVANAGARI LETTER CHA;Lo;0;L;;;;;N;;;;;\n091C;DEVANAGARI LETTER JA;Lo;0;L;;;;;N;;;;;\n091D;DEVANAGARI LETTER JHA;Lo;0;L;;;;;N;;;;;\n091E;DEVANAGARI LETTER NYA;Lo;0;L;;;;;N;;;;;\n091F;DEVANAGARI LETTER TTA;Lo;0;L;;;;;N;;;;;\n0920;DEVANAGARI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n0921;DEVANAGARI LETTER DDA;Lo;0;L;;;;;N;;;;;\n0922;DEVANAGARI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n0923;DEVANAGARI LETTER NNA;Lo;0;L;;;;;N;;;;;\n0924;DEVANAGARI LETTER TA;Lo;0;L;;;;;N;;;;;\n0925;DEVANAGARI LETTER THA;Lo;0;L;;;;;N;;;;;\n0926;DEVANAGARI LETTER DA;Lo;0;L;;;;;N;;;;;\n0927;DEVANAGARI LETTER DHA;Lo;0;L;;;;;N;;;;;\n0928;DEVANAGARI LETTER NA;Lo;0;L;;;;;N;;;;;\n0929;DEVANAGARI LETTER NNNA;Lo;0;L;0928 093C;;;;N;;;;;\n092A;DEVANAGARI LETTER PA;Lo;0;L;;;;;N;;;;;\n092B;DEVANAGARI LETTER PHA;Lo;0;L;;;;;N;;;;;\n092C;DEVANAGARI LETTER BA;Lo;0;L;;;;;N;;;;;\n092D;DEVANAGARI LETTER BHA;Lo;0;L;;;;;N;;;;;\n092E;DEVANAGARI LETTER MA;Lo;0;L;;;;;N;;;;;\n092F;DEVANAGARI LETTER YA;Lo;0;L;;;;;N;;;;;\n0930;DEVANAGARI LETTER RA;Lo;0;L;;;;;N;;;;;\n0931;DEVANAGARI LETTER RRA;Lo;0;L;0930 093C;;;;N;;;;;\n0932;DEVANAGARI LETTER LA;Lo;0;L;;;;;N;;;;;\n0933;DEVANAGARI LETTER LLA;Lo;0;L;;;;;N;;;;;\n0934;DEVANAGARI LETTER LLLA;Lo;0;L;0933 093C;;;;N;;;;;\n0935;DEVANAGARI LETTER VA;Lo;0;L;;;;;N;;;;;\n0936;DEVANAGARI LETTER SHA;Lo;0;L;;;;;N;;;;;\n0937;DEVANAGARI LETTER SSA;Lo;0;L;;;;;N;;;;;\n0938;DEVANAGARI LETTER SA;Lo;0;L;;;;;N;;;;;\n0939;DEVANAGARI LETTER HA;Lo;0;L;;;;;N;;;;;\n093A;DEVANAGARI VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;;\n093B;DEVANAGARI VOWEL SIGN OOE;Mc;0;L;;;;;N;;;;;\n093C;DEVANAGARI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n093D;DEVANAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;\n093E;DEVANAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n093F;DEVANAGARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n0940;DEVANAGARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n0941;DEVANAGARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n0942;DEVANAGARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n0943;DEVANAGARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n0944;DEVANAGARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;\n0945;DEVANAGARI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;;\n0946;DEVANAGARI VOWEL SIGN SHORT E;Mn;0;NSM;;;;;N;;;;;\n0947;DEVANAGARI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n0948;DEVANAGARI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n0949;DEVANAGARI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;;\n094A;DEVANAGARI VOWEL SIGN SHORT O;Mc;0;L;;;;;N;;;;;\n094B;DEVANAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;\n094C;DEVANAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;\n094D;DEVANAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n094E;DEVANAGARI VOWEL SIGN PRISHTHAMATRA E;Mc;0;L;;;;;N;;;;;\n094F;DEVANAGARI VOWEL SIGN AW;Mc;0;L;;;;;N;;;;;\n0950;DEVANAGARI OM;Lo;0;L;;;;;N;;;;;\n0951;DEVANAGARI STRESS SIGN UDATTA;Mn;230;NSM;;;;;N;;;;;\n0952;DEVANAGARI STRESS SIGN ANUDATTA;Mn;220;NSM;;;;;N;;;;;\n0953;DEVANAGARI GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;;\n0954;DEVANAGARI ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;;\n0955;DEVANAGARI VOWEL SIGN CANDRA LONG E;Mn;0;NSM;;;;;N;;;;;\n0956;DEVANAGARI VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;\n0957;DEVANAGARI VOWEL SIGN UUE;Mn;0;NSM;;;;;N;;;;;\n0958;DEVANAGARI LETTER QA;Lo;0;L;0915 093C;;;;N;;;;;\n0959;DEVANAGARI LETTER KHHA;Lo;0;L;0916 093C;;;;N;;;;;\n095A;DEVANAGARI LETTER GHHA;Lo;0;L;0917 093C;;;;N;;;;;\n095B;DEVANAGARI LETTER ZA;Lo;0;L;091C 093C;;;;N;;;;;\n095C;DEVANAGARI LETTER DDDHA;Lo;0;L;0921 093C;;;;N;;;;;\n095D;DEVANAGARI LETTER RHA;Lo;0;L;0922 093C;;;;N;;;;;\n095E;DEVANAGARI LETTER FA;Lo;0;L;092B 093C;;;;N;;;;;\n095F;DEVANAGARI LETTER YYA;Lo;0;L;092F 093C;;;;N;;;;;\n0960;DEVANAGARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n0961;DEVANAGARI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\n0962;DEVANAGARI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;\n0963;DEVANAGARI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;\n0964;DEVANAGARI DANDA;Po;0;L;;;;;N;;;;;\n0965;DEVANAGARI DOUBLE DANDA;Po;0;L;;;;;N;;;;;\n0966;DEVANAGARI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n0967;DEVANAGARI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n0968;DEVANAGARI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n0969;DEVANAGARI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n096A;DEVANAGARI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n096B;DEVANAGARI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n096C;DEVANAGARI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n096D;DEVANAGARI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n096E;DEVANAGARI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n096F;DEVANAGARI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n0970;DEVANAGARI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;\n0971;DEVANAGARI SIGN HIGH SPACING DOT;Lm;0;L;;;;;N;;;;;\n0972;DEVANAGARI LETTER CANDRA A;Lo;0;L;;;;;N;;;;;\n0973;DEVANAGARI LETTER OE;Lo;0;L;;;;;N;;;;;\n0974;DEVANAGARI LETTER OOE;Lo;0;L;;;;;N;;;;;\n0975;DEVANAGARI LETTER AW;Lo;0;L;;;;;N;;;;;\n0976;DEVANAGARI LETTER UE;Lo;0;L;;;;;N;;;;;\n0977;DEVANAGARI LETTER UUE;Lo;0;L;;;;;N;;;;;\n0978;DEVANAGARI LETTER MARWARI DDA;Lo;0;L;;;;;N;;;;;\n0979;DEVANAGARI LETTER ZHA;Lo;0;L;;;;;N;;;;;\n097A;DEVANAGARI LETTER HEAVY YA;Lo;0;L;;;;;N;;;;;\n097B;DEVANAGARI LETTER GGA;Lo;0;L;;;;;N;;;;;\n097C;DEVANAGARI LETTER JJA;Lo;0;L;;;;;N;;;;;\n097D;DEVANAGARI LETTER GLOTTAL STOP;Lo;0;L;;;;;N;;;;;\n097E;DEVANAGARI LETTER DDDA;Lo;0;L;;;;;N;;;;;\n097F;DEVANAGARI LETTER BBA;Lo;0;L;;;;;N;;;;;\n0980;BENGALI ANJI;Lo;0;L;;;;;N;;;;;\n0981;BENGALI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n0982;BENGALI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;\n0983;BENGALI SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n0985;BENGALI LETTER A;Lo;0;L;;;;;N;;;;;\n0986;BENGALI LETTER AA;Lo;0;L;;;;;N;;;;;\n0987;BENGALI LETTER I;Lo;0;L;;;;;N;;;;;\n0988;BENGALI LETTER II;Lo;0;L;;;;;N;;;;;\n0989;BENGALI LETTER U;Lo;0;L;;;;;N;;;;;\n098A;BENGALI LETTER UU;Lo;0;L;;;;;N;;;;;\n098B;BENGALI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n098C;BENGALI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n098F;BENGALI LETTER E;Lo;0;L;;;;;N;;;;;\n0990;BENGALI LETTER AI;Lo;0;L;;;;;N;;;;;\n0993;BENGALI LETTER O;Lo;0;L;;;;;N;;;;;\n0994;BENGALI LETTER AU;Lo;0;L;;;;;N;;;;;\n0995;BENGALI LETTER KA;Lo;0;L;;;;;N;;;;;\n0996;BENGALI LETTER KHA;Lo;0;L;;;;;N;;;;;\n0997;BENGALI LETTER GA;Lo;0;L;;;;;N;;;;;\n0998;BENGALI LETTER GHA;Lo;0;L;;;;;N;;;;;\n0999;BENGALI LETTER NGA;Lo;0;L;;;;;N;;;;;\n099A;BENGALI LETTER CA;Lo;0;L;;;;;N;;;;;\n099B;BENGALI LETTER CHA;Lo;0;L;;;;;N;;;;;\n099C;BENGALI LETTER JA;Lo;0;L;;;;;N;;;;;\n099D;BENGALI LETTER JHA;Lo;0;L;;;;;N;;;;;\n099E;BENGALI LETTER NYA;Lo;0;L;;;;;N;;;;;\n099F;BENGALI LETTER TTA;Lo;0;L;;;;;N;;;;;\n09A0;BENGALI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n09A1;BENGALI LETTER DDA;Lo;0;L;;;;;N;;;;;\n09A2;BENGALI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n09A3;BENGALI LETTER NNA;Lo;0;L;;;;;N;;;;;\n09A4;BENGALI LETTER TA;Lo;0;L;;;;;N;;;;;\n09A5;BENGALI LETTER THA;Lo;0;L;;;;;N;;;;;\n09A6;BENGALI LETTER DA;Lo;0;L;;;;;N;;;;;\n09A7;BENGALI LETTER DHA;Lo;0;L;;;;;N;;;;;\n09A8;BENGALI LETTER NA;Lo;0;L;;;;;N;;;;;\n09AA;BENGALI LETTER PA;Lo;0;L;;;;;N;;;;;\n09AB;BENGALI LETTER PHA;Lo;0;L;;;;;N;;;;;\n09AC;BENGALI LETTER BA;Lo;0;L;;;;;N;;;;;\n09AD;BENGALI LETTER BHA;Lo;0;L;;;;;N;;;;;\n09AE;BENGALI LETTER MA;Lo;0;L;;;;;N;;;;;\n09AF;BENGALI LETTER YA;Lo;0;L;;;;;N;;;;;\n09B0;BENGALI LETTER RA;Lo;0;L;;;;;N;;;;;\n09B2;BENGALI LETTER LA;Lo;0;L;;;;;N;;;;;\n09B6;BENGALI LETTER SHA;Lo;0;L;;;;;N;;;;;\n09B7;BENGALI LETTER SSA;Lo;0;L;;;;;N;;;;;\n09B8;BENGALI LETTER SA;Lo;0;L;;;;;N;;;;;\n09B9;BENGALI LETTER HA;Lo;0;L;;;;;N;;;;;\n09BC;BENGALI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n09BD;BENGALI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;\n09BE;BENGALI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n09BF;BENGALI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n09C0;BENGALI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n09C1;BENGALI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n09C2;BENGALI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n09C3;BENGALI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n09C4;BENGALI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;\n09C7;BENGALI VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\n09C8;BENGALI VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;\n09CB;BENGALI VOWEL SIGN O;Mc;0;L;09C7 09BE;;;;N;;;;;\n09CC;BENGALI VOWEL SIGN AU;Mc;0;L;09C7 09D7;;;;N;;;;;\n09CD;BENGALI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n09CE;BENGALI LETTER KHANDA TA;Lo;0;L;;;;;N;;;;;\n09D7;BENGALI AU LENGTH MARK;Mc;0;L;;;;;N;;;;;\n09DC;BENGALI LETTER RRA;Lo;0;L;09A1 09BC;;;;N;;;;;\n09DD;BENGALI LETTER RHA;Lo;0;L;09A2 09BC;;;;N;;;;;\n09DF;BENGALI LETTER YYA;Lo;0;L;09AF 09BC;;;;N;;;;;\n09E0;BENGALI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n09E1;BENGALI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\n09E2;BENGALI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;\n09E3;BENGALI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;\n09E6;BENGALI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n09E7;BENGALI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n09E8;BENGALI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n09E9;BENGALI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n09EA;BENGALI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n09EB;BENGALI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n09EC;BENGALI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n09ED;BENGALI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n09EE;BENGALI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n09EF;BENGALI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n09F0;BENGALI LETTER RA WITH MIDDLE DIAGONAL;Lo;0;L;;;;;N;;;;;\n09F1;BENGALI LETTER RA WITH LOWER DIAGONAL;Lo;0;L;;;;;N;BENGALI LETTER VA WITH LOWER DIAGONAL;;;;\n09F2;BENGALI RUPEE MARK;Sc;0;ET;;;;;N;;;;;\n09F3;BENGALI RUPEE SIGN;Sc;0;ET;;;;;N;;;;;\n09F4;BENGALI CURRENCY NUMERATOR ONE;No;0;L;;;;1/16;N;;;;;\n09F5;BENGALI CURRENCY NUMERATOR TWO;No;0;L;;;;1/8;N;;;;;\n09F6;BENGALI CURRENCY NUMERATOR THREE;No;0;L;;;;3/16;N;;;;;\n09F7;BENGALI CURRENCY NUMERATOR FOUR;No;0;L;;;;1/4;N;;;;;\n09F8;BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR;No;0;L;;;;3/4;N;;;;;\n09F9;BENGALI CURRENCY DENOMINATOR SIXTEEN;No;0;L;;;;16;N;;;;;\n09FA;BENGALI ISSHAR;So;0;L;;;;;N;;;;;\n09FB;BENGALI GANDA MARK;Sc;0;ET;;;;;N;;;;;\n09FC;BENGALI LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;;\n09FD;BENGALI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;\n09FE;BENGALI SANDHI MARK;Mn;230;NSM;;;;;N;;;;;\n0A01;GURMUKHI SIGN ADAK BINDI;Mn;0;NSM;;;;;N;;;;;\n0A02;GURMUKHI SIGN BINDI;Mn;0;NSM;;;;;N;;;;;\n0A03;GURMUKHI SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n0A05;GURMUKHI LETTER A;Lo;0;L;;;;;N;;;;;\n0A06;GURMUKHI LETTER AA;Lo;0;L;;;;;N;;;;;\n0A07;GURMUKHI LETTER I;Lo;0;L;;;;;N;;;;;\n0A08;GURMUKHI LETTER II;Lo;0;L;;;;;N;;;;;\n0A09;GURMUKHI LETTER U;Lo;0;L;;;;;N;;;;;\n0A0A;GURMUKHI LETTER UU;Lo;0;L;;;;;N;;;;;\n0A0F;GURMUKHI LETTER EE;Lo;0;L;;;;;N;;;;;\n0A10;GURMUKHI LETTER AI;Lo;0;L;;;;;N;;;;;\n0A13;GURMUKHI LETTER OO;Lo;0;L;;;;;N;;;;;\n0A14;GURMUKHI LETTER AU;Lo;0;L;;;;;N;;;;;\n0A15;GURMUKHI LETTER KA;Lo;0;L;;;;;N;;;;;\n0A16;GURMUKHI LETTER KHA;Lo;0;L;;;;;N;;;;;\n0A17;GURMUKHI LETTER GA;Lo;0;L;;;;;N;;;;;\n0A18;GURMUKHI LETTER GHA;Lo;0;L;;;;;N;;;;;\n0A19;GURMUKHI LETTER NGA;Lo;0;L;;;;;N;;;;;\n0A1A;GURMUKHI LETTER CA;Lo;0;L;;;;;N;;;;;\n0A1B;GURMUKHI LETTER CHA;Lo;0;L;;;;;N;;;;;\n0A1C;GURMUKHI LETTER JA;Lo;0;L;;;;;N;;;;;\n0A1D;GURMUKHI LETTER JHA;Lo;0;L;;;;;N;;;;;\n0A1E;GURMUKHI LETTER NYA;Lo;0;L;;;;;N;;;;;\n0A1F;GURMUKHI LETTER TTA;Lo;0;L;;;;;N;;;;;\n0A20;GURMUKHI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n0A21;GURMUKHI LETTER DDA;Lo;0;L;;;;;N;;;;;\n0A22;GURMUKHI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n0A23;GURMUKHI LETTER NNA;Lo;0;L;;;;;N;;;;;\n0A24;GURMUKHI LETTER TA;Lo;0;L;;;;;N;;;;;\n0A25;GURMUKHI LETTER THA;Lo;0;L;;;;;N;;;;;\n0A26;GURMUKHI LETTER DA;Lo;0;L;;;;;N;;;;;\n0A27;GURMUKHI LETTER DHA;Lo;0;L;;;;;N;;;;;\n0A28;GURMUKHI LETTER NA;Lo;0;L;;;;;N;;;;;\n0A2A;GURMUKHI LETTER PA;Lo;0;L;;;;;N;;;;;\n0A2B;GURMUKHI LETTER PHA;Lo;0;L;;;;;N;;;;;\n0A2C;GURMUKHI LETTER BA;Lo;0;L;;;;;N;;;;;\n0A2D;GURMUKHI LETTER BHA;Lo;0;L;;;;;N;;;;;\n0A2E;GURMUKHI LETTER MA;Lo;0;L;;;;;N;;;;;\n0A2F;GURMUKHI LETTER YA;Lo;0;L;;;;;N;;;;;\n0A30;GURMUKHI LETTER RA;Lo;0;L;;;;;N;;;;;\n0A32;GURMUKHI LETTER LA;Lo;0;L;;;;;N;;;;;\n0A33;GURMUKHI LETTER LLA;Lo;0;L;0A32 0A3C;;;;N;;;;;\n0A35;GURMUKHI LETTER VA;Lo;0;L;;;;;N;;;;;\n0A36;GURMUKHI LETTER SHA;Lo;0;L;0A38 0A3C;;;;N;;;;;\n0A38;GURMUKHI LETTER SA;Lo;0;L;;;;;N;;;;;\n0A39;GURMUKHI LETTER HA;Lo;0;L;;;;;N;;;;;\n0A3C;GURMUKHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n0A3E;GURMUKHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n0A3F;GURMUKHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n0A40;GURMUKHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n0A41;GURMUKHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n0A42;GURMUKHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n0A47;GURMUKHI VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;;\n0A48;GURMUKHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n0A4B;GURMUKHI VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;;\n0A4C;GURMUKHI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;\n0A4D;GURMUKHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n0A51;GURMUKHI SIGN UDAAT;Mn;0;NSM;;;;;N;;;;;\n0A59;GURMUKHI LETTER KHHA;Lo;0;L;0A16 0A3C;;;;N;;;;;\n0A5A;GURMUKHI LETTER GHHA;Lo;0;L;0A17 0A3C;;;;N;;;;;\n0A5B;GURMUKHI LETTER ZA;Lo;0;L;0A1C 0A3C;;;;N;;;;;\n0A5C;GURMUKHI LETTER RRA;Lo;0;L;;;;;N;;;;;\n0A5E;GURMUKHI LETTER FA;Lo;0;L;0A2B 0A3C;;;;N;;;;;\n0A66;GURMUKHI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n0A67;GURMUKHI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n0A68;GURMUKHI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n0A69;GURMUKHI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n0A6A;GURMUKHI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n0A6B;GURMUKHI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n0A6C;GURMUKHI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n0A6D;GURMUKHI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n0A6E;GURMUKHI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n0A6F;GURMUKHI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n0A70;GURMUKHI TIPPI;Mn;0;NSM;;;;;N;;;;;\n0A71;GURMUKHI ADDAK;Mn;0;NSM;;;;;N;;;;;\n0A72;GURMUKHI IRI;Lo;0;L;;;;;N;;;;;\n0A73;GURMUKHI URA;Lo;0;L;;;;;N;;;;;\n0A74;GURMUKHI EK ONKAR;Lo;0;L;;;;;N;;;;;\n0A75;GURMUKHI SIGN YAKASH;Mn;0;NSM;;;;;N;;;;;\n0A76;GURMUKHI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;\n0A81;GUJARATI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n0A82;GUJARATI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n0A83;GUJARATI SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n0A85;GUJARATI LETTER A;Lo;0;L;;;;;N;;;;;\n0A86;GUJARATI LETTER AA;Lo;0;L;;;;;N;;;;;\n0A87;GUJARATI LETTER I;Lo;0;L;;;;;N;;;;;\n0A88;GUJARATI LETTER II;Lo;0;L;;;;;N;;;;;\n0A89;GUJARATI LETTER U;Lo;0;L;;;;;N;;;;;\n0A8A;GUJARATI LETTER UU;Lo;0;L;;;;;N;;;;;\n0A8B;GUJARATI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n0A8C;GUJARATI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n0A8D;GUJARATI VOWEL CANDRA E;Lo;0;L;;;;;N;;;;;\n0A8F;GUJARATI LETTER E;Lo;0;L;;;;;N;;;;;\n0A90;GUJARATI LETTER AI;Lo;0;L;;;;;N;;;;;\n0A91;GUJARATI VOWEL CANDRA O;Lo;0;L;;;;;N;;;;;\n0A93;GUJARATI LETTER O;Lo;0;L;;;;;N;;;;;\n0A94;GUJARATI LETTER AU;Lo;0;L;;;;;N;;;;;\n0A95;GUJARATI LETTER KA;Lo;0;L;;;;;N;;;;;\n0A96;GUJARATI LETTER KHA;Lo;0;L;;;;;N;;;;;\n0A97;GUJARATI LETTER GA;Lo;0;L;;;;;N;;;;;\n0A98;GUJARATI LETTER GHA;Lo;0;L;;;;;N;;;;;\n0A99;GUJARATI LETTER NGA;Lo;0;L;;;;;N;;;;;\n0A9A;GUJARATI LETTER CA;Lo;0;L;;;;;N;;;;;\n0A9B;GUJARATI LETTER CHA;Lo;0;L;;;;;N;;;;;\n0A9C;GUJARATI LETTER JA;Lo;0;L;;;;;N;;;;;\n0A9D;GUJARATI LETTER JHA;Lo;0;L;;;;;N;;;;;\n0A9E;GUJARATI LETTER NYA;Lo;0;L;;;;;N;;;;;\n0A9F;GUJARATI LETTER TTA;Lo;0;L;;;;;N;;;;;\n0AA0;GUJARATI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n0AA1;GUJARATI LETTER DDA;Lo;0;L;;;;;N;;;;;\n0AA2;GUJARATI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n0AA3;GUJARATI LETTER NNA;Lo;0;L;;;;;N;;;;;\n0AA4;GUJARATI LETTER TA;Lo;0;L;;;;;N;;;;;\n0AA5;GUJARATI LETTER THA;Lo;0;L;;;;;N;;;;;\n0AA6;GUJARATI LETTER DA;Lo;0;L;;;;;N;;;;;\n0AA7;GUJARATI LETTER DHA;Lo;0;L;;;;;N;;;;;\n0AA8;GUJARATI LETTER NA;Lo;0;L;;;;;N;;;;;\n0AAA;GUJARATI LETTER PA;Lo;0;L;;;;;N;;;;;\n0AAB;GUJARATI LETTER PHA;Lo;0;L;;;;;N;;;;;\n0AAC;GUJARATI LETTER BA;Lo;0;L;;;;;N;;;;;\n0AAD;GUJARATI LETTER BHA;Lo;0;L;;;;;N;;;;;\n0AAE;GUJARATI LETTER MA;Lo;0;L;;;;;N;;;;;\n0AAF;GUJARATI LETTER YA;Lo;0;L;;;;;N;;;;;\n0AB0;GUJARATI LETTER RA;Lo;0;L;;;;;N;;;;;\n0AB2;GUJARATI LETTER LA;Lo;0;L;;;;;N;;;;;\n0AB3;GUJARATI LETTER LLA;Lo;0;L;;;;;N;;;;;\n0AB5;GUJARATI LETTER VA;Lo;0;L;;;;;N;;;;;\n0AB6;GUJARATI LETTER SHA;Lo;0;L;;;;;N;;;;;\n0AB7;GUJARATI LETTER SSA;Lo;0;L;;;;;N;;;;;\n0AB8;GUJARATI LETTER SA;Lo;0;L;;;;;N;;;;;\n0AB9;GUJARATI LETTER HA;Lo;0;L;;;;;N;;;;;\n0ABC;GUJARATI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n0ABD;GUJARATI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;\n0ABE;GUJARATI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n0ABF;GUJARATI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n0AC0;GUJARATI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n0AC1;GUJARATI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n0AC2;GUJARATI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n0AC3;GUJARATI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n0AC4;GUJARATI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;\n0AC5;GUJARATI VOWEL SIGN CANDRA E;Mn;0;NSM;;;;;N;;;;;\n0AC7;GUJARATI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n0AC8;GUJARATI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n0AC9;GUJARATI VOWEL SIGN CANDRA O;Mc;0;L;;;;;N;;;;;\n0ACB;GUJARATI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;\n0ACC;GUJARATI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;\n0ACD;GUJARATI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n0AD0;GUJARATI OM;Lo;0;L;;;;;N;;;;;\n0AE0;GUJARATI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n0AE1;GUJARATI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\n0AE2;GUJARATI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;\n0AE3;GUJARATI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;\n0AE6;GUJARATI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n0AE7;GUJARATI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n0AE8;GUJARATI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n0AE9;GUJARATI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n0AEA;GUJARATI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n0AEB;GUJARATI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n0AEC;GUJARATI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n0AED;GUJARATI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n0AEE;GUJARATI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n0AEF;GUJARATI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n0AF0;GUJARATI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;\n0AF1;GUJARATI RUPEE SIGN;Sc;0;ET;;;;;N;;;;;\n0AF9;GUJARATI LETTER ZHA;Lo;0;L;;;;;N;;;;;\n0AFA;GUJARATI SIGN SUKUN;Mn;0;NSM;;;;;N;;;;;\n0AFB;GUJARATI SIGN SHADDA;Mn;0;NSM;;;;;N;;;;;\n0AFC;GUJARATI SIGN MADDAH;Mn;0;NSM;;;;;N;;;;;\n0AFD;GUJARATI SIGN THREE-DOT NUKTA ABOVE;Mn;0;NSM;;;;;N;;;;;\n0AFE;GUJARATI SIGN CIRCLE NUKTA ABOVE;Mn;0;NSM;;;;;N;;;;;\n0AFF;GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE;Mn;0;NSM;;;;;N;;;;;\n0B01;ORIYA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n0B02;ORIYA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;\n0B03;ORIYA SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n0B05;ORIYA LETTER A;Lo;0;L;;;;;N;;;;;\n0B06;ORIYA LETTER AA;Lo;0;L;;;;;N;;;;;\n0B07;ORIYA LETTER I;Lo;0;L;;;;;N;;;;;\n0B08;ORIYA LETTER II;Lo;0;L;;;;;N;;;;;\n0B09;ORIYA LETTER U;Lo;0;L;;;;;N;;;;;\n0B0A;ORIYA LETTER UU;Lo;0;L;;;;;N;;;;;\n0B0B;ORIYA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n0B0C;ORIYA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n0B0F;ORIYA LETTER E;Lo;0;L;;;;;N;;;;;\n0B10;ORIYA LETTER AI;Lo;0;L;;;;;N;;;;;\n0B13;ORIYA LETTER O;Lo;0;L;;;;;N;;;;;\n0B14;ORIYA LETTER AU;Lo;0;L;;;;;N;;;;;\n0B15;ORIYA LETTER KA;Lo;0;L;;;;;N;;;;;\n0B16;ORIYA LETTER KHA;Lo;0;L;;;;;N;;;;;\n0B17;ORIYA LETTER GA;Lo;0;L;;;;;N;;;;;\n0B18;ORIYA LETTER GHA;Lo;0;L;;;;;N;;;;;\n0B19;ORIYA LETTER NGA;Lo;0;L;;;;;N;;;;;\n0B1A;ORIYA LETTER CA;Lo;0;L;;;;;N;;;;;\n0B1B;ORIYA LETTER CHA;Lo;0;L;;;;;N;;;;;\n0B1C;ORIYA LETTER JA;Lo;0;L;;;;;N;;;;;\n0B1D;ORIYA LETTER JHA;Lo;0;L;;;;;N;;;;;\n0B1E;ORIYA LETTER NYA;Lo;0;L;;;;;N;;;;;\n0B1F;ORIYA LETTER TTA;Lo;0;L;;;;;N;;;;;\n0B20;ORIYA LETTER TTHA;Lo;0;L;;;;;N;;;;;\n0B21;ORIYA LETTER DDA;Lo;0;L;;;;;N;;;;;\n0B22;ORIYA LETTER DDHA;Lo;0;L;;;;;N;;;;;\n0B23;ORIYA LETTER NNA;Lo;0;L;;;;;N;;;;;\n0B24;ORIYA LETTER TA;Lo;0;L;;;;;N;;;;;\n0B25;ORIYA LETTER THA;Lo;0;L;;;;;N;;;;;\n0B26;ORIYA LETTER DA;Lo;0;L;;;;;N;;;;;\n0B27;ORIYA LETTER DHA;Lo;0;L;;;;;N;;;;;\n0B28;ORIYA LETTER NA;Lo;0;L;;;;;N;;;;;\n0B2A;ORIYA LETTER PA;Lo;0;L;;;;;N;;;;;\n0B2B;ORIYA LETTER PHA;Lo;0;L;;;;;N;;;;;\n0B2C;ORIYA LETTER BA;Lo;0;L;;;;;N;;;;;\n0B2D;ORIYA LETTER BHA;Lo;0;L;;;;;N;;;;;\n0B2E;ORIYA LETTER MA;Lo;0;L;;;;;N;;;;;\n0B2F;ORIYA LETTER YA;Lo;0;L;;;;;N;;;;;\n0B30;ORIYA LETTER RA;Lo;0;L;;;;;N;;;;;\n0B32;ORIYA LETTER LA;Lo;0;L;;;;;N;;;;;\n0B33;ORIYA LETTER LLA;Lo;0;L;;;;;N;;;;;\n0B35;ORIYA LETTER VA;Lo;0;L;;;;;N;;;;;\n0B36;ORIYA LETTER SHA;Lo;0;L;;;;;N;;;;;\n0B37;ORIYA LETTER SSA;Lo;0;L;;;;;N;;;;;\n0B38;ORIYA LETTER SA;Lo;0;L;;;;;N;;;;;\n0B39;ORIYA LETTER HA;Lo;0;L;;;;;N;;;;;\n0B3C;ORIYA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n0B3D;ORIYA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;\n0B3E;ORIYA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n0B3F;ORIYA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n0B40;ORIYA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n0B41;ORIYA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n0B42;ORIYA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n0B43;ORIYA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n0B44;ORIYA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;\n0B47;ORIYA VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\n0B48;ORIYA VOWEL SIGN AI;Mc;0;L;0B47 0B56;;;;N;;;;;\n0B4B;ORIYA VOWEL SIGN O;Mc;0;L;0B47 0B3E;;;;N;;;;;\n0B4C;ORIYA VOWEL SIGN AU;Mc;0;L;0B47 0B57;;;;N;;;;;\n0B4D;ORIYA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n0B56;ORIYA AI LENGTH MARK;Mn;0;NSM;;;;;N;;;;;\n0B57;ORIYA AU LENGTH MARK;Mc;0;L;;;;;N;;;;;\n0B5C;ORIYA LETTER RRA;Lo;0;L;0B21 0B3C;;;;N;;;;;\n0B5D;ORIYA LETTER RHA;Lo;0;L;0B22 0B3C;;;;N;;;;;\n0B5F;ORIYA LETTER YYA;Lo;0;L;;;;;N;;;;;\n0B60;ORIYA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n0B61;ORIYA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\n0B62;ORIYA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;\n0B63;ORIYA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;\n0B66;ORIYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n0B67;ORIYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n0B68;ORIYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n0B69;ORIYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n0B6A;ORIYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n0B6B;ORIYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n0B6C;ORIYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n0B6D;ORIYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n0B6E;ORIYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n0B6F;ORIYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n0B70;ORIYA ISSHAR;So;0;L;;;;;N;;;;;\n0B71;ORIYA LETTER WA;Lo;0;L;;;;;N;;;;;\n0B72;ORIYA FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;;\n0B73;ORIYA FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;;\n0B74;ORIYA FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;;\n0B75;ORIYA FRACTION ONE SIXTEENTH;No;0;L;;;;1/16;N;;;;;\n0B76;ORIYA FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;;\n0B77;ORIYA FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;;\n0B82;TAMIL SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n0B83;TAMIL SIGN VISARGA;Lo;0;L;;;;;N;;;;;\n0B85;TAMIL LETTER A;Lo;0;L;;;;;N;;;;;\n0B86;TAMIL LETTER AA;Lo;0;L;;;;;N;;;;;\n0B87;TAMIL LETTER I;Lo;0;L;;;;;N;;;;;\n0B88;TAMIL LETTER II;Lo;0;L;;;;;N;;;;;\n0B89;TAMIL LETTER U;Lo;0;L;;;;;N;;;;;\n0B8A;TAMIL LETTER UU;Lo;0;L;;;;;N;;;;;\n0B8E;TAMIL LETTER E;Lo;0;L;;;;;N;;;;;\n0B8F;TAMIL LETTER EE;Lo;0;L;;;;;N;;;;;\n0B90;TAMIL LETTER AI;Lo;0;L;;;;;N;;;;;\n0B92;TAMIL LETTER O;Lo;0;L;;;;;N;;;;;\n0B93;TAMIL LETTER OO;Lo;0;L;;;;;N;;;;;\n0B94;TAMIL LETTER AU;Lo;0;L;0B92 0BD7;;;;N;;;;;\n0B95;TAMIL LETTER KA;Lo;0;L;;;;;N;;;;;\n0B99;TAMIL LETTER NGA;Lo;0;L;;;;;N;;;;;\n0B9A;TAMIL LETTER CA;Lo;0;L;;;;;N;;;;;\n0B9C;TAMIL LETTER JA;Lo;0;L;;;;;N;;;;;\n0B9E;TAMIL LETTER NYA;Lo;0;L;;;;;N;;;;;\n0B9F;TAMIL LETTER TTA;Lo;0;L;;;;;N;;;;;\n0BA3;TAMIL LETTER NNA;Lo;0;L;;;;;N;;;;;\n0BA4;TAMIL LETTER TA;Lo;0;L;;;;;N;;;;;\n0BA8;TAMIL LETTER NA;Lo;0;L;;;;;N;;;;;\n0BA9;TAMIL LETTER NNNA;Lo;0;L;;;;;N;;;;;\n0BAA;TAMIL LETTER PA;Lo;0;L;;;;;N;;;;;\n0BAE;TAMIL LETTER MA;Lo;0;L;;;;;N;;;;;\n0BAF;TAMIL LETTER YA;Lo;0;L;;;;;N;;;;;\n0BB0;TAMIL LETTER RA;Lo;0;L;;;;;N;;;;;\n0BB1;TAMIL LETTER RRA;Lo;0;L;;;;;N;;;;;\n0BB2;TAMIL LETTER LA;Lo;0;L;;;;;N;;;;;\n0BB3;TAMIL LETTER LLA;Lo;0;L;;;;;N;;;;;\n0BB4;TAMIL LETTER LLLA;Lo;0;L;;;;;N;;;;;\n0BB5;TAMIL LETTER VA;Lo;0;L;;;;;N;;;;;\n0BB6;TAMIL LETTER SHA;Lo;0;L;;;;;N;;;;;\n0BB7;TAMIL LETTER SSA;Lo;0;L;;;;;N;;;;;\n0BB8;TAMIL LETTER SA;Lo;0;L;;;;;N;;;;;\n0BB9;TAMIL LETTER HA;Lo;0;L;;;;;N;;;;;\n0BBE;TAMIL VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n0BBF;TAMIL VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n0BC0;TAMIL VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;\n0BC1;TAMIL VOWEL SIGN U;Mc;0;L;;;;;N;;;;;\n0BC2;TAMIL VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;\n0BC6;TAMIL VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\n0BC7;TAMIL VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;\n0BC8;TAMIL VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;\n0BCA;TAMIL VOWEL SIGN O;Mc;0;L;0BC6 0BBE;;;;N;;;;;\n0BCB;TAMIL VOWEL SIGN OO;Mc;0;L;0BC7 0BBE;;;;N;;;;;\n0BCC;TAMIL VOWEL SIGN AU;Mc;0;L;0BC6 0BD7;;;;N;;;;;\n0BCD;TAMIL SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n0BD0;TAMIL OM;Lo;0;L;;;;;N;;;;;\n0BD7;TAMIL AU LENGTH MARK;Mc;0;L;;;;;N;;;;;\n0BE6;TAMIL DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n0BE7;TAMIL DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n0BE8;TAMIL DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n0BE9;TAMIL DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n0BEA;TAMIL DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n0BEB;TAMIL DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n0BEC;TAMIL DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n0BED;TAMIL DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n0BEE;TAMIL DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n0BEF;TAMIL DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n0BF0;TAMIL NUMBER TEN;No;0;L;;;;10;N;;;;;\n0BF1;TAMIL NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;\n0BF2;TAMIL NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;\n0BF3;TAMIL DAY SIGN;So;0;ON;;;;;N;;;;;\n0BF4;TAMIL MONTH SIGN;So;0;ON;;;;;N;;;;;\n0BF5;TAMIL YEAR SIGN;So;0;ON;;;;;N;;;;;\n0BF6;TAMIL DEBIT SIGN;So;0;ON;;;;;N;;;;;\n0BF7;TAMIL CREDIT SIGN;So;0;ON;;;;;N;;;;;\n0BF8;TAMIL AS ABOVE SIGN;So;0;ON;;;;;N;;;;;\n0BF9;TAMIL RUPEE SIGN;Sc;0;ET;;;;;N;;;;;\n0BFA;TAMIL NUMBER SIGN;So;0;ON;;;;;N;;;;;\n0C00;TELUGU SIGN COMBINING CANDRABINDU ABOVE;Mn;0;NSM;;;;;N;;;;;\n0C01;TELUGU SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;;\n0C02;TELUGU SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;\n0C03;TELUGU SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n0C04;TELUGU SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;;\n0C05;TELUGU LETTER A;Lo;0;L;;;;;N;;;;;\n0C06;TELUGU LETTER AA;Lo;0;L;;;;;N;;;;;\n0C07;TELUGU LETTER I;Lo;0;L;;;;;N;;;;;\n0C08;TELUGU LETTER II;Lo;0;L;;;;;N;;;;;\n0C09;TELUGU LETTER U;Lo;0;L;;;;;N;;;;;\n0C0A;TELUGU LETTER UU;Lo;0;L;;;;;N;;;;;\n0C0B;TELUGU LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n0C0C;TELUGU LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n0C0E;TELUGU LETTER E;Lo;0;L;;;;;N;;;;;\n0C0F;TELUGU LETTER EE;Lo;0;L;;;;;N;;;;;\n0C10;TELUGU LETTER AI;Lo;0;L;;;;;N;;;;;\n0C12;TELUGU LETTER O;Lo;0;L;;;;;N;;;;;\n0C13;TELUGU LETTER OO;Lo;0;L;;;;;N;;;;;\n0C14;TELUGU LETTER AU;Lo;0;L;;;;;N;;;;;\n0C15;TELUGU LETTER KA;Lo;0;L;;;;;N;;;;;\n0C16;TELUGU LETTER KHA;Lo;0;L;;;;;N;;;;;\n0C17;TELUGU LETTER GA;Lo;0;L;;;;;N;;;;;\n0C18;TELUGU LETTER GHA;Lo;0;L;;;;;N;;;;;\n0C19;TELUGU LETTER NGA;Lo;0;L;;;;;N;;;;;\n0C1A;TELUGU LETTER CA;Lo;0;L;;;;;N;;;;;\n0C1B;TELUGU LETTER CHA;Lo;0;L;;;;;N;;;;;\n0C1C;TELUGU LETTER JA;Lo;0;L;;;;;N;;;;;\n0C1D;TELUGU LETTER JHA;Lo;0;L;;;;;N;;;;;\n0C1E;TELUGU LETTER NYA;Lo;0;L;;;;;N;;;;;\n0C1F;TELUGU LETTER TTA;Lo;0;L;;;;;N;;;;;\n0C20;TELUGU LETTER TTHA;Lo;0;L;;;;;N;;;;;\n0C21;TELUGU LETTER DDA;Lo;0;L;;;;;N;;;;;\n0C22;TELUGU LETTER DDHA;Lo;0;L;;;;;N;;;;;\n0C23;TELUGU LETTER NNA;Lo;0;L;;;;;N;;;;;\n0C24;TELUGU LETTER TA;Lo;0;L;;;;;N;;;;;\n0C25;TELUGU LETTER THA;Lo;0;L;;;;;N;;;;;\n0C26;TELUGU LETTER DA;Lo;0;L;;;;;N;;;;;\n0C27;TELUGU LETTER DHA;Lo;0;L;;;;;N;;;;;\n0C28;TELUGU LETTER NA;Lo;0;L;;;;;N;;;;;\n0C2A;TELUGU LETTER PA;Lo;0;L;;;;;N;;;;;\n0C2B;TELUGU LETTER PHA;Lo;0;L;;;;;N;;;;;\n0C2C;TELUGU LETTER BA;Lo;0;L;;;;;N;;;;;\n0C2D;TELUGU LETTER BHA;Lo;0;L;;;;;N;;;;;\n0C2E;TELUGU LETTER MA;Lo;0;L;;;;;N;;;;;\n0C2F;TELUGU LETTER YA;Lo;0;L;;;;;N;;;;;\n0C30;TELUGU LETTER RA;Lo;0;L;;;;;N;;;;;\n0C31;TELUGU LETTER RRA;Lo;0;L;;;;;N;;;;;\n0C32;TELUGU LETTER LA;Lo;0;L;;;;;N;;;;;\n0C33;TELUGU LETTER LLA;Lo;0;L;;;;;N;;;;;\n0C34;TELUGU LETTER LLLA;Lo;0;L;;;;;N;;;;;\n0C35;TELUGU LETTER VA;Lo;0;L;;;;;N;;;;;\n0C36;TELUGU LETTER SHA;Lo;0;L;;;;;N;;;;;\n0C37;TELUGU LETTER SSA;Lo;0;L;;;;;N;;;;;\n0C38;TELUGU LETTER SA;Lo;0;L;;;;;N;;;;;\n0C39;TELUGU LETTER HA;Lo;0;L;;;;;N;;;;;\n0C3D;TELUGU SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;\n0C3E;TELUGU VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;\n0C3F;TELUGU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n0C40;TELUGU VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;\n0C41;TELUGU VOWEL SIGN U;Mc;0;L;;;;;N;;;;;\n0C42;TELUGU VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;\n0C43;TELUGU VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;\n0C44;TELUGU VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;\n0C46;TELUGU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n0C47;TELUGU VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;;\n0C48;TELUGU VOWEL SIGN AI;Mn;0;NSM;0C46 0C56;;;;N;;;;;\n0C4A;TELUGU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;\n0C4B;TELUGU VOWEL SIGN OO;Mn;0;NSM;;;;;N;;;;;\n0C4C;TELUGU VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;\n0C4D;TELUGU SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n0C55;TELUGU LENGTH MARK;Mn;84;NSM;;;;;N;;;;;\n0C56;TELUGU AI LENGTH MARK;Mn;91;NSM;;;;;N;;;;;\n0C58;TELUGU LETTER TSA;Lo;0;L;;;;;N;;;;;\n0C59;TELUGU LETTER DZA;Lo;0;L;;;;;N;;;;;\n0C5A;TELUGU LETTER RRRA;Lo;0;L;;;;;N;;;;;\n0C60;TELUGU LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n0C61;TELUGU LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\n0C62;TELUGU VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;\n0C63;TELUGU VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;\n0C66;TELUGU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n0C67;TELUGU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n0C68;TELUGU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n0C69;TELUGU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n0C6A;TELUGU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n0C6B;TELUGU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n0C6C;TELUGU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n0C6D;TELUGU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n0C6E;TELUGU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n0C6F;TELUGU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n0C77;TELUGU SIGN SIDDHAM;Po;0;L;;;;;N;;;;;\n0C78;TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR;No;0;ON;;;;0;N;;;;;\n0C79;TELUGU FRACTION DIGIT ONE FOR ODD POWERS OF FOUR;No;0;ON;;;;1;N;;;;;\n0C7A;TELUGU FRACTION DIGIT TWO FOR ODD POWERS OF FOUR;No;0;ON;;;;2;N;;;;;\n0C7B;TELUGU FRACTION DIGIT THREE FOR ODD POWERS OF FOUR;No;0;ON;;;;3;N;;;;;\n0C7C;TELUGU FRACTION DIGIT ONE FOR EVEN POWERS OF FOUR;No;0;ON;;;;1;N;;;;;\n0C7D;TELUGU FRACTION DIGIT TWO FOR EVEN POWERS OF FOUR;No;0;ON;;;;2;N;;;;;\n0C7E;TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR;No;0;ON;;;;3;N;;;;;\n0C7F;TELUGU SIGN TUUMU;So;0;L;;;;;N;;;;;\n0C80;KANNADA SIGN SPACING CANDRABINDU;Lo;0;L;;;;;N;;;;;\n0C81;KANNADA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n0C82;KANNADA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;\n0C83;KANNADA SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n0C84;KANNADA SIGN SIDDHAM;Po;0;L;;;;;N;;;;;\n0C85;KANNADA LETTER A;Lo;0;L;;;;;N;;;;;\n0C86;KANNADA LETTER AA;Lo;0;L;;;;;N;;;;;\n0C87;KANNADA LETTER I;Lo;0;L;;;;;N;;;;;\n0C88;KANNADA LETTER II;Lo;0;L;;;;;N;;;;;\n0C89;KANNADA LETTER U;Lo;0;L;;;;;N;;;;;\n0C8A;KANNADA LETTER UU;Lo;0;L;;;;;N;;;;;\n0C8B;KANNADA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n0C8C;KANNADA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n0C8E;KANNADA LETTER E;Lo;0;L;;;;;N;;;;;\n0C8F;KANNADA LETTER EE;Lo;0;L;;;;;N;;;;;\n0C90;KANNADA LETTER AI;Lo;0;L;;;;;N;;;;;\n0C92;KANNADA LETTER O;Lo;0;L;;;;;N;;;;;\n0C93;KANNADA LETTER OO;Lo;0;L;;;;;N;;;;;\n0C94;KANNADA LETTER AU;Lo;0;L;;;;;N;;;;;\n0C95;KANNADA LETTER KA;Lo;0;L;;;;;N;;;;;\n0C96;KANNADA LETTER KHA;Lo;0;L;;;;;N;;;;;\n0C97;KANNADA LETTER GA;Lo;0;L;;;;;N;;;;;\n0C98;KANNADA LETTER GHA;Lo;0;L;;;;;N;;;;;\n0C99;KANNADA LETTER NGA;Lo;0;L;;;;;N;;;;;\n0C9A;KANNADA LETTER CA;Lo;0;L;;;;;N;;;;;\n0C9B;KANNADA LETTER CHA;Lo;0;L;;;;;N;;;;;\n0C9C;KANNADA LETTER JA;Lo;0;L;;;;;N;;;;;\n0C9D;KANNADA LETTER JHA;Lo;0;L;;;;;N;;;;;\n0C9E;KANNADA LETTER NYA;Lo;0;L;;;;;N;;;;;\n0C9F;KANNADA LETTER TTA;Lo;0;L;;;;;N;;;;;\n0CA0;KANNADA LETTER TTHA;Lo;0;L;;;;;N;;;;;\n0CA1;KANNADA LETTER DDA;Lo;0;L;;;;;N;;;;;\n0CA2;KANNADA LETTER DDHA;Lo;0;L;;;;;N;;;;;\n0CA3;KANNADA LETTER NNA;Lo;0;L;;;;;N;;;;;\n0CA4;KANNADA LETTER TA;Lo;0;L;;;;;N;;;;;\n0CA5;KANNADA LETTER THA;Lo;0;L;;;;;N;;;;;\n0CA6;KANNADA LETTER DA;Lo;0;L;;;;;N;;;;;\n0CA7;KANNADA LETTER DHA;Lo;0;L;;;;;N;;;;;\n0CA8;KANNADA LETTER NA;Lo;0;L;;;;;N;;;;;\n0CAA;KANNADA LETTER PA;Lo;0;L;;;;;N;;;;;\n0CAB;KANNADA LETTER PHA;Lo;0;L;;;;;N;;;;;\n0CAC;KANNADA LETTER BA;Lo;0;L;;;;;N;;;;;\n0CAD;KANNADA LETTER BHA;Lo;0;L;;;;;N;;;;;\n0CAE;KANNADA LETTER MA;Lo;0;L;;;;;N;;;;;\n0CAF;KANNADA LETTER YA;Lo;0;L;;;;;N;;;;;\n0CB0;KANNADA LETTER RA;Lo;0;L;;;;;N;;;;;\n0CB1;KANNADA LETTER RRA;Lo;0;L;;;;;N;;;;;\n0CB2;KANNADA LETTER LA;Lo;0;L;;;;;N;;;;;\n0CB3;KANNADA LETTER LLA;Lo;0;L;;;;;N;;;;;\n0CB5;KANNADA LETTER VA;Lo;0;L;;;;;N;;;;;\n0CB6;KANNADA LETTER SHA;Lo;0;L;;;;;N;;;;;\n0CB7;KANNADA LETTER SSA;Lo;0;L;;;;;N;;;;;\n0CB8;KANNADA LETTER SA;Lo;0;L;;;;;N;;;;;\n0CB9;KANNADA LETTER HA;Lo;0;L;;;;;N;;;;;\n0CBC;KANNADA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n0CBD;KANNADA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;\n0CBE;KANNADA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n0CBF;KANNADA VOWEL SIGN I;Mn;0;L;;;;;N;;;;;\n0CC0;KANNADA VOWEL SIGN II;Mc;0;L;0CBF 0CD5;;;;N;;;;;\n0CC1;KANNADA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;\n0CC2;KANNADA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;\n0CC3;KANNADA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;\n0CC4;KANNADA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;\n0CC6;KANNADA VOWEL SIGN E;Mn;0;L;;;;;N;;;;;\n0CC7;KANNADA VOWEL SIGN EE;Mc;0;L;0CC6 0CD5;;;;N;;;;;\n0CC8;KANNADA VOWEL SIGN AI;Mc;0;L;0CC6 0CD6;;;;N;;;;;\n0CCA;KANNADA VOWEL SIGN O;Mc;0;L;0CC6 0CC2;;;;N;;;;;\n0CCB;KANNADA VOWEL SIGN OO;Mc;0;L;0CCA 0CD5;;;;N;;;;;\n0CCC;KANNADA VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;\n0CCD;KANNADA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n0CD5;KANNADA LENGTH MARK;Mc;0;L;;;;;N;;;;;\n0CD6;KANNADA AI LENGTH MARK;Mc;0;L;;;;;N;;;;;\n0CDE;KANNADA LETTER FA;Lo;0;L;;;;;N;;;;;\n0CE0;KANNADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n0CE1;KANNADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\n0CE2;KANNADA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;\n0CE3;KANNADA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;\n0CE6;KANNADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n0CE7;KANNADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n0CE8;KANNADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n0CE9;KANNADA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n0CEA;KANNADA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n0CEB;KANNADA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n0CEC;KANNADA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n0CED;KANNADA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n0CEE;KANNADA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n0CEF;KANNADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n0CF1;KANNADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;\n0CF2;KANNADA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;\n0D00;MALAYALAM SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;;\n0D01;MALAYALAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n0D02;MALAYALAM SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;\n0D03;MALAYALAM SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n0D05;MALAYALAM LETTER A;Lo;0;L;;;;;N;;;;;\n0D06;MALAYALAM LETTER AA;Lo;0;L;;;;;N;;;;;\n0D07;MALAYALAM LETTER I;Lo;0;L;;;;;N;;;;;\n0D08;MALAYALAM LETTER II;Lo;0;L;;;;;N;;;;;\n0D09;MALAYALAM LETTER U;Lo;0;L;;;;;N;;;;;\n0D0A;MALAYALAM LETTER UU;Lo;0;L;;;;;N;;;;;\n0D0B;MALAYALAM LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n0D0C;MALAYALAM LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n0D0E;MALAYALAM LETTER E;Lo;0;L;;;;;N;;;;;\n0D0F;MALAYALAM LETTER EE;Lo;0;L;;;;;N;;;;;\n0D10;MALAYALAM LETTER AI;Lo;0;L;;;;;N;;;;;\n0D12;MALAYALAM LETTER O;Lo;0;L;;;;;N;;;;;\n0D13;MALAYALAM LETTER OO;Lo;0;L;;;;;N;;;;;\n0D14;MALAYALAM LETTER AU;Lo;0;L;;;;;N;;;;;\n0D15;MALAYALAM LETTER KA;Lo;0;L;;;;;N;;;;;\n0D16;MALAYALAM LETTER KHA;Lo;0;L;;;;;N;;;;;\n0D17;MALAYALAM LETTER GA;Lo;0;L;;;;;N;;;;;\n0D18;MALAYALAM LETTER GHA;Lo;0;L;;;;;N;;;;;\n0D19;MALAYALAM LETTER NGA;Lo;0;L;;;;;N;;;;;\n0D1A;MALAYALAM LETTER CA;Lo;0;L;;;;;N;;;;;\n0D1B;MALAYALAM LETTER CHA;Lo;0;L;;;;;N;;;;;\n0D1C;MALAYALAM LETTER JA;Lo;0;L;;;;;N;;;;;\n0D1D;MALAYALAM LETTER JHA;Lo;0;L;;;;;N;;;;;\n0D1E;MALAYALAM LETTER NYA;Lo;0;L;;;;;N;;;;;\n0D1F;MALAYALAM LETTER TTA;Lo;0;L;;;;;N;;;;;\n0D20;MALAYALAM LETTER TTHA;Lo;0;L;;;;;N;;;;;\n0D21;MALAYALAM LETTER DDA;Lo;0;L;;;;;N;;;;;\n0D22;MALAYALAM LETTER DDHA;Lo;0;L;;;;;N;;;;;\n0D23;MALAYALAM LETTER NNA;Lo;0;L;;;;;N;;;;;\n0D24;MALAYALAM LETTER TA;Lo;0;L;;;;;N;;;;;\n0D25;MALAYALAM LETTER THA;Lo;0;L;;;;;N;;;;;\n0D26;MALAYALAM LETTER DA;Lo;0;L;;;;;N;;;;;\n0D27;MALAYALAM LETTER DHA;Lo;0;L;;;;;N;;;;;\n0D28;MALAYALAM LETTER NA;Lo;0;L;;;;;N;;;;;\n0D29;MALAYALAM LETTER NNNA;Lo;0;L;;;;;N;;;;;\n0D2A;MALAYALAM LETTER PA;Lo;0;L;;;;;N;;;;;\n0D2B;MALAYALAM LETTER PHA;Lo;0;L;;;;;N;;;;;\n0D2C;MALAYALAM LETTER BA;Lo;0;L;;;;;N;;;;;\n0D2D;MALAYALAM LETTER BHA;Lo;0;L;;;;;N;;;;;\n0D2E;MALAYALAM LETTER MA;Lo;0;L;;;;;N;;;;;\n0D2F;MALAYALAM LETTER YA;Lo;0;L;;;;;N;;;;;\n0D30;MALAYALAM LETTER RA;Lo;0;L;;;;;N;;;;;\n0D31;MALAYALAM LETTER RRA;Lo;0;L;;;;;N;;;;;\n0D32;MALAYALAM LETTER LA;Lo;0;L;;;;;N;;;;;\n0D33;MALAYALAM LETTER LLA;Lo;0;L;;;;;N;;;;;\n0D34;MALAYALAM LETTER LLLA;Lo;0;L;;;;;N;;;;;\n0D35;MALAYALAM LETTER VA;Lo;0;L;;;;;N;;;;;\n0D36;MALAYALAM LETTER SHA;Lo;0;L;;;;;N;;;;;\n0D37;MALAYALAM LETTER SSA;Lo;0;L;;;;;N;;;;;\n0D38;MALAYALAM LETTER SA;Lo;0;L;;;;;N;;;;;\n0D39;MALAYALAM LETTER HA;Lo;0;L;;;;;N;;;;;\n0D3A;MALAYALAM LETTER TTTA;Lo;0;L;;;;;N;;;;;\n0D3B;MALAYALAM SIGN VERTICAL BAR VIRAMA;Mn;9;NSM;;;;;N;;;;;\n0D3C;MALAYALAM SIGN CIRCULAR VIRAMA;Mn;9;NSM;;;;;N;;;;;\n0D3D;MALAYALAM SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;\n0D3E;MALAYALAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n0D3F;MALAYALAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n0D40;MALAYALAM VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n0D41;MALAYALAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n0D42;MALAYALAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n0D43;MALAYALAM VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n0D44;MALAYALAM VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;\n0D46;MALAYALAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\n0D47;MALAYALAM VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;\n0D48;MALAYALAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;\n0D4A;MALAYALAM VOWEL SIGN O;Mc;0;L;0D46 0D3E;;;;N;;;;;\n0D4B;MALAYALAM VOWEL SIGN OO;Mc;0;L;0D47 0D3E;;;;N;;;;;\n0D4C;MALAYALAM VOWEL SIGN AU;Mc;0;L;0D46 0D57;;;;N;;;;;\n0D4D;MALAYALAM SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n0D4E;MALAYALAM LETTER DOT REPH;Lo;0;L;;;;;N;;;;;\n0D4F;MALAYALAM SIGN PARA;So;0;L;;;;;N;;;;;\n0D54;MALAYALAM LETTER CHILLU M;Lo;0;L;;;;;N;;;;;\n0D55;MALAYALAM LETTER CHILLU Y;Lo;0;L;;;;;N;;;;;\n0D56;MALAYALAM LETTER CHILLU LLL;Lo;0;L;;;;;N;;;;;\n0D57;MALAYALAM AU LENGTH MARK;Mc;0;L;;;;;N;;;;;\n0D58;MALAYALAM FRACTION ONE ONE-HUNDRED-AND-SIXTIETH;No;0;L;;;;1/160;N;;;;;\n0D59;MALAYALAM FRACTION ONE FORTIETH;No;0;L;;;;1/40;N;;;;;\n0D5A;MALAYALAM FRACTION THREE EIGHTIETHS;No;0;L;;;;3/80;N;;;;;\n0D5B;MALAYALAM FRACTION ONE TWENTIETH;No;0;L;;;;1/20;N;;;;;\n0D5C;MALAYALAM FRACTION ONE TENTH;No;0;L;;;;1/10;N;;;;;\n0D5D;MALAYALAM FRACTION THREE TWENTIETHS;No;0;L;;;;3/20;N;;;;;\n0D5E;MALAYALAM FRACTION ONE FIFTH;No;0;L;;;;1/5;N;;;;;\n0D5F;MALAYALAM LETTER ARCHAIC II;Lo;0;L;;;;;N;;;;;\n0D60;MALAYALAM LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n0D61;MALAYALAM LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\n0D62;MALAYALAM VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;\n0D63;MALAYALAM VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;\n0D66;MALAYALAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n0D67;MALAYALAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n0D68;MALAYALAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n0D69;MALAYALAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n0D6A;MALAYALAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n0D6B;MALAYALAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n0D6C;MALAYALAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n0D6D;MALAYALAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n0D6E;MALAYALAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n0D6F;MALAYALAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n0D70;MALAYALAM NUMBER TEN;No;0;L;;;;10;N;;;;;\n0D71;MALAYALAM NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;\n0D72;MALAYALAM NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;\n0D73;MALAYALAM FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;;\n0D74;MALAYALAM FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;;\n0D75;MALAYALAM FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;;\n0D76;MALAYALAM FRACTION ONE SIXTEENTH;No;0;L;;;;1/16;N;;;;;\n0D77;MALAYALAM FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;;\n0D78;MALAYALAM FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;;\n0D79;MALAYALAM DATE MARK;So;0;L;;;;;N;;;;;\n0D7A;MALAYALAM LETTER CHILLU NN;Lo;0;L;;;;;N;;;;;\n0D7B;MALAYALAM LETTER CHILLU N;Lo;0;L;;;;;N;;;;;\n0D7C;MALAYALAM LETTER CHILLU RR;Lo;0;L;;;;;N;;;;;\n0D7D;MALAYALAM LETTER CHILLU L;Lo;0;L;;;;;N;;;;;\n0D7E;MALAYALAM LETTER CHILLU LL;Lo;0;L;;;;;N;;;;;\n0D7F;MALAYALAM LETTER CHILLU K;Lo;0;L;;;;;N;;;;;\n0D82;SINHALA SIGN ANUSVARAYA;Mc;0;L;;;;;N;;;;;\n0D83;SINHALA SIGN VISARGAYA;Mc;0;L;;;;;N;;;;;\n0D85;SINHALA LETTER AYANNA;Lo;0;L;;;;;N;;;;;\n0D86;SINHALA LETTER AAYANNA;Lo;0;L;;;;;N;;;;;\n0D87;SINHALA LETTER AEYANNA;Lo;0;L;;;;;N;;;;;\n0D88;SINHALA LETTER AEEYANNA;Lo;0;L;;;;;N;;;;;\n0D89;SINHALA LETTER IYANNA;Lo;0;L;;;;;N;;;;;\n0D8A;SINHALA LETTER IIYANNA;Lo;0;L;;;;;N;;;;;\n0D8B;SINHALA LETTER UYANNA;Lo;0;L;;;;;N;;;;;\n0D8C;SINHALA LETTER UUYANNA;Lo;0;L;;;;;N;;;;;\n0D8D;SINHALA LETTER IRUYANNA;Lo;0;L;;;;;N;;;;;\n0D8E;SINHALA LETTER IRUUYANNA;Lo;0;L;;;;;N;;;;;\n0D8F;SINHALA LETTER ILUYANNA;Lo;0;L;;;;;N;;;;;\n0D90;SINHALA LETTER ILUUYANNA;Lo;0;L;;;;;N;;;;;\n0D91;SINHALA LETTER EYANNA;Lo;0;L;;;;;N;;;;;\n0D92;SINHALA LETTER EEYANNA;Lo;0;L;;;;;N;;;;;\n0D93;SINHALA LETTER AIYANNA;Lo;0;L;;;;;N;;;;;\n0D94;SINHALA LETTER OYANNA;Lo;0;L;;;;;N;;;;;\n0D95;SINHALA LETTER OOYANNA;Lo;0;L;;;;;N;;;;;\n0D96;SINHALA LETTER AUYANNA;Lo;0;L;;;;;N;;;;;\n0D9A;SINHALA LETTER ALPAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;;\n0D9B;SINHALA LETTER MAHAAPRAANA KAYANNA;Lo;0;L;;;;;N;;;;;\n0D9C;SINHALA LETTER ALPAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;;\n0D9D;SINHALA LETTER MAHAAPRAANA GAYANNA;Lo;0;L;;;;;N;;;;;\n0D9E;SINHALA LETTER KANTAJA NAASIKYAYA;Lo;0;L;;;;;N;;;;;\n0D9F;SINHALA LETTER SANYAKA GAYANNA;Lo;0;L;;;;;N;;;;;\n0DA0;SINHALA LETTER ALPAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;;\n0DA1;SINHALA LETTER MAHAAPRAANA CAYANNA;Lo;0;L;;;;;N;;;;;\n0DA2;SINHALA LETTER ALPAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;;\n0DA3;SINHALA LETTER MAHAAPRAANA JAYANNA;Lo;0;L;;;;;N;;;;;\n0DA4;SINHALA LETTER TAALUJA NAASIKYAYA;Lo;0;L;;;;;N;;;;;\n0DA5;SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA;Lo;0;L;;;;;N;;;;;\n0DA6;SINHALA LETTER SANYAKA JAYANNA;Lo;0;L;;;;;N;;;;;\n0DA7;SINHALA LETTER ALPAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;;\n0DA8;SINHALA LETTER MAHAAPRAANA TTAYANNA;Lo;0;L;;;;;N;;;;;\n0DA9;SINHALA LETTER ALPAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;;\n0DAA;SINHALA LETTER MAHAAPRAANA DDAYANNA;Lo;0;L;;;;;N;;;;;\n0DAB;SINHALA LETTER MUURDHAJA NAYANNA;Lo;0;L;;;;;N;;;;;\n0DAC;SINHALA LETTER SANYAKA DDAYANNA;Lo;0;L;;;;;N;;;;;\n0DAD;SINHALA LETTER ALPAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;;\n0DAE;SINHALA LETTER MAHAAPRAANA TAYANNA;Lo;0;L;;;;;N;;;;;\n0DAF;SINHALA LETTER ALPAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;;\n0DB0;SINHALA LETTER MAHAAPRAANA DAYANNA;Lo;0;L;;;;;N;;;;;\n0DB1;SINHALA LETTER DANTAJA NAYANNA;Lo;0;L;;;;;N;;;;;\n0DB3;SINHALA LETTER SANYAKA DAYANNA;Lo;0;L;;;;;N;;;;;\n0DB4;SINHALA LETTER ALPAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;;\n0DB5;SINHALA LETTER MAHAAPRAANA PAYANNA;Lo;0;L;;;;;N;;;;;\n0DB6;SINHALA LETTER ALPAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;;\n0DB7;SINHALA LETTER MAHAAPRAANA BAYANNA;Lo;0;L;;;;;N;;;;;\n0DB8;SINHALA LETTER MAYANNA;Lo;0;L;;;;;N;;;;;\n0DB9;SINHALA LETTER AMBA BAYANNA;Lo;0;L;;;;;N;;;;;\n0DBA;SINHALA LETTER YAYANNA;Lo;0;L;;;;;N;;;;;\n0DBB;SINHALA LETTER RAYANNA;Lo;0;L;;;;;N;;;;;\n0DBD;SINHALA LETTER DANTAJA LAYANNA;Lo;0;L;;;;;N;;;;;\n0DC0;SINHALA LETTER VAYANNA;Lo;0;L;;;;;N;;;;;\n0DC1;SINHALA LETTER TAALUJA SAYANNA;Lo;0;L;;;;;N;;;;;\n0DC2;SINHALA LETTER MUURDHAJA SAYANNA;Lo;0;L;;;;;N;;;;;\n0DC3;SINHALA LETTER DANTAJA SAYANNA;Lo;0;L;;;;;N;;;;;\n0DC4;SINHALA LETTER HAYANNA;Lo;0;L;;;;;N;;;;;\n0DC5;SINHALA LETTER MUURDHAJA LAYANNA;Lo;0;L;;;;;N;;;;;\n0DC6;SINHALA LETTER FAYANNA;Lo;0;L;;;;;N;;;;;\n0DCA;SINHALA SIGN AL-LAKUNA;Mn;9;NSM;;;;;N;;;;;\n0DCF;SINHALA VOWEL SIGN AELA-PILLA;Mc;0;L;;;;;N;;;;;\n0DD0;SINHALA VOWEL SIGN KETTI AEDA-PILLA;Mc;0;L;;;;;N;;;;;\n0DD1;SINHALA VOWEL SIGN DIGA AEDA-PILLA;Mc;0;L;;;;;N;;;;;\n0DD2;SINHALA VOWEL SIGN KETTI IS-PILLA;Mn;0;NSM;;;;;N;;;;;\n0DD3;SINHALA VOWEL SIGN DIGA IS-PILLA;Mn;0;NSM;;;;;N;;;;;\n0DD4;SINHALA VOWEL SIGN KETTI PAA-PILLA;Mn;0;NSM;;;;;N;;;;;\n0DD6;SINHALA VOWEL SIGN DIGA PAA-PILLA;Mn;0;NSM;;;;;N;;;;;\n0DD8;SINHALA VOWEL SIGN GAETTA-PILLA;Mc;0;L;;;;;N;;;;;\n0DD9;SINHALA VOWEL SIGN KOMBUVA;Mc;0;L;;;;;N;;;;;\n0DDA;SINHALA VOWEL SIGN DIGA KOMBUVA;Mc;0;L;0DD9 0DCA;;;;N;;;;;\n0DDB;SINHALA VOWEL SIGN KOMBU DEKA;Mc;0;L;;;;;N;;;;;\n0DDC;SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA;Mc;0;L;0DD9 0DCF;;;;N;;;;;\n0DDD;SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA;Mc;0;L;0DDC 0DCA;;;;N;;;;;\n0DDE;SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA;Mc;0;L;0DD9 0DDF;;;;N;;;;;\n0DDF;SINHALA VOWEL SIGN GAYANUKITTA;Mc;0;L;;;;;N;;;;;\n0DE6;SINHALA LITH DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n0DE7;SINHALA LITH DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n0DE8;SINHALA LITH DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n0DE9;SINHALA LITH DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n0DEA;SINHALA LITH DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n0DEB;SINHALA LITH DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n0DEC;SINHALA LITH DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n0DED;SINHALA LITH DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n0DEE;SINHALA LITH DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n0DEF;SINHALA LITH DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n0DF2;SINHALA VOWEL SIGN DIGA GAETTA-PILLA;Mc;0;L;;;;;N;;;;;\n0DF3;SINHALA VOWEL SIGN DIGA GAYANUKITTA;Mc;0;L;;;;;N;;;;;\n0DF4;SINHALA PUNCTUATION KUNDDALIYA;Po;0;L;;;;;N;;;;;\n0E01;THAI CHARACTER KO KAI;Lo;0;L;;;;;N;THAI LETTER KO KAI;;;;\n0E02;THAI CHARACTER KHO KHAI;Lo;0;L;;;;;N;THAI LETTER KHO KHAI;;;;\n0E03;THAI CHARACTER KHO KHUAT;Lo;0;L;;;;;N;THAI LETTER KHO KHUAT;;;;\n0E04;THAI CHARACTER KHO KHWAI;Lo;0;L;;;;;N;THAI LETTER KHO KHWAI;;;;\n0E05;THAI CHARACTER KHO KHON;Lo;0;L;;;;;N;THAI LETTER KHO KHON;;;;\n0E06;THAI CHARACTER KHO RAKHANG;Lo;0;L;;;;;N;THAI LETTER KHO RAKHANG;;;;\n0E07;THAI CHARACTER NGO NGU;Lo;0;L;;;;;N;THAI LETTER NGO NGU;;;;\n0E08;THAI CHARACTER CHO CHAN;Lo;0;L;;;;;N;THAI LETTER CHO CHAN;;;;\n0E09;THAI CHARACTER CHO CHING;Lo;0;L;;;;;N;THAI LETTER CHO CHING;;;;\n0E0A;THAI CHARACTER CHO CHANG;Lo;0;L;;;;;N;THAI LETTER CHO CHANG;;;;\n0E0B;THAI CHARACTER SO SO;Lo;0;L;;;;;N;THAI LETTER SO SO;;;;\n0E0C;THAI CHARACTER CHO CHOE;Lo;0;L;;;;;N;THAI LETTER CHO CHOE;;;;\n0E0D;THAI CHARACTER YO YING;Lo;0;L;;;;;N;THAI LETTER YO YING;;;;\n0E0E;THAI CHARACTER DO CHADA;Lo;0;L;;;;;N;THAI LETTER DO CHADA;;;;\n0E0F;THAI CHARACTER TO PATAK;Lo;0;L;;;;;N;THAI LETTER TO PATAK;;;;\n0E10;THAI CHARACTER THO THAN;Lo;0;L;;;;;N;THAI LETTER THO THAN;;;;\n0E11;THAI CHARACTER THO NANGMONTHO;Lo;0;L;;;;;N;THAI LETTER THO NANGMONTHO;;;;\n0E12;THAI CHARACTER THO PHUTHAO;Lo;0;L;;;;;N;THAI LETTER THO PHUTHAO;;;;\n0E13;THAI CHARACTER NO NEN;Lo;0;L;;;;;N;THAI LETTER NO NEN;;;;\n0E14;THAI CHARACTER DO DEK;Lo;0;L;;;;;N;THAI LETTER DO DEK;;;;\n0E15;THAI CHARACTER TO TAO;Lo;0;L;;;;;N;THAI LETTER TO TAO;;;;\n0E16;THAI CHARACTER THO THUNG;Lo;0;L;;;;;N;THAI LETTER THO THUNG;;;;\n0E17;THAI CHARACTER THO THAHAN;Lo;0;L;;;;;N;THAI LETTER THO THAHAN;;;;\n0E18;THAI CHARACTER THO THONG;Lo;0;L;;;;;N;THAI LETTER THO THONG;;;;\n0E19;THAI CHARACTER NO NU;Lo;0;L;;;;;N;THAI LETTER NO NU;;;;\n0E1A;THAI CHARACTER BO BAIMAI;Lo;0;L;;;;;N;THAI LETTER BO BAIMAI;;;;\n0E1B;THAI CHARACTER PO PLA;Lo;0;L;;;;;N;THAI LETTER PO PLA;;;;\n0E1C;THAI CHARACTER PHO PHUNG;Lo;0;L;;;;;N;THAI LETTER PHO PHUNG;;;;\n0E1D;THAI CHARACTER FO FA;Lo;0;L;;;;;N;THAI LETTER FO FA;;;;\n0E1E;THAI CHARACTER PHO PHAN;Lo;0;L;;;;;N;THAI LETTER PHO PHAN;;;;\n0E1F;THAI CHARACTER FO FAN;Lo;0;L;;;;;N;THAI LETTER FO FAN;;;;\n0E20;THAI CHARACTER PHO SAMPHAO;Lo;0;L;;;;;N;THAI LETTER PHO SAMPHAO;;;;\n0E21;THAI CHARACTER MO MA;Lo;0;L;;;;;N;THAI LETTER MO MA;;;;\n0E22;THAI CHARACTER YO YAK;Lo;0;L;;;;;N;THAI LETTER YO YAK;;;;\n0E23;THAI CHARACTER RO RUA;Lo;0;L;;;;;N;THAI LETTER RO RUA;;;;\n0E24;THAI CHARACTER RU;Lo;0;L;;;;;N;THAI LETTER RU;;;;\n0E25;THAI CHARACTER LO LING;Lo;0;L;;;;;N;THAI LETTER LO LING;;;;\n0E26;THAI CHARACTER LU;Lo;0;L;;;;;N;THAI LETTER LU;;;;\n0E27;THAI CHARACTER WO WAEN;Lo;0;L;;;;;N;THAI LETTER WO WAEN;;;;\n0E28;THAI CHARACTER SO SALA;Lo;0;L;;;;;N;THAI LETTER SO SALA;;;;\n0E29;THAI CHARACTER SO RUSI;Lo;0;L;;;;;N;THAI LETTER SO RUSI;;;;\n0E2A;THAI CHARACTER SO SUA;Lo;0;L;;;;;N;THAI LETTER SO SUA;;;;\n0E2B;THAI CHARACTER HO HIP;Lo;0;L;;;;;N;THAI LETTER HO HIP;;;;\n0E2C;THAI CHARACTER LO CHULA;Lo;0;L;;;;;N;THAI LETTER LO CHULA;;;;\n0E2D;THAI CHARACTER O ANG;Lo;0;L;;;;;N;THAI LETTER O ANG;;;;\n0E2E;THAI CHARACTER HO NOKHUK;Lo;0;L;;;;;N;THAI LETTER HO NOK HUK;;;;\n0E2F;THAI CHARACTER PAIYANNOI;Lo;0;L;;;;;N;THAI PAI YAN NOI;;;;\n0E30;THAI CHARACTER SARA A;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA A;;;;\n0E31;THAI CHARACTER MAI HAN-AKAT;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI HAN-AKAT;;;;\n0E32;THAI CHARACTER SARA AA;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AA;;;;\n0E33;THAI CHARACTER SARA AM;Lo;0;L;<compat> 0E4D 0E32;;;;N;THAI VOWEL SIGN SARA AM;;;;\n0E34;THAI CHARACTER SARA I;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA I;;;;\n0E35;THAI CHARACTER SARA II;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA II;;;;\n0E36;THAI CHARACTER SARA UE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UE;;;;\n0E37;THAI CHARACTER SARA UEE;Mn;0;NSM;;;;;N;THAI VOWEL SIGN SARA UEE;;;;\n0E38;THAI CHARACTER SARA U;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA U;;;;\n0E39;THAI CHARACTER SARA UU;Mn;103;NSM;;;;;N;THAI VOWEL SIGN SARA UU;;;;\n0E3A;THAI CHARACTER PHINTHU;Mn;9;NSM;;;;;N;THAI VOWEL SIGN PHINTHU;;;;\n0E3F;THAI CURRENCY SYMBOL BAHT;Sc;0;ET;;;;;N;THAI BAHT SIGN;;;;\n0E40;THAI CHARACTER SARA E;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA E;;;;\n0E41;THAI CHARACTER SARA AE;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA AE;;;;\n0E42;THAI CHARACTER SARA O;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA O;;;;\n0E43;THAI CHARACTER SARA AI MAIMUAN;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MUAN;;;;\n0E44;THAI CHARACTER SARA AI MAIMALAI;Lo;0;L;;;;;N;THAI VOWEL SIGN SARA MAI MALAI;;;;\n0E45;THAI CHARACTER LAKKHANGYAO;Lo;0;L;;;;;N;THAI LAK KHANG YAO;;;;\n0E46;THAI CHARACTER MAIYAMOK;Lm;0;L;;;;;N;THAI MAI YAMOK;;;;\n0E47;THAI CHARACTER MAITAIKHU;Mn;0;NSM;;;;;N;THAI VOWEL SIGN MAI TAI KHU;;;;\n0E48;THAI CHARACTER MAI EK;Mn;107;NSM;;;;;N;THAI TONE MAI EK;;;;\n0E49;THAI CHARACTER MAI THO;Mn;107;NSM;;;;;N;THAI TONE MAI THO;;;;\n0E4A;THAI CHARACTER MAI TRI;Mn;107;NSM;;;;;N;THAI TONE MAI TRI;;;;\n0E4B;THAI CHARACTER MAI CHATTAWA;Mn;107;NSM;;;;;N;THAI TONE MAI CHATTAWA;;;;\n0E4C;THAI CHARACTER THANTHAKHAT;Mn;0;NSM;;;;;N;THAI THANTHAKHAT;;;;\n0E4D;THAI CHARACTER NIKHAHIT;Mn;0;NSM;;;;;N;THAI NIKKHAHIT;;;;\n0E4E;THAI CHARACTER YAMAKKAN;Mn;0;NSM;;;;;N;THAI YAMAKKAN;;;;\n0E4F;THAI CHARACTER FONGMAN;Po;0;L;;;;;N;THAI FONGMAN;;;;\n0E50;THAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n0E51;THAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n0E52;THAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n0E53;THAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n0E54;THAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n0E55;THAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n0E56;THAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n0E57;THAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n0E58;THAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n0E59;THAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n0E5A;THAI CHARACTER ANGKHANKHU;Po;0;L;;;;;N;THAI ANGKHANKHU;;;;\n0E5B;THAI CHARACTER KHOMUT;Po;0;L;;;;;N;THAI KHOMUT;;;;\n0E81;LAO LETTER KO;Lo;0;L;;;;;N;;;;;\n0E82;LAO LETTER KHO SUNG;Lo;0;L;;;;;N;;;;;\n0E84;LAO LETTER KHO TAM;Lo;0;L;;;;;N;;;;;\n0E86;LAO LETTER PALI GHA;Lo;0;L;;;;;N;;;;;\n0E87;LAO LETTER NGO;Lo;0;L;;;;;N;;;;;\n0E88;LAO LETTER CO;Lo;0;L;;;;;N;;;;;\n0E89;LAO LETTER PALI CHA;Lo;0;L;;;;;N;;;;;\n0E8A;LAO LETTER SO TAM;Lo;0;L;;;;;N;;;;;\n0E8C;LAO LETTER PALI JHA;Lo;0;L;;;;;N;;;;;\n0E8D;LAO LETTER NYO;Lo;0;L;;;;;N;;;;;\n0E8E;LAO LETTER PALI NYA;Lo;0;L;;;;;N;;;;;\n0E8F;LAO LETTER PALI TTA;Lo;0;L;;;;;N;;;;;\n0E90;LAO LETTER PALI TTHA;Lo;0;L;;;;;N;;;;;\n0E91;LAO LETTER PALI DDA;Lo;0;L;;;;;N;;;;;\n0E92;LAO LETTER PALI DDHA;Lo;0;L;;;;;N;;;;;\n0E93;LAO LETTER PALI NNA;Lo;0;L;;;;;N;;;;;\n0E94;LAO LETTER DO;Lo;0;L;;;;;N;;;;;\n0E95;LAO LETTER TO;Lo;0;L;;;;;N;;;;;\n0E96;LAO LETTER THO SUNG;Lo;0;L;;;;;N;;;;;\n0E97;LAO LETTER THO TAM;Lo;0;L;;;;;N;;;;;\n0E98;LAO LETTER PALI DHA;Lo;0;L;;;;;N;;;;;\n0E99;LAO LETTER NO;Lo;0;L;;;;;N;;;;;\n0E9A;LAO LETTER BO;Lo;0;L;;;;;N;;;;;\n0E9B;LAO LETTER PO;Lo;0;L;;;;;N;;;;;\n0E9C;LAO LETTER PHO SUNG;Lo;0;L;;;;;N;;;;;\n0E9D;LAO LETTER FO TAM;Lo;0;L;;;;;N;;;;;\n0E9E;LAO LETTER PHO TAM;Lo;0;L;;;;;N;;;;;\n0E9F;LAO LETTER FO SUNG;Lo;0;L;;;;;N;;;;;\n0EA0;LAO LETTER PALI BHA;Lo;0;L;;;;;N;;;;;\n0EA1;LAO LETTER MO;Lo;0;L;;;;;N;;;;;\n0EA2;LAO LETTER YO;Lo;0;L;;;;;N;;;;;\n0EA3;LAO LETTER LO LING;Lo;0;L;;;;;N;;;;;\n0EA5;LAO LETTER LO LOOT;Lo;0;L;;;;;N;;;;;\n0EA7;LAO LETTER WO;Lo;0;L;;;;;N;;;;;\n0EA8;LAO LETTER SANSKRIT SHA;Lo;0;L;;;;;N;;;;;\n0EA9;LAO LETTER SANSKRIT SSA;Lo;0;L;;;;;N;;;;;\n0EAA;LAO LETTER SO SUNG;Lo;0;L;;;;;N;;;;;\n0EAB;LAO LETTER HO SUNG;Lo;0;L;;;;;N;;;;;\n0EAC;LAO LETTER PALI LLA;Lo;0;L;;;;;N;;;;;\n0EAD;LAO LETTER O;Lo;0;L;;;;;N;;;;;\n0EAE;LAO LETTER HO TAM;Lo;0;L;;;;;N;;;;;\n0EAF;LAO ELLIPSIS;Lo;0;L;;;;;N;;;;;\n0EB0;LAO VOWEL SIGN A;Lo;0;L;;;;;N;;;;;\n0EB1;LAO VOWEL SIGN MAI KAN;Mn;0;NSM;;;;;N;;;;;\n0EB2;LAO VOWEL SIGN AA;Lo;0;L;;;;;N;;;;;\n0EB3;LAO VOWEL SIGN AM;Lo;0;L;<compat> 0ECD 0EB2;;;;N;;;;;\n0EB4;LAO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n0EB5;LAO VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;\n0EB6;LAO VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;;\n0EB7;LAO VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;;\n0EB8;LAO VOWEL SIGN U;Mn;118;NSM;;;;;N;;;;;\n0EB9;LAO VOWEL SIGN UU;Mn;118;NSM;;;;;N;;;;;\n0EBA;LAO SIGN PALI VIRAMA;Mn;9;NSM;;;;;N;;;;;\n0EBB;LAO VOWEL SIGN MAI KON;Mn;0;NSM;;;;;N;;;;;\n0EBC;LAO SEMIVOWEL SIGN LO;Mn;0;NSM;;;;;N;;;;;\n0EBD;LAO SEMIVOWEL SIGN NYO;Lo;0;L;;;;;N;;;;;\n0EC0;LAO VOWEL SIGN E;Lo;0;L;;;;;N;;;;;\n0EC1;LAO VOWEL SIGN EI;Lo;0;L;;;;;N;;;;;\n0EC2;LAO VOWEL SIGN O;Lo;0;L;;;;;N;;;;;\n0EC3;LAO VOWEL SIGN AY;Lo;0;L;;;;;N;;;;;\n0EC4;LAO VOWEL SIGN AI;Lo;0;L;;;;;N;;;;;\n0EC6;LAO KO LA;Lm;0;L;;;;;N;;;;;\n0EC8;LAO TONE MAI EK;Mn;122;NSM;;;;;N;;;;;\n0EC9;LAO TONE MAI THO;Mn;122;NSM;;;;;N;;;;;\n0ECA;LAO TONE MAI TI;Mn;122;NSM;;;;;N;;;;;\n0ECB;LAO TONE MAI CATAWA;Mn;122;NSM;;;;;N;;;;;\n0ECC;LAO CANCELLATION MARK;Mn;0;NSM;;;;;N;;;;;\n0ECD;LAO NIGGAHITA;Mn;0;NSM;;;;;N;;;;;\n0ED0;LAO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n0ED1;LAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n0ED2;LAO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n0ED3;LAO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n0ED4;LAO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n0ED5;LAO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n0ED6;LAO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n0ED7;LAO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n0ED8;LAO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n0ED9;LAO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n0EDC;LAO HO NO;Lo;0;L;<compat> 0EAB 0E99;;;;N;;;;;\n0EDD;LAO HO MO;Lo;0;L;<compat> 0EAB 0EA1;;;;N;;;;;\n0EDE;LAO LETTER KHMU GO;Lo;0;L;;;;;N;;;;;\n0EDF;LAO LETTER KHMU NYO;Lo;0;L;;;;;N;;;;;\n0F00;TIBETAN SYLLABLE OM;Lo;0;L;;;;;N;;;;;\n0F01;TIBETAN MARK GTER YIG MGO TRUNCATED A;So;0;L;;;;;N;;;;;\n0F02;TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA;So;0;L;;;;;N;;;;;\n0F03;TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA;So;0;L;;;;;N;;;;;\n0F04;TIBETAN MARK INITIAL YIG MGO MDUN MA;Po;0;L;;;;;N;TIBETAN SINGLE ORNAMENT;;;;\n0F05;TIBETAN MARK CLOSING YIG MGO SGAB MA;Po;0;L;;;;;N;;;;;\n0F06;TIBETAN MARK CARET YIG MGO PHUR SHAD MA;Po;0;L;;;;;N;;;;;\n0F07;TIBETAN MARK YIG MGO TSHEG SHAD MA;Po;0;L;;;;;N;;;;;\n0F08;TIBETAN MARK SBRUL SHAD;Po;0;L;;;;;N;TIBETAN RGYANSHAD;;;;\n0F09;TIBETAN MARK BSKUR YIG MGO;Po;0;L;;;;;N;;;;;\n0F0A;TIBETAN MARK BKA- SHOG YIG MGO;Po;0;L;;;;;N;;;;;\n0F0B;TIBETAN MARK INTERSYLLABIC TSHEG;Po;0;L;;;;;N;TIBETAN TSEG;;;;\n0F0C;TIBETAN MARK DELIMITER TSHEG BSTAR;Po;0;L;<noBreak> 0F0B;;;;N;;;;;\n0F0D;TIBETAN MARK SHAD;Po;0;L;;;;;N;TIBETAN SHAD;;;;\n0F0E;TIBETAN MARK NYIS SHAD;Po;0;L;;;;;N;TIBETAN DOUBLE SHAD;;;;\n0F0F;TIBETAN MARK TSHEG SHAD;Po;0;L;;;;;N;;;;;\n0F10;TIBETAN MARK NYIS TSHEG SHAD;Po;0;L;;;;;N;;;;;\n0F11;TIBETAN MARK RIN CHEN SPUNGS SHAD;Po;0;L;;;;;N;TIBETAN RINCHANPHUNGSHAD;;;;\n0F12;TIBETAN MARK RGYA GRAM SHAD;Po;0;L;;;;;N;;;;;\n0F13;TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN;So;0;L;;;;;N;;;;;\n0F14;TIBETAN MARK GTER TSHEG;Po;0;L;;;;;N;TIBETAN COMMA;;;;\n0F15;TIBETAN LOGOTYPE SIGN CHAD RTAGS;So;0;L;;;;;N;;;;;\n0F16;TIBETAN LOGOTYPE SIGN LHAG RTAGS;So;0;L;;;;;N;;;;;\n0F17;TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS;So;0;L;;;;;N;;;;;\n0F18;TIBETAN ASTROLOGICAL SIGN -KHYUD PA;Mn;220;NSM;;;;;N;;;;;\n0F19;TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS;Mn;220;NSM;;;;;N;;;;;\n0F1A;TIBETAN SIGN RDEL DKAR GCIG;So;0;L;;;;;N;;;;;\n0F1B;TIBETAN SIGN RDEL DKAR GNYIS;So;0;L;;;;;N;;;;;\n0F1C;TIBETAN SIGN RDEL DKAR GSUM;So;0;L;;;;;N;;;;;\n0F1D;TIBETAN SIGN RDEL NAG GCIG;So;0;L;;;;;N;;;;;\n0F1E;TIBETAN SIGN RDEL NAG GNYIS;So;0;L;;;;;N;;;;;\n0F1F;TIBETAN SIGN RDEL DKAR RDEL NAG;So;0;L;;;;;N;;;;;\n0F20;TIBETAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n0F21;TIBETAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n0F22;TIBETAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n0F23;TIBETAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n0F24;TIBETAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n0F25;TIBETAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n0F26;TIBETAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n0F27;TIBETAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n0F28;TIBETAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n0F29;TIBETAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n0F2A;TIBETAN DIGIT HALF ONE;No;0;L;;;;1/2;N;;;;;\n0F2B;TIBETAN DIGIT HALF TWO;No;0;L;;;;3/2;N;;;;;\n0F2C;TIBETAN DIGIT HALF THREE;No;0;L;;;;5/2;N;;;;;\n0F2D;TIBETAN DIGIT HALF FOUR;No;0;L;;;;7/2;N;;;;;\n0F2E;TIBETAN DIGIT HALF FIVE;No;0;L;;;;9/2;N;;;;;\n0F2F;TIBETAN DIGIT HALF SIX;No;0;L;;;;11/2;N;;;;;\n0F30;TIBETAN DIGIT HALF SEVEN;No;0;L;;;;13/2;N;;;;;\n0F31;TIBETAN DIGIT HALF EIGHT;No;0;L;;;;15/2;N;;;;;\n0F32;TIBETAN DIGIT HALF NINE;No;0;L;;;;17/2;N;;;;;\n0F33;TIBETAN DIGIT HALF ZERO;No;0;L;;;;-1/2;N;;;;;\n0F34;TIBETAN MARK BSDUS RTAGS;So;0;L;;;;;N;;;;;\n0F35;TIBETAN MARK NGAS BZUNG NYI ZLA;Mn;220;NSM;;;;;N;TIBETAN HONORIFIC UNDER RING;;;;\n0F36;TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN;So;0;L;;;;;N;;;;;\n0F37;TIBETAN MARK NGAS BZUNG SGOR RTAGS;Mn;220;NSM;;;;;N;TIBETAN UNDER RING;;;;\n0F38;TIBETAN MARK CHE MGO;So;0;L;;;;;N;;;;;\n0F39;TIBETAN MARK TSA -PHRU;Mn;216;NSM;;;;;N;TIBETAN LENITION MARK;;;;\n0F3A;TIBETAN MARK GUG RTAGS GYON;Ps;0;ON;;;;;Y;;;;;\n0F3B;TIBETAN MARK GUG RTAGS GYAS;Pe;0;ON;;;;;Y;;;;;\n0F3C;TIBETAN MARK ANG KHANG GYON;Ps;0;ON;;;;;Y;TIBETAN LEFT BRACE;;;;\n0F3D;TIBETAN MARK ANG KHANG GYAS;Pe;0;ON;;;;;Y;TIBETAN RIGHT BRACE;;;;\n0F3E;TIBETAN SIGN YAR TSHES;Mc;0;L;;;;;N;;;;;\n0F3F;TIBETAN SIGN MAR TSHES;Mc;0;L;;;;;N;;;;;\n0F40;TIBETAN LETTER KA;Lo;0;L;;;;;N;;;;;\n0F41;TIBETAN LETTER KHA;Lo;0;L;;;;;N;;;;;\n0F42;TIBETAN LETTER GA;Lo;0;L;;;;;N;;;;;\n0F43;TIBETAN LETTER GHA;Lo;0;L;0F42 0FB7;;;;N;;;;;\n0F44;TIBETAN LETTER NGA;Lo;0;L;;;;;N;;;;;\n0F45;TIBETAN LETTER CA;Lo;0;L;;;;;N;;;;;\n0F46;TIBETAN LETTER CHA;Lo;0;L;;;;;N;;;;;\n0F47;TIBETAN LETTER JA;Lo;0;L;;;;;N;;;;;\n0F49;TIBETAN LETTER NYA;Lo;0;L;;;;;N;;;;;\n0F4A;TIBETAN LETTER TTA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED TA;;;;\n0F4B;TIBETAN LETTER TTHA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED THA;;;;\n0F4C;TIBETAN LETTER DDA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED DA;;;;\n0F4D;TIBETAN LETTER DDHA;Lo;0;L;0F4C 0FB7;;;;N;;;;;\n0F4E;TIBETAN LETTER NNA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED NA;;;;\n0F4F;TIBETAN LETTER TA;Lo;0;L;;;;;N;;;;;\n0F50;TIBETAN LETTER THA;Lo;0;L;;;;;N;;;;;\n0F51;TIBETAN LETTER DA;Lo;0;L;;;;;N;;;;;\n0F52;TIBETAN LETTER DHA;Lo;0;L;0F51 0FB7;;;;N;;;;;\n0F53;TIBETAN LETTER NA;Lo;0;L;;;;;N;;;;;\n0F54;TIBETAN LETTER PA;Lo;0;L;;;;;N;;;;;\n0F55;TIBETAN LETTER PHA;Lo;0;L;;;;;N;;;;;\n0F56;TIBETAN LETTER BA;Lo;0;L;;;;;N;;;;;\n0F57;TIBETAN LETTER BHA;Lo;0;L;0F56 0FB7;;;;N;;;;;\n0F58;TIBETAN LETTER MA;Lo;0;L;;;;;N;;;;;\n0F59;TIBETAN LETTER TSA;Lo;0;L;;;;;N;;;;;\n0F5A;TIBETAN LETTER TSHA;Lo;0;L;;;;;N;;;;;\n0F5B;TIBETAN LETTER DZA;Lo;0;L;;;;;N;;;;;\n0F5C;TIBETAN LETTER DZHA;Lo;0;L;0F5B 0FB7;;;;N;;;;;\n0F5D;TIBETAN LETTER WA;Lo;0;L;;;;;N;;;;;\n0F5E;TIBETAN LETTER ZHA;Lo;0;L;;;;;N;;;;;\n0F5F;TIBETAN LETTER ZA;Lo;0;L;;;;;N;;;;;\n0F60;TIBETAN LETTER -A;Lo;0;L;;;;;N;TIBETAN LETTER AA;;;;\n0F61;TIBETAN LETTER YA;Lo;0;L;;;;;N;;;;;\n0F62;TIBETAN LETTER RA;Lo;0;L;;;;;N;;;;;\n0F63;TIBETAN LETTER LA;Lo;0;L;;;;;N;;;;;\n0F64;TIBETAN LETTER SHA;Lo;0;L;;;;;N;;;;;\n0F65;TIBETAN LETTER SSA;Lo;0;L;;;;;N;TIBETAN LETTER REVERSED SHA;;;;\n0F66;TIBETAN LETTER SA;Lo;0;L;;;;;N;;;;;\n0F67;TIBETAN LETTER HA;Lo;0;L;;;;;N;;;;;\n0F68;TIBETAN LETTER A;Lo;0;L;;;;;N;;;;;\n0F69;TIBETAN LETTER KSSA;Lo;0;L;0F40 0FB5;;;;N;;;;;\n0F6A;TIBETAN LETTER FIXED-FORM RA;Lo;0;L;;;;;N;;;;;\n0F6B;TIBETAN LETTER KKA;Lo;0;L;;;;;N;;;;;\n0F6C;TIBETAN LETTER RRA;Lo;0;L;;;;;N;;;;;\n0F71;TIBETAN VOWEL SIGN AA;Mn;129;NSM;;;;;N;;;;;\n0F72;TIBETAN VOWEL SIGN I;Mn;130;NSM;;;;;N;;;;;\n0F73;TIBETAN VOWEL SIGN II;Mn;0;NSM;0F71 0F72;;;;N;;;;;\n0F74;TIBETAN VOWEL SIGN U;Mn;132;NSM;;;;;N;;;;;\n0F75;TIBETAN VOWEL SIGN UU;Mn;0;NSM;0F71 0F74;;;;N;;;;;\n0F76;TIBETAN VOWEL SIGN VOCALIC R;Mn;0;NSM;0FB2 0F80;;;;N;;;;;\n0F77;TIBETAN VOWEL SIGN VOCALIC RR;Mn;0;NSM;<compat> 0FB2 0F81;;;;N;;;;;\n0F78;TIBETAN VOWEL SIGN VOCALIC L;Mn;0;NSM;0FB3 0F80;;;;N;;;;;\n0F79;TIBETAN VOWEL SIGN VOCALIC LL;Mn;0;NSM;<compat> 0FB3 0F81;;;;N;;;;;\n0F7A;TIBETAN VOWEL SIGN E;Mn;130;NSM;;;;;N;;;;;\n0F7B;TIBETAN VOWEL SIGN EE;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AI;;;;\n0F7C;TIBETAN VOWEL SIGN O;Mn;130;NSM;;;;;N;;;;;\n0F7D;TIBETAN VOWEL SIGN OO;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN AU;;;;\n0F7E;TIBETAN SIGN RJES SU NGA RO;Mn;0;NSM;;;;;N;TIBETAN ANUSVARA;;;;\n0F7F;TIBETAN SIGN RNAM BCAD;Mc;0;L;;;;;N;TIBETAN VISARGA;;;;\n0F80;TIBETAN VOWEL SIGN REVERSED I;Mn;130;NSM;;;;;N;TIBETAN VOWEL SIGN SHORT I;;;;\n0F81;TIBETAN VOWEL SIGN REVERSED II;Mn;0;NSM;0F71 0F80;;;;N;;;;;\n0F82;TIBETAN SIGN NYI ZLA NAA DA;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU WITH ORNAMENT;;;;\n0F83;TIBETAN SIGN SNA LDAN;Mn;230;NSM;;;;;N;TIBETAN CANDRABINDU;;;;\n0F84;TIBETAN MARK HALANTA;Mn;9;NSM;;;;;N;TIBETAN VIRAMA;;;;\n0F85;TIBETAN MARK PALUTA;Po;0;L;;;;;N;TIBETAN CHUCHENYIGE;;;;\n0F86;TIBETAN SIGN LCI RTAGS;Mn;230;NSM;;;;;N;;;;;\n0F87;TIBETAN SIGN YANG RTAGS;Mn;230;NSM;;;;;N;;;;;\n0F88;TIBETAN SIGN LCE TSA CAN;Lo;0;L;;;;;N;;;;;\n0F89;TIBETAN SIGN MCHU CAN;Lo;0;L;;;;;N;;;;;\n0F8A;TIBETAN SIGN GRU CAN RGYINGS;Lo;0;L;;;;;N;;;;;\n0F8B;TIBETAN SIGN GRU MED RGYINGS;Lo;0;L;;;;;N;;;;;\n0F8C;TIBETAN SIGN INVERTED MCHU CAN;Lo;0;L;;;;;N;;;;;\n0F8D;TIBETAN SUBJOINED SIGN LCE TSA CAN;Mn;0;NSM;;;;;N;;;;;\n0F8E;TIBETAN SUBJOINED SIGN MCHU CAN;Mn;0;NSM;;;;;N;;;;;\n0F8F;TIBETAN SUBJOINED SIGN INVERTED MCHU CAN;Mn;0;NSM;;;;;N;;;;;\n0F90;TIBETAN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;;\n0F91;TIBETAN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;;\n0F92;TIBETAN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;;\n0F93;TIBETAN SUBJOINED LETTER GHA;Mn;0;NSM;0F92 0FB7;;;;N;;;;;\n0F94;TIBETAN SUBJOINED LETTER NGA;Mn;0;NSM;;;;;N;;;;;\n0F95;TIBETAN SUBJOINED LETTER CA;Mn;0;NSM;;;;;N;;;;;\n0F96;TIBETAN SUBJOINED LETTER CHA;Mn;0;NSM;;;;;N;;;;;\n0F97;TIBETAN SUBJOINED LETTER JA;Mn;0;NSM;;;;;N;;;;;\n0F99;TIBETAN SUBJOINED LETTER NYA;Mn;0;NSM;;;;;N;;;;;\n0F9A;TIBETAN SUBJOINED LETTER TTA;Mn;0;NSM;;;;;N;;;;;\n0F9B;TIBETAN SUBJOINED LETTER TTHA;Mn;0;NSM;;;;;N;;;;;\n0F9C;TIBETAN SUBJOINED LETTER DDA;Mn;0;NSM;;;;;N;;;;;\n0F9D;TIBETAN SUBJOINED LETTER DDHA;Mn;0;NSM;0F9C 0FB7;;;;N;;;;;\n0F9E;TIBETAN SUBJOINED LETTER NNA;Mn;0;NSM;;;;;N;;;;;\n0F9F;TIBETAN SUBJOINED LETTER TA;Mn;0;NSM;;;;;N;;;;;\n0FA0;TIBETAN SUBJOINED LETTER THA;Mn;0;NSM;;;;;N;;;;;\n0FA1;TIBETAN SUBJOINED LETTER DA;Mn;0;NSM;;;;;N;;;;;\n0FA2;TIBETAN SUBJOINED LETTER DHA;Mn;0;NSM;0FA1 0FB7;;;;N;;;;;\n0FA3;TIBETAN SUBJOINED LETTER NA;Mn;0;NSM;;;;;N;;;;;\n0FA4;TIBETAN SUBJOINED LETTER PA;Mn;0;NSM;;;;;N;;;;;\n0FA5;TIBETAN SUBJOINED LETTER PHA;Mn;0;NSM;;;;;N;;;;;\n0FA6;TIBETAN SUBJOINED LETTER BA;Mn;0;NSM;;;;;N;;;;;\n0FA7;TIBETAN SUBJOINED LETTER BHA;Mn;0;NSM;0FA6 0FB7;;;;N;;;;;\n0FA8;TIBETAN SUBJOINED LETTER MA;Mn;0;NSM;;;;;N;;;;;\n0FA9;TIBETAN SUBJOINED LETTER TSA;Mn;0;NSM;;;;;N;;;;;\n0FAA;TIBETAN SUBJOINED LETTER TSHA;Mn;0;NSM;;;;;N;;;;;\n0FAB;TIBETAN SUBJOINED LETTER DZA;Mn;0;NSM;;;;;N;;;;;\n0FAC;TIBETAN SUBJOINED LETTER DZHA;Mn;0;NSM;0FAB 0FB7;;;;N;;;;;\n0FAD;TIBETAN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;;;;\n0FAE;TIBETAN SUBJOINED LETTER ZHA;Mn;0;NSM;;;;;N;;;;;\n0FAF;TIBETAN SUBJOINED LETTER ZA;Mn;0;NSM;;;;;N;;;;;\n0FB0;TIBETAN SUBJOINED LETTER -A;Mn;0;NSM;;;;;N;;;;;\n0FB1;TIBETAN SUBJOINED LETTER YA;Mn;0;NSM;;;;;N;;;;;\n0FB2;TIBETAN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;;;;\n0FB3;TIBETAN SUBJOINED LETTER LA;Mn;0;NSM;;;;;N;;;;;\n0FB4;TIBETAN SUBJOINED LETTER SHA;Mn;0;NSM;;;;;N;;;;;\n0FB5;TIBETAN SUBJOINED LETTER SSA;Mn;0;NSM;;;;;N;;;;;\n0FB6;TIBETAN SUBJOINED LETTER SA;Mn;0;NSM;;;;;N;;;;;\n0FB7;TIBETAN SUBJOINED LETTER HA;Mn;0;NSM;;;;;N;;;;;\n0FB8;TIBETAN SUBJOINED LETTER A;Mn;0;NSM;;;;;N;;;;;\n0FB9;TIBETAN SUBJOINED LETTER KSSA;Mn;0;NSM;0F90 0FB5;;;;N;;;;;\n0FBA;TIBETAN SUBJOINED LETTER FIXED-FORM WA;Mn;0;NSM;;;;;N;;;;;\n0FBB;TIBETAN SUBJOINED LETTER FIXED-FORM YA;Mn;0;NSM;;;;;N;;;;;\n0FBC;TIBETAN SUBJOINED LETTER FIXED-FORM RA;Mn;0;NSM;;;;;N;;;;;\n0FBE;TIBETAN KU RU KHA;So;0;L;;;;;N;;;;;\n0FBF;TIBETAN KU RU KHA BZHI MIG CAN;So;0;L;;;;;N;;;;;\n0FC0;TIBETAN CANTILLATION SIGN HEAVY BEAT;So;0;L;;;;;N;;;;;\n0FC1;TIBETAN CANTILLATION SIGN LIGHT BEAT;So;0;L;;;;;N;;;;;\n0FC2;TIBETAN CANTILLATION SIGN CANG TE-U;So;0;L;;;;;N;;;;;\n0FC3;TIBETAN CANTILLATION SIGN SBUB -CHAL;So;0;L;;;;;N;;;;;\n0FC4;TIBETAN SYMBOL DRIL BU;So;0;L;;;;;N;;;;;\n0FC5;TIBETAN SYMBOL RDO RJE;So;0;L;;;;;N;;;;;\n0FC6;TIBETAN SYMBOL PADMA GDAN;Mn;220;NSM;;;;;N;;;;;\n0FC7;TIBETAN SYMBOL RDO RJE RGYA GRAM;So;0;L;;;;;N;;;;;\n0FC8;TIBETAN SYMBOL PHUR PA;So;0;L;;;;;N;;;;;\n0FC9;TIBETAN SYMBOL NOR BU;So;0;L;;;;;N;;;;;\n0FCA;TIBETAN SYMBOL NOR BU NYIS -KHYIL;So;0;L;;;;;N;;;;;\n0FCB;TIBETAN SYMBOL NOR BU GSUM -KHYIL;So;0;L;;;;;N;;;;;\n0FCC;TIBETAN SYMBOL NOR BU BZHI -KHYIL;So;0;L;;;;;N;;;;;\n0FCE;TIBETAN SIGN RDEL NAG RDEL DKAR;So;0;L;;;;;N;;;;;\n0FCF;TIBETAN SIGN RDEL NAG GSUM;So;0;L;;;;;N;;;;;\n0FD0;TIBETAN MARK BSKA- SHOG GI MGO RGYAN;Po;0;L;;;;;N;;;;;\n0FD1;TIBETAN MARK MNYAM YIG GI MGO RGYAN;Po;0;L;;;;;N;;;;;\n0FD2;TIBETAN MARK NYIS TSHEG;Po;0;L;;;;;N;;;;;\n0FD3;TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA;Po;0;L;;;;;N;;;;;\n0FD4;TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA;Po;0;L;;;;;N;;;;;\n0FD5;RIGHT-FACING SVASTI SIGN;So;0;L;;;;;N;;;;;\n0FD6;LEFT-FACING SVASTI SIGN;So;0;L;;;;;N;;;;;\n0FD7;RIGHT-FACING SVASTI SIGN WITH DOTS;So;0;L;;;;;N;;;;;\n0FD8;LEFT-FACING SVASTI SIGN WITH DOTS;So;0;L;;;;;N;;;;;\n0FD9;TIBETAN MARK LEADING MCHAN RTAGS;Po;0;L;;;;;N;;;;;\n0FDA;TIBETAN MARK TRAILING MCHAN RTAGS;Po;0;L;;;;;N;;;;;\n1000;MYANMAR LETTER KA;Lo;0;L;;;;;N;;;;;\n1001;MYANMAR LETTER KHA;Lo;0;L;;;;;N;;;;;\n1002;MYANMAR LETTER GA;Lo;0;L;;;;;N;;;;;\n1003;MYANMAR LETTER GHA;Lo;0;L;;;;;N;;;;;\n1004;MYANMAR LETTER NGA;Lo;0;L;;;;;N;;;;;\n1005;MYANMAR LETTER CA;Lo;0;L;;;;;N;;;;;\n1006;MYANMAR LETTER CHA;Lo;0;L;;;;;N;;;;;\n1007;MYANMAR LETTER JA;Lo;0;L;;;;;N;;;;;\n1008;MYANMAR LETTER JHA;Lo;0;L;;;;;N;;;;;\n1009;MYANMAR LETTER NYA;Lo;0;L;;;;;N;;;;;\n100A;MYANMAR LETTER NNYA;Lo;0;L;;;;;N;;;;;\n100B;MYANMAR LETTER TTA;Lo;0;L;;;;;N;;;;;\n100C;MYANMAR LETTER TTHA;Lo;0;L;;;;;N;;;;;\n100D;MYANMAR LETTER DDA;Lo;0;L;;;;;N;;;;;\n100E;MYANMAR LETTER DDHA;Lo;0;L;;;;;N;;;;;\n100F;MYANMAR LETTER NNA;Lo;0;L;;;;;N;;;;;\n1010;MYANMAR LETTER TA;Lo;0;L;;;;;N;;;;;\n1011;MYANMAR LETTER THA;Lo;0;L;;;;;N;;;;;\n1012;MYANMAR LETTER DA;Lo;0;L;;;;;N;;;;;\n1013;MYANMAR LETTER DHA;Lo;0;L;;;;;N;;;;;\n1014;MYANMAR LETTER NA;Lo;0;L;;;;;N;;;;;\n1015;MYANMAR LETTER PA;Lo;0;L;;;;;N;;;;;\n1016;MYANMAR LETTER PHA;Lo;0;L;;;;;N;;;;;\n1017;MYANMAR LETTER BA;Lo;0;L;;;;;N;;;;;\n1018;MYANMAR LETTER BHA;Lo;0;L;;;;;N;;;;;\n1019;MYANMAR LETTER MA;Lo;0;L;;;;;N;;;;;\n101A;MYANMAR LETTER YA;Lo;0;L;;;;;N;;;;;\n101B;MYANMAR LETTER RA;Lo;0;L;;;;;N;;;;;\n101C;MYANMAR LETTER LA;Lo;0;L;;;;;N;;;;;\n101D;MYANMAR LETTER WA;Lo;0;L;;;;;N;;;;;\n101E;MYANMAR LETTER SA;Lo;0;L;;;;;N;;;;;\n101F;MYANMAR LETTER HA;Lo;0;L;;;;;N;;;;;\n1020;MYANMAR LETTER LLA;Lo;0;L;;;;;N;;;;;\n1021;MYANMAR LETTER A;Lo;0;L;;;;;N;;;;;\n1022;MYANMAR LETTER SHAN A;Lo;0;L;;;;;N;;;;;\n1023;MYANMAR LETTER I;Lo;0;L;;;;;N;;;;;\n1024;MYANMAR LETTER II;Lo;0;L;;;;;N;;;;;\n1025;MYANMAR LETTER U;Lo;0;L;;;;;N;;;;;\n1026;MYANMAR LETTER UU;Lo;0;L;1025 102E;;;;N;;;;;\n1027;MYANMAR LETTER E;Lo;0;L;;;;;N;;;;;\n1028;MYANMAR LETTER MON E;Lo;0;L;;;;;N;;;;;\n1029;MYANMAR LETTER O;Lo;0;L;;;;;N;;;;;\n102A;MYANMAR LETTER AU;Lo;0;L;;;;;N;;;;;\n102B;MYANMAR VOWEL SIGN TALL AA;Mc;0;L;;;;;N;;;;;\n102C;MYANMAR VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n102D;MYANMAR VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n102E;MYANMAR VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;\n102F;MYANMAR VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n1030;MYANMAR VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n1031;MYANMAR VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\n1032;MYANMAR VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n1033;MYANMAR VOWEL SIGN MON II;Mn;0;NSM;;;;;N;;;;;\n1034;MYANMAR VOWEL SIGN MON O;Mn;0;NSM;;;;;N;;;;;\n1035;MYANMAR VOWEL SIGN E ABOVE;Mn;0;NSM;;;;;N;;;;;\n1036;MYANMAR SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n1037;MYANMAR SIGN DOT BELOW;Mn;7;NSM;;;;;N;;;;;\n1038;MYANMAR SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n1039;MYANMAR SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n103A;MYANMAR SIGN ASAT;Mn;9;NSM;;;;;N;;;;;\n103B;MYANMAR CONSONANT SIGN MEDIAL YA;Mc;0;L;;;;;N;;;;;\n103C;MYANMAR CONSONANT SIGN MEDIAL RA;Mc;0;L;;;;;N;;;;;\n103D;MYANMAR CONSONANT SIGN MEDIAL WA;Mn;0;NSM;;;;;N;;;;;\n103E;MYANMAR CONSONANT SIGN MEDIAL HA;Mn;0;NSM;;;;;N;;;;;\n103F;MYANMAR LETTER GREAT SA;Lo;0;L;;;;;N;;;;;\n1040;MYANMAR DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n1041;MYANMAR DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n1042;MYANMAR DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n1043;MYANMAR DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n1044;MYANMAR DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n1045;MYANMAR DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n1046;MYANMAR DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n1047;MYANMAR DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n1048;MYANMAR DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n1049;MYANMAR DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n104A;MYANMAR SIGN LITTLE SECTION;Po;0;L;;;;;N;;;;;\n104B;MYANMAR SIGN SECTION;Po;0;L;;;;;N;;;;;\n104C;MYANMAR SYMBOL LOCATIVE;Po;0;L;;;;;N;;;;;\n104D;MYANMAR SYMBOL COMPLETED;Po;0;L;;;;;N;;;;;\n104E;MYANMAR SYMBOL AFOREMENTIONED;Po;0;L;;;;;N;;;;;\n104F;MYANMAR SYMBOL GENITIVE;Po;0;L;;;;;N;;;;;\n1050;MYANMAR LETTER SHA;Lo;0;L;;;;;N;;;;;\n1051;MYANMAR LETTER SSA;Lo;0;L;;;;;N;;;;;\n1052;MYANMAR LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n1053;MYANMAR LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n1054;MYANMAR LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n1055;MYANMAR LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\n1056;MYANMAR VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;\n1057;MYANMAR VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;\n1058;MYANMAR VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;\n1059;MYANMAR VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;\n105A;MYANMAR LETTER MON NGA;Lo;0;L;;;;;N;;;;;\n105B;MYANMAR LETTER MON JHA;Lo;0;L;;;;;N;;;;;\n105C;MYANMAR LETTER MON BBA;Lo;0;L;;;;;N;;;;;\n105D;MYANMAR LETTER MON BBE;Lo;0;L;;;;;N;;;;;\n105E;MYANMAR CONSONANT SIGN MON MEDIAL NA;Mn;0;NSM;;;;;N;;;;;\n105F;MYANMAR CONSONANT SIGN MON MEDIAL MA;Mn;0;NSM;;;;;N;;;;;\n1060;MYANMAR CONSONANT SIGN MON MEDIAL LA;Mn;0;NSM;;;;;N;;;;;\n1061;MYANMAR LETTER SGAW KAREN SHA;Lo;0;L;;;;;N;;;;;\n1062;MYANMAR VOWEL SIGN SGAW KAREN EU;Mc;0;L;;;;;N;;;;;\n1063;MYANMAR TONE MARK SGAW KAREN HATHI;Mc;0;L;;;;;N;;;;;\n1064;MYANMAR TONE MARK SGAW KAREN KE PHO;Mc;0;L;;;;;N;;;;;\n1065;MYANMAR LETTER WESTERN PWO KAREN THA;Lo;0;L;;;;;N;;;;;\n1066;MYANMAR LETTER WESTERN PWO KAREN PWA;Lo;0;L;;;;;N;;;;;\n1067;MYANMAR VOWEL SIGN WESTERN PWO KAREN EU;Mc;0;L;;;;;N;;;;;\n1068;MYANMAR VOWEL SIGN WESTERN PWO KAREN UE;Mc;0;L;;;;;N;;;;;\n1069;MYANMAR SIGN WESTERN PWO KAREN TONE-1;Mc;0;L;;;;;N;;;;;\n106A;MYANMAR SIGN WESTERN PWO KAREN TONE-2;Mc;0;L;;;;;N;;;;;\n106B;MYANMAR SIGN WESTERN PWO KAREN TONE-3;Mc;0;L;;;;;N;;;;;\n106C;MYANMAR SIGN WESTERN PWO KAREN TONE-4;Mc;0;L;;;;;N;;;;;\n106D;MYANMAR SIGN WESTERN PWO KAREN TONE-5;Mc;0;L;;;;;N;;;;;\n106E;MYANMAR LETTER EASTERN PWO KAREN NNA;Lo;0;L;;;;;N;;;;;\n106F;MYANMAR LETTER EASTERN PWO KAREN YWA;Lo;0;L;;;;;N;;;;;\n1070;MYANMAR LETTER EASTERN PWO KAREN GHWA;Lo;0;L;;;;;N;;;;;\n1071;MYANMAR VOWEL SIGN GEBA KAREN I;Mn;0;NSM;;;;;N;;;;;\n1072;MYANMAR VOWEL SIGN KAYAH OE;Mn;0;NSM;;;;;N;;;;;\n1073;MYANMAR VOWEL SIGN KAYAH U;Mn;0;NSM;;;;;N;;;;;\n1074;MYANMAR VOWEL SIGN KAYAH EE;Mn;0;NSM;;;;;N;;;;;\n1075;MYANMAR LETTER SHAN KA;Lo;0;L;;;;;N;;;;;\n1076;MYANMAR LETTER SHAN KHA;Lo;0;L;;;;;N;;;;;\n1077;MYANMAR LETTER SHAN GA;Lo;0;L;;;;;N;;;;;\n1078;MYANMAR LETTER SHAN CA;Lo;0;L;;;;;N;;;;;\n1079;MYANMAR LETTER SHAN ZA;Lo;0;L;;;;;N;;;;;\n107A;MYANMAR LETTER SHAN NYA;Lo;0;L;;;;;N;;;;;\n107B;MYANMAR LETTER SHAN DA;Lo;0;L;;;;;N;;;;;\n107C;MYANMAR LETTER SHAN NA;Lo;0;L;;;;;N;;;;;\n107D;MYANMAR LETTER SHAN PHA;Lo;0;L;;;;;N;;;;;\n107E;MYANMAR LETTER SHAN FA;Lo;0;L;;;;;N;;;;;\n107F;MYANMAR LETTER SHAN BA;Lo;0;L;;;;;N;;;;;\n1080;MYANMAR LETTER SHAN THA;Lo;0;L;;;;;N;;;;;\n1081;MYANMAR LETTER SHAN HA;Lo;0;L;;;;;N;;;;;\n1082;MYANMAR CONSONANT SIGN SHAN MEDIAL WA;Mn;0;NSM;;;;;N;;;;;\n1083;MYANMAR VOWEL SIGN SHAN AA;Mc;0;L;;;;;N;;;;;\n1084;MYANMAR VOWEL SIGN SHAN E;Mc;0;L;;;;;N;;;;;\n1085;MYANMAR VOWEL SIGN SHAN E ABOVE;Mn;0;NSM;;;;;N;;;;;\n1086;MYANMAR VOWEL SIGN SHAN FINAL Y;Mn;0;NSM;;;;;N;;;;;\n1087;MYANMAR SIGN SHAN TONE-2;Mc;0;L;;;;;N;;;;;\n1088;MYANMAR SIGN SHAN TONE-3;Mc;0;L;;;;;N;;;;;\n1089;MYANMAR SIGN SHAN TONE-5;Mc;0;L;;;;;N;;;;;\n108A;MYANMAR SIGN SHAN TONE-6;Mc;0;L;;;;;N;;;;;\n108B;MYANMAR SIGN SHAN COUNCIL TONE-2;Mc;0;L;;;;;N;;;;;\n108C;MYANMAR SIGN SHAN COUNCIL TONE-3;Mc;0;L;;;;;N;;;;;\n108D;MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE;Mn;220;NSM;;;;;N;;;;;\n108E;MYANMAR LETTER RUMAI PALAUNG FA;Lo;0;L;;;;;N;;;;;\n108F;MYANMAR SIGN RUMAI PALAUNG TONE-5;Mc;0;L;;;;;N;;;;;\n1090;MYANMAR SHAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n1091;MYANMAR SHAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n1092;MYANMAR SHAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n1093;MYANMAR SHAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n1094;MYANMAR SHAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n1095;MYANMAR SHAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n1096;MYANMAR SHAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n1097;MYANMAR SHAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n1098;MYANMAR SHAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n1099;MYANMAR SHAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n109A;MYANMAR SIGN KHAMTI TONE-1;Mc;0;L;;;;;N;;;;;\n109B;MYANMAR SIGN KHAMTI TONE-3;Mc;0;L;;;;;N;;;;;\n109C;MYANMAR VOWEL SIGN AITON A;Mc;0;L;;;;;N;;;;;\n109D;MYANMAR VOWEL SIGN AITON AI;Mn;0;NSM;;;;;N;;;;;\n109E;MYANMAR SYMBOL SHAN ONE;So;0;L;;;;;N;;;;;\n109F;MYANMAR SYMBOL SHAN EXCLAMATION;So;0;L;;;;;N;;;;;\n10A0;GEORGIAN CAPITAL LETTER AN;Lu;0;L;;;;;N;;;;2D00;\n10A1;GEORGIAN CAPITAL LETTER BAN;Lu;0;L;;;;;N;;;;2D01;\n10A2;GEORGIAN CAPITAL LETTER GAN;Lu;0;L;;;;;N;;;;2D02;\n10A3;GEORGIAN CAPITAL LETTER DON;Lu;0;L;;;;;N;;;;2D03;\n10A4;GEORGIAN CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;2D04;\n10A5;GEORGIAN CAPITAL LETTER VIN;Lu;0;L;;;;;N;;;;2D05;\n10A6;GEORGIAN CAPITAL LETTER ZEN;Lu;0;L;;;;;N;;;;2D06;\n10A7;GEORGIAN CAPITAL LETTER TAN;Lu;0;L;;;;;N;;;;2D07;\n10A8;GEORGIAN CAPITAL LETTER IN;Lu;0;L;;;;;N;;;;2D08;\n10A9;GEORGIAN CAPITAL LETTER KAN;Lu;0;L;;;;;N;;;;2D09;\n10AA;GEORGIAN CAPITAL LETTER LAS;Lu;0;L;;;;;N;;;;2D0A;\n10AB;GEORGIAN CAPITAL LETTER MAN;Lu;0;L;;;;;N;;;;2D0B;\n10AC;GEORGIAN CAPITAL LETTER NAR;Lu;0;L;;;;;N;;;;2D0C;\n10AD;GEORGIAN CAPITAL LETTER ON;Lu;0;L;;;;;N;;;;2D0D;\n10AE;GEORGIAN CAPITAL LETTER PAR;Lu;0;L;;;;;N;;;;2D0E;\n10AF;GEORGIAN CAPITAL LETTER ZHAR;Lu;0;L;;;;;N;;;;2D0F;\n10B0;GEORGIAN CAPITAL LETTER RAE;Lu;0;L;;;;;N;;;;2D10;\n10B1;GEORGIAN CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;2D11;\n10B2;GEORGIAN CAPITAL LETTER TAR;Lu;0;L;;;;;N;;;;2D12;\n10B3;GEORGIAN CAPITAL LETTER UN;Lu;0;L;;;;;N;;;;2D13;\n10B4;GEORGIAN CAPITAL LETTER PHAR;Lu;0;L;;;;;N;;;;2D14;\n10B5;GEORGIAN CAPITAL LETTER KHAR;Lu;0;L;;;;;N;;;;2D15;\n10B6;GEORGIAN CAPITAL LETTER GHAN;Lu;0;L;;;;;N;;;;2D16;\n10B7;GEORGIAN CAPITAL LETTER QAR;Lu;0;L;;;;;N;;;;2D17;\n10B8;GEORGIAN CAPITAL LETTER SHIN;Lu;0;L;;;;;N;;;;2D18;\n10B9;GEORGIAN CAPITAL LETTER CHIN;Lu;0;L;;;;;N;;;;2D19;\n10BA;GEORGIAN CAPITAL LETTER CAN;Lu;0;L;;;;;N;;;;2D1A;\n10BB;GEORGIAN CAPITAL LETTER JIL;Lu;0;L;;;;;N;;;;2D1B;\n10BC;GEORGIAN CAPITAL LETTER CIL;Lu;0;L;;;;;N;;;;2D1C;\n10BD;GEORGIAN CAPITAL LETTER CHAR;Lu;0;L;;;;;N;;;;2D1D;\n10BE;GEORGIAN CAPITAL LETTER XAN;Lu;0;L;;;;;N;;;;2D1E;\n10BF;GEORGIAN CAPITAL LETTER JHAN;Lu;0;L;;;;;N;;;;2D1F;\n10C0;GEORGIAN CAPITAL LETTER HAE;Lu;0;L;;;;;N;;;;2D20;\n10C1;GEORGIAN CAPITAL LETTER HE;Lu;0;L;;;;;N;;;;2D21;\n10C2;GEORGIAN CAPITAL LETTER HIE;Lu;0;L;;;;;N;;;;2D22;\n10C3;GEORGIAN CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;2D23;\n10C4;GEORGIAN CAPITAL LETTER HAR;Lu;0;L;;;;;N;;;;2D24;\n10C5;GEORGIAN CAPITAL LETTER HOE;Lu;0;L;;;;;N;;;;2D25;\n10C7;GEORGIAN CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;2D27;\n10CD;GEORGIAN CAPITAL LETTER AEN;Lu;0;L;;;;;N;;;;2D2D;\n10D0;GEORGIAN LETTER AN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER AN;;1C90;;10D0\n10D1;GEORGIAN LETTER BAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER BAN;;1C91;;10D1\n10D2;GEORGIAN LETTER GAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER GAN;;1C92;;10D2\n10D3;GEORGIAN LETTER DON;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER DON;;1C93;;10D3\n10D4;GEORGIAN LETTER EN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER EN;;1C94;;10D4\n10D5;GEORGIAN LETTER VIN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER VIN;;1C95;;10D5\n10D6;GEORGIAN LETTER ZEN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER ZEN;;1C96;;10D6\n10D7;GEORGIAN LETTER TAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER TAN;;1C97;;10D7\n10D8;GEORGIAN LETTER IN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER IN;;1C98;;10D8\n10D9;GEORGIAN LETTER KAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER KAN;;1C99;;10D9\n10DA;GEORGIAN LETTER LAS;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER LAS;;1C9A;;10DA\n10DB;GEORGIAN LETTER MAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER MAN;;1C9B;;10DB\n10DC;GEORGIAN LETTER NAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER NAR;;1C9C;;10DC\n10DD;GEORGIAN LETTER ON;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER ON;;1C9D;;10DD\n10DE;GEORGIAN LETTER PAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER PAR;;1C9E;;10DE\n10DF;GEORGIAN LETTER ZHAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER ZHAR;;1C9F;;10DF\n10E0;GEORGIAN LETTER RAE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER RAE;;1CA0;;10E0\n10E1;GEORGIAN LETTER SAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER SAN;;1CA1;;10E1\n10E2;GEORGIAN LETTER TAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER TAR;;1CA2;;10E2\n10E3;GEORGIAN LETTER UN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER UN;;1CA3;;10E3\n10E4;GEORGIAN LETTER PHAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER PHAR;;1CA4;;10E4\n10E5;GEORGIAN LETTER KHAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER KHAR;;1CA5;;10E5\n10E6;GEORGIAN LETTER GHAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER GHAN;;1CA6;;10E6\n10E7;GEORGIAN LETTER QAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER QAR;;1CA7;;10E7\n10E8;GEORGIAN LETTER SHIN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER SHIN;;1CA8;;10E8\n10E9;GEORGIAN LETTER CHIN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER CHIN;;1CA9;;10E9\n10EA;GEORGIAN LETTER CAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER CAN;;1CAA;;10EA\n10EB;GEORGIAN LETTER JIL;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER JIL;;1CAB;;10EB\n10EC;GEORGIAN LETTER CIL;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER CIL;;1CAC;;10EC\n10ED;GEORGIAN LETTER CHAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER CHAR;;1CAD;;10ED\n10EE;GEORGIAN LETTER XAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER XAN;;1CAE;;10EE\n10EF;GEORGIAN LETTER JHAN;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER JHAN;;1CAF;;10EF\n10F0;GEORGIAN LETTER HAE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER HAE;;1CB0;;10F0\n10F1;GEORGIAN LETTER HE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER HE;;1CB1;;10F1\n10F2;GEORGIAN LETTER HIE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER HIE;;1CB2;;10F2\n10F3;GEORGIAN LETTER WE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER WE;;1CB3;;10F3\n10F4;GEORGIAN LETTER HAR;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER HAR;;1CB4;;10F4\n10F5;GEORGIAN LETTER HOE;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER HOE;;1CB5;;10F5\n10F6;GEORGIAN LETTER FI;Ll;0;L;;;;;N;GEORGIAN SMALL LETTER FI;;1CB6;;10F6\n10F7;GEORGIAN LETTER YN;Ll;0;L;;;;;N;;;1CB7;;10F7\n10F8;GEORGIAN LETTER ELIFI;Ll;0;L;;;;;N;;;1CB8;;10F8\n10F9;GEORGIAN LETTER TURNED GAN;Ll;0;L;;;;;N;;;1CB9;;10F9\n10FA;GEORGIAN LETTER AIN;Ll;0;L;;;;;N;;;1CBA;;10FA\n10FB;GEORGIAN PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;;\n10FC;MODIFIER LETTER GEORGIAN NAR;Lm;0;L;<super> 10DC;;;;N;;;;;\n10FD;GEORGIAN LETTER AEN;Ll;0;L;;;;;N;;;1CBD;;10FD\n10FE;GEORGIAN LETTER HARD SIGN;Ll;0;L;;;;;N;;;1CBE;;10FE\n10FF;GEORGIAN LETTER LABIAL SIGN;Ll;0;L;;;;;N;;;1CBF;;10FF\n1100;HANGUL CHOSEONG KIYEOK;Lo;0;L;;;;;N;;;;;\n1101;HANGUL CHOSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;;;;\n1102;HANGUL CHOSEONG NIEUN;Lo;0;L;;;;;N;;;;;\n1103;HANGUL CHOSEONG TIKEUT;Lo;0;L;;;;;N;;;;;\n1104;HANGUL CHOSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;;;;\n1105;HANGUL CHOSEONG RIEUL;Lo;0;L;;;;;N;;;;;\n1106;HANGUL CHOSEONG MIEUM;Lo;0;L;;;;;N;;;;;\n1107;HANGUL CHOSEONG PIEUP;Lo;0;L;;;;;N;;;;;\n1108;HANGUL CHOSEONG SSANGPIEUP;Lo;0;L;;;;;N;;;;;\n1109;HANGUL CHOSEONG SIOS;Lo;0;L;;;;;N;;;;;\n110A;HANGUL CHOSEONG SSANGSIOS;Lo;0;L;;;;;N;;;;;\n110B;HANGUL CHOSEONG IEUNG;Lo;0;L;;;;;N;;;;;\n110C;HANGUL CHOSEONG CIEUC;Lo;0;L;;;;;N;;;;;\n110D;HANGUL CHOSEONG SSANGCIEUC;Lo;0;L;;;;;N;;;;;\n110E;HANGUL CHOSEONG CHIEUCH;Lo;0;L;;;;;N;;;;;\n110F;HANGUL CHOSEONG KHIEUKH;Lo;0;L;;;;;N;;;;;\n1110;HANGUL CHOSEONG THIEUTH;Lo;0;L;;;;;N;;;;;\n1111;HANGUL CHOSEONG PHIEUPH;Lo;0;L;;;;;N;;;;;\n1112;HANGUL CHOSEONG HIEUH;Lo;0;L;;;;;N;;;;;\n1113;HANGUL CHOSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;;\n1114;HANGUL CHOSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;;\n1115;HANGUL CHOSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;;\n1116;HANGUL CHOSEONG NIEUN-PIEUP;Lo;0;L;;;;;N;;;;;\n1117;HANGUL CHOSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;;\n1118;HANGUL CHOSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;;\n1119;HANGUL CHOSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;;\n111A;HANGUL CHOSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;;\n111B;HANGUL CHOSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;;\n111C;HANGUL CHOSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;;\n111D;HANGUL CHOSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;;\n111E;HANGUL CHOSEONG PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;;\n111F;HANGUL CHOSEONG PIEUP-NIEUN;Lo;0;L;;;;;N;;;;;\n1120;HANGUL CHOSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;;\n1121;HANGUL CHOSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;;\n1122;HANGUL CHOSEONG PIEUP-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;\n1123;HANGUL CHOSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;\n1124;HANGUL CHOSEONG PIEUP-SIOS-PIEUP;Lo;0;L;;;;;N;;;;;\n1125;HANGUL CHOSEONG PIEUP-SSANGSIOS;Lo;0;L;;;;;N;;;;;\n1126;HANGUL CHOSEONG PIEUP-SIOS-CIEUC;Lo;0;L;;;;;N;;;;;\n1127;HANGUL CHOSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;;\n1128;HANGUL CHOSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;;\n1129;HANGUL CHOSEONG PIEUP-THIEUTH;Lo;0;L;;;;;N;;;;;\n112A;HANGUL CHOSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;;\n112B;HANGUL CHOSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;\n112C;HANGUL CHOSEONG KAPYEOUNSSANGPIEUP;Lo;0;L;;;;;N;;;;;\n112D;HANGUL CHOSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;\n112E;HANGUL CHOSEONG SIOS-NIEUN;Lo;0;L;;;;;N;;;;;\n112F;HANGUL CHOSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;\n1130;HANGUL CHOSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;;\n1131;HANGUL CHOSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;;\n1132;HANGUL CHOSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;;\n1133;HANGUL CHOSEONG SIOS-PIEUP-KIYEOK;Lo;0;L;;;;;N;;;;;\n1134;HANGUL CHOSEONG SIOS-SSANGSIOS;Lo;0;L;;;;;N;;;;;\n1135;HANGUL CHOSEONG SIOS-IEUNG;Lo;0;L;;;;;N;;;;;\n1136;HANGUL CHOSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;;\n1137;HANGUL CHOSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;;\n1138;HANGUL CHOSEONG SIOS-KHIEUKH;Lo;0;L;;;;;N;;;;;\n1139;HANGUL CHOSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;;\n113A;HANGUL CHOSEONG SIOS-PHIEUPH;Lo;0;L;;;;;N;;;;;\n113B;HANGUL CHOSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;;\n113C;HANGUL CHOSEONG CHITUEUMSIOS;Lo;0;L;;;;;N;;;;;\n113D;HANGUL CHOSEONG CHITUEUMSSANGSIOS;Lo;0;L;;;;;N;;;;;\n113E;HANGUL CHOSEONG CEONGCHIEUMSIOS;Lo;0;L;;;;;N;;;;;\n113F;HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS;Lo;0;L;;;;;N;;;;;\n1140;HANGUL CHOSEONG PANSIOS;Lo;0;L;;;;;N;;;;;\n1141;HANGUL CHOSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;;\n1142;HANGUL CHOSEONG IEUNG-TIKEUT;Lo;0;L;;;;;N;;;;;\n1143;HANGUL CHOSEONG IEUNG-MIEUM;Lo;0;L;;;;;N;;;;;\n1144;HANGUL CHOSEONG IEUNG-PIEUP;Lo;0;L;;;;;N;;;;;\n1145;HANGUL CHOSEONG IEUNG-SIOS;Lo;0;L;;;;;N;;;;;\n1146;HANGUL CHOSEONG IEUNG-PANSIOS;Lo;0;L;;;;;N;;;;;\n1147;HANGUL CHOSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;;\n1148;HANGUL CHOSEONG IEUNG-CIEUC;Lo;0;L;;;;;N;;;;;\n1149;HANGUL CHOSEONG IEUNG-CHIEUCH;Lo;0;L;;;;;N;;;;;\n114A;HANGUL CHOSEONG IEUNG-THIEUTH;Lo;0;L;;;;;N;;;;;\n114B;HANGUL CHOSEONG IEUNG-PHIEUPH;Lo;0;L;;;;;N;;;;;\n114C;HANGUL CHOSEONG YESIEUNG;Lo;0;L;;;;;N;;;;;\n114D;HANGUL CHOSEONG CIEUC-IEUNG;Lo;0;L;;;;;N;;;;;\n114E;HANGUL CHOSEONG CHITUEUMCIEUC;Lo;0;L;;;;;N;;;;;\n114F;HANGUL CHOSEONG CHITUEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;;\n1150;HANGUL CHOSEONG CEONGCHIEUMCIEUC;Lo;0;L;;;;;N;;;;;\n1151;HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC;Lo;0;L;;;;;N;;;;;\n1152;HANGUL CHOSEONG CHIEUCH-KHIEUKH;Lo;0;L;;;;;N;;;;;\n1153;HANGUL CHOSEONG CHIEUCH-HIEUH;Lo;0;L;;;;;N;;;;;\n1154;HANGUL CHOSEONG CHITUEUMCHIEUCH;Lo;0;L;;;;;N;;;;;\n1155;HANGUL CHOSEONG CEONGCHIEUMCHIEUCH;Lo;0;L;;;;;N;;;;;\n1156;HANGUL CHOSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;;\n1157;HANGUL CHOSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;;\n1158;HANGUL CHOSEONG SSANGHIEUH;Lo;0;L;;;;;N;;;;;\n1159;HANGUL CHOSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;;\n115A;HANGUL CHOSEONG KIYEOK-TIKEUT;Lo;0;L;;;;;N;;;;;\n115B;HANGUL CHOSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;;\n115C;HANGUL CHOSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;;;;\n115D;HANGUL CHOSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;;;;\n115E;HANGUL CHOSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;;\n115F;HANGUL CHOSEONG FILLER;Lo;0;L;;;;;N;;;;;\n1160;HANGUL JUNGSEONG FILLER;Lo;0;L;;;;;N;;;;;\n1161;HANGUL JUNGSEONG A;Lo;0;L;;;;;N;;;;;\n1162;HANGUL JUNGSEONG AE;Lo;0;L;;;;;N;;;;;\n1163;HANGUL JUNGSEONG YA;Lo;0;L;;;;;N;;;;;\n1164;HANGUL JUNGSEONG YAE;Lo;0;L;;;;;N;;;;;\n1165;HANGUL JUNGSEONG EO;Lo;0;L;;;;;N;;;;;\n1166;HANGUL JUNGSEONG E;Lo;0;L;;;;;N;;;;;\n1167;HANGUL JUNGSEONG YEO;Lo;0;L;;;;;N;;;;;\n1168;HANGUL JUNGSEONG YE;Lo;0;L;;;;;N;;;;;\n1169;HANGUL JUNGSEONG O;Lo;0;L;;;;;N;;;;;\n116A;HANGUL JUNGSEONG WA;Lo;0;L;;;;;N;;;;;\n116B;HANGUL JUNGSEONG WAE;Lo;0;L;;;;;N;;;;;\n116C;HANGUL JUNGSEONG OE;Lo;0;L;;;;;N;;;;;\n116D;HANGUL JUNGSEONG YO;Lo;0;L;;;;;N;;;;;\n116E;HANGUL JUNGSEONG U;Lo;0;L;;;;;N;;;;;\n116F;HANGUL JUNGSEONG WEO;Lo;0;L;;;;;N;;;;;\n1170;HANGUL JUNGSEONG WE;Lo;0;L;;;;;N;;;;;\n1171;HANGUL JUNGSEONG WI;Lo;0;L;;;;;N;;;;;\n1172;HANGUL JUNGSEONG YU;Lo;0;L;;;;;N;;;;;\n1173;HANGUL JUNGSEONG EU;Lo;0;L;;;;;N;;;;;\n1174;HANGUL JUNGSEONG YI;Lo;0;L;;;;;N;;;;;\n1175;HANGUL JUNGSEONG I;Lo;0;L;;;;;N;;;;;\n1176;HANGUL JUNGSEONG A-O;Lo;0;L;;;;;N;;;;;\n1177;HANGUL JUNGSEONG A-U;Lo;0;L;;;;;N;;;;;\n1178;HANGUL JUNGSEONG YA-O;Lo;0;L;;;;;N;;;;;\n1179;HANGUL JUNGSEONG YA-YO;Lo;0;L;;;;;N;;;;;\n117A;HANGUL JUNGSEONG EO-O;Lo;0;L;;;;;N;;;;;\n117B;HANGUL JUNGSEONG EO-U;Lo;0;L;;;;;N;;;;;\n117C;HANGUL JUNGSEONG EO-EU;Lo;0;L;;;;;N;;;;;\n117D;HANGUL JUNGSEONG YEO-O;Lo;0;L;;;;;N;;;;;\n117E;HANGUL JUNGSEONG YEO-U;Lo;0;L;;;;;N;;;;;\n117F;HANGUL JUNGSEONG O-EO;Lo;0;L;;;;;N;;;;;\n1180;HANGUL JUNGSEONG O-E;Lo;0;L;;;;;N;;;;;\n1181;HANGUL JUNGSEONG O-YE;Lo;0;L;;;;;N;;;;;\n1182;HANGUL JUNGSEONG O-O;Lo;0;L;;;;;N;;;;;\n1183;HANGUL JUNGSEONG O-U;Lo;0;L;;;;;N;;;;;\n1184;HANGUL JUNGSEONG YO-YA;Lo;0;L;;;;;N;;;;;\n1185;HANGUL JUNGSEONG YO-YAE;Lo;0;L;;;;;N;;;;;\n1186;HANGUL JUNGSEONG YO-YEO;Lo;0;L;;;;;N;;;;;\n1187;HANGUL JUNGSEONG YO-O;Lo;0;L;;;;;N;;;;;\n1188;HANGUL JUNGSEONG YO-I;Lo;0;L;;;;;N;;;;;\n1189;HANGUL JUNGSEONG U-A;Lo;0;L;;;;;N;;;;;\n118A;HANGUL JUNGSEONG U-AE;Lo;0;L;;;;;N;;;;;\n118B;HANGUL JUNGSEONG U-EO-EU;Lo;0;L;;;;;N;;;;;\n118C;HANGUL JUNGSEONG U-YE;Lo;0;L;;;;;N;;;;;\n118D;HANGUL JUNGSEONG U-U;Lo;0;L;;;;;N;;;;;\n118E;HANGUL JUNGSEONG YU-A;Lo;0;L;;;;;N;;;;;\n118F;HANGUL JUNGSEONG YU-EO;Lo;0;L;;;;;N;;;;;\n1190;HANGUL JUNGSEONG YU-E;Lo;0;L;;;;;N;;;;;\n1191;HANGUL JUNGSEONG YU-YEO;Lo;0;L;;;;;N;;;;;\n1192;HANGUL JUNGSEONG YU-YE;Lo;0;L;;;;;N;;;;;\n1193;HANGUL JUNGSEONG YU-U;Lo;0;L;;;;;N;;;;;\n1194;HANGUL JUNGSEONG YU-I;Lo;0;L;;;;;N;;;;;\n1195;HANGUL JUNGSEONG EU-U;Lo;0;L;;;;;N;;;;;\n1196;HANGUL JUNGSEONG EU-EU;Lo;0;L;;;;;N;;;;;\n1197;HANGUL JUNGSEONG YI-U;Lo;0;L;;;;;N;;;;;\n1198;HANGUL JUNGSEONG I-A;Lo;0;L;;;;;N;;;;;\n1199;HANGUL JUNGSEONG I-YA;Lo;0;L;;;;;N;;;;;\n119A;HANGUL JUNGSEONG I-O;Lo;0;L;;;;;N;;;;;\n119B;HANGUL JUNGSEONG I-U;Lo;0;L;;;;;N;;;;;\n119C;HANGUL JUNGSEONG I-EU;Lo;0;L;;;;;N;;;;;\n119D;HANGUL JUNGSEONG I-ARAEA;Lo;0;L;;;;;N;;;;;\n119E;HANGUL JUNGSEONG ARAEA;Lo;0;L;;;;;N;;;;;\n119F;HANGUL JUNGSEONG ARAEA-EO;Lo;0;L;;;;;N;;;;;\n11A0;HANGUL JUNGSEONG ARAEA-U;Lo;0;L;;;;;N;;;;;\n11A1;HANGUL JUNGSEONG ARAEA-I;Lo;0;L;;;;;N;;;;;\n11A2;HANGUL JUNGSEONG SSANGARAEA;Lo;0;L;;;;;N;;;;;\n11A3;HANGUL JUNGSEONG A-EU;Lo;0;L;;;;;N;;;;;\n11A4;HANGUL JUNGSEONG YA-U;Lo;0;L;;;;;N;;;;;\n11A5;HANGUL JUNGSEONG YEO-YA;Lo;0;L;;;;;N;;;;;\n11A6;HANGUL JUNGSEONG O-YA;Lo;0;L;;;;;N;;;;;\n11A7;HANGUL JUNGSEONG O-YAE;Lo;0;L;;;;;N;;;;;\n11A8;HANGUL JONGSEONG KIYEOK;Lo;0;L;;;;;N;;;;;\n11A9;HANGUL JONGSEONG SSANGKIYEOK;Lo;0;L;;;;;N;;;;;\n11AA;HANGUL JONGSEONG KIYEOK-SIOS;Lo;0;L;;;;;N;;;;;\n11AB;HANGUL JONGSEONG NIEUN;Lo;0;L;;;;;N;;;;;\n11AC;HANGUL JONGSEONG NIEUN-CIEUC;Lo;0;L;;;;;N;;;;;\n11AD;HANGUL JONGSEONG NIEUN-HIEUH;Lo;0;L;;;;;N;;;;;\n11AE;HANGUL JONGSEONG TIKEUT;Lo;0;L;;;;;N;;;;;\n11AF;HANGUL JONGSEONG RIEUL;Lo;0;L;;;;;N;;;;;\n11B0;HANGUL JONGSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;;;;\n11B1;HANGUL JONGSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;;;;\n11B2;HANGUL JONGSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;;;;\n11B3;HANGUL JONGSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;;;;\n11B4;HANGUL JONGSEONG RIEUL-THIEUTH;Lo;0;L;;;;;N;;;;;\n11B5;HANGUL JONGSEONG RIEUL-PHIEUPH;Lo;0;L;;;;;N;;;;;\n11B6;HANGUL JONGSEONG RIEUL-HIEUH;Lo;0;L;;;;;N;;;;;\n11B7;HANGUL JONGSEONG MIEUM;Lo;0;L;;;;;N;;;;;\n11B8;HANGUL JONGSEONG PIEUP;Lo;0;L;;;;;N;;;;;\n11B9;HANGUL JONGSEONG PIEUP-SIOS;Lo;0;L;;;;;N;;;;;\n11BA;HANGUL JONGSEONG SIOS;Lo;0;L;;;;;N;;;;;\n11BB;HANGUL JONGSEONG SSANGSIOS;Lo;0;L;;;;;N;;;;;\n11BC;HANGUL JONGSEONG IEUNG;Lo;0;L;;;;;N;;;;;\n11BD;HANGUL JONGSEONG CIEUC;Lo;0;L;;;;;N;;;;;\n11BE;HANGUL JONGSEONG CHIEUCH;Lo;0;L;;;;;N;;;;;\n11BF;HANGUL JONGSEONG KHIEUKH;Lo;0;L;;;;;N;;;;;\n11C0;HANGUL JONGSEONG THIEUTH;Lo;0;L;;;;;N;;;;;\n11C1;HANGUL JONGSEONG PHIEUPH;Lo;0;L;;;;;N;;;;;\n11C2;HANGUL JONGSEONG HIEUH;Lo;0;L;;;;;N;;;;;\n11C3;HANGUL JONGSEONG KIYEOK-RIEUL;Lo;0;L;;;;;N;;;;;\n11C4;HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;\n11C5;HANGUL JONGSEONG NIEUN-KIYEOK;Lo;0;L;;;;;N;;;;;\n11C6;HANGUL JONGSEONG NIEUN-TIKEUT;Lo;0;L;;;;;N;;;;;\n11C7;HANGUL JONGSEONG NIEUN-SIOS;Lo;0;L;;;;;N;;;;;\n11C8;HANGUL JONGSEONG NIEUN-PANSIOS;Lo;0;L;;;;;N;;;;;\n11C9;HANGUL JONGSEONG NIEUN-THIEUTH;Lo;0;L;;;;;N;;;;;\n11CA;HANGUL JONGSEONG TIKEUT-KIYEOK;Lo;0;L;;;;;N;;;;;\n11CB;HANGUL JONGSEONG TIKEUT-RIEUL;Lo;0;L;;;;;N;;;;;\n11CC;HANGUL JONGSEONG RIEUL-KIYEOK-SIOS;Lo;0;L;;;;;N;;;;;\n11CD;HANGUL JONGSEONG RIEUL-NIEUN;Lo;0;L;;;;;N;;;;;\n11CE;HANGUL JONGSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;;\n11CF;HANGUL JONGSEONG RIEUL-TIKEUT-HIEUH;Lo;0;L;;;;;N;;;;;\n11D0;HANGUL JONGSEONG SSANGRIEUL;Lo;0;L;;;;;N;;;;;\n11D1;HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;;\n11D2;HANGUL JONGSEONG RIEUL-MIEUM-SIOS;Lo;0;L;;;;;N;;;;;\n11D3;HANGUL JONGSEONG RIEUL-PIEUP-SIOS;Lo;0;L;;;;;N;;;;;\n11D4;HANGUL JONGSEONG RIEUL-PIEUP-HIEUH;Lo;0;L;;;;;N;;;;;\n11D5;HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;\n11D6;HANGUL JONGSEONG RIEUL-SSANGSIOS;Lo;0;L;;;;;N;;;;;\n11D7;HANGUL JONGSEONG RIEUL-PANSIOS;Lo;0;L;;;;;N;;;;;\n11D8;HANGUL JONGSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;;\n11D9;HANGUL JONGSEONG RIEUL-YEORINHIEUH;Lo;0;L;;;;;N;;;;;\n11DA;HANGUL JONGSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;;\n11DB;HANGUL JONGSEONG MIEUM-RIEUL;Lo;0;L;;;;;N;;;;;\n11DC;HANGUL JONGSEONG MIEUM-PIEUP;Lo;0;L;;;;;N;;;;;\n11DD;HANGUL JONGSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;;\n11DE;HANGUL JONGSEONG MIEUM-SSANGSIOS;Lo;0;L;;;;;N;;;;;\n11DF;HANGUL JONGSEONG MIEUM-PANSIOS;Lo;0;L;;;;;N;;;;;\n11E0;HANGUL JONGSEONG MIEUM-CHIEUCH;Lo;0;L;;;;;N;;;;;\n11E1;HANGUL JONGSEONG MIEUM-HIEUH;Lo;0;L;;;;;N;;;;;\n11E2;HANGUL JONGSEONG KAPYEOUNMIEUM;Lo;0;L;;;;;N;;;;;\n11E3;HANGUL JONGSEONG PIEUP-RIEUL;Lo;0;L;;;;;N;;;;;\n11E4;HANGUL JONGSEONG PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;;\n11E5;HANGUL JONGSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;;\n11E6;HANGUL JONGSEONG KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;\n11E7;HANGUL JONGSEONG SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;\n11E8;HANGUL JONGSEONG SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;\n11E9;HANGUL JONGSEONG SIOS-RIEUL;Lo;0;L;;;;;N;;;;;\n11EA;HANGUL JONGSEONG SIOS-PIEUP;Lo;0;L;;;;;N;;;;;\n11EB;HANGUL JONGSEONG PANSIOS;Lo;0;L;;;;;N;;;;;\n11EC;HANGUL JONGSEONG IEUNG-KIYEOK;Lo;0;L;;;;;N;;;;;\n11ED;HANGUL JONGSEONG IEUNG-SSANGKIYEOK;Lo;0;L;;;;;N;;;;;\n11EE;HANGUL JONGSEONG SSANGIEUNG;Lo;0;L;;;;;N;;;;;\n11EF;HANGUL JONGSEONG IEUNG-KHIEUKH;Lo;0;L;;;;;N;;;;;\n11F0;HANGUL JONGSEONG YESIEUNG;Lo;0;L;;;;;N;;;;;\n11F1;HANGUL JONGSEONG YESIEUNG-SIOS;Lo;0;L;;;;;N;;;;;\n11F2;HANGUL JONGSEONG YESIEUNG-PANSIOS;Lo;0;L;;;;;N;;;;;\n11F3;HANGUL JONGSEONG PHIEUPH-PIEUP;Lo;0;L;;;;;N;;;;;\n11F4;HANGUL JONGSEONG KAPYEOUNPHIEUPH;Lo;0;L;;;;;N;;;;;\n11F5;HANGUL JONGSEONG HIEUH-NIEUN;Lo;0;L;;;;;N;;;;;\n11F6;HANGUL JONGSEONG HIEUH-RIEUL;Lo;0;L;;;;;N;;;;;\n11F7;HANGUL JONGSEONG HIEUH-MIEUM;Lo;0;L;;;;;N;;;;;\n11F8;HANGUL JONGSEONG HIEUH-PIEUP;Lo;0;L;;;;;N;;;;;\n11F9;HANGUL JONGSEONG YEORINHIEUH;Lo;0;L;;;;;N;;;;;\n11FA;HANGUL JONGSEONG KIYEOK-NIEUN;Lo;0;L;;;;;N;;;;;\n11FB;HANGUL JONGSEONG KIYEOK-PIEUP;Lo;0;L;;;;;N;;;;;\n11FC;HANGUL JONGSEONG KIYEOK-CHIEUCH;Lo;0;L;;;;;N;;;;;\n11FD;HANGUL JONGSEONG KIYEOK-KHIEUKH;Lo;0;L;;;;;N;;;;;\n11FE;HANGUL JONGSEONG KIYEOK-HIEUH;Lo;0;L;;;;;N;;;;;\n11FF;HANGUL JONGSEONG SSANGNIEUN;Lo;0;L;;;;;N;;;;;\n1200;ETHIOPIC SYLLABLE HA;Lo;0;L;;;;;N;;;;;\n1201;ETHIOPIC SYLLABLE HU;Lo;0;L;;;;;N;;;;;\n1202;ETHIOPIC SYLLABLE HI;Lo;0;L;;;;;N;;;;;\n1203;ETHIOPIC SYLLABLE HAA;Lo;0;L;;;;;N;;;;;\n1204;ETHIOPIC SYLLABLE HEE;Lo;0;L;;;;;N;;;;;\n1205;ETHIOPIC SYLLABLE HE;Lo;0;L;;;;;N;;;;;\n1206;ETHIOPIC SYLLABLE HO;Lo;0;L;;;;;N;;;;;\n1207;ETHIOPIC SYLLABLE HOA;Lo;0;L;;;;;N;;;;;\n1208;ETHIOPIC SYLLABLE LA;Lo;0;L;;;;;N;;;;;\n1209;ETHIOPIC SYLLABLE LU;Lo;0;L;;;;;N;;;;;\n120A;ETHIOPIC SYLLABLE LI;Lo;0;L;;;;;N;;;;;\n120B;ETHIOPIC SYLLABLE LAA;Lo;0;L;;;;;N;;;;;\n120C;ETHIOPIC SYLLABLE LEE;Lo;0;L;;;;;N;;;;;\n120D;ETHIOPIC SYLLABLE LE;Lo;0;L;;;;;N;;;;;\n120E;ETHIOPIC SYLLABLE LO;Lo;0;L;;;;;N;;;;;\n120F;ETHIOPIC SYLLABLE LWA;Lo;0;L;;;;;N;;;;;\n1210;ETHIOPIC SYLLABLE HHA;Lo;0;L;;;;;N;;;;;\n1211;ETHIOPIC SYLLABLE HHU;Lo;0;L;;;;;N;;;;;\n1212;ETHIOPIC SYLLABLE HHI;Lo;0;L;;;;;N;;;;;\n1213;ETHIOPIC SYLLABLE HHAA;Lo;0;L;;;;;N;;;;;\n1214;ETHIOPIC SYLLABLE HHEE;Lo;0;L;;;;;N;;;;;\n1215;ETHIOPIC SYLLABLE HHE;Lo;0;L;;;;;N;;;;;\n1216;ETHIOPIC SYLLABLE HHO;Lo;0;L;;;;;N;;;;;\n1217;ETHIOPIC SYLLABLE HHWA;Lo;0;L;;;;;N;;;;;\n1218;ETHIOPIC SYLLABLE MA;Lo;0;L;;;;;N;;;;;\n1219;ETHIOPIC SYLLABLE MU;Lo;0;L;;;;;N;;;;;\n121A;ETHIOPIC SYLLABLE MI;Lo;0;L;;;;;N;;;;;\n121B;ETHIOPIC SYLLABLE MAA;Lo;0;L;;;;;N;;;;;\n121C;ETHIOPIC SYLLABLE MEE;Lo;0;L;;;;;N;;;;;\n121D;ETHIOPIC SYLLABLE ME;Lo;0;L;;;;;N;;;;;\n121E;ETHIOPIC SYLLABLE MO;Lo;0;L;;;;;N;;;;;\n121F;ETHIOPIC SYLLABLE MWA;Lo;0;L;;;;;N;;;;;\n1220;ETHIOPIC SYLLABLE SZA;Lo;0;L;;;;;N;;;;;\n1221;ETHIOPIC SYLLABLE SZU;Lo;0;L;;;;;N;;;;;\n1222;ETHIOPIC SYLLABLE SZI;Lo;0;L;;;;;N;;;;;\n1223;ETHIOPIC SYLLABLE SZAA;Lo;0;L;;;;;N;;;;;\n1224;ETHIOPIC SYLLABLE SZEE;Lo;0;L;;;;;N;;;;;\n1225;ETHIOPIC SYLLABLE SZE;Lo;0;L;;;;;N;;;;;\n1226;ETHIOPIC SYLLABLE SZO;Lo;0;L;;;;;N;;;;;\n1227;ETHIOPIC SYLLABLE SZWA;Lo;0;L;;;;;N;;;;;\n1228;ETHIOPIC SYLLABLE RA;Lo;0;L;;;;;N;;;;;\n1229;ETHIOPIC SYLLABLE RU;Lo;0;L;;;;;N;;;;;\n122A;ETHIOPIC SYLLABLE RI;Lo;0;L;;;;;N;;;;;\n122B;ETHIOPIC SYLLABLE RAA;Lo;0;L;;;;;N;;;;;\n122C;ETHIOPIC SYLLABLE REE;Lo;0;L;;;;;N;;;;;\n122D;ETHIOPIC SYLLABLE RE;Lo;0;L;;;;;N;;;;;\n122E;ETHIOPIC SYLLABLE RO;Lo;0;L;;;;;N;;;;;\n122F;ETHIOPIC SYLLABLE RWA;Lo;0;L;;;;;N;;;;;\n1230;ETHIOPIC SYLLABLE SA;Lo;0;L;;;;;N;;;;;\n1231;ETHIOPIC SYLLABLE SU;Lo;0;L;;;;;N;;;;;\n1232;ETHIOPIC SYLLABLE SI;Lo;0;L;;;;;N;;;;;\n1233;ETHIOPIC SYLLABLE SAA;Lo;0;L;;;;;N;;;;;\n1234;ETHIOPIC SYLLABLE SEE;Lo;0;L;;;;;N;;;;;\n1235;ETHIOPIC SYLLABLE SE;Lo;0;L;;;;;N;;;;;\n1236;ETHIOPIC SYLLABLE SO;Lo;0;L;;;;;N;;;;;\n1237;ETHIOPIC SYLLABLE SWA;Lo;0;L;;;;;N;;;;;\n1238;ETHIOPIC SYLLABLE SHA;Lo;0;L;;;;;N;;;;;\n1239;ETHIOPIC SYLLABLE SHU;Lo;0;L;;;;;N;;;;;\n123A;ETHIOPIC SYLLABLE SHI;Lo;0;L;;;;;N;;;;;\n123B;ETHIOPIC SYLLABLE SHAA;Lo;0;L;;;;;N;;;;;\n123C;ETHIOPIC SYLLABLE SHEE;Lo;0;L;;;;;N;;;;;\n123D;ETHIOPIC SYLLABLE SHE;Lo;0;L;;;;;N;;;;;\n123E;ETHIOPIC SYLLABLE SHO;Lo;0;L;;;;;N;;;;;\n123F;ETHIOPIC SYLLABLE SHWA;Lo;0;L;;;;;N;;;;;\n1240;ETHIOPIC SYLLABLE QA;Lo;0;L;;;;;N;;;;;\n1241;ETHIOPIC SYLLABLE QU;Lo;0;L;;;;;N;;;;;\n1242;ETHIOPIC SYLLABLE QI;Lo;0;L;;;;;N;;;;;\n1243;ETHIOPIC SYLLABLE QAA;Lo;0;L;;;;;N;;;;;\n1244;ETHIOPIC SYLLABLE QEE;Lo;0;L;;;;;N;;;;;\n1245;ETHIOPIC SYLLABLE QE;Lo;0;L;;;;;N;;;;;\n1246;ETHIOPIC SYLLABLE QO;Lo;0;L;;;;;N;;;;;\n1247;ETHIOPIC SYLLABLE QOA;Lo;0;L;;;;;N;;;;;\n1248;ETHIOPIC SYLLABLE QWA;Lo;0;L;;;;;N;;;;;\n124A;ETHIOPIC SYLLABLE QWI;Lo;0;L;;;;;N;;;;;\n124B;ETHIOPIC SYLLABLE QWAA;Lo;0;L;;;;;N;;;;;\n124C;ETHIOPIC SYLLABLE QWEE;Lo;0;L;;;;;N;;;;;\n124D;ETHIOPIC SYLLABLE QWE;Lo;0;L;;;;;N;;;;;\n1250;ETHIOPIC SYLLABLE QHA;Lo;0;L;;;;;N;;;;;\n1251;ETHIOPIC SYLLABLE QHU;Lo;0;L;;;;;N;;;;;\n1252;ETHIOPIC SYLLABLE QHI;Lo;0;L;;;;;N;;;;;\n1253;ETHIOPIC SYLLABLE QHAA;Lo;0;L;;;;;N;;;;;\n1254;ETHIOPIC SYLLABLE QHEE;Lo;0;L;;;;;N;;;;;\n1255;ETHIOPIC SYLLABLE QHE;Lo;0;L;;;;;N;;;;;\n1256;ETHIOPIC SYLLABLE QHO;Lo;0;L;;;;;N;;;;;\n1258;ETHIOPIC SYLLABLE QHWA;Lo;0;L;;;;;N;;;;;\n125A;ETHIOPIC SYLLABLE QHWI;Lo;0;L;;;;;N;;;;;\n125B;ETHIOPIC SYLLABLE QHWAA;Lo;0;L;;;;;N;;;;;\n125C;ETHIOPIC SYLLABLE QHWEE;Lo;0;L;;;;;N;;;;;\n125D;ETHIOPIC SYLLABLE QHWE;Lo;0;L;;;;;N;;;;;\n1260;ETHIOPIC SYLLABLE BA;Lo;0;L;;;;;N;;;;;\n1261;ETHIOPIC SYLLABLE BU;Lo;0;L;;;;;N;;;;;\n1262;ETHIOPIC SYLLABLE BI;Lo;0;L;;;;;N;;;;;\n1263;ETHIOPIC SYLLABLE BAA;Lo;0;L;;;;;N;;;;;\n1264;ETHIOPIC SYLLABLE BEE;Lo;0;L;;;;;N;;;;;\n1265;ETHIOPIC SYLLABLE BE;Lo;0;L;;;;;N;;;;;\n1266;ETHIOPIC SYLLABLE BO;Lo;0;L;;;;;N;;;;;\n1267;ETHIOPIC SYLLABLE BWA;Lo;0;L;;;;;N;;;;;\n1268;ETHIOPIC SYLLABLE VA;Lo;0;L;;;;;N;;;;;\n1269;ETHIOPIC SYLLABLE VU;Lo;0;L;;;;;N;;;;;\n126A;ETHIOPIC SYLLABLE VI;Lo;0;L;;;;;N;;;;;\n126B;ETHIOPIC SYLLABLE VAA;Lo;0;L;;;;;N;;;;;\n126C;ETHIOPIC SYLLABLE VEE;Lo;0;L;;;;;N;;;;;\n126D;ETHIOPIC SYLLABLE VE;Lo;0;L;;;;;N;;;;;\n126E;ETHIOPIC SYLLABLE VO;Lo;0;L;;;;;N;;;;;\n126F;ETHIOPIC SYLLABLE VWA;Lo;0;L;;;;;N;;;;;\n1270;ETHIOPIC SYLLABLE TA;Lo;0;L;;;;;N;;;;;\n1271;ETHIOPIC SYLLABLE TU;Lo;0;L;;;;;N;;;;;\n1272;ETHIOPIC SYLLABLE TI;Lo;0;L;;;;;N;;;;;\n1273;ETHIOPIC SYLLABLE TAA;Lo;0;L;;;;;N;;;;;\n1274;ETHIOPIC SYLLABLE TEE;Lo;0;L;;;;;N;;;;;\n1275;ETHIOPIC SYLLABLE TE;Lo;0;L;;;;;N;;;;;\n1276;ETHIOPIC SYLLABLE TO;Lo;0;L;;;;;N;;;;;\n1277;ETHIOPIC SYLLABLE TWA;Lo;0;L;;;;;N;;;;;\n1278;ETHIOPIC SYLLABLE CA;Lo;0;L;;;;;N;;;;;\n1279;ETHIOPIC SYLLABLE CU;Lo;0;L;;;;;N;;;;;\n127A;ETHIOPIC SYLLABLE CI;Lo;0;L;;;;;N;;;;;\n127B;ETHIOPIC SYLLABLE CAA;Lo;0;L;;;;;N;;;;;\n127C;ETHIOPIC SYLLABLE CEE;Lo;0;L;;;;;N;;;;;\n127D;ETHIOPIC SYLLABLE CE;Lo;0;L;;;;;N;;;;;\n127E;ETHIOPIC SYLLABLE CO;Lo;0;L;;;;;N;;;;;\n127F;ETHIOPIC SYLLABLE CWA;Lo;0;L;;;;;N;;;;;\n1280;ETHIOPIC SYLLABLE XA;Lo;0;L;;;;;N;;;;;\n1281;ETHIOPIC SYLLABLE XU;Lo;0;L;;;;;N;;;;;\n1282;ETHIOPIC SYLLABLE XI;Lo;0;L;;;;;N;;;;;\n1283;ETHIOPIC SYLLABLE XAA;Lo;0;L;;;;;N;;;;;\n1284;ETHIOPIC SYLLABLE XEE;Lo;0;L;;;;;N;;;;;\n1285;ETHIOPIC SYLLABLE XE;Lo;0;L;;;;;N;;;;;\n1286;ETHIOPIC SYLLABLE XO;Lo;0;L;;;;;N;;;;;\n1287;ETHIOPIC SYLLABLE XOA;Lo;0;L;;;;;N;;;;;\n1288;ETHIOPIC SYLLABLE XWA;Lo;0;L;;;;;N;;;;;\n128A;ETHIOPIC SYLLABLE XWI;Lo;0;L;;;;;N;;;;;\n128B;ETHIOPIC SYLLABLE XWAA;Lo;0;L;;;;;N;;;;;\n128C;ETHIOPIC SYLLABLE XWEE;Lo;0;L;;;;;N;;;;;\n128D;ETHIOPIC SYLLABLE XWE;Lo;0;L;;;;;N;;;;;\n1290;ETHIOPIC SYLLABLE NA;Lo;0;L;;;;;N;;;;;\n1291;ETHIOPIC SYLLABLE NU;Lo;0;L;;;;;N;;;;;\n1292;ETHIOPIC SYLLABLE NI;Lo;0;L;;;;;N;;;;;\n1293;ETHIOPIC SYLLABLE NAA;Lo;0;L;;;;;N;;;;;\n1294;ETHIOPIC SYLLABLE NEE;Lo;0;L;;;;;N;;;;;\n1295;ETHIOPIC SYLLABLE NE;Lo;0;L;;;;;N;;;;;\n1296;ETHIOPIC SYLLABLE NO;Lo;0;L;;;;;N;;;;;\n1297;ETHIOPIC SYLLABLE NWA;Lo;0;L;;;;;N;;;;;\n1298;ETHIOPIC SYLLABLE NYA;Lo;0;L;;;;;N;;;;;\n1299;ETHIOPIC SYLLABLE NYU;Lo;0;L;;;;;N;;;;;\n129A;ETHIOPIC SYLLABLE NYI;Lo;0;L;;;;;N;;;;;\n129B;ETHIOPIC SYLLABLE NYAA;Lo;0;L;;;;;N;;;;;\n129C;ETHIOPIC SYLLABLE NYEE;Lo;0;L;;;;;N;;;;;\n129D;ETHIOPIC SYLLABLE NYE;Lo;0;L;;;;;N;;;;;\n129E;ETHIOPIC SYLLABLE NYO;Lo;0;L;;;;;N;;;;;\n129F;ETHIOPIC SYLLABLE NYWA;Lo;0;L;;;;;N;;;;;\n12A0;ETHIOPIC SYLLABLE GLOTTAL A;Lo;0;L;;;;;N;;;;;\n12A1;ETHIOPIC SYLLABLE GLOTTAL U;Lo;0;L;;;;;N;;;;;\n12A2;ETHIOPIC SYLLABLE GLOTTAL I;Lo;0;L;;;;;N;;;;;\n12A3;ETHIOPIC SYLLABLE GLOTTAL AA;Lo;0;L;;;;;N;;;;;\n12A4;ETHIOPIC SYLLABLE GLOTTAL EE;Lo;0;L;;;;;N;;;;;\n12A5;ETHIOPIC SYLLABLE GLOTTAL E;Lo;0;L;;;;;N;;;;;\n12A6;ETHIOPIC SYLLABLE GLOTTAL O;Lo;0;L;;;;;N;;;;;\n12A7;ETHIOPIC SYLLABLE GLOTTAL WA;Lo;0;L;;;;;N;;;;;\n12A8;ETHIOPIC SYLLABLE KA;Lo;0;L;;;;;N;;;;;\n12A9;ETHIOPIC SYLLABLE KU;Lo;0;L;;;;;N;;;;;\n12AA;ETHIOPIC SYLLABLE KI;Lo;0;L;;;;;N;;;;;\n12AB;ETHIOPIC SYLLABLE KAA;Lo;0;L;;;;;N;;;;;\n12AC;ETHIOPIC SYLLABLE KEE;Lo;0;L;;;;;N;;;;;\n12AD;ETHIOPIC SYLLABLE KE;Lo;0;L;;;;;N;;;;;\n12AE;ETHIOPIC SYLLABLE KO;Lo;0;L;;;;;N;;;;;\n12AF;ETHIOPIC SYLLABLE KOA;Lo;0;L;;;;;N;;;;;\n12B0;ETHIOPIC SYLLABLE KWA;Lo;0;L;;;;;N;;;;;\n12B2;ETHIOPIC SYLLABLE KWI;Lo;0;L;;;;;N;;;;;\n12B3;ETHIOPIC SYLLABLE KWAA;Lo;0;L;;;;;N;;;;;\n12B4;ETHIOPIC SYLLABLE KWEE;Lo;0;L;;;;;N;;;;;\n12B5;ETHIOPIC SYLLABLE KWE;Lo;0;L;;;;;N;;;;;\n12B8;ETHIOPIC SYLLABLE KXA;Lo;0;L;;;;;N;;;;;\n12B9;ETHIOPIC SYLLABLE KXU;Lo;0;L;;;;;N;;;;;\n12BA;ETHIOPIC SYLLABLE KXI;Lo;0;L;;;;;N;;;;;\n12BB;ETHIOPIC SYLLABLE KXAA;Lo;0;L;;;;;N;;;;;\n12BC;ETHIOPIC SYLLABLE KXEE;Lo;0;L;;;;;N;;;;;\n12BD;ETHIOPIC SYLLABLE KXE;Lo;0;L;;;;;N;;;;;\n12BE;ETHIOPIC SYLLABLE KXO;Lo;0;L;;;;;N;;;;;\n12C0;ETHIOPIC SYLLABLE KXWA;Lo;0;L;;;;;N;;;;;\n12C2;ETHIOPIC SYLLABLE KXWI;Lo;0;L;;;;;N;;;;;\n12C3;ETHIOPIC SYLLABLE KXWAA;Lo;0;L;;;;;N;;;;;\n12C4;ETHIOPIC SYLLABLE KXWEE;Lo;0;L;;;;;N;;;;;\n12C5;ETHIOPIC SYLLABLE KXWE;Lo;0;L;;;;;N;;;;;\n12C8;ETHIOPIC SYLLABLE WA;Lo;0;L;;;;;N;;;;;\n12C9;ETHIOPIC SYLLABLE WU;Lo;0;L;;;;;N;;;;;\n12CA;ETHIOPIC SYLLABLE WI;Lo;0;L;;;;;N;;;;;\n12CB;ETHIOPIC SYLLABLE WAA;Lo;0;L;;;;;N;;;;;\n12CC;ETHIOPIC SYLLABLE WEE;Lo;0;L;;;;;N;;;;;\n12CD;ETHIOPIC SYLLABLE WE;Lo;0;L;;;;;N;;;;;\n12CE;ETHIOPIC SYLLABLE WO;Lo;0;L;;;;;N;;;;;\n12CF;ETHIOPIC SYLLABLE WOA;Lo;0;L;;;;;N;;;;;\n12D0;ETHIOPIC SYLLABLE PHARYNGEAL A;Lo;0;L;;;;;N;;;;;\n12D1;ETHIOPIC SYLLABLE PHARYNGEAL U;Lo;0;L;;;;;N;;;;;\n12D2;ETHIOPIC SYLLABLE PHARYNGEAL I;Lo;0;L;;;;;N;;;;;\n12D3;ETHIOPIC SYLLABLE PHARYNGEAL AA;Lo;0;L;;;;;N;;;;;\n12D4;ETHIOPIC SYLLABLE PHARYNGEAL EE;Lo;0;L;;;;;N;;;;;\n12D5;ETHIOPIC SYLLABLE PHARYNGEAL E;Lo;0;L;;;;;N;;;;;\n12D6;ETHIOPIC SYLLABLE PHARYNGEAL O;Lo;0;L;;;;;N;;;;;\n12D8;ETHIOPIC SYLLABLE ZA;Lo;0;L;;;;;N;;;;;\n12D9;ETHIOPIC SYLLABLE ZU;Lo;0;L;;;;;N;;;;;\n12DA;ETHIOPIC SYLLABLE ZI;Lo;0;L;;;;;N;;;;;\n12DB;ETHIOPIC SYLLABLE ZAA;Lo;0;L;;;;;N;;;;;\n12DC;ETHIOPIC SYLLABLE ZEE;Lo;0;L;;;;;N;;;;;\n12DD;ETHIOPIC SYLLABLE ZE;Lo;0;L;;;;;N;;;;;\n12DE;ETHIOPIC SYLLABLE ZO;Lo;0;L;;;;;N;;;;;\n12DF;ETHIOPIC SYLLABLE ZWA;Lo;0;L;;;;;N;;;;;\n12E0;ETHIOPIC SYLLABLE ZHA;Lo;0;L;;;;;N;;;;;\n12E1;ETHIOPIC SYLLABLE ZHU;Lo;0;L;;;;;N;;;;;\n12E2;ETHIOPIC SYLLABLE ZHI;Lo;0;L;;;;;N;;;;;\n12E3;ETHIOPIC SYLLABLE ZHAA;Lo;0;L;;;;;N;;;;;\n12E4;ETHIOPIC SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;;\n12E5;ETHIOPIC SYLLABLE ZHE;Lo;0;L;;;;;N;;;;;\n12E6;ETHIOPIC SYLLABLE ZHO;Lo;0;L;;;;;N;;;;;\n12E7;ETHIOPIC SYLLABLE ZHWA;Lo;0;L;;;;;N;;;;;\n12E8;ETHIOPIC SYLLABLE YA;Lo;0;L;;;;;N;;;;;\n12E9;ETHIOPIC SYLLABLE YU;Lo;0;L;;;;;N;;;;;\n12EA;ETHIOPIC SYLLABLE YI;Lo;0;L;;;;;N;;;;;\n12EB;ETHIOPIC SYLLABLE YAA;Lo;0;L;;;;;N;;;;;\n12EC;ETHIOPIC SYLLABLE YEE;Lo;0;L;;;;;N;;;;;\n12ED;ETHIOPIC SYLLABLE YE;Lo;0;L;;;;;N;;;;;\n12EE;ETHIOPIC SYLLABLE YO;Lo;0;L;;;;;N;;;;;\n12EF;ETHIOPIC SYLLABLE YOA;Lo;0;L;;;;;N;;;;;\n12F0;ETHIOPIC SYLLABLE DA;Lo;0;L;;;;;N;;;;;\n12F1;ETHIOPIC SYLLABLE DU;Lo;0;L;;;;;N;;;;;\n12F2;ETHIOPIC SYLLABLE DI;Lo;0;L;;;;;N;;;;;\n12F3;ETHIOPIC SYLLABLE DAA;Lo;0;L;;;;;N;;;;;\n12F4;ETHIOPIC SYLLABLE DEE;Lo;0;L;;;;;N;;;;;\n12F5;ETHIOPIC SYLLABLE DE;Lo;0;L;;;;;N;;;;;\n12F6;ETHIOPIC SYLLABLE DO;Lo;0;L;;;;;N;;;;;\n12F7;ETHIOPIC SYLLABLE DWA;Lo;0;L;;;;;N;;;;;\n12F8;ETHIOPIC SYLLABLE DDA;Lo;0;L;;;;;N;;;;;\n12F9;ETHIOPIC SYLLABLE DDU;Lo;0;L;;;;;N;;;;;\n12FA;ETHIOPIC SYLLABLE DDI;Lo;0;L;;;;;N;;;;;\n12FB;ETHIOPIC SYLLABLE DDAA;Lo;0;L;;;;;N;;;;;\n12FC;ETHIOPIC SYLLABLE DDEE;Lo;0;L;;;;;N;;;;;\n12FD;ETHIOPIC SYLLABLE DDE;Lo;0;L;;;;;N;;;;;\n12FE;ETHIOPIC SYLLABLE DDO;Lo;0;L;;;;;N;;;;;\n12FF;ETHIOPIC SYLLABLE DDWA;Lo;0;L;;;;;N;;;;;\n1300;ETHIOPIC SYLLABLE JA;Lo;0;L;;;;;N;;;;;\n1301;ETHIOPIC SYLLABLE JU;Lo;0;L;;;;;N;;;;;\n1302;ETHIOPIC SYLLABLE JI;Lo;0;L;;;;;N;;;;;\n1303;ETHIOPIC SYLLABLE JAA;Lo;0;L;;;;;N;;;;;\n1304;ETHIOPIC SYLLABLE JEE;Lo;0;L;;;;;N;;;;;\n1305;ETHIOPIC SYLLABLE JE;Lo;0;L;;;;;N;;;;;\n1306;ETHIOPIC SYLLABLE JO;Lo;0;L;;;;;N;;;;;\n1307;ETHIOPIC SYLLABLE JWA;Lo;0;L;;;;;N;;;;;\n1308;ETHIOPIC SYLLABLE GA;Lo;0;L;;;;;N;;;;;\n1309;ETHIOPIC SYLLABLE GU;Lo;0;L;;;;;N;;;;;\n130A;ETHIOPIC SYLLABLE GI;Lo;0;L;;;;;N;;;;;\n130B;ETHIOPIC SYLLABLE GAA;Lo;0;L;;;;;N;;;;;\n130C;ETHIOPIC SYLLABLE GEE;Lo;0;L;;;;;N;;;;;\n130D;ETHIOPIC SYLLABLE GE;Lo;0;L;;;;;N;;;;;\n130E;ETHIOPIC SYLLABLE GO;Lo;0;L;;;;;N;;;;;\n130F;ETHIOPIC SYLLABLE GOA;Lo;0;L;;;;;N;;;;;\n1310;ETHIOPIC SYLLABLE GWA;Lo;0;L;;;;;N;;;;;\n1312;ETHIOPIC SYLLABLE GWI;Lo;0;L;;;;;N;;;;;\n1313;ETHIOPIC SYLLABLE GWAA;Lo;0;L;;;;;N;;;;;\n1314;ETHIOPIC SYLLABLE GWEE;Lo;0;L;;;;;N;;;;;\n1315;ETHIOPIC SYLLABLE GWE;Lo;0;L;;;;;N;;;;;\n1318;ETHIOPIC SYLLABLE GGA;Lo;0;L;;;;;N;;;;;\n1319;ETHIOPIC SYLLABLE GGU;Lo;0;L;;;;;N;;;;;\n131A;ETHIOPIC SYLLABLE GGI;Lo;0;L;;;;;N;;;;;\n131B;ETHIOPIC SYLLABLE GGAA;Lo;0;L;;;;;N;;;;;\n131C;ETHIOPIC SYLLABLE GGEE;Lo;0;L;;;;;N;;;;;\n131D;ETHIOPIC SYLLABLE GGE;Lo;0;L;;;;;N;;;;;\n131E;ETHIOPIC SYLLABLE GGO;Lo;0;L;;;;;N;;;;;\n131F;ETHIOPIC SYLLABLE GGWAA;Lo;0;L;;;;;N;;;;;\n1320;ETHIOPIC SYLLABLE THA;Lo;0;L;;;;;N;;;;;\n1321;ETHIOPIC SYLLABLE THU;Lo;0;L;;;;;N;;;;;\n1322;ETHIOPIC SYLLABLE THI;Lo;0;L;;;;;N;;;;;\n1323;ETHIOPIC SYLLABLE THAA;Lo;0;L;;;;;N;;;;;\n1324;ETHIOPIC SYLLABLE THEE;Lo;0;L;;;;;N;;;;;\n1325;ETHIOPIC SYLLABLE THE;Lo;0;L;;;;;N;;;;;\n1326;ETHIOPIC SYLLABLE THO;Lo;0;L;;;;;N;;;;;\n1327;ETHIOPIC SYLLABLE THWA;Lo;0;L;;;;;N;;;;;\n1328;ETHIOPIC SYLLABLE CHA;Lo;0;L;;;;;N;;;;;\n1329;ETHIOPIC SYLLABLE CHU;Lo;0;L;;;;;N;;;;;\n132A;ETHIOPIC SYLLABLE CHI;Lo;0;L;;;;;N;;;;;\n132B;ETHIOPIC SYLLABLE CHAA;Lo;0;L;;;;;N;;;;;\n132C;ETHIOPIC SYLLABLE CHEE;Lo;0;L;;;;;N;;;;;\n132D;ETHIOPIC SYLLABLE CHE;Lo;0;L;;;;;N;;;;;\n132E;ETHIOPIC SYLLABLE CHO;Lo;0;L;;;;;N;;;;;\n132F;ETHIOPIC SYLLABLE CHWA;Lo;0;L;;;;;N;;;;;\n1330;ETHIOPIC SYLLABLE PHA;Lo;0;L;;;;;N;;;;;\n1331;ETHIOPIC SYLLABLE PHU;Lo;0;L;;;;;N;;;;;\n1332;ETHIOPIC SYLLABLE PHI;Lo;0;L;;;;;N;;;;;\n1333;ETHIOPIC SYLLABLE PHAA;Lo;0;L;;;;;N;;;;;\n1334;ETHIOPIC SYLLABLE PHEE;Lo;0;L;;;;;N;;;;;\n1335;ETHIOPIC SYLLABLE PHE;Lo;0;L;;;;;N;;;;;\n1336;ETHIOPIC SYLLABLE PHO;Lo;0;L;;;;;N;;;;;\n1337;ETHIOPIC SYLLABLE PHWA;Lo;0;L;;;;;N;;;;;\n1338;ETHIOPIC SYLLABLE TSA;Lo;0;L;;;;;N;;;;;\n1339;ETHIOPIC SYLLABLE TSU;Lo;0;L;;;;;N;;;;;\n133A;ETHIOPIC SYLLABLE TSI;Lo;0;L;;;;;N;;;;;\n133B;ETHIOPIC SYLLABLE TSAA;Lo;0;L;;;;;N;;;;;\n133C;ETHIOPIC SYLLABLE TSEE;Lo;0;L;;;;;N;;;;;\n133D;ETHIOPIC SYLLABLE TSE;Lo;0;L;;;;;N;;;;;\n133E;ETHIOPIC SYLLABLE TSO;Lo;0;L;;;;;N;;;;;\n133F;ETHIOPIC SYLLABLE TSWA;Lo;0;L;;;;;N;;;;;\n1340;ETHIOPIC SYLLABLE TZA;Lo;0;L;;;;;N;;;;;\n1341;ETHIOPIC SYLLABLE TZU;Lo;0;L;;;;;N;;;;;\n1342;ETHIOPIC SYLLABLE TZI;Lo;0;L;;;;;N;;;;;\n1343;ETHIOPIC SYLLABLE TZAA;Lo;0;L;;;;;N;;;;;\n1344;ETHIOPIC SYLLABLE TZEE;Lo;0;L;;;;;N;;;;;\n1345;ETHIOPIC SYLLABLE TZE;Lo;0;L;;;;;N;;;;;\n1346;ETHIOPIC SYLLABLE TZO;Lo;0;L;;;;;N;;;;;\n1347;ETHIOPIC SYLLABLE TZOA;Lo;0;L;;;;;N;;;;;\n1348;ETHIOPIC SYLLABLE FA;Lo;0;L;;;;;N;;;;;\n1349;ETHIOPIC SYLLABLE FU;Lo;0;L;;;;;N;;;;;\n134A;ETHIOPIC SYLLABLE FI;Lo;0;L;;;;;N;;;;;\n134B;ETHIOPIC SYLLABLE FAA;Lo;0;L;;;;;N;;;;;\n134C;ETHIOPIC SYLLABLE FEE;Lo;0;L;;;;;N;;;;;\n134D;ETHIOPIC SYLLABLE FE;Lo;0;L;;;;;N;;;;;\n134E;ETHIOPIC SYLLABLE FO;Lo;0;L;;;;;N;;;;;\n134F;ETHIOPIC SYLLABLE FWA;Lo;0;L;;;;;N;;;;;\n1350;ETHIOPIC SYLLABLE PA;Lo;0;L;;;;;N;;;;;\n1351;ETHIOPIC SYLLABLE PU;Lo;0;L;;;;;N;;;;;\n1352;ETHIOPIC SYLLABLE PI;Lo;0;L;;;;;N;;;;;\n1353;ETHIOPIC SYLLABLE PAA;Lo;0;L;;;;;N;;;;;\n1354;ETHIOPIC SYLLABLE PEE;Lo;0;L;;;;;N;;;;;\n1355;ETHIOPIC SYLLABLE PE;Lo;0;L;;;;;N;;;;;\n1356;ETHIOPIC SYLLABLE PO;Lo;0;L;;;;;N;;;;;\n1357;ETHIOPIC SYLLABLE PWA;Lo;0;L;;;;;N;;;;;\n1358;ETHIOPIC SYLLABLE RYA;Lo;0;L;;;;;N;;;;;\n1359;ETHIOPIC SYLLABLE MYA;Lo;0;L;;;;;N;;;;;\n135A;ETHIOPIC SYLLABLE FYA;Lo;0;L;;;;;N;;;;;\n135D;ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK;Mn;230;NSM;;;;;N;;;;;\n135E;ETHIOPIC COMBINING VOWEL LENGTH MARK;Mn;230;NSM;;;;;N;;;;;\n135F;ETHIOPIC COMBINING GEMINATION MARK;Mn;230;NSM;;;;;N;;;;;\n1360;ETHIOPIC SECTION MARK;Po;0;L;;;;;N;;;;;\n1361;ETHIOPIC WORDSPACE;Po;0;L;;;;;N;;;;;\n1362;ETHIOPIC FULL STOP;Po;0;L;;;;;N;;;;;\n1363;ETHIOPIC COMMA;Po;0;L;;;;;N;;;;;\n1364;ETHIOPIC SEMICOLON;Po;0;L;;;;;N;;;;;\n1365;ETHIOPIC COLON;Po;0;L;;;;;N;;;;;\n1366;ETHIOPIC PREFACE COLON;Po;0;L;;;;;N;;;;;\n1367;ETHIOPIC QUESTION MARK;Po;0;L;;;;;N;;;;;\n1368;ETHIOPIC PARAGRAPH SEPARATOR;Po;0;L;;;;;N;;;;;\n1369;ETHIOPIC DIGIT ONE;No;0;L;;;1;1;N;;;;;\n136A;ETHIOPIC DIGIT TWO;No;0;L;;;2;2;N;;;;;\n136B;ETHIOPIC DIGIT THREE;No;0;L;;;3;3;N;;;;;\n136C;ETHIOPIC DIGIT FOUR;No;0;L;;;4;4;N;;;;;\n136D;ETHIOPIC DIGIT FIVE;No;0;L;;;5;5;N;;;;;\n136E;ETHIOPIC DIGIT SIX;No;0;L;;;6;6;N;;;;;\n136F;ETHIOPIC DIGIT SEVEN;No;0;L;;;7;7;N;;;;;\n1370;ETHIOPIC DIGIT EIGHT;No;0;L;;;8;8;N;;;;;\n1371;ETHIOPIC DIGIT NINE;No;0;L;;;9;9;N;;;;;\n1372;ETHIOPIC NUMBER TEN;No;0;L;;;;10;N;;;;;\n1373;ETHIOPIC NUMBER TWENTY;No;0;L;;;;20;N;;;;;\n1374;ETHIOPIC NUMBER THIRTY;No;0;L;;;;30;N;;;;;\n1375;ETHIOPIC NUMBER FORTY;No;0;L;;;;40;N;;;;;\n1376;ETHIOPIC NUMBER FIFTY;No;0;L;;;;50;N;;;;;\n1377;ETHIOPIC NUMBER SIXTY;No;0;L;;;;60;N;;;;;\n1378;ETHIOPIC NUMBER SEVENTY;No;0;L;;;;70;N;;;;;\n1379;ETHIOPIC NUMBER EIGHTY;No;0;L;;;;80;N;;;;;\n137A;ETHIOPIC NUMBER NINETY;No;0;L;;;;90;N;;;;;\n137B;ETHIOPIC NUMBER HUNDRED;No;0;L;;;;100;N;;;;;\n137C;ETHIOPIC NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;;\n1380;ETHIOPIC SYLLABLE SEBATBEIT MWA;Lo;0;L;;;;;N;;;;;\n1381;ETHIOPIC SYLLABLE MWI;Lo;0;L;;;;;N;;;;;\n1382;ETHIOPIC SYLLABLE MWEE;Lo;0;L;;;;;N;;;;;\n1383;ETHIOPIC SYLLABLE MWE;Lo;0;L;;;;;N;;;;;\n1384;ETHIOPIC SYLLABLE SEBATBEIT BWA;Lo;0;L;;;;;N;;;;;\n1385;ETHIOPIC SYLLABLE BWI;Lo;0;L;;;;;N;;;;;\n1386;ETHIOPIC SYLLABLE BWEE;Lo;0;L;;;;;N;;;;;\n1387;ETHIOPIC SYLLABLE BWE;Lo;0;L;;;;;N;;;;;\n1388;ETHIOPIC SYLLABLE SEBATBEIT FWA;Lo;0;L;;;;;N;;;;;\n1389;ETHIOPIC SYLLABLE FWI;Lo;0;L;;;;;N;;;;;\n138A;ETHIOPIC SYLLABLE FWEE;Lo;0;L;;;;;N;;;;;\n138B;ETHIOPIC SYLLABLE FWE;Lo;0;L;;;;;N;;;;;\n138C;ETHIOPIC SYLLABLE SEBATBEIT PWA;Lo;0;L;;;;;N;;;;;\n138D;ETHIOPIC SYLLABLE PWI;Lo;0;L;;;;;N;;;;;\n138E;ETHIOPIC SYLLABLE PWEE;Lo;0;L;;;;;N;;;;;\n138F;ETHIOPIC SYLLABLE PWE;Lo;0;L;;;;;N;;;;;\n1390;ETHIOPIC TONAL MARK YIZET;So;0;ON;;;;;N;;;;;\n1391;ETHIOPIC TONAL MARK DERET;So;0;ON;;;;;N;;;;;\n1392;ETHIOPIC TONAL MARK RIKRIK;So;0;ON;;;;;N;;;;;\n1393;ETHIOPIC TONAL MARK SHORT RIKRIK;So;0;ON;;;;;N;;;;;\n1394;ETHIOPIC TONAL MARK DIFAT;So;0;ON;;;;;N;;;;;\n1395;ETHIOPIC TONAL MARK KENAT;So;0;ON;;;;;N;;;;;\n1396;ETHIOPIC TONAL MARK CHIRET;So;0;ON;;;;;N;;;;;\n1397;ETHIOPIC TONAL MARK HIDET;So;0;ON;;;;;N;;;;;\n1398;ETHIOPIC TONAL MARK DERET-HIDET;So;0;ON;;;;;N;;;;;\n1399;ETHIOPIC TONAL MARK KURT;So;0;ON;;;;;N;;;;;\n13A0;CHEROKEE LETTER A;Lu;0;L;;;;;N;;;;AB70;\n13A1;CHEROKEE LETTER E;Lu;0;L;;;;;N;;;;AB71;\n13A2;CHEROKEE LETTER I;Lu;0;L;;;;;N;;;;AB72;\n13A3;CHEROKEE LETTER O;Lu;0;L;;;;;N;;;;AB73;\n13A4;CHEROKEE LETTER U;Lu;0;L;;;;;N;;;;AB74;\n13A5;CHEROKEE LETTER V;Lu;0;L;;;;;N;;;;AB75;\n13A6;CHEROKEE LETTER GA;Lu;0;L;;;;;N;;;;AB76;\n13A7;CHEROKEE LETTER KA;Lu;0;L;;;;;N;;;;AB77;\n13A8;CHEROKEE LETTER GE;Lu;0;L;;;;;N;;;;AB78;\n13A9;CHEROKEE LETTER GI;Lu;0;L;;;;;N;;;;AB79;\n13AA;CHEROKEE LETTER GO;Lu;0;L;;;;;N;;;;AB7A;\n13AB;CHEROKEE LETTER GU;Lu;0;L;;;;;N;;;;AB7B;\n13AC;CHEROKEE LETTER GV;Lu;0;L;;;;;N;;;;AB7C;\n13AD;CHEROKEE LETTER HA;Lu;0;L;;;;;N;;;;AB7D;\n13AE;CHEROKEE LETTER HE;Lu;0;L;;;;;N;;;;AB7E;\n13AF;CHEROKEE LETTER HI;Lu;0;L;;;;;N;;;;AB7F;\n13B0;CHEROKEE LETTER HO;Lu;0;L;;;;;N;;;;AB80;\n13B1;CHEROKEE LETTER HU;Lu;0;L;;;;;N;;;;AB81;\n13B2;CHEROKEE LETTER HV;Lu;0;L;;;;;N;;;;AB82;\n13B3;CHEROKEE LETTER LA;Lu;0;L;;;;;N;;;;AB83;\n13B4;CHEROKEE LETTER LE;Lu;0;L;;;;;N;;;;AB84;\n13B5;CHEROKEE LETTER LI;Lu;0;L;;;;;N;;;;AB85;\n13B6;CHEROKEE LETTER LO;Lu;0;L;;;;;N;;;;AB86;\n13B7;CHEROKEE LETTER LU;Lu;0;L;;;;;N;;;;AB87;\n13B8;CHEROKEE LETTER LV;Lu;0;L;;;;;N;;;;AB88;\n13B9;CHEROKEE LETTER MA;Lu;0;L;;;;;N;;;;AB89;\n13BA;CHEROKEE LETTER ME;Lu;0;L;;;;;N;;;;AB8A;\n13BB;CHEROKEE LETTER MI;Lu;0;L;;;;;N;;;;AB8B;\n13BC;CHEROKEE LETTER MO;Lu;0;L;;;;;N;;;;AB8C;\n13BD;CHEROKEE LETTER MU;Lu;0;L;;;;;N;;;;AB8D;\n13BE;CHEROKEE LETTER NA;Lu;0;L;;;;;N;;;;AB8E;\n13BF;CHEROKEE LETTER HNA;Lu;0;L;;;;;N;;;;AB8F;\n13C0;CHEROKEE LETTER NAH;Lu;0;L;;;;;N;;;;AB90;\n13C1;CHEROKEE LETTER NE;Lu;0;L;;;;;N;;;;AB91;\n13C2;CHEROKEE LETTER NI;Lu;0;L;;;;;N;;;;AB92;\n13C3;CHEROKEE LETTER NO;Lu;0;L;;;;;N;;;;AB93;\n13C4;CHEROKEE LETTER NU;Lu;0;L;;;;;N;;;;AB94;\n13C5;CHEROKEE LETTER NV;Lu;0;L;;;;;N;;;;AB95;\n13C6;CHEROKEE LETTER QUA;Lu;0;L;;;;;N;;;;AB96;\n13C7;CHEROKEE LETTER QUE;Lu;0;L;;;;;N;;;;AB97;\n13C8;CHEROKEE LETTER QUI;Lu;0;L;;;;;N;;;;AB98;\n13C9;CHEROKEE LETTER QUO;Lu;0;L;;;;;N;;;;AB99;\n13CA;CHEROKEE LETTER QUU;Lu;0;L;;;;;N;;;;AB9A;\n13CB;CHEROKEE LETTER QUV;Lu;0;L;;;;;N;;;;AB9B;\n13CC;CHEROKEE LETTER SA;Lu;0;L;;;;;N;;;;AB9C;\n13CD;CHEROKEE LETTER S;Lu;0;L;;;;;N;;;;AB9D;\n13CE;CHEROKEE LETTER SE;Lu;0;L;;;;;N;;;;AB9E;\n13CF;CHEROKEE LETTER SI;Lu;0;L;;;;;N;;;;AB9F;\n13D0;CHEROKEE LETTER SO;Lu;0;L;;;;;N;;;;ABA0;\n13D1;CHEROKEE LETTER SU;Lu;0;L;;;;;N;;;;ABA1;\n13D2;CHEROKEE LETTER SV;Lu;0;L;;;;;N;;;;ABA2;\n13D3;CHEROKEE LETTER DA;Lu;0;L;;;;;N;;;;ABA3;\n13D4;CHEROKEE LETTER TA;Lu;0;L;;;;;N;;;;ABA4;\n13D5;CHEROKEE LETTER DE;Lu;0;L;;;;;N;;;;ABA5;\n13D6;CHEROKEE LETTER TE;Lu;0;L;;;;;N;;;;ABA6;\n13D7;CHEROKEE LETTER DI;Lu;0;L;;;;;N;;;;ABA7;\n13D8;CHEROKEE LETTER TI;Lu;0;L;;;;;N;;;;ABA8;\n13D9;CHEROKEE LETTER DO;Lu;0;L;;;;;N;;;;ABA9;\n13DA;CHEROKEE LETTER DU;Lu;0;L;;;;;N;;;;ABAA;\n13DB;CHEROKEE LETTER DV;Lu;0;L;;;;;N;;;;ABAB;\n13DC;CHEROKEE LETTER DLA;Lu;0;L;;;;;N;;;;ABAC;\n13DD;CHEROKEE LETTER TLA;Lu;0;L;;;;;N;;;;ABAD;\n13DE;CHEROKEE LETTER TLE;Lu;0;L;;;;;N;;;;ABAE;\n13DF;CHEROKEE LETTER TLI;Lu;0;L;;;;;N;;;;ABAF;\n13E0;CHEROKEE LETTER TLO;Lu;0;L;;;;;N;;;;ABB0;\n13E1;CHEROKEE LETTER TLU;Lu;0;L;;;;;N;;;;ABB1;\n13E2;CHEROKEE LETTER TLV;Lu;0;L;;;;;N;;;;ABB2;\n13E3;CHEROKEE LETTER TSA;Lu;0;L;;;;;N;;;;ABB3;\n13E4;CHEROKEE LETTER TSE;Lu;0;L;;;;;N;;;;ABB4;\n13E5;CHEROKEE LETTER TSI;Lu;0;L;;;;;N;;;;ABB5;\n13E6;CHEROKEE LETTER TSO;Lu;0;L;;;;;N;;;;ABB6;\n13E7;CHEROKEE LETTER TSU;Lu;0;L;;;;;N;;;;ABB7;\n13E8;CHEROKEE LETTER TSV;Lu;0;L;;;;;N;;;;ABB8;\n13E9;CHEROKEE LETTER WA;Lu;0;L;;;;;N;;;;ABB9;\n13EA;CHEROKEE LETTER WE;Lu;0;L;;;;;N;;;;ABBA;\n13EB;CHEROKEE LETTER WI;Lu;0;L;;;;;N;;;;ABBB;\n13EC;CHEROKEE LETTER WO;Lu;0;L;;;;;N;;;;ABBC;\n13ED;CHEROKEE LETTER WU;Lu;0;L;;;;;N;;;;ABBD;\n13EE;CHEROKEE LETTER WV;Lu;0;L;;;;;N;;;;ABBE;\n13EF;CHEROKEE LETTER YA;Lu;0;L;;;;;N;;;;ABBF;\n13F0;CHEROKEE LETTER YE;Lu;0;L;;;;;N;;;;13F8;\n13F1;CHEROKEE LETTER YI;Lu;0;L;;;;;N;;;;13F9;\n13F2;CHEROKEE LETTER YO;Lu;0;L;;;;;N;;;;13FA;\n13F3;CHEROKEE LETTER YU;Lu;0;L;;;;;N;;;;13FB;\n13F4;CHEROKEE LETTER YV;Lu;0;L;;;;;N;;;;13FC;\n13F5;CHEROKEE LETTER MV;Lu;0;L;;;;;N;;;;13FD;\n13F8;CHEROKEE SMALL LETTER YE;Ll;0;L;;;;;N;;;13F0;;13F0\n13F9;CHEROKEE SMALL LETTER YI;Ll;0;L;;;;;N;;;13F1;;13F1\n13FA;CHEROKEE SMALL LETTER YO;Ll;0;L;;;;;N;;;13F2;;13F2\n13FB;CHEROKEE SMALL LETTER YU;Ll;0;L;;;;;N;;;13F3;;13F3\n13FC;CHEROKEE SMALL LETTER YV;Ll;0;L;;;;;N;;;13F4;;13F4\n13FD;CHEROKEE SMALL LETTER MV;Ll;0;L;;;;;N;;;13F5;;13F5\n1400;CANADIAN SYLLABICS HYPHEN;Pd;0;ON;;;;;N;;;;;\n1401;CANADIAN SYLLABICS E;Lo;0;L;;;;;N;;;;;\n1402;CANADIAN SYLLABICS AAI;Lo;0;L;;;;;N;;;;;\n1403;CANADIAN SYLLABICS I;Lo;0;L;;;;;N;;;;;\n1404;CANADIAN SYLLABICS II;Lo;0;L;;;;;N;;;;;\n1405;CANADIAN SYLLABICS O;Lo;0;L;;;;;N;;;;;\n1406;CANADIAN SYLLABICS OO;Lo;0;L;;;;;N;;;;;\n1407;CANADIAN SYLLABICS Y-CREE OO;Lo;0;L;;;;;N;;;;;\n1408;CANADIAN SYLLABICS CARRIER EE;Lo;0;L;;;;;N;;;;;\n1409;CANADIAN SYLLABICS CARRIER I;Lo;0;L;;;;;N;;;;;\n140A;CANADIAN SYLLABICS A;Lo;0;L;;;;;N;;;;;\n140B;CANADIAN SYLLABICS AA;Lo;0;L;;;;;N;;;;;\n140C;CANADIAN SYLLABICS WE;Lo;0;L;;;;;N;;;;;\n140D;CANADIAN SYLLABICS WEST-CREE WE;Lo;0;L;;;;;N;;;;;\n140E;CANADIAN SYLLABICS WI;Lo;0;L;;;;;N;;;;;\n140F;CANADIAN SYLLABICS WEST-CREE WI;Lo;0;L;;;;;N;;;;;\n1410;CANADIAN SYLLABICS WII;Lo;0;L;;;;;N;;;;;\n1411;CANADIAN SYLLABICS WEST-CREE WII;Lo;0;L;;;;;N;;;;;\n1412;CANADIAN SYLLABICS WO;Lo;0;L;;;;;N;;;;;\n1413;CANADIAN SYLLABICS WEST-CREE WO;Lo;0;L;;;;;N;;;;;\n1414;CANADIAN SYLLABICS WOO;Lo;0;L;;;;;N;;;;;\n1415;CANADIAN SYLLABICS WEST-CREE WOO;Lo;0;L;;;;;N;;;;;\n1416;CANADIAN SYLLABICS NASKAPI WOO;Lo;0;L;;;;;N;;;;;\n1417;CANADIAN SYLLABICS WA;Lo;0;L;;;;;N;;;;;\n1418;CANADIAN SYLLABICS WEST-CREE WA;Lo;0;L;;;;;N;;;;;\n1419;CANADIAN SYLLABICS WAA;Lo;0;L;;;;;N;;;;;\n141A;CANADIAN SYLLABICS WEST-CREE WAA;Lo;0;L;;;;;N;;;;;\n141B;CANADIAN SYLLABICS NASKAPI WAA;Lo;0;L;;;;;N;;;;;\n141C;CANADIAN SYLLABICS AI;Lo;0;L;;;;;N;;;;;\n141D;CANADIAN SYLLABICS Y-CREE W;Lo;0;L;;;;;N;;;;;\n141E;CANADIAN SYLLABICS GLOTTAL STOP;Lo;0;L;;;;;N;;;;;\n141F;CANADIAN SYLLABICS FINAL ACUTE;Lo;0;L;;;;;N;;;;;\n1420;CANADIAN SYLLABICS FINAL GRAVE;Lo;0;L;;;;;N;;;;;\n1421;CANADIAN SYLLABICS FINAL BOTTOM HALF RING;Lo;0;L;;;;;N;;;;;\n1422;CANADIAN SYLLABICS FINAL TOP HALF RING;Lo;0;L;;;;;N;;;;;\n1423;CANADIAN SYLLABICS FINAL RIGHT HALF RING;Lo;0;L;;;;;N;;;;;\n1424;CANADIAN SYLLABICS FINAL RING;Lo;0;L;;;;;N;;;;;\n1425;CANADIAN SYLLABICS FINAL DOUBLE ACUTE;Lo;0;L;;;;;N;;;;;\n1426;CANADIAN SYLLABICS FINAL DOUBLE SHORT VERTICAL STROKES;Lo;0;L;;;;;N;;;;;\n1427;CANADIAN SYLLABICS FINAL MIDDLE DOT;Lo;0;L;;;;;N;;;;;\n1428;CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE;Lo;0;L;;;;;N;;;;;\n1429;CANADIAN SYLLABICS FINAL PLUS;Lo;0;L;;;;;N;;;;;\n142A;CANADIAN SYLLABICS FINAL DOWN TACK;Lo;0;L;;;;;N;;;;;\n142B;CANADIAN SYLLABICS EN;Lo;0;L;;;;;N;;;;;\n142C;CANADIAN SYLLABICS IN;Lo;0;L;;;;;N;;;;;\n142D;CANADIAN SYLLABICS ON;Lo;0;L;;;;;N;;;;;\n142E;CANADIAN SYLLABICS AN;Lo;0;L;;;;;N;;;;;\n142F;CANADIAN SYLLABICS PE;Lo;0;L;;;;;N;;;;;\n1430;CANADIAN SYLLABICS PAAI;Lo;0;L;;;;;N;;;;;\n1431;CANADIAN SYLLABICS PI;Lo;0;L;;;;;N;;;;;\n1432;CANADIAN SYLLABICS PII;Lo;0;L;;;;;N;;;;;\n1433;CANADIAN SYLLABICS PO;Lo;0;L;;;;;N;;;;;\n1434;CANADIAN SYLLABICS POO;Lo;0;L;;;;;N;;;;;\n1435;CANADIAN SYLLABICS Y-CREE POO;Lo;0;L;;;;;N;;;;;\n1436;CANADIAN SYLLABICS CARRIER HEE;Lo;0;L;;;;;N;;;;;\n1437;CANADIAN SYLLABICS CARRIER HI;Lo;0;L;;;;;N;;;;;\n1438;CANADIAN SYLLABICS PA;Lo;0;L;;;;;N;;;;;\n1439;CANADIAN SYLLABICS PAA;Lo;0;L;;;;;N;;;;;\n143A;CANADIAN SYLLABICS PWE;Lo;0;L;;;;;N;;;;;\n143B;CANADIAN SYLLABICS WEST-CREE PWE;Lo;0;L;;;;;N;;;;;\n143C;CANADIAN SYLLABICS PWI;Lo;0;L;;;;;N;;;;;\n143D;CANADIAN SYLLABICS WEST-CREE PWI;Lo;0;L;;;;;N;;;;;\n143E;CANADIAN SYLLABICS PWII;Lo;0;L;;;;;N;;;;;\n143F;CANADIAN SYLLABICS WEST-CREE PWII;Lo;0;L;;;;;N;;;;;\n1440;CANADIAN SYLLABICS PWO;Lo;0;L;;;;;N;;;;;\n1441;CANADIAN SYLLABICS WEST-CREE PWO;Lo;0;L;;;;;N;;;;;\n1442;CANADIAN SYLLABICS PWOO;Lo;0;L;;;;;N;;;;;\n1443;CANADIAN SYLLABICS WEST-CREE PWOO;Lo;0;L;;;;;N;;;;;\n1444;CANADIAN SYLLABICS PWA;Lo;0;L;;;;;N;;;;;\n1445;CANADIAN SYLLABICS WEST-CREE PWA;Lo;0;L;;;;;N;;;;;\n1446;CANADIAN SYLLABICS PWAA;Lo;0;L;;;;;N;;;;;\n1447;CANADIAN SYLLABICS WEST-CREE PWAA;Lo;0;L;;;;;N;;;;;\n1448;CANADIAN SYLLABICS Y-CREE PWAA;Lo;0;L;;;;;N;;;;;\n1449;CANADIAN SYLLABICS P;Lo;0;L;;;;;N;;;;;\n144A;CANADIAN SYLLABICS WEST-CREE P;Lo;0;L;;;;;N;;;;;\n144B;CANADIAN SYLLABICS CARRIER H;Lo;0;L;;;;;N;;;;;\n144C;CANADIAN SYLLABICS TE;Lo;0;L;;;;;N;;;;;\n144D;CANADIAN SYLLABICS TAAI;Lo;0;L;;;;;N;;;;;\n144E;CANADIAN SYLLABICS TI;Lo;0;L;;;;;N;;;;;\n144F;CANADIAN SYLLABICS TII;Lo;0;L;;;;;N;;;;;\n1450;CANADIAN SYLLABICS TO;Lo;0;L;;;;;N;;;;;\n1451;CANADIAN SYLLABICS TOO;Lo;0;L;;;;;N;;;;;\n1452;CANADIAN SYLLABICS Y-CREE TOO;Lo;0;L;;;;;N;;;;;\n1453;CANADIAN SYLLABICS CARRIER DEE;Lo;0;L;;;;;N;;;;;\n1454;CANADIAN SYLLABICS CARRIER DI;Lo;0;L;;;;;N;;;;;\n1455;CANADIAN SYLLABICS TA;Lo;0;L;;;;;N;;;;;\n1456;CANADIAN SYLLABICS TAA;Lo;0;L;;;;;N;;;;;\n1457;CANADIAN SYLLABICS TWE;Lo;0;L;;;;;N;;;;;\n1458;CANADIAN SYLLABICS WEST-CREE TWE;Lo;0;L;;;;;N;;;;;\n1459;CANADIAN SYLLABICS TWI;Lo;0;L;;;;;N;;;;;\n145A;CANADIAN SYLLABICS WEST-CREE TWI;Lo;0;L;;;;;N;;;;;\n145B;CANADIAN SYLLABICS TWII;Lo;0;L;;;;;N;;;;;\n145C;CANADIAN SYLLABICS WEST-CREE TWII;Lo;0;L;;;;;N;;;;;\n145D;CANADIAN SYLLABICS TWO;Lo;0;L;;;;;N;;;;;\n145E;CANADIAN SYLLABICS WEST-CREE TWO;Lo;0;L;;;;;N;;;;;\n145F;CANADIAN SYLLABICS TWOO;Lo;0;L;;;;;N;;;;;\n1460;CANADIAN SYLLABICS WEST-CREE TWOO;Lo;0;L;;;;;N;;;;;\n1461;CANADIAN SYLLABICS TWA;Lo;0;L;;;;;N;;;;;\n1462;CANADIAN SYLLABICS WEST-CREE TWA;Lo;0;L;;;;;N;;;;;\n1463;CANADIAN SYLLABICS TWAA;Lo;0;L;;;;;N;;;;;\n1464;CANADIAN SYLLABICS WEST-CREE TWAA;Lo;0;L;;;;;N;;;;;\n1465;CANADIAN SYLLABICS NASKAPI TWAA;Lo;0;L;;;;;N;;;;;\n1466;CANADIAN SYLLABICS T;Lo;0;L;;;;;N;;;;;\n1467;CANADIAN SYLLABICS TTE;Lo;0;L;;;;;N;;;;;\n1468;CANADIAN SYLLABICS TTI;Lo;0;L;;;;;N;;;;;\n1469;CANADIAN SYLLABICS TTO;Lo;0;L;;;;;N;;;;;\n146A;CANADIAN SYLLABICS TTA;Lo;0;L;;;;;N;;;;;\n146B;CANADIAN SYLLABICS KE;Lo;0;L;;;;;N;;;;;\n146C;CANADIAN SYLLABICS KAAI;Lo;0;L;;;;;N;;;;;\n146D;CANADIAN SYLLABICS KI;Lo;0;L;;;;;N;;;;;\n146E;CANADIAN SYLLABICS KII;Lo;0;L;;;;;N;;;;;\n146F;CANADIAN SYLLABICS KO;Lo;0;L;;;;;N;;;;;\n1470;CANADIAN SYLLABICS KOO;Lo;0;L;;;;;N;;;;;\n1471;CANADIAN SYLLABICS Y-CREE KOO;Lo;0;L;;;;;N;;;;;\n1472;CANADIAN SYLLABICS KA;Lo;0;L;;;;;N;;;;;\n1473;CANADIAN SYLLABICS KAA;Lo;0;L;;;;;N;;;;;\n1474;CANADIAN SYLLABICS KWE;Lo;0;L;;;;;N;;;;;\n1475;CANADIAN SYLLABICS WEST-CREE KWE;Lo;0;L;;;;;N;;;;;\n1476;CANADIAN SYLLABICS KWI;Lo;0;L;;;;;N;;;;;\n1477;CANADIAN SYLLABICS WEST-CREE KWI;Lo;0;L;;;;;N;;;;;\n1478;CANADIAN SYLLABICS KWII;Lo;0;L;;;;;N;;;;;\n1479;CANADIAN SYLLABICS WEST-CREE KWII;Lo;0;L;;;;;N;;;;;\n147A;CANADIAN SYLLABICS KWO;Lo;0;L;;;;;N;;;;;\n147B;CANADIAN SYLLABICS WEST-CREE KWO;Lo;0;L;;;;;N;;;;;\n147C;CANADIAN SYLLABICS KWOO;Lo;0;L;;;;;N;;;;;\n147D;CANADIAN SYLLABICS WEST-CREE KWOO;Lo;0;L;;;;;N;;;;;\n147E;CANADIAN SYLLABICS KWA;Lo;0;L;;;;;N;;;;;\n147F;CANADIAN SYLLABICS WEST-CREE KWA;Lo;0;L;;;;;N;;;;;\n1480;CANADIAN SYLLABICS KWAA;Lo;0;L;;;;;N;;;;;\n1481;CANADIAN SYLLABICS WEST-CREE KWAA;Lo;0;L;;;;;N;;;;;\n1482;CANADIAN SYLLABICS NASKAPI KWAA;Lo;0;L;;;;;N;;;;;\n1483;CANADIAN SYLLABICS K;Lo;0;L;;;;;N;;;;;\n1484;CANADIAN SYLLABICS KW;Lo;0;L;;;;;N;;;;;\n1485;CANADIAN SYLLABICS SOUTH-SLAVEY KEH;Lo;0;L;;;;;N;;;;;\n1486;CANADIAN SYLLABICS SOUTH-SLAVEY KIH;Lo;0;L;;;;;N;;;;;\n1487;CANADIAN SYLLABICS SOUTH-SLAVEY KOH;Lo;0;L;;;;;N;;;;;\n1488;CANADIAN SYLLABICS SOUTH-SLAVEY KAH;Lo;0;L;;;;;N;;;;;\n1489;CANADIAN SYLLABICS CE;Lo;0;L;;;;;N;;;;;\n148A;CANADIAN SYLLABICS CAAI;Lo;0;L;;;;;N;;;;;\n148B;CANADIAN SYLLABICS CI;Lo;0;L;;;;;N;;;;;\n148C;CANADIAN SYLLABICS CII;Lo;0;L;;;;;N;;;;;\n148D;CANADIAN SYLLABICS CO;Lo;0;L;;;;;N;;;;;\n148E;CANADIAN SYLLABICS COO;Lo;0;L;;;;;N;;;;;\n148F;CANADIAN SYLLABICS Y-CREE COO;Lo;0;L;;;;;N;;;;;\n1490;CANADIAN SYLLABICS CA;Lo;0;L;;;;;N;;;;;\n1491;CANADIAN SYLLABICS CAA;Lo;0;L;;;;;N;;;;;\n1492;CANADIAN SYLLABICS CWE;Lo;0;L;;;;;N;;;;;\n1493;CANADIAN SYLLABICS WEST-CREE CWE;Lo;0;L;;;;;N;;;;;\n1494;CANADIAN SYLLABICS CWI;Lo;0;L;;;;;N;;;;;\n1495;CANADIAN SYLLABICS WEST-CREE CWI;Lo;0;L;;;;;N;;;;;\n1496;CANADIAN SYLLABICS CWII;Lo;0;L;;;;;N;;;;;\n1497;CANADIAN SYLLABICS WEST-CREE CWII;Lo;0;L;;;;;N;;;;;\n1498;CANADIAN SYLLABICS CWO;Lo;0;L;;;;;N;;;;;\n1499;CANADIAN SYLLABICS WEST-CREE CWO;Lo;0;L;;;;;N;;;;;\n149A;CANADIAN SYLLABICS CWOO;Lo;0;L;;;;;N;;;;;\n149B;CANADIAN SYLLABICS WEST-CREE CWOO;Lo;0;L;;;;;N;;;;;\n149C;CANADIAN SYLLABICS CWA;Lo;0;L;;;;;N;;;;;\n149D;CANADIAN SYLLABICS WEST-CREE CWA;Lo;0;L;;;;;N;;;;;\n149E;CANADIAN SYLLABICS CWAA;Lo;0;L;;;;;N;;;;;\n149F;CANADIAN SYLLABICS WEST-CREE CWAA;Lo;0;L;;;;;N;;;;;\n14A0;CANADIAN SYLLABICS NASKAPI CWAA;Lo;0;L;;;;;N;;;;;\n14A1;CANADIAN SYLLABICS C;Lo;0;L;;;;;N;;;;;\n14A2;CANADIAN SYLLABICS SAYISI TH;Lo;0;L;;;;;N;;;;;\n14A3;CANADIAN SYLLABICS ME;Lo;0;L;;;;;N;;;;;\n14A4;CANADIAN SYLLABICS MAAI;Lo;0;L;;;;;N;;;;;\n14A5;CANADIAN SYLLABICS MI;Lo;0;L;;;;;N;;;;;\n14A6;CANADIAN SYLLABICS MII;Lo;0;L;;;;;N;;;;;\n14A7;CANADIAN SYLLABICS MO;Lo;0;L;;;;;N;;;;;\n14A8;CANADIAN SYLLABICS MOO;Lo;0;L;;;;;N;;;;;\n14A9;CANADIAN SYLLABICS Y-CREE MOO;Lo;0;L;;;;;N;;;;;\n14AA;CANADIAN SYLLABICS MA;Lo;0;L;;;;;N;;;;;\n14AB;CANADIAN SYLLABICS MAA;Lo;0;L;;;;;N;;;;;\n14AC;CANADIAN SYLLABICS MWE;Lo;0;L;;;;;N;;;;;\n14AD;CANADIAN SYLLABICS WEST-CREE MWE;Lo;0;L;;;;;N;;;;;\n14AE;CANADIAN SYLLABICS MWI;Lo;0;L;;;;;N;;;;;\n14AF;CANADIAN SYLLABICS WEST-CREE MWI;Lo;0;L;;;;;N;;;;;\n14B0;CANADIAN SYLLABICS MWII;Lo;0;L;;;;;N;;;;;\n14B1;CANADIAN SYLLABICS WEST-CREE MWII;Lo;0;L;;;;;N;;;;;\n14B2;CANADIAN SYLLABICS MWO;Lo;0;L;;;;;N;;;;;\n14B3;CANADIAN SYLLABICS WEST-CREE MWO;Lo;0;L;;;;;N;;;;;\n14B4;CANADIAN SYLLABICS MWOO;Lo;0;L;;;;;N;;;;;\n14B5;CANADIAN SYLLABICS WEST-CREE MWOO;Lo;0;L;;;;;N;;;;;\n14B6;CANADIAN SYLLABICS MWA;Lo;0;L;;;;;N;;;;;\n14B7;CANADIAN SYLLABICS WEST-CREE MWA;Lo;0;L;;;;;N;;;;;\n14B8;CANADIAN SYLLABICS MWAA;Lo;0;L;;;;;N;;;;;\n14B9;CANADIAN SYLLABICS WEST-CREE MWAA;Lo;0;L;;;;;N;;;;;\n14BA;CANADIAN SYLLABICS NASKAPI MWAA;Lo;0;L;;;;;N;;;;;\n14BB;CANADIAN SYLLABICS M;Lo;0;L;;;;;N;;;;;\n14BC;CANADIAN SYLLABICS WEST-CREE M;Lo;0;L;;;;;N;;;;;\n14BD;CANADIAN SYLLABICS MH;Lo;0;L;;;;;N;;;;;\n14BE;CANADIAN SYLLABICS ATHAPASCAN M;Lo;0;L;;;;;N;;;;;\n14BF;CANADIAN SYLLABICS SAYISI M;Lo;0;L;;;;;N;;;;;\n14C0;CANADIAN SYLLABICS NE;Lo;0;L;;;;;N;;;;;\n14C1;CANADIAN SYLLABICS NAAI;Lo;0;L;;;;;N;;;;;\n14C2;CANADIAN SYLLABICS NI;Lo;0;L;;;;;N;;;;;\n14C3;CANADIAN SYLLABICS NII;Lo;0;L;;;;;N;;;;;\n14C4;CANADIAN SYLLABICS NO;Lo;0;L;;;;;N;;;;;\n14C5;CANADIAN SYLLABICS NOO;Lo;0;L;;;;;N;;;;;\n14C6;CANADIAN SYLLABICS Y-CREE NOO;Lo;0;L;;;;;N;;;;;\n14C7;CANADIAN SYLLABICS NA;Lo;0;L;;;;;N;;;;;\n14C8;CANADIAN SYLLABICS NAA;Lo;0;L;;;;;N;;;;;\n14C9;CANADIAN SYLLABICS NWE;Lo;0;L;;;;;N;;;;;\n14CA;CANADIAN SYLLABICS WEST-CREE NWE;Lo;0;L;;;;;N;;;;;\n14CB;CANADIAN SYLLABICS NWA;Lo;0;L;;;;;N;;;;;\n14CC;CANADIAN SYLLABICS WEST-CREE NWA;Lo;0;L;;;;;N;;;;;\n14CD;CANADIAN SYLLABICS NWAA;Lo;0;L;;;;;N;;;;;\n14CE;CANADIAN SYLLABICS WEST-CREE NWAA;Lo;0;L;;;;;N;;;;;\n14CF;CANADIAN SYLLABICS NASKAPI NWAA;Lo;0;L;;;;;N;;;;;\n14D0;CANADIAN SYLLABICS N;Lo;0;L;;;;;N;;;;;\n14D1;CANADIAN SYLLABICS CARRIER NG;Lo;0;L;;;;;N;;;;;\n14D2;CANADIAN SYLLABICS NH;Lo;0;L;;;;;N;;;;;\n14D3;CANADIAN SYLLABICS LE;Lo;0;L;;;;;N;;;;;\n14D4;CANADIAN SYLLABICS LAAI;Lo;0;L;;;;;N;;;;;\n14D5;CANADIAN SYLLABICS LI;Lo;0;L;;;;;N;;;;;\n14D6;CANADIAN SYLLABICS LII;Lo;0;L;;;;;N;;;;;\n14D7;CANADIAN SYLLABICS LO;Lo;0;L;;;;;N;;;;;\n14D8;CANADIAN SYLLABICS LOO;Lo;0;L;;;;;N;;;;;\n14D9;CANADIAN SYLLABICS Y-CREE LOO;Lo;0;L;;;;;N;;;;;\n14DA;CANADIAN SYLLABICS LA;Lo;0;L;;;;;N;;;;;\n14DB;CANADIAN SYLLABICS LAA;Lo;0;L;;;;;N;;;;;\n14DC;CANADIAN SYLLABICS LWE;Lo;0;L;;;;;N;;;;;\n14DD;CANADIAN SYLLABICS WEST-CREE LWE;Lo;0;L;;;;;N;;;;;\n14DE;CANADIAN SYLLABICS LWI;Lo;0;L;;;;;N;;;;;\n14DF;CANADIAN SYLLABICS WEST-CREE LWI;Lo;0;L;;;;;N;;;;;\n14E0;CANADIAN SYLLABICS LWII;Lo;0;L;;;;;N;;;;;\n14E1;CANADIAN SYLLABICS WEST-CREE LWII;Lo;0;L;;;;;N;;;;;\n14E2;CANADIAN SYLLABICS LWO;Lo;0;L;;;;;N;;;;;\n14E3;CANADIAN SYLLABICS WEST-CREE LWO;Lo;0;L;;;;;N;;;;;\n14E4;CANADIAN SYLLABICS LWOO;Lo;0;L;;;;;N;;;;;\n14E5;CANADIAN SYLLABICS WEST-CREE LWOO;Lo;0;L;;;;;N;;;;;\n14E6;CANADIAN SYLLABICS LWA;Lo;0;L;;;;;N;;;;;\n14E7;CANADIAN SYLLABICS WEST-CREE LWA;Lo;0;L;;;;;N;;;;;\n14E8;CANADIAN SYLLABICS LWAA;Lo;0;L;;;;;N;;;;;\n14E9;CANADIAN SYLLABICS WEST-CREE LWAA;Lo;0;L;;;;;N;;;;;\n14EA;CANADIAN SYLLABICS L;Lo;0;L;;;;;N;;;;;\n14EB;CANADIAN SYLLABICS WEST-CREE L;Lo;0;L;;;;;N;;;;;\n14EC;CANADIAN SYLLABICS MEDIAL L;Lo;0;L;;;;;N;;;;;\n14ED;CANADIAN SYLLABICS SE;Lo;0;L;;;;;N;;;;;\n14EE;CANADIAN SYLLABICS SAAI;Lo;0;L;;;;;N;;;;;\n14EF;CANADIAN SYLLABICS SI;Lo;0;L;;;;;N;;;;;\n14F0;CANADIAN SYLLABICS SII;Lo;0;L;;;;;N;;;;;\n14F1;CANADIAN SYLLABICS SO;Lo;0;L;;;;;N;;;;;\n14F2;CANADIAN SYLLABICS SOO;Lo;0;L;;;;;N;;;;;\n14F3;CANADIAN SYLLABICS Y-CREE SOO;Lo;0;L;;;;;N;;;;;\n14F4;CANADIAN SYLLABICS SA;Lo;0;L;;;;;N;;;;;\n14F5;CANADIAN SYLLABICS SAA;Lo;0;L;;;;;N;;;;;\n14F6;CANADIAN SYLLABICS SWE;Lo;0;L;;;;;N;;;;;\n14F7;CANADIAN SYLLABICS WEST-CREE SWE;Lo;0;L;;;;;N;;;;;\n14F8;CANADIAN SYLLABICS SWI;Lo;0;L;;;;;N;;;;;\n14F9;CANADIAN SYLLABICS WEST-CREE SWI;Lo;0;L;;;;;N;;;;;\n14FA;CANADIAN SYLLABICS SWII;Lo;0;L;;;;;N;;;;;\n14FB;CANADIAN SYLLABICS WEST-CREE SWII;Lo;0;L;;;;;N;;;;;\n14FC;CANADIAN SYLLABICS SWO;Lo;0;L;;;;;N;;;;;\n14FD;CANADIAN SYLLABICS WEST-CREE SWO;Lo;0;L;;;;;N;;;;;\n14FE;CANADIAN SYLLABICS SWOO;Lo;0;L;;;;;N;;;;;\n14FF;CANADIAN SYLLABICS WEST-CREE SWOO;Lo;0;L;;;;;N;;;;;\n1500;CANADIAN SYLLABICS SWA;Lo;0;L;;;;;N;;;;;\n1501;CANADIAN SYLLABICS WEST-CREE SWA;Lo;0;L;;;;;N;;;;;\n1502;CANADIAN SYLLABICS SWAA;Lo;0;L;;;;;N;;;;;\n1503;CANADIAN SYLLABICS WEST-CREE SWAA;Lo;0;L;;;;;N;;;;;\n1504;CANADIAN SYLLABICS NASKAPI SWAA;Lo;0;L;;;;;N;;;;;\n1505;CANADIAN SYLLABICS S;Lo;0;L;;;;;N;;;;;\n1506;CANADIAN SYLLABICS ATHAPASCAN S;Lo;0;L;;;;;N;;;;;\n1507;CANADIAN SYLLABICS SW;Lo;0;L;;;;;N;;;;;\n1508;CANADIAN SYLLABICS BLACKFOOT S;Lo;0;L;;;;;N;;;;;\n1509;CANADIAN SYLLABICS MOOSE-CREE SK;Lo;0;L;;;;;N;;;;;\n150A;CANADIAN SYLLABICS NASKAPI SKW;Lo;0;L;;;;;N;;;;;\n150B;CANADIAN SYLLABICS NASKAPI S-W;Lo;0;L;;;;;N;;;;;\n150C;CANADIAN SYLLABICS NASKAPI SPWA;Lo;0;L;;;;;N;;;;;\n150D;CANADIAN SYLLABICS NASKAPI STWA;Lo;0;L;;;;;N;;;;;\n150E;CANADIAN SYLLABICS NASKAPI SKWA;Lo;0;L;;;;;N;;;;;\n150F;CANADIAN SYLLABICS NASKAPI SCWA;Lo;0;L;;;;;N;;;;;\n1510;CANADIAN SYLLABICS SHE;Lo;0;L;;;;;N;;;;;\n1511;CANADIAN SYLLABICS SHI;Lo;0;L;;;;;N;;;;;\n1512;CANADIAN SYLLABICS SHII;Lo;0;L;;;;;N;;;;;\n1513;CANADIAN SYLLABICS SHO;Lo;0;L;;;;;N;;;;;\n1514;CANADIAN SYLLABICS SHOO;Lo;0;L;;;;;N;;;;;\n1515;CANADIAN SYLLABICS SHA;Lo;0;L;;;;;N;;;;;\n1516;CANADIAN SYLLABICS SHAA;Lo;0;L;;;;;N;;;;;\n1517;CANADIAN SYLLABICS SHWE;Lo;0;L;;;;;N;;;;;\n1518;CANADIAN SYLLABICS WEST-CREE SHWE;Lo;0;L;;;;;N;;;;;\n1519;CANADIAN SYLLABICS SHWI;Lo;0;L;;;;;N;;;;;\n151A;CANADIAN SYLLABICS WEST-CREE SHWI;Lo;0;L;;;;;N;;;;;\n151B;CANADIAN SYLLABICS SHWII;Lo;0;L;;;;;N;;;;;\n151C;CANADIAN SYLLABICS WEST-CREE SHWII;Lo;0;L;;;;;N;;;;;\n151D;CANADIAN SYLLABICS SHWO;Lo;0;L;;;;;N;;;;;\n151E;CANADIAN SYLLABICS WEST-CREE SHWO;Lo;0;L;;;;;N;;;;;\n151F;CANADIAN SYLLABICS SHWOO;Lo;0;L;;;;;N;;;;;\n1520;CANADIAN SYLLABICS WEST-CREE SHWOO;Lo;0;L;;;;;N;;;;;\n1521;CANADIAN SYLLABICS SHWA;Lo;0;L;;;;;N;;;;;\n1522;CANADIAN SYLLABICS WEST-CREE SHWA;Lo;0;L;;;;;N;;;;;\n1523;CANADIAN SYLLABICS SHWAA;Lo;0;L;;;;;N;;;;;\n1524;CANADIAN SYLLABICS WEST-CREE SHWAA;Lo;0;L;;;;;N;;;;;\n1525;CANADIAN SYLLABICS SH;Lo;0;L;;;;;N;;;;;\n1526;CANADIAN SYLLABICS YE;Lo;0;L;;;;;N;;;;;\n1527;CANADIAN SYLLABICS YAAI;Lo;0;L;;;;;N;;;;;\n1528;CANADIAN SYLLABICS YI;Lo;0;L;;;;;N;;;;;\n1529;CANADIAN SYLLABICS YII;Lo;0;L;;;;;N;;;;;\n152A;CANADIAN SYLLABICS YO;Lo;0;L;;;;;N;;;;;\n152B;CANADIAN SYLLABICS YOO;Lo;0;L;;;;;N;;;;;\n152C;CANADIAN SYLLABICS Y-CREE YOO;Lo;0;L;;;;;N;;;;;\n152D;CANADIAN SYLLABICS YA;Lo;0;L;;;;;N;;;;;\n152E;CANADIAN SYLLABICS YAA;Lo;0;L;;;;;N;;;;;\n152F;CANADIAN SYLLABICS YWE;Lo;0;L;;;;;N;;;;;\n1530;CANADIAN SYLLABICS WEST-CREE YWE;Lo;0;L;;;;;N;;;;;\n1531;CANADIAN SYLLABICS YWI;Lo;0;L;;;;;N;;;;;\n1532;CANADIAN SYLLABICS WEST-CREE YWI;Lo;0;L;;;;;N;;;;;\n1533;CANADIAN SYLLABICS YWII;Lo;0;L;;;;;N;;;;;\n1534;CANADIAN SYLLABICS WEST-CREE YWII;Lo;0;L;;;;;N;;;;;\n1535;CANADIAN SYLLABICS YWO;Lo;0;L;;;;;N;;;;;\n1536;CANADIAN SYLLABICS WEST-CREE YWO;Lo;0;L;;;;;N;;;;;\n1537;CANADIAN SYLLABICS YWOO;Lo;0;L;;;;;N;;;;;\n1538;CANADIAN SYLLABICS WEST-CREE YWOO;Lo;0;L;;;;;N;;;;;\n1539;CANADIAN SYLLABICS YWA;Lo;0;L;;;;;N;;;;;\n153A;CANADIAN SYLLABICS WEST-CREE YWA;Lo;0;L;;;;;N;;;;;\n153B;CANADIAN SYLLABICS YWAA;Lo;0;L;;;;;N;;;;;\n153C;CANADIAN SYLLABICS WEST-CREE YWAA;Lo;0;L;;;;;N;;;;;\n153D;CANADIAN SYLLABICS NASKAPI YWAA;Lo;0;L;;;;;N;;;;;\n153E;CANADIAN SYLLABICS Y;Lo;0;L;;;;;N;;;;;\n153F;CANADIAN SYLLABICS BIBLE-CREE Y;Lo;0;L;;;;;N;;;;;\n1540;CANADIAN SYLLABICS WEST-CREE Y;Lo;0;L;;;;;N;;;;;\n1541;CANADIAN SYLLABICS SAYISI YI;Lo;0;L;;;;;N;;;;;\n1542;CANADIAN SYLLABICS RE;Lo;0;L;;;;;N;;;;;\n1543;CANADIAN SYLLABICS R-CREE RE;Lo;0;L;;;;;N;;;;;\n1544;CANADIAN SYLLABICS WEST-CREE LE;Lo;0;L;;;;;N;;;;;\n1545;CANADIAN SYLLABICS RAAI;Lo;0;L;;;;;N;;;;;\n1546;CANADIAN SYLLABICS RI;Lo;0;L;;;;;N;;;;;\n1547;CANADIAN SYLLABICS RII;Lo;0;L;;;;;N;;;;;\n1548;CANADIAN SYLLABICS RO;Lo;0;L;;;;;N;;;;;\n1549;CANADIAN SYLLABICS ROO;Lo;0;L;;;;;N;;;;;\n154A;CANADIAN SYLLABICS WEST-CREE LO;Lo;0;L;;;;;N;;;;;\n154B;CANADIAN SYLLABICS RA;Lo;0;L;;;;;N;;;;;\n154C;CANADIAN SYLLABICS RAA;Lo;0;L;;;;;N;;;;;\n154D;CANADIAN SYLLABICS WEST-CREE LA;Lo;0;L;;;;;N;;;;;\n154E;CANADIAN SYLLABICS RWAA;Lo;0;L;;;;;N;;;;;\n154F;CANADIAN SYLLABICS WEST-CREE RWAA;Lo;0;L;;;;;N;;;;;\n1550;CANADIAN SYLLABICS R;Lo;0;L;;;;;N;;;;;\n1551;CANADIAN SYLLABICS WEST-CREE R;Lo;0;L;;;;;N;;;;;\n1552;CANADIAN SYLLABICS MEDIAL R;Lo;0;L;;;;;N;;;;;\n1553;CANADIAN SYLLABICS FE;Lo;0;L;;;;;N;;;;;\n1554;CANADIAN SYLLABICS FAAI;Lo;0;L;;;;;N;;;;;\n1555;CANADIAN SYLLABICS FI;Lo;0;L;;;;;N;;;;;\n1556;CANADIAN SYLLABICS FII;Lo;0;L;;;;;N;;;;;\n1557;CANADIAN SYLLABICS FO;Lo;0;L;;;;;N;;;;;\n1558;CANADIAN SYLLABICS FOO;Lo;0;L;;;;;N;;;;;\n1559;CANADIAN SYLLABICS FA;Lo;0;L;;;;;N;;;;;\n155A;CANADIAN SYLLABICS FAA;Lo;0;L;;;;;N;;;;;\n155B;CANADIAN SYLLABICS FWAA;Lo;0;L;;;;;N;;;;;\n155C;CANADIAN SYLLABICS WEST-CREE FWAA;Lo;0;L;;;;;N;;;;;\n155D;CANADIAN SYLLABICS F;Lo;0;L;;;;;N;;;;;\n155E;CANADIAN SYLLABICS THE;Lo;0;L;;;;;N;;;;;\n155F;CANADIAN SYLLABICS N-CREE THE;Lo;0;L;;;;;N;;;;;\n1560;CANADIAN SYLLABICS THI;Lo;0;L;;;;;N;;;;;\n1561;CANADIAN SYLLABICS N-CREE THI;Lo;0;L;;;;;N;;;;;\n1562;CANADIAN SYLLABICS THII;Lo;0;L;;;;;N;;;;;\n1563;CANADIAN SYLLABICS N-CREE THII;Lo;0;L;;;;;N;;;;;\n1564;CANADIAN SYLLABICS THO;Lo;0;L;;;;;N;;;;;\n1565;CANADIAN SYLLABICS THOO;Lo;0;L;;;;;N;;;;;\n1566;CANADIAN SYLLABICS THA;Lo;0;L;;;;;N;;;;;\n1567;CANADIAN SYLLABICS THAA;Lo;0;L;;;;;N;;;;;\n1568;CANADIAN SYLLABICS THWAA;Lo;0;L;;;;;N;;;;;\n1569;CANADIAN SYLLABICS WEST-CREE THWAA;Lo;0;L;;;;;N;;;;;\n156A;CANADIAN SYLLABICS TH;Lo;0;L;;;;;N;;;;;\n156B;CANADIAN SYLLABICS TTHE;Lo;0;L;;;;;N;;;;;\n156C;CANADIAN SYLLABICS TTHI;Lo;0;L;;;;;N;;;;;\n156D;CANADIAN SYLLABICS TTHO;Lo;0;L;;;;;N;;;;;\n156E;CANADIAN SYLLABICS TTHA;Lo;0;L;;;;;N;;;;;\n156F;CANADIAN SYLLABICS TTH;Lo;0;L;;;;;N;;;;;\n1570;CANADIAN SYLLABICS TYE;Lo;0;L;;;;;N;;;;;\n1571;CANADIAN SYLLABICS TYI;Lo;0;L;;;;;N;;;;;\n1572;CANADIAN SYLLABICS TYO;Lo;0;L;;;;;N;;;;;\n1573;CANADIAN SYLLABICS TYA;Lo;0;L;;;;;N;;;;;\n1574;CANADIAN SYLLABICS NUNAVIK HE;Lo;0;L;;;;;N;;;;;\n1575;CANADIAN SYLLABICS NUNAVIK HI;Lo;0;L;;;;;N;;;;;\n1576;CANADIAN SYLLABICS NUNAVIK HII;Lo;0;L;;;;;N;;;;;\n1577;CANADIAN SYLLABICS NUNAVIK HO;Lo;0;L;;;;;N;;;;;\n1578;CANADIAN SYLLABICS NUNAVIK HOO;Lo;0;L;;;;;N;;;;;\n1579;CANADIAN SYLLABICS NUNAVIK HA;Lo;0;L;;;;;N;;;;;\n157A;CANADIAN SYLLABICS NUNAVIK HAA;Lo;0;L;;;;;N;;;;;\n157B;CANADIAN SYLLABICS NUNAVIK H;Lo;0;L;;;;;N;;;;;\n157C;CANADIAN SYLLABICS NUNAVUT H;Lo;0;L;;;;;N;;;;;\n157D;CANADIAN SYLLABICS HK;Lo;0;L;;;;;N;;;;;\n157E;CANADIAN SYLLABICS QAAI;Lo;0;L;;;;;N;;;;;\n157F;CANADIAN SYLLABICS QI;Lo;0;L;;;;;N;;;;;\n1580;CANADIAN SYLLABICS QII;Lo;0;L;;;;;N;;;;;\n1581;CANADIAN SYLLABICS QO;Lo;0;L;;;;;N;;;;;\n1582;CANADIAN SYLLABICS QOO;Lo;0;L;;;;;N;;;;;\n1583;CANADIAN SYLLABICS QA;Lo;0;L;;;;;N;;;;;\n1584;CANADIAN SYLLABICS QAA;Lo;0;L;;;;;N;;;;;\n1585;CANADIAN SYLLABICS Q;Lo;0;L;;;;;N;;;;;\n1586;CANADIAN SYLLABICS TLHE;Lo;0;L;;;;;N;;;;;\n1587;CANADIAN SYLLABICS TLHI;Lo;0;L;;;;;N;;;;;\n1588;CANADIAN SYLLABICS TLHO;Lo;0;L;;;;;N;;;;;\n1589;CANADIAN SYLLABICS TLHA;Lo;0;L;;;;;N;;;;;\n158A;CANADIAN SYLLABICS WEST-CREE RE;Lo;0;L;;;;;N;;;;;\n158B;CANADIAN SYLLABICS WEST-CREE RI;Lo;0;L;;;;;N;;;;;\n158C;CANADIAN SYLLABICS WEST-CREE RO;Lo;0;L;;;;;N;;;;;\n158D;CANADIAN SYLLABICS WEST-CREE RA;Lo;0;L;;;;;N;;;;;\n158E;CANADIAN SYLLABICS NGAAI;Lo;0;L;;;;;N;;;;;\n158F;CANADIAN SYLLABICS NGI;Lo;0;L;;;;;N;;;;;\n1590;CANADIAN SYLLABICS NGII;Lo;0;L;;;;;N;;;;;\n1591;CANADIAN SYLLABICS NGO;Lo;0;L;;;;;N;;;;;\n1592;CANADIAN SYLLABICS NGOO;Lo;0;L;;;;;N;;;;;\n1593;CANADIAN SYLLABICS NGA;Lo;0;L;;;;;N;;;;;\n1594;CANADIAN SYLLABICS NGAA;Lo;0;L;;;;;N;;;;;\n1595;CANADIAN SYLLABICS NG;Lo;0;L;;;;;N;;;;;\n1596;CANADIAN SYLLABICS NNG;Lo;0;L;;;;;N;;;;;\n1597;CANADIAN SYLLABICS SAYISI SHE;Lo;0;L;;;;;N;;;;;\n1598;CANADIAN SYLLABICS SAYISI SHI;Lo;0;L;;;;;N;;;;;\n1599;CANADIAN SYLLABICS SAYISI SHO;Lo;0;L;;;;;N;;;;;\n159A;CANADIAN SYLLABICS SAYISI SHA;Lo;0;L;;;;;N;;;;;\n159B;CANADIAN SYLLABICS WOODS-CREE THE;Lo;0;L;;;;;N;;;;;\n159C;CANADIAN SYLLABICS WOODS-CREE THI;Lo;0;L;;;;;N;;;;;\n159D;CANADIAN SYLLABICS WOODS-CREE THO;Lo;0;L;;;;;N;;;;;\n159E;CANADIAN SYLLABICS WOODS-CREE THA;Lo;0;L;;;;;N;;;;;\n159F;CANADIAN SYLLABICS WOODS-CREE TH;Lo;0;L;;;;;N;;;;;\n15A0;CANADIAN SYLLABICS LHI;Lo;0;L;;;;;N;;;;;\n15A1;CANADIAN SYLLABICS LHII;Lo;0;L;;;;;N;;;;;\n15A2;CANADIAN SYLLABICS LHO;Lo;0;L;;;;;N;;;;;\n15A3;CANADIAN SYLLABICS LHOO;Lo;0;L;;;;;N;;;;;\n15A4;CANADIAN SYLLABICS LHA;Lo;0;L;;;;;N;;;;;\n15A5;CANADIAN SYLLABICS LHAA;Lo;0;L;;;;;N;;;;;\n15A6;CANADIAN SYLLABICS LH;Lo;0;L;;;;;N;;;;;\n15A7;CANADIAN SYLLABICS TH-CREE THE;Lo;0;L;;;;;N;;;;;\n15A8;CANADIAN SYLLABICS TH-CREE THI;Lo;0;L;;;;;N;;;;;\n15A9;CANADIAN SYLLABICS TH-CREE THII;Lo;0;L;;;;;N;;;;;\n15AA;CANADIAN SYLLABICS TH-CREE THO;Lo;0;L;;;;;N;;;;;\n15AB;CANADIAN SYLLABICS TH-CREE THOO;Lo;0;L;;;;;N;;;;;\n15AC;CANADIAN SYLLABICS TH-CREE THA;Lo;0;L;;;;;N;;;;;\n15AD;CANADIAN SYLLABICS TH-CREE THAA;Lo;0;L;;;;;N;;;;;\n15AE;CANADIAN SYLLABICS TH-CREE TH;Lo;0;L;;;;;N;;;;;\n15AF;CANADIAN SYLLABICS AIVILIK B;Lo;0;L;;;;;N;;;;;\n15B0;CANADIAN SYLLABICS BLACKFOOT E;Lo;0;L;;;;;N;;;;;\n15B1;CANADIAN SYLLABICS BLACKFOOT I;Lo;0;L;;;;;N;;;;;\n15B2;CANADIAN SYLLABICS BLACKFOOT O;Lo;0;L;;;;;N;;;;;\n15B3;CANADIAN SYLLABICS BLACKFOOT A;Lo;0;L;;;;;N;;;;;\n15B4;CANADIAN SYLLABICS BLACKFOOT WE;Lo;0;L;;;;;N;;;;;\n15B5;CANADIAN SYLLABICS BLACKFOOT WI;Lo;0;L;;;;;N;;;;;\n15B6;CANADIAN SYLLABICS BLACKFOOT WO;Lo;0;L;;;;;N;;;;;\n15B7;CANADIAN SYLLABICS BLACKFOOT WA;Lo;0;L;;;;;N;;;;;\n15B8;CANADIAN SYLLABICS BLACKFOOT NE;Lo;0;L;;;;;N;;;;;\n15B9;CANADIAN SYLLABICS BLACKFOOT NI;Lo;0;L;;;;;N;;;;;\n15BA;CANADIAN SYLLABICS BLACKFOOT NO;Lo;0;L;;;;;N;;;;;\n15BB;CANADIAN SYLLABICS BLACKFOOT NA;Lo;0;L;;;;;N;;;;;\n15BC;CANADIAN SYLLABICS BLACKFOOT KE;Lo;0;L;;;;;N;;;;;\n15BD;CANADIAN SYLLABICS BLACKFOOT KI;Lo;0;L;;;;;N;;;;;\n15BE;CANADIAN SYLLABICS BLACKFOOT KO;Lo;0;L;;;;;N;;;;;\n15BF;CANADIAN SYLLABICS BLACKFOOT KA;Lo;0;L;;;;;N;;;;;\n15C0;CANADIAN SYLLABICS SAYISI HE;Lo;0;L;;;;;N;;;;;\n15C1;CANADIAN SYLLABICS SAYISI HI;Lo;0;L;;;;;N;;;;;\n15C2;CANADIAN SYLLABICS SAYISI HO;Lo;0;L;;;;;N;;;;;\n15C3;CANADIAN SYLLABICS SAYISI HA;Lo;0;L;;;;;N;;;;;\n15C4;CANADIAN SYLLABICS CARRIER GHU;Lo;0;L;;;;;N;;;;;\n15C5;CANADIAN SYLLABICS CARRIER GHO;Lo;0;L;;;;;N;;;;;\n15C6;CANADIAN SYLLABICS CARRIER GHE;Lo;0;L;;;;;N;;;;;\n15C7;CANADIAN SYLLABICS CARRIER GHEE;Lo;0;L;;;;;N;;;;;\n15C8;CANADIAN SYLLABICS CARRIER GHI;Lo;0;L;;;;;N;;;;;\n15C9;CANADIAN SYLLABICS CARRIER GHA;Lo;0;L;;;;;N;;;;;\n15CA;CANADIAN SYLLABICS CARRIER RU;Lo;0;L;;;;;N;;;;;\n15CB;CANADIAN SYLLABICS CARRIER RO;Lo;0;L;;;;;N;;;;;\n15CC;CANADIAN SYLLABICS CARRIER RE;Lo;0;L;;;;;N;;;;;\n15CD;CANADIAN SYLLABICS CARRIER REE;Lo;0;L;;;;;N;;;;;\n15CE;CANADIAN SYLLABICS CARRIER RI;Lo;0;L;;;;;N;;;;;\n15CF;CANADIAN SYLLABICS CARRIER RA;Lo;0;L;;;;;N;;;;;\n15D0;CANADIAN SYLLABICS CARRIER WU;Lo;0;L;;;;;N;;;;;\n15D1;CANADIAN SYLLABICS CARRIER WO;Lo;0;L;;;;;N;;;;;\n15D2;CANADIAN SYLLABICS CARRIER WE;Lo;0;L;;;;;N;;;;;\n15D3;CANADIAN SYLLABICS CARRIER WEE;Lo;0;L;;;;;N;;;;;\n15D4;CANADIAN SYLLABICS CARRIER WI;Lo;0;L;;;;;N;;;;;\n15D5;CANADIAN SYLLABICS CARRIER WA;Lo;0;L;;;;;N;;;;;\n15D6;CANADIAN SYLLABICS CARRIER HWU;Lo;0;L;;;;;N;;;;;\n15D7;CANADIAN SYLLABICS CARRIER HWO;Lo;0;L;;;;;N;;;;;\n15D8;CANADIAN SYLLABICS CARRIER HWE;Lo;0;L;;;;;N;;;;;\n15D9;CANADIAN SYLLABICS CARRIER HWEE;Lo;0;L;;;;;N;;;;;\n15DA;CANADIAN SYLLABICS CARRIER HWI;Lo;0;L;;;;;N;;;;;\n15DB;CANADIAN SYLLABICS CARRIER HWA;Lo;0;L;;;;;N;;;;;\n15DC;CANADIAN SYLLABICS CARRIER THU;Lo;0;L;;;;;N;;;;;\n15DD;CANADIAN SYLLABICS CARRIER THO;Lo;0;L;;;;;N;;;;;\n15DE;CANADIAN SYLLABICS CARRIER THE;Lo;0;L;;;;;N;;;;;\n15DF;CANADIAN SYLLABICS CARRIER THEE;Lo;0;L;;;;;N;;;;;\n15E0;CANADIAN SYLLABICS CARRIER THI;Lo;0;L;;;;;N;;;;;\n15E1;CANADIAN SYLLABICS CARRIER THA;Lo;0;L;;;;;N;;;;;\n15E2;CANADIAN SYLLABICS CARRIER TTU;Lo;0;L;;;;;N;;;;;\n15E3;CANADIAN SYLLABICS CARRIER TTO;Lo;0;L;;;;;N;;;;;\n15E4;CANADIAN SYLLABICS CARRIER TTE;Lo;0;L;;;;;N;;;;;\n15E5;CANADIAN SYLLABICS CARRIER TTEE;Lo;0;L;;;;;N;;;;;\n15E6;CANADIAN SYLLABICS CARRIER TTI;Lo;0;L;;;;;N;;;;;\n15E7;CANADIAN SYLLABICS CARRIER TTA;Lo;0;L;;;;;N;;;;;\n15E8;CANADIAN SYLLABICS CARRIER PU;Lo;0;L;;;;;N;;;;;\n15E9;CANADIAN SYLLABICS CARRIER PO;Lo;0;L;;;;;N;;;;;\n15EA;CANADIAN SYLLABICS CARRIER PE;Lo;0;L;;;;;N;;;;;\n15EB;CANADIAN SYLLABICS CARRIER PEE;Lo;0;L;;;;;N;;;;;\n15EC;CANADIAN SYLLABICS CARRIER PI;Lo;0;L;;;;;N;;;;;\n15ED;CANADIAN SYLLABICS CARRIER PA;Lo;0;L;;;;;N;;;;;\n15EE;CANADIAN SYLLABICS CARRIER P;Lo;0;L;;;;;N;;;;;\n15EF;CANADIAN SYLLABICS CARRIER GU;Lo;0;L;;;;;N;;;;;\n15F0;CANADIAN SYLLABICS CARRIER GO;Lo;0;L;;;;;N;;;;;\n15F1;CANADIAN SYLLABICS CARRIER GE;Lo;0;L;;;;;N;;;;;\n15F2;CANADIAN SYLLABICS CARRIER GEE;Lo;0;L;;;;;N;;;;;\n15F3;CANADIAN SYLLABICS CARRIER GI;Lo;0;L;;;;;N;;;;;\n15F4;CANADIAN SYLLABICS CARRIER GA;Lo;0;L;;;;;N;;;;;\n15F5;CANADIAN SYLLABICS CARRIER KHU;Lo;0;L;;;;;N;;;;;\n15F6;CANADIAN SYLLABICS CARRIER KHO;Lo;0;L;;;;;N;;;;;\n15F7;CANADIAN SYLLABICS CARRIER KHE;Lo;0;L;;;;;N;;;;;\n15F8;CANADIAN SYLLABICS CARRIER KHEE;Lo;0;L;;;;;N;;;;;\n15F9;CANADIAN SYLLABICS CARRIER KHI;Lo;0;L;;;;;N;;;;;\n15FA;CANADIAN SYLLABICS CARRIER KHA;Lo;0;L;;;;;N;;;;;\n15FB;CANADIAN SYLLABICS CARRIER KKU;Lo;0;L;;;;;N;;;;;\n15FC;CANADIAN SYLLABICS CARRIER KKO;Lo;0;L;;;;;N;;;;;\n15FD;CANADIAN SYLLABICS CARRIER KKE;Lo;0;L;;;;;N;;;;;\n15FE;CANADIAN SYLLABICS CARRIER KKEE;Lo;0;L;;;;;N;;;;;\n15FF;CANADIAN SYLLABICS CARRIER KKI;Lo;0;L;;;;;N;;;;;\n1600;CANADIAN SYLLABICS CARRIER KKA;Lo;0;L;;;;;N;;;;;\n1601;CANADIAN SYLLABICS CARRIER KK;Lo;0;L;;;;;N;;;;;\n1602;CANADIAN SYLLABICS CARRIER NU;Lo;0;L;;;;;N;;;;;\n1603;CANADIAN SYLLABICS CARRIER NO;Lo;0;L;;;;;N;;;;;\n1604;CANADIAN SYLLABICS CARRIER NE;Lo;0;L;;;;;N;;;;;\n1605;CANADIAN SYLLABICS CARRIER NEE;Lo;0;L;;;;;N;;;;;\n1606;CANADIAN SYLLABICS CARRIER NI;Lo;0;L;;;;;N;;;;;\n1607;CANADIAN SYLLABICS CARRIER NA;Lo;0;L;;;;;N;;;;;\n1608;CANADIAN SYLLABICS CARRIER MU;Lo;0;L;;;;;N;;;;;\n1609;CANADIAN SYLLABICS CARRIER MO;Lo;0;L;;;;;N;;;;;\n160A;CANADIAN SYLLABICS CARRIER ME;Lo;0;L;;;;;N;;;;;\n160B;CANADIAN SYLLABICS CARRIER MEE;Lo;0;L;;;;;N;;;;;\n160C;CANADIAN SYLLABICS CARRIER MI;Lo;0;L;;;;;N;;;;;\n160D;CANADIAN SYLLABICS CARRIER MA;Lo;0;L;;;;;N;;;;;\n160E;CANADIAN SYLLABICS CARRIER YU;Lo;0;L;;;;;N;;;;;\n160F;CANADIAN SYLLABICS CARRIER YO;Lo;0;L;;;;;N;;;;;\n1610;CANADIAN SYLLABICS CARRIER YE;Lo;0;L;;;;;N;;;;;\n1611;CANADIAN SYLLABICS CARRIER YEE;Lo;0;L;;;;;N;;;;;\n1612;CANADIAN SYLLABICS CARRIER YI;Lo;0;L;;;;;N;;;;;\n1613;CANADIAN SYLLABICS CARRIER YA;Lo;0;L;;;;;N;;;;;\n1614;CANADIAN SYLLABICS CARRIER JU;Lo;0;L;;;;;N;;;;;\n1615;CANADIAN SYLLABICS SAYISI JU;Lo;0;L;;;;;N;;;;;\n1616;CANADIAN SYLLABICS CARRIER JO;Lo;0;L;;;;;N;;;;;\n1617;CANADIAN SYLLABICS CARRIER JE;Lo;0;L;;;;;N;;;;;\n1618;CANADIAN SYLLABICS CARRIER JEE;Lo;0;L;;;;;N;;;;;\n1619;CANADIAN SYLLABICS CARRIER JI;Lo;0;L;;;;;N;;;;;\n161A;CANADIAN SYLLABICS SAYISI JI;Lo;0;L;;;;;N;;;;;\n161B;CANADIAN SYLLABICS CARRIER JA;Lo;0;L;;;;;N;;;;;\n161C;CANADIAN SYLLABICS CARRIER JJU;Lo;0;L;;;;;N;;;;;\n161D;CANADIAN SYLLABICS CARRIER JJO;Lo;0;L;;;;;N;;;;;\n161E;CANADIAN SYLLABICS CARRIER JJE;Lo;0;L;;;;;N;;;;;\n161F;CANADIAN SYLLABICS CARRIER JJEE;Lo;0;L;;;;;N;;;;;\n1620;CANADIAN SYLLABICS CARRIER JJI;Lo;0;L;;;;;N;;;;;\n1621;CANADIAN SYLLABICS CARRIER JJA;Lo;0;L;;;;;N;;;;;\n1622;CANADIAN SYLLABICS CARRIER LU;Lo;0;L;;;;;N;;;;;\n1623;CANADIAN SYLLABICS CARRIER LO;Lo;0;L;;;;;N;;;;;\n1624;CANADIAN SYLLABICS CARRIER LE;Lo;0;L;;;;;N;;;;;\n1625;CANADIAN SYLLABICS CARRIER LEE;Lo;0;L;;;;;N;;;;;\n1626;CANADIAN SYLLABICS CARRIER LI;Lo;0;L;;;;;N;;;;;\n1627;CANADIAN SYLLABICS CARRIER LA;Lo;0;L;;;;;N;;;;;\n1628;CANADIAN SYLLABICS CARRIER DLU;Lo;0;L;;;;;N;;;;;\n1629;CANADIAN SYLLABICS CARRIER DLO;Lo;0;L;;;;;N;;;;;\n162A;CANADIAN SYLLABICS CARRIER DLE;Lo;0;L;;;;;N;;;;;\n162B;CANADIAN SYLLABICS CARRIER DLEE;Lo;0;L;;;;;N;;;;;\n162C;CANADIAN SYLLABICS CARRIER DLI;Lo;0;L;;;;;N;;;;;\n162D;CANADIAN SYLLABICS CARRIER DLA;Lo;0;L;;;;;N;;;;;\n162E;CANADIAN SYLLABICS CARRIER LHU;Lo;0;L;;;;;N;;;;;\n162F;CANADIAN SYLLABICS CARRIER LHO;Lo;0;L;;;;;N;;;;;\n1630;CANADIAN SYLLABICS CARRIER LHE;Lo;0;L;;;;;N;;;;;\n1631;CANADIAN SYLLABICS CARRIER LHEE;Lo;0;L;;;;;N;;;;;\n1632;CANADIAN SYLLABICS CARRIER LHI;Lo;0;L;;;;;N;;;;;\n1633;CANADIAN SYLLABICS CARRIER LHA;Lo;0;L;;;;;N;;;;;\n1634;CANADIAN SYLLABICS CARRIER TLHU;Lo;0;L;;;;;N;;;;;\n1635;CANADIAN SYLLABICS CARRIER TLHO;Lo;0;L;;;;;N;;;;;\n1636;CANADIAN SYLLABICS CARRIER TLHE;Lo;0;L;;;;;N;;;;;\n1637;CANADIAN SYLLABICS CARRIER TLHEE;Lo;0;L;;;;;N;;;;;\n1638;CANADIAN SYLLABICS CARRIER TLHI;Lo;0;L;;;;;N;;;;;\n1639;CANADIAN SYLLABICS CARRIER TLHA;Lo;0;L;;;;;N;;;;;\n163A;CANADIAN SYLLABICS CARRIER TLU;Lo;0;L;;;;;N;;;;;\n163B;CANADIAN SYLLABICS CARRIER TLO;Lo;0;L;;;;;N;;;;;\n163C;CANADIAN SYLLABICS CARRIER TLE;Lo;0;L;;;;;N;;;;;\n163D;CANADIAN SYLLABICS CARRIER TLEE;Lo;0;L;;;;;N;;;;;\n163E;CANADIAN SYLLABICS CARRIER TLI;Lo;0;L;;;;;N;;;;;\n163F;CANADIAN SYLLABICS CARRIER TLA;Lo;0;L;;;;;N;;;;;\n1640;CANADIAN SYLLABICS CARRIER ZU;Lo;0;L;;;;;N;;;;;\n1641;CANADIAN SYLLABICS CARRIER ZO;Lo;0;L;;;;;N;;;;;\n1642;CANADIAN SYLLABICS CARRIER ZE;Lo;0;L;;;;;N;;;;;\n1643;CANADIAN SYLLABICS CARRIER ZEE;Lo;0;L;;;;;N;;;;;\n1644;CANADIAN SYLLABICS CARRIER ZI;Lo;0;L;;;;;N;;;;;\n1645;CANADIAN SYLLABICS CARRIER ZA;Lo;0;L;;;;;N;;;;;\n1646;CANADIAN SYLLABICS CARRIER Z;Lo;0;L;;;;;N;;;;;\n1647;CANADIAN SYLLABICS CARRIER INITIAL Z;Lo;0;L;;;;;N;;;;;\n1648;CANADIAN SYLLABICS CARRIER DZU;Lo;0;L;;;;;N;;;;;\n1649;CANADIAN SYLLABICS CARRIER DZO;Lo;0;L;;;;;N;;;;;\n164A;CANADIAN SYLLABICS CARRIER DZE;Lo;0;L;;;;;N;;;;;\n164B;CANADIAN SYLLABICS CARRIER DZEE;Lo;0;L;;;;;N;;;;;\n164C;CANADIAN SYLLABICS CARRIER DZI;Lo;0;L;;;;;N;;;;;\n164D;CANADIAN SYLLABICS CARRIER DZA;Lo;0;L;;;;;N;;;;;\n164E;CANADIAN SYLLABICS CARRIER SU;Lo;0;L;;;;;N;;;;;\n164F;CANADIAN SYLLABICS CARRIER SO;Lo;0;L;;;;;N;;;;;\n1650;CANADIAN SYLLABICS CARRIER SE;Lo;0;L;;;;;N;;;;;\n1651;CANADIAN SYLLABICS CARRIER SEE;Lo;0;L;;;;;N;;;;;\n1652;CANADIAN SYLLABICS CARRIER SI;Lo;0;L;;;;;N;;;;;\n1653;CANADIAN SYLLABICS CARRIER SA;Lo;0;L;;;;;N;;;;;\n1654;CANADIAN SYLLABICS CARRIER SHU;Lo;0;L;;;;;N;;;;;\n1655;CANADIAN SYLLABICS CARRIER SHO;Lo;0;L;;;;;N;;;;;\n1656;CANADIAN SYLLABICS CARRIER SHE;Lo;0;L;;;;;N;;;;;\n1657;CANADIAN SYLLABICS CARRIER SHEE;Lo;0;L;;;;;N;;;;;\n1658;CANADIAN SYLLABICS CARRIER SHI;Lo;0;L;;;;;N;;;;;\n1659;CANADIAN SYLLABICS CARRIER SHA;Lo;0;L;;;;;N;;;;;\n165A;CANADIAN SYLLABICS CARRIER SH;Lo;0;L;;;;;N;;;;;\n165B;CANADIAN SYLLABICS CARRIER TSU;Lo;0;L;;;;;N;;;;;\n165C;CANADIAN SYLLABICS CARRIER TSO;Lo;0;L;;;;;N;;;;;\n165D;CANADIAN SYLLABICS CARRIER TSE;Lo;0;L;;;;;N;;;;;\n165E;CANADIAN SYLLABICS CARRIER TSEE;Lo;0;L;;;;;N;;;;;\n165F;CANADIAN SYLLABICS CARRIER TSI;Lo;0;L;;;;;N;;;;;\n1660;CANADIAN SYLLABICS CARRIER TSA;Lo;0;L;;;;;N;;;;;\n1661;CANADIAN SYLLABICS CARRIER CHU;Lo;0;L;;;;;N;;;;;\n1662;CANADIAN SYLLABICS CARRIER CHO;Lo;0;L;;;;;N;;;;;\n1663;CANADIAN SYLLABICS CARRIER CHE;Lo;0;L;;;;;N;;;;;\n1664;CANADIAN SYLLABICS CARRIER CHEE;Lo;0;L;;;;;N;;;;;\n1665;CANADIAN SYLLABICS CARRIER CHI;Lo;0;L;;;;;N;;;;;\n1666;CANADIAN SYLLABICS CARRIER CHA;Lo;0;L;;;;;N;;;;;\n1667;CANADIAN SYLLABICS CARRIER TTSU;Lo;0;L;;;;;N;;;;;\n1668;CANADIAN SYLLABICS CARRIER TTSO;Lo;0;L;;;;;N;;;;;\n1669;CANADIAN SYLLABICS CARRIER TTSE;Lo;0;L;;;;;N;;;;;\n166A;CANADIAN SYLLABICS CARRIER TTSEE;Lo;0;L;;;;;N;;;;;\n166B;CANADIAN SYLLABICS CARRIER TTSI;Lo;0;L;;;;;N;;;;;\n166C;CANADIAN SYLLABICS CARRIER TTSA;Lo;0;L;;;;;N;;;;;\n166D;CANADIAN SYLLABICS CHI SIGN;So;0;L;;;;;N;;;;;\n166E;CANADIAN SYLLABICS FULL STOP;Po;0;L;;;;;N;;;;;\n166F;CANADIAN SYLLABICS QAI;Lo;0;L;;;;;N;;;;;\n1670;CANADIAN SYLLABICS NGAI;Lo;0;L;;;;;N;;;;;\n1671;CANADIAN SYLLABICS NNGI;Lo;0;L;;;;;N;;;;;\n1672;CANADIAN SYLLABICS NNGII;Lo;0;L;;;;;N;;;;;\n1673;CANADIAN SYLLABICS NNGO;Lo;0;L;;;;;N;;;;;\n1674;CANADIAN SYLLABICS NNGOO;Lo;0;L;;;;;N;;;;;\n1675;CANADIAN SYLLABICS NNGA;Lo;0;L;;;;;N;;;;;\n1676;CANADIAN SYLLABICS NNGAA;Lo;0;L;;;;;N;;;;;\n1677;CANADIAN SYLLABICS WOODS-CREE THWEE;Lo;0;L;;;;;N;;;;;\n1678;CANADIAN SYLLABICS WOODS-CREE THWI;Lo;0;L;;;;;N;;;;;\n1679;CANADIAN SYLLABICS WOODS-CREE THWII;Lo;0;L;;;;;N;;;;;\n167A;CANADIAN SYLLABICS WOODS-CREE THWO;Lo;0;L;;;;;N;;;;;\n167B;CANADIAN SYLLABICS WOODS-CREE THWOO;Lo;0;L;;;;;N;;;;;\n167C;CANADIAN SYLLABICS WOODS-CREE THWA;Lo;0;L;;;;;N;;;;;\n167D;CANADIAN SYLLABICS WOODS-CREE THWAA;Lo;0;L;;;;;N;;;;;\n167E;CANADIAN SYLLABICS WOODS-CREE FINAL TH;Lo;0;L;;;;;N;;;;;\n167F;CANADIAN SYLLABICS BLACKFOOT W;Lo;0;L;;;;;N;;;;;\n1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;;\n1681;OGHAM LETTER BEITH;Lo;0;L;;;;;N;;;;;\n1682;OGHAM LETTER LUIS;Lo;0;L;;;;;N;;;;;\n1683;OGHAM LETTER FEARN;Lo;0;L;;;;;N;;;;;\n1684;OGHAM LETTER SAIL;Lo;0;L;;;;;N;;;;;\n1685;OGHAM LETTER NION;Lo;0;L;;;;;N;;;;;\n1686;OGHAM LETTER UATH;Lo;0;L;;;;;N;;;;;\n1687;OGHAM LETTER DAIR;Lo;0;L;;;;;N;;;;;\n1688;OGHAM LETTER TINNE;Lo;0;L;;;;;N;;;;;\n1689;OGHAM LETTER COLL;Lo;0;L;;;;;N;;;;;\n168A;OGHAM LETTER CEIRT;Lo;0;L;;;;;N;;;;;\n168B;OGHAM LETTER MUIN;Lo;0;L;;;;;N;;;;;\n168C;OGHAM LETTER GORT;Lo;0;L;;;;;N;;;;;\n168D;OGHAM LETTER NGEADAL;Lo;0;L;;;;;N;;;;;\n168E;OGHAM LETTER STRAIF;Lo;0;L;;;;;N;;;;;\n168F;OGHAM LETTER RUIS;Lo;0;L;;;;;N;;;;;\n1690;OGHAM LETTER AILM;Lo;0;L;;;;;N;;;;;\n1691;OGHAM LETTER ONN;Lo;0;L;;;;;N;;;;;\n1692;OGHAM LETTER UR;Lo;0;L;;;;;N;;;;;\n1693;OGHAM LETTER EADHADH;Lo;0;L;;;;;N;;;;;\n1694;OGHAM LETTER IODHADH;Lo;0;L;;;;;N;;;;;\n1695;OGHAM LETTER EABHADH;Lo;0;L;;;;;N;;;;;\n1696;OGHAM LETTER OR;Lo;0;L;;;;;N;;;;;\n1697;OGHAM LETTER UILLEANN;Lo;0;L;;;;;N;;;;;\n1698;OGHAM LETTER IFIN;Lo;0;L;;;;;N;;;;;\n1699;OGHAM LETTER EAMHANCHOLL;Lo;0;L;;;;;N;;;;;\n169A;OGHAM LETTER PEITH;Lo;0;L;;;;;N;;;;;\n169B;OGHAM FEATHER MARK;Ps;0;ON;;;;;Y;;;;;\n169C;OGHAM REVERSED FEATHER MARK;Pe;0;ON;;;;;Y;;;;;\n16A0;RUNIC LETTER FEHU FEOH FE F;Lo;0;L;;;;;N;;;;;\n16A1;RUNIC LETTER V;Lo;0;L;;;;;N;;;;;\n16A2;RUNIC LETTER URUZ UR U;Lo;0;L;;;;;N;;;;;\n16A3;RUNIC LETTER YR;Lo;0;L;;;;;N;;;;;\n16A4;RUNIC LETTER Y;Lo;0;L;;;;;N;;;;;\n16A5;RUNIC LETTER W;Lo;0;L;;;;;N;;;;;\n16A6;RUNIC LETTER THURISAZ THURS THORN;Lo;0;L;;;;;N;;;;;\n16A7;RUNIC LETTER ETH;Lo;0;L;;;;;N;;;;;\n16A8;RUNIC LETTER ANSUZ A;Lo;0;L;;;;;N;;;;;\n16A9;RUNIC LETTER OS O;Lo;0;L;;;;;N;;;;;\n16AA;RUNIC LETTER AC A;Lo;0;L;;;;;N;;;;;\n16AB;RUNIC LETTER AESC;Lo;0;L;;;;;N;;;;;\n16AC;RUNIC LETTER LONG-BRANCH-OSS O;Lo;0;L;;;;;N;;;;;\n16AD;RUNIC LETTER SHORT-TWIG-OSS O;Lo;0;L;;;;;N;;;;;\n16AE;RUNIC LETTER O;Lo;0;L;;;;;N;;;;;\n16AF;RUNIC LETTER OE;Lo;0;L;;;;;N;;;;;\n16B0;RUNIC LETTER ON;Lo;0;L;;;;;N;;;;;\n16B1;RUNIC LETTER RAIDO RAD REID R;Lo;0;L;;;;;N;;;;;\n16B2;RUNIC LETTER KAUNA;Lo;0;L;;;;;N;;;;;\n16B3;RUNIC LETTER CEN;Lo;0;L;;;;;N;;;;;\n16B4;RUNIC LETTER KAUN K;Lo;0;L;;;;;N;;;;;\n16B5;RUNIC LETTER G;Lo;0;L;;;;;N;;;;;\n16B6;RUNIC LETTER ENG;Lo;0;L;;;;;N;;;;;\n16B7;RUNIC LETTER GEBO GYFU G;Lo;0;L;;;;;N;;;;;\n16B8;RUNIC LETTER GAR;Lo;0;L;;;;;N;;;;;\n16B9;RUNIC LETTER WUNJO WYNN W;Lo;0;L;;;;;N;;;;;\n16BA;RUNIC LETTER HAGLAZ H;Lo;0;L;;;;;N;;;;;\n16BB;RUNIC LETTER HAEGL H;Lo;0;L;;;;;N;;;;;\n16BC;RUNIC LETTER LONG-BRANCH-HAGALL H;Lo;0;L;;;;;N;;;;;\n16BD;RUNIC LETTER SHORT-TWIG-HAGALL H;Lo;0;L;;;;;N;;;;;\n16BE;RUNIC LETTER NAUDIZ NYD NAUD N;Lo;0;L;;;;;N;;;;;\n16BF;RUNIC LETTER SHORT-TWIG-NAUD N;Lo;0;L;;;;;N;;;;;\n16C0;RUNIC LETTER DOTTED-N;Lo;0;L;;;;;N;;;;;\n16C1;RUNIC LETTER ISAZ IS ISS I;Lo;0;L;;;;;N;;;;;\n16C2;RUNIC LETTER E;Lo;0;L;;;;;N;;;;;\n16C3;RUNIC LETTER JERAN J;Lo;0;L;;;;;N;;;;;\n16C4;RUNIC LETTER GER;Lo;0;L;;;;;N;;;;;\n16C5;RUNIC LETTER LONG-BRANCH-AR AE;Lo;0;L;;;;;N;;;;;\n16C6;RUNIC LETTER SHORT-TWIG-AR A;Lo;0;L;;;;;N;;;;;\n16C7;RUNIC LETTER IWAZ EOH;Lo;0;L;;;;;N;;;;;\n16C8;RUNIC LETTER PERTHO PEORTH P;Lo;0;L;;;;;N;;;;;\n16C9;RUNIC LETTER ALGIZ EOLHX;Lo;0;L;;;;;N;;;;;\n16CA;RUNIC LETTER SOWILO S;Lo;0;L;;;;;N;;;;;\n16CB;RUNIC LETTER SIGEL LONG-BRANCH-SOL S;Lo;0;L;;;;;N;;;;;\n16CC;RUNIC LETTER SHORT-TWIG-SOL S;Lo;0;L;;;;;N;;;;;\n16CD;RUNIC LETTER C;Lo;0;L;;;;;N;;;;;\n16CE;RUNIC LETTER Z;Lo;0;L;;;;;N;;;;;\n16CF;RUNIC LETTER TIWAZ TIR TYR T;Lo;0;L;;;;;N;;;;;\n16D0;RUNIC LETTER SHORT-TWIG-TYR T;Lo;0;L;;;;;N;;;;;\n16D1;RUNIC LETTER D;Lo;0;L;;;;;N;;;;;\n16D2;RUNIC LETTER BERKANAN BEORC BJARKAN B;Lo;0;L;;;;;N;;;;;\n16D3;RUNIC LETTER SHORT-TWIG-BJARKAN B;Lo;0;L;;;;;N;;;;;\n16D4;RUNIC LETTER DOTTED-P;Lo;0;L;;;;;N;;;;;\n16D5;RUNIC LETTER OPEN-P;Lo;0;L;;;;;N;;;;;\n16D6;RUNIC LETTER EHWAZ EH E;Lo;0;L;;;;;N;;;;;\n16D7;RUNIC LETTER MANNAZ MAN M;Lo;0;L;;;;;N;;;;;\n16D8;RUNIC LETTER LONG-BRANCH-MADR M;Lo;0;L;;;;;N;;;;;\n16D9;RUNIC LETTER SHORT-TWIG-MADR M;Lo;0;L;;;;;N;;;;;\n16DA;RUNIC LETTER LAUKAZ LAGU LOGR L;Lo;0;L;;;;;N;;;;;\n16DB;RUNIC LETTER DOTTED-L;Lo;0;L;;;;;N;;;;;\n16DC;RUNIC LETTER INGWAZ;Lo;0;L;;;;;N;;;;;\n16DD;RUNIC LETTER ING;Lo;0;L;;;;;N;;;;;\n16DE;RUNIC LETTER DAGAZ DAEG D;Lo;0;L;;;;;N;;;;;\n16DF;RUNIC LETTER OTHALAN ETHEL O;Lo;0;L;;;;;N;;;;;\n16E0;RUNIC LETTER EAR;Lo;0;L;;;;;N;;;;;\n16E1;RUNIC LETTER IOR;Lo;0;L;;;;;N;;;;;\n16E2;RUNIC LETTER CWEORTH;Lo;0;L;;;;;N;;;;;\n16E3;RUNIC LETTER CALC;Lo;0;L;;;;;N;;;;;\n16E4;RUNIC LETTER CEALC;Lo;0;L;;;;;N;;;;;\n16E5;RUNIC LETTER STAN;Lo;0;L;;;;;N;;;;;\n16E6;RUNIC LETTER LONG-BRANCH-YR;Lo;0;L;;;;;N;;;;;\n16E7;RUNIC LETTER SHORT-TWIG-YR;Lo;0;L;;;;;N;;;;;\n16E8;RUNIC LETTER ICELANDIC-YR;Lo;0;L;;;;;N;;;;;\n16E9;RUNIC LETTER Q;Lo;0;L;;;;;N;;;;;\n16EA;RUNIC LETTER X;Lo;0;L;;;;;N;;;;;\n16EB;RUNIC SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;;\n16EC;RUNIC MULTIPLE PUNCTUATION;Po;0;L;;;;;N;;;;;\n16ED;RUNIC CROSS PUNCTUATION;Po;0;L;;;;;N;;;;;\n16EE;RUNIC ARLAUG SYMBOL;Nl;0;L;;;;17;N;;;;;\n16EF;RUNIC TVIMADUR SYMBOL;Nl;0;L;;;;18;N;;;;;\n16F0;RUNIC BELGTHOR SYMBOL;Nl;0;L;;;;19;N;;;;;\n16F1;RUNIC LETTER K;Lo;0;L;;;;;N;;;;;\n16F2;RUNIC LETTER SH;Lo;0;L;;;;;N;;;;;\n16F3;RUNIC LETTER OO;Lo;0;L;;;;;N;;;;;\n16F4;RUNIC LETTER FRANKS CASKET OS;Lo;0;L;;;;;N;;;;;\n16F5;RUNIC LETTER FRANKS CASKET IS;Lo;0;L;;;;;N;;;;;\n16F6;RUNIC LETTER FRANKS CASKET EH;Lo;0;L;;;;;N;;;;;\n16F7;RUNIC LETTER FRANKS CASKET AC;Lo;0;L;;;;;N;;;;;\n16F8;RUNIC LETTER FRANKS CASKET AESC;Lo;0;L;;;;;N;;;;;\n1700;TAGALOG LETTER A;Lo;0;L;;;;;N;;;;;\n1701;TAGALOG LETTER I;Lo;0;L;;;;;N;;;;;\n1702;TAGALOG LETTER U;Lo;0;L;;;;;N;;;;;\n1703;TAGALOG LETTER KA;Lo;0;L;;;;;N;;;;;\n1704;TAGALOG LETTER GA;Lo;0;L;;;;;N;;;;;\n1705;TAGALOG LETTER NGA;Lo;0;L;;;;;N;;;;;\n1706;TAGALOG LETTER TA;Lo;0;L;;;;;N;;;;;\n1707;TAGALOG LETTER DA;Lo;0;L;;;;;N;;;;;\n1708;TAGALOG LETTER NA;Lo;0;L;;;;;N;;;;;\n1709;TAGALOG LETTER PA;Lo;0;L;;;;;N;;;;;\n170A;TAGALOG LETTER BA;Lo;0;L;;;;;N;;;;;\n170B;TAGALOG LETTER MA;Lo;0;L;;;;;N;;;;;\n170C;TAGALOG LETTER YA;Lo;0;L;;;;;N;;;;;\n170E;TAGALOG LETTER LA;Lo;0;L;;;;;N;;;;;\n170F;TAGALOG LETTER WA;Lo;0;L;;;;;N;;;;;\n1710;TAGALOG LETTER SA;Lo;0;L;;;;;N;;;;;\n1711;TAGALOG LETTER HA;Lo;0;L;;;;;N;;;;;\n1712;TAGALOG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n1713;TAGALOG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n1714;TAGALOG SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n1720;HANUNOO LETTER A;Lo;0;L;;;;;N;;;;;\n1721;HANUNOO LETTER I;Lo;0;L;;;;;N;;;;;\n1722;HANUNOO LETTER U;Lo;0;L;;;;;N;;;;;\n1723;HANUNOO LETTER KA;Lo;0;L;;;;;N;;;;;\n1724;HANUNOO LETTER GA;Lo;0;L;;;;;N;;;;;\n1725;HANUNOO LETTER NGA;Lo;0;L;;;;;N;;;;;\n1726;HANUNOO LETTER TA;Lo;0;L;;;;;N;;;;;\n1727;HANUNOO LETTER DA;Lo;0;L;;;;;N;;;;;\n1728;HANUNOO LETTER NA;Lo;0;L;;;;;N;;;;;\n1729;HANUNOO LETTER PA;Lo;0;L;;;;;N;;;;;\n172A;HANUNOO LETTER BA;Lo;0;L;;;;;N;;;;;\n172B;HANUNOO LETTER MA;Lo;0;L;;;;;N;;;;;\n172C;HANUNOO LETTER YA;Lo;0;L;;;;;N;;;;;\n172D;HANUNOO LETTER RA;Lo;0;L;;;;;N;;;;;\n172E;HANUNOO LETTER LA;Lo;0;L;;;;;N;;;;;\n172F;HANUNOO LETTER WA;Lo;0;L;;;;;N;;;;;\n1730;HANUNOO LETTER SA;Lo;0;L;;;;;N;;;;;\n1731;HANUNOO LETTER HA;Lo;0;L;;;;;N;;;;;\n1732;HANUNOO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n1733;HANUNOO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n1734;HANUNOO SIGN PAMUDPOD;Mn;9;NSM;;;;;N;;;;;\n1735;PHILIPPINE SINGLE PUNCTUATION;Po;0;L;;;;;N;;;;;\n1736;PHILIPPINE DOUBLE PUNCTUATION;Po;0;L;;;;;N;;;;;\n1740;BUHID LETTER A;Lo;0;L;;;;;N;;;;;\n1741;BUHID LETTER I;Lo;0;L;;;;;N;;;;;\n1742;BUHID LETTER U;Lo;0;L;;;;;N;;;;;\n1743;BUHID LETTER KA;Lo;0;L;;;;;N;;;;;\n1744;BUHID LETTER GA;Lo;0;L;;;;;N;;;;;\n1745;BUHID LETTER NGA;Lo;0;L;;;;;N;;;;;\n1746;BUHID LETTER TA;Lo;0;L;;;;;N;;;;;\n1747;BUHID LETTER DA;Lo;0;L;;;;;N;;;;;\n1748;BUHID LETTER NA;Lo;0;L;;;;;N;;;;;\n1749;BUHID LETTER PA;Lo;0;L;;;;;N;;;;;\n174A;BUHID LETTER BA;Lo;0;L;;;;;N;;;;;\n174B;BUHID LETTER MA;Lo;0;L;;;;;N;;;;;\n174C;BUHID LETTER YA;Lo;0;L;;;;;N;;;;;\n174D;BUHID LETTER RA;Lo;0;L;;;;;N;;;;;\n174E;BUHID LETTER LA;Lo;0;L;;;;;N;;;;;\n174F;BUHID LETTER WA;Lo;0;L;;;;;N;;;;;\n1750;BUHID LETTER SA;Lo;0;L;;;;;N;;;;;\n1751;BUHID LETTER HA;Lo;0;L;;;;;N;;;;;\n1752;BUHID VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n1753;BUHID VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n1760;TAGBANWA LETTER A;Lo;0;L;;;;;N;;;;;\n1761;TAGBANWA LETTER I;Lo;0;L;;;;;N;;;;;\n1762;TAGBANWA LETTER U;Lo;0;L;;;;;N;;;;;\n1763;TAGBANWA LETTER KA;Lo;0;L;;;;;N;;;;;\n1764;TAGBANWA LETTER GA;Lo;0;L;;;;;N;;;;;\n1765;TAGBANWA LETTER NGA;Lo;0;L;;;;;N;;;;;\n1766;TAGBANWA LETTER TA;Lo;0;L;;;;;N;;;;;\n1767;TAGBANWA LETTER DA;Lo;0;L;;;;;N;;;;;\n1768;TAGBANWA LETTER NA;Lo;0;L;;;;;N;;;;;\n1769;TAGBANWA LETTER PA;Lo;0;L;;;;;N;;;;;\n176A;TAGBANWA LETTER BA;Lo;0;L;;;;;N;;;;;\n176B;TAGBANWA LETTER MA;Lo;0;L;;;;;N;;;;;\n176C;TAGBANWA LETTER YA;Lo;0;L;;;;;N;;;;;\n176E;TAGBANWA LETTER LA;Lo;0;L;;;;;N;;;;;\n176F;TAGBANWA LETTER WA;Lo;0;L;;;;;N;;;;;\n1770;TAGBANWA LETTER SA;Lo;0;L;;;;;N;;;;;\n1772;TAGBANWA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n1773;TAGBANWA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n1780;KHMER LETTER KA;Lo;0;L;;;;;N;;;;;\n1781;KHMER LETTER KHA;Lo;0;L;;;;;N;;;;;\n1782;KHMER LETTER KO;Lo;0;L;;;;;N;;;;;\n1783;KHMER LETTER KHO;Lo;0;L;;;;;N;;;;;\n1784;KHMER LETTER NGO;Lo;0;L;;;;;N;;;;;\n1785;KHMER LETTER CA;Lo;0;L;;;;;N;;;;;\n1786;KHMER LETTER CHA;Lo;0;L;;;;;N;;;;;\n1787;KHMER LETTER CO;Lo;0;L;;;;;N;;;;;\n1788;KHMER LETTER CHO;Lo;0;L;;;;;N;;;;;\n1789;KHMER LETTER NYO;Lo;0;L;;;;;N;;;;;\n178A;KHMER LETTER DA;Lo;0;L;;;;;N;;;;;\n178B;KHMER LETTER TTHA;Lo;0;L;;;;;N;;;;;\n178C;KHMER LETTER DO;Lo;0;L;;;;;N;;;;;\n178D;KHMER LETTER TTHO;Lo;0;L;;;;;N;;;;;\n178E;KHMER LETTER NNO;Lo;0;L;;;;;N;;;;;\n178F;KHMER LETTER TA;Lo;0;L;;;;;N;;;;;\n1790;KHMER LETTER THA;Lo;0;L;;;;;N;;;;;\n1791;KHMER LETTER TO;Lo;0;L;;;;;N;;;;;\n1792;KHMER LETTER THO;Lo;0;L;;;;;N;;;;;\n1793;KHMER LETTER NO;Lo;0;L;;;;;N;;;;;\n1794;KHMER LETTER BA;Lo;0;L;;;;;N;;;;;\n1795;KHMER LETTER PHA;Lo;0;L;;;;;N;;;;;\n1796;KHMER LETTER PO;Lo;0;L;;;;;N;;;;;\n1797;KHMER LETTER PHO;Lo;0;L;;;;;N;;;;;\n1798;KHMER LETTER MO;Lo;0;L;;;;;N;;;;;\n1799;KHMER LETTER YO;Lo;0;L;;;;;N;;;;;\n179A;KHMER LETTER RO;Lo;0;L;;;;;N;;;;;\n179B;KHMER LETTER LO;Lo;0;L;;;;;N;;;;;\n179C;KHMER LETTER VO;Lo;0;L;;;;;N;;;;;\n179D;KHMER LETTER SHA;Lo;0;L;;;;;N;;;;;\n179E;KHMER LETTER SSO;Lo;0;L;;;;;N;;;;;\n179F;KHMER LETTER SA;Lo;0;L;;;;;N;;;;;\n17A0;KHMER LETTER HA;Lo;0;L;;;;;N;;;;;\n17A1;KHMER LETTER LA;Lo;0;L;;;;;N;;;;;\n17A2;KHMER LETTER QA;Lo;0;L;;;;;N;;;;;\n17A3;KHMER INDEPENDENT VOWEL QAQ;Lo;0;L;;;;;N;;;;;\n17A4;KHMER INDEPENDENT VOWEL QAA;Lo;0;L;;;;;N;;;;;\n17A5;KHMER INDEPENDENT VOWEL QI;Lo;0;L;;;;;N;;;;;\n17A6;KHMER INDEPENDENT VOWEL QII;Lo;0;L;;;;;N;;;;;\n17A7;KHMER INDEPENDENT VOWEL QU;Lo;0;L;;;;;N;;;;;\n17A8;KHMER INDEPENDENT VOWEL QUK;Lo;0;L;;;;;N;;;;;\n17A9;KHMER INDEPENDENT VOWEL QUU;Lo;0;L;;;;;N;;;;;\n17AA;KHMER INDEPENDENT VOWEL QUUV;Lo;0;L;;;;;N;;;;;\n17AB;KHMER INDEPENDENT VOWEL RY;Lo;0;L;;;;;N;;;;;\n17AC;KHMER INDEPENDENT VOWEL RYY;Lo;0;L;;;;;N;;;;;\n17AD;KHMER INDEPENDENT VOWEL LY;Lo;0;L;;;;;N;;;;;\n17AE;KHMER INDEPENDENT VOWEL LYY;Lo;0;L;;;;;N;;;;;\n17AF;KHMER INDEPENDENT VOWEL QE;Lo;0;L;;;;;N;;;;;\n17B0;KHMER INDEPENDENT VOWEL QAI;Lo;0;L;;;;;N;;;;;\n17B1;KHMER INDEPENDENT VOWEL QOO TYPE ONE;Lo;0;L;;;;;N;;;;;\n17B2;KHMER INDEPENDENT VOWEL QOO TYPE TWO;Lo;0;L;;;;;N;;;;;\n17B3;KHMER INDEPENDENT VOWEL QAU;Lo;0;L;;;;;N;;;;;\n17B4;KHMER VOWEL INHERENT AQ;Mn;0;NSM;;;;;N;;;;;\n17B5;KHMER VOWEL INHERENT AA;Mn;0;NSM;;;;;N;;;;;\n17B6;KHMER VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n17B7;KHMER VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n17B8;KHMER VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;\n17B9;KHMER VOWEL SIGN Y;Mn;0;NSM;;;;;N;;;;;\n17BA;KHMER VOWEL SIGN YY;Mn;0;NSM;;;;;N;;;;;\n17BB;KHMER VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n17BC;KHMER VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n17BD;KHMER VOWEL SIGN UA;Mn;0;NSM;;;;;N;;;;;\n17BE;KHMER VOWEL SIGN OE;Mc;0;L;;;;;N;;;;;\n17BF;KHMER VOWEL SIGN YA;Mc;0;L;;;;;N;;;;;\n17C0;KHMER VOWEL SIGN IE;Mc;0;L;;;;;N;;;;;\n17C1;KHMER VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\n17C2;KHMER VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;\n17C3;KHMER VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;\n17C4;KHMER VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;\n17C5;KHMER VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;\n17C6;KHMER SIGN NIKAHIT;Mn;0;NSM;;;;;N;;;;;\n17C7;KHMER SIGN REAHMUK;Mc;0;L;;;;;N;;;;;\n17C8;KHMER SIGN YUUKALEAPINTU;Mc;0;L;;;;;N;;;;;\n17C9;KHMER SIGN MUUSIKATOAN;Mn;0;NSM;;;;;N;;;;;\n17CA;KHMER SIGN TRIISAP;Mn;0;NSM;;;;;N;;;;;\n17CB;KHMER SIGN BANTOC;Mn;0;NSM;;;;;N;;;;;\n17CC;KHMER SIGN ROBAT;Mn;0;NSM;;;;;N;;;;;\n17CD;KHMER SIGN TOANDAKHIAT;Mn;0;NSM;;;;;N;;;;;\n17CE;KHMER SIGN KAKABAT;Mn;0;NSM;;;;;N;;;;;\n17CF;KHMER SIGN AHSDA;Mn;0;NSM;;;;;N;;;;;\n17D0;KHMER SIGN SAMYOK SANNYA;Mn;0;NSM;;;;;N;;;;;\n17D1;KHMER SIGN VIRIAM;Mn;0;NSM;;;;;N;;;;;\n17D2;KHMER SIGN COENG;Mn;9;NSM;;;;;N;;;;;\n17D3;KHMER SIGN BATHAMASAT;Mn;0;NSM;;;;;N;;;;;\n17D4;KHMER SIGN KHAN;Po;0;L;;;;;N;;;;;\n17D5;KHMER SIGN BARIYOOSAN;Po;0;L;;;;;N;;;;;\n17D6;KHMER SIGN CAMNUC PII KUUH;Po;0;L;;;;;N;;;;;\n17D7;KHMER SIGN LEK TOO;Lm;0;L;;;;;N;;;;;\n17D8;KHMER SIGN BEYYAL;Po;0;L;;;;;N;;;;;\n17D9;KHMER SIGN PHNAEK MUAN;Po;0;L;;;;;N;;;;;\n17DA;KHMER SIGN KOOMUUT;Po;0;L;;;;;N;;;;;\n17DB;KHMER CURRENCY SYMBOL RIEL;Sc;0;ET;;;;;N;;;;;\n17DC;KHMER SIGN AVAKRAHASANYA;Lo;0;L;;;;;N;;;;;\n17DD;KHMER SIGN ATTHACAN;Mn;230;NSM;;;;;N;;;;;\n17E0;KHMER DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n17E1;KHMER DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n17E2;KHMER DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n17E3;KHMER DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n17E4;KHMER DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n17E5;KHMER DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n17E6;KHMER DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n17E7;KHMER DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n17E8;KHMER DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n17E9;KHMER DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n17F0;KHMER SYMBOL LEK ATTAK SON;No;0;ON;;;;0;N;;;;;\n17F1;KHMER SYMBOL LEK ATTAK MUOY;No;0;ON;;;;1;N;;;;;\n17F2;KHMER SYMBOL LEK ATTAK PII;No;0;ON;;;;2;N;;;;;\n17F3;KHMER SYMBOL LEK ATTAK BEI;No;0;ON;;;;3;N;;;;;\n17F4;KHMER SYMBOL LEK ATTAK BUON;No;0;ON;;;;4;N;;;;;\n17F5;KHMER SYMBOL LEK ATTAK PRAM;No;0;ON;;;;5;N;;;;;\n17F6;KHMER SYMBOL LEK ATTAK PRAM-MUOY;No;0;ON;;;;6;N;;;;;\n17F7;KHMER SYMBOL LEK ATTAK PRAM-PII;No;0;ON;;;;7;N;;;;;\n17F8;KHMER SYMBOL LEK ATTAK PRAM-BEI;No;0;ON;;;;8;N;;;;;\n17F9;KHMER SYMBOL LEK ATTAK PRAM-BUON;No;0;ON;;;;9;N;;;;;\n1800;MONGOLIAN BIRGA;Po;0;ON;;;;;N;;;;;\n1801;MONGOLIAN ELLIPSIS;Po;0;ON;;;;;N;;;;;\n1802;MONGOLIAN COMMA;Po;0;ON;;;;;N;;;;;\n1803;MONGOLIAN FULL STOP;Po;0;ON;;;;;N;;;;;\n1804;MONGOLIAN COLON;Po;0;ON;;;;;N;;;;;\n1805;MONGOLIAN FOUR DOTS;Po;0;ON;;;;;N;;;;;\n1806;MONGOLIAN TODO SOFT HYPHEN;Pd;0;ON;;;;;N;;;;;\n1807;MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER;Po;0;ON;;;;;N;;;;;\n1808;MONGOLIAN MANCHU COMMA;Po;0;ON;;;;;N;;;;;\n1809;MONGOLIAN MANCHU FULL STOP;Po;0;ON;;;;;N;;;;;\n180A;MONGOLIAN NIRUGU;Po;0;ON;;;;;N;;;;;\n180B;MONGOLIAN FREE VARIATION SELECTOR ONE;Mn;0;NSM;;;;;N;;;;;\n180C;MONGOLIAN FREE VARIATION SELECTOR TWO;Mn;0;NSM;;;;;N;;;;;\n180D;MONGOLIAN FREE VARIATION SELECTOR THREE;Mn;0;NSM;;;;;N;;;;;\n180E;MONGOLIAN VOWEL SEPARATOR;Cf;0;BN;;;;;N;;;;;\n1810;MONGOLIAN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n1811;MONGOLIAN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n1812;MONGOLIAN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n1813;MONGOLIAN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n1814;MONGOLIAN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n1815;MONGOLIAN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n1816;MONGOLIAN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n1817;MONGOLIAN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n1818;MONGOLIAN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n1819;MONGOLIAN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n1820;MONGOLIAN LETTER A;Lo;0;L;;;;;N;;;;;\n1821;MONGOLIAN LETTER E;Lo;0;L;;;;;N;;;;;\n1822;MONGOLIAN LETTER I;Lo;0;L;;;;;N;;;;;\n1823;MONGOLIAN LETTER O;Lo;0;L;;;;;N;;;;;\n1824;MONGOLIAN LETTER U;Lo;0;L;;;;;N;;;;;\n1825;MONGOLIAN LETTER OE;Lo;0;L;;;;;N;;;;;\n1826;MONGOLIAN LETTER UE;Lo;0;L;;;;;N;;;;;\n1827;MONGOLIAN LETTER EE;Lo;0;L;;;;;N;;;;;\n1828;MONGOLIAN LETTER NA;Lo;0;L;;;;;N;;;;;\n1829;MONGOLIAN LETTER ANG;Lo;0;L;;;;;N;;;;;\n182A;MONGOLIAN LETTER BA;Lo;0;L;;;;;N;;;;;\n182B;MONGOLIAN LETTER PA;Lo;0;L;;;;;N;;;;;\n182C;MONGOLIAN LETTER QA;Lo;0;L;;;;;N;;;;;\n182D;MONGOLIAN LETTER GA;Lo;0;L;;;;;N;;;;;\n182E;MONGOLIAN LETTER MA;Lo;0;L;;;;;N;;;;;\n182F;MONGOLIAN LETTER LA;Lo;0;L;;;;;N;;;;;\n1830;MONGOLIAN LETTER SA;Lo;0;L;;;;;N;;;;;\n1831;MONGOLIAN LETTER SHA;Lo;0;L;;;;;N;;;;;\n1832;MONGOLIAN LETTER TA;Lo;0;L;;;;;N;;;;;\n1833;MONGOLIAN LETTER DA;Lo;0;L;;;;;N;;;;;\n1834;MONGOLIAN LETTER CHA;Lo;0;L;;;;;N;;;;;\n1835;MONGOLIAN LETTER JA;Lo;0;L;;;;;N;;;;;\n1836;MONGOLIAN LETTER YA;Lo;0;L;;;;;N;;;;;\n1837;MONGOLIAN LETTER RA;Lo;0;L;;;;;N;;;;;\n1838;MONGOLIAN LETTER WA;Lo;0;L;;;;;N;;;;;\n1839;MONGOLIAN LETTER FA;Lo;0;L;;;;;N;;;;;\n183A;MONGOLIAN LETTER KA;Lo;0;L;;;;;N;;;;;\n183B;MONGOLIAN LETTER KHA;Lo;0;L;;;;;N;;;;;\n183C;MONGOLIAN LETTER TSA;Lo;0;L;;;;;N;;;;;\n183D;MONGOLIAN LETTER ZA;Lo;0;L;;;;;N;;;;;\n183E;MONGOLIAN LETTER HAA;Lo;0;L;;;;;N;;;;;\n183F;MONGOLIAN LETTER ZRA;Lo;0;L;;;;;N;;;;;\n1840;MONGOLIAN LETTER LHA;Lo;0;L;;;;;N;;;;;\n1841;MONGOLIAN LETTER ZHI;Lo;0;L;;;;;N;;;;;\n1842;MONGOLIAN LETTER CHI;Lo;0;L;;;;;N;;;;;\n1843;MONGOLIAN LETTER TODO LONG VOWEL SIGN;Lm;0;L;;;;;N;;;;;\n1844;MONGOLIAN LETTER TODO E;Lo;0;L;;;;;N;;;;;\n1845;MONGOLIAN LETTER TODO I;Lo;0;L;;;;;N;;;;;\n1846;MONGOLIAN LETTER TODO O;Lo;0;L;;;;;N;;;;;\n1847;MONGOLIAN LETTER TODO U;Lo;0;L;;;;;N;;;;;\n1848;MONGOLIAN LETTER TODO OE;Lo;0;L;;;;;N;;;;;\n1849;MONGOLIAN LETTER TODO UE;Lo;0;L;;;;;N;;;;;\n184A;MONGOLIAN LETTER TODO ANG;Lo;0;L;;;;;N;;;;;\n184B;MONGOLIAN LETTER TODO BA;Lo;0;L;;;;;N;;;;;\n184C;MONGOLIAN LETTER TODO PA;Lo;0;L;;;;;N;;;;;\n184D;MONGOLIAN LETTER TODO QA;Lo;0;L;;;;;N;;;;;\n184E;MONGOLIAN LETTER TODO GA;Lo;0;L;;;;;N;;;;;\n184F;MONGOLIAN LETTER TODO MA;Lo;0;L;;;;;N;;;;;\n1850;MONGOLIAN LETTER TODO TA;Lo;0;L;;;;;N;;;;;\n1851;MONGOLIAN LETTER TODO DA;Lo;0;L;;;;;N;;;;;\n1852;MONGOLIAN LETTER TODO CHA;Lo;0;L;;;;;N;;;;;\n1853;MONGOLIAN LETTER TODO JA;Lo;0;L;;;;;N;;;;;\n1854;MONGOLIAN LETTER TODO TSA;Lo;0;L;;;;;N;;;;;\n1855;MONGOLIAN LETTER TODO YA;Lo;0;L;;;;;N;;;;;\n1856;MONGOLIAN LETTER TODO WA;Lo;0;L;;;;;N;;;;;\n1857;MONGOLIAN LETTER TODO KA;Lo;0;L;;;;;N;;;;;\n1858;MONGOLIAN LETTER TODO GAA;Lo;0;L;;;;;N;;;;;\n1859;MONGOLIAN LETTER TODO HAA;Lo;0;L;;;;;N;;;;;\n185A;MONGOLIAN LETTER TODO JIA;Lo;0;L;;;;;N;;;;;\n185B;MONGOLIAN LETTER TODO NIA;Lo;0;L;;;;;N;;;;;\n185C;MONGOLIAN LETTER TODO DZA;Lo;0;L;;;;;N;;;;;\n185D;MONGOLIAN LETTER SIBE E;Lo;0;L;;;;;N;;;;;\n185E;MONGOLIAN LETTER SIBE I;Lo;0;L;;;;;N;;;;;\n185F;MONGOLIAN LETTER SIBE IY;Lo;0;L;;;;;N;;;;;\n1860;MONGOLIAN LETTER SIBE UE;Lo;0;L;;;;;N;;;;;\n1861;MONGOLIAN LETTER SIBE U;Lo;0;L;;;;;N;;;;;\n1862;MONGOLIAN LETTER SIBE ANG;Lo;0;L;;;;;N;;;;;\n1863;MONGOLIAN LETTER SIBE KA;Lo;0;L;;;;;N;;;;;\n1864;MONGOLIAN LETTER SIBE GA;Lo;0;L;;;;;N;;;;;\n1865;MONGOLIAN LETTER SIBE HA;Lo;0;L;;;;;N;;;;;\n1866;MONGOLIAN LETTER SIBE PA;Lo;0;L;;;;;N;;;;;\n1867;MONGOLIAN LETTER SIBE SHA;Lo;0;L;;;;;N;;;;;\n1868;MONGOLIAN LETTER SIBE TA;Lo;0;L;;;;;N;;;;;\n1869;MONGOLIAN LETTER SIBE DA;Lo;0;L;;;;;N;;;;;\n186A;MONGOLIAN LETTER SIBE JA;Lo;0;L;;;;;N;;;;;\n186B;MONGOLIAN LETTER SIBE FA;Lo;0;L;;;;;N;;;;;\n186C;MONGOLIAN LETTER SIBE GAA;Lo;0;L;;;;;N;;;;;\n186D;MONGOLIAN LETTER SIBE HAA;Lo;0;L;;;;;N;;;;;\n186E;MONGOLIAN LETTER SIBE TSA;Lo;0;L;;;;;N;;;;;\n186F;MONGOLIAN LETTER SIBE ZA;Lo;0;L;;;;;N;;;;;\n1870;MONGOLIAN LETTER SIBE RAA;Lo;0;L;;;;;N;;;;;\n1871;MONGOLIAN LETTER SIBE CHA;Lo;0;L;;;;;N;;;;;\n1872;MONGOLIAN LETTER SIBE ZHA;Lo;0;L;;;;;N;;;;;\n1873;MONGOLIAN LETTER MANCHU I;Lo;0;L;;;;;N;;;;;\n1874;MONGOLIAN LETTER MANCHU KA;Lo;0;L;;;;;N;;;;;\n1875;MONGOLIAN LETTER MANCHU RA;Lo;0;L;;;;;N;;;;;\n1876;MONGOLIAN LETTER MANCHU FA;Lo;0;L;;;;;N;;;;;\n1877;MONGOLIAN LETTER MANCHU ZHA;Lo;0;L;;;;;N;;;;;\n1878;MONGOLIAN LETTER CHA WITH TWO DOTS;Lo;0;L;;;;;N;;;;;\n1880;MONGOLIAN LETTER ALI GALI ANUSVARA ONE;Lo;0;L;;;;;N;;;;;\n1881;MONGOLIAN LETTER ALI GALI VISARGA ONE;Lo;0;L;;;;;N;;;;;\n1882;MONGOLIAN LETTER ALI GALI DAMARU;Lo;0;L;;;;;N;;;;;\n1883;MONGOLIAN LETTER ALI GALI UBADAMA;Lo;0;L;;;;;N;;;;;\n1884;MONGOLIAN LETTER ALI GALI INVERTED UBADAMA;Lo;0;L;;;;;N;;;;;\n1885;MONGOLIAN LETTER ALI GALI BALUDA;Mn;0;NSM;;;;;N;;;;;\n1886;MONGOLIAN LETTER ALI GALI THREE BALUDA;Mn;0;NSM;;;;;N;;;;;\n1887;MONGOLIAN LETTER ALI GALI A;Lo;0;L;;;;;N;;;;;\n1888;MONGOLIAN LETTER ALI GALI I;Lo;0;L;;;;;N;;;;;\n1889;MONGOLIAN LETTER ALI GALI KA;Lo;0;L;;;;;N;;;;;\n188A;MONGOLIAN LETTER ALI GALI NGA;Lo;0;L;;;;;N;;;;;\n188B;MONGOLIAN LETTER ALI GALI CA;Lo;0;L;;;;;N;;;;;\n188C;MONGOLIAN LETTER ALI GALI TTA;Lo;0;L;;;;;N;;;;;\n188D;MONGOLIAN LETTER ALI GALI TTHA;Lo;0;L;;;;;N;;;;;\n188E;MONGOLIAN LETTER ALI GALI DDA;Lo;0;L;;;;;N;;;;;\n188F;MONGOLIAN LETTER ALI GALI NNA;Lo;0;L;;;;;N;;;;;\n1890;MONGOLIAN LETTER ALI GALI TA;Lo;0;L;;;;;N;;;;;\n1891;MONGOLIAN LETTER ALI GALI DA;Lo;0;L;;;;;N;;;;;\n1892;MONGOLIAN LETTER ALI GALI PA;Lo;0;L;;;;;N;;;;;\n1893;MONGOLIAN LETTER ALI GALI PHA;Lo;0;L;;;;;N;;;;;\n1894;MONGOLIAN LETTER ALI GALI SSA;Lo;0;L;;;;;N;;;;;\n1895;MONGOLIAN LETTER ALI GALI ZHA;Lo;0;L;;;;;N;;;;;\n1896;MONGOLIAN LETTER ALI GALI ZA;Lo;0;L;;;;;N;;;;;\n1897;MONGOLIAN LETTER ALI GALI AH;Lo;0;L;;;;;N;;;;;\n1898;MONGOLIAN LETTER TODO ALI GALI TA;Lo;0;L;;;;;N;;;;;\n1899;MONGOLIAN LETTER TODO ALI GALI ZHA;Lo;0;L;;;;;N;;;;;\n189A;MONGOLIAN LETTER MANCHU ALI GALI GHA;Lo;0;L;;;;;N;;;;;\n189B;MONGOLIAN LETTER MANCHU ALI GALI NGA;Lo;0;L;;;;;N;;;;;\n189C;MONGOLIAN LETTER MANCHU ALI GALI CA;Lo;0;L;;;;;N;;;;;\n189D;MONGOLIAN LETTER MANCHU ALI GALI JHA;Lo;0;L;;;;;N;;;;;\n189E;MONGOLIAN LETTER MANCHU ALI GALI TTA;Lo;0;L;;;;;N;;;;;\n189F;MONGOLIAN LETTER MANCHU ALI GALI DDHA;Lo;0;L;;;;;N;;;;;\n18A0;MONGOLIAN LETTER MANCHU ALI GALI TA;Lo;0;L;;;;;N;;;;;\n18A1;MONGOLIAN LETTER MANCHU ALI GALI DHA;Lo;0;L;;;;;N;;;;;\n18A2;MONGOLIAN LETTER MANCHU ALI GALI SSA;Lo;0;L;;;;;N;;;;;\n18A3;MONGOLIAN LETTER MANCHU ALI GALI CYA;Lo;0;L;;;;;N;;;;;\n18A4;MONGOLIAN LETTER MANCHU ALI GALI ZHA;Lo;0;L;;;;;N;;;;;\n18A5;MONGOLIAN LETTER MANCHU ALI GALI ZA;Lo;0;L;;;;;N;;;;;\n18A6;MONGOLIAN LETTER ALI GALI HALF U;Lo;0;L;;;;;N;;;;;\n18A7;MONGOLIAN LETTER ALI GALI HALF YA;Lo;0;L;;;;;N;;;;;\n18A8;MONGOLIAN LETTER MANCHU ALI GALI BHA;Lo;0;L;;;;;N;;;;;\n18A9;MONGOLIAN LETTER ALI GALI DAGALGA;Mn;228;NSM;;;;;N;;;;;\n18AA;MONGOLIAN LETTER MANCHU ALI GALI LHA;Lo;0;L;;;;;N;;;;;\n18B0;CANADIAN SYLLABICS OY;Lo;0;L;;;;;N;;;;;\n18B1;CANADIAN SYLLABICS AY;Lo;0;L;;;;;N;;;;;\n18B2;CANADIAN SYLLABICS AAY;Lo;0;L;;;;;N;;;;;\n18B3;CANADIAN SYLLABICS WAY;Lo;0;L;;;;;N;;;;;\n18B4;CANADIAN SYLLABICS POY;Lo;0;L;;;;;N;;;;;\n18B5;CANADIAN SYLLABICS PAY;Lo;0;L;;;;;N;;;;;\n18B6;CANADIAN SYLLABICS PWOY;Lo;0;L;;;;;N;;;;;\n18B7;CANADIAN SYLLABICS TAY;Lo;0;L;;;;;N;;;;;\n18B8;CANADIAN SYLLABICS KAY;Lo;0;L;;;;;N;;;;;\n18B9;CANADIAN SYLLABICS KWAY;Lo;0;L;;;;;N;;;;;\n18BA;CANADIAN SYLLABICS MAY;Lo;0;L;;;;;N;;;;;\n18BB;CANADIAN SYLLABICS NOY;Lo;0;L;;;;;N;;;;;\n18BC;CANADIAN SYLLABICS NAY;Lo;0;L;;;;;N;;;;;\n18BD;CANADIAN SYLLABICS LAY;Lo;0;L;;;;;N;;;;;\n18BE;CANADIAN SYLLABICS SOY;Lo;0;L;;;;;N;;;;;\n18BF;CANADIAN SYLLABICS SAY;Lo;0;L;;;;;N;;;;;\n18C0;CANADIAN SYLLABICS SHOY;Lo;0;L;;;;;N;;;;;\n18C1;CANADIAN SYLLABICS SHAY;Lo;0;L;;;;;N;;;;;\n18C2;CANADIAN SYLLABICS SHWOY;Lo;0;L;;;;;N;;;;;\n18C3;CANADIAN SYLLABICS YOY;Lo;0;L;;;;;N;;;;;\n18C4;CANADIAN SYLLABICS YAY;Lo;0;L;;;;;N;;;;;\n18C5;CANADIAN SYLLABICS RAY;Lo;0;L;;;;;N;;;;;\n18C6;CANADIAN SYLLABICS NWI;Lo;0;L;;;;;N;;;;;\n18C7;CANADIAN SYLLABICS OJIBWAY NWI;Lo;0;L;;;;;N;;;;;\n18C8;CANADIAN SYLLABICS NWII;Lo;0;L;;;;;N;;;;;\n18C9;CANADIAN SYLLABICS OJIBWAY NWII;Lo;0;L;;;;;N;;;;;\n18CA;CANADIAN SYLLABICS NWO;Lo;0;L;;;;;N;;;;;\n18CB;CANADIAN SYLLABICS OJIBWAY NWO;Lo;0;L;;;;;N;;;;;\n18CC;CANADIAN SYLLABICS NWOO;Lo;0;L;;;;;N;;;;;\n18CD;CANADIAN SYLLABICS OJIBWAY NWOO;Lo;0;L;;;;;N;;;;;\n18CE;CANADIAN SYLLABICS RWEE;Lo;0;L;;;;;N;;;;;\n18CF;CANADIAN SYLLABICS RWI;Lo;0;L;;;;;N;;;;;\n18D0;CANADIAN SYLLABICS RWII;Lo;0;L;;;;;N;;;;;\n18D1;CANADIAN SYLLABICS RWO;Lo;0;L;;;;;N;;;;;\n18D2;CANADIAN SYLLABICS RWOO;Lo;0;L;;;;;N;;;;;\n18D3;CANADIAN SYLLABICS RWA;Lo;0;L;;;;;N;;;;;\n18D4;CANADIAN SYLLABICS OJIBWAY P;Lo;0;L;;;;;N;;;;;\n18D5;CANADIAN SYLLABICS OJIBWAY T;Lo;0;L;;;;;N;;;;;\n18D6;CANADIAN SYLLABICS OJIBWAY K;Lo;0;L;;;;;N;;;;;\n18D7;CANADIAN SYLLABICS OJIBWAY C;Lo;0;L;;;;;N;;;;;\n18D8;CANADIAN SYLLABICS OJIBWAY M;Lo;0;L;;;;;N;;;;;\n18D9;CANADIAN SYLLABICS OJIBWAY N;Lo;0;L;;;;;N;;;;;\n18DA;CANADIAN SYLLABICS OJIBWAY S;Lo;0;L;;;;;N;;;;;\n18DB;CANADIAN SYLLABICS OJIBWAY SH;Lo;0;L;;;;;N;;;;;\n18DC;CANADIAN SYLLABICS EASTERN W;Lo;0;L;;;;;N;;;;;\n18DD;CANADIAN SYLLABICS WESTERN W;Lo;0;L;;;;;N;;;;;\n18DE;CANADIAN SYLLABICS FINAL SMALL RING;Lo;0;L;;;;;N;;;;;\n18DF;CANADIAN SYLLABICS FINAL RAISED DOT;Lo;0;L;;;;;N;;;;;\n18E0;CANADIAN SYLLABICS R-CREE RWE;Lo;0;L;;;;;N;;;;;\n18E1;CANADIAN SYLLABICS WEST-CREE LOO;Lo;0;L;;;;;N;;;;;\n18E2;CANADIAN SYLLABICS WEST-CREE LAA;Lo;0;L;;;;;N;;;;;\n18E3;CANADIAN SYLLABICS THWE;Lo;0;L;;;;;N;;;;;\n18E4;CANADIAN SYLLABICS THWA;Lo;0;L;;;;;N;;;;;\n18E5;CANADIAN SYLLABICS TTHWE;Lo;0;L;;;;;N;;;;;\n18E6;CANADIAN SYLLABICS TTHOO;Lo;0;L;;;;;N;;;;;\n18E7;CANADIAN SYLLABICS TTHAA;Lo;0;L;;;;;N;;;;;\n18E8;CANADIAN SYLLABICS TLHWE;Lo;0;L;;;;;N;;;;;\n18E9;CANADIAN SYLLABICS TLHOO;Lo;0;L;;;;;N;;;;;\n18EA;CANADIAN SYLLABICS SAYISI SHWE;Lo;0;L;;;;;N;;;;;\n18EB;CANADIAN SYLLABICS SAYISI SHOO;Lo;0;L;;;;;N;;;;;\n18EC;CANADIAN SYLLABICS SAYISI HOO;Lo;0;L;;;;;N;;;;;\n18ED;CANADIAN SYLLABICS CARRIER GWU;Lo;0;L;;;;;N;;;;;\n18EE;CANADIAN SYLLABICS CARRIER DENE GEE;Lo;0;L;;;;;N;;;;;\n18EF;CANADIAN SYLLABICS CARRIER GAA;Lo;0;L;;;;;N;;;;;\n18F0;CANADIAN SYLLABICS CARRIER GWA;Lo;0;L;;;;;N;;;;;\n18F1;CANADIAN SYLLABICS SAYISI JUU;Lo;0;L;;;;;N;;;;;\n18F2;CANADIAN SYLLABICS CARRIER JWA;Lo;0;L;;;;;N;;;;;\n18F3;CANADIAN SYLLABICS BEAVER DENE L;Lo;0;L;;;;;N;;;;;\n18F4;CANADIAN SYLLABICS BEAVER DENE R;Lo;0;L;;;;;N;;;;;\n18F5;CANADIAN SYLLABICS CARRIER DENTAL S;Lo;0;L;;;;;N;;;;;\n1900;LIMBU VOWEL-CARRIER LETTER;Lo;0;L;;;;;N;;;;;\n1901;LIMBU LETTER KA;Lo;0;L;;;;;N;;;;;\n1902;LIMBU LETTER KHA;Lo;0;L;;;;;N;;;;;\n1903;LIMBU LETTER GA;Lo;0;L;;;;;N;;;;;\n1904;LIMBU LETTER GHA;Lo;0;L;;;;;N;;;;;\n1905;LIMBU LETTER NGA;Lo;0;L;;;;;N;;;;;\n1906;LIMBU LETTER CA;Lo;0;L;;;;;N;;;;;\n1907;LIMBU LETTER CHA;Lo;0;L;;;;;N;;;;;\n1908;LIMBU LETTER JA;Lo;0;L;;;;;N;;;;;\n1909;LIMBU LETTER JHA;Lo;0;L;;;;;N;;;;;\n190A;LIMBU LETTER YAN;Lo;0;L;;;;;N;;;;;\n190B;LIMBU LETTER TA;Lo;0;L;;;;;N;;;;;\n190C;LIMBU LETTER THA;Lo;0;L;;;;;N;;;;;\n190D;LIMBU LETTER DA;Lo;0;L;;;;;N;;;;;\n190E;LIMBU LETTER DHA;Lo;0;L;;;;;N;;;;;\n190F;LIMBU LETTER NA;Lo;0;L;;;;;N;;;;;\n1910;LIMBU LETTER PA;Lo;0;L;;;;;N;;;;;\n1911;LIMBU LETTER PHA;Lo;0;L;;;;;N;;;;;\n1912;LIMBU LETTER BA;Lo;0;L;;;;;N;;;;;\n1913;LIMBU LETTER BHA;Lo;0;L;;;;;N;;;;;\n1914;LIMBU LETTER MA;Lo;0;L;;;;;N;;;;;\n1915;LIMBU LETTER YA;Lo;0;L;;;;;N;;;;;\n1916;LIMBU LETTER RA;Lo;0;L;;;;;N;;;;;\n1917;LIMBU LETTER LA;Lo;0;L;;;;;N;;;;;\n1918;LIMBU LETTER WA;Lo;0;L;;;;;N;;;;;\n1919;LIMBU LETTER SHA;Lo;0;L;;;;;N;;;;;\n191A;LIMBU LETTER SSA;Lo;0;L;;;;;N;;;;;\n191B;LIMBU LETTER SA;Lo;0;L;;;;;N;;;;;\n191C;LIMBU LETTER HA;Lo;0;L;;;;;N;;;;;\n191D;LIMBU LETTER GYAN;Lo;0;L;;;;;N;;;;;\n191E;LIMBU LETTER TRA;Lo;0;L;;;;;N;;;;;\n1920;LIMBU VOWEL SIGN A;Mn;0;NSM;;;;;N;;;;;\n1921;LIMBU VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n1922;LIMBU VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n1923;LIMBU VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;\n1924;LIMBU VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;\n1925;LIMBU VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;\n1926;LIMBU VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;\n1927;LIMBU VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n1928;LIMBU VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;\n1929;LIMBU SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;;\n192A;LIMBU SUBJOINED LETTER RA;Mc;0;L;;;;;N;;;;;\n192B;LIMBU SUBJOINED LETTER WA;Mc;0;L;;;;;N;;;;;\n1930;LIMBU SMALL LETTER KA;Mc;0;L;;;;;N;;;;;\n1931;LIMBU SMALL LETTER NGA;Mc;0;L;;;;;N;;;;;\n1932;LIMBU SMALL LETTER ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n1933;LIMBU SMALL LETTER TA;Mc;0;L;;;;;N;;;;;\n1934;LIMBU SMALL LETTER NA;Mc;0;L;;;;;N;;;;;\n1935;LIMBU SMALL LETTER PA;Mc;0;L;;;;;N;;;;;\n1936;LIMBU SMALL LETTER MA;Mc;0;L;;;;;N;;;;;\n1937;LIMBU SMALL LETTER RA;Mc;0;L;;;;;N;;;;;\n1938;LIMBU SMALL LETTER LA;Mc;0;L;;;;;N;;;;;\n1939;LIMBU SIGN MUKPHRENG;Mn;222;NSM;;;;;N;;;;;\n193A;LIMBU SIGN KEMPHRENG;Mn;230;NSM;;;;;N;;;;;\n193B;LIMBU SIGN SA-I;Mn;220;NSM;;;;;N;;;;;\n1940;LIMBU SIGN LOO;So;0;ON;;;;;N;;;;;\n1944;LIMBU EXCLAMATION MARK;Po;0;ON;;;;;N;;;;;\n1945;LIMBU QUESTION MARK;Po;0;ON;;;;;N;;;;;\n1946;LIMBU DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n1947;LIMBU DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n1948;LIMBU DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n1949;LIMBU DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n194A;LIMBU DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n194B;LIMBU DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n194C;LIMBU DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n194D;LIMBU DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n194E;LIMBU DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n194F;LIMBU DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n1950;TAI LE LETTER KA;Lo;0;L;;;;;N;;;;;\n1951;TAI LE LETTER XA;Lo;0;L;;;;;N;;;;;\n1952;TAI LE LETTER NGA;Lo;0;L;;;;;N;;;;;\n1953;TAI LE LETTER TSA;Lo;0;L;;;;;N;;;;;\n1954;TAI LE LETTER SA;Lo;0;L;;;;;N;;;;;\n1955;TAI LE LETTER YA;Lo;0;L;;;;;N;;;;;\n1956;TAI LE LETTER TA;Lo;0;L;;;;;N;;;;;\n1957;TAI LE LETTER THA;Lo;0;L;;;;;N;;;;;\n1958;TAI LE LETTER LA;Lo;0;L;;;;;N;;;;;\n1959;TAI LE LETTER PA;Lo;0;L;;;;;N;;;;;\n195A;TAI LE LETTER PHA;Lo;0;L;;;;;N;;;;;\n195B;TAI LE LETTER MA;Lo;0;L;;;;;N;;;;;\n195C;TAI LE LETTER FA;Lo;0;L;;;;;N;;;;;\n195D;TAI LE LETTER VA;Lo;0;L;;;;;N;;;;;\n195E;TAI LE LETTER HA;Lo;0;L;;;;;N;;;;;\n195F;TAI LE LETTER QA;Lo;0;L;;;;;N;;;;;\n1960;TAI LE LETTER KHA;Lo;0;L;;;;;N;;;;;\n1961;TAI LE LETTER TSHA;Lo;0;L;;;;;N;;;;;\n1962;TAI LE LETTER NA;Lo;0;L;;;;;N;;;;;\n1963;TAI LE LETTER A;Lo;0;L;;;;;N;;;;;\n1964;TAI LE LETTER I;Lo;0;L;;;;;N;;;;;\n1965;TAI LE LETTER EE;Lo;0;L;;;;;N;;;;;\n1966;TAI LE LETTER EH;Lo;0;L;;;;;N;;;;;\n1967;TAI LE LETTER U;Lo;0;L;;;;;N;;;;;\n1968;TAI LE LETTER OO;Lo;0;L;;;;;N;;;;;\n1969;TAI LE LETTER O;Lo;0;L;;;;;N;;;;;\n196A;TAI LE LETTER UE;Lo;0;L;;;;;N;;;;;\n196B;TAI LE LETTER E;Lo;0;L;;;;;N;;;;;\n196C;TAI LE LETTER AUE;Lo;0;L;;;;;N;;;;;\n196D;TAI LE LETTER AI;Lo;0;L;;;;;N;;;;;\n1970;TAI LE LETTER TONE-2;Lo;0;L;;;;;N;;;;;\n1971;TAI LE LETTER TONE-3;Lo;0;L;;;;;N;;;;;\n1972;TAI LE LETTER TONE-4;Lo;0;L;;;;;N;;;;;\n1973;TAI LE LETTER TONE-5;Lo;0;L;;;;;N;;;;;\n1974;TAI LE LETTER TONE-6;Lo;0;L;;;;;N;;;;;\n1980;NEW TAI LUE LETTER HIGH QA;Lo;0;L;;;;;N;;;;;\n1981;NEW TAI LUE LETTER LOW QA;Lo;0;L;;;;;N;;;;;\n1982;NEW TAI LUE LETTER HIGH KA;Lo;0;L;;;;;N;;;;;\n1983;NEW TAI LUE LETTER HIGH XA;Lo;0;L;;;;;N;;;;;\n1984;NEW TAI LUE LETTER HIGH NGA;Lo;0;L;;;;;N;;;;;\n1985;NEW TAI LUE LETTER LOW KA;Lo;0;L;;;;;N;;;;;\n1986;NEW TAI LUE LETTER LOW XA;Lo;0;L;;;;;N;;;;;\n1987;NEW TAI LUE LETTER LOW NGA;Lo;0;L;;;;;N;;;;;\n1988;NEW TAI LUE LETTER HIGH TSA;Lo;0;L;;;;;N;;;;;\n1989;NEW TAI LUE LETTER HIGH SA;Lo;0;L;;;;;N;;;;;\n198A;NEW TAI LUE LETTER HIGH YA;Lo;0;L;;;;;N;;;;;\n198B;NEW TAI LUE LETTER LOW TSA;Lo;0;L;;;;;N;;;;;\n198C;NEW TAI LUE LETTER LOW SA;Lo;0;L;;;;;N;;;;;\n198D;NEW TAI LUE LETTER LOW YA;Lo;0;L;;;;;N;;;;;\n198E;NEW TAI LUE LETTER HIGH TA;Lo;0;L;;;;;N;;;;;\n198F;NEW TAI LUE LETTER HIGH THA;Lo;0;L;;;;;N;;;;;\n1990;NEW TAI LUE LETTER HIGH NA;Lo;0;L;;;;;N;;;;;\n1991;NEW TAI LUE LETTER LOW TA;Lo;0;L;;;;;N;;;;;\n1992;NEW TAI LUE LETTER LOW THA;Lo;0;L;;;;;N;;;;;\n1993;NEW TAI LUE LETTER LOW NA;Lo;0;L;;;;;N;;;;;\n1994;NEW TAI LUE LETTER HIGH PA;Lo;0;L;;;;;N;;;;;\n1995;NEW TAI LUE LETTER HIGH PHA;Lo;0;L;;;;;N;;;;;\n1996;NEW TAI LUE LETTER HIGH MA;Lo;0;L;;;;;N;;;;;\n1997;NEW TAI LUE LETTER LOW PA;Lo;0;L;;;;;N;;;;;\n1998;NEW TAI LUE LETTER LOW PHA;Lo;0;L;;;;;N;;;;;\n1999;NEW TAI LUE LETTER LOW MA;Lo;0;L;;;;;N;;;;;\n199A;NEW TAI LUE LETTER HIGH FA;Lo;0;L;;;;;N;;;;;\n199B;NEW TAI LUE LETTER HIGH VA;Lo;0;L;;;;;N;;;;;\n199C;NEW TAI LUE LETTER HIGH LA;Lo;0;L;;;;;N;;;;;\n199D;NEW TAI LUE LETTER LOW FA;Lo;0;L;;;;;N;;;;;\n199E;NEW TAI LUE LETTER LOW VA;Lo;0;L;;;;;N;;;;;\n199F;NEW TAI LUE LETTER LOW LA;Lo;0;L;;;;;N;;;;;\n19A0;NEW TAI LUE LETTER HIGH HA;Lo;0;L;;;;;N;;;;;\n19A1;NEW TAI LUE LETTER HIGH DA;Lo;0;L;;;;;N;;;;;\n19A2;NEW TAI LUE LETTER HIGH BA;Lo;0;L;;;;;N;;;;;\n19A3;NEW TAI LUE LETTER LOW HA;Lo;0;L;;;;;N;;;;;\n19A4;NEW TAI LUE LETTER LOW DA;Lo;0;L;;;;;N;;;;;\n19A5;NEW TAI LUE LETTER LOW BA;Lo;0;L;;;;;N;;;;;\n19A6;NEW TAI LUE LETTER HIGH KVA;Lo;0;L;;;;;N;;;;;\n19A7;NEW TAI LUE LETTER HIGH XVA;Lo;0;L;;;;;N;;;;;\n19A8;NEW TAI LUE LETTER LOW KVA;Lo;0;L;;;;;N;;;;;\n19A9;NEW TAI LUE LETTER LOW XVA;Lo;0;L;;;;;N;;;;;\n19AA;NEW TAI LUE LETTER HIGH SUA;Lo;0;L;;;;;N;;;;;\n19AB;NEW TAI LUE LETTER LOW SUA;Lo;0;L;;;;;N;;;;;\n19B0;NEW TAI LUE VOWEL SIGN VOWEL SHORTENER;Lo;0;L;;;;;N;;;;;\n19B1;NEW TAI LUE VOWEL SIGN AA;Lo;0;L;;;;;N;;;;;\n19B2;NEW TAI LUE VOWEL SIGN II;Lo;0;L;;;;;N;;;;;\n19B3;NEW TAI LUE VOWEL SIGN U;Lo;0;L;;;;;N;;;;;\n19B4;NEW TAI LUE VOWEL SIGN UU;Lo;0;L;;;;;N;;;;;\n19B5;NEW TAI LUE VOWEL SIGN E;Lo;0;L;;;;;N;;;;;\n19B6;NEW TAI LUE VOWEL SIGN AE;Lo;0;L;;;;;N;;;;;\n19B7;NEW TAI LUE VOWEL SIGN O;Lo;0;L;;;;;N;;;;;\n19B8;NEW TAI LUE VOWEL SIGN OA;Lo;0;L;;;;;N;;;;;\n19B9;NEW TAI LUE VOWEL SIGN UE;Lo;0;L;;;;;N;;;;;\n19BA;NEW TAI LUE VOWEL SIGN AY;Lo;0;L;;;;;N;;;;;\n19BB;NEW TAI LUE VOWEL SIGN AAY;Lo;0;L;;;;;N;;;;;\n19BC;NEW TAI LUE VOWEL SIGN UY;Lo;0;L;;;;;N;;;;;\n19BD;NEW TAI LUE VOWEL SIGN OY;Lo;0;L;;;;;N;;;;;\n19BE;NEW TAI LUE VOWEL SIGN OAY;Lo;0;L;;;;;N;;;;;\n19BF;NEW TAI LUE VOWEL SIGN UEY;Lo;0;L;;;;;N;;;;;\n19C0;NEW TAI LUE VOWEL SIGN IY;Lo;0;L;;;;;N;;;;;\n19C1;NEW TAI LUE LETTER FINAL V;Lo;0;L;;;;;N;;;;;\n19C2;NEW TAI LUE LETTER FINAL NG;Lo;0;L;;;;;N;;;;;\n19C3;NEW TAI LUE LETTER FINAL N;Lo;0;L;;;;;N;;;;;\n19C4;NEW TAI LUE LETTER FINAL M;Lo;0;L;;;;;N;;;;;\n19C5;NEW TAI LUE LETTER FINAL K;Lo;0;L;;;;;N;;;;;\n19C6;NEW TAI LUE LETTER FINAL D;Lo;0;L;;;;;N;;;;;\n19C7;NEW TAI LUE LETTER FINAL B;Lo;0;L;;;;;N;;;;;\n19C8;NEW TAI LUE TONE MARK-1;Lo;0;L;;;;;N;;;;;\n19C9;NEW TAI LUE TONE MARK-2;Lo;0;L;;;;;N;;;;;\n19D0;NEW TAI LUE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n19D1;NEW TAI LUE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n19D2;NEW TAI LUE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n19D3;NEW TAI LUE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n19D4;NEW TAI LUE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n19D5;NEW TAI LUE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n19D6;NEW TAI LUE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n19D7;NEW TAI LUE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n19D8;NEW TAI LUE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n19D9;NEW TAI LUE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n19DA;NEW TAI LUE THAM DIGIT ONE;No;0;L;;;1;1;N;;;;;\n19DE;NEW TAI LUE SIGN LAE;So;0;ON;;;;;N;;;;;\n19DF;NEW TAI LUE SIGN LAEV;So;0;ON;;;;;N;;;;;\n19E0;KHMER SYMBOL PATHAMASAT;So;0;ON;;;;;N;;;;;\n19E1;KHMER SYMBOL MUOY KOET;So;0;ON;;;;;N;;;;;\n19E2;KHMER SYMBOL PII KOET;So;0;ON;;;;;N;;;;;\n19E3;KHMER SYMBOL BEI KOET;So;0;ON;;;;;N;;;;;\n19E4;KHMER SYMBOL BUON KOET;So;0;ON;;;;;N;;;;;\n19E5;KHMER SYMBOL PRAM KOET;So;0;ON;;;;;N;;;;;\n19E6;KHMER SYMBOL PRAM-MUOY KOET;So;0;ON;;;;;N;;;;;\n19E7;KHMER SYMBOL PRAM-PII KOET;So;0;ON;;;;;N;;;;;\n19E8;KHMER SYMBOL PRAM-BEI KOET;So;0;ON;;;;;N;;;;;\n19E9;KHMER SYMBOL PRAM-BUON KOET;So;0;ON;;;;;N;;;;;\n19EA;KHMER SYMBOL DAP KOET;So;0;ON;;;;;N;;;;;\n19EB;KHMER SYMBOL DAP-MUOY KOET;So;0;ON;;;;;N;;;;;\n19EC;KHMER SYMBOL DAP-PII KOET;So;0;ON;;;;;N;;;;;\n19ED;KHMER SYMBOL DAP-BEI KOET;So;0;ON;;;;;N;;;;;\n19EE;KHMER SYMBOL DAP-BUON KOET;So;0;ON;;;;;N;;;;;\n19EF;KHMER SYMBOL DAP-PRAM KOET;So;0;ON;;;;;N;;;;;\n19F0;KHMER SYMBOL TUTEYASAT;So;0;ON;;;;;N;;;;;\n19F1;KHMER SYMBOL MUOY ROC;So;0;ON;;;;;N;;;;;\n19F2;KHMER SYMBOL PII ROC;So;0;ON;;;;;N;;;;;\n19F3;KHMER SYMBOL BEI ROC;So;0;ON;;;;;N;;;;;\n19F4;KHMER SYMBOL BUON ROC;So;0;ON;;;;;N;;;;;\n19F5;KHMER SYMBOL PRAM ROC;So;0;ON;;;;;N;;;;;\n19F6;KHMER SYMBOL PRAM-MUOY ROC;So;0;ON;;;;;N;;;;;\n19F7;KHMER SYMBOL PRAM-PII ROC;So;0;ON;;;;;N;;;;;\n19F8;KHMER SYMBOL PRAM-BEI ROC;So;0;ON;;;;;N;;;;;\n19F9;KHMER SYMBOL PRAM-BUON ROC;So;0;ON;;;;;N;;;;;\n19FA;KHMER SYMBOL DAP ROC;So;0;ON;;;;;N;;;;;\n19FB;KHMER SYMBOL DAP-MUOY ROC;So;0;ON;;;;;N;;;;;\n19FC;KHMER SYMBOL DAP-PII ROC;So;0;ON;;;;;N;;;;;\n19FD;KHMER SYMBOL DAP-BEI ROC;So;0;ON;;;;;N;;;;;\n19FE;KHMER SYMBOL DAP-BUON ROC;So;0;ON;;;;;N;;;;;\n19FF;KHMER SYMBOL DAP-PRAM ROC;So;0;ON;;;;;N;;;;;\n1A00;BUGINESE LETTER KA;Lo;0;L;;;;;N;;;;;\n1A01;BUGINESE LETTER GA;Lo;0;L;;;;;N;;;;;\n1A02;BUGINESE LETTER NGA;Lo;0;L;;;;;N;;;;;\n1A03;BUGINESE LETTER NGKA;Lo;0;L;;;;;N;;;;;\n1A04;BUGINESE LETTER PA;Lo;0;L;;;;;N;;;;;\n1A05;BUGINESE LETTER BA;Lo;0;L;;;;;N;;;;;\n1A06;BUGINESE LETTER MA;Lo;0;L;;;;;N;;;;;\n1A07;BUGINESE LETTER MPA;Lo;0;L;;;;;N;;;;;\n1A08;BUGINESE LETTER TA;Lo;0;L;;;;;N;;;;;\n1A09;BUGINESE LETTER DA;Lo;0;L;;;;;N;;;;;\n1A0A;BUGINESE LETTER NA;Lo;0;L;;;;;N;;;;;\n1A0B;BUGINESE LETTER NRA;Lo;0;L;;;;;N;;;;;\n1A0C;BUGINESE LETTER CA;Lo;0;L;;;;;N;;;;;\n1A0D;BUGINESE LETTER JA;Lo;0;L;;;;;N;;;;;\n1A0E;BUGINESE LETTER NYA;Lo;0;L;;;;;N;;;;;\n1A0F;BUGINESE LETTER NYCA;Lo;0;L;;;;;N;;;;;\n1A10;BUGINESE LETTER YA;Lo;0;L;;;;;N;;;;;\n1A11;BUGINESE LETTER RA;Lo;0;L;;;;;N;;;;;\n1A12;BUGINESE LETTER LA;Lo;0;L;;;;;N;;;;;\n1A13;BUGINESE LETTER VA;Lo;0;L;;;;;N;;;;;\n1A14;BUGINESE LETTER SA;Lo;0;L;;;;;N;;;;;\n1A15;BUGINESE LETTER A;Lo;0;L;;;;;N;;;;;\n1A16;BUGINESE LETTER HA;Lo;0;L;;;;;N;;;;;\n1A17;BUGINESE VOWEL SIGN I;Mn;230;NSM;;;;;N;;;;;\n1A18;BUGINESE VOWEL SIGN U;Mn;220;NSM;;;;;N;;;;;\n1A19;BUGINESE VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\n1A1A;BUGINESE VOWEL SIGN O;Mc;0;L;;;;;N;;;;;\n1A1B;BUGINESE VOWEL SIGN AE;Mn;0;NSM;;;;;N;;;;;\n1A1E;BUGINESE PALLAWA;Po;0;L;;;;;N;;;;;\n1A1F;BUGINESE END OF SECTION;Po;0;L;;;;;N;;;;;\n1A20;TAI THAM LETTER HIGH KA;Lo;0;L;;;;;N;;;;;\n1A21;TAI THAM LETTER HIGH KHA;Lo;0;L;;;;;N;;;;;\n1A22;TAI THAM LETTER HIGH KXA;Lo;0;L;;;;;N;;;;;\n1A23;TAI THAM LETTER LOW KA;Lo;0;L;;;;;N;;;;;\n1A24;TAI THAM LETTER LOW KXA;Lo;0;L;;;;;N;;;;;\n1A25;TAI THAM LETTER LOW KHA;Lo;0;L;;;;;N;;;;;\n1A26;TAI THAM LETTER NGA;Lo;0;L;;;;;N;;;;;\n1A27;TAI THAM LETTER HIGH CA;Lo;0;L;;;;;N;;;;;\n1A28;TAI THAM LETTER HIGH CHA;Lo;0;L;;;;;N;;;;;\n1A29;TAI THAM LETTER LOW CA;Lo;0;L;;;;;N;;;;;\n1A2A;TAI THAM LETTER LOW SA;Lo;0;L;;;;;N;;;;;\n1A2B;TAI THAM LETTER LOW CHA;Lo;0;L;;;;;N;;;;;\n1A2C;TAI THAM LETTER NYA;Lo;0;L;;;;;N;;;;;\n1A2D;TAI THAM LETTER RATA;Lo;0;L;;;;;N;;;;;\n1A2E;TAI THAM LETTER HIGH RATHA;Lo;0;L;;;;;N;;;;;\n1A2F;TAI THAM LETTER DA;Lo;0;L;;;;;N;;;;;\n1A30;TAI THAM LETTER LOW RATHA;Lo;0;L;;;;;N;;;;;\n1A31;TAI THAM LETTER RANA;Lo;0;L;;;;;N;;;;;\n1A32;TAI THAM LETTER HIGH TA;Lo;0;L;;;;;N;;;;;\n1A33;TAI THAM LETTER HIGH THA;Lo;0;L;;;;;N;;;;;\n1A34;TAI THAM LETTER LOW TA;Lo;0;L;;;;;N;;;;;\n1A35;TAI THAM LETTER LOW THA;Lo;0;L;;;;;N;;;;;\n1A36;TAI THAM LETTER NA;Lo;0;L;;;;;N;;;;;\n1A37;TAI THAM LETTER BA;Lo;0;L;;;;;N;;;;;\n1A38;TAI THAM LETTER HIGH PA;Lo;0;L;;;;;N;;;;;\n1A39;TAI THAM LETTER HIGH PHA;Lo;0;L;;;;;N;;;;;\n1A3A;TAI THAM LETTER HIGH FA;Lo;0;L;;;;;N;;;;;\n1A3B;TAI THAM LETTER LOW PA;Lo;0;L;;;;;N;;;;;\n1A3C;TAI THAM LETTER LOW FA;Lo;0;L;;;;;N;;;;;\n1A3D;TAI THAM LETTER LOW PHA;Lo;0;L;;;;;N;;;;;\n1A3E;TAI THAM LETTER MA;Lo;0;L;;;;;N;;;;;\n1A3F;TAI THAM LETTER LOW YA;Lo;0;L;;;;;N;;;;;\n1A40;TAI THAM LETTER HIGH YA;Lo;0;L;;;;;N;;;;;\n1A41;TAI THAM LETTER RA;Lo;0;L;;;;;N;;;;;\n1A42;TAI THAM LETTER RUE;Lo;0;L;;;;;N;;;;;\n1A43;TAI THAM LETTER LA;Lo;0;L;;;;;N;;;;;\n1A44;TAI THAM LETTER LUE;Lo;0;L;;;;;N;;;;;\n1A45;TAI THAM LETTER WA;Lo;0;L;;;;;N;;;;;\n1A46;TAI THAM LETTER HIGH SHA;Lo;0;L;;;;;N;;;;;\n1A47;TAI THAM LETTER HIGH SSA;Lo;0;L;;;;;N;;;;;\n1A48;TAI THAM LETTER HIGH SA;Lo;0;L;;;;;N;;;;;\n1A49;TAI THAM LETTER HIGH HA;Lo;0;L;;;;;N;;;;;\n1A4A;TAI THAM LETTER LLA;Lo;0;L;;;;;N;;;;;\n1A4B;TAI THAM LETTER A;Lo;0;L;;;;;N;;;;;\n1A4C;TAI THAM LETTER LOW HA;Lo;0;L;;;;;N;;;;;\n1A4D;TAI THAM LETTER I;Lo;0;L;;;;;N;;;;;\n1A4E;TAI THAM LETTER II;Lo;0;L;;;;;N;;;;;\n1A4F;TAI THAM LETTER U;Lo;0;L;;;;;N;;;;;\n1A50;TAI THAM LETTER UU;Lo;0;L;;;;;N;;;;;\n1A51;TAI THAM LETTER EE;Lo;0;L;;;;;N;;;;;\n1A52;TAI THAM LETTER OO;Lo;0;L;;;;;N;;;;;\n1A53;TAI THAM LETTER LAE;Lo;0;L;;;;;N;;;;;\n1A54;TAI THAM LETTER GREAT SA;Lo;0;L;;;;;N;;;;;\n1A55;TAI THAM CONSONANT SIGN MEDIAL RA;Mc;0;L;;;;;N;;;;;\n1A56;TAI THAM CONSONANT SIGN MEDIAL LA;Mn;0;NSM;;;;;N;;;;;\n1A57;TAI THAM CONSONANT SIGN LA TANG LAI;Mc;0;L;;;;;N;;;;;\n1A58;TAI THAM SIGN MAI KANG LAI;Mn;0;NSM;;;;;N;;;;;\n1A59;TAI THAM CONSONANT SIGN FINAL NGA;Mn;0;NSM;;;;;N;;;;;\n1A5A;TAI THAM CONSONANT SIGN LOW PA;Mn;0;NSM;;;;;N;;;;;\n1A5B;TAI THAM CONSONANT SIGN HIGH RATHA OR LOW PA;Mn;0;NSM;;;;;N;;;;;\n1A5C;TAI THAM CONSONANT SIGN MA;Mn;0;NSM;;;;;N;;;;;\n1A5D;TAI THAM CONSONANT SIGN BA;Mn;0;NSM;;;;;N;;;;;\n1A5E;TAI THAM CONSONANT SIGN SA;Mn;0;NSM;;;;;N;;;;;\n1A60;TAI THAM SIGN SAKOT;Mn;9;NSM;;;;;N;;;;;\n1A61;TAI THAM VOWEL SIGN A;Mc;0;L;;;;;N;;;;;\n1A62;TAI THAM VOWEL SIGN MAI SAT;Mn;0;NSM;;;;;N;;;;;\n1A63;TAI THAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n1A64;TAI THAM VOWEL SIGN TALL AA;Mc;0;L;;;;;N;;;;;\n1A65;TAI THAM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n1A66;TAI THAM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;\n1A67;TAI THAM VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;\n1A68;TAI THAM VOWEL SIGN UUE;Mn;0;NSM;;;;;N;;;;;\n1A69;TAI THAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n1A6A;TAI THAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n1A6B;TAI THAM VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;\n1A6C;TAI THAM VOWEL SIGN OA BELOW;Mn;0;NSM;;;;;N;;;;;\n1A6D;TAI THAM VOWEL SIGN OY;Mc;0;L;;;;;N;;;;;\n1A6E;TAI THAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\n1A6F;TAI THAM VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;\n1A70;TAI THAM VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;\n1A71;TAI THAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;\n1A72;TAI THAM VOWEL SIGN THAM AI;Mc;0;L;;;;;N;;;;;\n1A73;TAI THAM VOWEL SIGN OA ABOVE;Mn;0;NSM;;;;;N;;;;;\n1A74;TAI THAM SIGN MAI KANG;Mn;0;NSM;;;;;N;;;;;\n1A75;TAI THAM SIGN TONE-1;Mn;230;NSM;;;;;N;;;;;\n1A76;TAI THAM SIGN TONE-2;Mn;230;NSM;;;;;N;;;;;\n1A77;TAI THAM SIGN KHUEN TONE-3;Mn;230;NSM;;;;;N;;;;;\n1A78;TAI THAM SIGN KHUEN TONE-4;Mn;230;NSM;;;;;N;;;;;\n1A79;TAI THAM SIGN KHUEN TONE-5;Mn;230;NSM;;;;;N;;;;;\n1A7A;TAI THAM SIGN RA HAAM;Mn;230;NSM;;;;;N;;;;;\n1A7B;TAI THAM SIGN MAI SAM;Mn;230;NSM;;;;;N;;;;;\n1A7C;TAI THAM SIGN KHUEN-LUE KARAN;Mn;230;NSM;;;;;N;;;;;\n1A7F;TAI THAM COMBINING CRYPTOGRAMMIC DOT;Mn;220;NSM;;;;;N;;;;;\n1A80;TAI THAM HORA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n1A81;TAI THAM HORA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n1A82;TAI THAM HORA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n1A83;TAI THAM HORA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n1A84;TAI THAM HORA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n1A85;TAI THAM HORA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n1A86;TAI THAM HORA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n1A87;TAI THAM HORA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n1A88;TAI THAM HORA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n1A89;TAI THAM HORA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n1A90;TAI THAM THAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n1A91;TAI THAM THAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n1A92;TAI THAM THAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n1A93;TAI THAM THAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n1A94;TAI THAM THAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n1A95;TAI THAM THAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n1A96;TAI THAM THAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n1A97;TAI THAM THAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n1A98;TAI THAM THAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n1A99;TAI THAM THAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n1AA0;TAI THAM SIGN WIANG;Po;0;L;;;;;N;;;;;\n1AA1;TAI THAM SIGN WIANGWAAK;Po;0;L;;;;;N;;;;;\n1AA2;TAI THAM SIGN SAWAN;Po;0;L;;;;;N;;;;;\n1AA3;TAI THAM SIGN KEOW;Po;0;L;;;;;N;;;;;\n1AA4;TAI THAM SIGN HOY;Po;0;L;;;;;N;;;;;\n1AA5;TAI THAM SIGN DOKMAI;Po;0;L;;;;;N;;;;;\n1AA6;TAI THAM SIGN REVERSED ROTATED RANA;Po;0;L;;;;;N;;;;;\n1AA7;TAI THAM SIGN MAI YAMOK;Lm;0;L;;;;;N;;;;;\n1AA8;TAI THAM SIGN KAAN;Po;0;L;;;;;N;;;;;\n1AA9;TAI THAM SIGN KAANKUU;Po;0;L;;;;;N;;;;;\n1AAA;TAI THAM SIGN SATKAAN;Po;0;L;;;;;N;;;;;\n1AAB;TAI THAM SIGN SATKAANKUU;Po;0;L;;;;;N;;;;;\n1AAC;TAI THAM SIGN HANG;Po;0;L;;;;;N;;;;;\n1AAD;TAI THAM SIGN CAANG;Po;0;L;;;;;N;;;;;\n1AB0;COMBINING DOUBLED CIRCUMFLEX ACCENT;Mn;230;NSM;;;;;N;;;;;\n1AB1;COMBINING DIAERESIS-RING;Mn;230;NSM;;;;;N;;;;;\n1AB2;COMBINING INFINITY;Mn;230;NSM;;;;;N;;;;;\n1AB3;COMBINING DOWNWARDS ARROW;Mn;230;NSM;;;;;N;;;;;\n1AB4;COMBINING TRIPLE DOT;Mn;230;NSM;;;;;N;;;;;\n1AB5;COMBINING X-X BELOW;Mn;220;NSM;;;;;N;;;;;\n1AB6;COMBINING WIGGLY LINE BELOW;Mn;220;NSM;;;;;N;;;;;\n1AB7;COMBINING OPEN MARK BELOW;Mn;220;NSM;;;;;N;;;;;\n1AB8;COMBINING DOUBLE OPEN MARK BELOW;Mn;220;NSM;;;;;N;;;;;\n1AB9;COMBINING LIGHT CENTRALIZATION STROKE BELOW;Mn;220;NSM;;;;;N;;;;;\n1ABA;COMBINING STRONG CENTRALIZATION STROKE BELOW;Mn;220;NSM;;;;;N;;;;;\n1ABB;COMBINING PARENTHESES ABOVE;Mn;230;NSM;;;;;N;;;;;\n1ABC;COMBINING DOUBLE PARENTHESES ABOVE;Mn;230;NSM;;;;;N;;;;;\n1ABD;COMBINING PARENTHESES BELOW;Mn;220;NSM;;;;;N;;;;;\n1ABE;COMBINING PARENTHESES OVERLAY;Me;0;NSM;;;;;N;;;;;\n1B00;BALINESE SIGN ULU RICEM;Mn;0;NSM;;;;;N;;;;;\n1B01;BALINESE SIGN ULU CANDRA;Mn;0;NSM;;;;;N;;;;;\n1B02;BALINESE SIGN CECEK;Mn;0;NSM;;;;;N;;;;;\n1B03;BALINESE SIGN SURANG;Mn;0;NSM;;;;;N;;;;;\n1B04;BALINESE SIGN BISAH;Mc;0;L;;;;;N;;;;;\n1B05;BALINESE LETTER AKARA;Lo;0;L;;;;;N;;;;;\n1B06;BALINESE LETTER AKARA TEDUNG;Lo;0;L;1B05 1B35;;;;N;;;;;\n1B07;BALINESE LETTER IKARA;Lo;0;L;;;;;N;;;;;\n1B08;BALINESE LETTER IKARA TEDUNG;Lo;0;L;1B07 1B35;;;;N;;;;;\n1B09;BALINESE LETTER UKARA;Lo;0;L;;;;;N;;;;;\n1B0A;BALINESE LETTER UKARA TEDUNG;Lo;0;L;1B09 1B35;;;;N;;;;;\n1B0B;BALINESE LETTER RA REPA;Lo;0;L;;;;;N;;;;;\n1B0C;BALINESE LETTER RA REPA TEDUNG;Lo;0;L;1B0B 1B35;;;;N;;;;;\n1B0D;BALINESE LETTER LA LENGA;Lo;0;L;;;;;N;;;;;\n1B0E;BALINESE LETTER LA LENGA TEDUNG;Lo;0;L;1B0D 1B35;;;;N;;;;;\n1B0F;BALINESE LETTER EKARA;Lo;0;L;;;;;N;;;;;\n1B10;BALINESE LETTER AIKARA;Lo;0;L;;;;;N;;;;;\n1B11;BALINESE LETTER OKARA;Lo;0;L;;;;;N;;;;;\n1B12;BALINESE LETTER OKARA TEDUNG;Lo;0;L;1B11 1B35;;;;N;;;;;\n1B13;BALINESE LETTER KA;Lo;0;L;;;;;N;;;;;\n1B14;BALINESE LETTER KA MAHAPRANA;Lo;0;L;;;;;N;;;;;\n1B15;BALINESE LETTER GA;Lo;0;L;;;;;N;;;;;\n1B16;BALINESE LETTER GA GORA;Lo;0;L;;;;;N;;;;;\n1B17;BALINESE LETTER NGA;Lo;0;L;;;;;N;;;;;\n1B18;BALINESE LETTER CA;Lo;0;L;;;;;N;;;;;\n1B19;BALINESE LETTER CA LACA;Lo;0;L;;;;;N;;;;;\n1B1A;BALINESE LETTER JA;Lo;0;L;;;;;N;;;;;\n1B1B;BALINESE LETTER JA JERA;Lo;0;L;;;;;N;;;;;\n1B1C;BALINESE LETTER NYA;Lo;0;L;;;;;N;;;;;\n1B1D;BALINESE LETTER TA LATIK;Lo;0;L;;;;;N;;;;;\n1B1E;BALINESE LETTER TA MURDA MAHAPRANA;Lo;0;L;;;;;N;;;;;\n1B1F;BALINESE LETTER DA MURDA ALPAPRANA;Lo;0;L;;;;;N;;;;;\n1B20;BALINESE LETTER DA MURDA MAHAPRANA;Lo;0;L;;;;;N;;;;;\n1B21;BALINESE LETTER NA RAMBAT;Lo;0;L;;;;;N;;;;;\n1B22;BALINESE LETTER TA;Lo;0;L;;;;;N;;;;;\n1B23;BALINESE LETTER TA TAWA;Lo;0;L;;;;;N;;;;;\n1B24;BALINESE LETTER DA;Lo;0;L;;;;;N;;;;;\n1B25;BALINESE LETTER DA MADU;Lo;0;L;;;;;N;;;;;\n1B26;BALINESE LETTER NA;Lo;0;L;;;;;N;;;;;\n1B27;BALINESE LETTER PA;Lo;0;L;;;;;N;;;;;\n1B28;BALINESE LETTER PA KAPAL;Lo;0;L;;;;;N;;;;;\n1B29;BALINESE LETTER BA;Lo;0;L;;;;;N;;;;;\n1B2A;BALINESE LETTER BA KEMBANG;Lo;0;L;;;;;N;;;;;\n1B2B;BALINESE LETTER MA;Lo;0;L;;;;;N;;;;;\n1B2C;BALINESE LETTER YA;Lo;0;L;;;;;N;;;;;\n1B2D;BALINESE LETTER RA;Lo;0;L;;;;;N;;;;;\n1B2E;BALINESE LETTER LA;Lo;0;L;;;;;N;;;;;\n1B2F;BALINESE LETTER WA;Lo;0;L;;;;;N;;;;;\n1B30;BALINESE LETTER SA SAGA;Lo;0;L;;;;;N;;;;;\n1B31;BALINESE LETTER SA SAPA;Lo;0;L;;;;;N;;;;;\n1B32;BALINESE LETTER SA;Lo;0;L;;;;;N;;;;;\n1B33;BALINESE LETTER HA;Lo;0;L;;;;;N;;;;;\n1B34;BALINESE SIGN REREKAN;Mn;7;NSM;;;;;N;;;;;\n1B35;BALINESE VOWEL SIGN TEDUNG;Mc;0;L;;;;;N;;;;;\n1B36;BALINESE VOWEL SIGN ULU;Mn;0;NSM;;;;;N;;;;;\n1B37;BALINESE VOWEL SIGN ULU SARI;Mn;0;NSM;;;;;N;;;;;\n1B38;BALINESE VOWEL SIGN SUKU;Mn;0;NSM;;;;;N;;;;;\n1B39;BALINESE VOWEL SIGN SUKU ILUT;Mn;0;NSM;;;;;N;;;;;\n1B3A;BALINESE VOWEL SIGN RA REPA;Mn;0;NSM;;;;;N;;;;;\n1B3B;BALINESE VOWEL SIGN RA REPA TEDUNG;Mc;0;L;1B3A 1B35;;;;N;;;;;\n1B3C;BALINESE VOWEL SIGN LA LENGA;Mn;0;NSM;;;;;N;;;;;\n1B3D;BALINESE VOWEL SIGN LA LENGA TEDUNG;Mc;0;L;1B3C 1B35;;;;N;;;;;\n1B3E;BALINESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;;;;\n1B3F;BALINESE VOWEL SIGN TALING REPA;Mc;0;L;;;;;N;;;;;\n1B40;BALINESE VOWEL SIGN TALING TEDUNG;Mc;0;L;1B3E 1B35;;;;N;;;;;\n1B41;BALINESE VOWEL SIGN TALING REPA TEDUNG;Mc;0;L;1B3F 1B35;;;;N;;;;;\n1B42;BALINESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;;;;\n1B43;BALINESE VOWEL SIGN PEPET TEDUNG;Mc;0;L;1B42 1B35;;;;N;;;;;\n1B44;BALINESE ADEG ADEG;Mc;9;L;;;;;N;;;;;\n1B45;BALINESE LETTER KAF SASAK;Lo;0;L;;;;;N;;;;;\n1B46;BALINESE LETTER KHOT SASAK;Lo;0;L;;;;;N;;;;;\n1B47;BALINESE LETTER TZIR SASAK;Lo;0;L;;;;;N;;;;;\n1B48;BALINESE LETTER EF SASAK;Lo;0;L;;;;;N;;;;;\n1B49;BALINESE LETTER VE SASAK;Lo;0;L;;;;;N;;;;;\n1B4A;BALINESE LETTER ZAL SASAK;Lo;0;L;;;;;N;;;;;\n1B4B;BALINESE LETTER ASYURA SASAK;Lo;0;L;;;;;N;;;;;\n1B50;BALINESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n1B51;BALINESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n1B52;BALINESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n1B53;BALINESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n1B54;BALINESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n1B55;BALINESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n1B56;BALINESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n1B57;BALINESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n1B58;BALINESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n1B59;BALINESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n1B5A;BALINESE PANTI;Po;0;L;;;;;N;;;;;\n1B5B;BALINESE PAMADA;Po;0;L;;;;;N;;;;;\n1B5C;BALINESE WINDU;Po;0;L;;;;;N;;;;;\n1B5D;BALINESE CARIK PAMUNGKAH;Po;0;L;;;;;N;;;;;\n1B5E;BALINESE CARIK SIKI;Po;0;L;;;;;N;;;;;\n1B5F;BALINESE CARIK PAREREN;Po;0;L;;;;;N;;;;;\n1B60;BALINESE PAMENENG;Po;0;L;;;;;N;;;;;\n1B61;BALINESE MUSICAL SYMBOL DONG;So;0;L;;;;;N;;;;;\n1B62;BALINESE MUSICAL SYMBOL DENG;So;0;L;;;;;N;;;;;\n1B63;BALINESE MUSICAL SYMBOL DUNG;So;0;L;;;;;N;;;;;\n1B64;BALINESE MUSICAL SYMBOL DANG;So;0;L;;;;;N;;;;;\n1B65;BALINESE MUSICAL SYMBOL DANG SURANG;So;0;L;;;;;N;;;;;\n1B66;BALINESE MUSICAL SYMBOL DING;So;0;L;;;;;N;;;;;\n1B67;BALINESE MUSICAL SYMBOL DAENG;So;0;L;;;;;N;;;;;\n1B68;BALINESE MUSICAL SYMBOL DEUNG;So;0;L;;;;;N;;;;;\n1B69;BALINESE MUSICAL SYMBOL DAING;So;0;L;;;;;N;;;;;\n1B6A;BALINESE MUSICAL SYMBOL DANG GEDE;So;0;L;;;;;N;;;;;\n1B6B;BALINESE MUSICAL SYMBOL COMBINING TEGEH;Mn;230;NSM;;;;;N;;;;;\n1B6C;BALINESE MUSICAL SYMBOL COMBINING ENDEP;Mn;220;NSM;;;;;N;;;;;\n1B6D;BALINESE MUSICAL SYMBOL COMBINING KEMPUL;Mn;230;NSM;;;;;N;;;;;\n1B6E;BALINESE MUSICAL SYMBOL COMBINING KEMPLI;Mn;230;NSM;;;;;N;;;;;\n1B6F;BALINESE MUSICAL SYMBOL COMBINING JEGOGAN;Mn;230;NSM;;;;;N;;;;;\n1B70;BALINESE MUSICAL SYMBOL COMBINING KEMPUL WITH JEGOGAN;Mn;230;NSM;;;;;N;;;;;\n1B71;BALINESE MUSICAL SYMBOL COMBINING KEMPLI WITH JEGOGAN;Mn;230;NSM;;;;;N;;;;;\n1B72;BALINESE MUSICAL SYMBOL COMBINING BENDE;Mn;230;NSM;;;;;N;;;;;\n1B73;BALINESE MUSICAL SYMBOL COMBINING GONG;Mn;230;NSM;;;;;N;;;;;\n1B74;BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG;So;0;L;;;;;N;;;;;\n1B75;BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DAG;So;0;L;;;;;N;;;;;\n1B76;BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TUK;So;0;L;;;;;N;;;;;\n1B77;BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TAK;So;0;L;;;;;N;;;;;\n1B78;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PANG;So;0;L;;;;;N;;;;;\n1B79;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PUNG;So;0;L;;;;;N;;;;;\n1B7A;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLAK;So;0;L;;;;;N;;;;;\n1B7B;BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLUK;So;0;L;;;;;N;;;;;\n1B7C;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING;So;0;L;;;;;N;;;;;\n1B80;SUNDANESE SIGN PANYECEK;Mn;0;NSM;;;;;N;;;;;\n1B81;SUNDANESE SIGN PANGLAYAR;Mn;0;NSM;;;;;N;;;;;\n1B82;SUNDANESE SIGN PANGWISAD;Mc;0;L;;;;;N;;;;;\n1B83;SUNDANESE LETTER A;Lo;0;L;;;;;N;;;;;\n1B84;SUNDANESE LETTER I;Lo;0;L;;;;;N;;;;;\n1B85;SUNDANESE LETTER U;Lo;0;L;;;;;N;;;;;\n1B86;SUNDANESE LETTER AE;Lo;0;L;;;;;N;;;;;\n1B87;SUNDANESE LETTER O;Lo;0;L;;;;;N;;;;;\n1B88;SUNDANESE LETTER E;Lo;0;L;;;;;N;;;;;\n1B89;SUNDANESE LETTER EU;Lo;0;L;;;;;N;;;;;\n1B8A;SUNDANESE LETTER KA;Lo;0;L;;;;;N;;;;;\n1B8B;SUNDANESE LETTER QA;Lo;0;L;;;;;N;;;;;\n1B8C;SUNDANESE LETTER GA;Lo;0;L;;;;;N;;;;;\n1B8D;SUNDANESE LETTER NGA;Lo;0;L;;;;;N;;;;;\n1B8E;SUNDANESE LETTER CA;Lo;0;L;;;;;N;;;;;\n1B8F;SUNDANESE LETTER JA;Lo;0;L;;;;;N;;;;;\n1B90;SUNDANESE LETTER ZA;Lo;0;L;;;;;N;;;;;\n1B91;SUNDANESE LETTER NYA;Lo;0;L;;;;;N;;;;;\n1B92;SUNDANESE LETTER TA;Lo;0;L;;;;;N;;;;;\n1B93;SUNDANESE LETTER DA;Lo;0;L;;;;;N;;;;;\n1B94;SUNDANESE LETTER NA;Lo;0;L;;;;;N;;;;;\n1B95;SUNDANESE LETTER PA;Lo;0;L;;;;;N;;;;;\n1B96;SUNDANESE LETTER FA;Lo;0;L;;;;;N;;;;;\n1B97;SUNDANESE LETTER VA;Lo;0;L;;;;;N;;;;;\n1B98;SUNDANESE LETTER BA;Lo;0;L;;;;;N;;;;;\n1B99;SUNDANESE LETTER MA;Lo;0;L;;;;;N;;;;;\n1B9A;SUNDANESE LETTER YA;Lo;0;L;;;;;N;;;;;\n1B9B;SUNDANESE LETTER RA;Lo;0;L;;;;;N;;;;;\n1B9C;SUNDANESE LETTER LA;Lo;0;L;;;;;N;;;;;\n1B9D;SUNDANESE LETTER WA;Lo;0;L;;;;;N;;;;;\n1B9E;SUNDANESE LETTER SA;Lo;0;L;;;;;N;;;;;\n1B9F;SUNDANESE LETTER XA;Lo;0;L;;;;;N;;;;;\n1BA0;SUNDANESE LETTER HA;Lo;0;L;;;;;N;;;;;\n1BA1;SUNDANESE CONSONANT SIGN PAMINGKAL;Mc;0;L;;;;;N;;;;;\n1BA2;SUNDANESE CONSONANT SIGN PANYAKRA;Mn;0;NSM;;;;;N;;;;;\n1BA3;SUNDANESE CONSONANT SIGN PANYIKU;Mn;0;NSM;;;;;N;;;;;\n1BA4;SUNDANESE VOWEL SIGN PANGHULU;Mn;0;NSM;;;;;N;;;;;\n1BA5;SUNDANESE VOWEL SIGN PANYUKU;Mn;0;NSM;;;;;N;;;;;\n1BA6;SUNDANESE VOWEL SIGN PANAELAENG;Mc;0;L;;;;;N;;;;;\n1BA7;SUNDANESE VOWEL SIGN PANOLONG;Mc;0;L;;;;;N;;;;;\n1BA8;SUNDANESE VOWEL SIGN PAMEPET;Mn;0;NSM;;;;;N;;;;;\n1BA9;SUNDANESE VOWEL SIGN PANEULEUNG;Mn;0;NSM;;;;;N;;;;;\n1BAA;SUNDANESE SIGN PAMAAEH;Mc;9;L;;;;;N;;;;;\n1BAB;SUNDANESE SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n1BAC;SUNDANESE CONSONANT SIGN PASANGAN MA;Mn;0;NSM;;;;;N;;;;;\n1BAD;SUNDANESE CONSONANT SIGN PASANGAN WA;Mn;0;NSM;;;;;N;;;;;\n1BAE;SUNDANESE LETTER KHA;Lo;0;L;;;;;N;;;;;\n1BAF;SUNDANESE LETTER SYA;Lo;0;L;;;;;N;;;;;\n1BB0;SUNDANESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n1BB1;SUNDANESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n1BB2;SUNDANESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n1BB3;SUNDANESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n1BB4;SUNDANESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n1BB5;SUNDANESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n1BB6;SUNDANESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n1BB7;SUNDANESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n1BB8;SUNDANESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n1BB9;SUNDANESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n1BBA;SUNDANESE AVAGRAHA;Lo;0;L;;;;;N;;;;;\n1BBB;SUNDANESE LETTER REU;Lo;0;L;;;;;N;;;;;\n1BBC;SUNDANESE LETTER LEU;Lo;0;L;;;;;N;;;;;\n1BBD;SUNDANESE LETTER BHA;Lo;0;L;;;;;N;;;;;\n1BBE;SUNDANESE LETTER FINAL K;Lo;0;L;;;;;N;;;;;\n1BBF;SUNDANESE LETTER FINAL M;Lo;0;L;;;;;N;;;;;\n1BC0;BATAK LETTER A;Lo;0;L;;;;;N;;;;;\n1BC1;BATAK LETTER SIMALUNGUN A;Lo;0;L;;;;;N;;;;;\n1BC2;BATAK LETTER HA;Lo;0;L;;;;;N;;;;;\n1BC3;BATAK LETTER SIMALUNGUN HA;Lo;0;L;;;;;N;;;;;\n1BC4;BATAK LETTER MANDAILING HA;Lo;0;L;;;;;N;;;;;\n1BC5;BATAK LETTER BA;Lo;0;L;;;;;N;;;;;\n1BC6;BATAK LETTER KARO BA;Lo;0;L;;;;;N;;;;;\n1BC7;BATAK LETTER PA;Lo;0;L;;;;;N;;;;;\n1BC8;BATAK LETTER SIMALUNGUN PA;Lo;0;L;;;;;N;;;;;\n1BC9;BATAK LETTER NA;Lo;0;L;;;;;N;;;;;\n1BCA;BATAK LETTER MANDAILING NA;Lo;0;L;;;;;N;;;;;\n1BCB;BATAK LETTER WA;Lo;0;L;;;;;N;;;;;\n1BCC;BATAK LETTER SIMALUNGUN WA;Lo;0;L;;;;;N;;;;;\n1BCD;BATAK LETTER PAKPAK WA;Lo;0;L;;;;;N;;;;;\n1BCE;BATAK LETTER GA;Lo;0;L;;;;;N;;;;;\n1BCF;BATAK LETTER SIMALUNGUN GA;Lo;0;L;;;;;N;;;;;\n1BD0;BATAK LETTER JA;Lo;0;L;;;;;N;;;;;\n1BD1;BATAK LETTER DA;Lo;0;L;;;;;N;;;;;\n1BD2;BATAK LETTER RA;Lo;0;L;;;;;N;;;;;\n1BD3;BATAK LETTER SIMALUNGUN RA;Lo;0;L;;;;;N;;;;;\n1BD4;BATAK LETTER MA;Lo;0;L;;;;;N;;;;;\n1BD5;BATAK LETTER SIMALUNGUN MA;Lo;0;L;;;;;N;;;;;\n1BD6;BATAK LETTER SOUTHERN TA;Lo;0;L;;;;;N;;;;;\n1BD7;BATAK LETTER NORTHERN TA;Lo;0;L;;;;;N;;;;;\n1BD8;BATAK LETTER SA;Lo;0;L;;;;;N;;;;;\n1BD9;BATAK LETTER SIMALUNGUN SA;Lo;0;L;;;;;N;;;;;\n1BDA;BATAK LETTER MANDAILING SA;Lo;0;L;;;;;N;;;;;\n1BDB;BATAK LETTER YA;Lo;0;L;;;;;N;;;;;\n1BDC;BATAK LETTER SIMALUNGUN YA;Lo;0;L;;;;;N;;;;;\n1BDD;BATAK LETTER NGA;Lo;0;L;;;;;N;;;;;\n1BDE;BATAK LETTER LA;Lo;0;L;;;;;N;;;;;\n1BDF;BATAK LETTER SIMALUNGUN LA;Lo;0;L;;;;;N;;;;;\n1BE0;BATAK LETTER NYA;Lo;0;L;;;;;N;;;;;\n1BE1;BATAK LETTER CA;Lo;0;L;;;;;N;;;;;\n1BE2;BATAK LETTER NDA;Lo;0;L;;;;;N;;;;;\n1BE3;BATAK LETTER MBA;Lo;0;L;;;;;N;;;;;\n1BE4;BATAK LETTER I;Lo;0;L;;;;;N;;;;;\n1BE5;BATAK LETTER U;Lo;0;L;;;;;N;;;;;\n1BE6;BATAK SIGN TOMPI;Mn;7;NSM;;;;;N;;;;;\n1BE7;BATAK VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\n1BE8;BATAK VOWEL SIGN PAKPAK E;Mn;0;NSM;;;;;N;;;;;\n1BE9;BATAK VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;;\n1BEA;BATAK VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n1BEB;BATAK VOWEL SIGN KARO I;Mc;0;L;;;;;N;;;;;\n1BEC;BATAK VOWEL SIGN O;Mc;0;L;;;;;N;;;;;\n1BED;BATAK VOWEL SIGN KARO O;Mn;0;NSM;;;;;N;;;;;\n1BEE;BATAK VOWEL SIGN U;Mc;0;L;;;;;N;;;;;\n1BEF;BATAK VOWEL SIGN U FOR SIMALUNGUN SA;Mn;0;NSM;;;;;N;;;;;\n1BF0;BATAK CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;;\n1BF1;BATAK CONSONANT SIGN H;Mn;0;NSM;;;;;N;;;;;\n1BF2;BATAK PANGOLAT;Mc;9;L;;;;;N;;;;;\n1BF3;BATAK PANONGONAN;Mc;9;L;;;;;N;;;;;\n1BFC;BATAK SYMBOL BINDU NA METEK;Po;0;L;;;;;N;;;;;\n1BFD;BATAK SYMBOL BINDU PINARBORAS;Po;0;L;;;;;N;;;;;\n1BFE;BATAK SYMBOL BINDU JUDUL;Po;0;L;;;;;N;;;;;\n1BFF;BATAK SYMBOL BINDU PANGOLAT;Po;0;L;;;;;N;;;;;\n1C00;LEPCHA LETTER KA;Lo;0;L;;;;;N;;;;;\n1C01;LEPCHA LETTER KLA;Lo;0;L;;;;;N;;;;;\n1C02;LEPCHA LETTER KHA;Lo;0;L;;;;;N;;;;;\n1C03;LEPCHA LETTER GA;Lo;0;L;;;;;N;;;;;\n1C04;LEPCHA LETTER GLA;Lo;0;L;;;;;N;;;;;\n1C05;LEPCHA LETTER NGA;Lo;0;L;;;;;N;;;;;\n1C06;LEPCHA LETTER CA;Lo;0;L;;;;;N;;;;;\n1C07;LEPCHA LETTER CHA;Lo;0;L;;;;;N;;;;;\n1C08;LEPCHA LETTER JA;Lo;0;L;;;;;N;;;;;\n1C09;LEPCHA LETTER NYA;Lo;0;L;;;;;N;;;;;\n1C0A;LEPCHA LETTER TA;Lo;0;L;;;;;N;;;;;\n1C0B;LEPCHA LETTER THA;Lo;0;L;;;;;N;;;;;\n1C0C;LEPCHA LETTER DA;Lo;0;L;;;;;N;;;;;\n1C0D;LEPCHA LETTER NA;Lo;0;L;;;;;N;;;;;\n1C0E;LEPCHA LETTER PA;Lo;0;L;;;;;N;;;;;\n1C0F;LEPCHA LETTER PLA;Lo;0;L;;;;;N;;;;;\n1C10;LEPCHA LETTER PHA;Lo;0;L;;;;;N;;;;;\n1C11;LEPCHA LETTER FA;Lo;0;L;;;;;N;;;;;\n1C12;LEPCHA LETTER FLA;Lo;0;L;;;;;N;;;;;\n1C13;LEPCHA LETTER BA;Lo;0;L;;;;;N;;;;;\n1C14;LEPCHA LETTER BLA;Lo;0;L;;;;;N;;;;;\n1C15;LEPCHA LETTER MA;Lo;0;L;;;;;N;;;;;\n1C16;LEPCHA LETTER MLA;Lo;0;L;;;;;N;;;;;\n1C17;LEPCHA LETTER TSA;Lo;0;L;;;;;N;;;;;\n1C18;LEPCHA LETTER TSHA;Lo;0;L;;;;;N;;;;;\n1C19;LEPCHA LETTER DZA;Lo;0;L;;;;;N;;;;;\n1C1A;LEPCHA LETTER YA;Lo;0;L;;;;;N;;;;;\n1C1B;LEPCHA LETTER RA;Lo;0;L;;;;;N;;;;;\n1C1C;LEPCHA LETTER LA;Lo;0;L;;;;;N;;;;;\n1C1D;LEPCHA LETTER HA;Lo;0;L;;;;;N;;;;;\n1C1E;LEPCHA LETTER HLA;Lo;0;L;;;;;N;;;;;\n1C1F;LEPCHA LETTER VA;Lo;0;L;;;;;N;;;;;\n1C20;LEPCHA LETTER SA;Lo;0;L;;;;;N;;;;;\n1C21;LEPCHA LETTER SHA;Lo;0;L;;;;;N;;;;;\n1C22;LEPCHA LETTER WA;Lo;0;L;;;;;N;;;;;\n1C23;LEPCHA LETTER A;Lo;0;L;;;;;N;;;;;\n1C24;LEPCHA SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;;\n1C25;LEPCHA SUBJOINED LETTER RA;Mc;0;L;;;;;N;;;;;\n1C26;LEPCHA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n1C27;LEPCHA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n1C28;LEPCHA VOWEL SIGN O;Mc;0;L;;;;;N;;;;;\n1C29;LEPCHA VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;\n1C2A;LEPCHA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;\n1C2B;LEPCHA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;\n1C2C;LEPCHA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n1C2D;LEPCHA CONSONANT SIGN K;Mn;0;NSM;;;;;N;;;;;\n1C2E;LEPCHA CONSONANT SIGN M;Mn;0;NSM;;;;;N;;;;;\n1C2F;LEPCHA CONSONANT SIGN L;Mn;0;NSM;;;;;N;;;;;\n1C30;LEPCHA CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;;\n1C31;LEPCHA CONSONANT SIGN P;Mn;0;NSM;;;;;N;;;;;\n1C32;LEPCHA CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;;\n1C33;LEPCHA CONSONANT SIGN T;Mn;0;NSM;;;;;N;;;;;\n1C34;LEPCHA CONSONANT SIGN NYIN-DO;Mc;0;L;;;;;N;;;;;\n1C35;LEPCHA CONSONANT SIGN KANG;Mc;0;L;;;;;N;;;;;\n1C36;LEPCHA SIGN RAN;Mn;0;NSM;;;;;N;;;;;\n1C37;LEPCHA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n1C3B;LEPCHA PUNCTUATION TA-ROL;Po;0;L;;;;;N;;;;;\n1C3C;LEPCHA PUNCTUATION NYET THYOOM TA-ROL;Po;0;L;;;;;N;;;;;\n1C3D;LEPCHA PUNCTUATION CER-WA;Po;0;L;;;;;N;;;;;\n1C3E;LEPCHA PUNCTUATION TSHOOK CER-WA;Po;0;L;;;;;N;;;;;\n1C3F;LEPCHA PUNCTUATION TSHOOK;Po;0;L;;;;;N;;;;;\n1C40;LEPCHA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n1C41;LEPCHA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n1C42;LEPCHA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n1C43;LEPCHA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n1C44;LEPCHA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n1C45;LEPCHA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n1C46;LEPCHA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n1C47;LEPCHA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n1C48;LEPCHA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n1C49;LEPCHA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n1C4D;LEPCHA LETTER TTA;Lo;0;L;;;;;N;;;;;\n1C4E;LEPCHA LETTER TTHA;Lo;0;L;;;;;N;;;;;\n1C4F;LEPCHA LETTER DDA;Lo;0;L;;;;;N;;;;;\n1C50;OL CHIKI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n1C51;OL CHIKI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n1C52;OL CHIKI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n1C53;OL CHIKI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n1C54;OL CHIKI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n1C55;OL CHIKI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n1C56;OL CHIKI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n1C57;OL CHIKI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n1C58;OL CHIKI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n1C59;OL CHIKI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n1C5A;OL CHIKI LETTER LA;Lo;0;L;;;;;N;;;;;\n1C5B;OL CHIKI LETTER AT;Lo;0;L;;;;;N;;;;;\n1C5C;OL CHIKI LETTER AG;Lo;0;L;;;;;N;;;;;\n1C5D;OL CHIKI LETTER ANG;Lo;0;L;;;;;N;;;;;\n1C5E;OL CHIKI LETTER AL;Lo;0;L;;;;;N;;;;;\n1C5F;OL CHIKI LETTER LAA;Lo;0;L;;;;;N;;;;;\n1C60;OL CHIKI LETTER AAK;Lo;0;L;;;;;N;;;;;\n1C61;OL CHIKI LETTER AAJ;Lo;0;L;;;;;N;;;;;\n1C62;OL CHIKI LETTER AAM;Lo;0;L;;;;;N;;;;;\n1C63;OL CHIKI LETTER AAW;Lo;0;L;;;;;N;;;;;\n1C64;OL CHIKI LETTER LI;Lo;0;L;;;;;N;;;;;\n1C65;OL CHIKI LETTER IS;Lo;0;L;;;;;N;;;;;\n1C66;OL CHIKI LETTER IH;Lo;0;L;;;;;N;;;;;\n1C67;OL CHIKI LETTER INY;Lo;0;L;;;;;N;;;;;\n1C68;OL CHIKI LETTER IR;Lo;0;L;;;;;N;;;;;\n1C69;OL CHIKI LETTER LU;Lo;0;L;;;;;N;;;;;\n1C6A;OL CHIKI LETTER UC;Lo;0;L;;;;;N;;;;;\n1C6B;OL CHIKI LETTER UD;Lo;0;L;;;;;N;;;;;\n1C6C;OL CHIKI LETTER UNN;Lo;0;L;;;;;N;;;;;\n1C6D;OL CHIKI LETTER UY;Lo;0;L;;;;;N;;;;;\n1C6E;OL CHIKI LETTER LE;Lo;0;L;;;;;N;;;;;\n1C6F;OL CHIKI LETTER EP;Lo;0;L;;;;;N;;;;;\n1C70;OL CHIKI LETTER EDD;Lo;0;L;;;;;N;;;;;\n1C71;OL CHIKI LETTER EN;Lo;0;L;;;;;N;;;;;\n1C72;OL CHIKI LETTER ERR;Lo;0;L;;;;;N;;;;;\n1C73;OL CHIKI LETTER LO;Lo;0;L;;;;;N;;;;;\n1C74;OL CHIKI LETTER OTT;Lo;0;L;;;;;N;;;;;\n1C75;OL CHIKI LETTER OB;Lo;0;L;;;;;N;;;;;\n1C76;OL CHIKI LETTER OV;Lo;0;L;;;;;N;;;;;\n1C77;OL CHIKI LETTER OH;Lo;0;L;;;;;N;;;;;\n1C78;OL CHIKI MU TTUDDAG;Lm;0;L;;;;;N;;;;;\n1C79;OL CHIKI GAAHLAA TTUDDAAG;Lm;0;L;;;;;N;;;;;\n1C7A;OL CHIKI MU-GAAHLAA TTUDDAAG;Lm;0;L;;;;;N;;;;;\n1C7B;OL CHIKI RELAA;Lm;0;L;;;;;N;;;;;\n1C7C;OL CHIKI PHAARKAA;Lm;0;L;;;;;N;;;;;\n1C7D;OL CHIKI AHAD;Lm;0;L;;;;;N;;;;;\n1C7E;OL CHIKI PUNCTUATION MUCAAD;Po;0;L;;;;;N;;;;;\n1C7F;OL CHIKI PUNCTUATION DOUBLE MUCAAD;Po;0;L;;;;;N;;;;;\n1C80;CYRILLIC SMALL LETTER ROUNDED VE;Ll;0;L;;;;;N;;;0412;;0412\n1C81;CYRILLIC SMALL LETTER LONG-LEGGED DE;Ll;0;L;;;;;N;;;0414;;0414\n1C82;CYRILLIC SMALL LETTER NARROW O;Ll;0;L;;;;;N;;;041E;;041E\n1C83;CYRILLIC SMALL LETTER WIDE ES;Ll;0;L;;;;;N;;;0421;;0421\n1C84;CYRILLIC SMALL LETTER TALL TE;Ll;0;L;;;;;N;;;0422;;0422\n1C85;CYRILLIC SMALL LETTER THREE-LEGGED TE;Ll;0;L;;;;;N;;;0422;;0422\n1C86;CYRILLIC SMALL LETTER TALL HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A\n1C87;CYRILLIC SMALL LETTER TALL YAT;Ll;0;L;;;;;N;;;0462;;0462\n1C88;CYRILLIC SMALL LETTER UNBLENDED UK;Ll;0;L;;;;;N;;;A64A;;A64A\n1C90;GEORGIAN MTAVRULI CAPITAL LETTER AN;Lu;0;L;;;;;N;;;;10D0;\n1C91;GEORGIAN MTAVRULI CAPITAL LETTER BAN;Lu;0;L;;;;;N;;;;10D1;\n1C92;GEORGIAN MTAVRULI CAPITAL LETTER GAN;Lu;0;L;;;;;N;;;;10D2;\n1C93;GEORGIAN MTAVRULI CAPITAL LETTER DON;Lu;0;L;;;;;N;;;;10D3;\n1C94;GEORGIAN MTAVRULI CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;10D4;\n1C95;GEORGIAN MTAVRULI CAPITAL LETTER VIN;Lu;0;L;;;;;N;;;;10D5;\n1C96;GEORGIAN MTAVRULI CAPITAL LETTER ZEN;Lu;0;L;;;;;N;;;;10D6;\n1C97;GEORGIAN MTAVRULI CAPITAL LETTER TAN;Lu;0;L;;;;;N;;;;10D7;\n1C98;GEORGIAN MTAVRULI CAPITAL LETTER IN;Lu;0;L;;;;;N;;;;10D8;\n1C99;GEORGIAN MTAVRULI CAPITAL LETTER KAN;Lu;0;L;;;;;N;;;;10D9;\n1C9A;GEORGIAN MTAVRULI CAPITAL LETTER LAS;Lu;0;L;;;;;N;;;;10DA;\n1C9B;GEORGIAN MTAVRULI CAPITAL LETTER MAN;Lu;0;L;;;;;N;;;;10DB;\n1C9C;GEORGIAN MTAVRULI CAPITAL LETTER NAR;Lu;0;L;;;;;N;;;;10DC;\n1C9D;GEORGIAN MTAVRULI CAPITAL LETTER ON;Lu;0;L;;;;;N;;;;10DD;\n1C9E;GEORGIAN MTAVRULI CAPITAL LETTER PAR;Lu;0;L;;;;;N;;;;10DE;\n1C9F;GEORGIAN MTAVRULI CAPITAL LETTER ZHAR;Lu;0;L;;;;;N;;;;10DF;\n1CA0;GEORGIAN MTAVRULI CAPITAL LETTER RAE;Lu;0;L;;;;;N;;;;10E0;\n1CA1;GEORGIAN MTAVRULI CAPITAL LETTER SAN;Lu;0;L;;;;;N;;;;10E1;\n1CA2;GEORGIAN MTAVRULI CAPITAL LETTER TAR;Lu;0;L;;;;;N;;;;10E2;\n1CA3;GEORGIAN MTAVRULI CAPITAL LETTER UN;Lu;0;L;;;;;N;;;;10E3;\n1CA4;GEORGIAN MTAVRULI CAPITAL LETTER PHAR;Lu;0;L;;;;;N;;;;10E4;\n1CA5;GEORGIAN MTAVRULI CAPITAL LETTER KHAR;Lu;0;L;;;;;N;;;;10E5;\n1CA6;GEORGIAN MTAVRULI CAPITAL LETTER GHAN;Lu;0;L;;;;;N;;;;10E6;\n1CA7;GEORGIAN MTAVRULI CAPITAL LETTER QAR;Lu;0;L;;;;;N;;;;10E7;\n1CA8;GEORGIAN MTAVRULI CAPITAL LETTER SHIN;Lu;0;L;;;;;N;;;;10E8;\n1CA9;GEORGIAN MTAVRULI CAPITAL LETTER CHIN;Lu;0;L;;;;;N;;;;10E9;\n1CAA;GEORGIAN MTAVRULI CAPITAL LETTER CAN;Lu;0;L;;;;;N;;;;10EA;\n1CAB;GEORGIAN MTAVRULI CAPITAL LETTER JIL;Lu;0;L;;;;;N;;;;10EB;\n1CAC;GEORGIAN MTAVRULI CAPITAL LETTER CIL;Lu;0;L;;;;;N;;;;10EC;\n1CAD;GEORGIAN MTAVRULI CAPITAL LETTER CHAR;Lu;0;L;;;;;N;;;;10ED;\n1CAE;GEORGIAN MTAVRULI CAPITAL LETTER XAN;Lu;0;L;;;;;N;;;;10EE;\n1CAF;GEORGIAN MTAVRULI CAPITAL LETTER JHAN;Lu;0;L;;;;;N;;;;10EF;\n1CB0;GEORGIAN MTAVRULI CAPITAL LETTER HAE;Lu;0;L;;;;;N;;;;10F0;\n1CB1;GEORGIAN MTAVRULI CAPITAL LETTER HE;Lu;0;L;;;;;N;;;;10F1;\n1CB2;GEORGIAN MTAVRULI CAPITAL LETTER HIE;Lu;0;L;;;;;N;;;;10F2;\n1CB3;GEORGIAN MTAVRULI CAPITAL LETTER WE;Lu;0;L;;;;;N;;;;10F3;\n1CB4;GEORGIAN MTAVRULI CAPITAL LETTER HAR;Lu;0;L;;;;;N;;;;10F4;\n1CB5;GEORGIAN MTAVRULI CAPITAL LETTER HOE;Lu;0;L;;;;;N;;;;10F5;\n1CB6;GEORGIAN MTAVRULI CAPITAL LETTER FI;Lu;0;L;;;;;N;;;;10F6;\n1CB7;GEORGIAN MTAVRULI CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;10F7;\n1CB8;GEORGIAN MTAVRULI CAPITAL LETTER ELIFI;Lu;0;L;;;;;N;;;;10F8;\n1CB9;GEORGIAN MTAVRULI CAPITAL LETTER TURNED GAN;Lu;0;L;;;;;N;;;;10F9;\n1CBA;GEORGIAN MTAVRULI CAPITAL LETTER AIN;Lu;0;L;;;;;N;;;;10FA;\n1CBD;GEORGIAN MTAVRULI CAPITAL LETTER AEN;Lu;0;L;;;;;N;;;;10FD;\n1CBE;GEORGIAN MTAVRULI CAPITAL LETTER HARD SIGN;Lu;0;L;;;;;N;;;;10FE;\n1CBF;GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN;Lu;0;L;;;;;N;;;;10FF;\n1CC0;SUNDANESE PUNCTUATION BINDU SURYA;Po;0;L;;;;;N;;;;;\n1CC1;SUNDANESE PUNCTUATION BINDU PANGLONG;Po;0;L;;;;;N;;;;;\n1CC2;SUNDANESE PUNCTUATION BINDU PURNAMA;Po;0;L;;;;;N;;;;;\n1CC3;SUNDANESE PUNCTUATION BINDU CAKRA;Po;0;L;;;;;N;;;;;\n1CC4;SUNDANESE PUNCTUATION BINDU LEU SATANGA;Po;0;L;;;;;N;;;;;\n1CC5;SUNDANESE PUNCTUATION BINDU KA SATANGA;Po;0;L;;;;;N;;;;;\n1CC6;SUNDANESE PUNCTUATION BINDU DA SATANGA;Po;0;L;;;;;N;;;;;\n1CC7;SUNDANESE PUNCTUATION BINDU BA SATANGA;Po;0;L;;;;;N;;;;;\n1CD0;VEDIC TONE KARSHANA;Mn;230;NSM;;;;;N;;;;;\n1CD1;VEDIC TONE SHARA;Mn;230;NSM;;;;;N;;;;;\n1CD2;VEDIC TONE PRENKHA;Mn;230;NSM;;;;;N;;;;;\n1CD3;VEDIC SIGN NIHSHVASA;Po;0;L;;;;;N;;;;;\n1CD4;VEDIC SIGN YAJURVEDIC MIDLINE SVARITA;Mn;1;NSM;;;;;N;;;;;\n1CD5;VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;;\n1CD6;VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;;\n1CD7;VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA;Mn;220;NSM;;;;;N;;;;;\n1CD8;VEDIC TONE CANDRA BELOW;Mn;220;NSM;;;;;N;;;;;\n1CD9;VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER;Mn;220;NSM;;;;;N;;;;;\n1CDA;VEDIC TONE DOUBLE SVARITA;Mn;230;NSM;;;;;N;;;;;\n1CDB;VEDIC TONE TRIPLE SVARITA;Mn;230;NSM;;;;;N;;;;;\n1CDC;VEDIC TONE KATHAKA ANUDATTA;Mn;220;NSM;;;;;N;;;;;\n1CDD;VEDIC TONE DOT BELOW;Mn;220;NSM;;;;;N;;;;;\n1CDE;VEDIC TONE TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;;\n1CDF;VEDIC TONE THREE DOTS BELOW;Mn;220;NSM;;;;;N;;;;;\n1CE0;VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA;Mn;230;NSM;;;;;N;;;;;\n1CE1;VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA;Mc;0;L;;;;;N;;;;;\n1CE2;VEDIC SIGN VISARGA SVARITA;Mn;1;NSM;;;;;N;;;;;\n1CE3;VEDIC SIGN VISARGA UDATTA;Mn;1;NSM;;;;;N;;;;;\n1CE4;VEDIC SIGN REVERSED VISARGA UDATTA;Mn;1;NSM;;;;;N;;;;;\n1CE5;VEDIC SIGN VISARGA ANUDATTA;Mn;1;NSM;;;;;N;;;;;\n1CE6;VEDIC SIGN REVERSED VISARGA ANUDATTA;Mn;1;NSM;;;;;N;;;;;\n1CE7;VEDIC SIGN VISARGA UDATTA WITH TAIL;Mn;1;NSM;;;;;N;;;;;\n1CE8;VEDIC SIGN VISARGA ANUDATTA WITH TAIL;Mn;1;NSM;;;;;N;;;;;\n1CE9;VEDIC SIGN ANUSVARA ANTARGOMUKHA;Lo;0;L;;;;;N;;;;;\n1CEA;VEDIC SIGN ANUSVARA BAHIRGOMUKHA;Lo;0;L;;;;;N;;;;;\n1CEB;VEDIC SIGN ANUSVARA VAMAGOMUKHA;Lo;0;L;;;;;N;;;;;\n1CEC;VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL;Lo;0;L;;;;;N;;;;;\n1CED;VEDIC SIGN TIRYAK;Mn;220;NSM;;;;;N;;;;;\n1CEE;VEDIC SIGN HEXIFORM LONG ANUSVARA;Lo;0;L;;;;;N;;;;;\n1CEF;VEDIC SIGN LONG ANUSVARA;Lo;0;L;;;;;N;;;;;\n1CF0;VEDIC SIGN RTHANG LONG ANUSVARA;Lo;0;L;;;;;N;;;;;\n1CF1;VEDIC SIGN ANUSVARA UBHAYATO MUKHA;Lo;0;L;;;;;N;;;;;\n1CF2;VEDIC SIGN ARDHAVISARGA;Lo;0;L;;;;;N;;;;;\n1CF3;VEDIC SIGN ROTATED ARDHAVISARGA;Lo;0;L;;;;;N;;;;;\n1CF4;VEDIC TONE CANDRA ABOVE;Mn;230;NSM;;;;;N;;;;;\n1CF5;VEDIC SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;\n1CF6;VEDIC SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;\n1CF7;VEDIC SIGN ATIKRAMA;Mc;0;L;;;;;N;;;;;\n1CF8;VEDIC TONE RING ABOVE;Mn;230;NSM;;;;;N;;;;;\n1CF9;VEDIC TONE DOUBLE RING ABOVE;Mn;230;NSM;;;;;N;;;;;\n1CFA;VEDIC SIGN DOUBLE ANUSVARA ANTARGOMUKHA;Lo;0;L;;;;;N;;;;;\n1D00;LATIN LETTER SMALL CAPITAL A;Ll;0;L;;;;;N;;;;;\n1D01;LATIN LETTER SMALL CAPITAL AE;Ll;0;L;;;;;N;;;;;\n1D02;LATIN SMALL LETTER TURNED AE;Ll;0;L;;;;;N;;;;;\n1D03;LATIN LETTER SMALL CAPITAL BARRED B;Ll;0;L;;;;;N;;;;;\n1D04;LATIN LETTER SMALL CAPITAL C;Ll;0;L;;;;;N;;;;;\n1D05;LATIN LETTER SMALL CAPITAL D;Ll;0;L;;;;;N;;;;;\n1D06;LATIN LETTER SMALL CAPITAL ETH;Ll;0;L;;;;;N;;;;;\n1D07;LATIN LETTER SMALL CAPITAL E;Ll;0;L;;;;;N;;;;;\n1D08;LATIN SMALL LETTER TURNED OPEN E;Ll;0;L;;;;;N;;;;;\n1D09;LATIN SMALL LETTER TURNED I;Ll;0;L;;;;;N;;;;;\n1D0A;LATIN LETTER SMALL CAPITAL J;Ll;0;L;;;;;N;;;;;\n1D0B;LATIN LETTER SMALL CAPITAL K;Ll;0;L;;;;;N;;;;;\n1D0C;LATIN LETTER SMALL CAPITAL L WITH STROKE;Ll;0;L;;;;;N;;;;;\n1D0D;LATIN LETTER SMALL CAPITAL M;Ll;0;L;;;;;N;;;;;\n1D0E;LATIN LETTER SMALL CAPITAL REVERSED N;Ll;0;L;;;;;N;;;;;\n1D0F;LATIN LETTER SMALL CAPITAL O;Ll;0;L;;;;;N;;;;;\n1D10;LATIN LETTER SMALL CAPITAL OPEN O;Ll;0;L;;;;;N;;;;;\n1D11;LATIN SMALL LETTER SIDEWAYS O;Ll;0;L;;;;;N;;;;;\n1D12;LATIN SMALL LETTER SIDEWAYS OPEN O;Ll;0;L;;;;;N;;;;;\n1D13;LATIN SMALL LETTER SIDEWAYS O WITH STROKE;Ll;0;L;;;;;N;;;;;\n1D14;LATIN SMALL LETTER TURNED OE;Ll;0;L;;;;;N;;;;;\n1D15;LATIN LETTER SMALL CAPITAL OU;Ll;0;L;;;;;N;;;;;\n1D16;LATIN SMALL LETTER TOP HALF O;Ll;0;L;;;;;N;;;;;\n1D17;LATIN SMALL LETTER BOTTOM HALF O;Ll;0;L;;;;;N;;;;;\n1D18;LATIN LETTER SMALL CAPITAL P;Ll;0;L;;;;;N;;;;;\n1D19;LATIN LETTER SMALL CAPITAL REVERSED R;Ll;0;L;;;;;N;;;;;\n1D1A;LATIN LETTER SMALL CAPITAL TURNED R;Ll;0;L;;;;;N;;;;;\n1D1B;LATIN LETTER SMALL CAPITAL T;Ll;0;L;;;;;N;;;;;\n1D1C;LATIN LETTER SMALL CAPITAL U;Ll;0;L;;;;;N;;;;;\n1D1D;LATIN SMALL LETTER SIDEWAYS U;Ll;0;L;;;;;N;;;;;\n1D1E;LATIN SMALL LETTER SIDEWAYS DIAERESIZED U;Ll;0;L;;;;;N;;;;;\n1D1F;LATIN SMALL LETTER SIDEWAYS TURNED M;Ll;0;L;;;;;N;;;;;\n1D20;LATIN LETTER SMALL CAPITAL V;Ll;0;L;;;;;N;;;;;\n1D21;LATIN LETTER SMALL CAPITAL W;Ll;0;L;;;;;N;;;;;\n1D22;LATIN LETTER SMALL CAPITAL Z;Ll;0;L;;;;;N;;;;;\n1D23;LATIN LETTER SMALL CAPITAL EZH;Ll;0;L;;;;;N;;;;;\n1D24;LATIN LETTER VOICED LARYNGEAL SPIRANT;Ll;0;L;;;;;N;;;;;\n1D25;LATIN LETTER AIN;Ll;0;L;;;;;N;;;;;\n1D26;GREEK LETTER SMALL CAPITAL GAMMA;Ll;0;L;;;;;N;;;;;\n1D27;GREEK LETTER SMALL CAPITAL LAMDA;Ll;0;L;;;;;N;;;;;\n1D28;GREEK LETTER SMALL CAPITAL PI;Ll;0;L;;;;;N;;;;;\n1D29;GREEK LETTER SMALL CAPITAL RHO;Ll;0;L;;;;;N;;;;;\n1D2A;GREEK LETTER SMALL CAPITAL PSI;Ll;0;L;;;;;N;;;;;\n1D2B;CYRILLIC LETTER SMALL CAPITAL EL;Ll;0;L;;;;;N;;;;;\n1D2C;MODIFIER LETTER CAPITAL A;Lm;0;L;<super> 0041;;;;N;;;;;\n1D2D;MODIFIER LETTER CAPITAL AE;Lm;0;L;<super> 00C6;;;;N;;;;;\n1D2E;MODIFIER LETTER CAPITAL B;Lm;0;L;<super> 0042;;;;N;;;;;\n1D2F;MODIFIER LETTER CAPITAL BARRED B;Lm;0;L;;;;;N;;;;;\n1D30;MODIFIER LETTER CAPITAL D;Lm;0;L;<super> 0044;;;;N;;;;;\n1D31;MODIFIER LETTER CAPITAL E;Lm;0;L;<super> 0045;;;;N;;;;;\n1D32;MODIFIER LETTER CAPITAL REVERSED E;Lm;0;L;<super> 018E;;;;N;;;;;\n1D33;MODIFIER LETTER CAPITAL G;Lm;0;L;<super> 0047;;;;N;;;;;\n1D34;MODIFIER LETTER CAPITAL H;Lm;0;L;<super> 0048;;;;N;;;;;\n1D35;MODIFIER LETTER CAPITAL I;Lm;0;L;<super> 0049;;;;N;;;;;\n1D36;MODIFIER LETTER CAPITAL J;Lm;0;L;<super> 004A;;;;N;;;;;\n1D37;MODIFIER LETTER CAPITAL K;Lm;0;L;<super> 004B;;;;N;;;;;\n1D38;MODIFIER LETTER CAPITAL L;Lm;0;L;<super> 004C;;;;N;;;;;\n1D39;MODIFIER LETTER CAPITAL M;Lm;0;L;<super> 004D;;;;N;;;;;\n1D3A;MODIFIER LETTER CAPITAL N;Lm;0;L;<super> 004E;;;;N;;;;;\n1D3B;MODIFIER LETTER CAPITAL REVERSED N;Lm;0;L;;;;;N;;;;;\n1D3C;MODIFIER LETTER CAPITAL O;Lm;0;L;<super> 004F;;;;N;;;;;\n1D3D;MODIFIER LETTER CAPITAL OU;Lm;0;L;<super> 0222;;;;N;;;;;\n1D3E;MODIFIER LETTER CAPITAL P;Lm;0;L;<super> 0050;;;;N;;;;;\n1D3F;MODIFIER LETTER CAPITAL R;Lm;0;L;<super> 0052;;;;N;;;;;\n1D40;MODIFIER LETTER CAPITAL T;Lm;0;L;<super> 0054;;;;N;;;;;\n1D41;MODIFIER LETTER CAPITAL U;Lm;0;L;<super> 0055;;;;N;;;;;\n1D42;MODIFIER LETTER CAPITAL W;Lm;0;L;<super> 0057;;;;N;;;;;\n1D43;MODIFIER LETTER SMALL A;Lm;0;L;<super> 0061;;;;N;;;;;\n1D44;MODIFIER LETTER SMALL TURNED A;Lm;0;L;<super> 0250;;;;N;;;;;\n1D45;MODIFIER LETTER SMALL ALPHA;Lm;0;L;<super> 0251;;;;N;;;;;\n1D46;MODIFIER LETTER SMALL TURNED AE;Lm;0;L;<super> 1D02;;;;N;;;;;\n1D47;MODIFIER LETTER SMALL B;Lm;0;L;<super> 0062;;;;N;;;;;\n1D48;MODIFIER LETTER SMALL D;Lm;0;L;<super> 0064;;;;N;;;;;\n1D49;MODIFIER LETTER SMALL E;Lm;0;L;<super> 0065;;;;N;;;;;\n1D4A;MODIFIER LETTER SMALL SCHWA;Lm;0;L;<super> 0259;;;;N;;;;;\n1D4B;MODIFIER LETTER SMALL OPEN E;Lm;0;L;<super> 025B;;;;N;;;;;\n1D4C;MODIFIER LETTER SMALL TURNED OPEN E;Lm;0;L;<super> 025C;;;;N;;;;;\n1D4D;MODIFIER LETTER SMALL G;Lm;0;L;<super> 0067;;;;N;;;;;\n1D4E;MODIFIER LETTER SMALL TURNED I;Lm;0;L;;;;;N;;;;;\n1D4F;MODIFIER LETTER SMALL K;Lm;0;L;<super> 006B;;;;N;;;;;\n1D50;MODIFIER LETTER SMALL M;Lm;0;L;<super> 006D;;;;N;;;;;\n1D51;MODIFIER LETTER SMALL ENG;Lm;0;L;<super> 014B;;;;N;;;;;\n1D52;MODIFIER LETTER SMALL O;Lm;0;L;<super> 006F;;;;N;;;;;\n1D53;MODIFIER LETTER SMALL OPEN O;Lm;0;L;<super> 0254;;;;N;;;;;\n1D54;MODIFIER LETTER SMALL TOP HALF O;Lm;0;L;<super> 1D16;;;;N;;;;;\n1D55;MODIFIER LETTER SMALL BOTTOM HALF O;Lm;0;L;<super> 1D17;;;;N;;;;;\n1D56;MODIFIER LETTER SMALL P;Lm;0;L;<super> 0070;;;;N;;;;;\n1D57;MODIFIER LETTER SMALL T;Lm;0;L;<super> 0074;;;;N;;;;;\n1D58;MODIFIER LETTER SMALL U;Lm;0;L;<super> 0075;;;;N;;;;;\n1D59;MODIFIER LETTER SMALL SIDEWAYS U;Lm;0;L;<super> 1D1D;;;;N;;;;;\n1D5A;MODIFIER LETTER SMALL TURNED M;Lm;0;L;<super> 026F;;;;N;;;;;\n1D5B;MODIFIER LETTER SMALL V;Lm;0;L;<super> 0076;;;;N;;;;;\n1D5C;MODIFIER LETTER SMALL AIN;Lm;0;L;<super> 1D25;;;;N;;;;;\n1D5D;MODIFIER LETTER SMALL BETA;Lm;0;L;<super> 03B2;;;;N;;;;;\n1D5E;MODIFIER LETTER SMALL GREEK GAMMA;Lm;0;L;<super> 03B3;;;;N;;;;;\n1D5F;MODIFIER LETTER SMALL DELTA;Lm;0;L;<super> 03B4;;;;N;;;;;\n1D60;MODIFIER LETTER SMALL GREEK PHI;Lm;0;L;<super> 03C6;;;;N;;;;;\n1D61;MODIFIER LETTER SMALL CHI;Lm;0;L;<super> 03C7;;;;N;;;;;\n1D62;LATIN SUBSCRIPT SMALL LETTER I;Lm;0;L;<sub> 0069;;;;N;;;;;\n1D63;LATIN SUBSCRIPT SMALL LETTER R;Lm;0;L;<sub> 0072;;;;N;;;;;\n1D64;LATIN SUBSCRIPT SMALL LETTER U;Lm;0;L;<sub> 0075;;;;N;;;;;\n1D65;LATIN SUBSCRIPT SMALL LETTER V;Lm;0;L;<sub> 0076;;;;N;;;;;\n1D66;GREEK SUBSCRIPT SMALL LETTER BETA;Lm;0;L;<sub> 03B2;;;;N;;;;;\n1D67;GREEK SUBSCRIPT SMALL LETTER GAMMA;Lm;0;L;<sub> 03B3;;;;N;;;;;\n1D68;GREEK SUBSCRIPT SMALL LETTER RHO;Lm;0;L;<sub> 03C1;;;;N;;;;;\n1D69;GREEK SUBSCRIPT SMALL LETTER PHI;Lm;0;L;<sub> 03C6;;;;N;;;;;\n1D6A;GREEK SUBSCRIPT SMALL LETTER CHI;Lm;0;L;<sub> 03C7;;;;N;;;;;\n1D6B;LATIN SMALL LETTER UE;Ll;0;L;;;;;N;;;;;\n1D6C;LATIN SMALL LETTER B WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;\n1D6D;LATIN SMALL LETTER D WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;\n1D6E;LATIN SMALL LETTER F WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;\n1D6F;LATIN SMALL LETTER M WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;\n1D70;LATIN SMALL LETTER N WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;\n1D71;LATIN SMALL LETTER P WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;\n1D72;LATIN SMALL LETTER R WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;\n1D73;LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE;Ll;0;L;;;;;N;;;;;\n1D74;LATIN SMALL LETTER S WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;\n1D75;LATIN SMALL LETTER T WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;\n1D76;LATIN SMALL LETTER Z WITH MIDDLE TILDE;Ll;0;L;;;;;N;;;;;\n1D77;LATIN SMALL LETTER TURNED G;Ll;0;L;;;;;N;;;;;\n1D78;MODIFIER LETTER CYRILLIC EN;Lm;0;L;<super> 043D;;;;N;;;;;\n1D79;LATIN SMALL LETTER INSULAR G;Ll;0;L;;;;;N;;;A77D;;A77D\n1D7A;LATIN SMALL LETTER TH WITH STRIKETHROUGH;Ll;0;L;;;;;N;;;;;\n1D7B;LATIN SMALL CAPITAL LETTER I WITH STROKE;Ll;0;L;;;;;N;;;;;\n1D7C;LATIN SMALL LETTER IOTA WITH STROKE;Ll;0;L;;;;;N;;;;;\n1D7D;LATIN SMALL LETTER P WITH STROKE;Ll;0;L;;;;;N;;;2C63;;2C63\n1D7E;LATIN SMALL CAPITAL LETTER U WITH STROKE;Ll;0;L;;;;;N;;;;;\n1D7F;LATIN SMALL LETTER UPSILON WITH STROKE;Ll;0;L;;;;;N;;;;;\n1D80;LATIN SMALL LETTER B WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;\n1D81;LATIN SMALL LETTER D WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;\n1D82;LATIN SMALL LETTER F WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;\n1D83;LATIN SMALL LETTER G WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;\n1D84;LATIN SMALL LETTER K WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;\n1D85;LATIN SMALL LETTER L WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;\n1D86;LATIN SMALL LETTER M WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;\n1D87;LATIN SMALL LETTER N WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;\n1D88;LATIN SMALL LETTER P WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;\n1D89;LATIN SMALL LETTER R WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;\n1D8A;LATIN SMALL LETTER S WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;\n1D8B;LATIN SMALL LETTER ESH WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;\n1D8C;LATIN SMALL LETTER V WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;\n1D8D;LATIN SMALL LETTER X WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;\n1D8E;LATIN SMALL LETTER Z WITH PALATAL HOOK;Ll;0;L;;;;;N;;;A7C6;;A7C6\n1D8F;LATIN SMALL LETTER A WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;\n1D90;LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;\n1D91;LATIN SMALL LETTER D WITH HOOK AND TAIL;Ll;0;L;;;;;N;;;;;\n1D92;LATIN SMALL LETTER E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;\n1D93;LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;\n1D94;LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;\n1D95;LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;\n1D96;LATIN SMALL LETTER I WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;\n1D97;LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;\n1D98;LATIN SMALL LETTER ESH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;\n1D99;LATIN SMALL LETTER U WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;\n1D9A;LATIN SMALL LETTER EZH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;\n1D9B;MODIFIER LETTER SMALL TURNED ALPHA;Lm;0;L;<super> 0252;;;;N;;;;;\n1D9C;MODIFIER LETTER SMALL C;Lm;0;L;<super> 0063;;;;N;;;;;\n1D9D;MODIFIER LETTER SMALL C WITH CURL;Lm;0;L;<super> 0255;;;;N;;;;;\n1D9E;MODIFIER LETTER SMALL ETH;Lm;0;L;<super> 00F0;;;;N;;;;;\n1D9F;MODIFIER LETTER SMALL REVERSED OPEN E;Lm;0;L;<super> 025C;;;;N;;;;;\n1DA0;MODIFIER LETTER SMALL F;Lm;0;L;<super> 0066;;;;N;;;;;\n1DA1;MODIFIER LETTER SMALL DOTLESS J WITH STROKE;Lm;0;L;<super> 025F;;;;N;;;;;\n1DA2;MODIFIER LETTER SMALL SCRIPT G;Lm;0;L;<super> 0261;;;;N;;;;;\n1DA3;MODIFIER LETTER SMALL TURNED H;Lm;0;L;<super> 0265;;;;N;;;;;\n1DA4;MODIFIER LETTER SMALL I WITH STROKE;Lm;0;L;<super> 0268;;;;N;;;;;\n1DA5;MODIFIER LETTER SMALL IOTA;Lm;0;L;<super> 0269;;;;N;;;;;\n1DA6;MODIFIER LETTER SMALL CAPITAL I;Lm;0;L;<super> 026A;;;;N;;;;;\n1DA7;MODIFIER LETTER SMALL CAPITAL I WITH STROKE;Lm;0;L;<super> 1D7B;;;;N;;;;;\n1DA8;MODIFIER LETTER SMALL J WITH CROSSED-TAIL;Lm;0;L;<super> 029D;;;;N;;;;;\n1DA9;MODIFIER LETTER SMALL L WITH RETROFLEX HOOK;Lm;0;L;<super> 026D;;;;N;;;;;\n1DAA;MODIFIER LETTER SMALL L WITH PALATAL HOOK;Lm;0;L;<super> 1D85;;;;N;;;;;\n1DAB;MODIFIER LETTER SMALL CAPITAL L;Lm;0;L;<super> 029F;;;;N;;;;;\n1DAC;MODIFIER LETTER SMALL M WITH HOOK;Lm;0;L;<super> 0271;;;;N;;;;;\n1DAD;MODIFIER LETTER SMALL TURNED M WITH LONG LEG;Lm;0;L;<super> 0270;;;;N;;;;;\n1DAE;MODIFIER LETTER SMALL N WITH LEFT HOOK;Lm;0;L;<super> 0272;;;;N;;;;;\n1DAF;MODIFIER LETTER SMALL N WITH RETROFLEX HOOK;Lm;0;L;<super> 0273;;;;N;;;;;\n1DB0;MODIFIER LETTER SMALL CAPITAL N;Lm;0;L;<super> 0274;;;;N;;;;;\n1DB1;MODIFIER LETTER SMALL BARRED O;Lm;0;L;<super> 0275;;;;N;;;;;\n1DB2;MODIFIER LETTER SMALL PHI;Lm;0;L;<super> 0278;;;;N;;;;;\n1DB3;MODIFIER LETTER SMALL S WITH HOOK;Lm;0;L;<super> 0282;;;;N;;;;;\n1DB4;MODIFIER LETTER SMALL ESH;Lm;0;L;<super> 0283;;;;N;;;;;\n1DB5;MODIFIER LETTER SMALL T WITH PALATAL HOOK;Lm;0;L;<super> 01AB;;;;N;;;;;\n1DB6;MODIFIER LETTER SMALL U BAR;Lm;0;L;<super> 0289;;;;N;;;;;\n1DB7;MODIFIER LETTER SMALL UPSILON;Lm;0;L;<super> 028A;;;;N;;;;;\n1DB8;MODIFIER LETTER SMALL CAPITAL U;Lm;0;L;<super> 1D1C;;;;N;;;;;\n1DB9;MODIFIER LETTER SMALL V WITH HOOK;Lm;0;L;<super> 028B;;;;N;;;;;\n1DBA;MODIFIER LETTER SMALL TURNED V;Lm;0;L;<super> 028C;;;;N;;;;;\n1DBB;MODIFIER LETTER SMALL Z;Lm;0;L;<super> 007A;;;;N;;;;;\n1DBC;MODIFIER LETTER SMALL Z WITH RETROFLEX HOOK;Lm;0;L;<super> 0290;;;;N;;;;;\n1DBD;MODIFIER LETTER SMALL Z WITH CURL;Lm;0;L;<super> 0291;;;;N;;;;;\n1DBE;MODIFIER LETTER SMALL EZH;Lm;0;L;<super> 0292;;;;N;;;;;\n1DBF;MODIFIER LETTER SMALL THETA;Lm;0;L;<super> 03B8;;;;N;;;;;\n1DC0;COMBINING DOTTED GRAVE ACCENT;Mn;230;NSM;;;;;N;;;;;\n1DC1;COMBINING DOTTED ACUTE ACCENT;Mn;230;NSM;;;;;N;;;;;\n1DC2;COMBINING SNAKE BELOW;Mn;220;NSM;;;;;N;;;;;\n1DC3;COMBINING SUSPENSION MARK;Mn;230;NSM;;;;;N;;;;;\n1DC4;COMBINING MACRON-ACUTE;Mn;230;NSM;;;;;N;;;;;\n1DC5;COMBINING GRAVE-MACRON;Mn;230;NSM;;;;;N;;;;;\n1DC6;COMBINING MACRON-GRAVE;Mn;230;NSM;;;;;N;;;;;\n1DC7;COMBINING ACUTE-MACRON;Mn;230;NSM;;;;;N;;;;;\n1DC8;COMBINING GRAVE-ACUTE-GRAVE;Mn;230;NSM;;;;;N;;;;;\n1DC9;COMBINING ACUTE-GRAVE-ACUTE;Mn;230;NSM;;;;;N;;;;;\n1DCA;COMBINING LATIN SMALL LETTER R BELOW;Mn;220;NSM;;;;;N;;;;;\n1DCB;COMBINING BREVE-MACRON;Mn;230;NSM;;;;;N;;;;;\n1DCC;COMBINING MACRON-BREVE;Mn;230;NSM;;;;;N;;;;;\n1DCD;COMBINING DOUBLE CIRCUMFLEX ABOVE;Mn;234;NSM;;;;;N;;;;;\n1DCE;COMBINING OGONEK ABOVE;Mn;214;NSM;;;;;N;;;;;\n1DCF;COMBINING ZIGZAG BELOW;Mn;220;NSM;;;;;N;;;;;\n1DD0;COMBINING IS BELOW;Mn;202;NSM;;;;;N;;;;;\n1DD1;COMBINING UR ABOVE;Mn;230;NSM;;;;;N;;;;;\n1DD2;COMBINING US ABOVE;Mn;230;NSM;;;;;N;;;;;\n1DD3;COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE;Mn;230;NSM;;;;;N;;;;;\n1DD4;COMBINING LATIN SMALL LETTER AE;Mn;230;NSM;;;;;N;;;;;\n1DD5;COMBINING LATIN SMALL LETTER AO;Mn;230;NSM;;;;;N;;;;;\n1DD6;COMBINING LATIN SMALL LETTER AV;Mn;230;NSM;;;;;N;;;;;\n1DD7;COMBINING LATIN SMALL LETTER C CEDILLA;Mn;230;NSM;;;;;N;;;;;\n1DD8;COMBINING LATIN SMALL LETTER INSULAR D;Mn;230;NSM;;;;;N;;;;;\n1DD9;COMBINING LATIN SMALL LETTER ETH;Mn;230;NSM;;;;;N;;;;;\n1DDA;COMBINING LATIN SMALL LETTER G;Mn;230;NSM;;;;;N;;;;;\n1DDB;COMBINING LATIN LETTER SMALL CAPITAL G;Mn;230;NSM;;;;;N;;;;;\n1DDC;COMBINING LATIN SMALL LETTER K;Mn;230;NSM;;;;;N;;;;;\n1DDD;COMBINING LATIN SMALL LETTER L;Mn;230;NSM;;;;;N;;;;;\n1DDE;COMBINING LATIN LETTER SMALL CAPITAL L;Mn;230;NSM;;;;;N;;;;;\n1DDF;COMBINING LATIN LETTER SMALL CAPITAL M;Mn;230;NSM;;;;;N;;;;;\n1DE0;COMBINING LATIN SMALL LETTER N;Mn;230;NSM;;;;;N;;;;;\n1DE1;COMBINING LATIN LETTER SMALL CAPITAL N;Mn;230;NSM;;;;;N;;;;;\n1DE2;COMBINING LATIN LETTER SMALL CAPITAL R;Mn;230;NSM;;;;;N;;;;;\n1DE3;COMBINING LATIN SMALL LETTER R ROTUNDA;Mn;230;NSM;;;;;N;;;;;\n1DE4;COMBINING LATIN SMALL LETTER S;Mn;230;NSM;;;;;N;;;;;\n1DE5;COMBINING LATIN SMALL LETTER LONG S;Mn;230;NSM;;;;;N;;;;;\n1DE6;COMBINING LATIN SMALL LETTER Z;Mn;230;NSM;;;;;N;;;;;\n1DE7;COMBINING LATIN SMALL LETTER ALPHA;Mn;230;NSM;;;;;N;;;;;\n1DE8;COMBINING LATIN SMALL LETTER B;Mn;230;NSM;;;;;N;;;;;\n1DE9;COMBINING LATIN SMALL LETTER BETA;Mn;230;NSM;;;;;N;;;;;\n1DEA;COMBINING LATIN SMALL LETTER SCHWA;Mn;230;NSM;;;;;N;;;;;\n1DEB;COMBINING LATIN SMALL LETTER F;Mn;230;NSM;;;;;N;;;;;\n1DEC;COMBINING LATIN SMALL LETTER L WITH DOUBLE MIDDLE TILDE;Mn;230;NSM;;;;;N;;;;;\n1DED;COMBINING LATIN SMALL LETTER O WITH LIGHT CENTRALIZATION STROKE;Mn;230;NSM;;;;;N;;;;;\n1DEE;COMBINING LATIN SMALL LETTER P;Mn;230;NSM;;;;;N;;;;;\n1DEF;COMBINING LATIN SMALL LETTER ESH;Mn;230;NSM;;;;;N;;;;;\n1DF0;COMBINING LATIN SMALL LETTER U WITH LIGHT CENTRALIZATION STROKE;Mn;230;NSM;;;;;N;;;;;\n1DF1;COMBINING LATIN SMALL LETTER W;Mn;230;NSM;;;;;N;;;;;\n1DF2;COMBINING LATIN SMALL LETTER A WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;;\n1DF3;COMBINING LATIN SMALL LETTER O WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;;\n1DF4;COMBINING LATIN SMALL LETTER U WITH DIAERESIS;Mn;230;NSM;;;;;N;;;;;\n1DF5;COMBINING UP TACK ABOVE;Mn;230;NSM;;;;;N;;;;;\n1DF6;COMBINING KAVYKA ABOVE RIGHT;Mn;232;NSM;;;;;N;;;;;\n1DF7;COMBINING KAVYKA ABOVE LEFT;Mn;228;NSM;;;;;N;;;;;\n1DF8;COMBINING DOT ABOVE LEFT;Mn;228;NSM;;;;;N;;;;;\n1DF9;COMBINING WIDE INVERTED BRIDGE BELOW;Mn;220;NSM;;;;;N;;;;;\n1DFB;COMBINING DELETION MARK;Mn;230;NSM;;;;;N;;;;;\n1DFC;COMBINING DOUBLE INVERTED BREVE BELOW;Mn;233;NSM;;;;;N;;;;;\n1DFD;COMBINING ALMOST EQUAL TO BELOW;Mn;220;NSM;;;;;N;;;;;\n1DFE;COMBINING LEFT ARROWHEAD ABOVE;Mn;230;NSM;;;;;N;;;;;\n1DFF;COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW;Mn;220;NSM;;;;;N;;;;;\n1E00;LATIN CAPITAL LETTER A WITH RING BELOW;Lu;0;L;0041 0325;;;;N;;;;1E01;\n1E01;LATIN SMALL LETTER A WITH RING BELOW;Ll;0;L;0061 0325;;;;N;;;1E00;;1E00\n1E02;LATIN CAPITAL LETTER B WITH DOT ABOVE;Lu;0;L;0042 0307;;;;N;;;;1E03;\n1E03;LATIN SMALL LETTER B WITH DOT ABOVE;Ll;0;L;0062 0307;;;;N;;;1E02;;1E02\n1E04;LATIN CAPITAL LETTER B WITH DOT BELOW;Lu;0;L;0042 0323;;;;N;;;;1E05;\n1E05;LATIN SMALL LETTER B WITH DOT BELOW;Ll;0;L;0062 0323;;;;N;;;1E04;;1E04\n1E06;LATIN CAPITAL LETTER B WITH LINE BELOW;Lu;0;L;0042 0331;;;;N;;;;1E07;\n1E07;LATIN SMALL LETTER B WITH LINE BELOW;Ll;0;L;0062 0331;;;;N;;;1E06;;1E06\n1E08;LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE;Lu;0;L;00C7 0301;;;;N;;;;1E09;\n1E09;LATIN SMALL LETTER C WITH CEDILLA AND ACUTE;Ll;0;L;00E7 0301;;;;N;;;1E08;;1E08\n1E0A;LATIN CAPITAL LETTER D WITH DOT ABOVE;Lu;0;L;0044 0307;;;;N;;;;1E0B;\n1E0B;LATIN SMALL LETTER D WITH DOT ABOVE;Ll;0;L;0064 0307;;;;N;;;1E0A;;1E0A\n1E0C;LATIN CAPITAL LETTER D WITH DOT BELOW;Lu;0;L;0044 0323;;;;N;;;;1E0D;\n1E0D;LATIN SMALL LETTER D WITH DOT BELOW;Ll;0;L;0064 0323;;;;N;;;1E0C;;1E0C\n1E0E;LATIN CAPITAL LETTER D WITH LINE BELOW;Lu;0;L;0044 0331;;;;N;;;;1E0F;\n1E0F;LATIN SMALL LETTER D WITH LINE BELOW;Ll;0;L;0064 0331;;;;N;;;1E0E;;1E0E\n1E10;LATIN CAPITAL LETTER D WITH CEDILLA;Lu;0;L;0044 0327;;;;N;;;;1E11;\n1E11;LATIN SMALL LETTER D WITH CEDILLA;Ll;0;L;0064 0327;;;;N;;;1E10;;1E10\n1E12;LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW;Lu;0;L;0044 032D;;;;N;;;;1E13;\n1E13;LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW;Ll;0;L;0064 032D;;;;N;;;1E12;;1E12\n1E14;LATIN CAPITAL LETTER E WITH MACRON AND GRAVE;Lu;0;L;0112 0300;;;;N;;;;1E15;\n1E15;LATIN SMALL LETTER E WITH MACRON AND GRAVE;Ll;0;L;0113 0300;;;;N;;;1E14;;1E14\n1E16;LATIN CAPITAL LETTER E WITH MACRON AND ACUTE;Lu;0;L;0112 0301;;;;N;;;;1E17;\n1E17;LATIN SMALL LETTER E WITH MACRON AND ACUTE;Ll;0;L;0113 0301;;;;N;;;1E16;;1E16\n1E18;LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW;Lu;0;L;0045 032D;;;;N;;;;1E19;\n1E19;LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW;Ll;0;L;0065 032D;;;;N;;;1E18;;1E18\n1E1A;LATIN CAPITAL LETTER E WITH TILDE BELOW;Lu;0;L;0045 0330;;;;N;;;;1E1B;\n1E1B;LATIN SMALL LETTER E WITH TILDE BELOW;Ll;0;L;0065 0330;;;;N;;;1E1A;;1E1A\n1E1C;LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE;Lu;0;L;0228 0306;;;;N;;;;1E1D;\n1E1D;LATIN SMALL LETTER E WITH CEDILLA AND BREVE;Ll;0;L;0229 0306;;;;N;;;1E1C;;1E1C\n1E1E;LATIN CAPITAL LETTER F WITH DOT ABOVE;Lu;0;L;0046 0307;;;;N;;;;1E1F;\n1E1F;LATIN SMALL LETTER F WITH DOT ABOVE;Ll;0;L;0066 0307;;;;N;;;1E1E;;1E1E\n1E20;LATIN CAPITAL LETTER G WITH MACRON;Lu;0;L;0047 0304;;;;N;;;;1E21;\n1E21;LATIN SMALL LETTER G WITH MACRON;Ll;0;L;0067 0304;;;;N;;;1E20;;1E20\n1E22;LATIN CAPITAL LETTER H WITH DOT ABOVE;Lu;0;L;0048 0307;;;;N;;;;1E23;\n1E23;LATIN SMALL LETTER H WITH DOT ABOVE;Ll;0;L;0068 0307;;;;N;;;1E22;;1E22\n1E24;LATIN CAPITAL LETTER H WITH DOT BELOW;Lu;0;L;0048 0323;;;;N;;;;1E25;\n1E25;LATIN SMALL LETTER H WITH DOT BELOW;Ll;0;L;0068 0323;;;;N;;;1E24;;1E24\n1E26;LATIN CAPITAL LETTER H WITH DIAERESIS;Lu;0;L;0048 0308;;;;N;;;;1E27;\n1E27;LATIN SMALL LETTER H WITH DIAERESIS;Ll;0;L;0068 0308;;;;N;;;1E26;;1E26\n1E28;LATIN CAPITAL LETTER H WITH CEDILLA;Lu;0;L;0048 0327;;;;N;;;;1E29;\n1E29;LATIN SMALL LETTER H WITH CEDILLA;Ll;0;L;0068 0327;;;;N;;;1E28;;1E28\n1E2A;LATIN CAPITAL LETTER H WITH BREVE BELOW;Lu;0;L;0048 032E;;;;N;;;;1E2B;\n1E2B;LATIN SMALL LETTER H WITH BREVE BELOW;Ll;0;L;0068 032E;;;;N;;;1E2A;;1E2A\n1E2C;LATIN CAPITAL LETTER I WITH TILDE BELOW;Lu;0;L;0049 0330;;;;N;;;;1E2D;\n1E2D;LATIN SMALL LETTER I WITH TILDE BELOW;Ll;0;L;0069 0330;;;;N;;;1E2C;;1E2C\n1E2E;LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE;Lu;0;L;00CF 0301;;;;N;;;;1E2F;\n1E2F;LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE;Ll;0;L;00EF 0301;;;;N;;;1E2E;;1E2E\n1E30;LATIN CAPITAL LETTER K WITH ACUTE;Lu;0;L;004B 0301;;;;N;;;;1E31;\n1E31;LATIN SMALL LETTER K WITH ACUTE;Ll;0;L;006B 0301;;;;N;;;1E30;;1E30\n1E32;LATIN CAPITAL LETTER K WITH DOT BELOW;Lu;0;L;004B 0323;;;;N;;;;1E33;\n1E33;LATIN SMALL LETTER K WITH DOT BELOW;Ll;0;L;006B 0323;;;;N;;;1E32;;1E32\n1E34;LATIN CAPITAL LETTER K WITH LINE BELOW;Lu;0;L;004B 0331;;;;N;;;;1E35;\n1E35;LATIN SMALL LETTER K WITH LINE BELOW;Ll;0;L;006B 0331;;;;N;;;1E34;;1E34\n1E36;LATIN CAPITAL LETTER L WITH DOT BELOW;Lu;0;L;004C 0323;;;;N;;;;1E37;\n1E37;LATIN SMALL LETTER L WITH DOT BELOW;Ll;0;L;006C 0323;;;;N;;;1E36;;1E36\n1E38;LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON;Lu;0;L;1E36 0304;;;;N;;;;1E39;\n1E39;LATIN SMALL LETTER L WITH DOT BELOW AND MACRON;Ll;0;L;1E37 0304;;;;N;;;1E38;;1E38\n1E3A;LATIN CAPITAL LETTER L WITH LINE BELOW;Lu;0;L;004C 0331;;;;N;;;;1E3B;\n1E3B;LATIN SMALL LETTER L WITH LINE BELOW;Ll;0;L;006C 0331;;;;N;;;1E3A;;1E3A\n1E3C;LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW;Lu;0;L;004C 032D;;;;N;;;;1E3D;\n1E3D;LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW;Ll;0;L;006C 032D;;;;N;;;1E3C;;1E3C\n1E3E;LATIN CAPITAL LETTER M WITH ACUTE;Lu;0;L;004D 0301;;;;N;;;;1E3F;\n1E3F;LATIN SMALL LETTER M WITH ACUTE;Ll;0;L;006D 0301;;;;N;;;1E3E;;1E3E\n1E40;LATIN CAPITAL LETTER M WITH DOT ABOVE;Lu;0;L;004D 0307;;;;N;;;;1E41;\n1E41;LATIN SMALL LETTER M WITH DOT ABOVE;Ll;0;L;006D 0307;;;;N;;;1E40;;1E40\n1E42;LATIN CAPITAL LETTER M WITH DOT BELOW;Lu;0;L;004D 0323;;;;N;;;;1E43;\n1E43;LATIN SMALL LETTER M WITH DOT BELOW;Ll;0;L;006D 0323;;;;N;;;1E42;;1E42\n1E44;LATIN CAPITAL LETTER N WITH DOT ABOVE;Lu;0;L;004E 0307;;;;N;;;;1E45;\n1E45;LATIN SMALL LETTER N WITH DOT ABOVE;Ll;0;L;006E 0307;;;;N;;;1E44;;1E44\n1E46;LATIN CAPITAL LETTER N WITH DOT BELOW;Lu;0;L;004E 0323;;;;N;;;;1E47;\n1E47;LATIN SMALL LETTER N WITH DOT BELOW;Ll;0;L;006E 0323;;;;N;;;1E46;;1E46\n1E48;LATIN CAPITAL LETTER N WITH LINE BELOW;Lu;0;L;004E 0331;;;;N;;;;1E49;\n1E49;LATIN SMALL LETTER N WITH LINE BELOW;Ll;0;L;006E 0331;;;;N;;;1E48;;1E48\n1E4A;LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW;Lu;0;L;004E 032D;;;;N;;;;1E4B;\n1E4B;LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW;Ll;0;L;006E 032D;;;;N;;;1E4A;;1E4A\n1E4C;LATIN CAPITAL LETTER O WITH TILDE AND ACUTE;Lu;0;L;00D5 0301;;;;N;;;;1E4D;\n1E4D;LATIN SMALL LETTER O WITH TILDE AND ACUTE;Ll;0;L;00F5 0301;;;;N;;;1E4C;;1E4C\n1E4E;LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS;Lu;0;L;00D5 0308;;;;N;;;;1E4F;\n1E4F;LATIN SMALL LETTER O WITH TILDE AND DIAERESIS;Ll;0;L;00F5 0308;;;;N;;;1E4E;;1E4E\n1E50;LATIN CAPITAL LETTER O WITH MACRON AND GRAVE;Lu;0;L;014C 0300;;;;N;;;;1E51;\n1E51;LATIN SMALL LETTER O WITH MACRON AND GRAVE;Ll;0;L;014D 0300;;;;N;;;1E50;;1E50\n1E52;LATIN CAPITAL LETTER O WITH MACRON AND ACUTE;Lu;0;L;014C 0301;;;;N;;;;1E53;\n1E53;LATIN SMALL LETTER O WITH MACRON AND ACUTE;Ll;0;L;014D 0301;;;;N;;;1E52;;1E52\n1E54;LATIN CAPITAL LETTER P WITH ACUTE;Lu;0;L;0050 0301;;;;N;;;;1E55;\n1E55;LATIN SMALL LETTER P WITH ACUTE;Ll;0;L;0070 0301;;;;N;;;1E54;;1E54\n1E56;LATIN CAPITAL LETTER P WITH DOT ABOVE;Lu;0;L;0050 0307;;;;N;;;;1E57;\n1E57;LATIN SMALL LETTER P WITH DOT ABOVE;Ll;0;L;0070 0307;;;;N;;;1E56;;1E56\n1E58;LATIN CAPITAL LETTER R WITH DOT ABOVE;Lu;0;L;0052 0307;;;;N;;;;1E59;\n1E59;LATIN SMALL LETTER R WITH DOT ABOVE;Ll;0;L;0072 0307;;;;N;;;1E58;;1E58\n1E5A;LATIN CAPITAL LETTER R WITH DOT BELOW;Lu;0;L;0052 0323;;;;N;;;;1E5B;\n1E5B;LATIN SMALL LETTER R WITH DOT BELOW;Ll;0;L;0072 0323;;;;N;;;1E5A;;1E5A\n1E5C;LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON;Lu;0;L;1E5A 0304;;;;N;;;;1E5D;\n1E5D;LATIN SMALL LETTER R WITH DOT BELOW AND MACRON;Ll;0;L;1E5B 0304;;;;N;;;1E5C;;1E5C\n1E5E;LATIN CAPITAL LETTER R WITH LINE BELOW;Lu;0;L;0052 0331;;;;N;;;;1E5F;\n1E5F;LATIN SMALL LETTER R WITH LINE BELOW;Ll;0;L;0072 0331;;;;N;;;1E5E;;1E5E\n1E60;LATIN CAPITAL LETTER S WITH DOT ABOVE;Lu;0;L;0053 0307;;;;N;;;;1E61;\n1E61;LATIN SMALL LETTER S WITH DOT ABOVE;Ll;0;L;0073 0307;;;;N;;;1E60;;1E60\n1E62;LATIN CAPITAL LETTER S WITH DOT BELOW;Lu;0;L;0053 0323;;;;N;;;;1E63;\n1E63;LATIN SMALL LETTER S WITH DOT BELOW;Ll;0;L;0073 0323;;;;N;;;1E62;;1E62\n1E64;LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE;Lu;0;L;015A 0307;;;;N;;;;1E65;\n1E65;LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE;Ll;0;L;015B 0307;;;;N;;;1E64;;1E64\n1E66;LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE;Lu;0;L;0160 0307;;;;N;;;;1E67;\n1E67;LATIN SMALL LETTER S WITH CARON AND DOT ABOVE;Ll;0;L;0161 0307;;;;N;;;1E66;;1E66\n1E68;LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE;Lu;0;L;1E62 0307;;;;N;;;;1E69;\n1E69;LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE;Ll;0;L;1E63 0307;;;;N;;;1E68;;1E68\n1E6A;LATIN CAPITAL LETTER T WITH DOT ABOVE;Lu;0;L;0054 0307;;;;N;;;;1E6B;\n1E6B;LATIN SMALL LETTER T WITH DOT ABOVE;Ll;0;L;0074 0307;;;;N;;;1E6A;;1E6A\n1E6C;LATIN CAPITAL LETTER T WITH DOT BELOW;Lu;0;L;0054 0323;;;;N;;;;1E6D;\n1E6D;LATIN SMALL LETTER T WITH DOT BELOW;Ll;0;L;0074 0323;;;;N;;;1E6C;;1E6C\n1E6E;LATIN CAPITAL LETTER T WITH LINE BELOW;Lu;0;L;0054 0331;;;;N;;;;1E6F;\n1E6F;LATIN SMALL LETTER T WITH LINE BELOW;Ll;0;L;0074 0331;;;;N;;;1E6E;;1E6E\n1E70;LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW;Lu;0;L;0054 032D;;;;N;;;;1E71;\n1E71;LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW;Ll;0;L;0074 032D;;;;N;;;1E70;;1E70\n1E72;LATIN CAPITAL LETTER U WITH DIAERESIS BELOW;Lu;0;L;0055 0324;;;;N;;;;1E73;\n1E73;LATIN SMALL LETTER U WITH DIAERESIS BELOW;Ll;0;L;0075 0324;;;;N;;;1E72;;1E72\n1E74;LATIN CAPITAL LETTER U WITH TILDE BELOW;Lu;0;L;0055 0330;;;;N;;;;1E75;\n1E75;LATIN SMALL LETTER U WITH TILDE BELOW;Ll;0;L;0075 0330;;;;N;;;1E74;;1E74\n1E76;LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW;Lu;0;L;0055 032D;;;;N;;;;1E77;\n1E77;LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW;Ll;0;L;0075 032D;;;;N;;;1E76;;1E76\n1E78;LATIN CAPITAL LETTER U WITH TILDE AND ACUTE;Lu;0;L;0168 0301;;;;N;;;;1E79;\n1E79;LATIN SMALL LETTER U WITH TILDE AND ACUTE;Ll;0;L;0169 0301;;;;N;;;1E78;;1E78\n1E7A;LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS;Lu;0;L;016A 0308;;;;N;;;;1E7B;\n1E7B;LATIN SMALL LETTER U WITH MACRON AND DIAERESIS;Ll;0;L;016B 0308;;;;N;;;1E7A;;1E7A\n1E7C;LATIN CAPITAL LETTER V WITH TILDE;Lu;0;L;0056 0303;;;;N;;;;1E7D;\n1E7D;LATIN SMALL LETTER V WITH TILDE;Ll;0;L;0076 0303;;;;N;;;1E7C;;1E7C\n1E7E;LATIN CAPITAL LETTER V WITH DOT BELOW;Lu;0;L;0056 0323;;;;N;;;;1E7F;\n1E7F;LATIN SMALL LETTER V WITH DOT BELOW;Ll;0;L;0076 0323;;;;N;;;1E7E;;1E7E\n1E80;LATIN CAPITAL LETTER W WITH GRAVE;Lu;0;L;0057 0300;;;;N;;;;1E81;\n1E81;LATIN SMALL LETTER W WITH GRAVE;Ll;0;L;0077 0300;;;;N;;;1E80;;1E80\n1E82;LATIN CAPITAL LETTER W WITH ACUTE;Lu;0;L;0057 0301;;;;N;;;;1E83;\n1E83;LATIN SMALL LETTER W WITH ACUTE;Ll;0;L;0077 0301;;;;N;;;1E82;;1E82\n1E84;LATIN CAPITAL LETTER W WITH DIAERESIS;Lu;0;L;0057 0308;;;;N;;;;1E85;\n1E85;LATIN SMALL LETTER W WITH DIAERESIS;Ll;0;L;0077 0308;;;;N;;;1E84;;1E84\n1E86;LATIN CAPITAL LETTER W WITH DOT ABOVE;Lu;0;L;0057 0307;;;;N;;;;1E87;\n1E87;LATIN SMALL LETTER W WITH DOT ABOVE;Ll;0;L;0077 0307;;;;N;;;1E86;;1E86\n1E88;LATIN CAPITAL LETTER W WITH DOT BELOW;Lu;0;L;0057 0323;;;;N;;;;1E89;\n1E89;LATIN SMALL LETTER W WITH DOT BELOW;Ll;0;L;0077 0323;;;;N;;;1E88;;1E88\n1E8A;LATIN CAPITAL LETTER X WITH DOT ABOVE;Lu;0;L;0058 0307;;;;N;;;;1E8B;\n1E8B;LATIN SMALL LETTER X WITH DOT ABOVE;Ll;0;L;0078 0307;;;;N;;;1E8A;;1E8A\n1E8C;LATIN CAPITAL LETTER X WITH DIAERESIS;Lu;0;L;0058 0308;;;;N;;;;1E8D;\n1E8D;LATIN SMALL LETTER X WITH DIAERESIS;Ll;0;L;0078 0308;;;;N;;;1E8C;;1E8C\n1E8E;LATIN CAPITAL LETTER Y WITH DOT ABOVE;Lu;0;L;0059 0307;;;;N;;;;1E8F;\n1E8F;LATIN SMALL LETTER Y WITH DOT ABOVE;Ll;0;L;0079 0307;;;;N;;;1E8E;;1E8E\n1E90;LATIN CAPITAL LETTER Z WITH CIRCUMFLEX;Lu;0;L;005A 0302;;;;N;;;;1E91;\n1E91;LATIN SMALL LETTER Z WITH CIRCUMFLEX;Ll;0;L;007A 0302;;;;N;;;1E90;;1E90\n1E92;LATIN CAPITAL LETTER Z WITH DOT BELOW;Lu;0;L;005A 0323;;;;N;;;;1E93;\n1E93;LATIN SMALL LETTER Z WITH DOT BELOW;Ll;0;L;007A 0323;;;;N;;;1E92;;1E92\n1E94;LATIN CAPITAL LETTER Z WITH LINE BELOW;Lu;0;L;005A 0331;;;;N;;;;1E95;\n1E95;LATIN SMALL LETTER Z WITH LINE BELOW;Ll;0;L;007A 0331;;;;N;;;1E94;;1E94\n1E96;LATIN SMALL LETTER H WITH LINE BELOW;Ll;0;L;0068 0331;;;;N;;;;;\n1E97;LATIN SMALL LETTER T WITH DIAERESIS;Ll;0;L;0074 0308;;;;N;;;;;\n1E98;LATIN SMALL LETTER W WITH RING ABOVE;Ll;0;L;0077 030A;;;;N;;;;;\n1E99;LATIN SMALL LETTER Y WITH RING ABOVE;Ll;0;L;0079 030A;;;;N;;;;;\n1E9A;LATIN SMALL LETTER A WITH RIGHT HALF RING;Ll;0;L;<compat> 0061 02BE;;;;N;;;;;\n1E9B;LATIN SMALL LETTER LONG S WITH DOT ABOVE;Ll;0;L;017F 0307;;;;N;;;1E60;;1E60\n1E9C;LATIN SMALL LETTER LONG S WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;;;\n1E9D;LATIN SMALL LETTER LONG S WITH HIGH STROKE;Ll;0;L;;;;;N;;;;;\n1E9E;LATIN CAPITAL LETTER SHARP S;Lu;0;L;;;;;N;;;;00DF;\n1E9F;LATIN SMALL LETTER DELTA;Ll;0;L;;;;;N;;;;;\n1EA0;LATIN CAPITAL LETTER A WITH DOT BELOW;Lu;0;L;0041 0323;;;;N;;;;1EA1;\n1EA1;LATIN SMALL LETTER A WITH DOT BELOW;Ll;0;L;0061 0323;;;;N;;;1EA0;;1EA0\n1EA2;LATIN CAPITAL LETTER A WITH HOOK ABOVE;Lu;0;L;0041 0309;;;;N;;;;1EA3;\n1EA3;LATIN SMALL LETTER A WITH HOOK ABOVE;Ll;0;L;0061 0309;;;;N;;;1EA2;;1EA2\n1EA4;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00C2 0301;;;;N;;;;1EA5;\n1EA5;LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00E2 0301;;;;N;;;1EA4;;1EA4\n1EA6;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00C2 0300;;;;N;;;;1EA7;\n1EA7;LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00E2 0300;;;;N;;;1EA6;;1EA6\n1EA8;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00C2 0309;;;;N;;;;1EA9;\n1EA9;LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00E2 0309;;;;N;;;1EA8;;1EA8\n1EAA;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE;Lu;0;L;00C2 0303;;;;N;;;;1EAB;\n1EAB;LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE;Ll;0;L;00E2 0303;;;;N;;;1EAA;;1EAA\n1EAC;LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EA0 0302;;;;N;;;;1EAD;\n1EAD;LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EA1 0302;;;;N;;;1EAC;;1EAC\n1EAE;LATIN CAPITAL LETTER A WITH BREVE AND ACUTE;Lu;0;L;0102 0301;;;;N;;;;1EAF;\n1EAF;LATIN SMALL LETTER A WITH BREVE AND ACUTE;Ll;0;L;0103 0301;;;;N;;;1EAE;;1EAE\n1EB0;LATIN CAPITAL LETTER A WITH BREVE AND GRAVE;Lu;0;L;0102 0300;;;;N;;;;1EB1;\n1EB1;LATIN SMALL LETTER A WITH BREVE AND GRAVE;Ll;0;L;0103 0300;;;;N;;;1EB0;;1EB0\n1EB2;LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE;Lu;0;L;0102 0309;;;;N;;;;1EB3;\n1EB3;LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE;Ll;0;L;0103 0309;;;;N;;;1EB2;;1EB2\n1EB4;LATIN CAPITAL LETTER A WITH BREVE AND TILDE;Lu;0;L;0102 0303;;;;N;;;;1EB5;\n1EB5;LATIN SMALL LETTER A WITH BREVE AND TILDE;Ll;0;L;0103 0303;;;;N;;;1EB4;;1EB4\n1EB6;LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW;Lu;0;L;1EA0 0306;;;;N;;;;1EB7;\n1EB7;LATIN SMALL LETTER A WITH BREVE AND DOT BELOW;Ll;0;L;1EA1 0306;;;;N;;;1EB6;;1EB6\n1EB8;LATIN CAPITAL LETTER E WITH DOT BELOW;Lu;0;L;0045 0323;;;;N;;;;1EB9;\n1EB9;LATIN SMALL LETTER E WITH DOT BELOW;Ll;0;L;0065 0323;;;;N;;;1EB8;;1EB8\n1EBA;LATIN CAPITAL LETTER E WITH HOOK ABOVE;Lu;0;L;0045 0309;;;;N;;;;1EBB;\n1EBB;LATIN SMALL LETTER E WITH HOOK ABOVE;Ll;0;L;0065 0309;;;;N;;;1EBA;;1EBA\n1EBC;LATIN CAPITAL LETTER E WITH TILDE;Lu;0;L;0045 0303;;;;N;;;;1EBD;\n1EBD;LATIN SMALL LETTER E WITH TILDE;Ll;0;L;0065 0303;;;;N;;;1EBC;;1EBC\n1EBE;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00CA 0301;;;;N;;;;1EBF;\n1EBF;LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00EA 0301;;;;N;;;1EBE;;1EBE\n1EC0;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00CA 0300;;;;N;;;;1EC1;\n1EC1;LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00EA 0300;;;;N;;;1EC0;;1EC0\n1EC2;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00CA 0309;;;;N;;;;1EC3;\n1EC3;LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00EA 0309;;;;N;;;1EC2;;1EC2\n1EC4;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE;Lu;0;L;00CA 0303;;;;N;;;;1EC5;\n1EC5;LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE;Ll;0;L;00EA 0303;;;;N;;;1EC4;;1EC4\n1EC6;LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1EB8 0302;;;;N;;;;1EC7;\n1EC7;LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1EB9 0302;;;;N;;;1EC6;;1EC6\n1EC8;LATIN CAPITAL LETTER I WITH HOOK ABOVE;Lu;0;L;0049 0309;;;;N;;;;1EC9;\n1EC9;LATIN SMALL LETTER I WITH HOOK ABOVE;Ll;0;L;0069 0309;;;;N;;;1EC8;;1EC8\n1ECA;LATIN CAPITAL LETTER I WITH DOT BELOW;Lu;0;L;0049 0323;;;;N;;;;1ECB;\n1ECB;LATIN SMALL LETTER I WITH DOT BELOW;Ll;0;L;0069 0323;;;;N;;;1ECA;;1ECA\n1ECC;LATIN CAPITAL LETTER O WITH DOT BELOW;Lu;0;L;004F 0323;;;;N;;;;1ECD;\n1ECD;LATIN SMALL LETTER O WITH DOT BELOW;Ll;0;L;006F 0323;;;;N;;;1ECC;;1ECC\n1ECE;LATIN CAPITAL LETTER O WITH HOOK ABOVE;Lu;0;L;004F 0309;;;;N;;;;1ECF;\n1ECF;LATIN SMALL LETTER O WITH HOOK ABOVE;Ll;0;L;006F 0309;;;;N;;;1ECE;;1ECE\n1ED0;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE;Lu;0;L;00D4 0301;;;;N;;;;1ED1;\n1ED1;LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE;Ll;0;L;00F4 0301;;;;N;;;1ED0;;1ED0\n1ED2;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE;Lu;0;L;00D4 0300;;;;N;;;;1ED3;\n1ED3;LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE;Ll;0;L;00F4 0300;;;;N;;;1ED2;;1ED2\n1ED4;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Lu;0;L;00D4 0309;;;;N;;;;1ED5;\n1ED5;LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE;Ll;0;L;00F4 0309;;;;N;;;1ED4;;1ED4\n1ED6;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE;Lu;0;L;00D4 0303;;;;N;;;;1ED7;\n1ED7;LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE;Ll;0;L;00F4 0303;;;;N;;;1ED6;;1ED6\n1ED8;LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Lu;0;L;1ECC 0302;;;;N;;;;1ED9;\n1ED9;LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW;Ll;0;L;1ECD 0302;;;;N;;;1ED8;;1ED8\n1EDA;LATIN CAPITAL LETTER O WITH HORN AND ACUTE;Lu;0;L;01A0 0301;;;;N;;;;1EDB;\n1EDB;LATIN SMALL LETTER O WITH HORN AND ACUTE;Ll;0;L;01A1 0301;;;;N;;;1EDA;;1EDA\n1EDC;LATIN CAPITAL LETTER O WITH HORN AND GRAVE;Lu;0;L;01A0 0300;;;;N;;;;1EDD;\n1EDD;LATIN SMALL LETTER O WITH HORN AND GRAVE;Ll;0;L;01A1 0300;;;;N;;;1EDC;;1EDC\n1EDE;LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE;Lu;0;L;01A0 0309;;;;N;;;;1EDF;\n1EDF;LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE;Ll;0;L;01A1 0309;;;;N;;;1EDE;;1EDE\n1EE0;LATIN CAPITAL LETTER O WITH HORN AND TILDE;Lu;0;L;01A0 0303;;;;N;;;;1EE1;\n1EE1;LATIN SMALL LETTER O WITH HORN AND TILDE;Ll;0;L;01A1 0303;;;;N;;;1EE0;;1EE0\n1EE2;LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW;Lu;0;L;01A0 0323;;;;N;;;;1EE3;\n1EE3;LATIN SMALL LETTER O WITH HORN AND DOT BELOW;Ll;0;L;01A1 0323;;;;N;;;1EE2;;1EE2\n1EE4;LATIN CAPITAL LETTER U WITH DOT BELOW;Lu;0;L;0055 0323;;;;N;;;;1EE5;\n1EE5;LATIN SMALL LETTER U WITH DOT BELOW;Ll;0;L;0075 0323;;;;N;;;1EE4;;1EE4\n1EE6;LATIN CAPITAL LETTER U WITH HOOK ABOVE;Lu;0;L;0055 0309;;;;N;;;;1EE7;\n1EE7;LATIN SMALL LETTER U WITH HOOK ABOVE;Ll;0;L;0075 0309;;;;N;;;1EE6;;1EE6\n1EE8;LATIN CAPITAL LETTER U WITH HORN AND ACUTE;Lu;0;L;01AF 0301;;;;N;;;;1EE9;\n1EE9;LATIN SMALL LETTER U WITH HORN AND ACUTE;Ll;0;L;01B0 0301;;;;N;;;1EE8;;1EE8\n1EEA;LATIN CAPITAL LETTER U WITH HORN AND GRAVE;Lu;0;L;01AF 0300;;;;N;;;;1EEB;\n1EEB;LATIN SMALL LETTER U WITH HORN AND GRAVE;Ll;0;L;01B0 0300;;;;N;;;1EEA;;1EEA\n1EEC;LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE;Lu;0;L;01AF 0309;;;;N;;;;1EED;\n1EED;LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE;Ll;0;L;01B0 0309;;;;N;;;1EEC;;1EEC\n1EEE;LATIN CAPITAL LETTER U WITH HORN AND TILDE;Lu;0;L;01AF 0303;;;;N;;;;1EEF;\n1EEF;LATIN SMALL LETTER U WITH HORN AND TILDE;Ll;0;L;01B0 0303;;;;N;;;1EEE;;1EEE\n1EF0;LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW;Lu;0;L;01AF 0323;;;;N;;;;1EF1;\n1EF1;LATIN SMALL LETTER U WITH HORN AND DOT BELOW;Ll;0;L;01B0 0323;;;;N;;;1EF0;;1EF0\n1EF2;LATIN CAPITAL LETTER Y WITH GRAVE;Lu;0;L;0059 0300;;;;N;;;;1EF3;\n1EF3;LATIN SMALL LETTER Y WITH GRAVE;Ll;0;L;0079 0300;;;;N;;;1EF2;;1EF2\n1EF4;LATIN CAPITAL LETTER Y WITH DOT BELOW;Lu;0;L;0059 0323;;;;N;;;;1EF5;\n1EF5;LATIN SMALL LETTER Y WITH DOT BELOW;Ll;0;L;0079 0323;;;;N;;;1EF4;;1EF4\n1EF6;LATIN CAPITAL LETTER Y WITH HOOK ABOVE;Lu;0;L;0059 0309;;;;N;;;;1EF7;\n1EF7;LATIN SMALL LETTER Y WITH HOOK ABOVE;Ll;0;L;0079 0309;;;;N;;;1EF6;;1EF6\n1EF8;LATIN CAPITAL LETTER Y WITH TILDE;Lu;0;L;0059 0303;;;;N;;;;1EF9;\n1EF9;LATIN SMALL LETTER Y WITH TILDE;Ll;0;L;0079 0303;;;;N;;;1EF8;;1EF8\n1EFA;LATIN CAPITAL LETTER MIDDLE-WELSH LL;Lu;0;L;;;;;N;;;;1EFB;\n1EFB;LATIN SMALL LETTER MIDDLE-WELSH LL;Ll;0;L;;;;;N;;;1EFA;;1EFA\n1EFC;LATIN CAPITAL LETTER MIDDLE-WELSH V;Lu;0;L;;;;;N;;;;1EFD;\n1EFD;LATIN SMALL LETTER MIDDLE-WELSH V;Ll;0;L;;;;;N;;;1EFC;;1EFC\n1EFE;LATIN CAPITAL LETTER Y WITH LOOP;Lu;0;L;;;;;N;;;;1EFF;\n1EFF;LATIN SMALL LETTER Y WITH LOOP;Ll;0;L;;;;;N;;;1EFE;;1EFE\n1F00;GREEK SMALL LETTER ALPHA WITH PSILI;Ll;0;L;03B1 0313;;;;N;;;1F08;;1F08\n1F01;GREEK SMALL LETTER ALPHA WITH DASIA;Ll;0;L;03B1 0314;;;;N;;;1F09;;1F09\n1F02;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA;Ll;0;L;1F00 0300;;;;N;;;1F0A;;1F0A\n1F03;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA;Ll;0;L;1F01 0300;;;;N;;;1F0B;;1F0B\n1F04;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA;Ll;0;L;1F00 0301;;;;N;;;1F0C;;1F0C\n1F05;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA;Ll;0;L;1F01 0301;;;;N;;;1F0D;;1F0D\n1F06;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI;Ll;0;L;1F00 0342;;;;N;;;1F0E;;1F0E\n1F07;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI;Ll;0;L;1F01 0342;;;;N;;;1F0F;;1F0F\n1F08;GREEK CAPITAL LETTER ALPHA WITH PSILI;Lu;0;L;0391 0313;;;;N;;;;1F00;\n1F09;GREEK CAPITAL LETTER ALPHA WITH DASIA;Lu;0;L;0391 0314;;;;N;;;;1F01;\n1F0A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA;Lu;0;L;1F08 0300;;;;N;;;;1F02;\n1F0B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA;Lu;0;L;1F09 0300;;;;N;;;;1F03;\n1F0C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA;Lu;0;L;1F08 0301;;;;N;;;;1F04;\n1F0D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA;Lu;0;L;1F09 0301;;;;N;;;;1F05;\n1F0E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI;Lu;0;L;1F08 0342;;;;N;;;;1F06;\n1F0F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI;Lu;0;L;1F09 0342;;;;N;;;;1F07;\n1F10;GREEK SMALL LETTER EPSILON WITH PSILI;Ll;0;L;03B5 0313;;;;N;;;1F18;;1F18\n1F11;GREEK SMALL LETTER EPSILON WITH DASIA;Ll;0;L;03B5 0314;;;;N;;;1F19;;1F19\n1F12;GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA;Ll;0;L;1F10 0300;;;;N;;;1F1A;;1F1A\n1F13;GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA;Ll;0;L;1F11 0300;;;;N;;;1F1B;;1F1B\n1F14;GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA;Ll;0;L;1F10 0301;;;;N;;;1F1C;;1F1C\n1F15;GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA;Ll;0;L;1F11 0301;;;;N;;;1F1D;;1F1D\n1F18;GREEK CAPITAL LETTER EPSILON WITH PSILI;Lu;0;L;0395 0313;;;;N;;;;1F10;\n1F19;GREEK CAPITAL LETTER EPSILON WITH DASIA;Lu;0;L;0395 0314;;;;N;;;;1F11;\n1F1A;GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA;Lu;0;L;1F18 0300;;;;N;;;;1F12;\n1F1B;GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA;Lu;0;L;1F19 0300;;;;N;;;;1F13;\n1F1C;GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA;Lu;0;L;1F18 0301;;;;N;;;;1F14;\n1F1D;GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA;Lu;0;L;1F19 0301;;;;N;;;;1F15;\n1F20;GREEK SMALL LETTER ETA WITH PSILI;Ll;0;L;03B7 0313;;;;N;;;1F28;;1F28\n1F21;GREEK SMALL LETTER ETA WITH DASIA;Ll;0;L;03B7 0314;;;;N;;;1F29;;1F29\n1F22;GREEK SMALL LETTER ETA WITH PSILI AND VARIA;Ll;0;L;1F20 0300;;;;N;;;1F2A;;1F2A\n1F23;GREEK SMALL LETTER ETA WITH DASIA AND VARIA;Ll;0;L;1F21 0300;;;;N;;;1F2B;;1F2B\n1F24;GREEK SMALL LETTER ETA WITH PSILI AND OXIA;Ll;0;L;1F20 0301;;;;N;;;1F2C;;1F2C\n1F25;GREEK SMALL LETTER ETA WITH DASIA AND OXIA;Ll;0;L;1F21 0301;;;;N;;;1F2D;;1F2D\n1F26;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI;Ll;0;L;1F20 0342;;;;N;;;1F2E;;1F2E\n1F27;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI;Ll;0;L;1F21 0342;;;;N;;;1F2F;;1F2F\n1F28;GREEK CAPITAL LETTER ETA WITH PSILI;Lu;0;L;0397 0313;;;;N;;;;1F20;\n1F29;GREEK CAPITAL LETTER ETA WITH DASIA;Lu;0;L;0397 0314;;;;N;;;;1F21;\n1F2A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA;Lu;0;L;1F28 0300;;;;N;;;;1F22;\n1F2B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA;Lu;0;L;1F29 0300;;;;N;;;;1F23;\n1F2C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA;Lu;0;L;1F28 0301;;;;N;;;;1F24;\n1F2D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA;Lu;0;L;1F29 0301;;;;N;;;;1F25;\n1F2E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI;Lu;0;L;1F28 0342;;;;N;;;;1F26;\n1F2F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI;Lu;0;L;1F29 0342;;;;N;;;;1F27;\n1F30;GREEK SMALL LETTER IOTA WITH PSILI;Ll;0;L;03B9 0313;;;;N;;;1F38;;1F38\n1F31;GREEK SMALL LETTER IOTA WITH DASIA;Ll;0;L;03B9 0314;;;;N;;;1F39;;1F39\n1F32;GREEK SMALL LETTER IOTA WITH PSILI AND VARIA;Ll;0;L;1F30 0300;;;;N;;;1F3A;;1F3A\n1F33;GREEK SMALL LETTER IOTA WITH DASIA AND VARIA;Ll;0;L;1F31 0300;;;;N;;;1F3B;;1F3B\n1F34;GREEK SMALL LETTER IOTA WITH PSILI AND OXIA;Ll;0;L;1F30 0301;;;;N;;;1F3C;;1F3C\n1F35;GREEK SMALL LETTER IOTA WITH DASIA AND OXIA;Ll;0;L;1F31 0301;;;;N;;;1F3D;;1F3D\n1F36;GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI;Ll;0;L;1F30 0342;;;;N;;;1F3E;;1F3E\n1F37;GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI;Ll;0;L;1F31 0342;;;;N;;;1F3F;;1F3F\n1F38;GREEK CAPITAL LETTER IOTA WITH PSILI;Lu;0;L;0399 0313;;;;N;;;;1F30;\n1F39;GREEK CAPITAL LETTER IOTA WITH DASIA;Lu;0;L;0399 0314;;;;N;;;;1F31;\n1F3A;GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA;Lu;0;L;1F38 0300;;;;N;;;;1F32;\n1F3B;GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA;Lu;0;L;1F39 0300;;;;N;;;;1F33;\n1F3C;GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA;Lu;0;L;1F38 0301;;;;N;;;;1F34;\n1F3D;GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA;Lu;0;L;1F39 0301;;;;N;;;;1F35;\n1F3E;GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI;Lu;0;L;1F38 0342;;;;N;;;;1F36;\n1F3F;GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI;Lu;0;L;1F39 0342;;;;N;;;;1F37;\n1F40;GREEK SMALL LETTER OMICRON WITH PSILI;Ll;0;L;03BF 0313;;;;N;;;1F48;;1F48\n1F41;GREEK SMALL LETTER OMICRON WITH DASIA;Ll;0;L;03BF 0314;;;;N;;;1F49;;1F49\n1F42;GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA;Ll;0;L;1F40 0300;;;;N;;;1F4A;;1F4A\n1F43;GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA;Ll;0;L;1F41 0300;;;;N;;;1F4B;;1F4B\n1F44;GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA;Ll;0;L;1F40 0301;;;;N;;;1F4C;;1F4C\n1F45;GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA;Ll;0;L;1F41 0301;;;;N;;;1F4D;;1F4D\n1F48;GREEK CAPITAL LETTER OMICRON WITH PSILI;Lu;0;L;039F 0313;;;;N;;;;1F40;\n1F49;GREEK CAPITAL LETTER OMICRON WITH DASIA;Lu;0;L;039F 0314;;;;N;;;;1F41;\n1F4A;GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA;Lu;0;L;1F48 0300;;;;N;;;;1F42;\n1F4B;GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA;Lu;0;L;1F49 0300;;;;N;;;;1F43;\n1F4C;GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA;Lu;0;L;1F48 0301;;;;N;;;;1F44;\n1F4D;GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA;Lu;0;L;1F49 0301;;;;N;;;;1F45;\n1F50;GREEK SMALL LETTER UPSILON WITH PSILI;Ll;0;L;03C5 0313;;;;N;;;;;\n1F51;GREEK SMALL LETTER UPSILON WITH DASIA;Ll;0;L;03C5 0314;;;;N;;;1F59;;1F59\n1F52;GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA;Ll;0;L;1F50 0300;;;;N;;;;;\n1F53;GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA;Ll;0;L;1F51 0300;;;;N;;;1F5B;;1F5B\n1F54;GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA;Ll;0;L;1F50 0301;;;;N;;;;;\n1F55;GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA;Ll;0;L;1F51 0301;;;;N;;;1F5D;;1F5D\n1F56;GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI;Ll;0;L;1F50 0342;;;;N;;;;;\n1F57;GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI;Ll;0;L;1F51 0342;;;;N;;;1F5F;;1F5F\n1F59;GREEK CAPITAL LETTER UPSILON WITH DASIA;Lu;0;L;03A5 0314;;;;N;;;;1F51;\n1F5B;GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA;Lu;0;L;1F59 0300;;;;N;;;;1F53;\n1F5D;GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA;Lu;0;L;1F59 0301;;;;N;;;;1F55;\n1F5F;GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI;Lu;0;L;1F59 0342;;;;N;;;;1F57;\n1F60;GREEK SMALL LETTER OMEGA WITH PSILI;Ll;0;L;03C9 0313;;;;N;;;1F68;;1F68\n1F61;GREEK SMALL LETTER OMEGA WITH DASIA;Ll;0;L;03C9 0314;;;;N;;;1F69;;1F69\n1F62;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA;Ll;0;L;1F60 0300;;;;N;;;1F6A;;1F6A\n1F63;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA;Ll;0;L;1F61 0300;;;;N;;;1F6B;;1F6B\n1F64;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA;Ll;0;L;1F60 0301;;;;N;;;1F6C;;1F6C\n1F65;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA;Ll;0;L;1F61 0301;;;;N;;;1F6D;;1F6D\n1F66;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI;Ll;0;L;1F60 0342;;;;N;;;1F6E;;1F6E\n1F67;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI;Ll;0;L;1F61 0342;;;;N;;;1F6F;;1F6F\n1F68;GREEK CAPITAL LETTER OMEGA WITH PSILI;Lu;0;L;03A9 0313;;;;N;;;;1F60;\n1F69;GREEK CAPITAL LETTER OMEGA WITH DASIA;Lu;0;L;03A9 0314;;;;N;;;;1F61;\n1F6A;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA;Lu;0;L;1F68 0300;;;;N;;;;1F62;\n1F6B;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA;Lu;0;L;1F69 0300;;;;N;;;;1F63;\n1F6C;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA;Lu;0;L;1F68 0301;;;;N;;;;1F64;\n1F6D;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA;Lu;0;L;1F69 0301;;;;N;;;;1F65;\n1F6E;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI;Lu;0;L;1F68 0342;;;;N;;;;1F66;\n1F6F;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI;Lu;0;L;1F69 0342;;;;N;;;;1F67;\n1F70;GREEK SMALL LETTER ALPHA WITH VARIA;Ll;0;L;03B1 0300;;;;N;;;1FBA;;1FBA\n1F71;GREEK SMALL LETTER ALPHA WITH OXIA;Ll;0;L;03AC;;;;N;;;1FBB;;1FBB\n1F72;GREEK SMALL LETTER EPSILON WITH VARIA;Ll;0;L;03B5 0300;;;;N;;;1FC8;;1FC8\n1F73;GREEK SMALL LETTER EPSILON WITH OXIA;Ll;0;L;03AD;;;;N;;;1FC9;;1FC9\n1F74;GREEK SMALL LETTER ETA WITH VARIA;Ll;0;L;03B7 0300;;;;N;;;1FCA;;1FCA\n1F75;GREEK SMALL LETTER ETA WITH OXIA;Ll;0;L;03AE;;;;N;;;1FCB;;1FCB\n1F76;GREEK SMALL LETTER IOTA WITH VARIA;Ll;0;L;03B9 0300;;;;N;;;1FDA;;1FDA\n1F77;GREEK SMALL LETTER IOTA WITH OXIA;Ll;0;L;03AF;;;;N;;;1FDB;;1FDB\n1F78;GREEK SMALL LETTER OMICRON WITH VARIA;Ll;0;L;03BF 0300;;;;N;;;1FF8;;1FF8\n1F79;GREEK SMALL LETTER OMICRON WITH OXIA;Ll;0;L;03CC;;;;N;;;1FF9;;1FF9\n1F7A;GREEK SMALL LETTER UPSILON WITH VARIA;Ll;0;L;03C5 0300;;;;N;;;1FEA;;1FEA\n1F7B;GREEK SMALL LETTER UPSILON WITH OXIA;Ll;0;L;03CD;;;;N;;;1FEB;;1FEB\n1F7C;GREEK SMALL LETTER OMEGA WITH VARIA;Ll;0;L;03C9 0300;;;;N;;;1FFA;;1FFA\n1F7D;GREEK SMALL LETTER OMEGA WITH OXIA;Ll;0;L;03CE;;;;N;;;1FFB;;1FFB\n1F80;GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F00 0345;;;;N;;;1F88;;1F88\n1F81;GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F01 0345;;;;N;;;1F89;;1F89\n1F82;GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F02 0345;;;;N;;;1F8A;;1F8A\n1F83;GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F03 0345;;;;N;;;1F8B;;1F8B\n1F84;GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F04 0345;;;;N;;;1F8C;;1F8C\n1F85;GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F05 0345;;;;N;;;1F8D;;1F8D\n1F86;GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F06 0345;;;;N;;;1F8E;;1F8E\n1F87;GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F07 0345;;;;N;;;1F8F;;1F8F\n1F88;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F08 0345;;;;N;;;;1F80;\n1F89;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F09 0345;;;;N;;;;1F81;\n1F8A;GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0A 0345;;;;N;;;;1F82;\n1F8B;GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F0B 0345;;;;N;;;;1F83;\n1F8C;GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0C 0345;;;;N;;;;1F84;\n1F8D;GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F0D 0345;;;;N;;;;1F85;\n1F8E;GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0E 0345;;;;N;;;;1F86;\n1F8F;GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F0F 0345;;;;N;;;;1F87;\n1F90;GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F20 0345;;;;N;;;1F98;;1F98\n1F91;GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F21 0345;;;;N;;;1F99;;1F99\n1F92;GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F22 0345;;;;N;;;1F9A;;1F9A\n1F93;GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F23 0345;;;;N;;;1F9B;;1F9B\n1F94;GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F24 0345;;;;N;;;1F9C;;1F9C\n1F95;GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F25 0345;;;;N;;;1F9D;;1F9D\n1F96;GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F26 0345;;;;N;;;1F9E;;1F9E\n1F97;GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F27 0345;;;;N;;;1F9F;;1F9F\n1F98;GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F28 0345;;;;N;;;;1F90;\n1F99;GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F29 0345;;;;N;;;;1F91;\n1F9A;GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2A 0345;;;;N;;;;1F92;\n1F9B;GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F2B 0345;;;;N;;;;1F93;\n1F9C;GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2C 0345;;;;N;;;;1F94;\n1F9D;GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F2D 0345;;;;N;;;;1F95;\n1F9E;GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2E 0345;;;;N;;;;1F96;\n1F9F;GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F2F 0345;;;;N;;;;1F97;\n1FA0;GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI;Ll;0;L;1F60 0345;;;;N;;;1FA8;;1FA8\n1FA1;GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI;Ll;0;L;1F61 0345;;;;N;;;1FA9;;1FA9\n1FA2;GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F62 0345;;;;N;;;1FAA;;1FAA\n1FA3;GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI;Ll;0;L;1F63 0345;;;;N;;;1FAB;;1FAB\n1FA4;GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F64 0345;;;;N;;;1FAC;;1FAC\n1FA5;GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI;Ll;0;L;1F65 0345;;;;N;;;1FAD;;1FAD\n1FA6;GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F66 0345;;;;N;;;1FAE;;1FAE\n1FA7;GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1F67 0345;;;;N;;;1FAF;;1FAF\n1FA8;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI;Lt;0;L;1F68 0345;;;;N;;;;1FA0;\n1FA9;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI;Lt;0;L;1F69 0345;;;;N;;;;1FA1;\n1FAA;GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6A 0345;;;;N;;;;1FA2;\n1FAB;GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI;Lt;0;L;1F6B 0345;;;;N;;;;1FA3;\n1FAC;GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6C 0345;;;;N;;;;1FA4;\n1FAD;GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI;Lt;0;L;1F6D 0345;;;;N;;;;1FA5;\n1FAE;GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6E 0345;;;;N;;;;1FA6;\n1FAF;GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI;Lt;0;L;1F6F 0345;;;;N;;;;1FA7;\n1FB0;GREEK SMALL LETTER ALPHA WITH VRACHY;Ll;0;L;03B1 0306;;;;N;;;1FB8;;1FB8\n1FB1;GREEK SMALL LETTER ALPHA WITH MACRON;Ll;0;L;03B1 0304;;;;N;;;1FB9;;1FB9\n1FB2;GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F70 0345;;;;N;;;;;\n1FB3;GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI;Ll;0;L;03B1 0345;;;;N;;;1FBC;;1FBC\n1FB4;GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AC 0345;;;;N;;;;;\n1FB6;GREEK SMALL LETTER ALPHA WITH PERISPOMENI;Ll;0;L;03B1 0342;;;;N;;;;;\n1FB7;GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FB6 0345;;;;N;;;;;\n1FB8;GREEK CAPITAL LETTER ALPHA WITH VRACHY;Lu;0;L;0391 0306;;;;N;;;;1FB0;\n1FB9;GREEK CAPITAL LETTER ALPHA WITH MACRON;Lu;0;L;0391 0304;;;;N;;;;1FB1;\n1FBA;GREEK CAPITAL LETTER ALPHA WITH VARIA;Lu;0;L;0391 0300;;;;N;;;;1F70;\n1FBB;GREEK CAPITAL LETTER ALPHA WITH OXIA;Lu;0;L;0386;;;;N;;;;1F71;\n1FBC;GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI;Lt;0;L;0391 0345;;;;N;;;;1FB3;\n1FBD;GREEK KORONIS;Sk;0;ON;<compat> 0020 0313;;;;N;;;;;\n1FBE;GREEK PROSGEGRAMMENI;Ll;0;L;03B9;;;;N;;;0399;;0399\n1FBF;GREEK PSILI;Sk;0;ON;<compat> 0020 0313;;;;N;;;;;\n1FC0;GREEK PERISPOMENI;Sk;0;ON;<compat> 0020 0342;;;;N;;;;;\n1FC1;GREEK DIALYTIKA AND PERISPOMENI;Sk;0;ON;00A8 0342;;;;N;;;;;\n1FC2;GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F74 0345;;;;N;;;;;\n1FC3;GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI;Ll;0;L;03B7 0345;;;;N;;;1FCC;;1FCC\n1FC4;GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03AE 0345;;;;N;;;;;\n1FC6;GREEK SMALL LETTER ETA WITH PERISPOMENI;Ll;0;L;03B7 0342;;;;N;;;;;\n1FC7;GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FC6 0345;;;;N;;;;;\n1FC8;GREEK CAPITAL LETTER EPSILON WITH VARIA;Lu;0;L;0395 0300;;;;N;;;;1F72;\n1FC9;GREEK CAPITAL LETTER EPSILON WITH OXIA;Lu;0;L;0388;;;;N;;;;1F73;\n1FCA;GREEK CAPITAL LETTER ETA WITH VARIA;Lu;0;L;0397 0300;;;;N;;;;1F74;\n1FCB;GREEK CAPITAL LETTER ETA WITH OXIA;Lu;0;L;0389;;;;N;;;;1F75;\n1FCC;GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI;Lt;0;L;0397 0345;;;;N;;;;1FC3;\n1FCD;GREEK PSILI AND VARIA;Sk;0;ON;1FBF 0300;;;;N;;;;;\n1FCE;GREEK PSILI AND OXIA;Sk;0;ON;1FBF 0301;;;;N;;;;;\n1FCF;GREEK PSILI AND PERISPOMENI;Sk;0;ON;1FBF 0342;;;;N;;;;;\n1FD0;GREEK SMALL LETTER IOTA WITH VRACHY;Ll;0;L;03B9 0306;;;;N;;;1FD8;;1FD8\n1FD1;GREEK SMALL LETTER IOTA WITH MACRON;Ll;0;L;03B9 0304;;;;N;;;1FD9;;1FD9\n1FD2;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA;Ll;0;L;03CA 0300;;;;N;;;;;\n1FD3;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA;Ll;0;L;0390;;;;N;;;;;\n1FD6;GREEK SMALL LETTER IOTA WITH PERISPOMENI;Ll;0;L;03B9 0342;;;;N;;;;;\n1FD7;GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CA 0342;;;;N;;;;;\n1FD8;GREEK CAPITAL LETTER IOTA WITH VRACHY;Lu;0;L;0399 0306;;;;N;;;;1FD0;\n1FD9;GREEK CAPITAL LETTER IOTA WITH MACRON;Lu;0;L;0399 0304;;;;N;;;;1FD1;\n1FDA;GREEK CAPITAL LETTER IOTA WITH VARIA;Lu;0;L;0399 0300;;;;N;;;;1F76;\n1FDB;GREEK CAPITAL LETTER IOTA WITH OXIA;Lu;0;L;038A;;;;N;;;;1F77;\n1FDD;GREEK DASIA AND VARIA;Sk;0;ON;1FFE 0300;;;;N;;;;;\n1FDE;GREEK DASIA AND OXIA;Sk;0;ON;1FFE 0301;;;;N;;;;;\n1FDF;GREEK DASIA AND PERISPOMENI;Sk;0;ON;1FFE 0342;;;;N;;;;;\n1FE0;GREEK SMALL LETTER UPSILON WITH VRACHY;Ll;0;L;03C5 0306;;;;N;;;1FE8;;1FE8\n1FE1;GREEK SMALL LETTER UPSILON WITH MACRON;Ll;0;L;03C5 0304;;;;N;;;1FE9;;1FE9\n1FE2;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA;Ll;0;L;03CB 0300;;;;N;;;;;\n1FE3;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA;Ll;0;L;03B0;;;;N;;;;;\n1FE4;GREEK SMALL LETTER RHO WITH PSILI;Ll;0;L;03C1 0313;;;;N;;;;;\n1FE5;GREEK SMALL LETTER RHO WITH DASIA;Ll;0;L;03C1 0314;;;;N;;;1FEC;;1FEC\n1FE6;GREEK SMALL LETTER UPSILON WITH PERISPOMENI;Ll;0;L;03C5 0342;;;;N;;;;;\n1FE7;GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI;Ll;0;L;03CB 0342;;;;N;;;;;\n1FE8;GREEK CAPITAL LETTER UPSILON WITH VRACHY;Lu;0;L;03A5 0306;;;;N;;;;1FE0;\n1FE9;GREEK CAPITAL LETTER UPSILON WITH MACRON;Lu;0;L;03A5 0304;;;;N;;;;1FE1;\n1FEA;GREEK CAPITAL LETTER UPSILON WITH VARIA;Lu;0;L;03A5 0300;;;;N;;;;1F7A;\n1FEB;GREEK CAPITAL LETTER UPSILON WITH OXIA;Lu;0;L;038E;;;;N;;;;1F7B;\n1FEC;GREEK CAPITAL LETTER RHO WITH DASIA;Lu;0;L;03A1 0314;;;;N;;;;1FE5;\n1FED;GREEK DIALYTIKA AND VARIA;Sk;0;ON;00A8 0300;;;;N;;;;;\n1FEE;GREEK DIALYTIKA AND OXIA;Sk;0;ON;0385;;;;N;;;;;\n1FEF;GREEK VARIA;Sk;0;ON;0060;;;;N;;;;;\n1FF2;GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI;Ll;0;L;1F7C 0345;;;;N;;;;;\n1FF3;GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI;Ll;0;L;03C9 0345;;;;N;;;1FFC;;1FFC\n1FF4;GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI;Ll;0;L;03CE 0345;;;;N;;;;;\n1FF6;GREEK SMALL LETTER OMEGA WITH PERISPOMENI;Ll;0;L;03C9 0342;;;;N;;;;;\n1FF7;GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI;Ll;0;L;1FF6 0345;;;;N;;;;;\n1FF8;GREEK CAPITAL LETTER OMICRON WITH VARIA;Lu;0;L;039F 0300;;;;N;;;;1F78;\n1FF9;GREEK CAPITAL LETTER OMICRON WITH OXIA;Lu;0;L;038C;;;;N;;;;1F79;\n1FFA;GREEK CAPITAL LETTER OMEGA WITH VARIA;Lu;0;L;03A9 0300;;;;N;;;;1F7C;\n1FFB;GREEK CAPITAL LETTER OMEGA WITH OXIA;Lu;0;L;038F;;;;N;;;;1F7D;\n1FFC;GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI;Lt;0;L;03A9 0345;;;;N;;;;1FF3;\n1FFD;GREEK OXIA;Sk;0;ON;00B4;;;;N;;;;;\n1FFE;GREEK DASIA;Sk;0;ON;<compat> 0020 0314;;;;N;;;;;\n2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;;\n2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;;\n2002;EN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n2003;EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n2004;THREE-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n2005;FOUR-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n2006;SIX-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n2007;FIGURE SPACE;Zs;0;WS;<noBreak> 0020;;;;N;;;;;\n2008;PUNCTUATION SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n2009;THIN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n200A;HAIR SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n200B;ZERO WIDTH SPACE;Cf;0;BN;;;;;N;;;;;\n200C;ZERO WIDTH NON-JOINER;Cf;0;BN;;;;;N;;;;;\n200D;ZERO WIDTH JOINER;Cf;0;BN;;;;;N;;;;;\n200E;LEFT-TO-RIGHT MARK;Cf;0;L;;;;;N;;;;;\n200F;RIGHT-TO-LEFT MARK;Cf;0;R;;;;;N;;;;;\n2010;HYPHEN;Pd;0;ON;;;;;N;;;;;\n2011;NON-BREAKING HYPHEN;Pd;0;ON;<noBreak> 2010;;;;N;;;;;\n2012;FIGURE DASH;Pd;0;ON;;;;;N;;;;;\n2013;EN DASH;Pd;0;ON;;;;;N;;;;;\n2014;EM DASH;Pd;0;ON;;;;;N;;;;;\n2015;HORIZONTAL BAR;Pd;0;ON;;;;;N;QUOTATION DASH;;;;\n2016;DOUBLE VERTICAL LINE;Po;0;ON;;;;;N;DOUBLE VERTICAL BAR;;;;\n2017;DOUBLE LOW LINE;Po;0;ON;<compat> 0020 0333;;;;N;SPACING DOUBLE UNDERSCORE;;;;\n2018;LEFT SINGLE QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE TURNED COMMA QUOTATION MARK;;;;\n2019;RIGHT SINGLE QUOTATION MARK;Pf;0;ON;;;;;N;SINGLE COMMA QUOTATION MARK;;;;\n201A;SINGLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW SINGLE COMMA QUOTATION MARK;;;;\n201B;SINGLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;SINGLE REVERSED COMMA QUOTATION MARK;;;;\n201C;LEFT DOUBLE QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE TURNED COMMA QUOTATION MARK;;;;\n201D;RIGHT DOUBLE QUOTATION MARK;Pf;0;ON;;;;;N;DOUBLE COMMA QUOTATION MARK;;;;\n201E;DOUBLE LOW-9 QUOTATION MARK;Ps;0;ON;;;;;N;LOW DOUBLE COMMA QUOTATION MARK;;;;\n201F;DOUBLE HIGH-REVERSED-9 QUOTATION MARK;Pi;0;ON;;;;;N;DOUBLE REVERSED COMMA QUOTATION MARK;;;;\n2020;DAGGER;Po;0;ON;;;;;N;;;;;\n2021;DOUBLE DAGGER;Po;0;ON;;;;;N;;;;;\n2022;BULLET;Po;0;ON;;;;;N;;;;;\n2023;TRIANGULAR BULLET;Po;0;ON;;;;;N;;;;;\n2024;ONE DOT LEADER;Po;0;ON;<compat> 002E;;;;N;;;;;\n2025;TWO DOT LEADER;Po;0;ON;<compat> 002E 002E;;;;N;;;;;\n2026;HORIZONTAL ELLIPSIS;Po;0;ON;<compat> 002E 002E 002E;;;;N;;;;;\n2027;HYPHENATION POINT;Po;0;ON;;;;;N;;;;;\n2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;;\n2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;;\n202A;LEFT-TO-RIGHT EMBEDDING;Cf;0;LRE;;;;;N;;;;;\n202B;RIGHT-TO-LEFT EMBEDDING;Cf;0;RLE;;;;;N;;;;;\n202C;POP DIRECTIONAL FORMATTING;Cf;0;PDF;;;;;N;;;;;\n202D;LEFT-TO-RIGHT OVERRIDE;Cf;0;LRO;;;;;N;;;;;\n202E;RIGHT-TO-LEFT OVERRIDE;Cf;0;RLO;;;;;N;;;;;\n202F;NARROW NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;;;;;\n2030;PER MILLE SIGN;Po;0;ET;;;;;N;;;;;\n2031;PER TEN THOUSAND SIGN;Po;0;ET;;;;;N;;;;;\n2032;PRIME;Po;0;ET;;;;;N;;;;;\n2033;DOUBLE PRIME;Po;0;ET;<compat> 2032 2032;;;;N;;;;;\n2034;TRIPLE PRIME;Po;0;ET;<compat> 2032 2032 2032;;;;N;;;;;\n2035;REVERSED PRIME;Po;0;ON;;;;;N;;;;;\n2036;REVERSED DOUBLE PRIME;Po;0;ON;<compat> 2035 2035;;;;N;;;;;\n2037;REVERSED TRIPLE PRIME;Po;0;ON;<compat> 2035 2035 2035;;;;N;;;;;\n2038;CARET;Po;0;ON;;;;;N;;;;;\n2039;SINGLE LEFT-POINTING ANGLE QUOTATION MARK;Pi;0;ON;;;;;Y;LEFT POINTING SINGLE GUILLEMET;;;;\n203A;SINGLE RIGHT-POINTING ANGLE QUOTATION MARK;Pf;0;ON;;;;;Y;RIGHT POINTING SINGLE GUILLEMET;;;;\n203B;REFERENCE MARK;Po;0;ON;;;;;N;;;;;\n203C;DOUBLE EXCLAMATION MARK;Po;0;ON;<compat> 0021 0021;;;;N;;;;;\n203D;INTERROBANG;Po;0;ON;;;;;N;;;;;\n203E;OVERLINE;Po;0;ON;<compat> 0020 0305;;;;N;SPACING OVERSCORE;;;;\n203F;UNDERTIE;Pc;0;ON;;;;;N;;;;;\n2040;CHARACTER TIE;Pc;0;ON;;;;;N;;;;;\n2041;CARET INSERTION POINT;Po;0;ON;;;;;N;;;;;\n2042;ASTERISM;Po;0;ON;;;;;N;;;;;\n2043;HYPHEN BULLET;Po;0;ON;;;;;N;;;;;\n2044;FRACTION SLASH;Sm;0;CS;;;;;N;;;;;\n2045;LEFT SQUARE BRACKET WITH QUILL;Ps;0;ON;;;;;Y;;;;;\n2046;RIGHT SQUARE BRACKET WITH QUILL;Pe;0;ON;;;;;Y;;;;;\n2047;DOUBLE QUESTION MARK;Po;0;ON;<compat> 003F 003F;;;;N;;;;;\n2048;QUESTION EXCLAMATION MARK;Po;0;ON;<compat> 003F 0021;;;;N;;;;;\n2049;EXCLAMATION QUESTION MARK;Po;0;ON;<compat> 0021 003F;;;;N;;;;;\n204A;TIRONIAN SIGN ET;Po;0;ON;;;;;N;;;;;\n204B;REVERSED PILCROW SIGN;Po;0;ON;;;;;N;;;;;\n204C;BLACK LEFTWARDS BULLET;Po;0;ON;;;;;N;;;;;\n204D;BLACK RIGHTWARDS BULLET;Po;0;ON;;;;;N;;;;;\n204E;LOW ASTERISK;Po;0;ON;;;;;N;;;;;\n204F;REVERSED SEMICOLON;Po;0;ON;;;;;N;;;;;\n2050;CLOSE UP;Po;0;ON;;;;;N;;;;;\n2051;TWO ASTERISKS ALIGNED VERTICALLY;Po;0;ON;;;;;N;;;;;\n2052;COMMERCIAL MINUS SIGN;Sm;0;ON;;;;;N;;;;;\n2053;SWUNG DASH;Po;0;ON;;;;;N;;;;;\n2054;INVERTED UNDERTIE;Pc;0;ON;;;;;N;;;;;\n2055;FLOWER PUNCTUATION MARK;Po;0;ON;;;;;N;;;;;\n2056;THREE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;\n2057;QUADRUPLE PRIME;Po;0;ON;<compat> 2032 2032 2032 2032;;;;N;;;;;\n2058;FOUR DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;\n2059;FIVE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;\n205A;TWO DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;\n205B;FOUR DOT MARK;Po;0;ON;;;;;N;;;;;\n205C;DOTTED CROSS;Po;0;ON;;;;;N;;;;;\n205D;TRICOLON;Po;0;ON;;;;;N;;;;;\n205E;VERTICAL FOUR DOTS;Po;0;ON;;;;;N;;;;;\n205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n2060;WORD JOINER;Cf;0;BN;;;;;N;;;;;\n2061;FUNCTION APPLICATION;Cf;0;BN;;;;;N;;;;;\n2062;INVISIBLE TIMES;Cf;0;BN;;;;;N;;;;;\n2063;INVISIBLE SEPARATOR;Cf;0;BN;;;;;N;;;;;\n2064;INVISIBLE PLUS;Cf;0;BN;;;;;N;;;;;\n2066;LEFT-TO-RIGHT ISOLATE;Cf;0;LRI;;;;;N;;;;;\n2067;RIGHT-TO-LEFT ISOLATE;Cf;0;RLI;;;;;N;;;;;\n2068;FIRST STRONG ISOLATE;Cf;0;FSI;;;;;N;;;;;\n2069;POP DIRECTIONAL ISOLATE;Cf;0;PDI;;;;;N;;;;;\n206A;INHIBIT SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;;\n206B;ACTIVATE SYMMETRIC SWAPPING;Cf;0;BN;;;;;N;;;;;\n206C;INHIBIT ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;;\n206D;ACTIVATE ARABIC FORM SHAPING;Cf;0;BN;;;;;N;;;;;\n206E;NATIONAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;;\n206F;NOMINAL DIGIT SHAPES;Cf;0;BN;;;;;N;;;;;\n2070;SUPERSCRIPT ZERO;No;0;EN;<super> 0030;;0;0;N;SUPERSCRIPT DIGIT ZERO;;;;\n2071;SUPERSCRIPT LATIN SMALL LETTER I;Lm;0;L;<super> 0069;;;;N;;;;;\n2074;SUPERSCRIPT FOUR;No;0;EN;<super> 0034;;4;4;N;SUPERSCRIPT DIGIT FOUR;;;;\n2075;SUPERSCRIPT FIVE;No;0;EN;<super> 0035;;5;5;N;SUPERSCRIPT DIGIT FIVE;;;;\n2076;SUPERSCRIPT SIX;No;0;EN;<super> 0036;;6;6;N;SUPERSCRIPT DIGIT SIX;;;;\n2077;SUPERSCRIPT SEVEN;No;0;EN;<super> 0037;;7;7;N;SUPERSCRIPT DIGIT SEVEN;;;;\n2078;SUPERSCRIPT EIGHT;No;0;EN;<super> 0038;;8;8;N;SUPERSCRIPT DIGIT EIGHT;;;;\n2079;SUPERSCRIPT NINE;No;0;EN;<super> 0039;;9;9;N;SUPERSCRIPT DIGIT NINE;;;;\n207A;SUPERSCRIPT PLUS SIGN;Sm;0;ES;<super> 002B;;;;N;;;;;\n207B;SUPERSCRIPT MINUS;Sm;0;ES;<super> 2212;;;;N;SUPERSCRIPT HYPHEN-MINUS;;;;\n207C;SUPERSCRIPT EQUALS SIGN;Sm;0;ON;<super> 003D;;;;N;;;;;\n207D;SUPERSCRIPT LEFT PARENTHESIS;Ps;0;ON;<super> 0028;;;;Y;SUPERSCRIPT OPENING PARENTHESIS;;;;\n207E;SUPERSCRIPT RIGHT PARENTHESIS;Pe;0;ON;<super> 0029;;;;Y;SUPERSCRIPT CLOSING PARENTHESIS;;;;\n207F;SUPERSCRIPT LATIN SMALL LETTER N;Lm;0;L;<super> 006E;;;;N;;;;;\n2080;SUBSCRIPT ZERO;No;0;EN;<sub> 0030;;0;0;N;SUBSCRIPT DIGIT ZERO;;;;\n2081;SUBSCRIPT ONE;No;0;EN;<sub> 0031;;1;1;N;SUBSCRIPT DIGIT ONE;;;;\n2082;SUBSCRIPT TWO;No;0;EN;<sub> 0032;;2;2;N;SUBSCRIPT DIGIT TWO;;;;\n2083;SUBSCRIPT THREE;No;0;EN;<sub> 0033;;3;3;N;SUBSCRIPT DIGIT THREE;;;;\n2084;SUBSCRIPT FOUR;No;0;EN;<sub> 0034;;4;4;N;SUBSCRIPT DIGIT FOUR;;;;\n2085;SUBSCRIPT FIVE;No;0;EN;<sub> 0035;;5;5;N;SUBSCRIPT DIGIT FIVE;;;;\n2086;SUBSCRIPT SIX;No;0;EN;<sub> 0036;;6;6;N;SUBSCRIPT DIGIT SIX;;;;\n2087;SUBSCRIPT SEVEN;No;0;EN;<sub> 0037;;7;7;N;SUBSCRIPT DIGIT SEVEN;;;;\n2088;SUBSCRIPT EIGHT;No;0;EN;<sub> 0038;;8;8;N;SUBSCRIPT DIGIT EIGHT;;;;\n2089;SUBSCRIPT NINE;No;0;EN;<sub> 0039;;9;9;N;SUBSCRIPT DIGIT NINE;;;;\n208A;SUBSCRIPT PLUS SIGN;Sm;0;ES;<sub> 002B;;;;N;;;;;\n208B;SUBSCRIPT MINUS;Sm;0;ES;<sub> 2212;;;;N;SUBSCRIPT HYPHEN-MINUS;;;;\n208C;SUBSCRIPT EQUALS SIGN;Sm;0;ON;<sub> 003D;;;;N;;;;;\n208D;SUBSCRIPT LEFT PARENTHESIS;Ps;0;ON;<sub> 0028;;;;Y;SUBSCRIPT OPENING PARENTHESIS;;;;\n208E;SUBSCRIPT RIGHT PARENTHESIS;Pe;0;ON;<sub> 0029;;;;Y;SUBSCRIPT CLOSING PARENTHESIS;;;;\n2090;LATIN SUBSCRIPT SMALL LETTER A;Lm;0;L;<sub> 0061;;;;N;;;;;\n2091;LATIN SUBSCRIPT SMALL LETTER E;Lm;0;L;<sub> 0065;;;;N;;;;;\n2092;LATIN SUBSCRIPT SMALL LETTER O;Lm;0;L;<sub> 006F;;;;N;;;;;\n2093;LATIN SUBSCRIPT SMALL LETTER X;Lm;0;L;<sub> 0078;;;;N;;;;;\n2094;LATIN SUBSCRIPT SMALL LETTER SCHWA;Lm;0;L;<sub> 0259;;;;N;;;;;\n2095;LATIN SUBSCRIPT SMALL LETTER H;Lm;0;L;<sub> 0068;;;;N;;;;;\n2096;LATIN SUBSCRIPT SMALL LETTER K;Lm;0;L;<sub> 006B;;;;N;;;;;\n2097;LATIN SUBSCRIPT SMALL LETTER L;Lm;0;L;<sub> 006C;;;;N;;;;;\n2098;LATIN SUBSCRIPT SMALL LETTER M;Lm;0;L;<sub> 006D;;;;N;;;;;\n2099;LATIN SUBSCRIPT SMALL LETTER N;Lm;0;L;<sub> 006E;;;;N;;;;;\n209A;LATIN SUBSCRIPT SMALL LETTER P;Lm;0;L;<sub> 0070;;;;N;;;;;\n209B;LATIN SUBSCRIPT SMALL LETTER S;Lm;0;L;<sub> 0073;;;;N;;;;;\n209C;LATIN SUBSCRIPT SMALL LETTER T;Lm;0;L;<sub> 0074;;;;N;;;;;\n20A0;EURO-CURRENCY SIGN;Sc;0;ET;;;;;N;;;;;\n20A1;COLON SIGN;Sc;0;ET;;;;;N;;;;;\n20A2;CRUZEIRO SIGN;Sc;0;ET;;;;;N;;;;;\n20A3;FRENCH FRANC SIGN;Sc;0;ET;;;;;N;;;;;\n20A4;LIRA SIGN;Sc;0;ET;;;;;N;;;;;\n20A5;MILL SIGN;Sc;0;ET;;;;;N;;;;;\n20A6;NAIRA SIGN;Sc;0;ET;;;;;N;;;;;\n20A7;PESETA SIGN;Sc;0;ET;;;;;N;;;;;\n20A8;RUPEE SIGN;Sc;0;ET;<compat> 0052 0073;;;;N;;;;;\n20A9;WON SIGN;Sc;0;ET;;;;;N;;;;;\n20AA;NEW SHEQEL SIGN;Sc;0;ET;;;;;N;;;;;\n20AB;DONG SIGN;Sc;0;ET;;;;;N;;;;;\n20AC;EURO SIGN;Sc;0;ET;;;;;N;;;;;\n20AD;KIP SIGN;Sc;0;ET;;;;;N;;;;;\n20AE;TUGRIK SIGN;Sc;0;ET;;;;;N;;;;;\n20AF;DRACHMA SIGN;Sc;0;ET;;;;;N;;;;;\n20B0;GERMAN PENNY SIGN;Sc;0;ET;;;;;N;;;;;\n20B1;PESO SIGN;Sc;0;ET;;;;;N;;;;;\n20B2;GUARANI SIGN;Sc;0;ET;;;;;N;;;;;\n20B3;AUSTRAL SIGN;Sc;0;ET;;;;;N;;;;;\n20B4;HRYVNIA SIGN;Sc;0;ET;;;;;N;;;;;\n20B5;CEDI SIGN;Sc;0;ET;;;;;N;;;;;\n20B6;LIVRE TOURNOIS SIGN;Sc;0;ET;;;;;N;;;;;\n20B7;SPESMILO SIGN;Sc;0;ET;;;;;N;;;;;\n20B8;TENGE SIGN;Sc;0;ET;;;;;N;;;;;\n20B9;INDIAN RUPEE SIGN;Sc;0;ET;;;;;N;;;;;\n20BA;TURKISH LIRA SIGN;Sc;0;ET;;;;;N;;;;;\n20BB;NORDIC MARK SIGN;Sc;0;ET;;;;;N;;;;;\n20BC;MANAT SIGN;Sc;0;ET;;;;;N;;;;;\n20BD;RUBLE SIGN;Sc;0;ET;;;;;N;;;;;\n20BE;LARI SIGN;Sc;0;ET;;;;;N;;;;;\n20BF;BITCOIN SIGN;Sc;0;ET;;;;;N;;;;;\n20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;;\n20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;;\n20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;;\n20D3;COMBINING SHORT VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING SHORT VERTICAL BAR OVERLAY;;;;\n20D4;COMBINING ANTICLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING ANTICLOCKWISE ARROW ABOVE;;;;\n20D5;COMBINING CLOCKWISE ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING CLOCKWISE ARROW ABOVE;;;;\n20D6;COMBINING LEFT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT ARROW ABOVE;;;;\n20D7;COMBINING RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT ARROW ABOVE;;;;\n20D8;COMBINING RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING RING OVERLAY;;;;\n20D9;COMBINING CLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING CLOCKWISE RING OVERLAY;;;;\n20DA;COMBINING ANTICLOCKWISE RING OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING ANTICLOCKWISE RING OVERLAY;;;;\n20DB;COMBINING THREE DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING THREE DOTS ABOVE;;;;\n20DC;COMBINING FOUR DOTS ABOVE;Mn;230;NSM;;;;;N;NON-SPACING FOUR DOTS ABOVE;;;;\n20DD;COMBINING ENCLOSING CIRCLE;Me;0;NSM;;;;;N;ENCLOSING CIRCLE;;;;\n20DE;COMBINING ENCLOSING SQUARE;Me;0;NSM;;;;;N;ENCLOSING SQUARE;;;;\n20DF;COMBINING ENCLOSING DIAMOND;Me;0;NSM;;;;;N;ENCLOSING DIAMOND;;;;\n20E0;COMBINING ENCLOSING CIRCLE BACKSLASH;Me;0;NSM;;;;;N;ENCLOSING CIRCLE SLASH;;;;\n20E1;COMBINING LEFT RIGHT ARROW ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT RIGHT ARROW ABOVE;;;;\n20E2;COMBINING ENCLOSING SCREEN;Me;0;NSM;;;;;N;;;;;\n20E3;COMBINING ENCLOSING KEYCAP;Me;0;NSM;;;;;N;;;;;\n20E4;COMBINING ENCLOSING UPWARD POINTING TRIANGLE;Me;0;NSM;;;;;N;;;;;\n20E5;COMBINING REVERSE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;;\n20E6;COMBINING DOUBLE VERTICAL STROKE OVERLAY;Mn;1;NSM;;;;;N;;;;;\n20E7;COMBINING ANNUITY SYMBOL;Mn;230;NSM;;;;;N;;;;;\n20E8;COMBINING TRIPLE UNDERDOT;Mn;220;NSM;;;;;N;;;;;\n20E9;COMBINING WIDE BRIDGE ABOVE;Mn;230;NSM;;;;;N;;;;;\n20EA;COMBINING LEFTWARDS ARROW OVERLAY;Mn;1;NSM;;;;;N;;;;;\n20EB;COMBINING LONG DOUBLE SOLIDUS OVERLAY;Mn;1;NSM;;;;;N;;;;;\n20EC;COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS;Mn;220;NSM;;;;;N;;;;;\n20ED;COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS;Mn;220;NSM;;;;;N;;;;;\n20EE;COMBINING LEFT ARROW BELOW;Mn;220;NSM;;;;;N;;;;;\n20EF;COMBINING RIGHT ARROW BELOW;Mn;220;NSM;;;;;N;;;;;\n20F0;COMBINING ASTERISK ABOVE;Mn;230;NSM;;;;;N;;;;;\n2100;ACCOUNT OF;So;0;ON;<compat> 0061 002F 0063;;;;N;;;;;\n2101;ADDRESSED TO THE SUBJECT;So;0;ON;<compat> 0061 002F 0073;;;;N;;;;;\n2102;DOUBLE-STRUCK CAPITAL C;Lu;0;L;<font> 0043;;;;N;DOUBLE-STRUCK C;;;;\n2103;DEGREE CELSIUS;So;0;ON;<compat> 00B0 0043;;;;N;DEGREES CENTIGRADE;;;;\n2104;CENTRE LINE SYMBOL;So;0;ON;;;;;N;C L SYMBOL;;;;\n2105;CARE OF;So;0;ON;<compat> 0063 002F 006F;;;;N;;;;;\n2106;CADA UNA;So;0;ON;<compat> 0063 002F 0075;;;;N;;;;;\n2107;EULER CONSTANT;Lu;0;L;<compat> 0190;;;;N;EULERS;;;;\n2108;SCRUPLE;So;0;ON;;;;;N;;;;;\n2109;DEGREE FAHRENHEIT;So;0;ON;<compat> 00B0 0046;;;;N;DEGREES FAHRENHEIT;;;;\n210A;SCRIPT SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;\n210B;SCRIPT CAPITAL H;Lu;0;L;<font> 0048;;;;N;SCRIPT H;;;;\n210C;BLACK-LETTER CAPITAL H;Lu;0;L;<font> 0048;;;;N;BLACK-LETTER H;;;;\n210D;DOUBLE-STRUCK CAPITAL H;Lu;0;L;<font> 0048;;;;N;DOUBLE-STRUCK H;;;;\n210E;PLANCK CONSTANT;Ll;0;L;<font> 0068;;;;N;;;;;\n210F;PLANCK CONSTANT OVER TWO PI;Ll;0;L;<font> 0127;;;;N;PLANCK CONSTANT OVER 2 PI;;;;\n2110;SCRIPT CAPITAL I;Lu;0;L;<font> 0049;;;;N;SCRIPT I;;;;\n2111;BLACK-LETTER CAPITAL I;Lu;0;L;<font> 0049;;;;N;BLACK-LETTER I;;;;\n2112;SCRIPT CAPITAL L;Lu;0;L;<font> 004C;;;;N;SCRIPT L;;;;\n2113;SCRIPT SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;\n2114;L B BAR SYMBOL;So;0;ON;;;;;N;;;;;\n2115;DOUBLE-STRUCK CAPITAL N;Lu;0;L;<font> 004E;;;;N;DOUBLE-STRUCK N;;;;\n2116;NUMERO SIGN;So;0;ON;<compat> 004E 006F;;;;N;NUMERO;;;;\n2117;SOUND RECORDING COPYRIGHT;So;0;ON;;;;;N;;;;;\n2118;SCRIPT CAPITAL P;Sm;0;ON;;;;;N;SCRIPT P;;;;\n2119;DOUBLE-STRUCK CAPITAL P;Lu;0;L;<font> 0050;;;;N;DOUBLE-STRUCK P;;;;\n211A;DOUBLE-STRUCK CAPITAL Q;Lu;0;L;<font> 0051;;;;N;DOUBLE-STRUCK Q;;;;\n211B;SCRIPT CAPITAL R;Lu;0;L;<font> 0052;;;;N;SCRIPT R;;;;\n211C;BLACK-LETTER CAPITAL R;Lu;0;L;<font> 0052;;;;N;BLACK-LETTER R;;;;\n211D;DOUBLE-STRUCK CAPITAL R;Lu;0;L;<font> 0052;;;;N;DOUBLE-STRUCK R;;;;\n211E;PRESCRIPTION TAKE;So;0;ON;;;;;N;;;;;\n211F;RESPONSE;So;0;ON;;;;;N;;;;;\n2120;SERVICE MARK;So;0;ON;<super> 0053 004D;;;;N;;;;;\n2121;TELEPHONE SIGN;So;0;ON;<compat> 0054 0045 004C;;;;N;T E L SYMBOL;;;;\n2122;TRADE MARK SIGN;So;0;ON;<super> 0054 004D;;;;N;TRADEMARK;;;;\n2123;VERSICLE;So;0;ON;;;;;N;;;;;\n2124;DOUBLE-STRUCK CAPITAL Z;Lu;0;L;<font> 005A;;;;N;DOUBLE-STRUCK Z;;;;\n2125;OUNCE SIGN;So;0;ON;;;;;N;OUNCE;;;;\n2126;OHM SIGN;Lu;0;L;03A9;;;;N;OHM;;;03C9;\n2127;INVERTED OHM SIGN;So;0;ON;;;;;N;MHO;;;;\n2128;BLACK-LETTER CAPITAL Z;Lu;0;L;<font> 005A;;;;N;BLACK-LETTER Z;;;;\n2129;TURNED GREEK SMALL LETTER IOTA;So;0;ON;;;;;N;;;;;\n212A;KELVIN SIGN;Lu;0;L;004B;;;;N;DEGREES KELVIN;;;006B;\n212B;ANGSTROM SIGN;Lu;0;L;00C5;;;;N;ANGSTROM UNIT;;;00E5;\n212C;SCRIPT CAPITAL B;Lu;0;L;<font> 0042;;;;N;SCRIPT B;;;;\n212D;BLACK-LETTER CAPITAL C;Lu;0;L;<font> 0043;;;;N;BLACK-LETTER C;;;;\n212E;ESTIMATED SYMBOL;So;0;ET;;;;;N;;;;;\n212F;SCRIPT SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;\n2130;SCRIPT CAPITAL E;Lu;0;L;<font> 0045;;;;N;SCRIPT E;;;;\n2131;SCRIPT CAPITAL F;Lu;0;L;<font> 0046;;;;N;SCRIPT F;;;;\n2132;TURNED CAPITAL F;Lu;0;L;;;;;N;TURNED F;;;214E;\n2133;SCRIPT CAPITAL M;Lu;0;L;<font> 004D;;;;N;SCRIPT M;;;;\n2134;SCRIPT SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;\n2135;ALEF SYMBOL;Lo;0;L;<compat> 05D0;;;;N;FIRST TRANSFINITE CARDINAL;;;;\n2136;BET SYMBOL;Lo;0;L;<compat> 05D1;;;;N;SECOND TRANSFINITE CARDINAL;;;;\n2137;GIMEL SYMBOL;Lo;0;L;<compat> 05D2;;;;N;THIRD TRANSFINITE CARDINAL;;;;\n2138;DALET SYMBOL;Lo;0;L;<compat> 05D3;;;;N;FOURTH TRANSFINITE CARDINAL;;;;\n2139;INFORMATION SOURCE;Ll;0;L;<font> 0069;;;;N;;;;;\n213A;ROTATED CAPITAL Q;So;0;ON;;;;;N;;;;;\n213B;FACSIMILE SIGN;So;0;ON;<compat> 0046 0041 0058;;;;N;;;;;\n213C;DOUBLE-STRUCK SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;\n213D;DOUBLE-STRUCK SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;\n213E;DOUBLE-STRUCK CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;\n213F;DOUBLE-STRUCK CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;\n2140;DOUBLE-STRUCK N-ARY SUMMATION;Sm;0;ON;<font> 2211;;;;Y;;;;;\n2141;TURNED SANS-SERIF CAPITAL G;Sm;0;ON;;;;;N;;;;;\n2142;TURNED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;;\n2143;REVERSED SANS-SERIF CAPITAL L;Sm;0;ON;;;;;N;;;;;\n2144;TURNED SANS-SERIF CAPITAL Y;Sm;0;ON;;;;;N;;;;;\n2145;DOUBLE-STRUCK ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;\n2146;DOUBLE-STRUCK ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;\n2147;DOUBLE-STRUCK ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;\n2148;DOUBLE-STRUCK ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;\n2149;DOUBLE-STRUCK ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;\n214A;PROPERTY LINE;So;0;ON;;;;;N;;;;;\n214B;TURNED AMPERSAND;Sm;0;ON;;;;;N;;;;;\n214C;PER SIGN;So;0;ON;;;;;N;;;;;\n214D;AKTIESELSKAB;So;0;ON;;;;;N;;;;;\n214E;TURNED SMALL F;Ll;0;L;;;;;N;;;2132;;2132\n214F;SYMBOL FOR SAMARITAN SOURCE;So;0;L;;;;;N;;;;;\n2150;VULGAR FRACTION ONE SEVENTH;No;0;ON;<fraction> 0031 2044 0037;;;1/7;N;;;;;\n2151;VULGAR FRACTION ONE NINTH;No;0;ON;<fraction> 0031 2044 0039;;;1/9;N;;;;;\n2152;VULGAR FRACTION ONE TENTH;No;0;ON;<fraction> 0031 2044 0031 0030;;;1/10;N;;;;;\n2153;VULGAR FRACTION ONE THIRD;No;0;ON;<fraction> 0031 2044 0033;;;1/3;N;FRACTION ONE THIRD;;;;\n2154;VULGAR FRACTION TWO THIRDS;No;0;ON;<fraction> 0032 2044 0033;;;2/3;N;FRACTION TWO THIRDS;;;;\n2155;VULGAR FRACTION ONE FIFTH;No;0;ON;<fraction> 0031 2044 0035;;;1/5;N;FRACTION ONE FIFTH;;;;\n2156;VULGAR FRACTION TWO FIFTHS;No;0;ON;<fraction> 0032 2044 0035;;;2/5;N;FRACTION TWO FIFTHS;;;;\n2157;VULGAR FRACTION THREE FIFTHS;No;0;ON;<fraction> 0033 2044 0035;;;3/5;N;FRACTION THREE FIFTHS;;;;\n2158;VULGAR FRACTION FOUR FIFTHS;No;0;ON;<fraction> 0034 2044 0035;;;4/5;N;FRACTION FOUR FIFTHS;;;;\n2159;VULGAR FRACTION ONE SIXTH;No;0;ON;<fraction> 0031 2044 0036;;;1/6;N;FRACTION ONE SIXTH;;;;\n215A;VULGAR FRACTION FIVE SIXTHS;No;0;ON;<fraction> 0035 2044 0036;;;5/6;N;FRACTION FIVE SIXTHS;;;;\n215B;VULGAR FRACTION ONE EIGHTH;No;0;ON;<fraction> 0031 2044 0038;;;1/8;N;FRACTION ONE EIGHTH;;;;\n215C;VULGAR FRACTION THREE EIGHTHS;No;0;ON;<fraction> 0033 2044 0038;;;3/8;N;FRACTION THREE EIGHTHS;;;;\n215D;VULGAR FRACTION FIVE EIGHTHS;No;0;ON;<fraction> 0035 2044 0038;;;5/8;N;FRACTION FIVE EIGHTHS;;;;\n215E;VULGAR FRACTION SEVEN EIGHTHS;No;0;ON;<fraction> 0037 2044 0038;;;7/8;N;FRACTION SEVEN EIGHTHS;;;;\n215F;FRACTION NUMERATOR ONE;No;0;ON;<fraction> 0031 2044;;;1;N;;;;;\n2160;ROMAN NUMERAL ONE;Nl;0;L;<compat> 0049;;;1;N;;;;2170;\n2161;ROMAN NUMERAL TWO;Nl;0;L;<compat> 0049 0049;;;2;N;;;;2171;\n2162;ROMAN NUMERAL THREE;Nl;0;L;<compat> 0049 0049 0049;;;3;N;;;;2172;\n2163;ROMAN NUMERAL FOUR;Nl;0;L;<compat> 0049 0056;;;4;N;;;;2173;\n2164;ROMAN NUMERAL FIVE;Nl;0;L;<compat> 0056;;;5;N;;;;2174;\n2165;ROMAN NUMERAL SIX;Nl;0;L;<compat> 0056 0049;;;6;N;;;;2175;\n2166;ROMAN NUMERAL SEVEN;Nl;0;L;<compat> 0056 0049 0049;;;7;N;;;;2176;\n2167;ROMAN NUMERAL EIGHT;Nl;0;L;<compat> 0056 0049 0049 0049;;;8;N;;;;2177;\n2168;ROMAN NUMERAL NINE;Nl;0;L;<compat> 0049 0058;;;9;N;;;;2178;\n2169;ROMAN NUMERAL TEN;Nl;0;L;<compat> 0058;;;10;N;;;;2179;\n216A;ROMAN NUMERAL ELEVEN;Nl;0;L;<compat> 0058 0049;;;11;N;;;;217A;\n216B;ROMAN NUMERAL TWELVE;Nl;0;L;<compat> 0058 0049 0049;;;12;N;;;;217B;\n216C;ROMAN NUMERAL FIFTY;Nl;0;L;<compat> 004C;;;50;N;;;;217C;\n216D;ROMAN NUMERAL ONE HUNDRED;Nl;0;L;<compat> 0043;;;100;N;;;;217D;\n216E;ROMAN NUMERAL FIVE HUNDRED;Nl;0;L;<compat> 0044;;;500;N;;;;217E;\n216F;ROMAN NUMERAL ONE THOUSAND;Nl;0;L;<compat> 004D;;;1000;N;;;;217F;\n2170;SMALL ROMAN NUMERAL ONE;Nl;0;L;<compat> 0069;;;1;N;;;2160;;2160\n2171;SMALL ROMAN NUMERAL TWO;Nl;0;L;<compat> 0069 0069;;;2;N;;;2161;;2161\n2172;SMALL ROMAN NUMERAL THREE;Nl;0;L;<compat> 0069 0069 0069;;;3;N;;;2162;;2162\n2173;SMALL ROMAN NUMERAL FOUR;Nl;0;L;<compat> 0069 0076;;;4;N;;;2163;;2163\n2174;SMALL ROMAN NUMERAL FIVE;Nl;0;L;<compat> 0076;;;5;N;;;2164;;2164\n2175;SMALL ROMAN NUMERAL SIX;Nl;0;L;<compat> 0076 0069;;;6;N;;;2165;;2165\n2176;SMALL ROMAN NUMERAL SEVEN;Nl;0;L;<compat> 0076 0069 0069;;;7;N;;;2166;;2166\n2177;SMALL ROMAN NUMERAL EIGHT;Nl;0;L;<compat> 0076 0069 0069 0069;;;8;N;;;2167;;2167\n2178;SMALL ROMAN NUMERAL NINE;Nl;0;L;<compat> 0069 0078;;;9;N;;;2168;;2168\n2179;SMALL ROMAN NUMERAL TEN;Nl;0;L;<compat> 0078;;;10;N;;;2169;;2169\n217A;SMALL ROMAN NUMERAL ELEVEN;Nl;0;L;<compat> 0078 0069;;;11;N;;;216A;;216A\n217B;SMALL ROMAN NUMERAL TWELVE;Nl;0;L;<compat> 0078 0069 0069;;;12;N;;;216B;;216B\n217C;SMALL ROMAN NUMERAL FIFTY;Nl;0;L;<compat> 006C;;;50;N;;;216C;;216C\n217D;SMALL ROMAN NUMERAL ONE HUNDRED;Nl;0;L;<compat> 0063;;;100;N;;;216D;;216D\n217E;SMALL ROMAN NUMERAL FIVE HUNDRED;Nl;0;L;<compat> 0064;;;500;N;;;216E;;216E\n217F;SMALL ROMAN NUMERAL ONE THOUSAND;Nl;0;L;<compat> 006D;;;1000;N;;;216F;;216F\n2180;ROMAN NUMERAL ONE THOUSAND C D;Nl;0;L;;;;1000;N;;;;;\n2181;ROMAN NUMERAL FIVE THOUSAND;Nl;0;L;;;;5000;N;;;;;\n2182;ROMAN NUMERAL TEN THOUSAND;Nl;0;L;;;;10000;N;;;;;\n2183;ROMAN NUMERAL REVERSED ONE HUNDRED;Lu;0;L;;;;;N;;;;2184;\n2184;LATIN SMALL LETTER REVERSED C;Ll;0;L;;;;;N;;;2183;;2183\n2185;ROMAN NUMERAL SIX LATE FORM;Nl;0;L;;;;6;N;;;;;\n2186;ROMAN NUMERAL FIFTY EARLY FORM;Nl;0;L;;;;50;N;;;;;\n2187;ROMAN NUMERAL FIFTY THOUSAND;Nl;0;L;;;;50000;N;;;;;\n2188;ROMAN NUMERAL ONE HUNDRED THOUSAND;Nl;0;L;;;;100000;N;;;;;\n2189;VULGAR FRACTION ZERO THIRDS;No;0;ON;<fraction> 0030 2044 0033;;;0;N;;;;;\n218A;TURNED DIGIT TWO;So;0;ON;;;;;N;;;;;\n218B;TURNED DIGIT THREE;So;0;ON;;;;;N;;;;;\n2190;LEFTWARDS ARROW;Sm;0;ON;;;;;N;LEFT ARROW;;;;\n2191;UPWARDS ARROW;Sm;0;ON;;;;;N;UP ARROW;;;;\n2192;RIGHTWARDS ARROW;Sm;0;ON;;;;;N;RIGHT ARROW;;;;\n2193;DOWNWARDS ARROW;Sm;0;ON;;;;;N;DOWN ARROW;;;;\n2194;LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;;\n2195;UP DOWN ARROW;So;0;ON;;;;;N;;;;;\n2196;NORTH WEST ARROW;So;0;ON;;;;;N;UPPER LEFT ARROW;;;;\n2197;NORTH EAST ARROW;So;0;ON;;;;;N;UPPER RIGHT ARROW;;;;\n2198;SOUTH EAST ARROW;So;0;ON;;;;;N;LOWER RIGHT ARROW;;;;\n2199;SOUTH WEST ARROW;So;0;ON;;;;;N;LOWER LEFT ARROW;;;;\n219A;LEFTWARDS ARROW WITH STROKE;Sm;0;ON;2190 0338;;;;N;LEFT ARROW WITH STROKE;;;;\n219B;RIGHTWARDS ARROW WITH STROKE;Sm;0;ON;2192 0338;;;;N;RIGHT ARROW WITH STROKE;;;;\n219C;LEFTWARDS WAVE ARROW;So;0;ON;;;;;N;LEFT WAVE ARROW;;;;\n219D;RIGHTWARDS WAVE ARROW;So;0;ON;;;;;N;RIGHT WAVE ARROW;;;;\n219E;LEFTWARDS TWO HEADED ARROW;So;0;ON;;;;;N;LEFT TWO HEADED ARROW;;;;\n219F;UPWARDS TWO HEADED ARROW;So;0;ON;;;;;N;UP TWO HEADED ARROW;;;;\n21A0;RIGHTWARDS TWO HEADED ARROW;Sm;0;ON;;;;;N;RIGHT TWO HEADED ARROW;;;;\n21A1;DOWNWARDS TWO HEADED ARROW;So;0;ON;;;;;N;DOWN TWO HEADED ARROW;;;;\n21A2;LEFTWARDS ARROW WITH TAIL;So;0;ON;;;;;N;LEFT ARROW WITH TAIL;;;;\n21A3;RIGHTWARDS ARROW WITH TAIL;Sm;0;ON;;;;;N;RIGHT ARROW WITH TAIL;;;;\n21A4;LEFTWARDS ARROW FROM BAR;So;0;ON;;;;;N;LEFT ARROW FROM BAR;;;;\n21A5;UPWARDS ARROW FROM BAR;So;0;ON;;;;;N;UP ARROW FROM BAR;;;;\n21A6;RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;RIGHT ARROW FROM BAR;;;;\n21A7;DOWNWARDS ARROW FROM BAR;So;0;ON;;;;;N;DOWN ARROW FROM BAR;;;;\n21A8;UP DOWN ARROW WITH BASE;So;0;ON;;;;;N;;;;;\n21A9;LEFTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;LEFT ARROW WITH HOOK;;;;\n21AA;RIGHTWARDS ARROW WITH HOOK;So;0;ON;;;;;N;RIGHT ARROW WITH HOOK;;;;\n21AB;LEFTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;LEFT ARROW WITH LOOP;;;;\n21AC;RIGHTWARDS ARROW WITH LOOP;So;0;ON;;;;;N;RIGHT ARROW WITH LOOP;;;;\n21AD;LEFT RIGHT WAVE ARROW;So;0;ON;;;;;N;;;;;\n21AE;LEFT RIGHT ARROW WITH STROKE;Sm;0;ON;2194 0338;;;;N;;;;;\n21AF;DOWNWARDS ZIGZAG ARROW;So;0;ON;;;;;N;DOWN ZIGZAG ARROW;;;;\n21B0;UPWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP LEFT;;;;\n21B1;UPWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;UP ARROW WITH TIP RIGHT;;;;\n21B2;DOWNWARDS ARROW WITH TIP LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP LEFT;;;;\n21B3;DOWNWARDS ARROW WITH TIP RIGHTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH TIP RIGHT;;;;\n21B4;RIGHTWARDS ARROW WITH CORNER DOWNWARDS;So;0;ON;;;;;N;RIGHT ARROW WITH CORNER DOWN;;;;\n21B5;DOWNWARDS ARROW WITH CORNER LEFTWARDS;So;0;ON;;;;;N;DOWN ARROW WITH CORNER LEFT;;;;\n21B6;ANTICLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;;\n21B7;CLOCKWISE TOP SEMICIRCLE ARROW;So;0;ON;;;;;N;;;;;\n21B8;NORTH WEST ARROW TO LONG BAR;So;0;ON;;;;;N;UPPER LEFT ARROW TO LONG BAR;;;;\n21B9;LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR OVER RIGHT ARROW TO BAR;;;;\n21BA;ANTICLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;\n21BB;CLOCKWISE OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;\n21BC;LEFTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB UP;;;;\n21BD;LEFTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;LEFT HARPOON WITH BARB DOWN;;;;\n21BE;UPWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB RIGHT;;;;\n21BF;UPWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;UP HARPOON WITH BARB LEFT;;;;\n21C0;RIGHTWARDS HARPOON WITH BARB UPWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB UP;;;;\n21C1;RIGHTWARDS HARPOON WITH BARB DOWNWARDS;So;0;ON;;;;;N;RIGHT HARPOON WITH BARB DOWN;;;;\n21C2;DOWNWARDS HARPOON WITH BARB RIGHTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB RIGHT;;;;\n21C3;DOWNWARDS HARPOON WITH BARB LEFTWARDS;So;0;ON;;;;;N;DOWN HARPOON WITH BARB LEFT;;;;\n21C4;RIGHTWARDS ARROW OVER LEFTWARDS ARROW;So;0;ON;;;;;N;RIGHT ARROW OVER LEFT ARROW;;;;\n21C5;UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW;So;0;ON;;;;;N;UP ARROW LEFT OF DOWN ARROW;;;;\n21C6;LEFTWARDS ARROW OVER RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT ARROW OVER RIGHT ARROW;;;;\n21C7;LEFTWARDS PAIRED ARROWS;So;0;ON;;;;;N;LEFT PAIRED ARROWS;;;;\n21C8;UPWARDS PAIRED ARROWS;So;0;ON;;;;;N;UP PAIRED ARROWS;;;;\n21C9;RIGHTWARDS PAIRED ARROWS;So;0;ON;;;;;N;RIGHT PAIRED ARROWS;;;;\n21CA;DOWNWARDS PAIRED ARROWS;So;0;ON;;;;;N;DOWN PAIRED ARROWS;;;;\n21CB;LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON;So;0;ON;;;;;N;LEFT HARPOON OVER RIGHT HARPOON;;;;\n21CC;RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON;So;0;ON;;;;;N;RIGHT HARPOON OVER LEFT HARPOON;;;;\n21CD;LEFTWARDS DOUBLE ARROW WITH STROKE;So;0;ON;21D0 0338;;;;N;LEFT DOUBLE ARROW WITH STROKE;;;;\n21CE;LEFT RIGHT DOUBLE ARROW WITH STROKE;Sm;0;ON;21D4 0338;;;;N;;;;;\n21CF;RIGHTWARDS DOUBLE ARROW WITH STROKE;Sm;0;ON;21D2 0338;;;;N;RIGHT DOUBLE ARROW WITH STROKE;;;;\n21D0;LEFTWARDS DOUBLE ARROW;So;0;ON;;;;;N;LEFT DOUBLE ARROW;;;;\n21D1;UPWARDS DOUBLE ARROW;So;0;ON;;;;;N;UP DOUBLE ARROW;;;;\n21D2;RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;RIGHT DOUBLE ARROW;;;;\n21D3;DOWNWARDS DOUBLE ARROW;So;0;ON;;;;;N;DOWN DOUBLE ARROW;;;;\n21D4;LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;\n21D5;UP DOWN DOUBLE ARROW;So;0;ON;;;;;N;;;;;\n21D6;NORTH WEST DOUBLE ARROW;So;0;ON;;;;;N;UPPER LEFT DOUBLE ARROW;;;;\n21D7;NORTH EAST DOUBLE ARROW;So;0;ON;;;;;N;UPPER RIGHT DOUBLE ARROW;;;;\n21D8;SOUTH EAST DOUBLE ARROW;So;0;ON;;;;;N;LOWER RIGHT DOUBLE ARROW;;;;\n21D9;SOUTH WEST DOUBLE ARROW;So;0;ON;;;;;N;LOWER LEFT DOUBLE ARROW;;;;\n21DA;LEFTWARDS TRIPLE ARROW;So;0;ON;;;;;N;LEFT TRIPLE ARROW;;;;\n21DB;RIGHTWARDS TRIPLE ARROW;So;0;ON;;;;;N;RIGHT TRIPLE ARROW;;;;\n21DC;LEFTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;LEFT SQUIGGLE ARROW;;;;\n21DD;RIGHTWARDS SQUIGGLE ARROW;So;0;ON;;;;;N;RIGHT SQUIGGLE ARROW;;;;\n21DE;UPWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;UP ARROW WITH DOUBLE STROKE;;;;\n21DF;DOWNWARDS ARROW WITH DOUBLE STROKE;So;0;ON;;;;;N;DOWN ARROW WITH DOUBLE STROKE;;;;\n21E0;LEFTWARDS DASHED ARROW;So;0;ON;;;;;N;LEFT DASHED ARROW;;;;\n21E1;UPWARDS DASHED ARROW;So;0;ON;;;;;N;UP DASHED ARROW;;;;\n21E2;RIGHTWARDS DASHED ARROW;So;0;ON;;;;;N;RIGHT DASHED ARROW;;;;\n21E3;DOWNWARDS DASHED ARROW;So;0;ON;;;;;N;DOWN DASHED ARROW;;;;\n21E4;LEFTWARDS ARROW TO BAR;So;0;ON;;;;;N;LEFT ARROW TO BAR;;;;\n21E5;RIGHTWARDS ARROW TO BAR;So;0;ON;;;;;N;RIGHT ARROW TO BAR;;;;\n21E6;LEFTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE LEFT ARROW;;;;\n21E7;UPWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE UP ARROW;;;;\n21E8;RIGHTWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE RIGHT ARROW;;;;\n21E9;DOWNWARDS WHITE ARROW;So;0;ON;;;;;N;WHITE DOWN ARROW;;;;\n21EA;UPWARDS WHITE ARROW FROM BAR;So;0;ON;;;;;N;WHITE UP ARROW FROM BAR;;;;\n21EB;UPWARDS WHITE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;;\n21EC;UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;;\n21ED;UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR;So;0;ON;;;;;N;;;;;\n21EE;UPWARDS WHITE DOUBLE ARROW;So;0;ON;;;;;N;;;;;\n21EF;UPWARDS WHITE DOUBLE ARROW ON PEDESTAL;So;0;ON;;;;;N;;;;;\n21F0;RIGHTWARDS WHITE ARROW FROM WALL;So;0;ON;;;;;N;;;;;\n21F1;NORTH WEST ARROW TO CORNER;So;0;ON;;;;;N;;;;;\n21F2;SOUTH EAST ARROW TO CORNER;So;0;ON;;;;;N;;;;;\n21F3;UP DOWN WHITE ARROW;So;0;ON;;;;;N;;;;;\n21F4;RIGHT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;\n21F5;DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n21F6;THREE RIGHTWARDS ARROWS;Sm;0;ON;;;;;N;;;;;\n21F7;LEFTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n21F8;RIGHTWARDS ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n21F9;LEFT RIGHT ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n21FA;LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n21FB;RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n21FC;LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n21FD;LEFTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;;\n21FE;RIGHTWARDS OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;;\n21FF;LEFT RIGHT OPEN-HEADED ARROW;Sm;0;ON;;;;;N;;;;;\n2200;FOR ALL;Sm;0;ON;;;;;N;;;;;\n2201;COMPLEMENT;Sm;0;ON;;;;;Y;;;;;\n2202;PARTIAL DIFFERENTIAL;Sm;0;ON;;;;;Y;;;;;\n2203;THERE EXISTS;Sm;0;ON;;;;;Y;;;;;\n2204;THERE DOES NOT EXIST;Sm;0;ON;2203 0338;;;;Y;;;;;\n2205;EMPTY SET;Sm;0;ON;;;;;N;;;;;\n2206;INCREMENT;Sm;0;ON;;;;;N;;;;;\n2207;NABLA;Sm;0;ON;;;;;N;;;;;\n2208;ELEMENT OF;Sm;0;ON;;;;;Y;;;;;\n2209;NOT AN ELEMENT OF;Sm;0;ON;2208 0338;;;;Y;;;;;\n220A;SMALL ELEMENT OF;Sm;0;ON;;;;;Y;;;;;\n220B;CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;;\n220C;DOES NOT CONTAIN AS MEMBER;Sm;0;ON;220B 0338;;;;Y;;;;;\n220D;SMALL CONTAINS AS MEMBER;Sm;0;ON;;;;;Y;;;;;\n220E;END OF PROOF;Sm;0;ON;;;;;N;;;;;\n220F;N-ARY PRODUCT;Sm;0;ON;;;;;N;;;;;\n2210;N-ARY COPRODUCT;Sm;0;ON;;;;;N;;;;;\n2211;N-ARY SUMMATION;Sm;0;ON;;;;;Y;;;;;\n2212;MINUS SIGN;Sm;0;ES;;;;;N;;;;;\n2213;MINUS-OR-PLUS SIGN;Sm;0;ET;;;;;N;;;;;\n2214;DOT PLUS;Sm;0;ON;;;;;N;;;;;\n2215;DIVISION SLASH;Sm;0;ON;;;;;Y;;;;;\n2216;SET MINUS;Sm;0;ON;;;;;Y;;;;;\n2217;ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;;\n2218;RING OPERATOR;Sm;0;ON;;;;;N;;;;;\n2219;BULLET OPERATOR;Sm;0;ON;;;;;N;;;;;\n221A;SQUARE ROOT;Sm;0;ON;;;;;Y;;;;;\n221B;CUBE ROOT;Sm;0;ON;;;;;Y;;;;;\n221C;FOURTH ROOT;Sm;0;ON;;;;;Y;;;;;\n221D;PROPORTIONAL TO;Sm;0;ON;;;;;Y;;;;;\n221E;INFINITY;Sm;0;ON;;;;;N;;;;;\n221F;RIGHT ANGLE;Sm;0;ON;;;;;Y;;;;;\n2220;ANGLE;Sm;0;ON;;;;;Y;;;;;\n2221;MEASURED ANGLE;Sm;0;ON;;;;;Y;;;;;\n2222;SPHERICAL ANGLE;Sm;0;ON;;;;;Y;;;;;\n2223;DIVIDES;Sm;0;ON;;;;;N;;;;;\n2224;DOES NOT DIVIDE;Sm;0;ON;2223 0338;;;;Y;;;;;\n2225;PARALLEL TO;Sm;0;ON;;;;;N;;;;;\n2226;NOT PARALLEL TO;Sm;0;ON;2225 0338;;;;Y;;;;;\n2227;LOGICAL AND;Sm;0;ON;;;;;N;;;;;\n2228;LOGICAL OR;Sm;0;ON;;;;;N;;;;;\n2229;INTERSECTION;Sm;0;ON;;;;;N;;;;;\n222A;UNION;Sm;0;ON;;;;;N;;;;;\n222B;INTEGRAL;Sm;0;ON;;;;;Y;;;;;\n222C;DOUBLE INTEGRAL;Sm;0;ON;<compat> 222B 222B;;;;Y;;;;;\n222D;TRIPLE INTEGRAL;Sm;0;ON;<compat> 222B 222B 222B;;;;Y;;;;;\n222E;CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;;\n222F;SURFACE INTEGRAL;Sm;0;ON;<compat> 222E 222E;;;;Y;;;;;\n2230;VOLUME INTEGRAL;Sm;0;ON;<compat> 222E 222E 222E;;;;Y;;;;;\n2231;CLOCKWISE INTEGRAL;Sm;0;ON;;;;;Y;;;;;\n2232;CLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;;\n2233;ANTICLOCKWISE CONTOUR INTEGRAL;Sm;0;ON;;;;;Y;;;;;\n2234;THEREFORE;Sm;0;ON;;;;;N;;;;;\n2235;BECAUSE;Sm;0;ON;;;;;N;;;;;\n2236;RATIO;Sm;0;ON;;;;;N;;;;;\n2237;PROPORTION;Sm;0;ON;;;;;N;;;;;\n2238;DOT MINUS;Sm;0;ON;;;;;N;;;;;\n2239;EXCESS;Sm;0;ON;;;;;Y;;;;;\n223A;GEOMETRIC PROPORTION;Sm;0;ON;;;;;N;;;;;\n223B;HOMOTHETIC;Sm;0;ON;;;;;Y;;;;;\n223C;TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;\n223D;REVERSED TILDE;Sm;0;ON;;;;;Y;;;;;\n223E;INVERTED LAZY S;Sm;0;ON;;;;;Y;;;;;\n223F;SINE WAVE;Sm;0;ON;;;;;Y;;;;;\n2240;WREATH PRODUCT;Sm;0;ON;;;;;Y;;;;;\n2241;NOT TILDE;Sm;0;ON;223C 0338;;;;Y;;;;;\n2242;MINUS TILDE;Sm;0;ON;;;;;Y;;;;;\n2243;ASYMPTOTICALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2244;NOT ASYMPTOTICALLY EQUAL TO;Sm;0;ON;2243 0338;;;;Y;;;;;\n2245;APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2246;APPROXIMATELY BUT NOT ACTUALLY EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2247;NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO;Sm;0;ON;2245 0338;;;;Y;;;;;\n2248;ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2249;NOT ALMOST EQUAL TO;Sm;0;ON;2248 0338;;;;Y;;;;;\n224A;ALMOST EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n224B;TRIPLE TILDE;Sm;0;ON;;;;;Y;;;;;\n224C;ALL EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n224D;EQUIVALENT TO;Sm;0;ON;;;;;N;;;;;\n224E;GEOMETRICALLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;;\n224F;DIFFERENCE BETWEEN;Sm;0;ON;;;;;N;;;;;\n2250;APPROACHES THE LIMIT;Sm;0;ON;;;;;N;;;;;\n2251;GEOMETRICALLY EQUAL TO;Sm;0;ON;;;;;N;;;;;\n2252;APPROXIMATELY EQUAL TO OR THE IMAGE OF;Sm;0;ON;;;;;Y;;;;;\n2253;IMAGE OF OR APPROXIMATELY EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2254;COLON EQUALS;Sm;0;ON;;;;;Y;COLON EQUAL;;;;\n2255;EQUALS COLON;Sm;0;ON;;;;;Y;EQUAL COLON;;;;\n2256;RING IN EQUAL TO;Sm;0;ON;;;;;N;;;;;\n2257;RING EQUAL TO;Sm;0;ON;;;;;N;;;;;\n2258;CORRESPONDS TO;Sm;0;ON;;;;;N;;;;;\n2259;ESTIMATES;Sm;0;ON;;;;;N;;;;;\n225A;EQUIANGULAR TO;Sm;0;ON;;;;;N;;;;;\n225B;STAR EQUALS;Sm;0;ON;;;;;N;;;;;\n225C;DELTA EQUAL TO;Sm;0;ON;;;;;N;;;;;\n225D;EQUAL TO BY DEFINITION;Sm;0;ON;;;;;N;;;;;\n225E;MEASURED BY;Sm;0;ON;;;;;N;;;;;\n225F;QUESTIONED EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2260;NOT EQUAL TO;Sm;0;ON;003D 0338;;;;Y;;;;;\n2261;IDENTICAL TO;Sm;0;ON;;;;;N;;;;;\n2262;NOT IDENTICAL TO;Sm;0;ON;2261 0338;;;;Y;;;;;\n2263;STRICTLY EQUIVALENT TO;Sm;0;ON;;;;;N;;;;;\n2264;LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUAL TO;;;;\n2265;GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUAL TO;;;;\n2266;LESS-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN OVER EQUAL TO;;;;\n2267;GREATER-THAN OVER EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN OVER EQUAL TO;;;;\n2268;LESS-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUAL TO;;;;\n2269;GREATER-THAN BUT NOT EQUAL TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUAL TO;;;;\n226A;MUCH LESS-THAN;Sm;0;ON;;;;;Y;MUCH LESS THAN;;;;\n226B;MUCH GREATER-THAN;Sm;0;ON;;;;;Y;MUCH GREATER THAN;;;;\n226C;BETWEEN;Sm;0;ON;;;;;N;;;;;\n226D;NOT EQUIVALENT TO;Sm;0;ON;224D 0338;;;;N;;;;;\n226E;NOT LESS-THAN;Sm;0;ON;003C 0338;;;;Y;NOT LESS THAN;;;;\n226F;NOT GREATER-THAN;Sm;0;ON;003E 0338;;;;Y;NOT GREATER THAN;;;;\n2270;NEITHER LESS-THAN NOR EQUAL TO;Sm;0;ON;2264 0338;;;;Y;NEITHER LESS THAN NOR EQUAL TO;;;;\n2271;NEITHER GREATER-THAN NOR EQUAL TO;Sm;0;ON;2265 0338;;;;Y;NEITHER GREATER THAN NOR EQUAL TO;;;;\n2272;LESS-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN OR EQUIVALENT TO;;;;\n2273;GREATER-THAN OR EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN OR EQUIVALENT TO;;;;\n2274;NEITHER LESS-THAN NOR EQUIVALENT TO;Sm;0;ON;2272 0338;;;;Y;NEITHER LESS THAN NOR EQUIVALENT TO;;;;\n2275;NEITHER GREATER-THAN NOR EQUIVALENT TO;Sm;0;ON;2273 0338;;;;Y;NEITHER GREATER THAN NOR EQUIVALENT TO;;;;\n2276;LESS-THAN OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN OR GREATER THAN;;;;\n2277;GREATER-THAN OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN OR LESS THAN;;;;\n2278;NEITHER LESS-THAN NOR GREATER-THAN;Sm;0;ON;2276 0338;;;;Y;NEITHER LESS THAN NOR GREATER THAN;;;;\n2279;NEITHER GREATER-THAN NOR LESS-THAN;Sm;0;ON;2277 0338;;;;Y;NEITHER GREATER THAN NOR LESS THAN;;;;\n227A;PRECEDES;Sm;0;ON;;;;;Y;;;;;\n227B;SUCCEEDS;Sm;0;ON;;;;;Y;;;;;\n227C;PRECEDES OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n227D;SUCCEEDS OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n227E;PRECEDES OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;\n227F;SUCCEEDS OR EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;\n2280;DOES NOT PRECEDE;Sm;0;ON;227A 0338;;;;Y;;;;;\n2281;DOES NOT SUCCEED;Sm;0;ON;227B 0338;;;;Y;;;;;\n2282;SUBSET OF;Sm;0;ON;;;;;Y;;;;;\n2283;SUPERSET OF;Sm;0;ON;;;;;Y;;;;;\n2284;NOT A SUBSET OF;Sm;0;ON;2282 0338;;;;Y;;;;;\n2285;NOT A SUPERSET OF;Sm;0;ON;2283 0338;;;;Y;;;;;\n2286;SUBSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2287;SUPERSET OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2288;NEITHER A SUBSET OF NOR EQUAL TO;Sm;0;ON;2286 0338;;;;Y;;;;;\n2289;NEITHER A SUPERSET OF NOR EQUAL TO;Sm;0;ON;2287 0338;;;;Y;;;;;\n228A;SUBSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUBSET OF OR NOT EQUAL TO;;;;\n228B;SUPERSET OF WITH NOT EQUAL TO;Sm;0;ON;;;;;Y;SUPERSET OF OR NOT EQUAL TO;;;;\n228C;MULTISET;Sm;0;ON;;;;;Y;;;;;\n228D;MULTISET MULTIPLICATION;Sm;0;ON;;;;;N;;;;;\n228E;MULTISET UNION;Sm;0;ON;;;;;N;;;;;\n228F;SQUARE IMAGE OF;Sm;0;ON;;;;;Y;;;;;\n2290;SQUARE ORIGINAL OF;Sm;0;ON;;;;;Y;;;;;\n2291;SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2292;SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2293;SQUARE CAP;Sm;0;ON;;;;;N;;;;;\n2294;SQUARE CUP;Sm;0;ON;;;;;N;;;;;\n2295;CIRCLED PLUS;Sm;0;ON;;;;;N;;;;;\n2296;CIRCLED MINUS;Sm;0;ON;;;;;N;;;;;\n2297;CIRCLED TIMES;Sm;0;ON;;;;;N;;;;;\n2298;CIRCLED DIVISION SLASH;Sm;0;ON;;;;;Y;;;;;\n2299;CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;;\n229A;CIRCLED RING OPERATOR;Sm;0;ON;;;;;N;;;;;\n229B;CIRCLED ASTERISK OPERATOR;Sm;0;ON;;;;;N;;;;;\n229C;CIRCLED EQUALS;Sm;0;ON;;;;;N;;;;;\n229D;CIRCLED DASH;Sm;0;ON;;;;;N;;;;;\n229E;SQUARED PLUS;Sm;0;ON;;;;;N;;;;;\n229F;SQUARED MINUS;Sm;0;ON;;;;;N;;;;;\n22A0;SQUARED TIMES;Sm;0;ON;;;;;N;;;;;\n22A1;SQUARED DOT OPERATOR;Sm;0;ON;;;;;N;;;;;\n22A2;RIGHT TACK;Sm;0;ON;;;;;Y;;;;;\n22A3;LEFT TACK;Sm;0;ON;;;;;Y;;;;;\n22A4;DOWN TACK;Sm;0;ON;;;;;N;;;;;\n22A5;UP TACK;Sm;0;ON;;;;;N;;;;;\n22A6;ASSERTION;Sm;0;ON;;;;;Y;;;;;\n22A7;MODELS;Sm;0;ON;;;;;Y;;;;;\n22A8;TRUE;Sm;0;ON;;;;;Y;;;;;\n22A9;FORCES;Sm;0;ON;;;;;Y;;;;;\n22AA;TRIPLE VERTICAL BAR RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;;\n22AB;DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;;\n22AC;DOES NOT PROVE;Sm;0;ON;22A2 0338;;;;Y;;;;;\n22AD;NOT TRUE;Sm;0;ON;22A8 0338;;;;Y;;;;;\n22AE;DOES NOT FORCE;Sm;0;ON;22A9 0338;;;;Y;;;;;\n22AF;NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE;Sm;0;ON;22AB 0338;;;;Y;;;;;\n22B0;PRECEDES UNDER RELATION;Sm;0;ON;;;;;Y;;;;;\n22B1;SUCCEEDS UNDER RELATION;Sm;0;ON;;;;;Y;;;;;\n22B2;NORMAL SUBGROUP OF;Sm;0;ON;;;;;Y;;;;;\n22B3;CONTAINS AS NORMAL SUBGROUP;Sm;0;ON;;;;;Y;;;;;\n22B4;NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n22B5;CONTAINS AS NORMAL SUBGROUP OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n22B6;ORIGINAL OF;Sm;0;ON;;;;;Y;;;;;\n22B7;IMAGE OF;Sm;0;ON;;;;;Y;;;;;\n22B8;MULTIMAP;Sm;0;ON;;;;;Y;;;;;\n22B9;HERMITIAN CONJUGATE MATRIX;Sm;0;ON;;;;;N;;;;;\n22BA;INTERCALATE;Sm;0;ON;;;;;N;;;;;\n22BB;XOR;Sm;0;ON;;;;;N;;;;;\n22BC;NAND;Sm;0;ON;;;;;N;;;;;\n22BD;NOR;Sm;0;ON;;;;;N;;;;;\n22BE;RIGHT ANGLE WITH ARC;Sm;0;ON;;;;;Y;;;;;\n22BF;RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;;\n22C0;N-ARY LOGICAL AND;Sm;0;ON;;;;;N;;;;;\n22C1;N-ARY LOGICAL OR;Sm;0;ON;;;;;N;;;;;\n22C2;N-ARY INTERSECTION;Sm;0;ON;;;;;N;;;;;\n22C3;N-ARY UNION;Sm;0;ON;;;;;N;;;;;\n22C4;DIAMOND OPERATOR;Sm;0;ON;;;;;N;;;;;\n22C5;DOT OPERATOR;Sm;0;ON;;;;;N;;;;;\n22C6;STAR OPERATOR;Sm;0;ON;;;;;N;;;;;\n22C7;DIVISION TIMES;Sm;0;ON;;;;;N;;;;;\n22C8;BOWTIE;Sm;0;ON;;;;;N;;;;;\n22C9;LEFT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;\n22CA;RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;\n22CB;LEFT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;\n22CC;RIGHT SEMIDIRECT PRODUCT;Sm;0;ON;;;;;Y;;;;;\n22CD;REVERSED TILDE EQUALS;Sm;0;ON;;;;;Y;;;;;\n22CE;CURLY LOGICAL OR;Sm;0;ON;;;;;N;;;;;\n22CF;CURLY LOGICAL AND;Sm;0;ON;;;;;N;;;;;\n22D0;DOUBLE SUBSET;Sm;0;ON;;;;;Y;;;;;\n22D1;DOUBLE SUPERSET;Sm;0;ON;;;;;Y;;;;;\n22D2;DOUBLE INTERSECTION;Sm;0;ON;;;;;N;;;;;\n22D3;DOUBLE UNION;Sm;0;ON;;;;;N;;;;;\n22D4;PITCHFORK;Sm;0;ON;;;;;N;;;;;\n22D5;EQUAL AND PARALLEL TO;Sm;0;ON;;;;;N;;;;;\n22D6;LESS-THAN WITH DOT;Sm;0;ON;;;;;Y;LESS THAN WITH DOT;;;;\n22D7;GREATER-THAN WITH DOT;Sm;0;ON;;;;;Y;GREATER THAN WITH DOT;;;;\n22D8;VERY MUCH LESS-THAN;Sm;0;ON;;;;;Y;VERY MUCH LESS THAN;;;;\n22D9;VERY MUCH GREATER-THAN;Sm;0;ON;;;;;Y;VERY MUCH GREATER THAN;;;;\n22DA;LESS-THAN EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;LESS THAN EQUAL TO OR GREATER THAN;;;;\n22DB;GREATER-THAN EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;GREATER THAN EQUAL TO OR LESS THAN;;;;\n22DC;EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR LESS THAN;;;;\n22DD;EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;EQUAL TO OR GREATER THAN;;;;\n22DE;EQUAL TO OR PRECEDES;Sm;0;ON;;;;;Y;;;;;\n22DF;EQUAL TO OR SUCCEEDS;Sm;0;ON;;;;;Y;;;;;\n22E0;DOES NOT PRECEDE OR EQUAL;Sm;0;ON;227C 0338;;;;Y;;;;;\n22E1;DOES NOT SUCCEED OR EQUAL;Sm;0;ON;227D 0338;;;;Y;;;;;\n22E2;NOT SQUARE IMAGE OF OR EQUAL TO;Sm;0;ON;2291 0338;;;;Y;;;;;\n22E3;NOT SQUARE ORIGINAL OF OR EQUAL TO;Sm;0;ON;2292 0338;;;;Y;;;;;\n22E4;SQUARE IMAGE OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n22E5;SQUARE ORIGINAL OF OR NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n22E6;LESS-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;LESS THAN BUT NOT EQUIVALENT TO;;;;\n22E7;GREATER-THAN BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;GREATER THAN BUT NOT EQUIVALENT TO;;;;\n22E8;PRECEDES BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;\n22E9;SUCCEEDS BUT NOT EQUIVALENT TO;Sm;0;ON;;;;;Y;;;;;\n22EA;NOT NORMAL SUBGROUP OF;Sm;0;ON;22B2 0338;;;;Y;;;;;\n22EB;DOES NOT CONTAIN AS NORMAL SUBGROUP;Sm;0;ON;22B3 0338;;;;Y;;;;;\n22EC;NOT NORMAL SUBGROUP OF OR EQUAL TO;Sm;0;ON;22B4 0338;;;;Y;;;;;\n22ED;DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL;Sm;0;ON;22B5 0338;;;;Y;;;;;\n22EE;VERTICAL ELLIPSIS;Sm;0;ON;;;;;N;;;;;\n22EF;MIDLINE HORIZONTAL ELLIPSIS;Sm;0;ON;;;;;N;;;;;\n22F0;UP RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;;\n22F1;DOWN RIGHT DIAGONAL ELLIPSIS;Sm;0;ON;;;;;Y;;;;;\n22F2;ELEMENT OF WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;\n22F3;ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;\n22F4;SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;\n22F5;ELEMENT OF WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;\n22F6;ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;\n22F7;SMALL ELEMENT OF WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;\n22F8;ELEMENT OF WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;\n22F9;ELEMENT OF WITH TWO HORIZONTAL STROKES;Sm;0;ON;;;;;Y;;;;;\n22FA;CONTAINS WITH LONG HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;\n22FB;CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;\n22FC;SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;\n22FD;CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;\n22FE;SMALL CONTAINS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;\n22FF;Z NOTATION BAG MEMBERSHIP;Sm;0;ON;;;;;Y;;;;;\n2300;DIAMETER SIGN;So;0;ON;;;;;N;;;;;\n2301;ELECTRIC ARROW;So;0;ON;;;;;N;;;;;\n2302;HOUSE;So;0;ON;;;;;N;;;;;\n2303;UP ARROWHEAD;So;0;ON;;;;;N;;;;;\n2304;DOWN ARROWHEAD;So;0;ON;;;;;N;;;;;\n2305;PROJECTIVE;So;0;ON;;;;;N;;;;;\n2306;PERSPECTIVE;So;0;ON;;;;;N;;;;;\n2307;WAVY LINE;So;0;ON;;;;;N;;;;;\n2308;LEFT CEILING;Ps;0;ON;;;;;Y;;;;;\n2309;RIGHT CEILING;Pe;0;ON;;;;;Y;;;;;\n230A;LEFT FLOOR;Ps;0;ON;;;;;Y;;;;;\n230B;RIGHT FLOOR;Pe;0;ON;;;;;Y;;;;;\n230C;BOTTOM RIGHT CROP;So;0;ON;;;;;N;;;;;\n230D;BOTTOM LEFT CROP;So;0;ON;;;;;N;;;;;\n230E;TOP RIGHT CROP;So;0;ON;;;;;N;;;;;\n230F;TOP LEFT CROP;So;0;ON;;;;;N;;;;;\n2310;REVERSED NOT SIGN;So;0;ON;;;;;N;;;;;\n2311;SQUARE LOZENGE;So;0;ON;;;;;N;;;;;\n2312;ARC;So;0;ON;;;;;N;;;;;\n2313;SEGMENT;So;0;ON;;;;;N;;;;;\n2314;SECTOR;So;0;ON;;;;;N;;;;;\n2315;TELEPHONE RECORDER;So;0;ON;;;;;N;;;;;\n2316;POSITION INDICATOR;So;0;ON;;;;;N;;;;;\n2317;VIEWDATA SQUARE;So;0;ON;;;;;N;;;;;\n2318;PLACE OF INTEREST SIGN;So;0;ON;;;;;N;COMMAND KEY;;;;\n2319;TURNED NOT SIGN;So;0;ON;;;;;N;;;;;\n231A;WATCH;So;0;ON;;;;;N;;;;;\n231B;HOURGLASS;So;0;ON;;;;;N;;;;;\n231C;TOP LEFT CORNER;So;0;ON;;;;;N;;;;;\n231D;TOP RIGHT CORNER;So;0;ON;;;;;N;;;;;\n231E;BOTTOM LEFT CORNER;So;0;ON;;;;;N;;;;;\n231F;BOTTOM RIGHT CORNER;So;0;ON;;;;;N;;;;;\n2320;TOP HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;;\n2321;BOTTOM HALF INTEGRAL;Sm;0;ON;;;;;Y;;;;;\n2322;FROWN;So;0;ON;;;;;N;;;;;\n2323;SMILE;So;0;ON;;;;;N;;;;;\n2324;UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS;So;0;ON;;;;;N;ENTER KEY;;;;\n2325;OPTION KEY;So;0;ON;;;;;N;;;;;\n2326;ERASE TO THE RIGHT;So;0;ON;;;;;N;DELETE TO THE RIGHT KEY;;;;\n2327;X IN A RECTANGLE BOX;So;0;ON;;;;;N;CLEAR KEY;;;;\n2328;KEYBOARD;So;0;ON;;;;;N;;;;;\n2329;LEFT-POINTING ANGLE BRACKET;Ps;0;ON;3008;;;;Y;BRA;;;;\n232A;RIGHT-POINTING ANGLE BRACKET;Pe;0;ON;3009;;;;Y;KET;;;;\n232B;ERASE TO THE LEFT;So;0;ON;;;;;N;DELETE TO THE LEFT KEY;;;;\n232C;BENZENE RING;So;0;ON;;;;;N;;;;;\n232D;CYLINDRICITY;So;0;ON;;;;;N;;;;;\n232E;ALL AROUND-PROFILE;So;0;ON;;;;;N;;;;;\n232F;SYMMETRY;So;0;ON;;;;;N;;;;;\n2330;TOTAL RUNOUT;So;0;ON;;;;;N;;;;;\n2331;DIMENSION ORIGIN;So;0;ON;;;;;N;;;;;\n2332;CONICAL TAPER;So;0;ON;;;;;N;;;;;\n2333;SLOPE;So;0;ON;;;;;N;;;;;\n2334;COUNTERBORE;So;0;ON;;;;;N;;;;;\n2335;COUNTERSINK;So;0;ON;;;;;N;;;;;\n2336;APL FUNCTIONAL SYMBOL I-BEAM;So;0;L;;;;;N;;;;;\n2337;APL FUNCTIONAL SYMBOL SQUISH QUAD;So;0;L;;;;;N;;;;;\n2338;APL FUNCTIONAL SYMBOL QUAD EQUAL;So;0;L;;;;;N;;;;;\n2339;APL FUNCTIONAL SYMBOL QUAD DIVIDE;So;0;L;;;;;N;;;;;\n233A;APL FUNCTIONAL SYMBOL QUAD DIAMOND;So;0;L;;;;;N;;;;;\n233B;APL FUNCTIONAL SYMBOL QUAD JOT;So;0;L;;;;;N;;;;;\n233C;APL FUNCTIONAL SYMBOL QUAD CIRCLE;So;0;L;;;;;N;;;;;\n233D;APL FUNCTIONAL SYMBOL CIRCLE STILE;So;0;L;;;;;N;;;;;\n233E;APL FUNCTIONAL SYMBOL CIRCLE JOT;So;0;L;;;;;N;;;;;\n233F;APL FUNCTIONAL SYMBOL SLASH BAR;So;0;L;;;;;N;;;;;\n2340;APL FUNCTIONAL SYMBOL BACKSLASH BAR;So;0;L;;;;;N;;;;;\n2341;APL FUNCTIONAL SYMBOL QUAD SLASH;So;0;L;;;;;N;;;;;\n2342;APL FUNCTIONAL SYMBOL QUAD BACKSLASH;So;0;L;;;;;N;;;;;\n2343;APL FUNCTIONAL SYMBOL QUAD LESS-THAN;So;0;L;;;;;N;;;;;\n2344;APL FUNCTIONAL SYMBOL QUAD GREATER-THAN;So;0;L;;;;;N;;;;;\n2345;APL FUNCTIONAL SYMBOL LEFTWARDS VANE;So;0;L;;;;;N;;;;;\n2346;APL FUNCTIONAL SYMBOL RIGHTWARDS VANE;So;0;L;;;;;N;;;;;\n2347;APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW;So;0;L;;;;;N;;;;;\n2348;APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW;So;0;L;;;;;N;;;;;\n2349;APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH;So;0;L;;;;;N;;;;;\n234A;APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR;So;0;L;;;;;N;;;;;\n234B;APL FUNCTIONAL SYMBOL DELTA STILE;So;0;L;;;;;N;;;;;\n234C;APL FUNCTIONAL SYMBOL QUAD DOWN CARET;So;0;L;;;;;N;;;;;\n234D;APL FUNCTIONAL SYMBOL QUAD DELTA;So;0;L;;;;;N;;;;;\n234E;APL FUNCTIONAL SYMBOL DOWN TACK JOT;So;0;L;;;;;N;;;;;\n234F;APL FUNCTIONAL SYMBOL UPWARDS VANE;So;0;L;;;;;N;;;;;\n2350;APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW;So;0;L;;;;;N;;;;;\n2351;APL FUNCTIONAL SYMBOL UP TACK OVERBAR;So;0;L;;;;;N;;;;;\n2352;APL FUNCTIONAL SYMBOL DEL STILE;So;0;L;;;;;N;;;;;\n2353;APL FUNCTIONAL SYMBOL QUAD UP CARET;So;0;L;;;;;N;;;;;\n2354;APL FUNCTIONAL SYMBOL QUAD DEL;So;0;L;;;;;N;;;;;\n2355;APL FUNCTIONAL SYMBOL UP TACK JOT;So;0;L;;;;;N;;;;;\n2356;APL FUNCTIONAL SYMBOL DOWNWARDS VANE;So;0;L;;;;;N;;;;;\n2357;APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW;So;0;L;;;;;N;;;;;\n2358;APL FUNCTIONAL SYMBOL QUOTE UNDERBAR;So;0;L;;;;;N;;;;;\n2359;APL FUNCTIONAL SYMBOL DELTA UNDERBAR;So;0;L;;;;;N;;;;;\n235A;APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR;So;0;L;;;;;N;;;;;\n235B;APL FUNCTIONAL SYMBOL JOT UNDERBAR;So;0;L;;;;;N;;;;;\n235C;APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR;So;0;L;;;;;N;;;;;\n235D;APL FUNCTIONAL SYMBOL UP SHOE JOT;So;0;L;;;;;N;;;;;\n235E;APL FUNCTIONAL SYMBOL QUOTE QUAD;So;0;L;;;;;N;;;;;\n235F;APL FUNCTIONAL SYMBOL CIRCLE STAR;So;0;L;;;;;N;;;;;\n2360;APL FUNCTIONAL SYMBOL QUAD COLON;So;0;L;;;;;N;;;;;\n2361;APL FUNCTIONAL SYMBOL UP TACK DIAERESIS;So;0;L;;;;;N;;;;;\n2362;APL FUNCTIONAL SYMBOL DEL DIAERESIS;So;0;L;;;;;N;;;;;\n2363;APL FUNCTIONAL SYMBOL STAR DIAERESIS;So;0;L;;;;;N;;;;;\n2364;APL FUNCTIONAL SYMBOL JOT DIAERESIS;So;0;L;;;;;N;;;;;\n2365;APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS;So;0;L;;;;;N;;;;;\n2366;APL FUNCTIONAL SYMBOL DOWN SHOE STILE;So;0;L;;;;;N;;;;;\n2367;APL FUNCTIONAL SYMBOL LEFT SHOE STILE;So;0;L;;;;;N;;;;;\n2368;APL FUNCTIONAL SYMBOL TILDE DIAERESIS;So;0;L;;;;;N;;;;;\n2369;APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS;So;0;L;;;;;N;;;;;\n236A;APL FUNCTIONAL SYMBOL COMMA BAR;So;0;L;;;;;N;;;;;\n236B;APL FUNCTIONAL SYMBOL DEL TILDE;So;0;L;;;;;N;;;;;\n236C;APL FUNCTIONAL SYMBOL ZILDE;So;0;L;;;;;N;;;;;\n236D;APL FUNCTIONAL SYMBOL STILE TILDE;So;0;L;;;;;N;;;;;\n236E;APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR;So;0;L;;;;;N;;;;;\n236F;APL FUNCTIONAL SYMBOL QUAD NOT EQUAL;So;0;L;;;;;N;;;;;\n2370;APL FUNCTIONAL SYMBOL QUAD QUESTION;So;0;L;;;;;N;;;;;\n2371;APL FUNCTIONAL SYMBOL DOWN CARET TILDE;So;0;L;;;;;N;;;;;\n2372;APL FUNCTIONAL SYMBOL UP CARET TILDE;So;0;L;;;;;N;;;;;\n2373;APL FUNCTIONAL SYMBOL IOTA;So;0;L;;;;;N;;;;;\n2374;APL FUNCTIONAL SYMBOL RHO;So;0;L;;;;;N;;;;;\n2375;APL FUNCTIONAL SYMBOL OMEGA;So;0;L;;;;;N;;;;;\n2376;APL FUNCTIONAL SYMBOL ALPHA UNDERBAR;So;0;L;;;;;N;;;;;\n2377;APL FUNCTIONAL SYMBOL EPSILON UNDERBAR;So;0;L;;;;;N;;;;;\n2378;APL FUNCTIONAL SYMBOL IOTA UNDERBAR;So;0;L;;;;;N;;;;;\n2379;APL FUNCTIONAL SYMBOL OMEGA UNDERBAR;So;0;L;;;;;N;;;;;\n237A;APL FUNCTIONAL SYMBOL ALPHA;So;0;L;;;;;N;;;;;\n237B;NOT CHECK MARK;So;0;ON;;;;;N;;;;;\n237C;RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW;Sm;0;ON;;;;;N;;;;;\n237D;SHOULDERED OPEN BOX;So;0;ON;;;;;N;;;;;\n237E;BELL SYMBOL;So;0;ON;;;;;N;;;;;\n237F;VERTICAL LINE WITH MIDDLE DOT;So;0;ON;;;;;N;;;;;\n2380;INSERTION SYMBOL;So;0;ON;;;;;N;;;;;\n2381;CONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;;\n2382;DISCONTINUOUS UNDERLINE SYMBOL;So;0;ON;;;;;N;;;;;\n2383;EMPHASIS SYMBOL;So;0;ON;;;;;N;;;;;\n2384;COMPOSITION SYMBOL;So;0;ON;;;;;N;;;;;\n2385;WHITE SQUARE WITH CENTRE VERTICAL LINE;So;0;ON;;;;;N;;;;;\n2386;ENTER SYMBOL;So;0;ON;;;;;N;;;;;\n2387;ALTERNATIVE KEY SYMBOL;So;0;ON;;;;;N;;;;;\n2388;HELM SYMBOL;So;0;ON;;;;;N;;;;;\n2389;CIRCLED HORIZONTAL BAR WITH NOTCH;So;0;ON;;;;;N;;;;;\n238A;CIRCLED TRIANGLE DOWN;So;0;ON;;;;;N;;;;;\n238B;BROKEN CIRCLE WITH NORTHWEST ARROW;So;0;ON;;;;;N;;;;;\n238C;UNDO SYMBOL;So;0;ON;;;;;N;;;;;\n238D;MONOSTABLE SYMBOL;So;0;ON;;;;;N;;;;;\n238E;HYSTERESIS SYMBOL;So;0;ON;;;;;N;;;;;\n238F;OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL;So;0;ON;;;;;N;;;;;\n2390;OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL;So;0;ON;;;;;N;;;;;\n2391;PASSIVE-PULL-DOWN-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;;\n2392;PASSIVE-PULL-UP-OUTPUT SYMBOL;So;0;ON;;;;;N;;;;;\n2393;DIRECT CURRENT SYMBOL FORM TWO;So;0;ON;;;;;N;;;;;\n2394;SOFTWARE-FUNCTION SYMBOL;So;0;ON;;;;;N;;;;;\n2395;APL FUNCTIONAL SYMBOL QUAD;So;0;L;;;;;N;;;;;\n2396;DECIMAL SEPARATOR KEY SYMBOL;So;0;ON;;;;;N;;;;;\n2397;PREVIOUS PAGE;So;0;ON;;;;;N;;;;;\n2398;NEXT PAGE;So;0;ON;;;;;N;;;;;\n2399;PRINT SCREEN SYMBOL;So;0;ON;;;;;N;;;;;\n239A;CLEAR SCREEN SYMBOL;So;0;ON;;;;;N;;;;;\n239B;LEFT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;;\n239C;LEFT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;;\n239D;LEFT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;;\n239E;RIGHT PARENTHESIS UPPER HOOK;Sm;0;ON;;;;;N;;;;;\n239F;RIGHT PARENTHESIS EXTENSION;Sm;0;ON;;;;;N;;;;;\n23A0;RIGHT PARENTHESIS LOWER HOOK;Sm;0;ON;;;;;N;;;;;\n23A1;LEFT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;;\n23A2;LEFT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;;\n23A3;LEFT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;;\n23A4;RIGHT SQUARE BRACKET UPPER CORNER;Sm;0;ON;;;;;N;;;;;\n23A5;RIGHT SQUARE BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;;\n23A6;RIGHT SQUARE BRACKET LOWER CORNER;Sm;0;ON;;;;;N;;;;;\n23A7;LEFT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;;\n23A8;LEFT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;;\n23A9;LEFT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;;\n23AA;CURLY BRACKET EXTENSION;Sm;0;ON;;;;;N;;;;;\n23AB;RIGHT CURLY BRACKET UPPER HOOK;Sm;0;ON;;;;;N;;;;;\n23AC;RIGHT CURLY BRACKET MIDDLE PIECE;Sm;0;ON;;;;;N;;;;;\n23AD;RIGHT CURLY BRACKET LOWER HOOK;Sm;0;ON;;;;;N;;;;;\n23AE;INTEGRAL EXTENSION;Sm;0;ON;;;;;N;;;;;\n23AF;HORIZONTAL LINE EXTENSION;Sm;0;ON;;;;;N;;;;;\n23B0;UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;;\n23B1;UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION;Sm;0;ON;;;;;N;;;;;\n23B2;SUMMATION TOP;Sm;0;ON;;;;;N;;;;;\n23B3;SUMMATION BOTTOM;Sm;0;ON;;;;;N;;;;;\n23B4;TOP SQUARE BRACKET;So;0;ON;;;;;N;;;;;\n23B5;BOTTOM SQUARE BRACKET;So;0;ON;;;;;N;;;;;\n23B6;BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET;So;0;ON;;;;;N;;;;;\n23B7;RADICAL SYMBOL BOTTOM;So;0;ON;;;;;N;;;;;\n23B8;LEFT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;;\n23B9;RIGHT VERTICAL BOX LINE;So;0;ON;;;;;N;;;;;\n23BA;HORIZONTAL SCAN LINE-1;So;0;ON;;;;;N;;;;;\n23BB;HORIZONTAL SCAN LINE-3;So;0;ON;;;;;N;;;;;\n23BC;HORIZONTAL SCAN LINE-7;So;0;ON;;;;;N;;;;;\n23BD;HORIZONTAL SCAN LINE-9;So;0;ON;;;;;N;;;;;\n23BE;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT;So;0;ON;;;;;N;;;;;\n23BF;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT;So;0;ON;;;;;N;;;;;\n23C0;DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE;So;0;ON;;;;;N;;;;;\n23C1;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;;\n23C2;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE;So;0;ON;;;;;N;;;;;\n23C3;DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE;So;0;ON;;;;;N;;;;;\n23C4;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;;\n23C5;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE;So;0;ON;;;;;N;;;;;\n23C6;DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE;So;0;ON;;;;;N;;;;;\n23C7;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;;\n23C8;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE;So;0;ON;;;;;N;;;;;\n23C9;DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;;;;;\n23CA;DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;;;;;\n23CB;DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT;So;0;ON;;;;;N;;;;;\n23CC;DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT;So;0;ON;;;;;N;;;;;\n23CD;SQUARE FOOT;So;0;ON;;;;;N;;;;;\n23CE;RETURN SYMBOL;So;0;ON;;;;;N;;;;;\n23CF;EJECT SYMBOL;So;0;ON;;;;;N;;;;;\n23D0;VERTICAL LINE EXTENSION;So;0;ON;;;;;N;;;;;\n23D1;METRICAL BREVE;So;0;ON;;;;;N;;;;;\n23D2;METRICAL LONG OVER SHORT;So;0;ON;;;;;N;;;;;\n23D3;METRICAL SHORT OVER LONG;So;0;ON;;;;;N;;;;;\n23D4;METRICAL LONG OVER TWO SHORTS;So;0;ON;;;;;N;;;;;\n23D5;METRICAL TWO SHORTS OVER LONG;So;0;ON;;;;;N;;;;;\n23D6;METRICAL TWO SHORTS JOINED;So;0;ON;;;;;N;;;;;\n23D7;METRICAL TRISEME;So;0;ON;;;;;N;;;;;\n23D8;METRICAL TETRASEME;So;0;ON;;;;;N;;;;;\n23D9;METRICAL PENTASEME;So;0;ON;;;;;N;;;;;\n23DA;EARTH GROUND;So;0;ON;;;;;N;;;;;\n23DB;FUSE;So;0;ON;;;;;N;;;;;\n23DC;TOP PARENTHESIS;Sm;0;ON;;;;;N;;;;;\n23DD;BOTTOM PARENTHESIS;Sm;0;ON;;;;;N;;;;;\n23DE;TOP CURLY BRACKET;Sm;0;ON;;;;;N;;;;;\n23DF;BOTTOM CURLY BRACKET;Sm;0;ON;;;;;N;;;;;\n23E0;TOP TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;;;;\n23E1;BOTTOM TORTOISE SHELL BRACKET;Sm;0;ON;;;;;N;;;;;\n23E2;WHITE TRAPEZIUM;So;0;ON;;;;;N;;;;;\n23E3;BENZENE RING WITH CIRCLE;So;0;ON;;;;;N;;;;;\n23E4;STRAIGHTNESS;So;0;ON;;;;;N;;;;;\n23E5;FLATNESS;So;0;ON;;;;;N;;;;;\n23E6;AC CURRENT;So;0;ON;;;;;N;;;;;\n23E7;ELECTRICAL INTERSECTION;So;0;ON;;;;;N;;;;;\n23E8;DECIMAL EXPONENT SYMBOL;So;0;ON;;;;;N;;;;;\n23E9;BLACK RIGHT-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;\n23EA;BLACK LEFT-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;\n23EB;BLACK UP-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;\n23EC;BLACK DOWN-POINTING DOUBLE TRIANGLE;So;0;ON;;;;;N;;;;;\n23ED;BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR;So;0;ON;;;;;N;;;;;\n23EE;BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR;So;0;ON;;;;;N;;;;;\n23EF;BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR;So;0;ON;;;;;N;;;;;\n23F0;ALARM CLOCK;So;0;ON;;;;;N;;;;;\n23F1;STOPWATCH;So;0;ON;;;;;N;;;;;\n23F2;TIMER CLOCK;So;0;ON;;;;;N;;;;;\n23F3;HOURGLASS WITH FLOWING SAND;So;0;ON;;;;;N;;;;;\n23F4;BLACK MEDIUM LEFT-POINTING TRIANGLE;So;0;ON;;;;;N;;;;;\n23F5;BLACK MEDIUM RIGHT-POINTING TRIANGLE;So;0;ON;;;;;N;;;;;\n23F6;BLACK MEDIUM UP-POINTING TRIANGLE;So;0;ON;;;;;N;;;;;\n23F7;BLACK MEDIUM DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;;;;;\n23F8;DOUBLE VERTICAL BAR;So;0;ON;;;;;N;;;;;\n23F9;BLACK SQUARE FOR STOP;So;0;ON;;;;;N;;;;;\n23FA;BLACK CIRCLE FOR RECORD;So;0;ON;;;;;N;;;;;\n23FB;POWER SYMBOL;So;0;ON;;;;;N;;;;;\n23FC;POWER ON-OFF SYMBOL;So;0;ON;;;;;N;;;;;\n23FD;POWER ON SYMBOL;So;0;ON;;;;;N;;;;;\n23FE;POWER SLEEP SYMBOL;So;0;ON;;;;;N;;;;;\n23FF;OBSERVER EYE SYMBOL;So;0;ON;;;;;N;;;;;\n2400;SYMBOL FOR NULL;So;0;ON;;;;;N;GRAPHIC FOR NULL;;;;\n2401;SYMBOL FOR START OF HEADING;So;0;ON;;;;;N;GRAPHIC FOR START OF HEADING;;;;\n2402;SYMBOL FOR START OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR START OF TEXT;;;;\n2403;SYMBOL FOR END OF TEXT;So;0;ON;;;;;N;GRAPHIC FOR END OF TEXT;;;;\n2404;SYMBOL FOR END OF TRANSMISSION;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION;;;;\n2405;SYMBOL FOR ENQUIRY;So;0;ON;;;;;N;GRAPHIC FOR ENQUIRY;;;;\n2406;SYMBOL FOR ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR ACKNOWLEDGE;;;;\n2407;SYMBOL FOR BELL;So;0;ON;;;;;N;GRAPHIC FOR BELL;;;;\n2408;SYMBOL FOR BACKSPACE;So;0;ON;;;;;N;GRAPHIC FOR BACKSPACE;;;;\n2409;SYMBOL FOR HORIZONTAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR HORIZONTAL TABULATION;;;;\n240A;SYMBOL FOR LINE FEED;So;0;ON;;;;;N;GRAPHIC FOR LINE FEED;;;;\n240B;SYMBOL FOR VERTICAL TABULATION;So;0;ON;;;;;N;GRAPHIC FOR VERTICAL TABULATION;;;;\n240C;SYMBOL FOR FORM FEED;So;0;ON;;;;;N;GRAPHIC FOR FORM FEED;;;;\n240D;SYMBOL FOR CARRIAGE RETURN;So;0;ON;;;;;N;GRAPHIC FOR CARRIAGE RETURN;;;;\n240E;SYMBOL FOR SHIFT OUT;So;0;ON;;;;;N;GRAPHIC FOR SHIFT OUT;;;;\n240F;SYMBOL FOR SHIFT IN;So;0;ON;;;;;N;GRAPHIC FOR SHIFT IN;;;;\n2410;SYMBOL FOR DATA LINK ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR DATA LINK ESCAPE;;;;\n2411;SYMBOL FOR DEVICE CONTROL ONE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL ONE;;;;\n2412;SYMBOL FOR DEVICE CONTROL TWO;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL TWO;;;;\n2413;SYMBOL FOR DEVICE CONTROL THREE;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL THREE;;;;\n2414;SYMBOL FOR DEVICE CONTROL FOUR;So;0;ON;;;;;N;GRAPHIC FOR DEVICE CONTROL FOUR;;;;\n2415;SYMBOL FOR NEGATIVE ACKNOWLEDGE;So;0;ON;;;;;N;GRAPHIC FOR NEGATIVE ACKNOWLEDGE;;;;\n2416;SYMBOL FOR SYNCHRONOUS IDLE;So;0;ON;;;;;N;GRAPHIC FOR SYNCHRONOUS IDLE;;;;\n2417;SYMBOL FOR END OF TRANSMISSION BLOCK;So;0;ON;;;;;N;GRAPHIC FOR END OF TRANSMISSION BLOCK;;;;\n2418;SYMBOL FOR CANCEL;So;0;ON;;;;;N;GRAPHIC FOR CANCEL;;;;\n2419;SYMBOL FOR END OF MEDIUM;So;0;ON;;;;;N;GRAPHIC FOR END OF MEDIUM;;;;\n241A;SYMBOL FOR SUBSTITUTE;So;0;ON;;;;;N;GRAPHIC FOR SUBSTITUTE;;;;\n241B;SYMBOL FOR ESCAPE;So;0;ON;;;;;N;GRAPHIC FOR ESCAPE;;;;\n241C;SYMBOL FOR FILE SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR FILE SEPARATOR;;;;\n241D;SYMBOL FOR GROUP SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR GROUP SEPARATOR;;;;\n241E;SYMBOL FOR RECORD SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR RECORD SEPARATOR;;;;\n241F;SYMBOL FOR UNIT SEPARATOR;So;0;ON;;;;;N;GRAPHIC FOR UNIT SEPARATOR;;;;\n2420;SYMBOL FOR SPACE;So;0;ON;;;;;N;GRAPHIC FOR SPACE;;;;\n2421;SYMBOL FOR DELETE;So;0;ON;;;;;N;GRAPHIC FOR DELETE;;;;\n2422;BLANK SYMBOL;So;0;ON;;;;;N;BLANK;;;;\n2423;OPEN BOX;So;0;ON;;;;;N;;;;;\n2424;SYMBOL FOR NEWLINE;So;0;ON;;;;;N;GRAPHIC FOR NEWLINE;;;;\n2425;SYMBOL FOR DELETE FORM TWO;So;0;ON;;;;;N;;;;;\n2426;SYMBOL FOR SUBSTITUTE FORM TWO;So;0;ON;;;;;N;;;;;\n2440;OCR HOOK;So;0;ON;;;;;N;;;;;\n2441;OCR CHAIR;So;0;ON;;;;;N;;;;;\n2442;OCR FORK;So;0;ON;;;;;N;;;;;\n2443;OCR INVERTED FORK;So;0;ON;;;;;N;;;;;\n2444;OCR BELT BUCKLE;So;0;ON;;;;;N;;;;;\n2445;OCR BOW TIE;So;0;ON;;;;;N;;;;;\n2446;OCR BRANCH BANK IDENTIFICATION;So;0;ON;;;;;N;;;;;\n2447;OCR AMOUNT OF CHECK;So;0;ON;;;;;N;;;;;\n2448;OCR DASH;So;0;ON;;;;;N;;;;;\n2449;OCR CUSTOMER ACCOUNT NUMBER;So;0;ON;;;;;N;;;;;\n244A;OCR DOUBLE BACKSLASH;So;0;ON;;;;;N;;;;;\n2460;CIRCLED DIGIT ONE;No;0;ON;<circle> 0031;;1;1;N;;;;;\n2461;CIRCLED DIGIT TWO;No;0;ON;<circle> 0032;;2;2;N;;;;;\n2462;CIRCLED DIGIT THREE;No;0;ON;<circle> 0033;;3;3;N;;;;;\n2463;CIRCLED DIGIT FOUR;No;0;ON;<circle> 0034;;4;4;N;;;;;\n2464;CIRCLED DIGIT FIVE;No;0;ON;<circle> 0035;;5;5;N;;;;;\n2465;CIRCLED DIGIT SIX;No;0;ON;<circle> 0036;;6;6;N;;;;;\n2466;CIRCLED DIGIT SEVEN;No;0;ON;<circle> 0037;;7;7;N;;;;;\n2467;CIRCLED DIGIT EIGHT;No;0;ON;<circle> 0038;;8;8;N;;;;;\n2468;CIRCLED DIGIT NINE;No;0;ON;<circle> 0039;;9;9;N;;;;;\n2469;CIRCLED NUMBER TEN;No;0;ON;<circle> 0031 0030;;;10;N;;;;;\n246A;CIRCLED NUMBER ELEVEN;No;0;ON;<circle> 0031 0031;;;11;N;;;;;\n246B;CIRCLED NUMBER TWELVE;No;0;ON;<circle> 0031 0032;;;12;N;;;;;\n246C;CIRCLED NUMBER THIRTEEN;No;0;ON;<circle> 0031 0033;;;13;N;;;;;\n246D;CIRCLED NUMBER FOURTEEN;No;0;ON;<circle> 0031 0034;;;14;N;;;;;\n246E;CIRCLED NUMBER FIFTEEN;No;0;ON;<circle> 0031 0035;;;15;N;;;;;\n246F;CIRCLED NUMBER SIXTEEN;No;0;ON;<circle> 0031 0036;;;16;N;;;;;\n2470;CIRCLED NUMBER SEVENTEEN;No;0;ON;<circle> 0031 0037;;;17;N;;;;;\n2471;CIRCLED NUMBER EIGHTEEN;No;0;ON;<circle> 0031 0038;;;18;N;;;;;\n2472;CIRCLED NUMBER NINETEEN;No;0;ON;<circle> 0031 0039;;;19;N;;;;;\n2473;CIRCLED NUMBER TWENTY;No;0;ON;<circle> 0032 0030;;;20;N;;;;;\n2474;PARENTHESIZED DIGIT ONE;No;0;ON;<compat> 0028 0031 0029;;1;1;N;;;;;\n2475;PARENTHESIZED DIGIT TWO;No;0;ON;<compat> 0028 0032 0029;;2;2;N;;;;;\n2476;PARENTHESIZED DIGIT THREE;No;0;ON;<compat> 0028 0033 0029;;3;3;N;;;;;\n2477;PARENTHESIZED DIGIT FOUR;No;0;ON;<compat> 0028 0034 0029;;4;4;N;;;;;\n2478;PARENTHESIZED DIGIT FIVE;No;0;ON;<compat> 0028 0035 0029;;5;5;N;;;;;\n2479;PARENTHESIZED DIGIT SIX;No;0;ON;<compat> 0028 0036 0029;;6;6;N;;;;;\n247A;PARENTHESIZED DIGIT SEVEN;No;0;ON;<compat> 0028 0037 0029;;7;7;N;;;;;\n247B;PARENTHESIZED DIGIT EIGHT;No;0;ON;<compat> 0028 0038 0029;;8;8;N;;;;;\n247C;PARENTHESIZED DIGIT NINE;No;0;ON;<compat> 0028 0039 0029;;9;9;N;;;;;\n247D;PARENTHESIZED NUMBER TEN;No;0;ON;<compat> 0028 0031 0030 0029;;;10;N;;;;;\n247E;PARENTHESIZED NUMBER ELEVEN;No;0;ON;<compat> 0028 0031 0031 0029;;;11;N;;;;;\n247F;PARENTHESIZED NUMBER TWELVE;No;0;ON;<compat> 0028 0031 0032 0029;;;12;N;;;;;\n2480;PARENTHESIZED NUMBER THIRTEEN;No;0;ON;<compat> 0028 0031 0033 0029;;;13;N;;;;;\n2481;PARENTHESIZED NUMBER FOURTEEN;No;0;ON;<compat> 0028 0031 0034 0029;;;14;N;;;;;\n2482;PARENTHESIZED NUMBER FIFTEEN;No;0;ON;<compat> 0028 0031 0035 0029;;;15;N;;;;;\n2483;PARENTHESIZED NUMBER SIXTEEN;No;0;ON;<compat> 0028 0031 0036 0029;;;16;N;;;;;\n2484;PARENTHESIZED NUMBER SEVENTEEN;No;0;ON;<compat> 0028 0031 0037 0029;;;17;N;;;;;\n2485;PARENTHESIZED NUMBER EIGHTEEN;No;0;ON;<compat> 0028 0031 0038 0029;;;18;N;;;;;\n2486;PARENTHESIZED NUMBER NINETEEN;No;0;ON;<compat> 0028 0031 0039 0029;;;19;N;;;;;\n2487;PARENTHESIZED NUMBER TWENTY;No;0;ON;<compat> 0028 0032 0030 0029;;;20;N;;;;;\n2488;DIGIT ONE FULL STOP;No;0;EN;<compat> 0031 002E;;1;1;N;DIGIT ONE PERIOD;;;;\n2489;DIGIT TWO FULL STOP;No;0;EN;<compat> 0032 002E;;2;2;N;DIGIT TWO PERIOD;;;;\n248A;DIGIT THREE FULL STOP;No;0;EN;<compat> 0033 002E;;3;3;N;DIGIT THREE PERIOD;;;;\n248B;DIGIT FOUR FULL STOP;No;0;EN;<compat> 0034 002E;;4;4;N;DIGIT FOUR PERIOD;;;;\n248C;DIGIT FIVE FULL STOP;No;0;EN;<compat> 0035 002E;;5;5;N;DIGIT FIVE PERIOD;;;;\n248D;DIGIT SIX FULL STOP;No;0;EN;<compat> 0036 002E;;6;6;N;DIGIT SIX PERIOD;;;;\n248E;DIGIT SEVEN FULL STOP;No;0;EN;<compat> 0037 002E;;7;7;N;DIGIT SEVEN PERIOD;;;;\n248F;DIGIT EIGHT FULL STOP;No;0;EN;<compat> 0038 002E;;8;8;N;DIGIT EIGHT PERIOD;;;;\n2490;DIGIT NINE FULL STOP;No;0;EN;<compat> 0039 002E;;9;9;N;DIGIT NINE PERIOD;;;;\n2491;NUMBER TEN FULL STOP;No;0;EN;<compat> 0031 0030 002E;;;10;N;NUMBER TEN PERIOD;;;;\n2492;NUMBER ELEVEN FULL STOP;No;0;EN;<compat> 0031 0031 002E;;;11;N;NUMBER ELEVEN PERIOD;;;;\n2493;NUMBER TWELVE FULL STOP;No;0;EN;<compat> 0031 0032 002E;;;12;N;NUMBER TWELVE PERIOD;;;;\n2494;NUMBER THIRTEEN FULL STOP;No;0;EN;<compat> 0031 0033 002E;;;13;N;NUMBER THIRTEEN PERIOD;;;;\n2495;NUMBER FOURTEEN FULL STOP;No;0;EN;<compat> 0031 0034 002E;;;14;N;NUMBER FOURTEEN PERIOD;;;;\n2496;NUMBER FIFTEEN FULL STOP;No;0;EN;<compat> 0031 0035 002E;;;15;N;NUMBER FIFTEEN PERIOD;;;;\n2497;NUMBER SIXTEEN FULL STOP;No;0;EN;<compat> 0031 0036 002E;;;16;N;NUMBER SIXTEEN PERIOD;;;;\n2498;NUMBER SEVENTEEN FULL STOP;No;0;EN;<compat> 0031 0037 002E;;;17;N;NUMBER SEVENTEEN PERIOD;;;;\n2499;NUMBER EIGHTEEN FULL STOP;No;0;EN;<compat> 0031 0038 002E;;;18;N;NUMBER EIGHTEEN PERIOD;;;;\n249A;NUMBER NINETEEN FULL STOP;No;0;EN;<compat> 0031 0039 002E;;;19;N;NUMBER NINETEEN PERIOD;;;;\n249B;NUMBER TWENTY FULL STOP;No;0;EN;<compat> 0032 0030 002E;;;20;N;NUMBER TWENTY PERIOD;;;;\n249C;PARENTHESIZED LATIN SMALL LETTER A;So;0;L;<compat> 0028 0061 0029;;;;N;;;;;\n249D;PARENTHESIZED LATIN SMALL LETTER B;So;0;L;<compat> 0028 0062 0029;;;;N;;;;;\n249E;PARENTHESIZED LATIN SMALL LETTER C;So;0;L;<compat> 0028 0063 0029;;;;N;;;;;\n249F;PARENTHESIZED LATIN SMALL LETTER D;So;0;L;<compat> 0028 0064 0029;;;;N;;;;;\n24A0;PARENTHESIZED LATIN SMALL LETTER E;So;0;L;<compat> 0028 0065 0029;;;;N;;;;;\n24A1;PARENTHESIZED LATIN SMALL LETTER F;So;0;L;<compat> 0028 0066 0029;;;;N;;;;;\n24A2;PARENTHESIZED LATIN SMALL LETTER G;So;0;L;<compat> 0028 0067 0029;;;;N;;;;;\n24A3;PARENTHESIZED LATIN SMALL LETTER H;So;0;L;<compat> 0028 0068 0029;;;;N;;;;;\n24A4;PARENTHESIZED LATIN SMALL LETTER I;So;0;L;<compat> 0028 0069 0029;;;;N;;;;;\n24A5;PARENTHESIZED LATIN SMALL LETTER J;So;0;L;<compat> 0028 006A 0029;;;;N;;;;;\n24A6;PARENTHESIZED LATIN SMALL LETTER K;So;0;L;<compat> 0028 006B 0029;;;;N;;;;;\n24A7;PARENTHESIZED LATIN SMALL LETTER L;So;0;L;<compat> 0028 006C 0029;;;;N;;;;;\n24A8;PARENTHESIZED LATIN SMALL LETTER M;So;0;L;<compat> 0028 006D 0029;;;;N;;;;;\n24A9;PARENTHESIZED LATIN SMALL LETTER N;So;0;L;<compat> 0028 006E 0029;;;;N;;;;;\n24AA;PARENTHESIZED LATIN SMALL LETTER O;So;0;L;<compat> 0028 006F 0029;;;;N;;;;;\n24AB;PARENTHESIZED LATIN SMALL LETTER P;So;0;L;<compat> 0028 0070 0029;;;;N;;;;;\n24AC;PARENTHESIZED LATIN SMALL LETTER Q;So;0;L;<compat> 0028 0071 0029;;;;N;;;;;\n24AD;PARENTHESIZED LATIN SMALL LETTER R;So;0;L;<compat> 0028 0072 0029;;;;N;;;;;\n24AE;PARENTHESIZED LATIN SMALL LETTER S;So;0;L;<compat> 0028 0073 0029;;;;N;;;;;\n24AF;PARENTHESIZED LATIN SMALL LETTER T;So;0;L;<compat> 0028 0074 0029;;;;N;;;;;\n24B0;PARENTHESIZED LATIN SMALL LETTER U;So;0;L;<compat> 0028 0075 0029;;;;N;;;;;\n24B1;PARENTHESIZED LATIN SMALL LETTER V;So;0;L;<compat> 0028 0076 0029;;;;N;;;;;\n24B2;PARENTHESIZED LATIN SMALL LETTER W;So;0;L;<compat> 0028 0077 0029;;;;N;;;;;\n24B3;PARENTHESIZED LATIN SMALL LETTER X;So;0;L;<compat> 0028 0078 0029;;;;N;;;;;\n24B4;PARENTHESIZED LATIN SMALL LETTER Y;So;0;L;<compat> 0028 0079 0029;;;;N;;;;;\n24B5;PARENTHESIZED LATIN SMALL LETTER Z;So;0;L;<compat> 0028 007A 0029;;;;N;;;;;\n24B6;CIRCLED LATIN CAPITAL LETTER A;So;0;L;<circle> 0041;;;;N;;;;24D0;\n24B7;CIRCLED LATIN CAPITAL LETTER B;So;0;L;<circle> 0042;;;;N;;;;24D1;\n24B8;CIRCLED LATIN CAPITAL LETTER C;So;0;L;<circle> 0043;;;;N;;;;24D2;\n24B9;CIRCLED LATIN CAPITAL LETTER D;So;0;L;<circle> 0044;;;;N;;;;24D3;\n24BA;CIRCLED LATIN CAPITAL LETTER E;So;0;L;<circle> 0045;;;;N;;;;24D4;\n24BB;CIRCLED LATIN CAPITAL LETTER F;So;0;L;<circle> 0046;;;;N;;;;24D5;\n24BC;CIRCLED LATIN CAPITAL LETTER G;So;0;L;<circle> 0047;;;;N;;;;24D6;\n24BD;CIRCLED LATIN CAPITAL LETTER H;So;0;L;<circle> 0048;;;;N;;;;24D7;\n24BE;CIRCLED LATIN CAPITAL LETTER I;So;0;L;<circle> 0049;;;;N;;;;24D8;\n24BF;CIRCLED LATIN CAPITAL LETTER J;So;0;L;<circle> 004A;;;;N;;;;24D9;\n24C0;CIRCLED LATIN CAPITAL LETTER K;So;0;L;<circle> 004B;;;;N;;;;24DA;\n24C1;CIRCLED LATIN CAPITAL LETTER L;So;0;L;<circle> 004C;;;;N;;;;24DB;\n24C2;CIRCLED LATIN CAPITAL LETTER M;So;0;L;<circle> 004D;;;;N;;;;24DC;\n24C3;CIRCLED LATIN CAPITAL LETTER N;So;0;L;<circle> 004E;;;;N;;;;24DD;\n24C4;CIRCLED LATIN CAPITAL LETTER O;So;0;L;<circle> 004F;;;;N;;;;24DE;\n24C5;CIRCLED LATIN CAPITAL LETTER P;So;0;L;<circle> 0050;;;;N;;;;24DF;\n24C6;CIRCLED LATIN CAPITAL LETTER Q;So;0;L;<circle> 0051;;;;N;;;;24E0;\n24C7;CIRCLED LATIN CAPITAL LETTER R;So;0;L;<circle> 0052;;;;N;;;;24E1;\n24C8;CIRCLED LATIN CAPITAL LETTER S;So;0;L;<circle> 0053;;;;N;;;;24E2;\n24C9;CIRCLED LATIN CAPITAL LETTER T;So;0;L;<circle> 0054;;;;N;;;;24E3;\n24CA;CIRCLED LATIN CAPITAL LETTER U;So;0;L;<circle> 0055;;;;N;;;;24E4;\n24CB;CIRCLED LATIN CAPITAL LETTER V;So;0;L;<circle> 0056;;;;N;;;;24E5;\n24CC;CIRCLED LATIN CAPITAL LETTER W;So;0;L;<circle> 0057;;;;N;;;;24E6;\n24CD;CIRCLED LATIN CAPITAL LETTER X;So;0;L;<circle> 0058;;;;N;;;;24E7;\n24CE;CIRCLED LATIN CAPITAL LETTER Y;So;0;L;<circle> 0059;;;;N;;;;24E8;\n24CF;CIRCLED LATIN CAPITAL LETTER Z;So;0;L;<circle> 005A;;;;N;;;;24E9;\n24D0;CIRCLED LATIN SMALL LETTER A;So;0;L;<circle> 0061;;;;N;;;24B6;;24B6\n24D1;CIRCLED LATIN SMALL LETTER B;So;0;L;<circle> 0062;;;;N;;;24B7;;24B7\n24D2;CIRCLED LATIN SMALL LETTER C;So;0;L;<circle> 0063;;;;N;;;24B8;;24B8\n24D3;CIRCLED LATIN SMALL LETTER D;So;0;L;<circle> 0064;;;;N;;;24B9;;24B9\n24D4;CIRCLED LATIN SMALL LETTER E;So;0;L;<circle> 0065;;;;N;;;24BA;;24BA\n24D5;CIRCLED LATIN SMALL LETTER F;So;0;L;<circle> 0066;;;;N;;;24BB;;24BB\n24D6;CIRCLED LATIN SMALL LETTER G;So;0;L;<circle> 0067;;;;N;;;24BC;;24BC\n24D7;CIRCLED LATIN SMALL LETTER H;So;0;L;<circle> 0068;;;;N;;;24BD;;24BD\n24D8;CIRCLED LATIN SMALL LETTER I;So;0;L;<circle> 0069;;;;N;;;24BE;;24BE\n24D9;CIRCLED LATIN SMALL LETTER J;So;0;L;<circle> 006A;;;;N;;;24BF;;24BF\n24DA;CIRCLED LATIN SMALL LETTER K;So;0;L;<circle> 006B;;;;N;;;24C0;;24C0\n24DB;CIRCLED LATIN SMALL LETTER L;So;0;L;<circle> 006C;;;;N;;;24C1;;24C1\n24DC;CIRCLED LATIN SMALL LETTER M;So;0;L;<circle> 006D;;;;N;;;24C2;;24C2\n24DD;CIRCLED LATIN SMALL LETTER N;So;0;L;<circle> 006E;;;;N;;;24C3;;24C3\n24DE;CIRCLED LATIN SMALL LETTER O;So;0;L;<circle> 006F;;;;N;;;24C4;;24C4\n24DF;CIRCLED LATIN SMALL LETTER P;So;0;L;<circle> 0070;;;;N;;;24C5;;24C5\n24E0;CIRCLED LATIN SMALL LETTER Q;So;0;L;<circle> 0071;;;;N;;;24C6;;24C6\n24E1;CIRCLED LATIN SMALL LETTER R;So;0;L;<circle> 0072;;;;N;;;24C7;;24C7\n24E2;CIRCLED LATIN SMALL LETTER S;So;0;L;<circle> 0073;;;;N;;;24C8;;24C8\n24E3;CIRCLED LATIN SMALL LETTER T;So;0;L;<circle> 0074;;;;N;;;24C9;;24C9\n24E4;CIRCLED LATIN SMALL LETTER U;So;0;L;<circle> 0075;;;;N;;;24CA;;24CA\n24E5;CIRCLED LATIN SMALL LETTER V;So;0;L;<circle> 0076;;;;N;;;24CB;;24CB\n24E6;CIRCLED LATIN SMALL LETTER W;So;0;L;<circle> 0077;;;;N;;;24CC;;24CC\n24E7;CIRCLED LATIN SMALL LETTER X;So;0;L;<circle> 0078;;;;N;;;24CD;;24CD\n24E8;CIRCLED LATIN SMALL LETTER Y;So;0;L;<circle> 0079;;;;N;;;24CE;;24CE\n24E9;CIRCLED LATIN SMALL LETTER Z;So;0;L;<circle> 007A;;;;N;;;24CF;;24CF\n24EA;CIRCLED DIGIT ZERO;No;0;ON;<circle> 0030;;0;0;N;;;;;\n24EB;NEGATIVE CIRCLED NUMBER ELEVEN;No;0;ON;;;;11;N;;;;;\n24EC;NEGATIVE CIRCLED NUMBER TWELVE;No;0;ON;;;;12;N;;;;;\n24ED;NEGATIVE CIRCLED NUMBER THIRTEEN;No;0;ON;;;;13;N;;;;;\n24EE;NEGATIVE CIRCLED NUMBER FOURTEEN;No;0;ON;;;;14;N;;;;;\n24EF;NEGATIVE CIRCLED NUMBER FIFTEEN;No;0;ON;;;;15;N;;;;;\n24F0;NEGATIVE CIRCLED NUMBER SIXTEEN;No;0;ON;;;;16;N;;;;;\n24F1;NEGATIVE CIRCLED NUMBER SEVENTEEN;No;0;ON;;;;17;N;;;;;\n24F2;NEGATIVE CIRCLED NUMBER EIGHTEEN;No;0;ON;;;;18;N;;;;;\n24F3;NEGATIVE CIRCLED NUMBER NINETEEN;No;0;ON;;;;19;N;;;;;\n24F4;NEGATIVE CIRCLED NUMBER TWENTY;No;0;ON;;;;20;N;;;;;\n24F5;DOUBLE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;;;;;\n24F6;DOUBLE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;;;;;\n24F7;DOUBLE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;;;;;\n24F8;DOUBLE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;;;;;\n24F9;DOUBLE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;;;;;\n24FA;DOUBLE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;;;;;\n24FB;DOUBLE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;;;;;\n24FC;DOUBLE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;;;;;\n24FD;DOUBLE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;;;;;\n24FE;DOUBLE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;;;;;\n24FF;NEGATIVE CIRCLED DIGIT ZERO;No;0;ON;;;0;0;N;;;;;\n2500;BOX DRAWINGS LIGHT HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT HORIZONTAL;;;;\n2501;BOX DRAWINGS HEAVY HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY HORIZONTAL;;;;\n2502;BOX DRAWINGS LIGHT VERTICAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL;;;;\n2503;BOX DRAWINGS HEAVY VERTICAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL;;;;\n2504;BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH HORIZONTAL;;;;\n2505;BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH HORIZONTAL;;;;\n2506;BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT TRIPLE DASH VERTICAL;;;;\n2507;BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY TRIPLE DASH VERTICAL;;;;\n2508;BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH HORIZONTAL;;;;\n2509;BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH HORIZONTAL;;;;\n250A;BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT QUADRUPLE DASH VERTICAL;;;;\n250B;BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY QUADRUPLE DASH VERTICAL;;;;\n250C;BOX DRAWINGS LIGHT DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND RIGHT;;;;\n250D;BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT HEAVY;;;;\n250E;BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT LIGHT;;;;\n250F;BOX DRAWINGS HEAVY DOWN AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND RIGHT;;;;\n2510;BOX DRAWINGS LIGHT DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT DOWN AND LEFT;;;;\n2511;BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT HEAVY;;;;\n2512;BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT LIGHT;;;;\n2513;BOX DRAWINGS HEAVY DOWN AND LEFT;So;0;ON;;;;;N;FORMS HEAVY DOWN AND LEFT;;;;\n2514;BOX DRAWINGS LIGHT UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT UP AND RIGHT;;;;\n2515;BOX DRAWINGS UP LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT HEAVY;;;;\n2516;BOX DRAWINGS UP HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT LIGHT;;;;\n2517;BOX DRAWINGS HEAVY UP AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY UP AND RIGHT;;;;\n2518;BOX DRAWINGS LIGHT UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT UP AND LEFT;;;;\n2519;BOX DRAWINGS UP LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT HEAVY;;;;\n251A;BOX DRAWINGS UP HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT LIGHT;;;;\n251B;BOX DRAWINGS HEAVY UP AND LEFT;So;0;ON;;;;;N;FORMS HEAVY UP AND LEFT;;;;\n251C;BOX DRAWINGS LIGHT VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND RIGHT;;;;\n251D;BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND RIGHT HEAVY;;;;\n251E;BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND RIGHT DOWN LIGHT;;;;\n251F;BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND RIGHT UP LIGHT;;;;\n2520;BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND RIGHT LIGHT;;;;\n2521;BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND RIGHT UP HEAVY;;;;\n2522;BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND RIGHT DOWN HEAVY;;;;\n2523;BOX DRAWINGS HEAVY VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND RIGHT;;;;\n2524;BOX DRAWINGS LIGHT VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND LEFT;;;;\n2525;BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND LEFT HEAVY;;;;\n2526;BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND LEFT DOWN LIGHT;;;;\n2527;BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND LEFT UP LIGHT;;;;\n2528;BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND LEFT LIGHT;;;;\n2529;BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND LEFT UP HEAVY;;;;\n252A;BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND LEFT DOWN HEAVY;;;;\n252B;BOX DRAWINGS HEAVY VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND LEFT;;;;\n252C;BOX DRAWINGS LIGHT DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOWN AND HORIZONTAL;;;;\n252D;BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT DOWN LIGHT;;;;\n252E;BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT DOWN LIGHT;;;;\n252F;BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND HORIZONTAL HEAVY;;;;\n2530;BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND HORIZONTAL LIGHT;;;;\n2531;BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT DOWN HEAVY;;;;\n2532;BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT DOWN HEAVY;;;;\n2533;BOX DRAWINGS HEAVY DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOWN AND HORIZONTAL;;;;\n2534;BOX DRAWINGS LIGHT UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT UP AND HORIZONTAL;;;;\n2535;BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT UP LIGHT;;;;\n2536;BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT UP LIGHT;;;;\n2537;BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND HORIZONTAL HEAVY;;;;\n2538;BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND HORIZONTAL LIGHT;;;;\n2539;BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT UP HEAVY;;;;\n253A;BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT UP HEAVY;;;;\n253B;BOX DRAWINGS HEAVY UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY UP AND HORIZONTAL;;;;\n253C;BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT VERTICAL AND HORIZONTAL;;;;\n253D;BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS LEFT HEAVY AND RIGHT VERTICAL LIGHT;;;;\n253E;BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT;So;0;ON;;;;;N;FORMS RIGHT HEAVY AND LEFT VERTICAL LIGHT;;;;\n253F;BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS VERTICAL LIGHT AND HORIZONTAL HEAVY;;;;\n2540;BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS UP HEAVY AND DOWN HORIZONTAL LIGHT;;;;\n2541;BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS DOWN HEAVY AND UP HORIZONTAL LIGHT;;;;\n2542;BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT;So;0;ON;;;;;N;FORMS VERTICAL HEAVY AND HORIZONTAL LIGHT;;;;\n2543;BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT;So;0;ON;;;;;N;FORMS LEFT UP HEAVY AND RIGHT DOWN LIGHT;;;;\n2544;BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT;So;0;ON;;;;;N;FORMS RIGHT UP HEAVY AND LEFT DOWN LIGHT;;;;\n2545;BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT;So;0;ON;;;;;N;FORMS LEFT DOWN HEAVY AND RIGHT UP LIGHT;;;;\n2546;BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT;So;0;ON;;;;;N;FORMS RIGHT DOWN HEAVY AND LEFT UP LIGHT;;;;\n2547;BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS DOWN LIGHT AND UP HORIZONTAL HEAVY;;;;\n2548;BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY;So;0;ON;;;;;N;FORMS UP LIGHT AND DOWN HORIZONTAL HEAVY;;;;\n2549;BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS RIGHT LIGHT AND LEFT VERTICAL HEAVY;;;;\n254A;BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY;So;0;ON;;;;;N;FORMS LEFT LIGHT AND RIGHT VERTICAL HEAVY;;;;\n254B;BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY VERTICAL AND HORIZONTAL;;;;\n254C;BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH HORIZONTAL;;;;\n254D;BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH HORIZONTAL;;;;\n254E;BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS LIGHT DOUBLE DASH VERTICAL;;;;\n254F;BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL;So;0;ON;;;;;N;FORMS HEAVY DOUBLE DASH VERTICAL;;;;\n2550;BOX DRAWINGS DOUBLE HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE HORIZONTAL;;;;\n2551;BOX DRAWINGS DOUBLE VERTICAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL;;;;\n2552;BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND RIGHT DOUBLE;;;;\n2553;BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND RIGHT SINGLE;;;;\n2554;BOX DRAWINGS DOUBLE DOWN AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND RIGHT;;;;\n2555;BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND LEFT DOUBLE;;;;\n2556;BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND LEFT SINGLE;;;;\n2557;BOX DRAWINGS DOUBLE DOWN AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND LEFT;;;;\n2558;BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND RIGHT DOUBLE;;;;\n2559;BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND RIGHT SINGLE;;;;\n255A;BOX DRAWINGS DOUBLE UP AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE UP AND RIGHT;;;;\n255B;BOX DRAWINGS UP SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND LEFT DOUBLE;;;;\n255C;BOX DRAWINGS UP DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND LEFT SINGLE;;;;\n255D;BOX DRAWINGS DOUBLE UP AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE UP AND LEFT;;;;\n255E;BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND RIGHT DOUBLE;;;;\n255F;BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND RIGHT SINGLE;;;;\n2560;BOX DRAWINGS DOUBLE VERTICAL AND RIGHT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND RIGHT;;;;\n2561;BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND LEFT DOUBLE;;;;\n2562;BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND LEFT SINGLE;;;;\n2563;BOX DRAWINGS DOUBLE VERTICAL AND LEFT;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND LEFT;;;;\n2564;BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS DOWN SINGLE AND HORIZONTAL DOUBLE;;;;\n2565;BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS DOWN DOUBLE AND HORIZONTAL SINGLE;;;;\n2566;BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE DOWN AND HORIZONTAL;;;;\n2567;BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS UP SINGLE AND HORIZONTAL DOUBLE;;;;\n2568;BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS UP DOUBLE AND HORIZONTAL SINGLE;;;;\n2569;BOX DRAWINGS DOUBLE UP AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE UP AND HORIZONTAL;;;;\n256A;BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE;So;0;ON;;;;;N;FORMS VERTICAL SINGLE AND HORIZONTAL DOUBLE;;;;\n256B;BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE;So;0;ON;;;;;N;FORMS VERTICAL DOUBLE AND HORIZONTAL SINGLE;;;;\n256C;BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL;So;0;ON;;;;;N;FORMS DOUBLE VERTICAL AND HORIZONTAL;;;;\n256D;BOX DRAWINGS LIGHT ARC DOWN AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND RIGHT;;;;\n256E;BOX DRAWINGS LIGHT ARC DOWN AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC DOWN AND LEFT;;;;\n256F;BOX DRAWINGS LIGHT ARC UP AND LEFT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND LEFT;;;;\n2570;BOX DRAWINGS LIGHT ARC UP AND RIGHT;So;0;ON;;;;;N;FORMS LIGHT ARC UP AND RIGHT;;;;\n2571;BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT;;;;\n2572;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT;;;;\n2573;BOX DRAWINGS LIGHT DIAGONAL CROSS;So;0;ON;;;;;N;FORMS LIGHT DIAGONAL CROSS;;;;\n2574;BOX DRAWINGS LIGHT LEFT;So;0;ON;;;;;N;FORMS LIGHT LEFT;;;;\n2575;BOX DRAWINGS LIGHT UP;So;0;ON;;;;;N;FORMS LIGHT UP;;;;\n2576;BOX DRAWINGS LIGHT RIGHT;So;0;ON;;;;;N;FORMS LIGHT RIGHT;;;;\n2577;BOX DRAWINGS LIGHT DOWN;So;0;ON;;;;;N;FORMS LIGHT DOWN;;;;\n2578;BOX DRAWINGS HEAVY LEFT;So;0;ON;;;;;N;FORMS HEAVY LEFT;;;;\n2579;BOX DRAWINGS HEAVY UP;So;0;ON;;;;;N;FORMS HEAVY UP;;;;\n257A;BOX DRAWINGS HEAVY RIGHT;So;0;ON;;;;;N;FORMS HEAVY RIGHT;;;;\n257B;BOX DRAWINGS HEAVY DOWN;So;0;ON;;;;;N;FORMS HEAVY DOWN;;;;\n257C;BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT;So;0;ON;;;;;N;FORMS LIGHT LEFT AND HEAVY RIGHT;;;;\n257D;BOX DRAWINGS LIGHT UP AND HEAVY DOWN;So;0;ON;;;;;N;FORMS LIGHT UP AND HEAVY DOWN;;;;\n257E;BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT;So;0;ON;;;;;N;FORMS HEAVY LEFT AND LIGHT RIGHT;;;;\n257F;BOX DRAWINGS HEAVY UP AND LIGHT DOWN;So;0;ON;;;;;N;FORMS HEAVY UP AND LIGHT DOWN;;;;\n2580;UPPER HALF BLOCK;So;0;ON;;;;;N;;;;;\n2581;LOWER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;\n2582;LOWER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;\n2583;LOWER THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;\n2584;LOWER HALF BLOCK;So;0;ON;;;;;N;;;;;\n2585;LOWER FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;\n2586;LOWER THREE QUARTERS BLOCK;So;0;ON;;;;;N;LOWER THREE QUARTER BLOCK;;;;\n2587;LOWER SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;\n2588;FULL BLOCK;So;0;ON;;;;;N;;;;;\n2589;LEFT SEVEN EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;\n258A;LEFT THREE QUARTERS BLOCK;So;0;ON;;;;;N;LEFT THREE QUARTER BLOCK;;;;\n258B;LEFT FIVE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;\n258C;LEFT HALF BLOCK;So;0;ON;;;;;N;;;;;\n258D;LEFT THREE EIGHTHS BLOCK;So;0;ON;;;;;N;;;;;\n258E;LEFT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;;\n258F;LEFT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;\n2590;RIGHT HALF BLOCK;So;0;ON;;;;;N;;;;;\n2591;LIGHT SHADE;So;0;ON;;;;;N;;;;;\n2592;MEDIUM SHADE;So;0;ON;;;;;N;;;;;\n2593;DARK SHADE;So;0;ON;;;;;N;;;;;\n2594;UPPER ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;\n2595;RIGHT ONE EIGHTH BLOCK;So;0;ON;;;;;N;;;;;\n2596;QUADRANT LOWER LEFT;So;0;ON;;;;;N;;;;;\n2597;QUADRANT LOWER RIGHT;So;0;ON;;;;;N;;;;;\n2598;QUADRANT UPPER LEFT;So;0;ON;;;;;N;;;;;\n2599;QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;\n259A;QUADRANT UPPER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;\n259B;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;;\n259C;QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;\n259D;QUADRANT UPPER RIGHT;So;0;ON;;;;;N;;;;;\n259E;QUADRANT UPPER RIGHT AND LOWER LEFT;So;0;ON;;;;;N;;;;;\n259F;QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT;So;0;ON;;;;;N;;;;;\n25A0;BLACK SQUARE;So;0;ON;;;;;N;;;;;\n25A1;WHITE SQUARE;So;0;ON;;;;;N;;;;;\n25A2;WHITE SQUARE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;;\n25A3;WHITE SQUARE CONTAINING BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;;\n25A4;SQUARE WITH HORIZONTAL FILL;So;0;ON;;;;;N;;;;;\n25A5;SQUARE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;;\n25A6;SQUARE WITH ORTHOGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;;\n25A7;SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL;So;0;ON;;;;;N;;;;;\n25A8;SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL;So;0;ON;;;;;N;;;;;\n25A9;SQUARE WITH DIAGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;;\n25AA;BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;;\n25AB;WHITE SMALL SQUARE;So;0;ON;;;;;N;;;;;\n25AC;BLACK RECTANGLE;So;0;ON;;;;;N;;;;;\n25AD;WHITE RECTANGLE;So;0;ON;;;;;N;;;;;\n25AE;BLACK VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;;\n25AF;WHITE VERTICAL RECTANGLE;So;0;ON;;;;;N;;;;;\n25B0;BLACK PARALLELOGRAM;So;0;ON;;;;;N;;;;;\n25B1;WHITE PARALLELOGRAM;So;0;ON;;;;;N;;;;;\n25B2;BLACK UP-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING TRIANGLE;;;;\n25B3;WHITE UP-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE;;;;\n25B4;BLACK UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK UP POINTING SMALL TRIANGLE;;;;\n25B5;WHITE UP-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE UP POINTING SMALL TRIANGLE;;;;\n25B6;BLACK RIGHT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING TRIANGLE;;;;\n25B7;WHITE RIGHT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE RIGHT POINTING TRIANGLE;;;;\n25B8;BLACK RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK RIGHT POINTING SMALL TRIANGLE;;;;\n25B9;WHITE RIGHT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE RIGHT POINTING SMALL TRIANGLE;;;;\n25BA;BLACK RIGHT-POINTING POINTER;So;0;ON;;;;;N;BLACK RIGHT POINTING POINTER;;;;\n25BB;WHITE RIGHT-POINTING POINTER;So;0;ON;;;;;N;WHITE RIGHT POINTING POINTER;;;;\n25BC;BLACK DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING TRIANGLE;;;;\n25BD;WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING TRIANGLE;;;;\n25BE;BLACK DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK DOWN POINTING SMALL TRIANGLE;;;;\n25BF;WHITE DOWN-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE DOWN POINTING SMALL TRIANGLE;;;;\n25C0;BLACK LEFT-POINTING TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING TRIANGLE;;;;\n25C1;WHITE LEFT-POINTING TRIANGLE;Sm;0;ON;;;;;N;WHITE LEFT POINTING TRIANGLE;;;;\n25C2;BLACK LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;BLACK LEFT POINTING SMALL TRIANGLE;;;;\n25C3;WHITE LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;WHITE LEFT POINTING SMALL TRIANGLE;;;;\n25C4;BLACK LEFT-POINTING POINTER;So;0;ON;;;;;N;BLACK LEFT POINTING POINTER;;;;\n25C5;WHITE LEFT-POINTING POINTER;So;0;ON;;;;;N;WHITE LEFT POINTING POINTER;;;;\n25C6;BLACK DIAMOND;So;0;ON;;;;;N;;;;;\n25C7;WHITE DIAMOND;So;0;ON;;;;;N;;;;;\n25C8;WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;;\n25C9;FISHEYE;So;0;ON;;;;;N;;;;;\n25CA;LOZENGE;So;0;ON;;;;;N;;;;;\n25CB;WHITE CIRCLE;So;0;ON;;;;;N;;;;;\n25CC;DOTTED CIRCLE;So;0;ON;;;;;N;;;;;\n25CD;CIRCLE WITH VERTICAL FILL;So;0;ON;;;;;N;;;;;\n25CE;BULLSEYE;So;0;ON;;;;;N;;;;;\n25CF;BLACK CIRCLE;So;0;ON;;;;;N;;;;;\n25D0;CIRCLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;;\n25D1;CIRCLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;;\n25D2;CIRCLE WITH LOWER HALF BLACK;So;0;ON;;;;;N;;;;;\n25D3;CIRCLE WITH UPPER HALF BLACK;So;0;ON;;;;;N;;;;;\n25D4;CIRCLE WITH UPPER RIGHT QUADRANT BLACK;So;0;ON;;;;;N;;;;;\n25D5;CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK;So;0;ON;;;;;N;;;;;\n25D6;LEFT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;\n25D7;RIGHT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;\n25D8;INVERSE BULLET;So;0;ON;;;;;N;;;;;\n25D9;INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;;\n25DA;UPPER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;;\n25DB;LOWER HALF INVERSE WHITE CIRCLE;So;0;ON;;;;;N;;;;;\n25DC;UPPER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;\n25DD;UPPER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;\n25DE;LOWER RIGHT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;\n25DF;LOWER LEFT QUADRANT CIRCULAR ARC;So;0;ON;;;;;N;;;;;\n25E0;UPPER HALF CIRCLE;So;0;ON;;;;;N;;;;;\n25E1;LOWER HALF CIRCLE;So;0;ON;;;;;N;;;;;\n25E2;BLACK LOWER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;\n25E3;BLACK LOWER LEFT TRIANGLE;So;0;ON;;;;;N;;;;;\n25E4;BLACK UPPER LEFT TRIANGLE;So;0;ON;;;;;N;;;;;\n25E5;BLACK UPPER RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;\n25E6;WHITE BULLET;So;0;ON;;;;;N;;;;;\n25E7;SQUARE WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;;\n25E8;SQUARE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;;\n25E9;SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;\n25EA;SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;\n25EB;WHITE SQUARE WITH VERTICAL BISECTING LINE;So;0;ON;;;;;N;;;;;\n25EC;WHITE UP-POINTING TRIANGLE WITH DOT;So;0;ON;;;;;N;WHITE UP POINTING TRIANGLE WITH DOT;;;;\n25ED;UP-POINTING TRIANGLE WITH LEFT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH LEFT HALF BLACK;;;;\n25EE;UP-POINTING TRIANGLE WITH RIGHT HALF BLACK;So;0;ON;;;;;N;UP POINTING TRIANGLE WITH RIGHT HALF BLACK;;;;\n25EF;LARGE CIRCLE;So;0;ON;;;;;N;;;;;\n25F0;WHITE SQUARE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;;\n25F1;WHITE SQUARE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;;\n25F2;WHITE SQUARE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;\n25F3;WHITE SQUARE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;\n25F4;WHITE CIRCLE WITH UPPER LEFT QUADRANT;So;0;ON;;;;;N;;;;;\n25F5;WHITE CIRCLE WITH LOWER LEFT QUADRANT;So;0;ON;;;;;N;;;;;\n25F6;WHITE CIRCLE WITH LOWER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;\n25F7;WHITE CIRCLE WITH UPPER RIGHT QUADRANT;So;0;ON;;;;;N;;;;;\n25F8;UPPER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;;\n25F9;UPPER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;;\n25FA;LOWER LEFT TRIANGLE;Sm;0;ON;;;;;N;;;;;\n25FB;WHITE MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;;\n25FC;BLACK MEDIUM SQUARE;Sm;0;ON;;;;;N;;;;;\n25FD;WHITE MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;;\n25FE;BLACK MEDIUM SMALL SQUARE;Sm;0;ON;;;;;N;;;;;\n25FF;LOWER RIGHT TRIANGLE;Sm;0;ON;;;;;N;;;;;\n2600;BLACK SUN WITH RAYS;So;0;ON;;;;;N;;;;;\n2601;CLOUD;So;0;ON;;;;;N;;;;;\n2602;UMBRELLA;So;0;ON;;;;;N;;;;;\n2603;SNOWMAN;So;0;ON;;;;;N;;;;;\n2604;COMET;So;0;ON;;;;;N;;;;;\n2605;BLACK STAR;So;0;ON;;;;;N;;;;;\n2606;WHITE STAR;So;0;ON;;;;;N;;;;;\n2607;LIGHTNING;So;0;ON;;;;;N;;;;;\n2608;THUNDERSTORM;So;0;ON;;;;;N;;;;;\n2609;SUN;So;0;ON;;;;;N;;;;;\n260A;ASCENDING NODE;So;0;ON;;;;;N;;;;;\n260B;DESCENDING NODE;So;0;ON;;;;;N;;;;;\n260C;CONJUNCTION;So;0;ON;;;;;N;;;;;\n260D;OPPOSITION;So;0;ON;;;;;N;;;;;\n260E;BLACK TELEPHONE;So;0;ON;;;;;N;;;;;\n260F;WHITE TELEPHONE;So;0;ON;;;;;N;;;;;\n2610;BALLOT BOX;So;0;ON;;;;;N;;;;;\n2611;BALLOT BOX WITH CHECK;So;0;ON;;;;;N;;;;;\n2612;BALLOT BOX WITH X;So;0;ON;;;;;N;;;;;\n2613;SALTIRE;So;0;ON;;;;;N;;;;;\n2614;UMBRELLA WITH RAIN DROPS;So;0;ON;;;;;N;;;;;\n2615;HOT BEVERAGE;So;0;ON;;;;;N;;;;;\n2616;WHITE SHOGI PIECE;So;0;ON;;;;;N;;;;;\n2617;BLACK SHOGI PIECE;So;0;ON;;;;;N;;;;;\n2618;SHAMROCK;So;0;ON;;;;;N;;;;;\n2619;REVERSED ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;;\n261A;BLACK LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;\n261B;BLACK RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;\n261C;WHITE LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;\n261D;WHITE UP POINTING INDEX;So;0;ON;;;;;N;;;;;\n261E;WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;\n261F;WHITE DOWN POINTING INDEX;So;0;ON;;;;;N;;;;;\n2620;SKULL AND CROSSBONES;So;0;ON;;;;;N;;;;;\n2621;CAUTION SIGN;So;0;ON;;;;;N;;;;;\n2622;RADIOACTIVE SIGN;So;0;ON;;;;;N;;;;;\n2623;BIOHAZARD SIGN;So;0;ON;;;;;N;;;;;\n2624;CADUCEUS;So;0;ON;;;;;N;;;;;\n2625;ANKH;So;0;ON;;;;;N;;;;;\n2626;ORTHODOX CROSS;So;0;ON;;;;;N;;;;;\n2627;CHI RHO;So;0;ON;;;;;N;;;;;\n2628;CROSS OF LORRAINE;So;0;ON;;;;;N;;;;;\n2629;CROSS OF JERUSALEM;So;0;ON;;;;;N;;;;;\n262A;STAR AND CRESCENT;So;0;ON;;;;;N;;;;;\n262B;FARSI SYMBOL;So;0;ON;;;;;N;SYMBOL OF IRAN;;;;\n262C;ADI SHAKTI;So;0;ON;;;;;N;;;;;\n262D;HAMMER AND SICKLE;So;0;ON;;;;;N;;;;;\n262E;PEACE SYMBOL;So;0;ON;;;;;N;;;;;\n262F;YIN YANG;So;0;ON;;;;;N;;;;;\n2630;TRIGRAM FOR HEAVEN;So;0;ON;;;;;N;;;;;\n2631;TRIGRAM FOR LAKE;So;0;ON;;;;;N;;;;;\n2632;TRIGRAM FOR FIRE;So;0;ON;;;;;N;;;;;\n2633;TRIGRAM FOR THUNDER;So;0;ON;;;;;N;;;;;\n2634;TRIGRAM FOR WIND;So;0;ON;;;;;N;;;;;\n2635;TRIGRAM FOR WATER;So;0;ON;;;;;N;;;;;\n2636;TRIGRAM FOR MOUNTAIN;So;0;ON;;;;;N;;;;;\n2637;TRIGRAM FOR EARTH;So;0;ON;;;;;N;;;;;\n2638;WHEEL OF DHARMA;So;0;ON;;;;;N;;;;;\n2639;WHITE FROWNING FACE;So;0;ON;;;;;N;;;;;\n263A;WHITE SMILING FACE;So;0;ON;;;;;N;;;;;\n263B;BLACK SMILING FACE;So;0;ON;;;;;N;;;;;\n263C;WHITE SUN WITH RAYS;So;0;ON;;;;;N;;;;;\n263D;FIRST QUARTER MOON;So;0;ON;;;;;N;;;;;\n263E;LAST QUARTER MOON;So;0;ON;;;;;N;;;;;\n263F;MERCURY;So;0;ON;;;;;N;;;;;\n2640;FEMALE SIGN;So;0;ON;;;;;N;;;;;\n2641;EARTH;So;0;ON;;;;;N;;;;;\n2642;MALE SIGN;So;0;ON;;;;;N;;;;;\n2643;JUPITER;So;0;ON;;;;;N;;;;;\n2644;SATURN;So;0;ON;;;;;N;;;;;\n2645;URANUS;So;0;ON;;;;;N;;;;;\n2646;NEPTUNE;So;0;ON;;;;;N;;;;;\n2647;PLUTO;So;0;ON;;;;;N;;;;;\n2648;ARIES;So;0;ON;;;;;N;;;;;\n2649;TAURUS;So;0;ON;;;;;N;;;;;\n264A;GEMINI;So;0;ON;;;;;N;;;;;\n264B;CANCER;So;0;ON;;;;;N;;;;;\n264C;LEO;So;0;ON;;;;;N;;;;;\n264D;VIRGO;So;0;ON;;;;;N;;;;;\n264E;LIBRA;So;0;ON;;;;;N;;;;;\n264F;SCORPIUS;So;0;ON;;;;;N;;;;;\n2650;SAGITTARIUS;So;0;ON;;;;;N;;;;;\n2651;CAPRICORN;So;0;ON;;;;;N;;;;;\n2652;AQUARIUS;So;0;ON;;;;;N;;;;;\n2653;PISCES;So;0;ON;;;;;N;;;;;\n2654;WHITE CHESS KING;So;0;ON;;;;;N;;;;;\n2655;WHITE CHESS QUEEN;So;0;ON;;;;;N;;;;;\n2656;WHITE CHESS ROOK;So;0;ON;;;;;N;;;;;\n2657;WHITE CHESS BISHOP;So;0;ON;;;;;N;;;;;\n2658;WHITE CHESS KNIGHT;So;0;ON;;;;;N;;;;;\n2659;WHITE CHESS PAWN;So;0;ON;;;;;N;;;;;\n265A;BLACK CHESS KING;So;0;ON;;;;;N;;;;;\n265B;BLACK CHESS QUEEN;So;0;ON;;;;;N;;;;;\n265C;BLACK CHESS ROOK;So;0;ON;;;;;N;;;;;\n265D;BLACK CHESS BISHOP;So;0;ON;;;;;N;;;;;\n265E;BLACK CHESS KNIGHT;So;0;ON;;;;;N;;;;;\n265F;BLACK CHESS PAWN;So;0;ON;;;;;N;;;;;\n2660;BLACK SPADE SUIT;So;0;ON;;;;;N;;;;;\n2661;WHITE HEART SUIT;So;0;ON;;;;;N;;;;;\n2662;WHITE DIAMOND SUIT;So;0;ON;;;;;N;;;;;\n2663;BLACK CLUB SUIT;So;0;ON;;;;;N;;;;;\n2664;WHITE SPADE SUIT;So;0;ON;;;;;N;;;;;\n2665;BLACK HEART SUIT;So;0;ON;;;;;N;;;;;\n2666;BLACK DIAMOND SUIT;So;0;ON;;;;;N;;;;;\n2667;WHITE CLUB SUIT;So;0;ON;;;;;N;;;;;\n2668;HOT SPRINGS;So;0;ON;;;;;N;;;;;\n2669;QUARTER NOTE;So;0;ON;;;;;N;;;;;\n266A;EIGHTH NOTE;So;0;ON;;;;;N;;;;;\n266B;BEAMED EIGHTH NOTES;So;0;ON;;;;;N;BARRED EIGHTH NOTES;;;;\n266C;BEAMED SIXTEENTH NOTES;So;0;ON;;;;;N;BARRED SIXTEENTH NOTES;;;;\n266D;MUSIC FLAT SIGN;So;0;ON;;;;;N;FLAT;;;;\n266E;MUSIC NATURAL SIGN;So;0;ON;;;;;N;NATURAL;;;;\n266F;MUSIC SHARP SIGN;Sm;0;ON;;;;;N;SHARP;;;;\n2670;WEST SYRIAC CROSS;So;0;ON;;;;;N;;;;;\n2671;EAST SYRIAC CROSS;So;0;ON;;;;;N;;;;;\n2672;UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;;\n2673;RECYCLING SYMBOL FOR TYPE-1 PLASTICS;So;0;ON;;;;;N;;;;;\n2674;RECYCLING SYMBOL FOR TYPE-2 PLASTICS;So;0;ON;;;;;N;;;;;\n2675;RECYCLING SYMBOL FOR TYPE-3 PLASTICS;So;0;ON;;;;;N;;;;;\n2676;RECYCLING SYMBOL FOR TYPE-4 PLASTICS;So;0;ON;;;;;N;;;;;\n2677;RECYCLING SYMBOL FOR TYPE-5 PLASTICS;So;0;ON;;;;;N;;;;;\n2678;RECYCLING SYMBOL FOR TYPE-6 PLASTICS;So;0;ON;;;;;N;;;;;\n2679;RECYCLING SYMBOL FOR TYPE-7 PLASTICS;So;0;ON;;;;;N;;;;;\n267A;RECYCLING SYMBOL FOR GENERIC MATERIALS;So;0;ON;;;;;N;;;;;\n267B;BLACK UNIVERSAL RECYCLING SYMBOL;So;0;ON;;;;;N;;;;;\n267C;RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;;\n267D;PARTIALLY-RECYCLED PAPER SYMBOL;So;0;ON;;;;;N;;;;;\n267E;PERMANENT PAPER SIGN;So;0;ON;;;;;N;;;;;\n267F;WHEELCHAIR SYMBOL;So;0;ON;;;;;N;;;;;\n2680;DIE FACE-1;So;0;ON;;;;;N;;;;;\n2681;DIE FACE-2;So;0;ON;;;;;N;;;;;\n2682;DIE FACE-3;So;0;ON;;;;;N;;;;;\n2683;DIE FACE-4;So;0;ON;;;;;N;;;;;\n2684;DIE FACE-5;So;0;ON;;;;;N;;;;;\n2685;DIE FACE-6;So;0;ON;;;;;N;;;;;\n2686;WHITE CIRCLE WITH DOT RIGHT;So;0;ON;;;;;N;;;;;\n2687;WHITE CIRCLE WITH TWO DOTS;So;0;ON;;;;;N;;;;;\n2688;BLACK CIRCLE WITH WHITE DOT RIGHT;So;0;ON;;;;;N;;;;;\n2689;BLACK CIRCLE WITH TWO WHITE DOTS;So;0;ON;;;;;N;;;;;\n268A;MONOGRAM FOR YANG;So;0;ON;;;;;N;;;;;\n268B;MONOGRAM FOR YIN;So;0;ON;;;;;N;;;;;\n268C;DIGRAM FOR GREATER YANG;So;0;ON;;;;;N;;;;;\n268D;DIGRAM FOR LESSER YIN;So;0;ON;;;;;N;;;;;\n268E;DIGRAM FOR LESSER YANG;So;0;ON;;;;;N;;;;;\n268F;DIGRAM FOR GREATER YIN;So;0;ON;;;;;N;;;;;\n2690;WHITE FLAG;So;0;ON;;;;;N;;;;;\n2691;BLACK FLAG;So;0;ON;;;;;N;;;;;\n2692;HAMMER AND PICK;So;0;ON;;;;;N;;;;;\n2693;ANCHOR;So;0;ON;;;;;N;;;;;\n2694;CROSSED SWORDS;So;0;ON;;;;;N;;;;;\n2695;STAFF OF AESCULAPIUS;So;0;ON;;;;;N;;;;;\n2696;SCALES;So;0;ON;;;;;N;;;;;\n2697;ALEMBIC;So;0;ON;;;;;N;;;;;\n2698;FLOWER;So;0;ON;;;;;N;;;;;\n2699;GEAR;So;0;ON;;;;;N;;;;;\n269A;STAFF OF HERMES;So;0;ON;;;;;N;;;;;\n269B;ATOM SYMBOL;So;0;ON;;;;;N;;;;;\n269C;FLEUR-DE-LIS;So;0;ON;;;;;N;;;;;\n269D;OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;;\n269E;THREE LINES CONVERGING RIGHT;So;0;ON;;;;;N;;;;;\n269F;THREE LINES CONVERGING LEFT;So;0;ON;;;;;N;;;;;\n26A0;WARNING SIGN;So;0;ON;;;;;N;;;;;\n26A1;HIGH VOLTAGE SIGN;So;0;ON;;;;;N;;;;;\n26A2;DOUBLED FEMALE SIGN;So;0;ON;;;;;N;;;;;\n26A3;DOUBLED MALE SIGN;So;0;ON;;;;;N;;;;;\n26A4;INTERLOCKED FEMALE AND MALE SIGN;So;0;ON;;;;;N;;;;;\n26A5;MALE AND FEMALE SIGN;So;0;ON;;;;;N;;;;;\n26A6;MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;;\n26A7;MALE WITH STROKE AND MALE AND FEMALE SIGN;So;0;ON;;;;;N;;;;;\n26A8;VERTICAL MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;;\n26A9;HORIZONTAL MALE WITH STROKE SIGN;So;0;ON;;;;;N;;;;;\n26AA;MEDIUM WHITE CIRCLE;So;0;ON;;;;;N;;;;;\n26AB;MEDIUM BLACK CIRCLE;So;0;ON;;;;;N;;;;;\n26AC;MEDIUM SMALL WHITE CIRCLE;So;0;L;;;;;N;;;;;\n26AD;MARRIAGE SYMBOL;So;0;ON;;;;;N;;;;;\n26AE;DIVORCE SYMBOL;So;0;ON;;;;;N;;;;;\n26AF;UNMARRIED PARTNERSHIP SYMBOL;So;0;ON;;;;;N;;;;;\n26B0;COFFIN;So;0;ON;;;;;N;;;;;\n26B1;FUNERAL URN;So;0;ON;;;;;N;;;;;\n26B2;NEUTER;So;0;ON;;;;;N;;;;;\n26B3;CERES;So;0;ON;;;;;N;;;;;\n26B4;PALLAS;So;0;ON;;;;;N;;;;;\n26B5;JUNO;So;0;ON;;;;;N;;;;;\n26B6;VESTA;So;0;ON;;;;;N;;;;;\n26B7;CHIRON;So;0;ON;;;;;N;;;;;\n26B8;BLACK MOON LILITH;So;0;ON;;;;;N;;;;;\n26B9;SEXTILE;So;0;ON;;;;;N;;;;;\n26BA;SEMISEXTILE;So;0;ON;;;;;N;;;;;\n26BB;QUINCUNX;So;0;ON;;;;;N;;;;;\n26BC;SESQUIQUADRATE;So;0;ON;;;;;N;;;;;\n26BD;SOCCER BALL;So;0;ON;;;;;N;;;;;\n26BE;BASEBALL;So;0;ON;;;;;N;;;;;\n26BF;SQUARED KEY;So;0;ON;;;;;N;;;;;\n26C0;WHITE DRAUGHTS MAN;So;0;ON;;;;;N;;;;;\n26C1;WHITE DRAUGHTS KING;So;0;ON;;;;;N;;;;;\n26C2;BLACK DRAUGHTS MAN;So;0;ON;;;;;N;;;;;\n26C3;BLACK DRAUGHTS KING;So;0;ON;;;;;N;;;;;\n26C4;SNOWMAN WITHOUT SNOW;So;0;ON;;;;;N;;;;;\n26C5;SUN BEHIND CLOUD;So;0;ON;;;;;N;;;;;\n26C6;RAIN;So;0;ON;;;;;N;;;;;\n26C7;BLACK SNOWMAN;So;0;ON;;;;;N;;;;;\n26C8;THUNDER CLOUD AND RAIN;So;0;ON;;;;;N;;;;;\n26C9;TURNED WHITE SHOGI PIECE;So;0;ON;;;;;N;;;;;\n26CA;TURNED BLACK SHOGI PIECE;So;0;ON;;;;;N;;;;;\n26CB;WHITE DIAMOND IN SQUARE;So;0;ON;;;;;N;;;;;\n26CC;CROSSING LANES;So;0;ON;;;;;N;;;;;\n26CD;DISABLED CAR;So;0;ON;;;;;N;;;;;\n26CE;OPHIUCHUS;So;0;ON;;;;;N;;;;;\n26CF;PICK;So;0;ON;;;;;N;;;;;\n26D0;CAR SLIDING;So;0;ON;;;;;N;;;;;\n26D1;HELMET WITH WHITE CROSS;So;0;ON;;;;;N;;;;;\n26D2;CIRCLED CROSSING LANES;So;0;ON;;;;;N;;;;;\n26D3;CHAINS;So;0;ON;;;;;N;;;;;\n26D4;NO ENTRY;So;0;ON;;;;;N;;;;;\n26D5;ALTERNATE ONE-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;;\n26D6;BLACK TWO-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;;\n26D7;WHITE TWO-WAY LEFT WAY TRAFFIC;So;0;ON;;;;;N;;;;;\n26D8;BLACK LEFT LANE MERGE;So;0;ON;;;;;N;;;;;\n26D9;WHITE LEFT LANE MERGE;So;0;ON;;;;;N;;;;;\n26DA;DRIVE SLOW SIGN;So;0;ON;;;;;N;;;;;\n26DB;HEAVY WHITE DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;;;;;\n26DC;LEFT CLOSED ENTRY;So;0;ON;;;;;N;;;;;\n26DD;SQUARED SALTIRE;So;0;ON;;;;;N;;;;;\n26DE;FALLING DIAGONAL IN WHITE CIRCLE IN BLACK SQUARE;So;0;ON;;;;;N;;;;;\n26DF;BLACK TRUCK;So;0;ON;;;;;N;;;;;\n26E0;RESTRICTED LEFT ENTRY-1;So;0;ON;;;;;N;;;;;\n26E1;RESTRICTED LEFT ENTRY-2;So;0;ON;;;;;N;;;;;\n26E2;ASTRONOMICAL SYMBOL FOR URANUS;So;0;ON;;;;;N;;;;;\n26E3;HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE;So;0;ON;;;;;N;;;;;\n26E4;PENTAGRAM;So;0;ON;;;;;N;;;;;\n26E5;RIGHT-HANDED INTERLACED PENTAGRAM;So;0;ON;;;;;N;;;;;\n26E6;LEFT-HANDED INTERLACED PENTAGRAM;So;0;ON;;;;;N;;;;;\n26E7;INVERTED PENTAGRAM;So;0;ON;;;;;N;;;;;\n26E8;BLACK CROSS ON SHIELD;So;0;ON;;;;;N;;;;;\n26E9;SHINTO SHRINE;So;0;ON;;;;;N;;;;;\n26EA;CHURCH;So;0;ON;;;;;N;;;;;\n26EB;CASTLE;So;0;ON;;;;;N;;;;;\n26EC;HISTORIC SITE;So;0;ON;;;;;N;;;;;\n26ED;GEAR WITHOUT HUB;So;0;ON;;;;;N;;;;;\n26EE;GEAR WITH HANDLES;So;0;ON;;;;;N;;;;;\n26EF;MAP SYMBOL FOR LIGHTHOUSE;So;0;ON;;;;;N;;;;;\n26F0;MOUNTAIN;So;0;ON;;;;;N;;;;;\n26F1;UMBRELLA ON GROUND;So;0;ON;;;;;N;;;;;\n26F2;FOUNTAIN;So;0;ON;;;;;N;;;;;\n26F3;FLAG IN HOLE;So;0;ON;;;;;N;;;;;\n26F4;FERRY;So;0;ON;;;;;N;;;;;\n26F5;SAILBOAT;So;0;ON;;;;;N;;;;;\n26F6;SQUARE FOUR CORNERS;So;0;ON;;;;;N;;;;;\n26F7;SKIER;So;0;ON;;;;;N;;;;;\n26F8;ICE SKATE;So;0;ON;;;;;N;;;;;\n26F9;PERSON WITH BALL;So;0;ON;;;;;N;;;;;\n26FA;TENT;So;0;ON;;;;;N;;;;;\n26FB;JAPANESE BANK SYMBOL;So;0;ON;;;;;N;;;;;\n26FC;HEADSTONE GRAVEYARD SYMBOL;So;0;ON;;;;;N;;;;;\n26FD;FUEL PUMP;So;0;ON;;;;;N;;;;;\n26FE;CUP ON BLACK SQUARE;So;0;ON;;;;;N;;;;;\n26FF;WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE;So;0;ON;;;;;N;;;;;\n2700;BLACK SAFETY SCISSORS;So;0;ON;;;;;N;;;;;\n2701;UPPER BLADE SCISSORS;So;0;ON;;;;;N;;;;;\n2702;BLACK SCISSORS;So;0;ON;;;;;N;;;;;\n2703;LOWER BLADE SCISSORS;So;0;ON;;;;;N;;;;;\n2704;WHITE SCISSORS;So;0;ON;;;;;N;;;;;\n2705;WHITE HEAVY CHECK MARK;So;0;ON;;;;;N;;;;;\n2706;TELEPHONE LOCATION SIGN;So;0;ON;;;;;N;;;;;\n2707;TAPE DRIVE;So;0;ON;;;;;N;;;;;\n2708;AIRPLANE;So;0;ON;;;;;N;;;;;\n2709;ENVELOPE;So;0;ON;;;;;N;;;;;\n270A;RAISED FIST;So;0;ON;;;;;N;;;;;\n270B;RAISED HAND;So;0;ON;;;;;N;;;;;\n270C;VICTORY HAND;So;0;ON;;;;;N;;;;;\n270D;WRITING HAND;So;0;ON;;;;;N;;;;;\n270E;LOWER RIGHT PENCIL;So;0;ON;;;;;N;;;;;\n270F;PENCIL;So;0;ON;;;;;N;;;;;\n2710;UPPER RIGHT PENCIL;So;0;ON;;;;;N;;;;;\n2711;WHITE NIB;So;0;ON;;;;;N;;;;;\n2712;BLACK NIB;So;0;ON;;;;;N;;;;;\n2713;CHECK MARK;So;0;ON;;;;;N;;;;;\n2714;HEAVY CHECK MARK;So;0;ON;;;;;N;;;;;\n2715;MULTIPLICATION X;So;0;ON;;;;;N;;;;;\n2716;HEAVY MULTIPLICATION X;So;0;ON;;;;;N;;;;;\n2717;BALLOT X;So;0;ON;;;;;N;;;;;\n2718;HEAVY BALLOT X;So;0;ON;;;;;N;;;;;\n2719;OUTLINED GREEK CROSS;So;0;ON;;;;;N;;;;;\n271A;HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;;\n271B;OPEN CENTRE CROSS;So;0;ON;;;;;N;OPEN CENTER CROSS;;;;\n271C;HEAVY OPEN CENTRE CROSS;So;0;ON;;;;;N;HEAVY OPEN CENTER CROSS;;;;\n271D;LATIN CROSS;So;0;ON;;;;;N;;;;;\n271E;SHADOWED WHITE LATIN CROSS;So;0;ON;;;;;N;;;;;\n271F;OUTLINED LATIN CROSS;So;0;ON;;;;;N;;;;;\n2720;MALTESE CROSS;So;0;ON;;;;;N;;;;;\n2721;STAR OF DAVID;So;0;ON;;;;;N;;;;;\n2722;FOUR TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n2723;FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n2724;HEAVY FOUR BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n2725;FOUR CLUB-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n2726;BLACK FOUR POINTED STAR;So;0;ON;;;;;N;;;;;\n2727;WHITE FOUR POINTED STAR;So;0;ON;;;;;N;;;;;\n2728;SPARKLES;So;0;ON;;;;;N;;;;;\n2729;STRESS OUTLINED WHITE STAR;So;0;ON;;;;;N;;;;;\n272A;CIRCLED WHITE STAR;So;0;ON;;;;;N;;;;;\n272B;OPEN CENTRE BLACK STAR;So;0;ON;;;;;N;OPEN CENTER BLACK STAR;;;;\n272C;BLACK CENTRE WHITE STAR;So;0;ON;;;;;N;BLACK CENTER WHITE STAR;;;;\n272D;OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;;\n272E;HEAVY OUTLINED BLACK STAR;So;0;ON;;;;;N;;;;;\n272F;PINWHEEL STAR;So;0;ON;;;;;N;;;;;\n2730;SHADOWED WHITE STAR;So;0;ON;;;;;N;;;;;\n2731;HEAVY ASTERISK;So;0;ON;;;;;N;;;;;\n2732;OPEN CENTRE ASTERISK;So;0;ON;;;;;N;OPEN CENTER ASTERISK;;;;\n2733;EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n2734;EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n2735;EIGHT POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;\n2736;SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n2737;EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;;\n2738;HEAVY EIGHT POINTED RECTILINEAR BLACK STAR;So;0;ON;;;;;N;;;;;\n2739;TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n273A;SIXTEEN POINTED ASTERISK;So;0;ON;;;;;N;;;;;\n273B;TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n273C;OPEN CENTRE TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;OPEN CENTER TEARDROP-SPOKED ASTERISK;;;;\n273D;HEAVY TEARDROP-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n273E;SIX PETALLED BLACK AND WHITE FLORETTE;So;0;ON;;;;;N;;;;;\n273F;BLACK FLORETTE;So;0;ON;;;;;N;;;;;\n2740;WHITE FLORETTE;So;0;ON;;;;;N;;;;;\n2741;EIGHT PETALLED OUTLINED BLACK FLORETTE;So;0;ON;;;;;N;;;;;\n2742;CIRCLED OPEN CENTRE EIGHT POINTED STAR;So;0;ON;;;;;N;CIRCLED OPEN CENTER EIGHT POINTED STAR;;;;\n2743;HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK;So;0;ON;;;;;N;;;;;\n2744;SNOWFLAKE;So;0;ON;;;;;N;;;;;\n2745;TIGHT TRIFOLIATE SNOWFLAKE;So;0;ON;;;;;N;;;;;\n2746;HEAVY CHEVRON SNOWFLAKE;So;0;ON;;;;;N;;;;;\n2747;SPARKLE;So;0;ON;;;;;N;;;;;\n2748;HEAVY SPARKLE;So;0;ON;;;;;N;;;;;\n2749;BALLOON-SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n274A;EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;;\n274B;HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK;So;0;ON;;;;;N;;;;;\n274C;CROSS MARK;So;0;ON;;;;;N;;;;;\n274D;SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;;\n274E;NEGATIVE SQUARED CROSS MARK;So;0;ON;;;;;N;;;;;\n274F;LOWER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;\n2750;UPPER RIGHT DROP-SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;\n2751;LOWER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;\n2752;UPPER RIGHT SHADOWED WHITE SQUARE;So;0;ON;;;;;N;;;;;\n2753;BLACK QUESTION MARK ORNAMENT;So;0;ON;;;;;N;;;;;\n2754;WHITE QUESTION MARK ORNAMENT;So;0;ON;;;;;N;;;;;\n2755;WHITE EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;\n2756;BLACK DIAMOND MINUS WHITE X;So;0;ON;;;;;N;;;;;\n2757;HEAVY EXCLAMATION MARK SYMBOL;So;0;ON;;;;;N;;;;;\n2758;LIGHT VERTICAL BAR;So;0;ON;;;;;N;;;;;\n2759;MEDIUM VERTICAL BAR;So;0;ON;;;;;N;;;;;\n275A;HEAVY VERTICAL BAR;So;0;ON;;;;;N;;;;;\n275B;HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;\n275C;HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;\n275D;HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;\n275E;HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;\n275F;HEAVY LOW SINGLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;\n2760;HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;\n2761;CURVED STEM PARAGRAPH SIGN ORNAMENT;So;0;ON;;;;;N;;;;;\n2762;HEAVY EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;\n2763;HEAVY HEART EXCLAMATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;\n2764;HEAVY BLACK HEART;So;0;ON;;;;;N;;;;;\n2765;ROTATED HEAVY BLACK HEART BULLET;So;0;ON;;;;;N;;;;;\n2766;FLORAL HEART;So;0;ON;;;;;N;;;;;\n2767;ROTATED FLORAL HEART BULLET;So;0;ON;;;;;N;;;;;\n2768;MEDIUM LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;;\n2769;MEDIUM RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;;\n276A;MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT;Ps;0;ON;;;;;Y;;;;;\n276B;MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT;Pe;0;ON;;;;;Y;;;;;\n276C;MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;\n276D;MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;\n276E;HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT;Ps;0;ON;;;;;Y;;;;;\n276F;HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT;Pe;0;ON;;;;;Y;;;;;\n2770;HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;\n2771;HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;\n2772;LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;\n2773;LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;\n2774;MEDIUM LEFT CURLY BRACKET ORNAMENT;Ps;0;ON;;;;;Y;;;;;\n2775;MEDIUM RIGHT CURLY BRACKET ORNAMENT;Pe;0;ON;;;;;Y;;;;;\n2776;DINGBAT NEGATIVE CIRCLED DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED DIGIT ONE;;;;\n2777;DINGBAT NEGATIVE CIRCLED DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED DIGIT TWO;;;;\n2778;DINGBAT NEGATIVE CIRCLED DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED DIGIT THREE;;;;\n2779;DINGBAT NEGATIVE CIRCLED DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED DIGIT FOUR;;;;\n277A;DINGBAT NEGATIVE CIRCLED DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED DIGIT FIVE;;;;\n277B;DINGBAT NEGATIVE CIRCLED DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED DIGIT SIX;;;;\n277C;DINGBAT NEGATIVE CIRCLED DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED DIGIT SEVEN;;;;\n277D;DINGBAT NEGATIVE CIRCLED DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED DIGIT EIGHT;;;;\n277E;DINGBAT NEGATIVE CIRCLED DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED DIGIT NINE;;;;\n277F;DINGBAT NEGATIVE CIRCLED NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED NUMBER TEN;;;;\n2780;DINGBAT CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;CIRCLED SANS-SERIF DIGIT ONE;;;;\n2781;DINGBAT CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;CIRCLED SANS-SERIF DIGIT TWO;;;;\n2782;DINGBAT CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;CIRCLED SANS-SERIF DIGIT THREE;;;;\n2783;DINGBAT CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;CIRCLED SANS-SERIF DIGIT FOUR;;;;\n2784;DINGBAT CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;CIRCLED SANS-SERIF DIGIT FIVE;;;;\n2785;DINGBAT CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;CIRCLED SANS-SERIF DIGIT SIX;;;;\n2786;DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;CIRCLED SANS-SERIF DIGIT SEVEN;;;;\n2787;DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;CIRCLED SANS-SERIF DIGIT EIGHT;;;;\n2788;DINGBAT CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;CIRCLED SANS-SERIF DIGIT NINE;;;;\n2789;DINGBAT CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;CIRCLED SANS-SERIF NUMBER TEN;;;;\n278A;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE;No;0;ON;;;1;1;N;INVERSE CIRCLED SANS-SERIF DIGIT ONE;;;;\n278B;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO;No;0;ON;;;2;2;N;INVERSE CIRCLED SANS-SERIF DIGIT TWO;;;;\n278C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE;No;0;ON;;;3;3;N;INVERSE CIRCLED SANS-SERIF DIGIT THREE;;;;\n278D;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR;No;0;ON;;;4;4;N;INVERSE CIRCLED SANS-SERIF DIGIT FOUR;;;;\n278E;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE;No;0;ON;;;5;5;N;INVERSE CIRCLED SANS-SERIF DIGIT FIVE;;;;\n278F;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX;No;0;ON;;;6;6;N;INVERSE CIRCLED SANS-SERIF DIGIT SIX;;;;\n2790;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN;No;0;ON;;;7;7;N;INVERSE CIRCLED SANS-SERIF DIGIT SEVEN;;;;\n2791;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT;No;0;ON;;;8;8;N;INVERSE CIRCLED SANS-SERIF DIGIT EIGHT;;;;\n2792;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE;No;0;ON;;;9;9;N;INVERSE CIRCLED SANS-SERIF DIGIT NINE;;;;\n2793;DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN;No;0;ON;;;;10;N;INVERSE CIRCLED SANS-SERIF NUMBER TEN;;;;\n2794;HEAVY WIDE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WIDE-HEADED RIGHT ARROW;;;;\n2795;HEAVY PLUS SIGN;So;0;ON;;;;;N;;;;;\n2796;HEAVY MINUS SIGN;So;0;ON;;;;;N;;;;;\n2797;HEAVY DIVISION SIGN;So;0;ON;;;;;N;;;;;\n2798;HEAVY SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT ARROW;;;;\n2799;HEAVY RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY RIGHT ARROW;;;;\n279A;HEAVY NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT ARROW;;;;\n279B;DRAFTING POINT RIGHTWARDS ARROW;So;0;ON;;;;;N;DRAFTING POINT RIGHT ARROW;;;;\n279C;HEAVY ROUND-TIPPED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY ROUND-TIPPED RIGHT ARROW;;;;\n279D;TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;TRIANGLE-HEADED RIGHT ARROW;;;;\n279E;HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TRIANGLE-HEADED RIGHT ARROW;;;;\n279F;DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;DASHED TRIANGLE-HEADED RIGHT ARROW;;;;\n27A0;HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY DASHED TRIANGLE-HEADED RIGHT ARROW;;;;\n27A1;BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK RIGHT ARROW;;;;\n27A2;THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D TOP-LIGHTED RIGHT ARROWHEAD;;;;\n27A3;THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;THREE-D BOTTOM-LIGHTED RIGHT ARROWHEAD;;;;\n27A4;BLACK RIGHTWARDS ARROWHEAD;So;0;ON;;;;;N;BLACK RIGHT ARROWHEAD;;;;\n27A5;HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED DOWN AND RIGHT ARROW;;;;\n27A6;HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK CURVED UP AND RIGHT ARROW;;;;\n27A7;SQUAT BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;SQUAT BLACK RIGHT ARROW;;;;\n27A8;HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY CONCAVE-POINTED BLACK RIGHT ARROW;;;;\n27A9;RIGHT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;RIGHT-SHADED WHITE RIGHT ARROW;;;;\n27AA;LEFT-SHADED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;LEFT-SHADED WHITE RIGHT ARROW;;;;\n27AB;BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;BACK-TILTED SHADOWED WHITE RIGHT ARROW;;;;\n27AC;FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;FRONT-TILTED SHADOWED WHITE RIGHT ARROW;;;;\n27AD;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;\n27AE;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;\n27AF;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;\n27B0;CURLY LOOP;So;0;ON;;;;;N;;;;;\n27B1;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHT ARROW;;;;\n27B2;CIRCLED HEAVY WHITE RIGHTWARDS ARROW;So;0;ON;;;;;N;CIRCLED HEAVY WHITE RIGHT ARROW;;;;\n27B3;WHITE-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;WHITE-FEATHERED RIGHT ARROW;;;;\n27B4;BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED LOWER RIGHT ARROW;;;;\n27B5;BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;BLACK-FEATHERED RIGHT ARROW;;;;\n27B6;BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;BLACK-FEATHERED UPPER RIGHT ARROW;;;;\n27B7;HEAVY BLACK-FEATHERED SOUTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED LOWER RIGHT ARROW;;;;\n27B8;HEAVY BLACK-FEATHERED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED RIGHT ARROW;;;;\n27B9;HEAVY BLACK-FEATHERED NORTH EAST ARROW;So;0;ON;;;;;N;HEAVY BLACK-FEATHERED UPPER RIGHT ARROW;;;;\n27BA;TEARDROP-BARBED RIGHTWARDS ARROW;So;0;ON;;;;;N;TEARDROP-BARBED RIGHT ARROW;;;;\n27BB;HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY TEARDROP-SHANKED RIGHT ARROW;;;;\n27BC;WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;WEDGE-TAILED RIGHT ARROW;;;;\n27BD;HEAVY WEDGE-TAILED RIGHTWARDS ARROW;So;0;ON;;;;;N;HEAVY WEDGE-TAILED RIGHT ARROW;;;;\n27BE;OPEN-OUTLINED RIGHTWARDS ARROW;So;0;ON;;;;;N;OPEN-OUTLINED RIGHT ARROW;;;;\n27BF;DOUBLE CURLY LOOP;So;0;ON;;;;;N;;;;;\n27C0;THREE DIMENSIONAL ANGLE;Sm;0;ON;;;;;Y;;;;;\n27C1;WHITE TRIANGLE CONTAINING SMALL WHITE TRIANGLE;Sm;0;ON;;;;;N;;;;;\n27C2;PERPENDICULAR;Sm;0;ON;;;;;N;;;;;\n27C3;OPEN SUBSET;Sm;0;ON;;;;;Y;;;;;\n27C4;OPEN SUPERSET;Sm;0;ON;;;;;Y;;;;;\n27C5;LEFT S-SHAPED BAG DELIMITER;Ps;0;ON;;;;;Y;;;;;\n27C6;RIGHT S-SHAPED BAG DELIMITER;Pe;0;ON;;;;;Y;;;;;\n27C7;OR WITH DOT INSIDE;Sm;0;ON;;;;;N;;;;;\n27C8;REVERSE SOLIDUS PRECEDING SUBSET;Sm;0;ON;;;;;Y;;;;;\n27C9;SUPERSET PRECEDING SOLIDUS;Sm;0;ON;;;;;Y;;;;;\n27CA;VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;\n27CB;MATHEMATICAL RISING DIAGONAL;Sm;0;ON;;;;;Y;;;;;\n27CC;LONG DIVISION;Sm;0;ON;;;;;Y;;;;;\n27CD;MATHEMATICAL FALLING DIAGONAL;Sm;0;ON;;;;;Y;;;;;\n27CE;SQUARED LOGICAL AND;Sm;0;ON;;;;;N;;;;;\n27CF;SQUARED LOGICAL OR;Sm;0;ON;;;;;N;;;;;\n27D0;WHITE DIAMOND WITH CENTRED DOT;Sm;0;ON;;;;;N;;;;;\n27D1;AND WITH DOT;Sm;0;ON;;;;;N;;;;;\n27D2;ELEMENT OF OPENING UPWARDS;Sm;0;ON;;;;;N;;;;;\n27D3;LOWER RIGHT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;;\n27D4;UPPER LEFT CORNER WITH DOT;Sm;0;ON;;;;;Y;;;;;\n27D5;LEFT OUTER JOIN;Sm;0;ON;;;;;Y;;;;;\n27D6;RIGHT OUTER JOIN;Sm;0;ON;;;;;Y;;;;;\n27D7;FULL OUTER JOIN;Sm;0;ON;;;;;N;;;;;\n27D8;LARGE UP TACK;Sm;0;ON;;;;;N;;;;;\n27D9;LARGE DOWN TACK;Sm;0;ON;;;;;N;;;;;\n27DA;LEFT AND RIGHT DOUBLE TURNSTILE;Sm;0;ON;;;;;N;;;;;\n27DB;LEFT AND RIGHT TACK;Sm;0;ON;;;;;N;;;;;\n27DC;LEFT MULTIMAP;Sm;0;ON;;;;;Y;;;;;\n27DD;LONG RIGHT TACK;Sm;0;ON;;;;;Y;;;;;\n27DE;LONG LEFT TACK;Sm;0;ON;;;;;Y;;;;;\n27DF;UP TACK WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;\n27E0;LOZENGE DIVIDED BY HORIZONTAL RULE;Sm;0;ON;;;;;N;;;;;\n27E1;WHITE CONCAVE-SIDED DIAMOND;Sm;0;ON;;;;;N;;;;;\n27E2;WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;;\n27E3;WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;;\n27E4;WHITE SQUARE WITH LEFTWARDS TICK;Sm;0;ON;;;;;Y;;;;;\n27E5;WHITE SQUARE WITH RIGHTWARDS TICK;Sm;0;ON;;;;;Y;;;;;\n27E6;MATHEMATICAL LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;;;;;\n27E7;MATHEMATICAL RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;;;;;\n27E8;MATHEMATICAL LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;;\n27E9;MATHEMATICAL RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;;\n27EA;MATHEMATICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;;\n27EB;MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;;\n27EC;MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;;\n27ED;MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;;\n27EE;MATHEMATICAL LEFT FLATTENED PARENTHESIS;Ps;0;ON;;;;;Y;;;;;\n27EF;MATHEMATICAL RIGHT FLATTENED PARENTHESIS;Pe;0;ON;;;;;Y;;;;;\n27F0;UPWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;;\n27F1;DOWNWARDS QUADRUPLE ARROW;Sm;0;ON;;;;;N;;;;;\n27F2;ANTICLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;\n27F3;CLOCKWISE GAPPED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;\n27F4;RIGHT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;;\n27F5;LONG LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n27F6;LONG RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n27F7;LONG LEFT RIGHT ARROW;Sm;0;ON;;;;;N;;;;;\n27F8;LONG LEFTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;\n27F9;LONG RIGHTWARDS DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;\n27FA;LONG LEFT RIGHT DOUBLE ARROW;Sm;0;ON;;;;;N;;;;;\n27FB;LONG LEFTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;\n27FC;LONG RIGHTWARDS ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;\n27FD;LONG LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;\n27FE;LONG RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;\n27FF;LONG RIGHTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;;\n2800;BRAILLE PATTERN BLANK;So;0;L;;;;;N;;;;;\n2801;BRAILLE PATTERN DOTS-1;So;0;L;;;;;N;;;;;\n2802;BRAILLE PATTERN DOTS-2;So;0;L;;;;;N;;;;;\n2803;BRAILLE PATTERN DOTS-12;So;0;L;;;;;N;;;;;\n2804;BRAILLE PATTERN DOTS-3;So;0;L;;;;;N;;;;;\n2805;BRAILLE PATTERN DOTS-13;So;0;L;;;;;N;;;;;\n2806;BRAILLE PATTERN DOTS-23;So;0;L;;;;;N;;;;;\n2807;BRAILLE PATTERN DOTS-123;So;0;L;;;;;N;;;;;\n2808;BRAILLE PATTERN DOTS-4;So;0;L;;;;;N;;;;;\n2809;BRAILLE PATTERN DOTS-14;So;0;L;;;;;N;;;;;\n280A;BRAILLE PATTERN DOTS-24;So;0;L;;;;;N;;;;;\n280B;BRAILLE PATTERN DOTS-124;So;0;L;;;;;N;;;;;\n280C;BRAILLE PATTERN DOTS-34;So;0;L;;;;;N;;;;;\n280D;BRAILLE PATTERN DOTS-134;So;0;L;;;;;N;;;;;\n280E;BRAILLE PATTERN DOTS-234;So;0;L;;;;;N;;;;;\n280F;BRAILLE PATTERN DOTS-1234;So;0;L;;;;;N;;;;;\n2810;BRAILLE PATTERN DOTS-5;So;0;L;;;;;N;;;;;\n2811;BRAILLE PATTERN DOTS-15;So;0;L;;;;;N;;;;;\n2812;BRAILLE PATTERN DOTS-25;So;0;L;;;;;N;;;;;\n2813;BRAILLE PATTERN DOTS-125;So;0;L;;;;;N;;;;;\n2814;BRAILLE PATTERN DOTS-35;So;0;L;;;;;N;;;;;\n2815;BRAILLE PATTERN DOTS-135;So;0;L;;;;;N;;;;;\n2816;BRAILLE PATTERN DOTS-235;So;0;L;;;;;N;;;;;\n2817;BRAILLE PATTERN DOTS-1235;So;0;L;;;;;N;;;;;\n2818;BRAILLE PATTERN DOTS-45;So;0;L;;;;;N;;;;;\n2819;BRAILLE PATTERN DOTS-145;So;0;L;;;;;N;;;;;\n281A;BRAILLE PATTERN DOTS-245;So;0;L;;;;;N;;;;;\n281B;BRAILLE PATTERN DOTS-1245;So;0;L;;;;;N;;;;;\n281C;BRAILLE PATTERN DOTS-345;So;0;L;;;;;N;;;;;\n281D;BRAILLE PATTERN DOTS-1345;So;0;L;;;;;N;;;;;\n281E;BRAILLE PATTERN DOTS-2345;So;0;L;;;;;N;;;;;\n281F;BRAILLE PATTERN DOTS-12345;So;0;L;;;;;N;;;;;\n2820;BRAILLE PATTERN DOTS-6;So;0;L;;;;;N;;;;;\n2821;BRAILLE PATTERN DOTS-16;So;0;L;;;;;N;;;;;\n2822;BRAILLE PATTERN DOTS-26;So;0;L;;;;;N;;;;;\n2823;BRAILLE PATTERN DOTS-126;So;0;L;;;;;N;;;;;\n2824;BRAILLE PATTERN DOTS-36;So;0;L;;;;;N;;;;;\n2825;BRAILLE PATTERN DOTS-136;So;0;L;;;;;N;;;;;\n2826;BRAILLE PATTERN DOTS-236;So;0;L;;;;;N;;;;;\n2827;BRAILLE PATTERN DOTS-1236;So;0;L;;;;;N;;;;;\n2828;BRAILLE PATTERN DOTS-46;So;0;L;;;;;N;;;;;\n2829;BRAILLE PATTERN DOTS-146;So;0;L;;;;;N;;;;;\n282A;BRAILLE PATTERN DOTS-246;So;0;L;;;;;N;;;;;\n282B;BRAILLE PATTERN DOTS-1246;So;0;L;;;;;N;;;;;\n282C;BRAILLE PATTERN DOTS-346;So;0;L;;;;;N;;;;;\n282D;BRAILLE PATTERN DOTS-1346;So;0;L;;;;;N;;;;;\n282E;BRAILLE PATTERN DOTS-2346;So;0;L;;;;;N;;;;;\n282F;BRAILLE PATTERN DOTS-12346;So;0;L;;;;;N;;;;;\n2830;BRAILLE PATTERN DOTS-56;So;0;L;;;;;N;;;;;\n2831;BRAILLE PATTERN DOTS-156;So;0;L;;;;;N;;;;;\n2832;BRAILLE PATTERN DOTS-256;So;0;L;;;;;N;;;;;\n2833;BRAILLE PATTERN DOTS-1256;So;0;L;;;;;N;;;;;\n2834;BRAILLE PATTERN DOTS-356;So;0;L;;;;;N;;;;;\n2835;BRAILLE PATTERN DOTS-1356;So;0;L;;;;;N;;;;;\n2836;BRAILLE PATTERN DOTS-2356;So;0;L;;;;;N;;;;;\n2837;BRAILLE PATTERN DOTS-12356;So;0;L;;;;;N;;;;;\n2838;BRAILLE PATTERN DOTS-456;So;0;L;;;;;N;;;;;\n2839;BRAILLE PATTERN DOTS-1456;So;0;L;;;;;N;;;;;\n283A;BRAILLE PATTERN DOTS-2456;So;0;L;;;;;N;;;;;\n283B;BRAILLE PATTERN DOTS-12456;So;0;L;;;;;N;;;;;\n283C;BRAILLE PATTERN DOTS-3456;So;0;L;;;;;N;;;;;\n283D;BRAILLE PATTERN DOTS-13456;So;0;L;;;;;N;;;;;\n283E;BRAILLE PATTERN DOTS-23456;So;0;L;;;;;N;;;;;\n283F;BRAILLE PATTERN DOTS-123456;So;0;L;;;;;N;;;;;\n2840;BRAILLE PATTERN DOTS-7;So;0;L;;;;;N;;;;;\n2841;BRAILLE PATTERN DOTS-17;So;0;L;;;;;N;;;;;\n2842;BRAILLE PATTERN DOTS-27;So;0;L;;;;;N;;;;;\n2843;BRAILLE PATTERN DOTS-127;So;0;L;;;;;N;;;;;\n2844;BRAILLE PATTERN DOTS-37;So;0;L;;;;;N;;;;;\n2845;BRAILLE PATTERN DOTS-137;So;0;L;;;;;N;;;;;\n2846;BRAILLE PATTERN DOTS-237;So;0;L;;;;;N;;;;;\n2847;BRAILLE PATTERN DOTS-1237;So;0;L;;;;;N;;;;;\n2848;BRAILLE PATTERN DOTS-47;So;0;L;;;;;N;;;;;\n2849;BRAILLE PATTERN DOTS-147;So;0;L;;;;;N;;;;;\n284A;BRAILLE PATTERN DOTS-247;So;0;L;;;;;N;;;;;\n284B;BRAILLE PATTERN DOTS-1247;So;0;L;;;;;N;;;;;\n284C;BRAILLE PATTERN DOTS-347;So;0;L;;;;;N;;;;;\n284D;BRAILLE PATTERN DOTS-1347;So;0;L;;;;;N;;;;;\n284E;BRAILLE PATTERN DOTS-2347;So;0;L;;;;;N;;;;;\n284F;BRAILLE PATTERN DOTS-12347;So;0;L;;;;;N;;;;;\n2850;BRAILLE PATTERN DOTS-57;So;0;L;;;;;N;;;;;\n2851;BRAILLE PATTERN DOTS-157;So;0;L;;;;;N;;;;;\n2852;BRAILLE PATTERN DOTS-257;So;0;L;;;;;N;;;;;\n2853;BRAILLE PATTERN DOTS-1257;So;0;L;;;;;N;;;;;\n2854;BRAILLE PATTERN DOTS-357;So;0;L;;;;;N;;;;;\n2855;BRAILLE PATTERN DOTS-1357;So;0;L;;;;;N;;;;;\n2856;BRAILLE PATTERN DOTS-2357;So;0;L;;;;;N;;;;;\n2857;BRAILLE PATTERN DOTS-12357;So;0;L;;;;;N;;;;;\n2858;BRAILLE PATTERN DOTS-457;So;0;L;;;;;N;;;;;\n2859;BRAILLE PATTERN DOTS-1457;So;0;L;;;;;N;;;;;\n285A;BRAILLE PATTERN DOTS-2457;So;0;L;;;;;N;;;;;\n285B;BRAILLE PATTERN DOTS-12457;So;0;L;;;;;N;;;;;\n285C;BRAILLE PATTERN DOTS-3457;So;0;L;;;;;N;;;;;\n285D;BRAILLE PATTERN DOTS-13457;So;0;L;;;;;N;;;;;\n285E;BRAILLE PATTERN DOTS-23457;So;0;L;;;;;N;;;;;\n285F;BRAILLE PATTERN DOTS-123457;So;0;L;;;;;N;;;;;\n2860;BRAILLE PATTERN DOTS-67;So;0;L;;;;;N;;;;;\n2861;BRAILLE PATTERN DOTS-167;So;0;L;;;;;N;;;;;\n2862;BRAILLE PATTERN DOTS-267;So;0;L;;;;;N;;;;;\n2863;BRAILLE PATTERN DOTS-1267;So;0;L;;;;;N;;;;;\n2864;BRAILLE PATTERN DOTS-367;So;0;L;;;;;N;;;;;\n2865;BRAILLE PATTERN DOTS-1367;So;0;L;;;;;N;;;;;\n2866;BRAILLE PATTERN DOTS-2367;So;0;L;;;;;N;;;;;\n2867;BRAILLE PATTERN DOTS-12367;So;0;L;;;;;N;;;;;\n2868;BRAILLE PATTERN DOTS-467;So;0;L;;;;;N;;;;;\n2869;BRAILLE PATTERN DOTS-1467;So;0;L;;;;;N;;;;;\n286A;BRAILLE PATTERN DOTS-2467;So;0;L;;;;;N;;;;;\n286B;BRAILLE PATTERN DOTS-12467;So;0;L;;;;;N;;;;;\n286C;BRAILLE PATTERN DOTS-3467;So;0;L;;;;;N;;;;;\n286D;BRAILLE PATTERN DOTS-13467;So;0;L;;;;;N;;;;;\n286E;BRAILLE PATTERN DOTS-23467;So;0;L;;;;;N;;;;;\n286F;BRAILLE PATTERN DOTS-123467;So;0;L;;;;;N;;;;;\n2870;BRAILLE PATTERN DOTS-567;So;0;L;;;;;N;;;;;\n2871;BRAILLE PATTERN DOTS-1567;So;0;L;;;;;N;;;;;\n2872;BRAILLE PATTERN DOTS-2567;So;0;L;;;;;N;;;;;\n2873;BRAILLE PATTERN DOTS-12567;So;0;L;;;;;N;;;;;\n2874;BRAILLE PATTERN DOTS-3567;So;0;L;;;;;N;;;;;\n2875;BRAILLE PATTERN DOTS-13567;So;0;L;;;;;N;;;;;\n2876;BRAILLE PATTERN DOTS-23567;So;0;L;;;;;N;;;;;\n2877;BRAILLE PATTERN DOTS-123567;So;0;L;;;;;N;;;;;\n2878;BRAILLE PATTERN DOTS-4567;So;0;L;;;;;N;;;;;\n2879;BRAILLE PATTERN DOTS-14567;So;0;L;;;;;N;;;;;\n287A;BRAILLE PATTERN DOTS-24567;So;0;L;;;;;N;;;;;\n287B;BRAILLE PATTERN DOTS-124567;So;0;L;;;;;N;;;;;\n287C;BRAILLE PATTERN DOTS-34567;So;0;L;;;;;N;;;;;\n287D;BRAILLE PATTERN DOTS-134567;So;0;L;;;;;N;;;;;\n287E;BRAILLE PATTERN DOTS-234567;So;0;L;;;;;N;;;;;\n287F;BRAILLE PATTERN DOTS-1234567;So;0;L;;;;;N;;;;;\n2880;BRAILLE PATTERN DOTS-8;So;0;L;;;;;N;;;;;\n2881;BRAILLE PATTERN DOTS-18;So;0;L;;;;;N;;;;;\n2882;BRAILLE PATTERN DOTS-28;So;0;L;;;;;N;;;;;\n2883;BRAILLE PATTERN DOTS-128;So;0;L;;;;;N;;;;;\n2884;BRAILLE PATTERN DOTS-38;So;0;L;;;;;N;;;;;\n2885;BRAILLE PATTERN DOTS-138;So;0;L;;;;;N;;;;;\n2886;BRAILLE PATTERN DOTS-238;So;0;L;;;;;N;;;;;\n2887;BRAILLE PATTERN DOTS-1238;So;0;L;;;;;N;;;;;\n2888;BRAILLE PATTERN DOTS-48;So;0;L;;;;;N;;;;;\n2889;BRAILLE PATTERN DOTS-148;So;0;L;;;;;N;;;;;\n288A;BRAILLE PATTERN DOTS-248;So;0;L;;;;;N;;;;;\n288B;BRAILLE PATTERN DOTS-1248;So;0;L;;;;;N;;;;;\n288C;BRAILLE PATTERN DOTS-348;So;0;L;;;;;N;;;;;\n288D;BRAILLE PATTERN DOTS-1348;So;0;L;;;;;N;;;;;\n288E;BRAILLE PATTERN DOTS-2348;So;0;L;;;;;N;;;;;\n288F;BRAILLE PATTERN DOTS-12348;So;0;L;;;;;N;;;;;\n2890;BRAILLE PATTERN DOTS-58;So;0;L;;;;;N;;;;;\n2891;BRAILLE PATTERN DOTS-158;So;0;L;;;;;N;;;;;\n2892;BRAILLE PATTERN DOTS-258;So;0;L;;;;;N;;;;;\n2893;BRAILLE PATTERN DOTS-1258;So;0;L;;;;;N;;;;;\n2894;BRAILLE PATTERN DOTS-358;So;0;L;;;;;N;;;;;\n2895;BRAILLE PATTERN DOTS-1358;So;0;L;;;;;N;;;;;\n2896;BRAILLE PATTERN DOTS-2358;So;0;L;;;;;N;;;;;\n2897;BRAILLE PATTERN DOTS-12358;So;0;L;;;;;N;;;;;\n2898;BRAILLE PATTERN DOTS-458;So;0;L;;;;;N;;;;;\n2899;BRAILLE PATTERN DOTS-1458;So;0;L;;;;;N;;;;;\n289A;BRAILLE PATTERN DOTS-2458;So;0;L;;;;;N;;;;;\n289B;BRAILLE PATTERN DOTS-12458;So;0;L;;;;;N;;;;;\n289C;BRAILLE PATTERN DOTS-3458;So;0;L;;;;;N;;;;;\n289D;BRAILLE PATTERN DOTS-13458;So;0;L;;;;;N;;;;;\n289E;BRAILLE PATTERN DOTS-23458;So;0;L;;;;;N;;;;;\n289F;BRAILLE PATTERN DOTS-123458;So;0;L;;;;;N;;;;;\n28A0;BRAILLE PATTERN DOTS-68;So;0;L;;;;;N;;;;;\n28A1;BRAILLE PATTERN DOTS-168;So;0;L;;;;;N;;;;;\n28A2;BRAILLE PATTERN DOTS-268;So;0;L;;;;;N;;;;;\n28A3;BRAILLE PATTERN DOTS-1268;So;0;L;;;;;N;;;;;\n28A4;BRAILLE PATTERN DOTS-368;So;0;L;;;;;N;;;;;\n28A5;BRAILLE PATTERN DOTS-1368;So;0;L;;;;;N;;;;;\n28A6;BRAILLE PATTERN DOTS-2368;So;0;L;;;;;N;;;;;\n28A7;BRAILLE PATTERN DOTS-12368;So;0;L;;;;;N;;;;;\n28A8;BRAILLE PATTERN DOTS-468;So;0;L;;;;;N;;;;;\n28A9;BRAILLE PATTERN DOTS-1468;So;0;L;;;;;N;;;;;\n28AA;BRAILLE PATTERN DOTS-2468;So;0;L;;;;;N;;;;;\n28AB;BRAILLE PATTERN DOTS-12468;So;0;L;;;;;N;;;;;\n28AC;BRAILLE PATTERN DOTS-3468;So;0;L;;;;;N;;;;;\n28AD;BRAILLE PATTERN DOTS-13468;So;0;L;;;;;N;;;;;\n28AE;BRAILLE PATTERN DOTS-23468;So;0;L;;;;;N;;;;;\n28AF;BRAILLE PATTERN DOTS-123468;So;0;L;;;;;N;;;;;\n28B0;BRAILLE PATTERN DOTS-568;So;0;L;;;;;N;;;;;\n28B1;BRAILLE PATTERN DOTS-1568;So;0;L;;;;;N;;;;;\n28B2;BRAILLE PATTERN DOTS-2568;So;0;L;;;;;N;;;;;\n28B3;BRAILLE PATTERN DOTS-12568;So;0;L;;;;;N;;;;;\n28B4;BRAILLE PATTERN DOTS-3568;So;0;L;;;;;N;;;;;\n28B5;BRAILLE PATTERN DOTS-13568;So;0;L;;;;;N;;;;;\n28B6;BRAILLE PATTERN DOTS-23568;So;0;L;;;;;N;;;;;\n28B7;BRAILLE PATTERN DOTS-123568;So;0;L;;;;;N;;;;;\n28B8;BRAILLE PATTERN DOTS-4568;So;0;L;;;;;N;;;;;\n28B9;BRAILLE PATTERN DOTS-14568;So;0;L;;;;;N;;;;;\n28BA;BRAILLE PATTERN DOTS-24568;So;0;L;;;;;N;;;;;\n28BB;BRAILLE PATTERN DOTS-124568;So;0;L;;;;;N;;;;;\n28BC;BRAILLE PATTERN DOTS-34568;So;0;L;;;;;N;;;;;\n28BD;BRAILLE PATTERN DOTS-134568;So;0;L;;;;;N;;;;;\n28BE;BRAILLE PATTERN DOTS-234568;So;0;L;;;;;N;;;;;\n28BF;BRAILLE PATTERN DOTS-1234568;So;0;L;;;;;N;;;;;\n28C0;BRAILLE PATTERN DOTS-78;So;0;L;;;;;N;;;;;\n28C1;BRAILLE PATTERN DOTS-178;So;0;L;;;;;N;;;;;\n28C2;BRAILLE PATTERN DOTS-278;So;0;L;;;;;N;;;;;\n28C3;BRAILLE PATTERN DOTS-1278;So;0;L;;;;;N;;;;;\n28C4;BRAILLE PATTERN DOTS-378;So;0;L;;;;;N;;;;;\n28C5;BRAILLE PATTERN DOTS-1378;So;0;L;;;;;N;;;;;\n28C6;BRAILLE PATTERN DOTS-2378;So;0;L;;;;;N;;;;;\n28C7;BRAILLE PATTERN DOTS-12378;So;0;L;;;;;N;;;;;\n28C8;BRAILLE PATTERN DOTS-478;So;0;L;;;;;N;;;;;\n28C9;BRAILLE PATTERN DOTS-1478;So;0;L;;;;;N;;;;;\n28CA;BRAILLE PATTERN DOTS-2478;So;0;L;;;;;N;;;;;\n28CB;BRAILLE PATTERN DOTS-12478;So;0;L;;;;;N;;;;;\n28CC;BRAILLE PATTERN DOTS-3478;So;0;L;;;;;N;;;;;\n28CD;BRAILLE PATTERN DOTS-13478;So;0;L;;;;;N;;;;;\n28CE;BRAILLE PATTERN DOTS-23478;So;0;L;;;;;N;;;;;\n28CF;BRAILLE PATTERN DOTS-123478;So;0;L;;;;;N;;;;;\n28D0;BRAILLE PATTERN DOTS-578;So;0;L;;;;;N;;;;;\n28D1;BRAILLE PATTERN DOTS-1578;So;0;L;;;;;N;;;;;\n28D2;BRAILLE PATTERN DOTS-2578;So;0;L;;;;;N;;;;;\n28D3;BRAILLE PATTERN DOTS-12578;So;0;L;;;;;N;;;;;\n28D4;BRAILLE PATTERN DOTS-3578;So;0;L;;;;;N;;;;;\n28D5;BRAILLE PATTERN DOTS-13578;So;0;L;;;;;N;;;;;\n28D6;BRAILLE PATTERN DOTS-23578;So;0;L;;;;;N;;;;;\n28D7;BRAILLE PATTERN DOTS-123578;So;0;L;;;;;N;;;;;\n28D8;BRAILLE PATTERN DOTS-4578;So;0;L;;;;;N;;;;;\n28D9;BRAILLE PATTERN DOTS-14578;So;0;L;;;;;N;;;;;\n28DA;BRAILLE PATTERN DOTS-24578;So;0;L;;;;;N;;;;;\n28DB;BRAILLE PATTERN DOTS-124578;So;0;L;;;;;N;;;;;\n28DC;BRAILLE PATTERN DOTS-34578;So;0;L;;;;;N;;;;;\n28DD;BRAILLE PATTERN DOTS-134578;So;0;L;;;;;N;;;;;\n28DE;BRAILLE PATTERN DOTS-234578;So;0;L;;;;;N;;;;;\n28DF;BRAILLE PATTERN DOTS-1234578;So;0;L;;;;;N;;;;;\n28E0;BRAILLE PATTERN DOTS-678;So;0;L;;;;;N;;;;;\n28E1;BRAILLE PATTERN DOTS-1678;So;0;L;;;;;N;;;;;\n28E2;BRAILLE PATTERN DOTS-2678;So;0;L;;;;;N;;;;;\n28E3;BRAILLE PATTERN DOTS-12678;So;0;L;;;;;N;;;;;\n28E4;BRAILLE PATTERN DOTS-3678;So;0;L;;;;;N;;;;;\n28E5;BRAILLE PATTERN DOTS-13678;So;0;L;;;;;N;;;;;\n28E6;BRAILLE PATTERN DOTS-23678;So;0;L;;;;;N;;;;;\n28E7;BRAILLE PATTERN DOTS-123678;So;0;L;;;;;N;;;;;\n28E8;BRAILLE PATTERN DOTS-4678;So;0;L;;;;;N;;;;;\n28E9;BRAILLE PATTERN DOTS-14678;So;0;L;;;;;N;;;;;\n28EA;BRAILLE PATTERN DOTS-24678;So;0;L;;;;;N;;;;;\n28EB;BRAILLE PATTERN DOTS-124678;So;0;L;;;;;N;;;;;\n28EC;BRAILLE PATTERN DOTS-34678;So;0;L;;;;;N;;;;;\n28ED;BRAILLE PATTERN DOTS-134678;So;0;L;;;;;N;;;;;\n28EE;BRAILLE PATTERN DOTS-234678;So;0;L;;;;;N;;;;;\n28EF;BRAILLE PATTERN DOTS-1234678;So;0;L;;;;;N;;;;;\n28F0;BRAILLE PATTERN DOTS-5678;So;0;L;;;;;N;;;;;\n28F1;BRAILLE PATTERN DOTS-15678;So;0;L;;;;;N;;;;;\n28F2;BRAILLE PATTERN DOTS-25678;So;0;L;;;;;N;;;;;\n28F3;BRAILLE PATTERN DOTS-125678;So;0;L;;;;;N;;;;;\n28F4;BRAILLE PATTERN DOTS-35678;So;0;L;;;;;N;;;;;\n28F5;BRAILLE PATTERN DOTS-135678;So;0;L;;;;;N;;;;;\n28F6;BRAILLE PATTERN DOTS-235678;So;0;L;;;;;N;;;;;\n28F7;BRAILLE PATTERN DOTS-1235678;So;0;L;;;;;N;;;;;\n28F8;BRAILLE PATTERN DOTS-45678;So;0;L;;;;;N;;;;;\n28F9;BRAILLE PATTERN DOTS-145678;So;0;L;;;;;N;;;;;\n28FA;BRAILLE PATTERN DOTS-245678;So;0;L;;;;;N;;;;;\n28FB;BRAILLE PATTERN DOTS-1245678;So;0;L;;;;;N;;;;;\n28FC;BRAILLE PATTERN DOTS-345678;So;0;L;;;;;N;;;;;\n28FD;BRAILLE PATTERN DOTS-1345678;So;0;L;;;;;N;;;;;\n28FE;BRAILLE PATTERN DOTS-2345678;So;0;L;;;;;N;;;;;\n28FF;BRAILLE PATTERN DOTS-12345678;So;0;L;;;;;N;;;;;\n2900;RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2901;RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2902;LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2903;RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2904;LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2905;RIGHTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;\n2906;LEFTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;\n2907;RIGHTWARDS DOUBLE ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;\n2908;DOWNWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;\n2909;UPWARDS ARROW WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;\n290A;UPWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;;\n290B;DOWNWARDS TRIPLE ARROW;Sm;0;ON;;;;;N;;;;;\n290C;LEFTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;;\n290D;RIGHTWARDS DOUBLE DASH ARROW;Sm;0;ON;;;;;N;;;;;\n290E;LEFTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;\n290F;RIGHTWARDS TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;\n2910;RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;\n2911;RIGHTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;;\n2912;UPWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;;\n2913;DOWNWARDS ARROW TO BAR;Sm;0;ON;;;;;N;;;;;\n2914;RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2915;RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2916;RIGHTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;;\n2917;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2918;RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2919;LEFTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;;\n291A;RIGHTWARDS ARROW-TAIL;Sm;0;ON;;;;;N;;;;;\n291B;LEFTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;;\n291C;RIGHTWARDS DOUBLE ARROW-TAIL;Sm;0;ON;;;;;N;;;;;\n291D;LEFTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;\n291E;RIGHTWARDS ARROW TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;\n291F;LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;\n2920;RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;\n2921;NORTH WEST AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;\n2922;NORTH EAST AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;;\n2923;NORTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;\n2924;NORTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;\n2925;SOUTH EAST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;\n2926;SOUTH WEST ARROW WITH HOOK;Sm;0;ON;;;;;N;;;;;\n2927;NORTH WEST ARROW AND NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;\n2928;NORTH EAST ARROW AND SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;\n2929;SOUTH EAST ARROW AND SOUTH WEST ARROW;Sm;0;ON;;;;;N;;;;;\n292A;SOUTH WEST ARROW AND NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;;\n292B;RISING DIAGONAL CROSSING FALLING DIAGONAL;Sm;0;ON;;;;;N;;;;;\n292C;FALLING DIAGONAL CROSSING RISING DIAGONAL;Sm;0;ON;;;;;N;;;;;\n292D;SOUTH EAST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;\n292E;NORTH EAST ARROW CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;\n292F;FALLING DIAGONAL CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;\n2930;RISING DIAGONAL CROSSING SOUTH EAST ARROW;Sm;0;ON;;;;;N;;;;;\n2931;NORTH EAST ARROW CROSSING NORTH WEST ARROW;Sm;0;ON;;;;;N;;;;;\n2932;NORTH WEST ARROW CROSSING NORTH EAST ARROW;Sm;0;ON;;;;;N;;;;;\n2933;WAVE ARROW POINTING DIRECTLY RIGHT;Sm;0;ON;;;;;N;;;;;\n2934;ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS;Sm;0;ON;;;;;N;;;;;\n2935;ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS;Sm;0;ON;;;;;N;;;;;\n2936;ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS;Sm;0;ON;;;;;N;;;;;\n2937;ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS;Sm;0;ON;;;;;N;;;;;\n2938;RIGHT-SIDE ARC CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;\n2939;LEFT-SIDE ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;\n293A;TOP ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;\n293B;BOTTOM ARC ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;\n293C;TOP ARC CLOCKWISE ARROW WITH MINUS;Sm;0;ON;;;;;N;;;;;\n293D;TOP ARC ANTICLOCKWISE ARROW WITH PLUS;Sm;0;ON;;;;;N;;;;;\n293E;LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;\n293F;LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW;Sm;0;ON;;;;;N;;;;;\n2940;ANTICLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;\n2941;CLOCKWISE CLOSED CIRCLE ARROW;Sm;0;ON;;;;;N;;;;;\n2942;RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n2943;LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n2944;SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n2945;RIGHTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;;\n2946;LEFTWARDS ARROW WITH PLUS BELOW;Sm;0;ON;;;;;N;;;;;\n2947;RIGHTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;;\n2948;LEFT RIGHT ARROW THROUGH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;\n2949;UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;\n294A;LEFT BARB UP RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;;\n294B;LEFT BARB DOWN RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;;\n294C;UP BARB RIGHT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;;\n294D;UP BARB LEFT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;;\n294E;LEFT BARB UP RIGHT BARB UP HARPOON;Sm;0;ON;;;;;N;;;;;\n294F;UP BARB RIGHT DOWN BARB RIGHT HARPOON;Sm;0;ON;;;;;N;;;;;\n2950;LEFT BARB DOWN RIGHT BARB DOWN HARPOON;Sm;0;ON;;;;;N;;;;;\n2951;UP BARB LEFT DOWN BARB LEFT HARPOON;Sm;0;ON;;;;;N;;;;;\n2952;LEFTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;;\n2953;RIGHTWARDS HARPOON WITH BARB UP TO BAR;Sm;0;ON;;;;;N;;;;;\n2954;UPWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;;\n2955;DOWNWARDS HARPOON WITH BARB RIGHT TO BAR;Sm;0;ON;;;;;N;;;;;\n2956;LEFTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;;\n2957;RIGHTWARDS HARPOON WITH BARB DOWN TO BAR;Sm;0;ON;;;;;N;;;;;\n2958;UPWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;;\n2959;DOWNWARDS HARPOON WITH BARB LEFT TO BAR;Sm;0;ON;;;;;N;;;;;\n295A;LEFTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;;\n295B;RIGHTWARDS HARPOON WITH BARB UP FROM BAR;Sm;0;ON;;;;;N;;;;;\n295C;UPWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;;\n295D;DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR;Sm;0;ON;;;;;N;;;;;\n295E;LEFTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;;\n295F;RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR;Sm;0;ON;;;;;N;;;;;\n2960;UPWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;;\n2961;DOWNWARDS HARPOON WITH BARB LEFT FROM BAR;Sm;0;ON;;;;;N;;;;;\n2962;LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;\n2963;UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;\n2964;RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;\n2965;DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;\n2966;LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;;\n2967;LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;\n2968;RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP;Sm;0;ON;;;;;N;;;;;\n2969;RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN;Sm;0;ON;;;;;N;;;;;\n296A;LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;;\n296B;LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;;\n296C;RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH;Sm;0;ON;;;;;N;;;;;\n296D;RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH;Sm;0;ON;;;;;N;;;;;\n296E;UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;\n296F;DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT;Sm;0;ON;;;;;N;;;;;\n2970;RIGHT DOUBLE ARROW WITH ROUNDED HEAD;Sm;0;ON;;;;;N;;;;;\n2971;EQUALS SIGN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n2972;TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n2973;LEFTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;\n2974;RIGHTWARDS ARROW ABOVE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;\n2975;RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;\n2976;LESS-THAN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n2977;LEFTWARDS ARROW THROUGH LESS-THAN;Sm;0;ON;;;;;N;;;;;\n2978;GREATER-THAN ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n2979;SUBSET ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n297A;LEFTWARDS ARROW THROUGH SUBSET;Sm;0;ON;;;;;N;;;;;\n297B;SUPERSET ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n297C;LEFT FISH TAIL;Sm;0;ON;;;;;N;;;;;\n297D;RIGHT FISH TAIL;Sm;0;ON;;;;;N;;;;;\n297E;UP FISH TAIL;Sm;0;ON;;;;;N;;;;;\n297F;DOWN FISH TAIL;Sm;0;ON;;;;;N;;;;;\n2980;TRIPLE VERTICAL BAR DELIMITER;Sm;0;ON;;;;;N;;;;;\n2981;Z NOTATION SPOT;Sm;0;ON;;;;;N;;;;;\n2982;Z NOTATION TYPE COLON;Sm;0;ON;;;;;N;;;;;\n2983;LEFT WHITE CURLY BRACKET;Ps;0;ON;;;;;Y;;;;;\n2984;RIGHT WHITE CURLY BRACKET;Pe;0;ON;;;;;Y;;;;;\n2985;LEFT WHITE PARENTHESIS;Ps;0;ON;;;;;Y;;;;;\n2986;RIGHT WHITE PARENTHESIS;Pe;0;ON;;;;;Y;;;;;\n2987;Z NOTATION LEFT IMAGE BRACKET;Ps;0;ON;;;;;Y;;;;;\n2988;Z NOTATION RIGHT IMAGE BRACKET;Pe;0;ON;;;;;Y;;;;;\n2989;Z NOTATION LEFT BINDING BRACKET;Ps;0;ON;;;;;Y;;;;;\n298A;Z NOTATION RIGHT BINDING BRACKET;Pe;0;ON;;;;;Y;;;;;\n298B;LEFT SQUARE BRACKET WITH UNDERBAR;Ps;0;ON;;;;;Y;;;;;\n298C;RIGHT SQUARE BRACKET WITH UNDERBAR;Pe;0;ON;;;;;Y;;;;;\n298D;LEFT SQUARE BRACKET WITH TICK IN TOP CORNER;Ps;0;ON;;;;;Y;;;;;\n298E;RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Pe;0;ON;;;;;Y;;;;;\n298F;LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER;Ps;0;ON;;;;;Y;;;;;\n2990;RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER;Pe;0;ON;;;;;Y;;;;;\n2991;LEFT ANGLE BRACKET WITH DOT;Ps;0;ON;;;;;Y;;;;;\n2992;RIGHT ANGLE BRACKET WITH DOT;Pe;0;ON;;;;;Y;;;;;\n2993;LEFT ARC LESS-THAN BRACKET;Ps;0;ON;;;;;Y;;;;;\n2994;RIGHT ARC GREATER-THAN BRACKET;Pe;0;ON;;;;;Y;;;;;\n2995;DOUBLE LEFT ARC GREATER-THAN BRACKET;Ps;0;ON;;;;;Y;;;;;\n2996;DOUBLE RIGHT ARC LESS-THAN BRACKET;Pe;0;ON;;;;;Y;;;;;\n2997;LEFT BLACK TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;;;;;\n2998;RIGHT BLACK TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;;;;;\n2999;DOTTED FENCE;Sm;0;ON;;;;;N;;;;;\n299A;VERTICAL ZIGZAG LINE;Sm;0;ON;;;;;N;;;;;\n299B;MEASURED ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;;\n299C;RIGHT ANGLE VARIANT WITH SQUARE;Sm;0;ON;;;;;Y;;;;;\n299D;MEASURED RIGHT ANGLE WITH DOT;Sm;0;ON;;;;;Y;;;;;\n299E;ANGLE WITH S INSIDE;Sm;0;ON;;;;;Y;;;;;\n299F;ACUTE ANGLE;Sm;0;ON;;;;;Y;;;;;\n29A0;SPHERICAL ANGLE OPENING LEFT;Sm;0;ON;;;;;Y;;;;;\n29A1;SPHERICAL ANGLE OPENING UP;Sm;0;ON;;;;;N;;;;;\n29A2;TURNED ANGLE;Sm;0;ON;;;;;Y;;;;;\n29A3;REVERSED ANGLE;Sm;0;ON;;;;;Y;;;;;\n29A4;ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;\n29A5;REVERSED ANGLE WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;\n29A6;OBLIQUE ANGLE OPENING UP;Sm;0;ON;;;;;Y;;;;;\n29A7;OBLIQUE ANGLE OPENING DOWN;Sm;0;ON;;;;;Y;;;;;\n29A8;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT;Sm;0;ON;;;;;Y;;;;;\n29A9;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT;Sm;0;ON;;;;;Y;;;;;\n29AA;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT;Sm;0;ON;;;;;Y;;;;;\n29AB;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT;Sm;0;ON;;;;;Y;;;;;\n29AC;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP;Sm;0;ON;;;;;Y;;;;;\n29AD;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP;Sm;0;ON;;;;;Y;;;;;\n29AE;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN;Sm;0;ON;;;;;Y;;;;;\n29AF;MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN;Sm;0;ON;;;;;Y;;;;;\n29B0;REVERSED EMPTY SET;Sm;0;ON;;;;;N;;;;;\n29B1;EMPTY SET WITH OVERBAR;Sm;0;ON;;;;;N;;;;;\n29B2;EMPTY SET WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;\n29B3;EMPTY SET WITH RIGHT ARROW ABOVE;Sm;0;ON;;;;;N;;;;;\n29B4;EMPTY SET WITH LEFT ARROW ABOVE;Sm;0;ON;;;;;N;;;;;\n29B5;CIRCLE WITH HORIZONTAL BAR;Sm;0;ON;;;;;N;;;;;\n29B6;CIRCLED VERTICAL BAR;Sm;0;ON;;;;;N;;;;;\n29B7;CIRCLED PARALLEL;Sm;0;ON;;;;;N;;;;;\n29B8;CIRCLED REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;;\n29B9;CIRCLED PERPENDICULAR;Sm;0;ON;;;;;N;;;;;\n29BA;CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR;Sm;0;ON;;;;;N;;;;;\n29BB;CIRCLE WITH SUPERIMPOSED X;Sm;0;ON;;;;;N;;;;;\n29BC;CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN;Sm;0;ON;;;;;N;;;;;\n29BD;UP ARROW THROUGH CIRCLE;Sm;0;ON;;;;;N;;;;;\n29BE;CIRCLED WHITE BULLET;Sm;0;ON;;;;;N;;;;;\n29BF;CIRCLED BULLET;Sm;0;ON;;;;;N;;;;;\n29C0;CIRCLED LESS-THAN;Sm;0;ON;;;;;Y;;;;;\n29C1;CIRCLED GREATER-THAN;Sm;0;ON;;;;;Y;;;;;\n29C2;CIRCLE WITH SMALL CIRCLE TO THE RIGHT;Sm;0;ON;;;;;Y;;;;;\n29C3;CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT;Sm;0;ON;;;;;Y;;;;;\n29C4;SQUARED RISING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;;\n29C5;SQUARED FALLING DIAGONAL SLASH;Sm;0;ON;;;;;Y;;;;;\n29C6;SQUARED ASTERISK;Sm;0;ON;;;;;N;;;;;\n29C7;SQUARED SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;\n29C8;SQUARED SQUARE;Sm;0;ON;;;;;N;;;;;\n29C9;TWO JOINED SQUARES;Sm;0;ON;;;;;Y;;;;;\n29CA;TRIANGLE WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;\n29CB;TRIANGLE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;\n29CC;S IN TRIANGLE;Sm;0;ON;;;;;N;;;;;\n29CD;TRIANGLE WITH SERIFS AT BOTTOM;Sm;0;ON;;;;;N;;;;;\n29CE;RIGHT TRIANGLE ABOVE LEFT TRIANGLE;Sm;0;ON;;;;;Y;;;;;\n29CF;LEFT TRIANGLE BESIDE VERTICAL BAR;Sm;0;ON;;;;;Y;;;;;\n29D0;VERTICAL BAR BESIDE RIGHT TRIANGLE;Sm;0;ON;;;;;Y;;;;;\n29D1;BOWTIE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;;\n29D2;BOWTIE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;;\n29D3;BLACK BOWTIE;Sm;0;ON;;;;;N;;;;;\n29D4;TIMES WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;;\n29D5;TIMES WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;;\n29D6;WHITE HOURGLASS;Sm;0;ON;;;;;N;;;;;\n29D7;BLACK HOURGLASS;Sm;0;ON;;;;;N;;;;;\n29D8;LEFT WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;;\n29D9;RIGHT WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;;\n29DA;LEFT DOUBLE WIGGLY FENCE;Ps;0;ON;;;;;Y;;;;;\n29DB;RIGHT DOUBLE WIGGLY FENCE;Pe;0;ON;;;;;Y;;;;;\n29DC;INCOMPLETE INFINITY;Sm;0;ON;;;;;Y;;;;;\n29DD;TIE OVER INFINITY;Sm;0;ON;;;;;N;;;;;\n29DE;INFINITY NEGATED WITH VERTICAL BAR;Sm;0;ON;;;;;N;;;;;\n29DF;DOUBLE-ENDED MULTIMAP;Sm;0;ON;;;;;N;;;;;\n29E0;SQUARE WITH CONTOURED OUTLINE;Sm;0;ON;;;;;N;;;;;\n29E1;INCREASES AS;Sm;0;ON;;;;;Y;;;;;\n29E2;SHUFFLE PRODUCT;Sm;0;ON;;;;;N;;;;;\n29E3;EQUALS SIGN AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;;\n29E4;EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;;\n29E5;IDENTICAL TO AND SLANTED PARALLEL;Sm;0;ON;;;;;Y;;;;;\n29E6;GLEICH STARK;Sm;0;ON;;;;;N;;;;;\n29E7;THERMODYNAMIC;Sm;0;ON;;;;;N;;;;;\n29E8;DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK;Sm;0;ON;;;;;Y;;;;;\n29E9;DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK;Sm;0;ON;;;;;Y;;;;;\n29EA;BLACK DIAMOND WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;;\n29EB;BLACK LOZENGE;Sm;0;ON;;;;;N;;;;;\n29EC;WHITE CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;;\n29ED;BLACK CIRCLE WITH DOWN ARROW;Sm;0;ON;;;;;N;;;;;\n29EE;ERROR-BARRED WHITE SQUARE;Sm;0;ON;;;;;N;;;;;\n29EF;ERROR-BARRED BLACK SQUARE;Sm;0;ON;;;;;N;;;;;\n29F0;ERROR-BARRED WHITE DIAMOND;Sm;0;ON;;;;;N;;;;;\n29F1;ERROR-BARRED BLACK DIAMOND;Sm;0;ON;;;;;N;;;;;\n29F2;ERROR-BARRED WHITE CIRCLE;Sm;0;ON;;;;;N;;;;;\n29F3;ERROR-BARRED BLACK CIRCLE;Sm;0;ON;;;;;N;;;;;\n29F4;RULE-DELAYED;Sm;0;ON;;;;;Y;;;;;\n29F5;REVERSE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;;\n29F6;SOLIDUS WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;\n29F7;REVERSE SOLIDUS WITH HORIZONTAL STROKE;Sm;0;ON;;;;;Y;;;;;\n29F8;BIG SOLIDUS;Sm;0;ON;;;;;Y;;;;;\n29F9;BIG REVERSE SOLIDUS;Sm;0;ON;;;;;Y;;;;;\n29FA;DOUBLE PLUS;Sm;0;ON;;;;;N;;;;;\n29FB;TRIPLE PLUS;Sm;0;ON;;;;;N;;;;;\n29FC;LEFT-POINTING CURVED ANGLE BRACKET;Ps;0;ON;;;;;Y;;;;;\n29FD;RIGHT-POINTING CURVED ANGLE BRACKET;Pe;0;ON;;;;;Y;;;;;\n29FE;TINY;Sm;0;ON;;;;;N;;;;;\n29FF;MINY;Sm;0;ON;;;;;N;;;;;\n2A00;N-ARY CIRCLED DOT OPERATOR;Sm;0;ON;;;;;N;;;;;\n2A01;N-ARY CIRCLED PLUS OPERATOR;Sm;0;ON;;;;;N;;;;;\n2A02;N-ARY CIRCLED TIMES OPERATOR;Sm;0;ON;;;;;N;;;;;\n2A03;N-ARY UNION OPERATOR WITH DOT;Sm;0;ON;;;;;N;;;;;\n2A04;N-ARY UNION OPERATOR WITH PLUS;Sm;0;ON;;;;;N;;;;;\n2A05;N-ARY SQUARE INTERSECTION OPERATOR;Sm;0;ON;;;;;N;;;;;\n2A06;N-ARY SQUARE UNION OPERATOR;Sm;0;ON;;;;;N;;;;;\n2A07;TWO LOGICAL AND OPERATOR;Sm;0;ON;;;;;N;;;;;\n2A08;TWO LOGICAL OR OPERATOR;Sm;0;ON;;;;;N;;;;;\n2A09;N-ARY TIMES OPERATOR;Sm;0;ON;;;;;N;;;;;\n2A0A;MODULO TWO SUM;Sm;0;ON;;;;;Y;;;;;\n2A0B;SUMMATION WITH INTEGRAL;Sm;0;ON;;;;;Y;;;;;\n2A0C;QUADRUPLE INTEGRAL OPERATOR;Sm;0;ON;<compat> 222B 222B 222B 222B;;;;Y;;;;;\n2A0D;FINITE PART INTEGRAL;Sm;0;ON;;;;;Y;;;;;\n2A0E;INTEGRAL WITH DOUBLE STROKE;Sm;0;ON;;;;;Y;;;;;\n2A0F;INTEGRAL AVERAGE WITH SLASH;Sm;0;ON;;;;;Y;;;;;\n2A10;CIRCULATION FUNCTION;Sm;0;ON;;;;;Y;;;;;\n2A11;ANTICLOCKWISE INTEGRATION;Sm;0;ON;;;;;Y;;;;;\n2A12;LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;;\n2A13;LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE;Sm;0;ON;;;;;Y;;;;;\n2A14;LINE INTEGRATION NOT INCLUDING THE POLE;Sm;0;ON;;;;;Y;;;;;\n2A15;INTEGRAL AROUND A POINT OPERATOR;Sm;0;ON;;;;;Y;;;;;\n2A16;QUATERNION INTEGRAL OPERATOR;Sm;0;ON;;;;;Y;;;;;\n2A17;INTEGRAL WITH LEFTWARDS ARROW WITH HOOK;Sm;0;ON;;;;;Y;;;;;\n2A18;INTEGRAL WITH TIMES SIGN;Sm;0;ON;;;;;Y;;;;;\n2A19;INTEGRAL WITH INTERSECTION;Sm;0;ON;;;;;Y;;;;;\n2A1A;INTEGRAL WITH UNION;Sm;0;ON;;;;;Y;;;;;\n2A1B;INTEGRAL WITH OVERBAR;Sm;0;ON;;;;;Y;;;;;\n2A1C;INTEGRAL WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;\n2A1D;JOIN;Sm;0;ON;;;;;N;;;;;\n2A1E;LARGE LEFT TRIANGLE OPERATOR;Sm;0;ON;;;;;Y;;;;;\n2A1F;Z NOTATION SCHEMA COMPOSITION;Sm;0;ON;;;;;Y;;;;;\n2A20;Z NOTATION SCHEMA PIPING;Sm;0;ON;;;;;Y;;;;;\n2A21;Z NOTATION SCHEMA PROJECTION;Sm;0;ON;;;;;Y;;;;;\n2A22;PLUS SIGN WITH SMALL CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;\n2A23;PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE;Sm;0;ON;;;;;N;;;;;\n2A24;PLUS SIGN WITH TILDE ABOVE;Sm;0;ON;;;;;Y;;;;;\n2A25;PLUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;;\n2A26;PLUS SIGN WITH TILDE BELOW;Sm;0;ON;;;;;Y;;;;;\n2A27;PLUS SIGN WITH SUBSCRIPT TWO;Sm;0;ON;;;;;N;;;;;\n2A28;PLUS SIGN WITH BLACK TRIANGLE;Sm;0;ON;;;;;N;;;;;\n2A29;MINUS SIGN WITH COMMA ABOVE;Sm;0;ON;;;;;Y;;;;;\n2A2A;MINUS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;;\n2A2B;MINUS SIGN WITH FALLING DOTS;Sm;0;ON;;;;;Y;;;;;\n2A2C;MINUS SIGN WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;;\n2A2D;PLUS SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;\n2A2E;PLUS SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;\n2A2F;VECTOR OR CROSS PRODUCT;Sm;0;ON;;;;;N;;;;;\n2A30;MULTIPLICATION SIGN WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;\n2A31;MULTIPLICATION SIGN WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;\n2A32;SEMIDIRECT PRODUCT WITH BOTTOM CLOSED;Sm;0;ON;;;;;N;;;;;\n2A33;SMASH PRODUCT;Sm;0;ON;;;;;N;;;;;\n2A34;MULTIPLICATION SIGN IN LEFT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;\n2A35;MULTIPLICATION SIGN IN RIGHT HALF CIRCLE;Sm;0;ON;;;;;Y;;;;;\n2A36;CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;N;;;;;\n2A37;MULTIPLICATION SIGN IN DOUBLE CIRCLE;Sm;0;ON;;;;;N;;;;;\n2A38;CIRCLED DIVISION SIGN;Sm;0;ON;;;;;N;;;;;\n2A39;PLUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;;\n2A3A;MINUS SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;;\n2A3B;MULTIPLICATION SIGN IN TRIANGLE;Sm;0;ON;;;;;N;;;;;\n2A3C;INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;;\n2A3D;RIGHTHAND INTERIOR PRODUCT;Sm;0;ON;;;;;Y;;;;;\n2A3E;Z NOTATION RELATIONAL COMPOSITION;Sm;0;ON;;;;;Y;;;;;\n2A3F;AMALGAMATION OR COPRODUCT;Sm;0;ON;;;;;N;;;;;\n2A40;INTERSECTION WITH DOT;Sm;0;ON;;;;;N;;;;;\n2A41;UNION WITH MINUS SIGN;Sm;0;ON;;;;;N;;;;;\n2A42;UNION WITH OVERBAR;Sm;0;ON;;;;;N;;;;;\n2A43;INTERSECTION WITH OVERBAR;Sm;0;ON;;;;;N;;;;;\n2A44;INTERSECTION WITH LOGICAL AND;Sm;0;ON;;;;;N;;;;;\n2A45;UNION WITH LOGICAL OR;Sm;0;ON;;;;;N;;;;;\n2A46;UNION ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;;\n2A47;INTERSECTION ABOVE UNION;Sm;0;ON;;;;;N;;;;;\n2A48;UNION ABOVE BAR ABOVE INTERSECTION;Sm;0;ON;;;;;N;;;;;\n2A49;INTERSECTION ABOVE BAR ABOVE UNION;Sm;0;ON;;;;;N;;;;;\n2A4A;UNION BESIDE AND JOINED WITH UNION;Sm;0;ON;;;;;N;;;;;\n2A4B;INTERSECTION BESIDE AND JOINED WITH INTERSECTION;Sm;0;ON;;;;;N;;;;;\n2A4C;CLOSED UNION WITH SERIFS;Sm;0;ON;;;;;N;;;;;\n2A4D;CLOSED INTERSECTION WITH SERIFS;Sm;0;ON;;;;;N;;;;;\n2A4E;DOUBLE SQUARE INTERSECTION;Sm;0;ON;;;;;N;;;;;\n2A4F;DOUBLE SQUARE UNION;Sm;0;ON;;;;;N;;;;;\n2A50;CLOSED UNION WITH SERIFS AND SMASH PRODUCT;Sm;0;ON;;;;;N;;;;;\n2A51;LOGICAL AND WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;\n2A52;LOGICAL OR WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;\n2A53;DOUBLE LOGICAL AND;Sm;0;ON;;;;;N;;;;;\n2A54;DOUBLE LOGICAL OR;Sm;0;ON;;;;;N;;;;;\n2A55;TWO INTERSECTING LOGICAL AND;Sm;0;ON;;;;;N;;;;;\n2A56;TWO INTERSECTING LOGICAL OR;Sm;0;ON;;;;;N;;;;;\n2A57;SLOPING LARGE OR;Sm;0;ON;;;;;Y;;;;;\n2A58;SLOPING LARGE AND;Sm;0;ON;;;;;Y;;;;;\n2A59;LOGICAL OR OVERLAPPING LOGICAL AND;Sm;0;ON;;;;;N;;;;;\n2A5A;LOGICAL AND WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;;\n2A5B;LOGICAL OR WITH MIDDLE STEM;Sm;0;ON;;;;;N;;;;;\n2A5C;LOGICAL AND WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;;\n2A5D;LOGICAL OR WITH HORIZONTAL DASH;Sm;0;ON;;;;;N;;;;;\n2A5E;LOGICAL AND WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;;\n2A5F;LOGICAL AND WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;\n2A60;LOGICAL AND WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;;\n2A61;SMALL VEE WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;\n2A62;LOGICAL OR WITH DOUBLE OVERBAR;Sm;0;ON;;;;;N;;;;;\n2A63;LOGICAL OR WITH DOUBLE UNDERBAR;Sm;0;ON;;;;;N;;;;;\n2A64;Z NOTATION DOMAIN ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;;\n2A65;Z NOTATION RANGE ANTIRESTRICTION;Sm;0;ON;;;;;Y;;;;;\n2A66;EQUALS SIGN WITH DOT BELOW;Sm;0;ON;;;;;N;;;;;\n2A67;IDENTICAL WITH DOT ABOVE;Sm;0;ON;;;;;N;;;;;\n2A68;TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2A69;TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2A6A;TILDE OPERATOR WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;\n2A6B;TILDE OPERATOR WITH RISING DOTS;Sm;0;ON;;;;;Y;;;;;\n2A6C;SIMILAR MINUS SIMILAR;Sm;0;ON;;;;;Y;;;;;\n2A6D;CONGRUENT WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;\n2A6E;EQUALS WITH ASTERISK;Sm;0;ON;;;;;N;;;;;\n2A6F;ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT;Sm;0;ON;;;;;Y;;;;;\n2A70;APPROXIMATELY EQUAL OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2A71;EQUALS SIGN ABOVE PLUS SIGN;Sm;0;ON;;;;;N;;;;;\n2A72;PLUS SIGN ABOVE EQUALS SIGN;Sm;0;ON;;;;;N;;;;;\n2A73;EQUALS SIGN ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;\n2A74;DOUBLE COLON EQUAL;Sm;0;ON;<compat> 003A 003A 003D;;;;Y;;;;;\n2A75;TWO CONSECUTIVE EQUALS SIGNS;Sm;0;ON;<compat> 003D 003D;;;;N;;;;;\n2A76;THREE CONSECUTIVE EQUALS SIGNS;Sm;0;ON;<compat> 003D 003D 003D;;;;N;;;;;\n2A77;EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW;Sm;0;ON;;;;;N;;;;;\n2A78;EQUIVALENT WITH FOUR DOTS ABOVE;Sm;0;ON;;;;;N;;;;;\n2A79;LESS-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;;\n2A7A;GREATER-THAN WITH CIRCLE INSIDE;Sm;0;ON;;;;;Y;;;;;\n2A7B;LESS-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;;\n2A7C;GREATER-THAN WITH QUESTION MARK ABOVE;Sm;0;ON;;;;;Y;;;;;\n2A7D;LESS-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2A7E;GREATER-THAN OR SLANTED EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2A7F;LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;\n2A80;GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;\n2A81;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;\n2A82;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;\n2A83;LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT;Sm;0;ON;;;;;Y;;;;;\n2A84;GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT;Sm;0;ON;;;;;Y;;;;;\n2A85;LESS-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;;\n2A86;GREATER-THAN OR APPROXIMATE;Sm;0;ON;;;;;Y;;;;;\n2A87;LESS-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2A88;GREATER-THAN AND SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2A89;LESS-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;;\n2A8A;GREATER-THAN AND NOT APPROXIMATE;Sm;0;ON;;;;;Y;;;;;\n2A8B;LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;;\n2A8C;GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;;\n2A8D;LESS-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;;\n2A8E;GREATER-THAN ABOVE SIMILAR OR EQUAL;Sm;0;ON;;;;;Y;;;;;\n2A8F;LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN;Sm;0;ON;;;;;Y;;;;;\n2A90;GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN;Sm;0;ON;;;;;Y;;;;;\n2A91;LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;;\n2A92;GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL;Sm;0;ON;;;;;Y;;;;;\n2A93;LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;\n2A94;GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;\n2A95;SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;\n2A96;SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;\n2A97;SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;\n2A98;SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE;Sm;0;ON;;;;;Y;;;;;\n2A99;DOUBLE-LINE EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;\n2A9A;DOUBLE-LINE EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;\n2A9B;DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;\n2A9C;DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;\n2A9D;SIMILAR OR LESS-THAN;Sm;0;ON;;;;;Y;;;;;\n2A9E;SIMILAR OR GREATER-THAN;Sm;0;ON;;;;;Y;;;;;\n2A9F;SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;\n2AA0;SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;\n2AA1;DOUBLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;;\n2AA2;DOUBLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;;\n2AA3;DOUBLE NESTED LESS-THAN WITH UNDERBAR;Sm;0;ON;;;;;Y;;;;;\n2AA4;GREATER-THAN OVERLAPPING LESS-THAN;Sm;0;ON;;;;;N;;;;;\n2AA5;GREATER-THAN BESIDE LESS-THAN;Sm;0;ON;;;;;N;;;;;\n2AA6;LESS-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;;\n2AA7;GREATER-THAN CLOSED BY CURVE;Sm;0;ON;;;;;Y;;;;;\n2AA8;LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;\n2AA9;GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL;Sm;0;ON;;;;;Y;;;;;\n2AAA;SMALLER THAN;Sm;0;ON;;;;;Y;;;;;\n2AAB;LARGER THAN;Sm;0;ON;;;;;Y;;;;;\n2AAC;SMALLER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2AAD;LARGER THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2AAE;EQUALS SIGN WITH BUMPY ABOVE;Sm;0;ON;;;;;N;;;;;\n2AAF;PRECEDES ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;\n2AB0;SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;\n2AB1;PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2AB2;SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2AB3;PRECEDES ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;\n2AB4;SUCCEEDS ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;\n2AB5;PRECEDES ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2AB6;SUCCEEDS ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2AB7;PRECEDES ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2AB8;SUCCEEDS ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2AB9;PRECEDES ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2ABA;SUCCEEDS ABOVE NOT ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2ABB;DOUBLE PRECEDES;Sm;0;ON;;;;;Y;;;;;\n2ABC;DOUBLE SUCCEEDS;Sm;0;ON;;;;;Y;;;;;\n2ABD;SUBSET WITH DOT;Sm;0;ON;;;;;Y;;;;;\n2ABE;SUPERSET WITH DOT;Sm;0;ON;;;;;Y;;;;;\n2ABF;SUBSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;;\n2AC0;SUPERSET WITH PLUS SIGN BELOW;Sm;0;ON;;;;;Y;;;;;\n2AC1;SUBSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;;\n2AC2;SUPERSET WITH MULTIPLICATION SIGN BELOW;Sm;0;ON;;;;;Y;;;;;\n2AC3;SUBSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;\n2AC4;SUPERSET OF OR EQUAL TO WITH DOT ABOVE;Sm;0;ON;;;;;Y;;;;;\n2AC5;SUBSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;\n2AC6;SUPERSET OF ABOVE EQUALS SIGN;Sm;0;ON;;;;;Y;;;;;\n2AC7;SUBSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;\n2AC8;SUPERSET OF ABOVE TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;\n2AC9;SUBSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2ACA;SUPERSET OF ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2ACB;SUBSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2ACC;SUPERSET OF ABOVE NOT EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2ACD;SQUARE LEFT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;;\n2ACE;SQUARE RIGHT OPEN BOX OPERATOR;Sm;0;ON;;;;;Y;;;;;\n2ACF;CLOSED SUBSET;Sm;0;ON;;;;;Y;;;;;\n2AD0;CLOSED SUPERSET;Sm;0;ON;;;;;Y;;;;;\n2AD1;CLOSED SUBSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2AD2;CLOSED SUPERSET OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2AD3;SUBSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;;\n2AD4;SUPERSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;;\n2AD5;SUBSET ABOVE SUBSET;Sm;0;ON;;;;;Y;;;;;\n2AD6;SUPERSET ABOVE SUPERSET;Sm;0;ON;;;;;Y;;;;;\n2AD7;SUPERSET BESIDE SUBSET;Sm;0;ON;;;;;N;;;;;\n2AD8;SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET;Sm;0;ON;;;;;N;;;;;\n2AD9;ELEMENT OF OPENING DOWNWARDS;Sm;0;ON;;;;;N;;;;;\n2ADA;PITCHFORK WITH TEE TOP;Sm;0;ON;;;;;N;;;;;\n2ADB;TRANSVERSAL INTERSECTION;Sm;0;ON;;;;;N;;;;;\n2ADC;FORKING;Sm;0;ON;2ADD 0338;;;;Y;;;;;\n2ADD;NONFORKING;Sm;0;ON;;;;;N;;;;;\n2ADE;SHORT LEFT TACK;Sm;0;ON;;;;;Y;;;;;\n2ADF;SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;;\n2AE0;SHORT UP TACK;Sm;0;ON;;;;;N;;;;;\n2AE1;PERPENDICULAR WITH S;Sm;0;ON;;;;;N;;;;;\n2AE2;VERTICAL BAR TRIPLE RIGHT TURNSTILE;Sm;0;ON;;;;;Y;;;;;\n2AE3;DOUBLE VERTICAL BAR LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;;\n2AE4;VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;;\n2AE5;DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE;Sm;0;ON;;;;;Y;;;;;\n2AE6;LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL;Sm;0;ON;;;;;Y;;;;;\n2AE7;SHORT DOWN TACK WITH OVERBAR;Sm;0;ON;;;;;N;;;;;\n2AE8;SHORT UP TACK WITH UNDERBAR;Sm;0;ON;;;;;N;;;;;\n2AE9;SHORT UP TACK ABOVE SHORT DOWN TACK;Sm;0;ON;;;;;N;;;;;\n2AEA;DOUBLE DOWN TACK;Sm;0;ON;;;;;N;;;;;\n2AEB;DOUBLE UP TACK;Sm;0;ON;;;;;N;;;;;\n2AEC;DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;;\n2AED;REVERSED DOUBLE STROKE NOT SIGN;Sm;0;ON;;;;;Y;;;;;\n2AEE;DOES NOT DIVIDE WITH REVERSED NEGATION SLASH;Sm;0;ON;;;;;Y;;;;;\n2AEF;VERTICAL LINE WITH CIRCLE ABOVE;Sm;0;ON;;;;;N;;;;;\n2AF0;VERTICAL LINE WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;;\n2AF1;DOWN TACK WITH CIRCLE BELOW;Sm;0;ON;;;;;N;;;;;\n2AF2;PARALLEL WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;\n2AF3;PARALLEL WITH TILDE OPERATOR;Sm;0;ON;;;;;Y;;;;;\n2AF4;TRIPLE VERTICAL BAR BINARY RELATION;Sm;0;ON;;;;;N;;;;;\n2AF5;TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE;Sm;0;ON;;;;;N;;;;;\n2AF6;TRIPLE COLON OPERATOR;Sm;0;ON;;;;;N;;;;;\n2AF7;TRIPLE NESTED LESS-THAN;Sm;0;ON;;;;;Y;;;;;\n2AF8;TRIPLE NESTED GREATER-THAN;Sm;0;ON;;;;;Y;;;;;\n2AF9;DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2AFA;DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO;Sm;0;ON;;;;;Y;;;;;\n2AFB;TRIPLE SOLIDUS BINARY RELATION;Sm;0;ON;;;;;Y;;;;;\n2AFC;LARGE TRIPLE VERTICAL BAR OPERATOR;Sm;0;ON;;;;;N;;;;;\n2AFD;DOUBLE SOLIDUS OPERATOR;Sm;0;ON;;;;;Y;;;;;\n2AFE;WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;;\n2AFF;N-ARY WHITE VERTICAL BAR;Sm;0;ON;;;;;N;;;;;\n2B00;NORTH EAST WHITE ARROW;So;0;ON;;;;;N;;;;;\n2B01;NORTH WEST WHITE ARROW;So;0;ON;;;;;N;;;;;\n2B02;SOUTH EAST WHITE ARROW;So;0;ON;;;;;N;;;;;\n2B03;SOUTH WEST WHITE ARROW;So;0;ON;;;;;N;;;;;\n2B04;LEFT RIGHT WHITE ARROW;So;0;ON;;;;;N;;;;;\n2B05;LEFTWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;\n2B06;UPWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;\n2B07;DOWNWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;\n2B08;NORTH EAST BLACK ARROW;So;0;ON;;;;;N;;;;;\n2B09;NORTH WEST BLACK ARROW;So;0;ON;;;;;N;;;;;\n2B0A;SOUTH EAST BLACK ARROW;So;0;ON;;;;;N;;;;;\n2B0B;SOUTH WEST BLACK ARROW;So;0;ON;;;;;N;;;;;\n2B0C;LEFT RIGHT BLACK ARROW;So;0;ON;;;;;N;;;;;\n2B0D;UP DOWN BLACK ARROW;So;0;ON;;;;;N;;;;;\n2B0E;RIGHTWARDS ARROW WITH TIP DOWNWARDS;So;0;ON;;;;;N;;;;;\n2B0F;RIGHTWARDS ARROW WITH TIP UPWARDS;So;0;ON;;;;;N;;;;;\n2B10;LEFTWARDS ARROW WITH TIP DOWNWARDS;So;0;ON;;;;;N;;;;;\n2B11;LEFTWARDS ARROW WITH TIP UPWARDS;So;0;ON;;;;;N;;;;;\n2B12;SQUARE WITH TOP HALF BLACK;So;0;ON;;;;;N;;;;;\n2B13;SQUARE WITH BOTTOM HALF BLACK;So;0;ON;;;;;N;;;;;\n2B14;SQUARE WITH UPPER RIGHT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;\n2B15;SQUARE WITH LOWER LEFT DIAGONAL HALF BLACK;So;0;ON;;;;;N;;;;;\n2B16;DIAMOND WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;;\n2B17;DIAMOND WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;;\n2B18;DIAMOND WITH TOP HALF BLACK;So;0;ON;;;;;N;;;;;\n2B19;DIAMOND WITH BOTTOM HALF BLACK;So;0;ON;;;;;N;;;;;\n2B1A;DOTTED SQUARE;So;0;ON;;;;;N;;;;;\n2B1B;BLACK LARGE SQUARE;So;0;ON;;;;;N;;;;;\n2B1C;WHITE LARGE SQUARE;So;0;ON;;;;;N;;;;;\n2B1D;BLACK VERY SMALL SQUARE;So;0;ON;;;;;N;;;;;\n2B1E;WHITE VERY SMALL SQUARE;So;0;ON;;;;;N;;;;;\n2B1F;BLACK PENTAGON;So;0;ON;;;;;N;;;;;\n2B20;WHITE PENTAGON;So;0;ON;;;;;N;;;;;\n2B21;WHITE HEXAGON;So;0;ON;;;;;N;;;;;\n2B22;BLACK HEXAGON;So;0;ON;;;;;N;;;;;\n2B23;HORIZONTAL BLACK HEXAGON;So;0;ON;;;;;N;;;;;\n2B24;BLACK LARGE CIRCLE;So;0;ON;;;;;N;;;;;\n2B25;BLACK MEDIUM DIAMOND;So;0;ON;;;;;N;;;;;\n2B26;WHITE MEDIUM DIAMOND;So;0;ON;;;;;N;;;;;\n2B27;BLACK MEDIUM LOZENGE;So;0;ON;;;;;N;;;;;\n2B28;WHITE MEDIUM LOZENGE;So;0;ON;;;;;N;;;;;\n2B29;BLACK SMALL DIAMOND;So;0;ON;;;;;N;;;;;\n2B2A;BLACK SMALL LOZENGE;So;0;ON;;;;;N;;;;;\n2B2B;WHITE SMALL LOZENGE;So;0;ON;;;;;N;;;;;\n2B2C;BLACK HORIZONTAL ELLIPSE;So;0;ON;;;;;N;;;;;\n2B2D;WHITE HORIZONTAL ELLIPSE;So;0;ON;;;;;N;;;;;\n2B2E;BLACK VERTICAL ELLIPSE;So;0;ON;;;;;N;;;;;\n2B2F;WHITE VERTICAL ELLIPSE;So;0;ON;;;;;N;;;;;\n2B30;LEFT ARROW WITH SMALL CIRCLE;Sm;0;ON;;;;;N;;;;;\n2B31;THREE LEFTWARDS ARROWS;Sm;0;ON;;;;;N;;;;;\n2B32;LEFT ARROW WITH CIRCLED PLUS;Sm;0;ON;;;;;N;;;;;\n2B33;LONG LEFTWARDS SQUIGGLE ARROW;Sm;0;ON;;;;;N;;;;;\n2B34;LEFTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2B35;LEFTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2B36;LEFTWARDS TWO-HEADED ARROW FROM BAR;Sm;0;ON;;;;;N;;;;;\n2B37;LEFTWARDS TWO-HEADED TRIPLE DASH ARROW;Sm;0;ON;;;;;N;;;;;\n2B38;LEFTWARDS ARROW WITH DOTTED STEM;Sm;0;ON;;;;;N;;;;;\n2B39;LEFTWARDS ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2B3A;LEFTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2B3B;LEFTWARDS TWO-HEADED ARROW WITH TAIL;Sm;0;ON;;;;;N;;;;;\n2B3C;LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2B3D;LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE;Sm;0;ON;;;;;N;;;;;\n2B3E;LEFTWARDS ARROW THROUGH X;Sm;0;ON;;;;;N;;;;;\n2B3F;WAVE ARROW POINTING DIRECTLY LEFT;Sm;0;ON;;;;;N;;;;;\n2B40;EQUALS SIGN ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n2B41;REVERSE TILDE OPERATOR ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n2B42;LEFTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;\n2B43;RIGHTWARDS ARROW THROUGH GREATER-THAN;Sm;0;ON;;;;;N;;;;;\n2B44;RIGHTWARDS ARROW THROUGH SUPERSET;Sm;0;ON;;;;;N;;;;;\n2B45;LEFTWARDS QUADRUPLE ARROW;So;0;ON;;;;;N;;;;;\n2B46;RIGHTWARDS QUADRUPLE ARROW;So;0;ON;;;;;N;;;;;\n2B47;REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n2B48;RIGHTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;\n2B49;TILDE OPERATOR ABOVE LEFTWARDS ARROW;Sm;0;ON;;;;;N;;;;;\n2B4A;LEFTWARDS ARROW ABOVE ALMOST EQUAL TO;Sm;0;ON;;;;;N;;;;;\n2B4B;LEFTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;\n2B4C;RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR;Sm;0;ON;;;;;N;;;;;\n2B4D;DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW;So;0;ON;;;;;N;;;;;\n2B4E;SHORT SLANTED NORTH ARROW;So;0;ON;;;;;N;;;;;\n2B4F;SHORT BACKSLANTED SOUTH ARROW;So;0;ON;;;;;N;;;;;\n2B50;WHITE MEDIUM STAR;So;0;ON;;;;;N;;;;;\n2B51;BLACK SMALL STAR;So;0;ON;;;;;N;;;;;\n2B52;WHITE SMALL STAR;So;0;ON;;;;;N;;;;;\n2B53;BLACK RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;;\n2B54;WHITE RIGHT-POINTING PENTAGON;So;0;ON;;;;;N;;;;;\n2B55;HEAVY LARGE CIRCLE;So;0;ON;;;;;N;;;;;\n2B56;HEAVY OVAL WITH OVAL INSIDE;So;0;ON;;;;;N;;;;;\n2B57;HEAVY CIRCLE WITH CIRCLE INSIDE;So;0;ON;;;;;N;;;;;\n2B58;HEAVY CIRCLE;So;0;ON;;;;;N;;;;;\n2B59;HEAVY CIRCLED SALTIRE;So;0;ON;;;;;N;;;;;\n2B5A;SLANTED NORTH ARROW WITH HOOKED HEAD;So;0;ON;;;;;N;;;;;\n2B5B;BACKSLANTED SOUTH ARROW WITH HOOKED TAIL;So;0;ON;;;;;N;;;;;\n2B5C;SLANTED NORTH ARROW WITH HORIZONTAL TAIL;So;0;ON;;;;;N;;;;;\n2B5D;BACKSLANTED SOUTH ARROW WITH HORIZONTAL TAIL;So;0;ON;;;;;N;;;;;\n2B5E;BENT ARROW POINTING DOWNWARDS THEN NORTH EAST;So;0;ON;;;;;N;;;;;\n2B5F;SHORT BENT ARROW POINTING DOWNWARDS THEN NORTH EAST;So;0;ON;;;;;N;;;;;\n2B60;LEFTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;\n2B61;UPWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;\n2B62;RIGHTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;\n2B63;DOWNWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;\n2B64;LEFT RIGHT TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;\n2B65;UP DOWN TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;\n2B66;NORTH WEST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;\n2B67;NORTH EAST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;\n2B68;SOUTH EAST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;\n2B69;SOUTH WEST TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;\n2B6A;LEFTWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;;\n2B6B;UPWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;;\n2B6C;RIGHTWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;;\n2B6D;DOWNWARDS TRIANGLE-HEADED DASHED ARROW;So;0;ON;;;;;N;;;;;\n2B6E;CLOCKWISE TRIANGLE-HEADED OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;\n2B6F;ANTICLOCKWISE TRIANGLE-HEADED OPEN CIRCLE ARROW;So;0;ON;;;;;N;;;;;\n2B70;LEFTWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;\n2B71;UPWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;\n2B72;RIGHTWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;\n2B73;DOWNWARDS TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;\n2B76;NORTH WEST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;\n2B77;NORTH EAST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;\n2B78;SOUTH EAST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;\n2B79;SOUTH WEST TRIANGLE-HEADED ARROW TO BAR;So;0;ON;;;;;N;;;;;\n2B7A;LEFTWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;;\n2B7B;UPWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;;\n2B7C;RIGHTWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;;\n2B7D;DOWNWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE;So;0;ON;;;;;N;;;;;\n2B7E;HORIZONTAL TAB KEY;So;0;ON;;;;;N;;;;;\n2B7F;VERTICAL TAB KEY;So;0;ON;;;;;N;;;;;\n2B80;LEFTWARDS TRIANGLE-HEADED ARROW OVER RIGHTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;\n2B81;UPWARDS TRIANGLE-HEADED ARROW LEFTWARDS OF DOWNWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;\n2B82;RIGHTWARDS TRIANGLE-HEADED ARROW OVER LEFTWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;\n2B83;DOWNWARDS TRIANGLE-HEADED ARROW LEFTWARDS OF UPWARDS TRIANGLE-HEADED ARROW;So;0;ON;;;;;N;;;;;\n2B84;LEFTWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;;\n2B85;UPWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;;\n2B86;RIGHTWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;;\n2B87;DOWNWARDS TRIANGLE-HEADED PAIRED ARROWS;So;0;ON;;;;;N;;;;;\n2B88;LEFTWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;;\n2B89;UPWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;;\n2B8A;RIGHTWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;;\n2B8B;DOWNWARDS BLACK CIRCLED WHITE ARROW;So;0;ON;;;;;N;;;;;\n2B8C;ANTICLOCKWISE TRIANGLE-HEADED RIGHT U-SHAPED ARROW;So;0;ON;;;;;N;;;;;\n2B8D;ANTICLOCKWISE TRIANGLE-HEADED BOTTOM U-SHAPED ARROW;So;0;ON;;;;;N;;;;;\n2B8E;ANTICLOCKWISE TRIANGLE-HEADED LEFT U-SHAPED ARROW;So;0;ON;;;;;N;;;;;\n2B8F;ANTICLOCKWISE TRIANGLE-HEADED TOP U-SHAPED ARROW;So;0;ON;;;;;N;;;;;\n2B90;RETURN LEFT;So;0;ON;;;;;N;;;;;\n2B91;RETURN RIGHT;So;0;ON;;;;;N;;;;;\n2B92;NEWLINE LEFT;So;0;ON;;;;;N;;;;;\n2B93;NEWLINE RIGHT;So;0;ON;;;;;N;;;;;\n2B94;FOUR CORNER ARROWS CIRCLING ANTICLOCKWISE;So;0;ON;;;;;N;;;;;\n2B95;RIGHTWARDS BLACK ARROW;So;0;ON;;;;;N;;;;;\n2B98;THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n2B99;THREE-D RIGHT-LIGHTED UPWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n2B9A;THREE-D TOP-LIGHTED RIGHTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n2B9B;THREE-D LEFT-LIGHTED DOWNWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n2B9C;BLACK LEFTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n2B9D;BLACK UPWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n2B9E;BLACK RIGHTWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n2B9F;BLACK DOWNWARDS EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n2BA0;DOWNWARDS TRIANGLE-HEADED ARROW WITH LONG TIP LEFTWARDS;So;0;ON;;;;;N;;;;;\n2BA1;DOWNWARDS TRIANGLE-HEADED ARROW WITH LONG TIP RIGHTWARDS;So;0;ON;;;;;N;;;;;\n2BA2;UPWARDS TRIANGLE-HEADED ARROW WITH LONG TIP LEFTWARDS;So;0;ON;;;;;N;;;;;\n2BA3;UPWARDS TRIANGLE-HEADED ARROW WITH LONG TIP RIGHTWARDS;So;0;ON;;;;;N;;;;;\n2BA4;LEFTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP UPWARDS;So;0;ON;;;;;N;;;;;\n2BA5;RIGHTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP UPWARDS;So;0;ON;;;;;N;;;;;\n2BA6;LEFTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP DOWNWARDS;So;0;ON;;;;;N;;;;;\n2BA7;RIGHTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP DOWNWARDS;So;0;ON;;;;;N;;;;;\n2BA8;BLACK CURVED DOWNWARDS AND LEFTWARDS ARROW;So;0;ON;;;;;N;;;;;\n2BA9;BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;;;;;\n2BAA;BLACK CURVED UPWARDS AND LEFTWARDS ARROW;So;0;ON;;;;;N;;;;;\n2BAB;BLACK CURVED UPWARDS AND RIGHTWARDS ARROW;So;0;ON;;;;;N;;;;;\n2BAC;BLACK CURVED LEFTWARDS AND UPWARDS ARROW;So;0;ON;;;;;N;;;;;\n2BAD;BLACK CURVED RIGHTWARDS AND UPWARDS ARROW;So;0;ON;;;;;N;;;;;\n2BAE;BLACK CURVED LEFTWARDS AND DOWNWARDS ARROW;So;0;ON;;;;;N;;;;;\n2BAF;BLACK CURVED RIGHTWARDS AND DOWNWARDS ARROW;So;0;ON;;;;;N;;;;;\n2BB0;RIBBON ARROW DOWN LEFT;So;0;ON;;;;;N;;;;;\n2BB1;RIBBON ARROW DOWN RIGHT;So;0;ON;;;;;N;;;;;\n2BB2;RIBBON ARROW UP LEFT;So;0;ON;;;;;N;;;;;\n2BB3;RIBBON ARROW UP RIGHT;So;0;ON;;;;;N;;;;;\n2BB4;RIBBON ARROW LEFT UP;So;0;ON;;;;;N;;;;;\n2BB5;RIBBON ARROW RIGHT UP;So;0;ON;;;;;N;;;;;\n2BB6;RIBBON ARROW LEFT DOWN;So;0;ON;;;;;N;;;;;\n2BB7;RIBBON ARROW RIGHT DOWN;So;0;ON;;;;;N;;;;;\n2BB8;UPWARDS WHITE ARROW FROM BAR WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;;\n2BB9;UP ARROWHEAD IN A RECTANGLE BOX;So;0;ON;;;;;N;;;;;\n2BBA;OVERLAPPING WHITE SQUARES;So;0;ON;;;;;N;;;;;\n2BBB;OVERLAPPING WHITE AND BLACK SQUARES;So;0;ON;;;;;N;;;;;\n2BBC;OVERLAPPING BLACK SQUARES;So;0;ON;;;;;N;;;;;\n2BBD;BALLOT BOX WITH LIGHT X;So;0;ON;;;;;N;;;;;\n2BBE;CIRCLED X;So;0;ON;;;;;N;;;;;\n2BBF;CIRCLED BOLD X;So;0;ON;;;;;N;;;;;\n2BC0;BLACK SQUARE CENTRED;So;0;ON;;;;;N;;;;;\n2BC1;BLACK DIAMOND CENTRED;So;0;ON;;;;;N;;;;;\n2BC2;TURNED BLACK PENTAGON;So;0;ON;;;;;N;;;;;\n2BC3;HORIZONTAL BLACK OCTAGON;So;0;ON;;;;;N;;;;;\n2BC4;BLACK OCTAGON;So;0;ON;;;;;N;;;;;\n2BC5;BLACK MEDIUM UP-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;;\n2BC6;BLACK MEDIUM DOWN-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;;\n2BC7;BLACK MEDIUM LEFT-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;;\n2BC8;BLACK MEDIUM RIGHT-POINTING TRIANGLE CENTRED;So;0;ON;;;;;N;;;;;\n2BC9;NEPTUNE FORM TWO;So;0;ON;;;;;N;;;;;\n2BCA;TOP HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;\n2BCB;BOTTOM HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;;\n2BCC;LIGHT FOUR POINTED BLACK CUSP;So;0;ON;;;;;N;;;;;\n2BCD;ROTATED LIGHT FOUR POINTED BLACK CUSP;So;0;ON;;;;;N;;;;;\n2BCE;WHITE FOUR POINTED CUSP;So;0;ON;;;;;N;;;;;\n2BCF;ROTATED WHITE FOUR POINTED CUSP;So;0;ON;;;;;N;;;;;\n2BD0;SQUARE POSITION INDICATOR;So;0;ON;;;;;N;;;;;\n2BD1;UNCERTAINTY SIGN;So;0;ON;;;;;N;;;;;\n2BD2;GROUP MARK;So;0;ON;;;;;N;;;;;\n2BD3;PLUTO FORM TWO;So;0;ON;;;;;N;;;;;\n2BD4;PLUTO FORM THREE;So;0;ON;;;;;N;;;;;\n2BD5;PLUTO FORM FOUR;So;0;ON;;;;;N;;;;;\n2BD6;PLUTO FORM FIVE;So;0;ON;;;;;N;;;;;\n2BD7;TRANSPLUTO;So;0;ON;;;;;N;;;;;\n2BD8;PROSERPINA;So;0;ON;;;;;N;;;;;\n2BD9;ASTRAEA;So;0;ON;;;;;N;;;;;\n2BDA;HYGIEA;So;0;ON;;;;;N;;;;;\n2BDB;PHOLUS;So;0;ON;;;;;N;;;;;\n2BDC;NESSUS;So;0;ON;;;;;N;;;;;\n2BDD;WHITE MOON SELENA;So;0;ON;;;;;N;;;;;\n2BDE;BLACK DIAMOND ON CROSS;So;0;ON;;;;;N;;;;;\n2BDF;TRUE LIGHT MOON ARTA;So;0;ON;;;;;N;;;;;\n2BE0;CUPIDO;So;0;ON;;;;;N;;;;;\n2BE1;HADES;So;0;ON;;;;;N;;;;;\n2BE2;ZEUS;So;0;ON;;;;;N;;;;;\n2BE3;KRONOS;So;0;ON;;;;;N;;;;;\n2BE4;APOLLON;So;0;ON;;;;;N;;;;;\n2BE5;ADMETOS;So;0;ON;;;;;N;;;;;\n2BE6;VULCANUS;So;0;ON;;;;;N;;;;;\n2BE7;POSEIDON;So;0;ON;;;;;N;;;;;\n2BE8;LEFT HALF BLACK STAR;So;0;ON;;;;;N;;;;;\n2BE9;RIGHT HALF BLACK STAR;So;0;ON;;;;;N;;;;;\n2BEA;STAR WITH LEFT HALF BLACK;So;0;ON;;;;;N;;;;;\n2BEB;STAR WITH RIGHT HALF BLACK;So;0;ON;;;;;N;;;;;\n2BEC;LEFTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;;\n2BED;UPWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;;\n2BEE;RIGHTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;;\n2BEF;DOWNWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS;So;0;ON;;;;;N;;;;;\n2BF0;ERIS FORM ONE;So;0;ON;;;;;N;;;;;\n2BF1;ERIS FORM TWO;So;0;ON;;;;;N;;;;;\n2BF2;SEDNA;So;0;ON;;;;;N;;;;;\n2BF3;RUSSIAN ASTROLOGICAL SYMBOL VIGINTILE;So;0;ON;;;;;N;;;;;\n2BF4;RUSSIAN ASTROLOGICAL SYMBOL NOVILE;So;0;ON;;;;;N;;;;;\n2BF5;RUSSIAN ASTROLOGICAL SYMBOL QUINTILE;So;0;ON;;;;;N;;;;;\n2BF6;RUSSIAN ASTROLOGICAL SYMBOL BINOVILE;So;0;ON;;;;;N;;;;;\n2BF7;RUSSIAN ASTROLOGICAL SYMBOL SENTAGON;So;0;ON;;;;;N;;;;;\n2BF8;RUSSIAN ASTROLOGICAL SYMBOL TREDECILE;So;0;ON;;;;;N;;;;;\n2BF9;EQUALS SIGN WITH INFINITY BELOW;So;0;ON;;;;;N;;;;;\n2BFA;UNITED SYMBOL;So;0;ON;;;;;N;;;;;\n2BFB;SEPARATED SYMBOL;So;0;ON;;;;;N;;;;;\n2BFC;DOUBLED SYMBOL;So;0;ON;;;;;N;;;;;\n2BFD;PASSED SYMBOL;So;0;ON;;;;;N;;;;;\n2BFE;REVERSED RIGHT ANGLE;So;0;ON;;;;;Y;;;;;\n2BFF;HELLSCHREIBER PAUSE SYMBOL;So;0;ON;;;;;N;;;;;\n2C00;GLAGOLITIC CAPITAL LETTER AZU;Lu;0;L;;;;;N;;;;2C30;\n2C01;GLAGOLITIC CAPITAL LETTER BUKY;Lu;0;L;;;;;N;;;;2C31;\n2C02;GLAGOLITIC CAPITAL LETTER VEDE;Lu;0;L;;;;;N;;;;2C32;\n2C03;GLAGOLITIC CAPITAL LETTER GLAGOLI;Lu;0;L;;;;;N;;;;2C33;\n2C04;GLAGOLITIC CAPITAL LETTER DOBRO;Lu;0;L;;;;;N;;;;2C34;\n2C05;GLAGOLITIC CAPITAL LETTER YESTU;Lu;0;L;;;;;N;;;;2C35;\n2C06;GLAGOLITIC CAPITAL LETTER ZHIVETE;Lu;0;L;;;;;N;;;;2C36;\n2C07;GLAGOLITIC CAPITAL LETTER DZELO;Lu;0;L;;;;;N;;;;2C37;\n2C08;GLAGOLITIC CAPITAL LETTER ZEMLJA;Lu;0;L;;;;;N;;;;2C38;\n2C09;GLAGOLITIC CAPITAL LETTER IZHE;Lu;0;L;;;;;N;;;;2C39;\n2C0A;GLAGOLITIC CAPITAL LETTER INITIAL IZHE;Lu;0;L;;;;;N;;;;2C3A;\n2C0B;GLAGOLITIC CAPITAL LETTER I;Lu;0;L;;;;;N;;;;2C3B;\n2C0C;GLAGOLITIC CAPITAL LETTER DJERVI;Lu;0;L;;;;;N;;;;2C3C;\n2C0D;GLAGOLITIC CAPITAL LETTER KAKO;Lu;0;L;;;;;N;;;;2C3D;\n2C0E;GLAGOLITIC CAPITAL LETTER LJUDIJE;Lu;0;L;;;;;N;;;;2C3E;\n2C0F;GLAGOLITIC CAPITAL LETTER MYSLITE;Lu;0;L;;;;;N;;;;2C3F;\n2C10;GLAGOLITIC CAPITAL LETTER NASHI;Lu;0;L;;;;;N;;;;2C40;\n2C11;GLAGOLITIC CAPITAL LETTER ONU;Lu;0;L;;;;;N;;;;2C41;\n2C12;GLAGOLITIC CAPITAL LETTER POKOJI;Lu;0;L;;;;;N;;;;2C42;\n2C13;GLAGOLITIC CAPITAL LETTER RITSI;Lu;0;L;;;;;N;;;;2C43;\n2C14;GLAGOLITIC CAPITAL LETTER SLOVO;Lu;0;L;;;;;N;;;;2C44;\n2C15;GLAGOLITIC CAPITAL LETTER TVRIDO;Lu;0;L;;;;;N;;;;2C45;\n2C16;GLAGOLITIC CAPITAL LETTER UKU;Lu;0;L;;;;;N;;;;2C46;\n2C17;GLAGOLITIC CAPITAL LETTER FRITU;Lu;0;L;;;;;N;;;;2C47;\n2C18;GLAGOLITIC CAPITAL LETTER HERU;Lu;0;L;;;;;N;;;;2C48;\n2C19;GLAGOLITIC CAPITAL LETTER OTU;Lu;0;L;;;;;N;;;;2C49;\n2C1A;GLAGOLITIC CAPITAL LETTER PE;Lu;0;L;;;;;N;;;;2C4A;\n2C1B;GLAGOLITIC CAPITAL LETTER SHTA;Lu;0;L;;;;;N;;;;2C4B;\n2C1C;GLAGOLITIC CAPITAL LETTER TSI;Lu;0;L;;;;;N;;;;2C4C;\n2C1D;GLAGOLITIC CAPITAL LETTER CHRIVI;Lu;0;L;;;;;N;;;;2C4D;\n2C1E;GLAGOLITIC CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;2C4E;\n2C1F;GLAGOLITIC CAPITAL LETTER YERU;Lu;0;L;;;;;N;;;;2C4F;\n2C20;GLAGOLITIC CAPITAL LETTER YERI;Lu;0;L;;;;;N;;;;2C50;\n2C21;GLAGOLITIC CAPITAL LETTER YATI;Lu;0;L;;;;;N;;;;2C51;\n2C22;GLAGOLITIC CAPITAL LETTER SPIDERY HA;Lu;0;L;;;;;N;;;;2C52;\n2C23;GLAGOLITIC CAPITAL LETTER YU;Lu;0;L;;;;;N;;;;2C53;\n2C24;GLAGOLITIC CAPITAL LETTER SMALL YUS;Lu;0;L;;;;;N;;;;2C54;\n2C25;GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL;Lu;0;L;;;;;N;;;;2C55;\n2C26;GLAGOLITIC CAPITAL LETTER YO;Lu;0;L;;;;;N;;;;2C56;\n2C27;GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS;Lu;0;L;;;;;N;;;;2C57;\n2C28;GLAGOLITIC CAPITAL LETTER BIG YUS;Lu;0;L;;;;;N;;;;2C58;\n2C29;GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS;Lu;0;L;;;;;N;;;;2C59;\n2C2A;GLAGOLITIC CAPITAL LETTER FITA;Lu;0;L;;;;;N;;;;2C5A;\n2C2B;GLAGOLITIC CAPITAL LETTER IZHITSA;Lu;0;L;;;;;N;;;;2C5B;\n2C2C;GLAGOLITIC CAPITAL LETTER SHTAPIC;Lu;0;L;;;;;N;;;;2C5C;\n2C2D;GLAGOLITIC CAPITAL LETTER TROKUTASTI A;Lu;0;L;;;;;N;;;;2C5D;\n2C2E;GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE;Lu;0;L;;;;;N;;;;2C5E;\n2C30;GLAGOLITIC SMALL LETTER AZU;Ll;0;L;;;;;N;;;2C00;;2C00\n2C31;GLAGOLITIC SMALL LETTER BUKY;Ll;0;L;;;;;N;;;2C01;;2C01\n2C32;GLAGOLITIC SMALL LETTER VEDE;Ll;0;L;;;;;N;;;2C02;;2C02\n2C33;GLAGOLITIC SMALL LETTER GLAGOLI;Ll;0;L;;;;;N;;;2C03;;2C03\n2C34;GLAGOLITIC SMALL LETTER DOBRO;Ll;0;L;;;;;N;;;2C04;;2C04\n2C35;GLAGOLITIC SMALL LETTER YESTU;Ll;0;L;;;;;N;;;2C05;;2C05\n2C36;GLAGOLITIC SMALL LETTER ZHIVETE;Ll;0;L;;;;;N;;;2C06;;2C06\n2C37;GLAGOLITIC SMALL LETTER DZELO;Ll;0;L;;;;;N;;;2C07;;2C07\n2C38;GLAGOLITIC SMALL LETTER ZEMLJA;Ll;0;L;;;;;N;;;2C08;;2C08\n2C39;GLAGOLITIC SMALL LETTER IZHE;Ll;0;L;;;;;N;;;2C09;;2C09\n2C3A;GLAGOLITIC SMALL LETTER INITIAL IZHE;Ll;0;L;;;;;N;;;2C0A;;2C0A\n2C3B;GLAGOLITIC SMALL LETTER I;Ll;0;L;;;;;N;;;2C0B;;2C0B\n2C3C;GLAGOLITIC SMALL LETTER DJERVI;Ll;0;L;;;;;N;;;2C0C;;2C0C\n2C3D;GLAGOLITIC SMALL LETTER KAKO;Ll;0;L;;;;;N;;;2C0D;;2C0D\n2C3E;GLAGOLITIC SMALL LETTER LJUDIJE;Ll;0;L;;;;;N;;;2C0E;;2C0E\n2C3F;GLAGOLITIC SMALL LETTER MYSLITE;Ll;0;L;;;;;N;;;2C0F;;2C0F\n2C40;GLAGOLITIC SMALL LETTER NASHI;Ll;0;L;;;;;N;;;2C10;;2C10\n2C41;GLAGOLITIC SMALL LETTER ONU;Ll;0;L;;;;;N;;;2C11;;2C11\n2C42;GLAGOLITIC SMALL LETTER POKOJI;Ll;0;L;;;;;N;;;2C12;;2C12\n2C43;GLAGOLITIC SMALL LETTER RITSI;Ll;0;L;;;;;N;;;2C13;;2C13\n2C44;GLAGOLITIC SMALL LETTER SLOVO;Ll;0;L;;;;;N;;;2C14;;2C14\n2C45;GLAGOLITIC SMALL LETTER TVRIDO;Ll;0;L;;;;;N;;;2C15;;2C15\n2C46;GLAGOLITIC SMALL LETTER UKU;Ll;0;L;;;;;N;;;2C16;;2C16\n2C47;GLAGOLITIC SMALL LETTER FRITU;Ll;0;L;;;;;N;;;2C17;;2C17\n2C48;GLAGOLITIC SMALL LETTER HERU;Ll;0;L;;;;;N;;;2C18;;2C18\n2C49;GLAGOLITIC SMALL LETTER OTU;Ll;0;L;;;;;N;;;2C19;;2C19\n2C4A;GLAGOLITIC SMALL LETTER PE;Ll;0;L;;;;;N;;;2C1A;;2C1A\n2C4B;GLAGOLITIC SMALL LETTER SHTA;Ll;0;L;;;;;N;;;2C1B;;2C1B\n2C4C;GLAGOLITIC SMALL LETTER TSI;Ll;0;L;;;;;N;;;2C1C;;2C1C\n2C4D;GLAGOLITIC SMALL LETTER CHRIVI;Ll;0;L;;;;;N;;;2C1D;;2C1D\n2C4E;GLAGOLITIC SMALL LETTER SHA;Ll;0;L;;;;;N;;;2C1E;;2C1E\n2C4F;GLAGOLITIC SMALL LETTER YERU;Ll;0;L;;;;;N;;;2C1F;;2C1F\n2C50;GLAGOLITIC SMALL LETTER YERI;Ll;0;L;;;;;N;;;2C20;;2C20\n2C51;GLAGOLITIC SMALL LETTER YATI;Ll;0;L;;;;;N;;;2C21;;2C21\n2C52;GLAGOLITIC SMALL LETTER SPIDERY HA;Ll;0;L;;;;;N;;;2C22;;2C22\n2C53;GLAGOLITIC SMALL LETTER YU;Ll;0;L;;;;;N;;;2C23;;2C23\n2C54;GLAGOLITIC SMALL LETTER SMALL YUS;Ll;0;L;;;;;N;;;2C24;;2C24\n2C55;GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL;Ll;0;L;;;;;N;;;2C25;;2C25\n2C56;GLAGOLITIC SMALL LETTER YO;Ll;0;L;;;;;N;;;2C26;;2C26\n2C57;GLAGOLITIC SMALL LETTER IOTATED SMALL YUS;Ll;0;L;;;;;N;;;2C27;;2C27\n2C58;GLAGOLITIC SMALL LETTER BIG YUS;Ll;0;L;;;;;N;;;2C28;;2C28\n2C59;GLAGOLITIC SMALL LETTER IOTATED BIG YUS;Ll;0;L;;;;;N;;;2C29;;2C29\n2C5A;GLAGOLITIC SMALL LETTER FITA;Ll;0;L;;;;;N;;;2C2A;;2C2A\n2C5B;GLAGOLITIC SMALL LETTER IZHITSA;Ll;0;L;;;;;N;;;2C2B;;2C2B\n2C5C;GLAGOLITIC SMALL LETTER SHTAPIC;Ll;0;L;;;;;N;;;2C2C;;2C2C\n2C5D;GLAGOLITIC SMALL LETTER TROKUTASTI A;Ll;0;L;;;;;N;;;2C2D;;2C2D\n2C5E;GLAGOLITIC SMALL LETTER LATINATE MYSLITE;Ll;0;L;;;;;N;;;2C2E;;2C2E\n2C60;LATIN CAPITAL LETTER L WITH DOUBLE BAR;Lu;0;L;;;;;N;;;;2C61;\n2C61;LATIN SMALL LETTER L WITH DOUBLE BAR;Ll;0;L;;;;;N;;;2C60;;2C60\n2C62;LATIN CAPITAL LETTER L WITH MIDDLE TILDE;Lu;0;L;;;;;N;;;;026B;\n2C63;LATIN CAPITAL LETTER P WITH STROKE;Lu;0;L;;;;;N;;;;1D7D;\n2C64;LATIN CAPITAL LETTER R WITH TAIL;Lu;0;L;;;;;N;;;;027D;\n2C65;LATIN SMALL LETTER A WITH STROKE;Ll;0;L;;;;;N;;;023A;;023A\n2C66;LATIN SMALL LETTER T WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;023E;;023E\n2C67;LATIN CAPITAL LETTER H WITH DESCENDER;Lu;0;L;;;;;N;;;;2C68;\n2C68;LATIN SMALL LETTER H WITH DESCENDER;Ll;0;L;;;;;N;;;2C67;;2C67\n2C69;LATIN CAPITAL LETTER K WITH DESCENDER;Lu;0;L;;;;;N;;;;2C6A;\n2C6A;LATIN SMALL LETTER K WITH DESCENDER;Ll;0;L;;;;;N;;;2C69;;2C69\n2C6B;LATIN CAPITAL LETTER Z WITH DESCENDER;Lu;0;L;;;;;N;;;;2C6C;\n2C6C;LATIN SMALL LETTER Z WITH DESCENDER;Ll;0;L;;;;;N;;;2C6B;;2C6B\n2C6D;LATIN CAPITAL LETTER ALPHA;Lu;0;L;;;;;N;;;;0251;\n2C6E;LATIN CAPITAL LETTER M WITH HOOK;Lu;0;L;;;;;N;;;;0271;\n2C6F;LATIN CAPITAL LETTER TURNED A;Lu;0;L;;;;;N;;;;0250;\n2C70;LATIN CAPITAL LETTER TURNED ALPHA;Lu;0;L;;;;;N;;;;0252;\n2C71;LATIN SMALL LETTER V WITH RIGHT HOOK;Ll;0;L;;;;;N;;;;;\n2C72;LATIN CAPITAL LETTER W WITH HOOK;Lu;0;L;;;;;N;;;;2C73;\n2C73;LATIN SMALL LETTER W WITH HOOK;Ll;0;L;;;;;N;;;2C72;;2C72\n2C74;LATIN SMALL LETTER V WITH CURL;Ll;0;L;;;;;N;;;;;\n2C75;LATIN CAPITAL LETTER HALF H;Lu;0;L;;;;;N;;;;2C76;\n2C76;LATIN SMALL LETTER HALF H;Ll;0;L;;;;;N;;;2C75;;2C75\n2C77;LATIN SMALL LETTER TAILLESS PHI;Ll;0;L;;;;;N;;;;;\n2C78;LATIN SMALL LETTER E WITH NOTCH;Ll;0;L;;;;;N;;;;;\n2C79;LATIN SMALL LETTER TURNED R WITH TAIL;Ll;0;L;;;;;N;;;;;\n2C7A;LATIN SMALL LETTER O WITH LOW RING INSIDE;Ll;0;L;;;;;N;;;;;\n2C7B;LATIN LETTER SMALL CAPITAL TURNED E;Ll;0;L;;;;;N;;;;;\n2C7C;LATIN SUBSCRIPT SMALL LETTER J;Lm;0;L;<sub> 006A;;;;N;;;;;\n2C7D;MODIFIER LETTER CAPITAL V;Lm;0;L;<super> 0056;;;;N;;;;;\n2C7E;LATIN CAPITAL LETTER S WITH SWASH TAIL;Lu;0;L;;;;;N;;;;023F;\n2C7F;LATIN CAPITAL LETTER Z WITH SWASH TAIL;Lu;0;L;;;;;N;;;;0240;\n2C80;COPTIC CAPITAL LETTER ALFA;Lu;0;L;;;;;N;;;;2C81;\n2C81;COPTIC SMALL LETTER ALFA;Ll;0;L;;;;;N;;;2C80;;2C80\n2C82;COPTIC CAPITAL LETTER VIDA;Lu;0;L;;;;;N;;;;2C83;\n2C83;COPTIC SMALL LETTER VIDA;Ll;0;L;;;;;N;;;2C82;;2C82\n2C84;COPTIC CAPITAL LETTER GAMMA;Lu;0;L;;;;;N;;;;2C85;\n2C85;COPTIC SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;2C84;;2C84\n2C86;COPTIC CAPITAL LETTER DALDA;Lu;0;L;;;;;N;;;;2C87;\n2C87;COPTIC SMALL LETTER DALDA;Ll;0;L;;;;;N;;;2C86;;2C86\n2C88;COPTIC CAPITAL LETTER EIE;Lu;0;L;;;;;N;;;;2C89;\n2C89;COPTIC SMALL LETTER EIE;Ll;0;L;;;;;N;;;2C88;;2C88\n2C8A;COPTIC CAPITAL LETTER SOU;Lu;0;L;;;;;N;;;;2C8B;\n2C8B;COPTIC SMALL LETTER SOU;Ll;0;L;;;;;N;;;2C8A;;2C8A\n2C8C;COPTIC CAPITAL LETTER ZATA;Lu;0;L;;;;;N;;;;2C8D;\n2C8D;COPTIC SMALL LETTER ZATA;Ll;0;L;;;;;N;;;2C8C;;2C8C\n2C8E;COPTIC CAPITAL LETTER HATE;Lu;0;L;;;;;N;;;;2C8F;\n2C8F;COPTIC SMALL LETTER HATE;Ll;0;L;;;;;N;;;2C8E;;2C8E\n2C90;COPTIC CAPITAL LETTER THETHE;Lu;0;L;;;;;N;;;;2C91;\n2C91;COPTIC SMALL LETTER THETHE;Ll;0;L;;;;;N;;;2C90;;2C90\n2C92;COPTIC CAPITAL LETTER IAUDA;Lu;0;L;;;;;N;;;;2C93;\n2C93;COPTIC SMALL LETTER IAUDA;Ll;0;L;;;;;N;;;2C92;;2C92\n2C94;COPTIC CAPITAL LETTER KAPA;Lu;0;L;;;;;N;;;;2C95;\n2C95;COPTIC SMALL LETTER KAPA;Ll;0;L;;;;;N;;;2C94;;2C94\n2C96;COPTIC CAPITAL LETTER LAULA;Lu;0;L;;;;;N;;;;2C97;\n2C97;COPTIC SMALL LETTER LAULA;Ll;0;L;;;;;N;;;2C96;;2C96\n2C98;COPTIC CAPITAL LETTER MI;Lu;0;L;;;;;N;;;;2C99;\n2C99;COPTIC SMALL LETTER MI;Ll;0;L;;;;;N;;;2C98;;2C98\n2C9A;COPTIC CAPITAL LETTER NI;Lu;0;L;;;;;N;;;;2C9B;\n2C9B;COPTIC SMALL LETTER NI;Ll;0;L;;;;;N;;;2C9A;;2C9A\n2C9C;COPTIC CAPITAL LETTER KSI;Lu;0;L;;;;;N;;;;2C9D;\n2C9D;COPTIC SMALL LETTER KSI;Ll;0;L;;;;;N;;;2C9C;;2C9C\n2C9E;COPTIC CAPITAL LETTER O;Lu;0;L;;;;;N;;;;2C9F;\n2C9F;COPTIC SMALL LETTER O;Ll;0;L;;;;;N;;;2C9E;;2C9E\n2CA0;COPTIC CAPITAL LETTER PI;Lu;0;L;;;;;N;;;;2CA1;\n2CA1;COPTIC SMALL LETTER PI;Ll;0;L;;;;;N;;;2CA0;;2CA0\n2CA2;COPTIC CAPITAL LETTER RO;Lu;0;L;;;;;N;;;;2CA3;\n2CA3;COPTIC SMALL LETTER RO;Ll;0;L;;;;;N;;;2CA2;;2CA2\n2CA4;COPTIC CAPITAL LETTER SIMA;Lu;0;L;;;;;N;;;;2CA5;\n2CA5;COPTIC SMALL LETTER SIMA;Ll;0;L;;;;;N;;;2CA4;;2CA4\n2CA6;COPTIC CAPITAL LETTER TAU;Lu;0;L;;;;;N;;;;2CA7;\n2CA7;COPTIC SMALL LETTER TAU;Ll;0;L;;;;;N;;;2CA6;;2CA6\n2CA8;COPTIC CAPITAL LETTER UA;Lu;0;L;;;;;N;;;;2CA9;\n2CA9;COPTIC SMALL LETTER UA;Ll;0;L;;;;;N;;;2CA8;;2CA8\n2CAA;COPTIC CAPITAL LETTER FI;Lu;0;L;;;;;N;;;;2CAB;\n2CAB;COPTIC SMALL LETTER FI;Ll;0;L;;;;;N;;;2CAA;;2CAA\n2CAC;COPTIC CAPITAL LETTER KHI;Lu;0;L;;;;;N;;;;2CAD;\n2CAD;COPTIC SMALL LETTER KHI;Ll;0;L;;;;;N;;;2CAC;;2CAC\n2CAE;COPTIC CAPITAL LETTER PSI;Lu;0;L;;;;;N;;;;2CAF;\n2CAF;COPTIC SMALL LETTER PSI;Ll;0;L;;;;;N;;;2CAE;;2CAE\n2CB0;COPTIC CAPITAL LETTER OOU;Lu;0;L;;;;;N;;;;2CB1;\n2CB1;COPTIC SMALL LETTER OOU;Ll;0;L;;;;;N;;;2CB0;;2CB0\n2CB2;COPTIC CAPITAL LETTER DIALECT-P ALEF;Lu;0;L;;;;;N;;;;2CB3;\n2CB3;COPTIC SMALL LETTER DIALECT-P ALEF;Ll;0;L;;;;;N;;;2CB2;;2CB2\n2CB4;COPTIC CAPITAL LETTER OLD COPTIC AIN;Lu;0;L;;;;;N;;;;2CB5;\n2CB5;COPTIC SMALL LETTER OLD COPTIC AIN;Ll;0;L;;;;;N;;;2CB4;;2CB4\n2CB6;COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE;Lu;0;L;;;;;N;;;;2CB7;\n2CB7;COPTIC SMALL LETTER CRYPTOGRAMMIC EIE;Ll;0;L;;;;;N;;;2CB6;;2CB6\n2CB8;COPTIC CAPITAL LETTER DIALECT-P KAPA;Lu;0;L;;;;;N;;;;2CB9;\n2CB9;COPTIC SMALL LETTER DIALECT-P KAPA;Ll;0;L;;;;;N;;;2CB8;;2CB8\n2CBA;COPTIC CAPITAL LETTER DIALECT-P NI;Lu;0;L;;;;;N;;;;2CBB;\n2CBB;COPTIC SMALL LETTER DIALECT-P NI;Ll;0;L;;;;;N;;;2CBA;;2CBA\n2CBC;COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI;Lu;0;L;;;;;N;;;;2CBD;\n2CBD;COPTIC SMALL LETTER CRYPTOGRAMMIC NI;Ll;0;L;;;;;N;;;2CBC;;2CBC\n2CBE;COPTIC CAPITAL LETTER OLD COPTIC OOU;Lu;0;L;;;;;N;;;;2CBF;\n2CBF;COPTIC SMALL LETTER OLD COPTIC OOU;Ll;0;L;;;;;N;;;2CBE;;2CBE\n2CC0;COPTIC CAPITAL LETTER SAMPI;Lu;0;L;;;;;N;;;;2CC1;\n2CC1;COPTIC SMALL LETTER SAMPI;Ll;0;L;;;;;N;;;2CC0;;2CC0\n2CC2;COPTIC CAPITAL LETTER CROSSED SHEI;Lu;0;L;;;;;N;;;;2CC3;\n2CC3;COPTIC SMALL LETTER CROSSED SHEI;Ll;0;L;;;;;N;;;2CC2;;2CC2\n2CC4;COPTIC CAPITAL LETTER OLD COPTIC SHEI;Lu;0;L;;;;;N;;;;2CC5;\n2CC5;COPTIC SMALL LETTER OLD COPTIC SHEI;Ll;0;L;;;;;N;;;2CC4;;2CC4\n2CC6;COPTIC CAPITAL LETTER OLD COPTIC ESH;Lu;0;L;;;;;N;;;;2CC7;\n2CC7;COPTIC SMALL LETTER OLD COPTIC ESH;Ll;0;L;;;;;N;;;2CC6;;2CC6\n2CC8;COPTIC CAPITAL LETTER AKHMIMIC KHEI;Lu;0;L;;;;;N;;;;2CC9;\n2CC9;COPTIC SMALL LETTER AKHMIMIC KHEI;Ll;0;L;;;;;N;;;2CC8;;2CC8\n2CCA;COPTIC CAPITAL LETTER DIALECT-P HORI;Lu;0;L;;;;;N;;;;2CCB;\n2CCB;COPTIC SMALL LETTER DIALECT-P HORI;Ll;0;L;;;;;N;;;2CCA;;2CCA\n2CCC;COPTIC CAPITAL LETTER OLD COPTIC HORI;Lu;0;L;;;;;N;;;;2CCD;\n2CCD;COPTIC SMALL LETTER OLD COPTIC HORI;Ll;0;L;;;;;N;;;2CCC;;2CCC\n2CCE;COPTIC CAPITAL LETTER OLD COPTIC HA;Lu;0;L;;;;;N;;;;2CCF;\n2CCF;COPTIC SMALL LETTER OLD COPTIC HA;Ll;0;L;;;;;N;;;2CCE;;2CCE\n2CD0;COPTIC CAPITAL LETTER L-SHAPED HA;Lu;0;L;;;;;N;;;;2CD1;\n2CD1;COPTIC SMALL LETTER L-SHAPED HA;Ll;0;L;;;;;N;;;2CD0;;2CD0\n2CD2;COPTIC CAPITAL LETTER OLD COPTIC HEI;Lu;0;L;;;;;N;;;;2CD3;\n2CD3;COPTIC SMALL LETTER OLD COPTIC HEI;Ll;0;L;;;;;N;;;2CD2;;2CD2\n2CD4;COPTIC CAPITAL LETTER OLD COPTIC HAT;Lu;0;L;;;;;N;;;;2CD5;\n2CD5;COPTIC SMALL LETTER OLD COPTIC HAT;Ll;0;L;;;;;N;;;2CD4;;2CD4\n2CD6;COPTIC CAPITAL LETTER OLD COPTIC GANGIA;Lu;0;L;;;;;N;;;;2CD7;\n2CD7;COPTIC SMALL LETTER OLD COPTIC GANGIA;Ll;0;L;;;;;N;;;2CD6;;2CD6\n2CD8;COPTIC CAPITAL LETTER OLD COPTIC DJA;Lu;0;L;;;;;N;;;;2CD9;\n2CD9;COPTIC SMALL LETTER OLD COPTIC DJA;Ll;0;L;;;;;N;;;2CD8;;2CD8\n2CDA;COPTIC CAPITAL LETTER OLD COPTIC SHIMA;Lu;0;L;;;;;N;;;;2CDB;\n2CDB;COPTIC SMALL LETTER OLD COPTIC SHIMA;Ll;0;L;;;;;N;;;2CDA;;2CDA\n2CDC;COPTIC CAPITAL LETTER OLD NUBIAN SHIMA;Lu;0;L;;;;;N;;;;2CDD;\n2CDD;COPTIC SMALL LETTER OLD NUBIAN SHIMA;Ll;0;L;;;;;N;;;2CDC;;2CDC\n2CDE;COPTIC CAPITAL LETTER OLD NUBIAN NGI;Lu;0;L;;;;;N;;;;2CDF;\n2CDF;COPTIC SMALL LETTER OLD NUBIAN NGI;Ll;0;L;;;;;N;;;2CDE;;2CDE\n2CE0;COPTIC CAPITAL LETTER OLD NUBIAN NYI;Lu;0;L;;;;;N;;;;2CE1;\n2CE1;COPTIC SMALL LETTER OLD NUBIAN NYI;Ll;0;L;;;;;N;;;2CE0;;2CE0\n2CE2;COPTIC CAPITAL LETTER OLD NUBIAN WAU;Lu;0;L;;;;;N;;;;2CE3;\n2CE3;COPTIC SMALL LETTER OLD NUBIAN WAU;Ll;0;L;;;;;N;;;2CE2;;2CE2\n2CE4;COPTIC SYMBOL KAI;Ll;0;L;;;;;N;;;;;\n2CE5;COPTIC SYMBOL MI RO;So;0;ON;;;;;N;;;;;\n2CE6;COPTIC SYMBOL PI RO;So;0;ON;;;;;N;;;;;\n2CE7;COPTIC SYMBOL STAUROS;So;0;ON;;;;;N;;;;;\n2CE8;COPTIC SYMBOL TAU RO;So;0;ON;;;;;N;;;;;\n2CE9;COPTIC SYMBOL KHI RO;So;0;ON;;;;;N;;;;;\n2CEA;COPTIC SYMBOL SHIMA SIMA;So;0;ON;;;;;N;;;;;\n2CEB;COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI;Lu;0;L;;;;;N;;;;2CEC;\n2CEC;COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI;Ll;0;L;;;;;N;;;2CEB;;2CEB\n2CED;COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA;Lu;0;L;;;;;N;;;;2CEE;\n2CEE;COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA;Ll;0;L;;;;;N;;;2CED;;2CED\n2CEF;COPTIC COMBINING NI ABOVE;Mn;230;NSM;;;;;N;;;;;\n2CF0;COPTIC COMBINING SPIRITUS ASPER;Mn;230;NSM;;;;;N;;;;;\n2CF1;COPTIC COMBINING SPIRITUS LENIS;Mn;230;NSM;;;;;N;;;;;\n2CF2;COPTIC CAPITAL LETTER BOHAIRIC KHEI;Lu;0;L;;;;;N;;;;2CF3;\n2CF3;COPTIC SMALL LETTER BOHAIRIC KHEI;Ll;0;L;;;;;N;;;2CF2;;2CF2\n2CF9;COPTIC OLD NUBIAN FULL STOP;Po;0;ON;;;;;N;;;;;\n2CFA;COPTIC OLD NUBIAN DIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;;\n2CFB;COPTIC OLD NUBIAN INDIRECT QUESTION MARK;Po;0;ON;;;;;N;;;;;\n2CFC;COPTIC OLD NUBIAN VERSE DIVIDER;Po;0;ON;;;;;N;;;;;\n2CFD;COPTIC FRACTION ONE HALF;No;0;ON;;;;1/2;N;;;;;\n2CFE;COPTIC FULL STOP;Po;0;ON;;;;;N;;;;;\n2CFF;COPTIC MORPHOLOGICAL DIVIDER;Po;0;ON;;;;;N;;;;;\n2D00;GEORGIAN SMALL LETTER AN;Ll;0;L;;;;;N;;;10A0;;10A0\n2D01;GEORGIAN SMALL LETTER BAN;Ll;0;L;;;;;N;;;10A1;;10A1\n2D02;GEORGIAN SMALL LETTER GAN;Ll;0;L;;;;;N;;;10A2;;10A2\n2D03;GEORGIAN SMALL LETTER DON;Ll;0;L;;;;;N;;;10A3;;10A3\n2D04;GEORGIAN SMALL LETTER EN;Ll;0;L;;;;;N;;;10A4;;10A4\n2D05;GEORGIAN SMALL LETTER VIN;Ll;0;L;;;;;N;;;10A5;;10A5\n2D06;GEORGIAN SMALL LETTER ZEN;Ll;0;L;;;;;N;;;10A6;;10A6\n2D07;GEORGIAN SMALL LETTER TAN;Ll;0;L;;;;;N;;;10A7;;10A7\n2D08;GEORGIAN SMALL LETTER IN;Ll;0;L;;;;;N;;;10A8;;10A8\n2D09;GEORGIAN SMALL LETTER KAN;Ll;0;L;;;;;N;;;10A9;;10A9\n2D0A;GEORGIAN SMALL LETTER LAS;Ll;0;L;;;;;N;;;10AA;;10AA\n2D0B;GEORGIAN SMALL LETTER MAN;Ll;0;L;;;;;N;;;10AB;;10AB\n2D0C;GEORGIAN SMALL LETTER NAR;Ll;0;L;;;;;N;;;10AC;;10AC\n2D0D;GEORGIAN SMALL LETTER ON;Ll;0;L;;;;;N;;;10AD;;10AD\n2D0E;GEORGIAN SMALL LETTER PAR;Ll;0;L;;;;;N;;;10AE;;10AE\n2D0F;GEORGIAN SMALL LETTER ZHAR;Ll;0;L;;;;;N;;;10AF;;10AF\n2D10;GEORGIAN SMALL LETTER RAE;Ll;0;L;;;;;N;;;10B0;;10B0\n2D11;GEORGIAN SMALL LETTER SAN;Ll;0;L;;;;;N;;;10B1;;10B1\n2D12;GEORGIAN SMALL LETTER TAR;Ll;0;L;;;;;N;;;10B2;;10B2\n2D13;GEORGIAN SMALL LETTER UN;Ll;0;L;;;;;N;;;10B3;;10B3\n2D14;GEORGIAN SMALL LETTER PHAR;Ll;0;L;;;;;N;;;10B4;;10B4\n2D15;GEORGIAN SMALL LETTER KHAR;Ll;0;L;;;;;N;;;10B5;;10B5\n2D16;GEORGIAN SMALL LETTER GHAN;Ll;0;L;;;;;N;;;10B6;;10B6\n2D17;GEORGIAN SMALL LETTER QAR;Ll;0;L;;;;;N;;;10B7;;10B7\n2D18;GEORGIAN SMALL LETTER SHIN;Ll;0;L;;;;;N;;;10B8;;10B8\n2D19;GEORGIAN SMALL LETTER CHIN;Ll;0;L;;;;;N;;;10B9;;10B9\n2D1A;GEORGIAN SMALL LETTER CAN;Ll;0;L;;;;;N;;;10BA;;10BA\n2D1B;GEORGIAN SMALL LETTER JIL;Ll;0;L;;;;;N;;;10BB;;10BB\n2D1C;GEORGIAN SMALL LETTER CIL;Ll;0;L;;;;;N;;;10BC;;10BC\n2D1D;GEORGIAN SMALL LETTER CHAR;Ll;0;L;;;;;N;;;10BD;;10BD\n2D1E;GEORGIAN SMALL LETTER XAN;Ll;0;L;;;;;N;;;10BE;;10BE\n2D1F;GEORGIAN SMALL LETTER JHAN;Ll;0;L;;;;;N;;;10BF;;10BF\n2D20;GEORGIAN SMALL LETTER HAE;Ll;0;L;;;;;N;;;10C0;;10C0\n2D21;GEORGIAN SMALL LETTER HE;Ll;0;L;;;;;N;;;10C1;;10C1\n2D22;GEORGIAN SMALL LETTER HIE;Ll;0;L;;;;;N;;;10C2;;10C2\n2D23;GEORGIAN SMALL LETTER WE;Ll;0;L;;;;;N;;;10C3;;10C3\n2D24;GEORGIAN SMALL LETTER HAR;Ll;0;L;;;;;N;;;10C4;;10C4\n2D25;GEORGIAN SMALL LETTER HOE;Ll;0;L;;;;;N;;;10C5;;10C5\n2D27;GEORGIAN SMALL LETTER YN;Ll;0;L;;;;;N;;;10C7;;10C7\n2D2D;GEORGIAN SMALL LETTER AEN;Ll;0;L;;;;;N;;;10CD;;10CD\n2D30;TIFINAGH LETTER YA;Lo;0;L;;;;;N;;;;;\n2D31;TIFINAGH LETTER YAB;Lo;0;L;;;;;N;;;;;\n2D32;TIFINAGH LETTER YABH;Lo;0;L;;;;;N;;;;;\n2D33;TIFINAGH LETTER YAG;Lo;0;L;;;;;N;;;;;\n2D34;TIFINAGH LETTER YAGHH;Lo;0;L;;;;;N;;;;;\n2D35;TIFINAGH LETTER BERBER ACADEMY YAJ;Lo;0;L;;;;;N;;;;;\n2D36;TIFINAGH LETTER YAJ;Lo;0;L;;;;;N;;;;;\n2D37;TIFINAGH LETTER YAD;Lo;0;L;;;;;N;;;;;\n2D38;TIFINAGH LETTER YADH;Lo;0;L;;;;;N;;;;;\n2D39;TIFINAGH LETTER YADD;Lo;0;L;;;;;N;;;;;\n2D3A;TIFINAGH LETTER YADDH;Lo;0;L;;;;;N;;;;;\n2D3B;TIFINAGH LETTER YEY;Lo;0;L;;;;;N;;;;;\n2D3C;TIFINAGH LETTER YAF;Lo;0;L;;;;;N;;;;;\n2D3D;TIFINAGH LETTER YAK;Lo;0;L;;;;;N;;;;;\n2D3E;TIFINAGH LETTER TUAREG YAK;Lo;0;L;;;;;N;;;;;\n2D3F;TIFINAGH LETTER YAKHH;Lo;0;L;;;;;N;;;;;\n2D40;TIFINAGH LETTER YAH;Lo;0;L;;;;;N;;;;;\n2D41;TIFINAGH LETTER BERBER ACADEMY YAH;Lo;0;L;;;;;N;;;;;\n2D42;TIFINAGH LETTER TUAREG YAH;Lo;0;L;;;;;N;;;;;\n2D43;TIFINAGH LETTER YAHH;Lo;0;L;;;;;N;;;;;\n2D44;TIFINAGH LETTER YAA;Lo;0;L;;;;;N;;;;;\n2D45;TIFINAGH LETTER YAKH;Lo;0;L;;;;;N;;;;;\n2D46;TIFINAGH LETTER TUAREG YAKH;Lo;0;L;;;;;N;;;;;\n2D47;TIFINAGH LETTER YAQ;Lo;0;L;;;;;N;;;;;\n2D48;TIFINAGH LETTER TUAREG YAQ;Lo;0;L;;;;;N;;;;;\n2D49;TIFINAGH LETTER YI;Lo;0;L;;;;;N;;;;;\n2D4A;TIFINAGH LETTER YAZH;Lo;0;L;;;;;N;;;;;\n2D4B;TIFINAGH LETTER AHAGGAR YAZH;Lo;0;L;;;;;N;;;;;\n2D4C;TIFINAGH LETTER TUAREG YAZH;Lo;0;L;;;;;N;;;;;\n2D4D;TIFINAGH LETTER YAL;Lo;0;L;;;;;N;;;;;\n2D4E;TIFINAGH LETTER YAM;Lo;0;L;;;;;N;;;;;\n2D4F;TIFINAGH LETTER YAN;Lo;0;L;;;;;N;;;;;\n2D50;TIFINAGH LETTER TUAREG YAGN;Lo;0;L;;;;;N;;;;;\n2D51;TIFINAGH LETTER TUAREG YANG;Lo;0;L;;;;;N;;;;;\n2D52;TIFINAGH LETTER YAP;Lo;0;L;;;;;N;;;;;\n2D53;TIFINAGH LETTER YU;Lo;0;L;;;;;N;;;;;\n2D54;TIFINAGH LETTER YAR;Lo;0;L;;;;;N;;;;;\n2D55;TIFINAGH LETTER YARR;Lo;0;L;;;;;N;;;;;\n2D56;TIFINAGH LETTER YAGH;Lo;0;L;;;;;N;;;;;\n2D57;TIFINAGH LETTER TUAREG YAGH;Lo;0;L;;;;;N;;;;;\n2D58;TIFINAGH LETTER AYER YAGH;Lo;0;L;;;;;N;;;;;\n2D59;TIFINAGH LETTER YAS;Lo;0;L;;;;;N;;;;;\n2D5A;TIFINAGH LETTER YASS;Lo;0;L;;;;;N;;;;;\n2D5B;TIFINAGH LETTER YASH;Lo;0;L;;;;;N;;;;;\n2D5C;TIFINAGH LETTER YAT;Lo;0;L;;;;;N;;;;;\n2D5D;TIFINAGH LETTER YATH;Lo;0;L;;;;;N;;;;;\n2D5E;TIFINAGH LETTER YACH;Lo;0;L;;;;;N;;;;;\n2D5F;TIFINAGH LETTER YATT;Lo;0;L;;;;;N;;;;;\n2D60;TIFINAGH LETTER YAV;Lo;0;L;;;;;N;;;;;\n2D61;TIFINAGH LETTER YAW;Lo;0;L;;;;;N;;;;;\n2D62;TIFINAGH LETTER YAY;Lo;0;L;;;;;N;;;;;\n2D63;TIFINAGH LETTER YAZ;Lo;0;L;;;;;N;;;;;\n2D64;TIFINAGH LETTER TAWELLEMET YAZ;Lo;0;L;;;;;N;;;;;\n2D65;TIFINAGH LETTER YAZZ;Lo;0;L;;;;;N;;;;;\n2D66;TIFINAGH LETTER YE;Lo;0;L;;;;;N;;;;;\n2D67;TIFINAGH LETTER YO;Lo;0;L;;;;;N;;;;;\n2D6F;TIFINAGH MODIFIER LETTER LABIALIZATION MARK;Lm;0;L;<super> 2D61;;;;N;;;;;\n2D70;TIFINAGH SEPARATOR MARK;Po;0;L;;;;;N;;;;;\n2D7F;TIFINAGH CONSONANT JOINER;Mn;9;NSM;;;;;N;;;;;\n2D80;ETHIOPIC SYLLABLE LOA;Lo;0;L;;;;;N;;;;;\n2D81;ETHIOPIC SYLLABLE MOA;Lo;0;L;;;;;N;;;;;\n2D82;ETHIOPIC SYLLABLE ROA;Lo;0;L;;;;;N;;;;;\n2D83;ETHIOPIC SYLLABLE SOA;Lo;0;L;;;;;N;;;;;\n2D84;ETHIOPIC SYLLABLE SHOA;Lo;0;L;;;;;N;;;;;\n2D85;ETHIOPIC SYLLABLE BOA;Lo;0;L;;;;;N;;;;;\n2D86;ETHIOPIC SYLLABLE TOA;Lo;0;L;;;;;N;;;;;\n2D87;ETHIOPIC SYLLABLE COA;Lo;0;L;;;;;N;;;;;\n2D88;ETHIOPIC SYLLABLE NOA;Lo;0;L;;;;;N;;;;;\n2D89;ETHIOPIC SYLLABLE NYOA;Lo;0;L;;;;;N;;;;;\n2D8A;ETHIOPIC SYLLABLE GLOTTAL OA;Lo;0;L;;;;;N;;;;;\n2D8B;ETHIOPIC SYLLABLE ZOA;Lo;0;L;;;;;N;;;;;\n2D8C;ETHIOPIC SYLLABLE DOA;Lo;0;L;;;;;N;;;;;\n2D8D;ETHIOPIC SYLLABLE DDOA;Lo;0;L;;;;;N;;;;;\n2D8E;ETHIOPIC SYLLABLE JOA;Lo;0;L;;;;;N;;;;;\n2D8F;ETHIOPIC SYLLABLE THOA;Lo;0;L;;;;;N;;;;;\n2D90;ETHIOPIC SYLLABLE CHOA;Lo;0;L;;;;;N;;;;;\n2D91;ETHIOPIC SYLLABLE PHOA;Lo;0;L;;;;;N;;;;;\n2D92;ETHIOPIC SYLLABLE POA;Lo;0;L;;;;;N;;;;;\n2D93;ETHIOPIC SYLLABLE GGWA;Lo;0;L;;;;;N;;;;;\n2D94;ETHIOPIC SYLLABLE GGWI;Lo;0;L;;;;;N;;;;;\n2D95;ETHIOPIC SYLLABLE GGWEE;Lo;0;L;;;;;N;;;;;\n2D96;ETHIOPIC SYLLABLE GGWE;Lo;0;L;;;;;N;;;;;\n2DA0;ETHIOPIC SYLLABLE SSA;Lo;0;L;;;;;N;;;;;\n2DA1;ETHIOPIC SYLLABLE SSU;Lo;0;L;;;;;N;;;;;\n2DA2;ETHIOPIC SYLLABLE SSI;Lo;0;L;;;;;N;;;;;\n2DA3;ETHIOPIC SYLLABLE SSAA;Lo;0;L;;;;;N;;;;;\n2DA4;ETHIOPIC SYLLABLE SSEE;Lo;0;L;;;;;N;;;;;\n2DA5;ETHIOPIC SYLLABLE SSE;Lo;0;L;;;;;N;;;;;\n2DA6;ETHIOPIC SYLLABLE SSO;Lo;0;L;;;;;N;;;;;\n2DA8;ETHIOPIC SYLLABLE CCA;Lo;0;L;;;;;N;;;;;\n2DA9;ETHIOPIC SYLLABLE CCU;Lo;0;L;;;;;N;;;;;\n2DAA;ETHIOPIC SYLLABLE CCI;Lo;0;L;;;;;N;;;;;\n2DAB;ETHIOPIC SYLLABLE CCAA;Lo;0;L;;;;;N;;;;;\n2DAC;ETHIOPIC SYLLABLE CCEE;Lo;0;L;;;;;N;;;;;\n2DAD;ETHIOPIC SYLLABLE CCE;Lo;0;L;;;;;N;;;;;\n2DAE;ETHIOPIC SYLLABLE CCO;Lo;0;L;;;;;N;;;;;\n2DB0;ETHIOPIC SYLLABLE ZZA;Lo;0;L;;;;;N;;;;;\n2DB1;ETHIOPIC SYLLABLE ZZU;Lo;0;L;;;;;N;;;;;\n2DB2;ETHIOPIC SYLLABLE ZZI;Lo;0;L;;;;;N;;;;;\n2DB3;ETHIOPIC SYLLABLE ZZAA;Lo;0;L;;;;;N;;;;;\n2DB4;ETHIOPIC SYLLABLE ZZEE;Lo;0;L;;;;;N;;;;;\n2DB5;ETHIOPIC SYLLABLE ZZE;Lo;0;L;;;;;N;;;;;\n2DB6;ETHIOPIC SYLLABLE ZZO;Lo;0;L;;;;;N;;;;;\n2DB8;ETHIOPIC SYLLABLE CCHA;Lo;0;L;;;;;N;;;;;\n2DB9;ETHIOPIC SYLLABLE CCHU;Lo;0;L;;;;;N;;;;;\n2DBA;ETHIOPIC SYLLABLE CCHI;Lo;0;L;;;;;N;;;;;\n2DBB;ETHIOPIC SYLLABLE CCHAA;Lo;0;L;;;;;N;;;;;\n2DBC;ETHIOPIC SYLLABLE CCHEE;Lo;0;L;;;;;N;;;;;\n2DBD;ETHIOPIC SYLLABLE CCHE;Lo;0;L;;;;;N;;;;;\n2DBE;ETHIOPIC SYLLABLE CCHO;Lo;0;L;;;;;N;;;;;\n2DC0;ETHIOPIC SYLLABLE QYA;Lo;0;L;;;;;N;;;;;\n2DC1;ETHIOPIC SYLLABLE QYU;Lo;0;L;;;;;N;;;;;\n2DC2;ETHIOPIC SYLLABLE QYI;Lo;0;L;;;;;N;;;;;\n2DC3;ETHIOPIC SYLLABLE QYAA;Lo;0;L;;;;;N;;;;;\n2DC4;ETHIOPIC SYLLABLE QYEE;Lo;0;L;;;;;N;;;;;\n2DC5;ETHIOPIC SYLLABLE QYE;Lo;0;L;;;;;N;;;;;\n2DC6;ETHIOPIC SYLLABLE QYO;Lo;0;L;;;;;N;;;;;\n2DC8;ETHIOPIC SYLLABLE KYA;Lo;0;L;;;;;N;;;;;\n2DC9;ETHIOPIC SYLLABLE KYU;Lo;0;L;;;;;N;;;;;\n2DCA;ETHIOPIC SYLLABLE KYI;Lo;0;L;;;;;N;;;;;\n2DCB;ETHIOPIC SYLLABLE KYAA;Lo;0;L;;;;;N;;;;;\n2DCC;ETHIOPIC SYLLABLE KYEE;Lo;0;L;;;;;N;;;;;\n2DCD;ETHIOPIC SYLLABLE KYE;Lo;0;L;;;;;N;;;;;\n2DCE;ETHIOPIC SYLLABLE KYO;Lo;0;L;;;;;N;;;;;\n2DD0;ETHIOPIC SYLLABLE XYA;Lo;0;L;;;;;N;;;;;\n2DD1;ETHIOPIC SYLLABLE XYU;Lo;0;L;;;;;N;;;;;\n2DD2;ETHIOPIC SYLLABLE XYI;Lo;0;L;;;;;N;;;;;\n2DD3;ETHIOPIC SYLLABLE XYAA;Lo;0;L;;;;;N;;;;;\n2DD4;ETHIOPIC SYLLABLE XYEE;Lo;0;L;;;;;N;;;;;\n2DD5;ETHIOPIC SYLLABLE XYE;Lo;0;L;;;;;N;;;;;\n2DD6;ETHIOPIC SYLLABLE XYO;Lo;0;L;;;;;N;;;;;\n2DD8;ETHIOPIC SYLLABLE GYA;Lo;0;L;;;;;N;;;;;\n2DD9;ETHIOPIC SYLLABLE GYU;Lo;0;L;;;;;N;;;;;\n2DDA;ETHIOPIC SYLLABLE GYI;Lo;0;L;;;;;N;;;;;\n2DDB;ETHIOPIC SYLLABLE GYAA;Lo;0;L;;;;;N;;;;;\n2DDC;ETHIOPIC SYLLABLE GYEE;Lo;0;L;;;;;N;;;;;\n2DDD;ETHIOPIC SYLLABLE GYE;Lo;0;L;;;;;N;;;;;\n2DDE;ETHIOPIC SYLLABLE GYO;Lo;0;L;;;;;N;;;;;\n2DE0;COMBINING CYRILLIC LETTER BE;Mn;230;NSM;;;;;N;;;;;\n2DE1;COMBINING CYRILLIC LETTER VE;Mn;230;NSM;;;;;N;;;;;\n2DE2;COMBINING CYRILLIC LETTER GHE;Mn;230;NSM;;;;;N;;;;;\n2DE3;COMBINING CYRILLIC LETTER DE;Mn;230;NSM;;;;;N;;;;;\n2DE4;COMBINING CYRILLIC LETTER ZHE;Mn;230;NSM;;;;;N;;;;;\n2DE5;COMBINING CYRILLIC LETTER ZE;Mn;230;NSM;;;;;N;;;;;\n2DE6;COMBINING CYRILLIC LETTER KA;Mn;230;NSM;;;;;N;;;;;\n2DE7;COMBINING CYRILLIC LETTER EL;Mn;230;NSM;;;;;N;;;;;\n2DE8;COMBINING CYRILLIC LETTER EM;Mn;230;NSM;;;;;N;;;;;\n2DE9;COMBINING CYRILLIC LETTER EN;Mn;230;NSM;;;;;N;;;;;\n2DEA;COMBINING CYRILLIC LETTER O;Mn;230;NSM;;;;;N;;;;;\n2DEB;COMBINING CYRILLIC LETTER PE;Mn;230;NSM;;;;;N;;;;;\n2DEC;COMBINING CYRILLIC LETTER ER;Mn;230;NSM;;;;;N;;;;;\n2DED;COMBINING CYRILLIC LETTER ES;Mn;230;NSM;;;;;N;;;;;\n2DEE;COMBINING CYRILLIC LETTER TE;Mn;230;NSM;;;;;N;;;;;\n2DEF;COMBINING CYRILLIC LETTER HA;Mn;230;NSM;;;;;N;;;;;\n2DF0;COMBINING CYRILLIC LETTER TSE;Mn;230;NSM;;;;;N;;;;;\n2DF1;COMBINING CYRILLIC LETTER CHE;Mn;230;NSM;;;;;N;;;;;\n2DF2;COMBINING CYRILLIC LETTER SHA;Mn;230;NSM;;;;;N;;;;;\n2DF3;COMBINING CYRILLIC LETTER SHCHA;Mn;230;NSM;;;;;N;;;;;\n2DF4;COMBINING CYRILLIC LETTER FITA;Mn;230;NSM;;;;;N;;;;;\n2DF5;COMBINING CYRILLIC LETTER ES-TE;Mn;230;NSM;;;;;N;;;;;\n2DF6;COMBINING CYRILLIC LETTER A;Mn;230;NSM;;;;;N;;;;;\n2DF7;COMBINING CYRILLIC LETTER IE;Mn;230;NSM;;;;;N;;;;;\n2DF8;COMBINING CYRILLIC LETTER DJERV;Mn;230;NSM;;;;;N;;;;;\n2DF9;COMBINING CYRILLIC LETTER MONOGRAPH UK;Mn;230;NSM;;;;;N;;;;;\n2DFA;COMBINING CYRILLIC LETTER YAT;Mn;230;NSM;;;;;N;;;;;\n2DFB;COMBINING CYRILLIC LETTER YU;Mn;230;NSM;;;;;N;;;;;\n2DFC;COMBINING CYRILLIC LETTER IOTIFIED A;Mn;230;NSM;;;;;N;;;;;\n2DFD;COMBINING CYRILLIC LETTER LITTLE YUS;Mn;230;NSM;;;;;N;;;;;\n2DFE;COMBINING CYRILLIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;;\n2DFF;COMBINING CYRILLIC LETTER IOTIFIED BIG YUS;Mn;230;NSM;;;;;N;;;;;\n2E00;RIGHT ANGLE SUBSTITUTION MARKER;Po;0;ON;;;;;N;;;;;\n2E01;RIGHT ANGLE DOTTED SUBSTITUTION MARKER;Po;0;ON;;;;;N;;;;;\n2E02;LEFT SUBSTITUTION BRACKET;Pi;0;ON;;;;;Y;;;;;\n2E03;RIGHT SUBSTITUTION BRACKET;Pf;0;ON;;;;;Y;;;;;\n2E04;LEFT DOTTED SUBSTITUTION BRACKET;Pi;0;ON;;;;;Y;;;;;\n2E05;RIGHT DOTTED SUBSTITUTION BRACKET;Pf;0;ON;;;;;Y;;;;;\n2E06;RAISED INTERPOLATION MARKER;Po;0;ON;;;;;N;;;;;\n2E07;RAISED DOTTED INTERPOLATION MARKER;Po;0;ON;;;;;N;;;;;\n2E08;DOTTED TRANSPOSITION MARKER;Po;0;ON;;;;;N;;;;;\n2E09;LEFT TRANSPOSITION BRACKET;Pi;0;ON;;;;;Y;;;;;\n2E0A;RIGHT TRANSPOSITION BRACKET;Pf;0;ON;;;;;Y;;;;;\n2E0B;RAISED SQUARE;Po;0;ON;;;;;N;;;;;\n2E0C;LEFT RAISED OMISSION BRACKET;Pi;0;ON;;;;;Y;;;;;\n2E0D;RIGHT RAISED OMISSION BRACKET;Pf;0;ON;;;;;Y;;;;;\n2E0E;EDITORIAL CORONIS;Po;0;ON;;;;;N;;;;;\n2E0F;PARAGRAPHOS;Po;0;ON;;;;;N;;;;;\n2E10;FORKED PARAGRAPHOS;Po;0;ON;;;;;N;;;;;\n2E11;REVERSED FORKED PARAGRAPHOS;Po;0;ON;;;;;N;;;;;\n2E12;HYPODIASTOLE;Po;0;ON;;;;;N;;;;;\n2E13;DOTTED OBELOS;Po;0;ON;;;;;N;;;;;\n2E14;DOWNWARDS ANCORA;Po;0;ON;;;;;N;;;;;\n2E15;UPWARDS ANCORA;Po;0;ON;;;;;N;;;;;\n2E16;DOTTED RIGHT-POINTING ANGLE;Po;0;ON;;;;;N;;;;;\n2E17;DOUBLE OBLIQUE HYPHEN;Pd;0;ON;;;;;N;;;;;\n2E18;INVERTED INTERROBANG;Po;0;ON;;;;;N;;;;;\n2E19;PALM BRANCH;Po;0;ON;;;;;N;;;;;\n2E1A;HYPHEN WITH DIAERESIS;Pd;0;ON;;;;;N;;;;;\n2E1B;TILDE WITH RING ABOVE;Po;0;ON;;;;;N;;;;;\n2E1C;LEFT LOW PARAPHRASE BRACKET;Pi;0;ON;;;;;Y;;;;;\n2E1D;RIGHT LOW PARAPHRASE BRACKET;Pf;0;ON;;;;;Y;;;;;\n2E1E;TILDE WITH DOT ABOVE;Po;0;ON;;;;;N;;;;;\n2E1F;TILDE WITH DOT BELOW;Po;0;ON;;;;;N;;;;;\n2E20;LEFT VERTICAL BAR WITH QUILL;Pi;0;ON;;;;;Y;;;;;\n2E21;RIGHT VERTICAL BAR WITH QUILL;Pf;0;ON;;;;;Y;;;;;\n2E22;TOP LEFT HALF BRACKET;Ps;0;ON;;;;;Y;;;;;\n2E23;TOP RIGHT HALF BRACKET;Pe;0;ON;;;;;Y;;;;;\n2E24;BOTTOM LEFT HALF BRACKET;Ps;0;ON;;;;;Y;;;;;\n2E25;BOTTOM RIGHT HALF BRACKET;Pe;0;ON;;;;;Y;;;;;\n2E26;LEFT SIDEWAYS U BRACKET;Ps;0;ON;;;;;Y;;;;;\n2E27;RIGHT SIDEWAYS U BRACKET;Pe;0;ON;;;;;Y;;;;;\n2E28;LEFT DOUBLE PARENTHESIS;Ps;0;ON;;;;;Y;;;;;\n2E29;RIGHT DOUBLE PARENTHESIS;Pe;0;ON;;;;;Y;;;;;\n2E2A;TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;\n2E2B;ONE DOT OVER TWO DOTS PUNCTUATION;Po;0;ON;;;;;N;;;;;\n2E2C;SQUARED FOUR DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;\n2E2D;FIVE DOT MARK;Po;0;ON;;;;;N;;;;;\n2E2E;REVERSED QUESTION MARK;Po;0;ON;;;;;N;;;;;\n2E2F;VERTICAL TILDE;Lm;0;ON;;;;;N;;;;;\n2E30;RING POINT;Po;0;ON;;;;;N;;;;;\n2E31;WORD SEPARATOR MIDDLE DOT;Po;0;ON;;;;;N;;;;;\n2E32;TURNED COMMA;Po;0;ON;;;;;N;;;;;\n2E33;RAISED DOT;Po;0;ON;;;;;N;;;;;\n2E34;RAISED COMMA;Po;0;ON;;;;;N;;;;;\n2E35;TURNED SEMICOLON;Po;0;ON;;;;;N;;;;;\n2E36;DAGGER WITH LEFT GUARD;Po;0;ON;;;;;N;;;;;\n2E37;DAGGER WITH RIGHT GUARD;Po;0;ON;;;;;N;;;;;\n2E38;TURNED DAGGER;Po;0;ON;;;;;N;;;;;\n2E39;TOP HALF SECTION SIGN;Po;0;ON;;;;;N;;;;;\n2E3A;TWO-EM DASH;Pd;0;ON;;;;;N;;;;;\n2E3B;THREE-EM DASH;Pd;0;ON;;;;;N;;;;;\n2E3C;STENOGRAPHIC FULL STOP;Po;0;ON;;;;;N;;;;;\n2E3D;VERTICAL SIX DOTS;Po;0;ON;;;;;N;;;;;\n2E3E;WIGGLY VERTICAL LINE;Po;0;ON;;;;;N;;;;;\n2E3F;CAPITULUM;Po;0;ON;;;;;N;;;;;\n2E40;DOUBLE HYPHEN;Pd;0;ON;;;;;N;;;;;\n2E41;REVERSED COMMA;Po;0;ON;;;;;N;;;;;\n2E42;DOUBLE LOW-REVERSED-9 QUOTATION MARK;Ps;0;ON;;;;;N;;;;;\n2E43;DASH WITH LEFT UPTURN;Po;0;ON;;;;;N;;;;;\n2E44;DOUBLE SUSPENSION MARK;Po;0;ON;;;;;N;;;;;\n2E45;INVERTED LOW KAVYKA;Po;0;ON;;;;;N;;;;;\n2E46;INVERTED LOW KAVYKA WITH KAVYKA ABOVE;Po;0;ON;;;;;N;;;;;\n2E47;LOW KAVYKA;Po;0;ON;;;;;N;;;;;\n2E48;LOW KAVYKA WITH DOT;Po;0;ON;;;;;N;;;;;\n2E49;DOUBLE STACKED COMMA;Po;0;ON;;;;;N;;;;;\n2E4A;DOTTED SOLIDUS;Po;0;ON;;;;;N;;;;;\n2E4B;TRIPLE DAGGER;Po;0;ON;;;;;N;;;;;\n2E4C;MEDIEVAL COMMA;Po;0;ON;;;;;N;;;;;\n2E4D;PARAGRAPHUS MARK;Po;0;ON;;;;;N;;;;;\n2E4E;PUNCTUS ELEVATUS MARK;Po;0;ON;;;;;N;;;;;\n2E4F;CORNISH VERSE DIVIDER;Po;0;ON;;;;;N;;;;;\n2E80;CJK RADICAL REPEAT;So;0;ON;;;;;N;;;;;\n2E81;CJK RADICAL CLIFF;So;0;ON;;;;;N;;;;;\n2E82;CJK RADICAL SECOND ONE;So;0;ON;;;;;N;;;;;\n2E83;CJK RADICAL SECOND TWO;So;0;ON;;;;;N;;;;;\n2E84;CJK RADICAL SECOND THREE;So;0;ON;;;;;N;;;;;\n2E85;CJK RADICAL PERSON;So;0;ON;;;;;N;;;;;\n2E86;CJK RADICAL BOX;So;0;ON;;;;;N;;;;;\n2E87;CJK RADICAL TABLE;So;0;ON;;;;;N;;;;;\n2E88;CJK RADICAL KNIFE ONE;So;0;ON;;;;;N;;;;;\n2E89;CJK RADICAL KNIFE TWO;So;0;ON;;;;;N;;;;;\n2E8A;CJK RADICAL DIVINATION;So;0;ON;;;;;N;;;;;\n2E8B;CJK RADICAL SEAL;So;0;ON;;;;;N;;;;;\n2E8C;CJK RADICAL SMALL ONE;So;0;ON;;;;;N;;;;;\n2E8D;CJK RADICAL SMALL TWO;So;0;ON;;;;;N;;;;;\n2E8E;CJK RADICAL LAME ONE;So;0;ON;;;;;N;;;;;\n2E8F;CJK RADICAL LAME TWO;So;0;ON;;;;;N;;;;;\n2E90;CJK RADICAL LAME THREE;So;0;ON;;;;;N;;;;;\n2E91;CJK RADICAL LAME FOUR;So;0;ON;;;;;N;;;;;\n2E92;CJK RADICAL SNAKE;So;0;ON;;;;;N;;;;;\n2E93;CJK RADICAL THREAD;So;0;ON;;;;;N;;;;;\n2E94;CJK RADICAL SNOUT ONE;So;0;ON;;;;;N;;;;;\n2E95;CJK RADICAL SNOUT TWO;So;0;ON;;;;;N;;;;;\n2E96;CJK RADICAL HEART ONE;So;0;ON;;;;;N;;;;;\n2E97;CJK RADICAL HEART TWO;So;0;ON;;;;;N;;;;;\n2E98;CJK RADICAL HAND;So;0;ON;;;;;N;;;;;\n2E99;CJK RADICAL RAP;So;0;ON;;;;;N;;;;;\n2E9B;CJK RADICAL CHOKE;So;0;ON;;;;;N;;;;;\n2E9C;CJK RADICAL SUN;So;0;ON;;;;;N;;;;;\n2E9D;CJK RADICAL MOON;So;0;ON;;;;;N;;;;;\n2E9E;CJK RADICAL DEATH;So;0;ON;;;;;N;;;;;\n2E9F;CJK RADICAL MOTHER;So;0;ON;<compat> 6BCD;;;;N;;;;;\n2EA0;CJK RADICAL CIVILIAN;So;0;ON;;;;;N;;;;;\n2EA1;CJK RADICAL WATER ONE;So;0;ON;;;;;N;;;;;\n2EA2;CJK RADICAL WATER TWO;So;0;ON;;;;;N;;;;;\n2EA3;CJK RADICAL FIRE;So;0;ON;;;;;N;;;;;\n2EA4;CJK RADICAL PAW ONE;So;0;ON;;;;;N;;;;;\n2EA5;CJK RADICAL PAW TWO;So;0;ON;;;;;N;;;;;\n2EA6;CJK RADICAL SIMPLIFIED HALF TREE TRUNK;So;0;ON;;;;;N;;;;;\n2EA7;CJK RADICAL COW;So;0;ON;;;;;N;;;;;\n2EA8;CJK RADICAL DOG;So;0;ON;;;;;N;;;;;\n2EA9;CJK RADICAL JADE;So;0;ON;;;;;N;;;;;\n2EAA;CJK RADICAL BOLT OF CLOTH;So;0;ON;;;;;N;;;;;\n2EAB;CJK RADICAL EYE;So;0;ON;;;;;N;;;;;\n2EAC;CJK RADICAL SPIRIT ONE;So;0;ON;;;;;N;;;;;\n2EAD;CJK RADICAL SPIRIT TWO;So;0;ON;;;;;N;;;;;\n2EAE;CJK RADICAL BAMBOO;So;0;ON;;;;;N;;;;;\n2EAF;CJK RADICAL SILK;So;0;ON;;;;;N;;;;;\n2EB0;CJK RADICAL C-SIMPLIFIED SILK;So;0;ON;;;;;N;;;;;\n2EB1;CJK RADICAL NET ONE;So;0;ON;;;;;N;;;;;\n2EB2;CJK RADICAL NET TWO;So;0;ON;;;;;N;;;;;\n2EB3;CJK RADICAL NET THREE;So;0;ON;;;;;N;;;;;\n2EB4;CJK RADICAL NET FOUR;So;0;ON;;;;;N;;;;;\n2EB5;CJK RADICAL MESH;So;0;ON;;;;;N;;;;;\n2EB6;CJK RADICAL SHEEP;So;0;ON;;;;;N;;;;;\n2EB7;CJK RADICAL RAM;So;0;ON;;;;;N;;;;;\n2EB8;CJK RADICAL EWE;So;0;ON;;;;;N;;;;;\n2EB9;CJK RADICAL OLD;So;0;ON;;;;;N;;;;;\n2EBA;CJK RADICAL BRUSH ONE;So;0;ON;;;;;N;;;;;\n2EBB;CJK RADICAL BRUSH TWO;So;0;ON;;;;;N;;;;;\n2EBC;CJK RADICAL MEAT;So;0;ON;;;;;N;;;;;\n2EBD;CJK RADICAL MORTAR;So;0;ON;;;;;N;;;;;\n2EBE;CJK RADICAL GRASS ONE;So;0;ON;;;;;N;;;;;\n2EBF;CJK RADICAL GRASS TWO;So;0;ON;;;;;N;;;;;\n2EC0;CJK RADICAL GRASS THREE;So;0;ON;;;;;N;;;;;\n2EC1;CJK RADICAL TIGER;So;0;ON;;;;;N;;;;;\n2EC2;CJK RADICAL CLOTHES;So;0;ON;;;;;N;;;;;\n2EC3;CJK RADICAL WEST ONE;So;0;ON;;;;;N;;;;;\n2EC4;CJK RADICAL WEST TWO;So;0;ON;;;;;N;;;;;\n2EC5;CJK RADICAL C-SIMPLIFIED SEE;So;0;ON;;;;;N;;;;;\n2EC6;CJK RADICAL SIMPLIFIED HORN;So;0;ON;;;;;N;;;;;\n2EC7;CJK RADICAL HORN;So;0;ON;;;;;N;;;;;\n2EC8;CJK RADICAL C-SIMPLIFIED SPEECH;So;0;ON;;;;;N;;;;;\n2EC9;CJK RADICAL C-SIMPLIFIED SHELL;So;0;ON;;;;;N;;;;;\n2ECA;CJK RADICAL FOOT;So;0;ON;;;;;N;;;;;\n2ECB;CJK RADICAL C-SIMPLIFIED CART;So;0;ON;;;;;N;;;;;\n2ECC;CJK RADICAL SIMPLIFIED WALK;So;0;ON;;;;;N;;;;;\n2ECD;CJK RADICAL WALK ONE;So;0;ON;;;;;N;;;;;\n2ECE;CJK RADICAL WALK TWO;So;0;ON;;;;;N;;;;;\n2ECF;CJK RADICAL CITY;So;0;ON;;;;;N;;;;;\n2ED0;CJK RADICAL C-SIMPLIFIED GOLD;So;0;ON;;;;;N;;;;;\n2ED1;CJK RADICAL LONG ONE;So;0;ON;;;;;N;;;;;\n2ED2;CJK RADICAL LONG TWO;So;0;ON;;;;;N;;;;;\n2ED3;CJK RADICAL C-SIMPLIFIED LONG;So;0;ON;;;;;N;;;;;\n2ED4;CJK RADICAL C-SIMPLIFIED GATE;So;0;ON;;;;;N;;;;;\n2ED5;CJK RADICAL MOUND ONE;So;0;ON;;;;;N;;;;;\n2ED6;CJK RADICAL MOUND TWO;So;0;ON;;;;;N;;;;;\n2ED7;CJK RADICAL RAIN;So;0;ON;;;;;N;;;;;\n2ED8;CJK RADICAL BLUE;So;0;ON;;;;;N;;;;;\n2ED9;CJK RADICAL C-SIMPLIFIED TANNED LEATHER;So;0;ON;;;;;N;;;;;\n2EDA;CJK RADICAL C-SIMPLIFIED LEAF;So;0;ON;;;;;N;;;;;\n2EDB;CJK RADICAL C-SIMPLIFIED WIND;So;0;ON;;;;;N;;;;;\n2EDC;CJK RADICAL C-SIMPLIFIED FLY;So;0;ON;;;;;N;;;;;\n2EDD;CJK RADICAL EAT ONE;So;0;ON;;;;;N;;;;;\n2EDE;CJK RADICAL EAT TWO;So;0;ON;;;;;N;;;;;\n2EDF;CJK RADICAL EAT THREE;So;0;ON;;;;;N;;;;;\n2EE0;CJK RADICAL C-SIMPLIFIED EAT;So;0;ON;;;;;N;;;;;\n2EE1;CJK RADICAL HEAD;So;0;ON;;;;;N;;;;;\n2EE2;CJK RADICAL C-SIMPLIFIED HORSE;So;0;ON;;;;;N;;;;;\n2EE3;CJK RADICAL BONE;So;0;ON;;;;;N;;;;;\n2EE4;CJK RADICAL GHOST;So;0;ON;;;;;N;;;;;\n2EE5;CJK RADICAL C-SIMPLIFIED FISH;So;0;ON;;;;;N;;;;;\n2EE6;CJK RADICAL C-SIMPLIFIED BIRD;So;0;ON;;;;;N;;;;;\n2EE7;CJK RADICAL C-SIMPLIFIED SALT;So;0;ON;;;;;N;;;;;\n2EE8;CJK RADICAL SIMPLIFIED WHEAT;So;0;ON;;;;;N;;;;;\n2EE9;CJK RADICAL SIMPLIFIED YELLOW;So;0;ON;;;;;N;;;;;\n2EEA;CJK RADICAL C-SIMPLIFIED FROG;So;0;ON;;;;;N;;;;;\n2EEB;CJK RADICAL J-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;;\n2EEC;CJK RADICAL C-SIMPLIFIED EVEN;So;0;ON;;;;;N;;;;;\n2EED;CJK RADICAL J-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;;\n2EEE;CJK RADICAL C-SIMPLIFIED TOOTH;So;0;ON;;;;;N;;;;;\n2EEF;CJK RADICAL J-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;;\n2EF0;CJK RADICAL C-SIMPLIFIED DRAGON;So;0;ON;;;;;N;;;;;\n2EF1;CJK RADICAL TURTLE;So;0;ON;;;;;N;;;;;\n2EF2;CJK RADICAL J-SIMPLIFIED TURTLE;So;0;ON;;;;;N;;;;;\n2EF3;CJK RADICAL C-SIMPLIFIED TURTLE;So;0;ON;<compat> 9F9F;;;;N;;;;;\n2F00;KANGXI RADICAL ONE;So;0;ON;<compat> 4E00;;;;N;;;;;\n2F01;KANGXI RADICAL LINE;So;0;ON;<compat> 4E28;;;;N;;;;;\n2F02;KANGXI RADICAL DOT;So;0;ON;<compat> 4E36;;;;N;;;;;\n2F03;KANGXI RADICAL SLASH;So;0;ON;<compat> 4E3F;;;;N;;;;;\n2F04;KANGXI RADICAL SECOND;So;0;ON;<compat> 4E59;;;;N;;;;;\n2F05;KANGXI RADICAL HOOK;So;0;ON;<compat> 4E85;;;;N;;;;;\n2F06;KANGXI RADICAL TWO;So;0;ON;<compat> 4E8C;;;;N;;;;;\n2F07;KANGXI RADICAL LID;So;0;ON;<compat> 4EA0;;;;N;;;;;\n2F08;KANGXI RADICAL MAN;So;0;ON;<compat> 4EBA;;;;N;;;;;\n2F09;KANGXI RADICAL LEGS;So;0;ON;<compat> 513F;;;;N;;;;;\n2F0A;KANGXI RADICAL ENTER;So;0;ON;<compat> 5165;;;;N;;;;;\n2F0B;KANGXI RADICAL EIGHT;So;0;ON;<compat> 516B;;;;N;;;;;\n2F0C;KANGXI RADICAL DOWN BOX;So;0;ON;<compat> 5182;;;;N;;;;;\n2F0D;KANGXI RADICAL COVER;So;0;ON;<compat> 5196;;;;N;;;;;\n2F0E;KANGXI RADICAL ICE;So;0;ON;<compat> 51AB;;;;N;;;;;\n2F0F;KANGXI RADICAL TABLE;So;0;ON;<compat> 51E0;;;;N;;;;;\n2F10;KANGXI RADICAL OPEN BOX;So;0;ON;<compat> 51F5;;;;N;;;;;\n2F11;KANGXI RADICAL KNIFE;So;0;ON;<compat> 5200;;;;N;;;;;\n2F12;KANGXI RADICAL POWER;So;0;ON;<compat> 529B;;;;N;;;;;\n2F13;KANGXI RADICAL WRAP;So;0;ON;<compat> 52F9;;;;N;;;;;\n2F14;KANGXI RADICAL SPOON;So;0;ON;<compat> 5315;;;;N;;;;;\n2F15;KANGXI RADICAL RIGHT OPEN BOX;So;0;ON;<compat> 531A;;;;N;;;;;\n2F16;KANGXI RADICAL HIDING ENCLOSURE;So;0;ON;<compat> 5338;;;;N;;;;;\n2F17;KANGXI RADICAL TEN;So;0;ON;<compat> 5341;;;;N;;;;;\n2F18;KANGXI RADICAL DIVINATION;So;0;ON;<compat> 535C;;;;N;;;;;\n2F19;KANGXI RADICAL SEAL;So;0;ON;<compat> 5369;;;;N;;;;;\n2F1A;KANGXI RADICAL CLIFF;So;0;ON;<compat> 5382;;;;N;;;;;\n2F1B;KANGXI RADICAL PRIVATE;So;0;ON;<compat> 53B6;;;;N;;;;;\n2F1C;KANGXI RADICAL AGAIN;So;0;ON;<compat> 53C8;;;;N;;;;;\n2F1D;KANGXI RADICAL MOUTH;So;0;ON;<compat> 53E3;;;;N;;;;;\n2F1E;KANGXI RADICAL ENCLOSURE;So;0;ON;<compat> 56D7;;;;N;;;;;\n2F1F;KANGXI RADICAL EARTH;So;0;ON;<compat> 571F;;;;N;;;;;\n2F20;KANGXI RADICAL SCHOLAR;So;0;ON;<compat> 58EB;;;;N;;;;;\n2F21;KANGXI RADICAL GO;So;0;ON;<compat> 5902;;;;N;;;;;\n2F22;KANGXI RADICAL GO SLOWLY;So;0;ON;<compat> 590A;;;;N;;;;;\n2F23;KANGXI RADICAL EVENING;So;0;ON;<compat> 5915;;;;N;;;;;\n2F24;KANGXI RADICAL BIG;So;0;ON;<compat> 5927;;;;N;;;;;\n2F25;KANGXI RADICAL WOMAN;So;0;ON;<compat> 5973;;;;N;;;;;\n2F26;KANGXI RADICAL CHILD;So;0;ON;<compat> 5B50;;;;N;;;;;\n2F27;KANGXI RADICAL ROOF;So;0;ON;<compat> 5B80;;;;N;;;;;\n2F28;KANGXI RADICAL INCH;So;0;ON;<compat> 5BF8;;;;N;;;;;\n2F29;KANGXI RADICAL SMALL;So;0;ON;<compat> 5C0F;;;;N;;;;;\n2F2A;KANGXI RADICAL LAME;So;0;ON;<compat> 5C22;;;;N;;;;;\n2F2B;KANGXI RADICAL CORPSE;So;0;ON;<compat> 5C38;;;;N;;;;;\n2F2C;KANGXI RADICAL SPROUT;So;0;ON;<compat> 5C6E;;;;N;;;;;\n2F2D;KANGXI RADICAL MOUNTAIN;So;0;ON;<compat> 5C71;;;;N;;;;;\n2F2E;KANGXI RADICAL RIVER;So;0;ON;<compat> 5DDB;;;;N;;;;;\n2F2F;KANGXI RADICAL WORK;So;0;ON;<compat> 5DE5;;;;N;;;;;\n2F30;KANGXI RADICAL ONESELF;So;0;ON;<compat> 5DF1;;;;N;;;;;\n2F31;KANGXI RADICAL TURBAN;So;0;ON;<compat> 5DFE;;;;N;;;;;\n2F32;KANGXI RADICAL DRY;So;0;ON;<compat> 5E72;;;;N;;;;;\n2F33;KANGXI RADICAL SHORT THREAD;So;0;ON;<compat> 5E7A;;;;N;;;;;\n2F34;KANGXI RADICAL DOTTED CLIFF;So;0;ON;<compat> 5E7F;;;;N;;;;;\n2F35;KANGXI RADICAL LONG STRIDE;So;0;ON;<compat> 5EF4;;;;N;;;;;\n2F36;KANGXI RADICAL TWO HANDS;So;0;ON;<compat> 5EFE;;;;N;;;;;\n2F37;KANGXI RADICAL SHOOT;So;0;ON;<compat> 5F0B;;;;N;;;;;\n2F38;KANGXI RADICAL BOW;So;0;ON;<compat> 5F13;;;;N;;;;;\n2F39;KANGXI RADICAL SNOUT;So;0;ON;<compat> 5F50;;;;N;;;;;\n2F3A;KANGXI RADICAL BRISTLE;So;0;ON;<compat> 5F61;;;;N;;;;;\n2F3B;KANGXI RADICAL STEP;So;0;ON;<compat> 5F73;;;;N;;;;;\n2F3C;KANGXI RADICAL HEART;So;0;ON;<compat> 5FC3;;;;N;;;;;\n2F3D;KANGXI RADICAL HALBERD;So;0;ON;<compat> 6208;;;;N;;;;;\n2F3E;KANGXI RADICAL DOOR;So;0;ON;<compat> 6236;;;;N;;;;;\n2F3F;KANGXI RADICAL HAND;So;0;ON;<compat> 624B;;;;N;;;;;\n2F40;KANGXI RADICAL BRANCH;So;0;ON;<compat> 652F;;;;N;;;;;\n2F41;KANGXI RADICAL RAP;So;0;ON;<compat> 6534;;;;N;;;;;\n2F42;KANGXI RADICAL SCRIPT;So;0;ON;<compat> 6587;;;;N;;;;;\n2F43;KANGXI RADICAL DIPPER;So;0;ON;<compat> 6597;;;;N;;;;;\n2F44;KANGXI RADICAL AXE;So;0;ON;<compat> 65A4;;;;N;;;;;\n2F45;KANGXI RADICAL SQUARE;So;0;ON;<compat> 65B9;;;;N;;;;;\n2F46;KANGXI RADICAL NOT;So;0;ON;<compat> 65E0;;;;N;;;;;\n2F47;KANGXI RADICAL SUN;So;0;ON;<compat> 65E5;;;;N;;;;;\n2F48;KANGXI RADICAL SAY;So;0;ON;<compat> 66F0;;;;N;;;;;\n2F49;KANGXI RADICAL MOON;So;0;ON;<compat> 6708;;;;N;;;;;\n2F4A;KANGXI RADICAL TREE;So;0;ON;<compat> 6728;;;;N;;;;;\n2F4B;KANGXI RADICAL LACK;So;0;ON;<compat> 6B20;;;;N;;;;;\n2F4C;KANGXI RADICAL STOP;So;0;ON;<compat> 6B62;;;;N;;;;;\n2F4D;KANGXI RADICAL DEATH;So;0;ON;<compat> 6B79;;;;N;;;;;\n2F4E;KANGXI RADICAL WEAPON;So;0;ON;<compat> 6BB3;;;;N;;;;;\n2F4F;KANGXI RADICAL DO NOT;So;0;ON;<compat> 6BCB;;;;N;;;;;\n2F50;KANGXI RADICAL COMPARE;So;0;ON;<compat> 6BD4;;;;N;;;;;\n2F51;KANGXI RADICAL FUR;So;0;ON;<compat> 6BDB;;;;N;;;;;\n2F52;KANGXI RADICAL CLAN;So;0;ON;<compat> 6C0F;;;;N;;;;;\n2F53;KANGXI RADICAL STEAM;So;0;ON;<compat> 6C14;;;;N;;;;;\n2F54;KANGXI RADICAL WATER;So;0;ON;<compat> 6C34;;;;N;;;;;\n2F55;KANGXI RADICAL FIRE;So;0;ON;<compat> 706B;;;;N;;;;;\n2F56;KANGXI RADICAL CLAW;So;0;ON;<compat> 722A;;;;N;;;;;\n2F57;KANGXI RADICAL FATHER;So;0;ON;<compat> 7236;;;;N;;;;;\n2F58;KANGXI RADICAL DOUBLE X;So;0;ON;<compat> 723B;;;;N;;;;;\n2F59;KANGXI RADICAL HALF TREE TRUNK;So;0;ON;<compat> 723F;;;;N;;;;;\n2F5A;KANGXI RADICAL SLICE;So;0;ON;<compat> 7247;;;;N;;;;;\n2F5B;KANGXI RADICAL FANG;So;0;ON;<compat> 7259;;;;N;;;;;\n2F5C;KANGXI RADICAL COW;So;0;ON;<compat> 725B;;;;N;;;;;\n2F5D;KANGXI RADICAL DOG;So;0;ON;<compat> 72AC;;;;N;;;;;\n2F5E;KANGXI RADICAL PROFOUND;So;0;ON;<compat> 7384;;;;N;;;;;\n2F5F;KANGXI RADICAL JADE;So;0;ON;<compat> 7389;;;;N;;;;;\n2F60;KANGXI RADICAL MELON;So;0;ON;<compat> 74DC;;;;N;;;;;\n2F61;KANGXI RADICAL TILE;So;0;ON;<compat> 74E6;;;;N;;;;;\n2F62;KANGXI RADICAL SWEET;So;0;ON;<compat> 7518;;;;N;;;;;\n2F63;KANGXI RADICAL LIFE;So;0;ON;<compat> 751F;;;;N;;;;;\n2F64;KANGXI RADICAL USE;So;0;ON;<compat> 7528;;;;N;;;;;\n2F65;KANGXI RADICAL FIELD;So;0;ON;<compat> 7530;;;;N;;;;;\n2F66;KANGXI RADICAL BOLT OF CLOTH;So;0;ON;<compat> 758B;;;;N;;;;;\n2F67;KANGXI RADICAL SICKNESS;So;0;ON;<compat> 7592;;;;N;;;;;\n2F68;KANGXI RADICAL DOTTED TENT;So;0;ON;<compat> 7676;;;;N;;;;;\n2F69;KANGXI RADICAL WHITE;So;0;ON;<compat> 767D;;;;N;;;;;\n2F6A;KANGXI RADICAL SKIN;So;0;ON;<compat> 76AE;;;;N;;;;;\n2F6B;KANGXI RADICAL DISH;So;0;ON;<compat> 76BF;;;;N;;;;;\n2F6C;KANGXI RADICAL EYE;So;0;ON;<compat> 76EE;;;;N;;;;;\n2F6D;KANGXI RADICAL SPEAR;So;0;ON;<compat> 77DB;;;;N;;;;;\n2F6E;KANGXI RADICAL ARROW;So;0;ON;<compat> 77E2;;;;N;;;;;\n2F6F;KANGXI RADICAL STONE;So;0;ON;<compat> 77F3;;;;N;;;;;\n2F70;KANGXI RADICAL SPIRIT;So;0;ON;<compat> 793A;;;;N;;;;;\n2F71;KANGXI RADICAL TRACK;So;0;ON;<compat> 79B8;;;;N;;;;;\n2F72;KANGXI RADICAL GRAIN;So;0;ON;<compat> 79BE;;;;N;;;;;\n2F73;KANGXI RADICAL CAVE;So;0;ON;<compat> 7A74;;;;N;;;;;\n2F74;KANGXI RADICAL STAND;So;0;ON;<compat> 7ACB;;;;N;;;;;\n2F75;KANGXI RADICAL BAMBOO;So;0;ON;<compat> 7AF9;;;;N;;;;;\n2F76;KANGXI RADICAL RICE;So;0;ON;<compat> 7C73;;;;N;;;;;\n2F77;KANGXI RADICAL SILK;So;0;ON;<compat> 7CF8;;;;N;;;;;\n2F78;KANGXI RADICAL JAR;So;0;ON;<compat> 7F36;;;;N;;;;;\n2F79;KANGXI RADICAL NET;So;0;ON;<compat> 7F51;;;;N;;;;;\n2F7A;KANGXI RADICAL SHEEP;So;0;ON;<compat> 7F8A;;;;N;;;;;\n2F7B;KANGXI RADICAL FEATHER;So;0;ON;<compat> 7FBD;;;;N;;;;;\n2F7C;KANGXI RADICAL OLD;So;0;ON;<compat> 8001;;;;N;;;;;\n2F7D;KANGXI RADICAL AND;So;0;ON;<compat> 800C;;;;N;;;;;\n2F7E;KANGXI RADICAL PLOW;So;0;ON;<compat> 8012;;;;N;;;;;\n2F7F;KANGXI RADICAL EAR;So;0;ON;<compat> 8033;;;;N;;;;;\n2F80;KANGXI RADICAL BRUSH;So;0;ON;<compat> 807F;;;;N;;;;;\n2F81;KANGXI RADICAL MEAT;So;0;ON;<compat> 8089;;;;N;;;;;\n2F82;KANGXI RADICAL MINISTER;So;0;ON;<compat> 81E3;;;;N;;;;;\n2F83;KANGXI RADICAL SELF;So;0;ON;<compat> 81EA;;;;N;;;;;\n2F84;KANGXI RADICAL ARRIVE;So;0;ON;<compat> 81F3;;;;N;;;;;\n2F85;KANGXI RADICAL MORTAR;So;0;ON;<compat> 81FC;;;;N;;;;;\n2F86;KANGXI RADICAL TONGUE;So;0;ON;<compat> 820C;;;;N;;;;;\n2F87;KANGXI RADICAL OPPOSE;So;0;ON;<compat> 821B;;;;N;;;;;\n2F88;KANGXI RADICAL BOAT;So;0;ON;<compat> 821F;;;;N;;;;;\n2F89;KANGXI RADICAL STOPPING;So;0;ON;<compat> 826E;;;;N;;;;;\n2F8A;KANGXI RADICAL COLOR;So;0;ON;<compat> 8272;;;;N;;;;;\n2F8B;KANGXI RADICAL GRASS;So;0;ON;<compat> 8278;;;;N;;;;;\n2F8C;KANGXI RADICAL TIGER;So;0;ON;<compat> 864D;;;;N;;;;;\n2F8D;KANGXI RADICAL INSECT;So;0;ON;<compat> 866B;;;;N;;;;;\n2F8E;KANGXI RADICAL BLOOD;So;0;ON;<compat> 8840;;;;N;;;;;\n2F8F;KANGXI RADICAL WALK ENCLOSURE;So;0;ON;<compat> 884C;;;;N;;;;;\n2F90;KANGXI RADICAL CLOTHES;So;0;ON;<compat> 8863;;;;N;;;;;\n2F91;KANGXI RADICAL WEST;So;0;ON;<compat> 897E;;;;N;;;;;\n2F92;KANGXI RADICAL SEE;So;0;ON;<compat> 898B;;;;N;;;;;\n2F93;KANGXI RADICAL HORN;So;0;ON;<compat> 89D2;;;;N;;;;;\n2F94;KANGXI RADICAL SPEECH;So;0;ON;<compat> 8A00;;;;N;;;;;\n2F95;KANGXI RADICAL VALLEY;So;0;ON;<compat> 8C37;;;;N;;;;;\n2F96;KANGXI RADICAL BEAN;So;0;ON;<compat> 8C46;;;;N;;;;;\n2F97;KANGXI RADICAL PIG;So;0;ON;<compat> 8C55;;;;N;;;;;\n2F98;KANGXI RADICAL BADGER;So;0;ON;<compat> 8C78;;;;N;;;;;\n2F99;KANGXI RADICAL SHELL;So;0;ON;<compat> 8C9D;;;;N;;;;;\n2F9A;KANGXI RADICAL RED;So;0;ON;<compat> 8D64;;;;N;;;;;\n2F9B;KANGXI RADICAL RUN;So;0;ON;<compat> 8D70;;;;N;;;;;\n2F9C;KANGXI RADICAL FOOT;So;0;ON;<compat> 8DB3;;;;N;;;;;\n2F9D;KANGXI RADICAL BODY;So;0;ON;<compat> 8EAB;;;;N;;;;;\n2F9E;KANGXI RADICAL CART;So;0;ON;<compat> 8ECA;;;;N;;;;;\n2F9F;KANGXI RADICAL BITTER;So;0;ON;<compat> 8F9B;;;;N;;;;;\n2FA0;KANGXI RADICAL MORNING;So;0;ON;<compat> 8FB0;;;;N;;;;;\n2FA1;KANGXI RADICAL WALK;So;0;ON;<compat> 8FB5;;;;N;;;;;\n2FA2;KANGXI RADICAL CITY;So;0;ON;<compat> 9091;;;;N;;;;;\n2FA3;KANGXI RADICAL WINE;So;0;ON;<compat> 9149;;;;N;;;;;\n2FA4;KANGXI RADICAL DISTINGUISH;So;0;ON;<compat> 91C6;;;;N;;;;;\n2FA5;KANGXI RADICAL VILLAGE;So;0;ON;<compat> 91CC;;;;N;;;;;\n2FA6;KANGXI RADICAL GOLD;So;0;ON;<compat> 91D1;;;;N;;;;;\n2FA7;KANGXI RADICAL LONG;So;0;ON;<compat> 9577;;;;N;;;;;\n2FA8;KANGXI RADICAL GATE;So;0;ON;<compat> 9580;;;;N;;;;;\n2FA9;KANGXI RADICAL MOUND;So;0;ON;<compat> 961C;;;;N;;;;;\n2FAA;KANGXI RADICAL SLAVE;So;0;ON;<compat> 96B6;;;;N;;;;;\n2FAB;KANGXI RADICAL SHORT TAILED BIRD;So;0;ON;<compat> 96B9;;;;N;;;;;\n2FAC;KANGXI RADICAL RAIN;So;0;ON;<compat> 96E8;;;;N;;;;;\n2FAD;KANGXI RADICAL BLUE;So;0;ON;<compat> 9751;;;;N;;;;;\n2FAE;KANGXI RADICAL WRONG;So;0;ON;<compat> 975E;;;;N;;;;;\n2FAF;KANGXI RADICAL FACE;So;0;ON;<compat> 9762;;;;N;;;;;\n2FB0;KANGXI RADICAL LEATHER;So;0;ON;<compat> 9769;;;;N;;;;;\n2FB1;KANGXI RADICAL TANNED LEATHER;So;0;ON;<compat> 97CB;;;;N;;;;;\n2FB2;KANGXI RADICAL LEEK;So;0;ON;<compat> 97ED;;;;N;;;;;\n2FB3;KANGXI RADICAL SOUND;So;0;ON;<compat> 97F3;;;;N;;;;;\n2FB4;KANGXI RADICAL LEAF;So;0;ON;<compat> 9801;;;;N;;;;;\n2FB5;KANGXI RADICAL WIND;So;0;ON;<compat> 98A8;;;;N;;;;;\n2FB6;KANGXI RADICAL FLY;So;0;ON;<compat> 98DB;;;;N;;;;;\n2FB7;KANGXI RADICAL EAT;So;0;ON;<compat> 98DF;;;;N;;;;;\n2FB8;KANGXI RADICAL HEAD;So;0;ON;<compat> 9996;;;;N;;;;;\n2FB9;KANGXI RADICAL FRAGRANT;So;0;ON;<compat> 9999;;;;N;;;;;\n2FBA;KANGXI RADICAL HORSE;So;0;ON;<compat> 99AC;;;;N;;;;;\n2FBB;KANGXI RADICAL BONE;So;0;ON;<compat> 9AA8;;;;N;;;;;\n2FBC;KANGXI RADICAL TALL;So;0;ON;<compat> 9AD8;;;;N;;;;;\n2FBD;KANGXI RADICAL HAIR;So;0;ON;<compat> 9ADF;;;;N;;;;;\n2FBE;KANGXI RADICAL FIGHT;So;0;ON;<compat> 9B25;;;;N;;;;;\n2FBF;KANGXI RADICAL SACRIFICIAL WINE;So;0;ON;<compat> 9B2F;;;;N;;;;;\n2FC0;KANGXI RADICAL CAULDRON;So;0;ON;<compat> 9B32;;;;N;;;;;\n2FC1;KANGXI RADICAL GHOST;So;0;ON;<compat> 9B3C;;;;N;;;;;\n2FC2;KANGXI RADICAL FISH;So;0;ON;<compat> 9B5A;;;;N;;;;;\n2FC3;KANGXI RADICAL BIRD;So;0;ON;<compat> 9CE5;;;;N;;;;;\n2FC4;KANGXI RADICAL SALT;So;0;ON;<compat> 9E75;;;;N;;;;;\n2FC5;KANGXI RADICAL DEER;So;0;ON;<compat> 9E7F;;;;N;;;;;\n2FC6;KANGXI RADICAL WHEAT;So;0;ON;<compat> 9EA5;;;;N;;;;;\n2FC7;KANGXI RADICAL HEMP;So;0;ON;<compat> 9EBB;;;;N;;;;;\n2FC8;KANGXI RADICAL YELLOW;So;0;ON;<compat> 9EC3;;;;N;;;;;\n2FC9;KANGXI RADICAL MILLET;So;0;ON;<compat> 9ECD;;;;N;;;;;\n2FCA;KANGXI RADICAL BLACK;So;0;ON;<compat> 9ED1;;;;N;;;;;\n2FCB;KANGXI RADICAL EMBROIDERY;So;0;ON;<compat> 9EF9;;;;N;;;;;\n2FCC;KANGXI RADICAL FROG;So;0;ON;<compat> 9EFD;;;;N;;;;;\n2FCD;KANGXI RADICAL TRIPOD;So;0;ON;<compat> 9F0E;;;;N;;;;;\n2FCE;KANGXI RADICAL DRUM;So;0;ON;<compat> 9F13;;;;N;;;;;\n2FCF;KANGXI RADICAL RAT;So;0;ON;<compat> 9F20;;;;N;;;;;\n2FD0;KANGXI RADICAL NOSE;So;0;ON;<compat> 9F3B;;;;N;;;;;\n2FD1;KANGXI RADICAL EVEN;So;0;ON;<compat> 9F4A;;;;N;;;;;\n2FD2;KANGXI RADICAL TOOTH;So;0;ON;<compat> 9F52;;;;N;;;;;\n2FD3;KANGXI RADICAL DRAGON;So;0;ON;<compat> 9F8D;;;;N;;;;;\n2FD4;KANGXI RADICAL TURTLE;So;0;ON;<compat> 9F9C;;;;N;;;;;\n2FD5;KANGXI RADICAL FLUTE;So;0;ON;<compat> 9FA0;;;;N;;;;;\n2FF0;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT;So;0;ON;;;;;N;;;;;\n2FF1;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW;So;0;ON;;;;;N;;;;;\n2FF2;IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT;So;0;ON;;;;;N;;;;;\n2FF3;IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW;So;0;ON;;;;;N;;;;;\n2FF4;IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND;So;0;ON;;;;;N;;;;;\n2FF5;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE;So;0;ON;;;;;N;;;;;\n2FF6;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW;So;0;ON;;;;;N;;;;;\n2FF7;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT;So;0;ON;;;;;N;;;;;\n2FF8;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT;So;0;ON;;;;;N;;;;;\n2FF9;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT;So;0;ON;;;;;N;;;;;\n2FFA;IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT;So;0;ON;;;;;N;;;;;\n2FFB;IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID;So;0;ON;;;;;N;;;;;\n3000;IDEOGRAPHIC SPACE;Zs;0;WS;<wide> 0020;;;;N;;;;;\n3001;IDEOGRAPHIC COMMA;Po;0;ON;;;;;N;;;;;\n3002;IDEOGRAPHIC FULL STOP;Po;0;ON;;;;;N;IDEOGRAPHIC PERIOD;;;;\n3003;DITTO MARK;Po;0;ON;;;;;N;;;;;\n3004;JAPANESE INDUSTRIAL STANDARD SYMBOL;So;0;ON;;;;;N;;;;;\n3005;IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;;\n3006;IDEOGRAPHIC CLOSING MARK;Lo;0;L;;;;;N;;;;;\n3007;IDEOGRAPHIC NUMBER ZERO;Nl;0;L;;;;0;N;;;;;\n3008;LEFT ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING ANGLE BRACKET;;;;\n3009;RIGHT ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING ANGLE BRACKET;;;;\n300A;LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;;;;;Y;OPENING DOUBLE ANGLE BRACKET;;;;\n300B;RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;;;;;Y;CLOSING DOUBLE ANGLE BRACKET;;;;\n300C;LEFT CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING CORNER BRACKET;;;;\n300D;RIGHT CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING CORNER BRACKET;;;;\n300E;LEFT WHITE CORNER BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE CORNER BRACKET;;;;\n300F;RIGHT WHITE CORNER BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE CORNER BRACKET;;;;\n3010;LEFT BLACK LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING BLACK LENTICULAR BRACKET;;;;\n3011;RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING BLACK LENTICULAR BRACKET;;;;\n3012;POSTAL MARK;So;0;ON;;;;;N;;;;;\n3013;GETA MARK;So;0;ON;;;;;N;;;;;\n3014;LEFT TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING TORTOISE SHELL BRACKET;;;;\n3015;RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING TORTOISE SHELL BRACKET;;;;\n3016;LEFT WHITE LENTICULAR BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE LENTICULAR BRACKET;;;;\n3017;RIGHT WHITE LENTICULAR BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE LENTICULAR BRACKET;;;;\n3018;LEFT WHITE TORTOISE SHELL BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE TORTOISE SHELL BRACKET;;;;\n3019;RIGHT WHITE TORTOISE SHELL BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE TORTOISE SHELL BRACKET;;;;\n301A;LEFT WHITE SQUARE BRACKET;Ps;0;ON;;;;;Y;OPENING WHITE SQUARE BRACKET;;;;\n301B;RIGHT WHITE SQUARE BRACKET;Pe;0;ON;;;;;Y;CLOSING WHITE SQUARE BRACKET;;;;\n301C;WAVE DASH;Pd;0;ON;;;;;N;;;;;\n301D;REVERSED DOUBLE PRIME QUOTATION MARK;Ps;0;ON;;;;;N;;;;;\n301E;DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;;\n301F;LOW DOUBLE PRIME QUOTATION MARK;Pe;0;ON;;;;;N;;;;;\n3020;POSTAL MARK FACE;So;0;ON;;;;;N;;;;;\n3021;HANGZHOU NUMERAL ONE;Nl;0;L;;;;1;N;;;;;\n3022;HANGZHOU NUMERAL TWO;Nl;0;L;;;;2;N;;;;;\n3023;HANGZHOU NUMERAL THREE;Nl;0;L;;;;3;N;;;;;\n3024;HANGZHOU NUMERAL FOUR;Nl;0;L;;;;4;N;;;;;\n3025;HANGZHOU NUMERAL FIVE;Nl;0;L;;;;5;N;;;;;\n3026;HANGZHOU NUMERAL SIX;Nl;0;L;;;;6;N;;;;;\n3027;HANGZHOU NUMERAL SEVEN;Nl;0;L;;;;7;N;;;;;\n3028;HANGZHOU NUMERAL EIGHT;Nl;0;L;;;;8;N;;;;;\n3029;HANGZHOU NUMERAL NINE;Nl;0;L;;;;9;N;;;;;\n302A;IDEOGRAPHIC LEVEL TONE MARK;Mn;218;NSM;;;;;N;;;;;\n302B;IDEOGRAPHIC RISING TONE MARK;Mn;228;NSM;;;;;N;;;;;\n302C;IDEOGRAPHIC DEPARTING TONE MARK;Mn;232;NSM;;;;;N;;;;;\n302D;IDEOGRAPHIC ENTERING TONE MARK;Mn;222;NSM;;;;;N;;;;;\n302E;HANGUL SINGLE DOT TONE MARK;Mc;224;L;;;;;N;;;;;\n302F;HANGUL DOUBLE DOT TONE MARK;Mc;224;L;;;;;N;;;;;\n3030;WAVY DASH;Pd;0;ON;;;;;N;;;;;\n3031;VERTICAL KANA REPEAT MARK;Lm;0;L;;;;;N;;;;;\n3032;VERTICAL KANA REPEAT WITH VOICED SOUND MARK;Lm;0;L;;;;;N;;;;;\n3033;VERTICAL KANA REPEAT MARK UPPER HALF;Lm;0;L;;;;;N;;;;;\n3034;VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF;Lm;0;L;;;;;N;;;;;\n3035;VERTICAL KANA REPEAT MARK LOWER HALF;Lm;0;L;;;;;N;;;;;\n3036;CIRCLED POSTAL MARK;So;0;ON;<compat> 3012;;;;N;;;;;\n3037;IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL;So;0;ON;;;;;N;;;;;\n3038;HANGZHOU NUMERAL TEN;Nl;0;L;<compat> 5341;;;10;N;;;;;\n3039;HANGZHOU NUMERAL TWENTY;Nl;0;L;<compat> 5344;;;20;N;;;;;\n303A;HANGZHOU NUMERAL THIRTY;Nl;0;L;<compat> 5345;;;30;N;;;;;\n303B;VERTICAL IDEOGRAPHIC ITERATION MARK;Lm;0;L;;;;;N;;;;;\n303C;MASU MARK;Lo;0;L;;;;;N;;;;;\n303D;PART ALTERNATION MARK;Po;0;ON;;;;;N;;;;;\n303E;IDEOGRAPHIC VARIATION INDICATOR;So;0;ON;;;;;N;;;;;\n303F;IDEOGRAPHIC HALF FILL SPACE;So;0;ON;;;;;N;;;;;\n3041;HIRAGANA LETTER SMALL A;Lo;0;L;;;;;N;;;;;\n3042;HIRAGANA LETTER A;Lo;0;L;;;;;N;;;;;\n3043;HIRAGANA LETTER SMALL I;Lo;0;L;;;;;N;;;;;\n3044;HIRAGANA LETTER I;Lo;0;L;;;;;N;;;;;\n3045;HIRAGANA LETTER SMALL U;Lo;0;L;;;;;N;;;;;\n3046;HIRAGANA LETTER U;Lo;0;L;;;;;N;;;;;\n3047;HIRAGANA LETTER SMALL E;Lo;0;L;;;;;N;;;;;\n3048;HIRAGANA LETTER E;Lo;0;L;;;;;N;;;;;\n3049;HIRAGANA LETTER SMALL O;Lo;0;L;;;;;N;;;;;\n304A;HIRAGANA LETTER O;Lo;0;L;;;;;N;;;;;\n304B;HIRAGANA LETTER KA;Lo;0;L;;;;;N;;;;;\n304C;HIRAGANA LETTER GA;Lo;0;L;304B 3099;;;;N;;;;;\n304D;HIRAGANA LETTER KI;Lo;0;L;;;;;N;;;;;\n304E;HIRAGANA LETTER GI;Lo;0;L;304D 3099;;;;N;;;;;\n304F;HIRAGANA LETTER KU;Lo;0;L;;;;;N;;;;;\n3050;HIRAGANA LETTER GU;Lo;0;L;304F 3099;;;;N;;;;;\n3051;HIRAGANA LETTER KE;Lo;0;L;;;;;N;;;;;\n3052;HIRAGANA LETTER GE;Lo;0;L;3051 3099;;;;N;;;;;\n3053;HIRAGANA LETTER KO;Lo;0;L;;;;;N;;;;;\n3054;HIRAGANA LETTER GO;Lo;0;L;3053 3099;;;;N;;;;;\n3055;HIRAGANA LETTER SA;Lo;0;L;;;;;N;;;;;\n3056;HIRAGANA LETTER ZA;Lo;0;L;3055 3099;;;;N;;;;;\n3057;HIRAGANA LETTER SI;Lo;0;L;;;;;N;;;;;\n3058;HIRAGANA LETTER ZI;Lo;0;L;3057 3099;;;;N;;;;;\n3059;HIRAGANA LETTER SU;Lo;0;L;;;;;N;;;;;\n305A;HIRAGANA LETTER ZU;Lo;0;L;3059 3099;;;;N;;;;;\n305B;HIRAGANA LETTER SE;Lo;0;L;;;;;N;;;;;\n305C;HIRAGANA LETTER ZE;Lo;0;L;305B 3099;;;;N;;;;;\n305D;HIRAGANA LETTER SO;Lo;0;L;;;;;N;;;;;\n305E;HIRAGANA LETTER ZO;Lo;0;L;305D 3099;;;;N;;;;;\n305F;HIRAGANA LETTER TA;Lo;0;L;;;;;N;;;;;\n3060;HIRAGANA LETTER DA;Lo;0;L;305F 3099;;;;N;;;;;\n3061;HIRAGANA LETTER TI;Lo;0;L;;;;;N;;;;;\n3062;HIRAGANA LETTER DI;Lo;0;L;3061 3099;;;;N;;;;;\n3063;HIRAGANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;;\n3064;HIRAGANA LETTER TU;Lo;0;L;;;;;N;;;;;\n3065;HIRAGANA LETTER DU;Lo;0;L;3064 3099;;;;N;;;;;\n3066;HIRAGANA LETTER TE;Lo;0;L;;;;;N;;;;;\n3067;HIRAGANA LETTER DE;Lo;0;L;3066 3099;;;;N;;;;;\n3068;HIRAGANA LETTER TO;Lo;0;L;;;;;N;;;;;\n3069;HIRAGANA LETTER DO;Lo;0;L;3068 3099;;;;N;;;;;\n306A;HIRAGANA LETTER NA;Lo;0;L;;;;;N;;;;;\n306B;HIRAGANA LETTER NI;Lo;0;L;;;;;N;;;;;\n306C;HIRAGANA LETTER NU;Lo;0;L;;;;;N;;;;;\n306D;HIRAGANA LETTER NE;Lo;0;L;;;;;N;;;;;\n306E;HIRAGANA LETTER NO;Lo;0;L;;;;;N;;;;;\n306F;HIRAGANA LETTER HA;Lo;0;L;;;;;N;;;;;\n3070;HIRAGANA LETTER BA;Lo;0;L;306F 3099;;;;N;;;;;\n3071;HIRAGANA LETTER PA;Lo;0;L;306F 309A;;;;N;;;;;\n3072;HIRAGANA LETTER HI;Lo;0;L;;;;;N;;;;;\n3073;HIRAGANA LETTER BI;Lo;0;L;3072 3099;;;;N;;;;;\n3074;HIRAGANA LETTER PI;Lo;0;L;3072 309A;;;;N;;;;;\n3075;HIRAGANA LETTER HU;Lo;0;L;;;;;N;;;;;\n3076;HIRAGANA LETTER BU;Lo;0;L;3075 3099;;;;N;;;;;\n3077;HIRAGANA LETTER PU;Lo;0;L;3075 309A;;;;N;;;;;\n3078;HIRAGANA LETTER HE;Lo;0;L;;;;;N;;;;;\n3079;HIRAGANA LETTER BE;Lo;0;L;3078 3099;;;;N;;;;;\n307A;HIRAGANA LETTER PE;Lo;0;L;3078 309A;;;;N;;;;;\n307B;HIRAGANA LETTER HO;Lo;0;L;;;;;N;;;;;\n307C;HIRAGANA LETTER BO;Lo;0;L;307B 3099;;;;N;;;;;\n307D;HIRAGANA LETTER PO;Lo;0;L;307B 309A;;;;N;;;;;\n307E;HIRAGANA LETTER MA;Lo;0;L;;;;;N;;;;;\n307F;HIRAGANA LETTER MI;Lo;0;L;;;;;N;;;;;\n3080;HIRAGANA LETTER MU;Lo;0;L;;;;;N;;;;;\n3081;HIRAGANA LETTER ME;Lo;0;L;;;;;N;;;;;\n3082;HIRAGANA LETTER MO;Lo;0;L;;;;;N;;;;;\n3083;HIRAGANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;;\n3084;HIRAGANA LETTER YA;Lo;0;L;;;;;N;;;;;\n3085;HIRAGANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;;\n3086;HIRAGANA LETTER YU;Lo;0;L;;;;;N;;;;;\n3087;HIRAGANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;;\n3088;HIRAGANA LETTER YO;Lo;0;L;;;;;N;;;;;\n3089;HIRAGANA LETTER RA;Lo;0;L;;;;;N;;;;;\n308A;HIRAGANA LETTER RI;Lo;0;L;;;;;N;;;;;\n308B;HIRAGANA LETTER RU;Lo;0;L;;;;;N;;;;;\n308C;HIRAGANA LETTER RE;Lo;0;L;;;;;N;;;;;\n308D;HIRAGANA LETTER RO;Lo;0;L;;;;;N;;;;;\n308E;HIRAGANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;;\n308F;HIRAGANA LETTER WA;Lo;0;L;;;;;N;;;;;\n3090;HIRAGANA LETTER WI;Lo;0;L;;;;;N;;;;;\n3091;HIRAGANA LETTER WE;Lo;0;L;;;;;N;;;;;\n3092;HIRAGANA LETTER WO;Lo;0;L;;;;;N;;;;;\n3093;HIRAGANA LETTER N;Lo;0;L;;;;;N;;;;;\n3094;HIRAGANA LETTER VU;Lo;0;L;3046 3099;;;;N;;;;;\n3095;HIRAGANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;;\n3096;HIRAGANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;;\n3099;COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA VOICED SOUND MARK;;;;\n309A;COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Mn;8;NSM;;;;;N;NON-SPACING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;;;;\n309B;KATAKANA-HIRAGANA VOICED SOUND MARK;Sk;0;ON;<compat> 0020 3099;;;;N;;;;;\n309C;KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK;Sk;0;ON;<compat> 0020 309A;;;;N;;;;;\n309D;HIRAGANA ITERATION MARK;Lm;0;L;;;;;N;;;;;\n309E;HIRAGANA VOICED ITERATION MARK;Lm;0;L;309D 3099;;;;N;;;;;\n309F;HIRAGANA DIGRAPH YORI;Lo;0;L;<vertical> 3088 308A;;;;N;;;;;\n30A0;KATAKANA-HIRAGANA DOUBLE HYPHEN;Pd;0;ON;;;;;N;;;;;\n30A1;KATAKANA LETTER SMALL A;Lo;0;L;;;;;N;;;;;\n30A2;KATAKANA LETTER A;Lo;0;L;;;;;N;;;;;\n30A3;KATAKANA LETTER SMALL I;Lo;0;L;;;;;N;;;;;\n30A4;KATAKANA LETTER I;Lo;0;L;;;;;N;;;;;\n30A5;KATAKANA LETTER SMALL U;Lo;0;L;;;;;N;;;;;\n30A6;KATAKANA LETTER U;Lo;0;L;;;;;N;;;;;\n30A7;KATAKANA LETTER SMALL E;Lo;0;L;;;;;N;;;;;\n30A8;KATAKANA LETTER E;Lo;0;L;;;;;N;;;;;\n30A9;KATAKANA LETTER SMALL O;Lo;0;L;;;;;N;;;;;\n30AA;KATAKANA LETTER O;Lo;0;L;;;;;N;;;;;\n30AB;KATAKANA LETTER KA;Lo;0;L;;;;;N;;;;;\n30AC;KATAKANA LETTER GA;Lo;0;L;30AB 3099;;;;N;;;;;\n30AD;KATAKANA LETTER KI;Lo;0;L;;;;;N;;;;;\n30AE;KATAKANA LETTER GI;Lo;0;L;30AD 3099;;;;N;;;;;\n30AF;KATAKANA LETTER KU;Lo;0;L;;;;;N;;;;;\n30B0;KATAKANA LETTER GU;Lo;0;L;30AF 3099;;;;N;;;;;\n30B1;KATAKANA LETTER KE;Lo;0;L;;;;;N;;;;;\n30B2;KATAKANA LETTER GE;Lo;0;L;30B1 3099;;;;N;;;;;\n30B3;KATAKANA LETTER KO;Lo;0;L;;;;;N;;;;;\n30B4;KATAKANA LETTER GO;Lo;0;L;30B3 3099;;;;N;;;;;\n30B5;KATAKANA LETTER SA;Lo;0;L;;;;;N;;;;;\n30B6;KATAKANA LETTER ZA;Lo;0;L;30B5 3099;;;;N;;;;;\n30B7;KATAKANA LETTER SI;Lo;0;L;;;;;N;;;;;\n30B8;KATAKANA LETTER ZI;Lo;0;L;30B7 3099;;;;N;;;;;\n30B9;KATAKANA LETTER SU;Lo;0;L;;;;;N;;;;;\n30BA;KATAKANA LETTER ZU;Lo;0;L;30B9 3099;;;;N;;;;;\n30BB;KATAKANA LETTER SE;Lo;0;L;;;;;N;;;;;\n30BC;KATAKANA LETTER ZE;Lo;0;L;30BB 3099;;;;N;;;;;\n30BD;KATAKANA LETTER SO;Lo;0;L;;;;;N;;;;;\n30BE;KATAKANA LETTER ZO;Lo;0;L;30BD 3099;;;;N;;;;;\n30BF;KATAKANA LETTER TA;Lo;0;L;;;;;N;;;;;\n30C0;KATAKANA LETTER DA;Lo;0;L;30BF 3099;;;;N;;;;;\n30C1;KATAKANA LETTER TI;Lo;0;L;;;;;N;;;;;\n30C2;KATAKANA LETTER DI;Lo;0;L;30C1 3099;;;;N;;;;;\n30C3;KATAKANA LETTER SMALL TU;Lo;0;L;;;;;N;;;;;\n30C4;KATAKANA LETTER TU;Lo;0;L;;;;;N;;;;;\n30C5;KATAKANA LETTER DU;Lo;0;L;30C4 3099;;;;N;;;;;\n30C6;KATAKANA LETTER TE;Lo;0;L;;;;;N;;;;;\n30C7;KATAKANA LETTER DE;Lo;0;L;30C6 3099;;;;N;;;;;\n30C8;KATAKANA LETTER TO;Lo;0;L;;;;;N;;;;;\n30C9;KATAKANA LETTER DO;Lo;0;L;30C8 3099;;;;N;;;;;\n30CA;KATAKANA LETTER NA;Lo;0;L;;;;;N;;;;;\n30CB;KATAKANA LETTER NI;Lo;0;L;;;;;N;;;;;\n30CC;KATAKANA LETTER NU;Lo;0;L;;;;;N;;;;;\n30CD;KATAKANA LETTER NE;Lo;0;L;;;;;N;;;;;\n30CE;KATAKANA LETTER NO;Lo;0;L;;;;;N;;;;;\n30CF;KATAKANA LETTER HA;Lo;0;L;;;;;N;;;;;\n30D0;KATAKANA LETTER BA;Lo;0;L;30CF 3099;;;;N;;;;;\n30D1;KATAKANA LETTER PA;Lo;0;L;30CF 309A;;;;N;;;;;\n30D2;KATAKANA LETTER HI;Lo;0;L;;;;;N;;;;;\n30D3;KATAKANA LETTER BI;Lo;0;L;30D2 3099;;;;N;;;;;\n30D4;KATAKANA LETTER PI;Lo;0;L;30D2 309A;;;;N;;;;;\n30D5;KATAKANA LETTER HU;Lo;0;L;;;;;N;;;;;\n30D6;KATAKANA LETTER BU;Lo;0;L;30D5 3099;;;;N;;;;;\n30D7;KATAKANA LETTER PU;Lo;0;L;30D5 309A;;;;N;;;;;\n30D8;KATAKANA LETTER HE;Lo;0;L;;;;;N;;;;;\n30D9;KATAKANA LETTER BE;Lo;0;L;30D8 3099;;;;N;;;;;\n30DA;KATAKANA LETTER PE;Lo;0;L;30D8 309A;;;;N;;;;;\n30DB;KATAKANA LETTER HO;Lo;0;L;;;;;N;;;;;\n30DC;KATAKANA LETTER BO;Lo;0;L;30DB 3099;;;;N;;;;;\n30DD;KATAKANA LETTER PO;Lo;0;L;30DB 309A;;;;N;;;;;\n30DE;KATAKANA LETTER MA;Lo;0;L;;;;;N;;;;;\n30DF;KATAKANA LETTER MI;Lo;0;L;;;;;N;;;;;\n30E0;KATAKANA LETTER MU;Lo;0;L;;;;;N;;;;;\n30E1;KATAKANA LETTER ME;Lo;0;L;;;;;N;;;;;\n30E2;KATAKANA LETTER MO;Lo;0;L;;;;;N;;;;;\n30E3;KATAKANA LETTER SMALL YA;Lo;0;L;;;;;N;;;;;\n30E4;KATAKANA LETTER YA;Lo;0;L;;;;;N;;;;;\n30E5;KATAKANA LETTER SMALL YU;Lo;0;L;;;;;N;;;;;\n30E6;KATAKANA LETTER YU;Lo;0;L;;;;;N;;;;;\n30E7;KATAKANA LETTER SMALL YO;Lo;0;L;;;;;N;;;;;\n30E8;KATAKANA LETTER YO;Lo;0;L;;;;;N;;;;;\n30E9;KATAKANA LETTER RA;Lo;0;L;;;;;N;;;;;\n30EA;KATAKANA LETTER RI;Lo;0;L;;;;;N;;;;;\n30EB;KATAKANA LETTER RU;Lo;0;L;;;;;N;;;;;\n30EC;KATAKANA LETTER RE;Lo;0;L;;;;;N;;;;;\n30ED;KATAKANA LETTER RO;Lo;0;L;;;;;N;;;;;\n30EE;KATAKANA LETTER SMALL WA;Lo;0;L;;;;;N;;;;;\n30EF;KATAKANA LETTER WA;Lo;0;L;;;;;N;;;;;\n30F0;KATAKANA LETTER WI;Lo;0;L;;;;;N;;;;;\n30F1;KATAKANA LETTER WE;Lo;0;L;;;;;N;;;;;\n30F2;KATAKANA LETTER WO;Lo;0;L;;;;;N;;;;;\n30F3;KATAKANA LETTER N;Lo;0;L;;;;;N;;;;;\n30F4;KATAKANA LETTER VU;Lo;0;L;30A6 3099;;;;N;;;;;\n30F5;KATAKANA LETTER SMALL KA;Lo;0;L;;;;;N;;;;;\n30F6;KATAKANA LETTER SMALL KE;Lo;0;L;;;;;N;;;;;\n30F7;KATAKANA LETTER VA;Lo;0;L;30EF 3099;;;;N;;;;;\n30F8;KATAKANA LETTER VI;Lo;0;L;30F0 3099;;;;N;;;;;\n30F9;KATAKANA LETTER VE;Lo;0;L;30F1 3099;;;;N;;;;;\n30FA;KATAKANA LETTER VO;Lo;0;L;30F2 3099;;;;N;;;;;\n30FB;KATAKANA MIDDLE DOT;Po;0;ON;;;;;N;;;;;\n30FC;KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L;;;;;N;;;;;\n30FD;KATAKANA ITERATION MARK;Lm;0;L;;;;;N;;;;;\n30FE;KATAKANA VOICED ITERATION MARK;Lm;0;L;30FD 3099;;;;N;;;;;\n30FF;KATAKANA DIGRAPH KOTO;Lo;0;L;<vertical> 30B3 30C8;;;;N;;;;;\n3105;BOPOMOFO LETTER B;Lo;0;L;;;;;N;;;;;\n3106;BOPOMOFO LETTER P;Lo;0;L;;;;;N;;;;;\n3107;BOPOMOFO LETTER M;Lo;0;L;;;;;N;;;;;\n3108;BOPOMOFO LETTER F;Lo;0;L;;;;;N;;;;;\n3109;BOPOMOFO LETTER D;Lo;0;L;;;;;N;;;;;\n310A;BOPOMOFO LETTER T;Lo;0;L;;;;;N;;;;;\n310B;BOPOMOFO LETTER N;Lo;0;L;;;;;N;;;;;\n310C;BOPOMOFO LETTER L;Lo;0;L;;;;;N;;;;;\n310D;BOPOMOFO LETTER G;Lo;0;L;;;;;N;;;;;\n310E;BOPOMOFO LETTER K;Lo;0;L;;;;;N;;;;;\n310F;BOPOMOFO LETTER H;Lo;0;L;;;;;N;;;;;\n3110;BOPOMOFO LETTER J;Lo;0;L;;;;;N;;;;;\n3111;BOPOMOFO LETTER Q;Lo;0;L;;;;;N;;;;;\n3112;BOPOMOFO LETTER X;Lo;0;L;;;;;N;;;;;\n3113;BOPOMOFO LETTER ZH;Lo;0;L;;;;;N;;;;;\n3114;BOPOMOFO LETTER CH;Lo;0;L;;;;;N;;;;;\n3115;BOPOMOFO LETTER SH;Lo;0;L;;;;;N;;;;;\n3116;BOPOMOFO LETTER R;Lo;0;L;;;;;N;;;;;\n3117;BOPOMOFO LETTER Z;Lo;0;L;;;;;N;;;;;\n3118;BOPOMOFO LETTER C;Lo;0;L;;;;;N;;;;;\n3119;BOPOMOFO LETTER S;Lo;0;L;;;;;N;;;;;\n311A;BOPOMOFO LETTER A;Lo;0;L;;;;;N;;;;;\n311B;BOPOMOFO LETTER O;Lo;0;L;;;;;N;;;;;\n311C;BOPOMOFO LETTER E;Lo;0;L;;;;;N;;;;;\n311D;BOPOMOFO LETTER EH;Lo;0;L;;;;;N;;;;;\n311E;BOPOMOFO LETTER AI;Lo;0;L;;;;;N;;;;;\n311F;BOPOMOFO LETTER EI;Lo;0;L;;;;;N;;;;;\n3120;BOPOMOFO LETTER AU;Lo;0;L;;;;;N;;;;;\n3121;BOPOMOFO LETTER OU;Lo;0;L;;;;;N;;;;;\n3122;BOPOMOFO LETTER AN;Lo;0;L;;;;;N;;;;;\n3123;BOPOMOFO LETTER EN;Lo;0;L;;;;;N;;;;;\n3124;BOPOMOFO LETTER ANG;Lo;0;L;;;;;N;;;;;\n3125;BOPOMOFO LETTER ENG;Lo;0;L;;;;;N;;;;;\n3126;BOPOMOFO LETTER ER;Lo;0;L;;;;;N;;;;;\n3127;BOPOMOFO LETTER I;Lo;0;L;;;;;N;;;;;\n3128;BOPOMOFO LETTER U;Lo;0;L;;;;;N;;;;;\n3129;BOPOMOFO LETTER IU;Lo;0;L;;;;;N;;;;;\n312A;BOPOMOFO LETTER V;Lo;0;L;;;;;N;;;;;\n312B;BOPOMOFO LETTER NG;Lo;0;L;;;;;N;;;;;\n312C;BOPOMOFO LETTER GN;Lo;0;L;;;;;N;;;;;\n312D;BOPOMOFO LETTER IH;Lo;0;L;;;;;N;;;;;\n312E;BOPOMOFO LETTER O WITH DOT ABOVE;Lo;0;L;;;;;N;;;;;\n312F;BOPOMOFO LETTER NN;Lo;0;L;;;;;N;;;;;\n3131;HANGUL LETTER KIYEOK;Lo;0;L;<compat> 1100;;;;N;HANGUL LETTER GIYEOG;;;;\n3132;HANGUL LETTER SSANGKIYEOK;Lo;0;L;<compat> 1101;;;;N;HANGUL LETTER SSANG GIYEOG;;;;\n3133;HANGUL LETTER KIYEOK-SIOS;Lo;0;L;<compat> 11AA;;;;N;HANGUL LETTER GIYEOG SIOS;;;;\n3134;HANGUL LETTER NIEUN;Lo;0;L;<compat> 1102;;;;N;;;;;\n3135;HANGUL LETTER NIEUN-CIEUC;Lo;0;L;<compat> 11AC;;;;N;HANGUL LETTER NIEUN JIEUJ;;;;\n3136;HANGUL LETTER NIEUN-HIEUH;Lo;0;L;<compat> 11AD;;;;N;HANGUL LETTER NIEUN HIEUH;;;;\n3137;HANGUL LETTER TIKEUT;Lo;0;L;<compat> 1103;;;;N;HANGUL LETTER DIGEUD;;;;\n3138;HANGUL LETTER SSANGTIKEUT;Lo;0;L;<compat> 1104;;;;N;HANGUL LETTER SSANG DIGEUD;;;;\n3139;HANGUL LETTER RIEUL;Lo;0;L;<compat> 1105;;;;N;HANGUL LETTER LIEUL;;;;\n313A;HANGUL LETTER RIEUL-KIYEOK;Lo;0;L;<compat> 11B0;;;;N;HANGUL LETTER LIEUL GIYEOG;;;;\n313B;HANGUL LETTER RIEUL-MIEUM;Lo;0;L;<compat> 11B1;;;;N;HANGUL LETTER LIEUL MIEUM;;;;\n313C;HANGUL LETTER RIEUL-PIEUP;Lo;0;L;<compat> 11B2;;;;N;HANGUL LETTER LIEUL BIEUB;;;;\n313D;HANGUL LETTER RIEUL-SIOS;Lo;0;L;<compat> 11B3;;;;N;HANGUL LETTER LIEUL SIOS;;;;\n313E;HANGUL LETTER RIEUL-THIEUTH;Lo;0;L;<compat> 11B4;;;;N;HANGUL LETTER LIEUL TIEUT;;;;\n313F;HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L;<compat> 11B5;;;;N;HANGUL LETTER LIEUL PIEUP;;;;\n3140;HANGUL LETTER RIEUL-HIEUH;Lo;0;L;<compat> 111A;;;;N;HANGUL LETTER LIEUL HIEUH;;;;\n3141;HANGUL LETTER MIEUM;Lo;0;L;<compat> 1106;;;;N;;;;;\n3142;HANGUL LETTER PIEUP;Lo;0;L;<compat> 1107;;;;N;HANGUL LETTER BIEUB;;;;\n3143;HANGUL LETTER SSANGPIEUP;Lo;0;L;<compat> 1108;;;;N;HANGUL LETTER SSANG BIEUB;;;;\n3144;HANGUL LETTER PIEUP-SIOS;Lo;0;L;<compat> 1121;;;;N;HANGUL LETTER BIEUB SIOS;;;;\n3145;HANGUL LETTER SIOS;Lo;0;L;<compat> 1109;;;;N;;;;;\n3146;HANGUL LETTER SSANGSIOS;Lo;0;L;<compat> 110A;;;;N;HANGUL LETTER SSANG SIOS;;;;\n3147;HANGUL LETTER IEUNG;Lo;0;L;<compat> 110B;;;;N;;;;;\n3148;HANGUL LETTER CIEUC;Lo;0;L;<compat> 110C;;;;N;HANGUL LETTER JIEUJ;;;;\n3149;HANGUL LETTER SSANGCIEUC;Lo;0;L;<compat> 110D;;;;N;HANGUL LETTER SSANG JIEUJ;;;;\n314A;HANGUL LETTER CHIEUCH;Lo;0;L;<compat> 110E;;;;N;HANGUL LETTER CIEUC;;;;\n314B;HANGUL LETTER KHIEUKH;Lo;0;L;<compat> 110F;;;;N;HANGUL LETTER KIYEOK;;;;\n314C;HANGUL LETTER THIEUTH;Lo;0;L;<compat> 1110;;;;N;HANGUL LETTER TIEUT;;;;\n314D;HANGUL LETTER PHIEUPH;Lo;0;L;<compat> 1111;;;;N;HANGUL LETTER PIEUP;;;;\n314E;HANGUL LETTER HIEUH;Lo;0;L;<compat> 1112;;;;N;;;;;\n314F;HANGUL LETTER A;Lo;0;L;<compat> 1161;;;;N;;;;;\n3150;HANGUL LETTER AE;Lo;0;L;<compat> 1162;;;;N;;;;;\n3151;HANGUL LETTER YA;Lo;0;L;<compat> 1163;;;;N;;;;;\n3152;HANGUL LETTER YAE;Lo;0;L;<compat> 1164;;;;N;;;;;\n3153;HANGUL LETTER EO;Lo;0;L;<compat> 1165;;;;N;;;;;\n3154;HANGUL LETTER E;Lo;0;L;<compat> 1166;;;;N;;;;;\n3155;HANGUL LETTER YEO;Lo;0;L;<compat> 1167;;;;N;;;;;\n3156;HANGUL LETTER YE;Lo;0;L;<compat> 1168;;;;N;;;;;\n3157;HANGUL LETTER O;Lo;0;L;<compat> 1169;;;;N;;;;;\n3158;HANGUL LETTER WA;Lo;0;L;<compat> 116A;;;;N;;;;;\n3159;HANGUL LETTER WAE;Lo;0;L;<compat> 116B;;;;N;;;;;\n315A;HANGUL LETTER OE;Lo;0;L;<compat> 116C;;;;N;;;;;\n315B;HANGUL LETTER YO;Lo;0;L;<compat> 116D;;;;N;;;;;\n315C;HANGUL LETTER U;Lo;0;L;<compat> 116E;;;;N;;;;;\n315D;HANGUL LETTER WEO;Lo;0;L;<compat> 116F;;;;N;;;;;\n315E;HANGUL LETTER WE;Lo;0;L;<compat> 1170;;;;N;;;;;\n315F;HANGUL LETTER WI;Lo;0;L;<compat> 1171;;;;N;;;;;\n3160;HANGUL LETTER YU;Lo;0;L;<compat> 1172;;;;N;;;;;\n3161;HANGUL LETTER EU;Lo;0;L;<compat> 1173;;;;N;;;;;\n3162;HANGUL LETTER YI;Lo;0;L;<compat> 1174;;;;N;;;;;\n3163;HANGUL LETTER I;Lo;0;L;<compat> 1175;;;;N;;;;;\n3164;HANGUL FILLER;Lo;0;L;<compat> 1160;;;;N;HANGUL CAE OM;;;;\n3165;HANGUL LETTER SSANGNIEUN;Lo;0;L;<compat> 1114;;;;N;HANGUL LETTER SSANG NIEUN;;;;\n3166;HANGUL LETTER NIEUN-TIKEUT;Lo;0;L;<compat> 1115;;;;N;HANGUL LETTER NIEUN DIGEUD;;;;\n3167;HANGUL LETTER NIEUN-SIOS;Lo;0;L;<compat> 11C7;;;;N;HANGUL LETTER NIEUN SIOS;;;;\n3168;HANGUL LETTER NIEUN-PANSIOS;Lo;0;L;<compat> 11C8;;;;N;HANGUL LETTER NIEUN BAN CHI EUM;;;;\n3169;HANGUL LETTER RIEUL-KIYEOK-SIOS;Lo;0;L;<compat> 11CC;;;;N;HANGUL LETTER LIEUL GIYEOG SIOS;;;;\n316A;HANGUL LETTER RIEUL-TIKEUT;Lo;0;L;<compat> 11CE;;;;N;HANGUL LETTER LIEUL DIGEUD;;;;\n316B;HANGUL LETTER RIEUL-PIEUP-SIOS;Lo;0;L;<compat> 11D3;;;;N;HANGUL LETTER LIEUL BIEUB SIOS;;;;\n316C;HANGUL LETTER RIEUL-PANSIOS;Lo;0;L;<compat> 11D7;;;;N;HANGUL LETTER LIEUL BAN CHI EUM;;;;\n316D;HANGUL LETTER RIEUL-YEORINHIEUH;Lo;0;L;<compat> 11D9;;;;N;HANGUL LETTER LIEUL YEOLIN HIEUH;;;;\n316E;HANGUL LETTER MIEUM-PIEUP;Lo;0;L;<compat> 111C;;;;N;HANGUL LETTER MIEUM BIEUB;;;;\n316F;HANGUL LETTER MIEUM-SIOS;Lo;0;L;<compat> 11DD;;;;N;HANGUL LETTER MIEUM SIOS;;;;\n3170;HANGUL LETTER MIEUM-PANSIOS;Lo;0;L;<compat> 11DF;;;;N;HANGUL LETTER BIEUB BAN CHI EUM;;;;\n3171;HANGUL LETTER KAPYEOUNMIEUM;Lo;0;L;<compat> 111D;;;;N;HANGUL LETTER MIEUM SUN GYEONG EUM;;;;\n3172;HANGUL LETTER PIEUP-KIYEOK;Lo;0;L;<compat> 111E;;;;N;HANGUL LETTER BIEUB GIYEOG;;;;\n3173;HANGUL LETTER PIEUP-TIKEUT;Lo;0;L;<compat> 1120;;;;N;HANGUL LETTER BIEUB DIGEUD;;;;\n3174;HANGUL LETTER PIEUP-SIOS-KIYEOK;Lo;0;L;<compat> 1122;;;;N;HANGUL LETTER BIEUB SIOS GIYEOG;;;;\n3175;HANGUL LETTER PIEUP-SIOS-TIKEUT;Lo;0;L;<compat> 1123;;;;N;HANGUL LETTER BIEUB SIOS DIGEUD;;;;\n3176;HANGUL LETTER PIEUP-CIEUC;Lo;0;L;<compat> 1127;;;;N;HANGUL LETTER BIEUB JIEUJ;;;;\n3177;HANGUL LETTER PIEUP-THIEUTH;Lo;0;L;<compat> 1129;;;;N;HANGUL LETTER BIEUB TIEUT;;;;\n3178;HANGUL LETTER KAPYEOUNPIEUP;Lo;0;L;<compat> 112B;;;;N;HANGUL LETTER BIEUB SUN GYEONG EUM;;;;\n3179;HANGUL LETTER KAPYEOUNSSANGPIEUP;Lo;0;L;<compat> 112C;;;;N;HANGUL LETTER SSANG BIEUB SUN GYEONG EUM;;;;\n317A;HANGUL LETTER SIOS-KIYEOK;Lo;0;L;<compat> 112D;;;;N;HANGUL LETTER SIOS GIYEOG;;;;\n317B;HANGUL LETTER SIOS-NIEUN;Lo;0;L;<compat> 112E;;;;N;HANGUL LETTER SIOS NIEUN;;;;\n317C;HANGUL LETTER SIOS-TIKEUT;Lo;0;L;<compat> 112F;;;;N;HANGUL LETTER SIOS DIGEUD;;;;\n317D;HANGUL LETTER SIOS-PIEUP;Lo;0;L;<compat> 1132;;;;N;HANGUL LETTER SIOS BIEUB;;;;\n317E;HANGUL LETTER SIOS-CIEUC;Lo;0;L;<compat> 1136;;;;N;HANGUL LETTER SIOS JIEUJ;;;;\n317F;HANGUL LETTER PANSIOS;Lo;0;L;<compat> 1140;;;;N;HANGUL LETTER BAN CHI EUM;;;;\n3180;HANGUL LETTER SSANGIEUNG;Lo;0;L;<compat> 1147;;;;N;HANGUL LETTER SSANG IEUNG;;;;\n3181;HANGUL LETTER YESIEUNG;Lo;0;L;<compat> 114C;;;;N;HANGUL LETTER NGIEUNG;;;;\n3182;HANGUL LETTER YESIEUNG-SIOS;Lo;0;L;<compat> 11F1;;;;N;HANGUL LETTER NGIEUNG SIOS;;;;\n3183;HANGUL LETTER YESIEUNG-PANSIOS;Lo;0;L;<compat> 11F2;;;;N;HANGUL LETTER NGIEUNG BAN CHI EUM;;;;\n3184;HANGUL LETTER KAPYEOUNPHIEUPH;Lo;0;L;<compat> 1157;;;;N;HANGUL LETTER PIEUP SUN GYEONG EUM;;;;\n3185;HANGUL LETTER SSANGHIEUH;Lo;0;L;<compat> 1158;;;;N;HANGUL LETTER SSANG HIEUH;;;;\n3186;HANGUL LETTER YEORINHIEUH;Lo;0;L;<compat> 1159;;;;N;HANGUL LETTER YEOLIN HIEUH;;;;\n3187;HANGUL LETTER YO-YA;Lo;0;L;<compat> 1184;;;;N;HANGUL LETTER YOYA;;;;\n3188;HANGUL LETTER YO-YAE;Lo;0;L;<compat> 1185;;;;N;HANGUL LETTER YOYAE;;;;\n3189;HANGUL LETTER YO-I;Lo;0;L;<compat> 1188;;;;N;HANGUL LETTER YOI;;;;\n318A;HANGUL LETTER YU-YEO;Lo;0;L;<compat> 1191;;;;N;HANGUL LETTER YUYEO;;;;\n318B;HANGUL LETTER YU-YE;Lo;0;L;<compat> 1192;;;;N;HANGUL LETTER YUYE;;;;\n318C;HANGUL LETTER YU-I;Lo;0;L;<compat> 1194;;;;N;HANGUL LETTER YUI;;;;\n318D;HANGUL LETTER ARAEA;Lo;0;L;<compat> 119E;;;;N;HANGUL LETTER ALAE A;;;;\n318E;HANGUL LETTER ARAEAE;Lo;0;L;<compat> 11A1;;;;N;HANGUL LETTER ALAE AE;;;;\n3190;IDEOGRAPHIC ANNOTATION LINKING MARK;So;0;L;;;;;N;KANBUN TATETEN;;;;\n3191;IDEOGRAPHIC ANNOTATION REVERSE MARK;So;0;L;;;;;N;KAERITEN RE;;;;\n3192;IDEOGRAPHIC ANNOTATION ONE MARK;No;0;L;<super> 4E00;;;1;N;KAERITEN ITI;;;;\n3193;IDEOGRAPHIC ANNOTATION TWO MARK;No;0;L;<super> 4E8C;;;2;N;KAERITEN NI;;;;\n3194;IDEOGRAPHIC ANNOTATION THREE MARK;No;0;L;<super> 4E09;;;3;N;KAERITEN SAN;;;;\n3195;IDEOGRAPHIC ANNOTATION FOUR MARK;No;0;L;<super> 56DB;;;4;N;KAERITEN SI;;;;\n3196;IDEOGRAPHIC ANNOTATION TOP MARK;So;0;L;<super> 4E0A;;;;N;KAERITEN ZYOU;;;;\n3197;IDEOGRAPHIC ANNOTATION MIDDLE MARK;So;0;L;<super> 4E2D;;;;N;KAERITEN TYUU;;;;\n3198;IDEOGRAPHIC ANNOTATION BOTTOM MARK;So;0;L;<super> 4E0B;;;;N;KAERITEN GE;;;;\n3199;IDEOGRAPHIC ANNOTATION FIRST MARK;So;0;L;<super> 7532;;;;N;KAERITEN KOU;;;;\n319A;IDEOGRAPHIC ANNOTATION SECOND MARK;So;0;L;<super> 4E59;;;;N;KAERITEN OTU;;;;\n319B;IDEOGRAPHIC ANNOTATION THIRD MARK;So;0;L;<super> 4E19;;;;N;KAERITEN HEI;;;;\n319C;IDEOGRAPHIC ANNOTATION FOURTH MARK;So;0;L;<super> 4E01;;;;N;KAERITEN TEI;;;;\n319D;IDEOGRAPHIC ANNOTATION HEAVEN MARK;So;0;L;<super> 5929;;;;N;KAERITEN TEN;;;;\n319E;IDEOGRAPHIC ANNOTATION EARTH MARK;So;0;L;<super> 5730;;;;N;KAERITEN TI;;;;\n319F;IDEOGRAPHIC ANNOTATION MAN MARK;So;0;L;<super> 4EBA;;;;N;KAERITEN ZIN;;;;\n31A0;BOPOMOFO LETTER BU;Lo;0;L;;;;;N;;;;;\n31A1;BOPOMOFO LETTER ZI;Lo;0;L;;;;;N;;;;;\n31A2;BOPOMOFO LETTER JI;Lo;0;L;;;;;N;;;;;\n31A3;BOPOMOFO LETTER GU;Lo;0;L;;;;;N;;;;;\n31A4;BOPOMOFO LETTER EE;Lo;0;L;;;;;N;;;;;\n31A5;BOPOMOFO LETTER ENN;Lo;0;L;;;;;N;;;;;\n31A6;BOPOMOFO LETTER OO;Lo;0;L;;;;;N;;;;;\n31A7;BOPOMOFO LETTER ONN;Lo;0;L;;;;;N;;;;;\n31A8;BOPOMOFO LETTER IR;Lo;0;L;;;;;N;;;;;\n31A9;BOPOMOFO LETTER ANN;Lo;0;L;;;;;N;;;;;\n31AA;BOPOMOFO LETTER INN;Lo;0;L;;;;;N;;;;;\n31AB;BOPOMOFO LETTER UNN;Lo;0;L;;;;;N;;;;;\n31AC;BOPOMOFO LETTER IM;Lo;0;L;;;;;N;;;;;\n31AD;BOPOMOFO LETTER NGG;Lo;0;L;;;;;N;;;;;\n31AE;BOPOMOFO LETTER AINN;Lo;0;L;;;;;N;;;;;\n31AF;BOPOMOFO LETTER AUNN;Lo;0;L;;;;;N;;;;;\n31B0;BOPOMOFO LETTER AM;Lo;0;L;;;;;N;;;;;\n31B1;BOPOMOFO LETTER OM;Lo;0;L;;;;;N;;;;;\n31B2;BOPOMOFO LETTER ONG;Lo;0;L;;;;;N;;;;;\n31B3;BOPOMOFO LETTER INNN;Lo;0;L;;;;;N;;;;;\n31B4;BOPOMOFO FINAL LETTER P;Lo;0;L;;;;;N;;;;;\n31B5;BOPOMOFO FINAL LETTER T;Lo;0;L;;;;;N;;;;;\n31B6;BOPOMOFO FINAL LETTER K;Lo;0;L;;;;;N;;;;;\n31B7;BOPOMOFO FINAL LETTER H;Lo;0;L;;;;;N;;;;;\n31B8;BOPOMOFO LETTER GH;Lo;0;L;;;;;N;;;;;\n31B9;BOPOMOFO LETTER LH;Lo;0;L;;;;;N;;;;;\n31BA;BOPOMOFO LETTER ZY;Lo;0;L;;;;;N;;;;;\n31C0;CJK STROKE T;So;0;ON;;;;;N;;;;;\n31C1;CJK STROKE WG;So;0;ON;;;;;N;;;;;\n31C2;CJK STROKE XG;So;0;ON;;;;;N;;;;;\n31C3;CJK STROKE BXG;So;0;ON;;;;;N;;;;;\n31C4;CJK STROKE SW;So;0;ON;;;;;N;;;;;\n31C5;CJK STROKE HZZ;So;0;ON;;;;;N;;;;;\n31C6;CJK STROKE HZG;So;0;ON;;;;;N;;;;;\n31C7;CJK STROKE HP;So;0;ON;;;;;N;;;;;\n31C8;CJK STROKE HZWG;So;0;ON;;;;;N;;;;;\n31C9;CJK STROKE SZWG;So;0;ON;;;;;N;;;;;\n31CA;CJK STROKE HZT;So;0;ON;;;;;N;;;;;\n31CB;CJK STROKE HZZP;So;0;ON;;;;;N;;;;;\n31CC;CJK STROKE HPWG;So;0;ON;;;;;N;;;;;\n31CD;CJK STROKE HZW;So;0;ON;;;;;N;;;;;\n31CE;CJK STROKE HZZZ;So;0;ON;;;;;N;;;;;\n31CF;CJK STROKE N;So;0;ON;;;;;N;;;;;\n31D0;CJK STROKE H;So;0;ON;;;;;N;;;;;\n31D1;CJK STROKE S;So;0;ON;;;;;N;;;;;\n31D2;CJK STROKE P;So;0;ON;;;;;N;;;;;\n31D3;CJK STROKE SP;So;0;ON;;;;;N;;;;;\n31D4;CJK STROKE D;So;0;ON;;;;;N;;;;;\n31D5;CJK STROKE HZ;So;0;ON;;;;;N;;;;;\n31D6;CJK STROKE HG;So;0;ON;;;;;N;;;;;\n31D7;CJK STROKE SZ;So;0;ON;;;;;N;;;;;\n31D8;CJK STROKE SWZ;So;0;ON;;;;;N;;;;;\n31D9;CJK STROKE ST;So;0;ON;;;;;N;;;;;\n31DA;CJK STROKE SG;So;0;ON;;;;;N;;;;;\n31DB;CJK STROKE PD;So;0;ON;;;;;N;;;;;\n31DC;CJK STROKE PZ;So;0;ON;;;;;N;;;;;\n31DD;CJK STROKE TN;So;0;ON;;;;;N;;;;;\n31DE;CJK STROKE SZZ;So;0;ON;;;;;N;;;;;\n31DF;CJK STROKE SWG;So;0;ON;;;;;N;;;;;\n31E0;CJK STROKE HXWG;So;0;ON;;;;;N;;;;;\n31E1;CJK STROKE HZZZG;So;0;ON;;;;;N;;;;;\n31E2;CJK STROKE PG;So;0;ON;;;;;N;;;;;\n31E3;CJK STROKE Q;So;0;ON;;;;;N;;;;;\n31F0;KATAKANA LETTER SMALL KU;Lo;0;L;;;;;N;;;;;\n31F1;KATAKANA LETTER SMALL SI;Lo;0;L;;;;;N;;;;;\n31F2;KATAKANA LETTER SMALL SU;Lo;0;L;;;;;N;;;;;\n31F3;KATAKANA LETTER SMALL TO;Lo;0;L;;;;;N;;;;;\n31F4;KATAKANA LETTER SMALL NU;Lo;0;L;;;;;N;;;;;\n31F5;KATAKANA LETTER SMALL HA;Lo;0;L;;;;;N;;;;;\n31F6;KATAKANA LETTER SMALL HI;Lo;0;L;;;;;N;;;;;\n31F7;KATAKANA LETTER SMALL HU;Lo;0;L;;;;;N;;;;;\n31F8;KATAKANA LETTER SMALL HE;Lo;0;L;;;;;N;;;;;\n31F9;KATAKANA LETTER SMALL HO;Lo;0;L;;;;;N;;;;;\n31FA;KATAKANA LETTER SMALL MU;Lo;0;L;;;;;N;;;;;\n31FB;KATAKANA LETTER SMALL RA;Lo;0;L;;;;;N;;;;;\n31FC;KATAKANA LETTER SMALL RI;Lo;0;L;;;;;N;;;;;\n31FD;KATAKANA LETTER SMALL RU;Lo;0;L;;;;;N;;;;;\n31FE;KATAKANA LETTER SMALL RE;Lo;0;L;;;;;N;;;;;\n31FF;KATAKANA LETTER SMALL RO;Lo;0;L;;;;;N;;;;;\n3200;PARENTHESIZED HANGUL KIYEOK;So;0;L;<compat> 0028 1100 0029;;;;N;PARENTHESIZED HANGUL GIYEOG;;;;\n3201;PARENTHESIZED HANGUL NIEUN;So;0;L;<compat> 0028 1102 0029;;;;N;;;;;\n3202;PARENTHESIZED HANGUL TIKEUT;So;0;L;<compat> 0028 1103 0029;;;;N;PARENTHESIZED HANGUL DIGEUD;;;;\n3203;PARENTHESIZED HANGUL RIEUL;So;0;L;<compat> 0028 1105 0029;;;;N;PARENTHESIZED HANGUL LIEUL;;;;\n3204;PARENTHESIZED HANGUL MIEUM;So;0;L;<compat> 0028 1106 0029;;;;N;;;;;\n3205;PARENTHESIZED HANGUL PIEUP;So;0;L;<compat> 0028 1107 0029;;;;N;PARENTHESIZED HANGUL BIEUB;;;;\n3206;PARENTHESIZED HANGUL SIOS;So;0;L;<compat> 0028 1109 0029;;;;N;;;;;\n3207;PARENTHESIZED HANGUL IEUNG;So;0;L;<compat> 0028 110B 0029;;;;N;;;;;\n3208;PARENTHESIZED HANGUL CIEUC;So;0;L;<compat> 0028 110C 0029;;;;N;PARENTHESIZED HANGUL JIEUJ;;;;\n3209;PARENTHESIZED HANGUL CHIEUCH;So;0;L;<compat> 0028 110E 0029;;;;N;PARENTHESIZED HANGUL CIEUC;;;;\n320A;PARENTHESIZED HANGUL KHIEUKH;So;0;L;<compat> 0028 110F 0029;;;;N;PARENTHESIZED HANGUL KIYEOK;;;;\n320B;PARENTHESIZED HANGUL THIEUTH;So;0;L;<compat> 0028 1110 0029;;;;N;PARENTHESIZED HANGUL TIEUT;;;;\n320C;PARENTHESIZED HANGUL PHIEUPH;So;0;L;<compat> 0028 1111 0029;;;;N;PARENTHESIZED HANGUL PIEUP;;;;\n320D;PARENTHESIZED HANGUL HIEUH;So;0;L;<compat> 0028 1112 0029;;;;N;;;;;\n320E;PARENTHESIZED HANGUL KIYEOK A;So;0;L;<compat> 0028 1100 1161 0029;;;;N;PARENTHESIZED HANGUL GA;;;;\n320F;PARENTHESIZED HANGUL NIEUN A;So;0;L;<compat> 0028 1102 1161 0029;;;;N;PARENTHESIZED HANGUL NA;;;;\n3210;PARENTHESIZED HANGUL TIKEUT A;So;0;L;<compat> 0028 1103 1161 0029;;;;N;PARENTHESIZED HANGUL DA;;;;\n3211;PARENTHESIZED HANGUL RIEUL A;So;0;L;<compat> 0028 1105 1161 0029;;;;N;PARENTHESIZED HANGUL LA;;;;\n3212;PARENTHESIZED HANGUL MIEUM A;So;0;L;<compat> 0028 1106 1161 0029;;;;N;PARENTHESIZED HANGUL MA;;;;\n3213;PARENTHESIZED HANGUL PIEUP A;So;0;L;<compat> 0028 1107 1161 0029;;;;N;PARENTHESIZED HANGUL BA;;;;\n3214;PARENTHESIZED HANGUL SIOS A;So;0;L;<compat> 0028 1109 1161 0029;;;;N;PARENTHESIZED HANGUL SA;;;;\n3215;PARENTHESIZED HANGUL IEUNG A;So;0;L;<compat> 0028 110B 1161 0029;;;;N;PARENTHESIZED HANGUL A;;;;\n3216;PARENTHESIZED HANGUL CIEUC A;So;0;L;<compat> 0028 110C 1161 0029;;;;N;PARENTHESIZED HANGUL JA;;;;\n3217;PARENTHESIZED HANGUL CHIEUCH A;So;0;L;<compat> 0028 110E 1161 0029;;;;N;PARENTHESIZED HANGUL CA;;;;\n3218;PARENTHESIZED HANGUL KHIEUKH A;So;0;L;<compat> 0028 110F 1161 0029;;;;N;PARENTHESIZED HANGUL KA;;;;\n3219;PARENTHESIZED HANGUL THIEUTH A;So;0;L;<compat> 0028 1110 1161 0029;;;;N;PARENTHESIZED HANGUL TA;;;;\n321A;PARENTHESIZED HANGUL PHIEUPH A;So;0;L;<compat> 0028 1111 1161 0029;;;;N;PARENTHESIZED HANGUL PA;;;;\n321B;PARENTHESIZED HANGUL HIEUH A;So;0;L;<compat> 0028 1112 1161 0029;;;;N;PARENTHESIZED HANGUL HA;;;;\n321C;PARENTHESIZED HANGUL CIEUC U;So;0;L;<compat> 0028 110C 116E 0029;;;;N;PARENTHESIZED HANGUL JU;;;;\n321D;PARENTHESIZED KOREAN CHARACTER OJEON;So;0;ON;<compat> 0028 110B 1169 110C 1165 11AB 0029;;;;N;;;;;\n321E;PARENTHESIZED KOREAN CHARACTER O HU;So;0;ON;<compat> 0028 110B 1169 1112 116E 0029;;;;N;;;;;\n3220;PARENTHESIZED IDEOGRAPH ONE;No;0;L;<compat> 0028 4E00 0029;;;1;N;;;;;\n3221;PARENTHESIZED IDEOGRAPH TWO;No;0;L;<compat> 0028 4E8C 0029;;;2;N;;;;;\n3222;PARENTHESIZED IDEOGRAPH THREE;No;0;L;<compat> 0028 4E09 0029;;;3;N;;;;;\n3223;PARENTHESIZED IDEOGRAPH FOUR;No;0;L;<compat> 0028 56DB 0029;;;4;N;;;;;\n3224;PARENTHESIZED IDEOGRAPH FIVE;No;0;L;<compat> 0028 4E94 0029;;;5;N;;;;;\n3225;PARENTHESIZED IDEOGRAPH SIX;No;0;L;<compat> 0028 516D 0029;;;6;N;;;;;\n3226;PARENTHESIZED IDEOGRAPH SEVEN;No;0;L;<compat> 0028 4E03 0029;;;7;N;;;;;\n3227;PARENTHESIZED IDEOGRAPH EIGHT;No;0;L;<compat> 0028 516B 0029;;;8;N;;;;;\n3228;PARENTHESIZED IDEOGRAPH NINE;No;0;L;<compat> 0028 4E5D 0029;;;9;N;;;;;\n3229;PARENTHESIZED IDEOGRAPH TEN;No;0;L;<compat> 0028 5341 0029;;;10;N;;;;;\n322A;PARENTHESIZED IDEOGRAPH MOON;So;0;L;<compat> 0028 6708 0029;;;;N;;;;;\n322B;PARENTHESIZED IDEOGRAPH FIRE;So;0;L;<compat> 0028 706B 0029;;;;N;;;;;\n322C;PARENTHESIZED IDEOGRAPH WATER;So;0;L;<compat> 0028 6C34 0029;;;;N;;;;;\n322D;PARENTHESIZED IDEOGRAPH WOOD;So;0;L;<compat> 0028 6728 0029;;;;N;;;;;\n322E;PARENTHESIZED IDEOGRAPH METAL;So;0;L;<compat> 0028 91D1 0029;;;;N;;;;;\n322F;PARENTHESIZED IDEOGRAPH EARTH;So;0;L;<compat> 0028 571F 0029;;;;N;;;;;\n3230;PARENTHESIZED IDEOGRAPH SUN;So;0;L;<compat> 0028 65E5 0029;;;;N;;;;;\n3231;PARENTHESIZED IDEOGRAPH STOCK;So;0;L;<compat> 0028 682A 0029;;;;N;;;;;\n3232;PARENTHESIZED IDEOGRAPH HAVE;So;0;L;<compat> 0028 6709 0029;;;;N;;;;;\n3233;PARENTHESIZED IDEOGRAPH SOCIETY;So;0;L;<compat> 0028 793E 0029;;;;N;;;;;\n3234;PARENTHESIZED IDEOGRAPH NAME;So;0;L;<compat> 0028 540D 0029;;;;N;;;;;\n3235;PARENTHESIZED IDEOGRAPH SPECIAL;So;0;L;<compat> 0028 7279 0029;;;;N;;;;;\n3236;PARENTHESIZED IDEOGRAPH FINANCIAL;So;0;L;<compat> 0028 8CA1 0029;;;;N;;;;;\n3237;PARENTHESIZED IDEOGRAPH CONGRATULATION;So;0;L;<compat> 0028 795D 0029;;;;N;;;;;\n3238;PARENTHESIZED IDEOGRAPH LABOR;So;0;L;<compat> 0028 52B4 0029;;;;N;;;;;\n3239;PARENTHESIZED IDEOGRAPH REPRESENT;So;0;L;<compat> 0028 4EE3 0029;;;;N;;;;;\n323A;PARENTHESIZED IDEOGRAPH CALL;So;0;L;<compat> 0028 547C 0029;;;;N;;;;;\n323B;PARENTHESIZED IDEOGRAPH STUDY;So;0;L;<compat> 0028 5B66 0029;;;;N;;;;;\n323C;PARENTHESIZED IDEOGRAPH SUPERVISE;So;0;L;<compat> 0028 76E3 0029;;;;N;;;;;\n323D;PARENTHESIZED IDEOGRAPH ENTERPRISE;So;0;L;<compat> 0028 4F01 0029;;;;N;;;;;\n323E;PARENTHESIZED IDEOGRAPH RESOURCE;So;0;L;<compat> 0028 8CC7 0029;;;;N;;;;;\n323F;PARENTHESIZED IDEOGRAPH ALLIANCE;So;0;L;<compat> 0028 5354 0029;;;;N;;;;;\n3240;PARENTHESIZED IDEOGRAPH FESTIVAL;So;0;L;<compat> 0028 796D 0029;;;;N;;;;;\n3241;PARENTHESIZED IDEOGRAPH REST;So;0;L;<compat> 0028 4F11 0029;;;;N;;;;;\n3242;PARENTHESIZED IDEOGRAPH SELF;So;0;L;<compat> 0028 81EA 0029;;;;N;;;;;\n3243;PARENTHESIZED IDEOGRAPH REACH;So;0;L;<compat> 0028 81F3 0029;;;;N;;;;;\n3244;CIRCLED IDEOGRAPH QUESTION;So;0;L;<circle> 554F;;;;N;;;;;\n3245;CIRCLED IDEOGRAPH KINDERGARTEN;So;0;L;<circle> 5E7C;;;;N;;;;;\n3246;CIRCLED IDEOGRAPH SCHOOL;So;0;L;<circle> 6587;;;;N;;;;;\n3247;CIRCLED IDEOGRAPH KOTO;So;0;L;<circle> 7B8F;;;;N;;;;;\n3248;CIRCLED NUMBER TEN ON BLACK SQUARE;No;0;L;;;;10;N;;;;;\n3249;CIRCLED NUMBER TWENTY ON BLACK SQUARE;No;0;L;;;;20;N;;;;;\n324A;CIRCLED NUMBER THIRTY ON BLACK SQUARE;No;0;L;;;;30;N;;;;;\n324B;CIRCLED NUMBER FORTY ON BLACK SQUARE;No;0;L;;;;40;N;;;;;\n324C;CIRCLED NUMBER FIFTY ON BLACK SQUARE;No;0;L;;;;50;N;;;;;\n324D;CIRCLED NUMBER SIXTY ON BLACK SQUARE;No;0;L;;;;60;N;;;;;\n324E;CIRCLED NUMBER SEVENTY ON BLACK SQUARE;No;0;L;;;;70;N;;;;;\n324F;CIRCLED NUMBER EIGHTY ON BLACK SQUARE;No;0;L;;;;80;N;;;;;\n3250;PARTNERSHIP SIGN;So;0;ON;<square> 0050 0054 0045;;;;N;;;;;\n3251;CIRCLED NUMBER TWENTY ONE;No;0;ON;<circle> 0032 0031;;;21;N;;;;;\n3252;CIRCLED NUMBER TWENTY TWO;No;0;ON;<circle> 0032 0032;;;22;N;;;;;\n3253;CIRCLED NUMBER TWENTY THREE;No;0;ON;<circle> 0032 0033;;;23;N;;;;;\n3254;CIRCLED NUMBER TWENTY FOUR;No;0;ON;<circle> 0032 0034;;;24;N;;;;;\n3255;CIRCLED NUMBER TWENTY FIVE;No;0;ON;<circle> 0032 0035;;;25;N;;;;;\n3256;CIRCLED NUMBER TWENTY SIX;No;0;ON;<circle> 0032 0036;;;26;N;;;;;\n3257;CIRCLED NUMBER TWENTY SEVEN;No;0;ON;<circle> 0032 0037;;;27;N;;;;;\n3258;CIRCLED NUMBER TWENTY EIGHT;No;0;ON;<circle> 0032 0038;;;28;N;;;;;\n3259;CIRCLED NUMBER TWENTY NINE;No;0;ON;<circle> 0032 0039;;;29;N;;;;;\n325A;CIRCLED NUMBER THIRTY;No;0;ON;<circle> 0033 0030;;;30;N;;;;;\n325B;CIRCLED NUMBER THIRTY ONE;No;0;ON;<circle> 0033 0031;;;31;N;;;;;\n325C;CIRCLED NUMBER THIRTY TWO;No;0;ON;<circle> 0033 0032;;;32;N;;;;;\n325D;CIRCLED NUMBER THIRTY THREE;No;0;ON;<circle> 0033 0033;;;33;N;;;;;\n325E;CIRCLED NUMBER THIRTY FOUR;No;0;ON;<circle> 0033 0034;;;34;N;;;;;\n325F;CIRCLED NUMBER THIRTY FIVE;No;0;ON;<circle> 0033 0035;;;35;N;;;;;\n3260;CIRCLED HANGUL KIYEOK;So;0;L;<circle> 1100;;;;N;CIRCLED HANGUL GIYEOG;;;;\n3261;CIRCLED HANGUL NIEUN;So;0;L;<circle> 1102;;;;N;;;;;\n3262;CIRCLED HANGUL TIKEUT;So;0;L;<circle> 1103;;;;N;CIRCLED HANGUL DIGEUD;;;;\n3263;CIRCLED HANGUL RIEUL;So;0;L;<circle> 1105;;;;N;CIRCLED HANGUL LIEUL;;;;\n3264;CIRCLED HANGUL MIEUM;So;0;L;<circle> 1106;;;;N;;;;;\n3265;CIRCLED HANGUL PIEUP;So;0;L;<circle> 1107;;;;N;CIRCLED HANGUL BIEUB;;;;\n3266;CIRCLED HANGUL SIOS;So;0;L;<circle> 1109;;;;N;;;;;\n3267;CIRCLED HANGUL IEUNG;So;0;L;<circle> 110B;;;;N;;;;;\n3268;CIRCLED HANGUL CIEUC;So;0;L;<circle> 110C;;;;N;CIRCLED HANGUL JIEUJ;;;;\n3269;CIRCLED HANGUL CHIEUCH;So;0;L;<circle> 110E;;;;N;CIRCLED HANGUL CIEUC;;;;\n326A;CIRCLED HANGUL KHIEUKH;So;0;L;<circle> 110F;;;;N;CIRCLED HANGUL KIYEOK;;;;\n326B;CIRCLED HANGUL THIEUTH;So;0;L;<circle> 1110;;;;N;CIRCLED HANGUL TIEUT;;;;\n326C;CIRCLED HANGUL PHIEUPH;So;0;L;<circle> 1111;;;;N;CIRCLED HANGUL PIEUP;;;;\n326D;CIRCLED HANGUL HIEUH;So;0;L;<circle> 1112;;;;N;;;;;\n326E;CIRCLED HANGUL KIYEOK A;So;0;L;<circle> 1100 1161;;;;N;CIRCLED HANGUL GA;;;;\n326F;CIRCLED HANGUL NIEUN A;So;0;L;<circle> 1102 1161;;;;N;CIRCLED HANGUL NA;;;;\n3270;CIRCLED HANGUL TIKEUT A;So;0;L;<circle> 1103 1161;;;;N;CIRCLED HANGUL DA;;;;\n3271;CIRCLED HANGUL RIEUL A;So;0;L;<circle> 1105 1161;;;;N;CIRCLED HANGUL LA;;;;\n3272;CIRCLED HANGUL MIEUM A;So;0;L;<circle> 1106 1161;;;;N;CIRCLED HANGUL MA;;;;\n3273;CIRCLED HANGUL PIEUP A;So;0;L;<circle> 1107 1161;;;;N;CIRCLED HANGUL BA;;;;\n3274;CIRCLED HANGUL SIOS A;So;0;L;<circle> 1109 1161;;;;N;CIRCLED HANGUL SA;;;;\n3275;CIRCLED HANGUL IEUNG A;So;0;L;<circle> 110B 1161;;;;N;CIRCLED HANGUL A;;;;\n3276;CIRCLED HANGUL CIEUC A;So;0;L;<circle> 110C 1161;;;;N;CIRCLED HANGUL JA;;;;\n3277;CIRCLED HANGUL CHIEUCH A;So;0;L;<circle> 110E 1161;;;;N;CIRCLED HANGUL CA;;;;\n3278;CIRCLED HANGUL KHIEUKH A;So;0;L;<circle> 110F 1161;;;;N;CIRCLED HANGUL KA;;;;\n3279;CIRCLED HANGUL THIEUTH A;So;0;L;<circle> 1110 1161;;;;N;CIRCLED HANGUL TA;;;;\n327A;CIRCLED HANGUL PHIEUPH A;So;0;L;<circle> 1111 1161;;;;N;CIRCLED HANGUL PA;;;;\n327B;CIRCLED HANGUL HIEUH A;So;0;L;<circle> 1112 1161;;;;N;CIRCLED HANGUL HA;;;;\n327C;CIRCLED KOREAN CHARACTER CHAMKO;So;0;ON;<circle> 110E 1161 11B7 1100 1169;;;;N;;;;;\n327D;CIRCLED KOREAN CHARACTER JUEUI;So;0;ON;<circle> 110C 116E 110B 1174;;;;N;;;;;\n327E;CIRCLED HANGUL IEUNG U;So;0;ON;<circle> 110B 116E;;;;N;;;;;\n327F;KOREAN STANDARD SYMBOL;So;0;L;;;;;N;;;;;\n3280;CIRCLED IDEOGRAPH ONE;No;0;L;<circle> 4E00;;;1;N;;;;;\n3281;CIRCLED IDEOGRAPH TWO;No;0;L;<circle> 4E8C;;;2;N;;;;;\n3282;CIRCLED IDEOGRAPH THREE;No;0;L;<circle> 4E09;;;3;N;;;;;\n3283;CIRCLED IDEOGRAPH FOUR;No;0;L;<circle> 56DB;;;4;N;;;;;\n3284;CIRCLED IDEOGRAPH FIVE;No;0;L;<circle> 4E94;;;5;N;;;;;\n3285;CIRCLED IDEOGRAPH SIX;No;0;L;<circle> 516D;;;6;N;;;;;\n3286;CIRCLED IDEOGRAPH SEVEN;No;0;L;<circle> 4E03;;;7;N;;;;;\n3287;CIRCLED IDEOGRAPH EIGHT;No;0;L;<circle> 516B;;;8;N;;;;;\n3288;CIRCLED IDEOGRAPH NINE;No;0;L;<circle> 4E5D;;;9;N;;;;;\n3289;CIRCLED IDEOGRAPH TEN;No;0;L;<circle> 5341;;;10;N;;;;;\n328A;CIRCLED IDEOGRAPH MOON;So;0;L;<circle> 6708;;;;N;;;;;\n328B;CIRCLED IDEOGRAPH FIRE;So;0;L;<circle> 706B;;;;N;;;;;\n328C;CIRCLED IDEOGRAPH WATER;So;0;L;<circle> 6C34;;;;N;;;;;\n328D;CIRCLED IDEOGRAPH WOOD;So;0;L;<circle> 6728;;;;N;;;;;\n328E;CIRCLED IDEOGRAPH METAL;So;0;L;<circle> 91D1;;;;N;;;;;\n328F;CIRCLED IDEOGRAPH EARTH;So;0;L;<circle> 571F;;;;N;;;;;\n3290;CIRCLED IDEOGRAPH SUN;So;0;L;<circle> 65E5;;;;N;;;;;\n3291;CIRCLED IDEOGRAPH STOCK;So;0;L;<circle> 682A;;;;N;;;;;\n3292;CIRCLED IDEOGRAPH HAVE;So;0;L;<circle> 6709;;;;N;;;;;\n3293;CIRCLED IDEOGRAPH SOCIETY;So;0;L;<circle> 793E;;;;N;;;;;\n3294;CIRCLED IDEOGRAPH NAME;So;0;L;<circle> 540D;;;;N;;;;;\n3295;CIRCLED IDEOGRAPH SPECIAL;So;0;L;<circle> 7279;;;;N;;;;;\n3296;CIRCLED IDEOGRAPH FINANCIAL;So;0;L;<circle> 8CA1;;;;N;;;;;\n3297;CIRCLED IDEOGRAPH CONGRATULATION;So;0;L;<circle> 795D;;;;N;;;;;\n3298;CIRCLED IDEOGRAPH LABOR;So;0;L;<circle> 52B4;;;;N;;;;;\n3299;CIRCLED IDEOGRAPH SECRET;So;0;L;<circle> 79D8;;;;N;;;;;\n329A;CIRCLED IDEOGRAPH MALE;So;0;L;<circle> 7537;;;;N;;;;;\n329B;CIRCLED IDEOGRAPH FEMALE;So;0;L;<circle> 5973;;;;N;;;;;\n329C;CIRCLED IDEOGRAPH SUITABLE;So;0;L;<circle> 9069;;;;N;;;;;\n329D;CIRCLED IDEOGRAPH EXCELLENT;So;0;L;<circle> 512A;;;;N;;;;;\n329E;CIRCLED IDEOGRAPH PRINT;So;0;L;<circle> 5370;;;;N;;;;;\n329F;CIRCLED IDEOGRAPH ATTENTION;So;0;L;<circle> 6CE8;;;;N;;;;;\n32A0;CIRCLED IDEOGRAPH ITEM;So;0;L;<circle> 9805;;;;N;;;;;\n32A1;CIRCLED IDEOGRAPH REST;So;0;L;<circle> 4F11;;;;N;;;;;\n32A2;CIRCLED IDEOGRAPH COPY;So;0;L;<circle> 5199;;;;N;;;;;\n32A3;CIRCLED IDEOGRAPH CORRECT;So;0;L;<circle> 6B63;;;;N;;;;;\n32A4;CIRCLED IDEOGRAPH HIGH;So;0;L;<circle> 4E0A;;;;N;;;;;\n32A5;CIRCLED IDEOGRAPH CENTRE;So;0;L;<circle> 4E2D;;;;N;CIRCLED IDEOGRAPH CENTER;;;;\n32A6;CIRCLED IDEOGRAPH LOW;So;0;L;<circle> 4E0B;;;;N;;;;;\n32A7;CIRCLED IDEOGRAPH LEFT;So;0;L;<circle> 5DE6;;;;N;;;;;\n32A8;CIRCLED IDEOGRAPH RIGHT;So;0;L;<circle> 53F3;;;;N;;;;;\n32A9;CIRCLED IDEOGRAPH MEDICINE;So;0;L;<circle> 533B;;;;N;;;;;\n32AA;CIRCLED IDEOGRAPH RELIGION;So;0;L;<circle> 5B97;;;;N;;;;;\n32AB;CIRCLED IDEOGRAPH STUDY;So;0;L;<circle> 5B66;;;;N;;;;;\n32AC;CIRCLED IDEOGRAPH SUPERVISE;So;0;L;<circle> 76E3;;;;N;;;;;\n32AD;CIRCLED IDEOGRAPH ENTERPRISE;So;0;L;<circle> 4F01;;;;N;;;;;\n32AE;CIRCLED IDEOGRAPH RESOURCE;So;0;L;<circle> 8CC7;;;;N;;;;;\n32AF;CIRCLED IDEOGRAPH ALLIANCE;So;0;L;<circle> 5354;;;;N;;;;;\n32B0;CIRCLED IDEOGRAPH NIGHT;So;0;L;<circle> 591C;;;;N;;;;;\n32B1;CIRCLED NUMBER THIRTY SIX;No;0;ON;<circle> 0033 0036;;;36;N;;;;;\n32B2;CIRCLED NUMBER THIRTY SEVEN;No;0;ON;<circle> 0033 0037;;;37;N;;;;;\n32B3;CIRCLED NUMBER THIRTY EIGHT;No;0;ON;<circle> 0033 0038;;;38;N;;;;;\n32B4;CIRCLED NUMBER THIRTY NINE;No;0;ON;<circle> 0033 0039;;;39;N;;;;;\n32B5;CIRCLED NUMBER FORTY;No;0;ON;<circle> 0034 0030;;;40;N;;;;;\n32B6;CIRCLED NUMBER FORTY ONE;No;0;ON;<circle> 0034 0031;;;41;N;;;;;\n32B7;CIRCLED NUMBER FORTY TWO;No;0;ON;<circle> 0034 0032;;;42;N;;;;;\n32B8;CIRCLED NUMBER FORTY THREE;No;0;ON;<circle> 0034 0033;;;43;N;;;;;\n32B9;CIRCLED NUMBER FORTY FOUR;No;0;ON;<circle> 0034 0034;;;44;N;;;;;\n32BA;CIRCLED NUMBER FORTY FIVE;No;0;ON;<circle> 0034 0035;;;45;N;;;;;\n32BB;CIRCLED NUMBER FORTY SIX;No;0;ON;<circle> 0034 0036;;;46;N;;;;;\n32BC;CIRCLED NUMBER FORTY SEVEN;No;0;ON;<circle> 0034 0037;;;47;N;;;;;\n32BD;CIRCLED NUMBER FORTY EIGHT;No;0;ON;<circle> 0034 0038;;;48;N;;;;;\n32BE;CIRCLED NUMBER FORTY NINE;No;0;ON;<circle> 0034 0039;;;49;N;;;;;\n32BF;CIRCLED NUMBER FIFTY;No;0;ON;<circle> 0035 0030;;;50;N;;;;;\n32C0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY;So;0;L;<compat> 0031 6708;;;;N;;;;;\n32C1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY;So;0;L;<compat> 0032 6708;;;;N;;;;;\n32C2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH;So;0;L;<compat> 0033 6708;;;;N;;;;;\n32C3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL;So;0;L;<compat> 0034 6708;;;;N;;;;;\n32C4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY;So;0;L;<compat> 0035 6708;;;;N;;;;;\n32C5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE;So;0;L;<compat> 0036 6708;;;;N;;;;;\n32C6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY;So;0;L;<compat> 0037 6708;;;;N;;;;;\n32C7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST;So;0;L;<compat> 0038 6708;;;;N;;;;;\n32C8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER;So;0;L;<compat> 0039 6708;;;;N;;;;;\n32C9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER;So;0;L;<compat> 0031 0030 6708;;;;N;;;;;\n32CA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER;So;0;L;<compat> 0031 0031 6708;;;;N;;;;;\n32CB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER;So;0;L;<compat> 0031 0032 6708;;;;N;;;;;\n32CC;SQUARE HG;So;0;ON;<square> 0048 0067;;;;N;;;;;\n32CD;SQUARE ERG;So;0;ON;<square> 0065 0072 0067;;;;N;;;;;\n32CE;SQUARE EV;So;0;ON;<square> 0065 0056;;;;N;;;;;\n32CF;LIMITED LIABILITY SIGN;So;0;ON;<square> 004C 0054 0044;;;;N;;;;;\n32D0;CIRCLED KATAKANA A;So;0;L;<circle> 30A2;;;;N;;;;;\n32D1;CIRCLED KATAKANA I;So;0;L;<circle> 30A4;;;;N;;;;;\n32D2;CIRCLED KATAKANA U;So;0;L;<circle> 30A6;;;;N;;;;;\n32D3;CIRCLED KATAKANA E;So;0;L;<circle> 30A8;;;;N;;;;;\n32D4;CIRCLED KATAKANA O;So;0;L;<circle> 30AA;;;;N;;;;;\n32D5;CIRCLED KATAKANA KA;So;0;L;<circle> 30AB;;;;N;;;;;\n32D6;CIRCLED KATAKANA KI;So;0;L;<circle> 30AD;;;;N;;;;;\n32D7;CIRCLED KATAKANA KU;So;0;L;<circle> 30AF;;;;N;;;;;\n32D8;CIRCLED KATAKANA KE;So;0;L;<circle> 30B1;;;;N;;;;;\n32D9;CIRCLED KATAKANA KO;So;0;L;<circle> 30B3;;;;N;;;;;\n32DA;CIRCLED KATAKANA SA;So;0;L;<circle> 30B5;;;;N;;;;;\n32DB;CIRCLED KATAKANA SI;So;0;L;<circle> 30B7;;;;N;;;;;\n32DC;CIRCLED KATAKANA SU;So;0;L;<circle> 30B9;;;;N;;;;;\n32DD;CIRCLED KATAKANA SE;So;0;L;<circle> 30BB;;;;N;;;;;\n32DE;CIRCLED KATAKANA SO;So;0;L;<circle> 30BD;;;;N;;;;;\n32DF;CIRCLED KATAKANA TA;So;0;L;<circle> 30BF;;;;N;;;;;\n32E0;CIRCLED KATAKANA TI;So;0;L;<circle> 30C1;;;;N;;;;;\n32E1;CIRCLED KATAKANA TU;So;0;L;<circle> 30C4;;;;N;;;;;\n32E2;CIRCLED KATAKANA TE;So;0;L;<circle> 30C6;;;;N;;;;;\n32E3;CIRCLED KATAKANA TO;So;0;L;<circle> 30C8;;;;N;;;;;\n32E4;CIRCLED KATAKANA NA;So;0;L;<circle> 30CA;;;;N;;;;;\n32E5;CIRCLED KATAKANA NI;So;0;L;<circle> 30CB;;;;N;;;;;\n32E6;CIRCLED KATAKANA NU;So;0;L;<circle> 30CC;;;;N;;;;;\n32E7;CIRCLED KATAKANA NE;So;0;L;<circle> 30CD;;;;N;;;;;\n32E8;CIRCLED KATAKANA NO;So;0;L;<circle> 30CE;;;;N;;;;;\n32E9;CIRCLED KATAKANA HA;So;0;L;<circle> 30CF;;;;N;;;;;\n32EA;CIRCLED KATAKANA HI;So;0;L;<circle> 30D2;;;;N;;;;;\n32EB;CIRCLED KATAKANA HU;So;0;L;<circle> 30D5;;;;N;;;;;\n32EC;CIRCLED KATAKANA HE;So;0;L;<circle> 30D8;;;;N;;;;;\n32ED;CIRCLED KATAKANA HO;So;0;L;<circle> 30DB;;;;N;;;;;\n32EE;CIRCLED KATAKANA MA;So;0;L;<circle> 30DE;;;;N;;;;;\n32EF;CIRCLED KATAKANA MI;So;0;L;<circle> 30DF;;;;N;;;;;\n32F0;CIRCLED KATAKANA MU;So;0;L;<circle> 30E0;;;;N;;;;;\n32F1;CIRCLED KATAKANA ME;So;0;L;<circle> 30E1;;;;N;;;;;\n32F2;CIRCLED KATAKANA MO;So;0;L;<circle> 30E2;;;;N;;;;;\n32F3;CIRCLED KATAKANA YA;So;0;L;<circle> 30E4;;;;N;;;;;\n32F4;CIRCLED KATAKANA YU;So;0;L;<circle> 30E6;;;;N;;;;;\n32F5;CIRCLED KATAKANA YO;So;0;L;<circle> 30E8;;;;N;;;;;\n32F6;CIRCLED KATAKANA RA;So;0;L;<circle> 30E9;;;;N;;;;;\n32F7;CIRCLED KATAKANA RI;So;0;L;<circle> 30EA;;;;N;;;;;\n32F8;CIRCLED KATAKANA RU;So;0;L;<circle> 30EB;;;;N;;;;;\n32F9;CIRCLED KATAKANA RE;So;0;L;<circle> 30EC;;;;N;;;;;\n32FA;CIRCLED KATAKANA RO;So;0;L;<circle> 30ED;;;;N;;;;;\n32FB;CIRCLED KATAKANA WA;So;0;L;<circle> 30EF;;;;N;;;;;\n32FC;CIRCLED KATAKANA WI;So;0;L;<circle> 30F0;;;;N;;;;;\n32FD;CIRCLED KATAKANA WE;So;0;L;<circle> 30F1;;;;N;;;;;\n32FE;CIRCLED KATAKANA WO;So;0;L;<circle> 30F2;;;;N;;;;;\n32FF;SQUARE ERA NAME REIWA;So;0;L;<square> 4EE4 548C;;;;N;;;;;\n3300;SQUARE APAATO;So;0;L;<square> 30A2 30D1 30FC 30C8;;;;N;SQUARED APAATO;;;;\n3301;SQUARE ARUHUA;So;0;L;<square> 30A2 30EB 30D5 30A1;;;;N;SQUARED ARUHUA;;;;\n3302;SQUARE ANPEA;So;0;L;<square> 30A2 30F3 30DA 30A2;;;;N;SQUARED ANPEA;;;;\n3303;SQUARE AARU;So;0;L;<square> 30A2 30FC 30EB;;;;N;SQUARED AARU;;;;\n3304;SQUARE ININGU;So;0;L;<square> 30A4 30CB 30F3 30B0;;;;N;SQUARED ININGU;;;;\n3305;SQUARE INTI;So;0;L;<square> 30A4 30F3 30C1;;;;N;SQUARED INTI;;;;\n3306;SQUARE UON;So;0;L;<square> 30A6 30A9 30F3;;;;N;SQUARED UON;;;;\n3307;SQUARE ESUKUUDO;So;0;L;<square> 30A8 30B9 30AF 30FC 30C9;;;;N;SQUARED ESUKUUDO;;;;\n3308;SQUARE EEKAA;So;0;L;<square> 30A8 30FC 30AB 30FC;;;;N;SQUARED EEKAA;;;;\n3309;SQUARE ONSU;So;0;L;<square> 30AA 30F3 30B9;;;;N;SQUARED ONSU;;;;\n330A;SQUARE OOMU;So;0;L;<square> 30AA 30FC 30E0;;;;N;SQUARED OOMU;;;;\n330B;SQUARE KAIRI;So;0;L;<square> 30AB 30A4 30EA;;;;N;SQUARED KAIRI;;;;\n330C;SQUARE KARATTO;So;0;L;<square> 30AB 30E9 30C3 30C8;;;;N;SQUARED KARATTO;;;;\n330D;SQUARE KARORII;So;0;L;<square> 30AB 30ED 30EA 30FC;;;;N;SQUARED KARORII;;;;\n330E;SQUARE GARON;So;0;L;<square> 30AC 30ED 30F3;;;;N;SQUARED GARON;;;;\n330F;SQUARE GANMA;So;0;L;<square> 30AC 30F3 30DE;;;;N;SQUARED GANMA;;;;\n3310;SQUARE GIGA;So;0;L;<square> 30AE 30AC;;;;N;SQUARED GIGA;;;;\n3311;SQUARE GINII;So;0;L;<square> 30AE 30CB 30FC;;;;N;SQUARED GINII;;;;\n3312;SQUARE KYURII;So;0;L;<square> 30AD 30E5 30EA 30FC;;;;N;SQUARED KYURII;;;;\n3313;SQUARE GIRUDAA;So;0;L;<square> 30AE 30EB 30C0 30FC;;;;N;SQUARED GIRUDAA;;;;\n3314;SQUARE KIRO;So;0;L;<square> 30AD 30ED;;;;N;SQUARED KIRO;;;;\n3315;SQUARE KIROGURAMU;So;0;L;<square> 30AD 30ED 30B0 30E9 30E0;;;;N;SQUARED KIROGURAMU;;;;\n3316;SQUARE KIROMEETORU;So;0;L;<square> 30AD 30ED 30E1 30FC 30C8 30EB;;;;N;SQUARED KIROMEETORU;;;;\n3317;SQUARE KIROWATTO;So;0;L;<square> 30AD 30ED 30EF 30C3 30C8;;;;N;SQUARED KIROWATTO;;;;\n3318;SQUARE GURAMU;So;0;L;<square> 30B0 30E9 30E0;;;;N;SQUARED GURAMU;;;;\n3319;SQUARE GURAMUTON;So;0;L;<square> 30B0 30E9 30E0 30C8 30F3;;;;N;SQUARED GURAMUTON;;;;\n331A;SQUARE KURUZEIRO;So;0;L;<square> 30AF 30EB 30BC 30A4 30ED;;;;N;SQUARED KURUZEIRO;;;;\n331B;SQUARE KUROONE;So;0;L;<square> 30AF 30ED 30FC 30CD;;;;N;SQUARED KUROONE;;;;\n331C;SQUARE KEESU;So;0;L;<square> 30B1 30FC 30B9;;;;N;SQUARED KEESU;;;;\n331D;SQUARE KORUNA;So;0;L;<square> 30B3 30EB 30CA;;;;N;SQUARED KORUNA;;;;\n331E;SQUARE KOOPO;So;0;L;<square> 30B3 30FC 30DD;;;;N;SQUARED KOOPO;;;;\n331F;SQUARE SAIKURU;So;0;L;<square> 30B5 30A4 30AF 30EB;;;;N;SQUARED SAIKURU;;;;\n3320;SQUARE SANTIIMU;So;0;L;<square> 30B5 30F3 30C1 30FC 30E0;;;;N;SQUARED SANTIIMU;;;;\n3321;SQUARE SIRINGU;So;0;L;<square> 30B7 30EA 30F3 30B0;;;;N;SQUARED SIRINGU;;;;\n3322;SQUARE SENTI;So;0;L;<square> 30BB 30F3 30C1;;;;N;SQUARED SENTI;;;;\n3323;SQUARE SENTO;So;0;L;<square> 30BB 30F3 30C8;;;;N;SQUARED SENTO;;;;\n3324;SQUARE DAASU;So;0;L;<square> 30C0 30FC 30B9;;;;N;SQUARED DAASU;;;;\n3325;SQUARE DESI;So;0;L;<square> 30C7 30B7;;;;N;SQUARED DESI;;;;\n3326;SQUARE DORU;So;0;L;<square> 30C9 30EB;;;;N;SQUARED DORU;;;;\n3327;SQUARE TON;So;0;L;<square> 30C8 30F3;;;;N;SQUARED TON;;;;\n3328;SQUARE NANO;So;0;L;<square> 30CA 30CE;;;;N;SQUARED NANO;;;;\n3329;SQUARE NOTTO;So;0;L;<square> 30CE 30C3 30C8;;;;N;SQUARED NOTTO;;;;\n332A;SQUARE HAITU;So;0;L;<square> 30CF 30A4 30C4;;;;N;SQUARED HAITU;;;;\n332B;SQUARE PAASENTO;So;0;L;<square> 30D1 30FC 30BB 30F3 30C8;;;;N;SQUARED PAASENTO;;;;\n332C;SQUARE PAATU;So;0;L;<square> 30D1 30FC 30C4;;;;N;SQUARED PAATU;;;;\n332D;SQUARE BAARERU;So;0;L;<square> 30D0 30FC 30EC 30EB;;;;N;SQUARED BAARERU;;;;\n332E;SQUARE PIASUTORU;So;0;L;<square> 30D4 30A2 30B9 30C8 30EB;;;;N;SQUARED PIASUTORU;;;;\n332F;SQUARE PIKURU;So;0;L;<square> 30D4 30AF 30EB;;;;N;SQUARED PIKURU;;;;\n3330;SQUARE PIKO;So;0;L;<square> 30D4 30B3;;;;N;SQUARED PIKO;;;;\n3331;SQUARE BIRU;So;0;L;<square> 30D3 30EB;;;;N;SQUARED BIRU;;;;\n3332;SQUARE HUARADDO;So;0;L;<square> 30D5 30A1 30E9 30C3 30C9;;;;N;SQUARED HUARADDO;;;;\n3333;SQUARE HUIITO;So;0;L;<square> 30D5 30A3 30FC 30C8;;;;N;SQUARED HUIITO;;;;\n3334;SQUARE BUSSYERU;So;0;L;<square> 30D6 30C3 30B7 30A7 30EB;;;;N;SQUARED BUSSYERU;;;;\n3335;SQUARE HURAN;So;0;L;<square> 30D5 30E9 30F3;;;;N;SQUARED HURAN;;;;\n3336;SQUARE HEKUTAARU;So;0;L;<square> 30D8 30AF 30BF 30FC 30EB;;;;N;SQUARED HEKUTAARU;;;;\n3337;SQUARE PESO;So;0;L;<square> 30DA 30BD;;;;N;SQUARED PESO;;;;\n3338;SQUARE PENIHI;So;0;L;<square> 30DA 30CB 30D2;;;;N;SQUARED PENIHI;;;;\n3339;SQUARE HERUTU;So;0;L;<square> 30D8 30EB 30C4;;;;N;SQUARED HERUTU;;;;\n333A;SQUARE PENSU;So;0;L;<square> 30DA 30F3 30B9;;;;N;SQUARED PENSU;;;;\n333B;SQUARE PEEZI;So;0;L;<square> 30DA 30FC 30B8;;;;N;SQUARED PEEZI;;;;\n333C;SQUARE BEETA;So;0;L;<square> 30D9 30FC 30BF;;;;N;SQUARED BEETA;;;;\n333D;SQUARE POINTO;So;0;L;<square> 30DD 30A4 30F3 30C8;;;;N;SQUARED POINTO;;;;\n333E;SQUARE BORUTO;So;0;L;<square> 30DC 30EB 30C8;;;;N;SQUARED BORUTO;;;;\n333F;SQUARE HON;So;0;L;<square> 30DB 30F3;;;;N;SQUARED HON;;;;\n3340;SQUARE PONDO;So;0;L;<square> 30DD 30F3 30C9;;;;N;SQUARED PONDO;;;;\n3341;SQUARE HOORU;So;0;L;<square> 30DB 30FC 30EB;;;;N;SQUARED HOORU;;;;\n3342;SQUARE HOON;So;0;L;<square> 30DB 30FC 30F3;;;;N;SQUARED HOON;;;;\n3343;SQUARE MAIKURO;So;0;L;<square> 30DE 30A4 30AF 30ED;;;;N;SQUARED MAIKURO;;;;\n3344;SQUARE MAIRU;So;0;L;<square> 30DE 30A4 30EB;;;;N;SQUARED MAIRU;;;;\n3345;SQUARE MAHHA;So;0;L;<square> 30DE 30C3 30CF;;;;N;SQUARED MAHHA;;;;\n3346;SQUARE MARUKU;So;0;L;<square> 30DE 30EB 30AF;;;;N;SQUARED MARUKU;;;;\n3347;SQUARE MANSYON;So;0;L;<square> 30DE 30F3 30B7 30E7 30F3;;;;N;SQUARED MANSYON;;;;\n3348;SQUARE MIKURON;So;0;L;<square> 30DF 30AF 30ED 30F3;;;;N;SQUARED MIKURON;;;;\n3349;SQUARE MIRI;So;0;L;<square> 30DF 30EA;;;;N;SQUARED MIRI;;;;\n334A;SQUARE MIRIBAARU;So;0;L;<square> 30DF 30EA 30D0 30FC 30EB;;;;N;SQUARED MIRIBAARU;;;;\n334B;SQUARE MEGA;So;0;L;<square> 30E1 30AC;;;;N;SQUARED MEGA;;;;\n334C;SQUARE MEGATON;So;0;L;<square> 30E1 30AC 30C8 30F3;;;;N;SQUARED MEGATON;;;;\n334D;SQUARE MEETORU;So;0;L;<square> 30E1 30FC 30C8 30EB;;;;N;SQUARED MEETORU;;;;\n334E;SQUARE YAADO;So;0;L;<square> 30E4 30FC 30C9;;;;N;SQUARED YAADO;;;;\n334F;SQUARE YAARU;So;0;L;<square> 30E4 30FC 30EB;;;;N;SQUARED YAARU;;;;\n3350;SQUARE YUAN;So;0;L;<square> 30E6 30A2 30F3;;;;N;SQUARED YUAN;;;;\n3351;SQUARE RITTORU;So;0;L;<square> 30EA 30C3 30C8 30EB;;;;N;SQUARED RITTORU;;;;\n3352;SQUARE RIRA;So;0;L;<square> 30EA 30E9;;;;N;SQUARED RIRA;;;;\n3353;SQUARE RUPII;So;0;L;<square> 30EB 30D4 30FC;;;;N;SQUARED RUPII;;;;\n3354;SQUARE RUUBURU;So;0;L;<square> 30EB 30FC 30D6 30EB;;;;N;SQUARED RUUBURU;;;;\n3355;SQUARE REMU;So;0;L;<square> 30EC 30E0;;;;N;SQUARED REMU;;;;\n3356;SQUARE RENTOGEN;So;0;L;<square> 30EC 30F3 30C8 30B2 30F3;;;;N;SQUARED RENTOGEN;;;;\n3357;SQUARE WATTO;So;0;L;<square> 30EF 30C3 30C8;;;;N;SQUARED WATTO;;;;\n3358;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO;So;0;L;<compat> 0030 70B9;;;;N;;;;;\n3359;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE;So;0;L;<compat> 0031 70B9;;;;N;;;;;\n335A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO;So;0;L;<compat> 0032 70B9;;;;N;;;;;\n335B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE;So;0;L;<compat> 0033 70B9;;;;N;;;;;\n335C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR;So;0;L;<compat> 0034 70B9;;;;N;;;;;\n335D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE;So;0;L;<compat> 0035 70B9;;;;N;;;;;\n335E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX;So;0;L;<compat> 0036 70B9;;;;N;;;;;\n335F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN;So;0;L;<compat> 0037 70B9;;;;N;;;;;\n3360;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT;So;0;L;<compat> 0038 70B9;;;;N;;;;;\n3361;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE;So;0;L;<compat> 0039 70B9;;;;N;;;;;\n3362;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN;So;0;L;<compat> 0031 0030 70B9;;;;N;;;;;\n3363;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN;So;0;L;<compat> 0031 0031 70B9;;;;N;;;;;\n3364;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE;So;0;L;<compat> 0031 0032 70B9;;;;N;;;;;\n3365;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN;So;0;L;<compat> 0031 0033 70B9;;;;N;;;;;\n3366;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN;So;0;L;<compat> 0031 0034 70B9;;;;N;;;;;\n3367;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN;So;0;L;<compat> 0031 0035 70B9;;;;N;;;;;\n3368;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN;So;0;L;<compat> 0031 0036 70B9;;;;N;;;;;\n3369;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN;So;0;L;<compat> 0031 0037 70B9;;;;N;;;;;\n336A;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN;So;0;L;<compat> 0031 0038 70B9;;;;N;;;;;\n336B;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN;So;0;L;<compat> 0031 0039 70B9;;;;N;;;;;\n336C;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY;So;0;L;<compat> 0032 0030 70B9;;;;N;;;;;\n336D;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE;So;0;L;<compat> 0032 0031 70B9;;;;N;;;;;\n336E;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO;So;0;L;<compat> 0032 0032 70B9;;;;N;;;;;\n336F;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE;So;0;L;<compat> 0032 0033 70B9;;;;N;;;;;\n3370;IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR;So;0;L;<compat> 0032 0034 70B9;;;;N;;;;;\n3371;SQUARE HPA;So;0;L;<square> 0068 0050 0061;;;;N;;;;;\n3372;SQUARE DA;So;0;L;<square> 0064 0061;;;;N;;;;;\n3373;SQUARE AU;So;0;L;<square> 0041 0055;;;;N;;;;;\n3374;SQUARE BAR;So;0;L;<square> 0062 0061 0072;;;;N;;;;;\n3375;SQUARE OV;So;0;L;<square> 006F 0056;;;;N;;;;;\n3376;SQUARE PC;So;0;L;<square> 0070 0063;;;;N;;;;;\n3377;SQUARE DM;So;0;ON;<square> 0064 006D;;;;N;;;;;\n3378;SQUARE DM SQUARED;So;0;ON;<square> 0064 006D 00B2;;;;N;;;;;\n3379;SQUARE DM CUBED;So;0;ON;<square> 0064 006D 00B3;;;;N;;;;;\n337A;SQUARE IU;So;0;ON;<square> 0049 0055;;;;N;;;;;\n337B;SQUARE ERA NAME HEISEI;So;0;L;<square> 5E73 6210;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME HEISEI;;;;\n337C;SQUARE ERA NAME SYOUWA;So;0;L;<square> 662D 548C;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME SYOUWA;;;;\n337D;SQUARE ERA NAME TAISYOU;So;0;L;<square> 5927 6B63;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME TAISYOU;;;;\n337E;SQUARE ERA NAME MEIZI;So;0;L;<square> 660E 6CBB;;;;N;SQUARED TWO IDEOGRAPHS ERA NAME MEIZI;;;;\n337F;SQUARE CORPORATION;So;0;L;<square> 682A 5F0F 4F1A 793E;;;;N;SQUARED FOUR IDEOGRAPHS CORPORATION;;;;\n3380;SQUARE PA AMPS;So;0;L;<square> 0070 0041;;;;N;SQUARED PA AMPS;;;;\n3381;SQUARE NA;So;0;L;<square> 006E 0041;;;;N;SQUARED NA;;;;\n3382;SQUARE MU A;So;0;L;<square> 03BC 0041;;;;N;SQUARED MU A;;;;\n3383;SQUARE MA;So;0;L;<square> 006D 0041;;;;N;SQUARED MA;;;;\n3384;SQUARE KA;So;0;L;<square> 006B 0041;;;;N;SQUARED KA;;;;\n3385;SQUARE KB;So;0;L;<square> 004B 0042;;;;N;SQUARED KB;;;;\n3386;SQUARE MB;So;0;L;<square> 004D 0042;;;;N;SQUARED MB;;;;\n3387;SQUARE GB;So;0;L;<square> 0047 0042;;;;N;SQUARED GB;;;;\n3388;SQUARE CAL;So;0;L;<square> 0063 0061 006C;;;;N;SQUARED CAL;;;;\n3389;SQUARE KCAL;So;0;L;<square> 006B 0063 0061 006C;;;;N;SQUARED KCAL;;;;\n338A;SQUARE PF;So;0;L;<square> 0070 0046;;;;N;SQUARED PF;;;;\n338B;SQUARE NF;So;0;L;<square> 006E 0046;;;;N;SQUARED NF;;;;\n338C;SQUARE MU F;So;0;L;<square> 03BC 0046;;;;N;SQUARED MU F;;;;\n338D;SQUARE MU G;So;0;L;<square> 03BC 0067;;;;N;SQUARED MU G;;;;\n338E;SQUARE MG;So;0;L;<square> 006D 0067;;;;N;SQUARED MG;;;;\n338F;SQUARE KG;So;0;L;<square> 006B 0067;;;;N;SQUARED KG;;;;\n3390;SQUARE HZ;So;0;L;<square> 0048 007A;;;;N;SQUARED HZ;;;;\n3391;SQUARE KHZ;So;0;L;<square> 006B 0048 007A;;;;N;SQUARED KHZ;;;;\n3392;SQUARE MHZ;So;0;L;<square> 004D 0048 007A;;;;N;SQUARED MHZ;;;;\n3393;SQUARE GHZ;So;0;L;<square> 0047 0048 007A;;;;N;SQUARED GHZ;;;;\n3394;SQUARE THZ;So;0;L;<square> 0054 0048 007A;;;;N;SQUARED THZ;;;;\n3395;SQUARE MU L;So;0;L;<square> 03BC 2113;;;;N;SQUARED MU L;;;;\n3396;SQUARE ML;So;0;L;<square> 006D 2113;;;;N;SQUARED ML;;;;\n3397;SQUARE DL;So;0;L;<square> 0064 2113;;;;N;SQUARED DL;;;;\n3398;SQUARE KL;So;0;L;<square> 006B 2113;;;;N;SQUARED KL;;;;\n3399;SQUARE FM;So;0;L;<square> 0066 006D;;;;N;SQUARED FM;;;;\n339A;SQUARE NM;So;0;L;<square> 006E 006D;;;;N;SQUARED NM;;;;\n339B;SQUARE MU M;So;0;L;<square> 03BC 006D;;;;N;SQUARED MU M;;;;\n339C;SQUARE MM;So;0;L;<square> 006D 006D;;;;N;SQUARED MM;;;;\n339D;SQUARE CM;So;0;L;<square> 0063 006D;;;;N;SQUARED CM;;;;\n339E;SQUARE KM;So;0;L;<square> 006B 006D;;;;N;SQUARED KM;;;;\n339F;SQUARE MM SQUARED;So;0;L;<square> 006D 006D 00B2;;;;N;SQUARED MM SQUARED;;;;\n33A0;SQUARE CM SQUARED;So;0;L;<square> 0063 006D 00B2;;;;N;SQUARED CM SQUARED;;;;\n33A1;SQUARE M SQUARED;So;0;L;<square> 006D 00B2;;;;N;SQUARED M SQUARED;;;;\n33A2;SQUARE KM SQUARED;So;0;L;<square> 006B 006D 00B2;;;;N;SQUARED KM SQUARED;;;;\n33A3;SQUARE MM CUBED;So;0;L;<square> 006D 006D 00B3;;;;N;SQUARED MM CUBED;;;;\n33A4;SQUARE CM CUBED;So;0;L;<square> 0063 006D 00B3;;;;N;SQUARED CM CUBED;;;;\n33A5;SQUARE M CUBED;So;0;L;<square> 006D 00B3;;;;N;SQUARED M CUBED;;;;\n33A6;SQUARE KM CUBED;So;0;L;<square> 006B 006D 00B3;;;;N;SQUARED KM CUBED;;;;\n33A7;SQUARE M OVER S;So;0;L;<square> 006D 2215 0073;;;;N;SQUARED M OVER S;;;;\n33A8;SQUARE M OVER S SQUARED;So;0;L;<square> 006D 2215 0073 00B2;;;;N;SQUARED M OVER S SQUARED;;;;\n33A9;SQUARE PA;So;0;L;<square> 0050 0061;;;;N;SQUARED PA;;;;\n33AA;SQUARE KPA;So;0;L;<square> 006B 0050 0061;;;;N;SQUARED KPA;;;;\n33AB;SQUARE MPA;So;0;L;<square> 004D 0050 0061;;;;N;SQUARED MPA;;;;\n33AC;SQUARE GPA;So;0;L;<square> 0047 0050 0061;;;;N;SQUARED GPA;;;;\n33AD;SQUARE RAD;So;0;L;<square> 0072 0061 0064;;;;N;SQUARED RAD;;;;\n33AE;SQUARE RAD OVER S;So;0;L;<square> 0072 0061 0064 2215 0073;;;;N;SQUARED RAD OVER S;;;;\n33AF;SQUARE RAD OVER S SQUARED;So;0;L;<square> 0072 0061 0064 2215 0073 00B2;;;;N;SQUARED RAD OVER S SQUARED;;;;\n33B0;SQUARE PS;So;0;L;<square> 0070 0073;;;;N;SQUARED PS;;;;\n33B1;SQUARE NS;So;0;L;<square> 006E 0073;;;;N;SQUARED NS;;;;\n33B2;SQUARE MU S;So;0;L;<square> 03BC 0073;;;;N;SQUARED MU S;;;;\n33B3;SQUARE MS;So;0;L;<square> 006D 0073;;;;N;SQUARED MS;;;;\n33B4;SQUARE PV;So;0;L;<square> 0070 0056;;;;N;SQUARED PV;;;;\n33B5;SQUARE NV;So;0;L;<square> 006E 0056;;;;N;SQUARED NV;;;;\n33B6;SQUARE MU V;So;0;L;<square> 03BC 0056;;;;N;SQUARED MU V;;;;\n33B7;SQUARE MV;So;0;L;<square> 006D 0056;;;;N;SQUARED MV;;;;\n33B8;SQUARE KV;So;0;L;<square> 006B 0056;;;;N;SQUARED KV;;;;\n33B9;SQUARE MV MEGA;So;0;L;<square> 004D 0056;;;;N;SQUARED MV MEGA;;;;\n33BA;SQUARE PW;So;0;L;<square> 0070 0057;;;;N;SQUARED PW;;;;\n33BB;SQUARE NW;So;0;L;<square> 006E 0057;;;;N;SQUARED NW;;;;\n33BC;SQUARE MU W;So;0;L;<square> 03BC 0057;;;;N;SQUARED MU W;;;;\n33BD;SQUARE MW;So;0;L;<square> 006D 0057;;;;N;SQUARED MW;;;;\n33BE;SQUARE KW;So;0;L;<square> 006B 0057;;;;N;SQUARED KW;;;;\n33BF;SQUARE MW MEGA;So;0;L;<square> 004D 0057;;;;N;SQUARED MW MEGA;;;;\n33C0;SQUARE K OHM;So;0;L;<square> 006B 03A9;;;;N;SQUARED K OHM;;;;\n33C1;SQUARE M OHM;So;0;L;<square> 004D 03A9;;;;N;SQUARED M OHM;;;;\n33C2;SQUARE AM;So;0;L;<square> 0061 002E 006D 002E;;;;N;SQUARED AM;;;;\n33C3;SQUARE BQ;So;0;L;<square> 0042 0071;;;;N;SQUARED BQ;;;;\n33C4;SQUARE CC;So;0;L;<square> 0063 0063;;;;N;SQUARED CC;;;;\n33C5;SQUARE CD;So;0;L;<square> 0063 0064;;;;N;SQUARED CD;;;;\n33C6;SQUARE C OVER KG;So;0;L;<square> 0043 2215 006B 0067;;;;N;SQUARED C OVER KG;;;;\n33C7;SQUARE CO;So;0;L;<square> 0043 006F 002E;;;;N;SQUARED CO;;;;\n33C8;SQUARE DB;So;0;L;<square> 0064 0042;;;;N;SQUARED DB;;;;\n33C9;SQUARE GY;So;0;L;<square> 0047 0079;;;;N;SQUARED GY;;;;\n33CA;SQUARE HA;So;0;L;<square> 0068 0061;;;;N;SQUARED HA;;;;\n33CB;SQUARE HP;So;0;L;<square> 0048 0050;;;;N;SQUARED HP;;;;\n33CC;SQUARE IN;So;0;L;<square> 0069 006E;;;;N;SQUARED IN;;;;\n33CD;SQUARE KK;So;0;L;<square> 004B 004B;;;;N;SQUARED KK;;;;\n33CE;SQUARE KM CAPITAL;So;0;L;<square> 004B 004D;;;;N;SQUARED KM CAPITAL;;;;\n33CF;SQUARE KT;So;0;L;<square> 006B 0074;;;;N;SQUARED KT;;;;\n33D0;SQUARE LM;So;0;L;<square> 006C 006D;;;;N;SQUARED LM;;;;\n33D1;SQUARE LN;So;0;L;<square> 006C 006E;;;;N;SQUARED LN;;;;\n33D2;SQUARE LOG;So;0;L;<square> 006C 006F 0067;;;;N;SQUARED LOG;;;;\n33D3;SQUARE LX;So;0;L;<square> 006C 0078;;;;N;SQUARED LX;;;;\n33D4;SQUARE MB SMALL;So;0;L;<square> 006D 0062;;;;N;SQUARED MB SMALL;;;;\n33D5;SQUARE MIL;So;0;L;<square> 006D 0069 006C;;;;N;SQUARED MIL;;;;\n33D6;SQUARE MOL;So;0;L;<square> 006D 006F 006C;;;;N;SQUARED MOL;;;;\n33D7;SQUARE PH;So;0;L;<square> 0050 0048;;;;N;SQUARED PH;;;;\n33D8;SQUARE PM;So;0;L;<square> 0070 002E 006D 002E;;;;N;SQUARED PM;;;;\n33D9;SQUARE PPM;So;0;L;<square> 0050 0050 004D;;;;N;SQUARED PPM;;;;\n33DA;SQUARE PR;So;0;L;<square> 0050 0052;;;;N;SQUARED PR;;;;\n33DB;SQUARE SR;So;0;L;<square> 0073 0072;;;;N;SQUARED SR;;;;\n33DC;SQUARE SV;So;0;L;<square> 0053 0076;;;;N;SQUARED SV;;;;\n33DD;SQUARE WB;So;0;L;<square> 0057 0062;;;;N;SQUARED WB;;;;\n33DE;SQUARE V OVER M;So;0;ON;<square> 0056 2215 006D;;;;N;;;;;\n33DF;SQUARE A OVER M;So;0;ON;<square> 0041 2215 006D;;;;N;;;;;\n33E0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE;So;0;L;<compat> 0031 65E5;;;;N;;;;;\n33E1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO;So;0;L;<compat> 0032 65E5;;;;N;;;;;\n33E2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE;So;0;L;<compat> 0033 65E5;;;;N;;;;;\n33E3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR;So;0;L;<compat> 0034 65E5;;;;N;;;;;\n33E4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE;So;0;L;<compat> 0035 65E5;;;;N;;;;;\n33E5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX;So;0;L;<compat> 0036 65E5;;;;N;;;;;\n33E6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN;So;0;L;<compat> 0037 65E5;;;;N;;;;;\n33E7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT;So;0;L;<compat> 0038 65E5;;;;N;;;;;\n33E8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE;So;0;L;<compat> 0039 65E5;;;;N;;;;;\n33E9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN;So;0;L;<compat> 0031 0030 65E5;;;;N;;;;;\n33EA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN;So;0;L;<compat> 0031 0031 65E5;;;;N;;;;;\n33EB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE;So;0;L;<compat> 0031 0032 65E5;;;;N;;;;;\n33EC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN;So;0;L;<compat> 0031 0033 65E5;;;;N;;;;;\n33ED;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN;So;0;L;<compat> 0031 0034 65E5;;;;N;;;;;\n33EE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN;So;0;L;<compat> 0031 0035 65E5;;;;N;;;;;\n33EF;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN;So;0;L;<compat> 0031 0036 65E5;;;;N;;;;;\n33F0;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN;So;0;L;<compat> 0031 0037 65E5;;;;N;;;;;\n33F1;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN;So;0;L;<compat> 0031 0038 65E5;;;;N;;;;;\n33F2;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN;So;0;L;<compat> 0031 0039 65E5;;;;N;;;;;\n33F3;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY;So;0;L;<compat> 0032 0030 65E5;;;;N;;;;;\n33F4;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE;So;0;L;<compat> 0032 0031 65E5;;;;N;;;;;\n33F5;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO;So;0;L;<compat> 0032 0032 65E5;;;;N;;;;;\n33F6;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE;So;0;L;<compat> 0032 0033 65E5;;;;N;;;;;\n33F7;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR;So;0;L;<compat> 0032 0034 65E5;;;;N;;;;;\n33F8;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE;So;0;L;<compat> 0032 0035 65E5;;;;N;;;;;\n33F9;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX;So;0;L;<compat> 0032 0036 65E5;;;;N;;;;;\n33FA;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN;So;0;L;<compat> 0032 0037 65E5;;;;N;;;;;\n33FB;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT;So;0;L;<compat> 0032 0038 65E5;;;;N;;;;;\n33FC;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE;So;0;L;<compat> 0032 0039 65E5;;;;N;;;;;\n33FD;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY;So;0;L;<compat> 0033 0030 65E5;;;;N;;;;;\n33FE;IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE;So;0;L;<compat> 0033 0031 65E5;;;;N;;;;;\n33FF;SQUARE GAL;So;0;ON;<square> 0067 0061 006C;;;;N;;;;;\n3400;<CJK Ideograph Extension A, First>;Lo;0;L;;;;;N;;;;;\n4DB5;<CJK Ideograph Extension A, Last>;Lo;0;L;;;;;N;;;;;\n4DC0;HEXAGRAM FOR THE CREATIVE HEAVEN;So;0;ON;;;;;N;;;;;\n4DC1;HEXAGRAM FOR THE RECEPTIVE EARTH;So;0;ON;;;;;N;;;;;\n4DC2;HEXAGRAM FOR DIFFICULTY AT THE BEGINNING;So;0;ON;;;;;N;;;;;\n4DC3;HEXAGRAM FOR YOUTHFUL FOLLY;So;0;ON;;;;;N;;;;;\n4DC4;HEXAGRAM FOR WAITING;So;0;ON;;;;;N;;;;;\n4DC5;HEXAGRAM FOR CONFLICT;So;0;ON;;;;;N;;;;;\n4DC6;HEXAGRAM FOR THE ARMY;So;0;ON;;;;;N;;;;;\n4DC7;HEXAGRAM FOR HOLDING TOGETHER;So;0;ON;;;;;N;;;;;\n4DC8;HEXAGRAM FOR SMALL TAMING;So;0;ON;;;;;N;;;;;\n4DC9;HEXAGRAM FOR TREADING;So;0;ON;;;;;N;;;;;\n4DCA;HEXAGRAM FOR PEACE;So;0;ON;;;;;N;;;;;\n4DCB;HEXAGRAM FOR STANDSTILL;So;0;ON;;;;;N;;;;;\n4DCC;HEXAGRAM FOR FELLOWSHIP;So;0;ON;;;;;N;;;;;\n4DCD;HEXAGRAM FOR GREAT POSSESSION;So;0;ON;;;;;N;;;;;\n4DCE;HEXAGRAM FOR MODESTY;So;0;ON;;;;;N;;;;;\n4DCF;HEXAGRAM FOR ENTHUSIASM;So;0;ON;;;;;N;;;;;\n4DD0;HEXAGRAM FOR FOLLOWING;So;0;ON;;;;;N;;;;;\n4DD1;HEXAGRAM FOR WORK ON THE DECAYED;So;0;ON;;;;;N;;;;;\n4DD2;HEXAGRAM FOR APPROACH;So;0;ON;;;;;N;;;;;\n4DD3;HEXAGRAM FOR CONTEMPLATION;So;0;ON;;;;;N;;;;;\n4DD4;HEXAGRAM FOR BITING THROUGH;So;0;ON;;;;;N;;;;;\n4DD5;HEXAGRAM FOR GRACE;So;0;ON;;;;;N;;;;;\n4DD6;HEXAGRAM FOR SPLITTING APART;So;0;ON;;;;;N;;;;;\n4DD7;HEXAGRAM FOR RETURN;So;0;ON;;;;;N;;;;;\n4DD8;HEXAGRAM FOR INNOCENCE;So;0;ON;;;;;N;;;;;\n4DD9;HEXAGRAM FOR GREAT TAMING;So;0;ON;;;;;N;;;;;\n4DDA;HEXAGRAM FOR MOUTH CORNERS;So;0;ON;;;;;N;;;;;\n4DDB;HEXAGRAM FOR GREAT PREPONDERANCE;So;0;ON;;;;;N;;;;;\n4DDC;HEXAGRAM FOR THE ABYSMAL WATER;So;0;ON;;;;;N;;;;;\n4DDD;HEXAGRAM FOR THE CLINGING FIRE;So;0;ON;;;;;N;;;;;\n4DDE;HEXAGRAM FOR INFLUENCE;So;0;ON;;;;;N;;;;;\n4DDF;HEXAGRAM FOR DURATION;So;0;ON;;;;;N;;;;;\n4DE0;HEXAGRAM FOR RETREAT;So;0;ON;;;;;N;;;;;\n4DE1;HEXAGRAM FOR GREAT POWER;So;0;ON;;;;;N;;;;;\n4DE2;HEXAGRAM FOR PROGRESS;So;0;ON;;;;;N;;;;;\n4DE3;HEXAGRAM FOR DARKENING OF THE LIGHT;So;0;ON;;;;;N;;;;;\n4DE4;HEXAGRAM FOR THE FAMILY;So;0;ON;;;;;N;;;;;\n4DE5;HEXAGRAM FOR OPPOSITION;So;0;ON;;;;;N;;;;;\n4DE6;HEXAGRAM FOR OBSTRUCTION;So;0;ON;;;;;N;;;;;\n4DE7;HEXAGRAM FOR DELIVERANCE;So;0;ON;;;;;N;;;;;\n4DE8;HEXAGRAM FOR DECREASE;So;0;ON;;;;;N;;;;;\n4DE9;HEXAGRAM FOR INCREASE;So;0;ON;;;;;N;;;;;\n4DEA;HEXAGRAM FOR BREAKTHROUGH;So;0;ON;;;;;N;;;;;\n4DEB;HEXAGRAM FOR COMING TO MEET;So;0;ON;;;;;N;;;;;\n4DEC;HEXAGRAM FOR GATHERING TOGETHER;So;0;ON;;;;;N;;;;;\n4DED;HEXAGRAM FOR PUSHING UPWARD;So;0;ON;;;;;N;;;;;\n4DEE;HEXAGRAM FOR OPPRESSION;So;0;ON;;;;;N;;;;;\n4DEF;HEXAGRAM FOR THE WELL;So;0;ON;;;;;N;;;;;\n4DF0;HEXAGRAM FOR REVOLUTION;So;0;ON;;;;;N;;;;;\n4DF1;HEXAGRAM FOR THE CAULDRON;So;0;ON;;;;;N;;;;;\n4DF2;HEXAGRAM FOR THE AROUSING THUNDER;So;0;ON;;;;;N;;;;;\n4DF3;HEXAGRAM FOR THE KEEPING STILL MOUNTAIN;So;0;ON;;;;;N;;;;;\n4DF4;HEXAGRAM FOR DEVELOPMENT;So;0;ON;;;;;N;;;;;\n4DF5;HEXAGRAM FOR THE MARRYING MAIDEN;So;0;ON;;;;;N;;;;;\n4DF6;HEXAGRAM FOR ABUNDANCE;So;0;ON;;;;;N;;;;;\n4DF7;HEXAGRAM FOR THE WANDERER;So;0;ON;;;;;N;;;;;\n4DF8;HEXAGRAM FOR THE GENTLE WIND;So;0;ON;;;;;N;;;;;\n4DF9;HEXAGRAM FOR THE JOYOUS LAKE;So;0;ON;;;;;N;;;;;\n4DFA;HEXAGRAM FOR DISPERSION;So;0;ON;;;;;N;;;;;\n4DFB;HEXAGRAM FOR LIMITATION;So;0;ON;;;;;N;;;;;\n4DFC;HEXAGRAM FOR INNER TRUTH;So;0;ON;;;;;N;;;;;\n4DFD;HEXAGRAM FOR SMALL PREPONDERANCE;So;0;ON;;;;;N;;;;;\n4DFE;HEXAGRAM FOR AFTER COMPLETION;So;0;ON;;;;;N;;;;;\n4DFF;HEXAGRAM FOR BEFORE COMPLETION;So;0;ON;;;;;N;;;;;\n4E00;<CJK Ideograph, First>;Lo;0;L;;;;;N;;;;;\n9FEF;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;\nA000;YI SYLLABLE IT;Lo;0;L;;;;;N;;;;;\nA001;YI SYLLABLE IX;Lo;0;L;;;;;N;;;;;\nA002;YI SYLLABLE I;Lo;0;L;;;;;N;;;;;\nA003;YI SYLLABLE IP;Lo;0;L;;;;;N;;;;;\nA004;YI SYLLABLE IET;Lo;0;L;;;;;N;;;;;\nA005;YI SYLLABLE IEX;Lo;0;L;;;;;N;;;;;\nA006;YI SYLLABLE IE;Lo;0;L;;;;;N;;;;;\nA007;YI SYLLABLE IEP;Lo;0;L;;;;;N;;;;;\nA008;YI SYLLABLE AT;Lo;0;L;;;;;N;;;;;\nA009;YI SYLLABLE AX;Lo;0;L;;;;;N;;;;;\nA00A;YI SYLLABLE A;Lo;0;L;;;;;N;;;;;\nA00B;YI SYLLABLE AP;Lo;0;L;;;;;N;;;;;\nA00C;YI SYLLABLE UOX;Lo;0;L;;;;;N;;;;;\nA00D;YI SYLLABLE UO;Lo;0;L;;;;;N;;;;;\nA00E;YI SYLLABLE UOP;Lo;0;L;;;;;N;;;;;\nA00F;YI SYLLABLE OT;Lo;0;L;;;;;N;;;;;\nA010;YI SYLLABLE OX;Lo;0;L;;;;;N;;;;;\nA011;YI SYLLABLE O;Lo;0;L;;;;;N;;;;;\nA012;YI SYLLABLE OP;Lo;0;L;;;;;N;;;;;\nA013;YI SYLLABLE EX;Lo;0;L;;;;;N;;;;;\nA014;YI SYLLABLE E;Lo;0;L;;;;;N;;;;;\nA015;YI SYLLABLE WU;Lm;0;L;;;;;N;;;;;\nA016;YI SYLLABLE BIT;Lo;0;L;;;;;N;;;;;\nA017;YI SYLLABLE BIX;Lo;0;L;;;;;N;;;;;\nA018;YI SYLLABLE BI;Lo;0;L;;;;;N;;;;;\nA019;YI SYLLABLE BIP;Lo;0;L;;;;;N;;;;;\nA01A;YI SYLLABLE BIET;Lo;0;L;;;;;N;;;;;\nA01B;YI SYLLABLE BIEX;Lo;0;L;;;;;N;;;;;\nA01C;YI SYLLABLE BIE;Lo;0;L;;;;;N;;;;;\nA01D;YI SYLLABLE BIEP;Lo;0;L;;;;;N;;;;;\nA01E;YI SYLLABLE BAT;Lo;0;L;;;;;N;;;;;\nA01F;YI SYLLABLE BAX;Lo;0;L;;;;;N;;;;;\nA020;YI SYLLABLE BA;Lo;0;L;;;;;N;;;;;\nA021;YI SYLLABLE BAP;Lo;0;L;;;;;N;;;;;\nA022;YI SYLLABLE BUOX;Lo;0;L;;;;;N;;;;;\nA023;YI SYLLABLE BUO;Lo;0;L;;;;;N;;;;;\nA024;YI SYLLABLE BUOP;Lo;0;L;;;;;N;;;;;\nA025;YI SYLLABLE BOT;Lo;0;L;;;;;N;;;;;\nA026;YI SYLLABLE BOX;Lo;0;L;;;;;N;;;;;\nA027;YI SYLLABLE BO;Lo;0;L;;;;;N;;;;;\nA028;YI SYLLABLE BOP;Lo;0;L;;;;;N;;;;;\nA029;YI SYLLABLE BEX;Lo;0;L;;;;;N;;;;;\nA02A;YI SYLLABLE BE;Lo;0;L;;;;;N;;;;;\nA02B;YI SYLLABLE BEP;Lo;0;L;;;;;N;;;;;\nA02C;YI SYLLABLE BUT;Lo;0;L;;;;;N;;;;;\nA02D;YI SYLLABLE BUX;Lo;0;L;;;;;N;;;;;\nA02E;YI SYLLABLE BU;Lo;0;L;;;;;N;;;;;\nA02F;YI SYLLABLE BUP;Lo;0;L;;;;;N;;;;;\nA030;YI SYLLABLE BURX;Lo;0;L;;;;;N;;;;;\nA031;YI SYLLABLE BUR;Lo;0;L;;;;;N;;;;;\nA032;YI SYLLABLE BYT;Lo;0;L;;;;;N;;;;;\nA033;YI SYLLABLE BYX;Lo;0;L;;;;;N;;;;;\nA034;YI SYLLABLE BY;Lo;0;L;;;;;N;;;;;\nA035;YI SYLLABLE BYP;Lo;0;L;;;;;N;;;;;\nA036;YI SYLLABLE BYRX;Lo;0;L;;;;;N;;;;;\nA037;YI SYLLABLE BYR;Lo;0;L;;;;;N;;;;;\nA038;YI SYLLABLE PIT;Lo;0;L;;;;;N;;;;;\nA039;YI SYLLABLE PIX;Lo;0;L;;;;;N;;;;;\nA03A;YI SYLLABLE PI;Lo;0;L;;;;;N;;;;;\nA03B;YI SYLLABLE PIP;Lo;0;L;;;;;N;;;;;\nA03C;YI SYLLABLE PIEX;Lo;0;L;;;;;N;;;;;\nA03D;YI SYLLABLE PIE;Lo;0;L;;;;;N;;;;;\nA03E;YI SYLLABLE PIEP;Lo;0;L;;;;;N;;;;;\nA03F;YI SYLLABLE PAT;Lo;0;L;;;;;N;;;;;\nA040;YI SYLLABLE PAX;Lo;0;L;;;;;N;;;;;\nA041;YI SYLLABLE PA;Lo;0;L;;;;;N;;;;;\nA042;YI SYLLABLE PAP;Lo;0;L;;;;;N;;;;;\nA043;YI SYLLABLE PUOX;Lo;0;L;;;;;N;;;;;\nA044;YI SYLLABLE PUO;Lo;0;L;;;;;N;;;;;\nA045;YI SYLLABLE PUOP;Lo;0;L;;;;;N;;;;;\nA046;YI SYLLABLE POT;Lo;0;L;;;;;N;;;;;\nA047;YI SYLLABLE POX;Lo;0;L;;;;;N;;;;;\nA048;YI SYLLABLE PO;Lo;0;L;;;;;N;;;;;\nA049;YI SYLLABLE POP;Lo;0;L;;;;;N;;;;;\nA04A;YI SYLLABLE PUT;Lo;0;L;;;;;N;;;;;\nA04B;YI SYLLABLE PUX;Lo;0;L;;;;;N;;;;;\nA04C;YI SYLLABLE PU;Lo;0;L;;;;;N;;;;;\nA04D;YI SYLLABLE PUP;Lo;0;L;;;;;N;;;;;\nA04E;YI SYLLABLE PURX;Lo;0;L;;;;;N;;;;;\nA04F;YI SYLLABLE PUR;Lo;0;L;;;;;N;;;;;\nA050;YI SYLLABLE PYT;Lo;0;L;;;;;N;;;;;\nA051;YI SYLLABLE PYX;Lo;0;L;;;;;N;;;;;\nA052;YI SYLLABLE PY;Lo;0;L;;;;;N;;;;;\nA053;YI SYLLABLE PYP;Lo;0;L;;;;;N;;;;;\nA054;YI SYLLABLE PYRX;Lo;0;L;;;;;N;;;;;\nA055;YI SYLLABLE PYR;Lo;0;L;;;;;N;;;;;\nA056;YI SYLLABLE BBIT;Lo;0;L;;;;;N;;;;;\nA057;YI SYLLABLE BBIX;Lo;0;L;;;;;N;;;;;\nA058;YI SYLLABLE BBI;Lo;0;L;;;;;N;;;;;\nA059;YI SYLLABLE BBIP;Lo;0;L;;;;;N;;;;;\nA05A;YI SYLLABLE BBIET;Lo;0;L;;;;;N;;;;;\nA05B;YI SYLLABLE BBIEX;Lo;0;L;;;;;N;;;;;\nA05C;YI SYLLABLE BBIE;Lo;0;L;;;;;N;;;;;\nA05D;YI SYLLABLE BBIEP;Lo;0;L;;;;;N;;;;;\nA05E;YI SYLLABLE BBAT;Lo;0;L;;;;;N;;;;;\nA05F;YI SYLLABLE BBAX;Lo;0;L;;;;;N;;;;;\nA060;YI SYLLABLE BBA;Lo;0;L;;;;;N;;;;;\nA061;YI SYLLABLE BBAP;Lo;0;L;;;;;N;;;;;\nA062;YI SYLLABLE BBUOX;Lo;0;L;;;;;N;;;;;\nA063;YI SYLLABLE BBUO;Lo;0;L;;;;;N;;;;;\nA064;YI SYLLABLE BBUOP;Lo;0;L;;;;;N;;;;;\nA065;YI SYLLABLE BBOT;Lo;0;L;;;;;N;;;;;\nA066;YI SYLLABLE BBOX;Lo;0;L;;;;;N;;;;;\nA067;YI SYLLABLE BBO;Lo;0;L;;;;;N;;;;;\nA068;YI SYLLABLE BBOP;Lo;0;L;;;;;N;;;;;\nA069;YI SYLLABLE BBEX;Lo;0;L;;;;;N;;;;;\nA06A;YI SYLLABLE BBE;Lo;0;L;;;;;N;;;;;\nA06B;YI SYLLABLE BBEP;Lo;0;L;;;;;N;;;;;\nA06C;YI SYLLABLE BBUT;Lo;0;L;;;;;N;;;;;\nA06D;YI SYLLABLE BBUX;Lo;0;L;;;;;N;;;;;\nA06E;YI SYLLABLE BBU;Lo;0;L;;;;;N;;;;;\nA06F;YI SYLLABLE BBUP;Lo;0;L;;;;;N;;;;;\nA070;YI SYLLABLE BBURX;Lo;0;L;;;;;N;;;;;\nA071;YI SYLLABLE BBUR;Lo;0;L;;;;;N;;;;;\nA072;YI SYLLABLE BBYT;Lo;0;L;;;;;N;;;;;\nA073;YI SYLLABLE BBYX;Lo;0;L;;;;;N;;;;;\nA074;YI SYLLABLE BBY;Lo;0;L;;;;;N;;;;;\nA075;YI SYLLABLE BBYP;Lo;0;L;;;;;N;;;;;\nA076;YI SYLLABLE NBIT;Lo;0;L;;;;;N;;;;;\nA077;YI SYLLABLE NBIX;Lo;0;L;;;;;N;;;;;\nA078;YI SYLLABLE NBI;Lo;0;L;;;;;N;;;;;\nA079;YI SYLLABLE NBIP;Lo;0;L;;;;;N;;;;;\nA07A;YI SYLLABLE NBIEX;Lo;0;L;;;;;N;;;;;\nA07B;YI SYLLABLE NBIE;Lo;0;L;;;;;N;;;;;\nA07C;YI SYLLABLE NBIEP;Lo;0;L;;;;;N;;;;;\nA07D;YI SYLLABLE NBAT;Lo;0;L;;;;;N;;;;;\nA07E;YI SYLLABLE NBAX;Lo;0;L;;;;;N;;;;;\nA07F;YI SYLLABLE NBA;Lo;0;L;;;;;N;;;;;\nA080;YI SYLLABLE NBAP;Lo;0;L;;;;;N;;;;;\nA081;YI SYLLABLE NBOT;Lo;0;L;;;;;N;;;;;\nA082;YI SYLLABLE NBOX;Lo;0;L;;;;;N;;;;;\nA083;YI SYLLABLE NBO;Lo;0;L;;;;;N;;;;;\nA084;YI SYLLABLE NBOP;Lo;0;L;;;;;N;;;;;\nA085;YI SYLLABLE NBUT;Lo;0;L;;;;;N;;;;;\nA086;YI SYLLABLE NBUX;Lo;0;L;;;;;N;;;;;\nA087;YI SYLLABLE NBU;Lo;0;L;;;;;N;;;;;\nA088;YI SYLLABLE NBUP;Lo;0;L;;;;;N;;;;;\nA089;YI SYLLABLE NBURX;Lo;0;L;;;;;N;;;;;\nA08A;YI SYLLABLE NBUR;Lo;0;L;;;;;N;;;;;\nA08B;YI SYLLABLE NBYT;Lo;0;L;;;;;N;;;;;\nA08C;YI SYLLABLE NBYX;Lo;0;L;;;;;N;;;;;\nA08D;YI SYLLABLE NBY;Lo;0;L;;;;;N;;;;;\nA08E;YI SYLLABLE NBYP;Lo;0;L;;;;;N;;;;;\nA08F;YI SYLLABLE NBYRX;Lo;0;L;;;;;N;;;;;\nA090;YI SYLLABLE NBYR;Lo;0;L;;;;;N;;;;;\nA091;YI SYLLABLE HMIT;Lo;0;L;;;;;N;;;;;\nA092;YI SYLLABLE HMIX;Lo;0;L;;;;;N;;;;;\nA093;YI SYLLABLE HMI;Lo;0;L;;;;;N;;;;;\nA094;YI SYLLABLE HMIP;Lo;0;L;;;;;N;;;;;\nA095;YI SYLLABLE HMIEX;Lo;0;L;;;;;N;;;;;\nA096;YI SYLLABLE HMIE;Lo;0;L;;;;;N;;;;;\nA097;YI SYLLABLE HMIEP;Lo;0;L;;;;;N;;;;;\nA098;YI SYLLABLE HMAT;Lo;0;L;;;;;N;;;;;\nA099;YI SYLLABLE HMAX;Lo;0;L;;;;;N;;;;;\nA09A;YI SYLLABLE HMA;Lo;0;L;;;;;N;;;;;\nA09B;YI SYLLABLE HMAP;Lo;0;L;;;;;N;;;;;\nA09C;YI SYLLABLE HMUOX;Lo;0;L;;;;;N;;;;;\nA09D;YI SYLLABLE HMUO;Lo;0;L;;;;;N;;;;;\nA09E;YI SYLLABLE HMUOP;Lo;0;L;;;;;N;;;;;\nA09F;YI SYLLABLE HMOT;Lo;0;L;;;;;N;;;;;\nA0A0;YI SYLLABLE HMOX;Lo;0;L;;;;;N;;;;;\nA0A1;YI SYLLABLE HMO;Lo;0;L;;;;;N;;;;;\nA0A2;YI SYLLABLE HMOP;Lo;0;L;;;;;N;;;;;\nA0A3;YI SYLLABLE HMUT;Lo;0;L;;;;;N;;;;;\nA0A4;YI SYLLABLE HMUX;Lo;0;L;;;;;N;;;;;\nA0A5;YI SYLLABLE HMU;Lo;0;L;;;;;N;;;;;\nA0A6;YI SYLLABLE HMUP;Lo;0;L;;;;;N;;;;;\nA0A7;YI SYLLABLE HMURX;Lo;0;L;;;;;N;;;;;\nA0A8;YI SYLLABLE HMUR;Lo;0;L;;;;;N;;;;;\nA0A9;YI SYLLABLE HMYX;Lo;0;L;;;;;N;;;;;\nA0AA;YI SYLLABLE HMY;Lo;0;L;;;;;N;;;;;\nA0AB;YI SYLLABLE HMYP;Lo;0;L;;;;;N;;;;;\nA0AC;YI SYLLABLE HMYRX;Lo;0;L;;;;;N;;;;;\nA0AD;YI SYLLABLE HMYR;Lo;0;L;;;;;N;;;;;\nA0AE;YI SYLLABLE MIT;Lo;0;L;;;;;N;;;;;\nA0AF;YI SYLLABLE MIX;Lo;0;L;;;;;N;;;;;\nA0B0;YI SYLLABLE MI;Lo;0;L;;;;;N;;;;;\nA0B1;YI SYLLABLE MIP;Lo;0;L;;;;;N;;;;;\nA0B2;YI SYLLABLE MIEX;Lo;0;L;;;;;N;;;;;\nA0B3;YI SYLLABLE MIE;Lo;0;L;;;;;N;;;;;\nA0B4;YI SYLLABLE MIEP;Lo;0;L;;;;;N;;;;;\nA0B5;YI SYLLABLE MAT;Lo;0;L;;;;;N;;;;;\nA0B6;YI SYLLABLE MAX;Lo;0;L;;;;;N;;;;;\nA0B7;YI SYLLABLE MA;Lo;0;L;;;;;N;;;;;\nA0B8;YI SYLLABLE MAP;Lo;0;L;;;;;N;;;;;\nA0B9;YI SYLLABLE MUOT;Lo;0;L;;;;;N;;;;;\nA0BA;YI SYLLABLE MUOX;Lo;0;L;;;;;N;;;;;\nA0BB;YI SYLLABLE MUO;Lo;0;L;;;;;N;;;;;\nA0BC;YI SYLLABLE MUOP;Lo;0;L;;;;;N;;;;;\nA0BD;YI SYLLABLE MOT;Lo;0;L;;;;;N;;;;;\nA0BE;YI SYLLABLE MOX;Lo;0;L;;;;;N;;;;;\nA0BF;YI SYLLABLE MO;Lo;0;L;;;;;N;;;;;\nA0C0;YI SYLLABLE MOP;Lo;0;L;;;;;N;;;;;\nA0C1;YI SYLLABLE MEX;Lo;0;L;;;;;N;;;;;\nA0C2;YI SYLLABLE ME;Lo;0;L;;;;;N;;;;;\nA0C3;YI SYLLABLE MUT;Lo;0;L;;;;;N;;;;;\nA0C4;YI SYLLABLE MUX;Lo;0;L;;;;;N;;;;;\nA0C5;YI SYLLABLE MU;Lo;0;L;;;;;N;;;;;\nA0C6;YI SYLLABLE MUP;Lo;0;L;;;;;N;;;;;\nA0C7;YI SYLLABLE MURX;Lo;0;L;;;;;N;;;;;\nA0C8;YI SYLLABLE MUR;Lo;0;L;;;;;N;;;;;\nA0C9;YI SYLLABLE MYT;Lo;0;L;;;;;N;;;;;\nA0CA;YI SYLLABLE MYX;Lo;0;L;;;;;N;;;;;\nA0CB;YI SYLLABLE MY;Lo;0;L;;;;;N;;;;;\nA0CC;YI SYLLABLE MYP;Lo;0;L;;;;;N;;;;;\nA0CD;YI SYLLABLE FIT;Lo;0;L;;;;;N;;;;;\nA0CE;YI SYLLABLE FIX;Lo;0;L;;;;;N;;;;;\nA0CF;YI SYLLABLE FI;Lo;0;L;;;;;N;;;;;\nA0D0;YI SYLLABLE FIP;Lo;0;L;;;;;N;;;;;\nA0D1;YI SYLLABLE FAT;Lo;0;L;;;;;N;;;;;\nA0D2;YI SYLLABLE FAX;Lo;0;L;;;;;N;;;;;\nA0D3;YI SYLLABLE FA;Lo;0;L;;;;;N;;;;;\nA0D4;YI SYLLABLE FAP;Lo;0;L;;;;;N;;;;;\nA0D5;YI SYLLABLE FOX;Lo;0;L;;;;;N;;;;;\nA0D6;YI SYLLABLE FO;Lo;0;L;;;;;N;;;;;\nA0D7;YI SYLLABLE FOP;Lo;0;L;;;;;N;;;;;\nA0D8;YI SYLLABLE FUT;Lo;0;L;;;;;N;;;;;\nA0D9;YI SYLLABLE FUX;Lo;0;L;;;;;N;;;;;\nA0DA;YI SYLLABLE FU;Lo;0;L;;;;;N;;;;;\nA0DB;YI SYLLABLE FUP;Lo;0;L;;;;;N;;;;;\nA0DC;YI SYLLABLE FURX;Lo;0;L;;;;;N;;;;;\nA0DD;YI SYLLABLE FUR;Lo;0;L;;;;;N;;;;;\nA0DE;YI SYLLABLE FYT;Lo;0;L;;;;;N;;;;;\nA0DF;YI SYLLABLE FYX;Lo;0;L;;;;;N;;;;;\nA0E0;YI SYLLABLE FY;Lo;0;L;;;;;N;;;;;\nA0E1;YI SYLLABLE FYP;Lo;0;L;;;;;N;;;;;\nA0E2;YI SYLLABLE VIT;Lo;0;L;;;;;N;;;;;\nA0E3;YI SYLLABLE VIX;Lo;0;L;;;;;N;;;;;\nA0E4;YI SYLLABLE VI;Lo;0;L;;;;;N;;;;;\nA0E5;YI SYLLABLE VIP;Lo;0;L;;;;;N;;;;;\nA0E6;YI SYLLABLE VIET;Lo;0;L;;;;;N;;;;;\nA0E7;YI SYLLABLE VIEX;Lo;0;L;;;;;N;;;;;\nA0E8;YI SYLLABLE VIE;Lo;0;L;;;;;N;;;;;\nA0E9;YI SYLLABLE VIEP;Lo;0;L;;;;;N;;;;;\nA0EA;YI SYLLABLE VAT;Lo;0;L;;;;;N;;;;;\nA0EB;YI SYLLABLE VAX;Lo;0;L;;;;;N;;;;;\nA0EC;YI SYLLABLE VA;Lo;0;L;;;;;N;;;;;\nA0ED;YI SYLLABLE VAP;Lo;0;L;;;;;N;;;;;\nA0EE;YI SYLLABLE VOT;Lo;0;L;;;;;N;;;;;\nA0EF;YI SYLLABLE VOX;Lo;0;L;;;;;N;;;;;\nA0F0;YI SYLLABLE VO;Lo;0;L;;;;;N;;;;;\nA0F1;YI SYLLABLE VOP;Lo;0;L;;;;;N;;;;;\nA0F2;YI SYLLABLE VEX;Lo;0;L;;;;;N;;;;;\nA0F3;YI SYLLABLE VEP;Lo;0;L;;;;;N;;;;;\nA0F4;YI SYLLABLE VUT;Lo;0;L;;;;;N;;;;;\nA0F5;YI SYLLABLE VUX;Lo;0;L;;;;;N;;;;;\nA0F6;YI SYLLABLE VU;Lo;0;L;;;;;N;;;;;\nA0F7;YI SYLLABLE VUP;Lo;0;L;;;;;N;;;;;\nA0F8;YI SYLLABLE VURX;Lo;0;L;;;;;N;;;;;\nA0F9;YI SYLLABLE VUR;Lo;0;L;;;;;N;;;;;\nA0FA;YI SYLLABLE VYT;Lo;0;L;;;;;N;;;;;\nA0FB;YI SYLLABLE VYX;Lo;0;L;;;;;N;;;;;\nA0FC;YI SYLLABLE VY;Lo;0;L;;;;;N;;;;;\nA0FD;YI SYLLABLE VYP;Lo;0;L;;;;;N;;;;;\nA0FE;YI SYLLABLE VYRX;Lo;0;L;;;;;N;;;;;\nA0FF;YI SYLLABLE VYR;Lo;0;L;;;;;N;;;;;\nA100;YI SYLLABLE DIT;Lo;0;L;;;;;N;;;;;\nA101;YI SYLLABLE DIX;Lo;0;L;;;;;N;;;;;\nA102;YI SYLLABLE DI;Lo;0;L;;;;;N;;;;;\nA103;YI SYLLABLE DIP;Lo;0;L;;;;;N;;;;;\nA104;YI SYLLABLE DIEX;Lo;0;L;;;;;N;;;;;\nA105;YI SYLLABLE DIE;Lo;0;L;;;;;N;;;;;\nA106;YI SYLLABLE DIEP;Lo;0;L;;;;;N;;;;;\nA107;YI SYLLABLE DAT;Lo;0;L;;;;;N;;;;;\nA108;YI SYLLABLE DAX;Lo;0;L;;;;;N;;;;;\nA109;YI SYLLABLE DA;Lo;0;L;;;;;N;;;;;\nA10A;YI SYLLABLE DAP;Lo;0;L;;;;;N;;;;;\nA10B;YI SYLLABLE DUOX;Lo;0;L;;;;;N;;;;;\nA10C;YI SYLLABLE DUO;Lo;0;L;;;;;N;;;;;\nA10D;YI SYLLABLE DOT;Lo;0;L;;;;;N;;;;;\nA10E;YI SYLLABLE DOX;Lo;0;L;;;;;N;;;;;\nA10F;YI SYLLABLE DO;Lo;0;L;;;;;N;;;;;\nA110;YI SYLLABLE DOP;Lo;0;L;;;;;N;;;;;\nA111;YI SYLLABLE DEX;Lo;0;L;;;;;N;;;;;\nA112;YI SYLLABLE DE;Lo;0;L;;;;;N;;;;;\nA113;YI SYLLABLE DEP;Lo;0;L;;;;;N;;;;;\nA114;YI SYLLABLE DUT;Lo;0;L;;;;;N;;;;;\nA115;YI SYLLABLE DUX;Lo;0;L;;;;;N;;;;;\nA116;YI SYLLABLE DU;Lo;0;L;;;;;N;;;;;\nA117;YI SYLLABLE DUP;Lo;0;L;;;;;N;;;;;\nA118;YI SYLLABLE DURX;Lo;0;L;;;;;N;;;;;\nA119;YI SYLLABLE DUR;Lo;0;L;;;;;N;;;;;\nA11A;YI SYLLABLE TIT;Lo;0;L;;;;;N;;;;;\nA11B;YI SYLLABLE TIX;Lo;0;L;;;;;N;;;;;\nA11C;YI SYLLABLE TI;Lo;0;L;;;;;N;;;;;\nA11D;YI SYLLABLE TIP;Lo;0;L;;;;;N;;;;;\nA11E;YI SYLLABLE TIEX;Lo;0;L;;;;;N;;;;;\nA11F;YI SYLLABLE TIE;Lo;0;L;;;;;N;;;;;\nA120;YI SYLLABLE TIEP;Lo;0;L;;;;;N;;;;;\nA121;YI SYLLABLE TAT;Lo;0;L;;;;;N;;;;;\nA122;YI SYLLABLE TAX;Lo;0;L;;;;;N;;;;;\nA123;YI SYLLABLE TA;Lo;0;L;;;;;N;;;;;\nA124;YI SYLLABLE TAP;Lo;0;L;;;;;N;;;;;\nA125;YI SYLLABLE TUOT;Lo;0;L;;;;;N;;;;;\nA126;YI SYLLABLE TUOX;Lo;0;L;;;;;N;;;;;\nA127;YI SYLLABLE TUO;Lo;0;L;;;;;N;;;;;\nA128;YI SYLLABLE TUOP;Lo;0;L;;;;;N;;;;;\nA129;YI SYLLABLE TOT;Lo;0;L;;;;;N;;;;;\nA12A;YI SYLLABLE TOX;Lo;0;L;;;;;N;;;;;\nA12B;YI SYLLABLE TO;Lo;0;L;;;;;N;;;;;\nA12C;YI SYLLABLE TOP;Lo;0;L;;;;;N;;;;;\nA12D;YI SYLLABLE TEX;Lo;0;L;;;;;N;;;;;\nA12E;YI SYLLABLE TE;Lo;0;L;;;;;N;;;;;\nA12F;YI SYLLABLE TEP;Lo;0;L;;;;;N;;;;;\nA130;YI SYLLABLE TUT;Lo;0;L;;;;;N;;;;;\nA131;YI SYLLABLE TUX;Lo;0;L;;;;;N;;;;;\nA132;YI SYLLABLE TU;Lo;0;L;;;;;N;;;;;\nA133;YI SYLLABLE TUP;Lo;0;L;;;;;N;;;;;\nA134;YI SYLLABLE TURX;Lo;0;L;;;;;N;;;;;\nA135;YI SYLLABLE TUR;Lo;0;L;;;;;N;;;;;\nA136;YI SYLLABLE DDIT;Lo;0;L;;;;;N;;;;;\nA137;YI SYLLABLE DDIX;Lo;0;L;;;;;N;;;;;\nA138;YI SYLLABLE DDI;Lo;0;L;;;;;N;;;;;\nA139;YI SYLLABLE DDIP;Lo;0;L;;;;;N;;;;;\nA13A;YI SYLLABLE DDIEX;Lo;0;L;;;;;N;;;;;\nA13B;YI SYLLABLE DDIE;Lo;0;L;;;;;N;;;;;\nA13C;YI SYLLABLE DDIEP;Lo;0;L;;;;;N;;;;;\nA13D;YI SYLLABLE DDAT;Lo;0;L;;;;;N;;;;;\nA13E;YI SYLLABLE DDAX;Lo;0;L;;;;;N;;;;;\nA13F;YI SYLLABLE DDA;Lo;0;L;;;;;N;;;;;\nA140;YI SYLLABLE DDAP;Lo;0;L;;;;;N;;;;;\nA141;YI SYLLABLE DDUOX;Lo;0;L;;;;;N;;;;;\nA142;YI SYLLABLE DDUO;Lo;0;L;;;;;N;;;;;\nA143;YI SYLLABLE DDUOP;Lo;0;L;;;;;N;;;;;\nA144;YI SYLLABLE DDOT;Lo;0;L;;;;;N;;;;;\nA145;YI SYLLABLE DDOX;Lo;0;L;;;;;N;;;;;\nA146;YI SYLLABLE DDO;Lo;0;L;;;;;N;;;;;\nA147;YI SYLLABLE DDOP;Lo;0;L;;;;;N;;;;;\nA148;YI SYLLABLE DDEX;Lo;0;L;;;;;N;;;;;\nA149;YI SYLLABLE DDE;Lo;0;L;;;;;N;;;;;\nA14A;YI SYLLABLE DDEP;Lo;0;L;;;;;N;;;;;\nA14B;YI SYLLABLE DDUT;Lo;0;L;;;;;N;;;;;\nA14C;YI SYLLABLE DDUX;Lo;0;L;;;;;N;;;;;\nA14D;YI SYLLABLE DDU;Lo;0;L;;;;;N;;;;;\nA14E;YI SYLLABLE DDUP;Lo;0;L;;;;;N;;;;;\nA14F;YI SYLLABLE DDURX;Lo;0;L;;;;;N;;;;;\nA150;YI SYLLABLE DDUR;Lo;0;L;;;;;N;;;;;\nA151;YI SYLLABLE NDIT;Lo;0;L;;;;;N;;;;;\nA152;YI SYLLABLE NDIX;Lo;0;L;;;;;N;;;;;\nA153;YI SYLLABLE NDI;Lo;0;L;;;;;N;;;;;\nA154;YI SYLLABLE NDIP;Lo;0;L;;;;;N;;;;;\nA155;YI SYLLABLE NDIEX;Lo;0;L;;;;;N;;;;;\nA156;YI SYLLABLE NDIE;Lo;0;L;;;;;N;;;;;\nA157;YI SYLLABLE NDAT;Lo;0;L;;;;;N;;;;;\nA158;YI SYLLABLE NDAX;Lo;0;L;;;;;N;;;;;\nA159;YI SYLLABLE NDA;Lo;0;L;;;;;N;;;;;\nA15A;YI SYLLABLE NDAP;Lo;0;L;;;;;N;;;;;\nA15B;YI SYLLABLE NDOT;Lo;0;L;;;;;N;;;;;\nA15C;YI SYLLABLE NDOX;Lo;0;L;;;;;N;;;;;\nA15D;YI SYLLABLE NDO;Lo;0;L;;;;;N;;;;;\nA15E;YI SYLLABLE NDOP;Lo;0;L;;;;;N;;;;;\nA15F;YI SYLLABLE NDEX;Lo;0;L;;;;;N;;;;;\nA160;YI SYLLABLE NDE;Lo;0;L;;;;;N;;;;;\nA161;YI SYLLABLE NDEP;Lo;0;L;;;;;N;;;;;\nA162;YI SYLLABLE NDUT;Lo;0;L;;;;;N;;;;;\nA163;YI SYLLABLE NDUX;Lo;0;L;;;;;N;;;;;\nA164;YI SYLLABLE NDU;Lo;0;L;;;;;N;;;;;\nA165;YI SYLLABLE NDUP;Lo;0;L;;;;;N;;;;;\nA166;YI SYLLABLE NDURX;Lo;0;L;;;;;N;;;;;\nA167;YI SYLLABLE NDUR;Lo;0;L;;;;;N;;;;;\nA168;YI SYLLABLE HNIT;Lo;0;L;;;;;N;;;;;\nA169;YI SYLLABLE HNIX;Lo;0;L;;;;;N;;;;;\nA16A;YI SYLLABLE HNI;Lo;0;L;;;;;N;;;;;\nA16B;YI SYLLABLE HNIP;Lo;0;L;;;;;N;;;;;\nA16C;YI SYLLABLE HNIET;Lo;0;L;;;;;N;;;;;\nA16D;YI SYLLABLE HNIEX;Lo;0;L;;;;;N;;;;;\nA16E;YI SYLLABLE HNIE;Lo;0;L;;;;;N;;;;;\nA16F;YI SYLLABLE HNIEP;Lo;0;L;;;;;N;;;;;\nA170;YI SYLLABLE HNAT;Lo;0;L;;;;;N;;;;;\nA171;YI SYLLABLE HNAX;Lo;0;L;;;;;N;;;;;\nA172;YI SYLLABLE HNA;Lo;0;L;;;;;N;;;;;\nA173;YI SYLLABLE HNAP;Lo;0;L;;;;;N;;;;;\nA174;YI SYLLABLE HNUOX;Lo;0;L;;;;;N;;;;;\nA175;YI SYLLABLE HNUO;Lo;0;L;;;;;N;;;;;\nA176;YI SYLLABLE HNOT;Lo;0;L;;;;;N;;;;;\nA177;YI SYLLABLE HNOX;Lo;0;L;;;;;N;;;;;\nA178;YI SYLLABLE HNOP;Lo;0;L;;;;;N;;;;;\nA179;YI SYLLABLE HNEX;Lo;0;L;;;;;N;;;;;\nA17A;YI SYLLABLE HNE;Lo;0;L;;;;;N;;;;;\nA17B;YI SYLLABLE HNEP;Lo;0;L;;;;;N;;;;;\nA17C;YI SYLLABLE HNUT;Lo;0;L;;;;;N;;;;;\nA17D;YI SYLLABLE NIT;Lo;0;L;;;;;N;;;;;\nA17E;YI SYLLABLE NIX;Lo;0;L;;;;;N;;;;;\nA17F;YI SYLLABLE NI;Lo;0;L;;;;;N;;;;;\nA180;YI SYLLABLE NIP;Lo;0;L;;;;;N;;;;;\nA181;YI SYLLABLE NIEX;Lo;0;L;;;;;N;;;;;\nA182;YI SYLLABLE NIE;Lo;0;L;;;;;N;;;;;\nA183;YI SYLLABLE NIEP;Lo;0;L;;;;;N;;;;;\nA184;YI SYLLABLE NAX;Lo;0;L;;;;;N;;;;;\nA185;YI SYLLABLE NA;Lo;0;L;;;;;N;;;;;\nA186;YI SYLLABLE NAP;Lo;0;L;;;;;N;;;;;\nA187;YI SYLLABLE NUOX;Lo;0;L;;;;;N;;;;;\nA188;YI SYLLABLE NUO;Lo;0;L;;;;;N;;;;;\nA189;YI SYLLABLE NUOP;Lo;0;L;;;;;N;;;;;\nA18A;YI SYLLABLE NOT;Lo;0;L;;;;;N;;;;;\nA18B;YI SYLLABLE NOX;Lo;0;L;;;;;N;;;;;\nA18C;YI SYLLABLE NO;Lo;0;L;;;;;N;;;;;\nA18D;YI SYLLABLE NOP;Lo;0;L;;;;;N;;;;;\nA18E;YI SYLLABLE NEX;Lo;0;L;;;;;N;;;;;\nA18F;YI SYLLABLE NE;Lo;0;L;;;;;N;;;;;\nA190;YI SYLLABLE NEP;Lo;0;L;;;;;N;;;;;\nA191;YI SYLLABLE NUT;Lo;0;L;;;;;N;;;;;\nA192;YI SYLLABLE NUX;Lo;0;L;;;;;N;;;;;\nA193;YI SYLLABLE NU;Lo;0;L;;;;;N;;;;;\nA194;YI SYLLABLE NUP;Lo;0;L;;;;;N;;;;;\nA195;YI SYLLABLE NURX;Lo;0;L;;;;;N;;;;;\nA196;YI SYLLABLE NUR;Lo;0;L;;;;;N;;;;;\nA197;YI SYLLABLE HLIT;Lo;0;L;;;;;N;;;;;\nA198;YI SYLLABLE HLIX;Lo;0;L;;;;;N;;;;;\nA199;YI SYLLABLE HLI;Lo;0;L;;;;;N;;;;;\nA19A;YI SYLLABLE HLIP;Lo;0;L;;;;;N;;;;;\nA19B;YI SYLLABLE HLIEX;Lo;0;L;;;;;N;;;;;\nA19C;YI SYLLABLE HLIE;Lo;0;L;;;;;N;;;;;\nA19D;YI SYLLABLE HLIEP;Lo;0;L;;;;;N;;;;;\nA19E;YI SYLLABLE HLAT;Lo;0;L;;;;;N;;;;;\nA19F;YI SYLLABLE HLAX;Lo;0;L;;;;;N;;;;;\nA1A0;YI SYLLABLE HLA;Lo;0;L;;;;;N;;;;;\nA1A1;YI SYLLABLE HLAP;Lo;0;L;;;;;N;;;;;\nA1A2;YI SYLLABLE HLUOX;Lo;0;L;;;;;N;;;;;\nA1A3;YI SYLLABLE HLUO;Lo;0;L;;;;;N;;;;;\nA1A4;YI SYLLABLE HLUOP;Lo;0;L;;;;;N;;;;;\nA1A5;YI SYLLABLE HLOX;Lo;0;L;;;;;N;;;;;\nA1A6;YI SYLLABLE HLO;Lo;0;L;;;;;N;;;;;\nA1A7;YI SYLLABLE HLOP;Lo;0;L;;;;;N;;;;;\nA1A8;YI SYLLABLE HLEX;Lo;0;L;;;;;N;;;;;\nA1A9;YI SYLLABLE HLE;Lo;0;L;;;;;N;;;;;\nA1AA;YI SYLLABLE HLEP;Lo;0;L;;;;;N;;;;;\nA1AB;YI SYLLABLE HLUT;Lo;0;L;;;;;N;;;;;\nA1AC;YI SYLLABLE HLUX;Lo;0;L;;;;;N;;;;;\nA1AD;YI SYLLABLE HLU;Lo;0;L;;;;;N;;;;;\nA1AE;YI SYLLABLE HLUP;Lo;0;L;;;;;N;;;;;\nA1AF;YI SYLLABLE HLURX;Lo;0;L;;;;;N;;;;;\nA1B0;YI SYLLABLE HLUR;Lo;0;L;;;;;N;;;;;\nA1B1;YI SYLLABLE HLYT;Lo;0;L;;;;;N;;;;;\nA1B2;YI SYLLABLE HLYX;Lo;0;L;;;;;N;;;;;\nA1B3;YI SYLLABLE HLY;Lo;0;L;;;;;N;;;;;\nA1B4;YI SYLLABLE HLYP;Lo;0;L;;;;;N;;;;;\nA1B5;YI SYLLABLE HLYRX;Lo;0;L;;;;;N;;;;;\nA1B6;YI SYLLABLE HLYR;Lo;0;L;;;;;N;;;;;\nA1B7;YI SYLLABLE LIT;Lo;0;L;;;;;N;;;;;\nA1B8;YI SYLLABLE LIX;Lo;0;L;;;;;N;;;;;\nA1B9;YI SYLLABLE LI;Lo;0;L;;;;;N;;;;;\nA1BA;YI SYLLABLE LIP;Lo;0;L;;;;;N;;;;;\nA1BB;YI SYLLABLE LIET;Lo;0;L;;;;;N;;;;;\nA1BC;YI SYLLABLE LIEX;Lo;0;L;;;;;N;;;;;\nA1BD;YI SYLLABLE LIE;Lo;0;L;;;;;N;;;;;\nA1BE;YI SYLLABLE LIEP;Lo;0;L;;;;;N;;;;;\nA1BF;YI SYLLABLE LAT;Lo;0;L;;;;;N;;;;;\nA1C0;YI SYLLABLE LAX;Lo;0;L;;;;;N;;;;;\nA1C1;YI SYLLABLE LA;Lo;0;L;;;;;N;;;;;\nA1C2;YI SYLLABLE LAP;Lo;0;L;;;;;N;;;;;\nA1C3;YI SYLLABLE LUOT;Lo;0;L;;;;;N;;;;;\nA1C4;YI SYLLABLE LUOX;Lo;0;L;;;;;N;;;;;\nA1C5;YI SYLLABLE LUO;Lo;0;L;;;;;N;;;;;\nA1C6;YI SYLLABLE LUOP;Lo;0;L;;;;;N;;;;;\nA1C7;YI SYLLABLE LOT;Lo;0;L;;;;;N;;;;;\nA1C8;YI SYLLABLE LOX;Lo;0;L;;;;;N;;;;;\nA1C9;YI SYLLABLE LO;Lo;0;L;;;;;N;;;;;\nA1CA;YI SYLLABLE LOP;Lo;0;L;;;;;N;;;;;\nA1CB;YI SYLLABLE LEX;Lo;0;L;;;;;N;;;;;\nA1CC;YI SYLLABLE LE;Lo;0;L;;;;;N;;;;;\nA1CD;YI SYLLABLE LEP;Lo;0;L;;;;;N;;;;;\nA1CE;YI SYLLABLE LUT;Lo;0;L;;;;;N;;;;;\nA1CF;YI SYLLABLE LUX;Lo;0;L;;;;;N;;;;;\nA1D0;YI SYLLABLE LU;Lo;0;L;;;;;N;;;;;\nA1D1;YI SYLLABLE LUP;Lo;0;L;;;;;N;;;;;\nA1D2;YI SYLLABLE LURX;Lo;0;L;;;;;N;;;;;\nA1D3;YI SYLLABLE LUR;Lo;0;L;;;;;N;;;;;\nA1D4;YI SYLLABLE LYT;Lo;0;L;;;;;N;;;;;\nA1D5;YI SYLLABLE LYX;Lo;0;L;;;;;N;;;;;\nA1D6;YI SYLLABLE LY;Lo;0;L;;;;;N;;;;;\nA1D7;YI SYLLABLE LYP;Lo;0;L;;;;;N;;;;;\nA1D8;YI SYLLABLE LYRX;Lo;0;L;;;;;N;;;;;\nA1D9;YI SYLLABLE LYR;Lo;0;L;;;;;N;;;;;\nA1DA;YI SYLLABLE GIT;Lo;0;L;;;;;N;;;;;\nA1DB;YI SYLLABLE GIX;Lo;0;L;;;;;N;;;;;\nA1DC;YI SYLLABLE GI;Lo;0;L;;;;;N;;;;;\nA1DD;YI SYLLABLE GIP;Lo;0;L;;;;;N;;;;;\nA1DE;YI SYLLABLE GIET;Lo;0;L;;;;;N;;;;;\nA1DF;YI SYLLABLE GIEX;Lo;0;L;;;;;N;;;;;\nA1E0;YI SYLLABLE GIE;Lo;0;L;;;;;N;;;;;\nA1E1;YI SYLLABLE GIEP;Lo;0;L;;;;;N;;;;;\nA1E2;YI SYLLABLE GAT;Lo;0;L;;;;;N;;;;;\nA1E3;YI SYLLABLE GAX;Lo;0;L;;;;;N;;;;;\nA1E4;YI SYLLABLE GA;Lo;0;L;;;;;N;;;;;\nA1E5;YI SYLLABLE GAP;Lo;0;L;;;;;N;;;;;\nA1E6;YI SYLLABLE GUOT;Lo;0;L;;;;;N;;;;;\nA1E7;YI SYLLABLE GUOX;Lo;0;L;;;;;N;;;;;\nA1E8;YI SYLLABLE GUO;Lo;0;L;;;;;N;;;;;\nA1E9;YI SYLLABLE GUOP;Lo;0;L;;;;;N;;;;;\nA1EA;YI SYLLABLE GOT;Lo;0;L;;;;;N;;;;;\nA1EB;YI SYLLABLE GOX;Lo;0;L;;;;;N;;;;;\nA1EC;YI SYLLABLE GO;Lo;0;L;;;;;N;;;;;\nA1ED;YI SYLLABLE GOP;Lo;0;L;;;;;N;;;;;\nA1EE;YI SYLLABLE GET;Lo;0;L;;;;;N;;;;;\nA1EF;YI SYLLABLE GEX;Lo;0;L;;;;;N;;;;;\nA1F0;YI SYLLABLE GE;Lo;0;L;;;;;N;;;;;\nA1F1;YI SYLLABLE GEP;Lo;0;L;;;;;N;;;;;\nA1F2;YI SYLLABLE GUT;Lo;0;L;;;;;N;;;;;\nA1F3;YI SYLLABLE GUX;Lo;0;L;;;;;N;;;;;\nA1F4;YI SYLLABLE GU;Lo;0;L;;;;;N;;;;;\nA1F5;YI SYLLABLE GUP;Lo;0;L;;;;;N;;;;;\nA1F6;YI SYLLABLE GURX;Lo;0;L;;;;;N;;;;;\nA1F7;YI SYLLABLE GUR;Lo;0;L;;;;;N;;;;;\nA1F8;YI SYLLABLE KIT;Lo;0;L;;;;;N;;;;;\nA1F9;YI SYLLABLE KIX;Lo;0;L;;;;;N;;;;;\nA1FA;YI SYLLABLE KI;Lo;0;L;;;;;N;;;;;\nA1FB;YI SYLLABLE KIP;Lo;0;L;;;;;N;;;;;\nA1FC;YI SYLLABLE KIEX;Lo;0;L;;;;;N;;;;;\nA1FD;YI SYLLABLE KIE;Lo;0;L;;;;;N;;;;;\nA1FE;YI SYLLABLE KIEP;Lo;0;L;;;;;N;;;;;\nA1FF;YI SYLLABLE KAT;Lo;0;L;;;;;N;;;;;\nA200;YI SYLLABLE KAX;Lo;0;L;;;;;N;;;;;\nA201;YI SYLLABLE KA;Lo;0;L;;;;;N;;;;;\nA202;YI SYLLABLE KAP;Lo;0;L;;;;;N;;;;;\nA203;YI SYLLABLE KUOX;Lo;0;L;;;;;N;;;;;\nA204;YI SYLLABLE KUO;Lo;0;L;;;;;N;;;;;\nA205;YI SYLLABLE KUOP;Lo;0;L;;;;;N;;;;;\nA206;YI SYLLABLE KOT;Lo;0;L;;;;;N;;;;;\nA207;YI SYLLABLE KOX;Lo;0;L;;;;;N;;;;;\nA208;YI SYLLABLE KO;Lo;0;L;;;;;N;;;;;\nA209;YI SYLLABLE KOP;Lo;0;L;;;;;N;;;;;\nA20A;YI SYLLABLE KET;Lo;0;L;;;;;N;;;;;\nA20B;YI SYLLABLE KEX;Lo;0;L;;;;;N;;;;;\nA20C;YI SYLLABLE KE;Lo;0;L;;;;;N;;;;;\nA20D;YI SYLLABLE KEP;Lo;0;L;;;;;N;;;;;\nA20E;YI SYLLABLE KUT;Lo;0;L;;;;;N;;;;;\nA20F;YI SYLLABLE KUX;Lo;0;L;;;;;N;;;;;\nA210;YI SYLLABLE KU;Lo;0;L;;;;;N;;;;;\nA211;YI SYLLABLE KUP;Lo;0;L;;;;;N;;;;;\nA212;YI SYLLABLE KURX;Lo;0;L;;;;;N;;;;;\nA213;YI SYLLABLE KUR;Lo;0;L;;;;;N;;;;;\nA214;YI SYLLABLE GGIT;Lo;0;L;;;;;N;;;;;\nA215;YI SYLLABLE GGIX;Lo;0;L;;;;;N;;;;;\nA216;YI SYLLABLE GGI;Lo;0;L;;;;;N;;;;;\nA217;YI SYLLABLE GGIEX;Lo;0;L;;;;;N;;;;;\nA218;YI SYLLABLE GGIE;Lo;0;L;;;;;N;;;;;\nA219;YI SYLLABLE GGIEP;Lo;0;L;;;;;N;;;;;\nA21A;YI SYLLABLE GGAT;Lo;0;L;;;;;N;;;;;\nA21B;YI SYLLABLE GGAX;Lo;0;L;;;;;N;;;;;\nA21C;YI SYLLABLE GGA;Lo;0;L;;;;;N;;;;;\nA21D;YI SYLLABLE GGAP;Lo;0;L;;;;;N;;;;;\nA21E;YI SYLLABLE GGUOT;Lo;0;L;;;;;N;;;;;\nA21F;YI SYLLABLE GGUOX;Lo;0;L;;;;;N;;;;;\nA220;YI SYLLABLE GGUO;Lo;0;L;;;;;N;;;;;\nA221;YI SYLLABLE GGUOP;Lo;0;L;;;;;N;;;;;\nA222;YI SYLLABLE GGOT;Lo;0;L;;;;;N;;;;;\nA223;YI SYLLABLE GGOX;Lo;0;L;;;;;N;;;;;\nA224;YI SYLLABLE GGO;Lo;0;L;;;;;N;;;;;\nA225;YI SYLLABLE GGOP;Lo;0;L;;;;;N;;;;;\nA226;YI SYLLABLE GGET;Lo;0;L;;;;;N;;;;;\nA227;YI SYLLABLE GGEX;Lo;0;L;;;;;N;;;;;\nA228;YI SYLLABLE GGE;Lo;0;L;;;;;N;;;;;\nA229;YI SYLLABLE GGEP;Lo;0;L;;;;;N;;;;;\nA22A;YI SYLLABLE GGUT;Lo;0;L;;;;;N;;;;;\nA22B;YI SYLLABLE GGUX;Lo;0;L;;;;;N;;;;;\nA22C;YI SYLLABLE GGU;Lo;0;L;;;;;N;;;;;\nA22D;YI SYLLABLE GGUP;Lo;0;L;;;;;N;;;;;\nA22E;YI SYLLABLE GGURX;Lo;0;L;;;;;N;;;;;\nA22F;YI SYLLABLE GGUR;Lo;0;L;;;;;N;;;;;\nA230;YI SYLLABLE MGIEX;Lo;0;L;;;;;N;;;;;\nA231;YI SYLLABLE MGIE;Lo;0;L;;;;;N;;;;;\nA232;YI SYLLABLE MGAT;Lo;0;L;;;;;N;;;;;\nA233;YI SYLLABLE MGAX;Lo;0;L;;;;;N;;;;;\nA234;YI SYLLABLE MGA;Lo;0;L;;;;;N;;;;;\nA235;YI SYLLABLE MGAP;Lo;0;L;;;;;N;;;;;\nA236;YI SYLLABLE MGUOX;Lo;0;L;;;;;N;;;;;\nA237;YI SYLLABLE MGUO;Lo;0;L;;;;;N;;;;;\nA238;YI SYLLABLE MGUOP;Lo;0;L;;;;;N;;;;;\nA239;YI SYLLABLE MGOT;Lo;0;L;;;;;N;;;;;\nA23A;YI SYLLABLE MGOX;Lo;0;L;;;;;N;;;;;\nA23B;YI SYLLABLE MGO;Lo;0;L;;;;;N;;;;;\nA23C;YI SYLLABLE MGOP;Lo;0;L;;;;;N;;;;;\nA23D;YI SYLLABLE MGEX;Lo;0;L;;;;;N;;;;;\nA23E;YI SYLLABLE MGE;Lo;0;L;;;;;N;;;;;\nA23F;YI SYLLABLE MGEP;Lo;0;L;;;;;N;;;;;\nA240;YI SYLLABLE MGUT;Lo;0;L;;;;;N;;;;;\nA241;YI SYLLABLE MGUX;Lo;0;L;;;;;N;;;;;\nA242;YI SYLLABLE MGU;Lo;0;L;;;;;N;;;;;\nA243;YI SYLLABLE MGUP;Lo;0;L;;;;;N;;;;;\nA244;YI SYLLABLE MGURX;Lo;0;L;;;;;N;;;;;\nA245;YI SYLLABLE MGUR;Lo;0;L;;;;;N;;;;;\nA246;YI SYLLABLE HXIT;Lo;0;L;;;;;N;;;;;\nA247;YI SYLLABLE HXIX;Lo;0;L;;;;;N;;;;;\nA248;YI SYLLABLE HXI;Lo;0;L;;;;;N;;;;;\nA249;YI SYLLABLE HXIP;Lo;0;L;;;;;N;;;;;\nA24A;YI SYLLABLE HXIET;Lo;0;L;;;;;N;;;;;\nA24B;YI SYLLABLE HXIEX;Lo;0;L;;;;;N;;;;;\nA24C;YI SYLLABLE HXIE;Lo;0;L;;;;;N;;;;;\nA24D;YI SYLLABLE HXIEP;Lo;0;L;;;;;N;;;;;\nA24E;YI SYLLABLE HXAT;Lo;0;L;;;;;N;;;;;\nA24F;YI SYLLABLE HXAX;Lo;0;L;;;;;N;;;;;\nA250;YI SYLLABLE HXA;Lo;0;L;;;;;N;;;;;\nA251;YI SYLLABLE HXAP;Lo;0;L;;;;;N;;;;;\nA252;YI SYLLABLE HXUOT;Lo;0;L;;;;;N;;;;;\nA253;YI SYLLABLE HXUOX;Lo;0;L;;;;;N;;;;;\nA254;YI SYLLABLE HXUO;Lo;0;L;;;;;N;;;;;\nA255;YI SYLLABLE HXUOP;Lo;0;L;;;;;N;;;;;\nA256;YI SYLLABLE HXOT;Lo;0;L;;;;;N;;;;;\nA257;YI SYLLABLE HXOX;Lo;0;L;;;;;N;;;;;\nA258;YI SYLLABLE HXO;Lo;0;L;;;;;N;;;;;\nA259;YI SYLLABLE HXOP;Lo;0;L;;;;;N;;;;;\nA25A;YI SYLLABLE HXEX;Lo;0;L;;;;;N;;;;;\nA25B;YI SYLLABLE HXE;Lo;0;L;;;;;N;;;;;\nA25C;YI SYLLABLE HXEP;Lo;0;L;;;;;N;;;;;\nA25D;YI SYLLABLE NGIEX;Lo;0;L;;;;;N;;;;;\nA25E;YI SYLLABLE NGIE;Lo;0;L;;;;;N;;;;;\nA25F;YI SYLLABLE NGIEP;Lo;0;L;;;;;N;;;;;\nA260;YI SYLLABLE NGAT;Lo;0;L;;;;;N;;;;;\nA261;YI SYLLABLE NGAX;Lo;0;L;;;;;N;;;;;\nA262;YI SYLLABLE NGA;Lo;0;L;;;;;N;;;;;\nA263;YI SYLLABLE NGAP;Lo;0;L;;;;;N;;;;;\nA264;YI SYLLABLE NGUOT;Lo;0;L;;;;;N;;;;;\nA265;YI SYLLABLE NGUOX;Lo;0;L;;;;;N;;;;;\nA266;YI SYLLABLE NGUO;Lo;0;L;;;;;N;;;;;\nA267;YI SYLLABLE NGOT;Lo;0;L;;;;;N;;;;;\nA268;YI SYLLABLE NGOX;Lo;0;L;;;;;N;;;;;\nA269;YI SYLLABLE NGO;Lo;0;L;;;;;N;;;;;\nA26A;YI SYLLABLE NGOP;Lo;0;L;;;;;N;;;;;\nA26B;YI SYLLABLE NGEX;Lo;0;L;;;;;N;;;;;\nA26C;YI SYLLABLE NGE;Lo;0;L;;;;;N;;;;;\nA26D;YI SYLLABLE NGEP;Lo;0;L;;;;;N;;;;;\nA26E;YI SYLLABLE HIT;Lo;0;L;;;;;N;;;;;\nA26F;YI SYLLABLE HIEX;Lo;0;L;;;;;N;;;;;\nA270;YI SYLLABLE HIE;Lo;0;L;;;;;N;;;;;\nA271;YI SYLLABLE HAT;Lo;0;L;;;;;N;;;;;\nA272;YI SYLLABLE HAX;Lo;0;L;;;;;N;;;;;\nA273;YI SYLLABLE HA;Lo;0;L;;;;;N;;;;;\nA274;YI SYLLABLE HAP;Lo;0;L;;;;;N;;;;;\nA275;YI SYLLABLE HUOT;Lo;0;L;;;;;N;;;;;\nA276;YI SYLLABLE HUOX;Lo;0;L;;;;;N;;;;;\nA277;YI SYLLABLE HUO;Lo;0;L;;;;;N;;;;;\nA278;YI SYLLABLE HUOP;Lo;0;L;;;;;N;;;;;\nA279;YI SYLLABLE HOT;Lo;0;L;;;;;N;;;;;\nA27A;YI SYLLABLE HOX;Lo;0;L;;;;;N;;;;;\nA27B;YI SYLLABLE HO;Lo;0;L;;;;;N;;;;;\nA27C;YI SYLLABLE HOP;Lo;0;L;;;;;N;;;;;\nA27D;YI SYLLABLE HEX;Lo;0;L;;;;;N;;;;;\nA27E;YI SYLLABLE HE;Lo;0;L;;;;;N;;;;;\nA27F;YI SYLLABLE HEP;Lo;0;L;;;;;N;;;;;\nA280;YI SYLLABLE WAT;Lo;0;L;;;;;N;;;;;\nA281;YI SYLLABLE WAX;Lo;0;L;;;;;N;;;;;\nA282;YI SYLLABLE WA;Lo;0;L;;;;;N;;;;;\nA283;YI SYLLABLE WAP;Lo;0;L;;;;;N;;;;;\nA284;YI SYLLABLE WUOX;Lo;0;L;;;;;N;;;;;\nA285;YI SYLLABLE WUO;Lo;0;L;;;;;N;;;;;\nA286;YI SYLLABLE WUOP;Lo;0;L;;;;;N;;;;;\nA287;YI SYLLABLE WOX;Lo;0;L;;;;;N;;;;;\nA288;YI SYLLABLE WO;Lo;0;L;;;;;N;;;;;\nA289;YI SYLLABLE WOP;Lo;0;L;;;;;N;;;;;\nA28A;YI SYLLABLE WEX;Lo;0;L;;;;;N;;;;;\nA28B;YI SYLLABLE WE;Lo;0;L;;;;;N;;;;;\nA28C;YI SYLLABLE WEP;Lo;0;L;;;;;N;;;;;\nA28D;YI SYLLABLE ZIT;Lo;0;L;;;;;N;;;;;\nA28E;YI SYLLABLE ZIX;Lo;0;L;;;;;N;;;;;\nA28F;YI SYLLABLE ZI;Lo;0;L;;;;;N;;;;;\nA290;YI SYLLABLE ZIP;Lo;0;L;;;;;N;;;;;\nA291;YI SYLLABLE ZIEX;Lo;0;L;;;;;N;;;;;\nA292;YI SYLLABLE ZIE;Lo;0;L;;;;;N;;;;;\nA293;YI SYLLABLE ZIEP;Lo;0;L;;;;;N;;;;;\nA294;YI SYLLABLE ZAT;Lo;0;L;;;;;N;;;;;\nA295;YI SYLLABLE ZAX;Lo;0;L;;;;;N;;;;;\nA296;YI SYLLABLE ZA;Lo;0;L;;;;;N;;;;;\nA297;YI SYLLABLE ZAP;Lo;0;L;;;;;N;;;;;\nA298;YI SYLLABLE ZUOX;Lo;0;L;;;;;N;;;;;\nA299;YI SYLLABLE ZUO;Lo;0;L;;;;;N;;;;;\nA29A;YI SYLLABLE ZUOP;Lo;0;L;;;;;N;;;;;\nA29B;YI SYLLABLE ZOT;Lo;0;L;;;;;N;;;;;\nA29C;YI SYLLABLE ZOX;Lo;0;L;;;;;N;;;;;\nA29D;YI SYLLABLE ZO;Lo;0;L;;;;;N;;;;;\nA29E;YI SYLLABLE ZOP;Lo;0;L;;;;;N;;;;;\nA29F;YI SYLLABLE ZEX;Lo;0;L;;;;;N;;;;;\nA2A0;YI SYLLABLE ZE;Lo;0;L;;;;;N;;;;;\nA2A1;YI SYLLABLE ZEP;Lo;0;L;;;;;N;;;;;\nA2A2;YI SYLLABLE ZUT;Lo;0;L;;;;;N;;;;;\nA2A3;YI SYLLABLE ZUX;Lo;0;L;;;;;N;;;;;\nA2A4;YI SYLLABLE ZU;Lo;0;L;;;;;N;;;;;\nA2A5;YI SYLLABLE ZUP;Lo;0;L;;;;;N;;;;;\nA2A6;YI SYLLABLE ZURX;Lo;0;L;;;;;N;;;;;\nA2A7;YI SYLLABLE ZUR;Lo;0;L;;;;;N;;;;;\nA2A8;YI SYLLABLE ZYT;Lo;0;L;;;;;N;;;;;\nA2A9;YI SYLLABLE ZYX;Lo;0;L;;;;;N;;;;;\nA2AA;YI SYLLABLE ZY;Lo;0;L;;;;;N;;;;;\nA2AB;YI SYLLABLE ZYP;Lo;0;L;;;;;N;;;;;\nA2AC;YI SYLLABLE ZYRX;Lo;0;L;;;;;N;;;;;\nA2AD;YI SYLLABLE ZYR;Lo;0;L;;;;;N;;;;;\nA2AE;YI SYLLABLE CIT;Lo;0;L;;;;;N;;;;;\nA2AF;YI SYLLABLE CIX;Lo;0;L;;;;;N;;;;;\nA2B0;YI SYLLABLE CI;Lo;0;L;;;;;N;;;;;\nA2B1;YI SYLLABLE CIP;Lo;0;L;;;;;N;;;;;\nA2B2;YI SYLLABLE CIET;Lo;0;L;;;;;N;;;;;\nA2B3;YI SYLLABLE CIEX;Lo;0;L;;;;;N;;;;;\nA2B4;YI SYLLABLE CIE;Lo;0;L;;;;;N;;;;;\nA2B5;YI SYLLABLE CIEP;Lo;0;L;;;;;N;;;;;\nA2B6;YI SYLLABLE CAT;Lo;0;L;;;;;N;;;;;\nA2B7;YI SYLLABLE CAX;Lo;0;L;;;;;N;;;;;\nA2B8;YI SYLLABLE CA;Lo;0;L;;;;;N;;;;;\nA2B9;YI SYLLABLE CAP;Lo;0;L;;;;;N;;;;;\nA2BA;YI SYLLABLE CUOX;Lo;0;L;;;;;N;;;;;\nA2BB;YI SYLLABLE CUO;Lo;0;L;;;;;N;;;;;\nA2BC;YI SYLLABLE CUOP;Lo;0;L;;;;;N;;;;;\nA2BD;YI SYLLABLE COT;Lo;0;L;;;;;N;;;;;\nA2BE;YI SYLLABLE COX;Lo;0;L;;;;;N;;;;;\nA2BF;YI SYLLABLE CO;Lo;0;L;;;;;N;;;;;\nA2C0;YI SYLLABLE COP;Lo;0;L;;;;;N;;;;;\nA2C1;YI SYLLABLE CEX;Lo;0;L;;;;;N;;;;;\nA2C2;YI SYLLABLE CE;Lo;0;L;;;;;N;;;;;\nA2C3;YI SYLLABLE CEP;Lo;0;L;;;;;N;;;;;\nA2C4;YI SYLLABLE CUT;Lo;0;L;;;;;N;;;;;\nA2C5;YI SYLLABLE CUX;Lo;0;L;;;;;N;;;;;\nA2C6;YI SYLLABLE CU;Lo;0;L;;;;;N;;;;;\nA2C7;YI SYLLABLE CUP;Lo;0;L;;;;;N;;;;;\nA2C8;YI SYLLABLE CURX;Lo;0;L;;;;;N;;;;;\nA2C9;YI SYLLABLE CUR;Lo;0;L;;;;;N;;;;;\nA2CA;YI SYLLABLE CYT;Lo;0;L;;;;;N;;;;;\nA2CB;YI SYLLABLE CYX;Lo;0;L;;;;;N;;;;;\nA2CC;YI SYLLABLE CY;Lo;0;L;;;;;N;;;;;\nA2CD;YI SYLLABLE CYP;Lo;0;L;;;;;N;;;;;\nA2CE;YI SYLLABLE CYRX;Lo;0;L;;;;;N;;;;;\nA2CF;YI SYLLABLE CYR;Lo;0;L;;;;;N;;;;;\nA2D0;YI SYLLABLE ZZIT;Lo;0;L;;;;;N;;;;;\nA2D1;YI SYLLABLE ZZIX;Lo;0;L;;;;;N;;;;;\nA2D2;YI SYLLABLE ZZI;Lo;0;L;;;;;N;;;;;\nA2D3;YI SYLLABLE ZZIP;Lo;0;L;;;;;N;;;;;\nA2D4;YI SYLLABLE ZZIET;Lo;0;L;;;;;N;;;;;\nA2D5;YI SYLLABLE ZZIEX;Lo;0;L;;;;;N;;;;;\nA2D6;YI SYLLABLE ZZIE;Lo;0;L;;;;;N;;;;;\nA2D7;YI SYLLABLE ZZIEP;Lo;0;L;;;;;N;;;;;\nA2D8;YI SYLLABLE ZZAT;Lo;0;L;;;;;N;;;;;\nA2D9;YI SYLLABLE ZZAX;Lo;0;L;;;;;N;;;;;\nA2DA;YI SYLLABLE ZZA;Lo;0;L;;;;;N;;;;;\nA2DB;YI SYLLABLE ZZAP;Lo;0;L;;;;;N;;;;;\nA2DC;YI SYLLABLE ZZOX;Lo;0;L;;;;;N;;;;;\nA2DD;YI SYLLABLE ZZO;Lo;0;L;;;;;N;;;;;\nA2DE;YI SYLLABLE ZZOP;Lo;0;L;;;;;N;;;;;\nA2DF;YI SYLLABLE ZZEX;Lo;0;L;;;;;N;;;;;\nA2E0;YI SYLLABLE ZZE;Lo;0;L;;;;;N;;;;;\nA2E1;YI SYLLABLE ZZEP;Lo;0;L;;;;;N;;;;;\nA2E2;YI SYLLABLE ZZUX;Lo;0;L;;;;;N;;;;;\nA2E3;YI SYLLABLE ZZU;Lo;0;L;;;;;N;;;;;\nA2E4;YI SYLLABLE ZZUP;Lo;0;L;;;;;N;;;;;\nA2E5;YI SYLLABLE ZZURX;Lo;0;L;;;;;N;;;;;\nA2E6;YI SYLLABLE ZZUR;Lo;0;L;;;;;N;;;;;\nA2E7;YI SYLLABLE ZZYT;Lo;0;L;;;;;N;;;;;\nA2E8;YI SYLLABLE ZZYX;Lo;0;L;;;;;N;;;;;\nA2E9;YI SYLLABLE ZZY;Lo;0;L;;;;;N;;;;;\nA2EA;YI SYLLABLE ZZYP;Lo;0;L;;;;;N;;;;;\nA2EB;YI SYLLABLE ZZYRX;Lo;0;L;;;;;N;;;;;\nA2EC;YI SYLLABLE ZZYR;Lo;0;L;;;;;N;;;;;\nA2ED;YI SYLLABLE NZIT;Lo;0;L;;;;;N;;;;;\nA2EE;YI SYLLABLE NZIX;Lo;0;L;;;;;N;;;;;\nA2EF;YI SYLLABLE NZI;Lo;0;L;;;;;N;;;;;\nA2F0;YI SYLLABLE NZIP;Lo;0;L;;;;;N;;;;;\nA2F1;YI SYLLABLE NZIEX;Lo;0;L;;;;;N;;;;;\nA2F2;YI SYLLABLE NZIE;Lo;0;L;;;;;N;;;;;\nA2F3;YI SYLLABLE NZIEP;Lo;0;L;;;;;N;;;;;\nA2F4;YI SYLLABLE NZAT;Lo;0;L;;;;;N;;;;;\nA2F5;YI SYLLABLE NZAX;Lo;0;L;;;;;N;;;;;\nA2F6;YI SYLLABLE NZA;Lo;0;L;;;;;N;;;;;\nA2F7;YI SYLLABLE NZAP;Lo;0;L;;;;;N;;;;;\nA2F8;YI SYLLABLE NZUOX;Lo;0;L;;;;;N;;;;;\nA2F9;YI SYLLABLE NZUO;Lo;0;L;;;;;N;;;;;\nA2FA;YI SYLLABLE NZOX;Lo;0;L;;;;;N;;;;;\nA2FB;YI SYLLABLE NZOP;Lo;0;L;;;;;N;;;;;\nA2FC;YI SYLLABLE NZEX;Lo;0;L;;;;;N;;;;;\nA2FD;YI SYLLABLE NZE;Lo;0;L;;;;;N;;;;;\nA2FE;YI SYLLABLE NZUX;Lo;0;L;;;;;N;;;;;\nA2FF;YI SYLLABLE NZU;Lo;0;L;;;;;N;;;;;\nA300;YI SYLLABLE NZUP;Lo;0;L;;;;;N;;;;;\nA301;YI SYLLABLE NZURX;Lo;0;L;;;;;N;;;;;\nA302;YI SYLLABLE NZUR;Lo;0;L;;;;;N;;;;;\nA303;YI SYLLABLE NZYT;Lo;0;L;;;;;N;;;;;\nA304;YI SYLLABLE NZYX;Lo;0;L;;;;;N;;;;;\nA305;YI SYLLABLE NZY;Lo;0;L;;;;;N;;;;;\nA306;YI SYLLABLE NZYP;Lo;0;L;;;;;N;;;;;\nA307;YI SYLLABLE NZYRX;Lo;0;L;;;;;N;;;;;\nA308;YI SYLLABLE NZYR;Lo;0;L;;;;;N;;;;;\nA309;YI SYLLABLE SIT;Lo;0;L;;;;;N;;;;;\nA30A;YI SYLLABLE SIX;Lo;0;L;;;;;N;;;;;\nA30B;YI SYLLABLE SI;Lo;0;L;;;;;N;;;;;\nA30C;YI SYLLABLE SIP;Lo;0;L;;;;;N;;;;;\nA30D;YI SYLLABLE SIEX;Lo;0;L;;;;;N;;;;;\nA30E;YI SYLLABLE SIE;Lo;0;L;;;;;N;;;;;\nA30F;YI SYLLABLE SIEP;Lo;0;L;;;;;N;;;;;\nA310;YI SYLLABLE SAT;Lo;0;L;;;;;N;;;;;\nA311;YI SYLLABLE SAX;Lo;0;L;;;;;N;;;;;\nA312;YI SYLLABLE SA;Lo;0;L;;;;;N;;;;;\nA313;YI SYLLABLE SAP;Lo;0;L;;;;;N;;;;;\nA314;YI SYLLABLE SUOX;Lo;0;L;;;;;N;;;;;\nA315;YI SYLLABLE SUO;Lo;0;L;;;;;N;;;;;\nA316;YI SYLLABLE SUOP;Lo;0;L;;;;;N;;;;;\nA317;YI SYLLABLE SOT;Lo;0;L;;;;;N;;;;;\nA318;YI SYLLABLE SOX;Lo;0;L;;;;;N;;;;;\nA319;YI SYLLABLE SO;Lo;0;L;;;;;N;;;;;\nA31A;YI SYLLABLE SOP;Lo;0;L;;;;;N;;;;;\nA31B;YI SYLLABLE SEX;Lo;0;L;;;;;N;;;;;\nA31C;YI SYLLABLE SE;Lo;0;L;;;;;N;;;;;\nA31D;YI SYLLABLE SEP;Lo;0;L;;;;;N;;;;;\nA31E;YI SYLLABLE SUT;Lo;0;L;;;;;N;;;;;\nA31F;YI SYLLABLE SUX;Lo;0;L;;;;;N;;;;;\nA320;YI SYLLABLE SU;Lo;0;L;;;;;N;;;;;\nA321;YI SYLLABLE SUP;Lo;0;L;;;;;N;;;;;\nA322;YI SYLLABLE SURX;Lo;0;L;;;;;N;;;;;\nA323;YI SYLLABLE SUR;Lo;0;L;;;;;N;;;;;\nA324;YI SYLLABLE SYT;Lo;0;L;;;;;N;;;;;\nA325;YI SYLLABLE SYX;Lo;0;L;;;;;N;;;;;\nA326;YI SYLLABLE SY;Lo;0;L;;;;;N;;;;;\nA327;YI SYLLABLE SYP;Lo;0;L;;;;;N;;;;;\nA328;YI SYLLABLE SYRX;Lo;0;L;;;;;N;;;;;\nA329;YI SYLLABLE SYR;Lo;0;L;;;;;N;;;;;\nA32A;YI SYLLABLE SSIT;Lo;0;L;;;;;N;;;;;\nA32B;YI SYLLABLE SSIX;Lo;0;L;;;;;N;;;;;\nA32C;YI SYLLABLE SSI;Lo;0;L;;;;;N;;;;;\nA32D;YI SYLLABLE SSIP;Lo;0;L;;;;;N;;;;;\nA32E;YI SYLLABLE SSIEX;Lo;0;L;;;;;N;;;;;\nA32F;YI SYLLABLE SSIE;Lo;0;L;;;;;N;;;;;\nA330;YI SYLLABLE SSIEP;Lo;0;L;;;;;N;;;;;\nA331;YI SYLLABLE SSAT;Lo;0;L;;;;;N;;;;;\nA332;YI SYLLABLE SSAX;Lo;0;L;;;;;N;;;;;\nA333;YI SYLLABLE SSA;Lo;0;L;;;;;N;;;;;\nA334;YI SYLLABLE SSAP;Lo;0;L;;;;;N;;;;;\nA335;YI SYLLABLE SSOT;Lo;0;L;;;;;N;;;;;\nA336;YI SYLLABLE SSOX;Lo;0;L;;;;;N;;;;;\nA337;YI SYLLABLE SSO;Lo;0;L;;;;;N;;;;;\nA338;YI SYLLABLE SSOP;Lo;0;L;;;;;N;;;;;\nA339;YI SYLLABLE SSEX;Lo;0;L;;;;;N;;;;;\nA33A;YI SYLLABLE SSE;Lo;0;L;;;;;N;;;;;\nA33B;YI SYLLABLE SSEP;Lo;0;L;;;;;N;;;;;\nA33C;YI SYLLABLE SSUT;Lo;0;L;;;;;N;;;;;\nA33D;YI SYLLABLE SSUX;Lo;0;L;;;;;N;;;;;\nA33E;YI SYLLABLE SSU;Lo;0;L;;;;;N;;;;;\nA33F;YI SYLLABLE SSUP;Lo;0;L;;;;;N;;;;;\nA340;YI SYLLABLE SSYT;Lo;0;L;;;;;N;;;;;\nA341;YI SYLLABLE SSYX;Lo;0;L;;;;;N;;;;;\nA342;YI SYLLABLE SSY;Lo;0;L;;;;;N;;;;;\nA343;YI SYLLABLE SSYP;Lo;0;L;;;;;N;;;;;\nA344;YI SYLLABLE SSYRX;Lo;0;L;;;;;N;;;;;\nA345;YI SYLLABLE SSYR;Lo;0;L;;;;;N;;;;;\nA346;YI SYLLABLE ZHAT;Lo;0;L;;;;;N;;;;;\nA347;YI SYLLABLE ZHAX;Lo;0;L;;;;;N;;;;;\nA348;YI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;;\nA349;YI SYLLABLE ZHAP;Lo;0;L;;;;;N;;;;;\nA34A;YI SYLLABLE ZHUOX;Lo;0;L;;;;;N;;;;;\nA34B;YI SYLLABLE ZHUO;Lo;0;L;;;;;N;;;;;\nA34C;YI SYLLABLE ZHUOP;Lo;0;L;;;;;N;;;;;\nA34D;YI SYLLABLE ZHOT;Lo;0;L;;;;;N;;;;;\nA34E;YI SYLLABLE ZHOX;Lo;0;L;;;;;N;;;;;\nA34F;YI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;;\nA350;YI SYLLABLE ZHOP;Lo;0;L;;;;;N;;;;;\nA351;YI SYLLABLE ZHET;Lo;0;L;;;;;N;;;;;\nA352;YI SYLLABLE ZHEX;Lo;0;L;;;;;N;;;;;\nA353;YI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;;\nA354;YI SYLLABLE ZHEP;Lo;0;L;;;;;N;;;;;\nA355;YI SYLLABLE ZHUT;Lo;0;L;;;;;N;;;;;\nA356;YI SYLLABLE ZHUX;Lo;0;L;;;;;N;;;;;\nA357;YI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;;\nA358;YI SYLLABLE ZHUP;Lo;0;L;;;;;N;;;;;\nA359;YI SYLLABLE ZHURX;Lo;0;L;;;;;N;;;;;\nA35A;YI SYLLABLE ZHUR;Lo;0;L;;;;;N;;;;;\nA35B;YI SYLLABLE ZHYT;Lo;0;L;;;;;N;;;;;\nA35C;YI SYLLABLE ZHYX;Lo;0;L;;;;;N;;;;;\nA35D;YI SYLLABLE ZHY;Lo;0;L;;;;;N;;;;;\nA35E;YI SYLLABLE ZHYP;Lo;0;L;;;;;N;;;;;\nA35F;YI SYLLABLE ZHYRX;Lo;0;L;;;;;N;;;;;\nA360;YI SYLLABLE ZHYR;Lo;0;L;;;;;N;;;;;\nA361;YI SYLLABLE CHAT;Lo;0;L;;;;;N;;;;;\nA362;YI SYLLABLE CHAX;Lo;0;L;;;;;N;;;;;\nA363;YI SYLLABLE CHA;Lo;0;L;;;;;N;;;;;\nA364;YI SYLLABLE CHAP;Lo;0;L;;;;;N;;;;;\nA365;YI SYLLABLE CHUOT;Lo;0;L;;;;;N;;;;;\nA366;YI SYLLABLE CHUOX;Lo;0;L;;;;;N;;;;;\nA367;YI SYLLABLE CHUO;Lo;0;L;;;;;N;;;;;\nA368;YI SYLLABLE CHUOP;Lo;0;L;;;;;N;;;;;\nA369;YI SYLLABLE CHOT;Lo;0;L;;;;;N;;;;;\nA36A;YI SYLLABLE CHOX;Lo;0;L;;;;;N;;;;;\nA36B;YI SYLLABLE CHO;Lo;0;L;;;;;N;;;;;\nA36C;YI SYLLABLE CHOP;Lo;0;L;;;;;N;;;;;\nA36D;YI SYLLABLE CHET;Lo;0;L;;;;;N;;;;;\nA36E;YI SYLLABLE CHEX;Lo;0;L;;;;;N;;;;;\nA36F;YI SYLLABLE CHE;Lo;0;L;;;;;N;;;;;\nA370;YI SYLLABLE CHEP;Lo;0;L;;;;;N;;;;;\nA371;YI SYLLABLE CHUX;Lo;0;L;;;;;N;;;;;\nA372;YI SYLLABLE CHU;Lo;0;L;;;;;N;;;;;\nA373;YI SYLLABLE CHUP;Lo;0;L;;;;;N;;;;;\nA374;YI SYLLABLE CHURX;Lo;0;L;;;;;N;;;;;\nA375;YI SYLLABLE CHUR;Lo;0;L;;;;;N;;;;;\nA376;YI SYLLABLE CHYT;Lo;0;L;;;;;N;;;;;\nA377;YI SYLLABLE CHYX;Lo;0;L;;;;;N;;;;;\nA378;YI SYLLABLE CHY;Lo;0;L;;;;;N;;;;;\nA379;YI SYLLABLE CHYP;Lo;0;L;;;;;N;;;;;\nA37A;YI SYLLABLE CHYRX;Lo;0;L;;;;;N;;;;;\nA37B;YI SYLLABLE CHYR;Lo;0;L;;;;;N;;;;;\nA37C;YI SYLLABLE RRAX;Lo;0;L;;;;;N;;;;;\nA37D;YI SYLLABLE RRA;Lo;0;L;;;;;N;;;;;\nA37E;YI SYLLABLE RRUOX;Lo;0;L;;;;;N;;;;;\nA37F;YI SYLLABLE RRUO;Lo;0;L;;;;;N;;;;;\nA380;YI SYLLABLE RROT;Lo;0;L;;;;;N;;;;;\nA381;YI SYLLABLE RROX;Lo;0;L;;;;;N;;;;;\nA382;YI SYLLABLE RRO;Lo;0;L;;;;;N;;;;;\nA383;YI SYLLABLE RROP;Lo;0;L;;;;;N;;;;;\nA384;YI SYLLABLE RRET;Lo;0;L;;;;;N;;;;;\nA385;YI SYLLABLE RREX;Lo;0;L;;;;;N;;;;;\nA386;YI SYLLABLE RRE;Lo;0;L;;;;;N;;;;;\nA387;YI SYLLABLE RREP;Lo;0;L;;;;;N;;;;;\nA388;YI SYLLABLE RRUT;Lo;0;L;;;;;N;;;;;\nA389;YI SYLLABLE RRUX;Lo;0;L;;;;;N;;;;;\nA38A;YI SYLLABLE RRU;Lo;0;L;;;;;N;;;;;\nA38B;YI SYLLABLE RRUP;Lo;0;L;;;;;N;;;;;\nA38C;YI SYLLABLE RRURX;Lo;0;L;;;;;N;;;;;\nA38D;YI SYLLABLE RRUR;Lo;0;L;;;;;N;;;;;\nA38E;YI SYLLABLE RRYT;Lo;0;L;;;;;N;;;;;\nA38F;YI SYLLABLE RRYX;Lo;0;L;;;;;N;;;;;\nA390;YI SYLLABLE RRY;Lo;0;L;;;;;N;;;;;\nA391;YI SYLLABLE RRYP;Lo;0;L;;;;;N;;;;;\nA392;YI SYLLABLE RRYRX;Lo;0;L;;;;;N;;;;;\nA393;YI SYLLABLE RRYR;Lo;0;L;;;;;N;;;;;\nA394;YI SYLLABLE NRAT;Lo;0;L;;;;;N;;;;;\nA395;YI SYLLABLE NRAX;Lo;0;L;;;;;N;;;;;\nA396;YI SYLLABLE NRA;Lo;0;L;;;;;N;;;;;\nA397;YI SYLLABLE NRAP;Lo;0;L;;;;;N;;;;;\nA398;YI SYLLABLE NROX;Lo;0;L;;;;;N;;;;;\nA399;YI SYLLABLE NRO;Lo;0;L;;;;;N;;;;;\nA39A;YI SYLLABLE NROP;Lo;0;L;;;;;N;;;;;\nA39B;YI SYLLABLE NRET;Lo;0;L;;;;;N;;;;;\nA39C;YI SYLLABLE NREX;Lo;0;L;;;;;N;;;;;\nA39D;YI SYLLABLE NRE;Lo;0;L;;;;;N;;;;;\nA39E;YI SYLLABLE NREP;Lo;0;L;;;;;N;;;;;\nA39F;YI SYLLABLE NRUT;Lo;0;L;;;;;N;;;;;\nA3A0;YI SYLLABLE NRUX;Lo;0;L;;;;;N;;;;;\nA3A1;YI SYLLABLE NRU;Lo;0;L;;;;;N;;;;;\nA3A2;YI SYLLABLE NRUP;Lo;0;L;;;;;N;;;;;\nA3A3;YI SYLLABLE NRURX;Lo;0;L;;;;;N;;;;;\nA3A4;YI SYLLABLE NRUR;Lo;0;L;;;;;N;;;;;\nA3A5;YI SYLLABLE NRYT;Lo;0;L;;;;;N;;;;;\nA3A6;YI SYLLABLE NRYX;Lo;0;L;;;;;N;;;;;\nA3A7;YI SYLLABLE NRY;Lo;0;L;;;;;N;;;;;\nA3A8;YI SYLLABLE NRYP;Lo;0;L;;;;;N;;;;;\nA3A9;YI SYLLABLE NRYRX;Lo;0;L;;;;;N;;;;;\nA3AA;YI SYLLABLE NRYR;Lo;0;L;;;;;N;;;;;\nA3AB;YI SYLLABLE SHAT;Lo;0;L;;;;;N;;;;;\nA3AC;YI SYLLABLE SHAX;Lo;0;L;;;;;N;;;;;\nA3AD;YI SYLLABLE SHA;Lo;0;L;;;;;N;;;;;\nA3AE;YI SYLLABLE SHAP;Lo;0;L;;;;;N;;;;;\nA3AF;YI SYLLABLE SHUOX;Lo;0;L;;;;;N;;;;;\nA3B0;YI SYLLABLE SHUO;Lo;0;L;;;;;N;;;;;\nA3B1;YI SYLLABLE SHUOP;Lo;0;L;;;;;N;;;;;\nA3B2;YI SYLLABLE SHOT;Lo;0;L;;;;;N;;;;;\nA3B3;YI SYLLABLE SHOX;Lo;0;L;;;;;N;;;;;\nA3B4;YI SYLLABLE SHO;Lo;0;L;;;;;N;;;;;\nA3B5;YI SYLLABLE SHOP;Lo;0;L;;;;;N;;;;;\nA3B6;YI SYLLABLE SHET;Lo;0;L;;;;;N;;;;;\nA3B7;YI SYLLABLE SHEX;Lo;0;L;;;;;N;;;;;\nA3B8;YI SYLLABLE SHE;Lo;0;L;;;;;N;;;;;\nA3B9;YI SYLLABLE SHEP;Lo;0;L;;;;;N;;;;;\nA3BA;YI SYLLABLE SHUT;Lo;0;L;;;;;N;;;;;\nA3BB;YI SYLLABLE SHUX;Lo;0;L;;;;;N;;;;;\nA3BC;YI SYLLABLE SHU;Lo;0;L;;;;;N;;;;;\nA3BD;YI SYLLABLE SHUP;Lo;0;L;;;;;N;;;;;\nA3BE;YI SYLLABLE SHURX;Lo;0;L;;;;;N;;;;;\nA3BF;YI SYLLABLE SHUR;Lo;0;L;;;;;N;;;;;\nA3C0;YI SYLLABLE SHYT;Lo;0;L;;;;;N;;;;;\nA3C1;YI SYLLABLE SHYX;Lo;0;L;;;;;N;;;;;\nA3C2;YI SYLLABLE SHY;Lo;0;L;;;;;N;;;;;\nA3C3;YI SYLLABLE SHYP;Lo;0;L;;;;;N;;;;;\nA3C4;YI SYLLABLE SHYRX;Lo;0;L;;;;;N;;;;;\nA3C5;YI SYLLABLE SHYR;Lo;0;L;;;;;N;;;;;\nA3C6;YI SYLLABLE RAT;Lo;0;L;;;;;N;;;;;\nA3C7;YI SYLLABLE RAX;Lo;0;L;;;;;N;;;;;\nA3C8;YI SYLLABLE RA;Lo;0;L;;;;;N;;;;;\nA3C9;YI SYLLABLE RAP;Lo;0;L;;;;;N;;;;;\nA3CA;YI SYLLABLE RUOX;Lo;0;L;;;;;N;;;;;\nA3CB;YI SYLLABLE RUO;Lo;0;L;;;;;N;;;;;\nA3CC;YI SYLLABLE RUOP;Lo;0;L;;;;;N;;;;;\nA3CD;YI SYLLABLE ROT;Lo;0;L;;;;;N;;;;;\nA3CE;YI SYLLABLE ROX;Lo;0;L;;;;;N;;;;;\nA3CF;YI SYLLABLE RO;Lo;0;L;;;;;N;;;;;\nA3D0;YI SYLLABLE ROP;Lo;0;L;;;;;N;;;;;\nA3D1;YI SYLLABLE REX;Lo;0;L;;;;;N;;;;;\nA3D2;YI SYLLABLE RE;Lo;0;L;;;;;N;;;;;\nA3D3;YI SYLLABLE REP;Lo;0;L;;;;;N;;;;;\nA3D4;YI SYLLABLE RUT;Lo;0;L;;;;;N;;;;;\nA3D5;YI SYLLABLE RUX;Lo;0;L;;;;;N;;;;;\nA3D6;YI SYLLABLE RU;Lo;0;L;;;;;N;;;;;\nA3D7;YI SYLLABLE RUP;Lo;0;L;;;;;N;;;;;\nA3D8;YI SYLLABLE RURX;Lo;0;L;;;;;N;;;;;\nA3D9;YI SYLLABLE RUR;Lo;0;L;;;;;N;;;;;\nA3DA;YI SYLLABLE RYT;Lo;0;L;;;;;N;;;;;\nA3DB;YI SYLLABLE RYX;Lo;0;L;;;;;N;;;;;\nA3DC;YI SYLLABLE RY;Lo;0;L;;;;;N;;;;;\nA3DD;YI SYLLABLE RYP;Lo;0;L;;;;;N;;;;;\nA3DE;YI SYLLABLE RYRX;Lo;0;L;;;;;N;;;;;\nA3DF;YI SYLLABLE RYR;Lo;0;L;;;;;N;;;;;\nA3E0;YI SYLLABLE JIT;Lo;0;L;;;;;N;;;;;\nA3E1;YI SYLLABLE JIX;Lo;0;L;;;;;N;;;;;\nA3E2;YI SYLLABLE JI;Lo;0;L;;;;;N;;;;;\nA3E3;YI SYLLABLE JIP;Lo;0;L;;;;;N;;;;;\nA3E4;YI SYLLABLE JIET;Lo;0;L;;;;;N;;;;;\nA3E5;YI SYLLABLE JIEX;Lo;0;L;;;;;N;;;;;\nA3E6;YI SYLLABLE JIE;Lo;0;L;;;;;N;;;;;\nA3E7;YI SYLLABLE JIEP;Lo;0;L;;;;;N;;;;;\nA3E8;YI SYLLABLE JUOT;Lo;0;L;;;;;N;;;;;\nA3E9;YI SYLLABLE JUOX;Lo;0;L;;;;;N;;;;;\nA3EA;YI SYLLABLE JUO;Lo;0;L;;;;;N;;;;;\nA3EB;YI SYLLABLE JUOP;Lo;0;L;;;;;N;;;;;\nA3EC;YI SYLLABLE JOT;Lo;0;L;;;;;N;;;;;\nA3ED;YI SYLLABLE JOX;Lo;0;L;;;;;N;;;;;\nA3EE;YI SYLLABLE JO;Lo;0;L;;;;;N;;;;;\nA3EF;YI SYLLABLE JOP;Lo;0;L;;;;;N;;;;;\nA3F0;YI SYLLABLE JUT;Lo;0;L;;;;;N;;;;;\nA3F1;YI SYLLABLE JUX;Lo;0;L;;;;;N;;;;;\nA3F2;YI SYLLABLE JU;Lo;0;L;;;;;N;;;;;\nA3F3;YI SYLLABLE JUP;Lo;0;L;;;;;N;;;;;\nA3F4;YI SYLLABLE JURX;Lo;0;L;;;;;N;;;;;\nA3F5;YI SYLLABLE JUR;Lo;0;L;;;;;N;;;;;\nA3F6;YI SYLLABLE JYT;Lo;0;L;;;;;N;;;;;\nA3F7;YI SYLLABLE JYX;Lo;0;L;;;;;N;;;;;\nA3F8;YI SYLLABLE JY;Lo;0;L;;;;;N;;;;;\nA3F9;YI SYLLABLE JYP;Lo;0;L;;;;;N;;;;;\nA3FA;YI SYLLABLE JYRX;Lo;0;L;;;;;N;;;;;\nA3FB;YI SYLLABLE JYR;Lo;0;L;;;;;N;;;;;\nA3FC;YI SYLLABLE QIT;Lo;0;L;;;;;N;;;;;\nA3FD;YI SYLLABLE QIX;Lo;0;L;;;;;N;;;;;\nA3FE;YI SYLLABLE QI;Lo;0;L;;;;;N;;;;;\nA3FF;YI SYLLABLE QIP;Lo;0;L;;;;;N;;;;;\nA400;YI SYLLABLE QIET;Lo;0;L;;;;;N;;;;;\nA401;YI SYLLABLE QIEX;Lo;0;L;;;;;N;;;;;\nA402;YI SYLLABLE QIE;Lo;0;L;;;;;N;;;;;\nA403;YI SYLLABLE QIEP;Lo;0;L;;;;;N;;;;;\nA404;YI SYLLABLE QUOT;Lo;0;L;;;;;N;;;;;\nA405;YI SYLLABLE QUOX;Lo;0;L;;;;;N;;;;;\nA406;YI SYLLABLE QUO;Lo;0;L;;;;;N;;;;;\nA407;YI SYLLABLE QUOP;Lo;0;L;;;;;N;;;;;\nA408;YI SYLLABLE QOT;Lo;0;L;;;;;N;;;;;\nA409;YI SYLLABLE QOX;Lo;0;L;;;;;N;;;;;\nA40A;YI SYLLABLE QO;Lo;0;L;;;;;N;;;;;\nA40B;YI SYLLABLE QOP;Lo;0;L;;;;;N;;;;;\nA40C;YI SYLLABLE QUT;Lo;0;L;;;;;N;;;;;\nA40D;YI SYLLABLE QUX;Lo;0;L;;;;;N;;;;;\nA40E;YI SYLLABLE QU;Lo;0;L;;;;;N;;;;;\nA40F;YI SYLLABLE QUP;Lo;0;L;;;;;N;;;;;\nA410;YI SYLLABLE QURX;Lo;0;L;;;;;N;;;;;\nA411;YI SYLLABLE QUR;Lo;0;L;;;;;N;;;;;\nA412;YI SYLLABLE QYT;Lo;0;L;;;;;N;;;;;\nA413;YI SYLLABLE QYX;Lo;0;L;;;;;N;;;;;\nA414;YI SYLLABLE QY;Lo;0;L;;;;;N;;;;;\nA415;YI SYLLABLE QYP;Lo;0;L;;;;;N;;;;;\nA416;YI SYLLABLE QYRX;Lo;0;L;;;;;N;;;;;\nA417;YI SYLLABLE QYR;Lo;0;L;;;;;N;;;;;\nA418;YI SYLLABLE JJIT;Lo;0;L;;;;;N;;;;;\nA419;YI SYLLABLE JJIX;Lo;0;L;;;;;N;;;;;\nA41A;YI SYLLABLE JJI;Lo;0;L;;;;;N;;;;;\nA41B;YI SYLLABLE JJIP;Lo;0;L;;;;;N;;;;;\nA41C;YI SYLLABLE JJIET;Lo;0;L;;;;;N;;;;;\nA41D;YI SYLLABLE JJIEX;Lo;0;L;;;;;N;;;;;\nA41E;YI SYLLABLE JJIE;Lo;0;L;;;;;N;;;;;\nA41F;YI SYLLABLE JJIEP;Lo;0;L;;;;;N;;;;;\nA420;YI SYLLABLE JJUOX;Lo;0;L;;;;;N;;;;;\nA421;YI SYLLABLE JJUO;Lo;0;L;;;;;N;;;;;\nA422;YI SYLLABLE JJUOP;Lo;0;L;;;;;N;;;;;\nA423;YI SYLLABLE JJOT;Lo;0;L;;;;;N;;;;;\nA424;YI SYLLABLE JJOX;Lo;0;L;;;;;N;;;;;\nA425;YI SYLLABLE JJO;Lo;0;L;;;;;N;;;;;\nA426;YI SYLLABLE JJOP;Lo;0;L;;;;;N;;;;;\nA427;YI SYLLABLE JJUT;Lo;0;L;;;;;N;;;;;\nA428;YI SYLLABLE JJUX;Lo;0;L;;;;;N;;;;;\nA429;YI SYLLABLE JJU;Lo;0;L;;;;;N;;;;;\nA42A;YI SYLLABLE JJUP;Lo;0;L;;;;;N;;;;;\nA42B;YI SYLLABLE JJURX;Lo;0;L;;;;;N;;;;;\nA42C;YI SYLLABLE JJUR;Lo;0;L;;;;;N;;;;;\nA42D;YI SYLLABLE JJYT;Lo;0;L;;;;;N;;;;;\nA42E;YI SYLLABLE JJYX;Lo;0;L;;;;;N;;;;;\nA42F;YI SYLLABLE JJY;Lo;0;L;;;;;N;;;;;\nA430;YI SYLLABLE JJYP;Lo;0;L;;;;;N;;;;;\nA431;YI SYLLABLE NJIT;Lo;0;L;;;;;N;;;;;\nA432;YI SYLLABLE NJIX;Lo;0;L;;;;;N;;;;;\nA433;YI SYLLABLE NJI;Lo;0;L;;;;;N;;;;;\nA434;YI SYLLABLE NJIP;Lo;0;L;;;;;N;;;;;\nA435;YI SYLLABLE NJIET;Lo;0;L;;;;;N;;;;;\nA436;YI SYLLABLE NJIEX;Lo;0;L;;;;;N;;;;;\nA437;YI SYLLABLE NJIE;Lo;0;L;;;;;N;;;;;\nA438;YI SYLLABLE NJIEP;Lo;0;L;;;;;N;;;;;\nA439;YI SYLLABLE NJUOX;Lo;0;L;;;;;N;;;;;\nA43A;YI SYLLABLE NJUO;Lo;0;L;;;;;N;;;;;\nA43B;YI SYLLABLE NJOT;Lo;0;L;;;;;N;;;;;\nA43C;YI SYLLABLE NJOX;Lo;0;L;;;;;N;;;;;\nA43D;YI SYLLABLE NJO;Lo;0;L;;;;;N;;;;;\nA43E;YI SYLLABLE NJOP;Lo;0;L;;;;;N;;;;;\nA43F;YI SYLLABLE NJUX;Lo;0;L;;;;;N;;;;;\nA440;YI SYLLABLE NJU;Lo;0;L;;;;;N;;;;;\nA441;YI SYLLABLE NJUP;Lo;0;L;;;;;N;;;;;\nA442;YI SYLLABLE NJURX;Lo;0;L;;;;;N;;;;;\nA443;YI SYLLABLE NJUR;Lo;0;L;;;;;N;;;;;\nA444;YI SYLLABLE NJYT;Lo;0;L;;;;;N;;;;;\nA445;YI SYLLABLE NJYX;Lo;0;L;;;;;N;;;;;\nA446;YI SYLLABLE NJY;Lo;0;L;;;;;N;;;;;\nA447;YI SYLLABLE NJYP;Lo;0;L;;;;;N;;;;;\nA448;YI SYLLABLE NJYRX;Lo;0;L;;;;;N;;;;;\nA449;YI SYLLABLE NJYR;Lo;0;L;;;;;N;;;;;\nA44A;YI SYLLABLE NYIT;Lo;0;L;;;;;N;;;;;\nA44B;YI SYLLABLE NYIX;Lo;0;L;;;;;N;;;;;\nA44C;YI SYLLABLE NYI;Lo;0;L;;;;;N;;;;;\nA44D;YI SYLLABLE NYIP;Lo;0;L;;;;;N;;;;;\nA44E;YI SYLLABLE NYIET;Lo;0;L;;;;;N;;;;;\nA44F;YI SYLLABLE NYIEX;Lo;0;L;;;;;N;;;;;\nA450;YI SYLLABLE NYIE;Lo;0;L;;;;;N;;;;;\nA451;YI SYLLABLE NYIEP;Lo;0;L;;;;;N;;;;;\nA452;YI SYLLABLE NYUOX;Lo;0;L;;;;;N;;;;;\nA453;YI SYLLABLE NYUO;Lo;0;L;;;;;N;;;;;\nA454;YI SYLLABLE NYUOP;Lo;0;L;;;;;N;;;;;\nA455;YI SYLLABLE NYOT;Lo;0;L;;;;;N;;;;;\nA456;YI SYLLABLE NYOX;Lo;0;L;;;;;N;;;;;\nA457;YI SYLLABLE NYO;Lo;0;L;;;;;N;;;;;\nA458;YI SYLLABLE NYOP;Lo;0;L;;;;;N;;;;;\nA459;YI SYLLABLE NYUT;Lo;0;L;;;;;N;;;;;\nA45A;YI SYLLABLE NYUX;Lo;0;L;;;;;N;;;;;\nA45B;YI SYLLABLE NYU;Lo;0;L;;;;;N;;;;;\nA45C;YI SYLLABLE NYUP;Lo;0;L;;;;;N;;;;;\nA45D;YI SYLLABLE XIT;Lo;0;L;;;;;N;;;;;\nA45E;YI SYLLABLE XIX;Lo;0;L;;;;;N;;;;;\nA45F;YI SYLLABLE XI;Lo;0;L;;;;;N;;;;;\nA460;YI SYLLABLE XIP;Lo;0;L;;;;;N;;;;;\nA461;YI SYLLABLE XIET;Lo;0;L;;;;;N;;;;;\nA462;YI SYLLABLE XIEX;Lo;0;L;;;;;N;;;;;\nA463;YI SYLLABLE XIE;Lo;0;L;;;;;N;;;;;\nA464;YI SYLLABLE XIEP;Lo;0;L;;;;;N;;;;;\nA465;YI SYLLABLE XUOX;Lo;0;L;;;;;N;;;;;\nA466;YI SYLLABLE XUO;Lo;0;L;;;;;N;;;;;\nA467;YI SYLLABLE XOT;Lo;0;L;;;;;N;;;;;\nA468;YI SYLLABLE XOX;Lo;0;L;;;;;N;;;;;\nA469;YI SYLLABLE XO;Lo;0;L;;;;;N;;;;;\nA46A;YI SYLLABLE XOP;Lo;0;L;;;;;N;;;;;\nA46B;YI SYLLABLE XYT;Lo;0;L;;;;;N;;;;;\nA46C;YI SYLLABLE XYX;Lo;0;L;;;;;N;;;;;\nA46D;YI SYLLABLE XY;Lo;0;L;;;;;N;;;;;\nA46E;YI SYLLABLE XYP;Lo;0;L;;;;;N;;;;;\nA46F;YI SYLLABLE XYRX;Lo;0;L;;;;;N;;;;;\nA470;YI SYLLABLE XYR;Lo;0;L;;;;;N;;;;;\nA471;YI SYLLABLE YIT;Lo;0;L;;;;;N;;;;;\nA472;YI SYLLABLE YIX;Lo;0;L;;;;;N;;;;;\nA473;YI SYLLABLE YI;Lo;0;L;;;;;N;;;;;\nA474;YI SYLLABLE YIP;Lo;0;L;;;;;N;;;;;\nA475;YI SYLLABLE YIET;Lo;0;L;;;;;N;;;;;\nA476;YI SYLLABLE YIEX;Lo;0;L;;;;;N;;;;;\nA477;YI SYLLABLE YIE;Lo;0;L;;;;;N;;;;;\nA478;YI SYLLABLE YIEP;Lo;0;L;;;;;N;;;;;\nA479;YI SYLLABLE YUOT;Lo;0;L;;;;;N;;;;;\nA47A;YI SYLLABLE YUOX;Lo;0;L;;;;;N;;;;;\nA47B;YI SYLLABLE YUO;Lo;0;L;;;;;N;;;;;\nA47C;YI SYLLABLE YUOP;Lo;0;L;;;;;N;;;;;\nA47D;YI SYLLABLE YOT;Lo;0;L;;;;;N;;;;;\nA47E;YI SYLLABLE YOX;Lo;0;L;;;;;N;;;;;\nA47F;YI SYLLABLE YO;Lo;0;L;;;;;N;;;;;\nA480;YI SYLLABLE YOP;Lo;0;L;;;;;N;;;;;\nA481;YI SYLLABLE YUT;Lo;0;L;;;;;N;;;;;\nA482;YI SYLLABLE YUX;Lo;0;L;;;;;N;;;;;\nA483;YI SYLLABLE YU;Lo;0;L;;;;;N;;;;;\nA484;YI SYLLABLE YUP;Lo;0;L;;;;;N;;;;;\nA485;YI SYLLABLE YURX;Lo;0;L;;;;;N;;;;;\nA486;YI SYLLABLE YUR;Lo;0;L;;;;;N;;;;;\nA487;YI SYLLABLE YYT;Lo;0;L;;;;;N;;;;;\nA488;YI SYLLABLE YYX;Lo;0;L;;;;;N;;;;;\nA489;YI SYLLABLE YY;Lo;0;L;;;;;N;;;;;\nA48A;YI SYLLABLE YYP;Lo;0;L;;;;;N;;;;;\nA48B;YI SYLLABLE YYRX;Lo;0;L;;;;;N;;;;;\nA48C;YI SYLLABLE YYR;Lo;0;L;;;;;N;;;;;\nA490;YI RADICAL QOT;So;0;ON;;;;;N;;;;;\nA491;YI RADICAL LI;So;0;ON;;;;;N;;;;;\nA492;YI RADICAL KIT;So;0;ON;;;;;N;;;;;\nA493;YI RADICAL NYIP;So;0;ON;;;;;N;;;;;\nA494;YI RADICAL CYP;So;0;ON;;;;;N;;;;;\nA495;YI RADICAL SSI;So;0;ON;;;;;N;;;;;\nA496;YI RADICAL GGOP;So;0;ON;;;;;N;;;;;\nA497;YI RADICAL GEP;So;0;ON;;;;;N;;;;;\nA498;YI RADICAL MI;So;0;ON;;;;;N;;;;;\nA499;YI RADICAL HXIT;So;0;ON;;;;;N;;;;;\nA49A;YI RADICAL LYR;So;0;ON;;;;;N;;;;;\nA49B;YI RADICAL BBUT;So;0;ON;;;;;N;;;;;\nA49C;YI RADICAL MOP;So;0;ON;;;;;N;;;;;\nA49D;YI RADICAL YO;So;0;ON;;;;;N;;;;;\nA49E;YI RADICAL PUT;So;0;ON;;;;;N;;;;;\nA49F;YI RADICAL HXUO;So;0;ON;;;;;N;;;;;\nA4A0;YI RADICAL TAT;So;0;ON;;;;;N;;;;;\nA4A1;YI RADICAL GA;So;0;ON;;;;;N;;;;;\nA4A2;YI RADICAL ZUP;So;0;ON;;;;;N;;;;;\nA4A3;YI RADICAL CYT;So;0;ON;;;;;N;;;;;\nA4A4;YI RADICAL DDUR;So;0;ON;;;;;N;;;;;\nA4A5;YI RADICAL BUR;So;0;ON;;;;;N;;;;;\nA4A6;YI RADICAL GGUO;So;0;ON;;;;;N;;;;;\nA4A7;YI RADICAL NYOP;So;0;ON;;;;;N;;;;;\nA4A8;YI RADICAL TU;So;0;ON;;;;;N;;;;;\nA4A9;YI RADICAL OP;So;0;ON;;;;;N;;;;;\nA4AA;YI RADICAL JJUT;So;0;ON;;;;;N;;;;;\nA4AB;YI RADICAL ZOT;So;0;ON;;;;;N;;;;;\nA4AC;YI RADICAL PYT;So;0;ON;;;;;N;;;;;\nA4AD;YI RADICAL HMO;So;0;ON;;;;;N;;;;;\nA4AE;YI RADICAL YIT;So;0;ON;;;;;N;;;;;\nA4AF;YI RADICAL VUR;So;0;ON;;;;;N;;;;;\nA4B0;YI RADICAL SHY;So;0;ON;;;;;N;;;;;\nA4B1;YI RADICAL VEP;So;0;ON;;;;;N;;;;;\nA4B2;YI RADICAL ZA;So;0;ON;;;;;N;;;;;\nA4B3;YI RADICAL JO;So;0;ON;;;;;N;;;;;\nA4B4;YI RADICAL NZUP;So;0;ON;;;;;N;;;;;\nA4B5;YI RADICAL JJY;So;0;ON;;;;;N;;;;;\nA4B6;YI RADICAL GOT;So;0;ON;;;;;N;;;;;\nA4B7;YI RADICAL JJIE;So;0;ON;;;;;N;;;;;\nA4B8;YI RADICAL WO;So;0;ON;;;;;N;;;;;\nA4B9;YI RADICAL DU;So;0;ON;;;;;N;;;;;\nA4BA;YI RADICAL SHUR;So;0;ON;;;;;N;;;;;\nA4BB;YI RADICAL LIE;So;0;ON;;;;;N;;;;;\nA4BC;YI RADICAL CY;So;0;ON;;;;;N;;;;;\nA4BD;YI RADICAL CUOP;So;0;ON;;;;;N;;;;;\nA4BE;YI RADICAL CIP;So;0;ON;;;;;N;;;;;\nA4BF;YI RADICAL HXOP;So;0;ON;;;;;N;;;;;\nA4C0;YI RADICAL SHAT;So;0;ON;;;;;N;;;;;\nA4C1;YI RADICAL ZUR;So;0;ON;;;;;N;;;;;\nA4C2;YI RADICAL SHOP;So;0;ON;;;;;N;;;;;\nA4C3;YI RADICAL CHE;So;0;ON;;;;;N;;;;;\nA4C4;YI RADICAL ZZIET;So;0;ON;;;;;N;;;;;\nA4C5;YI RADICAL NBIE;So;0;ON;;;;;N;;;;;\nA4C6;YI RADICAL KE;So;0;ON;;;;;N;;;;;\nA4D0;LISU LETTER BA;Lo;0;L;;;;;N;;;;;\nA4D1;LISU LETTER PA;Lo;0;L;;;;;N;;;;;\nA4D2;LISU LETTER PHA;Lo;0;L;;;;;N;;;;;\nA4D3;LISU LETTER DA;Lo;0;L;;;;;N;;;;;\nA4D4;LISU LETTER TA;Lo;0;L;;;;;N;;;;;\nA4D5;LISU LETTER THA;Lo;0;L;;;;;N;;;;;\nA4D6;LISU LETTER GA;Lo;0;L;;;;;N;;;;;\nA4D7;LISU LETTER KA;Lo;0;L;;;;;N;;;;;\nA4D8;LISU LETTER KHA;Lo;0;L;;;;;N;;;;;\nA4D9;LISU LETTER JA;Lo;0;L;;;;;N;;;;;\nA4DA;LISU LETTER CA;Lo;0;L;;;;;N;;;;;\nA4DB;LISU LETTER CHA;Lo;0;L;;;;;N;;;;;\nA4DC;LISU LETTER DZA;Lo;0;L;;;;;N;;;;;\nA4DD;LISU LETTER TSA;Lo;0;L;;;;;N;;;;;\nA4DE;LISU LETTER TSHA;Lo;0;L;;;;;N;;;;;\nA4DF;LISU LETTER MA;Lo;0;L;;;;;N;;;;;\nA4E0;LISU LETTER NA;Lo;0;L;;;;;N;;;;;\nA4E1;LISU LETTER LA;Lo;0;L;;;;;N;;;;;\nA4E2;LISU LETTER SA;Lo;0;L;;;;;N;;;;;\nA4E3;LISU LETTER ZHA;Lo;0;L;;;;;N;;;;;\nA4E4;LISU LETTER ZA;Lo;0;L;;;;;N;;;;;\nA4E5;LISU LETTER NGA;Lo;0;L;;;;;N;;;;;\nA4E6;LISU LETTER HA;Lo;0;L;;;;;N;;;;;\nA4E7;LISU LETTER XA;Lo;0;L;;;;;N;;;;;\nA4E8;LISU LETTER HHA;Lo;0;L;;;;;N;;;;;\nA4E9;LISU LETTER FA;Lo;0;L;;;;;N;;;;;\nA4EA;LISU LETTER WA;Lo;0;L;;;;;N;;;;;\nA4EB;LISU LETTER SHA;Lo;0;L;;;;;N;;;;;\nA4EC;LISU LETTER YA;Lo;0;L;;;;;N;;;;;\nA4ED;LISU LETTER GHA;Lo;0;L;;;;;N;;;;;\nA4EE;LISU LETTER A;Lo;0;L;;;;;N;;;;;\nA4EF;LISU LETTER AE;Lo;0;L;;;;;N;;;;;\nA4F0;LISU LETTER E;Lo;0;L;;;;;N;;;;;\nA4F1;LISU LETTER EU;Lo;0;L;;;;;N;;;;;\nA4F2;LISU LETTER I;Lo;0;L;;;;;N;;;;;\nA4F3;LISU LETTER O;Lo;0;L;;;;;N;;;;;\nA4F4;LISU LETTER U;Lo;0;L;;;;;N;;;;;\nA4F5;LISU LETTER UE;Lo;0;L;;;;;N;;;;;\nA4F6;LISU LETTER UH;Lo;0;L;;;;;N;;;;;\nA4F7;LISU LETTER OE;Lo;0;L;;;;;N;;;;;\nA4F8;LISU LETTER TONE MYA TI;Lm;0;L;;;;;N;;;;;\nA4F9;LISU LETTER TONE NA PO;Lm;0;L;;;;;N;;;;;\nA4FA;LISU LETTER TONE MYA CYA;Lm;0;L;;;;;N;;;;;\nA4FB;LISU LETTER TONE MYA BO;Lm;0;L;;;;;N;;;;;\nA4FC;LISU LETTER TONE MYA NA;Lm;0;L;;;;;N;;;;;\nA4FD;LISU LETTER TONE MYA JEU;Lm;0;L;;;;;N;;;;;\nA4FE;LISU PUNCTUATION COMMA;Po;0;L;;;;;N;;;;;\nA4FF;LISU PUNCTUATION FULL STOP;Po;0;L;;;;;N;;;;;\nA500;VAI SYLLABLE EE;Lo;0;L;;;;;N;;;;;\nA501;VAI SYLLABLE EEN;Lo;0;L;;;;;N;;;;;\nA502;VAI SYLLABLE HEE;Lo;0;L;;;;;N;;;;;\nA503;VAI SYLLABLE WEE;Lo;0;L;;;;;N;;;;;\nA504;VAI SYLLABLE WEEN;Lo;0;L;;;;;N;;;;;\nA505;VAI SYLLABLE PEE;Lo;0;L;;;;;N;;;;;\nA506;VAI SYLLABLE BHEE;Lo;0;L;;;;;N;;;;;\nA507;VAI SYLLABLE BEE;Lo;0;L;;;;;N;;;;;\nA508;VAI SYLLABLE MBEE;Lo;0;L;;;;;N;;;;;\nA509;VAI SYLLABLE KPEE;Lo;0;L;;;;;N;;;;;\nA50A;VAI SYLLABLE MGBEE;Lo;0;L;;;;;N;;;;;\nA50B;VAI SYLLABLE GBEE;Lo;0;L;;;;;N;;;;;\nA50C;VAI SYLLABLE FEE;Lo;0;L;;;;;N;;;;;\nA50D;VAI SYLLABLE VEE;Lo;0;L;;;;;N;;;;;\nA50E;VAI SYLLABLE TEE;Lo;0;L;;;;;N;;;;;\nA50F;VAI SYLLABLE THEE;Lo;0;L;;;;;N;;;;;\nA510;VAI SYLLABLE DHEE;Lo;0;L;;;;;N;;;;;\nA511;VAI SYLLABLE DHHEE;Lo;0;L;;;;;N;;;;;\nA512;VAI SYLLABLE LEE;Lo;0;L;;;;;N;;;;;\nA513;VAI SYLLABLE REE;Lo;0;L;;;;;N;;;;;\nA514;VAI SYLLABLE DEE;Lo;0;L;;;;;N;;;;;\nA515;VAI SYLLABLE NDEE;Lo;0;L;;;;;N;;;;;\nA516;VAI SYLLABLE SEE;Lo;0;L;;;;;N;;;;;\nA517;VAI SYLLABLE SHEE;Lo;0;L;;;;;N;;;;;\nA518;VAI SYLLABLE ZEE;Lo;0;L;;;;;N;;;;;\nA519;VAI SYLLABLE ZHEE;Lo;0;L;;;;;N;;;;;\nA51A;VAI SYLLABLE CEE;Lo;0;L;;;;;N;;;;;\nA51B;VAI SYLLABLE JEE;Lo;0;L;;;;;N;;;;;\nA51C;VAI SYLLABLE NJEE;Lo;0;L;;;;;N;;;;;\nA51D;VAI SYLLABLE YEE;Lo;0;L;;;;;N;;;;;\nA51E;VAI SYLLABLE KEE;Lo;0;L;;;;;N;;;;;\nA51F;VAI SYLLABLE NGGEE;Lo;0;L;;;;;N;;;;;\nA520;VAI SYLLABLE GEE;Lo;0;L;;;;;N;;;;;\nA521;VAI SYLLABLE MEE;Lo;0;L;;;;;N;;;;;\nA522;VAI SYLLABLE NEE;Lo;0;L;;;;;N;;;;;\nA523;VAI SYLLABLE NYEE;Lo;0;L;;;;;N;;;;;\nA524;VAI SYLLABLE I;Lo;0;L;;;;;N;;;;;\nA525;VAI SYLLABLE IN;Lo;0;L;;;;;N;;;;;\nA526;VAI SYLLABLE HI;Lo;0;L;;;;;N;;;;;\nA527;VAI SYLLABLE HIN;Lo;0;L;;;;;N;;;;;\nA528;VAI SYLLABLE WI;Lo;0;L;;;;;N;;;;;\nA529;VAI SYLLABLE WIN;Lo;0;L;;;;;N;;;;;\nA52A;VAI SYLLABLE PI;Lo;0;L;;;;;N;;;;;\nA52B;VAI SYLLABLE BHI;Lo;0;L;;;;;N;;;;;\nA52C;VAI SYLLABLE BI;Lo;0;L;;;;;N;;;;;\nA52D;VAI SYLLABLE MBI;Lo;0;L;;;;;N;;;;;\nA52E;VAI SYLLABLE KPI;Lo;0;L;;;;;N;;;;;\nA52F;VAI SYLLABLE MGBI;Lo;0;L;;;;;N;;;;;\nA530;VAI SYLLABLE GBI;Lo;0;L;;;;;N;;;;;\nA531;VAI SYLLABLE FI;Lo;0;L;;;;;N;;;;;\nA532;VAI SYLLABLE VI;Lo;0;L;;;;;N;;;;;\nA533;VAI SYLLABLE TI;Lo;0;L;;;;;N;;;;;\nA534;VAI SYLLABLE THI;Lo;0;L;;;;;N;;;;;\nA535;VAI SYLLABLE DHI;Lo;0;L;;;;;N;;;;;\nA536;VAI SYLLABLE DHHI;Lo;0;L;;;;;N;;;;;\nA537;VAI SYLLABLE LI;Lo;0;L;;;;;N;;;;;\nA538;VAI SYLLABLE RI;Lo;0;L;;;;;N;;;;;\nA539;VAI SYLLABLE DI;Lo;0;L;;;;;N;;;;;\nA53A;VAI SYLLABLE NDI;Lo;0;L;;;;;N;;;;;\nA53B;VAI SYLLABLE SI;Lo;0;L;;;;;N;;;;;\nA53C;VAI SYLLABLE SHI;Lo;0;L;;;;;N;;;;;\nA53D;VAI SYLLABLE ZI;Lo;0;L;;;;;N;;;;;\nA53E;VAI SYLLABLE ZHI;Lo;0;L;;;;;N;;;;;\nA53F;VAI SYLLABLE CI;Lo;0;L;;;;;N;;;;;\nA540;VAI SYLLABLE JI;Lo;0;L;;;;;N;;;;;\nA541;VAI SYLLABLE NJI;Lo;0;L;;;;;N;;;;;\nA542;VAI SYLLABLE YI;Lo;0;L;;;;;N;;;;;\nA543;VAI SYLLABLE KI;Lo;0;L;;;;;N;;;;;\nA544;VAI SYLLABLE NGGI;Lo;0;L;;;;;N;;;;;\nA545;VAI SYLLABLE GI;Lo;0;L;;;;;N;;;;;\nA546;VAI SYLLABLE MI;Lo;0;L;;;;;N;;;;;\nA547;VAI SYLLABLE NI;Lo;0;L;;;;;N;;;;;\nA548;VAI SYLLABLE NYI;Lo;0;L;;;;;N;;;;;\nA549;VAI SYLLABLE A;Lo;0;L;;;;;N;;;;;\nA54A;VAI SYLLABLE AN;Lo;0;L;;;;;N;;;;;\nA54B;VAI SYLLABLE NGAN;Lo;0;L;;;;;N;;;;;\nA54C;VAI SYLLABLE HA;Lo;0;L;;;;;N;;;;;\nA54D;VAI SYLLABLE HAN;Lo;0;L;;;;;N;;;;;\nA54E;VAI SYLLABLE WA;Lo;0;L;;;;;N;;;;;\nA54F;VAI SYLLABLE WAN;Lo;0;L;;;;;N;;;;;\nA550;VAI SYLLABLE PA;Lo;0;L;;;;;N;;;;;\nA551;VAI SYLLABLE BHA;Lo;0;L;;;;;N;;;;;\nA552;VAI SYLLABLE BA;Lo;0;L;;;;;N;;;;;\nA553;VAI SYLLABLE MBA;Lo;0;L;;;;;N;;;;;\nA554;VAI SYLLABLE KPA;Lo;0;L;;;;;N;;;;;\nA555;VAI SYLLABLE KPAN;Lo;0;L;;;;;N;;;;;\nA556;VAI SYLLABLE MGBA;Lo;0;L;;;;;N;;;;;\nA557;VAI SYLLABLE GBA;Lo;0;L;;;;;N;;;;;\nA558;VAI SYLLABLE FA;Lo;0;L;;;;;N;;;;;\nA559;VAI SYLLABLE VA;Lo;0;L;;;;;N;;;;;\nA55A;VAI SYLLABLE TA;Lo;0;L;;;;;N;;;;;\nA55B;VAI SYLLABLE THA;Lo;0;L;;;;;N;;;;;\nA55C;VAI SYLLABLE DHA;Lo;0;L;;;;;N;;;;;\nA55D;VAI SYLLABLE DHHA;Lo;0;L;;;;;N;;;;;\nA55E;VAI SYLLABLE LA;Lo;0;L;;;;;N;;;;;\nA55F;VAI SYLLABLE RA;Lo;0;L;;;;;N;;;;;\nA560;VAI SYLLABLE DA;Lo;0;L;;;;;N;;;;;\nA561;VAI SYLLABLE NDA;Lo;0;L;;;;;N;;;;;\nA562;VAI SYLLABLE SA;Lo;0;L;;;;;N;;;;;\nA563;VAI SYLLABLE SHA;Lo;0;L;;;;;N;;;;;\nA564;VAI SYLLABLE ZA;Lo;0;L;;;;;N;;;;;\nA565;VAI SYLLABLE ZHA;Lo;0;L;;;;;N;;;;;\nA566;VAI SYLLABLE CA;Lo;0;L;;;;;N;;;;;\nA567;VAI SYLLABLE JA;Lo;0;L;;;;;N;;;;;\nA568;VAI SYLLABLE NJA;Lo;0;L;;;;;N;;;;;\nA569;VAI SYLLABLE YA;Lo;0;L;;;;;N;;;;;\nA56A;VAI SYLLABLE KA;Lo;0;L;;;;;N;;;;;\nA56B;VAI SYLLABLE KAN;Lo;0;L;;;;;N;;;;;\nA56C;VAI SYLLABLE NGGA;Lo;0;L;;;;;N;;;;;\nA56D;VAI SYLLABLE GA;Lo;0;L;;;;;N;;;;;\nA56E;VAI SYLLABLE MA;Lo;0;L;;;;;N;;;;;\nA56F;VAI SYLLABLE NA;Lo;0;L;;;;;N;;;;;\nA570;VAI SYLLABLE NYA;Lo;0;L;;;;;N;;;;;\nA571;VAI SYLLABLE OO;Lo;0;L;;;;;N;;;;;\nA572;VAI SYLLABLE OON;Lo;0;L;;;;;N;;;;;\nA573;VAI SYLLABLE HOO;Lo;0;L;;;;;N;;;;;\nA574;VAI SYLLABLE WOO;Lo;0;L;;;;;N;;;;;\nA575;VAI SYLLABLE WOON;Lo;0;L;;;;;N;;;;;\nA576;VAI SYLLABLE POO;Lo;0;L;;;;;N;;;;;\nA577;VAI SYLLABLE BHOO;Lo;0;L;;;;;N;;;;;\nA578;VAI SYLLABLE BOO;Lo;0;L;;;;;N;;;;;\nA579;VAI SYLLABLE MBOO;Lo;0;L;;;;;N;;;;;\nA57A;VAI SYLLABLE KPOO;Lo;0;L;;;;;N;;;;;\nA57B;VAI SYLLABLE MGBOO;Lo;0;L;;;;;N;;;;;\nA57C;VAI SYLLABLE GBOO;Lo;0;L;;;;;N;;;;;\nA57D;VAI SYLLABLE FOO;Lo;0;L;;;;;N;;;;;\nA57E;VAI SYLLABLE VOO;Lo;0;L;;;;;N;;;;;\nA57F;VAI SYLLABLE TOO;Lo;0;L;;;;;N;;;;;\nA580;VAI SYLLABLE THOO;Lo;0;L;;;;;N;;;;;\nA581;VAI SYLLABLE DHOO;Lo;0;L;;;;;N;;;;;\nA582;VAI SYLLABLE DHHOO;Lo;0;L;;;;;N;;;;;\nA583;VAI SYLLABLE LOO;Lo;0;L;;;;;N;;;;;\nA584;VAI SYLLABLE ROO;Lo;0;L;;;;;N;;;;;\nA585;VAI SYLLABLE DOO;Lo;0;L;;;;;N;;;;;\nA586;VAI SYLLABLE NDOO;Lo;0;L;;;;;N;;;;;\nA587;VAI SYLLABLE SOO;Lo;0;L;;;;;N;;;;;\nA588;VAI SYLLABLE SHOO;Lo;0;L;;;;;N;;;;;\nA589;VAI SYLLABLE ZOO;Lo;0;L;;;;;N;;;;;\nA58A;VAI SYLLABLE ZHOO;Lo;0;L;;;;;N;;;;;\nA58B;VAI SYLLABLE COO;Lo;0;L;;;;;N;;;;;\nA58C;VAI SYLLABLE JOO;Lo;0;L;;;;;N;;;;;\nA58D;VAI SYLLABLE NJOO;Lo;0;L;;;;;N;;;;;\nA58E;VAI SYLLABLE YOO;Lo;0;L;;;;;N;;;;;\nA58F;VAI SYLLABLE KOO;Lo;0;L;;;;;N;;;;;\nA590;VAI SYLLABLE NGGOO;Lo;0;L;;;;;N;;;;;\nA591;VAI SYLLABLE GOO;Lo;0;L;;;;;N;;;;;\nA592;VAI SYLLABLE MOO;Lo;0;L;;;;;N;;;;;\nA593;VAI SYLLABLE NOO;Lo;0;L;;;;;N;;;;;\nA594;VAI SYLLABLE NYOO;Lo;0;L;;;;;N;;;;;\nA595;VAI SYLLABLE U;Lo;0;L;;;;;N;;;;;\nA596;VAI SYLLABLE UN;Lo;0;L;;;;;N;;;;;\nA597;VAI SYLLABLE HU;Lo;0;L;;;;;N;;;;;\nA598;VAI SYLLABLE HUN;Lo;0;L;;;;;N;;;;;\nA599;VAI SYLLABLE WU;Lo;0;L;;;;;N;;;;;\nA59A;VAI SYLLABLE WUN;Lo;0;L;;;;;N;;;;;\nA59B;VAI SYLLABLE PU;Lo;0;L;;;;;N;;;;;\nA59C;VAI SYLLABLE BHU;Lo;0;L;;;;;N;;;;;\nA59D;VAI SYLLABLE BU;Lo;0;L;;;;;N;;;;;\nA59E;VAI SYLLABLE MBU;Lo;0;L;;;;;N;;;;;\nA59F;VAI SYLLABLE KPU;Lo;0;L;;;;;N;;;;;\nA5A0;VAI SYLLABLE MGBU;Lo;0;L;;;;;N;;;;;\nA5A1;VAI SYLLABLE GBU;Lo;0;L;;;;;N;;;;;\nA5A2;VAI SYLLABLE FU;Lo;0;L;;;;;N;;;;;\nA5A3;VAI SYLLABLE VU;Lo;0;L;;;;;N;;;;;\nA5A4;VAI SYLLABLE TU;Lo;0;L;;;;;N;;;;;\nA5A5;VAI SYLLABLE THU;Lo;0;L;;;;;N;;;;;\nA5A6;VAI SYLLABLE DHU;Lo;0;L;;;;;N;;;;;\nA5A7;VAI SYLLABLE DHHU;Lo;0;L;;;;;N;;;;;\nA5A8;VAI SYLLABLE LU;Lo;0;L;;;;;N;;;;;\nA5A9;VAI SYLLABLE RU;Lo;0;L;;;;;N;;;;;\nA5AA;VAI SYLLABLE DU;Lo;0;L;;;;;N;;;;;\nA5AB;VAI SYLLABLE NDU;Lo;0;L;;;;;N;;;;;\nA5AC;VAI SYLLABLE SU;Lo;0;L;;;;;N;;;;;\nA5AD;VAI SYLLABLE SHU;Lo;0;L;;;;;N;;;;;\nA5AE;VAI SYLLABLE ZU;Lo;0;L;;;;;N;;;;;\nA5AF;VAI SYLLABLE ZHU;Lo;0;L;;;;;N;;;;;\nA5B0;VAI SYLLABLE CU;Lo;0;L;;;;;N;;;;;\nA5B1;VAI SYLLABLE JU;Lo;0;L;;;;;N;;;;;\nA5B2;VAI SYLLABLE NJU;Lo;0;L;;;;;N;;;;;\nA5B3;VAI SYLLABLE YU;Lo;0;L;;;;;N;;;;;\nA5B4;VAI SYLLABLE KU;Lo;0;L;;;;;N;;;;;\nA5B5;VAI SYLLABLE NGGU;Lo;0;L;;;;;N;;;;;\nA5B6;VAI SYLLABLE GU;Lo;0;L;;;;;N;;;;;\nA5B7;VAI SYLLABLE MU;Lo;0;L;;;;;N;;;;;\nA5B8;VAI SYLLABLE NU;Lo;0;L;;;;;N;;;;;\nA5B9;VAI SYLLABLE NYU;Lo;0;L;;;;;N;;;;;\nA5BA;VAI SYLLABLE O;Lo;0;L;;;;;N;;;;;\nA5BB;VAI SYLLABLE ON;Lo;0;L;;;;;N;;;;;\nA5BC;VAI SYLLABLE NGON;Lo;0;L;;;;;N;;;;;\nA5BD;VAI SYLLABLE HO;Lo;0;L;;;;;N;;;;;\nA5BE;VAI SYLLABLE HON;Lo;0;L;;;;;N;;;;;\nA5BF;VAI SYLLABLE WO;Lo;0;L;;;;;N;;;;;\nA5C0;VAI SYLLABLE WON;Lo;0;L;;;;;N;;;;;\nA5C1;VAI SYLLABLE PO;Lo;0;L;;;;;N;;;;;\nA5C2;VAI SYLLABLE BHO;Lo;0;L;;;;;N;;;;;\nA5C3;VAI SYLLABLE BO;Lo;0;L;;;;;N;;;;;\nA5C4;VAI SYLLABLE MBO;Lo;0;L;;;;;N;;;;;\nA5C5;VAI SYLLABLE KPO;Lo;0;L;;;;;N;;;;;\nA5C6;VAI SYLLABLE MGBO;Lo;0;L;;;;;N;;;;;\nA5C7;VAI SYLLABLE GBO;Lo;0;L;;;;;N;;;;;\nA5C8;VAI SYLLABLE GBON;Lo;0;L;;;;;N;;;;;\nA5C9;VAI SYLLABLE FO;Lo;0;L;;;;;N;;;;;\nA5CA;VAI SYLLABLE VO;Lo;0;L;;;;;N;;;;;\nA5CB;VAI SYLLABLE TO;Lo;0;L;;;;;N;;;;;\nA5CC;VAI SYLLABLE THO;Lo;0;L;;;;;N;;;;;\nA5CD;VAI SYLLABLE DHO;Lo;0;L;;;;;N;;;;;\nA5CE;VAI SYLLABLE DHHO;Lo;0;L;;;;;N;;;;;\nA5CF;VAI SYLLABLE LO;Lo;0;L;;;;;N;;;;;\nA5D0;VAI SYLLABLE RO;Lo;0;L;;;;;N;;;;;\nA5D1;VAI SYLLABLE DO;Lo;0;L;;;;;N;;;;;\nA5D2;VAI SYLLABLE NDO;Lo;0;L;;;;;N;;;;;\nA5D3;VAI SYLLABLE SO;Lo;0;L;;;;;N;;;;;\nA5D4;VAI SYLLABLE SHO;Lo;0;L;;;;;N;;;;;\nA5D5;VAI SYLLABLE ZO;Lo;0;L;;;;;N;;;;;\nA5D6;VAI SYLLABLE ZHO;Lo;0;L;;;;;N;;;;;\nA5D7;VAI SYLLABLE CO;Lo;0;L;;;;;N;;;;;\nA5D8;VAI SYLLABLE JO;Lo;0;L;;;;;N;;;;;\nA5D9;VAI SYLLABLE NJO;Lo;0;L;;;;;N;;;;;\nA5DA;VAI SYLLABLE YO;Lo;0;L;;;;;N;;;;;\nA5DB;VAI SYLLABLE KO;Lo;0;L;;;;;N;;;;;\nA5DC;VAI SYLLABLE NGGO;Lo;0;L;;;;;N;;;;;\nA5DD;VAI SYLLABLE GO;Lo;0;L;;;;;N;;;;;\nA5DE;VAI SYLLABLE MO;Lo;0;L;;;;;N;;;;;\nA5DF;VAI SYLLABLE NO;Lo;0;L;;;;;N;;;;;\nA5E0;VAI SYLLABLE NYO;Lo;0;L;;;;;N;;;;;\nA5E1;VAI SYLLABLE E;Lo;0;L;;;;;N;;;;;\nA5E2;VAI SYLLABLE EN;Lo;0;L;;;;;N;;;;;\nA5E3;VAI SYLLABLE NGEN;Lo;0;L;;;;;N;;;;;\nA5E4;VAI SYLLABLE HE;Lo;0;L;;;;;N;;;;;\nA5E5;VAI SYLLABLE HEN;Lo;0;L;;;;;N;;;;;\nA5E6;VAI SYLLABLE WE;Lo;0;L;;;;;N;;;;;\nA5E7;VAI SYLLABLE WEN;Lo;0;L;;;;;N;;;;;\nA5E8;VAI SYLLABLE PE;Lo;0;L;;;;;N;;;;;\nA5E9;VAI SYLLABLE BHE;Lo;0;L;;;;;N;;;;;\nA5EA;VAI SYLLABLE BE;Lo;0;L;;;;;N;;;;;\nA5EB;VAI SYLLABLE MBE;Lo;0;L;;;;;N;;;;;\nA5EC;VAI SYLLABLE KPE;Lo;0;L;;;;;N;;;;;\nA5ED;VAI SYLLABLE KPEN;Lo;0;L;;;;;N;;;;;\nA5EE;VAI SYLLABLE MGBE;Lo;0;L;;;;;N;;;;;\nA5EF;VAI SYLLABLE GBE;Lo;0;L;;;;;N;;;;;\nA5F0;VAI SYLLABLE GBEN;Lo;0;L;;;;;N;;;;;\nA5F1;VAI SYLLABLE FE;Lo;0;L;;;;;N;;;;;\nA5F2;VAI SYLLABLE VE;Lo;0;L;;;;;N;;;;;\nA5F3;VAI SYLLABLE TE;Lo;0;L;;;;;N;;;;;\nA5F4;VAI SYLLABLE THE;Lo;0;L;;;;;N;;;;;\nA5F5;VAI SYLLABLE DHE;Lo;0;L;;;;;N;;;;;\nA5F6;VAI SYLLABLE DHHE;Lo;0;L;;;;;N;;;;;\nA5F7;VAI SYLLABLE LE;Lo;0;L;;;;;N;;;;;\nA5F8;VAI SYLLABLE RE;Lo;0;L;;;;;N;;;;;\nA5F9;VAI SYLLABLE DE;Lo;0;L;;;;;N;;;;;\nA5FA;VAI SYLLABLE NDE;Lo;0;L;;;;;N;;;;;\nA5FB;VAI SYLLABLE SE;Lo;0;L;;;;;N;;;;;\nA5FC;VAI SYLLABLE SHE;Lo;0;L;;;;;N;;;;;\nA5FD;VAI SYLLABLE ZE;Lo;0;L;;;;;N;;;;;\nA5FE;VAI SYLLABLE ZHE;Lo;0;L;;;;;N;;;;;\nA5FF;VAI SYLLABLE CE;Lo;0;L;;;;;N;;;;;\nA600;VAI SYLLABLE JE;Lo;0;L;;;;;N;;;;;\nA601;VAI SYLLABLE NJE;Lo;0;L;;;;;N;;;;;\nA602;VAI SYLLABLE YE;Lo;0;L;;;;;N;;;;;\nA603;VAI SYLLABLE KE;Lo;0;L;;;;;N;;;;;\nA604;VAI SYLLABLE NGGE;Lo;0;L;;;;;N;;;;;\nA605;VAI SYLLABLE NGGEN;Lo;0;L;;;;;N;;;;;\nA606;VAI SYLLABLE GE;Lo;0;L;;;;;N;;;;;\nA607;VAI SYLLABLE GEN;Lo;0;L;;;;;N;;;;;\nA608;VAI SYLLABLE ME;Lo;0;L;;;;;N;;;;;\nA609;VAI SYLLABLE NE;Lo;0;L;;;;;N;;;;;\nA60A;VAI SYLLABLE NYE;Lo;0;L;;;;;N;;;;;\nA60B;VAI SYLLABLE NG;Lo;0;L;;;;;N;;;;;\nA60C;VAI SYLLABLE LENGTHENER;Lm;0;L;;;;;N;;;;;\nA60D;VAI COMMA;Po;0;ON;;;;;N;;;;;\nA60E;VAI FULL STOP;Po;0;ON;;;;;N;;;;;\nA60F;VAI QUESTION MARK;Po;0;ON;;;;;N;;;;;\nA610;VAI SYLLABLE NDOLE FA;Lo;0;L;;;;;N;;;;;\nA611;VAI SYLLABLE NDOLE KA;Lo;0;L;;;;;N;;;;;\nA612;VAI SYLLABLE NDOLE SOO;Lo;0;L;;;;;N;;;;;\nA613;VAI SYMBOL FEENG;Lo;0;L;;;;;N;;;;;\nA614;VAI SYMBOL KEENG;Lo;0;L;;;;;N;;;;;\nA615;VAI SYMBOL TING;Lo;0;L;;;;;N;;;;;\nA616;VAI SYMBOL NII;Lo;0;L;;;;;N;;;;;\nA617;VAI SYMBOL BANG;Lo;0;L;;;;;N;;;;;\nA618;VAI SYMBOL FAA;Lo;0;L;;;;;N;;;;;\nA619;VAI SYMBOL TAA;Lo;0;L;;;;;N;;;;;\nA61A;VAI SYMBOL DANG;Lo;0;L;;;;;N;;;;;\nA61B;VAI SYMBOL DOONG;Lo;0;L;;;;;N;;;;;\nA61C;VAI SYMBOL KUNG;Lo;0;L;;;;;N;;;;;\nA61D;VAI SYMBOL TONG;Lo;0;L;;;;;N;;;;;\nA61E;VAI SYMBOL DO-O;Lo;0;L;;;;;N;;;;;\nA61F;VAI SYMBOL JONG;Lo;0;L;;;;;N;;;;;\nA620;VAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\nA621;VAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\nA622;VAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\nA623;VAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\nA624;VAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\nA625;VAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\nA626;VAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\nA627;VAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\nA628;VAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\nA629;VAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\nA62A;VAI SYLLABLE NDOLE MA;Lo;0;L;;;;;N;;;;;\nA62B;VAI SYLLABLE NDOLE DO;Lo;0;L;;;;;N;;;;;\nA640;CYRILLIC CAPITAL LETTER ZEMLYA;Lu;0;L;;;;;N;;;;A641;\nA641;CYRILLIC SMALL LETTER ZEMLYA;Ll;0;L;;;;;N;;;A640;;A640\nA642;CYRILLIC CAPITAL LETTER DZELO;Lu;0;L;;;;;N;;;;A643;\nA643;CYRILLIC SMALL LETTER DZELO;Ll;0;L;;;;;N;;;A642;;A642\nA644;CYRILLIC CAPITAL LETTER REVERSED DZE;Lu;0;L;;;;;N;;;;A645;\nA645;CYRILLIC SMALL LETTER REVERSED DZE;Ll;0;L;;;;;N;;;A644;;A644\nA646;CYRILLIC CAPITAL LETTER IOTA;Lu;0;L;;;;;N;;;;A647;\nA647;CYRILLIC SMALL LETTER IOTA;Ll;0;L;;;;;N;;;A646;;A646\nA648;CYRILLIC CAPITAL LETTER DJERV;Lu;0;L;;;;;N;;;;A649;\nA649;CYRILLIC SMALL LETTER DJERV;Ll;0;L;;;;;N;;;A648;;A648\nA64A;CYRILLIC CAPITAL LETTER MONOGRAPH UK;Lu;0;L;;;;;N;;;;A64B;\nA64B;CYRILLIC SMALL LETTER MONOGRAPH UK;Ll;0;L;;;;;N;;;A64A;;A64A\nA64C;CYRILLIC CAPITAL LETTER BROAD OMEGA;Lu;0;L;;;;;N;;;;A64D;\nA64D;CYRILLIC SMALL LETTER BROAD OMEGA;Ll;0;L;;;;;N;;;A64C;;A64C\nA64E;CYRILLIC CAPITAL LETTER NEUTRAL YER;Lu;0;L;;;;;N;;;;A64F;\nA64F;CYRILLIC SMALL LETTER NEUTRAL YER;Ll;0;L;;;;;N;;;A64E;;A64E\nA650;CYRILLIC CAPITAL LETTER YERU WITH BACK YER;Lu;0;L;;;;;N;;;;A651;\nA651;CYRILLIC SMALL LETTER YERU WITH BACK YER;Ll;0;L;;;;;N;;;A650;;A650\nA652;CYRILLIC CAPITAL LETTER IOTIFIED YAT;Lu;0;L;;;;;N;;;;A653;\nA653;CYRILLIC SMALL LETTER IOTIFIED YAT;Ll;0;L;;;;;N;;;A652;;A652\nA654;CYRILLIC CAPITAL LETTER REVERSED YU;Lu;0;L;;;;;N;;;;A655;\nA655;CYRILLIC SMALL LETTER REVERSED YU;Ll;0;L;;;;;N;;;A654;;A654\nA656;CYRILLIC CAPITAL LETTER IOTIFIED A;Lu;0;L;;;;;N;;;;A657;\nA657;CYRILLIC SMALL LETTER IOTIFIED A;Ll;0;L;;;;;N;;;A656;;A656\nA658;CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS;Lu;0;L;;;;;N;;;;A659;\nA659;CYRILLIC SMALL LETTER CLOSED LITTLE YUS;Ll;0;L;;;;;N;;;A658;;A658\nA65A;CYRILLIC CAPITAL LETTER BLENDED YUS;Lu;0;L;;;;;N;;;;A65B;\nA65B;CYRILLIC SMALL LETTER BLENDED YUS;Ll;0;L;;;;;N;;;A65A;;A65A\nA65C;CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS;Lu;0;L;;;;;N;;;;A65D;\nA65D;CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS;Ll;0;L;;;;;N;;;A65C;;A65C\nA65E;CYRILLIC CAPITAL LETTER YN;Lu;0;L;;;;;N;;;;A65F;\nA65F;CYRILLIC SMALL LETTER YN;Ll;0;L;;;;;N;;;A65E;;A65E\nA660;CYRILLIC CAPITAL LETTER REVERSED TSE;Lu;0;L;;;;;N;;;;A661;\nA661;CYRILLIC SMALL LETTER REVERSED TSE;Ll;0;L;;;;;N;;;A660;;A660\nA662;CYRILLIC CAPITAL LETTER SOFT DE;Lu;0;L;;;;;N;;;;A663;\nA663;CYRILLIC SMALL LETTER SOFT DE;Ll;0;L;;;;;N;;;A662;;A662\nA664;CYRILLIC CAPITAL LETTER SOFT EL;Lu;0;L;;;;;N;;;;A665;\nA665;CYRILLIC SMALL LETTER SOFT EL;Ll;0;L;;;;;N;;;A664;;A664\nA666;CYRILLIC CAPITAL LETTER SOFT EM;Lu;0;L;;;;;N;;;;A667;\nA667;CYRILLIC SMALL LETTER SOFT EM;Ll;0;L;;;;;N;;;A666;;A666\nA668;CYRILLIC CAPITAL LETTER MONOCULAR O;Lu;0;L;;;;;N;;;;A669;\nA669;CYRILLIC SMALL LETTER MONOCULAR O;Ll;0;L;;;;;N;;;A668;;A668\nA66A;CYRILLIC CAPITAL LETTER BINOCULAR O;Lu;0;L;;;;;N;;;;A66B;\nA66B;CYRILLIC SMALL LETTER BINOCULAR O;Ll;0;L;;;;;N;;;A66A;;A66A\nA66C;CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O;Lu;0;L;;;;;N;;;;A66D;\nA66D;CYRILLIC SMALL LETTER DOUBLE MONOCULAR O;Ll;0;L;;;;;N;;;A66C;;A66C\nA66E;CYRILLIC LETTER MULTIOCULAR O;Lo;0;L;;;;;N;;;;;\nA66F;COMBINING CYRILLIC VZMET;Mn;230;NSM;;;;;N;;;;;\nA670;COMBINING CYRILLIC TEN MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;\nA671;COMBINING CYRILLIC HUNDRED MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;\nA672;COMBINING CYRILLIC THOUSAND MILLIONS SIGN;Me;0;NSM;;;;;N;;;;;\nA673;SLAVONIC ASTERISK;Po;0;ON;;;;;N;;;;;\nA674;COMBINING CYRILLIC LETTER UKRAINIAN IE;Mn;230;NSM;;;;;N;;;;;\nA675;COMBINING CYRILLIC LETTER I;Mn;230;NSM;;;;;N;;;;;\nA676;COMBINING CYRILLIC LETTER YI;Mn;230;NSM;;;;;N;;;;;\nA677;COMBINING CYRILLIC LETTER U;Mn;230;NSM;;;;;N;;;;;\nA678;COMBINING CYRILLIC LETTER HARD SIGN;Mn;230;NSM;;;;;N;;;;;\nA679;COMBINING CYRILLIC LETTER YERU;Mn;230;NSM;;;;;N;;;;;\nA67A;COMBINING CYRILLIC LETTER SOFT SIGN;Mn;230;NSM;;;;;N;;;;;\nA67B;COMBINING CYRILLIC LETTER OMEGA;Mn;230;NSM;;;;;N;;;;;\nA67C;COMBINING CYRILLIC KAVYKA;Mn;230;NSM;;;;;N;;;;;\nA67D;COMBINING CYRILLIC PAYEROK;Mn;230;NSM;;;;;N;;;;;\nA67E;CYRILLIC KAVYKA;Po;0;ON;;;;;N;;;;;\nA67F;CYRILLIC PAYEROK;Lm;0;ON;;;;;N;;;;;\nA680;CYRILLIC CAPITAL LETTER DWE;Lu;0;L;;;;;N;;;;A681;\nA681;CYRILLIC SMALL LETTER DWE;Ll;0;L;;;;;N;;;A680;;A680\nA682;CYRILLIC CAPITAL LETTER DZWE;Lu;0;L;;;;;N;;;;A683;\nA683;CYRILLIC SMALL LETTER DZWE;Ll;0;L;;;;;N;;;A682;;A682\nA684;CYRILLIC CAPITAL LETTER ZHWE;Lu;0;L;;;;;N;;;;A685;\nA685;CYRILLIC SMALL LETTER ZHWE;Ll;0;L;;;;;N;;;A684;;A684\nA686;CYRILLIC CAPITAL LETTER CCHE;Lu;0;L;;;;;N;;;;A687;\nA687;CYRILLIC SMALL LETTER CCHE;Ll;0;L;;;;;N;;;A686;;A686\nA688;CYRILLIC CAPITAL LETTER DZZE;Lu;0;L;;;;;N;;;;A689;\nA689;CYRILLIC SMALL LETTER DZZE;Ll;0;L;;;;;N;;;A688;;A688\nA68A;CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK;Lu;0;L;;;;;N;;;;A68B;\nA68B;CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK;Ll;0;L;;;;;N;;;A68A;;A68A\nA68C;CYRILLIC CAPITAL LETTER TWE;Lu;0;L;;;;;N;;;;A68D;\nA68D;CYRILLIC SMALL LETTER TWE;Ll;0;L;;;;;N;;;A68C;;A68C\nA68E;CYRILLIC CAPITAL LETTER TSWE;Lu;0;L;;;;;N;;;;A68F;\nA68F;CYRILLIC SMALL LETTER TSWE;Ll;0;L;;;;;N;;;A68E;;A68E\nA690;CYRILLIC CAPITAL LETTER TSSE;Lu;0;L;;;;;N;;;;A691;\nA691;CYRILLIC SMALL LETTER TSSE;Ll;0;L;;;;;N;;;A690;;A690\nA692;CYRILLIC CAPITAL LETTER TCHE;Lu;0;L;;;;;N;;;;A693;\nA693;CYRILLIC SMALL LETTER TCHE;Ll;0;L;;;;;N;;;A692;;A692\nA694;CYRILLIC CAPITAL LETTER HWE;Lu;0;L;;;;;N;;;;A695;\nA695;CYRILLIC SMALL LETTER HWE;Ll;0;L;;;;;N;;;A694;;A694\nA696;CYRILLIC CAPITAL LETTER SHWE;Lu;0;L;;;;;N;;;;A697;\nA697;CYRILLIC SMALL LETTER SHWE;Ll;0;L;;;;;N;;;A696;;A696\nA698;CYRILLIC CAPITAL LETTER DOUBLE O;Lu;0;L;;;;;N;;;;A699;\nA699;CYRILLIC SMALL LETTER DOUBLE O;Ll;0;L;;;;;N;;;A698;;A698\nA69A;CYRILLIC CAPITAL LETTER CROSSED O;Lu;0;L;;;;;N;;;;A69B;\nA69B;CYRILLIC SMALL LETTER CROSSED O;Ll;0;L;;;;;N;;;A69A;;A69A\nA69C;MODIFIER LETTER CYRILLIC HARD SIGN;Lm;0;L;<super> 044A;;;;N;;;;;\nA69D;MODIFIER LETTER CYRILLIC SOFT SIGN;Lm;0;L;<super> 044C;;;;N;;;;;\nA69E;COMBINING CYRILLIC LETTER EF;Mn;230;NSM;;;;;N;;;;;\nA69F;COMBINING CYRILLIC LETTER IOTIFIED E;Mn;230;NSM;;;;;N;;;;;\nA6A0;BAMUM LETTER A;Lo;0;L;;;;;N;;;;;\nA6A1;BAMUM LETTER KA;Lo;0;L;;;;;N;;;;;\nA6A2;BAMUM LETTER U;Lo;0;L;;;;;N;;;;;\nA6A3;BAMUM LETTER KU;Lo;0;L;;;;;N;;;;;\nA6A4;BAMUM LETTER EE;Lo;0;L;;;;;N;;;;;\nA6A5;BAMUM LETTER REE;Lo;0;L;;;;;N;;;;;\nA6A6;BAMUM LETTER TAE;Lo;0;L;;;;;N;;;;;\nA6A7;BAMUM LETTER O;Lo;0;L;;;;;N;;;;;\nA6A8;BAMUM LETTER NYI;Lo;0;L;;;;;N;;;;;\nA6A9;BAMUM LETTER I;Lo;0;L;;;;;N;;;;;\nA6AA;BAMUM LETTER LA;Lo;0;L;;;;;N;;;;;\nA6AB;BAMUM LETTER PA;Lo;0;L;;;;;N;;;;;\nA6AC;BAMUM LETTER RII;Lo;0;L;;;;;N;;;;;\nA6AD;BAMUM LETTER RIEE;Lo;0;L;;;;;N;;;;;\nA6AE;BAMUM LETTER LEEEE;Lo;0;L;;;;;N;;;;;\nA6AF;BAMUM LETTER MEEEE;Lo;0;L;;;;;N;;;;;\nA6B0;BAMUM LETTER TAA;Lo;0;L;;;;;N;;;;;\nA6B1;BAMUM LETTER NDAA;Lo;0;L;;;;;N;;;;;\nA6B2;BAMUM LETTER NJAEM;Lo;0;L;;;;;N;;;;;\nA6B3;BAMUM LETTER M;Lo;0;L;;;;;N;;;;;\nA6B4;BAMUM LETTER SUU;Lo;0;L;;;;;N;;;;;\nA6B5;BAMUM LETTER MU;Lo;0;L;;;;;N;;;;;\nA6B6;BAMUM LETTER SHII;Lo;0;L;;;;;N;;;;;\nA6B7;BAMUM LETTER SI;Lo;0;L;;;;;N;;;;;\nA6B8;BAMUM LETTER SHEUX;Lo;0;L;;;;;N;;;;;\nA6B9;BAMUM LETTER SEUX;Lo;0;L;;;;;N;;;;;\nA6BA;BAMUM LETTER KYEE;Lo;0;L;;;;;N;;;;;\nA6BB;BAMUM LETTER KET;Lo;0;L;;;;;N;;;;;\nA6BC;BAMUM LETTER NUAE;Lo;0;L;;;;;N;;;;;\nA6BD;BAMUM LETTER NU;Lo;0;L;;;;;N;;;;;\nA6BE;BAMUM LETTER NJUAE;Lo;0;L;;;;;N;;;;;\nA6BF;BAMUM LETTER YOQ;Lo;0;L;;;;;N;;;;;\nA6C0;BAMUM LETTER SHU;Lo;0;L;;;;;N;;;;;\nA6C1;BAMUM LETTER YUQ;Lo;0;L;;;;;N;;;;;\nA6C2;BAMUM LETTER YA;Lo;0;L;;;;;N;;;;;\nA6C3;BAMUM LETTER NSHA;Lo;0;L;;;;;N;;;;;\nA6C4;BAMUM LETTER KEUX;Lo;0;L;;;;;N;;;;;\nA6C5;BAMUM LETTER PEUX;Lo;0;L;;;;;N;;;;;\nA6C6;BAMUM LETTER NJEE;Lo;0;L;;;;;N;;;;;\nA6C7;BAMUM LETTER NTEE;Lo;0;L;;;;;N;;;;;\nA6C8;BAMUM LETTER PUE;Lo;0;L;;;;;N;;;;;\nA6C9;BAMUM LETTER WUE;Lo;0;L;;;;;N;;;;;\nA6CA;BAMUM LETTER PEE;Lo;0;L;;;;;N;;;;;\nA6CB;BAMUM LETTER FEE;Lo;0;L;;;;;N;;;;;\nA6CC;BAMUM LETTER RU;Lo;0;L;;;;;N;;;;;\nA6CD;BAMUM LETTER LU;Lo;0;L;;;;;N;;;;;\nA6CE;BAMUM LETTER MI;Lo;0;L;;;;;N;;;;;\nA6CF;BAMUM LETTER NI;Lo;0;L;;;;;N;;;;;\nA6D0;BAMUM LETTER REUX;Lo;0;L;;;;;N;;;;;\nA6D1;BAMUM LETTER RAE;Lo;0;L;;;;;N;;;;;\nA6D2;BAMUM LETTER KEN;Lo;0;L;;;;;N;;;;;\nA6D3;BAMUM LETTER NGKWAEN;Lo;0;L;;;;;N;;;;;\nA6D4;BAMUM LETTER NGGA;Lo;0;L;;;;;N;;;;;\nA6D5;BAMUM LETTER NGA;Lo;0;L;;;;;N;;;;;\nA6D6;BAMUM LETTER SHO;Lo;0;L;;;;;N;;;;;\nA6D7;BAMUM LETTER PUAE;Lo;0;L;;;;;N;;;;;\nA6D8;BAMUM LETTER FU;Lo;0;L;;;;;N;;;;;\nA6D9;BAMUM LETTER FOM;Lo;0;L;;;;;N;;;;;\nA6DA;BAMUM LETTER WA;Lo;0;L;;;;;N;;;;;\nA6DB;BAMUM LETTER NA;Lo;0;L;;;;;N;;;;;\nA6DC;BAMUM LETTER LI;Lo;0;L;;;;;N;;;;;\nA6DD;BAMUM LETTER PI;Lo;0;L;;;;;N;;;;;\nA6DE;BAMUM LETTER LOQ;Lo;0;L;;;;;N;;;;;\nA6DF;BAMUM LETTER KO;Lo;0;L;;;;;N;;;;;\nA6E0;BAMUM LETTER MBEN;Lo;0;L;;;;;N;;;;;\nA6E1;BAMUM LETTER REN;Lo;0;L;;;;;N;;;;;\nA6E2;BAMUM LETTER MEN;Lo;0;L;;;;;N;;;;;\nA6E3;BAMUM LETTER MA;Lo;0;L;;;;;N;;;;;\nA6E4;BAMUM LETTER TI;Lo;0;L;;;;;N;;;;;\nA6E5;BAMUM LETTER KI;Lo;0;L;;;;;N;;;;;\nA6E6;BAMUM LETTER MO;Nl;0;L;;;;1;N;;;;;\nA6E7;BAMUM LETTER MBAA;Nl;0;L;;;;2;N;;;;;\nA6E8;BAMUM LETTER TET;Nl;0;L;;;;3;N;;;;;\nA6E9;BAMUM LETTER KPA;Nl;0;L;;;;4;N;;;;;\nA6EA;BAMUM LETTER TEN;Nl;0;L;;;;5;N;;;;;\nA6EB;BAMUM LETTER NTUU;Nl;0;L;;;;6;N;;;;;\nA6EC;BAMUM LETTER SAMBA;Nl;0;L;;;;7;N;;;;;\nA6ED;BAMUM LETTER FAAMAE;Nl;0;L;;;;8;N;;;;;\nA6EE;BAMUM LETTER KOVUU;Nl;0;L;;;;9;N;;;;;\nA6EF;BAMUM LETTER KOGHOM;Nl;0;L;;;;0;N;;;;;\nA6F0;BAMUM COMBINING MARK KOQNDON;Mn;230;NSM;;;;;N;;;;;\nA6F1;BAMUM COMBINING MARK TUKWENTIS;Mn;230;NSM;;;;;N;;;;;\nA6F2;BAMUM NJAEMLI;Po;0;L;;;;;N;;;;;\nA6F3;BAMUM FULL STOP;Po;0;L;;;;;N;;;;;\nA6F4;BAMUM COLON;Po;0;L;;;;;N;;;;;\nA6F5;BAMUM COMMA;Po;0;L;;;;;N;;;;;\nA6F6;BAMUM SEMICOLON;Po;0;L;;;;;N;;;;;\nA6F7;BAMUM QUESTION MARK;Po;0;L;;;;;N;;;;;\nA700;MODIFIER LETTER CHINESE TONE YIN PING;Sk;0;ON;;;;;N;;;;;\nA701;MODIFIER LETTER CHINESE TONE YANG PING;Sk;0;ON;;;;;N;;;;;\nA702;MODIFIER LETTER CHINESE TONE YIN SHANG;Sk;0;ON;;;;;N;;;;;\nA703;MODIFIER LETTER CHINESE TONE YANG SHANG;Sk;0;ON;;;;;N;;;;;\nA704;MODIFIER LETTER CHINESE TONE YIN QU;Sk;0;ON;;;;;N;;;;;\nA705;MODIFIER LETTER CHINESE TONE YANG QU;Sk;0;ON;;;;;N;;;;;\nA706;MODIFIER LETTER CHINESE TONE YIN RU;Sk;0;ON;;;;;N;;;;;\nA707;MODIFIER LETTER CHINESE TONE YANG RU;Sk;0;ON;;;;;N;;;;;\nA708;MODIFIER LETTER EXTRA-HIGH DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;\nA709;MODIFIER LETTER HIGH DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;\nA70A;MODIFIER LETTER MID DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;\nA70B;MODIFIER LETTER LOW DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;\nA70C;MODIFIER LETTER EXTRA-LOW DOTTED TONE BAR;Sk;0;ON;;;;;N;;;;;\nA70D;MODIFIER LETTER EXTRA-HIGH DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;\nA70E;MODIFIER LETTER HIGH DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;\nA70F;MODIFIER LETTER MID DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;\nA710;MODIFIER LETTER LOW DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;\nA711;MODIFIER LETTER EXTRA-LOW DOTTED LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;\nA712;MODIFIER LETTER EXTRA-HIGH LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;\nA713;MODIFIER LETTER HIGH LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;\nA714;MODIFIER LETTER MID LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;\nA715;MODIFIER LETTER LOW LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;\nA716;MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR;Sk;0;ON;;;;;N;;;;;\nA717;MODIFIER LETTER DOT VERTICAL BAR;Lm;0;ON;;;;;N;;;;;\nA718;MODIFIER LETTER DOT SLASH;Lm;0;ON;;;;;N;;;;;\nA719;MODIFIER LETTER DOT HORIZONTAL BAR;Lm;0;ON;;;;;N;;;;;\nA71A;MODIFIER LETTER LOWER RIGHT CORNER ANGLE;Lm;0;ON;;;;;N;;;;;\nA71B;MODIFIER LETTER RAISED UP ARROW;Lm;0;ON;;;;;N;;;;;\nA71C;MODIFIER LETTER RAISED DOWN ARROW;Lm;0;ON;;;;;N;;;;;\nA71D;MODIFIER LETTER RAISED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;;\nA71E;MODIFIER LETTER RAISED INVERTED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;;\nA71F;MODIFIER LETTER LOW INVERTED EXCLAMATION MARK;Lm;0;ON;;;;;N;;;;;\nA720;MODIFIER LETTER STRESS AND HIGH TONE;Sk;0;ON;;;;;N;;;;;\nA721;MODIFIER LETTER STRESS AND LOW TONE;Sk;0;ON;;;;;N;;;;;\nA722;LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF;Lu;0;L;;;;;N;;;;A723;\nA723;LATIN SMALL LETTER EGYPTOLOGICAL ALEF;Ll;0;L;;;;;N;;;A722;;A722\nA724;LATIN CAPITAL LETTER EGYPTOLOGICAL AIN;Lu;0;L;;;;;N;;;;A725;\nA725;LATIN SMALL LETTER EGYPTOLOGICAL AIN;Ll;0;L;;;;;N;;;A724;;A724\nA726;LATIN CAPITAL LETTER HENG;Lu;0;L;;;;;N;;;;A727;\nA727;LATIN SMALL LETTER HENG;Ll;0;L;;;;;N;;;A726;;A726\nA728;LATIN CAPITAL LETTER TZ;Lu;0;L;;;;;N;;;;A729;\nA729;LATIN SMALL LETTER TZ;Ll;0;L;;;;;N;;;A728;;A728\nA72A;LATIN CAPITAL LETTER TRESILLO;Lu;0;L;;;;;N;;;;A72B;\nA72B;LATIN SMALL LETTER TRESILLO;Ll;0;L;;;;;N;;;A72A;;A72A\nA72C;LATIN CAPITAL LETTER CUATRILLO;Lu;0;L;;;;;N;;;;A72D;\nA72D;LATIN SMALL LETTER CUATRILLO;Ll;0;L;;;;;N;;;A72C;;A72C\nA72E;LATIN CAPITAL LETTER CUATRILLO WITH COMMA;Lu;0;L;;;;;N;;;;A72F;\nA72F;LATIN SMALL LETTER CUATRILLO WITH COMMA;Ll;0;L;;;;;N;;;A72E;;A72E\nA730;LATIN LETTER SMALL CAPITAL F;Ll;0;L;;;;;N;;;;;\nA731;LATIN LETTER SMALL CAPITAL S;Ll;0;L;;;;;N;;;;;\nA732;LATIN CAPITAL LETTER AA;Lu;0;L;;;;;N;;;;A733;\nA733;LATIN SMALL LETTER AA;Ll;0;L;;;;;N;;;A732;;A732\nA734;LATIN CAPITAL LETTER AO;Lu;0;L;;;;;N;;;;A735;\nA735;LATIN SMALL LETTER AO;Ll;0;L;;;;;N;;;A734;;A734\nA736;LATIN CAPITAL LETTER AU;Lu;0;L;;;;;N;;;;A737;\nA737;LATIN SMALL LETTER AU;Ll;0;L;;;;;N;;;A736;;A736\nA738;LATIN CAPITAL LETTER AV;Lu;0;L;;;;;N;;;;A739;\nA739;LATIN SMALL LETTER AV;Ll;0;L;;;;;N;;;A738;;A738\nA73A;LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR;Lu;0;L;;;;;N;;;;A73B;\nA73B;LATIN SMALL LETTER AV WITH HORIZONTAL BAR;Ll;0;L;;;;;N;;;A73A;;A73A\nA73C;LATIN CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;A73D;\nA73D;LATIN SMALL LETTER AY;Ll;0;L;;;;;N;;;A73C;;A73C\nA73E;LATIN CAPITAL LETTER REVERSED C WITH DOT;Lu;0;L;;;;;N;;;;A73F;\nA73F;LATIN SMALL LETTER REVERSED C WITH DOT;Ll;0;L;;;;;N;;;A73E;;A73E\nA740;LATIN CAPITAL LETTER K WITH STROKE;Lu;0;L;;;;;N;;;;A741;\nA741;LATIN SMALL LETTER K WITH STROKE;Ll;0;L;;;;;N;;;A740;;A740\nA742;LATIN CAPITAL LETTER K WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A743;\nA743;LATIN SMALL LETTER K WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A742;;A742\nA744;LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A745;\nA745;LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE;Ll;0;L;;;;;N;;;A744;;A744\nA746;LATIN CAPITAL LETTER BROKEN L;Lu;0;L;;;;;N;;;;A747;\nA747;LATIN SMALL LETTER BROKEN L;Ll;0;L;;;;;N;;;A746;;A746\nA748;LATIN CAPITAL LETTER L WITH HIGH STROKE;Lu;0;L;;;;;N;;;;A749;\nA749;LATIN SMALL LETTER L WITH HIGH STROKE;Ll;0;L;;;;;N;;;A748;;A748\nA74A;LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY;Lu;0;L;;;;;N;;;;A74B;\nA74B;LATIN SMALL LETTER O WITH LONG STROKE OVERLAY;Ll;0;L;;;;;N;;;A74A;;A74A\nA74C;LATIN CAPITAL LETTER O WITH LOOP;Lu;0;L;;;;;N;;;;A74D;\nA74D;LATIN SMALL LETTER O WITH LOOP;Ll;0;L;;;;;N;;;A74C;;A74C\nA74E;LATIN CAPITAL LETTER OO;Lu;0;L;;;;;N;;;;A74F;\nA74F;LATIN SMALL LETTER OO;Ll;0;L;;;;;N;;;A74E;;A74E\nA750;LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A751;\nA751;LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A750;;A750\nA752;LATIN CAPITAL LETTER P WITH FLOURISH;Lu;0;L;;;;;N;;;;A753;\nA753;LATIN SMALL LETTER P WITH FLOURISH;Ll;0;L;;;;;N;;;A752;;A752\nA754;LATIN CAPITAL LETTER P WITH SQUIRREL TAIL;Lu;0;L;;;;;N;;;;A755;\nA755;LATIN SMALL LETTER P WITH SQUIRREL TAIL;Ll;0;L;;;;;N;;;A754;;A754\nA756;LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A757;\nA757;LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A756;;A756\nA758;LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A759;\nA759;LATIN SMALL LETTER Q WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A758;;A758\nA75A;LATIN CAPITAL LETTER R ROTUNDA;Lu;0;L;;;;;N;;;;A75B;\nA75B;LATIN SMALL LETTER R ROTUNDA;Ll;0;L;;;;;N;;;A75A;;A75A\nA75C;LATIN CAPITAL LETTER RUM ROTUNDA;Lu;0;L;;;;;N;;;;A75D;\nA75D;LATIN SMALL LETTER RUM ROTUNDA;Ll;0;L;;;;;N;;;A75C;;A75C\nA75E;LATIN CAPITAL LETTER V WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A75F;\nA75F;LATIN SMALL LETTER V WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A75E;;A75E\nA760;LATIN CAPITAL LETTER VY;Lu;0;L;;;;;N;;;;A761;\nA761;LATIN SMALL LETTER VY;Ll;0;L;;;;;N;;;A760;;A760\nA762;LATIN CAPITAL LETTER VISIGOTHIC Z;Lu;0;L;;;;;N;;;;A763;\nA763;LATIN SMALL LETTER VISIGOTHIC Z;Ll;0;L;;;;;N;;;A762;;A762\nA764;LATIN CAPITAL LETTER THORN WITH STROKE;Lu;0;L;;;;;N;;;;A765;\nA765;LATIN SMALL LETTER THORN WITH STROKE;Ll;0;L;;;;;N;;;A764;;A764\nA766;LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER;Lu;0;L;;;;;N;;;;A767;\nA767;LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER;Ll;0;L;;;;;N;;;A766;;A766\nA768;LATIN CAPITAL LETTER VEND;Lu;0;L;;;;;N;;;;A769;\nA769;LATIN SMALL LETTER VEND;Ll;0;L;;;;;N;;;A768;;A768\nA76A;LATIN CAPITAL LETTER ET;Lu;0;L;;;;;N;;;;A76B;\nA76B;LATIN SMALL LETTER ET;Ll;0;L;;;;;N;;;A76A;;A76A\nA76C;LATIN CAPITAL LETTER IS;Lu;0;L;;;;;N;;;;A76D;\nA76D;LATIN SMALL LETTER IS;Ll;0;L;;;;;N;;;A76C;;A76C\nA76E;LATIN CAPITAL LETTER CON;Lu;0;L;;;;;N;;;;A76F;\nA76F;LATIN SMALL LETTER CON;Ll;0;L;;;;;N;;;A76E;;A76E\nA770;MODIFIER LETTER US;Lm;0;L;<super> A76F;;;;N;;;;;\nA771;LATIN SMALL LETTER DUM;Ll;0;L;;;;;N;;;;;\nA772;LATIN SMALL LETTER LUM;Ll;0;L;;;;;N;;;;;\nA773;LATIN SMALL LETTER MUM;Ll;0;L;;;;;N;;;;;\nA774;LATIN SMALL LETTER NUM;Ll;0;L;;;;;N;;;;;\nA775;LATIN SMALL LETTER RUM;Ll;0;L;;;;;N;;;;;\nA776;LATIN LETTER SMALL CAPITAL RUM;Ll;0;L;;;;;N;;;;;\nA777;LATIN SMALL LETTER TUM;Ll;0;L;;;;;N;;;;;\nA778;LATIN SMALL LETTER UM;Ll;0;L;;;;;N;;;;;\nA779;LATIN CAPITAL LETTER INSULAR D;Lu;0;L;;;;;N;;;;A77A;\nA77A;LATIN SMALL LETTER INSULAR D;Ll;0;L;;;;;N;;;A779;;A779\nA77B;LATIN CAPITAL LETTER INSULAR F;Lu;0;L;;;;;N;;;;A77C;\nA77C;LATIN SMALL LETTER INSULAR F;Ll;0;L;;;;;N;;;A77B;;A77B\nA77D;LATIN CAPITAL LETTER INSULAR G;Lu;0;L;;;;;N;;;;1D79;\nA77E;LATIN CAPITAL LETTER TURNED INSULAR G;Lu;0;L;;;;;N;;;;A77F;\nA77F;LATIN SMALL LETTER TURNED INSULAR G;Ll;0;L;;;;;N;;;A77E;;A77E\nA780;LATIN CAPITAL LETTER TURNED L;Lu;0;L;;;;;N;;;;A781;\nA781;LATIN SMALL LETTER TURNED L;Ll;0;L;;;;;N;;;A780;;A780\nA782;LATIN CAPITAL LETTER INSULAR R;Lu;0;L;;;;;N;;;;A783;\nA783;LATIN SMALL LETTER INSULAR R;Ll;0;L;;;;;N;;;A782;;A782\nA784;LATIN CAPITAL LETTER INSULAR S;Lu;0;L;;;;;N;;;;A785;\nA785;LATIN SMALL LETTER INSULAR S;Ll;0;L;;;;;N;;;A784;;A784\nA786;LATIN CAPITAL LETTER INSULAR T;Lu;0;L;;;;;N;;;;A787;\nA787;LATIN SMALL LETTER INSULAR T;Ll;0;L;;;;;N;;;A786;;A786\nA788;MODIFIER LETTER LOW CIRCUMFLEX ACCENT;Lm;0;ON;;;;;N;;;;;\nA789;MODIFIER LETTER COLON;Sk;0;L;;;;;N;;;;;\nA78A;MODIFIER LETTER SHORT EQUALS SIGN;Sk;0;L;;;;;N;;;;;\nA78B;LATIN CAPITAL LETTER SALTILLO;Lu;0;L;;;;;N;;;;A78C;\nA78C;LATIN SMALL LETTER SALTILLO;Ll;0;L;;;;;N;;;A78B;;A78B\nA78D;LATIN CAPITAL LETTER TURNED H;Lu;0;L;;;;;N;;;;0265;\nA78E;LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT;Ll;0;L;;;;;N;;;;;\nA78F;LATIN LETTER SINOLOGICAL DOT;Lo;0;L;;;;;N;;;;;\nA790;LATIN CAPITAL LETTER N WITH DESCENDER;Lu;0;L;;;;;N;;;;A791;\nA791;LATIN SMALL LETTER N WITH DESCENDER;Ll;0;L;;;;;N;;;A790;;A790\nA792;LATIN CAPITAL LETTER C WITH BAR;Lu;0;L;;;;;N;;;;A793;\nA793;LATIN SMALL LETTER C WITH BAR;Ll;0;L;;;;;N;;;A792;;A792\nA794;LATIN SMALL LETTER C WITH PALATAL HOOK;Ll;0;L;;;;;N;;;A7C4;;A7C4\nA795;LATIN SMALL LETTER H WITH PALATAL HOOK;Ll;0;L;;;;;N;;;;;\nA796;LATIN CAPITAL LETTER B WITH FLOURISH;Lu;0;L;;;;;N;;;;A797;\nA797;LATIN SMALL LETTER B WITH FLOURISH;Ll;0;L;;;;;N;;;A796;;A796\nA798;LATIN CAPITAL LETTER F WITH STROKE;Lu;0;L;;;;;N;;;;A799;\nA799;LATIN SMALL LETTER F WITH STROKE;Ll;0;L;;;;;N;;;A798;;A798\nA79A;LATIN CAPITAL LETTER VOLAPUK AE;Lu;0;L;;;;;N;;;;A79B;\nA79B;LATIN SMALL LETTER VOLAPUK AE;Ll;0;L;;;;;N;;;A79A;;A79A\nA79C;LATIN CAPITAL LETTER VOLAPUK OE;Lu;0;L;;;;;N;;;;A79D;\nA79D;LATIN SMALL LETTER VOLAPUK OE;Ll;0;L;;;;;N;;;A79C;;A79C\nA79E;LATIN CAPITAL LETTER VOLAPUK UE;Lu;0;L;;;;;N;;;;A79F;\nA79F;LATIN SMALL LETTER VOLAPUK UE;Ll;0;L;;;;;N;;;A79E;;A79E\nA7A0;LATIN CAPITAL LETTER G WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A1;\nA7A1;LATIN SMALL LETTER G WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A0;;A7A0\nA7A2;LATIN CAPITAL LETTER K WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A3;\nA7A3;LATIN SMALL LETTER K WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A2;;A7A2\nA7A4;LATIN CAPITAL LETTER N WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A5;\nA7A5;LATIN SMALL LETTER N WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A4;;A7A4\nA7A6;LATIN CAPITAL LETTER R WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A7;\nA7A7;LATIN SMALL LETTER R WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A6;;A7A6\nA7A8;LATIN CAPITAL LETTER S WITH OBLIQUE STROKE;Lu;0;L;;;;;N;;;;A7A9;\nA7A9;LATIN SMALL LETTER S WITH OBLIQUE STROKE;Ll;0;L;;;;;N;;;A7A8;;A7A8\nA7AA;LATIN CAPITAL LETTER H WITH HOOK;Lu;0;L;;;;;N;;;;0266;\nA7AB;LATIN CAPITAL LETTER REVERSED OPEN E;Lu;0;L;;;;;N;;;;025C;\nA7AC;LATIN CAPITAL LETTER SCRIPT G;Lu;0;L;;;;;N;;;;0261;\nA7AD;LATIN CAPITAL LETTER L WITH BELT;Lu;0;L;;;;;N;;;;026C;\nA7AE;LATIN CAPITAL LETTER SMALL CAPITAL I;Lu;0;L;;;;;N;;;;026A;\nA7AF;LATIN LETTER SMALL CAPITAL Q;Ll;0;L;;;;;N;;;;;\nA7B0;LATIN CAPITAL LETTER TURNED K;Lu;0;L;;;;;N;;;;029E;\nA7B1;LATIN CAPITAL LETTER TURNED T;Lu;0;L;;;;;N;;;;0287;\nA7B2;LATIN CAPITAL LETTER J WITH CROSSED-TAIL;Lu;0;L;;;;;N;;;;029D;\nA7B3;LATIN CAPITAL LETTER CHI;Lu;0;L;;;;;N;;;;AB53;\nA7B4;LATIN CAPITAL LETTER BETA;Lu;0;L;;;;;N;;;;A7B5;\nA7B5;LATIN SMALL LETTER BETA;Ll;0;L;;;;;N;;;A7B4;;A7B4\nA7B6;LATIN CAPITAL LETTER OMEGA;Lu;0;L;;;;;N;;;;A7B7;\nA7B7;LATIN SMALL LETTER OMEGA;Ll;0;L;;;;;N;;;A7B6;;A7B6\nA7B8;LATIN CAPITAL LETTER U WITH STROKE;Lu;0;L;;;;;N;;;;A7B9;\nA7B9;LATIN SMALL LETTER U WITH STROKE;Ll;0;L;;;;;N;;;A7B8;;A7B8\nA7BA;LATIN CAPITAL LETTER GLOTTAL A;Lu;0;L;;;;;N;;;;A7BB;\nA7BB;LATIN SMALL LETTER GLOTTAL A;Ll;0;L;;;;;N;;;A7BA;;A7BA\nA7BC;LATIN CAPITAL LETTER GLOTTAL I;Lu;0;L;;;;;N;;;;A7BD;\nA7BD;LATIN SMALL LETTER GLOTTAL I;Ll;0;L;;;;;N;;;A7BC;;A7BC\nA7BE;LATIN CAPITAL LETTER GLOTTAL U;Lu;0;L;;;;;N;;;;A7BF;\nA7BF;LATIN SMALL LETTER GLOTTAL U;Ll;0;L;;;;;N;;;A7BE;;A7BE\nA7C2;LATIN CAPITAL LETTER ANGLICANA W;Lu;0;L;;;;;N;;;;A7C3;\nA7C3;LATIN SMALL LETTER ANGLICANA W;Ll;0;L;;;;;N;;;A7C2;;A7C2\nA7C4;LATIN CAPITAL LETTER C WITH PALATAL HOOK;Lu;0;L;;;;;N;;;;A794;\nA7C5;LATIN CAPITAL LETTER S WITH HOOK;Lu;0;L;;;;;N;;;;0282;\nA7C6;LATIN CAPITAL LETTER Z WITH PALATAL HOOK;Lu;0;L;;;;;N;;;;1D8E;\nA7F7;LATIN EPIGRAPHIC LETTER SIDEWAYS I;Lo;0;L;;;;;N;;;;;\nA7F8;MODIFIER LETTER CAPITAL H WITH STROKE;Lm;0;L;<super> 0126;;;;N;;;;;\nA7F9;MODIFIER LETTER SMALL LIGATURE OE;Lm;0;L;<super> 0153;;;;N;;;;;\nA7FA;LATIN LETTER SMALL CAPITAL TURNED M;Ll;0;L;;;;;N;;;;;\nA7FB;LATIN EPIGRAPHIC LETTER REVERSED F;Lo;0;L;;;;;N;;;;;\nA7FC;LATIN EPIGRAPHIC LETTER REVERSED P;Lo;0;L;;;;;N;;;;;\nA7FD;LATIN EPIGRAPHIC LETTER INVERTED M;Lo;0;L;;;;;N;;;;;\nA7FE;LATIN EPIGRAPHIC LETTER I LONGA;Lo;0;L;;;;;N;;;;;\nA7FF;LATIN EPIGRAPHIC LETTER ARCHAIC M;Lo;0;L;;;;;N;;;;;\nA800;SYLOTI NAGRI LETTER A;Lo;0;L;;;;;N;;;;;\nA801;SYLOTI NAGRI LETTER I;Lo;0;L;;;;;N;;;;;\nA802;SYLOTI NAGRI SIGN DVISVARA;Mn;0;NSM;;;;;N;;;;;\nA803;SYLOTI NAGRI LETTER U;Lo;0;L;;;;;N;;;;;\nA804;SYLOTI NAGRI LETTER E;Lo;0;L;;;;;N;;;;;\nA805;SYLOTI NAGRI LETTER O;Lo;0;L;;;;;N;;;;;\nA806;SYLOTI NAGRI SIGN HASANTA;Mn;9;NSM;;;;;N;;;;;\nA807;SYLOTI NAGRI LETTER KO;Lo;0;L;;;;;N;;;;;\nA808;SYLOTI NAGRI LETTER KHO;Lo;0;L;;;;;N;;;;;\nA809;SYLOTI NAGRI LETTER GO;Lo;0;L;;;;;N;;;;;\nA80A;SYLOTI NAGRI LETTER GHO;Lo;0;L;;;;;N;;;;;\nA80B;SYLOTI NAGRI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\nA80C;SYLOTI NAGRI LETTER CO;Lo;0;L;;;;;N;;;;;\nA80D;SYLOTI NAGRI LETTER CHO;Lo;0;L;;;;;N;;;;;\nA80E;SYLOTI NAGRI LETTER JO;Lo;0;L;;;;;N;;;;;\nA80F;SYLOTI NAGRI LETTER JHO;Lo;0;L;;;;;N;;;;;\nA810;SYLOTI NAGRI LETTER TTO;Lo;0;L;;;;;N;;;;;\nA811;SYLOTI NAGRI LETTER TTHO;Lo;0;L;;;;;N;;;;;\nA812;SYLOTI NAGRI LETTER DDO;Lo;0;L;;;;;N;;;;;\nA813;SYLOTI NAGRI LETTER DDHO;Lo;0;L;;;;;N;;;;;\nA814;SYLOTI NAGRI LETTER TO;Lo;0;L;;;;;N;;;;;\nA815;SYLOTI NAGRI LETTER THO;Lo;0;L;;;;;N;;;;;\nA816;SYLOTI NAGRI LETTER DO;Lo;0;L;;;;;N;;;;;\nA817;SYLOTI NAGRI LETTER DHO;Lo;0;L;;;;;N;;;;;\nA818;SYLOTI NAGRI LETTER NO;Lo;0;L;;;;;N;;;;;\nA819;SYLOTI NAGRI LETTER PO;Lo;0;L;;;;;N;;;;;\nA81A;SYLOTI NAGRI LETTER PHO;Lo;0;L;;;;;N;;;;;\nA81B;SYLOTI NAGRI LETTER BO;Lo;0;L;;;;;N;;;;;\nA81C;SYLOTI NAGRI LETTER BHO;Lo;0;L;;;;;N;;;;;\nA81D;SYLOTI NAGRI LETTER MO;Lo;0;L;;;;;N;;;;;\nA81E;SYLOTI NAGRI LETTER RO;Lo;0;L;;;;;N;;;;;\nA81F;SYLOTI NAGRI LETTER LO;Lo;0;L;;;;;N;;;;;\nA820;SYLOTI NAGRI LETTER RRO;Lo;0;L;;;;;N;;;;;\nA821;SYLOTI NAGRI LETTER SO;Lo;0;L;;;;;N;;;;;\nA822;SYLOTI NAGRI LETTER HO;Lo;0;L;;;;;N;;;;;\nA823;SYLOTI NAGRI VOWEL SIGN A;Mc;0;L;;;;;N;;;;;\nA824;SYLOTI NAGRI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\nA825;SYLOTI NAGRI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\nA826;SYLOTI NAGRI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\nA827;SYLOTI NAGRI VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;\nA828;SYLOTI NAGRI POETRY MARK-1;So;0;ON;;;;;N;;;;;\nA829;SYLOTI NAGRI POETRY MARK-2;So;0;ON;;;;;N;;;;;\nA82A;SYLOTI NAGRI POETRY MARK-3;So;0;ON;;;;;N;;;;;\nA82B;SYLOTI NAGRI POETRY MARK-4;So;0;ON;;;;;N;;;;;\nA830;NORTH INDIC FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;;\nA831;NORTH INDIC FRACTION ONE HALF;No;0;L;;;;1/2;N;;;;;\nA832;NORTH INDIC FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;;\nA833;NORTH INDIC FRACTION ONE SIXTEENTH;No;0;L;;;;1/16;N;;;;;\nA834;NORTH INDIC FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;;\nA835;NORTH INDIC FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;;\nA836;NORTH INDIC QUARTER MARK;So;0;L;;;;;N;;;;;\nA837;NORTH INDIC PLACEHOLDER MARK;So;0;L;;;;;N;;;;;\nA838;NORTH INDIC RUPEE MARK;Sc;0;ET;;;;;N;;;;;\nA839;NORTH INDIC QUANTITY MARK;So;0;ET;;;;;N;;;;;\nA840;PHAGS-PA LETTER KA;Lo;0;L;;;;;N;;;;;\nA841;PHAGS-PA LETTER KHA;Lo;0;L;;;;;N;;;;;\nA842;PHAGS-PA LETTER GA;Lo;0;L;;;;;N;;;;;\nA843;PHAGS-PA LETTER NGA;Lo;0;L;;;;;N;;;;;\nA844;PHAGS-PA LETTER CA;Lo;0;L;;;;;N;;;;;\nA845;PHAGS-PA LETTER CHA;Lo;0;L;;;;;N;;;;;\nA846;PHAGS-PA LETTER JA;Lo;0;L;;;;;N;;;;;\nA847;PHAGS-PA LETTER NYA;Lo;0;L;;;;;N;;;;;\nA848;PHAGS-PA LETTER TA;Lo;0;L;;;;;N;;;;;\nA849;PHAGS-PA LETTER THA;Lo;0;L;;;;;N;;;;;\nA84A;PHAGS-PA LETTER DA;Lo;0;L;;;;;N;;;;;\nA84B;PHAGS-PA LETTER NA;Lo;0;L;;;;;N;;;;;\nA84C;PHAGS-PA LETTER PA;Lo;0;L;;;;;N;;;;;\nA84D;PHAGS-PA LETTER PHA;Lo;0;L;;;;;N;;;;;\nA84E;PHAGS-PA LETTER BA;Lo;0;L;;;;;N;;;;;\nA84F;PHAGS-PA LETTER MA;Lo;0;L;;;;;N;;;;;\nA850;PHAGS-PA LETTER TSA;Lo;0;L;;;;;N;;;;;\nA851;PHAGS-PA LETTER TSHA;Lo;0;L;;;;;N;;;;;\nA852;PHAGS-PA LETTER DZA;Lo;0;L;;;;;N;;;;;\nA853;PHAGS-PA LETTER WA;Lo;0;L;;;;;N;;;;;\nA854;PHAGS-PA LETTER ZHA;Lo;0;L;;;;;N;;;;;\nA855;PHAGS-PA LETTER ZA;Lo;0;L;;;;;N;;;;;\nA856;PHAGS-PA LETTER SMALL A;Lo;0;L;;;;;N;;;;;\nA857;PHAGS-PA LETTER YA;Lo;0;L;;;;;N;;;;;\nA858;PHAGS-PA LETTER RA;Lo;0;L;;;;;N;;;;;\nA859;PHAGS-PA LETTER LA;Lo;0;L;;;;;N;;;;;\nA85A;PHAGS-PA LETTER SHA;Lo;0;L;;;;;N;;;;;\nA85B;PHAGS-PA LETTER SA;Lo;0;L;;;;;N;;;;;\nA85C;PHAGS-PA LETTER HA;Lo;0;L;;;;;N;;;;;\nA85D;PHAGS-PA LETTER A;Lo;0;L;;;;;N;;;;;\nA85E;PHAGS-PA LETTER I;Lo;0;L;;;;;N;;;;;\nA85F;PHAGS-PA LETTER U;Lo;0;L;;;;;N;;;;;\nA860;PHAGS-PA LETTER E;Lo;0;L;;;;;N;;;;;\nA861;PHAGS-PA LETTER O;Lo;0;L;;;;;N;;;;;\nA862;PHAGS-PA LETTER QA;Lo;0;L;;;;;N;;;;;\nA863;PHAGS-PA LETTER XA;Lo;0;L;;;;;N;;;;;\nA864;PHAGS-PA LETTER FA;Lo;0;L;;;;;N;;;;;\nA865;PHAGS-PA LETTER GGA;Lo;0;L;;;;;N;;;;;\nA866;PHAGS-PA LETTER EE;Lo;0;L;;;;;N;;;;;\nA867;PHAGS-PA SUBJOINED LETTER WA;Lo;0;L;;;;;N;;;;;\nA868;PHAGS-PA SUBJOINED LETTER YA;Lo;0;L;;;;;N;;;;;\nA869;PHAGS-PA LETTER TTA;Lo;0;L;;;;;N;;;;;\nA86A;PHAGS-PA LETTER TTHA;Lo;0;L;;;;;N;;;;;\nA86B;PHAGS-PA LETTER DDA;Lo;0;L;;;;;N;;;;;\nA86C;PHAGS-PA LETTER NNA;Lo;0;L;;;;;N;;;;;\nA86D;PHAGS-PA LETTER ALTERNATE YA;Lo;0;L;;;;;N;;;;;\nA86E;PHAGS-PA LETTER VOICELESS SHA;Lo;0;L;;;;;N;;;;;\nA86F;PHAGS-PA LETTER VOICED HA;Lo;0;L;;;;;N;;;;;\nA870;PHAGS-PA LETTER ASPIRATED FA;Lo;0;L;;;;;N;;;;;\nA871;PHAGS-PA SUBJOINED LETTER RA;Lo;0;L;;;;;N;;;;;\nA872;PHAGS-PA SUPERFIXED LETTER RA;Lo;0;L;;;;;N;;;;;\nA873;PHAGS-PA LETTER CANDRABINDU;Lo;0;L;;;;;N;;;;;\nA874;PHAGS-PA SINGLE HEAD MARK;Po;0;ON;;;;;N;;;;;\nA875;PHAGS-PA DOUBLE HEAD MARK;Po;0;ON;;;;;N;;;;;\nA876;PHAGS-PA MARK SHAD;Po;0;ON;;;;;N;;;;;\nA877;PHAGS-PA MARK DOUBLE SHAD;Po;0;ON;;;;;N;;;;;\nA880;SAURASHTRA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;\nA881;SAURASHTRA SIGN VISARGA;Mc;0;L;;;;;N;;;;;\nA882;SAURASHTRA LETTER A;Lo;0;L;;;;;N;;;;;\nA883;SAURASHTRA LETTER AA;Lo;0;L;;;;;N;;;;;\nA884;SAURASHTRA LETTER I;Lo;0;L;;;;;N;;;;;\nA885;SAURASHTRA LETTER II;Lo;0;L;;;;;N;;;;;\nA886;SAURASHTRA LETTER U;Lo;0;L;;;;;N;;;;;\nA887;SAURASHTRA LETTER UU;Lo;0;L;;;;;N;;;;;\nA888;SAURASHTRA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\nA889;SAURASHTRA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\nA88A;SAURASHTRA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\nA88B;SAURASHTRA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\nA88C;SAURASHTRA LETTER E;Lo;0;L;;;;;N;;;;;\nA88D;SAURASHTRA LETTER EE;Lo;0;L;;;;;N;;;;;\nA88E;SAURASHTRA LETTER AI;Lo;0;L;;;;;N;;;;;\nA88F;SAURASHTRA LETTER O;Lo;0;L;;;;;N;;;;;\nA890;SAURASHTRA LETTER OO;Lo;0;L;;;;;N;;;;;\nA891;SAURASHTRA LETTER AU;Lo;0;L;;;;;N;;;;;\nA892;SAURASHTRA LETTER KA;Lo;0;L;;;;;N;;;;;\nA893;SAURASHTRA LETTER KHA;Lo;0;L;;;;;N;;;;;\nA894;SAURASHTRA LETTER GA;Lo;0;L;;;;;N;;;;;\nA895;SAURASHTRA LETTER GHA;Lo;0;L;;;;;N;;;;;\nA896;SAURASHTRA LETTER NGA;Lo;0;L;;;;;N;;;;;\nA897;SAURASHTRA LETTER CA;Lo;0;L;;;;;N;;;;;\nA898;SAURASHTRA LETTER CHA;Lo;0;L;;;;;N;;;;;\nA899;SAURASHTRA LETTER JA;Lo;0;L;;;;;N;;;;;\nA89A;SAURASHTRA LETTER JHA;Lo;0;L;;;;;N;;;;;\nA89B;SAURASHTRA LETTER NYA;Lo;0;L;;;;;N;;;;;\nA89C;SAURASHTRA LETTER TTA;Lo;0;L;;;;;N;;;;;\nA89D;SAURASHTRA LETTER TTHA;Lo;0;L;;;;;N;;;;;\nA89E;SAURASHTRA LETTER DDA;Lo;0;L;;;;;N;;;;;\nA89F;SAURASHTRA LETTER DDHA;Lo;0;L;;;;;N;;;;;\nA8A0;SAURASHTRA LETTER NNA;Lo;0;L;;;;;N;;;;;\nA8A1;SAURASHTRA LETTER TA;Lo;0;L;;;;;N;;;;;\nA8A2;SAURASHTRA LETTER THA;Lo;0;L;;;;;N;;;;;\nA8A3;SAURASHTRA LETTER DA;Lo;0;L;;;;;N;;;;;\nA8A4;SAURASHTRA LETTER DHA;Lo;0;L;;;;;N;;;;;\nA8A5;SAURASHTRA LETTER NA;Lo;0;L;;;;;N;;;;;\nA8A6;SAURASHTRA LETTER PA;Lo;0;L;;;;;N;;;;;\nA8A7;SAURASHTRA LETTER PHA;Lo;0;L;;;;;N;;;;;\nA8A8;SAURASHTRA LETTER BA;Lo;0;L;;;;;N;;;;;\nA8A9;SAURASHTRA LETTER BHA;Lo;0;L;;;;;N;;;;;\nA8AA;SAURASHTRA LETTER MA;Lo;0;L;;;;;N;;;;;\nA8AB;SAURASHTRA LETTER YA;Lo;0;L;;;;;N;;;;;\nA8AC;SAURASHTRA LETTER RA;Lo;0;L;;;;;N;;;;;\nA8AD;SAURASHTRA LETTER LA;Lo;0;L;;;;;N;;;;;\nA8AE;SAURASHTRA LETTER VA;Lo;0;L;;;;;N;;;;;\nA8AF;SAURASHTRA LETTER SHA;Lo;0;L;;;;;N;;;;;\nA8B0;SAURASHTRA LETTER SSA;Lo;0;L;;;;;N;;;;;\nA8B1;SAURASHTRA LETTER SA;Lo;0;L;;;;;N;;;;;\nA8B2;SAURASHTRA LETTER HA;Lo;0;L;;;;;N;;;;;\nA8B3;SAURASHTRA LETTER LLA;Lo;0;L;;;;;N;;;;;\nA8B4;SAURASHTRA CONSONANT SIGN HAARU;Mc;0;L;;;;;N;;;;;\nA8B5;SAURASHTRA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\nA8B6;SAURASHTRA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\nA8B7;SAURASHTRA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\nA8B8;SAURASHTRA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;\nA8B9;SAURASHTRA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;\nA8BA;SAURASHTRA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;\nA8BB;SAURASHTRA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;\nA8BC;SAURASHTRA VOWEL SIGN VOCALIC L;Mc;0;L;;;;;N;;;;;\nA8BD;SAURASHTRA VOWEL SIGN VOCALIC LL;Mc;0;L;;;;;N;;;;;\nA8BE;SAURASHTRA VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\nA8BF;SAURASHTRA VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;\nA8C0;SAURASHTRA VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;\nA8C1;SAURASHTRA VOWEL SIGN O;Mc;0;L;;;;;N;;;;;\nA8C2;SAURASHTRA VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;\nA8C3;SAURASHTRA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;\nA8C4;SAURASHTRA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\nA8C5;SAURASHTRA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\nA8CE;SAURASHTRA DANDA;Po;0;L;;;;;N;;;;;\nA8CF;SAURASHTRA DOUBLE DANDA;Po;0;L;;;;;N;;;;;\nA8D0;SAURASHTRA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\nA8D1;SAURASHTRA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\nA8D2;SAURASHTRA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\nA8D3;SAURASHTRA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\nA8D4;SAURASHTRA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\nA8D5;SAURASHTRA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\nA8D6;SAURASHTRA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\nA8D7;SAURASHTRA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\nA8D8;SAURASHTRA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\nA8D9;SAURASHTRA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\nA8E0;COMBINING DEVANAGARI DIGIT ZERO;Mn;230;NSM;;;;;N;;;;;\nA8E1;COMBINING DEVANAGARI DIGIT ONE;Mn;230;NSM;;;;;N;;;;;\nA8E2;COMBINING DEVANAGARI DIGIT TWO;Mn;230;NSM;;;;;N;;;;;\nA8E3;COMBINING DEVANAGARI DIGIT THREE;Mn;230;NSM;;;;;N;;;;;\nA8E4;COMBINING DEVANAGARI DIGIT FOUR;Mn;230;NSM;;;;;N;;;;;\nA8E5;COMBINING DEVANAGARI DIGIT FIVE;Mn;230;NSM;;;;;N;;;;;\nA8E6;COMBINING DEVANAGARI DIGIT SIX;Mn;230;NSM;;;;;N;;;;;\nA8E7;COMBINING DEVANAGARI DIGIT SEVEN;Mn;230;NSM;;;;;N;;;;;\nA8E8;COMBINING DEVANAGARI DIGIT EIGHT;Mn;230;NSM;;;;;N;;;;;\nA8E9;COMBINING DEVANAGARI DIGIT NINE;Mn;230;NSM;;;;;N;;;;;\nA8EA;COMBINING DEVANAGARI LETTER A;Mn;230;NSM;;;;;N;;;;;\nA8EB;COMBINING DEVANAGARI LETTER U;Mn;230;NSM;;;;;N;;;;;\nA8EC;COMBINING DEVANAGARI LETTER KA;Mn;230;NSM;;;;;N;;;;;\nA8ED;COMBINING DEVANAGARI LETTER NA;Mn;230;NSM;;;;;N;;;;;\nA8EE;COMBINING DEVANAGARI LETTER PA;Mn;230;NSM;;;;;N;;;;;\nA8EF;COMBINING DEVANAGARI LETTER RA;Mn;230;NSM;;;;;N;;;;;\nA8F0;COMBINING DEVANAGARI LETTER VI;Mn;230;NSM;;;;;N;;;;;\nA8F1;COMBINING DEVANAGARI SIGN AVAGRAHA;Mn;230;NSM;;;;;N;;;;;\nA8F2;DEVANAGARI SIGN SPACING CANDRABINDU;Lo;0;L;;;;;N;;;;;\nA8F3;DEVANAGARI SIGN CANDRABINDU VIRAMA;Lo;0;L;;;;;N;;;;;\nA8F4;DEVANAGARI SIGN DOUBLE CANDRABINDU VIRAMA;Lo;0;L;;;;;N;;;;;\nA8F5;DEVANAGARI SIGN CANDRABINDU TWO;Lo;0;L;;;;;N;;;;;\nA8F6;DEVANAGARI SIGN CANDRABINDU THREE;Lo;0;L;;;;;N;;;;;\nA8F7;DEVANAGARI SIGN CANDRABINDU AVAGRAHA;Lo;0;L;;;;;N;;;;;\nA8F8;DEVANAGARI SIGN PUSHPIKA;Po;0;L;;;;;N;;;;;\nA8F9;DEVANAGARI GAP FILLER;Po;0;L;;;;;N;;;;;\nA8FA;DEVANAGARI CARET;Po;0;L;;;;;N;;;;;\nA8FB;DEVANAGARI HEADSTROKE;Lo;0;L;;;;;N;;;;;\nA8FC;DEVANAGARI SIGN SIDDHAM;Po;0;L;;;;;N;;;;;\nA8FD;DEVANAGARI JAIN OM;Lo;0;L;;;;;N;;;;;\nA8FE;DEVANAGARI LETTER AY;Lo;0;L;;;;;N;;;;;\nA8FF;DEVANAGARI VOWEL SIGN AY;Mn;0;NSM;;;;;N;;;;;\nA900;KAYAH LI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\nA901;KAYAH LI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\nA902;KAYAH LI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\nA903;KAYAH LI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\nA904;KAYAH LI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\nA905;KAYAH LI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\nA906;KAYAH LI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\nA907;KAYAH LI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\nA908;KAYAH LI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\nA909;KAYAH LI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\nA90A;KAYAH LI LETTER KA;Lo;0;L;;;;;N;;;;;\nA90B;KAYAH LI LETTER KHA;Lo;0;L;;;;;N;;;;;\nA90C;KAYAH LI LETTER GA;Lo;0;L;;;;;N;;;;;\nA90D;KAYAH LI LETTER NGA;Lo;0;L;;;;;N;;;;;\nA90E;KAYAH LI LETTER SA;Lo;0;L;;;;;N;;;;;\nA90F;KAYAH LI LETTER SHA;Lo;0;L;;;;;N;;;;;\nA910;KAYAH LI LETTER ZA;Lo;0;L;;;;;N;;;;;\nA911;KAYAH LI LETTER NYA;Lo;0;L;;;;;N;;;;;\nA912;KAYAH LI LETTER TA;Lo;0;L;;;;;N;;;;;\nA913;KAYAH LI LETTER HTA;Lo;0;L;;;;;N;;;;;\nA914;KAYAH LI LETTER NA;Lo;0;L;;;;;N;;;;;\nA915;KAYAH LI LETTER PA;Lo;0;L;;;;;N;;;;;\nA916;KAYAH LI LETTER PHA;Lo;0;L;;;;;N;;;;;\nA917;KAYAH LI LETTER MA;Lo;0;L;;;;;N;;;;;\nA918;KAYAH LI LETTER DA;Lo;0;L;;;;;N;;;;;\nA919;KAYAH LI LETTER BA;Lo;0;L;;;;;N;;;;;\nA91A;KAYAH LI LETTER RA;Lo;0;L;;;;;N;;;;;\nA91B;KAYAH LI LETTER YA;Lo;0;L;;;;;N;;;;;\nA91C;KAYAH LI LETTER LA;Lo;0;L;;;;;N;;;;;\nA91D;KAYAH LI LETTER WA;Lo;0;L;;;;;N;;;;;\nA91E;KAYAH LI LETTER THA;Lo;0;L;;;;;N;;;;;\nA91F;KAYAH LI LETTER HA;Lo;0;L;;;;;N;;;;;\nA920;KAYAH LI LETTER VA;Lo;0;L;;;;;N;;;;;\nA921;KAYAH LI LETTER CA;Lo;0;L;;;;;N;;;;;\nA922;KAYAH LI LETTER A;Lo;0;L;;;;;N;;;;;\nA923;KAYAH LI LETTER OE;Lo;0;L;;;;;N;;;;;\nA924;KAYAH LI LETTER I;Lo;0;L;;;;;N;;;;;\nA925;KAYAH LI LETTER OO;Lo;0;L;;;;;N;;;;;\nA926;KAYAH LI VOWEL UE;Mn;0;NSM;;;;;N;;;;;\nA927;KAYAH LI VOWEL E;Mn;0;NSM;;;;;N;;;;;\nA928;KAYAH LI VOWEL U;Mn;0;NSM;;;;;N;;;;;\nA929;KAYAH LI VOWEL EE;Mn;0;NSM;;;;;N;;;;;\nA92A;KAYAH LI VOWEL O;Mn;0;NSM;;;;;N;;;;;\nA92B;KAYAH LI TONE PLOPHU;Mn;220;NSM;;;;;N;;;;;\nA92C;KAYAH LI TONE CALYA;Mn;220;NSM;;;;;N;;;;;\nA92D;KAYAH LI TONE CALYA PLOPHU;Mn;220;NSM;;;;;N;;;;;\nA92E;KAYAH LI SIGN CWI;Po;0;L;;;;;N;;;;;\nA92F;KAYAH LI SIGN SHYA;Po;0;L;;;;;N;;;;;\nA930;REJANG LETTER KA;Lo;0;L;;;;;N;;;;;\nA931;REJANG LETTER GA;Lo;0;L;;;;;N;;;;;\nA932;REJANG LETTER NGA;Lo;0;L;;;;;N;;;;;\nA933;REJANG LETTER TA;Lo;0;L;;;;;N;;;;;\nA934;REJANG LETTER DA;Lo;0;L;;;;;N;;;;;\nA935;REJANG LETTER NA;Lo;0;L;;;;;N;;;;;\nA936;REJANG LETTER PA;Lo;0;L;;;;;N;;;;;\nA937;REJANG LETTER BA;Lo;0;L;;;;;N;;;;;\nA938;REJANG LETTER MA;Lo;0;L;;;;;N;;;;;\nA939;REJANG LETTER CA;Lo;0;L;;;;;N;;;;;\nA93A;REJANG LETTER JA;Lo;0;L;;;;;N;;;;;\nA93B;REJANG LETTER NYA;Lo;0;L;;;;;N;;;;;\nA93C;REJANG LETTER SA;Lo;0;L;;;;;N;;;;;\nA93D;REJANG LETTER RA;Lo;0;L;;;;;N;;;;;\nA93E;REJANG LETTER LA;Lo;0;L;;;;;N;;;;;\nA93F;REJANG LETTER YA;Lo;0;L;;;;;N;;;;;\nA940;REJANG LETTER WA;Lo;0;L;;;;;N;;;;;\nA941;REJANG LETTER HA;Lo;0;L;;;;;N;;;;;\nA942;REJANG LETTER MBA;Lo;0;L;;;;;N;;;;;\nA943;REJANG LETTER NGGA;Lo;0;L;;;;;N;;;;;\nA944;REJANG LETTER NDA;Lo;0;L;;;;;N;;;;;\nA945;REJANG LETTER NYJA;Lo;0;L;;;;;N;;;;;\nA946;REJANG LETTER A;Lo;0;L;;;;;N;;;;;\nA947;REJANG VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\nA948;REJANG VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\nA949;REJANG VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\nA94A;REJANG VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\nA94B;REJANG VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;\nA94C;REJANG VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;\nA94D;REJANG VOWEL SIGN EU;Mn;0;NSM;;;;;N;;;;;\nA94E;REJANG VOWEL SIGN EA;Mn;0;NSM;;;;;N;;;;;\nA94F;REJANG CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;;\nA950;REJANG CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;;\nA951;REJANG CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;;\nA952;REJANG CONSONANT SIGN H;Mc;0;L;;;;;N;;;;;\nA953;REJANG VIRAMA;Mc;9;L;;;;;N;;;;;\nA95F;REJANG SECTION MARK;Po;0;L;;;;;N;;;;;\nA960;HANGUL CHOSEONG TIKEUT-MIEUM;Lo;0;L;;;;;N;;;;;\nA961;HANGUL CHOSEONG TIKEUT-PIEUP;Lo;0;L;;;;;N;;;;;\nA962;HANGUL CHOSEONG TIKEUT-SIOS;Lo;0;L;;;;;N;;;;;\nA963;HANGUL CHOSEONG TIKEUT-CIEUC;Lo;0;L;;;;;N;;;;;\nA964;HANGUL CHOSEONG RIEUL-KIYEOK;Lo;0;L;;;;;N;;;;;\nA965;HANGUL CHOSEONG RIEUL-SSANGKIYEOK;Lo;0;L;;;;;N;;;;;\nA966;HANGUL CHOSEONG RIEUL-TIKEUT;Lo;0;L;;;;;N;;;;;\nA967;HANGUL CHOSEONG RIEUL-SSANGTIKEUT;Lo;0;L;;;;;N;;;;;\nA968;HANGUL CHOSEONG RIEUL-MIEUM;Lo;0;L;;;;;N;;;;;\nA969;HANGUL CHOSEONG RIEUL-PIEUP;Lo;0;L;;;;;N;;;;;\nA96A;HANGUL CHOSEONG RIEUL-SSANGPIEUP;Lo;0;L;;;;;N;;;;;\nA96B;HANGUL CHOSEONG RIEUL-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;\nA96C;HANGUL CHOSEONG RIEUL-SIOS;Lo;0;L;;;;;N;;;;;\nA96D;HANGUL CHOSEONG RIEUL-CIEUC;Lo;0;L;;;;;N;;;;;\nA96E;HANGUL CHOSEONG RIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;;\nA96F;HANGUL CHOSEONG MIEUM-KIYEOK;Lo;0;L;;;;;N;;;;;\nA970;HANGUL CHOSEONG MIEUM-TIKEUT;Lo;0;L;;;;;N;;;;;\nA971;HANGUL CHOSEONG MIEUM-SIOS;Lo;0;L;;;;;N;;;;;\nA972;HANGUL CHOSEONG PIEUP-SIOS-THIEUTH;Lo;0;L;;;;;N;;;;;\nA973;HANGUL CHOSEONG PIEUP-KHIEUKH;Lo;0;L;;;;;N;;;;;\nA974;HANGUL CHOSEONG PIEUP-HIEUH;Lo;0;L;;;;;N;;;;;\nA975;HANGUL CHOSEONG SSANGSIOS-PIEUP;Lo;0;L;;;;;N;;;;;\nA976;HANGUL CHOSEONG IEUNG-RIEUL;Lo;0;L;;;;;N;;;;;\nA977;HANGUL CHOSEONG IEUNG-HIEUH;Lo;0;L;;;;;N;;;;;\nA978;HANGUL CHOSEONG SSANGCIEUC-HIEUH;Lo;0;L;;;;;N;;;;;\nA979;HANGUL CHOSEONG SSANGTHIEUTH;Lo;0;L;;;;;N;;;;;\nA97A;HANGUL CHOSEONG PHIEUPH-HIEUH;Lo;0;L;;;;;N;;;;;\nA97B;HANGUL CHOSEONG HIEUH-SIOS;Lo;0;L;;;;;N;;;;;\nA97C;HANGUL CHOSEONG SSANGYEORINHIEUH;Lo;0;L;;;;;N;;;;;\nA980;JAVANESE SIGN PANYANGGA;Mn;0;NSM;;;;;N;;;;;\nA981;JAVANESE SIGN CECAK;Mn;0;NSM;;;;;N;;;;;\nA982;JAVANESE SIGN LAYAR;Mn;0;NSM;;;;;N;;;;;\nA983;JAVANESE SIGN WIGNYAN;Mc;0;L;;;;;N;;;;;\nA984;JAVANESE LETTER A;Lo;0;L;;;;;N;;;;;\nA985;JAVANESE LETTER I KAWI;Lo;0;L;;;;;N;;;;;\nA986;JAVANESE LETTER I;Lo;0;L;;;;;N;;;;;\nA987;JAVANESE LETTER II;Lo;0;L;;;;;N;;;;;\nA988;JAVANESE LETTER U;Lo;0;L;;;;;N;;;;;\nA989;JAVANESE LETTER PA CEREK;Lo;0;L;;;;;N;;;;;\nA98A;JAVANESE LETTER NGA LELET;Lo;0;L;;;;;N;;;;;\nA98B;JAVANESE LETTER NGA LELET RASWADI;Lo;0;L;;;;;N;;;;;\nA98C;JAVANESE LETTER E;Lo;0;L;;;;;N;;;;;\nA98D;JAVANESE LETTER AI;Lo;0;L;;;;;N;;;;;\nA98E;JAVANESE LETTER O;Lo;0;L;;;;;N;;;;;\nA98F;JAVANESE LETTER KA;Lo;0;L;;;;;N;;;;;\nA990;JAVANESE LETTER KA SASAK;Lo;0;L;;;;;N;;;;;\nA991;JAVANESE LETTER KA MURDA;Lo;0;L;;;;;N;;;;;\nA992;JAVANESE LETTER GA;Lo;0;L;;;;;N;;;;;\nA993;JAVANESE LETTER GA MURDA;Lo;0;L;;;;;N;;;;;\nA994;JAVANESE LETTER NGA;Lo;0;L;;;;;N;;;;;\nA995;JAVANESE LETTER CA;Lo;0;L;;;;;N;;;;;\nA996;JAVANESE LETTER CA MURDA;Lo;0;L;;;;;N;;;;;\nA997;JAVANESE LETTER JA;Lo;0;L;;;;;N;;;;;\nA998;JAVANESE LETTER NYA MURDA;Lo;0;L;;;;;N;;;;;\nA999;JAVANESE LETTER JA MAHAPRANA;Lo;0;L;;;;;N;;;;;\nA99A;JAVANESE LETTER NYA;Lo;0;L;;;;;N;;;;;\nA99B;JAVANESE LETTER TTA;Lo;0;L;;;;;N;;;;;\nA99C;JAVANESE LETTER TTA MAHAPRANA;Lo;0;L;;;;;N;;;;;\nA99D;JAVANESE LETTER DDA;Lo;0;L;;;;;N;;;;;\nA99E;JAVANESE LETTER DDA MAHAPRANA;Lo;0;L;;;;;N;;;;;\nA99F;JAVANESE LETTER NA MURDA;Lo;0;L;;;;;N;;;;;\nA9A0;JAVANESE LETTER TA;Lo;0;L;;;;;N;;;;;\nA9A1;JAVANESE LETTER TA MURDA;Lo;0;L;;;;;N;;;;;\nA9A2;JAVANESE LETTER DA;Lo;0;L;;;;;N;;;;;\nA9A3;JAVANESE LETTER DA MAHAPRANA;Lo;0;L;;;;;N;;;;;\nA9A4;JAVANESE LETTER NA;Lo;0;L;;;;;N;;;;;\nA9A5;JAVANESE LETTER PA;Lo;0;L;;;;;N;;;;;\nA9A6;JAVANESE LETTER PA MURDA;Lo;0;L;;;;;N;;;;;\nA9A7;JAVANESE LETTER BA;Lo;0;L;;;;;N;;;;;\nA9A8;JAVANESE LETTER BA MURDA;Lo;0;L;;;;;N;;;;;\nA9A9;JAVANESE LETTER MA;Lo;0;L;;;;;N;;;;;\nA9AA;JAVANESE LETTER YA;Lo;0;L;;;;;N;;;;;\nA9AB;JAVANESE LETTER RA;Lo;0;L;;;;;N;;;;;\nA9AC;JAVANESE LETTER RA AGUNG;Lo;0;L;;;;;N;;;;;\nA9AD;JAVANESE LETTER LA;Lo;0;L;;;;;N;;;;;\nA9AE;JAVANESE LETTER WA;Lo;0;L;;;;;N;;;;;\nA9AF;JAVANESE LETTER SA MURDA;Lo;0;L;;;;;N;;;;;\nA9B0;JAVANESE LETTER SA MAHAPRANA;Lo;0;L;;;;;N;;;;;\nA9B1;JAVANESE LETTER SA;Lo;0;L;;;;;N;;;;;\nA9B2;JAVANESE LETTER HA;Lo;0;L;;;;;N;;;;;\nA9B3;JAVANESE SIGN CECAK TELU;Mn;7;NSM;;;;;N;;;;;\nA9B4;JAVANESE VOWEL SIGN TARUNG;Mc;0;L;;;;;N;;;;;\nA9B5;JAVANESE VOWEL SIGN TOLONG;Mc;0;L;;;;;N;;;;;\nA9B6;JAVANESE VOWEL SIGN WULU;Mn;0;NSM;;;;;N;;;;;\nA9B7;JAVANESE VOWEL SIGN WULU MELIK;Mn;0;NSM;;;;;N;;;;;\nA9B8;JAVANESE VOWEL SIGN SUKU;Mn;0;NSM;;;;;N;;;;;\nA9B9;JAVANESE VOWEL SIGN SUKU MENDUT;Mn;0;NSM;;;;;N;;;;;\nA9BA;JAVANESE VOWEL SIGN TALING;Mc;0;L;;;;;N;;;;;\nA9BB;JAVANESE VOWEL SIGN DIRGA MURE;Mc;0;L;;;;;N;;;;;\nA9BC;JAVANESE VOWEL SIGN PEPET;Mn;0;NSM;;;;;N;;;;;\nA9BD;JAVANESE CONSONANT SIGN KERET;Mn;0;NSM;;;;;N;;;;;\nA9BE;JAVANESE CONSONANT SIGN PENGKAL;Mc;0;L;;;;;N;;;;;\nA9BF;JAVANESE CONSONANT SIGN CAKRA;Mc;0;L;;;;;N;;;;;\nA9C0;JAVANESE PANGKON;Mc;9;L;;;;;N;;;;;\nA9C1;JAVANESE LEFT RERENGGAN;Po;0;L;;;;;N;;;;;\nA9C2;JAVANESE RIGHT RERENGGAN;Po;0;L;;;;;N;;;;;\nA9C3;JAVANESE PADA ANDAP;Po;0;L;;;;;N;;;;;\nA9C4;JAVANESE PADA MADYA;Po;0;L;;;;;N;;;;;\nA9C5;JAVANESE PADA LUHUR;Po;0;L;;;;;N;;;;;\nA9C6;JAVANESE PADA WINDU;Po;0;L;;;;;N;;;;;\nA9C7;JAVANESE PADA PANGKAT;Po;0;L;;;;;N;;;;;\nA9C8;JAVANESE PADA LINGSA;Po;0;L;;;;;N;;;;;\nA9C9;JAVANESE PADA LUNGSI;Po;0;L;;;;;N;;;;;\nA9CA;JAVANESE PADA ADEG;Po;0;L;;;;;N;;;;;\nA9CB;JAVANESE PADA ADEG ADEG;Po;0;L;;;;;N;;;;;\nA9CC;JAVANESE PADA PISELEH;Po;0;L;;;;;N;;;;;\nA9CD;JAVANESE TURNED PADA PISELEH;Po;0;L;;;;;N;;;;;\nA9CF;JAVANESE PANGRANGKEP;Lm;0;L;;;;;N;;;;;\nA9D0;JAVANESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\nA9D1;JAVANESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\nA9D2;JAVANESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\nA9D3;JAVANESE DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\nA9D4;JAVANESE DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\nA9D5;JAVANESE DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\nA9D6;JAVANESE DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\nA9D7;JAVANESE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\nA9D8;JAVANESE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\nA9D9;JAVANESE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\nA9DE;JAVANESE PADA TIRTA TUMETES;Po;0;L;;;;;N;;;;;\nA9DF;JAVANESE PADA ISEN-ISEN;Po;0;L;;;;;N;;;;;\nA9E0;MYANMAR LETTER SHAN GHA;Lo;0;L;;;;;N;;;;;\nA9E1;MYANMAR LETTER SHAN CHA;Lo;0;L;;;;;N;;;;;\nA9E2;MYANMAR LETTER SHAN JHA;Lo;0;L;;;;;N;;;;;\nA9E3;MYANMAR LETTER SHAN NNA;Lo;0;L;;;;;N;;;;;\nA9E4;MYANMAR LETTER SHAN BHA;Lo;0;L;;;;;N;;;;;\nA9E5;MYANMAR SIGN SHAN SAW;Mn;0;NSM;;;;;N;;;;;\nA9E6;MYANMAR MODIFIER LETTER SHAN REDUPLICATION;Lm;0;L;;;;;N;;;;;\nA9E7;MYANMAR LETTER TAI LAING NYA;Lo;0;L;;;;;N;;;;;\nA9E8;MYANMAR LETTER TAI LAING FA;Lo;0;L;;;;;N;;;;;\nA9E9;MYANMAR LETTER TAI LAING GA;Lo;0;L;;;;;N;;;;;\nA9EA;MYANMAR LETTER TAI LAING GHA;Lo;0;L;;;;;N;;;;;\nA9EB;MYANMAR LETTER TAI LAING JA;Lo;0;L;;;;;N;;;;;\nA9EC;MYANMAR LETTER TAI LAING JHA;Lo;0;L;;;;;N;;;;;\nA9ED;MYANMAR LETTER TAI LAING DDA;Lo;0;L;;;;;N;;;;;\nA9EE;MYANMAR LETTER TAI LAING DDHA;Lo;0;L;;;;;N;;;;;\nA9EF;MYANMAR LETTER TAI LAING NNA;Lo;0;L;;;;;N;;;;;\nA9F0;MYANMAR TAI LAING DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\nA9F1;MYANMAR TAI LAING DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\nA9F2;MYANMAR TAI LAING DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\nA9F3;MYANMAR TAI LAING DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\nA9F4;MYANMAR TAI LAING DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\nA9F5;MYANMAR TAI LAING DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\nA9F6;MYANMAR TAI LAING DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\nA9F7;MYANMAR TAI LAING DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\nA9F8;MYANMAR TAI LAING DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\nA9F9;MYANMAR TAI LAING DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\nA9FA;MYANMAR LETTER TAI LAING LLA;Lo;0;L;;;;;N;;;;;\nA9FB;MYANMAR LETTER TAI LAING DA;Lo;0;L;;;;;N;;;;;\nA9FC;MYANMAR LETTER TAI LAING DHA;Lo;0;L;;;;;N;;;;;\nA9FD;MYANMAR LETTER TAI LAING BA;Lo;0;L;;;;;N;;;;;\nA9FE;MYANMAR LETTER TAI LAING BHA;Lo;0;L;;;;;N;;;;;\nAA00;CHAM LETTER A;Lo;0;L;;;;;N;;;;;\nAA01;CHAM LETTER I;Lo;0;L;;;;;N;;;;;\nAA02;CHAM LETTER U;Lo;0;L;;;;;N;;;;;\nAA03;CHAM LETTER E;Lo;0;L;;;;;N;;;;;\nAA04;CHAM LETTER AI;Lo;0;L;;;;;N;;;;;\nAA05;CHAM LETTER O;Lo;0;L;;;;;N;;;;;\nAA06;CHAM LETTER KA;Lo;0;L;;;;;N;;;;;\nAA07;CHAM LETTER KHA;Lo;0;L;;;;;N;;;;;\nAA08;CHAM LETTER GA;Lo;0;L;;;;;N;;;;;\nAA09;CHAM LETTER GHA;Lo;0;L;;;;;N;;;;;\nAA0A;CHAM LETTER NGUE;Lo;0;L;;;;;N;;;;;\nAA0B;CHAM LETTER NGA;Lo;0;L;;;;;N;;;;;\nAA0C;CHAM LETTER CHA;Lo;0;L;;;;;N;;;;;\nAA0D;CHAM LETTER CHHA;Lo;0;L;;;;;N;;;;;\nAA0E;CHAM LETTER JA;Lo;0;L;;;;;N;;;;;\nAA0F;CHAM LETTER JHA;Lo;0;L;;;;;N;;;;;\nAA10;CHAM LETTER NHUE;Lo;0;L;;;;;N;;;;;\nAA11;CHAM LETTER NHA;Lo;0;L;;;;;N;;;;;\nAA12;CHAM LETTER NHJA;Lo;0;L;;;;;N;;;;;\nAA13;CHAM LETTER TA;Lo;0;L;;;;;N;;;;;\nAA14;CHAM LETTER THA;Lo;0;L;;;;;N;;;;;\nAA15;CHAM LETTER DA;Lo;0;L;;;;;N;;;;;\nAA16;CHAM LETTER DHA;Lo;0;L;;;;;N;;;;;\nAA17;CHAM LETTER NUE;Lo;0;L;;;;;N;;;;;\nAA18;CHAM LETTER NA;Lo;0;L;;;;;N;;;;;\nAA19;CHAM LETTER DDA;Lo;0;L;;;;;N;;;;;\nAA1A;CHAM LETTER PA;Lo;0;L;;;;;N;;;;;\nAA1B;CHAM LETTER PPA;Lo;0;L;;;;;N;;;;;\nAA1C;CHAM LETTER PHA;Lo;0;L;;;;;N;;;;;\nAA1D;CHAM LETTER BA;Lo;0;L;;;;;N;;;;;\nAA1E;CHAM LETTER BHA;Lo;0;L;;;;;N;;;;;\nAA1F;CHAM LETTER MUE;Lo;0;L;;;;;N;;;;;\nAA20;CHAM LETTER MA;Lo;0;L;;;;;N;;;;;\nAA21;CHAM LETTER BBA;Lo;0;L;;;;;N;;;;;\nAA22;CHAM LETTER YA;Lo;0;L;;;;;N;;;;;\nAA23;CHAM LETTER RA;Lo;0;L;;;;;N;;;;;\nAA24;CHAM LETTER LA;Lo;0;L;;;;;N;;;;;\nAA25;CHAM LETTER VA;Lo;0;L;;;;;N;;;;;\nAA26;CHAM LETTER SSA;Lo;0;L;;;;;N;;;;;\nAA27;CHAM LETTER SA;Lo;0;L;;;;;N;;;;;\nAA28;CHAM LETTER HA;Lo;0;L;;;;;N;;;;;\nAA29;CHAM VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;\nAA2A;CHAM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\nAA2B;CHAM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;\nAA2C;CHAM VOWEL SIGN EI;Mn;0;NSM;;;;;N;;;;;\nAA2D;CHAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\nAA2E;CHAM VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;;\nAA2F;CHAM VOWEL SIGN O;Mc;0;L;;;;;N;;;;;\nAA30;CHAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;\nAA31;CHAM VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;\nAA32;CHAM VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;\nAA33;CHAM CONSONANT SIGN YA;Mc;0;L;;;;;N;;;;;\nAA34;CHAM CONSONANT SIGN RA;Mc;0;L;;;;;N;;;;;\nAA35;CHAM CONSONANT SIGN LA;Mn;0;NSM;;;;;N;;;;;\nAA36;CHAM CONSONANT SIGN WA;Mn;0;NSM;;;;;N;;;;;\nAA40;CHAM LETTER FINAL K;Lo;0;L;;;;;N;;;;;\nAA41;CHAM LETTER FINAL G;Lo;0;L;;;;;N;;;;;\nAA42;CHAM LETTER FINAL NG;Lo;0;L;;;;;N;;;;;\nAA43;CHAM CONSONANT SIGN FINAL NG;Mn;0;NSM;;;;;N;;;;;\nAA44;CHAM LETTER FINAL CH;Lo;0;L;;;;;N;;;;;\nAA45;CHAM LETTER FINAL T;Lo;0;L;;;;;N;;;;;\nAA46;CHAM LETTER FINAL N;Lo;0;L;;;;;N;;;;;\nAA47;CHAM LETTER FINAL P;Lo;0;L;;;;;N;;;;;\nAA48;CHAM LETTER FINAL Y;Lo;0;L;;;;;N;;;;;\nAA49;CHAM LETTER FINAL R;Lo;0;L;;;;;N;;;;;\nAA4A;CHAM LETTER FINAL L;Lo;0;L;;;;;N;;;;;\nAA4B;CHAM LETTER FINAL SS;Lo;0;L;;;;;N;;;;;\nAA4C;CHAM CONSONANT SIGN FINAL M;Mn;0;NSM;;;;;N;;;;;\nAA4D;CHAM CONSONANT SIGN FINAL H;Mc;0;L;;;;;N;;;;;\nAA50;CHAM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\nAA51;CHAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\nAA52;CHAM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\nAA53;CHAM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\nAA54;CHAM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\nAA55;CHAM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\nAA56;CHAM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\nAA57;CHAM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\nAA58;CHAM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\nAA59;CHAM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\nAA5C;CHAM PUNCTUATION SPIRAL;Po;0;L;;;;;N;;;;;\nAA5D;CHAM PUNCTUATION DANDA;Po;0;L;;;;;N;;;;;\nAA5E;CHAM PUNCTUATION DOUBLE DANDA;Po;0;L;;;;;N;;;;;\nAA5F;CHAM PUNCTUATION TRIPLE DANDA;Po;0;L;;;;;N;;;;;\nAA60;MYANMAR LETTER KHAMTI GA;Lo;0;L;;;;;N;;;;;\nAA61;MYANMAR LETTER KHAMTI CA;Lo;0;L;;;;;N;;;;;\nAA62;MYANMAR LETTER KHAMTI CHA;Lo;0;L;;;;;N;;;;;\nAA63;MYANMAR LETTER KHAMTI JA;Lo;0;L;;;;;N;;;;;\nAA64;MYANMAR LETTER KHAMTI JHA;Lo;0;L;;;;;N;;;;;\nAA65;MYANMAR LETTER KHAMTI NYA;Lo;0;L;;;;;N;;;;;\nAA66;MYANMAR LETTER KHAMTI TTA;Lo;0;L;;;;;N;;;;;\nAA67;MYANMAR LETTER KHAMTI TTHA;Lo;0;L;;;;;N;;;;;\nAA68;MYANMAR LETTER KHAMTI DDA;Lo;0;L;;;;;N;;;;;\nAA69;MYANMAR LETTER KHAMTI DDHA;Lo;0;L;;;;;N;;;;;\nAA6A;MYANMAR LETTER KHAMTI DHA;Lo;0;L;;;;;N;;;;;\nAA6B;MYANMAR LETTER KHAMTI NA;Lo;0;L;;;;;N;;;;;\nAA6C;MYANMAR LETTER KHAMTI SA;Lo;0;L;;;;;N;;;;;\nAA6D;MYANMAR LETTER KHAMTI HA;Lo;0;L;;;;;N;;;;;\nAA6E;MYANMAR LETTER KHAMTI HHA;Lo;0;L;;;;;N;;;;;\nAA6F;MYANMAR LETTER KHAMTI FA;Lo;0;L;;;;;N;;;;;\nAA70;MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION;Lm;0;L;;;;;N;;;;;\nAA71;MYANMAR LETTER KHAMTI XA;Lo;0;L;;;;;N;;;;;\nAA72;MYANMAR LETTER KHAMTI ZA;Lo;0;L;;;;;N;;;;;\nAA73;MYANMAR LETTER KHAMTI RA;Lo;0;L;;;;;N;;;;;\nAA74;MYANMAR LOGOGRAM KHAMTI OAY;Lo;0;L;;;;;N;;;;;\nAA75;MYANMAR LOGOGRAM KHAMTI QN;Lo;0;L;;;;;N;;;;;\nAA76;MYANMAR LOGOGRAM KHAMTI HM;Lo;0;L;;;;;N;;;;;\nAA77;MYANMAR SYMBOL AITON EXCLAMATION;So;0;L;;;;;N;;;;;\nAA78;MYANMAR SYMBOL AITON ONE;So;0;L;;;;;N;;;;;\nAA79;MYANMAR SYMBOL AITON TWO;So;0;L;;;;;N;;;;;\nAA7A;MYANMAR LETTER AITON RA;Lo;0;L;;;;;N;;;;;\nAA7B;MYANMAR SIGN PAO KAREN TONE;Mc;0;L;;;;;N;;;;;\nAA7C;MYANMAR SIGN TAI LAING TONE-2;Mn;0;NSM;;;;;N;;;;;\nAA7D;MYANMAR SIGN TAI LAING TONE-5;Mc;0;L;;;;;N;;;;;\nAA7E;MYANMAR LETTER SHWE PALAUNG CHA;Lo;0;L;;;;;N;;;;;\nAA7F;MYANMAR LETTER SHWE PALAUNG SHA;Lo;0;L;;;;;N;;;;;\nAA80;TAI VIET LETTER LOW KO;Lo;0;L;;;;;N;;;;;\nAA81;TAI VIET LETTER HIGH KO;Lo;0;L;;;;;N;;;;;\nAA82;TAI VIET LETTER LOW KHO;Lo;0;L;;;;;N;;;;;\nAA83;TAI VIET LETTER HIGH KHO;Lo;0;L;;;;;N;;;;;\nAA84;TAI VIET LETTER LOW KHHO;Lo;0;L;;;;;N;;;;;\nAA85;TAI VIET LETTER HIGH KHHO;Lo;0;L;;;;;N;;;;;\nAA86;TAI VIET LETTER LOW GO;Lo;0;L;;;;;N;;;;;\nAA87;TAI VIET LETTER HIGH GO;Lo;0;L;;;;;N;;;;;\nAA88;TAI VIET LETTER LOW NGO;Lo;0;L;;;;;N;;;;;\nAA89;TAI VIET LETTER HIGH NGO;Lo;0;L;;;;;N;;;;;\nAA8A;TAI VIET LETTER LOW CO;Lo;0;L;;;;;N;;;;;\nAA8B;TAI VIET LETTER HIGH CO;Lo;0;L;;;;;N;;;;;\nAA8C;TAI VIET LETTER LOW CHO;Lo;0;L;;;;;N;;;;;\nAA8D;TAI VIET LETTER HIGH CHO;Lo;0;L;;;;;N;;;;;\nAA8E;TAI VIET LETTER LOW SO;Lo;0;L;;;;;N;;;;;\nAA8F;TAI VIET LETTER HIGH SO;Lo;0;L;;;;;N;;;;;\nAA90;TAI VIET LETTER LOW NYO;Lo;0;L;;;;;N;;;;;\nAA91;TAI VIET LETTER HIGH NYO;Lo;0;L;;;;;N;;;;;\nAA92;TAI VIET LETTER LOW DO;Lo;0;L;;;;;N;;;;;\nAA93;TAI VIET LETTER HIGH DO;Lo;0;L;;;;;N;;;;;\nAA94;TAI VIET LETTER LOW TO;Lo;0;L;;;;;N;;;;;\nAA95;TAI VIET LETTER HIGH TO;Lo;0;L;;;;;N;;;;;\nAA96;TAI VIET LETTER LOW THO;Lo;0;L;;;;;N;;;;;\nAA97;TAI VIET LETTER HIGH THO;Lo;0;L;;;;;N;;;;;\nAA98;TAI VIET LETTER LOW NO;Lo;0;L;;;;;N;;;;;\nAA99;TAI VIET LETTER HIGH NO;Lo;0;L;;;;;N;;;;;\nAA9A;TAI VIET LETTER LOW BO;Lo;0;L;;;;;N;;;;;\nAA9B;TAI VIET LETTER HIGH BO;Lo;0;L;;;;;N;;;;;\nAA9C;TAI VIET LETTER LOW PO;Lo;0;L;;;;;N;;;;;\nAA9D;TAI VIET LETTER HIGH PO;Lo;0;L;;;;;N;;;;;\nAA9E;TAI VIET LETTER LOW PHO;Lo;0;L;;;;;N;;;;;\nAA9F;TAI VIET LETTER HIGH PHO;Lo;0;L;;;;;N;;;;;\nAAA0;TAI VIET LETTER LOW FO;Lo;0;L;;;;;N;;;;;\nAAA1;TAI VIET LETTER HIGH FO;Lo;0;L;;;;;N;;;;;\nAAA2;TAI VIET LETTER LOW MO;Lo;0;L;;;;;N;;;;;\nAAA3;TAI VIET LETTER HIGH MO;Lo;0;L;;;;;N;;;;;\nAAA4;TAI VIET LETTER LOW YO;Lo;0;L;;;;;N;;;;;\nAAA5;TAI VIET LETTER HIGH YO;Lo;0;L;;;;;N;;;;;\nAAA6;TAI VIET LETTER LOW RO;Lo;0;L;;;;;N;;;;;\nAAA7;TAI VIET LETTER HIGH RO;Lo;0;L;;;;;N;;;;;\nAAA8;TAI VIET LETTER LOW LO;Lo;0;L;;;;;N;;;;;\nAAA9;TAI VIET LETTER HIGH LO;Lo;0;L;;;;;N;;;;;\nAAAA;TAI VIET LETTER LOW VO;Lo;0;L;;;;;N;;;;;\nAAAB;TAI VIET LETTER HIGH VO;Lo;0;L;;;;;N;;;;;\nAAAC;TAI VIET LETTER LOW HO;Lo;0;L;;;;;N;;;;;\nAAAD;TAI VIET LETTER HIGH HO;Lo;0;L;;;;;N;;;;;\nAAAE;TAI VIET LETTER LOW O;Lo;0;L;;;;;N;;;;;\nAAAF;TAI VIET LETTER HIGH O;Lo;0;L;;;;;N;;;;;\nAAB0;TAI VIET MAI KANG;Mn;230;NSM;;;;;N;;;;;\nAAB1;TAI VIET VOWEL AA;Lo;0;L;;;;;N;;;;;\nAAB2;TAI VIET VOWEL I;Mn;230;NSM;;;;;N;;;;;\nAAB3;TAI VIET VOWEL UE;Mn;230;NSM;;;;;N;;;;;\nAAB4;TAI VIET VOWEL U;Mn;220;NSM;;;;;N;;;;;\nAAB5;TAI VIET VOWEL E;Lo;0;L;;;;;N;;;;;\nAAB6;TAI VIET VOWEL O;Lo;0;L;;;;;N;;;;;\nAAB7;TAI VIET MAI KHIT;Mn;230;NSM;;;;;N;;;;;\nAAB8;TAI VIET VOWEL IA;Mn;230;NSM;;;;;N;;;;;\nAAB9;TAI VIET VOWEL UEA;Lo;0;L;;;;;N;;;;;\nAABA;TAI VIET VOWEL UA;Lo;0;L;;;;;N;;;;;\nAABB;TAI VIET VOWEL AUE;Lo;0;L;;;;;N;;;;;\nAABC;TAI VIET VOWEL AY;Lo;0;L;;;;;N;;;;;\nAABD;TAI VIET VOWEL AN;Lo;0;L;;;;;N;;;;;\nAABE;TAI VIET VOWEL AM;Mn;230;NSM;;;;;N;;;;;\nAABF;TAI VIET TONE MAI EK;Mn;230;NSM;;;;;N;;;;;\nAAC0;TAI VIET TONE MAI NUENG;Lo;0;L;;;;;N;;;;;\nAAC1;TAI VIET TONE MAI THO;Mn;230;NSM;;;;;N;;;;;\nAAC2;TAI VIET TONE MAI SONG;Lo;0;L;;;;;N;;;;;\nAADB;TAI VIET SYMBOL KON;Lo;0;L;;;;;N;;;;;\nAADC;TAI VIET SYMBOL NUENG;Lo;0;L;;;;;N;;;;;\nAADD;TAI VIET SYMBOL SAM;Lm;0;L;;;;;N;;;;;\nAADE;TAI VIET SYMBOL HO HOI;Po;0;L;;;;;N;;;;;\nAADF;TAI VIET SYMBOL KOI KOI;Po;0;L;;;;;N;;;;;\nAAE0;MEETEI MAYEK LETTER E;Lo;0;L;;;;;N;;;;;\nAAE1;MEETEI MAYEK LETTER O;Lo;0;L;;;;;N;;;;;\nAAE2;MEETEI MAYEK LETTER CHA;Lo;0;L;;;;;N;;;;;\nAAE3;MEETEI MAYEK LETTER NYA;Lo;0;L;;;;;N;;;;;\nAAE4;MEETEI MAYEK LETTER TTA;Lo;0;L;;;;;N;;;;;\nAAE5;MEETEI MAYEK LETTER TTHA;Lo;0;L;;;;;N;;;;;\nAAE6;MEETEI MAYEK LETTER DDA;Lo;0;L;;;;;N;;;;;\nAAE7;MEETEI MAYEK LETTER DDHA;Lo;0;L;;;;;N;;;;;\nAAE8;MEETEI MAYEK LETTER NNA;Lo;0;L;;;;;N;;;;;\nAAE9;MEETEI MAYEK LETTER SHA;Lo;0;L;;;;;N;;;;;\nAAEA;MEETEI MAYEK LETTER SSA;Lo;0;L;;;;;N;;;;;\nAAEB;MEETEI MAYEK VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\nAAEC;MEETEI MAYEK VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\nAAED;MEETEI MAYEK VOWEL SIGN AAI;Mn;0;NSM;;;;;N;;;;;\nAAEE;MEETEI MAYEK VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;\nAAEF;MEETEI MAYEK VOWEL SIGN AAU;Mc;0;L;;;;;N;;;;;\nAAF0;MEETEI MAYEK CHEIKHAN;Po;0;L;;;;;N;;;;;\nAAF1;MEETEI MAYEK AHANG KHUDAM;Po;0;L;;;;;N;;;;;\nAAF2;MEETEI MAYEK ANJI;Lo;0;L;;;;;N;;;;;\nAAF3;MEETEI MAYEK SYLLABLE REPETITION MARK;Lm;0;L;;;;;N;;;;;\nAAF4;MEETEI MAYEK WORD REPETITION MARK;Lm;0;L;;;;;N;;;;;\nAAF5;MEETEI MAYEK VOWEL SIGN VISARGA;Mc;0;L;;;;;N;;;;;\nAAF6;MEETEI MAYEK VIRAMA;Mn;9;NSM;;;;;N;;;;;\nAB01;ETHIOPIC SYLLABLE TTHU;Lo;0;L;;;;;N;;;;;\nAB02;ETHIOPIC SYLLABLE TTHI;Lo;0;L;;;;;N;;;;;\nAB03;ETHIOPIC SYLLABLE TTHAA;Lo;0;L;;;;;N;;;;;\nAB04;ETHIOPIC SYLLABLE TTHEE;Lo;0;L;;;;;N;;;;;\nAB05;ETHIOPIC SYLLABLE TTHE;Lo;0;L;;;;;N;;;;;\nAB06;ETHIOPIC SYLLABLE TTHO;Lo;0;L;;;;;N;;;;;\nAB09;ETHIOPIC SYLLABLE DDHU;Lo;0;L;;;;;N;;;;;\nAB0A;ETHIOPIC SYLLABLE DDHI;Lo;0;L;;;;;N;;;;;\nAB0B;ETHIOPIC SYLLABLE DDHAA;Lo;0;L;;;;;N;;;;;\nAB0C;ETHIOPIC SYLLABLE DDHEE;Lo;0;L;;;;;N;;;;;\nAB0D;ETHIOPIC SYLLABLE DDHE;Lo;0;L;;;;;N;;;;;\nAB0E;ETHIOPIC SYLLABLE DDHO;Lo;0;L;;;;;N;;;;;\nAB11;ETHIOPIC SYLLABLE DZU;Lo;0;L;;;;;N;;;;;\nAB12;ETHIOPIC SYLLABLE DZI;Lo;0;L;;;;;N;;;;;\nAB13;ETHIOPIC SYLLABLE DZAA;Lo;0;L;;;;;N;;;;;\nAB14;ETHIOPIC SYLLABLE DZEE;Lo;0;L;;;;;N;;;;;\nAB15;ETHIOPIC SYLLABLE DZE;Lo;0;L;;;;;N;;;;;\nAB16;ETHIOPIC SYLLABLE DZO;Lo;0;L;;;;;N;;;;;\nAB20;ETHIOPIC SYLLABLE CCHHA;Lo;0;L;;;;;N;;;;;\nAB21;ETHIOPIC SYLLABLE CCHHU;Lo;0;L;;;;;N;;;;;\nAB22;ETHIOPIC SYLLABLE CCHHI;Lo;0;L;;;;;N;;;;;\nAB23;ETHIOPIC SYLLABLE CCHHAA;Lo;0;L;;;;;N;;;;;\nAB24;ETHIOPIC SYLLABLE CCHHEE;Lo;0;L;;;;;N;;;;;\nAB25;ETHIOPIC SYLLABLE CCHHE;Lo;0;L;;;;;N;;;;;\nAB26;ETHIOPIC SYLLABLE CCHHO;Lo;0;L;;;;;N;;;;;\nAB28;ETHIOPIC SYLLABLE BBA;Lo;0;L;;;;;N;;;;;\nAB29;ETHIOPIC SYLLABLE BBU;Lo;0;L;;;;;N;;;;;\nAB2A;ETHIOPIC SYLLABLE BBI;Lo;0;L;;;;;N;;;;;\nAB2B;ETHIOPIC SYLLABLE BBAA;Lo;0;L;;;;;N;;;;;\nAB2C;ETHIOPIC SYLLABLE BBEE;Lo;0;L;;;;;N;;;;;\nAB2D;ETHIOPIC SYLLABLE BBE;Lo;0;L;;;;;N;;;;;\nAB2E;ETHIOPIC SYLLABLE BBO;Lo;0;L;;;;;N;;;;;\nAB30;LATIN SMALL LETTER BARRED ALPHA;Ll;0;L;;;;;N;;;;;\nAB31;LATIN SMALL LETTER A REVERSED-SCHWA;Ll;0;L;;;;;N;;;;;\nAB32;LATIN SMALL LETTER BLACKLETTER E;Ll;0;L;;;;;N;;;;;\nAB33;LATIN SMALL LETTER BARRED E;Ll;0;L;;;;;N;;;;;\nAB34;LATIN SMALL LETTER E WITH FLOURISH;Ll;0;L;;;;;N;;;;;\nAB35;LATIN SMALL LETTER LENIS F;Ll;0;L;;;;;N;;;;;\nAB36;LATIN SMALL LETTER SCRIPT G WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;\nAB37;LATIN SMALL LETTER L WITH INVERTED LAZY S;Ll;0;L;;;;;N;;;;;\nAB38;LATIN SMALL LETTER L WITH DOUBLE MIDDLE TILDE;Ll;0;L;;;;;N;;;;;\nAB39;LATIN SMALL LETTER L WITH MIDDLE RING;Ll;0;L;;;;;N;;;;;\nAB3A;LATIN SMALL LETTER M WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;\nAB3B;LATIN SMALL LETTER N WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;\nAB3C;LATIN SMALL LETTER ENG WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;\nAB3D;LATIN SMALL LETTER BLACKLETTER O;Ll;0;L;;;;;N;;;;;\nAB3E;LATIN SMALL LETTER BLACKLETTER O WITH STROKE;Ll;0;L;;;;;N;;;;;\nAB3F;LATIN SMALL LETTER OPEN O WITH STROKE;Ll;0;L;;;;;N;;;;;\nAB40;LATIN SMALL LETTER INVERTED OE;Ll;0;L;;;;;N;;;;;\nAB41;LATIN SMALL LETTER TURNED OE WITH STROKE;Ll;0;L;;;;;N;;;;;\nAB42;LATIN SMALL LETTER TURNED OE WITH HORIZONTAL STROKE;Ll;0;L;;;;;N;;;;;\nAB43;LATIN SMALL LETTER TURNED O OPEN-O;Ll;0;L;;;;;N;;;;;\nAB44;LATIN SMALL LETTER TURNED O OPEN-O WITH STROKE;Ll;0;L;;;;;N;;;;;\nAB45;LATIN SMALL LETTER STIRRUP R;Ll;0;L;;;;;N;;;;;\nAB46;LATIN LETTER SMALL CAPITAL R WITH RIGHT LEG;Ll;0;L;;;;;N;;;;;\nAB47;LATIN SMALL LETTER R WITHOUT HANDLE;Ll;0;L;;;;;N;;;;;\nAB48;LATIN SMALL LETTER DOUBLE R;Ll;0;L;;;;;N;;;;;\nAB49;LATIN SMALL LETTER R WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;\nAB4A;LATIN SMALL LETTER DOUBLE R WITH CROSSED-TAIL;Ll;0;L;;;;;N;;;;;\nAB4B;LATIN SMALL LETTER SCRIPT R;Ll;0;L;;;;;N;;;;;\nAB4C;LATIN SMALL LETTER SCRIPT R WITH RING;Ll;0;L;;;;;N;;;;;\nAB4D;LATIN SMALL LETTER BASELINE ESH;Ll;0;L;;;;;N;;;;;\nAB4E;LATIN SMALL LETTER U WITH SHORT RIGHT LEG;Ll;0;L;;;;;N;;;;;\nAB4F;LATIN SMALL LETTER U BAR WITH SHORT RIGHT LEG;Ll;0;L;;;;;N;;;;;\nAB50;LATIN SMALL LETTER UI;Ll;0;L;;;;;N;;;;;\nAB51;LATIN SMALL LETTER TURNED UI;Ll;0;L;;;;;N;;;;;\nAB52;LATIN SMALL LETTER U WITH LEFT HOOK;Ll;0;L;;;;;N;;;;;\nAB53;LATIN SMALL LETTER CHI;Ll;0;L;;;;;N;;;A7B3;;A7B3\nAB54;LATIN SMALL LETTER CHI WITH LOW RIGHT RING;Ll;0;L;;;;;N;;;;;\nAB55;LATIN SMALL LETTER CHI WITH LOW LEFT SERIF;Ll;0;L;;;;;N;;;;;\nAB56;LATIN SMALL LETTER X WITH LOW RIGHT RING;Ll;0;L;;;;;N;;;;;\nAB57;LATIN SMALL LETTER X WITH LONG LEFT LEG;Ll;0;L;;;;;N;;;;;\nAB58;LATIN SMALL LETTER X WITH LONG LEFT LEG AND LOW RIGHT RING;Ll;0;L;;;;;N;;;;;\nAB59;LATIN SMALL LETTER X WITH LONG LEFT LEG WITH SERIF;Ll;0;L;;;;;N;;;;;\nAB5A;LATIN SMALL LETTER Y WITH SHORT RIGHT LEG;Ll;0;L;;;;;N;;;;;\nAB5B;MODIFIER BREVE WITH INVERTED BREVE;Sk;0;L;;;;;N;;;;;\nAB5C;MODIFIER LETTER SMALL HENG;Lm;0;L;<super> A727;;;;N;;;;;\nAB5D;MODIFIER LETTER SMALL L WITH INVERTED LAZY S;Lm;0;L;<super> AB37;;;;N;;;;;\nAB5E;MODIFIER LETTER SMALL L WITH MIDDLE TILDE;Lm;0;L;<super> 026B;;;;N;;;;;\nAB5F;MODIFIER LETTER SMALL U WITH LEFT HOOK;Lm;0;L;<super> AB52;;;;N;;;;;\nAB60;LATIN SMALL LETTER SAKHA YAT;Ll;0;L;;;;;N;;;;;\nAB61;LATIN SMALL LETTER IOTIFIED E;Ll;0;L;;;;;N;;;;;\nAB62;LATIN SMALL LETTER OPEN OE;Ll;0;L;;;;;N;;;;;\nAB63;LATIN SMALL LETTER UO;Ll;0;L;;;;;N;;;;;\nAB64;LATIN SMALL LETTER INVERTED ALPHA;Ll;0;L;;;;;N;;;;;\nAB65;GREEK LETTER SMALL CAPITAL OMEGA;Ll;0;L;;;;;N;;;;;\nAB66;LATIN SMALL LETTER DZ DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;\nAB67;LATIN SMALL LETTER TS DIGRAPH WITH RETROFLEX HOOK;Ll;0;L;;;;;N;;;;;\nAB70;CHEROKEE SMALL LETTER A;Ll;0;L;;;;;N;;;13A0;;13A0\nAB71;CHEROKEE SMALL LETTER E;Ll;0;L;;;;;N;;;13A1;;13A1\nAB72;CHEROKEE SMALL LETTER I;Ll;0;L;;;;;N;;;13A2;;13A2\nAB73;CHEROKEE SMALL LETTER O;Ll;0;L;;;;;N;;;13A3;;13A3\nAB74;CHEROKEE SMALL LETTER U;Ll;0;L;;;;;N;;;13A4;;13A4\nAB75;CHEROKEE SMALL LETTER V;Ll;0;L;;;;;N;;;13A5;;13A5\nAB76;CHEROKEE SMALL LETTER GA;Ll;0;L;;;;;N;;;13A6;;13A6\nAB77;CHEROKEE SMALL LETTER KA;Ll;0;L;;;;;N;;;13A7;;13A7\nAB78;CHEROKEE SMALL LETTER GE;Ll;0;L;;;;;N;;;13A8;;13A8\nAB79;CHEROKEE SMALL LETTER GI;Ll;0;L;;;;;N;;;13A9;;13A9\nAB7A;CHEROKEE SMALL LETTER GO;Ll;0;L;;;;;N;;;13AA;;13AA\nAB7B;CHEROKEE SMALL LETTER GU;Ll;0;L;;;;;N;;;13AB;;13AB\nAB7C;CHEROKEE SMALL LETTER GV;Ll;0;L;;;;;N;;;13AC;;13AC\nAB7D;CHEROKEE SMALL LETTER HA;Ll;0;L;;;;;N;;;13AD;;13AD\nAB7E;CHEROKEE SMALL LETTER HE;Ll;0;L;;;;;N;;;13AE;;13AE\nAB7F;CHEROKEE SMALL LETTER HI;Ll;0;L;;;;;N;;;13AF;;13AF\nAB80;CHEROKEE SMALL LETTER HO;Ll;0;L;;;;;N;;;13B0;;13B0\nAB81;CHEROKEE SMALL LETTER HU;Ll;0;L;;;;;N;;;13B1;;13B1\nAB82;CHEROKEE SMALL LETTER HV;Ll;0;L;;;;;N;;;13B2;;13B2\nAB83;CHEROKEE SMALL LETTER LA;Ll;0;L;;;;;N;;;13B3;;13B3\nAB84;CHEROKEE SMALL LETTER LE;Ll;0;L;;;;;N;;;13B4;;13B4\nAB85;CHEROKEE SMALL LETTER LI;Ll;0;L;;;;;N;;;13B5;;13B5\nAB86;CHEROKEE SMALL LETTER LO;Ll;0;L;;;;;N;;;13B6;;13B6\nAB87;CHEROKEE SMALL LETTER LU;Ll;0;L;;;;;N;;;13B7;;13B7\nAB88;CHEROKEE SMALL LETTER LV;Ll;0;L;;;;;N;;;13B8;;13B8\nAB89;CHEROKEE SMALL LETTER MA;Ll;0;L;;;;;N;;;13B9;;13B9\nAB8A;CHEROKEE SMALL LETTER ME;Ll;0;L;;;;;N;;;13BA;;13BA\nAB8B;CHEROKEE SMALL LETTER MI;Ll;0;L;;;;;N;;;13BB;;13BB\nAB8C;CHEROKEE SMALL LETTER MO;Ll;0;L;;;;;N;;;13BC;;13BC\nAB8D;CHEROKEE SMALL LETTER MU;Ll;0;L;;;;;N;;;13BD;;13BD\nAB8E;CHEROKEE SMALL LETTER NA;Ll;0;L;;;;;N;;;13BE;;13BE\nAB8F;CHEROKEE SMALL LETTER HNA;Ll;0;L;;;;;N;;;13BF;;13BF\nAB90;CHEROKEE SMALL LETTER NAH;Ll;0;L;;;;;N;;;13C0;;13C0\nAB91;CHEROKEE SMALL LETTER NE;Ll;0;L;;;;;N;;;13C1;;13C1\nAB92;CHEROKEE SMALL LETTER NI;Ll;0;L;;;;;N;;;13C2;;13C2\nAB93;CHEROKEE SMALL LETTER NO;Ll;0;L;;;;;N;;;13C3;;13C3\nAB94;CHEROKEE SMALL LETTER NU;Ll;0;L;;;;;N;;;13C4;;13C4\nAB95;CHEROKEE SMALL LETTER NV;Ll;0;L;;;;;N;;;13C5;;13C5\nAB96;CHEROKEE SMALL LETTER QUA;Ll;0;L;;;;;N;;;13C6;;13C6\nAB97;CHEROKEE SMALL LETTER QUE;Ll;0;L;;;;;N;;;13C7;;13C7\nAB98;CHEROKEE SMALL LETTER QUI;Ll;0;L;;;;;N;;;13C8;;13C8\nAB99;CHEROKEE SMALL LETTER QUO;Ll;0;L;;;;;N;;;13C9;;13C9\nAB9A;CHEROKEE SMALL LETTER QUU;Ll;0;L;;;;;N;;;13CA;;13CA\nAB9B;CHEROKEE SMALL LETTER QUV;Ll;0;L;;;;;N;;;13CB;;13CB\nAB9C;CHEROKEE SMALL LETTER SA;Ll;0;L;;;;;N;;;13CC;;13CC\nAB9D;CHEROKEE SMALL LETTER S;Ll;0;L;;;;;N;;;13CD;;13CD\nAB9E;CHEROKEE SMALL LETTER SE;Ll;0;L;;;;;N;;;13CE;;13CE\nAB9F;CHEROKEE SMALL LETTER SI;Ll;0;L;;;;;N;;;13CF;;13CF\nABA0;CHEROKEE SMALL LETTER SO;Ll;0;L;;;;;N;;;13D0;;13D0\nABA1;CHEROKEE SMALL LETTER SU;Ll;0;L;;;;;N;;;13D1;;13D1\nABA2;CHEROKEE SMALL LETTER SV;Ll;0;L;;;;;N;;;13D2;;13D2\nABA3;CHEROKEE SMALL LETTER DA;Ll;0;L;;;;;N;;;13D3;;13D3\nABA4;CHEROKEE SMALL LETTER TA;Ll;0;L;;;;;N;;;13D4;;13D4\nABA5;CHEROKEE SMALL LETTER DE;Ll;0;L;;;;;N;;;13D5;;13D5\nABA6;CHEROKEE SMALL LETTER TE;Ll;0;L;;;;;N;;;13D6;;13D6\nABA7;CHEROKEE SMALL LETTER DI;Ll;0;L;;;;;N;;;13D7;;13D7\nABA8;CHEROKEE SMALL LETTER TI;Ll;0;L;;;;;N;;;13D8;;13D8\nABA9;CHEROKEE SMALL LETTER DO;Ll;0;L;;;;;N;;;13D9;;13D9\nABAA;CHEROKEE SMALL LETTER DU;Ll;0;L;;;;;N;;;13DA;;13DA\nABAB;CHEROKEE SMALL LETTER DV;Ll;0;L;;;;;N;;;13DB;;13DB\nABAC;CHEROKEE SMALL LETTER DLA;Ll;0;L;;;;;N;;;13DC;;13DC\nABAD;CHEROKEE SMALL LETTER TLA;Ll;0;L;;;;;N;;;13DD;;13DD\nABAE;CHEROKEE SMALL LETTER TLE;Ll;0;L;;;;;N;;;13DE;;13DE\nABAF;CHEROKEE SMALL LETTER TLI;Ll;0;L;;;;;N;;;13DF;;13DF\nABB0;CHEROKEE SMALL LETTER TLO;Ll;0;L;;;;;N;;;13E0;;13E0\nABB1;CHEROKEE SMALL LETTER TLU;Ll;0;L;;;;;N;;;13E1;;13E1\nABB2;CHEROKEE SMALL LETTER TLV;Ll;0;L;;;;;N;;;13E2;;13E2\nABB3;CHEROKEE SMALL LETTER TSA;Ll;0;L;;;;;N;;;13E3;;13E3\nABB4;CHEROKEE SMALL LETTER TSE;Ll;0;L;;;;;N;;;13E4;;13E4\nABB5;CHEROKEE SMALL LETTER TSI;Ll;0;L;;;;;N;;;13E5;;13E5\nABB6;CHEROKEE SMALL LETTER TSO;Ll;0;L;;;;;N;;;13E6;;13E6\nABB7;CHEROKEE SMALL LETTER TSU;Ll;0;L;;;;;N;;;13E7;;13E7\nABB8;CHEROKEE SMALL LETTER TSV;Ll;0;L;;;;;N;;;13E8;;13E8\nABB9;CHEROKEE SMALL LETTER WA;Ll;0;L;;;;;N;;;13E9;;13E9\nABBA;CHEROKEE SMALL LETTER WE;Ll;0;L;;;;;N;;;13EA;;13EA\nABBB;CHEROKEE SMALL LETTER WI;Ll;0;L;;;;;N;;;13EB;;13EB\nABBC;CHEROKEE SMALL LETTER WO;Ll;0;L;;;;;N;;;13EC;;13EC\nABBD;CHEROKEE SMALL LETTER WU;Ll;0;L;;;;;N;;;13ED;;13ED\nABBE;CHEROKEE SMALL LETTER WV;Ll;0;L;;;;;N;;;13EE;;13EE\nABBF;CHEROKEE SMALL LETTER YA;Ll;0;L;;;;;N;;;13EF;;13EF\nABC0;MEETEI MAYEK LETTER KOK;Lo;0;L;;;;;N;;;;;\nABC1;MEETEI MAYEK LETTER SAM;Lo;0;L;;;;;N;;;;;\nABC2;MEETEI MAYEK LETTER LAI;Lo;0;L;;;;;N;;;;;\nABC3;MEETEI MAYEK LETTER MIT;Lo;0;L;;;;;N;;;;;\nABC4;MEETEI MAYEK LETTER PA;Lo;0;L;;;;;N;;;;;\nABC5;MEETEI MAYEK LETTER NA;Lo;0;L;;;;;N;;;;;\nABC6;MEETEI MAYEK LETTER CHIL;Lo;0;L;;;;;N;;;;;\nABC7;MEETEI MAYEK LETTER TIL;Lo;0;L;;;;;N;;;;;\nABC8;MEETEI MAYEK LETTER KHOU;Lo;0;L;;;;;N;;;;;\nABC9;MEETEI MAYEK LETTER NGOU;Lo;0;L;;;;;N;;;;;\nABCA;MEETEI MAYEK LETTER THOU;Lo;0;L;;;;;N;;;;;\nABCB;MEETEI MAYEK LETTER WAI;Lo;0;L;;;;;N;;;;;\nABCC;MEETEI MAYEK LETTER YANG;Lo;0;L;;;;;N;;;;;\nABCD;MEETEI MAYEK LETTER HUK;Lo;0;L;;;;;N;;;;;\nABCE;MEETEI MAYEK LETTER UN;Lo;0;L;;;;;N;;;;;\nABCF;MEETEI MAYEK LETTER I;Lo;0;L;;;;;N;;;;;\nABD0;MEETEI MAYEK LETTER PHAM;Lo;0;L;;;;;N;;;;;\nABD1;MEETEI MAYEK LETTER ATIYA;Lo;0;L;;;;;N;;;;;\nABD2;MEETEI MAYEK LETTER GOK;Lo;0;L;;;;;N;;;;;\nABD3;MEETEI MAYEK LETTER JHAM;Lo;0;L;;;;;N;;;;;\nABD4;MEETEI MAYEK LETTER RAI;Lo;0;L;;;;;N;;;;;\nABD5;MEETEI MAYEK LETTER BA;Lo;0;L;;;;;N;;;;;\nABD6;MEETEI MAYEK LETTER JIL;Lo;0;L;;;;;N;;;;;\nABD7;MEETEI MAYEK LETTER DIL;Lo;0;L;;;;;N;;;;;\nABD8;MEETEI MAYEK LETTER GHOU;Lo;0;L;;;;;N;;;;;\nABD9;MEETEI MAYEK LETTER DHOU;Lo;0;L;;;;;N;;;;;\nABDA;MEETEI MAYEK LETTER BHAM;Lo;0;L;;;;;N;;;;;\nABDB;MEETEI MAYEK LETTER KOK LONSUM;Lo;0;L;;;;;N;;;;;\nABDC;MEETEI MAYEK LETTER LAI LONSUM;Lo;0;L;;;;;N;;;;;\nABDD;MEETEI MAYEK LETTER MIT LONSUM;Lo;0;L;;;;;N;;;;;\nABDE;MEETEI MAYEK LETTER PA LONSUM;Lo;0;L;;;;;N;;;;;\nABDF;MEETEI MAYEK LETTER NA LONSUM;Lo;0;L;;;;;N;;;;;\nABE0;MEETEI MAYEK LETTER TIL LONSUM;Lo;0;L;;;;;N;;;;;\nABE1;MEETEI MAYEK LETTER NGOU LONSUM;Lo;0;L;;;;;N;;;;;\nABE2;MEETEI MAYEK LETTER I LONSUM;Lo;0;L;;;;;N;;;;;\nABE3;MEETEI MAYEK VOWEL SIGN ONAP;Mc;0;L;;;;;N;;;;;\nABE4;MEETEI MAYEK VOWEL SIGN INAP;Mc;0;L;;;;;N;;;;;\nABE5;MEETEI MAYEK VOWEL SIGN ANAP;Mn;0;NSM;;;;;N;;;;;\nABE6;MEETEI MAYEK VOWEL SIGN YENAP;Mc;0;L;;;;;N;;;;;\nABE7;MEETEI MAYEK VOWEL SIGN SOUNAP;Mc;0;L;;;;;N;;;;;\nABE8;MEETEI MAYEK VOWEL SIGN UNAP;Mn;0;NSM;;;;;N;;;;;\nABE9;MEETEI MAYEK VOWEL SIGN CHEINAP;Mc;0;L;;;;;N;;;;;\nABEA;MEETEI MAYEK VOWEL SIGN NUNG;Mc;0;L;;;;;N;;;;;\nABEB;MEETEI MAYEK CHEIKHEI;Po;0;L;;;;;N;;;;;\nABEC;MEETEI MAYEK LUM IYEK;Mc;0;L;;;;;N;;;;;\nABED;MEETEI MAYEK APUN IYEK;Mn;9;NSM;;;;;N;;;;;\nABF0;MEETEI MAYEK DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\nABF1;MEETEI MAYEK DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\nABF2;MEETEI MAYEK DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\nABF3;MEETEI MAYEK DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\nABF4;MEETEI MAYEK DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\nABF5;MEETEI MAYEK DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\nABF6;MEETEI MAYEK DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\nABF7;MEETEI MAYEK DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\nABF8;MEETEI MAYEK DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\nABF9;MEETEI MAYEK DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\nAC00;<Hangul Syllable, First>;Lo;0;L;;;;;N;;;;;\nD7A3;<Hangul Syllable, Last>;Lo;0;L;;;;;N;;;;;\nD7B0;HANGUL JUNGSEONG O-YEO;Lo;0;L;;;;;N;;;;;\nD7B1;HANGUL JUNGSEONG O-O-I;Lo;0;L;;;;;N;;;;;\nD7B2;HANGUL JUNGSEONG YO-A;Lo;0;L;;;;;N;;;;;\nD7B3;HANGUL JUNGSEONG YO-AE;Lo;0;L;;;;;N;;;;;\nD7B4;HANGUL JUNGSEONG YO-EO;Lo;0;L;;;;;N;;;;;\nD7B5;HANGUL JUNGSEONG U-YEO;Lo;0;L;;;;;N;;;;;\nD7B6;HANGUL JUNGSEONG U-I-I;Lo;0;L;;;;;N;;;;;\nD7B7;HANGUL JUNGSEONG YU-AE;Lo;0;L;;;;;N;;;;;\nD7B8;HANGUL JUNGSEONG YU-O;Lo;0;L;;;;;N;;;;;\nD7B9;HANGUL JUNGSEONG EU-A;Lo;0;L;;;;;N;;;;;\nD7BA;HANGUL JUNGSEONG EU-EO;Lo;0;L;;;;;N;;;;;\nD7BB;HANGUL JUNGSEONG EU-E;Lo;0;L;;;;;N;;;;;\nD7BC;HANGUL JUNGSEONG EU-O;Lo;0;L;;;;;N;;;;;\nD7BD;HANGUL JUNGSEONG I-YA-O;Lo;0;L;;;;;N;;;;;\nD7BE;HANGUL JUNGSEONG I-YAE;Lo;0;L;;;;;N;;;;;\nD7BF;HANGUL JUNGSEONG I-YEO;Lo;0;L;;;;;N;;;;;\nD7C0;HANGUL JUNGSEONG I-YE;Lo;0;L;;;;;N;;;;;\nD7C1;HANGUL JUNGSEONG I-O-I;Lo;0;L;;;;;N;;;;;\nD7C2;HANGUL JUNGSEONG I-YO;Lo;0;L;;;;;N;;;;;\nD7C3;HANGUL JUNGSEONG I-YU;Lo;0;L;;;;;N;;;;;\nD7C4;HANGUL JUNGSEONG I-I;Lo;0;L;;;;;N;;;;;\nD7C5;HANGUL JUNGSEONG ARAEA-A;Lo;0;L;;;;;N;;;;;\nD7C6;HANGUL JUNGSEONG ARAEA-E;Lo;0;L;;;;;N;;;;;\nD7CB;HANGUL JONGSEONG NIEUN-RIEUL;Lo;0;L;;;;;N;;;;;\nD7CC;HANGUL JONGSEONG NIEUN-CHIEUCH;Lo;0;L;;;;;N;;;;;\nD7CD;HANGUL JONGSEONG SSANGTIKEUT;Lo;0;L;;;;;N;;;;;\nD7CE;HANGUL JONGSEONG SSANGTIKEUT-PIEUP;Lo;0;L;;;;;N;;;;;\nD7CF;HANGUL JONGSEONG TIKEUT-PIEUP;Lo;0;L;;;;;N;;;;;\nD7D0;HANGUL JONGSEONG TIKEUT-SIOS;Lo;0;L;;;;;N;;;;;\nD7D1;HANGUL JONGSEONG TIKEUT-SIOS-KIYEOK;Lo;0;L;;;;;N;;;;;\nD7D2;HANGUL JONGSEONG TIKEUT-CIEUC;Lo;0;L;;;;;N;;;;;\nD7D3;HANGUL JONGSEONG TIKEUT-CHIEUCH;Lo;0;L;;;;;N;;;;;\nD7D4;HANGUL JONGSEONG TIKEUT-THIEUTH;Lo;0;L;;;;;N;;;;;\nD7D5;HANGUL JONGSEONG RIEUL-SSANGKIYEOK;Lo;0;L;;;;;N;;;;;\nD7D6;HANGUL JONGSEONG RIEUL-KIYEOK-HIEUH;Lo;0;L;;;;;N;;;;;\nD7D7;HANGUL JONGSEONG SSANGRIEUL-KHIEUKH;Lo;0;L;;;;;N;;;;;\nD7D8;HANGUL JONGSEONG RIEUL-MIEUM-HIEUH;Lo;0;L;;;;;N;;;;;\nD7D9;HANGUL JONGSEONG RIEUL-PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;;\nD7DA;HANGUL JONGSEONG RIEUL-PIEUP-PHIEUPH;Lo;0;L;;;;;N;;;;;\nD7DB;HANGUL JONGSEONG RIEUL-YESIEUNG;Lo;0;L;;;;;N;;;;;\nD7DC;HANGUL JONGSEONG RIEUL-YEORINHIEUH-HIEUH;Lo;0;L;;;;;N;;;;;\nD7DD;HANGUL JONGSEONG KAPYEOUNRIEUL;Lo;0;L;;;;;N;;;;;\nD7DE;HANGUL JONGSEONG MIEUM-NIEUN;Lo;0;L;;;;;N;;;;;\nD7DF;HANGUL JONGSEONG MIEUM-SSANGNIEUN;Lo;0;L;;;;;N;;;;;\nD7E0;HANGUL JONGSEONG SSANGMIEUM;Lo;0;L;;;;;N;;;;;\nD7E1;HANGUL JONGSEONG MIEUM-PIEUP-SIOS;Lo;0;L;;;;;N;;;;;\nD7E2;HANGUL JONGSEONG MIEUM-CIEUC;Lo;0;L;;;;;N;;;;;\nD7E3;HANGUL JONGSEONG PIEUP-TIKEUT;Lo;0;L;;;;;N;;;;;\nD7E4;HANGUL JONGSEONG PIEUP-RIEUL-PHIEUPH;Lo;0;L;;;;;N;;;;;\nD7E5;HANGUL JONGSEONG PIEUP-MIEUM;Lo;0;L;;;;;N;;;;;\nD7E6;HANGUL JONGSEONG SSANGPIEUP;Lo;0;L;;;;;N;;;;;\nD7E7;HANGUL JONGSEONG PIEUP-SIOS-TIKEUT;Lo;0;L;;;;;N;;;;;\nD7E8;HANGUL JONGSEONG PIEUP-CIEUC;Lo;0;L;;;;;N;;;;;\nD7E9;HANGUL JONGSEONG PIEUP-CHIEUCH;Lo;0;L;;;;;N;;;;;\nD7EA;HANGUL JONGSEONG SIOS-MIEUM;Lo;0;L;;;;;N;;;;;\nD7EB;HANGUL JONGSEONG SIOS-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;\nD7EC;HANGUL JONGSEONG SSANGSIOS-KIYEOK;Lo;0;L;;;;;N;;;;;\nD7ED;HANGUL JONGSEONG SSANGSIOS-TIKEUT;Lo;0;L;;;;;N;;;;;\nD7EE;HANGUL JONGSEONG SIOS-PANSIOS;Lo;0;L;;;;;N;;;;;\nD7EF;HANGUL JONGSEONG SIOS-CIEUC;Lo;0;L;;;;;N;;;;;\nD7F0;HANGUL JONGSEONG SIOS-CHIEUCH;Lo;0;L;;;;;N;;;;;\nD7F1;HANGUL JONGSEONG SIOS-THIEUTH;Lo;0;L;;;;;N;;;;;\nD7F2;HANGUL JONGSEONG SIOS-HIEUH;Lo;0;L;;;;;N;;;;;\nD7F3;HANGUL JONGSEONG PANSIOS-PIEUP;Lo;0;L;;;;;N;;;;;\nD7F4;HANGUL JONGSEONG PANSIOS-KAPYEOUNPIEUP;Lo;0;L;;;;;N;;;;;\nD7F5;HANGUL JONGSEONG YESIEUNG-MIEUM;Lo;0;L;;;;;N;;;;;\nD7F6;HANGUL JONGSEONG YESIEUNG-HIEUH;Lo;0;L;;;;;N;;;;;\nD7F7;HANGUL JONGSEONG CIEUC-PIEUP;Lo;0;L;;;;;N;;;;;\nD7F8;HANGUL JONGSEONG CIEUC-SSANGPIEUP;Lo;0;L;;;;;N;;;;;\nD7F9;HANGUL JONGSEONG SSANGCIEUC;Lo;0;L;;;;;N;;;;;\nD7FA;HANGUL JONGSEONG PHIEUPH-SIOS;Lo;0;L;;;;;N;;;;;\nD7FB;HANGUL JONGSEONG PHIEUPH-THIEUTH;Lo;0;L;;;;;N;;;;;\nD800;<Non Private Use High Surrogate, First>;Cs;0;L;;;;;N;;;;;\nDB7F;<Non Private Use High Surrogate, Last>;Cs;0;L;;;;;N;;;;;\nDB80;<Private Use High Surrogate, First>;Cs;0;L;;;;;N;;;;;\nDBFF;<Private Use High Surrogate, Last>;Cs;0;L;;;;;N;;;;;\nDC00;<Low Surrogate, First>;Cs;0;L;;;;;N;;;;;\nDFFF;<Low Surrogate, Last>;Cs;0;L;;;;;N;;;;;\nE000;<Private Use, First>;Co;0;L;;;;;N;;;;;\nF8FF;<Private Use, Last>;Co;0;L;;;;;N;;;;;\nF900;CJK COMPATIBILITY IDEOGRAPH-F900;Lo;0;L;8C48;;;;N;;;;;\nF901;CJK COMPATIBILITY IDEOGRAPH-F901;Lo;0;L;66F4;;;;N;;;;;\nF902;CJK COMPATIBILITY IDEOGRAPH-F902;Lo;0;L;8ECA;;;;N;;;;;\nF903;CJK COMPATIBILITY IDEOGRAPH-F903;Lo;0;L;8CC8;;;;N;;;;;\nF904;CJK COMPATIBILITY IDEOGRAPH-F904;Lo;0;L;6ED1;;;;N;;;;;\nF905;CJK COMPATIBILITY IDEOGRAPH-F905;Lo;0;L;4E32;;;;N;;;;;\nF906;CJK COMPATIBILITY IDEOGRAPH-F906;Lo;0;L;53E5;;;;N;;;;;\nF907;CJK COMPATIBILITY IDEOGRAPH-F907;Lo;0;L;9F9C;;;;N;;;;;\nF908;CJK COMPATIBILITY IDEOGRAPH-F908;Lo;0;L;9F9C;;;;N;;;;;\nF909;CJK COMPATIBILITY IDEOGRAPH-F909;Lo;0;L;5951;;;;N;;;;;\nF90A;CJK COMPATIBILITY IDEOGRAPH-F90A;Lo;0;L;91D1;;;;N;;;;;\nF90B;CJK COMPATIBILITY IDEOGRAPH-F90B;Lo;0;L;5587;;;;N;;;;;\nF90C;CJK COMPATIBILITY IDEOGRAPH-F90C;Lo;0;L;5948;;;;N;;;;;\nF90D;CJK COMPATIBILITY IDEOGRAPH-F90D;Lo;0;L;61F6;;;;N;;;;;\nF90E;CJK COMPATIBILITY IDEOGRAPH-F90E;Lo;0;L;7669;;;;N;;;;;\nF90F;CJK COMPATIBILITY IDEOGRAPH-F90F;Lo;0;L;7F85;;;;N;;;;;\nF910;CJK COMPATIBILITY IDEOGRAPH-F910;Lo;0;L;863F;;;;N;;;;;\nF911;CJK COMPATIBILITY IDEOGRAPH-F911;Lo;0;L;87BA;;;;N;;;;;\nF912;CJK COMPATIBILITY IDEOGRAPH-F912;Lo;0;L;88F8;;;;N;;;;;\nF913;CJK COMPATIBILITY IDEOGRAPH-F913;Lo;0;L;908F;;;;N;;;;;\nF914;CJK COMPATIBILITY IDEOGRAPH-F914;Lo;0;L;6A02;;;;N;;;;;\nF915;CJK COMPATIBILITY IDEOGRAPH-F915;Lo;0;L;6D1B;;;;N;;;;;\nF916;CJK COMPATIBILITY IDEOGRAPH-F916;Lo;0;L;70D9;;;;N;;;;;\nF917;CJK COMPATIBILITY IDEOGRAPH-F917;Lo;0;L;73DE;;;;N;;;;;\nF918;CJK COMPATIBILITY IDEOGRAPH-F918;Lo;0;L;843D;;;;N;;;;;\nF919;CJK COMPATIBILITY IDEOGRAPH-F919;Lo;0;L;916A;;;;N;;;;;\nF91A;CJK COMPATIBILITY IDEOGRAPH-F91A;Lo;0;L;99F1;;;;N;;;;;\nF91B;CJK COMPATIBILITY IDEOGRAPH-F91B;Lo;0;L;4E82;;;;N;;;;;\nF91C;CJK COMPATIBILITY IDEOGRAPH-F91C;Lo;0;L;5375;;;;N;;;;;\nF91D;CJK COMPATIBILITY IDEOGRAPH-F91D;Lo;0;L;6B04;;;;N;;;;;\nF91E;CJK COMPATIBILITY IDEOGRAPH-F91E;Lo;0;L;721B;;;;N;;;;;\nF91F;CJK COMPATIBILITY IDEOGRAPH-F91F;Lo;0;L;862D;;;;N;;;;;\nF920;CJK COMPATIBILITY IDEOGRAPH-F920;Lo;0;L;9E1E;;;;N;;;;;\nF921;CJK COMPATIBILITY IDEOGRAPH-F921;Lo;0;L;5D50;;;;N;;;;;\nF922;CJK COMPATIBILITY IDEOGRAPH-F922;Lo;0;L;6FEB;;;;N;;;;;\nF923;CJK COMPATIBILITY IDEOGRAPH-F923;Lo;0;L;85CD;;;;N;;;;;\nF924;CJK COMPATIBILITY IDEOGRAPH-F924;Lo;0;L;8964;;;;N;;;;;\nF925;CJK COMPATIBILITY IDEOGRAPH-F925;Lo;0;L;62C9;;;;N;;;;;\nF926;CJK COMPATIBILITY IDEOGRAPH-F926;Lo;0;L;81D8;;;;N;;;;;\nF927;CJK COMPATIBILITY IDEOGRAPH-F927;Lo;0;L;881F;;;;N;;;;;\nF928;CJK COMPATIBILITY IDEOGRAPH-F928;Lo;0;L;5ECA;;;;N;;;;;\nF929;CJK COMPATIBILITY IDEOGRAPH-F929;Lo;0;L;6717;;;;N;;;;;\nF92A;CJK COMPATIBILITY IDEOGRAPH-F92A;Lo;0;L;6D6A;;;;N;;;;;\nF92B;CJK COMPATIBILITY IDEOGRAPH-F92B;Lo;0;L;72FC;;;;N;;;;;\nF92C;CJK COMPATIBILITY IDEOGRAPH-F92C;Lo;0;L;90CE;;;;N;;;;;\nF92D;CJK COMPATIBILITY IDEOGRAPH-F92D;Lo;0;L;4F86;;;;N;;;;;\nF92E;CJK COMPATIBILITY IDEOGRAPH-F92E;Lo;0;L;51B7;;;;N;;;;;\nF92F;CJK COMPATIBILITY IDEOGRAPH-F92F;Lo;0;L;52DE;;;;N;;;;;\nF930;CJK COMPATIBILITY IDEOGRAPH-F930;Lo;0;L;64C4;;;;N;;;;;\nF931;CJK COMPATIBILITY IDEOGRAPH-F931;Lo;0;L;6AD3;;;;N;;;;;\nF932;CJK COMPATIBILITY IDEOGRAPH-F932;Lo;0;L;7210;;;;N;;;;;\nF933;CJK COMPATIBILITY IDEOGRAPH-F933;Lo;0;L;76E7;;;;N;;;;;\nF934;CJK COMPATIBILITY IDEOGRAPH-F934;Lo;0;L;8001;;;;N;;;;;\nF935;CJK COMPATIBILITY IDEOGRAPH-F935;Lo;0;L;8606;;;;N;;;;;\nF936;CJK COMPATIBILITY IDEOGRAPH-F936;Lo;0;L;865C;;;;N;;;;;\nF937;CJK COMPATIBILITY IDEOGRAPH-F937;Lo;0;L;8DEF;;;;N;;;;;\nF938;CJK COMPATIBILITY IDEOGRAPH-F938;Lo;0;L;9732;;;;N;;;;;\nF939;CJK COMPATIBILITY IDEOGRAPH-F939;Lo;0;L;9B6F;;;;N;;;;;\nF93A;CJK COMPATIBILITY IDEOGRAPH-F93A;Lo;0;L;9DFA;;;;N;;;;;\nF93B;CJK COMPATIBILITY IDEOGRAPH-F93B;Lo;0;L;788C;;;;N;;;;;\nF93C;CJK COMPATIBILITY IDEOGRAPH-F93C;Lo;0;L;797F;;;;N;;;;;\nF93D;CJK COMPATIBILITY IDEOGRAPH-F93D;Lo;0;L;7DA0;;;;N;;;;;\nF93E;CJK COMPATIBILITY IDEOGRAPH-F93E;Lo;0;L;83C9;;;;N;;;;;\nF93F;CJK COMPATIBILITY IDEOGRAPH-F93F;Lo;0;L;9304;;;;N;;;;;\nF940;CJK COMPATIBILITY IDEOGRAPH-F940;Lo;0;L;9E7F;;;;N;;;;;\nF941;CJK COMPATIBILITY IDEOGRAPH-F941;Lo;0;L;8AD6;;;;N;;;;;\nF942;CJK COMPATIBILITY IDEOGRAPH-F942;Lo;0;L;58DF;;;;N;;;;;\nF943;CJK COMPATIBILITY IDEOGRAPH-F943;Lo;0;L;5F04;;;;N;;;;;\nF944;CJK COMPATIBILITY IDEOGRAPH-F944;Lo;0;L;7C60;;;;N;;;;;\nF945;CJK COMPATIBILITY IDEOGRAPH-F945;Lo;0;L;807E;;;;N;;;;;\nF946;CJK COMPATIBILITY IDEOGRAPH-F946;Lo;0;L;7262;;;;N;;;;;\nF947;CJK COMPATIBILITY IDEOGRAPH-F947;Lo;0;L;78CA;;;;N;;;;;\nF948;CJK COMPATIBILITY IDEOGRAPH-F948;Lo;0;L;8CC2;;;;N;;;;;\nF949;CJK COMPATIBILITY IDEOGRAPH-F949;Lo;0;L;96F7;;;;N;;;;;\nF94A;CJK COMPATIBILITY IDEOGRAPH-F94A;Lo;0;L;58D8;;;;N;;;;;\nF94B;CJK COMPATIBILITY IDEOGRAPH-F94B;Lo;0;L;5C62;;;;N;;;;;\nF94C;CJK COMPATIBILITY IDEOGRAPH-F94C;Lo;0;L;6A13;;;;N;;;;;\nF94D;CJK COMPATIBILITY IDEOGRAPH-F94D;Lo;0;L;6DDA;;;;N;;;;;\nF94E;CJK COMPATIBILITY IDEOGRAPH-F94E;Lo;0;L;6F0F;;;;N;;;;;\nF94F;CJK COMPATIBILITY IDEOGRAPH-F94F;Lo;0;L;7D2F;;;;N;;;;;\nF950;CJK COMPATIBILITY IDEOGRAPH-F950;Lo;0;L;7E37;;;;N;;;;;\nF951;CJK COMPATIBILITY IDEOGRAPH-F951;Lo;0;L;964B;;;;N;;;;;\nF952;CJK COMPATIBILITY IDEOGRAPH-F952;Lo;0;L;52D2;;;;N;;;;;\nF953;CJK COMPATIBILITY IDEOGRAPH-F953;Lo;0;L;808B;;;;N;;;;;\nF954;CJK COMPATIBILITY IDEOGRAPH-F954;Lo;0;L;51DC;;;;N;;;;;\nF955;CJK COMPATIBILITY IDEOGRAPH-F955;Lo;0;L;51CC;;;;N;;;;;\nF956;CJK COMPATIBILITY IDEOGRAPH-F956;Lo;0;L;7A1C;;;;N;;;;;\nF957;CJK COMPATIBILITY IDEOGRAPH-F957;Lo;0;L;7DBE;;;;N;;;;;\nF958;CJK COMPATIBILITY IDEOGRAPH-F958;Lo;0;L;83F1;;;;N;;;;;\nF959;CJK COMPATIBILITY IDEOGRAPH-F959;Lo;0;L;9675;;;;N;;;;;\nF95A;CJK COMPATIBILITY IDEOGRAPH-F95A;Lo;0;L;8B80;;;;N;;;;;\nF95B;CJK COMPATIBILITY IDEOGRAPH-F95B;Lo;0;L;62CF;;;;N;;;;;\nF95C;CJK COMPATIBILITY IDEOGRAPH-F95C;Lo;0;L;6A02;;;;N;;;;;\nF95D;CJK COMPATIBILITY IDEOGRAPH-F95D;Lo;0;L;8AFE;;;;N;;;;;\nF95E;CJK COMPATIBILITY IDEOGRAPH-F95E;Lo;0;L;4E39;;;;N;;;;;\nF95F;CJK COMPATIBILITY IDEOGRAPH-F95F;Lo;0;L;5BE7;;;;N;;;;;\nF960;CJK COMPATIBILITY IDEOGRAPH-F960;Lo;0;L;6012;;;;N;;;;;\nF961;CJK COMPATIBILITY IDEOGRAPH-F961;Lo;0;L;7387;;;;N;;;;;\nF962;CJK COMPATIBILITY IDEOGRAPH-F962;Lo;0;L;7570;;;;N;;;;;\nF963;CJK COMPATIBILITY IDEOGRAPH-F963;Lo;0;L;5317;;;;N;;;;;\nF964;CJK COMPATIBILITY IDEOGRAPH-F964;Lo;0;L;78FB;;;;N;;;;;\nF965;CJK COMPATIBILITY IDEOGRAPH-F965;Lo;0;L;4FBF;;;;N;;;;;\nF966;CJK COMPATIBILITY IDEOGRAPH-F966;Lo;0;L;5FA9;;;;N;;;;;\nF967;CJK COMPATIBILITY IDEOGRAPH-F967;Lo;0;L;4E0D;;;;N;;;;;\nF968;CJK COMPATIBILITY IDEOGRAPH-F968;Lo;0;L;6CCC;;;;N;;;;;\nF969;CJK COMPATIBILITY IDEOGRAPH-F969;Lo;0;L;6578;;;;N;;;;;\nF96A;CJK COMPATIBILITY IDEOGRAPH-F96A;Lo;0;L;7D22;;;;N;;;;;\nF96B;CJK COMPATIBILITY IDEOGRAPH-F96B;Lo;0;L;53C3;;;3;N;;;;;\nF96C;CJK COMPATIBILITY IDEOGRAPH-F96C;Lo;0;L;585E;;;;N;;;;;\nF96D;CJK COMPATIBILITY IDEOGRAPH-F96D;Lo;0;L;7701;;;;N;;;;;\nF96E;CJK COMPATIBILITY IDEOGRAPH-F96E;Lo;0;L;8449;;;;N;;;;;\nF96F;CJK COMPATIBILITY IDEOGRAPH-F96F;Lo;0;L;8AAA;;;;N;;;;;\nF970;CJK COMPATIBILITY IDEOGRAPH-F970;Lo;0;L;6BBA;;;;N;;;;;\nF971;CJK COMPATIBILITY IDEOGRAPH-F971;Lo;0;L;8FB0;;;;N;;;;;\nF972;CJK COMPATIBILITY IDEOGRAPH-F972;Lo;0;L;6C88;;;;N;;;;;\nF973;CJK COMPATIBILITY IDEOGRAPH-F973;Lo;0;L;62FE;;;10;N;;;;;\nF974;CJK COMPATIBILITY IDEOGRAPH-F974;Lo;0;L;82E5;;;;N;;;;;\nF975;CJK COMPATIBILITY IDEOGRAPH-F975;Lo;0;L;63A0;;;;N;;;;;\nF976;CJK COMPATIBILITY IDEOGRAPH-F976;Lo;0;L;7565;;;;N;;;;;\nF977;CJK COMPATIBILITY IDEOGRAPH-F977;Lo;0;L;4EAE;;;;N;;;;;\nF978;CJK COMPATIBILITY IDEOGRAPH-F978;Lo;0;L;5169;;;2;N;;;;;\nF979;CJK COMPATIBILITY IDEOGRAPH-F979;Lo;0;L;51C9;;;;N;;;;;\nF97A;CJK COMPATIBILITY IDEOGRAPH-F97A;Lo;0;L;6881;;;;N;;;;;\nF97B;CJK COMPATIBILITY IDEOGRAPH-F97B;Lo;0;L;7CE7;;;;N;;;;;\nF97C;CJK COMPATIBILITY IDEOGRAPH-F97C;Lo;0;L;826F;;;;N;;;;;\nF97D;CJK COMPATIBILITY IDEOGRAPH-F97D;Lo;0;L;8AD2;;;;N;;;;;\nF97E;CJK COMPATIBILITY IDEOGRAPH-F97E;Lo;0;L;91CF;;;;N;;;;;\nF97F;CJK COMPATIBILITY IDEOGRAPH-F97F;Lo;0;L;52F5;;;;N;;;;;\nF980;CJK COMPATIBILITY IDEOGRAPH-F980;Lo;0;L;5442;;;;N;;;;;\nF981;CJK COMPATIBILITY IDEOGRAPH-F981;Lo;0;L;5973;;;;N;;;;;\nF982;CJK COMPATIBILITY IDEOGRAPH-F982;Lo;0;L;5EEC;;;;N;;;;;\nF983;CJK COMPATIBILITY IDEOGRAPH-F983;Lo;0;L;65C5;;;;N;;;;;\nF984;CJK COMPATIBILITY IDEOGRAPH-F984;Lo;0;L;6FFE;;;;N;;;;;\nF985;CJK COMPATIBILITY IDEOGRAPH-F985;Lo;0;L;792A;;;;N;;;;;\nF986;CJK COMPATIBILITY IDEOGRAPH-F986;Lo;0;L;95AD;;;;N;;;;;\nF987;CJK COMPATIBILITY IDEOGRAPH-F987;Lo;0;L;9A6A;;;;N;;;;;\nF988;CJK COMPATIBILITY IDEOGRAPH-F988;Lo;0;L;9E97;;;;N;;;;;\nF989;CJK COMPATIBILITY IDEOGRAPH-F989;Lo;0;L;9ECE;;;;N;;;;;\nF98A;CJK COMPATIBILITY IDEOGRAPH-F98A;Lo;0;L;529B;;;;N;;;;;\nF98B;CJK COMPATIBILITY IDEOGRAPH-F98B;Lo;0;L;66C6;;;;N;;;;;\nF98C;CJK COMPATIBILITY IDEOGRAPH-F98C;Lo;0;L;6B77;;;;N;;;;;\nF98D;CJK COMPATIBILITY IDEOGRAPH-F98D;Lo;0;L;8F62;;;;N;;;;;\nF98E;CJK COMPATIBILITY IDEOGRAPH-F98E;Lo;0;L;5E74;;;;N;;;;;\nF98F;CJK COMPATIBILITY IDEOGRAPH-F98F;Lo;0;L;6190;;;;N;;;;;\nF990;CJK COMPATIBILITY IDEOGRAPH-F990;Lo;0;L;6200;;;;N;;;;;\nF991;CJK COMPATIBILITY IDEOGRAPH-F991;Lo;0;L;649A;;;;N;;;;;\nF992;CJK COMPATIBILITY IDEOGRAPH-F992;Lo;0;L;6F23;;;;N;;;;;\nF993;CJK COMPATIBILITY IDEOGRAPH-F993;Lo;0;L;7149;;;;N;;;;;\nF994;CJK COMPATIBILITY IDEOGRAPH-F994;Lo;0;L;7489;;;;N;;;;;\nF995;CJK COMPATIBILITY IDEOGRAPH-F995;Lo;0;L;79CA;;;;N;;;;;\nF996;CJK COMPATIBILITY IDEOGRAPH-F996;Lo;0;L;7DF4;;;;N;;;;;\nF997;CJK COMPATIBILITY IDEOGRAPH-F997;Lo;0;L;806F;;;;N;;;;;\nF998;CJK COMPATIBILITY IDEOGRAPH-F998;Lo;0;L;8F26;;;;N;;;;;\nF999;CJK COMPATIBILITY IDEOGRAPH-F999;Lo;0;L;84EE;;;;N;;;;;\nF99A;CJK COMPATIBILITY IDEOGRAPH-F99A;Lo;0;L;9023;;;;N;;;;;\nF99B;CJK COMPATIBILITY IDEOGRAPH-F99B;Lo;0;L;934A;;;;N;;;;;\nF99C;CJK COMPATIBILITY IDEOGRAPH-F99C;Lo;0;L;5217;;;;N;;;;;\nF99D;CJK COMPATIBILITY IDEOGRAPH-F99D;Lo;0;L;52A3;;;;N;;;;;\nF99E;CJK COMPATIBILITY IDEOGRAPH-F99E;Lo;0;L;54BD;;;;N;;;;;\nF99F;CJK COMPATIBILITY IDEOGRAPH-F99F;Lo;0;L;70C8;;;;N;;;;;\nF9A0;CJK COMPATIBILITY IDEOGRAPH-F9A0;Lo;0;L;88C2;;;;N;;;;;\nF9A1;CJK COMPATIBILITY IDEOGRAPH-F9A1;Lo;0;L;8AAA;;;;N;;;;;\nF9A2;CJK COMPATIBILITY IDEOGRAPH-F9A2;Lo;0;L;5EC9;;;;N;;;;;\nF9A3;CJK COMPATIBILITY IDEOGRAPH-F9A3;Lo;0;L;5FF5;;;;N;;;;;\nF9A4;CJK COMPATIBILITY IDEOGRAPH-F9A4;Lo;0;L;637B;;;;N;;;;;\nF9A5;CJK COMPATIBILITY IDEOGRAPH-F9A5;Lo;0;L;6BAE;;;;N;;;;;\nF9A6;CJK COMPATIBILITY IDEOGRAPH-F9A6;Lo;0;L;7C3E;;;;N;;;;;\nF9A7;CJK COMPATIBILITY IDEOGRAPH-F9A7;Lo;0;L;7375;;;;N;;;;;\nF9A8;CJK COMPATIBILITY IDEOGRAPH-F9A8;Lo;0;L;4EE4;;;;N;;;;;\nF9A9;CJK COMPATIBILITY IDEOGRAPH-F9A9;Lo;0;L;56F9;;;;N;;;;;\nF9AA;CJK COMPATIBILITY IDEOGRAPH-F9AA;Lo;0;L;5BE7;;;;N;;;;;\nF9AB;CJK COMPATIBILITY IDEOGRAPH-F9AB;Lo;0;L;5DBA;;;;N;;;;;\nF9AC;CJK COMPATIBILITY IDEOGRAPH-F9AC;Lo;0;L;601C;;;;N;;;;;\nF9AD;CJK COMPATIBILITY IDEOGRAPH-F9AD;Lo;0;L;73B2;;;;N;;;;;\nF9AE;CJK COMPATIBILITY IDEOGRAPH-F9AE;Lo;0;L;7469;;;;N;;;;;\nF9AF;CJK COMPATIBILITY IDEOGRAPH-F9AF;Lo;0;L;7F9A;;;;N;;;;;\nF9B0;CJK COMPATIBILITY IDEOGRAPH-F9B0;Lo;0;L;8046;;;;N;;;;;\nF9B1;CJK COMPATIBILITY IDEOGRAPH-F9B1;Lo;0;L;9234;;;;N;;;;;\nF9B2;CJK COMPATIBILITY IDEOGRAPH-F9B2;Lo;0;L;96F6;;;0;N;;;;;\nF9B3;CJK COMPATIBILITY IDEOGRAPH-F9B3;Lo;0;L;9748;;;;N;;;;;\nF9B4;CJK COMPATIBILITY IDEOGRAPH-F9B4;Lo;0;L;9818;;;;N;;;;;\nF9B5;CJK COMPATIBILITY IDEOGRAPH-F9B5;Lo;0;L;4F8B;;;;N;;;;;\nF9B6;CJK COMPATIBILITY IDEOGRAPH-F9B6;Lo;0;L;79AE;;;;N;;;;;\nF9B7;CJK COMPATIBILITY IDEOGRAPH-F9B7;Lo;0;L;91B4;;;;N;;;;;\nF9B8;CJK COMPATIBILITY IDEOGRAPH-F9B8;Lo;0;L;96B8;;;;N;;;;;\nF9B9;CJK COMPATIBILITY IDEOGRAPH-F9B9;Lo;0;L;60E1;;;;N;;;;;\nF9BA;CJK COMPATIBILITY IDEOGRAPH-F9BA;Lo;0;L;4E86;;;;N;;;;;\nF9BB;CJK COMPATIBILITY IDEOGRAPH-F9BB;Lo;0;L;50DA;;;;N;;;;;\nF9BC;CJK COMPATIBILITY IDEOGRAPH-F9BC;Lo;0;L;5BEE;;;;N;;;;;\nF9BD;CJK COMPATIBILITY IDEOGRAPH-F9BD;Lo;0;L;5C3F;;;;N;;;;;\nF9BE;CJK COMPATIBILITY IDEOGRAPH-F9BE;Lo;0;L;6599;;;;N;;;;;\nF9BF;CJK COMPATIBILITY IDEOGRAPH-F9BF;Lo;0;L;6A02;;;;N;;;;;\nF9C0;CJK COMPATIBILITY IDEOGRAPH-F9C0;Lo;0;L;71CE;;;;N;;;;;\nF9C1;CJK COMPATIBILITY IDEOGRAPH-F9C1;Lo;0;L;7642;;;;N;;;;;\nF9C2;CJK COMPATIBILITY IDEOGRAPH-F9C2;Lo;0;L;84FC;;;;N;;;;;\nF9C3;CJK COMPATIBILITY IDEOGRAPH-F9C3;Lo;0;L;907C;;;;N;;;;;\nF9C4;CJK COMPATIBILITY IDEOGRAPH-F9C4;Lo;0;L;9F8D;;;;N;;;;;\nF9C5;CJK COMPATIBILITY IDEOGRAPH-F9C5;Lo;0;L;6688;;;;N;;;;;\nF9C6;CJK COMPATIBILITY IDEOGRAPH-F9C6;Lo;0;L;962E;;;;N;;;;;\nF9C7;CJK COMPATIBILITY IDEOGRAPH-F9C7;Lo;0;L;5289;;;;N;;;;;\nF9C8;CJK COMPATIBILITY IDEOGRAPH-F9C8;Lo;0;L;677B;;;;N;;;;;\nF9C9;CJK COMPATIBILITY IDEOGRAPH-F9C9;Lo;0;L;67F3;;;;N;;;;;\nF9CA;CJK COMPATIBILITY IDEOGRAPH-F9CA;Lo;0;L;6D41;;;;N;;;;;\nF9CB;CJK COMPATIBILITY IDEOGRAPH-F9CB;Lo;0;L;6E9C;;;;N;;;;;\nF9CC;CJK COMPATIBILITY IDEOGRAPH-F9CC;Lo;0;L;7409;;;;N;;;;;\nF9CD;CJK COMPATIBILITY IDEOGRAPH-F9CD;Lo;0;L;7559;;;;N;;;;;\nF9CE;CJK COMPATIBILITY IDEOGRAPH-F9CE;Lo;0;L;786B;;;;N;;;;;\nF9CF;CJK COMPATIBILITY IDEOGRAPH-F9CF;Lo;0;L;7D10;;;;N;;;;;\nF9D0;CJK COMPATIBILITY IDEOGRAPH-F9D0;Lo;0;L;985E;;;;N;;;;;\nF9D1;CJK COMPATIBILITY IDEOGRAPH-F9D1;Lo;0;L;516D;;;6;N;;;;;\nF9D2;CJK COMPATIBILITY IDEOGRAPH-F9D2;Lo;0;L;622E;;;;N;;;;;\nF9D3;CJK COMPATIBILITY IDEOGRAPH-F9D3;Lo;0;L;9678;;;6;N;;;;;\nF9D4;CJK COMPATIBILITY IDEOGRAPH-F9D4;Lo;0;L;502B;;;;N;;;;;\nF9D5;CJK COMPATIBILITY IDEOGRAPH-F9D5;Lo;0;L;5D19;;;;N;;;;;\nF9D6;CJK COMPATIBILITY IDEOGRAPH-F9D6;Lo;0;L;6DEA;;;;N;;;;;\nF9D7;CJK COMPATIBILITY IDEOGRAPH-F9D7;Lo;0;L;8F2A;;;;N;;;;;\nF9D8;CJK COMPATIBILITY IDEOGRAPH-F9D8;Lo;0;L;5F8B;;;;N;;;;;\nF9D9;CJK COMPATIBILITY IDEOGRAPH-F9D9;Lo;0;L;6144;;;;N;;;;;\nF9DA;CJK COMPATIBILITY IDEOGRAPH-F9DA;Lo;0;L;6817;;;;N;;;;;\nF9DB;CJK COMPATIBILITY IDEOGRAPH-F9DB;Lo;0;L;7387;;;;N;;;;;\nF9DC;CJK COMPATIBILITY IDEOGRAPH-F9DC;Lo;0;L;9686;;;;N;;;;;\nF9DD;CJK COMPATIBILITY IDEOGRAPH-F9DD;Lo;0;L;5229;;;;N;;;;;\nF9DE;CJK COMPATIBILITY IDEOGRAPH-F9DE;Lo;0;L;540F;;;;N;;;;;\nF9DF;CJK COMPATIBILITY IDEOGRAPH-F9DF;Lo;0;L;5C65;;;;N;;;;;\nF9E0;CJK COMPATIBILITY IDEOGRAPH-F9E0;Lo;0;L;6613;;;;N;;;;;\nF9E1;CJK COMPATIBILITY IDEOGRAPH-F9E1;Lo;0;L;674E;;;;N;;;;;\nF9E2;CJK COMPATIBILITY IDEOGRAPH-F9E2;Lo;0;L;68A8;;;;N;;;;;\nF9E3;CJK COMPATIBILITY IDEOGRAPH-F9E3;Lo;0;L;6CE5;;;;N;;;;;\nF9E4;CJK COMPATIBILITY IDEOGRAPH-F9E4;Lo;0;L;7406;;;;N;;;;;\nF9E5;CJK COMPATIBILITY IDEOGRAPH-F9E5;Lo;0;L;75E2;;;;N;;;;;\nF9E6;CJK COMPATIBILITY IDEOGRAPH-F9E6;Lo;0;L;7F79;;;;N;;;;;\nF9E7;CJK COMPATIBILITY IDEOGRAPH-F9E7;Lo;0;L;88CF;;;;N;;;;;\nF9E8;CJK COMPATIBILITY IDEOGRAPH-F9E8;Lo;0;L;88E1;;;;N;;;;;\nF9E9;CJK COMPATIBILITY IDEOGRAPH-F9E9;Lo;0;L;91CC;;;;N;;;;;\nF9EA;CJK COMPATIBILITY IDEOGRAPH-F9EA;Lo;0;L;96E2;;;;N;;;;;\nF9EB;CJK COMPATIBILITY IDEOGRAPH-F9EB;Lo;0;L;533F;;;;N;;;;;\nF9EC;CJK COMPATIBILITY IDEOGRAPH-F9EC;Lo;0;L;6EBA;;;;N;;;;;\nF9ED;CJK COMPATIBILITY IDEOGRAPH-F9ED;Lo;0;L;541D;;;;N;;;;;\nF9EE;CJK COMPATIBILITY IDEOGRAPH-F9EE;Lo;0;L;71D0;;;;N;;;;;\nF9EF;CJK COMPATIBILITY IDEOGRAPH-F9EF;Lo;0;L;7498;;;;N;;;;;\nF9F0;CJK COMPATIBILITY IDEOGRAPH-F9F0;Lo;0;L;85FA;;;;N;;;;;\nF9F1;CJK COMPATIBILITY IDEOGRAPH-F9F1;Lo;0;L;96A3;;;;N;;;;;\nF9F2;CJK COMPATIBILITY IDEOGRAPH-F9F2;Lo;0;L;9C57;;;;N;;;;;\nF9F3;CJK COMPATIBILITY IDEOGRAPH-F9F3;Lo;0;L;9E9F;;;;N;;;;;\nF9F4;CJK COMPATIBILITY IDEOGRAPH-F9F4;Lo;0;L;6797;;;;N;;;;;\nF9F5;CJK COMPATIBILITY IDEOGRAPH-F9F5;Lo;0;L;6DCB;;;;N;;;;;\nF9F6;CJK COMPATIBILITY IDEOGRAPH-F9F6;Lo;0;L;81E8;;;;N;;;;;\nF9F7;CJK COMPATIBILITY IDEOGRAPH-F9F7;Lo;0;L;7ACB;;;;N;;;;;\nF9F8;CJK COMPATIBILITY IDEOGRAPH-F9F8;Lo;0;L;7B20;;;;N;;;;;\nF9F9;CJK COMPATIBILITY IDEOGRAPH-F9F9;Lo;0;L;7C92;;;;N;;;;;\nF9FA;CJK COMPATIBILITY IDEOGRAPH-F9FA;Lo;0;L;72C0;;;;N;;;;;\nF9FB;CJK COMPATIBILITY IDEOGRAPH-F9FB;Lo;0;L;7099;;;;N;;;;;\nF9FC;CJK COMPATIBILITY IDEOGRAPH-F9FC;Lo;0;L;8B58;;;;N;;;;;\nF9FD;CJK COMPATIBILITY IDEOGRAPH-F9FD;Lo;0;L;4EC0;;;10;N;;;;;\nF9FE;CJK COMPATIBILITY IDEOGRAPH-F9FE;Lo;0;L;8336;;;;N;;;;;\nF9FF;CJK COMPATIBILITY IDEOGRAPH-F9FF;Lo;0;L;523A;;;;N;;;;;\nFA00;CJK COMPATIBILITY IDEOGRAPH-FA00;Lo;0;L;5207;;;;N;;;;;\nFA01;CJK COMPATIBILITY IDEOGRAPH-FA01;Lo;0;L;5EA6;;;;N;;;;;\nFA02;CJK COMPATIBILITY IDEOGRAPH-FA02;Lo;0;L;62D3;;;;N;;;;;\nFA03;CJK COMPATIBILITY IDEOGRAPH-FA03;Lo;0;L;7CD6;;;;N;;;;;\nFA04;CJK COMPATIBILITY IDEOGRAPH-FA04;Lo;0;L;5B85;;;;N;;;;;\nFA05;CJK COMPATIBILITY IDEOGRAPH-FA05;Lo;0;L;6D1E;;;;N;;;;;\nFA06;CJK COMPATIBILITY IDEOGRAPH-FA06;Lo;0;L;66B4;;;;N;;;;;\nFA07;CJK COMPATIBILITY IDEOGRAPH-FA07;Lo;0;L;8F3B;;;;N;;;;;\nFA08;CJK COMPATIBILITY IDEOGRAPH-FA08;Lo;0;L;884C;;;;N;;;;;\nFA09;CJK COMPATIBILITY IDEOGRAPH-FA09;Lo;0;L;964D;;;;N;;;;;\nFA0A;CJK COMPATIBILITY IDEOGRAPH-FA0A;Lo;0;L;898B;;;;N;;;;;\nFA0B;CJK COMPATIBILITY IDEOGRAPH-FA0B;Lo;0;L;5ED3;;;;N;;;;;\nFA0C;CJK COMPATIBILITY IDEOGRAPH-FA0C;Lo;0;L;5140;;;;N;;;;;\nFA0D;CJK COMPATIBILITY IDEOGRAPH-FA0D;Lo;0;L;55C0;;;;N;;;;;\nFA0E;CJK COMPATIBILITY IDEOGRAPH-FA0E;Lo;0;L;;;;;N;;;;;\nFA0F;CJK COMPATIBILITY IDEOGRAPH-FA0F;Lo;0;L;;;;;N;;;;;\nFA10;CJK COMPATIBILITY IDEOGRAPH-FA10;Lo;0;L;585A;;;;N;;;;;\nFA11;CJK COMPATIBILITY IDEOGRAPH-FA11;Lo;0;L;;;;;N;;;;;\nFA12;CJK COMPATIBILITY IDEOGRAPH-FA12;Lo;0;L;6674;;;;N;;;;;\nFA13;CJK COMPATIBILITY IDEOGRAPH-FA13;Lo;0;L;;;;;N;;;;;\nFA14;CJK COMPATIBILITY IDEOGRAPH-FA14;Lo;0;L;;;;;N;;;;;\nFA15;CJK COMPATIBILITY IDEOGRAPH-FA15;Lo;0;L;51DE;;;;N;;;;;\nFA16;CJK COMPATIBILITY IDEOGRAPH-FA16;Lo;0;L;732A;;;;N;;;;;\nFA17;CJK COMPATIBILITY IDEOGRAPH-FA17;Lo;0;L;76CA;;;;N;;;;;\nFA18;CJK COMPATIBILITY IDEOGRAPH-FA18;Lo;0;L;793C;;;;N;;;;;\nFA19;CJK COMPATIBILITY IDEOGRAPH-FA19;Lo;0;L;795E;;;;N;;;;;\nFA1A;CJK COMPATIBILITY IDEOGRAPH-FA1A;Lo;0;L;7965;;;;N;;;;;\nFA1B;CJK COMPATIBILITY IDEOGRAPH-FA1B;Lo;0;L;798F;;;;N;;;;;\nFA1C;CJK COMPATIBILITY IDEOGRAPH-FA1C;Lo;0;L;9756;;;;N;;;;;\nFA1D;CJK COMPATIBILITY IDEOGRAPH-FA1D;Lo;0;L;7CBE;;;;N;;;;;\nFA1E;CJK COMPATIBILITY IDEOGRAPH-FA1E;Lo;0;L;7FBD;;;;N;;;;;\nFA1F;CJK COMPATIBILITY IDEOGRAPH-FA1F;Lo;0;L;;;;;N;;;;;\nFA20;CJK COMPATIBILITY IDEOGRAPH-FA20;Lo;0;L;8612;;;;N;;;;;\nFA21;CJK COMPATIBILITY IDEOGRAPH-FA21;Lo;0;L;;;;;N;;;;;\nFA22;CJK COMPATIBILITY IDEOGRAPH-FA22;Lo;0;L;8AF8;;;;N;;;;;\nFA23;CJK COMPATIBILITY IDEOGRAPH-FA23;Lo;0;L;;;;;N;;;;;\nFA24;CJK COMPATIBILITY IDEOGRAPH-FA24;Lo;0;L;;;;;N;;;;;\nFA25;CJK COMPATIBILITY IDEOGRAPH-FA25;Lo;0;L;9038;;;;N;;;;;\nFA26;CJK COMPATIBILITY IDEOGRAPH-FA26;Lo;0;L;90FD;;;;N;;;;;\nFA27;CJK COMPATIBILITY IDEOGRAPH-FA27;Lo;0;L;;;;;N;;;;;\nFA28;CJK COMPATIBILITY IDEOGRAPH-FA28;Lo;0;L;;;;;N;;;;;\nFA29;CJK COMPATIBILITY IDEOGRAPH-FA29;Lo;0;L;;;;;N;;;;;\nFA2A;CJK COMPATIBILITY IDEOGRAPH-FA2A;Lo;0;L;98EF;;;;N;;;;;\nFA2B;CJK COMPATIBILITY IDEOGRAPH-FA2B;Lo;0;L;98FC;;;;N;;;;;\nFA2C;CJK COMPATIBILITY IDEOGRAPH-FA2C;Lo;0;L;9928;;;;N;;;;;\nFA2D;CJK COMPATIBILITY IDEOGRAPH-FA2D;Lo;0;L;9DB4;;;;N;;;;;\nFA2E;CJK COMPATIBILITY IDEOGRAPH-FA2E;Lo;0;L;90DE;;;;N;;;;;\nFA2F;CJK COMPATIBILITY IDEOGRAPH-FA2F;Lo;0;L;96B7;;;;N;;;;;\nFA30;CJK COMPATIBILITY IDEOGRAPH-FA30;Lo;0;L;4FAE;;;;N;;;;;\nFA31;CJK COMPATIBILITY IDEOGRAPH-FA31;Lo;0;L;50E7;;;;N;;;;;\nFA32;CJK COMPATIBILITY IDEOGRAPH-FA32;Lo;0;L;514D;;;;N;;;;;\nFA33;CJK COMPATIBILITY IDEOGRAPH-FA33;Lo;0;L;52C9;;;;N;;;;;\nFA34;CJK COMPATIBILITY IDEOGRAPH-FA34;Lo;0;L;52E4;;;;N;;;;;\nFA35;CJK COMPATIBILITY IDEOGRAPH-FA35;Lo;0;L;5351;;;;N;;;;;\nFA36;CJK COMPATIBILITY IDEOGRAPH-FA36;Lo;0;L;559D;;;;N;;;;;\nFA37;CJK COMPATIBILITY IDEOGRAPH-FA37;Lo;0;L;5606;;;;N;;;;;\nFA38;CJK COMPATIBILITY IDEOGRAPH-FA38;Lo;0;L;5668;;;;N;;;;;\nFA39;CJK COMPATIBILITY IDEOGRAPH-FA39;Lo;0;L;5840;;;;N;;;;;\nFA3A;CJK COMPATIBILITY IDEOGRAPH-FA3A;Lo;0;L;58A8;;;;N;;;;;\nFA3B;CJK COMPATIBILITY IDEOGRAPH-FA3B;Lo;0;L;5C64;;;;N;;;;;\nFA3C;CJK COMPATIBILITY IDEOGRAPH-FA3C;Lo;0;L;5C6E;;;;N;;;;;\nFA3D;CJK COMPATIBILITY IDEOGRAPH-FA3D;Lo;0;L;6094;;;;N;;;;;\nFA3E;CJK COMPATIBILITY IDEOGRAPH-FA3E;Lo;0;L;6168;;;;N;;;;;\nFA3F;CJK COMPATIBILITY IDEOGRAPH-FA3F;Lo;0;L;618E;;;;N;;;;;\nFA40;CJK COMPATIBILITY IDEOGRAPH-FA40;Lo;0;L;61F2;;;;N;;;;;\nFA41;CJK COMPATIBILITY IDEOGRAPH-FA41;Lo;0;L;654F;;;;N;;;;;\nFA42;CJK COMPATIBILITY IDEOGRAPH-FA42;Lo;0;L;65E2;;;;N;;;;;\nFA43;CJK COMPATIBILITY IDEOGRAPH-FA43;Lo;0;L;6691;;;;N;;;;;\nFA44;CJK COMPATIBILITY IDEOGRAPH-FA44;Lo;0;L;6885;;;;N;;;;;\nFA45;CJK COMPATIBILITY IDEOGRAPH-FA45;Lo;0;L;6D77;;;;N;;;;;\nFA46;CJK COMPATIBILITY IDEOGRAPH-FA46;Lo;0;L;6E1A;;;;N;;;;;\nFA47;CJK COMPATIBILITY IDEOGRAPH-FA47;Lo;0;L;6F22;;;;N;;;;;\nFA48;CJK COMPATIBILITY IDEOGRAPH-FA48;Lo;0;L;716E;;;;N;;;;;\nFA49;CJK COMPATIBILITY IDEOGRAPH-FA49;Lo;0;L;722B;;;;N;;;;;\nFA4A;CJK COMPATIBILITY IDEOGRAPH-FA4A;Lo;0;L;7422;;;;N;;;;;\nFA4B;CJK COMPATIBILITY IDEOGRAPH-FA4B;Lo;0;L;7891;;;;N;;;;;\nFA4C;CJK COMPATIBILITY IDEOGRAPH-FA4C;Lo;0;L;793E;;;;N;;;;;\nFA4D;CJK COMPATIBILITY IDEOGRAPH-FA4D;Lo;0;L;7949;;;;N;;;;;\nFA4E;CJK COMPATIBILITY IDEOGRAPH-FA4E;Lo;0;L;7948;;;;N;;;;;\nFA4F;CJK COMPATIBILITY IDEOGRAPH-FA4F;Lo;0;L;7950;;;;N;;;;;\nFA50;CJK COMPATIBILITY IDEOGRAPH-FA50;Lo;0;L;7956;;;;N;;;;;\nFA51;CJK COMPATIBILITY IDEOGRAPH-FA51;Lo;0;L;795D;;;;N;;;;;\nFA52;CJK COMPATIBILITY IDEOGRAPH-FA52;Lo;0;L;798D;;;;N;;;;;\nFA53;CJK COMPATIBILITY IDEOGRAPH-FA53;Lo;0;L;798E;;;;N;;;;;\nFA54;CJK COMPATIBILITY IDEOGRAPH-FA54;Lo;0;L;7A40;;;;N;;;;;\nFA55;CJK COMPATIBILITY IDEOGRAPH-FA55;Lo;0;L;7A81;;;;N;;;;;\nFA56;CJK COMPATIBILITY IDEOGRAPH-FA56;Lo;0;L;7BC0;;;;N;;;;;\nFA57;CJK COMPATIBILITY IDEOGRAPH-FA57;Lo;0;L;7DF4;;;;N;;;;;\nFA58;CJK COMPATIBILITY IDEOGRAPH-FA58;Lo;0;L;7E09;;;;N;;;;;\nFA59;CJK COMPATIBILITY IDEOGRAPH-FA59;Lo;0;L;7E41;;;;N;;;;;\nFA5A;CJK COMPATIBILITY IDEOGRAPH-FA5A;Lo;0;L;7F72;;;;N;;;;;\nFA5B;CJK COMPATIBILITY IDEOGRAPH-FA5B;Lo;0;L;8005;;;;N;;;;;\nFA5C;CJK COMPATIBILITY IDEOGRAPH-FA5C;Lo;0;L;81ED;;;;N;;;;;\nFA5D;CJK COMPATIBILITY IDEOGRAPH-FA5D;Lo;0;L;8279;;;;N;;;;;\nFA5E;CJK COMPATIBILITY IDEOGRAPH-FA5E;Lo;0;L;8279;;;;N;;;;;\nFA5F;CJK COMPATIBILITY IDEOGRAPH-FA5F;Lo;0;L;8457;;;;N;;;;;\nFA60;CJK COMPATIBILITY IDEOGRAPH-FA60;Lo;0;L;8910;;;;N;;;;;\nFA61;CJK COMPATIBILITY IDEOGRAPH-FA61;Lo;0;L;8996;;;;N;;;;;\nFA62;CJK COMPATIBILITY IDEOGRAPH-FA62;Lo;0;L;8B01;;;;N;;;;;\nFA63;CJK COMPATIBILITY IDEOGRAPH-FA63;Lo;0;L;8B39;;;;N;;;;;\nFA64;CJK COMPATIBILITY IDEOGRAPH-FA64;Lo;0;L;8CD3;;;;N;;;;;\nFA65;CJK COMPATIBILITY IDEOGRAPH-FA65;Lo;0;L;8D08;;;;N;;;;;\nFA66;CJK COMPATIBILITY IDEOGRAPH-FA66;Lo;0;L;8FB6;;;;N;;;;;\nFA67;CJK COMPATIBILITY IDEOGRAPH-FA67;Lo;0;L;9038;;;;N;;;;;\nFA68;CJK COMPATIBILITY IDEOGRAPH-FA68;Lo;0;L;96E3;;;;N;;;;;\nFA69;CJK COMPATIBILITY IDEOGRAPH-FA69;Lo;0;L;97FF;;;;N;;;;;\nFA6A;CJK COMPATIBILITY IDEOGRAPH-FA6A;Lo;0;L;983B;;;;N;;;;;\nFA6B;CJK COMPATIBILITY IDEOGRAPH-FA6B;Lo;0;L;6075;;;;N;;;;;\nFA6C;CJK COMPATIBILITY IDEOGRAPH-FA6C;Lo;0;L;242EE;;;;N;;;;;\nFA6D;CJK COMPATIBILITY IDEOGRAPH-FA6D;Lo;0;L;8218;;;;N;;;;;\nFA70;CJK COMPATIBILITY IDEOGRAPH-FA70;Lo;0;L;4E26;;;;N;;;;;\nFA71;CJK COMPATIBILITY IDEOGRAPH-FA71;Lo;0;L;51B5;;;;N;;;;;\nFA72;CJK COMPATIBILITY IDEOGRAPH-FA72;Lo;0;L;5168;;;;N;;;;;\nFA73;CJK COMPATIBILITY IDEOGRAPH-FA73;Lo;0;L;4F80;;;;N;;;;;\nFA74;CJK COMPATIBILITY IDEOGRAPH-FA74;Lo;0;L;5145;;;;N;;;;;\nFA75;CJK COMPATIBILITY IDEOGRAPH-FA75;Lo;0;L;5180;;;;N;;;;;\nFA76;CJK COMPATIBILITY IDEOGRAPH-FA76;Lo;0;L;52C7;;;;N;;;;;\nFA77;CJK COMPATIBILITY IDEOGRAPH-FA77;Lo;0;L;52FA;;;;N;;;;;\nFA78;CJK COMPATIBILITY IDEOGRAPH-FA78;Lo;0;L;559D;;;;N;;;;;\nFA79;CJK COMPATIBILITY IDEOGRAPH-FA79;Lo;0;L;5555;;;;N;;;;;\nFA7A;CJK COMPATIBILITY IDEOGRAPH-FA7A;Lo;0;L;5599;;;;N;;;;;\nFA7B;CJK COMPATIBILITY IDEOGRAPH-FA7B;Lo;0;L;55E2;;;;N;;;;;\nFA7C;CJK COMPATIBILITY IDEOGRAPH-FA7C;Lo;0;L;585A;;;;N;;;;;\nFA7D;CJK COMPATIBILITY IDEOGRAPH-FA7D;Lo;0;L;58B3;;;;N;;;;;\nFA7E;CJK COMPATIBILITY IDEOGRAPH-FA7E;Lo;0;L;5944;;;;N;;;;;\nFA7F;CJK COMPATIBILITY IDEOGRAPH-FA7F;Lo;0;L;5954;;;;N;;;;;\nFA80;CJK COMPATIBILITY IDEOGRAPH-FA80;Lo;0;L;5A62;;;;N;;;;;\nFA81;CJK COMPATIBILITY IDEOGRAPH-FA81;Lo;0;L;5B28;;;;N;;;;;\nFA82;CJK COMPATIBILITY IDEOGRAPH-FA82;Lo;0;L;5ED2;;;;N;;;;;\nFA83;CJK COMPATIBILITY IDEOGRAPH-FA83;Lo;0;L;5ED9;;;;N;;;;;\nFA84;CJK COMPATIBILITY IDEOGRAPH-FA84;Lo;0;L;5F69;;;;N;;;;;\nFA85;CJK COMPATIBILITY IDEOGRAPH-FA85;Lo;0;L;5FAD;;;;N;;;;;\nFA86;CJK COMPATIBILITY IDEOGRAPH-FA86;Lo;0;L;60D8;;;;N;;;;;\nFA87;CJK COMPATIBILITY IDEOGRAPH-FA87;Lo;0;L;614E;;;;N;;;;;\nFA88;CJK COMPATIBILITY IDEOGRAPH-FA88;Lo;0;L;6108;;;;N;;;;;\nFA89;CJK COMPATIBILITY IDEOGRAPH-FA89;Lo;0;L;618E;;;;N;;;;;\nFA8A;CJK COMPATIBILITY IDEOGRAPH-FA8A;Lo;0;L;6160;;;;N;;;;;\nFA8B;CJK COMPATIBILITY IDEOGRAPH-FA8B;Lo;0;L;61F2;;;;N;;;;;\nFA8C;CJK COMPATIBILITY IDEOGRAPH-FA8C;Lo;0;L;6234;;;;N;;;;;\nFA8D;CJK COMPATIBILITY IDEOGRAPH-FA8D;Lo;0;L;63C4;;;;N;;;;;\nFA8E;CJK COMPATIBILITY IDEOGRAPH-FA8E;Lo;0;L;641C;;;;N;;;;;\nFA8F;CJK COMPATIBILITY IDEOGRAPH-FA8F;Lo;0;L;6452;;;;N;;;;;\nFA90;CJK COMPATIBILITY IDEOGRAPH-FA90;Lo;0;L;6556;;;;N;;;;;\nFA91;CJK COMPATIBILITY IDEOGRAPH-FA91;Lo;0;L;6674;;;;N;;;;;\nFA92;CJK COMPATIBILITY IDEOGRAPH-FA92;Lo;0;L;6717;;;;N;;;;;\nFA93;CJK COMPATIBILITY IDEOGRAPH-FA93;Lo;0;L;671B;;;;N;;;;;\nFA94;CJK COMPATIBILITY IDEOGRAPH-FA94;Lo;0;L;6756;;;;N;;;;;\nFA95;CJK COMPATIBILITY IDEOGRAPH-FA95;Lo;0;L;6B79;;;;N;;;;;\nFA96;CJK COMPATIBILITY IDEOGRAPH-FA96;Lo;0;L;6BBA;;;;N;;;;;\nFA97;CJK COMPATIBILITY IDEOGRAPH-FA97;Lo;0;L;6D41;;;;N;;;;;\nFA98;CJK COMPATIBILITY IDEOGRAPH-FA98;Lo;0;L;6EDB;;;;N;;;;;\nFA99;CJK COMPATIBILITY IDEOGRAPH-FA99;Lo;0;L;6ECB;;;;N;;;;;\nFA9A;CJK COMPATIBILITY IDEOGRAPH-FA9A;Lo;0;L;6F22;;;;N;;;;;\nFA9B;CJK COMPATIBILITY IDEOGRAPH-FA9B;Lo;0;L;701E;;;;N;;;;;\nFA9C;CJK COMPATIBILITY IDEOGRAPH-FA9C;Lo;0;L;716E;;;;N;;;;;\nFA9D;CJK COMPATIBILITY IDEOGRAPH-FA9D;Lo;0;L;77A7;;;;N;;;;;\nFA9E;CJK COMPATIBILITY IDEOGRAPH-FA9E;Lo;0;L;7235;;;;N;;;;;\nFA9F;CJK COMPATIBILITY IDEOGRAPH-FA9F;Lo;0;L;72AF;;;;N;;;;;\nFAA0;CJK COMPATIBILITY IDEOGRAPH-FAA0;Lo;0;L;732A;;;;N;;;;;\nFAA1;CJK COMPATIBILITY IDEOGRAPH-FAA1;Lo;0;L;7471;;;;N;;;;;\nFAA2;CJK COMPATIBILITY IDEOGRAPH-FAA2;Lo;0;L;7506;;;;N;;;;;\nFAA3;CJK COMPATIBILITY IDEOGRAPH-FAA3;Lo;0;L;753B;;;;N;;;;;\nFAA4;CJK COMPATIBILITY IDEOGRAPH-FAA4;Lo;0;L;761D;;;;N;;;;;\nFAA5;CJK COMPATIBILITY IDEOGRAPH-FAA5;Lo;0;L;761F;;;;N;;;;;\nFAA6;CJK COMPATIBILITY IDEOGRAPH-FAA6;Lo;0;L;76CA;;;;N;;;;;\nFAA7;CJK COMPATIBILITY IDEOGRAPH-FAA7;Lo;0;L;76DB;;;;N;;;;;\nFAA8;CJK COMPATIBILITY IDEOGRAPH-FAA8;Lo;0;L;76F4;;;;N;;;;;\nFAA9;CJK COMPATIBILITY IDEOGRAPH-FAA9;Lo;0;L;774A;;;;N;;;;;\nFAAA;CJK COMPATIBILITY IDEOGRAPH-FAAA;Lo;0;L;7740;;;;N;;;;;\nFAAB;CJK COMPATIBILITY IDEOGRAPH-FAAB;Lo;0;L;78CC;;;;N;;;;;\nFAAC;CJK COMPATIBILITY IDEOGRAPH-FAAC;Lo;0;L;7AB1;;;;N;;;;;\nFAAD;CJK COMPATIBILITY IDEOGRAPH-FAAD;Lo;0;L;7BC0;;;;N;;;;;\nFAAE;CJK COMPATIBILITY IDEOGRAPH-FAAE;Lo;0;L;7C7B;;;;N;;;;;\nFAAF;CJK COMPATIBILITY IDEOGRAPH-FAAF;Lo;0;L;7D5B;;;;N;;;;;\nFAB0;CJK COMPATIBILITY IDEOGRAPH-FAB0;Lo;0;L;7DF4;;;;N;;;;;\nFAB1;CJK COMPATIBILITY IDEOGRAPH-FAB1;Lo;0;L;7F3E;;;;N;;;;;\nFAB2;CJK COMPATIBILITY IDEOGRAPH-FAB2;Lo;0;L;8005;;;;N;;;;;\nFAB3;CJK COMPATIBILITY IDEOGRAPH-FAB3;Lo;0;L;8352;;;;N;;;;;\nFAB4;CJK COMPATIBILITY IDEOGRAPH-FAB4;Lo;0;L;83EF;;;;N;;;;;\nFAB5;CJK COMPATIBILITY IDEOGRAPH-FAB5;Lo;0;L;8779;;;;N;;;;;\nFAB6;CJK COMPATIBILITY IDEOGRAPH-FAB6;Lo;0;L;8941;;;;N;;;;;\nFAB7;CJK COMPATIBILITY IDEOGRAPH-FAB7;Lo;0;L;8986;;;;N;;;;;\nFAB8;CJK COMPATIBILITY IDEOGRAPH-FAB8;Lo;0;L;8996;;;;N;;;;;\nFAB9;CJK COMPATIBILITY IDEOGRAPH-FAB9;Lo;0;L;8ABF;;;;N;;;;;\nFABA;CJK COMPATIBILITY IDEOGRAPH-FABA;Lo;0;L;8AF8;;;;N;;;;;\nFABB;CJK COMPATIBILITY IDEOGRAPH-FABB;Lo;0;L;8ACB;;;;N;;;;;\nFABC;CJK COMPATIBILITY IDEOGRAPH-FABC;Lo;0;L;8B01;;;;N;;;;;\nFABD;CJK COMPATIBILITY IDEOGRAPH-FABD;Lo;0;L;8AFE;;;;N;;;;;\nFABE;CJK COMPATIBILITY IDEOGRAPH-FABE;Lo;0;L;8AED;;;;N;;;;;\nFABF;CJK COMPATIBILITY IDEOGRAPH-FABF;Lo;0;L;8B39;;;;N;;;;;\nFAC0;CJK COMPATIBILITY IDEOGRAPH-FAC0;Lo;0;L;8B8A;;;;N;;;;;\nFAC1;CJK COMPATIBILITY IDEOGRAPH-FAC1;Lo;0;L;8D08;;;;N;;;;;\nFAC2;CJK COMPATIBILITY IDEOGRAPH-FAC2;Lo;0;L;8F38;;;;N;;;;;\nFAC3;CJK COMPATIBILITY IDEOGRAPH-FAC3;Lo;0;L;9072;;;;N;;;;;\nFAC4;CJK COMPATIBILITY IDEOGRAPH-FAC4;Lo;0;L;9199;;;;N;;;;;\nFAC5;CJK COMPATIBILITY IDEOGRAPH-FAC5;Lo;0;L;9276;;;;N;;;;;\nFAC6;CJK COMPATIBILITY IDEOGRAPH-FAC6;Lo;0;L;967C;;;;N;;;;;\nFAC7;CJK COMPATIBILITY IDEOGRAPH-FAC7;Lo;0;L;96E3;;;;N;;;;;\nFAC8;CJK COMPATIBILITY IDEOGRAPH-FAC8;Lo;0;L;9756;;;;N;;;;;\nFAC9;CJK COMPATIBILITY IDEOGRAPH-FAC9;Lo;0;L;97DB;;;;N;;;;;\nFACA;CJK COMPATIBILITY IDEOGRAPH-FACA;Lo;0;L;97FF;;;;N;;;;;\nFACB;CJK COMPATIBILITY IDEOGRAPH-FACB;Lo;0;L;980B;;;;N;;;;;\nFACC;CJK COMPATIBILITY IDEOGRAPH-FACC;Lo;0;L;983B;;;;N;;;;;\nFACD;CJK COMPATIBILITY IDEOGRAPH-FACD;Lo;0;L;9B12;;;;N;;;;;\nFACE;CJK COMPATIBILITY IDEOGRAPH-FACE;Lo;0;L;9F9C;;;;N;;;;;\nFACF;CJK COMPATIBILITY IDEOGRAPH-FACF;Lo;0;L;2284A;;;;N;;;;;\nFAD0;CJK COMPATIBILITY IDEOGRAPH-FAD0;Lo;0;L;22844;;;;N;;;;;\nFAD1;CJK COMPATIBILITY IDEOGRAPH-FAD1;Lo;0;L;233D5;;;;N;;;;;\nFAD2;CJK COMPATIBILITY IDEOGRAPH-FAD2;Lo;0;L;3B9D;;;;N;;;;;\nFAD3;CJK COMPATIBILITY IDEOGRAPH-FAD3;Lo;0;L;4018;;;;N;;;;;\nFAD4;CJK COMPATIBILITY IDEOGRAPH-FAD4;Lo;0;L;4039;;;;N;;;;;\nFAD5;CJK COMPATIBILITY IDEOGRAPH-FAD5;Lo;0;L;25249;;;;N;;;;;\nFAD6;CJK COMPATIBILITY IDEOGRAPH-FAD6;Lo;0;L;25CD0;;;;N;;;;;\nFAD7;CJK COMPATIBILITY IDEOGRAPH-FAD7;Lo;0;L;27ED3;;;;N;;;;;\nFAD8;CJK COMPATIBILITY IDEOGRAPH-FAD8;Lo;0;L;9F43;;;;N;;;;;\nFAD9;CJK COMPATIBILITY IDEOGRAPH-FAD9;Lo;0;L;9F8E;;;;N;;;;;\nFB00;LATIN SMALL LIGATURE FF;Ll;0;L;<compat> 0066 0066;;;;N;;;;;\nFB01;LATIN SMALL LIGATURE FI;Ll;0;L;<compat> 0066 0069;;;;N;;;;;\nFB02;LATIN SMALL LIGATURE FL;Ll;0;L;<compat> 0066 006C;;;;N;;;;;\nFB03;LATIN SMALL LIGATURE FFI;Ll;0;L;<compat> 0066 0066 0069;;;;N;;;;;\nFB04;LATIN SMALL LIGATURE FFL;Ll;0;L;<compat> 0066 0066 006C;;;;N;;;;;\nFB05;LATIN SMALL LIGATURE LONG S T;Ll;0;L;<compat> 017F 0074;;;;N;;;;;\nFB06;LATIN SMALL LIGATURE ST;Ll;0;L;<compat> 0073 0074;;;;N;;;;;\nFB13;ARMENIAN SMALL LIGATURE MEN NOW;Ll;0;L;<compat> 0574 0576;;;;N;;;;;\nFB14;ARMENIAN SMALL LIGATURE MEN ECH;Ll;0;L;<compat> 0574 0565;;;;N;;;;;\nFB15;ARMENIAN SMALL LIGATURE MEN INI;Ll;0;L;<compat> 0574 056B;;;;N;;;;;\nFB16;ARMENIAN SMALL LIGATURE VEW NOW;Ll;0;L;<compat> 057E 0576;;;;N;;;;;\nFB17;ARMENIAN SMALL LIGATURE MEN XEH;Ll;0;L;<compat> 0574 056D;;;;N;;;;;\nFB1D;HEBREW LETTER YOD WITH HIRIQ;Lo;0;R;05D9 05B4;;;;N;;;;;\nFB1E;HEBREW POINT JUDEO-SPANISH VARIKA;Mn;26;NSM;;;;;N;HEBREW POINT VARIKA;;;;\nFB1F;HEBREW LIGATURE YIDDISH YOD YOD PATAH;Lo;0;R;05F2 05B7;;;;N;;;;;\nFB20;HEBREW LETTER ALTERNATIVE AYIN;Lo;0;R;<font> 05E2;;;;N;;;;;\nFB21;HEBREW LETTER WIDE ALEF;Lo;0;R;<font> 05D0;;;;N;;;;;\nFB22;HEBREW LETTER WIDE DALET;Lo;0;R;<font> 05D3;;;;N;;;;;\nFB23;HEBREW LETTER WIDE HE;Lo;0;R;<font> 05D4;;;;N;;;;;\nFB24;HEBREW LETTER WIDE KAF;Lo;0;R;<font> 05DB;;;;N;;;;;\nFB25;HEBREW LETTER WIDE LAMED;Lo;0;R;<font> 05DC;;;;N;;;;;\nFB26;HEBREW LETTER WIDE FINAL MEM;Lo;0;R;<font> 05DD;;;;N;;;;;\nFB27;HEBREW LETTER WIDE RESH;Lo;0;R;<font> 05E8;;;;N;;;;;\nFB28;HEBREW LETTER WIDE TAV;Lo;0;R;<font> 05EA;;;;N;;;;;\nFB29;HEBREW LETTER ALTERNATIVE PLUS SIGN;Sm;0;ES;<font> 002B;;;;N;;;;;\nFB2A;HEBREW LETTER SHIN WITH SHIN DOT;Lo;0;R;05E9 05C1;;;;N;;;;;\nFB2B;HEBREW LETTER SHIN WITH SIN DOT;Lo;0;R;05E9 05C2;;;;N;;;;;\nFB2C;HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT;Lo;0;R;FB49 05C1;;;;N;;;;;\nFB2D;HEBREW LETTER SHIN WITH DAGESH AND SIN DOT;Lo;0;R;FB49 05C2;;;;N;;;;;\nFB2E;HEBREW LETTER ALEF WITH PATAH;Lo;0;R;05D0 05B7;;;;N;;;;;\nFB2F;HEBREW LETTER ALEF WITH QAMATS;Lo;0;R;05D0 05B8;;;;N;;;;;\nFB30;HEBREW LETTER ALEF WITH MAPIQ;Lo;0;R;05D0 05BC;;;;N;;;;;\nFB31;HEBREW LETTER BET WITH DAGESH;Lo;0;R;05D1 05BC;;;;N;;;;;\nFB32;HEBREW LETTER GIMEL WITH DAGESH;Lo;0;R;05D2 05BC;;;;N;;;;;\nFB33;HEBREW LETTER DALET WITH DAGESH;Lo;0;R;05D3 05BC;;;;N;;;;;\nFB34;HEBREW LETTER HE WITH MAPIQ;Lo;0;R;05D4 05BC;;;;N;;;;;\nFB35;HEBREW LETTER VAV WITH DAGESH;Lo;0;R;05D5 05BC;;;;N;;;;;\nFB36;HEBREW LETTER ZAYIN WITH DAGESH;Lo;0;R;05D6 05BC;;;;N;;;;;\nFB38;HEBREW LETTER TET WITH DAGESH;Lo;0;R;05D8 05BC;;;;N;;;;;\nFB39;HEBREW LETTER YOD WITH DAGESH;Lo;0;R;05D9 05BC;;;;N;;;;;\nFB3A;HEBREW LETTER FINAL KAF WITH DAGESH;Lo;0;R;05DA 05BC;;;;N;;;;;\nFB3B;HEBREW LETTER KAF WITH DAGESH;Lo;0;R;05DB 05BC;;;;N;;;;;\nFB3C;HEBREW LETTER LAMED WITH DAGESH;Lo;0;R;05DC 05BC;;;;N;;;;;\nFB3E;HEBREW LETTER MEM WITH DAGESH;Lo;0;R;05DE 05BC;;;;N;;;;;\nFB40;HEBREW LETTER NUN WITH DAGESH;Lo;0;R;05E0 05BC;;;;N;;;;;\nFB41;HEBREW LETTER SAMEKH WITH DAGESH;Lo;0;R;05E1 05BC;;;;N;;;;;\nFB43;HEBREW LETTER FINAL PE WITH DAGESH;Lo;0;R;05E3 05BC;;;;N;;;;;\nFB44;HEBREW LETTER PE WITH DAGESH;Lo;0;R;05E4 05BC;;;;N;;;;;\nFB46;HEBREW LETTER TSADI WITH DAGESH;Lo;0;R;05E6 05BC;;;;N;;;;;\nFB47;HEBREW LETTER QOF WITH DAGESH;Lo;0;R;05E7 05BC;;;;N;;;;;\nFB48;HEBREW LETTER RESH WITH DAGESH;Lo;0;R;05E8 05BC;;;;N;;;;;\nFB49;HEBREW LETTER SHIN WITH DAGESH;Lo;0;R;05E9 05BC;;;;N;;;;;\nFB4A;HEBREW LETTER TAV WITH DAGESH;Lo;0;R;05EA 05BC;;;;N;;;;;\nFB4B;HEBREW LETTER VAV WITH HOLAM;Lo;0;R;05D5 05B9;;;;N;;;;;\nFB4C;HEBREW LETTER BET WITH RAFE;Lo;0;R;05D1 05BF;;;;N;;;;;\nFB4D;HEBREW LETTER KAF WITH RAFE;Lo;0;R;05DB 05BF;;;;N;;;;;\nFB4E;HEBREW LETTER PE WITH RAFE;Lo;0;R;05E4 05BF;;;;N;;;;;\nFB4F;HEBREW LIGATURE ALEF LAMED;Lo;0;R;<compat> 05D0 05DC;;;;N;;;;;\nFB50;ARABIC LETTER ALEF WASLA ISOLATED FORM;Lo;0;AL;<isolated> 0671;;;;N;;;;;\nFB51;ARABIC LETTER ALEF WASLA FINAL FORM;Lo;0;AL;<final> 0671;;;;N;;;;;\nFB52;ARABIC LETTER BEEH ISOLATED FORM;Lo;0;AL;<isolated> 067B;;;;N;;;;;\nFB53;ARABIC LETTER BEEH FINAL FORM;Lo;0;AL;<final> 067B;;;;N;;;;;\nFB54;ARABIC LETTER BEEH INITIAL FORM;Lo;0;AL;<initial> 067B;;;;N;;;;;\nFB55;ARABIC LETTER BEEH MEDIAL FORM;Lo;0;AL;<medial> 067B;;;;N;;;;;\nFB56;ARABIC LETTER PEH ISOLATED FORM;Lo;0;AL;<isolated> 067E;;;;N;;;;;\nFB57;ARABIC LETTER PEH FINAL FORM;Lo;0;AL;<final> 067E;;;;N;;;;;\nFB58;ARABIC LETTER PEH INITIAL FORM;Lo;0;AL;<initial> 067E;;;;N;;;;;\nFB59;ARABIC LETTER PEH MEDIAL FORM;Lo;0;AL;<medial> 067E;;;;N;;;;;\nFB5A;ARABIC LETTER BEHEH ISOLATED FORM;Lo;0;AL;<isolated> 0680;;;;N;;;;;\nFB5B;ARABIC LETTER BEHEH FINAL FORM;Lo;0;AL;<final> 0680;;;;N;;;;;\nFB5C;ARABIC LETTER BEHEH INITIAL FORM;Lo;0;AL;<initial> 0680;;;;N;;;;;\nFB5D;ARABIC LETTER BEHEH MEDIAL FORM;Lo;0;AL;<medial> 0680;;;;N;;;;;\nFB5E;ARABIC LETTER TTEHEH ISOLATED FORM;Lo;0;AL;<isolated> 067A;;;;N;;;;;\nFB5F;ARABIC LETTER TTEHEH FINAL FORM;Lo;0;AL;<final> 067A;;;;N;;;;;\nFB60;ARABIC LETTER TTEHEH INITIAL FORM;Lo;0;AL;<initial> 067A;;;;N;;;;;\nFB61;ARABIC LETTER TTEHEH MEDIAL FORM;Lo;0;AL;<medial> 067A;;;;N;;;;;\nFB62;ARABIC LETTER TEHEH ISOLATED FORM;Lo;0;AL;<isolated> 067F;;;;N;;;;;\nFB63;ARABIC LETTER TEHEH FINAL FORM;Lo;0;AL;<final> 067F;;;;N;;;;;\nFB64;ARABIC LETTER TEHEH INITIAL FORM;Lo;0;AL;<initial> 067F;;;;N;;;;;\nFB65;ARABIC LETTER TEHEH MEDIAL FORM;Lo;0;AL;<medial> 067F;;;;N;;;;;\nFB66;ARABIC LETTER TTEH ISOLATED FORM;Lo;0;AL;<isolated> 0679;;;;N;;;;;\nFB67;ARABIC LETTER TTEH FINAL FORM;Lo;0;AL;<final> 0679;;;;N;;;;;\nFB68;ARABIC LETTER TTEH INITIAL FORM;Lo;0;AL;<initial> 0679;;;;N;;;;;\nFB69;ARABIC LETTER TTEH MEDIAL FORM;Lo;0;AL;<medial> 0679;;;;N;;;;;\nFB6A;ARABIC LETTER VEH ISOLATED FORM;Lo;0;AL;<isolated> 06A4;;;;N;;;;;\nFB6B;ARABIC LETTER VEH FINAL FORM;Lo;0;AL;<final> 06A4;;;;N;;;;;\nFB6C;ARABIC LETTER VEH INITIAL FORM;Lo;0;AL;<initial> 06A4;;;;N;;;;;\nFB6D;ARABIC LETTER VEH MEDIAL FORM;Lo;0;AL;<medial> 06A4;;;;N;;;;;\nFB6E;ARABIC LETTER PEHEH ISOLATED FORM;Lo;0;AL;<isolated> 06A6;;;;N;;;;;\nFB6F;ARABIC LETTER PEHEH FINAL FORM;Lo;0;AL;<final> 06A6;;;;N;;;;;\nFB70;ARABIC LETTER PEHEH INITIAL FORM;Lo;0;AL;<initial> 06A6;;;;N;;;;;\nFB71;ARABIC LETTER PEHEH MEDIAL FORM;Lo;0;AL;<medial> 06A6;;;;N;;;;;\nFB72;ARABIC LETTER DYEH ISOLATED FORM;Lo;0;AL;<isolated> 0684;;;;N;;;;;\nFB73;ARABIC LETTER DYEH FINAL FORM;Lo;0;AL;<final> 0684;;;;N;;;;;\nFB74;ARABIC LETTER DYEH INITIAL FORM;Lo;0;AL;<initial> 0684;;;;N;;;;;\nFB75;ARABIC LETTER DYEH MEDIAL FORM;Lo;0;AL;<medial> 0684;;;;N;;;;;\nFB76;ARABIC LETTER NYEH ISOLATED FORM;Lo;0;AL;<isolated> 0683;;;;N;;;;;\nFB77;ARABIC LETTER NYEH FINAL FORM;Lo;0;AL;<final> 0683;;;;N;;;;;\nFB78;ARABIC LETTER NYEH INITIAL FORM;Lo;0;AL;<initial> 0683;;;;N;;;;;\nFB79;ARABIC LETTER NYEH MEDIAL FORM;Lo;0;AL;<medial> 0683;;;;N;;;;;\nFB7A;ARABIC LETTER TCHEH ISOLATED FORM;Lo;0;AL;<isolated> 0686;;;;N;;;;;\nFB7B;ARABIC LETTER TCHEH FINAL FORM;Lo;0;AL;<final> 0686;;;;N;;;;;\nFB7C;ARABIC LETTER TCHEH INITIAL FORM;Lo;0;AL;<initial> 0686;;;;N;;;;;\nFB7D;ARABIC LETTER TCHEH MEDIAL FORM;Lo;0;AL;<medial> 0686;;;;N;;;;;\nFB7E;ARABIC LETTER TCHEHEH ISOLATED FORM;Lo;0;AL;<isolated> 0687;;;;N;;;;;\nFB7F;ARABIC LETTER TCHEHEH FINAL FORM;Lo;0;AL;<final> 0687;;;;N;;;;;\nFB80;ARABIC LETTER TCHEHEH INITIAL FORM;Lo;0;AL;<initial> 0687;;;;N;;;;;\nFB81;ARABIC LETTER TCHEHEH MEDIAL FORM;Lo;0;AL;<medial> 0687;;;;N;;;;;\nFB82;ARABIC LETTER DDAHAL ISOLATED FORM;Lo;0;AL;<isolated> 068D;;;;N;;;;;\nFB83;ARABIC LETTER DDAHAL FINAL FORM;Lo;0;AL;<final> 068D;;;;N;;;;;\nFB84;ARABIC LETTER DAHAL ISOLATED FORM;Lo;0;AL;<isolated> 068C;;;;N;;;;;\nFB85;ARABIC LETTER DAHAL FINAL FORM;Lo;0;AL;<final> 068C;;;;N;;;;;\nFB86;ARABIC LETTER DUL ISOLATED FORM;Lo;0;AL;<isolated> 068E;;;;N;;;;;\nFB87;ARABIC LETTER DUL FINAL FORM;Lo;0;AL;<final> 068E;;;;N;;;;;\nFB88;ARABIC LETTER DDAL ISOLATED FORM;Lo;0;AL;<isolated> 0688;;;;N;;;;;\nFB89;ARABIC LETTER DDAL FINAL FORM;Lo;0;AL;<final> 0688;;;;N;;;;;\nFB8A;ARABIC LETTER JEH ISOLATED FORM;Lo;0;AL;<isolated> 0698;;;;N;;;;;\nFB8B;ARABIC LETTER JEH FINAL FORM;Lo;0;AL;<final> 0698;;;;N;;;;;\nFB8C;ARABIC LETTER RREH ISOLATED FORM;Lo;0;AL;<isolated> 0691;;;;N;;;;;\nFB8D;ARABIC LETTER RREH FINAL FORM;Lo;0;AL;<final> 0691;;;;N;;;;;\nFB8E;ARABIC LETTER KEHEH ISOLATED FORM;Lo;0;AL;<isolated> 06A9;;;;N;;;;;\nFB8F;ARABIC LETTER KEHEH FINAL FORM;Lo;0;AL;<final> 06A9;;;;N;;;;;\nFB90;ARABIC LETTER KEHEH INITIAL FORM;Lo;0;AL;<initial> 06A9;;;;N;;;;;\nFB91;ARABIC LETTER KEHEH MEDIAL FORM;Lo;0;AL;<medial> 06A9;;;;N;;;;;\nFB92;ARABIC LETTER GAF ISOLATED FORM;Lo;0;AL;<isolated> 06AF;;;;N;;;;;\nFB93;ARABIC LETTER GAF FINAL FORM;Lo;0;AL;<final> 06AF;;;;N;;;;;\nFB94;ARABIC LETTER GAF INITIAL FORM;Lo;0;AL;<initial> 06AF;;;;N;;;;;\nFB95;ARABIC LETTER GAF MEDIAL FORM;Lo;0;AL;<medial> 06AF;;;;N;;;;;\nFB96;ARABIC LETTER GUEH ISOLATED FORM;Lo;0;AL;<isolated> 06B3;;;;N;;;;;\nFB97;ARABIC LETTER GUEH FINAL FORM;Lo;0;AL;<final> 06B3;;;;N;;;;;\nFB98;ARABIC LETTER GUEH INITIAL FORM;Lo;0;AL;<initial> 06B3;;;;N;;;;;\nFB99;ARABIC LETTER GUEH MEDIAL FORM;Lo;0;AL;<medial> 06B3;;;;N;;;;;\nFB9A;ARABIC LETTER NGOEH ISOLATED FORM;Lo;0;AL;<isolated> 06B1;;;;N;;;;;\nFB9B;ARABIC LETTER NGOEH FINAL FORM;Lo;0;AL;<final> 06B1;;;;N;;;;;\nFB9C;ARABIC LETTER NGOEH INITIAL FORM;Lo;0;AL;<initial> 06B1;;;;N;;;;;\nFB9D;ARABIC LETTER NGOEH MEDIAL FORM;Lo;0;AL;<medial> 06B1;;;;N;;;;;\nFB9E;ARABIC LETTER NOON GHUNNA ISOLATED FORM;Lo;0;AL;<isolated> 06BA;;;;N;;;;;\nFB9F;ARABIC LETTER NOON GHUNNA FINAL FORM;Lo;0;AL;<final> 06BA;;;;N;;;;;\nFBA0;ARABIC LETTER RNOON ISOLATED FORM;Lo;0;AL;<isolated> 06BB;;;;N;;;;;\nFBA1;ARABIC LETTER RNOON FINAL FORM;Lo;0;AL;<final> 06BB;;;;N;;;;;\nFBA2;ARABIC LETTER RNOON INITIAL FORM;Lo;0;AL;<initial> 06BB;;;;N;;;;;\nFBA3;ARABIC LETTER RNOON MEDIAL FORM;Lo;0;AL;<medial> 06BB;;;;N;;;;;\nFBA4;ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 06C0;;;;N;;;;;\nFBA5;ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM;Lo;0;AL;<final> 06C0;;;;N;;;;;\nFBA6;ARABIC LETTER HEH GOAL ISOLATED FORM;Lo;0;AL;<isolated> 06C1;;;;N;;;;;\nFBA7;ARABIC LETTER HEH GOAL FINAL FORM;Lo;0;AL;<final> 06C1;;;;N;;;;;\nFBA8;ARABIC LETTER HEH GOAL INITIAL FORM;Lo;0;AL;<initial> 06C1;;;;N;;;;;\nFBA9;ARABIC LETTER HEH GOAL MEDIAL FORM;Lo;0;AL;<medial> 06C1;;;;N;;;;;\nFBAA;ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM;Lo;0;AL;<isolated> 06BE;;;;N;;;;;\nFBAB;ARABIC LETTER HEH DOACHASHMEE FINAL FORM;Lo;0;AL;<final> 06BE;;;;N;;;;;\nFBAC;ARABIC LETTER HEH DOACHASHMEE INITIAL FORM;Lo;0;AL;<initial> 06BE;;;;N;;;;;\nFBAD;ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM;Lo;0;AL;<medial> 06BE;;;;N;;;;;\nFBAE;ARABIC LETTER YEH BARREE ISOLATED FORM;Lo;0;AL;<isolated> 06D2;;;;N;;;;;\nFBAF;ARABIC LETTER YEH BARREE FINAL FORM;Lo;0;AL;<final> 06D2;;;;N;;;;;\nFBB0;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 06D3;;;;N;;;;;\nFBB1;ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 06D3;;;;N;;;;;\nFBB2;ARABIC SYMBOL DOT ABOVE;Sk;0;AL;;;;;N;;;;;\nFBB3;ARABIC SYMBOL DOT BELOW;Sk;0;AL;;;;;N;;;;;\nFBB4;ARABIC SYMBOL TWO DOTS ABOVE;Sk;0;AL;;;;;N;;;;;\nFBB5;ARABIC SYMBOL TWO DOTS BELOW;Sk;0;AL;;;;;N;;;;;\nFBB6;ARABIC SYMBOL THREE DOTS ABOVE;Sk;0;AL;;;;;N;;;;;\nFBB7;ARABIC SYMBOL THREE DOTS BELOW;Sk;0;AL;;;;;N;;;;;\nFBB8;ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS ABOVE;Sk;0;AL;;;;;N;;;;;\nFBB9;ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS BELOW;Sk;0;AL;;;;;N;;;;;\nFBBA;ARABIC SYMBOL FOUR DOTS ABOVE;Sk;0;AL;;;;;N;;;;;\nFBBB;ARABIC SYMBOL FOUR DOTS BELOW;Sk;0;AL;;;;;N;;;;;\nFBBC;ARABIC SYMBOL DOUBLE VERTICAL BAR BELOW;Sk;0;AL;;;;;N;;;;;\nFBBD;ARABIC SYMBOL TWO DOTS VERTICALLY ABOVE;Sk;0;AL;;;;;N;;;;;\nFBBE;ARABIC SYMBOL TWO DOTS VERTICALLY BELOW;Sk;0;AL;;;;;N;;;;;\nFBBF;ARABIC SYMBOL RING;Sk;0;AL;;;;;N;;;;;\nFBC0;ARABIC SYMBOL SMALL TAH ABOVE;Sk;0;AL;;;;;N;;;;;\nFBC1;ARABIC SYMBOL SMALL TAH BELOW;Sk;0;AL;;;;;N;;;;;\nFBD3;ARABIC LETTER NG ISOLATED FORM;Lo;0;AL;<isolated> 06AD;;;;N;;;;;\nFBD4;ARABIC LETTER NG FINAL FORM;Lo;0;AL;<final> 06AD;;;;N;;;;;\nFBD5;ARABIC LETTER NG INITIAL FORM;Lo;0;AL;<initial> 06AD;;;;N;;;;;\nFBD6;ARABIC LETTER NG MEDIAL FORM;Lo;0;AL;<medial> 06AD;;;;N;;;;;\nFBD7;ARABIC LETTER U ISOLATED FORM;Lo;0;AL;<isolated> 06C7;;;;N;;;;;\nFBD8;ARABIC LETTER U FINAL FORM;Lo;0;AL;<final> 06C7;;;;N;;;;;\nFBD9;ARABIC LETTER OE ISOLATED FORM;Lo;0;AL;<isolated> 06C6;;;;N;;;;;\nFBDA;ARABIC LETTER OE FINAL FORM;Lo;0;AL;<final> 06C6;;;;N;;;;;\nFBDB;ARABIC LETTER YU ISOLATED FORM;Lo;0;AL;<isolated> 06C8;;;;N;;;;;\nFBDC;ARABIC LETTER YU FINAL FORM;Lo;0;AL;<final> 06C8;;;;N;;;;;\nFBDD;ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0677;;;;N;;;;;\nFBDE;ARABIC LETTER VE ISOLATED FORM;Lo;0;AL;<isolated> 06CB;;;;N;;;;;\nFBDF;ARABIC LETTER VE FINAL FORM;Lo;0;AL;<final> 06CB;;;;N;;;;;\nFBE0;ARABIC LETTER KIRGHIZ OE ISOLATED FORM;Lo;0;AL;<isolated> 06C5;;;;N;;;;;\nFBE1;ARABIC LETTER KIRGHIZ OE FINAL FORM;Lo;0;AL;<final> 06C5;;;;N;;;;;\nFBE2;ARABIC LETTER KIRGHIZ YU ISOLATED FORM;Lo;0;AL;<isolated> 06C9;;;;N;;;;;\nFBE3;ARABIC LETTER KIRGHIZ YU FINAL FORM;Lo;0;AL;<final> 06C9;;;;N;;;;;\nFBE4;ARABIC LETTER E ISOLATED FORM;Lo;0;AL;<isolated> 06D0;;;;N;;;;;\nFBE5;ARABIC LETTER E FINAL FORM;Lo;0;AL;<final> 06D0;;;;N;;;;;\nFBE6;ARABIC LETTER E INITIAL FORM;Lo;0;AL;<initial> 06D0;;;;N;;;;;\nFBE7;ARABIC LETTER E MEDIAL FORM;Lo;0;AL;<medial> 06D0;;;;N;;;;;\nFBE8;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM;Lo;0;AL;<initial> 0649;;;;N;;;;;\nFBE9;ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM;Lo;0;AL;<medial> 0649;;;;N;;;;;\nFBEA;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0626 0627;;;;N;;;;;\nFBEB;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM;Lo;0;AL;<final> 0626 0627;;;;N;;;;;\nFBEC;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM;Lo;0;AL;<isolated> 0626 06D5;;;;N;;;;;\nFBED;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM;Lo;0;AL;<final> 0626 06D5;;;;N;;;;;\nFBEE;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM;Lo;0;AL;<isolated> 0626 0648;;;;N;;;;;\nFBEF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM;Lo;0;AL;<final> 0626 0648;;;;N;;;;;\nFBF0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM;Lo;0;AL;<isolated> 0626 06C7;;;;N;;;;;\nFBF1;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM;Lo;0;AL;<final> 0626 06C7;;;;N;;;;;\nFBF2;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM;Lo;0;AL;<isolated> 0626 06C6;;;;N;;;;;\nFBF3;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM;Lo;0;AL;<final> 0626 06C6;;;;N;;;;;\nFBF4;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM;Lo;0;AL;<isolated> 0626 06C8;;;;N;;;;;\nFBF5;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM;Lo;0;AL;<final> 0626 06C8;;;;N;;;;;\nFBF6;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM;Lo;0;AL;<isolated> 0626 06D0;;;;N;;;;;\nFBF7;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM;Lo;0;AL;<final> 0626 06D0;;;;N;;;;;\nFBF8;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM;Lo;0;AL;<initial> 0626 06D0;;;;N;;;;;\nFBF9;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0626 0649;;;;N;;;;;\nFBFA;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0626 0649;;;;N;;;;;\nFBFB;ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM;Lo;0;AL;<initial> 0626 0649;;;;N;;;;;\nFBFC;ARABIC LETTER FARSI YEH ISOLATED FORM;Lo;0;AL;<isolated> 06CC;;;;N;;;;;\nFBFD;ARABIC LETTER FARSI YEH FINAL FORM;Lo;0;AL;<final> 06CC;;;;N;;;;;\nFBFE;ARABIC LETTER FARSI YEH INITIAL FORM;Lo;0;AL;<initial> 06CC;;;;N;;;;;\nFBFF;ARABIC LETTER FARSI YEH MEDIAL FORM;Lo;0;AL;<medial> 06CC;;;;N;;;;;\nFC00;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0626 062C;;;;N;;;;;\nFC01;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0626 062D;;;;N;;;;;\nFC02;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0626 0645;;;;N;;;;;\nFC03;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0626 0649;;;;N;;;;;\nFC04;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0626 064A;;;;N;;;;;\nFC05;ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0628 062C;;;;N;;;;;\nFC06;ARABIC LIGATURE BEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0628 062D;;;;N;;;;;\nFC07;ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0628 062E;;;;N;;;;;\nFC08;ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0628 0645;;;;N;;;;;\nFC09;ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0628 0649;;;;N;;;;;\nFC0A;ARABIC LIGATURE BEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0628 064A;;;;N;;;;;\nFC0B;ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062A 062C;;;;N;;;;;\nFC0C;ARABIC LIGATURE TEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 062A 062D;;;;N;;;;;\nFC0D;ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 062A 062E;;;;N;;;;;\nFC0E;ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062A 0645;;;;N;;;;;\nFC0F;ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062A 0649;;;;N;;;;;\nFC10;ARABIC LIGATURE TEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062A 064A;;;;N;;;;;\nFC11;ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062B 062C;;;;N;;;;;\nFC12;ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062B 0645;;;;N;;;;;\nFC13;ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062B 0649;;;;N;;;;;\nFC14;ARABIC LIGATURE THEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062B 064A;;;;N;;;;;\nFC15;ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 062C 062D;;;;N;;;;;\nFC16;ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062C 0645;;;;N;;;;;\nFC17;ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062D 062C;;;;N;;;;;\nFC18;ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062D 0645;;;;N;;;;;\nFC19;ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062E 062C;;;;N;;;;;\nFC1A;ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 062E 062D;;;;N;;;;;\nFC1B;ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 062E 0645;;;;N;;;;;\nFC1C;ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0633 062C;;;;N;;;;;\nFC1D;ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0633 062D;;;;N;;;;;\nFC1E;ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0633 062E;;;;N;;;;;\nFC1F;ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0633 0645;;;;N;;;;;\nFC20;ARABIC LIGATURE SAD WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0635 062D;;;;N;;;;;\nFC21;ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0635 0645;;;;N;;;;;\nFC22;ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0636 062C;;;;N;;;;;\nFC23;ARABIC LIGATURE DAD WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0636 062D;;;;N;;;;;\nFC24;ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0636 062E;;;;N;;;;;\nFC25;ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0636 0645;;;;N;;;;;\nFC26;ARABIC LIGATURE TAH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0637 062D;;;;N;;;;;\nFC27;ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0637 0645;;;;N;;;;;\nFC28;ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0638 0645;;;;N;;;;;\nFC29;ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0639 062C;;;;N;;;;;\nFC2A;ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0639 0645;;;;N;;;;;\nFC2B;ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 063A 062C;;;;N;;;;;\nFC2C;ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 063A 0645;;;;N;;;;;\nFC2D;ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0641 062C;;;;N;;;;;\nFC2E;ARABIC LIGATURE FEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0641 062D;;;;N;;;;;\nFC2F;ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0641 062E;;;;N;;;;;\nFC30;ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0641 0645;;;;N;;;;;\nFC31;ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0641 0649;;;;N;;;;;\nFC32;ARABIC LIGATURE FEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0641 064A;;;;N;;;;;\nFC33;ARABIC LIGATURE QAF WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0642 062D;;;;N;;;;;\nFC34;ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0642 0645;;;;N;;;;;\nFC35;ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0642 0649;;;;N;;;;;\nFC36;ARABIC LIGATURE QAF WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0642 064A;;;;N;;;;;\nFC37;ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0643 0627;;;;N;;;;;\nFC38;ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0643 062C;;;;N;;;;;\nFC39;ARABIC LIGATURE KAF WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0643 062D;;;;N;;;;;\nFC3A;ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0643 062E;;;;N;;;;;\nFC3B;ARABIC LIGATURE KAF WITH LAM ISOLATED FORM;Lo;0;AL;<isolated> 0643 0644;;;;N;;;;;\nFC3C;ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0643 0645;;;;N;;;;;\nFC3D;ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0643 0649;;;;N;;;;;\nFC3E;ARABIC LIGATURE KAF WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0643 064A;;;;N;;;;;\nFC3F;ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0644 062C;;;;N;;;;;\nFC40;ARABIC LIGATURE LAM WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0644 062D;;;;N;;;;;\nFC41;ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0644 062E;;;;N;;;;;\nFC42;ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0644 0645;;;;N;;;;;\nFC43;ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0644 0649;;;;N;;;;;\nFC44;ARABIC LIGATURE LAM WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0644 064A;;;;N;;;;;\nFC45;ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0645 062C;;;;N;;;;;\nFC46;ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0645 062D;;;;N;;;;;\nFC47;ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0645 062E;;;;N;;;;;\nFC48;ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0645 0645;;;;N;;;;;\nFC49;ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0645 0649;;;;N;;;;;\nFC4A;ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0645 064A;;;;N;;;;;\nFC4B;ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0646 062C;;;;N;;;;;\nFC4C;ARABIC LIGATURE NOON WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0646 062D;;;;N;;;;;\nFC4D;ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0646 062E;;;;N;;;;;\nFC4E;ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0646 0645;;;;N;;;;;\nFC4F;ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0646 0649;;;;N;;;;;\nFC50;ARABIC LIGATURE NOON WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0646 064A;;;;N;;;;;\nFC51;ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0647 062C;;;;N;;;;;\nFC52;ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0647 0645;;;;N;;;;;\nFC53;ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0647 0649;;;;N;;;;;\nFC54;ARABIC LIGATURE HEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0647 064A;;;;N;;;;;\nFC55;ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 064A 062C;;;;N;;;;;\nFC56;ARABIC LIGATURE YEH WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 064A 062D;;;;N;;;;;\nFC57;ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 064A 062E;;;;N;;;;;\nFC58;ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 064A 0645;;;;N;;;;;\nFC59;ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 064A 0649;;;;N;;;;;\nFC5A;ARABIC LIGATURE YEH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 064A 064A;;;;N;;;;;\nFC5B;ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0630 0670;;;;N;;;;;\nFC5C;ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0631 0670;;;;N;;;;;\nFC5D;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0649 0670;;;;N;;;;;\nFC5E;ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064C 0651;;;;N;;;;;\nFC5F;ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064D 0651;;;;N;;;;;\nFC60;ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064E 0651;;;;N;;;;;\nFC61;ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064F 0651;;;;N;;;;;\nFC62;ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM;Lo;0;AL;<isolated> 0020 0650 0651;;;;N;;;;;\nFC63;ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0020 0651 0670;;;;N;;;;;\nFC64;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM;Lo;0;AL;<final> 0626 0631;;;;N;;;;;\nFC65;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM;Lo;0;AL;<final> 0626 0632;;;;N;;;;;\nFC66;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM;Lo;0;AL;<final> 0626 0645;;;;N;;;;;\nFC67;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM;Lo;0;AL;<final> 0626 0646;;;;N;;;;;\nFC68;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0626 0649;;;;N;;;;;\nFC69;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM;Lo;0;AL;<final> 0626 064A;;;;N;;;;;\nFC6A;ARABIC LIGATURE BEH WITH REH FINAL FORM;Lo;0;AL;<final> 0628 0631;;;;N;;;;;\nFC6B;ARABIC LIGATURE BEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 0628 0632;;;;N;;;;;\nFC6C;ARABIC LIGATURE BEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0628 0645;;;;N;;;;;\nFC6D;ARABIC LIGATURE BEH WITH NOON FINAL FORM;Lo;0;AL;<final> 0628 0646;;;;N;;;;;\nFC6E;ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0628 0649;;;;N;;;;;\nFC6F;ARABIC LIGATURE BEH WITH YEH FINAL FORM;Lo;0;AL;<final> 0628 064A;;;;N;;;;;\nFC70;ARABIC LIGATURE TEH WITH REH FINAL FORM;Lo;0;AL;<final> 062A 0631;;;;N;;;;;\nFC71;ARABIC LIGATURE TEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 062A 0632;;;;N;;;;;\nFC72;ARABIC LIGATURE TEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 062A 0645;;;;N;;;;;\nFC73;ARABIC LIGATURE TEH WITH NOON FINAL FORM;Lo;0;AL;<final> 062A 0646;;;;N;;;;;\nFC74;ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 0649;;;;N;;;;;\nFC75;ARABIC LIGATURE TEH WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 064A;;;;N;;;;;\nFC76;ARABIC LIGATURE THEH WITH REH FINAL FORM;Lo;0;AL;<final> 062B 0631;;;;N;;;;;\nFC77;ARABIC LIGATURE THEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 062B 0632;;;;N;;;;;\nFC78;ARABIC LIGATURE THEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 062B 0645;;;;N;;;;;\nFC79;ARABIC LIGATURE THEH WITH NOON FINAL FORM;Lo;0;AL;<final> 062B 0646;;;;N;;;;;\nFC7A;ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062B 0649;;;;N;;;;;\nFC7B;ARABIC LIGATURE THEH WITH YEH FINAL FORM;Lo;0;AL;<final> 062B 064A;;;;N;;;;;\nFC7C;ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0641 0649;;;;N;;;;;\nFC7D;ARABIC LIGATURE FEH WITH YEH FINAL FORM;Lo;0;AL;<final> 0641 064A;;;;N;;;;;\nFC7E;ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0642 0649;;;;N;;;;;\nFC7F;ARABIC LIGATURE QAF WITH YEH FINAL FORM;Lo;0;AL;<final> 0642 064A;;;;N;;;;;\nFC80;ARABIC LIGATURE KAF WITH ALEF FINAL FORM;Lo;0;AL;<final> 0643 0627;;;;N;;;;;\nFC81;ARABIC LIGATURE KAF WITH LAM FINAL FORM;Lo;0;AL;<final> 0643 0644;;;;N;;;;;\nFC82;ARABIC LIGATURE KAF WITH MEEM FINAL FORM;Lo;0;AL;<final> 0643 0645;;;;N;;;;;\nFC83;ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0643 0649;;;;N;;;;;\nFC84;ARABIC LIGATURE KAF WITH YEH FINAL FORM;Lo;0;AL;<final> 0643 064A;;;;N;;;;;\nFC85;ARABIC LIGATURE LAM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 0645;;;;N;;;;;\nFC86;ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0644 0649;;;;N;;;;;\nFC87;ARABIC LIGATURE LAM WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 064A;;;;N;;;;;\nFC88;ARABIC LIGATURE MEEM WITH ALEF FINAL FORM;Lo;0;AL;<final> 0645 0627;;;;N;;;;;\nFC89;ARABIC LIGATURE MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0645 0645;;;;N;;;;;\nFC8A;ARABIC LIGATURE NOON WITH REH FINAL FORM;Lo;0;AL;<final> 0646 0631;;;;N;;;;;\nFC8B;ARABIC LIGATURE NOON WITH ZAIN FINAL FORM;Lo;0;AL;<final> 0646 0632;;;;N;;;;;\nFC8C;ARABIC LIGATURE NOON WITH MEEM FINAL FORM;Lo;0;AL;<final> 0646 0645;;;;N;;;;;\nFC8D;ARABIC LIGATURE NOON WITH NOON FINAL FORM;Lo;0;AL;<final> 0646 0646;;;;N;;;;;\nFC8E;ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 0649;;;;N;;;;;\nFC8F;ARABIC LIGATURE NOON WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 064A;;;;N;;;;;\nFC90;ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM;Lo;0;AL;<final> 0649 0670;;;;N;;;;;\nFC91;ARABIC LIGATURE YEH WITH REH FINAL FORM;Lo;0;AL;<final> 064A 0631;;;;N;;;;;\nFC92;ARABIC LIGATURE YEH WITH ZAIN FINAL FORM;Lo;0;AL;<final> 064A 0632;;;;N;;;;;\nFC93;ARABIC LIGATURE YEH WITH MEEM FINAL FORM;Lo;0;AL;<final> 064A 0645;;;;N;;;;;\nFC94;ARABIC LIGATURE YEH WITH NOON FINAL FORM;Lo;0;AL;<final> 064A 0646;;;;N;;;;;\nFC95;ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 064A 0649;;;;N;;;;;\nFC96;ARABIC LIGATURE YEH WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 064A;;;;N;;;;;\nFC97;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0626 062C;;;;N;;;;;\nFC98;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0626 062D;;;;N;;;;;\nFC99;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0626 062E;;;;N;;;;;\nFC9A;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0626 0645;;;;N;;;;;\nFC9B;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0626 0647;;;;N;;;;;\nFC9C;ARABIC LIGATURE BEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0628 062C;;;;N;;;;;\nFC9D;ARABIC LIGATURE BEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0628 062D;;;;N;;;;;\nFC9E;ARABIC LIGATURE BEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0628 062E;;;;N;;;;;\nFC9F;ARABIC LIGATURE BEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0628 0645;;;;N;;;;;\nFCA0;ARABIC LIGATURE BEH WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0628 0647;;;;N;;;;;\nFCA1;ARABIC LIGATURE TEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062C;;;;N;;;;;\nFCA2;ARABIC LIGATURE TEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062A 062D;;;;N;;;;;\nFCA3;ARABIC LIGATURE TEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 062A 062E;;;;N;;;;;\nFCA4;ARABIC LIGATURE TEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 0645;;;;N;;;;;\nFCA5;ARABIC LIGATURE TEH WITH HEH INITIAL FORM;Lo;0;AL;<initial> 062A 0647;;;;N;;;;;\nFCA6;ARABIC LIGATURE THEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062B 0645;;;;N;;;;;\nFCA7;ARABIC LIGATURE JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062C 062D;;;;N;;;;;\nFCA8;ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062C 0645;;;;N;;;;;\nFCA9;ARABIC LIGATURE HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062D 062C;;;;N;;;;;\nFCAA;ARABIC LIGATURE HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062D 0645;;;;N;;;;;\nFCAB;ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062E 062C;;;;N;;;;;\nFCAC;ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062E 0645;;;;N;;;;;\nFCAD;ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0633 062C;;;;N;;;;;\nFCAE;ARABIC LIGATURE SEEN WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0633 062D;;;;N;;;;;\nFCAF;ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0633 062E;;;;N;;;;;\nFCB0;ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0633 0645;;;;N;;;;;\nFCB1;ARABIC LIGATURE SAD WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0635 062D;;;;N;;;;;\nFCB2;ARABIC LIGATURE SAD WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0635 062E;;;;N;;;;;\nFCB3;ARABIC LIGATURE SAD WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0635 0645;;;;N;;;;;\nFCB4;ARABIC LIGATURE DAD WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0636 062C;;;;N;;;;;\nFCB5;ARABIC LIGATURE DAD WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0636 062D;;;;N;;;;;\nFCB6;ARABIC LIGATURE DAD WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0636 062E;;;;N;;;;;\nFCB7;ARABIC LIGATURE DAD WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0636 0645;;;;N;;;;;\nFCB8;ARABIC LIGATURE TAH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0637 062D;;;;N;;;;;\nFCB9;ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0638 0645;;;;N;;;;;\nFCBA;ARABIC LIGATURE AIN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0639 062C;;;;N;;;;;\nFCBB;ARABIC LIGATURE AIN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639 0645;;;;N;;;;;\nFCBC;ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 063A 062C;;;;N;;;;;\nFCBD;ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 063A 0645;;;;N;;;;;\nFCBE;ARABIC LIGATURE FEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0641 062C;;;;N;;;;;\nFCBF;ARABIC LIGATURE FEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0641 062D;;;;N;;;;;\nFCC0;ARABIC LIGATURE FEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0641 062E;;;;N;;;;;\nFCC1;ARABIC LIGATURE FEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0641 0645;;;;N;;;;;\nFCC2;ARABIC LIGATURE QAF WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0642 062D;;;;N;;;;;\nFCC3;ARABIC LIGATURE QAF WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0642 0645;;;;N;;;;;\nFCC4;ARABIC LIGATURE KAF WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0643 062C;;;;N;;;;;\nFCC5;ARABIC LIGATURE KAF WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0643 062D;;;;N;;;;;\nFCC6;ARABIC LIGATURE KAF WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0643 062E;;;;N;;;;;\nFCC7;ARABIC LIGATURE KAF WITH LAM INITIAL FORM;Lo;0;AL;<initial> 0643 0644;;;;N;;;;;\nFCC8;ARABIC LIGATURE KAF WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0643 0645;;;;N;;;;;\nFCC9;ARABIC LIGATURE LAM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062C;;;;N;;;;;\nFCCA;ARABIC LIGATURE LAM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0644 062D;;;;N;;;;;\nFCCB;ARABIC LIGATURE LAM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0644 062E;;;;N;;;;;\nFCCC;ARABIC LIGATURE LAM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 0645;;;;N;;;;;\nFCCD;ARABIC LIGATURE LAM WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0644 0647;;;;N;;;;;\nFCCE;ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062C;;;;N;;;;;\nFCCF;ARABIC LIGATURE MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0645 062D;;;;N;;;;;\nFCD0;ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0645 062E;;;;N;;;;;\nFCD1;ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 0645;;;;N;;;;;\nFCD2;ARABIC LIGATURE NOON WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0646 062C;;;;N;;;;;\nFCD3;ARABIC LIGATURE NOON WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0646 062D;;;;N;;;;;\nFCD4;ARABIC LIGATURE NOON WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0646 062E;;;;N;;;;;\nFCD5;ARABIC LIGATURE NOON WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0646 0645;;;;N;;;;;\nFCD6;ARABIC LIGATURE NOON WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0646 0647;;;;N;;;;;\nFCD7;ARABIC LIGATURE HEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0647 062C;;;;N;;;;;\nFCD8;ARABIC LIGATURE HEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0647 0645;;;;N;;;;;\nFCD9;ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM;Lo;0;AL;<initial> 0647 0670;;;;N;;;;;\nFCDA;ARABIC LIGATURE YEH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 064A 062C;;;;N;;;;;\nFCDB;ARABIC LIGATURE YEH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 064A 062D;;;;N;;;;;\nFCDC;ARABIC LIGATURE YEH WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 064A 062E;;;;N;;;;;\nFCDD;ARABIC LIGATURE YEH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 064A 0645;;;;N;;;;;\nFCDE;ARABIC LIGATURE YEH WITH HEH INITIAL FORM;Lo;0;AL;<initial> 064A 0647;;;;N;;;;;\nFCDF;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0626 0645;;;;N;;;;;\nFCE0;ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0626 0647;;;;N;;;;;\nFCE1;ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0628 0645;;;;N;;;;;\nFCE2;ARABIC LIGATURE BEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0628 0647;;;;N;;;;;\nFCE3;ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 062A 0645;;;;N;;;;;\nFCE4;ARABIC LIGATURE TEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 062A 0647;;;;N;;;;;\nFCE5;ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 062B 0645;;;;N;;;;;\nFCE6;ARABIC LIGATURE THEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 062B 0647;;;;N;;;;;\nFCE7;ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0633 0645;;;;N;;;;;\nFCE8;ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0633 0647;;;;N;;;;;\nFCE9;ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0634 0645;;;;N;;;;;\nFCEA;ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0634 0647;;;;N;;;;;\nFCEB;ARABIC LIGATURE KAF WITH LAM MEDIAL FORM;Lo;0;AL;<medial> 0643 0644;;;;N;;;;;\nFCEC;ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0643 0645;;;;N;;;;;\nFCED;ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0644 0645;;;;N;;;;;\nFCEE;ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0646 0645;;;;N;;;;;\nFCEF;ARABIC LIGATURE NOON WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 0646 0647;;;;N;;;;;\nFCF0;ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 064A 0645;;;;N;;;;;\nFCF1;ARABIC LIGATURE YEH WITH HEH MEDIAL FORM;Lo;0;AL;<medial> 064A 0647;;;;N;;;;;\nFCF2;ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM;Lo;0;AL;<medial> 0640 064E 0651;;;;N;;;;;\nFCF3;ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM;Lo;0;AL;<medial> 0640 064F 0651;;;;N;;;;;\nFCF4;ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM;Lo;0;AL;<medial> 0640 0650 0651;;;;N;;;;;\nFCF5;ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0637 0649;;;;N;;;;;\nFCF6;ARABIC LIGATURE TAH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0637 064A;;;;N;;;;;\nFCF7;ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0639 0649;;;;N;;;;;\nFCF8;ARABIC LIGATURE AIN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0639 064A;;;;N;;;;;\nFCF9;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 063A 0649;;;;N;;;;;\nFCFA;ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 063A 064A;;;;N;;;;;\nFCFB;ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0633 0649;;;;N;;;;;\nFCFC;ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0633 064A;;;;N;;;;;\nFCFD;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0634 0649;;;;N;;;;;\nFCFE;ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0634 064A;;;;N;;;;;\nFCFF;ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062D 0649;;;;N;;;;;\nFD00;ARABIC LIGATURE HAH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062D 064A;;;;N;;;;;\nFD01;ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062C 0649;;;;N;;;;;\nFD02;ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062C 064A;;;;N;;;;;\nFD03;ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 062E 0649;;;;N;;;;;\nFD04;ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 062E 064A;;;;N;;;;;\nFD05;ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0635 0649;;;;N;;;;;\nFD06;ARABIC LIGATURE SAD WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0635 064A;;;;N;;;;;\nFD07;ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0636 0649;;;;N;;;;;\nFD08;ARABIC LIGATURE DAD WITH YEH ISOLATED FORM;Lo;0;AL;<isolated> 0636 064A;;;;N;;;;;\nFD09;ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM;Lo;0;AL;<isolated> 0634 062C;;;;N;;;;;\nFD0A;ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM;Lo;0;AL;<isolated> 0634 062D;;;;N;;;;;\nFD0B;ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM;Lo;0;AL;<isolated> 0634 062E;;;;N;;;;;\nFD0C;ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0634 0645;;;;N;;;;;\nFD0D;ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0634 0631;;;;N;;;;;\nFD0E;ARABIC LIGATURE SEEN WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0633 0631;;;;N;;;;;\nFD0F;ARABIC LIGATURE SAD WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0635 0631;;;;N;;;;;\nFD10;ARABIC LIGATURE DAD WITH REH ISOLATED FORM;Lo;0;AL;<isolated> 0636 0631;;;;N;;;;;\nFD11;ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0637 0649;;;;N;;;;;\nFD12;ARABIC LIGATURE TAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0637 064A;;;;N;;;;;\nFD13;ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0639 0649;;;;N;;;;;\nFD14;ARABIC LIGATURE AIN WITH YEH FINAL FORM;Lo;0;AL;<final> 0639 064A;;;;N;;;;;\nFD15;ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 063A 0649;;;;N;;;;;\nFD16;ARABIC LIGATURE GHAIN WITH YEH FINAL FORM;Lo;0;AL;<final> 063A 064A;;;;N;;;;;\nFD17;ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0633 0649;;;;N;;;;;\nFD18;ARABIC LIGATURE SEEN WITH YEH FINAL FORM;Lo;0;AL;<final> 0633 064A;;;;N;;;;;\nFD19;ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0634 0649;;;;N;;;;;\nFD1A;ARABIC LIGATURE SHEEN WITH YEH FINAL FORM;Lo;0;AL;<final> 0634 064A;;;;N;;;;;\nFD1B;ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062D 0649;;;;N;;;;;\nFD1C;ARABIC LIGATURE HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062D 064A;;;;N;;;;;\nFD1D;ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062C 0649;;;;N;;;;;\nFD1E;ARABIC LIGATURE JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062C 064A;;;;N;;;;;\nFD1F;ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062E 0649;;;;N;;;;;\nFD20;ARABIC LIGATURE KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062E 064A;;;;N;;;;;\nFD21;ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0635 0649;;;;N;;;;;\nFD22;ARABIC LIGATURE SAD WITH YEH FINAL FORM;Lo;0;AL;<final> 0635 064A;;;;N;;;;;\nFD23;ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0636 0649;;;;N;;;;;\nFD24;ARABIC LIGATURE DAD WITH YEH FINAL FORM;Lo;0;AL;<final> 0636 064A;;;;N;;;;;\nFD25;ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM;Lo;0;AL;<final> 0634 062C;;;;N;;;;;\nFD26;ARABIC LIGATURE SHEEN WITH HAH FINAL FORM;Lo;0;AL;<final> 0634 062D;;;;N;;;;;\nFD27;ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM;Lo;0;AL;<final> 0634 062E;;;;N;;;;;\nFD28;ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM;Lo;0;AL;<final> 0634 0645;;;;N;;;;;\nFD29;ARABIC LIGATURE SHEEN WITH REH FINAL FORM;Lo;0;AL;<final> 0634 0631;;;;N;;;;;\nFD2A;ARABIC LIGATURE SEEN WITH REH FINAL FORM;Lo;0;AL;<final> 0633 0631;;;;N;;;;;\nFD2B;ARABIC LIGATURE SAD WITH REH FINAL FORM;Lo;0;AL;<final> 0635 0631;;;;N;;;;;\nFD2C;ARABIC LIGATURE DAD WITH REH FINAL FORM;Lo;0;AL;<final> 0636 0631;;;;N;;;;;\nFD2D;ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0634 062C;;;;N;;;;;\nFD2E;ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0634 062D;;;;N;;;;;\nFD2F;ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0634 062E;;;;N;;;;;\nFD30;ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0634 0645;;;;N;;;;;\nFD31;ARABIC LIGATURE SEEN WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0633 0647;;;;N;;;;;\nFD32;ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM;Lo;0;AL;<initial> 0634 0647;;;;N;;;;;\nFD33;ARABIC LIGATURE TAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0637 0645;;;;N;;;;;\nFD34;ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM;Lo;0;AL;<medial> 0633 062C;;;;N;;;;;\nFD35;ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM;Lo;0;AL;<medial> 0633 062D;;;;N;;;;;\nFD36;ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM;Lo;0;AL;<medial> 0633 062E;;;;N;;;;;\nFD37;ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM;Lo;0;AL;<medial> 0634 062C;;;;N;;;;;\nFD38;ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM;Lo;0;AL;<medial> 0634 062D;;;;N;;;;;\nFD39;ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM;Lo;0;AL;<medial> 0634 062E;;;;N;;;;;\nFD3A;ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0637 0645;;;;N;;;;;\nFD3B;ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM;Lo;0;AL;<medial> 0638 0645;;;;N;;;;;\nFD3C;ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM;Lo;0;AL;<final> 0627 064B;;;;N;;;;;\nFD3D;ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM;Lo;0;AL;<isolated> 0627 064B;;;;N;;;;;\nFD3E;ORNATE LEFT PARENTHESIS;Pe;0;ON;;;;;N;;;;;\nFD3F;ORNATE RIGHT PARENTHESIS;Ps;0;ON;;;;;N;;;;;\nFD50;ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062C 0645;;;;N;;;;;\nFD51;ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM;Lo;0;AL;<final> 062A 062D 062C;;;;N;;;;;\nFD52;ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062D 062C;;;;N;;;;;\nFD53;ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062D 0645;;;;N;;;;;\nFD54;ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 062A 062E 0645;;;;N;;;;;\nFD55;ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 062A 0645 062C;;;;N;;;;;\nFD56;ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062A 0645 062D;;;;N;;;;;\nFD57;ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 062A 0645 062E;;;;N;;;;;\nFD58;ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 062C 0645 062D;;;;N;;;;;\nFD59;ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 062C 0645 062D;;;;N;;;;;\nFD5A;ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062D 0645 064A;;;;N;;;;;\nFD5B;ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062D 0645 0649;;;;N;;;;;\nFD5C;ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0633 062D 062C;;;;N;;;;;\nFD5D;ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0633 062C 062D;;;;N;;;;;\nFD5E;ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0633 062C 0649;;;;N;;;;;\nFD5F;ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0633 0645 062D;;;;N;;;;;\nFD60;ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0633 0645 062D;;;;N;;;;;\nFD61;ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0633 0645 062C;;;;N;;;;;\nFD62;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0633 0645 0645;;;;N;;;;;\nFD63;ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0633 0645 0645;;;;N;;;;;\nFD64;ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM;Lo;0;AL;<final> 0635 062D 062D;;;;N;;;;;\nFD65;ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0635 062D 062D;;;;N;;;;;\nFD66;ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0635 0645 0645;;;;N;;;;;\nFD67;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0634 062D 0645;;;;N;;;;;\nFD68;ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0634 062D 0645;;;;N;;;;;\nFD69;ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0634 062C 064A;;;;N;;;;;\nFD6A;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM;Lo;0;AL;<final> 0634 0645 062E;;;;N;;;;;\nFD6B;ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0634 0645 062E;;;;N;;;;;\nFD6C;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0634 0645 0645;;;;N;;;;;\nFD6D;ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0634 0645 0645;;;;N;;;;;\nFD6E;ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0636 062D 0649;;;;N;;;;;\nFD6F;ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0636 062E 0645;;;;N;;;;;\nFD70;ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0636 062E 0645;;;;N;;;;;\nFD71;ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0637 0645 062D;;;;N;;;;;\nFD72;ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0637 0645 062D;;;;N;;;;;\nFD73;ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0637 0645 0645;;;;N;;;;;\nFD74;ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0637 0645 064A;;;;N;;;;;\nFD75;ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0639 062C 0645;;;;N;;;;;\nFD76;ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0639 0645 0645;;;;N;;;;;\nFD77;ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639 0645 0645;;;;N;;;;;\nFD78;ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0639 0645 0649;;;;N;;;;;\nFD79;ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 063A 0645 0645;;;;N;;;;;\nFD7A;ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 063A 0645 064A;;;;N;;;;;\nFD7B;ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 063A 0645 0649;;;;N;;;;;\nFD7C;ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0641 062E 0645;;;;N;;;;;\nFD7D;ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0641 062E 0645;;;;N;;;;;\nFD7E;ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0642 0645 062D;;;;N;;;;;\nFD7F;ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0642 0645 0645;;;;N;;;;;\nFD80;ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 062D 0645;;;;N;;;;;\nFD81;ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 062D 064A;;;;N;;;;;\nFD82;ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0644 062D 0649;;;;N;;;;;\nFD83;ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062C 062C;;;;N;;;;;\nFD84;ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM;Lo;0;AL;<final> 0644 062C 062C;;;;N;;;;;\nFD85;ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 062E 0645;;;;N;;;;;\nFD86;ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062E 0645;;;;N;;;;;\nFD87;ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0644 0645 062D;;;;N;;;;;\nFD88;ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0644 0645 062D;;;;N;;;;;\nFD89;ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062D 062C;;;;N;;;;;\nFD8A;ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062D 0645;;;;N;;;;;\nFD8B;ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 062D 064A;;;;N;;;;;\nFD8C;ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0645 062C 062D;;;;N;;;;;\nFD8D;ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062C 0645;;;;N;;;;;\nFD8E;ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062E 062C;;;;N;;;;;\nFD8F;ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0645 062E 0645;;;;N;;;;;\nFD92;ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM;Lo;0;AL;<initial> 0645 062C 062E;;;;N;;;;;\nFD93;ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM;Lo;0;AL;<initial> 0647 0645 062C;;;;N;;;;;\nFD94;ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0647 0645 0645;;;;N;;;;;\nFD95;ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0646 062D 0645;;;;N;;;;;\nFD96;ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 062D 0649;;;;N;;;;;\nFD97;ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0646 062C 0645;;;;N;;;;;\nFD98;ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0646 062C 0645;;;;N;;;;;\nFD99;ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 062C 0649;;;;N;;;;;\nFD9A;ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 0645 064A;;;;N;;;;;\nFD9B;ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0646 0645 0649;;;;N;;;;;\nFD9C;ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 064A 0645 0645;;;;N;;;;;\nFD9D;ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 064A 0645 0645;;;;N;;;;;\nFD9E;ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0628 062E 064A;;;;N;;;;;\nFD9F;ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 062C 064A;;;;N;;;;;\nFDA0;ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 062C 0649;;;;N;;;;;\nFDA1;ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 062E 064A;;;;N;;;;;\nFDA2;ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 062E 0649;;;;N;;;;;\nFDA3;ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062A 0645 064A;;;;N;;;;;\nFDA4;ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062A 0645 0649;;;;N;;;;;\nFDA5;ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062C 0645 064A;;;;N;;;;;\nFDA6;ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062C 062D 0649;;;;N;;;;;\nFDA7;ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 062C 0645 0649;;;;N;;;;;\nFDA8;ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0633 062E 0649;;;;N;;;;;\nFDA9;ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0635 062D 064A;;;;N;;;;;\nFDAA;ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0634 062D 064A;;;;N;;;;;\nFDAB;ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0636 062D 064A;;;;N;;;;;\nFDAC;ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 062C 064A;;;;N;;;;;\nFDAD;ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0644 0645 064A;;;;N;;;;;\nFDAE;ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 062D 064A;;;;N;;;;;\nFDAF;ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 062C 064A;;;;N;;;;;\nFDB0;ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 064A 0645 064A;;;;N;;;;;\nFDB1;ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 0645 064A;;;;N;;;;;\nFDB2;ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0642 0645 064A;;;;N;;;;;\nFDB3;ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 062D 064A;;;;N;;;;;\nFDB4;ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0642 0645 062D;;;;N;;;;;\nFDB5;ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062D 0645;;;;N;;;;;\nFDB6;ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0639 0645 064A;;;;N;;;;;\nFDB7;ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0643 0645 064A;;;;N;;;;;\nFDB8;ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM;Lo;0;AL;<initial> 0646 062C 062D;;;;N;;;;;\nFDB9;ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 062E 064A;;;;N;;;;;\nFDBA;ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0644 062C 0645;;;;N;;;;;\nFDBB;ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0643 0645 0645;;;;N;;;;;\nFDBC;ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM;Lo;0;AL;<final> 0644 062C 0645;;;;N;;;;;\nFDBD;ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM;Lo;0;AL;<final> 0646 062C 062D;;;;N;;;;;\nFDBE;ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 062C 062D 064A;;;;N;;;;;\nFDBF;ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 062D 062C 064A;;;;N;;;;;\nFDC0;ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0645 062C 064A;;;;N;;;;;\nFDC1;ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0641 0645 064A;;;;N;;;;;\nFDC2;ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0628 062D 064A;;;;N;;;;;\nFDC3;ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0643 0645 0645;;;;N;;;;;\nFDC4;ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0639 062C 0645;;;;N;;;;;\nFDC5;ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM;Lo;0;AL;<initial> 0635 0645 0645;;;;N;;;;;\nFDC6;ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM;Lo;0;AL;<final> 0633 062E 064A;;;;N;;;;;\nFDC7;ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM;Lo;0;AL;<final> 0646 062C 064A;;;;N;;;;;\nFDF0;ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 06D2;;;;N;;;;;\nFDF1;ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM;Lo;0;AL;<isolated> 0642 0644 06D2;;;;N;;;;;\nFDF2;ARABIC LIGATURE ALLAH ISOLATED FORM;Lo;0;AL;<isolated> 0627 0644 0644 0647;;;;N;;;;;\nFDF3;ARABIC LIGATURE AKBAR ISOLATED FORM;Lo;0;AL;<isolated> 0627 0643 0628 0631;;;;N;;;;;\nFDF4;ARABIC LIGATURE MOHAMMAD ISOLATED FORM;Lo;0;AL;<isolated> 0645 062D 0645 062F;;;;N;;;;;\nFDF5;ARABIC LIGATURE SALAM ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 0639 0645;;;;N;;;;;\nFDF6;ARABIC LIGATURE RASOUL ISOLATED FORM;Lo;0;AL;<isolated> 0631 0633 0648 0644;;;;N;;;;;\nFDF7;ARABIC LIGATURE ALAYHE ISOLATED FORM;Lo;0;AL;<isolated> 0639 0644 064A 0647;;;;N;;;;;\nFDF8;ARABIC LIGATURE WASALLAM ISOLATED FORM;Lo;0;AL;<isolated> 0648 0633 0644 0645;;;;N;;;;;\nFDF9;ARABIC LIGATURE SALLA ISOLATED FORM;Lo;0;AL;<isolated> 0635 0644 0649;;;;N;;;;;\nFDFA;ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM;Lo;0;AL;<isolated> 0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645;;;;N;ARABIC LETTER SALLALLAHOU ALAYHE WASALLAM;;;;\nFDFB;ARABIC LIGATURE JALLAJALALOUHOU;Lo;0;AL;<isolated> 062C 0644 0020 062C 0644 0627 0644 0647;;;;N;ARABIC LETTER JALLAJALALOUHOU;;;;\nFDFC;RIAL SIGN;Sc;0;AL;<isolated> 0631 06CC 0627 0644;;;;N;;;;;\nFDFD;ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM;So;0;ON;;;;;N;;;;;\nFE00;VARIATION SELECTOR-1;Mn;0;NSM;;;;;N;;;;;\nFE01;VARIATION SELECTOR-2;Mn;0;NSM;;;;;N;;;;;\nFE02;VARIATION SELECTOR-3;Mn;0;NSM;;;;;N;;;;;\nFE03;VARIATION SELECTOR-4;Mn;0;NSM;;;;;N;;;;;\nFE04;VARIATION SELECTOR-5;Mn;0;NSM;;;;;N;;;;;\nFE05;VARIATION SELECTOR-6;Mn;0;NSM;;;;;N;;;;;\nFE06;VARIATION SELECTOR-7;Mn;0;NSM;;;;;N;;;;;\nFE07;VARIATION SELECTOR-8;Mn;0;NSM;;;;;N;;;;;\nFE08;VARIATION SELECTOR-9;Mn;0;NSM;;;;;N;;;;;\nFE09;VARIATION SELECTOR-10;Mn;0;NSM;;;;;N;;;;;\nFE0A;VARIATION SELECTOR-11;Mn;0;NSM;;;;;N;;;;;\nFE0B;VARIATION SELECTOR-12;Mn;0;NSM;;;;;N;;;;;\nFE0C;VARIATION SELECTOR-13;Mn;0;NSM;;;;;N;;;;;\nFE0D;VARIATION SELECTOR-14;Mn;0;NSM;;;;;N;;;;;\nFE0E;VARIATION SELECTOR-15;Mn;0;NSM;;;;;N;;;;;\nFE0F;VARIATION SELECTOR-16;Mn;0;NSM;;;;;N;;;;;\nFE10;PRESENTATION FORM FOR VERTICAL COMMA;Po;0;ON;<vertical> 002C;;;;N;;;;;\nFE11;PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA;Po;0;ON;<vertical> 3001;;;;N;;;;;\nFE12;PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP;Po;0;ON;<vertical> 3002;;;;N;;;;;\nFE13;PRESENTATION FORM FOR VERTICAL COLON;Po;0;ON;<vertical> 003A;;;;N;;;;;\nFE14;PRESENTATION FORM FOR VERTICAL SEMICOLON;Po;0;ON;<vertical> 003B;;;;N;;;;;\nFE15;PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK;Po;0;ON;<vertical> 0021;;;;N;;;;;\nFE16;PRESENTATION FORM FOR VERTICAL QUESTION MARK;Po;0;ON;<vertical> 003F;;;;N;;;;;\nFE17;PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET;Ps;0;ON;<vertical> 3016;;;;N;;;;;\nFE18;PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET;Pe;0;ON;<vertical> 3017;;;;N;;;;;\nFE19;PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS;Po;0;ON;<vertical> 2026;;;;N;;;;;\nFE20;COMBINING LIGATURE LEFT HALF;Mn;230;NSM;;;;;N;;;;;\nFE21;COMBINING LIGATURE RIGHT HALF;Mn;230;NSM;;;;;N;;;;;\nFE22;COMBINING DOUBLE TILDE LEFT HALF;Mn;230;NSM;;;;;N;;;;;\nFE23;COMBINING DOUBLE TILDE RIGHT HALF;Mn;230;NSM;;;;;N;;;;;\nFE24;COMBINING MACRON LEFT HALF;Mn;230;NSM;;;;;N;;;;;\nFE25;COMBINING MACRON RIGHT HALF;Mn;230;NSM;;;;;N;;;;;\nFE26;COMBINING CONJOINING MACRON;Mn;230;NSM;;;;;N;;;;;\nFE27;COMBINING LIGATURE LEFT HALF BELOW;Mn;220;NSM;;;;;N;;;;;\nFE28;COMBINING LIGATURE RIGHT HALF BELOW;Mn;220;NSM;;;;;N;;;;;\nFE29;COMBINING TILDE LEFT HALF BELOW;Mn;220;NSM;;;;;N;;;;;\nFE2A;COMBINING TILDE RIGHT HALF BELOW;Mn;220;NSM;;;;;N;;;;;\nFE2B;COMBINING MACRON LEFT HALF BELOW;Mn;220;NSM;;;;;N;;;;;\nFE2C;COMBINING MACRON RIGHT HALF BELOW;Mn;220;NSM;;;;;N;;;;;\nFE2D;COMBINING CONJOINING MACRON BELOW;Mn;220;NSM;;;;;N;;;;;\nFE2E;COMBINING CYRILLIC TITLO LEFT HALF;Mn;230;NSM;;;;;N;;;;;\nFE2F;COMBINING CYRILLIC TITLO RIGHT HALF;Mn;230;NSM;;;;;N;;;;;\nFE30;PRESENTATION FORM FOR VERTICAL TWO DOT LEADER;Po;0;ON;<vertical> 2025;;;;N;GLYPH FOR VERTICAL TWO DOT LEADER;;;;\nFE31;PRESENTATION FORM FOR VERTICAL EM DASH;Pd;0;ON;<vertical> 2014;;;;N;GLYPH FOR VERTICAL EM DASH;;;;\nFE32;PRESENTATION FORM FOR VERTICAL EN DASH;Pd;0;ON;<vertical> 2013;;;;N;GLYPH FOR VERTICAL EN DASH;;;;\nFE33;PRESENTATION FORM FOR VERTICAL LOW LINE;Pc;0;ON;<vertical> 005F;;;;N;GLYPH FOR VERTICAL SPACING UNDERSCORE;;;;\nFE34;PRESENTATION FORM FOR VERTICAL WAVY LOW LINE;Pc;0;ON;<vertical> 005F;;;;N;GLYPH FOR VERTICAL SPACING WAVY UNDERSCORE;;;;\nFE35;PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS;Ps;0;ON;<vertical> 0028;;;;N;GLYPH FOR VERTICAL OPENING PARENTHESIS;;;;\nFE36;PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS;Pe;0;ON;<vertical> 0029;;;;N;GLYPH FOR VERTICAL CLOSING PARENTHESIS;;;;\nFE37;PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET;Ps;0;ON;<vertical> 007B;;;;N;GLYPH FOR VERTICAL OPENING CURLY BRACKET;;;;\nFE38;PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET;Pe;0;ON;<vertical> 007D;;;;N;GLYPH FOR VERTICAL CLOSING CURLY BRACKET;;;;\nFE39;PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET;Ps;0;ON;<vertical> 3014;;;;N;GLYPH FOR VERTICAL OPENING TORTOISE SHELL BRACKET;;;;\nFE3A;PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;<vertical> 3015;;;;N;GLYPH FOR VERTICAL CLOSING TORTOISE SHELL BRACKET;;;;\nFE3B;PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET;Ps;0;ON;<vertical> 3010;;;;N;GLYPH FOR VERTICAL OPENING BLACK LENTICULAR BRACKET;;;;\nFE3C;PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET;Pe;0;ON;<vertical> 3011;;;;N;GLYPH FOR VERTICAL CLOSING BLACK LENTICULAR BRACKET;;;;\nFE3D;PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET;Ps;0;ON;<vertical> 300A;;;;N;GLYPH FOR VERTICAL OPENING DOUBLE ANGLE BRACKET;;;;\nFE3E;PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET;Pe;0;ON;<vertical> 300B;;;;N;GLYPH FOR VERTICAL CLOSING DOUBLE ANGLE BRACKET;;;;\nFE3F;PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET;Ps;0;ON;<vertical> 3008;;;;N;GLYPH FOR VERTICAL OPENING ANGLE BRACKET;;;;\nFE40;PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET;Pe;0;ON;<vertical> 3009;;;;N;GLYPH FOR VERTICAL CLOSING ANGLE BRACKET;;;;\nFE41;PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET;Ps;0;ON;<vertical> 300C;;;;N;GLYPH FOR VERTICAL OPENING CORNER BRACKET;;;;\nFE42;PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET;Pe;0;ON;<vertical> 300D;;;;N;GLYPH FOR VERTICAL CLOSING CORNER BRACKET;;;;\nFE43;PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET;Ps;0;ON;<vertical> 300E;;;;N;GLYPH FOR VERTICAL OPENING WHITE CORNER BRACKET;;;;\nFE44;PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET;Pe;0;ON;<vertical> 300F;;;;N;GLYPH FOR VERTICAL CLOSING WHITE CORNER BRACKET;;;;\nFE45;SESAME DOT;Po;0;ON;;;;;N;;;;;\nFE46;WHITE SESAME DOT;Po;0;ON;;;;;N;;;;;\nFE47;PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET;Ps;0;ON;<vertical> 005B;;;;N;;;;;\nFE48;PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET;Pe;0;ON;<vertical> 005D;;;;N;;;;;\nFE49;DASHED OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING DASHED OVERSCORE;;;;\nFE4A;CENTRELINE OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING CENTERLINE OVERSCORE;;;;\nFE4B;WAVY OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING WAVY OVERSCORE;;;;\nFE4C;DOUBLE WAVY OVERLINE;Po;0;ON;<compat> 203E;;;;N;SPACING DOUBLE WAVY OVERSCORE;;;;\nFE4D;DASHED LOW LINE;Pc;0;ON;<compat> 005F;;;;N;SPACING DASHED UNDERSCORE;;;;\nFE4E;CENTRELINE LOW LINE;Pc;0;ON;<compat> 005F;;;;N;SPACING CENTERLINE UNDERSCORE;;;;\nFE4F;WAVY LOW LINE;Pc;0;ON;<compat> 005F;;;;N;SPACING WAVY UNDERSCORE;;;;\nFE50;SMALL COMMA;Po;0;CS;<small> 002C;;;;N;;;;;\nFE51;SMALL IDEOGRAPHIC COMMA;Po;0;ON;<small> 3001;;;;N;;;;;\nFE52;SMALL FULL STOP;Po;0;CS;<small> 002E;;;;N;SMALL PERIOD;;;;\nFE54;SMALL SEMICOLON;Po;0;ON;<small> 003B;;;;N;;;;;\nFE55;SMALL COLON;Po;0;CS;<small> 003A;;;;N;;;;;\nFE56;SMALL QUESTION MARK;Po;0;ON;<small> 003F;;;;N;;;;;\nFE57;SMALL EXCLAMATION MARK;Po;0;ON;<small> 0021;;;;N;;;;;\nFE58;SMALL EM DASH;Pd;0;ON;<small> 2014;;;;N;;;;;\nFE59;SMALL LEFT PARENTHESIS;Ps;0;ON;<small> 0028;;;;Y;SMALL OPENING PARENTHESIS;;;;\nFE5A;SMALL RIGHT PARENTHESIS;Pe;0;ON;<small> 0029;;;;Y;SMALL CLOSING PARENTHESIS;;;;\nFE5B;SMALL LEFT CURLY BRACKET;Ps;0;ON;<small> 007B;;;;Y;SMALL OPENING CURLY BRACKET;;;;\nFE5C;SMALL RIGHT CURLY BRACKET;Pe;0;ON;<small> 007D;;;;Y;SMALL CLOSING CURLY BRACKET;;;;\nFE5D;SMALL LEFT TORTOISE SHELL BRACKET;Ps;0;ON;<small> 3014;;;;Y;SMALL OPENING TORTOISE SHELL BRACKET;;;;\nFE5E;SMALL RIGHT TORTOISE SHELL BRACKET;Pe;0;ON;<small> 3015;;;;Y;SMALL CLOSING TORTOISE SHELL BRACKET;;;;\nFE5F;SMALL NUMBER SIGN;Po;0;ET;<small> 0023;;;;N;;;;;\nFE60;SMALL AMPERSAND;Po;0;ON;<small> 0026;;;;N;;;;;\nFE61;SMALL ASTERISK;Po;0;ON;<small> 002A;;;;N;;;;;\nFE62;SMALL PLUS SIGN;Sm;0;ES;<small> 002B;;;;N;;;;;\nFE63;SMALL HYPHEN-MINUS;Pd;0;ES;<small> 002D;;;;N;;;;;\nFE64;SMALL LESS-THAN SIGN;Sm;0;ON;<small> 003C;;;;Y;;;;;\nFE65;SMALL GREATER-THAN SIGN;Sm;0;ON;<small> 003E;;;;Y;;;;;\nFE66;SMALL EQUALS SIGN;Sm;0;ON;<small> 003D;;;;N;;;;;\nFE68;SMALL REVERSE SOLIDUS;Po;0;ON;<small> 005C;;;;N;SMALL BACKSLASH;;;;\nFE69;SMALL DOLLAR SIGN;Sc;0;ET;<small> 0024;;;;N;;;;;\nFE6A;SMALL PERCENT SIGN;Po;0;ET;<small> 0025;;;;N;;;;;\nFE6B;SMALL COMMERCIAL AT;Po;0;ON;<small> 0040;;;;N;;;;;\nFE70;ARABIC FATHATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064B;;;;N;ARABIC SPACING FATHATAN;;;;\nFE71;ARABIC TATWEEL WITH FATHATAN ABOVE;Lo;0;AL;<medial> 0640 064B;;;;N;ARABIC FATHATAN ON TATWEEL;;;;\nFE72;ARABIC DAMMATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064C;;;;N;ARABIC SPACING DAMMATAN;;;;\nFE73;ARABIC TAIL FRAGMENT;Lo;0;AL;;;;;N;;;;;\nFE74;ARABIC KASRATAN ISOLATED FORM;Lo;0;AL;<isolated> 0020 064D;;;;N;ARABIC SPACING KASRATAN;;;;\nFE76;ARABIC FATHA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064E;;;;N;ARABIC SPACING FATHAH;;;;\nFE77;ARABIC FATHA MEDIAL FORM;Lo;0;AL;<medial> 0640 064E;;;;N;ARABIC FATHAH ON TATWEEL;;;;\nFE78;ARABIC DAMMA ISOLATED FORM;Lo;0;AL;<isolated> 0020 064F;;;;N;ARABIC SPACING DAMMAH;;;;\nFE79;ARABIC DAMMA MEDIAL FORM;Lo;0;AL;<medial> 0640 064F;;;;N;ARABIC DAMMAH ON TATWEEL;;;;\nFE7A;ARABIC KASRA ISOLATED FORM;Lo;0;AL;<isolated> 0020 0650;;;;N;ARABIC SPACING KASRAH;;;;\nFE7B;ARABIC KASRA MEDIAL FORM;Lo;0;AL;<medial> 0640 0650;;;;N;ARABIC KASRAH ON TATWEEL;;;;\nFE7C;ARABIC SHADDA ISOLATED FORM;Lo;0;AL;<isolated> 0020 0651;;;;N;ARABIC SPACING SHADDAH;;;;\nFE7D;ARABIC SHADDA MEDIAL FORM;Lo;0;AL;<medial> 0640 0651;;;;N;ARABIC SHADDAH ON TATWEEL;;;;\nFE7E;ARABIC SUKUN ISOLATED FORM;Lo;0;AL;<isolated> 0020 0652;;;;N;ARABIC SPACING SUKUN;;;;\nFE7F;ARABIC SUKUN MEDIAL FORM;Lo;0;AL;<medial> 0640 0652;;;;N;ARABIC SUKUN ON TATWEEL;;;;\nFE80;ARABIC LETTER HAMZA ISOLATED FORM;Lo;0;AL;<isolated> 0621;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH;;;;\nFE81;ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON ALEF;;;;\nFE82;ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL;<final> 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON ALEF;;;;\nFE83;ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON ALEF;;;;\nFE84;ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON ALEF;;;;\nFE85;ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0624;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON WAW;;;;\nFE86;ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0624;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON WAW;;;;\nFE87;ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL;<isolated> 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER ALEF;;;;\nFE88;ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL;<final> 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER ALEF;;;;\nFE89;ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0626;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON YA;;;;\nFE8A;ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0626;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON YA;;;;\nFE8B;ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM;Lo;0;AL;<initial> 0626;;;;N;GLYPH FOR INITIAL ARABIC HAMZAH ON YA;;;;\nFE8C;ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM;Lo;0;AL;<medial> 0626;;;;N;GLYPH FOR MEDIAL ARABIC HAMZAH ON YA;;;;\nFE8D;ARABIC LETTER ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0627;;;;N;GLYPH FOR ISOLATE ARABIC ALEF;;;;\nFE8E;ARABIC LETTER ALEF FINAL FORM;Lo;0;AL;<final> 0627;;;;N;GLYPH FOR FINAL ARABIC ALEF;;;;\nFE8F;ARABIC LETTER BEH ISOLATED FORM;Lo;0;AL;<isolated> 0628;;;;N;GLYPH FOR ISOLATE ARABIC BAA;;;;\nFE90;ARABIC LETTER BEH FINAL FORM;Lo;0;AL;<final> 0628;;;;N;GLYPH FOR FINAL ARABIC BAA;;;;\nFE91;ARABIC LETTER BEH INITIAL FORM;Lo;0;AL;<initial> 0628;;;;N;GLYPH FOR INITIAL ARABIC BAA;;;;\nFE92;ARABIC LETTER BEH MEDIAL FORM;Lo;0;AL;<medial> 0628;;;;N;GLYPH FOR MEDIAL ARABIC BAA;;;;\nFE93;ARABIC LETTER TEH MARBUTA ISOLATED FORM;Lo;0;AL;<isolated> 0629;;;;N;GLYPH FOR ISOLATE ARABIC TAA MARBUTAH;;;;\nFE94;ARABIC LETTER TEH MARBUTA FINAL FORM;Lo;0;AL;<final> 0629;;;;N;GLYPH FOR FINAL ARABIC TAA MARBUTAH;;;;\nFE95;ARABIC LETTER TEH ISOLATED FORM;Lo;0;AL;<isolated> 062A;;;;N;GLYPH FOR ISOLATE ARABIC TAA;;;;\nFE96;ARABIC LETTER TEH FINAL FORM;Lo;0;AL;<final> 062A;;;;N;GLYPH FOR FINAL ARABIC TAA;;;;\nFE97;ARABIC LETTER TEH INITIAL FORM;Lo;0;AL;<initial> 062A;;;;N;GLYPH FOR INITIAL ARABIC TAA;;;;\nFE98;ARABIC LETTER TEH MEDIAL FORM;Lo;0;AL;<medial> 062A;;;;N;GLYPH FOR MEDIAL ARABIC TAA;;;;\nFE99;ARABIC LETTER THEH ISOLATED FORM;Lo;0;AL;<isolated> 062B;;;;N;GLYPH FOR ISOLATE ARABIC THAA;;;;\nFE9A;ARABIC LETTER THEH FINAL FORM;Lo;0;AL;<final> 062B;;;;N;GLYPH FOR FINAL ARABIC THAA;;;;\nFE9B;ARABIC LETTER THEH INITIAL FORM;Lo;0;AL;<initial> 062B;;;;N;GLYPH FOR INITIAL ARABIC THAA;;;;\nFE9C;ARABIC LETTER THEH MEDIAL FORM;Lo;0;AL;<medial> 062B;;;;N;GLYPH FOR MEDIAL ARABIC THAA;;;;\nFE9D;ARABIC LETTER JEEM ISOLATED FORM;Lo;0;AL;<isolated> 062C;;;;N;GLYPH FOR ISOLATE ARABIC JEEM;;;;\nFE9E;ARABIC LETTER JEEM FINAL FORM;Lo;0;AL;<final> 062C;;;;N;GLYPH FOR FINAL ARABIC JEEM;;;;\nFE9F;ARABIC LETTER JEEM INITIAL FORM;Lo;0;AL;<initial> 062C;;;;N;GLYPH FOR INITIAL ARABIC JEEM;;;;\nFEA0;ARABIC LETTER JEEM MEDIAL FORM;Lo;0;AL;<medial> 062C;;;;N;GLYPH FOR MEDIAL ARABIC JEEM;;;;\nFEA1;ARABIC LETTER HAH ISOLATED FORM;Lo;0;AL;<isolated> 062D;;;;N;GLYPH FOR ISOLATE ARABIC HAA;;;;\nFEA2;ARABIC LETTER HAH FINAL FORM;Lo;0;AL;<final> 062D;;;;N;GLYPH FOR FINAL ARABIC HAA;;;;\nFEA3;ARABIC LETTER HAH INITIAL FORM;Lo;0;AL;<initial> 062D;;;;N;GLYPH FOR INITIAL ARABIC HAA;;;;\nFEA4;ARABIC LETTER HAH MEDIAL FORM;Lo;0;AL;<medial> 062D;;;;N;GLYPH FOR MEDIAL ARABIC HAA;;;;\nFEA5;ARABIC LETTER KHAH ISOLATED FORM;Lo;0;AL;<isolated> 062E;;;;N;GLYPH FOR ISOLATE ARABIC KHAA;;;;\nFEA6;ARABIC LETTER KHAH FINAL FORM;Lo;0;AL;<final> 062E;;;;N;GLYPH FOR FINAL ARABIC KHAA;;;;\nFEA7;ARABIC LETTER KHAH INITIAL FORM;Lo;0;AL;<initial> 062E;;;;N;GLYPH FOR INITIAL ARABIC KHAA;;;;\nFEA8;ARABIC LETTER KHAH MEDIAL FORM;Lo;0;AL;<medial> 062E;;;;N;GLYPH FOR MEDIAL ARABIC KHAA;;;;\nFEA9;ARABIC LETTER DAL ISOLATED FORM;Lo;0;AL;<isolated> 062F;;;;N;GLYPH FOR ISOLATE ARABIC DAL;;;;\nFEAA;ARABIC LETTER DAL FINAL FORM;Lo;0;AL;<final> 062F;;;;N;GLYPH FOR FINAL ARABIC DAL;;;;\nFEAB;ARABIC LETTER THAL ISOLATED FORM;Lo;0;AL;<isolated> 0630;;;;N;GLYPH FOR ISOLATE ARABIC THAL;;;;\nFEAC;ARABIC LETTER THAL FINAL FORM;Lo;0;AL;<final> 0630;;;;N;GLYPH FOR FINAL ARABIC THAL;;;;\nFEAD;ARABIC LETTER REH ISOLATED FORM;Lo;0;AL;<isolated> 0631;;;;N;GLYPH FOR ISOLATE ARABIC RA;;;;\nFEAE;ARABIC LETTER REH FINAL FORM;Lo;0;AL;<final> 0631;;;;N;GLYPH FOR FINAL ARABIC RA;;;;\nFEAF;ARABIC LETTER ZAIN ISOLATED FORM;Lo;0;AL;<isolated> 0632;;;;N;GLYPH FOR ISOLATE ARABIC ZAIN;;;;\nFEB0;ARABIC LETTER ZAIN FINAL FORM;Lo;0;AL;<final> 0632;;;;N;GLYPH FOR FINAL ARABIC ZAIN;;;;\nFEB1;ARABIC LETTER SEEN ISOLATED FORM;Lo;0;AL;<isolated> 0633;;;;N;GLYPH FOR ISOLATE ARABIC SEEN;;;;\nFEB2;ARABIC LETTER SEEN FINAL FORM;Lo;0;AL;<final> 0633;;;;N;GLYPH FOR FINAL ARABIC SEEN;;;;\nFEB3;ARABIC LETTER SEEN INITIAL FORM;Lo;0;AL;<initial> 0633;;;;N;GLYPH FOR INITIAL ARABIC SEEN;;;;\nFEB4;ARABIC LETTER SEEN MEDIAL FORM;Lo;0;AL;<medial> 0633;;;;N;GLYPH FOR MEDIAL ARABIC SEEN;;;;\nFEB5;ARABIC LETTER SHEEN ISOLATED FORM;Lo;0;AL;<isolated> 0634;;;;N;GLYPH FOR ISOLATE ARABIC SHEEN;;;;\nFEB6;ARABIC LETTER SHEEN FINAL FORM;Lo;0;AL;<final> 0634;;;;N;GLYPH FOR FINAL ARABIC SHEEN;;;;\nFEB7;ARABIC LETTER SHEEN INITIAL FORM;Lo;0;AL;<initial> 0634;;;;N;GLYPH FOR INITIAL ARABIC SHEEN;;;;\nFEB8;ARABIC LETTER SHEEN MEDIAL FORM;Lo;0;AL;<medial> 0634;;;;N;GLYPH FOR MEDIAL ARABIC SHEEN;;;;\nFEB9;ARABIC LETTER SAD ISOLATED FORM;Lo;0;AL;<isolated> 0635;;;;N;GLYPH FOR ISOLATE ARABIC SAD;;;;\nFEBA;ARABIC LETTER SAD FINAL FORM;Lo;0;AL;<final> 0635;;;;N;GLYPH FOR FINAL ARABIC SAD;;;;\nFEBB;ARABIC LETTER SAD INITIAL FORM;Lo;0;AL;<initial> 0635;;;;N;GLYPH FOR INITIAL ARABIC SAD;;;;\nFEBC;ARABIC LETTER SAD MEDIAL FORM;Lo;0;AL;<medial> 0635;;;;N;GLYPH FOR MEDIAL ARABIC SAD;;;;\nFEBD;ARABIC LETTER DAD ISOLATED FORM;Lo;0;AL;<isolated> 0636;;;;N;GLYPH FOR ISOLATE ARABIC DAD;;;;\nFEBE;ARABIC LETTER DAD FINAL FORM;Lo;0;AL;<final> 0636;;;;N;GLYPH FOR FINAL ARABIC DAD;;;;\nFEBF;ARABIC LETTER DAD INITIAL FORM;Lo;0;AL;<initial> 0636;;;;N;GLYPH FOR INITIAL ARABIC DAD;;;;\nFEC0;ARABIC LETTER DAD MEDIAL FORM;Lo;0;AL;<medial> 0636;;;;N;GLYPH FOR MEDIAL ARABIC DAD;;;;\nFEC1;ARABIC LETTER TAH ISOLATED FORM;Lo;0;AL;<isolated> 0637;;;;N;GLYPH FOR ISOLATE ARABIC TAH;;;;\nFEC2;ARABIC LETTER TAH FINAL FORM;Lo;0;AL;<final> 0637;;;;N;GLYPH FOR FINAL ARABIC TAH;;;;\nFEC3;ARABIC LETTER TAH INITIAL FORM;Lo;0;AL;<initial> 0637;;;;N;GLYPH FOR INITIAL ARABIC TAH;;;;\nFEC4;ARABIC LETTER TAH MEDIAL FORM;Lo;0;AL;<medial> 0637;;;;N;GLYPH FOR MEDIAL ARABIC TAH;;;;\nFEC5;ARABIC LETTER ZAH ISOLATED FORM;Lo;0;AL;<isolated> 0638;;;;N;GLYPH FOR ISOLATE ARABIC DHAH;;;;\nFEC6;ARABIC LETTER ZAH FINAL FORM;Lo;0;AL;<final> 0638;;;;N;GLYPH FOR FINAL ARABIC DHAH;;;;\nFEC7;ARABIC LETTER ZAH INITIAL FORM;Lo;0;AL;<initial> 0638;;;;N;GLYPH FOR INITIAL ARABIC DHAH;;;;\nFEC8;ARABIC LETTER ZAH MEDIAL FORM;Lo;0;AL;<medial> 0638;;;;N;GLYPH FOR MEDIAL ARABIC DHAH;;;;\nFEC9;ARABIC LETTER AIN ISOLATED FORM;Lo;0;AL;<isolated> 0639;;;;N;GLYPH FOR ISOLATE ARABIC AIN;;;;\nFECA;ARABIC LETTER AIN FINAL FORM;Lo;0;AL;<final> 0639;;;;N;GLYPH FOR FINAL ARABIC AIN;;;;\nFECB;ARABIC LETTER AIN INITIAL FORM;Lo;0;AL;<initial> 0639;;;;N;GLYPH FOR INITIAL ARABIC AIN;;;;\nFECC;ARABIC LETTER AIN MEDIAL FORM;Lo;0;AL;<medial> 0639;;;;N;GLYPH FOR MEDIAL ARABIC AIN;;;;\nFECD;ARABIC LETTER GHAIN ISOLATED FORM;Lo;0;AL;<isolated> 063A;;;;N;GLYPH FOR ISOLATE ARABIC GHAIN;;;;\nFECE;ARABIC LETTER GHAIN FINAL FORM;Lo;0;AL;<final> 063A;;;;N;GLYPH FOR FINAL ARABIC GHAIN;;;;\nFECF;ARABIC LETTER GHAIN INITIAL FORM;Lo;0;AL;<initial> 063A;;;;N;GLYPH FOR INITIAL ARABIC GHAIN;;;;\nFED0;ARABIC LETTER GHAIN MEDIAL FORM;Lo;0;AL;<medial> 063A;;;;N;GLYPH FOR MEDIAL ARABIC GHAIN;;;;\nFED1;ARABIC LETTER FEH ISOLATED FORM;Lo;0;AL;<isolated> 0641;;;;N;GLYPH FOR ISOLATE ARABIC FA;;;;\nFED2;ARABIC LETTER FEH FINAL FORM;Lo;0;AL;<final> 0641;;;;N;GLYPH FOR FINAL ARABIC FA;;;;\nFED3;ARABIC LETTER FEH INITIAL FORM;Lo;0;AL;<initial> 0641;;;;N;GLYPH FOR INITIAL ARABIC FA;;;;\nFED4;ARABIC LETTER FEH MEDIAL FORM;Lo;0;AL;<medial> 0641;;;;N;GLYPH FOR MEDIAL ARABIC FA;;;;\nFED5;ARABIC LETTER QAF ISOLATED FORM;Lo;0;AL;<isolated> 0642;;;;N;GLYPH FOR ISOLATE ARABIC QAF;;;;\nFED6;ARABIC LETTER QAF FINAL FORM;Lo;0;AL;<final> 0642;;;;N;GLYPH FOR FINAL ARABIC QAF;;;;\nFED7;ARABIC LETTER QAF INITIAL FORM;Lo;0;AL;<initial> 0642;;;;N;GLYPH FOR INITIAL ARABIC QAF;;;;\nFED8;ARABIC LETTER QAF MEDIAL FORM;Lo;0;AL;<medial> 0642;;;;N;GLYPH FOR MEDIAL ARABIC QAF;;;;\nFED9;ARABIC LETTER KAF ISOLATED FORM;Lo;0;AL;<isolated> 0643;;;;N;GLYPH FOR ISOLATE ARABIC CAF;;;;\nFEDA;ARABIC LETTER KAF FINAL FORM;Lo;0;AL;<final> 0643;;;;N;GLYPH FOR FINAL ARABIC CAF;;;;\nFEDB;ARABIC LETTER KAF INITIAL FORM;Lo;0;AL;<initial> 0643;;;;N;GLYPH FOR INITIAL ARABIC CAF;;;;\nFEDC;ARABIC LETTER KAF MEDIAL FORM;Lo;0;AL;<medial> 0643;;;;N;GLYPH FOR MEDIAL ARABIC CAF;;;;\nFEDD;ARABIC LETTER LAM ISOLATED FORM;Lo;0;AL;<isolated> 0644;;;;N;GLYPH FOR ISOLATE ARABIC LAM;;;;\nFEDE;ARABIC LETTER LAM FINAL FORM;Lo;0;AL;<final> 0644;;;;N;GLYPH FOR FINAL ARABIC LAM;;;;\nFEDF;ARABIC LETTER LAM INITIAL FORM;Lo;0;AL;<initial> 0644;;;;N;GLYPH FOR INITIAL ARABIC LAM;;;;\nFEE0;ARABIC LETTER LAM MEDIAL FORM;Lo;0;AL;<medial> 0644;;;;N;GLYPH FOR MEDIAL ARABIC LAM;;;;\nFEE1;ARABIC LETTER MEEM ISOLATED FORM;Lo;0;AL;<isolated> 0645;;;;N;GLYPH FOR ISOLATE ARABIC MEEM;;;;\nFEE2;ARABIC LETTER MEEM FINAL FORM;Lo;0;AL;<final> 0645;;;;N;GLYPH FOR FINAL ARABIC MEEM;;;;\nFEE3;ARABIC LETTER MEEM INITIAL FORM;Lo;0;AL;<initial> 0645;;;;N;GLYPH FOR INITIAL ARABIC MEEM;;;;\nFEE4;ARABIC LETTER MEEM MEDIAL FORM;Lo;0;AL;<medial> 0645;;;;N;GLYPH FOR MEDIAL ARABIC MEEM;;;;\nFEE5;ARABIC LETTER NOON ISOLATED FORM;Lo;0;AL;<isolated> 0646;;;;N;GLYPH FOR ISOLATE ARABIC NOON;;;;\nFEE6;ARABIC LETTER NOON FINAL FORM;Lo;0;AL;<final> 0646;;;;N;GLYPH FOR FINAL ARABIC NOON;;;;\nFEE7;ARABIC LETTER NOON INITIAL FORM;Lo;0;AL;<initial> 0646;;;;N;GLYPH FOR INITIAL ARABIC NOON;;;;\nFEE8;ARABIC LETTER NOON MEDIAL FORM;Lo;0;AL;<medial> 0646;;;;N;GLYPH FOR MEDIAL ARABIC NOON;;;;\nFEE9;ARABIC LETTER HEH ISOLATED FORM;Lo;0;AL;<isolated> 0647;;;;N;GLYPH FOR ISOLATE ARABIC HA;;;;\nFEEA;ARABIC LETTER HEH FINAL FORM;Lo;0;AL;<final> 0647;;;;N;GLYPH FOR FINAL ARABIC HA;;;;\nFEEB;ARABIC LETTER HEH INITIAL FORM;Lo;0;AL;<initial> 0647;;;;N;GLYPH FOR INITIAL ARABIC HA;;;;\nFEEC;ARABIC LETTER HEH MEDIAL FORM;Lo;0;AL;<medial> 0647;;;;N;GLYPH FOR MEDIAL ARABIC HA;;;;\nFEED;ARABIC LETTER WAW ISOLATED FORM;Lo;0;AL;<isolated> 0648;;;;N;GLYPH FOR ISOLATE ARABIC WAW;;;;\nFEEE;ARABIC LETTER WAW FINAL FORM;Lo;0;AL;<final> 0648;;;;N;GLYPH FOR FINAL ARABIC WAW;;;;\nFEEF;ARABIC LETTER ALEF MAKSURA ISOLATED FORM;Lo;0;AL;<isolated> 0649;;;;N;GLYPH FOR ISOLATE ARABIC ALEF MAQSURAH;;;;\nFEF0;ARABIC LETTER ALEF MAKSURA FINAL FORM;Lo;0;AL;<final> 0649;;;;N;GLYPH FOR FINAL ARABIC ALEF MAQSURAH;;;;\nFEF1;ARABIC LETTER YEH ISOLATED FORM;Lo;0;AL;<isolated> 064A;;;;N;GLYPH FOR ISOLATE ARABIC YA;;;;\nFEF2;ARABIC LETTER YEH FINAL FORM;Lo;0;AL;<final> 064A;;;;N;GLYPH FOR FINAL ARABIC YA;;;;\nFEF3;ARABIC LETTER YEH INITIAL FORM;Lo;0;AL;<initial> 064A;;;;N;GLYPH FOR INITIAL ARABIC YA;;;;\nFEF4;ARABIC LETTER YEH MEDIAL FORM;Lo;0;AL;<medial> 064A;;;;N;GLYPH FOR MEDIAL ARABIC YA;;;;\nFEF5;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0644 0622;;;;N;GLYPH FOR ISOLATE ARABIC MADDAH ON LIGATURE LAM ALEF;;;;\nFEF6;ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM;Lo;0;AL;<final> 0644 0622;;;;N;GLYPH FOR FINAL ARABIC MADDAH ON LIGATURE LAM ALEF;;;;\nFEF7;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM;Lo;0;AL;<isolated> 0644 0623;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH ON LIGATURE LAM ALEF;;;;\nFEF8;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM;Lo;0;AL;<final> 0644 0623;;;;N;GLYPH FOR FINAL ARABIC HAMZAH ON LIGATURE LAM ALEF;;;;\nFEF9;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM;Lo;0;AL;<isolated> 0644 0625;;;;N;GLYPH FOR ISOLATE ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;;\nFEFA;ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM;Lo;0;AL;<final> 0644 0625;;;;N;GLYPH FOR FINAL ARABIC HAMZAH UNDER LIGATURE LAM ALEF;;;;\nFEFB;ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM;Lo;0;AL;<isolated> 0644 0627;;;;N;GLYPH FOR ISOLATE ARABIC LIGATURE LAM ALEF;;;;\nFEFC;ARABIC LIGATURE LAM WITH ALEF FINAL FORM;Lo;0;AL;<final> 0644 0627;;;;N;GLYPH FOR FINAL ARABIC LIGATURE LAM ALEF;;;;\nFEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;;\nFF01;FULLWIDTH EXCLAMATION MARK;Po;0;ON;<wide> 0021;;;;N;;;;;\nFF02;FULLWIDTH QUOTATION MARK;Po;0;ON;<wide> 0022;;;;N;;;;;\nFF03;FULLWIDTH NUMBER SIGN;Po;0;ET;<wide> 0023;;;;N;;;;;\nFF04;FULLWIDTH DOLLAR SIGN;Sc;0;ET;<wide> 0024;;;;N;;;;;\nFF05;FULLWIDTH PERCENT SIGN;Po;0;ET;<wide> 0025;;;;N;;;;;\nFF06;FULLWIDTH AMPERSAND;Po;0;ON;<wide> 0026;;;;N;;;;;\nFF07;FULLWIDTH APOSTROPHE;Po;0;ON;<wide> 0027;;;;N;;;;;\nFF08;FULLWIDTH LEFT PARENTHESIS;Ps;0;ON;<wide> 0028;;;;Y;FULLWIDTH OPENING PARENTHESIS;;;;\nFF09;FULLWIDTH RIGHT PARENTHESIS;Pe;0;ON;<wide> 0029;;;;Y;FULLWIDTH CLOSING PARENTHESIS;;;;\nFF0A;FULLWIDTH ASTERISK;Po;0;ON;<wide> 002A;;;;N;;;;;\nFF0B;FULLWIDTH PLUS SIGN;Sm;0;ES;<wide> 002B;;;;N;;;;;\nFF0C;FULLWIDTH COMMA;Po;0;CS;<wide> 002C;;;;N;;;;;\nFF0D;FULLWIDTH HYPHEN-MINUS;Pd;0;ES;<wide> 002D;;;;N;;;;;\nFF0E;FULLWIDTH FULL STOP;Po;0;CS;<wide> 002E;;;;N;FULLWIDTH PERIOD;;;;\nFF0F;FULLWIDTH SOLIDUS;Po;0;CS;<wide> 002F;;;;N;FULLWIDTH SLASH;;;;\nFF10;FULLWIDTH DIGIT ZERO;Nd;0;EN;<wide> 0030;0;0;0;N;;;;;\nFF11;FULLWIDTH DIGIT ONE;Nd;0;EN;<wide> 0031;1;1;1;N;;;;;\nFF12;FULLWIDTH DIGIT TWO;Nd;0;EN;<wide> 0032;2;2;2;N;;;;;\nFF13;FULLWIDTH DIGIT THREE;Nd;0;EN;<wide> 0033;3;3;3;N;;;;;\nFF14;FULLWIDTH DIGIT FOUR;Nd;0;EN;<wide> 0034;4;4;4;N;;;;;\nFF15;FULLWIDTH DIGIT FIVE;Nd;0;EN;<wide> 0035;5;5;5;N;;;;;\nFF16;FULLWIDTH DIGIT SIX;Nd;0;EN;<wide> 0036;6;6;6;N;;;;;\nFF17;FULLWIDTH DIGIT SEVEN;Nd;0;EN;<wide> 0037;7;7;7;N;;;;;\nFF18;FULLWIDTH DIGIT EIGHT;Nd;0;EN;<wide> 0038;8;8;8;N;;;;;\nFF19;FULLWIDTH DIGIT NINE;Nd;0;EN;<wide> 0039;9;9;9;N;;;;;\nFF1A;FULLWIDTH COLON;Po;0;CS;<wide> 003A;;;;N;;;;;\nFF1B;FULLWIDTH SEMICOLON;Po;0;ON;<wide> 003B;;;;N;;;;;\nFF1C;FULLWIDTH LESS-THAN SIGN;Sm;0;ON;<wide> 003C;;;;Y;;;;;\nFF1D;FULLWIDTH EQUALS SIGN;Sm;0;ON;<wide> 003D;;;;N;;;;;\nFF1E;FULLWIDTH GREATER-THAN SIGN;Sm;0;ON;<wide> 003E;;;;Y;;;;;\nFF1F;FULLWIDTH QUESTION MARK;Po;0;ON;<wide> 003F;;;;N;;;;;\nFF20;FULLWIDTH COMMERCIAL AT;Po;0;ON;<wide> 0040;;;;N;;;;;\nFF21;FULLWIDTH LATIN CAPITAL LETTER A;Lu;0;L;<wide> 0041;;;;N;;;;FF41;\nFF22;FULLWIDTH LATIN CAPITAL LETTER B;Lu;0;L;<wide> 0042;;;;N;;;;FF42;\nFF23;FULLWIDTH LATIN CAPITAL LETTER C;Lu;0;L;<wide> 0043;;;;N;;;;FF43;\nFF24;FULLWIDTH LATIN CAPITAL LETTER D;Lu;0;L;<wide> 0044;;;;N;;;;FF44;\nFF25;FULLWIDTH LATIN CAPITAL LETTER E;Lu;0;L;<wide> 0045;;;;N;;;;FF45;\nFF26;FULLWIDTH LATIN CAPITAL LETTER F;Lu;0;L;<wide> 0046;;;;N;;;;FF46;\nFF27;FULLWIDTH LATIN CAPITAL LETTER G;Lu;0;L;<wide> 0047;;;;N;;;;FF47;\nFF28;FULLWIDTH LATIN CAPITAL LETTER H;Lu;0;L;<wide> 0048;;;;N;;;;FF48;\nFF29;FULLWIDTH LATIN CAPITAL LETTER I;Lu;0;L;<wide> 0049;;;;N;;;;FF49;\nFF2A;FULLWIDTH LATIN CAPITAL LETTER J;Lu;0;L;<wide> 004A;;;;N;;;;FF4A;\nFF2B;FULLWIDTH LATIN CAPITAL LETTER K;Lu;0;L;<wide> 004B;;;;N;;;;FF4B;\nFF2C;FULLWIDTH LATIN CAPITAL LETTER L;Lu;0;L;<wide> 004C;;;;N;;;;FF4C;\nFF2D;FULLWIDTH LATIN CAPITAL LETTER M;Lu;0;L;<wide> 004D;;;;N;;;;FF4D;\nFF2E;FULLWIDTH LATIN CAPITAL LETTER N;Lu;0;L;<wide> 004E;;;;N;;;;FF4E;\nFF2F;FULLWIDTH LATIN CAPITAL LETTER O;Lu;0;L;<wide> 004F;;;;N;;;;FF4F;\nFF30;FULLWIDTH LATIN CAPITAL LETTER P;Lu;0;L;<wide> 0050;;;;N;;;;FF50;\nFF31;FULLWIDTH LATIN CAPITAL LETTER Q;Lu;0;L;<wide> 0051;;;;N;;;;FF51;\nFF32;FULLWIDTH LATIN CAPITAL LETTER R;Lu;0;L;<wide> 0052;;;;N;;;;FF52;\nFF33;FULLWIDTH LATIN CAPITAL LETTER S;Lu;0;L;<wide> 0053;;;;N;;;;FF53;\nFF34;FULLWIDTH LATIN CAPITAL LETTER T;Lu;0;L;<wide> 0054;;;;N;;;;FF54;\nFF35;FULLWIDTH LATIN CAPITAL LETTER U;Lu;0;L;<wide> 0055;;;;N;;;;FF55;\nFF36;FULLWIDTH LATIN CAPITAL LETTER V;Lu;0;L;<wide> 0056;;;;N;;;;FF56;\nFF37;FULLWIDTH LATIN CAPITAL LETTER W;Lu;0;L;<wide> 0057;;;;N;;;;FF57;\nFF38;FULLWIDTH LATIN CAPITAL LETTER X;Lu;0;L;<wide> 0058;;;;N;;;;FF58;\nFF39;FULLWIDTH LATIN CAPITAL LETTER Y;Lu;0;L;<wide> 0059;;;;N;;;;FF59;\nFF3A;FULLWIDTH LATIN CAPITAL LETTER Z;Lu;0;L;<wide> 005A;;;;N;;;;FF5A;\nFF3B;FULLWIDTH LEFT SQUARE BRACKET;Ps;0;ON;<wide> 005B;;;;Y;FULLWIDTH OPENING SQUARE BRACKET;;;;\nFF3C;FULLWIDTH REVERSE SOLIDUS;Po;0;ON;<wide> 005C;;;;N;FULLWIDTH BACKSLASH;;;;\nFF3D;FULLWIDTH RIGHT SQUARE BRACKET;Pe;0;ON;<wide> 005D;;;;Y;FULLWIDTH CLOSING SQUARE BRACKET;;;;\nFF3E;FULLWIDTH CIRCUMFLEX ACCENT;Sk;0;ON;<wide> 005E;;;;N;FULLWIDTH SPACING CIRCUMFLEX;;;;\nFF3F;FULLWIDTH LOW LINE;Pc;0;ON;<wide> 005F;;;;N;FULLWIDTH SPACING UNDERSCORE;;;;\nFF40;FULLWIDTH GRAVE ACCENT;Sk;0;ON;<wide> 0060;;;;N;FULLWIDTH SPACING GRAVE;;;;\nFF41;FULLWIDTH LATIN SMALL LETTER A;Ll;0;L;<wide> 0061;;;;N;;;FF21;;FF21\nFF42;FULLWIDTH LATIN SMALL LETTER B;Ll;0;L;<wide> 0062;;;;N;;;FF22;;FF22\nFF43;FULLWIDTH LATIN SMALL LETTER C;Ll;0;L;<wide> 0063;;;;N;;;FF23;;FF23\nFF44;FULLWIDTH LATIN SMALL LETTER D;Ll;0;L;<wide> 0064;;;;N;;;FF24;;FF24\nFF45;FULLWIDTH LATIN SMALL LETTER E;Ll;0;L;<wide> 0065;;;;N;;;FF25;;FF25\nFF46;FULLWIDTH LATIN SMALL LETTER F;Ll;0;L;<wide> 0066;;;;N;;;FF26;;FF26\nFF47;FULLWIDTH LATIN SMALL LETTER G;Ll;0;L;<wide> 0067;;;;N;;;FF27;;FF27\nFF48;FULLWIDTH LATIN SMALL LETTER H;Ll;0;L;<wide> 0068;;;;N;;;FF28;;FF28\nFF49;FULLWIDTH LATIN SMALL LETTER I;Ll;0;L;<wide> 0069;;;;N;;;FF29;;FF29\nFF4A;FULLWIDTH LATIN SMALL LETTER J;Ll;0;L;<wide> 006A;;;;N;;;FF2A;;FF2A\nFF4B;FULLWIDTH LATIN SMALL LETTER K;Ll;0;L;<wide> 006B;;;;N;;;FF2B;;FF2B\nFF4C;FULLWIDTH LATIN SMALL LETTER L;Ll;0;L;<wide> 006C;;;;N;;;FF2C;;FF2C\nFF4D;FULLWIDTH LATIN SMALL LETTER M;Ll;0;L;<wide> 006D;;;;N;;;FF2D;;FF2D\nFF4E;FULLWIDTH LATIN SMALL LETTER N;Ll;0;L;<wide> 006E;;;;N;;;FF2E;;FF2E\nFF4F;FULLWIDTH LATIN SMALL LETTER O;Ll;0;L;<wide> 006F;;;;N;;;FF2F;;FF2F\nFF50;FULLWIDTH LATIN SMALL LETTER P;Ll;0;L;<wide> 0070;;;;N;;;FF30;;FF30\nFF51;FULLWIDTH LATIN SMALL LETTER Q;Ll;0;L;<wide> 0071;;;;N;;;FF31;;FF31\nFF52;FULLWIDTH LATIN SMALL LETTER R;Ll;0;L;<wide> 0072;;;;N;;;FF32;;FF32\nFF53;FULLWIDTH LATIN SMALL LETTER S;Ll;0;L;<wide> 0073;;;;N;;;FF33;;FF33\nFF54;FULLWIDTH LATIN SMALL LETTER T;Ll;0;L;<wide> 0074;;;;N;;;FF34;;FF34\nFF55;FULLWIDTH LATIN SMALL LETTER U;Ll;0;L;<wide> 0075;;;;N;;;FF35;;FF35\nFF56;FULLWIDTH LATIN SMALL LETTER V;Ll;0;L;<wide> 0076;;;;N;;;FF36;;FF36\nFF57;FULLWIDTH LATIN SMALL LETTER W;Ll;0;L;<wide> 0077;;;;N;;;FF37;;FF37\nFF58;FULLWIDTH LATIN SMALL LETTER X;Ll;0;L;<wide> 0078;;;;N;;;FF38;;FF38\nFF59;FULLWIDTH LATIN SMALL LETTER Y;Ll;0;L;<wide> 0079;;;;N;;;FF39;;FF39\nFF5A;FULLWIDTH LATIN SMALL LETTER Z;Ll;0;L;<wide> 007A;;;;N;;;FF3A;;FF3A\nFF5B;FULLWIDTH LEFT CURLY BRACKET;Ps;0;ON;<wide> 007B;;;;Y;FULLWIDTH OPENING CURLY BRACKET;;;;\nFF5C;FULLWIDTH VERTICAL LINE;Sm;0;ON;<wide> 007C;;;;N;FULLWIDTH VERTICAL BAR;;;;\nFF5D;FULLWIDTH RIGHT CURLY BRACKET;Pe;0;ON;<wide> 007D;;;;Y;FULLWIDTH CLOSING CURLY BRACKET;;;;\nFF5E;FULLWIDTH TILDE;Sm;0;ON;<wide> 007E;;;;N;FULLWIDTH SPACING TILDE;;;;\nFF5F;FULLWIDTH LEFT WHITE PARENTHESIS;Ps;0;ON;<wide> 2985;;;;Y;;;;;\nFF60;FULLWIDTH RIGHT WHITE PARENTHESIS;Pe;0;ON;<wide> 2986;;;;Y;;;;;\nFF61;HALFWIDTH IDEOGRAPHIC FULL STOP;Po;0;ON;<narrow> 3002;;;;N;HALFWIDTH IDEOGRAPHIC PERIOD;;;;\nFF62;HALFWIDTH LEFT CORNER BRACKET;Ps;0;ON;<narrow> 300C;;;;Y;HALFWIDTH OPENING CORNER BRACKET;;;;\nFF63;HALFWIDTH RIGHT CORNER BRACKET;Pe;0;ON;<narrow> 300D;;;;Y;HALFWIDTH CLOSING CORNER BRACKET;;;;\nFF64;HALFWIDTH IDEOGRAPHIC COMMA;Po;0;ON;<narrow> 3001;;;;N;;;;;\nFF65;HALFWIDTH KATAKANA MIDDLE DOT;Po;0;ON;<narrow> 30FB;;;;N;;;;;\nFF66;HALFWIDTH KATAKANA LETTER WO;Lo;0;L;<narrow> 30F2;;;;N;;;;;\nFF67;HALFWIDTH KATAKANA LETTER SMALL A;Lo;0;L;<narrow> 30A1;;;;N;;;;;\nFF68;HALFWIDTH KATAKANA LETTER SMALL I;Lo;0;L;<narrow> 30A3;;;;N;;;;;\nFF69;HALFWIDTH KATAKANA LETTER SMALL U;Lo;0;L;<narrow> 30A5;;;;N;;;;;\nFF6A;HALFWIDTH KATAKANA LETTER SMALL E;Lo;0;L;<narrow> 30A7;;;;N;;;;;\nFF6B;HALFWIDTH KATAKANA LETTER SMALL O;Lo;0;L;<narrow> 30A9;;;;N;;;;;\nFF6C;HALFWIDTH KATAKANA LETTER SMALL YA;Lo;0;L;<narrow> 30E3;;;;N;;;;;\nFF6D;HALFWIDTH KATAKANA LETTER SMALL YU;Lo;0;L;<narrow> 30E5;;;;N;;;;;\nFF6E;HALFWIDTH KATAKANA LETTER SMALL YO;Lo;0;L;<narrow> 30E7;;;;N;;;;;\nFF6F;HALFWIDTH KATAKANA LETTER SMALL TU;Lo;0;L;<narrow> 30C3;;;;N;;;;;\nFF70;HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK;Lm;0;L;<narrow> 30FC;;;;N;;;;;\nFF71;HALFWIDTH KATAKANA LETTER A;Lo;0;L;<narrow> 30A2;;;;N;;;;;\nFF72;HALFWIDTH KATAKANA LETTER I;Lo;0;L;<narrow> 30A4;;;;N;;;;;\nFF73;HALFWIDTH KATAKANA LETTER U;Lo;0;L;<narrow> 30A6;;;;N;;;;;\nFF74;HALFWIDTH KATAKANA LETTER E;Lo;0;L;<narrow> 30A8;;;;N;;;;;\nFF75;HALFWIDTH KATAKANA LETTER O;Lo;0;L;<narrow> 30AA;;;;N;;;;;\nFF76;HALFWIDTH KATAKANA LETTER KA;Lo;0;L;<narrow> 30AB;;;;N;;;;;\nFF77;HALFWIDTH KATAKANA LETTER KI;Lo;0;L;<narrow> 30AD;;;;N;;;;;\nFF78;HALFWIDTH KATAKANA LETTER KU;Lo;0;L;<narrow> 30AF;;;;N;;;;;\nFF79;HALFWIDTH KATAKANA LETTER KE;Lo;0;L;<narrow> 30B1;;;;N;;;;;\nFF7A;HALFWIDTH KATAKANA LETTER KO;Lo;0;L;<narrow> 30B3;;;;N;;;;;\nFF7B;HALFWIDTH KATAKANA LETTER SA;Lo;0;L;<narrow> 30B5;;;;N;;;;;\nFF7C;HALFWIDTH KATAKANA LETTER SI;Lo;0;L;<narrow> 30B7;;;;N;;;;;\nFF7D;HALFWIDTH KATAKANA LETTER SU;Lo;0;L;<narrow> 30B9;;;;N;;;;;\nFF7E;HALFWIDTH KATAKANA LETTER SE;Lo;0;L;<narrow> 30BB;;;;N;;;;;\nFF7F;HALFWIDTH KATAKANA LETTER SO;Lo;0;L;<narrow> 30BD;;;;N;;;;;\nFF80;HALFWIDTH KATAKANA LETTER TA;Lo;0;L;<narrow> 30BF;;;;N;;;;;\nFF81;HALFWIDTH KATAKANA LETTER TI;Lo;0;L;<narrow> 30C1;;;;N;;;;;\nFF82;HALFWIDTH KATAKANA LETTER TU;Lo;0;L;<narrow> 30C4;;;;N;;;;;\nFF83;HALFWIDTH KATAKANA LETTER TE;Lo;0;L;<narrow> 30C6;;;;N;;;;;\nFF84;HALFWIDTH KATAKANA LETTER TO;Lo;0;L;<narrow> 30C8;;;;N;;;;;\nFF85;HALFWIDTH KATAKANA LETTER NA;Lo;0;L;<narrow> 30CA;;;;N;;;;;\nFF86;HALFWIDTH KATAKANA LETTER NI;Lo;0;L;<narrow> 30CB;;;;N;;;;;\nFF87;HALFWIDTH KATAKANA LETTER NU;Lo;0;L;<narrow> 30CC;;;;N;;;;;\nFF88;HALFWIDTH KATAKANA LETTER NE;Lo;0;L;<narrow> 30CD;;;;N;;;;;\nFF89;HALFWIDTH KATAKANA LETTER NO;Lo;0;L;<narrow> 30CE;;;;N;;;;;\nFF8A;HALFWIDTH KATAKANA LETTER HA;Lo;0;L;<narrow> 30CF;;;;N;;;;;\nFF8B;HALFWIDTH KATAKANA LETTER HI;Lo;0;L;<narrow> 30D2;;;;N;;;;;\nFF8C;HALFWIDTH KATAKANA LETTER HU;Lo;0;L;<narrow> 30D5;;;;N;;;;;\nFF8D;HALFWIDTH KATAKANA LETTER HE;Lo;0;L;<narrow> 30D8;;;;N;;;;;\nFF8E;HALFWIDTH KATAKANA LETTER HO;Lo;0;L;<narrow> 30DB;;;;N;;;;;\nFF8F;HALFWIDTH KATAKANA LETTER MA;Lo;0;L;<narrow> 30DE;;;;N;;;;;\nFF90;HALFWIDTH KATAKANA LETTER MI;Lo;0;L;<narrow> 30DF;;;;N;;;;;\nFF91;HALFWIDTH KATAKANA LETTER MU;Lo;0;L;<narrow> 30E0;;;;N;;;;;\nFF92;HALFWIDTH KATAKANA LETTER ME;Lo;0;L;<narrow> 30E1;;;;N;;;;;\nFF93;HALFWIDTH KATAKANA LETTER MO;Lo;0;L;<narrow> 30E2;;;;N;;;;;\nFF94;HALFWIDTH KATAKANA LETTER YA;Lo;0;L;<narrow> 30E4;;;;N;;;;;\nFF95;HALFWIDTH KATAKANA LETTER YU;Lo;0;L;<narrow> 30E6;;;;N;;;;;\nFF96;HALFWIDTH KATAKANA LETTER YO;Lo;0;L;<narrow> 30E8;;;;N;;;;;\nFF97;HALFWIDTH KATAKANA LETTER RA;Lo;0;L;<narrow> 30E9;;;;N;;;;;\nFF98;HALFWIDTH KATAKANA LETTER RI;Lo;0;L;<narrow> 30EA;;;;N;;;;;\nFF99;HALFWIDTH KATAKANA LETTER RU;Lo;0;L;<narrow> 30EB;;;;N;;;;;\nFF9A;HALFWIDTH KATAKANA LETTER RE;Lo;0;L;<narrow> 30EC;;;;N;;;;;\nFF9B;HALFWIDTH KATAKANA LETTER RO;Lo;0;L;<narrow> 30ED;;;;N;;;;;\nFF9C;HALFWIDTH KATAKANA LETTER WA;Lo;0;L;<narrow> 30EF;;;;N;;;;;\nFF9D;HALFWIDTH KATAKANA LETTER N;Lo;0;L;<narrow> 30F3;;;;N;;;;;\nFF9E;HALFWIDTH KATAKANA VOICED SOUND MARK;Lm;0;L;<narrow> 3099;;;;N;;;;;\nFF9F;HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK;Lm;0;L;<narrow> 309A;;;;N;;;;;\nFFA0;HALFWIDTH HANGUL FILLER;Lo;0;L;<narrow> 3164;;;;N;HALFWIDTH HANGUL CAE OM;;;;\nFFA1;HALFWIDTH HANGUL LETTER KIYEOK;Lo;0;L;<narrow> 3131;;;;N;HALFWIDTH HANGUL LETTER GIYEOG;;;;\nFFA2;HALFWIDTH HANGUL LETTER SSANGKIYEOK;Lo;0;L;<narrow> 3132;;;;N;HALFWIDTH HANGUL LETTER SSANG GIYEOG;;;;\nFFA3;HALFWIDTH HANGUL LETTER KIYEOK-SIOS;Lo;0;L;<narrow> 3133;;;;N;HALFWIDTH HANGUL LETTER GIYEOG SIOS;;;;\nFFA4;HALFWIDTH HANGUL LETTER NIEUN;Lo;0;L;<narrow> 3134;;;;N;;;;;\nFFA5;HALFWIDTH HANGUL LETTER NIEUN-CIEUC;Lo;0;L;<narrow> 3135;;;;N;HALFWIDTH HANGUL LETTER NIEUN JIEUJ;;;;\nFFA6;HALFWIDTH HANGUL LETTER NIEUN-HIEUH;Lo;0;L;<narrow> 3136;;;;N;HALFWIDTH HANGUL LETTER NIEUN HIEUH;;;;\nFFA7;HALFWIDTH HANGUL LETTER TIKEUT;Lo;0;L;<narrow> 3137;;;;N;HALFWIDTH HANGUL LETTER DIGEUD;;;;\nFFA8;HALFWIDTH HANGUL LETTER SSANGTIKEUT;Lo;0;L;<narrow> 3138;;;;N;HALFWIDTH HANGUL LETTER SSANG DIGEUD;;;;\nFFA9;HALFWIDTH HANGUL LETTER RIEUL;Lo;0;L;<narrow> 3139;;;;N;HALFWIDTH HANGUL LETTER LIEUL;;;;\nFFAA;HALFWIDTH HANGUL LETTER RIEUL-KIYEOK;Lo;0;L;<narrow> 313A;;;;N;HALFWIDTH HANGUL LETTER LIEUL GIYEOG;;;;\nFFAB;HALFWIDTH HANGUL LETTER RIEUL-MIEUM;Lo;0;L;<narrow> 313B;;;;N;HALFWIDTH HANGUL LETTER LIEUL MIEUM;;;;\nFFAC;HALFWIDTH HANGUL LETTER RIEUL-PIEUP;Lo;0;L;<narrow> 313C;;;;N;HALFWIDTH HANGUL LETTER LIEUL BIEUB;;;;\nFFAD;HALFWIDTH HANGUL LETTER RIEUL-SIOS;Lo;0;L;<narrow> 313D;;;;N;HALFWIDTH HANGUL LETTER LIEUL SIOS;;;;\nFFAE;HALFWIDTH HANGUL LETTER RIEUL-THIEUTH;Lo;0;L;<narrow> 313E;;;;N;HALFWIDTH HANGUL LETTER LIEUL TIEUT;;;;\nFFAF;HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH;Lo;0;L;<narrow> 313F;;;;N;HALFWIDTH HANGUL LETTER LIEUL PIEUP;;;;\nFFB0;HALFWIDTH HANGUL LETTER RIEUL-HIEUH;Lo;0;L;<narrow> 3140;;;;N;HALFWIDTH HANGUL LETTER LIEUL HIEUH;;;;\nFFB1;HALFWIDTH HANGUL LETTER MIEUM;Lo;0;L;<narrow> 3141;;;;N;;;;;\nFFB2;HALFWIDTH HANGUL LETTER PIEUP;Lo;0;L;<narrow> 3142;;;;N;HALFWIDTH HANGUL LETTER BIEUB;;;;\nFFB3;HALFWIDTH HANGUL LETTER SSANGPIEUP;Lo;0;L;<narrow> 3143;;;;N;HALFWIDTH HANGUL LETTER SSANG BIEUB;;;;\nFFB4;HALFWIDTH HANGUL LETTER PIEUP-SIOS;Lo;0;L;<narrow> 3144;;;;N;HALFWIDTH HANGUL LETTER BIEUB SIOS;;;;\nFFB5;HALFWIDTH HANGUL LETTER SIOS;Lo;0;L;<narrow> 3145;;;;N;;;;;\nFFB6;HALFWIDTH HANGUL LETTER SSANGSIOS;Lo;0;L;<narrow> 3146;;;;N;HALFWIDTH HANGUL LETTER SSANG SIOS;;;;\nFFB7;HALFWIDTH HANGUL LETTER IEUNG;Lo;0;L;<narrow> 3147;;;;N;;;;;\nFFB8;HALFWIDTH HANGUL LETTER CIEUC;Lo;0;L;<narrow> 3148;;;;N;HALFWIDTH HANGUL LETTER JIEUJ;;;;\nFFB9;HALFWIDTH HANGUL LETTER SSANGCIEUC;Lo;0;L;<narrow> 3149;;;;N;HALFWIDTH HANGUL LETTER SSANG JIEUJ;;;;\nFFBA;HALFWIDTH HANGUL LETTER CHIEUCH;Lo;0;L;<narrow> 314A;;;;N;HALFWIDTH HANGUL LETTER CIEUC;;;;\nFFBB;HALFWIDTH HANGUL LETTER KHIEUKH;Lo;0;L;<narrow> 314B;;;;N;HALFWIDTH HANGUL LETTER KIYEOK;;;;\nFFBC;HALFWIDTH HANGUL LETTER THIEUTH;Lo;0;L;<narrow> 314C;;;;N;HALFWIDTH HANGUL LETTER TIEUT;;;;\nFFBD;HALFWIDTH HANGUL LETTER PHIEUPH;Lo;0;L;<narrow> 314D;;;;N;HALFWIDTH HANGUL LETTER PIEUP;;;;\nFFBE;HALFWIDTH HANGUL LETTER HIEUH;Lo;0;L;<narrow> 314E;;;;N;;;;;\nFFC2;HALFWIDTH HANGUL LETTER A;Lo;0;L;<narrow> 314F;;;;N;;;;;\nFFC3;HALFWIDTH HANGUL LETTER AE;Lo;0;L;<narrow> 3150;;;;N;;;;;\nFFC4;HALFWIDTH HANGUL LETTER YA;Lo;0;L;<narrow> 3151;;;;N;;;;;\nFFC5;HALFWIDTH HANGUL LETTER YAE;Lo;0;L;<narrow> 3152;;;;N;;;;;\nFFC6;HALFWIDTH HANGUL LETTER EO;Lo;0;L;<narrow> 3153;;;;N;;;;;\nFFC7;HALFWIDTH HANGUL LETTER E;Lo;0;L;<narrow> 3154;;;;N;;;;;\nFFCA;HALFWIDTH HANGUL LETTER YEO;Lo;0;L;<narrow> 3155;;;;N;;;;;\nFFCB;HALFWIDTH HANGUL LETTER YE;Lo;0;L;<narrow> 3156;;;;N;;;;;\nFFCC;HALFWIDTH HANGUL LETTER O;Lo;0;L;<narrow> 3157;;;;N;;;;;\nFFCD;HALFWIDTH HANGUL LETTER WA;Lo;0;L;<narrow> 3158;;;;N;;;;;\nFFCE;HALFWIDTH HANGUL LETTER WAE;Lo;0;L;<narrow> 3159;;;;N;;;;;\nFFCF;HALFWIDTH HANGUL LETTER OE;Lo;0;L;<narrow> 315A;;;;N;;;;;\nFFD2;HALFWIDTH HANGUL LETTER YO;Lo;0;L;<narrow> 315B;;;;N;;;;;\nFFD3;HALFWIDTH HANGUL LETTER U;Lo;0;L;<narrow> 315C;;;;N;;;;;\nFFD4;HALFWIDTH HANGUL LETTER WEO;Lo;0;L;<narrow> 315D;;;;N;;;;;\nFFD5;HALFWIDTH HANGUL LETTER WE;Lo;0;L;<narrow> 315E;;;;N;;;;;\nFFD6;HALFWIDTH HANGUL LETTER WI;Lo;0;L;<narrow> 315F;;;;N;;;;;\nFFD7;HALFWIDTH HANGUL LETTER YU;Lo;0;L;<narrow> 3160;;;;N;;;;;\nFFDA;HALFWIDTH HANGUL LETTER EU;Lo;0;L;<narrow> 3161;;;;N;;;;;\nFFDB;HALFWIDTH HANGUL LETTER YI;Lo;0;L;<narrow> 3162;;;;N;;;;;\nFFDC;HALFWIDTH HANGUL LETTER I;Lo;0;L;<narrow> 3163;;;;N;;;;;\nFFE0;FULLWIDTH CENT SIGN;Sc;0;ET;<wide> 00A2;;;;N;;;;;\nFFE1;FULLWIDTH POUND SIGN;Sc;0;ET;<wide> 00A3;;;;N;;;;;\nFFE2;FULLWIDTH NOT SIGN;Sm;0;ON;<wide> 00AC;;;;N;;;;;\nFFE3;FULLWIDTH MACRON;Sk;0;ON;<wide> 00AF;;;;N;FULLWIDTH SPACING MACRON;;;;\nFFE4;FULLWIDTH BROKEN BAR;So;0;ON;<wide> 00A6;;;;N;FULLWIDTH BROKEN VERTICAL BAR;;;;\nFFE5;FULLWIDTH YEN SIGN;Sc;0;ET;<wide> 00A5;;;;N;;;;;\nFFE6;FULLWIDTH WON SIGN;Sc;0;ET;<wide> 20A9;;;;N;;;;;\nFFE8;HALFWIDTH FORMS LIGHT VERTICAL;So;0;ON;<narrow> 2502;;;;N;;;;;\nFFE9;HALFWIDTH LEFTWARDS ARROW;Sm;0;ON;<narrow> 2190;;;;N;;;;;\nFFEA;HALFWIDTH UPWARDS ARROW;Sm;0;ON;<narrow> 2191;;;;N;;;;;\nFFEB;HALFWIDTH RIGHTWARDS ARROW;Sm;0;ON;<narrow> 2192;;;;N;;;;;\nFFEC;HALFWIDTH DOWNWARDS ARROW;Sm;0;ON;<narrow> 2193;;;;N;;;;;\nFFED;HALFWIDTH BLACK SQUARE;So;0;ON;<narrow> 25A0;;;;N;;;;;\nFFEE;HALFWIDTH WHITE CIRCLE;So;0;ON;<narrow> 25CB;;;;N;;;;;\nFFF9;INTERLINEAR ANNOTATION ANCHOR;Cf;0;ON;;;;;N;;;;;\nFFFA;INTERLINEAR ANNOTATION SEPARATOR;Cf;0;ON;;;;;N;;;;;\nFFFB;INTERLINEAR ANNOTATION TERMINATOR;Cf;0;ON;;;;;N;;;;;\nFFFC;OBJECT REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;\nFFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;;\n10000;LINEAR B SYLLABLE B008 A;Lo;0;L;;;;;N;;;;;\n10001;LINEAR B SYLLABLE B038 E;Lo;0;L;;;;;N;;;;;\n10002;LINEAR B SYLLABLE B028 I;Lo;0;L;;;;;N;;;;;\n10003;LINEAR B SYLLABLE B061 O;Lo;0;L;;;;;N;;;;;\n10004;LINEAR B SYLLABLE B010 U;Lo;0;L;;;;;N;;;;;\n10005;LINEAR B SYLLABLE B001 DA;Lo;0;L;;;;;N;;;;;\n10006;LINEAR B SYLLABLE B045 DE;Lo;0;L;;;;;N;;;;;\n10007;LINEAR B SYLLABLE B007 DI;Lo;0;L;;;;;N;;;;;\n10008;LINEAR B SYLLABLE B014 DO;Lo;0;L;;;;;N;;;;;\n10009;LINEAR B SYLLABLE B051 DU;Lo;0;L;;;;;N;;;;;\n1000A;LINEAR B SYLLABLE B057 JA;Lo;0;L;;;;;N;;;;;\n1000B;LINEAR B SYLLABLE B046 JE;Lo;0;L;;;;;N;;;;;\n1000D;LINEAR B SYLLABLE B036 JO;Lo;0;L;;;;;N;;;;;\n1000E;LINEAR B SYLLABLE B065 JU;Lo;0;L;;;;;N;;;;;\n1000F;LINEAR B SYLLABLE B077 KA;Lo;0;L;;;;;N;;;;;\n10010;LINEAR B SYLLABLE B044 KE;Lo;0;L;;;;;N;;;;;\n10011;LINEAR B SYLLABLE B067 KI;Lo;0;L;;;;;N;;;;;\n10012;LINEAR B SYLLABLE B070 KO;Lo;0;L;;;;;N;;;;;\n10013;LINEAR B SYLLABLE B081 KU;Lo;0;L;;;;;N;;;;;\n10014;LINEAR B SYLLABLE B080 MA;Lo;0;L;;;;;N;;;;;\n10015;LINEAR B SYLLABLE B013 ME;Lo;0;L;;;;;N;;;;;\n10016;LINEAR B SYLLABLE B073 MI;Lo;0;L;;;;;N;;;;;\n10017;LINEAR B SYLLABLE B015 MO;Lo;0;L;;;;;N;;;;;\n10018;LINEAR B SYLLABLE B023 MU;Lo;0;L;;;;;N;;;;;\n10019;LINEAR B SYLLABLE B006 NA;Lo;0;L;;;;;N;;;;;\n1001A;LINEAR B SYLLABLE B024 NE;Lo;0;L;;;;;N;;;;;\n1001B;LINEAR B SYLLABLE B030 NI;Lo;0;L;;;;;N;;;;;\n1001C;LINEAR B SYLLABLE B052 NO;Lo;0;L;;;;;N;;;;;\n1001D;LINEAR B SYLLABLE B055 NU;Lo;0;L;;;;;N;;;;;\n1001E;LINEAR B SYLLABLE B003 PA;Lo;0;L;;;;;N;;;;;\n1001F;LINEAR B SYLLABLE B072 PE;Lo;0;L;;;;;N;;;;;\n10020;LINEAR B SYLLABLE B039 PI;Lo;0;L;;;;;N;;;;;\n10021;LINEAR B SYLLABLE B011 PO;Lo;0;L;;;;;N;;;;;\n10022;LINEAR B SYLLABLE B050 PU;Lo;0;L;;;;;N;;;;;\n10023;LINEAR B SYLLABLE B016 QA;Lo;0;L;;;;;N;;;;;\n10024;LINEAR B SYLLABLE B078 QE;Lo;0;L;;;;;N;;;;;\n10025;LINEAR B SYLLABLE B021 QI;Lo;0;L;;;;;N;;;;;\n10026;LINEAR B SYLLABLE B032 QO;Lo;0;L;;;;;N;;;;;\n10028;LINEAR B SYLLABLE B060 RA;Lo;0;L;;;;;N;;;;;\n10029;LINEAR B SYLLABLE B027 RE;Lo;0;L;;;;;N;;;;;\n1002A;LINEAR B SYLLABLE B053 RI;Lo;0;L;;;;;N;;;;;\n1002B;LINEAR B SYLLABLE B002 RO;Lo;0;L;;;;;N;;;;;\n1002C;LINEAR B SYLLABLE B026 RU;Lo;0;L;;;;;N;;;;;\n1002D;LINEAR B SYLLABLE B031 SA;Lo;0;L;;;;;N;;;;;\n1002E;LINEAR B SYLLABLE B009 SE;Lo;0;L;;;;;N;;;;;\n1002F;LINEAR B SYLLABLE B041 SI;Lo;0;L;;;;;N;;;;;\n10030;LINEAR B SYLLABLE B012 SO;Lo;0;L;;;;;N;;;;;\n10031;LINEAR B SYLLABLE B058 SU;Lo;0;L;;;;;N;;;;;\n10032;LINEAR B SYLLABLE B059 TA;Lo;0;L;;;;;N;;;;;\n10033;LINEAR B SYLLABLE B004 TE;Lo;0;L;;;;;N;;;;;\n10034;LINEAR B SYLLABLE B037 TI;Lo;0;L;;;;;N;;;;;\n10035;LINEAR B SYLLABLE B005 TO;Lo;0;L;;;;;N;;;;;\n10036;LINEAR B SYLLABLE B069 TU;Lo;0;L;;;;;N;;;;;\n10037;LINEAR B SYLLABLE B054 WA;Lo;0;L;;;;;N;;;;;\n10038;LINEAR B SYLLABLE B075 WE;Lo;0;L;;;;;N;;;;;\n10039;LINEAR B SYLLABLE B040 WI;Lo;0;L;;;;;N;;;;;\n1003A;LINEAR B SYLLABLE B042 WO;Lo;0;L;;;;;N;;;;;\n1003C;LINEAR B SYLLABLE B017 ZA;Lo;0;L;;;;;N;;;;;\n1003D;LINEAR B SYLLABLE B074 ZE;Lo;0;L;;;;;N;;;;;\n1003F;LINEAR B SYLLABLE B020 ZO;Lo;0;L;;;;;N;;;;;\n10040;LINEAR B SYLLABLE B025 A2;Lo;0;L;;;;;N;;;;;\n10041;LINEAR B SYLLABLE B043 A3;Lo;0;L;;;;;N;;;;;\n10042;LINEAR B SYLLABLE B085 AU;Lo;0;L;;;;;N;;;;;\n10043;LINEAR B SYLLABLE B071 DWE;Lo;0;L;;;;;N;;;;;\n10044;LINEAR B SYLLABLE B090 DWO;Lo;0;L;;;;;N;;;;;\n10045;LINEAR B SYLLABLE B048 NWA;Lo;0;L;;;;;N;;;;;\n10046;LINEAR B SYLLABLE B029 PU2;Lo;0;L;;;;;N;;;;;\n10047;LINEAR B SYLLABLE B062 PTE;Lo;0;L;;;;;N;;;;;\n10048;LINEAR B SYLLABLE B076 RA2;Lo;0;L;;;;;N;;;;;\n10049;LINEAR B SYLLABLE B033 RA3;Lo;0;L;;;;;N;;;;;\n1004A;LINEAR B SYLLABLE B068 RO2;Lo;0;L;;;;;N;;;;;\n1004B;LINEAR B SYLLABLE B066 TA2;Lo;0;L;;;;;N;;;;;\n1004C;LINEAR B SYLLABLE B087 TWE;Lo;0;L;;;;;N;;;;;\n1004D;LINEAR B SYLLABLE B091 TWO;Lo;0;L;;;;;N;;;;;\n10050;LINEAR B SYMBOL B018;Lo;0;L;;;;;N;;;;;\n10051;LINEAR B SYMBOL B019;Lo;0;L;;;;;N;;;;;\n10052;LINEAR B SYMBOL B022;Lo;0;L;;;;;N;;;;;\n10053;LINEAR B SYMBOL B034;Lo;0;L;;;;;N;;;;;\n10054;LINEAR B SYMBOL B047;Lo;0;L;;;;;N;;;;;\n10055;LINEAR B SYMBOL B049;Lo;0;L;;;;;N;;;;;\n10056;LINEAR B SYMBOL B056;Lo;0;L;;;;;N;;;;;\n10057;LINEAR B SYMBOL B063;Lo;0;L;;;;;N;;;;;\n10058;LINEAR B SYMBOL B064;Lo;0;L;;;;;N;;;;;\n10059;LINEAR B SYMBOL B079;Lo;0;L;;;;;N;;;;;\n1005A;LINEAR B SYMBOL B082;Lo;0;L;;;;;N;;;;;\n1005B;LINEAR B SYMBOL B083;Lo;0;L;;;;;N;;;;;\n1005C;LINEAR B SYMBOL B086;Lo;0;L;;;;;N;;;;;\n1005D;LINEAR B SYMBOL B089;Lo;0;L;;;;;N;;;;;\n10080;LINEAR B IDEOGRAM B100 MAN;Lo;0;L;;;;;N;;;;;\n10081;LINEAR B IDEOGRAM B102 WOMAN;Lo;0;L;;;;;N;;;;;\n10082;LINEAR B IDEOGRAM B104 DEER;Lo;0;L;;;;;N;;;;;\n10083;LINEAR B IDEOGRAM B105 EQUID;Lo;0;L;;;;;N;;;;;\n10084;LINEAR B IDEOGRAM B105F MARE;Lo;0;L;;;;;N;;;;;\n10085;LINEAR B IDEOGRAM B105M STALLION;Lo;0;L;;;;;N;;;;;\n10086;LINEAR B IDEOGRAM B106F EWE;Lo;0;L;;;;;N;;;;;\n10087;LINEAR B IDEOGRAM B106M RAM;Lo;0;L;;;;;N;;;;;\n10088;LINEAR B IDEOGRAM B107F SHE-GOAT;Lo;0;L;;;;;N;;;;;\n10089;LINEAR B IDEOGRAM B107M HE-GOAT;Lo;0;L;;;;;N;;;;;\n1008A;LINEAR B IDEOGRAM B108F SOW;Lo;0;L;;;;;N;;;;;\n1008B;LINEAR B IDEOGRAM B108M BOAR;Lo;0;L;;;;;N;;;;;\n1008C;LINEAR B IDEOGRAM B109F COW;Lo;0;L;;;;;N;;;;;\n1008D;LINEAR B IDEOGRAM B109M BULL;Lo;0;L;;;;;N;;;;;\n1008E;LINEAR B IDEOGRAM B120 WHEAT;Lo;0;L;;;;;N;;;;;\n1008F;LINEAR B IDEOGRAM B121 BARLEY;Lo;0;L;;;;;N;;;;;\n10090;LINEAR B IDEOGRAM B122 OLIVE;Lo;0;L;;;;;N;;;;;\n10091;LINEAR B IDEOGRAM B123 SPICE;Lo;0;L;;;;;N;;;;;\n10092;LINEAR B IDEOGRAM B125 CYPERUS;Lo;0;L;;;;;N;;;;;\n10093;LINEAR B MONOGRAM B127 KAPO;Lo;0;L;;;;;N;;;;;\n10094;LINEAR B MONOGRAM B128 KANAKO;Lo;0;L;;;;;N;;;;;\n10095;LINEAR B IDEOGRAM B130 OIL;Lo;0;L;;;;;N;;;;;\n10096;LINEAR B IDEOGRAM B131 WINE;Lo;0;L;;;;;N;;;;;\n10097;LINEAR B IDEOGRAM B132;Lo;0;L;;;;;N;;;;;\n10098;LINEAR B MONOGRAM B133 AREPA;Lo;0;L;;;;;N;;;;;\n10099;LINEAR B MONOGRAM B135 MERI;Lo;0;L;;;;;N;;;;;\n1009A;LINEAR B IDEOGRAM B140 BRONZE;Lo;0;L;;;;;N;;;;;\n1009B;LINEAR B IDEOGRAM B141 GOLD;Lo;0;L;;;;;N;;;;;\n1009C;LINEAR B IDEOGRAM B142;Lo;0;L;;;;;N;;;;;\n1009D;LINEAR B IDEOGRAM B145 WOOL;Lo;0;L;;;;;N;;;;;\n1009E;LINEAR B IDEOGRAM B146;Lo;0;L;;;;;N;;;;;\n1009F;LINEAR B IDEOGRAM B150;Lo;0;L;;;;;N;;;;;\n100A0;LINEAR B IDEOGRAM B151 HORN;Lo;0;L;;;;;N;;;;;\n100A1;LINEAR B IDEOGRAM B152;Lo;0;L;;;;;N;;;;;\n100A2;LINEAR B IDEOGRAM B153;Lo;0;L;;;;;N;;;;;\n100A3;LINEAR B IDEOGRAM B154;Lo;0;L;;;;;N;;;;;\n100A4;LINEAR B MONOGRAM B156 TURO2;Lo;0;L;;;;;N;;;;;\n100A5;LINEAR B IDEOGRAM B157;Lo;0;L;;;;;N;;;;;\n100A6;LINEAR B IDEOGRAM B158;Lo;0;L;;;;;N;;;;;\n100A7;LINEAR B IDEOGRAM B159 CLOTH;Lo;0;L;;;;;N;;;;;\n100A8;LINEAR B IDEOGRAM B160;Lo;0;L;;;;;N;;;;;\n100A9;LINEAR B IDEOGRAM B161;Lo;0;L;;;;;N;;;;;\n100AA;LINEAR B IDEOGRAM B162 GARMENT;Lo;0;L;;;;;N;;;;;\n100AB;LINEAR B IDEOGRAM B163 ARMOUR;Lo;0;L;;;;;N;;;;;\n100AC;LINEAR B IDEOGRAM B164;Lo;0;L;;;;;N;;;;;\n100AD;LINEAR B IDEOGRAM B165;Lo;0;L;;;;;N;;;;;\n100AE;LINEAR B IDEOGRAM B166;Lo;0;L;;;;;N;;;;;\n100AF;LINEAR B IDEOGRAM B167;Lo;0;L;;;;;N;;;;;\n100B0;LINEAR B IDEOGRAM B168;Lo;0;L;;;;;N;;;;;\n100B1;LINEAR B IDEOGRAM B169;Lo;0;L;;;;;N;;;;;\n100B2;LINEAR B IDEOGRAM B170;Lo;0;L;;;;;N;;;;;\n100B3;LINEAR B IDEOGRAM B171;Lo;0;L;;;;;N;;;;;\n100B4;LINEAR B IDEOGRAM B172;Lo;0;L;;;;;N;;;;;\n100B5;LINEAR B IDEOGRAM B173 MONTH;Lo;0;L;;;;;N;;;;;\n100B6;LINEAR B IDEOGRAM B174;Lo;0;L;;;;;N;;;;;\n100B7;LINEAR B IDEOGRAM B176 TREE;Lo;0;L;;;;;N;;;;;\n100B8;LINEAR B IDEOGRAM B177;Lo;0;L;;;;;N;;;;;\n100B9;LINEAR B IDEOGRAM B178;Lo;0;L;;;;;N;;;;;\n100BA;LINEAR B IDEOGRAM B179;Lo;0;L;;;;;N;;;;;\n100BB;LINEAR B IDEOGRAM B180;Lo;0;L;;;;;N;;;;;\n100BC;LINEAR B IDEOGRAM B181;Lo;0;L;;;;;N;;;;;\n100BD;LINEAR B IDEOGRAM B182;Lo;0;L;;;;;N;;;;;\n100BE;LINEAR B IDEOGRAM B183;Lo;0;L;;;;;N;;;;;\n100BF;LINEAR B IDEOGRAM B184;Lo;0;L;;;;;N;;;;;\n100C0;LINEAR B IDEOGRAM B185;Lo;0;L;;;;;N;;;;;\n100C1;LINEAR B IDEOGRAM B189;Lo;0;L;;;;;N;;;;;\n100C2;LINEAR B IDEOGRAM B190;Lo;0;L;;;;;N;;;;;\n100C3;LINEAR B IDEOGRAM B191 HELMET;Lo;0;L;;;;;N;;;;;\n100C4;LINEAR B IDEOGRAM B220 FOOTSTOOL;Lo;0;L;;;;;N;;;;;\n100C5;LINEAR B IDEOGRAM B225 BATHTUB;Lo;0;L;;;;;N;;;;;\n100C6;LINEAR B IDEOGRAM B230 SPEAR;Lo;0;L;;;;;N;;;;;\n100C7;LINEAR B IDEOGRAM B231 ARROW;Lo;0;L;;;;;N;;;;;\n100C8;LINEAR B IDEOGRAM B232;Lo;0;L;;;;;N;;;;;\n100C9;LINEAR B IDEOGRAM B233 SWORD;Lo;0;L;;;;;N;;;;;\n100CA;LINEAR B IDEOGRAM B234;Lo;0;L;;;;;N;;;;;\n100CB;LINEAR B IDEOGRAM B236;Lo;0;L;;;;;N;;;;;\n100CC;LINEAR B IDEOGRAM B240 WHEELED CHARIOT;Lo;0;L;;;;;N;;;;;\n100CD;LINEAR B IDEOGRAM B241 CHARIOT;Lo;0;L;;;;;N;;;;;\n100CE;LINEAR B IDEOGRAM B242 CHARIOT FRAME;Lo;0;L;;;;;N;;;;;\n100CF;LINEAR B IDEOGRAM B243 WHEEL;Lo;0;L;;;;;N;;;;;\n100D0;LINEAR B IDEOGRAM B245;Lo;0;L;;;;;N;;;;;\n100D1;LINEAR B IDEOGRAM B246;Lo;0;L;;;;;N;;;;;\n100D2;LINEAR B MONOGRAM B247 DIPTE;Lo;0;L;;;;;N;;;;;\n100D3;LINEAR B IDEOGRAM B248;Lo;0;L;;;;;N;;;;;\n100D4;LINEAR B IDEOGRAM B249;Lo;0;L;;;;;N;;;;;\n100D5;LINEAR B IDEOGRAM B251;Lo;0;L;;;;;N;;;;;\n100D6;LINEAR B IDEOGRAM B252;Lo;0;L;;;;;N;;;;;\n100D7;LINEAR B IDEOGRAM B253;Lo;0;L;;;;;N;;;;;\n100D8;LINEAR B IDEOGRAM B254 DART;Lo;0;L;;;;;N;;;;;\n100D9;LINEAR B IDEOGRAM B255;Lo;0;L;;;;;N;;;;;\n100DA;LINEAR B IDEOGRAM B256;Lo;0;L;;;;;N;;;;;\n100DB;LINEAR B IDEOGRAM B257;Lo;0;L;;;;;N;;;;;\n100DC;LINEAR B IDEOGRAM B258;Lo;0;L;;;;;N;;;;;\n100DD;LINEAR B IDEOGRAM B259;Lo;0;L;;;;;N;;;;;\n100DE;LINEAR B IDEOGRAM VESSEL B155;Lo;0;L;;;;;N;;;;;\n100DF;LINEAR B IDEOGRAM VESSEL B200;Lo;0;L;;;;;N;;;;;\n100E0;LINEAR B IDEOGRAM VESSEL B201;Lo;0;L;;;;;N;;;;;\n100E1;LINEAR B IDEOGRAM VESSEL B202;Lo;0;L;;;;;N;;;;;\n100E2;LINEAR B IDEOGRAM VESSEL B203;Lo;0;L;;;;;N;;;;;\n100E3;LINEAR B IDEOGRAM VESSEL B204;Lo;0;L;;;;;N;;;;;\n100E4;LINEAR B IDEOGRAM VESSEL B205;Lo;0;L;;;;;N;;;;;\n100E5;LINEAR B IDEOGRAM VESSEL B206;Lo;0;L;;;;;N;;;;;\n100E6;LINEAR B IDEOGRAM VESSEL B207;Lo;0;L;;;;;N;;;;;\n100E7;LINEAR B IDEOGRAM VESSEL B208;Lo;0;L;;;;;N;;;;;\n100E8;LINEAR B IDEOGRAM VESSEL B209;Lo;0;L;;;;;N;;;;;\n100E9;LINEAR B IDEOGRAM VESSEL B210;Lo;0;L;;;;;N;;;;;\n100EA;LINEAR B IDEOGRAM VESSEL B211;Lo;0;L;;;;;N;;;;;\n100EB;LINEAR B IDEOGRAM VESSEL B212;Lo;0;L;;;;;N;;;;;\n100EC;LINEAR B IDEOGRAM VESSEL B213;Lo;0;L;;;;;N;;;;;\n100ED;LINEAR B IDEOGRAM VESSEL B214;Lo;0;L;;;;;N;;;;;\n100EE;LINEAR B IDEOGRAM VESSEL B215;Lo;0;L;;;;;N;;;;;\n100EF;LINEAR B IDEOGRAM VESSEL B216;Lo;0;L;;;;;N;;;;;\n100F0;LINEAR B IDEOGRAM VESSEL B217;Lo;0;L;;;;;N;;;;;\n100F1;LINEAR B IDEOGRAM VESSEL B218;Lo;0;L;;;;;N;;;;;\n100F2;LINEAR B IDEOGRAM VESSEL B219;Lo;0;L;;;;;N;;;;;\n100F3;LINEAR B IDEOGRAM VESSEL B221;Lo;0;L;;;;;N;;;;;\n100F4;LINEAR B IDEOGRAM VESSEL B222;Lo;0;L;;;;;N;;;;;\n100F5;LINEAR B IDEOGRAM VESSEL B226;Lo;0;L;;;;;N;;;;;\n100F6;LINEAR B IDEOGRAM VESSEL B227;Lo;0;L;;;;;N;;;;;\n100F7;LINEAR B IDEOGRAM VESSEL B228;Lo;0;L;;;;;N;;;;;\n100F8;LINEAR B IDEOGRAM VESSEL B229;Lo;0;L;;;;;N;;;;;\n100F9;LINEAR B IDEOGRAM VESSEL B250;Lo;0;L;;;;;N;;;;;\n100FA;LINEAR B IDEOGRAM VESSEL B305;Lo;0;L;;;;;N;;;;;\n10100;AEGEAN WORD SEPARATOR LINE;Po;0;L;;;;;N;;;;;\n10101;AEGEAN WORD SEPARATOR DOT;Po;0;ON;;;;;N;;;;;\n10102;AEGEAN CHECK MARK;Po;0;L;;;;;N;;;;;\n10107;AEGEAN NUMBER ONE;No;0;L;;;;1;N;;;;;\n10108;AEGEAN NUMBER TWO;No;0;L;;;;2;N;;;;;\n10109;AEGEAN NUMBER THREE;No;0;L;;;;3;N;;;;;\n1010A;AEGEAN NUMBER FOUR;No;0;L;;;;4;N;;;;;\n1010B;AEGEAN NUMBER FIVE;No;0;L;;;;5;N;;;;;\n1010C;AEGEAN NUMBER SIX;No;0;L;;;;6;N;;;;;\n1010D;AEGEAN NUMBER SEVEN;No;0;L;;;;7;N;;;;;\n1010E;AEGEAN NUMBER EIGHT;No;0;L;;;;8;N;;;;;\n1010F;AEGEAN NUMBER NINE;No;0;L;;;;9;N;;;;;\n10110;AEGEAN NUMBER TEN;No;0;L;;;;10;N;;;;;\n10111;AEGEAN NUMBER TWENTY;No;0;L;;;;20;N;;;;;\n10112;AEGEAN NUMBER THIRTY;No;0;L;;;;30;N;;;;;\n10113;AEGEAN NUMBER FORTY;No;0;L;;;;40;N;;;;;\n10114;AEGEAN NUMBER FIFTY;No;0;L;;;;50;N;;;;;\n10115;AEGEAN NUMBER SIXTY;No;0;L;;;;60;N;;;;;\n10116;AEGEAN NUMBER SEVENTY;No;0;L;;;;70;N;;;;;\n10117;AEGEAN NUMBER EIGHTY;No;0;L;;;;80;N;;;;;\n10118;AEGEAN NUMBER NINETY;No;0;L;;;;90;N;;;;;\n10119;AEGEAN NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;\n1011A;AEGEAN NUMBER TWO HUNDRED;No;0;L;;;;200;N;;;;;\n1011B;AEGEAN NUMBER THREE HUNDRED;No;0;L;;;;300;N;;;;;\n1011C;AEGEAN NUMBER FOUR HUNDRED;No;0;L;;;;400;N;;;;;\n1011D;AEGEAN NUMBER FIVE HUNDRED;No;0;L;;;;500;N;;;;;\n1011E;AEGEAN NUMBER SIX HUNDRED;No;0;L;;;;600;N;;;;;\n1011F;AEGEAN NUMBER SEVEN HUNDRED;No;0;L;;;;700;N;;;;;\n10120;AEGEAN NUMBER EIGHT HUNDRED;No;0;L;;;;800;N;;;;;\n10121;AEGEAN NUMBER NINE HUNDRED;No;0;L;;;;900;N;;;;;\n10122;AEGEAN NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;\n10123;AEGEAN NUMBER TWO THOUSAND;No;0;L;;;;2000;N;;;;;\n10124;AEGEAN NUMBER THREE THOUSAND;No;0;L;;;;3000;N;;;;;\n10125;AEGEAN NUMBER FOUR THOUSAND;No;0;L;;;;4000;N;;;;;\n10126;AEGEAN NUMBER FIVE THOUSAND;No;0;L;;;;5000;N;;;;;\n10127;AEGEAN NUMBER SIX THOUSAND;No;0;L;;;;6000;N;;;;;\n10128;AEGEAN NUMBER SEVEN THOUSAND;No;0;L;;;;7000;N;;;;;\n10129;AEGEAN NUMBER EIGHT THOUSAND;No;0;L;;;;8000;N;;;;;\n1012A;AEGEAN NUMBER NINE THOUSAND;No;0;L;;;;9000;N;;;;;\n1012B;AEGEAN NUMBER TEN THOUSAND;No;0;L;;;;10000;N;;;;;\n1012C;AEGEAN NUMBER TWENTY THOUSAND;No;0;L;;;;20000;N;;;;;\n1012D;AEGEAN NUMBER THIRTY THOUSAND;No;0;L;;;;30000;N;;;;;\n1012E;AEGEAN NUMBER FORTY THOUSAND;No;0;L;;;;40000;N;;;;;\n1012F;AEGEAN NUMBER FIFTY THOUSAND;No;0;L;;;;50000;N;;;;;\n10130;AEGEAN NUMBER SIXTY THOUSAND;No;0;L;;;;60000;N;;;;;\n10131;AEGEAN NUMBER SEVENTY THOUSAND;No;0;L;;;;70000;N;;;;;\n10132;AEGEAN NUMBER EIGHTY THOUSAND;No;0;L;;;;80000;N;;;;;\n10133;AEGEAN NUMBER NINETY THOUSAND;No;0;L;;;;90000;N;;;;;\n10137;AEGEAN WEIGHT BASE UNIT;So;0;L;;;;;N;;;;;\n10138;AEGEAN WEIGHT FIRST SUBUNIT;So;0;L;;;;;N;;;;;\n10139;AEGEAN WEIGHT SECOND SUBUNIT;So;0;L;;;;;N;;;;;\n1013A;AEGEAN WEIGHT THIRD SUBUNIT;So;0;L;;;;;N;;;;;\n1013B;AEGEAN WEIGHT FOURTH SUBUNIT;So;0;L;;;;;N;;;;;\n1013C;AEGEAN DRY MEASURE FIRST SUBUNIT;So;0;L;;;;;N;;;;;\n1013D;AEGEAN LIQUID MEASURE FIRST SUBUNIT;So;0;L;;;;;N;;;;;\n1013E;AEGEAN MEASURE SECOND SUBUNIT;So;0;L;;;;;N;;;;;\n1013F;AEGEAN MEASURE THIRD SUBUNIT;So;0;L;;;;;N;;;;;\n10140;GREEK ACROPHONIC ATTIC ONE QUARTER;Nl;0;ON;;;;1/4;N;;;;;\n10141;GREEK ACROPHONIC ATTIC ONE HALF;Nl;0;ON;;;;1/2;N;;;;;\n10142;GREEK ACROPHONIC ATTIC ONE DRACHMA;Nl;0;ON;;;;1;N;;;;;\n10143;GREEK ACROPHONIC ATTIC FIVE;Nl;0;ON;;;;5;N;;;;;\n10144;GREEK ACROPHONIC ATTIC FIFTY;Nl;0;ON;;;;50;N;;;;;\n10145;GREEK ACROPHONIC ATTIC FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;\n10146;GREEK ACROPHONIC ATTIC FIVE THOUSAND;Nl;0;ON;;;;5000;N;;;;;\n10147;GREEK ACROPHONIC ATTIC FIFTY THOUSAND;Nl;0;ON;;;;50000;N;;;;;\n10148;GREEK ACROPHONIC ATTIC FIVE TALENTS;Nl;0;ON;;;;5;N;;;;;\n10149;GREEK ACROPHONIC ATTIC TEN TALENTS;Nl;0;ON;;;;10;N;;;;;\n1014A;GREEK ACROPHONIC ATTIC FIFTY TALENTS;Nl;0;ON;;;;50;N;;;;;\n1014B;GREEK ACROPHONIC ATTIC ONE HUNDRED TALENTS;Nl;0;ON;;;;100;N;;;;;\n1014C;GREEK ACROPHONIC ATTIC FIVE HUNDRED TALENTS;Nl;0;ON;;;;500;N;;;;;\n1014D;GREEK ACROPHONIC ATTIC ONE THOUSAND TALENTS;Nl;0;ON;;;;1000;N;;;;;\n1014E;GREEK ACROPHONIC ATTIC FIVE THOUSAND TALENTS;Nl;0;ON;;;;5000;N;;;;;\n1014F;GREEK ACROPHONIC ATTIC FIVE STATERS;Nl;0;ON;;;;5;N;;;;;\n10150;GREEK ACROPHONIC ATTIC TEN STATERS;Nl;0;ON;;;;10;N;;;;;\n10151;GREEK ACROPHONIC ATTIC FIFTY STATERS;Nl;0;ON;;;;50;N;;;;;\n10152;GREEK ACROPHONIC ATTIC ONE HUNDRED STATERS;Nl;0;ON;;;;100;N;;;;;\n10153;GREEK ACROPHONIC ATTIC FIVE HUNDRED STATERS;Nl;0;ON;;;;500;N;;;;;\n10154;GREEK ACROPHONIC ATTIC ONE THOUSAND STATERS;Nl;0;ON;;;;1000;N;;;;;\n10155;GREEK ACROPHONIC ATTIC TEN THOUSAND STATERS;Nl;0;ON;;;;10000;N;;;;;\n10156;GREEK ACROPHONIC ATTIC FIFTY THOUSAND STATERS;Nl;0;ON;;;;50000;N;;;;;\n10157;GREEK ACROPHONIC ATTIC TEN MNAS;Nl;0;ON;;;;10;N;;;;;\n10158;GREEK ACROPHONIC HERAEUM ONE PLETHRON;Nl;0;ON;;;;1;N;;;;;\n10159;GREEK ACROPHONIC THESPIAN ONE;Nl;0;ON;;;;1;N;;;;;\n1015A;GREEK ACROPHONIC HERMIONIAN ONE;Nl;0;ON;;;;1;N;;;;;\n1015B;GREEK ACROPHONIC EPIDAUREAN TWO;Nl;0;ON;;;;2;N;;;;;\n1015C;GREEK ACROPHONIC THESPIAN TWO;Nl;0;ON;;;;2;N;;;;;\n1015D;GREEK ACROPHONIC CYRENAIC TWO DRACHMAS;Nl;0;ON;;;;2;N;;;;;\n1015E;GREEK ACROPHONIC EPIDAUREAN TWO DRACHMAS;Nl;0;ON;;;;2;N;;;;;\n1015F;GREEK ACROPHONIC TROEZENIAN FIVE;Nl;0;ON;;;;5;N;;;;;\n10160;GREEK ACROPHONIC TROEZENIAN TEN;Nl;0;ON;;;;10;N;;;;;\n10161;GREEK ACROPHONIC TROEZENIAN TEN ALTERNATE FORM;Nl;0;ON;;;;10;N;;;;;\n10162;GREEK ACROPHONIC HERMIONIAN TEN;Nl;0;ON;;;;10;N;;;;;\n10163;GREEK ACROPHONIC MESSENIAN TEN;Nl;0;ON;;;;10;N;;;;;\n10164;GREEK ACROPHONIC THESPIAN TEN;Nl;0;ON;;;;10;N;;;;;\n10165;GREEK ACROPHONIC THESPIAN THIRTY;Nl;0;ON;;;;30;N;;;;;\n10166;GREEK ACROPHONIC TROEZENIAN FIFTY;Nl;0;ON;;;;50;N;;;;;\n10167;GREEK ACROPHONIC TROEZENIAN FIFTY ALTERNATE FORM;Nl;0;ON;;;;50;N;;;;;\n10168;GREEK ACROPHONIC HERMIONIAN FIFTY;Nl;0;ON;;;;50;N;;;;;\n10169;GREEK ACROPHONIC THESPIAN FIFTY;Nl;0;ON;;;;50;N;;;;;\n1016A;GREEK ACROPHONIC THESPIAN ONE HUNDRED;Nl;0;ON;;;;100;N;;;;;\n1016B;GREEK ACROPHONIC THESPIAN THREE HUNDRED;Nl;0;ON;;;;300;N;;;;;\n1016C;GREEK ACROPHONIC EPIDAUREAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;\n1016D;GREEK ACROPHONIC TROEZENIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;\n1016E;GREEK ACROPHONIC THESPIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;\n1016F;GREEK ACROPHONIC CARYSTIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;\n10170;GREEK ACROPHONIC NAXIAN FIVE HUNDRED;Nl;0;ON;;;;500;N;;;;;\n10171;GREEK ACROPHONIC THESPIAN ONE THOUSAND;Nl;0;ON;;;;1000;N;;;;;\n10172;GREEK ACROPHONIC THESPIAN FIVE THOUSAND;Nl;0;ON;;;;5000;N;;;;;\n10173;GREEK ACROPHONIC DELPHIC FIVE MNAS;Nl;0;ON;;;;5;N;;;;;\n10174;GREEK ACROPHONIC STRATIAN FIFTY MNAS;Nl;0;ON;;;;50;N;;;;;\n10175;GREEK ONE HALF SIGN;No;0;ON;;;;1/2;N;;;;;\n10176;GREEK ONE HALF SIGN ALTERNATE FORM;No;0;ON;;;;1/2;N;;;;;\n10177;GREEK TWO THIRDS SIGN;No;0;ON;;;;2/3;N;;;;;\n10178;GREEK THREE QUARTERS SIGN;No;0;ON;;;;3/4;N;;;;;\n10179;GREEK YEAR SIGN;So;0;ON;;;;;N;;;;;\n1017A;GREEK TALENT SIGN;So;0;ON;;;;;N;;;;;\n1017B;GREEK DRACHMA SIGN;So;0;ON;;;;;N;;;;;\n1017C;GREEK OBOL SIGN;So;0;ON;;;;;N;;;;;\n1017D;GREEK TWO OBOLS SIGN;So;0;ON;;;;;N;;;;;\n1017E;GREEK THREE OBOLS SIGN;So;0;ON;;;;;N;;;;;\n1017F;GREEK FOUR OBOLS SIGN;So;0;ON;;;;;N;;;;;\n10180;GREEK FIVE OBOLS SIGN;So;0;ON;;;;;N;;;;;\n10181;GREEK METRETES SIGN;So;0;ON;;;;;N;;;;;\n10182;GREEK KYATHOS BASE SIGN;So;0;ON;;;;;N;;;;;\n10183;GREEK LITRA SIGN;So;0;ON;;;;;N;;;;;\n10184;GREEK OUNKIA SIGN;So;0;ON;;;;;N;;;;;\n10185;GREEK XESTES SIGN;So;0;ON;;;;;N;;;;;\n10186;GREEK ARTABE SIGN;So;0;ON;;;;;N;;;;;\n10187;GREEK AROURA SIGN;So;0;ON;;;;;N;;;;;\n10188;GREEK GRAMMA SIGN;So;0;ON;;;;;N;;;;;\n10189;GREEK TRYBLION BASE SIGN;So;0;ON;;;;;N;;;;;\n1018A;GREEK ZERO SIGN;No;0;ON;;;;0;N;;;;;\n1018B;GREEK ONE QUARTER SIGN;No;0;ON;;;;1/4;N;;;;;\n1018C;GREEK SINUSOID SIGN;So;0;ON;;;;;N;;;;;\n1018D;GREEK INDICTION SIGN;So;0;L;;;;;N;;;;;\n1018E;NOMISMA SIGN;So;0;L;;;;;N;;;;;\n10190;ROMAN SEXTANS SIGN;So;0;ON;;;;;N;;;;;\n10191;ROMAN UNCIA SIGN;So;0;ON;;;;;N;;;;;\n10192;ROMAN SEMUNCIA SIGN;So;0;ON;;;;;N;;;;;\n10193;ROMAN SEXTULA SIGN;So;0;ON;;;;;N;;;;;\n10194;ROMAN DIMIDIA SEXTULA SIGN;So;0;ON;;;;;N;;;;;\n10195;ROMAN SILIQUA SIGN;So;0;ON;;;;;N;;;;;\n10196;ROMAN DENARIUS SIGN;So;0;ON;;;;;N;;;;;\n10197;ROMAN QUINARIUS SIGN;So;0;ON;;;;;N;;;;;\n10198;ROMAN SESTERTIUS SIGN;So;0;ON;;;;;N;;;;;\n10199;ROMAN DUPONDIUS SIGN;So;0;ON;;;;;N;;;;;\n1019A;ROMAN AS SIGN;So;0;ON;;;;;N;;;;;\n1019B;ROMAN CENTURIAL SIGN;So;0;ON;;;;;N;;;;;\n101A0;GREEK SYMBOL TAU RHO;So;0;ON;;;;;N;;;;;\n101D0;PHAISTOS DISC SIGN PEDESTRIAN;So;0;L;;;;;N;;;;;\n101D1;PHAISTOS DISC SIGN PLUMED HEAD;So;0;L;;;;;N;;;;;\n101D2;PHAISTOS DISC SIGN TATTOOED HEAD;So;0;L;;;;;N;;;;;\n101D3;PHAISTOS DISC SIGN CAPTIVE;So;0;L;;;;;N;;;;;\n101D4;PHAISTOS DISC SIGN CHILD;So;0;L;;;;;N;;;;;\n101D5;PHAISTOS DISC SIGN WOMAN;So;0;L;;;;;N;;;;;\n101D6;PHAISTOS DISC SIGN HELMET;So;0;L;;;;;N;;;;;\n101D7;PHAISTOS DISC SIGN GAUNTLET;So;0;L;;;;;N;;;;;\n101D8;PHAISTOS DISC SIGN TIARA;So;0;L;;;;;N;;;;;\n101D9;PHAISTOS DISC SIGN ARROW;So;0;L;;;;;N;;;;;\n101DA;PHAISTOS DISC SIGN BOW;So;0;L;;;;;N;;;;;\n101DB;PHAISTOS DISC SIGN SHIELD;So;0;L;;;;;N;;;;;\n101DC;PHAISTOS DISC SIGN CLUB;So;0;L;;;;;N;;;;;\n101DD;PHAISTOS DISC SIGN MANACLES;So;0;L;;;;;N;;;;;\n101DE;PHAISTOS DISC SIGN MATTOCK;So;0;L;;;;;N;;;;;\n101DF;PHAISTOS DISC SIGN SAW;So;0;L;;;;;N;;;;;\n101E0;PHAISTOS DISC SIGN LID;So;0;L;;;;;N;;;;;\n101E1;PHAISTOS DISC SIGN BOOMERANG;So;0;L;;;;;N;;;;;\n101E2;PHAISTOS DISC SIGN CARPENTRY PLANE;So;0;L;;;;;N;;;;;\n101E3;PHAISTOS DISC SIGN DOLIUM;So;0;L;;;;;N;;;;;\n101E4;PHAISTOS DISC SIGN COMB;So;0;L;;;;;N;;;;;\n101E5;PHAISTOS DISC SIGN SLING;So;0;L;;;;;N;;;;;\n101E6;PHAISTOS DISC SIGN COLUMN;So;0;L;;;;;N;;;;;\n101E7;PHAISTOS DISC SIGN BEEHIVE;So;0;L;;;;;N;;;;;\n101E8;PHAISTOS DISC SIGN SHIP;So;0;L;;;;;N;;;;;\n101E9;PHAISTOS DISC SIGN HORN;So;0;L;;;;;N;;;;;\n101EA;PHAISTOS DISC SIGN HIDE;So;0;L;;;;;N;;;;;\n101EB;PHAISTOS DISC SIGN BULLS LEG;So;0;L;;;;;N;;;;;\n101EC;PHAISTOS DISC SIGN CAT;So;0;L;;;;;N;;;;;\n101ED;PHAISTOS DISC SIGN RAM;So;0;L;;;;;N;;;;;\n101EE;PHAISTOS DISC SIGN EAGLE;So;0;L;;;;;N;;;;;\n101EF;PHAISTOS DISC SIGN DOVE;So;0;L;;;;;N;;;;;\n101F0;PHAISTOS DISC SIGN TUNNY;So;0;L;;;;;N;;;;;\n101F1;PHAISTOS DISC SIGN BEE;So;0;L;;;;;N;;;;;\n101F2;PHAISTOS DISC SIGN PLANE TREE;So;0;L;;;;;N;;;;;\n101F3;PHAISTOS DISC SIGN VINE;So;0;L;;;;;N;;;;;\n101F4;PHAISTOS DISC SIGN PAPYRUS;So;0;L;;;;;N;;;;;\n101F5;PHAISTOS DISC SIGN ROSETTE;So;0;L;;;;;N;;;;;\n101F6;PHAISTOS DISC SIGN LILY;So;0;L;;;;;N;;;;;\n101F7;PHAISTOS DISC SIGN OX BACK;So;0;L;;;;;N;;;;;\n101F8;PHAISTOS DISC SIGN FLUTE;So;0;L;;;;;N;;;;;\n101F9;PHAISTOS DISC SIGN GRATER;So;0;L;;;;;N;;;;;\n101FA;PHAISTOS DISC SIGN STRAINER;So;0;L;;;;;N;;;;;\n101FB;PHAISTOS DISC SIGN SMALL AXE;So;0;L;;;;;N;;;;;\n101FC;PHAISTOS DISC SIGN WAVY BAND;So;0;L;;;;;N;;;;;\n101FD;PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE;Mn;220;NSM;;;;;N;;;;;\n10280;LYCIAN LETTER A;Lo;0;L;;;;;N;;;;;\n10281;LYCIAN LETTER E;Lo;0;L;;;;;N;;;;;\n10282;LYCIAN LETTER B;Lo;0;L;;;;;N;;;;;\n10283;LYCIAN LETTER BH;Lo;0;L;;;;;N;;;;;\n10284;LYCIAN LETTER G;Lo;0;L;;;;;N;;;;;\n10285;LYCIAN LETTER D;Lo;0;L;;;;;N;;;;;\n10286;LYCIAN LETTER I;Lo;0;L;;;;;N;;;;;\n10287;LYCIAN LETTER W;Lo;0;L;;;;;N;;;;;\n10288;LYCIAN LETTER Z;Lo;0;L;;;;;N;;;;;\n10289;LYCIAN LETTER TH;Lo;0;L;;;;;N;;;;;\n1028A;LYCIAN LETTER J;Lo;0;L;;;;;N;;;;;\n1028B;LYCIAN LETTER K;Lo;0;L;;;;;N;;;;;\n1028C;LYCIAN LETTER Q;Lo;0;L;;;;;N;;;;;\n1028D;LYCIAN LETTER L;Lo;0;L;;;;;N;;;;;\n1028E;LYCIAN LETTER M;Lo;0;L;;;;;N;;;;;\n1028F;LYCIAN LETTER N;Lo;0;L;;;;;N;;;;;\n10290;LYCIAN LETTER MM;Lo;0;L;;;;;N;;;;;\n10291;LYCIAN LETTER NN;Lo;0;L;;;;;N;;;;;\n10292;LYCIAN LETTER U;Lo;0;L;;;;;N;;;;;\n10293;LYCIAN LETTER P;Lo;0;L;;;;;N;;;;;\n10294;LYCIAN LETTER KK;Lo;0;L;;;;;N;;;;;\n10295;LYCIAN LETTER R;Lo;0;L;;;;;N;;;;;\n10296;LYCIAN LETTER S;Lo;0;L;;;;;N;;;;;\n10297;LYCIAN LETTER T;Lo;0;L;;;;;N;;;;;\n10298;LYCIAN LETTER TT;Lo;0;L;;;;;N;;;;;\n10299;LYCIAN LETTER AN;Lo;0;L;;;;;N;;;;;\n1029A;LYCIAN LETTER EN;Lo;0;L;;;;;N;;;;;\n1029B;LYCIAN LETTER H;Lo;0;L;;;;;N;;;;;\n1029C;LYCIAN LETTER X;Lo;0;L;;;;;N;;;;;\n102A0;CARIAN LETTER A;Lo;0;L;;;;;N;;;;;\n102A1;CARIAN LETTER P2;Lo;0;L;;;;;N;;;;;\n102A2;CARIAN LETTER D;Lo;0;L;;;;;N;;;;;\n102A3;CARIAN LETTER L;Lo;0;L;;;;;N;;;;;\n102A4;CARIAN LETTER UUU;Lo;0;L;;;;;N;;;;;\n102A5;CARIAN LETTER R;Lo;0;L;;;;;N;;;;;\n102A6;CARIAN LETTER LD;Lo;0;L;;;;;N;;;;;\n102A7;CARIAN LETTER A2;Lo;0;L;;;;;N;;;;;\n102A8;CARIAN LETTER Q;Lo;0;L;;;;;N;;;;;\n102A9;CARIAN LETTER B;Lo;0;L;;;;;N;;;;;\n102AA;CARIAN LETTER M;Lo;0;L;;;;;N;;;;;\n102AB;CARIAN LETTER O;Lo;0;L;;;;;N;;;;;\n102AC;CARIAN LETTER D2;Lo;0;L;;;;;N;;;;;\n102AD;CARIAN LETTER T;Lo;0;L;;;;;N;;;;;\n102AE;CARIAN LETTER SH;Lo;0;L;;;;;N;;;;;\n102AF;CARIAN LETTER SH2;Lo;0;L;;;;;N;;;;;\n102B0;CARIAN LETTER S;Lo;0;L;;;;;N;;;;;\n102B1;CARIAN LETTER C-18;Lo;0;L;;;;;N;;;;;\n102B2;CARIAN LETTER U;Lo;0;L;;;;;N;;;;;\n102B3;CARIAN LETTER NN;Lo;0;L;;;;;N;;;;;\n102B4;CARIAN LETTER X;Lo;0;L;;;;;N;;;;;\n102B5;CARIAN LETTER N;Lo;0;L;;;;;N;;;;;\n102B6;CARIAN LETTER TT2;Lo;0;L;;;;;N;;;;;\n102B7;CARIAN LETTER P;Lo;0;L;;;;;N;;;;;\n102B8;CARIAN LETTER SS;Lo;0;L;;;;;N;;;;;\n102B9;CARIAN LETTER I;Lo;0;L;;;;;N;;;;;\n102BA;CARIAN LETTER E;Lo;0;L;;;;;N;;;;;\n102BB;CARIAN LETTER UUUU;Lo;0;L;;;;;N;;;;;\n102BC;CARIAN LETTER K;Lo;0;L;;;;;N;;;;;\n102BD;CARIAN LETTER K2;Lo;0;L;;;;;N;;;;;\n102BE;CARIAN LETTER ND;Lo;0;L;;;;;N;;;;;\n102BF;CARIAN LETTER UU;Lo;0;L;;;;;N;;;;;\n102C0;CARIAN LETTER G;Lo;0;L;;;;;N;;;;;\n102C1;CARIAN LETTER G2;Lo;0;L;;;;;N;;;;;\n102C2;CARIAN LETTER ST;Lo;0;L;;;;;N;;;;;\n102C3;CARIAN LETTER ST2;Lo;0;L;;;;;N;;;;;\n102C4;CARIAN LETTER NG;Lo;0;L;;;;;N;;;;;\n102C5;CARIAN LETTER II;Lo;0;L;;;;;N;;;;;\n102C6;CARIAN LETTER C-39;Lo;0;L;;;;;N;;;;;\n102C7;CARIAN LETTER TT;Lo;0;L;;;;;N;;;;;\n102C8;CARIAN LETTER UUU2;Lo;0;L;;;;;N;;;;;\n102C9;CARIAN LETTER RR;Lo;0;L;;;;;N;;;;;\n102CA;CARIAN LETTER MB;Lo;0;L;;;;;N;;;;;\n102CB;CARIAN LETTER MB2;Lo;0;L;;;;;N;;;;;\n102CC;CARIAN LETTER MB3;Lo;0;L;;;;;N;;;;;\n102CD;CARIAN LETTER MB4;Lo;0;L;;;;;N;;;;;\n102CE;CARIAN LETTER LD2;Lo;0;L;;;;;N;;;;;\n102CF;CARIAN LETTER E2;Lo;0;L;;;;;N;;;;;\n102D0;CARIAN LETTER UUU3;Lo;0;L;;;;;N;;;;;\n102E0;COPTIC EPACT THOUSANDS MARK;Mn;220;NSM;;;;;N;;;;;\n102E1;COPTIC EPACT DIGIT ONE;No;0;EN;;;;1;N;;;;;\n102E2;COPTIC EPACT DIGIT TWO;No;0;EN;;;;2;N;;;;;\n102E3;COPTIC EPACT DIGIT THREE;No;0;EN;;;;3;N;;;;;\n102E4;COPTIC EPACT DIGIT FOUR;No;0;EN;;;;4;N;;;;;\n102E5;COPTIC EPACT DIGIT FIVE;No;0;EN;;;;5;N;;;;;\n102E6;COPTIC EPACT DIGIT SIX;No;0;EN;;;;6;N;;;;;\n102E7;COPTIC EPACT DIGIT SEVEN;No;0;EN;;;;7;N;;;;;\n102E8;COPTIC EPACT DIGIT EIGHT;No;0;EN;;;;8;N;;;;;\n102E9;COPTIC EPACT DIGIT NINE;No;0;EN;;;;9;N;;;;;\n102EA;COPTIC EPACT NUMBER TEN;No;0;EN;;;;10;N;;;;;\n102EB;COPTIC EPACT NUMBER TWENTY;No;0;EN;;;;20;N;;;;;\n102EC;COPTIC EPACT NUMBER THIRTY;No;0;EN;;;;30;N;;;;;\n102ED;COPTIC EPACT NUMBER FORTY;No;0;EN;;;;40;N;;;;;\n102EE;COPTIC EPACT NUMBER FIFTY;No;0;EN;;;;50;N;;;;;\n102EF;COPTIC EPACT NUMBER SIXTY;No;0;EN;;;;60;N;;;;;\n102F0;COPTIC EPACT NUMBER SEVENTY;No;0;EN;;;;70;N;;;;;\n102F1;COPTIC EPACT NUMBER EIGHTY;No;0;EN;;;;80;N;;;;;\n102F2;COPTIC EPACT NUMBER NINETY;No;0;EN;;;;90;N;;;;;\n102F3;COPTIC EPACT NUMBER ONE HUNDRED;No;0;EN;;;;100;N;;;;;\n102F4;COPTIC EPACT NUMBER TWO HUNDRED;No;0;EN;;;;200;N;;;;;\n102F5;COPTIC EPACT NUMBER THREE HUNDRED;No;0;EN;;;;300;N;;;;;\n102F6;COPTIC EPACT NUMBER FOUR HUNDRED;No;0;EN;;;;400;N;;;;;\n102F7;COPTIC EPACT NUMBER FIVE HUNDRED;No;0;EN;;;;500;N;;;;;\n102F8;COPTIC EPACT NUMBER SIX HUNDRED;No;0;EN;;;;600;N;;;;;\n102F9;COPTIC EPACT NUMBER SEVEN HUNDRED;No;0;EN;;;;700;N;;;;;\n102FA;COPTIC EPACT NUMBER EIGHT HUNDRED;No;0;EN;;;;800;N;;;;;\n102FB;COPTIC EPACT NUMBER NINE HUNDRED;No;0;EN;;;;900;N;;;;;\n10300;OLD ITALIC LETTER A;Lo;0;L;;;;;N;;;;;\n10301;OLD ITALIC LETTER BE;Lo;0;L;;;;;N;;;;;\n10302;OLD ITALIC LETTER KE;Lo;0;L;;;;;N;;;;;\n10303;OLD ITALIC LETTER DE;Lo;0;L;;;;;N;;;;;\n10304;OLD ITALIC LETTER E;Lo;0;L;;;;;N;;;;;\n10305;OLD ITALIC LETTER VE;Lo;0;L;;;;;N;;;;;\n10306;OLD ITALIC LETTER ZE;Lo;0;L;;;;;N;;;;;\n10307;OLD ITALIC LETTER HE;Lo;0;L;;;;;N;;;;;\n10308;OLD ITALIC LETTER THE;Lo;0;L;;;;;N;;;;;\n10309;OLD ITALIC LETTER I;Lo;0;L;;;;;N;;;;;\n1030A;OLD ITALIC LETTER KA;Lo;0;L;;;;;N;;;;;\n1030B;OLD ITALIC LETTER EL;Lo;0;L;;;;;N;;;;;\n1030C;OLD ITALIC LETTER EM;Lo;0;L;;;;;N;;;;;\n1030D;OLD ITALIC LETTER EN;Lo;0;L;;;;;N;;;;;\n1030E;OLD ITALIC LETTER ESH;Lo;0;L;;;;;N;;;;;\n1030F;OLD ITALIC LETTER O;Lo;0;L;;;;;N;;;;;\n10310;OLD ITALIC LETTER PE;Lo;0;L;;;;;N;;;;;\n10311;OLD ITALIC LETTER SHE;Lo;0;L;;;;;N;;;;;\n10312;OLD ITALIC LETTER KU;Lo;0;L;;;;;N;;;;;\n10313;OLD ITALIC LETTER ER;Lo;0;L;;;;;N;;;;;\n10314;OLD ITALIC LETTER ES;Lo;0;L;;;;;N;;;;;\n10315;OLD ITALIC LETTER TE;Lo;0;L;;;;;N;;;;;\n10316;OLD ITALIC LETTER U;Lo;0;L;;;;;N;;;;;\n10317;OLD ITALIC LETTER EKS;Lo;0;L;;;;;N;;;;;\n10318;OLD ITALIC LETTER PHE;Lo;0;L;;;;;N;;;;;\n10319;OLD ITALIC LETTER KHE;Lo;0;L;;;;;N;;;;;\n1031A;OLD ITALIC LETTER EF;Lo;0;L;;;;;N;;;;;\n1031B;OLD ITALIC LETTER ERS;Lo;0;L;;;;;N;;;;;\n1031C;OLD ITALIC LETTER CHE;Lo;0;L;;;;;N;;;;;\n1031D;OLD ITALIC LETTER II;Lo;0;L;;;;;N;;;;;\n1031E;OLD ITALIC LETTER UU;Lo;0;L;;;;;N;;;;;\n1031F;OLD ITALIC LETTER ESS;Lo;0;L;;;;;N;;;;;\n10320;OLD ITALIC NUMERAL ONE;No;0;L;;;;1;N;;;;;\n10321;OLD ITALIC NUMERAL FIVE;No;0;L;;;;5;N;;;;;\n10322;OLD ITALIC NUMERAL TEN;No;0;L;;;;10;N;;;;;\n10323;OLD ITALIC NUMERAL FIFTY;No;0;L;;;;50;N;;;;;\n1032D;OLD ITALIC LETTER YE;Lo;0;L;;;;;N;;;;;\n1032E;OLD ITALIC LETTER NORTHERN TSE;Lo;0;L;;;;;N;;;;;\n1032F;OLD ITALIC LETTER SOUTHERN TSE;Lo;0;L;;;;;N;;;;;\n10330;GOTHIC LETTER AHSA;Lo;0;L;;;;;N;;;;;\n10331;GOTHIC LETTER BAIRKAN;Lo;0;L;;;;;N;;;;;\n10332;GOTHIC LETTER GIBA;Lo;0;L;;;;;N;;;;;\n10333;GOTHIC LETTER DAGS;Lo;0;L;;;;;N;;;;;\n10334;GOTHIC LETTER AIHVUS;Lo;0;L;;;;;N;;;;;\n10335;GOTHIC LETTER QAIRTHRA;Lo;0;L;;;;;N;;;;;\n10336;GOTHIC LETTER IUJA;Lo;0;L;;;;;N;;;;;\n10337;GOTHIC LETTER HAGL;Lo;0;L;;;;;N;;;;;\n10338;GOTHIC LETTER THIUTH;Lo;0;L;;;;;N;;;;;\n10339;GOTHIC LETTER EIS;Lo;0;L;;;;;N;;;;;\n1033A;GOTHIC LETTER KUSMA;Lo;0;L;;;;;N;;;;;\n1033B;GOTHIC LETTER LAGUS;Lo;0;L;;;;;N;;;;;\n1033C;GOTHIC LETTER MANNA;Lo;0;L;;;;;N;;;;;\n1033D;GOTHIC LETTER NAUTHS;Lo;0;L;;;;;N;;;;;\n1033E;GOTHIC LETTER JER;Lo;0;L;;;;;N;;;;;\n1033F;GOTHIC LETTER URUS;Lo;0;L;;;;;N;;;;;\n10340;GOTHIC LETTER PAIRTHRA;Lo;0;L;;;;;N;;;;;\n10341;GOTHIC LETTER NINETY;Nl;0;L;;;;90;N;;;;;\n10342;GOTHIC LETTER RAIDA;Lo;0;L;;;;;N;;;;;\n10343;GOTHIC LETTER SAUIL;Lo;0;L;;;;;N;;;;;\n10344;GOTHIC LETTER TEIWS;Lo;0;L;;;;;N;;;;;\n10345;GOTHIC LETTER WINJA;Lo;0;L;;;;;N;;;;;\n10346;GOTHIC LETTER FAIHU;Lo;0;L;;;;;N;;;;;\n10347;GOTHIC LETTER IGGWS;Lo;0;L;;;;;N;;;;;\n10348;GOTHIC LETTER HWAIR;Lo;0;L;;;;;N;;;;;\n10349;GOTHIC LETTER OTHAL;Lo;0;L;;;;;N;;;;;\n1034A;GOTHIC LETTER NINE HUNDRED;Nl;0;L;;;;900;N;;;;;\n10350;OLD PERMIC LETTER AN;Lo;0;L;;;;;N;;;;;\n10351;OLD PERMIC LETTER BUR;Lo;0;L;;;;;N;;;;;\n10352;OLD PERMIC LETTER GAI;Lo;0;L;;;;;N;;;;;\n10353;OLD PERMIC LETTER DOI;Lo;0;L;;;;;N;;;;;\n10354;OLD PERMIC LETTER E;Lo;0;L;;;;;N;;;;;\n10355;OLD PERMIC LETTER ZHOI;Lo;0;L;;;;;N;;;;;\n10356;OLD PERMIC LETTER DZHOI;Lo;0;L;;;;;N;;;;;\n10357;OLD PERMIC LETTER ZATA;Lo;0;L;;;;;N;;;;;\n10358;OLD PERMIC LETTER DZITA;Lo;0;L;;;;;N;;;;;\n10359;OLD PERMIC LETTER I;Lo;0;L;;;;;N;;;;;\n1035A;OLD PERMIC LETTER KOKE;Lo;0;L;;;;;N;;;;;\n1035B;OLD PERMIC LETTER LEI;Lo;0;L;;;;;N;;;;;\n1035C;OLD PERMIC LETTER MENOE;Lo;0;L;;;;;N;;;;;\n1035D;OLD PERMIC LETTER NENOE;Lo;0;L;;;;;N;;;;;\n1035E;OLD PERMIC LETTER VOOI;Lo;0;L;;;;;N;;;;;\n1035F;OLD PERMIC LETTER PEEI;Lo;0;L;;;;;N;;;;;\n10360;OLD PERMIC LETTER REI;Lo;0;L;;;;;N;;;;;\n10361;OLD PERMIC LETTER SII;Lo;0;L;;;;;N;;;;;\n10362;OLD PERMIC LETTER TAI;Lo;0;L;;;;;N;;;;;\n10363;OLD PERMIC LETTER U;Lo;0;L;;;;;N;;;;;\n10364;OLD PERMIC LETTER CHERY;Lo;0;L;;;;;N;;;;;\n10365;OLD PERMIC LETTER SHOOI;Lo;0;L;;;;;N;;;;;\n10366;OLD PERMIC LETTER SHCHOOI;Lo;0;L;;;;;N;;;;;\n10367;OLD PERMIC LETTER YRY;Lo;0;L;;;;;N;;;;;\n10368;OLD PERMIC LETTER YERU;Lo;0;L;;;;;N;;;;;\n10369;OLD PERMIC LETTER O;Lo;0;L;;;;;N;;;;;\n1036A;OLD PERMIC LETTER OO;Lo;0;L;;;;;N;;;;;\n1036B;OLD PERMIC LETTER EF;Lo;0;L;;;;;N;;;;;\n1036C;OLD PERMIC LETTER HA;Lo;0;L;;;;;N;;;;;\n1036D;OLD PERMIC LETTER TSIU;Lo;0;L;;;;;N;;;;;\n1036E;OLD PERMIC LETTER VER;Lo;0;L;;;;;N;;;;;\n1036F;OLD PERMIC LETTER YER;Lo;0;L;;;;;N;;;;;\n10370;OLD PERMIC LETTER YERI;Lo;0;L;;;;;N;;;;;\n10371;OLD PERMIC LETTER YAT;Lo;0;L;;;;;N;;;;;\n10372;OLD PERMIC LETTER IE;Lo;0;L;;;;;N;;;;;\n10373;OLD PERMIC LETTER YU;Lo;0;L;;;;;N;;;;;\n10374;OLD PERMIC LETTER YA;Lo;0;L;;;;;N;;;;;\n10375;OLD PERMIC LETTER IA;Lo;0;L;;;;;N;;;;;\n10376;COMBINING OLD PERMIC LETTER AN;Mn;230;NSM;;;;;N;;;;;\n10377;COMBINING OLD PERMIC LETTER DOI;Mn;230;NSM;;;;;N;;;;;\n10378;COMBINING OLD PERMIC LETTER ZATA;Mn;230;NSM;;;;;N;;;;;\n10379;COMBINING OLD PERMIC LETTER NENOE;Mn;230;NSM;;;;;N;;;;;\n1037A;COMBINING OLD PERMIC LETTER SII;Mn;230;NSM;;;;;N;;;;;\n10380;UGARITIC LETTER ALPA;Lo;0;L;;;;;N;;;;;\n10381;UGARITIC LETTER BETA;Lo;0;L;;;;;N;;;;;\n10382;UGARITIC LETTER GAMLA;Lo;0;L;;;;;N;;;;;\n10383;UGARITIC LETTER KHA;Lo;0;L;;;;;N;;;;;\n10384;UGARITIC LETTER DELTA;Lo;0;L;;;;;N;;;;;\n10385;UGARITIC LETTER HO;Lo;0;L;;;;;N;;;;;\n10386;UGARITIC LETTER WO;Lo;0;L;;;;;N;;;;;\n10387;UGARITIC LETTER ZETA;Lo;0;L;;;;;N;;;;;\n10388;UGARITIC LETTER HOTA;Lo;0;L;;;;;N;;;;;\n10389;UGARITIC LETTER TET;Lo;0;L;;;;;N;;;;;\n1038A;UGARITIC LETTER YOD;Lo;0;L;;;;;N;;;;;\n1038B;UGARITIC LETTER KAF;Lo;0;L;;;;;N;;;;;\n1038C;UGARITIC LETTER SHIN;Lo;0;L;;;;;N;;;;;\n1038D;UGARITIC LETTER LAMDA;Lo;0;L;;;;;N;;;;;\n1038E;UGARITIC LETTER MEM;Lo;0;L;;;;;N;;;;;\n1038F;UGARITIC LETTER DHAL;Lo;0;L;;;;;N;;;;;\n10390;UGARITIC LETTER NUN;Lo;0;L;;;;;N;;;;;\n10391;UGARITIC LETTER ZU;Lo;0;L;;;;;N;;;;;\n10392;UGARITIC LETTER SAMKA;Lo;0;L;;;;;N;;;;;\n10393;UGARITIC LETTER AIN;Lo;0;L;;;;;N;;;;;\n10394;UGARITIC LETTER PU;Lo;0;L;;;;;N;;;;;\n10395;UGARITIC LETTER SADE;Lo;0;L;;;;;N;;;;;\n10396;UGARITIC LETTER QOPA;Lo;0;L;;;;;N;;;;;\n10397;UGARITIC LETTER RASHA;Lo;0;L;;;;;N;;;;;\n10398;UGARITIC LETTER THANNA;Lo;0;L;;;;;N;;;;;\n10399;UGARITIC LETTER GHAIN;Lo;0;L;;;;;N;;;;;\n1039A;UGARITIC LETTER TO;Lo;0;L;;;;;N;;;;;\n1039B;UGARITIC LETTER I;Lo;0;L;;;;;N;;;;;\n1039C;UGARITIC LETTER U;Lo;0;L;;;;;N;;;;;\n1039D;UGARITIC LETTER SSU;Lo;0;L;;;;;N;;;;;\n1039F;UGARITIC WORD DIVIDER;Po;0;L;;;;;N;;;;;\n103A0;OLD PERSIAN SIGN A;Lo;0;L;;;;;N;;;;;\n103A1;OLD PERSIAN SIGN I;Lo;0;L;;;;;N;;;;;\n103A2;OLD PERSIAN SIGN U;Lo;0;L;;;;;N;;;;;\n103A3;OLD PERSIAN SIGN KA;Lo;0;L;;;;;N;;;;;\n103A4;OLD PERSIAN SIGN KU;Lo;0;L;;;;;N;;;;;\n103A5;OLD PERSIAN SIGN GA;Lo;0;L;;;;;N;;;;;\n103A6;OLD PERSIAN SIGN GU;Lo;0;L;;;;;N;;;;;\n103A7;OLD PERSIAN SIGN XA;Lo;0;L;;;;;N;;;;;\n103A8;OLD PERSIAN SIGN CA;Lo;0;L;;;;;N;;;;;\n103A9;OLD PERSIAN SIGN JA;Lo;0;L;;;;;N;;;;;\n103AA;OLD PERSIAN SIGN JI;Lo;0;L;;;;;N;;;;;\n103AB;OLD PERSIAN SIGN TA;Lo;0;L;;;;;N;;;;;\n103AC;OLD PERSIAN SIGN TU;Lo;0;L;;;;;N;;;;;\n103AD;OLD PERSIAN SIGN DA;Lo;0;L;;;;;N;;;;;\n103AE;OLD PERSIAN SIGN DI;Lo;0;L;;;;;N;;;;;\n103AF;OLD PERSIAN SIGN DU;Lo;0;L;;;;;N;;;;;\n103B0;OLD PERSIAN SIGN THA;Lo;0;L;;;;;N;;;;;\n103B1;OLD PERSIAN SIGN PA;Lo;0;L;;;;;N;;;;;\n103B2;OLD PERSIAN SIGN BA;Lo;0;L;;;;;N;;;;;\n103B3;OLD PERSIAN SIGN FA;Lo;0;L;;;;;N;;;;;\n103B4;OLD PERSIAN SIGN NA;Lo;0;L;;;;;N;;;;;\n103B5;OLD PERSIAN SIGN NU;Lo;0;L;;;;;N;;;;;\n103B6;OLD PERSIAN SIGN MA;Lo;0;L;;;;;N;;;;;\n103B7;OLD PERSIAN SIGN MI;Lo;0;L;;;;;N;;;;;\n103B8;OLD PERSIAN SIGN MU;Lo;0;L;;;;;N;;;;;\n103B9;OLD PERSIAN SIGN YA;Lo;0;L;;;;;N;;;;;\n103BA;OLD PERSIAN SIGN VA;Lo;0;L;;;;;N;;;;;\n103BB;OLD PERSIAN SIGN VI;Lo;0;L;;;;;N;;;;;\n103BC;OLD PERSIAN SIGN RA;Lo;0;L;;;;;N;;;;;\n103BD;OLD PERSIAN SIGN RU;Lo;0;L;;;;;N;;;;;\n103BE;OLD PERSIAN SIGN LA;Lo;0;L;;;;;N;;;;;\n103BF;OLD PERSIAN SIGN SA;Lo;0;L;;;;;N;;;;;\n103C0;OLD PERSIAN SIGN ZA;Lo;0;L;;;;;N;;;;;\n103C1;OLD PERSIAN SIGN SHA;Lo;0;L;;;;;N;;;;;\n103C2;OLD PERSIAN SIGN SSA;Lo;0;L;;;;;N;;;;;\n103C3;OLD PERSIAN SIGN HA;Lo;0;L;;;;;N;;;;;\n103C8;OLD PERSIAN SIGN AURAMAZDAA;Lo;0;L;;;;;N;;;;;\n103C9;OLD PERSIAN SIGN AURAMAZDAA-2;Lo;0;L;;;;;N;;;;;\n103CA;OLD PERSIAN SIGN AURAMAZDAAHA;Lo;0;L;;;;;N;;;;;\n103CB;OLD PERSIAN SIGN XSHAAYATHIYA;Lo;0;L;;;;;N;;;;;\n103CC;OLD PERSIAN SIGN DAHYAAUSH;Lo;0;L;;;;;N;;;;;\n103CD;OLD PERSIAN SIGN DAHYAAUSH-2;Lo;0;L;;;;;N;;;;;\n103CE;OLD PERSIAN SIGN BAGA;Lo;0;L;;;;;N;;;;;\n103CF;OLD PERSIAN SIGN BUUMISH;Lo;0;L;;;;;N;;;;;\n103D0;OLD PERSIAN WORD DIVIDER;Po;0;L;;;;;N;;;;;\n103D1;OLD PERSIAN NUMBER ONE;Nl;0;L;;;;1;N;;;;;\n103D2;OLD PERSIAN NUMBER TWO;Nl;0;L;;;;2;N;;;;;\n103D3;OLD PERSIAN NUMBER TEN;Nl;0;L;;;;10;N;;;;;\n103D4;OLD PERSIAN NUMBER TWENTY;Nl;0;L;;;;20;N;;;;;\n103D5;OLD PERSIAN NUMBER HUNDRED;Nl;0;L;;;;100;N;;;;;\n10400;DESERET CAPITAL LETTER LONG I;Lu;0;L;;;;;N;;;;10428;\n10401;DESERET CAPITAL LETTER LONG E;Lu;0;L;;;;;N;;;;10429;\n10402;DESERET CAPITAL LETTER LONG A;Lu;0;L;;;;;N;;;;1042A;\n10403;DESERET CAPITAL LETTER LONG AH;Lu;0;L;;;;;N;;;;1042B;\n10404;DESERET CAPITAL LETTER LONG O;Lu;0;L;;;;;N;;;;1042C;\n10405;DESERET CAPITAL LETTER LONG OO;Lu;0;L;;;;;N;;;;1042D;\n10406;DESERET CAPITAL LETTER SHORT I;Lu;0;L;;;;;N;;;;1042E;\n10407;DESERET CAPITAL LETTER SHORT E;Lu;0;L;;;;;N;;;;1042F;\n10408;DESERET CAPITAL LETTER SHORT A;Lu;0;L;;;;;N;;;;10430;\n10409;DESERET CAPITAL LETTER SHORT AH;Lu;0;L;;;;;N;;;;10431;\n1040A;DESERET CAPITAL LETTER SHORT O;Lu;0;L;;;;;N;;;;10432;\n1040B;DESERET CAPITAL LETTER SHORT OO;Lu;0;L;;;;;N;;;;10433;\n1040C;DESERET CAPITAL LETTER AY;Lu;0;L;;;;;N;;;;10434;\n1040D;DESERET CAPITAL LETTER OW;Lu;0;L;;;;;N;;;;10435;\n1040E;DESERET CAPITAL LETTER WU;Lu;0;L;;;;;N;;;;10436;\n1040F;DESERET CAPITAL LETTER YEE;Lu;0;L;;;;;N;;;;10437;\n10410;DESERET CAPITAL LETTER H;Lu;0;L;;;;;N;;;;10438;\n10411;DESERET CAPITAL LETTER PEE;Lu;0;L;;;;;N;;;;10439;\n10412;DESERET CAPITAL LETTER BEE;Lu;0;L;;;;;N;;;;1043A;\n10413;DESERET CAPITAL LETTER TEE;Lu;0;L;;;;;N;;;;1043B;\n10414;DESERET CAPITAL LETTER DEE;Lu;0;L;;;;;N;;;;1043C;\n10415;DESERET CAPITAL LETTER CHEE;Lu;0;L;;;;;N;;;;1043D;\n10416;DESERET CAPITAL LETTER JEE;Lu;0;L;;;;;N;;;;1043E;\n10417;DESERET CAPITAL LETTER KAY;Lu;0;L;;;;;N;;;;1043F;\n10418;DESERET CAPITAL LETTER GAY;Lu;0;L;;;;;N;;;;10440;\n10419;DESERET CAPITAL LETTER EF;Lu;0;L;;;;;N;;;;10441;\n1041A;DESERET CAPITAL LETTER VEE;Lu;0;L;;;;;N;;;;10442;\n1041B;DESERET CAPITAL LETTER ETH;Lu;0;L;;;;;N;;;;10443;\n1041C;DESERET CAPITAL LETTER THEE;Lu;0;L;;;;;N;;;;10444;\n1041D;DESERET CAPITAL LETTER ES;Lu;0;L;;;;;N;;;;10445;\n1041E;DESERET CAPITAL LETTER ZEE;Lu;0;L;;;;;N;;;;10446;\n1041F;DESERET CAPITAL LETTER ESH;Lu;0;L;;;;;N;;;;10447;\n10420;DESERET CAPITAL LETTER ZHEE;Lu;0;L;;;;;N;;;;10448;\n10421;DESERET CAPITAL LETTER ER;Lu;0;L;;;;;N;;;;10449;\n10422;DESERET CAPITAL LETTER EL;Lu;0;L;;;;;N;;;;1044A;\n10423;DESERET CAPITAL LETTER EM;Lu;0;L;;;;;N;;;;1044B;\n10424;DESERET CAPITAL LETTER EN;Lu;0;L;;;;;N;;;;1044C;\n10425;DESERET CAPITAL LETTER ENG;Lu;0;L;;;;;N;;;;1044D;\n10426;DESERET CAPITAL LETTER OI;Lu;0;L;;;;;N;;;;1044E;\n10427;DESERET CAPITAL LETTER EW;Lu;0;L;;;;;N;;;;1044F;\n10428;DESERET SMALL LETTER LONG I;Ll;0;L;;;;;N;;;10400;;10400\n10429;DESERET SMALL LETTER LONG E;Ll;0;L;;;;;N;;;10401;;10401\n1042A;DESERET SMALL LETTER LONG A;Ll;0;L;;;;;N;;;10402;;10402\n1042B;DESERET SMALL LETTER LONG AH;Ll;0;L;;;;;N;;;10403;;10403\n1042C;DESERET SMALL LETTER LONG O;Ll;0;L;;;;;N;;;10404;;10404\n1042D;DESERET SMALL LETTER LONG OO;Ll;0;L;;;;;N;;;10405;;10405\n1042E;DESERET SMALL LETTER SHORT I;Ll;0;L;;;;;N;;;10406;;10406\n1042F;DESERET SMALL LETTER SHORT E;Ll;0;L;;;;;N;;;10407;;10407\n10430;DESERET SMALL LETTER SHORT A;Ll;0;L;;;;;N;;;10408;;10408\n10431;DESERET SMALL LETTER SHORT AH;Ll;0;L;;;;;N;;;10409;;10409\n10432;DESERET SMALL LETTER SHORT O;Ll;0;L;;;;;N;;;1040A;;1040A\n10433;DESERET SMALL LETTER SHORT OO;Ll;0;L;;;;;N;;;1040B;;1040B\n10434;DESERET SMALL LETTER AY;Ll;0;L;;;;;N;;;1040C;;1040C\n10435;DESERET SMALL LETTER OW;Ll;0;L;;;;;N;;;1040D;;1040D\n10436;DESERET SMALL LETTER WU;Ll;0;L;;;;;N;;;1040E;;1040E\n10437;DESERET SMALL LETTER YEE;Ll;0;L;;;;;N;;;1040F;;1040F\n10438;DESERET SMALL LETTER H;Ll;0;L;;;;;N;;;10410;;10410\n10439;DESERET SMALL LETTER PEE;Ll;0;L;;;;;N;;;10411;;10411\n1043A;DESERET SMALL LETTER BEE;Ll;0;L;;;;;N;;;10412;;10412\n1043B;DESERET SMALL LETTER TEE;Ll;0;L;;;;;N;;;10413;;10413\n1043C;DESERET SMALL LETTER DEE;Ll;0;L;;;;;N;;;10414;;10414\n1043D;DESERET SMALL LETTER CHEE;Ll;0;L;;;;;N;;;10415;;10415\n1043E;DESERET SMALL LETTER JEE;Ll;0;L;;;;;N;;;10416;;10416\n1043F;DESERET SMALL LETTER KAY;Ll;0;L;;;;;N;;;10417;;10417\n10440;DESERET SMALL LETTER GAY;Ll;0;L;;;;;N;;;10418;;10418\n10441;DESERET SMALL LETTER EF;Ll;0;L;;;;;N;;;10419;;10419\n10442;DESERET SMALL LETTER VEE;Ll;0;L;;;;;N;;;1041A;;1041A\n10443;DESERET SMALL LETTER ETH;Ll;0;L;;;;;N;;;1041B;;1041B\n10444;DESERET SMALL LETTER THEE;Ll;0;L;;;;;N;;;1041C;;1041C\n10445;DESERET SMALL LETTER ES;Ll;0;L;;;;;N;;;1041D;;1041D\n10446;DESERET SMALL LETTER ZEE;Ll;0;L;;;;;N;;;1041E;;1041E\n10447;DESERET SMALL LETTER ESH;Ll;0;L;;;;;N;;;1041F;;1041F\n10448;DESERET SMALL LETTER ZHEE;Ll;0;L;;;;;N;;;10420;;10420\n10449;DESERET SMALL LETTER ER;Ll;0;L;;;;;N;;;10421;;10421\n1044A;DESERET SMALL LETTER EL;Ll;0;L;;;;;N;;;10422;;10422\n1044B;DESERET SMALL LETTER EM;Ll;0;L;;;;;N;;;10423;;10423\n1044C;DESERET SMALL LETTER EN;Ll;0;L;;;;;N;;;10424;;10424\n1044D;DESERET SMALL LETTER ENG;Ll;0;L;;;;;N;;;10425;;10425\n1044E;DESERET SMALL LETTER OI;Ll;0;L;;;;;N;;;10426;;10426\n1044F;DESERET SMALL LETTER EW;Ll;0;L;;;;;N;;;10427;;10427\n10450;SHAVIAN LETTER PEEP;Lo;0;L;;;;;N;;;;;\n10451;SHAVIAN LETTER TOT;Lo;0;L;;;;;N;;;;;\n10452;SHAVIAN LETTER KICK;Lo;0;L;;;;;N;;;;;\n10453;SHAVIAN LETTER FEE;Lo;0;L;;;;;N;;;;;\n10454;SHAVIAN LETTER THIGH;Lo;0;L;;;;;N;;;;;\n10455;SHAVIAN LETTER SO;Lo;0;L;;;;;N;;;;;\n10456;SHAVIAN LETTER SURE;Lo;0;L;;;;;N;;;;;\n10457;SHAVIAN LETTER CHURCH;Lo;0;L;;;;;N;;;;;\n10458;SHAVIAN LETTER YEA;Lo;0;L;;;;;N;;;;;\n10459;SHAVIAN LETTER HUNG;Lo;0;L;;;;;N;;;;;\n1045A;SHAVIAN LETTER BIB;Lo;0;L;;;;;N;;;;;\n1045B;SHAVIAN LETTER DEAD;Lo;0;L;;;;;N;;;;;\n1045C;SHAVIAN LETTER GAG;Lo;0;L;;;;;N;;;;;\n1045D;SHAVIAN LETTER VOW;Lo;0;L;;;;;N;;;;;\n1045E;SHAVIAN LETTER THEY;Lo;0;L;;;;;N;;;;;\n1045F;SHAVIAN LETTER ZOO;Lo;0;L;;;;;N;;;;;\n10460;SHAVIAN LETTER MEASURE;Lo;0;L;;;;;N;;;;;\n10461;SHAVIAN LETTER JUDGE;Lo;0;L;;;;;N;;;;;\n10462;SHAVIAN LETTER WOE;Lo;0;L;;;;;N;;;;;\n10463;SHAVIAN LETTER HA-HA;Lo;0;L;;;;;N;;;;;\n10464;SHAVIAN LETTER LOLL;Lo;0;L;;;;;N;;;;;\n10465;SHAVIAN LETTER MIME;Lo;0;L;;;;;N;;;;;\n10466;SHAVIAN LETTER IF;Lo;0;L;;;;;N;;;;;\n10467;SHAVIAN LETTER EGG;Lo;0;L;;;;;N;;;;;\n10468;SHAVIAN LETTER ASH;Lo;0;L;;;;;N;;;;;\n10469;SHAVIAN LETTER ADO;Lo;0;L;;;;;N;;;;;\n1046A;SHAVIAN LETTER ON;Lo;0;L;;;;;N;;;;;\n1046B;SHAVIAN LETTER WOOL;Lo;0;L;;;;;N;;;;;\n1046C;SHAVIAN LETTER OUT;Lo;0;L;;;;;N;;;;;\n1046D;SHAVIAN LETTER AH;Lo;0;L;;;;;N;;;;;\n1046E;SHAVIAN LETTER ROAR;Lo;0;L;;;;;N;;;;;\n1046F;SHAVIAN LETTER NUN;Lo;0;L;;;;;N;;;;;\n10470;SHAVIAN LETTER EAT;Lo;0;L;;;;;N;;;;;\n10471;SHAVIAN LETTER AGE;Lo;0;L;;;;;N;;;;;\n10472;SHAVIAN LETTER ICE;Lo;0;L;;;;;N;;;;;\n10473;SHAVIAN LETTER UP;Lo;0;L;;;;;N;;;;;\n10474;SHAVIAN LETTER OAK;Lo;0;L;;;;;N;;;;;\n10475;SHAVIAN LETTER OOZE;Lo;0;L;;;;;N;;;;;\n10476;SHAVIAN LETTER OIL;Lo;0;L;;;;;N;;;;;\n10477;SHAVIAN LETTER AWE;Lo;0;L;;;;;N;;;;;\n10478;SHAVIAN LETTER ARE;Lo;0;L;;;;;N;;;;;\n10479;SHAVIAN LETTER OR;Lo;0;L;;;;;N;;;;;\n1047A;SHAVIAN LETTER AIR;Lo;0;L;;;;;N;;;;;\n1047B;SHAVIAN LETTER ERR;Lo;0;L;;;;;N;;;;;\n1047C;SHAVIAN LETTER ARRAY;Lo;0;L;;;;;N;;;;;\n1047D;SHAVIAN LETTER EAR;Lo;0;L;;;;;N;;;;;\n1047E;SHAVIAN LETTER IAN;Lo;0;L;;;;;N;;;;;\n1047F;SHAVIAN LETTER YEW;Lo;0;L;;;;;N;;;;;\n10480;OSMANYA LETTER ALEF;Lo;0;L;;;;;N;;;;;\n10481;OSMANYA LETTER BA;Lo;0;L;;;;;N;;;;;\n10482;OSMANYA LETTER TA;Lo;0;L;;;;;N;;;;;\n10483;OSMANYA LETTER JA;Lo;0;L;;;;;N;;;;;\n10484;OSMANYA LETTER XA;Lo;0;L;;;;;N;;;;;\n10485;OSMANYA LETTER KHA;Lo;0;L;;;;;N;;;;;\n10486;OSMANYA LETTER DEEL;Lo;0;L;;;;;N;;;;;\n10487;OSMANYA LETTER RA;Lo;0;L;;;;;N;;;;;\n10488;OSMANYA LETTER SA;Lo;0;L;;;;;N;;;;;\n10489;OSMANYA LETTER SHIIN;Lo;0;L;;;;;N;;;;;\n1048A;OSMANYA LETTER DHA;Lo;0;L;;;;;N;;;;;\n1048B;OSMANYA LETTER CAYN;Lo;0;L;;;;;N;;;;;\n1048C;OSMANYA LETTER GA;Lo;0;L;;;;;N;;;;;\n1048D;OSMANYA LETTER FA;Lo;0;L;;;;;N;;;;;\n1048E;OSMANYA LETTER QAAF;Lo;0;L;;;;;N;;;;;\n1048F;OSMANYA LETTER KAAF;Lo;0;L;;;;;N;;;;;\n10490;OSMANYA LETTER LAAN;Lo;0;L;;;;;N;;;;;\n10491;OSMANYA LETTER MIIN;Lo;0;L;;;;;N;;;;;\n10492;OSMANYA LETTER NUUN;Lo;0;L;;;;;N;;;;;\n10493;OSMANYA LETTER WAW;Lo;0;L;;;;;N;;;;;\n10494;OSMANYA LETTER HA;Lo;0;L;;;;;N;;;;;\n10495;OSMANYA LETTER YA;Lo;0;L;;;;;N;;;;;\n10496;OSMANYA LETTER A;Lo;0;L;;;;;N;;;;;\n10497;OSMANYA LETTER E;Lo;0;L;;;;;N;;;;;\n10498;OSMANYA LETTER I;Lo;0;L;;;;;N;;;;;\n10499;OSMANYA LETTER O;Lo;0;L;;;;;N;;;;;\n1049A;OSMANYA LETTER U;Lo;0;L;;;;;N;;;;;\n1049B;OSMANYA LETTER AA;Lo;0;L;;;;;N;;;;;\n1049C;OSMANYA LETTER EE;Lo;0;L;;;;;N;;;;;\n1049D;OSMANYA LETTER OO;Lo;0;L;;;;;N;;;;;\n104A0;OSMANYA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n104A1;OSMANYA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n104A2;OSMANYA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n104A3;OSMANYA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n104A4;OSMANYA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n104A5;OSMANYA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n104A6;OSMANYA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n104A7;OSMANYA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n104A8;OSMANYA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n104A9;OSMANYA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n104B0;OSAGE CAPITAL LETTER A;Lu;0;L;;;;;N;;;;104D8;\n104B1;OSAGE CAPITAL LETTER AI;Lu;0;L;;;;;N;;;;104D9;\n104B2;OSAGE CAPITAL LETTER AIN;Lu;0;L;;;;;N;;;;104DA;\n104B3;OSAGE CAPITAL LETTER AH;Lu;0;L;;;;;N;;;;104DB;\n104B4;OSAGE CAPITAL LETTER BRA;Lu;0;L;;;;;N;;;;104DC;\n104B5;OSAGE CAPITAL LETTER CHA;Lu;0;L;;;;;N;;;;104DD;\n104B6;OSAGE CAPITAL LETTER EHCHA;Lu;0;L;;;;;N;;;;104DE;\n104B7;OSAGE CAPITAL LETTER E;Lu;0;L;;;;;N;;;;104DF;\n104B8;OSAGE CAPITAL LETTER EIN;Lu;0;L;;;;;N;;;;104E0;\n104B9;OSAGE CAPITAL LETTER HA;Lu;0;L;;;;;N;;;;104E1;\n104BA;OSAGE CAPITAL LETTER HYA;Lu;0;L;;;;;N;;;;104E2;\n104BB;OSAGE CAPITAL LETTER I;Lu;0;L;;;;;N;;;;104E3;\n104BC;OSAGE CAPITAL LETTER KA;Lu;0;L;;;;;N;;;;104E4;\n104BD;OSAGE CAPITAL LETTER EHKA;Lu;0;L;;;;;N;;;;104E5;\n104BE;OSAGE CAPITAL LETTER KYA;Lu;0;L;;;;;N;;;;104E6;\n104BF;OSAGE CAPITAL LETTER LA;Lu;0;L;;;;;N;;;;104E7;\n104C0;OSAGE CAPITAL LETTER MA;Lu;0;L;;;;;N;;;;104E8;\n104C1;OSAGE CAPITAL LETTER NA;Lu;0;L;;;;;N;;;;104E9;\n104C2;OSAGE CAPITAL LETTER O;Lu;0;L;;;;;N;;;;104EA;\n104C3;OSAGE CAPITAL LETTER OIN;Lu;0;L;;;;;N;;;;104EB;\n104C4;OSAGE CAPITAL LETTER PA;Lu;0;L;;;;;N;;;;104EC;\n104C5;OSAGE CAPITAL LETTER EHPA;Lu;0;L;;;;;N;;;;104ED;\n104C6;OSAGE CAPITAL LETTER SA;Lu;0;L;;;;;N;;;;104EE;\n104C7;OSAGE CAPITAL LETTER SHA;Lu;0;L;;;;;N;;;;104EF;\n104C8;OSAGE CAPITAL LETTER TA;Lu;0;L;;;;;N;;;;104F0;\n104C9;OSAGE CAPITAL LETTER EHTA;Lu;0;L;;;;;N;;;;104F1;\n104CA;OSAGE CAPITAL LETTER TSA;Lu;0;L;;;;;N;;;;104F2;\n104CB;OSAGE CAPITAL LETTER EHTSA;Lu;0;L;;;;;N;;;;104F3;\n104CC;OSAGE CAPITAL LETTER TSHA;Lu;0;L;;;;;N;;;;104F4;\n104CD;OSAGE CAPITAL LETTER DHA;Lu;0;L;;;;;N;;;;104F5;\n104CE;OSAGE CAPITAL LETTER U;Lu;0;L;;;;;N;;;;104F6;\n104CF;OSAGE CAPITAL LETTER WA;Lu;0;L;;;;;N;;;;104F7;\n104D0;OSAGE CAPITAL LETTER KHA;Lu;0;L;;;;;N;;;;104F8;\n104D1;OSAGE CAPITAL LETTER GHA;Lu;0;L;;;;;N;;;;104F9;\n104D2;OSAGE CAPITAL LETTER ZA;Lu;0;L;;;;;N;;;;104FA;\n104D3;OSAGE CAPITAL LETTER ZHA;Lu;0;L;;;;;N;;;;104FB;\n104D8;OSAGE SMALL LETTER A;Ll;0;L;;;;;N;;;104B0;;104B0\n104D9;OSAGE SMALL LETTER AI;Ll;0;L;;;;;N;;;104B1;;104B1\n104DA;OSAGE SMALL LETTER AIN;Ll;0;L;;;;;N;;;104B2;;104B2\n104DB;OSAGE SMALL LETTER AH;Ll;0;L;;;;;N;;;104B3;;104B3\n104DC;OSAGE SMALL LETTER BRA;Ll;0;L;;;;;N;;;104B4;;104B4\n104DD;OSAGE SMALL LETTER CHA;Ll;0;L;;;;;N;;;104B5;;104B5\n104DE;OSAGE SMALL LETTER EHCHA;Ll;0;L;;;;;N;;;104B6;;104B6\n104DF;OSAGE SMALL LETTER E;Ll;0;L;;;;;N;;;104B7;;104B7\n104E0;OSAGE SMALL LETTER EIN;Ll;0;L;;;;;N;;;104B8;;104B8\n104E1;OSAGE SMALL LETTER HA;Ll;0;L;;;;;N;;;104B9;;104B9\n104E2;OSAGE SMALL LETTER HYA;Ll;0;L;;;;;N;;;104BA;;104BA\n104E3;OSAGE SMALL LETTER I;Ll;0;L;;;;;N;;;104BB;;104BB\n104E4;OSAGE SMALL LETTER KA;Ll;0;L;;;;;N;;;104BC;;104BC\n104E5;OSAGE SMALL LETTER EHKA;Ll;0;L;;;;;N;;;104BD;;104BD\n104E6;OSAGE SMALL LETTER KYA;Ll;0;L;;;;;N;;;104BE;;104BE\n104E7;OSAGE SMALL LETTER LA;Ll;0;L;;;;;N;;;104BF;;104BF\n104E8;OSAGE SMALL LETTER MA;Ll;0;L;;;;;N;;;104C0;;104C0\n104E9;OSAGE SMALL LETTER NA;Ll;0;L;;;;;N;;;104C1;;104C1\n104EA;OSAGE SMALL LETTER O;Ll;0;L;;;;;N;;;104C2;;104C2\n104EB;OSAGE SMALL LETTER OIN;Ll;0;L;;;;;N;;;104C3;;104C3\n104EC;OSAGE SMALL LETTER PA;Ll;0;L;;;;;N;;;104C4;;104C4\n104ED;OSAGE SMALL LETTER EHPA;Ll;0;L;;;;;N;;;104C5;;104C5\n104EE;OSAGE SMALL LETTER SA;Ll;0;L;;;;;N;;;104C6;;104C6\n104EF;OSAGE SMALL LETTER SHA;Ll;0;L;;;;;N;;;104C7;;104C7\n104F0;OSAGE SMALL LETTER TA;Ll;0;L;;;;;N;;;104C8;;104C8\n104F1;OSAGE SMALL LETTER EHTA;Ll;0;L;;;;;N;;;104C9;;104C9\n104F2;OSAGE SMALL LETTER TSA;Ll;0;L;;;;;N;;;104CA;;104CA\n104F3;OSAGE SMALL LETTER EHTSA;Ll;0;L;;;;;N;;;104CB;;104CB\n104F4;OSAGE SMALL LETTER TSHA;Ll;0;L;;;;;N;;;104CC;;104CC\n104F5;OSAGE SMALL LETTER DHA;Ll;0;L;;;;;N;;;104CD;;104CD\n104F6;OSAGE SMALL LETTER U;Ll;0;L;;;;;N;;;104CE;;104CE\n104F7;OSAGE SMALL LETTER WA;Ll;0;L;;;;;N;;;104CF;;104CF\n104F8;OSAGE SMALL LETTER KHA;Ll;0;L;;;;;N;;;104D0;;104D0\n104F9;OSAGE SMALL LETTER GHA;Ll;0;L;;;;;N;;;104D1;;104D1\n104FA;OSAGE SMALL LETTER ZA;Ll;0;L;;;;;N;;;104D2;;104D2\n104FB;OSAGE SMALL LETTER ZHA;Ll;0;L;;;;;N;;;104D3;;104D3\n10500;ELBASAN LETTER A;Lo;0;L;;;;;N;;;;;\n10501;ELBASAN LETTER BE;Lo;0;L;;;;;N;;;;;\n10502;ELBASAN LETTER CE;Lo;0;L;;;;;N;;;;;\n10503;ELBASAN LETTER CHE;Lo;0;L;;;;;N;;;;;\n10504;ELBASAN LETTER DE;Lo;0;L;;;;;N;;;;;\n10505;ELBASAN LETTER NDE;Lo;0;L;;;;;N;;;;;\n10506;ELBASAN LETTER DHE;Lo;0;L;;;;;N;;;;;\n10507;ELBASAN LETTER EI;Lo;0;L;;;;;N;;;;;\n10508;ELBASAN LETTER E;Lo;0;L;;;;;N;;;;;\n10509;ELBASAN LETTER FE;Lo;0;L;;;;;N;;;;;\n1050A;ELBASAN LETTER GE;Lo;0;L;;;;;N;;;;;\n1050B;ELBASAN LETTER GJE;Lo;0;L;;;;;N;;;;;\n1050C;ELBASAN LETTER HE;Lo;0;L;;;;;N;;;;;\n1050D;ELBASAN LETTER I;Lo;0;L;;;;;N;;;;;\n1050E;ELBASAN LETTER JE;Lo;0;L;;;;;N;;;;;\n1050F;ELBASAN LETTER KE;Lo;0;L;;;;;N;;;;;\n10510;ELBASAN LETTER LE;Lo;0;L;;;;;N;;;;;\n10511;ELBASAN LETTER LLE;Lo;0;L;;;;;N;;;;;\n10512;ELBASAN LETTER ME;Lo;0;L;;;;;N;;;;;\n10513;ELBASAN LETTER NE;Lo;0;L;;;;;N;;;;;\n10514;ELBASAN LETTER NA;Lo;0;L;;;;;N;;;;;\n10515;ELBASAN LETTER NJE;Lo;0;L;;;;;N;;;;;\n10516;ELBASAN LETTER O;Lo;0;L;;;;;N;;;;;\n10517;ELBASAN LETTER PE;Lo;0;L;;;;;N;;;;;\n10518;ELBASAN LETTER QE;Lo;0;L;;;;;N;;;;;\n10519;ELBASAN LETTER RE;Lo;0;L;;;;;N;;;;;\n1051A;ELBASAN LETTER RRE;Lo;0;L;;;;;N;;;;;\n1051B;ELBASAN LETTER SE;Lo;0;L;;;;;N;;;;;\n1051C;ELBASAN LETTER SHE;Lo;0;L;;;;;N;;;;;\n1051D;ELBASAN LETTER TE;Lo;0;L;;;;;N;;;;;\n1051E;ELBASAN LETTER THE;Lo;0;L;;;;;N;;;;;\n1051F;ELBASAN LETTER U;Lo;0;L;;;;;N;;;;;\n10520;ELBASAN LETTER VE;Lo;0;L;;;;;N;;;;;\n10521;ELBASAN LETTER XE;Lo;0;L;;;;;N;;;;;\n10522;ELBASAN LETTER Y;Lo;0;L;;;;;N;;;;;\n10523;ELBASAN LETTER ZE;Lo;0;L;;;;;N;;;;;\n10524;ELBASAN LETTER ZHE;Lo;0;L;;;;;N;;;;;\n10525;ELBASAN LETTER GHE;Lo;0;L;;;;;N;;;;;\n10526;ELBASAN LETTER GHAMMA;Lo;0;L;;;;;N;;;;;\n10527;ELBASAN LETTER KHE;Lo;0;L;;;;;N;;;;;\n10530;CAUCASIAN ALBANIAN LETTER ALT;Lo;0;L;;;;;N;;;;;\n10531;CAUCASIAN ALBANIAN LETTER BET;Lo;0;L;;;;;N;;;;;\n10532;CAUCASIAN ALBANIAN LETTER GIM;Lo;0;L;;;;;N;;;;;\n10533;CAUCASIAN ALBANIAN LETTER DAT;Lo;0;L;;;;;N;;;;;\n10534;CAUCASIAN ALBANIAN LETTER EB;Lo;0;L;;;;;N;;;;;\n10535;CAUCASIAN ALBANIAN LETTER ZARL;Lo;0;L;;;;;N;;;;;\n10536;CAUCASIAN ALBANIAN LETTER EYN;Lo;0;L;;;;;N;;;;;\n10537;CAUCASIAN ALBANIAN LETTER ZHIL;Lo;0;L;;;;;N;;;;;\n10538;CAUCASIAN ALBANIAN LETTER TAS;Lo;0;L;;;;;N;;;;;\n10539;CAUCASIAN ALBANIAN LETTER CHA;Lo;0;L;;;;;N;;;;;\n1053A;CAUCASIAN ALBANIAN LETTER YOWD;Lo;0;L;;;;;N;;;;;\n1053B;CAUCASIAN ALBANIAN LETTER ZHA;Lo;0;L;;;;;N;;;;;\n1053C;CAUCASIAN ALBANIAN LETTER IRB;Lo;0;L;;;;;N;;;;;\n1053D;CAUCASIAN ALBANIAN LETTER SHA;Lo;0;L;;;;;N;;;;;\n1053E;CAUCASIAN ALBANIAN LETTER LAN;Lo;0;L;;;;;N;;;;;\n1053F;CAUCASIAN ALBANIAN LETTER INYA;Lo;0;L;;;;;N;;;;;\n10540;CAUCASIAN ALBANIAN LETTER XEYN;Lo;0;L;;;;;N;;;;;\n10541;CAUCASIAN ALBANIAN LETTER DYAN;Lo;0;L;;;;;N;;;;;\n10542;CAUCASIAN ALBANIAN LETTER CAR;Lo;0;L;;;;;N;;;;;\n10543;CAUCASIAN ALBANIAN LETTER JHOX;Lo;0;L;;;;;N;;;;;\n10544;CAUCASIAN ALBANIAN LETTER KAR;Lo;0;L;;;;;N;;;;;\n10545;CAUCASIAN ALBANIAN LETTER LYIT;Lo;0;L;;;;;N;;;;;\n10546;CAUCASIAN ALBANIAN LETTER HEYT;Lo;0;L;;;;;N;;;;;\n10547;CAUCASIAN ALBANIAN LETTER QAY;Lo;0;L;;;;;N;;;;;\n10548;CAUCASIAN ALBANIAN LETTER AOR;Lo;0;L;;;;;N;;;;;\n10549;CAUCASIAN ALBANIAN LETTER CHOY;Lo;0;L;;;;;N;;;;;\n1054A;CAUCASIAN ALBANIAN LETTER CHI;Lo;0;L;;;;;N;;;;;\n1054B;CAUCASIAN ALBANIAN LETTER CYAY;Lo;0;L;;;;;N;;;;;\n1054C;CAUCASIAN ALBANIAN LETTER MAQ;Lo;0;L;;;;;N;;;;;\n1054D;CAUCASIAN ALBANIAN LETTER QAR;Lo;0;L;;;;;N;;;;;\n1054E;CAUCASIAN ALBANIAN LETTER NOWC;Lo;0;L;;;;;N;;;;;\n1054F;CAUCASIAN ALBANIAN LETTER DZYAY;Lo;0;L;;;;;N;;;;;\n10550;CAUCASIAN ALBANIAN LETTER SHAK;Lo;0;L;;;;;N;;;;;\n10551;CAUCASIAN ALBANIAN LETTER JAYN;Lo;0;L;;;;;N;;;;;\n10552;CAUCASIAN ALBANIAN LETTER ON;Lo;0;L;;;;;N;;;;;\n10553;CAUCASIAN ALBANIAN LETTER TYAY;Lo;0;L;;;;;N;;;;;\n10554;CAUCASIAN ALBANIAN LETTER FAM;Lo;0;L;;;;;N;;;;;\n10555;CAUCASIAN ALBANIAN LETTER DZAY;Lo;0;L;;;;;N;;;;;\n10556;CAUCASIAN ALBANIAN LETTER CHAT;Lo;0;L;;;;;N;;;;;\n10557;CAUCASIAN ALBANIAN LETTER PEN;Lo;0;L;;;;;N;;;;;\n10558;CAUCASIAN ALBANIAN LETTER GHEYS;Lo;0;L;;;;;N;;;;;\n10559;CAUCASIAN ALBANIAN LETTER RAT;Lo;0;L;;;;;N;;;;;\n1055A;CAUCASIAN ALBANIAN LETTER SEYK;Lo;0;L;;;;;N;;;;;\n1055B;CAUCASIAN ALBANIAN LETTER VEYZ;Lo;0;L;;;;;N;;;;;\n1055C;CAUCASIAN ALBANIAN LETTER TIWR;Lo;0;L;;;;;N;;;;;\n1055D;CAUCASIAN ALBANIAN LETTER SHOY;Lo;0;L;;;;;N;;;;;\n1055E;CAUCASIAN ALBANIAN LETTER IWN;Lo;0;L;;;;;N;;;;;\n1055F;CAUCASIAN ALBANIAN LETTER CYAW;Lo;0;L;;;;;N;;;;;\n10560;CAUCASIAN ALBANIAN LETTER CAYN;Lo;0;L;;;;;N;;;;;\n10561;CAUCASIAN ALBANIAN LETTER YAYD;Lo;0;L;;;;;N;;;;;\n10562;CAUCASIAN ALBANIAN LETTER PIWR;Lo;0;L;;;;;N;;;;;\n10563;CAUCASIAN ALBANIAN LETTER KIW;Lo;0;L;;;;;N;;;;;\n1056F;CAUCASIAN ALBANIAN CITATION MARK;Po;0;L;;;;;N;;;;;\n10600;LINEAR A SIGN AB001;Lo;0;L;;;;;N;;;;;\n10601;LINEAR A SIGN AB002;Lo;0;L;;;;;N;;;;;\n10602;LINEAR A SIGN AB003;Lo;0;L;;;;;N;;;;;\n10603;LINEAR A SIGN AB004;Lo;0;L;;;;;N;;;;;\n10604;LINEAR A SIGN AB005;Lo;0;L;;;;;N;;;;;\n10605;LINEAR A SIGN AB006;Lo;0;L;;;;;N;;;;;\n10606;LINEAR A SIGN AB007;Lo;0;L;;;;;N;;;;;\n10607;LINEAR A SIGN AB008;Lo;0;L;;;;;N;;;;;\n10608;LINEAR A SIGN AB009;Lo;0;L;;;;;N;;;;;\n10609;LINEAR A SIGN AB010;Lo;0;L;;;;;N;;;;;\n1060A;LINEAR A SIGN AB011;Lo;0;L;;;;;N;;;;;\n1060B;LINEAR A SIGN AB013;Lo;0;L;;;;;N;;;;;\n1060C;LINEAR A SIGN AB016;Lo;0;L;;;;;N;;;;;\n1060D;LINEAR A SIGN AB017;Lo;0;L;;;;;N;;;;;\n1060E;LINEAR A SIGN AB020;Lo;0;L;;;;;N;;;;;\n1060F;LINEAR A SIGN AB021;Lo;0;L;;;;;N;;;;;\n10610;LINEAR A SIGN AB021F;Lo;0;L;;;;;N;;;;;\n10611;LINEAR A SIGN AB021M;Lo;0;L;;;;;N;;;;;\n10612;LINEAR A SIGN AB022;Lo;0;L;;;;;N;;;;;\n10613;LINEAR A SIGN AB022F;Lo;0;L;;;;;N;;;;;\n10614;LINEAR A SIGN AB022M;Lo;0;L;;;;;N;;;;;\n10615;LINEAR A SIGN AB023;Lo;0;L;;;;;N;;;;;\n10616;LINEAR A SIGN AB023M;Lo;0;L;;;;;N;;;;;\n10617;LINEAR A SIGN AB024;Lo;0;L;;;;;N;;;;;\n10618;LINEAR A SIGN AB026;Lo;0;L;;;;;N;;;;;\n10619;LINEAR A SIGN AB027;Lo;0;L;;;;;N;;;;;\n1061A;LINEAR A SIGN AB028;Lo;0;L;;;;;N;;;;;\n1061B;LINEAR A SIGN A028B;Lo;0;L;;;;;N;;;;;\n1061C;LINEAR A SIGN AB029;Lo;0;L;;;;;N;;;;;\n1061D;LINEAR A SIGN AB030;Lo;0;L;;;;;N;;;;;\n1061E;LINEAR A SIGN AB031;Lo;0;L;;;;;N;;;;;\n1061F;LINEAR A SIGN AB034;Lo;0;L;;;;;N;;;;;\n10620;LINEAR A SIGN AB037;Lo;0;L;;;;;N;;;;;\n10621;LINEAR A SIGN AB038;Lo;0;L;;;;;N;;;;;\n10622;LINEAR A SIGN AB039;Lo;0;L;;;;;N;;;;;\n10623;LINEAR A SIGN AB040;Lo;0;L;;;;;N;;;;;\n10624;LINEAR A SIGN AB041;Lo;0;L;;;;;N;;;;;\n10625;LINEAR A SIGN AB044;Lo;0;L;;;;;N;;;;;\n10626;LINEAR A SIGN AB045;Lo;0;L;;;;;N;;;;;\n10627;LINEAR A SIGN AB046;Lo;0;L;;;;;N;;;;;\n10628;LINEAR A SIGN AB047;Lo;0;L;;;;;N;;;;;\n10629;LINEAR A SIGN AB048;Lo;0;L;;;;;N;;;;;\n1062A;LINEAR A SIGN AB049;Lo;0;L;;;;;N;;;;;\n1062B;LINEAR A SIGN AB050;Lo;0;L;;;;;N;;;;;\n1062C;LINEAR A SIGN AB051;Lo;0;L;;;;;N;;;;;\n1062D;LINEAR A SIGN AB053;Lo;0;L;;;;;N;;;;;\n1062E;LINEAR A SIGN AB054;Lo;0;L;;;;;N;;;;;\n1062F;LINEAR A SIGN AB055;Lo;0;L;;;;;N;;;;;\n10630;LINEAR A SIGN AB056;Lo;0;L;;;;;N;;;;;\n10631;LINEAR A SIGN AB057;Lo;0;L;;;;;N;;;;;\n10632;LINEAR A SIGN AB058;Lo;0;L;;;;;N;;;;;\n10633;LINEAR A SIGN AB059;Lo;0;L;;;;;N;;;;;\n10634;LINEAR A SIGN AB060;Lo;0;L;;;;;N;;;;;\n10635;LINEAR A SIGN AB061;Lo;0;L;;;;;N;;;;;\n10636;LINEAR A SIGN AB065;Lo;0;L;;;;;N;;;;;\n10637;LINEAR A SIGN AB066;Lo;0;L;;;;;N;;;;;\n10638;LINEAR A SIGN AB067;Lo;0;L;;;;;N;;;;;\n10639;LINEAR A SIGN AB069;Lo;0;L;;;;;N;;;;;\n1063A;LINEAR A SIGN AB070;Lo;0;L;;;;;N;;;;;\n1063B;LINEAR A SIGN AB073;Lo;0;L;;;;;N;;;;;\n1063C;LINEAR A SIGN AB074;Lo;0;L;;;;;N;;;;;\n1063D;LINEAR A SIGN AB076;Lo;0;L;;;;;N;;;;;\n1063E;LINEAR A SIGN AB077;Lo;0;L;;;;;N;;;;;\n1063F;LINEAR A SIGN AB078;Lo;0;L;;;;;N;;;;;\n10640;LINEAR A SIGN AB079;Lo;0;L;;;;;N;;;;;\n10641;LINEAR A SIGN AB080;Lo;0;L;;;;;N;;;;;\n10642;LINEAR A SIGN AB081;Lo;0;L;;;;;N;;;;;\n10643;LINEAR A SIGN AB082;Lo;0;L;;;;;N;;;;;\n10644;LINEAR A SIGN AB085;Lo;0;L;;;;;N;;;;;\n10645;LINEAR A SIGN AB086;Lo;0;L;;;;;N;;;;;\n10646;LINEAR A SIGN AB087;Lo;0;L;;;;;N;;;;;\n10647;LINEAR A SIGN A100-102;Lo;0;L;;;;;N;;;;;\n10648;LINEAR A SIGN AB118;Lo;0;L;;;;;N;;;;;\n10649;LINEAR A SIGN AB120;Lo;0;L;;;;;N;;;;;\n1064A;LINEAR A SIGN A120B;Lo;0;L;;;;;N;;;;;\n1064B;LINEAR A SIGN AB122;Lo;0;L;;;;;N;;;;;\n1064C;LINEAR A SIGN AB123;Lo;0;L;;;;;N;;;;;\n1064D;LINEAR A SIGN AB131A;Lo;0;L;;;;;N;;;;;\n1064E;LINEAR A SIGN AB131B;Lo;0;L;;;;;N;;;;;\n1064F;LINEAR A SIGN A131C;Lo;0;L;;;;;N;;;;;\n10650;LINEAR A SIGN AB164;Lo;0;L;;;;;N;;;;;\n10651;LINEAR A SIGN AB171;Lo;0;L;;;;;N;;;;;\n10652;LINEAR A SIGN AB180;Lo;0;L;;;;;N;;;;;\n10653;LINEAR A SIGN AB188;Lo;0;L;;;;;N;;;;;\n10654;LINEAR A SIGN AB191;Lo;0;L;;;;;N;;;;;\n10655;LINEAR A SIGN A301;Lo;0;L;;;;;N;;;;;\n10656;LINEAR A SIGN A302;Lo;0;L;;;;;N;;;;;\n10657;LINEAR A SIGN A303;Lo;0;L;;;;;N;;;;;\n10658;LINEAR A SIGN A304;Lo;0;L;;;;;N;;;;;\n10659;LINEAR A SIGN A305;Lo;0;L;;;;;N;;;;;\n1065A;LINEAR A SIGN A306;Lo;0;L;;;;;N;;;;;\n1065B;LINEAR A SIGN A307;Lo;0;L;;;;;N;;;;;\n1065C;LINEAR A SIGN A308;Lo;0;L;;;;;N;;;;;\n1065D;LINEAR A SIGN A309A;Lo;0;L;;;;;N;;;;;\n1065E;LINEAR A SIGN A309B;Lo;0;L;;;;;N;;;;;\n1065F;LINEAR A SIGN A309C;Lo;0;L;;;;;N;;;;;\n10660;LINEAR A SIGN A310;Lo;0;L;;;;;N;;;;;\n10661;LINEAR A SIGN A311;Lo;0;L;;;;;N;;;;;\n10662;LINEAR A SIGN A312;Lo;0;L;;;;;N;;;;;\n10663;LINEAR A SIGN A313A;Lo;0;L;;;;;N;;;;;\n10664;LINEAR A SIGN A313B;Lo;0;L;;;;;N;;;;;\n10665;LINEAR A SIGN A313C;Lo;0;L;;;;;N;;;;;\n10666;LINEAR A SIGN A314;Lo;0;L;;;;;N;;;;;\n10667;LINEAR A SIGN A315;Lo;0;L;;;;;N;;;;;\n10668;LINEAR A SIGN A316;Lo;0;L;;;;;N;;;;;\n10669;LINEAR A SIGN A317;Lo;0;L;;;;;N;;;;;\n1066A;LINEAR A SIGN A318;Lo;0;L;;;;;N;;;;;\n1066B;LINEAR A SIGN A319;Lo;0;L;;;;;N;;;;;\n1066C;LINEAR A SIGN A320;Lo;0;L;;;;;N;;;;;\n1066D;LINEAR A SIGN A321;Lo;0;L;;;;;N;;;;;\n1066E;LINEAR A SIGN A322;Lo;0;L;;;;;N;;;;;\n1066F;LINEAR A SIGN A323;Lo;0;L;;;;;N;;;;;\n10670;LINEAR A SIGN A324;Lo;0;L;;;;;N;;;;;\n10671;LINEAR A SIGN A325;Lo;0;L;;;;;N;;;;;\n10672;LINEAR A SIGN A326;Lo;0;L;;;;;N;;;;;\n10673;LINEAR A SIGN A327;Lo;0;L;;;;;N;;;;;\n10674;LINEAR A SIGN A328;Lo;0;L;;;;;N;;;;;\n10675;LINEAR A SIGN A329;Lo;0;L;;;;;N;;;;;\n10676;LINEAR A SIGN A330;Lo;0;L;;;;;N;;;;;\n10677;LINEAR A SIGN A331;Lo;0;L;;;;;N;;;;;\n10678;LINEAR A SIGN A332;Lo;0;L;;;;;N;;;;;\n10679;LINEAR A SIGN A333;Lo;0;L;;;;;N;;;;;\n1067A;LINEAR A SIGN A334;Lo;0;L;;;;;N;;;;;\n1067B;LINEAR A SIGN A335;Lo;0;L;;;;;N;;;;;\n1067C;LINEAR A SIGN A336;Lo;0;L;;;;;N;;;;;\n1067D;LINEAR A SIGN A337;Lo;0;L;;;;;N;;;;;\n1067E;LINEAR A SIGN A338;Lo;0;L;;;;;N;;;;;\n1067F;LINEAR A SIGN A339;Lo;0;L;;;;;N;;;;;\n10680;LINEAR A SIGN A340;Lo;0;L;;;;;N;;;;;\n10681;LINEAR A SIGN A341;Lo;0;L;;;;;N;;;;;\n10682;LINEAR A SIGN A342;Lo;0;L;;;;;N;;;;;\n10683;LINEAR A SIGN A343;Lo;0;L;;;;;N;;;;;\n10684;LINEAR A SIGN A344;Lo;0;L;;;;;N;;;;;\n10685;LINEAR A SIGN A345;Lo;0;L;;;;;N;;;;;\n10686;LINEAR A SIGN A346;Lo;0;L;;;;;N;;;;;\n10687;LINEAR A SIGN A347;Lo;0;L;;;;;N;;;;;\n10688;LINEAR A SIGN A348;Lo;0;L;;;;;N;;;;;\n10689;LINEAR A SIGN A349;Lo;0;L;;;;;N;;;;;\n1068A;LINEAR A SIGN A350;Lo;0;L;;;;;N;;;;;\n1068B;LINEAR A SIGN A351;Lo;0;L;;;;;N;;;;;\n1068C;LINEAR A SIGN A352;Lo;0;L;;;;;N;;;;;\n1068D;LINEAR A SIGN A353;Lo;0;L;;;;;N;;;;;\n1068E;LINEAR A SIGN A354;Lo;0;L;;;;;N;;;;;\n1068F;LINEAR A SIGN A355;Lo;0;L;;;;;N;;;;;\n10690;LINEAR A SIGN A356;Lo;0;L;;;;;N;;;;;\n10691;LINEAR A SIGN A357;Lo;0;L;;;;;N;;;;;\n10692;LINEAR A SIGN A358;Lo;0;L;;;;;N;;;;;\n10693;LINEAR A SIGN A359;Lo;0;L;;;;;N;;;;;\n10694;LINEAR A SIGN A360;Lo;0;L;;;;;N;;;;;\n10695;LINEAR A SIGN A361;Lo;0;L;;;;;N;;;;;\n10696;LINEAR A SIGN A362;Lo;0;L;;;;;N;;;;;\n10697;LINEAR A SIGN A363;Lo;0;L;;;;;N;;;;;\n10698;LINEAR A SIGN A364;Lo;0;L;;;;;N;;;;;\n10699;LINEAR A SIGN A365;Lo;0;L;;;;;N;;;;;\n1069A;LINEAR A SIGN A366;Lo;0;L;;;;;N;;;;;\n1069B;LINEAR A SIGN A367;Lo;0;L;;;;;N;;;;;\n1069C;LINEAR A SIGN A368;Lo;0;L;;;;;N;;;;;\n1069D;LINEAR A SIGN A369;Lo;0;L;;;;;N;;;;;\n1069E;LINEAR A SIGN A370;Lo;0;L;;;;;N;;;;;\n1069F;LINEAR A SIGN A371;Lo;0;L;;;;;N;;;;;\n106A0;LINEAR A SIGN A400-VAS;Lo;0;L;;;;;N;;;;;\n106A1;LINEAR A SIGN A401-VAS;Lo;0;L;;;;;N;;;;;\n106A2;LINEAR A SIGN A402-VAS;Lo;0;L;;;;;N;;;;;\n106A3;LINEAR A SIGN A403-VAS;Lo;0;L;;;;;N;;;;;\n106A4;LINEAR A SIGN A404-VAS;Lo;0;L;;;;;N;;;;;\n106A5;LINEAR A SIGN A405-VAS;Lo;0;L;;;;;N;;;;;\n106A6;LINEAR A SIGN A406-VAS;Lo;0;L;;;;;N;;;;;\n106A7;LINEAR A SIGN A407-VAS;Lo;0;L;;;;;N;;;;;\n106A8;LINEAR A SIGN A408-VAS;Lo;0;L;;;;;N;;;;;\n106A9;LINEAR A SIGN A409-VAS;Lo;0;L;;;;;N;;;;;\n106AA;LINEAR A SIGN A410-VAS;Lo;0;L;;;;;N;;;;;\n106AB;LINEAR A SIGN A411-VAS;Lo;0;L;;;;;N;;;;;\n106AC;LINEAR A SIGN A412-VAS;Lo;0;L;;;;;N;;;;;\n106AD;LINEAR A SIGN A413-VAS;Lo;0;L;;;;;N;;;;;\n106AE;LINEAR A SIGN A414-VAS;Lo;0;L;;;;;N;;;;;\n106AF;LINEAR A SIGN A415-VAS;Lo;0;L;;;;;N;;;;;\n106B0;LINEAR A SIGN A416-VAS;Lo;0;L;;;;;N;;;;;\n106B1;LINEAR A SIGN A417-VAS;Lo;0;L;;;;;N;;;;;\n106B2;LINEAR A SIGN A418-VAS;Lo;0;L;;;;;N;;;;;\n106B3;LINEAR A SIGN A501;Lo;0;L;;;;;N;;;;;\n106B4;LINEAR A SIGN A502;Lo;0;L;;;;;N;;;;;\n106B5;LINEAR A SIGN A503;Lo;0;L;;;;;N;;;;;\n106B6;LINEAR A SIGN A504;Lo;0;L;;;;;N;;;;;\n106B7;LINEAR A SIGN A505;Lo;0;L;;;;;N;;;;;\n106B8;LINEAR A SIGN A506;Lo;0;L;;;;;N;;;;;\n106B9;LINEAR A SIGN A508;Lo;0;L;;;;;N;;;;;\n106BA;LINEAR A SIGN A509;Lo;0;L;;;;;N;;;;;\n106BB;LINEAR A SIGN A510;Lo;0;L;;;;;N;;;;;\n106BC;LINEAR A SIGN A511;Lo;0;L;;;;;N;;;;;\n106BD;LINEAR A SIGN A512;Lo;0;L;;;;;N;;;;;\n106BE;LINEAR A SIGN A513;Lo;0;L;;;;;N;;;;;\n106BF;LINEAR A SIGN A515;Lo;0;L;;;;;N;;;;;\n106C0;LINEAR A SIGN A516;Lo;0;L;;;;;N;;;;;\n106C1;LINEAR A SIGN A520;Lo;0;L;;;;;N;;;;;\n106C2;LINEAR A SIGN A521;Lo;0;L;;;;;N;;;;;\n106C3;LINEAR A SIGN A523;Lo;0;L;;;;;N;;;;;\n106C4;LINEAR A SIGN A524;Lo;0;L;;;;;N;;;;;\n106C5;LINEAR A SIGN A525;Lo;0;L;;;;;N;;;;;\n106C6;LINEAR A SIGN A526;Lo;0;L;;;;;N;;;;;\n106C7;LINEAR A SIGN A527;Lo;0;L;;;;;N;;;;;\n106C8;LINEAR A SIGN A528;Lo;0;L;;;;;N;;;;;\n106C9;LINEAR A SIGN A529;Lo;0;L;;;;;N;;;;;\n106CA;LINEAR A SIGN A530;Lo;0;L;;;;;N;;;;;\n106CB;LINEAR A SIGN A531;Lo;0;L;;;;;N;;;;;\n106CC;LINEAR A SIGN A532;Lo;0;L;;;;;N;;;;;\n106CD;LINEAR A SIGN A534;Lo;0;L;;;;;N;;;;;\n106CE;LINEAR A SIGN A535;Lo;0;L;;;;;N;;;;;\n106CF;LINEAR A SIGN A536;Lo;0;L;;;;;N;;;;;\n106D0;LINEAR A SIGN A537;Lo;0;L;;;;;N;;;;;\n106D1;LINEAR A SIGN A538;Lo;0;L;;;;;N;;;;;\n106D2;LINEAR A SIGN A539;Lo;0;L;;;;;N;;;;;\n106D3;LINEAR A SIGN A540;Lo;0;L;;;;;N;;;;;\n106D4;LINEAR A SIGN A541;Lo;0;L;;;;;N;;;;;\n106D5;LINEAR A SIGN A542;Lo;0;L;;;;;N;;;;;\n106D6;LINEAR A SIGN A545;Lo;0;L;;;;;N;;;;;\n106D7;LINEAR A SIGN A547;Lo;0;L;;;;;N;;;;;\n106D8;LINEAR A SIGN A548;Lo;0;L;;;;;N;;;;;\n106D9;LINEAR A SIGN A549;Lo;0;L;;;;;N;;;;;\n106DA;LINEAR A SIGN A550;Lo;0;L;;;;;N;;;;;\n106DB;LINEAR A SIGN A551;Lo;0;L;;;;;N;;;;;\n106DC;LINEAR A SIGN A552;Lo;0;L;;;;;N;;;;;\n106DD;LINEAR A SIGN A553;Lo;0;L;;;;;N;;;;;\n106DE;LINEAR A SIGN A554;Lo;0;L;;;;;N;;;;;\n106DF;LINEAR A SIGN A555;Lo;0;L;;;;;N;;;;;\n106E0;LINEAR A SIGN A556;Lo;0;L;;;;;N;;;;;\n106E1;LINEAR A SIGN A557;Lo;0;L;;;;;N;;;;;\n106E2;LINEAR A SIGN A559;Lo;0;L;;;;;N;;;;;\n106E3;LINEAR A SIGN A563;Lo;0;L;;;;;N;;;;;\n106E4;LINEAR A SIGN A564;Lo;0;L;;;;;N;;;;;\n106E5;LINEAR A SIGN A565;Lo;0;L;;;;;N;;;;;\n106E6;LINEAR A SIGN A566;Lo;0;L;;;;;N;;;;;\n106E7;LINEAR A SIGN A568;Lo;0;L;;;;;N;;;;;\n106E8;LINEAR A SIGN A569;Lo;0;L;;;;;N;;;;;\n106E9;LINEAR A SIGN A570;Lo;0;L;;;;;N;;;;;\n106EA;LINEAR A SIGN A571;Lo;0;L;;;;;N;;;;;\n106EB;LINEAR A SIGN A572;Lo;0;L;;;;;N;;;;;\n106EC;LINEAR A SIGN A573;Lo;0;L;;;;;N;;;;;\n106ED;LINEAR A SIGN A574;Lo;0;L;;;;;N;;;;;\n106EE;LINEAR A SIGN A575;Lo;0;L;;;;;N;;;;;\n106EF;LINEAR A SIGN A576;Lo;0;L;;;;;N;;;;;\n106F0;LINEAR A SIGN A577;Lo;0;L;;;;;N;;;;;\n106F1;LINEAR A SIGN A578;Lo;0;L;;;;;N;;;;;\n106F2;LINEAR A SIGN A579;Lo;0;L;;;;;N;;;;;\n106F3;LINEAR A SIGN A580;Lo;0;L;;;;;N;;;;;\n106F4;LINEAR A SIGN A581;Lo;0;L;;;;;N;;;;;\n106F5;LINEAR A SIGN A582;Lo;0;L;;;;;N;;;;;\n106F6;LINEAR A SIGN A583;Lo;0;L;;;;;N;;;;;\n106F7;LINEAR A SIGN A584;Lo;0;L;;;;;N;;;;;\n106F8;LINEAR A SIGN A585;Lo;0;L;;;;;N;;;;;\n106F9;LINEAR A SIGN A586;Lo;0;L;;;;;N;;;;;\n106FA;LINEAR A SIGN A587;Lo;0;L;;;;;N;;;;;\n106FB;LINEAR A SIGN A588;Lo;0;L;;;;;N;;;;;\n106FC;LINEAR A SIGN A589;Lo;0;L;;;;;N;;;;;\n106FD;LINEAR A SIGN A591;Lo;0;L;;;;;N;;;;;\n106FE;LINEAR A SIGN A592;Lo;0;L;;;;;N;;;;;\n106FF;LINEAR A SIGN A594;Lo;0;L;;;;;N;;;;;\n10700;LINEAR A SIGN A595;Lo;0;L;;;;;N;;;;;\n10701;LINEAR A SIGN A596;Lo;0;L;;;;;N;;;;;\n10702;LINEAR A SIGN A598;Lo;0;L;;;;;N;;;;;\n10703;LINEAR A SIGN A600;Lo;0;L;;;;;N;;;;;\n10704;LINEAR A SIGN A601;Lo;0;L;;;;;N;;;;;\n10705;LINEAR A SIGN A602;Lo;0;L;;;;;N;;;;;\n10706;LINEAR A SIGN A603;Lo;0;L;;;;;N;;;;;\n10707;LINEAR A SIGN A604;Lo;0;L;;;;;N;;;;;\n10708;LINEAR A SIGN A606;Lo;0;L;;;;;N;;;;;\n10709;LINEAR A SIGN A608;Lo;0;L;;;;;N;;;;;\n1070A;LINEAR A SIGN A609;Lo;0;L;;;;;N;;;;;\n1070B;LINEAR A SIGN A610;Lo;0;L;;;;;N;;;;;\n1070C;LINEAR A SIGN A611;Lo;0;L;;;;;N;;;;;\n1070D;LINEAR A SIGN A612;Lo;0;L;;;;;N;;;;;\n1070E;LINEAR A SIGN A613;Lo;0;L;;;;;N;;;;;\n1070F;LINEAR A SIGN A614;Lo;0;L;;;;;N;;;;;\n10710;LINEAR A SIGN A615;Lo;0;L;;;;;N;;;;;\n10711;LINEAR A SIGN A616;Lo;0;L;;;;;N;;;;;\n10712;LINEAR A SIGN A617;Lo;0;L;;;;;N;;;;;\n10713;LINEAR A SIGN A618;Lo;0;L;;;;;N;;;;;\n10714;LINEAR A SIGN A619;Lo;0;L;;;;;N;;;;;\n10715;LINEAR A SIGN A620;Lo;0;L;;;;;N;;;;;\n10716;LINEAR A SIGN A621;Lo;0;L;;;;;N;;;;;\n10717;LINEAR A SIGN A622;Lo;0;L;;;;;N;;;;;\n10718;LINEAR A SIGN A623;Lo;0;L;;;;;N;;;;;\n10719;LINEAR A SIGN A624;Lo;0;L;;;;;N;;;;;\n1071A;LINEAR A SIGN A626;Lo;0;L;;;;;N;;;;;\n1071B;LINEAR A SIGN A627;Lo;0;L;;;;;N;;;;;\n1071C;LINEAR A SIGN A628;Lo;0;L;;;;;N;;;;;\n1071D;LINEAR A SIGN A629;Lo;0;L;;;;;N;;;;;\n1071E;LINEAR A SIGN A634;Lo;0;L;;;;;N;;;;;\n1071F;LINEAR A SIGN A637;Lo;0;L;;;;;N;;;;;\n10720;LINEAR A SIGN A638;Lo;0;L;;;;;N;;;;;\n10721;LINEAR A SIGN A640;Lo;0;L;;;;;N;;;;;\n10722;LINEAR A SIGN A642;Lo;0;L;;;;;N;;;;;\n10723;LINEAR A SIGN A643;Lo;0;L;;;;;N;;;;;\n10724;LINEAR A SIGN A644;Lo;0;L;;;;;N;;;;;\n10725;LINEAR A SIGN A645;Lo;0;L;;;;;N;;;;;\n10726;LINEAR A SIGN A646;Lo;0;L;;;;;N;;;;;\n10727;LINEAR A SIGN A648;Lo;0;L;;;;;N;;;;;\n10728;LINEAR A SIGN A649;Lo;0;L;;;;;N;;;;;\n10729;LINEAR A SIGN A651;Lo;0;L;;;;;N;;;;;\n1072A;LINEAR A SIGN A652;Lo;0;L;;;;;N;;;;;\n1072B;LINEAR A SIGN A653;Lo;0;L;;;;;N;;;;;\n1072C;LINEAR A SIGN A654;Lo;0;L;;;;;N;;;;;\n1072D;LINEAR A SIGN A655;Lo;0;L;;;;;N;;;;;\n1072E;LINEAR A SIGN A656;Lo;0;L;;;;;N;;;;;\n1072F;LINEAR A SIGN A657;Lo;0;L;;;;;N;;;;;\n10730;LINEAR A SIGN A658;Lo;0;L;;;;;N;;;;;\n10731;LINEAR A SIGN A659;Lo;0;L;;;;;N;;;;;\n10732;LINEAR A SIGN A660;Lo;0;L;;;;;N;;;;;\n10733;LINEAR A SIGN A661;Lo;0;L;;;;;N;;;;;\n10734;LINEAR A SIGN A662;Lo;0;L;;;;;N;;;;;\n10735;LINEAR A SIGN A663;Lo;0;L;;;;;N;;;;;\n10736;LINEAR A SIGN A664;Lo;0;L;;;;;N;;;;;\n10740;LINEAR A SIGN A701 A;Lo;0;L;;;;;N;;;;;\n10741;LINEAR A SIGN A702 B;Lo;0;L;;;;;N;;;;;\n10742;LINEAR A SIGN A703 D;Lo;0;L;;;;;N;;;;;\n10743;LINEAR A SIGN A704 E;Lo;0;L;;;;;N;;;;;\n10744;LINEAR A SIGN A705 F;Lo;0;L;;;;;N;;;;;\n10745;LINEAR A SIGN A706 H;Lo;0;L;;;;;N;;;;;\n10746;LINEAR A SIGN A707 J;Lo;0;L;;;;;N;;;;;\n10747;LINEAR A SIGN A708 K;Lo;0;L;;;;;N;;;;;\n10748;LINEAR A SIGN A709 L;Lo;0;L;;;;;N;;;;;\n10749;LINEAR A SIGN A709-2 L2;Lo;0;L;;;;;N;;;;;\n1074A;LINEAR A SIGN A709-3 L3;Lo;0;L;;;;;N;;;;;\n1074B;LINEAR A SIGN A709-4 L4;Lo;0;L;;;;;N;;;;;\n1074C;LINEAR A SIGN A709-6 L6;Lo;0;L;;;;;N;;;;;\n1074D;LINEAR A SIGN A710 W;Lo;0;L;;;;;N;;;;;\n1074E;LINEAR A SIGN A711 X;Lo;0;L;;;;;N;;;;;\n1074F;LINEAR A SIGN A712 Y;Lo;0;L;;;;;N;;;;;\n10750;LINEAR A SIGN A713 OMEGA;Lo;0;L;;;;;N;;;;;\n10751;LINEAR A SIGN A714 ABB;Lo;0;L;;;;;N;;;;;\n10752;LINEAR A SIGN A715 BB;Lo;0;L;;;;;N;;;;;\n10753;LINEAR A SIGN A717 DD;Lo;0;L;;;;;N;;;;;\n10754;LINEAR A SIGN A726 EYYY;Lo;0;L;;;;;N;;;;;\n10755;LINEAR A SIGN A732 JE;Lo;0;L;;;;;N;;;;;\n10760;LINEAR A SIGN A800;Lo;0;L;;;;;N;;;;;\n10761;LINEAR A SIGN A801;Lo;0;L;;;;;N;;;;;\n10762;LINEAR A SIGN A802;Lo;0;L;;;;;N;;;;;\n10763;LINEAR A SIGN A803;Lo;0;L;;;;;N;;;;;\n10764;LINEAR A SIGN A804;Lo;0;L;;;;;N;;;;;\n10765;LINEAR A SIGN A805;Lo;0;L;;;;;N;;;;;\n10766;LINEAR A SIGN A806;Lo;0;L;;;;;N;;;;;\n10767;LINEAR A SIGN A807;Lo;0;L;;;;;N;;;;;\n10800;CYPRIOT SYLLABLE A;Lo;0;R;;;;;N;;;;;\n10801;CYPRIOT SYLLABLE E;Lo;0;R;;;;;N;;;;;\n10802;CYPRIOT SYLLABLE I;Lo;0;R;;;;;N;;;;;\n10803;CYPRIOT SYLLABLE O;Lo;0;R;;;;;N;;;;;\n10804;CYPRIOT SYLLABLE U;Lo;0;R;;;;;N;;;;;\n10805;CYPRIOT SYLLABLE JA;Lo;0;R;;;;;N;;;;;\n10808;CYPRIOT SYLLABLE JO;Lo;0;R;;;;;N;;;;;\n1080A;CYPRIOT SYLLABLE KA;Lo;0;R;;;;;N;;;;;\n1080B;CYPRIOT SYLLABLE KE;Lo;0;R;;;;;N;;;;;\n1080C;CYPRIOT SYLLABLE KI;Lo;0;R;;;;;N;;;;;\n1080D;CYPRIOT SYLLABLE KO;Lo;0;R;;;;;N;;;;;\n1080E;CYPRIOT SYLLABLE KU;Lo;0;R;;;;;N;;;;;\n1080F;CYPRIOT SYLLABLE LA;Lo;0;R;;;;;N;;;;;\n10810;CYPRIOT SYLLABLE LE;Lo;0;R;;;;;N;;;;;\n10811;CYPRIOT SYLLABLE LI;Lo;0;R;;;;;N;;;;;\n10812;CYPRIOT SYLLABLE LO;Lo;0;R;;;;;N;;;;;\n10813;CYPRIOT SYLLABLE LU;Lo;0;R;;;;;N;;;;;\n10814;CYPRIOT SYLLABLE MA;Lo;0;R;;;;;N;;;;;\n10815;CYPRIOT SYLLABLE ME;Lo;0;R;;;;;N;;;;;\n10816;CYPRIOT SYLLABLE MI;Lo;0;R;;;;;N;;;;;\n10817;CYPRIOT SYLLABLE MO;Lo;0;R;;;;;N;;;;;\n10818;CYPRIOT SYLLABLE MU;Lo;0;R;;;;;N;;;;;\n10819;CYPRIOT SYLLABLE NA;Lo;0;R;;;;;N;;;;;\n1081A;CYPRIOT SYLLABLE NE;Lo;0;R;;;;;N;;;;;\n1081B;CYPRIOT SYLLABLE NI;Lo;0;R;;;;;N;;;;;\n1081C;CYPRIOT SYLLABLE NO;Lo;0;R;;;;;N;;;;;\n1081D;CYPRIOT SYLLABLE NU;Lo;0;R;;;;;N;;;;;\n1081E;CYPRIOT SYLLABLE PA;Lo;0;R;;;;;N;;;;;\n1081F;CYPRIOT SYLLABLE PE;Lo;0;R;;;;;N;;;;;\n10820;CYPRIOT SYLLABLE PI;Lo;0;R;;;;;N;;;;;\n10821;CYPRIOT SYLLABLE PO;Lo;0;R;;;;;N;;;;;\n10822;CYPRIOT SYLLABLE PU;Lo;0;R;;;;;N;;;;;\n10823;CYPRIOT SYLLABLE RA;Lo;0;R;;;;;N;;;;;\n10824;CYPRIOT SYLLABLE RE;Lo;0;R;;;;;N;;;;;\n10825;CYPRIOT SYLLABLE RI;Lo;0;R;;;;;N;;;;;\n10826;CYPRIOT SYLLABLE RO;Lo;0;R;;;;;N;;;;;\n10827;CYPRIOT SYLLABLE RU;Lo;0;R;;;;;N;;;;;\n10828;CYPRIOT SYLLABLE SA;Lo;0;R;;;;;N;;;;;\n10829;CYPRIOT SYLLABLE SE;Lo;0;R;;;;;N;;;;;\n1082A;CYPRIOT SYLLABLE SI;Lo;0;R;;;;;N;;;;;\n1082B;CYPRIOT SYLLABLE SO;Lo;0;R;;;;;N;;;;;\n1082C;CYPRIOT SYLLABLE SU;Lo;0;R;;;;;N;;;;;\n1082D;CYPRIOT SYLLABLE TA;Lo;0;R;;;;;N;;;;;\n1082E;CYPRIOT SYLLABLE TE;Lo;0;R;;;;;N;;;;;\n1082F;CYPRIOT SYLLABLE TI;Lo;0;R;;;;;N;;;;;\n10830;CYPRIOT SYLLABLE TO;Lo;0;R;;;;;N;;;;;\n10831;CYPRIOT SYLLABLE TU;Lo;0;R;;;;;N;;;;;\n10832;CYPRIOT SYLLABLE WA;Lo;0;R;;;;;N;;;;;\n10833;CYPRIOT SYLLABLE WE;Lo;0;R;;;;;N;;;;;\n10834;CYPRIOT SYLLABLE WI;Lo;0;R;;;;;N;;;;;\n10835;CYPRIOT SYLLABLE WO;Lo;0;R;;;;;N;;;;;\n10837;CYPRIOT SYLLABLE XA;Lo;0;R;;;;;N;;;;;\n10838;CYPRIOT SYLLABLE XE;Lo;0;R;;;;;N;;;;;\n1083C;CYPRIOT SYLLABLE ZA;Lo;0;R;;;;;N;;;;;\n1083F;CYPRIOT SYLLABLE ZO;Lo;0;R;;;;;N;;;;;\n10840;IMPERIAL ARAMAIC LETTER ALEPH;Lo;0;R;;;;;N;;;;;\n10841;IMPERIAL ARAMAIC LETTER BETH;Lo;0;R;;;;;N;;;;;\n10842;IMPERIAL ARAMAIC LETTER GIMEL;Lo;0;R;;;;;N;;;;;\n10843;IMPERIAL ARAMAIC LETTER DALETH;Lo;0;R;;;;;N;;;;;\n10844;IMPERIAL ARAMAIC LETTER HE;Lo;0;R;;;;;N;;;;;\n10845;IMPERIAL ARAMAIC LETTER WAW;Lo;0;R;;;;;N;;;;;\n10846;IMPERIAL ARAMAIC LETTER ZAYIN;Lo;0;R;;;;;N;;;;;\n10847;IMPERIAL ARAMAIC LETTER HETH;Lo;0;R;;;;;N;;;;;\n10848;IMPERIAL ARAMAIC LETTER TETH;Lo;0;R;;;;;N;;;;;\n10849;IMPERIAL ARAMAIC LETTER YODH;Lo;0;R;;;;;N;;;;;\n1084A;IMPERIAL ARAMAIC LETTER KAPH;Lo;0;R;;;;;N;;;;;\n1084B;IMPERIAL ARAMAIC LETTER LAMEDH;Lo;0;R;;;;;N;;;;;\n1084C;IMPERIAL ARAMAIC LETTER MEM;Lo;0;R;;;;;N;;;;;\n1084D;IMPERIAL ARAMAIC LETTER NUN;Lo;0;R;;;;;N;;;;;\n1084E;IMPERIAL ARAMAIC LETTER SAMEKH;Lo;0;R;;;;;N;;;;;\n1084F;IMPERIAL ARAMAIC LETTER AYIN;Lo;0;R;;;;;N;;;;;\n10850;IMPERIAL ARAMAIC LETTER PE;Lo;0;R;;;;;N;;;;;\n10851;IMPERIAL ARAMAIC LETTER SADHE;Lo;0;R;;;;;N;;;;;\n10852;IMPERIAL ARAMAIC LETTER QOPH;Lo;0;R;;;;;N;;;;;\n10853;IMPERIAL ARAMAIC LETTER RESH;Lo;0;R;;;;;N;;;;;\n10854;IMPERIAL ARAMAIC LETTER SHIN;Lo;0;R;;;;;N;;;;;\n10855;IMPERIAL ARAMAIC LETTER TAW;Lo;0;R;;;;;N;;;;;\n10857;IMPERIAL ARAMAIC SECTION SIGN;Po;0;R;;;;;N;;;;;\n10858;IMPERIAL ARAMAIC NUMBER ONE;No;0;R;;;;1;N;;;;;\n10859;IMPERIAL ARAMAIC NUMBER TWO;No;0;R;;;;2;N;;;;;\n1085A;IMPERIAL ARAMAIC NUMBER THREE;No;0;R;;;;3;N;;;;;\n1085B;IMPERIAL ARAMAIC NUMBER TEN;No;0;R;;;;10;N;;;;;\n1085C;IMPERIAL ARAMAIC NUMBER TWENTY;No;0;R;;;;20;N;;;;;\n1085D;IMPERIAL ARAMAIC NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;\n1085E;IMPERIAL ARAMAIC NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;\n1085F;IMPERIAL ARAMAIC NUMBER TEN THOUSAND;No;0;R;;;;10000;N;;;;;\n10860;PALMYRENE LETTER ALEPH;Lo;0;R;;;;;N;;;;;\n10861;PALMYRENE LETTER BETH;Lo;0;R;;;;;N;;;;;\n10862;PALMYRENE LETTER GIMEL;Lo;0;R;;;;;N;;;;;\n10863;PALMYRENE LETTER DALETH;Lo;0;R;;;;;N;;;;;\n10864;PALMYRENE LETTER HE;Lo;0;R;;;;;N;;;;;\n10865;PALMYRENE LETTER WAW;Lo;0;R;;;;;N;;;;;\n10866;PALMYRENE LETTER ZAYIN;Lo;0;R;;;;;N;;;;;\n10867;PALMYRENE LETTER HETH;Lo;0;R;;;;;N;;;;;\n10868;PALMYRENE LETTER TETH;Lo;0;R;;;;;N;;;;;\n10869;PALMYRENE LETTER YODH;Lo;0;R;;;;;N;;;;;\n1086A;PALMYRENE LETTER KAPH;Lo;0;R;;;;;N;;;;;\n1086B;PALMYRENE LETTER LAMEDH;Lo;0;R;;;;;N;;;;;\n1086C;PALMYRENE LETTER MEM;Lo;0;R;;;;;N;;;;;\n1086D;PALMYRENE LETTER FINAL NUN;Lo;0;R;;;;;N;;;;;\n1086E;PALMYRENE LETTER NUN;Lo;0;R;;;;;N;;;;;\n1086F;PALMYRENE LETTER SAMEKH;Lo;0;R;;;;;N;;;;;\n10870;PALMYRENE LETTER AYIN;Lo;0;R;;;;;N;;;;;\n10871;PALMYRENE LETTER PE;Lo;0;R;;;;;N;;;;;\n10872;PALMYRENE LETTER SADHE;Lo;0;R;;;;;N;;;;;\n10873;PALMYRENE LETTER QOPH;Lo;0;R;;;;;N;;;;;\n10874;PALMYRENE LETTER RESH;Lo;0;R;;;;;N;;;;;\n10875;PALMYRENE LETTER SHIN;Lo;0;R;;;;;N;;;;;\n10876;PALMYRENE LETTER TAW;Lo;0;R;;;;;N;;;;;\n10877;PALMYRENE LEFT-POINTING FLEURON;So;0;R;;;;;N;;;;;\n10878;PALMYRENE RIGHT-POINTING FLEURON;So;0;R;;;;;N;;;;;\n10879;PALMYRENE NUMBER ONE;No;0;R;;;;1;N;;;;;\n1087A;PALMYRENE NUMBER TWO;No;0;R;;;;2;N;;;;;\n1087B;PALMYRENE NUMBER THREE;No;0;R;;;;3;N;;;;;\n1087C;PALMYRENE NUMBER FOUR;No;0;R;;;;4;N;;;;;\n1087D;PALMYRENE NUMBER FIVE;No;0;R;;;;5;N;;;;;\n1087E;PALMYRENE NUMBER TEN;No;0;R;;;;10;N;;;;;\n1087F;PALMYRENE NUMBER TWENTY;No;0;R;;;;20;N;;;;;\n10880;NABATAEAN LETTER FINAL ALEPH;Lo;0;R;;;;;N;;;;;\n10881;NABATAEAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;\n10882;NABATAEAN LETTER FINAL BETH;Lo;0;R;;;;;N;;;;;\n10883;NABATAEAN LETTER BETH;Lo;0;R;;;;;N;;;;;\n10884;NABATAEAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;\n10885;NABATAEAN LETTER DALETH;Lo;0;R;;;;;N;;;;;\n10886;NABATAEAN LETTER FINAL HE;Lo;0;R;;;;;N;;;;;\n10887;NABATAEAN LETTER HE;Lo;0;R;;;;;N;;;;;\n10888;NABATAEAN LETTER WAW;Lo;0;R;;;;;N;;;;;\n10889;NABATAEAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;;\n1088A;NABATAEAN LETTER HETH;Lo;0;R;;;;;N;;;;;\n1088B;NABATAEAN LETTER TETH;Lo;0;R;;;;;N;;;;;\n1088C;NABATAEAN LETTER FINAL YODH;Lo;0;R;;;;;N;;;;;\n1088D;NABATAEAN LETTER YODH;Lo;0;R;;;;;N;;;;;\n1088E;NABATAEAN LETTER FINAL KAPH;Lo;0;R;;;;;N;;;;;\n1088F;NABATAEAN LETTER KAPH;Lo;0;R;;;;;N;;;;;\n10890;NABATAEAN LETTER FINAL LAMEDH;Lo;0;R;;;;;N;;;;;\n10891;NABATAEAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;\n10892;NABATAEAN LETTER FINAL MEM;Lo;0;R;;;;;N;;;;;\n10893;NABATAEAN LETTER MEM;Lo;0;R;;;;;N;;;;;\n10894;NABATAEAN LETTER FINAL NUN;Lo;0;R;;;;;N;;;;;\n10895;NABATAEAN LETTER NUN;Lo;0;R;;;;;N;;;;;\n10896;NABATAEAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;\n10897;NABATAEAN LETTER AYIN;Lo;0;R;;;;;N;;;;;\n10898;NABATAEAN LETTER PE;Lo;0;R;;;;;N;;;;;\n10899;NABATAEAN LETTER SADHE;Lo;0;R;;;;;N;;;;;\n1089A;NABATAEAN LETTER QOPH;Lo;0;R;;;;;N;;;;;\n1089B;NABATAEAN LETTER RESH;Lo;0;R;;;;;N;;;;;\n1089C;NABATAEAN LETTER FINAL SHIN;Lo;0;R;;;;;N;;;;;\n1089D;NABATAEAN LETTER SHIN;Lo;0;R;;;;;N;;;;;\n1089E;NABATAEAN LETTER TAW;Lo;0;R;;;;;N;;;;;\n108A7;NABATAEAN NUMBER ONE;No;0;R;;;;1;N;;;;;\n108A8;NABATAEAN NUMBER TWO;No;0;R;;;;2;N;;;;;\n108A9;NABATAEAN NUMBER THREE;No;0;R;;;;3;N;;;;;\n108AA;NABATAEAN NUMBER FOUR;No;0;R;;;;4;N;;;;;\n108AB;NABATAEAN CRUCIFORM NUMBER FOUR;No;0;R;;;;4;N;;;;;\n108AC;NABATAEAN NUMBER FIVE;No;0;R;;;;5;N;;;;;\n108AD;NABATAEAN NUMBER TEN;No;0;R;;;;10;N;;;;;\n108AE;NABATAEAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;\n108AF;NABATAEAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;\n108E0;HATRAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;\n108E1;HATRAN LETTER BETH;Lo;0;R;;;;;N;;;;;\n108E2;HATRAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;\n108E3;HATRAN LETTER DALETH-RESH;Lo;0;R;;;;;N;;;;;\n108E4;HATRAN LETTER HE;Lo;0;R;;;;;N;;;;;\n108E5;HATRAN LETTER WAW;Lo;0;R;;;;;N;;;;;\n108E6;HATRAN LETTER ZAYN;Lo;0;R;;;;;N;;;;;\n108E7;HATRAN LETTER HETH;Lo;0;R;;;;;N;;;;;\n108E8;HATRAN LETTER TETH;Lo;0;R;;;;;N;;;;;\n108E9;HATRAN LETTER YODH;Lo;0;R;;;;;N;;;;;\n108EA;HATRAN LETTER KAPH;Lo;0;R;;;;;N;;;;;\n108EB;HATRAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;\n108EC;HATRAN LETTER MEM;Lo;0;R;;;;;N;;;;;\n108ED;HATRAN LETTER NUN;Lo;0;R;;;;;N;;;;;\n108EE;HATRAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;\n108EF;HATRAN LETTER AYN;Lo;0;R;;;;;N;;;;;\n108F0;HATRAN LETTER PE;Lo;0;R;;;;;N;;;;;\n108F1;HATRAN LETTER SADHE;Lo;0;R;;;;;N;;;;;\n108F2;HATRAN LETTER QOPH;Lo;0;R;;;;;N;;;;;\n108F4;HATRAN LETTER SHIN;Lo;0;R;;;;;N;;;;;\n108F5;HATRAN LETTER TAW;Lo;0;R;;;;;N;;;;;\n108FB;HATRAN NUMBER ONE;No;0;R;;;;1;N;;;;;\n108FC;HATRAN NUMBER FIVE;No;0;R;;;;5;N;;;;;\n108FD;HATRAN NUMBER TEN;No;0;R;;;;10;N;;;;;\n108FE;HATRAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;\n108FF;HATRAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;\n10900;PHOENICIAN LETTER ALF;Lo;0;R;;;;;N;;;;;\n10901;PHOENICIAN LETTER BET;Lo;0;R;;;;;N;;;;;\n10902;PHOENICIAN LETTER GAML;Lo;0;R;;;;;N;;;;;\n10903;PHOENICIAN LETTER DELT;Lo;0;R;;;;;N;;;;;\n10904;PHOENICIAN LETTER HE;Lo;0;R;;;;;N;;;;;\n10905;PHOENICIAN LETTER WAU;Lo;0;R;;;;;N;;;;;\n10906;PHOENICIAN LETTER ZAI;Lo;0;R;;;;;N;;;;;\n10907;PHOENICIAN LETTER HET;Lo;0;R;;;;;N;;;;;\n10908;PHOENICIAN LETTER TET;Lo;0;R;;;;;N;;;;;\n10909;PHOENICIAN LETTER YOD;Lo;0;R;;;;;N;;;;;\n1090A;PHOENICIAN LETTER KAF;Lo;0;R;;;;;N;;;;;\n1090B;PHOENICIAN LETTER LAMD;Lo;0;R;;;;;N;;;;;\n1090C;PHOENICIAN LETTER MEM;Lo;0;R;;;;;N;;;;;\n1090D;PHOENICIAN LETTER NUN;Lo;0;R;;;;;N;;;;;\n1090E;PHOENICIAN LETTER SEMK;Lo;0;R;;;;;N;;;;;\n1090F;PHOENICIAN LETTER AIN;Lo;0;R;;;;;N;;;;;\n10910;PHOENICIAN LETTER PE;Lo;0;R;;;;;N;;;;;\n10911;PHOENICIAN LETTER SADE;Lo;0;R;;;;;N;;;;;\n10912;PHOENICIAN LETTER QOF;Lo;0;R;;;;;N;;;;;\n10913;PHOENICIAN LETTER ROSH;Lo;0;R;;;;;N;;;;;\n10914;PHOENICIAN LETTER SHIN;Lo;0;R;;;;;N;;;;;\n10915;PHOENICIAN LETTER TAU;Lo;0;R;;;;;N;;;;;\n10916;PHOENICIAN NUMBER ONE;No;0;R;;;;1;N;;;;;\n10917;PHOENICIAN NUMBER TEN;No;0;R;;;;10;N;;;;;\n10918;PHOENICIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;\n10919;PHOENICIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;\n1091A;PHOENICIAN NUMBER TWO;No;0;R;;;;2;N;;;;;\n1091B;PHOENICIAN NUMBER THREE;No;0;R;;;;3;N;;;;;\n1091F;PHOENICIAN WORD SEPARATOR;Po;0;ON;;;;;N;;;;;\n10920;LYDIAN LETTER A;Lo;0;R;;;;;N;;;;;\n10921;LYDIAN LETTER B;Lo;0;R;;;;;N;;;;;\n10922;LYDIAN LETTER G;Lo;0;R;;;;;N;;;;;\n10923;LYDIAN LETTER D;Lo;0;R;;;;;N;;;;;\n10924;LYDIAN LETTER E;Lo;0;R;;;;;N;;;;;\n10925;LYDIAN LETTER V;Lo;0;R;;;;;N;;;;;\n10926;LYDIAN LETTER I;Lo;0;R;;;;;N;;;;;\n10927;LYDIAN LETTER Y;Lo;0;R;;;;;N;;;;;\n10928;LYDIAN LETTER K;Lo;0;R;;;;;N;;;;;\n10929;LYDIAN LETTER L;Lo;0;R;;;;;N;;;;;\n1092A;LYDIAN LETTER M;Lo;0;R;;;;;N;;;;;\n1092B;LYDIAN LETTER N;Lo;0;R;;;;;N;;;;;\n1092C;LYDIAN LETTER O;Lo;0;R;;;;;N;;;;;\n1092D;LYDIAN LETTER R;Lo;0;R;;;;;N;;;;;\n1092E;LYDIAN LETTER SS;Lo;0;R;;;;;N;;;;;\n1092F;LYDIAN LETTER T;Lo;0;R;;;;;N;;;;;\n10930;LYDIAN LETTER U;Lo;0;R;;;;;N;;;;;\n10931;LYDIAN LETTER F;Lo;0;R;;;;;N;;;;;\n10932;LYDIAN LETTER Q;Lo;0;R;;;;;N;;;;;\n10933;LYDIAN LETTER S;Lo;0;R;;;;;N;;;;;\n10934;LYDIAN LETTER TT;Lo;0;R;;;;;N;;;;;\n10935;LYDIAN LETTER AN;Lo;0;R;;;;;N;;;;;\n10936;LYDIAN LETTER EN;Lo;0;R;;;;;N;;;;;\n10937;LYDIAN LETTER LY;Lo;0;R;;;;;N;;;;;\n10938;LYDIAN LETTER NN;Lo;0;R;;;;;N;;;;;\n10939;LYDIAN LETTER C;Lo;0;R;;;;;N;;;;;\n1093F;LYDIAN TRIANGULAR MARK;Po;0;R;;;;;N;;;;;\n10980;MEROITIC HIEROGLYPHIC LETTER A;Lo;0;R;;;;;N;;;;;\n10981;MEROITIC HIEROGLYPHIC LETTER E;Lo;0;R;;;;;N;;;;;\n10982;MEROITIC HIEROGLYPHIC LETTER I;Lo;0;R;;;;;N;;;;;\n10983;MEROITIC HIEROGLYPHIC LETTER O;Lo;0;R;;;;;N;;;;;\n10984;MEROITIC HIEROGLYPHIC LETTER YA;Lo;0;R;;;;;N;;;;;\n10985;MEROITIC HIEROGLYPHIC LETTER WA;Lo;0;R;;;;;N;;;;;\n10986;MEROITIC HIEROGLYPHIC LETTER BA;Lo;0;R;;;;;N;;;;;\n10987;MEROITIC HIEROGLYPHIC LETTER BA-2;Lo;0;R;;;;;N;;;;;\n10988;MEROITIC HIEROGLYPHIC LETTER PA;Lo;0;R;;;;;N;;;;;\n10989;MEROITIC HIEROGLYPHIC LETTER MA;Lo;0;R;;;;;N;;;;;\n1098A;MEROITIC HIEROGLYPHIC LETTER NA;Lo;0;R;;;;;N;;;;;\n1098B;MEROITIC HIEROGLYPHIC LETTER NA-2;Lo;0;R;;;;;N;;;;;\n1098C;MEROITIC HIEROGLYPHIC LETTER NE;Lo;0;R;;;;;N;;;;;\n1098D;MEROITIC HIEROGLYPHIC LETTER NE-2;Lo;0;R;;;;;N;;;;;\n1098E;MEROITIC HIEROGLYPHIC LETTER RA;Lo;0;R;;;;;N;;;;;\n1098F;MEROITIC HIEROGLYPHIC LETTER RA-2;Lo;0;R;;;;;N;;;;;\n10990;MEROITIC HIEROGLYPHIC LETTER LA;Lo;0;R;;;;;N;;;;;\n10991;MEROITIC HIEROGLYPHIC LETTER KHA;Lo;0;R;;;;;N;;;;;\n10992;MEROITIC HIEROGLYPHIC LETTER HHA;Lo;0;R;;;;;N;;;;;\n10993;MEROITIC HIEROGLYPHIC LETTER SA;Lo;0;R;;;;;N;;;;;\n10994;MEROITIC HIEROGLYPHIC LETTER SA-2;Lo;0;R;;;;;N;;;;;\n10995;MEROITIC HIEROGLYPHIC LETTER SE;Lo;0;R;;;;;N;;;;;\n10996;MEROITIC HIEROGLYPHIC LETTER KA;Lo;0;R;;;;;N;;;;;\n10997;MEROITIC HIEROGLYPHIC LETTER QA;Lo;0;R;;;;;N;;;;;\n10998;MEROITIC HIEROGLYPHIC LETTER TA;Lo;0;R;;;;;N;;;;;\n10999;MEROITIC HIEROGLYPHIC LETTER TA-2;Lo;0;R;;;;;N;;;;;\n1099A;MEROITIC HIEROGLYPHIC LETTER TE;Lo;0;R;;;;;N;;;;;\n1099B;MEROITIC HIEROGLYPHIC LETTER TE-2;Lo;0;R;;;;;N;;;;;\n1099C;MEROITIC HIEROGLYPHIC LETTER TO;Lo;0;R;;;;;N;;;;;\n1099D;MEROITIC HIEROGLYPHIC LETTER DA;Lo;0;R;;;;;N;;;;;\n1099E;MEROITIC HIEROGLYPHIC SYMBOL VIDJ;Lo;0;R;;;;;N;;;;;\n1099F;MEROITIC HIEROGLYPHIC SYMBOL VIDJ-2;Lo;0;R;;;;;N;;;;;\n109A0;MEROITIC CURSIVE LETTER A;Lo;0;R;;;;;N;;;;;\n109A1;MEROITIC CURSIVE LETTER E;Lo;0;R;;;;;N;;;;;\n109A2;MEROITIC CURSIVE LETTER I;Lo;0;R;;;;;N;;;;;\n109A3;MEROITIC CURSIVE LETTER O;Lo;0;R;;;;;N;;;;;\n109A4;MEROITIC CURSIVE LETTER YA;Lo;0;R;;;;;N;;;;;\n109A5;MEROITIC CURSIVE LETTER WA;Lo;0;R;;;;;N;;;;;\n109A6;MEROITIC CURSIVE LETTER BA;Lo;0;R;;;;;N;;;;;\n109A7;MEROITIC CURSIVE LETTER PA;Lo;0;R;;;;;N;;;;;\n109A8;MEROITIC CURSIVE LETTER MA;Lo;0;R;;;;;N;;;;;\n109A9;MEROITIC CURSIVE LETTER NA;Lo;0;R;;;;;N;;;;;\n109AA;MEROITIC CURSIVE LETTER NE;Lo;0;R;;;;;N;;;;;\n109AB;MEROITIC CURSIVE LETTER RA;Lo;0;R;;;;;N;;;;;\n109AC;MEROITIC CURSIVE LETTER LA;Lo;0;R;;;;;N;;;;;\n109AD;MEROITIC CURSIVE LETTER KHA;Lo;0;R;;;;;N;;;;;\n109AE;MEROITIC CURSIVE LETTER HHA;Lo;0;R;;;;;N;;;;;\n109AF;MEROITIC CURSIVE LETTER SA;Lo;0;R;;;;;N;;;;;\n109B0;MEROITIC CURSIVE LETTER ARCHAIC SA;Lo;0;R;;;;;N;;;;;\n109B1;MEROITIC CURSIVE LETTER SE;Lo;0;R;;;;;N;;;;;\n109B2;MEROITIC CURSIVE LETTER KA;Lo;0;R;;;;;N;;;;;\n109B3;MEROITIC CURSIVE LETTER QA;Lo;0;R;;;;;N;;;;;\n109B4;MEROITIC CURSIVE LETTER TA;Lo;0;R;;;;;N;;;;;\n109B5;MEROITIC CURSIVE LETTER TE;Lo;0;R;;;;;N;;;;;\n109B6;MEROITIC CURSIVE LETTER TO;Lo;0;R;;;;;N;;;;;\n109B7;MEROITIC CURSIVE LETTER DA;Lo;0;R;;;;;N;;;;;\n109BC;MEROITIC CURSIVE FRACTION ELEVEN TWELFTHS;No;0;R;;;;11/12;N;;;;;\n109BD;MEROITIC CURSIVE FRACTION ONE HALF;No;0;R;;;;1/2;N;;;;;\n109BE;MEROITIC CURSIVE LOGOGRAM RMT;Lo;0;R;;;;;N;;;;;\n109BF;MEROITIC CURSIVE LOGOGRAM IMN;Lo;0;R;;;;;N;;;;;\n109C0;MEROITIC CURSIVE NUMBER ONE;No;0;R;;;;1;N;;;;;\n109C1;MEROITIC CURSIVE NUMBER TWO;No;0;R;;;;2;N;;;;;\n109C2;MEROITIC CURSIVE NUMBER THREE;No;0;R;;;;3;N;;;;;\n109C3;MEROITIC CURSIVE NUMBER FOUR;No;0;R;;;;4;N;;;;;\n109C4;MEROITIC CURSIVE NUMBER FIVE;No;0;R;;;;5;N;;;;;\n109C5;MEROITIC CURSIVE NUMBER SIX;No;0;R;;;;6;N;;;;;\n109C6;MEROITIC CURSIVE NUMBER SEVEN;No;0;R;;;;7;N;;;;;\n109C7;MEROITIC CURSIVE NUMBER EIGHT;No;0;R;;;;8;N;;;;;\n109C8;MEROITIC CURSIVE NUMBER NINE;No;0;R;;;;9;N;;;;;\n109C9;MEROITIC CURSIVE NUMBER TEN;No;0;R;;;;10;N;;;;;\n109CA;MEROITIC CURSIVE NUMBER TWENTY;No;0;R;;;;20;N;;;;;\n109CB;MEROITIC CURSIVE NUMBER THIRTY;No;0;R;;;;30;N;;;;;\n109CC;MEROITIC CURSIVE NUMBER FORTY;No;0;R;;;;40;N;;;;;\n109CD;MEROITIC CURSIVE NUMBER FIFTY;No;0;R;;;;50;N;;;;;\n109CE;MEROITIC CURSIVE NUMBER SIXTY;No;0;R;;;;60;N;;;;;\n109CF;MEROITIC CURSIVE NUMBER SEVENTY;No;0;R;;;;70;N;;;;;\n109D2;MEROITIC CURSIVE NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;\n109D3;MEROITIC CURSIVE NUMBER TWO HUNDRED;No;0;R;;;;200;N;;;;;\n109D4;MEROITIC CURSIVE NUMBER THREE HUNDRED;No;0;R;;;;300;N;;;;;\n109D5;MEROITIC CURSIVE NUMBER FOUR HUNDRED;No;0;R;;;;400;N;;;;;\n109D6;MEROITIC CURSIVE NUMBER FIVE HUNDRED;No;0;R;;;;500;N;;;;;\n109D7;MEROITIC CURSIVE NUMBER SIX HUNDRED;No;0;R;;;;600;N;;;;;\n109D8;MEROITIC CURSIVE NUMBER SEVEN HUNDRED;No;0;R;;;;700;N;;;;;\n109D9;MEROITIC CURSIVE NUMBER EIGHT HUNDRED;No;0;R;;;;800;N;;;;;\n109DA;MEROITIC CURSIVE NUMBER NINE HUNDRED;No;0;R;;;;900;N;;;;;\n109DB;MEROITIC CURSIVE NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;\n109DC;MEROITIC CURSIVE NUMBER TWO THOUSAND;No;0;R;;;;2000;N;;;;;\n109DD;MEROITIC CURSIVE NUMBER THREE THOUSAND;No;0;R;;;;3000;N;;;;;\n109DE;MEROITIC CURSIVE NUMBER FOUR THOUSAND;No;0;R;;;;4000;N;;;;;\n109DF;MEROITIC CURSIVE NUMBER FIVE THOUSAND;No;0;R;;;;5000;N;;;;;\n109E0;MEROITIC CURSIVE NUMBER SIX THOUSAND;No;0;R;;;;6000;N;;;;;\n109E1;MEROITIC CURSIVE NUMBER SEVEN THOUSAND;No;0;R;;;;7000;N;;;;;\n109E2;MEROITIC CURSIVE NUMBER EIGHT THOUSAND;No;0;R;;;;8000;N;;;;;\n109E3;MEROITIC CURSIVE NUMBER NINE THOUSAND;No;0;R;;;;9000;N;;;;;\n109E4;MEROITIC CURSIVE NUMBER TEN THOUSAND;No;0;R;;;;10000;N;;;;;\n109E5;MEROITIC CURSIVE NUMBER TWENTY THOUSAND;No;0;R;;;;20000;N;;;;;\n109E6;MEROITIC CURSIVE NUMBER THIRTY THOUSAND;No;0;R;;;;30000;N;;;;;\n109E7;MEROITIC CURSIVE NUMBER FORTY THOUSAND;No;0;R;;;;40000;N;;;;;\n109E8;MEROITIC CURSIVE NUMBER FIFTY THOUSAND;No;0;R;;;;50000;N;;;;;\n109E9;MEROITIC CURSIVE NUMBER SIXTY THOUSAND;No;0;R;;;;60000;N;;;;;\n109EA;MEROITIC CURSIVE NUMBER SEVENTY THOUSAND;No;0;R;;;;70000;N;;;;;\n109EB;MEROITIC CURSIVE NUMBER EIGHTY THOUSAND;No;0;R;;;;80000;N;;;;;\n109EC;MEROITIC CURSIVE NUMBER NINETY THOUSAND;No;0;R;;;;90000;N;;;;;\n109ED;MEROITIC CURSIVE NUMBER ONE HUNDRED THOUSAND;No;0;R;;;;100000;N;;;;;\n109EE;MEROITIC CURSIVE NUMBER TWO HUNDRED THOUSAND;No;0;R;;;;200000;N;;;;;\n109EF;MEROITIC CURSIVE NUMBER THREE HUNDRED THOUSAND;No;0;R;;;;300000;N;;;;;\n109F0;MEROITIC CURSIVE NUMBER FOUR HUNDRED THOUSAND;No;0;R;;;;400000;N;;;;;\n109F1;MEROITIC CURSIVE NUMBER FIVE HUNDRED THOUSAND;No;0;R;;;;500000;N;;;;;\n109F2;MEROITIC CURSIVE NUMBER SIX HUNDRED THOUSAND;No;0;R;;;;600000;N;;;;;\n109F3;MEROITIC CURSIVE NUMBER SEVEN HUNDRED THOUSAND;No;0;R;;;;700000;N;;;;;\n109F4;MEROITIC CURSIVE NUMBER EIGHT HUNDRED THOUSAND;No;0;R;;;;800000;N;;;;;\n109F5;MEROITIC CURSIVE NUMBER NINE HUNDRED THOUSAND;No;0;R;;;;900000;N;;;;;\n109F6;MEROITIC CURSIVE FRACTION ONE TWELFTH;No;0;R;;;;1/12;N;;;;;\n109F7;MEROITIC CURSIVE FRACTION TWO TWELFTHS;No;0;R;;;;2/12;N;;;;;\n109F8;MEROITIC CURSIVE FRACTION THREE TWELFTHS;No;0;R;;;;3/12;N;;;;;\n109F9;MEROITIC CURSIVE FRACTION FOUR TWELFTHS;No;0;R;;;;4/12;N;;;;;\n109FA;MEROITIC CURSIVE FRACTION FIVE TWELFTHS;No;0;R;;;;5/12;N;;;;;\n109FB;MEROITIC CURSIVE FRACTION SIX TWELFTHS;No;0;R;;;;6/12;N;;;;;\n109FC;MEROITIC CURSIVE FRACTION SEVEN TWELFTHS;No;0;R;;;;7/12;N;;;;;\n109FD;MEROITIC CURSIVE FRACTION EIGHT TWELFTHS;No;0;R;;;;8/12;N;;;;;\n109FE;MEROITIC CURSIVE FRACTION NINE TWELFTHS;No;0;R;;;;9/12;N;;;;;\n109FF;MEROITIC CURSIVE FRACTION TEN TWELFTHS;No;0;R;;;;10/12;N;;;;;\n10A00;KHAROSHTHI LETTER A;Lo;0;R;;;;;N;;;;;\n10A01;KHAROSHTHI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n10A02;KHAROSHTHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n10A03;KHAROSHTHI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n10A05;KHAROSHTHI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n10A06;KHAROSHTHI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;\n10A0C;KHAROSHTHI VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;;\n10A0D;KHAROSHTHI SIGN DOUBLE RING BELOW;Mn;220;NSM;;;;;N;;;;;\n10A0E;KHAROSHTHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n10A0F;KHAROSHTHI SIGN VISARGA;Mn;230;NSM;;;;;N;;;;;\n10A10;KHAROSHTHI LETTER KA;Lo;0;R;;;;;N;;;;;\n10A11;KHAROSHTHI LETTER KHA;Lo;0;R;;;;;N;;;;;\n10A12;KHAROSHTHI LETTER GA;Lo;0;R;;;;;N;;;;;\n10A13;KHAROSHTHI LETTER GHA;Lo;0;R;;;;;N;;;;;\n10A15;KHAROSHTHI LETTER CA;Lo;0;R;;;;;N;;;;;\n10A16;KHAROSHTHI LETTER CHA;Lo;0;R;;;;;N;;;;;\n10A17;KHAROSHTHI LETTER JA;Lo;0;R;;;;;N;;;;;\n10A19;KHAROSHTHI LETTER NYA;Lo;0;R;;;;;N;;;;;\n10A1A;KHAROSHTHI LETTER TTA;Lo;0;R;;;;;N;;;;;\n10A1B;KHAROSHTHI LETTER TTHA;Lo;0;R;;;;;N;;;;;\n10A1C;KHAROSHTHI LETTER DDA;Lo;0;R;;;;;N;;;;;\n10A1D;KHAROSHTHI LETTER DDHA;Lo;0;R;;;;;N;;;;;\n10A1E;KHAROSHTHI LETTER NNA;Lo;0;R;;;;;N;;;;;\n10A1F;KHAROSHTHI LETTER TA;Lo;0;R;;;;;N;;;;;\n10A20;KHAROSHTHI LETTER THA;Lo;0;R;;;;;N;;;;;\n10A21;KHAROSHTHI LETTER DA;Lo;0;R;;;;;N;;;;;\n10A22;KHAROSHTHI LETTER DHA;Lo;0;R;;;;;N;;;;;\n10A23;KHAROSHTHI LETTER NA;Lo;0;R;;;;;N;;;;;\n10A24;KHAROSHTHI LETTER PA;Lo;0;R;;;;;N;;;;;\n10A25;KHAROSHTHI LETTER PHA;Lo;0;R;;;;;N;;;;;\n10A26;KHAROSHTHI LETTER BA;Lo;0;R;;;;;N;;;;;\n10A27;KHAROSHTHI LETTER BHA;Lo;0;R;;;;;N;;;;;\n10A28;KHAROSHTHI LETTER MA;Lo;0;R;;;;;N;;;;;\n10A29;KHAROSHTHI LETTER YA;Lo;0;R;;;;;N;;;;;\n10A2A;KHAROSHTHI LETTER RA;Lo;0;R;;;;;N;;;;;\n10A2B;KHAROSHTHI LETTER LA;Lo;0;R;;;;;N;;;;;\n10A2C;KHAROSHTHI LETTER VA;Lo;0;R;;;;;N;;;;;\n10A2D;KHAROSHTHI LETTER SHA;Lo;0;R;;;;;N;;;;;\n10A2E;KHAROSHTHI LETTER SSA;Lo;0;R;;;;;N;;;;;\n10A2F;KHAROSHTHI LETTER SA;Lo;0;R;;;;;N;;;;;\n10A30;KHAROSHTHI LETTER ZA;Lo;0;R;;;;;N;;;;;\n10A31;KHAROSHTHI LETTER HA;Lo;0;R;;;;;N;;;;;\n10A32;KHAROSHTHI LETTER KKA;Lo;0;R;;;;;N;;;;;\n10A33;KHAROSHTHI LETTER TTTHA;Lo;0;R;;;;;N;;;;;\n10A34;KHAROSHTHI LETTER TTTA;Lo;0;R;;;;;N;;;;;\n10A35;KHAROSHTHI LETTER VHA;Lo;0;R;;;;;N;;;;;\n10A38;KHAROSHTHI SIGN BAR ABOVE;Mn;230;NSM;;;;;N;;;;;\n10A39;KHAROSHTHI SIGN CAUDA;Mn;1;NSM;;;;;N;;;;;\n10A3A;KHAROSHTHI SIGN DOT BELOW;Mn;220;NSM;;;;;N;;;;;\n10A3F;KHAROSHTHI VIRAMA;Mn;9;NSM;;;;;N;;;;;\n10A40;KHAROSHTHI DIGIT ONE;No;0;R;;;1;1;N;;;;;\n10A41;KHAROSHTHI DIGIT TWO;No;0;R;;;2;2;N;;;;;\n10A42;KHAROSHTHI DIGIT THREE;No;0;R;;;3;3;N;;;;;\n10A43;KHAROSHTHI DIGIT FOUR;No;0;R;;;4;4;N;;;;;\n10A44;KHAROSHTHI NUMBER TEN;No;0;R;;;;10;N;;;;;\n10A45;KHAROSHTHI NUMBER TWENTY;No;0;R;;;;20;N;;;;;\n10A46;KHAROSHTHI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;\n10A47;KHAROSHTHI NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;\n10A48;KHAROSHTHI FRACTION ONE HALF;No;0;R;;;;1/2;N;;;;;\n10A50;KHAROSHTHI PUNCTUATION DOT;Po;0;R;;;;;N;;;;;\n10A51;KHAROSHTHI PUNCTUATION SMALL CIRCLE;Po;0;R;;;;;N;;;;;\n10A52;KHAROSHTHI PUNCTUATION CIRCLE;Po;0;R;;;;;N;;;;;\n10A53;KHAROSHTHI PUNCTUATION CRESCENT BAR;Po;0;R;;;;;N;;;;;\n10A54;KHAROSHTHI PUNCTUATION MANGALAM;Po;0;R;;;;;N;;;;;\n10A55;KHAROSHTHI PUNCTUATION LOTUS;Po;0;R;;;;;N;;;;;\n10A56;KHAROSHTHI PUNCTUATION DANDA;Po;0;R;;;;;N;;;;;\n10A57;KHAROSHTHI PUNCTUATION DOUBLE DANDA;Po;0;R;;;;;N;;;;;\n10A58;KHAROSHTHI PUNCTUATION LINES;Po;0;R;;;;;N;;;;;\n10A60;OLD SOUTH ARABIAN LETTER HE;Lo;0;R;;;;;N;;;;;\n10A61;OLD SOUTH ARABIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;\n10A62;OLD SOUTH ARABIAN LETTER HETH;Lo;0;R;;;;;N;;;;;\n10A63;OLD SOUTH ARABIAN LETTER MEM;Lo;0;R;;;;;N;;;;;\n10A64;OLD SOUTH ARABIAN LETTER QOPH;Lo;0;R;;;;;N;;;;;\n10A65;OLD SOUTH ARABIAN LETTER WAW;Lo;0;R;;;;;N;;;;;\n10A66;OLD SOUTH ARABIAN LETTER SHIN;Lo;0;R;;;;;N;;;;;\n10A67;OLD SOUTH ARABIAN LETTER RESH;Lo;0;R;;;;;N;;;;;\n10A68;OLD SOUTH ARABIAN LETTER BETH;Lo;0;R;;;;;N;;;;;\n10A69;OLD SOUTH ARABIAN LETTER TAW;Lo;0;R;;;;;N;;;;;\n10A6A;OLD SOUTH ARABIAN LETTER SAT;Lo;0;R;;;;;N;;;;;\n10A6B;OLD SOUTH ARABIAN LETTER KAPH;Lo;0;R;;;;;N;;;;;\n10A6C;OLD SOUTH ARABIAN LETTER NUN;Lo;0;R;;;;;N;;;;;\n10A6D;OLD SOUTH ARABIAN LETTER KHETH;Lo;0;R;;;;;N;;;;;\n10A6E;OLD SOUTH ARABIAN LETTER SADHE;Lo;0;R;;;;;N;;;;;\n10A6F;OLD SOUTH ARABIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;\n10A70;OLD SOUTH ARABIAN LETTER FE;Lo;0;R;;;;;N;;;;;\n10A71;OLD SOUTH ARABIAN LETTER ALEF;Lo;0;R;;;;;N;;;;;\n10A72;OLD SOUTH ARABIAN LETTER AYN;Lo;0;R;;;;;N;;;;;\n10A73;OLD SOUTH ARABIAN LETTER DHADHE;Lo;0;R;;;;;N;;;;;\n10A74;OLD SOUTH ARABIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;\n10A75;OLD SOUTH ARABIAN LETTER DALETH;Lo;0;R;;;;;N;;;;;\n10A76;OLD SOUTH ARABIAN LETTER GHAYN;Lo;0;R;;;;;N;;;;;\n10A77;OLD SOUTH ARABIAN LETTER TETH;Lo;0;R;;;;;N;;;;;\n10A78;OLD SOUTH ARABIAN LETTER ZAYN;Lo;0;R;;;;;N;;;;;\n10A79;OLD SOUTH ARABIAN LETTER DHALETH;Lo;0;R;;;;;N;;;;;\n10A7A;OLD SOUTH ARABIAN LETTER YODH;Lo;0;R;;;;;N;;;;;\n10A7B;OLD SOUTH ARABIAN LETTER THAW;Lo;0;R;;;;;N;;;;;\n10A7C;OLD SOUTH ARABIAN LETTER THETH;Lo;0;R;;;;;N;;;;;\n10A7D;OLD SOUTH ARABIAN NUMBER ONE;No;0;R;;;;1;N;;;;;\n10A7E;OLD SOUTH ARABIAN NUMBER FIFTY;No;0;R;;;;50;N;;;;;\n10A7F;OLD SOUTH ARABIAN NUMERIC INDICATOR;Po;0;R;;;;;N;;;;;\n10A80;OLD NORTH ARABIAN LETTER HEH;Lo;0;R;;;;;N;;;;;\n10A81;OLD NORTH ARABIAN LETTER LAM;Lo;0;R;;;;;N;;;;;\n10A82;OLD NORTH ARABIAN LETTER HAH;Lo;0;R;;;;;N;;;;;\n10A83;OLD NORTH ARABIAN LETTER MEEM;Lo;0;R;;;;;N;;;;;\n10A84;OLD NORTH ARABIAN LETTER QAF;Lo;0;R;;;;;N;;;;;\n10A85;OLD NORTH ARABIAN LETTER WAW;Lo;0;R;;;;;N;;;;;\n10A86;OLD NORTH ARABIAN LETTER ES-2;Lo;0;R;;;;;N;;;;;\n10A87;OLD NORTH ARABIAN LETTER REH;Lo;0;R;;;;;N;;;;;\n10A88;OLD NORTH ARABIAN LETTER BEH;Lo;0;R;;;;;N;;;;;\n10A89;OLD NORTH ARABIAN LETTER TEH;Lo;0;R;;;;;N;;;;;\n10A8A;OLD NORTH ARABIAN LETTER ES-1;Lo;0;R;;;;;N;;;;;\n10A8B;OLD NORTH ARABIAN LETTER KAF;Lo;0;R;;;;;N;;;;;\n10A8C;OLD NORTH ARABIAN LETTER NOON;Lo;0;R;;;;;N;;;;;\n10A8D;OLD NORTH ARABIAN LETTER KHAH;Lo;0;R;;;;;N;;;;;\n10A8E;OLD NORTH ARABIAN LETTER SAD;Lo;0;R;;;;;N;;;;;\n10A8F;OLD NORTH ARABIAN LETTER ES-3;Lo;0;R;;;;;N;;;;;\n10A90;OLD NORTH ARABIAN LETTER FEH;Lo;0;R;;;;;N;;;;;\n10A91;OLD NORTH ARABIAN LETTER ALEF;Lo;0;R;;;;;N;;;;;\n10A92;OLD NORTH ARABIAN LETTER AIN;Lo;0;R;;;;;N;;;;;\n10A93;OLD NORTH ARABIAN LETTER DAD;Lo;0;R;;;;;N;;;;;\n10A94;OLD NORTH ARABIAN LETTER GEEM;Lo;0;R;;;;;N;;;;;\n10A95;OLD NORTH ARABIAN LETTER DAL;Lo;0;R;;;;;N;;;;;\n10A96;OLD NORTH ARABIAN LETTER GHAIN;Lo;0;R;;;;;N;;;;;\n10A97;OLD NORTH ARABIAN LETTER TAH;Lo;0;R;;;;;N;;;;;\n10A98;OLD NORTH ARABIAN LETTER ZAIN;Lo;0;R;;;;;N;;;;;\n10A99;OLD NORTH ARABIAN LETTER THAL;Lo;0;R;;;;;N;;;;;\n10A9A;OLD NORTH ARABIAN LETTER YEH;Lo;0;R;;;;;N;;;;;\n10A9B;OLD NORTH ARABIAN LETTER THEH;Lo;0;R;;;;;N;;;;;\n10A9C;OLD NORTH ARABIAN LETTER ZAH;Lo;0;R;;;;;N;;;;;\n10A9D;OLD NORTH ARABIAN NUMBER ONE;No;0;R;;;;1;N;;;;;\n10A9E;OLD NORTH ARABIAN NUMBER TEN;No;0;R;;;;10;N;;;;;\n10A9F;OLD NORTH ARABIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;\n10AC0;MANICHAEAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;\n10AC1;MANICHAEAN LETTER BETH;Lo;0;R;;;;;N;;;;;\n10AC2;MANICHAEAN LETTER BHETH;Lo;0;R;;;;;N;;;;;\n10AC3;MANICHAEAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;\n10AC4;MANICHAEAN LETTER GHIMEL;Lo;0;R;;;;;N;;;;;\n10AC5;MANICHAEAN LETTER DALETH;Lo;0;R;;;;;N;;;;;\n10AC6;MANICHAEAN LETTER HE;Lo;0;R;;;;;N;;;;;\n10AC7;MANICHAEAN LETTER WAW;Lo;0;R;;;;;N;;;;;\n10AC8;MANICHAEAN SIGN UD;So;0;R;;;;;N;;;;;\n10AC9;MANICHAEAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;;\n10ACA;MANICHAEAN LETTER ZHAYIN;Lo;0;R;;;;;N;;;;;\n10ACB;MANICHAEAN LETTER JAYIN;Lo;0;R;;;;;N;;;;;\n10ACC;MANICHAEAN LETTER JHAYIN;Lo;0;R;;;;;N;;;;;\n10ACD;MANICHAEAN LETTER HETH;Lo;0;R;;;;;N;;;;;\n10ACE;MANICHAEAN LETTER TETH;Lo;0;R;;;;;N;;;;;\n10ACF;MANICHAEAN LETTER YODH;Lo;0;R;;;;;N;;;;;\n10AD0;MANICHAEAN LETTER KAPH;Lo;0;R;;;;;N;;;;;\n10AD1;MANICHAEAN LETTER XAPH;Lo;0;R;;;;;N;;;;;\n10AD2;MANICHAEAN LETTER KHAPH;Lo;0;R;;;;;N;;;;;\n10AD3;MANICHAEAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;\n10AD4;MANICHAEAN LETTER DHAMEDH;Lo;0;R;;;;;N;;;;;\n10AD5;MANICHAEAN LETTER THAMEDH;Lo;0;R;;;;;N;;;;;\n10AD6;MANICHAEAN LETTER MEM;Lo;0;R;;;;;N;;;;;\n10AD7;MANICHAEAN LETTER NUN;Lo;0;R;;;;;N;;;;;\n10AD8;MANICHAEAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;\n10AD9;MANICHAEAN LETTER AYIN;Lo;0;R;;;;;N;;;;;\n10ADA;MANICHAEAN LETTER AAYIN;Lo;0;R;;;;;N;;;;;\n10ADB;MANICHAEAN LETTER PE;Lo;0;R;;;;;N;;;;;\n10ADC;MANICHAEAN LETTER FE;Lo;0;R;;;;;N;;;;;\n10ADD;MANICHAEAN LETTER SADHE;Lo;0;R;;;;;N;;;;;\n10ADE;MANICHAEAN LETTER QOPH;Lo;0;R;;;;;N;;;;;\n10ADF;MANICHAEAN LETTER XOPH;Lo;0;R;;;;;N;;;;;\n10AE0;MANICHAEAN LETTER QHOPH;Lo;0;R;;;;;N;;;;;\n10AE1;MANICHAEAN LETTER RESH;Lo;0;R;;;;;N;;;;;\n10AE2;MANICHAEAN LETTER SHIN;Lo;0;R;;;;;N;;;;;\n10AE3;MANICHAEAN LETTER SSHIN;Lo;0;R;;;;;N;;;;;\n10AE4;MANICHAEAN LETTER TAW;Lo;0;R;;;;;N;;;;;\n10AE5;MANICHAEAN ABBREVIATION MARK ABOVE;Mn;230;NSM;;;;;N;;;;;\n10AE6;MANICHAEAN ABBREVIATION MARK BELOW;Mn;220;NSM;;;;;N;;;;;\n10AEB;MANICHAEAN NUMBER ONE;No;0;R;;;;1;N;;;;;\n10AEC;MANICHAEAN NUMBER FIVE;No;0;R;;;;5;N;;;;;\n10AED;MANICHAEAN NUMBER TEN;No;0;R;;;;10;N;;;;;\n10AEE;MANICHAEAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;\n10AEF;MANICHAEAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;\n10AF0;MANICHAEAN PUNCTUATION STAR;Po;0;R;;;;;N;;;;;\n10AF1;MANICHAEAN PUNCTUATION FLEURON;Po;0;R;;;;;N;;;;;\n10AF2;MANICHAEAN PUNCTUATION DOUBLE DOT WITHIN DOT;Po;0;R;;;;;N;;;;;\n10AF3;MANICHAEAN PUNCTUATION DOT WITHIN DOT;Po;0;R;;;;;N;;;;;\n10AF4;MANICHAEAN PUNCTUATION DOT;Po;0;R;;;;;N;;;;;\n10AF5;MANICHAEAN PUNCTUATION TWO DOTS;Po;0;R;;;;;N;;;;;\n10AF6;MANICHAEAN PUNCTUATION LINE FILLER;Po;0;R;;;;;N;;;;;\n10B00;AVESTAN LETTER A;Lo;0;R;;;;;N;;;;;\n10B01;AVESTAN LETTER AA;Lo;0;R;;;;;N;;;;;\n10B02;AVESTAN LETTER AO;Lo;0;R;;;;;N;;;;;\n10B03;AVESTAN LETTER AAO;Lo;0;R;;;;;N;;;;;\n10B04;AVESTAN LETTER AN;Lo;0;R;;;;;N;;;;;\n10B05;AVESTAN LETTER AAN;Lo;0;R;;;;;N;;;;;\n10B06;AVESTAN LETTER AE;Lo;0;R;;;;;N;;;;;\n10B07;AVESTAN LETTER AEE;Lo;0;R;;;;;N;;;;;\n10B08;AVESTAN LETTER E;Lo;0;R;;;;;N;;;;;\n10B09;AVESTAN LETTER EE;Lo;0;R;;;;;N;;;;;\n10B0A;AVESTAN LETTER O;Lo;0;R;;;;;N;;;;;\n10B0B;AVESTAN LETTER OO;Lo;0;R;;;;;N;;;;;\n10B0C;AVESTAN LETTER I;Lo;0;R;;;;;N;;;;;\n10B0D;AVESTAN LETTER II;Lo;0;R;;;;;N;;;;;\n10B0E;AVESTAN LETTER U;Lo;0;R;;;;;N;;;;;\n10B0F;AVESTAN LETTER UU;Lo;0;R;;;;;N;;;;;\n10B10;AVESTAN LETTER KE;Lo;0;R;;;;;N;;;;;\n10B11;AVESTAN LETTER XE;Lo;0;R;;;;;N;;;;;\n10B12;AVESTAN LETTER XYE;Lo;0;R;;;;;N;;;;;\n10B13;AVESTAN LETTER XVE;Lo;0;R;;;;;N;;;;;\n10B14;AVESTAN LETTER GE;Lo;0;R;;;;;N;;;;;\n10B15;AVESTAN LETTER GGE;Lo;0;R;;;;;N;;;;;\n10B16;AVESTAN LETTER GHE;Lo;0;R;;;;;N;;;;;\n10B17;AVESTAN LETTER CE;Lo;0;R;;;;;N;;;;;\n10B18;AVESTAN LETTER JE;Lo;0;R;;;;;N;;;;;\n10B19;AVESTAN LETTER TE;Lo;0;R;;;;;N;;;;;\n10B1A;AVESTAN LETTER THE;Lo;0;R;;;;;N;;;;;\n10B1B;AVESTAN LETTER DE;Lo;0;R;;;;;N;;;;;\n10B1C;AVESTAN LETTER DHE;Lo;0;R;;;;;N;;;;;\n10B1D;AVESTAN LETTER TTE;Lo;0;R;;;;;N;;;;;\n10B1E;AVESTAN LETTER PE;Lo;0;R;;;;;N;;;;;\n10B1F;AVESTAN LETTER FE;Lo;0;R;;;;;N;;;;;\n10B20;AVESTAN LETTER BE;Lo;0;R;;;;;N;;;;;\n10B21;AVESTAN LETTER BHE;Lo;0;R;;;;;N;;;;;\n10B22;AVESTAN LETTER NGE;Lo;0;R;;;;;N;;;;;\n10B23;AVESTAN LETTER NGYE;Lo;0;R;;;;;N;;;;;\n10B24;AVESTAN LETTER NGVE;Lo;0;R;;;;;N;;;;;\n10B25;AVESTAN LETTER NE;Lo;0;R;;;;;N;;;;;\n10B26;AVESTAN LETTER NYE;Lo;0;R;;;;;N;;;;;\n10B27;AVESTAN LETTER NNE;Lo;0;R;;;;;N;;;;;\n10B28;AVESTAN LETTER ME;Lo;0;R;;;;;N;;;;;\n10B29;AVESTAN LETTER HME;Lo;0;R;;;;;N;;;;;\n10B2A;AVESTAN LETTER YYE;Lo;0;R;;;;;N;;;;;\n10B2B;AVESTAN LETTER YE;Lo;0;R;;;;;N;;;;;\n10B2C;AVESTAN LETTER VE;Lo;0;R;;;;;N;;;;;\n10B2D;AVESTAN LETTER RE;Lo;0;R;;;;;N;;;;;\n10B2E;AVESTAN LETTER LE;Lo;0;R;;;;;N;;;;;\n10B2F;AVESTAN LETTER SE;Lo;0;R;;;;;N;;;;;\n10B30;AVESTAN LETTER ZE;Lo;0;R;;;;;N;;;;;\n10B31;AVESTAN LETTER SHE;Lo;0;R;;;;;N;;;;;\n10B32;AVESTAN LETTER ZHE;Lo;0;R;;;;;N;;;;;\n10B33;AVESTAN LETTER SHYE;Lo;0;R;;;;;N;;;;;\n10B34;AVESTAN LETTER SSHE;Lo;0;R;;;;;N;;;;;\n10B35;AVESTAN LETTER HE;Lo;0;R;;;;;N;;;;;\n10B39;AVESTAN ABBREVIATION MARK;Po;0;ON;;;;;N;;;;;\n10B3A;TINY TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;\n10B3B;SMALL TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;\n10B3C;LARGE TWO DOTS OVER ONE DOT PUNCTUATION;Po;0;ON;;;;;N;;;;;\n10B3D;LARGE ONE DOT OVER TWO DOTS PUNCTUATION;Po;0;ON;;;;;N;;;;;\n10B3E;LARGE TWO RINGS OVER ONE RING PUNCTUATION;Po;0;ON;;;;;N;;;;;\n10B3F;LARGE ONE RING OVER TWO RINGS PUNCTUATION;Po;0;ON;;;;;N;;;;;\n10B40;INSCRIPTIONAL PARTHIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;\n10B41;INSCRIPTIONAL PARTHIAN LETTER BETH;Lo;0;R;;;;;N;;;;;\n10B42;INSCRIPTIONAL PARTHIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;\n10B43;INSCRIPTIONAL PARTHIAN LETTER DALETH;Lo;0;R;;;;;N;;;;;\n10B44;INSCRIPTIONAL PARTHIAN LETTER HE;Lo;0;R;;;;;N;;;;;\n10B45;INSCRIPTIONAL PARTHIAN LETTER WAW;Lo;0;R;;;;;N;;;;;\n10B46;INSCRIPTIONAL PARTHIAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;;\n10B47;INSCRIPTIONAL PARTHIAN LETTER HETH;Lo;0;R;;;;;N;;;;;\n10B48;INSCRIPTIONAL PARTHIAN LETTER TETH;Lo;0;R;;;;;N;;;;;\n10B49;INSCRIPTIONAL PARTHIAN LETTER YODH;Lo;0;R;;;;;N;;;;;\n10B4A;INSCRIPTIONAL PARTHIAN LETTER KAPH;Lo;0;R;;;;;N;;;;;\n10B4B;INSCRIPTIONAL PARTHIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;\n10B4C;INSCRIPTIONAL PARTHIAN LETTER MEM;Lo;0;R;;;;;N;;;;;\n10B4D;INSCRIPTIONAL PARTHIAN LETTER NUN;Lo;0;R;;;;;N;;;;;\n10B4E;INSCRIPTIONAL PARTHIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;\n10B4F;INSCRIPTIONAL PARTHIAN LETTER AYIN;Lo;0;R;;;;;N;;;;;\n10B50;INSCRIPTIONAL PARTHIAN LETTER PE;Lo;0;R;;;;;N;;;;;\n10B51;INSCRIPTIONAL PARTHIAN LETTER SADHE;Lo;0;R;;;;;N;;;;;\n10B52;INSCRIPTIONAL PARTHIAN LETTER QOPH;Lo;0;R;;;;;N;;;;;\n10B53;INSCRIPTIONAL PARTHIAN LETTER RESH;Lo;0;R;;;;;N;;;;;\n10B54;INSCRIPTIONAL PARTHIAN LETTER SHIN;Lo;0;R;;;;;N;;;;;\n10B55;INSCRIPTIONAL PARTHIAN LETTER TAW;Lo;0;R;;;;;N;;;;;\n10B58;INSCRIPTIONAL PARTHIAN NUMBER ONE;No;0;R;;;;1;N;;;;;\n10B59;INSCRIPTIONAL PARTHIAN NUMBER TWO;No;0;R;;;;2;N;;;;;\n10B5A;INSCRIPTIONAL PARTHIAN NUMBER THREE;No;0;R;;;;3;N;;;;;\n10B5B;INSCRIPTIONAL PARTHIAN NUMBER FOUR;No;0;R;;;;4;N;;;;;\n10B5C;INSCRIPTIONAL PARTHIAN NUMBER TEN;No;0;R;;;;10;N;;;;;\n10B5D;INSCRIPTIONAL PARTHIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;\n10B5E;INSCRIPTIONAL PARTHIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;\n10B5F;INSCRIPTIONAL PARTHIAN NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;\n10B60;INSCRIPTIONAL PAHLAVI LETTER ALEPH;Lo;0;R;;;;;N;;;;;\n10B61;INSCRIPTIONAL PAHLAVI LETTER BETH;Lo;0;R;;;;;N;;;;;\n10B62;INSCRIPTIONAL PAHLAVI LETTER GIMEL;Lo;0;R;;;;;N;;;;;\n10B63;INSCRIPTIONAL PAHLAVI LETTER DALETH;Lo;0;R;;;;;N;;;;;\n10B64;INSCRIPTIONAL PAHLAVI LETTER HE;Lo;0;R;;;;;N;;;;;\n10B65;INSCRIPTIONAL PAHLAVI LETTER WAW-AYIN-RESH;Lo;0;R;;;;;N;;;;;\n10B66;INSCRIPTIONAL PAHLAVI LETTER ZAYIN;Lo;0;R;;;;;N;;;;;\n10B67;INSCRIPTIONAL PAHLAVI LETTER HETH;Lo;0;R;;;;;N;;;;;\n10B68;INSCRIPTIONAL PAHLAVI LETTER TETH;Lo;0;R;;;;;N;;;;;\n10B69;INSCRIPTIONAL PAHLAVI LETTER YODH;Lo;0;R;;;;;N;;;;;\n10B6A;INSCRIPTIONAL PAHLAVI LETTER KAPH;Lo;0;R;;;;;N;;;;;\n10B6B;INSCRIPTIONAL PAHLAVI LETTER LAMEDH;Lo;0;R;;;;;N;;;;;\n10B6C;INSCRIPTIONAL PAHLAVI LETTER MEM-QOPH;Lo;0;R;;;;;N;;;;;\n10B6D;INSCRIPTIONAL PAHLAVI LETTER NUN;Lo;0;R;;;;;N;;;;;\n10B6E;INSCRIPTIONAL PAHLAVI LETTER SAMEKH;Lo;0;R;;;;;N;;;;;\n10B6F;INSCRIPTIONAL PAHLAVI LETTER PE;Lo;0;R;;;;;N;;;;;\n10B70;INSCRIPTIONAL PAHLAVI LETTER SADHE;Lo;0;R;;;;;N;;;;;\n10B71;INSCRIPTIONAL PAHLAVI LETTER SHIN;Lo;0;R;;;;;N;;;;;\n10B72;INSCRIPTIONAL PAHLAVI LETTER TAW;Lo;0;R;;;;;N;;;;;\n10B78;INSCRIPTIONAL PAHLAVI NUMBER ONE;No;0;R;;;;1;N;;;;;\n10B79;INSCRIPTIONAL PAHLAVI NUMBER TWO;No;0;R;;;;2;N;;;;;\n10B7A;INSCRIPTIONAL PAHLAVI NUMBER THREE;No;0;R;;;;3;N;;;;;\n10B7B;INSCRIPTIONAL PAHLAVI NUMBER FOUR;No;0;R;;;;4;N;;;;;\n10B7C;INSCRIPTIONAL PAHLAVI NUMBER TEN;No;0;R;;;;10;N;;;;;\n10B7D;INSCRIPTIONAL PAHLAVI NUMBER TWENTY;No;0;R;;;;20;N;;;;;\n10B7E;INSCRIPTIONAL PAHLAVI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;\n10B7F;INSCRIPTIONAL PAHLAVI NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;\n10B80;PSALTER PAHLAVI LETTER ALEPH;Lo;0;R;;;;;N;;;;;\n10B81;PSALTER PAHLAVI LETTER BETH;Lo;0;R;;;;;N;;;;;\n10B82;PSALTER PAHLAVI LETTER GIMEL;Lo;0;R;;;;;N;;;;;\n10B83;PSALTER PAHLAVI LETTER DALETH;Lo;0;R;;;;;N;;;;;\n10B84;PSALTER PAHLAVI LETTER HE;Lo;0;R;;;;;N;;;;;\n10B85;PSALTER PAHLAVI LETTER WAW-AYIN-RESH;Lo;0;R;;;;;N;;;;;\n10B86;PSALTER PAHLAVI LETTER ZAYIN;Lo;0;R;;;;;N;;;;;\n10B87;PSALTER PAHLAVI LETTER HETH;Lo;0;R;;;;;N;;;;;\n10B88;PSALTER PAHLAVI LETTER YODH;Lo;0;R;;;;;N;;;;;\n10B89;PSALTER PAHLAVI LETTER KAPH;Lo;0;R;;;;;N;;;;;\n10B8A;PSALTER PAHLAVI LETTER LAMEDH;Lo;0;R;;;;;N;;;;;\n10B8B;PSALTER PAHLAVI LETTER MEM-QOPH;Lo;0;R;;;;;N;;;;;\n10B8C;PSALTER PAHLAVI LETTER NUN;Lo;0;R;;;;;N;;;;;\n10B8D;PSALTER PAHLAVI LETTER SAMEKH;Lo;0;R;;;;;N;;;;;\n10B8E;PSALTER PAHLAVI LETTER PE;Lo;0;R;;;;;N;;;;;\n10B8F;PSALTER PAHLAVI LETTER SADHE;Lo;0;R;;;;;N;;;;;\n10B90;PSALTER PAHLAVI LETTER SHIN;Lo;0;R;;;;;N;;;;;\n10B91;PSALTER PAHLAVI LETTER TAW;Lo;0;R;;;;;N;;;;;\n10B99;PSALTER PAHLAVI SECTION MARK;Po;0;R;;;;;N;;;;;\n10B9A;PSALTER PAHLAVI TURNED SECTION MARK;Po;0;R;;;;;N;;;;;\n10B9B;PSALTER PAHLAVI FOUR DOTS WITH CROSS;Po;0;R;;;;;N;;;;;\n10B9C;PSALTER PAHLAVI FOUR DOTS WITH DOT;Po;0;R;;;;;N;;;;;\n10BA9;PSALTER PAHLAVI NUMBER ONE;No;0;R;;;;1;N;;;;;\n10BAA;PSALTER PAHLAVI NUMBER TWO;No;0;R;;;;2;N;;;;;\n10BAB;PSALTER PAHLAVI NUMBER THREE;No;0;R;;;;3;N;;;;;\n10BAC;PSALTER PAHLAVI NUMBER FOUR;No;0;R;;;;4;N;;;;;\n10BAD;PSALTER PAHLAVI NUMBER TEN;No;0;R;;;;10;N;;;;;\n10BAE;PSALTER PAHLAVI NUMBER TWENTY;No;0;R;;;;20;N;;;;;\n10BAF;PSALTER PAHLAVI NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;\n10C00;OLD TURKIC LETTER ORKHON A;Lo;0;R;;;;;N;;;;;\n10C01;OLD TURKIC LETTER YENISEI A;Lo;0;R;;;;;N;;;;;\n10C02;OLD TURKIC LETTER YENISEI AE;Lo;0;R;;;;;N;;;;;\n10C03;OLD TURKIC LETTER ORKHON I;Lo;0;R;;;;;N;;;;;\n10C04;OLD TURKIC LETTER YENISEI I;Lo;0;R;;;;;N;;;;;\n10C05;OLD TURKIC LETTER YENISEI E;Lo;0;R;;;;;N;;;;;\n10C06;OLD TURKIC LETTER ORKHON O;Lo;0;R;;;;;N;;;;;\n10C07;OLD TURKIC LETTER ORKHON OE;Lo;0;R;;;;;N;;;;;\n10C08;OLD TURKIC LETTER YENISEI OE;Lo;0;R;;;;;N;;;;;\n10C09;OLD TURKIC LETTER ORKHON AB;Lo;0;R;;;;;N;;;;;\n10C0A;OLD TURKIC LETTER YENISEI AB;Lo;0;R;;;;;N;;;;;\n10C0B;OLD TURKIC LETTER ORKHON AEB;Lo;0;R;;;;;N;;;;;\n10C0C;OLD TURKIC LETTER YENISEI AEB;Lo;0;R;;;;;N;;;;;\n10C0D;OLD TURKIC LETTER ORKHON AG;Lo;0;R;;;;;N;;;;;\n10C0E;OLD TURKIC LETTER YENISEI AG;Lo;0;R;;;;;N;;;;;\n10C0F;OLD TURKIC LETTER ORKHON AEG;Lo;0;R;;;;;N;;;;;\n10C10;OLD TURKIC LETTER YENISEI AEG;Lo;0;R;;;;;N;;;;;\n10C11;OLD TURKIC LETTER ORKHON AD;Lo;0;R;;;;;N;;;;;\n10C12;OLD TURKIC LETTER YENISEI AD;Lo;0;R;;;;;N;;;;;\n10C13;OLD TURKIC LETTER ORKHON AED;Lo;0;R;;;;;N;;;;;\n10C14;OLD TURKIC LETTER ORKHON EZ;Lo;0;R;;;;;N;;;;;\n10C15;OLD TURKIC LETTER YENISEI EZ;Lo;0;R;;;;;N;;;;;\n10C16;OLD TURKIC LETTER ORKHON AY;Lo;0;R;;;;;N;;;;;\n10C17;OLD TURKIC LETTER YENISEI AY;Lo;0;R;;;;;N;;;;;\n10C18;OLD TURKIC LETTER ORKHON AEY;Lo;0;R;;;;;N;;;;;\n10C19;OLD TURKIC LETTER YENISEI AEY;Lo;0;R;;;;;N;;;;;\n10C1A;OLD TURKIC LETTER ORKHON AEK;Lo;0;R;;;;;N;;;;;\n10C1B;OLD TURKIC LETTER YENISEI AEK;Lo;0;R;;;;;N;;;;;\n10C1C;OLD TURKIC LETTER ORKHON OEK;Lo;0;R;;;;;N;;;;;\n10C1D;OLD TURKIC LETTER YENISEI OEK;Lo;0;R;;;;;N;;;;;\n10C1E;OLD TURKIC LETTER ORKHON AL;Lo;0;R;;;;;N;;;;;\n10C1F;OLD TURKIC LETTER YENISEI AL;Lo;0;R;;;;;N;;;;;\n10C20;OLD TURKIC LETTER ORKHON AEL;Lo;0;R;;;;;N;;;;;\n10C21;OLD TURKIC LETTER ORKHON ELT;Lo;0;R;;;;;N;;;;;\n10C22;OLD TURKIC LETTER ORKHON EM;Lo;0;R;;;;;N;;;;;\n10C23;OLD TURKIC LETTER ORKHON AN;Lo;0;R;;;;;N;;;;;\n10C24;OLD TURKIC LETTER ORKHON AEN;Lo;0;R;;;;;N;;;;;\n10C25;OLD TURKIC LETTER YENISEI AEN;Lo;0;R;;;;;N;;;;;\n10C26;OLD TURKIC LETTER ORKHON ENT;Lo;0;R;;;;;N;;;;;\n10C27;OLD TURKIC LETTER YENISEI ENT;Lo;0;R;;;;;N;;;;;\n10C28;OLD TURKIC LETTER ORKHON ENC;Lo;0;R;;;;;N;;;;;\n10C29;OLD TURKIC LETTER YENISEI ENC;Lo;0;R;;;;;N;;;;;\n10C2A;OLD TURKIC LETTER ORKHON ENY;Lo;0;R;;;;;N;;;;;\n10C2B;OLD TURKIC LETTER YENISEI ENY;Lo;0;R;;;;;N;;;;;\n10C2C;OLD TURKIC LETTER YENISEI ANG;Lo;0;R;;;;;N;;;;;\n10C2D;OLD TURKIC LETTER ORKHON ENG;Lo;0;R;;;;;N;;;;;\n10C2E;OLD TURKIC LETTER YENISEI AENG;Lo;0;R;;;;;N;;;;;\n10C2F;OLD TURKIC LETTER ORKHON EP;Lo;0;R;;;;;N;;;;;\n10C30;OLD TURKIC LETTER ORKHON OP;Lo;0;R;;;;;N;;;;;\n10C31;OLD TURKIC LETTER ORKHON IC;Lo;0;R;;;;;N;;;;;\n10C32;OLD TURKIC LETTER ORKHON EC;Lo;0;R;;;;;N;;;;;\n10C33;OLD TURKIC LETTER YENISEI EC;Lo;0;R;;;;;N;;;;;\n10C34;OLD TURKIC LETTER ORKHON AQ;Lo;0;R;;;;;N;;;;;\n10C35;OLD TURKIC LETTER YENISEI AQ;Lo;0;R;;;;;N;;;;;\n10C36;OLD TURKIC LETTER ORKHON IQ;Lo;0;R;;;;;N;;;;;\n10C37;OLD TURKIC LETTER YENISEI IQ;Lo;0;R;;;;;N;;;;;\n10C38;OLD TURKIC LETTER ORKHON OQ;Lo;0;R;;;;;N;;;;;\n10C39;OLD TURKIC LETTER YENISEI OQ;Lo;0;R;;;;;N;;;;;\n10C3A;OLD TURKIC LETTER ORKHON AR;Lo;0;R;;;;;N;;;;;\n10C3B;OLD TURKIC LETTER YENISEI AR;Lo;0;R;;;;;N;;;;;\n10C3C;OLD TURKIC LETTER ORKHON AER;Lo;0;R;;;;;N;;;;;\n10C3D;OLD TURKIC LETTER ORKHON AS;Lo;0;R;;;;;N;;;;;\n10C3E;OLD TURKIC LETTER ORKHON AES;Lo;0;R;;;;;N;;;;;\n10C3F;OLD TURKIC LETTER ORKHON ASH;Lo;0;R;;;;;N;;;;;\n10C40;OLD TURKIC LETTER YENISEI ASH;Lo;0;R;;;;;N;;;;;\n10C41;OLD TURKIC LETTER ORKHON ESH;Lo;0;R;;;;;N;;;;;\n10C42;OLD TURKIC LETTER YENISEI ESH;Lo;0;R;;;;;N;;;;;\n10C43;OLD TURKIC LETTER ORKHON AT;Lo;0;R;;;;;N;;;;;\n10C44;OLD TURKIC LETTER YENISEI AT;Lo;0;R;;;;;N;;;;;\n10C45;OLD TURKIC LETTER ORKHON AET;Lo;0;R;;;;;N;;;;;\n10C46;OLD TURKIC LETTER YENISEI AET;Lo;0;R;;;;;N;;;;;\n10C47;OLD TURKIC LETTER ORKHON OT;Lo;0;R;;;;;N;;;;;\n10C48;OLD TURKIC LETTER ORKHON BASH;Lo;0;R;;;;;N;;;;;\n10C80;OLD HUNGARIAN CAPITAL LETTER A;Lu;0;R;;;;;N;;;;10CC0;\n10C81;OLD HUNGARIAN CAPITAL LETTER AA;Lu;0;R;;;;;N;;;;10CC1;\n10C82;OLD HUNGARIAN CAPITAL LETTER EB;Lu;0;R;;;;;N;;;;10CC2;\n10C83;OLD HUNGARIAN CAPITAL LETTER AMB;Lu;0;R;;;;;N;;;;10CC3;\n10C84;OLD HUNGARIAN CAPITAL LETTER EC;Lu;0;R;;;;;N;;;;10CC4;\n10C85;OLD HUNGARIAN CAPITAL LETTER ENC;Lu;0;R;;;;;N;;;;10CC5;\n10C86;OLD HUNGARIAN CAPITAL LETTER ECS;Lu;0;R;;;;;N;;;;10CC6;\n10C87;OLD HUNGARIAN CAPITAL LETTER ED;Lu;0;R;;;;;N;;;;10CC7;\n10C88;OLD HUNGARIAN CAPITAL LETTER AND;Lu;0;R;;;;;N;;;;10CC8;\n10C89;OLD HUNGARIAN CAPITAL LETTER E;Lu;0;R;;;;;N;;;;10CC9;\n10C8A;OLD HUNGARIAN CAPITAL LETTER CLOSE E;Lu;0;R;;;;;N;;;;10CCA;\n10C8B;OLD HUNGARIAN CAPITAL LETTER EE;Lu;0;R;;;;;N;;;;10CCB;\n10C8C;OLD HUNGARIAN CAPITAL LETTER EF;Lu;0;R;;;;;N;;;;10CCC;\n10C8D;OLD HUNGARIAN CAPITAL LETTER EG;Lu;0;R;;;;;N;;;;10CCD;\n10C8E;OLD HUNGARIAN CAPITAL LETTER EGY;Lu;0;R;;;;;N;;;;10CCE;\n10C8F;OLD HUNGARIAN CAPITAL LETTER EH;Lu;0;R;;;;;N;;;;10CCF;\n10C90;OLD HUNGARIAN CAPITAL LETTER I;Lu;0;R;;;;;N;;;;10CD0;\n10C91;OLD HUNGARIAN CAPITAL LETTER II;Lu;0;R;;;;;N;;;;10CD1;\n10C92;OLD HUNGARIAN CAPITAL LETTER EJ;Lu;0;R;;;;;N;;;;10CD2;\n10C93;OLD HUNGARIAN CAPITAL LETTER EK;Lu;0;R;;;;;N;;;;10CD3;\n10C94;OLD HUNGARIAN CAPITAL LETTER AK;Lu;0;R;;;;;N;;;;10CD4;\n10C95;OLD HUNGARIAN CAPITAL LETTER UNK;Lu;0;R;;;;;N;;;;10CD5;\n10C96;OLD HUNGARIAN CAPITAL LETTER EL;Lu;0;R;;;;;N;;;;10CD6;\n10C97;OLD HUNGARIAN CAPITAL LETTER ELY;Lu;0;R;;;;;N;;;;10CD7;\n10C98;OLD HUNGARIAN CAPITAL LETTER EM;Lu;0;R;;;;;N;;;;10CD8;\n10C99;OLD HUNGARIAN CAPITAL LETTER EN;Lu;0;R;;;;;N;;;;10CD9;\n10C9A;OLD HUNGARIAN CAPITAL LETTER ENY;Lu;0;R;;;;;N;;;;10CDA;\n10C9B;OLD HUNGARIAN CAPITAL LETTER O;Lu;0;R;;;;;N;;;;10CDB;\n10C9C;OLD HUNGARIAN CAPITAL LETTER OO;Lu;0;R;;;;;N;;;;10CDC;\n10C9D;OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG OE;Lu;0;R;;;;;N;;;;10CDD;\n10C9E;OLD HUNGARIAN CAPITAL LETTER RUDIMENTA OE;Lu;0;R;;;;;N;;;;10CDE;\n10C9F;OLD HUNGARIAN CAPITAL LETTER OEE;Lu;0;R;;;;;N;;;;10CDF;\n10CA0;OLD HUNGARIAN CAPITAL LETTER EP;Lu;0;R;;;;;N;;;;10CE0;\n10CA1;OLD HUNGARIAN CAPITAL LETTER EMP;Lu;0;R;;;;;N;;;;10CE1;\n10CA2;OLD HUNGARIAN CAPITAL LETTER ER;Lu;0;R;;;;;N;;;;10CE2;\n10CA3;OLD HUNGARIAN CAPITAL LETTER SHORT ER;Lu;0;R;;;;;N;;;;10CE3;\n10CA4;OLD HUNGARIAN CAPITAL LETTER ES;Lu;0;R;;;;;N;;;;10CE4;\n10CA5;OLD HUNGARIAN CAPITAL LETTER ESZ;Lu;0;R;;;;;N;;;;10CE5;\n10CA6;OLD HUNGARIAN CAPITAL LETTER ET;Lu;0;R;;;;;N;;;;10CE6;\n10CA7;OLD HUNGARIAN CAPITAL LETTER ENT;Lu;0;R;;;;;N;;;;10CE7;\n10CA8;OLD HUNGARIAN CAPITAL LETTER ETY;Lu;0;R;;;;;N;;;;10CE8;\n10CA9;OLD HUNGARIAN CAPITAL LETTER ECH;Lu;0;R;;;;;N;;;;10CE9;\n10CAA;OLD HUNGARIAN CAPITAL LETTER U;Lu;0;R;;;;;N;;;;10CEA;\n10CAB;OLD HUNGARIAN CAPITAL LETTER UU;Lu;0;R;;;;;N;;;;10CEB;\n10CAC;OLD HUNGARIAN CAPITAL LETTER NIKOLSBURG UE;Lu;0;R;;;;;N;;;;10CEC;\n10CAD;OLD HUNGARIAN CAPITAL LETTER RUDIMENTA UE;Lu;0;R;;;;;N;;;;10CED;\n10CAE;OLD HUNGARIAN CAPITAL LETTER EV;Lu;0;R;;;;;N;;;;10CEE;\n10CAF;OLD HUNGARIAN CAPITAL LETTER EZ;Lu;0;R;;;;;N;;;;10CEF;\n10CB0;OLD HUNGARIAN CAPITAL LETTER EZS;Lu;0;R;;;;;N;;;;10CF0;\n10CB1;OLD HUNGARIAN CAPITAL LETTER ENT-SHAPED SIGN;Lu;0;R;;;;;N;;;;10CF1;\n10CB2;OLD HUNGARIAN CAPITAL LETTER US;Lu;0;R;;;;;N;;;;10CF2;\n10CC0;OLD HUNGARIAN SMALL LETTER A;Ll;0;R;;;;;N;;;10C80;;10C80\n10CC1;OLD HUNGARIAN SMALL LETTER AA;Ll;0;R;;;;;N;;;10C81;;10C81\n10CC2;OLD HUNGARIAN SMALL LETTER EB;Ll;0;R;;;;;N;;;10C82;;10C82\n10CC3;OLD HUNGARIAN SMALL LETTER AMB;Ll;0;R;;;;;N;;;10C83;;10C83\n10CC4;OLD HUNGARIAN SMALL LETTER EC;Ll;0;R;;;;;N;;;10C84;;10C84\n10CC5;OLD HUNGARIAN SMALL LETTER ENC;Ll;0;R;;;;;N;;;10C85;;10C85\n10CC6;OLD HUNGARIAN SMALL LETTER ECS;Ll;0;R;;;;;N;;;10C86;;10C86\n10CC7;OLD HUNGARIAN SMALL LETTER ED;Ll;0;R;;;;;N;;;10C87;;10C87\n10CC8;OLD HUNGARIAN SMALL LETTER AND;Ll;0;R;;;;;N;;;10C88;;10C88\n10CC9;OLD HUNGARIAN SMALL LETTER E;Ll;0;R;;;;;N;;;10C89;;10C89\n10CCA;OLD HUNGARIAN SMALL LETTER CLOSE E;Ll;0;R;;;;;N;;;10C8A;;10C8A\n10CCB;OLD HUNGARIAN SMALL LETTER EE;Ll;0;R;;;;;N;;;10C8B;;10C8B\n10CCC;OLD HUNGARIAN SMALL LETTER EF;Ll;0;R;;;;;N;;;10C8C;;10C8C\n10CCD;OLD HUNGARIAN SMALL LETTER EG;Ll;0;R;;;;;N;;;10C8D;;10C8D\n10CCE;OLD HUNGARIAN SMALL LETTER EGY;Ll;0;R;;;;;N;;;10C8E;;10C8E\n10CCF;OLD HUNGARIAN SMALL LETTER EH;Ll;0;R;;;;;N;;;10C8F;;10C8F\n10CD0;OLD HUNGARIAN SMALL LETTER I;Ll;0;R;;;;;N;;;10C90;;10C90\n10CD1;OLD HUNGARIAN SMALL LETTER II;Ll;0;R;;;;;N;;;10C91;;10C91\n10CD2;OLD HUNGARIAN SMALL LETTER EJ;Ll;0;R;;;;;N;;;10C92;;10C92\n10CD3;OLD HUNGARIAN SMALL LETTER EK;Ll;0;R;;;;;N;;;10C93;;10C93\n10CD4;OLD HUNGARIAN SMALL LETTER AK;Ll;0;R;;;;;N;;;10C94;;10C94\n10CD5;OLD HUNGARIAN SMALL LETTER UNK;Ll;0;R;;;;;N;;;10C95;;10C95\n10CD6;OLD HUNGARIAN SMALL LETTER EL;Ll;0;R;;;;;N;;;10C96;;10C96\n10CD7;OLD HUNGARIAN SMALL LETTER ELY;Ll;0;R;;;;;N;;;10C97;;10C97\n10CD8;OLD HUNGARIAN SMALL LETTER EM;Ll;0;R;;;;;N;;;10C98;;10C98\n10CD9;OLD HUNGARIAN SMALL LETTER EN;Ll;0;R;;;;;N;;;10C99;;10C99\n10CDA;OLD HUNGARIAN SMALL LETTER ENY;Ll;0;R;;;;;N;;;10C9A;;10C9A\n10CDB;OLD HUNGARIAN SMALL LETTER O;Ll;0;R;;;;;N;;;10C9B;;10C9B\n10CDC;OLD HUNGARIAN SMALL LETTER OO;Ll;0;R;;;;;N;;;10C9C;;10C9C\n10CDD;OLD HUNGARIAN SMALL LETTER NIKOLSBURG OE;Ll;0;R;;;;;N;;;10C9D;;10C9D\n10CDE;OLD HUNGARIAN SMALL LETTER RUDIMENTA OE;Ll;0;R;;;;;N;;;10C9E;;10C9E\n10CDF;OLD HUNGARIAN SMALL LETTER OEE;Ll;0;R;;;;;N;;;10C9F;;10C9F\n10CE0;OLD HUNGARIAN SMALL LETTER EP;Ll;0;R;;;;;N;;;10CA0;;10CA0\n10CE1;OLD HUNGARIAN SMALL LETTER EMP;Ll;0;R;;;;;N;;;10CA1;;10CA1\n10CE2;OLD HUNGARIAN SMALL LETTER ER;Ll;0;R;;;;;N;;;10CA2;;10CA2\n10CE3;OLD HUNGARIAN SMALL LETTER SHORT ER;Ll;0;R;;;;;N;;;10CA3;;10CA3\n10CE4;OLD HUNGARIAN SMALL LETTER ES;Ll;0;R;;;;;N;;;10CA4;;10CA4\n10CE5;OLD HUNGARIAN SMALL LETTER ESZ;Ll;0;R;;;;;N;;;10CA5;;10CA5\n10CE6;OLD HUNGARIAN SMALL LETTER ET;Ll;0;R;;;;;N;;;10CA6;;10CA6\n10CE7;OLD HUNGARIAN SMALL LETTER ENT;Ll;0;R;;;;;N;;;10CA7;;10CA7\n10CE8;OLD HUNGARIAN SMALL LETTER ETY;Ll;0;R;;;;;N;;;10CA8;;10CA8\n10CE9;OLD HUNGARIAN SMALL LETTER ECH;Ll;0;R;;;;;N;;;10CA9;;10CA9\n10CEA;OLD HUNGARIAN SMALL LETTER U;Ll;0;R;;;;;N;;;10CAA;;10CAA\n10CEB;OLD HUNGARIAN SMALL LETTER UU;Ll;0;R;;;;;N;;;10CAB;;10CAB\n10CEC;OLD HUNGARIAN SMALL LETTER NIKOLSBURG UE;Ll;0;R;;;;;N;;;10CAC;;10CAC\n10CED;OLD HUNGARIAN SMALL LETTER RUDIMENTA UE;Ll;0;R;;;;;N;;;10CAD;;10CAD\n10CEE;OLD HUNGARIAN SMALL LETTER EV;Ll;0;R;;;;;N;;;10CAE;;10CAE\n10CEF;OLD HUNGARIAN SMALL LETTER EZ;Ll;0;R;;;;;N;;;10CAF;;10CAF\n10CF0;OLD HUNGARIAN SMALL LETTER EZS;Ll;0;R;;;;;N;;;10CB0;;10CB0\n10CF1;OLD HUNGARIAN SMALL LETTER ENT-SHAPED SIGN;Ll;0;R;;;;;N;;;10CB1;;10CB1\n10CF2;OLD HUNGARIAN SMALL LETTER US;Ll;0;R;;;;;N;;;10CB2;;10CB2\n10CFA;OLD HUNGARIAN NUMBER ONE;No;0;R;;;;1;N;;;;;\n10CFB;OLD HUNGARIAN NUMBER FIVE;No;0;R;;;;5;N;;;;;\n10CFC;OLD HUNGARIAN NUMBER TEN;No;0;R;;;;10;N;;;;;\n10CFD;OLD HUNGARIAN NUMBER FIFTY;No;0;R;;;;50;N;;;;;\n10CFE;OLD HUNGARIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;\n10CFF;OLD HUNGARIAN NUMBER ONE THOUSAND;No;0;R;;;;1000;N;;;;;\n10D00;HANIFI ROHINGYA LETTER A;Lo;0;AL;;;;;N;;;;;\n10D01;HANIFI ROHINGYA LETTER BA;Lo;0;AL;;;;;N;;;;;\n10D02;HANIFI ROHINGYA LETTER PA;Lo;0;AL;;;;;N;;;;;\n10D03;HANIFI ROHINGYA LETTER TA;Lo;0;AL;;;;;N;;;;;\n10D04;HANIFI ROHINGYA LETTER TTA;Lo;0;AL;;;;;N;;;;;\n10D05;HANIFI ROHINGYA LETTER JA;Lo;0;AL;;;;;N;;;;;\n10D06;HANIFI ROHINGYA LETTER CA;Lo;0;AL;;;;;N;;;;;\n10D07;HANIFI ROHINGYA LETTER HA;Lo;0;AL;;;;;N;;;;;\n10D08;HANIFI ROHINGYA LETTER KHA;Lo;0;AL;;;;;N;;;;;\n10D09;HANIFI ROHINGYA LETTER FA;Lo;0;AL;;;;;N;;;;;\n10D0A;HANIFI ROHINGYA LETTER DA;Lo;0;AL;;;;;N;;;;;\n10D0B;HANIFI ROHINGYA LETTER DDA;Lo;0;AL;;;;;N;;;;;\n10D0C;HANIFI ROHINGYA LETTER RA;Lo;0;AL;;;;;N;;;;;\n10D0D;HANIFI ROHINGYA LETTER RRA;Lo;0;AL;;;;;N;;;;;\n10D0E;HANIFI ROHINGYA LETTER ZA;Lo;0;AL;;;;;N;;;;;\n10D0F;HANIFI ROHINGYA LETTER SA;Lo;0;AL;;;;;N;;;;;\n10D10;HANIFI ROHINGYA LETTER SHA;Lo;0;AL;;;;;N;;;;;\n10D11;HANIFI ROHINGYA LETTER KA;Lo;0;AL;;;;;N;;;;;\n10D12;HANIFI ROHINGYA LETTER GA;Lo;0;AL;;;;;N;;;;;\n10D13;HANIFI ROHINGYA LETTER LA;Lo;0;AL;;;;;N;;;;;\n10D14;HANIFI ROHINGYA LETTER MA;Lo;0;AL;;;;;N;;;;;\n10D15;HANIFI ROHINGYA LETTER NA;Lo;0;AL;;;;;N;;;;;\n10D16;HANIFI ROHINGYA LETTER WA;Lo;0;AL;;;;;N;;;;;\n10D17;HANIFI ROHINGYA LETTER KINNA WA;Lo;0;AL;;;;;N;;;;;\n10D18;HANIFI ROHINGYA LETTER YA;Lo;0;AL;;;;;N;;;;;\n10D19;HANIFI ROHINGYA LETTER KINNA YA;Lo;0;AL;;;;;N;;;;;\n10D1A;HANIFI ROHINGYA LETTER NGA;Lo;0;AL;;;;;N;;;;;\n10D1B;HANIFI ROHINGYA LETTER NYA;Lo;0;AL;;;;;N;;;;;\n10D1C;HANIFI ROHINGYA LETTER VA;Lo;0;AL;;;;;N;;;;;\n10D1D;HANIFI ROHINGYA VOWEL A;Lo;0;AL;;;;;N;;;;;\n10D1E;HANIFI ROHINGYA VOWEL I;Lo;0;AL;;;;;N;;;;;\n10D1F;HANIFI ROHINGYA VOWEL U;Lo;0;AL;;;;;N;;;;;\n10D20;HANIFI ROHINGYA VOWEL E;Lo;0;AL;;;;;N;;;;;\n10D21;HANIFI ROHINGYA VOWEL O;Lo;0;AL;;;;;N;;;;;\n10D22;HANIFI ROHINGYA MARK SAKIN;Lo;0;AL;;;;;N;;;;;\n10D23;HANIFI ROHINGYA MARK NA KHONNA;Lo;0;AL;;;;;N;;;;;\n10D24;HANIFI ROHINGYA SIGN HARBAHAY;Mn;230;NSM;;;;;N;;;;;\n10D25;HANIFI ROHINGYA SIGN TAHALA;Mn;230;NSM;;;;;N;;;;;\n10D26;HANIFI ROHINGYA SIGN TANA;Mn;230;NSM;;;;;N;;;;;\n10D27;HANIFI ROHINGYA SIGN TASSI;Mn;230;NSM;;;;;N;;;;;\n10D30;HANIFI ROHINGYA DIGIT ZERO;Nd;0;AN;;0;0;0;N;;;;;\n10D31;HANIFI ROHINGYA DIGIT ONE;Nd;0;AN;;1;1;1;N;;;;;\n10D32;HANIFI ROHINGYA DIGIT TWO;Nd;0;AN;;2;2;2;N;;;;;\n10D33;HANIFI ROHINGYA DIGIT THREE;Nd;0;AN;;3;3;3;N;;;;;\n10D34;HANIFI ROHINGYA DIGIT FOUR;Nd;0;AN;;4;4;4;N;;;;;\n10D35;HANIFI ROHINGYA DIGIT FIVE;Nd;0;AN;;5;5;5;N;;;;;\n10D36;HANIFI ROHINGYA DIGIT SIX;Nd;0;AN;;6;6;6;N;;;;;\n10D37;HANIFI ROHINGYA DIGIT SEVEN;Nd;0;AN;;7;7;7;N;;;;;\n10D38;HANIFI ROHINGYA DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;;\n10D39;HANIFI ROHINGYA DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;;\n10E60;RUMI DIGIT ONE;No;0;AN;;;1;1;N;;;;;\n10E61;RUMI DIGIT TWO;No;0;AN;;;2;2;N;;;;;\n10E62;RUMI DIGIT THREE;No;0;AN;;;3;3;N;;;;;\n10E63;RUMI DIGIT FOUR;No;0;AN;;;4;4;N;;;;;\n10E64;RUMI DIGIT FIVE;No;0;AN;;;5;5;N;;;;;\n10E65;RUMI DIGIT SIX;No;0;AN;;;6;6;N;;;;;\n10E66;RUMI DIGIT SEVEN;No;0;AN;;;7;7;N;;;;;\n10E67;RUMI DIGIT EIGHT;No;0;AN;;;8;8;N;;;;;\n10E68;RUMI DIGIT NINE;No;0;AN;;;9;9;N;;;;;\n10E69;RUMI NUMBER TEN;No;0;AN;;;;10;N;;;;;\n10E6A;RUMI NUMBER TWENTY;No;0;AN;;;;20;N;;;;;\n10E6B;RUMI NUMBER THIRTY;No;0;AN;;;;30;N;;;;;\n10E6C;RUMI NUMBER FORTY;No;0;AN;;;;40;N;;;;;\n10E6D;RUMI NUMBER FIFTY;No;0;AN;;;;50;N;;;;;\n10E6E;RUMI NUMBER SIXTY;No;0;AN;;;;60;N;;;;;\n10E6F;RUMI NUMBER SEVENTY;No;0;AN;;;;70;N;;;;;\n10E70;RUMI NUMBER EIGHTY;No;0;AN;;;;80;N;;;;;\n10E71;RUMI NUMBER NINETY;No;0;AN;;;;90;N;;;;;\n10E72;RUMI NUMBER ONE HUNDRED;No;0;AN;;;;100;N;;;;;\n10E73;RUMI NUMBER TWO HUNDRED;No;0;AN;;;;200;N;;;;;\n10E74;RUMI NUMBER THREE HUNDRED;No;0;AN;;;;300;N;;;;;\n10E75;RUMI NUMBER FOUR HUNDRED;No;0;AN;;;;400;N;;;;;\n10E76;RUMI NUMBER FIVE HUNDRED;No;0;AN;;;;500;N;;;;;\n10E77;RUMI NUMBER SIX HUNDRED;No;0;AN;;;;600;N;;;;;\n10E78;RUMI NUMBER SEVEN HUNDRED;No;0;AN;;;;700;N;;;;;\n10E79;RUMI NUMBER EIGHT HUNDRED;No;0;AN;;;;800;N;;;;;\n10E7A;RUMI NUMBER NINE HUNDRED;No;0;AN;;;;900;N;;;;;\n10E7B;RUMI FRACTION ONE HALF;No;0;AN;;;;1/2;N;;;;;\n10E7C;RUMI FRACTION ONE QUARTER;No;0;AN;;;;1/4;N;;;;;\n10E7D;RUMI FRACTION ONE THIRD;No;0;AN;;;;1/3;N;;;;;\n10E7E;RUMI FRACTION TWO THIRDS;No;0;AN;;;;2/3;N;;;;;\n10F00;OLD SOGDIAN LETTER ALEPH;Lo;0;R;;;;;N;;;;;\n10F01;OLD SOGDIAN LETTER FINAL ALEPH;Lo;0;R;;;;;N;;;;;\n10F02;OLD SOGDIAN LETTER BETH;Lo;0;R;;;;;N;;;;;\n10F03;OLD SOGDIAN LETTER FINAL BETH;Lo;0;R;;;;;N;;;;;\n10F04;OLD SOGDIAN LETTER GIMEL;Lo;0;R;;;;;N;;;;;\n10F05;OLD SOGDIAN LETTER HE;Lo;0;R;;;;;N;;;;;\n10F06;OLD SOGDIAN LETTER FINAL HE;Lo;0;R;;;;;N;;;;;\n10F07;OLD SOGDIAN LETTER WAW;Lo;0;R;;;;;N;;;;;\n10F08;OLD SOGDIAN LETTER ZAYIN;Lo;0;R;;;;;N;;;;;\n10F09;OLD SOGDIAN LETTER HETH;Lo;0;R;;;;;N;;;;;\n10F0A;OLD SOGDIAN LETTER YODH;Lo;0;R;;;;;N;;;;;\n10F0B;OLD SOGDIAN LETTER KAPH;Lo;0;R;;;;;N;;;;;\n10F0C;OLD SOGDIAN LETTER LAMEDH;Lo;0;R;;;;;N;;;;;\n10F0D;OLD SOGDIAN LETTER MEM;Lo;0;R;;;;;N;;;;;\n10F0E;OLD SOGDIAN LETTER NUN;Lo;0;R;;;;;N;;;;;\n10F0F;OLD SOGDIAN LETTER FINAL NUN;Lo;0;R;;;;;N;;;;;\n10F10;OLD SOGDIAN LETTER FINAL NUN WITH VERTICAL TAIL;Lo;0;R;;;;;N;;;;;\n10F11;OLD SOGDIAN LETTER SAMEKH;Lo;0;R;;;;;N;;;;;\n10F12;OLD SOGDIAN LETTER AYIN;Lo;0;R;;;;;N;;;;;\n10F13;OLD SOGDIAN LETTER ALTERNATE AYIN;Lo;0;R;;;;;N;;;;;\n10F14;OLD SOGDIAN LETTER PE;Lo;0;R;;;;;N;;;;;\n10F15;OLD SOGDIAN LETTER SADHE;Lo;0;R;;;;;N;;;;;\n10F16;OLD SOGDIAN LETTER FINAL SADHE;Lo;0;R;;;;;N;;;;;\n10F17;OLD SOGDIAN LETTER FINAL SADHE WITH VERTICAL TAIL;Lo;0;R;;;;;N;;;;;\n10F18;OLD SOGDIAN LETTER RESH-AYIN-DALETH;Lo;0;R;;;;;N;;;;;\n10F19;OLD SOGDIAN LETTER SHIN;Lo;0;R;;;;;N;;;;;\n10F1A;OLD SOGDIAN LETTER TAW;Lo;0;R;;;;;N;;;;;\n10F1B;OLD SOGDIAN LETTER FINAL TAW;Lo;0;R;;;;;N;;;;;\n10F1C;OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL;Lo;0;R;;;;;N;;;;;\n10F1D;OLD SOGDIAN NUMBER ONE;No;0;R;;;;1;N;;;;;\n10F1E;OLD SOGDIAN NUMBER TWO;No;0;R;;;;2;N;;;;;\n10F1F;OLD SOGDIAN NUMBER THREE;No;0;R;;;;3;N;;;;;\n10F20;OLD SOGDIAN NUMBER FOUR;No;0;R;;;;4;N;;;;;\n10F21;OLD SOGDIAN NUMBER FIVE;No;0;R;;;;5;N;;;;;\n10F22;OLD SOGDIAN NUMBER TEN;No;0;R;;;;10;N;;;;;\n10F23;OLD SOGDIAN NUMBER TWENTY;No;0;R;;;;20;N;;;;;\n10F24;OLD SOGDIAN NUMBER THIRTY;No;0;R;;;;30;N;;;;;\n10F25;OLD SOGDIAN NUMBER ONE HUNDRED;No;0;R;;;;100;N;;;;;\n10F26;OLD SOGDIAN FRACTION ONE HALF;No;0;R;;;;1/2;N;;;;;\n10F27;OLD SOGDIAN LIGATURE AYIN-DALETH;Lo;0;R;;;;;N;;;;;\n10F30;SOGDIAN LETTER ALEPH;Lo;0;AL;;;;;N;;;;;\n10F31;SOGDIAN LETTER BETH;Lo;0;AL;;;;;N;;;;;\n10F32;SOGDIAN LETTER GIMEL;Lo;0;AL;;;;;N;;;;;\n10F33;SOGDIAN LETTER HE;Lo;0;AL;;;;;N;;;;;\n10F34;SOGDIAN LETTER WAW;Lo;0;AL;;;;;N;;;;;\n10F35;SOGDIAN LETTER ZAYIN;Lo;0;AL;;;;;N;;;;;\n10F36;SOGDIAN LETTER HETH;Lo;0;AL;;;;;N;;;;;\n10F37;SOGDIAN LETTER YODH;Lo;0;AL;;;;;N;;;;;\n10F38;SOGDIAN LETTER KAPH;Lo;0;AL;;;;;N;;;;;\n10F39;SOGDIAN LETTER LAMEDH;Lo;0;AL;;;;;N;;;;;\n10F3A;SOGDIAN LETTER MEM;Lo;0;AL;;;;;N;;;;;\n10F3B;SOGDIAN LETTER NUN;Lo;0;AL;;;;;N;;;;;\n10F3C;SOGDIAN LETTER SAMEKH;Lo;0;AL;;;;;N;;;;;\n10F3D;SOGDIAN LETTER AYIN;Lo;0;AL;;;;;N;;;;;\n10F3E;SOGDIAN LETTER PE;Lo;0;AL;;;;;N;;;;;\n10F3F;SOGDIAN LETTER SADHE;Lo;0;AL;;;;;N;;;;;\n10F40;SOGDIAN LETTER RESH-AYIN;Lo;0;AL;;;;;N;;;;;\n10F41;SOGDIAN LETTER SHIN;Lo;0;AL;;;;;N;;;;;\n10F42;SOGDIAN LETTER TAW;Lo;0;AL;;;;;N;;;;;\n10F43;SOGDIAN LETTER FETH;Lo;0;AL;;;;;N;;;;;\n10F44;SOGDIAN LETTER LESH;Lo;0;AL;;;;;N;;;;;\n10F45;SOGDIAN INDEPENDENT SHIN;Lo;0;AL;;;;;N;;;;;\n10F46;SOGDIAN COMBINING DOT BELOW;Mn;220;NSM;;;;;N;;;;;\n10F47;SOGDIAN COMBINING TWO DOTS BELOW;Mn;220;NSM;;;;;N;;;;;\n10F48;SOGDIAN COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;;;;;\n10F49;SOGDIAN COMBINING TWO DOTS ABOVE;Mn;230;NSM;;;;;N;;;;;\n10F4A;SOGDIAN COMBINING CURVE ABOVE;Mn;230;NSM;;;;;N;;;;;\n10F4B;SOGDIAN COMBINING CURVE BELOW;Mn;220;NSM;;;;;N;;;;;\n10F4C;SOGDIAN COMBINING HOOK ABOVE;Mn;230;NSM;;;;;N;;;;;\n10F4D;SOGDIAN COMBINING HOOK BELOW;Mn;220;NSM;;;;;N;;;;;\n10F4E;SOGDIAN COMBINING LONG HOOK BELOW;Mn;220;NSM;;;;;N;;;;;\n10F4F;SOGDIAN COMBINING RESH BELOW;Mn;220;NSM;;;;;N;;;;;\n10F50;SOGDIAN COMBINING STROKE BELOW;Mn;220;NSM;;;;;N;;;;;\n10F51;SOGDIAN NUMBER ONE;No;0;AL;;;;1;N;;;;;\n10F52;SOGDIAN NUMBER TEN;No;0;AL;;;;10;N;;;;;\n10F53;SOGDIAN NUMBER TWENTY;No;0;AL;;;;20;N;;;;;\n10F54;SOGDIAN NUMBER ONE HUNDRED;No;0;AL;;;;100;N;;;;;\n10F55;SOGDIAN PUNCTUATION TWO VERTICAL BARS;Po;0;AL;;;;;N;;;;;\n10F56;SOGDIAN PUNCTUATION TWO VERTICAL BARS WITH DOTS;Po;0;AL;;;;;N;;;;;\n10F57;SOGDIAN PUNCTUATION CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;;\n10F58;SOGDIAN PUNCTUATION TWO CIRCLES WITH DOTS;Po;0;AL;;;;;N;;;;;\n10F59;SOGDIAN PUNCTUATION HALF CIRCLE WITH DOT;Po;0;AL;;;;;N;;;;;\n10FE0;ELYMAIC LETTER ALEPH;Lo;0;R;;;;;N;;;;;\n10FE1;ELYMAIC LETTER BETH;Lo;0;R;;;;;N;;;;;\n10FE2;ELYMAIC LETTER GIMEL;Lo;0;R;;;;;N;;;;;\n10FE3;ELYMAIC LETTER DALETH;Lo;0;R;;;;;N;;;;;\n10FE4;ELYMAIC LETTER HE;Lo;0;R;;;;;N;;;;;\n10FE5;ELYMAIC LETTER WAW;Lo;0;R;;;;;N;;;;;\n10FE6;ELYMAIC LETTER ZAYIN;Lo;0;R;;;;;N;;;;;\n10FE7;ELYMAIC LETTER HETH;Lo;0;R;;;;;N;;;;;\n10FE8;ELYMAIC LETTER TETH;Lo;0;R;;;;;N;;;;;\n10FE9;ELYMAIC LETTER YODH;Lo;0;R;;;;;N;;;;;\n10FEA;ELYMAIC LETTER KAPH;Lo;0;R;;;;;N;;;;;\n10FEB;ELYMAIC LETTER LAMEDH;Lo;0;R;;;;;N;;;;;\n10FEC;ELYMAIC LETTER MEM;Lo;0;R;;;;;N;;;;;\n10FED;ELYMAIC LETTER NUN;Lo;0;R;;;;;N;;;;;\n10FEE;ELYMAIC LETTER SAMEKH;Lo;0;R;;;;;N;;;;;\n10FEF;ELYMAIC LETTER AYIN;Lo;0;R;;;;;N;;;;;\n10FF0;ELYMAIC LETTER PE;Lo;0;R;;;;;N;;;;;\n10FF1;ELYMAIC LETTER SADHE;Lo;0;R;;;;;N;;;;;\n10FF2;ELYMAIC LETTER QOPH;Lo;0;R;;;;;N;;;;;\n10FF3;ELYMAIC LETTER RESH;Lo;0;R;;;;;N;;;;;\n10FF4;ELYMAIC LETTER SHIN;Lo;0;R;;;;;N;;;;;\n10FF5;ELYMAIC LETTER TAW;Lo;0;R;;;;;N;;;;;\n10FF6;ELYMAIC LIGATURE ZAYIN-YODH;Lo;0;R;;;;;N;;;;;\n11000;BRAHMI SIGN CANDRABINDU;Mc;0;L;;;;;N;;;;;\n11001;BRAHMI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n11002;BRAHMI SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n11003;BRAHMI SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;\n11004;BRAHMI SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;\n11005;BRAHMI LETTER A;Lo;0;L;;;;;N;;;;;\n11006;BRAHMI LETTER AA;Lo;0;L;;;;;N;;;;;\n11007;BRAHMI LETTER I;Lo;0;L;;;;;N;;;;;\n11008;BRAHMI LETTER II;Lo;0;L;;;;;N;;;;;\n11009;BRAHMI LETTER U;Lo;0;L;;;;;N;;;;;\n1100A;BRAHMI LETTER UU;Lo;0;L;;;;;N;;;;;\n1100B;BRAHMI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n1100C;BRAHMI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n1100D;BRAHMI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n1100E;BRAHMI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\n1100F;BRAHMI LETTER E;Lo;0;L;;;;;N;;;;;\n11010;BRAHMI LETTER AI;Lo;0;L;;;;;N;;;;;\n11011;BRAHMI LETTER O;Lo;0;L;;;;;N;;;;;\n11012;BRAHMI LETTER AU;Lo;0;L;;;;;N;;;;;\n11013;BRAHMI LETTER KA;Lo;0;L;;;;;N;;;;;\n11014;BRAHMI LETTER KHA;Lo;0;L;;;;;N;;;;;\n11015;BRAHMI LETTER GA;Lo;0;L;;;;;N;;;;;\n11016;BRAHMI LETTER GHA;Lo;0;L;;;;;N;;;;;\n11017;BRAHMI LETTER NGA;Lo;0;L;;;;;N;;;;;\n11018;BRAHMI LETTER CA;Lo;0;L;;;;;N;;;;;\n11019;BRAHMI LETTER CHA;Lo;0;L;;;;;N;;;;;\n1101A;BRAHMI LETTER JA;Lo;0;L;;;;;N;;;;;\n1101B;BRAHMI LETTER JHA;Lo;0;L;;;;;N;;;;;\n1101C;BRAHMI LETTER NYA;Lo;0;L;;;;;N;;;;;\n1101D;BRAHMI LETTER TTA;Lo;0;L;;;;;N;;;;;\n1101E;BRAHMI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n1101F;BRAHMI LETTER DDA;Lo;0;L;;;;;N;;;;;\n11020;BRAHMI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n11021;BRAHMI LETTER NNA;Lo;0;L;;;;;N;;;;;\n11022;BRAHMI LETTER TA;Lo;0;L;;;;;N;;;;;\n11023;BRAHMI LETTER THA;Lo;0;L;;;;;N;;;;;\n11024;BRAHMI LETTER DA;Lo;0;L;;;;;N;;;;;\n11025;BRAHMI LETTER DHA;Lo;0;L;;;;;N;;;;;\n11026;BRAHMI LETTER NA;Lo;0;L;;;;;N;;;;;\n11027;BRAHMI LETTER PA;Lo;0;L;;;;;N;;;;;\n11028;BRAHMI LETTER PHA;Lo;0;L;;;;;N;;;;;\n11029;BRAHMI LETTER BA;Lo;0;L;;;;;N;;;;;\n1102A;BRAHMI LETTER BHA;Lo;0;L;;;;;N;;;;;\n1102B;BRAHMI LETTER MA;Lo;0;L;;;;;N;;;;;\n1102C;BRAHMI LETTER YA;Lo;0;L;;;;;N;;;;;\n1102D;BRAHMI LETTER RA;Lo;0;L;;;;;N;;;;;\n1102E;BRAHMI LETTER LA;Lo;0;L;;;;;N;;;;;\n1102F;BRAHMI LETTER VA;Lo;0;L;;;;;N;;;;;\n11030;BRAHMI LETTER SHA;Lo;0;L;;;;;N;;;;;\n11031;BRAHMI LETTER SSA;Lo;0;L;;;;;N;;;;;\n11032;BRAHMI LETTER SA;Lo;0;L;;;;;N;;;;;\n11033;BRAHMI LETTER HA;Lo;0;L;;;;;N;;;;;\n11034;BRAHMI LETTER LLA;Lo;0;L;;;;;N;;;;;\n11035;BRAHMI LETTER OLD TAMIL LLLA;Lo;0;L;;;;;N;;;;;\n11036;BRAHMI LETTER OLD TAMIL RRA;Lo;0;L;;;;;N;;;;;\n11037;BRAHMI LETTER OLD TAMIL NNNA;Lo;0;L;;;;;N;;;;;\n11038;BRAHMI VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;\n11039;BRAHMI VOWEL SIGN BHATTIPROLU AA;Mn;0;NSM;;;;;N;;;;;\n1103A;BRAHMI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n1103B;BRAHMI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;\n1103C;BRAHMI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n1103D;BRAHMI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n1103E;BRAHMI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n1103F;BRAHMI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;\n11040;BRAHMI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;\n11041;BRAHMI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;\n11042;BRAHMI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n11043;BRAHMI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n11044;BRAHMI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;\n11045;BRAHMI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;\n11046;BRAHMI VIRAMA;Mn;9;NSM;;;;;N;;;;;\n11047;BRAHMI DANDA;Po;0;L;;;;;N;;;;;\n11048;BRAHMI DOUBLE DANDA;Po;0;L;;;;;N;;;;;\n11049;BRAHMI PUNCTUATION DOT;Po;0;L;;;;;N;;;;;\n1104A;BRAHMI PUNCTUATION DOUBLE DOT;Po;0;L;;;;;N;;;;;\n1104B;BRAHMI PUNCTUATION LINE;Po;0;L;;;;;N;;;;;\n1104C;BRAHMI PUNCTUATION CRESCENT BAR;Po;0;L;;;;;N;;;;;\n1104D;BRAHMI PUNCTUATION LOTUS;Po;0;L;;;;;N;;;;;\n11052;BRAHMI NUMBER ONE;No;0;ON;;;1;1;N;;;;;\n11053;BRAHMI NUMBER TWO;No;0;ON;;;2;2;N;;;;;\n11054;BRAHMI NUMBER THREE;No;0;ON;;;3;3;N;;;;;\n11055;BRAHMI NUMBER FOUR;No;0;ON;;;4;4;N;;;;;\n11056;BRAHMI NUMBER FIVE;No;0;ON;;;5;5;N;;;;;\n11057;BRAHMI NUMBER SIX;No;0;ON;;;6;6;N;;;;;\n11058;BRAHMI NUMBER SEVEN;No;0;ON;;;7;7;N;;;;;\n11059;BRAHMI NUMBER EIGHT;No;0;ON;;;8;8;N;;;;;\n1105A;BRAHMI NUMBER NINE;No;0;ON;;;9;9;N;;;;;\n1105B;BRAHMI NUMBER TEN;No;0;ON;;;;10;N;;;;;\n1105C;BRAHMI NUMBER TWENTY;No;0;ON;;;;20;N;;;;;\n1105D;BRAHMI NUMBER THIRTY;No;0;ON;;;;30;N;;;;;\n1105E;BRAHMI NUMBER FORTY;No;0;ON;;;;40;N;;;;;\n1105F;BRAHMI NUMBER FIFTY;No;0;ON;;;;50;N;;;;;\n11060;BRAHMI NUMBER SIXTY;No;0;ON;;;;60;N;;;;;\n11061;BRAHMI NUMBER SEVENTY;No;0;ON;;;;70;N;;;;;\n11062;BRAHMI NUMBER EIGHTY;No;0;ON;;;;80;N;;;;;\n11063;BRAHMI NUMBER NINETY;No;0;ON;;;;90;N;;;;;\n11064;BRAHMI NUMBER ONE HUNDRED;No;0;ON;;;;100;N;;;;;\n11065;BRAHMI NUMBER ONE THOUSAND;No;0;ON;;;;1000;N;;;;;\n11066;BRAHMI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n11067;BRAHMI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n11068;BRAHMI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n11069;BRAHMI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n1106A;BRAHMI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n1106B;BRAHMI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n1106C;BRAHMI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n1106D;BRAHMI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n1106E;BRAHMI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n1106F;BRAHMI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n1107F;BRAHMI NUMBER JOINER;Mn;9;NSM;;;;;N;;;;;\n11080;KAITHI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n11081;KAITHI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n11082;KAITHI SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n11083;KAITHI LETTER A;Lo;0;L;;;;;N;;;;;\n11084;KAITHI LETTER AA;Lo;0;L;;;;;N;;;;;\n11085;KAITHI LETTER I;Lo;0;L;;;;;N;;;;;\n11086;KAITHI LETTER II;Lo;0;L;;;;;N;;;;;\n11087;KAITHI LETTER U;Lo;0;L;;;;;N;;;;;\n11088;KAITHI LETTER UU;Lo;0;L;;;;;N;;;;;\n11089;KAITHI LETTER E;Lo;0;L;;;;;N;;;;;\n1108A;KAITHI LETTER AI;Lo;0;L;;;;;N;;;;;\n1108B;KAITHI LETTER O;Lo;0;L;;;;;N;;;;;\n1108C;KAITHI LETTER AU;Lo;0;L;;;;;N;;;;;\n1108D;KAITHI LETTER KA;Lo;0;L;;;;;N;;;;;\n1108E;KAITHI LETTER KHA;Lo;0;L;;;;;N;;;;;\n1108F;KAITHI LETTER GA;Lo;0;L;;;;;N;;;;;\n11090;KAITHI LETTER GHA;Lo;0;L;;;;;N;;;;;\n11091;KAITHI LETTER NGA;Lo;0;L;;;;;N;;;;;\n11092;KAITHI LETTER CA;Lo;0;L;;;;;N;;;;;\n11093;KAITHI LETTER CHA;Lo;0;L;;;;;N;;;;;\n11094;KAITHI LETTER JA;Lo;0;L;;;;;N;;;;;\n11095;KAITHI LETTER JHA;Lo;0;L;;;;;N;;;;;\n11096;KAITHI LETTER NYA;Lo;0;L;;;;;N;;;;;\n11097;KAITHI LETTER TTA;Lo;0;L;;;;;N;;;;;\n11098;KAITHI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n11099;KAITHI LETTER DDA;Lo;0;L;;;;;N;;;;;\n1109A;KAITHI LETTER DDDHA;Lo;0;L;11099 110BA;;;;N;;;;;\n1109B;KAITHI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n1109C;KAITHI LETTER RHA;Lo;0;L;1109B 110BA;;;;N;;;;;\n1109D;KAITHI LETTER NNA;Lo;0;L;;;;;N;;;;;\n1109E;KAITHI LETTER TA;Lo;0;L;;;;;N;;;;;\n1109F;KAITHI LETTER THA;Lo;0;L;;;;;N;;;;;\n110A0;KAITHI LETTER DA;Lo;0;L;;;;;N;;;;;\n110A1;KAITHI LETTER DHA;Lo;0;L;;;;;N;;;;;\n110A2;KAITHI LETTER NA;Lo;0;L;;;;;N;;;;;\n110A3;KAITHI LETTER PA;Lo;0;L;;;;;N;;;;;\n110A4;KAITHI LETTER PHA;Lo;0;L;;;;;N;;;;;\n110A5;KAITHI LETTER BA;Lo;0;L;;;;;N;;;;;\n110A6;KAITHI LETTER BHA;Lo;0;L;;;;;N;;;;;\n110A7;KAITHI LETTER MA;Lo;0;L;;;;;N;;;;;\n110A8;KAITHI LETTER YA;Lo;0;L;;;;;N;;;;;\n110A9;KAITHI LETTER RA;Lo;0;L;;;;;N;;;;;\n110AA;KAITHI LETTER LA;Lo;0;L;;;;;N;;;;;\n110AB;KAITHI LETTER VA;Lo;0;L;110A5 110BA;;;;N;;;;;\n110AC;KAITHI LETTER SHA;Lo;0;L;;;;;N;;;;;\n110AD;KAITHI LETTER SSA;Lo;0;L;;;;;N;;;;;\n110AE;KAITHI LETTER SA;Lo;0;L;;;;;N;;;;;\n110AF;KAITHI LETTER HA;Lo;0;L;;;;;N;;;;;\n110B0;KAITHI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n110B1;KAITHI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n110B2;KAITHI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n110B3;KAITHI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n110B4;KAITHI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n110B5;KAITHI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n110B6;KAITHI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n110B7;KAITHI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;\n110B8;KAITHI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;\n110B9;KAITHI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n110BA;KAITHI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n110BB;KAITHI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;\n110BC;KAITHI ENUMERATION SIGN;Po;0;L;;;;;N;;;;;\n110BD;KAITHI NUMBER SIGN;Cf;0;L;;;;;N;;;;;\n110BE;KAITHI SECTION MARK;Po;0;L;;;;;N;;;;;\n110BF;KAITHI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;;\n110C0;KAITHI DANDA;Po;0;L;;;;;N;;;;;\n110C1;KAITHI DOUBLE DANDA;Po;0;L;;;;;N;;;;;\n110CD;KAITHI NUMBER SIGN ABOVE;Cf;0;L;;;;;N;;;;;\n110D0;SORA SOMPENG LETTER SAH;Lo;0;L;;;;;N;;;;;\n110D1;SORA SOMPENG LETTER TAH;Lo;0;L;;;;;N;;;;;\n110D2;SORA SOMPENG LETTER BAH;Lo;0;L;;;;;N;;;;;\n110D3;SORA SOMPENG LETTER CAH;Lo;0;L;;;;;N;;;;;\n110D4;SORA SOMPENG LETTER DAH;Lo;0;L;;;;;N;;;;;\n110D5;SORA SOMPENG LETTER GAH;Lo;0;L;;;;;N;;;;;\n110D6;SORA SOMPENG LETTER MAH;Lo;0;L;;;;;N;;;;;\n110D7;SORA SOMPENG LETTER NGAH;Lo;0;L;;;;;N;;;;;\n110D8;SORA SOMPENG LETTER LAH;Lo;0;L;;;;;N;;;;;\n110D9;SORA SOMPENG LETTER NAH;Lo;0;L;;;;;N;;;;;\n110DA;SORA SOMPENG LETTER VAH;Lo;0;L;;;;;N;;;;;\n110DB;SORA SOMPENG LETTER PAH;Lo;0;L;;;;;N;;;;;\n110DC;SORA SOMPENG LETTER YAH;Lo;0;L;;;;;N;;;;;\n110DD;SORA SOMPENG LETTER RAH;Lo;0;L;;;;;N;;;;;\n110DE;SORA SOMPENG LETTER HAH;Lo;0;L;;;;;N;;;;;\n110DF;SORA SOMPENG LETTER KAH;Lo;0;L;;;;;N;;;;;\n110E0;SORA SOMPENG LETTER JAH;Lo;0;L;;;;;N;;;;;\n110E1;SORA SOMPENG LETTER NYAH;Lo;0;L;;;;;N;;;;;\n110E2;SORA SOMPENG LETTER AH;Lo;0;L;;;;;N;;;;;\n110E3;SORA SOMPENG LETTER EEH;Lo;0;L;;;;;N;;;;;\n110E4;SORA SOMPENG LETTER IH;Lo;0;L;;;;;N;;;;;\n110E5;SORA SOMPENG LETTER UH;Lo;0;L;;;;;N;;;;;\n110E6;SORA SOMPENG LETTER OH;Lo;0;L;;;;;N;;;;;\n110E7;SORA SOMPENG LETTER EH;Lo;0;L;;;;;N;;;;;\n110E8;SORA SOMPENG LETTER MAE;Lo;0;L;;;;;N;;;;;\n110F0;SORA SOMPENG DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n110F1;SORA SOMPENG DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n110F2;SORA SOMPENG DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n110F3;SORA SOMPENG DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n110F4;SORA SOMPENG DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n110F5;SORA SOMPENG DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n110F6;SORA SOMPENG DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n110F7;SORA SOMPENG DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n110F8;SORA SOMPENG DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n110F9;SORA SOMPENG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n11100;CHAKMA SIGN CANDRABINDU;Mn;230;NSM;;;;;N;;;;;\n11101;CHAKMA SIGN ANUSVARA;Mn;230;NSM;;;;;N;;;;;\n11102;CHAKMA SIGN VISARGA;Mn;230;NSM;;;;;N;;;;;\n11103;CHAKMA LETTER AA;Lo;0;L;;;;;N;;;;;\n11104;CHAKMA LETTER I;Lo;0;L;;;;;N;;;;;\n11105;CHAKMA LETTER U;Lo;0;L;;;;;N;;;;;\n11106;CHAKMA LETTER E;Lo;0;L;;;;;N;;;;;\n11107;CHAKMA LETTER KAA;Lo;0;L;;;;;N;;;;;\n11108;CHAKMA LETTER KHAA;Lo;0;L;;;;;N;;;;;\n11109;CHAKMA LETTER GAA;Lo;0;L;;;;;N;;;;;\n1110A;CHAKMA LETTER GHAA;Lo;0;L;;;;;N;;;;;\n1110B;CHAKMA LETTER NGAA;Lo;0;L;;;;;N;;;;;\n1110C;CHAKMA LETTER CAA;Lo;0;L;;;;;N;;;;;\n1110D;CHAKMA LETTER CHAA;Lo;0;L;;;;;N;;;;;\n1110E;CHAKMA LETTER JAA;Lo;0;L;;;;;N;;;;;\n1110F;CHAKMA LETTER JHAA;Lo;0;L;;;;;N;;;;;\n11110;CHAKMA LETTER NYAA;Lo;0;L;;;;;N;;;;;\n11111;CHAKMA LETTER TTAA;Lo;0;L;;;;;N;;;;;\n11112;CHAKMA LETTER TTHAA;Lo;0;L;;;;;N;;;;;\n11113;CHAKMA LETTER DDAA;Lo;0;L;;;;;N;;;;;\n11114;CHAKMA LETTER DDHAA;Lo;0;L;;;;;N;;;;;\n11115;CHAKMA LETTER NNAA;Lo;0;L;;;;;N;;;;;\n11116;CHAKMA LETTER TAA;Lo;0;L;;;;;N;;;;;\n11117;CHAKMA LETTER THAA;Lo;0;L;;;;;N;;;;;\n11118;CHAKMA LETTER DAA;Lo;0;L;;;;;N;;;;;\n11119;CHAKMA LETTER DHAA;Lo;0;L;;;;;N;;;;;\n1111A;CHAKMA LETTER NAA;Lo;0;L;;;;;N;;;;;\n1111B;CHAKMA LETTER PAA;Lo;0;L;;;;;N;;;;;\n1111C;CHAKMA LETTER PHAA;Lo;0;L;;;;;N;;;;;\n1111D;CHAKMA LETTER BAA;Lo;0;L;;;;;N;;;;;\n1111E;CHAKMA LETTER BHAA;Lo;0;L;;;;;N;;;;;\n1111F;CHAKMA LETTER MAA;Lo;0;L;;;;;N;;;;;\n11120;CHAKMA LETTER YYAA;Lo;0;L;;;;;N;;;;;\n11121;CHAKMA LETTER YAA;Lo;0;L;;;;;N;;;;;\n11122;CHAKMA LETTER RAA;Lo;0;L;;;;;N;;;;;\n11123;CHAKMA LETTER LAA;Lo;0;L;;;;;N;;;;;\n11124;CHAKMA LETTER WAA;Lo;0;L;;;;;N;;;;;\n11125;CHAKMA LETTER SAA;Lo;0;L;;;;;N;;;;;\n11126;CHAKMA LETTER HAA;Lo;0;L;;;;;N;;;;;\n11127;CHAKMA VOWEL SIGN A;Mn;0;NSM;;;;;N;;;;;\n11128;CHAKMA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n11129;CHAKMA VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;\n1112A;CHAKMA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n1112B;CHAKMA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n1112C;CHAKMA VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\n1112D;CHAKMA VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n1112E;CHAKMA VOWEL SIGN O;Mn;0;NSM;11131 11127;;;;N;;;;;\n1112F;CHAKMA VOWEL SIGN AU;Mn;0;NSM;11132 11127;;;;N;;;;;\n11130;CHAKMA VOWEL SIGN OI;Mn;0;NSM;;;;;N;;;;;\n11131;CHAKMA O MARK;Mn;0;NSM;;;;;N;;;;;\n11132;CHAKMA AU MARK;Mn;0;NSM;;;;;N;;;;;\n11133;CHAKMA VIRAMA;Mn;9;NSM;;;;;N;;;;;\n11134;CHAKMA MAAYYAA;Mn;9;NSM;;;;;N;;;;;\n11136;CHAKMA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n11137;CHAKMA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n11138;CHAKMA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n11139;CHAKMA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n1113A;CHAKMA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n1113B;CHAKMA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n1113C;CHAKMA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n1113D;CHAKMA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n1113E;CHAKMA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n1113F;CHAKMA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n11140;CHAKMA SECTION MARK;Po;0;L;;;;;N;;;;;\n11141;CHAKMA DANDA;Po;0;L;;;;;N;;;;;\n11142;CHAKMA DOUBLE DANDA;Po;0;L;;;;;N;;;;;\n11143;CHAKMA QUESTION MARK;Po;0;L;;;;;N;;;;;\n11144;CHAKMA LETTER LHAA;Lo;0;L;;;;;N;;;;;\n11145;CHAKMA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n11146;CHAKMA VOWEL SIGN EI;Mc;0;L;;;;;N;;;;;\n11150;MAHAJANI LETTER A;Lo;0;L;;;;;N;;;;;\n11151;MAHAJANI LETTER I;Lo;0;L;;;;;N;;;;;\n11152;MAHAJANI LETTER U;Lo;0;L;;;;;N;;;;;\n11153;MAHAJANI LETTER E;Lo;0;L;;;;;N;;;;;\n11154;MAHAJANI LETTER O;Lo;0;L;;;;;N;;;;;\n11155;MAHAJANI LETTER KA;Lo;0;L;;;;;N;;;;;\n11156;MAHAJANI LETTER KHA;Lo;0;L;;;;;N;;;;;\n11157;MAHAJANI LETTER GA;Lo;0;L;;;;;N;;;;;\n11158;MAHAJANI LETTER GHA;Lo;0;L;;;;;N;;;;;\n11159;MAHAJANI LETTER CA;Lo;0;L;;;;;N;;;;;\n1115A;MAHAJANI LETTER CHA;Lo;0;L;;;;;N;;;;;\n1115B;MAHAJANI LETTER JA;Lo;0;L;;;;;N;;;;;\n1115C;MAHAJANI LETTER JHA;Lo;0;L;;;;;N;;;;;\n1115D;MAHAJANI LETTER NYA;Lo;0;L;;;;;N;;;;;\n1115E;MAHAJANI LETTER TTA;Lo;0;L;;;;;N;;;;;\n1115F;MAHAJANI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n11160;MAHAJANI LETTER DDA;Lo;0;L;;;;;N;;;;;\n11161;MAHAJANI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n11162;MAHAJANI LETTER NNA;Lo;0;L;;;;;N;;;;;\n11163;MAHAJANI LETTER TA;Lo;0;L;;;;;N;;;;;\n11164;MAHAJANI LETTER THA;Lo;0;L;;;;;N;;;;;\n11165;MAHAJANI LETTER DA;Lo;0;L;;;;;N;;;;;\n11166;MAHAJANI LETTER DHA;Lo;0;L;;;;;N;;;;;\n11167;MAHAJANI LETTER NA;Lo;0;L;;;;;N;;;;;\n11168;MAHAJANI LETTER PA;Lo;0;L;;;;;N;;;;;\n11169;MAHAJANI LETTER PHA;Lo;0;L;;;;;N;;;;;\n1116A;MAHAJANI LETTER BA;Lo;0;L;;;;;N;;;;;\n1116B;MAHAJANI LETTER BHA;Lo;0;L;;;;;N;;;;;\n1116C;MAHAJANI LETTER MA;Lo;0;L;;;;;N;;;;;\n1116D;MAHAJANI LETTER RA;Lo;0;L;;;;;N;;;;;\n1116E;MAHAJANI LETTER LA;Lo;0;L;;;;;N;;;;;\n1116F;MAHAJANI LETTER VA;Lo;0;L;;;;;N;;;;;\n11170;MAHAJANI LETTER SA;Lo;0;L;;;;;N;;;;;\n11171;MAHAJANI LETTER HA;Lo;0;L;;;;;N;;;;;\n11172;MAHAJANI LETTER RRA;Lo;0;L;;;;;N;;;;;\n11173;MAHAJANI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n11174;MAHAJANI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;\n11175;MAHAJANI SECTION MARK;Po;0;L;;;;;N;;;;;\n11176;MAHAJANI LIGATURE SHRI;Lo;0;L;;;;;N;;;;;\n11180;SHARADA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n11181;SHARADA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n11182;SHARADA SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n11183;SHARADA LETTER A;Lo;0;L;;;;;N;;;;;\n11184;SHARADA LETTER AA;Lo;0;L;;;;;N;;;;;\n11185;SHARADA LETTER I;Lo;0;L;;;;;N;;;;;\n11186;SHARADA LETTER II;Lo;0;L;;;;;N;;;;;\n11187;SHARADA LETTER U;Lo;0;L;;;;;N;;;;;\n11188;SHARADA LETTER UU;Lo;0;L;;;;;N;;;;;\n11189;SHARADA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n1118A;SHARADA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n1118B;SHARADA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n1118C;SHARADA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\n1118D;SHARADA LETTER E;Lo;0;L;;;;;N;;;;;\n1118E;SHARADA LETTER AI;Lo;0;L;;;;;N;;;;;\n1118F;SHARADA LETTER O;Lo;0;L;;;;;N;;;;;\n11190;SHARADA LETTER AU;Lo;0;L;;;;;N;;;;;\n11191;SHARADA LETTER KA;Lo;0;L;;;;;N;;;;;\n11192;SHARADA LETTER KHA;Lo;0;L;;;;;N;;;;;\n11193;SHARADA LETTER GA;Lo;0;L;;;;;N;;;;;\n11194;SHARADA LETTER GHA;Lo;0;L;;;;;N;;;;;\n11195;SHARADA LETTER NGA;Lo;0;L;;;;;N;;;;;\n11196;SHARADA LETTER CA;Lo;0;L;;;;;N;;;;;\n11197;SHARADA LETTER CHA;Lo;0;L;;;;;N;;;;;\n11198;SHARADA LETTER JA;Lo;0;L;;;;;N;;;;;\n11199;SHARADA LETTER JHA;Lo;0;L;;;;;N;;;;;\n1119A;SHARADA LETTER NYA;Lo;0;L;;;;;N;;;;;\n1119B;SHARADA LETTER TTA;Lo;0;L;;;;;N;;;;;\n1119C;SHARADA LETTER TTHA;Lo;0;L;;;;;N;;;;;\n1119D;SHARADA LETTER DDA;Lo;0;L;;;;;N;;;;;\n1119E;SHARADA LETTER DDHA;Lo;0;L;;;;;N;;;;;\n1119F;SHARADA LETTER NNA;Lo;0;L;;;;;N;;;;;\n111A0;SHARADA LETTER TA;Lo;0;L;;;;;N;;;;;\n111A1;SHARADA LETTER THA;Lo;0;L;;;;;N;;;;;\n111A2;SHARADA LETTER DA;Lo;0;L;;;;;N;;;;;\n111A3;SHARADA LETTER DHA;Lo;0;L;;;;;N;;;;;\n111A4;SHARADA LETTER NA;Lo;0;L;;;;;N;;;;;\n111A5;SHARADA LETTER PA;Lo;0;L;;;;;N;;;;;\n111A6;SHARADA LETTER PHA;Lo;0;L;;;;;N;;;;;\n111A7;SHARADA LETTER BA;Lo;0;L;;;;;N;;;;;\n111A8;SHARADA LETTER BHA;Lo;0;L;;;;;N;;;;;\n111A9;SHARADA LETTER MA;Lo;0;L;;;;;N;;;;;\n111AA;SHARADA LETTER YA;Lo;0;L;;;;;N;;;;;\n111AB;SHARADA LETTER RA;Lo;0;L;;;;;N;;;;;\n111AC;SHARADA LETTER LA;Lo;0;L;;;;;N;;;;;\n111AD;SHARADA LETTER LLA;Lo;0;L;;;;;N;;;;;\n111AE;SHARADA LETTER VA;Lo;0;L;;;;;N;;;;;\n111AF;SHARADA LETTER SHA;Lo;0;L;;;;;N;;;;;\n111B0;SHARADA LETTER SSA;Lo;0;L;;;;;N;;;;;\n111B1;SHARADA LETTER SA;Lo;0;L;;;;;N;;;;;\n111B2;SHARADA LETTER HA;Lo;0;L;;;;;N;;;;;\n111B3;SHARADA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n111B4;SHARADA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n111B5;SHARADA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n111B6;SHARADA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n111B7;SHARADA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n111B8;SHARADA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n111B9;SHARADA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;\n111BA;SHARADA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;\n111BB;SHARADA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;\n111BC;SHARADA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n111BD;SHARADA VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n111BE;SHARADA VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;\n111BF;SHARADA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;\n111C0;SHARADA SIGN VIRAMA;Mc;9;L;;;;;N;;;;;\n111C1;SHARADA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;\n111C2;SHARADA SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;\n111C3;SHARADA SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;\n111C4;SHARADA OM;Lo;0;L;;;;;N;;;;;\n111C5;SHARADA DANDA;Po;0;L;;;;;N;;;;;\n111C6;SHARADA DOUBLE DANDA;Po;0;L;;;;;N;;;;;\n111C7;SHARADA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;\n111C8;SHARADA SEPARATOR;Po;0;L;;;;;N;;;;;\n111C9;SHARADA SANDHI MARK;Mn;0;NSM;;;;;N;;;;;\n111CA;SHARADA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n111CB;SHARADA VOWEL MODIFIER MARK;Mn;0;NSM;;;;;N;;;;;\n111CC;SHARADA EXTRA SHORT VOWEL MARK;Mn;0;NSM;;;;;N;;;;;\n111CD;SHARADA SUTRA MARK;Po;0;L;;;;;N;;;;;\n111D0;SHARADA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n111D1;SHARADA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n111D2;SHARADA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n111D3;SHARADA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n111D4;SHARADA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n111D5;SHARADA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n111D6;SHARADA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n111D7;SHARADA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n111D8;SHARADA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n111D9;SHARADA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n111DA;SHARADA EKAM;Lo;0;L;;;;;N;;;;;\n111DB;SHARADA SIGN SIDDHAM;Po;0;L;;;;;N;;;;;\n111DC;SHARADA HEADSTROKE;Lo;0;L;;;;;N;;;;;\n111DD;SHARADA CONTINUATION SIGN;Po;0;L;;;;;N;;;;;\n111DE;SHARADA SECTION MARK-1;Po;0;L;;;;;N;;;;;\n111DF;SHARADA SECTION MARK-2;Po;0;L;;;;;N;;;;;\n111E1;SINHALA ARCHAIC DIGIT ONE;No;0;L;;;;1;N;;;;;\n111E2;SINHALA ARCHAIC DIGIT TWO;No;0;L;;;;2;N;;;;;\n111E3;SINHALA ARCHAIC DIGIT THREE;No;0;L;;;;3;N;;;;;\n111E4;SINHALA ARCHAIC DIGIT FOUR;No;0;L;;;;4;N;;;;;\n111E5;SINHALA ARCHAIC DIGIT FIVE;No;0;L;;;;5;N;;;;;\n111E6;SINHALA ARCHAIC DIGIT SIX;No;0;L;;;;6;N;;;;;\n111E7;SINHALA ARCHAIC DIGIT SEVEN;No;0;L;;;;7;N;;;;;\n111E8;SINHALA ARCHAIC DIGIT EIGHT;No;0;L;;;;8;N;;;;;\n111E9;SINHALA ARCHAIC DIGIT NINE;No;0;L;;;;9;N;;;;;\n111EA;SINHALA ARCHAIC NUMBER TEN;No;0;L;;;;10;N;;;;;\n111EB;SINHALA ARCHAIC NUMBER TWENTY;No;0;L;;;;20;N;;;;;\n111EC;SINHALA ARCHAIC NUMBER THIRTY;No;0;L;;;;30;N;;;;;\n111ED;SINHALA ARCHAIC NUMBER FORTY;No;0;L;;;;40;N;;;;;\n111EE;SINHALA ARCHAIC NUMBER FIFTY;No;0;L;;;;50;N;;;;;\n111EF;SINHALA ARCHAIC NUMBER SIXTY;No;0;L;;;;60;N;;;;;\n111F0;SINHALA ARCHAIC NUMBER SEVENTY;No;0;L;;;;70;N;;;;;\n111F1;SINHALA ARCHAIC NUMBER EIGHTY;No;0;L;;;;80;N;;;;;\n111F2;SINHALA ARCHAIC NUMBER NINETY;No;0;L;;;;90;N;;;;;\n111F3;SINHALA ARCHAIC NUMBER ONE HUNDRED;No;0;L;;;;100;N;;;;;\n111F4;SINHALA ARCHAIC NUMBER ONE THOUSAND;No;0;L;;;;1000;N;;;;;\n11200;KHOJKI LETTER A;Lo;0;L;;;;;N;;;;;\n11201;KHOJKI LETTER AA;Lo;0;L;;;;;N;;;;;\n11202;KHOJKI LETTER I;Lo;0;L;;;;;N;;;;;\n11203;KHOJKI LETTER U;Lo;0;L;;;;;N;;;;;\n11204;KHOJKI LETTER E;Lo;0;L;;;;;N;;;;;\n11205;KHOJKI LETTER AI;Lo;0;L;;;;;N;;;;;\n11206;KHOJKI LETTER O;Lo;0;L;;;;;N;;;;;\n11207;KHOJKI LETTER AU;Lo;0;L;;;;;N;;;;;\n11208;KHOJKI LETTER KA;Lo;0;L;;;;;N;;;;;\n11209;KHOJKI LETTER KHA;Lo;0;L;;;;;N;;;;;\n1120A;KHOJKI LETTER GA;Lo;0;L;;;;;N;;;;;\n1120B;KHOJKI LETTER GGA;Lo;0;L;;;;;N;;;;;\n1120C;KHOJKI LETTER GHA;Lo;0;L;;;;;N;;;;;\n1120D;KHOJKI LETTER NGA;Lo;0;L;;;;;N;;;;;\n1120E;KHOJKI LETTER CA;Lo;0;L;;;;;N;;;;;\n1120F;KHOJKI LETTER CHA;Lo;0;L;;;;;N;;;;;\n11210;KHOJKI LETTER JA;Lo;0;L;;;;;N;;;;;\n11211;KHOJKI LETTER JJA;Lo;0;L;;;;;N;;;;;\n11213;KHOJKI LETTER NYA;Lo;0;L;;;;;N;;;;;\n11214;KHOJKI LETTER TTA;Lo;0;L;;;;;N;;;;;\n11215;KHOJKI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n11216;KHOJKI LETTER DDA;Lo;0;L;;;;;N;;;;;\n11217;KHOJKI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n11218;KHOJKI LETTER NNA;Lo;0;L;;;;;N;;;;;\n11219;KHOJKI LETTER TA;Lo;0;L;;;;;N;;;;;\n1121A;KHOJKI LETTER THA;Lo;0;L;;;;;N;;;;;\n1121B;KHOJKI LETTER DA;Lo;0;L;;;;;N;;;;;\n1121C;KHOJKI LETTER DDDA;Lo;0;L;;;;;N;;;;;\n1121D;KHOJKI LETTER DHA;Lo;0;L;;;;;N;;;;;\n1121E;KHOJKI LETTER NA;Lo;0;L;;;;;N;;;;;\n1121F;KHOJKI LETTER PA;Lo;0;L;;;;;N;;;;;\n11220;KHOJKI LETTER PHA;Lo;0;L;;;;;N;;;;;\n11221;KHOJKI LETTER BA;Lo;0;L;;;;;N;;;;;\n11222;KHOJKI LETTER BBA;Lo;0;L;;;;;N;;;;;\n11223;KHOJKI LETTER BHA;Lo;0;L;;;;;N;;;;;\n11224;KHOJKI LETTER MA;Lo;0;L;;;;;N;;;;;\n11225;KHOJKI LETTER YA;Lo;0;L;;;;;N;;;;;\n11226;KHOJKI LETTER RA;Lo;0;L;;;;;N;;;;;\n11227;KHOJKI LETTER LA;Lo;0;L;;;;;N;;;;;\n11228;KHOJKI LETTER VA;Lo;0;L;;;;;N;;;;;\n11229;KHOJKI LETTER SA;Lo;0;L;;;;;N;;;;;\n1122A;KHOJKI LETTER HA;Lo;0;L;;;;;N;;;;;\n1122B;KHOJKI LETTER LLA;Lo;0;L;;;;;N;;;;;\n1122C;KHOJKI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n1122D;KHOJKI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n1122E;KHOJKI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n1122F;KHOJKI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n11230;KHOJKI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n11231;KHOJKI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n11232;KHOJKI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;\n11233;KHOJKI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;\n11234;KHOJKI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n11235;KHOJKI SIGN VIRAMA;Mc;9;L;;;;;N;;;;;\n11236;KHOJKI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n11237;KHOJKI SIGN SHADDA;Mn;0;NSM;;;;;N;;;;;\n11238;KHOJKI DANDA;Po;0;L;;;;;N;;;;;\n11239;KHOJKI DOUBLE DANDA;Po;0;L;;;;;N;;;;;\n1123A;KHOJKI WORD SEPARATOR;Po;0;L;;;;;N;;;;;\n1123B;KHOJKI SECTION MARK;Po;0;L;;;;;N;;;;;\n1123C;KHOJKI DOUBLE SECTION MARK;Po;0;L;;;;;N;;;;;\n1123D;KHOJKI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;\n1123E;KHOJKI SIGN SUKUN;Mn;0;NSM;;;;;N;;;;;\n11280;MULTANI LETTER A;Lo;0;L;;;;;N;;;;;\n11281;MULTANI LETTER I;Lo;0;L;;;;;N;;;;;\n11282;MULTANI LETTER U;Lo;0;L;;;;;N;;;;;\n11283;MULTANI LETTER E;Lo;0;L;;;;;N;;;;;\n11284;MULTANI LETTER KA;Lo;0;L;;;;;N;;;;;\n11285;MULTANI LETTER KHA;Lo;0;L;;;;;N;;;;;\n11286;MULTANI LETTER GA;Lo;0;L;;;;;N;;;;;\n11288;MULTANI LETTER GHA;Lo;0;L;;;;;N;;;;;\n1128A;MULTANI LETTER CA;Lo;0;L;;;;;N;;;;;\n1128B;MULTANI LETTER CHA;Lo;0;L;;;;;N;;;;;\n1128C;MULTANI LETTER JA;Lo;0;L;;;;;N;;;;;\n1128D;MULTANI LETTER JJA;Lo;0;L;;;;;N;;;;;\n1128F;MULTANI LETTER NYA;Lo;0;L;;;;;N;;;;;\n11290;MULTANI LETTER TTA;Lo;0;L;;;;;N;;;;;\n11291;MULTANI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n11292;MULTANI LETTER DDA;Lo;0;L;;;;;N;;;;;\n11293;MULTANI LETTER DDDA;Lo;0;L;;;;;N;;;;;\n11294;MULTANI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n11295;MULTANI LETTER NNA;Lo;0;L;;;;;N;;;;;\n11296;MULTANI LETTER TA;Lo;0;L;;;;;N;;;;;\n11297;MULTANI LETTER THA;Lo;0;L;;;;;N;;;;;\n11298;MULTANI LETTER DA;Lo;0;L;;;;;N;;;;;\n11299;MULTANI LETTER DHA;Lo;0;L;;;;;N;;;;;\n1129A;MULTANI LETTER NA;Lo;0;L;;;;;N;;;;;\n1129B;MULTANI LETTER PA;Lo;0;L;;;;;N;;;;;\n1129C;MULTANI LETTER PHA;Lo;0;L;;;;;N;;;;;\n1129D;MULTANI LETTER BA;Lo;0;L;;;;;N;;;;;\n1129F;MULTANI LETTER BHA;Lo;0;L;;;;;N;;;;;\n112A0;MULTANI LETTER MA;Lo;0;L;;;;;N;;;;;\n112A1;MULTANI LETTER YA;Lo;0;L;;;;;N;;;;;\n112A2;MULTANI LETTER RA;Lo;0;L;;;;;N;;;;;\n112A3;MULTANI LETTER LA;Lo;0;L;;;;;N;;;;;\n112A4;MULTANI LETTER VA;Lo;0;L;;;;;N;;;;;\n112A5;MULTANI LETTER SA;Lo;0;L;;;;;N;;;;;\n112A6;MULTANI LETTER HA;Lo;0;L;;;;;N;;;;;\n112A7;MULTANI LETTER RRA;Lo;0;L;;;;;N;;;;;\n112A8;MULTANI LETTER RHA;Lo;0;L;;;;;N;;;;;\n112A9;MULTANI SECTION MARK;Po;0;L;;;;;N;;;;;\n112B0;KHUDAWADI LETTER A;Lo;0;L;;;;;N;;;;;\n112B1;KHUDAWADI LETTER AA;Lo;0;L;;;;;N;;;;;\n112B2;KHUDAWADI LETTER I;Lo;0;L;;;;;N;;;;;\n112B3;KHUDAWADI LETTER II;Lo;0;L;;;;;N;;;;;\n112B4;KHUDAWADI LETTER U;Lo;0;L;;;;;N;;;;;\n112B5;KHUDAWADI LETTER UU;Lo;0;L;;;;;N;;;;;\n112B6;KHUDAWADI LETTER E;Lo;0;L;;;;;N;;;;;\n112B7;KHUDAWADI LETTER AI;Lo;0;L;;;;;N;;;;;\n112B8;KHUDAWADI LETTER O;Lo;0;L;;;;;N;;;;;\n112B9;KHUDAWADI LETTER AU;Lo;0;L;;;;;N;;;;;\n112BA;KHUDAWADI LETTER KA;Lo;0;L;;;;;N;;;;;\n112BB;KHUDAWADI LETTER KHA;Lo;0;L;;;;;N;;;;;\n112BC;KHUDAWADI LETTER GA;Lo;0;L;;;;;N;;;;;\n112BD;KHUDAWADI LETTER GGA;Lo;0;L;;;;;N;;;;;\n112BE;KHUDAWADI LETTER GHA;Lo;0;L;;;;;N;;;;;\n112BF;KHUDAWADI LETTER NGA;Lo;0;L;;;;;N;;;;;\n112C0;KHUDAWADI LETTER CA;Lo;0;L;;;;;N;;;;;\n112C1;KHUDAWADI LETTER CHA;Lo;0;L;;;;;N;;;;;\n112C2;KHUDAWADI LETTER JA;Lo;0;L;;;;;N;;;;;\n112C3;KHUDAWADI LETTER JJA;Lo;0;L;;;;;N;;;;;\n112C4;KHUDAWADI LETTER JHA;Lo;0;L;;;;;N;;;;;\n112C5;KHUDAWADI LETTER NYA;Lo;0;L;;;;;N;;;;;\n112C6;KHUDAWADI LETTER TTA;Lo;0;L;;;;;N;;;;;\n112C7;KHUDAWADI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n112C8;KHUDAWADI LETTER DDA;Lo;0;L;;;;;N;;;;;\n112C9;KHUDAWADI LETTER DDDA;Lo;0;L;;;;;N;;;;;\n112CA;KHUDAWADI LETTER RRA;Lo;0;L;;;;;N;;;;;\n112CB;KHUDAWADI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n112CC;KHUDAWADI LETTER NNA;Lo;0;L;;;;;N;;;;;\n112CD;KHUDAWADI LETTER TA;Lo;0;L;;;;;N;;;;;\n112CE;KHUDAWADI LETTER THA;Lo;0;L;;;;;N;;;;;\n112CF;KHUDAWADI LETTER DA;Lo;0;L;;;;;N;;;;;\n112D0;KHUDAWADI LETTER DHA;Lo;0;L;;;;;N;;;;;\n112D1;KHUDAWADI LETTER NA;Lo;0;L;;;;;N;;;;;\n112D2;KHUDAWADI LETTER PA;Lo;0;L;;;;;N;;;;;\n112D3;KHUDAWADI LETTER PHA;Lo;0;L;;;;;N;;;;;\n112D4;KHUDAWADI LETTER BA;Lo;0;L;;;;;N;;;;;\n112D5;KHUDAWADI LETTER BBA;Lo;0;L;;;;;N;;;;;\n112D6;KHUDAWADI LETTER BHA;Lo;0;L;;;;;N;;;;;\n112D7;KHUDAWADI LETTER MA;Lo;0;L;;;;;N;;;;;\n112D8;KHUDAWADI LETTER YA;Lo;0;L;;;;;N;;;;;\n112D9;KHUDAWADI LETTER RA;Lo;0;L;;;;;N;;;;;\n112DA;KHUDAWADI LETTER LA;Lo;0;L;;;;;N;;;;;\n112DB;KHUDAWADI LETTER VA;Lo;0;L;;;;;N;;;;;\n112DC;KHUDAWADI LETTER SHA;Lo;0;L;;;;;N;;;;;\n112DD;KHUDAWADI LETTER SA;Lo;0;L;;;;;N;;;;;\n112DE;KHUDAWADI LETTER HA;Lo;0;L;;;;;N;;;;;\n112DF;KHUDAWADI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n112E0;KHUDAWADI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n112E1;KHUDAWADI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n112E2;KHUDAWADI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n112E3;KHUDAWADI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n112E4;KHUDAWADI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n112E5;KHUDAWADI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n112E6;KHUDAWADI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n112E7;KHUDAWADI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;\n112E8;KHUDAWADI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;\n112E9;KHUDAWADI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n112EA;KHUDAWADI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n112F0;KHUDAWADI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n112F1;KHUDAWADI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n112F2;KHUDAWADI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n112F3;KHUDAWADI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n112F4;KHUDAWADI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n112F5;KHUDAWADI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n112F6;KHUDAWADI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n112F7;KHUDAWADI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n112F8;KHUDAWADI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n112F9;KHUDAWADI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n11300;GRANTHA SIGN COMBINING ANUSVARA ABOVE;Mn;0;NSM;;;;;N;;;;;\n11301;GRANTHA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n11302;GRANTHA SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;\n11303;GRANTHA SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n11305;GRANTHA LETTER A;Lo;0;L;;;;;N;;;;;\n11306;GRANTHA LETTER AA;Lo;0;L;;;;;N;;;;;\n11307;GRANTHA LETTER I;Lo;0;L;;;;;N;;;;;\n11308;GRANTHA LETTER II;Lo;0;L;;;;;N;;;;;\n11309;GRANTHA LETTER U;Lo;0;L;;;;;N;;;;;\n1130A;GRANTHA LETTER UU;Lo;0;L;;;;;N;;;;;\n1130B;GRANTHA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n1130C;GRANTHA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n1130F;GRANTHA LETTER EE;Lo;0;L;;;;;N;;;;;\n11310;GRANTHA LETTER AI;Lo;0;L;;;;;N;;;;;\n11313;GRANTHA LETTER OO;Lo;0;L;;;;;N;;;;;\n11314;GRANTHA LETTER AU;Lo;0;L;;;;;N;;;;;\n11315;GRANTHA LETTER KA;Lo;0;L;;;;;N;;;;;\n11316;GRANTHA LETTER KHA;Lo;0;L;;;;;N;;;;;\n11317;GRANTHA LETTER GA;Lo;0;L;;;;;N;;;;;\n11318;GRANTHA LETTER GHA;Lo;0;L;;;;;N;;;;;\n11319;GRANTHA LETTER NGA;Lo;0;L;;;;;N;;;;;\n1131A;GRANTHA LETTER CA;Lo;0;L;;;;;N;;;;;\n1131B;GRANTHA LETTER CHA;Lo;0;L;;;;;N;;;;;\n1131C;GRANTHA LETTER JA;Lo;0;L;;;;;N;;;;;\n1131D;GRANTHA LETTER JHA;Lo;0;L;;;;;N;;;;;\n1131E;GRANTHA LETTER NYA;Lo;0;L;;;;;N;;;;;\n1131F;GRANTHA LETTER TTA;Lo;0;L;;;;;N;;;;;\n11320;GRANTHA LETTER TTHA;Lo;0;L;;;;;N;;;;;\n11321;GRANTHA LETTER DDA;Lo;0;L;;;;;N;;;;;\n11322;GRANTHA LETTER DDHA;Lo;0;L;;;;;N;;;;;\n11323;GRANTHA LETTER NNA;Lo;0;L;;;;;N;;;;;\n11324;GRANTHA LETTER TA;Lo;0;L;;;;;N;;;;;\n11325;GRANTHA LETTER THA;Lo;0;L;;;;;N;;;;;\n11326;GRANTHA LETTER DA;Lo;0;L;;;;;N;;;;;\n11327;GRANTHA LETTER DHA;Lo;0;L;;;;;N;;;;;\n11328;GRANTHA LETTER NA;Lo;0;L;;;;;N;;;;;\n1132A;GRANTHA LETTER PA;Lo;0;L;;;;;N;;;;;\n1132B;GRANTHA LETTER PHA;Lo;0;L;;;;;N;;;;;\n1132C;GRANTHA LETTER BA;Lo;0;L;;;;;N;;;;;\n1132D;GRANTHA LETTER BHA;Lo;0;L;;;;;N;;;;;\n1132E;GRANTHA LETTER MA;Lo;0;L;;;;;N;;;;;\n1132F;GRANTHA LETTER YA;Lo;0;L;;;;;N;;;;;\n11330;GRANTHA LETTER RA;Lo;0;L;;;;;N;;;;;\n11332;GRANTHA LETTER LA;Lo;0;L;;;;;N;;;;;\n11333;GRANTHA LETTER LLA;Lo;0;L;;;;;N;;;;;\n11335;GRANTHA LETTER VA;Lo;0;L;;;;;N;;;;;\n11336;GRANTHA LETTER SHA;Lo;0;L;;;;;N;;;;;\n11337;GRANTHA LETTER SSA;Lo;0;L;;;;;N;;;;;\n11338;GRANTHA LETTER SA;Lo;0;L;;;;;N;;;;;\n11339;GRANTHA LETTER HA;Lo;0;L;;;;;N;;;;;\n1133B;COMBINING BINDU BELOW;Mn;7;NSM;;;;;N;;;;;\n1133C;GRANTHA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n1133D;GRANTHA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;\n1133E;GRANTHA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n1133F;GRANTHA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n11340;GRANTHA VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;\n11341;GRANTHA VOWEL SIGN U;Mc;0;L;;;;;N;;;;;\n11342;GRANTHA VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;\n11343;GRANTHA VOWEL SIGN VOCALIC R;Mc;0;L;;;;;N;;;;;\n11344;GRANTHA VOWEL SIGN VOCALIC RR;Mc;0;L;;;;;N;;;;;\n11347;GRANTHA VOWEL SIGN EE;Mc;0;L;;;;;N;;;;;\n11348;GRANTHA VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;\n1134B;GRANTHA VOWEL SIGN OO;Mc;0;L;11347 1133E;;;;N;;;;;\n1134C;GRANTHA VOWEL SIGN AU;Mc;0;L;11347 11357;;;;N;;;;;\n1134D;GRANTHA SIGN VIRAMA;Mc;9;L;;;;;N;;;;;\n11350;GRANTHA OM;Lo;0;L;;;;;N;;;;;\n11357;GRANTHA AU LENGTH MARK;Mc;0;L;;;;;N;;;;;\n1135D;GRANTHA SIGN PLUTA;Lo;0;L;;;;;N;;;;;\n1135E;GRANTHA LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;;\n1135F;GRANTHA LETTER VEDIC DOUBLE ANUSVARA;Lo;0;L;;;;;N;;;;;\n11360;GRANTHA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n11361;GRANTHA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\n11362;GRANTHA VOWEL SIGN VOCALIC L;Mc;0;L;;;;;N;;;;;\n11363;GRANTHA VOWEL SIGN VOCALIC LL;Mc;0;L;;;;;N;;;;;\n11366;COMBINING GRANTHA DIGIT ZERO;Mn;230;NSM;;;;;N;;;;;\n11367;COMBINING GRANTHA DIGIT ONE;Mn;230;NSM;;;;;N;;;;;\n11368;COMBINING GRANTHA DIGIT TWO;Mn;230;NSM;;;;;N;;;;;\n11369;COMBINING GRANTHA DIGIT THREE;Mn;230;NSM;;;;;N;;;;;\n1136A;COMBINING GRANTHA DIGIT FOUR;Mn;230;NSM;;;;;N;;;;;\n1136B;COMBINING GRANTHA DIGIT FIVE;Mn;230;NSM;;;;;N;;;;;\n1136C;COMBINING GRANTHA DIGIT SIX;Mn;230;NSM;;;;;N;;;;;\n11370;COMBINING GRANTHA LETTER A;Mn;230;NSM;;;;;N;;;;;\n11371;COMBINING GRANTHA LETTER KA;Mn;230;NSM;;;;;N;;;;;\n11372;COMBINING GRANTHA LETTER NA;Mn;230;NSM;;;;;N;;;;;\n11373;COMBINING GRANTHA LETTER VI;Mn;230;NSM;;;;;N;;;;;\n11374;COMBINING GRANTHA LETTER PA;Mn;230;NSM;;;;;N;;;;;\n11400;NEWA LETTER A;Lo;0;L;;;;;N;;;;;\n11401;NEWA LETTER AA;Lo;0;L;;;;;N;;;;;\n11402;NEWA LETTER I;Lo;0;L;;;;;N;;;;;\n11403;NEWA LETTER II;Lo;0;L;;;;;N;;;;;\n11404;NEWA LETTER U;Lo;0;L;;;;;N;;;;;\n11405;NEWA LETTER UU;Lo;0;L;;;;;N;;;;;\n11406;NEWA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n11407;NEWA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n11408;NEWA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n11409;NEWA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\n1140A;NEWA LETTER E;Lo;0;L;;;;;N;;;;;\n1140B;NEWA LETTER AI;Lo;0;L;;;;;N;;;;;\n1140C;NEWA LETTER O;Lo;0;L;;;;;N;;;;;\n1140D;NEWA LETTER AU;Lo;0;L;;;;;N;;;;;\n1140E;NEWA LETTER KA;Lo;0;L;;;;;N;;;;;\n1140F;NEWA LETTER KHA;Lo;0;L;;;;;N;;;;;\n11410;NEWA LETTER GA;Lo;0;L;;;;;N;;;;;\n11411;NEWA LETTER GHA;Lo;0;L;;;;;N;;;;;\n11412;NEWA LETTER NGA;Lo;0;L;;;;;N;;;;;\n11413;NEWA LETTER NGHA;Lo;0;L;;;;;N;;;;;\n11414;NEWA LETTER CA;Lo;0;L;;;;;N;;;;;\n11415;NEWA LETTER CHA;Lo;0;L;;;;;N;;;;;\n11416;NEWA LETTER JA;Lo;0;L;;;;;N;;;;;\n11417;NEWA LETTER JHA;Lo;0;L;;;;;N;;;;;\n11418;NEWA LETTER NYA;Lo;0;L;;;;;N;;;;;\n11419;NEWA LETTER NYHA;Lo;0;L;;;;;N;;;;;\n1141A;NEWA LETTER TTA;Lo;0;L;;;;;N;;;;;\n1141B;NEWA LETTER TTHA;Lo;0;L;;;;;N;;;;;\n1141C;NEWA LETTER DDA;Lo;0;L;;;;;N;;;;;\n1141D;NEWA LETTER DDHA;Lo;0;L;;;;;N;;;;;\n1141E;NEWA LETTER NNA;Lo;0;L;;;;;N;;;;;\n1141F;NEWA LETTER TA;Lo;0;L;;;;;N;;;;;\n11420;NEWA LETTER THA;Lo;0;L;;;;;N;;;;;\n11421;NEWA LETTER DA;Lo;0;L;;;;;N;;;;;\n11422;NEWA LETTER DHA;Lo;0;L;;;;;N;;;;;\n11423;NEWA LETTER NA;Lo;0;L;;;;;N;;;;;\n11424;NEWA LETTER NHA;Lo;0;L;;;;;N;;;;;\n11425;NEWA LETTER PA;Lo;0;L;;;;;N;;;;;\n11426;NEWA LETTER PHA;Lo;0;L;;;;;N;;;;;\n11427;NEWA LETTER BA;Lo;0;L;;;;;N;;;;;\n11428;NEWA LETTER BHA;Lo;0;L;;;;;N;;;;;\n11429;NEWA LETTER MA;Lo;0;L;;;;;N;;;;;\n1142A;NEWA LETTER MHA;Lo;0;L;;;;;N;;;;;\n1142B;NEWA LETTER YA;Lo;0;L;;;;;N;;;;;\n1142C;NEWA LETTER RA;Lo;0;L;;;;;N;;;;;\n1142D;NEWA LETTER RHA;Lo;0;L;;;;;N;;;;;\n1142E;NEWA LETTER LA;Lo;0;L;;;;;N;;;;;\n1142F;NEWA LETTER LHA;Lo;0;L;;;;;N;;;;;\n11430;NEWA LETTER WA;Lo;0;L;;;;;N;;;;;\n11431;NEWA LETTER SHA;Lo;0;L;;;;;N;;;;;\n11432;NEWA LETTER SSA;Lo;0;L;;;;;N;;;;;\n11433;NEWA LETTER SA;Lo;0;L;;;;;N;;;;;\n11434;NEWA LETTER HA;Lo;0;L;;;;;N;;;;;\n11435;NEWA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n11436;NEWA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n11437;NEWA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n11438;NEWA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n11439;NEWA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n1143A;NEWA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n1143B;NEWA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;\n1143C;NEWA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;\n1143D;NEWA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;\n1143E;NEWA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n1143F;NEWA VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n11440;NEWA VOWEL SIGN O;Mc;0;L;;;;;N;;;;;\n11441;NEWA VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;\n11442;NEWA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n11443;NEWA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n11444;NEWA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n11445;NEWA SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n11446;NEWA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n11447;NEWA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;\n11448;NEWA SIGN FINAL ANUSVARA;Lo;0;L;;;;;N;;;;;\n11449;NEWA OM;Lo;0;L;;;;;N;;;;;\n1144A;NEWA SIDDHI;Lo;0;L;;;;;N;;;;;\n1144B;NEWA DANDA;Po;0;L;;;;;N;;;;;\n1144C;NEWA DOUBLE DANDA;Po;0;L;;;;;N;;;;;\n1144D;NEWA COMMA;Po;0;L;;;;;N;;;;;\n1144E;NEWA GAP FILLER;Po;0;L;;;;;N;;;;;\n1144F;NEWA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;\n11450;NEWA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n11451;NEWA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n11452;NEWA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n11453;NEWA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n11454;NEWA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n11455;NEWA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n11456;NEWA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n11457;NEWA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n11458;NEWA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n11459;NEWA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n1145B;NEWA PLACEHOLDER MARK;Po;0;L;;;;;N;;;;;\n1145D;NEWA INSERTION SIGN;Po;0;L;;;;;N;;;;;\n1145E;NEWA SANDHI MARK;Mn;230;NSM;;;;;N;;;;;\n1145F;NEWA LETTER VEDIC ANUSVARA;Lo;0;L;;;;;N;;;;;\n11480;TIRHUTA ANJI;Lo;0;L;;;;;N;;;;;\n11481;TIRHUTA LETTER A;Lo;0;L;;;;;N;;;;;\n11482;TIRHUTA LETTER AA;Lo;0;L;;;;;N;;;;;\n11483;TIRHUTA LETTER I;Lo;0;L;;;;;N;;;;;\n11484;TIRHUTA LETTER II;Lo;0;L;;;;;N;;;;;\n11485;TIRHUTA LETTER U;Lo;0;L;;;;;N;;;;;\n11486;TIRHUTA LETTER UU;Lo;0;L;;;;;N;;;;;\n11487;TIRHUTA LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n11488;TIRHUTA LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n11489;TIRHUTA LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n1148A;TIRHUTA LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\n1148B;TIRHUTA LETTER E;Lo;0;L;;;;;N;;;;;\n1148C;TIRHUTA LETTER AI;Lo;0;L;;;;;N;;;;;\n1148D;TIRHUTA LETTER O;Lo;0;L;;;;;N;;;;;\n1148E;TIRHUTA LETTER AU;Lo;0;L;;;;;N;;;;;\n1148F;TIRHUTA LETTER KA;Lo;0;L;;;;;N;;;;;\n11490;TIRHUTA LETTER KHA;Lo;0;L;;;;;N;;;;;\n11491;TIRHUTA LETTER GA;Lo;0;L;;;;;N;;;;;\n11492;TIRHUTA LETTER GHA;Lo;0;L;;;;;N;;;;;\n11493;TIRHUTA LETTER NGA;Lo;0;L;;;;;N;;;;;\n11494;TIRHUTA LETTER CA;Lo;0;L;;;;;N;;;;;\n11495;TIRHUTA LETTER CHA;Lo;0;L;;;;;N;;;;;\n11496;TIRHUTA LETTER JA;Lo;0;L;;;;;N;;;;;\n11497;TIRHUTA LETTER JHA;Lo;0;L;;;;;N;;;;;\n11498;TIRHUTA LETTER NYA;Lo;0;L;;;;;N;;;;;\n11499;TIRHUTA LETTER TTA;Lo;0;L;;;;;N;;;;;\n1149A;TIRHUTA LETTER TTHA;Lo;0;L;;;;;N;;;;;\n1149B;TIRHUTA LETTER DDA;Lo;0;L;;;;;N;;;;;\n1149C;TIRHUTA LETTER DDHA;Lo;0;L;;;;;N;;;;;\n1149D;TIRHUTA LETTER NNA;Lo;0;L;;;;;N;;;;;\n1149E;TIRHUTA LETTER TA;Lo;0;L;;;;;N;;;;;\n1149F;TIRHUTA LETTER THA;Lo;0;L;;;;;N;;;;;\n114A0;TIRHUTA LETTER DA;Lo;0;L;;;;;N;;;;;\n114A1;TIRHUTA LETTER DHA;Lo;0;L;;;;;N;;;;;\n114A2;TIRHUTA LETTER NA;Lo;0;L;;;;;N;;;;;\n114A3;TIRHUTA LETTER PA;Lo;0;L;;;;;N;;;;;\n114A4;TIRHUTA LETTER PHA;Lo;0;L;;;;;N;;;;;\n114A5;TIRHUTA LETTER BA;Lo;0;L;;;;;N;;;;;\n114A6;TIRHUTA LETTER BHA;Lo;0;L;;;;;N;;;;;\n114A7;TIRHUTA LETTER MA;Lo;0;L;;;;;N;;;;;\n114A8;TIRHUTA LETTER YA;Lo;0;L;;;;;N;;;;;\n114A9;TIRHUTA LETTER RA;Lo;0;L;;;;;N;;;;;\n114AA;TIRHUTA LETTER LA;Lo;0;L;;;;;N;;;;;\n114AB;TIRHUTA LETTER VA;Lo;0;L;;;;;N;;;;;\n114AC;TIRHUTA LETTER SHA;Lo;0;L;;;;;N;;;;;\n114AD;TIRHUTA LETTER SSA;Lo;0;L;;;;;N;;;;;\n114AE;TIRHUTA LETTER SA;Lo;0;L;;;;;N;;;;;\n114AF;TIRHUTA LETTER HA;Lo;0;L;;;;;N;;;;;\n114B0;TIRHUTA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n114B1;TIRHUTA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n114B2;TIRHUTA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n114B3;TIRHUTA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n114B4;TIRHUTA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n114B5;TIRHUTA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n114B6;TIRHUTA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;\n114B7;TIRHUTA VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;\n114B8;TIRHUTA VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;\n114B9;TIRHUTA VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\n114BA;TIRHUTA VOWEL SIGN SHORT E;Mn;0;NSM;;;;;N;;;;;\n114BB;TIRHUTA VOWEL SIGN AI;Mc;0;L;114B9 114BA;;;;N;;;;;\n114BC;TIRHUTA VOWEL SIGN O;Mc;0;L;114B9 114B0;;;;N;;;;;\n114BD;TIRHUTA VOWEL SIGN SHORT O;Mc;0;L;;;;;N;;;;;\n114BE;TIRHUTA VOWEL SIGN AU;Mc;0;L;114B9 114BD;;;;N;;;;;\n114BF;TIRHUTA SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n114C0;TIRHUTA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n114C1;TIRHUTA SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n114C2;TIRHUTA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n114C3;TIRHUTA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n114C4;TIRHUTA SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;\n114C5;TIRHUTA GVANG;Lo;0;L;;;;;N;;;;;\n114C6;TIRHUTA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;\n114C7;TIRHUTA OM;Lo;0;L;;;;;N;;;;;\n114D0;TIRHUTA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n114D1;TIRHUTA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n114D2;TIRHUTA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n114D3;TIRHUTA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n114D4;TIRHUTA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n114D5;TIRHUTA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n114D6;TIRHUTA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n114D7;TIRHUTA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n114D8;TIRHUTA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n114D9;TIRHUTA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n11580;SIDDHAM LETTER A;Lo;0;L;;;;;N;;;;;\n11581;SIDDHAM LETTER AA;Lo;0;L;;;;;N;;;;;\n11582;SIDDHAM LETTER I;Lo;0;L;;;;;N;;;;;\n11583;SIDDHAM LETTER II;Lo;0;L;;;;;N;;;;;\n11584;SIDDHAM LETTER U;Lo;0;L;;;;;N;;;;;\n11585;SIDDHAM LETTER UU;Lo;0;L;;;;;N;;;;;\n11586;SIDDHAM LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n11587;SIDDHAM LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n11588;SIDDHAM LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n11589;SIDDHAM LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\n1158A;SIDDHAM LETTER E;Lo;0;L;;;;;N;;;;;\n1158B;SIDDHAM LETTER AI;Lo;0;L;;;;;N;;;;;\n1158C;SIDDHAM LETTER O;Lo;0;L;;;;;N;;;;;\n1158D;SIDDHAM LETTER AU;Lo;0;L;;;;;N;;;;;\n1158E;SIDDHAM LETTER KA;Lo;0;L;;;;;N;;;;;\n1158F;SIDDHAM LETTER KHA;Lo;0;L;;;;;N;;;;;\n11590;SIDDHAM LETTER GA;Lo;0;L;;;;;N;;;;;\n11591;SIDDHAM LETTER GHA;Lo;0;L;;;;;N;;;;;\n11592;SIDDHAM LETTER NGA;Lo;0;L;;;;;N;;;;;\n11593;SIDDHAM LETTER CA;Lo;0;L;;;;;N;;;;;\n11594;SIDDHAM LETTER CHA;Lo;0;L;;;;;N;;;;;\n11595;SIDDHAM LETTER JA;Lo;0;L;;;;;N;;;;;\n11596;SIDDHAM LETTER JHA;Lo;0;L;;;;;N;;;;;\n11597;SIDDHAM LETTER NYA;Lo;0;L;;;;;N;;;;;\n11598;SIDDHAM LETTER TTA;Lo;0;L;;;;;N;;;;;\n11599;SIDDHAM LETTER TTHA;Lo;0;L;;;;;N;;;;;\n1159A;SIDDHAM LETTER DDA;Lo;0;L;;;;;N;;;;;\n1159B;SIDDHAM LETTER DDHA;Lo;0;L;;;;;N;;;;;\n1159C;SIDDHAM LETTER NNA;Lo;0;L;;;;;N;;;;;\n1159D;SIDDHAM LETTER TA;Lo;0;L;;;;;N;;;;;\n1159E;SIDDHAM LETTER THA;Lo;0;L;;;;;N;;;;;\n1159F;SIDDHAM LETTER DA;Lo;0;L;;;;;N;;;;;\n115A0;SIDDHAM LETTER DHA;Lo;0;L;;;;;N;;;;;\n115A1;SIDDHAM LETTER NA;Lo;0;L;;;;;N;;;;;\n115A2;SIDDHAM LETTER PA;Lo;0;L;;;;;N;;;;;\n115A3;SIDDHAM LETTER PHA;Lo;0;L;;;;;N;;;;;\n115A4;SIDDHAM LETTER BA;Lo;0;L;;;;;N;;;;;\n115A5;SIDDHAM LETTER BHA;Lo;0;L;;;;;N;;;;;\n115A6;SIDDHAM LETTER MA;Lo;0;L;;;;;N;;;;;\n115A7;SIDDHAM LETTER YA;Lo;0;L;;;;;N;;;;;\n115A8;SIDDHAM LETTER RA;Lo;0;L;;;;;N;;;;;\n115A9;SIDDHAM LETTER LA;Lo;0;L;;;;;N;;;;;\n115AA;SIDDHAM LETTER VA;Lo;0;L;;;;;N;;;;;\n115AB;SIDDHAM LETTER SHA;Lo;0;L;;;;;N;;;;;\n115AC;SIDDHAM LETTER SSA;Lo;0;L;;;;;N;;;;;\n115AD;SIDDHAM LETTER SA;Lo;0;L;;;;;N;;;;;\n115AE;SIDDHAM LETTER HA;Lo;0;L;;;;;N;;;;;\n115AF;SIDDHAM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n115B0;SIDDHAM VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n115B1;SIDDHAM VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n115B2;SIDDHAM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n115B3;SIDDHAM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n115B4;SIDDHAM VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n115B5;SIDDHAM VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;\n115B8;SIDDHAM VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\n115B9;SIDDHAM VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;\n115BA;SIDDHAM VOWEL SIGN O;Mc;0;L;115B8 115AF;;;;N;;;;;\n115BB;SIDDHAM VOWEL SIGN AU;Mc;0;L;115B9 115AF;;;;N;;;;;\n115BC;SIDDHAM SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n115BD;SIDDHAM SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n115BE;SIDDHAM SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n115BF;SIDDHAM SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n115C0;SIDDHAM SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n115C1;SIDDHAM SIGN SIDDHAM;Po;0;L;;;;;N;;;;;\n115C2;SIDDHAM DANDA;Po;0;L;;;;;N;;;;;\n115C3;SIDDHAM DOUBLE DANDA;Po;0;L;;;;;N;;;;;\n115C4;SIDDHAM SEPARATOR DOT;Po;0;L;;;;;N;;;;;\n115C5;SIDDHAM SEPARATOR BAR;Po;0;L;;;;;N;;;;;\n115C6;SIDDHAM REPETITION MARK-1;Po;0;L;;;;;N;;;;;\n115C7;SIDDHAM REPETITION MARK-2;Po;0;L;;;;;N;;;;;\n115C8;SIDDHAM REPETITION MARK-3;Po;0;L;;;;;N;;;;;\n115C9;SIDDHAM END OF TEXT MARK;Po;0;L;;;;;N;;;;;\n115CA;SIDDHAM SECTION MARK WITH TRIDENT AND U-SHAPED ORNAMENTS;Po;0;L;;;;;N;;;;;\n115CB;SIDDHAM SECTION MARK WITH TRIDENT AND DOTTED CRESCENTS;Po;0;L;;;;;N;;;;;\n115CC;SIDDHAM SECTION MARK WITH RAYS AND DOTTED CRESCENTS;Po;0;L;;;;;N;;;;;\n115CD;SIDDHAM SECTION MARK WITH RAYS AND DOTTED DOUBLE CRESCENTS;Po;0;L;;;;;N;;;;;\n115CE;SIDDHAM SECTION MARK WITH RAYS AND DOTTED TRIPLE CRESCENTS;Po;0;L;;;;;N;;;;;\n115CF;SIDDHAM SECTION MARK DOUBLE RING;Po;0;L;;;;;N;;;;;\n115D0;SIDDHAM SECTION MARK DOUBLE RING WITH RAYS;Po;0;L;;;;;N;;;;;\n115D1;SIDDHAM SECTION MARK WITH DOUBLE CRESCENTS;Po;0;L;;;;;N;;;;;\n115D2;SIDDHAM SECTION MARK WITH TRIPLE CRESCENTS;Po;0;L;;;;;N;;;;;\n115D3;SIDDHAM SECTION MARK WITH QUADRUPLE CRESCENTS;Po;0;L;;;;;N;;;;;\n115D4;SIDDHAM SECTION MARK WITH SEPTUPLE CRESCENTS;Po;0;L;;;;;N;;;;;\n115D5;SIDDHAM SECTION MARK WITH CIRCLES AND RAYS;Po;0;L;;;;;N;;;;;\n115D6;SIDDHAM SECTION MARK WITH CIRCLES AND TWO ENCLOSURES;Po;0;L;;;;;N;;;;;\n115D7;SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES;Po;0;L;;;;;N;;;;;\n115D8;SIDDHAM LETTER THREE-CIRCLE ALTERNATE I;Lo;0;L;;;;;N;;;;;\n115D9;SIDDHAM LETTER TWO-CIRCLE ALTERNATE I;Lo;0;L;;;;;N;;;;;\n115DA;SIDDHAM LETTER TWO-CIRCLE ALTERNATE II;Lo;0;L;;;;;N;;;;;\n115DB;SIDDHAM LETTER ALTERNATE U;Lo;0;L;;;;;N;;;;;\n115DC;SIDDHAM VOWEL SIGN ALTERNATE U;Mn;0;NSM;;;;;N;;;;;\n115DD;SIDDHAM VOWEL SIGN ALTERNATE UU;Mn;0;NSM;;;;;N;;;;;\n11600;MODI LETTER A;Lo;0;L;;;;;N;;;;;\n11601;MODI LETTER AA;Lo;0;L;;;;;N;;;;;\n11602;MODI LETTER I;Lo;0;L;;;;;N;;;;;\n11603;MODI LETTER II;Lo;0;L;;;;;N;;;;;\n11604;MODI LETTER U;Lo;0;L;;;;;N;;;;;\n11605;MODI LETTER UU;Lo;0;L;;;;;N;;;;;\n11606;MODI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n11607;MODI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n11608;MODI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n11609;MODI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;;\n1160A;MODI LETTER E;Lo;0;L;;;;;N;;;;;\n1160B;MODI LETTER AI;Lo;0;L;;;;;N;;;;;\n1160C;MODI LETTER O;Lo;0;L;;;;;N;;;;;\n1160D;MODI LETTER AU;Lo;0;L;;;;;N;;;;;\n1160E;MODI LETTER KA;Lo;0;L;;;;;N;;;;;\n1160F;MODI LETTER KHA;Lo;0;L;;;;;N;;;;;\n11610;MODI LETTER GA;Lo;0;L;;;;;N;;;;;\n11611;MODI LETTER GHA;Lo;0;L;;;;;N;;;;;\n11612;MODI LETTER NGA;Lo;0;L;;;;;N;;;;;\n11613;MODI LETTER CA;Lo;0;L;;;;;N;;;;;\n11614;MODI LETTER CHA;Lo;0;L;;;;;N;;;;;\n11615;MODI LETTER JA;Lo;0;L;;;;;N;;;;;\n11616;MODI LETTER JHA;Lo;0;L;;;;;N;;;;;\n11617;MODI LETTER NYA;Lo;0;L;;;;;N;;;;;\n11618;MODI LETTER TTA;Lo;0;L;;;;;N;;;;;\n11619;MODI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n1161A;MODI LETTER DDA;Lo;0;L;;;;;N;;;;;\n1161B;MODI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n1161C;MODI LETTER NNA;Lo;0;L;;;;;N;;;;;\n1161D;MODI LETTER TA;Lo;0;L;;;;;N;;;;;\n1161E;MODI LETTER THA;Lo;0;L;;;;;N;;;;;\n1161F;MODI LETTER DA;Lo;0;L;;;;;N;;;;;\n11620;MODI LETTER DHA;Lo;0;L;;;;;N;;;;;\n11621;MODI LETTER NA;Lo;0;L;;;;;N;;;;;\n11622;MODI LETTER PA;Lo;0;L;;;;;N;;;;;\n11623;MODI LETTER PHA;Lo;0;L;;;;;N;;;;;\n11624;MODI LETTER BA;Lo;0;L;;;;;N;;;;;\n11625;MODI LETTER BHA;Lo;0;L;;;;;N;;;;;\n11626;MODI LETTER MA;Lo;0;L;;;;;N;;;;;\n11627;MODI LETTER YA;Lo;0;L;;;;;N;;;;;\n11628;MODI LETTER RA;Lo;0;L;;;;;N;;;;;\n11629;MODI LETTER LA;Lo;0;L;;;;;N;;;;;\n1162A;MODI LETTER VA;Lo;0;L;;;;;N;;;;;\n1162B;MODI LETTER SHA;Lo;0;L;;;;;N;;;;;\n1162C;MODI LETTER SSA;Lo;0;L;;;;;N;;;;;\n1162D;MODI LETTER SA;Lo;0;L;;;;;N;;;;;\n1162E;MODI LETTER HA;Lo;0;L;;;;;N;;;;;\n1162F;MODI LETTER LLA;Lo;0;L;;;;;N;;;;;\n11630;MODI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n11631;MODI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n11632;MODI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n11633;MODI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n11634;MODI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n11635;MODI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n11636;MODI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;\n11637;MODI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;\n11638;MODI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;;\n11639;MODI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n1163A;MODI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n1163B;MODI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;\n1163C;MODI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;\n1163D;MODI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n1163E;MODI SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n1163F;MODI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n11640;MODI SIGN ARDHACANDRA;Mn;0;NSM;;;;;N;;;;;\n11641;MODI DANDA;Po;0;L;;;;;N;;;;;\n11642;MODI DOUBLE DANDA;Po;0;L;;;;;N;;;;;\n11643;MODI ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;\n11644;MODI SIGN HUVA;Lo;0;L;;;;;N;;;;;\n11650;MODI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n11651;MODI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n11652;MODI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n11653;MODI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n11654;MODI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n11655;MODI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n11656;MODI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n11657;MODI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n11658;MODI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n11659;MODI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n11660;MONGOLIAN BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;;\n11661;MONGOLIAN ROTATED BIRGA;Po;0;ON;;;;;N;;;;;\n11662;MONGOLIAN DOUBLE BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;;\n11663;MONGOLIAN TRIPLE BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;;\n11664;MONGOLIAN BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;;\n11665;MONGOLIAN ROTATED BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;;\n11666;MONGOLIAN ROTATED BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;;\n11667;MONGOLIAN INVERTED BIRGA;Po;0;ON;;;;;N;;;;;\n11668;MONGOLIAN INVERTED BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;;\n11669;MONGOLIAN SWIRL BIRGA;Po;0;ON;;;;;N;;;;;\n1166A;MONGOLIAN SWIRL BIRGA WITH ORNAMENT;Po;0;ON;;;;;N;;;;;\n1166B;MONGOLIAN SWIRL BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;;\n1166C;MONGOLIAN TURNED SWIRL BIRGA WITH DOUBLE ORNAMENT;Po;0;ON;;;;;N;;;;;\n11680;TAKRI LETTER A;Lo;0;L;;;;;N;;;;;\n11681;TAKRI LETTER AA;Lo;0;L;;;;;N;;;;;\n11682;TAKRI LETTER I;Lo;0;L;;;;;N;;;;;\n11683;TAKRI LETTER II;Lo;0;L;;;;;N;;;;;\n11684;TAKRI LETTER U;Lo;0;L;;;;;N;;;;;\n11685;TAKRI LETTER UU;Lo;0;L;;;;;N;;;;;\n11686;TAKRI LETTER E;Lo;0;L;;;;;N;;;;;\n11687;TAKRI LETTER AI;Lo;0;L;;;;;N;;;;;\n11688;TAKRI LETTER O;Lo;0;L;;;;;N;;;;;\n11689;TAKRI LETTER AU;Lo;0;L;;;;;N;;;;;\n1168A;TAKRI LETTER KA;Lo;0;L;;;;;N;;;;;\n1168B;TAKRI LETTER KHA;Lo;0;L;;;;;N;;;;;\n1168C;TAKRI LETTER GA;Lo;0;L;;;;;N;;;;;\n1168D;TAKRI LETTER GHA;Lo;0;L;;;;;N;;;;;\n1168E;TAKRI LETTER NGA;Lo;0;L;;;;;N;;;;;\n1168F;TAKRI LETTER CA;Lo;0;L;;;;;N;;;;;\n11690;TAKRI LETTER CHA;Lo;0;L;;;;;N;;;;;\n11691;TAKRI LETTER JA;Lo;0;L;;;;;N;;;;;\n11692;TAKRI LETTER JHA;Lo;0;L;;;;;N;;;;;\n11693;TAKRI LETTER NYA;Lo;0;L;;;;;N;;;;;\n11694;TAKRI LETTER TTA;Lo;0;L;;;;;N;;;;;\n11695;TAKRI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n11696;TAKRI LETTER DDA;Lo;0;L;;;;;N;;;;;\n11697;TAKRI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n11698;TAKRI LETTER NNA;Lo;0;L;;;;;N;;;;;\n11699;TAKRI LETTER TA;Lo;0;L;;;;;N;;;;;\n1169A;TAKRI LETTER THA;Lo;0;L;;;;;N;;;;;\n1169B;TAKRI LETTER DA;Lo;0;L;;;;;N;;;;;\n1169C;TAKRI LETTER DHA;Lo;0;L;;;;;N;;;;;\n1169D;TAKRI LETTER NA;Lo;0;L;;;;;N;;;;;\n1169E;TAKRI LETTER PA;Lo;0;L;;;;;N;;;;;\n1169F;TAKRI LETTER PHA;Lo;0;L;;;;;N;;;;;\n116A0;TAKRI LETTER BA;Lo;0;L;;;;;N;;;;;\n116A1;TAKRI LETTER BHA;Lo;0;L;;;;;N;;;;;\n116A2;TAKRI LETTER MA;Lo;0;L;;;;;N;;;;;\n116A3;TAKRI LETTER YA;Lo;0;L;;;;;N;;;;;\n116A4;TAKRI LETTER RA;Lo;0;L;;;;;N;;;;;\n116A5;TAKRI LETTER LA;Lo;0;L;;;;;N;;;;;\n116A6;TAKRI LETTER VA;Lo;0;L;;;;;N;;;;;\n116A7;TAKRI LETTER SHA;Lo;0;L;;;;;N;;;;;\n116A8;TAKRI LETTER SA;Lo;0;L;;;;;N;;;;;\n116A9;TAKRI LETTER HA;Lo;0;L;;;;;N;;;;;\n116AA;TAKRI LETTER RRA;Lo;0;L;;;;;N;;;;;\n116AB;TAKRI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n116AC;TAKRI SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n116AD;TAKRI VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;\n116AE;TAKRI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n116AF;TAKRI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n116B0;TAKRI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n116B1;TAKRI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n116B2;TAKRI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n116B3;TAKRI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n116B4;TAKRI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;\n116B5;TAKRI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;\n116B6;TAKRI SIGN VIRAMA;Mc;9;L;;;;;N;;;;;\n116B7;TAKRI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n116B8;TAKRI LETTER ARCHAIC KHA;Lo;0;L;;;;;N;;;;;\n116C0;TAKRI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n116C1;TAKRI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n116C2;TAKRI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n116C3;TAKRI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n116C4;TAKRI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n116C5;TAKRI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n116C6;TAKRI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n116C7;TAKRI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n116C8;TAKRI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n116C9;TAKRI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n11700;AHOM LETTER KA;Lo;0;L;;;;;N;;;;;\n11701;AHOM LETTER KHA;Lo;0;L;;;;;N;;;;;\n11702;AHOM LETTER NGA;Lo;0;L;;;;;N;;;;;\n11703;AHOM LETTER NA;Lo;0;L;;;;;N;;;;;\n11704;AHOM LETTER TA;Lo;0;L;;;;;N;;;;;\n11705;AHOM LETTER ALTERNATE TA;Lo;0;L;;;;;N;;;;;\n11706;AHOM LETTER PA;Lo;0;L;;;;;N;;;;;\n11707;AHOM LETTER PHA;Lo;0;L;;;;;N;;;;;\n11708;AHOM LETTER BA;Lo;0;L;;;;;N;;;;;\n11709;AHOM LETTER MA;Lo;0;L;;;;;N;;;;;\n1170A;AHOM LETTER JA;Lo;0;L;;;;;N;;;;;\n1170B;AHOM LETTER CHA;Lo;0;L;;;;;N;;;;;\n1170C;AHOM LETTER THA;Lo;0;L;;;;;N;;;;;\n1170D;AHOM LETTER RA;Lo;0;L;;;;;N;;;;;\n1170E;AHOM LETTER LA;Lo;0;L;;;;;N;;;;;\n1170F;AHOM LETTER SA;Lo;0;L;;;;;N;;;;;\n11710;AHOM LETTER NYA;Lo;0;L;;;;;N;;;;;\n11711;AHOM LETTER HA;Lo;0;L;;;;;N;;;;;\n11712;AHOM LETTER A;Lo;0;L;;;;;N;;;;;\n11713;AHOM LETTER DA;Lo;0;L;;;;;N;;;;;\n11714;AHOM LETTER DHA;Lo;0;L;;;;;N;;;;;\n11715;AHOM LETTER GA;Lo;0;L;;;;;N;;;;;\n11716;AHOM LETTER ALTERNATE GA;Lo;0;L;;;;;N;;;;;\n11717;AHOM LETTER GHA;Lo;0;L;;;;;N;;;;;\n11718;AHOM LETTER BHA;Lo;0;L;;;;;N;;;;;\n11719;AHOM LETTER JHA;Lo;0;L;;;;;N;;;;;\n1171A;AHOM LETTER ALTERNATE BA;Lo;0;L;;;;;N;;;;;\n1171D;AHOM CONSONANT SIGN MEDIAL LA;Mn;0;NSM;;;;;N;;;;;\n1171E;AHOM CONSONANT SIGN MEDIAL RA;Mn;0;NSM;;;;;N;;;;;\n1171F;AHOM CONSONANT SIGN MEDIAL LIGATING RA;Mn;0;NSM;;;;;N;;;;;\n11720;AHOM VOWEL SIGN A;Mc;0;L;;;;;N;;;;;\n11721;AHOM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n11722;AHOM VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n11723;AHOM VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;\n11724;AHOM VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n11725;AHOM VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n11726;AHOM VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\n11727;AHOM VOWEL SIGN AW;Mn;0;NSM;;;;;N;;;;;\n11728;AHOM VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;\n11729;AHOM VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n1172A;AHOM VOWEL SIGN AM;Mn;0;NSM;;;;;N;;;;;\n1172B;AHOM SIGN KILLER;Mn;9;NSM;;;;;N;;;;;\n11730;AHOM DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n11731;AHOM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n11732;AHOM DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n11733;AHOM DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n11734;AHOM DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n11735;AHOM DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n11736;AHOM DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n11737;AHOM DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n11738;AHOM DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n11739;AHOM DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n1173A;AHOM NUMBER TEN;No;0;L;;;;10;N;;;;;\n1173B;AHOM NUMBER TWENTY;No;0;L;;;;20;N;;;;;\n1173C;AHOM SIGN SMALL SECTION;Po;0;L;;;;;N;;;;;\n1173D;AHOM SIGN SECTION;Po;0;L;;;;;N;;;;;\n1173E;AHOM SIGN RULAI;Po;0;L;;;;;N;;;;;\n1173F;AHOM SYMBOL VI;So;0;L;;;;;N;;;;;\n11800;DOGRA LETTER A;Lo;0;L;;;;;N;;;;;\n11801;DOGRA LETTER AA;Lo;0;L;;;;;N;;;;;\n11802;DOGRA LETTER I;Lo;0;L;;;;;N;;;;;\n11803;DOGRA LETTER II;Lo;0;L;;;;;N;;;;;\n11804;DOGRA LETTER U;Lo;0;L;;;;;N;;;;;\n11805;DOGRA LETTER UU;Lo;0;L;;;;;N;;;;;\n11806;DOGRA LETTER E;Lo;0;L;;;;;N;;;;;\n11807;DOGRA LETTER AI;Lo;0;L;;;;;N;;;;;\n11808;DOGRA LETTER O;Lo;0;L;;;;;N;;;;;\n11809;DOGRA LETTER AU;Lo;0;L;;;;;N;;;;;\n1180A;DOGRA LETTER KA;Lo;0;L;;;;;N;;;;;\n1180B;DOGRA LETTER KHA;Lo;0;L;;;;;N;;;;;\n1180C;DOGRA LETTER GA;Lo;0;L;;;;;N;;;;;\n1180D;DOGRA LETTER GHA;Lo;0;L;;;;;N;;;;;\n1180E;DOGRA LETTER NGA;Lo;0;L;;;;;N;;;;;\n1180F;DOGRA LETTER CA;Lo;0;L;;;;;N;;;;;\n11810;DOGRA LETTER CHA;Lo;0;L;;;;;N;;;;;\n11811;DOGRA LETTER JA;Lo;0;L;;;;;N;;;;;\n11812;DOGRA LETTER JHA;Lo;0;L;;;;;N;;;;;\n11813;DOGRA LETTER NYA;Lo;0;L;;;;;N;;;;;\n11814;DOGRA LETTER TTA;Lo;0;L;;;;;N;;;;;\n11815;DOGRA LETTER TTHA;Lo;0;L;;;;;N;;;;;\n11816;DOGRA LETTER DDA;Lo;0;L;;;;;N;;;;;\n11817;DOGRA LETTER DDHA;Lo;0;L;;;;;N;;;;;\n11818;DOGRA LETTER NNA;Lo;0;L;;;;;N;;;;;\n11819;DOGRA LETTER TA;Lo;0;L;;;;;N;;;;;\n1181A;DOGRA LETTER THA;Lo;0;L;;;;;N;;;;;\n1181B;DOGRA LETTER DA;Lo;0;L;;;;;N;;;;;\n1181C;DOGRA LETTER DHA;Lo;0;L;;;;;N;;;;;\n1181D;DOGRA LETTER NA;Lo;0;L;;;;;N;;;;;\n1181E;DOGRA LETTER PA;Lo;0;L;;;;;N;;;;;\n1181F;DOGRA LETTER PHA;Lo;0;L;;;;;N;;;;;\n11820;DOGRA LETTER BA;Lo;0;L;;;;;N;;;;;\n11821;DOGRA LETTER BHA;Lo;0;L;;;;;N;;;;;\n11822;DOGRA LETTER MA;Lo;0;L;;;;;N;;;;;\n11823;DOGRA LETTER YA;Lo;0;L;;;;;N;;;;;\n11824;DOGRA LETTER RA;Lo;0;L;;;;;N;;;;;\n11825;DOGRA LETTER LA;Lo;0;L;;;;;N;;;;;\n11826;DOGRA LETTER VA;Lo;0;L;;;;;N;;;;;\n11827;DOGRA LETTER SHA;Lo;0;L;;;;;N;;;;;\n11828;DOGRA LETTER SSA;Lo;0;L;;;;;N;;;;;\n11829;DOGRA LETTER SA;Lo;0;L;;;;;N;;;;;\n1182A;DOGRA LETTER HA;Lo;0;L;;;;;N;;;;;\n1182B;DOGRA LETTER RRA;Lo;0;L;;;;;N;;;;;\n1182C;DOGRA VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n1182D;DOGRA VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n1182E;DOGRA VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n1182F;DOGRA VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n11830;DOGRA VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n11831;DOGRA VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n11832;DOGRA VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;\n11833;DOGRA VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n11834;DOGRA VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n11835;DOGRA VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;\n11836;DOGRA VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;\n11837;DOGRA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n11838;DOGRA SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n11839;DOGRA SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n1183A;DOGRA SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n1183B;DOGRA ABBREVIATION SIGN;Po;0;L;;;;;N;;;;;\n118A0;WARANG CITI CAPITAL LETTER NGAA;Lu;0;L;;;;;N;;;;118C0;\n118A1;WARANG CITI CAPITAL LETTER A;Lu;0;L;;;;;N;;;;118C1;\n118A2;WARANG CITI CAPITAL LETTER WI;Lu;0;L;;;;;N;;;;118C2;\n118A3;WARANG CITI CAPITAL LETTER YU;Lu;0;L;;;;;N;;;;118C3;\n118A4;WARANG CITI CAPITAL LETTER YA;Lu;0;L;;;;;N;;;;118C4;\n118A5;WARANG CITI CAPITAL LETTER YO;Lu;0;L;;;;;N;;;;118C5;\n118A6;WARANG CITI CAPITAL LETTER II;Lu;0;L;;;;;N;;;;118C6;\n118A7;WARANG CITI CAPITAL LETTER UU;Lu;0;L;;;;;N;;;;118C7;\n118A8;WARANG CITI CAPITAL LETTER E;Lu;0;L;;;;;N;;;;118C8;\n118A9;WARANG CITI CAPITAL LETTER O;Lu;0;L;;;;;N;;;;118C9;\n118AA;WARANG CITI CAPITAL LETTER ANG;Lu;0;L;;;;;N;;;;118CA;\n118AB;WARANG CITI CAPITAL LETTER GA;Lu;0;L;;;;;N;;;;118CB;\n118AC;WARANG CITI CAPITAL LETTER KO;Lu;0;L;;;;;N;;;;118CC;\n118AD;WARANG CITI CAPITAL LETTER ENY;Lu;0;L;;;;;N;;;;118CD;\n118AE;WARANG CITI CAPITAL LETTER YUJ;Lu;0;L;;;;;N;;;;118CE;\n118AF;WARANG CITI CAPITAL LETTER UC;Lu;0;L;;;;;N;;;;118CF;\n118B0;WARANG CITI CAPITAL LETTER ENN;Lu;0;L;;;;;N;;;;118D0;\n118B1;WARANG CITI CAPITAL LETTER ODD;Lu;0;L;;;;;N;;;;118D1;\n118B2;WARANG CITI CAPITAL LETTER TTE;Lu;0;L;;;;;N;;;;118D2;\n118B3;WARANG CITI CAPITAL LETTER NUNG;Lu;0;L;;;;;N;;;;118D3;\n118B4;WARANG CITI CAPITAL LETTER DA;Lu;0;L;;;;;N;;;;118D4;\n118B5;WARANG CITI CAPITAL LETTER AT;Lu;0;L;;;;;N;;;;118D5;\n118B6;WARANG CITI CAPITAL LETTER AM;Lu;0;L;;;;;N;;;;118D6;\n118B7;WARANG CITI CAPITAL LETTER BU;Lu;0;L;;;;;N;;;;118D7;\n118B8;WARANG CITI CAPITAL LETTER PU;Lu;0;L;;;;;N;;;;118D8;\n118B9;WARANG CITI CAPITAL LETTER HIYO;Lu;0;L;;;;;N;;;;118D9;\n118BA;WARANG CITI CAPITAL LETTER HOLO;Lu;0;L;;;;;N;;;;118DA;\n118BB;WARANG CITI CAPITAL LETTER HORR;Lu;0;L;;;;;N;;;;118DB;\n118BC;WARANG CITI CAPITAL LETTER HAR;Lu;0;L;;;;;N;;;;118DC;\n118BD;WARANG CITI CAPITAL LETTER SSUU;Lu;0;L;;;;;N;;;;118DD;\n118BE;WARANG CITI CAPITAL LETTER SII;Lu;0;L;;;;;N;;;;118DE;\n118BF;WARANG CITI CAPITAL LETTER VIYO;Lu;0;L;;;;;N;;;;118DF;\n118C0;WARANG CITI SMALL LETTER NGAA;Ll;0;L;;;;;N;;;118A0;;118A0\n118C1;WARANG CITI SMALL LETTER A;Ll;0;L;;;;;N;;;118A1;;118A1\n118C2;WARANG CITI SMALL LETTER WI;Ll;0;L;;;;;N;;;118A2;;118A2\n118C3;WARANG CITI SMALL LETTER YU;Ll;0;L;;;;;N;;;118A3;;118A3\n118C4;WARANG CITI SMALL LETTER YA;Ll;0;L;;;;;N;;;118A4;;118A4\n118C5;WARANG CITI SMALL LETTER YO;Ll;0;L;;;;;N;;;118A5;;118A5\n118C6;WARANG CITI SMALL LETTER II;Ll;0;L;;;;;N;;;118A6;;118A6\n118C7;WARANG CITI SMALL LETTER UU;Ll;0;L;;;;;N;;;118A7;;118A7\n118C8;WARANG CITI SMALL LETTER E;Ll;0;L;;;;;N;;;118A8;;118A8\n118C9;WARANG CITI SMALL LETTER O;Ll;0;L;;;;;N;;;118A9;;118A9\n118CA;WARANG CITI SMALL LETTER ANG;Ll;0;L;;;;;N;;;118AA;;118AA\n118CB;WARANG CITI SMALL LETTER GA;Ll;0;L;;;;;N;;;118AB;;118AB\n118CC;WARANG CITI SMALL LETTER KO;Ll;0;L;;;;;N;;;118AC;;118AC\n118CD;WARANG CITI SMALL LETTER ENY;Ll;0;L;;;;;N;;;118AD;;118AD\n118CE;WARANG CITI SMALL LETTER YUJ;Ll;0;L;;;;;N;;;118AE;;118AE\n118CF;WARANG CITI SMALL LETTER UC;Ll;0;L;;;;;N;;;118AF;;118AF\n118D0;WARANG CITI SMALL LETTER ENN;Ll;0;L;;;;;N;;;118B0;;118B0\n118D1;WARANG CITI SMALL LETTER ODD;Ll;0;L;;;;;N;;;118B1;;118B1\n118D2;WARANG CITI SMALL LETTER TTE;Ll;0;L;;;;;N;;;118B2;;118B2\n118D3;WARANG CITI SMALL LETTER NUNG;Ll;0;L;;;;;N;;;118B3;;118B3\n118D4;WARANG CITI SMALL LETTER DA;Ll;0;L;;;;;N;;;118B4;;118B4\n118D5;WARANG CITI SMALL LETTER AT;Ll;0;L;;;;;N;;;118B5;;118B5\n118D6;WARANG CITI SMALL LETTER AM;Ll;0;L;;;;;N;;;118B6;;118B6\n118D7;WARANG CITI SMALL LETTER BU;Ll;0;L;;;;;N;;;118B7;;118B7\n118D8;WARANG CITI SMALL LETTER PU;Ll;0;L;;;;;N;;;118B8;;118B8\n118D9;WARANG CITI SMALL LETTER HIYO;Ll;0;L;;;;;N;;;118B9;;118B9\n118DA;WARANG CITI SMALL LETTER HOLO;Ll;0;L;;;;;N;;;118BA;;118BA\n118DB;WARANG CITI SMALL LETTER HORR;Ll;0;L;;;;;N;;;118BB;;118BB\n118DC;WARANG CITI SMALL LETTER HAR;Ll;0;L;;;;;N;;;118BC;;118BC\n118DD;WARANG CITI SMALL LETTER SSUU;Ll;0;L;;;;;N;;;118BD;;118BD\n118DE;WARANG CITI SMALL LETTER SII;Ll;0;L;;;;;N;;;118BE;;118BE\n118DF;WARANG CITI SMALL LETTER VIYO;Ll;0;L;;;;;N;;;118BF;;118BF\n118E0;WARANG CITI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n118E1;WARANG CITI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n118E2;WARANG CITI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n118E3;WARANG CITI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n118E4;WARANG CITI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n118E5;WARANG CITI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n118E6;WARANG CITI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n118E7;WARANG CITI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n118E8;WARANG CITI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n118E9;WARANG CITI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n118EA;WARANG CITI NUMBER TEN;No;0;L;;;;10;N;;;;;\n118EB;WARANG CITI NUMBER TWENTY;No;0;L;;;;20;N;;;;;\n118EC;WARANG CITI NUMBER THIRTY;No;0;L;;;;30;N;;;;;\n118ED;WARANG CITI NUMBER FORTY;No;0;L;;;;40;N;;;;;\n118EE;WARANG CITI NUMBER FIFTY;No;0;L;;;;50;N;;;;;\n118EF;WARANG CITI NUMBER SIXTY;No;0;L;;;;60;N;;;;;\n118F0;WARANG CITI NUMBER SEVENTY;No;0;L;;;;70;N;;;;;\n118F1;WARANG CITI NUMBER EIGHTY;No;0;L;;;;80;N;;;;;\n118F2;WARANG CITI NUMBER NINETY;No;0;L;;;;90;N;;;;;\n118FF;WARANG CITI OM;Lo;0;L;;;;;N;;;;;\n119A0;NANDINAGARI LETTER A;Lo;0;L;;;;;N;;;;;\n119A1;NANDINAGARI LETTER AA;Lo;0;L;;;;;N;;;;;\n119A2;NANDINAGARI LETTER I;Lo;0;L;;;;;N;;;;;\n119A3;NANDINAGARI LETTER II;Lo;0;L;;;;;N;;;;;\n119A4;NANDINAGARI LETTER U;Lo;0;L;;;;;N;;;;;\n119A5;NANDINAGARI LETTER UU;Lo;0;L;;;;;N;;;;;\n119A6;NANDINAGARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n119A7;NANDINAGARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n119AA;NANDINAGARI LETTER E;Lo;0;L;;;;;N;;;;;\n119AB;NANDINAGARI LETTER AI;Lo;0;L;;;;;N;;;;;\n119AC;NANDINAGARI LETTER O;Lo;0;L;;;;;N;;;;;\n119AD;NANDINAGARI LETTER AU;Lo;0;L;;;;;N;;;;;\n119AE;NANDINAGARI LETTER KA;Lo;0;L;;;;;N;;;;;\n119AF;NANDINAGARI LETTER KHA;Lo;0;L;;;;;N;;;;;\n119B0;NANDINAGARI LETTER GA;Lo;0;L;;;;;N;;;;;\n119B1;NANDINAGARI LETTER GHA;Lo;0;L;;;;;N;;;;;\n119B2;NANDINAGARI LETTER NGA;Lo;0;L;;;;;N;;;;;\n119B3;NANDINAGARI LETTER CA;Lo;0;L;;;;;N;;;;;\n119B4;NANDINAGARI LETTER CHA;Lo;0;L;;;;;N;;;;;\n119B5;NANDINAGARI LETTER JA;Lo;0;L;;;;;N;;;;;\n119B6;NANDINAGARI LETTER JHA;Lo;0;L;;;;;N;;;;;\n119B7;NANDINAGARI LETTER NYA;Lo;0;L;;;;;N;;;;;\n119B8;NANDINAGARI LETTER TTA;Lo;0;L;;;;;N;;;;;\n119B9;NANDINAGARI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n119BA;NANDINAGARI LETTER DDA;Lo;0;L;;;;;N;;;;;\n119BB;NANDINAGARI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n119BC;NANDINAGARI LETTER NNA;Lo;0;L;;;;;N;;;;;\n119BD;NANDINAGARI LETTER TA;Lo;0;L;;;;;N;;;;;\n119BE;NANDINAGARI LETTER THA;Lo;0;L;;;;;N;;;;;\n119BF;NANDINAGARI LETTER DA;Lo;0;L;;;;;N;;;;;\n119C0;NANDINAGARI LETTER DHA;Lo;0;L;;;;;N;;;;;\n119C1;NANDINAGARI LETTER NA;Lo;0;L;;;;;N;;;;;\n119C2;NANDINAGARI LETTER PA;Lo;0;L;;;;;N;;;;;\n119C3;NANDINAGARI LETTER PHA;Lo;0;L;;;;;N;;;;;\n119C4;NANDINAGARI LETTER BA;Lo;0;L;;;;;N;;;;;\n119C5;NANDINAGARI LETTER BHA;Lo;0;L;;;;;N;;;;;\n119C6;NANDINAGARI LETTER MA;Lo;0;L;;;;;N;;;;;\n119C7;NANDINAGARI LETTER YA;Lo;0;L;;;;;N;;;;;\n119C8;NANDINAGARI LETTER RA;Lo;0;L;;;;;N;;;;;\n119C9;NANDINAGARI LETTER LA;Lo;0;L;;;;;N;;;;;\n119CA;NANDINAGARI LETTER VA;Lo;0;L;;;;;N;;;;;\n119CB;NANDINAGARI LETTER SHA;Lo;0;L;;;;;N;;;;;\n119CC;NANDINAGARI LETTER SSA;Lo;0;L;;;;;N;;;;;\n119CD;NANDINAGARI LETTER SA;Lo;0;L;;;;;N;;;;;\n119CE;NANDINAGARI LETTER HA;Lo;0;L;;;;;N;;;;;\n119CF;NANDINAGARI LETTER LLA;Lo;0;L;;;;;N;;;;;\n119D0;NANDINAGARI LETTER RRA;Lo;0;L;;;;;N;;;;;\n119D1;NANDINAGARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n119D2;NANDINAGARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n119D3;NANDINAGARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n119D4;NANDINAGARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n119D5;NANDINAGARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n119D6;NANDINAGARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n119D7;NANDINAGARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;\n119DA;NANDINAGARI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n119DB;NANDINAGARI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n119DC;NANDINAGARI VOWEL SIGN O;Mc;0;L;;;;;N;;;;;\n119DD;NANDINAGARI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;\n119DE;NANDINAGARI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;;\n119DF;NANDINAGARI SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n119E0;NANDINAGARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n119E1;NANDINAGARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;\n119E2;NANDINAGARI SIGN SIDDHAM;Po;0;L;;;;;N;;;;;\n119E3;NANDINAGARI HEADSTROKE;Lo;0;L;;;;;N;;;;;\n119E4;NANDINAGARI VOWEL SIGN PRISHTHAMATRA E;Mc;0;L;;;;;N;;;;;\n11A00;ZANABAZAR SQUARE LETTER A;Lo;0;L;;;;;N;;;;;\n11A01;ZANABAZAR SQUARE VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n11A02;ZANABAZAR SQUARE VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;\n11A03;ZANABAZAR SQUARE VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n11A04;ZANABAZAR SQUARE VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n11A05;ZANABAZAR SQUARE VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;;\n11A06;ZANABAZAR SQUARE VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;\n11A07;ZANABAZAR SQUARE VOWEL SIGN AI;Mn;0;L;;;;;N;;;;;\n11A08;ZANABAZAR SQUARE VOWEL SIGN AU;Mn;0;L;;;;;N;;;;;\n11A09;ZANABAZAR SQUARE VOWEL SIGN REVERSED I;Mn;0;NSM;;;;;N;;;;;\n11A0A;ZANABAZAR SQUARE VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;;\n11A0B;ZANABAZAR SQUARE LETTER KA;Lo;0;L;;;;;N;;;;;\n11A0C;ZANABAZAR SQUARE LETTER KHA;Lo;0;L;;;;;N;;;;;\n11A0D;ZANABAZAR SQUARE LETTER GA;Lo;0;L;;;;;N;;;;;\n11A0E;ZANABAZAR SQUARE LETTER GHA;Lo;0;L;;;;;N;;;;;\n11A0F;ZANABAZAR SQUARE LETTER NGA;Lo;0;L;;;;;N;;;;;\n11A10;ZANABAZAR SQUARE LETTER CA;Lo;0;L;;;;;N;;;;;\n11A11;ZANABAZAR SQUARE LETTER CHA;Lo;0;L;;;;;N;;;;;\n11A12;ZANABAZAR SQUARE LETTER JA;Lo;0;L;;;;;N;;;;;\n11A13;ZANABAZAR SQUARE LETTER NYA;Lo;0;L;;;;;N;;;;;\n11A14;ZANABAZAR SQUARE LETTER TTA;Lo;0;L;;;;;N;;;;;\n11A15;ZANABAZAR SQUARE LETTER TTHA;Lo;0;L;;;;;N;;;;;\n11A16;ZANABAZAR SQUARE LETTER DDA;Lo;0;L;;;;;N;;;;;\n11A17;ZANABAZAR SQUARE LETTER DDHA;Lo;0;L;;;;;N;;;;;\n11A18;ZANABAZAR SQUARE LETTER NNA;Lo;0;L;;;;;N;;;;;\n11A19;ZANABAZAR SQUARE LETTER TA;Lo;0;L;;;;;N;;;;;\n11A1A;ZANABAZAR SQUARE LETTER THA;Lo;0;L;;;;;N;;;;;\n11A1B;ZANABAZAR SQUARE LETTER DA;Lo;0;L;;;;;N;;;;;\n11A1C;ZANABAZAR SQUARE LETTER DHA;Lo;0;L;;;;;N;;;;;\n11A1D;ZANABAZAR SQUARE LETTER NA;Lo;0;L;;;;;N;;;;;\n11A1E;ZANABAZAR SQUARE LETTER PA;Lo;0;L;;;;;N;;;;;\n11A1F;ZANABAZAR SQUARE LETTER PHA;Lo;0;L;;;;;N;;;;;\n11A20;ZANABAZAR SQUARE LETTER BA;Lo;0;L;;;;;N;;;;;\n11A21;ZANABAZAR SQUARE LETTER BHA;Lo;0;L;;;;;N;;;;;\n11A22;ZANABAZAR SQUARE LETTER MA;Lo;0;L;;;;;N;;;;;\n11A23;ZANABAZAR SQUARE LETTER TSA;Lo;0;L;;;;;N;;;;;\n11A24;ZANABAZAR SQUARE LETTER TSHA;Lo;0;L;;;;;N;;;;;\n11A25;ZANABAZAR SQUARE LETTER DZA;Lo;0;L;;;;;N;;;;;\n11A26;ZANABAZAR SQUARE LETTER DZHA;Lo;0;L;;;;;N;;;;;\n11A27;ZANABAZAR SQUARE LETTER ZHA;Lo;0;L;;;;;N;;;;;\n11A28;ZANABAZAR SQUARE LETTER ZA;Lo;0;L;;;;;N;;;;;\n11A29;ZANABAZAR SQUARE LETTER -A;Lo;0;L;;;;;N;;;;;\n11A2A;ZANABAZAR SQUARE LETTER YA;Lo;0;L;;;;;N;;;;;\n11A2B;ZANABAZAR SQUARE LETTER RA;Lo;0;L;;;;;N;;;;;\n11A2C;ZANABAZAR SQUARE LETTER LA;Lo;0;L;;;;;N;;;;;\n11A2D;ZANABAZAR SQUARE LETTER VA;Lo;0;L;;;;;N;;;;;\n11A2E;ZANABAZAR SQUARE LETTER SHA;Lo;0;L;;;;;N;;;;;\n11A2F;ZANABAZAR SQUARE LETTER SSA;Lo;0;L;;;;;N;;;;;\n11A30;ZANABAZAR SQUARE LETTER SA;Lo;0;L;;;;;N;;;;;\n11A31;ZANABAZAR SQUARE LETTER HA;Lo;0;L;;;;;N;;;;;\n11A32;ZANABAZAR SQUARE LETTER KSSA;Lo;0;L;;;;;N;;;;;\n11A33;ZANABAZAR SQUARE FINAL CONSONANT MARK;Mn;0;NSM;;;;;N;;;;;\n11A34;ZANABAZAR SQUARE SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;;\n11A35;ZANABAZAR SQUARE SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n11A36;ZANABAZAR SQUARE SIGN CANDRABINDU WITH ORNAMENT;Mn;0;NSM;;;;;N;;;;;\n11A37;ZANABAZAR SQUARE SIGN CANDRA WITH ORNAMENT;Mn;0;NSM;;;;;N;;;;;\n11A38;ZANABAZAR SQUARE SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n11A39;ZANABAZAR SQUARE SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n11A3A;ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA;Lo;0;L;;;;;N;;;;;\n11A3B;ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA;Mn;0;NSM;;;;;N;;;;;\n11A3C;ZANABAZAR SQUARE CLUSTER-FINAL LETTER RA;Mn;0;NSM;;;;;N;;;;;\n11A3D;ZANABAZAR SQUARE CLUSTER-FINAL LETTER LA;Mn;0;NSM;;;;;N;;;;;\n11A3E;ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA;Mn;0;NSM;;;;;N;;;;;\n11A3F;ZANABAZAR SQUARE INITIAL HEAD MARK;Po;0;L;;;;;N;;;;;\n11A40;ZANABAZAR SQUARE CLOSING HEAD MARK;Po;0;L;;;;;N;;;;;\n11A41;ZANABAZAR SQUARE MARK TSHEG;Po;0;L;;;;;N;;;;;\n11A42;ZANABAZAR SQUARE MARK SHAD;Po;0;L;;;;;N;;;;;\n11A43;ZANABAZAR SQUARE MARK DOUBLE SHAD;Po;0;L;;;;;N;;;;;\n11A44;ZANABAZAR SQUARE MARK LONG TSHEG;Po;0;L;;;;;N;;;;;\n11A45;ZANABAZAR SQUARE INITIAL DOUBLE-LINED HEAD MARK;Po;0;L;;;;;N;;;;;\n11A46;ZANABAZAR SQUARE CLOSING DOUBLE-LINED HEAD MARK;Po;0;L;;;;;N;;;;;\n11A47;ZANABAZAR SQUARE SUBJOINER;Mn;9;NSM;;;;;N;;;;;\n11A50;SOYOMBO LETTER A;Lo;0;L;;;;;N;;;;;\n11A51;SOYOMBO VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n11A52;SOYOMBO VOWEL SIGN UE;Mn;0;NSM;;;;;N;;;;;\n11A53;SOYOMBO VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n11A54;SOYOMBO VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n11A55;SOYOMBO VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;\n11A56;SOYOMBO VOWEL SIGN OE;Mn;0;NSM;;;;;N;;;;;\n11A57;SOYOMBO VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;\n11A58;SOYOMBO VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;\n11A59;SOYOMBO VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n11A5A;SOYOMBO VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;\n11A5B;SOYOMBO VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;;\n11A5C;SOYOMBO LETTER KA;Lo;0;L;;;;;N;;;;;\n11A5D;SOYOMBO LETTER KHA;Lo;0;L;;;;;N;;;;;\n11A5E;SOYOMBO LETTER GA;Lo;0;L;;;;;N;;;;;\n11A5F;SOYOMBO LETTER GHA;Lo;0;L;;;;;N;;;;;\n11A60;SOYOMBO LETTER NGA;Lo;0;L;;;;;N;;;;;\n11A61;SOYOMBO LETTER CA;Lo;0;L;;;;;N;;;;;\n11A62;SOYOMBO LETTER CHA;Lo;0;L;;;;;N;;;;;\n11A63;SOYOMBO LETTER JA;Lo;0;L;;;;;N;;;;;\n11A64;SOYOMBO LETTER JHA;Lo;0;L;;;;;N;;;;;\n11A65;SOYOMBO LETTER NYA;Lo;0;L;;;;;N;;;;;\n11A66;SOYOMBO LETTER TTA;Lo;0;L;;;;;N;;;;;\n11A67;SOYOMBO LETTER TTHA;Lo;0;L;;;;;N;;;;;\n11A68;SOYOMBO LETTER DDA;Lo;0;L;;;;;N;;;;;\n11A69;SOYOMBO LETTER DDHA;Lo;0;L;;;;;N;;;;;\n11A6A;SOYOMBO LETTER NNA;Lo;0;L;;;;;N;;;;;\n11A6B;SOYOMBO LETTER TA;Lo;0;L;;;;;N;;;;;\n11A6C;SOYOMBO LETTER THA;Lo;0;L;;;;;N;;;;;\n11A6D;SOYOMBO LETTER DA;Lo;0;L;;;;;N;;;;;\n11A6E;SOYOMBO LETTER DHA;Lo;0;L;;;;;N;;;;;\n11A6F;SOYOMBO LETTER NA;Lo;0;L;;;;;N;;;;;\n11A70;SOYOMBO LETTER PA;Lo;0;L;;;;;N;;;;;\n11A71;SOYOMBO LETTER PHA;Lo;0;L;;;;;N;;;;;\n11A72;SOYOMBO LETTER BA;Lo;0;L;;;;;N;;;;;\n11A73;SOYOMBO LETTER BHA;Lo;0;L;;;;;N;;;;;\n11A74;SOYOMBO LETTER MA;Lo;0;L;;;;;N;;;;;\n11A75;SOYOMBO LETTER TSA;Lo;0;L;;;;;N;;;;;\n11A76;SOYOMBO LETTER TSHA;Lo;0;L;;;;;N;;;;;\n11A77;SOYOMBO LETTER DZA;Lo;0;L;;;;;N;;;;;\n11A78;SOYOMBO LETTER ZHA;Lo;0;L;;;;;N;;;;;\n11A79;SOYOMBO LETTER ZA;Lo;0;L;;;;;N;;;;;\n11A7A;SOYOMBO LETTER -A;Lo;0;L;;;;;N;;;;;\n11A7B;SOYOMBO LETTER YA;Lo;0;L;;;;;N;;;;;\n11A7C;SOYOMBO LETTER RA;Lo;0;L;;;;;N;;;;;\n11A7D;SOYOMBO LETTER LA;Lo;0;L;;;;;N;;;;;\n11A7E;SOYOMBO LETTER VA;Lo;0;L;;;;;N;;;;;\n11A7F;SOYOMBO LETTER SHA;Lo;0;L;;;;;N;;;;;\n11A80;SOYOMBO LETTER SSA;Lo;0;L;;;;;N;;;;;\n11A81;SOYOMBO LETTER SA;Lo;0;L;;;;;N;;;;;\n11A82;SOYOMBO LETTER HA;Lo;0;L;;;;;N;;;;;\n11A83;SOYOMBO LETTER KSSA;Lo;0;L;;;;;N;;;;;\n11A84;SOYOMBO SIGN JIHVAMULIYA;Lo;0;L;;;;;N;;;;;\n11A85;SOYOMBO SIGN UPADHMANIYA;Lo;0;L;;;;;N;;;;;\n11A86;SOYOMBO CLUSTER-INITIAL LETTER RA;Lo;0;L;;;;;N;;;;;\n11A87;SOYOMBO CLUSTER-INITIAL LETTER LA;Lo;0;L;;;;;N;;;;;\n11A88;SOYOMBO CLUSTER-INITIAL LETTER SHA;Lo;0;L;;;;;N;;;;;\n11A89;SOYOMBO CLUSTER-INITIAL LETTER SA;Lo;0;L;;;;;N;;;;;\n11A8A;SOYOMBO FINAL CONSONANT SIGN G;Mn;0;NSM;;;;;N;;;;;\n11A8B;SOYOMBO FINAL CONSONANT SIGN K;Mn;0;NSM;;;;;N;;;;;\n11A8C;SOYOMBO FINAL CONSONANT SIGN NG;Mn;0;NSM;;;;;N;;;;;\n11A8D;SOYOMBO FINAL CONSONANT SIGN D;Mn;0;NSM;;;;;N;;;;;\n11A8E;SOYOMBO FINAL CONSONANT SIGN N;Mn;0;NSM;;;;;N;;;;;\n11A8F;SOYOMBO FINAL CONSONANT SIGN B;Mn;0;NSM;;;;;N;;;;;\n11A90;SOYOMBO FINAL CONSONANT SIGN M;Mn;0;NSM;;;;;N;;;;;\n11A91;SOYOMBO FINAL CONSONANT SIGN R;Mn;0;NSM;;;;;N;;;;;\n11A92;SOYOMBO FINAL CONSONANT SIGN L;Mn;0;NSM;;;;;N;;;;;\n11A93;SOYOMBO FINAL CONSONANT SIGN SH;Mn;0;NSM;;;;;N;;;;;\n11A94;SOYOMBO FINAL CONSONANT SIGN S;Mn;0;NSM;;;;;N;;;;;\n11A95;SOYOMBO FINAL CONSONANT SIGN -A;Mn;0;NSM;;;;;N;;;;;\n11A96;SOYOMBO SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n11A97;SOYOMBO SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n11A98;SOYOMBO GEMINATION MARK;Mn;0;NSM;;;;;N;;;;;\n11A99;SOYOMBO SUBJOINER;Mn;9;NSM;;;;;N;;;;;\n11A9A;SOYOMBO MARK TSHEG;Po;0;L;;;;;N;;;;;\n11A9B;SOYOMBO MARK SHAD;Po;0;L;;;;;N;;;;;\n11A9C;SOYOMBO MARK DOUBLE SHAD;Po;0;L;;;;;N;;;;;\n11A9D;SOYOMBO MARK PLUTA;Lo;0;L;;;;;N;;;;;\n11A9E;SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME;Po;0;L;;;;;N;;;;;\n11A9F;SOYOMBO HEAD MARK WITH MOON AND SUN AND FLAME;Po;0;L;;;;;N;;;;;\n11AA0;SOYOMBO HEAD MARK WITH MOON AND SUN;Po;0;L;;;;;N;;;;;\n11AA1;SOYOMBO TERMINAL MARK-1;Po;0;L;;;;;N;;;;;\n11AA2;SOYOMBO TERMINAL MARK-2;Po;0;L;;;;;N;;;;;\n11AC0;PAU CIN HAU LETTER PA;Lo;0;L;;;;;N;;;;;\n11AC1;PAU CIN HAU LETTER KA;Lo;0;L;;;;;N;;;;;\n11AC2;PAU CIN HAU LETTER LA;Lo;0;L;;;;;N;;;;;\n11AC3;PAU CIN HAU LETTER MA;Lo;0;L;;;;;N;;;;;\n11AC4;PAU CIN HAU LETTER DA;Lo;0;L;;;;;N;;;;;\n11AC5;PAU CIN HAU LETTER ZA;Lo;0;L;;;;;N;;;;;\n11AC6;PAU CIN HAU LETTER VA;Lo;0;L;;;;;N;;;;;\n11AC7;PAU CIN HAU LETTER NGA;Lo;0;L;;;;;N;;;;;\n11AC8;PAU CIN HAU LETTER HA;Lo;0;L;;;;;N;;;;;\n11AC9;PAU CIN HAU LETTER GA;Lo;0;L;;;;;N;;;;;\n11ACA;PAU CIN HAU LETTER KHA;Lo;0;L;;;;;N;;;;;\n11ACB;PAU CIN HAU LETTER SA;Lo;0;L;;;;;N;;;;;\n11ACC;PAU CIN HAU LETTER BA;Lo;0;L;;;;;N;;;;;\n11ACD;PAU CIN HAU LETTER CA;Lo;0;L;;;;;N;;;;;\n11ACE;PAU CIN HAU LETTER TA;Lo;0;L;;;;;N;;;;;\n11ACF;PAU CIN HAU LETTER THA;Lo;0;L;;;;;N;;;;;\n11AD0;PAU CIN HAU LETTER NA;Lo;0;L;;;;;N;;;;;\n11AD1;PAU CIN HAU LETTER PHA;Lo;0;L;;;;;N;;;;;\n11AD2;PAU CIN HAU LETTER RA;Lo;0;L;;;;;N;;;;;\n11AD3;PAU CIN HAU LETTER FA;Lo;0;L;;;;;N;;;;;\n11AD4;PAU CIN HAU LETTER CHA;Lo;0;L;;;;;N;;;;;\n11AD5;PAU CIN HAU LETTER A;Lo;0;L;;;;;N;;;;;\n11AD6;PAU CIN HAU LETTER E;Lo;0;L;;;;;N;;;;;\n11AD7;PAU CIN HAU LETTER I;Lo;0;L;;;;;N;;;;;\n11AD8;PAU CIN HAU LETTER O;Lo;0;L;;;;;N;;;;;\n11AD9;PAU CIN HAU LETTER U;Lo;0;L;;;;;N;;;;;\n11ADA;PAU CIN HAU LETTER UA;Lo;0;L;;;;;N;;;;;\n11ADB;PAU CIN HAU LETTER IA;Lo;0;L;;;;;N;;;;;\n11ADC;PAU CIN HAU LETTER FINAL P;Lo;0;L;;;;;N;;;;;\n11ADD;PAU CIN HAU LETTER FINAL K;Lo;0;L;;;;;N;;;;;\n11ADE;PAU CIN HAU LETTER FINAL T;Lo;0;L;;;;;N;;;;;\n11ADF;PAU CIN HAU LETTER FINAL M;Lo;0;L;;;;;N;;;;;\n11AE0;PAU CIN HAU LETTER FINAL N;Lo;0;L;;;;;N;;;;;\n11AE1;PAU CIN HAU LETTER FINAL L;Lo;0;L;;;;;N;;;;;\n11AE2;PAU CIN HAU LETTER FINAL W;Lo;0;L;;;;;N;;;;;\n11AE3;PAU CIN HAU LETTER FINAL NG;Lo;0;L;;;;;N;;;;;\n11AE4;PAU CIN HAU LETTER FINAL Y;Lo;0;L;;;;;N;;;;;\n11AE5;PAU CIN HAU RISING TONE LONG;Lo;0;L;;;;;N;;;;;\n11AE6;PAU CIN HAU RISING TONE;Lo;0;L;;;;;N;;;;;\n11AE7;PAU CIN HAU SANDHI GLOTTAL STOP;Lo;0;L;;;;;N;;;;;\n11AE8;PAU CIN HAU RISING TONE LONG FINAL;Lo;0;L;;;;;N;;;;;\n11AE9;PAU CIN HAU RISING TONE FINAL;Lo;0;L;;;;;N;;;;;\n11AEA;PAU CIN HAU SANDHI GLOTTAL STOP FINAL;Lo;0;L;;;;;N;;;;;\n11AEB;PAU CIN HAU SANDHI TONE LONG;Lo;0;L;;;;;N;;;;;\n11AEC;PAU CIN HAU SANDHI TONE;Lo;0;L;;;;;N;;;;;\n11AED;PAU CIN HAU SANDHI TONE LONG FINAL;Lo;0;L;;;;;N;;;;;\n11AEE;PAU CIN HAU SANDHI TONE FINAL;Lo;0;L;;;;;N;;;;;\n11AEF;PAU CIN HAU MID-LEVEL TONE;Lo;0;L;;;;;N;;;;;\n11AF0;PAU CIN HAU GLOTTAL STOP VARIANT;Lo;0;L;;;;;N;;;;;\n11AF1;PAU CIN HAU MID-LEVEL TONE LONG FINAL;Lo;0;L;;;;;N;;;;;\n11AF2;PAU CIN HAU MID-LEVEL TONE FINAL;Lo;0;L;;;;;N;;;;;\n11AF3;PAU CIN HAU LOW-FALLING TONE LONG;Lo;0;L;;;;;N;;;;;\n11AF4;PAU CIN HAU LOW-FALLING TONE;Lo;0;L;;;;;N;;;;;\n11AF5;PAU CIN HAU GLOTTAL STOP;Lo;0;L;;;;;N;;;;;\n11AF6;PAU CIN HAU LOW-FALLING TONE LONG FINAL;Lo;0;L;;;;;N;;;;;\n11AF7;PAU CIN HAU LOW-FALLING TONE FINAL;Lo;0;L;;;;;N;;;;;\n11AF8;PAU CIN HAU GLOTTAL STOP FINAL;Lo;0;L;;;;;N;;;;;\n11C00;BHAIKSUKI LETTER A;Lo;0;L;;;;;N;;;;;\n11C01;BHAIKSUKI LETTER AA;Lo;0;L;;;;;N;;;;;\n11C02;BHAIKSUKI LETTER I;Lo;0;L;;;;;N;;;;;\n11C03;BHAIKSUKI LETTER II;Lo;0;L;;;;;N;;;;;\n11C04;BHAIKSUKI LETTER U;Lo;0;L;;;;;N;;;;;\n11C05;BHAIKSUKI LETTER UU;Lo;0;L;;;;;N;;;;;\n11C06;BHAIKSUKI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;;\n11C07;BHAIKSUKI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;;\n11C08;BHAIKSUKI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;;\n11C0A;BHAIKSUKI LETTER E;Lo;0;L;;;;;N;;;;;\n11C0B;BHAIKSUKI LETTER AI;Lo;0;L;;;;;N;;;;;\n11C0C;BHAIKSUKI LETTER O;Lo;0;L;;;;;N;;;;;\n11C0D;BHAIKSUKI LETTER AU;Lo;0;L;;;;;N;;;;;\n11C0E;BHAIKSUKI LETTER KA;Lo;0;L;;;;;N;;;;;\n11C0F;BHAIKSUKI LETTER KHA;Lo;0;L;;;;;N;;;;;\n11C10;BHAIKSUKI LETTER GA;Lo;0;L;;;;;N;;;;;\n11C11;BHAIKSUKI LETTER GHA;Lo;0;L;;;;;N;;;;;\n11C12;BHAIKSUKI LETTER NGA;Lo;0;L;;;;;N;;;;;\n11C13;BHAIKSUKI LETTER CA;Lo;0;L;;;;;N;;;;;\n11C14;BHAIKSUKI LETTER CHA;Lo;0;L;;;;;N;;;;;\n11C15;BHAIKSUKI LETTER JA;Lo;0;L;;;;;N;;;;;\n11C16;BHAIKSUKI LETTER JHA;Lo;0;L;;;;;N;;;;;\n11C17;BHAIKSUKI LETTER NYA;Lo;0;L;;;;;N;;;;;\n11C18;BHAIKSUKI LETTER TTA;Lo;0;L;;;;;N;;;;;\n11C19;BHAIKSUKI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n11C1A;BHAIKSUKI LETTER DDA;Lo;0;L;;;;;N;;;;;\n11C1B;BHAIKSUKI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n11C1C;BHAIKSUKI LETTER NNA;Lo;0;L;;;;;N;;;;;\n11C1D;BHAIKSUKI LETTER TA;Lo;0;L;;;;;N;;;;;\n11C1E;BHAIKSUKI LETTER THA;Lo;0;L;;;;;N;;;;;\n11C1F;BHAIKSUKI LETTER DA;Lo;0;L;;;;;N;;;;;\n11C20;BHAIKSUKI LETTER DHA;Lo;0;L;;;;;N;;;;;\n11C21;BHAIKSUKI LETTER NA;Lo;0;L;;;;;N;;;;;\n11C22;BHAIKSUKI LETTER PA;Lo;0;L;;;;;N;;;;;\n11C23;BHAIKSUKI LETTER PHA;Lo;0;L;;;;;N;;;;;\n11C24;BHAIKSUKI LETTER BA;Lo;0;L;;;;;N;;;;;\n11C25;BHAIKSUKI LETTER BHA;Lo;0;L;;;;;N;;;;;\n11C26;BHAIKSUKI LETTER MA;Lo;0;L;;;;;N;;;;;\n11C27;BHAIKSUKI LETTER YA;Lo;0;L;;;;;N;;;;;\n11C28;BHAIKSUKI LETTER RA;Lo;0;L;;;;;N;;;;;\n11C29;BHAIKSUKI LETTER LA;Lo;0;L;;;;;N;;;;;\n11C2A;BHAIKSUKI LETTER VA;Lo;0;L;;;;;N;;;;;\n11C2B;BHAIKSUKI LETTER SHA;Lo;0;L;;;;;N;;;;;\n11C2C;BHAIKSUKI LETTER SSA;Lo;0;L;;;;;N;;;;;\n11C2D;BHAIKSUKI LETTER SA;Lo;0;L;;;;;N;;;;;\n11C2E;BHAIKSUKI LETTER HA;Lo;0;L;;;;;N;;;;;\n11C2F;BHAIKSUKI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n11C30;BHAIKSUKI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n11C31;BHAIKSUKI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;\n11C32;BHAIKSUKI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n11C33;BHAIKSUKI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n11C34;BHAIKSUKI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n11C35;BHAIKSUKI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;;\n11C36;BHAIKSUKI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;;\n11C38;BHAIKSUKI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n11C39;BHAIKSUKI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n11C3A;BHAIKSUKI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;\n11C3B;BHAIKSUKI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;\n11C3C;BHAIKSUKI SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n11C3D;BHAIKSUKI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n11C3E;BHAIKSUKI SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n11C3F;BHAIKSUKI SIGN VIRAMA;Mn;9;L;;;;;N;;;;;\n11C40;BHAIKSUKI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;;\n11C41;BHAIKSUKI DANDA;Po;0;L;;;;;N;;;;;\n11C42;BHAIKSUKI DOUBLE DANDA;Po;0;L;;;;;N;;;;;\n11C43;BHAIKSUKI WORD SEPARATOR;Po;0;L;;;;;N;;;;;\n11C44;BHAIKSUKI GAP FILLER-1;Po;0;L;;;;;N;;;;;\n11C45;BHAIKSUKI GAP FILLER-2;Po;0;L;;;;;N;;;;;\n11C50;BHAIKSUKI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n11C51;BHAIKSUKI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n11C52;BHAIKSUKI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n11C53;BHAIKSUKI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n11C54;BHAIKSUKI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n11C55;BHAIKSUKI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n11C56;BHAIKSUKI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n11C57;BHAIKSUKI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n11C58;BHAIKSUKI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n11C59;BHAIKSUKI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n11C5A;BHAIKSUKI NUMBER ONE;No;0;L;;;;1;N;;;;;\n11C5B;BHAIKSUKI NUMBER TWO;No;0;L;;;;2;N;;;;;\n11C5C;BHAIKSUKI NUMBER THREE;No;0;L;;;;3;N;;;;;\n11C5D;BHAIKSUKI NUMBER FOUR;No;0;L;;;;4;N;;;;;\n11C5E;BHAIKSUKI NUMBER FIVE;No;0;L;;;;5;N;;;;;\n11C5F;BHAIKSUKI NUMBER SIX;No;0;L;;;;6;N;;;;;\n11C60;BHAIKSUKI NUMBER SEVEN;No;0;L;;;;7;N;;;;;\n11C61;BHAIKSUKI NUMBER EIGHT;No;0;L;;;;8;N;;;;;\n11C62;BHAIKSUKI NUMBER NINE;No;0;L;;;;9;N;;;;;\n11C63;BHAIKSUKI NUMBER TEN;No;0;L;;;;10;N;;;;;\n11C64;BHAIKSUKI NUMBER TWENTY;No;0;L;;;;20;N;;;;;\n11C65;BHAIKSUKI NUMBER THIRTY;No;0;L;;;;30;N;;;;;\n11C66;BHAIKSUKI NUMBER FORTY;No;0;L;;;;40;N;;;;;\n11C67;BHAIKSUKI NUMBER FIFTY;No;0;L;;;;50;N;;;;;\n11C68;BHAIKSUKI NUMBER SIXTY;No;0;L;;;;60;N;;;;;\n11C69;BHAIKSUKI NUMBER SEVENTY;No;0;L;;;;70;N;;;;;\n11C6A;BHAIKSUKI NUMBER EIGHTY;No;0;L;;;;80;N;;;;;\n11C6B;BHAIKSUKI NUMBER NINETY;No;0;L;;;;90;N;;;;;\n11C6C;BHAIKSUKI HUNDREDS UNIT MARK;No;0;L;;;;100;N;;;;;\n11C70;MARCHEN HEAD MARK;Po;0;L;;;;;N;;;;;\n11C71;MARCHEN MARK SHAD;Po;0;L;;;;;N;;;;;\n11C72;MARCHEN LETTER KA;Lo;0;L;;;;;N;;;;;\n11C73;MARCHEN LETTER KHA;Lo;0;L;;;;;N;;;;;\n11C74;MARCHEN LETTER GA;Lo;0;L;;;;;N;;;;;\n11C75;MARCHEN LETTER NGA;Lo;0;L;;;;;N;;;;;\n11C76;MARCHEN LETTER CA;Lo;0;L;;;;;N;;;;;\n11C77;MARCHEN LETTER CHA;Lo;0;L;;;;;N;;;;;\n11C78;MARCHEN LETTER JA;Lo;0;L;;;;;N;;;;;\n11C79;MARCHEN LETTER NYA;Lo;0;L;;;;;N;;;;;\n11C7A;MARCHEN LETTER TA;Lo;0;L;;;;;N;;;;;\n11C7B;MARCHEN LETTER THA;Lo;0;L;;;;;N;;;;;\n11C7C;MARCHEN LETTER DA;Lo;0;L;;;;;N;;;;;\n11C7D;MARCHEN LETTER NA;Lo;0;L;;;;;N;;;;;\n11C7E;MARCHEN LETTER PA;Lo;0;L;;;;;N;;;;;\n11C7F;MARCHEN LETTER PHA;Lo;0;L;;;;;N;;;;;\n11C80;MARCHEN LETTER BA;Lo;0;L;;;;;N;;;;;\n11C81;MARCHEN LETTER MA;Lo;0;L;;;;;N;;;;;\n11C82;MARCHEN LETTER TSA;Lo;0;L;;;;;N;;;;;\n11C83;MARCHEN LETTER TSHA;Lo;0;L;;;;;N;;;;;\n11C84;MARCHEN LETTER DZA;Lo;0;L;;;;;N;;;;;\n11C85;MARCHEN LETTER WA;Lo;0;L;;;;;N;;;;;\n11C86;MARCHEN LETTER ZHA;Lo;0;L;;;;;N;;;;;\n11C87;MARCHEN LETTER ZA;Lo;0;L;;;;;N;;;;;\n11C88;MARCHEN LETTER -A;Lo;0;L;;;;;N;;;;;\n11C89;MARCHEN LETTER YA;Lo;0;L;;;;;N;;;;;\n11C8A;MARCHEN LETTER RA;Lo;0;L;;;;;N;;;;;\n11C8B;MARCHEN LETTER LA;Lo;0;L;;;;;N;;;;;\n11C8C;MARCHEN LETTER SHA;Lo;0;L;;;;;N;;;;;\n11C8D;MARCHEN LETTER SA;Lo;0;L;;;;;N;;;;;\n11C8E;MARCHEN LETTER HA;Lo;0;L;;;;;N;;;;;\n11C8F;MARCHEN LETTER A;Lo;0;L;;;;;N;;;;;\n11C92;MARCHEN SUBJOINED LETTER KA;Mn;0;NSM;;;;;N;;;;;\n11C93;MARCHEN SUBJOINED LETTER KHA;Mn;0;NSM;;;;;N;;;;;\n11C94;MARCHEN SUBJOINED LETTER GA;Mn;0;NSM;;;;;N;;;;;\n11C95;MARCHEN SUBJOINED LETTER NGA;Mn;0;NSM;;;;;N;;;;;\n11C96;MARCHEN SUBJOINED LETTER CA;Mn;0;NSM;;;;;N;;;;;\n11C97;MARCHEN SUBJOINED LETTER CHA;Mn;0;NSM;;;;;N;;;;;\n11C98;MARCHEN SUBJOINED LETTER JA;Mn;0;NSM;;;;;N;;;;;\n11C99;MARCHEN SUBJOINED LETTER NYA;Mn;0;NSM;;;;;N;;;;;\n11C9A;MARCHEN SUBJOINED LETTER TA;Mn;0;NSM;;;;;N;;;;;\n11C9B;MARCHEN SUBJOINED LETTER THA;Mn;0;NSM;;;;;N;;;;;\n11C9C;MARCHEN SUBJOINED LETTER DA;Mn;0;NSM;;;;;N;;;;;\n11C9D;MARCHEN SUBJOINED LETTER NA;Mn;0;NSM;;;;;N;;;;;\n11C9E;MARCHEN SUBJOINED LETTER PA;Mn;0;NSM;;;;;N;;;;;\n11C9F;MARCHEN SUBJOINED LETTER PHA;Mn;0;NSM;;;;;N;;;;;\n11CA0;MARCHEN SUBJOINED LETTER BA;Mn;0;NSM;;;;;N;;;;;\n11CA1;MARCHEN SUBJOINED LETTER MA;Mn;0;NSM;;;;;N;;;;;\n11CA2;MARCHEN SUBJOINED LETTER TSA;Mn;0;NSM;;;;;N;;;;;\n11CA3;MARCHEN SUBJOINED LETTER TSHA;Mn;0;NSM;;;;;N;;;;;\n11CA4;MARCHEN SUBJOINED LETTER DZA;Mn;0;NSM;;;;;N;;;;;\n11CA5;MARCHEN SUBJOINED LETTER WA;Mn;0;NSM;;;;;N;;;;;\n11CA6;MARCHEN SUBJOINED LETTER ZHA;Mn;0;NSM;;;;;N;;;;;\n11CA7;MARCHEN SUBJOINED LETTER ZA;Mn;0;NSM;;;;;N;;;;;\n11CA9;MARCHEN SUBJOINED LETTER YA;Mc;0;L;;;;;N;;;;;\n11CAA;MARCHEN SUBJOINED LETTER RA;Mn;0;NSM;;;;;N;;;;;\n11CAB;MARCHEN SUBJOINED LETTER LA;Mn;0;NSM;;;;;N;;;;;\n11CAC;MARCHEN SUBJOINED LETTER SHA;Mn;0;NSM;;;;;N;;;;;\n11CAD;MARCHEN SUBJOINED LETTER SA;Mn;0;NSM;;;;;N;;;;;\n11CAE;MARCHEN SUBJOINED LETTER HA;Mn;0;NSM;;;;;N;;;;;\n11CAF;MARCHEN SUBJOINED LETTER A;Mn;0;NSM;;;;;N;;;;;\n11CB0;MARCHEN VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;\n11CB1;MARCHEN VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n11CB2;MARCHEN VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n11CB3;MARCHEN VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n11CB4;MARCHEN VOWEL SIGN O;Mc;0;L;;;;;N;;;;;\n11CB5;MARCHEN SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n11CB6;MARCHEN SIGN CANDRABINDU;Mn;0;NSM;;;;;N;;;;;\n11D00;MASARAM GONDI LETTER A;Lo;0;L;;;;;N;;;;;\n11D01;MASARAM GONDI LETTER AA;Lo;0;L;;;;;N;;;;;\n11D02;MASARAM GONDI LETTER I;Lo;0;L;;;;;N;;;;;\n11D03;MASARAM GONDI LETTER II;Lo;0;L;;;;;N;;;;;\n11D04;MASARAM GONDI LETTER U;Lo;0;L;;;;;N;;;;;\n11D05;MASARAM GONDI LETTER UU;Lo;0;L;;;;;N;;;;;\n11D06;MASARAM GONDI LETTER E;Lo;0;L;;;;;N;;;;;\n11D08;MASARAM GONDI LETTER AI;Lo;0;L;;;;;N;;;;;\n11D09;MASARAM GONDI LETTER O;Lo;0;L;;;;;N;;;;;\n11D0B;MASARAM GONDI LETTER AU;Lo;0;L;;;;;N;;;;;\n11D0C;MASARAM GONDI LETTER KA;Lo;0;L;;;;;N;;;;;\n11D0D;MASARAM GONDI LETTER KHA;Lo;0;L;;;;;N;;;;;\n11D0E;MASARAM GONDI LETTER GA;Lo;0;L;;;;;N;;;;;\n11D0F;MASARAM GONDI LETTER GHA;Lo;0;L;;;;;N;;;;;\n11D10;MASARAM GONDI LETTER NGA;Lo;0;L;;;;;N;;;;;\n11D11;MASARAM GONDI LETTER CA;Lo;0;L;;;;;N;;;;;\n11D12;MASARAM GONDI LETTER CHA;Lo;0;L;;;;;N;;;;;\n11D13;MASARAM GONDI LETTER JA;Lo;0;L;;;;;N;;;;;\n11D14;MASARAM GONDI LETTER JHA;Lo;0;L;;;;;N;;;;;\n11D15;MASARAM GONDI LETTER NYA;Lo;0;L;;;;;N;;;;;\n11D16;MASARAM GONDI LETTER TTA;Lo;0;L;;;;;N;;;;;\n11D17;MASARAM GONDI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n11D18;MASARAM GONDI LETTER DDA;Lo;0;L;;;;;N;;;;;\n11D19;MASARAM GONDI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n11D1A;MASARAM GONDI LETTER NNA;Lo;0;L;;;;;N;;;;;\n11D1B;MASARAM GONDI LETTER TA;Lo;0;L;;;;;N;;;;;\n11D1C;MASARAM GONDI LETTER THA;Lo;0;L;;;;;N;;;;;\n11D1D;MASARAM GONDI LETTER DA;Lo;0;L;;;;;N;;;;;\n11D1E;MASARAM GONDI LETTER DHA;Lo;0;L;;;;;N;;;;;\n11D1F;MASARAM GONDI LETTER NA;Lo;0;L;;;;;N;;;;;\n11D20;MASARAM GONDI LETTER PA;Lo;0;L;;;;;N;;;;;\n11D21;MASARAM GONDI LETTER PHA;Lo;0;L;;;;;N;;;;;\n11D22;MASARAM GONDI LETTER BA;Lo;0;L;;;;;N;;;;;\n11D23;MASARAM GONDI LETTER BHA;Lo;0;L;;;;;N;;;;;\n11D24;MASARAM GONDI LETTER MA;Lo;0;L;;;;;N;;;;;\n11D25;MASARAM GONDI LETTER YA;Lo;0;L;;;;;N;;;;;\n11D26;MASARAM GONDI LETTER RA;Lo;0;L;;;;;N;;;;;\n11D27;MASARAM GONDI LETTER LA;Lo;0;L;;;;;N;;;;;\n11D28;MASARAM GONDI LETTER VA;Lo;0;L;;;;;N;;;;;\n11D29;MASARAM GONDI LETTER SHA;Lo;0;L;;;;;N;;;;;\n11D2A;MASARAM GONDI LETTER SSA;Lo;0;L;;;;;N;;;;;\n11D2B;MASARAM GONDI LETTER SA;Lo;0;L;;;;;N;;;;;\n11D2C;MASARAM GONDI LETTER HA;Lo;0;L;;;;;N;;;;;\n11D2D;MASARAM GONDI LETTER LLA;Lo;0;L;;;;;N;;;;;\n11D2E;MASARAM GONDI LETTER KSSA;Lo;0;L;;;;;N;;;;;\n11D2F;MASARAM GONDI LETTER JNYA;Lo;0;L;;;;;N;;;;;\n11D30;MASARAM GONDI LETTER TRA;Lo;0;L;;;;;N;;;;;\n11D31;MASARAM GONDI VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;;\n11D32;MASARAM GONDI VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n11D33;MASARAM GONDI VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;;\n11D34;MASARAM GONDI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n11D35;MASARAM GONDI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;;\n11D36;MASARAM GONDI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;;\n11D3A;MASARAM GONDI VOWEL SIGN E;Mn;0;NSM;;;;;N;;;;;\n11D3C;MASARAM GONDI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n11D3D;MASARAM GONDI VOWEL SIGN O;Mn;0;NSM;;;;;N;;;;;\n11D3F;MASARAM GONDI VOWEL SIGN AU;Mn;0;NSM;;;;;N;;;;;\n11D40;MASARAM GONDI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n11D41;MASARAM GONDI SIGN VISARGA;Mn;0;NSM;;;;;N;;;;;\n11D42;MASARAM GONDI SIGN NUKTA;Mn;7;NSM;;;;;N;;;;;\n11D43;MASARAM GONDI SIGN CANDRA;Mn;0;NSM;;;;;N;;;;;\n11D44;MASARAM GONDI SIGN HALANTA;Mn;9;NSM;;;;;N;;;;;\n11D45;MASARAM GONDI VIRAMA;Mn;9;NSM;;;;;N;;;;;\n11D46;MASARAM GONDI REPHA;Lo;0;L;;;;;N;;;;;\n11D47;MASARAM GONDI RA-KARA;Mn;0;NSM;;;;;N;;;;;\n11D50;MASARAM GONDI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n11D51;MASARAM GONDI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n11D52;MASARAM GONDI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n11D53;MASARAM GONDI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n11D54;MASARAM GONDI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n11D55;MASARAM GONDI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n11D56;MASARAM GONDI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n11D57;MASARAM GONDI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n11D58;MASARAM GONDI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n11D59;MASARAM GONDI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n11D60;GUNJALA GONDI LETTER A;Lo;0;L;;;;;N;;;;;\n11D61;GUNJALA GONDI LETTER AA;Lo;0;L;;;;;N;;;;;\n11D62;GUNJALA GONDI LETTER I;Lo;0;L;;;;;N;;;;;\n11D63;GUNJALA GONDI LETTER II;Lo;0;L;;;;;N;;;;;\n11D64;GUNJALA GONDI LETTER U;Lo;0;L;;;;;N;;;;;\n11D65;GUNJALA GONDI LETTER UU;Lo;0;L;;;;;N;;;;;\n11D67;GUNJALA GONDI LETTER EE;Lo;0;L;;;;;N;;;;;\n11D68;GUNJALA GONDI LETTER AI;Lo;0;L;;;;;N;;;;;\n11D6A;GUNJALA GONDI LETTER OO;Lo;0;L;;;;;N;;;;;\n11D6B;GUNJALA GONDI LETTER AU;Lo;0;L;;;;;N;;;;;\n11D6C;GUNJALA GONDI LETTER YA;Lo;0;L;;;;;N;;;;;\n11D6D;GUNJALA GONDI LETTER VA;Lo;0;L;;;;;N;;;;;\n11D6E;GUNJALA GONDI LETTER BA;Lo;0;L;;;;;N;;;;;\n11D6F;GUNJALA GONDI LETTER BHA;Lo;0;L;;;;;N;;;;;\n11D70;GUNJALA GONDI LETTER MA;Lo;0;L;;;;;N;;;;;\n11D71;GUNJALA GONDI LETTER KA;Lo;0;L;;;;;N;;;;;\n11D72;GUNJALA GONDI LETTER KHA;Lo;0;L;;;;;N;;;;;\n11D73;GUNJALA GONDI LETTER TA;Lo;0;L;;;;;N;;;;;\n11D74;GUNJALA GONDI LETTER THA;Lo;0;L;;;;;N;;;;;\n11D75;GUNJALA GONDI LETTER LA;Lo;0;L;;;;;N;;;;;\n11D76;GUNJALA GONDI LETTER GA;Lo;0;L;;;;;N;;;;;\n11D77;GUNJALA GONDI LETTER GHA;Lo;0;L;;;;;N;;;;;\n11D78;GUNJALA GONDI LETTER DA;Lo;0;L;;;;;N;;;;;\n11D79;GUNJALA GONDI LETTER DHA;Lo;0;L;;;;;N;;;;;\n11D7A;GUNJALA GONDI LETTER NA;Lo;0;L;;;;;N;;;;;\n11D7B;GUNJALA GONDI LETTER CA;Lo;0;L;;;;;N;;;;;\n11D7C;GUNJALA GONDI LETTER CHA;Lo;0;L;;;;;N;;;;;\n11D7D;GUNJALA GONDI LETTER TTA;Lo;0;L;;;;;N;;;;;\n11D7E;GUNJALA GONDI LETTER TTHA;Lo;0;L;;;;;N;;;;;\n11D7F;GUNJALA GONDI LETTER LLA;Lo;0;L;;;;;N;;;;;\n11D80;GUNJALA GONDI LETTER JA;Lo;0;L;;;;;N;;;;;\n11D81;GUNJALA GONDI LETTER JHA;Lo;0;L;;;;;N;;;;;\n11D82;GUNJALA GONDI LETTER DDA;Lo;0;L;;;;;N;;;;;\n11D83;GUNJALA GONDI LETTER DDHA;Lo;0;L;;;;;N;;;;;\n11D84;GUNJALA GONDI LETTER NGA;Lo;0;L;;;;;N;;;;;\n11D85;GUNJALA GONDI LETTER PA;Lo;0;L;;;;;N;;;;;\n11D86;GUNJALA GONDI LETTER PHA;Lo;0;L;;;;;N;;;;;\n11D87;GUNJALA GONDI LETTER HA;Lo;0;L;;;;;N;;;;;\n11D88;GUNJALA GONDI LETTER RA;Lo;0;L;;;;;N;;;;;\n11D89;GUNJALA GONDI LETTER SA;Lo;0;L;;;;;N;;;;;\n11D8A;GUNJALA GONDI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n11D8B;GUNJALA GONDI VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n11D8C;GUNJALA GONDI VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n11D8D;GUNJALA GONDI VOWEL SIGN U;Mc;0;L;;;;;N;;;;;\n11D8E;GUNJALA GONDI VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;\n11D90;GUNJALA GONDI VOWEL SIGN EE;Mn;0;NSM;;;;;N;;;;;\n11D91;GUNJALA GONDI VOWEL SIGN AI;Mn;0;NSM;;;;;N;;;;;\n11D93;GUNJALA GONDI VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;\n11D94;GUNJALA GONDI VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;\n11D95;GUNJALA GONDI SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;;\n11D96;GUNJALA GONDI SIGN VISARGA;Mc;0;L;;;;;N;;;;;\n11D97;GUNJALA GONDI VIRAMA;Mn;9;NSM;;;;;N;;;;;\n11D98;GUNJALA GONDI OM;Lo;0;L;;;;;N;;;;;\n11DA0;GUNJALA GONDI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n11DA1;GUNJALA GONDI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n11DA2;GUNJALA GONDI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n11DA3;GUNJALA GONDI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n11DA4;GUNJALA GONDI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n11DA5;GUNJALA GONDI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n11DA6;GUNJALA GONDI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n11DA7;GUNJALA GONDI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n11DA8;GUNJALA GONDI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n11DA9;GUNJALA GONDI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n11EE0;MAKASAR LETTER KA;Lo;0;L;;;;;N;;;;;\n11EE1;MAKASAR LETTER GA;Lo;0;L;;;;;N;;;;;\n11EE2;MAKASAR LETTER NGA;Lo;0;L;;;;;N;;;;;\n11EE3;MAKASAR LETTER PA;Lo;0;L;;;;;N;;;;;\n11EE4;MAKASAR LETTER BA;Lo;0;L;;;;;N;;;;;\n11EE5;MAKASAR LETTER MA;Lo;0;L;;;;;N;;;;;\n11EE6;MAKASAR LETTER TA;Lo;0;L;;;;;N;;;;;\n11EE7;MAKASAR LETTER DA;Lo;0;L;;;;;N;;;;;\n11EE8;MAKASAR LETTER NA;Lo;0;L;;;;;N;;;;;\n11EE9;MAKASAR LETTER CA;Lo;0;L;;;;;N;;;;;\n11EEA;MAKASAR LETTER JA;Lo;0;L;;;;;N;;;;;\n11EEB;MAKASAR LETTER NYA;Lo;0;L;;;;;N;;;;;\n11EEC;MAKASAR LETTER YA;Lo;0;L;;;;;N;;;;;\n11EED;MAKASAR LETTER RA;Lo;0;L;;;;;N;;;;;\n11EEE;MAKASAR LETTER LA;Lo;0;L;;;;;N;;;;;\n11EEF;MAKASAR LETTER VA;Lo;0;L;;;;;N;;;;;\n11EF0;MAKASAR LETTER SA;Lo;0;L;;;;;N;;;;;\n11EF1;MAKASAR LETTER A;Lo;0;L;;;;;N;;;;;\n11EF2;MAKASAR ANGKA;Lo;0;L;;;;;N;;;;;\n11EF3;MAKASAR VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;;\n11EF4;MAKASAR VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;;\n11EF5;MAKASAR VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\n11EF6;MAKASAR VOWEL SIGN O;Mc;0;L;;;;;N;;;;;\n11EF7;MAKASAR PASSIMBANG;Po;0;L;;;;;N;;;;;\n11EF8;MAKASAR END OF SECTION;Po;0;L;;;;;N;;;;;\n11FC0;TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH;No;0;L;;;;1/320;N;;;;;\n11FC1;TAMIL FRACTION ONE ONE-HUNDRED-AND-SIXTIETH;No;0;L;;;;1/160;N;;;;;\n11FC2;TAMIL FRACTION ONE EIGHTIETH;No;0;L;;;;1/80;N;;;;;\n11FC3;TAMIL FRACTION ONE SIXTY-FOURTH;No;0;L;;;;1/64;N;;;;;\n11FC4;TAMIL FRACTION ONE FORTIETH;No;0;L;;;;1/40;N;;;;;\n11FC5;TAMIL FRACTION ONE THIRTY-SECOND;No;0;L;;;;1/32;N;;;;;\n11FC6;TAMIL FRACTION THREE EIGHTIETHS;No;0;L;;;;3/80;N;;;;;\n11FC7;TAMIL FRACTION THREE SIXTY-FOURTHS;No;0;L;;;;3/64;N;;;;;\n11FC8;TAMIL FRACTION ONE TWENTIETH;No;0;L;;;;1/20;N;;;;;\n11FC9;TAMIL FRACTION ONE SIXTEENTH-1;No;0;L;;;;1/16;N;;;;;\n11FCA;TAMIL FRACTION ONE SIXTEENTH-2;No;0;L;;;;1/16;N;;;;;\n11FCB;TAMIL FRACTION ONE TENTH;No;0;L;;;;1/10;N;;;;;\n11FCC;TAMIL FRACTION ONE EIGHTH;No;0;L;;;;1/8;N;;;;;\n11FCD;TAMIL FRACTION THREE TWENTIETHS;No;0;L;;;;3/20;N;;;;;\n11FCE;TAMIL FRACTION THREE SIXTEENTHS;No;0;L;;;;3/16;N;;;;;\n11FCF;TAMIL FRACTION ONE FIFTH;No;0;L;;;;1/5;N;;;;;\n11FD0;TAMIL FRACTION ONE QUARTER;No;0;L;;;;1/4;N;;;;;\n11FD1;TAMIL FRACTION ONE HALF-1;No;0;L;;;;1/2;N;;;;;\n11FD2;TAMIL FRACTION ONE HALF-2;No;0;L;;;;1/2;N;;;;;\n11FD3;TAMIL FRACTION THREE QUARTERS;No;0;L;;;;3/4;N;;;;;\n11FD4;TAMIL FRACTION DOWNSCALING FACTOR KIIZH;No;0;L;;;;1/320;N;;;;;\n11FD5;TAMIL SIGN NEL;So;0;ON;;;;;N;;;;;\n11FD6;TAMIL SIGN CEVITU;So;0;ON;;;;;N;;;;;\n11FD7;TAMIL SIGN AAZHAAKKU;So;0;ON;;;;;N;;;;;\n11FD8;TAMIL SIGN UZHAKKU;So;0;ON;;;;;N;;;;;\n11FD9;TAMIL SIGN MUUVUZHAKKU;So;0;ON;;;;;N;;;;;\n11FDA;TAMIL SIGN KURUNI;So;0;ON;;;;;N;;;;;\n11FDB;TAMIL SIGN PATHAKKU;So;0;ON;;;;;N;;;;;\n11FDC;TAMIL SIGN MUKKURUNI;So;0;ON;;;;;N;;;;;\n11FDD;TAMIL SIGN KAACU;Sc;0;ET;;;;;N;;;;;\n11FDE;TAMIL SIGN PANAM;Sc;0;ET;;;;;N;;;;;\n11FDF;TAMIL SIGN PON;Sc;0;ET;;;;;N;;;;;\n11FE0;TAMIL SIGN VARAAKAN;Sc;0;ET;;;;;N;;;;;\n11FE1;TAMIL SIGN PAARAM;So;0;ON;;;;;N;;;;;\n11FE2;TAMIL SIGN KUZHI;So;0;ON;;;;;N;;;;;\n11FE3;TAMIL SIGN VELI;So;0;ON;;;;;N;;;;;\n11FE4;TAMIL WET CULTIVATION SIGN;So;0;ON;;;;;N;;;;;\n11FE5;TAMIL DRY CULTIVATION SIGN;So;0;ON;;;;;N;;;;;\n11FE6;TAMIL LAND SIGN;So;0;ON;;;;;N;;;;;\n11FE7;TAMIL SALT PAN SIGN;So;0;ON;;;;;N;;;;;\n11FE8;TAMIL TRADITIONAL CREDIT SIGN;So;0;ON;;;;;N;;;;;\n11FE9;TAMIL TRADITIONAL NUMBER SIGN;So;0;ON;;;;;N;;;;;\n11FEA;TAMIL CURRENT SIGN;So;0;ON;;;;;N;;;;;\n11FEB;TAMIL AND ODD SIGN;So;0;ON;;;;;N;;;;;\n11FEC;TAMIL SPENT SIGN;So;0;ON;;;;;N;;;;;\n11FED;TAMIL TOTAL SIGN;So;0;ON;;;;;N;;;;;\n11FEE;TAMIL IN POSSESSION SIGN;So;0;ON;;;;;N;;;;;\n11FEF;TAMIL STARTING FROM SIGN;So;0;ON;;;;;N;;;;;\n11FF0;TAMIL SIGN MUTHALIYA;So;0;ON;;;;;N;;;;;\n11FF1;TAMIL SIGN VAKAIYARAA;So;0;ON;;;;;N;;;;;\n11FFF;TAMIL PUNCTUATION END OF TEXT;Po;0;L;;;;;N;;;;;\n12000;CUNEIFORM SIGN A;Lo;0;L;;;;;N;;;;;\n12001;CUNEIFORM SIGN A TIMES A;Lo;0;L;;;;;N;;;;;\n12002;CUNEIFORM SIGN A TIMES BAD;Lo;0;L;;;;;N;;;;;\n12003;CUNEIFORM SIGN A TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;\n12004;CUNEIFORM SIGN A TIMES HA;Lo;0;L;;;;;N;;;;;\n12005;CUNEIFORM SIGN A TIMES IGI;Lo;0;L;;;;;N;;;;;\n12006;CUNEIFORM SIGN A TIMES LAGAR GUNU;Lo;0;L;;;;;N;;;;;\n12007;CUNEIFORM SIGN A TIMES MUSH;Lo;0;L;;;;;N;;;;;\n12008;CUNEIFORM SIGN A TIMES SAG;Lo;0;L;;;;;N;;;;;\n12009;CUNEIFORM SIGN A2;Lo;0;L;;;;;N;;;;;\n1200A;CUNEIFORM SIGN AB;Lo;0;L;;;;;N;;;;;\n1200B;CUNEIFORM SIGN AB TIMES ASH2;Lo;0;L;;;;;N;;;;;\n1200C;CUNEIFORM SIGN AB TIMES DUN3 GUNU;Lo;0;L;;;;;N;;;;;\n1200D;CUNEIFORM SIGN AB TIMES GAL;Lo;0;L;;;;;N;;;;;\n1200E;CUNEIFORM SIGN AB TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;\n1200F;CUNEIFORM SIGN AB TIMES HA;Lo;0;L;;;;;N;;;;;\n12010;CUNEIFORM SIGN AB TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;\n12011;CUNEIFORM SIGN AB TIMES IMIN;Lo;0;L;;;;;N;;;;;\n12012;CUNEIFORM SIGN AB TIMES LAGAB;Lo;0;L;;;;;N;;;;;\n12013;CUNEIFORM SIGN AB TIMES SHESH;Lo;0;L;;;;;N;;;;;\n12014;CUNEIFORM SIGN AB TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;;\n12015;CUNEIFORM SIGN AB GUNU;Lo;0;L;;;;;N;;;;;\n12016;CUNEIFORM SIGN AB2;Lo;0;L;;;;;N;;;;;\n12017;CUNEIFORM SIGN AB2 TIMES BALAG;Lo;0;L;;;;;N;;;;;\n12018;CUNEIFORM SIGN AB2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;\n12019;CUNEIFORM SIGN AB2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;\n1201A;CUNEIFORM SIGN AB2 TIMES SHA3;Lo;0;L;;;;;N;;;;;\n1201B;CUNEIFORM SIGN AB2 TIMES TAK4;Lo;0;L;;;;;N;;;;;\n1201C;CUNEIFORM SIGN AD;Lo;0;L;;;;;N;;;;;\n1201D;CUNEIFORM SIGN AK;Lo;0;L;;;;;N;;;;;\n1201E;CUNEIFORM SIGN AK TIMES ERIN2;Lo;0;L;;;;;N;;;;;\n1201F;CUNEIFORM SIGN AK TIMES SHITA PLUS GISH;Lo;0;L;;;;;N;;;;;\n12020;CUNEIFORM SIGN AL;Lo;0;L;;;;;N;;;;;\n12021;CUNEIFORM SIGN AL TIMES AL;Lo;0;L;;;;;N;;;;;\n12022;CUNEIFORM SIGN AL TIMES DIM2;Lo;0;L;;;;;N;;;;;\n12023;CUNEIFORM SIGN AL TIMES GISH;Lo;0;L;;;;;N;;;;;\n12024;CUNEIFORM SIGN AL TIMES HA;Lo;0;L;;;;;N;;;;;\n12025;CUNEIFORM SIGN AL TIMES KAD3;Lo;0;L;;;;;N;;;;;\n12026;CUNEIFORM SIGN AL TIMES KI;Lo;0;L;;;;;N;;;;;\n12027;CUNEIFORM SIGN AL TIMES SHE;Lo;0;L;;;;;N;;;;;\n12028;CUNEIFORM SIGN AL TIMES USH;Lo;0;L;;;;;N;;;;;\n12029;CUNEIFORM SIGN ALAN;Lo;0;L;;;;;N;;;;;\n1202A;CUNEIFORM SIGN ALEPH;Lo;0;L;;;;;N;;;;;\n1202B;CUNEIFORM SIGN AMAR;Lo;0;L;;;;;N;;;;;\n1202C;CUNEIFORM SIGN AMAR TIMES SHE;Lo;0;L;;;;;N;;;;;\n1202D;CUNEIFORM SIGN AN;Lo;0;L;;;;;N;;;;;\n1202E;CUNEIFORM SIGN AN OVER AN;Lo;0;L;;;;;N;;;;;\n1202F;CUNEIFORM SIGN AN THREE TIMES;Lo;0;L;;;;;N;;;;;\n12030;CUNEIFORM SIGN AN PLUS NAGA OPPOSING AN PLUS NAGA;Lo;0;L;;;;;N;;;;;\n12031;CUNEIFORM SIGN AN PLUS NAGA SQUARED;Lo;0;L;;;;;N;;;;;\n12032;CUNEIFORM SIGN ANSHE;Lo;0;L;;;;;N;;;;;\n12033;CUNEIFORM SIGN APIN;Lo;0;L;;;;;N;;;;;\n12034;CUNEIFORM SIGN ARAD;Lo;0;L;;;;;N;;;;;\n12035;CUNEIFORM SIGN ARAD TIMES KUR;Lo;0;L;;;;;N;;;;;\n12036;CUNEIFORM SIGN ARKAB;Lo;0;L;;;;;N;;;;;\n12037;CUNEIFORM SIGN ASAL2;Lo;0;L;;;;;N;;;;;\n12038;CUNEIFORM SIGN ASH;Lo;0;L;;;;;N;;;;;\n12039;CUNEIFORM SIGN ASH ZIDA TENU;Lo;0;L;;;;;N;;;;;\n1203A;CUNEIFORM SIGN ASH KABA TENU;Lo;0;L;;;;;N;;;;;\n1203B;CUNEIFORM SIGN ASH OVER ASH TUG2 OVER TUG2 TUG2 OVER TUG2 PAP;Lo;0;L;;;;;N;;;;;\n1203C;CUNEIFORM SIGN ASH OVER ASH OVER ASH;Lo;0;L;;;;;N;;;;;\n1203D;CUNEIFORM SIGN ASH OVER ASH OVER ASH CROSSING ASH OVER ASH OVER ASH;Lo;0;L;;;;;N;;;;;\n1203E;CUNEIFORM SIGN ASH2;Lo;0;L;;;;;N;;;;;\n1203F;CUNEIFORM SIGN ASHGAB;Lo;0;L;;;;;N;;;;;\n12040;CUNEIFORM SIGN BA;Lo;0;L;;;;;N;;;;;\n12041;CUNEIFORM SIGN BAD;Lo;0;L;;;;;N;;;;;\n12042;CUNEIFORM SIGN BAG3;Lo;0;L;;;;;N;;;;;\n12043;CUNEIFORM SIGN BAHAR2;Lo;0;L;;;;;N;;;;;\n12044;CUNEIFORM SIGN BAL;Lo;0;L;;;;;N;;;;;\n12045;CUNEIFORM SIGN BAL OVER BAL;Lo;0;L;;;;;N;;;;;\n12046;CUNEIFORM SIGN BALAG;Lo;0;L;;;;;N;;;;;\n12047;CUNEIFORM SIGN BAR;Lo;0;L;;;;;N;;;;;\n12048;CUNEIFORM SIGN BARA2;Lo;0;L;;;;;N;;;;;\n12049;CUNEIFORM SIGN BI;Lo;0;L;;;;;N;;;;;\n1204A;CUNEIFORM SIGN BI TIMES A;Lo;0;L;;;;;N;;;;;\n1204B;CUNEIFORM SIGN BI TIMES GAR;Lo;0;L;;;;;N;;;;;\n1204C;CUNEIFORM SIGN BI TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;\n1204D;CUNEIFORM SIGN BU;Lo;0;L;;;;;N;;;;;\n1204E;CUNEIFORM SIGN BU OVER BU AB;Lo;0;L;;;;;N;;;;;\n1204F;CUNEIFORM SIGN BU OVER BU UN;Lo;0;L;;;;;N;;;;;\n12050;CUNEIFORM SIGN BU CROSSING BU;Lo;0;L;;;;;N;;;;;\n12051;CUNEIFORM SIGN BULUG;Lo;0;L;;;;;N;;;;;\n12052;CUNEIFORM SIGN BULUG OVER BULUG;Lo;0;L;;;;;N;;;;;\n12053;CUNEIFORM SIGN BUR;Lo;0;L;;;;;N;;;;;\n12054;CUNEIFORM SIGN BUR2;Lo;0;L;;;;;N;;;;;\n12055;CUNEIFORM SIGN DA;Lo;0;L;;;;;N;;;;;\n12056;CUNEIFORM SIGN DAG;Lo;0;L;;;;;N;;;;;\n12057;CUNEIFORM SIGN DAG KISIM5 TIMES A PLUS MASH;Lo;0;L;;;;;N;;;;;\n12058;CUNEIFORM SIGN DAG KISIM5 TIMES AMAR;Lo;0;L;;;;;N;;;;;\n12059;CUNEIFORM SIGN DAG KISIM5 TIMES BALAG;Lo;0;L;;;;;N;;;;;\n1205A;CUNEIFORM SIGN DAG KISIM5 TIMES BI;Lo;0;L;;;;;N;;;;;\n1205B;CUNEIFORM SIGN DAG KISIM5 TIMES GA;Lo;0;L;;;;;N;;;;;\n1205C;CUNEIFORM SIGN DAG KISIM5 TIMES GA PLUS MASH;Lo;0;L;;;;;N;;;;;\n1205D;CUNEIFORM SIGN DAG KISIM5 TIMES GI;Lo;0;L;;;;;N;;;;;\n1205E;CUNEIFORM SIGN DAG KISIM5 TIMES GIR2;Lo;0;L;;;;;N;;;;;\n1205F;CUNEIFORM SIGN DAG KISIM5 TIMES GUD;Lo;0;L;;;;;N;;;;;\n12060;CUNEIFORM SIGN DAG KISIM5 TIMES HA;Lo;0;L;;;;;N;;;;;\n12061;CUNEIFORM SIGN DAG KISIM5 TIMES IR;Lo;0;L;;;;;N;;;;;\n12062;CUNEIFORM SIGN DAG KISIM5 TIMES IR PLUS LU;Lo;0;L;;;;;N;;;;;\n12063;CUNEIFORM SIGN DAG KISIM5 TIMES KAK;Lo;0;L;;;;;N;;;;;\n12064;CUNEIFORM SIGN DAG KISIM5 TIMES LA;Lo;0;L;;;;;N;;;;;\n12065;CUNEIFORM SIGN DAG KISIM5 TIMES LU;Lo;0;L;;;;;N;;;;;\n12066;CUNEIFORM SIGN DAG KISIM5 TIMES LU PLUS MASH2;Lo;0;L;;;;;N;;;;;\n12067;CUNEIFORM SIGN DAG KISIM5 TIMES LUM;Lo;0;L;;;;;N;;;;;\n12068;CUNEIFORM SIGN DAG KISIM5 TIMES NE;Lo;0;L;;;;;N;;;;;\n12069;CUNEIFORM SIGN DAG KISIM5 TIMES PAP PLUS PAP;Lo;0;L;;;;;N;;;;;\n1206A;CUNEIFORM SIGN DAG KISIM5 TIMES SI;Lo;0;L;;;;;N;;;;;\n1206B;CUNEIFORM SIGN DAG KISIM5 TIMES TAK4;Lo;0;L;;;;;N;;;;;\n1206C;CUNEIFORM SIGN DAG KISIM5 TIMES U2 PLUS GIR2;Lo;0;L;;;;;N;;;;;\n1206D;CUNEIFORM SIGN DAG KISIM5 TIMES USH;Lo;0;L;;;;;N;;;;;\n1206E;CUNEIFORM SIGN DAM;Lo;0;L;;;;;N;;;;;\n1206F;CUNEIFORM SIGN DAR;Lo;0;L;;;;;N;;;;;\n12070;CUNEIFORM SIGN DARA3;Lo;0;L;;;;;N;;;;;\n12071;CUNEIFORM SIGN DARA4;Lo;0;L;;;;;N;;;;;\n12072;CUNEIFORM SIGN DI;Lo;0;L;;;;;N;;;;;\n12073;CUNEIFORM SIGN DIB;Lo;0;L;;;;;N;;;;;\n12074;CUNEIFORM SIGN DIM;Lo;0;L;;;;;N;;;;;\n12075;CUNEIFORM SIGN DIM TIMES SHE;Lo;0;L;;;;;N;;;;;\n12076;CUNEIFORM SIGN DIM2;Lo;0;L;;;;;N;;;;;\n12077;CUNEIFORM SIGN DIN;Lo;0;L;;;;;N;;;;;\n12078;CUNEIFORM SIGN DIN KASKAL U GUNU DISH;Lo;0;L;;;;;N;;;;;\n12079;CUNEIFORM SIGN DISH;Lo;0;L;;;;;N;;;;;\n1207A;CUNEIFORM SIGN DU;Lo;0;L;;;;;N;;;;;\n1207B;CUNEIFORM SIGN DU OVER DU;Lo;0;L;;;;;N;;;;;\n1207C;CUNEIFORM SIGN DU GUNU;Lo;0;L;;;;;N;;;;;\n1207D;CUNEIFORM SIGN DU SHESHIG;Lo;0;L;;;;;N;;;;;\n1207E;CUNEIFORM SIGN DUB;Lo;0;L;;;;;N;;;;;\n1207F;CUNEIFORM SIGN DUB TIMES ESH2;Lo;0;L;;;;;N;;;;;\n12080;CUNEIFORM SIGN DUB2;Lo;0;L;;;;;N;;;;;\n12081;CUNEIFORM SIGN DUG;Lo;0;L;;;;;N;;;;;\n12082;CUNEIFORM SIGN DUGUD;Lo;0;L;;;;;N;;;;;\n12083;CUNEIFORM SIGN DUH;Lo;0;L;;;;;N;;;;;\n12084;CUNEIFORM SIGN DUN;Lo;0;L;;;;;N;;;;;\n12085;CUNEIFORM SIGN DUN3;Lo;0;L;;;;;N;;;;;\n12086;CUNEIFORM SIGN DUN3 GUNU;Lo;0;L;;;;;N;;;;;\n12087;CUNEIFORM SIGN DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;;\n12088;CUNEIFORM SIGN DUN4;Lo;0;L;;;;;N;;;;;\n12089;CUNEIFORM SIGN DUR2;Lo;0;L;;;;;N;;;;;\n1208A;CUNEIFORM SIGN E;Lo;0;L;;;;;N;;;;;\n1208B;CUNEIFORM SIGN E TIMES PAP;Lo;0;L;;;;;N;;;;;\n1208C;CUNEIFORM SIGN E OVER E NUN OVER NUN;Lo;0;L;;;;;N;;;;;\n1208D;CUNEIFORM SIGN E2;Lo;0;L;;;;;N;;;;;\n1208E;CUNEIFORM SIGN E2 TIMES A PLUS HA PLUS DA;Lo;0;L;;;;;N;;;;;\n1208F;CUNEIFORM SIGN E2 TIMES GAR;Lo;0;L;;;;;N;;;;;\n12090;CUNEIFORM SIGN E2 TIMES MI;Lo;0;L;;;;;N;;;;;\n12091;CUNEIFORM SIGN E2 TIMES SAL;Lo;0;L;;;;;N;;;;;\n12092;CUNEIFORM SIGN E2 TIMES SHE;Lo;0;L;;;;;N;;;;;\n12093;CUNEIFORM SIGN E2 TIMES U;Lo;0;L;;;;;N;;;;;\n12094;CUNEIFORM SIGN EDIN;Lo;0;L;;;;;N;;;;;\n12095;CUNEIFORM SIGN EGIR;Lo;0;L;;;;;N;;;;;\n12096;CUNEIFORM SIGN EL;Lo;0;L;;;;;N;;;;;\n12097;CUNEIFORM SIGN EN;Lo;0;L;;;;;N;;;;;\n12098;CUNEIFORM SIGN EN TIMES GAN2;Lo;0;L;;;;;N;;;;;\n12099;CUNEIFORM SIGN EN TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;\n1209A;CUNEIFORM SIGN EN TIMES ME;Lo;0;L;;;;;N;;;;;\n1209B;CUNEIFORM SIGN EN CROSSING EN;Lo;0;L;;;;;N;;;;;\n1209C;CUNEIFORM SIGN EN OPPOSING EN;Lo;0;L;;;;;N;;;;;\n1209D;CUNEIFORM SIGN EN SQUARED;Lo;0;L;;;;;N;;;;;\n1209E;CUNEIFORM SIGN EREN;Lo;0;L;;;;;N;;;;;\n1209F;CUNEIFORM SIGN ERIN2;Lo;0;L;;;;;N;;;;;\n120A0;CUNEIFORM SIGN ESH2;Lo;0;L;;;;;N;;;;;\n120A1;CUNEIFORM SIGN EZEN;Lo;0;L;;;;;N;;;;;\n120A2;CUNEIFORM SIGN EZEN TIMES A;Lo;0;L;;;;;N;;;;;\n120A3;CUNEIFORM SIGN EZEN TIMES A PLUS LAL;Lo;0;L;;;;;N;;;;;\n120A4;CUNEIFORM SIGN EZEN TIMES A PLUS LAL TIMES LAL;Lo;0;L;;;;;N;;;;;\n120A5;CUNEIFORM SIGN EZEN TIMES AN;Lo;0;L;;;;;N;;;;;\n120A6;CUNEIFORM SIGN EZEN TIMES BAD;Lo;0;L;;;;;N;;;;;\n120A7;CUNEIFORM SIGN EZEN TIMES DUN3 GUNU;Lo;0;L;;;;;N;;;;;\n120A8;CUNEIFORM SIGN EZEN TIMES DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;;\n120A9;CUNEIFORM SIGN EZEN TIMES HA;Lo;0;L;;;;;N;;;;;\n120AA;CUNEIFORM SIGN EZEN TIMES HA GUNU;Lo;0;L;;;;;N;;;;;\n120AB;CUNEIFORM SIGN EZEN TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;\n120AC;CUNEIFORM SIGN EZEN TIMES KASKAL;Lo;0;L;;;;;N;;;;;\n120AD;CUNEIFORM SIGN EZEN TIMES KASKAL SQUARED;Lo;0;L;;;;;N;;;;;\n120AE;CUNEIFORM SIGN EZEN TIMES KU3;Lo;0;L;;;;;N;;;;;\n120AF;CUNEIFORM SIGN EZEN TIMES LA;Lo;0;L;;;;;N;;;;;\n120B0;CUNEIFORM SIGN EZEN TIMES LAL TIMES LAL;Lo;0;L;;;;;N;;;;;\n120B1;CUNEIFORM SIGN EZEN TIMES LI;Lo;0;L;;;;;N;;;;;\n120B2;CUNEIFORM SIGN EZEN TIMES LU;Lo;0;L;;;;;N;;;;;\n120B3;CUNEIFORM SIGN EZEN TIMES U2;Lo;0;L;;;;;N;;;;;\n120B4;CUNEIFORM SIGN EZEN TIMES UD;Lo;0;L;;;;;N;;;;;\n120B5;CUNEIFORM SIGN GA;Lo;0;L;;;;;N;;;;;\n120B6;CUNEIFORM SIGN GA GUNU;Lo;0;L;;;;;N;;;;;\n120B7;CUNEIFORM SIGN GA2;Lo;0;L;;;;;N;;;;;\n120B8;CUNEIFORM SIGN GA2 TIMES A PLUS DA PLUS HA;Lo;0;L;;;;;N;;;;;\n120B9;CUNEIFORM SIGN GA2 TIMES A PLUS HA;Lo;0;L;;;;;N;;;;;\n120BA;CUNEIFORM SIGN GA2 TIMES A PLUS IGI;Lo;0;L;;;;;N;;;;;\n120BB;CUNEIFORM SIGN GA2 TIMES AB2 TENU PLUS TAB;Lo;0;L;;;;;N;;;;;\n120BC;CUNEIFORM SIGN GA2 TIMES AN;Lo;0;L;;;;;N;;;;;\n120BD;CUNEIFORM SIGN GA2 TIMES ASH;Lo;0;L;;;;;N;;;;;\n120BE;CUNEIFORM SIGN GA2 TIMES ASH2 PLUS GAL;Lo;0;L;;;;;N;;;;;\n120BF;CUNEIFORM SIGN GA2 TIMES BAD;Lo;0;L;;;;;N;;;;;\n120C0;CUNEIFORM SIGN GA2 TIMES BAR PLUS RA;Lo;0;L;;;;;N;;;;;\n120C1;CUNEIFORM SIGN GA2 TIMES BUR;Lo;0;L;;;;;N;;;;;\n120C2;CUNEIFORM SIGN GA2 TIMES BUR PLUS RA;Lo;0;L;;;;;N;;;;;\n120C3;CUNEIFORM SIGN GA2 TIMES DA;Lo;0;L;;;;;N;;;;;\n120C4;CUNEIFORM SIGN GA2 TIMES DI;Lo;0;L;;;;;N;;;;;\n120C5;CUNEIFORM SIGN GA2 TIMES DIM TIMES SHE;Lo;0;L;;;;;N;;;;;\n120C6;CUNEIFORM SIGN GA2 TIMES DUB;Lo;0;L;;;;;N;;;;;\n120C7;CUNEIFORM SIGN GA2 TIMES EL;Lo;0;L;;;;;N;;;;;\n120C8;CUNEIFORM SIGN GA2 TIMES EL PLUS LA;Lo;0;L;;;;;N;;;;;\n120C9;CUNEIFORM SIGN GA2 TIMES EN;Lo;0;L;;;;;N;;;;;\n120CA;CUNEIFORM SIGN GA2 TIMES EN TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;\n120CB;CUNEIFORM SIGN GA2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;\n120CC;CUNEIFORM SIGN GA2 TIMES GAR;Lo;0;L;;;;;N;;;;;\n120CD;CUNEIFORM SIGN GA2 TIMES GI;Lo;0;L;;;;;N;;;;;\n120CE;CUNEIFORM SIGN GA2 TIMES GI4;Lo;0;L;;;;;N;;;;;\n120CF;CUNEIFORM SIGN GA2 TIMES GI4 PLUS A;Lo;0;L;;;;;N;;;;;\n120D0;CUNEIFORM SIGN GA2 TIMES GIR2 PLUS SU;Lo;0;L;;;;;N;;;;;\n120D1;CUNEIFORM SIGN GA2 TIMES HA PLUS LU PLUS ESH2;Lo;0;L;;;;;N;;;;;\n120D2;CUNEIFORM SIGN GA2 TIMES HAL;Lo;0;L;;;;;N;;;;;\n120D3;CUNEIFORM SIGN GA2 TIMES HAL PLUS LA;Lo;0;L;;;;;N;;;;;\n120D4;CUNEIFORM SIGN GA2 TIMES HI PLUS LI;Lo;0;L;;;;;N;;;;;\n120D5;CUNEIFORM SIGN GA2 TIMES HUB2;Lo;0;L;;;;;N;;;;;\n120D6;CUNEIFORM SIGN GA2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;\n120D7;CUNEIFORM SIGN GA2 TIMES ISH PLUS HU PLUS ASH;Lo;0;L;;;;;N;;;;;\n120D8;CUNEIFORM SIGN GA2 TIMES KAK;Lo;0;L;;;;;N;;;;;\n120D9;CUNEIFORM SIGN GA2 TIMES KASKAL;Lo;0;L;;;;;N;;;;;\n120DA;CUNEIFORM SIGN GA2 TIMES KID;Lo;0;L;;;;;N;;;;;\n120DB;CUNEIFORM SIGN GA2 TIMES KID PLUS LAL;Lo;0;L;;;;;N;;;;;\n120DC;CUNEIFORM SIGN GA2 TIMES KU3 PLUS AN;Lo;0;L;;;;;N;;;;;\n120DD;CUNEIFORM SIGN GA2 TIMES LA;Lo;0;L;;;;;N;;;;;\n120DE;CUNEIFORM SIGN GA2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;\n120DF;CUNEIFORM SIGN GA2 TIMES MI;Lo;0;L;;;;;N;;;;;\n120E0;CUNEIFORM SIGN GA2 TIMES NUN;Lo;0;L;;;;;N;;;;;\n120E1;CUNEIFORM SIGN GA2 TIMES NUN OVER NUN;Lo;0;L;;;;;N;;;;;\n120E2;CUNEIFORM SIGN GA2 TIMES PA;Lo;0;L;;;;;N;;;;;\n120E3;CUNEIFORM SIGN GA2 TIMES SAL;Lo;0;L;;;;;N;;;;;\n120E4;CUNEIFORM SIGN GA2 TIMES SAR;Lo;0;L;;;;;N;;;;;\n120E5;CUNEIFORM SIGN GA2 TIMES SHE;Lo;0;L;;;;;N;;;;;\n120E6;CUNEIFORM SIGN GA2 TIMES SHE PLUS TUR;Lo;0;L;;;;;N;;;;;\n120E7;CUNEIFORM SIGN GA2 TIMES SHID;Lo;0;L;;;;;N;;;;;\n120E8;CUNEIFORM SIGN GA2 TIMES SUM;Lo;0;L;;;;;N;;;;;\n120E9;CUNEIFORM SIGN GA2 TIMES TAK4;Lo;0;L;;;;;N;;;;;\n120EA;CUNEIFORM SIGN GA2 TIMES U;Lo;0;L;;;;;N;;;;;\n120EB;CUNEIFORM SIGN GA2 TIMES UD;Lo;0;L;;;;;N;;;;;\n120EC;CUNEIFORM SIGN GA2 TIMES UD PLUS DU;Lo;0;L;;;;;N;;;;;\n120ED;CUNEIFORM SIGN GA2 OVER GA2;Lo;0;L;;;;;N;;;;;\n120EE;CUNEIFORM SIGN GABA;Lo;0;L;;;;;N;;;;;\n120EF;CUNEIFORM SIGN GABA CROSSING GABA;Lo;0;L;;;;;N;;;;;\n120F0;CUNEIFORM SIGN GAD;Lo;0;L;;;;;N;;;;;\n120F1;CUNEIFORM SIGN GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;\n120F2;CUNEIFORM SIGN GAL;Lo;0;L;;;;;N;;;;;\n120F3;CUNEIFORM SIGN GAL GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;\n120F4;CUNEIFORM SIGN GALAM;Lo;0;L;;;;;N;;;;;\n120F5;CUNEIFORM SIGN GAM;Lo;0;L;;;;;N;;;;;\n120F6;CUNEIFORM SIGN GAN;Lo;0;L;;;;;N;;;;;\n120F7;CUNEIFORM SIGN GAN2;Lo;0;L;;;;;N;;;;;\n120F8;CUNEIFORM SIGN GAN2 TENU;Lo;0;L;;;;;N;;;;;\n120F9;CUNEIFORM SIGN GAN2 OVER GAN2;Lo;0;L;;;;;N;;;;;\n120FA;CUNEIFORM SIGN GAN2 CROSSING GAN2;Lo;0;L;;;;;N;;;;;\n120FB;CUNEIFORM SIGN GAR;Lo;0;L;;;;;N;;;;;\n120FC;CUNEIFORM SIGN GAR3;Lo;0;L;;;;;N;;;;;\n120FD;CUNEIFORM SIGN GASHAN;Lo;0;L;;;;;N;;;;;\n120FE;CUNEIFORM SIGN GESHTIN;Lo;0;L;;;;;N;;;;;\n120FF;CUNEIFORM SIGN GESHTIN TIMES KUR;Lo;0;L;;;;;N;;;;;\n12100;CUNEIFORM SIGN GI;Lo;0;L;;;;;N;;;;;\n12101;CUNEIFORM SIGN GI TIMES E;Lo;0;L;;;;;N;;;;;\n12102;CUNEIFORM SIGN GI TIMES U;Lo;0;L;;;;;N;;;;;\n12103;CUNEIFORM SIGN GI CROSSING GI;Lo;0;L;;;;;N;;;;;\n12104;CUNEIFORM SIGN GI4;Lo;0;L;;;;;N;;;;;\n12105;CUNEIFORM SIGN GI4 OVER GI4;Lo;0;L;;;;;N;;;;;\n12106;CUNEIFORM SIGN GI4 CROSSING GI4;Lo;0;L;;;;;N;;;;;\n12107;CUNEIFORM SIGN GIDIM;Lo;0;L;;;;;N;;;;;\n12108;CUNEIFORM SIGN GIR2;Lo;0;L;;;;;N;;;;;\n12109;CUNEIFORM SIGN GIR2 GUNU;Lo;0;L;;;;;N;;;;;\n1210A;CUNEIFORM SIGN GIR3;Lo;0;L;;;;;N;;;;;\n1210B;CUNEIFORM SIGN GIR3 TIMES A PLUS IGI;Lo;0;L;;;;;N;;;;;\n1210C;CUNEIFORM SIGN GIR3 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;\n1210D;CUNEIFORM SIGN GIR3 TIMES IGI;Lo;0;L;;;;;N;;;;;\n1210E;CUNEIFORM SIGN GIR3 TIMES LU PLUS IGI;Lo;0;L;;;;;N;;;;;\n1210F;CUNEIFORM SIGN GIR3 TIMES PA;Lo;0;L;;;;;N;;;;;\n12110;CUNEIFORM SIGN GISAL;Lo;0;L;;;;;N;;;;;\n12111;CUNEIFORM SIGN GISH;Lo;0;L;;;;;N;;;;;\n12112;CUNEIFORM SIGN GISH CROSSING GISH;Lo;0;L;;;;;N;;;;;\n12113;CUNEIFORM SIGN GISH TIMES BAD;Lo;0;L;;;;;N;;;;;\n12114;CUNEIFORM SIGN GISH TIMES TAK4;Lo;0;L;;;;;N;;;;;\n12115;CUNEIFORM SIGN GISH TENU;Lo;0;L;;;;;N;;;;;\n12116;CUNEIFORM SIGN GU;Lo;0;L;;;;;N;;;;;\n12117;CUNEIFORM SIGN GU CROSSING GU;Lo;0;L;;;;;N;;;;;\n12118;CUNEIFORM SIGN GU2;Lo;0;L;;;;;N;;;;;\n12119;CUNEIFORM SIGN GU2 TIMES KAK;Lo;0;L;;;;;N;;;;;\n1211A;CUNEIFORM SIGN GU2 TIMES KAK TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;\n1211B;CUNEIFORM SIGN GU2 TIMES NUN;Lo;0;L;;;;;N;;;;;\n1211C;CUNEIFORM SIGN GU2 TIMES SAL PLUS TUG2;Lo;0;L;;;;;N;;;;;\n1211D;CUNEIFORM SIGN GU2 GUNU;Lo;0;L;;;;;N;;;;;\n1211E;CUNEIFORM SIGN GUD;Lo;0;L;;;;;N;;;;;\n1211F;CUNEIFORM SIGN GUD TIMES A PLUS KUR;Lo;0;L;;;;;N;;;;;\n12120;CUNEIFORM SIGN GUD TIMES KUR;Lo;0;L;;;;;N;;;;;\n12121;CUNEIFORM SIGN GUD OVER GUD LUGAL;Lo;0;L;;;;;N;;;;;\n12122;CUNEIFORM SIGN GUL;Lo;0;L;;;;;N;;;;;\n12123;CUNEIFORM SIGN GUM;Lo;0;L;;;;;N;;;;;\n12124;CUNEIFORM SIGN GUM TIMES SHE;Lo;0;L;;;;;N;;;;;\n12125;CUNEIFORM SIGN GUR;Lo;0;L;;;;;N;;;;;\n12126;CUNEIFORM SIGN GUR7;Lo;0;L;;;;;N;;;;;\n12127;CUNEIFORM SIGN GURUN;Lo;0;L;;;;;N;;;;;\n12128;CUNEIFORM SIGN GURUSH;Lo;0;L;;;;;N;;;;;\n12129;CUNEIFORM SIGN HA;Lo;0;L;;;;;N;;;;;\n1212A;CUNEIFORM SIGN HA TENU;Lo;0;L;;;;;N;;;;;\n1212B;CUNEIFORM SIGN HA GUNU;Lo;0;L;;;;;N;;;;;\n1212C;CUNEIFORM SIGN HAL;Lo;0;L;;;;;N;;;;;\n1212D;CUNEIFORM SIGN HI;Lo;0;L;;;;;N;;;;;\n1212E;CUNEIFORM SIGN HI TIMES ASH;Lo;0;L;;;;;N;;;;;\n1212F;CUNEIFORM SIGN HI TIMES ASH2;Lo;0;L;;;;;N;;;;;\n12130;CUNEIFORM SIGN HI TIMES BAD;Lo;0;L;;;;;N;;;;;\n12131;CUNEIFORM SIGN HI TIMES DISH;Lo;0;L;;;;;N;;;;;\n12132;CUNEIFORM SIGN HI TIMES GAD;Lo;0;L;;;;;N;;;;;\n12133;CUNEIFORM SIGN HI TIMES KIN;Lo;0;L;;;;;N;;;;;\n12134;CUNEIFORM SIGN HI TIMES NUN;Lo;0;L;;;;;N;;;;;\n12135;CUNEIFORM SIGN HI TIMES SHE;Lo;0;L;;;;;N;;;;;\n12136;CUNEIFORM SIGN HI TIMES U;Lo;0;L;;;;;N;;;;;\n12137;CUNEIFORM SIGN HU;Lo;0;L;;;;;N;;;;;\n12138;CUNEIFORM SIGN HUB2;Lo;0;L;;;;;N;;;;;\n12139;CUNEIFORM SIGN HUB2 TIMES AN;Lo;0;L;;;;;N;;;;;\n1213A;CUNEIFORM SIGN HUB2 TIMES HAL;Lo;0;L;;;;;N;;;;;\n1213B;CUNEIFORM SIGN HUB2 TIMES KASKAL;Lo;0;L;;;;;N;;;;;\n1213C;CUNEIFORM SIGN HUB2 TIMES LISH;Lo;0;L;;;;;N;;;;;\n1213D;CUNEIFORM SIGN HUB2 TIMES UD;Lo;0;L;;;;;N;;;;;\n1213E;CUNEIFORM SIGN HUL2;Lo;0;L;;;;;N;;;;;\n1213F;CUNEIFORM SIGN I;Lo;0;L;;;;;N;;;;;\n12140;CUNEIFORM SIGN I A;Lo;0;L;;;;;N;;;;;\n12141;CUNEIFORM SIGN IB;Lo;0;L;;;;;N;;;;;\n12142;CUNEIFORM SIGN IDIM;Lo;0;L;;;;;N;;;;;\n12143;CUNEIFORM SIGN IDIM OVER IDIM BUR;Lo;0;L;;;;;N;;;;;\n12144;CUNEIFORM SIGN IDIM OVER IDIM SQUARED;Lo;0;L;;;;;N;;;;;\n12145;CUNEIFORM SIGN IG;Lo;0;L;;;;;N;;;;;\n12146;CUNEIFORM SIGN IGI;Lo;0;L;;;;;N;;;;;\n12147;CUNEIFORM SIGN IGI DIB;Lo;0;L;;;;;N;;;;;\n12148;CUNEIFORM SIGN IGI RI;Lo;0;L;;;;;N;;;;;\n12149;CUNEIFORM SIGN IGI OVER IGI SHIR OVER SHIR UD OVER UD;Lo;0;L;;;;;N;;;;;\n1214A;CUNEIFORM SIGN IGI GUNU;Lo;0;L;;;;;N;;;;;\n1214B;CUNEIFORM SIGN IL;Lo;0;L;;;;;N;;;;;\n1214C;CUNEIFORM SIGN IL TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;\n1214D;CUNEIFORM SIGN IL2;Lo;0;L;;;;;N;;;;;\n1214E;CUNEIFORM SIGN IM;Lo;0;L;;;;;N;;;;;\n1214F;CUNEIFORM SIGN IM TIMES TAK4;Lo;0;L;;;;;N;;;;;\n12150;CUNEIFORM SIGN IM CROSSING IM;Lo;0;L;;;;;N;;;;;\n12151;CUNEIFORM SIGN IM OPPOSING IM;Lo;0;L;;;;;N;;;;;\n12152;CUNEIFORM SIGN IM SQUARED;Lo;0;L;;;;;N;;;;;\n12153;CUNEIFORM SIGN IMIN;Lo;0;L;;;;;N;;;;;\n12154;CUNEIFORM SIGN IN;Lo;0;L;;;;;N;;;;;\n12155;CUNEIFORM SIGN IR;Lo;0;L;;;;;N;;;;;\n12156;CUNEIFORM SIGN ISH;Lo;0;L;;;;;N;;;;;\n12157;CUNEIFORM SIGN KA;Lo;0;L;;;;;N;;;;;\n12158;CUNEIFORM SIGN KA TIMES A;Lo;0;L;;;;;N;;;;;\n12159;CUNEIFORM SIGN KA TIMES AD;Lo;0;L;;;;;N;;;;;\n1215A;CUNEIFORM SIGN KA TIMES AD PLUS KU3;Lo;0;L;;;;;N;;;;;\n1215B;CUNEIFORM SIGN KA TIMES ASH2;Lo;0;L;;;;;N;;;;;\n1215C;CUNEIFORM SIGN KA TIMES BAD;Lo;0;L;;;;;N;;;;;\n1215D;CUNEIFORM SIGN KA TIMES BALAG;Lo;0;L;;;;;N;;;;;\n1215E;CUNEIFORM SIGN KA TIMES BAR;Lo;0;L;;;;;N;;;;;\n1215F;CUNEIFORM SIGN KA TIMES BI;Lo;0;L;;;;;N;;;;;\n12160;CUNEIFORM SIGN KA TIMES ERIN2;Lo;0;L;;;;;N;;;;;\n12161;CUNEIFORM SIGN KA TIMES ESH2;Lo;0;L;;;;;N;;;;;\n12162;CUNEIFORM SIGN KA TIMES GA;Lo;0;L;;;;;N;;;;;\n12163;CUNEIFORM SIGN KA TIMES GAL;Lo;0;L;;;;;N;;;;;\n12164;CUNEIFORM SIGN KA TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;\n12165;CUNEIFORM SIGN KA TIMES GAR;Lo;0;L;;;;;N;;;;;\n12166;CUNEIFORM SIGN KA TIMES GAR PLUS SHA3 PLUS A;Lo;0;L;;;;;N;;;;;\n12167;CUNEIFORM SIGN KA TIMES GI;Lo;0;L;;;;;N;;;;;\n12168;CUNEIFORM SIGN KA TIMES GIR2;Lo;0;L;;;;;N;;;;;\n12169;CUNEIFORM SIGN KA TIMES GISH PLUS SAR;Lo;0;L;;;;;N;;;;;\n1216A;CUNEIFORM SIGN KA TIMES GISH CROSSING GISH;Lo;0;L;;;;;N;;;;;\n1216B;CUNEIFORM SIGN KA TIMES GU;Lo;0;L;;;;;N;;;;;\n1216C;CUNEIFORM SIGN KA TIMES GUR7;Lo;0;L;;;;;N;;;;;\n1216D;CUNEIFORM SIGN KA TIMES IGI;Lo;0;L;;;;;N;;;;;\n1216E;CUNEIFORM SIGN KA TIMES IM;Lo;0;L;;;;;N;;;;;\n1216F;CUNEIFORM SIGN KA TIMES KAK;Lo;0;L;;;;;N;;;;;\n12170;CUNEIFORM SIGN KA TIMES KI;Lo;0;L;;;;;N;;;;;\n12171;CUNEIFORM SIGN KA TIMES KID;Lo;0;L;;;;;N;;;;;\n12172;CUNEIFORM SIGN KA TIMES LI;Lo;0;L;;;;;N;;;;;\n12173;CUNEIFORM SIGN KA TIMES LU;Lo;0;L;;;;;N;;;;;\n12174;CUNEIFORM SIGN KA TIMES ME;Lo;0;L;;;;;N;;;;;\n12175;CUNEIFORM SIGN KA TIMES ME PLUS DU;Lo;0;L;;;;;N;;;;;\n12176;CUNEIFORM SIGN KA TIMES ME PLUS GI;Lo;0;L;;;;;N;;;;;\n12177;CUNEIFORM SIGN KA TIMES ME PLUS TE;Lo;0;L;;;;;N;;;;;\n12178;CUNEIFORM SIGN KA TIMES MI;Lo;0;L;;;;;N;;;;;\n12179;CUNEIFORM SIGN KA TIMES MI PLUS NUNUZ;Lo;0;L;;;;;N;;;;;\n1217A;CUNEIFORM SIGN KA TIMES NE;Lo;0;L;;;;;N;;;;;\n1217B;CUNEIFORM SIGN KA TIMES NUN;Lo;0;L;;;;;N;;;;;\n1217C;CUNEIFORM SIGN KA TIMES PI;Lo;0;L;;;;;N;;;;;\n1217D;CUNEIFORM SIGN KA TIMES RU;Lo;0;L;;;;;N;;;;;\n1217E;CUNEIFORM SIGN KA TIMES SA;Lo;0;L;;;;;N;;;;;\n1217F;CUNEIFORM SIGN KA TIMES SAR;Lo;0;L;;;;;N;;;;;\n12180;CUNEIFORM SIGN KA TIMES SHA;Lo;0;L;;;;;N;;;;;\n12181;CUNEIFORM SIGN KA TIMES SHE;Lo;0;L;;;;;N;;;;;\n12182;CUNEIFORM SIGN KA TIMES SHID;Lo;0;L;;;;;N;;;;;\n12183;CUNEIFORM SIGN KA TIMES SHU;Lo;0;L;;;;;N;;;;;\n12184;CUNEIFORM SIGN KA TIMES SIG;Lo;0;L;;;;;N;;;;;\n12185;CUNEIFORM SIGN KA TIMES SUHUR;Lo;0;L;;;;;N;;;;;\n12186;CUNEIFORM SIGN KA TIMES TAR;Lo;0;L;;;;;N;;;;;\n12187;CUNEIFORM SIGN KA TIMES U;Lo;0;L;;;;;N;;;;;\n12188;CUNEIFORM SIGN KA TIMES U2;Lo;0;L;;;;;N;;;;;\n12189;CUNEIFORM SIGN KA TIMES UD;Lo;0;L;;;;;N;;;;;\n1218A;CUNEIFORM SIGN KA TIMES UMUM TIMES PA;Lo;0;L;;;;;N;;;;;\n1218B;CUNEIFORM SIGN KA TIMES USH;Lo;0;L;;;;;N;;;;;\n1218C;CUNEIFORM SIGN KA TIMES ZI;Lo;0;L;;;;;N;;;;;\n1218D;CUNEIFORM SIGN KA2;Lo;0;L;;;;;N;;;;;\n1218E;CUNEIFORM SIGN KA2 CROSSING KA2;Lo;0;L;;;;;N;;;;;\n1218F;CUNEIFORM SIGN KAB;Lo;0;L;;;;;N;;;;;\n12190;CUNEIFORM SIGN KAD2;Lo;0;L;;;;;N;;;;;\n12191;CUNEIFORM SIGN KAD3;Lo;0;L;;;;;N;;;;;\n12192;CUNEIFORM SIGN KAD4;Lo;0;L;;;;;N;;;;;\n12193;CUNEIFORM SIGN KAD5;Lo;0;L;;;;;N;;;;;\n12194;CUNEIFORM SIGN KAD5 OVER KAD5;Lo;0;L;;;;;N;;;;;\n12195;CUNEIFORM SIGN KAK;Lo;0;L;;;;;N;;;;;\n12196;CUNEIFORM SIGN KAK TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;\n12197;CUNEIFORM SIGN KAL;Lo;0;L;;;;;N;;;;;\n12198;CUNEIFORM SIGN KAL TIMES BAD;Lo;0;L;;;;;N;;;;;\n12199;CUNEIFORM SIGN KAL CROSSING KAL;Lo;0;L;;;;;N;;;;;\n1219A;CUNEIFORM SIGN KAM2;Lo;0;L;;;;;N;;;;;\n1219B;CUNEIFORM SIGN KAM4;Lo;0;L;;;;;N;;;;;\n1219C;CUNEIFORM SIGN KASKAL;Lo;0;L;;;;;N;;;;;\n1219D;CUNEIFORM SIGN KASKAL LAGAB TIMES U OVER LAGAB TIMES U;Lo;0;L;;;;;N;;;;;\n1219E;CUNEIFORM SIGN KASKAL OVER KASKAL LAGAB TIMES U OVER LAGAB TIMES U;Lo;0;L;;;;;N;;;;;\n1219F;CUNEIFORM SIGN KESH2;Lo;0;L;;;;;N;;;;;\n121A0;CUNEIFORM SIGN KI;Lo;0;L;;;;;N;;;;;\n121A1;CUNEIFORM SIGN KI TIMES BAD;Lo;0;L;;;;;N;;;;;\n121A2;CUNEIFORM SIGN KI TIMES U;Lo;0;L;;;;;N;;;;;\n121A3;CUNEIFORM SIGN KI TIMES UD;Lo;0;L;;;;;N;;;;;\n121A4;CUNEIFORM SIGN KID;Lo;0;L;;;;;N;;;;;\n121A5;CUNEIFORM SIGN KIN;Lo;0;L;;;;;N;;;;;\n121A6;CUNEIFORM SIGN KISAL;Lo;0;L;;;;;N;;;;;\n121A7;CUNEIFORM SIGN KISH;Lo;0;L;;;;;N;;;;;\n121A8;CUNEIFORM SIGN KISIM5;Lo;0;L;;;;;N;;;;;\n121A9;CUNEIFORM SIGN KISIM5 OVER KISIM5;Lo;0;L;;;;;N;;;;;\n121AA;CUNEIFORM SIGN KU;Lo;0;L;;;;;N;;;;;\n121AB;CUNEIFORM SIGN KU OVER HI TIMES ASH2 KU OVER HI TIMES ASH2;Lo;0;L;;;;;N;;;;;\n121AC;CUNEIFORM SIGN KU3;Lo;0;L;;;;;N;;;;;\n121AD;CUNEIFORM SIGN KU4;Lo;0;L;;;;;N;;;;;\n121AE;CUNEIFORM SIGN KU4 VARIANT FORM;Lo;0;L;;;;;N;;;;;\n121AF;CUNEIFORM SIGN KU7;Lo;0;L;;;;;N;;;;;\n121B0;CUNEIFORM SIGN KUL;Lo;0;L;;;;;N;;;;;\n121B1;CUNEIFORM SIGN KUL GUNU;Lo;0;L;;;;;N;;;;;\n121B2;CUNEIFORM SIGN KUN;Lo;0;L;;;;;N;;;;;\n121B3;CUNEIFORM SIGN KUR;Lo;0;L;;;;;N;;;;;\n121B4;CUNEIFORM SIGN KUR OPPOSING KUR;Lo;0;L;;;;;N;;;;;\n121B5;CUNEIFORM SIGN KUSHU2;Lo;0;L;;;;;N;;;;;\n121B6;CUNEIFORM SIGN KWU318;Lo;0;L;;;;;N;;;;;\n121B7;CUNEIFORM SIGN LA;Lo;0;L;;;;;N;;;;;\n121B8;CUNEIFORM SIGN LAGAB;Lo;0;L;;;;;N;;;;;\n121B9;CUNEIFORM SIGN LAGAB TIMES A;Lo;0;L;;;;;N;;;;;\n121BA;CUNEIFORM SIGN LAGAB TIMES A PLUS DA PLUS HA;Lo;0;L;;;;;N;;;;;\n121BB;CUNEIFORM SIGN LAGAB TIMES A PLUS GAR;Lo;0;L;;;;;N;;;;;\n121BC;CUNEIFORM SIGN LAGAB TIMES A PLUS LAL;Lo;0;L;;;;;N;;;;;\n121BD;CUNEIFORM SIGN LAGAB TIMES AL;Lo;0;L;;;;;N;;;;;\n121BE;CUNEIFORM SIGN LAGAB TIMES AN;Lo;0;L;;;;;N;;;;;\n121BF;CUNEIFORM SIGN LAGAB TIMES ASH ZIDA TENU;Lo;0;L;;;;;N;;;;;\n121C0;CUNEIFORM SIGN LAGAB TIMES BAD;Lo;0;L;;;;;N;;;;;\n121C1;CUNEIFORM SIGN LAGAB TIMES BI;Lo;0;L;;;;;N;;;;;\n121C2;CUNEIFORM SIGN LAGAB TIMES DAR;Lo;0;L;;;;;N;;;;;\n121C3;CUNEIFORM SIGN LAGAB TIMES EN;Lo;0;L;;;;;N;;;;;\n121C4;CUNEIFORM SIGN LAGAB TIMES GA;Lo;0;L;;;;;N;;;;;\n121C5;CUNEIFORM SIGN LAGAB TIMES GAR;Lo;0;L;;;;;N;;;;;\n121C6;CUNEIFORM SIGN LAGAB TIMES GUD;Lo;0;L;;;;;N;;;;;\n121C7;CUNEIFORM SIGN LAGAB TIMES GUD PLUS GUD;Lo;0;L;;;;;N;;;;;\n121C8;CUNEIFORM SIGN LAGAB TIMES HA;Lo;0;L;;;;;N;;;;;\n121C9;CUNEIFORM SIGN LAGAB TIMES HAL;Lo;0;L;;;;;N;;;;;\n121CA;CUNEIFORM SIGN LAGAB TIMES HI TIMES NUN;Lo;0;L;;;;;N;;;;;\n121CB;CUNEIFORM SIGN LAGAB TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;\n121CC;CUNEIFORM SIGN LAGAB TIMES IM;Lo;0;L;;;;;N;;;;;\n121CD;CUNEIFORM SIGN LAGAB TIMES IM PLUS HA;Lo;0;L;;;;;N;;;;;\n121CE;CUNEIFORM SIGN LAGAB TIMES IM PLUS LU;Lo;0;L;;;;;N;;;;;\n121CF;CUNEIFORM SIGN LAGAB TIMES KI;Lo;0;L;;;;;N;;;;;\n121D0;CUNEIFORM SIGN LAGAB TIMES KIN;Lo;0;L;;;;;N;;;;;\n121D1;CUNEIFORM SIGN LAGAB TIMES KU3;Lo;0;L;;;;;N;;;;;\n121D2;CUNEIFORM SIGN LAGAB TIMES KUL;Lo;0;L;;;;;N;;;;;\n121D3;CUNEIFORM SIGN LAGAB TIMES KUL PLUS HI PLUS A;Lo;0;L;;;;;N;;;;;\n121D4;CUNEIFORM SIGN LAGAB TIMES LAGAB;Lo;0;L;;;;;N;;;;;\n121D5;CUNEIFORM SIGN LAGAB TIMES LISH;Lo;0;L;;;;;N;;;;;\n121D6;CUNEIFORM SIGN LAGAB TIMES LU;Lo;0;L;;;;;N;;;;;\n121D7;CUNEIFORM SIGN LAGAB TIMES LUL;Lo;0;L;;;;;N;;;;;\n121D8;CUNEIFORM SIGN LAGAB TIMES ME;Lo;0;L;;;;;N;;;;;\n121D9;CUNEIFORM SIGN LAGAB TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;\n121DA;CUNEIFORM SIGN LAGAB TIMES MUSH;Lo;0;L;;;;;N;;;;;\n121DB;CUNEIFORM SIGN LAGAB TIMES NE;Lo;0;L;;;;;N;;;;;\n121DC;CUNEIFORM SIGN LAGAB TIMES SHE PLUS SUM;Lo;0;L;;;;;N;;;;;\n121DD;CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH PLUS ERIN2;Lo;0;L;;;;;N;;;;;\n121DE;CUNEIFORM SIGN LAGAB TIMES SHITA PLUS GISH TENU;Lo;0;L;;;;;N;;;;;\n121DF;CUNEIFORM SIGN LAGAB TIMES SHU2;Lo;0;L;;;;;N;;;;;\n121E0;CUNEIFORM SIGN LAGAB TIMES SHU2 PLUS SHU2;Lo;0;L;;;;;N;;;;;\n121E1;CUNEIFORM SIGN LAGAB TIMES SUM;Lo;0;L;;;;;N;;;;;\n121E2;CUNEIFORM SIGN LAGAB TIMES TAG;Lo;0;L;;;;;N;;;;;\n121E3;CUNEIFORM SIGN LAGAB TIMES TAK4;Lo;0;L;;;;;N;;;;;\n121E4;CUNEIFORM SIGN LAGAB TIMES TE PLUS A PLUS SU PLUS NA;Lo;0;L;;;;;N;;;;;\n121E5;CUNEIFORM SIGN LAGAB TIMES U;Lo;0;L;;;;;N;;;;;\n121E6;CUNEIFORM SIGN LAGAB TIMES U PLUS A;Lo;0;L;;;;;N;;;;;\n121E7;CUNEIFORM SIGN LAGAB TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;;\n121E8;CUNEIFORM SIGN LAGAB TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;;\n121E9;CUNEIFORM SIGN LAGAB TIMES UD;Lo;0;L;;;;;N;;;;;\n121EA;CUNEIFORM SIGN LAGAB TIMES USH;Lo;0;L;;;;;N;;;;;\n121EB;CUNEIFORM SIGN LAGAB SQUARED;Lo;0;L;;;;;N;;;;;\n121EC;CUNEIFORM SIGN LAGAR;Lo;0;L;;;;;N;;;;;\n121ED;CUNEIFORM SIGN LAGAR TIMES SHE;Lo;0;L;;;;;N;;;;;\n121EE;CUNEIFORM SIGN LAGAR TIMES SHE PLUS SUM;Lo;0;L;;;;;N;;;;;\n121EF;CUNEIFORM SIGN LAGAR GUNU;Lo;0;L;;;;;N;;;;;\n121F0;CUNEIFORM SIGN LAGAR GUNU OVER LAGAR GUNU SHE;Lo;0;L;;;;;N;;;;;\n121F1;CUNEIFORM SIGN LAHSHU;Lo;0;L;;;;;N;;;;;\n121F2;CUNEIFORM SIGN LAL;Lo;0;L;;;;;N;;;;;\n121F3;CUNEIFORM SIGN LAL TIMES LAL;Lo;0;L;;;;;N;;;;;\n121F4;CUNEIFORM SIGN LAM;Lo;0;L;;;;;N;;;;;\n121F5;CUNEIFORM SIGN LAM TIMES KUR;Lo;0;L;;;;;N;;;;;\n121F6;CUNEIFORM SIGN LAM TIMES KUR PLUS RU;Lo;0;L;;;;;N;;;;;\n121F7;CUNEIFORM SIGN LI;Lo;0;L;;;;;N;;;;;\n121F8;CUNEIFORM SIGN LIL;Lo;0;L;;;;;N;;;;;\n121F9;CUNEIFORM SIGN LIMMU2;Lo;0;L;;;;;N;;;;;\n121FA;CUNEIFORM SIGN LISH;Lo;0;L;;;;;N;;;;;\n121FB;CUNEIFORM SIGN LU;Lo;0;L;;;;;N;;;;;\n121FC;CUNEIFORM SIGN LU TIMES BAD;Lo;0;L;;;;;N;;;;;\n121FD;CUNEIFORM SIGN LU2;Lo;0;L;;;;;N;;;;;\n121FE;CUNEIFORM SIGN LU2 TIMES AL;Lo;0;L;;;;;N;;;;;\n121FF;CUNEIFORM SIGN LU2 TIMES BAD;Lo;0;L;;;;;N;;;;;\n12200;CUNEIFORM SIGN LU2 TIMES ESH2;Lo;0;L;;;;;N;;;;;\n12201;CUNEIFORM SIGN LU2 TIMES ESH2 TENU;Lo;0;L;;;;;N;;;;;\n12202;CUNEIFORM SIGN LU2 TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;\n12203;CUNEIFORM SIGN LU2 TIMES HI TIMES BAD;Lo;0;L;;;;;N;;;;;\n12204;CUNEIFORM SIGN LU2 TIMES IM;Lo;0;L;;;;;N;;;;;\n12205;CUNEIFORM SIGN LU2 TIMES KAD2;Lo;0;L;;;;;N;;;;;\n12206;CUNEIFORM SIGN LU2 TIMES KAD3;Lo;0;L;;;;;N;;;;;\n12207;CUNEIFORM SIGN LU2 TIMES KAD3 PLUS ASH;Lo;0;L;;;;;N;;;;;\n12208;CUNEIFORM SIGN LU2 TIMES KI;Lo;0;L;;;;;N;;;;;\n12209;CUNEIFORM SIGN LU2 TIMES LA PLUS ASH;Lo;0;L;;;;;N;;;;;\n1220A;CUNEIFORM SIGN LU2 TIMES LAGAB;Lo;0;L;;;;;N;;;;;\n1220B;CUNEIFORM SIGN LU2 TIMES ME PLUS EN;Lo;0;L;;;;;N;;;;;\n1220C;CUNEIFORM SIGN LU2 TIMES NE;Lo;0;L;;;;;N;;;;;\n1220D;CUNEIFORM SIGN LU2 TIMES NU;Lo;0;L;;;;;N;;;;;\n1220E;CUNEIFORM SIGN LU2 TIMES SI PLUS ASH;Lo;0;L;;;;;N;;;;;\n1220F;CUNEIFORM SIGN LU2 TIMES SIK2 PLUS BU;Lo;0;L;;;;;N;;;;;\n12210;CUNEIFORM SIGN LU2 TIMES TUG2;Lo;0;L;;;;;N;;;;;\n12211;CUNEIFORM SIGN LU2 TENU;Lo;0;L;;;;;N;;;;;\n12212;CUNEIFORM SIGN LU2 CROSSING LU2;Lo;0;L;;;;;N;;;;;\n12213;CUNEIFORM SIGN LU2 OPPOSING LU2;Lo;0;L;;;;;N;;;;;\n12214;CUNEIFORM SIGN LU2 SQUARED;Lo;0;L;;;;;N;;;;;\n12215;CUNEIFORM SIGN LU2 SHESHIG;Lo;0;L;;;;;N;;;;;\n12216;CUNEIFORM SIGN LU3;Lo;0;L;;;;;N;;;;;\n12217;CUNEIFORM SIGN LUGAL;Lo;0;L;;;;;N;;;;;\n12218;CUNEIFORM SIGN LUGAL OVER LUGAL;Lo;0;L;;;;;N;;;;;\n12219;CUNEIFORM SIGN LUGAL OPPOSING LUGAL;Lo;0;L;;;;;N;;;;;\n1221A;CUNEIFORM SIGN LUGAL SHESHIG;Lo;0;L;;;;;N;;;;;\n1221B;CUNEIFORM SIGN LUH;Lo;0;L;;;;;N;;;;;\n1221C;CUNEIFORM SIGN LUL;Lo;0;L;;;;;N;;;;;\n1221D;CUNEIFORM SIGN LUM;Lo;0;L;;;;;N;;;;;\n1221E;CUNEIFORM SIGN LUM OVER LUM;Lo;0;L;;;;;N;;;;;\n1221F;CUNEIFORM SIGN LUM OVER LUM GAR OVER GAR;Lo;0;L;;;;;N;;;;;\n12220;CUNEIFORM SIGN MA;Lo;0;L;;;;;N;;;;;\n12221;CUNEIFORM SIGN MA TIMES TAK4;Lo;0;L;;;;;N;;;;;\n12222;CUNEIFORM SIGN MA GUNU;Lo;0;L;;;;;N;;;;;\n12223;CUNEIFORM SIGN MA2;Lo;0;L;;;;;N;;;;;\n12224;CUNEIFORM SIGN MAH;Lo;0;L;;;;;N;;;;;\n12225;CUNEIFORM SIGN MAR;Lo;0;L;;;;;N;;;;;\n12226;CUNEIFORM SIGN MASH;Lo;0;L;;;;;N;;;;;\n12227;CUNEIFORM SIGN MASH2;Lo;0;L;;;;;N;;;;;\n12228;CUNEIFORM SIGN ME;Lo;0;L;;;;;N;;;;;\n12229;CUNEIFORM SIGN MES;Lo;0;L;;;;;N;;;;;\n1222A;CUNEIFORM SIGN MI;Lo;0;L;;;;;N;;;;;\n1222B;CUNEIFORM SIGN MIN;Lo;0;L;;;;;N;;;;;\n1222C;CUNEIFORM SIGN MU;Lo;0;L;;;;;N;;;;;\n1222D;CUNEIFORM SIGN MU OVER MU;Lo;0;L;;;;;N;;;;;\n1222E;CUNEIFORM SIGN MUG;Lo;0;L;;;;;N;;;;;\n1222F;CUNEIFORM SIGN MUG GUNU;Lo;0;L;;;;;N;;;;;\n12230;CUNEIFORM SIGN MUNSUB;Lo;0;L;;;;;N;;;;;\n12231;CUNEIFORM SIGN MURGU2;Lo;0;L;;;;;N;;;;;\n12232;CUNEIFORM SIGN MUSH;Lo;0;L;;;;;N;;;;;\n12233;CUNEIFORM SIGN MUSH TIMES A;Lo;0;L;;;;;N;;;;;\n12234;CUNEIFORM SIGN MUSH TIMES KUR;Lo;0;L;;;;;N;;;;;\n12235;CUNEIFORM SIGN MUSH TIMES ZA;Lo;0;L;;;;;N;;;;;\n12236;CUNEIFORM SIGN MUSH OVER MUSH;Lo;0;L;;;;;N;;;;;\n12237;CUNEIFORM SIGN MUSH OVER MUSH TIMES A PLUS NA;Lo;0;L;;;;;N;;;;;\n12238;CUNEIFORM SIGN MUSH CROSSING MUSH;Lo;0;L;;;;;N;;;;;\n12239;CUNEIFORM SIGN MUSH3;Lo;0;L;;;;;N;;;;;\n1223A;CUNEIFORM SIGN MUSH3 TIMES A;Lo;0;L;;;;;N;;;;;\n1223B;CUNEIFORM SIGN MUSH3 TIMES A PLUS DI;Lo;0;L;;;;;N;;;;;\n1223C;CUNEIFORM SIGN MUSH3 TIMES DI;Lo;0;L;;;;;N;;;;;\n1223D;CUNEIFORM SIGN MUSH3 GUNU;Lo;0;L;;;;;N;;;;;\n1223E;CUNEIFORM SIGN NA;Lo;0;L;;;;;N;;;;;\n1223F;CUNEIFORM SIGN NA2;Lo;0;L;;;;;N;;;;;\n12240;CUNEIFORM SIGN NAGA;Lo;0;L;;;;;N;;;;;\n12241;CUNEIFORM SIGN NAGA INVERTED;Lo;0;L;;;;;N;;;;;\n12242;CUNEIFORM SIGN NAGA TIMES SHU TENU;Lo;0;L;;;;;N;;;;;\n12243;CUNEIFORM SIGN NAGA OPPOSING NAGA;Lo;0;L;;;;;N;;;;;\n12244;CUNEIFORM SIGN NAGAR;Lo;0;L;;;;;N;;;;;\n12245;CUNEIFORM SIGN NAM NUTILLU;Lo;0;L;;;;;N;;;;;\n12246;CUNEIFORM SIGN NAM;Lo;0;L;;;;;N;;;;;\n12247;CUNEIFORM SIGN NAM2;Lo;0;L;;;;;N;;;;;\n12248;CUNEIFORM SIGN NE;Lo;0;L;;;;;N;;;;;\n12249;CUNEIFORM SIGN NE TIMES A;Lo;0;L;;;;;N;;;;;\n1224A;CUNEIFORM SIGN NE TIMES UD;Lo;0;L;;;;;N;;;;;\n1224B;CUNEIFORM SIGN NE SHESHIG;Lo;0;L;;;;;N;;;;;\n1224C;CUNEIFORM SIGN NI;Lo;0;L;;;;;N;;;;;\n1224D;CUNEIFORM SIGN NI TIMES E;Lo;0;L;;;;;N;;;;;\n1224E;CUNEIFORM SIGN NI2;Lo;0;L;;;;;N;;;;;\n1224F;CUNEIFORM SIGN NIM;Lo;0;L;;;;;N;;;;;\n12250;CUNEIFORM SIGN NIM TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;\n12251;CUNEIFORM SIGN NIM TIMES GAR PLUS GAN2 TENU;Lo;0;L;;;;;N;;;;;\n12252;CUNEIFORM SIGN NINDA2;Lo;0;L;;;;;N;;;;;\n12253;CUNEIFORM SIGN NINDA2 TIMES AN;Lo;0;L;;;;;N;;;;;\n12254;CUNEIFORM SIGN NINDA2 TIMES ASH;Lo;0;L;;;;;N;;;;;\n12255;CUNEIFORM SIGN NINDA2 TIMES ASH PLUS ASH;Lo;0;L;;;;;N;;;;;\n12256;CUNEIFORM SIGN NINDA2 TIMES GUD;Lo;0;L;;;;;N;;;;;\n12257;CUNEIFORM SIGN NINDA2 TIMES ME PLUS GAN2 TENU;Lo;0;L;;;;;N;;;;;\n12258;CUNEIFORM SIGN NINDA2 TIMES NE;Lo;0;L;;;;;N;;;;;\n12259;CUNEIFORM SIGN NINDA2 TIMES NUN;Lo;0;L;;;;;N;;;;;\n1225A;CUNEIFORM SIGN NINDA2 TIMES SHE;Lo;0;L;;;;;N;;;;;\n1225B;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS A AN;Lo;0;L;;;;;N;;;;;\n1225C;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH;Lo;0;L;;;;;N;;;;;\n1225D;CUNEIFORM SIGN NINDA2 TIMES SHE PLUS ASH PLUS ASH;Lo;0;L;;;;;N;;;;;\n1225E;CUNEIFORM SIGN NINDA2 TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;;\n1225F;CUNEIFORM SIGN NINDA2 TIMES USH;Lo;0;L;;;;;N;;;;;\n12260;CUNEIFORM SIGN NISAG;Lo;0;L;;;;;N;;;;;\n12261;CUNEIFORM SIGN NU;Lo;0;L;;;;;N;;;;;\n12262;CUNEIFORM SIGN NU11;Lo;0;L;;;;;N;;;;;\n12263;CUNEIFORM SIGN NUN;Lo;0;L;;;;;N;;;;;\n12264;CUNEIFORM SIGN NUN LAGAR TIMES GAR;Lo;0;L;;;;;N;;;;;\n12265;CUNEIFORM SIGN NUN LAGAR TIMES MASH;Lo;0;L;;;;;N;;;;;\n12266;CUNEIFORM SIGN NUN LAGAR TIMES SAL;Lo;0;L;;;;;N;;;;;\n12267;CUNEIFORM SIGN NUN LAGAR TIMES SAL OVER NUN LAGAR TIMES SAL;Lo;0;L;;;;;N;;;;;\n12268;CUNEIFORM SIGN NUN LAGAR TIMES USH;Lo;0;L;;;;;N;;;;;\n12269;CUNEIFORM SIGN NUN TENU;Lo;0;L;;;;;N;;;;;\n1226A;CUNEIFORM SIGN NUN OVER NUN;Lo;0;L;;;;;N;;;;;\n1226B;CUNEIFORM SIGN NUN CROSSING NUN;Lo;0;L;;;;;N;;;;;\n1226C;CUNEIFORM SIGN NUN CROSSING NUN LAGAR OVER LAGAR;Lo;0;L;;;;;N;;;;;\n1226D;CUNEIFORM SIGN NUNUZ;Lo;0;L;;;;;N;;;;;\n1226E;CUNEIFORM SIGN NUNUZ AB2 TIMES ASHGAB;Lo;0;L;;;;;N;;;;;\n1226F;CUNEIFORM SIGN NUNUZ AB2 TIMES BI;Lo;0;L;;;;;N;;;;;\n12270;CUNEIFORM SIGN NUNUZ AB2 TIMES DUG;Lo;0;L;;;;;N;;;;;\n12271;CUNEIFORM SIGN NUNUZ AB2 TIMES GUD;Lo;0;L;;;;;N;;;;;\n12272;CUNEIFORM SIGN NUNUZ AB2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;\n12273;CUNEIFORM SIGN NUNUZ AB2 TIMES KAD3;Lo;0;L;;;;;N;;;;;\n12274;CUNEIFORM SIGN NUNUZ AB2 TIMES LA;Lo;0;L;;;;;N;;;;;\n12275;CUNEIFORM SIGN NUNUZ AB2 TIMES NE;Lo;0;L;;;;;N;;;;;\n12276;CUNEIFORM SIGN NUNUZ AB2 TIMES SILA3;Lo;0;L;;;;;N;;;;;\n12277;CUNEIFORM SIGN NUNUZ AB2 TIMES U2;Lo;0;L;;;;;N;;;;;\n12278;CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI;Lo;0;L;;;;;N;;;;;\n12279;CUNEIFORM SIGN NUNUZ KISIM5 TIMES BI U;Lo;0;L;;;;;N;;;;;\n1227A;CUNEIFORM SIGN PA;Lo;0;L;;;;;N;;;;;\n1227B;CUNEIFORM SIGN PAD;Lo;0;L;;;;;N;;;;;\n1227C;CUNEIFORM SIGN PAN;Lo;0;L;;;;;N;;;;;\n1227D;CUNEIFORM SIGN PAP;Lo;0;L;;;;;N;;;;;\n1227E;CUNEIFORM SIGN PESH2;Lo;0;L;;;;;N;;;;;\n1227F;CUNEIFORM SIGN PI;Lo;0;L;;;;;N;;;;;\n12280;CUNEIFORM SIGN PI TIMES A;Lo;0;L;;;;;N;;;;;\n12281;CUNEIFORM SIGN PI TIMES AB;Lo;0;L;;;;;N;;;;;\n12282;CUNEIFORM SIGN PI TIMES BI;Lo;0;L;;;;;N;;;;;\n12283;CUNEIFORM SIGN PI TIMES BU;Lo;0;L;;;;;N;;;;;\n12284;CUNEIFORM SIGN PI TIMES E;Lo;0;L;;;;;N;;;;;\n12285;CUNEIFORM SIGN PI TIMES I;Lo;0;L;;;;;N;;;;;\n12286;CUNEIFORM SIGN PI TIMES IB;Lo;0;L;;;;;N;;;;;\n12287;CUNEIFORM SIGN PI TIMES U;Lo;0;L;;;;;N;;;;;\n12288;CUNEIFORM SIGN PI TIMES U2;Lo;0;L;;;;;N;;;;;\n12289;CUNEIFORM SIGN PI CROSSING PI;Lo;0;L;;;;;N;;;;;\n1228A;CUNEIFORM SIGN PIRIG;Lo;0;L;;;;;N;;;;;\n1228B;CUNEIFORM SIGN PIRIG TIMES KAL;Lo;0;L;;;;;N;;;;;\n1228C;CUNEIFORM SIGN PIRIG TIMES UD;Lo;0;L;;;;;N;;;;;\n1228D;CUNEIFORM SIGN PIRIG TIMES ZA;Lo;0;L;;;;;N;;;;;\n1228E;CUNEIFORM SIGN PIRIG OPPOSING PIRIG;Lo;0;L;;;;;N;;;;;\n1228F;CUNEIFORM SIGN RA;Lo;0;L;;;;;N;;;;;\n12290;CUNEIFORM SIGN RAB;Lo;0;L;;;;;N;;;;;\n12291;CUNEIFORM SIGN RI;Lo;0;L;;;;;N;;;;;\n12292;CUNEIFORM SIGN RU;Lo;0;L;;;;;N;;;;;\n12293;CUNEIFORM SIGN SA;Lo;0;L;;;;;N;;;;;\n12294;CUNEIFORM SIGN SAG NUTILLU;Lo;0;L;;;;;N;;;;;\n12295;CUNEIFORM SIGN SAG;Lo;0;L;;;;;N;;;;;\n12296;CUNEIFORM SIGN SAG TIMES A;Lo;0;L;;;;;N;;;;;\n12297;CUNEIFORM SIGN SAG TIMES DU;Lo;0;L;;;;;N;;;;;\n12298;CUNEIFORM SIGN SAG TIMES DUB;Lo;0;L;;;;;N;;;;;\n12299;CUNEIFORM SIGN SAG TIMES HA;Lo;0;L;;;;;N;;;;;\n1229A;CUNEIFORM SIGN SAG TIMES KAK;Lo;0;L;;;;;N;;;;;\n1229B;CUNEIFORM SIGN SAG TIMES KUR;Lo;0;L;;;;;N;;;;;\n1229C;CUNEIFORM SIGN SAG TIMES LUM;Lo;0;L;;;;;N;;;;;\n1229D;CUNEIFORM SIGN SAG TIMES MI;Lo;0;L;;;;;N;;;;;\n1229E;CUNEIFORM SIGN SAG TIMES NUN;Lo;0;L;;;;;N;;;;;\n1229F;CUNEIFORM SIGN SAG TIMES SAL;Lo;0;L;;;;;N;;;;;\n122A0;CUNEIFORM SIGN SAG TIMES SHID;Lo;0;L;;;;;N;;;;;\n122A1;CUNEIFORM SIGN SAG TIMES TAB;Lo;0;L;;;;;N;;;;;\n122A2;CUNEIFORM SIGN SAG TIMES U2;Lo;0;L;;;;;N;;;;;\n122A3;CUNEIFORM SIGN SAG TIMES UB;Lo;0;L;;;;;N;;;;;\n122A4;CUNEIFORM SIGN SAG TIMES UM;Lo;0;L;;;;;N;;;;;\n122A5;CUNEIFORM SIGN SAG TIMES UR;Lo;0;L;;;;;N;;;;;\n122A6;CUNEIFORM SIGN SAG TIMES USH;Lo;0;L;;;;;N;;;;;\n122A7;CUNEIFORM SIGN SAG OVER SAG;Lo;0;L;;;;;N;;;;;\n122A8;CUNEIFORM SIGN SAG GUNU;Lo;0;L;;;;;N;;;;;\n122A9;CUNEIFORM SIGN SAL;Lo;0;L;;;;;N;;;;;\n122AA;CUNEIFORM SIGN SAL LAGAB TIMES ASH2;Lo;0;L;;;;;N;;;;;\n122AB;CUNEIFORM SIGN SANGA2;Lo;0;L;;;;;N;;;;;\n122AC;CUNEIFORM SIGN SAR;Lo;0;L;;;;;N;;;;;\n122AD;CUNEIFORM SIGN SHA;Lo;0;L;;;;;N;;;;;\n122AE;CUNEIFORM SIGN SHA3;Lo;0;L;;;;;N;;;;;\n122AF;CUNEIFORM SIGN SHA3 TIMES A;Lo;0;L;;;;;N;;;;;\n122B0;CUNEIFORM SIGN SHA3 TIMES BAD;Lo;0;L;;;;;N;;;;;\n122B1;CUNEIFORM SIGN SHA3 TIMES GISH;Lo;0;L;;;;;N;;;;;\n122B2;CUNEIFORM SIGN SHA3 TIMES NE;Lo;0;L;;;;;N;;;;;\n122B3;CUNEIFORM SIGN SHA3 TIMES SHU2;Lo;0;L;;;;;N;;;;;\n122B4;CUNEIFORM SIGN SHA3 TIMES TUR;Lo;0;L;;;;;N;;;;;\n122B5;CUNEIFORM SIGN SHA3 TIMES U;Lo;0;L;;;;;N;;;;;\n122B6;CUNEIFORM SIGN SHA3 TIMES U PLUS A;Lo;0;L;;;;;N;;;;;\n122B7;CUNEIFORM SIGN SHA6;Lo;0;L;;;;;N;;;;;\n122B8;CUNEIFORM SIGN SHAB6;Lo;0;L;;;;;N;;;;;\n122B9;CUNEIFORM SIGN SHAR2;Lo;0;L;;;;;N;;;;;\n122BA;CUNEIFORM SIGN SHE;Lo;0;L;;;;;N;;;;;\n122BB;CUNEIFORM SIGN SHE HU;Lo;0;L;;;;;N;;;;;\n122BC;CUNEIFORM SIGN SHE OVER SHE GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;\n122BD;CUNEIFORM SIGN SHE OVER SHE TAB OVER TAB GAR OVER GAR;Lo;0;L;;;;;N;;;;;\n122BE;CUNEIFORM SIGN SHEG9;Lo;0;L;;;;;N;;;;;\n122BF;CUNEIFORM SIGN SHEN;Lo;0;L;;;;;N;;;;;\n122C0;CUNEIFORM SIGN SHESH;Lo;0;L;;;;;N;;;;;\n122C1;CUNEIFORM SIGN SHESH2;Lo;0;L;;;;;N;;;;;\n122C2;CUNEIFORM SIGN SHESHLAM;Lo;0;L;;;;;N;;;;;\n122C3;CUNEIFORM SIGN SHID;Lo;0;L;;;;;N;;;;;\n122C4;CUNEIFORM SIGN SHID TIMES A;Lo;0;L;;;;;N;;;;;\n122C5;CUNEIFORM SIGN SHID TIMES IM;Lo;0;L;;;;;N;;;;;\n122C6;CUNEIFORM SIGN SHIM;Lo;0;L;;;;;N;;;;;\n122C7;CUNEIFORM SIGN SHIM TIMES A;Lo;0;L;;;;;N;;;;;\n122C8;CUNEIFORM SIGN SHIM TIMES BAL;Lo;0;L;;;;;N;;;;;\n122C9;CUNEIFORM SIGN SHIM TIMES BULUG;Lo;0;L;;;;;N;;;;;\n122CA;CUNEIFORM SIGN SHIM TIMES DIN;Lo;0;L;;;;;N;;;;;\n122CB;CUNEIFORM SIGN SHIM TIMES GAR;Lo;0;L;;;;;N;;;;;\n122CC;CUNEIFORM SIGN SHIM TIMES IGI;Lo;0;L;;;;;N;;;;;\n122CD;CUNEIFORM SIGN SHIM TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;\n122CE;CUNEIFORM SIGN SHIM TIMES KUSHU2;Lo;0;L;;;;;N;;;;;\n122CF;CUNEIFORM SIGN SHIM TIMES LUL;Lo;0;L;;;;;N;;;;;\n122D0;CUNEIFORM SIGN SHIM TIMES MUG;Lo;0;L;;;;;N;;;;;\n122D1;CUNEIFORM SIGN SHIM TIMES SAL;Lo;0;L;;;;;N;;;;;\n122D2;CUNEIFORM SIGN SHINIG;Lo;0;L;;;;;N;;;;;\n122D3;CUNEIFORM SIGN SHIR;Lo;0;L;;;;;N;;;;;\n122D4;CUNEIFORM SIGN SHIR TENU;Lo;0;L;;;;;N;;;;;\n122D5;CUNEIFORM SIGN SHIR OVER SHIR BUR OVER BUR;Lo;0;L;;;;;N;;;;;\n122D6;CUNEIFORM SIGN SHITA;Lo;0;L;;;;;N;;;;;\n122D7;CUNEIFORM SIGN SHU;Lo;0;L;;;;;N;;;;;\n122D8;CUNEIFORM SIGN SHU OVER INVERTED SHU;Lo;0;L;;;;;N;;;;;\n122D9;CUNEIFORM SIGN SHU2;Lo;0;L;;;;;N;;;;;\n122DA;CUNEIFORM SIGN SHUBUR;Lo;0;L;;;;;N;;;;;\n122DB;CUNEIFORM SIGN SI;Lo;0;L;;;;;N;;;;;\n122DC;CUNEIFORM SIGN SI GUNU;Lo;0;L;;;;;N;;;;;\n122DD;CUNEIFORM SIGN SIG;Lo;0;L;;;;;N;;;;;\n122DE;CUNEIFORM SIGN SIG4;Lo;0;L;;;;;N;;;;;\n122DF;CUNEIFORM SIGN SIG4 OVER SIG4 SHU2;Lo;0;L;;;;;N;;;;;\n122E0;CUNEIFORM SIGN SIK2;Lo;0;L;;;;;N;;;;;\n122E1;CUNEIFORM SIGN SILA3;Lo;0;L;;;;;N;;;;;\n122E2;CUNEIFORM SIGN SU;Lo;0;L;;;;;N;;;;;\n122E3;CUNEIFORM SIGN SU OVER SU;Lo;0;L;;;;;N;;;;;\n122E4;CUNEIFORM SIGN SUD;Lo;0;L;;;;;N;;;;;\n122E5;CUNEIFORM SIGN SUD2;Lo;0;L;;;;;N;;;;;\n122E6;CUNEIFORM SIGN SUHUR;Lo;0;L;;;;;N;;;;;\n122E7;CUNEIFORM SIGN SUM;Lo;0;L;;;;;N;;;;;\n122E8;CUNEIFORM SIGN SUMASH;Lo;0;L;;;;;N;;;;;\n122E9;CUNEIFORM SIGN SUR;Lo;0;L;;;;;N;;;;;\n122EA;CUNEIFORM SIGN SUR9;Lo;0;L;;;;;N;;;;;\n122EB;CUNEIFORM SIGN TA;Lo;0;L;;;;;N;;;;;\n122EC;CUNEIFORM SIGN TA ASTERISK;Lo;0;L;;;;;N;;;;;\n122ED;CUNEIFORM SIGN TA TIMES HI;Lo;0;L;;;;;N;;;;;\n122EE;CUNEIFORM SIGN TA TIMES MI;Lo;0;L;;;;;N;;;;;\n122EF;CUNEIFORM SIGN TA GUNU;Lo;0;L;;;;;N;;;;;\n122F0;CUNEIFORM SIGN TAB;Lo;0;L;;;;;N;;;;;\n122F1;CUNEIFORM SIGN TAB OVER TAB NI OVER NI DISH OVER DISH;Lo;0;L;;;;;N;;;;;\n122F2;CUNEIFORM SIGN TAB SQUARED;Lo;0;L;;;;;N;;;;;\n122F3;CUNEIFORM SIGN TAG;Lo;0;L;;;;;N;;;;;\n122F4;CUNEIFORM SIGN TAG TIMES BI;Lo;0;L;;;;;N;;;;;\n122F5;CUNEIFORM SIGN TAG TIMES GUD;Lo;0;L;;;;;N;;;;;\n122F6;CUNEIFORM SIGN TAG TIMES SHE;Lo;0;L;;;;;N;;;;;\n122F7;CUNEIFORM SIGN TAG TIMES SHU;Lo;0;L;;;;;N;;;;;\n122F8;CUNEIFORM SIGN TAG TIMES TUG2;Lo;0;L;;;;;N;;;;;\n122F9;CUNEIFORM SIGN TAG TIMES UD;Lo;0;L;;;;;N;;;;;\n122FA;CUNEIFORM SIGN TAK4;Lo;0;L;;;;;N;;;;;\n122FB;CUNEIFORM SIGN TAR;Lo;0;L;;;;;N;;;;;\n122FC;CUNEIFORM SIGN TE;Lo;0;L;;;;;N;;;;;\n122FD;CUNEIFORM SIGN TE GUNU;Lo;0;L;;;;;N;;;;;\n122FE;CUNEIFORM SIGN TI;Lo;0;L;;;;;N;;;;;\n122FF;CUNEIFORM SIGN TI TENU;Lo;0;L;;;;;N;;;;;\n12300;CUNEIFORM SIGN TIL;Lo;0;L;;;;;N;;;;;\n12301;CUNEIFORM SIGN TIR;Lo;0;L;;;;;N;;;;;\n12302;CUNEIFORM SIGN TIR TIMES TAK4;Lo;0;L;;;;;N;;;;;\n12303;CUNEIFORM SIGN TIR OVER TIR;Lo;0;L;;;;;N;;;;;\n12304;CUNEIFORM SIGN TIR OVER TIR GAD OVER GAD GAR OVER GAR;Lo;0;L;;;;;N;;;;;\n12305;CUNEIFORM SIGN TU;Lo;0;L;;;;;N;;;;;\n12306;CUNEIFORM SIGN TUG2;Lo;0;L;;;;;N;;;;;\n12307;CUNEIFORM SIGN TUK;Lo;0;L;;;;;N;;;;;\n12308;CUNEIFORM SIGN TUM;Lo;0;L;;;;;N;;;;;\n12309;CUNEIFORM SIGN TUR;Lo;0;L;;;;;N;;;;;\n1230A;CUNEIFORM SIGN TUR OVER TUR ZA OVER ZA;Lo;0;L;;;;;N;;;;;\n1230B;CUNEIFORM SIGN U;Lo;0;L;;;;;N;;;;;\n1230C;CUNEIFORM SIGN U GUD;Lo;0;L;;;;;N;;;;;\n1230D;CUNEIFORM SIGN U U U;Lo;0;L;;;;;N;;;;;\n1230E;CUNEIFORM SIGN U OVER U PA OVER PA GAR OVER GAR;Lo;0;L;;;;;N;;;;;\n1230F;CUNEIFORM SIGN U OVER U SUR OVER SUR;Lo;0;L;;;;;N;;;;;\n12310;CUNEIFORM SIGN U OVER U U REVERSED OVER U REVERSED;Lo;0;L;;;;;N;;;;;\n12311;CUNEIFORM SIGN U2;Lo;0;L;;;;;N;;;;;\n12312;CUNEIFORM SIGN UB;Lo;0;L;;;;;N;;;;;\n12313;CUNEIFORM SIGN UD;Lo;0;L;;;;;N;;;;;\n12314;CUNEIFORM SIGN UD KUSHU2;Lo;0;L;;;;;N;;;;;\n12315;CUNEIFORM SIGN UD TIMES BAD;Lo;0;L;;;;;N;;;;;\n12316;CUNEIFORM SIGN UD TIMES MI;Lo;0;L;;;;;N;;;;;\n12317;CUNEIFORM SIGN UD TIMES U PLUS U PLUS U;Lo;0;L;;;;;N;;;;;\n12318;CUNEIFORM SIGN UD TIMES U PLUS U PLUS U GUNU;Lo;0;L;;;;;N;;;;;\n12319;CUNEIFORM SIGN UD GUNU;Lo;0;L;;;;;N;;;;;\n1231A;CUNEIFORM SIGN UD SHESHIG;Lo;0;L;;;;;N;;;;;\n1231B;CUNEIFORM SIGN UD SHESHIG TIMES BAD;Lo;0;L;;;;;N;;;;;\n1231C;CUNEIFORM SIGN UDUG;Lo;0;L;;;;;N;;;;;\n1231D;CUNEIFORM SIGN UM;Lo;0;L;;;;;N;;;;;\n1231E;CUNEIFORM SIGN UM TIMES LAGAB;Lo;0;L;;;;;N;;;;;\n1231F;CUNEIFORM SIGN UM TIMES ME PLUS DA;Lo;0;L;;;;;N;;;;;\n12320;CUNEIFORM SIGN UM TIMES SHA3;Lo;0;L;;;;;N;;;;;\n12321;CUNEIFORM SIGN UM TIMES U;Lo;0;L;;;;;N;;;;;\n12322;CUNEIFORM SIGN UMBIN;Lo;0;L;;;;;N;;;;;\n12323;CUNEIFORM SIGN UMUM;Lo;0;L;;;;;N;;;;;\n12324;CUNEIFORM SIGN UMUM TIMES KASKAL;Lo;0;L;;;;;N;;;;;\n12325;CUNEIFORM SIGN UMUM TIMES PA;Lo;0;L;;;;;N;;;;;\n12326;CUNEIFORM SIGN UN;Lo;0;L;;;;;N;;;;;\n12327;CUNEIFORM SIGN UN GUNU;Lo;0;L;;;;;N;;;;;\n12328;CUNEIFORM SIGN UR;Lo;0;L;;;;;N;;;;;\n12329;CUNEIFORM SIGN UR CROSSING UR;Lo;0;L;;;;;N;;;;;\n1232A;CUNEIFORM SIGN UR SHESHIG;Lo;0;L;;;;;N;;;;;\n1232B;CUNEIFORM SIGN UR2;Lo;0;L;;;;;N;;;;;\n1232C;CUNEIFORM SIGN UR2 TIMES A PLUS HA;Lo;0;L;;;;;N;;;;;\n1232D;CUNEIFORM SIGN UR2 TIMES A PLUS NA;Lo;0;L;;;;;N;;;;;\n1232E;CUNEIFORM SIGN UR2 TIMES AL;Lo;0;L;;;;;N;;;;;\n1232F;CUNEIFORM SIGN UR2 TIMES HA;Lo;0;L;;;;;N;;;;;\n12330;CUNEIFORM SIGN UR2 TIMES NUN;Lo;0;L;;;;;N;;;;;\n12331;CUNEIFORM SIGN UR2 TIMES U2;Lo;0;L;;;;;N;;;;;\n12332;CUNEIFORM SIGN UR2 TIMES U2 PLUS ASH;Lo;0;L;;;;;N;;;;;\n12333;CUNEIFORM SIGN UR2 TIMES U2 PLUS BI;Lo;0;L;;;;;N;;;;;\n12334;CUNEIFORM SIGN UR4;Lo;0;L;;;;;N;;;;;\n12335;CUNEIFORM SIGN URI;Lo;0;L;;;;;N;;;;;\n12336;CUNEIFORM SIGN URI3;Lo;0;L;;;;;N;;;;;\n12337;CUNEIFORM SIGN URU;Lo;0;L;;;;;N;;;;;\n12338;CUNEIFORM SIGN URU TIMES A;Lo;0;L;;;;;N;;;;;\n12339;CUNEIFORM SIGN URU TIMES ASHGAB;Lo;0;L;;;;;N;;;;;\n1233A;CUNEIFORM SIGN URU TIMES BAR;Lo;0;L;;;;;N;;;;;\n1233B;CUNEIFORM SIGN URU TIMES DUN;Lo;0;L;;;;;N;;;;;\n1233C;CUNEIFORM SIGN URU TIMES GA;Lo;0;L;;;;;N;;;;;\n1233D;CUNEIFORM SIGN URU TIMES GAL;Lo;0;L;;;;;N;;;;;\n1233E;CUNEIFORM SIGN URU TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;\n1233F;CUNEIFORM SIGN URU TIMES GAR;Lo;0;L;;;;;N;;;;;\n12340;CUNEIFORM SIGN URU TIMES GU;Lo;0;L;;;;;N;;;;;\n12341;CUNEIFORM SIGN URU TIMES HA;Lo;0;L;;;;;N;;;;;\n12342;CUNEIFORM SIGN URU TIMES IGI;Lo;0;L;;;;;N;;;;;\n12343;CUNEIFORM SIGN URU TIMES IM;Lo;0;L;;;;;N;;;;;\n12344;CUNEIFORM SIGN URU TIMES ISH;Lo;0;L;;;;;N;;;;;\n12345;CUNEIFORM SIGN URU TIMES KI;Lo;0;L;;;;;N;;;;;\n12346;CUNEIFORM SIGN URU TIMES LUM;Lo;0;L;;;;;N;;;;;\n12347;CUNEIFORM SIGN URU TIMES MIN;Lo;0;L;;;;;N;;;;;\n12348;CUNEIFORM SIGN URU TIMES PA;Lo;0;L;;;;;N;;;;;\n12349;CUNEIFORM SIGN URU TIMES SHE;Lo;0;L;;;;;N;;;;;\n1234A;CUNEIFORM SIGN URU TIMES SIG4;Lo;0;L;;;;;N;;;;;\n1234B;CUNEIFORM SIGN URU TIMES TU;Lo;0;L;;;;;N;;;;;\n1234C;CUNEIFORM SIGN URU TIMES U PLUS GUD;Lo;0;L;;;;;N;;;;;\n1234D;CUNEIFORM SIGN URU TIMES UD;Lo;0;L;;;;;N;;;;;\n1234E;CUNEIFORM SIGN URU TIMES URUDA;Lo;0;L;;;;;N;;;;;\n1234F;CUNEIFORM SIGN URUDA;Lo;0;L;;;;;N;;;;;\n12350;CUNEIFORM SIGN URUDA TIMES U;Lo;0;L;;;;;N;;;;;\n12351;CUNEIFORM SIGN USH;Lo;0;L;;;;;N;;;;;\n12352;CUNEIFORM SIGN USH TIMES A;Lo;0;L;;;;;N;;;;;\n12353;CUNEIFORM SIGN USH TIMES KU;Lo;0;L;;;;;N;;;;;\n12354;CUNEIFORM SIGN USH TIMES KUR;Lo;0;L;;;;;N;;;;;\n12355;CUNEIFORM SIGN USH TIMES TAK4;Lo;0;L;;;;;N;;;;;\n12356;CUNEIFORM SIGN USHX;Lo;0;L;;;;;N;;;;;\n12357;CUNEIFORM SIGN USH2;Lo;0;L;;;;;N;;;;;\n12358;CUNEIFORM SIGN USHUMX;Lo;0;L;;;;;N;;;;;\n12359;CUNEIFORM SIGN UTUKI;Lo;0;L;;;;;N;;;;;\n1235A;CUNEIFORM SIGN UZ3;Lo;0;L;;;;;N;;;;;\n1235B;CUNEIFORM SIGN UZ3 TIMES KASKAL;Lo;0;L;;;;;N;;;;;\n1235C;CUNEIFORM SIGN UZU;Lo;0;L;;;;;N;;;;;\n1235D;CUNEIFORM SIGN ZA;Lo;0;L;;;;;N;;;;;\n1235E;CUNEIFORM SIGN ZA TENU;Lo;0;L;;;;;N;;;;;\n1235F;CUNEIFORM SIGN ZA SQUARED TIMES KUR;Lo;0;L;;;;;N;;;;;\n12360;CUNEIFORM SIGN ZAG;Lo;0;L;;;;;N;;;;;\n12361;CUNEIFORM SIGN ZAMX;Lo;0;L;;;;;N;;;;;\n12362;CUNEIFORM SIGN ZE2;Lo;0;L;;;;;N;;;;;\n12363;CUNEIFORM SIGN ZI;Lo;0;L;;;;;N;;;;;\n12364;CUNEIFORM SIGN ZI OVER ZI;Lo;0;L;;;;;N;;;;;\n12365;CUNEIFORM SIGN ZI3;Lo;0;L;;;;;N;;;;;\n12366;CUNEIFORM SIGN ZIB;Lo;0;L;;;;;N;;;;;\n12367;CUNEIFORM SIGN ZIB KABA TENU;Lo;0;L;;;;;N;;;;;\n12368;CUNEIFORM SIGN ZIG;Lo;0;L;;;;;N;;;;;\n12369;CUNEIFORM SIGN ZIZ2;Lo;0;L;;;;;N;;;;;\n1236A;CUNEIFORM SIGN ZU;Lo;0;L;;;;;N;;;;;\n1236B;CUNEIFORM SIGN ZU5;Lo;0;L;;;;;N;;;;;\n1236C;CUNEIFORM SIGN ZU5 TIMES A;Lo;0;L;;;;;N;;;;;\n1236D;CUNEIFORM SIGN ZUBUR;Lo;0;L;;;;;N;;;;;\n1236E;CUNEIFORM SIGN ZUM;Lo;0;L;;;;;N;;;;;\n1236F;CUNEIFORM SIGN KAP ELAMITE;Lo;0;L;;;;;N;;;;;\n12370;CUNEIFORM SIGN AB TIMES NUN;Lo;0;L;;;;;N;;;;;\n12371;CUNEIFORM SIGN AB2 TIMES A;Lo;0;L;;;;;N;;;;;\n12372;CUNEIFORM SIGN AMAR TIMES KUG;Lo;0;L;;;;;N;;;;;\n12373;CUNEIFORM SIGN DAG KISIM5 TIMES U2 PLUS MASH;Lo;0;L;;;;;N;;;;;\n12374;CUNEIFORM SIGN DAG3;Lo;0;L;;;;;N;;;;;\n12375;CUNEIFORM SIGN DISH PLUS SHU;Lo;0;L;;;;;N;;;;;\n12376;CUNEIFORM SIGN DUB TIMES SHE;Lo;0;L;;;;;N;;;;;\n12377;CUNEIFORM SIGN EZEN TIMES GUD;Lo;0;L;;;;;N;;;;;\n12378;CUNEIFORM SIGN EZEN TIMES SHE;Lo;0;L;;;;;N;;;;;\n12379;CUNEIFORM SIGN GA2 TIMES AN PLUS KAK PLUS A;Lo;0;L;;;;;N;;;;;\n1237A;CUNEIFORM SIGN GA2 TIMES ASH2;Lo;0;L;;;;;N;;;;;\n1237B;CUNEIFORM SIGN GE22;Lo;0;L;;;;;N;;;;;\n1237C;CUNEIFORM SIGN GIG;Lo;0;L;;;;;N;;;;;\n1237D;CUNEIFORM SIGN HUSH;Lo;0;L;;;;;N;;;;;\n1237E;CUNEIFORM SIGN KA TIMES ANSHE;Lo;0;L;;;;;N;;;;;\n1237F;CUNEIFORM SIGN KA TIMES ASH3;Lo;0;L;;;;;N;;;;;\n12380;CUNEIFORM SIGN KA TIMES GISH;Lo;0;L;;;;;N;;;;;\n12381;CUNEIFORM SIGN KA TIMES GUD;Lo;0;L;;;;;N;;;;;\n12382;CUNEIFORM SIGN KA TIMES HI TIMES ASH2;Lo;0;L;;;;;N;;;;;\n12383;CUNEIFORM SIGN KA TIMES LUM;Lo;0;L;;;;;N;;;;;\n12384;CUNEIFORM SIGN KA TIMES PA;Lo;0;L;;;;;N;;;;;\n12385;CUNEIFORM SIGN KA TIMES SHUL;Lo;0;L;;;;;N;;;;;\n12386;CUNEIFORM SIGN KA TIMES TU;Lo;0;L;;;;;N;;;;;\n12387;CUNEIFORM SIGN KA TIMES UR2;Lo;0;L;;;;;N;;;;;\n12388;CUNEIFORM SIGN LAGAB TIMES GI;Lo;0;L;;;;;N;;;;;\n12389;CUNEIFORM SIGN LU2 SHESHIG TIMES BAD;Lo;0;L;;;;;N;;;;;\n1238A;CUNEIFORM SIGN LU2 TIMES ESH2 PLUS LAL;Lo;0;L;;;;;N;;;;;\n1238B;CUNEIFORM SIGN LU2 TIMES SHU;Lo;0;L;;;;;N;;;;;\n1238C;CUNEIFORM SIGN MESH;Lo;0;L;;;;;N;;;;;\n1238D;CUNEIFORM SIGN MUSH3 TIMES ZA;Lo;0;L;;;;;N;;;;;\n1238E;CUNEIFORM SIGN NA4;Lo;0;L;;;;;N;;;;;\n1238F;CUNEIFORM SIGN NIN;Lo;0;L;;;;;N;;;;;\n12390;CUNEIFORM SIGN NIN9;Lo;0;L;;;;;N;;;;;\n12391;CUNEIFORM SIGN NINDA2 TIMES BAL;Lo;0;L;;;;;N;;;;;\n12392;CUNEIFORM SIGN NINDA2 TIMES GI;Lo;0;L;;;;;N;;;;;\n12393;CUNEIFORM SIGN NU11 ROTATED NINETY DEGREES;Lo;0;L;;;;;N;;;;;\n12394;CUNEIFORM SIGN PESH2 ASTERISK;Lo;0;L;;;;;N;;;;;\n12395;CUNEIFORM SIGN PIR2;Lo;0;L;;;;;N;;;;;\n12396;CUNEIFORM SIGN SAG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;\n12397;CUNEIFORM SIGN TI2;Lo;0;L;;;;;N;;;;;\n12398;CUNEIFORM SIGN UM TIMES ME;Lo;0;L;;;;;N;;;;;\n12399;CUNEIFORM SIGN U U;Lo;0;L;;;;;N;;;;;\n12400;CUNEIFORM NUMERIC SIGN TWO ASH;Nl;0;L;;;;2;N;;;;;\n12401;CUNEIFORM NUMERIC SIGN THREE ASH;Nl;0;L;;;;3;N;;;;;\n12402;CUNEIFORM NUMERIC SIGN FOUR ASH;Nl;0;L;;;;4;N;;;;;\n12403;CUNEIFORM NUMERIC SIGN FIVE ASH;Nl;0;L;;;;5;N;;;;;\n12404;CUNEIFORM NUMERIC SIGN SIX ASH;Nl;0;L;;;;6;N;;;;;\n12405;CUNEIFORM NUMERIC SIGN SEVEN ASH;Nl;0;L;;;;7;N;;;;;\n12406;CUNEIFORM NUMERIC SIGN EIGHT ASH;Nl;0;L;;;;8;N;;;;;\n12407;CUNEIFORM NUMERIC SIGN NINE ASH;Nl;0;L;;;;9;N;;;;;\n12408;CUNEIFORM NUMERIC SIGN THREE DISH;Nl;0;L;;;;3;N;;;;;\n12409;CUNEIFORM NUMERIC SIGN FOUR DISH;Nl;0;L;;;;4;N;;;;;\n1240A;CUNEIFORM NUMERIC SIGN FIVE DISH;Nl;0;L;;;;5;N;;;;;\n1240B;CUNEIFORM NUMERIC SIGN SIX DISH;Nl;0;L;;;;6;N;;;;;\n1240C;CUNEIFORM NUMERIC SIGN SEVEN DISH;Nl;0;L;;;;7;N;;;;;\n1240D;CUNEIFORM NUMERIC SIGN EIGHT DISH;Nl;0;L;;;;8;N;;;;;\n1240E;CUNEIFORM NUMERIC SIGN NINE DISH;Nl;0;L;;;;9;N;;;;;\n1240F;CUNEIFORM NUMERIC SIGN FOUR U;Nl;0;L;;;;4;N;;;;;\n12410;CUNEIFORM NUMERIC SIGN FIVE U;Nl;0;L;;;;5;N;;;;;\n12411;CUNEIFORM NUMERIC SIGN SIX U;Nl;0;L;;;;6;N;;;;;\n12412;CUNEIFORM NUMERIC SIGN SEVEN U;Nl;0;L;;;;7;N;;;;;\n12413;CUNEIFORM NUMERIC SIGN EIGHT U;Nl;0;L;;;;8;N;;;;;\n12414;CUNEIFORM NUMERIC SIGN NINE U;Nl;0;L;;;;9;N;;;;;\n12415;CUNEIFORM NUMERIC SIGN ONE GESH2;Nl;0;L;;;;1;N;;;;;\n12416;CUNEIFORM NUMERIC SIGN TWO GESH2;Nl;0;L;;;;2;N;;;;;\n12417;CUNEIFORM NUMERIC SIGN THREE GESH2;Nl;0;L;;;;3;N;;;;;\n12418;CUNEIFORM NUMERIC SIGN FOUR GESH2;Nl;0;L;;;;4;N;;;;;\n12419;CUNEIFORM NUMERIC SIGN FIVE GESH2;Nl;0;L;;;;5;N;;;;;\n1241A;CUNEIFORM NUMERIC SIGN SIX GESH2;Nl;0;L;;;;6;N;;;;;\n1241B;CUNEIFORM NUMERIC SIGN SEVEN GESH2;Nl;0;L;;;;7;N;;;;;\n1241C;CUNEIFORM NUMERIC SIGN EIGHT GESH2;Nl;0;L;;;;8;N;;;;;\n1241D;CUNEIFORM NUMERIC SIGN NINE GESH2;Nl;0;L;;;;9;N;;;;;\n1241E;CUNEIFORM NUMERIC SIGN ONE GESHU;Nl;0;L;;;;1;N;;;;;\n1241F;CUNEIFORM NUMERIC SIGN TWO GESHU;Nl;0;L;;;;2;N;;;;;\n12420;CUNEIFORM NUMERIC SIGN THREE GESHU;Nl;0;L;;;;3;N;;;;;\n12421;CUNEIFORM NUMERIC SIGN FOUR GESHU;Nl;0;L;;;;4;N;;;;;\n12422;CUNEIFORM NUMERIC SIGN FIVE GESHU;Nl;0;L;;;;5;N;;;;;\n12423;CUNEIFORM NUMERIC SIGN TWO SHAR2;Nl;0;L;;;;2;N;;;;;\n12424;CUNEIFORM NUMERIC SIGN THREE SHAR2;Nl;0;L;;;;3;N;;;;;\n12425;CUNEIFORM NUMERIC SIGN THREE SHAR2 VARIANT FORM;Nl;0;L;;;;3;N;;;;;\n12426;CUNEIFORM NUMERIC SIGN FOUR SHAR2;Nl;0;L;;;;4;N;;;;;\n12427;CUNEIFORM NUMERIC SIGN FIVE SHAR2;Nl;0;L;;;;5;N;;;;;\n12428;CUNEIFORM NUMERIC SIGN SIX SHAR2;Nl;0;L;;;;6;N;;;;;\n12429;CUNEIFORM NUMERIC SIGN SEVEN SHAR2;Nl;0;L;;;;7;N;;;;;\n1242A;CUNEIFORM NUMERIC SIGN EIGHT SHAR2;Nl;0;L;;;;8;N;;;;;\n1242B;CUNEIFORM NUMERIC SIGN NINE SHAR2;Nl;0;L;;;;9;N;;;;;\n1242C;CUNEIFORM NUMERIC SIGN ONE SHARU;Nl;0;L;;;;1;N;;;;;\n1242D;CUNEIFORM NUMERIC SIGN TWO SHARU;Nl;0;L;;;;2;N;;;;;\n1242E;CUNEIFORM NUMERIC SIGN THREE SHARU;Nl;0;L;;;;3;N;;;;;\n1242F;CUNEIFORM NUMERIC SIGN THREE SHARU VARIANT FORM;Nl;0;L;;;;3;N;;;;;\n12430;CUNEIFORM NUMERIC SIGN FOUR SHARU;Nl;0;L;;;;4;N;;;;;\n12431;CUNEIFORM NUMERIC SIGN FIVE SHARU;Nl;0;L;;;;5;N;;;;;\n12432;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS DISH;Nl;0;L;;;;216000;N;;;;;\n12433;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS MIN;Nl;0;L;;;;432000;N;;;;;\n12434;CUNEIFORM NUMERIC SIGN ONE BURU;Nl;0;L;;;;1;N;;;;;\n12435;CUNEIFORM NUMERIC SIGN TWO BURU;Nl;0;L;;;;2;N;;;;;\n12436;CUNEIFORM NUMERIC SIGN THREE BURU;Nl;0;L;;;;3;N;;;;;\n12437;CUNEIFORM NUMERIC SIGN THREE BURU VARIANT FORM;Nl;0;L;;;;3;N;;;;;\n12438;CUNEIFORM NUMERIC SIGN FOUR BURU;Nl;0;L;;;;4;N;;;;;\n12439;CUNEIFORM NUMERIC SIGN FIVE BURU;Nl;0;L;;;;5;N;;;;;\n1243A;CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH16;Nl;0;L;;;;3;N;;;;;\n1243B;CUNEIFORM NUMERIC SIGN THREE VARIANT FORM ESH21;Nl;0;L;;;;3;N;;;;;\n1243C;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU;Nl;0;L;;;;4;N;;;;;\n1243D;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU4;Nl;0;L;;;;4;N;;;;;\n1243E;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU A;Nl;0;L;;;;4;N;;;;;\n1243F;CUNEIFORM NUMERIC SIGN FOUR VARIANT FORM LIMMU B;Nl;0;L;;;;4;N;;;;;\n12440;CUNEIFORM NUMERIC SIGN SIX VARIANT FORM ASH9;Nl;0;L;;;;6;N;;;;;\n12441;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN3;Nl;0;L;;;;7;N;;;;;\n12442;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN A;Nl;0;L;;;;7;N;;;;;\n12443;CUNEIFORM NUMERIC SIGN SEVEN VARIANT FORM IMIN B;Nl;0;L;;;;7;N;;;;;\n12444;CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU;Nl;0;L;;;;8;N;;;;;\n12445;CUNEIFORM NUMERIC SIGN EIGHT VARIANT FORM USSU3;Nl;0;L;;;;8;N;;;;;\n12446;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU;Nl;0;L;;;;9;N;;;;;\n12447;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU3;Nl;0;L;;;;9;N;;;;;\n12448;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU4;Nl;0;L;;;;9;N;;;;;\n12449;CUNEIFORM NUMERIC SIGN NINE VARIANT FORM ILIMMU A;Nl;0;L;;;;9;N;;;;;\n1244A;CUNEIFORM NUMERIC SIGN TWO ASH TENU;Nl;0;L;;;;2;N;;;;;\n1244B;CUNEIFORM NUMERIC SIGN THREE ASH TENU;Nl;0;L;;;;3;N;;;;;\n1244C;CUNEIFORM NUMERIC SIGN FOUR ASH TENU;Nl;0;L;;;;4;N;;;;;\n1244D;CUNEIFORM NUMERIC SIGN FIVE ASH TENU;Nl;0;L;;;;5;N;;;;;\n1244E;CUNEIFORM NUMERIC SIGN SIX ASH TENU;Nl;0;L;;;;6;N;;;;;\n1244F;CUNEIFORM NUMERIC SIGN ONE BAN2;Nl;0;L;;;;1;N;;;;;\n12450;CUNEIFORM NUMERIC SIGN TWO BAN2;Nl;0;L;;;;2;N;;;;;\n12451;CUNEIFORM NUMERIC SIGN THREE BAN2;Nl;0;L;;;;3;N;;;;;\n12452;CUNEIFORM NUMERIC SIGN FOUR BAN2;Nl;0;L;;;;4;N;;;;;\n12453;CUNEIFORM NUMERIC SIGN FOUR BAN2 VARIANT FORM;Nl;0;L;;;;4;N;;;;;\n12454;CUNEIFORM NUMERIC SIGN FIVE BAN2;Nl;0;L;;;;5;N;;;;;\n12455;CUNEIFORM NUMERIC SIGN FIVE BAN2 VARIANT FORM;Nl;0;L;;;;5;N;;;;;\n12456;CUNEIFORM NUMERIC SIGN NIGIDAMIN;Nl;0;L;;;;2;N;;;;;\n12457;CUNEIFORM NUMERIC SIGN NIGIDAESH;Nl;0;L;;;;3;N;;;;;\n12458;CUNEIFORM NUMERIC SIGN ONE ESHE3;Nl;0;L;;;;1;N;;;;;\n12459;CUNEIFORM NUMERIC SIGN TWO ESHE3;Nl;0;L;;;;2;N;;;;;\n1245A;CUNEIFORM NUMERIC SIGN ONE THIRD DISH;Nl;0;L;;;;1/3;N;;;;;\n1245B;CUNEIFORM NUMERIC SIGN TWO THIRDS DISH;Nl;0;L;;;;2/3;N;;;;;\n1245C;CUNEIFORM NUMERIC SIGN FIVE SIXTHS DISH;Nl;0;L;;;;5/6;N;;;;;\n1245D;CUNEIFORM NUMERIC SIGN ONE THIRD VARIANT FORM A;Nl;0;L;;;;1/3;N;;;;;\n1245E;CUNEIFORM NUMERIC SIGN TWO THIRDS VARIANT FORM A;Nl;0;L;;;;2/3;N;;;;;\n1245F;CUNEIFORM NUMERIC SIGN ONE EIGHTH ASH;Nl;0;L;;;;1/8;N;;;;;\n12460;CUNEIFORM NUMERIC SIGN ONE QUARTER ASH;Nl;0;L;;;;1/4;N;;;;;\n12461;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE SIXTH;Nl;0;L;;;;1/6;N;;;;;\n12462;CUNEIFORM NUMERIC SIGN OLD ASSYRIAN ONE QUARTER;Nl;0;L;;;;1/4;N;;;;;\n12463;CUNEIFORM NUMERIC SIGN ONE QUARTER GUR;Nl;0;L;;;;1/4;N;;;;;\n12464;CUNEIFORM NUMERIC SIGN ONE HALF GUR;Nl;0;L;;;;1/2;N;;;;;\n12465;CUNEIFORM NUMERIC SIGN ELAMITE ONE THIRD;Nl;0;L;;;;1/3;N;;;;;\n12466;CUNEIFORM NUMERIC SIGN ELAMITE TWO THIRDS;Nl;0;L;;;;2/3;N;;;;;\n12467;CUNEIFORM NUMERIC SIGN ELAMITE FORTY;Nl;0;L;;;;40;N;;;;;\n12468;CUNEIFORM NUMERIC SIGN ELAMITE FIFTY;Nl;0;L;;;;50;N;;;;;\n12469;CUNEIFORM NUMERIC SIGN FOUR U VARIANT FORM;Nl;0;L;;;;4;N;;;;;\n1246A;CUNEIFORM NUMERIC SIGN FIVE U VARIANT FORM;Nl;0;L;;;;5;N;;;;;\n1246B;CUNEIFORM NUMERIC SIGN SIX U VARIANT FORM;Nl;0;L;;;;6;N;;;;;\n1246C;CUNEIFORM NUMERIC SIGN SEVEN U VARIANT FORM;Nl;0;L;;;;7;N;;;;;\n1246D;CUNEIFORM NUMERIC SIGN EIGHT U VARIANT FORM;Nl;0;L;;;;8;N;;;;;\n1246E;CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM;Nl;0;L;;;;9;N;;;;;\n12470;CUNEIFORM PUNCTUATION SIGN OLD ASSYRIAN WORD DIVIDER;Po;0;L;;;;;N;;;;;\n12471;CUNEIFORM PUNCTUATION SIGN VERTICAL COLON;Po;0;L;;;;;N;;;;;\n12472;CUNEIFORM PUNCTUATION SIGN DIAGONAL COLON;Po;0;L;;;;;N;;;;;\n12473;CUNEIFORM PUNCTUATION SIGN DIAGONAL TRICOLON;Po;0;L;;;;;N;;;;;\n12474;CUNEIFORM PUNCTUATION SIGN DIAGONAL QUADCOLON;Po;0;L;;;;;N;;;;;\n12480;CUNEIFORM SIGN AB TIMES NUN TENU;Lo;0;L;;;;;N;;;;;\n12481;CUNEIFORM SIGN AB TIMES SHU2;Lo;0;L;;;;;N;;;;;\n12482;CUNEIFORM SIGN AD TIMES ESH2;Lo;0;L;;;;;N;;;;;\n12483;CUNEIFORM SIGN BAD TIMES DISH TENU;Lo;0;L;;;;;N;;;;;\n12484;CUNEIFORM SIGN BAHAR2 TIMES AB2;Lo;0;L;;;;;N;;;;;\n12485;CUNEIFORM SIGN BAHAR2 TIMES NI;Lo;0;L;;;;;N;;;;;\n12486;CUNEIFORM SIGN BAHAR2 TIMES ZA;Lo;0;L;;;;;N;;;;;\n12487;CUNEIFORM SIGN BU OVER BU TIMES NA2;Lo;0;L;;;;;N;;;;;\n12488;CUNEIFORM SIGN DA TIMES TAK4;Lo;0;L;;;;;N;;;;;\n12489;CUNEIFORM SIGN DAG TIMES KUR;Lo;0;L;;;;;N;;;;;\n1248A;CUNEIFORM SIGN DIM TIMES IGI;Lo;0;L;;;;;N;;;;;\n1248B;CUNEIFORM SIGN DIM TIMES U U U;Lo;0;L;;;;;N;;;;;\n1248C;CUNEIFORM SIGN DIM2 TIMES UD;Lo;0;L;;;;;N;;;;;\n1248D;CUNEIFORM SIGN DUG TIMES ANSHE;Lo;0;L;;;;;N;;;;;\n1248E;CUNEIFORM SIGN DUG TIMES ASH;Lo;0;L;;;;;N;;;;;\n1248F;CUNEIFORM SIGN DUG TIMES ASH AT LEFT;Lo;0;L;;;;;N;;;;;\n12490;CUNEIFORM SIGN DUG TIMES DIN;Lo;0;L;;;;;N;;;;;\n12491;CUNEIFORM SIGN DUG TIMES DUN;Lo;0;L;;;;;N;;;;;\n12492;CUNEIFORM SIGN DUG TIMES ERIN2;Lo;0;L;;;;;N;;;;;\n12493;CUNEIFORM SIGN DUG TIMES GA;Lo;0;L;;;;;N;;;;;\n12494;CUNEIFORM SIGN DUG TIMES GI;Lo;0;L;;;;;N;;;;;\n12495;CUNEIFORM SIGN DUG TIMES GIR2 GUNU;Lo;0;L;;;;;N;;;;;\n12496;CUNEIFORM SIGN DUG TIMES GISH;Lo;0;L;;;;;N;;;;;\n12497;CUNEIFORM SIGN DUG TIMES HA;Lo;0;L;;;;;N;;;;;\n12498;CUNEIFORM SIGN DUG TIMES HI;Lo;0;L;;;;;N;;;;;\n12499;CUNEIFORM SIGN DUG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;\n1249A;CUNEIFORM SIGN DUG TIMES KASKAL;Lo;0;L;;;;;N;;;;;\n1249B;CUNEIFORM SIGN DUG TIMES KUR;Lo;0;L;;;;;N;;;;;\n1249C;CUNEIFORM SIGN DUG TIMES KUSHU2;Lo;0;L;;;;;N;;;;;\n1249D;CUNEIFORM SIGN DUG TIMES KUSHU2 PLUS KASKAL;Lo;0;L;;;;;N;;;;;\n1249E;CUNEIFORM SIGN DUG TIMES LAK-020;Lo;0;L;;;;;N;;;;;\n1249F;CUNEIFORM SIGN DUG TIMES LAM;Lo;0;L;;;;;N;;;;;\n124A0;CUNEIFORM SIGN DUG TIMES LAM TIMES KUR;Lo;0;L;;;;;N;;;;;\n124A1;CUNEIFORM SIGN DUG TIMES LUH PLUS GISH;Lo;0;L;;;;;N;;;;;\n124A2;CUNEIFORM SIGN DUG TIMES MASH;Lo;0;L;;;;;N;;;;;\n124A3;CUNEIFORM SIGN DUG TIMES MES;Lo;0;L;;;;;N;;;;;\n124A4;CUNEIFORM SIGN DUG TIMES MI;Lo;0;L;;;;;N;;;;;\n124A5;CUNEIFORM SIGN DUG TIMES NI;Lo;0;L;;;;;N;;;;;\n124A6;CUNEIFORM SIGN DUG TIMES PI;Lo;0;L;;;;;N;;;;;\n124A7;CUNEIFORM SIGN DUG TIMES SHE;Lo;0;L;;;;;N;;;;;\n124A8;CUNEIFORM SIGN DUG TIMES SI GUNU;Lo;0;L;;;;;N;;;;;\n124A9;CUNEIFORM SIGN E2 TIMES KUR;Lo;0;L;;;;;N;;;;;\n124AA;CUNEIFORM SIGN E2 TIMES PAP;Lo;0;L;;;;;N;;;;;\n124AB;CUNEIFORM SIGN ERIN2 X;Lo;0;L;;;;;N;;;;;\n124AC;CUNEIFORM SIGN ESH2 CROSSING ESH2;Lo;0;L;;;;;N;;;;;\n124AD;CUNEIFORM SIGN EZEN SHESHIG TIMES ASH;Lo;0;L;;;;;N;;;;;\n124AE;CUNEIFORM SIGN EZEN SHESHIG TIMES HI;Lo;0;L;;;;;N;;;;;\n124AF;CUNEIFORM SIGN EZEN SHESHIG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;\n124B0;CUNEIFORM SIGN EZEN SHESHIG TIMES LA;Lo;0;L;;;;;N;;;;;\n124B1;CUNEIFORM SIGN EZEN SHESHIG TIMES LAL;Lo;0;L;;;;;N;;;;;\n124B2;CUNEIFORM SIGN EZEN SHESHIG TIMES ME;Lo;0;L;;;;;N;;;;;\n124B3;CUNEIFORM SIGN EZEN SHESHIG TIMES MES;Lo;0;L;;;;;N;;;;;\n124B4;CUNEIFORM SIGN EZEN SHESHIG TIMES SU;Lo;0;L;;;;;N;;;;;\n124B5;CUNEIFORM SIGN EZEN TIMES SU;Lo;0;L;;;;;N;;;;;\n124B6;CUNEIFORM SIGN GA2 TIMES BAHAR2;Lo;0;L;;;;;N;;;;;\n124B7;CUNEIFORM SIGN GA2 TIMES DIM GUNU;Lo;0;L;;;;;N;;;;;\n124B8;CUNEIFORM SIGN GA2 TIMES DUG TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;\n124B9;CUNEIFORM SIGN GA2 TIMES DUG TIMES KASKAL;Lo;0;L;;;;;N;;;;;\n124BA;CUNEIFORM SIGN GA2 TIMES EREN;Lo;0;L;;;;;N;;;;;\n124BB;CUNEIFORM SIGN GA2 TIMES GA;Lo;0;L;;;;;N;;;;;\n124BC;CUNEIFORM SIGN GA2 TIMES GAR PLUS DI;Lo;0;L;;;;;N;;;;;\n124BD;CUNEIFORM SIGN GA2 TIMES GAR PLUS NE;Lo;0;L;;;;;N;;;;;\n124BE;CUNEIFORM SIGN GA2 TIMES HA PLUS A;Lo;0;L;;;;;N;;;;;\n124BF;CUNEIFORM SIGN GA2 TIMES KUSHU2 PLUS KASKAL;Lo;0;L;;;;;N;;;;;\n124C0;CUNEIFORM SIGN GA2 TIMES LAM;Lo;0;L;;;;;N;;;;;\n124C1;CUNEIFORM SIGN GA2 TIMES LAM TIMES KUR;Lo;0;L;;;;;N;;;;;\n124C2;CUNEIFORM SIGN GA2 TIMES LUH;Lo;0;L;;;;;N;;;;;\n124C3;CUNEIFORM SIGN GA2 TIMES MUSH;Lo;0;L;;;;;N;;;;;\n124C4;CUNEIFORM SIGN GA2 TIMES NE;Lo;0;L;;;;;N;;;;;\n124C5;CUNEIFORM SIGN GA2 TIMES NE PLUS E2;Lo;0;L;;;;;N;;;;;\n124C6;CUNEIFORM SIGN GA2 TIMES NE PLUS GI;Lo;0;L;;;;;N;;;;;\n124C7;CUNEIFORM SIGN GA2 TIMES SHIM;Lo;0;L;;;;;N;;;;;\n124C8;CUNEIFORM SIGN GA2 TIMES ZIZ2;Lo;0;L;;;;;N;;;;;\n124C9;CUNEIFORM SIGN GABA ROTATED NINETY DEGREES;Lo;0;L;;;;;N;;;;;\n124CA;CUNEIFORM SIGN GESHTIN TIMES U;Lo;0;L;;;;;N;;;;;\n124CB;CUNEIFORM SIGN GISH TIMES GISH CROSSING GISH;Lo;0;L;;;;;N;;;;;\n124CC;CUNEIFORM SIGN GU2 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;\n124CD;CUNEIFORM SIGN GUD PLUS GISH TIMES TAK4;Lo;0;L;;;;;N;;;;;\n124CE;CUNEIFORM SIGN HA TENU GUNU;Lo;0;L;;;;;N;;;;;\n124CF;CUNEIFORM SIGN HI TIMES ASH OVER HI TIMES ASH;Lo;0;L;;;;;N;;;;;\n124D0;CUNEIFORM SIGN KA TIMES BU;Lo;0;L;;;;;N;;;;;\n124D1;CUNEIFORM SIGN KA TIMES KA;Lo;0;L;;;;;N;;;;;\n124D2;CUNEIFORM SIGN KA TIMES U U U;Lo;0;L;;;;;N;;;;;\n124D3;CUNEIFORM SIGN KA TIMES UR;Lo;0;L;;;;;N;;;;;\n124D4;CUNEIFORM SIGN LAGAB TIMES ZU OVER ZU;Lo;0;L;;;;;N;;;;;\n124D5;CUNEIFORM SIGN LAK-003;Lo;0;L;;;;;N;;;;;\n124D6;CUNEIFORM SIGN LAK-021;Lo;0;L;;;;;N;;;;;\n124D7;CUNEIFORM SIGN LAK-025;Lo;0;L;;;;;N;;;;;\n124D8;CUNEIFORM SIGN LAK-030;Lo;0;L;;;;;N;;;;;\n124D9;CUNEIFORM SIGN LAK-050;Lo;0;L;;;;;N;;;;;\n124DA;CUNEIFORM SIGN LAK-051;Lo;0;L;;;;;N;;;;;\n124DB;CUNEIFORM SIGN LAK-062;Lo;0;L;;;;;N;;;;;\n124DC;CUNEIFORM SIGN LAK-079 OVER LAK-079 GUNU;Lo;0;L;;;;;N;;;;;\n124DD;CUNEIFORM SIGN LAK-080;Lo;0;L;;;;;N;;;;;\n124DE;CUNEIFORM SIGN LAK-081 OVER LAK-081;Lo;0;L;;;;;N;;;;;\n124DF;CUNEIFORM SIGN LAK-092;Lo;0;L;;;;;N;;;;;\n124E0;CUNEIFORM SIGN LAK-130;Lo;0;L;;;;;N;;;;;\n124E1;CUNEIFORM SIGN LAK-142;Lo;0;L;;;;;N;;;;;\n124E2;CUNEIFORM SIGN LAK-210;Lo;0;L;;;;;N;;;;;\n124E3;CUNEIFORM SIGN LAK-219;Lo;0;L;;;;;N;;;;;\n124E4;CUNEIFORM SIGN LAK-220;Lo;0;L;;;;;N;;;;;\n124E5;CUNEIFORM SIGN LAK-225;Lo;0;L;;;;;N;;;;;\n124E6;CUNEIFORM SIGN LAK-228;Lo;0;L;;;;;N;;;;;\n124E7;CUNEIFORM SIGN LAK-238;Lo;0;L;;;;;N;;;;;\n124E8;CUNEIFORM SIGN LAK-265;Lo;0;L;;;;;N;;;;;\n124E9;CUNEIFORM SIGN LAK-266;Lo;0;L;;;;;N;;;;;\n124EA;CUNEIFORM SIGN LAK-343;Lo;0;L;;;;;N;;;;;\n124EB;CUNEIFORM SIGN LAK-347;Lo;0;L;;;;;N;;;;;\n124EC;CUNEIFORM SIGN LAK-348;Lo;0;L;;;;;N;;;;;\n124ED;CUNEIFORM SIGN LAK-383;Lo;0;L;;;;;N;;;;;\n124EE;CUNEIFORM SIGN LAK-384;Lo;0;L;;;;;N;;;;;\n124EF;CUNEIFORM SIGN LAK-390;Lo;0;L;;;;;N;;;;;\n124F0;CUNEIFORM SIGN LAK-441;Lo;0;L;;;;;N;;;;;\n124F1;CUNEIFORM SIGN LAK-449;Lo;0;L;;;;;N;;;;;\n124F2;CUNEIFORM SIGN LAK-449 TIMES GU;Lo;0;L;;;;;N;;;;;\n124F3;CUNEIFORM SIGN LAK-449 TIMES IGI;Lo;0;L;;;;;N;;;;;\n124F4;CUNEIFORM SIGN LAK-449 TIMES PAP PLUS LU3;Lo;0;L;;;;;N;;;;;\n124F5;CUNEIFORM SIGN LAK-449 TIMES PAP PLUS PAP PLUS LU3;Lo;0;L;;;;;N;;;;;\n124F6;CUNEIFORM SIGN LAK-449 TIMES U2 PLUS BA;Lo;0;L;;;;;N;;;;;\n124F7;CUNEIFORM SIGN LAK-450;Lo;0;L;;;;;N;;;;;\n124F8;CUNEIFORM SIGN LAK-457;Lo;0;L;;;;;N;;;;;\n124F9;CUNEIFORM SIGN LAK-470;Lo;0;L;;;;;N;;;;;\n124FA;CUNEIFORM SIGN LAK-483;Lo;0;L;;;;;N;;;;;\n124FB;CUNEIFORM SIGN LAK-490;Lo;0;L;;;;;N;;;;;\n124FC;CUNEIFORM SIGN LAK-492;Lo;0;L;;;;;N;;;;;\n124FD;CUNEIFORM SIGN LAK-493;Lo;0;L;;;;;N;;;;;\n124FE;CUNEIFORM SIGN LAK-495;Lo;0;L;;;;;N;;;;;\n124FF;CUNEIFORM SIGN LAK-550;Lo;0;L;;;;;N;;;;;\n12500;CUNEIFORM SIGN LAK-608;Lo;0;L;;;;;N;;;;;\n12501;CUNEIFORM SIGN LAK-617;Lo;0;L;;;;;N;;;;;\n12502;CUNEIFORM SIGN LAK-617 TIMES ASH;Lo;0;L;;;;;N;;;;;\n12503;CUNEIFORM SIGN LAK-617 TIMES BAD;Lo;0;L;;;;;N;;;;;\n12504;CUNEIFORM SIGN LAK-617 TIMES DUN3 GUNU GUNU;Lo;0;L;;;;;N;;;;;\n12505;CUNEIFORM SIGN LAK-617 TIMES KU3;Lo;0;L;;;;;N;;;;;\n12506;CUNEIFORM SIGN LAK-617 TIMES LA;Lo;0;L;;;;;N;;;;;\n12507;CUNEIFORM SIGN LAK-617 TIMES TAR;Lo;0;L;;;;;N;;;;;\n12508;CUNEIFORM SIGN LAK-617 TIMES TE;Lo;0;L;;;;;N;;;;;\n12509;CUNEIFORM SIGN LAK-617 TIMES U2;Lo;0;L;;;;;N;;;;;\n1250A;CUNEIFORM SIGN LAK-617 TIMES UD;Lo;0;L;;;;;N;;;;;\n1250B;CUNEIFORM SIGN LAK-617 TIMES URUDA;Lo;0;L;;;;;N;;;;;\n1250C;CUNEIFORM SIGN LAK-636;Lo;0;L;;;;;N;;;;;\n1250D;CUNEIFORM SIGN LAK-648;Lo;0;L;;;;;N;;;;;\n1250E;CUNEIFORM SIGN LAK-648 TIMES DUB;Lo;0;L;;;;;N;;;;;\n1250F;CUNEIFORM SIGN LAK-648 TIMES GA;Lo;0;L;;;;;N;;;;;\n12510;CUNEIFORM SIGN LAK-648 TIMES IGI;Lo;0;L;;;;;N;;;;;\n12511;CUNEIFORM SIGN LAK-648 TIMES IGI GUNU;Lo;0;L;;;;;N;;;;;\n12512;CUNEIFORM SIGN LAK-648 TIMES NI;Lo;0;L;;;;;N;;;;;\n12513;CUNEIFORM SIGN LAK-648 TIMES PAP PLUS PAP PLUS LU3;Lo;0;L;;;;;N;;;;;\n12514;CUNEIFORM SIGN LAK-648 TIMES SHESH PLUS KI;Lo;0;L;;;;;N;;;;;\n12515;CUNEIFORM SIGN LAK-648 TIMES UD;Lo;0;L;;;;;N;;;;;\n12516;CUNEIFORM SIGN LAK-648 TIMES URUDA;Lo;0;L;;;;;N;;;;;\n12517;CUNEIFORM SIGN LAK-724;Lo;0;L;;;;;N;;;;;\n12518;CUNEIFORM SIGN LAK-749;Lo;0;L;;;;;N;;;;;\n12519;CUNEIFORM SIGN LU2 GUNU TIMES ASH;Lo;0;L;;;;;N;;;;;\n1251A;CUNEIFORM SIGN LU2 TIMES DISH;Lo;0;L;;;;;N;;;;;\n1251B;CUNEIFORM SIGN LU2 TIMES HAL;Lo;0;L;;;;;N;;;;;\n1251C;CUNEIFORM SIGN LU2 TIMES PAP;Lo;0;L;;;;;N;;;;;\n1251D;CUNEIFORM SIGN LU2 TIMES PAP PLUS PAP PLUS LU3;Lo;0;L;;;;;N;;;;;\n1251E;CUNEIFORM SIGN LU2 TIMES TAK4;Lo;0;L;;;;;N;;;;;\n1251F;CUNEIFORM SIGN MI PLUS ZA7;Lo;0;L;;;;;N;;;;;\n12520;CUNEIFORM SIGN MUSH OVER MUSH TIMES GA;Lo;0;L;;;;;N;;;;;\n12521;CUNEIFORM SIGN MUSH OVER MUSH TIMES KAK;Lo;0;L;;;;;N;;;;;\n12522;CUNEIFORM SIGN NINDA2 TIMES DIM GUNU;Lo;0;L;;;;;N;;;;;\n12523;CUNEIFORM SIGN NINDA2 TIMES GISH;Lo;0;L;;;;;N;;;;;\n12524;CUNEIFORM SIGN NINDA2 TIMES GUL;Lo;0;L;;;;;N;;;;;\n12525;CUNEIFORM SIGN NINDA2 TIMES HI;Lo;0;L;;;;;N;;;;;\n12526;CUNEIFORM SIGN NINDA2 TIMES KESH2;Lo;0;L;;;;;N;;;;;\n12527;CUNEIFORM SIGN NINDA2 TIMES LAK-050;Lo;0;L;;;;;N;;;;;\n12528;CUNEIFORM SIGN NINDA2 TIMES MASH;Lo;0;L;;;;;N;;;;;\n12529;CUNEIFORM SIGN NINDA2 TIMES PAP PLUS PAP;Lo;0;L;;;;;N;;;;;\n1252A;CUNEIFORM SIGN NINDA2 TIMES U;Lo;0;L;;;;;N;;;;;\n1252B;CUNEIFORM SIGN NINDA2 TIMES U PLUS U;Lo;0;L;;;;;N;;;;;\n1252C;CUNEIFORM SIGN NINDA2 TIMES URUDA;Lo;0;L;;;;;N;;;;;\n1252D;CUNEIFORM SIGN SAG GUNU TIMES HA;Lo;0;L;;;;;N;;;;;\n1252E;CUNEIFORM SIGN SAG TIMES EN;Lo;0;L;;;;;N;;;;;\n1252F;CUNEIFORM SIGN SAG TIMES SHE AT LEFT;Lo;0;L;;;;;N;;;;;\n12530;CUNEIFORM SIGN SAG TIMES TAK4;Lo;0;L;;;;;N;;;;;\n12531;CUNEIFORM SIGN SHA6 TENU;Lo;0;L;;;;;N;;;;;\n12532;CUNEIFORM SIGN SHE OVER SHE;Lo;0;L;;;;;N;;;;;\n12533;CUNEIFORM SIGN SHE PLUS HUB2;Lo;0;L;;;;;N;;;;;\n12534;CUNEIFORM SIGN SHE PLUS NAM2;Lo;0;L;;;;;N;;;;;\n12535;CUNEIFORM SIGN SHE PLUS SAR;Lo;0;L;;;;;N;;;;;\n12536;CUNEIFORM SIGN SHU2 PLUS DUG TIMES NI;Lo;0;L;;;;;N;;;;;\n12537;CUNEIFORM SIGN SHU2 PLUS E2 TIMES AN;Lo;0;L;;;;;N;;;;;\n12538;CUNEIFORM SIGN SI TIMES TAK4;Lo;0;L;;;;;N;;;;;\n12539;CUNEIFORM SIGN TAK4 PLUS SAG;Lo;0;L;;;;;N;;;;;\n1253A;CUNEIFORM SIGN TUM TIMES GAN2 TENU;Lo;0;L;;;;;N;;;;;\n1253B;CUNEIFORM SIGN TUM TIMES THREE DISH;Lo;0;L;;;;;N;;;;;\n1253C;CUNEIFORM SIGN UR2 INVERTED;Lo;0;L;;;;;N;;;;;\n1253D;CUNEIFORM SIGN UR2 TIMES UD;Lo;0;L;;;;;N;;;;;\n1253E;CUNEIFORM SIGN URU TIMES DARA3;Lo;0;L;;;;;N;;;;;\n1253F;CUNEIFORM SIGN URU TIMES LAK-668;Lo;0;L;;;;;N;;;;;\n12540;CUNEIFORM SIGN URU TIMES LU3;Lo;0;L;;;;;N;;;;;\n12541;CUNEIFORM SIGN ZA7;Lo;0;L;;;;;N;;;;;\n12542;CUNEIFORM SIGN ZU OVER ZU PLUS SAR;Lo;0;L;;;;;N;;;;;\n12543;CUNEIFORM SIGN ZU5 TIMES THREE DISH TENU;Lo;0;L;;;;;N;;;;;\n13000;EGYPTIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;;\n13001;EGYPTIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;;\n13002;EGYPTIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;;\n13003;EGYPTIAN HIEROGLYPH A004;Lo;0;L;;;;;N;;;;;\n13004;EGYPTIAN HIEROGLYPH A005;Lo;0;L;;;;;N;;;;;\n13005;EGYPTIAN HIEROGLYPH A005A;Lo;0;L;;;;;N;;;;;\n13006;EGYPTIAN HIEROGLYPH A006;Lo;0;L;;;;;N;;;;;\n13007;EGYPTIAN HIEROGLYPH A006A;Lo;0;L;;;;;N;;;;;\n13008;EGYPTIAN HIEROGLYPH A006B;Lo;0;L;;;;;N;;;;;\n13009;EGYPTIAN HIEROGLYPH A007;Lo;0;L;;;;;N;;;;;\n1300A;EGYPTIAN HIEROGLYPH A008;Lo;0;L;;;;;N;;;;;\n1300B;EGYPTIAN HIEROGLYPH A009;Lo;0;L;;;;;N;;;;;\n1300C;EGYPTIAN HIEROGLYPH A010;Lo;0;L;;;;;N;;;;;\n1300D;EGYPTIAN HIEROGLYPH A011;Lo;0;L;;;;;N;;;;;\n1300E;EGYPTIAN HIEROGLYPH A012;Lo;0;L;;;;;N;;;;;\n1300F;EGYPTIAN HIEROGLYPH A013;Lo;0;L;;;;;N;;;;;\n13010;EGYPTIAN HIEROGLYPH A014;Lo;0;L;;;;;N;;;;;\n13011;EGYPTIAN HIEROGLYPH A014A;Lo;0;L;;;;;N;;;;;\n13012;EGYPTIAN HIEROGLYPH A015;Lo;0;L;;;;;N;;;;;\n13013;EGYPTIAN HIEROGLYPH A016;Lo;0;L;;;;;N;;;;;\n13014;EGYPTIAN HIEROGLYPH A017;Lo;0;L;;;;;N;;;;;\n13015;EGYPTIAN HIEROGLYPH A017A;Lo;0;L;;;;;N;;;;;\n13016;EGYPTIAN HIEROGLYPH A018;Lo;0;L;;;;;N;;;;;\n13017;EGYPTIAN HIEROGLYPH A019;Lo;0;L;;;;;N;;;;;\n13018;EGYPTIAN HIEROGLYPH A020;Lo;0;L;;;;;N;;;;;\n13019;EGYPTIAN HIEROGLYPH A021;Lo;0;L;;;;;N;;;;;\n1301A;EGYPTIAN HIEROGLYPH A022;Lo;0;L;;;;;N;;;;;\n1301B;EGYPTIAN HIEROGLYPH A023;Lo;0;L;;;;;N;;;;;\n1301C;EGYPTIAN HIEROGLYPH A024;Lo;0;L;;;;;N;;;;;\n1301D;EGYPTIAN HIEROGLYPH A025;Lo;0;L;;;;;N;;;;;\n1301E;EGYPTIAN HIEROGLYPH A026;Lo;0;L;;;;;N;;;;;\n1301F;EGYPTIAN HIEROGLYPH A027;Lo;0;L;;;;;N;;;;;\n13020;EGYPTIAN HIEROGLYPH A028;Lo;0;L;;;;;N;;;;;\n13021;EGYPTIAN HIEROGLYPH A029;Lo;0;L;;;;;N;;;;;\n13022;EGYPTIAN HIEROGLYPH A030;Lo;0;L;;;;;N;;;;;\n13023;EGYPTIAN HIEROGLYPH A031;Lo;0;L;;;;;N;;;;;\n13024;EGYPTIAN HIEROGLYPH A032;Lo;0;L;;;;;N;;;;;\n13025;EGYPTIAN HIEROGLYPH A032A;Lo;0;L;;;;;N;;;;;\n13026;EGYPTIAN HIEROGLYPH A033;Lo;0;L;;;;;N;;;;;\n13027;EGYPTIAN HIEROGLYPH A034;Lo;0;L;;;;;N;;;;;\n13028;EGYPTIAN HIEROGLYPH A035;Lo;0;L;;;;;N;;;;;\n13029;EGYPTIAN HIEROGLYPH A036;Lo;0;L;;;;;N;;;;;\n1302A;EGYPTIAN HIEROGLYPH A037;Lo;0;L;;;;;N;;;;;\n1302B;EGYPTIAN HIEROGLYPH A038;Lo;0;L;;;;;N;;;;;\n1302C;EGYPTIAN HIEROGLYPH A039;Lo;0;L;;;;;N;;;;;\n1302D;EGYPTIAN HIEROGLYPH A040;Lo;0;L;;;;;N;;;;;\n1302E;EGYPTIAN HIEROGLYPH A040A;Lo;0;L;;;;;N;;;;;\n1302F;EGYPTIAN HIEROGLYPH A041;Lo;0;L;;;;;N;;;;;\n13030;EGYPTIAN HIEROGLYPH A042;Lo;0;L;;;;;N;;;;;\n13031;EGYPTIAN HIEROGLYPH A042A;Lo;0;L;;;;;N;;;;;\n13032;EGYPTIAN HIEROGLYPH A043;Lo;0;L;;;;;N;;;;;\n13033;EGYPTIAN HIEROGLYPH A043A;Lo;0;L;;;;;N;;;;;\n13034;EGYPTIAN HIEROGLYPH A044;Lo;0;L;;;;;N;;;;;\n13035;EGYPTIAN HIEROGLYPH A045;Lo;0;L;;;;;N;;;;;\n13036;EGYPTIAN HIEROGLYPH A045A;Lo;0;L;;;;;N;;;;;\n13037;EGYPTIAN HIEROGLYPH A046;Lo;0;L;;;;;N;;;;;\n13038;EGYPTIAN HIEROGLYPH A047;Lo;0;L;;;;;N;;;;;\n13039;EGYPTIAN HIEROGLYPH A048;Lo;0;L;;;;;N;;;;;\n1303A;EGYPTIAN HIEROGLYPH A049;Lo;0;L;;;;;N;;;;;\n1303B;EGYPTIAN HIEROGLYPH A050;Lo;0;L;;;;;N;;;;;\n1303C;EGYPTIAN HIEROGLYPH A051;Lo;0;L;;;;;N;;;;;\n1303D;EGYPTIAN HIEROGLYPH A052;Lo;0;L;;;;;N;;;;;\n1303E;EGYPTIAN HIEROGLYPH A053;Lo;0;L;;;;;N;;;;;\n1303F;EGYPTIAN HIEROGLYPH A054;Lo;0;L;;;;;N;;;;;\n13040;EGYPTIAN HIEROGLYPH A055;Lo;0;L;;;;;N;;;;;\n13041;EGYPTIAN HIEROGLYPH A056;Lo;0;L;;;;;N;;;;;\n13042;EGYPTIAN HIEROGLYPH A057;Lo;0;L;;;;;N;;;;;\n13043;EGYPTIAN HIEROGLYPH A058;Lo;0;L;;;;;N;;;;;\n13044;EGYPTIAN HIEROGLYPH A059;Lo;0;L;;;;;N;;;;;\n13045;EGYPTIAN HIEROGLYPH A060;Lo;0;L;;;;;N;;;;;\n13046;EGYPTIAN HIEROGLYPH A061;Lo;0;L;;;;;N;;;;;\n13047;EGYPTIAN HIEROGLYPH A062;Lo;0;L;;;;;N;;;;;\n13048;EGYPTIAN HIEROGLYPH A063;Lo;0;L;;;;;N;;;;;\n13049;EGYPTIAN HIEROGLYPH A064;Lo;0;L;;;;;N;;;;;\n1304A;EGYPTIAN HIEROGLYPH A065;Lo;0;L;;;;;N;;;;;\n1304B;EGYPTIAN HIEROGLYPH A066;Lo;0;L;;;;;N;;;;;\n1304C;EGYPTIAN HIEROGLYPH A067;Lo;0;L;;;;;N;;;;;\n1304D;EGYPTIAN HIEROGLYPH A068;Lo;0;L;;;;;N;;;;;\n1304E;EGYPTIAN HIEROGLYPH A069;Lo;0;L;;;;;N;;;;;\n1304F;EGYPTIAN HIEROGLYPH A070;Lo;0;L;;;;;N;;;;;\n13050;EGYPTIAN HIEROGLYPH B001;Lo;0;L;;;;;N;;;;;\n13051;EGYPTIAN HIEROGLYPH B002;Lo;0;L;;;;;N;;;;;\n13052;EGYPTIAN HIEROGLYPH B003;Lo;0;L;;;;;N;;;;;\n13053;EGYPTIAN HIEROGLYPH B004;Lo;0;L;;;;;N;;;;;\n13054;EGYPTIAN HIEROGLYPH B005;Lo;0;L;;;;;N;;;;;\n13055;EGYPTIAN HIEROGLYPH B005A;Lo;0;L;;;;;N;;;;;\n13056;EGYPTIAN HIEROGLYPH B006;Lo;0;L;;;;;N;;;;;\n13057;EGYPTIAN HIEROGLYPH B007;Lo;0;L;;;;;N;;;;;\n13058;EGYPTIAN HIEROGLYPH B008;Lo;0;L;;;;;N;;;;;\n13059;EGYPTIAN HIEROGLYPH B009;Lo;0;L;;;;;N;;;;;\n1305A;EGYPTIAN HIEROGLYPH C001;Lo;0;L;;;;;N;;;;;\n1305B;EGYPTIAN HIEROGLYPH C002;Lo;0;L;;;;;N;;;;;\n1305C;EGYPTIAN HIEROGLYPH C002A;Lo;0;L;;;;;N;;;;;\n1305D;EGYPTIAN HIEROGLYPH C002B;Lo;0;L;;;;;N;;;;;\n1305E;EGYPTIAN HIEROGLYPH C002C;Lo;0;L;;;;;N;;;;;\n1305F;EGYPTIAN HIEROGLYPH C003;Lo;0;L;;;;;N;;;;;\n13060;EGYPTIAN HIEROGLYPH C004;Lo;0;L;;;;;N;;;;;\n13061;EGYPTIAN HIEROGLYPH C005;Lo;0;L;;;;;N;;;;;\n13062;EGYPTIAN HIEROGLYPH C006;Lo;0;L;;;;;N;;;;;\n13063;EGYPTIAN HIEROGLYPH C007;Lo;0;L;;;;;N;;;;;\n13064;EGYPTIAN HIEROGLYPH C008;Lo;0;L;;;;;N;;;;;\n13065;EGYPTIAN HIEROGLYPH C009;Lo;0;L;;;;;N;;;;;\n13066;EGYPTIAN HIEROGLYPH C010;Lo;0;L;;;;;N;;;;;\n13067;EGYPTIAN HIEROGLYPH C010A;Lo;0;L;;;;;N;;;;;\n13068;EGYPTIAN HIEROGLYPH C011;Lo;0;L;;;;;N;;;;;\n13069;EGYPTIAN HIEROGLYPH C012;Lo;0;L;;;;;N;;;;;\n1306A;EGYPTIAN HIEROGLYPH C013;Lo;0;L;;;;;N;;;;;\n1306B;EGYPTIAN HIEROGLYPH C014;Lo;0;L;;;;;N;;;;;\n1306C;EGYPTIAN HIEROGLYPH C015;Lo;0;L;;;;;N;;;;;\n1306D;EGYPTIAN HIEROGLYPH C016;Lo;0;L;;;;;N;;;;;\n1306E;EGYPTIAN HIEROGLYPH C017;Lo;0;L;;;;;N;;;;;\n1306F;EGYPTIAN HIEROGLYPH C018;Lo;0;L;;;;;N;;;;;\n13070;EGYPTIAN HIEROGLYPH C019;Lo;0;L;;;;;N;;;;;\n13071;EGYPTIAN HIEROGLYPH C020;Lo;0;L;;;;;N;;;;;\n13072;EGYPTIAN HIEROGLYPH C021;Lo;0;L;;;;;N;;;;;\n13073;EGYPTIAN HIEROGLYPH C022;Lo;0;L;;;;;N;;;;;\n13074;EGYPTIAN HIEROGLYPH C023;Lo;0;L;;;;;N;;;;;\n13075;EGYPTIAN HIEROGLYPH C024;Lo;0;L;;;;;N;;;;;\n13076;EGYPTIAN HIEROGLYPH D001;Lo;0;L;;;;;N;;;;;\n13077;EGYPTIAN HIEROGLYPH D002;Lo;0;L;;;;;N;;;;;\n13078;EGYPTIAN HIEROGLYPH D003;Lo;0;L;;;;;N;;;;;\n13079;EGYPTIAN HIEROGLYPH D004;Lo;0;L;;;;;N;;;;;\n1307A;EGYPTIAN HIEROGLYPH D005;Lo;0;L;;;;;N;;;;;\n1307B;EGYPTIAN HIEROGLYPH D006;Lo;0;L;;;;;N;;;;;\n1307C;EGYPTIAN HIEROGLYPH D007;Lo;0;L;;;;;N;;;;;\n1307D;EGYPTIAN HIEROGLYPH D008;Lo;0;L;;;;;N;;;;;\n1307E;EGYPTIAN HIEROGLYPH D008A;Lo;0;L;;;;;N;;;;;\n1307F;EGYPTIAN HIEROGLYPH D009;Lo;0;L;;;;;N;;;;;\n13080;EGYPTIAN HIEROGLYPH D010;Lo;0;L;;;;;N;;;;;\n13081;EGYPTIAN HIEROGLYPH D011;Lo;0;L;;;;;N;;;;;\n13082;EGYPTIAN HIEROGLYPH D012;Lo;0;L;;;;;N;;;;;\n13083;EGYPTIAN HIEROGLYPH D013;Lo;0;L;;;;;N;;;;;\n13084;EGYPTIAN HIEROGLYPH D014;Lo;0;L;;;;;N;;;;;\n13085;EGYPTIAN HIEROGLYPH D015;Lo;0;L;;;;;N;;;;;\n13086;EGYPTIAN HIEROGLYPH D016;Lo;0;L;;;;;N;;;;;\n13087;EGYPTIAN HIEROGLYPH D017;Lo;0;L;;;;;N;;;;;\n13088;EGYPTIAN HIEROGLYPH D018;Lo;0;L;;;;;N;;;;;\n13089;EGYPTIAN HIEROGLYPH D019;Lo;0;L;;;;;N;;;;;\n1308A;EGYPTIAN HIEROGLYPH D020;Lo;0;L;;;;;N;;;;;\n1308B;EGYPTIAN HIEROGLYPH D021;Lo;0;L;;;;;N;;;;;\n1308C;EGYPTIAN HIEROGLYPH D022;Lo;0;L;;;;;N;;;;;\n1308D;EGYPTIAN HIEROGLYPH D023;Lo;0;L;;;;;N;;;;;\n1308E;EGYPTIAN HIEROGLYPH D024;Lo;0;L;;;;;N;;;;;\n1308F;EGYPTIAN HIEROGLYPH D025;Lo;0;L;;;;;N;;;;;\n13090;EGYPTIAN HIEROGLYPH D026;Lo;0;L;;;;;N;;;;;\n13091;EGYPTIAN HIEROGLYPH D027;Lo;0;L;;;;;N;;;;;\n13092;EGYPTIAN HIEROGLYPH D027A;Lo;0;L;;;;;N;;;;;\n13093;EGYPTIAN HIEROGLYPH D028;Lo;0;L;;;;;N;;;;;\n13094;EGYPTIAN HIEROGLYPH D029;Lo;0;L;;;;;N;;;;;\n13095;EGYPTIAN HIEROGLYPH D030;Lo;0;L;;;;;N;;;;;\n13096;EGYPTIAN HIEROGLYPH D031;Lo;0;L;;;;;N;;;;;\n13097;EGYPTIAN HIEROGLYPH D031A;Lo;0;L;;;;;N;;;;;\n13098;EGYPTIAN HIEROGLYPH D032;Lo;0;L;;;;;N;;;;;\n13099;EGYPTIAN HIEROGLYPH D033;Lo;0;L;;;;;N;;;;;\n1309A;EGYPTIAN HIEROGLYPH D034;Lo;0;L;;;;;N;;;;;\n1309B;EGYPTIAN HIEROGLYPH D034A;Lo;0;L;;;;;N;;;;;\n1309C;EGYPTIAN HIEROGLYPH D035;Lo;0;L;;;;;N;;;;;\n1309D;EGYPTIAN HIEROGLYPH D036;Lo;0;L;;;;;N;;;;;\n1309E;EGYPTIAN HIEROGLYPH D037;Lo;0;L;;;;;N;;;;;\n1309F;EGYPTIAN HIEROGLYPH D038;Lo;0;L;;;;;N;;;;;\n130A0;EGYPTIAN HIEROGLYPH D039;Lo;0;L;;;;;N;;;;;\n130A1;EGYPTIAN HIEROGLYPH D040;Lo;0;L;;;;;N;;;;;\n130A2;EGYPTIAN HIEROGLYPH D041;Lo;0;L;;;;;N;;;;;\n130A3;EGYPTIAN HIEROGLYPH D042;Lo;0;L;;;;;N;;;;;\n130A4;EGYPTIAN HIEROGLYPH D043;Lo;0;L;;;;;N;;;;;\n130A5;EGYPTIAN HIEROGLYPH D044;Lo;0;L;;;;;N;;;;;\n130A6;EGYPTIAN HIEROGLYPH D045;Lo;0;L;;;;;N;;;;;\n130A7;EGYPTIAN HIEROGLYPH D046;Lo;0;L;;;;;N;;;;;\n130A8;EGYPTIAN HIEROGLYPH D046A;Lo;0;L;;;;;N;;;;;\n130A9;EGYPTIAN HIEROGLYPH D047;Lo;0;L;;;;;N;;;;;\n130AA;EGYPTIAN HIEROGLYPH D048;Lo;0;L;;;;;N;;;;;\n130AB;EGYPTIAN HIEROGLYPH D048A;Lo;0;L;;;;;N;;;;;\n130AC;EGYPTIAN HIEROGLYPH D049;Lo;0;L;;;;;N;;;;;\n130AD;EGYPTIAN HIEROGLYPH D050;Lo;0;L;;;;;N;;;;;\n130AE;EGYPTIAN HIEROGLYPH D050A;Lo;0;L;;;;;N;;;;;\n130AF;EGYPTIAN HIEROGLYPH D050B;Lo;0;L;;;;;N;;;;;\n130B0;EGYPTIAN HIEROGLYPH D050C;Lo;0;L;;;;;N;;;;;\n130B1;EGYPTIAN HIEROGLYPH D050D;Lo;0;L;;;;;N;;;;;\n130B2;EGYPTIAN HIEROGLYPH D050E;Lo;0;L;;;;;N;;;;;\n130B3;EGYPTIAN HIEROGLYPH D050F;Lo;0;L;;;;;N;;;;;\n130B4;EGYPTIAN HIEROGLYPH D050G;Lo;0;L;;;;;N;;;;;\n130B5;EGYPTIAN HIEROGLYPH D050H;Lo;0;L;;;;;N;;;;;\n130B6;EGYPTIAN HIEROGLYPH D050I;Lo;0;L;;;;;N;;;;;\n130B7;EGYPTIAN HIEROGLYPH D051;Lo;0;L;;;;;N;;;;;\n130B8;EGYPTIAN HIEROGLYPH D052;Lo;0;L;;;;;N;;;;;\n130B9;EGYPTIAN HIEROGLYPH D052A;Lo;0;L;;;;;N;;;;;\n130BA;EGYPTIAN HIEROGLYPH D053;Lo;0;L;;;;;N;;;;;\n130BB;EGYPTIAN HIEROGLYPH D054;Lo;0;L;;;;;N;;;;;\n130BC;EGYPTIAN HIEROGLYPH D054A;Lo;0;L;;;;;N;;;;;\n130BD;EGYPTIAN HIEROGLYPH D055;Lo;0;L;;;;;N;;;;;\n130BE;EGYPTIAN HIEROGLYPH D056;Lo;0;L;;;;;N;;;;;\n130BF;EGYPTIAN HIEROGLYPH D057;Lo;0;L;;;;;N;;;;;\n130C0;EGYPTIAN HIEROGLYPH D058;Lo;0;L;;;;;N;;;;;\n130C1;EGYPTIAN HIEROGLYPH D059;Lo;0;L;;;;;N;;;;;\n130C2;EGYPTIAN HIEROGLYPH D060;Lo;0;L;;;;;N;;;;;\n130C3;EGYPTIAN HIEROGLYPH D061;Lo;0;L;;;;;N;;;;;\n130C4;EGYPTIAN HIEROGLYPH D062;Lo;0;L;;;;;N;;;;;\n130C5;EGYPTIAN HIEROGLYPH D063;Lo;0;L;;;;;N;;;;;\n130C6;EGYPTIAN HIEROGLYPH D064;Lo;0;L;;;;;N;;;;;\n130C7;EGYPTIAN HIEROGLYPH D065;Lo;0;L;;;;;N;;;;;\n130C8;EGYPTIAN HIEROGLYPH D066;Lo;0;L;;;;;N;;;;;\n130C9;EGYPTIAN HIEROGLYPH D067;Lo;0;L;;;;;N;;;;;\n130CA;EGYPTIAN HIEROGLYPH D067A;Lo;0;L;;;;;N;;;;;\n130CB;EGYPTIAN HIEROGLYPH D067B;Lo;0;L;;;;;N;;;;;\n130CC;EGYPTIAN HIEROGLYPH D067C;Lo;0;L;;;;;N;;;;;\n130CD;EGYPTIAN HIEROGLYPH D067D;Lo;0;L;;;;;N;;;;;\n130CE;EGYPTIAN HIEROGLYPH D067E;Lo;0;L;;;;;N;;;;;\n130CF;EGYPTIAN HIEROGLYPH D067F;Lo;0;L;;;;;N;;;;;\n130D0;EGYPTIAN HIEROGLYPH D067G;Lo;0;L;;;;;N;;;;;\n130D1;EGYPTIAN HIEROGLYPH D067H;Lo;0;L;;;;;N;;;;;\n130D2;EGYPTIAN HIEROGLYPH E001;Lo;0;L;;;;;N;;;;;\n130D3;EGYPTIAN HIEROGLYPH E002;Lo;0;L;;;;;N;;;;;\n130D4;EGYPTIAN HIEROGLYPH E003;Lo;0;L;;;;;N;;;;;\n130D5;EGYPTIAN HIEROGLYPH E004;Lo;0;L;;;;;N;;;;;\n130D6;EGYPTIAN HIEROGLYPH E005;Lo;0;L;;;;;N;;;;;\n130D7;EGYPTIAN HIEROGLYPH E006;Lo;0;L;;;;;N;;;;;\n130D8;EGYPTIAN HIEROGLYPH E007;Lo;0;L;;;;;N;;;;;\n130D9;EGYPTIAN HIEROGLYPH E008;Lo;0;L;;;;;N;;;;;\n130DA;EGYPTIAN HIEROGLYPH E008A;Lo;0;L;;;;;N;;;;;\n130DB;EGYPTIAN HIEROGLYPH E009;Lo;0;L;;;;;N;;;;;\n130DC;EGYPTIAN HIEROGLYPH E009A;Lo;0;L;;;;;N;;;;;\n130DD;EGYPTIAN HIEROGLYPH E010;Lo;0;L;;;;;N;;;;;\n130DE;EGYPTIAN HIEROGLYPH E011;Lo;0;L;;;;;N;;;;;\n130DF;EGYPTIAN HIEROGLYPH E012;Lo;0;L;;;;;N;;;;;\n130E0;EGYPTIAN HIEROGLYPH E013;Lo;0;L;;;;;N;;;;;\n130E1;EGYPTIAN HIEROGLYPH E014;Lo;0;L;;;;;N;;;;;\n130E2;EGYPTIAN HIEROGLYPH E015;Lo;0;L;;;;;N;;;;;\n130E3;EGYPTIAN HIEROGLYPH E016;Lo;0;L;;;;;N;;;;;\n130E4;EGYPTIAN HIEROGLYPH E016A;Lo;0;L;;;;;N;;;;;\n130E5;EGYPTIAN HIEROGLYPH E017;Lo;0;L;;;;;N;;;;;\n130E6;EGYPTIAN HIEROGLYPH E017A;Lo;0;L;;;;;N;;;;;\n130E7;EGYPTIAN HIEROGLYPH E018;Lo;0;L;;;;;N;;;;;\n130E8;EGYPTIAN HIEROGLYPH E019;Lo;0;L;;;;;N;;;;;\n130E9;EGYPTIAN HIEROGLYPH E020;Lo;0;L;;;;;N;;;;;\n130EA;EGYPTIAN HIEROGLYPH E020A;Lo;0;L;;;;;N;;;;;\n130EB;EGYPTIAN HIEROGLYPH E021;Lo;0;L;;;;;N;;;;;\n130EC;EGYPTIAN HIEROGLYPH E022;Lo;0;L;;;;;N;;;;;\n130ED;EGYPTIAN HIEROGLYPH E023;Lo;0;L;;;;;N;;;;;\n130EE;EGYPTIAN HIEROGLYPH E024;Lo;0;L;;;;;N;;;;;\n130EF;EGYPTIAN HIEROGLYPH E025;Lo;0;L;;;;;N;;;;;\n130F0;EGYPTIAN HIEROGLYPH E026;Lo;0;L;;;;;N;;;;;\n130F1;EGYPTIAN HIEROGLYPH E027;Lo;0;L;;;;;N;;;;;\n130F2;EGYPTIAN HIEROGLYPH E028;Lo;0;L;;;;;N;;;;;\n130F3;EGYPTIAN HIEROGLYPH E028A;Lo;0;L;;;;;N;;;;;\n130F4;EGYPTIAN HIEROGLYPH E029;Lo;0;L;;;;;N;;;;;\n130F5;EGYPTIAN HIEROGLYPH E030;Lo;0;L;;;;;N;;;;;\n130F6;EGYPTIAN HIEROGLYPH E031;Lo;0;L;;;;;N;;;;;\n130F7;EGYPTIAN HIEROGLYPH E032;Lo;0;L;;;;;N;;;;;\n130F8;EGYPTIAN HIEROGLYPH E033;Lo;0;L;;;;;N;;;;;\n130F9;EGYPTIAN HIEROGLYPH E034;Lo;0;L;;;;;N;;;;;\n130FA;EGYPTIAN HIEROGLYPH E034A;Lo;0;L;;;;;N;;;;;\n130FB;EGYPTIAN HIEROGLYPH E036;Lo;0;L;;;;;N;;;;;\n130FC;EGYPTIAN HIEROGLYPH E037;Lo;0;L;;;;;N;;;;;\n130FD;EGYPTIAN HIEROGLYPH E038;Lo;0;L;;;;;N;;;;;\n130FE;EGYPTIAN HIEROGLYPH F001;Lo;0;L;;;;;N;;;;;\n130FF;EGYPTIAN HIEROGLYPH F001A;Lo;0;L;;;;;N;;;;;\n13100;EGYPTIAN HIEROGLYPH F002;Lo;0;L;;;;;N;;;;;\n13101;EGYPTIAN HIEROGLYPH F003;Lo;0;L;;;;;N;;;;;\n13102;EGYPTIAN HIEROGLYPH F004;Lo;0;L;;;;;N;;;;;\n13103;EGYPTIAN HIEROGLYPH F005;Lo;0;L;;;;;N;;;;;\n13104;EGYPTIAN HIEROGLYPH F006;Lo;0;L;;;;;N;;;;;\n13105;EGYPTIAN HIEROGLYPH F007;Lo;0;L;;;;;N;;;;;\n13106;EGYPTIAN HIEROGLYPH F008;Lo;0;L;;;;;N;;;;;\n13107;EGYPTIAN HIEROGLYPH F009;Lo;0;L;;;;;N;;;;;\n13108;EGYPTIAN HIEROGLYPH F010;Lo;0;L;;;;;N;;;;;\n13109;EGYPTIAN HIEROGLYPH F011;Lo;0;L;;;;;N;;;;;\n1310A;EGYPTIAN HIEROGLYPH F012;Lo;0;L;;;;;N;;;;;\n1310B;EGYPTIAN HIEROGLYPH F013;Lo;0;L;;;;;N;;;;;\n1310C;EGYPTIAN HIEROGLYPH F013A;Lo;0;L;;;;;N;;;;;\n1310D;EGYPTIAN HIEROGLYPH F014;Lo;0;L;;;;;N;;;;;\n1310E;EGYPTIAN HIEROGLYPH F015;Lo;0;L;;;;;N;;;;;\n1310F;EGYPTIAN HIEROGLYPH F016;Lo;0;L;;;;;N;;;;;\n13110;EGYPTIAN HIEROGLYPH F017;Lo;0;L;;;;;N;;;;;\n13111;EGYPTIAN HIEROGLYPH F018;Lo;0;L;;;;;N;;;;;\n13112;EGYPTIAN HIEROGLYPH F019;Lo;0;L;;;;;N;;;;;\n13113;EGYPTIAN HIEROGLYPH F020;Lo;0;L;;;;;N;;;;;\n13114;EGYPTIAN HIEROGLYPH F021;Lo;0;L;;;;;N;;;;;\n13115;EGYPTIAN HIEROGLYPH F021A;Lo;0;L;;;;;N;;;;;\n13116;EGYPTIAN HIEROGLYPH F022;Lo;0;L;;;;;N;;;;;\n13117;EGYPTIAN HIEROGLYPH F023;Lo;0;L;;;;;N;;;;;\n13118;EGYPTIAN HIEROGLYPH F024;Lo;0;L;;;;;N;;;;;\n13119;EGYPTIAN HIEROGLYPH F025;Lo;0;L;;;;;N;;;;;\n1311A;EGYPTIAN HIEROGLYPH F026;Lo;0;L;;;;;N;;;;;\n1311B;EGYPTIAN HIEROGLYPH F027;Lo;0;L;;;;;N;;;;;\n1311C;EGYPTIAN HIEROGLYPH F028;Lo;0;L;;;;;N;;;;;\n1311D;EGYPTIAN HIEROGLYPH F029;Lo;0;L;;;;;N;;;;;\n1311E;EGYPTIAN HIEROGLYPH F030;Lo;0;L;;;;;N;;;;;\n1311F;EGYPTIAN HIEROGLYPH F031;Lo;0;L;;;;;N;;;;;\n13120;EGYPTIAN HIEROGLYPH F031A;Lo;0;L;;;;;N;;;;;\n13121;EGYPTIAN HIEROGLYPH F032;Lo;0;L;;;;;N;;;;;\n13122;EGYPTIAN HIEROGLYPH F033;Lo;0;L;;;;;N;;;;;\n13123;EGYPTIAN HIEROGLYPH F034;Lo;0;L;;;;;N;;;;;\n13124;EGYPTIAN HIEROGLYPH F035;Lo;0;L;;;;;N;;;;;\n13125;EGYPTIAN HIEROGLYPH F036;Lo;0;L;;;;;N;;;;;\n13126;EGYPTIAN HIEROGLYPH F037;Lo;0;L;;;;;N;;;;;\n13127;EGYPTIAN HIEROGLYPH F037A;Lo;0;L;;;;;N;;;;;\n13128;EGYPTIAN HIEROGLYPH F038;Lo;0;L;;;;;N;;;;;\n13129;EGYPTIAN HIEROGLYPH F038A;Lo;0;L;;;;;N;;;;;\n1312A;EGYPTIAN HIEROGLYPH F039;Lo;0;L;;;;;N;;;;;\n1312B;EGYPTIAN HIEROGLYPH F040;Lo;0;L;;;;;N;;;;;\n1312C;EGYPTIAN HIEROGLYPH F041;Lo;0;L;;;;;N;;;;;\n1312D;EGYPTIAN HIEROGLYPH F042;Lo;0;L;;;;;N;;;;;\n1312E;EGYPTIAN HIEROGLYPH F043;Lo;0;L;;;;;N;;;;;\n1312F;EGYPTIAN HIEROGLYPH F044;Lo;0;L;;;;;N;;;;;\n13130;EGYPTIAN HIEROGLYPH F045;Lo;0;L;;;;;N;;;;;\n13131;EGYPTIAN HIEROGLYPH F045A;Lo;0;L;;;;;N;;;;;\n13132;EGYPTIAN HIEROGLYPH F046;Lo;0;L;;;;;N;;;;;\n13133;EGYPTIAN HIEROGLYPH F046A;Lo;0;L;;;;;N;;;;;\n13134;EGYPTIAN HIEROGLYPH F047;Lo;0;L;;;;;N;;;;;\n13135;EGYPTIAN HIEROGLYPH F047A;Lo;0;L;;;;;N;;;;;\n13136;EGYPTIAN HIEROGLYPH F048;Lo;0;L;;;;;N;;;;;\n13137;EGYPTIAN HIEROGLYPH F049;Lo;0;L;;;;;N;;;;;\n13138;EGYPTIAN HIEROGLYPH F050;Lo;0;L;;;;;N;;;;;\n13139;EGYPTIAN HIEROGLYPH F051;Lo;0;L;;;;;N;;;;;\n1313A;EGYPTIAN HIEROGLYPH F051A;Lo;0;L;;;;;N;;;;;\n1313B;EGYPTIAN HIEROGLYPH F051B;Lo;0;L;;;;;N;;;;;\n1313C;EGYPTIAN HIEROGLYPH F051C;Lo;0;L;;;;;N;;;;;\n1313D;EGYPTIAN HIEROGLYPH F052;Lo;0;L;;;;;N;;;;;\n1313E;EGYPTIAN HIEROGLYPH F053;Lo;0;L;;;;;N;;;;;\n1313F;EGYPTIAN HIEROGLYPH G001;Lo;0;L;;;;;N;;;;;\n13140;EGYPTIAN HIEROGLYPH G002;Lo;0;L;;;;;N;;;;;\n13141;EGYPTIAN HIEROGLYPH G003;Lo;0;L;;;;;N;;;;;\n13142;EGYPTIAN HIEROGLYPH G004;Lo;0;L;;;;;N;;;;;\n13143;EGYPTIAN HIEROGLYPH G005;Lo;0;L;;;;;N;;;;;\n13144;EGYPTIAN HIEROGLYPH G006;Lo;0;L;;;;;N;;;;;\n13145;EGYPTIAN HIEROGLYPH G006A;Lo;0;L;;;;;N;;;;;\n13146;EGYPTIAN HIEROGLYPH G007;Lo;0;L;;;;;N;;;;;\n13147;EGYPTIAN HIEROGLYPH G007A;Lo;0;L;;;;;N;;;;;\n13148;EGYPTIAN HIEROGLYPH G007B;Lo;0;L;;;;;N;;;;;\n13149;EGYPTIAN HIEROGLYPH G008;Lo;0;L;;;;;N;;;;;\n1314A;EGYPTIAN HIEROGLYPH G009;Lo;0;L;;;;;N;;;;;\n1314B;EGYPTIAN HIEROGLYPH G010;Lo;0;L;;;;;N;;;;;\n1314C;EGYPTIAN HIEROGLYPH G011;Lo;0;L;;;;;N;;;;;\n1314D;EGYPTIAN HIEROGLYPH G011A;Lo;0;L;;;;;N;;;;;\n1314E;EGYPTIAN HIEROGLYPH G012;Lo;0;L;;;;;N;;;;;\n1314F;EGYPTIAN HIEROGLYPH G013;Lo;0;L;;;;;N;;;;;\n13150;EGYPTIAN HIEROGLYPH G014;Lo;0;L;;;;;N;;;;;\n13151;EGYPTIAN HIEROGLYPH G015;Lo;0;L;;;;;N;;;;;\n13152;EGYPTIAN HIEROGLYPH G016;Lo;0;L;;;;;N;;;;;\n13153;EGYPTIAN HIEROGLYPH G017;Lo;0;L;;;;;N;;;;;\n13154;EGYPTIAN HIEROGLYPH G018;Lo;0;L;;;;;N;;;;;\n13155;EGYPTIAN HIEROGLYPH G019;Lo;0;L;;;;;N;;;;;\n13156;EGYPTIAN HIEROGLYPH G020;Lo;0;L;;;;;N;;;;;\n13157;EGYPTIAN HIEROGLYPH G020A;Lo;0;L;;;;;N;;;;;\n13158;EGYPTIAN HIEROGLYPH G021;Lo;0;L;;;;;N;;;;;\n13159;EGYPTIAN HIEROGLYPH G022;Lo;0;L;;;;;N;;;;;\n1315A;EGYPTIAN HIEROGLYPH G023;Lo;0;L;;;;;N;;;;;\n1315B;EGYPTIAN HIEROGLYPH G024;Lo;0;L;;;;;N;;;;;\n1315C;EGYPTIAN HIEROGLYPH G025;Lo;0;L;;;;;N;;;;;\n1315D;EGYPTIAN HIEROGLYPH G026;Lo;0;L;;;;;N;;;;;\n1315E;EGYPTIAN HIEROGLYPH G026A;Lo;0;L;;;;;N;;;;;\n1315F;EGYPTIAN HIEROGLYPH G027;Lo;0;L;;;;;N;;;;;\n13160;EGYPTIAN HIEROGLYPH G028;Lo;0;L;;;;;N;;;;;\n13161;EGYPTIAN HIEROGLYPH G029;Lo;0;L;;;;;N;;;;;\n13162;EGYPTIAN HIEROGLYPH G030;Lo;0;L;;;;;N;;;;;\n13163;EGYPTIAN HIEROGLYPH G031;Lo;0;L;;;;;N;;;;;\n13164;EGYPTIAN HIEROGLYPH G032;Lo;0;L;;;;;N;;;;;\n13165;EGYPTIAN HIEROGLYPH G033;Lo;0;L;;;;;N;;;;;\n13166;EGYPTIAN HIEROGLYPH G034;Lo;0;L;;;;;N;;;;;\n13167;EGYPTIAN HIEROGLYPH G035;Lo;0;L;;;;;N;;;;;\n13168;EGYPTIAN HIEROGLYPH G036;Lo;0;L;;;;;N;;;;;\n13169;EGYPTIAN HIEROGLYPH G036A;Lo;0;L;;;;;N;;;;;\n1316A;EGYPTIAN HIEROGLYPH G037;Lo;0;L;;;;;N;;;;;\n1316B;EGYPTIAN HIEROGLYPH G037A;Lo;0;L;;;;;N;;;;;\n1316C;EGYPTIAN HIEROGLYPH G038;Lo;0;L;;;;;N;;;;;\n1316D;EGYPTIAN HIEROGLYPH G039;Lo;0;L;;;;;N;;;;;\n1316E;EGYPTIAN HIEROGLYPH G040;Lo;0;L;;;;;N;;;;;\n1316F;EGYPTIAN HIEROGLYPH G041;Lo;0;L;;;;;N;;;;;\n13170;EGYPTIAN HIEROGLYPH G042;Lo;0;L;;;;;N;;;;;\n13171;EGYPTIAN HIEROGLYPH G043;Lo;0;L;;;;;N;;;;;\n13172;EGYPTIAN HIEROGLYPH G043A;Lo;0;L;;;;;N;;;;;\n13173;EGYPTIAN HIEROGLYPH G044;Lo;0;L;;;;;N;;;;;\n13174;EGYPTIAN HIEROGLYPH G045;Lo;0;L;;;;;N;;;;;\n13175;EGYPTIAN HIEROGLYPH G045A;Lo;0;L;;;;;N;;;;;\n13176;EGYPTIAN HIEROGLYPH G046;Lo;0;L;;;;;N;;;;;\n13177;EGYPTIAN HIEROGLYPH G047;Lo;0;L;;;;;N;;;;;\n13178;EGYPTIAN HIEROGLYPH G048;Lo;0;L;;;;;N;;;;;\n13179;EGYPTIAN HIEROGLYPH G049;Lo;0;L;;;;;N;;;;;\n1317A;EGYPTIAN HIEROGLYPH G050;Lo;0;L;;;;;N;;;;;\n1317B;EGYPTIAN HIEROGLYPH G051;Lo;0;L;;;;;N;;;;;\n1317C;EGYPTIAN HIEROGLYPH G052;Lo;0;L;;;;;N;;;;;\n1317D;EGYPTIAN HIEROGLYPH G053;Lo;0;L;;;;;N;;;;;\n1317E;EGYPTIAN HIEROGLYPH G054;Lo;0;L;;;;;N;;;;;\n1317F;EGYPTIAN HIEROGLYPH H001;Lo;0;L;;;;;N;;;;;\n13180;EGYPTIAN HIEROGLYPH H002;Lo;0;L;;;;;N;;;;;\n13181;EGYPTIAN HIEROGLYPH H003;Lo;0;L;;;;;N;;;;;\n13182;EGYPTIAN HIEROGLYPH H004;Lo;0;L;;;;;N;;;;;\n13183;EGYPTIAN HIEROGLYPH H005;Lo;0;L;;;;;N;;;;;\n13184;EGYPTIAN HIEROGLYPH H006;Lo;0;L;;;;;N;;;;;\n13185;EGYPTIAN HIEROGLYPH H006A;Lo;0;L;;;;;N;;;;;\n13186;EGYPTIAN HIEROGLYPH H007;Lo;0;L;;;;;N;;;;;\n13187;EGYPTIAN HIEROGLYPH H008;Lo;0;L;;;;;N;;;;;\n13188;EGYPTIAN HIEROGLYPH I001;Lo;0;L;;;;;N;;;;;\n13189;EGYPTIAN HIEROGLYPH I002;Lo;0;L;;;;;N;;;;;\n1318A;EGYPTIAN HIEROGLYPH I003;Lo;0;L;;;;;N;;;;;\n1318B;EGYPTIAN HIEROGLYPH I004;Lo;0;L;;;;;N;;;;;\n1318C;EGYPTIAN HIEROGLYPH I005;Lo;0;L;;;;;N;;;;;\n1318D;EGYPTIAN HIEROGLYPH I005A;Lo;0;L;;;;;N;;;;;\n1318E;EGYPTIAN HIEROGLYPH I006;Lo;0;L;;;;;N;;;;;\n1318F;EGYPTIAN HIEROGLYPH I007;Lo;0;L;;;;;N;;;;;\n13190;EGYPTIAN HIEROGLYPH I008;Lo;0;L;;;;;N;;;;;\n13191;EGYPTIAN HIEROGLYPH I009;Lo;0;L;;;;;N;;;;;\n13192;EGYPTIAN HIEROGLYPH I009A;Lo;0;L;;;;;N;;;;;\n13193;EGYPTIAN HIEROGLYPH I010;Lo;0;L;;;;;N;;;;;\n13194;EGYPTIAN HIEROGLYPH I010A;Lo;0;L;;;;;N;;;;;\n13195;EGYPTIAN HIEROGLYPH I011;Lo;0;L;;;;;N;;;;;\n13196;EGYPTIAN HIEROGLYPH I011A;Lo;0;L;;;;;N;;;;;\n13197;EGYPTIAN HIEROGLYPH I012;Lo;0;L;;;;;N;;;;;\n13198;EGYPTIAN HIEROGLYPH I013;Lo;0;L;;;;;N;;;;;\n13199;EGYPTIAN HIEROGLYPH I014;Lo;0;L;;;;;N;;;;;\n1319A;EGYPTIAN HIEROGLYPH I015;Lo;0;L;;;;;N;;;;;\n1319B;EGYPTIAN HIEROGLYPH K001;Lo;0;L;;;;;N;;;;;\n1319C;EGYPTIAN HIEROGLYPH K002;Lo;0;L;;;;;N;;;;;\n1319D;EGYPTIAN HIEROGLYPH K003;Lo;0;L;;;;;N;;;;;\n1319E;EGYPTIAN HIEROGLYPH K004;Lo;0;L;;;;;N;;;;;\n1319F;EGYPTIAN HIEROGLYPH K005;Lo;0;L;;;;;N;;;;;\n131A0;EGYPTIAN HIEROGLYPH K006;Lo;0;L;;;;;N;;;;;\n131A1;EGYPTIAN HIEROGLYPH K007;Lo;0;L;;;;;N;;;;;\n131A2;EGYPTIAN HIEROGLYPH K008;Lo;0;L;;;;;N;;;;;\n131A3;EGYPTIAN HIEROGLYPH L001;Lo;0;L;;;;;N;;;;;\n131A4;EGYPTIAN HIEROGLYPH L002;Lo;0;L;;;;;N;;;;;\n131A5;EGYPTIAN HIEROGLYPH L002A;Lo;0;L;;;;;N;;;;;\n131A6;EGYPTIAN HIEROGLYPH L003;Lo;0;L;;;;;N;;;;;\n131A7;EGYPTIAN HIEROGLYPH L004;Lo;0;L;;;;;N;;;;;\n131A8;EGYPTIAN HIEROGLYPH L005;Lo;0;L;;;;;N;;;;;\n131A9;EGYPTIAN HIEROGLYPH L006;Lo;0;L;;;;;N;;;;;\n131AA;EGYPTIAN HIEROGLYPH L006A;Lo;0;L;;;;;N;;;;;\n131AB;EGYPTIAN HIEROGLYPH L007;Lo;0;L;;;;;N;;;;;\n131AC;EGYPTIAN HIEROGLYPH L008;Lo;0;L;;;;;N;;;;;\n131AD;EGYPTIAN HIEROGLYPH M001;Lo;0;L;;;;;N;;;;;\n131AE;EGYPTIAN HIEROGLYPH M001A;Lo;0;L;;;;;N;;;;;\n131AF;EGYPTIAN HIEROGLYPH M001B;Lo;0;L;;;;;N;;;;;\n131B0;EGYPTIAN HIEROGLYPH M002;Lo;0;L;;;;;N;;;;;\n131B1;EGYPTIAN HIEROGLYPH M003;Lo;0;L;;;;;N;;;;;\n131B2;EGYPTIAN HIEROGLYPH M003A;Lo;0;L;;;;;N;;;;;\n131B3;EGYPTIAN HIEROGLYPH M004;Lo;0;L;;;;;N;;;;;\n131B4;EGYPTIAN HIEROGLYPH M005;Lo;0;L;;;;;N;;;;;\n131B5;EGYPTIAN HIEROGLYPH M006;Lo;0;L;;;;;N;;;;;\n131B6;EGYPTIAN HIEROGLYPH M007;Lo;0;L;;;;;N;;;;;\n131B7;EGYPTIAN HIEROGLYPH M008;Lo;0;L;;;;;N;;;;;\n131B8;EGYPTIAN HIEROGLYPH M009;Lo;0;L;;;;;N;;;;;\n131B9;EGYPTIAN HIEROGLYPH M010;Lo;0;L;;;;;N;;;;;\n131BA;EGYPTIAN HIEROGLYPH M010A;Lo;0;L;;;;;N;;;;;\n131BB;EGYPTIAN HIEROGLYPH M011;Lo;0;L;;;;;N;;;;;\n131BC;EGYPTIAN HIEROGLYPH M012;Lo;0;L;;;;;N;;;;;\n131BD;EGYPTIAN HIEROGLYPH M012A;Lo;0;L;;;;;N;;;;;\n131BE;EGYPTIAN HIEROGLYPH M012B;Lo;0;L;;;;;N;;;;;\n131BF;EGYPTIAN HIEROGLYPH M012C;Lo;0;L;;;;;N;;;;;\n131C0;EGYPTIAN HIEROGLYPH M012D;Lo;0;L;;;;;N;;;;;\n131C1;EGYPTIAN HIEROGLYPH M012E;Lo;0;L;;;;;N;;;;;\n131C2;EGYPTIAN HIEROGLYPH M012F;Lo;0;L;;;;;N;;;;;\n131C3;EGYPTIAN HIEROGLYPH M012G;Lo;0;L;;;;;N;;;;;\n131C4;EGYPTIAN HIEROGLYPH M012H;Lo;0;L;;;;;N;;;;;\n131C5;EGYPTIAN HIEROGLYPH M013;Lo;0;L;;;;;N;;;;;\n131C6;EGYPTIAN HIEROGLYPH M014;Lo;0;L;;;;;N;;;;;\n131C7;EGYPTIAN HIEROGLYPH M015;Lo;0;L;;;;;N;;;;;\n131C8;EGYPTIAN HIEROGLYPH M015A;Lo;0;L;;;;;N;;;;;\n131C9;EGYPTIAN HIEROGLYPH M016;Lo;0;L;;;;;N;;;;;\n131CA;EGYPTIAN HIEROGLYPH M016A;Lo;0;L;;;;;N;;;;;\n131CB;EGYPTIAN HIEROGLYPH M017;Lo;0;L;;;;;N;;;;;\n131CC;EGYPTIAN HIEROGLYPH M017A;Lo;0;L;;;;;N;;;;;\n131CD;EGYPTIAN HIEROGLYPH M018;Lo;0;L;;;;;N;;;;;\n131CE;EGYPTIAN HIEROGLYPH M019;Lo;0;L;;;;;N;;;;;\n131CF;EGYPTIAN HIEROGLYPH M020;Lo;0;L;;;;;N;;;;;\n131D0;EGYPTIAN HIEROGLYPH M021;Lo;0;L;;;;;N;;;;;\n131D1;EGYPTIAN HIEROGLYPH M022;Lo;0;L;;;;;N;;;;;\n131D2;EGYPTIAN HIEROGLYPH M022A;Lo;0;L;;;;;N;;;;;\n131D3;EGYPTIAN HIEROGLYPH M023;Lo;0;L;;;;;N;;;;;\n131D4;EGYPTIAN HIEROGLYPH M024;Lo;0;L;;;;;N;;;;;\n131D5;EGYPTIAN HIEROGLYPH M024A;Lo;0;L;;;;;N;;;;;\n131D6;EGYPTIAN HIEROGLYPH M025;Lo;0;L;;;;;N;;;;;\n131D7;EGYPTIAN HIEROGLYPH M026;Lo;0;L;;;;;N;;;;;\n131D8;EGYPTIAN HIEROGLYPH M027;Lo;0;L;;;;;N;;;;;\n131D9;EGYPTIAN HIEROGLYPH M028;Lo;0;L;;;;;N;;;;;\n131DA;EGYPTIAN HIEROGLYPH M028A;Lo;0;L;;;;;N;;;;;\n131DB;EGYPTIAN HIEROGLYPH M029;Lo;0;L;;;;;N;;;;;\n131DC;EGYPTIAN HIEROGLYPH M030;Lo;0;L;;;;;N;;;;;\n131DD;EGYPTIAN HIEROGLYPH M031;Lo;0;L;;;;;N;;;;;\n131DE;EGYPTIAN HIEROGLYPH M031A;Lo;0;L;;;;;N;;;;;\n131DF;EGYPTIAN HIEROGLYPH M032;Lo;0;L;;;;;N;;;;;\n131E0;EGYPTIAN HIEROGLYPH M033;Lo;0;L;;;;;N;;;;;\n131E1;EGYPTIAN HIEROGLYPH M033A;Lo;0;L;;;;;N;;;;;\n131E2;EGYPTIAN HIEROGLYPH M033B;Lo;0;L;;;;;N;;;;;\n131E3;EGYPTIAN HIEROGLYPH M034;Lo;0;L;;;;;N;;;;;\n131E4;EGYPTIAN HIEROGLYPH M035;Lo;0;L;;;;;N;;;;;\n131E5;EGYPTIAN HIEROGLYPH M036;Lo;0;L;;;;;N;;;;;\n131E6;EGYPTIAN HIEROGLYPH M037;Lo;0;L;;;;;N;;;;;\n131E7;EGYPTIAN HIEROGLYPH M038;Lo;0;L;;;;;N;;;;;\n131E8;EGYPTIAN HIEROGLYPH M039;Lo;0;L;;;;;N;;;;;\n131E9;EGYPTIAN HIEROGLYPH M040;Lo;0;L;;;;;N;;;;;\n131EA;EGYPTIAN HIEROGLYPH M040A;Lo;0;L;;;;;N;;;;;\n131EB;EGYPTIAN HIEROGLYPH M041;Lo;0;L;;;;;N;;;;;\n131EC;EGYPTIAN HIEROGLYPH M042;Lo;0;L;;;;;N;;;;;\n131ED;EGYPTIAN HIEROGLYPH M043;Lo;0;L;;;;;N;;;;;\n131EE;EGYPTIAN HIEROGLYPH M044;Lo;0;L;;;;;N;;;;;\n131EF;EGYPTIAN HIEROGLYPH N001;Lo;0;L;;;;;N;;;;;\n131F0;EGYPTIAN HIEROGLYPH N002;Lo;0;L;;;;;N;;;;;\n131F1;EGYPTIAN HIEROGLYPH N003;Lo;0;L;;;;;N;;;;;\n131F2;EGYPTIAN HIEROGLYPH N004;Lo;0;L;;;;;N;;;;;\n131F3;EGYPTIAN HIEROGLYPH N005;Lo;0;L;;;;;N;;;;;\n131F4;EGYPTIAN HIEROGLYPH N006;Lo;0;L;;;;;N;;;;;\n131F5;EGYPTIAN HIEROGLYPH N007;Lo;0;L;;;;;N;;;;;\n131F6;EGYPTIAN HIEROGLYPH N008;Lo;0;L;;;;;N;;;;;\n131F7;EGYPTIAN HIEROGLYPH N009;Lo;0;L;;;;;N;;;;;\n131F8;EGYPTIAN HIEROGLYPH N010;Lo;0;L;;;;;N;;;;;\n131F9;EGYPTIAN HIEROGLYPH N011;Lo;0;L;;;;;N;;;;;\n131FA;EGYPTIAN HIEROGLYPH N012;Lo;0;L;;;;;N;;;;;\n131FB;EGYPTIAN HIEROGLYPH N013;Lo;0;L;;;;;N;;;;;\n131FC;EGYPTIAN HIEROGLYPH N014;Lo;0;L;;;;;N;;;;;\n131FD;EGYPTIAN HIEROGLYPH N015;Lo;0;L;;;;;N;;;;;\n131FE;EGYPTIAN HIEROGLYPH N016;Lo;0;L;;;;;N;;;;;\n131FF;EGYPTIAN HIEROGLYPH N017;Lo;0;L;;;;;N;;;;;\n13200;EGYPTIAN HIEROGLYPH N018;Lo;0;L;;;;;N;;;;;\n13201;EGYPTIAN HIEROGLYPH N018A;Lo;0;L;;;;;N;;;;;\n13202;EGYPTIAN HIEROGLYPH N018B;Lo;0;L;;;;;N;;;;;\n13203;EGYPTIAN HIEROGLYPH N019;Lo;0;L;;;;;N;;;;;\n13204;EGYPTIAN HIEROGLYPH N020;Lo;0;L;;;;;N;;;;;\n13205;EGYPTIAN HIEROGLYPH N021;Lo;0;L;;;;;N;;;;;\n13206;EGYPTIAN HIEROGLYPH N022;Lo;0;L;;;;;N;;;;;\n13207;EGYPTIAN HIEROGLYPH N023;Lo;0;L;;;;;N;;;;;\n13208;EGYPTIAN HIEROGLYPH N024;Lo;0;L;;;;;N;;;;;\n13209;EGYPTIAN HIEROGLYPH N025;Lo;0;L;;;;;N;;;;;\n1320A;EGYPTIAN HIEROGLYPH N025A;Lo;0;L;;;;;N;;;;;\n1320B;EGYPTIAN HIEROGLYPH N026;Lo;0;L;;;;;N;;;;;\n1320C;EGYPTIAN HIEROGLYPH N027;Lo;0;L;;;;;N;;;;;\n1320D;EGYPTIAN HIEROGLYPH N028;Lo;0;L;;;;;N;;;;;\n1320E;EGYPTIAN HIEROGLYPH N029;Lo;0;L;;;;;N;;;;;\n1320F;EGYPTIAN HIEROGLYPH N030;Lo;0;L;;;;;N;;;;;\n13210;EGYPTIAN HIEROGLYPH N031;Lo;0;L;;;;;N;;;;;\n13211;EGYPTIAN HIEROGLYPH N032;Lo;0;L;;;;;N;;;;;\n13212;EGYPTIAN HIEROGLYPH N033;Lo;0;L;;;;;N;;;;;\n13213;EGYPTIAN HIEROGLYPH N033A;Lo;0;L;;;;;N;;;;;\n13214;EGYPTIAN HIEROGLYPH N034;Lo;0;L;;;;;N;;;;;\n13215;EGYPTIAN HIEROGLYPH N034A;Lo;0;L;;;;;N;;;;;\n13216;EGYPTIAN HIEROGLYPH N035;Lo;0;L;;;;;N;;;;;\n13217;EGYPTIAN HIEROGLYPH N035A;Lo;0;L;;;;;N;;;;;\n13218;EGYPTIAN HIEROGLYPH N036;Lo;0;L;;;;;N;;;;;\n13219;EGYPTIAN HIEROGLYPH N037;Lo;0;L;;;;;N;;;;;\n1321A;EGYPTIAN HIEROGLYPH N037A;Lo;0;L;;;;;N;;;;;\n1321B;EGYPTIAN HIEROGLYPH N038;Lo;0;L;;;;;N;;;;;\n1321C;EGYPTIAN HIEROGLYPH N039;Lo;0;L;;;;;N;;;;;\n1321D;EGYPTIAN HIEROGLYPH N040;Lo;0;L;;;;;N;;;;;\n1321E;EGYPTIAN HIEROGLYPH N041;Lo;0;L;;;;;N;;;;;\n1321F;EGYPTIAN HIEROGLYPH N042;Lo;0;L;;;;;N;;;;;\n13220;EGYPTIAN HIEROGLYPH NL001;Lo;0;L;;;;;N;;;;;\n13221;EGYPTIAN HIEROGLYPH NL002;Lo;0;L;;;;;N;;;;;\n13222;EGYPTIAN HIEROGLYPH NL003;Lo;0;L;;;;;N;;;;;\n13223;EGYPTIAN HIEROGLYPH NL004;Lo;0;L;;;;;N;;;;;\n13224;EGYPTIAN HIEROGLYPH NL005;Lo;0;L;;;;;N;;;;;\n13225;EGYPTIAN HIEROGLYPH NL005A;Lo;0;L;;;;;N;;;;;\n13226;EGYPTIAN HIEROGLYPH NL006;Lo;0;L;;;;;N;;;;;\n13227;EGYPTIAN HIEROGLYPH NL007;Lo;0;L;;;;;N;;;;;\n13228;EGYPTIAN HIEROGLYPH NL008;Lo;0;L;;;;;N;;;;;\n13229;EGYPTIAN HIEROGLYPH NL009;Lo;0;L;;;;;N;;;;;\n1322A;EGYPTIAN HIEROGLYPH NL010;Lo;0;L;;;;;N;;;;;\n1322B;EGYPTIAN HIEROGLYPH NL011;Lo;0;L;;;;;N;;;;;\n1322C;EGYPTIAN HIEROGLYPH NL012;Lo;0;L;;;;;N;;;;;\n1322D;EGYPTIAN HIEROGLYPH NL013;Lo;0;L;;;;;N;;;;;\n1322E;EGYPTIAN HIEROGLYPH NL014;Lo;0;L;;;;;N;;;;;\n1322F;EGYPTIAN HIEROGLYPH NL015;Lo;0;L;;;;;N;;;;;\n13230;EGYPTIAN HIEROGLYPH NL016;Lo;0;L;;;;;N;;;;;\n13231;EGYPTIAN HIEROGLYPH NL017;Lo;0;L;;;;;N;;;;;\n13232;EGYPTIAN HIEROGLYPH NL017A;Lo;0;L;;;;;N;;;;;\n13233;EGYPTIAN HIEROGLYPH NL018;Lo;0;L;;;;;N;;;;;\n13234;EGYPTIAN HIEROGLYPH NL019;Lo;0;L;;;;;N;;;;;\n13235;EGYPTIAN HIEROGLYPH NL020;Lo;0;L;;;;;N;;;;;\n13236;EGYPTIAN HIEROGLYPH NU001;Lo;0;L;;;;;N;;;;;\n13237;EGYPTIAN HIEROGLYPH NU002;Lo;0;L;;;;;N;;;;;\n13238;EGYPTIAN HIEROGLYPH NU003;Lo;0;L;;;;;N;;;;;\n13239;EGYPTIAN HIEROGLYPH NU004;Lo;0;L;;;;;N;;;;;\n1323A;EGYPTIAN HIEROGLYPH NU005;Lo;0;L;;;;;N;;;;;\n1323B;EGYPTIAN HIEROGLYPH NU006;Lo;0;L;;;;;N;;;;;\n1323C;EGYPTIAN HIEROGLYPH NU007;Lo;0;L;;;;;N;;;;;\n1323D;EGYPTIAN HIEROGLYPH NU008;Lo;0;L;;;;;N;;;;;\n1323E;EGYPTIAN HIEROGLYPH NU009;Lo;0;L;;;;;N;;;;;\n1323F;EGYPTIAN HIEROGLYPH NU010;Lo;0;L;;;;;N;;;;;\n13240;EGYPTIAN HIEROGLYPH NU010A;Lo;0;L;;;;;N;;;;;\n13241;EGYPTIAN HIEROGLYPH NU011;Lo;0;L;;;;;N;;;;;\n13242;EGYPTIAN HIEROGLYPH NU011A;Lo;0;L;;;;;N;;;;;\n13243;EGYPTIAN HIEROGLYPH NU012;Lo;0;L;;;;;N;;;;;\n13244;EGYPTIAN HIEROGLYPH NU013;Lo;0;L;;;;;N;;;;;\n13245;EGYPTIAN HIEROGLYPH NU014;Lo;0;L;;;;;N;;;;;\n13246;EGYPTIAN HIEROGLYPH NU015;Lo;0;L;;;;;N;;;;;\n13247;EGYPTIAN HIEROGLYPH NU016;Lo;0;L;;;;;N;;;;;\n13248;EGYPTIAN HIEROGLYPH NU017;Lo;0;L;;;;;N;;;;;\n13249;EGYPTIAN HIEROGLYPH NU018;Lo;0;L;;;;;N;;;;;\n1324A;EGYPTIAN HIEROGLYPH NU018A;Lo;0;L;;;;;N;;;;;\n1324B;EGYPTIAN HIEROGLYPH NU019;Lo;0;L;;;;;N;;;;;\n1324C;EGYPTIAN HIEROGLYPH NU020;Lo;0;L;;;;;N;;;;;\n1324D;EGYPTIAN HIEROGLYPH NU021;Lo;0;L;;;;;N;;;;;\n1324E;EGYPTIAN HIEROGLYPH NU022;Lo;0;L;;;;;N;;;;;\n1324F;EGYPTIAN HIEROGLYPH NU022A;Lo;0;L;;;;;N;;;;;\n13250;EGYPTIAN HIEROGLYPH O001;Lo;0;L;;;;;N;;;;;\n13251;EGYPTIAN HIEROGLYPH O001A;Lo;0;L;;;;;N;;;;;\n13252;EGYPTIAN HIEROGLYPH O002;Lo;0;L;;;;;N;;;;;\n13253;EGYPTIAN HIEROGLYPH O003;Lo;0;L;;;;;N;;;;;\n13254;EGYPTIAN HIEROGLYPH O004;Lo;0;L;;;;;N;;;;;\n13255;EGYPTIAN HIEROGLYPH O005;Lo;0;L;;;;;N;;;;;\n13256;EGYPTIAN HIEROGLYPH O005A;Lo;0;L;;;;;N;;;;;\n13257;EGYPTIAN HIEROGLYPH O006;Lo;0;L;;;;;N;;;;;\n13258;EGYPTIAN HIEROGLYPH O006A;Lo;0;L;;;;;N;;;;;\n13259;EGYPTIAN HIEROGLYPH O006B;Lo;0;L;;;;;N;;;;;\n1325A;EGYPTIAN HIEROGLYPH O006C;Lo;0;L;;;;;N;;;;;\n1325B;EGYPTIAN HIEROGLYPH O006D;Lo;0;L;;;;;N;;;;;\n1325C;EGYPTIAN HIEROGLYPH O006E;Lo;0;L;;;;;N;;;;;\n1325D;EGYPTIAN HIEROGLYPH O006F;Lo;0;L;;;;;N;;;;;\n1325E;EGYPTIAN HIEROGLYPH O007;Lo;0;L;;;;;N;;;;;\n1325F;EGYPTIAN HIEROGLYPH O008;Lo;0;L;;;;;N;;;;;\n13260;EGYPTIAN HIEROGLYPH O009;Lo;0;L;;;;;N;;;;;\n13261;EGYPTIAN HIEROGLYPH O010;Lo;0;L;;;;;N;;;;;\n13262;EGYPTIAN HIEROGLYPH O010A;Lo;0;L;;;;;N;;;;;\n13263;EGYPTIAN HIEROGLYPH O010B;Lo;0;L;;;;;N;;;;;\n13264;EGYPTIAN HIEROGLYPH O010C;Lo;0;L;;;;;N;;;;;\n13265;EGYPTIAN HIEROGLYPH O011;Lo;0;L;;;;;N;;;;;\n13266;EGYPTIAN HIEROGLYPH O012;Lo;0;L;;;;;N;;;;;\n13267;EGYPTIAN HIEROGLYPH O013;Lo;0;L;;;;;N;;;;;\n13268;EGYPTIAN HIEROGLYPH O014;Lo;0;L;;;;;N;;;;;\n13269;EGYPTIAN HIEROGLYPH O015;Lo;0;L;;;;;N;;;;;\n1326A;EGYPTIAN HIEROGLYPH O016;Lo;0;L;;;;;N;;;;;\n1326B;EGYPTIAN HIEROGLYPH O017;Lo;0;L;;;;;N;;;;;\n1326C;EGYPTIAN HIEROGLYPH O018;Lo;0;L;;;;;N;;;;;\n1326D;EGYPTIAN HIEROGLYPH O019;Lo;0;L;;;;;N;;;;;\n1326E;EGYPTIAN HIEROGLYPH O019A;Lo;0;L;;;;;N;;;;;\n1326F;EGYPTIAN HIEROGLYPH O020;Lo;0;L;;;;;N;;;;;\n13270;EGYPTIAN HIEROGLYPH O020A;Lo;0;L;;;;;N;;;;;\n13271;EGYPTIAN HIEROGLYPH O021;Lo;0;L;;;;;N;;;;;\n13272;EGYPTIAN HIEROGLYPH O022;Lo;0;L;;;;;N;;;;;\n13273;EGYPTIAN HIEROGLYPH O023;Lo;0;L;;;;;N;;;;;\n13274;EGYPTIAN HIEROGLYPH O024;Lo;0;L;;;;;N;;;;;\n13275;EGYPTIAN HIEROGLYPH O024A;Lo;0;L;;;;;N;;;;;\n13276;EGYPTIAN HIEROGLYPH O025;Lo;0;L;;;;;N;;;;;\n13277;EGYPTIAN HIEROGLYPH O025A;Lo;0;L;;;;;N;;;;;\n13278;EGYPTIAN HIEROGLYPH O026;Lo;0;L;;;;;N;;;;;\n13279;EGYPTIAN HIEROGLYPH O027;Lo;0;L;;;;;N;;;;;\n1327A;EGYPTIAN HIEROGLYPH O028;Lo;0;L;;;;;N;;;;;\n1327B;EGYPTIAN HIEROGLYPH O029;Lo;0;L;;;;;N;;;;;\n1327C;EGYPTIAN HIEROGLYPH O029A;Lo;0;L;;;;;N;;;;;\n1327D;EGYPTIAN HIEROGLYPH O030;Lo;0;L;;;;;N;;;;;\n1327E;EGYPTIAN HIEROGLYPH O030A;Lo;0;L;;;;;N;;;;;\n1327F;EGYPTIAN HIEROGLYPH O031;Lo;0;L;;;;;N;;;;;\n13280;EGYPTIAN HIEROGLYPH O032;Lo;0;L;;;;;N;;;;;\n13281;EGYPTIAN HIEROGLYPH O033;Lo;0;L;;;;;N;;;;;\n13282;EGYPTIAN HIEROGLYPH O033A;Lo;0;L;;;;;N;;;;;\n13283;EGYPTIAN HIEROGLYPH O034;Lo;0;L;;;;;N;;;;;\n13284;EGYPTIAN HIEROGLYPH O035;Lo;0;L;;;;;N;;;;;\n13285;EGYPTIAN HIEROGLYPH O036;Lo;0;L;;;;;N;;;;;\n13286;EGYPTIAN HIEROGLYPH O036A;Lo;0;L;;;;;N;;;;;\n13287;EGYPTIAN HIEROGLYPH O036B;Lo;0;L;;;;;N;;;;;\n13288;EGYPTIAN HIEROGLYPH O036C;Lo;0;L;;;;;N;;;;;\n13289;EGYPTIAN HIEROGLYPH O036D;Lo;0;L;;;;;N;;;;;\n1328A;EGYPTIAN HIEROGLYPH O037;Lo;0;L;;;;;N;;;;;\n1328B;EGYPTIAN HIEROGLYPH O038;Lo;0;L;;;;;N;;;;;\n1328C;EGYPTIAN HIEROGLYPH O039;Lo;0;L;;;;;N;;;;;\n1328D;EGYPTIAN HIEROGLYPH O040;Lo;0;L;;;;;N;;;;;\n1328E;EGYPTIAN HIEROGLYPH O041;Lo;0;L;;;;;N;;;;;\n1328F;EGYPTIAN HIEROGLYPH O042;Lo;0;L;;;;;N;;;;;\n13290;EGYPTIAN HIEROGLYPH O043;Lo;0;L;;;;;N;;;;;\n13291;EGYPTIAN HIEROGLYPH O044;Lo;0;L;;;;;N;;;;;\n13292;EGYPTIAN HIEROGLYPH O045;Lo;0;L;;;;;N;;;;;\n13293;EGYPTIAN HIEROGLYPH O046;Lo;0;L;;;;;N;;;;;\n13294;EGYPTIAN HIEROGLYPH O047;Lo;0;L;;;;;N;;;;;\n13295;EGYPTIAN HIEROGLYPH O048;Lo;0;L;;;;;N;;;;;\n13296;EGYPTIAN HIEROGLYPH O049;Lo;0;L;;;;;N;;;;;\n13297;EGYPTIAN HIEROGLYPH O050;Lo;0;L;;;;;N;;;;;\n13298;EGYPTIAN HIEROGLYPH O050A;Lo;0;L;;;;;N;;;;;\n13299;EGYPTIAN HIEROGLYPH O050B;Lo;0;L;;;;;N;;;;;\n1329A;EGYPTIAN HIEROGLYPH O051;Lo;0;L;;;;;N;;;;;\n1329B;EGYPTIAN HIEROGLYPH P001;Lo;0;L;;;;;N;;;;;\n1329C;EGYPTIAN HIEROGLYPH P001A;Lo;0;L;;;;;N;;;;;\n1329D;EGYPTIAN HIEROGLYPH P002;Lo;0;L;;;;;N;;;;;\n1329E;EGYPTIAN HIEROGLYPH P003;Lo;0;L;;;;;N;;;;;\n1329F;EGYPTIAN HIEROGLYPH P003A;Lo;0;L;;;;;N;;;;;\n132A0;EGYPTIAN HIEROGLYPH P004;Lo;0;L;;;;;N;;;;;\n132A1;EGYPTIAN HIEROGLYPH P005;Lo;0;L;;;;;N;;;;;\n132A2;EGYPTIAN HIEROGLYPH P006;Lo;0;L;;;;;N;;;;;\n132A3;EGYPTIAN HIEROGLYPH P007;Lo;0;L;;;;;N;;;;;\n132A4;EGYPTIAN HIEROGLYPH P008;Lo;0;L;;;;;N;;;;;\n132A5;EGYPTIAN HIEROGLYPH P009;Lo;0;L;;;;;N;;;;;\n132A6;EGYPTIAN HIEROGLYPH P010;Lo;0;L;;;;;N;;;;;\n132A7;EGYPTIAN HIEROGLYPH P011;Lo;0;L;;;;;N;;;;;\n132A8;EGYPTIAN HIEROGLYPH Q001;Lo;0;L;;;;;N;;;;;\n132A9;EGYPTIAN HIEROGLYPH Q002;Lo;0;L;;;;;N;;;;;\n132AA;EGYPTIAN HIEROGLYPH Q003;Lo;0;L;;;;;N;;;;;\n132AB;EGYPTIAN HIEROGLYPH Q004;Lo;0;L;;;;;N;;;;;\n132AC;EGYPTIAN HIEROGLYPH Q005;Lo;0;L;;;;;N;;;;;\n132AD;EGYPTIAN HIEROGLYPH Q006;Lo;0;L;;;;;N;;;;;\n132AE;EGYPTIAN HIEROGLYPH Q007;Lo;0;L;;;;;N;;;;;\n132AF;EGYPTIAN HIEROGLYPH R001;Lo;0;L;;;;;N;;;;;\n132B0;EGYPTIAN HIEROGLYPH R002;Lo;0;L;;;;;N;;;;;\n132B1;EGYPTIAN HIEROGLYPH R002A;Lo;0;L;;;;;N;;;;;\n132B2;EGYPTIAN HIEROGLYPH R003;Lo;0;L;;;;;N;;;;;\n132B3;EGYPTIAN HIEROGLYPH R003A;Lo;0;L;;;;;N;;;;;\n132B4;EGYPTIAN HIEROGLYPH R003B;Lo;0;L;;;;;N;;;;;\n132B5;EGYPTIAN HIEROGLYPH R004;Lo;0;L;;;;;N;;;;;\n132B6;EGYPTIAN HIEROGLYPH R005;Lo;0;L;;;;;N;;;;;\n132B7;EGYPTIAN HIEROGLYPH R006;Lo;0;L;;;;;N;;;;;\n132B8;EGYPTIAN HIEROGLYPH R007;Lo;0;L;;;;;N;;;;;\n132B9;EGYPTIAN HIEROGLYPH R008;Lo;0;L;;;;;N;;;;;\n132BA;EGYPTIAN HIEROGLYPH R009;Lo;0;L;;;;;N;;;;;\n132BB;EGYPTIAN HIEROGLYPH R010;Lo;0;L;;;;;N;;;;;\n132BC;EGYPTIAN HIEROGLYPH R010A;Lo;0;L;;;;;N;;;;;\n132BD;EGYPTIAN HIEROGLYPH R011;Lo;0;L;;;;;N;;;;;\n132BE;EGYPTIAN HIEROGLYPH R012;Lo;0;L;;;;;N;;;;;\n132BF;EGYPTIAN HIEROGLYPH R013;Lo;0;L;;;;;N;;;;;\n132C0;EGYPTIAN HIEROGLYPH R014;Lo;0;L;;;;;N;;;;;\n132C1;EGYPTIAN HIEROGLYPH R015;Lo;0;L;;;;;N;;;;;\n132C2;EGYPTIAN HIEROGLYPH R016;Lo;0;L;;;;;N;;;;;\n132C3;EGYPTIAN HIEROGLYPH R016A;Lo;0;L;;;;;N;;;;;\n132C4;EGYPTIAN HIEROGLYPH R017;Lo;0;L;;;;;N;;;;;\n132C5;EGYPTIAN HIEROGLYPH R018;Lo;0;L;;;;;N;;;;;\n132C6;EGYPTIAN HIEROGLYPH R019;Lo;0;L;;;;;N;;;;;\n132C7;EGYPTIAN HIEROGLYPH R020;Lo;0;L;;;;;N;;;;;\n132C8;EGYPTIAN HIEROGLYPH R021;Lo;0;L;;;;;N;;;;;\n132C9;EGYPTIAN HIEROGLYPH R022;Lo;0;L;;;;;N;;;;;\n132CA;EGYPTIAN HIEROGLYPH R023;Lo;0;L;;;;;N;;;;;\n132CB;EGYPTIAN HIEROGLYPH R024;Lo;0;L;;;;;N;;;;;\n132CC;EGYPTIAN HIEROGLYPH R025;Lo;0;L;;;;;N;;;;;\n132CD;EGYPTIAN HIEROGLYPH R026;Lo;0;L;;;;;N;;;;;\n132CE;EGYPTIAN HIEROGLYPH R027;Lo;0;L;;;;;N;;;;;\n132CF;EGYPTIAN HIEROGLYPH R028;Lo;0;L;;;;;N;;;;;\n132D0;EGYPTIAN HIEROGLYPH R029;Lo;0;L;;;;;N;;;;;\n132D1;EGYPTIAN HIEROGLYPH S001;Lo;0;L;;;;;N;;;;;\n132D2;EGYPTIAN HIEROGLYPH S002;Lo;0;L;;;;;N;;;;;\n132D3;EGYPTIAN HIEROGLYPH S002A;Lo;0;L;;;;;N;;;;;\n132D4;EGYPTIAN HIEROGLYPH S003;Lo;0;L;;;;;N;;;;;\n132D5;EGYPTIAN HIEROGLYPH S004;Lo;0;L;;;;;N;;;;;\n132D6;EGYPTIAN HIEROGLYPH S005;Lo;0;L;;;;;N;;;;;\n132D7;EGYPTIAN HIEROGLYPH S006;Lo;0;L;;;;;N;;;;;\n132D8;EGYPTIAN HIEROGLYPH S006A;Lo;0;L;;;;;N;;;;;\n132D9;EGYPTIAN HIEROGLYPH S007;Lo;0;L;;;;;N;;;;;\n132DA;EGYPTIAN HIEROGLYPH S008;Lo;0;L;;;;;N;;;;;\n132DB;EGYPTIAN HIEROGLYPH S009;Lo;0;L;;;;;N;;;;;\n132DC;EGYPTIAN HIEROGLYPH S010;Lo;0;L;;;;;N;;;;;\n132DD;EGYPTIAN HIEROGLYPH S011;Lo;0;L;;;;;N;;;;;\n132DE;EGYPTIAN HIEROGLYPH S012;Lo;0;L;;;;;N;;;;;\n132DF;EGYPTIAN HIEROGLYPH S013;Lo;0;L;;;;;N;;;;;\n132E0;EGYPTIAN HIEROGLYPH S014;Lo;0;L;;;;;N;;;;;\n132E1;EGYPTIAN HIEROGLYPH S014A;Lo;0;L;;;;;N;;;;;\n132E2;EGYPTIAN HIEROGLYPH S014B;Lo;0;L;;;;;N;;;;;\n132E3;EGYPTIAN HIEROGLYPH S015;Lo;0;L;;;;;N;;;;;\n132E4;EGYPTIAN HIEROGLYPH S016;Lo;0;L;;;;;N;;;;;\n132E5;EGYPTIAN HIEROGLYPH S017;Lo;0;L;;;;;N;;;;;\n132E6;EGYPTIAN HIEROGLYPH S017A;Lo;0;L;;;;;N;;;;;\n132E7;EGYPTIAN HIEROGLYPH S018;Lo;0;L;;;;;N;;;;;\n132E8;EGYPTIAN HIEROGLYPH S019;Lo;0;L;;;;;N;;;;;\n132E9;EGYPTIAN HIEROGLYPH S020;Lo;0;L;;;;;N;;;;;\n132EA;EGYPTIAN HIEROGLYPH S021;Lo;0;L;;;;;N;;;;;\n132EB;EGYPTIAN HIEROGLYPH S022;Lo;0;L;;;;;N;;;;;\n132EC;EGYPTIAN HIEROGLYPH S023;Lo;0;L;;;;;N;;;;;\n132ED;EGYPTIAN HIEROGLYPH S024;Lo;0;L;;;;;N;;;;;\n132EE;EGYPTIAN HIEROGLYPH S025;Lo;0;L;;;;;N;;;;;\n132EF;EGYPTIAN HIEROGLYPH S026;Lo;0;L;;;;;N;;;;;\n132F0;EGYPTIAN HIEROGLYPH S026A;Lo;0;L;;;;;N;;;;;\n132F1;EGYPTIAN HIEROGLYPH S026B;Lo;0;L;;;;;N;;;;;\n132F2;EGYPTIAN HIEROGLYPH S027;Lo;0;L;;;;;N;;;;;\n132F3;EGYPTIAN HIEROGLYPH S028;Lo;0;L;;;;;N;;;;;\n132F4;EGYPTIAN HIEROGLYPH S029;Lo;0;L;;;;;N;;;;;\n132F5;EGYPTIAN HIEROGLYPH S030;Lo;0;L;;;;;N;;;;;\n132F6;EGYPTIAN HIEROGLYPH S031;Lo;0;L;;;;;N;;;;;\n132F7;EGYPTIAN HIEROGLYPH S032;Lo;0;L;;;;;N;;;;;\n132F8;EGYPTIAN HIEROGLYPH S033;Lo;0;L;;;;;N;;;;;\n132F9;EGYPTIAN HIEROGLYPH S034;Lo;0;L;;;;;N;;;;;\n132FA;EGYPTIAN HIEROGLYPH S035;Lo;0;L;;;;;N;;;;;\n132FB;EGYPTIAN HIEROGLYPH S035A;Lo;0;L;;;;;N;;;;;\n132FC;EGYPTIAN HIEROGLYPH S036;Lo;0;L;;;;;N;;;;;\n132FD;EGYPTIAN HIEROGLYPH S037;Lo;0;L;;;;;N;;;;;\n132FE;EGYPTIAN HIEROGLYPH S038;Lo;0;L;;;;;N;;;;;\n132FF;EGYPTIAN HIEROGLYPH S039;Lo;0;L;;;;;N;;;;;\n13300;EGYPTIAN HIEROGLYPH S040;Lo;0;L;;;;;N;;;;;\n13301;EGYPTIAN HIEROGLYPH S041;Lo;0;L;;;;;N;;;;;\n13302;EGYPTIAN HIEROGLYPH S042;Lo;0;L;;;;;N;;;;;\n13303;EGYPTIAN HIEROGLYPH S043;Lo;0;L;;;;;N;;;;;\n13304;EGYPTIAN HIEROGLYPH S044;Lo;0;L;;;;;N;;;;;\n13305;EGYPTIAN HIEROGLYPH S045;Lo;0;L;;;;;N;;;;;\n13306;EGYPTIAN HIEROGLYPH S046;Lo;0;L;;;;;N;;;;;\n13307;EGYPTIAN HIEROGLYPH T001;Lo;0;L;;;;;N;;;;;\n13308;EGYPTIAN HIEROGLYPH T002;Lo;0;L;;;;;N;;;;;\n13309;EGYPTIAN HIEROGLYPH T003;Lo;0;L;;;;;N;;;;;\n1330A;EGYPTIAN HIEROGLYPH T003A;Lo;0;L;;;;;N;;;;;\n1330B;EGYPTIAN HIEROGLYPH T004;Lo;0;L;;;;;N;;;;;\n1330C;EGYPTIAN HIEROGLYPH T005;Lo;0;L;;;;;N;;;;;\n1330D;EGYPTIAN HIEROGLYPH T006;Lo;0;L;;;;;N;;;;;\n1330E;EGYPTIAN HIEROGLYPH T007;Lo;0;L;;;;;N;;;;;\n1330F;EGYPTIAN HIEROGLYPH T007A;Lo;0;L;;;;;N;;;;;\n13310;EGYPTIAN HIEROGLYPH T008;Lo;0;L;;;;;N;;;;;\n13311;EGYPTIAN HIEROGLYPH T008A;Lo;0;L;;;;;N;;;;;\n13312;EGYPTIAN HIEROGLYPH T009;Lo;0;L;;;;;N;;;;;\n13313;EGYPTIAN HIEROGLYPH T009A;Lo;0;L;;;;;N;;;;;\n13314;EGYPTIAN HIEROGLYPH T010;Lo;0;L;;;;;N;;;;;\n13315;EGYPTIAN HIEROGLYPH T011;Lo;0;L;;;;;N;;;;;\n13316;EGYPTIAN HIEROGLYPH T011A;Lo;0;L;;;;;N;;;;;\n13317;EGYPTIAN HIEROGLYPH T012;Lo;0;L;;;;;N;;;;;\n13318;EGYPTIAN HIEROGLYPH T013;Lo;0;L;;;;;N;;;;;\n13319;EGYPTIAN HIEROGLYPH T014;Lo;0;L;;;;;N;;;;;\n1331A;EGYPTIAN HIEROGLYPH T015;Lo;0;L;;;;;N;;;;;\n1331B;EGYPTIAN HIEROGLYPH T016;Lo;0;L;;;;;N;;;;;\n1331C;EGYPTIAN HIEROGLYPH T016A;Lo;0;L;;;;;N;;;;;\n1331D;EGYPTIAN HIEROGLYPH T017;Lo;0;L;;;;;N;;;;;\n1331E;EGYPTIAN HIEROGLYPH T018;Lo;0;L;;;;;N;;;;;\n1331F;EGYPTIAN HIEROGLYPH T019;Lo;0;L;;;;;N;;;;;\n13320;EGYPTIAN HIEROGLYPH T020;Lo;0;L;;;;;N;;;;;\n13321;EGYPTIAN HIEROGLYPH T021;Lo;0;L;;;;;N;;;;;\n13322;EGYPTIAN HIEROGLYPH T022;Lo;0;L;;;;;N;;;;;\n13323;EGYPTIAN HIEROGLYPH T023;Lo;0;L;;;;;N;;;;;\n13324;EGYPTIAN HIEROGLYPH T024;Lo;0;L;;;;;N;;;;;\n13325;EGYPTIAN HIEROGLYPH T025;Lo;0;L;;;;;N;;;;;\n13326;EGYPTIAN HIEROGLYPH T026;Lo;0;L;;;;;N;;;;;\n13327;EGYPTIAN HIEROGLYPH T027;Lo;0;L;;;;;N;;;;;\n13328;EGYPTIAN HIEROGLYPH T028;Lo;0;L;;;;;N;;;;;\n13329;EGYPTIAN HIEROGLYPH T029;Lo;0;L;;;;;N;;;;;\n1332A;EGYPTIAN HIEROGLYPH T030;Lo;0;L;;;;;N;;;;;\n1332B;EGYPTIAN HIEROGLYPH T031;Lo;0;L;;;;;N;;;;;\n1332C;EGYPTIAN HIEROGLYPH T032;Lo;0;L;;;;;N;;;;;\n1332D;EGYPTIAN HIEROGLYPH T032A;Lo;0;L;;;;;N;;;;;\n1332E;EGYPTIAN HIEROGLYPH T033;Lo;0;L;;;;;N;;;;;\n1332F;EGYPTIAN HIEROGLYPH T033A;Lo;0;L;;;;;N;;;;;\n13330;EGYPTIAN HIEROGLYPH T034;Lo;0;L;;;;;N;;;;;\n13331;EGYPTIAN HIEROGLYPH T035;Lo;0;L;;;;;N;;;;;\n13332;EGYPTIAN HIEROGLYPH T036;Lo;0;L;;;;;N;;;;;\n13333;EGYPTIAN HIEROGLYPH U001;Lo;0;L;;;;;N;;;;;\n13334;EGYPTIAN HIEROGLYPH U002;Lo;0;L;;;;;N;;;;;\n13335;EGYPTIAN HIEROGLYPH U003;Lo;0;L;;;;;N;;;;;\n13336;EGYPTIAN HIEROGLYPH U004;Lo;0;L;;;;;N;;;;;\n13337;EGYPTIAN HIEROGLYPH U005;Lo;0;L;;;;;N;;;;;\n13338;EGYPTIAN HIEROGLYPH U006;Lo;0;L;;;;;N;;;;;\n13339;EGYPTIAN HIEROGLYPH U006A;Lo;0;L;;;;;N;;;;;\n1333A;EGYPTIAN HIEROGLYPH U006B;Lo;0;L;;;;;N;;;;;\n1333B;EGYPTIAN HIEROGLYPH U007;Lo;0;L;;;;;N;;;;;\n1333C;EGYPTIAN HIEROGLYPH U008;Lo;0;L;;;;;N;;;;;\n1333D;EGYPTIAN HIEROGLYPH U009;Lo;0;L;;;;;N;;;;;\n1333E;EGYPTIAN HIEROGLYPH U010;Lo;0;L;;;;;N;;;;;\n1333F;EGYPTIAN HIEROGLYPH U011;Lo;0;L;;;;;N;;;;;\n13340;EGYPTIAN HIEROGLYPH U012;Lo;0;L;;;;;N;;;;;\n13341;EGYPTIAN HIEROGLYPH U013;Lo;0;L;;;;;N;;;;;\n13342;EGYPTIAN HIEROGLYPH U014;Lo;0;L;;;;;N;;;;;\n13343;EGYPTIAN HIEROGLYPH U015;Lo;0;L;;;;;N;;;;;\n13344;EGYPTIAN HIEROGLYPH U016;Lo;0;L;;;;;N;;;;;\n13345;EGYPTIAN HIEROGLYPH U017;Lo;0;L;;;;;N;;;;;\n13346;EGYPTIAN HIEROGLYPH U018;Lo;0;L;;;;;N;;;;;\n13347;EGYPTIAN HIEROGLYPH U019;Lo;0;L;;;;;N;;;;;\n13348;EGYPTIAN HIEROGLYPH U020;Lo;0;L;;;;;N;;;;;\n13349;EGYPTIAN HIEROGLYPH U021;Lo;0;L;;;;;N;;;;;\n1334A;EGYPTIAN HIEROGLYPH U022;Lo;0;L;;;;;N;;;;;\n1334B;EGYPTIAN HIEROGLYPH U023;Lo;0;L;;;;;N;;;;;\n1334C;EGYPTIAN HIEROGLYPH U023A;Lo;0;L;;;;;N;;;;;\n1334D;EGYPTIAN HIEROGLYPH U024;Lo;0;L;;;;;N;;;;;\n1334E;EGYPTIAN HIEROGLYPH U025;Lo;0;L;;;;;N;;;;;\n1334F;EGYPTIAN HIEROGLYPH U026;Lo;0;L;;;;;N;;;;;\n13350;EGYPTIAN HIEROGLYPH U027;Lo;0;L;;;;;N;;;;;\n13351;EGYPTIAN HIEROGLYPH U028;Lo;0;L;;;;;N;;;;;\n13352;EGYPTIAN HIEROGLYPH U029;Lo;0;L;;;;;N;;;;;\n13353;EGYPTIAN HIEROGLYPH U029A;Lo;0;L;;;;;N;;;;;\n13354;EGYPTIAN HIEROGLYPH U030;Lo;0;L;;;;;N;;;;;\n13355;EGYPTIAN HIEROGLYPH U031;Lo;0;L;;;;;N;;;;;\n13356;EGYPTIAN HIEROGLYPH U032;Lo;0;L;;;;;N;;;;;\n13357;EGYPTIAN HIEROGLYPH U032A;Lo;0;L;;;;;N;;;;;\n13358;EGYPTIAN HIEROGLYPH U033;Lo;0;L;;;;;N;;;;;\n13359;EGYPTIAN HIEROGLYPH U034;Lo;0;L;;;;;N;;;;;\n1335A;EGYPTIAN HIEROGLYPH U035;Lo;0;L;;;;;N;;;;;\n1335B;EGYPTIAN HIEROGLYPH U036;Lo;0;L;;;;;N;;;;;\n1335C;EGYPTIAN HIEROGLYPH U037;Lo;0;L;;;;;N;;;;;\n1335D;EGYPTIAN HIEROGLYPH U038;Lo;0;L;;;;;N;;;;;\n1335E;EGYPTIAN HIEROGLYPH U039;Lo;0;L;;;;;N;;;;;\n1335F;EGYPTIAN HIEROGLYPH U040;Lo;0;L;;;;;N;;;;;\n13360;EGYPTIAN HIEROGLYPH U041;Lo;0;L;;;;;N;;;;;\n13361;EGYPTIAN HIEROGLYPH U042;Lo;0;L;;;;;N;;;;;\n13362;EGYPTIAN HIEROGLYPH V001;Lo;0;L;;;;;N;;;;;\n13363;EGYPTIAN HIEROGLYPH V001A;Lo;0;L;;;;;N;;;;;\n13364;EGYPTIAN HIEROGLYPH V001B;Lo;0;L;;;;;N;;;;;\n13365;EGYPTIAN HIEROGLYPH V001C;Lo;0;L;;;;;N;;;;;\n13366;EGYPTIAN HIEROGLYPH V001D;Lo;0;L;;;;;N;;;;;\n13367;EGYPTIAN HIEROGLYPH V001E;Lo;0;L;;;;;N;;;;;\n13368;EGYPTIAN HIEROGLYPH V001F;Lo;0;L;;;;;N;;;;;\n13369;EGYPTIAN HIEROGLYPH V001G;Lo;0;L;;;;;N;;;;;\n1336A;EGYPTIAN HIEROGLYPH V001H;Lo;0;L;;;;;N;;;;;\n1336B;EGYPTIAN HIEROGLYPH V001I;Lo;0;L;;;;;N;;;;;\n1336C;EGYPTIAN HIEROGLYPH V002;Lo;0;L;;;;;N;;;;;\n1336D;EGYPTIAN HIEROGLYPH V002A;Lo;0;L;;;;;N;;;;;\n1336E;EGYPTIAN HIEROGLYPH V003;Lo;0;L;;;;;N;;;;;\n1336F;EGYPTIAN HIEROGLYPH V004;Lo;0;L;;;;;N;;;;;\n13370;EGYPTIAN HIEROGLYPH V005;Lo;0;L;;;;;N;;;;;\n13371;EGYPTIAN HIEROGLYPH V006;Lo;0;L;;;;;N;;;;;\n13372;EGYPTIAN HIEROGLYPH V007;Lo;0;L;;;;;N;;;;;\n13373;EGYPTIAN HIEROGLYPH V007A;Lo;0;L;;;;;N;;;;;\n13374;EGYPTIAN HIEROGLYPH V007B;Lo;0;L;;;;;N;;;;;\n13375;EGYPTIAN HIEROGLYPH V008;Lo;0;L;;;;;N;;;;;\n13376;EGYPTIAN HIEROGLYPH V009;Lo;0;L;;;;;N;;;;;\n13377;EGYPTIAN HIEROGLYPH V010;Lo;0;L;;;;;N;;;;;\n13378;EGYPTIAN HIEROGLYPH V011;Lo;0;L;;;;;N;;;;;\n13379;EGYPTIAN HIEROGLYPH V011A;Lo;0;L;;;;;N;;;;;\n1337A;EGYPTIAN HIEROGLYPH V011B;Lo;0;L;;;;;N;;;;;\n1337B;EGYPTIAN HIEROGLYPH V011C;Lo;0;L;;;;;N;;;;;\n1337C;EGYPTIAN HIEROGLYPH V012;Lo;0;L;;;;;N;;;;;\n1337D;EGYPTIAN HIEROGLYPH V012A;Lo;0;L;;;;;N;;;;;\n1337E;EGYPTIAN HIEROGLYPH V012B;Lo;0;L;;;;;N;;;;;\n1337F;EGYPTIAN HIEROGLYPH V013;Lo;0;L;;;;;N;;;;;\n13380;EGYPTIAN HIEROGLYPH V014;Lo;0;L;;;;;N;;;;;\n13381;EGYPTIAN HIEROGLYPH V015;Lo;0;L;;;;;N;;;;;\n13382;EGYPTIAN HIEROGLYPH V016;Lo;0;L;;;;;N;;;;;\n13383;EGYPTIAN HIEROGLYPH V017;Lo;0;L;;;;;N;;;;;\n13384;EGYPTIAN HIEROGLYPH V018;Lo;0;L;;;;;N;;;;;\n13385;EGYPTIAN HIEROGLYPH V019;Lo;0;L;;;;;N;;;;;\n13386;EGYPTIAN HIEROGLYPH V020;Lo;0;L;;;;;N;;;;;\n13387;EGYPTIAN HIEROGLYPH V020A;Lo;0;L;;;;;N;;;;;\n13388;EGYPTIAN HIEROGLYPH V020B;Lo;0;L;;;;;N;;;;;\n13389;EGYPTIAN HIEROGLYPH V020C;Lo;0;L;;;;;N;;;;;\n1338A;EGYPTIAN HIEROGLYPH V020D;Lo;0;L;;;;;N;;;;;\n1338B;EGYPTIAN HIEROGLYPH V020E;Lo;0;L;;;;;N;;;;;\n1338C;EGYPTIAN HIEROGLYPH V020F;Lo;0;L;;;;;N;;;;;\n1338D;EGYPTIAN HIEROGLYPH V020G;Lo;0;L;;;;;N;;;;;\n1338E;EGYPTIAN HIEROGLYPH V020H;Lo;0;L;;;;;N;;;;;\n1338F;EGYPTIAN HIEROGLYPH V020I;Lo;0;L;;;;;N;;;;;\n13390;EGYPTIAN HIEROGLYPH V020J;Lo;0;L;;;;;N;;;;;\n13391;EGYPTIAN HIEROGLYPH V020K;Lo;0;L;;;;;N;;;;;\n13392;EGYPTIAN HIEROGLYPH V020L;Lo;0;L;;;;;N;;;;;\n13393;EGYPTIAN HIEROGLYPH V021;Lo;0;L;;;;;N;;;;;\n13394;EGYPTIAN HIEROGLYPH V022;Lo;0;L;;;;;N;;;;;\n13395;EGYPTIAN HIEROGLYPH V023;Lo;0;L;;;;;N;;;;;\n13396;EGYPTIAN HIEROGLYPH V023A;Lo;0;L;;;;;N;;;;;\n13397;EGYPTIAN HIEROGLYPH V024;Lo;0;L;;;;;N;;;;;\n13398;EGYPTIAN HIEROGLYPH V025;Lo;0;L;;;;;N;;;;;\n13399;EGYPTIAN HIEROGLYPH V026;Lo;0;L;;;;;N;;;;;\n1339A;EGYPTIAN HIEROGLYPH V027;Lo;0;L;;;;;N;;;;;\n1339B;EGYPTIAN HIEROGLYPH V028;Lo;0;L;;;;;N;;;;;\n1339C;EGYPTIAN HIEROGLYPH V028A;Lo;0;L;;;;;N;;;;;\n1339D;EGYPTIAN HIEROGLYPH V029;Lo;0;L;;;;;N;;;;;\n1339E;EGYPTIAN HIEROGLYPH V029A;Lo;0;L;;;;;N;;;;;\n1339F;EGYPTIAN HIEROGLYPH V030;Lo;0;L;;;;;N;;;;;\n133A0;EGYPTIAN HIEROGLYPH V030A;Lo;0;L;;;;;N;;;;;\n133A1;EGYPTIAN HIEROGLYPH V031;Lo;0;L;;;;;N;;;;;\n133A2;EGYPTIAN HIEROGLYPH V031A;Lo;0;L;;;;;N;;;;;\n133A3;EGYPTIAN HIEROGLYPH V032;Lo;0;L;;;;;N;;;;;\n133A4;EGYPTIAN HIEROGLYPH V033;Lo;0;L;;;;;N;;;;;\n133A5;EGYPTIAN HIEROGLYPH V033A;Lo;0;L;;;;;N;;;;;\n133A6;EGYPTIAN HIEROGLYPH V034;Lo;0;L;;;;;N;;;;;\n133A7;EGYPTIAN HIEROGLYPH V035;Lo;0;L;;;;;N;;;;;\n133A8;EGYPTIAN HIEROGLYPH V036;Lo;0;L;;;;;N;;;;;\n133A9;EGYPTIAN HIEROGLYPH V037;Lo;0;L;;;;;N;;;;;\n133AA;EGYPTIAN HIEROGLYPH V037A;Lo;0;L;;;;;N;;;;;\n133AB;EGYPTIAN HIEROGLYPH V038;Lo;0;L;;;;;N;;;;;\n133AC;EGYPTIAN HIEROGLYPH V039;Lo;0;L;;;;;N;;;;;\n133AD;EGYPTIAN HIEROGLYPH V040;Lo;0;L;;;;;N;;;;;\n133AE;EGYPTIAN HIEROGLYPH V040A;Lo;0;L;;;;;N;;;;;\n133AF;EGYPTIAN HIEROGLYPH W001;Lo;0;L;;;;;N;;;;;\n133B0;EGYPTIAN HIEROGLYPH W002;Lo;0;L;;;;;N;;;;;\n133B1;EGYPTIAN HIEROGLYPH W003;Lo;0;L;;;;;N;;;;;\n133B2;EGYPTIAN HIEROGLYPH W003A;Lo;0;L;;;;;N;;;;;\n133B3;EGYPTIAN HIEROGLYPH W004;Lo;0;L;;;;;N;;;;;\n133B4;EGYPTIAN HIEROGLYPH W005;Lo;0;L;;;;;N;;;;;\n133B5;EGYPTIAN HIEROGLYPH W006;Lo;0;L;;;;;N;;;;;\n133B6;EGYPTIAN HIEROGLYPH W007;Lo;0;L;;;;;N;;;;;\n133B7;EGYPTIAN HIEROGLYPH W008;Lo;0;L;;;;;N;;;;;\n133B8;EGYPTIAN HIEROGLYPH W009;Lo;0;L;;;;;N;;;;;\n133B9;EGYPTIAN HIEROGLYPH W009A;Lo;0;L;;;;;N;;;;;\n133BA;EGYPTIAN HIEROGLYPH W010;Lo;0;L;;;;;N;;;;;\n133BB;EGYPTIAN HIEROGLYPH W010A;Lo;0;L;;;;;N;;;;;\n133BC;EGYPTIAN HIEROGLYPH W011;Lo;0;L;;;;;N;;;;;\n133BD;EGYPTIAN HIEROGLYPH W012;Lo;0;L;;;;;N;;;;;\n133BE;EGYPTIAN HIEROGLYPH W013;Lo;0;L;;;;;N;;;;;\n133BF;EGYPTIAN HIEROGLYPH W014;Lo;0;L;;;;;N;;;;;\n133C0;EGYPTIAN HIEROGLYPH W014A;Lo;0;L;;;;;N;;;;;\n133C1;EGYPTIAN HIEROGLYPH W015;Lo;0;L;;;;;N;;;;;\n133C2;EGYPTIAN HIEROGLYPH W016;Lo;0;L;;;;;N;;;;;\n133C3;EGYPTIAN HIEROGLYPH W017;Lo;0;L;;;;;N;;;;;\n133C4;EGYPTIAN HIEROGLYPH W017A;Lo;0;L;;;;;N;;;;;\n133C5;EGYPTIAN HIEROGLYPH W018;Lo;0;L;;;;;N;;;;;\n133C6;EGYPTIAN HIEROGLYPH W018A;Lo;0;L;;;;;N;;;;;\n133C7;EGYPTIAN HIEROGLYPH W019;Lo;0;L;;;;;N;;;;;\n133C8;EGYPTIAN HIEROGLYPH W020;Lo;0;L;;;;;N;;;;;\n133C9;EGYPTIAN HIEROGLYPH W021;Lo;0;L;;;;;N;;;;;\n133CA;EGYPTIAN HIEROGLYPH W022;Lo;0;L;;;;;N;;;;;\n133CB;EGYPTIAN HIEROGLYPH W023;Lo;0;L;;;;;N;;;;;\n133CC;EGYPTIAN HIEROGLYPH W024;Lo;0;L;;;;;N;;;;;\n133CD;EGYPTIAN HIEROGLYPH W024A;Lo;0;L;;;;;N;;;;;\n133CE;EGYPTIAN HIEROGLYPH W025;Lo;0;L;;;;;N;;;;;\n133CF;EGYPTIAN HIEROGLYPH X001;Lo;0;L;;;;;N;;;;;\n133D0;EGYPTIAN HIEROGLYPH X002;Lo;0;L;;;;;N;;;;;\n133D1;EGYPTIAN HIEROGLYPH X003;Lo;0;L;;;;;N;;;;;\n133D2;EGYPTIAN HIEROGLYPH X004;Lo;0;L;;;;;N;;;;;\n133D3;EGYPTIAN HIEROGLYPH X004A;Lo;0;L;;;;;N;;;;;\n133D4;EGYPTIAN HIEROGLYPH X004B;Lo;0;L;;;;;N;;;;;\n133D5;EGYPTIAN HIEROGLYPH X005;Lo;0;L;;;;;N;;;;;\n133D6;EGYPTIAN HIEROGLYPH X006;Lo;0;L;;;;;N;;;;;\n133D7;EGYPTIAN HIEROGLYPH X006A;Lo;0;L;;;;;N;;;;;\n133D8;EGYPTIAN HIEROGLYPH X007;Lo;0;L;;;;;N;;;;;\n133D9;EGYPTIAN HIEROGLYPH X008;Lo;0;L;;;;;N;;;;;\n133DA;EGYPTIAN HIEROGLYPH X008A;Lo;0;L;;;;;N;;;;;\n133DB;EGYPTIAN HIEROGLYPH Y001;Lo;0;L;;;;;N;;;;;\n133DC;EGYPTIAN HIEROGLYPH Y001A;Lo;0;L;;;;;N;;;;;\n133DD;EGYPTIAN HIEROGLYPH Y002;Lo;0;L;;;;;N;;;;;\n133DE;EGYPTIAN HIEROGLYPH Y003;Lo;0;L;;;;;N;;;;;\n133DF;EGYPTIAN HIEROGLYPH Y004;Lo;0;L;;;;;N;;;;;\n133E0;EGYPTIAN HIEROGLYPH Y005;Lo;0;L;;;;;N;;;;;\n133E1;EGYPTIAN HIEROGLYPH Y006;Lo;0;L;;;;;N;;;;;\n133E2;EGYPTIAN HIEROGLYPH Y007;Lo;0;L;;;;;N;;;;;\n133E3;EGYPTIAN HIEROGLYPH Y008;Lo;0;L;;;;;N;;;;;\n133E4;EGYPTIAN HIEROGLYPH Z001;Lo;0;L;;;;;N;;;;;\n133E5;EGYPTIAN HIEROGLYPH Z002;Lo;0;L;;;;;N;;;;;\n133E6;EGYPTIAN HIEROGLYPH Z002A;Lo;0;L;;;;;N;;;;;\n133E7;EGYPTIAN HIEROGLYPH Z002B;Lo;0;L;;;;;N;;;;;\n133E8;EGYPTIAN HIEROGLYPH Z002C;Lo;0;L;;;;;N;;;;;\n133E9;EGYPTIAN HIEROGLYPH Z002D;Lo;0;L;;;;;N;;;;;\n133EA;EGYPTIAN HIEROGLYPH Z003;Lo;0;L;;;;;N;;;;;\n133EB;EGYPTIAN HIEROGLYPH Z003A;Lo;0;L;;;;;N;;;;;\n133EC;EGYPTIAN HIEROGLYPH Z003B;Lo;0;L;;;;;N;;;;;\n133ED;EGYPTIAN HIEROGLYPH Z004;Lo;0;L;;;;;N;;;;;\n133EE;EGYPTIAN HIEROGLYPH Z004A;Lo;0;L;;;;;N;;;;;\n133EF;EGYPTIAN HIEROGLYPH Z005;Lo;0;L;;;;;N;;;;;\n133F0;EGYPTIAN HIEROGLYPH Z005A;Lo;0;L;;;;;N;;;;;\n133F1;EGYPTIAN HIEROGLYPH Z006;Lo;0;L;;;;;N;;;;;\n133F2;EGYPTIAN HIEROGLYPH Z007;Lo;0;L;;;;;N;;;;;\n133F3;EGYPTIAN HIEROGLYPH Z008;Lo;0;L;;;;;N;;;;;\n133F4;EGYPTIAN HIEROGLYPH Z009;Lo;0;L;;;;;N;;;;;\n133F5;EGYPTIAN HIEROGLYPH Z010;Lo;0;L;;;;;N;;;;;\n133F6;EGYPTIAN HIEROGLYPH Z011;Lo;0;L;;;;;N;;;;;\n133F7;EGYPTIAN HIEROGLYPH Z012;Lo;0;L;;;;;N;;;;;\n133F8;EGYPTIAN HIEROGLYPH Z013;Lo;0;L;;;;;N;;;;;\n133F9;EGYPTIAN HIEROGLYPH Z014;Lo;0;L;;;;;N;;;;;\n133FA;EGYPTIAN HIEROGLYPH Z015;Lo;0;L;;;;;N;;;;;\n133FB;EGYPTIAN HIEROGLYPH Z015A;Lo;0;L;;;;;N;;;;;\n133FC;EGYPTIAN HIEROGLYPH Z015B;Lo;0;L;;;;;N;;;;;\n133FD;EGYPTIAN HIEROGLYPH Z015C;Lo;0;L;;;;;N;;;;;\n133FE;EGYPTIAN HIEROGLYPH Z015D;Lo;0;L;;;;;N;;;;;\n133FF;EGYPTIAN HIEROGLYPH Z015E;Lo;0;L;;;;;N;;;;;\n13400;EGYPTIAN HIEROGLYPH Z015F;Lo;0;L;;;;;N;;;;;\n13401;EGYPTIAN HIEROGLYPH Z015G;Lo;0;L;;;;;N;;;;;\n13402;EGYPTIAN HIEROGLYPH Z015H;Lo;0;L;;;;;N;;;;;\n13403;EGYPTIAN HIEROGLYPH Z015I;Lo;0;L;;;;;N;;;;;\n13404;EGYPTIAN HIEROGLYPH Z016;Lo;0;L;;;;;N;;;;;\n13405;EGYPTIAN HIEROGLYPH Z016A;Lo;0;L;;;;;N;;;;;\n13406;EGYPTIAN HIEROGLYPH Z016B;Lo;0;L;;;;;N;;;;;\n13407;EGYPTIAN HIEROGLYPH Z016C;Lo;0;L;;;;;N;;;;;\n13408;EGYPTIAN HIEROGLYPH Z016D;Lo;0;L;;;;;N;;;;;\n13409;EGYPTIAN HIEROGLYPH Z016E;Lo;0;L;;;;;N;;;;;\n1340A;EGYPTIAN HIEROGLYPH Z016F;Lo;0;L;;;;;N;;;;;\n1340B;EGYPTIAN HIEROGLYPH Z016G;Lo;0;L;;;;;N;;;;;\n1340C;EGYPTIAN HIEROGLYPH Z016H;Lo;0;L;;;;;N;;;;;\n1340D;EGYPTIAN HIEROGLYPH AA001;Lo;0;L;;;;;N;;;;;\n1340E;EGYPTIAN HIEROGLYPH AA002;Lo;0;L;;;;;N;;;;;\n1340F;EGYPTIAN HIEROGLYPH AA003;Lo;0;L;;;;;N;;;;;\n13410;EGYPTIAN HIEROGLYPH AA004;Lo;0;L;;;;;N;;;;;\n13411;EGYPTIAN HIEROGLYPH AA005;Lo;0;L;;;;;N;;;;;\n13412;EGYPTIAN HIEROGLYPH AA006;Lo;0;L;;;;;N;;;;;\n13413;EGYPTIAN HIEROGLYPH AA007;Lo;0;L;;;;;N;;;;;\n13414;EGYPTIAN HIEROGLYPH AA007A;Lo;0;L;;;;;N;;;;;\n13415;EGYPTIAN HIEROGLYPH AA007B;Lo;0;L;;;;;N;;;;;\n13416;EGYPTIAN HIEROGLYPH AA008;Lo;0;L;;;;;N;;;;;\n13417;EGYPTIAN HIEROGLYPH AA009;Lo;0;L;;;;;N;;;;;\n13418;EGYPTIAN HIEROGLYPH AA010;Lo;0;L;;;;;N;;;;;\n13419;EGYPTIAN HIEROGLYPH AA011;Lo;0;L;;;;;N;;;;;\n1341A;EGYPTIAN HIEROGLYPH AA012;Lo;0;L;;;;;N;;;;;\n1341B;EGYPTIAN HIEROGLYPH AA013;Lo;0;L;;;;;N;;;;;\n1341C;EGYPTIAN HIEROGLYPH AA014;Lo;0;L;;;;;N;;;;;\n1341D;EGYPTIAN HIEROGLYPH AA015;Lo;0;L;;;;;N;;;;;\n1341E;EGYPTIAN HIEROGLYPH AA016;Lo;0;L;;;;;N;;;;;\n1341F;EGYPTIAN HIEROGLYPH AA017;Lo;0;L;;;;;N;;;;;\n13420;EGYPTIAN HIEROGLYPH AA018;Lo;0;L;;;;;N;;;;;\n13421;EGYPTIAN HIEROGLYPH AA019;Lo;0;L;;;;;N;;;;;\n13422;EGYPTIAN HIEROGLYPH AA020;Lo;0;L;;;;;N;;;;;\n13423;EGYPTIAN HIEROGLYPH AA021;Lo;0;L;;;;;N;;;;;\n13424;EGYPTIAN HIEROGLYPH AA022;Lo;0;L;;;;;N;;;;;\n13425;EGYPTIAN HIEROGLYPH AA023;Lo;0;L;;;;;N;;;;;\n13426;EGYPTIAN HIEROGLYPH AA024;Lo;0;L;;;;;N;;;;;\n13427;EGYPTIAN HIEROGLYPH AA025;Lo;0;L;;;;;N;;;;;\n13428;EGYPTIAN HIEROGLYPH AA026;Lo;0;L;;;;;N;;;;;\n13429;EGYPTIAN HIEROGLYPH AA027;Lo;0;L;;;;;N;;;;;\n1342A;EGYPTIAN HIEROGLYPH AA028;Lo;0;L;;;;;N;;;;;\n1342B;EGYPTIAN HIEROGLYPH AA029;Lo;0;L;;;;;N;;;;;\n1342C;EGYPTIAN HIEROGLYPH AA030;Lo;0;L;;;;;N;;;;;\n1342D;EGYPTIAN HIEROGLYPH AA031;Lo;0;L;;;;;N;;;;;\n1342E;EGYPTIAN HIEROGLYPH AA032;Lo;0;L;;;;;N;;;;;\n13430;EGYPTIAN HIEROGLYPH VERTICAL JOINER;Cf;0;L;;;;;N;;;;;\n13431;EGYPTIAN HIEROGLYPH HORIZONTAL JOINER;Cf;0;L;;;;;N;;;;;\n13432;EGYPTIAN HIEROGLYPH INSERT AT TOP START;Cf;0;L;;;;;N;;;;;\n13433;EGYPTIAN HIEROGLYPH INSERT AT BOTTOM START;Cf;0;L;;;;;N;;;;;\n13434;EGYPTIAN HIEROGLYPH INSERT AT TOP END;Cf;0;L;;;;;N;;;;;\n13435;EGYPTIAN HIEROGLYPH INSERT AT BOTTOM END;Cf;0;L;;;;;N;;;;;\n13436;EGYPTIAN HIEROGLYPH OVERLAY MIDDLE;Cf;0;L;;;;;N;;;;;\n13437;EGYPTIAN HIEROGLYPH BEGIN SEGMENT;Cf;0;L;;;;;N;;;;;\n13438;EGYPTIAN HIEROGLYPH END SEGMENT;Cf;0;L;;;;;N;;;;;\n14400;ANATOLIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;;\n14401;ANATOLIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;;\n14402;ANATOLIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;;\n14403;ANATOLIAN HIEROGLYPH A004;Lo;0;L;;;;;N;;;;;\n14404;ANATOLIAN HIEROGLYPH A005;Lo;0;L;;;;;N;;;;;\n14405;ANATOLIAN HIEROGLYPH A006;Lo;0;L;;;;;N;;;;;\n14406;ANATOLIAN HIEROGLYPH A007;Lo;0;L;;;;;N;;;;;\n14407;ANATOLIAN HIEROGLYPH A008;Lo;0;L;;;;;N;;;;;\n14408;ANATOLIAN HIEROGLYPH A009;Lo;0;L;;;;;N;;;;;\n14409;ANATOLIAN HIEROGLYPH A010;Lo;0;L;;;;;N;;;;;\n1440A;ANATOLIAN HIEROGLYPH A010A;Lo;0;L;;;;;N;;;;;\n1440B;ANATOLIAN HIEROGLYPH A011;Lo;0;L;;;;;N;;;;;\n1440C;ANATOLIAN HIEROGLYPH A012;Lo;0;L;;;;;N;;;;;\n1440D;ANATOLIAN HIEROGLYPH A013;Lo;0;L;;;;;N;;;;;\n1440E;ANATOLIAN HIEROGLYPH A014;Lo;0;L;;;;;N;;;;;\n1440F;ANATOLIAN HIEROGLYPH A015;Lo;0;L;;;;;N;;;;;\n14410;ANATOLIAN HIEROGLYPH A016;Lo;0;L;;;;;N;;;;;\n14411;ANATOLIAN HIEROGLYPH A017;Lo;0;L;;;;;N;;;;;\n14412;ANATOLIAN HIEROGLYPH A018;Lo;0;L;;;;;N;;;;;\n14413;ANATOLIAN HIEROGLYPH A019;Lo;0;L;;;;;N;;;;;\n14414;ANATOLIAN HIEROGLYPH A020;Lo;0;L;;;;;N;;;;;\n14415;ANATOLIAN HIEROGLYPH A021;Lo;0;L;;;;;N;;;;;\n14416;ANATOLIAN HIEROGLYPH A022;Lo;0;L;;;;;N;;;;;\n14417;ANATOLIAN HIEROGLYPH A023;Lo;0;L;;;;;N;;;;;\n14418;ANATOLIAN HIEROGLYPH A024;Lo;0;L;;;;;N;;;;;\n14419;ANATOLIAN HIEROGLYPH A025;Lo;0;L;;;;;N;;;;;\n1441A;ANATOLIAN HIEROGLYPH A026;Lo;0;L;;;;;N;;;;;\n1441B;ANATOLIAN HIEROGLYPH A026A;Lo;0;L;;;;;N;;;;;\n1441C;ANATOLIAN HIEROGLYPH A027;Lo;0;L;;;;;N;;;;;\n1441D;ANATOLIAN HIEROGLYPH A028;Lo;0;L;;;;;N;;;;;\n1441E;ANATOLIAN HIEROGLYPH A029;Lo;0;L;;;;;N;;;;;\n1441F;ANATOLIAN HIEROGLYPH A030;Lo;0;L;;;;;N;;;;;\n14420;ANATOLIAN HIEROGLYPH A031;Lo;0;L;;;;;N;;;;;\n14421;ANATOLIAN HIEROGLYPH A032;Lo;0;L;;;;;N;;;;;\n14422;ANATOLIAN HIEROGLYPH A033;Lo;0;L;;;;;N;;;;;\n14423;ANATOLIAN HIEROGLYPH A034;Lo;0;L;;;;;N;;;;;\n14424;ANATOLIAN HIEROGLYPH A035;Lo;0;L;;;;;N;;;;;\n14425;ANATOLIAN HIEROGLYPH A036;Lo;0;L;;;;;N;;;;;\n14426;ANATOLIAN HIEROGLYPH A037;Lo;0;L;;;;;N;;;;;\n14427;ANATOLIAN HIEROGLYPH A038;Lo;0;L;;;;;N;;;;;\n14428;ANATOLIAN HIEROGLYPH A039;Lo;0;L;;;;;N;;;;;\n14429;ANATOLIAN HIEROGLYPH A039A;Lo;0;L;;;;;N;;;;;\n1442A;ANATOLIAN HIEROGLYPH A040;Lo;0;L;;;;;N;;;;;\n1442B;ANATOLIAN HIEROGLYPH A041;Lo;0;L;;;;;N;;;;;\n1442C;ANATOLIAN HIEROGLYPH A041A;Lo;0;L;;;;;N;;;;;\n1442D;ANATOLIAN HIEROGLYPH A042;Lo;0;L;;;;;N;;;;;\n1442E;ANATOLIAN HIEROGLYPH A043;Lo;0;L;;;;;N;;;;;\n1442F;ANATOLIAN HIEROGLYPH A044;Lo;0;L;;;;;N;;;;;\n14430;ANATOLIAN HIEROGLYPH A045;Lo;0;L;;;;;N;;;;;\n14431;ANATOLIAN HIEROGLYPH A045A;Lo;0;L;;;;;N;;;;;\n14432;ANATOLIAN HIEROGLYPH A046;Lo;0;L;;;;;N;;;;;\n14433;ANATOLIAN HIEROGLYPH A046A;Lo;0;L;;;;;N;;;;;\n14434;ANATOLIAN HIEROGLYPH A046B;Lo;0;L;;;;;N;;;;;\n14435;ANATOLIAN HIEROGLYPH A047;Lo;0;L;;;;;N;;;;;\n14436;ANATOLIAN HIEROGLYPH A048;Lo;0;L;;;;;N;;;;;\n14437;ANATOLIAN HIEROGLYPH A049;Lo;0;L;;;;;N;;;;;\n14438;ANATOLIAN HIEROGLYPH A050;Lo;0;L;;;;;N;;;;;\n14439;ANATOLIAN HIEROGLYPH A051;Lo;0;L;;;;;N;;;;;\n1443A;ANATOLIAN HIEROGLYPH A052;Lo;0;L;;;;;N;;;;;\n1443B;ANATOLIAN HIEROGLYPH A053;Lo;0;L;;;;;N;;;;;\n1443C;ANATOLIAN HIEROGLYPH A054;Lo;0;L;;;;;N;;;;;\n1443D;ANATOLIAN HIEROGLYPH A055;Lo;0;L;;;;;N;;;;;\n1443E;ANATOLIAN HIEROGLYPH A056;Lo;0;L;;;;;N;;;;;\n1443F;ANATOLIAN HIEROGLYPH A057;Lo;0;L;;;;;N;;;;;\n14440;ANATOLIAN HIEROGLYPH A058;Lo;0;L;;;;;N;;;;;\n14441;ANATOLIAN HIEROGLYPH A059;Lo;0;L;;;;;N;;;;;\n14442;ANATOLIAN HIEROGLYPH A060;Lo;0;L;;;;;N;;;;;\n14443;ANATOLIAN HIEROGLYPH A061;Lo;0;L;;;;;N;;;;;\n14444;ANATOLIAN HIEROGLYPH A062;Lo;0;L;;;;;N;;;;;\n14445;ANATOLIAN HIEROGLYPH A063;Lo;0;L;;;;;N;;;;;\n14446;ANATOLIAN HIEROGLYPH A064;Lo;0;L;;;;;N;;;;;\n14447;ANATOLIAN HIEROGLYPH A065;Lo;0;L;;;;;N;;;;;\n14448;ANATOLIAN HIEROGLYPH A066;Lo;0;L;;;;;N;;;;;\n14449;ANATOLIAN HIEROGLYPH A066A;Lo;0;L;;;;;N;;;;;\n1444A;ANATOLIAN HIEROGLYPH A066B;Lo;0;L;;;;;N;;;;;\n1444B;ANATOLIAN HIEROGLYPH A066C;Lo;0;L;;;;;N;;;;;\n1444C;ANATOLIAN HIEROGLYPH A067;Lo;0;L;;;;;N;;;;;\n1444D;ANATOLIAN HIEROGLYPH A068;Lo;0;L;;;;;N;;;;;\n1444E;ANATOLIAN HIEROGLYPH A069;Lo;0;L;;;;;N;;;;;\n1444F;ANATOLIAN HIEROGLYPH A070;Lo;0;L;;;;;N;;;;;\n14450;ANATOLIAN HIEROGLYPH A071;Lo;0;L;;;;;N;;;;;\n14451;ANATOLIAN HIEROGLYPH A072;Lo;0;L;;;;;N;;;;;\n14452;ANATOLIAN HIEROGLYPH A073;Lo;0;L;;;;;N;;;;;\n14453;ANATOLIAN HIEROGLYPH A074;Lo;0;L;;;;;N;;;;;\n14454;ANATOLIAN HIEROGLYPH A075;Lo;0;L;;;;;N;;;;;\n14455;ANATOLIAN HIEROGLYPH A076;Lo;0;L;;;;;N;;;;;\n14456;ANATOLIAN HIEROGLYPH A077;Lo;0;L;;;;;N;;;;;\n14457;ANATOLIAN HIEROGLYPH A078;Lo;0;L;;;;;N;;;;;\n14458;ANATOLIAN HIEROGLYPH A079;Lo;0;L;;;;;N;;;;;\n14459;ANATOLIAN HIEROGLYPH A080;Lo;0;L;;;;;N;;;;;\n1445A;ANATOLIAN HIEROGLYPH A081;Lo;0;L;;;;;N;;;;;\n1445B;ANATOLIAN HIEROGLYPH A082;Lo;0;L;;;;;N;;;;;\n1445C;ANATOLIAN HIEROGLYPH A083;Lo;0;L;;;;;N;;;;;\n1445D;ANATOLIAN HIEROGLYPH A084;Lo;0;L;;;;;N;;;;;\n1445E;ANATOLIAN HIEROGLYPH A085;Lo;0;L;;;;;N;;;;;\n1445F;ANATOLIAN HIEROGLYPH A086;Lo;0;L;;;;;N;;;;;\n14460;ANATOLIAN HIEROGLYPH A087;Lo;0;L;;;;;N;;;;;\n14461;ANATOLIAN HIEROGLYPH A088;Lo;0;L;;;;;N;;;;;\n14462;ANATOLIAN HIEROGLYPH A089;Lo;0;L;;;;;N;;;;;\n14463;ANATOLIAN HIEROGLYPH A090;Lo;0;L;;;;;N;;;;;\n14464;ANATOLIAN HIEROGLYPH A091;Lo;0;L;;;;;N;;;;;\n14465;ANATOLIAN HIEROGLYPH A092;Lo;0;L;;;;;N;;;;;\n14466;ANATOLIAN HIEROGLYPH A093;Lo;0;L;;;;;N;;;;;\n14467;ANATOLIAN HIEROGLYPH A094;Lo;0;L;;;;;N;;;;;\n14468;ANATOLIAN HIEROGLYPH A095;Lo;0;L;;;;;N;;;;;\n14469;ANATOLIAN HIEROGLYPH A096;Lo;0;L;;;;;N;;;;;\n1446A;ANATOLIAN HIEROGLYPH A097;Lo;0;L;;;;;N;;;;;\n1446B;ANATOLIAN HIEROGLYPH A097A;Lo;0;L;;;;;N;;;;;\n1446C;ANATOLIAN HIEROGLYPH A098;Lo;0;L;;;;;N;;;;;\n1446D;ANATOLIAN HIEROGLYPH A098A;Lo;0;L;;;;;N;;;;;\n1446E;ANATOLIAN HIEROGLYPH A099;Lo;0;L;;;;;N;;;;;\n1446F;ANATOLIAN HIEROGLYPH A100;Lo;0;L;;;;;N;;;;;\n14470;ANATOLIAN HIEROGLYPH A100A;Lo;0;L;;;;;N;;;;;\n14471;ANATOLIAN HIEROGLYPH A101;Lo;0;L;;;;;N;;;;;\n14472;ANATOLIAN HIEROGLYPH A101A;Lo;0;L;;;;;N;;;;;\n14473;ANATOLIAN HIEROGLYPH A102;Lo;0;L;;;;;N;;;;;\n14474;ANATOLIAN HIEROGLYPH A102A;Lo;0;L;;;;;N;;;;;\n14475;ANATOLIAN HIEROGLYPH A103;Lo;0;L;;;;;N;;;;;\n14476;ANATOLIAN HIEROGLYPH A104;Lo;0;L;;;;;N;;;;;\n14477;ANATOLIAN HIEROGLYPH A104A;Lo;0;L;;;;;N;;;;;\n14478;ANATOLIAN HIEROGLYPH A104B;Lo;0;L;;;;;N;;;;;\n14479;ANATOLIAN HIEROGLYPH A104C;Lo;0;L;;;;;N;;;;;\n1447A;ANATOLIAN HIEROGLYPH A105;Lo;0;L;;;;;N;;;;;\n1447B;ANATOLIAN HIEROGLYPH A105A;Lo;0;L;;;;;N;;;;;\n1447C;ANATOLIAN HIEROGLYPH A105B;Lo;0;L;;;;;N;;;;;\n1447D;ANATOLIAN HIEROGLYPH A106;Lo;0;L;;;;;N;;;;;\n1447E;ANATOLIAN HIEROGLYPH A107;Lo;0;L;;;;;N;;;;;\n1447F;ANATOLIAN HIEROGLYPH A107A;Lo;0;L;;;;;N;;;;;\n14480;ANATOLIAN HIEROGLYPH A107B;Lo;0;L;;;;;N;;;;;\n14481;ANATOLIAN HIEROGLYPH A107C;Lo;0;L;;;;;N;;;;;\n14482;ANATOLIAN HIEROGLYPH A108;Lo;0;L;;;;;N;;;;;\n14483;ANATOLIAN HIEROGLYPH A109;Lo;0;L;;;;;N;;;;;\n14484;ANATOLIAN HIEROGLYPH A110;Lo;0;L;;;;;N;;;;;\n14485;ANATOLIAN HIEROGLYPH A110A;Lo;0;L;;;;;N;;;;;\n14486;ANATOLIAN HIEROGLYPH A110B;Lo;0;L;;;;;N;;;;;\n14487;ANATOLIAN HIEROGLYPH A111;Lo;0;L;;;;;N;;;;;\n14488;ANATOLIAN HIEROGLYPH A112;Lo;0;L;;;;;N;;;;;\n14489;ANATOLIAN HIEROGLYPH A113;Lo;0;L;;;;;N;;;;;\n1448A;ANATOLIAN HIEROGLYPH A114;Lo;0;L;;;;;N;;;;;\n1448B;ANATOLIAN HIEROGLYPH A115;Lo;0;L;;;;;N;;;;;\n1448C;ANATOLIAN HIEROGLYPH A115A;Lo;0;L;;;;;N;;;;;\n1448D;ANATOLIAN HIEROGLYPH A116;Lo;0;L;;;;;N;;;;;\n1448E;ANATOLIAN HIEROGLYPH A117;Lo;0;L;;;;;N;;;;;\n1448F;ANATOLIAN HIEROGLYPH A118;Lo;0;L;;;;;N;;;;;\n14490;ANATOLIAN HIEROGLYPH A119;Lo;0;L;;;;;N;;;;;\n14491;ANATOLIAN HIEROGLYPH A120;Lo;0;L;;;;;N;;;;;\n14492;ANATOLIAN HIEROGLYPH A121;Lo;0;L;;;;;N;;;;;\n14493;ANATOLIAN HIEROGLYPH A122;Lo;0;L;;;;;N;;;;;\n14494;ANATOLIAN HIEROGLYPH A123;Lo;0;L;;;;;N;;;;;\n14495;ANATOLIAN HIEROGLYPH A124;Lo;0;L;;;;;N;;;;;\n14496;ANATOLIAN HIEROGLYPH A125;Lo;0;L;;;;;N;;;;;\n14497;ANATOLIAN HIEROGLYPH A125A;Lo;0;L;;;;;N;;;;;\n14498;ANATOLIAN HIEROGLYPH A126;Lo;0;L;;;;;N;;;;;\n14499;ANATOLIAN HIEROGLYPH A127;Lo;0;L;;;;;N;;;;;\n1449A;ANATOLIAN HIEROGLYPH A128;Lo;0;L;;;;;N;;;;;\n1449B;ANATOLIAN HIEROGLYPH A129;Lo;0;L;;;;;N;;;;;\n1449C;ANATOLIAN HIEROGLYPH A130;Lo;0;L;;;;;N;;;;;\n1449D;ANATOLIAN HIEROGLYPH A131;Lo;0;L;;;;;N;;;;;\n1449E;ANATOLIAN HIEROGLYPH A132;Lo;0;L;;;;;N;;;;;\n1449F;ANATOLIAN HIEROGLYPH A133;Lo;0;L;;;;;N;;;;;\n144A0;ANATOLIAN HIEROGLYPH A134;Lo;0;L;;;;;N;;;;;\n144A1;ANATOLIAN HIEROGLYPH A135;Lo;0;L;;;;;N;;;;;\n144A2;ANATOLIAN HIEROGLYPH A135A;Lo;0;L;;;;;N;;;;;\n144A3;ANATOLIAN HIEROGLYPH A136;Lo;0;L;;;;;N;;;;;\n144A4;ANATOLIAN HIEROGLYPH A137;Lo;0;L;;;;;N;;;;;\n144A5;ANATOLIAN HIEROGLYPH A138;Lo;0;L;;;;;N;;;;;\n144A6;ANATOLIAN HIEROGLYPH A139;Lo;0;L;;;;;N;;;;;\n144A7;ANATOLIAN HIEROGLYPH A140;Lo;0;L;;;;;N;;;;;\n144A8;ANATOLIAN HIEROGLYPH A141;Lo;0;L;;;;;N;;;;;\n144A9;ANATOLIAN HIEROGLYPH A142;Lo;0;L;;;;;N;;;;;\n144AA;ANATOLIAN HIEROGLYPH A143;Lo;0;L;;;;;N;;;;;\n144AB;ANATOLIAN HIEROGLYPH A144;Lo;0;L;;;;;N;;;;;\n144AC;ANATOLIAN HIEROGLYPH A145;Lo;0;L;;;;;N;;;;;\n144AD;ANATOLIAN HIEROGLYPH A146;Lo;0;L;;;;;N;;;;;\n144AE;ANATOLIAN HIEROGLYPH A147;Lo;0;L;;;;;N;;;;;\n144AF;ANATOLIAN HIEROGLYPH A148;Lo;0;L;;;;;N;;;;;\n144B0;ANATOLIAN HIEROGLYPH A149;Lo;0;L;;;;;N;;;;;\n144B1;ANATOLIAN HIEROGLYPH A150;Lo;0;L;;;;;N;;;;;\n144B2;ANATOLIAN HIEROGLYPH A151;Lo;0;L;;;;;N;;;;;\n144B3;ANATOLIAN HIEROGLYPH A152;Lo;0;L;;;;;N;;;;;\n144B4;ANATOLIAN HIEROGLYPH A153;Lo;0;L;;;;;N;;;;;\n144B5;ANATOLIAN HIEROGLYPH A154;Lo;0;L;;;;;N;;;;;\n144B6;ANATOLIAN HIEROGLYPH A155;Lo;0;L;;;;;N;;;;;\n144B7;ANATOLIAN HIEROGLYPH A156;Lo;0;L;;;;;N;;;;;\n144B8;ANATOLIAN HIEROGLYPH A157;Lo;0;L;;;;;N;;;;;\n144B9;ANATOLIAN HIEROGLYPH A158;Lo;0;L;;;;;N;;;;;\n144BA;ANATOLIAN HIEROGLYPH A159;Lo;0;L;;;;;N;;;;;\n144BB;ANATOLIAN HIEROGLYPH A160;Lo;0;L;;;;;N;;;;;\n144BC;ANATOLIAN HIEROGLYPH A161;Lo;0;L;;;;;N;;;;;\n144BD;ANATOLIAN HIEROGLYPH A162;Lo;0;L;;;;;N;;;;;\n144BE;ANATOLIAN HIEROGLYPH A163;Lo;0;L;;;;;N;;;;;\n144BF;ANATOLIAN HIEROGLYPH A164;Lo;0;L;;;;;N;;;;;\n144C0;ANATOLIAN HIEROGLYPH A165;Lo;0;L;;;;;N;;;;;\n144C1;ANATOLIAN HIEROGLYPH A166;Lo;0;L;;;;;N;;;;;\n144C2;ANATOLIAN HIEROGLYPH A167;Lo;0;L;;;;;N;;;;;\n144C3;ANATOLIAN HIEROGLYPH A168;Lo;0;L;;;;;N;;;;;\n144C4;ANATOLIAN HIEROGLYPH A169;Lo;0;L;;;;;N;;;;;\n144C5;ANATOLIAN HIEROGLYPH A170;Lo;0;L;;;;;N;;;;;\n144C6;ANATOLIAN HIEROGLYPH A171;Lo;0;L;;;;;N;;;;;\n144C7;ANATOLIAN HIEROGLYPH A172;Lo;0;L;;;;;N;;;;;\n144C8;ANATOLIAN HIEROGLYPH A173;Lo;0;L;;;;;N;;;;;\n144C9;ANATOLIAN HIEROGLYPH A174;Lo;0;L;;;;;N;;;;;\n144CA;ANATOLIAN HIEROGLYPH A175;Lo;0;L;;;;;N;;;;;\n144CB;ANATOLIAN HIEROGLYPH A176;Lo;0;L;;;;;N;;;;;\n144CC;ANATOLIAN HIEROGLYPH A177;Lo;0;L;;;;;N;;;;;\n144CD;ANATOLIAN HIEROGLYPH A178;Lo;0;L;;;;;N;;;;;\n144CE;ANATOLIAN HIEROGLYPH A179;Lo;0;L;;;;;N;;;;;\n144CF;ANATOLIAN HIEROGLYPH A180;Lo;0;L;;;;;N;;;;;\n144D0;ANATOLIAN HIEROGLYPH A181;Lo;0;L;;;;;N;;;;;\n144D1;ANATOLIAN HIEROGLYPH A182;Lo;0;L;;;;;N;;;;;\n144D2;ANATOLIAN HIEROGLYPH A183;Lo;0;L;;;;;N;;;;;\n144D3;ANATOLIAN HIEROGLYPH A184;Lo;0;L;;;;;N;;;;;\n144D4;ANATOLIAN HIEROGLYPH A185;Lo;0;L;;;;;N;;;;;\n144D5;ANATOLIAN HIEROGLYPH A186;Lo;0;L;;;;;N;;;;;\n144D6;ANATOLIAN HIEROGLYPH A187;Lo;0;L;;;;;N;;;;;\n144D7;ANATOLIAN HIEROGLYPH A188;Lo;0;L;;;;;N;;;;;\n144D8;ANATOLIAN HIEROGLYPH A189;Lo;0;L;;;;;N;;;;;\n144D9;ANATOLIAN HIEROGLYPH A190;Lo;0;L;;;;;N;;;;;\n144DA;ANATOLIAN HIEROGLYPH A191;Lo;0;L;;;;;N;;;;;\n144DB;ANATOLIAN HIEROGLYPH A192;Lo;0;L;;;;;N;;;;;\n144DC;ANATOLIAN HIEROGLYPH A193;Lo;0;L;;;;;N;;;;;\n144DD;ANATOLIAN HIEROGLYPH A194;Lo;0;L;;;;;N;;;;;\n144DE;ANATOLIAN HIEROGLYPH A195;Lo;0;L;;;;;N;;;;;\n144DF;ANATOLIAN HIEROGLYPH A196;Lo;0;L;;;;;N;;;;;\n144E0;ANATOLIAN HIEROGLYPH A197;Lo;0;L;;;;;N;;;;;\n144E1;ANATOLIAN HIEROGLYPH A198;Lo;0;L;;;;;N;;;;;\n144E2;ANATOLIAN HIEROGLYPH A199;Lo;0;L;;;;;N;;;;;\n144E3;ANATOLIAN HIEROGLYPH A200;Lo;0;L;;;;;N;;;;;\n144E4;ANATOLIAN HIEROGLYPH A201;Lo;0;L;;;;;N;;;;;\n144E5;ANATOLIAN HIEROGLYPH A202;Lo;0;L;;;;;N;;;;;\n144E6;ANATOLIAN HIEROGLYPH A202A;Lo;0;L;;;;;N;;;;;\n144E7;ANATOLIAN HIEROGLYPH A202B;Lo;0;L;;;;;N;;;;;\n144E8;ANATOLIAN HIEROGLYPH A203;Lo;0;L;;;;;N;;;;;\n144E9;ANATOLIAN HIEROGLYPH A204;Lo;0;L;;;;;N;;;;;\n144EA;ANATOLIAN HIEROGLYPH A205;Lo;0;L;;;;;N;;;;;\n144EB;ANATOLIAN HIEROGLYPH A206;Lo;0;L;;;;;N;;;;;\n144EC;ANATOLIAN HIEROGLYPH A207;Lo;0;L;;;;;N;;;;;\n144ED;ANATOLIAN HIEROGLYPH A207A;Lo;0;L;;;;;N;;;;;\n144EE;ANATOLIAN HIEROGLYPH A208;Lo;0;L;;;;;N;;;;;\n144EF;ANATOLIAN HIEROGLYPH A209;Lo;0;L;;;;;N;;;;;\n144F0;ANATOLIAN HIEROGLYPH A209A;Lo;0;L;;;;;N;;;;;\n144F1;ANATOLIAN HIEROGLYPH A210;Lo;0;L;;;;;N;;;;;\n144F2;ANATOLIAN HIEROGLYPH A211;Lo;0;L;;;;;N;;;;;\n144F3;ANATOLIAN HIEROGLYPH A212;Lo;0;L;;;;;N;;;;;\n144F4;ANATOLIAN HIEROGLYPH A213;Lo;0;L;;;;;N;;;;;\n144F5;ANATOLIAN HIEROGLYPH A214;Lo;0;L;;;;;N;;;;;\n144F6;ANATOLIAN HIEROGLYPH A215;Lo;0;L;;;;;N;;;;;\n144F7;ANATOLIAN HIEROGLYPH A215A;Lo;0;L;;;;;N;;;;;\n144F8;ANATOLIAN HIEROGLYPH A216;Lo;0;L;;;;;N;;;;;\n144F9;ANATOLIAN HIEROGLYPH A216A;Lo;0;L;;;;;N;;;;;\n144FA;ANATOLIAN HIEROGLYPH A217;Lo;0;L;;;;;N;;;;;\n144FB;ANATOLIAN HIEROGLYPH A218;Lo;0;L;;;;;N;;;;;\n144FC;ANATOLIAN HIEROGLYPH A219;Lo;0;L;;;;;N;;;;;\n144FD;ANATOLIAN HIEROGLYPH A220;Lo;0;L;;;;;N;;;;;\n144FE;ANATOLIAN HIEROGLYPH A221;Lo;0;L;;;;;N;;;;;\n144FF;ANATOLIAN HIEROGLYPH A222;Lo;0;L;;;;;N;;;;;\n14500;ANATOLIAN HIEROGLYPH A223;Lo;0;L;;;;;N;;;;;\n14501;ANATOLIAN HIEROGLYPH A224;Lo;0;L;;;;;N;;;;;\n14502;ANATOLIAN HIEROGLYPH A225;Lo;0;L;;;;;N;;;;;\n14503;ANATOLIAN HIEROGLYPH A226;Lo;0;L;;;;;N;;;;;\n14504;ANATOLIAN HIEROGLYPH A227;Lo;0;L;;;;;N;;;;;\n14505;ANATOLIAN HIEROGLYPH A227A;Lo;0;L;;;;;N;;;;;\n14506;ANATOLIAN HIEROGLYPH A228;Lo;0;L;;;;;N;;;;;\n14507;ANATOLIAN HIEROGLYPH A229;Lo;0;L;;;;;N;;;;;\n14508;ANATOLIAN HIEROGLYPH A230;Lo;0;L;;;;;N;;;;;\n14509;ANATOLIAN HIEROGLYPH A231;Lo;0;L;;;;;N;;;;;\n1450A;ANATOLIAN HIEROGLYPH A232;Lo;0;L;;;;;N;;;;;\n1450B;ANATOLIAN HIEROGLYPH A233;Lo;0;L;;;;;N;;;;;\n1450C;ANATOLIAN HIEROGLYPH A234;Lo;0;L;;;;;N;;;;;\n1450D;ANATOLIAN HIEROGLYPH A235;Lo;0;L;;;;;N;;;;;\n1450E;ANATOLIAN HIEROGLYPH A236;Lo;0;L;;;;;N;;;;;\n1450F;ANATOLIAN HIEROGLYPH A237;Lo;0;L;;;;;N;;;;;\n14510;ANATOLIAN HIEROGLYPH A238;Lo;0;L;;;;;N;;;;;\n14511;ANATOLIAN HIEROGLYPH A239;Lo;0;L;;;;;N;;;;;\n14512;ANATOLIAN HIEROGLYPH A240;Lo;0;L;;;;;N;;;;;\n14513;ANATOLIAN HIEROGLYPH A241;Lo;0;L;;;;;N;;;;;\n14514;ANATOLIAN HIEROGLYPH A242;Lo;0;L;;;;;N;;;;;\n14515;ANATOLIAN HIEROGLYPH A243;Lo;0;L;;;;;N;;;;;\n14516;ANATOLIAN HIEROGLYPH A244;Lo;0;L;;;;;N;;;;;\n14517;ANATOLIAN HIEROGLYPH A245;Lo;0;L;;;;;N;;;;;\n14518;ANATOLIAN HIEROGLYPH A246;Lo;0;L;;;;;N;;;;;\n14519;ANATOLIAN HIEROGLYPH A247;Lo;0;L;;;;;N;;;;;\n1451A;ANATOLIAN HIEROGLYPH A248;Lo;0;L;;;;;N;;;;;\n1451B;ANATOLIAN HIEROGLYPH A249;Lo;0;L;;;;;N;;;;;\n1451C;ANATOLIAN HIEROGLYPH A250;Lo;0;L;;;;;N;;;;;\n1451D;ANATOLIAN HIEROGLYPH A251;Lo;0;L;;;;;N;;;;;\n1451E;ANATOLIAN HIEROGLYPH A252;Lo;0;L;;;;;N;;;;;\n1451F;ANATOLIAN HIEROGLYPH A253;Lo;0;L;;;;;N;;;;;\n14520;ANATOLIAN HIEROGLYPH A254;Lo;0;L;;;;;N;;;;;\n14521;ANATOLIAN HIEROGLYPH A255;Lo;0;L;;;;;N;;;;;\n14522;ANATOLIAN HIEROGLYPH A256;Lo;0;L;;;;;N;;;;;\n14523;ANATOLIAN HIEROGLYPH A257;Lo;0;L;;;;;N;;;;;\n14524;ANATOLIAN HIEROGLYPH A258;Lo;0;L;;;;;N;;;;;\n14525;ANATOLIAN HIEROGLYPH A259;Lo;0;L;;;;;N;;;;;\n14526;ANATOLIAN HIEROGLYPH A260;Lo;0;L;;;;;N;;;;;\n14527;ANATOLIAN HIEROGLYPH A261;Lo;0;L;;;;;N;;;;;\n14528;ANATOLIAN HIEROGLYPH A262;Lo;0;L;;;;;N;;;;;\n14529;ANATOLIAN HIEROGLYPH A263;Lo;0;L;;;;;N;;;;;\n1452A;ANATOLIAN HIEROGLYPH A264;Lo;0;L;;;;;N;;;;;\n1452B;ANATOLIAN HIEROGLYPH A265;Lo;0;L;;;;;N;;;;;\n1452C;ANATOLIAN HIEROGLYPH A266;Lo;0;L;;;;;N;;;;;\n1452D;ANATOLIAN HIEROGLYPH A267;Lo;0;L;;;;;N;;;;;\n1452E;ANATOLIAN HIEROGLYPH A267A;Lo;0;L;;;;;N;;;;;\n1452F;ANATOLIAN HIEROGLYPH A268;Lo;0;L;;;;;N;;;;;\n14530;ANATOLIAN HIEROGLYPH A269;Lo;0;L;;;;;N;;;;;\n14531;ANATOLIAN HIEROGLYPH A270;Lo;0;L;;;;;N;;;;;\n14532;ANATOLIAN HIEROGLYPH A271;Lo;0;L;;;;;N;;;;;\n14533;ANATOLIAN HIEROGLYPH A272;Lo;0;L;;;;;N;;;;;\n14534;ANATOLIAN HIEROGLYPH A273;Lo;0;L;;;;;N;;;;;\n14535;ANATOLIAN HIEROGLYPH A274;Lo;0;L;;;;;N;;;;;\n14536;ANATOLIAN HIEROGLYPH A275;Lo;0;L;;;;;N;;;;;\n14537;ANATOLIAN HIEROGLYPH A276;Lo;0;L;;;;;N;;;;;\n14538;ANATOLIAN HIEROGLYPH A277;Lo;0;L;;;;;N;;;;;\n14539;ANATOLIAN HIEROGLYPH A278;Lo;0;L;;;;;N;;;;;\n1453A;ANATOLIAN HIEROGLYPH A279;Lo;0;L;;;;;N;;;;;\n1453B;ANATOLIAN HIEROGLYPH A280;Lo;0;L;;;;;N;;;;;\n1453C;ANATOLIAN HIEROGLYPH A281;Lo;0;L;;;;;N;;;;;\n1453D;ANATOLIAN HIEROGLYPH A282;Lo;0;L;;;;;N;;;;;\n1453E;ANATOLIAN HIEROGLYPH A283;Lo;0;L;;;;;N;;;;;\n1453F;ANATOLIAN HIEROGLYPH A284;Lo;0;L;;;;;N;;;;;\n14540;ANATOLIAN HIEROGLYPH A285;Lo;0;L;;;;;N;;;;;\n14541;ANATOLIAN HIEROGLYPH A286;Lo;0;L;;;;;N;;;;;\n14542;ANATOLIAN HIEROGLYPH A287;Lo;0;L;;;;;N;;;;;\n14543;ANATOLIAN HIEROGLYPH A288;Lo;0;L;;;;;N;;;;;\n14544;ANATOLIAN HIEROGLYPH A289;Lo;0;L;;;;;N;;;;;\n14545;ANATOLIAN HIEROGLYPH A289A;Lo;0;L;;;;;N;;;;;\n14546;ANATOLIAN HIEROGLYPH A290;Lo;0;L;;;;;N;;;;;\n14547;ANATOLIAN HIEROGLYPH A291;Lo;0;L;;;;;N;;;;;\n14548;ANATOLIAN HIEROGLYPH A292;Lo;0;L;;;;;N;;;;;\n14549;ANATOLIAN HIEROGLYPH A293;Lo;0;L;;;;;N;;;;;\n1454A;ANATOLIAN HIEROGLYPH A294;Lo;0;L;;;;;N;;;;;\n1454B;ANATOLIAN HIEROGLYPH A294A;Lo;0;L;;;;;N;;;;;\n1454C;ANATOLIAN HIEROGLYPH A295;Lo;0;L;;;;;N;;;;;\n1454D;ANATOLIAN HIEROGLYPH A296;Lo;0;L;;;;;N;;;;;\n1454E;ANATOLIAN HIEROGLYPH A297;Lo;0;L;;;;;N;;;;;\n1454F;ANATOLIAN HIEROGLYPH A298;Lo;0;L;;;;;N;;;;;\n14550;ANATOLIAN HIEROGLYPH A299;Lo;0;L;;;;;N;;;;;\n14551;ANATOLIAN HIEROGLYPH A299A;Lo;0;L;;;;;N;;;;;\n14552;ANATOLIAN HIEROGLYPH A300;Lo;0;L;;;;;N;;;;;\n14553;ANATOLIAN HIEROGLYPH A301;Lo;0;L;;;;;N;;;;;\n14554;ANATOLIAN HIEROGLYPH A302;Lo;0;L;;;;;N;;;;;\n14555;ANATOLIAN HIEROGLYPH A303;Lo;0;L;;;;;N;;;;;\n14556;ANATOLIAN HIEROGLYPH A304;Lo;0;L;;;;;N;;;;;\n14557;ANATOLIAN HIEROGLYPH A305;Lo;0;L;;;;;N;;;;;\n14558;ANATOLIAN HIEROGLYPH A306;Lo;0;L;;;;;N;;;;;\n14559;ANATOLIAN HIEROGLYPH A307;Lo;0;L;;;;;N;;;;;\n1455A;ANATOLIAN HIEROGLYPH A308;Lo;0;L;;;;;N;;;;;\n1455B;ANATOLIAN HIEROGLYPH A309;Lo;0;L;;;;;N;;;;;\n1455C;ANATOLIAN HIEROGLYPH A309A;Lo;0;L;;;;;N;;;;;\n1455D;ANATOLIAN HIEROGLYPH A310;Lo;0;L;;;;;N;;;;;\n1455E;ANATOLIAN HIEROGLYPH A311;Lo;0;L;;;;;N;;;;;\n1455F;ANATOLIAN HIEROGLYPH A312;Lo;0;L;;;;;N;;;;;\n14560;ANATOLIAN HIEROGLYPH A313;Lo;0;L;;;;;N;;;;;\n14561;ANATOLIAN HIEROGLYPH A314;Lo;0;L;;;;;N;;;;;\n14562;ANATOLIAN HIEROGLYPH A315;Lo;0;L;;;;;N;;;;;\n14563;ANATOLIAN HIEROGLYPH A316;Lo;0;L;;;;;N;;;;;\n14564;ANATOLIAN HIEROGLYPH A317;Lo;0;L;;;;;N;;;;;\n14565;ANATOLIAN HIEROGLYPH A318;Lo;0;L;;;;;N;;;;;\n14566;ANATOLIAN HIEROGLYPH A319;Lo;0;L;;;;;N;;;;;\n14567;ANATOLIAN HIEROGLYPH A320;Lo;0;L;;;;;N;;;;;\n14568;ANATOLIAN HIEROGLYPH A321;Lo;0;L;;;;;N;;;;;\n14569;ANATOLIAN HIEROGLYPH A322;Lo;0;L;;;;;N;;;;;\n1456A;ANATOLIAN HIEROGLYPH A323;Lo;0;L;;;;;N;;;;;\n1456B;ANATOLIAN HIEROGLYPH A324;Lo;0;L;;;;;N;;;;;\n1456C;ANATOLIAN HIEROGLYPH A325;Lo;0;L;;;;;N;;;;;\n1456D;ANATOLIAN HIEROGLYPH A326;Lo;0;L;;;;;N;;;;;\n1456E;ANATOLIAN HIEROGLYPH A327;Lo;0;L;;;;;N;;;;;\n1456F;ANATOLIAN HIEROGLYPH A328;Lo;0;L;;;;;N;;;;;\n14570;ANATOLIAN HIEROGLYPH A329;Lo;0;L;;;;;N;;;;;\n14571;ANATOLIAN HIEROGLYPH A329A;Lo;0;L;;;;;N;;;;;\n14572;ANATOLIAN HIEROGLYPH A330;Lo;0;L;;;;;N;;;;;\n14573;ANATOLIAN HIEROGLYPH A331;Lo;0;L;;;;;N;;;;;\n14574;ANATOLIAN HIEROGLYPH A332A;Lo;0;L;;;;;N;;;;;\n14575;ANATOLIAN HIEROGLYPH A332B;Lo;0;L;;;;;N;;;;;\n14576;ANATOLIAN HIEROGLYPH A332C;Lo;0;L;;;;;N;;;;;\n14577;ANATOLIAN HIEROGLYPH A333;Lo;0;L;;;;;N;;;;;\n14578;ANATOLIAN HIEROGLYPH A334;Lo;0;L;;;;;N;;;;;\n14579;ANATOLIAN HIEROGLYPH A335;Lo;0;L;;;;;N;;;;;\n1457A;ANATOLIAN HIEROGLYPH A336;Lo;0;L;;;;;N;;;;;\n1457B;ANATOLIAN HIEROGLYPH A336A;Lo;0;L;;;;;N;;;;;\n1457C;ANATOLIAN HIEROGLYPH A336B;Lo;0;L;;;;;N;;;;;\n1457D;ANATOLIAN HIEROGLYPH A336C;Lo;0;L;;;;;N;;;;;\n1457E;ANATOLIAN HIEROGLYPH A337;Lo;0;L;;;;;N;;;;;\n1457F;ANATOLIAN HIEROGLYPH A338;Lo;0;L;;;;;N;;;;;\n14580;ANATOLIAN HIEROGLYPH A339;Lo;0;L;;;;;N;;;;;\n14581;ANATOLIAN HIEROGLYPH A340;Lo;0;L;;;;;N;;;;;\n14582;ANATOLIAN HIEROGLYPH A341;Lo;0;L;;;;;N;;;;;\n14583;ANATOLIAN HIEROGLYPH A342;Lo;0;L;;;;;N;;;;;\n14584;ANATOLIAN HIEROGLYPH A343;Lo;0;L;;;;;N;;;;;\n14585;ANATOLIAN HIEROGLYPH A344;Lo;0;L;;;;;N;;;;;\n14586;ANATOLIAN HIEROGLYPH A345;Lo;0;L;;;;;N;;;;;\n14587;ANATOLIAN HIEROGLYPH A346;Lo;0;L;;;;;N;;;;;\n14588;ANATOLIAN HIEROGLYPH A347;Lo;0;L;;;;;N;;;;;\n14589;ANATOLIAN HIEROGLYPH A348;Lo;0;L;;;;;N;;;;;\n1458A;ANATOLIAN HIEROGLYPH A349;Lo;0;L;;;;;N;;;;;\n1458B;ANATOLIAN HIEROGLYPH A350;Lo;0;L;;;;;N;;;;;\n1458C;ANATOLIAN HIEROGLYPH A351;Lo;0;L;;;;;N;;;;;\n1458D;ANATOLIAN HIEROGLYPH A352;Lo;0;L;;;;;N;;;;;\n1458E;ANATOLIAN HIEROGLYPH A353;Lo;0;L;;;;;N;;;;;\n1458F;ANATOLIAN HIEROGLYPH A354;Lo;0;L;;;;;N;;;;;\n14590;ANATOLIAN HIEROGLYPH A355;Lo;0;L;;;;;N;;;;;\n14591;ANATOLIAN HIEROGLYPH A356;Lo;0;L;;;;;N;;;;;\n14592;ANATOLIAN HIEROGLYPH A357;Lo;0;L;;;;;N;;;;;\n14593;ANATOLIAN HIEROGLYPH A358;Lo;0;L;;;;;N;;;;;\n14594;ANATOLIAN HIEROGLYPH A359;Lo;0;L;;;;;N;;;;;\n14595;ANATOLIAN HIEROGLYPH A359A;Lo;0;L;;;;;N;;;;;\n14596;ANATOLIAN HIEROGLYPH A360;Lo;0;L;;;;;N;;;;;\n14597;ANATOLIAN HIEROGLYPH A361;Lo;0;L;;;;;N;;;;;\n14598;ANATOLIAN HIEROGLYPH A362;Lo;0;L;;;;;N;;;;;\n14599;ANATOLIAN HIEROGLYPH A363;Lo;0;L;;;;;N;;;;;\n1459A;ANATOLIAN HIEROGLYPH A364;Lo;0;L;;;;;N;;;;;\n1459B;ANATOLIAN HIEROGLYPH A364A;Lo;0;L;;;;;N;;;;;\n1459C;ANATOLIAN HIEROGLYPH A365;Lo;0;L;;;;;N;;;;;\n1459D;ANATOLIAN HIEROGLYPH A366;Lo;0;L;;;;;N;;;;;\n1459E;ANATOLIAN HIEROGLYPH A367;Lo;0;L;;;;;N;;;;;\n1459F;ANATOLIAN HIEROGLYPH A368;Lo;0;L;;;;;N;;;;;\n145A0;ANATOLIAN HIEROGLYPH A368A;Lo;0;L;;;;;N;;;;;\n145A1;ANATOLIAN HIEROGLYPH A369;Lo;0;L;;;;;N;;;;;\n145A2;ANATOLIAN HIEROGLYPH A370;Lo;0;L;;;;;N;;;;;\n145A3;ANATOLIAN HIEROGLYPH A371;Lo;0;L;;;;;N;;;;;\n145A4;ANATOLIAN HIEROGLYPH A371A;Lo;0;L;;;;;N;;;;;\n145A5;ANATOLIAN HIEROGLYPH A372;Lo;0;L;;;;;N;;;;;\n145A6;ANATOLIAN HIEROGLYPH A373;Lo;0;L;;;;;N;;;;;\n145A7;ANATOLIAN HIEROGLYPH A374;Lo;0;L;;;;;N;;;;;\n145A8;ANATOLIAN HIEROGLYPH A375;Lo;0;L;;;;;N;;;;;\n145A9;ANATOLIAN HIEROGLYPH A376;Lo;0;L;;;;;N;;;;;\n145AA;ANATOLIAN HIEROGLYPH A377;Lo;0;L;;;;;N;;;;;\n145AB;ANATOLIAN HIEROGLYPH A378;Lo;0;L;;;;;N;;;;;\n145AC;ANATOLIAN HIEROGLYPH A379;Lo;0;L;;;;;N;;;;;\n145AD;ANATOLIAN HIEROGLYPH A380;Lo;0;L;;;;;N;;;;;\n145AE;ANATOLIAN HIEROGLYPH A381;Lo;0;L;;;;;N;;;;;\n145AF;ANATOLIAN HIEROGLYPH A381A;Lo;0;L;;;;;N;;;;;\n145B0;ANATOLIAN HIEROGLYPH A382;Lo;0;L;;;;;N;;;;;\n145B1;ANATOLIAN HIEROGLYPH A383 RA OR RI;Lo;0;L;;;;;N;;;;;\n145B2;ANATOLIAN HIEROGLYPH A383A;Lo;0;L;;;;;N;;;;;\n145B3;ANATOLIAN HIEROGLYPH A384;Lo;0;L;;;;;N;;;;;\n145B4;ANATOLIAN HIEROGLYPH A385;Lo;0;L;;;;;N;;;;;\n145B5;ANATOLIAN HIEROGLYPH A386;Lo;0;L;;;;;N;;;;;\n145B6;ANATOLIAN HIEROGLYPH A386A;Lo;0;L;;;;;N;;;;;\n145B7;ANATOLIAN HIEROGLYPH A387;Lo;0;L;;;;;N;;;;;\n145B8;ANATOLIAN HIEROGLYPH A388;Lo;0;L;;;;;N;;;;;\n145B9;ANATOLIAN HIEROGLYPH A389;Lo;0;L;;;;;N;;;;;\n145BA;ANATOLIAN HIEROGLYPH A390;Lo;0;L;;;;;N;;;;;\n145BB;ANATOLIAN HIEROGLYPH A391;Lo;0;L;;;;;N;;;;;\n145BC;ANATOLIAN HIEROGLYPH A392;Lo;0;L;;;;;N;;;;;\n145BD;ANATOLIAN HIEROGLYPH A393 EIGHT;Lo;0;L;;;;;N;;;;;\n145BE;ANATOLIAN HIEROGLYPH A394;Lo;0;L;;;;;N;;;;;\n145BF;ANATOLIAN HIEROGLYPH A395;Lo;0;L;;;;;N;;;;;\n145C0;ANATOLIAN HIEROGLYPH A396;Lo;0;L;;;;;N;;;;;\n145C1;ANATOLIAN HIEROGLYPH A397;Lo;0;L;;;;;N;;;;;\n145C2;ANATOLIAN HIEROGLYPH A398;Lo;0;L;;;;;N;;;;;\n145C3;ANATOLIAN HIEROGLYPH A399;Lo;0;L;;;;;N;;;;;\n145C4;ANATOLIAN HIEROGLYPH A400;Lo;0;L;;;;;N;;;;;\n145C5;ANATOLIAN HIEROGLYPH A401;Lo;0;L;;;;;N;;;;;\n145C6;ANATOLIAN HIEROGLYPH A402;Lo;0;L;;;;;N;;;;;\n145C7;ANATOLIAN HIEROGLYPH A403;Lo;0;L;;;;;N;;;;;\n145C8;ANATOLIAN HIEROGLYPH A404;Lo;0;L;;;;;N;;;;;\n145C9;ANATOLIAN HIEROGLYPH A405;Lo;0;L;;;;;N;;;;;\n145CA;ANATOLIAN HIEROGLYPH A406;Lo;0;L;;;;;N;;;;;\n145CB;ANATOLIAN HIEROGLYPH A407;Lo;0;L;;;;;N;;;;;\n145CC;ANATOLIAN HIEROGLYPH A408;Lo;0;L;;;;;N;;;;;\n145CD;ANATOLIAN HIEROGLYPH A409;Lo;0;L;;;;;N;;;;;\n145CE;ANATOLIAN HIEROGLYPH A410 BEGIN LOGOGRAM MARK;Lo;0;L;;;;;N;;;;;\n145CF;ANATOLIAN HIEROGLYPH A410A END LOGOGRAM MARK;Lo;0;L;;;;;N;;;;;\n145D0;ANATOLIAN HIEROGLYPH A411;Lo;0;L;;;;;N;;;;;\n145D1;ANATOLIAN HIEROGLYPH A412;Lo;0;L;;;;;N;;;;;\n145D2;ANATOLIAN HIEROGLYPH A413;Lo;0;L;;;;;N;;;;;\n145D3;ANATOLIAN HIEROGLYPH A414;Lo;0;L;;;;;N;;;;;\n145D4;ANATOLIAN HIEROGLYPH A415;Lo;0;L;;;;;N;;;;;\n145D5;ANATOLIAN HIEROGLYPH A416;Lo;0;L;;;;;N;;;;;\n145D6;ANATOLIAN HIEROGLYPH A417;Lo;0;L;;;;;N;;;;;\n145D7;ANATOLIAN HIEROGLYPH A418;Lo;0;L;;;;;N;;;;;\n145D8;ANATOLIAN HIEROGLYPH A419;Lo;0;L;;;;;N;;;;;\n145D9;ANATOLIAN HIEROGLYPH A420;Lo;0;L;;;;;N;;;;;\n145DA;ANATOLIAN HIEROGLYPH A421;Lo;0;L;;;;;N;;;;;\n145DB;ANATOLIAN HIEROGLYPH A422;Lo;0;L;;;;;N;;;;;\n145DC;ANATOLIAN HIEROGLYPH A423;Lo;0;L;;;;;N;;;;;\n145DD;ANATOLIAN HIEROGLYPH A424;Lo;0;L;;;;;N;;;;;\n145DE;ANATOLIAN HIEROGLYPH A425;Lo;0;L;;;;;N;;;;;\n145DF;ANATOLIAN HIEROGLYPH A426;Lo;0;L;;;;;N;;;;;\n145E0;ANATOLIAN HIEROGLYPH A427;Lo;0;L;;;;;N;;;;;\n145E1;ANATOLIAN HIEROGLYPH A428;Lo;0;L;;;;;N;;;;;\n145E2;ANATOLIAN HIEROGLYPH A429;Lo;0;L;;;;;N;;;;;\n145E3;ANATOLIAN HIEROGLYPH A430;Lo;0;L;;;;;N;;;;;\n145E4;ANATOLIAN HIEROGLYPH A431;Lo;0;L;;;;;N;;;;;\n145E5;ANATOLIAN HIEROGLYPH A432;Lo;0;L;;;;;N;;;;;\n145E6;ANATOLIAN HIEROGLYPH A433;Lo;0;L;;;;;N;;;;;\n145E7;ANATOLIAN HIEROGLYPH A434;Lo;0;L;;;;;N;;;;;\n145E8;ANATOLIAN HIEROGLYPH A435;Lo;0;L;;;;;N;;;;;\n145E9;ANATOLIAN HIEROGLYPH A436;Lo;0;L;;;;;N;;;;;\n145EA;ANATOLIAN HIEROGLYPH A437;Lo;0;L;;;;;N;;;;;\n145EB;ANATOLIAN HIEROGLYPH A438;Lo;0;L;;;;;N;;;;;\n145EC;ANATOLIAN HIEROGLYPH A439;Lo;0;L;;;;;N;;;;;\n145ED;ANATOLIAN HIEROGLYPH A440;Lo;0;L;;;;;N;;;;;\n145EE;ANATOLIAN HIEROGLYPH A441;Lo;0;L;;;;;N;;;;;\n145EF;ANATOLIAN HIEROGLYPH A442;Lo;0;L;;;;;N;;;;;\n145F0;ANATOLIAN HIEROGLYPH A443;Lo;0;L;;;;;N;;;;;\n145F1;ANATOLIAN HIEROGLYPH A444;Lo;0;L;;;;;N;;;;;\n145F2;ANATOLIAN HIEROGLYPH A445;Lo;0;L;;;;;N;;;;;\n145F3;ANATOLIAN HIEROGLYPH A446;Lo;0;L;;;;;N;;;;;\n145F4;ANATOLIAN HIEROGLYPH A447;Lo;0;L;;;;;N;;;;;\n145F5;ANATOLIAN HIEROGLYPH A448;Lo;0;L;;;;;N;;;;;\n145F6;ANATOLIAN HIEROGLYPH A449;Lo;0;L;;;;;N;;;;;\n145F7;ANATOLIAN HIEROGLYPH A450;Lo;0;L;;;;;N;;;;;\n145F8;ANATOLIAN HIEROGLYPH A450A;Lo;0;L;;;;;N;;;;;\n145F9;ANATOLIAN HIEROGLYPH A451;Lo;0;L;;;;;N;;;;;\n145FA;ANATOLIAN HIEROGLYPH A452;Lo;0;L;;;;;N;;;;;\n145FB;ANATOLIAN HIEROGLYPH A453;Lo;0;L;;;;;N;;;;;\n145FC;ANATOLIAN HIEROGLYPH A454;Lo;0;L;;;;;N;;;;;\n145FD;ANATOLIAN HIEROGLYPH A455;Lo;0;L;;;;;N;;;;;\n145FE;ANATOLIAN HIEROGLYPH A456;Lo;0;L;;;;;N;;;;;\n145FF;ANATOLIAN HIEROGLYPH A457;Lo;0;L;;;;;N;;;;;\n14600;ANATOLIAN HIEROGLYPH A457A;Lo;0;L;;;;;N;;;;;\n14601;ANATOLIAN HIEROGLYPH A458;Lo;0;L;;;;;N;;;;;\n14602;ANATOLIAN HIEROGLYPH A459;Lo;0;L;;;;;N;;;;;\n14603;ANATOLIAN HIEROGLYPH A460;Lo;0;L;;;;;N;;;;;\n14604;ANATOLIAN HIEROGLYPH A461;Lo;0;L;;;;;N;;;;;\n14605;ANATOLIAN HIEROGLYPH A462;Lo;0;L;;;;;N;;;;;\n14606;ANATOLIAN HIEROGLYPH A463;Lo;0;L;;;;;N;;;;;\n14607;ANATOLIAN HIEROGLYPH A464;Lo;0;L;;;;;N;;;;;\n14608;ANATOLIAN HIEROGLYPH A465;Lo;0;L;;;;;N;;;;;\n14609;ANATOLIAN HIEROGLYPH A466;Lo;0;L;;;;;N;;;;;\n1460A;ANATOLIAN HIEROGLYPH A467;Lo;0;L;;;;;N;;;;;\n1460B;ANATOLIAN HIEROGLYPH A468;Lo;0;L;;;;;N;;;;;\n1460C;ANATOLIAN HIEROGLYPH A469;Lo;0;L;;;;;N;;;;;\n1460D;ANATOLIAN HIEROGLYPH A470;Lo;0;L;;;;;N;;;;;\n1460E;ANATOLIAN HIEROGLYPH A471;Lo;0;L;;;;;N;;;;;\n1460F;ANATOLIAN HIEROGLYPH A472;Lo;0;L;;;;;N;;;;;\n14610;ANATOLIAN HIEROGLYPH A473;Lo;0;L;;;;;N;;;;;\n14611;ANATOLIAN HIEROGLYPH A474;Lo;0;L;;;;;N;;;;;\n14612;ANATOLIAN HIEROGLYPH A475;Lo;0;L;;;;;N;;;;;\n14613;ANATOLIAN HIEROGLYPH A476;Lo;0;L;;;;;N;;;;;\n14614;ANATOLIAN HIEROGLYPH A477;Lo;0;L;;;;;N;;;;;\n14615;ANATOLIAN HIEROGLYPH A478;Lo;0;L;;;;;N;;;;;\n14616;ANATOLIAN HIEROGLYPH A479;Lo;0;L;;;;;N;;;;;\n14617;ANATOLIAN HIEROGLYPH A480;Lo;0;L;;;;;N;;;;;\n14618;ANATOLIAN HIEROGLYPH A481;Lo;0;L;;;;;N;;;;;\n14619;ANATOLIAN HIEROGLYPH A482;Lo;0;L;;;;;N;;;;;\n1461A;ANATOLIAN HIEROGLYPH A483;Lo;0;L;;;;;N;;;;;\n1461B;ANATOLIAN HIEROGLYPH A484;Lo;0;L;;;;;N;;;;;\n1461C;ANATOLIAN HIEROGLYPH A485;Lo;0;L;;;;;N;;;;;\n1461D;ANATOLIAN HIEROGLYPH A486;Lo;0;L;;;;;N;;;;;\n1461E;ANATOLIAN HIEROGLYPH A487;Lo;0;L;;;;;N;;;;;\n1461F;ANATOLIAN HIEROGLYPH A488;Lo;0;L;;;;;N;;;;;\n14620;ANATOLIAN HIEROGLYPH A489;Lo;0;L;;;;;N;;;;;\n14621;ANATOLIAN HIEROGLYPH A490;Lo;0;L;;;;;N;;;;;\n14622;ANATOLIAN HIEROGLYPH A491;Lo;0;L;;;;;N;;;;;\n14623;ANATOLIAN HIEROGLYPH A492;Lo;0;L;;;;;N;;;;;\n14624;ANATOLIAN HIEROGLYPH A493;Lo;0;L;;;;;N;;;;;\n14625;ANATOLIAN HIEROGLYPH A494;Lo;0;L;;;;;N;;;;;\n14626;ANATOLIAN HIEROGLYPH A495;Lo;0;L;;;;;N;;;;;\n14627;ANATOLIAN HIEROGLYPH A496;Lo;0;L;;;;;N;;;;;\n14628;ANATOLIAN HIEROGLYPH A497;Lo;0;L;;;;;N;;;;;\n14629;ANATOLIAN HIEROGLYPH A501;Lo;0;L;;;;;N;;;;;\n1462A;ANATOLIAN HIEROGLYPH A502;Lo;0;L;;;;;N;;;;;\n1462B;ANATOLIAN HIEROGLYPH A503;Lo;0;L;;;;;N;;;;;\n1462C;ANATOLIAN HIEROGLYPH A504;Lo;0;L;;;;;N;;;;;\n1462D;ANATOLIAN HIEROGLYPH A505;Lo;0;L;;;;;N;;;;;\n1462E;ANATOLIAN HIEROGLYPH A506;Lo;0;L;;;;;N;;;;;\n1462F;ANATOLIAN HIEROGLYPH A507;Lo;0;L;;;;;N;;;;;\n14630;ANATOLIAN HIEROGLYPH A508;Lo;0;L;;;;;N;;;;;\n14631;ANATOLIAN HIEROGLYPH A509;Lo;0;L;;;;;N;;;;;\n14632;ANATOLIAN HIEROGLYPH A510;Lo;0;L;;;;;N;;;;;\n14633;ANATOLIAN HIEROGLYPH A511;Lo;0;L;;;;;N;;;;;\n14634;ANATOLIAN HIEROGLYPH A512;Lo;0;L;;;;;N;;;;;\n14635;ANATOLIAN HIEROGLYPH A513;Lo;0;L;;;;;N;;;;;\n14636;ANATOLIAN HIEROGLYPH A514;Lo;0;L;;;;;N;;;;;\n14637;ANATOLIAN HIEROGLYPH A515;Lo;0;L;;;;;N;;;;;\n14638;ANATOLIAN HIEROGLYPH A516;Lo;0;L;;;;;N;;;;;\n14639;ANATOLIAN HIEROGLYPH A517;Lo;0;L;;;;;N;;;;;\n1463A;ANATOLIAN HIEROGLYPH A518;Lo;0;L;;;;;N;;;;;\n1463B;ANATOLIAN HIEROGLYPH A519;Lo;0;L;;;;;N;;;;;\n1463C;ANATOLIAN HIEROGLYPH A520;Lo;0;L;;;;;N;;;;;\n1463D;ANATOLIAN HIEROGLYPH A521;Lo;0;L;;;;;N;;;;;\n1463E;ANATOLIAN HIEROGLYPH A522;Lo;0;L;;;;;N;;;;;\n1463F;ANATOLIAN HIEROGLYPH A523;Lo;0;L;;;;;N;;;;;\n14640;ANATOLIAN HIEROGLYPH A524;Lo;0;L;;;;;N;;;;;\n14641;ANATOLIAN HIEROGLYPH A525;Lo;0;L;;;;;N;;;;;\n14642;ANATOLIAN HIEROGLYPH A526;Lo;0;L;;;;;N;;;;;\n14643;ANATOLIAN HIEROGLYPH A527;Lo;0;L;;;;;N;;;;;\n14644;ANATOLIAN HIEROGLYPH A528;Lo;0;L;;;;;N;;;;;\n14645;ANATOLIAN HIEROGLYPH A529;Lo;0;L;;;;;N;;;;;\n14646;ANATOLIAN HIEROGLYPH A530;Lo;0;L;;;;;N;;;;;\n16800;BAMUM LETTER PHASE-A NGKUE MFON;Lo;0;L;;;;;N;;;;;\n16801;BAMUM LETTER PHASE-A GBIEE FON;Lo;0;L;;;;;N;;;;;\n16802;BAMUM LETTER PHASE-A PON MFON PIPAEMGBIEE;Lo;0;L;;;;;N;;;;;\n16803;BAMUM LETTER PHASE-A PON MFON PIPAEMBA;Lo;0;L;;;;;N;;;;;\n16804;BAMUM LETTER PHASE-A NAA MFON;Lo;0;L;;;;;N;;;;;\n16805;BAMUM LETTER PHASE-A SHUENSHUET;Lo;0;L;;;;;N;;;;;\n16806;BAMUM LETTER PHASE-A TITA MFON;Lo;0;L;;;;;N;;;;;\n16807;BAMUM LETTER PHASE-A NZA MFON;Lo;0;L;;;;;N;;;;;\n16808;BAMUM LETTER PHASE-A SHINDA PA NJI;Lo;0;L;;;;;N;;;;;\n16809;BAMUM LETTER PHASE-A PON PA NJI PIPAEMGBIEE;Lo;0;L;;;;;N;;;;;\n1680A;BAMUM LETTER PHASE-A PON PA NJI PIPAEMBA;Lo;0;L;;;;;N;;;;;\n1680B;BAMUM LETTER PHASE-A MAEMBGBIEE;Lo;0;L;;;;;N;;;;;\n1680C;BAMUM LETTER PHASE-A TU MAEMBA;Lo;0;L;;;;;N;;;;;\n1680D;BAMUM LETTER PHASE-A NGANGU;Lo;0;L;;;;;N;;;;;\n1680E;BAMUM LETTER PHASE-A MAEMVEUX;Lo;0;L;;;;;N;;;;;\n1680F;BAMUM LETTER PHASE-A MANSUAE;Lo;0;L;;;;;N;;;;;\n16810;BAMUM LETTER PHASE-A MVEUAENGAM;Lo;0;L;;;;;N;;;;;\n16811;BAMUM LETTER PHASE-A SEUNYAM;Lo;0;L;;;;;N;;;;;\n16812;BAMUM LETTER PHASE-A NTOQPEN;Lo;0;L;;;;;N;;;;;\n16813;BAMUM LETTER PHASE-A KEUKEUTNDA;Lo;0;L;;;;;N;;;;;\n16814;BAMUM LETTER PHASE-A NKINDI;Lo;0;L;;;;;N;;;;;\n16815;BAMUM LETTER PHASE-A SUU;Lo;0;L;;;;;N;;;;;\n16816;BAMUM LETTER PHASE-A NGKUENZEUM;Lo;0;L;;;;;N;;;;;\n16817;BAMUM LETTER PHASE-A LAPAQ;Lo;0;L;;;;;N;;;;;\n16818;BAMUM LETTER PHASE-A LET KUT;Lo;0;L;;;;;N;;;;;\n16819;BAMUM LETTER PHASE-A NTAP MFAA;Lo;0;L;;;;;N;;;;;\n1681A;BAMUM LETTER PHASE-A MAEKEUP;Lo;0;L;;;;;N;;;;;\n1681B;BAMUM LETTER PHASE-A PASHAE;Lo;0;L;;;;;N;;;;;\n1681C;BAMUM LETTER PHASE-A GHEUAERAE;Lo;0;L;;;;;N;;;;;\n1681D;BAMUM LETTER PHASE-A PAMSHAE;Lo;0;L;;;;;N;;;;;\n1681E;BAMUM LETTER PHASE-A MON NGGEUAET;Lo;0;L;;;;;N;;;;;\n1681F;BAMUM LETTER PHASE-A NZUN MEUT;Lo;0;L;;;;;N;;;;;\n16820;BAMUM LETTER PHASE-A U YUQ NAE;Lo;0;L;;;;;N;;;;;\n16821;BAMUM LETTER PHASE-A GHEUAEGHEUAE;Lo;0;L;;;;;N;;;;;\n16822;BAMUM LETTER PHASE-A NTAP NTAA;Lo;0;L;;;;;N;;;;;\n16823;BAMUM LETTER PHASE-A SISA;Lo;0;L;;;;;N;;;;;\n16824;BAMUM LETTER PHASE-A MGBASA;Lo;0;L;;;;;N;;;;;\n16825;BAMUM LETTER PHASE-A MEUNJOMNDEUQ;Lo;0;L;;;;;N;;;;;\n16826;BAMUM LETTER PHASE-A MOOMPUQ;Lo;0;L;;;;;N;;;;;\n16827;BAMUM LETTER PHASE-A KAFA;Lo;0;L;;;;;N;;;;;\n16828;BAMUM LETTER PHASE-A PA LEERAEWA;Lo;0;L;;;;;N;;;;;\n16829;BAMUM LETTER PHASE-A NDA LEERAEWA;Lo;0;L;;;;;N;;;;;\n1682A;BAMUM LETTER PHASE-A PET;Lo;0;L;;;;;N;;;;;\n1682B;BAMUM LETTER PHASE-A MAEMKPEN;Lo;0;L;;;;;N;;;;;\n1682C;BAMUM LETTER PHASE-A NIKA;Lo;0;L;;;;;N;;;;;\n1682D;BAMUM LETTER PHASE-A PUP;Lo;0;L;;;;;N;;;;;\n1682E;BAMUM LETTER PHASE-A TUAEP;Lo;0;L;;;;;N;;;;;\n1682F;BAMUM LETTER PHASE-A LUAEP;Lo;0;L;;;;;N;;;;;\n16830;BAMUM LETTER PHASE-A SONJAM;Lo;0;L;;;;;N;;;;;\n16831;BAMUM LETTER PHASE-A TEUTEUWEN;Lo;0;L;;;;;N;;;;;\n16832;BAMUM LETTER PHASE-A MAENYI;Lo;0;L;;;;;N;;;;;\n16833;BAMUM LETTER PHASE-A KET;Lo;0;L;;;;;N;;;;;\n16834;BAMUM LETTER PHASE-A NDAANGGEUAET;Lo;0;L;;;;;N;;;;;\n16835;BAMUM LETTER PHASE-A KUOQ;Lo;0;L;;;;;N;;;;;\n16836;BAMUM LETTER PHASE-A MOOMEUT;Lo;0;L;;;;;N;;;;;\n16837;BAMUM LETTER PHASE-A SHUM;Lo;0;L;;;;;N;;;;;\n16838;BAMUM LETTER PHASE-A LOMMAE;Lo;0;L;;;;;N;;;;;\n16839;BAMUM LETTER PHASE-A FIRI;Lo;0;L;;;;;N;;;;;\n1683A;BAMUM LETTER PHASE-A ROM;Lo;0;L;;;;;N;;;;;\n1683B;BAMUM LETTER PHASE-A KPOQ;Lo;0;L;;;;;N;;;;;\n1683C;BAMUM LETTER PHASE-A SOQ;Lo;0;L;;;;;N;;;;;\n1683D;BAMUM LETTER PHASE-A MAP PIEET;Lo;0;L;;;;;N;;;;;\n1683E;BAMUM LETTER PHASE-A SHIRAE;Lo;0;L;;;;;N;;;;;\n1683F;BAMUM LETTER PHASE-A NTAP;Lo;0;L;;;;;N;;;;;\n16840;BAMUM LETTER PHASE-A SHOQ NSHUT YUM;Lo;0;L;;;;;N;;;;;\n16841;BAMUM LETTER PHASE-A NYIT MONGKEUAEQ;Lo;0;L;;;;;N;;;;;\n16842;BAMUM LETTER PHASE-A PAARAE;Lo;0;L;;;;;N;;;;;\n16843;BAMUM LETTER PHASE-A NKAARAE;Lo;0;L;;;;;N;;;;;\n16844;BAMUM LETTER PHASE-A UNKNOWN;Lo;0;L;;;;;N;;;;;\n16845;BAMUM LETTER PHASE-A NGGEN;Lo;0;L;;;;;N;;;;;\n16846;BAMUM LETTER PHASE-A MAESI;Lo;0;L;;;;;N;;;;;\n16847;BAMUM LETTER PHASE-A NJAM;Lo;0;L;;;;;N;;;;;\n16848;BAMUM LETTER PHASE-A MBANYI;Lo;0;L;;;;;N;;;;;\n16849;BAMUM LETTER PHASE-A NYET;Lo;0;L;;;;;N;;;;;\n1684A;BAMUM LETTER PHASE-A TEUAEN;Lo;0;L;;;;;N;;;;;\n1684B;BAMUM LETTER PHASE-A SOT;Lo;0;L;;;;;N;;;;;\n1684C;BAMUM LETTER PHASE-A PAAM;Lo;0;L;;;;;N;;;;;\n1684D;BAMUM LETTER PHASE-A NSHIEE;Lo;0;L;;;;;N;;;;;\n1684E;BAMUM LETTER PHASE-A MAEM;Lo;0;L;;;;;N;;;;;\n1684F;BAMUM LETTER PHASE-A NYI;Lo;0;L;;;;;N;;;;;\n16850;BAMUM LETTER PHASE-A KAQ;Lo;0;L;;;;;N;;;;;\n16851;BAMUM LETTER PHASE-A NSHA;Lo;0;L;;;;;N;;;;;\n16852;BAMUM LETTER PHASE-A VEE;Lo;0;L;;;;;N;;;;;\n16853;BAMUM LETTER PHASE-A LU;Lo;0;L;;;;;N;;;;;\n16854;BAMUM LETTER PHASE-A NEN;Lo;0;L;;;;;N;;;;;\n16855;BAMUM LETTER PHASE-A NAQ;Lo;0;L;;;;;N;;;;;\n16856;BAMUM LETTER PHASE-A MBAQ;Lo;0;L;;;;;N;;;;;\n16857;BAMUM LETTER PHASE-B NSHUET;Lo;0;L;;;;;N;;;;;\n16858;BAMUM LETTER PHASE-B TU MAEMGBIEE;Lo;0;L;;;;;N;;;;;\n16859;BAMUM LETTER PHASE-B SIEE;Lo;0;L;;;;;N;;;;;\n1685A;BAMUM LETTER PHASE-B SET TU;Lo;0;L;;;;;N;;;;;\n1685B;BAMUM LETTER PHASE-B LOM NTEUM;Lo;0;L;;;;;N;;;;;\n1685C;BAMUM LETTER PHASE-B MBA MAELEE;Lo;0;L;;;;;N;;;;;\n1685D;BAMUM LETTER PHASE-B KIEEM;Lo;0;L;;;;;N;;;;;\n1685E;BAMUM LETTER PHASE-B YEURAE;Lo;0;L;;;;;N;;;;;\n1685F;BAMUM LETTER PHASE-B MBAARAE;Lo;0;L;;;;;N;;;;;\n16860;BAMUM LETTER PHASE-B KAM;Lo;0;L;;;;;N;;;;;\n16861;BAMUM LETTER PHASE-B PEESHI;Lo;0;L;;;;;N;;;;;\n16862;BAMUM LETTER PHASE-B YAFU LEERAEWA;Lo;0;L;;;;;N;;;;;\n16863;BAMUM LETTER PHASE-B LAM NSHUT NYAM;Lo;0;L;;;;;N;;;;;\n16864;BAMUM LETTER PHASE-B NTIEE SHEUOQ;Lo;0;L;;;;;N;;;;;\n16865;BAMUM LETTER PHASE-B NDU NJAA;Lo;0;L;;;;;N;;;;;\n16866;BAMUM LETTER PHASE-B GHEUGHEUAEM;Lo;0;L;;;;;N;;;;;\n16867;BAMUM LETTER PHASE-B PIT;Lo;0;L;;;;;N;;;;;\n16868;BAMUM LETTER PHASE-B TU NSIEE;Lo;0;L;;;;;N;;;;;\n16869;BAMUM LETTER PHASE-B SHET NJAQ;Lo;0;L;;;;;N;;;;;\n1686A;BAMUM LETTER PHASE-B SHEUAEQTU;Lo;0;L;;;;;N;;;;;\n1686B;BAMUM LETTER PHASE-B MFON TEUAEQ;Lo;0;L;;;;;N;;;;;\n1686C;BAMUM LETTER PHASE-B MBIT MBAAKET;Lo;0;L;;;;;N;;;;;\n1686D;BAMUM LETTER PHASE-B NYI NTEUM;Lo;0;L;;;;;N;;;;;\n1686E;BAMUM LETTER PHASE-B KEUPUQ;Lo;0;L;;;;;N;;;;;\n1686F;BAMUM LETTER PHASE-B GHEUGHEN;Lo;0;L;;;;;N;;;;;\n16870;BAMUM LETTER PHASE-B KEUYEUX;Lo;0;L;;;;;N;;;;;\n16871;BAMUM LETTER PHASE-B LAANAE;Lo;0;L;;;;;N;;;;;\n16872;BAMUM LETTER PHASE-B PARUM;Lo;0;L;;;;;N;;;;;\n16873;BAMUM LETTER PHASE-B VEUM;Lo;0;L;;;;;N;;;;;\n16874;BAMUM LETTER PHASE-B NGKINDI MVOP;Lo;0;L;;;;;N;;;;;\n16875;BAMUM LETTER PHASE-B NGGEU MBU;Lo;0;L;;;;;N;;;;;\n16876;BAMUM LETTER PHASE-B WUAET;Lo;0;L;;;;;N;;;;;\n16877;BAMUM LETTER PHASE-B SAKEUAE;Lo;0;L;;;;;N;;;;;\n16878;BAMUM LETTER PHASE-B TAAM;Lo;0;L;;;;;N;;;;;\n16879;BAMUM LETTER PHASE-B MEUQ;Lo;0;L;;;;;N;;;;;\n1687A;BAMUM LETTER PHASE-B NGGUOQ;Lo;0;L;;;;;N;;;;;\n1687B;BAMUM LETTER PHASE-B NGGUOQ LARGE;Lo;0;L;;;;;N;;;;;\n1687C;BAMUM LETTER PHASE-B MFIYAQ;Lo;0;L;;;;;N;;;;;\n1687D;BAMUM LETTER PHASE-B SUE;Lo;0;L;;;;;N;;;;;\n1687E;BAMUM LETTER PHASE-B MBEURI;Lo;0;L;;;;;N;;;;;\n1687F;BAMUM LETTER PHASE-B MONTIEEN;Lo;0;L;;;;;N;;;;;\n16880;BAMUM LETTER PHASE-B NYAEMAE;Lo;0;L;;;;;N;;;;;\n16881;BAMUM LETTER PHASE-B PUNGAAM;Lo;0;L;;;;;N;;;;;\n16882;BAMUM LETTER PHASE-B MEUT NGGEET;Lo;0;L;;;;;N;;;;;\n16883;BAMUM LETTER PHASE-B FEUX;Lo;0;L;;;;;N;;;;;\n16884;BAMUM LETTER PHASE-B MBUOQ;Lo;0;L;;;;;N;;;;;\n16885;BAMUM LETTER PHASE-B FEE;Lo;0;L;;;;;N;;;;;\n16886;BAMUM LETTER PHASE-B KEUAEM;Lo;0;L;;;;;N;;;;;\n16887;BAMUM LETTER PHASE-B MA NJEUAENA;Lo;0;L;;;;;N;;;;;\n16888;BAMUM LETTER PHASE-B MA NJUQA;Lo;0;L;;;;;N;;;;;\n16889;BAMUM LETTER PHASE-B LET;Lo;0;L;;;;;N;;;;;\n1688A;BAMUM LETTER PHASE-B NGGAAM;Lo;0;L;;;;;N;;;;;\n1688B;BAMUM LETTER PHASE-B NSEN;Lo;0;L;;;;;N;;;;;\n1688C;BAMUM LETTER PHASE-B MA;Lo;0;L;;;;;N;;;;;\n1688D;BAMUM LETTER PHASE-B KIQ;Lo;0;L;;;;;N;;;;;\n1688E;BAMUM LETTER PHASE-B NGOM;Lo;0;L;;;;;N;;;;;\n1688F;BAMUM LETTER PHASE-C NGKUE MAEMBA;Lo;0;L;;;;;N;;;;;\n16890;BAMUM LETTER PHASE-C NZA;Lo;0;L;;;;;N;;;;;\n16891;BAMUM LETTER PHASE-C YUM;Lo;0;L;;;;;N;;;;;\n16892;BAMUM LETTER PHASE-C WANGKUOQ;Lo;0;L;;;;;N;;;;;\n16893;BAMUM LETTER PHASE-C NGGEN;Lo;0;L;;;;;N;;;;;\n16894;BAMUM LETTER PHASE-C NDEUAEREE;Lo;0;L;;;;;N;;;;;\n16895;BAMUM LETTER PHASE-C NGKAQ;Lo;0;L;;;;;N;;;;;\n16896;BAMUM LETTER PHASE-C GHARAE;Lo;0;L;;;;;N;;;;;\n16897;BAMUM LETTER PHASE-C MBEEKEET;Lo;0;L;;;;;N;;;;;\n16898;BAMUM LETTER PHASE-C GBAYI;Lo;0;L;;;;;N;;;;;\n16899;BAMUM LETTER PHASE-C NYIR MKPARAQ MEUN;Lo;0;L;;;;;N;;;;;\n1689A;BAMUM LETTER PHASE-C NTU MBIT;Lo;0;L;;;;;N;;;;;\n1689B;BAMUM LETTER PHASE-C MBEUM;Lo;0;L;;;;;N;;;;;\n1689C;BAMUM LETTER PHASE-C PIRIEEN;Lo;0;L;;;;;N;;;;;\n1689D;BAMUM LETTER PHASE-C NDOMBU;Lo;0;L;;;;;N;;;;;\n1689E;BAMUM LETTER PHASE-C MBAA CABBAGE-TREE;Lo;0;L;;;;;N;;;;;\n1689F;BAMUM LETTER PHASE-C KEUSHEUAEP;Lo;0;L;;;;;N;;;;;\n168A0;BAMUM LETTER PHASE-C GHAP;Lo;0;L;;;;;N;;;;;\n168A1;BAMUM LETTER PHASE-C KEUKAQ;Lo;0;L;;;;;N;;;;;\n168A2;BAMUM LETTER PHASE-C YU MUOMAE;Lo;0;L;;;;;N;;;;;\n168A3;BAMUM LETTER PHASE-C NZEUM;Lo;0;L;;;;;N;;;;;\n168A4;BAMUM LETTER PHASE-C MBUE;Lo;0;L;;;;;N;;;;;\n168A5;BAMUM LETTER PHASE-C NSEUAEN;Lo;0;L;;;;;N;;;;;\n168A6;BAMUM LETTER PHASE-C MBIT;Lo;0;L;;;;;N;;;;;\n168A7;BAMUM LETTER PHASE-C YEUQ;Lo;0;L;;;;;N;;;;;\n168A8;BAMUM LETTER PHASE-C KPARAQ;Lo;0;L;;;;;N;;;;;\n168A9;BAMUM LETTER PHASE-C KAA;Lo;0;L;;;;;N;;;;;\n168AA;BAMUM LETTER PHASE-C SEUX;Lo;0;L;;;;;N;;;;;\n168AB;BAMUM LETTER PHASE-C NDIDA;Lo;0;L;;;;;N;;;;;\n168AC;BAMUM LETTER PHASE-C TAASHAE;Lo;0;L;;;;;N;;;;;\n168AD;BAMUM LETTER PHASE-C NJUEQ;Lo;0;L;;;;;N;;;;;\n168AE;BAMUM LETTER PHASE-C TITA YUE;Lo;0;L;;;;;N;;;;;\n168AF;BAMUM LETTER PHASE-C SUAET;Lo;0;L;;;;;N;;;;;\n168B0;BAMUM LETTER PHASE-C NGGUAEN NYAM;Lo;0;L;;;;;N;;;;;\n168B1;BAMUM LETTER PHASE-C VEUX;Lo;0;L;;;;;N;;;;;\n168B2;BAMUM LETTER PHASE-C NANSANAQ;Lo;0;L;;;;;N;;;;;\n168B3;BAMUM LETTER PHASE-C MA KEUAERI;Lo;0;L;;;;;N;;;;;\n168B4;BAMUM LETTER PHASE-C NTAA;Lo;0;L;;;;;N;;;;;\n168B5;BAMUM LETTER PHASE-C NGGUON;Lo;0;L;;;;;N;;;;;\n168B6;BAMUM LETTER PHASE-C LAP;Lo;0;L;;;;;N;;;;;\n168B7;BAMUM LETTER PHASE-C MBIRIEEN;Lo;0;L;;;;;N;;;;;\n168B8;BAMUM LETTER PHASE-C MGBASAQ;Lo;0;L;;;;;N;;;;;\n168B9;BAMUM LETTER PHASE-C NTEUNGBA;Lo;0;L;;;;;N;;;;;\n168BA;BAMUM LETTER PHASE-C TEUTEUX;Lo;0;L;;;;;N;;;;;\n168BB;BAMUM LETTER PHASE-C NGGUM;Lo;0;L;;;;;N;;;;;\n168BC;BAMUM LETTER PHASE-C FUE;Lo;0;L;;;;;N;;;;;\n168BD;BAMUM LETTER PHASE-C NDEUT;Lo;0;L;;;;;N;;;;;\n168BE;BAMUM LETTER PHASE-C NSA;Lo;0;L;;;;;N;;;;;\n168BF;BAMUM LETTER PHASE-C NSHAQ;Lo;0;L;;;;;N;;;;;\n168C0;BAMUM LETTER PHASE-C BUNG;Lo;0;L;;;;;N;;;;;\n168C1;BAMUM LETTER PHASE-C VEUAEPEN;Lo;0;L;;;;;N;;;;;\n168C2;BAMUM LETTER PHASE-C MBERAE;Lo;0;L;;;;;N;;;;;\n168C3;BAMUM LETTER PHASE-C RU;Lo;0;L;;;;;N;;;;;\n168C4;BAMUM LETTER PHASE-C NJAEM;Lo;0;L;;;;;N;;;;;\n168C5;BAMUM LETTER PHASE-C LAM;Lo;0;L;;;;;N;;;;;\n168C6;BAMUM LETTER PHASE-C TITUAEP;Lo;0;L;;;;;N;;;;;\n168C7;BAMUM LETTER PHASE-C NSUOT NGOM;Lo;0;L;;;;;N;;;;;\n168C8;BAMUM LETTER PHASE-C NJEEEE;Lo;0;L;;;;;N;;;;;\n168C9;BAMUM LETTER PHASE-C KET;Lo;0;L;;;;;N;;;;;\n168CA;BAMUM LETTER PHASE-C NGGU;Lo;0;L;;;;;N;;;;;\n168CB;BAMUM LETTER PHASE-C MAESI;Lo;0;L;;;;;N;;;;;\n168CC;BAMUM LETTER PHASE-C MBUAEM;Lo;0;L;;;;;N;;;;;\n168CD;BAMUM LETTER PHASE-C LU;Lo;0;L;;;;;N;;;;;\n168CE;BAMUM LETTER PHASE-C KUT;Lo;0;L;;;;;N;;;;;\n168CF;BAMUM LETTER PHASE-C NJAM;Lo;0;L;;;;;N;;;;;\n168D0;BAMUM LETTER PHASE-C NGOM;Lo;0;L;;;;;N;;;;;\n168D1;BAMUM LETTER PHASE-C WUP;Lo;0;L;;;;;N;;;;;\n168D2;BAMUM LETTER PHASE-C NGGUEET;Lo;0;L;;;;;N;;;;;\n168D3;BAMUM LETTER PHASE-C NSOM;Lo;0;L;;;;;N;;;;;\n168D4;BAMUM LETTER PHASE-C NTEN;Lo;0;L;;;;;N;;;;;\n168D5;BAMUM LETTER PHASE-C KUOP NKAARAE;Lo;0;L;;;;;N;;;;;\n168D6;BAMUM LETTER PHASE-C NSUN;Lo;0;L;;;;;N;;;;;\n168D7;BAMUM LETTER PHASE-C NDAM;Lo;0;L;;;;;N;;;;;\n168D8;BAMUM LETTER PHASE-C MA NSIEE;Lo;0;L;;;;;N;;;;;\n168D9;BAMUM LETTER PHASE-C YAA;Lo;0;L;;;;;N;;;;;\n168DA;BAMUM LETTER PHASE-C NDAP;Lo;0;L;;;;;N;;;;;\n168DB;BAMUM LETTER PHASE-C SHUEQ;Lo;0;L;;;;;N;;;;;\n168DC;BAMUM LETTER PHASE-C SETFON;Lo;0;L;;;;;N;;;;;\n168DD;BAMUM LETTER PHASE-C MBI;Lo;0;L;;;;;N;;;;;\n168DE;BAMUM LETTER PHASE-C MAEMBA;Lo;0;L;;;;;N;;;;;\n168DF;BAMUM LETTER PHASE-C MBANYI;Lo;0;L;;;;;N;;;;;\n168E0;BAMUM LETTER PHASE-C KEUSEUX;Lo;0;L;;;;;N;;;;;\n168E1;BAMUM LETTER PHASE-C MBEUX;Lo;0;L;;;;;N;;;;;\n168E2;BAMUM LETTER PHASE-C KEUM;Lo;0;L;;;;;N;;;;;\n168E3;BAMUM LETTER PHASE-C MBAA PICKET;Lo;0;L;;;;;N;;;;;\n168E4;BAMUM LETTER PHASE-C YUWOQ;Lo;0;L;;;;;N;;;;;\n168E5;BAMUM LETTER PHASE-C NJEUX;Lo;0;L;;;;;N;;;;;\n168E6;BAMUM LETTER PHASE-C MIEE;Lo;0;L;;;;;N;;;;;\n168E7;BAMUM LETTER PHASE-C MUAE;Lo;0;L;;;;;N;;;;;\n168E8;BAMUM LETTER PHASE-C SHIQ;Lo;0;L;;;;;N;;;;;\n168E9;BAMUM LETTER PHASE-C KEN LAW;Lo;0;L;;;;;N;;;;;\n168EA;BAMUM LETTER PHASE-C KEN FATIGUE;Lo;0;L;;;;;N;;;;;\n168EB;BAMUM LETTER PHASE-C NGAQ;Lo;0;L;;;;;N;;;;;\n168EC;BAMUM LETTER PHASE-C NAQ;Lo;0;L;;;;;N;;;;;\n168ED;BAMUM LETTER PHASE-C LIQ;Lo;0;L;;;;;N;;;;;\n168EE;BAMUM LETTER PHASE-C PIN;Lo;0;L;;;;;N;;;;;\n168EF;BAMUM LETTER PHASE-C PEN;Lo;0;L;;;;;N;;;;;\n168F0;BAMUM LETTER PHASE-C TET;Lo;0;L;;;;;N;;;;;\n168F1;BAMUM LETTER PHASE-D MBUO;Lo;0;L;;;;;N;;;;;\n168F2;BAMUM LETTER PHASE-D WAP;Lo;0;L;;;;;N;;;;;\n168F3;BAMUM LETTER PHASE-D NJI;Lo;0;L;;;;;N;;;;;\n168F4;BAMUM LETTER PHASE-D MFON;Lo;0;L;;;;;N;;;;;\n168F5;BAMUM LETTER PHASE-D NJIEE;Lo;0;L;;;;;N;;;;;\n168F6;BAMUM LETTER PHASE-D LIEE;Lo;0;L;;;;;N;;;;;\n168F7;BAMUM LETTER PHASE-D NJEUT;Lo;0;L;;;;;N;;;;;\n168F8;BAMUM LETTER PHASE-D NSHEE;Lo;0;L;;;;;N;;;;;\n168F9;BAMUM LETTER PHASE-D NGGAAMAE;Lo;0;L;;;;;N;;;;;\n168FA;BAMUM LETTER PHASE-D NYAM;Lo;0;L;;;;;N;;;;;\n168FB;BAMUM LETTER PHASE-D WUAEN;Lo;0;L;;;;;N;;;;;\n168FC;BAMUM LETTER PHASE-D NGKUN;Lo;0;L;;;;;N;;;;;\n168FD;BAMUM LETTER PHASE-D SHEE;Lo;0;L;;;;;N;;;;;\n168FE;BAMUM LETTER PHASE-D NGKAP;Lo;0;L;;;;;N;;;;;\n168FF;BAMUM LETTER PHASE-D KEUAETMEUN;Lo;0;L;;;;;N;;;;;\n16900;BAMUM LETTER PHASE-D TEUT;Lo;0;L;;;;;N;;;;;\n16901;BAMUM LETTER PHASE-D SHEUAE;Lo;0;L;;;;;N;;;;;\n16902;BAMUM LETTER PHASE-D NJAP;Lo;0;L;;;;;N;;;;;\n16903;BAMUM LETTER PHASE-D SUE;Lo;0;L;;;;;N;;;;;\n16904;BAMUM LETTER PHASE-D KET;Lo;0;L;;;;;N;;;;;\n16905;BAMUM LETTER PHASE-D YAEMMAE;Lo;0;L;;;;;N;;;;;\n16906;BAMUM LETTER PHASE-D KUOM;Lo;0;L;;;;;N;;;;;\n16907;BAMUM LETTER PHASE-D SAP;Lo;0;L;;;;;N;;;;;\n16908;BAMUM LETTER PHASE-D MFEUT;Lo;0;L;;;;;N;;;;;\n16909;BAMUM LETTER PHASE-D NDEUX;Lo;0;L;;;;;N;;;;;\n1690A;BAMUM LETTER PHASE-D MALEERI;Lo;0;L;;;;;N;;;;;\n1690B;BAMUM LETTER PHASE-D MEUT;Lo;0;L;;;;;N;;;;;\n1690C;BAMUM LETTER PHASE-D SEUAEQ;Lo;0;L;;;;;N;;;;;\n1690D;BAMUM LETTER PHASE-D YEN;Lo;0;L;;;;;N;;;;;\n1690E;BAMUM LETTER PHASE-D NJEUAEM;Lo;0;L;;;;;N;;;;;\n1690F;BAMUM LETTER PHASE-D KEUOT MBUAE;Lo;0;L;;;;;N;;;;;\n16910;BAMUM LETTER PHASE-D NGKEURI;Lo;0;L;;;;;N;;;;;\n16911;BAMUM LETTER PHASE-D TU;Lo;0;L;;;;;N;;;;;\n16912;BAMUM LETTER PHASE-D GHAA;Lo;0;L;;;;;N;;;;;\n16913;BAMUM LETTER PHASE-D NGKYEE;Lo;0;L;;;;;N;;;;;\n16914;BAMUM LETTER PHASE-D FEUFEUAET;Lo;0;L;;;;;N;;;;;\n16915;BAMUM LETTER PHASE-D NDEE;Lo;0;L;;;;;N;;;;;\n16916;BAMUM LETTER PHASE-D MGBOFUM;Lo;0;L;;;;;N;;;;;\n16917;BAMUM LETTER PHASE-D LEUAEP;Lo;0;L;;;;;N;;;;;\n16918;BAMUM LETTER PHASE-D NDON;Lo;0;L;;;;;N;;;;;\n16919;BAMUM LETTER PHASE-D MONI;Lo;0;L;;;;;N;;;;;\n1691A;BAMUM LETTER PHASE-D MGBEUN;Lo;0;L;;;;;N;;;;;\n1691B;BAMUM LETTER PHASE-D PUUT;Lo;0;L;;;;;N;;;;;\n1691C;BAMUM LETTER PHASE-D MGBIEE;Lo;0;L;;;;;N;;;;;\n1691D;BAMUM LETTER PHASE-D MFO;Lo;0;L;;;;;N;;;;;\n1691E;BAMUM LETTER PHASE-D LUM;Lo;0;L;;;;;N;;;;;\n1691F;BAMUM LETTER PHASE-D NSIEEP;Lo;0;L;;;;;N;;;;;\n16920;BAMUM LETTER PHASE-D MBAA;Lo;0;L;;;;;N;;;;;\n16921;BAMUM LETTER PHASE-D KWAET;Lo;0;L;;;;;N;;;;;\n16922;BAMUM LETTER PHASE-D NYET;Lo;0;L;;;;;N;;;;;\n16923;BAMUM LETTER PHASE-D TEUAEN;Lo;0;L;;;;;N;;;;;\n16924;BAMUM LETTER PHASE-D SOT;Lo;0;L;;;;;N;;;;;\n16925;BAMUM LETTER PHASE-D YUWOQ;Lo;0;L;;;;;N;;;;;\n16926;BAMUM LETTER PHASE-D KEUM;Lo;0;L;;;;;N;;;;;\n16927;BAMUM LETTER PHASE-D RAEM;Lo;0;L;;;;;N;;;;;\n16928;BAMUM LETTER PHASE-D TEEEE;Lo;0;L;;;;;N;;;;;\n16929;BAMUM LETTER PHASE-D NGKEUAEQ;Lo;0;L;;;;;N;;;;;\n1692A;BAMUM LETTER PHASE-D MFEUAE;Lo;0;L;;;;;N;;;;;\n1692B;BAMUM LETTER PHASE-D NSIEET;Lo;0;L;;;;;N;;;;;\n1692C;BAMUM LETTER PHASE-D KEUP;Lo;0;L;;;;;N;;;;;\n1692D;BAMUM LETTER PHASE-D PIP;Lo;0;L;;;;;N;;;;;\n1692E;BAMUM LETTER PHASE-D PEUTAE;Lo;0;L;;;;;N;;;;;\n1692F;BAMUM LETTER PHASE-D NYUE;Lo;0;L;;;;;N;;;;;\n16930;BAMUM LETTER PHASE-D LET;Lo;0;L;;;;;N;;;;;\n16931;BAMUM LETTER PHASE-D NGGAAM;Lo;0;L;;;;;N;;;;;\n16932;BAMUM LETTER PHASE-D MFIEE;Lo;0;L;;;;;N;;;;;\n16933;BAMUM LETTER PHASE-D NGGWAEN;Lo;0;L;;;;;N;;;;;\n16934;BAMUM LETTER PHASE-D YUOM;Lo;0;L;;;;;N;;;;;\n16935;BAMUM LETTER PHASE-D PAP;Lo;0;L;;;;;N;;;;;\n16936;BAMUM LETTER PHASE-D YUOP;Lo;0;L;;;;;N;;;;;\n16937;BAMUM LETTER PHASE-D NDAM;Lo;0;L;;;;;N;;;;;\n16938;BAMUM LETTER PHASE-D NTEUM;Lo;0;L;;;;;N;;;;;\n16939;BAMUM LETTER PHASE-D SUAE;Lo;0;L;;;;;N;;;;;\n1693A;BAMUM LETTER PHASE-D KUN;Lo;0;L;;;;;N;;;;;\n1693B;BAMUM LETTER PHASE-D NGGEUX;Lo;0;L;;;;;N;;;;;\n1693C;BAMUM LETTER PHASE-D NGKIEE;Lo;0;L;;;;;N;;;;;\n1693D;BAMUM LETTER PHASE-D TUOT;Lo;0;L;;;;;N;;;;;\n1693E;BAMUM LETTER PHASE-D MEUN;Lo;0;L;;;;;N;;;;;\n1693F;BAMUM LETTER PHASE-D KUQ;Lo;0;L;;;;;N;;;;;\n16940;BAMUM LETTER PHASE-D NSUM;Lo;0;L;;;;;N;;;;;\n16941;BAMUM LETTER PHASE-D TEUN;Lo;0;L;;;;;N;;;;;\n16942;BAMUM LETTER PHASE-D MAENJET;Lo;0;L;;;;;N;;;;;\n16943;BAMUM LETTER PHASE-D NGGAP;Lo;0;L;;;;;N;;;;;\n16944;BAMUM LETTER PHASE-D LEUM;Lo;0;L;;;;;N;;;;;\n16945;BAMUM LETTER PHASE-D NGGUOM;Lo;0;L;;;;;N;;;;;\n16946;BAMUM LETTER PHASE-D NSHUT;Lo;0;L;;;;;N;;;;;\n16947;BAMUM LETTER PHASE-D NJUEQ;Lo;0;L;;;;;N;;;;;\n16948;BAMUM LETTER PHASE-D GHEUAE;Lo;0;L;;;;;N;;;;;\n16949;BAMUM LETTER PHASE-D KU;Lo;0;L;;;;;N;;;;;\n1694A;BAMUM LETTER PHASE-D REN OLD;Lo;0;L;;;;;N;;;;;\n1694B;BAMUM LETTER PHASE-D TAE;Lo;0;L;;;;;N;;;;;\n1694C;BAMUM LETTER PHASE-D TOQ;Lo;0;L;;;;;N;;;;;\n1694D;BAMUM LETTER PHASE-D NYI;Lo;0;L;;;;;N;;;;;\n1694E;BAMUM LETTER PHASE-D RII;Lo;0;L;;;;;N;;;;;\n1694F;BAMUM LETTER PHASE-D LEEEE;Lo;0;L;;;;;N;;;;;\n16950;BAMUM LETTER PHASE-D MEEEE;Lo;0;L;;;;;N;;;;;\n16951;BAMUM LETTER PHASE-D M;Lo;0;L;;;;;N;;;;;\n16952;BAMUM LETTER PHASE-D SUU;Lo;0;L;;;;;N;;;;;\n16953;BAMUM LETTER PHASE-D MU;Lo;0;L;;;;;N;;;;;\n16954;BAMUM LETTER PHASE-D SHII;Lo;0;L;;;;;N;;;;;\n16955;BAMUM LETTER PHASE-D SHEUX;Lo;0;L;;;;;N;;;;;\n16956;BAMUM LETTER PHASE-D KYEE;Lo;0;L;;;;;N;;;;;\n16957;BAMUM LETTER PHASE-D NU;Lo;0;L;;;;;N;;;;;\n16958;BAMUM LETTER PHASE-D SHU;Lo;0;L;;;;;N;;;;;\n16959;BAMUM LETTER PHASE-D NTEE;Lo;0;L;;;;;N;;;;;\n1695A;BAMUM LETTER PHASE-D PEE;Lo;0;L;;;;;N;;;;;\n1695B;BAMUM LETTER PHASE-D NI;Lo;0;L;;;;;N;;;;;\n1695C;BAMUM LETTER PHASE-D SHOQ;Lo;0;L;;;;;N;;;;;\n1695D;BAMUM LETTER PHASE-D PUQ;Lo;0;L;;;;;N;;;;;\n1695E;BAMUM LETTER PHASE-D MVOP;Lo;0;L;;;;;N;;;;;\n1695F;BAMUM LETTER PHASE-D LOQ;Lo;0;L;;;;;N;;;;;\n16960;BAMUM LETTER PHASE-D REN MUCH;Lo;0;L;;;;;N;;;;;\n16961;BAMUM LETTER PHASE-D TI;Lo;0;L;;;;;N;;;;;\n16962;BAMUM LETTER PHASE-D NTUU;Lo;0;L;;;;;N;;;;;\n16963;BAMUM LETTER PHASE-D MBAA SEVEN;Lo;0;L;;;;;N;;;;;\n16964;BAMUM LETTER PHASE-D SAQ;Lo;0;L;;;;;N;;;;;\n16965;BAMUM LETTER PHASE-D FAA;Lo;0;L;;;;;N;;;;;\n16966;BAMUM LETTER PHASE-E NDAP;Lo;0;L;;;;;N;;;;;\n16967;BAMUM LETTER PHASE-E TOON;Lo;0;L;;;;;N;;;;;\n16968;BAMUM LETTER PHASE-E MBEUM;Lo;0;L;;;;;N;;;;;\n16969;BAMUM LETTER PHASE-E LAP;Lo;0;L;;;;;N;;;;;\n1696A;BAMUM LETTER PHASE-E VOM;Lo;0;L;;;;;N;;;;;\n1696B;BAMUM LETTER PHASE-E LOON;Lo;0;L;;;;;N;;;;;\n1696C;BAMUM LETTER PHASE-E PAA;Lo;0;L;;;;;N;;;;;\n1696D;BAMUM LETTER PHASE-E SOM;Lo;0;L;;;;;N;;;;;\n1696E;BAMUM LETTER PHASE-E RAQ;Lo;0;L;;;;;N;;;;;\n1696F;BAMUM LETTER PHASE-E NSHUOP;Lo;0;L;;;;;N;;;;;\n16970;BAMUM LETTER PHASE-E NDUN;Lo;0;L;;;;;N;;;;;\n16971;BAMUM LETTER PHASE-E PUAE;Lo;0;L;;;;;N;;;;;\n16972;BAMUM LETTER PHASE-E TAM;Lo;0;L;;;;;N;;;;;\n16973;BAMUM LETTER PHASE-E NGKA;Lo;0;L;;;;;N;;;;;\n16974;BAMUM LETTER PHASE-E KPEUX;Lo;0;L;;;;;N;;;;;\n16975;BAMUM LETTER PHASE-E WUO;Lo;0;L;;;;;N;;;;;\n16976;BAMUM LETTER PHASE-E SEE;Lo;0;L;;;;;N;;;;;\n16977;BAMUM LETTER PHASE-E NGGEUAET;Lo;0;L;;;;;N;;;;;\n16978;BAMUM LETTER PHASE-E PAAM;Lo;0;L;;;;;N;;;;;\n16979;BAMUM LETTER PHASE-E TOO;Lo;0;L;;;;;N;;;;;\n1697A;BAMUM LETTER PHASE-E KUOP;Lo;0;L;;;;;N;;;;;\n1697B;BAMUM LETTER PHASE-E LOM;Lo;0;L;;;;;N;;;;;\n1697C;BAMUM LETTER PHASE-E NSHIEE;Lo;0;L;;;;;N;;;;;\n1697D;BAMUM LETTER PHASE-E NGOP;Lo;0;L;;;;;N;;;;;\n1697E;BAMUM LETTER PHASE-E MAEM;Lo;0;L;;;;;N;;;;;\n1697F;BAMUM LETTER PHASE-E NGKEUX;Lo;0;L;;;;;N;;;;;\n16980;BAMUM LETTER PHASE-E NGOQ;Lo;0;L;;;;;N;;;;;\n16981;BAMUM LETTER PHASE-E NSHUE;Lo;0;L;;;;;N;;;;;\n16982;BAMUM LETTER PHASE-E RIMGBA;Lo;0;L;;;;;N;;;;;\n16983;BAMUM LETTER PHASE-E NJEUX;Lo;0;L;;;;;N;;;;;\n16984;BAMUM LETTER PHASE-E PEEM;Lo;0;L;;;;;N;;;;;\n16985;BAMUM LETTER PHASE-E SAA;Lo;0;L;;;;;N;;;;;\n16986;BAMUM LETTER PHASE-E NGGURAE;Lo;0;L;;;;;N;;;;;\n16987;BAMUM LETTER PHASE-E MGBA;Lo;0;L;;;;;N;;;;;\n16988;BAMUM LETTER PHASE-E GHEUX;Lo;0;L;;;;;N;;;;;\n16989;BAMUM LETTER PHASE-E NGKEUAEM;Lo;0;L;;;;;N;;;;;\n1698A;BAMUM LETTER PHASE-E NJAEMLI;Lo;0;L;;;;;N;;;;;\n1698B;BAMUM LETTER PHASE-E MAP;Lo;0;L;;;;;N;;;;;\n1698C;BAMUM LETTER PHASE-E LOOT;Lo;0;L;;;;;N;;;;;\n1698D;BAMUM LETTER PHASE-E NGGEEEE;Lo;0;L;;;;;N;;;;;\n1698E;BAMUM LETTER PHASE-E NDIQ;Lo;0;L;;;;;N;;;;;\n1698F;BAMUM LETTER PHASE-E TAEN NTEUM;Lo;0;L;;;;;N;;;;;\n16990;BAMUM LETTER PHASE-E SET;Lo;0;L;;;;;N;;;;;\n16991;BAMUM LETTER PHASE-E PUM;Lo;0;L;;;;;N;;;;;\n16992;BAMUM LETTER PHASE-E NDAA SOFTNESS;Lo;0;L;;;;;N;;;;;\n16993;BAMUM LETTER PHASE-E NGGUAESHAE NYAM;Lo;0;L;;;;;N;;;;;\n16994;BAMUM LETTER PHASE-E YIEE;Lo;0;L;;;;;N;;;;;\n16995;BAMUM LETTER PHASE-E GHEUN;Lo;0;L;;;;;N;;;;;\n16996;BAMUM LETTER PHASE-E TUAE;Lo;0;L;;;;;N;;;;;\n16997;BAMUM LETTER PHASE-E YEUAE;Lo;0;L;;;;;N;;;;;\n16998;BAMUM LETTER PHASE-E PO;Lo;0;L;;;;;N;;;;;\n16999;BAMUM LETTER PHASE-E TUMAE;Lo;0;L;;;;;N;;;;;\n1699A;BAMUM LETTER PHASE-E KEUAE;Lo;0;L;;;;;N;;;;;\n1699B;BAMUM LETTER PHASE-E SUAEN;Lo;0;L;;;;;N;;;;;\n1699C;BAMUM LETTER PHASE-E TEUAEQ;Lo;0;L;;;;;N;;;;;\n1699D;BAMUM LETTER PHASE-E VEUAE;Lo;0;L;;;;;N;;;;;\n1699E;BAMUM LETTER PHASE-E WEUX;Lo;0;L;;;;;N;;;;;\n1699F;BAMUM LETTER PHASE-E LAAM;Lo;0;L;;;;;N;;;;;\n169A0;BAMUM LETTER PHASE-E PU;Lo;0;L;;;;;N;;;;;\n169A1;BAMUM LETTER PHASE-E TAAQ;Lo;0;L;;;;;N;;;;;\n169A2;BAMUM LETTER PHASE-E GHAAMAE;Lo;0;L;;;;;N;;;;;\n169A3;BAMUM LETTER PHASE-E NGEUREUT;Lo;0;L;;;;;N;;;;;\n169A4;BAMUM LETTER PHASE-E SHEUAEQ;Lo;0;L;;;;;N;;;;;\n169A5;BAMUM LETTER PHASE-E MGBEN;Lo;0;L;;;;;N;;;;;\n169A6;BAMUM LETTER PHASE-E MBEE;Lo;0;L;;;;;N;;;;;\n169A7;BAMUM LETTER PHASE-E NZAQ;Lo;0;L;;;;;N;;;;;\n169A8;BAMUM LETTER PHASE-E NKOM;Lo;0;L;;;;;N;;;;;\n169A9;BAMUM LETTER PHASE-E GBET;Lo;0;L;;;;;N;;;;;\n169AA;BAMUM LETTER PHASE-E TUM;Lo;0;L;;;;;N;;;;;\n169AB;BAMUM LETTER PHASE-E KUET;Lo;0;L;;;;;N;;;;;\n169AC;BAMUM LETTER PHASE-E YAP;Lo;0;L;;;;;N;;;;;\n169AD;BAMUM LETTER PHASE-E NYI CLEAVER;Lo;0;L;;;;;N;;;;;\n169AE;BAMUM LETTER PHASE-E YIT;Lo;0;L;;;;;N;;;;;\n169AF;BAMUM LETTER PHASE-E MFEUQ;Lo;0;L;;;;;N;;;;;\n169B0;BAMUM LETTER PHASE-E NDIAQ;Lo;0;L;;;;;N;;;;;\n169B1;BAMUM LETTER PHASE-E PIEEQ;Lo;0;L;;;;;N;;;;;\n169B2;BAMUM LETTER PHASE-E YUEQ;Lo;0;L;;;;;N;;;;;\n169B3;BAMUM LETTER PHASE-E LEUAEM;Lo;0;L;;;;;N;;;;;\n169B4;BAMUM LETTER PHASE-E FUE;Lo;0;L;;;;;N;;;;;\n169B5;BAMUM LETTER PHASE-E GBEUX;Lo;0;L;;;;;N;;;;;\n169B6;BAMUM LETTER PHASE-E NGKUP;Lo;0;L;;;;;N;;;;;\n169B7;BAMUM LETTER PHASE-E KET;Lo;0;L;;;;;N;;;;;\n169B8;BAMUM LETTER PHASE-E MAE;Lo;0;L;;;;;N;;;;;\n169B9;BAMUM LETTER PHASE-E NGKAAMI;Lo;0;L;;;;;N;;;;;\n169BA;BAMUM LETTER PHASE-E GHET;Lo;0;L;;;;;N;;;;;\n169BB;BAMUM LETTER PHASE-E FA;Lo;0;L;;;;;N;;;;;\n169BC;BAMUM LETTER PHASE-E NTUM;Lo;0;L;;;;;N;;;;;\n169BD;BAMUM LETTER PHASE-E PEUT;Lo;0;L;;;;;N;;;;;\n169BE;BAMUM LETTER PHASE-E YEUM;Lo;0;L;;;;;N;;;;;\n169BF;BAMUM LETTER PHASE-E NGGEUAE;Lo;0;L;;;;;N;;;;;\n169C0;BAMUM LETTER PHASE-E NYI BETWEEN;Lo;0;L;;;;;N;;;;;\n169C1;BAMUM LETTER PHASE-E NZUQ;Lo;0;L;;;;;N;;;;;\n169C2;BAMUM LETTER PHASE-E POON;Lo;0;L;;;;;N;;;;;\n169C3;BAMUM LETTER PHASE-E MIEE;Lo;0;L;;;;;N;;;;;\n169C4;BAMUM LETTER PHASE-E FUET;Lo;0;L;;;;;N;;;;;\n169C5;BAMUM LETTER PHASE-E NAE;Lo;0;L;;;;;N;;;;;\n169C6;BAMUM LETTER PHASE-E MUAE;Lo;0;L;;;;;N;;;;;\n169C7;BAMUM LETTER PHASE-E GHEUAE;Lo;0;L;;;;;N;;;;;\n169C8;BAMUM LETTER PHASE-E FU I;Lo;0;L;;;;;N;;;;;\n169C9;BAMUM LETTER PHASE-E MVI;Lo;0;L;;;;;N;;;;;\n169CA;BAMUM LETTER PHASE-E PUAQ;Lo;0;L;;;;;N;;;;;\n169CB;BAMUM LETTER PHASE-E NGKUM;Lo;0;L;;;;;N;;;;;\n169CC;BAMUM LETTER PHASE-E KUT;Lo;0;L;;;;;N;;;;;\n169CD;BAMUM LETTER PHASE-E PIET;Lo;0;L;;;;;N;;;;;\n169CE;BAMUM LETTER PHASE-E NTAP;Lo;0;L;;;;;N;;;;;\n169CF;BAMUM LETTER PHASE-E YEUAET;Lo;0;L;;;;;N;;;;;\n169D0;BAMUM LETTER PHASE-E NGGUP;Lo;0;L;;;;;N;;;;;\n169D1;BAMUM LETTER PHASE-E PA PEOPLE;Lo;0;L;;;;;N;;;;;\n169D2;BAMUM LETTER PHASE-E FU CALL;Lo;0;L;;;;;N;;;;;\n169D3;BAMUM LETTER PHASE-E FOM;Lo;0;L;;;;;N;;;;;\n169D4;BAMUM LETTER PHASE-E NJEE;Lo;0;L;;;;;N;;;;;\n169D5;BAMUM LETTER PHASE-E A;Lo;0;L;;;;;N;;;;;\n169D6;BAMUM LETTER PHASE-E TOQ;Lo;0;L;;;;;N;;;;;\n169D7;BAMUM LETTER PHASE-E O;Lo;0;L;;;;;N;;;;;\n169D8;BAMUM LETTER PHASE-E I;Lo;0;L;;;;;N;;;;;\n169D9;BAMUM LETTER PHASE-E LAQ;Lo;0;L;;;;;N;;;;;\n169DA;BAMUM LETTER PHASE-E PA PLURAL;Lo;0;L;;;;;N;;;;;\n169DB;BAMUM LETTER PHASE-E TAA;Lo;0;L;;;;;N;;;;;\n169DC;BAMUM LETTER PHASE-E TAQ;Lo;0;L;;;;;N;;;;;\n169DD;BAMUM LETTER PHASE-E NDAA MY HOUSE;Lo;0;L;;;;;N;;;;;\n169DE;BAMUM LETTER PHASE-E SHIQ;Lo;0;L;;;;;N;;;;;\n169DF;BAMUM LETTER PHASE-E YEUX;Lo;0;L;;;;;N;;;;;\n169E0;BAMUM LETTER PHASE-E NGUAE;Lo;0;L;;;;;N;;;;;\n169E1;BAMUM LETTER PHASE-E YUAEN;Lo;0;L;;;;;N;;;;;\n169E2;BAMUM LETTER PHASE-E YOQ SWIMMING;Lo;0;L;;;;;N;;;;;\n169E3;BAMUM LETTER PHASE-E YOQ COVER;Lo;0;L;;;;;N;;;;;\n169E4;BAMUM LETTER PHASE-E YUQ;Lo;0;L;;;;;N;;;;;\n169E5;BAMUM LETTER PHASE-E YUN;Lo;0;L;;;;;N;;;;;\n169E6;BAMUM LETTER PHASE-E KEUX;Lo;0;L;;;;;N;;;;;\n169E7;BAMUM LETTER PHASE-E PEUX;Lo;0;L;;;;;N;;;;;\n169E8;BAMUM LETTER PHASE-E NJEE EPOCH;Lo;0;L;;;;;N;;;;;\n169E9;BAMUM LETTER PHASE-E PUE;Lo;0;L;;;;;N;;;;;\n169EA;BAMUM LETTER PHASE-E WUE;Lo;0;L;;;;;N;;;;;\n169EB;BAMUM LETTER PHASE-E FEE;Lo;0;L;;;;;N;;;;;\n169EC;BAMUM LETTER PHASE-E VEE;Lo;0;L;;;;;N;;;;;\n169ED;BAMUM LETTER PHASE-E LU;Lo;0;L;;;;;N;;;;;\n169EE;BAMUM LETTER PHASE-E MI;Lo;0;L;;;;;N;;;;;\n169EF;BAMUM LETTER PHASE-E REUX;Lo;0;L;;;;;N;;;;;\n169F0;BAMUM LETTER PHASE-E RAE;Lo;0;L;;;;;N;;;;;\n169F1;BAMUM LETTER PHASE-E NGUAET;Lo;0;L;;;;;N;;;;;\n169F2;BAMUM LETTER PHASE-E NGA;Lo;0;L;;;;;N;;;;;\n169F3;BAMUM LETTER PHASE-E SHO;Lo;0;L;;;;;N;;;;;\n169F4;BAMUM LETTER PHASE-E SHOQ;Lo;0;L;;;;;N;;;;;\n169F5;BAMUM LETTER PHASE-E FU REMEDY;Lo;0;L;;;;;N;;;;;\n169F6;BAMUM LETTER PHASE-E NA;Lo;0;L;;;;;N;;;;;\n169F7;BAMUM LETTER PHASE-E PI;Lo;0;L;;;;;N;;;;;\n169F8;BAMUM LETTER PHASE-E LOQ;Lo;0;L;;;;;N;;;;;\n169F9;BAMUM LETTER PHASE-E KO;Lo;0;L;;;;;N;;;;;\n169FA;BAMUM LETTER PHASE-E MEN;Lo;0;L;;;;;N;;;;;\n169FB;BAMUM LETTER PHASE-E MA;Lo;0;L;;;;;N;;;;;\n169FC;BAMUM LETTER PHASE-E MAQ;Lo;0;L;;;;;N;;;;;\n169FD;BAMUM LETTER PHASE-E TEU;Lo;0;L;;;;;N;;;;;\n169FE;BAMUM LETTER PHASE-E KI;Lo;0;L;;;;;N;;;;;\n169FF;BAMUM LETTER PHASE-E MON;Lo;0;L;;;;;N;;;;;\n16A00;BAMUM LETTER PHASE-E TEN;Lo;0;L;;;;;N;;;;;\n16A01;BAMUM LETTER PHASE-E FAQ;Lo;0;L;;;;;N;;;;;\n16A02;BAMUM LETTER PHASE-E GHOM;Lo;0;L;;;;;N;;;;;\n16A03;BAMUM LETTER PHASE-F KA;Lo;0;L;;;;;N;;;;;\n16A04;BAMUM LETTER PHASE-F U;Lo;0;L;;;;;N;;;;;\n16A05;BAMUM LETTER PHASE-F KU;Lo;0;L;;;;;N;;;;;\n16A06;BAMUM LETTER PHASE-F EE;Lo;0;L;;;;;N;;;;;\n16A07;BAMUM LETTER PHASE-F REE;Lo;0;L;;;;;N;;;;;\n16A08;BAMUM LETTER PHASE-F TAE;Lo;0;L;;;;;N;;;;;\n16A09;BAMUM LETTER PHASE-F NYI;Lo;0;L;;;;;N;;;;;\n16A0A;BAMUM LETTER PHASE-F LA;Lo;0;L;;;;;N;;;;;\n16A0B;BAMUM LETTER PHASE-F RII;Lo;0;L;;;;;N;;;;;\n16A0C;BAMUM LETTER PHASE-F RIEE;Lo;0;L;;;;;N;;;;;\n16A0D;BAMUM LETTER PHASE-F MEEEE;Lo;0;L;;;;;N;;;;;\n16A0E;BAMUM LETTER PHASE-F TAA;Lo;0;L;;;;;N;;;;;\n16A0F;BAMUM LETTER PHASE-F NDAA;Lo;0;L;;;;;N;;;;;\n16A10;BAMUM LETTER PHASE-F NJAEM;Lo;0;L;;;;;N;;;;;\n16A11;BAMUM LETTER PHASE-F M;Lo;0;L;;;;;N;;;;;\n16A12;BAMUM LETTER PHASE-F SUU;Lo;0;L;;;;;N;;;;;\n16A13;BAMUM LETTER PHASE-F SHII;Lo;0;L;;;;;N;;;;;\n16A14;BAMUM LETTER PHASE-F SI;Lo;0;L;;;;;N;;;;;\n16A15;BAMUM LETTER PHASE-F SEUX;Lo;0;L;;;;;N;;;;;\n16A16;BAMUM LETTER PHASE-F KYEE;Lo;0;L;;;;;N;;;;;\n16A17;BAMUM LETTER PHASE-F KET;Lo;0;L;;;;;N;;;;;\n16A18;BAMUM LETTER PHASE-F NUAE;Lo;0;L;;;;;N;;;;;\n16A19;BAMUM LETTER PHASE-F NU;Lo;0;L;;;;;N;;;;;\n16A1A;BAMUM LETTER PHASE-F NJUAE;Lo;0;L;;;;;N;;;;;\n16A1B;BAMUM LETTER PHASE-F YOQ;Lo;0;L;;;;;N;;;;;\n16A1C;BAMUM LETTER PHASE-F SHU;Lo;0;L;;;;;N;;;;;\n16A1D;BAMUM LETTER PHASE-F YA;Lo;0;L;;;;;N;;;;;\n16A1E;BAMUM LETTER PHASE-F NSHA;Lo;0;L;;;;;N;;;;;\n16A1F;BAMUM LETTER PHASE-F PEUX;Lo;0;L;;;;;N;;;;;\n16A20;BAMUM LETTER PHASE-F NTEE;Lo;0;L;;;;;N;;;;;\n16A21;BAMUM LETTER PHASE-F WUE;Lo;0;L;;;;;N;;;;;\n16A22;BAMUM LETTER PHASE-F PEE;Lo;0;L;;;;;N;;;;;\n16A23;BAMUM LETTER PHASE-F RU;Lo;0;L;;;;;N;;;;;\n16A24;BAMUM LETTER PHASE-F NI;Lo;0;L;;;;;N;;;;;\n16A25;BAMUM LETTER PHASE-F REUX;Lo;0;L;;;;;N;;;;;\n16A26;BAMUM LETTER PHASE-F KEN;Lo;0;L;;;;;N;;;;;\n16A27;BAMUM LETTER PHASE-F NGKWAEN;Lo;0;L;;;;;N;;;;;\n16A28;BAMUM LETTER PHASE-F NGGA;Lo;0;L;;;;;N;;;;;\n16A29;BAMUM LETTER PHASE-F SHO;Lo;0;L;;;;;N;;;;;\n16A2A;BAMUM LETTER PHASE-F PUAE;Lo;0;L;;;;;N;;;;;\n16A2B;BAMUM LETTER PHASE-F FOM;Lo;0;L;;;;;N;;;;;\n16A2C;BAMUM LETTER PHASE-F WA;Lo;0;L;;;;;N;;;;;\n16A2D;BAMUM LETTER PHASE-F LI;Lo;0;L;;;;;N;;;;;\n16A2E;BAMUM LETTER PHASE-F LOQ;Lo;0;L;;;;;N;;;;;\n16A2F;BAMUM LETTER PHASE-F KO;Lo;0;L;;;;;N;;;;;\n16A30;BAMUM LETTER PHASE-F MBEN;Lo;0;L;;;;;N;;;;;\n16A31;BAMUM LETTER PHASE-F REN;Lo;0;L;;;;;N;;;;;\n16A32;BAMUM LETTER PHASE-F MA;Lo;0;L;;;;;N;;;;;\n16A33;BAMUM LETTER PHASE-F MO;Lo;0;L;;;;;N;;;;;\n16A34;BAMUM LETTER PHASE-F MBAA;Lo;0;L;;;;;N;;;;;\n16A35;BAMUM LETTER PHASE-F TET;Lo;0;L;;;;;N;;;;;\n16A36;BAMUM LETTER PHASE-F KPA;Lo;0;L;;;;;N;;;;;\n16A37;BAMUM LETTER PHASE-F SAMBA;Lo;0;L;;;;;N;;;;;\n16A38;BAMUM LETTER PHASE-F VUEQ;Lo;0;L;;;;;N;;;;;\n16A40;MRO LETTER TA;Lo;0;L;;;;;N;;;;;\n16A41;MRO LETTER NGI;Lo;0;L;;;;;N;;;;;\n16A42;MRO LETTER YO;Lo;0;L;;;;;N;;;;;\n16A43;MRO LETTER MIM;Lo;0;L;;;;;N;;;;;\n16A44;MRO LETTER BA;Lo;0;L;;;;;N;;;;;\n16A45;MRO LETTER DA;Lo;0;L;;;;;N;;;;;\n16A46;MRO LETTER A;Lo;0;L;;;;;N;;;;;\n16A47;MRO LETTER PHI;Lo;0;L;;;;;N;;;;;\n16A48;MRO LETTER KHAI;Lo;0;L;;;;;N;;;;;\n16A49;MRO LETTER HAO;Lo;0;L;;;;;N;;;;;\n16A4A;MRO LETTER DAI;Lo;0;L;;;;;N;;;;;\n16A4B;MRO LETTER CHU;Lo;0;L;;;;;N;;;;;\n16A4C;MRO LETTER KEAAE;Lo;0;L;;;;;N;;;;;\n16A4D;MRO LETTER OL;Lo;0;L;;;;;N;;;;;\n16A4E;MRO LETTER MAEM;Lo;0;L;;;;;N;;;;;\n16A4F;MRO LETTER NIN;Lo;0;L;;;;;N;;;;;\n16A50;MRO LETTER PA;Lo;0;L;;;;;N;;;;;\n16A51;MRO LETTER OO;Lo;0;L;;;;;N;;;;;\n16A52;MRO LETTER O;Lo;0;L;;;;;N;;;;;\n16A53;MRO LETTER RO;Lo;0;L;;;;;N;;;;;\n16A54;MRO LETTER SHI;Lo;0;L;;;;;N;;;;;\n16A55;MRO LETTER THEA;Lo;0;L;;;;;N;;;;;\n16A56;MRO LETTER EA;Lo;0;L;;;;;N;;;;;\n16A57;MRO LETTER WA;Lo;0;L;;;;;N;;;;;\n16A58;MRO LETTER E;Lo;0;L;;;;;N;;;;;\n16A59;MRO LETTER KO;Lo;0;L;;;;;N;;;;;\n16A5A;MRO LETTER LAN;Lo;0;L;;;;;N;;;;;\n16A5B;MRO LETTER LA;Lo;0;L;;;;;N;;;;;\n16A5C;MRO LETTER HAI;Lo;0;L;;;;;N;;;;;\n16A5D;MRO LETTER RI;Lo;0;L;;;;;N;;;;;\n16A5E;MRO LETTER TEK;Lo;0;L;;;;;N;;;;;\n16A60;MRO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n16A61;MRO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n16A62;MRO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n16A63;MRO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n16A64;MRO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n16A65;MRO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n16A66;MRO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n16A67;MRO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n16A68;MRO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n16A69;MRO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n16A6E;MRO DANDA;Po;0;L;;;;;N;;;;;\n16A6F;MRO DOUBLE DANDA;Po;0;L;;;;;N;;;;;\n16AD0;BASSA VAH LETTER ENNI;Lo;0;L;;;;;N;;;;;\n16AD1;BASSA VAH LETTER KA;Lo;0;L;;;;;N;;;;;\n16AD2;BASSA VAH LETTER SE;Lo;0;L;;;;;N;;;;;\n16AD3;BASSA VAH LETTER FA;Lo;0;L;;;;;N;;;;;\n16AD4;BASSA VAH LETTER MBE;Lo;0;L;;;;;N;;;;;\n16AD5;BASSA VAH LETTER YIE;Lo;0;L;;;;;N;;;;;\n16AD6;BASSA VAH LETTER GAH;Lo;0;L;;;;;N;;;;;\n16AD7;BASSA VAH LETTER DHII;Lo;0;L;;;;;N;;;;;\n16AD8;BASSA VAH LETTER KPAH;Lo;0;L;;;;;N;;;;;\n16AD9;BASSA VAH LETTER JO;Lo;0;L;;;;;N;;;;;\n16ADA;BASSA VAH LETTER HWAH;Lo;0;L;;;;;N;;;;;\n16ADB;BASSA VAH LETTER WA;Lo;0;L;;;;;N;;;;;\n16ADC;BASSA VAH LETTER ZO;Lo;0;L;;;;;N;;;;;\n16ADD;BASSA VAH LETTER GBU;Lo;0;L;;;;;N;;;;;\n16ADE;BASSA VAH LETTER DO;Lo;0;L;;;;;N;;;;;\n16ADF;BASSA VAH LETTER CE;Lo;0;L;;;;;N;;;;;\n16AE0;BASSA VAH LETTER UWU;Lo;0;L;;;;;N;;;;;\n16AE1;BASSA VAH LETTER TO;Lo;0;L;;;;;N;;;;;\n16AE2;BASSA VAH LETTER BA;Lo;0;L;;;;;N;;;;;\n16AE3;BASSA VAH LETTER VU;Lo;0;L;;;;;N;;;;;\n16AE4;BASSA VAH LETTER YEIN;Lo;0;L;;;;;N;;;;;\n16AE5;BASSA VAH LETTER PA;Lo;0;L;;;;;N;;;;;\n16AE6;BASSA VAH LETTER WADDA;Lo;0;L;;;;;N;;;;;\n16AE7;BASSA VAH LETTER A;Lo;0;L;;;;;N;;;;;\n16AE8;BASSA VAH LETTER O;Lo;0;L;;;;;N;;;;;\n16AE9;BASSA VAH LETTER OO;Lo;0;L;;;;;N;;;;;\n16AEA;BASSA VAH LETTER U;Lo;0;L;;;;;N;;;;;\n16AEB;BASSA VAH LETTER EE;Lo;0;L;;;;;N;;;;;\n16AEC;BASSA VAH LETTER E;Lo;0;L;;;;;N;;;;;\n16AED;BASSA VAH LETTER I;Lo;0;L;;;;;N;;;;;\n16AF0;BASSA VAH COMBINING HIGH TONE;Mn;1;NSM;;;;;N;;;;;\n16AF1;BASSA VAH COMBINING LOW TONE;Mn;1;NSM;;;;;N;;;;;\n16AF2;BASSA VAH COMBINING MID TONE;Mn;1;NSM;;;;;N;;;;;\n16AF3;BASSA VAH COMBINING LOW-MID TONE;Mn;1;NSM;;;;;N;;;;;\n16AF4;BASSA VAH COMBINING HIGH-LOW TONE;Mn;1;NSM;;;;;N;;;;;\n16AF5;BASSA VAH FULL STOP;Po;0;L;;;;;N;;;;;\n16B00;PAHAWH HMONG VOWEL KEEB;Lo;0;L;;;;;N;;;;;\n16B01;PAHAWH HMONG VOWEL KEEV;Lo;0;L;;;;;N;;;;;\n16B02;PAHAWH HMONG VOWEL KIB;Lo;0;L;;;;;N;;;;;\n16B03;PAHAWH HMONG VOWEL KIV;Lo;0;L;;;;;N;;;;;\n16B04;PAHAWH HMONG VOWEL KAUB;Lo;0;L;;;;;N;;;;;\n16B05;PAHAWH HMONG VOWEL KAUV;Lo;0;L;;;;;N;;;;;\n16B06;PAHAWH HMONG VOWEL KUB;Lo;0;L;;;;;N;;;;;\n16B07;PAHAWH HMONG VOWEL KUV;Lo;0;L;;;;;N;;;;;\n16B08;PAHAWH HMONG VOWEL KEB;Lo;0;L;;;;;N;;;;;\n16B09;PAHAWH HMONG VOWEL KEV;Lo;0;L;;;;;N;;;;;\n16B0A;PAHAWH HMONG VOWEL KAIB;Lo;0;L;;;;;N;;;;;\n16B0B;PAHAWH HMONG VOWEL KAIV;Lo;0;L;;;;;N;;;;;\n16B0C;PAHAWH HMONG VOWEL KOOB;Lo;0;L;;;;;N;;;;;\n16B0D;PAHAWH HMONG VOWEL KOOV;Lo;0;L;;;;;N;;;;;\n16B0E;PAHAWH HMONG VOWEL KAWB;Lo;0;L;;;;;N;;;;;\n16B0F;PAHAWH HMONG VOWEL KAWV;Lo;0;L;;;;;N;;;;;\n16B10;PAHAWH HMONG VOWEL KUAB;Lo;0;L;;;;;N;;;;;\n16B11;PAHAWH HMONG VOWEL KUAV;Lo;0;L;;;;;N;;;;;\n16B12;PAHAWH HMONG VOWEL KOB;Lo;0;L;;;;;N;;;;;\n16B13;PAHAWH HMONG VOWEL KOV;Lo;0;L;;;;;N;;;;;\n16B14;PAHAWH HMONG VOWEL KIAB;Lo;0;L;;;;;N;;;;;\n16B15;PAHAWH HMONG VOWEL KIAV;Lo;0;L;;;;;N;;;;;\n16B16;PAHAWH HMONG VOWEL KAB;Lo;0;L;;;;;N;;;;;\n16B17;PAHAWH HMONG VOWEL KAV;Lo;0;L;;;;;N;;;;;\n16B18;PAHAWH HMONG VOWEL KWB;Lo;0;L;;;;;N;;;;;\n16B19;PAHAWH HMONG VOWEL KWV;Lo;0;L;;;;;N;;;;;\n16B1A;PAHAWH HMONG VOWEL KAAB;Lo;0;L;;;;;N;;;;;\n16B1B;PAHAWH HMONG VOWEL KAAV;Lo;0;L;;;;;N;;;;;\n16B1C;PAHAWH HMONG CONSONANT VAU;Lo;0;L;;;;;N;;;;;\n16B1D;PAHAWH HMONG CONSONANT NTSAU;Lo;0;L;;;;;N;;;;;\n16B1E;PAHAWH HMONG CONSONANT LAU;Lo;0;L;;;;;N;;;;;\n16B1F;PAHAWH HMONG CONSONANT HAU;Lo;0;L;;;;;N;;;;;\n16B20;PAHAWH HMONG CONSONANT NLAU;Lo;0;L;;;;;N;;;;;\n16B21;PAHAWH HMONG CONSONANT RAU;Lo;0;L;;;;;N;;;;;\n16B22;PAHAWH HMONG CONSONANT NKAU;Lo;0;L;;;;;N;;;;;\n16B23;PAHAWH HMONG CONSONANT QHAU;Lo;0;L;;;;;N;;;;;\n16B24;PAHAWH HMONG CONSONANT YAU;Lo;0;L;;;;;N;;;;;\n16B25;PAHAWH HMONG CONSONANT HLAU;Lo;0;L;;;;;N;;;;;\n16B26;PAHAWH HMONG CONSONANT MAU;Lo;0;L;;;;;N;;;;;\n16B27;PAHAWH HMONG CONSONANT CHAU;Lo;0;L;;;;;N;;;;;\n16B28;PAHAWH HMONG CONSONANT NCHAU;Lo;0;L;;;;;N;;;;;\n16B29;PAHAWH HMONG CONSONANT HNAU;Lo;0;L;;;;;N;;;;;\n16B2A;PAHAWH HMONG CONSONANT PLHAU;Lo;0;L;;;;;N;;;;;\n16B2B;PAHAWH HMONG CONSONANT NTHAU;Lo;0;L;;;;;N;;;;;\n16B2C;PAHAWH HMONG CONSONANT NAU;Lo;0;L;;;;;N;;;;;\n16B2D;PAHAWH HMONG CONSONANT AU;Lo;0;L;;;;;N;;;;;\n16B2E;PAHAWH HMONG CONSONANT XAU;Lo;0;L;;;;;N;;;;;\n16B2F;PAHAWH HMONG CONSONANT CAU;Lo;0;L;;;;;N;;;;;\n16B30;PAHAWH HMONG MARK CIM TUB;Mn;230;NSM;;;;;N;;;;;\n16B31;PAHAWH HMONG MARK CIM SO;Mn;230;NSM;;;;;N;;;;;\n16B32;PAHAWH HMONG MARK CIM KES;Mn;230;NSM;;;;;N;;;;;\n16B33;PAHAWH HMONG MARK CIM KHAV;Mn;230;NSM;;;;;N;;;;;\n16B34;PAHAWH HMONG MARK CIM SUAM;Mn;230;NSM;;;;;N;;;;;\n16B35;PAHAWH HMONG MARK CIM HOM;Mn;230;NSM;;;;;N;;;;;\n16B36;PAHAWH HMONG MARK CIM TAUM;Mn;230;NSM;;;;;N;;;;;\n16B37;PAHAWH HMONG SIGN VOS THOM;Po;0;L;;;;;N;;;;;\n16B38;PAHAWH HMONG SIGN VOS TSHAB CEEB;Po;0;L;;;;;N;;;;;\n16B39;PAHAWH HMONG SIGN CIM CHEEM;Po;0;L;;;;;N;;;;;\n16B3A;PAHAWH HMONG SIGN VOS THIAB;Po;0;L;;;;;N;;;;;\n16B3B;PAHAWH HMONG SIGN VOS FEEM;Po;0;L;;;;;N;;;;;\n16B3C;PAHAWH HMONG SIGN XYEEM NTXIV;So;0;L;;;;;N;;;;;\n16B3D;PAHAWH HMONG SIGN XYEEM RHO;So;0;L;;;;;N;;;;;\n16B3E;PAHAWH HMONG SIGN XYEEM TOV;So;0;L;;;;;N;;;;;\n16B3F;PAHAWH HMONG SIGN XYEEM FAIB;So;0;L;;;;;N;;;;;\n16B40;PAHAWH HMONG SIGN VOS SEEV;Lm;0;L;;;;;N;;;;;\n16B41;PAHAWH HMONG SIGN MEEJ SUAB;Lm;0;L;;;;;N;;;;;\n16B42;PAHAWH HMONG SIGN VOS NRUA;Lm;0;L;;;;;N;;;;;\n16B43;PAHAWH HMONG SIGN IB YAM;Lm;0;L;;;;;N;;;;;\n16B44;PAHAWH HMONG SIGN XAUS;Po;0;L;;;;;N;;;;;\n16B45;PAHAWH HMONG SIGN CIM TSOV ROG;So;0;L;;;;;N;;;;;\n16B50;PAHAWH HMONG DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n16B51;PAHAWH HMONG DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n16B52;PAHAWH HMONG DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n16B53;PAHAWH HMONG DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n16B54;PAHAWH HMONG DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n16B55;PAHAWH HMONG DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n16B56;PAHAWH HMONG DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n16B57;PAHAWH HMONG DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n16B58;PAHAWH HMONG DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n16B59;PAHAWH HMONG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n16B5B;PAHAWH HMONG NUMBER TENS;No;0;L;;;;10;N;;;;;\n16B5C;PAHAWH HMONG NUMBER HUNDREDS;No;0;L;;;;100;N;;;;;\n16B5D;PAHAWH HMONG NUMBER TEN THOUSANDS;No;0;L;;;;10000;N;;;;;\n16B5E;PAHAWH HMONG NUMBER MILLIONS;No;0;L;;;;1000000;N;;;;;\n16B5F;PAHAWH HMONG NUMBER HUNDRED MILLIONS;No;0;L;;;;100000000;N;;;;;\n16B60;PAHAWH HMONG NUMBER TEN BILLIONS;No;0;L;;;;10000000000;N;;;;;\n16B61;PAHAWH HMONG NUMBER TRILLIONS;No;0;L;;;;1000000000000;N;;;;;\n16B63;PAHAWH HMONG SIGN VOS LUB;Lo;0;L;;;;;N;;;;;\n16B64;PAHAWH HMONG SIGN XYOO;Lo;0;L;;;;;N;;;;;\n16B65;PAHAWH HMONG SIGN HLI;Lo;0;L;;;;;N;;;;;\n16B66;PAHAWH HMONG SIGN THIRD-STAGE HLI;Lo;0;L;;;;;N;;;;;\n16B67;PAHAWH HMONG SIGN ZWJ THAJ;Lo;0;L;;;;;N;;;;;\n16B68;PAHAWH HMONG SIGN HNUB;Lo;0;L;;;;;N;;;;;\n16B69;PAHAWH HMONG SIGN NQIG;Lo;0;L;;;;;N;;;;;\n16B6A;PAHAWH HMONG SIGN XIAB;Lo;0;L;;;;;N;;;;;\n16B6B;PAHAWH HMONG SIGN NTUJ;Lo;0;L;;;;;N;;;;;\n16B6C;PAHAWH HMONG SIGN AV;Lo;0;L;;;;;N;;;;;\n16B6D;PAHAWH HMONG SIGN TXHEEJ CEEV;Lo;0;L;;;;;N;;;;;\n16B6E;PAHAWH HMONG SIGN MEEJ TSEEB;Lo;0;L;;;;;N;;;;;\n16B6F;PAHAWH HMONG SIGN TAU;Lo;0;L;;;;;N;;;;;\n16B70;PAHAWH HMONG SIGN LOS;Lo;0;L;;;;;N;;;;;\n16B71;PAHAWH HMONG SIGN MUS;Lo;0;L;;;;;N;;;;;\n16B72;PAHAWH HMONG SIGN CIM HAIS LUS NTOG NTOG;Lo;0;L;;;;;N;;;;;\n16B73;PAHAWH HMONG SIGN CIM CUAM TSHOOJ;Lo;0;L;;;;;N;;;;;\n16B74;PAHAWH HMONG SIGN CIM TXWV;Lo;0;L;;;;;N;;;;;\n16B75;PAHAWH HMONG SIGN CIM TXWV CHWV;Lo;0;L;;;;;N;;;;;\n16B76;PAHAWH HMONG SIGN CIM PUB DAWB;Lo;0;L;;;;;N;;;;;\n16B77;PAHAWH HMONG SIGN CIM NRES TOS;Lo;0;L;;;;;N;;;;;\n16B7D;PAHAWH HMONG CLAN SIGN TSHEEJ;Lo;0;L;;;;;N;;;;;\n16B7E;PAHAWH HMONG CLAN SIGN YEEG;Lo;0;L;;;;;N;;;;;\n16B7F;PAHAWH HMONG CLAN SIGN LIS;Lo;0;L;;;;;N;;;;;\n16B80;PAHAWH HMONG CLAN SIGN LAUJ;Lo;0;L;;;;;N;;;;;\n16B81;PAHAWH HMONG CLAN SIGN XYOOJ;Lo;0;L;;;;;N;;;;;\n16B82;PAHAWH HMONG CLAN SIGN KOO;Lo;0;L;;;;;N;;;;;\n16B83;PAHAWH HMONG CLAN SIGN HAWJ;Lo;0;L;;;;;N;;;;;\n16B84;PAHAWH HMONG CLAN SIGN MUAS;Lo;0;L;;;;;N;;;;;\n16B85;PAHAWH HMONG CLAN SIGN THOJ;Lo;0;L;;;;;N;;;;;\n16B86;PAHAWH HMONG CLAN SIGN TSAB;Lo;0;L;;;;;N;;;;;\n16B87;PAHAWH HMONG CLAN SIGN PHAB;Lo;0;L;;;;;N;;;;;\n16B88;PAHAWH HMONG CLAN SIGN KHAB;Lo;0;L;;;;;N;;;;;\n16B89;PAHAWH HMONG CLAN SIGN HAM;Lo;0;L;;;;;N;;;;;\n16B8A;PAHAWH HMONG CLAN SIGN VAJ;Lo;0;L;;;;;N;;;;;\n16B8B;PAHAWH HMONG CLAN SIGN FAJ;Lo;0;L;;;;;N;;;;;\n16B8C;PAHAWH HMONG CLAN SIGN YAJ;Lo;0;L;;;;;N;;;;;\n16B8D;PAHAWH HMONG CLAN SIGN TSWB;Lo;0;L;;;;;N;;;;;\n16B8E;PAHAWH HMONG CLAN SIGN KWM;Lo;0;L;;;;;N;;;;;\n16B8F;PAHAWH HMONG CLAN SIGN VWJ;Lo;0;L;;;;;N;;;;;\n16E40;MEDEFAIDRIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;16E60;\n16E41;MEDEFAIDRIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;16E61;\n16E42;MEDEFAIDRIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;16E62;\n16E43;MEDEFAIDRIN CAPITAL LETTER W;Lu;0;L;;;;;N;;;;16E63;\n16E44;MEDEFAIDRIN CAPITAL LETTER ATIU;Lu;0;L;;;;;N;;;;16E64;\n16E45;MEDEFAIDRIN CAPITAL LETTER Z;Lu;0;L;;;;;N;;;;16E65;\n16E46;MEDEFAIDRIN CAPITAL LETTER KP;Lu;0;L;;;;;N;;;;16E66;\n16E47;MEDEFAIDRIN CAPITAL LETTER P;Lu;0;L;;;;;N;;;;16E67;\n16E48;MEDEFAIDRIN CAPITAL LETTER T;Lu;0;L;;;;;N;;;;16E68;\n16E49;MEDEFAIDRIN CAPITAL LETTER G;Lu;0;L;;;;;N;;;;16E69;\n16E4A;MEDEFAIDRIN CAPITAL LETTER F;Lu;0;L;;;;;N;;;;16E6A;\n16E4B;MEDEFAIDRIN CAPITAL LETTER I;Lu;0;L;;;;;N;;;;16E6B;\n16E4C;MEDEFAIDRIN CAPITAL LETTER K;Lu;0;L;;;;;N;;;;16E6C;\n16E4D;MEDEFAIDRIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;16E6D;\n16E4E;MEDEFAIDRIN CAPITAL LETTER J;Lu;0;L;;;;;N;;;;16E6E;\n16E4F;MEDEFAIDRIN CAPITAL LETTER E;Lu;0;L;;;;;N;;;;16E6F;\n16E50;MEDEFAIDRIN CAPITAL LETTER B;Lu;0;L;;;;;N;;;;16E70;\n16E51;MEDEFAIDRIN CAPITAL LETTER C;Lu;0;L;;;;;N;;;;16E71;\n16E52;MEDEFAIDRIN CAPITAL LETTER U;Lu;0;L;;;;;N;;;;16E72;\n16E53;MEDEFAIDRIN CAPITAL LETTER YU;Lu;0;L;;;;;N;;;;16E73;\n16E54;MEDEFAIDRIN CAPITAL LETTER L;Lu;0;L;;;;;N;;;;16E74;\n16E55;MEDEFAIDRIN CAPITAL LETTER Q;Lu;0;L;;;;;N;;;;16E75;\n16E56;MEDEFAIDRIN CAPITAL LETTER HP;Lu;0;L;;;;;N;;;;16E76;\n16E57;MEDEFAIDRIN CAPITAL LETTER NY;Lu;0;L;;;;;N;;;;16E77;\n16E58;MEDEFAIDRIN CAPITAL LETTER X;Lu;0;L;;;;;N;;;;16E78;\n16E59;MEDEFAIDRIN CAPITAL LETTER D;Lu;0;L;;;;;N;;;;16E79;\n16E5A;MEDEFAIDRIN CAPITAL LETTER OE;Lu;0;L;;;;;N;;;;16E7A;\n16E5B;MEDEFAIDRIN CAPITAL LETTER N;Lu;0;L;;;;;N;;;;16E7B;\n16E5C;MEDEFAIDRIN CAPITAL LETTER R;Lu;0;L;;;;;N;;;;16E7C;\n16E5D;MEDEFAIDRIN CAPITAL LETTER O;Lu;0;L;;;;;N;;;;16E7D;\n16E5E;MEDEFAIDRIN CAPITAL LETTER AI;Lu;0;L;;;;;N;;;;16E7E;\n16E5F;MEDEFAIDRIN CAPITAL LETTER Y;Lu;0;L;;;;;N;;;;16E7F;\n16E60;MEDEFAIDRIN SMALL LETTER M;Ll;0;L;;;;;N;;;16E40;;16E40\n16E61;MEDEFAIDRIN SMALL LETTER S;Ll;0;L;;;;;N;;;16E41;;16E41\n16E62;MEDEFAIDRIN SMALL LETTER V;Ll;0;L;;;;;N;;;16E42;;16E42\n16E63;MEDEFAIDRIN SMALL LETTER W;Ll;0;L;;;;;N;;;16E43;;16E43\n16E64;MEDEFAIDRIN SMALL LETTER ATIU;Ll;0;L;;;;;N;;;16E44;;16E44\n16E65;MEDEFAIDRIN SMALL LETTER Z;Ll;0;L;;;;;N;;;16E45;;16E45\n16E66;MEDEFAIDRIN SMALL LETTER KP;Ll;0;L;;;;;N;;;16E46;;16E46\n16E67;MEDEFAIDRIN SMALL LETTER P;Ll;0;L;;;;;N;;;16E47;;16E47\n16E68;MEDEFAIDRIN SMALL LETTER T;Ll;0;L;;;;;N;;;16E48;;16E48\n16E69;MEDEFAIDRIN SMALL LETTER G;Ll;0;L;;;;;N;;;16E49;;16E49\n16E6A;MEDEFAIDRIN SMALL LETTER F;Ll;0;L;;;;;N;;;16E4A;;16E4A\n16E6B;MEDEFAIDRIN SMALL LETTER I;Ll;0;L;;;;;N;;;16E4B;;16E4B\n16E6C;MEDEFAIDRIN SMALL LETTER K;Ll;0;L;;;;;N;;;16E4C;;16E4C\n16E6D;MEDEFAIDRIN SMALL LETTER A;Ll;0;L;;;;;N;;;16E4D;;16E4D\n16E6E;MEDEFAIDRIN SMALL LETTER J;Ll;0;L;;;;;N;;;16E4E;;16E4E\n16E6F;MEDEFAIDRIN SMALL LETTER E;Ll;0;L;;;;;N;;;16E4F;;16E4F\n16E70;MEDEFAIDRIN SMALL LETTER B;Ll;0;L;;;;;N;;;16E50;;16E50\n16E71;MEDEFAIDRIN SMALL LETTER C;Ll;0;L;;;;;N;;;16E51;;16E51\n16E72;MEDEFAIDRIN SMALL LETTER U;Ll;0;L;;;;;N;;;16E52;;16E52\n16E73;MEDEFAIDRIN SMALL LETTER YU;Ll;0;L;;;;;N;;;16E53;;16E53\n16E74;MEDEFAIDRIN SMALL LETTER L;Ll;0;L;;;;;N;;;16E54;;16E54\n16E75;MEDEFAIDRIN SMALL LETTER Q;Ll;0;L;;;;;N;;;16E55;;16E55\n16E76;MEDEFAIDRIN SMALL LETTER HP;Ll;0;L;;;;;N;;;16E56;;16E56\n16E77;MEDEFAIDRIN SMALL LETTER NY;Ll;0;L;;;;;N;;;16E57;;16E57\n16E78;MEDEFAIDRIN SMALL LETTER X;Ll;0;L;;;;;N;;;16E58;;16E58\n16E79;MEDEFAIDRIN SMALL LETTER D;Ll;0;L;;;;;N;;;16E59;;16E59\n16E7A;MEDEFAIDRIN SMALL LETTER OE;Ll;0;L;;;;;N;;;16E5A;;16E5A\n16E7B;MEDEFAIDRIN SMALL LETTER N;Ll;0;L;;;;;N;;;16E5B;;16E5B\n16E7C;MEDEFAIDRIN SMALL LETTER R;Ll;0;L;;;;;N;;;16E5C;;16E5C\n16E7D;MEDEFAIDRIN SMALL LETTER O;Ll;0;L;;;;;N;;;16E5D;;16E5D\n16E7E;MEDEFAIDRIN SMALL LETTER AI;Ll;0;L;;;;;N;;;16E5E;;16E5E\n16E7F;MEDEFAIDRIN SMALL LETTER Y;Ll;0;L;;;;;N;;;16E5F;;16E5F\n16E80;MEDEFAIDRIN DIGIT ZERO;No;0;L;;;;0;N;;;;;\n16E81;MEDEFAIDRIN DIGIT ONE;No;0;L;;;;1;N;;;;;\n16E82;MEDEFAIDRIN DIGIT TWO;No;0;L;;;;2;N;;;;;\n16E83;MEDEFAIDRIN DIGIT THREE;No;0;L;;;;3;N;;;;;\n16E84;MEDEFAIDRIN DIGIT FOUR;No;0;L;;;;4;N;;;;;\n16E85;MEDEFAIDRIN DIGIT FIVE;No;0;L;;;;5;N;;;;;\n16E86;MEDEFAIDRIN DIGIT SIX;No;0;L;;;;6;N;;;;;\n16E87;MEDEFAIDRIN DIGIT SEVEN;No;0;L;;;;7;N;;;;;\n16E88;MEDEFAIDRIN DIGIT EIGHT;No;0;L;;;;8;N;;;;;\n16E89;MEDEFAIDRIN DIGIT NINE;No;0;L;;;;9;N;;;;;\n16E8A;MEDEFAIDRIN NUMBER TEN;No;0;L;;;;10;N;;;;;\n16E8B;MEDEFAIDRIN NUMBER ELEVEN;No;0;L;;;;11;N;;;;;\n16E8C;MEDEFAIDRIN NUMBER TWELVE;No;0;L;;;;12;N;;;;;\n16E8D;MEDEFAIDRIN NUMBER THIRTEEN;No;0;L;;;;13;N;;;;;\n16E8E;MEDEFAIDRIN NUMBER FOURTEEN;No;0;L;;;;14;N;;;;;\n16E8F;MEDEFAIDRIN NUMBER FIFTEEN;No;0;L;;;;15;N;;;;;\n16E90;MEDEFAIDRIN NUMBER SIXTEEN;No;0;L;;;;16;N;;;;;\n16E91;MEDEFAIDRIN NUMBER SEVENTEEN;No;0;L;;;;17;N;;;;;\n16E92;MEDEFAIDRIN NUMBER EIGHTEEN;No;0;L;;;;18;N;;;;;\n16E93;MEDEFAIDRIN NUMBER NINETEEN;No;0;L;;;;19;N;;;;;\n16E94;MEDEFAIDRIN DIGIT ONE ALTERNATE FORM;No;0;L;;;;1;N;;;;;\n16E95;MEDEFAIDRIN DIGIT TWO ALTERNATE FORM;No;0;L;;;;2;N;;;;;\n16E96;MEDEFAIDRIN DIGIT THREE ALTERNATE FORM;No;0;L;;;;3;N;;;;;\n16E97;MEDEFAIDRIN COMMA;Po;0;L;;;;;N;;;;;\n16E98;MEDEFAIDRIN FULL STOP;Po;0;L;;;;;N;;;;;\n16E99;MEDEFAIDRIN SYMBOL AIVA;Po;0;L;;;;;N;;;;;\n16E9A;MEDEFAIDRIN EXCLAMATION OH;Po;0;L;;;;;N;;;;;\n16F00;MIAO LETTER PA;Lo;0;L;;;;;N;;;;;\n16F01;MIAO LETTER BA;Lo;0;L;;;;;N;;;;;\n16F02;MIAO LETTER YI PA;Lo;0;L;;;;;N;;;;;\n16F03;MIAO LETTER PLA;Lo;0;L;;;;;N;;;;;\n16F04;MIAO LETTER MA;Lo;0;L;;;;;N;;;;;\n16F05;MIAO LETTER MHA;Lo;0;L;;;;;N;;;;;\n16F06;MIAO LETTER ARCHAIC MA;Lo;0;L;;;;;N;;;;;\n16F07;MIAO LETTER FA;Lo;0;L;;;;;N;;;;;\n16F08;MIAO LETTER VA;Lo;0;L;;;;;N;;;;;\n16F09;MIAO LETTER VFA;Lo;0;L;;;;;N;;;;;\n16F0A;MIAO LETTER TA;Lo;0;L;;;;;N;;;;;\n16F0B;MIAO LETTER DA;Lo;0;L;;;;;N;;;;;\n16F0C;MIAO LETTER YI TTA;Lo;0;L;;;;;N;;;;;\n16F0D;MIAO LETTER YI TA;Lo;0;L;;;;;N;;;;;\n16F0E;MIAO LETTER TTA;Lo;0;L;;;;;N;;;;;\n16F0F;MIAO LETTER DDA;Lo;0;L;;;;;N;;;;;\n16F10;MIAO LETTER NA;Lo;0;L;;;;;N;;;;;\n16F11;MIAO LETTER NHA;Lo;0;L;;;;;N;;;;;\n16F12;MIAO LETTER YI NNA;Lo;0;L;;;;;N;;;;;\n16F13;MIAO LETTER ARCHAIC NA;Lo;0;L;;;;;N;;;;;\n16F14;MIAO LETTER NNA;Lo;0;L;;;;;N;;;;;\n16F15;MIAO LETTER NNHA;Lo;0;L;;;;;N;;;;;\n16F16;MIAO LETTER LA;Lo;0;L;;;;;N;;;;;\n16F17;MIAO LETTER LYA;Lo;0;L;;;;;N;;;;;\n16F18;MIAO LETTER LHA;Lo;0;L;;;;;N;;;;;\n16F19;MIAO LETTER LHYA;Lo;0;L;;;;;N;;;;;\n16F1A;MIAO LETTER TLHA;Lo;0;L;;;;;N;;;;;\n16F1B;MIAO LETTER DLHA;Lo;0;L;;;;;N;;;;;\n16F1C;MIAO LETTER TLHYA;Lo;0;L;;;;;N;;;;;\n16F1D;MIAO LETTER DLHYA;Lo;0;L;;;;;N;;;;;\n16F1E;MIAO LETTER KA;Lo;0;L;;;;;N;;;;;\n16F1F;MIAO LETTER GA;Lo;0;L;;;;;N;;;;;\n16F20;MIAO LETTER YI KA;Lo;0;L;;;;;N;;;;;\n16F21;MIAO LETTER QA;Lo;0;L;;;;;N;;;;;\n16F22;MIAO LETTER QGA;Lo;0;L;;;;;N;;;;;\n16F23;MIAO LETTER NGA;Lo;0;L;;;;;N;;;;;\n16F24;MIAO LETTER NGHA;Lo;0;L;;;;;N;;;;;\n16F25;MIAO LETTER ARCHAIC NGA;Lo;0;L;;;;;N;;;;;\n16F26;MIAO LETTER HA;Lo;0;L;;;;;N;;;;;\n16F27;MIAO LETTER XA;Lo;0;L;;;;;N;;;;;\n16F28;MIAO LETTER GHA;Lo;0;L;;;;;N;;;;;\n16F29;MIAO LETTER GHHA;Lo;0;L;;;;;N;;;;;\n16F2A;MIAO LETTER TSSA;Lo;0;L;;;;;N;;;;;\n16F2B;MIAO LETTER DZZA;Lo;0;L;;;;;N;;;;;\n16F2C;MIAO LETTER NYA;Lo;0;L;;;;;N;;;;;\n16F2D;MIAO LETTER NYHA;Lo;0;L;;;;;N;;;;;\n16F2E;MIAO LETTER TSHA;Lo;0;L;;;;;N;;;;;\n16F2F;MIAO LETTER DZHA;Lo;0;L;;;;;N;;;;;\n16F30;MIAO LETTER YI TSHA;Lo;0;L;;;;;N;;;;;\n16F31;MIAO LETTER YI DZHA;Lo;0;L;;;;;N;;;;;\n16F32;MIAO LETTER REFORMED TSHA;Lo;0;L;;;;;N;;;;;\n16F33;MIAO LETTER SHA;Lo;0;L;;;;;N;;;;;\n16F34;MIAO LETTER SSA;Lo;0;L;;;;;N;;;;;\n16F35;MIAO LETTER ZHA;Lo;0;L;;;;;N;;;;;\n16F36;MIAO LETTER ZSHA;Lo;0;L;;;;;N;;;;;\n16F37;MIAO LETTER TSA;Lo;0;L;;;;;N;;;;;\n16F38;MIAO LETTER DZA;Lo;0;L;;;;;N;;;;;\n16F39;MIAO LETTER YI TSA;Lo;0;L;;;;;N;;;;;\n16F3A;MIAO LETTER SA;Lo;0;L;;;;;N;;;;;\n16F3B;MIAO LETTER ZA;Lo;0;L;;;;;N;;;;;\n16F3C;MIAO LETTER ZSA;Lo;0;L;;;;;N;;;;;\n16F3D;MIAO LETTER ZZA;Lo;0;L;;;;;N;;;;;\n16F3E;MIAO LETTER ZZSA;Lo;0;L;;;;;N;;;;;\n16F3F;MIAO LETTER ARCHAIC ZZA;Lo;0;L;;;;;N;;;;;\n16F40;MIAO LETTER ZZYA;Lo;0;L;;;;;N;;;;;\n16F41;MIAO LETTER ZZSYA;Lo;0;L;;;;;N;;;;;\n16F42;MIAO LETTER WA;Lo;0;L;;;;;N;;;;;\n16F43;MIAO LETTER AH;Lo;0;L;;;;;N;;;;;\n16F44;MIAO LETTER HHA;Lo;0;L;;;;;N;;;;;\n16F45;MIAO LETTER BRI;Lo;0;L;;;;;N;;;;;\n16F46;MIAO LETTER SYI;Lo;0;L;;;;;N;;;;;\n16F47;MIAO LETTER DZYI;Lo;0;L;;;;;N;;;;;\n16F48;MIAO LETTER TE;Lo;0;L;;;;;N;;;;;\n16F49;MIAO LETTER TSE;Lo;0;L;;;;;N;;;;;\n16F4A;MIAO LETTER RTE;Lo;0;L;;;;;N;;;;;\n16F4F;MIAO SIGN CONSONANT MODIFIER BAR;Mn;0;NSM;;;;;N;;;;;\n16F50;MIAO LETTER NASALIZATION;Lo;0;L;;;;;N;;;;;\n16F51;MIAO SIGN ASPIRATION;Mc;0;L;;;;;N;;;;;\n16F52;MIAO SIGN REFORMED VOICING;Mc;0;L;;;;;N;;;;;\n16F53;MIAO SIGN REFORMED ASPIRATION;Mc;0;L;;;;;N;;;;;\n16F54;MIAO VOWEL SIGN A;Mc;0;L;;;;;N;;;;;\n16F55;MIAO VOWEL SIGN AA;Mc;0;L;;;;;N;;;;;\n16F56;MIAO VOWEL SIGN AHH;Mc;0;L;;;;;N;;;;;\n16F57;MIAO VOWEL SIGN AN;Mc;0;L;;;;;N;;;;;\n16F58;MIAO VOWEL SIGN ANG;Mc;0;L;;;;;N;;;;;\n16F59;MIAO VOWEL SIGN O;Mc;0;L;;;;;N;;;;;\n16F5A;MIAO VOWEL SIGN OO;Mc;0;L;;;;;N;;;;;\n16F5B;MIAO VOWEL SIGN WO;Mc;0;L;;;;;N;;;;;\n16F5C;MIAO VOWEL SIGN W;Mc;0;L;;;;;N;;;;;\n16F5D;MIAO VOWEL SIGN E;Mc;0;L;;;;;N;;;;;\n16F5E;MIAO VOWEL SIGN EN;Mc;0;L;;;;;N;;;;;\n16F5F;MIAO VOWEL SIGN ENG;Mc;0;L;;;;;N;;;;;\n16F60;MIAO VOWEL SIGN OEY;Mc;0;L;;;;;N;;;;;\n16F61;MIAO VOWEL SIGN I;Mc;0;L;;;;;N;;;;;\n16F62;MIAO VOWEL SIGN IA;Mc;0;L;;;;;N;;;;;\n16F63;MIAO VOWEL SIGN IAN;Mc;0;L;;;;;N;;;;;\n16F64;MIAO VOWEL SIGN IANG;Mc;0;L;;;;;N;;;;;\n16F65;MIAO VOWEL SIGN IO;Mc;0;L;;;;;N;;;;;\n16F66;MIAO VOWEL SIGN IE;Mc;0;L;;;;;N;;;;;\n16F67;MIAO VOWEL SIGN II;Mc;0;L;;;;;N;;;;;\n16F68;MIAO VOWEL SIGN IU;Mc;0;L;;;;;N;;;;;\n16F69;MIAO VOWEL SIGN ING;Mc;0;L;;;;;N;;;;;\n16F6A;MIAO VOWEL SIGN U;Mc;0;L;;;;;N;;;;;\n16F6B;MIAO VOWEL SIGN UA;Mc;0;L;;;;;N;;;;;\n16F6C;MIAO VOWEL SIGN UAN;Mc;0;L;;;;;N;;;;;\n16F6D;MIAO VOWEL SIGN UANG;Mc;0;L;;;;;N;;;;;\n16F6E;MIAO VOWEL SIGN UU;Mc;0;L;;;;;N;;;;;\n16F6F;MIAO VOWEL SIGN UEI;Mc;0;L;;;;;N;;;;;\n16F70;MIAO VOWEL SIGN UNG;Mc;0;L;;;;;N;;;;;\n16F71;MIAO VOWEL SIGN Y;Mc;0;L;;;;;N;;;;;\n16F72;MIAO VOWEL SIGN YI;Mc;0;L;;;;;N;;;;;\n16F73;MIAO VOWEL SIGN AE;Mc;0;L;;;;;N;;;;;\n16F74;MIAO VOWEL SIGN AEE;Mc;0;L;;;;;N;;;;;\n16F75;MIAO VOWEL SIGN ERR;Mc;0;L;;;;;N;;;;;\n16F76;MIAO VOWEL SIGN ROUNDED ERR;Mc;0;L;;;;;N;;;;;\n16F77;MIAO VOWEL SIGN ER;Mc;0;L;;;;;N;;;;;\n16F78;MIAO VOWEL SIGN ROUNDED ER;Mc;0;L;;;;;N;;;;;\n16F79;MIAO VOWEL SIGN AI;Mc;0;L;;;;;N;;;;;\n16F7A;MIAO VOWEL SIGN EI;Mc;0;L;;;;;N;;;;;\n16F7B;MIAO VOWEL SIGN AU;Mc;0;L;;;;;N;;;;;\n16F7C;MIAO VOWEL SIGN OU;Mc;0;L;;;;;N;;;;;\n16F7D;MIAO VOWEL SIGN N;Mc;0;L;;;;;N;;;;;\n16F7E;MIAO VOWEL SIGN NG;Mc;0;L;;;;;N;;;;;\n16F7F;MIAO VOWEL SIGN UOG;Mc;0;L;;;;;N;;;;;\n16F80;MIAO VOWEL SIGN YUI;Mc;0;L;;;;;N;;;;;\n16F81;MIAO VOWEL SIGN OG;Mc;0;L;;;;;N;;;;;\n16F82;MIAO VOWEL SIGN OER;Mc;0;L;;;;;N;;;;;\n16F83;MIAO VOWEL SIGN VW;Mc;0;L;;;;;N;;;;;\n16F84;MIAO VOWEL SIGN IG;Mc;0;L;;;;;N;;;;;\n16F85;MIAO VOWEL SIGN EA;Mc;0;L;;;;;N;;;;;\n16F86;MIAO VOWEL SIGN IONG;Mc;0;L;;;;;N;;;;;\n16F87;MIAO VOWEL SIGN UI;Mc;0;L;;;;;N;;;;;\n16F8F;MIAO TONE RIGHT;Mn;0;NSM;;;;;N;;;;;\n16F90;MIAO TONE TOP RIGHT;Mn;0;NSM;;;;;N;;;;;\n16F91;MIAO TONE ABOVE;Mn;0;NSM;;;;;N;;;;;\n16F92;MIAO TONE BELOW;Mn;0;NSM;;;;;N;;;;;\n16F93;MIAO LETTER TONE-2;Lm;0;L;;;;;N;;;;;\n16F94;MIAO LETTER TONE-3;Lm;0;L;;;;;N;;;;;\n16F95;MIAO LETTER TONE-4;Lm;0;L;;;;;N;;;;;\n16F96;MIAO LETTER TONE-5;Lm;0;L;;;;;N;;;;;\n16F97;MIAO LETTER TONE-6;Lm;0;L;;;;;N;;;;;\n16F98;MIAO LETTER TONE-7;Lm;0;L;;;;;N;;;;;\n16F99;MIAO LETTER TONE-8;Lm;0;L;;;;;N;;;;;\n16F9A;MIAO LETTER REFORMED TONE-1;Lm;0;L;;;;;N;;;;;\n16F9B;MIAO LETTER REFORMED TONE-2;Lm;0;L;;;;;N;;;;;\n16F9C;MIAO LETTER REFORMED TONE-4;Lm;0;L;;;;;N;;;;;\n16F9D;MIAO LETTER REFORMED TONE-5;Lm;0;L;;;;;N;;;;;\n16F9E;MIAO LETTER REFORMED TONE-6;Lm;0;L;;;;;N;;;;;\n16F9F;MIAO LETTER REFORMED TONE-8;Lm;0;L;;;;;N;;;;;\n16FE0;TANGUT ITERATION MARK;Lm;0;L;;;;;N;;;;;\n16FE1;NUSHU ITERATION MARK;Lm;0;L;;;;;N;;;;;\n16FE2;OLD CHINESE HOOK MARK;Po;0;ON;;;;;N;;;;;\n16FE3;OLD CHINESE ITERATION MARK;Lm;0;L;;;;;N;;;;;\n17000;<Tangut Ideograph, First>;Lo;0;L;;;;;N;;;;;\n187F7;<Tangut Ideograph, Last>;Lo;0;L;;;;;N;;;;;\n18800;TANGUT COMPONENT-001;Lo;0;L;;;;;N;;;;;\n18801;TANGUT COMPONENT-002;Lo;0;L;;;;;N;;;;;\n18802;TANGUT COMPONENT-003;Lo;0;L;;;;;N;;;;;\n18803;TANGUT COMPONENT-004;Lo;0;L;;;;;N;;;;;\n18804;TANGUT COMPONENT-005;Lo;0;L;;;;;N;;;;;\n18805;TANGUT COMPONENT-006;Lo;0;L;;;;;N;;;;;\n18806;TANGUT COMPONENT-007;Lo;0;L;;;;;N;;;;;\n18807;TANGUT COMPONENT-008;Lo;0;L;;;;;N;;;;;\n18808;TANGUT COMPONENT-009;Lo;0;L;;;;;N;;;;;\n18809;TANGUT COMPONENT-010;Lo;0;L;;;;;N;;;;;\n1880A;TANGUT COMPONENT-011;Lo;0;L;;;;;N;;;;;\n1880B;TANGUT COMPONENT-012;Lo;0;L;;;;;N;;;;;\n1880C;TANGUT COMPONENT-013;Lo;0;L;;;;;N;;;;;\n1880D;TANGUT COMPONENT-014;Lo;0;L;;;;;N;;;;;\n1880E;TANGUT COMPONENT-015;Lo;0;L;;;;;N;;;;;\n1880F;TANGUT COMPONENT-016;Lo;0;L;;;;;N;;;;;\n18810;TANGUT COMPONENT-017;Lo;0;L;;;;;N;;;;;\n18811;TANGUT COMPONENT-018;Lo;0;L;;;;;N;;;;;\n18812;TANGUT COMPONENT-019;Lo;0;L;;;;;N;;;;;\n18813;TANGUT COMPONENT-020;Lo;0;L;;;;;N;;;;;\n18814;TANGUT COMPONENT-021;Lo;0;L;;;;;N;;;;;\n18815;TANGUT COMPONENT-022;Lo;0;L;;;;;N;;;;;\n18816;TANGUT COMPONENT-023;Lo;0;L;;;;;N;;;;;\n18817;TANGUT COMPONENT-024;Lo;0;L;;;;;N;;;;;\n18818;TANGUT COMPONENT-025;Lo;0;L;;;;;N;;;;;\n18819;TANGUT COMPONENT-026;Lo;0;L;;;;;N;;;;;\n1881A;TANGUT COMPONENT-027;Lo;0;L;;;;;N;;;;;\n1881B;TANGUT COMPONENT-028;Lo;0;L;;;;;N;;;;;\n1881C;TANGUT COMPONENT-029;Lo;0;L;;;;;N;;;;;\n1881D;TANGUT COMPONENT-030;Lo;0;L;;;;;N;;;;;\n1881E;TANGUT COMPONENT-031;Lo;0;L;;;;;N;;;;;\n1881F;TANGUT COMPONENT-032;Lo;0;L;;;;;N;;;;;\n18820;TANGUT COMPONENT-033;Lo;0;L;;;;;N;;;;;\n18821;TANGUT COMPONENT-034;Lo;0;L;;;;;N;;;;;\n18822;TANGUT COMPONENT-035;Lo;0;L;;;;;N;;;;;\n18823;TANGUT COMPONENT-036;Lo;0;L;;;;;N;;;;;\n18824;TANGUT COMPONENT-037;Lo;0;L;;;;;N;;;;;\n18825;TANGUT COMPONENT-038;Lo;0;L;;;;;N;;;;;\n18826;TANGUT COMPONENT-039;Lo;0;L;;;;;N;;;;;\n18827;TANGUT COMPONENT-040;Lo;0;L;;;;;N;;;;;\n18828;TANGUT COMPONENT-041;Lo;0;L;;;;;N;;;;;\n18829;TANGUT COMPONENT-042;Lo;0;L;;;;;N;;;;;\n1882A;TANGUT COMPONENT-043;Lo;0;L;;;;;N;;;;;\n1882B;TANGUT COMPONENT-044;Lo;0;L;;;;;N;;;;;\n1882C;TANGUT COMPONENT-045;Lo;0;L;;;;;N;;;;;\n1882D;TANGUT COMPONENT-046;Lo;0;L;;;;;N;;;;;\n1882E;TANGUT COMPONENT-047;Lo;0;L;;;;;N;;;;;\n1882F;TANGUT COMPONENT-048;Lo;0;L;;;;;N;;;;;\n18830;TANGUT COMPONENT-049;Lo;0;L;;;;;N;;;;;\n18831;TANGUT COMPONENT-050;Lo;0;L;;;;;N;;;;;\n18832;TANGUT COMPONENT-051;Lo;0;L;;;;;N;;;;;\n18833;TANGUT COMPONENT-052;Lo;0;L;;;;;N;;;;;\n18834;TANGUT COMPONENT-053;Lo;0;L;;;;;N;;;;;\n18835;TANGUT COMPONENT-054;Lo;0;L;;;;;N;;;;;\n18836;TANGUT COMPONENT-055;Lo;0;L;;;;;N;;;;;\n18837;TANGUT COMPONENT-056;Lo;0;L;;;;;N;;;;;\n18838;TANGUT COMPONENT-057;Lo;0;L;;;;;N;;;;;\n18839;TANGUT COMPONENT-058;Lo;0;L;;;;;N;;;;;\n1883A;TANGUT COMPONENT-059;Lo;0;L;;;;;N;;;;;\n1883B;TANGUT COMPONENT-060;Lo;0;L;;;;;N;;;;;\n1883C;TANGUT COMPONENT-061;Lo;0;L;;;;;N;;;;;\n1883D;TANGUT COMPONENT-062;Lo;0;L;;;;;N;;;;;\n1883E;TANGUT COMPONENT-063;Lo;0;L;;;;;N;;;;;\n1883F;TANGUT COMPONENT-064;Lo;0;L;;;;;N;;;;;\n18840;TANGUT COMPONENT-065;Lo;0;L;;;;;N;;;;;\n18841;TANGUT COMPONENT-066;Lo;0;L;;;;;N;;;;;\n18842;TANGUT COMPONENT-067;Lo;0;L;;;;;N;;;;;\n18843;TANGUT COMPONENT-068;Lo;0;L;;;;;N;;;;;\n18844;TANGUT COMPONENT-069;Lo;0;L;;;;;N;;;;;\n18845;TANGUT COMPONENT-070;Lo;0;L;;;;;N;;;;;\n18846;TANGUT COMPONENT-071;Lo;0;L;;;;;N;;;;;\n18847;TANGUT COMPONENT-072;Lo;0;L;;;;;N;;;;;\n18848;TANGUT COMPONENT-073;Lo;0;L;;;;;N;;;;;\n18849;TANGUT COMPONENT-074;Lo;0;L;;;;;N;;;;;\n1884A;TANGUT COMPONENT-075;Lo;0;L;;;;;N;;;;;\n1884B;TANGUT COMPONENT-076;Lo;0;L;;;;;N;;;;;\n1884C;TANGUT COMPONENT-077;Lo;0;L;;;;;N;;;;;\n1884D;TANGUT COMPONENT-078;Lo;0;L;;;;;N;;;;;\n1884E;TANGUT COMPONENT-079;Lo;0;L;;;;;N;;;;;\n1884F;TANGUT COMPONENT-080;Lo;0;L;;;;;N;;;;;\n18850;TANGUT COMPONENT-081;Lo;0;L;;;;;N;;;;;\n18851;TANGUT COMPONENT-082;Lo;0;L;;;;;N;;;;;\n18852;TANGUT COMPONENT-083;Lo;0;L;;;;;N;;;;;\n18853;TANGUT COMPONENT-084;Lo;0;L;;;;;N;;;;;\n18854;TANGUT COMPONENT-085;Lo;0;L;;;;;N;;;;;\n18855;TANGUT COMPONENT-086;Lo;0;L;;;;;N;;;;;\n18856;TANGUT COMPONENT-087;Lo;0;L;;;;;N;;;;;\n18857;TANGUT COMPONENT-088;Lo;0;L;;;;;N;;;;;\n18858;TANGUT COMPONENT-089;Lo;0;L;;;;;N;;;;;\n18859;TANGUT COMPONENT-090;Lo;0;L;;;;;N;;;;;\n1885A;TANGUT COMPONENT-091;Lo;0;L;;;;;N;;;;;\n1885B;TANGUT COMPONENT-092;Lo;0;L;;;;;N;;;;;\n1885C;TANGUT COMPONENT-093;Lo;0;L;;;;;N;;;;;\n1885D;TANGUT COMPONENT-094;Lo;0;L;;;;;N;;;;;\n1885E;TANGUT COMPONENT-095;Lo;0;L;;;;;N;;;;;\n1885F;TANGUT COMPONENT-096;Lo;0;L;;;;;N;;;;;\n18860;TANGUT COMPONENT-097;Lo;0;L;;;;;N;;;;;\n18861;TANGUT COMPONENT-098;Lo;0;L;;;;;N;;;;;\n18862;TANGUT COMPONENT-099;Lo;0;L;;;;;N;;;;;\n18863;TANGUT COMPONENT-100;Lo;0;L;;;;;N;;;;;\n18864;TANGUT COMPONENT-101;Lo;0;L;;;;;N;;;;;\n18865;TANGUT COMPONENT-102;Lo;0;L;;;;;N;;;;;\n18866;TANGUT COMPONENT-103;Lo;0;L;;;;;N;;;;;\n18867;TANGUT COMPONENT-104;Lo;0;L;;;;;N;;;;;\n18868;TANGUT COMPONENT-105;Lo;0;L;;;;;N;;;;;\n18869;TANGUT COMPONENT-106;Lo;0;L;;;;;N;;;;;\n1886A;TANGUT COMPONENT-107;Lo;0;L;;;;;N;;;;;\n1886B;TANGUT COMPONENT-108;Lo;0;L;;;;;N;;;;;\n1886C;TANGUT COMPONENT-109;Lo;0;L;;;;;N;;;;;\n1886D;TANGUT COMPONENT-110;Lo;0;L;;;;;N;;;;;\n1886E;TANGUT COMPONENT-111;Lo;0;L;;;;;N;;;;;\n1886F;TANGUT COMPONENT-112;Lo;0;L;;;;;N;;;;;\n18870;TANGUT COMPONENT-113;Lo;0;L;;;;;N;;;;;\n18871;TANGUT COMPONENT-114;Lo;0;L;;;;;N;;;;;\n18872;TANGUT COMPONENT-115;Lo;0;L;;;;;N;;;;;\n18873;TANGUT COMPONENT-116;Lo;0;L;;;;;N;;;;;\n18874;TANGUT COMPONENT-117;Lo;0;L;;;;;N;;;;;\n18875;TANGUT COMPONENT-118;Lo;0;L;;;;;N;;;;;\n18876;TANGUT COMPONENT-119;Lo;0;L;;;;;N;;;;;\n18877;TANGUT COMPONENT-120;Lo;0;L;;;;;N;;;;;\n18878;TANGUT COMPONENT-121;Lo;0;L;;;;;N;;;;;\n18879;TANGUT COMPONENT-122;Lo;0;L;;;;;N;;;;;\n1887A;TANGUT COMPONENT-123;Lo;0;L;;;;;N;;;;;\n1887B;TANGUT COMPONENT-124;Lo;0;L;;;;;N;;;;;\n1887C;TANGUT COMPONENT-125;Lo;0;L;;;;;N;;;;;\n1887D;TANGUT COMPONENT-126;Lo;0;L;;;;;N;;;;;\n1887E;TANGUT COMPONENT-127;Lo;0;L;;;;;N;;;;;\n1887F;TANGUT COMPONENT-128;Lo;0;L;;;;;N;;;;;\n18880;TANGUT COMPONENT-129;Lo;0;L;;;;;N;;;;;\n18881;TANGUT COMPONENT-130;Lo;0;L;;;;;N;;;;;\n18882;TANGUT COMPONENT-131;Lo;0;L;;;;;N;;;;;\n18883;TANGUT COMPONENT-132;Lo;0;L;;;;;N;;;;;\n18884;TANGUT COMPONENT-133;Lo;0;L;;;;;N;;;;;\n18885;TANGUT COMPONENT-134;Lo;0;L;;;;;N;;;;;\n18886;TANGUT COMPONENT-135;Lo;0;L;;;;;N;;;;;\n18887;TANGUT COMPONENT-136;Lo;0;L;;;;;N;;;;;\n18888;TANGUT COMPONENT-137;Lo;0;L;;;;;N;;;;;\n18889;TANGUT COMPONENT-138;Lo;0;L;;;;;N;;;;;\n1888A;TANGUT COMPONENT-139;Lo;0;L;;;;;N;;;;;\n1888B;TANGUT COMPONENT-140;Lo;0;L;;;;;N;;;;;\n1888C;TANGUT COMPONENT-141;Lo;0;L;;;;;N;;;;;\n1888D;TANGUT COMPONENT-142;Lo;0;L;;;;;N;;;;;\n1888E;TANGUT COMPONENT-143;Lo;0;L;;;;;N;;;;;\n1888F;TANGUT COMPONENT-144;Lo;0;L;;;;;N;;;;;\n18890;TANGUT COMPONENT-145;Lo;0;L;;;;;N;;;;;\n18891;TANGUT COMPONENT-146;Lo;0;L;;;;;N;;;;;\n18892;TANGUT COMPONENT-147;Lo;0;L;;;;;N;;;;;\n18893;TANGUT COMPONENT-148;Lo;0;L;;;;;N;;;;;\n18894;TANGUT COMPONENT-149;Lo;0;L;;;;;N;;;;;\n18895;TANGUT COMPONENT-150;Lo;0;L;;;;;N;;;;;\n18896;TANGUT COMPONENT-151;Lo;0;L;;;;;N;;;;;\n18897;TANGUT COMPONENT-152;Lo;0;L;;;;;N;;;;;\n18898;TANGUT COMPONENT-153;Lo;0;L;;;;;N;;;;;\n18899;TANGUT COMPONENT-154;Lo;0;L;;;;;N;;;;;\n1889A;TANGUT COMPONENT-155;Lo;0;L;;;;;N;;;;;\n1889B;TANGUT COMPONENT-156;Lo;0;L;;;;;N;;;;;\n1889C;TANGUT COMPONENT-157;Lo;0;L;;;;;N;;;;;\n1889D;TANGUT COMPONENT-158;Lo;0;L;;;;;N;;;;;\n1889E;TANGUT COMPONENT-159;Lo;0;L;;;;;N;;;;;\n1889F;TANGUT COMPONENT-160;Lo;0;L;;;;;N;;;;;\n188A0;TANGUT COMPONENT-161;Lo;0;L;;;;;N;;;;;\n188A1;TANGUT COMPONENT-162;Lo;0;L;;;;;N;;;;;\n188A2;TANGUT COMPONENT-163;Lo;0;L;;;;;N;;;;;\n188A3;TANGUT COMPONENT-164;Lo;0;L;;;;;N;;;;;\n188A4;TANGUT COMPONENT-165;Lo;0;L;;;;;N;;;;;\n188A5;TANGUT COMPONENT-166;Lo;0;L;;;;;N;;;;;\n188A6;TANGUT COMPONENT-167;Lo;0;L;;;;;N;;;;;\n188A7;TANGUT COMPONENT-168;Lo;0;L;;;;;N;;;;;\n188A8;TANGUT COMPONENT-169;Lo;0;L;;;;;N;;;;;\n188A9;TANGUT COMPONENT-170;Lo;0;L;;;;;N;;;;;\n188AA;TANGUT COMPONENT-171;Lo;0;L;;;;;N;;;;;\n188AB;TANGUT COMPONENT-172;Lo;0;L;;;;;N;;;;;\n188AC;TANGUT COMPONENT-173;Lo;0;L;;;;;N;;;;;\n188AD;TANGUT COMPONENT-174;Lo;0;L;;;;;N;;;;;\n188AE;TANGUT COMPONENT-175;Lo;0;L;;;;;N;;;;;\n188AF;TANGUT COMPONENT-176;Lo;0;L;;;;;N;;;;;\n188B0;TANGUT COMPONENT-177;Lo;0;L;;;;;N;;;;;\n188B1;TANGUT COMPONENT-178;Lo;0;L;;;;;N;;;;;\n188B2;TANGUT COMPONENT-179;Lo;0;L;;;;;N;;;;;\n188B3;TANGUT COMPONENT-180;Lo;0;L;;;;;N;;;;;\n188B4;TANGUT COMPONENT-181;Lo;0;L;;;;;N;;;;;\n188B5;TANGUT COMPONENT-182;Lo;0;L;;;;;N;;;;;\n188B6;TANGUT COMPONENT-183;Lo;0;L;;;;;N;;;;;\n188B7;TANGUT COMPONENT-184;Lo;0;L;;;;;N;;;;;\n188B8;TANGUT COMPONENT-185;Lo;0;L;;;;;N;;;;;\n188B9;TANGUT COMPONENT-186;Lo;0;L;;;;;N;;;;;\n188BA;TANGUT COMPONENT-187;Lo;0;L;;;;;N;;;;;\n188BB;TANGUT COMPONENT-188;Lo;0;L;;;;;N;;;;;\n188BC;TANGUT COMPONENT-189;Lo;0;L;;;;;N;;;;;\n188BD;TANGUT COMPONENT-190;Lo;0;L;;;;;N;;;;;\n188BE;TANGUT COMPONENT-191;Lo;0;L;;;;;N;;;;;\n188BF;TANGUT COMPONENT-192;Lo;0;L;;;;;N;;;;;\n188C0;TANGUT COMPONENT-193;Lo;0;L;;;;;N;;;;;\n188C1;TANGUT COMPONENT-194;Lo;0;L;;;;;N;;;;;\n188C2;TANGUT COMPONENT-195;Lo;0;L;;;;;N;;;;;\n188C3;TANGUT COMPONENT-196;Lo;0;L;;;;;N;;;;;\n188C4;TANGUT COMPONENT-197;Lo;0;L;;;;;N;;;;;\n188C5;TANGUT COMPONENT-198;Lo;0;L;;;;;N;;;;;\n188C6;TANGUT COMPONENT-199;Lo;0;L;;;;;N;;;;;\n188C7;TANGUT COMPONENT-200;Lo;0;L;;;;;N;;;;;\n188C8;TANGUT COMPONENT-201;Lo;0;L;;;;;N;;;;;\n188C9;TANGUT COMPONENT-202;Lo;0;L;;;;;N;;;;;\n188CA;TANGUT COMPONENT-203;Lo;0;L;;;;;N;;;;;\n188CB;TANGUT COMPONENT-204;Lo;0;L;;;;;N;;;;;\n188CC;TANGUT COMPONENT-205;Lo;0;L;;;;;N;;;;;\n188CD;TANGUT COMPONENT-206;Lo;0;L;;;;;N;;;;;\n188CE;TANGUT COMPONENT-207;Lo;0;L;;;;;N;;;;;\n188CF;TANGUT COMPONENT-208;Lo;0;L;;;;;N;;;;;\n188D0;TANGUT COMPONENT-209;Lo;0;L;;;;;N;;;;;\n188D1;TANGUT COMPONENT-210;Lo;0;L;;;;;N;;;;;\n188D2;TANGUT COMPONENT-211;Lo;0;L;;;;;N;;;;;\n188D3;TANGUT COMPONENT-212;Lo;0;L;;;;;N;;;;;\n188D4;TANGUT COMPONENT-213;Lo;0;L;;;;;N;;;;;\n188D5;TANGUT COMPONENT-214;Lo;0;L;;;;;N;;;;;\n188D6;TANGUT COMPONENT-215;Lo;0;L;;;;;N;;;;;\n188D7;TANGUT COMPONENT-216;Lo;0;L;;;;;N;;;;;\n188D8;TANGUT COMPONENT-217;Lo;0;L;;;;;N;;;;;\n188D9;TANGUT COMPONENT-218;Lo;0;L;;;;;N;;;;;\n188DA;TANGUT COMPONENT-219;Lo;0;L;;;;;N;;;;;\n188DB;TANGUT COMPONENT-220;Lo;0;L;;;;;N;;;;;\n188DC;TANGUT COMPONENT-221;Lo;0;L;;;;;N;;;;;\n188DD;TANGUT COMPONENT-222;Lo;0;L;;;;;N;;;;;\n188DE;TANGUT COMPONENT-223;Lo;0;L;;;;;N;;;;;\n188DF;TANGUT COMPONENT-224;Lo;0;L;;;;;N;;;;;\n188E0;TANGUT COMPONENT-225;Lo;0;L;;;;;N;;;;;\n188E1;TANGUT COMPONENT-226;Lo;0;L;;;;;N;;;;;\n188E2;TANGUT COMPONENT-227;Lo;0;L;;;;;N;;;;;\n188E3;TANGUT COMPONENT-228;Lo;0;L;;;;;N;;;;;\n188E4;TANGUT COMPONENT-229;Lo;0;L;;;;;N;;;;;\n188E5;TANGUT COMPONENT-230;Lo;0;L;;;;;N;;;;;\n188E6;TANGUT COMPONENT-231;Lo;0;L;;;;;N;;;;;\n188E7;TANGUT COMPONENT-232;Lo;0;L;;;;;N;;;;;\n188E8;TANGUT COMPONENT-233;Lo;0;L;;;;;N;;;;;\n188E9;TANGUT COMPONENT-234;Lo;0;L;;;;;N;;;;;\n188EA;TANGUT COMPONENT-235;Lo;0;L;;;;;N;;;;;\n188EB;TANGUT COMPONENT-236;Lo;0;L;;;;;N;;;;;\n188EC;TANGUT COMPONENT-237;Lo;0;L;;;;;N;;;;;\n188ED;TANGUT COMPONENT-238;Lo;0;L;;;;;N;;;;;\n188EE;TANGUT COMPONENT-239;Lo;0;L;;;;;N;;;;;\n188EF;TANGUT COMPONENT-240;Lo;0;L;;;;;N;;;;;\n188F0;TANGUT COMPONENT-241;Lo;0;L;;;;;N;;;;;\n188F1;TANGUT COMPONENT-242;Lo;0;L;;;;;N;;;;;\n188F2;TANGUT COMPONENT-243;Lo;0;L;;;;;N;;;;;\n188F3;TANGUT COMPONENT-244;Lo;0;L;;;;;N;;;;;\n188F4;TANGUT COMPONENT-245;Lo;0;L;;;;;N;;;;;\n188F5;TANGUT COMPONENT-246;Lo;0;L;;;;;N;;;;;\n188F6;TANGUT COMPONENT-247;Lo;0;L;;;;;N;;;;;\n188F7;TANGUT COMPONENT-248;Lo;0;L;;;;;N;;;;;\n188F8;TANGUT COMPONENT-249;Lo;0;L;;;;;N;;;;;\n188F9;TANGUT COMPONENT-250;Lo;0;L;;;;;N;;;;;\n188FA;TANGUT COMPONENT-251;Lo;0;L;;;;;N;;;;;\n188FB;TANGUT COMPONENT-252;Lo;0;L;;;;;N;;;;;\n188FC;TANGUT COMPONENT-253;Lo;0;L;;;;;N;;;;;\n188FD;TANGUT COMPONENT-254;Lo;0;L;;;;;N;;;;;\n188FE;TANGUT COMPONENT-255;Lo;0;L;;;;;N;;;;;\n188FF;TANGUT COMPONENT-256;Lo;0;L;;;;;N;;;;;\n18900;TANGUT COMPONENT-257;Lo;0;L;;;;;N;;;;;\n18901;TANGUT COMPONENT-258;Lo;0;L;;;;;N;;;;;\n18902;TANGUT COMPONENT-259;Lo;0;L;;;;;N;;;;;\n18903;TANGUT COMPONENT-260;Lo;0;L;;;;;N;;;;;\n18904;TANGUT COMPONENT-261;Lo;0;L;;;;;N;;;;;\n18905;TANGUT COMPONENT-262;Lo;0;L;;;;;N;;;;;\n18906;TANGUT COMPONENT-263;Lo;0;L;;;;;N;;;;;\n18907;TANGUT COMPONENT-264;Lo;0;L;;;;;N;;;;;\n18908;TANGUT COMPONENT-265;Lo;0;L;;;;;N;;;;;\n18909;TANGUT COMPONENT-266;Lo;0;L;;;;;N;;;;;\n1890A;TANGUT COMPONENT-267;Lo;0;L;;;;;N;;;;;\n1890B;TANGUT COMPONENT-268;Lo;0;L;;;;;N;;;;;\n1890C;TANGUT COMPONENT-269;Lo;0;L;;;;;N;;;;;\n1890D;TANGUT COMPONENT-270;Lo;0;L;;;;;N;;;;;\n1890E;TANGUT COMPONENT-271;Lo;0;L;;;;;N;;;;;\n1890F;TANGUT COMPONENT-272;Lo;0;L;;;;;N;;;;;\n18910;TANGUT COMPONENT-273;Lo;0;L;;;;;N;;;;;\n18911;TANGUT COMPONENT-274;Lo;0;L;;;;;N;;;;;\n18912;TANGUT COMPONENT-275;Lo;0;L;;;;;N;;;;;\n18913;TANGUT COMPONENT-276;Lo;0;L;;;;;N;;;;;\n18914;TANGUT COMPONENT-277;Lo;0;L;;;;;N;;;;;\n18915;TANGUT COMPONENT-278;Lo;0;L;;;;;N;;;;;\n18916;TANGUT COMPONENT-279;Lo;0;L;;;;;N;;;;;\n18917;TANGUT COMPONENT-280;Lo;0;L;;;;;N;;;;;\n18918;TANGUT COMPONENT-281;Lo;0;L;;;;;N;;;;;\n18919;TANGUT COMPONENT-282;Lo;0;L;;;;;N;;;;;\n1891A;TANGUT COMPONENT-283;Lo;0;L;;;;;N;;;;;\n1891B;TANGUT COMPONENT-284;Lo;0;L;;;;;N;;;;;\n1891C;TANGUT COMPONENT-285;Lo;0;L;;;;;N;;;;;\n1891D;TANGUT COMPONENT-286;Lo;0;L;;;;;N;;;;;\n1891E;TANGUT COMPONENT-287;Lo;0;L;;;;;N;;;;;\n1891F;TANGUT COMPONENT-288;Lo;0;L;;;;;N;;;;;\n18920;TANGUT COMPONENT-289;Lo;0;L;;;;;N;;;;;\n18921;TANGUT COMPONENT-290;Lo;0;L;;;;;N;;;;;\n18922;TANGUT COMPONENT-291;Lo;0;L;;;;;N;;;;;\n18923;TANGUT COMPONENT-292;Lo;0;L;;;;;N;;;;;\n18924;TANGUT COMPONENT-293;Lo;0;L;;;;;N;;;;;\n18925;TANGUT COMPONENT-294;Lo;0;L;;;;;N;;;;;\n18926;TANGUT COMPONENT-295;Lo;0;L;;;;;N;;;;;\n18927;TANGUT COMPONENT-296;Lo;0;L;;;;;N;;;;;\n18928;TANGUT COMPONENT-297;Lo;0;L;;;;;N;;;;;\n18929;TANGUT COMPONENT-298;Lo;0;L;;;;;N;;;;;\n1892A;TANGUT COMPONENT-299;Lo;0;L;;;;;N;;;;;\n1892B;TANGUT COMPONENT-300;Lo;0;L;;;;;N;;;;;\n1892C;TANGUT COMPONENT-301;Lo;0;L;;;;;N;;;;;\n1892D;TANGUT COMPONENT-302;Lo;0;L;;;;;N;;;;;\n1892E;TANGUT COMPONENT-303;Lo;0;L;;;;;N;;;;;\n1892F;TANGUT COMPONENT-304;Lo;0;L;;;;;N;;;;;\n18930;TANGUT COMPONENT-305;Lo;0;L;;;;;N;;;;;\n18931;TANGUT COMPONENT-306;Lo;0;L;;;;;N;;;;;\n18932;TANGUT COMPONENT-307;Lo;0;L;;;;;N;;;;;\n18933;TANGUT COMPONENT-308;Lo;0;L;;;;;N;;;;;\n18934;TANGUT COMPONENT-309;Lo;0;L;;;;;N;;;;;\n18935;TANGUT COMPONENT-310;Lo;0;L;;;;;N;;;;;\n18936;TANGUT COMPONENT-311;Lo;0;L;;;;;N;;;;;\n18937;TANGUT COMPONENT-312;Lo;0;L;;;;;N;;;;;\n18938;TANGUT COMPONENT-313;Lo;0;L;;;;;N;;;;;\n18939;TANGUT COMPONENT-314;Lo;0;L;;;;;N;;;;;\n1893A;TANGUT COMPONENT-315;Lo;0;L;;;;;N;;;;;\n1893B;TANGUT COMPONENT-316;Lo;0;L;;;;;N;;;;;\n1893C;TANGUT COMPONENT-317;Lo;0;L;;;;;N;;;;;\n1893D;TANGUT COMPONENT-318;Lo;0;L;;;;;N;;;;;\n1893E;TANGUT COMPONENT-319;Lo;0;L;;;;;N;;;;;\n1893F;TANGUT COMPONENT-320;Lo;0;L;;;;;N;;;;;\n18940;TANGUT COMPONENT-321;Lo;0;L;;;;;N;;;;;\n18941;TANGUT COMPONENT-322;Lo;0;L;;;;;N;;;;;\n18942;TANGUT COMPONENT-323;Lo;0;L;;;;;N;;;;;\n18943;TANGUT COMPONENT-324;Lo;0;L;;;;;N;;;;;\n18944;TANGUT COMPONENT-325;Lo;0;L;;;;;N;;;;;\n18945;TANGUT COMPONENT-326;Lo;0;L;;;;;N;;;;;\n18946;TANGUT COMPONENT-327;Lo;0;L;;;;;N;;;;;\n18947;TANGUT COMPONENT-328;Lo;0;L;;;;;N;;;;;\n18948;TANGUT COMPONENT-329;Lo;0;L;;;;;N;;;;;\n18949;TANGUT COMPONENT-330;Lo;0;L;;;;;N;;;;;\n1894A;TANGUT COMPONENT-331;Lo;0;L;;;;;N;;;;;\n1894B;TANGUT COMPONENT-332;Lo;0;L;;;;;N;;;;;\n1894C;TANGUT COMPONENT-333;Lo;0;L;;;;;N;;;;;\n1894D;TANGUT COMPONENT-334;Lo;0;L;;;;;N;;;;;\n1894E;TANGUT COMPONENT-335;Lo;0;L;;;;;N;;;;;\n1894F;TANGUT COMPONENT-336;Lo;0;L;;;;;N;;;;;\n18950;TANGUT COMPONENT-337;Lo;0;L;;;;;N;;;;;\n18951;TANGUT COMPONENT-338;Lo;0;L;;;;;N;;;;;\n18952;TANGUT COMPONENT-339;Lo;0;L;;;;;N;;;;;\n18953;TANGUT COMPONENT-340;Lo;0;L;;;;;N;;;;;\n18954;TANGUT COMPONENT-341;Lo;0;L;;;;;N;;;;;\n18955;TANGUT COMPONENT-342;Lo;0;L;;;;;N;;;;;\n18956;TANGUT COMPONENT-343;Lo;0;L;;;;;N;;;;;\n18957;TANGUT COMPONENT-344;Lo;0;L;;;;;N;;;;;\n18958;TANGUT COMPONENT-345;Lo;0;L;;;;;N;;;;;\n18959;TANGUT COMPONENT-346;Lo;0;L;;;;;N;;;;;\n1895A;TANGUT COMPONENT-347;Lo;0;L;;;;;N;;;;;\n1895B;TANGUT COMPONENT-348;Lo;0;L;;;;;N;;;;;\n1895C;TANGUT COMPONENT-349;Lo;0;L;;;;;N;;;;;\n1895D;TANGUT COMPONENT-350;Lo;0;L;;;;;N;;;;;\n1895E;TANGUT COMPONENT-351;Lo;0;L;;;;;N;;;;;\n1895F;TANGUT COMPONENT-352;Lo;0;L;;;;;N;;;;;\n18960;TANGUT COMPONENT-353;Lo;0;L;;;;;N;;;;;\n18961;TANGUT COMPONENT-354;Lo;0;L;;;;;N;;;;;\n18962;TANGUT COMPONENT-355;Lo;0;L;;;;;N;;;;;\n18963;TANGUT COMPONENT-356;Lo;0;L;;;;;N;;;;;\n18964;TANGUT COMPONENT-357;Lo;0;L;;;;;N;;;;;\n18965;TANGUT COMPONENT-358;Lo;0;L;;;;;N;;;;;\n18966;TANGUT COMPONENT-359;Lo;0;L;;;;;N;;;;;\n18967;TANGUT COMPONENT-360;Lo;0;L;;;;;N;;;;;\n18968;TANGUT COMPONENT-361;Lo;0;L;;;;;N;;;;;\n18969;TANGUT COMPONENT-362;Lo;0;L;;;;;N;;;;;\n1896A;TANGUT COMPONENT-363;Lo;0;L;;;;;N;;;;;\n1896B;TANGUT COMPONENT-364;Lo;0;L;;;;;N;;;;;\n1896C;TANGUT COMPONENT-365;Lo;0;L;;;;;N;;;;;\n1896D;TANGUT COMPONENT-366;Lo;0;L;;;;;N;;;;;\n1896E;TANGUT COMPONENT-367;Lo;0;L;;;;;N;;;;;\n1896F;TANGUT COMPONENT-368;Lo;0;L;;;;;N;;;;;\n18970;TANGUT COMPONENT-369;Lo;0;L;;;;;N;;;;;\n18971;TANGUT COMPONENT-370;Lo;0;L;;;;;N;;;;;\n18972;TANGUT COMPONENT-371;Lo;0;L;;;;;N;;;;;\n18973;TANGUT COMPONENT-372;Lo;0;L;;;;;N;;;;;\n18974;TANGUT COMPONENT-373;Lo;0;L;;;;;N;;;;;\n18975;TANGUT COMPONENT-374;Lo;0;L;;;;;N;;;;;\n18976;TANGUT COMPONENT-375;Lo;0;L;;;;;N;;;;;\n18977;TANGUT COMPONENT-376;Lo;0;L;;;;;N;;;;;\n18978;TANGUT COMPONENT-377;Lo;0;L;;;;;N;;;;;\n18979;TANGUT COMPONENT-378;Lo;0;L;;;;;N;;;;;\n1897A;TANGUT COMPONENT-379;Lo;0;L;;;;;N;;;;;\n1897B;TANGUT COMPONENT-380;Lo;0;L;;;;;N;;;;;\n1897C;TANGUT COMPONENT-381;Lo;0;L;;;;;N;;;;;\n1897D;TANGUT COMPONENT-382;Lo;0;L;;;;;N;;;;;\n1897E;TANGUT COMPONENT-383;Lo;0;L;;;;;N;;;;;\n1897F;TANGUT COMPONENT-384;Lo;0;L;;;;;N;;;;;\n18980;TANGUT COMPONENT-385;Lo;0;L;;;;;N;;;;;\n18981;TANGUT COMPONENT-386;Lo;0;L;;;;;N;;;;;\n18982;TANGUT COMPONENT-387;Lo;0;L;;;;;N;;;;;\n18983;TANGUT COMPONENT-388;Lo;0;L;;;;;N;;;;;\n18984;TANGUT COMPONENT-389;Lo;0;L;;;;;N;;;;;\n18985;TANGUT COMPONENT-390;Lo;0;L;;;;;N;;;;;\n18986;TANGUT COMPONENT-391;Lo;0;L;;;;;N;;;;;\n18987;TANGUT COMPONENT-392;Lo;0;L;;;;;N;;;;;\n18988;TANGUT COMPONENT-393;Lo;0;L;;;;;N;;;;;\n18989;TANGUT COMPONENT-394;Lo;0;L;;;;;N;;;;;\n1898A;TANGUT COMPONENT-395;Lo;0;L;;;;;N;;;;;\n1898B;TANGUT COMPONENT-396;Lo;0;L;;;;;N;;;;;\n1898C;TANGUT COMPONENT-397;Lo;0;L;;;;;N;;;;;\n1898D;TANGUT COMPONENT-398;Lo;0;L;;;;;N;;;;;\n1898E;TANGUT COMPONENT-399;Lo;0;L;;;;;N;;;;;\n1898F;TANGUT COMPONENT-400;Lo;0;L;;;;;N;;;;;\n18990;TANGUT COMPONENT-401;Lo;0;L;;;;;N;;;;;\n18991;TANGUT COMPONENT-402;Lo;0;L;;;;;N;;;;;\n18992;TANGUT COMPONENT-403;Lo;0;L;;;;;N;;;;;\n18993;TANGUT COMPONENT-404;Lo;0;L;;;;;N;;;;;\n18994;TANGUT COMPONENT-405;Lo;0;L;;;;;N;;;;;\n18995;TANGUT COMPONENT-406;Lo;0;L;;;;;N;;;;;\n18996;TANGUT COMPONENT-407;Lo;0;L;;;;;N;;;;;\n18997;TANGUT COMPONENT-408;Lo;0;L;;;;;N;;;;;\n18998;TANGUT COMPONENT-409;Lo;0;L;;;;;N;;;;;\n18999;TANGUT COMPONENT-410;Lo;0;L;;;;;N;;;;;\n1899A;TANGUT COMPONENT-411;Lo;0;L;;;;;N;;;;;\n1899B;TANGUT COMPONENT-412;Lo;0;L;;;;;N;;;;;\n1899C;TANGUT COMPONENT-413;Lo;0;L;;;;;N;;;;;\n1899D;TANGUT COMPONENT-414;Lo;0;L;;;;;N;;;;;\n1899E;TANGUT COMPONENT-415;Lo;0;L;;;;;N;;;;;\n1899F;TANGUT COMPONENT-416;Lo;0;L;;;;;N;;;;;\n189A0;TANGUT COMPONENT-417;Lo;0;L;;;;;N;;;;;\n189A1;TANGUT COMPONENT-418;Lo;0;L;;;;;N;;;;;\n189A2;TANGUT COMPONENT-419;Lo;0;L;;;;;N;;;;;\n189A3;TANGUT COMPONENT-420;Lo;0;L;;;;;N;;;;;\n189A4;TANGUT COMPONENT-421;Lo;0;L;;;;;N;;;;;\n189A5;TANGUT COMPONENT-422;Lo;0;L;;;;;N;;;;;\n189A6;TANGUT COMPONENT-423;Lo;0;L;;;;;N;;;;;\n189A7;TANGUT COMPONENT-424;Lo;0;L;;;;;N;;;;;\n189A8;TANGUT COMPONENT-425;Lo;0;L;;;;;N;;;;;\n189A9;TANGUT COMPONENT-426;Lo;0;L;;;;;N;;;;;\n189AA;TANGUT COMPONENT-427;Lo;0;L;;;;;N;;;;;\n189AB;TANGUT COMPONENT-428;Lo;0;L;;;;;N;;;;;\n189AC;TANGUT COMPONENT-429;Lo;0;L;;;;;N;;;;;\n189AD;TANGUT COMPONENT-430;Lo;0;L;;;;;N;;;;;\n189AE;TANGUT COMPONENT-431;Lo;0;L;;;;;N;;;;;\n189AF;TANGUT COMPONENT-432;Lo;0;L;;;;;N;;;;;\n189B0;TANGUT COMPONENT-433;Lo;0;L;;;;;N;;;;;\n189B1;TANGUT COMPONENT-434;Lo;0;L;;;;;N;;;;;\n189B2;TANGUT COMPONENT-435;Lo;0;L;;;;;N;;;;;\n189B3;TANGUT COMPONENT-436;Lo;0;L;;;;;N;;;;;\n189B4;TANGUT COMPONENT-437;Lo;0;L;;;;;N;;;;;\n189B5;TANGUT COMPONENT-438;Lo;0;L;;;;;N;;;;;\n189B6;TANGUT COMPONENT-439;Lo;0;L;;;;;N;;;;;\n189B7;TANGUT COMPONENT-440;Lo;0;L;;;;;N;;;;;\n189B8;TANGUT COMPONENT-441;Lo;0;L;;;;;N;;;;;\n189B9;TANGUT COMPONENT-442;Lo;0;L;;;;;N;;;;;\n189BA;TANGUT COMPONENT-443;Lo;0;L;;;;;N;;;;;\n189BB;TANGUT COMPONENT-444;Lo;0;L;;;;;N;;;;;\n189BC;TANGUT COMPONENT-445;Lo;0;L;;;;;N;;;;;\n189BD;TANGUT COMPONENT-446;Lo;0;L;;;;;N;;;;;\n189BE;TANGUT COMPONENT-447;Lo;0;L;;;;;N;;;;;\n189BF;TANGUT COMPONENT-448;Lo;0;L;;;;;N;;;;;\n189C0;TANGUT COMPONENT-449;Lo;0;L;;;;;N;;;;;\n189C1;TANGUT COMPONENT-450;Lo;0;L;;;;;N;;;;;\n189C2;TANGUT COMPONENT-451;Lo;0;L;;;;;N;;;;;\n189C3;TANGUT COMPONENT-452;Lo;0;L;;;;;N;;;;;\n189C4;TANGUT COMPONENT-453;Lo;0;L;;;;;N;;;;;\n189C5;TANGUT COMPONENT-454;Lo;0;L;;;;;N;;;;;\n189C6;TANGUT COMPONENT-455;Lo;0;L;;;;;N;;;;;\n189C7;TANGUT COMPONENT-456;Lo;0;L;;;;;N;;;;;\n189C8;TANGUT COMPONENT-457;Lo;0;L;;;;;N;;;;;\n189C9;TANGUT COMPONENT-458;Lo;0;L;;;;;N;;;;;\n189CA;TANGUT COMPONENT-459;Lo;0;L;;;;;N;;;;;\n189CB;TANGUT COMPONENT-460;Lo;0;L;;;;;N;;;;;\n189CC;TANGUT COMPONENT-461;Lo;0;L;;;;;N;;;;;\n189CD;TANGUT COMPONENT-462;Lo;0;L;;;;;N;;;;;\n189CE;TANGUT COMPONENT-463;Lo;0;L;;;;;N;;;;;\n189CF;TANGUT COMPONENT-464;Lo;0;L;;;;;N;;;;;\n189D0;TANGUT COMPONENT-465;Lo;0;L;;;;;N;;;;;\n189D1;TANGUT COMPONENT-466;Lo;0;L;;;;;N;;;;;\n189D2;TANGUT COMPONENT-467;Lo;0;L;;;;;N;;;;;\n189D3;TANGUT COMPONENT-468;Lo;0;L;;;;;N;;;;;\n189D4;TANGUT COMPONENT-469;Lo;0;L;;;;;N;;;;;\n189D5;TANGUT COMPONENT-470;Lo;0;L;;;;;N;;;;;\n189D6;TANGUT COMPONENT-471;Lo;0;L;;;;;N;;;;;\n189D7;TANGUT COMPONENT-472;Lo;0;L;;;;;N;;;;;\n189D8;TANGUT COMPONENT-473;Lo;0;L;;;;;N;;;;;\n189D9;TANGUT COMPONENT-474;Lo;0;L;;;;;N;;;;;\n189DA;TANGUT COMPONENT-475;Lo;0;L;;;;;N;;;;;\n189DB;TANGUT COMPONENT-476;Lo;0;L;;;;;N;;;;;\n189DC;TANGUT COMPONENT-477;Lo;0;L;;;;;N;;;;;\n189DD;TANGUT COMPONENT-478;Lo;0;L;;;;;N;;;;;\n189DE;TANGUT COMPONENT-479;Lo;0;L;;;;;N;;;;;\n189DF;TANGUT COMPONENT-480;Lo;0;L;;;;;N;;;;;\n189E0;TANGUT COMPONENT-481;Lo;0;L;;;;;N;;;;;\n189E1;TANGUT COMPONENT-482;Lo;0;L;;;;;N;;;;;\n189E2;TANGUT COMPONENT-483;Lo;0;L;;;;;N;;;;;\n189E3;TANGUT COMPONENT-484;Lo;0;L;;;;;N;;;;;\n189E4;TANGUT COMPONENT-485;Lo;0;L;;;;;N;;;;;\n189E5;TANGUT COMPONENT-486;Lo;0;L;;;;;N;;;;;\n189E6;TANGUT COMPONENT-487;Lo;0;L;;;;;N;;;;;\n189E7;TANGUT COMPONENT-488;Lo;0;L;;;;;N;;;;;\n189E8;TANGUT COMPONENT-489;Lo;0;L;;;;;N;;;;;\n189E9;TANGUT COMPONENT-490;Lo;0;L;;;;;N;;;;;\n189EA;TANGUT COMPONENT-491;Lo;0;L;;;;;N;;;;;\n189EB;TANGUT COMPONENT-492;Lo;0;L;;;;;N;;;;;\n189EC;TANGUT COMPONENT-493;Lo;0;L;;;;;N;;;;;\n189ED;TANGUT COMPONENT-494;Lo;0;L;;;;;N;;;;;\n189EE;TANGUT COMPONENT-495;Lo;0;L;;;;;N;;;;;\n189EF;TANGUT COMPONENT-496;Lo;0;L;;;;;N;;;;;\n189F0;TANGUT COMPONENT-497;Lo;0;L;;;;;N;;;;;\n189F1;TANGUT COMPONENT-498;Lo;0;L;;;;;N;;;;;\n189F2;TANGUT COMPONENT-499;Lo;0;L;;;;;N;;;;;\n189F3;TANGUT COMPONENT-500;Lo;0;L;;;;;N;;;;;\n189F4;TANGUT COMPONENT-501;Lo;0;L;;;;;N;;;;;\n189F5;TANGUT COMPONENT-502;Lo;0;L;;;;;N;;;;;\n189F6;TANGUT COMPONENT-503;Lo;0;L;;;;;N;;;;;\n189F7;TANGUT COMPONENT-504;Lo;0;L;;;;;N;;;;;\n189F8;TANGUT COMPONENT-505;Lo;0;L;;;;;N;;;;;\n189F9;TANGUT COMPONENT-506;Lo;0;L;;;;;N;;;;;\n189FA;TANGUT COMPONENT-507;Lo;0;L;;;;;N;;;;;\n189FB;TANGUT COMPONENT-508;Lo;0;L;;;;;N;;;;;\n189FC;TANGUT COMPONENT-509;Lo;0;L;;;;;N;;;;;\n189FD;TANGUT COMPONENT-510;Lo;0;L;;;;;N;;;;;\n189FE;TANGUT COMPONENT-511;Lo;0;L;;;;;N;;;;;\n189FF;TANGUT COMPONENT-512;Lo;0;L;;;;;N;;;;;\n18A00;TANGUT COMPONENT-513;Lo;0;L;;;;;N;;;;;\n18A01;TANGUT COMPONENT-514;Lo;0;L;;;;;N;;;;;\n18A02;TANGUT COMPONENT-515;Lo;0;L;;;;;N;;;;;\n18A03;TANGUT COMPONENT-516;Lo;0;L;;;;;N;;;;;\n18A04;TANGUT COMPONENT-517;Lo;0;L;;;;;N;;;;;\n18A05;TANGUT COMPONENT-518;Lo;0;L;;;;;N;;;;;\n18A06;TANGUT COMPONENT-519;Lo;0;L;;;;;N;;;;;\n18A07;TANGUT COMPONENT-520;Lo;0;L;;;;;N;;;;;\n18A08;TANGUT COMPONENT-521;Lo;0;L;;;;;N;;;;;\n18A09;TANGUT COMPONENT-522;Lo;0;L;;;;;N;;;;;\n18A0A;TANGUT COMPONENT-523;Lo;0;L;;;;;N;;;;;\n18A0B;TANGUT COMPONENT-524;Lo;0;L;;;;;N;;;;;\n18A0C;TANGUT COMPONENT-525;Lo;0;L;;;;;N;;;;;\n18A0D;TANGUT COMPONENT-526;Lo;0;L;;;;;N;;;;;\n18A0E;TANGUT COMPONENT-527;Lo;0;L;;;;;N;;;;;\n18A0F;TANGUT COMPONENT-528;Lo;0;L;;;;;N;;;;;\n18A10;TANGUT COMPONENT-529;Lo;0;L;;;;;N;;;;;\n18A11;TANGUT COMPONENT-530;Lo;0;L;;;;;N;;;;;\n18A12;TANGUT COMPONENT-531;Lo;0;L;;;;;N;;;;;\n18A13;TANGUT COMPONENT-532;Lo;0;L;;;;;N;;;;;\n18A14;TANGUT COMPONENT-533;Lo;0;L;;;;;N;;;;;\n18A15;TANGUT COMPONENT-534;Lo;0;L;;;;;N;;;;;\n18A16;TANGUT COMPONENT-535;Lo;0;L;;;;;N;;;;;\n18A17;TANGUT COMPONENT-536;Lo;0;L;;;;;N;;;;;\n18A18;TANGUT COMPONENT-537;Lo;0;L;;;;;N;;;;;\n18A19;TANGUT COMPONENT-538;Lo;0;L;;;;;N;;;;;\n18A1A;TANGUT COMPONENT-539;Lo;0;L;;;;;N;;;;;\n18A1B;TANGUT COMPONENT-540;Lo;0;L;;;;;N;;;;;\n18A1C;TANGUT COMPONENT-541;Lo;0;L;;;;;N;;;;;\n18A1D;TANGUT COMPONENT-542;Lo;0;L;;;;;N;;;;;\n18A1E;TANGUT COMPONENT-543;Lo;0;L;;;;;N;;;;;\n18A1F;TANGUT COMPONENT-544;Lo;0;L;;;;;N;;;;;\n18A20;TANGUT COMPONENT-545;Lo;0;L;;;;;N;;;;;\n18A21;TANGUT COMPONENT-546;Lo;0;L;;;;;N;;;;;\n18A22;TANGUT COMPONENT-547;Lo;0;L;;;;;N;;;;;\n18A23;TANGUT COMPONENT-548;Lo;0;L;;;;;N;;;;;\n18A24;TANGUT COMPONENT-549;Lo;0;L;;;;;N;;;;;\n18A25;TANGUT COMPONENT-550;Lo;0;L;;;;;N;;;;;\n18A26;TANGUT COMPONENT-551;Lo;0;L;;;;;N;;;;;\n18A27;TANGUT COMPONENT-552;Lo;0;L;;;;;N;;;;;\n18A28;TANGUT COMPONENT-553;Lo;0;L;;;;;N;;;;;\n18A29;TANGUT COMPONENT-554;Lo;0;L;;;;;N;;;;;\n18A2A;TANGUT COMPONENT-555;Lo;0;L;;;;;N;;;;;\n18A2B;TANGUT COMPONENT-556;Lo;0;L;;;;;N;;;;;\n18A2C;TANGUT COMPONENT-557;Lo;0;L;;;;;N;;;;;\n18A2D;TANGUT COMPONENT-558;Lo;0;L;;;;;N;;;;;\n18A2E;TANGUT COMPONENT-559;Lo;0;L;;;;;N;;;;;\n18A2F;TANGUT COMPONENT-560;Lo;0;L;;;;;N;;;;;\n18A30;TANGUT COMPONENT-561;Lo;0;L;;;;;N;;;;;\n18A31;TANGUT COMPONENT-562;Lo;0;L;;;;;N;;;;;\n18A32;TANGUT COMPONENT-563;Lo;0;L;;;;;N;;;;;\n18A33;TANGUT COMPONENT-564;Lo;0;L;;;;;N;;;;;\n18A34;TANGUT COMPONENT-565;Lo;0;L;;;;;N;;;;;\n18A35;TANGUT COMPONENT-566;Lo;0;L;;;;;N;;;;;\n18A36;TANGUT COMPONENT-567;Lo;0;L;;;;;N;;;;;\n18A37;TANGUT COMPONENT-568;Lo;0;L;;;;;N;;;;;\n18A38;TANGUT COMPONENT-569;Lo;0;L;;;;;N;;;;;\n18A39;TANGUT COMPONENT-570;Lo;0;L;;;;;N;;;;;\n18A3A;TANGUT COMPONENT-571;Lo;0;L;;;;;N;;;;;\n18A3B;TANGUT COMPONENT-572;Lo;0;L;;;;;N;;;;;\n18A3C;TANGUT COMPONENT-573;Lo;0;L;;;;;N;;;;;\n18A3D;TANGUT COMPONENT-574;Lo;0;L;;;;;N;;;;;\n18A3E;TANGUT COMPONENT-575;Lo;0;L;;;;;N;;;;;\n18A3F;TANGUT COMPONENT-576;Lo;0;L;;;;;N;;;;;\n18A40;TANGUT COMPONENT-577;Lo;0;L;;;;;N;;;;;\n18A41;TANGUT COMPONENT-578;Lo;0;L;;;;;N;;;;;\n18A42;TANGUT COMPONENT-579;Lo;0;L;;;;;N;;;;;\n18A43;TANGUT COMPONENT-580;Lo;0;L;;;;;N;;;;;\n18A44;TANGUT COMPONENT-581;Lo;0;L;;;;;N;;;;;\n18A45;TANGUT COMPONENT-582;Lo;0;L;;;;;N;;;;;\n18A46;TANGUT COMPONENT-583;Lo;0;L;;;;;N;;;;;\n18A47;TANGUT COMPONENT-584;Lo;0;L;;;;;N;;;;;\n18A48;TANGUT COMPONENT-585;Lo;0;L;;;;;N;;;;;\n18A49;TANGUT COMPONENT-586;Lo;0;L;;;;;N;;;;;\n18A4A;TANGUT COMPONENT-587;Lo;0;L;;;;;N;;;;;\n18A4B;TANGUT COMPONENT-588;Lo;0;L;;;;;N;;;;;\n18A4C;TANGUT COMPONENT-589;Lo;0;L;;;;;N;;;;;\n18A4D;TANGUT COMPONENT-590;Lo;0;L;;;;;N;;;;;\n18A4E;TANGUT COMPONENT-591;Lo;0;L;;;;;N;;;;;\n18A4F;TANGUT COMPONENT-592;Lo;0;L;;;;;N;;;;;\n18A50;TANGUT COMPONENT-593;Lo;0;L;;;;;N;;;;;\n18A51;TANGUT COMPONENT-594;Lo;0;L;;;;;N;;;;;\n18A52;TANGUT COMPONENT-595;Lo;0;L;;;;;N;;;;;\n18A53;TANGUT COMPONENT-596;Lo;0;L;;;;;N;;;;;\n18A54;TANGUT COMPONENT-597;Lo;0;L;;;;;N;;;;;\n18A55;TANGUT COMPONENT-598;Lo;0;L;;;;;N;;;;;\n18A56;TANGUT COMPONENT-599;Lo;0;L;;;;;N;;;;;\n18A57;TANGUT COMPONENT-600;Lo;0;L;;;;;N;;;;;\n18A58;TANGUT COMPONENT-601;Lo;0;L;;;;;N;;;;;\n18A59;TANGUT COMPONENT-602;Lo;0;L;;;;;N;;;;;\n18A5A;TANGUT COMPONENT-603;Lo;0;L;;;;;N;;;;;\n18A5B;TANGUT COMPONENT-604;Lo;0;L;;;;;N;;;;;\n18A5C;TANGUT COMPONENT-605;Lo;0;L;;;;;N;;;;;\n18A5D;TANGUT COMPONENT-606;Lo;0;L;;;;;N;;;;;\n18A5E;TANGUT COMPONENT-607;Lo;0;L;;;;;N;;;;;\n18A5F;TANGUT COMPONENT-608;Lo;0;L;;;;;N;;;;;\n18A60;TANGUT COMPONENT-609;Lo;0;L;;;;;N;;;;;\n18A61;TANGUT COMPONENT-610;Lo;0;L;;;;;N;;;;;\n18A62;TANGUT COMPONENT-611;Lo;0;L;;;;;N;;;;;\n18A63;TANGUT COMPONENT-612;Lo;0;L;;;;;N;;;;;\n18A64;TANGUT COMPONENT-613;Lo;0;L;;;;;N;;;;;\n18A65;TANGUT COMPONENT-614;Lo;0;L;;;;;N;;;;;\n18A66;TANGUT COMPONENT-615;Lo;0;L;;;;;N;;;;;\n18A67;TANGUT COMPONENT-616;Lo;0;L;;;;;N;;;;;\n18A68;TANGUT COMPONENT-617;Lo;0;L;;;;;N;;;;;\n18A69;TANGUT COMPONENT-618;Lo;0;L;;;;;N;;;;;\n18A6A;TANGUT COMPONENT-619;Lo;0;L;;;;;N;;;;;\n18A6B;TANGUT COMPONENT-620;Lo;0;L;;;;;N;;;;;\n18A6C;TANGUT COMPONENT-621;Lo;0;L;;;;;N;;;;;\n18A6D;TANGUT COMPONENT-622;Lo;0;L;;;;;N;;;;;\n18A6E;TANGUT COMPONENT-623;Lo;0;L;;;;;N;;;;;\n18A6F;TANGUT COMPONENT-624;Lo;0;L;;;;;N;;;;;\n18A70;TANGUT COMPONENT-625;Lo;0;L;;;;;N;;;;;\n18A71;TANGUT COMPONENT-626;Lo;0;L;;;;;N;;;;;\n18A72;TANGUT COMPONENT-627;Lo;0;L;;;;;N;;;;;\n18A73;TANGUT COMPONENT-628;Lo;0;L;;;;;N;;;;;\n18A74;TANGUT COMPONENT-629;Lo;0;L;;;;;N;;;;;\n18A75;TANGUT COMPONENT-630;Lo;0;L;;;;;N;;;;;\n18A76;TANGUT COMPONENT-631;Lo;0;L;;;;;N;;;;;\n18A77;TANGUT COMPONENT-632;Lo;0;L;;;;;N;;;;;\n18A78;TANGUT COMPONENT-633;Lo;0;L;;;;;N;;;;;\n18A79;TANGUT COMPONENT-634;Lo;0;L;;;;;N;;;;;\n18A7A;TANGUT COMPONENT-635;Lo;0;L;;;;;N;;;;;\n18A7B;TANGUT COMPONENT-636;Lo;0;L;;;;;N;;;;;\n18A7C;TANGUT COMPONENT-637;Lo;0;L;;;;;N;;;;;\n18A7D;TANGUT COMPONENT-638;Lo;0;L;;;;;N;;;;;\n18A7E;TANGUT COMPONENT-639;Lo;0;L;;;;;N;;;;;\n18A7F;TANGUT COMPONENT-640;Lo;0;L;;;;;N;;;;;\n18A80;TANGUT COMPONENT-641;Lo;0;L;;;;;N;;;;;\n18A81;TANGUT COMPONENT-642;Lo;0;L;;;;;N;;;;;\n18A82;TANGUT COMPONENT-643;Lo;0;L;;;;;N;;;;;\n18A83;TANGUT COMPONENT-644;Lo;0;L;;;;;N;;;;;\n18A84;TANGUT COMPONENT-645;Lo;0;L;;;;;N;;;;;\n18A85;TANGUT COMPONENT-646;Lo;0;L;;;;;N;;;;;\n18A86;TANGUT COMPONENT-647;Lo;0;L;;;;;N;;;;;\n18A87;TANGUT COMPONENT-648;Lo;0;L;;;;;N;;;;;\n18A88;TANGUT COMPONENT-649;Lo;0;L;;;;;N;;;;;\n18A89;TANGUT COMPONENT-650;Lo;0;L;;;;;N;;;;;\n18A8A;TANGUT COMPONENT-651;Lo;0;L;;;;;N;;;;;\n18A8B;TANGUT COMPONENT-652;Lo;0;L;;;;;N;;;;;\n18A8C;TANGUT COMPONENT-653;Lo;0;L;;;;;N;;;;;\n18A8D;TANGUT COMPONENT-654;Lo;0;L;;;;;N;;;;;\n18A8E;TANGUT COMPONENT-655;Lo;0;L;;;;;N;;;;;\n18A8F;TANGUT COMPONENT-656;Lo;0;L;;;;;N;;;;;\n18A90;TANGUT COMPONENT-657;Lo;0;L;;;;;N;;;;;\n18A91;TANGUT COMPONENT-658;Lo;0;L;;;;;N;;;;;\n18A92;TANGUT COMPONENT-659;Lo;0;L;;;;;N;;;;;\n18A93;TANGUT COMPONENT-660;Lo;0;L;;;;;N;;;;;\n18A94;TANGUT COMPONENT-661;Lo;0;L;;;;;N;;;;;\n18A95;TANGUT COMPONENT-662;Lo;0;L;;;;;N;;;;;\n18A96;TANGUT COMPONENT-663;Lo;0;L;;;;;N;;;;;\n18A97;TANGUT COMPONENT-664;Lo;0;L;;;;;N;;;;;\n18A98;TANGUT COMPONENT-665;Lo;0;L;;;;;N;;;;;\n18A99;TANGUT COMPONENT-666;Lo;0;L;;;;;N;;;;;\n18A9A;TANGUT COMPONENT-667;Lo;0;L;;;;;N;;;;;\n18A9B;TANGUT COMPONENT-668;Lo;0;L;;;;;N;;;;;\n18A9C;TANGUT COMPONENT-669;Lo;0;L;;;;;N;;;;;\n18A9D;TANGUT COMPONENT-670;Lo;0;L;;;;;N;;;;;\n18A9E;TANGUT COMPONENT-671;Lo;0;L;;;;;N;;;;;\n18A9F;TANGUT COMPONENT-672;Lo;0;L;;;;;N;;;;;\n18AA0;TANGUT COMPONENT-673;Lo;0;L;;;;;N;;;;;\n18AA1;TANGUT COMPONENT-674;Lo;0;L;;;;;N;;;;;\n18AA2;TANGUT COMPONENT-675;Lo;0;L;;;;;N;;;;;\n18AA3;TANGUT COMPONENT-676;Lo;0;L;;;;;N;;;;;\n18AA4;TANGUT COMPONENT-677;Lo;0;L;;;;;N;;;;;\n18AA5;TANGUT COMPONENT-678;Lo;0;L;;;;;N;;;;;\n18AA6;TANGUT COMPONENT-679;Lo;0;L;;;;;N;;;;;\n18AA7;TANGUT COMPONENT-680;Lo;0;L;;;;;N;;;;;\n18AA8;TANGUT COMPONENT-681;Lo;0;L;;;;;N;;;;;\n18AA9;TANGUT COMPONENT-682;Lo;0;L;;;;;N;;;;;\n18AAA;TANGUT COMPONENT-683;Lo;0;L;;;;;N;;;;;\n18AAB;TANGUT COMPONENT-684;Lo;0;L;;;;;N;;;;;\n18AAC;TANGUT COMPONENT-685;Lo;0;L;;;;;N;;;;;\n18AAD;TANGUT COMPONENT-686;Lo;0;L;;;;;N;;;;;\n18AAE;TANGUT COMPONENT-687;Lo;0;L;;;;;N;;;;;\n18AAF;TANGUT COMPONENT-688;Lo;0;L;;;;;N;;;;;\n18AB0;TANGUT COMPONENT-689;Lo;0;L;;;;;N;;;;;\n18AB1;TANGUT COMPONENT-690;Lo;0;L;;;;;N;;;;;\n18AB2;TANGUT COMPONENT-691;Lo;0;L;;;;;N;;;;;\n18AB3;TANGUT COMPONENT-692;Lo;0;L;;;;;N;;;;;\n18AB4;TANGUT COMPONENT-693;Lo;0;L;;;;;N;;;;;\n18AB5;TANGUT COMPONENT-694;Lo;0;L;;;;;N;;;;;\n18AB6;TANGUT COMPONENT-695;Lo;0;L;;;;;N;;;;;\n18AB7;TANGUT COMPONENT-696;Lo;0;L;;;;;N;;;;;\n18AB8;TANGUT COMPONENT-697;Lo;0;L;;;;;N;;;;;\n18AB9;TANGUT COMPONENT-698;Lo;0;L;;;;;N;;;;;\n18ABA;TANGUT COMPONENT-699;Lo;0;L;;;;;N;;;;;\n18ABB;TANGUT COMPONENT-700;Lo;0;L;;;;;N;;;;;\n18ABC;TANGUT COMPONENT-701;Lo;0;L;;;;;N;;;;;\n18ABD;TANGUT COMPONENT-702;Lo;0;L;;;;;N;;;;;\n18ABE;TANGUT COMPONENT-703;Lo;0;L;;;;;N;;;;;\n18ABF;TANGUT COMPONENT-704;Lo;0;L;;;;;N;;;;;\n18AC0;TANGUT COMPONENT-705;Lo;0;L;;;;;N;;;;;\n18AC1;TANGUT COMPONENT-706;Lo;0;L;;;;;N;;;;;\n18AC2;TANGUT COMPONENT-707;Lo;0;L;;;;;N;;;;;\n18AC3;TANGUT COMPONENT-708;Lo;0;L;;;;;N;;;;;\n18AC4;TANGUT COMPONENT-709;Lo;0;L;;;;;N;;;;;\n18AC5;TANGUT COMPONENT-710;Lo;0;L;;;;;N;;;;;\n18AC6;TANGUT COMPONENT-711;Lo;0;L;;;;;N;;;;;\n18AC7;TANGUT COMPONENT-712;Lo;0;L;;;;;N;;;;;\n18AC8;TANGUT COMPONENT-713;Lo;0;L;;;;;N;;;;;\n18AC9;TANGUT COMPONENT-714;Lo;0;L;;;;;N;;;;;\n18ACA;TANGUT COMPONENT-715;Lo;0;L;;;;;N;;;;;\n18ACB;TANGUT COMPONENT-716;Lo;0;L;;;;;N;;;;;\n18ACC;TANGUT COMPONENT-717;Lo;0;L;;;;;N;;;;;\n18ACD;TANGUT COMPONENT-718;Lo;0;L;;;;;N;;;;;\n18ACE;TANGUT COMPONENT-719;Lo;0;L;;;;;N;;;;;\n18ACF;TANGUT COMPONENT-720;Lo;0;L;;;;;N;;;;;\n18AD0;TANGUT COMPONENT-721;Lo;0;L;;;;;N;;;;;\n18AD1;TANGUT COMPONENT-722;Lo;0;L;;;;;N;;;;;\n18AD2;TANGUT COMPONENT-723;Lo;0;L;;;;;N;;;;;\n18AD3;TANGUT COMPONENT-724;Lo;0;L;;;;;N;;;;;\n18AD4;TANGUT COMPONENT-725;Lo;0;L;;;;;N;;;;;\n18AD5;TANGUT COMPONENT-726;Lo;0;L;;;;;N;;;;;\n18AD6;TANGUT COMPONENT-727;Lo;0;L;;;;;N;;;;;\n18AD7;TANGUT COMPONENT-728;Lo;0;L;;;;;N;;;;;\n18AD8;TANGUT COMPONENT-729;Lo;0;L;;;;;N;;;;;\n18AD9;TANGUT COMPONENT-730;Lo;0;L;;;;;N;;;;;\n18ADA;TANGUT COMPONENT-731;Lo;0;L;;;;;N;;;;;\n18ADB;TANGUT COMPONENT-732;Lo;0;L;;;;;N;;;;;\n18ADC;TANGUT COMPONENT-733;Lo;0;L;;;;;N;;;;;\n18ADD;TANGUT COMPONENT-734;Lo;0;L;;;;;N;;;;;\n18ADE;TANGUT COMPONENT-735;Lo;0;L;;;;;N;;;;;\n18ADF;TANGUT COMPONENT-736;Lo;0;L;;;;;N;;;;;\n18AE0;TANGUT COMPONENT-737;Lo;0;L;;;;;N;;;;;\n18AE1;TANGUT COMPONENT-738;Lo;0;L;;;;;N;;;;;\n18AE2;TANGUT COMPONENT-739;Lo;0;L;;;;;N;;;;;\n18AE3;TANGUT COMPONENT-740;Lo;0;L;;;;;N;;;;;\n18AE4;TANGUT COMPONENT-741;Lo;0;L;;;;;N;;;;;\n18AE5;TANGUT COMPONENT-742;Lo;0;L;;;;;N;;;;;\n18AE6;TANGUT COMPONENT-743;Lo;0;L;;;;;N;;;;;\n18AE7;TANGUT COMPONENT-744;Lo;0;L;;;;;N;;;;;\n18AE8;TANGUT COMPONENT-745;Lo;0;L;;;;;N;;;;;\n18AE9;TANGUT COMPONENT-746;Lo;0;L;;;;;N;;;;;\n18AEA;TANGUT COMPONENT-747;Lo;0;L;;;;;N;;;;;\n18AEB;TANGUT COMPONENT-748;Lo;0;L;;;;;N;;;;;\n18AEC;TANGUT COMPONENT-749;Lo;0;L;;;;;N;;;;;\n18AED;TANGUT COMPONENT-750;Lo;0;L;;;;;N;;;;;\n18AEE;TANGUT COMPONENT-751;Lo;0;L;;;;;N;;;;;\n18AEF;TANGUT COMPONENT-752;Lo;0;L;;;;;N;;;;;\n18AF0;TANGUT COMPONENT-753;Lo;0;L;;;;;N;;;;;\n18AF1;TANGUT COMPONENT-754;Lo;0;L;;;;;N;;;;;\n18AF2;TANGUT COMPONENT-755;Lo;0;L;;;;;N;;;;;\n1B000;KATAKANA LETTER ARCHAIC E;Lo;0;L;;;;;N;;;;;\n1B001;HIRAGANA LETTER ARCHAIC YE;Lo;0;L;;;;;N;;;;;\n1B002;HENTAIGANA LETTER A-1;Lo;0;L;;;;;N;;;;;\n1B003;HENTAIGANA LETTER A-2;Lo;0;L;;;;;N;;;;;\n1B004;HENTAIGANA LETTER A-3;Lo;0;L;;;;;N;;;;;\n1B005;HENTAIGANA LETTER A-WO;Lo;0;L;;;;;N;;;;;\n1B006;HENTAIGANA LETTER I-1;Lo;0;L;;;;;N;;;;;\n1B007;HENTAIGANA LETTER I-2;Lo;0;L;;;;;N;;;;;\n1B008;HENTAIGANA LETTER I-3;Lo;0;L;;;;;N;;;;;\n1B009;HENTAIGANA LETTER I-4;Lo;0;L;;;;;N;;;;;\n1B00A;HENTAIGANA LETTER U-1;Lo;0;L;;;;;N;;;;;\n1B00B;HENTAIGANA LETTER U-2;Lo;0;L;;;;;N;;;;;\n1B00C;HENTAIGANA LETTER U-3;Lo;0;L;;;;;N;;;;;\n1B00D;HENTAIGANA LETTER U-4;Lo;0;L;;;;;N;;;;;\n1B00E;HENTAIGANA LETTER U-5;Lo;0;L;;;;;N;;;;;\n1B00F;HENTAIGANA LETTER E-2;Lo;0;L;;;;;N;;;;;\n1B010;HENTAIGANA LETTER E-3;Lo;0;L;;;;;N;;;;;\n1B011;HENTAIGANA LETTER E-4;Lo;0;L;;;;;N;;;;;\n1B012;HENTAIGANA LETTER E-5;Lo;0;L;;;;;N;;;;;\n1B013;HENTAIGANA LETTER E-6;Lo;0;L;;;;;N;;;;;\n1B014;HENTAIGANA LETTER O-1;Lo;0;L;;;;;N;;;;;\n1B015;HENTAIGANA LETTER O-2;Lo;0;L;;;;;N;;;;;\n1B016;HENTAIGANA LETTER O-3;Lo;0;L;;;;;N;;;;;\n1B017;HENTAIGANA LETTER KA-1;Lo;0;L;;;;;N;;;;;\n1B018;HENTAIGANA LETTER KA-2;Lo;0;L;;;;;N;;;;;\n1B019;HENTAIGANA LETTER KA-3;Lo;0;L;;;;;N;;;;;\n1B01A;HENTAIGANA LETTER KA-4;Lo;0;L;;;;;N;;;;;\n1B01B;HENTAIGANA LETTER KA-5;Lo;0;L;;;;;N;;;;;\n1B01C;HENTAIGANA LETTER KA-6;Lo;0;L;;;;;N;;;;;\n1B01D;HENTAIGANA LETTER KA-7;Lo;0;L;;;;;N;;;;;\n1B01E;HENTAIGANA LETTER KA-8;Lo;0;L;;;;;N;;;;;\n1B01F;HENTAIGANA LETTER KA-9;Lo;0;L;;;;;N;;;;;\n1B020;HENTAIGANA LETTER KA-10;Lo;0;L;;;;;N;;;;;\n1B021;HENTAIGANA LETTER KA-11;Lo;0;L;;;;;N;;;;;\n1B022;HENTAIGANA LETTER KA-KE;Lo;0;L;;;;;N;;;;;\n1B023;HENTAIGANA LETTER KI-1;Lo;0;L;;;;;N;;;;;\n1B024;HENTAIGANA LETTER KI-2;Lo;0;L;;;;;N;;;;;\n1B025;HENTAIGANA LETTER KI-3;Lo;0;L;;;;;N;;;;;\n1B026;HENTAIGANA LETTER KI-4;Lo;0;L;;;;;N;;;;;\n1B027;HENTAIGANA LETTER KI-5;Lo;0;L;;;;;N;;;;;\n1B028;HENTAIGANA LETTER KI-6;Lo;0;L;;;;;N;;;;;\n1B029;HENTAIGANA LETTER KI-7;Lo;0;L;;;;;N;;;;;\n1B02A;HENTAIGANA LETTER KI-8;Lo;0;L;;;;;N;;;;;\n1B02B;HENTAIGANA LETTER KU-1;Lo;0;L;;;;;N;;;;;\n1B02C;HENTAIGANA LETTER KU-2;Lo;0;L;;;;;N;;;;;\n1B02D;HENTAIGANA LETTER KU-3;Lo;0;L;;;;;N;;;;;\n1B02E;HENTAIGANA LETTER KU-4;Lo;0;L;;;;;N;;;;;\n1B02F;HENTAIGANA LETTER KU-5;Lo;0;L;;;;;N;;;;;\n1B030;HENTAIGANA LETTER KU-6;Lo;0;L;;;;;N;;;;;\n1B031;HENTAIGANA LETTER KU-7;Lo;0;L;;;;;N;;;;;\n1B032;HENTAIGANA LETTER KE-1;Lo;0;L;;;;;N;;;;;\n1B033;HENTAIGANA LETTER KE-2;Lo;0;L;;;;;N;;;;;\n1B034;HENTAIGANA LETTER KE-3;Lo;0;L;;;;;N;;;;;\n1B035;HENTAIGANA LETTER KE-4;Lo;0;L;;;;;N;;;;;\n1B036;HENTAIGANA LETTER KE-5;Lo;0;L;;;;;N;;;;;\n1B037;HENTAIGANA LETTER KE-6;Lo;0;L;;;;;N;;;;;\n1B038;HENTAIGANA LETTER KO-1;Lo;0;L;;;;;N;;;;;\n1B039;HENTAIGANA LETTER KO-2;Lo;0;L;;;;;N;;;;;\n1B03A;HENTAIGANA LETTER KO-3;Lo;0;L;;;;;N;;;;;\n1B03B;HENTAIGANA LETTER KO-KI;Lo;0;L;;;;;N;;;;;\n1B03C;HENTAIGANA LETTER SA-1;Lo;0;L;;;;;N;;;;;\n1B03D;HENTAIGANA LETTER SA-2;Lo;0;L;;;;;N;;;;;\n1B03E;HENTAIGANA LETTER SA-3;Lo;0;L;;;;;N;;;;;\n1B03F;HENTAIGANA LETTER SA-4;Lo;0;L;;;;;N;;;;;\n1B040;HENTAIGANA LETTER SA-5;Lo;0;L;;;;;N;;;;;\n1B041;HENTAIGANA LETTER SA-6;Lo;0;L;;;;;N;;;;;\n1B042;HENTAIGANA LETTER SA-7;Lo;0;L;;;;;N;;;;;\n1B043;HENTAIGANA LETTER SA-8;Lo;0;L;;;;;N;;;;;\n1B044;HENTAIGANA LETTER SI-1;Lo;0;L;;;;;N;;;;;\n1B045;HENTAIGANA LETTER SI-2;Lo;0;L;;;;;N;;;;;\n1B046;HENTAIGANA LETTER SI-3;Lo;0;L;;;;;N;;;;;\n1B047;HENTAIGANA LETTER SI-4;Lo;0;L;;;;;N;;;;;\n1B048;HENTAIGANA LETTER SI-5;Lo;0;L;;;;;N;;;;;\n1B049;HENTAIGANA LETTER SI-6;Lo;0;L;;;;;N;;;;;\n1B04A;HENTAIGANA LETTER SU-1;Lo;0;L;;;;;N;;;;;\n1B04B;HENTAIGANA LETTER SU-2;Lo;0;L;;;;;N;;;;;\n1B04C;HENTAIGANA LETTER SU-3;Lo;0;L;;;;;N;;;;;\n1B04D;HENTAIGANA LETTER SU-4;Lo;0;L;;;;;N;;;;;\n1B04E;HENTAIGANA LETTER SU-5;Lo;0;L;;;;;N;;;;;\n1B04F;HENTAIGANA LETTER SU-6;Lo;0;L;;;;;N;;;;;\n1B050;HENTAIGANA LETTER SU-7;Lo;0;L;;;;;N;;;;;\n1B051;HENTAIGANA LETTER SU-8;Lo;0;L;;;;;N;;;;;\n1B052;HENTAIGANA LETTER SE-1;Lo;0;L;;;;;N;;;;;\n1B053;HENTAIGANA LETTER SE-2;Lo;0;L;;;;;N;;;;;\n1B054;HENTAIGANA LETTER SE-3;Lo;0;L;;;;;N;;;;;\n1B055;HENTAIGANA LETTER SE-4;Lo;0;L;;;;;N;;;;;\n1B056;HENTAIGANA LETTER SE-5;Lo;0;L;;;;;N;;;;;\n1B057;HENTAIGANA LETTER SO-1;Lo;0;L;;;;;N;;;;;\n1B058;HENTAIGANA LETTER SO-2;Lo;0;L;;;;;N;;;;;\n1B059;HENTAIGANA LETTER SO-3;Lo;0;L;;;;;N;;;;;\n1B05A;HENTAIGANA LETTER SO-4;Lo;0;L;;;;;N;;;;;\n1B05B;HENTAIGANA LETTER SO-5;Lo;0;L;;;;;N;;;;;\n1B05C;HENTAIGANA LETTER SO-6;Lo;0;L;;;;;N;;;;;\n1B05D;HENTAIGANA LETTER SO-7;Lo;0;L;;;;;N;;;;;\n1B05E;HENTAIGANA LETTER TA-1;Lo;0;L;;;;;N;;;;;\n1B05F;HENTAIGANA LETTER TA-2;Lo;0;L;;;;;N;;;;;\n1B060;HENTAIGANA LETTER TA-3;Lo;0;L;;;;;N;;;;;\n1B061;HENTAIGANA LETTER TA-4;Lo;0;L;;;;;N;;;;;\n1B062;HENTAIGANA LETTER TI-1;Lo;0;L;;;;;N;;;;;\n1B063;HENTAIGANA LETTER TI-2;Lo;0;L;;;;;N;;;;;\n1B064;HENTAIGANA LETTER TI-3;Lo;0;L;;;;;N;;;;;\n1B065;HENTAIGANA LETTER TI-4;Lo;0;L;;;;;N;;;;;\n1B066;HENTAIGANA LETTER TI-5;Lo;0;L;;;;;N;;;;;\n1B067;HENTAIGANA LETTER TI-6;Lo;0;L;;;;;N;;;;;\n1B068;HENTAIGANA LETTER TI-7;Lo;0;L;;;;;N;;;;;\n1B069;HENTAIGANA LETTER TU-1;Lo;0;L;;;;;N;;;;;\n1B06A;HENTAIGANA LETTER TU-2;Lo;0;L;;;;;N;;;;;\n1B06B;HENTAIGANA LETTER TU-3;Lo;0;L;;;;;N;;;;;\n1B06C;HENTAIGANA LETTER TU-4;Lo;0;L;;;;;N;;;;;\n1B06D;HENTAIGANA LETTER TU-TO;Lo;0;L;;;;;N;;;;;\n1B06E;HENTAIGANA LETTER TE-1;Lo;0;L;;;;;N;;;;;\n1B06F;HENTAIGANA LETTER TE-2;Lo;0;L;;;;;N;;;;;\n1B070;HENTAIGANA LETTER TE-3;Lo;0;L;;;;;N;;;;;\n1B071;HENTAIGANA LETTER TE-4;Lo;0;L;;;;;N;;;;;\n1B072;HENTAIGANA LETTER TE-5;Lo;0;L;;;;;N;;;;;\n1B073;HENTAIGANA LETTER TE-6;Lo;0;L;;;;;N;;;;;\n1B074;HENTAIGANA LETTER TE-7;Lo;0;L;;;;;N;;;;;\n1B075;HENTAIGANA LETTER TE-8;Lo;0;L;;;;;N;;;;;\n1B076;HENTAIGANA LETTER TE-9;Lo;0;L;;;;;N;;;;;\n1B077;HENTAIGANA LETTER TO-1;Lo;0;L;;;;;N;;;;;\n1B078;HENTAIGANA LETTER TO-2;Lo;0;L;;;;;N;;;;;\n1B079;HENTAIGANA LETTER TO-3;Lo;0;L;;;;;N;;;;;\n1B07A;HENTAIGANA LETTER TO-4;Lo;0;L;;;;;N;;;;;\n1B07B;HENTAIGANA LETTER TO-5;Lo;0;L;;;;;N;;;;;\n1B07C;HENTAIGANA LETTER TO-6;Lo;0;L;;;;;N;;;;;\n1B07D;HENTAIGANA LETTER TO-RA;Lo;0;L;;;;;N;;;;;\n1B07E;HENTAIGANA LETTER NA-1;Lo;0;L;;;;;N;;;;;\n1B07F;HENTAIGANA LETTER NA-2;Lo;0;L;;;;;N;;;;;\n1B080;HENTAIGANA LETTER NA-3;Lo;0;L;;;;;N;;;;;\n1B081;HENTAIGANA LETTER NA-4;Lo;0;L;;;;;N;;;;;\n1B082;HENTAIGANA LETTER NA-5;Lo;0;L;;;;;N;;;;;\n1B083;HENTAIGANA LETTER NA-6;Lo;0;L;;;;;N;;;;;\n1B084;HENTAIGANA LETTER NA-7;Lo;0;L;;;;;N;;;;;\n1B085;HENTAIGANA LETTER NA-8;Lo;0;L;;;;;N;;;;;\n1B086;HENTAIGANA LETTER NA-9;Lo;0;L;;;;;N;;;;;\n1B087;HENTAIGANA LETTER NI-1;Lo;0;L;;;;;N;;;;;\n1B088;HENTAIGANA LETTER NI-2;Lo;0;L;;;;;N;;;;;\n1B089;HENTAIGANA LETTER NI-3;Lo;0;L;;;;;N;;;;;\n1B08A;HENTAIGANA LETTER NI-4;Lo;0;L;;;;;N;;;;;\n1B08B;HENTAIGANA LETTER NI-5;Lo;0;L;;;;;N;;;;;\n1B08C;HENTAIGANA LETTER NI-6;Lo;0;L;;;;;N;;;;;\n1B08D;HENTAIGANA LETTER NI-7;Lo;0;L;;;;;N;;;;;\n1B08E;HENTAIGANA LETTER NI-TE;Lo;0;L;;;;;N;;;;;\n1B08F;HENTAIGANA LETTER NU-1;Lo;0;L;;;;;N;;;;;\n1B090;HENTAIGANA LETTER NU-2;Lo;0;L;;;;;N;;;;;\n1B091;HENTAIGANA LETTER NU-3;Lo;0;L;;;;;N;;;;;\n1B092;HENTAIGANA LETTER NE-1;Lo;0;L;;;;;N;;;;;\n1B093;HENTAIGANA LETTER NE-2;Lo;0;L;;;;;N;;;;;\n1B094;HENTAIGANA LETTER NE-3;Lo;0;L;;;;;N;;;;;\n1B095;HENTAIGANA LETTER NE-4;Lo;0;L;;;;;N;;;;;\n1B096;HENTAIGANA LETTER NE-5;Lo;0;L;;;;;N;;;;;\n1B097;HENTAIGANA LETTER NE-6;Lo;0;L;;;;;N;;;;;\n1B098;HENTAIGANA LETTER NE-KO;Lo;0;L;;;;;N;;;;;\n1B099;HENTAIGANA LETTER NO-1;Lo;0;L;;;;;N;;;;;\n1B09A;HENTAIGANA LETTER NO-2;Lo;0;L;;;;;N;;;;;\n1B09B;HENTAIGANA LETTER NO-3;Lo;0;L;;;;;N;;;;;\n1B09C;HENTAIGANA LETTER NO-4;Lo;0;L;;;;;N;;;;;\n1B09D;HENTAIGANA LETTER NO-5;Lo;0;L;;;;;N;;;;;\n1B09E;HENTAIGANA LETTER HA-1;Lo;0;L;;;;;N;;;;;\n1B09F;HENTAIGANA LETTER HA-2;Lo;0;L;;;;;N;;;;;\n1B0A0;HENTAIGANA LETTER HA-3;Lo;0;L;;;;;N;;;;;\n1B0A1;HENTAIGANA LETTER HA-4;Lo;0;L;;;;;N;;;;;\n1B0A2;HENTAIGANA LETTER HA-5;Lo;0;L;;;;;N;;;;;\n1B0A3;HENTAIGANA LETTER HA-6;Lo;0;L;;;;;N;;;;;\n1B0A4;HENTAIGANA LETTER HA-7;Lo;0;L;;;;;N;;;;;\n1B0A5;HENTAIGANA LETTER HA-8;Lo;0;L;;;;;N;;;;;\n1B0A6;HENTAIGANA LETTER HA-9;Lo;0;L;;;;;N;;;;;\n1B0A7;HENTAIGANA LETTER HA-10;Lo;0;L;;;;;N;;;;;\n1B0A8;HENTAIGANA LETTER HA-11;Lo;0;L;;;;;N;;;;;\n1B0A9;HENTAIGANA LETTER HI-1;Lo;0;L;;;;;N;;;;;\n1B0AA;HENTAIGANA LETTER HI-2;Lo;0;L;;;;;N;;;;;\n1B0AB;HENTAIGANA LETTER HI-3;Lo;0;L;;;;;N;;;;;\n1B0AC;HENTAIGANA LETTER HI-4;Lo;0;L;;;;;N;;;;;\n1B0AD;HENTAIGANA LETTER HI-5;Lo;0;L;;;;;N;;;;;\n1B0AE;HENTAIGANA LETTER HI-6;Lo;0;L;;;;;N;;;;;\n1B0AF;HENTAIGANA LETTER HI-7;Lo;0;L;;;;;N;;;;;\n1B0B0;HENTAIGANA LETTER HU-1;Lo;0;L;;;;;N;;;;;\n1B0B1;HENTAIGANA LETTER HU-2;Lo;0;L;;;;;N;;;;;\n1B0B2;HENTAIGANA LETTER HU-3;Lo;0;L;;;;;N;;;;;\n1B0B3;HENTAIGANA LETTER HE-1;Lo;0;L;;;;;N;;;;;\n1B0B4;HENTAIGANA LETTER HE-2;Lo;0;L;;;;;N;;;;;\n1B0B5;HENTAIGANA LETTER HE-3;Lo;0;L;;;;;N;;;;;\n1B0B6;HENTAIGANA LETTER HE-4;Lo;0;L;;;;;N;;;;;\n1B0B7;HENTAIGANA LETTER HE-5;Lo;0;L;;;;;N;;;;;\n1B0B8;HENTAIGANA LETTER HE-6;Lo;0;L;;;;;N;;;;;\n1B0B9;HENTAIGANA LETTER HE-7;Lo;0;L;;;;;N;;;;;\n1B0BA;HENTAIGANA LETTER HO-1;Lo;0;L;;;;;N;;;;;\n1B0BB;HENTAIGANA LETTER HO-2;Lo;0;L;;;;;N;;;;;\n1B0BC;HENTAIGANA LETTER HO-3;Lo;0;L;;;;;N;;;;;\n1B0BD;HENTAIGANA LETTER HO-4;Lo;0;L;;;;;N;;;;;\n1B0BE;HENTAIGANA LETTER HO-5;Lo;0;L;;;;;N;;;;;\n1B0BF;HENTAIGANA LETTER HO-6;Lo;0;L;;;;;N;;;;;\n1B0C0;HENTAIGANA LETTER HO-7;Lo;0;L;;;;;N;;;;;\n1B0C1;HENTAIGANA LETTER HO-8;Lo;0;L;;;;;N;;;;;\n1B0C2;HENTAIGANA LETTER MA-1;Lo;0;L;;;;;N;;;;;\n1B0C3;HENTAIGANA LETTER MA-2;Lo;0;L;;;;;N;;;;;\n1B0C4;HENTAIGANA LETTER MA-3;Lo;0;L;;;;;N;;;;;\n1B0C5;HENTAIGANA LETTER MA-4;Lo;0;L;;;;;N;;;;;\n1B0C6;HENTAIGANA LETTER MA-5;Lo;0;L;;;;;N;;;;;\n1B0C7;HENTAIGANA LETTER MA-6;Lo;0;L;;;;;N;;;;;\n1B0C8;HENTAIGANA LETTER MA-7;Lo;0;L;;;;;N;;;;;\n1B0C9;HENTAIGANA LETTER MI-1;Lo;0;L;;;;;N;;;;;\n1B0CA;HENTAIGANA LETTER MI-2;Lo;0;L;;;;;N;;;;;\n1B0CB;HENTAIGANA LETTER MI-3;Lo;0;L;;;;;N;;;;;\n1B0CC;HENTAIGANA LETTER MI-4;Lo;0;L;;;;;N;;;;;\n1B0CD;HENTAIGANA LETTER MI-5;Lo;0;L;;;;;N;;;;;\n1B0CE;HENTAIGANA LETTER MI-6;Lo;0;L;;;;;N;;;;;\n1B0CF;HENTAIGANA LETTER MI-7;Lo;0;L;;;;;N;;;;;\n1B0D0;HENTAIGANA LETTER MU-1;Lo;0;L;;;;;N;;;;;\n1B0D1;HENTAIGANA LETTER MU-2;Lo;0;L;;;;;N;;;;;\n1B0D2;HENTAIGANA LETTER MU-3;Lo;0;L;;;;;N;;;;;\n1B0D3;HENTAIGANA LETTER MU-4;Lo;0;L;;;;;N;;;;;\n1B0D4;HENTAIGANA LETTER ME-1;Lo;0;L;;;;;N;;;;;\n1B0D5;HENTAIGANA LETTER ME-2;Lo;0;L;;;;;N;;;;;\n1B0D6;HENTAIGANA LETTER ME-MA;Lo;0;L;;;;;N;;;;;\n1B0D7;HENTAIGANA LETTER MO-1;Lo;0;L;;;;;N;;;;;\n1B0D8;HENTAIGANA LETTER MO-2;Lo;0;L;;;;;N;;;;;\n1B0D9;HENTAIGANA LETTER MO-3;Lo;0;L;;;;;N;;;;;\n1B0DA;HENTAIGANA LETTER MO-4;Lo;0;L;;;;;N;;;;;\n1B0DB;HENTAIGANA LETTER MO-5;Lo;0;L;;;;;N;;;;;\n1B0DC;HENTAIGANA LETTER MO-6;Lo;0;L;;;;;N;;;;;\n1B0DD;HENTAIGANA LETTER YA-1;Lo;0;L;;;;;N;;;;;\n1B0DE;HENTAIGANA LETTER YA-2;Lo;0;L;;;;;N;;;;;\n1B0DF;HENTAIGANA LETTER YA-3;Lo;0;L;;;;;N;;;;;\n1B0E0;HENTAIGANA LETTER YA-4;Lo;0;L;;;;;N;;;;;\n1B0E1;HENTAIGANA LETTER YA-5;Lo;0;L;;;;;N;;;;;\n1B0E2;HENTAIGANA LETTER YA-YO;Lo;0;L;;;;;N;;;;;\n1B0E3;HENTAIGANA LETTER YU-1;Lo;0;L;;;;;N;;;;;\n1B0E4;HENTAIGANA LETTER YU-2;Lo;0;L;;;;;N;;;;;\n1B0E5;HENTAIGANA LETTER YU-3;Lo;0;L;;;;;N;;;;;\n1B0E6;HENTAIGANA LETTER YU-4;Lo;0;L;;;;;N;;;;;\n1B0E7;HENTAIGANA LETTER YO-1;Lo;0;L;;;;;N;;;;;\n1B0E8;HENTAIGANA LETTER YO-2;Lo;0;L;;;;;N;;;;;\n1B0E9;HENTAIGANA LETTER YO-3;Lo;0;L;;;;;N;;;;;\n1B0EA;HENTAIGANA LETTER YO-4;Lo;0;L;;;;;N;;;;;\n1B0EB;HENTAIGANA LETTER YO-5;Lo;0;L;;;;;N;;;;;\n1B0EC;HENTAIGANA LETTER YO-6;Lo;0;L;;;;;N;;;;;\n1B0ED;HENTAIGANA LETTER RA-1;Lo;0;L;;;;;N;;;;;\n1B0EE;HENTAIGANA LETTER RA-2;Lo;0;L;;;;;N;;;;;\n1B0EF;HENTAIGANA LETTER RA-3;Lo;0;L;;;;;N;;;;;\n1B0F0;HENTAIGANA LETTER RA-4;Lo;0;L;;;;;N;;;;;\n1B0F1;HENTAIGANA LETTER RI-1;Lo;0;L;;;;;N;;;;;\n1B0F2;HENTAIGANA LETTER RI-2;Lo;0;L;;;;;N;;;;;\n1B0F3;HENTAIGANA LETTER RI-3;Lo;0;L;;;;;N;;;;;\n1B0F4;HENTAIGANA LETTER RI-4;Lo;0;L;;;;;N;;;;;\n1B0F5;HENTAIGANA LETTER RI-5;Lo;0;L;;;;;N;;;;;\n1B0F6;HENTAIGANA LETTER RI-6;Lo;0;L;;;;;N;;;;;\n1B0F7;HENTAIGANA LETTER RI-7;Lo;0;L;;;;;N;;;;;\n1B0F8;HENTAIGANA LETTER RU-1;Lo;0;L;;;;;N;;;;;\n1B0F9;HENTAIGANA LETTER RU-2;Lo;0;L;;;;;N;;;;;\n1B0FA;HENTAIGANA LETTER RU-3;Lo;0;L;;;;;N;;;;;\n1B0FB;HENTAIGANA LETTER RU-4;Lo;0;L;;;;;N;;;;;\n1B0FC;HENTAIGANA LETTER RU-5;Lo;0;L;;;;;N;;;;;\n1B0FD;HENTAIGANA LETTER RU-6;Lo;0;L;;;;;N;;;;;\n1B0FE;HENTAIGANA LETTER RE-1;Lo;0;L;;;;;N;;;;;\n1B0FF;HENTAIGANA LETTER RE-2;Lo;0;L;;;;;N;;;;;\n1B100;HENTAIGANA LETTER RE-3;Lo;0;L;;;;;N;;;;;\n1B101;HENTAIGANA LETTER RE-4;Lo;0;L;;;;;N;;;;;\n1B102;HENTAIGANA LETTER RO-1;Lo;0;L;;;;;N;;;;;\n1B103;HENTAIGANA LETTER RO-2;Lo;0;L;;;;;N;;;;;\n1B104;HENTAIGANA LETTER RO-3;Lo;0;L;;;;;N;;;;;\n1B105;HENTAIGANA LETTER RO-4;Lo;0;L;;;;;N;;;;;\n1B106;HENTAIGANA LETTER RO-5;Lo;0;L;;;;;N;;;;;\n1B107;HENTAIGANA LETTER RO-6;Lo;0;L;;;;;N;;;;;\n1B108;HENTAIGANA LETTER WA-1;Lo;0;L;;;;;N;;;;;\n1B109;HENTAIGANA LETTER WA-2;Lo;0;L;;;;;N;;;;;\n1B10A;HENTAIGANA LETTER WA-3;Lo;0;L;;;;;N;;;;;\n1B10B;HENTAIGANA LETTER WA-4;Lo;0;L;;;;;N;;;;;\n1B10C;HENTAIGANA LETTER WA-5;Lo;0;L;;;;;N;;;;;\n1B10D;HENTAIGANA LETTER WI-1;Lo;0;L;;;;;N;;;;;\n1B10E;HENTAIGANA LETTER WI-2;Lo;0;L;;;;;N;;;;;\n1B10F;HENTAIGANA LETTER WI-3;Lo;0;L;;;;;N;;;;;\n1B110;HENTAIGANA LETTER WI-4;Lo;0;L;;;;;N;;;;;\n1B111;HENTAIGANA LETTER WI-5;Lo;0;L;;;;;N;;;;;\n1B112;HENTAIGANA LETTER WE-1;Lo;0;L;;;;;N;;;;;\n1B113;HENTAIGANA LETTER WE-2;Lo;0;L;;;;;N;;;;;\n1B114;HENTAIGANA LETTER WE-3;Lo;0;L;;;;;N;;;;;\n1B115;HENTAIGANA LETTER WE-4;Lo;0;L;;;;;N;;;;;\n1B116;HENTAIGANA LETTER WO-1;Lo;0;L;;;;;N;;;;;\n1B117;HENTAIGANA LETTER WO-2;Lo;0;L;;;;;N;;;;;\n1B118;HENTAIGANA LETTER WO-3;Lo;0;L;;;;;N;;;;;\n1B119;HENTAIGANA LETTER WO-4;Lo;0;L;;;;;N;;;;;\n1B11A;HENTAIGANA LETTER WO-5;Lo;0;L;;;;;N;;;;;\n1B11B;HENTAIGANA LETTER WO-6;Lo;0;L;;;;;N;;;;;\n1B11C;HENTAIGANA LETTER WO-7;Lo;0;L;;;;;N;;;;;\n1B11D;HENTAIGANA LETTER N-MU-MO-1;Lo;0;L;;;;;N;;;;;\n1B11E;HENTAIGANA LETTER N-MU-MO-2;Lo;0;L;;;;;N;;;;;\n1B150;HIRAGANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;;\n1B151;HIRAGANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;;\n1B152;HIRAGANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;;\n1B164;KATAKANA LETTER SMALL WI;Lo;0;L;;;;;N;;;;;\n1B165;KATAKANA LETTER SMALL WE;Lo;0;L;;;;;N;;;;;\n1B166;KATAKANA LETTER SMALL WO;Lo;0;L;;;;;N;;;;;\n1B167;KATAKANA LETTER SMALL N;Lo;0;L;;;;;N;;;;;\n1B170;NUSHU CHARACTER-1B170;Lo;0;L;;;;;N;;;;;\n1B171;NUSHU CHARACTER-1B171;Lo;0;L;;;;;N;;;;;\n1B172;NUSHU CHARACTER-1B172;Lo;0;L;;;;;N;;;;;\n1B173;NUSHU CHARACTER-1B173;Lo;0;L;;;;;N;;;;;\n1B174;NUSHU CHARACTER-1B174;Lo;0;L;;;;;N;;;;;\n1B175;NUSHU CHARACTER-1B175;Lo;0;L;;;;;N;;;;;\n1B176;NUSHU CHARACTER-1B176;Lo;0;L;;;;;N;;;;;\n1B177;NUSHU CHARACTER-1B177;Lo;0;L;;;;;N;;;;;\n1B178;NUSHU CHARACTER-1B178;Lo;0;L;;;;;N;;;;;\n1B179;NUSHU CHARACTER-1B179;Lo;0;L;;;;;N;;;;;\n1B17A;NUSHU CHARACTER-1B17A;Lo;0;L;;;;;N;;;;;\n1B17B;NUSHU CHARACTER-1B17B;Lo;0;L;;;;;N;;;;;\n1B17C;NUSHU CHARACTER-1B17C;Lo;0;L;;;;;N;;;;;\n1B17D;NUSHU CHARACTER-1B17D;Lo;0;L;;;;;N;;;;;\n1B17E;NUSHU CHARACTER-1B17E;Lo;0;L;;;;;N;;;;;\n1B17F;NUSHU CHARACTER-1B17F;Lo;0;L;;;;;N;;;;;\n1B180;NUSHU CHARACTER-1B180;Lo;0;L;;;;;N;;;;;\n1B181;NUSHU CHARACTER-1B181;Lo;0;L;;;;;N;;;;;\n1B182;NUSHU CHARACTER-1B182;Lo;0;L;;;;;N;;;;;\n1B183;NUSHU CHARACTER-1B183;Lo;0;L;;;;;N;;;;;\n1B184;NUSHU CHARACTER-1B184;Lo;0;L;;;;;N;;;;;\n1B185;NUSHU CHARACTER-1B185;Lo;0;L;;;;;N;;;;;\n1B186;NUSHU CHARACTER-1B186;Lo;0;L;;;;;N;;;;;\n1B187;NUSHU CHARACTER-1B187;Lo;0;L;;;;;N;;;;;\n1B188;NUSHU CHARACTER-1B188;Lo;0;L;;;;;N;;;;;\n1B189;NUSHU CHARACTER-1B189;Lo;0;L;;;;;N;;;;;\n1B18A;NUSHU CHARACTER-1B18A;Lo;0;L;;;;;N;;;;;\n1B18B;NUSHU CHARACTER-1B18B;Lo;0;L;;;;;N;;;;;\n1B18C;NUSHU CHARACTER-1B18C;Lo;0;L;;;;;N;;;;;\n1B18D;NUSHU CHARACTER-1B18D;Lo;0;L;;;;;N;;;;;\n1B18E;NUSHU CHARACTER-1B18E;Lo;0;L;;;;;N;;;;;\n1B18F;NUSHU CHARACTER-1B18F;Lo;0;L;;;;;N;;;;;\n1B190;NUSHU CHARACTER-1B190;Lo;0;L;;;;;N;;;;;\n1B191;NUSHU CHARACTER-1B191;Lo;0;L;;;;;N;;;;;\n1B192;NUSHU CHARACTER-1B192;Lo;0;L;;;;;N;;;;;\n1B193;NUSHU CHARACTER-1B193;Lo;0;L;;;;;N;;;;;\n1B194;NUSHU CHARACTER-1B194;Lo;0;L;;;;;N;;;;;\n1B195;NUSHU CHARACTER-1B195;Lo;0;L;;;;;N;;;;;\n1B196;NUSHU CHARACTER-1B196;Lo;0;L;;;;;N;;;;;\n1B197;NUSHU CHARACTER-1B197;Lo;0;L;;;;;N;;;;;\n1B198;NUSHU CHARACTER-1B198;Lo;0;L;;;;;N;;;;;\n1B199;NUSHU CHARACTER-1B199;Lo;0;L;;;;;N;;;;;\n1B19A;NUSHU CHARACTER-1B19A;Lo;0;L;;;;;N;;;;;\n1B19B;NUSHU CHARACTER-1B19B;Lo;0;L;;;;;N;;;;;\n1B19C;NUSHU CHARACTER-1B19C;Lo;0;L;;;;;N;;;;;\n1B19D;NUSHU CHARACTER-1B19D;Lo;0;L;;;;;N;;;;;\n1B19E;NUSHU CHARACTER-1B19E;Lo;0;L;;;;;N;;;;;\n1B19F;NUSHU CHARACTER-1B19F;Lo;0;L;;;;;N;;;;;\n1B1A0;NUSHU CHARACTER-1B1A0;Lo;0;L;;;;;N;;;;;\n1B1A1;NUSHU CHARACTER-1B1A1;Lo;0;L;;;;;N;;;;;\n1B1A2;NUSHU CHARACTER-1B1A2;Lo;0;L;;;;;N;;;;;\n1B1A3;NUSHU CHARACTER-1B1A3;Lo;0;L;;;;;N;;;;;\n1B1A4;NUSHU CHARACTER-1B1A4;Lo;0;L;;;;;N;;;;;\n1B1A5;NUSHU CHARACTER-1B1A5;Lo;0;L;;;;;N;;;;;\n1B1A6;NUSHU CHARACTER-1B1A6;Lo;0;L;;;;;N;;;;;\n1B1A7;NUSHU CHARACTER-1B1A7;Lo;0;L;;;;;N;;;;;\n1B1A8;NUSHU CHARACTER-1B1A8;Lo;0;L;;;;;N;;;;;\n1B1A9;NUSHU CHARACTER-1B1A9;Lo;0;L;;;;;N;;;;;\n1B1AA;NUSHU CHARACTER-1B1AA;Lo;0;L;;;;;N;;;;;\n1B1AB;NUSHU CHARACTER-1B1AB;Lo;0;L;;;;;N;;;;;\n1B1AC;NUSHU CHARACTER-1B1AC;Lo;0;L;;;;;N;;;;;\n1B1AD;NUSHU CHARACTER-1B1AD;Lo;0;L;;;;;N;;;;;\n1B1AE;NUSHU CHARACTER-1B1AE;Lo;0;L;;;;;N;;;;;\n1B1AF;NUSHU CHARACTER-1B1AF;Lo;0;L;;;;;N;;;;;\n1B1B0;NUSHU CHARACTER-1B1B0;Lo;0;L;;;;;N;;;;;\n1B1B1;NUSHU CHARACTER-1B1B1;Lo;0;L;;;;;N;;;;;\n1B1B2;NUSHU CHARACTER-1B1B2;Lo;0;L;;;;;N;;;;;\n1B1B3;NUSHU CHARACTER-1B1B3;Lo;0;L;;;;;N;;;;;\n1B1B4;NUSHU CHARACTER-1B1B4;Lo;0;L;;;;;N;;;;;\n1B1B5;NUSHU CHARACTER-1B1B5;Lo;0;L;;;;;N;;;;;\n1B1B6;NUSHU CHARACTER-1B1B6;Lo;0;L;;;;;N;;;;;\n1B1B7;NUSHU CHARACTER-1B1B7;Lo;0;L;;;;;N;;;;;\n1B1B8;NUSHU CHARACTER-1B1B8;Lo;0;L;;;;;N;;;;;\n1B1B9;NUSHU CHARACTER-1B1B9;Lo;0;L;;;;;N;;;;;\n1B1BA;NUSHU CHARACTER-1B1BA;Lo;0;L;;;;;N;;;;;\n1B1BB;NUSHU CHARACTER-1B1BB;Lo;0;L;;;;;N;;;;;\n1B1BC;NUSHU CHARACTER-1B1BC;Lo;0;L;;;;;N;;;;;\n1B1BD;NUSHU CHARACTER-1B1BD;Lo;0;L;;;;;N;;;;;\n1B1BE;NUSHU CHARACTER-1B1BE;Lo;0;L;;;;;N;;;;;\n1B1BF;NUSHU CHARACTER-1B1BF;Lo;0;L;;;;;N;;;;;\n1B1C0;NUSHU CHARACTER-1B1C0;Lo;0;L;;;;;N;;;;;\n1B1C1;NUSHU CHARACTER-1B1C1;Lo;0;L;;;;;N;;;;;\n1B1C2;NUSHU CHARACTER-1B1C2;Lo;0;L;;;;;N;;;;;\n1B1C3;NUSHU CHARACTER-1B1C3;Lo;0;L;;;;;N;;;;;\n1B1C4;NUSHU CHARACTER-1B1C4;Lo;0;L;;;;;N;;;;;\n1B1C5;NUSHU CHARACTER-1B1C5;Lo;0;L;;;;;N;;;;;\n1B1C6;NUSHU CHARACTER-1B1C6;Lo;0;L;;;;;N;;;;;\n1B1C7;NUSHU CHARACTER-1B1C7;Lo;0;L;;;;;N;;;;;\n1B1C8;NUSHU CHARACTER-1B1C8;Lo;0;L;;;;;N;;;;;\n1B1C9;NUSHU CHARACTER-1B1C9;Lo;0;L;;;;;N;;;;;\n1B1CA;NUSHU CHARACTER-1B1CA;Lo;0;L;;;;;N;;;;;\n1B1CB;NUSHU CHARACTER-1B1CB;Lo;0;L;;;;;N;;;;;\n1B1CC;NUSHU CHARACTER-1B1CC;Lo;0;L;;;;;N;;;;;\n1B1CD;NUSHU CHARACTER-1B1CD;Lo;0;L;;;;;N;;;;;\n1B1CE;NUSHU CHARACTER-1B1CE;Lo;0;L;;;;;N;;;;;\n1B1CF;NUSHU CHARACTER-1B1CF;Lo;0;L;;;;;N;;;;;\n1B1D0;NUSHU CHARACTER-1B1D0;Lo;0;L;;;;;N;;;;;\n1B1D1;NUSHU CHARACTER-1B1D1;Lo;0;L;;;;;N;;;;;\n1B1D2;NUSHU CHARACTER-1B1D2;Lo;0;L;;;;;N;;;;;\n1B1D3;NUSHU CHARACTER-1B1D3;Lo;0;L;;;;;N;;;;;\n1B1D4;NUSHU CHARACTER-1B1D4;Lo;0;L;;;;;N;;;;;\n1B1D5;NUSHU CHARACTER-1B1D5;Lo;0;L;;;;;N;;;;;\n1B1D6;NUSHU CHARACTER-1B1D6;Lo;0;L;;;;;N;;;;;\n1B1D7;NUSHU CHARACTER-1B1D7;Lo;0;L;;;;;N;;;;;\n1B1D8;NUSHU CHARACTER-1B1D8;Lo;0;L;;;;;N;;;;;\n1B1D9;NUSHU CHARACTER-1B1D9;Lo;0;L;;;;;N;;;;;\n1B1DA;NUSHU CHARACTER-1B1DA;Lo;0;L;;;;;N;;;;;\n1B1DB;NUSHU CHARACTER-1B1DB;Lo;0;L;;;;;N;;;;;\n1B1DC;NUSHU CHARACTER-1B1DC;Lo;0;L;;;;;N;;;;;\n1B1DD;NUSHU CHARACTER-1B1DD;Lo;0;L;;;;;N;;;;;\n1B1DE;NUSHU CHARACTER-1B1DE;Lo;0;L;;;;;N;;;;;\n1B1DF;NUSHU CHARACTER-1B1DF;Lo;0;L;;;;;N;;;;;\n1B1E0;NUSHU CHARACTER-1B1E0;Lo;0;L;;;;;N;;;;;\n1B1E1;NUSHU CHARACTER-1B1E1;Lo;0;L;;;;;N;;;;;\n1B1E2;NUSHU CHARACTER-1B1E2;Lo;0;L;;;;;N;;;;;\n1B1E3;NUSHU CHARACTER-1B1E3;Lo;0;L;;;;;N;;;;;\n1B1E4;NUSHU CHARACTER-1B1E4;Lo;0;L;;;;;N;;;;;\n1B1E5;NUSHU CHARACTER-1B1E5;Lo;0;L;;;;;N;;;;;\n1B1E6;NUSHU CHARACTER-1B1E6;Lo;0;L;;;;;N;;;;;\n1B1E7;NUSHU CHARACTER-1B1E7;Lo;0;L;;;;;N;;;;;\n1B1E8;NUSHU CHARACTER-1B1E8;Lo;0;L;;;;;N;;;;;\n1B1E9;NUSHU CHARACTER-1B1E9;Lo;0;L;;;;;N;;;;;\n1B1EA;NUSHU CHARACTER-1B1EA;Lo;0;L;;;;;N;;;;;\n1B1EB;NUSHU CHARACTER-1B1EB;Lo;0;L;;;;;N;;;;;\n1B1EC;NUSHU CHARACTER-1B1EC;Lo;0;L;;;;;N;;;;;\n1B1ED;NUSHU CHARACTER-1B1ED;Lo;0;L;;;;;N;;;;;\n1B1EE;NUSHU CHARACTER-1B1EE;Lo;0;L;;;;;N;;;;;\n1B1EF;NUSHU CHARACTER-1B1EF;Lo;0;L;;;;;N;;;;;\n1B1F0;NUSHU CHARACTER-1B1F0;Lo;0;L;;;;;N;;;;;\n1B1F1;NUSHU CHARACTER-1B1F1;Lo;0;L;;;;;N;;;;;\n1B1F2;NUSHU CHARACTER-1B1F2;Lo;0;L;;;;;N;;;;;\n1B1F3;NUSHU CHARACTER-1B1F3;Lo;0;L;;;;;N;;;;;\n1B1F4;NUSHU CHARACTER-1B1F4;Lo;0;L;;;;;N;;;;;\n1B1F5;NUSHU CHARACTER-1B1F5;Lo;0;L;;;;;N;;;;;\n1B1F6;NUSHU CHARACTER-1B1F6;Lo;0;L;;;;;N;;;;;\n1B1F7;NUSHU CHARACTER-1B1F7;Lo;0;L;;;;;N;;;;;\n1B1F8;NUSHU CHARACTER-1B1F8;Lo;0;L;;;;;N;;;;;\n1B1F9;NUSHU CHARACTER-1B1F9;Lo;0;L;;;;;N;;;;;\n1B1FA;NUSHU CHARACTER-1B1FA;Lo;0;L;;;;;N;;;;;\n1B1FB;NUSHU CHARACTER-1B1FB;Lo;0;L;;;;;N;;;;;\n1B1FC;NUSHU CHARACTER-1B1FC;Lo;0;L;;;;;N;;;;;\n1B1FD;NUSHU CHARACTER-1B1FD;Lo;0;L;;;;;N;;;;;\n1B1FE;NUSHU CHARACTER-1B1FE;Lo;0;L;;;;;N;;;;;\n1B1FF;NUSHU CHARACTER-1B1FF;Lo;0;L;;;;;N;;;;;\n1B200;NUSHU CHARACTER-1B200;Lo;0;L;;;;;N;;;;;\n1B201;NUSHU CHARACTER-1B201;Lo;0;L;;;;;N;;;;;\n1B202;NUSHU CHARACTER-1B202;Lo;0;L;;;;;N;;;;;\n1B203;NUSHU CHARACTER-1B203;Lo;0;L;;;;;N;;;;;\n1B204;NUSHU CHARACTER-1B204;Lo;0;L;;;;;N;;;;;\n1B205;NUSHU CHARACTER-1B205;Lo;0;L;;;;;N;;;;;\n1B206;NUSHU CHARACTER-1B206;Lo;0;L;;;;;N;;;;;\n1B207;NUSHU CHARACTER-1B207;Lo;0;L;;;;;N;;;;;\n1B208;NUSHU CHARACTER-1B208;Lo;0;L;;;;;N;;;;;\n1B209;NUSHU CHARACTER-1B209;Lo;0;L;;;;;N;;;;;\n1B20A;NUSHU CHARACTER-1B20A;Lo;0;L;;;;;N;;;;;\n1B20B;NUSHU CHARACTER-1B20B;Lo;0;L;;;;;N;;;;;\n1B20C;NUSHU CHARACTER-1B20C;Lo;0;L;;;;;N;;;;;\n1B20D;NUSHU CHARACTER-1B20D;Lo;0;L;;;;;N;;;;;\n1B20E;NUSHU CHARACTER-1B20E;Lo;0;L;;;;;N;;;;;\n1B20F;NUSHU CHARACTER-1B20F;Lo;0;L;;;;;N;;;;;\n1B210;NUSHU CHARACTER-1B210;Lo;0;L;;;;;N;;;;;\n1B211;NUSHU CHARACTER-1B211;Lo;0;L;;;;;N;;;;;\n1B212;NUSHU CHARACTER-1B212;Lo;0;L;;;;;N;;;;;\n1B213;NUSHU CHARACTER-1B213;Lo;0;L;;;;;N;;;;;\n1B214;NUSHU CHARACTER-1B214;Lo;0;L;;;;;N;;;;;\n1B215;NUSHU CHARACTER-1B215;Lo;0;L;;;;;N;;;;;\n1B216;NUSHU CHARACTER-1B216;Lo;0;L;;;;;N;;;;;\n1B217;NUSHU CHARACTER-1B217;Lo;0;L;;;;;N;;;;;\n1B218;NUSHU CHARACTER-1B218;Lo;0;L;;;;;N;;;;;\n1B219;NUSHU CHARACTER-1B219;Lo;0;L;;;;;N;;;;;\n1B21A;NUSHU CHARACTER-1B21A;Lo;0;L;;;;;N;;;;;\n1B21B;NUSHU CHARACTER-1B21B;Lo;0;L;;;;;N;;;;;\n1B21C;NUSHU CHARACTER-1B21C;Lo;0;L;;;;;N;;;;;\n1B21D;NUSHU CHARACTER-1B21D;Lo;0;L;;;;;N;;;;;\n1B21E;NUSHU CHARACTER-1B21E;Lo;0;L;;;;;N;;;;;\n1B21F;NUSHU CHARACTER-1B21F;Lo;0;L;;;;;N;;;;;\n1B220;NUSHU CHARACTER-1B220;Lo;0;L;;;;;N;;;;;\n1B221;NUSHU CHARACTER-1B221;Lo;0;L;;;;;N;;;;;\n1B222;NUSHU CHARACTER-1B222;Lo;0;L;;;;;N;;;;;\n1B223;NUSHU CHARACTER-1B223;Lo;0;L;;;;;N;;;;;\n1B224;NUSHU CHARACTER-1B224;Lo;0;L;;;;;N;;;;;\n1B225;NUSHU CHARACTER-1B225;Lo;0;L;;;;;N;;;;;\n1B226;NUSHU CHARACTER-1B226;Lo;0;L;;;;;N;;;;;\n1B227;NUSHU CHARACTER-1B227;Lo;0;L;;;;;N;;;;;\n1B228;NUSHU CHARACTER-1B228;Lo;0;L;;;;;N;;;;;\n1B229;NUSHU CHARACTER-1B229;Lo;0;L;;;;;N;;;;;\n1B22A;NUSHU CHARACTER-1B22A;Lo;0;L;;;;;N;;;;;\n1B22B;NUSHU CHARACTER-1B22B;Lo;0;L;;;;;N;;;;;\n1B22C;NUSHU CHARACTER-1B22C;Lo;0;L;;;;;N;;;;;\n1B22D;NUSHU CHARACTER-1B22D;Lo;0;L;;;;;N;;;;;\n1B22E;NUSHU CHARACTER-1B22E;Lo;0;L;;;;;N;;;;;\n1B22F;NUSHU CHARACTER-1B22F;Lo;0;L;;;;;N;;;;;\n1B230;NUSHU CHARACTER-1B230;Lo;0;L;;;;;N;;;;;\n1B231;NUSHU CHARACTER-1B231;Lo;0;L;;;;;N;;;;;\n1B232;NUSHU CHARACTER-1B232;Lo;0;L;;;;;N;;;;;\n1B233;NUSHU CHARACTER-1B233;Lo;0;L;;;;;N;;;;;\n1B234;NUSHU CHARACTER-1B234;Lo;0;L;;;;;N;;;;;\n1B235;NUSHU CHARACTER-1B235;Lo;0;L;;;;;N;;;;;\n1B236;NUSHU CHARACTER-1B236;Lo;0;L;;;;;N;;;;;\n1B237;NUSHU CHARACTER-1B237;Lo;0;L;;;;;N;;;;;\n1B238;NUSHU CHARACTER-1B238;Lo;0;L;;;;;N;;;;;\n1B239;NUSHU CHARACTER-1B239;Lo;0;L;;;;;N;;;;;\n1B23A;NUSHU CHARACTER-1B23A;Lo;0;L;;;;;N;;;;;\n1B23B;NUSHU CHARACTER-1B23B;Lo;0;L;;;;;N;;;;;\n1B23C;NUSHU CHARACTER-1B23C;Lo;0;L;;;;;N;;;;;\n1B23D;NUSHU CHARACTER-1B23D;Lo;0;L;;;;;N;;;;;\n1B23E;NUSHU CHARACTER-1B23E;Lo;0;L;;;;;N;;;;;\n1B23F;NUSHU CHARACTER-1B23F;Lo;0;L;;;;;N;;;;;\n1B240;NUSHU CHARACTER-1B240;Lo;0;L;;;;;N;;;;;\n1B241;NUSHU CHARACTER-1B241;Lo;0;L;;;;;N;;;;;\n1B242;NUSHU CHARACTER-1B242;Lo;0;L;;;;;N;;;;;\n1B243;NUSHU CHARACTER-1B243;Lo;0;L;;;;;N;;;;;\n1B244;NUSHU CHARACTER-1B244;Lo;0;L;;;;;N;;;;;\n1B245;NUSHU CHARACTER-1B245;Lo;0;L;;;;;N;;;;;\n1B246;NUSHU CHARACTER-1B246;Lo;0;L;;;;;N;;;;;\n1B247;NUSHU CHARACTER-1B247;Lo;0;L;;;;;N;;;;;\n1B248;NUSHU CHARACTER-1B248;Lo;0;L;;;;;N;;;;;\n1B249;NUSHU CHARACTER-1B249;Lo;0;L;;;;;N;;;;;\n1B24A;NUSHU CHARACTER-1B24A;Lo;0;L;;;;;N;;;;;\n1B24B;NUSHU CHARACTER-1B24B;Lo;0;L;;;;;N;;;;;\n1B24C;NUSHU CHARACTER-1B24C;Lo;0;L;;;;;N;;;;;\n1B24D;NUSHU CHARACTER-1B24D;Lo;0;L;;;;;N;;;;;\n1B24E;NUSHU CHARACTER-1B24E;Lo;0;L;;;;;N;;;;;\n1B24F;NUSHU CHARACTER-1B24F;Lo;0;L;;;;;N;;;;;\n1B250;NUSHU CHARACTER-1B250;Lo;0;L;;;;;N;;;;;\n1B251;NUSHU CHARACTER-1B251;Lo;0;L;;;;;N;;;;;\n1B252;NUSHU CHARACTER-1B252;Lo;0;L;;;;;N;;;;;\n1B253;NUSHU CHARACTER-1B253;Lo;0;L;;;;;N;;;;;\n1B254;NUSHU CHARACTER-1B254;Lo;0;L;;;;;N;;;;;\n1B255;NUSHU CHARACTER-1B255;Lo;0;L;;;;;N;;;;;\n1B256;NUSHU CHARACTER-1B256;Lo;0;L;;;;;N;;;;;\n1B257;NUSHU CHARACTER-1B257;Lo;0;L;;;;;N;;;;;\n1B258;NUSHU CHARACTER-1B258;Lo;0;L;;;;;N;;;;;\n1B259;NUSHU CHARACTER-1B259;Lo;0;L;;;;;N;;;;;\n1B25A;NUSHU CHARACTER-1B25A;Lo;0;L;;;;;N;;;;;\n1B25B;NUSHU CHARACTER-1B25B;Lo;0;L;;;;;N;;;;;\n1B25C;NUSHU CHARACTER-1B25C;Lo;0;L;;;;;N;;;;;\n1B25D;NUSHU CHARACTER-1B25D;Lo;0;L;;;;;N;;;;;\n1B25E;NUSHU CHARACTER-1B25E;Lo;0;L;;;;;N;;;;;\n1B25F;NUSHU CHARACTER-1B25F;Lo;0;L;;;;;N;;;;;\n1B260;NUSHU CHARACTER-1B260;Lo;0;L;;;;;N;;;;;\n1B261;NUSHU CHARACTER-1B261;Lo;0;L;;;;;N;;;;;\n1B262;NUSHU CHARACTER-1B262;Lo;0;L;;;;;N;;;;;\n1B263;NUSHU CHARACTER-1B263;Lo;0;L;;;;;N;;;;;\n1B264;NUSHU CHARACTER-1B264;Lo;0;L;;;;;N;;;;;\n1B265;NUSHU CHARACTER-1B265;Lo;0;L;;;;;N;;;;;\n1B266;NUSHU CHARACTER-1B266;Lo;0;L;;;;;N;;;;;\n1B267;NUSHU CHARACTER-1B267;Lo;0;L;;;;;N;;;;;\n1B268;NUSHU CHARACTER-1B268;Lo;0;L;;;;;N;;;;;\n1B269;NUSHU CHARACTER-1B269;Lo;0;L;;;;;N;;;;;\n1B26A;NUSHU CHARACTER-1B26A;Lo;0;L;;;;;N;;;;;\n1B26B;NUSHU CHARACTER-1B26B;Lo;0;L;;;;;N;;;;;\n1B26C;NUSHU CHARACTER-1B26C;Lo;0;L;;;;;N;;;;;\n1B26D;NUSHU CHARACTER-1B26D;Lo;0;L;;;;;N;;;;;\n1B26E;NUSHU CHARACTER-1B26E;Lo;0;L;;;;;N;;;;;\n1B26F;NUSHU CHARACTER-1B26F;Lo;0;L;;;;;N;;;;;\n1B270;NUSHU CHARACTER-1B270;Lo;0;L;;;;;N;;;;;\n1B271;NUSHU CHARACTER-1B271;Lo;0;L;;;;;N;;;;;\n1B272;NUSHU CHARACTER-1B272;Lo;0;L;;;;;N;;;;;\n1B273;NUSHU CHARACTER-1B273;Lo;0;L;;;;;N;;;;;\n1B274;NUSHU CHARACTER-1B274;Lo;0;L;;;;;N;;;;;\n1B275;NUSHU CHARACTER-1B275;Lo;0;L;;;;;N;;;;;\n1B276;NUSHU CHARACTER-1B276;Lo;0;L;;;;;N;;;;;\n1B277;NUSHU CHARACTER-1B277;Lo;0;L;;;;;N;;;;;\n1B278;NUSHU CHARACTER-1B278;Lo;0;L;;;;;N;;;;;\n1B279;NUSHU CHARACTER-1B279;Lo;0;L;;;;;N;;;;;\n1B27A;NUSHU CHARACTER-1B27A;Lo;0;L;;;;;N;;;;;\n1B27B;NUSHU CHARACTER-1B27B;Lo;0;L;;;;;N;;;;;\n1B27C;NUSHU CHARACTER-1B27C;Lo;0;L;;;;;N;;;;;\n1B27D;NUSHU CHARACTER-1B27D;Lo;0;L;;;;;N;;;;;\n1B27E;NUSHU CHARACTER-1B27E;Lo;0;L;;;;;N;;;;;\n1B27F;NUSHU CHARACTER-1B27F;Lo;0;L;;;;;N;;;;;\n1B280;NUSHU CHARACTER-1B280;Lo;0;L;;;;;N;;;;;\n1B281;NUSHU CHARACTER-1B281;Lo;0;L;;;;;N;;;;;\n1B282;NUSHU CHARACTER-1B282;Lo;0;L;;;;;N;;;;;\n1B283;NUSHU CHARACTER-1B283;Lo;0;L;;;;;N;;;;;\n1B284;NUSHU CHARACTER-1B284;Lo;0;L;;;;;N;;;;;\n1B285;NUSHU CHARACTER-1B285;Lo;0;L;;;;;N;;;;;\n1B286;NUSHU CHARACTER-1B286;Lo;0;L;;;;;N;;;;;\n1B287;NUSHU CHARACTER-1B287;Lo;0;L;;;;;N;;;;;\n1B288;NUSHU CHARACTER-1B288;Lo;0;L;;;;;N;;;;;\n1B289;NUSHU CHARACTER-1B289;Lo;0;L;;;;;N;;;;;\n1B28A;NUSHU CHARACTER-1B28A;Lo;0;L;;;;;N;;;;;\n1B28B;NUSHU CHARACTER-1B28B;Lo;0;L;;;;;N;;;;;\n1B28C;NUSHU CHARACTER-1B28C;Lo;0;L;;;;;N;;;;;\n1B28D;NUSHU CHARACTER-1B28D;Lo;0;L;;;;;N;;;;;\n1B28E;NUSHU CHARACTER-1B28E;Lo;0;L;;;;;N;;;;;\n1B28F;NUSHU CHARACTER-1B28F;Lo;0;L;;;;;N;;;;;\n1B290;NUSHU CHARACTER-1B290;Lo;0;L;;;;;N;;;;;\n1B291;NUSHU CHARACTER-1B291;Lo;0;L;;;;;N;;;;;\n1B292;NUSHU CHARACTER-1B292;Lo;0;L;;;;;N;;;;;\n1B293;NUSHU CHARACTER-1B293;Lo;0;L;;;;;N;;;;;\n1B294;NUSHU CHARACTER-1B294;Lo;0;L;;;;;N;;;;;\n1B295;NUSHU CHARACTER-1B295;Lo;0;L;;;;;N;;;;;\n1B296;NUSHU CHARACTER-1B296;Lo;0;L;;;;;N;;;;;\n1B297;NUSHU CHARACTER-1B297;Lo;0;L;;;;;N;;;;;\n1B298;NUSHU CHARACTER-1B298;Lo;0;L;;;;;N;;;;;\n1B299;NUSHU CHARACTER-1B299;Lo;0;L;;;;;N;;;;;\n1B29A;NUSHU CHARACTER-1B29A;Lo;0;L;;;;;N;;;;;\n1B29B;NUSHU CHARACTER-1B29B;Lo;0;L;;;;;N;;;;;\n1B29C;NUSHU CHARACTER-1B29C;Lo;0;L;;;;;N;;;;;\n1B29D;NUSHU CHARACTER-1B29D;Lo;0;L;;;;;N;;;;;\n1B29E;NUSHU CHARACTER-1B29E;Lo;0;L;;;;;N;;;;;\n1B29F;NUSHU CHARACTER-1B29F;Lo;0;L;;;;;N;;;;;\n1B2A0;NUSHU CHARACTER-1B2A0;Lo;0;L;;;;;N;;;;;\n1B2A1;NUSHU CHARACTER-1B2A1;Lo;0;L;;;;;N;;;;;\n1B2A2;NUSHU CHARACTER-1B2A2;Lo;0;L;;;;;N;;;;;\n1B2A3;NUSHU CHARACTER-1B2A3;Lo;0;L;;;;;N;;;;;\n1B2A4;NUSHU CHARACTER-1B2A4;Lo;0;L;;;;;N;;;;;\n1B2A5;NUSHU CHARACTER-1B2A5;Lo;0;L;;;;;N;;;;;\n1B2A6;NUSHU CHARACTER-1B2A6;Lo;0;L;;;;;N;;;;;\n1B2A7;NUSHU CHARACTER-1B2A7;Lo;0;L;;;;;N;;;;;\n1B2A8;NUSHU CHARACTER-1B2A8;Lo;0;L;;;;;N;;;;;\n1B2A9;NUSHU CHARACTER-1B2A9;Lo;0;L;;;;;N;;;;;\n1B2AA;NUSHU CHARACTER-1B2AA;Lo;0;L;;;;;N;;;;;\n1B2AB;NUSHU CHARACTER-1B2AB;Lo;0;L;;;;;N;;;;;\n1B2AC;NUSHU CHARACTER-1B2AC;Lo;0;L;;;;;N;;;;;\n1B2AD;NUSHU CHARACTER-1B2AD;Lo;0;L;;;;;N;;;;;\n1B2AE;NUSHU CHARACTER-1B2AE;Lo;0;L;;;;;N;;;;;\n1B2AF;NUSHU CHARACTER-1B2AF;Lo;0;L;;;;;N;;;;;\n1B2B0;NUSHU CHARACTER-1B2B0;Lo;0;L;;;;;N;;;;;\n1B2B1;NUSHU CHARACTER-1B2B1;Lo;0;L;;;;;N;;;;;\n1B2B2;NUSHU CHARACTER-1B2B2;Lo;0;L;;;;;N;;;;;\n1B2B3;NUSHU CHARACTER-1B2B3;Lo;0;L;;;;;N;;;;;\n1B2B4;NUSHU CHARACTER-1B2B4;Lo;0;L;;;;;N;;;;;\n1B2B5;NUSHU CHARACTER-1B2B5;Lo;0;L;;;;;N;;;;;\n1B2B6;NUSHU CHARACTER-1B2B6;Lo;0;L;;;;;N;;;;;\n1B2B7;NUSHU CHARACTER-1B2B7;Lo;0;L;;;;;N;;;;;\n1B2B8;NUSHU CHARACTER-1B2B8;Lo;0;L;;;;;N;;;;;\n1B2B9;NUSHU CHARACTER-1B2B9;Lo;0;L;;;;;N;;;;;\n1B2BA;NUSHU CHARACTER-1B2BA;Lo;0;L;;;;;N;;;;;\n1B2BB;NUSHU CHARACTER-1B2BB;Lo;0;L;;;;;N;;;;;\n1B2BC;NUSHU CHARACTER-1B2BC;Lo;0;L;;;;;N;;;;;\n1B2BD;NUSHU CHARACTER-1B2BD;Lo;0;L;;;;;N;;;;;\n1B2BE;NUSHU CHARACTER-1B2BE;Lo;0;L;;;;;N;;;;;\n1B2BF;NUSHU CHARACTER-1B2BF;Lo;0;L;;;;;N;;;;;\n1B2C0;NUSHU CHARACTER-1B2C0;Lo;0;L;;;;;N;;;;;\n1B2C1;NUSHU CHARACTER-1B2C1;Lo;0;L;;;;;N;;;;;\n1B2C2;NUSHU CHARACTER-1B2C2;Lo;0;L;;;;;N;;;;;\n1B2C3;NUSHU CHARACTER-1B2C3;Lo;0;L;;;;;N;;;;;\n1B2C4;NUSHU CHARACTER-1B2C4;Lo;0;L;;;;;N;;;;;\n1B2C5;NUSHU CHARACTER-1B2C5;Lo;0;L;;;;;N;;;;;\n1B2C6;NUSHU CHARACTER-1B2C6;Lo;0;L;;;;;N;;;;;\n1B2C7;NUSHU CHARACTER-1B2C7;Lo;0;L;;;;;N;;;;;\n1B2C8;NUSHU CHARACTER-1B2C8;Lo;0;L;;;;;N;;;;;\n1B2C9;NUSHU CHARACTER-1B2C9;Lo;0;L;;;;;N;;;;;\n1B2CA;NUSHU CHARACTER-1B2CA;Lo;0;L;;;;;N;;;;;\n1B2CB;NUSHU CHARACTER-1B2CB;Lo;0;L;;;;;N;;;;;\n1B2CC;NUSHU CHARACTER-1B2CC;Lo;0;L;;;;;N;;;;;\n1B2CD;NUSHU CHARACTER-1B2CD;Lo;0;L;;;;;N;;;;;\n1B2CE;NUSHU CHARACTER-1B2CE;Lo;0;L;;;;;N;;;;;\n1B2CF;NUSHU CHARACTER-1B2CF;Lo;0;L;;;;;N;;;;;\n1B2D0;NUSHU CHARACTER-1B2D0;Lo;0;L;;;;;N;;;;;\n1B2D1;NUSHU CHARACTER-1B2D1;Lo;0;L;;;;;N;;;;;\n1B2D2;NUSHU CHARACTER-1B2D2;Lo;0;L;;;;;N;;;;;\n1B2D3;NUSHU CHARACTER-1B2D3;Lo;0;L;;;;;N;;;;;\n1B2D4;NUSHU CHARACTER-1B2D4;Lo;0;L;;;;;N;;;;;\n1B2D5;NUSHU CHARACTER-1B2D5;Lo;0;L;;;;;N;;;;;\n1B2D6;NUSHU CHARACTER-1B2D6;Lo;0;L;;;;;N;;;;;\n1B2D7;NUSHU CHARACTER-1B2D7;Lo;0;L;;;;;N;;;;;\n1B2D8;NUSHU CHARACTER-1B2D8;Lo;0;L;;;;;N;;;;;\n1B2D9;NUSHU CHARACTER-1B2D9;Lo;0;L;;;;;N;;;;;\n1B2DA;NUSHU CHARACTER-1B2DA;Lo;0;L;;;;;N;;;;;\n1B2DB;NUSHU CHARACTER-1B2DB;Lo;0;L;;;;;N;;;;;\n1B2DC;NUSHU CHARACTER-1B2DC;Lo;0;L;;;;;N;;;;;\n1B2DD;NUSHU CHARACTER-1B2DD;Lo;0;L;;;;;N;;;;;\n1B2DE;NUSHU CHARACTER-1B2DE;Lo;0;L;;;;;N;;;;;\n1B2DF;NUSHU CHARACTER-1B2DF;Lo;0;L;;;;;N;;;;;\n1B2E0;NUSHU CHARACTER-1B2E0;Lo;0;L;;;;;N;;;;;\n1B2E1;NUSHU CHARACTER-1B2E1;Lo;0;L;;;;;N;;;;;\n1B2E2;NUSHU CHARACTER-1B2E2;Lo;0;L;;;;;N;;;;;\n1B2E3;NUSHU CHARACTER-1B2E3;Lo;0;L;;;;;N;;;;;\n1B2E4;NUSHU CHARACTER-1B2E4;Lo;0;L;;;;;N;;;;;\n1B2E5;NUSHU CHARACTER-1B2E5;Lo;0;L;;;;;N;;;;;\n1B2E6;NUSHU CHARACTER-1B2E6;Lo;0;L;;;;;N;;;;;\n1B2E7;NUSHU CHARACTER-1B2E7;Lo;0;L;;;;;N;;;;;\n1B2E8;NUSHU CHARACTER-1B2E8;Lo;0;L;;;;;N;;;;;\n1B2E9;NUSHU CHARACTER-1B2E9;Lo;0;L;;;;;N;;;;;\n1B2EA;NUSHU CHARACTER-1B2EA;Lo;0;L;;;;;N;;;;;\n1B2EB;NUSHU CHARACTER-1B2EB;Lo;0;L;;;;;N;;;;;\n1B2EC;NUSHU CHARACTER-1B2EC;Lo;0;L;;;;;N;;;;;\n1B2ED;NUSHU CHARACTER-1B2ED;Lo;0;L;;;;;N;;;;;\n1B2EE;NUSHU CHARACTER-1B2EE;Lo;0;L;;;;;N;;;;;\n1B2EF;NUSHU CHARACTER-1B2EF;Lo;0;L;;;;;N;;;;;\n1B2F0;NUSHU CHARACTER-1B2F0;Lo;0;L;;;;;N;;;;;\n1B2F1;NUSHU CHARACTER-1B2F1;Lo;0;L;;;;;N;;;;;\n1B2F2;NUSHU CHARACTER-1B2F2;Lo;0;L;;;;;N;;;;;\n1B2F3;NUSHU CHARACTER-1B2F3;Lo;0;L;;;;;N;;;;;\n1B2F4;NUSHU CHARACTER-1B2F4;Lo;0;L;;;;;N;;;;;\n1B2F5;NUSHU CHARACTER-1B2F5;Lo;0;L;;;;;N;;;;;\n1B2F6;NUSHU CHARACTER-1B2F6;Lo;0;L;;;;;N;;;;;\n1B2F7;NUSHU CHARACTER-1B2F7;Lo;0;L;;;;;N;;;;;\n1B2F8;NUSHU CHARACTER-1B2F8;Lo;0;L;;;;;N;;;;;\n1B2F9;NUSHU CHARACTER-1B2F9;Lo;0;L;;;;;N;;;;;\n1B2FA;NUSHU CHARACTER-1B2FA;Lo;0;L;;;;;N;;;;;\n1B2FB;NUSHU CHARACTER-1B2FB;Lo;0;L;;;;;N;;;;;\n1BC00;DUPLOYAN LETTER H;Lo;0;L;;;;;N;;;;;\n1BC01;DUPLOYAN LETTER X;Lo;0;L;;;;;N;;;;;\n1BC02;DUPLOYAN LETTER P;Lo;0;L;;;;;N;;;;;\n1BC03;DUPLOYAN LETTER T;Lo;0;L;;;;;N;;;;;\n1BC04;DUPLOYAN LETTER F;Lo;0;L;;;;;N;;;;;\n1BC05;DUPLOYAN LETTER K;Lo;0;L;;;;;N;;;;;\n1BC06;DUPLOYAN LETTER L;Lo;0;L;;;;;N;;;;;\n1BC07;DUPLOYAN LETTER B;Lo;0;L;;;;;N;;;;;\n1BC08;DUPLOYAN LETTER D;Lo;0;L;;;;;N;;;;;\n1BC09;DUPLOYAN LETTER V;Lo;0;L;;;;;N;;;;;\n1BC0A;DUPLOYAN LETTER G;Lo;0;L;;;;;N;;;;;\n1BC0B;DUPLOYAN LETTER R;Lo;0;L;;;;;N;;;;;\n1BC0C;DUPLOYAN LETTER P N;Lo;0;L;;;;;N;;;;;\n1BC0D;DUPLOYAN LETTER D S;Lo;0;L;;;;;N;;;;;\n1BC0E;DUPLOYAN LETTER F N;Lo;0;L;;;;;N;;;;;\n1BC0F;DUPLOYAN LETTER K M;Lo;0;L;;;;;N;;;;;\n1BC10;DUPLOYAN LETTER R S;Lo;0;L;;;;;N;;;;;\n1BC11;DUPLOYAN LETTER TH;Lo;0;L;;;;;N;;;;;\n1BC12;DUPLOYAN LETTER SLOAN DH;Lo;0;L;;;;;N;;;;;\n1BC13;DUPLOYAN LETTER DH;Lo;0;L;;;;;N;;;;;\n1BC14;DUPLOYAN LETTER KK;Lo;0;L;;;;;N;;;;;\n1BC15;DUPLOYAN LETTER SLOAN J;Lo;0;L;;;;;N;;;;;\n1BC16;DUPLOYAN LETTER HL;Lo;0;L;;;;;N;;;;;\n1BC17;DUPLOYAN LETTER LH;Lo;0;L;;;;;N;;;;;\n1BC18;DUPLOYAN LETTER RH;Lo;0;L;;;;;N;;;;;\n1BC19;DUPLOYAN LETTER M;Lo;0;L;;;;;N;;;;;\n1BC1A;DUPLOYAN LETTER N;Lo;0;L;;;;;N;;;;;\n1BC1B;DUPLOYAN LETTER J;Lo;0;L;;;;;N;;;;;\n1BC1C;DUPLOYAN LETTER S;Lo;0;L;;;;;N;;;;;\n1BC1D;DUPLOYAN LETTER M N;Lo;0;L;;;;;N;;;;;\n1BC1E;DUPLOYAN LETTER N M;Lo;0;L;;;;;N;;;;;\n1BC1F;DUPLOYAN LETTER J M;Lo;0;L;;;;;N;;;;;\n1BC20;DUPLOYAN LETTER S J;Lo;0;L;;;;;N;;;;;\n1BC21;DUPLOYAN LETTER M WITH DOT;Lo;0;L;;;;;N;;;;;\n1BC22;DUPLOYAN LETTER N WITH DOT;Lo;0;L;;;;;N;;;;;\n1BC23;DUPLOYAN LETTER J WITH DOT;Lo;0;L;;;;;N;;;;;\n1BC24;DUPLOYAN LETTER J WITH DOTS INSIDE AND ABOVE;Lo;0;L;;;;;N;;;;;\n1BC25;DUPLOYAN LETTER S WITH DOT;Lo;0;L;;;;;N;;;;;\n1BC26;DUPLOYAN LETTER S WITH DOT BELOW;Lo;0;L;;;;;N;;;;;\n1BC27;DUPLOYAN LETTER M S;Lo;0;L;;;;;N;;;;;\n1BC28;DUPLOYAN LETTER N S;Lo;0;L;;;;;N;;;;;\n1BC29;DUPLOYAN LETTER J S;Lo;0;L;;;;;N;;;;;\n1BC2A;DUPLOYAN LETTER S S;Lo;0;L;;;;;N;;;;;\n1BC2B;DUPLOYAN LETTER M N S;Lo;0;L;;;;;N;;;;;\n1BC2C;DUPLOYAN LETTER N M S;Lo;0;L;;;;;N;;;;;\n1BC2D;DUPLOYAN LETTER J M S;Lo;0;L;;;;;N;;;;;\n1BC2E;DUPLOYAN LETTER S J S;Lo;0;L;;;;;N;;;;;\n1BC2F;DUPLOYAN LETTER J S WITH DOT;Lo;0;L;;;;;N;;;;;\n1BC30;DUPLOYAN LETTER J N;Lo;0;L;;;;;N;;;;;\n1BC31;DUPLOYAN LETTER J N S;Lo;0;L;;;;;N;;;;;\n1BC32;DUPLOYAN LETTER S T;Lo;0;L;;;;;N;;;;;\n1BC33;DUPLOYAN LETTER S T R;Lo;0;L;;;;;N;;;;;\n1BC34;DUPLOYAN LETTER S P;Lo;0;L;;;;;N;;;;;\n1BC35;DUPLOYAN LETTER S P R;Lo;0;L;;;;;N;;;;;\n1BC36;DUPLOYAN LETTER T S;Lo;0;L;;;;;N;;;;;\n1BC37;DUPLOYAN LETTER T R S;Lo;0;L;;;;;N;;;;;\n1BC38;DUPLOYAN LETTER W;Lo;0;L;;;;;N;;;;;\n1BC39;DUPLOYAN LETTER WH;Lo;0;L;;;;;N;;;;;\n1BC3A;DUPLOYAN LETTER W R;Lo;0;L;;;;;N;;;;;\n1BC3B;DUPLOYAN LETTER S N;Lo;0;L;;;;;N;;;;;\n1BC3C;DUPLOYAN LETTER S M;Lo;0;L;;;;;N;;;;;\n1BC3D;DUPLOYAN LETTER K R S;Lo;0;L;;;;;N;;;;;\n1BC3E;DUPLOYAN LETTER G R S;Lo;0;L;;;;;N;;;;;\n1BC3F;DUPLOYAN LETTER S K;Lo;0;L;;;;;N;;;;;\n1BC40;DUPLOYAN LETTER S K R;Lo;0;L;;;;;N;;;;;\n1BC41;DUPLOYAN LETTER A;Lo;0;L;;;;;N;;;;;\n1BC42;DUPLOYAN LETTER SLOAN OW;Lo;0;L;;;;;N;;;;;\n1BC43;DUPLOYAN LETTER OA;Lo;0;L;;;;;N;;;;;\n1BC44;DUPLOYAN LETTER O;Lo;0;L;;;;;N;;;;;\n1BC45;DUPLOYAN LETTER AOU;Lo;0;L;;;;;N;;;;;\n1BC46;DUPLOYAN LETTER I;Lo;0;L;;;;;N;;;;;\n1BC47;DUPLOYAN LETTER E;Lo;0;L;;;;;N;;;;;\n1BC48;DUPLOYAN LETTER IE;Lo;0;L;;;;;N;;;;;\n1BC49;DUPLOYAN LETTER SHORT I;Lo;0;L;;;;;N;;;;;\n1BC4A;DUPLOYAN LETTER UI;Lo;0;L;;;;;N;;;;;\n1BC4B;DUPLOYAN LETTER EE;Lo;0;L;;;;;N;;;;;\n1BC4C;DUPLOYAN LETTER SLOAN EH;Lo;0;L;;;;;N;;;;;\n1BC4D;DUPLOYAN LETTER ROMANIAN I;Lo;0;L;;;;;N;;;;;\n1BC4E;DUPLOYAN LETTER SLOAN EE;Lo;0;L;;;;;N;;;;;\n1BC4F;DUPLOYAN LETTER LONG I;Lo;0;L;;;;;N;;;;;\n1BC50;DUPLOYAN LETTER YE;Lo;0;L;;;;;N;;;;;\n1BC51;DUPLOYAN LETTER U;Lo;0;L;;;;;N;;;;;\n1BC52;DUPLOYAN LETTER EU;Lo;0;L;;;;;N;;;;;\n1BC53;DUPLOYAN LETTER XW;Lo;0;L;;;;;N;;;;;\n1BC54;DUPLOYAN LETTER U N;Lo;0;L;;;;;N;;;;;\n1BC55;DUPLOYAN LETTER LONG U;Lo;0;L;;;;;N;;;;;\n1BC56;DUPLOYAN LETTER ROMANIAN U;Lo;0;L;;;;;N;;;;;\n1BC57;DUPLOYAN LETTER UH;Lo;0;L;;;;;N;;;;;\n1BC58;DUPLOYAN LETTER SLOAN U;Lo;0;L;;;;;N;;;;;\n1BC59;DUPLOYAN LETTER OOH;Lo;0;L;;;;;N;;;;;\n1BC5A;DUPLOYAN LETTER OW;Lo;0;L;;;;;N;;;;;\n1BC5B;DUPLOYAN LETTER OU;Lo;0;L;;;;;N;;;;;\n1BC5C;DUPLOYAN LETTER WA;Lo;0;L;;;;;N;;;;;\n1BC5D;DUPLOYAN LETTER WO;Lo;0;L;;;;;N;;;;;\n1BC5E;DUPLOYAN LETTER WI;Lo;0;L;;;;;N;;;;;\n1BC5F;DUPLOYAN LETTER WEI;Lo;0;L;;;;;N;;;;;\n1BC60;DUPLOYAN LETTER WOW;Lo;0;L;;;;;N;;;;;\n1BC61;DUPLOYAN LETTER NASAL U;Lo;0;L;;;;;N;;;;;\n1BC62;DUPLOYAN LETTER NASAL O;Lo;0;L;;;;;N;;;;;\n1BC63;DUPLOYAN LETTER NASAL I;Lo;0;L;;;;;N;;;;;\n1BC64;DUPLOYAN LETTER NASAL A;Lo;0;L;;;;;N;;;;;\n1BC65;DUPLOYAN LETTER PERNIN AN;Lo;0;L;;;;;N;;;;;\n1BC66;DUPLOYAN LETTER PERNIN AM;Lo;0;L;;;;;N;;;;;\n1BC67;DUPLOYAN LETTER SLOAN EN;Lo;0;L;;;;;N;;;;;\n1BC68;DUPLOYAN LETTER SLOAN AN;Lo;0;L;;;;;N;;;;;\n1BC69;DUPLOYAN LETTER SLOAN ON;Lo;0;L;;;;;N;;;;;\n1BC6A;DUPLOYAN LETTER VOCALIC M;Lo;0;L;;;;;N;;;;;\n1BC70;DUPLOYAN AFFIX LEFT HORIZONTAL SECANT;Lo;0;L;;;;;N;;;;;\n1BC71;DUPLOYAN AFFIX MID HORIZONTAL SECANT;Lo;0;L;;;;;N;;;;;\n1BC72;DUPLOYAN AFFIX RIGHT HORIZONTAL SECANT;Lo;0;L;;;;;N;;;;;\n1BC73;DUPLOYAN AFFIX LOW VERTICAL SECANT;Lo;0;L;;;;;N;;;;;\n1BC74;DUPLOYAN AFFIX MID VERTICAL SECANT;Lo;0;L;;;;;N;;;;;\n1BC75;DUPLOYAN AFFIX HIGH VERTICAL SECANT;Lo;0;L;;;;;N;;;;;\n1BC76;DUPLOYAN AFFIX ATTACHED SECANT;Lo;0;L;;;;;N;;;;;\n1BC77;DUPLOYAN AFFIX ATTACHED LEFT-TO-RIGHT SECANT;Lo;0;L;;;;;N;;;;;\n1BC78;DUPLOYAN AFFIX ATTACHED TANGENT;Lo;0;L;;;;;N;;;;;\n1BC79;DUPLOYAN AFFIX ATTACHED TAIL;Lo;0;L;;;;;N;;;;;\n1BC7A;DUPLOYAN AFFIX ATTACHED E HOOK;Lo;0;L;;;;;N;;;;;\n1BC7B;DUPLOYAN AFFIX ATTACHED I HOOK;Lo;0;L;;;;;N;;;;;\n1BC7C;DUPLOYAN AFFIX ATTACHED TANGENT HOOK;Lo;0;L;;;;;N;;;;;\n1BC80;DUPLOYAN AFFIX HIGH ACUTE;Lo;0;L;;;;;N;;;;;\n1BC81;DUPLOYAN AFFIX HIGH TIGHT ACUTE;Lo;0;L;;;;;N;;;;;\n1BC82;DUPLOYAN AFFIX HIGH GRAVE;Lo;0;L;;;;;N;;;;;\n1BC83;DUPLOYAN AFFIX HIGH LONG GRAVE;Lo;0;L;;;;;N;;;;;\n1BC84;DUPLOYAN AFFIX HIGH DOT;Lo;0;L;;;;;N;;;;;\n1BC85;DUPLOYAN AFFIX HIGH CIRCLE;Lo;0;L;;;;;N;;;;;\n1BC86;DUPLOYAN AFFIX HIGH LINE;Lo;0;L;;;;;N;;;;;\n1BC87;DUPLOYAN AFFIX HIGH WAVE;Lo;0;L;;;;;N;;;;;\n1BC88;DUPLOYAN AFFIX HIGH VERTICAL;Lo;0;L;;;;;N;;;;;\n1BC90;DUPLOYAN AFFIX LOW ACUTE;Lo;0;L;;;;;N;;;;;\n1BC91;DUPLOYAN AFFIX LOW TIGHT ACUTE;Lo;0;L;;;;;N;;;;;\n1BC92;DUPLOYAN AFFIX LOW GRAVE;Lo;0;L;;;;;N;;;;;\n1BC93;DUPLOYAN AFFIX LOW LONG GRAVE;Lo;0;L;;;;;N;;;;;\n1BC94;DUPLOYAN AFFIX LOW DOT;Lo;0;L;;;;;N;;;;;\n1BC95;DUPLOYAN AFFIX LOW CIRCLE;Lo;0;L;;;;;N;;;;;\n1BC96;DUPLOYAN AFFIX LOW LINE;Lo;0;L;;;;;N;;;;;\n1BC97;DUPLOYAN AFFIX LOW WAVE;Lo;0;L;;;;;N;;;;;\n1BC98;DUPLOYAN AFFIX LOW VERTICAL;Lo;0;L;;;;;N;;;;;\n1BC99;DUPLOYAN AFFIX LOW ARROW;Lo;0;L;;;;;N;;;;;\n1BC9C;DUPLOYAN SIGN O WITH CROSS;So;0;L;;;;;N;;;;;\n1BC9D;DUPLOYAN THICK LETTER SELECTOR;Mn;0;NSM;;;;;N;;;;;\n1BC9E;DUPLOYAN DOUBLE MARK;Mn;1;NSM;;;;;N;;;;;\n1BC9F;DUPLOYAN PUNCTUATION CHINOOK FULL STOP;Po;0;L;;;;;N;;;;;\n1BCA0;SHORTHAND FORMAT LETTER OVERLAP;Cf;0;BN;;;;;N;;;;;\n1BCA1;SHORTHAND FORMAT CONTINUING OVERLAP;Cf;0;BN;;;;;N;;;;;\n1BCA2;SHORTHAND FORMAT DOWN STEP;Cf;0;BN;;;;;N;;;;;\n1BCA3;SHORTHAND FORMAT UP STEP;Cf;0;BN;;;;;N;;;;;\n1D000;BYZANTINE MUSICAL SYMBOL PSILI;So;0;L;;;;;N;;;;;\n1D001;BYZANTINE MUSICAL SYMBOL DASEIA;So;0;L;;;;;N;;;;;\n1D002;BYZANTINE MUSICAL SYMBOL PERISPOMENI;So;0;L;;;;;N;;;;;\n1D003;BYZANTINE MUSICAL SYMBOL OXEIA EKFONITIKON;So;0;L;;;;;N;;;;;\n1D004;BYZANTINE MUSICAL SYMBOL OXEIA DIPLI;So;0;L;;;;;N;;;;;\n1D005;BYZANTINE MUSICAL SYMBOL VAREIA EKFONITIKON;So;0;L;;;;;N;;;;;\n1D006;BYZANTINE MUSICAL SYMBOL VAREIA DIPLI;So;0;L;;;;;N;;;;;\n1D007;BYZANTINE MUSICAL SYMBOL KATHISTI;So;0;L;;;;;N;;;;;\n1D008;BYZANTINE MUSICAL SYMBOL SYRMATIKI;So;0;L;;;;;N;;;;;\n1D009;BYZANTINE MUSICAL SYMBOL PARAKLITIKI;So;0;L;;;;;N;;;;;\n1D00A;BYZANTINE MUSICAL SYMBOL YPOKRISIS;So;0;L;;;;;N;;;;;\n1D00B;BYZANTINE MUSICAL SYMBOL YPOKRISIS DIPLI;So;0;L;;;;;N;;;;;\n1D00C;BYZANTINE MUSICAL SYMBOL KREMASTI;So;0;L;;;;;N;;;;;\n1D00D;BYZANTINE MUSICAL SYMBOL APESO EKFONITIKON;So;0;L;;;;;N;;;;;\n1D00E;BYZANTINE MUSICAL SYMBOL EXO EKFONITIKON;So;0;L;;;;;N;;;;;\n1D00F;BYZANTINE MUSICAL SYMBOL TELEIA;So;0;L;;;;;N;;;;;\n1D010;BYZANTINE MUSICAL SYMBOL KENTIMATA;So;0;L;;;;;N;;;;;\n1D011;BYZANTINE MUSICAL SYMBOL APOSTROFOS;So;0;L;;;;;N;;;;;\n1D012;BYZANTINE MUSICAL SYMBOL APOSTROFOS DIPLI;So;0;L;;;;;N;;;;;\n1D013;BYZANTINE MUSICAL SYMBOL SYNEVMA;So;0;L;;;;;N;;;;;\n1D014;BYZANTINE MUSICAL SYMBOL THITA;So;0;L;;;;;N;;;;;\n1D015;BYZANTINE MUSICAL SYMBOL OLIGON ARCHAION;So;0;L;;;;;N;;;;;\n1D016;BYZANTINE MUSICAL SYMBOL GORGON ARCHAION;So;0;L;;;;;N;;;;;\n1D017;BYZANTINE MUSICAL SYMBOL PSILON;So;0;L;;;;;N;;;;;\n1D018;BYZANTINE MUSICAL SYMBOL CHAMILON;So;0;L;;;;;N;;;;;\n1D019;BYZANTINE MUSICAL SYMBOL VATHY;So;0;L;;;;;N;;;;;\n1D01A;BYZANTINE MUSICAL SYMBOL ISON ARCHAION;So;0;L;;;;;N;;;;;\n1D01B;BYZANTINE MUSICAL SYMBOL KENTIMA ARCHAION;So;0;L;;;;;N;;;;;\n1D01C;BYZANTINE MUSICAL SYMBOL KENTIMATA ARCHAION;So;0;L;;;;;N;;;;;\n1D01D;BYZANTINE MUSICAL SYMBOL SAXIMATA;So;0;L;;;;;N;;;;;\n1D01E;BYZANTINE MUSICAL SYMBOL PARICHON;So;0;L;;;;;N;;;;;\n1D01F;BYZANTINE MUSICAL SYMBOL STAVROS APODEXIA;So;0;L;;;;;N;;;;;\n1D020;BYZANTINE MUSICAL SYMBOL OXEIAI ARCHAION;So;0;L;;;;;N;;;;;\n1D021;BYZANTINE MUSICAL SYMBOL VAREIAI ARCHAION;So;0;L;;;;;N;;;;;\n1D022;BYZANTINE MUSICAL SYMBOL APODERMA ARCHAION;So;0;L;;;;;N;;;;;\n1D023;BYZANTINE MUSICAL SYMBOL APOTHEMA;So;0;L;;;;;N;;;;;\n1D024;BYZANTINE MUSICAL SYMBOL KLASMA;So;0;L;;;;;N;;;;;\n1D025;BYZANTINE MUSICAL SYMBOL REVMA;So;0;L;;;;;N;;;;;\n1D026;BYZANTINE MUSICAL SYMBOL PIASMA ARCHAION;So;0;L;;;;;N;;;;;\n1D027;BYZANTINE MUSICAL SYMBOL TINAGMA;So;0;L;;;;;N;;;;;\n1D028;BYZANTINE MUSICAL SYMBOL ANATRICHISMA;So;0;L;;;;;N;;;;;\n1D029;BYZANTINE MUSICAL SYMBOL SEISMA;So;0;L;;;;;N;;;;;\n1D02A;BYZANTINE MUSICAL SYMBOL SYNAGMA ARCHAION;So;0;L;;;;;N;;;;;\n1D02B;BYZANTINE MUSICAL SYMBOL SYNAGMA META STAVROU;So;0;L;;;;;N;;;;;\n1D02C;BYZANTINE MUSICAL SYMBOL OYRANISMA ARCHAION;So;0;L;;;;;N;;;;;\n1D02D;BYZANTINE MUSICAL SYMBOL THEMA;So;0;L;;;;;N;;;;;\n1D02E;BYZANTINE MUSICAL SYMBOL LEMOI;So;0;L;;;;;N;;;;;\n1D02F;BYZANTINE MUSICAL SYMBOL DYO;So;0;L;;;;;N;;;;;\n1D030;BYZANTINE MUSICAL SYMBOL TRIA;So;0;L;;;;;N;;;;;\n1D031;BYZANTINE MUSICAL SYMBOL TESSERA;So;0;L;;;;;N;;;;;\n1D032;BYZANTINE MUSICAL SYMBOL KRATIMATA;So;0;L;;;;;N;;;;;\n1D033;BYZANTINE MUSICAL SYMBOL APESO EXO NEO;So;0;L;;;;;N;;;;;\n1D034;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION;So;0;L;;;;;N;;;;;\n1D035;BYZANTINE MUSICAL SYMBOL IMIFTHORA;So;0;L;;;;;N;;;;;\n1D036;BYZANTINE MUSICAL SYMBOL TROMIKON ARCHAION;So;0;L;;;;;N;;;;;\n1D037;BYZANTINE MUSICAL SYMBOL KATAVA TROMIKON;So;0;L;;;;;N;;;;;\n1D038;BYZANTINE MUSICAL SYMBOL PELASTON;So;0;L;;;;;N;;;;;\n1D039;BYZANTINE MUSICAL SYMBOL PSIFISTON;So;0;L;;;;;N;;;;;\n1D03A;BYZANTINE MUSICAL SYMBOL KONTEVMA;So;0;L;;;;;N;;;;;\n1D03B;BYZANTINE MUSICAL SYMBOL CHOREVMA ARCHAION;So;0;L;;;;;N;;;;;\n1D03C;BYZANTINE MUSICAL SYMBOL RAPISMA;So;0;L;;;;;N;;;;;\n1D03D;BYZANTINE MUSICAL SYMBOL PARAKALESMA ARCHAION;So;0;L;;;;;N;;;;;\n1D03E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI ARCHAION;So;0;L;;;;;N;;;;;\n1D03F;BYZANTINE MUSICAL SYMBOL ICHADIN;So;0;L;;;;;N;;;;;\n1D040;BYZANTINE MUSICAL SYMBOL NANA;So;0;L;;;;;N;;;;;\n1D041;BYZANTINE MUSICAL SYMBOL PETASMA;So;0;L;;;;;N;;;;;\n1D042;BYZANTINE MUSICAL SYMBOL KONTEVMA ALLO;So;0;L;;;;;N;;;;;\n1D043;BYZANTINE MUSICAL SYMBOL TROMIKON ALLO;So;0;L;;;;;N;;;;;\n1D044;BYZANTINE MUSICAL SYMBOL STRAGGISMATA;So;0;L;;;;;N;;;;;\n1D045;BYZANTINE MUSICAL SYMBOL GRONTHISMATA;So;0;L;;;;;N;;;;;\n1D046;BYZANTINE MUSICAL SYMBOL ISON NEO;So;0;L;;;;;N;;;;;\n1D047;BYZANTINE MUSICAL SYMBOL OLIGON NEO;So;0;L;;;;;N;;;;;\n1D048;BYZANTINE MUSICAL SYMBOL OXEIA NEO;So;0;L;;;;;N;;;;;\n1D049;BYZANTINE MUSICAL SYMBOL PETASTI;So;0;L;;;;;N;;;;;\n1D04A;BYZANTINE MUSICAL SYMBOL KOUFISMA;So;0;L;;;;;N;;;;;\n1D04B;BYZANTINE MUSICAL SYMBOL PETASTOKOUFISMA;So;0;L;;;;;N;;;;;\n1D04C;BYZANTINE MUSICAL SYMBOL KRATIMOKOUFISMA;So;0;L;;;;;N;;;;;\n1D04D;BYZANTINE MUSICAL SYMBOL PELASTON NEO;So;0;L;;;;;N;;;;;\n1D04E;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO ANO;So;0;L;;;;;N;;;;;\n1D04F;BYZANTINE MUSICAL SYMBOL KENTIMA NEO ANO;So;0;L;;;;;N;;;;;\n1D050;BYZANTINE MUSICAL SYMBOL YPSILI;So;0;L;;;;;N;;;;;\n1D051;BYZANTINE MUSICAL SYMBOL APOSTROFOS NEO;So;0;L;;;;;N;;;;;\n1D052;BYZANTINE MUSICAL SYMBOL APOSTROFOI SYNDESMOS NEO;So;0;L;;;;;N;;;;;\n1D053;BYZANTINE MUSICAL SYMBOL YPORROI;So;0;L;;;;;N;;;;;\n1D054;BYZANTINE MUSICAL SYMBOL KRATIMOYPORROON;So;0;L;;;;;N;;;;;\n1D055;BYZANTINE MUSICAL SYMBOL ELAFRON;So;0;L;;;;;N;;;;;\n1D056;BYZANTINE MUSICAL SYMBOL CHAMILI;So;0;L;;;;;N;;;;;\n1D057;BYZANTINE MUSICAL SYMBOL MIKRON ISON;So;0;L;;;;;N;;;;;\n1D058;BYZANTINE MUSICAL SYMBOL VAREIA NEO;So;0;L;;;;;N;;;;;\n1D059;BYZANTINE MUSICAL SYMBOL PIASMA NEO;So;0;L;;;;;N;;;;;\n1D05A;BYZANTINE MUSICAL SYMBOL PSIFISTON NEO;So;0;L;;;;;N;;;;;\n1D05B;BYZANTINE MUSICAL SYMBOL OMALON;So;0;L;;;;;N;;;;;\n1D05C;BYZANTINE MUSICAL SYMBOL ANTIKENOMA;So;0;L;;;;;N;;;;;\n1D05D;BYZANTINE MUSICAL SYMBOL LYGISMA;So;0;L;;;;;N;;;;;\n1D05E;BYZANTINE MUSICAL SYMBOL PARAKLITIKI NEO;So;0;L;;;;;N;;;;;\n1D05F;BYZANTINE MUSICAL SYMBOL PARAKALESMA NEO;So;0;L;;;;;N;;;;;\n1D060;BYZANTINE MUSICAL SYMBOL ETERON PARAKALESMA;So;0;L;;;;;N;;;;;\n1D061;BYZANTINE MUSICAL SYMBOL KYLISMA;So;0;L;;;;;N;;;;;\n1D062;BYZANTINE MUSICAL SYMBOL ANTIKENOKYLISMA;So;0;L;;;;;N;;;;;\n1D063;BYZANTINE MUSICAL SYMBOL TROMIKON NEO;So;0;L;;;;;N;;;;;\n1D064;BYZANTINE MUSICAL SYMBOL EKSTREPTON;So;0;L;;;;;N;;;;;\n1D065;BYZANTINE MUSICAL SYMBOL SYNAGMA NEO;So;0;L;;;;;N;;;;;\n1D066;BYZANTINE MUSICAL SYMBOL SYRMA;So;0;L;;;;;N;;;;;\n1D067;BYZANTINE MUSICAL SYMBOL CHOREVMA NEO;So;0;L;;;;;N;;;;;\n1D068;BYZANTINE MUSICAL SYMBOL EPEGERMA;So;0;L;;;;;N;;;;;\n1D069;BYZANTINE MUSICAL SYMBOL SEISMA NEO;So;0;L;;;;;N;;;;;\n1D06A;BYZANTINE MUSICAL SYMBOL XIRON KLASMA;So;0;L;;;;;N;;;;;\n1D06B;BYZANTINE MUSICAL SYMBOL TROMIKOPSIFISTON;So;0;L;;;;;N;;;;;\n1D06C;BYZANTINE MUSICAL SYMBOL PSIFISTOLYGISMA;So;0;L;;;;;N;;;;;\n1D06D;BYZANTINE MUSICAL SYMBOL TROMIKOLYGISMA;So;0;L;;;;;N;;;;;\n1D06E;BYZANTINE MUSICAL SYMBOL TROMIKOPARAKALESMA;So;0;L;;;;;N;;;;;\n1D06F;BYZANTINE MUSICAL SYMBOL PSIFISTOPARAKALESMA;So;0;L;;;;;N;;;;;\n1D070;BYZANTINE MUSICAL SYMBOL TROMIKOSYNAGMA;So;0;L;;;;;N;;;;;\n1D071;BYZANTINE MUSICAL SYMBOL PSIFISTOSYNAGMA;So;0;L;;;;;N;;;;;\n1D072;BYZANTINE MUSICAL SYMBOL GORGOSYNTHETON;So;0;L;;;;;N;;;;;\n1D073;BYZANTINE MUSICAL SYMBOL ARGOSYNTHETON;So;0;L;;;;;N;;;;;\n1D074;BYZANTINE MUSICAL SYMBOL ETERON ARGOSYNTHETON;So;0;L;;;;;N;;;;;\n1D075;BYZANTINE MUSICAL SYMBOL OYRANISMA NEO;So;0;L;;;;;N;;;;;\n1D076;BYZANTINE MUSICAL SYMBOL THEMATISMOS ESO;So;0;L;;;;;N;;;;;\n1D077;BYZANTINE MUSICAL SYMBOL THEMATISMOS EXO;So;0;L;;;;;N;;;;;\n1D078;BYZANTINE MUSICAL SYMBOL THEMA APLOUN;So;0;L;;;;;N;;;;;\n1D079;BYZANTINE MUSICAL SYMBOL THES KAI APOTHES;So;0;L;;;;;N;;;;;\n1D07A;BYZANTINE MUSICAL SYMBOL KATAVASMA;So;0;L;;;;;N;;;;;\n1D07B;BYZANTINE MUSICAL SYMBOL ENDOFONON;So;0;L;;;;;N;;;;;\n1D07C;BYZANTINE MUSICAL SYMBOL YFEN KATO;So;0;L;;;;;N;;;;;\n1D07D;BYZANTINE MUSICAL SYMBOL YFEN ANO;So;0;L;;;;;N;;;;;\n1D07E;BYZANTINE MUSICAL SYMBOL STAVROS;So;0;L;;;;;N;;;;;\n1D07F;BYZANTINE MUSICAL SYMBOL KLASMA ANO;So;0;L;;;;;N;;;;;\n1D080;BYZANTINE MUSICAL SYMBOL DIPLI ARCHAION;So;0;L;;;;;N;;;;;\n1D081;BYZANTINE MUSICAL SYMBOL KRATIMA ARCHAION;So;0;L;;;;;N;;;;;\n1D082;BYZANTINE MUSICAL SYMBOL KRATIMA ALLO;So;0;L;;;;;N;;;;;\n1D083;BYZANTINE MUSICAL SYMBOL KRATIMA NEO;So;0;L;;;;;N;;;;;\n1D084;BYZANTINE MUSICAL SYMBOL APODERMA NEO;So;0;L;;;;;N;;;;;\n1D085;BYZANTINE MUSICAL SYMBOL APLI;So;0;L;;;;;N;;;;;\n1D086;BYZANTINE MUSICAL SYMBOL DIPLI;So;0;L;;;;;N;;;;;\n1D087;BYZANTINE MUSICAL SYMBOL TRIPLI;So;0;L;;;;;N;;;;;\n1D088;BYZANTINE MUSICAL SYMBOL TETRAPLI;So;0;L;;;;;N;;;;;\n1D089;BYZANTINE MUSICAL SYMBOL KORONIS;So;0;L;;;;;N;;;;;\n1D08A;BYZANTINE MUSICAL SYMBOL LEIMMA ENOS CHRONOU;So;0;L;;;;;N;;;;;\n1D08B;BYZANTINE MUSICAL SYMBOL LEIMMA DYO CHRONON;So;0;L;;;;;N;;;;;\n1D08C;BYZANTINE MUSICAL SYMBOL LEIMMA TRION CHRONON;So;0;L;;;;;N;;;;;\n1D08D;BYZANTINE MUSICAL SYMBOL LEIMMA TESSARON CHRONON;So;0;L;;;;;N;;;;;\n1D08E;BYZANTINE MUSICAL SYMBOL LEIMMA IMISEOS CHRONOU;So;0;L;;;;;N;;;;;\n1D08F;BYZANTINE MUSICAL SYMBOL GORGON NEO ANO;So;0;L;;;;;N;;;;;\n1D090;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON ARISTERA;So;0;L;;;;;N;;;;;\n1D091;BYZANTINE MUSICAL SYMBOL GORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;;\n1D092;BYZANTINE MUSICAL SYMBOL DIGORGON;So;0;L;;;;;N;;;;;\n1D093;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA KATO;So;0;L;;;;;N;;;;;\n1D094;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON ARISTERA ANO;So;0;L;;;;;N;;;;;\n1D095;BYZANTINE MUSICAL SYMBOL DIGORGON PARESTIGMENON DEXIA;So;0;L;;;;;N;;;;;\n1D096;BYZANTINE MUSICAL SYMBOL TRIGORGON;So;0;L;;;;;N;;;;;\n1D097;BYZANTINE MUSICAL SYMBOL ARGON;So;0;L;;;;;N;;;;;\n1D098;BYZANTINE MUSICAL SYMBOL IMIDIARGON;So;0;L;;;;;N;;;;;\n1D099;BYZANTINE MUSICAL SYMBOL DIARGON;So;0;L;;;;;N;;;;;\n1D09A;BYZANTINE MUSICAL SYMBOL AGOGI POLI ARGI;So;0;L;;;;;N;;;;;\n1D09B;BYZANTINE MUSICAL SYMBOL AGOGI ARGOTERI;So;0;L;;;;;N;;;;;\n1D09C;BYZANTINE MUSICAL SYMBOL AGOGI ARGI;So;0;L;;;;;N;;;;;\n1D09D;BYZANTINE MUSICAL SYMBOL AGOGI METRIA;So;0;L;;;;;N;;;;;\n1D09E;BYZANTINE MUSICAL SYMBOL AGOGI MESI;So;0;L;;;;;N;;;;;\n1D09F;BYZANTINE MUSICAL SYMBOL AGOGI GORGI;So;0;L;;;;;N;;;;;\n1D0A0;BYZANTINE MUSICAL SYMBOL AGOGI GORGOTERI;So;0;L;;;;;N;;;;;\n1D0A1;BYZANTINE MUSICAL SYMBOL AGOGI POLI GORGI;So;0;L;;;;;N;;;;;\n1D0A2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOS ICHOS;So;0;L;;;;;N;;;;;\n1D0A3;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI PROTOS ICHOS;So;0;L;;;;;N;;;;;\n1D0A4;BYZANTINE MUSICAL SYMBOL MARTYRIA DEYTEROS ICHOS;So;0;L;;;;;N;;;;;\n1D0A5;BYZANTINE MUSICAL SYMBOL MARTYRIA ALLI DEYTEROS ICHOS;So;0;L;;;;;N;;;;;\n1D0A6;BYZANTINE MUSICAL SYMBOL MARTYRIA TRITOS ICHOS;So;0;L;;;;;N;;;;;\n1D0A7;BYZANTINE MUSICAL SYMBOL MARTYRIA TRIFONIAS;So;0;L;;;;;N;;;;;\n1D0A8;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS ICHOS;So;0;L;;;;;N;;;;;\n1D0A9;BYZANTINE MUSICAL SYMBOL MARTYRIA TETARTOS LEGETOS ICHOS;So;0;L;;;;;N;;;;;\n1D0AA;BYZANTINE MUSICAL SYMBOL MARTYRIA LEGETOS ICHOS;So;0;L;;;;;N;;;;;\n1D0AB;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS ICHOS;So;0;L;;;;;N;;;;;\n1D0AC;BYZANTINE MUSICAL SYMBOL ISAKIA TELOUS ICHIMATOS;So;0;L;;;;;N;;;;;\n1D0AD;BYZANTINE MUSICAL SYMBOL APOSTROFOI TELOUS ICHIMATOS;So;0;L;;;;;N;;;;;\n1D0AE;BYZANTINE MUSICAL SYMBOL FANEROSIS TETRAFONIAS;So;0;L;;;;;N;;;;;\n1D0AF;BYZANTINE MUSICAL SYMBOL FANEROSIS MONOFONIAS;So;0;L;;;;;N;;;;;\n1D0B0;BYZANTINE MUSICAL SYMBOL FANEROSIS DIFONIAS;So;0;L;;;;;N;;;;;\n1D0B1;BYZANTINE MUSICAL SYMBOL MARTYRIA VARYS ICHOS;So;0;L;;;;;N;;;;;\n1D0B2;BYZANTINE MUSICAL SYMBOL MARTYRIA PROTOVARYS ICHOS;So;0;L;;;;;N;;;;;\n1D0B3;BYZANTINE MUSICAL SYMBOL MARTYRIA PLAGIOS TETARTOS ICHOS;So;0;L;;;;;N;;;;;\n1D0B4;BYZANTINE MUSICAL SYMBOL GORTHMIKON N APLOUN;So;0;L;;;;;N;;;;;\n1D0B5;BYZANTINE MUSICAL SYMBOL GORTHMIKON N DIPLOUN;So;0;L;;;;;N;;;;;\n1D0B6;BYZANTINE MUSICAL SYMBOL ENARXIS KAI FTHORA VOU;So;0;L;;;;;N;;;;;\n1D0B7;BYZANTINE MUSICAL SYMBOL IMIFONON;So;0;L;;;;;N;;;;;\n1D0B8;BYZANTINE MUSICAL SYMBOL IMIFTHORON;So;0;L;;;;;N;;;;;\n1D0B9;BYZANTINE MUSICAL SYMBOL FTHORA ARCHAION DEYTEROU ICHOU;So;0;L;;;;;N;;;;;\n1D0BA;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI PA;So;0;L;;;;;N;;;;;\n1D0BB;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NANA;So;0;L;;;;;N;;;;;\n1D0BC;BYZANTINE MUSICAL SYMBOL FTHORA NAOS ICHOS;So;0;L;;;;;N;;;;;\n1D0BD;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI DI;So;0;L;;;;;N;;;;;\n1D0BE;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON DIATONON DI;So;0;L;;;;;N;;;;;\n1D0BF;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI KE;So;0;L;;;;;N;;;;;\n1D0C0;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI ZO;So;0;L;;;;;N;;;;;\n1D0C1;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI KATO;So;0;L;;;;;N;;;;;\n1D0C2;BYZANTINE MUSICAL SYMBOL FTHORA DIATONIKI NI ANO;So;0;L;;;;;N;;;;;\n1D0C3;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA DIFONIAS;So;0;L;;;;;N;;;;;\n1D0C4;BYZANTINE MUSICAL SYMBOL FTHORA MALAKON CHROMA MONOFONIAS;So;0;L;;;;;N;;;;;\n1D0C5;BYZANTINE MUSICAL SYMBOL FHTORA SKLIRON CHROMA VASIS;So;0;L;;;;;N;;;;;\n1D0C6;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON CHROMA SYNAFI;So;0;L;;;;;N;;;;;\n1D0C7;BYZANTINE MUSICAL SYMBOL FTHORA NENANO;So;0;L;;;;;N;;;;;\n1D0C8;BYZANTINE MUSICAL SYMBOL CHROA ZYGOS;So;0;L;;;;;N;;;;;\n1D0C9;BYZANTINE MUSICAL SYMBOL CHROA KLITON;So;0;L;;;;;N;;;;;\n1D0CA;BYZANTINE MUSICAL SYMBOL CHROA SPATHI;So;0;L;;;;;N;;;;;\n1D0CB;BYZANTINE MUSICAL SYMBOL FTHORA I YFESIS TETARTIMORION;So;0;L;;;;;N;;;;;\n1D0CC;BYZANTINE MUSICAL SYMBOL FTHORA ENARMONIOS ANTIFONIA;So;0;L;;;;;N;;;;;\n1D0CD;BYZANTINE MUSICAL SYMBOL YFESIS TRITIMORION;So;0;L;;;;;N;;;;;\n1D0CE;BYZANTINE MUSICAL SYMBOL DIESIS TRITIMORION;So;0;L;;;;;N;;;;;\n1D0CF;BYZANTINE MUSICAL SYMBOL DIESIS TETARTIMORION;So;0;L;;;;;N;;;;;\n1D0D0;BYZANTINE MUSICAL SYMBOL DIESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;;\n1D0D1;BYZANTINE MUSICAL SYMBOL DIESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;;\n1D0D2;BYZANTINE MUSICAL SYMBOL DIESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;;\n1D0D3;BYZANTINE MUSICAL SYMBOL DIESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;;\n1D0D4;BYZANTINE MUSICAL SYMBOL YFESIS APLI DYO DODEKATA;So;0;L;;;;;N;;;;;\n1D0D5;BYZANTINE MUSICAL SYMBOL YFESIS MONOGRAMMOS TESSERA DODEKATA;So;0;L;;;;;N;;;;;\n1D0D6;BYZANTINE MUSICAL SYMBOL YFESIS DIGRAMMOS EX DODEKATA;So;0;L;;;;;N;;;;;\n1D0D7;BYZANTINE MUSICAL SYMBOL YFESIS TRIGRAMMOS OKTO DODEKATA;So;0;L;;;;;N;;;;;\n1D0D8;BYZANTINE MUSICAL SYMBOL GENIKI DIESIS;So;0;L;;;;;N;;;;;\n1D0D9;BYZANTINE MUSICAL SYMBOL GENIKI YFESIS;So;0;L;;;;;N;;;;;\n1D0DA;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MIKRI;So;0;L;;;;;N;;;;;\n1D0DB;BYZANTINE MUSICAL SYMBOL DIASTOLI APLI MEGALI;So;0;L;;;;;N;;;;;\n1D0DC;BYZANTINE MUSICAL SYMBOL DIASTOLI DIPLI;So;0;L;;;;;N;;;;;\n1D0DD;BYZANTINE MUSICAL SYMBOL DIASTOLI THESEOS;So;0;L;;;;;N;;;;;\n1D0DE;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS;So;0;L;;;;;N;;;;;\n1D0DF;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS DISIMOU;So;0;L;;;;;N;;;;;\n1D0E0;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TRISIMOU;So;0;L;;;;;N;;;;;\n1D0E1;BYZANTINE MUSICAL SYMBOL SIMANSIS THESEOS TETRASIMOU;So;0;L;;;;;N;;;;;\n1D0E2;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS;So;0;L;;;;;N;;;;;\n1D0E3;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS DISIMOU;So;0;L;;;;;N;;;;;\n1D0E4;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TRISIMOU;So;0;L;;;;;N;;;;;\n1D0E5;BYZANTINE MUSICAL SYMBOL SIMANSIS ARSEOS TETRASIMOU;So;0;L;;;;;N;;;;;\n1D0E6;BYZANTINE MUSICAL SYMBOL DIGRAMMA GG;So;0;L;;;;;N;;;;;\n1D0E7;BYZANTINE MUSICAL SYMBOL DIFTOGGOS OU;So;0;L;;;;;N;;;;;\n1D0E8;BYZANTINE MUSICAL SYMBOL STIGMA;So;0;L;;;;;N;;;;;\n1D0E9;BYZANTINE MUSICAL SYMBOL ARKTIKO PA;So;0;L;;;;;N;;;;;\n1D0EA;BYZANTINE MUSICAL SYMBOL ARKTIKO VOU;So;0;L;;;;;N;;;;;\n1D0EB;BYZANTINE MUSICAL SYMBOL ARKTIKO GA;So;0;L;;;;;N;;;;;\n1D0EC;BYZANTINE MUSICAL SYMBOL ARKTIKO DI;So;0;L;;;;;N;;;;;\n1D0ED;BYZANTINE MUSICAL SYMBOL ARKTIKO KE;So;0;L;;;;;N;;;;;\n1D0EE;BYZANTINE MUSICAL SYMBOL ARKTIKO ZO;So;0;L;;;;;N;;;;;\n1D0EF;BYZANTINE MUSICAL SYMBOL ARKTIKO NI;So;0;L;;;;;N;;;;;\n1D0F0;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO MESO;So;0;L;;;;;N;;;;;\n1D0F1;BYZANTINE MUSICAL SYMBOL KENTIMA NEO MESO;So;0;L;;;;;N;;;;;\n1D0F2;BYZANTINE MUSICAL SYMBOL KENTIMATA NEO KATO;So;0;L;;;;;N;;;;;\n1D0F3;BYZANTINE MUSICAL SYMBOL KENTIMA NEO KATO;So;0;L;;;;;N;;;;;\n1D0F4;BYZANTINE MUSICAL SYMBOL KLASMA KATO;So;0;L;;;;;N;;;;;\n1D0F5;BYZANTINE MUSICAL SYMBOL GORGON NEO KATO;So;0;L;;;;;N;;;;;\n1D100;MUSICAL SYMBOL SINGLE BARLINE;So;0;L;;;;;N;;;;;\n1D101;MUSICAL SYMBOL DOUBLE BARLINE;So;0;L;;;;;N;;;;;\n1D102;MUSICAL SYMBOL FINAL BARLINE;So;0;L;;;;;N;;;;;\n1D103;MUSICAL SYMBOL REVERSE FINAL BARLINE;So;0;L;;;;;N;;;;;\n1D104;MUSICAL SYMBOL DASHED BARLINE;So;0;L;;;;;N;;;;;\n1D105;MUSICAL SYMBOL SHORT BARLINE;So;0;L;;;;;N;;;;;\n1D106;MUSICAL SYMBOL LEFT REPEAT SIGN;So;0;L;;;;;N;;;;;\n1D107;MUSICAL SYMBOL RIGHT REPEAT SIGN;So;0;L;;;;;N;;;;;\n1D108;MUSICAL SYMBOL REPEAT DOTS;So;0;L;;;;;N;;;;;\n1D109;MUSICAL SYMBOL DAL SEGNO;So;0;L;;;;;N;;;;;\n1D10A;MUSICAL SYMBOL DA CAPO;So;0;L;;;;;N;;;;;\n1D10B;MUSICAL SYMBOL SEGNO;So;0;L;;;;;N;;;;;\n1D10C;MUSICAL SYMBOL CODA;So;0;L;;;;;N;;;;;\n1D10D;MUSICAL SYMBOL REPEATED FIGURE-1;So;0;L;;;;;N;;;;;\n1D10E;MUSICAL SYMBOL REPEATED FIGURE-2;So;0;L;;;;;N;;;;;\n1D10F;MUSICAL SYMBOL REPEATED FIGURE-3;So;0;L;;;;;N;;;;;\n1D110;MUSICAL SYMBOL FERMATA;So;0;L;;;;;N;;;;;\n1D111;MUSICAL SYMBOL FERMATA BELOW;So;0;L;;;;;N;;;;;\n1D112;MUSICAL SYMBOL BREATH MARK;So;0;L;;;;;N;;;;;\n1D113;MUSICAL SYMBOL CAESURA;So;0;L;;;;;N;;;;;\n1D114;MUSICAL SYMBOL BRACE;So;0;L;;;;;N;;;;;\n1D115;MUSICAL SYMBOL BRACKET;So;0;L;;;;;N;;;;;\n1D116;MUSICAL SYMBOL ONE-LINE STAFF;So;0;L;;;;;N;;;;;\n1D117;MUSICAL SYMBOL TWO-LINE STAFF;So;0;L;;;;;N;;;;;\n1D118;MUSICAL SYMBOL THREE-LINE STAFF;So;0;L;;;;;N;;;;;\n1D119;MUSICAL SYMBOL FOUR-LINE STAFF;So;0;L;;;;;N;;;;;\n1D11A;MUSICAL SYMBOL FIVE-LINE STAFF;So;0;L;;;;;N;;;;;\n1D11B;MUSICAL SYMBOL SIX-LINE STAFF;So;0;L;;;;;N;;;;;\n1D11C;MUSICAL SYMBOL SIX-STRING FRETBOARD;So;0;L;;;;;N;;;;;\n1D11D;MUSICAL SYMBOL FOUR-STRING FRETBOARD;So;0;L;;;;;N;;;;;\n1D11E;MUSICAL SYMBOL G CLEF;So;0;L;;;;;N;;;;;\n1D11F;MUSICAL SYMBOL G CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;;\n1D120;MUSICAL SYMBOL G CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;;\n1D121;MUSICAL SYMBOL C CLEF;So;0;L;;;;;N;;;;;\n1D122;MUSICAL SYMBOL F CLEF;So;0;L;;;;;N;;;;;\n1D123;MUSICAL SYMBOL F CLEF OTTAVA ALTA;So;0;L;;;;;N;;;;;\n1D124;MUSICAL SYMBOL F CLEF OTTAVA BASSA;So;0;L;;;;;N;;;;;\n1D125;MUSICAL SYMBOL DRUM CLEF-1;So;0;L;;;;;N;;;;;\n1D126;MUSICAL SYMBOL DRUM CLEF-2;So;0;L;;;;;N;;;;;\n1D129;MUSICAL SYMBOL MULTIPLE MEASURE REST;So;0;L;;;;;N;;;;;\n1D12A;MUSICAL SYMBOL DOUBLE SHARP;So;0;L;;;;;N;;;;;\n1D12B;MUSICAL SYMBOL DOUBLE FLAT;So;0;L;;;;;N;;;;;\n1D12C;MUSICAL SYMBOL FLAT UP;So;0;L;;;;;N;;;;;\n1D12D;MUSICAL SYMBOL FLAT DOWN;So;0;L;;;;;N;;;;;\n1D12E;MUSICAL SYMBOL NATURAL UP;So;0;L;;;;;N;;;;;\n1D12F;MUSICAL SYMBOL NATURAL DOWN;So;0;L;;;;;N;;;;;\n1D130;MUSICAL SYMBOL SHARP UP;So;0;L;;;;;N;;;;;\n1D131;MUSICAL SYMBOL SHARP DOWN;So;0;L;;;;;N;;;;;\n1D132;MUSICAL SYMBOL QUARTER TONE SHARP;So;0;L;;;;;N;;;;;\n1D133;MUSICAL SYMBOL QUARTER TONE FLAT;So;0;L;;;;;N;;;;;\n1D134;MUSICAL SYMBOL COMMON TIME;So;0;L;;;;;N;;;;;\n1D135;MUSICAL SYMBOL CUT TIME;So;0;L;;;;;N;;;;;\n1D136;MUSICAL SYMBOL OTTAVA ALTA;So;0;L;;;;;N;;;;;\n1D137;MUSICAL SYMBOL OTTAVA BASSA;So;0;L;;;;;N;;;;;\n1D138;MUSICAL SYMBOL QUINDICESIMA ALTA;So;0;L;;;;;N;;;;;\n1D139;MUSICAL SYMBOL QUINDICESIMA BASSA;So;0;L;;;;;N;;;;;\n1D13A;MUSICAL SYMBOL MULTI REST;So;0;L;;;;;N;;;;;\n1D13B;MUSICAL SYMBOL WHOLE REST;So;0;L;;;;;N;;;;;\n1D13C;MUSICAL SYMBOL HALF REST;So;0;L;;;;;N;;;;;\n1D13D;MUSICAL SYMBOL QUARTER REST;So;0;L;;;;;N;;;;;\n1D13E;MUSICAL SYMBOL EIGHTH REST;So;0;L;;;;;N;;;;;\n1D13F;MUSICAL SYMBOL SIXTEENTH REST;So;0;L;;;;;N;;;;;\n1D140;MUSICAL SYMBOL THIRTY-SECOND REST;So;0;L;;;;;N;;;;;\n1D141;MUSICAL SYMBOL SIXTY-FOURTH REST;So;0;L;;;;;N;;;;;\n1D142;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH REST;So;0;L;;;;;N;;;;;\n1D143;MUSICAL SYMBOL X NOTEHEAD;So;0;L;;;;;N;;;;;\n1D144;MUSICAL SYMBOL PLUS NOTEHEAD;So;0;L;;;;;N;;;;;\n1D145;MUSICAL SYMBOL CIRCLE X NOTEHEAD;So;0;L;;;;;N;;;;;\n1D146;MUSICAL SYMBOL SQUARE NOTEHEAD WHITE;So;0;L;;;;;N;;;;;\n1D147;MUSICAL SYMBOL SQUARE NOTEHEAD BLACK;So;0;L;;;;;N;;;;;\n1D148;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP WHITE;So;0;L;;;;;N;;;;;\n1D149;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP BLACK;So;0;L;;;;;N;;;;;\n1D14A;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT WHITE;So;0;L;;;;;N;;;;;\n1D14B;MUSICAL SYMBOL TRIANGLE NOTEHEAD LEFT BLACK;So;0;L;;;;;N;;;;;\n1D14C;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT WHITE;So;0;L;;;;;N;;;;;\n1D14D;MUSICAL SYMBOL TRIANGLE NOTEHEAD RIGHT BLACK;So;0;L;;;;;N;;;;;\n1D14E;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;;\n1D14F;MUSICAL SYMBOL TRIANGLE NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;;\n1D150;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT WHITE;So;0;L;;;;;N;;;;;\n1D151;MUSICAL SYMBOL TRIANGLE NOTEHEAD UP RIGHT BLACK;So;0;L;;;;;N;;;;;\n1D152;MUSICAL SYMBOL MOON NOTEHEAD WHITE;So;0;L;;;;;N;;;;;\n1D153;MUSICAL SYMBOL MOON NOTEHEAD BLACK;So;0;L;;;;;N;;;;;\n1D154;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN WHITE;So;0;L;;;;;N;;;;;\n1D155;MUSICAL SYMBOL TRIANGLE-ROUND NOTEHEAD DOWN BLACK;So;0;L;;;;;N;;;;;\n1D156;MUSICAL SYMBOL PARENTHESIS NOTEHEAD;So;0;L;;;;;N;;;;;\n1D157;MUSICAL SYMBOL VOID NOTEHEAD;So;0;L;;;;;N;;;;;\n1D158;MUSICAL SYMBOL NOTEHEAD BLACK;So;0;L;;;;;N;;;;;\n1D159;MUSICAL SYMBOL NULL NOTEHEAD;So;0;L;;;;;N;;;;;\n1D15A;MUSICAL SYMBOL CLUSTER NOTEHEAD WHITE;So;0;L;;;;;N;;;;;\n1D15B;MUSICAL SYMBOL CLUSTER NOTEHEAD BLACK;So;0;L;;;;;N;;;;;\n1D15C;MUSICAL SYMBOL BREVE;So;0;L;;;;;N;;;;;\n1D15D;MUSICAL SYMBOL WHOLE NOTE;So;0;L;;;;;N;;;;;\n1D15E;MUSICAL SYMBOL HALF NOTE;So;0;L;1D157 1D165;;;;N;;;;;\n1D15F;MUSICAL SYMBOL QUARTER NOTE;So;0;L;1D158 1D165;;;;N;;;;;\n1D160;MUSICAL SYMBOL EIGHTH NOTE;So;0;L;1D15F 1D16E;;;;N;;;;;\n1D161;MUSICAL SYMBOL SIXTEENTH NOTE;So;0;L;1D15F 1D16F;;;;N;;;;;\n1D162;MUSICAL SYMBOL THIRTY-SECOND NOTE;So;0;L;1D15F 1D170;;;;N;;;;;\n1D163;MUSICAL SYMBOL SIXTY-FOURTH NOTE;So;0;L;1D15F 1D171;;;;N;;;;;\n1D164;MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE;So;0;L;1D15F 1D172;;;;N;;;;;\n1D165;MUSICAL SYMBOL COMBINING STEM;Mc;216;L;;;;;N;;;;;\n1D166;MUSICAL SYMBOL COMBINING SPRECHGESANG STEM;Mc;216;L;;;;;N;;;;;\n1D167;MUSICAL SYMBOL COMBINING TREMOLO-1;Mn;1;NSM;;;;;N;;;;;\n1D168;MUSICAL SYMBOL COMBINING TREMOLO-2;Mn;1;NSM;;;;;N;;;;;\n1D169;MUSICAL SYMBOL COMBINING TREMOLO-3;Mn;1;NSM;;;;;N;;;;;\n1D16A;MUSICAL SYMBOL FINGERED TREMOLO-1;So;0;L;;;;;N;;;;;\n1D16B;MUSICAL SYMBOL FINGERED TREMOLO-2;So;0;L;;;;;N;;;;;\n1D16C;MUSICAL SYMBOL FINGERED TREMOLO-3;So;0;L;;;;;N;;;;;\n1D16D;MUSICAL SYMBOL COMBINING AUGMENTATION DOT;Mc;226;L;;;;;N;;;;;\n1D16E;MUSICAL SYMBOL COMBINING FLAG-1;Mc;216;L;;;;;N;;;;;\n1D16F;MUSICAL SYMBOL COMBINING FLAG-2;Mc;216;L;;;;;N;;;;;\n1D170;MUSICAL SYMBOL COMBINING FLAG-3;Mc;216;L;;;;;N;;;;;\n1D171;MUSICAL SYMBOL COMBINING FLAG-4;Mc;216;L;;;;;N;;;;;\n1D172;MUSICAL SYMBOL COMBINING FLAG-5;Mc;216;L;;;;;N;;;;;\n1D173;MUSICAL SYMBOL BEGIN BEAM;Cf;0;BN;;;;;N;;;;;\n1D174;MUSICAL SYMBOL END BEAM;Cf;0;BN;;;;;N;;;;;\n1D175;MUSICAL SYMBOL BEGIN TIE;Cf;0;BN;;;;;N;;;;;\n1D176;MUSICAL SYMBOL END TIE;Cf;0;BN;;;;;N;;;;;\n1D177;MUSICAL SYMBOL BEGIN SLUR;Cf;0;BN;;;;;N;;;;;\n1D178;MUSICAL SYMBOL END SLUR;Cf;0;BN;;;;;N;;;;;\n1D179;MUSICAL SYMBOL BEGIN PHRASE;Cf;0;BN;;;;;N;;;;;\n1D17A;MUSICAL SYMBOL END PHRASE;Cf;0;BN;;;;;N;;;;;\n1D17B;MUSICAL SYMBOL COMBINING ACCENT;Mn;220;NSM;;;;;N;;;;;\n1D17C;MUSICAL SYMBOL COMBINING STACCATO;Mn;220;NSM;;;;;N;;;;;\n1D17D;MUSICAL SYMBOL COMBINING TENUTO;Mn;220;NSM;;;;;N;;;;;\n1D17E;MUSICAL SYMBOL COMBINING STACCATISSIMO;Mn;220;NSM;;;;;N;;;;;\n1D17F;MUSICAL SYMBOL COMBINING MARCATO;Mn;220;NSM;;;;;N;;;;;\n1D180;MUSICAL SYMBOL COMBINING MARCATO-STACCATO;Mn;220;NSM;;;;;N;;;;;\n1D181;MUSICAL SYMBOL COMBINING ACCENT-STACCATO;Mn;220;NSM;;;;;N;;;;;\n1D182;MUSICAL SYMBOL COMBINING LOURE;Mn;220;NSM;;;;;N;;;;;\n1D183;MUSICAL SYMBOL ARPEGGIATO UP;So;0;L;;;;;N;;;;;\n1D184;MUSICAL SYMBOL ARPEGGIATO DOWN;So;0;L;;;;;N;;;;;\n1D185;MUSICAL SYMBOL COMBINING DOIT;Mn;230;NSM;;;;;N;;;;;\n1D186;MUSICAL SYMBOL COMBINING RIP;Mn;230;NSM;;;;;N;;;;;\n1D187;MUSICAL SYMBOL COMBINING FLIP;Mn;230;NSM;;;;;N;;;;;\n1D188;MUSICAL SYMBOL COMBINING SMEAR;Mn;230;NSM;;;;;N;;;;;\n1D189;MUSICAL SYMBOL COMBINING BEND;Mn;230;NSM;;;;;N;;;;;\n1D18A;MUSICAL SYMBOL COMBINING DOUBLE TONGUE;Mn;220;NSM;;;;;N;;;;;\n1D18B;MUSICAL SYMBOL COMBINING TRIPLE TONGUE;Mn;220;NSM;;;;;N;;;;;\n1D18C;MUSICAL SYMBOL RINFORZANDO;So;0;L;;;;;N;;;;;\n1D18D;MUSICAL SYMBOL SUBITO;So;0;L;;;;;N;;;;;\n1D18E;MUSICAL SYMBOL Z;So;0;L;;;;;N;;;;;\n1D18F;MUSICAL SYMBOL PIANO;So;0;L;;;;;N;;;;;\n1D190;MUSICAL SYMBOL MEZZO;So;0;L;;;;;N;;;;;\n1D191;MUSICAL SYMBOL FORTE;So;0;L;;;;;N;;;;;\n1D192;MUSICAL SYMBOL CRESCENDO;So;0;L;;;;;N;;;;;\n1D193;MUSICAL SYMBOL DECRESCENDO;So;0;L;;;;;N;;;;;\n1D194;MUSICAL SYMBOL GRACE NOTE SLASH;So;0;L;;;;;N;;;;;\n1D195;MUSICAL SYMBOL GRACE NOTE NO SLASH;So;0;L;;;;;N;;;;;\n1D196;MUSICAL SYMBOL TR;So;0;L;;;;;N;;;;;\n1D197;MUSICAL SYMBOL TURN;So;0;L;;;;;N;;;;;\n1D198;MUSICAL SYMBOL INVERTED TURN;So;0;L;;;;;N;;;;;\n1D199;MUSICAL SYMBOL TURN SLASH;So;0;L;;;;;N;;;;;\n1D19A;MUSICAL SYMBOL TURN UP;So;0;L;;;;;N;;;;;\n1D19B;MUSICAL SYMBOL ORNAMENT STROKE-1;So;0;L;;;;;N;;;;;\n1D19C;MUSICAL SYMBOL ORNAMENT STROKE-2;So;0;L;;;;;N;;;;;\n1D19D;MUSICAL SYMBOL ORNAMENT STROKE-3;So;0;L;;;;;N;;;;;\n1D19E;MUSICAL SYMBOL ORNAMENT STROKE-4;So;0;L;;;;;N;;;;;\n1D19F;MUSICAL SYMBOL ORNAMENT STROKE-5;So;0;L;;;;;N;;;;;\n1D1A0;MUSICAL SYMBOL ORNAMENT STROKE-6;So;0;L;;;;;N;;;;;\n1D1A1;MUSICAL SYMBOL ORNAMENT STROKE-7;So;0;L;;;;;N;;;;;\n1D1A2;MUSICAL SYMBOL ORNAMENT STROKE-8;So;0;L;;;;;N;;;;;\n1D1A3;MUSICAL SYMBOL ORNAMENT STROKE-9;So;0;L;;;;;N;;;;;\n1D1A4;MUSICAL SYMBOL ORNAMENT STROKE-10;So;0;L;;;;;N;;;;;\n1D1A5;MUSICAL SYMBOL ORNAMENT STROKE-11;So;0;L;;;;;N;;;;;\n1D1A6;MUSICAL SYMBOL HAUPTSTIMME;So;0;L;;;;;N;;;;;\n1D1A7;MUSICAL SYMBOL NEBENSTIMME;So;0;L;;;;;N;;;;;\n1D1A8;MUSICAL SYMBOL END OF STIMME;So;0;L;;;;;N;;;;;\n1D1A9;MUSICAL SYMBOL DEGREE SLASH;So;0;L;;;;;N;;;;;\n1D1AA;MUSICAL SYMBOL COMBINING DOWN BOW;Mn;230;NSM;;;;;N;;;;;\n1D1AB;MUSICAL SYMBOL COMBINING UP BOW;Mn;230;NSM;;;;;N;;;;;\n1D1AC;MUSICAL SYMBOL COMBINING HARMONIC;Mn;230;NSM;;;;;N;;;;;\n1D1AD;MUSICAL SYMBOL COMBINING SNAP PIZZICATO;Mn;230;NSM;;;;;N;;;;;\n1D1AE;MUSICAL SYMBOL PEDAL MARK;So;0;L;;;;;N;;;;;\n1D1AF;MUSICAL SYMBOL PEDAL UP MARK;So;0;L;;;;;N;;;;;\n1D1B0;MUSICAL SYMBOL HALF PEDAL MARK;So;0;L;;;;;N;;;;;\n1D1B1;MUSICAL SYMBOL GLISSANDO UP;So;0;L;;;;;N;;;;;\n1D1B2;MUSICAL SYMBOL GLISSANDO DOWN;So;0;L;;;;;N;;;;;\n1D1B3;MUSICAL SYMBOL WITH FINGERNAILS;So;0;L;;;;;N;;;;;\n1D1B4;MUSICAL SYMBOL DAMP;So;0;L;;;;;N;;;;;\n1D1B5;MUSICAL SYMBOL DAMP ALL;So;0;L;;;;;N;;;;;\n1D1B6;MUSICAL SYMBOL MAXIMA;So;0;L;;;;;N;;;;;\n1D1B7;MUSICAL SYMBOL LONGA;So;0;L;;;;;N;;;;;\n1D1B8;MUSICAL SYMBOL BREVIS;So;0;L;;;;;N;;;;;\n1D1B9;MUSICAL SYMBOL SEMIBREVIS WHITE;So;0;L;;;;;N;;;;;\n1D1BA;MUSICAL SYMBOL SEMIBREVIS BLACK;So;0;L;;;;;N;;;;;\n1D1BB;MUSICAL SYMBOL MINIMA;So;0;L;1D1B9 1D165;;;;N;;;;;\n1D1BC;MUSICAL SYMBOL MINIMA BLACK;So;0;L;1D1BA 1D165;;;;N;;;;;\n1D1BD;MUSICAL SYMBOL SEMIMINIMA WHITE;So;0;L;1D1BB 1D16E;;;;N;;;;;\n1D1BE;MUSICAL SYMBOL SEMIMINIMA BLACK;So;0;L;1D1BC 1D16E;;;;N;;;;;\n1D1BF;MUSICAL SYMBOL FUSA WHITE;So;0;L;1D1BB 1D16F;;;;N;;;;;\n1D1C0;MUSICAL SYMBOL FUSA BLACK;So;0;L;1D1BC 1D16F;;;;N;;;;;\n1D1C1;MUSICAL SYMBOL LONGA PERFECTA REST;So;0;L;;;;;N;;;;;\n1D1C2;MUSICAL SYMBOL LONGA IMPERFECTA REST;So;0;L;;;;;N;;;;;\n1D1C3;MUSICAL SYMBOL BREVIS REST;So;0;L;;;;;N;;;;;\n1D1C4;MUSICAL SYMBOL SEMIBREVIS REST;So;0;L;;;;;N;;;;;\n1D1C5;MUSICAL SYMBOL MINIMA REST;So;0;L;;;;;N;;;;;\n1D1C6;MUSICAL SYMBOL SEMIMINIMA REST;So;0;L;;;;;N;;;;;\n1D1C7;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;;\n1D1C8;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;;\n1D1C9;MUSICAL SYMBOL TEMPUS PERFECTUM CUM PROLATIONE PERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;;\n1D1CA;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE PERFECTA;So;0;L;;;;;N;;;;;\n1D1CB;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA;So;0;L;;;;;N;;;;;\n1D1CC;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-1;So;0;L;;;;;N;;;;;\n1D1CD;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-2;So;0;L;;;;;N;;;;;\n1D1CE;MUSICAL SYMBOL TEMPUS IMPERFECTUM CUM PROLATIONE IMPERFECTA DIMINUTION-3;So;0;L;;;;;N;;;;;\n1D1CF;MUSICAL SYMBOL CROIX;So;0;L;;;;;N;;;;;\n1D1D0;MUSICAL SYMBOL GREGORIAN C CLEF;So;0;L;;;;;N;;;;;\n1D1D1;MUSICAL SYMBOL GREGORIAN F CLEF;So;0;L;;;;;N;;;;;\n1D1D2;MUSICAL SYMBOL SQUARE B;So;0;L;;;;;N;;;;;\n1D1D3;MUSICAL SYMBOL VIRGA;So;0;L;;;;;N;;;;;\n1D1D4;MUSICAL SYMBOL PODATUS;So;0;L;;;;;N;;;;;\n1D1D5;MUSICAL SYMBOL CLIVIS;So;0;L;;;;;N;;;;;\n1D1D6;MUSICAL SYMBOL SCANDICUS;So;0;L;;;;;N;;;;;\n1D1D7;MUSICAL SYMBOL CLIMACUS;So;0;L;;;;;N;;;;;\n1D1D8;MUSICAL SYMBOL TORCULUS;So;0;L;;;;;N;;;;;\n1D1D9;MUSICAL SYMBOL PORRECTUS;So;0;L;;;;;N;;;;;\n1D1DA;MUSICAL SYMBOL PORRECTUS FLEXUS;So;0;L;;;;;N;;;;;\n1D1DB;MUSICAL SYMBOL SCANDICUS FLEXUS;So;0;L;;;;;N;;;;;\n1D1DC;MUSICAL SYMBOL TORCULUS RESUPINUS;So;0;L;;;;;N;;;;;\n1D1DD;MUSICAL SYMBOL PES SUBPUNCTIS;So;0;L;;;;;N;;;;;\n1D1DE;MUSICAL SYMBOL KIEVAN C CLEF;So;0;L;;;;;N;;;;;\n1D1DF;MUSICAL SYMBOL KIEVAN END OF PIECE;So;0;L;;;;;N;;;;;\n1D1E0;MUSICAL SYMBOL KIEVAN FINAL NOTE;So;0;L;;;;;N;;;;;\n1D1E1;MUSICAL SYMBOL KIEVAN RECITATIVE MARK;So;0;L;;;;;N;;;;;\n1D1E2;MUSICAL SYMBOL KIEVAN WHOLE NOTE;So;0;L;;;;;N;;;;;\n1D1E3;MUSICAL SYMBOL KIEVAN HALF NOTE;So;0;L;;;;;N;;;;;\n1D1E4;MUSICAL SYMBOL KIEVAN QUARTER NOTE STEM DOWN;So;0;L;;;;;N;;;;;\n1D1E5;MUSICAL SYMBOL KIEVAN QUARTER NOTE STEM UP;So;0;L;;;;;N;;;;;\n1D1E6;MUSICAL SYMBOL KIEVAN EIGHTH NOTE STEM DOWN;So;0;L;;;;;N;;;;;\n1D1E7;MUSICAL SYMBOL KIEVAN EIGHTH NOTE STEM UP;So;0;L;;;;;N;;;;;\n1D1E8;MUSICAL SYMBOL KIEVAN FLAT SIGN;So;0;L;;;;;N;;;;;\n1D200;GREEK VOCAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;;\n1D201;GREEK VOCAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;;\n1D202;GREEK VOCAL NOTATION SYMBOL-3;So;0;ON;;;;;N;;;;;\n1D203;GREEK VOCAL NOTATION SYMBOL-4;So;0;ON;;;;;N;;;;;\n1D204;GREEK VOCAL NOTATION SYMBOL-5;So;0;ON;;;;;N;;;;;\n1D205;GREEK VOCAL NOTATION SYMBOL-6;So;0;ON;;;;;N;;;;;\n1D206;GREEK VOCAL NOTATION SYMBOL-7;So;0;ON;;;;;N;;;;;\n1D207;GREEK VOCAL NOTATION SYMBOL-8;So;0;ON;;;;;N;;;;;\n1D208;GREEK VOCAL NOTATION SYMBOL-9;So;0;ON;;;;;N;;;;;\n1D209;GREEK VOCAL NOTATION SYMBOL-10;So;0;ON;;;;;N;;;;;\n1D20A;GREEK VOCAL NOTATION SYMBOL-11;So;0;ON;;;;;N;;;;;\n1D20B;GREEK VOCAL NOTATION SYMBOL-12;So;0;ON;;;;;N;;;;;\n1D20C;GREEK VOCAL NOTATION SYMBOL-13;So;0;ON;;;;;N;;;;;\n1D20D;GREEK VOCAL NOTATION SYMBOL-14;So;0;ON;;;;;N;;;;;\n1D20E;GREEK VOCAL NOTATION SYMBOL-15;So;0;ON;;;;;N;;;;;\n1D20F;GREEK VOCAL NOTATION SYMBOL-16;So;0;ON;;;;;N;;;;;\n1D210;GREEK VOCAL NOTATION SYMBOL-17;So;0;ON;;;;;N;;;;;\n1D211;GREEK VOCAL NOTATION SYMBOL-18;So;0;ON;;;;;N;;;;;\n1D212;GREEK VOCAL NOTATION SYMBOL-19;So;0;ON;;;;;N;;;;;\n1D213;GREEK VOCAL NOTATION SYMBOL-20;So;0;ON;;;;;N;;;;;\n1D214;GREEK VOCAL NOTATION SYMBOL-21;So;0;ON;;;;;N;;;;;\n1D215;GREEK VOCAL NOTATION SYMBOL-22;So;0;ON;;;;;N;;;;;\n1D216;GREEK VOCAL NOTATION SYMBOL-23;So;0;ON;;;;;N;;;;;\n1D217;GREEK VOCAL NOTATION SYMBOL-24;So;0;ON;;;;;N;;;;;\n1D218;GREEK VOCAL NOTATION SYMBOL-50;So;0;ON;;;;;N;;;;;\n1D219;GREEK VOCAL NOTATION SYMBOL-51;So;0;ON;;;;;N;;;;;\n1D21A;GREEK VOCAL NOTATION SYMBOL-52;So;0;ON;;;;;N;;;;;\n1D21B;GREEK VOCAL NOTATION SYMBOL-53;So;0;ON;;;;;N;;;;;\n1D21C;GREEK VOCAL NOTATION SYMBOL-54;So;0;ON;;;;;N;;;;;\n1D21D;GREEK INSTRUMENTAL NOTATION SYMBOL-1;So;0;ON;;;;;N;;;;;\n1D21E;GREEK INSTRUMENTAL NOTATION SYMBOL-2;So;0;ON;;;;;N;;;;;\n1D21F;GREEK INSTRUMENTAL NOTATION SYMBOL-4;So;0;ON;;;;;N;;;;;\n1D220;GREEK INSTRUMENTAL NOTATION SYMBOL-5;So;0;ON;;;;;N;;;;;\n1D221;GREEK INSTRUMENTAL NOTATION SYMBOL-7;So;0;ON;;;;;N;;;;;\n1D222;GREEK INSTRUMENTAL NOTATION SYMBOL-8;So;0;ON;;;;;N;;;;;\n1D223;GREEK INSTRUMENTAL NOTATION SYMBOL-11;So;0;ON;;;;;N;;;;;\n1D224;GREEK INSTRUMENTAL NOTATION SYMBOL-12;So;0;ON;;;;;N;;;;;\n1D225;GREEK INSTRUMENTAL NOTATION SYMBOL-13;So;0;ON;;;;;N;;;;;\n1D226;GREEK INSTRUMENTAL NOTATION SYMBOL-14;So;0;ON;;;;;N;;;;;\n1D227;GREEK INSTRUMENTAL NOTATION SYMBOL-17;So;0;ON;;;;;N;;;;;\n1D228;GREEK INSTRUMENTAL NOTATION SYMBOL-18;So;0;ON;;;;;N;;;;;\n1D229;GREEK INSTRUMENTAL NOTATION SYMBOL-19;So;0;ON;;;;;N;;;;;\n1D22A;GREEK INSTRUMENTAL NOTATION SYMBOL-23;So;0;ON;;;;;N;;;;;\n1D22B;GREEK INSTRUMENTAL NOTATION SYMBOL-24;So;0;ON;;;;;N;;;;;\n1D22C;GREEK INSTRUMENTAL NOTATION SYMBOL-25;So;0;ON;;;;;N;;;;;\n1D22D;GREEK INSTRUMENTAL NOTATION SYMBOL-26;So;0;ON;;;;;N;;;;;\n1D22E;GREEK INSTRUMENTAL NOTATION SYMBOL-27;So;0;ON;;;;;N;;;;;\n1D22F;GREEK INSTRUMENTAL NOTATION SYMBOL-29;So;0;ON;;;;;N;;;;;\n1D230;GREEK INSTRUMENTAL NOTATION SYMBOL-30;So;0;ON;;;;;N;;;;;\n1D231;GREEK INSTRUMENTAL NOTATION SYMBOL-32;So;0;ON;;;;;N;;;;;\n1D232;GREEK INSTRUMENTAL NOTATION SYMBOL-36;So;0;ON;;;;;N;;;;;\n1D233;GREEK INSTRUMENTAL NOTATION SYMBOL-37;So;0;ON;;;;;N;;;;;\n1D234;GREEK INSTRUMENTAL NOTATION SYMBOL-38;So;0;ON;;;;;N;;;;;\n1D235;GREEK INSTRUMENTAL NOTATION SYMBOL-39;So;0;ON;;;;;N;;;;;\n1D236;GREEK INSTRUMENTAL NOTATION SYMBOL-40;So;0;ON;;;;;N;;;;;\n1D237;GREEK INSTRUMENTAL NOTATION SYMBOL-42;So;0;ON;;;;;N;;;;;\n1D238;GREEK INSTRUMENTAL NOTATION SYMBOL-43;So;0;ON;;;;;N;;;;;\n1D239;GREEK INSTRUMENTAL NOTATION SYMBOL-45;So;0;ON;;;;;N;;;;;\n1D23A;GREEK INSTRUMENTAL NOTATION SYMBOL-47;So;0;ON;;;;;N;;;;;\n1D23B;GREEK INSTRUMENTAL NOTATION SYMBOL-48;So;0;ON;;;;;N;;;;;\n1D23C;GREEK INSTRUMENTAL NOTATION SYMBOL-49;So;0;ON;;;;;N;;;;;\n1D23D;GREEK INSTRUMENTAL NOTATION SYMBOL-50;So;0;ON;;;;;N;;;;;\n1D23E;GREEK INSTRUMENTAL NOTATION SYMBOL-51;So;0;ON;;;;;N;;;;;\n1D23F;GREEK INSTRUMENTAL NOTATION SYMBOL-52;So;0;ON;;;;;N;;;;;\n1D240;GREEK INSTRUMENTAL NOTATION SYMBOL-53;So;0;ON;;;;;N;;;;;\n1D241;GREEK INSTRUMENTAL NOTATION SYMBOL-54;So;0;ON;;;;;N;;;;;\n1D242;COMBINING GREEK MUSICAL TRISEME;Mn;230;NSM;;;;;N;;;;;\n1D243;COMBINING GREEK MUSICAL TETRASEME;Mn;230;NSM;;;;;N;;;;;\n1D244;COMBINING GREEK MUSICAL PENTASEME;Mn;230;NSM;;;;;N;;;;;\n1D245;GREEK MUSICAL LEIMMA;So;0;ON;;;;;N;;;;;\n1D2E0;MAYAN NUMERAL ZERO;No;0;L;;;;0;N;;;;;\n1D2E1;MAYAN NUMERAL ONE;No;0;L;;;;1;N;;;;;\n1D2E2;MAYAN NUMERAL TWO;No;0;L;;;;2;N;;;;;\n1D2E3;MAYAN NUMERAL THREE;No;0;L;;;;3;N;;;;;\n1D2E4;MAYAN NUMERAL FOUR;No;0;L;;;;4;N;;;;;\n1D2E5;MAYAN NUMERAL FIVE;No;0;L;;;;5;N;;;;;\n1D2E6;MAYAN NUMERAL SIX;No;0;L;;;;6;N;;;;;\n1D2E7;MAYAN NUMERAL SEVEN;No;0;L;;;;7;N;;;;;\n1D2E8;MAYAN NUMERAL EIGHT;No;0;L;;;;8;N;;;;;\n1D2E9;MAYAN NUMERAL NINE;No;0;L;;;;9;N;;;;;\n1D2EA;MAYAN NUMERAL TEN;No;0;L;;;;10;N;;;;;\n1D2EB;MAYAN NUMERAL ELEVEN;No;0;L;;;;11;N;;;;;\n1D2EC;MAYAN NUMERAL TWELVE;No;0;L;;;;12;N;;;;;\n1D2ED;MAYAN NUMERAL THIRTEEN;No;0;L;;;;13;N;;;;;\n1D2EE;MAYAN NUMERAL FOURTEEN;No;0;L;;;;14;N;;;;;\n1D2EF;MAYAN NUMERAL FIFTEEN;No;0;L;;;;15;N;;;;;\n1D2F0;MAYAN NUMERAL SIXTEEN;No;0;L;;;;16;N;;;;;\n1D2F1;MAYAN NUMERAL SEVENTEEN;No;0;L;;;;17;N;;;;;\n1D2F2;MAYAN NUMERAL EIGHTEEN;No;0;L;;;;18;N;;;;;\n1D2F3;MAYAN NUMERAL NINETEEN;No;0;L;;;;19;N;;;;;\n1D300;MONOGRAM FOR EARTH;So;0;ON;;;;;N;;;;;\n1D301;DIGRAM FOR HEAVENLY EARTH;So;0;ON;;;;;N;;;;;\n1D302;DIGRAM FOR HUMAN EARTH;So;0;ON;;;;;N;;;;;\n1D303;DIGRAM FOR EARTHLY HEAVEN;So;0;ON;;;;;N;;;;;\n1D304;DIGRAM FOR EARTHLY HUMAN;So;0;ON;;;;;N;;;;;\n1D305;DIGRAM FOR EARTH;So;0;ON;;;;;N;;;;;\n1D306;TETRAGRAM FOR CENTRE;So;0;ON;;;;;N;;;;;\n1D307;TETRAGRAM FOR FULL CIRCLE;So;0;ON;;;;;N;;;;;\n1D308;TETRAGRAM FOR MIRED;So;0;ON;;;;;N;;;;;\n1D309;TETRAGRAM FOR BARRIER;So;0;ON;;;;;N;;;;;\n1D30A;TETRAGRAM FOR KEEPING SMALL;So;0;ON;;;;;N;;;;;\n1D30B;TETRAGRAM FOR CONTRARIETY;So;0;ON;;;;;N;;;;;\n1D30C;TETRAGRAM FOR ASCENT;So;0;ON;;;;;N;;;;;\n1D30D;TETRAGRAM FOR OPPOSITION;So;0;ON;;;;;N;;;;;\n1D30E;TETRAGRAM FOR BRANCHING OUT;So;0;ON;;;;;N;;;;;\n1D30F;TETRAGRAM FOR DEFECTIVENESS OR DISTORTION;So;0;ON;;;;;N;;;;;\n1D310;TETRAGRAM FOR DIVERGENCE;So;0;ON;;;;;N;;;;;\n1D311;TETRAGRAM FOR YOUTHFULNESS;So;0;ON;;;;;N;;;;;\n1D312;TETRAGRAM FOR INCREASE;So;0;ON;;;;;N;;;;;\n1D313;TETRAGRAM FOR PENETRATION;So;0;ON;;;;;N;;;;;\n1D314;TETRAGRAM FOR REACH;So;0;ON;;;;;N;;;;;\n1D315;TETRAGRAM FOR CONTACT;So;0;ON;;;;;N;;;;;\n1D316;TETRAGRAM FOR HOLDING BACK;So;0;ON;;;;;N;;;;;\n1D317;TETRAGRAM FOR WAITING;So;0;ON;;;;;N;;;;;\n1D318;TETRAGRAM FOR FOLLOWING;So;0;ON;;;;;N;;;;;\n1D319;TETRAGRAM FOR ADVANCE;So;0;ON;;;;;N;;;;;\n1D31A;TETRAGRAM FOR RELEASE;So;0;ON;;;;;N;;;;;\n1D31B;TETRAGRAM FOR RESISTANCE;So;0;ON;;;;;N;;;;;\n1D31C;TETRAGRAM FOR EASE;So;0;ON;;;;;N;;;;;\n1D31D;TETRAGRAM FOR JOY;So;0;ON;;;;;N;;;;;\n1D31E;TETRAGRAM FOR CONTENTION;So;0;ON;;;;;N;;;;;\n1D31F;TETRAGRAM FOR ENDEAVOUR;So;0;ON;;;;;N;;;;;\n1D320;TETRAGRAM FOR DUTIES;So;0;ON;;;;;N;;;;;\n1D321;TETRAGRAM FOR CHANGE;So;0;ON;;;;;N;;;;;\n1D322;TETRAGRAM FOR DECISIVENESS;So;0;ON;;;;;N;;;;;\n1D323;TETRAGRAM FOR BOLD RESOLUTION;So;0;ON;;;;;N;;;;;\n1D324;TETRAGRAM FOR PACKING;So;0;ON;;;;;N;;;;;\n1D325;TETRAGRAM FOR LEGION;So;0;ON;;;;;N;;;;;\n1D326;TETRAGRAM FOR CLOSENESS;So;0;ON;;;;;N;;;;;\n1D327;TETRAGRAM FOR KINSHIP;So;0;ON;;;;;N;;;;;\n1D328;TETRAGRAM FOR GATHERING;So;0;ON;;;;;N;;;;;\n1D329;TETRAGRAM FOR STRENGTH;So;0;ON;;;;;N;;;;;\n1D32A;TETRAGRAM FOR PURITY;So;0;ON;;;;;N;;;;;\n1D32B;TETRAGRAM FOR FULLNESS;So;0;ON;;;;;N;;;;;\n1D32C;TETRAGRAM FOR RESIDENCE;So;0;ON;;;;;N;;;;;\n1D32D;TETRAGRAM FOR LAW OR MODEL;So;0;ON;;;;;N;;;;;\n1D32E;TETRAGRAM FOR RESPONSE;So;0;ON;;;;;N;;;;;\n1D32F;TETRAGRAM FOR GOING TO MEET;So;0;ON;;;;;N;;;;;\n1D330;TETRAGRAM FOR ENCOUNTERS;So;0;ON;;;;;N;;;;;\n1D331;TETRAGRAM FOR STOVE;So;0;ON;;;;;N;;;;;\n1D332;TETRAGRAM FOR GREATNESS;So;0;ON;;;;;N;;;;;\n1D333;TETRAGRAM FOR ENLARGEMENT;So;0;ON;;;;;N;;;;;\n1D334;TETRAGRAM FOR PATTERN;So;0;ON;;;;;N;;;;;\n1D335;TETRAGRAM FOR RITUAL;So;0;ON;;;;;N;;;;;\n1D336;TETRAGRAM FOR FLIGHT;So;0;ON;;;;;N;;;;;\n1D337;TETRAGRAM FOR VASTNESS OR WASTING;So;0;ON;;;;;N;;;;;\n1D338;TETRAGRAM FOR CONSTANCY;So;0;ON;;;;;N;;;;;\n1D339;TETRAGRAM FOR MEASURE;So;0;ON;;;;;N;;;;;\n1D33A;TETRAGRAM FOR ETERNITY;So;0;ON;;;;;N;;;;;\n1D33B;TETRAGRAM FOR UNITY;So;0;ON;;;;;N;;;;;\n1D33C;TETRAGRAM FOR DIMINISHMENT;So;0;ON;;;;;N;;;;;\n1D33D;TETRAGRAM FOR CLOSED MOUTH;So;0;ON;;;;;N;;;;;\n1D33E;TETRAGRAM FOR GUARDEDNESS;So;0;ON;;;;;N;;;;;\n1D33F;TETRAGRAM FOR GATHERING IN;So;0;ON;;;;;N;;;;;\n1D340;TETRAGRAM FOR MASSING;So;0;ON;;;;;N;;;;;\n1D341;TETRAGRAM FOR ACCUMULATION;So;0;ON;;;;;N;;;;;\n1D342;TETRAGRAM FOR EMBELLISHMENT;So;0;ON;;;;;N;;;;;\n1D343;TETRAGRAM FOR DOUBT;So;0;ON;;;;;N;;;;;\n1D344;TETRAGRAM FOR WATCH;So;0;ON;;;;;N;;;;;\n1D345;TETRAGRAM FOR SINKING;So;0;ON;;;;;N;;;;;\n1D346;TETRAGRAM FOR INNER;So;0;ON;;;;;N;;;;;\n1D347;TETRAGRAM FOR DEPARTURE;So;0;ON;;;;;N;;;;;\n1D348;TETRAGRAM FOR DARKENING;So;0;ON;;;;;N;;;;;\n1D349;TETRAGRAM FOR DIMMING;So;0;ON;;;;;N;;;;;\n1D34A;TETRAGRAM FOR EXHAUSTION;So;0;ON;;;;;N;;;;;\n1D34B;TETRAGRAM FOR SEVERANCE;So;0;ON;;;;;N;;;;;\n1D34C;TETRAGRAM FOR STOPPAGE;So;0;ON;;;;;N;;;;;\n1D34D;TETRAGRAM FOR HARDNESS;So;0;ON;;;;;N;;;;;\n1D34E;TETRAGRAM FOR COMPLETION;So;0;ON;;;;;N;;;;;\n1D34F;TETRAGRAM FOR CLOSURE;So;0;ON;;;;;N;;;;;\n1D350;TETRAGRAM FOR FAILURE;So;0;ON;;;;;N;;;;;\n1D351;TETRAGRAM FOR AGGRAVATION;So;0;ON;;;;;N;;;;;\n1D352;TETRAGRAM FOR COMPLIANCE;So;0;ON;;;;;N;;;;;\n1D353;TETRAGRAM FOR ON THE VERGE;So;0;ON;;;;;N;;;;;\n1D354;TETRAGRAM FOR DIFFICULTIES;So;0;ON;;;;;N;;;;;\n1D355;TETRAGRAM FOR LABOURING;So;0;ON;;;;;N;;;;;\n1D356;TETRAGRAM FOR FOSTERING;So;0;ON;;;;;N;;;;;\n1D360;COUNTING ROD UNIT DIGIT ONE;No;0;L;;;;1;N;;;;;\n1D361;COUNTING ROD UNIT DIGIT TWO;No;0;L;;;;2;N;;;;;\n1D362;COUNTING ROD UNIT DIGIT THREE;No;0;L;;;;3;N;;;;;\n1D363;COUNTING ROD UNIT DIGIT FOUR;No;0;L;;;;4;N;;;;;\n1D364;COUNTING ROD UNIT DIGIT FIVE;No;0;L;;;;5;N;;;;;\n1D365;COUNTING ROD UNIT DIGIT SIX;No;0;L;;;;6;N;;;;;\n1D366;COUNTING ROD UNIT DIGIT SEVEN;No;0;L;;;;7;N;;;;;\n1D367;COUNTING ROD UNIT DIGIT EIGHT;No;0;L;;;;8;N;;;;;\n1D368;COUNTING ROD UNIT DIGIT NINE;No;0;L;;;;9;N;;;;;\n1D369;COUNTING ROD TENS DIGIT ONE;No;0;L;;;;10;N;;;;;\n1D36A;COUNTING ROD TENS DIGIT TWO;No;0;L;;;;20;N;;;;;\n1D36B;COUNTING ROD TENS DIGIT THREE;No;0;L;;;;30;N;;;;;\n1D36C;COUNTING ROD TENS DIGIT FOUR;No;0;L;;;;40;N;;;;;\n1D36D;COUNTING ROD TENS DIGIT FIVE;No;0;L;;;;50;N;;;;;\n1D36E;COUNTING ROD TENS DIGIT SIX;No;0;L;;;;60;N;;;;;\n1D36F;COUNTING ROD TENS DIGIT SEVEN;No;0;L;;;;70;N;;;;;\n1D370;COUNTING ROD TENS DIGIT EIGHT;No;0;L;;;;80;N;;;;;\n1D371;COUNTING ROD TENS DIGIT NINE;No;0;L;;;;90;N;;;;;\n1D372;IDEOGRAPHIC TALLY MARK ONE;No;0;L;;;;1;N;;;;;\n1D373;IDEOGRAPHIC TALLY MARK TWO;No;0;L;;;;2;N;;;;;\n1D374;IDEOGRAPHIC TALLY MARK THREE;No;0;L;;;;3;N;;;;;\n1D375;IDEOGRAPHIC TALLY MARK FOUR;No;0;L;;;;4;N;;;;;\n1D376;IDEOGRAPHIC TALLY MARK FIVE;No;0;L;;;;5;N;;;;;\n1D377;TALLY MARK ONE;No;0;L;;;;1;N;;;;;\n1D378;TALLY MARK FIVE;No;0;L;;;;5;N;;;;;\n1D400;MATHEMATICAL BOLD CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;\n1D401;MATHEMATICAL BOLD CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;\n1D402;MATHEMATICAL BOLD CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;\n1D403;MATHEMATICAL BOLD CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;\n1D404;MATHEMATICAL BOLD CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;\n1D405;MATHEMATICAL BOLD CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;\n1D406;MATHEMATICAL BOLD CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;\n1D407;MATHEMATICAL BOLD CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;\n1D408;MATHEMATICAL BOLD CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;\n1D409;MATHEMATICAL BOLD CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;\n1D40A;MATHEMATICAL BOLD CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;\n1D40B;MATHEMATICAL BOLD CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;\n1D40C;MATHEMATICAL BOLD CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;\n1D40D;MATHEMATICAL BOLD CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;\n1D40E;MATHEMATICAL BOLD CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;\n1D40F;MATHEMATICAL BOLD CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;\n1D410;MATHEMATICAL BOLD CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;\n1D411;MATHEMATICAL BOLD CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;\n1D412;MATHEMATICAL BOLD CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;\n1D413;MATHEMATICAL BOLD CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;\n1D414;MATHEMATICAL BOLD CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;\n1D415;MATHEMATICAL BOLD CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;\n1D416;MATHEMATICAL BOLD CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;\n1D417;MATHEMATICAL BOLD CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;\n1D418;MATHEMATICAL BOLD CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;\n1D419;MATHEMATICAL BOLD CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;\n1D41A;MATHEMATICAL BOLD SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;\n1D41B;MATHEMATICAL BOLD SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;\n1D41C;MATHEMATICAL BOLD SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;\n1D41D;MATHEMATICAL BOLD SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;\n1D41E;MATHEMATICAL BOLD SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;\n1D41F;MATHEMATICAL BOLD SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;\n1D420;MATHEMATICAL BOLD SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;\n1D421;MATHEMATICAL BOLD SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;\n1D422;MATHEMATICAL BOLD SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;\n1D423;MATHEMATICAL BOLD SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;\n1D424;MATHEMATICAL BOLD SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;\n1D425;MATHEMATICAL BOLD SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;\n1D426;MATHEMATICAL BOLD SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;\n1D427;MATHEMATICAL BOLD SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;\n1D428;MATHEMATICAL BOLD SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;\n1D429;MATHEMATICAL BOLD SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;\n1D42A;MATHEMATICAL BOLD SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;\n1D42B;MATHEMATICAL BOLD SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;\n1D42C;MATHEMATICAL BOLD SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;\n1D42D;MATHEMATICAL BOLD SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;\n1D42E;MATHEMATICAL BOLD SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;\n1D42F;MATHEMATICAL BOLD SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;\n1D430;MATHEMATICAL BOLD SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;\n1D431;MATHEMATICAL BOLD SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;\n1D432;MATHEMATICAL BOLD SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;\n1D433;MATHEMATICAL BOLD SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;\n1D434;MATHEMATICAL ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;\n1D435;MATHEMATICAL ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;\n1D436;MATHEMATICAL ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;\n1D437;MATHEMATICAL ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;\n1D438;MATHEMATICAL ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;\n1D439;MATHEMATICAL ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;\n1D43A;MATHEMATICAL ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;\n1D43B;MATHEMATICAL ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;\n1D43C;MATHEMATICAL ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;\n1D43D;MATHEMATICAL ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;\n1D43E;MATHEMATICAL ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;\n1D43F;MATHEMATICAL ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;\n1D440;MATHEMATICAL ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;\n1D441;MATHEMATICAL ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;\n1D442;MATHEMATICAL ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;\n1D443;MATHEMATICAL ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;\n1D444;MATHEMATICAL ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;\n1D445;MATHEMATICAL ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;\n1D446;MATHEMATICAL ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;\n1D447;MATHEMATICAL ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;\n1D448;MATHEMATICAL ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;\n1D449;MATHEMATICAL ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;\n1D44A;MATHEMATICAL ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;\n1D44B;MATHEMATICAL ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;\n1D44C;MATHEMATICAL ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;\n1D44D;MATHEMATICAL ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;\n1D44E;MATHEMATICAL ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;\n1D44F;MATHEMATICAL ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;\n1D450;MATHEMATICAL ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;\n1D451;MATHEMATICAL ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;\n1D452;MATHEMATICAL ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;\n1D453;MATHEMATICAL ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;\n1D454;MATHEMATICAL ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;\n1D456;MATHEMATICAL ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;\n1D457;MATHEMATICAL ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;\n1D458;MATHEMATICAL ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;\n1D459;MATHEMATICAL ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;\n1D45A;MATHEMATICAL ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;\n1D45B;MATHEMATICAL ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;\n1D45C;MATHEMATICAL ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;\n1D45D;MATHEMATICAL ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;\n1D45E;MATHEMATICAL ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;\n1D45F;MATHEMATICAL ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;\n1D460;MATHEMATICAL ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;\n1D461;MATHEMATICAL ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;\n1D462;MATHEMATICAL ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;\n1D463;MATHEMATICAL ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;\n1D464;MATHEMATICAL ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;\n1D465;MATHEMATICAL ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;\n1D466;MATHEMATICAL ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;\n1D467;MATHEMATICAL ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;\n1D468;MATHEMATICAL BOLD ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;\n1D469;MATHEMATICAL BOLD ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;\n1D46A;MATHEMATICAL BOLD ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;\n1D46B;MATHEMATICAL BOLD ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;\n1D46C;MATHEMATICAL BOLD ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;\n1D46D;MATHEMATICAL BOLD ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;\n1D46E;MATHEMATICAL BOLD ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;\n1D46F;MATHEMATICAL BOLD ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;\n1D470;MATHEMATICAL BOLD ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;\n1D471;MATHEMATICAL BOLD ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;\n1D472;MATHEMATICAL BOLD ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;\n1D473;MATHEMATICAL BOLD ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;\n1D474;MATHEMATICAL BOLD ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;\n1D475;MATHEMATICAL BOLD ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;\n1D476;MATHEMATICAL BOLD ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;\n1D477;MATHEMATICAL BOLD ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;\n1D478;MATHEMATICAL BOLD ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;\n1D479;MATHEMATICAL BOLD ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;\n1D47A;MATHEMATICAL BOLD ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;\n1D47B;MATHEMATICAL BOLD ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;\n1D47C;MATHEMATICAL BOLD ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;\n1D47D;MATHEMATICAL BOLD ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;\n1D47E;MATHEMATICAL BOLD ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;\n1D47F;MATHEMATICAL BOLD ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;\n1D480;MATHEMATICAL BOLD ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;\n1D481;MATHEMATICAL BOLD ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;\n1D482;MATHEMATICAL BOLD ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;\n1D483;MATHEMATICAL BOLD ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;\n1D484;MATHEMATICAL BOLD ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;\n1D485;MATHEMATICAL BOLD ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;\n1D486;MATHEMATICAL BOLD ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;\n1D487;MATHEMATICAL BOLD ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;\n1D488;MATHEMATICAL BOLD ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;\n1D489;MATHEMATICAL BOLD ITALIC SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;\n1D48A;MATHEMATICAL BOLD ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;\n1D48B;MATHEMATICAL BOLD ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;\n1D48C;MATHEMATICAL BOLD ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;\n1D48D;MATHEMATICAL BOLD ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;\n1D48E;MATHEMATICAL BOLD ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;\n1D48F;MATHEMATICAL BOLD ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;\n1D490;MATHEMATICAL BOLD ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;\n1D491;MATHEMATICAL BOLD ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;\n1D492;MATHEMATICAL BOLD ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;\n1D493;MATHEMATICAL BOLD ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;\n1D494;MATHEMATICAL BOLD ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;\n1D495;MATHEMATICAL BOLD ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;\n1D496;MATHEMATICAL BOLD ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;\n1D497;MATHEMATICAL BOLD ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;\n1D498;MATHEMATICAL BOLD ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;\n1D499;MATHEMATICAL BOLD ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;\n1D49A;MATHEMATICAL BOLD ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;\n1D49B;MATHEMATICAL BOLD ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;\n1D49C;MATHEMATICAL SCRIPT CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;\n1D49E;MATHEMATICAL SCRIPT CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;\n1D49F;MATHEMATICAL SCRIPT CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;\n1D4A2;MATHEMATICAL SCRIPT CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;\n1D4A5;MATHEMATICAL SCRIPT CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;\n1D4A6;MATHEMATICAL SCRIPT CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;\n1D4A9;MATHEMATICAL SCRIPT CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;\n1D4AA;MATHEMATICAL SCRIPT CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;\n1D4AB;MATHEMATICAL SCRIPT CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;\n1D4AC;MATHEMATICAL SCRIPT CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;\n1D4AE;MATHEMATICAL SCRIPT CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;\n1D4AF;MATHEMATICAL SCRIPT CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;\n1D4B0;MATHEMATICAL SCRIPT CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;\n1D4B1;MATHEMATICAL SCRIPT CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;\n1D4B2;MATHEMATICAL SCRIPT CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;\n1D4B3;MATHEMATICAL SCRIPT CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;\n1D4B4;MATHEMATICAL SCRIPT CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;\n1D4B5;MATHEMATICAL SCRIPT CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;\n1D4B6;MATHEMATICAL SCRIPT SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;\n1D4B7;MATHEMATICAL SCRIPT SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;\n1D4B8;MATHEMATICAL SCRIPT SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;\n1D4B9;MATHEMATICAL SCRIPT SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;\n1D4BB;MATHEMATICAL SCRIPT SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;\n1D4BD;MATHEMATICAL SCRIPT SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;\n1D4BE;MATHEMATICAL SCRIPT SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;\n1D4BF;MATHEMATICAL SCRIPT SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;\n1D4C0;MATHEMATICAL SCRIPT SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;\n1D4C1;MATHEMATICAL SCRIPT SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;\n1D4C2;MATHEMATICAL SCRIPT SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;\n1D4C3;MATHEMATICAL SCRIPT SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;\n1D4C5;MATHEMATICAL SCRIPT SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;\n1D4C6;MATHEMATICAL SCRIPT SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;\n1D4C7;MATHEMATICAL SCRIPT SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;\n1D4C8;MATHEMATICAL SCRIPT SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;\n1D4C9;MATHEMATICAL SCRIPT SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;\n1D4CA;MATHEMATICAL SCRIPT SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;\n1D4CB;MATHEMATICAL SCRIPT SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;\n1D4CC;MATHEMATICAL SCRIPT SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;\n1D4CD;MATHEMATICAL SCRIPT SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;\n1D4CE;MATHEMATICAL SCRIPT SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;\n1D4CF;MATHEMATICAL SCRIPT SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;\n1D4D0;MATHEMATICAL BOLD SCRIPT CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;\n1D4D1;MATHEMATICAL BOLD SCRIPT CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;\n1D4D2;MATHEMATICAL BOLD SCRIPT CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;\n1D4D3;MATHEMATICAL BOLD SCRIPT CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;\n1D4D4;MATHEMATICAL BOLD SCRIPT CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;\n1D4D5;MATHEMATICAL BOLD SCRIPT CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;\n1D4D6;MATHEMATICAL BOLD SCRIPT CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;\n1D4D7;MATHEMATICAL BOLD SCRIPT CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;\n1D4D8;MATHEMATICAL BOLD SCRIPT CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;\n1D4D9;MATHEMATICAL BOLD SCRIPT CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;\n1D4DA;MATHEMATICAL BOLD SCRIPT CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;\n1D4DB;MATHEMATICAL BOLD SCRIPT CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;\n1D4DC;MATHEMATICAL BOLD SCRIPT CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;\n1D4DD;MATHEMATICAL BOLD SCRIPT CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;\n1D4DE;MATHEMATICAL BOLD SCRIPT CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;\n1D4DF;MATHEMATICAL BOLD SCRIPT CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;\n1D4E0;MATHEMATICAL BOLD SCRIPT CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;\n1D4E1;MATHEMATICAL BOLD SCRIPT CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;\n1D4E2;MATHEMATICAL BOLD SCRIPT CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;\n1D4E3;MATHEMATICAL BOLD SCRIPT CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;\n1D4E4;MATHEMATICAL BOLD SCRIPT CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;\n1D4E5;MATHEMATICAL BOLD SCRIPT CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;\n1D4E6;MATHEMATICAL BOLD SCRIPT CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;\n1D4E7;MATHEMATICAL BOLD SCRIPT CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;\n1D4E8;MATHEMATICAL BOLD SCRIPT CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;\n1D4E9;MATHEMATICAL BOLD SCRIPT CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;\n1D4EA;MATHEMATICAL BOLD SCRIPT SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;\n1D4EB;MATHEMATICAL BOLD SCRIPT SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;\n1D4EC;MATHEMATICAL BOLD SCRIPT SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;\n1D4ED;MATHEMATICAL BOLD SCRIPT SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;\n1D4EE;MATHEMATICAL BOLD SCRIPT SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;\n1D4EF;MATHEMATICAL BOLD SCRIPT SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;\n1D4F0;MATHEMATICAL BOLD SCRIPT SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;\n1D4F1;MATHEMATICAL BOLD SCRIPT SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;\n1D4F2;MATHEMATICAL BOLD SCRIPT SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;\n1D4F3;MATHEMATICAL BOLD SCRIPT SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;\n1D4F4;MATHEMATICAL BOLD SCRIPT SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;\n1D4F5;MATHEMATICAL BOLD SCRIPT SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;\n1D4F6;MATHEMATICAL BOLD SCRIPT SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;\n1D4F7;MATHEMATICAL BOLD SCRIPT SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;\n1D4F8;MATHEMATICAL BOLD SCRIPT SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;\n1D4F9;MATHEMATICAL BOLD SCRIPT SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;\n1D4FA;MATHEMATICAL BOLD SCRIPT SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;\n1D4FB;MATHEMATICAL BOLD SCRIPT SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;\n1D4FC;MATHEMATICAL BOLD SCRIPT SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;\n1D4FD;MATHEMATICAL BOLD SCRIPT SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;\n1D4FE;MATHEMATICAL BOLD SCRIPT SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;\n1D4FF;MATHEMATICAL BOLD SCRIPT SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;\n1D500;MATHEMATICAL BOLD SCRIPT SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;\n1D501;MATHEMATICAL BOLD SCRIPT SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;\n1D502;MATHEMATICAL BOLD SCRIPT SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;\n1D503;MATHEMATICAL BOLD SCRIPT SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;\n1D504;MATHEMATICAL FRAKTUR CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;\n1D505;MATHEMATICAL FRAKTUR CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;\n1D507;MATHEMATICAL FRAKTUR CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;\n1D508;MATHEMATICAL FRAKTUR CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;\n1D509;MATHEMATICAL FRAKTUR CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;\n1D50A;MATHEMATICAL FRAKTUR CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;\n1D50D;MATHEMATICAL FRAKTUR CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;\n1D50E;MATHEMATICAL FRAKTUR CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;\n1D50F;MATHEMATICAL FRAKTUR CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;\n1D510;MATHEMATICAL FRAKTUR CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;\n1D511;MATHEMATICAL FRAKTUR CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;\n1D512;MATHEMATICAL FRAKTUR CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;\n1D513;MATHEMATICAL FRAKTUR CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;\n1D514;MATHEMATICAL FRAKTUR CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;\n1D516;MATHEMATICAL FRAKTUR CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;\n1D517;MATHEMATICAL FRAKTUR CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;\n1D518;MATHEMATICAL FRAKTUR CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;\n1D519;MATHEMATICAL FRAKTUR CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;\n1D51A;MATHEMATICAL FRAKTUR CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;\n1D51B;MATHEMATICAL FRAKTUR CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;\n1D51C;MATHEMATICAL FRAKTUR CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;\n1D51E;MATHEMATICAL FRAKTUR SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;\n1D51F;MATHEMATICAL FRAKTUR SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;\n1D520;MATHEMATICAL FRAKTUR SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;\n1D521;MATHEMATICAL FRAKTUR SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;\n1D522;MATHEMATICAL FRAKTUR SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;\n1D523;MATHEMATICAL FRAKTUR SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;\n1D524;MATHEMATICAL FRAKTUR SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;\n1D525;MATHEMATICAL FRAKTUR SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;\n1D526;MATHEMATICAL FRAKTUR SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;\n1D527;MATHEMATICAL FRAKTUR SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;\n1D528;MATHEMATICAL FRAKTUR SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;\n1D529;MATHEMATICAL FRAKTUR SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;\n1D52A;MATHEMATICAL FRAKTUR SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;\n1D52B;MATHEMATICAL FRAKTUR SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;\n1D52C;MATHEMATICAL FRAKTUR SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;\n1D52D;MATHEMATICAL FRAKTUR SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;\n1D52E;MATHEMATICAL FRAKTUR SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;\n1D52F;MATHEMATICAL FRAKTUR SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;\n1D530;MATHEMATICAL FRAKTUR SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;\n1D531;MATHEMATICAL FRAKTUR SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;\n1D532;MATHEMATICAL FRAKTUR SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;\n1D533;MATHEMATICAL FRAKTUR SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;\n1D534;MATHEMATICAL FRAKTUR SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;\n1D535;MATHEMATICAL FRAKTUR SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;\n1D536;MATHEMATICAL FRAKTUR SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;\n1D537;MATHEMATICAL FRAKTUR SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;\n1D538;MATHEMATICAL DOUBLE-STRUCK CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;\n1D539;MATHEMATICAL DOUBLE-STRUCK CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;\n1D53B;MATHEMATICAL DOUBLE-STRUCK CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;\n1D53C;MATHEMATICAL DOUBLE-STRUCK CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;\n1D53D;MATHEMATICAL DOUBLE-STRUCK CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;\n1D53E;MATHEMATICAL DOUBLE-STRUCK CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;\n1D540;MATHEMATICAL DOUBLE-STRUCK CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;\n1D541;MATHEMATICAL DOUBLE-STRUCK CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;\n1D542;MATHEMATICAL DOUBLE-STRUCK CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;\n1D543;MATHEMATICAL DOUBLE-STRUCK CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;\n1D544;MATHEMATICAL DOUBLE-STRUCK CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;\n1D546;MATHEMATICAL DOUBLE-STRUCK CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;\n1D54A;MATHEMATICAL DOUBLE-STRUCK CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;\n1D54B;MATHEMATICAL DOUBLE-STRUCK CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;\n1D54C;MATHEMATICAL DOUBLE-STRUCK CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;\n1D54D;MATHEMATICAL DOUBLE-STRUCK CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;\n1D54E;MATHEMATICAL DOUBLE-STRUCK CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;\n1D54F;MATHEMATICAL DOUBLE-STRUCK CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;\n1D550;MATHEMATICAL DOUBLE-STRUCK CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;\n1D552;MATHEMATICAL DOUBLE-STRUCK SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;\n1D553;MATHEMATICAL DOUBLE-STRUCK SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;\n1D554;MATHEMATICAL DOUBLE-STRUCK SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;\n1D555;MATHEMATICAL DOUBLE-STRUCK SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;\n1D556;MATHEMATICAL DOUBLE-STRUCK SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;\n1D557;MATHEMATICAL DOUBLE-STRUCK SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;\n1D558;MATHEMATICAL DOUBLE-STRUCK SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;\n1D559;MATHEMATICAL DOUBLE-STRUCK SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;\n1D55A;MATHEMATICAL DOUBLE-STRUCK SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;\n1D55B;MATHEMATICAL DOUBLE-STRUCK SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;\n1D55C;MATHEMATICAL DOUBLE-STRUCK SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;\n1D55D;MATHEMATICAL DOUBLE-STRUCK SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;\n1D55E;MATHEMATICAL DOUBLE-STRUCK SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;\n1D55F;MATHEMATICAL DOUBLE-STRUCK SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;\n1D560;MATHEMATICAL DOUBLE-STRUCK SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;\n1D561;MATHEMATICAL DOUBLE-STRUCK SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;\n1D562;MATHEMATICAL DOUBLE-STRUCK SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;\n1D563;MATHEMATICAL DOUBLE-STRUCK SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;\n1D564;MATHEMATICAL DOUBLE-STRUCK SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;\n1D565;MATHEMATICAL DOUBLE-STRUCK SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;\n1D566;MATHEMATICAL DOUBLE-STRUCK SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;\n1D567;MATHEMATICAL DOUBLE-STRUCK SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;\n1D568;MATHEMATICAL DOUBLE-STRUCK SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;\n1D569;MATHEMATICAL DOUBLE-STRUCK SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;\n1D56A;MATHEMATICAL DOUBLE-STRUCK SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;\n1D56B;MATHEMATICAL DOUBLE-STRUCK SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;\n1D56C;MATHEMATICAL BOLD FRAKTUR CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;\n1D56D;MATHEMATICAL BOLD FRAKTUR CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;\n1D56E;MATHEMATICAL BOLD FRAKTUR CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;\n1D56F;MATHEMATICAL BOLD FRAKTUR CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;\n1D570;MATHEMATICAL BOLD FRAKTUR CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;\n1D571;MATHEMATICAL BOLD FRAKTUR CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;\n1D572;MATHEMATICAL BOLD FRAKTUR CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;\n1D573;MATHEMATICAL BOLD FRAKTUR CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;\n1D574;MATHEMATICAL BOLD FRAKTUR CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;\n1D575;MATHEMATICAL BOLD FRAKTUR CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;\n1D576;MATHEMATICAL BOLD FRAKTUR CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;\n1D577;MATHEMATICAL BOLD FRAKTUR CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;\n1D578;MATHEMATICAL BOLD FRAKTUR CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;\n1D579;MATHEMATICAL BOLD FRAKTUR CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;\n1D57A;MATHEMATICAL BOLD FRAKTUR CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;\n1D57B;MATHEMATICAL BOLD FRAKTUR CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;\n1D57C;MATHEMATICAL BOLD FRAKTUR CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;\n1D57D;MATHEMATICAL BOLD FRAKTUR CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;\n1D57E;MATHEMATICAL BOLD FRAKTUR CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;\n1D57F;MATHEMATICAL BOLD FRAKTUR CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;\n1D580;MATHEMATICAL BOLD FRAKTUR CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;\n1D581;MATHEMATICAL BOLD FRAKTUR CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;\n1D582;MATHEMATICAL BOLD FRAKTUR CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;\n1D583;MATHEMATICAL BOLD FRAKTUR CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;\n1D584;MATHEMATICAL BOLD FRAKTUR CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;\n1D585;MATHEMATICAL BOLD FRAKTUR CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;\n1D586;MATHEMATICAL BOLD FRAKTUR SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;\n1D587;MATHEMATICAL BOLD FRAKTUR SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;\n1D588;MATHEMATICAL BOLD FRAKTUR SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;\n1D589;MATHEMATICAL BOLD FRAKTUR SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;\n1D58A;MATHEMATICAL BOLD FRAKTUR SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;\n1D58B;MATHEMATICAL BOLD FRAKTUR SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;\n1D58C;MATHEMATICAL BOLD FRAKTUR SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;\n1D58D;MATHEMATICAL BOLD FRAKTUR SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;\n1D58E;MATHEMATICAL BOLD FRAKTUR SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;\n1D58F;MATHEMATICAL BOLD FRAKTUR SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;\n1D590;MATHEMATICAL BOLD FRAKTUR SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;\n1D591;MATHEMATICAL BOLD FRAKTUR SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;\n1D592;MATHEMATICAL BOLD FRAKTUR SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;\n1D593;MATHEMATICAL BOLD FRAKTUR SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;\n1D594;MATHEMATICAL BOLD FRAKTUR SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;\n1D595;MATHEMATICAL BOLD FRAKTUR SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;\n1D596;MATHEMATICAL BOLD FRAKTUR SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;\n1D597;MATHEMATICAL BOLD FRAKTUR SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;\n1D598;MATHEMATICAL BOLD FRAKTUR SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;\n1D599;MATHEMATICAL BOLD FRAKTUR SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;\n1D59A;MATHEMATICAL BOLD FRAKTUR SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;\n1D59B;MATHEMATICAL BOLD FRAKTUR SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;\n1D59C;MATHEMATICAL BOLD FRAKTUR SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;\n1D59D;MATHEMATICAL BOLD FRAKTUR SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;\n1D59E;MATHEMATICAL BOLD FRAKTUR SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;\n1D59F;MATHEMATICAL BOLD FRAKTUR SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;\n1D5A0;MATHEMATICAL SANS-SERIF CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;\n1D5A1;MATHEMATICAL SANS-SERIF CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;\n1D5A2;MATHEMATICAL SANS-SERIF CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;\n1D5A3;MATHEMATICAL SANS-SERIF CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;\n1D5A4;MATHEMATICAL SANS-SERIF CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;\n1D5A5;MATHEMATICAL SANS-SERIF CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;\n1D5A6;MATHEMATICAL SANS-SERIF CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;\n1D5A7;MATHEMATICAL SANS-SERIF CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;\n1D5A8;MATHEMATICAL SANS-SERIF CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;\n1D5A9;MATHEMATICAL SANS-SERIF CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;\n1D5AA;MATHEMATICAL SANS-SERIF CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;\n1D5AB;MATHEMATICAL SANS-SERIF CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;\n1D5AC;MATHEMATICAL SANS-SERIF CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;\n1D5AD;MATHEMATICAL SANS-SERIF CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;\n1D5AE;MATHEMATICAL SANS-SERIF CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;\n1D5AF;MATHEMATICAL SANS-SERIF CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;\n1D5B0;MATHEMATICAL SANS-SERIF CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;\n1D5B1;MATHEMATICAL SANS-SERIF CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;\n1D5B2;MATHEMATICAL SANS-SERIF CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;\n1D5B3;MATHEMATICAL SANS-SERIF CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;\n1D5B4;MATHEMATICAL SANS-SERIF CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;\n1D5B5;MATHEMATICAL SANS-SERIF CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;\n1D5B6;MATHEMATICAL SANS-SERIF CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;\n1D5B7;MATHEMATICAL SANS-SERIF CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;\n1D5B8;MATHEMATICAL SANS-SERIF CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;\n1D5B9;MATHEMATICAL SANS-SERIF CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;\n1D5BA;MATHEMATICAL SANS-SERIF SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;\n1D5BB;MATHEMATICAL SANS-SERIF SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;\n1D5BC;MATHEMATICAL SANS-SERIF SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;\n1D5BD;MATHEMATICAL SANS-SERIF SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;\n1D5BE;MATHEMATICAL SANS-SERIF SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;\n1D5BF;MATHEMATICAL SANS-SERIF SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;\n1D5C0;MATHEMATICAL SANS-SERIF SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;\n1D5C1;MATHEMATICAL SANS-SERIF SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;\n1D5C2;MATHEMATICAL SANS-SERIF SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;\n1D5C3;MATHEMATICAL SANS-SERIF SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;\n1D5C4;MATHEMATICAL SANS-SERIF SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;\n1D5C5;MATHEMATICAL SANS-SERIF SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;\n1D5C6;MATHEMATICAL SANS-SERIF SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;\n1D5C7;MATHEMATICAL SANS-SERIF SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;\n1D5C8;MATHEMATICAL SANS-SERIF SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;\n1D5C9;MATHEMATICAL SANS-SERIF SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;\n1D5CA;MATHEMATICAL SANS-SERIF SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;\n1D5CB;MATHEMATICAL SANS-SERIF SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;\n1D5CC;MATHEMATICAL SANS-SERIF SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;\n1D5CD;MATHEMATICAL SANS-SERIF SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;\n1D5CE;MATHEMATICAL SANS-SERIF SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;\n1D5CF;MATHEMATICAL SANS-SERIF SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;\n1D5D0;MATHEMATICAL SANS-SERIF SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;\n1D5D1;MATHEMATICAL SANS-SERIF SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;\n1D5D2;MATHEMATICAL SANS-SERIF SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;\n1D5D3;MATHEMATICAL SANS-SERIF SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;\n1D5D4;MATHEMATICAL SANS-SERIF BOLD CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;\n1D5D5;MATHEMATICAL SANS-SERIF BOLD CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;\n1D5D6;MATHEMATICAL SANS-SERIF BOLD CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;\n1D5D7;MATHEMATICAL SANS-SERIF BOLD CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;\n1D5D8;MATHEMATICAL SANS-SERIF BOLD CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;\n1D5D9;MATHEMATICAL SANS-SERIF BOLD CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;\n1D5DA;MATHEMATICAL SANS-SERIF BOLD CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;\n1D5DB;MATHEMATICAL SANS-SERIF BOLD CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;\n1D5DC;MATHEMATICAL SANS-SERIF BOLD CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;\n1D5DD;MATHEMATICAL SANS-SERIF BOLD CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;\n1D5DE;MATHEMATICAL SANS-SERIF BOLD CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;\n1D5DF;MATHEMATICAL SANS-SERIF BOLD CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;\n1D5E0;MATHEMATICAL SANS-SERIF BOLD CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;\n1D5E1;MATHEMATICAL SANS-SERIF BOLD CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;\n1D5E2;MATHEMATICAL SANS-SERIF BOLD CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;\n1D5E3;MATHEMATICAL SANS-SERIF BOLD CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;\n1D5E4;MATHEMATICAL SANS-SERIF BOLD CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;\n1D5E5;MATHEMATICAL SANS-SERIF BOLD CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;\n1D5E6;MATHEMATICAL SANS-SERIF BOLD CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;\n1D5E7;MATHEMATICAL SANS-SERIF BOLD CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;\n1D5E8;MATHEMATICAL SANS-SERIF BOLD CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;\n1D5E9;MATHEMATICAL SANS-SERIF BOLD CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;\n1D5EA;MATHEMATICAL SANS-SERIF BOLD CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;\n1D5EB;MATHEMATICAL SANS-SERIF BOLD CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;\n1D5EC;MATHEMATICAL SANS-SERIF BOLD CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;\n1D5ED;MATHEMATICAL SANS-SERIF BOLD CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;\n1D5EE;MATHEMATICAL SANS-SERIF BOLD SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;\n1D5EF;MATHEMATICAL SANS-SERIF BOLD SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;\n1D5F0;MATHEMATICAL SANS-SERIF BOLD SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;\n1D5F1;MATHEMATICAL SANS-SERIF BOLD SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;\n1D5F2;MATHEMATICAL SANS-SERIF BOLD SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;\n1D5F3;MATHEMATICAL SANS-SERIF BOLD SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;\n1D5F4;MATHEMATICAL SANS-SERIF BOLD SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;\n1D5F5;MATHEMATICAL SANS-SERIF BOLD SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;\n1D5F6;MATHEMATICAL SANS-SERIF BOLD SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;\n1D5F7;MATHEMATICAL SANS-SERIF BOLD SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;\n1D5F8;MATHEMATICAL SANS-SERIF BOLD SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;\n1D5F9;MATHEMATICAL SANS-SERIF BOLD SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;\n1D5FA;MATHEMATICAL SANS-SERIF BOLD SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;\n1D5FB;MATHEMATICAL SANS-SERIF BOLD SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;\n1D5FC;MATHEMATICAL SANS-SERIF BOLD SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;\n1D5FD;MATHEMATICAL SANS-SERIF BOLD SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;\n1D5FE;MATHEMATICAL SANS-SERIF BOLD SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;\n1D5FF;MATHEMATICAL SANS-SERIF BOLD SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;\n1D600;MATHEMATICAL SANS-SERIF BOLD SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;\n1D601;MATHEMATICAL SANS-SERIF BOLD SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;\n1D602;MATHEMATICAL SANS-SERIF BOLD SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;\n1D603;MATHEMATICAL SANS-SERIF BOLD SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;\n1D604;MATHEMATICAL SANS-SERIF BOLD SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;\n1D605;MATHEMATICAL SANS-SERIF BOLD SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;\n1D606;MATHEMATICAL SANS-SERIF BOLD SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;\n1D607;MATHEMATICAL SANS-SERIF BOLD SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;\n1D608;MATHEMATICAL SANS-SERIF ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;\n1D609;MATHEMATICAL SANS-SERIF ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;\n1D60A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;\n1D60B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;\n1D60C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;\n1D60D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;\n1D60E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;\n1D60F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;\n1D610;MATHEMATICAL SANS-SERIF ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;\n1D611;MATHEMATICAL SANS-SERIF ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;\n1D612;MATHEMATICAL SANS-SERIF ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;\n1D613;MATHEMATICAL SANS-SERIF ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;\n1D614;MATHEMATICAL SANS-SERIF ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;\n1D615;MATHEMATICAL SANS-SERIF ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;\n1D616;MATHEMATICAL SANS-SERIF ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;\n1D617;MATHEMATICAL SANS-SERIF ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;\n1D618;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;\n1D619;MATHEMATICAL SANS-SERIF ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;\n1D61A;MATHEMATICAL SANS-SERIF ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;\n1D61B;MATHEMATICAL SANS-SERIF ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;\n1D61C;MATHEMATICAL SANS-SERIF ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;\n1D61D;MATHEMATICAL SANS-SERIF ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;\n1D61E;MATHEMATICAL SANS-SERIF ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;\n1D61F;MATHEMATICAL SANS-SERIF ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;\n1D620;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;\n1D621;MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;\n1D622;MATHEMATICAL SANS-SERIF ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;\n1D623;MATHEMATICAL SANS-SERIF ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;\n1D624;MATHEMATICAL SANS-SERIF ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;\n1D625;MATHEMATICAL SANS-SERIF ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;\n1D626;MATHEMATICAL SANS-SERIF ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;\n1D627;MATHEMATICAL SANS-SERIF ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;\n1D628;MATHEMATICAL SANS-SERIF ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;\n1D629;MATHEMATICAL SANS-SERIF ITALIC SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;\n1D62A;MATHEMATICAL SANS-SERIF ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;\n1D62B;MATHEMATICAL SANS-SERIF ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;\n1D62C;MATHEMATICAL SANS-SERIF ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;\n1D62D;MATHEMATICAL SANS-SERIF ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;\n1D62E;MATHEMATICAL SANS-SERIF ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;\n1D62F;MATHEMATICAL SANS-SERIF ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;\n1D630;MATHEMATICAL SANS-SERIF ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;\n1D631;MATHEMATICAL SANS-SERIF ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;\n1D632;MATHEMATICAL SANS-SERIF ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;\n1D633;MATHEMATICAL SANS-SERIF ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;\n1D634;MATHEMATICAL SANS-SERIF ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;\n1D635;MATHEMATICAL SANS-SERIF ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;\n1D636;MATHEMATICAL SANS-SERIF ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;\n1D637;MATHEMATICAL SANS-SERIF ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;\n1D638;MATHEMATICAL SANS-SERIF ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;\n1D639;MATHEMATICAL SANS-SERIF ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;\n1D63A;MATHEMATICAL SANS-SERIF ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;\n1D63B;MATHEMATICAL SANS-SERIF ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;\n1D63C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;\n1D63D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;\n1D63E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;\n1D63F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;\n1D640;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;\n1D641;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;\n1D642;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;\n1D643;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;\n1D644;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;\n1D645;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;\n1D646;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;\n1D647;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;\n1D648;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;\n1D649;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;\n1D64A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;\n1D64B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;\n1D64C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;\n1D64D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;\n1D64E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;\n1D64F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;\n1D650;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;\n1D651;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;\n1D652;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;\n1D653;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;\n1D654;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;\n1D655;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;\n1D656;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;\n1D657;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;\n1D658;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;\n1D659;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;\n1D65A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;\n1D65B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;\n1D65C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;\n1D65D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;\n1D65E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;\n1D65F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;\n1D660;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;\n1D661;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;\n1D662;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;\n1D663;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;\n1D664;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;\n1D665;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;\n1D666;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;\n1D667;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;\n1D668;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;\n1D669;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;\n1D66A;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;\n1D66B;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;\n1D66C;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;\n1D66D;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;\n1D66E;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;\n1D66F;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;\n1D670;MATHEMATICAL MONOSPACE CAPITAL A;Lu;0;L;<font> 0041;;;;N;;;;;\n1D671;MATHEMATICAL MONOSPACE CAPITAL B;Lu;0;L;<font> 0042;;;;N;;;;;\n1D672;MATHEMATICAL MONOSPACE CAPITAL C;Lu;0;L;<font> 0043;;;;N;;;;;\n1D673;MATHEMATICAL MONOSPACE CAPITAL D;Lu;0;L;<font> 0044;;;;N;;;;;\n1D674;MATHEMATICAL MONOSPACE CAPITAL E;Lu;0;L;<font> 0045;;;;N;;;;;\n1D675;MATHEMATICAL MONOSPACE CAPITAL F;Lu;0;L;<font> 0046;;;;N;;;;;\n1D676;MATHEMATICAL MONOSPACE CAPITAL G;Lu;0;L;<font> 0047;;;;N;;;;;\n1D677;MATHEMATICAL MONOSPACE CAPITAL H;Lu;0;L;<font> 0048;;;;N;;;;;\n1D678;MATHEMATICAL MONOSPACE CAPITAL I;Lu;0;L;<font> 0049;;;;N;;;;;\n1D679;MATHEMATICAL MONOSPACE CAPITAL J;Lu;0;L;<font> 004A;;;;N;;;;;\n1D67A;MATHEMATICAL MONOSPACE CAPITAL K;Lu;0;L;<font> 004B;;;;N;;;;;\n1D67B;MATHEMATICAL MONOSPACE CAPITAL L;Lu;0;L;<font> 004C;;;;N;;;;;\n1D67C;MATHEMATICAL MONOSPACE CAPITAL M;Lu;0;L;<font> 004D;;;;N;;;;;\n1D67D;MATHEMATICAL MONOSPACE CAPITAL N;Lu;0;L;<font> 004E;;;;N;;;;;\n1D67E;MATHEMATICAL MONOSPACE CAPITAL O;Lu;0;L;<font> 004F;;;;N;;;;;\n1D67F;MATHEMATICAL MONOSPACE CAPITAL P;Lu;0;L;<font> 0050;;;;N;;;;;\n1D680;MATHEMATICAL MONOSPACE CAPITAL Q;Lu;0;L;<font> 0051;;;;N;;;;;\n1D681;MATHEMATICAL MONOSPACE CAPITAL R;Lu;0;L;<font> 0052;;;;N;;;;;\n1D682;MATHEMATICAL MONOSPACE CAPITAL S;Lu;0;L;<font> 0053;;;;N;;;;;\n1D683;MATHEMATICAL MONOSPACE CAPITAL T;Lu;0;L;<font> 0054;;;;N;;;;;\n1D684;MATHEMATICAL MONOSPACE CAPITAL U;Lu;0;L;<font> 0055;;;;N;;;;;\n1D685;MATHEMATICAL MONOSPACE CAPITAL V;Lu;0;L;<font> 0056;;;;N;;;;;\n1D686;MATHEMATICAL MONOSPACE CAPITAL W;Lu;0;L;<font> 0057;;;;N;;;;;\n1D687;MATHEMATICAL MONOSPACE CAPITAL X;Lu;0;L;<font> 0058;;;;N;;;;;\n1D688;MATHEMATICAL MONOSPACE CAPITAL Y;Lu;0;L;<font> 0059;;;;N;;;;;\n1D689;MATHEMATICAL MONOSPACE CAPITAL Z;Lu;0;L;<font> 005A;;;;N;;;;;\n1D68A;MATHEMATICAL MONOSPACE SMALL A;Ll;0;L;<font> 0061;;;;N;;;;;\n1D68B;MATHEMATICAL MONOSPACE SMALL B;Ll;0;L;<font> 0062;;;;N;;;;;\n1D68C;MATHEMATICAL MONOSPACE SMALL C;Ll;0;L;<font> 0063;;;;N;;;;;\n1D68D;MATHEMATICAL MONOSPACE SMALL D;Ll;0;L;<font> 0064;;;;N;;;;;\n1D68E;MATHEMATICAL MONOSPACE SMALL E;Ll;0;L;<font> 0065;;;;N;;;;;\n1D68F;MATHEMATICAL MONOSPACE SMALL F;Ll;0;L;<font> 0066;;;;N;;;;;\n1D690;MATHEMATICAL MONOSPACE SMALL G;Ll;0;L;<font> 0067;;;;N;;;;;\n1D691;MATHEMATICAL MONOSPACE SMALL H;Ll;0;L;<font> 0068;;;;N;;;;;\n1D692;MATHEMATICAL MONOSPACE SMALL I;Ll;0;L;<font> 0069;;;;N;;;;;\n1D693;MATHEMATICAL MONOSPACE SMALL J;Ll;0;L;<font> 006A;;;;N;;;;;\n1D694;MATHEMATICAL MONOSPACE SMALL K;Ll;0;L;<font> 006B;;;;N;;;;;\n1D695;MATHEMATICAL MONOSPACE SMALL L;Ll;0;L;<font> 006C;;;;N;;;;;\n1D696;MATHEMATICAL MONOSPACE SMALL M;Ll;0;L;<font> 006D;;;;N;;;;;\n1D697;MATHEMATICAL MONOSPACE SMALL N;Ll;0;L;<font> 006E;;;;N;;;;;\n1D698;MATHEMATICAL MONOSPACE SMALL O;Ll;0;L;<font> 006F;;;;N;;;;;\n1D699;MATHEMATICAL MONOSPACE SMALL P;Ll;0;L;<font> 0070;;;;N;;;;;\n1D69A;MATHEMATICAL MONOSPACE SMALL Q;Ll;0;L;<font> 0071;;;;N;;;;;\n1D69B;MATHEMATICAL MONOSPACE SMALL R;Ll;0;L;<font> 0072;;;;N;;;;;\n1D69C;MATHEMATICAL MONOSPACE SMALL S;Ll;0;L;<font> 0073;;;;N;;;;;\n1D69D;MATHEMATICAL MONOSPACE SMALL T;Ll;0;L;<font> 0074;;;;N;;;;;\n1D69E;MATHEMATICAL MONOSPACE SMALL U;Ll;0;L;<font> 0075;;;;N;;;;;\n1D69F;MATHEMATICAL MONOSPACE SMALL V;Ll;0;L;<font> 0076;;;;N;;;;;\n1D6A0;MATHEMATICAL MONOSPACE SMALL W;Ll;0;L;<font> 0077;;;;N;;;;;\n1D6A1;MATHEMATICAL MONOSPACE SMALL X;Ll;0;L;<font> 0078;;;;N;;;;;\n1D6A2;MATHEMATICAL MONOSPACE SMALL Y;Ll;0;L;<font> 0079;;;;N;;;;;\n1D6A3;MATHEMATICAL MONOSPACE SMALL Z;Ll;0;L;<font> 007A;;;;N;;;;;\n1D6A4;MATHEMATICAL ITALIC SMALL DOTLESS I;Ll;0;L;<font> 0131;;;;N;;;;;\n1D6A5;MATHEMATICAL ITALIC SMALL DOTLESS J;Ll;0;L;<font> 0237;;;;N;;;;;\n1D6A8;MATHEMATICAL BOLD CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;\n1D6A9;MATHEMATICAL BOLD CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;\n1D6AA;MATHEMATICAL BOLD CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;\n1D6AB;MATHEMATICAL BOLD CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;\n1D6AC;MATHEMATICAL BOLD CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;\n1D6AD;MATHEMATICAL BOLD CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;\n1D6AE;MATHEMATICAL BOLD CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;\n1D6AF;MATHEMATICAL BOLD CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;\n1D6B0;MATHEMATICAL BOLD CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;\n1D6B1;MATHEMATICAL BOLD CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;\n1D6B2;MATHEMATICAL BOLD CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;\n1D6B3;MATHEMATICAL BOLD CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;\n1D6B4;MATHEMATICAL BOLD CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;\n1D6B5;MATHEMATICAL BOLD CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;\n1D6B6;MATHEMATICAL BOLD CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;\n1D6B7;MATHEMATICAL BOLD CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;\n1D6B8;MATHEMATICAL BOLD CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;\n1D6B9;MATHEMATICAL BOLD CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;\n1D6BA;MATHEMATICAL BOLD CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;\n1D6BB;MATHEMATICAL BOLD CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;\n1D6BC;MATHEMATICAL BOLD CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;\n1D6BD;MATHEMATICAL BOLD CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;\n1D6BE;MATHEMATICAL BOLD CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;\n1D6BF;MATHEMATICAL BOLD CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;\n1D6C0;MATHEMATICAL BOLD CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;\n1D6C1;MATHEMATICAL BOLD NABLA;Sm;0;L;<font> 2207;;;;N;;;;;\n1D6C2;MATHEMATICAL BOLD SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;\n1D6C3;MATHEMATICAL BOLD SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;\n1D6C4;MATHEMATICAL BOLD SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;\n1D6C5;MATHEMATICAL BOLD SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;\n1D6C6;MATHEMATICAL BOLD SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;\n1D6C7;MATHEMATICAL BOLD SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;\n1D6C8;MATHEMATICAL BOLD SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;\n1D6C9;MATHEMATICAL BOLD SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;\n1D6CA;MATHEMATICAL BOLD SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;\n1D6CB;MATHEMATICAL BOLD SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;\n1D6CC;MATHEMATICAL BOLD SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;\n1D6CD;MATHEMATICAL BOLD SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;\n1D6CE;MATHEMATICAL BOLD SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;\n1D6CF;MATHEMATICAL BOLD SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;\n1D6D0;MATHEMATICAL BOLD SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;\n1D6D1;MATHEMATICAL BOLD SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;\n1D6D2;MATHEMATICAL BOLD SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;\n1D6D3;MATHEMATICAL BOLD SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;\n1D6D4;MATHEMATICAL BOLD SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;\n1D6D5;MATHEMATICAL BOLD SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;\n1D6D6;MATHEMATICAL BOLD SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;\n1D6D7;MATHEMATICAL BOLD SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;\n1D6D8;MATHEMATICAL BOLD SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;\n1D6D9;MATHEMATICAL BOLD SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;\n1D6DA;MATHEMATICAL BOLD SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;\n1D6DB;MATHEMATICAL BOLD PARTIAL DIFFERENTIAL;Sm;0;ON;<font> 2202;;;;Y;;;;;\n1D6DC;MATHEMATICAL BOLD EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;\n1D6DD;MATHEMATICAL BOLD THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;\n1D6DE;MATHEMATICAL BOLD KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;\n1D6DF;MATHEMATICAL BOLD PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;\n1D6E0;MATHEMATICAL BOLD RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;\n1D6E1;MATHEMATICAL BOLD PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;\n1D6E2;MATHEMATICAL ITALIC CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;\n1D6E3;MATHEMATICAL ITALIC CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;\n1D6E4;MATHEMATICAL ITALIC CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;\n1D6E5;MATHEMATICAL ITALIC CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;\n1D6E6;MATHEMATICAL ITALIC CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;\n1D6E7;MATHEMATICAL ITALIC CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;\n1D6E8;MATHEMATICAL ITALIC CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;\n1D6E9;MATHEMATICAL ITALIC CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;\n1D6EA;MATHEMATICAL ITALIC CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;\n1D6EB;MATHEMATICAL ITALIC CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;\n1D6EC;MATHEMATICAL ITALIC CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;\n1D6ED;MATHEMATICAL ITALIC CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;\n1D6EE;MATHEMATICAL ITALIC CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;\n1D6EF;MATHEMATICAL ITALIC CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;\n1D6F0;MATHEMATICAL ITALIC CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;\n1D6F1;MATHEMATICAL ITALIC CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;\n1D6F2;MATHEMATICAL ITALIC CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;\n1D6F3;MATHEMATICAL ITALIC CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;\n1D6F4;MATHEMATICAL ITALIC CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;\n1D6F5;MATHEMATICAL ITALIC CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;\n1D6F6;MATHEMATICAL ITALIC CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;\n1D6F7;MATHEMATICAL ITALIC CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;\n1D6F8;MATHEMATICAL ITALIC CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;\n1D6F9;MATHEMATICAL ITALIC CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;\n1D6FA;MATHEMATICAL ITALIC CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;\n1D6FB;MATHEMATICAL ITALIC NABLA;Sm;0;L;<font> 2207;;;;N;;;;;\n1D6FC;MATHEMATICAL ITALIC SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;\n1D6FD;MATHEMATICAL ITALIC SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;\n1D6FE;MATHEMATICAL ITALIC SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;\n1D6FF;MATHEMATICAL ITALIC SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;\n1D700;MATHEMATICAL ITALIC SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;\n1D701;MATHEMATICAL ITALIC SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;\n1D702;MATHEMATICAL ITALIC SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;\n1D703;MATHEMATICAL ITALIC SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;\n1D704;MATHEMATICAL ITALIC SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;\n1D705;MATHEMATICAL ITALIC SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;\n1D706;MATHEMATICAL ITALIC SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;\n1D707;MATHEMATICAL ITALIC SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;\n1D708;MATHEMATICAL ITALIC SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;\n1D709;MATHEMATICAL ITALIC SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;\n1D70A;MATHEMATICAL ITALIC SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;\n1D70B;MATHEMATICAL ITALIC SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;\n1D70C;MATHEMATICAL ITALIC SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;\n1D70D;MATHEMATICAL ITALIC SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;\n1D70E;MATHEMATICAL ITALIC SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;\n1D70F;MATHEMATICAL ITALIC SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;\n1D710;MATHEMATICAL ITALIC SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;\n1D711;MATHEMATICAL ITALIC SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;\n1D712;MATHEMATICAL ITALIC SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;\n1D713;MATHEMATICAL ITALIC SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;\n1D714;MATHEMATICAL ITALIC SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;\n1D715;MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON;<font> 2202;;;;Y;;;;;\n1D716;MATHEMATICAL ITALIC EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;\n1D717;MATHEMATICAL ITALIC THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;\n1D718;MATHEMATICAL ITALIC KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;\n1D719;MATHEMATICAL ITALIC PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;\n1D71A;MATHEMATICAL ITALIC RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;\n1D71B;MATHEMATICAL ITALIC PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;\n1D71C;MATHEMATICAL BOLD ITALIC CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;\n1D71D;MATHEMATICAL BOLD ITALIC CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;\n1D71E;MATHEMATICAL BOLD ITALIC CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;\n1D71F;MATHEMATICAL BOLD ITALIC CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;\n1D720;MATHEMATICAL BOLD ITALIC CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;\n1D721;MATHEMATICAL BOLD ITALIC CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;\n1D722;MATHEMATICAL BOLD ITALIC CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;\n1D723;MATHEMATICAL BOLD ITALIC CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;\n1D724;MATHEMATICAL BOLD ITALIC CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;\n1D725;MATHEMATICAL BOLD ITALIC CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;\n1D726;MATHEMATICAL BOLD ITALIC CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;\n1D727;MATHEMATICAL BOLD ITALIC CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;\n1D728;MATHEMATICAL BOLD ITALIC CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;\n1D729;MATHEMATICAL BOLD ITALIC CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;\n1D72A;MATHEMATICAL BOLD ITALIC CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;\n1D72B;MATHEMATICAL BOLD ITALIC CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;\n1D72C;MATHEMATICAL BOLD ITALIC CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;\n1D72D;MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;\n1D72E;MATHEMATICAL BOLD ITALIC CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;\n1D72F;MATHEMATICAL BOLD ITALIC CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;\n1D730;MATHEMATICAL BOLD ITALIC CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;\n1D731;MATHEMATICAL BOLD ITALIC CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;\n1D732;MATHEMATICAL BOLD ITALIC CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;\n1D733;MATHEMATICAL BOLD ITALIC CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;\n1D734;MATHEMATICAL BOLD ITALIC CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;\n1D735;MATHEMATICAL BOLD ITALIC NABLA;Sm;0;L;<font> 2207;;;;N;;;;;\n1D736;MATHEMATICAL BOLD ITALIC SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;\n1D737;MATHEMATICAL BOLD ITALIC SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;\n1D738;MATHEMATICAL BOLD ITALIC SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;\n1D739;MATHEMATICAL BOLD ITALIC SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;\n1D73A;MATHEMATICAL BOLD ITALIC SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;\n1D73B;MATHEMATICAL BOLD ITALIC SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;\n1D73C;MATHEMATICAL BOLD ITALIC SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;\n1D73D;MATHEMATICAL BOLD ITALIC SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;\n1D73E;MATHEMATICAL BOLD ITALIC SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;\n1D73F;MATHEMATICAL BOLD ITALIC SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;\n1D740;MATHEMATICAL BOLD ITALIC SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;\n1D741;MATHEMATICAL BOLD ITALIC SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;\n1D742;MATHEMATICAL BOLD ITALIC SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;\n1D743;MATHEMATICAL BOLD ITALIC SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;\n1D744;MATHEMATICAL BOLD ITALIC SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;\n1D745;MATHEMATICAL BOLD ITALIC SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;\n1D746;MATHEMATICAL BOLD ITALIC SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;\n1D747;MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;\n1D748;MATHEMATICAL BOLD ITALIC SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;\n1D749;MATHEMATICAL BOLD ITALIC SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;\n1D74A;MATHEMATICAL BOLD ITALIC SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;\n1D74B;MATHEMATICAL BOLD ITALIC SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;\n1D74C;MATHEMATICAL BOLD ITALIC SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;\n1D74D;MATHEMATICAL BOLD ITALIC SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;\n1D74E;MATHEMATICAL BOLD ITALIC SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;\n1D74F;MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON;<font> 2202;;;;Y;;;;;\n1D750;MATHEMATICAL BOLD ITALIC EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;\n1D751;MATHEMATICAL BOLD ITALIC THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;\n1D752;MATHEMATICAL BOLD ITALIC KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;\n1D753;MATHEMATICAL BOLD ITALIC PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;\n1D754;MATHEMATICAL BOLD ITALIC RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;\n1D755;MATHEMATICAL BOLD ITALIC PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;\n1D756;MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;\n1D757;MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;\n1D758;MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;\n1D759;MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;\n1D75A;MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;\n1D75B;MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;\n1D75C;MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;\n1D75D;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;\n1D75E;MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;\n1D75F;MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;\n1D760;MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;\n1D761;MATHEMATICAL SANS-SERIF BOLD CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;\n1D762;MATHEMATICAL SANS-SERIF BOLD CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;\n1D763;MATHEMATICAL SANS-SERIF BOLD CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;\n1D764;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;\n1D765;MATHEMATICAL SANS-SERIF BOLD CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;\n1D766;MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;\n1D767;MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;\n1D768;MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;\n1D769;MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;\n1D76A;MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;\n1D76B;MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;\n1D76C;MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;\n1D76D;MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;\n1D76E;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;\n1D76F;MATHEMATICAL SANS-SERIF BOLD NABLA;Sm;0;L;<font> 2207;;;;N;;;;;\n1D770;MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;\n1D771;MATHEMATICAL SANS-SERIF BOLD SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;\n1D772;MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;\n1D773;MATHEMATICAL SANS-SERIF BOLD SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;\n1D774;MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;\n1D775;MATHEMATICAL SANS-SERIF BOLD SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;\n1D776;MATHEMATICAL SANS-SERIF BOLD SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;\n1D777;MATHEMATICAL SANS-SERIF BOLD SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;\n1D778;MATHEMATICAL SANS-SERIF BOLD SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;\n1D779;MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;\n1D77A;MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;\n1D77B;MATHEMATICAL SANS-SERIF BOLD SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;\n1D77C;MATHEMATICAL SANS-SERIF BOLD SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;\n1D77D;MATHEMATICAL SANS-SERIF BOLD SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;\n1D77E;MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;\n1D77F;MATHEMATICAL SANS-SERIF BOLD SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;\n1D780;MATHEMATICAL SANS-SERIF BOLD SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;\n1D781;MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;\n1D782;MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;\n1D783;MATHEMATICAL SANS-SERIF BOLD SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;\n1D784;MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;\n1D785;MATHEMATICAL SANS-SERIF BOLD SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;\n1D786;MATHEMATICAL SANS-SERIF BOLD SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;\n1D787;MATHEMATICAL SANS-SERIF BOLD SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;\n1D788;MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;\n1D789;MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL;Sm;0;ON;<font> 2202;;;;Y;;;;;\n1D78A;MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;\n1D78B;MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;\n1D78C;MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;\n1D78D;MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;\n1D78E;MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;\n1D78F;MATHEMATICAL SANS-SERIF BOLD PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;\n1D790;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA;Lu;0;L;<font> 0391;;;;N;;;;;\n1D791;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA;Lu;0;L;<font> 0392;;;;N;;;;;\n1D792;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA;Lu;0;L;<font> 0393;;;;N;;;;;\n1D793;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA;Lu;0;L;<font> 0394;;;;N;;;;;\n1D794;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON;Lu;0;L;<font> 0395;;;;N;;;;;\n1D795;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA;Lu;0;L;<font> 0396;;;;N;;;;;\n1D796;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA;Lu;0;L;<font> 0397;;;;N;;;;;\n1D797;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA;Lu;0;L;<font> 0398;;;;N;;;;;\n1D798;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA;Lu;0;L;<font> 0399;;;;N;;;;;\n1D799;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA;Lu;0;L;<font> 039A;;;;N;;;;;\n1D79A;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA;Lu;0;L;<font> 039B;;;;N;;;;;\n1D79B;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU;Lu;0;L;<font> 039C;;;;N;;;;;\n1D79C;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU;Lu;0;L;<font> 039D;;;;N;;;;;\n1D79D;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI;Lu;0;L;<font> 039E;;;;N;;;;;\n1D79E;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON;Lu;0;L;<font> 039F;;;;N;;;;;\n1D79F;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI;Lu;0;L;<font> 03A0;;;;N;;;;;\n1D7A0;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO;Lu;0;L;<font> 03A1;;;;N;;;;;\n1D7A1;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL;Lu;0;L;<font> 03F4;;;;N;;;;;\n1D7A2;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA;Lu;0;L;<font> 03A3;;;;N;;;;;\n1D7A3;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU;Lu;0;L;<font> 03A4;;;;N;;;;;\n1D7A4;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON;Lu;0;L;<font> 03A5;;;;N;;;;;\n1D7A5;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI;Lu;0;L;<font> 03A6;;;;N;;;;;\n1D7A6;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;;\n1D7A7;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;;\n1D7A8;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;;\n1D7A9;MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA;Sm;0;L;<font> 2207;;;;N;;;;;\n1D7AA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;;\n1D7AB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;;\n1D7AC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;;\n1D7AD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA;Ll;0;L;<font> 03B4;;;;N;;;;;\n1D7AE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON;Ll;0;L;<font> 03B5;;;;N;;;;;\n1D7AF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA;Ll;0;L;<font> 03B6;;;;N;;;;;\n1D7B0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA;Ll;0;L;<font> 03B7;;;;N;;;;;\n1D7B1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA;Ll;0;L;<font> 03B8;;;;N;;;;;\n1D7B2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA;Ll;0;L;<font> 03B9;;;;N;;;;;\n1D7B3;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA;Ll;0;L;<font> 03BA;;;;N;;;;;\n1D7B4;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA;Ll;0;L;<font> 03BB;;;;N;;;;;\n1D7B5;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU;Ll;0;L;<font> 03BC;;;;N;;;;;\n1D7B6;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU;Ll;0;L;<font> 03BD;;;;N;;;;;\n1D7B7;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI;Ll;0;L;<font> 03BE;;;;N;;;;;\n1D7B8;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON;Ll;0;L;<font> 03BF;;;;N;;;;;\n1D7B9;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI;Ll;0;L;<font> 03C0;;;;N;;;;;\n1D7BA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO;Ll;0;L;<font> 03C1;;;;N;;;;;\n1D7BB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA;Ll;0;L;<font> 03C2;;;;N;;;;;\n1D7BC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA;Ll;0;L;<font> 03C3;;;;N;;;;;\n1D7BD;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU;Ll;0;L;<font> 03C4;;;;N;;;;;\n1D7BE;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON;Ll;0;L;<font> 03C5;;;;N;;;;;\n1D7BF;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI;Ll;0;L;<font> 03C6;;;;N;;;;;\n1D7C0;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI;Ll;0;L;<font> 03C7;;;;N;;;;;\n1D7C1;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI;Ll;0;L;<font> 03C8;;;;N;;;;;\n1D7C2;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA;Ll;0;L;<font> 03C9;;;;N;;;;;\n1D7C3;MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL;Sm;0;ON;<font> 2202;;;;Y;;;;;\n1D7C4;MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL;Ll;0;L;<font> 03F5;;;;N;;;;;\n1D7C5;MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL;Ll;0;L;<font> 03D1;;;;N;;;;;\n1D7C6;MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL;Ll;0;L;<font> 03F0;;;;N;;;;;\n1D7C7;MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL;Ll;0;L;<font> 03D5;;;;N;;;;;\n1D7C8;MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL;Ll;0;L;<font> 03F1;;;;N;;;;;\n1D7C9;MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL;Ll;0;L;<font> 03D6;;;;N;;;;;\n1D7CA;MATHEMATICAL BOLD CAPITAL DIGAMMA;Lu;0;L;<font> 03DC;;;;N;;;;;\n1D7CB;MATHEMATICAL BOLD SMALL DIGAMMA;Ll;0;L;<font> 03DD;;;;N;;;;;\n1D7CE;MATHEMATICAL BOLD DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;\n1D7CF;MATHEMATICAL BOLD DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;\n1D7D0;MATHEMATICAL BOLD DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;\n1D7D1;MATHEMATICAL BOLD DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;\n1D7D2;MATHEMATICAL BOLD DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;\n1D7D3;MATHEMATICAL BOLD DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;\n1D7D4;MATHEMATICAL BOLD DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;\n1D7D5;MATHEMATICAL BOLD DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;\n1D7D6;MATHEMATICAL BOLD DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;\n1D7D7;MATHEMATICAL BOLD DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;\n1D7D8;MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;\n1D7D9;MATHEMATICAL DOUBLE-STRUCK DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;\n1D7DA;MATHEMATICAL DOUBLE-STRUCK DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;\n1D7DB;MATHEMATICAL DOUBLE-STRUCK DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;\n1D7DC;MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;\n1D7DD;MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;\n1D7DE;MATHEMATICAL DOUBLE-STRUCK DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;\n1D7DF;MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;\n1D7E0;MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;\n1D7E1;MATHEMATICAL DOUBLE-STRUCK DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;\n1D7E2;MATHEMATICAL SANS-SERIF DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;\n1D7E3;MATHEMATICAL SANS-SERIF DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;\n1D7E4;MATHEMATICAL SANS-SERIF DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;\n1D7E5;MATHEMATICAL SANS-SERIF DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;\n1D7E6;MATHEMATICAL SANS-SERIF DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;\n1D7E7;MATHEMATICAL SANS-SERIF DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;\n1D7E8;MATHEMATICAL SANS-SERIF DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;\n1D7E9;MATHEMATICAL SANS-SERIF DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;\n1D7EA;MATHEMATICAL SANS-SERIF DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;\n1D7EB;MATHEMATICAL SANS-SERIF DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;\n1D7EC;MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;\n1D7ED;MATHEMATICAL SANS-SERIF BOLD DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;\n1D7EE;MATHEMATICAL SANS-SERIF BOLD DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;\n1D7EF;MATHEMATICAL SANS-SERIF BOLD DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;\n1D7F0;MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;\n1D7F1;MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;\n1D7F2;MATHEMATICAL SANS-SERIF BOLD DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;\n1D7F3;MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;\n1D7F4;MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;\n1D7F5;MATHEMATICAL SANS-SERIF BOLD DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;\n1D7F6;MATHEMATICAL MONOSPACE DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;;\n1D7F7;MATHEMATICAL MONOSPACE DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;;\n1D7F8;MATHEMATICAL MONOSPACE DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;;\n1D7F9;MATHEMATICAL MONOSPACE DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;;\n1D7FA;MATHEMATICAL MONOSPACE DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;;\n1D7FB;MATHEMATICAL MONOSPACE DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;;\n1D7FC;MATHEMATICAL MONOSPACE DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;;\n1D7FD;MATHEMATICAL MONOSPACE DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;;\n1D7FE;MATHEMATICAL MONOSPACE DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;;\n1D7FF;MATHEMATICAL MONOSPACE DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;;\n1D800;SIGNWRITING HAND-FIST INDEX;So;0;L;;;;;N;;;;;\n1D801;SIGNWRITING HAND-CIRCLE INDEX;So;0;L;;;;;N;;;;;\n1D802;SIGNWRITING HAND-CUP INDEX;So;0;L;;;;;N;;;;;\n1D803;SIGNWRITING HAND-OVAL INDEX;So;0;L;;;;;N;;;;;\n1D804;SIGNWRITING HAND-HINGE INDEX;So;0;L;;;;;N;;;;;\n1D805;SIGNWRITING HAND-ANGLE INDEX;So;0;L;;;;;N;;;;;\n1D806;SIGNWRITING HAND-FIST INDEX BENT;So;0;L;;;;;N;;;;;\n1D807;SIGNWRITING HAND-CIRCLE INDEX BENT;So;0;L;;;;;N;;;;;\n1D808;SIGNWRITING HAND-FIST THUMB UNDER INDEX BENT;So;0;L;;;;;N;;;;;\n1D809;SIGNWRITING HAND-FIST INDEX RAISED KNUCKLE;So;0;L;;;;;N;;;;;\n1D80A;SIGNWRITING HAND-FIST INDEX CUPPED;So;0;L;;;;;N;;;;;\n1D80B;SIGNWRITING HAND-FIST INDEX HINGED;So;0;L;;;;;N;;;;;\n1D80C;SIGNWRITING HAND-FIST INDEX HINGED LOW;So;0;L;;;;;N;;;;;\n1D80D;SIGNWRITING HAND-CIRCLE INDEX HINGE;So;0;L;;;;;N;;;;;\n1D80E;SIGNWRITING HAND-FIST INDEX MIDDLE;So;0;L;;;;;N;;;;;\n1D80F;SIGNWRITING HAND-CIRCLE INDEX MIDDLE;So;0;L;;;;;N;;;;;\n1D810;SIGNWRITING HAND-FIST INDEX MIDDLE BENT;So;0;L;;;;;N;;;;;\n1D811;SIGNWRITING HAND-FIST INDEX MIDDLE RAISED KNUCKLES;So;0;L;;;;;N;;;;;\n1D812;SIGNWRITING HAND-FIST INDEX MIDDLE HINGED;So;0;L;;;;;N;;;;;\n1D813;SIGNWRITING HAND-FIST INDEX UP MIDDLE HINGED;So;0;L;;;;;N;;;;;\n1D814;SIGNWRITING HAND-FIST INDEX HINGED MIDDLE UP;So;0;L;;;;;N;;;;;\n1D815;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED;So;0;L;;;;;N;;;;;\n1D816;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED INDEX BENT;So;0;L;;;;;N;;;;;\n1D817;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED MIDDLE BENT;So;0;L;;;;;N;;;;;\n1D818;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED CUPPED;So;0;L;;;;;N;;;;;\n1D819;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED HINGED;So;0;L;;;;;N;;;;;\n1D81A;SIGNWRITING HAND-FIST INDEX MIDDLE CROSSED;So;0;L;;;;;N;;;;;\n1D81B;SIGNWRITING HAND-CIRCLE INDEX MIDDLE CROSSED;So;0;L;;;;;N;;;;;\n1D81C;SIGNWRITING HAND-FIST MIDDLE BENT OVER INDEX;So;0;L;;;;;N;;;;;\n1D81D;SIGNWRITING HAND-FIST INDEX BENT OVER MIDDLE;So;0;L;;;;;N;;;;;\n1D81E;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB;So;0;L;;;;;N;;;;;\n1D81F;SIGNWRITING HAND-CIRCLE INDEX MIDDLE THUMB;So;0;L;;;;;N;;;;;\n1D820;SIGNWRITING HAND-FIST INDEX MIDDLE STRAIGHT THUMB BENT;So;0;L;;;;;N;;;;;\n1D821;SIGNWRITING HAND-FIST INDEX MIDDLE BENT THUMB STRAIGHT;So;0;L;;;;;N;;;;;\n1D822;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB BENT;So;0;L;;;;;N;;;;;\n1D823;SIGNWRITING HAND-FIST INDEX MIDDLE HINGED SPREAD THUMB SIDE;So;0;L;;;;;N;;;;;\n1D824;SIGNWRITING HAND-FIST INDEX UP MIDDLE HINGED THUMB SIDE;So;0;L;;;;;N;;;;;\n1D825;SIGNWRITING HAND-FIST INDEX UP MIDDLE HINGED THUMB CONJOINED;So;0;L;;;;;N;;;;;\n1D826;SIGNWRITING HAND-FIST INDEX HINGED MIDDLE UP THUMB SIDE;So;0;L;;;;;N;;;;;\n1D827;SIGNWRITING HAND-FIST INDEX MIDDLE UP SPREAD THUMB FORWARD;So;0;L;;;;;N;;;;;\n1D828;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB CUPPED;So;0;L;;;;;N;;;;;\n1D829;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB CIRCLED;So;0;L;;;;;N;;;;;\n1D82A;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB HOOKED;So;0;L;;;;;N;;;;;\n1D82B;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB HINGED;So;0;L;;;;;N;;;;;\n1D82C;SIGNWRITING HAND-FIST THUMB BETWEEN INDEX MIDDLE STRAIGHT;So;0;L;;;;;N;;;;;\n1D82D;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB SIDE;So;0;L;;;;;N;;;;;\n1D82E;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB SIDE CONJOINED;So;0;L;;;;;N;;;;;\n1D82F;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB SIDE BENT;So;0;L;;;;;N;;;;;\n1D830;SIGNWRITING HAND-FIST MIDDLE THUMB HOOKED INDEX UP;So;0;L;;;;;N;;;;;\n1D831;SIGNWRITING HAND-FIST INDEX THUMB HOOKED MIDDLE UP;So;0;L;;;;;N;;;;;\n1D832;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED HINGED THUMB SIDE;So;0;L;;;;;N;;;;;\n1D833;SIGNWRITING HAND-FIST INDEX MIDDLE CROSSED THUMB SIDE;So;0;L;;;;;N;;;;;\n1D834;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED THUMB FORWARD;So;0;L;;;;;N;;;;;\n1D835;SIGNWRITING HAND-FIST INDEX MIDDLE CONJOINED CUPPED THUMB FORWARD;So;0;L;;;;;N;;;;;\n1D836;SIGNWRITING HAND-FIST MIDDLE THUMB CUPPED INDEX UP;So;0;L;;;;;N;;;;;\n1D837;SIGNWRITING HAND-FIST INDEX THUMB CUPPED MIDDLE UP;So;0;L;;;;;N;;;;;\n1D838;SIGNWRITING HAND-FIST MIDDLE THUMB CIRCLED INDEX UP;So;0;L;;;;;N;;;;;\n1D839;SIGNWRITING HAND-FIST MIDDLE THUMB CIRCLED INDEX HINGED;So;0;L;;;;;N;;;;;\n1D83A;SIGNWRITING HAND-FIST INDEX THUMB ANGLED OUT MIDDLE UP;So;0;L;;;;;N;;;;;\n1D83B;SIGNWRITING HAND-FIST INDEX THUMB ANGLED IN MIDDLE UP;So;0;L;;;;;N;;;;;\n1D83C;SIGNWRITING HAND-FIST INDEX THUMB CIRCLED MIDDLE UP;So;0;L;;;;;N;;;;;\n1D83D;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB CONJOINED HINGED;So;0;L;;;;;N;;;;;\n1D83E;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB ANGLED OUT;So;0;L;;;;;N;;;;;\n1D83F;SIGNWRITING HAND-FIST INDEX MIDDLE THUMB ANGLED;So;0;L;;;;;N;;;;;\n1D840;SIGNWRITING HAND-FIST MIDDLE THUMB ANGLED OUT INDEX UP;So;0;L;;;;;N;;;;;\n1D841;SIGNWRITING HAND-FIST MIDDLE THUMB ANGLED OUT INDEX CROSSED;So;0;L;;;;;N;;;;;\n1D842;SIGNWRITING HAND-FIST MIDDLE THUMB ANGLED INDEX UP;So;0;L;;;;;N;;;;;\n1D843;SIGNWRITING HAND-FIST INDEX THUMB HOOKED MIDDLE HINGED;So;0;L;;;;;N;;;;;\n1D844;SIGNWRITING HAND-FLAT FOUR FINGERS;So;0;L;;;;;N;;;;;\n1D845;SIGNWRITING HAND-FLAT FOUR FINGERS BENT;So;0;L;;;;;N;;;;;\n1D846;SIGNWRITING HAND-FLAT FOUR FINGERS HINGED;So;0;L;;;;;N;;;;;\n1D847;SIGNWRITING HAND-FLAT FOUR FINGERS CONJOINED;So;0;L;;;;;N;;;;;\n1D848;SIGNWRITING HAND-FLAT FOUR FINGERS CONJOINED SPLIT;So;0;L;;;;;N;;;;;\n1D849;SIGNWRITING HAND-CLAW FOUR FINGERS CONJOINED;So;0;L;;;;;N;;;;;\n1D84A;SIGNWRITING HAND-FIST FOUR FINGERS CONJOINED BENT;So;0;L;;;;;N;;;;;\n1D84B;SIGNWRITING HAND-HINGE FOUR FINGERS CONJOINED;So;0;L;;;;;N;;;;;\n1D84C;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;;\n1D84D;SIGNWRITING HAND-FLAT HEEL FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;;\n1D84E;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD FOUR BENT;So;0;L;;;;;N;;;;;\n1D84F;SIGNWRITING HAND-FLAT HEEL FIVE FINGERS SPREAD FOUR BENT;So;0;L;;;;;N;;;;;\n1D850;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD BENT;So;0;L;;;;;N;;;;;\n1D851;SIGNWRITING HAND-FLAT HEEL FIVE FINGERS SPREAD BENT;So;0;L;;;;;N;;;;;\n1D852;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD THUMB FORWARD;So;0;L;;;;;N;;;;;\n1D853;SIGNWRITING HAND-CUP FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;;\n1D854;SIGNWRITING HAND-CUP FIVE FINGERS SPREAD OPEN;So;0;L;;;;;N;;;;;\n1D855;SIGNWRITING HAND-HINGE FIVE FINGERS SPREAD OPEN;So;0;L;;;;;N;;;;;\n1D856;SIGNWRITING HAND-OVAL FIVE FINGERS SPREAD;So;0;L;;;;;N;;;;;\n1D857;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD HINGED;So;0;L;;;;;N;;;;;\n1D858;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD HINGED THUMB SIDE;So;0;L;;;;;N;;;;;\n1D859;SIGNWRITING HAND-FLAT FIVE FINGERS SPREAD HINGED NO THUMB;So;0;L;;;;;N;;;;;\n1D85A;SIGNWRITING HAND-FLAT;So;0;L;;;;;N;;;;;\n1D85B;SIGNWRITING HAND-FLAT BETWEEN PALM FACINGS;So;0;L;;;;;N;;;;;\n1D85C;SIGNWRITING HAND-FLAT HEEL;So;0;L;;;;;N;;;;;\n1D85D;SIGNWRITING HAND-FLAT THUMB SIDE;So;0;L;;;;;N;;;;;\n1D85E;SIGNWRITING HAND-FLAT HEEL THUMB SIDE;So;0;L;;;;;N;;;;;\n1D85F;SIGNWRITING HAND-FLAT THUMB BENT;So;0;L;;;;;N;;;;;\n1D860;SIGNWRITING HAND-FLAT THUMB FORWARD;So;0;L;;;;;N;;;;;\n1D861;SIGNWRITING HAND-FLAT SPLIT INDEX THUMB SIDE;So;0;L;;;;;N;;;;;\n1D862;SIGNWRITING HAND-FLAT SPLIT CENTRE;So;0;L;;;;;N;;;;;\n1D863;SIGNWRITING HAND-FLAT SPLIT CENTRE THUMB SIDE;So;0;L;;;;;N;;;;;\n1D864;SIGNWRITING HAND-FLAT SPLIT CENTRE THUMB SIDE BENT;So;0;L;;;;;N;;;;;\n1D865;SIGNWRITING HAND-FLAT SPLIT LITTLE;So;0;L;;;;;N;;;;;\n1D866;SIGNWRITING HAND-CLAW;So;0;L;;;;;N;;;;;\n1D867;SIGNWRITING HAND-CLAW THUMB SIDE;So;0;L;;;;;N;;;;;\n1D868;SIGNWRITING HAND-CLAW NO THUMB;So;0;L;;;;;N;;;;;\n1D869;SIGNWRITING HAND-CLAW THUMB FORWARD;So;0;L;;;;;N;;;;;\n1D86A;SIGNWRITING HAND-HOOK CURLICUE;So;0;L;;;;;N;;;;;\n1D86B;SIGNWRITING HAND-HOOK;So;0;L;;;;;N;;;;;\n1D86C;SIGNWRITING HAND-CUP OPEN;So;0;L;;;;;N;;;;;\n1D86D;SIGNWRITING HAND-CUP;So;0;L;;;;;N;;;;;\n1D86E;SIGNWRITING HAND-CUP OPEN THUMB SIDE;So;0;L;;;;;N;;;;;\n1D86F;SIGNWRITING HAND-CUP THUMB SIDE;So;0;L;;;;;N;;;;;\n1D870;SIGNWRITING HAND-CUP OPEN NO THUMB;So;0;L;;;;;N;;;;;\n1D871;SIGNWRITING HAND-CUP NO THUMB;So;0;L;;;;;N;;;;;\n1D872;SIGNWRITING HAND-CUP OPEN THUMB FORWARD;So;0;L;;;;;N;;;;;\n1D873;SIGNWRITING HAND-CUP THUMB FORWARD;So;0;L;;;;;N;;;;;\n1D874;SIGNWRITING HAND-CURLICUE OPEN;So;0;L;;;;;N;;;;;\n1D875;SIGNWRITING HAND-CURLICUE;So;0;L;;;;;N;;;;;\n1D876;SIGNWRITING HAND-CIRCLE;So;0;L;;;;;N;;;;;\n1D877;SIGNWRITING HAND-OVAL;So;0;L;;;;;N;;;;;\n1D878;SIGNWRITING HAND-OVAL THUMB SIDE;So;0;L;;;;;N;;;;;\n1D879;SIGNWRITING HAND-OVAL NO THUMB;So;0;L;;;;;N;;;;;\n1D87A;SIGNWRITING HAND-OVAL THUMB FORWARD;So;0;L;;;;;N;;;;;\n1D87B;SIGNWRITING HAND-HINGE OPEN;So;0;L;;;;;N;;;;;\n1D87C;SIGNWRITING HAND-HINGE OPEN THUMB FORWARD;So;0;L;;;;;N;;;;;\n1D87D;SIGNWRITING HAND-HINGE;So;0;L;;;;;N;;;;;\n1D87E;SIGNWRITING HAND-HINGE SMALL;So;0;L;;;;;N;;;;;\n1D87F;SIGNWRITING HAND-HINGE OPEN THUMB SIDE;So;0;L;;;;;N;;;;;\n1D880;SIGNWRITING HAND-HINGE THUMB SIDE;So;0;L;;;;;N;;;;;\n1D881;SIGNWRITING HAND-HINGE OPEN NO THUMB;So;0;L;;;;;N;;;;;\n1D882;SIGNWRITING HAND-HINGE NO THUMB;So;0;L;;;;;N;;;;;\n1D883;SIGNWRITING HAND-HINGE THUMB SIDE TOUCHING INDEX;So;0;L;;;;;N;;;;;\n1D884;SIGNWRITING HAND-HINGE THUMB BETWEEN MIDDLE RING;So;0;L;;;;;N;;;;;\n1D885;SIGNWRITING HAND-ANGLE;So;0;L;;;;;N;;;;;\n1D886;SIGNWRITING HAND-FIST INDEX MIDDLE RING;So;0;L;;;;;N;;;;;\n1D887;SIGNWRITING HAND-CIRCLE INDEX MIDDLE RING;So;0;L;;;;;N;;;;;\n1D888;SIGNWRITING HAND-HINGE INDEX MIDDLE RING;So;0;L;;;;;N;;;;;\n1D889;SIGNWRITING HAND-ANGLE INDEX MIDDLE RING;So;0;L;;;;;N;;;;;\n1D88A;SIGNWRITING HAND-HINGE LITTLE;So;0;L;;;;;N;;;;;\n1D88B;SIGNWRITING HAND-FIST INDEX MIDDLE RING BENT;So;0;L;;;;;N;;;;;\n1D88C;SIGNWRITING HAND-FIST INDEX MIDDLE RING CONJOINED;So;0;L;;;;;N;;;;;\n1D88D;SIGNWRITING HAND-HINGE INDEX MIDDLE RING CONJOINED;So;0;L;;;;;N;;;;;\n1D88E;SIGNWRITING HAND-FIST LITTLE DOWN;So;0;L;;;;;N;;;;;\n1D88F;SIGNWRITING HAND-FIST LITTLE DOWN RIPPLE STRAIGHT;So;0;L;;;;;N;;;;;\n1D890;SIGNWRITING HAND-FIST LITTLE DOWN RIPPLE CURVED;So;0;L;;;;;N;;;;;\n1D891;SIGNWRITING HAND-FIST LITTLE DOWN OTHERS CIRCLED;So;0;L;;;;;N;;;;;\n1D892;SIGNWRITING HAND-FIST LITTLE UP;So;0;L;;;;;N;;;;;\n1D893;SIGNWRITING HAND-FIST THUMB UNDER LITTLE UP;So;0;L;;;;;N;;;;;\n1D894;SIGNWRITING HAND-CIRCLE LITTLE UP;So;0;L;;;;;N;;;;;\n1D895;SIGNWRITING HAND-OVAL LITTLE UP;So;0;L;;;;;N;;;;;\n1D896;SIGNWRITING HAND-ANGLE LITTLE UP;So;0;L;;;;;N;;;;;\n1D897;SIGNWRITING HAND-FIST LITTLE RAISED KNUCKLE;So;0;L;;;;;N;;;;;\n1D898;SIGNWRITING HAND-FIST LITTLE BENT;So;0;L;;;;;N;;;;;\n1D899;SIGNWRITING HAND-FIST LITTLE TOUCHES THUMB;So;0;L;;;;;N;;;;;\n1D89A;SIGNWRITING HAND-FIST LITTLE THUMB;So;0;L;;;;;N;;;;;\n1D89B;SIGNWRITING HAND-HINGE LITTLE THUMB;So;0;L;;;;;N;;;;;\n1D89C;SIGNWRITING HAND-FIST LITTLE INDEX THUMB;So;0;L;;;;;N;;;;;\n1D89D;SIGNWRITING HAND-HINGE LITTLE INDEX THUMB;So;0;L;;;;;N;;;;;\n1D89E;SIGNWRITING HAND-ANGLE LITTLE INDEX THUMB INDEX THUMB OUT;So;0;L;;;;;N;;;;;\n1D89F;SIGNWRITING HAND-ANGLE LITTLE INDEX THUMB INDEX THUMB;So;0;L;;;;;N;;;;;\n1D8A0;SIGNWRITING HAND-FIST LITTLE INDEX;So;0;L;;;;;N;;;;;\n1D8A1;SIGNWRITING HAND-CIRCLE LITTLE INDEX;So;0;L;;;;;N;;;;;\n1D8A2;SIGNWRITING HAND-HINGE LITTLE INDEX;So;0;L;;;;;N;;;;;\n1D8A3;SIGNWRITING HAND-ANGLE LITTLE INDEX;So;0;L;;;;;N;;;;;\n1D8A4;SIGNWRITING HAND-FIST INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;;\n1D8A5;SIGNWRITING HAND-CIRCLE INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;;\n1D8A6;SIGNWRITING HAND-HINGE INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;;\n1D8A7;SIGNWRITING HAND-HINGE RING;So;0;L;;;;;N;;;;;\n1D8A8;SIGNWRITING HAND-ANGLE INDEX MIDDLE LITTLE;So;0;L;;;;;N;;;;;\n1D8A9;SIGNWRITING HAND-FIST INDEX MIDDLE CROSS LITTLE;So;0;L;;;;;N;;;;;\n1D8AA;SIGNWRITING HAND-CIRCLE INDEX MIDDLE CROSS LITTLE;So;0;L;;;;;N;;;;;\n1D8AB;SIGNWRITING HAND-FIST RING DOWN;So;0;L;;;;;N;;;;;\n1D8AC;SIGNWRITING HAND-HINGE RING DOWN INDEX THUMB HOOK MIDDLE;So;0;L;;;;;N;;;;;\n1D8AD;SIGNWRITING HAND-ANGLE RING DOWN MIDDLE THUMB INDEX CROSS;So;0;L;;;;;N;;;;;\n1D8AE;SIGNWRITING HAND-FIST RING UP;So;0;L;;;;;N;;;;;\n1D8AF;SIGNWRITING HAND-FIST RING RAISED KNUCKLE;So;0;L;;;;;N;;;;;\n1D8B0;SIGNWRITING HAND-FIST RING LITTLE;So;0;L;;;;;N;;;;;\n1D8B1;SIGNWRITING HAND-CIRCLE RING LITTLE;So;0;L;;;;;N;;;;;\n1D8B2;SIGNWRITING HAND-OVAL RING LITTLE;So;0;L;;;;;N;;;;;\n1D8B3;SIGNWRITING HAND-ANGLE RING LITTLE;So;0;L;;;;;N;;;;;\n1D8B4;SIGNWRITING HAND-FIST RING MIDDLE;So;0;L;;;;;N;;;;;\n1D8B5;SIGNWRITING HAND-FIST RING MIDDLE CONJOINED;So;0;L;;;;;N;;;;;\n1D8B6;SIGNWRITING HAND-FIST RING MIDDLE RAISED KNUCKLES;So;0;L;;;;;N;;;;;\n1D8B7;SIGNWRITING HAND-FIST RING INDEX;So;0;L;;;;;N;;;;;\n1D8B8;SIGNWRITING HAND-FIST RING THUMB;So;0;L;;;;;N;;;;;\n1D8B9;SIGNWRITING HAND-HOOK RING THUMB;So;0;L;;;;;N;;;;;\n1D8BA;SIGNWRITING HAND-FIST INDEX RING LITTLE;So;0;L;;;;;N;;;;;\n1D8BB;SIGNWRITING HAND-CIRCLE INDEX RING LITTLE;So;0;L;;;;;N;;;;;\n1D8BC;SIGNWRITING HAND-CURLICUE INDEX RING LITTLE ON;So;0;L;;;;;N;;;;;\n1D8BD;SIGNWRITING HAND-HOOK INDEX RING LITTLE OUT;So;0;L;;;;;N;;;;;\n1D8BE;SIGNWRITING HAND-HOOK INDEX RING LITTLE IN;So;0;L;;;;;N;;;;;\n1D8BF;SIGNWRITING HAND-HOOK INDEX RING LITTLE UNDER;So;0;L;;;;;N;;;;;\n1D8C0;SIGNWRITING HAND-CUP INDEX RING LITTLE;So;0;L;;;;;N;;;;;\n1D8C1;SIGNWRITING HAND-HINGE INDEX RING LITTLE;So;0;L;;;;;N;;;;;\n1D8C2;SIGNWRITING HAND-ANGLE INDEX RING LITTLE OUT;So;0;L;;;;;N;;;;;\n1D8C3;SIGNWRITING HAND-ANGLE INDEX RING LITTLE;So;0;L;;;;;N;;;;;\n1D8C4;SIGNWRITING HAND-FIST MIDDLE DOWN;So;0;L;;;;;N;;;;;\n1D8C5;SIGNWRITING HAND-HINGE MIDDLE;So;0;L;;;;;N;;;;;\n1D8C6;SIGNWRITING HAND-FIST MIDDLE UP;So;0;L;;;;;N;;;;;\n1D8C7;SIGNWRITING HAND-CIRCLE MIDDLE UP;So;0;L;;;;;N;;;;;\n1D8C8;SIGNWRITING HAND-FIST MIDDLE RAISED KNUCKLE;So;0;L;;;;;N;;;;;\n1D8C9;SIGNWRITING HAND-FIST MIDDLE UP THUMB SIDE;So;0;L;;;;;N;;;;;\n1D8CA;SIGNWRITING HAND-HOOK MIDDLE THUMB;So;0;L;;;;;N;;;;;\n1D8CB;SIGNWRITING HAND-FIST MIDDLE THUMB LITTLE;So;0;L;;;;;N;;;;;\n1D8CC;SIGNWRITING HAND-FIST MIDDLE LITTLE;So;0;L;;;;;N;;;;;\n1D8CD;SIGNWRITING HAND-FIST MIDDLE RING LITTLE;So;0;L;;;;;N;;;;;\n1D8CE;SIGNWRITING HAND-CIRCLE MIDDLE RING LITTLE;So;0;L;;;;;N;;;;;\n1D8CF;SIGNWRITING HAND-CURLICUE MIDDLE RING LITTLE ON;So;0;L;;;;;N;;;;;\n1D8D0;SIGNWRITING HAND-CUP MIDDLE RING LITTLE;So;0;L;;;;;N;;;;;\n1D8D1;SIGNWRITING HAND-HINGE MIDDLE RING LITTLE;So;0;L;;;;;N;;;;;\n1D8D2;SIGNWRITING HAND-ANGLE MIDDLE RING LITTLE OUT;So;0;L;;;;;N;;;;;\n1D8D3;SIGNWRITING HAND-ANGLE MIDDLE RING LITTLE IN;So;0;L;;;;;N;;;;;\n1D8D4;SIGNWRITING HAND-ANGLE MIDDLE RING LITTLE;So;0;L;;;;;N;;;;;\n1D8D5;SIGNWRITING HAND-CIRCLE MIDDLE RING LITTLE BENT;So;0;L;;;;;N;;;;;\n1D8D6;SIGNWRITING HAND-CLAW MIDDLE RING LITTLE CONJOINED;So;0;L;;;;;N;;;;;\n1D8D7;SIGNWRITING HAND-CLAW MIDDLE RING LITTLE CONJOINED SIDE;So;0;L;;;;;N;;;;;\n1D8D8;SIGNWRITING HAND-HOOK MIDDLE RING LITTLE CONJOINED OUT;So;0;L;;;;;N;;;;;\n1D8D9;SIGNWRITING HAND-HOOK MIDDLE RING LITTLE CONJOINED IN;So;0;L;;;;;N;;;;;\n1D8DA;SIGNWRITING HAND-HOOK MIDDLE RING LITTLE CONJOINED;So;0;L;;;;;N;;;;;\n1D8DB;SIGNWRITING HAND-HINGE INDEX HINGED;So;0;L;;;;;N;;;;;\n1D8DC;SIGNWRITING HAND-FIST INDEX THUMB SIDE;So;0;L;;;;;N;;;;;\n1D8DD;SIGNWRITING HAND-HINGE INDEX THUMB SIDE;So;0;L;;;;;N;;;;;\n1D8DE;SIGNWRITING HAND-FIST INDEX THUMB SIDE THUMB DIAGONAL;So;0;L;;;;;N;;;;;\n1D8DF;SIGNWRITING HAND-FIST INDEX THUMB SIDE THUMB CONJOINED;So;0;L;;;;;N;;;;;\n1D8E0;SIGNWRITING HAND-FIST INDEX THUMB SIDE THUMB BENT;So;0;L;;;;;N;;;;;\n1D8E1;SIGNWRITING HAND-FIST INDEX THUMB SIDE INDEX BENT;So;0;L;;;;;N;;;;;\n1D8E2;SIGNWRITING HAND-FIST INDEX THUMB SIDE BOTH BENT;So;0;L;;;;;N;;;;;\n1D8E3;SIGNWRITING HAND-FIST INDEX THUMB SIDE INDEX HINGE;So;0;L;;;;;N;;;;;\n1D8E4;SIGNWRITING HAND-FIST INDEX THUMB FORWARD INDEX STRAIGHT;So;0;L;;;;;N;;;;;\n1D8E5;SIGNWRITING HAND-FIST INDEX THUMB FORWARD INDEX BENT;So;0;L;;;;;N;;;;;\n1D8E6;SIGNWRITING HAND-FIST INDEX THUMB HOOK;So;0;L;;;;;N;;;;;\n1D8E7;SIGNWRITING HAND-FIST INDEX THUMB CURLICUE;So;0;L;;;;;N;;;;;\n1D8E8;SIGNWRITING HAND-FIST INDEX THUMB CURVE THUMB INSIDE;So;0;L;;;;;N;;;;;\n1D8E9;SIGNWRITING HAND-CLAW INDEX THUMB CURVE THUMB INSIDE;So;0;L;;;;;N;;;;;\n1D8EA;SIGNWRITING HAND-FIST INDEX THUMB CURVE THUMB UNDER;So;0;L;;;;;N;;;;;\n1D8EB;SIGNWRITING HAND-FIST INDEX THUMB CIRCLE;So;0;L;;;;;N;;;;;\n1D8EC;SIGNWRITING HAND-CUP INDEX THUMB;So;0;L;;;;;N;;;;;\n1D8ED;SIGNWRITING HAND-CUP INDEX THUMB OPEN;So;0;L;;;;;N;;;;;\n1D8EE;SIGNWRITING HAND-HINGE INDEX THUMB OPEN;So;0;L;;;;;N;;;;;\n1D8EF;SIGNWRITING HAND-HINGE INDEX THUMB LARGE;So;0;L;;;;;N;;;;;\n1D8F0;SIGNWRITING HAND-HINGE INDEX THUMB;So;0;L;;;;;N;;;;;\n1D8F1;SIGNWRITING HAND-HINGE INDEX THUMB SMALL;So;0;L;;;;;N;;;;;\n1D8F2;SIGNWRITING HAND-ANGLE INDEX THUMB OUT;So;0;L;;;;;N;;;;;\n1D8F3;SIGNWRITING HAND-ANGLE INDEX THUMB IN;So;0;L;;;;;N;;;;;\n1D8F4;SIGNWRITING HAND-ANGLE INDEX THUMB;So;0;L;;;;;N;;;;;\n1D8F5;SIGNWRITING HAND-FIST THUMB;So;0;L;;;;;N;;;;;\n1D8F6;SIGNWRITING HAND-FIST THUMB HEEL;So;0;L;;;;;N;;;;;\n1D8F7;SIGNWRITING HAND-FIST THUMB SIDE DIAGONAL;So;0;L;;;;;N;;;;;\n1D8F8;SIGNWRITING HAND-FIST THUMB SIDE CONJOINED;So;0;L;;;;;N;;;;;\n1D8F9;SIGNWRITING HAND-FIST THUMB SIDE BENT;So;0;L;;;;;N;;;;;\n1D8FA;SIGNWRITING HAND-FIST THUMB FORWARD;So;0;L;;;;;N;;;;;\n1D8FB;SIGNWRITING HAND-FIST THUMB BETWEEN INDEX MIDDLE;So;0;L;;;;;N;;;;;\n1D8FC;SIGNWRITING HAND-FIST THUMB BETWEEN MIDDLE RING;So;0;L;;;;;N;;;;;\n1D8FD;SIGNWRITING HAND-FIST THUMB BETWEEN RING LITTLE;So;0;L;;;;;N;;;;;\n1D8FE;SIGNWRITING HAND-FIST THUMB UNDER TWO FINGERS;So;0;L;;;;;N;;;;;\n1D8FF;SIGNWRITING HAND-FIST THUMB OVER TWO FINGERS;So;0;L;;;;;N;;;;;\n1D900;SIGNWRITING HAND-FIST THUMB UNDER THREE FINGERS;So;0;L;;;;;N;;;;;\n1D901;SIGNWRITING HAND-FIST THUMB UNDER FOUR FINGERS;So;0;L;;;;;N;;;;;\n1D902;SIGNWRITING HAND-FIST THUMB OVER FOUR RAISED KNUCKLES;So;0;L;;;;;N;;;;;\n1D903;SIGNWRITING HAND-FIST;So;0;L;;;;;N;;;;;\n1D904;SIGNWRITING HAND-FIST HEEL;So;0;L;;;;;N;;;;;\n1D905;SIGNWRITING TOUCH SINGLE;So;0;L;;;;;N;;;;;\n1D906;SIGNWRITING TOUCH MULTIPLE;So;0;L;;;;;N;;;;;\n1D907;SIGNWRITING TOUCH BETWEEN;So;0;L;;;;;N;;;;;\n1D908;SIGNWRITING GRASP SINGLE;So;0;L;;;;;N;;;;;\n1D909;SIGNWRITING GRASP MULTIPLE;So;0;L;;;;;N;;;;;\n1D90A;SIGNWRITING GRASP BETWEEN;So;0;L;;;;;N;;;;;\n1D90B;SIGNWRITING STRIKE SINGLE;So;0;L;;;;;N;;;;;\n1D90C;SIGNWRITING STRIKE MULTIPLE;So;0;L;;;;;N;;;;;\n1D90D;SIGNWRITING STRIKE BETWEEN;So;0;L;;;;;N;;;;;\n1D90E;SIGNWRITING BRUSH SINGLE;So;0;L;;;;;N;;;;;\n1D90F;SIGNWRITING BRUSH MULTIPLE;So;0;L;;;;;N;;;;;\n1D910;SIGNWRITING BRUSH BETWEEN;So;0;L;;;;;N;;;;;\n1D911;SIGNWRITING RUB SINGLE;So;0;L;;;;;N;;;;;\n1D912;SIGNWRITING RUB MULTIPLE;So;0;L;;;;;N;;;;;\n1D913;SIGNWRITING RUB BETWEEN;So;0;L;;;;;N;;;;;\n1D914;SIGNWRITING SURFACE SYMBOLS;So;0;L;;;;;N;;;;;\n1D915;SIGNWRITING SURFACE BETWEEN;So;0;L;;;;;N;;;;;\n1D916;SIGNWRITING SQUEEZE LARGE SINGLE;So;0;L;;;;;N;;;;;\n1D917;SIGNWRITING SQUEEZE SMALL SINGLE;So;0;L;;;;;N;;;;;\n1D918;SIGNWRITING SQUEEZE LARGE MULTIPLE;So;0;L;;;;;N;;;;;\n1D919;SIGNWRITING SQUEEZE SMALL MULTIPLE;So;0;L;;;;;N;;;;;\n1D91A;SIGNWRITING SQUEEZE SEQUENTIAL;So;0;L;;;;;N;;;;;\n1D91B;SIGNWRITING FLICK LARGE SINGLE;So;0;L;;;;;N;;;;;\n1D91C;SIGNWRITING FLICK SMALL SINGLE;So;0;L;;;;;N;;;;;\n1D91D;SIGNWRITING FLICK LARGE MULTIPLE;So;0;L;;;;;N;;;;;\n1D91E;SIGNWRITING FLICK SMALL MULTIPLE;So;0;L;;;;;N;;;;;\n1D91F;SIGNWRITING FLICK SEQUENTIAL;So;0;L;;;;;N;;;;;\n1D920;SIGNWRITING SQUEEZE FLICK ALTERNATING;So;0;L;;;;;N;;;;;\n1D921;SIGNWRITING MOVEMENT-HINGE UP DOWN LARGE;So;0;L;;;;;N;;;;;\n1D922;SIGNWRITING MOVEMENT-HINGE UP DOWN SMALL;So;0;L;;;;;N;;;;;\n1D923;SIGNWRITING MOVEMENT-HINGE UP SEQUENTIAL;So;0;L;;;;;N;;;;;\n1D924;SIGNWRITING MOVEMENT-HINGE DOWN SEQUENTIAL;So;0;L;;;;;N;;;;;\n1D925;SIGNWRITING MOVEMENT-HINGE UP DOWN ALTERNATING LARGE;So;0;L;;;;;N;;;;;\n1D926;SIGNWRITING MOVEMENT-HINGE UP DOWN ALTERNATING SMALL;So;0;L;;;;;N;;;;;\n1D927;SIGNWRITING MOVEMENT-HINGE SIDE TO SIDE SCISSORS;So;0;L;;;;;N;;;;;\n1D928;SIGNWRITING MOVEMENT-WALLPLANE FINGER CONTACT;So;0;L;;;;;N;;;;;\n1D929;SIGNWRITING MOVEMENT-FLOORPLANE FINGER CONTACT;So;0;L;;;;;N;;;;;\n1D92A;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT SMALL;So;0;L;;;;;N;;;;;\n1D92B;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT MEDIUM;So;0;L;;;;;N;;;;;\n1D92C;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT LARGE;So;0;L;;;;;N;;;;;\n1D92D;SIGNWRITING MOVEMENT-WALLPLANE SINGLE STRAIGHT LARGEST;So;0;L;;;;;N;;;;;\n1D92E;SIGNWRITING MOVEMENT-WALLPLANE SINGLE WRIST FLEX;So;0;L;;;;;N;;;;;\n1D92F;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE STRAIGHT;So;0;L;;;;;N;;;;;\n1D930;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE WRIST FLEX;So;0;L;;;;;N;;;;;\n1D931;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE ALTERNATING;So;0;L;;;;;N;;;;;\n1D932;SIGNWRITING MOVEMENT-WALLPLANE DOUBLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;;\n1D933;SIGNWRITING MOVEMENT-WALLPLANE CROSS;So;0;L;;;;;N;;;;;\n1D934;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE STRAIGHT MOVEMENT;So;0;L;;;;;N;;;;;\n1D935;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE WRIST FLEX;So;0;L;;;;;N;;;;;\n1D936;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE ALTERNATING;So;0;L;;;;;N;;;;;\n1D937;SIGNWRITING MOVEMENT-WALLPLANE TRIPLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;;\n1D938;SIGNWRITING MOVEMENT-WALLPLANE BEND SMALL;So;0;L;;;;;N;;;;;\n1D939;SIGNWRITING MOVEMENT-WALLPLANE BEND MEDIUM;So;0;L;;;;;N;;;;;\n1D93A;SIGNWRITING MOVEMENT-WALLPLANE BEND LARGE;So;0;L;;;;;N;;;;;\n1D93B;SIGNWRITING MOVEMENT-WALLPLANE CORNER SMALL;So;0;L;;;;;N;;;;;\n1D93C;SIGNWRITING MOVEMENT-WALLPLANE CORNER MEDIUM;So;0;L;;;;;N;;;;;\n1D93D;SIGNWRITING MOVEMENT-WALLPLANE CORNER LARGE;So;0;L;;;;;N;;;;;\n1D93E;SIGNWRITING MOVEMENT-WALLPLANE CORNER ROTATION;So;0;L;;;;;N;;;;;\n1D93F;SIGNWRITING MOVEMENT-WALLPLANE CHECK SMALL;So;0;L;;;;;N;;;;;\n1D940;SIGNWRITING MOVEMENT-WALLPLANE CHECK MEDIUM;So;0;L;;;;;N;;;;;\n1D941;SIGNWRITING MOVEMENT-WALLPLANE CHECK LARGE;So;0;L;;;;;N;;;;;\n1D942;SIGNWRITING MOVEMENT-WALLPLANE BOX SMALL;So;0;L;;;;;N;;;;;\n1D943;SIGNWRITING MOVEMENT-WALLPLANE BOX MEDIUM;So;0;L;;;;;N;;;;;\n1D944;SIGNWRITING MOVEMENT-WALLPLANE BOX LARGE;So;0;L;;;;;N;;;;;\n1D945;SIGNWRITING MOVEMENT-WALLPLANE ZIGZAG SMALL;So;0;L;;;;;N;;;;;\n1D946;SIGNWRITING MOVEMENT-WALLPLANE ZIGZAG MEDIUM;So;0;L;;;;;N;;;;;\n1D947;SIGNWRITING MOVEMENT-WALLPLANE ZIGZAG LARGE;So;0;L;;;;;N;;;;;\n1D948;SIGNWRITING MOVEMENT-WALLPLANE PEAKS SMALL;So;0;L;;;;;N;;;;;\n1D949;SIGNWRITING MOVEMENT-WALLPLANE PEAKS MEDIUM;So;0;L;;;;;N;;;;;\n1D94A;SIGNWRITING MOVEMENT-WALLPLANE PEAKS LARGE;So;0;L;;;;;N;;;;;\n1D94B;SIGNWRITING TRAVEL-WALLPLANE ROTATION-WALLPLANE SINGLE;So;0;L;;;;;N;;;;;\n1D94C;SIGNWRITING TRAVEL-WALLPLANE ROTATION-WALLPLANE DOUBLE;So;0;L;;;;;N;;;;;\n1D94D;SIGNWRITING TRAVEL-WALLPLANE ROTATION-WALLPLANE ALTERNATING;So;0;L;;;;;N;;;;;\n1D94E;SIGNWRITING TRAVEL-WALLPLANE ROTATION-FLOORPLANE SINGLE;So;0;L;;;;;N;;;;;\n1D94F;SIGNWRITING TRAVEL-WALLPLANE ROTATION-FLOORPLANE DOUBLE;So;0;L;;;;;N;;;;;\n1D950;SIGNWRITING TRAVEL-WALLPLANE ROTATION-FLOORPLANE ALTERNATING;So;0;L;;;;;N;;;;;\n1D951;SIGNWRITING TRAVEL-WALLPLANE SHAKING;So;0;L;;;;;N;;;;;\n1D952;SIGNWRITING TRAVEL-WALLPLANE ARM SPIRAL SINGLE;So;0;L;;;;;N;;;;;\n1D953;SIGNWRITING TRAVEL-WALLPLANE ARM SPIRAL DOUBLE;So;0;L;;;;;N;;;;;\n1D954;SIGNWRITING TRAVEL-WALLPLANE ARM SPIRAL TRIPLE;So;0;L;;;;;N;;;;;\n1D955;SIGNWRITING MOVEMENT-DIAGONAL AWAY SMALL;So;0;L;;;;;N;;;;;\n1D956;SIGNWRITING MOVEMENT-DIAGONAL AWAY MEDIUM;So;0;L;;;;;N;;;;;\n1D957;SIGNWRITING MOVEMENT-DIAGONAL AWAY LARGE;So;0;L;;;;;N;;;;;\n1D958;SIGNWRITING MOVEMENT-DIAGONAL AWAY LARGEST;So;0;L;;;;;N;;;;;\n1D959;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS SMALL;So;0;L;;;;;N;;;;;\n1D95A;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS MEDIUM;So;0;L;;;;;N;;;;;\n1D95B;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS LARGE;So;0;L;;;;;N;;;;;\n1D95C;SIGNWRITING MOVEMENT-DIAGONAL TOWARDS LARGEST;So;0;L;;;;;N;;;;;\n1D95D;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY SMALL;So;0;L;;;;;N;;;;;\n1D95E;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY MEDIUM;So;0;L;;;;;N;;;;;\n1D95F;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY LARGE;So;0;L;;;;;N;;;;;\n1D960;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN AWAY LARGEST;So;0;L;;;;;N;;;;;\n1D961;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS SMALL;So;0;L;;;;;N;;;;;\n1D962;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS MEDIUM;So;0;L;;;;;N;;;;;\n1D963;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS LARGE;So;0;L;;;;;N;;;;;\n1D964;SIGNWRITING MOVEMENT-DIAGONAL BETWEEN TOWARDS LARGEST;So;0;L;;;;;N;;;;;\n1D965;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT SMALL;So;0;L;;;;;N;;;;;\n1D966;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT MEDIUM;So;0;L;;;;;N;;;;;\n1D967;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT LARGE;So;0;L;;;;;N;;;;;\n1D968;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE STRAIGHT LARGEST;So;0;L;;;;;N;;;;;\n1D969;SIGNWRITING MOVEMENT-FLOORPLANE SINGLE WRIST FLEX;So;0;L;;;;;N;;;;;\n1D96A;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE STRAIGHT;So;0;L;;;;;N;;;;;\n1D96B;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE WRIST FLEX;So;0;L;;;;;N;;;;;\n1D96C;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE ALTERNATING;So;0;L;;;;;N;;;;;\n1D96D;SIGNWRITING MOVEMENT-FLOORPLANE DOUBLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;;\n1D96E;SIGNWRITING MOVEMENT-FLOORPLANE CROSS;So;0;L;;;;;N;;;;;\n1D96F;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE STRAIGHT MOVEMENT;So;0;L;;;;;N;;;;;\n1D970;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE WRIST FLEX;So;0;L;;;;;N;;;;;\n1D971;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE ALTERNATING MOVEMENT;So;0;L;;;;;N;;;;;\n1D972;SIGNWRITING MOVEMENT-FLOORPLANE TRIPLE ALTERNATING WRIST FLEX;So;0;L;;;;;N;;;;;\n1D973;SIGNWRITING MOVEMENT-FLOORPLANE BEND;So;0;L;;;;;N;;;;;\n1D974;SIGNWRITING MOVEMENT-FLOORPLANE CORNER SMALL;So;0;L;;;;;N;;;;;\n1D975;SIGNWRITING MOVEMENT-FLOORPLANE CORNER MEDIUM;So;0;L;;;;;N;;;;;\n1D976;SIGNWRITING MOVEMENT-FLOORPLANE CORNER LARGE;So;0;L;;;;;N;;;;;\n1D977;SIGNWRITING MOVEMENT-FLOORPLANE CHECK;So;0;L;;;;;N;;;;;\n1D978;SIGNWRITING MOVEMENT-FLOORPLANE BOX SMALL;So;0;L;;;;;N;;;;;\n1D979;SIGNWRITING MOVEMENT-FLOORPLANE BOX MEDIUM;So;0;L;;;;;N;;;;;\n1D97A;SIGNWRITING MOVEMENT-FLOORPLANE BOX LARGE;So;0;L;;;;;N;;;;;\n1D97B;SIGNWRITING MOVEMENT-FLOORPLANE ZIGZAG SMALL;So;0;L;;;;;N;;;;;\n1D97C;SIGNWRITING MOVEMENT-FLOORPLANE ZIGZAG MEDIUM;So;0;L;;;;;N;;;;;\n1D97D;SIGNWRITING MOVEMENT-FLOORPLANE ZIGZAG LARGE;So;0;L;;;;;N;;;;;\n1D97E;SIGNWRITING MOVEMENT-FLOORPLANE PEAKS SMALL;So;0;L;;;;;N;;;;;\n1D97F;SIGNWRITING MOVEMENT-FLOORPLANE PEAKS MEDIUM;So;0;L;;;;;N;;;;;\n1D980;SIGNWRITING MOVEMENT-FLOORPLANE PEAKS LARGE;So;0;L;;;;;N;;;;;\n1D981;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-FLOORPLANE SINGLE;So;0;L;;;;;N;;;;;\n1D982;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-FLOORPLANE DOUBLE;So;0;L;;;;;N;;;;;\n1D983;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-FLOORPLANE ALTERNATING;So;0;L;;;;;N;;;;;\n1D984;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-WALLPLANE SINGLE;So;0;L;;;;;N;;;;;\n1D985;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-WALLPLANE DOUBLE;So;0;L;;;;;N;;;;;\n1D986;SIGNWRITING TRAVEL-FLOORPLANE ROTATION-WALLPLANE ALTERNATING;So;0;L;;;;;N;;;;;\n1D987;SIGNWRITING TRAVEL-FLOORPLANE SHAKING;So;0;L;;;;;N;;;;;\n1D988;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER SMALL;So;0;L;;;;;N;;;;;\n1D989;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER MEDIUM;So;0;L;;;;;N;;;;;\n1D98A;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER LARGE;So;0;L;;;;;N;;;;;\n1D98B;SIGNWRITING MOVEMENT-WALLPLANE CURVE QUARTER LARGEST;So;0;L;;;;;N;;;;;\n1D98C;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE SMALL;So;0;L;;;;;N;;;;;\n1D98D;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE MEDIUM;So;0;L;;;;;N;;;;;\n1D98E;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE LARGE;So;0;L;;;;;N;;;;;\n1D98F;SIGNWRITING MOVEMENT-WALLPLANE CURVE HALF-CIRCLE LARGEST;So;0;L;;;;;N;;;;;\n1D990;SIGNWRITING MOVEMENT-WALLPLANE CURVE THREE-QUARTER CIRCLE SMALL;So;0;L;;;;;N;;;;;\n1D991;SIGNWRITING MOVEMENT-WALLPLANE CURVE THREE-QUARTER CIRCLE MEDIUM;So;0;L;;;;;N;;;;;\n1D992;SIGNWRITING MOVEMENT-WALLPLANE HUMP SMALL;So;0;L;;;;;N;;;;;\n1D993;SIGNWRITING MOVEMENT-WALLPLANE HUMP MEDIUM;So;0;L;;;;;N;;;;;\n1D994;SIGNWRITING MOVEMENT-WALLPLANE HUMP LARGE;So;0;L;;;;;N;;;;;\n1D995;SIGNWRITING MOVEMENT-WALLPLANE LOOP SMALL;So;0;L;;;;;N;;;;;\n1D996;SIGNWRITING MOVEMENT-WALLPLANE LOOP MEDIUM;So;0;L;;;;;N;;;;;\n1D997;SIGNWRITING MOVEMENT-WALLPLANE LOOP LARGE;So;0;L;;;;;N;;;;;\n1D998;SIGNWRITING MOVEMENT-WALLPLANE LOOP SMALL DOUBLE;So;0;L;;;;;N;;;;;\n1D999;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE DOUBLE SMALL;So;0;L;;;;;N;;;;;\n1D99A;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE DOUBLE MEDIUM;So;0;L;;;;;N;;;;;\n1D99B;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE DOUBLE LARGE;So;0;L;;;;;N;;;;;\n1D99C;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE TRIPLE SMALL;So;0;L;;;;;N;;;;;\n1D99D;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE TRIPLE MEDIUM;So;0;L;;;;;N;;;;;\n1D99E;SIGNWRITING MOVEMENT-WALLPLANE WAVE CURVE TRIPLE LARGE;So;0;L;;;;;N;;;;;\n1D99F;SIGNWRITING MOVEMENT-WALLPLANE CURVE THEN STRAIGHT;So;0;L;;;;;N;;;;;\n1D9A0;SIGNWRITING MOVEMENT-WALLPLANE CURVED CROSS SMALL;So;0;L;;;;;N;;;;;\n1D9A1;SIGNWRITING MOVEMENT-WALLPLANE CURVED CROSS MEDIUM;So;0;L;;;;;N;;;;;\n1D9A2;SIGNWRITING ROTATION-WALLPLANE SINGLE;So;0;L;;;;;N;;;;;\n1D9A3;SIGNWRITING ROTATION-WALLPLANE DOUBLE;So;0;L;;;;;N;;;;;\n1D9A4;SIGNWRITING ROTATION-WALLPLANE ALTERNATE;So;0;L;;;;;N;;;;;\n1D9A5;SIGNWRITING MOVEMENT-WALLPLANE SHAKING;So;0;L;;;;;N;;;;;\n1D9A6;SIGNWRITING MOVEMENT-WALLPLANE CURVE HITTING FRONT WALL;So;0;L;;;;;N;;;;;\n1D9A7;SIGNWRITING MOVEMENT-WALLPLANE HUMP HITTING FRONT WALL;So;0;L;;;;;N;;;;;\n1D9A8;SIGNWRITING MOVEMENT-WALLPLANE LOOP HITTING FRONT WALL;So;0;L;;;;;N;;;;;\n1D9A9;SIGNWRITING MOVEMENT-WALLPLANE WAVE HITTING FRONT WALL;So;0;L;;;;;N;;;;;\n1D9AA;SIGNWRITING ROTATION-WALLPLANE SINGLE HITTING FRONT WALL;So;0;L;;;;;N;;;;;\n1D9AB;SIGNWRITING ROTATION-WALLPLANE DOUBLE HITTING FRONT WALL;So;0;L;;;;;N;;;;;\n1D9AC;SIGNWRITING ROTATION-WALLPLANE ALTERNATING HITTING FRONT WALL;So;0;L;;;;;N;;;;;\n1D9AD;SIGNWRITING MOVEMENT-WALLPLANE CURVE HITTING CHEST;So;0;L;;;;;N;;;;;\n1D9AE;SIGNWRITING MOVEMENT-WALLPLANE HUMP HITTING CHEST;So;0;L;;;;;N;;;;;\n1D9AF;SIGNWRITING MOVEMENT-WALLPLANE LOOP HITTING CHEST;So;0;L;;;;;N;;;;;\n1D9B0;SIGNWRITING MOVEMENT-WALLPLANE WAVE HITTING CHEST;So;0;L;;;;;N;;;;;\n1D9B1;SIGNWRITING ROTATION-WALLPLANE SINGLE HITTING CHEST;So;0;L;;;;;N;;;;;\n1D9B2;SIGNWRITING ROTATION-WALLPLANE DOUBLE HITTING CHEST;So;0;L;;;;;N;;;;;\n1D9B3;SIGNWRITING ROTATION-WALLPLANE ALTERNATING HITTING CHEST;So;0;L;;;;;N;;;;;\n1D9B4;SIGNWRITING MOVEMENT-WALLPLANE WAVE DIAGONAL PATH SMALL;So;0;L;;;;;N;;;;;\n1D9B5;SIGNWRITING MOVEMENT-WALLPLANE WAVE DIAGONAL PATH MEDIUM;So;0;L;;;;;N;;;;;\n1D9B6;SIGNWRITING MOVEMENT-WALLPLANE WAVE DIAGONAL PATH LARGE;So;0;L;;;;;N;;;;;\n1D9B7;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING CEILING SMALL;So;0;L;;;;;N;;;;;\n1D9B8;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING CEILING LARGE;So;0;L;;;;;N;;;;;\n1D9B9;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING SMALL DOUBLE;So;0;L;;;;;N;;;;;\n1D9BA;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING LARGE DOUBLE;So;0;L;;;;;N;;;;;\n1D9BB;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING SMALL TRIPLE;So;0;L;;;;;N;;;;;\n1D9BC;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING CEILING LARGE TRIPLE;So;0;L;;;;;N;;;;;\n1D9BD;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING SMALL SINGLE;So;0;L;;;;;N;;;;;\n1D9BE;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING LARGE SINGLE;So;0;L;;;;;N;;;;;\n1D9BF;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING SMALL DOUBLE;So;0;L;;;;;N;;;;;\n1D9C0;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING CEILING LARGE DOUBLE;So;0;L;;;;;N;;;;;\n1D9C1;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING CEILING SMALL;So;0;L;;;;;N;;;;;\n1D9C2;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING CEILING LARGE;So;0;L;;;;;N;;;;;\n1D9C3;SIGNWRITING ROTATION-FLOORPLANE SINGLE HITTING CEILING;So;0;L;;;;;N;;;;;\n1D9C4;SIGNWRITING ROTATION-FLOORPLANE DOUBLE HITTING CEILING;So;0;L;;;;;N;;;;;\n1D9C5;SIGNWRITING ROTATION-FLOORPLANE ALTERNATING HITTING CEILING;So;0;L;;;;;N;;;;;\n1D9C6;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING FLOOR SMALL;So;0;L;;;;;N;;;;;\n1D9C7;SIGNWRITING MOVEMENT-FLOORPLANE CURVE HITTING FLOOR LARGE;So;0;L;;;;;N;;;;;\n1D9C8;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR SMALL DOUBLE;So;0;L;;;;;N;;;;;\n1D9C9;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR LARGE DOUBLE;So;0;L;;;;;N;;;;;\n1D9CA;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR TRIPLE SMALL TRIPLE;So;0;L;;;;;N;;;;;\n1D9CB;SIGNWRITING MOVEMENT-FLOORPLANE HUMP HITTING FLOOR TRIPLE LARGE TRIPLE;So;0;L;;;;;N;;;;;\n1D9CC;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR SMALL SINGLE;So;0;L;;;;;N;;;;;\n1D9CD;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR LARGE SINGLE;So;0;L;;;;;N;;;;;\n1D9CE;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR SMALL DOUBLE;So;0;L;;;;;N;;;;;\n1D9CF;SIGNWRITING MOVEMENT-FLOORPLANE LOOP HITTING FLOOR LARGE DOUBLE;So;0;L;;;;;N;;;;;\n1D9D0;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING FLOOR SMALL;So;0;L;;;;;N;;;;;\n1D9D1;SIGNWRITING MOVEMENT-FLOORPLANE WAVE HITTING FLOOR LARGE;So;0;L;;;;;N;;;;;\n1D9D2;SIGNWRITING ROTATION-FLOORPLANE SINGLE HITTING FLOOR;So;0;L;;;;;N;;;;;\n1D9D3;SIGNWRITING ROTATION-FLOORPLANE DOUBLE HITTING FLOOR;So;0;L;;;;;N;;;;;\n1D9D4;SIGNWRITING ROTATION-FLOORPLANE ALTERNATING HITTING FLOOR;So;0;L;;;;;N;;;;;\n1D9D5;SIGNWRITING MOVEMENT-FLOORPLANE CURVE SMALL;So;0;L;;;;;N;;;;;\n1D9D6;SIGNWRITING MOVEMENT-FLOORPLANE CURVE MEDIUM;So;0;L;;;;;N;;;;;\n1D9D7;SIGNWRITING MOVEMENT-FLOORPLANE CURVE LARGE;So;0;L;;;;;N;;;;;\n1D9D8;SIGNWRITING MOVEMENT-FLOORPLANE CURVE LARGEST;So;0;L;;;;;N;;;;;\n1D9D9;SIGNWRITING MOVEMENT-FLOORPLANE CURVE COMBINED;So;0;L;;;;;N;;;;;\n1D9DA;SIGNWRITING MOVEMENT-FLOORPLANE HUMP SMALL;So;0;L;;;;;N;;;;;\n1D9DB;SIGNWRITING MOVEMENT-FLOORPLANE LOOP SMALL;So;0;L;;;;;N;;;;;\n1D9DC;SIGNWRITING MOVEMENT-FLOORPLANE WAVE SNAKE;So;0;L;;;;;N;;;;;\n1D9DD;SIGNWRITING MOVEMENT-FLOORPLANE WAVE SMALL;So;0;L;;;;;N;;;;;\n1D9DE;SIGNWRITING MOVEMENT-FLOORPLANE WAVE LARGE;So;0;L;;;;;N;;;;;\n1D9DF;SIGNWRITING ROTATION-FLOORPLANE SINGLE;So;0;L;;;;;N;;;;;\n1D9E0;SIGNWRITING ROTATION-FLOORPLANE DOUBLE;So;0;L;;;;;N;;;;;\n1D9E1;SIGNWRITING ROTATION-FLOORPLANE ALTERNATING;So;0;L;;;;;N;;;;;\n1D9E2;SIGNWRITING MOVEMENT-FLOORPLANE SHAKING PARALLEL;So;0;L;;;;;N;;;;;\n1D9E3;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE SMALL SINGLE;So;0;L;;;;;N;;;;;\n1D9E4;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE MEDIUM SINGLE;So;0;L;;;;;N;;;;;\n1D9E5;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE SMALL DOUBLE;So;0;L;;;;;N;;;;;\n1D9E6;SIGNWRITING MOVEMENT-WALLPLANE ARM CIRCLE MEDIUM DOUBLE;So;0;L;;;;;N;;;;;\n1D9E7;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL SMALL SINGLE;So;0;L;;;;;N;;;;;\n1D9E8;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL MEDIUM SINGLE;So;0;L;;;;;N;;;;;\n1D9E9;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL LARGE SINGLE;So;0;L;;;;;N;;;;;\n1D9EA;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL SMALL DOUBLE;So;0;L;;;;;N;;;;;\n1D9EB;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL MEDIUM DOUBLE;So;0;L;;;;;N;;;;;\n1D9EC;SIGNWRITING MOVEMENT-FLOORPLANE ARM CIRCLE HITTING WALL LARGE DOUBLE;So;0;L;;;;;N;;;;;\n1D9ED;SIGNWRITING MOVEMENT-WALLPLANE WRIST CIRCLE FRONT SINGLE;So;0;L;;;;;N;;;;;\n1D9EE;SIGNWRITING MOVEMENT-WALLPLANE WRIST CIRCLE FRONT DOUBLE;So;0;L;;;;;N;;;;;\n1D9EF;SIGNWRITING MOVEMENT-FLOORPLANE WRIST CIRCLE HITTING WALL SINGLE;So;0;L;;;;;N;;;;;\n1D9F0;SIGNWRITING MOVEMENT-FLOORPLANE WRIST CIRCLE HITTING WALL DOUBLE;So;0;L;;;;;N;;;;;\n1D9F1;SIGNWRITING MOVEMENT-WALLPLANE FINGER CIRCLES SINGLE;So;0;L;;;;;N;;;;;\n1D9F2;SIGNWRITING MOVEMENT-WALLPLANE FINGER CIRCLES DOUBLE;So;0;L;;;;;N;;;;;\n1D9F3;SIGNWRITING MOVEMENT-FLOORPLANE FINGER CIRCLES HITTING WALL SINGLE;So;0;L;;;;;N;;;;;\n1D9F4;SIGNWRITING MOVEMENT-FLOORPLANE FINGER CIRCLES HITTING WALL DOUBLE;So;0;L;;;;;N;;;;;\n1D9F5;SIGNWRITING DYNAMIC ARROWHEAD SMALL;So;0;L;;;;;N;;;;;\n1D9F6;SIGNWRITING DYNAMIC ARROWHEAD LARGE;So;0;L;;;;;N;;;;;\n1D9F7;SIGNWRITING DYNAMIC FAST;So;0;L;;;;;N;;;;;\n1D9F8;SIGNWRITING DYNAMIC SLOW;So;0;L;;;;;N;;;;;\n1D9F9;SIGNWRITING DYNAMIC TENSE;So;0;L;;;;;N;;;;;\n1D9FA;SIGNWRITING DYNAMIC RELAXED;So;0;L;;;;;N;;;;;\n1D9FB;SIGNWRITING DYNAMIC SIMULTANEOUS;So;0;L;;;;;N;;;;;\n1D9FC;SIGNWRITING DYNAMIC SIMULTANEOUS ALTERNATING;So;0;L;;;;;N;;;;;\n1D9FD;SIGNWRITING DYNAMIC EVERY OTHER TIME;So;0;L;;;;;N;;;;;\n1D9FE;SIGNWRITING DYNAMIC GRADUAL;So;0;L;;;;;N;;;;;\n1D9FF;SIGNWRITING HEAD;So;0;L;;;;;N;;;;;\n1DA00;SIGNWRITING HEAD RIM;Mn;0;NSM;;;;;N;;;;;\n1DA01;SIGNWRITING HEAD MOVEMENT-WALLPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;;\n1DA02;SIGNWRITING HEAD MOVEMENT-WALLPLANE TILT;Mn;0;NSM;;;;;N;;;;;\n1DA03;SIGNWRITING HEAD MOVEMENT-FLOORPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;;\n1DA04;SIGNWRITING HEAD MOVEMENT-WALLPLANE CURVE;Mn;0;NSM;;;;;N;;;;;\n1DA05;SIGNWRITING HEAD MOVEMENT-FLOORPLANE CURVE;Mn;0;NSM;;;;;N;;;;;\n1DA06;SIGNWRITING HEAD MOVEMENT CIRCLE;Mn;0;NSM;;;;;N;;;;;\n1DA07;SIGNWRITING FACE DIRECTION POSITION NOSE FORWARD TILTING;Mn;0;NSM;;;;;N;;;;;\n1DA08;SIGNWRITING FACE DIRECTION POSITION NOSE UP OR DOWN;Mn;0;NSM;;;;;N;;;;;\n1DA09;SIGNWRITING FACE DIRECTION POSITION NOSE UP OR DOWN TILTING;Mn;0;NSM;;;;;N;;;;;\n1DA0A;SIGNWRITING EYEBROWS STRAIGHT UP;Mn;0;NSM;;;;;N;;;;;\n1DA0B;SIGNWRITING EYEBROWS STRAIGHT NEUTRAL;Mn;0;NSM;;;;;N;;;;;\n1DA0C;SIGNWRITING EYEBROWS STRAIGHT DOWN;Mn;0;NSM;;;;;N;;;;;\n1DA0D;SIGNWRITING DREAMY EYEBROWS NEUTRAL DOWN;Mn;0;NSM;;;;;N;;;;;\n1DA0E;SIGNWRITING DREAMY EYEBROWS DOWN NEUTRAL;Mn;0;NSM;;;;;N;;;;;\n1DA0F;SIGNWRITING DREAMY EYEBROWS UP NEUTRAL;Mn;0;NSM;;;;;N;;;;;\n1DA10;SIGNWRITING DREAMY EYEBROWS NEUTRAL UP;Mn;0;NSM;;;;;N;;;;;\n1DA11;SIGNWRITING FOREHEAD NEUTRAL;Mn;0;NSM;;;;;N;;;;;\n1DA12;SIGNWRITING FOREHEAD CONTACT;Mn;0;NSM;;;;;N;;;;;\n1DA13;SIGNWRITING FOREHEAD WRINKLED;Mn;0;NSM;;;;;N;;;;;\n1DA14;SIGNWRITING EYES OPEN;Mn;0;NSM;;;;;N;;;;;\n1DA15;SIGNWRITING EYES SQUEEZED;Mn;0;NSM;;;;;N;;;;;\n1DA16;SIGNWRITING EYES CLOSED;Mn;0;NSM;;;;;N;;;;;\n1DA17;SIGNWRITING EYE BLINK SINGLE;Mn;0;NSM;;;;;N;;;;;\n1DA18;SIGNWRITING EYE BLINK MULTIPLE;Mn;0;NSM;;;;;N;;;;;\n1DA19;SIGNWRITING EYES HALF OPEN;Mn;0;NSM;;;;;N;;;;;\n1DA1A;SIGNWRITING EYES WIDE OPEN;Mn;0;NSM;;;;;N;;;;;\n1DA1B;SIGNWRITING EYES HALF CLOSED;Mn;0;NSM;;;;;N;;;;;\n1DA1C;SIGNWRITING EYES WIDENING MOVEMENT;Mn;0;NSM;;;;;N;;;;;\n1DA1D;SIGNWRITING EYE WINK;Mn;0;NSM;;;;;N;;;;;\n1DA1E;SIGNWRITING EYELASHES UP;Mn;0;NSM;;;;;N;;;;;\n1DA1F;SIGNWRITING EYELASHES DOWN;Mn;0;NSM;;;;;N;;;;;\n1DA20;SIGNWRITING EYELASHES FLUTTERING;Mn;0;NSM;;;;;N;;;;;\n1DA21;SIGNWRITING EYEGAZE-WALLPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;;\n1DA22;SIGNWRITING EYEGAZE-WALLPLANE STRAIGHT DOUBLE;Mn;0;NSM;;;;;N;;;;;\n1DA23;SIGNWRITING EYEGAZE-WALLPLANE STRAIGHT ALTERNATING;Mn;0;NSM;;;;;N;;;;;\n1DA24;SIGNWRITING EYEGAZE-FLOORPLANE STRAIGHT;Mn;0;NSM;;;;;N;;;;;\n1DA25;SIGNWRITING EYEGAZE-FLOORPLANE STRAIGHT DOUBLE;Mn;0;NSM;;;;;N;;;;;\n1DA26;SIGNWRITING EYEGAZE-FLOORPLANE STRAIGHT ALTERNATING;Mn;0;NSM;;;;;N;;;;;\n1DA27;SIGNWRITING EYEGAZE-WALLPLANE CURVED;Mn;0;NSM;;;;;N;;;;;\n1DA28;SIGNWRITING EYEGAZE-FLOORPLANE CURVED;Mn;0;NSM;;;;;N;;;;;\n1DA29;SIGNWRITING EYEGAZE-WALLPLANE CIRCLING;Mn;0;NSM;;;;;N;;;;;\n1DA2A;SIGNWRITING CHEEKS PUFFED;Mn;0;NSM;;;;;N;;;;;\n1DA2B;SIGNWRITING CHEEKS NEUTRAL;Mn;0;NSM;;;;;N;;;;;\n1DA2C;SIGNWRITING CHEEKS SUCKED;Mn;0;NSM;;;;;N;;;;;\n1DA2D;SIGNWRITING TENSE CHEEKS HIGH;Mn;0;NSM;;;;;N;;;;;\n1DA2E;SIGNWRITING TENSE CHEEKS MIDDLE;Mn;0;NSM;;;;;N;;;;;\n1DA2F;SIGNWRITING TENSE CHEEKS LOW;Mn;0;NSM;;;;;N;;;;;\n1DA30;SIGNWRITING EARS;Mn;0;NSM;;;;;N;;;;;\n1DA31;SIGNWRITING NOSE NEUTRAL;Mn;0;NSM;;;;;N;;;;;\n1DA32;SIGNWRITING NOSE CONTACT;Mn;0;NSM;;;;;N;;;;;\n1DA33;SIGNWRITING NOSE WRINKLES;Mn;0;NSM;;;;;N;;;;;\n1DA34;SIGNWRITING NOSE WIGGLES;Mn;0;NSM;;;;;N;;;;;\n1DA35;SIGNWRITING AIR BLOWING OUT;Mn;0;NSM;;;;;N;;;;;\n1DA36;SIGNWRITING AIR SUCKING IN;Mn;0;NSM;;;;;N;;;;;\n1DA37;SIGNWRITING AIR BLOW SMALL ROTATIONS;So;0;L;;;;;N;;;;;\n1DA38;SIGNWRITING AIR SUCK SMALL ROTATIONS;So;0;L;;;;;N;;;;;\n1DA39;SIGNWRITING BREATH INHALE;So;0;L;;;;;N;;;;;\n1DA3A;SIGNWRITING BREATH EXHALE;So;0;L;;;;;N;;;;;\n1DA3B;SIGNWRITING MOUTH CLOSED NEUTRAL;Mn;0;NSM;;;;;N;;;;;\n1DA3C;SIGNWRITING MOUTH CLOSED FORWARD;Mn;0;NSM;;;;;N;;;;;\n1DA3D;SIGNWRITING MOUTH CLOSED CONTACT;Mn;0;NSM;;;;;N;;;;;\n1DA3E;SIGNWRITING MOUTH SMILE;Mn;0;NSM;;;;;N;;;;;\n1DA3F;SIGNWRITING MOUTH SMILE WRINKLED;Mn;0;NSM;;;;;N;;;;;\n1DA40;SIGNWRITING MOUTH SMILE OPEN;Mn;0;NSM;;;;;N;;;;;\n1DA41;SIGNWRITING MOUTH FROWN;Mn;0;NSM;;;;;N;;;;;\n1DA42;SIGNWRITING MOUTH FROWN WRINKLED;Mn;0;NSM;;;;;N;;;;;\n1DA43;SIGNWRITING MOUTH FROWN OPEN;Mn;0;NSM;;;;;N;;;;;\n1DA44;SIGNWRITING MOUTH OPEN CIRCLE;Mn;0;NSM;;;;;N;;;;;\n1DA45;SIGNWRITING MOUTH OPEN FORWARD;Mn;0;NSM;;;;;N;;;;;\n1DA46;SIGNWRITING MOUTH OPEN WRINKLED;Mn;0;NSM;;;;;N;;;;;\n1DA47;SIGNWRITING MOUTH OPEN OVAL;Mn;0;NSM;;;;;N;;;;;\n1DA48;SIGNWRITING MOUTH OPEN OVAL WRINKLED;Mn;0;NSM;;;;;N;;;;;\n1DA49;SIGNWRITING MOUTH OPEN OVAL YAWN;Mn;0;NSM;;;;;N;;;;;\n1DA4A;SIGNWRITING MOUTH OPEN RECTANGLE;Mn;0;NSM;;;;;N;;;;;\n1DA4B;SIGNWRITING MOUTH OPEN RECTANGLE WRINKLED;Mn;0;NSM;;;;;N;;;;;\n1DA4C;SIGNWRITING MOUTH OPEN RECTANGLE YAWN;Mn;0;NSM;;;;;N;;;;;\n1DA4D;SIGNWRITING MOUTH KISS;Mn;0;NSM;;;;;N;;;;;\n1DA4E;SIGNWRITING MOUTH KISS FORWARD;Mn;0;NSM;;;;;N;;;;;\n1DA4F;SIGNWRITING MOUTH KISS WRINKLED;Mn;0;NSM;;;;;N;;;;;\n1DA50;SIGNWRITING MOUTH TENSE;Mn;0;NSM;;;;;N;;;;;\n1DA51;SIGNWRITING MOUTH TENSE FORWARD;Mn;0;NSM;;;;;N;;;;;\n1DA52;SIGNWRITING MOUTH TENSE SUCKED;Mn;0;NSM;;;;;N;;;;;\n1DA53;SIGNWRITING LIPS PRESSED TOGETHER;Mn;0;NSM;;;;;N;;;;;\n1DA54;SIGNWRITING LIP LOWER OVER UPPER;Mn;0;NSM;;;;;N;;;;;\n1DA55;SIGNWRITING LIP UPPER OVER LOWER;Mn;0;NSM;;;;;N;;;;;\n1DA56;SIGNWRITING MOUTH CORNERS;Mn;0;NSM;;;;;N;;;;;\n1DA57;SIGNWRITING MOUTH WRINKLES SINGLE;Mn;0;NSM;;;;;N;;;;;\n1DA58;SIGNWRITING MOUTH WRINKLES DOUBLE;Mn;0;NSM;;;;;N;;;;;\n1DA59;SIGNWRITING TONGUE STICKING OUT FAR;Mn;0;NSM;;;;;N;;;;;\n1DA5A;SIGNWRITING TONGUE LICKING LIPS;Mn;0;NSM;;;;;N;;;;;\n1DA5B;SIGNWRITING TONGUE TIP BETWEEN LIPS;Mn;0;NSM;;;;;N;;;;;\n1DA5C;SIGNWRITING TONGUE TIP TOUCHING INSIDE MOUTH;Mn;0;NSM;;;;;N;;;;;\n1DA5D;SIGNWRITING TONGUE INSIDE MOUTH RELAXED;Mn;0;NSM;;;;;N;;;;;\n1DA5E;SIGNWRITING TONGUE MOVES AGAINST CHEEK;Mn;0;NSM;;;;;N;;;;;\n1DA5F;SIGNWRITING TONGUE CENTRE STICKING OUT;Mn;0;NSM;;;;;N;;;;;\n1DA60;SIGNWRITING TONGUE CENTRE INSIDE MOUTH;Mn;0;NSM;;;;;N;;;;;\n1DA61;SIGNWRITING TEETH;Mn;0;NSM;;;;;N;;;;;\n1DA62;SIGNWRITING TEETH MOVEMENT;Mn;0;NSM;;;;;N;;;;;\n1DA63;SIGNWRITING TEETH ON TONGUE;Mn;0;NSM;;;;;N;;;;;\n1DA64;SIGNWRITING TEETH ON TONGUE MOVEMENT;Mn;0;NSM;;;;;N;;;;;\n1DA65;SIGNWRITING TEETH ON LIPS;Mn;0;NSM;;;;;N;;;;;\n1DA66;SIGNWRITING TEETH ON LIPS MOVEMENT;Mn;0;NSM;;;;;N;;;;;\n1DA67;SIGNWRITING TEETH BITE LIPS;Mn;0;NSM;;;;;N;;;;;\n1DA68;SIGNWRITING MOVEMENT-WALLPLANE JAW;Mn;0;NSM;;;;;N;;;;;\n1DA69;SIGNWRITING MOVEMENT-FLOORPLANE JAW;Mn;0;NSM;;;;;N;;;;;\n1DA6A;SIGNWRITING NECK;Mn;0;NSM;;;;;N;;;;;\n1DA6B;SIGNWRITING HAIR;Mn;0;NSM;;;;;N;;;;;\n1DA6C;SIGNWRITING EXCITEMENT;Mn;0;NSM;;;;;N;;;;;\n1DA6D;SIGNWRITING SHOULDER HIP SPINE;So;0;L;;;;;N;;;;;\n1DA6E;SIGNWRITING SHOULDER HIP POSITIONS;So;0;L;;;;;N;;;;;\n1DA6F;SIGNWRITING WALLPLANE SHOULDER HIP MOVE;So;0;L;;;;;N;;;;;\n1DA70;SIGNWRITING FLOORPLANE SHOULDER HIP MOVE;So;0;L;;;;;N;;;;;\n1DA71;SIGNWRITING SHOULDER TILTING FROM WAIST;So;0;L;;;;;N;;;;;\n1DA72;SIGNWRITING TORSO-WALLPLANE STRAIGHT STRETCH;So;0;L;;;;;N;;;;;\n1DA73;SIGNWRITING TORSO-WALLPLANE CURVED BEND;So;0;L;;;;;N;;;;;\n1DA74;SIGNWRITING TORSO-FLOORPLANE TWISTING;So;0;L;;;;;N;;;;;\n1DA75;SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS;Mn;0;NSM;;;;;N;;;;;\n1DA76;SIGNWRITING LIMB COMBINATION;So;0;L;;;;;N;;;;;\n1DA77;SIGNWRITING LIMB LENGTH-1;So;0;L;;;;;N;;;;;\n1DA78;SIGNWRITING LIMB LENGTH-2;So;0;L;;;;;N;;;;;\n1DA79;SIGNWRITING LIMB LENGTH-3;So;0;L;;;;;N;;;;;\n1DA7A;SIGNWRITING LIMB LENGTH-4;So;0;L;;;;;N;;;;;\n1DA7B;SIGNWRITING LIMB LENGTH-5;So;0;L;;;;;N;;;;;\n1DA7C;SIGNWRITING LIMB LENGTH-6;So;0;L;;;;;N;;;;;\n1DA7D;SIGNWRITING LIMB LENGTH-7;So;0;L;;;;;N;;;;;\n1DA7E;SIGNWRITING FINGER;So;0;L;;;;;N;;;;;\n1DA7F;SIGNWRITING LOCATION-WALLPLANE SPACE;So;0;L;;;;;N;;;;;\n1DA80;SIGNWRITING LOCATION-FLOORPLANE SPACE;So;0;L;;;;;N;;;;;\n1DA81;SIGNWRITING LOCATION HEIGHT;So;0;L;;;;;N;;;;;\n1DA82;SIGNWRITING LOCATION WIDTH;So;0;L;;;;;N;;;;;\n1DA83;SIGNWRITING LOCATION DEPTH;So;0;L;;;;;N;;;;;\n1DA84;SIGNWRITING LOCATION HEAD NECK;Mn;0;NSM;;;;;N;;;;;\n1DA85;SIGNWRITING LOCATION TORSO;So;0;L;;;;;N;;;;;\n1DA86;SIGNWRITING LOCATION LIMBS DIGITS;So;0;L;;;;;N;;;;;\n1DA87;SIGNWRITING COMMA;Po;0;L;;;;;N;;;;;\n1DA88;SIGNWRITING FULL STOP;Po;0;L;;;;;N;;;;;\n1DA89;SIGNWRITING SEMICOLON;Po;0;L;;;;;N;;;;;\n1DA8A;SIGNWRITING COLON;Po;0;L;;;;;N;;;;;\n1DA8B;SIGNWRITING PARENTHESIS;Po;0;L;;;;;N;;;;;\n1DA9B;SIGNWRITING FILL MODIFIER-2;Mn;0;NSM;;;;;N;;;;;\n1DA9C;SIGNWRITING FILL MODIFIER-3;Mn;0;NSM;;;;;N;;;;;\n1DA9D;SIGNWRITING FILL MODIFIER-4;Mn;0;NSM;;;;;N;;;;;\n1DA9E;SIGNWRITING FILL MODIFIER-5;Mn;0;NSM;;;;;N;;;;;\n1DA9F;SIGNWRITING FILL MODIFIER-6;Mn;0;NSM;;;;;N;;;;;\n1DAA1;SIGNWRITING ROTATION MODIFIER-2;Mn;0;NSM;;;;;N;;;;;\n1DAA2;SIGNWRITING ROTATION MODIFIER-3;Mn;0;NSM;;;;;N;;;;;\n1DAA3;SIGNWRITING ROTATION MODIFIER-4;Mn;0;NSM;;;;;N;;;;;\n1DAA4;SIGNWRITING ROTATION MODIFIER-5;Mn;0;NSM;;;;;N;;;;;\n1DAA5;SIGNWRITING ROTATION MODIFIER-6;Mn;0;NSM;;;;;N;;;;;\n1DAA6;SIGNWRITING ROTATION MODIFIER-7;Mn;0;NSM;;;;;N;;;;;\n1DAA7;SIGNWRITING ROTATION MODIFIER-8;Mn;0;NSM;;;;;N;;;;;\n1DAA8;SIGNWRITING ROTATION MODIFIER-9;Mn;0;NSM;;;;;N;;;;;\n1DAA9;SIGNWRITING ROTATION MODIFIER-10;Mn;0;NSM;;;;;N;;;;;\n1DAAA;SIGNWRITING ROTATION MODIFIER-11;Mn;0;NSM;;;;;N;;;;;\n1DAAB;SIGNWRITING ROTATION MODIFIER-12;Mn;0;NSM;;;;;N;;;;;\n1DAAC;SIGNWRITING ROTATION MODIFIER-13;Mn;0;NSM;;;;;N;;;;;\n1DAAD;SIGNWRITING ROTATION MODIFIER-14;Mn;0;NSM;;;;;N;;;;;\n1DAAE;SIGNWRITING ROTATION MODIFIER-15;Mn;0;NSM;;;;;N;;;;;\n1DAAF;SIGNWRITING ROTATION MODIFIER-16;Mn;0;NSM;;;;;N;;;;;\n1E000;COMBINING GLAGOLITIC LETTER AZU;Mn;230;NSM;;;;;N;;;;;\n1E001;COMBINING GLAGOLITIC LETTER BUKY;Mn;230;NSM;;;;;N;;;;;\n1E002;COMBINING GLAGOLITIC LETTER VEDE;Mn;230;NSM;;;;;N;;;;;\n1E003;COMBINING GLAGOLITIC LETTER GLAGOLI;Mn;230;NSM;;;;;N;;;;;\n1E004;COMBINING GLAGOLITIC LETTER DOBRO;Mn;230;NSM;;;;;N;;;;;\n1E005;COMBINING GLAGOLITIC LETTER YESTU;Mn;230;NSM;;;;;N;;;;;\n1E006;COMBINING GLAGOLITIC LETTER ZHIVETE;Mn;230;NSM;;;;;N;;;;;\n1E008;COMBINING GLAGOLITIC LETTER ZEMLJA;Mn;230;NSM;;;;;N;;;;;\n1E009;COMBINING GLAGOLITIC LETTER IZHE;Mn;230;NSM;;;;;N;;;;;\n1E00A;COMBINING GLAGOLITIC LETTER INITIAL IZHE;Mn;230;NSM;;;;;N;;;;;\n1E00B;COMBINING GLAGOLITIC LETTER I;Mn;230;NSM;;;;;N;;;;;\n1E00C;COMBINING GLAGOLITIC LETTER DJERVI;Mn;230;NSM;;;;;N;;;;;\n1E00D;COMBINING GLAGOLITIC LETTER KAKO;Mn;230;NSM;;;;;N;;;;;\n1E00E;COMBINING GLAGOLITIC LETTER LJUDIJE;Mn;230;NSM;;;;;N;;;;;\n1E00F;COMBINING GLAGOLITIC LETTER MYSLITE;Mn;230;NSM;;;;;N;;;;;\n1E010;COMBINING GLAGOLITIC LETTER NASHI;Mn;230;NSM;;;;;N;;;;;\n1E011;COMBINING GLAGOLITIC LETTER ONU;Mn;230;NSM;;;;;N;;;;;\n1E012;COMBINING GLAGOLITIC LETTER POKOJI;Mn;230;NSM;;;;;N;;;;;\n1E013;COMBINING GLAGOLITIC LETTER RITSI;Mn;230;NSM;;;;;N;;;;;\n1E014;COMBINING GLAGOLITIC LETTER SLOVO;Mn;230;NSM;;;;;N;;;;;\n1E015;COMBINING GLAGOLITIC LETTER TVRIDO;Mn;230;NSM;;;;;N;;;;;\n1E016;COMBINING GLAGOLITIC LETTER UKU;Mn;230;NSM;;;;;N;;;;;\n1E017;COMBINING GLAGOLITIC LETTER FRITU;Mn;230;NSM;;;;;N;;;;;\n1E018;COMBINING GLAGOLITIC LETTER HERU;Mn;230;NSM;;;;;N;;;;;\n1E01B;COMBINING GLAGOLITIC LETTER SHTA;Mn;230;NSM;;;;;N;;;;;\n1E01C;COMBINING GLAGOLITIC LETTER TSI;Mn;230;NSM;;;;;N;;;;;\n1E01D;COMBINING GLAGOLITIC LETTER CHRIVI;Mn;230;NSM;;;;;N;;;;;\n1E01E;COMBINING GLAGOLITIC LETTER SHA;Mn;230;NSM;;;;;N;;;;;\n1E01F;COMBINING GLAGOLITIC LETTER YERU;Mn;230;NSM;;;;;N;;;;;\n1E020;COMBINING GLAGOLITIC LETTER YERI;Mn;230;NSM;;;;;N;;;;;\n1E021;COMBINING GLAGOLITIC LETTER YATI;Mn;230;NSM;;;;;N;;;;;\n1E023;COMBINING GLAGOLITIC LETTER YU;Mn;230;NSM;;;;;N;;;;;\n1E024;COMBINING GLAGOLITIC LETTER SMALL YUS;Mn;230;NSM;;;;;N;;;;;\n1E026;COMBINING GLAGOLITIC LETTER YO;Mn;230;NSM;;;;;N;;;;;\n1E027;COMBINING GLAGOLITIC LETTER IOTATED SMALL YUS;Mn;230;NSM;;;;;N;;;;;\n1E028;COMBINING GLAGOLITIC LETTER BIG YUS;Mn;230;NSM;;;;;N;;;;;\n1E029;COMBINING GLAGOLITIC LETTER IOTATED BIG YUS;Mn;230;NSM;;;;;N;;;;;\n1E02A;COMBINING GLAGOLITIC LETTER FITA;Mn;230;NSM;;;;;N;;;;;\n1E100;NYIAKENG PUACHUE HMONG LETTER MA;Lo;0;L;;;;;N;;;;;\n1E101;NYIAKENG PUACHUE HMONG LETTER TSA;Lo;0;L;;;;;N;;;;;\n1E102;NYIAKENG PUACHUE HMONG LETTER NTA;Lo;0;L;;;;;N;;;;;\n1E103;NYIAKENG PUACHUE HMONG LETTER TA;Lo;0;L;;;;;N;;;;;\n1E104;NYIAKENG PUACHUE HMONG LETTER HA;Lo;0;L;;;;;N;;;;;\n1E105;NYIAKENG PUACHUE HMONG LETTER NA;Lo;0;L;;;;;N;;;;;\n1E106;NYIAKENG PUACHUE HMONG LETTER XA;Lo;0;L;;;;;N;;;;;\n1E107;NYIAKENG PUACHUE HMONG LETTER NKA;Lo;0;L;;;;;N;;;;;\n1E108;NYIAKENG PUACHUE HMONG LETTER CA;Lo;0;L;;;;;N;;;;;\n1E109;NYIAKENG PUACHUE HMONG LETTER LA;Lo;0;L;;;;;N;;;;;\n1E10A;NYIAKENG PUACHUE HMONG LETTER SA;Lo;0;L;;;;;N;;;;;\n1E10B;NYIAKENG PUACHUE HMONG LETTER ZA;Lo;0;L;;;;;N;;;;;\n1E10C;NYIAKENG PUACHUE HMONG LETTER NCA;Lo;0;L;;;;;N;;;;;\n1E10D;NYIAKENG PUACHUE HMONG LETTER NTSA;Lo;0;L;;;;;N;;;;;\n1E10E;NYIAKENG PUACHUE HMONG LETTER KA;Lo;0;L;;;;;N;;;;;\n1E10F;NYIAKENG PUACHUE HMONG LETTER DA;Lo;0;L;;;;;N;;;;;\n1E110;NYIAKENG PUACHUE HMONG LETTER NYA;Lo;0;L;;;;;N;;;;;\n1E111;NYIAKENG PUACHUE HMONG LETTER NRA;Lo;0;L;;;;;N;;;;;\n1E112;NYIAKENG PUACHUE HMONG LETTER VA;Lo;0;L;;;;;N;;;;;\n1E113;NYIAKENG PUACHUE HMONG LETTER NTXA;Lo;0;L;;;;;N;;;;;\n1E114;NYIAKENG PUACHUE HMONG LETTER TXA;Lo;0;L;;;;;N;;;;;\n1E115;NYIAKENG PUACHUE HMONG LETTER FA;Lo;0;L;;;;;N;;;;;\n1E116;NYIAKENG PUACHUE HMONG LETTER RA;Lo;0;L;;;;;N;;;;;\n1E117;NYIAKENG PUACHUE HMONG LETTER QA;Lo;0;L;;;;;N;;;;;\n1E118;NYIAKENG PUACHUE HMONG LETTER YA;Lo;0;L;;;;;N;;;;;\n1E119;NYIAKENG PUACHUE HMONG LETTER NQA;Lo;0;L;;;;;N;;;;;\n1E11A;NYIAKENG PUACHUE HMONG LETTER PA;Lo;0;L;;;;;N;;;;;\n1E11B;NYIAKENG PUACHUE HMONG LETTER XYA;Lo;0;L;;;;;N;;;;;\n1E11C;NYIAKENG PUACHUE HMONG LETTER NPA;Lo;0;L;;;;;N;;;;;\n1E11D;NYIAKENG PUACHUE HMONG LETTER DLA;Lo;0;L;;;;;N;;;;;\n1E11E;NYIAKENG PUACHUE HMONG LETTER NPLA;Lo;0;L;;;;;N;;;;;\n1E11F;NYIAKENG PUACHUE HMONG LETTER HAH;Lo;0;L;;;;;N;;;;;\n1E120;NYIAKENG PUACHUE HMONG LETTER MLA;Lo;0;L;;;;;N;;;;;\n1E121;NYIAKENG PUACHUE HMONG LETTER PLA;Lo;0;L;;;;;N;;;;;\n1E122;NYIAKENG PUACHUE HMONG LETTER GA;Lo;0;L;;;;;N;;;;;\n1E123;NYIAKENG PUACHUE HMONG LETTER RRA;Lo;0;L;;;;;N;;;;;\n1E124;NYIAKENG PUACHUE HMONG LETTER A;Lo;0;L;;;;;N;;;;;\n1E125;NYIAKENG PUACHUE HMONG LETTER AA;Lo;0;L;;;;;N;;;;;\n1E126;NYIAKENG PUACHUE HMONG LETTER I;Lo;0;L;;;;;N;;;;;\n1E127;NYIAKENG PUACHUE HMONG LETTER U;Lo;0;L;;;;;N;;;;;\n1E128;NYIAKENG PUACHUE HMONG LETTER O;Lo;0;L;;;;;N;;;;;\n1E129;NYIAKENG PUACHUE HMONG LETTER OO;Lo;0;L;;;;;N;;;;;\n1E12A;NYIAKENG PUACHUE HMONG LETTER E;Lo;0;L;;;;;N;;;;;\n1E12B;NYIAKENG PUACHUE HMONG LETTER EE;Lo;0;L;;;;;N;;;;;\n1E12C;NYIAKENG PUACHUE HMONG LETTER W;Lo;0;L;;;;;N;;;;;\n1E130;NYIAKENG PUACHUE HMONG TONE-B;Mn;230;NSM;;;;;N;;;;;\n1E131;NYIAKENG PUACHUE HMONG TONE-M;Mn;230;NSM;;;;;N;;;;;\n1E132;NYIAKENG PUACHUE HMONG TONE-J;Mn;230;NSM;;;;;N;;;;;\n1E133;NYIAKENG PUACHUE HMONG TONE-V;Mn;230;NSM;;;;;N;;;;;\n1E134;NYIAKENG PUACHUE HMONG TONE-S;Mn;230;NSM;;;;;N;;;;;\n1E135;NYIAKENG PUACHUE HMONG TONE-G;Mn;230;NSM;;;;;N;;;;;\n1E136;NYIAKENG PUACHUE HMONG TONE-D;Mn;230;NSM;;;;;N;;;;;\n1E137;NYIAKENG PUACHUE HMONG SIGN FOR PERSON;Lm;0;L;;;;;N;;;;;\n1E138;NYIAKENG PUACHUE HMONG SIGN FOR THING;Lm;0;L;;;;;N;;;;;\n1E139;NYIAKENG PUACHUE HMONG SIGN FOR LOCATION;Lm;0;L;;;;;N;;;;;\n1E13A;NYIAKENG PUACHUE HMONG SIGN FOR ANIMAL;Lm;0;L;;;;;N;;;;;\n1E13B;NYIAKENG PUACHUE HMONG SIGN FOR INVERTEBRATE;Lm;0;L;;;;;N;;;;;\n1E13C;NYIAKENG PUACHUE HMONG SIGN XW XW;Lm;0;L;;;;;N;;;;;\n1E13D;NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER;Lm;0;L;;;;;N;;;;;\n1E140;NYIAKENG PUACHUE HMONG DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n1E141;NYIAKENG PUACHUE HMONG DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n1E142;NYIAKENG PUACHUE HMONG DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n1E143;NYIAKENG PUACHUE HMONG DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n1E144;NYIAKENG PUACHUE HMONG DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n1E145;NYIAKENG PUACHUE HMONG DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n1E146;NYIAKENG PUACHUE HMONG DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n1E147;NYIAKENG PUACHUE HMONG DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n1E148;NYIAKENG PUACHUE HMONG DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n1E149;NYIAKENG PUACHUE HMONG DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n1E14E;NYIAKENG PUACHUE HMONG LOGOGRAM NYAJ;Lo;0;L;;;;;N;;;;;\n1E14F;NYIAKENG PUACHUE HMONG CIRCLED CA;So;0;L;;;;;N;;;;;\n1E2C0;WANCHO LETTER AA;Lo;0;L;;;;;N;;;;;\n1E2C1;WANCHO LETTER A;Lo;0;L;;;;;N;;;;;\n1E2C2;WANCHO LETTER BA;Lo;0;L;;;;;N;;;;;\n1E2C3;WANCHO LETTER CA;Lo;0;L;;;;;N;;;;;\n1E2C4;WANCHO LETTER DA;Lo;0;L;;;;;N;;;;;\n1E2C5;WANCHO LETTER GA;Lo;0;L;;;;;N;;;;;\n1E2C6;WANCHO LETTER YA;Lo;0;L;;;;;N;;;;;\n1E2C7;WANCHO LETTER PHA;Lo;0;L;;;;;N;;;;;\n1E2C8;WANCHO LETTER LA;Lo;0;L;;;;;N;;;;;\n1E2C9;WANCHO LETTER NA;Lo;0;L;;;;;N;;;;;\n1E2CA;WANCHO LETTER PA;Lo;0;L;;;;;N;;;;;\n1E2CB;WANCHO LETTER TA;Lo;0;L;;;;;N;;;;;\n1E2CC;WANCHO LETTER THA;Lo;0;L;;;;;N;;;;;\n1E2CD;WANCHO LETTER FA;Lo;0;L;;;;;N;;;;;\n1E2CE;WANCHO LETTER SA;Lo;0;L;;;;;N;;;;;\n1E2CF;WANCHO LETTER SHA;Lo;0;L;;;;;N;;;;;\n1E2D0;WANCHO LETTER JA;Lo;0;L;;;;;N;;;;;\n1E2D1;WANCHO LETTER ZA;Lo;0;L;;;;;N;;;;;\n1E2D2;WANCHO LETTER WA;Lo;0;L;;;;;N;;;;;\n1E2D3;WANCHO LETTER VA;Lo;0;L;;;;;N;;;;;\n1E2D4;WANCHO LETTER KA;Lo;0;L;;;;;N;;;;;\n1E2D5;WANCHO LETTER O;Lo;0;L;;;;;N;;;;;\n1E2D6;WANCHO LETTER AU;Lo;0;L;;;;;N;;;;;\n1E2D7;WANCHO LETTER RA;Lo;0;L;;;;;N;;;;;\n1E2D8;WANCHO LETTER MA;Lo;0;L;;;;;N;;;;;\n1E2D9;WANCHO LETTER KHA;Lo;0;L;;;;;N;;;;;\n1E2DA;WANCHO LETTER HA;Lo;0;L;;;;;N;;;;;\n1E2DB;WANCHO LETTER E;Lo;0;L;;;;;N;;;;;\n1E2DC;WANCHO LETTER I;Lo;0;L;;;;;N;;;;;\n1E2DD;WANCHO LETTER NGA;Lo;0;L;;;;;N;;;;;\n1E2DE;WANCHO LETTER U;Lo;0;L;;;;;N;;;;;\n1E2DF;WANCHO LETTER LLHA;Lo;0;L;;;;;N;;;;;\n1E2E0;WANCHO LETTER TSA;Lo;0;L;;;;;N;;;;;\n1E2E1;WANCHO LETTER TRA;Lo;0;L;;;;;N;;;;;\n1E2E2;WANCHO LETTER ONG;Lo;0;L;;;;;N;;;;;\n1E2E3;WANCHO LETTER AANG;Lo;0;L;;;;;N;;;;;\n1E2E4;WANCHO LETTER ANG;Lo;0;L;;;;;N;;;;;\n1E2E5;WANCHO LETTER ING;Lo;0;L;;;;;N;;;;;\n1E2E6;WANCHO LETTER ON;Lo;0;L;;;;;N;;;;;\n1E2E7;WANCHO LETTER EN;Lo;0;L;;;;;N;;;;;\n1E2E8;WANCHO LETTER AAN;Lo;0;L;;;;;N;;;;;\n1E2E9;WANCHO LETTER NYA;Lo;0;L;;;;;N;;;;;\n1E2EA;WANCHO LETTER UEN;Lo;0;L;;;;;N;;;;;\n1E2EB;WANCHO LETTER YIH;Lo;0;L;;;;;N;;;;;\n1E2EC;WANCHO TONE TUP;Mn;230;NSM;;;;;N;;;;;\n1E2ED;WANCHO TONE TUPNI;Mn;230;NSM;;;;;N;;;;;\n1E2EE;WANCHO TONE KOI;Mn;230;NSM;;;;;N;;;;;\n1E2EF;WANCHO TONE KOINI;Mn;230;NSM;;;;;N;;;;;\n1E2F0;WANCHO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;;\n1E2F1;WANCHO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;\n1E2F2;WANCHO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;;\n1E2F3;WANCHO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;;\n1E2F4;WANCHO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;;\n1E2F5;WANCHO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;;\n1E2F6;WANCHO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;;\n1E2F7;WANCHO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;\n1E2F8;WANCHO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;\n1E2F9;WANCHO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;\n1E2FF;WANCHO NGUN SIGN;Sc;0;ET;;;;;N;;;;;\n1E800;MENDE KIKAKUI SYLLABLE M001 KI;Lo;0;R;;;;;N;;;;;\n1E801;MENDE KIKAKUI SYLLABLE M002 KA;Lo;0;R;;;;;N;;;;;\n1E802;MENDE KIKAKUI SYLLABLE M003 KU;Lo;0;R;;;;;N;;;;;\n1E803;MENDE KIKAKUI SYLLABLE M065 KEE;Lo;0;R;;;;;N;;;;;\n1E804;MENDE KIKAKUI SYLLABLE M095 KE;Lo;0;R;;;;;N;;;;;\n1E805;MENDE KIKAKUI SYLLABLE M076 KOO;Lo;0;R;;;;;N;;;;;\n1E806;MENDE KIKAKUI SYLLABLE M048 KO;Lo;0;R;;;;;N;;;;;\n1E807;MENDE KIKAKUI SYLLABLE M179 KUA;Lo;0;R;;;;;N;;;;;\n1E808;MENDE KIKAKUI SYLLABLE M004 WI;Lo;0;R;;;;;N;;;;;\n1E809;MENDE KIKAKUI SYLLABLE M005 WA;Lo;0;R;;;;;N;;;;;\n1E80A;MENDE KIKAKUI SYLLABLE M006 WU;Lo;0;R;;;;;N;;;;;\n1E80B;MENDE KIKAKUI SYLLABLE M126 WEE;Lo;0;R;;;;;N;;;;;\n1E80C;MENDE KIKAKUI SYLLABLE M118 WE;Lo;0;R;;;;;N;;;;;\n1E80D;MENDE KIKAKUI SYLLABLE M114 WOO;Lo;0;R;;;;;N;;;;;\n1E80E;MENDE KIKAKUI SYLLABLE M045 WO;Lo;0;R;;;;;N;;;;;\n1E80F;MENDE KIKAKUI SYLLABLE M194 WUI;Lo;0;R;;;;;N;;;;;\n1E810;MENDE KIKAKUI SYLLABLE M143 WEI;Lo;0;R;;;;;N;;;;;\n1E811;MENDE KIKAKUI SYLLABLE M061 WVI;Lo;0;R;;;;;N;;;;;\n1E812;MENDE KIKAKUI SYLLABLE M049 WVA;Lo;0;R;;;;;N;;;;;\n1E813;MENDE KIKAKUI SYLLABLE M139 WVE;Lo;0;R;;;;;N;;;;;\n1E814;MENDE KIKAKUI SYLLABLE M007 MIN;Lo;0;R;;;;;N;;;;;\n1E815;MENDE KIKAKUI SYLLABLE M008 MAN;Lo;0;R;;;;;N;;;;;\n1E816;MENDE KIKAKUI SYLLABLE M009 MUN;Lo;0;R;;;;;N;;;;;\n1E817;MENDE KIKAKUI SYLLABLE M059 MEN;Lo;0;R;;;;;N;;;;;\n1E818;MENDE KIKAKUI SYLLABLE M094 MON;Lo;0;R;;;;;N;;;;;\n1E819;MENDE KIKAKUI SYLLABLE M154 MUAN;Lo;0;R;;;;;N;;;;;\n1E81A;MENDE KIKAKUI SYLLABLE M189 MUEN;Lo;0;R;;;;;N;;;;;\n1E81B;MENDE KIKAKUI SYLLABLE M010 BI;Lo;0;R;;;;;N;;;;;\n1E81C;MENDE KIKAKUI SYLLABLE M011 BA;Lo;0;R;;;;;N;;;;;\n1E81D;MENDE KIKAKUI SYLLABLE M012 BU;Lo;0;R;;;;;N;;;;;\n1E81E;MENDE KIKAKUI SYLLABLE M150 BEE;Lo;0;R;;;;;N;;;;;\n1E81F;MENDE KIKAKUI SYLLABLE M097 BE;Lo;0;R;;;;;N;;;;;\n1E820;MENDE KIKAKUI SYLLABLE M103 BOO;Lo;0;R;;;;;N;;;;;\n1E821;MENDE KIKAKUI SYLLABLE M138 BO;Lo;0;R;;;;;N;;;;;\n1E822;MENDE KIKAKUI SYLLABLE M013 I;Lo;0;R;;;;;N;;;;;\n1E823;MENDE KIKAKUI SYLLABLE M014 A;Lo;0;R;;;;;N;;;;;\n1E824;MENDE KIKAKUI SYLLABLE M015 U;Lo;0;R;;;;;N;;;;;\n1E825;MENDE KIKAKUI SYLLABLE M163 EE;Lo;0;R;;;;;N;;;;;\n1E826;MENDE KIKAKUI SYLLABLE M100 E;Lo;0;R;;;;;N;;;;;\n1E827;MENDE KIKAKUI SYLLABLE M165 OO;Lo;0;R;;;;;N;;;;;\n1E828;MENDE KIKAKUI SYLLABLE M147 O;Lo;0;R;;;;;N;;;;;\n1E829;MENDE KIKAKUI SYLLABLE M137 EI;Lo;0;R;;;;;N;;;;;\n1E82A;MENDE KIKAKUI SYLLABLE M131 IN;Lo;0;R;;;;;N;;;;;\n1E82B;MENDE KIKAKUI SYLLABLE M135 IN;Lo;0;R;;;;;N;;;;;\n1E82C;MENDE KIKAKUI SYLLABLE M195 AN;Lo;0;R;;;;;N;;;;;\n1E82D;MENDE KIKAKUI SYLLABLE M178 EN;Lo;0;R;;;;;N;;;;;\n1E82E;MENDE KIKAKUI SYLLABLE M019 SI;Lo;0;R;;;;;N;;;;;\n1E82F;MENDE KIKAKUI SYLLABLE M020 SA;Lo;0;R;;;;;N;;;;;\n1E830;MENDE KIKAKUI SYLLABLE M021 SU;Lo;0;R;;;;;N;;;;;\n1E831;MENDE KIKAKUI SYLLABLE M162 SEE;Lo;0;R;;;;;N;;;;;\n1E832;MENDE KIKAKUI SYLLABLE M116 SE;Lo;0;R;;;;;N;;;;;\n1E833;MENDE KIKAKUI SYLLABLE M136 SOO;Lo;0;R;;;;;N;;;;;\n1E834;MENDE KIKAKUI SYLLABLE M079 SO;Lo;0;R;;;;;N;;;;;\n1E835;MENDE KIKAKUI SYLLABLE M196 SIA;Lo;0;R;;;;;N;;;;;\n1E836;MENDE KIKAKUI SYLLABLE M025 LI;Lo;0;R;;;;;N;;;;;\n1E837;MENDE KIKAKUI SYLLABLE M026 LA;Lo;0;R;;;;;N;;;;;\n1E838;MENDE KIKAKUI SYLLABLE M027 LU;Lo;0;R;;;;;N;;;;;\n1E839;MENDE KIKAKUI SYLLABLE M084 LEE;Lo;0;R;;;;;N;;;;;\n1E83A;MENDE KIKAKUI SYLLABLE M073 LE;Lo;0;R;;;;;N;;;;;\n1E83B;MENDE KIKAKUI SYLLABLE M054 LOO;Lo;0;R;;;;;N;;;;;\n1E83C;MENDE KIKAKUI SYLLABLE M153 LO;Lo;0;R;;;;;N;;;;;\n1E83D;MENDE KIKAKUI SYLLABLE M110 LONG LE;Lo;0;R;;;;;N;;;;;\n1E83E;MENDE KIKAKUI SYLLABLE M016 DI;Lo;0;R;;;;;N;;;;;\n1E83F;MENDE KIKAKUI SYLLABLE M017 DA;Lo;0;R;;;;;N;;;;;\n1E840;MENDE KIKAKUI SYLLABLE M018 DU;Lo;0;R;;;;;N;;;;;\n1E841;MENDE KIKAKUI SYLLABLE M089 DEE;Lo;0;R;;;;;N;;;;;\n1E842;MENDE KIKAKUI SYLLABLE M180 DOO;Lo;0;R;;;;;N;;;;;\n1E843;MENDE KIKAKUI SYLLABLE M181 DO;Lo;0;R;;;;;N;;;;;\n1E844;MENDE KIKAKUI SYLLABLE M022 TI;Lo;0;R;;;;;N;;;;;\n1E845;MENDE KIKAKUI SYLLABLE M023 TA;Lo;0;R;;;;;N;;;;;\n1E846;MENDE KIKAKUI SYLLABLE M024 TU;Lo;0;R;;;;;N;;;;;\n1E847;MENDE KIKAKUI SYLLABLE M091 TEE;Lo;0;R;;;;;N;;;;;\n1E848;MENDE KIKAKUI SYLLABLE M055 TE;Lo;0;R;;;;;N;;;;;\n1E849;MENDE KIKAKUI SYLLABLE M104 TOO;Lo;0;R;;;;;N;;;;;\n1E84A;MENDE KIKAKUI SYLLABLE M069 TO;Lo;0;R;;;;;N;;;;;\n1E84B;MENDE KIKAKUI SYLLABLE M028 JI;Lo;0;R;;;;;N;;;;;\n1E84C;MENDE KIKAKUI SYLLABLE M029 JA;Lo;0;R;;;;;N;;;;;\n1E84D;MENDE KIKAKUI SYLLABLE M030 JU;Lo;0;R;;;;;N;;;;;\n1E84E;MENDE KIKAKUI SYLLABLE M157 JEE;Lo;0;R;;;;;N;;;;;\n1E84F;MENDE KIKAKUI SYLLABLE M113 JE;Lo;0;R;;;;;N;;;;;\n1E850;MENDE KIKAKUI SYLLABLE M160 JOO;Lo;0;R;;;;;N;;;;;\n1E851;MENDE KIKAKUI SYLLABLE M063 JO;Lo;0;R;;;;;N;;;;;\n1E852;MENDE KIKAKUI SYLLABLE M175 LONG JO;Lo;0;R;;;;;N;;;;;\n1E853;MENDE KIKAKUI SYLLABLE M031 YI;Lo;0;R;;;;;N;;;;;\n1E854;MENDE KIKAKUI SYLLABLE M032 YA;Lo;0;R;;;;;N;;;;;\n1E855;MENDE KIKAKUI SYLLABLE M033 YU;Lo;0;R;;;;;N;;;;;\n1E856;MENDE KIKAKUI SYLLABLE M109 YEE;Lo;0;R;;;;;N;;;;;\n1E857;MENDE KIKAKUI SYLLABLE M080 YE;Lo;0;R;;;;;N;;;;;\n1E858;MENDE KIKAKUI SYLLABLE M141 YOO;Lo;0;R;;;;;N;;;;;\n1E859;MENDE KIKAKUI SYLLABLE M121 YO;Lo;0;R;;;;;N;;;;;\n1E85A;MENDE KIKAKUI SYLLABLE M034 FI;Lo;0;R;;;;;N;;;;;\n1E85B;MENDE KIKAKUI SYLLABLE M035 FA;Lo;0;R;;;;;N;;;;;\n1E85C;MENDE KIKAKUI SYLLABLE M036 FU;Lo;0;R;;;;;N;;;;;\n1E85D;MENDE KIKAKUI SYLLABLE M078 FEE;Lo;0;R;;;;;N;;;;;\n1E85E;MENDE KIKAKUI SYLLABLE M075 FE;Lo;0;R;;;;;N;;;;;\n1E85F;MENDE KIKAKUI SYLLABLE M133 FOO;Lo;0;R;;;;;N;;;;;\n1E860;MENDE KIKAKUI SYLLABLE M088 FO;Lo;0;R;;;;;N;;;;;\n1E861;MENDE KIKAKUI SYLLABLE M197 FUA;Lo;0;R;;;;;N;;;;;\n1E862;MENDE KIKAKUI SYLLABLE M101 FAN;Lo;0;R;;;;;N;;;;;\n1E863;MENDE KIKAKUI SYLLABLE M037 NIN;Lo;0;R;;;;;N;;;;;\n1E864;MENDE KIKAKUI SYLLABLE M038 NAN;Lo;0;R;;;;;N;;;;;\n1E865;MENDE KIKAKUI SYLLABLE M039 NUN;Lo;0;R;;;;;N;;;;;\n1E866;MENDE KIKAKUI SYLLABLE M117 NEN;Lo;0;R;;;;;N;;;;;\n1E867;MENDE KIKAKUI SYLLABLE M169 NON;Lo;0;R;;;;;N;;;;;\n1E868;MENDE KIKAKUI SYLLABLE M176 HI;Lo;0;R;;;;;N;;;;;\n1E869;MENDE KIKAKUI SYLLABLE M041 HA;Lo;0;R;;;;;N;;;;;\n1E86A;MENDE KIKAKUI SYLLABLE M186 HU;Lo;0;R;;;;;N;;;;;\n1E86B;MENDE KIKAKUI SYLLABLE M040 HEE;Lo;0;R;;;;;N;;;;;\n1E86C;MENDE KIKAKUI SYLLABLE M096 HE;Lo;0;R;;;;;N;;;;;\n1E86D;MENDE KIKAKUI SYLLABLE M042 HOO;Lo;0;R;;;;;N;;;;;\n1E86E;MENDE KIKAKUI SYLLABLE M140 HO;Lo;0;R;;;;;N;;;;;\n1E86F;MENDE KIKAKUI SYLLABLE M083 HEEI;Lo;0;R;;;;;N;;;;;\n1E870;MENDE KIKAKUI SYLLABLE M128 HOOU;Lo;0;R;;;;;N;;;;;\n1E871;MENDE KIKAKUI SYLLABLE M053 HIN;Lo;0;R;;;;;N;;;;;\n1E872;MENDE KIKAKUI SYLLABLE M130 HAN;Lo;0;R;;;;;N;;;;;\n1E873;MENDE KIKAKUI SYLLABLE M087 HUN;Lo;0;R;;;;;N;;;;;\n1E874;MENDE KIKAKUI SYLLABLE M052 HEN;Lo;0;R;;;;;N;;;;;\n1E875;MENDE KIKAKUI SYLLABLE M193 HON;Lo;0;R;;;;;N;;;;;\n1E876;MENDE KIKAKUI SYLLABLE M046 HUAN;Lo;0;R;;;;;N;;;;;\n1E877;MENDE KIKAKUI SYLLABLE M090 NGGI;Lo;0;R;;;;;N;;;;;\n1E878;MENDE KIKAKUI SYLLABLE M043 NGGA;Lo;0;R;;;;;N;;;;;\n1E879;MENDE KIKAKUI SYLLABLE M082 NGGU;Lo;0;R;;;;;N;;;;;\n1E87A;MENDE KIKAKUI SYLLABLE M115 NGGEE;Lo;0;R;;;;;N;;;;;\n1E87B;MENDE KIKAKUI SYLLABLE M146 NGGE;Lo;0;R;;;;;N;;;;;\n1E87C;MENDE KIKAKUI SYLLABLE M156 NGGOO;Lo;0;R;;;;;N;;;;;\n1E87D;MENDE KIKAKUI SYLLABLE M120 NGGO;Lo;0;R;;;;;N;;;;;\n1E87E;MENDE KIKAKUI SYLLABLE M159 NGGAA;Lo;0;R;;;;;N;;;;;\n1E87F;MENDE KIKAKUI SYLLABLE M127 NGGUA;Lo;0;R;;;;;N;;;;;\n1E880;MENDE KIKAKUI SYLLABLE M086 LONG NGGE;Lo;0;R;;;;;N;;;;;\n1E881;MENDE KIKAKUI SYLLABLE M106 LONG NGGOO;Lo;0;R;;;;;N;;;;;\n1E882;MENDE KIKAKUI SYLLABLE M183 LONG NGGO;Lo;0;R;;;;;N;;;;;\n1E883;MENDE KIKAKUI SYLLABLE M155 GI;Lo;0;R;;;;;N;;;;;\n1E884;MENDE KIKAKUI SYLLABLE M111 GA;Lo;0;R;;;;;N;;;;;\n1E885;MENDE KIKAKUI SYLLABLE M168 GU;Lo;0;R;;;;;N;;;;;\n1E886;MENDE KIKAKUI SYLLABLE M190 GEE;Lo;0;R;;;;;N;;;;;\n1E887;MENDE KIKAKUI SYLLABLE M166 GUEI;Lo;0;R;;;;;N;;;;;\n1E888;MENDE KIKAKUI SYLLABLE M167 GUAN;Lo;0;R;;;;;N;;;;;\n1E889;MENDE KIKAKUI SYLLABLE M184 NGEN;Lo;0;R;;;;;N;;;;;\n1E88A;MENDE KIKAKUI SYLLABLE M057 NGON;Lo;0;R;;;;;N;;;;;\n1E88B;MENDE KIKAKUI SYLLABLE M177 NGUAN;Lo;0;R;;;;;N;;;;;\n1E88C;MENDE KIKAKUI SYLLABLE M068 PI;Lo;0;R;;;;;N;;;;;\n1E88D;MENDE KIKAKUI SYLLABLE M099 PA;Lo;0;R;;;;;N;;;;;\n1E88E;MENDE KIKAKUI SYLLABLE M050 PU;Lo;0;R;;;;;N;;;;;\n1E88F;MENDE KIKAKUI SYLLABLE M081 PEE;Lo;0;R;;;;;N;;;;;\n1E890;MENDE KIKAKUI SYLLABLE M051 PE;Lo;0;R;;;;;N;;;;;\n1E891;MENDE KIKAKUI SYLLABLE M102 POO;Lo;0;R;;;;;N;;;;;\n1E892;MENDE KIKAKUI SYLLABLE M066 PO;Lo;0;R;;;;;N;;;;;\n1E893;MENDE KIKAKUI SYLLABLE M145 MBI;Lo;0;R;;;;;N;;;;;\n1E894;MENDE KIKAKUI SYLLABLE M062 MBA;Lo;0;R;;;;;N;;;;;\n1E895;MENDE KIKAKUI SYLLABLE M122 MBU;Lo;0;R;;;;;N;;;;;\n1E896;MENDE KIKAKUI SYLLABLE M047 MBEE;Lo;0;R;;;;;N;;;;;\n1E897;MENDE KIKAKUI SYLLABLE M188 MBEE;Lo;0;R;;;;;N;;;;;\n1E898;MENDE KIKAKUI SYLLABLE M072 MBE;Lo;0;R;;;;;N;;;;;\n1E899;MENDE KIKAKUI SYLLABLE M172 MBOO;Lo;0;R;;;;;N;;;;;\n1E89A;MENDE KIKAKUI SYLLABLE M174 MBO;Lo;0;R;;;;;N;;;;;\n1E89B;MENDE KIKAKUI SYLLABLE M187 MBUU;Lo;0;R;;;;;N;;;;;\n1E89C;MENDE KIKAKUI SYLLABLE M161 LONG MBE;Lo;0;R;;;;;N;;;;;\n1E89D;MENDE KIKAKUI SYLLABLE M105 LONG MBOO;Lo;0;R;;;;;N;;;;;\n1E89E;MENDE KIKAKUI SYLLABLE M142 LONG MBO;Lo;0;R;;;;;N;;;;;\n1E89F;MENDE KIKAKUI SYLLABLE M132 KPI;Lo;0;R;;;;;N;;;;;\n1E8A0;MENDE KIKAKUI SYLLABLE M092 KPA;Lo;0;R;;;;;N;;;;;\n1E8A1;MENDE KIKAKUI SYLLABLE M074 KPU;Lo;0;R;;;;;N;;;;;\n1E8A2;MENDE KIKAKUI SYLLABLE M044 KPEE;Lo;0;R;;;;;N;;;;;\n1E8A3;MENDE KIKAKUI SYLLABLE M108 KPE;Lo;0;R;;;;;N;;;;;\n1E8A4;MENDE KIKAKUI SYLLABLE M112 KPOO;Lo;0;R;;;;;N;;;;;\n1E8A5;MENDE KIKAKUI SYLLABLE M158 KPO;Lo;0;R;;;;;N;;;;;\n1E8A6;MENDE KIKAKUI SYLLABLE M124 GBI;Lo;0;R;;;;;N;;;;;\n1E8A7;MENDE KIKAKUI SYLLABLE M056 GBA;Lo;0;R;;;;;N;;;;;\n1E8A8;MENDE KIKAKUI SYLLABLE M148 GBU;Lo;0;R;;;;;N;;;;;\n1E8A9;MENDE KIKAKUI SYLLABLE M093 GBEE;Lo;0;R;;;;;N;;;;;\n1E8AA;MENDE KIKAKUI SYLLABLE M107 GBE;Lo;0;R;;;;;N;;;;;\n1E8AB;MENDE KIKAKUI SYLLABLE M071 GBOO;Lo;0;R;;;;;N;;;;;\n1E8AC;MENDE KIKAKUI SYLLABLE M070 GBO;Lo;0;R;;;;;N;;;;;\n1E8AD;MENDE KIKAKUI SYLLABLE M171 RA;Lo;0;R;;;;;N;;;;;\n1E8AE;MENDE KIKAKUI SYLLABLE M123 NDI;Lo;0;R;;;;;N;;;;;\n1E8AF;MENDE KIKAKUI SYLLABLE M129 NDA;Lo;0;R;;;;;N;;;;;\n1E8B0;MENDE KIKAKUI SYLLABLE M125 NDU;Lo;0;R;;;;;N;;;;;\n1E8B1;MENDE KIKAKUI SYLLABLE M191 NDEE;Lo;0;R;;;;;N;;;;;\n1E8B2;MENDE KIKAKUI SYLLABLE M119 NDE;Lo;0;R;;;;;N;;;;;\n1E8B3;MENDE KIKAKUI SYLLABLE M067 NDOO;Lo;0;R;;;;;N;;;;;\n1E8B4;MENDE KIKAKUI SYLLABLE M064 NDO;Lo;0;R;;;;;N;;;;;\n1E8B5;MENDE KIKAKUI SYLLABLE M152 NJA;Lo;0;R;;;;;N;;;;;\n1E8B6;MENDE KIKAKUI SYLLABLE M192 NJU;Lo;0;R;;;;;N;;;;;\n1E8B7;MENDE KIKAKUI SYLLABLE M149 NJEE;Lo;0;R;;;;;N;;;;;\n1E8B8;MENDE KIKAKUI SYLLABLE M134 NJOO;Lo;0;R;;;;;N;;;;;\n1E8B9;MENDE KIKAKUI SYLLABLE M182 VI;Lo;0;R;;;;;N;;;;;\n1E8BA;MENDE KIKAKUI SYLLABLE M185 VA;Lo;0;R;;;;;N;;;;;\n1E8BB;MENDE KIKAKUI SYLLABLE M151 VU;Lo;0;R;;;;;N;;;;;\n1E8BC;MENDE KIKAKUI SYLLABLE M173 VEE;Lo;0;R;;;;;N;;;;;\n1E8BD;MENDE KIKAKUI SYLLABLE M085 VE;Lo;0;R;;;;;N;;;;;\n1E8BE;MENDE KIKAKUI SYLLABLE M144 VOO;Lo;0;R;;;;;N;;;;;\n1E8BF;MENDE KIKAKUI SYLLABLE M077 VO;Lo;0;R;;;;;N;;;;;\n1E8C0;MENDE KIKAKUI SYLLABLE M164 NYIN;Lo;0;R;;;;;N;;;;;\n1E8C1;MENDE KIKAKUI SYLLABLE M058 NYAN;Lo;0;R;;;;;N;;;;;\n1E8C2;MENDE KIKAKUI SYLLABLE M170 NYUN;Lo;0;R;;;;;N;;;;;\n1E8C3;MENDE KIKAKUI SYLLABLE M098 NYEN;Lo;0;R;;;;;N;;;;;\n1E8C4;MENDE KIKAKUI SYLLABLE M060 NYON;Lo;0;R;;;;;N;;;;;\n1E8C7;MENDE KIKAKUI DIGIT ONE;No;0;R;;;;1;N;;;;;\n1E8C8;MENDE KIKAKUI DIGIT TWO;No;0;R;;;;2;N;;;;;\n1E8C9;MENDE KIKAKUI DIGIT THREE;No;0;R;;;;3;N;;;;;\n1E8CA;MENDE KIKAKUI DIGIT FOUR;No;0;R;;;;4;N;;;;;\n1E8CB;MENDE KIKAKUI DIGIT FIVE;No;0;R;;;;5;N;;;;;\n1E8CC;MENDE KIKAKUI DIGIT SIX;No;0;R;;;;6;N;;;;;\n1E8CD;MENDE KIKAKUI DIGIT SEVEN;No;0;R;;;;7;N;;;;;\n1E8CE;MENDE KIKAKUI DIGIT EIGHT;No;0;R;;;;8;N;;;;;\n1E8CF;MENDE KIKAKUI DIGIT NINE;No;0;R;;;;9;N;;;;;\n1E8D0;MENDE KIKAKUI COMBINING NUMBER TEENS;Mn;220;NSM;;;;;N;;;;;\n1E8D1;MENDE KIKAKUI COMBINING NUMBER TENS;Mn;220;NSM;;;;;N;;;;;\n1E8D2;MENDE KIKAKUI COMBINING NUMBER HUNDREDS;Mn;220;NSM;;;;;N;;;;;\n1E8D3;MENDE KIKAKUI COMBINING NUMBER THOUSANDS;Mn;220;NSM;;;;;N;;;;;\n1E8D4;MENDE KIKAKUI COMBINING NUMBER TEN THOUSANDS;Mn;220;NSM;;;;;N;;;;;\n1E8D5;MENDE KIKAKUI COMBINING NUMBER HUNDRED THOUSANDS;Mn;220;NSM;;;;;N;;;;;\n1E8D6;MENDE KIKAKUI COMBINING NUMBER MILLIONS;Mn;220;NSM;;;;;N;;;;;\n1E900;ADLAM CAPITAL LETTER ALIF;Lu;0;R;;;;;N;;;;1E922;\n1E901;ADLAM CAPITAL LETTER DAALI;Lu;0;R;;;;;N;;;;1E923;\n1E902;ADLAM CAPITAL LETTER LAAM;Lu;0;R;;;;;N;;;;1E924;\n1E903;ADLAM CAPITAL LETTER MIIM;Lu;0;R;;;;;N;;;;1E925;\n1E904;ADLAM CAPITAL LETTER BA;Lu;0;R;;;;;N;;;;1E926;\n1E905;ADLAM CAPITAL LETTER SINNYIIYHE;Lu;0;R;;;;;N;;;;1E927;\n1E906;ADLAM CAPITAL LETTER PE;Lu;0;R;;;;;N;;;;1E928;\n1E907;ADLAM CAPITAL LETTER BHE;Lu;0;R;;;;;N;;;;1E929;\n1E908;ADLAM CAPITAL LETTER RA;Lu;0;R;;;;;N;;;;1E92A;\n1E909;ADLAM CAPITAL LETTER E;Lu;0;R;;;;;N;;;;1E92B;\n1E90A;ADLAM CAPITAL LETTER FA;Lu;0;R;;;;;N;;;;1E92C;\n1E90B;ADLAM CAPITAL LETTER I;Lu;0;R;;;;;N;;;;1E92D;\n1E90C;ADLAM CAPITAL LETTER O;Lu;0;R;;;;;N;;;;1E92E;\n1E90D;ADLAM CAPITAL LETTER DHA;Lu;0;R;;;;;N;;;;1E92F;\n1E90E;ADLAM CAPITAL LETTER YHE;Lu;0;R;;;;;N;;;;1E930;\n1E90F;ADLAM CAPITAL LETTER WAW;Lu;0;R;;;;;N;;;;1E931;\n1E910;ADLAM CAPITAL LETTER NUN;Lu;0;R;;;;;N;;;;1E932;\n1E911;ADLAM CAPITAL LETTER KAF;Lu;0;R;;;;;N;;;;1E933;\n1E912;ADLAM CAPITAL LETTER YA;Lu;0;R;;;;;N;;;;1E934;\n1E913;ADLAM CAPITAL LETTER U;Lu;0;R;;;;;N;;;;1E935;\n1E914;ADLAM CAPITAL LETTER JIIM;Lu;0;R;;;;;N;;;;1E936;\n1E915;ADLAM CAPITAL LETTER CHI;Lu;0;R;;;;;N;;;;1E937;\n1E916;ADLAM CAPITAL LETTER HA;Lu;0;R;;;;;N;;;;1E938;\n1E917;ADLAM CAPITAL LETTER QAAF;Lu;0;R;;;;;N;;;;1E939;\n1E918;ADLAM CAPITAL LETTER GA;Lu;0;R;;;;;N;;;;1E93A;\n1E919;ADLAM CAPITAL LETTER NYA;Lu;0;R;;;;;N;;;;1E93B;\n1E91A;ADLAM CAPITAL LETTER TU;Lu;0;R;;;;;N;;;;1E93C;\n1E91B;ADLAM CAPITAL LETTER NHA;Lu;0;R;;;;;N;;;;1E93D;\n1E91C;ADLAM CAPITAL LETTER VA;Lu;0;R;;;;;N;;;;1E93E;\n1E91D;ADLAM CAPITAL LETTER KHA;Lu;0;R;;;;;N;;;;1E93F;\n1E91E;ADLAM CAPITAL LETTER GBE;Lu;0;R;;;;;N;;;;1E940;\n1E91F;ADLAM CAPITAL LETTER ZAL;Lu;0;R;;;;;N;;;;1E941;\n1E920;ADLAM CAPITAL LETTER KPO;Lu;0;R;;;;;N;;;;1E942;\n1E921;ADLAM CAPITAL LETTER SHA;Lu;0;R;;;;;N;;;;1E943;\n1E922;ADLAM SMALL LETTER ALIF;Ll;0;R;;;;;N;;;1E900;;1E900\n1E923;ADLAM SMALL LETTER DAALI;Ll;0;R;;;;;N;;;1E901;;1E901\n1E924;ADLAM SMALL LETTER LAAM;Ll;0;R;;;;;N;;;1E902;;1E902\n1E925;ADLAM SMALL LETTER MIIM;Ll;0;R;;;;;N;;;1E903;;1E903\n1E926;ADLAM SMALL LETTER BA;Ll;0;R;;;;;N;;;1E904;;1E904\n1E927;ADLAM SMALL LETTER SINNYIIYHE;Ll;0;R;;;;;N;;;1E905;;1E905\n1E928;ADLAM SMALL LETTER PE;Ll;0;R;;;;;N;;;1E906;;1E906\n1E929;ADLAM SMALL LETTER BHE;Ll;0;R;;;;;N;;;1E907;;1E907\n1E92A;ADLAM SMALL LETTER RA;Ll;0;R;;;;;N;;;1E908;;1E908\n1E92B;ADLAM SMALL LETTER E;Ll;0;R;;;;;N;;;1E909;;1E909\n1E92C;ADLAM SMALL LETTER FA;Ll;0;R;;;;;N;;;1E90A;;1E90A\n1E92D;ADLAM SMALL LETTER I;Ll;0;R;;;;;N;;;1E90B;;1E90B\n1E92E;ADLAM SMALL LETTER O;Ll;0;R;;;;;N;;;1E90C;;1E90C\n1E92F;ADLAM SMALL LETTER DHA;Ll;0;R;;;;;N;;;1E90D;;1E90D\n1E930;ADLAM SMALL LETTER YHE;Ll;0;R;;;;;N;;;1E90E;;1E90E\n1E931;ADLAM SMALL LETTER WAW;Ll;0;R;;;;;N;;;1E90F;;1E90F\n1E932;ADLAM SMALL LETTER NUN;Ll;0;R;;;;;N;;;1E910;;1E910\n1E933;ADLAM SMALL LETTER KAF;Ll;0;R;;;;;N;;;1E911;;1E911\n1E934;ADLAM SMALL LETTER YA;Ll;0;R;;;;;N;;;1E912;;1E912\n1E935;ADLAM SMALL LETTER U;Ll;0;R;;;;;N;;;1E913;;1E913\n1E936;ADLAM SMALL LETTER JIIM;Ll;0;R;;;;;N;;;1E914;;1E914\n1E937;ADLAM SMALL LETTER CHI;Ll;0;R;;;;;N;;;1E915;;1E915\n1E938;ADLAM SMALL LETTER HA;Ll;0;R;;;;;N;;;1E916;;1E916\n1E939;ADLAM SMALL LETTER QAAF;Ll;0;R;;;;;N;;;1E917;;1E917\n1E93A;ADLAM SMALL LETTER GA;Ll;0;R;;;;;N;;;1E918;;1E918\n1E93B;ADLAM SMALL LETTER NYA;Ll;0;R;;;;;N;;;1E919;;1E919\n1E93C;ADLAM SMALL LETTER TU;Ll;0;R;;;;;N;;;1E91A;;1E91A\n1E93D;ADLAM SMALL LETTER NHA;Ll;0;R;;;;;N;;;1E91B;;1E91B\n1E93E;ADLAM SMALL LETTER VA;Ll;0;R;;;;;N;;;1E91C;;1E91C\n1E93F;ADLAM SMALL LETTER KHA;Ll;0;R;;;;;N;;;1E91D;;1E91D\n1E940;ADLAM SMALL LETTER GBE;Ll;0;R;;;;;N;;;1E91E;;1E91E\n1E941;ADLAM SMALL LETTER ZAL;Ll;0;R;;;;;N;;;1E91F;;1E91F\n1E942;ADLAM SMALL LETTER KPO;Ll;0;R;;;;;N;;;1E920;;1E920\n1E943;ADLAM SMALL LETTER SHA;Ll;0;R;;;;;N;;;1E921;;1E921\n1E944;ADLAM ALIF LENGTHENER;Mn;230;NSM;;;;;N;;;;;\n1E945;ADLAM VOWEL LENGTHENER;Mn;230;NSM;;;;;N;;;;;\n1E946;ADLAM GEMINATION MARK;Mn;230;NSM;;;;;N;;;;;\n1E947;ADLAM HAMZA;Mn;230;NSM;;;;;N;;;;;\n1E948;ADLAM CONSONANT MODIFIER;Mn;230;NSM;;;;;N;;;;;\n1E949;ADLAM GEMINATE CONSONANT MODIFIER;Mn;230;NSM;;;;;N;;;;;\n1E94A;ADLAM NUKTA;Mn;7;NSM;;;;;N;;;;;\n1E94B;ADLAM NASALIZATION MARK;Lm;0;R;;;;;N;;;;;\n1E950;ADLAM DIGIT ZERO;Nd;0;R;;0;0;0;N;;;;;\n1E951;ADLAM DIGIT ONE;Nd;0;R;;1;1;1;N;;;;;\n1E952;ADLAM DIGIT TWO;Nd;0;R;;2;2;2;N;;;;;\n1E953;ADLAM DIGIT THREE;Nd;0;R;;3;3;3;N;;;;;\n1E954;ADLAM DIGIT FOUR;Nd;0;R;;4;4;4;N;;;;;\n1E955;ADLAM DIGIT FIVE;Nd;0;R;;5;5;5;N;;;;;\n1E956;ADLAM DIGIT SIX;Nd;0;R;;6;6;6;N;;;;;\n1E957;ADLAM DIGIT SEVEN;Nd;0;R;;7;7;7;N;;;;;\n1E958;ADLAM DIGIT EIGHT;Nd;0;R;;8;8;8;N;;;;;\n1E959;ADLAM DIGIT NINE;Nd;0;R;;9;9;9;N;;;;;\n1E95E;ADLAM INITIAL EXCLAMATION MARK;Po;0;R;;;;;N;;;;;\n1E95F;ADLAM INITIAL QUESTION MARK;Po;0;R;;;;;N;;;;;\n1EC71;INDIC SIYAQ NUMBER ONE;No;0;AL;;;;1;N;;;;;\n1EC72;INDIC SIYAQ NUMBER TWO;No;0;AL;;;;2;N;;;;;\n1EC73;INDIC SIYAQ NUMBER THREE;No;0;AL;;;;3;N;;;;;\n1EC74;INDIC SIYAQ NUMBER FOUR;No;0;AL;;;;4;N;;;;;\n1EC75;INDIC SIYAQ NUMBER FIVE;No;0;AL;;;;5;N;;;;;\n1EC76;INDIC SIYAQ NUMBER SIX;No;0;AL;;;;6;N;;;;;\n1EC77;INDIC SIYAQ NUMBER SEVEN;No;0;AL;;;;7;N;;;;;\n1EC78;INDIC SIYAQ NUMBER EIGHT;No;0;AL;;;;8;N;;;;;\n1EC79;INDIC SIYAQ NUMBER NINE;No;0;AL;;;;9;N;;;;;\n1EC7A;INDIC SIYAQ NUMBER TEN;No;0;AL;;;;10;N;;;;;\n1EC7B;INDIC SIYAQ NUMBER TWENTY;No;0;AL;;;;20;N;;;;;\n1EC7C;INDIC SIYAQ NUMBER THIRTY;No;0;AL;;;;30;N;;;;;\n1EC7D;INDIC SIYAQ NUMBER FORTY;No;0;AL;;;;40;N;;;;;\n1EC7E;INDIC SIYAQ NUMBER FIFTY;No;0;AL;;;;50;N;;;;;\n1EC7F;INDIC SIYAQ NUMBER SIXTY;No;0;AL;;;;60;N;;;;;\n1EC80;INDIC SIYAQ NUMBER SEVENTY;No;0;AL;;;;70;N;;;;;\n1EC81;INDIC SIYAQ NUMBER EIGHTY;No;0;AL;;;;80;N;;;;;\n1EC82;INDIC SIYAQ NUMBER NINETY;No;0;AL;;;;90;N;;;;;\n1EC83;INDIC SIYAQ NUMBER ONE HUNDRED;No;0;AL;;;;100;N;;;;;\n1EC84;INDIC SIYAQ NUMBER TWO HUNDRED;No;0;AL;;;;200;N;;;;;\n1EC85;INDIC SIYAQ NUMBER THREE HUNDRED;No;0;AL;;;;300;N;;;;;\n1EC86;INDIC SIYAQ NUMBER FOUR HUNDRED;No;0;AL;;;;400;N;;;;;\n1EC87;INDIC SIYAQ NUMBER FIVE HUNDRED;No;0;AL;;;;500;N;;;;;\n1EC88;INDIC SIYAQ NUMBER SIX HUNDRED;No;0;AL;;;;600;N;;;;;\n1EC89;INDIC SIYAQ NUMBER SEVEN HUNDRED;No;0;AL;;;;700;N;;;;;\n1EC8A;INDIC SIYAQ NUMBER EIGHT HUNDRED;No;0;AL;;;;800;N;;;;;\n1EC8B;INDIC SIYAQ NUMBER NINE HUNDRED;No;0;AL;;;;900;N;;;;;\n1EC8C;INDIC SIYAQ NUMBER ONE THOUSAND;No;0;AL;;;;1000;N;;;;;\n1EC8D;INDIC SIYAQ NUMBER TWO THOUSAND;No;0;AL;;;;2000;N;;;;;\n1EC8E;INDIC SIYAQ NUMBER THREE THOUSAND;No;0;AL;;;;3000;N;;;;;\n1EC8F;INDIC SIYAQ NUMBER FOUR THOUSAND;No;0;AL;;;;4000;N;;;;;\n1EC90;INDIC SIYAQ NUMBER FIVE THOUSAND;No;0;AL;;;;5000;N;;;;;\n1EC91;INDIC SIYAQ NUMBER SIX THOUSAND;No;0;AL;;;;6000;N;;;;;\n1EC92;INDIC SIYAQ NUMBER SEVEN THOUSAND;No;0;AL;;;;7000;N;;;;;\n1EC93;INDIC SIYAQ NUMBER EIGHT THOUSAND;No;0;AL;;;;8000;N;;;;;\n1EC94;INDIC SIYAQ NUMBER NINE THOUSAND;No;0;AL;;;;9000;N;;;;;\n1EC95;INDIC SIYAQ NUMBER TEN THOUSAND;No;0;AL;;;;10000;N;;;;;\n1EC96;INDIC SIYAQ NUMBER TWENTY THOUSAND;No;0;AL;;;;20000;N;;;;;\n1EC97;INDIC SIYAQ NUMBER THIRTY THOUSAND;No;0;AL;;;;30000;N;;;;;\n1EC98;INDIC SIYAQ NUMBER FORTY THOUSAND;No;0;AL;;;;40000;N;;;;;\n1EC99;INDIC SIYAQ NUMBER FIFTY THOUSAND;No;0;AL;;;;50000;N;;;;;\n1EC9A;INDIC SIYAQ NUMBER SIXTY THOUSAND;No;0;AL;;;;60000;N;;;;;\n1EC9B;INDIC SIYAQ NUMBER SEVENTY THOUSAND;No;0;AL;;;;70000;N;;;;;\n1EC9C;INDIC SIYAQ NUMBER EIGHTY THOUSAND;No;0;AL;;;;80000;N;;;;;\n1EC9D;INDIC SIYAQ NUMBER NINETY THOUSAND;No;0;AL;;;;90000;N;;;;;\n1EC9E;INDIC SIYAQ NUMBER LAKH;No;0;AL;;;;100000;N;;;;;\n1EC9F;INDIC SIYAQ NUMBER LAKHAN;No;0;AL;;;;200000;N;;;;;\n1ECA0;INDIC SIYAQ LAKH MARK;No;0;AL;;;;100000;N;;;;;\n1ECA1;INDIC SIYAQ NUMBER KAROR;No;0;AL;;;;10000000;N;;;;;\n1ECA2;INDIC SIYAQ NUMBER KARORAN;No;0;AL;;;;20000000;N;;;;;\n1ECA3;INDIC SIYAQ NUMBER PREFIXED ONE;No;0;AL;;;;1;N;;;;;\n1ECA4;INDIC SIYAQ NUMBER PREFIXED TWO;No;0;AL;;;;2;N;;;;;\n1ECA5;INDIC SIYAQ NUMBER PREFIXED THREE;No;0;AL;;;;3;N;;;;;\n1ECA6;INDIC SIYAQ NUMBER PREFIXED FOUR;No;0;AL;;;;4;N;;;;;\n1ECA7;INDIC SIYAQ NUMBER PREFIXED FIVE;No;0;AL;;;;5;N;;;;;\n1ECA8;INDIC SIYAQ NUMBER PREFIXED SIX;No;0;AL;;;;6;N;;;;;\n1ECA9;INDIC SIYAQ NUMBER PREFIXED SEVEN;No;0;AL;;;;7;N;;;;;\n1ECAA;INDIC SIYAQ NUMBER PREFIXED EIGHT;No;0;AL;;;;8;N;;;;;\n1ECAB;INDIC SIYAQ NUMBER PREFIXED NINE;No;0;AL;;;;9;N;;;;;\n1ECAC;INDIC SIYAQ PLACEHOLDER;So;0;AL;;;;;N;;;;;\n1ECAD;INDIC SIYAQ FRACTION ONE QUARTER;No;0;AL;;;;1/4;N;;;;;\n1ECAE;INDIC SIYAQ FRACTION ONE HALF;No;0;AL;;;;1/2;N;;;;;\n1ECAF;INDIC SIYAQ FRACTION THREE QUARTERS;No;0;AL;;;;3/4;N;;;;;\n1ECB0;INDIC SIYAQ RUPEE MARK;Sc;0;AL;;;;;N;;;;;\n1ECB1;INDIC SIYAQ NUMBER ALTERNATE ONE;No;0;AL;;;;1;N;;;;;\n1ECB2;INDIC SIYAQ NUMBER ALTERNATE TWO;No;0;AL;;;;2;N;;;;;\n1ECB3;INDIC SIYAQ NUMBER ALTERNATE TEN THOUSAND;No;0;AL;;;;10000;N;;;;;\n1ECB4;INDIC SIYAQ ALTERNATE LAKH MARK;No;0;AL;;;;100000;N;;;;;\n1ED01;OTTOMAN SIYAQ NUMBER ONE;No;0;AL;;;;1;N;;;;;\n1ED02;OTTOMAN SIYAQ NUMBER TWO;No;0;AL;;;;2;N;;;;;\n1ED03;OTTOMAN SIYAQ NUMBER THREE;No;0;AL;;;;3;N;;;;;\n1ED04;OTTOMAN SIYAQ NUMBER FOUR;No;0;AL;;;;4;N;;;;;\n1ED05;OTTOMAN SIYAQ NUMBER FIVE;No;0;AL;;;;5;N;;;;;\n1ED06;OTTOMAN SIYAQ NUMBER SIX;No;0;AL;;;;6;N;;;;;\n1ED07;OTTOMAN SIYAQ NUMBER SEVEN;No;0;AL;;;;7;N;;;;;\n1ED08;OTTOMAN SIYAQ NUMBER EIGHT;No;0;AL;;;;8;N;;;;;\n1ED09;OTTOMAN SIYAQ NUMBER NINE;No;0;AL;;;;9;N;;;;;\n1ED0A;OTTOMAN SIYAQ NUMBER TEN;No;0;AL;;;;10;N;;;;;\n1ED0B;OTTOMAN SIYAQ NUMBER TWENTY;No;0;AL;;;;20;N;;;;;\n1ED0C;OTTOMAN SIYAQ NUMBER THIRTY;No;0;AL;;;;30;N;;;;;\n1ED0D;OTTOMAN SIYAQ NUMBER FORTY;No;0;AL;;;;40;N;;;;;\n1ED0E;OTTOMAN SIYAQ NUMBER FIFTY;No;0;AL;;;;50;N;;;;;\n1ED0F;OTTOMAN SIYAQ NUMBER SIXTY;No;0;AL;;;;60;N;;;;;\n1ED10;OTTOMAN SIYAQ NUMBER SEVENTY;No;0;AL;;;;70;N;;;;;\n1ED11;OTTOMAN SIYAQ NUMBER EIGHTY;No;0;AL;;;;80;N;;;;;\n1ED12;OTTOMAN SIYAQ NUMBER NINETY;No;0;AL;;;;90;N;;;;;\n1ED13;OTTOMAN SIYAQ NUMBER ONE HUNDRED;No;0;AL;;;;100;N;;;;;\n1ED14;OTTOMAN SIYAQ NUMBER TWO HUNDRED;No;0;AL;;;;200;N;;;;;\n1ED15;OTTOMAN SIYAQ NUMBER THREE HUNDRED;No;0;AL;;;;300;N;;;;;\n1ED16;OTTOMAN SIYAQ NUMBER FOUR HUNDRED;No;0;AL;;;;400;N;;;;;\n1ED17;OTTOMAN SIYAQ NUMBER FIVE HUNDRED;No;0;AL;;;;500;N;;;;;\n1ED18;OTTOMAN SIYAQ NUMBER SIX HUNDRED;No;0;AL;;;;600;N;;;;;\n1ED19;OTTOMAN SIYAQ NUMBER SEVEN HUNDRED;No;0;AL;;;;700;N;;;;;\n1ED1A;OTTOMAN SIYAQ NUMBER EIGHT HUNDRED;No;0;AL;;;;800;N;;;;;\n1ED1B;OTTOMAN SIYAQ NUMBER NINE HUNDRED;No;0;AL;;;;900;N;;;;;\n1ED1C;OTTOMAN SIYAQ NUMBER ONE THOUSAND;No;0;AL;;;;1000;N;;;;;\n1ED1D;OTTOMAN SIYAQ NUMBER TWO THOUSAND;No;0;AL;;;;2000;N;;;;;\n1ED1E;OTTOMAN SIYAQ NUMBER THREE THOUSAND;No;0;AL;;;;3000;N;;;;;\n1ED1F;OTTOMAN SIYAQ NUMBER FOUR THOUSAND;No;0;AL;;;;4000;N;;;;;\n1ED20;OTTOMAN SIYAQ NUMBER FIVE THOUSAND;No;0;AL;;;;5000;N;;;;;\n1ED21;OTTOMAN SIYAQ NUMBER SIX THOUSAND;No;0;AL;;;;6000;N;;;;;\n1ED22;OTTOMAN SIYAQ NUMBER SEVEN THOUSAND;No;0;AL;;;;7000;N;;;;;\n1ED23;OTTOMAN SIYAQ NUMBER EIGHT THOUSAND;No;0;AL;;;;8000;N;;;;;\n1ED24;OTTOMAN SIYAQ NUMBER NINE THOUSAND;No;0;AL;;;;9000;N;;;;;\n1ED25;OTTOMAN SIYAQ NUMBER TEN THOUSAND;No;0;AL;;;;10000;N;;;;;\n1ED26;OTTOMAN SIYAQ NUMBER TWENTY THOUSAND;No;0;AL;;;;20000;N;;;;;\n1ED27;OTTOMAN SIYAQ NUMBER THIRTY THOUSAND;No;0;AL;;;;30000;N;;;;;\n1ED28;OTTOMAN SIYAQ NUMBER FORTY THOUSAND;No;0;AL;;;;40000;N;;;;;\n1ED29;OTTOMAN SIYAQ NUMBER FIFTY THOUSAND;No;0;AL;;;;50000;N;;;;;\n1ED2A;OTTOMAN SIYAQ NUMBER SIXTY THOUSAND;No;0;AL;;;;60000;N;;;;;\n1ED2B;OTTOMAN SIYAQ NUMBER SEVENTY THOUSAND;No;0;AL;;;;70000;N;;;;;\n1ED2C;OTTOMAN SIYAQ NUMBER EIGHTY THOUSAND;No;0;AL;;;;80000;N;;;;;\n1ED2D;OTTOMAN SIYAQ NUMBER NINETY THOUSAND;No;0;AL;;;;90000;N;;;;;\n1ED2E;OTTOMAN SIYAQ MARRATAN;So;0;AL;;;;;N;;;;;\n1ED2F;OTTOMAN SIYAQ ALTERNATE NUMBER TWO;No;0;AL;;;;2;N;;;;;\n1ED30;OTTOMAN SIYAQ ALTERNATE NUMBER THREE;No;0;AL;;;;3;N;;;;;\n1ED31;OTTOMAN SIYAQ ALTERNATE NUMBER FOUR;No;0;AL;;;;4;N;;;;;\n1ED32;OTTOMAN SIYAQ ALTERNATE NUMBER FIVE;No;0;AL;;;;5;N;;;;;\n1ED33;OTTOMAN SIYAQ ALTERNATE NUMBER SIX;No;0;AL;;;;6;N;;;;;\n1ED34;OTTOMAN SIYAQ ALTERNATE NUMBER SEVEN;No;0;AL;;;;7;N;;;;;\n1ED35;OTTOMAN SIYAQ ALTERNATE NUMBER EIGHT;No;0;AL;;;;8;N;;;;;\n1ED36;OTTOMAN SIYAQ ALTERNATE NUMBER NINE;No;0;AL;;;;9;N;;;;;\n1ED37;OTTOMAN SIYAQ ALTERNATE NUMBER TEN;No;0;AL;;;;10;N;;;;;\n1ED38;OTTOMAN SIYAQ ALTERNATE NUMBER FOUR HUNDRED;No;0;AL;;;;400;N;;;;;\n1ED39;OTTOMAN SIYAQ ALTERNATE NUMBER SIX HUNDRED;No;0;AL;;;;600;N;;;;;\n1ED3A;OTTOMAN SIYAQ ALTERNATE NUMBER TWO THOUSAND;No;0;AL;;;;2000;N;;;;;\n1ED3B;OTTOMAN SIYAQ ALTERNATE NUMBER TEN THOUSAND;No;0;AL;;;;10000;N;;;;;\n1ED3C;OTTOMAN SIYAQ FRACTION ONE HALF;No;0;AL;;;;1/2;N;;;;;\n1ED3D;OTTOMAN SIYAQ FRACTION ONE SIXTH;No;0;AL;;;;1/6;N;;;;;\n1EE00;ARABIC MATHEMATICAL ALEF;Lo;0;AL;<font> 0627;;;;N;;;;;\n1EE01;ARABIC MATHEMATICAL BEH;Lo;0;AL;<font> 0628;;;;N;;;;;\n1EE02;ARABIC MATHEMATICAL JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;\n1EE03;ARABIC MATHEMATICAL DAL;Lo;0;AL;<font> 062F;;;;N;;;;;\n1EE05;ARABIC MATHEMATICAL WAW;Lo;0;AL;<font> 0648;;;;N;;;;;\n1EE06;ARABIC MATHEMATICAL ZAIN;Lo;0;AL;<font> 0632;;;;N;;;;;\n1EE07;ARABIC MATHEMATICAL HAH;Lo;0;AL;<font> 062D;;;;N;;;;;\n1EE08;ARABIC MATHEMATICAL TAH;Lo;0;AL;<font> 0637;;;;N;;;;;\n1EE09;ARABIC MATHEMATICAL YEH;Lo;0;AL;<font> 064A;;;;N;;;;;\n1EE0A;ARABIC MATHEMATICAL KAF;Lo;0;AL;<font> 0643;;;;N;;;;;\n1EE0B;ARABIC MATHEMATICAL LAM;Lo;0;AL;<font> 0644;;;;N;;;;;\n1EE0C;ARABIC MATHEMATICAL MEEM;Lo;0;AL;<font> 0645;;;;N;;;;;\n1EE0D;ARABIC MATHEMATICAL NOON;Lo;0;AL;<font> 0646;;;;N;;;;;\n1EE0E;ARABIC MATHEMATICAL SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;\n1EE0F;ARABIC MATHEMATICAL AIN;Lo;0;AL;<font> 0639;;;;N;;;;;\n1EE10;ARABIC MATHEMATICAL FEH;Lo;0;AL;<font> 0641;;;;N;;;;;\n1EE11;ARABIC MATHEMATICAL SAD;Lo;0;AL;<font> 0635;;;;N;;;;;\n1EE12;ARABIC MATHEMATICAL QAF;Lo;0;AL;<font> 0642;;;;N;;;;;\n1EE13;ARABIC MATHEMATICAL REH;Lo;0;AL;<font> 0631;;;;N;;;;;\n1EE14;ARABIC MATHEMATICAL SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;\n1EE15;ARABIC MATHEMATICAL TEH;Lo;0;AL;<font> 062A;;;;N;;;;;\n1EE16;ARABIC MATHEMATICAL THEH;Lo;0;AL;<font> 062B;;;;N;;;;;\n1EE17;ARABIC MATHEMATICAL KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;\n1EE18;ARABIC MATHEMATICAL THAL;Lo;0;AL;<font> 0630;;;;N;;;;;\n1EE19;ARABIC MATHEMATICAL DAD;Lo;0;AL;<font> 0636;;;;N;;;;;\n1EE1A;ARABIC MATHEMATICAL ZAH;Lo;0;AL;<font> 0638;;;;N;;;;;\n1EE1B;ARABIC MATHEMATICAL GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;\n1EE1C;ARABIC MATHEMATICAL DOTLESS BEH;Lo;0;AL;<font> 066E;;;;N;;;;;\n1EE1D;ARABIC MATHEMATICAL DOTLESS NOON;Lo;0;AL;<font> 06BA;;;;N;;;;;\n1EE1E;ARABIC MATHEMATICAL DOTLESS FEH;Lo;0;AL;<font> 06A1;;;;N;;;;;\n1EE1F;ARABIC MATHEMATICAL DOTLESS QAF;Lo;0;AL;<font> 066F;;;;N;;;;;\n1EE21;ARABIC MATHEMATICAL INITIAL BEH;Lo;0;AL;<font> 0628;;;;N;;;;;\n1EE22;ARABIC MATHEMATICAL INITIAL JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;\n1EE24;ARABIC MATHEMATICAL INITIAL HEH;Lo;0;AL;<font> 0647;;;;N;;;;;\n1EE27;ARABIC MATHEMATICAL INITIAL HAH;Lo;0;AL;<font> 062D;;;;N;;;;;\n1EE29;ARABIC MATHEMATICAL INITIAL YEH;Lo;0;AL;<font> 064A;;;;N;;;;;\n1EE2A;ARABIC MATHEMATICAL INITIAL KAF;Lo;0;AL;<font> 0643;;;;N;;;;;\n1EE2B;ARABIC MATHEMATICAL INITIAL LAM;Lo;0;AL;<font> 0644;;;;N;;;;;\n1EE2C;ARABIC MATHEMATICAL INITIAL MEEM;Lo;0;AL;<font> 0645;;;;N;;;;;\n1EE2D;ARABIC MATHEMATICAL INITIAL NOON;Lo;0;AL;<font> 0646;;;;N;;;;;\n1EE2E;ARABIC MATHEMATICAL INITIAL SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;\n1EE2F;ARABIC MATHEMATICAL INITIAL AIN;Lo;0;AL;<font> 0639;;;;N;;;;;\n1EE30;ARABIC MATHEMATICAL INITIAL FEH;Lo;0;AL;<font> 0641;;;;N;;;;;\n1EE31;ARABIC MATHEMATICAL INITIAL SAD;Lo;0;AL;<font> 0635;;;;N;;;;;\n1EE32;ARABIC MATHEMATICAL INITIAL QAF;Lo;0;AL;<font> 0642;;;;N;;;;;\n1EE34;ARABIC MATHEMATICAL INITIAL SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;\n1EE35;ARABIC MATHEMATICAL INITIAL TEH;Lo;0;AL;<font> 062A;;;;N;;;;;\n1EE36;ARABIC MATHEMATICAL INITIAL THEH;Lo;0;AL;<font> 062B;;;;N;;;;;\n1EE37;ARABIC MATHEMATICAL INITIAL KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;\n1EE39;ARABIC MATHEMATICAL INITIAL DAD;Lo;0;AL;<font> 0636;;;;N;;;;;\n1EE3B;ARABIC MATHEMATICAL INITIAL GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;\n1EE42;ARABIC MATHEMATICAL TAILED JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;\n1EE47;ARABIC MATHEMATICAL TAILED HAH;Lo;0;AL;<font> 062D;;;;N;;;;;\n1EE49;ARABIC MATHEMATICAL TAILED YEH;Lo;0;AL;<font> 064A;;;;N;;;;;\n1EE4B;ARABIC MATHEMATICAL TAILED LAM;Lo;0;AL;<font> 0644;;;;N;;;;;\n1EE4D;ARABIC MATHEMATICAL TAILED NOON;Lo;0;AL;<font> 0646;;;;N;;;;;\n1EE4E;ARABIC MATHEMATICAL TAILED SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;\n1EE4F;ARABIC MATHEMATICAL TAILED AIN;Lo;0;AL;<font> 0639;;;;N;;;;;\n1EE51;ARABIC MATHEMATICAL TAILED SAD;Lo;0;AL;<font> 0635;;;;N;;;;;\n1EE52;ARABIC MATHEMATICAL TAILED QAF;Lo;0;AL;<font> 0642;;;;N;;;;;\n1EE54;ARABIC MATHEMATICAL TAILED SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;\n1EE57;ARABIC MATHEMATICAL TAILED KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;\n1EE59;ARABIC MATHEMATICAL TAILED DAD;Lo;0;AL;<font> 0636;;;;N;;;;;\n1EE5B;ARABIC MATHEMATICAL TAILED GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;\n1EE5D;ARABIC MATHEMATICAL TAILED DOTLESS NOON;Lo;0;AL;<font> 06BA;;;;N;;;;;\n1EE5F;ARABIC MATHEMATICAL TAILED DOTLESS QAF;Lo;0;AL;<font> 066F;;;;N;;;;;\n1EE61;ARABIC MATHEMATICAL STRETCHED BEH;Lo;0;AL;<font> 0628;;;;N;;;;;\n1EE62;ARABIC MATHEMATICAL STRETCHED JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;\n1EE64;ARABIC MATHEMATICAL STRETCHED HEH;Lo;0;AL;<font> 0647;;;;N;;;;;\n1EE67;ARABIC MATHEMATICAL STRETCHED HAH;Lo;0;AL;<font> 062D;;;;N;;;;;\n1EE68;ARABIC MATHEMATICAL STRETCHED TAH;Lo;0;AL;<font> 0637;;;;N;;;;;\n1EE69;ARABIC MATHEMATICAL STRETCHED YEH;Lo;0;AL;<font> 064A;;;;N;;;;;\n1EE6A;ARABIC MATHEMATICAL STRETCHED KAF;Lo;0;AL;<font> 0643;;;;N;;;;;\n1EE6C;ARABIC MATHEMATICAL STRETCHED MEEM;Lo;0;AL;<font> 0645;;;;N;;;;;\n1EE6D;ARABIC MATHEMATICAL STRETCHED NOON;Lo;0;AL;<font> 0646;;;;N;;;;;\n1EE6E;ARABIC MATHEMATICAL STRETCHED SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;\n1EE6F;ARABIC MATHEMATICAL STRETCHED AIN;Lo;0;AL;<font> 0639;;;;N;;;;;\n1EE70;ARABIC MATHEMATICAL STRETCHED FEH;Lo;0;AL;<font> 0641;;;;N;;;;;\n1EE71;ARABIC MATHEMATICAL STRETCHED SAD;Lo;0;AL;<font> 0635;;;;N;;;;;\n1EE72;ARABIC MATHEMATICAL STRETCHED QAF;Lo;0;AL;<font> 0642;;;;N;;;;;\n1EE74;ARABIC MATHEMATICAL STRETCHED SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;\n1EE75;ARABIC MATHEMATICAL STRETCHED TEH;Lo;0;AL;<font> 062A;;;;N;;;;;\n1EE76;ARABIC MATHEMATICAL STRETCHED THEH;Lo;0;AL;<font> 062B;;;;N;;;;;\n1EE77;ARABIC MATHEMATICAL STRETCHED KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;\n1EE79;ARABIC MATHEMATICAL STRETCHED DAD;Lo;0;AL;<font> 0636;;;;N;;;;;\n1EE7A;ARABIC MATHEMATICAL STRETCHED ZAH;Lo;0;AL;<font> 0638;;;;N;;;;;\n1EE7B;ARABIC MATHEMATICAL STRETCHED GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;\n1EE7C;ARABIC MATHEMATICAL STRETCHED DOTLESS BEH;Lo;0;AL;<font> 066E;;;;N;;;;;\n1EE7E;ARABIC MATHEMATICAL STRETCHED DOTLESS FEH;Lo;0;AL;<font> 06A1;;;;N;;;;;\n1EE80;ARABIC MATHEMATICAL LOOPED ALEF;Lo;0;AL;<font> 0627;;;;N;;;;;\n1EE81;ARABIC MATHEMATICAL LOOPED BEH;Lo;0;AL;<font> 0628;;;;N;;;;;\n1EE82;ARABIC MATHEMATICAL LOOPED JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;\n1EE83;ARABIC MATHEMATICAL LOOPED DAL;Lo;0;AL;<font> 062F;;;;N;;;;;\n1EE84;ARABIC MATHEMATICAL LOOPED HEH;Lo;0;AL;<font> 0647;;;;N;;;;;\n1EE85;ARABIC MATHEMATICAL LOOPED WAW;Lo;0;AL;<font> 0648;;;;N;;;;;\n1EE86;ARABIC MATHEMATICAL LOOPED ZAIN;Lo;0;AL;<font> 0632;;;;N;;;;;\n1EE87;ARABIC MATHEMATICAL LOOPED HAH;Lo;0;AL;<font> 062D;;;;N;;;;;\n1EE88;ARABIC MATHEMATICAL LOOPED TAH;Lo;0;AL;<font> 0637;;;;N;;;;;\n1EE89;ARABIC MATHEMATICAL LOOPED YEH;Lo;0;AL;<font> 064A;;;;N;;;;;\n1EE8B;ARABIC MATHEMATICAL LOOPED LAM;Lo;0;AL;<font> 0644;;;;N;;;;;\n1EE8C;ARABIC MATHEMATICAL LOOPED MEEM;Lo;0;AL;<font> 0645;;;;N;;;;;\n1EE8D;ARABIC MATHEMATICAL LOOPED NOON;Lo;0;AL;<font> 0646;;;;N;;;;;\n1EE8E;ARABIC MATHEMATICAL LOOPED SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;\n1EE8F;ARABIC MATHEMATICAL LOOPED AIN;Lo;0;AL;<font> 0639;;;;N;;;;;\n1EE90;ARABIC MATHEMATICAL LOOPED FEH;Lo;0;AL;<font> 0641;;;;N;;;;;\n1EE91;ARABIC MATHEMATICAL LOOPED SAD;Lo;0;AL;<font> 0635;;;;N;;;;;\n1EE92;ARABIC MATHEMATICAL LOOPED QAF;Lo;0;AL;<font> 0642;;;;N;;;;;\n1EE93;ARABIC MATHEMATICAL LOOPED REH;Lo;0;AL;<font> 0631;;;;N;;;;;\n1EE94;ARABIC MATHEMATICAL LOOPED SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;\n1EE95;ARABIC MATHEMATICAL LOOPED TEH;Lo;0;AL;<font> 062A;;;;N;;;;;\n1EE96;ARABIC MATHEMATICAL LOOPED THEH;Lo;0;AL;<font> 062B;;;;N;;;;;\n1EE97;ARABIC MATHEMATICAL LOOPED KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;\n1EE98;ARABIC MATHEMATICAL LOOPED THAL;Lo;0;AL;<font> 0630;;;;N;;;;;\n1EE99;ARABIC MATHEMATICAL LOOPED DAD;Lo;0;AL;<font> 0636;;;;N;;;;;\n1EE9A;ARABIC MATHEMATICAL LOOPED ZAH;Lo;0;AL;<font> 0638;;;;N;;;;;\n1EE9B;ARABIC MATHEMATICAL LOOPED GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;\n1EEA1;ARABIC MATHEMATICAL DOUBLE-STRUCK BEH;Lo;0;AL;<font> 0628;;;;N;;;;;\n1EEA2;ARABIC MATHEMATICAL DOUBLE-STRUCK JEEM;Lo;0;AL;<font> 062C;;;;N;;;;;\n1EEA3;ARABIC MATHEMATICAL DOUBLE-STRUCK DAL;Lo;0;AL;<font> 062F;;;;N;;;;;\n1EEA5;ARABIC MATHEMATICAL DOUBLE-STRUCK WAW;Lo;0;AL;<font> 0648;;;;N;;;;;\n1EEA6;ARABIC MATHEMATICAL DOUBLE-STRUCK ZAIN;Lo;0;AL;<font> 0632;;;;N;;;;;\n1EEA7;ARABIC MATHEMATICAL DOUBLE-STRUCK HAH;Lo;0;AL;<font> 062D;;;;N;;;;;\n1EEA8;ARABIC MATHEMATICAL DOUBLE-STRUCK TAH;Lo;0;AL;<font> 0637;;;;N;;;;;\n1EEA9;ARABIC MATHEMATICAL DOUBLE-STRUCK YEH;Lo;0;AL;<font> 064A;;;;N;;;;;\n1EEAB;ARABIC MATHEMATICAL DOUBLE-STRUCK LAM;Lo;0;AL;<font> 0644;;;;N;;;;;\n1EEAC;ARABIC MATHEMATICAL DOUBLE-STRUCK MEEM;Lo;0;AL;<font> 0645;;;;N;;;;;\n1EEAD;ARABIC MATHEMATICAL DOUBLE-STRUCK NOON;Lo;0;AL;<font> 0646;;;;N;;;;;\n1EEAE;ARABIC MATHEMATICAL DOUBLE-STRUCK SEEN;Lo;0;AL;<font> 0633;;;;N;;;;;\n1EEAF;ARABIC MATHEMATICAL DOUBLE-STRUCK AIN;Lo;0;AL;<font> 0639;;;;N;;;;;\n1EEB0;ARABIC MATHEMATICAL DOUBLE-STRUCK FEH;Lo;0;AL;<font> 0641;;;;N;;;;;\n1EEB1;ARABIC MATHEMATICAL DOUBLE-STRUCK SAD;Lo;0;AL;<font> 0635;;;;N;;;;;\n1EEB2;ARABIC MATHEMATICAL DOUBLE-STRUCK QAF;Lo;0;AL;<font> 0642;;;;N;;;;;\n1EEB3;ARABIC MATHEMATICAL DOUBLE-STRUCK REH;Lo;0;AL;<font> 0631;;;;N;;;;;\n1EEB4;ARABIC MATHEMATICAL DOUBLE-STRUCK SHEEN;Lo;0;AL;<font> 0634;;;;N;;;;;\n1EEB5;ARABIC MATHEMATICAL DOUBLE-STRUCK TEH;Lo;0;AL;<font> 062A;;;;N;;;;;\n1EEB6;ARABIC MATHEMATICAL DOUBLE-STRUCK THEH;Lo;0;AL;<font> 062B;;;;N;;;;;\n1EEB7;ARABIC MATHEMATICAL DOUBLE-STRUCK KHAH;Lo;0;AL;<font> 062E;;;;N;;;;;\n1EEB8;ARABIC MATHEMATICAL DOUBLE-STRUCK THAL;Lo;0;AL;<font> 0630;;;;N;;;;;\n1EEB9;ARABIC MATHEMATICAL DOUBLE-STRUCK DAD;Lo;0;AL;<font> 0636;;;;N;;;;;\n1EEBA;ARABIC MATHEMATICAL DOUBLE-STRUCK ZAH;Lo;0;AL;<font> 0638;;;;N;;;;;\n1EEBB;ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN;Lo;0;AL;<font> 063A;;;;N;;;;;\n1EEF0;ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL;Sm;0;ON;;;;;N;;;;;\n1EEF1;ARABIC MATHEMATICAL OPERATOR HAH WITH DAL;Sm;0;ON;;;;;N;;;;;\n1F000;MAHJONG TILE EAST WIND;So;0;ON;;;;;N;;;;;\n1F001;MAHJONG TILE SOUTH WIND;So;0;ON;;;;;N;;;;;\n1F002;MAHJONG TILE WEST WIND;So;0;ON;;;;;N;;;;;\n1F003;MAHJONG TILE NORTH WIND;So;0;ON;;;;;N;;;;;\n1F004;MAHJONG TILE RED DRAGON;So;0;ON;;;;;N;;;;;\n1F005;MAHJONG TILE GREEN DRAGON;So;0;ON;;;;;N;;;;;\n1F006;MAHJONG TILE WHITE DRAGON;So;0;ON;;;;;N;;;;;\n1F007;MAHJONG TILE ONE OF CHARACTERS;So;0;ON;;;;;N;;;;;\n1F008;MAHJONG TILE TWO OF CHARACTERS;So;0;ON;;;;;N;;;;;\n1F009;MAHJONG TILE THREE OF CHARACTERS;So;0;ON;;;;;N;;;;;\n1F00A;MAHJONG TILE FOUR OF CHARACTERS;So;0;ON;;;;;N;;;;;\n1F00B;MAHJONG TILE FIVE OF CHARACTERS;So;0;ON;;;;;N;;;;;\n1F00C;MAHJONG TILE SIX OF CHARACTERS;So;0;ON;;;;;N;;;;;\n1F00D;MAHJONG TILE SEVEN OF CHARACTERS;So;0;ON;;;;;N;;;;;\n1F00E;MAHJONG TILE EIGHT OF CHARACTERS;So;0;ON;;;;;N;;;;;\n1F00F;MAHJONG TILE NINE OF CHARACTERS;So;0;ON;;;;;N;;;;;\n1F010;MAHJONG TILE ONE OF BAMBOOS;So;0;ON;;;;;N;;;;;\n1F011;MAHJONG TILE TWO OF BAMBOOS;So;0;ON;;;;;N;;;;;\n1F012;MAHJONG TILE THREE OF BAMBOOS;So;0;ON;;;;;N;;;;;\n1F013;MAHJONG TILE FOUR OF BAMBOOS;So;0;ON;;;;;N;;;;;\n1F014;MAHJONG TILE FIVE OF BAMBOOS;So;0;ON;;;;;N;;;;;\n1F015;MAHJONG TILE SIX OF BAMBOOS;So;0;ON;;;;;N;;;;;\n1F016;MAHJONG TILE SEVEN OF BAMBOOS;So;0;ON;;;;;N;;;;;\n1F017;MAHJONG TILE EIGHT OF BAMBOOS;So;0;ON;;;;;N;;;;;\n1F018;MAHJONG TILE NINE OF BAMBOOS;So;0;ON;;;;;N;;;;;\n1F019;MAHJONG TILE ONE OF CIRCLES;So;0;ON;;;;;N;;;;;\n1F01A;MAHJONG TILE TWO OF CIRCLES;So;0;ON;;;;;N;;;;;\n1F01B;MAHJONG TILE THREE OF CIRCLES;So;0;ON;;;;;N;;;;;\n1F01C;MAHJONG TILE FOUR OF CIRCLES;So;0;ON;;;;;N;;;;;\n1F01D;MAHJONG TILE FIVE OF CIRCLES;So;0;ON;;;;;N;;;;;\n1F01E;MAHJONG TILE SIX OF CIRCLES;So;0;ON;;;;;N;;;;;\n1F01F;MAHJONG TILE SEVEN OF CIRCLES;So;0;ON;;;;;N;;;;;\n1F020;MAHJONG TILE EIGHT OF CIRCLES;So;0;ON;;;;;N;;;;;\n1F021;MAHJONG TILE NINE OF CIRCLES;So;0;ON;;;;;N;;;;;\n1F022;MAHJONG TILE PLUM;So;0;ON;;;;;N;;;;;\n1F023;MAHJONG TILE ORCHID;So;0;ON;;;;;N;;;;;\n1F024;MAHJONG TILE BAMBOO;So;0;ON;;;;;N;;;;;\n1F025;MAHJONG TILE CHRYSANTHEMUM;So;0;ON;;;;;N;;;;;\n1F026;MAHJONG TILE SPRING;So;0;ON;;;;;N;;;;;\n1F027;MAHJONG TILE SUMMER;So;0;ON;;;;;N;;;;;\n1F028;MAHJONG TILE AUTUMN;So;0;ON;;;;;N;;;;;\n1F029;MAHJONG TILE WINTER;So;0;ON;;;;;N;;;;;\n1F02A;MAHJONG TILE JOKER;So;0;ON;;;;;N;;;;;\n1F02B;MAHJONG TILE BACK;So;0;ON;;;;;N;;;;;\n1F030;DOMINO TILE HORIZONTAL BACK;So;0;ON;;;;;N;;;;;\n1F031;DOMINO TILE HORIZONTAL-00-00;So;0;ON;;;;;N;;;;;\n1F032;DOMINO TILE HORIZONTAL-00-01;So;0;ON;;;;;N;;;;;\n1F033;DOMINO TILE HORIZONTAL-00-02;So;0;ON;;;;;N;;;;;\n1F034;DOMINO TILE HORIZONTAL-00-03;So;0;ON;;;;;N;;;;;\n1F035;DOMINO TILE HORIZONTAL-00-04;So;0;ON;;;;;N;;;;;\n1F036;DOMINO TILE HORIZONTAL-00-05;So;0;ON;;;;;N;;;;;\n1F037;DOMINO TILE HORIZONTAL-00-06;So;0;ON;;;;;N;;;;;\n1F038;DOMINO TILE HORIZONTAL-01-00;So;0;ON;;;;;N;;;;;\n1F039;DOMINO TILE HORIZONTAL-01-01;So;0;ON;;;;;N;;;;;\n1F03A;DOMINO TILE HORIZONTAL-01-02;So;0;ON;;;;;N;;;;;\n1F03B;DOMINO TILE HORIZONTAL-01-03;So;0;ON;;;;;N;;;;;\n1F03C;DOMINO TILE HORIZONTAL-01-04;So;0;ON;;;;;N;;;;;\n1F03D;DOMINO TILE HORIZONTAL-01-05;So;0;ON;;;;;N;;;;;\n1F03E;DOMINO TILE HORIZONTAL-01-06;So;0;ON;;;;;N;;;;;\n1F03F;DOMINO TILE HORIZONTAL-02-00;So;0;ON;;;;;N;;;;;\n1F040;DOMINO TILE HORIZONTAL-02-01;So;0;ON;;;;;N;;;;;\n1F041;DOMINO TILE HORIZONTAL-02-02;So;0;ON;;;;;N;;;;;\n1F042;DOMINO TILE HORIZONTAL-02-03;So;0;ON;;;;;N;;;;;\n1F043;DOMINO TILE HORIZONTAL-02-04;So;0;ON;;;;;N;;;;;\n1F044;DOMINO TILE HORIZONTAL-02-05;So;0;ON;;;;;N;;;;;\n1F045;DOMINO TILE HORIZONTAL-02-06;So;0;ON;;;;;N;;;;;\n1F046;DOMINO TILE HORIZONTAL-03-00;So;0;ON;;;;;N;;;;;\n1F047;DOMINO TILE HORIZONTAL-03-01;So;0;ON;;;;;N;;;;;\n1F048;DOMINO TILE HORIZONTAL-03-02;So;0;ON;;;;;N;;;;;\n1F049;DOMINO TILE HORIZONTAL-03-03;So;0;ON;;;;;N;;;;;\n1F04A;DOMINO TILE HORIZONTAL-03-04;So;0;ON;;;;;N;;;;;\n1F04B;DOMINO TILE HORIZONTAL-03-05;So;0;ON;;;;;N;;;;;\n1F04C;DOMINO TILE HORIZONTAL-03-06;So;0;ON;;;;;N;;;;;\n1F04D;DOMINO TILE HORIZONTAL-04-00;So;0;ON;;;;;N;;;;;\n1F04E;DOMINO TILE HORIZONTAL-04-01;So;0;ON;;;;;N;;;;;\n1F04F;DOMINO TILE HORIZONTAL-04-02;So;0;ON;;;;;N;;;;;\n1F050;DOMINO TILE HORIZONTAL-04-03;So;0;ON;;;;;N;;;;;\n1F051;DOMINO TILE HORIZONTAL-04-04;So;0;ON;;;;;N;;;;;\n1F052;DOMINO TILE HORIZONTAL-04-05;So;0;ON;;;;;N;;;;;\n1F053;DOMINO TILE HORIZONTAL-04-06;So;0;ON;;;;;N;;;;;\n1F054;DOMINO TILE HORIZONTAL-05-00;So;0;ON;;;;;N;;;;;\n1F055;DOMINO TILE HORIZONTAL-05-01;So;0;ON;;;;;N;;;;;\n1F056;DOMINO TILE HORIZONTAL-05-02;So;0;ON;;;;;N;;;;;\n1F057;DOMINO TILE HORIZONTAL-05-03;So;0;ON;;;;;N;;;;;\n1F058;DOMINO TILE HORIZONTAL-05-04;So;0;ON;;;;;N;;;;;\n1F059;DOMINO TILE HORIZONTAL-05-05;So;0;ON;;;;;N;;;;;\n1F05A;DOMINO TILE HORIZONTAL-05-06;So;0;ON;;;;;N;;;;;\n1F05B;DOMINO TILE HORIZONTAL-06-00;So;0;ON;;;;;N;;;;;\n1F05C;DOMINO TILE HORIZONTAL-06-01;So;0;ON;;;;;N;;;;;\n1F05D;DOMINO TILE HORIZONTAL-06-02;So;0;ON;;;;;N;;;;;\n1F05E;DOMINO TILE HORIZONTAL-06-03;So;0;ON;;;;;N;;;;;\n1F05F;DOMINO TILE HORIZONTAL-06-04;So;0;ON;;;;;N;;;;;\n1F060;DOMINO TILE HORIZONTAL-06-05;So;0;ON;;;;;N;;;;;\n1F061;DOMINO TILE HORIZONTAL-06-06;So;0;ON;;;;;N;;;;;\n1F062;DOMINO TILE VERTICAL BACK;So;0;ON;;;;;N;;;;;\n1F063;DOMINO TILE VERTICAL-00-00;So;0;ON;;;;;N;;;;;\n1F064;DOMINO TILE VERTICAL-00-01;So;0;ON;;;;;N;;;;;\n1F065;DOMINO TILE VERTICAL-00-02;So;0;ON;;;;;N;;;;;\n1F066;DOMINO TILE VERTICAL-00-03;So;0;ON;;;;;N;;;;;\n1F067;DOMINO TILE VERTICAL-00-04;So;0;ON;;;;;N;;;;;\n1F068;DOMINO TILE VERTICAL-00-05;So;0;ON;;;;;N;;;;;\n1F069;DOMINO TILE VERTICAL-00-06;So;0;ON;;;;;N;;;;;\n1F06A;DOMINO TILE VERTICAL-01-00;So;0;ON;;;;;N;;;;;\n1F06B;DOMINO TILE VERTICAL-01-01;So;0;ON;;;;;N;;;;;\n1F06C;DOMINO TILE VERTICAL-01-02;So;0;ON;;;;;N;;;;;\n1F06D;DOMINO TILE VERTICAL-01-03;So;0;ON;;;;;N;;;;;\n1F06E;DOMINO TILE VERTICAL-01-04;So;0;ON;;;;;N;;;;;\n1F06F;DOMINO TILE VERTICAL-01-05;So;0;ON;;;;;N;;;;;\n1F070;DOMINO TILE VERTICAL-01-06;So;0;ON;;;;;N;;;;;\n1F071;DOMINO TILE VERTICAL-02-00;So;0;ON;;;;;N;;;;;\n1F072;DOMINO TILE VERTICAL-02-01;So;0;ON;;;;;N;;;;;\n1F073;DOMINO TILE VERTICAL-02-02;So;0;ON;;;;;N;;;;;\n1F074;DOMINO TILE VERTICAL-02-03;So;0;ON;;;;;N;;;;;\n1F075;DOMINO TILE VERTICAL-02-04;So;0;ON;;;;;N;;;;;\n1F076;DOMINO TILE VERTICAL-02-05;So;0;ON;;;;;N;;;;;\n1F077;DOMINO TILE VERTICAL-02-06;So;0;ON;;;;;N;;;;;\n1F078;DOMINO TILE VERTICAL-03-00;So;0;ON;;;;;N;;;;;\n1F079;DOMINO TILE VERTICAL-03-01;So;0;ON;;;;;N;;;;;\n1F07A;DOMINO TILE VERTICAL-03-02;So;0;ON;;;;;N;;;;;\n1F07B;DOMINO TILE VERTICAL-03-03;So;0;ON;;;;;N;;;;;\n1F07C;DOMINO TILE VERTICAL-03-04;So;0;ON;;;;;N;;;;;\n1F07D;DOMINO TILE VERTICAL-03-05;So;0;ON;;;;;N;;;;;\n1F07E;DOMINO TILE VERTICAL-03-06;So;0;ON;;;;;N;;;;;\n1F07F;DOMINO TILE VERTICAL-04-00;So;0;ON;;;;;N;;;;;\n1F080;DOMINO TILE VERTICAL-04-01;So;0;ON;;;;;N;;;;;\n1F081;DOMINO TILE VERTICAL-04-02;So;0;ON;;;;;N;;;;;\n1F082;DOMINO TILE VERTICAL-04-03;So;0;ON;;;;;N;;;;;\n1F083;DOMINO TILE VERTICAL-04-04;So;0;ON;;;;;N;;;;;\n1F084;DOMINO TILE VERTICAL-04-05;So;0;ON;;;;;N;;;;;\n1F085;DOMINO TILE VERTICAL-04-06;So;0;ON;;;;;N;;;;;\n1F086;DOMINO TILE VERTICAL-05-00;So;0;ON;;;;;N;;;;;\n1F087;DOMINO TILE VERTICAL-05-01;So;0;ON;;;;;N;;;;;\n1F088;DOMINO TILE VERTICAL-05-02;So;0;ON;;;;;N;;;;;\n1F089;DOMINO TILE VERTICAL-05-03;So;0;ON;;;;;N;;;;;\n1F08A;DOMINO TILE VERTICAL-05-04;So;0;ON;;;;;N;;;;;\n1F08B;DOMINO TILE VERTICAL-05-05;So;0;ON;;;;;N;;;;;\n1F08C;DOMINO TILE VERTICAL-05-06;So;0;ON;;;;;N;;;;;\n1F08D;DOMINO TILE VERTICAL-06-00;So;0;ON;;;;;N;;;;;\n1F08E;DOMINO TILE VERTICAL-06-01;So;0;ON;;;;;N;;;;;\n1F08F;DOMINO TILE VERTICAL-06-02;So;0;ON;;;;;N;;;;;\n1F090;DOMINO TILE VERTICAL-06-03;So;0;ON;;;;;N;;;;;\n1F091;DOMINO TILE VERTICAL-06-04;So;0;ON;;;;;N;;;;;\n1F092;DOMINO TILE VERTICAL-06-05;So;0;ON;;;;;N;;;;;\n1F093;DOMINO TILE VERTICAL-06-06;So;0;ON;;;;;N;;;;;\n1F0A0;PLAYING CARD BACK;So;0;ON;;;;;N;;;;;\n1F0A1;PLAYING CARD ACE OF SPADES;So;0;ON;;;;;N;;;;;\n1F0A2;PLAYING CARD TWO OF SPADES;So;0;ON;;;;;N;;;;;\n1F0A3;PLAYING CARD THREE OF SPADES;So;0;ON;;;;;N;;;;;\n1F0A4;PLAYING CARD FOUR OF SPADES;So;0;ON;;;;;N;;;;;\n1F0A5;PLAYING CARD FIVE OF SPADES;So;0;ON;;;;;N;;;;;\n1F0A6;PLAYING CARD SIX OF SPADES;So;0;ON;;;;;N;;;;;\n1F0A7;PLAYING CARD SEVEN OF SPADES;So;0;ON;;;;;N;;;;;\n1F0A8;PLAYING CARD EIGHT OF SPADES;So;0;ON;;;;;N;;;;;\n1F0A9;PLAYING CARD NINE OF SPADES;So;0;ON;;;;;N;;;;;\n1F0AA;PLAYING CARD TEN OF SPADES;So;0;ON;;;;;N;;;;;\n1F0AB;PLAYING CARD JACK OF SPADES;So;0;ON;;;;;N;;;;;\n1F0AC;PLAYING CARD KNIGHT OF SPADES;So;0;ON;;;;;N;;;;;\n1F0AD;PLAYING CARD QUEEN OF SPADES;So;0;ON;;;;;N;;;;;\n1F0AE;PLAYING CARD KING OF SPADES;So;0;ON;;;;;N;;;;;\n1F0B1;PLAYING CARD ACE OF HEARTS;So;0;ON;;;;;N;;;;;\n1F0B2;PLAYING CARD TWO OF HEARTS;So;0;ON;;;;;N;;;;;\n1F0B3;PLAYING CARD THREE OF HEARTS;So;0;ON;;;;;N;;;;;\n1F0B4;PLAYING CARD FOUR OF HEARTS;So;0;ON;;;;;N;;;;;\n1F0B5;PLAYING CARD FIVE OF HEARTS;So;0;ON;;;;;N;;;;;\n1F0B6;PLAYING CARD SIX OF HEARTS;So;0;ON;;;;;N;;;;;\n1F0B7;PLAYING CARD SEVEN OF HEARTS;So;0;ON;;;;;N;;;;;\n1F0B8;PLAYING CARD EIGHT OF HEARTS;So;0;ON;;;;;N;;;;;\n1F0B9;PLAYING CARD NINE OF HEARTS;So;0;ON;;;;;N;;;;;\n1F0BA;PLAYING CARD TEN OF HEARTS;So;0;ON;;;;;N;;;;;\n1F0BB;PLAYING CARD JACK OF HEARTS;So;0;ON;;;;;N;;;;;\n1F0BC;PLAYING CARD KNIGHT OF HEARTS;So;0;ON;;;;;N;;;;;\n1F0BD;PLAYING CARD QUEEN OF HEARTS;So;0;ON;;;;;N;;;;;\n1F0BE;PLAYING CARD KING OF HEARTS;So;0;ON;;;;;N;;;;;\n1F0BF;PLAYING CARD RED JOKER;So;0;ON;;;;;N;;;;;\n1F0C1;PLAYING CARD ACE OF DIAMONDS;So;0;ON;;;;;N;;;;;\n1F0C2;PLAYING CARD TWO OF DIAMONDS;So;0;ON;;;;;N;;;;;\n1F0C3;PLAYING CARD THREE OF DIAMONDS;So;0;ON;;;;;N;;;;;\n1F0C4;PLAYING CARD FOUR OF DIAMONDS;So;0;ON;;;;;N;;;;;\n1F0C5;PLAYING CARD FIVE OF DIAMONDS;So;0;ON;;;;;N;;;;;\n1F0C6;PLAYING CARD SIX OF DIAMONDS;So;0;ON;;;;;N;;;;;\n1F0C7;PLAYING CARD SEVEN OF DIAMONDS;So;0;ON;;;;;N;;;;;\n1F0C8;PLAYING CARD EIGHT OF DIAMONDS;So;0;ON;;;;;N;;;;;\n1F0C9;PLAYING CARD NINE OF DIAMONDS;So;0;ON;;;;;N;;;;;\n1F0CA;PLAYING CARD TEN OF DIAMONDS;So;0;ON;;;;;N;;;;;\n1F0CB;PLAYING CARD JACK OF DIAMONDS;So;0;ON;;;;;N;;;;;\n1F0CC;PLAYING CARD KNIGHT OF DIAMONDS;So;0;ON;;;;;N;;;;;\n1F0CD;PLAYING CARD QUEEN OF DIAMONDS;So;0;ON;;;;;N;;;;;\n1F0CE;PLAYING CARD KING OF DIAMONDS;So;0;ON;;;;;N;;;;;\n1F0CF;PLAYING CARD BLACK JOKER;So;0;ON;;;;;N;;;;;\n1F0D1;PLAYING CARD ACE OF CLUBS;So;0;ON;;;;;N;;;;;\n1F0D2;PLAYING CARD TWO OF CLUBS;So;0;ON;;;;;N;;;;;\n1F0D3;PLAYING CARD THREE OF CLUBS;So;0;ON;;;;;N;;;;;\n1F0D4;PLAYING CARD FOUR OF CLUBS;So;0;ON;;;;;N;;;;;\n1F0D5;PLAYING CARD FIVE OF CLUBS;So;0;ON;;;;;N;;;;;\n1F0D6;PLAYING CARD SIX OF CLUBS;So;0;ON;;;;;N;;;;;\n1F0D7;PLAYING CARD SEVEN OF CLUBS;So;0;ON;;;;;N;;;;;\n1F0D8;PLAYING CARD EIGHT OF CLUBS;So;0;ON;;;;;N;;;;;\n1F0D9;PLAYING CARD NINE OF CLUBS;So;0;ON;;;;;N;;;;;\n1F0DA;PLAYING CARD TEN OF CLUBS;So;0;ON;;;;;N;;;;;\n1F0DB;PLAYING CARD JACK OF CLUBS;So;0;ON;;;;;N;;;;;\n1F0DC;PLAYING CARD KNIGHT OF CLUBS;So;0;ON;;;;;N;;;;;\n1F0DD;PLAYING CARD QUEEN OF CLUBS;So;0;ON;;;;;N;;;;;\n1F0DE;PLAYING CARD KING OF CLUBS;So;0;ON;;;;;N;;;;;\n1F0DF;PLAYING CARD WHITE JOKER;So;0;ON;;;;;N;;;;;\n1F0E0;PLAYING CARD FOOL;So;0;ON;;;;;N;;;;;\n1F0E1;PLAYING CARD TRUMP-1;So;0;ON;;;;;N;;;;;\n1F0E2;PLAYING CARD TRUMP-2;So;0;ON;;;;;N;;;;;\n1F0E3;PLAYING CARD TRUMP-3;So;0;ON;;;;;N;;;;;\n1F0E4;PLAYING CARD TRUMP-4;So;0;ON;;;;;N;;;;;\n1F0E5;PLAYING CARD TRUMP-5;So;0;ON;;;;;N;;;;;\n1F0E6;PLAYING CARD TRUMP-6;So;0;ON;;;;;N;;;;;\n1F0E7;PLAYING CARD TRUMP-7;So;0;ON;;;;;N;;;;;\n1F0E8;PLAYING CARD TRUMP-8;So;0;ON;;;;;N;;;;;\n1F0E9;PLAYING CARD TRUMP-9;So;0;ON;;;;;N;;;;;\n1F0EA;PLAYING CARD TRUMP-10;So;0;ON;;;;;N;;;;;\n1F0EB;PLAYING CARD TRUMP-11;So;0;ON;;;;;N;;;;;\n1F0EC;PLAYING CARD TRUMP-12;So;0;ON;;;;;N;;;;;\n1F0ED;PLAYING CARD TRUMP-13;So;0;ON;;;;;N;;;;;\n1F0EE;PLAYING CARD TRUMP-14;So;0;ON;;;;;N;;;;;\n1F0EF;PLAYING CARD TRUMP-15;So;0;ON;;;;;N;;;;;\n1F0F0;PLAYING CARD TRUMP-16;So;0;ON;;;;;N;;;;;\n1F0F1;PLAYING CARD TRUMP-17;So;0;ON;;;;;N;;;;;\n1F0F2;PLAYING CARD TRUMP-18;So;0;ON;;;;;N;;;;;\n1F0F3;PLAYING CARD TRUMP-19;So;0;ON;;;;;N;;;;;\n1F0F4;PLAYING CARD TRUMP-20;So;0;ON;;;;;N;;;;;\n1F0F5;PLAYING CARD TRUMP-21;So;0;ON;;;;;N;;;;;\n1F100;DIGIT ZERO FULL STOP;No;0;EN;<compat> 0030 002E;;0;0;N;;;;;\n1F101;DIGIT ZERO COMMA;No;0;EN;<compat> 0030 002C;;0;0;N;;;;;\n1F102;DIGIT ONE COMMA;No;0;EN;<compat> 0031 002C;;1;1;N;;;;;\n1F103;DIGIT TWO COMMA;No;0;EN;<compat> 0032 002C;;2;2;N;;;;;\n1F104;DIGIT THREE COMMA;No;0;EN;<compat> 0033 002C;;3;3;N;;;;;\n1F105;DIGIT FOUR COMMA;No;0;EN;<compat> 0034 002C;;4;4;N;;;;;\n1F106;DIGIT FIVE COMMA;No;0;EN;<compat> 0035 002C;;5;5;N;;;;;\n1F107;DIGIT SIX COMMA;No;0;EN;<compat> 0036 002C;;6;6;N;;;;;\n1F108;DIGIT SEVEN COMMA;No;0;EN;<compat> 0037 002C;;7;7;N;;;;;\n1F109;DIGIT EIGHT COMMA;No;0;EN;<compat> 0038 002C;;8;8;N;;;;;\n1F10A;DIGIT NINE COMMA;No;0;EN;<compat> 0039 002C;;9;9;N;;;;;\n1F10B;DINGBAT CIRCLED SANS-SERIF DIGIT ZERO;No;0;ON;;;;0;N;;;;;\n1F10C;DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ZERO;No;0;ON;;;;0;N;;;;;\n1F110;PARENTHESIZED LATIN CAPITAL LETTER A;So;0;L;<compat> 0028 0041 0029;;;;N;;;;;\n1F111;PARENTHESIZED LATIN CAPITAL LETTER B;So;0;L;<compat> 0028 0042 0029;;;;N;;;;;\n1F112;PARENTHESIZED LATIN CAPITAL LETTER C;So;0;L;<compat> 0028 0043 0029;;;;N;;;;;\n1F113;PARENTHESIZED LATIN CAPITAL LETTER D;So;0;L;<compat> 0028 0044 0029;;;;N;;;;;\n1F114;PARENTHESIZED LATIN CAPITAL LETTER E;So;0;L;<compat> 0028 0045 0029;;;;N;;;;;\n1F115;PARENTHESIZED LATIN CAPITAL LETTER F;So;0;L;<compat> 0028 0046 0029;;;;N;;;;;\n1F116;PARENTHESIZED LATIN CAPITAL LETTER G;So;0;L;<compat> 0028 0047 0029;;;;N;;;;;\n1F117;PARENTHESIZED LATIN CAPITAL LETTER H;So;0;L;<compat> 0028 0048 0029;;;;N;;;;;\n1F118;PARENTHESIZED LATIN CAPITAL LETTER I;So;0;L;<compat> 0028 0049 0029;;;;N;;;;;\n1F119;PARENTHESIZED LATIN CAPITAL LETTER J;So;0;L;<compat> 0028 004A 0029;;;;N;;;;;\n1F11A;PARENTHESIZED LATIN CAPITAL LETTER K;So;0;L;<compat> 0028 004B 0029;;;;N;;;;;\n1F11B;PARENTHESIZED LATIN CAPITAL LETTER L;So;0;L;<compat> 0028 004C 0029;;;;N;;;;;\n1F11C;PARENTHESIZED LATIN CAPITAL LETTER M;So;0;L;<compat> 0028 004D 0029;;;;N;;;;;\n1F11D;PARENTHESIZED LATIN CAPITAL LETTER N;So;0;L;<compat> 0028 004E 0029;;;;N;;;;;\n1F11E;PARENTHESIZED LATIN CAPITAL LETTER O;So;0;L;<compat> 0028 004F 0029;;;;N;;;;;\n1F11F;PARENTHESIZED LATIN CAPITAL LETTER P;So;0;L;<compat> 0028 0050 0029;;;;N;;;;;\n1F120;PARENTHESIZED LATIN CAPITAL LETTER Q;So;0;L;<compat> 0028 0051 0029;;;;N;;;;;\n1F121;PARENTHESIZED LATIN CAPITAL LETTER R;So;0;L;<compat> 0028 0052 0029;;;;N;;;;;\n1F122;PARENTHESIZED LATIN CAPITAL LETTER S;So;0;L;<compat> 0028 0053 0029;;;;N;;;;;\n1F123;PARENTHESIZED LATIN CAPITAL LETTER T;So;0;L;<compat> 0028 0054 0029;;;;N;;;;;\n1F124;PARENTHESIZED LATIN CAPITAL LETTER U;So;0;L;<compat> 0028 0055 0029;;;;N;;;;;\n1F125;PARENTHESIZED LATIN CAPITAL LETTER V;So;0;L;<compat> 0028 0056 0029;;;;N;;;;;\n1F126;PARENTHESIZED LATIN CAPITAL LETTER W;So;0;L;<compat> 0028 0057 0029;;;;N;;;;;\n1F127;PARENTHESIZED LATIN CAPITAL LETTER X;So;0;L;<compat> 0028 0058 0029;;;;N;;;;;\n1F128;PARENTHESIZED LATIN CAPITAL LETTER Y;So;0;L;<compat> 0028 0059 0029;;;;N;;;;;\n1F129;PARENTHESIZED LATIN CAPITAL LETTER Z;So;0;L;<compat> 0028 005A 0029;;;;N;;;;;\n1F12A;TORTOISE SHELL BRACKETED LATIN CAPITAL LETTER S;So;0;L;<compat> 3014 0053 3015;;;;N;;;;;\n1F12B;CIRCLED ITALIC LATIN CAPITAL LETTER C;So;0;L;<circle> 0043;;;;N;;;;;\n1F12C;CIRCLED ITALIC LATIN CAPITAL LETTER R;So;0;L;<circle> 0052;;;;N;;;;;\n1F12D;CIRCLED CD;So;0;L;<circle> 0043 0044;;;;N;;;;;\n1F12E;CIRCLED WZ;So;0;L;<circle> 0057 005A;;;;N;;;;;\n1F12F;COPYLEFT SYMBOL;So;0;ON;;;;;N;;;;;\n1F130;SQUARED LATIN CAPITAL LETTER A;So;0;L;<square> 0041;;;;N;;;;;\n1F131;SQUARED LATIN CAPITAL LETTER B;So;0;L;<square> 0042;;;;N;;;;;\n1F132;SQUARED LATIN CAPITAL LETTER C;So;0;L;<square> 0043;;;;N;;;;;\n1F133;SQUARED LATIN CAPITAL LETTER D;So;0;L;<square> 0044;;;;N;;;;;\n1F134;SQUARED LATIN CAPITAL LETTER E;So;0;L;<square> 0045;;;;N;;;;;\n1F135;SQUARED LATIN CAPITAL LETTER F;So;0;L;<square> 0046;;;;N;;;;;\n1F136;SQUARED LATIN CAPITAL LETTER G;So;0;L;<square> 0047;;;;N;;;;;\n1F137;SQUARED LATIN CAPITAL LETTER H;So;0;L;<square> 0048;;;;N;;;;;\n1F138;SQUARED LATIN CAPITAL LETTER I;So;0;L;<square> 0049;;;;N;;;;;\n1F139;SQUARED LATIN CAPITAL LETTER J;So;0;L;<square> 004A;;;;N;;;;;\n1F13A;SQUARED LATIN CAPITAL LETTER K;So;0;L;<square> 004B;;;;N;;;;;\n1F13B;SQUARED LATIN CAPITAL LETTER L;So;0;L;<square> 004C;;;;N;;;;;\n1F13C;SQUARED LATIN CAPITAL LETTER M;So;0;L;<square> 004D;;;;N;;;;;\n1F13D;SQUARED LATIN CAPITAL LETTER N;So;0;L;<square> 004E;;;;N;;;;;\n1F13E;SQUARED LATIN CAPITAL LETTER O;So;0;L;<square> 004F;;;;N;;;;;\n1F13F;SQUARED LATIN CAPITAL LETTER P;So;0;L;<square> 0050;;;;N;;;;;\n1F140;SQUARED LATIN CAPITAL LETTER Q;So;0;L;<square> 0051;;;;N;;;;;\n1F141;SQUARED LATIN CAPITAL LETTER R;So;0;L;<square> 0052;;;;N;;;;;\n1F142;SQUARED LATIN CAPITAL LETTER S;So;0;L;<square> 0053;;;;N;;;;;\n1F143;SQUARED LATIN CAPITAL LETTER T;So;0;L;<square> 0054;;;;N;;;;;\n1F144;SQUARED LATIN CAPITAL LETTER U;So;0;L;<square> 0055;;;;N;;;;;\n1F145;SQUARED LATIN CAPITAL LETTER V;So;0;L;<square> 0056;;;;N;;;;;\n1F146;SQUARED LATIN CAPITAL LETTER W;So;0;L;<square> 0057;;;;N;;;;;\n1F147;SQUARED LATIN CAPITAL LETTER X;So;0;L;<square> 0058;;;;N;;;;;\n1F148;SQUARED LATIN CAPITAL LETTER Y;So;0;L;<square> 0059;;;;N;;;;;\n1F149;SQUARED LATIN CAPITAL LETTER Z;So;0;L;<square> 005A;;;;N;;;;;\n1F14A;SQUARED HV;So;0;L;<square> 0048 0056;;;;N;;;;;\n1F14B;SQUARED MV;So;0;L;<square> 004D 0056;;;;N;;;;;\n1F14C;SQUARED SD;So;0;L;<square> 0053 0044;;;;N;;;;;\n1F14D;SQUARED SS;So;0;L;<square> 0053 0053;;;;N;;;;;\n1F14E;SQUARED PPV;So;0;L;<square> 0050 0050 0056;;;;N;;;;;\n1F14F;SQUARED WC;So;0;L;<square> 0057 0043;;;;N;;;;;\n1F150;NEGATIVE CIRCLED LATIN CAPITAL LETTER A;So;0;L;;;;;N;;;;;\n1F151;NEGATIVE CIRCLED LATIN CAPITAL LETTER B;So;0;L;;;;;N;;;;;\n1F152;NEGATIVE CIRCLED LATIN CAPITAL LETTER C;So;0;L;;;;;N;;;;;\n1F153;NEGATIVE CIRCLED LATIN CAPITAL LETTER D;So;0;L;;;;;N;;;;;\n1F154;NEGATIVE CIRCLED LATIN CAPITAL LETTER E;So;0;L;;;;;N;;;;;\n1F155;NEGATIVE CIRCLED LATIN CAPITAL LETTER F;So;0;L;;;;;N;;;;;\n1F156;NEGATIVE CIRCLED LATIN CAPITAL LETTER G;So;0;L;;;;;N;;;;;\n1F157;NEGATIVE CIRCLED LATIN CAPITAL LETTER H;So;0;L;;;;;N;;;;;\n1F158;NEGATIVE CIRCLED LATIN CAPITAL LETTER I;So;0;L;;;;;N;;;;;\n1F159;NEGATIVE CIRCLED LATIN CAPITAL LETTER J;So;0;L;;;;;N;;;;;\n1F15A;NEGATIVE CIRCLED LATIN CAPITAL LETTER K;So;0;L;;;;;N;;;;;\n1F15B;NEGATIVE CIRCLED LATIN CAPITAL LETTER L;So;0;L;;;;;N;;;;;\n1F15C;NEGATIVE CIRCLED LATIN CAPITAL LETTER M;So;0;L;;;;;N;;;;;\n1F15D;NEGATIVE CIRCLED LATIN CAPITAL LETTER N;So;0;L;;;;;N;;;;;\n1F15E;NEGATIVE CIRCLED LATIN CAPITAL LETTER O;So;0;L;;;;;N;;;;;\n1F15F;NEGATIVE CIRCLED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;;\n1F160;NEGATIVE CIRCLED LATIN CAPITAL LETTER Q;So;0;L;;;;;N;;;;;\n1F161;NEGATIVE CIRCLED LATIN CAPITAL LETTER R;So;0;L;;;;;N;;;;;\n1F162;NEGATIVE CIRCLED LATIN CAPITAL LETTER S;So;0;L;;;;;N;;;;;\n1F163;NEGATIVE CIRCLED LATIN CAPITAL LETTER T;So;0;L;;;;;N;;;;;\n1F164;NEGATIVE CIRCLED LATIN CAPITAL LETTER U;So;0;L;;;;;N;;;;;\n1F165;NEGATIVE CIRCLED LATIN CAPITAL LETTER V;So;0;L;;;;;N;;;;;\n1F166;NEGATIVE CIRCLED LATIN CAPITAL LETTER W;So;0;L;;;;;N;;;;;\n1F167;NEGATIVE CIRCLED LATIN CAPITAL LETTER X;So;0;L;;;;;N;;;;;\n1F168;NEGATIVE CIRCLED LATIN CAPITAL LETTER Y;So;0;L;;;;;N;;;;;\n1F169;NEGATIVE CIRCLED LATIN CAPITAL LETTER Z;So;0;L;;;;;N;;;;;\n1F16A;RAISED MC SIGN;So;0;ON;<super> 004D 0043;;;;N;;;;;\n1F16B;RAISED MD SIGN;So;0;ON;<super> 004D 0044;;;;N;;;;;\n1F16C;RAISED MR SIGN;So;0;ON;<super> 004D 0052;;;;N;;;;;\n1F170;NEGATIVE SQUARED LATIN CAPITAL LETTER A;So;0;L;;;;;N;;;;;\n1F171;NEGATIVE SQUARED LATIN CAPITAL LETTER B;So;0;L;;;;;N;;;;;\n1F172;NEGATIVE SQUARED LATIN CAPITAL LETTER C;So;0;L;;;;;N;;;;;\n1F173;NEGATIVE SQUARED LATIN CAPITAL LETTER D;So;0;L;;;;;N;;;;;\n1F174;NEGATIVE SQUARED LATIN CAPITAL LETTER E;So;0;L;;;;;N;;;;;\n1F175;NEGATIVE SQUARED LATIN CAPITAL LETTER F;So;0;L;;;;;N;;;;;\n1F176;NEGATIVE SQUARED LATIN CAPITAL LETTER G;So;0;L;;;;;N;;;;;\n1F177;NEGATIVE SQUARED LATIN CAPITAL LETTER H;So;0;L;;;;;N;;;;;\n1F178;NEGATIVE SQUARED LATIN CAPITAL LETTER I;So;0;L;;;;;N;;;;;\n1F179;NEGATIVE SQUARED LATIN CAPITAL LETTER J;So;0;L;;;;;N;;;;;\n1F17A;NEGATIVE SQUARED LATIN CAPITAL LETTER K;So;0;L;;;;;N;;;;;\n1F17B;NEGATIVE SQUARED LATIN CAPITAL LETTER L;So;0;L;;;;;N;;;;;\n1F17C;NEGATIVE SQUARED LATIN CAPITAL LETTER M;So;0;L;;;;;N;;;;;\n1F17D;NEGATIVE SQUARED LATIN CAPITAL LETTER N;So;0;L;;;;;N;;;;;\n1F17E;NEGATIVE SQUARED LATIN CAPITAL LETTER O;So;0;L;;;;;N;;;;;\n1F17F;NEGATIVE SQUARED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;;\n1F180;NEGATIVE SQUARED LATIN CAPITAL LETTER Q;So;0;L;;;;;N;;;;;\n1F181;NEGATIVE SQUARED LATIN CAPITAL LETTER R;So;0;L;;;;;N;;;;;\n1F182;NEGATIVE SQUARED LATIN CAPITAL LETTER S;So;0;L;;;;;N;;;;;\n1F183;NEGATIVE SQUARED LATIN CAPITAL LETTER T;So;0;L;;;;;N;;;;;\n1F184;NEGATIVE SQUARED LATIN CAPITAL LETTER U;So;0;L;;;;;N;;;;;\n1F185;NEGATIVE SQUARED LATIN CAPITAL LETTER V;So;0;L;;;;;N;;;;;\n1F186;NEGATIVE SQUARED LATIN CAPITAL LETTER W;So;0;L;;;;;N;;;;;\n1F187;NEGATIVE SQUARED LATIN CAPITAL LETTER X;So;0;L;;;;;N;;;;;\n1F188;NEGATIVE SQUARED LATIN CAPITAL LETTER Y;So;0;L;;;;;N;;;;;\n1F189;NEGATIVE SQUARED LATIN CAPITAL LETTER Z;So;0;L;;;;;N;;;;;\n1F18A;CROSSED NEGATIVE SQUARED LATIN CAPITAL LETTER P;So;0;L;;;;;N;;;;;\n1F18B;NEGATIVE SQUARED IC;So;0;L;;;;;N;;;;;\n1F18C;NEGATIVE SQUARED PA;So;0;L;;;;;N;;;;;\n1F18D;NEGATIVE SQUARED SA;So;0;L;;;;;N;;;;;\n1F18E;NEGATIVE SQUARED AB;So;0;L;;;;;N;;;;;\n1F18F;NEGATIVE SQUARED WC;So;0;L;;;;;N;;;;;\n1F190;SQUARE DJ;So;0;L;<square> 0044 004A;;;;N;;;;;\n1F191;SQUARED CL;So;0;L;;;;;N;;;;;\n1F192;SQUARED COOL;So;0;L;;;;;N;;;;;\n1F193;SQUARED FREE;So;0;L;;;;;N;;;;;\n1F194;SQUARED ID;So;0;L;;;;;N;;;;;\n1F195;SQUARED NEW;So;0;L;;;;;N;;;;;\n1F196;SQUARED NG;So;0;L;;;;;N;;;;;\n1F197;SQUARED OK;So;0;L;;;;;N;;;;;\n1F198;SQUARED SOS;So;0;L;;;;;N;;;;;\n1F199;SQUARED UP WITH EXCLAMATION MARK;So;0;L;;;;;N;;;;;\n1F19A;SQUARED VS;So;0;L;;;;;N;;;;;\n1F19B;SQUARED THREE D;So;0;L;;;;;N;;;;;\n1F19C;SQUARED SECOND SCREEN;So;0;L;;;;;N;;;;;\n1F19D;SQUARED TWO K;So;0;L;;;;;N;;;;;\n1F19E;SQUARED FOUR K;So;0;L;;;;;N;;;;;\n1F19F;SQUARED EIGHT K;So;0;L;;;;;N;;;;;\n1F1A0;SQUARED FIVE POINT ONE;So;0;L;;;;;N;;;;;\n1F1A1;SQUARED SEVEN POINT ONE;So;0;L;;;;;N;;;;;\n1F1A2;SQUARED TWENTY-TWO POINT TWO;So;0;L;;;;;N;;;;;\n1F1A3;SQUARED SIXTY P;So;0;L;;;;;N;;;;;\n1F1A4;SQUARED ONE HUNDRED TWENTY P;So;0;L;;;;;N;;;;;\n1F1A5;SQUARED LATIN SMALL LETTER D;So;0;L;;;;;N;;;;;\n1F1A6;SQUARED HC;So;0;L;;;;;N;;;;;\n1F1A7;SQUARED HDR;So;0;L;;;;;N;;;;;\n1F1A8;SQUARED HI-RES;So;0;L;;;;;N;;;;;\n1F1A9;SQUARED LOSSLESS;So;0;L;;;;;N;;;;;\n1F1AA;SQUARED SHV;So;0;L;;;;;N;;;;;\n1F1AB;SQUARED UHD;So;0;L;;;;;N;;;;;\n1F1AC;SQUARED VOD;So;0;L;;;;;N;;;;;\n1F1E6;REGIONAL INDICATOR SYMBOL LETTER A;So;0;L;;;;;N;;;;;\n1F1E7;REGIONAL INDICATOR SYMBOL LETTER B;So;0;L;;;;;N;;;;;\n1F1E8;REGIONAL INDICATOR SYMBOL LETTER C;So;0;L;;;;;N;;;;;\n1F1E9;REGIONAL INDICATOR SYMBOL LETTER D;So;0;L;;;;;N;;;;;\n1F1EA;REGIONAL INDICATOR SYMBOL LETTER E;So;0;L;;;;;N;;;;;\n1F1EB;REGIONAL INDICATOR SYMBOL LETTER F;So;0;L;;;;;N;;;;;\n1F1EC;REGIONAL INDICATOR SYMBOL LETTER G;So;0;L;;;;;N;;;;;\n1F1ED;REGIONAL INDICATOR SYMBOL LETTER H;So;0;L;;;;;N;;;;;\n1F1EE;REGIONAL INDICATOR SYMBOL LETTER I;So;0;L;;;;;N;;;;;\n1F1EF;REGIONAL INDICATOR SYMBOL LETTER J;So;0;L;;;;;N;;;;;\n1F1F0;REGIONAL INDICATOR SYMBOL LETTER K;So;0;L;;;;;N;;;;;\n1F1F1;REGIONAL INDICATOR SYMBOL LETTER L;So;0;L;;;;;N;;;;;\n1F1F2;REGIONAL INDICATOR SYMBOL LETTER M;So;0;L;;;;;N;;;;;\n1F1F3;REGIONAL INDICATOR SYMBOL LETTER N;So;0;L;;;;;N;;;;;\n1F1F4;REGIONAL INDICATOR SYMBOL LETTER O;So;0;L;;;;;N;;;;;\n1F1F5;REGIONAL INDICATOR SYMBOL LETTER P;So;0;L;;;;;N;;;;;\n1F1F6;REGIONAL INDICATOR SYMBOL LETTER Q;So;0;L;;;;;N;;;;;\n1F1F7;REGIONAL INDICATOR SYMBOL LETTER R;So;0;L;;;;;N;;;;;\n1F1F8;REGIONAL INDICATOR SYMBOL LETTER S;So;0;L;;;;;N;;;;;\n1F1F9;REGIONAL INDICATOR SYMBOL LETTER T;So;0;L;;;;;N;;;;;\n1F1FA;REGIONAL INDICATOR SYMBOL LETTER U;So;0;L;;;;;N;;;;;\n1F1FB;REGIONAL INDICATOR SYMBOL LETTER V;So;0;L;;;;;N;;;;;\n1F1FC;REGIONAL INDICATOR SYMBOL LETTER W;So;0;L;;;;;N;;;;;\n1F1FD;REGIONAL INDICATOR SYMBOL LETTER X;So;0;L;;;;;N;;;;;\n1F1FE;REGIONAL INDICATOR SYMBOL LETTER Y;So;0;L;;;;;N;;;;;\n1F1FF;REGIONAL INDICATOR SYMBOL LETTER Z;So;0;L;;;;;N;;;;;\n1F200;SQUARE HIRAGANA HOKA;So;0;L;<square> 307B 304B;;;;N;;;;;\n1F201;SQUARED KATAKANA KOKO;So;0;L;<square> 30B3 30B3;;;;N;;;;;\n1F202;SQUARED KATAKANA SA;So;0;L;<square> 30B5;;;;N;;;;;\n1F210;SQUARED CJK UNIFIED IDEOGRAPH-624B;So;0;L;<square> 624B;;;;N;;;;;\n1F211;SQUARED CJK UNIFIED IDEOGRAPH-5B57;So;0;L;<square> 5B57;;;;N;;;;;\n1F212;SQUARED CJK UNIFIED IDEOGRAPH-53CC;So;0;L;<square> 53CC;;;;N;;;;;\n1F213;SQUARED KATAKANA DE;So;0;L;<square> 30C7;;;;N;;;;;\n1F214;SQUARED CJK UNIFIED IDEOGRAPH-4E8C;So;0;L;<square> 4E8C;;;;N;;;;;\n1F215;SQUARED CJK UNIFIED IDEOGRAPH-591A;So;0;L;<square> 591A;;;;N;;;;;\n1F216;SQUARED CJK UNIFIED IDEOGRAPH-89E3;So;0;L;<square> 89E3;;;;N;;;;;\n1F217;SQUARED CJK UNIFIED IDEOGRAPH-5929;So;0;L;<square> 5929;;;;N;;;;;\n1F218;SQUARED CJK UNIFIED IDEOGRAPH-4EA4;So;0;L;<square> 4EA4;;;;N;;;;;\n1F219;SQUARED CJK UNIFIED IDEOGRAPH-6620;So;0;L;<square> 6620;;;;N;;;;;\n1F21A;SQUARED CJK UNIFIED IDEOGRAPH-7121;So;0;L;<square> 7121;;;;N;;;;;\n1F21B;SQUARED CJK UNIFIED IDEOGRAPH-6599;So;0;L;<square> 6599;;;;N;;;;;\n1F21C;SQUARED CJK UNIFIED IDEOGRAPH-524D;So;0;L;<square> 524D;;;;N;;;;;\n1F21D;SQUARED CJK UNIFIED IDEOGRAPH-5F8C;So;0;L;<square> 5F8C;;;;N;;;;;\n1F21E;SQUARED CJK UNIFIED IDEOGRAPH-518D;So;0;L;<square> 518D;;;;N;;;;;\n1F21F;SQUARED CJK UNIFIED IDEOGRAPH-65B0;So;0;L;<square> 65B0;;;;N;;;;;\n1F220;SQUARED CJK UNIFIED IDEOGRAPH-521D;So;0;L;<square> 521D;;;;N;;;;;\n1F221;SQUARED CJK UNIFIED IDEOGRAPH-7D42;So;0;L;<square> 7D42;;;;N;;;;;\n1F222;SQUARED CJK UNIFIED IDEOGRAPH-751F;So;0;L;<square> 751F;;;;N;;;;;\n1F223;SQUARED CJK UNIFIED IDEOGRAPH-8CA9;So;0;L;<square> 8CA9;;;;N;;;;;\n1F224;SQUARED CJK UNIFIED IDEOGRAPH-58F0;So;0;L;<square> 58F0;;;;N;;;;;\n1F225;SQUARED CJK UNIFIED IDEOGRAPH-5439;So;0;L;<square> 5439;;;;N;;;;;\n1F226;SQUARED CJK UNIFIED IDEOGRAPH-6F14;So;0;L;<square> 6F14;;;;N;;;;;\n1F227;SQUARED CJK UNIFIED IDEOGRAPH-6295;So;0;L;<square> 6295;;;;N;;;;;\n1F228;SQUARED CJK UNIFIED IDEOGRAPH-6355;So;0;L;<square> 6355;;;;N;;;;;\n1F229;SQUARED CJK UNIFIED IDEOGRAPH-4E00;So;0;L;<square> 4E00;;;;N;;;;;\n1F22A;SQUARED CJK UNIFIED IDEOGRAPH-4E09;So;0;L;<square> 4E09;;;;N;;;;;\n1F22B;SQUARED CJK UNIFIED IDEOGRAPH-904A;So;0;L;<square> 904A;;;;N;;;;;\n1F22C;SQUARED CJK UNIFIED IDEOGRAPH-5DE6;So;0;L;<square> 5DE6;;;;N;;;;;\n1F22D;SQUARED CJK UNIFIED IDEOGRAPH-4E2D;So;0;L;<square> 4E2D;;;;N;;;;;\n1F22E;SQUARED CJK UNIFIED IDEOGRAPH-53F3;So;0;L;<square> 53F3;;;;N;;;;;\n1F22F;SQUARED CJK UNIFIED IDEOGRAPH-6307;So;0;L;<square> 6307;;;;N;;;;;\n1F230;SQUARED CJK UNIFIED IDEOGRAPH-8D70;So;0;L;<square> 8D70;;;;N;;;;;\n1F231;SQUARED CJK UNIFIED IDEOGRAPH-6253;So;0;L;<square> 6253;;;;N;;;;;\n1F232;SQUARED CJK UNIFIED IDEOGRAPH-7981;So;0;L;<square> 7981;;;;N;;;;;\n1F233;SQUARED CJK UNIFIED IDEOGRAPH-7A7A;So;0;L;<square> 7A7A;;;;N;;;;;\n1F234;SQUARED CJK UNIFIED IDEOGRAPH-5408;So;0;L;<square> 5408;;;;N;;;;;\n1F235;SQUARED CJK UNIFIED IDEOGRAPH-6E80;So;0;L;<square> 6E80;;;;N;;;;;\n1F236;SQUARED CJK UNIFIED IDEOGRAPH-6709;So;0;L;<square> 6709;;;;N;;;;;\n1F237;SQUARED CJK UNIFIED IDEOGRAPH-6708;So;0;L;<square> 6708;;;;N;;;;;\n1F238;SQUARED CJK UNIFIED IDEOGRAPH-7533;So;0;L;<square> 7533;;;;N;;;;;\n1F239;SQUARED CJK UNIFIED IDEOGRAPH-5272;So;0;L;<square> 5272;;;;N;;;;;\n1F23A;SQUARED CJK UNIFIED IDEOGRAPH-55B6;So;0;L;<square> 55B6;;;;N;;;;;\n1F23B;SQUARED CJK UNIFIED IDEOGRAPH-914D;So;0;L;<square> 914D;;;;N;;;;;\n1F240;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-672C;So;0;L;<compat> 3014 672C 3015;;;;N;;;;;\n1F241;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E09;So;0;L;<compat> 3014 4E09 3015;;;;N;;;;;\n1F242;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-4E8C;So;0;L;<compat> 3014 4E8C 3015;;;;N;;;;;\n1F243;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-5B89;So;0;L;<compat> 3014 5B89 3015;;;;N;;;;;\n1F244;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-70B9;So;0;L;<compat> 3014 70B9 3015;;;;N;;;;;\n1F245;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6253;So;0;L;<compat> 3014 6253 3015;;;;N;;;;;\n1F246;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-76D7;So;0;L;<compat> 3014 76D7 3015;;;;N;;;;;\n1F247;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-52DD;So;0;L;<compat> 3014 52DD 3015;;;;N;;;;;\n1F248;TORTOISE SHELL BRACKETED CJK UNIFIED IDEOGRAPH-6557;So;0;L;<compat> 3014 6557 3015;;;;N;;;;;\n1F250;CIRCLED IDEOGRAPH ADVANTAGE;So;0;L;<circle> 5F97;;;;N;;;;;\n1F251;CIRCLED IDEOGRAPH ACCEPT;So;0;L;<circle> 53EF;;;;N;;;;;\n1F260;ROUNDED SYMBOL FOR FU;So;0;ON;;;;;N;;;;;\n1F261;ROUNDED SYMBOL FOR LU;So;0;ON;;;;;N;;;;;\n1F262;ROUNDED SYMBOL FOR SHOU;So;0;ON;;;;;N;;;;;\n1F263;ROUNDED SYMBOL FOR XI;So;0;ON;;;;;N;;;;;\n1F264;ROUNDED SYMBOL FOR SHUANGXI;So;0;ON;;;;;N;;;;;\n1F265;ROUNDED SYMBOL FOR CAI;So;0;ON;;;;;N;;;;;\n1F300;CYCLONE;So;0;ON;;;;;N;;;;;\n1F301;FOGGY;So;0;ON;;;;;N;;;;;\n1F302;CLOSED UMBRELLA;So;0;ON;;;;;N;;;;;\n1F303;NIGHT WITH STARS;So;0;ON;;;;;N;;;;;\n1F304;SUNRISE OVER MOUNTAINS;So;0;ON;;;;;N;;;;;\n1F305;SUNRISE;So;0;ON;;;;;N;;;;;\n1F306;CITYSCAPE AT DUSK;So;0;ON;;;;;N;;;;;\n1F307;SUNSET OVER BUILDINGS;So;0;ON;;;;;N;;;;;\n1F308;RAINBOW;So;0;ON;;;;;N;;;;;\n1F309;BRIDGE AT NIGHT;So;0;ON;;;;;N;;;;;\n1F30A;WATER WAVE;So;0;ON;;;;;N;;;;;\n1F30B;VOLCANO;So;0;ON;;;;;N;;;;;\n1F30C;MILKY WAY;So;0;ON;;;;;N;;;;;\n1F30D;EARTH GLOBE EUROPE-AFRICA;So;0;ON;;;;;N;;;;;\n1F30E;EARTH GLOBE AMERICAS;So;0;ON;;;;;N;;;;;\n1F30F;EARTH GLOBE ASIA-AUSTRALIA;So;0;ON;;;;;N;;;;;\n1F310;GLOBE WITH MERIDIANS;So;0;ON;;;;;N;;;;;\n1F311;NEW MOON SYMBOL;So;0;ON;;;;;N;;;;;\n1F312;WAXING CRESCENT MOON SYMBOL;So;0;ON;;;;;N;;;;;\n1F313;FIRST QUARTER MOON SYMBOL;So;0;ON;;;;;N;;;;;\n1F314;WAXING GIBBOUS MOON SYMBOL;So;0;ON;;;;;N;;;;;\n1F315;FULL MOON SYMBOL;So;0;ON;;;;;N;;;;;\n1F316;WANING GIBBOUS MOON SYMBOL;So;0;ON;;;;;N;;;;;\n1F317;LAST QUARTER MOON SYMBOL;So;0;ON;;;;;N;;;;;\n1F318;WANING CRESCENT MOON SYMBOL;So;0;ON;;;;;N;;;;;\n1F319;CRESCENT MOON;So;0;ON;;;;;N;;;;;\n1F31A;NEW MOON WITH FACE;So;0;ON;;;;;N;;;;;\n1F31B;FIRST QUARTER MOON WITH FACE;So;0;ON;;;;;N;;;;;\n1F31C;LAST QUARTER MOON WITH FACE;So;0;ON;;;;;N;;;;;\n1F31D;FULL MOON WITH FACE;So;0;ON;;;;;N;;;;;\n1F31E;SUN WITH FACE;So;0;ON;;;;;N;;;;;\n1F31F;GLOWING STAR;So;0;ON;;;;;N;;;;;\n1F320;SHOOTING STAR;So;0;ON;;;;;N;;;;;\n1F321;THERMOMETER;So;0;ON;;;;;N;;;;;\n1F322;BLACK DROPLET;So;0;ON;;;;;N;;;;;\n1F323;WHITE SUN;So;0;ON;;;;;N;;;;;\n1F324;WHITE SUN WITH SMALL CLOUD;So;0;ON;;;;;N;;;;;\n1F325;WHITE SUN BEHIND CLOUD;So;0;ON;;;;;N;;;;;\n1F326;WHITE SUN BEHIND CLOUD WITH RAIN;So;0;ON;;;;;N;;;;;\n1F327;CLOUD WITH RAIN;So;0;ON;;;;;N;;;;;\n1F328;CLOUD WITH SNOW;So;0;ON;;;;;N;;;;;\n1F329;CLOUD WITH LIGHTNING;So;0;ON;;;;;N;;;;;\n1F32A;CLOUD WITH TORNADO;So;0;ON;;;;;N;;;;;\n1F32B;FOG;So;0;ON;;;;;N;;;;;\n1F32C;WIND BLOWING FACE;So;0;ON;;;;;N;;;;;\n1F32D;HOT DOG;So;0;ON;;;;;N;;;;;\n1F32E;TACO;So;0;ON;;;;;N;;;;;\n1F32F;BURRITO;So;0;ON;;;;;N;;;;;\n1F330;CHESTNUT;So;0;ON;;;;;N;;;;;\n1F331;SEEDLING;So;0;ON;;;;;N;;;;;\n1F332;EVERGREEN TREE;So;0;ON;;;;;N;;;;;\n1F333;DECIDUOUS TREE;So;0;ON;;;;;N;;;;;\n1F334;PALM TREE;So;0;ON;;;;;N;;;;;\n1F335;CACTUS;So;0;ON;;;;;N;;;;;\n1F336;HOT PEPPER;So;0;ON;;;;;N;;;;;\n1F337;TULIP;So;0;ON;;;;;N;;;;;\n1F338;CHERRY BLOSSOM;So;0;ON;;;;;N;;;;;\n1F339;ROSE;So;0;ON;;;;;N;;;;;\n1F33A;HIBISCUS;So;0;ON;;;;;N;;;;;\n1F33B;SUNFLOWER;So;0;ON;;;;;N;;;;;\n1F33C;BLOSSOM;So;0;ON;;;;;N;;;;;\n1F33D;EAR OF MAIZE;So;0;ON;;;;;N;;;;;\n1F33E;EAR OF RICE;So;0;ON;;;;;N;;;;;\n1F33F;HERB;So;0;ON;;;;;N;;;;;\n1F340;FOUR LEAF CLOVER;So;0;ON;;;;;N;;;;;\n1F341;MAPLE LEAF;So;0;ON;;;;;N;;;;;\n1F342;FALLEN LEAF;So;0;ON;;;;;N;;;;;\n1F343;LEAF FLUTTERING IN WIND;So;0;ON;;;;;N;;;;;\n1F344;MUSHROOM;So;0;ON;;;;;N;;;;;\n1F345;TOMATO;So;0;ON;;;;;N;;;;;\n1F346;AUBERGINE;So;0;ON;;;;;N;;;;;\n1F347;GRAPES;So;0;ON;;;;;N;;;;;\n1F348;MELON;So;0;ON;;;;;N;;;;;\n1F349;WATERMELON;So;0;ON;;;;;N;;;;;\n1F34A;TANGERINE;So;0;ON;;;;;N;;;;;\n1F34B;LEMON;So;0;ON;;;;;N;;;;;\n1F34C;BANANA;So;0;ON;;;;;N;;;;;\n1F34D;PINEAPPLE;So;0;ON;;;;;N;;;;;\n1F34E;RED APPLE;So;0;ON;;;;;N;;;;;\n1F34F;GREEN APPLE;So;0;ON;;;;;N;;;;;\n1F350;PEAR;So;0;ON;;;;;N;;;;;\n1F351;PEACH;So;0;ON;;;;;N;;;;;\n1F352;CHERRIES;So;0;ON;;;;;N;;;;;\n1F353;STRAWBERRY;So;0;ON;;;;;N;;;;;\n1F354;HAMBURGER;So;0;ON;;;;;N;;;;;\n1F355;SLICE OF PIZZA;So;0;ON;;;;;N;;;;;\n1F356;MEAT ON BONE;So;0;ON;;;;;N;;;;;\n1F357;POULTRY LEG;So;0;ON;;;;;N;;;;;\n1F358;RICE CRACKER;So;0;ON;;;;;N;;;;;\n1F359;RICE BALL;So;0;ON;;;;;N;;;;;\n1F35A;COOKED RICE;So;0;ON;;;;;N;;;;;\n1F35B;CURRY AND RICE;So;0;ON;;;;;N;;;;;\n1F35C;STEAMING BOWL;So;0;ON;;;;;N;;;;;\n1F35D;SPAGHETTI;So;0;ON;;;;;N;;;;;\n1F35E;BREAD;So;0;ON;;;;;N;;;;;\n1F35F;FRENCH FRIES;So;0;ON;;;;;N;;;;;\n1F360;ROASTED SWEET POTATO;So;0;ON;;;;;N;;;;;\n1F361;DANGO;So;0;ON;;;;;N;;;;;\n1F362;ODEN;So;0;ON;;;;;N;;;;;\n1F363;SUSHI;So;0;ON;;;;;N;;;;;\n1F364;FRIED SHRIMP;So;0;ON;;;;;N;;;;;\n1F365;FISH CAKE WITH SWIRL DESIGN;So;0;ON;;;;;N;;;;;\n1F366;SOFT ICE CREAM;So;0;ON;;;;;N;;;;;\n1F367;SHAVED ICE;So;0;ON;;;;;N;;;;;\n1F368;ICE CREAM;So;0;ON;;;;;N;;;;;\n1F369;DOUGHNUT;So;0;ON;;;;;N;;;;;\n1F36A;COOKIE;So;0;ON;;;;;N;;;;;\n1F36B;CHOCOLATE BAR;So;0;ON;;;;;N;;;;;\n1F36C;CANDY;So;0;ON;;;;;N;;;;;\n1F36D;LOLLIPOP;So;0;ON;;;;;N;;;;;\n1F36E;CUSTARD;So;0;ON;;;;;N;;;;;\n1F36F;HONEY POT;So;0;ON;;;;;N;;;;;\n1F370;SHORTCAKE;So;0;ON;;;;;N;;;;;\n1F371;BENTO BOX;So;0;ON;;;;;N;;;;;\n1F372;POT OF FOOD;So;0;ON;;;;;N;;;;;\n1F373;COOKING;So;0;ON;;;;;N;;;;;\n1F374;FORK AND KNIFE;So;0;ON;;;;;N;;;;;\n1F375;TEACUP WITHOUT HANDLE;So;0;ON;;;;;N;;;;;\n1F376;SAKE BOTTLE AND CUP;So;0;ON;;;;;N;;;;;\n1F377;WINE GLASS;So;0;ON;;;;;N;;;;;\n1F378;COCKTAIL GLASS;So;0;ON;;;;;N;;;;;\n1F379;TROPICAL DRINK;So;0;ON;;;;;N;;;;;\n1F37A;BEER MUG;So;0;ON;;;;;N;;;;;\n1F37B;CLINKING BEER MUGS;So;0;ON;;;;;N;;;;;\n1F37C;BABY BOTTLE;So;0;ON;;;;;N;;;;;\n1F37D;FORK AND KNIFE WITH PLATE;So;0;ON;;;;;N;;;;;\n1F37E;BOTTLE WITH POPPING CORK;So;0;ON;;;;;N;;;;;\n1F37F;POPCORN;So;0;ON;;;;;N;;;;;\n1F380;RIBBON;So;0;ON;;;;;N;;;;;\n1F381;WRAPPED PRESENT;So;0;ON;;;;;N;;;;;\n1F382;BIRTHDAY CAKE;So;0;ON;;;;;N;;;;;\n1F383;JACK-O-LANTERN;So;0;ON;;;;;N;;;;;\n1F384;CHRISTMAS TREE;So;0;ON;;;;;N;;;;;\n1F385;FATHER CHRISTMAS;So;0;ON;;;;;N;;;;;\n1F386;FIREWORKS;So;0;ON;;;;;N;;;;;\n1F387;FIREWORK SPARKLER;So;0;ON;;;;;N;;;;;\n1F388;BALLOON;So;0;ON;;;;;N;;;;;\n1F389;PARTY POPPER;So;0;ON;;;;;N;;;;;\n1F38A;CONFETTI BALL;So;0;ON;;;;;N;;;;;\n1F38B;TANABATA TREE;So;0;ON;;;;;N;;;;;\n1F38C;CROSSED FLAGS;So;0;ON;;;;;N;;;;;\n1F38D;PINE DECORATION;So;0;ON;;;;;N;;;;;\n1F38E;JAPANESE DOLLS;So;0;ON;;;;;N;;;;;\n1F38F;CARP STREAMER;So;0;ON;;;;;N;;;;;\n1F390;WIND CHIME;So;0;ON;;;;;N;;;;;\n1F391;MOON VIEWING CEREMONY;So;0;ON;;;;;N;;;;;\n1F392;SCHOOL SATCHEL;So;0;ON;;;;;N;;;;;\n1F393;GRADUATION CAP;So;0;ON;;;;;N;;;;;\n1F394;HEART WITH TIP ON THE LEFT;So;0;ON;;;;;N;;;;;\n1F395;BOUQUET OF FLOWERS;So;0;ON;;;;;N;;;;;\n1F396;MILITARY MEDAL;So;0;ON;;;;;N;;;;;\n1F397;REMINDER RIBBON;So;0;ON;;;;;N;;;;;\n1F398;MUSICAL KEYBOARD WITH JACKS;So;0;ON;;;;;N;;;;;\n1F399;STUDIO MICROPHONE;So;0;ON;;;;;N;;;;;\n1F39A;LEVEL SLIDER;So;0;ON;;;;;N;;;;;\n1F39B;CONTROL KNOBS;So;0;ON;;;;;N;;;;;\n1F39C;BEAMED ASCENDING MUSICAL NOTES;So;0;ON;;;;;N;;;;;\n1F39D;BEAMED DESCENDING MUSICAL NOTES;So;0;ON;;;;;N;;;;;\n1F39E;FILM FRAMES;So;0;ON;;;;;N;;;;;\n1F39F;ADMISSION TICKETS;So;0;ON;;;;;N;;;;;\n1F3A0;CAROUSEL HORSE;So;0;ON;;;;;N;;;;;\n1F3A1;FERRIS WHEEL;So;0;ON;;;;;N;;;;;\n1F3A2;ROLLER COASTER;So;0;ON;;;;;N;;;;;\n1F3A3;FISHING POLE AND FISH;So;0;ON;;;;;N;;;;;\n1F3A4;MICROPHONE;So;0;ON;;;;;N;;;;;\n1F3A5;MOVIE CAMERA;So;0;ON;;;;;N;;;;;\n1F3A6;CINEMA;So;0;ON;;;;;N;;;;;\n1F3A7;HEADPHONE;So;0;ON;;;;;N;;;;;\n1F3A8;ARTIST PALETTE;So;0;ON;;;;;N;;;;;\n1F3A9;TOP HAT;So;0;ON;;;;;N;;;;;\n1F3AA;CIRCUS TENT;So;0;ON;;;;;N;;;;;\n1F3AB;TICKET;So;0;ON;;;;;N;;;;;\n1F3AC;CLAPPER BOARD;So;0;ON;;;;;N;;;;;\n1F3AD;PERFORMING ARTS;So;0;ON;;;;;N;;;;;\n1F3AE;VIDEO GAME;So;0;ON;;;;;N;;;;;\n1F3AF;DIRECT HIT;So;0;ON;;;;;N;;;;;\n1F3B0;SLOT MACHINE;So;0;ON;;;;;N;;;;;\n1F3B1;BILLIARDS;So;0;ON;;;;;N;;;;;\n1F3B2;GAME DIE;So;0;ON;;;;;N;;;;;\n1F3B3;BOWLING;So;0;ON;;;;;N;;;;;\n1F3B4;FLOWER PLAYING CARDS;So;0;ON;;;;;N;;;;;\n1F3B5;MUSICAL NOTE;So;0;ON;;;;;N;;;;;\n1F3B6;MULTIPLE MUSICAL NOTES;So;0;ON;;;;;N;;;;;\n1F3B7;SAXOPHONE;So;0;ON;;;;;N;;;;;\n1F3B8;GUITAR;So;0;ON;;;;;N;;;;;\n1F3B9;MUSICAL KEYBOARD;So;0;ON;;;;;N;;;;;\n1F3BA;TRUMPET;So;0;ON;;;;;N;;;;;\n1F3BB;VIOLIN;So;0;ON;;;;;N;;;;;\n1F3BC;MUSICAL SCORE;So;0;ON;;;;;N;;;;;\n1F3BD;RUNNING SHIRT WITH SASH;So;0;ON;;;;;N;;;;;\n1F3BE;TENNIS RACQUET AND BALL;So;0;ON;;;;;N;;;;;\n1F3BF;SKI AND SKI BOOT;So;0;ON;;;;;N;;;;;\n1F3C0;BASKETBALL AND HOOP;So;0;ON;;;;;N;;;;;\n1F3C1;CHEQUERED FLAG;So;0;ON;;;;;N;;;;;\n1F3C2;SNOWBOARDER;So;0;ON;;;;;N;;;;;\n1F3C3;RUNNER;So;0;ON;;;;;N;;;;;\n1F3C4;SURFER;So;0;ON;;;;;N;;;;;\n1F3C5;SPORTS MEDAL;So;0;ON;;;;;N;;;;;\n1F3C6;TROPHY;So;0;ON;;;;;N;;;;;\n1F3C7;HORSE RACING;So;0;ON;;;;;N;;;;;\n1F3C8;AMERICAN FOOTBALL;So;0;ON;;;;;N;;;;;\n1F3C9;RUGBY FOOTBALL;So;0;ON;;;;;N;;;;;\n1F3CA;SWIMMER;So;0;ON;;;;;N;;;;;\n1F3CB;WEIGHT LIFTER;So;0;ON;;;;;N;;;;;\n1F3CC;GOLFER;So;0;ON;;;;;N;;;;;\n1F3CD;RACING MOTORCYCLE;So;0;ON;;;;;N;;;;;\n1F3CE;RACING CAR;So;0;ON;;;;;N;;;;;\n1F3CF;CRICKET BAT AND BALL;So;0;ON;;;;;N;;;;;\n1F3D0;VOLLEYBALL;So;0;ON;;;;;N;;;;;\n1F3D1;FIELD HOCKEY STICK AND BALL;So;0;ON;;;;;N;;;;;\n1F3D2;ICE HOCKEY STICK AND PUCK;So;0;ON;;;;;N;;;;;\n1F3D3;TABLE TENNIS PADDLE AND BALL;So;0;ON;;;;;N;;;;;\n1F3D4;SNOW CAPPED MOUNTAIN;So;0;ON;;;;;N;;;;;\n1F3D5;CAMPING;So;0;ON;;;;;N;;;;;\n1F3D6;BEACH WITH UMBRELLA;So;0;ON;;;;;N;;;;;\n1F3D7;BUILDING CONSTRUCTION;So;0;ON;;;;;N;;;;;\n1F3D8;HOUSE BUILDINGS;So;0;ON;;;;;N;;;;;\n1F3D9;CITYSCAPE;So;0;ON;;;;;N;;;;;\n1F3DA;DERELICT HOUSE BUILDING;So;0;ON;;;;;N;;;;;\n1F3DB;CLASSICAL BUILDING;So;0;ON;;;;;N;;;;;\n1F3DC;DESERT;So;0;ON;;;;;N;;;;;\n1F3DD;DESERT ISLAND;So;0;ON;;;;;N;;;;;\n1F3DE;NATIONAL PARK;So;0;ON;;;;;N;;;;;\n1F3DF;STADIUM;So;0;ON;;;;;N;;;;;\n1F3E0;HOUSE BUILDING;So;0;ON;;;;;N;;;;;\n1F3E1;HOUSE WITH GARDEN;So;0;ON;;;;;N;;;;;\n1F3E2;OFFICE BUILDING;So;0;ON;;;;;N;;;;;\n1F3E3;JAPANESE POST OFFICE;So;0;ON;;;;;N;;;;;\n1F3E4;EUROPEAN POST OFFICE;So;0;ON;;;;;N;;;;;\n1F3E5;HOSPITAL;So;0;ON;;;;;N;;;;;\n1F3E6;BANK;So;0;ON;;;;;N;;;;;\n1F3E7;AUTOMATED TELLER MACHINE;So;0;ON;;;;;N;;;;;\n1F3E8;HOTEL;So;0;ON;;;;;N;;;;;\n1F3E9;LOVE HOTEL;So;0;ON;;;;;N;;;;;\n1F3EA;CONVENIENCE STORE;So;0;ON;;;;;N;;;;;\n1F3EB;SCHOOL;So;0;ON;;;;;N;;;;;\n1F3EC;DEPARTMENT STORE;So;0;ON;;;;;N;;;;;\n1F3ED;FACTORY;So;0;ON;;;;;N;;;;;\n1F3EE;IZAKAYA LANTERN;So;0;ON;;;;;N;;;;;\n1F3EF;JAPANESE CASTLE;So;0;ON;;;;;N;;;;;\n1F3F0;EUROPEAN CASTLE;So;0;ON;;;;;N;;;;;\n1F3F1;WHITE PENNANT;So;0;ON;;;;;N;;;;;\n1F3F2;BLACK PENNANT;So;0;ON;;;;;N;;;;;\n1F3F3;WAVING WHITE FLAG;So;0;ON;;;;;N;;;;;\n1F3F4;WAVING BLACK FLAG;So;0;ON;;;;;N;;;;;\n1F3F5;ROSETTE;So;0;ON;;;;;N;;;;;\n1F3F6;BLACK ROSETTE;So;0;ON;;;;;N;;;;;\n1F3F7;LABEL;So;0;ON;;;;;N;;;;;\n1F3F8;BADMINTON RACQUET AND SHUTTLECOCK;So;0;ON;;;;;N;;;;;\n1F3F9;BOW AND ARROW;So;0;ON;;;;;N;;;;;\n1F3FA;AMPHORA;So;0;ON;;;;;N;;;;;\n1F3FB;EMOJI MODIFIER FITZPATRICK TYPE-1-2;Sk;0;ON;;;;;N;;;;;\n1F3FC;EMOJI MODIFIER FITZPATRICK TYPE-3;Sk;0;ON;;;;;N;;;;;\n1F3FD;EMOJI MODIFIER FITZPATRICK TYPE-4;Sk;0;ON;;;;;N;;;;;\n1F3FE;EMOJI MODIFIER FITZPATRICK TYPE-5;Sk;0;ON;;;;;N;;;;;\n1F3FF;EMOJI MODIFIER FITZPATRICK TYPE-6;Sk;0;ON;;;;;N;;;;;\n1F400;RAT;So;0;ON;;;;;N;;;;;\n1F401;MOUSE;So;0;ON;;;;;N;;;;;\n1F402;OX;So;0;ON;;;;;N;;;;;\n1F403;WATER BUFFALO;So;0;ON;;;;;N;;;;;\n1F404;COW;So;0;ON;;;;;N;;;;;\n1F405;TIGER;So;0;ON;;;;;N;;;;;\n1F406;LEOPARD;So;0;ON;;;;;N;;;;;\n1F407;RABBIT;So;0;ON;;;;;N;;;;;\n1F408;CAT;So;0;ON;;;;;N;;;;;\n1F409;DRAGON;So;0;ON;;;;;N;;;;;\n1F40A;CROCODILE;So;0;ON;;;;;N;;;;;\n1F40B;WHALE;So;0;ON;;;;;N;;;;;\n1F40C;SNAIL;So;0;ON;;;;;N;;;;;\n1F40D;SNAKE;So;0;ON;;;;;N;;;;;\n1F40E;HORSE;So;0;ON;;;;;N;;;;;\n1F40F;RAM;So;0;ON;;;;;N;;;;;\n1F410;GOAT;So;0;ON;;;;;N;;;;;\n1F411;SHEEP;So;0;ON;;;;;N;;;;;\n1F412;MONKEY;So;0;ON;;;;;N;;;;;\n1F413;ROOSTER;So;0;ON;;;;;N;;;;;\n1F414;CHICKEN;So;0;ON;;;;;N;;;;;\n1F415;DOG;So;0;ON;;;;;N;;;;;\n1F416;PIG;So;0;ON;;;;;N;;;;;\n1F417;BOAR;So;0;ON;;;;;N;;;;;\n1F418;ELEPHANT;So;0;ON;;;;;N;;;;;\n1F419;OCTOPUS;So;0;ON;;;;;N;;;;;\n1F41A;SPIRAL SHELL;So;0;ON;;;;;N;;;;;\n1F41B;BUG;So;0;ON;;;;;N;;;;;\n1F41C;ANT;So;0;ON;;;;;N;;;;;\n1F41D;HONEYBEE;So;0;ON;;;;;N;;;;;\n1F41E;LADY BEETLE;So;0;ON;;;;;N;;;;;\n1F41F;FISH;So;0;ON;;;;;N;;;;;\n1F420;TROPICAL FISH;So;0;ON;;;;;N;;;;;\n1F421;BLOWFISH;So;0;ON;;;;;N;;;;;\n1F422;TURTLE;So;0;ON;;;;;N;;;;;\n1F423;HATCHING CHICK;So;0;ON;;;;;N;;;;;\n1F424;BABY CHICK;So;0;ON;;;;;N;;;;;\n1F425;FRONT-FACING BABY CHICK;So;0;ON;;;;;N;;;;;\n1F426;BIRD;So;0;ON;;;;;N;;;;;\n1F427;PENGUIN;So;0;ON;;;;;N;;;;;\n1F428;KOALA;So;0;ON;;;;;N;;;;;\n1F429;POODLE;So;0;ON;;;;;N;;;;;\n1F42A;DROMEDARY CAMEL;So;0;ON;;;;;N;;;;;\n1F42B;BACTRIAN CAMEL;So;0;ON;;;;;N;;;;;\n1F42C;DOLPHIN;So;0;ON;;;;;N;;;;;\n1F42D;MOUSE FACE;So;0;ON;;;;;N;;;;;\n1F42E;COW FACE;So;0;ON;;;;;N;;;;;\n1F42F;TIGER FACE;So;0;ON;;;;;N;;;;;\n1F430;RABBIT FACE;So;0;ON;;;;;N;;;;;\n1F431;CAT FACE;So;0;ON;;;;;N;;;;;\n1F432;DRAGON FACE;So;0;ON;;;;;N;;;;;\n1F433;SPOUTING WHALE;So;0;ON;;;;;N;;;;;\n1F434;HORSE FACE;So;0;ON;;;;;N;;;;;\n1F435;MONKEY FACE;So;0;ON;;;;;N;;;;;\n1F436;DOG FACE;So;0;ON;;;;;N;;;;;\n1F437;PIG FACE;So;0;ON;;;;;N;;;;;\n1F438;FROG FACE;So;0;ON;;;;;N;;;;;\n1F439;HAMSTER FACE;So;0;ON;;;;;N;;;;;\n1F43A;WOLF FACE;So;0;ON;;;;;N;;;;;\n1F43B;BEAR FACE;So;0;ON;;;;;N;;;;;\n1F43C;PANDA FACE;So;0;ON;;;;;N;;;;;\n1F43D;PIG NOSE;So;0;ON;;;;;N;;;;;\n1F43E;PAW PRINTS;So;0;ON;;;;;N;;;;;\n1F43F;CHIPMUNK;So;0;ON;;;;;N;;;;;\n1F440;EYES;So;0;ON;;;;;N;;;;;\n1F441;EYE;So;0;ON;;;;;N;;;;;\n1F442;EAR;So;0;ON;;;;;N;;;;;\n1F443;NOSE;So;0;ON;;;;;N;;;;;\n1F444;MOUTH;So;0;ON;;;;;N;;;;;\n1F445;TONGUE;So;0;ON;;;;;N;;;;;\n1F446;WHITE UP POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;\n1F447;WHITE DOWN POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;\n1F448;WHITE LEFT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;\n1F449;WHITE RIGHT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;\n1F44A;FISTED HAND SIGN;So;0;ON;;;;;N;;;;;\n1F44B;WAVING HAND SIGN;So;0;ON;;;;;N;;;;;\n1F44C;OK HAND SIGN;So;0;ON;;;;;N;;;;;\n1F44D;THUMBS UP SIGN;So;0;ON;;;;;N;;;;;\n1F44E;THUMBS DOWN SIGN;So;0;ON;;;;;N;;;;;\n1F44F;CLAPPING HANDS SIGN;So;0;ON;;;;;N;;;;;\n1F450;OPEN HANDS SIGN;So;0;ON;;;;;N;;;;;\n1F451;CROWN;So;0;ON;;;;;N;;;;;\n1F452;WOMANS HAT;So;0;ON;;;;;N;;;;;\n1F453;EYEGLASSES;So;0;ON;;;;;N;;;;;\n1F454;NECKTIE;So;0;ON;;;;;N;;;;;\n1F455;T-SHIRT;So;0;ON;;;;;N;;;;;\n1F456;JEANS;So;0;ON;;;;;N;;;;;\n1F457;DRESS;So;0;ON;;;;;N;;;;;\n1F458;KIMONO;So;0;ON;;;;;N;;;;;\n1F459;BIKINI;So;0;ON;;;;;N;;;;;\n1F45A;WOMANS CLOTHES;So;0;ON;;;;;N;;;;;\n1F45B;PURSE;So;0;ON;;;;;N;;;;;\n1F45C;HANDBAG;So;0;ON;;;;;N;;;;;\n1F45D;POUCH;So;0;ON;;;;;N;;;;;\n1F45E;MANS SHOE;So;0;ON;;;;;N;;;;;\n1F45F;ATHLETIC SHOE;So;0;ON;;;;;N;;;;;\n1F460;HIGH-HEELED SHOE;So;0;ON;;;;;N;;;;;\n1F461;WOMANS SANDAL;So;0;ON;;;;;N;;;;;\n1F462;WOMANS BOOTS;So;0;ON;;;;;N;;;;;\n1F463;FOOTPRINTS;So;0;ON;;;;;N;;;;;\n1F464;BUST IN SILHOUETTE;So;0;ON;;;;;N;;;;;\n1F465;BUSTS IN SILHOUETTE;So;0;ON;;;;;N;;;;;\n1F466;BOY;So;0;ON;;;;;N;;;;;\n1F467;GIRL;So;0;ON;;;;;N;;;;;\n1F468;MAN;So;0;ON;;;;;N;;;;;\n1F469;WOMAN;So;0;ON;;;;;N;;;;;\n1F46A;FAMILY;So;0;ON;;;;;N;;;;;\n1F46B;MAN AND WOMAN HOLDING HANDS;So;0;ON;;;;;N;;;;;\n1F46C;TWO MEN HOLDING HANDS;So;0;ON;;;;;N;;;;;\n1F46D;TWO WOMEN HOLDING HANDS;So;0;ON;;;;;N;;;;;\n1F46E;POLICE OFFICER;So;0;ON;;;;;N;;;;;\n1F46F;WOMAN WITH BUNNY EARS;So;0;ON;;;;;N;;;;;\n1F470;BRIDE WITH VEIL;So;0;ON;;;;;N;;;;;\n1F471;PERSON WITH BLOND HAIR;So;0;ON;;;;;N;;;;;\n1F472;MAN WITH GUA PI MAO;So;0;ON;;;;;N;;;;;\n1F473;MAN WITH TURBAN;So;0;ON;;;;;N;;;;;\n1F474;OLDER MAN;So;0;ON;;;;;N;;;;;\n1F475;OLDER WOMAN;So;0;ON;;;;;N;;;;;\n1F476;BABY;So;0;ON;;;;;N;;;;;\n1F477;CONSTRUCTION WORKER;So;0;ON;;;;;N;;;;;\n1F478;PRINCESS;So;0;ON;;;;;N;;;;;\n1F479;JAPANESE OGRE;So;0;ON;;;;;N;;;;;\n1F47A;JAPANESE GOBLIN;So;0;ON;;;;;N;;;;;\n1F47B;GHOST;So;0;ON;;;;;N;;;;;\n1F47C;BABY ANGEL;So;0;ON;;;;;N;;;;;\n1F47D;EXTRATERRESTRIAL ALIEN;So;0;ON;;;;;N;;;;;\n1F47E;ALIEN MONSTER;So;0;ON;;;;;N;;;;;\n1F47F;IMP;So;0;ON;;;;;N;;;;;\n1F480;SKULL;So;0;ON;;;;;N;;;;;\n1F481;INFORMATION DESK PERSON;So;0;ON;;;;;N;;;;;\n1F482;GUARDSMAN;So;0;ON;;;;;N;;;;;\n1F483;DANCER;So;0;ON;;;;;N;;;;;\n1F484;LIPSTICK;So;0;ON;;;;;N;;;;;\n1F485;NAIL POLISH;So;0;ON;;;;;N;;;;;\n1F486;FACE MASSAGE;So;0;ON;;;;;N;;;;;\n1F487;HAIRCUT;So;0;ON;;;;;N;;;;;\n1F488;BARBER POLE;So;0;ON;;;;;N;;;;;\n1F489;SYRINGE;So;0;ON;;;;;N;;;;;\n1F48A;PILL;So;0;ON;;;;;N;;;;;\n1F48B;KISS MARK;So;0;ON;;;;;N;;;;;\n1F48C;LOVE LETTER;So;0;ON;;;;;N;;;;;\n1F48D;RING;So;0;ON;;;;;N;;;;;\n1F48E;GEM STONE;So;0;ON;;;;;N;;;;;\n1F48F;KISS;So;0;ON;;;;;N;;;;;\n1F490;BOUQUET;So;0;ON;;;;;N;;;;;\n1F491;COUPLE WITH HEART;So;0;ON;;;;;N;;;;;\n1F492;WEDDING;So;0;ON;;;;;N;;;;;\n1F493;BEATING HEART;So;0;ON;;;;;N;;;;;\n1F494;BROKEN HEART;So;0;ON;;;;;N;;;;;\n1F495;TWO HEARTS;So;0;ON;;;;;N;;;;;\n1F496;SPARKLING HEART;So;0;ON;;;;;N;;;;;\n1F497;GROWING HEART;So;0;ON;;;;;N;;;;;\n1F498;HEART WITH ARROW;So;0;ON;;;;;N;;;;;\n1F499;BLUE HEART;So;0;ON;;;;;N;;;;;\n1F49A;GREEN HEART;So;0;ON;;;;;N;;;;;\n1F49B;YELLOW HEART;So;0;ON;;;;;N;;;;;\n1F49C;PURPLE HEART;So;0;ON;;;;;N;;;;;\n1F49D;HEART WITH RIBBON;So;0;ON;;;;;N;;;;;\n1F49E;REVOLVING HEARTS;So;0;ON;;;;;N;;;;;\n1F49F;HEART DECORATION;So;0;ON;;;;;N;;;;;\n1F4A0;DIAMOND SHAPE WITH A DOT INSIDE;So;0;ON;;;;;N;;;;;\n1F4A1;ELECTRIC LIGHT BULB;So;0;ON;;;;;N;;;;;\n1F4A2;ANGER SYMBOL;So;0;ON;;;;;N;;;;;\n1F4A3;BOMB;So;0;ON;;;;;N;;;;;\n1F4A4;SLEEPING SYMBOL;So;0;ON;;;;;N;;;;;\n1F4A5;COLLISION SYMBOL;So;0;ON;;;;;N;;;;;\n1F4A6;SPLASHING SWEAT SYMBOL;So;0;ON;;;;;N;;;;;\n1F4A7;DROPLET;So;0;ON;;;;;N;;;;;\n1F4A8;DASH SYMBOL;So;0;ON;;;;;N;;;;;\n1F4A9;PILE OF POO;So;0;ON;;;;;N;;;;;\n1F4AA;FLEXED BICEPS;So;0;ON;;;;;N;;;;;\n1F4AB;DIZZY SYMBOL;So;0;ON;;;;;N;;;;;\n1F4AC;SPEECH BALLOON;So;0;ON;;;;;N;;;;;\n1F4AD;THOUGHT BALLOON;So;0;ON;;;;;N;;;;;\n1F4AE;WHITE FLOWER;So;0;ON;;;;;N;;;;;\n1F4AF;HUNDRED POINTS SYMBOL;So;0;ON;;;;;N;;;;;\n1F4B0;MONEY BAG;So;0;ON;;;;;N;;;;;\n1F4B1;CURRENCY EXCHANGE;So;0;ON;;;;;N;;;;;\n1F4B2;HEAVY DOLLAR SIGN;So;0;ON;;;;;N;;;;;\n1F4B3;CREDIT CARD;So;0;ON;;;;;N;;;;;\n1F4B4;BANKNOTE WITH YEN SIGN;So;0;ON;;;;;N;;;;;\n1F4B5;BANKNOTE WITH DOLLAR SIGN;So;0;ON;;;;;N;;;;;\n1F4B6;BANKNOTE WITH EURO SIGN;So;0;ON;;;;;N;;;;;\n1F4B7;BANKNOTE WITH POUND SIGN;So;0;ON;;;;;N;;;;;\n1F4B8;MONEY WITH WINGS;So;0;ON;;;;;N;;;;;\n1F4B9;CHART WITH UPWARDS TREND AND YEN SIGN;So;0;ON;;;;;N;;;;;\n1F4BA;SEAT;So;0;ON;;;;;N;;;;;\n1F4BB;PERSONAL COMPUTER;So;0;ON;;;;;N;;;;;\n1F4BC;BRIEFCASE;So;0;ON;;;;;N;;;;;\n1F4BD;MINIDISC;So;0;ON;;;;;N;;;;;\n1F4BE;FLOPPY DISK;So;0;ON;;;;;N;;;;;\n1F4BF;OPTICAL DISC;So;0;ON;;;;;N;;;;;\n1F4C0;DVD;So;0;ON;;;;;N;;;;;\n1F4C1;FILE FOLDER;So;0;ON;;;;;N;;;;;\n1F4C2;OPEN FILE FOLDER;So;0;ON;;;;;N;;;;;\n1F4C3;PAGE WITH CURL;So;0;ON;;;;;N;;;;;\n1F4C4;PAGE FACING UP;So;0;ON;;;;;N;;;;;\n1F4C5;CALENDAR;So;0;ON;;;;;N;;;;;\n1F4C6;TEAR-OFF CALENDAR;So;0;ON;;;;;N;;;;;\n1F4C7;CARD INDEX;So;0;ON;;;;;N;;;;;\n1F4C8;CHART WITH UPWARDS TREND;So;0;ON;;;;;N;;;;;\n1F4C9;CHART WITH DOWNWARDS TREND;So;0;ON;;;;;N;;;;;\n1F4CA;BAR CHART;So;0;ON;;;;;N;;;;;\n1F4CB;CLIPBOARD;So;0;ON;;;;;N;;;;;\n1F4CC;PUSHPIN;So;0;ON;;;;;N;;;;;\n1F4CD;ROUND PUSHPIN;So;0;ON;;;;;N;;;;;\n1F4CE;PAPERCLIP;So;0;ON;;;;;N;;;;;\n1F4CF;STRAIGHT RULER;So;0;ON;;;;;N;;;;;\n1F4D0;TRIANGULAR RULER;So;0;ON;;;;;N;;;;;\n1F4D1;BOOKMARK TABS;So;0;ON;;;;;N;;;;;\n1F4D2;LEDGER;So;0;ON;;;;;N;;;;;\n1F4D3;NOTEBOOK;So;0;ON;;;;;N;;;;;\n1F4D4;NOTEBOOK WITH DECORATIVE COVER;So;0;ON;;;;;N;;;;;\n1F4D5;CLOSED BOOK;So;0;ON;;;;;N;;;;;\n1F4D6;OPEN BOOK;So;0;ON;;;;;N;;;;;\n1F4D7;GREEN BOOK;So;0;ON;;;;;N;;;;;\n1F4D8;BLUE BOOK;So;0;ON;;;;;N;;;;;\n1F4D9;ORANGE BOOK;So;0;ON;;;;;N;;;;;\n1F4DA;BOOKS;So;0;ON;;;;;N;;;;;\n1F4DB;NAME BADGE;So;0;ON;;;;;N;;;;;\n1F4DC;SCROLL;So;0;ON;;;;;N;;;;;\n1F4DD;MEMO;So;0;ON;;;;;N;;;;;\n1F4DE;TELEPHONE RECEIVER;So;0;ON;;;;;N;;;;;\n1F4DF;PAGER;So;0;ON;;;;;N;;;;;\n1F4E0;FAX MACHINE;So;0;ON;;;;;N;;;;;\n1F4E1;SATELLITE ANTENNA;So;0;ON;;;;;N;;;;;\n1F4E2;PUBLIC ADDRESS LOUDSPEAKER;So;0;ON;;;;;N;;;;;\n1F4E3;CHEERING MEGAPHONE;So;0;ON;;;;;N;;;;;\n1F4E4;OUTBOX TRAY;So;0;ON;;;;;N;;;;;\n1F4E5;INBOX TRAY;So;0;ON;;;;;N;;;;;\n1F4E6;PACKAGE;So;0;ON;;;;;N;;;;;\n1F4E7;E-MAIL SYMBOL;So;0;ON;;;;;N;;;;;\n1F4E8;INCOMING ENVELOPE;So;0;ON;;;;;N;;;;;\n1F4E9;ENVELOPE WITH DOWNWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;\n1F4EA;CLOSED MAILBOX WITH LOWERED FLAG;So;0;ON;;;;;N;;;;;\n1F4EB;CLOSED MAILBOX WITH RAISED FLAG;So;0;ON;;;;;N;;;;;\n1F4EC;OPEN MAILBOX WITH RAISED FLAG;So;0;ON;;;;;N;;;;;\n1F4ED;OPEN MAILBOX WITH LOWERED FLAG;So;0;ON;;;;;N;;;;;\n1F4EE;POSTBOX;So;0;ON;;;;;N;;;;;\n1F4EF;POSTAL HORN;So;0;ON;;;;;N;;;;;\n1F4F0;NEWSPAPER;So;0;ON;;;;;N;;;;;\n1F4F1;MOBILE PHONE;So;0;ON;;;;;N;;;;;\n1F4F2;MOBILE PHONE WITH RIGHTWARDS ARROW AT LEFT;So;0;ON;;;;;N;;;;;\n1F4F3;VIBRATION MODE;So;0;ON;;;;;N;;;;;\n1F4F4;MOBILE PHONE OFF;So;0;ON;;;;;N;;;;;\n1F4F5;NO MOBILE PHONES;So;0;ON;;;;;N;;;;;\n1F4F6;ANTENNA WITH BARS;So;0;ON;;;;;N;;;;;\n1F4F7;CAMERA;So;0;ON;;;;;N;;;;;\n1F4F8;CAMERA WITH FLASH;So;0;ON;;;;;N;;;;;\n1F4F9;VIDEO CAMERA;So;0;ON;;;;;N;;;;;\n1F4FA;TELEVISION;So;0;ON;;;;;N;;;;;\n1F4FB;RADIO;So;0;ON;;;;;N;;;;;\n1F4FC;VIDEOCASSETTE;So;0;ON;;;;;N;;;;;\n1F4FD;FILM PROJECTOR;So;0;ON;;;;;N;;;;;\n1F4FE;PORTABLE STEREO;So;0;ON;;;;;N;;;;;\n1F4FF;PRAYER BEADS;So;0;ON;;;;;N;;;;;\n1F500;TWISTED RIGHTWARDS ARROWS;So;0;ON;;;;;N;;;;;\n1F501;CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS;So;0;ON;;;;;N;;;;;\n1F502;CLOCKWISE RIGHTWARDS AND LEFTWARDS OPEN CIRCLE ARROWS WITH CIRCLED ONE OVERLAY;So;0;ON;;;;;N;;;;;\n1F503;CLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS;So;0;ON;;;;;N;;;;;\n1F504;ANTICLOCKWISE DOWNWARDS AND UPWARDS OPEN CIRCLE ARROWS;So;0;ON;;;;;N;;;;;\n1F505;LOW BRIGHTNESS SYMBOL;So;0;ON;;;;;N;;;;;\n1F506;HIGH BRIGHTNESS SYMBOL;So;0;ON;;;;;N;;;;;\n1F507;SPEAKER WITH CANCELLATION STROKE;So;0;ON;;;;;N;;;;;\n1F508;SPEAKER;So;0;ON;;;;;N;;;;;\n1F509;SPEAKER WITH ONE SOUND WAVE;So;0;ON;;;;;N;;;;;\n1F50A;SPEAKER WITH THREE SOUND WAVES;So;0;ON;;;;;N;;;;;\n1F50B;BATTERY;So;0;ON;;;;;N;;;;;\n1F50C;ELECTRIC PLUG;So;0;ON;;;;;N;;;;;\n1F50D;LEFT-POINTING MAGNIFYING GLASS;So;0;ON;;;;;N;;;;;\n1F50E;RIGHT-POINTING MAGNIFYING GLASS;So;0;ON;;;;;N;;;;;\n1F50F;LOCK WITH INK PEN;So;0;ON;;;;;N;;;;;\n1F510;CLOSED LOCK WITH KEY;So;0;ON;;;;;N;;;;;\n1F511;KEY;So;0;ON;;;;;N;;;;;\n1F512;LOCK;So;0;ON;;;;;N;;;;;\n1F513;OPEN LOCK;So;0;ON;;;;;N;;;;;\n1F514;BELL;So;0;ON;;;;;N;;;;;\n1F515;BELL WITH CANCELLATION STROKE;So;0;ON;;;;;N;;;;;\n1F516;BOOKMARK;So;0;ON;;;;;N;;;;;\n1F517;LINK SYMBOL;So;0;ON;;;;;N;;;;;\n1F518;RADIO BUTTON;So;0;ON;;;;;N;;;;;\n1F519;BACK WITH LEFTWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;\n1F51A;END WITH LEFTWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;\n1F51B;ON WITH EXCLAMATION MARK WITH LEFT RIGHT ARROW ABOVE;So;0;ON;;;;;N;;;;;\n1F51C;SOON WITH RIGHTWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;\n1F51D;TOP WITH UPWARDS ARROW ABOVE;So;0;ON;;;;;N;;;;;\n1F51E;NO ONE UNDER EIGHTEEN SYMBOL;So;0;ON;;;;;N;;;;;\n1F51F;KEYCAP TEN;So;0;ON;;;;;N;;;;;\n1F520;INPUT SYMBOL FOR LATIN CAPITAL LETTERS;So;0;ON;;;;;N;;;;;\n1F521;INPUT SYMBOL FOR LATIN SMALL LETTERS;So;0;ON;;;;;N;;;;;\n1F522;INPUT SYMBOL FOR NUMBERS;So;0;ON;;;;;N;;;;;\n1F523;INPUT SYMBOL FOR SYMBOLS;So;0;ON;;;;;N;;;;;\n1F524;INPUT SYMBOL FOR LATIN LETTERS;So;0;ON;;;;;N;;;;;\n1F525;FIRE;So;0;ON;;;;;N;;;;;\n1F526;ELECTRIC TORCH;So;0;ON;;;;;N;;;;;\n1F527;WRENCH;So;0;ON;;;;;N;;;;;\n1F528;HAMMER;So;0;ON;;;;;N;;;;;\n1F529;NUT AND BOLT;So;0;ON;;;;;N;;;;;\n1F52A;HOCHO;So;0;ON;;;;;N;;;;;\n1F52B;PISTOL;So;0;ON;;;;;N;;;;;\n1F52C;MICROSCOPE;So;0;ON;;;;;N;;;;;\n1F52D;TELESCOPE;So;0;ON;;;;;N;;;;;\n1F52E;CRYSTAL BALL;So;0;ON;;;;;N;;;;;\n1F52F;SIX POINTED STAR WITH MIDDLE DOT;So;0;ON;;;;;N;;;;;\n1F530;JAPANESE SYMBOL FOR BEGINNER;So;0;ON;;;;;N;;;;;\n1F531;TRIDENT EMBLEM;So;0;ON;;;;;N;;;;;\n1F532;BLACK SQUARE BUTTON;So;0;ON;;;;;N;;;;;\n1F533;WHITE SQUARE BUTTON;So;0;ON;;;;;N;;;;;\n1F534;LARGE RED CIRCLE;So;0;ON;;;;;N;;;;;\n1F535;LARGE BLUE CIRCLE;So;0;ON;;;;;N;;;;;\n1F536;LARGE ORANGE DIAMOND;So;0;ON;;;;;N;;;;;\n1F537;LARGE BLUE DIAMOND;So;0;ON;;;;;N;;;;;\n1F538;SMALL ORANGE DIAMOND;So;0;ON;;;;;N;;;;;\n1F539;SMALL BLUE DIAMOND;So;0;ON;;;;;N;;;;;\n1F53A;UP-POINTING RED TRIANGLE;So;0;ON;;;;;N;;;;;\n1F53B;DOWN-POINTING RED TRIANGLE;So;0;ON;;;;;N;;;;;\n1F53C;UP-POINTING SMALL RED TRIANGLE;So;0;ON;;;;;N;;;;;\n1F53D;DOWN-POINTING SMALL RED TRIANGLE;So;0;ON;;;;;N;;;;;\n1F53E;LOWER RIGHT SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;;\n1F53F;UPPER RIGHT SHADOWED WHITE CIRCLE;So;0;ON;;;;;N;;;;;\n1F540;CIRCLED CROSS POMMEE;So;0;ON;;;;;N;;;;;\n1F541;CROSS POMMEE WITH HALF-CIRCLE BELOW;So;0;ON;;;;;N;;;;;\n1F542;CROSS POMMEE;So;0;ON;;;;;N;;;;;\n1F543;NOTCHED LEFT SEMICIRCLE WITH THREE DOTS;So;0;ON;;;;;N;;;;;\n1F544;NOTCHED RIGHT SEMICIRCLE WITH THREE DOTS;So;0;ON;;;;;N;;;;;\n1F545;SYMBOL FOR MARKS CHAPTER;So;0;ON;;;;;N;;;;;\n1F546;WHITE LATIN CROSS;So;0;ON;;;;;N;;;;;\n1F547;HEAVY LATIN CROSS;So;0;ON;;;;;N;;;;;\n1F548;CELTIC CROSS;So;0;ON;;;;;N;;;;;\n1F549;OM SYMBOL;So;0;ON;;;;;N;;;;;\n1F54A;DOVE OF PEACE;So;0;ON;;;;;N;;;;;\n1F54B;KAABA;So;0;ON;;;;;N;;;;;\n1F54C;MOSQUE;So;0;ON;;;;;N;;;;;\n1F54D;SYNAGOGUE;So;0;ON;;;;;N;;;;;\n1F54E;MENORAH WITH NINE BRANCHES;So;0;ON;;;;;N;;;;;\n1F54F;BOWL OF HYGIEIA;So;0;ON;;;;;N;;;;;\n1F550;CLOCK FACE ONE OCLOCK;So;0;ON;;;;;N;;;;;\n1F551;CLOCK FACE TWO OCLOCK;So;0;ON;;;;;N;;;;;\n1F552;CLOCK FACE THREE OCLOCK;So;0;ON;;;;;N;;;;;\n1F553;CLOCK FACE FOUR OCLOCK;So;0;ON;;;;;N;;;;;\n1F554;CLOCK FACE FIVE OCLOCK;So;0;ON;;;;;N;;;;;\n1F555;CLOCK FACE SIX OCLOCK;So;0;ON;;;;;N;;;;;\n1F556;CLOCK FACE SEVEN OCLOCK;So;0;ON;;;;;N;;;;;\n1F557;CLOCK FACE EIGHT OCLOCK;So;0;ON;;;;;N;;;;;\n1F558;CLOCK FACE NINE OCLOCK;So;0;ON;;;;;N;;;;;\n1F559;CLOCK FACE TEN OCLOCK;So;0;ON;;;;;N;;;;;\n1F55A;CLOCK FACE ELEVEN OCLOCK;So;0;ON;;;;;N;;;;;\n1F55B;CLOCK FACE TWELVE OCLOCK;So;0;ON;;;;;N;;;;;\n1F55C;CLOCK FACE ONE-THIRTY;So;0;ON;;;;;N;;;;;\n1F55D;CLOCK FACE TWO-THIRTY;So;0;ON;;;;;N;;;;;\n1F55E;CLOCK FACE THREE-THIRTY;So;0;ON;;;;;N;;;;;\n1F55F;CLOCK FACE FOUR-THIRTY;So;0;ON;;;;;N;;;;;\n1F560;CLOCK FACE FIVE-THIRTY;So;0;ON;;;;;N;;;;;\n1F561;CLOCK FACE SIX-THIRTY;So;0;ON;;;;;N;;;;;\n1F562;CLOCK FACE SEVEN-THIRTY;So;0;ON;;;;;N;;;;;\n1F563;CLOCK FACE EIGHT-THIRTY;So;0;ON;;;;;N;;;;;\n1F564;CLOCK FACE NINE-THIRTY;So;0;ON;;;;;N;;;;;\n1F565;CLOCK FACE TEN-THIRTY;So;0;ON;;;;;N;;;;;\n1F566;CLOCK FACE ELEVEN-THIRTY;So;0;ON;;;;;N;;;;;\n1F567;CLOCK FACE TWELVE-THIRTY;So;0;ON;;;;;N;;;;;\n1F568;RIGHT SPEAKER;So;0;ON;;;;;N;;;;;\n1F569;RIGHT SPEAKER WITH ONE SOUND WAVE;So;0;ON;;;;;N;;;;;\n1F56A;RIGHT SPEAKER WITH THREE SOUND WAVES;So;0;ON;;;;;N;;;;;\n1F56B;BULLHORN;So;0;ON;;;;;N;;;;;\n1F56C;BULLHORN WITH SOUND WAVES;So;0;ON;;;;;N;;;;;\n1F56D;RINGING BELL;So;0;ON;;;;;N;;;;;\n1F56E;BOOK;So;0;ON;;;;;N;;;;;\n1F56F;CANDLE;So;0;ON;;;;;N;;;;;\n1F570;MANTELPIECE CLOCK;So;0;ON;;;;;N;;;;;\n1F571;BLACK SKULL AND CROSSBONES;So;0;ON;;;;;N;;;;;\n1F572;NO PIRACY;So;0;ON;;;;;N;;;;;\n1F573;HOLE;So;0;ON;;;;;N;;;;;\n1F574;MAN IN BUSINESS SUIT LEVITATING;So;0;ON;;;;;N;;;;;\n1F575;SLEUTH OR SPY;So;0;ON;;;;;N;;;;;\n1F576;DARK SUNGLASSES;So;0;ON;;;;;N;;;;;\n1F577;SPIDER;So;0;ON;;;;;N;;;;;\n1F578;SPIDER WEB;So;0;ON;;;;;N;;;;;\n1F579;JOYSTICK;So;0;ON;;;;;N;;;;;\n1F57A;MAN DANCING;So;0;ON;;;;;N;;;;;\n1F57B;LEFT HAND TELEPHONE RECEIVER;So;0;ON;;;;;N;;;;;\n1F57C;TELEPHONE RECEIVER WITH PAGE;So;0;ON;;;;;N;;;;;\n1F57D;RIGHT HAND TELEPHONE RECEIVER;So;0;ON;;;;;N;;;;;\n1F57E;WHITE TOUCHTONE TELEPHONE;So;0;ON;;;;;N;;;;;\n1F57F;BLACK TOUCHTONE TELEPHONE;So;0;ON;;;;;N;;;;;\n1F580;TELEPHONE ON TOP OF MODEM;So;0;ON;;;;;N;;;;;\n1F581;CLAMSHELL MOBILE PHONE;So;0;ON;;;;;N;;;;;\n1F582;BACK OF ENVELOPE;So;0;ON;;;;;N;;;;;\n1F583;STAMPED ENVELOPE;So;0;ON;;;;;N;;;;;\n1F584;ENVELOPE WITH LIGHTNING;So;0;ON;;;;;N;;;;;\n1F585;FLYING ENVELOPE;So;0;ON;;;;;N;;;;;\n1F586;PEN OVER STAMPED ENVELOPE;So;0;ON;;;;;N;;;;;\n1F587;LINKED PAPERCLIPS;So;0;ON;;;;;N;;;;;\n1F588;BLACK PUSHPIN;So;0;ON;;;;;N;;;;;\n1F589;LOWER LEFT PENCIL;So;0;ON;;;;;N;;;;;\n1F58A;LOWER LEFT BALLPOINT PEN;So;0;ON;;;;;N;;;;;\n1F58B;LOWER LEFT FOUNTAIN PEN;So;0;ON;;;;;N;;;;;\n1F58C;LOWER LEFT PAINTBRUSH;So;0;ON;;;;;N;;;;;\n1F58D;LOWER LEFT CRAYON;So;0;ON;;;;;N;;;;;\n1F58E;LEFT WRITING HAND;So;0;ON;;;;;N;;;;;\n1F58F;TURNED OK HAND SIGN;So;0;ON;;;;;N;;;;;\n1F590;RAISED HAND WITH FINGERS SPLAYED;So;0;ON;;;;;N;;;;;\n1F591;REVERSED RAISED HAND WITH FINGERS SPLAYED;So;0;ON;;;;;N;;;;;\n1F592;REVERSED THUMBS UP SIGN;So;0;ON;;;;;N;;;;;\n1F593;REVERSED THUMBS DOWN SIGN;So;0;ON;;;;;N;;;;;\n1F594;REVERSED VICTORY HAND;So;0;ON;;;;;N;;;;;\n1F595;REVERSED HAND WITH MIDDLE FINGER EXTENDED;So;0;ON;;;;;N;;;;;\n1F596;RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS;So;0;ON;;;;;N;;;;;\n1F597;WHITE DOWN POINTING LEFT HAND INDEX;So;0;ON;;;;;N;;;;;\n1F598;SIDEWAYS WHITE LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;\n1F599;SIDEWAYS WHITE RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;\n1F59A;SIDEWAYS BLACK LEFT POINTING INDEX;So;0;ON;;;;;N;;;;;\n1F59B;SIDEWAYS BLACK RIGHT POINTING INDEX;So;0;ON;;;;;N;;;;;\n1F59C;BLACK LEFT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;\n1F59D;BLACK RIGHT POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;\n1F59E;SIDEWAYS WHITE UP POINTING INDEX;So;0;ON;;;;;N;;;;;\n1F59F;SIDEWAYS WHITE DOWN POINTING INDEX;So;0;ON;;;;;N;;;;;\n1F5A0;SIDEWAYS BLACK UP POINTING INDEX;So;0;ON;;;;;N;;;;;\n1F5A1;SIDEWAYS BLACK DOWN POINTING INDEX;So;0;ON;;;;;N;;;;;\n1F5A2;BLACK UP POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;\n1F5A3;BLACK DOWN POINTING BACKHAND INDEX;So;0;ON;;;;;N;;;;;\n1F5A4;BLACK HEART;So;0;ON;;;;;N;;;;;\n1F5A5;DESKTOP COMPUTER;So;0;ON;;;;;N;;;;;\n1F5A6;KEYBOARD AND MOUSE;So;0;ON;;;;;N;;;;;\n1F5A7;THREE NETWORKED COMPUTERS;So;0;ON;;;;;N;;;;;\n1F5A8;PRINTER;So;0;ON;;;;;N;;;;;\n1F5A9;POCKET CALCULATOR;So;0;ON;;;;;N;;;;;\n1F5AA;BLACK HARD SHELL FLOPPY DISK;So;0;ON;;;;;N;;;;;\n1F5AB;WHITE HARD SHELL FLOPPY DISK;So;0;ON;;;;;N;;;;;\n1F5AC;SOFT SHELL FLOPPY DISK;So;0;ON;;;;;N;;;;;\n1F5AD;TAPE CARTRIDGE;So;0;ON;;;;;N;;;;;\n1F5AE;WIRED KEYBOARD;So;0;ON;;;;;N;;;;;\n1F5AF;ONE BUTTON MOUSE;So;0;ON;;;;;N;;;;;\n1F5B0;TWO BUTTON MOUSE;So;0;ON;;;;;N;;;;;\n1F5B1;THREE BUTTON MOUSE;So;0;ON;;;;;N;;;;;\n1F5B2;TRACKBALL;So;0;ON;;;;;N;;;;;\n1F5B3;OLD PERSONAL COMPUTER;So;0;ON;;;;;N;;;;;\n1F5B4;HARD DISK;So;0;ON;;;;;N;;;;;\n1F5B5;SCREEN;So;0;ON;;;;;N;;;;;\n1F5B6;PRINTER ICON;So;0;ON;;;;;N;;;;;\n1F5B7;FAX ICON;So;0;ON;;;;;N;;;;;\n1F5B8;OPTICAL DISC ICON;So;0;ON;;;;;N;;;;;\n1F5B9;DOCUMENT WITH TEXT;So;0;ON;;;;;N;;;;;\n1F5BA;DOCUMENT WITH TEXT AND PICTURE;So;0;ON;;;;;N;;;;;\n1F5BB;DOCUMENT WITH PICTURE;So;0;ON;;;;;N;;;;;\n1F5BC;FRAME WITH PICTURE;So;0;ON;;;;;N;;;;;\n1F5BD;FRAME WITH TILES;So;0;ON;;;;;N;;;;;\n1F5BE;FRAME WITH AN X;So;0;ON;;;;;N;;;;;\n1F5BF;BLACK FOLDER;So;0;ON;;;;;N;;;;;\n1F5C0;FOLDER;So;0;ON;;;;;N;;;;;\n1F5C1;OPEN FOLDER;So;0;ON;;;;;N;;;;;\n1F5C2;CARD INDEX DIVIDERS;So;0;ON;;;;;N;;;;;\n1F5C3;CARD FILE BOX;So;0;ON;;;;;N;;;;;\n1F5C4;FILE CABINET;So;0;ON;;;;;N;;;;;\n1F5C5;EMPTY NOTE;So;0;ON;;;;;N;;;;;\n1F5C6;EMPTY NOTE PAGE;So;0;ON;;;;;N;;;;;\n1F5C7;EMPTY NOTE PAD;So;0;ON;;;;;N;;;;;\n1F5C8;NOTE;So;0;ON;;;;;N;;;;;\n1F5C9;NOTE PAGE;So;0;ON;;;;;N;;;;;\n1F5CA;NOTE PAD;So;0;ON;;;;;N;;;;;\n1F5CB;EMPTY DOCUMENT;So;0;ON;;;;;N;;;;;\n1F5CC;EMPTY PAGE;So;0;ON;;;;;N;;;;;\n1F5CD;EMPTY PAGES;So;0;ON;;;;;N;;;;;\n1F5CE;DOCUMENT;So;0;ON;;;;;N;;;;;\n1F5CF;PAGE;So;0;ON;;;;;N;;;;;\n1F5D0;PAGES;So;0;ON;;;;;N;;;;;\n1F5D1;WASTEBASKET;So;0;ON;;;;;N;;;;;\n1F5D2;SPIRAL NOTE PAD;So;0;ON;;;;;N;;;;;\n1F5D3;SPIRAL CALENDAR PAD;So;0;ON;;;;;N;;;;;\n1F5D4;DESKTOP WINDOW;So;0;ON;;;;;N;;;;;\n1F5D5;MINIMIZE;So;0;ON;;;;;N;;;;;\n1F5D6;MAXIMIZE;So;0;ON;;;;;N;;;;;\n1F5D7;OVERLAP;So;0;ON;;;;;N;;;;;\n1F5D8;CLOCKWISE RIGHT AND LEFT SEMICIRCLE ARROWS;So;0;ON;;;;;N;;;;;\n1F5D9;CANCELLATION X;So;0;ON;;;;;N;;;;;\n1F5DA;INCREASE FONT SIZE SYMBOL;So;0;ON;;;;;N;;;;;\n1F5DB;DECREASE FONT SIZE SYMBOL;So;0;ON;;;;;N;;;;;\n1F5DC;COMPRESSION;So;0;ON;;;;;N;;;;;\n1F5DD;OLD KEY;So;0;ON;;;;;N;;;;;\n1F5DE;ROLLED-UP NEWSPAPER;So;0;ON;;;;;N;;;;;\n1F5DF;PAGE WITH CIRCLED TEXT;So;0;ON;;;;;N;;;;;\n1F5E0;STOCK CHART;So;0;ON;;;;;N;;;;;\n1F5E1;DAGGER KNIFE;So;0;ON;;;;;N;;;;;\n1F5E2;LIPS;So;0;ON;;;;;N;;;;;\n1F5E3;SPEAKING HEAD IN SILHOUETTE;So;0;ON;;;;;N;;;;;\n1F5E4;THREE RAYS ABOVE;So;0;ON;;;;;N;;;;;\n1F5E5;THREE RAYS BELOW;So;0;ON;;;;;N;;;;;\n1F5E6;THREE RAYS LEFT;So;0;ON;;;;;N;;;;;\n1F5E7;THREE RAYS RIGHT;So;0;ON;;;;;N;;;;;\n1F5E8;LEFT SPEECH BUBBLE;So;0;ON;;;;;N;;;;;\n1F5E9;RIGHT SPEECH BUBBLE;So;0;ON;;;;;N;;;;;\n1F5EA;TWO SPEECH BUBBLES;So;0;ON;;;;;N;;;;;\n1F5EB;THREE SPEECH BUBBLES;So;0;ON;;;;;N;;;;;\n1F5EC;LEFT THOUGHT BUBBLE;So;0;ON;;;;;N;;;;;\n1F5ED;RIGHT THOUGHT BUBBLE;So;0;ON;;;;;N;;;;;\n1F5EE;LEFT ANGER BUBBLE;So;0;ON;;;;;N;;;;;\n1F5EF;RIGHT ANGER BUBBLE;So;0;ON;;;;;N;;;;;\n1F5F0;MOOD BUBBLE;So;0;ON;;;;;N;;;;;\n1F5F1;LIGHTNING MOOD BUBBLE;So;0;ON;;;;;N;;;;;\n1F5F2;LIGHTNING MOOD;So;0;ON;;;;;N;;;;;\n1F5F3;BALLOT BOX WITH BALLOT;So;0;ON;;;;;N;;;;;\n1F5F4;BALLOT SCRIPT X;So;0;ON;;;;;N;;;;;\n1F5F5;BALLOT BOX WITH SCRIPT X;So;0;ON;;;;;N;;;;;\n1F5F6;BALLOT BOLD SCRIPT X;So;0;ON;;;;;N;;;;;\n1F5F7;BALLOT BOX WITH BOLD SCRIPT X;So;0;ON;;;;;N;;;;;\n1F5F8;LIGHT CHECK MARK;So;0;ON;;;;;N;;;;;\n1F5F9;BALLOT BOX WITH BOLD CHECK;So;0;ON;;;;;N;;;;;\n1F5FA;WORLD MAP;So;0;ON;;;;;N;;;;;\n1F5FB;MOUNT FUJI;So;0;ON;;;;;N;;;;;\n1F5FC;TOKYO TOWER;So;0;ON;;;;;N;;;;;\n1F5FD;STATUE OF LIBERTY;So;0;ON;;;;;N;;;;;\n1F5FE;SILHOUETTE OF JAPAN;So;0;ON;;;;;N;;;;;\n1F5FF;MOYAI;So;0;ON;;;;;N;;;;;\n1F600;GRINNING FACE;So;0;ON;;;;;N;;;;;\n1F601;GRINNING FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;;\n1F602;FACE WITH TEARS OF JOY;So;0;ON;;;;;N;;;;;\n1F603;SMILING FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;;\n1F604;SMILING FACE WITH OPEN MOUTH AND SMILING EYES;So;0;ON;;;;;N;;;;;\n1F605;SMILING FACE WITH OPEN MOUTH AND COLD SWEAT;So;0;ON;;;;;N;;;;;\n1F606;SMILING FACE WITH OPEN MOUTH AND TIGHTLY-CLOSED EYES;So;0;ON;;;;;N;;;;;\n1F607;SMILING FACE WITH HALO;So;0;ON;;;;;N;;;;;\n1F608;SMILING FACE WITH HORNS;So;0;ON;;;;;N;;;;;\n1F609;WINKING FACE;So;0;ON;;;;;N;;;;;\n1F60A;SMILING FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;;\n1F60B;FACE SAVOURING DELICIOUS FOOD;So;0;ON;;;;;N;;;;;\n1F60C;RELIEVED FACE;So;0;ON;;;;;N;;;;;\n1F60D;SMILING FACE WITH HEART-SHAPED EYES;So;0;ON;;;;;N;;;;;\n1F60E;SMILING FACE WITH SUNGLASSES;So;0;ON;;;;;N;;;;;\n1F60F;SMIRKING FACE;So;0;ON;;;;;N;;;;;\n1F610;NEUTRAL FACE;So;0;ON;;;;;N;;;;;\n1F611;EXPRESSIONLESS FACE;So;0;ON;;;;;N;;;;;\n1F612;UNAMUSED FACE;So;0;ON;;;;;N;;;;;\n1F613;FACE WITH COLD SWEAT;So;0;ON;;;;;N;;;;;\n1F614;PENSIVE FACE;So;0;ON;;;;;N;;;;;\n1F615;CONFUSED FACE;So;0;ON;;;;;N;;;;;\n1F616;CONFOUNDED FACE;So;0;ON;;;;;N;;;;;\n1F617;KISSING FACE;So;0;ON;;;;;N;;;;;\n1F618;FACE THROWING A KISS;So;0;ON;;;;;N;;;;;\n1F619;KISSING FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;;\n1F61A;KISSING FACE WITH CLOSED EYES;So;0;ON;;;;;N;;;;;\n1F61B;FACE WITH STUCK-OUT TONGUE;So;0;ON;;;;;N;;;;;\n1F61C;FACE WITH STUCK-OUT TONGUE AND WINKING EYE;So;0;ON;;;;;N;;;;;\n1F61D;FACE WITH STUCK-OUT TONGUE AND TIGHTLY-CLOSED EYES;So;0;ON;;;;;N;;;;;\n1F61E;DISAPPOINTED FACE;So;0;ON;;;;;N;;;;;\n1F61F;WORRIED FACE;So;0;ON;;;;;N;;;;;\n1F620;ANGRY FACE;So;0;ON;;;;;N;;;;;\n1F621;POUTING FACE;So;0;ON;;;;;N;;;;;\n1F622;CRYING FACE;So;0;ON;;;;;N;;;;;\n1F623;PERSEVERING FACE;So;0;ON;;;;;N;;;;;\n1F624;FACE WITH LOOK OF TRIUMPH;So;0;ON;;;;;N;;;;;\n1F625;DISAPPOINTED BUT RELIEVED FACE;So;0;ON;;;;;N;;;;;\n1F626;FROWNING FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;;\n1F627;ANGUISHED FACE;So;0;ON;;;;;N;;;;;\n1F628;FEARFUL FACE;So;0;ON;;;;;N;;;;;\n1F629;WEARY FACE;So;0;ON;;;;;N;;;;;\n1F62A;SLEEPY FACE;So;0;ON;;;;;N;;;;;\n1F62B;TIRED FACE;So;0;ON;;;;;N;;;;;\n1F62C;GRIMACING FACE;So;0;ON;;;;;N;;;;;\n1F62D;LOUDLY CRYING FACE;So;0;ON;;;;;N;;;;;\n1F62E;FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;;\n1F62F;HUSHED FACE;So;0;ON;;;;;N;;;;;\n1F630;FACE WITH OPEN MOUTH AND COLD SWEAT;So;0;ON;;;;;N;;;;;\n1F631;FACE SCREAMING IN FEAR;So;0;ON;;;;;N;;;;;\n1F632;ASTONISHED FACE;So;0;ON;;;;;N;;;;;\n1F633;FLUSHED FACE;So;0;ON;;;;;N;;;;;\n1F634;SLEEPING FACE;So;0;ON;;;;;N;;;;;\n1F635;DIZZY FACE;So;0;ON;;;;;N;;;;;\n1F636;FACE WITHOUT MOUTH;So;0;ON;;;;;N;;;;;\n1F637;FACE WITH MEDICAL MASK;So;0;ON;;;;;N;;;;;\n1F638;GRINNING CAT FACE WITH SMILING EYES;So;0;ON;;;;;N;;;;;\n1F639;CAT FACE WITH TEARS OF JOY;So;0;ON;;;;;N;;;;;\n1F63A;SMILING CAT FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;;\n1F63B;SMILING CAT FACE WITH HEART-SHAPED EYES;So;0;ON;;;;;N;;;;;\n1F63C;CAT FACE WITH WRY SMILE;So;0;ON;;;;;N;;;;;\n1F63D;KISSING CAT FACE WITH CLOSED EYES;So;0;ON;;;;;N;;;;;\n1F63E;POUTING CAT FACE;So;0;ON;;;;;N;;;;;\n1F63F;CRYING CAT FACE;So;0;ON;;;;;N;;;;;\n1F640;WEARY CAT FACE;So;0;ON;;;;;N;;;;;\n1F641;SLIGHTLY FROWNING FACE;So;0;ON;;;;;N;;;;;\n1F642;SLIGHTLY SMILING FACE;So;0;ON;;;;;N;;;;;\n1F643;UPSIDE-DOWN FACE;So;0;ON;;;;;N;;;;;\n1F644;FACE WITH ROLLING EYES;So;0;ON;;;;;N;;;;;\n1F645;FACE WITH NO GOOD GESTURE;So;0;ON;;;;;N;;;;;\n1F646;FACE WITH OK GESTURE;So;0;ON;;;;;N;;;;;\n1F647;PERSON BOWING DEEPLY;So;0;ON;;;;;N;;;;;\n1F648;SEE-NO-EVIL MONKEY;So;0;ON;;;;;N;;;;;\n1F649;HEAR-NO-EVIL MONKEY;So;0;ON;;;;;N;;;;;\n1F64A;SPEAK-NO-EVIL MONKEY;So;0;ON;;;;;N;;;;;\n1F64B;HAPPY PERSON RAISING ONE HAND;So;0;ON;;;;;N;;;;;\n1F64C;PERSON RAISING BOTH HANDS IN CELEBRATION;So;0;ON;;;;;N;;;;;\n1F64D;PERSON FROWNING;So;0;ON;;;;;N;;;;;\n1F64E;PERSON WITH POUTING FACE;So;0;ON;;;;;N;;;;;\n1F64F;PERSON WITH FOLDED HANDS;So;0;ON;;;;;N;;;;;\n1F650;NORTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;;\n1F651;SOUTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;;\n1F652;NORTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;;\n1F653;SOUTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;;\n1F654;TURNED NORTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;;\n1F655;TURNED SOUTH WEST POINTING LEAF;So;0;ON;;;;;N;;;;;\n1F656;TURNED NORTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;;\n1F657;TURNED SOUTH EAST POINTING LEAF;So;0;ON;;;;;N;;;;;\n1F658;NORTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;\n1F659;SOUTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;\n1F65A;NORTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;\n1F65B;SOUTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;\n1F65C;HEAVY NORTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;\n1F65D;HEAVY SOUTH WEST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;\n1F65E;HEAVY NORTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;\n1F65F;HEAVY SOUTH EAST POINTING VINE LEAF;So;0;ON;;;;;N;;;;;\n1F660;NORTH WEST POINTING BUD;So;0;ON;;;;;N;;;;;\n1F661;SOUTH WEST POINTING BUD;So;0;ON;;;;;N;;;;;\n1F662;NORTH EAST POINTING BUD;So;0;ON;;;;;N;;;;;\n1F663;SOUTH EAST POINTING BUD;So;0;ON;;;;;N;;;;;\n1F664;HEAVY NORTH WEST POINTING BUD;So;0;ON;;;;;N;;;;;\n1F665;HEAVY SOUTH WEST POINTING BUD;So;0;ON;;;;;N;;;;;\n1F666;HEAVY NORTH EAST POINTING BUD;So;0;ON;;;;;N;;;;;\n1F667;HEAVY SOUTH EAST POINTING BUD;So;0;ON;;;;;N;;;;;\n1F668;HOLLOW QUILT SQUARE ORNAMENT;So;0;ON;;;;;N;;;;;\n1F669;HOLLOW QUILT SQUARE ORNAMENT IN BLACK SQUARE;So;0;ON;;;;;N;;;;;\n1F66A;SOLID QUILT SQUARE ORNAMENT;So;0;ON;;;;;N;;;;;\n1F66B;SOLID QUILT SQUARE ORNAMENT IN BLACK SQUARE;So;0;ON;;;;;N;;;;;\n1F66C;LEFTWARDS ROCKET;So;0;ON;;;;;N;;;;;\n1F66D;UPWARDS ROCKET;So;0;ON;;;;;N;;;;;\n1F66E;RIGHTWARDS ROCKET;So;0;ON;;;;;N;;;;;\n1F66F;DOWNWARDS ROCKET;So;0;ON;;;;;N;;;;;\n1F670;SCRIPT LIGATURE ET ORNAMENT;So;0;ON;;;;;N;;;;;\n1F671;HEAVY SCRIPT LIGATURE ET ORNAMENT;So;0;ON;;;;;N;;;;;\n1F672;LIGATURE OPEN ET ORNAMENT;So;0;ON;;;;;N;;;;;\n1F673;HEAVY LIGATURE OPEN ET ORNAMENT;So;0;ON;;;;;N;;;;;\n1F674;HEAVY AMPERSAND ORNAMENT;So;0;ON;;;;;N;;;;;\n1F675;SWASH AMPERSAND ORNAMENT;So;0;ON;;;;;N;;;;;\n1F676;SANS-SERIF HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;\n1F677;SANS-SERIF HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;\n1F678;SANS-SERIF HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT;So;0;ON;;;;;N;;;;;\n1F679;HEAVY INTERROBANG ORNAMENT;So;0;ON;;;;;N;;;;;\n1F67A;SANS-SERIF INTERROBANG ORNAMENT;So;0;ON;;;;;N;;;;;\n1F67B;HEAVY SANS-SERIF INTERROBANG ORNAMENT;So;0;ON;;;;;N;;;;;\n1F67C;VERY HEAVY SOLIDUS;So;0;ON;;;;;N;;;;;\n1F67D;VERY HEAVY REVERSE SOLIDUS;So;0;ON;;;;;N;;;;;\n1F67E;CHECKER BOARD;So;0;ON;;;;;N;;;;;\n1F67F;REVERSE CHECKER BOARD;So;0;ON;;;;;N;;;;;\n1F680;ROCKET;So;0;ON;;;;;N;;;;;\n1F681;HELICOPTER;So;0;ON;;;;;N;;;;;\n1F682;STEAM LOCOMOTIVE;So;0;ON;;;;;N;;;;;\n1F683;RAILWAY CAR;So;0;ON;;;;;N;;;;;\n1F684;HIGH-SPEED TRAIN;So;0;ON;;;;;N;;;;;\n1F685;HIGH-SPEED TRAIN WITH BULLET NOSE;So;0;ON;;;;;N;;;;;\n1F686;TRAIN;So;0;ON;;;;;N;;;;;\n1F687;METRO;So;0;ON;;;;;N;;;;;\n1F688;LIGHT RAIL;So;0;ON;;;;;N;;;;;\n1F689;STATION;So;0;ON;;;;;N;;;;;\n1F68A;TRAM;So;0;ON;;;;;N;;;;;\n1F68B;TRAM CAR;So;0;ON;;;;;N;;;;;\n1F68C;BUS;So;0;ON;;;;;N;;;;;\n1F68D;ONCOMING BUS;So;0;ON;;;;;N;;;;;\n1F68E;TROLLEYBUS;So;0;ON;;;;;N;;;;;\n1F68F;BUS STOP;So;0;ON;;;;;N;;;;;\n1F690;MINIBUS;So;0;ON;;;;;N;;;;;\n1F691;AMBULANCE;So;0;ON;;;;;N;;;;;\n1F692;FIRE ENGINE;So;0;ON;;;;;N;;;;;\n1F693;POLICE CAR;So;0;ON;;;;;N;;;;;\n1F694;ONCOMING POLICE CAR;So;0;ON;;;;;N;;;;;\n1F695;TAXI;So;0;ON;;;;;N;;;;;\n1F696;ONCOMING TAXI;So;0;ON;;;;;N;;;;;\n1F697;AUTOMOBILE;So;0;ON;;;;;N;;;;;\n1F698;ONCOMING AUTOMOBILE;So;0;ON;;;;;N;;;;;\n1F699;RECREATIONAL VEHICLE;So;0;ON;;;;;N;;;;;\n1F69A;DELIVERY TRUCK;So;0;ON;;;;;N;;;;;\n1F69B;ARTICULATED LORRY;So;0;ON;;;;;N;;;;;\n1F69C;TRACTOR;So;0;ON;;;;;N;;;;;\n1F69D;MONORAIL;So;0;ON;;;;;N;;;;;\n1F69E;MOUNTAIN RAILWAY;So;0;ON;;;;;N;;;;;\n1F69F;SUSPENSION RAILWAY;So;0;ON;;;;;N;;;;;\n1F6A0;MOUNTAIN CABLEWAY;So;0;ON;;;;;N;;;;;\n1F6A1;AERIAL TRAMWAY;So;0;ON;;;;;N;;;;;\n1F6A2;SHIP;So;0;ON;;;;;N;;;;;\n1F6A3;ROWBOAT;So;0;ON;;;;;N;;;;;\n1F6A4;SPEEDBOAT;So;0;ON;;;;;N;;;;;\n1F6A5;HORIZONTAL TRAFFIC LIGHT;So;0;ON;;;;;N;;;;;\n1F6A6;VERTICAL TRAFFIC LIGHT;So;0;ON;;;;;N;;;;;\n1F6A7;CONSTRUCTION SIGN;So;0;ON;;;;;N;;;;;\n1F6A8;POLICE CARS REVOLVING LIGHT;So;0;ON;;;;;N;;;;;\n1F6A9;TRIANGULAR FLAG ON POST;So;0;ON;;;;;N;;;;;\n1F6AA;DOOR;So;0;ON;;;;;N;;;;;\n1F6AB;NO ENTRY SIGN;So;0;ON;;;;;N;;;;;\n1F6AC;SMOKING SYMBOL;So;0;ON;;;;;N;;;;;\n1F6AD;NO SMOKING SYMBOL;So;0;ON;;;;;N;;;;;\n1F6AE;PUT LITTER IN ITS PLACE SYMBOL;So;0;ON;;;;;N;;;;;\n1F6AF;DO NOT LITTER SYMBOL;So;0;ON;;;;;N;;;;;\n1F6B0;POTABLE WATER SYMBOL;So;0;ON;;;;;N;;;;;\n1F6B1;NON-POTABLE WATER SYMBOL;So;0;ON;;;;;N;;;;;\n1F6B2;BICYCLE;So;0;ON;;;;;N;;;;;\n1F6B3;NO BICYCLES;So;0;ON;;;;;N;;;;;\n1F6B4;BICYCLIST;So;0;ON;;;;;N;;;;;\n1F6B5;MOUNTAIN BICYCLIST;So;0;ON;;;;;N;;;;;\n1F6B6;PEDESTRIAN;So;0;ON;;;;;N;;;;;\n1F6B7;NO PEDESTRIANS;So;0;ON;;;;;N;;;;;\n1F6B8;CHILDREN CROSSING;So;0;ON;;;;;N;;;;;\n1F6B9;MENS SYMBOL;So;0;ON;;;;;N;;;;;\n1F6BA;WOMENS SYMBOL;So;0;ON;;;;;N;;;;;\n1F6BB;RESTROOM;So;0;ON;;;;;N;;;;;\n1F6BC;BABY SYMBOL;So;0;ON;;;;;N;;;;;\n1F6BD;TOILET;So;0;ON;;;;;N;;;;;\n1F6BE;WATER CLOSET;So;0;ON;;;;;N;;;;;\n1F6BF;SHOWER;So;0;ON;;;;;N;;;;;\n1F6C0;BATH;So;0;ON;;;;;N;;;;;\n1F6C1;BATHTUB;So;0;ON;;;;;N;;;;;\n1F6C2;PASSPORT CONTROL;So;0;ON;;;;;N;;;;;\n1F6C3;CUSTOMS;So;0;ON;;;;;N;;;;;\n1F6C4;BAGGAGE CLAIM;So;0;ON;;;;;N;;;;;\n1F6C5;LEFT LUGGAGE;So;0;ON;;;;;N;;;;;\n1F6C6;TRIANGLE WITH ROUNDED CORNERS;So;0;ON;;;;;N;;;;;\n1F6C7;PROHIBITED SIGN;So;0;ON;;;;;N;;;;;\n1F6C8;CIRCLED INFORMATION SOURCE;So;0;ON;;;;;N;;;;;\n1F6C9;BOYS SYMBOL;So;0;ON;;;;;N;;;;;\n1F6CA;GIRLS SYMBOL;So;0;ON;;;;;N;;;;;\n1F6CB;COUCH AND LAMP;So;0;ON;;;;;N;;;;;\n1F6CC;SLEEPING ACCOMMODATION;So;0;ON;;;;;N;;;;;\n1F6CD;SHOPPING BAGS;So;0;ON;;;;;N;;;;;\n1F6CE;BELLHOP BELL;So;0;ON;;;;;N;;;;;\n1F6CF;BED;So;0;ON;;;;;N;;;;;\n1F6D0;PLACE OF WORSHIP;So;0;ON;;;;;N;;;;;\n1F6D1;OCTAGONAL SIGN;So;0;ON;;;;;N;;;;;\n1F6D2;SHOPPING TROLLEY;So;0;ON;;;;;N;;;;;\n1F6D3;STUPA;So;0;ON;;;;;N;;;;;\n1F6D4;PAGODA;So;0;ON;;;;;N;;;;;\n1F6D5;HINDU TEMPLE;So;0;ON;;;;;N;;;;;\n1F6E0;HAMMER AND WRENCH;So;0;ON;;;;;N;;;;;\n1F6E1;SHIELD;So;0;ON;;;;;N;;;;;\n1F6E2;OIL DRUM;So;0;ON;;;;;N;;;;;\n1F6E3;MOTORWAY;So;0;ON;;;;;N;;;;;\n1F6E4;RAILWAY TRACK;So;0;ON;;;;;N;;;;;\n1F6E5;MOTOR BOAT;So;0;ON;;;;;N;;;;;\n1F6E6;UP-POINTING MILITARY AIRPLANE;So;0;ON;;;;;N;;;;;\n1F6E7;UP-POINTING AIRPLANE;So;0;ON;;;;;N;;;;;\n1F6E8;UP-POINTING SMALL AIRPLANE;So;0;ON;;;;;N;;;;;\n1F6E9;SMALL AIRPLANE;So;0;ON;;;;;N;;;;;\n1F6EA;NORTHEAST-POINTING AIRPLANE;So;0;ON;;;;;N;;;;;\n1F6EB;AIRPLANE DEPARTURE;So;0;ON;;;;;N;;;;;\n1F6EC;AIRPLANE ARRIVING;So;0;ON;;;;;N;;;;;\n1F6F0;SATELLITE;So;0;ON;;;;;N;;;;;\n1F6F1;ONCOMING FIRE ENGINE;So;0;ON;;;;;N;;;;;\n1F6F2;DIESEL LOCOMOTIVE;So;0;ON;;;;;N;;;;;\n1F6F3;PASSENGER SHIP;So;0;ON;;;;;N;;;;;\n1F6F4;SCOOTER;So;0;ON;;;;;N;;;;;\n1F6F5;MOTOR SCOOTER;So;0;ON;;;;;N;;;;;\n1F6F6;CANOE;So;0;ON;;;;;N;;;;;\n1F6F7;SLED;So;0;ON;;;;;N;;;;;\n1F6F8;FLYING SAUCER;So;0;ON;;;;;N;;;;;\n1F6F9;SKATEBOARD;So;0;ON;;;;;N;;;;;\n1F6FA;AUTO RICKSHAW;So;0;ON;;;;;N;;;;;\n1F700;ALCHEMICAL SYMBOL FOR QUINTESSENCE;So;0;ON;;;;;N;;;;;\n1F701;ALCHEMICAL SYMBOL FOR AIR;So;0;ON;;;;;N;;;;;\n1F702;ALCHEMICAL SYMBOL FOR FIRE;So;0;ON;;;;;N;;;;;\n1F703;ALCHEMICAL SYMBOL FOR EARTH;So;0;ON;;;;;N;;;;;\n1F704;ALCHEMICAL SYMBOL FOR WATER;So;0;ON;;;;;N;;;;;\n1F705;ALCHEMICAL SYMBOL FOR AQUAFORTIS;So;0;ON;;;;;N;;;;;\n1F706;ALCHEMICAL SYMBOL FOR AQUA REGIA;So;0;ON;;;;;N;;;;;\n1F707;ALCHEMICAL SYMBOL FOR AQUA REGIA-2;So;0;ON;;;;;N;;;;;\n1F708;ALCHEMICAL SYMBOL FOR AQUA VITAE;So;0;ON;;;;;N;;;;;\n1F709;ALCHEMICAL SYMBOL FOR AQUA VITAE-2;So;0;ON;;;;;N;;;;;\n1F70A;ALCHEMICAL SYMBOL FOR VINEGAR;So;0;ON;;;;;N;;;;;\n1F70B;ALCHEMICAL SYMBOL FOR VINEGAR-2;So;0;ON;;;;;N;;;;;\n1F70C;ALCHEMICAL SYMBOL FOR VINEGAR-3;So;0;ON;;;;;N;;;;;\n1F70D;ALCHEMICAL SYMBOL FOR SULFUR;So;0;ON;;;;;N;;;;;\n1F70E;ALCHEMICAL SYMBOL FOR PHILOSOPHERS SULFUR;So;0;ON;;;;;N;;;;;\n1F70F;ALCHEMICAL SYMBOL FOR BLACK SULFUR;So;0;ON;;;;;N;;;;;\n1F710;ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE;So;0;ON;;;;;N;;;;;\n1F711;ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-2;So;0;ON;;;;;N;;;;;\n1F712;ALCHEMICAL SYMBOL FOR MERCURY SUBLIMATE-3;So;0;ON;;;;;N;;;;;\n1F713;ALCHEMICAL SYMBOL FOR CINNABAR;So;0;ON;;;;;N;;;;;\n1F714;ALCHEMICAL SYMBOL FOR SALT;So;0;ON;;;;;N;;;;;\n1F715;ALCHEMICAL SYMBOL FOR NITRE;So;0;ON;;;;;N;;;;;\n1F716;ALCHEMICAL SYMBOL FOR VITRIOL;So;0;ON;;;;;N;;;;;\n1F717;ALCHEMICAL SYMBOL FOR VITRIOL-2;So;0;ON;;;;;N;;;;;\n1F718;ALCHEMICAL SYMBOL FOR ROCK SALT;So;0;ON;;;;;N;;;;;\n1F719;ALCHEMICAL SYMBOL FOR ROCK SALT-2;So;0;ON;;;;;N;;;;;\n1F71A;ALCHEMICAL SYMBOL FOR GOLD;So;0;ON;;;;;N;;;;;\n1F71B;ALCHEMICAL SYMBOL FOR SILVER;So;0;ON;;;;;N;;;;;\n1F71C;ALCHEMICAL SYMBOL FOR IRON ORE;So;0;ON;;;;;N;;;;;\n1F71D;ALCHEMICAL SYMBOL FOR IRON ORE-2;So;0;ON;;;;;N;;;;;\n1F71E;ALCHEMICAL SYMBOL FOR CROCUS OF IRON;So;0;ON;;;;;N;;;;;\n1F71F;ALCHEMICAL SYMBOL FOR REGULUS OF IRON;So;0;ON;;;;;N;;;;;\n1F720;ALCHEMICAL SYMBOL FOR COPPER ORE;So;0;ON;;;;;N;;;;;\n1F721;ALCHEMICAL SYMBOL FOR IRON-COPPER ORE;So;0;ON;;;;;N;;;;;\n1F722;ALCHEMICAL SYMBOL FOR SUBLIMATE OF COPPER;So;0;ON;;;;;N;;;;;\n1F723;ALCHEMICAL SYMBOL FOR CROCUS OF COPPER;So;0;ON;;;;;N;;;;;\n1F724;ALCHEMICAL SYMBOL FOR CROCUS OF COPPER-2;So;0;ON;;;;;N;;;;;\n1F725;ALCHEMICAL SYMBOL FOR COPPER ANTIMONIATE;So;0;ON;;;;;N;;;;;\n1F726;ALCHEMICAL SYMBOL FOR SALT OF COPPER ANTIMONIATE;So;0;ON;;;;;N;;;;;\n1F727;ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF COPPER;So;0;ON;;;;;N;;;;;\n1F728;ALCHEMICAL SYMBOL FOR VERDIGRIS;So;0;ON;;;;;N;;;;;\n1F729;ALCHEMICAL SYMBOL FOR TIN ORE;So;0;ON;;;;;N;;;;;\n1F72A;ALCHEMICAL SYMBOL FOR LEAD ORE;So;0;ON;;;;;N;;;;;\n1F72B;ALCHEMICAL SYMBOL FOR ANTIMONY ORE;So;0;ON;;;;;N;;;;;\n1F72C;ALCHEMICAL SYMBOL FOR SUBLIMATE OF ANTIMONY;So;0;ON;;;;;N;;;;;\n1F72D;ALCHEMICAL SYMBOL FOR SALT OF ANTIMONY;So;0;ON;;;;;N;;;;;\n1F72E;ALCHEMICAL SYMBOL FOR SUBLIMATE OF SALT OF ANTIMONY;So;0;ON;;;;;N;;;;;\n1F72F;ALCHEMICAL SYMBOL FOR VINEGAR OF ANTIMONY;So;0;ON;;;;;N;;;;;\n1F730;ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY;So;0;ON;;;;;N;;;;;\n1F731;ALCHEMICAL SYMBOL FOR REGULUS OF ANTIMONY-2;So;0;ON;;;;;N;;;;;\n1F732;ALCHEMICAL SYMBOL FOR REGULUS;So;0;ON;;;;;N;;;;;\n1F733;ALCHEMICAL SYMBOL FOR REGULUS-2;So;0;ON;;;;;N;;;;;\n1F734;ALCHEMICAL SYMBOL FOR REGULUS-3;So;0;ON;;;;;N;;;;;\n1F735;ALCHEMICAL SYMBOL FOR REGULUS-4;So;0;ON;;;;;N;;;;;\n1F736;ALCHEMICAL SYMBOL FOR ALKALI;So;0;ON;;;;;N;;;;;\n1F737;ALCHEMICAL SYMBOL FOR ALKALI-2;So;0;ON;;;;;N;;;;;\n1F738;ALCHEMICAL SYMBOL FOR MARCASITE;So;0;ON;;;;;N;;;;;\n1F739;ALCHEMICAL SYMBOL FOR SAL-AMMONIAC;So;0;ON;;;;;N;;;;;\n1F73A;ALCHEMICAL SYMBOL FOR ARSENIC;So;0;ON;;;;;N;;;;;\n1F73B;ALCHEMICAL SYMBOL FOR REALGAR;So;0;ON;;;;;N;;;;;\n1F73C;ALCHEMICAL SYMBOL FOR REALGAR-2;So;0;ON;;;;;N;;;;;\n1F73D;ALCHEMICAL SYMBOL FOR AURIPIGMENT;So;0;ON;;;;;N;;;;;\n1F73E;ALCHEMICAL SYMBOL FOR BISMUTH ORE;So;0;ON;;;;;N;;;;;\n1F73F;ALCHEMICAL SYMBOL FOR TARTAR;So;0;ON;;;;;N;;;;;\n1F740;ALCHEMICAL SYMBOL FOR TARTAR-2;So;0;ON;;;;;N;;;;;\n1F741;ALCHEMICAL SYMBOL FOR QUICK LIME;So;0;ON;;;;;N;;;;;\n1F742;ALCHEMICAL SYMBOL FOR BORAX;So;0;ON;;;;;N;;;;;\n1F743;ALCHEMICAL SYMBOL FOR BORAX-2;So;0;ON;;;;;N;;;;;\n1F744;ALCHEMICAL SYMBOL FOR BORAX-3;So;0;ON;;;;;N;;;;;\n1F745;ALCHEMICAL SYMBOL FOR ALUM;So;0;ON;;;;;N;;;;;\n1F746;ALCHEMICAL SYMBOL FOR OIL;So;0;ON;;;;;N;;;;;\n1F747;ALCHEMICAL SYMBOL FOR SPIRIT;So;0;ON;;;;;N;;;;;\n1F748;ALCHEMICAL SYMBOL FOR TINCTURE;So;0;ON;;;;;N;;;;;\n1F749;ALCHEMICAL SYMBOL FOR GUM;So;0;ON;;;;;N;;;;;\n1F74A;ALCHEMICAL SYMBOL FOR WAX;So;0;ON;;;;;N;;;;;\n1F74B;ALCHEMICAL SYMBOL FOR POWDER;So;0;ON;;;;;N;;;;;\n1F74C;ALCHEMICAL SYMBOL FOR CALX;So;0;ON;;;;;N;;;;;\n1F74D;ALCHEMICAL SYMBOL FOR TUTTY;So;0;ON;;;;;N;;;;;\n1F74E;ALCHEMICAL SYMBOL FOR CAPUT MORTUUM;So;0;ON;;;;;N;;;;;\n1F74F;ALCHEMICAL SYMBOL FOR SCEPTER OF JOVE;So;0;ON;;;;;N;;;;;\n1F750;ALCHEMICAL SYMBOL FOR CADUCEUS;So;0;ON;;;;;N;;;;;\n1F751;ALCHEMICAL SYMBOL FOR TRIDENT;So;0;ON;;;;;N;;;;;\n1F752;ALCHEMICAL SYMBOL FOR STARRED TRIDENT;So;0;ON;;;;;N;;;;;\n1F753;ALCHEMICAL SYMBOL FOR LODESTONE;So;0;ON;;;;;N;;;;;\n1F754;ALCHEMICAL SYMBOL FOR SOAP;So;0;ON;;;;;N;;;;;\n1F755;ALCHEMICAL SYMBOL FOR URINE;So;0;ON;;;;;N;;;;;\n1F756;ALCHEMICAL SYMBOL FOR HORSE DUNG;So;0;ON;;;;;N;;;;;\n1F757;ALCHEMICAL SYMBOL FOR ASHES;So;0;ON;;;;;N;;;;;\n1F758;ALCHEMICAL SYMBOL FOR POT ASHES;So;0;ON;;;;;N;;;;;\n1F759;ALCHEMICAL SYMBOL FOR BRICK;So;0;ON;;;;;N;;;;;\n1F75A;ALCHEMICAL SYMBOL FOR POWDERED BRICK;So;0;ON;;;;;N;;;;;\n1F75B;ALCHEMICAL SYMBOL FOR AMALGAM;So;0;ON;;;;;N;;;;;\n1F75C;ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM;So;0;ON;;;;;N;;;;;\n1F75D;ALCHEMICAL SYMBOL FOR STRATUM SUPER STRATUM-2;So;0;ON;;;;;N;;;;;\n1F75E;ALCHEMICAL SYMBOL FOR SUBLIMATION;So;0;ON;;;;;N;;;;;\n1F75F;ALCHEMICAL SYMBOL FOR PRECIPITATE;So;0;ON;;;;;N;;;;;\n1F760;ALCHEMICAL SYMBOL FOR DISTILL;So;0;ON;;;;;N;;;;;\n1F761;ALCHEMICAL SYMBOL FOR DISSOLVE;So;0;ON;;;;;N;;;;;\n1F762;ALCHEMICAL SYMBOL FOR DISSOLVE-2;So;0;ON;;;;;N;;;;;\n1F763;ALCHEMICAL SYMBOL FOR PURIFY;So;0;ON;;;;;N;;;;;\n1F764;ALCHEMICAL SYMBOL FOR PUTREFACTION;So;0;ON;;;;;N;;;;;\n1F765;ALCHEMICAL SYMBOL FOR CRUCIBLE;So;0;ON;;;;;N;;;;;\n1F766;ALCHEMICAL SYMBOL FOR CRUCIBLE-2;So;0;ON;;;;;N;;;;;\n1F767;ALCHEMICAL SYMBOL FOR CRUCIBLE-3;So;0;ON;;;;;N;;;;;\n1F768;ALCHEMICAL SYMBOL FOR CRUCIBLE-4;So;0;ON;;;;;N;;;;;\n1F769;ALCHEMICAL SYMBOL FOR CRUCIBLE-5;So;0;ON;;;;;N;;;;;\n1F76A;ALCHEMICAL SYMBOL FOR ALEMBIC;So;0;ON;;;;;N;;;;;\n1F76B;ALCHEMICAL SYMBOL FOR BATH OF MARY;So;0;ON;;;;;N;;;;;\n1F76C;ALCHEMICAL SYMBOL FOR BATH OF VAPOURS;So;0;ON;;;;;N;;;;;\n1F76D;ALCHEMICAL SYMBOL FOR RETORT;So;0;ON;;;;;N;;;;;\n1F76E;ALCHEMICAL SYMBOL FOR HOUR;So;0;ON;;;;;N;;;;;\n1F76F;ALCHEMICAL SYMBOL FOR NIGHT;So;0;ON;;;;;N;;;;;\n1F770;ALCHEMICAL SYMBOL FOR DAY-NIGHT;So;0;ON;;;;;N;;;;;\n1F771;ALCHEMICAL SYMBOL FOR MONTH;So;0;ON;;;;;N;;;;;\n1F772;ALCHEMICAL SYMBOL FOR HALF DRAM;So;0;ON;;;;;N;;;;;\n1F773;ALCHEMICAL SYMBOL FOR HALF OUNCE;So;0;ON;;;;;N;;;;;\n1F780;BLACK LEFT-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;\n1F781;BLACK UP-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;\n1F782;BLACK RIGHT-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;\n1F783;BLACK DOWN-POINTING ISOSCELES RIGHT TRIANGLE;So;0;ON;;;;;N;;;;;\n1F784;BLACK SLIGHTLY SMALL CIRCLE;So;0;ON;;;;;N;;;;;\n1F785;MEDIUM BOLD WHITE CIRCLE;So;0;ON;;;;;N;;;;;\n1F786;BOLD WHITE CIRCLE;So;0;ON;;;;;N;;;;;\n1F787;HEAVY WHITE CIRCLE;So;0;ON;;;;;N;;;;;\n1F788;VERY HEAVY WHITE CIRCLE;So;0;ON;;;;;N;;;;;\n1F789;EXTREMELY HEAVY WHITE CIRCLE;So;0;ON;;;;;N;;;;;\n1F78A;WHITE CIRCLE CONTAINING BLACK SMALL CIRCLE;So;0;ON;;;;;N;;;;;\n1F78B;ROUND TARGET;So;0;ON;;;;;N;;;;;\n1F78C;BLACK TINY SQUARE;So;0;ON;;;;;N;;;;;\n1F78D;BLACK SLIGHTLY SMALL SQUARE;So;0;ON;;;;;N;;;;;\n1F78E;LIGHT WHITE SQUARE;So;0;ON;;;;;N;;;;;\n1F78F;MEDIUM WHITE SQUARE;So;0;ON;;;;;N;;;;;\n1F790;BOLD WHITE SQUARE;So;0;ON;;;;;N;;;;;\n1F791;HEAVY WHITE SQUARE;So;0;ON;;;;;N;;;;;\n1F792;VERY HEAVY WHITE SQUARE;So;0;ON;;;;;N;;;;;\n1F793;EXTREMELY HEAVY WHITE SQUARE;So;0;ON;;;;;N;;;;;\n1F794;WHITE SQUARE CONTAINING BLACK VERY SMALL SQUARE;So;0;ON;;;;;N;;;;;\n1F795;WHITE SQUARE CONTAINING BLACK MEDIUM SQUARE;So;0;ON;;;;;N;;;;;\n1F796;SQUARE TARGET;So;0;ON;;;;;N;;;;;\n1F797;BLACK TINY DIAMOND;So;0;ON;;;;;N;;;;;\n1F798;BLACK VERY SMALL DIAMOND;So;0;ON;;;;;N;;;;;\n1F799;BLACK MEDIUM SMALL DIAMOND;So;0;ON;;;;;N;;;;;\n1F79A;WHITE DIAMOND CONTAINING BLACK VERY SMALL DIAMOND;So;0;ON;;;;;N;;;;;\n1F79B;WHITE DIAMOND CONTAINING BLACK MEDIUM DIAMOND;So;0;ON;;;;;N;;;;;\n1F79C;DIAMOND TARGET;So;0;ON;;;;;N;;;;;\n1F79D;BLACK TINY LOZENGE;So;0;ON;;;;;N;;;;;\n1F79E;BLACK VERY SMALL LOZENGE;So;0;ON;;;;;N;;;;;\n1F79F;BLACK MEDIUM SMALL LOZENGE;So;0;ON;;;;;N;;;;;\n1F7A0;WHITE LOZENGE CONTAINING BLACK SMALL LOZENGE;So;0;ON;;;;;N;;;;;\n1F7A1;THIN GREEK CROSS;So;0;ON;;;;;N;;;;;\n1F7A2;LIGHT GREEK CROSS;So;0;ON;;;;;N;;;;;\n1F7A3;MEDIUM GREEK CROSS;So;0;ON;;;;;N;;;;;\n1F7A4;BOLD GREEK CROSS;So;0;ON;;;;;N;;;;;\n1F7A5;VERY BOLD GREEK CROSS;So;0;ON;;;;;N;;;;;\n1F7A6;VERY HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;;\n1F7A7;EXTREMELY HEAVY GREEK CROSS;So;0;ON;;;;;N;;;;;\n1F7A8;THIN SALTIRE;So;0;ON;;;;;N;;;;;\n1F7A9;LIGHT SALTIRE;So;0;ON;;;;;N;;;;;\n1F7AA;MEDIUM SALTIRE;So;0;ON;;;;;N;;;;;\n1F7AB;BOLD SALTIRE;So;0;ON;;;;;N;;;;;\n1F7AC;HEAVY SALTIRE;So;0;ON;;;;;N;;;;;\n1F7AD;VERY HEAVY SALTIRE;So;0;ON;;;;;N;;;;;\n1F7AE;EXTREMELY HEAVY SALTIRE;So;0;ON;;;;;N;;;;;\n1F7AF;LIGHT FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7B0;MEDIUM FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7B1;BOLD FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7B2;HEAVY FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7B3;VERY HEAVY FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7B4;EXTREMELY HEAVY FIVE SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7B5;LIGHT SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7B6;MEDIUM SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7B7;BOLD SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7B8;HEAVY SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7B9;VERY HEAVY SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7BA;EXTREMELY HEAVY SIX SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7BB;LIGHT EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7BC;MEDIUM EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7BD;BOLD EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7BE;HEAVY EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7BF;VERY HEAVY EIGHT SPOKED ASTERISK;So;0;ON;;;;;N;;;;;\n1F7C0;LIGHT THREE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n1F7C1;MEDIUM THREE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n1F7C2;THREE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n1F7C3;MEDIUM THREE POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;\n1F7C4;LIGHT FOUR POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n1F7C5;MEDIUM FOUR POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n1F7C6;FOUR POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n1F7C7;MEDIUM FOUR POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;\n1F7C8;REVERSE LIGHT FOUR POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;\n1F7C9;LIGHT FIVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n1F7CA;HEAVY FIVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n1F7CB;MEDIUM SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n1F7CC;HEAVY SIX POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n1F7CD;SIX POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;\n1F7CE;MEDIUM EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n1F7CF;HEAVY EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n1F7D0;VERY HEAVY EIGHT POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n1F7D1;HEAVY EIGHT POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;\n1F7D2;LIGHT TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n1F7D3;HEAVY TWELVE POINTED BLACK STAR;So;0;ON;;;;;N;;;;;\n1F7D4;HEAVY TWELVE POINTED PINWHEEL STAR;So;0;ON;;;;;N;;;;;\n1F7D5;CIRCLED TRIANGLE;So;0;ON;;;;;N;;;;;\n1F7D6;NEGATIVE CIRCLED TRIANGLE;So;0;ON;;;;;N;;;;;\n1F7D7;CIRCLED SQUARE;So;0;ON;;;;;N;;;;;\n1F7D8;NEGATIVE CIRCLED SQUARE;So;0;ON;;;;;N;;;;;\n1F7E0;LARGE ORANGE CIRCLE;So;0;ON;;;;;N;;;;;\n1F7E1;LARGE YELLOW CIRCLE;So;0;ON;;;;;N;;;;;\n1F7E2;LARGE GREEN CIRCLE;So;0;ON;;;;;N;;;;;\n1F7E3;LARGE PURPLE CIRCLE;So;0;ON;;;;;N;;;;;\n1F7E4;LARGE BROWN CIRCLE;So;0;ON;;;;;N;;;;;\n1F7E5;LARGE RED SQUARE;So;0;ON;;;;;N;;;;;\n1F7E6;LARGE BLUE SQUARE;So;0;ON;;;;;N;;;;;\n1F7E7;LARGE ORANGE SQUARE;So;0;ON;;;;;N;;;;;\n1F7E8;LARGE YELLOW SQUARE;So;0;ON;;;;;N;;;;;\n1F7E9;LARGE GREEN SQUARE;So;0;ON;;;;;N;;;;;\n1F7EA;LARGE PURPLE SQUARE;So;0;ON;;;;;N;;;;;\n1F7EB;LARGE BROWN SQUARE;So;0;ON;;;;;N;;;;;\n1F800;LEFTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F801;UPWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F802;RIGHTWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F803;DOWNWARDS ARROW WITH SMALL TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F804;LEFTWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F805;UPWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F806;RIGHTWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F807;DOWNWARDS ARROW WITH MEDIUM TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F808;LEFTWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F809;UPWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F80A;RIGHTWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F80B;DOWNWARDS ARROW WITH LARGE TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F810;LEFTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F811;UPWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F812;RIGHTWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F813;DOWNWARDS ARROW WITH SMALL EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F814;LEFTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F815;UPWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F816;RIGHTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F817;DOWNWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F818;HEAVY LEFTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F819;HEAVY UPWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F81A;HEAVY RIGHTWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F81B;HEAVY DOWNWARDS ARROW WITH EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F81C;HEAVY LEFTWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F81D;HEAVY UPWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F81E;HEAVY RIGHTWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F81F;HEAVY DOWNWARDS ARROW WITH LARGE EQUILATERAL ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F820;LEFTWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;;\n1F821;UPWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;;\n1F822;RIGHTWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;;\n1F823;DOWNWARDS TRIANGLE-HEADED ARROW WITH NARROW SHAFT;So;0;ON;;;;;N;;;;;\n1F824;LEFTWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;;\n1F825;UPWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;;\n1F826;RIGHTWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;;\n1F827;DOWNWARDS TRIANGLE-HEADED ARROW WITH MEDIUM SHAFT;So;0;ON;;;;;N;;;;;\n1F828;LEFTWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;;\n1F829;UPWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;;\n1F82A;RIGHTWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;;\n1F82B;DOWNWARDS TRIANGLE-HEADED ARROW WITH BOLD SHAFT;So;0;ON;;;;;N;;;;;\n1F82C;LEFTWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;;\n1F82D;UPWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;;\n1F82E;RIGHTWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;;\n1F82F;DOWNWARDS TRIANGLE-HEADED ARROW WITH HEAVY SHAFT;So;0;ON;;;;;N;;;;;\n1F830;LEFTWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;;\n1F831;UPWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;;\n1F832;RIGHTWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;;\n1F833;DOWNWARDS TRIANGLE-HEADED ARROW WITH VERY HEAVY SHAFT;So;0;ON;;;;;N;;;;;\n1F834;LEFTWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;;\n1F835;UPWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;;\n1F836;RIGHTWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;;\n1F837;DOWNWARDS FINGER-POST ARROW;So;0;ON;;;;;N;;;;;\n1F838;LEFTWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;;\n1F839;UPWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;;\n1F83A;RIGHTWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;;\n1F83B;DOWNWARDS SQUARED ARROW;So;0;ON;;;;;N;;;;;\n1F83C;LEFTWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;;\n1F83D;UPWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;;\n1F83E;RIGHTWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;;\n1F83F;DOWNWARDS COMPRESSED ARROW;So;0;ON;;;;;N;;;;;\n1F840;LEFTWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;;\n1F841;UPWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;;\n1F842;RIGHTWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;;\n1F843;DOWNWARDS HEAVY COMPRESSED ARROW;So;0;ON;;;;;N;;;;;\n1F844;LEFTWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;;\n1F845;UPWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;;\n1F846;RIGHTWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;;\n1F847;DOWNWARDS HEAVY ARROW;So;0;ON;;;;;N;;;;;\n1F850;LEFTWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;\n1F851;UPWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;\n1F852;RIGHTWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;\n1F853;DOWNWARDS SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;\n1F854;NORTH WEST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;\n1F855;NORTH EAST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;\n1F856;SOUTH EAST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;\n1F857;SOUTH WEST SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;\n1F858;LEFT RIGHT SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;\n1F859;UP DOWN SANS-SERIF ARROW;So;0;ON;;;;;N;;;;;\n1F860;WIDE-HEADED LEFTWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;\n1F861;WIDE-HEADED UPWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;\n1F862;WIDE-HEADED RIGHTWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;\n1F863;WIDE-HEADED DOWNWARDS LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;\n1F864;WIDE-HEADED NORTH WEST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;\n1F865;WIDE-HEADED NORTH EAST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;\n1F866;WIDE-HEADED SOUTH EAST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;\n1F867;WIDE-HEADED SOUTH WEST LIGHT BARB ARROW;So;0;ON;;;;;N;;;;;\n1F868;WIDE-HEADED LEFTWARDS BARB ARROW;So;0;ON;;;;;N;;;;;\n1F869;WIDE-HEADED UPWARDS BARB ARROW;So;0;ON;;;;;N;;;;;\n1F86A;WIDE-HEADED RIGHTWARDS BARB ARROW;So;0;ON;;;;;N;;;;;\n1F86B;WIDE-HEADED DOWNWARDS BARB ARROW;So;0;ON;;;;;N;;;;;\n1F86C;WIDE-HEADED NORTH WEST BARB ARROW;So;0;ON;;;;;N;;;;;\n1F86D;WIDE-HEADED NORTH EAST BARB ARROW;So;0;ON;;;;;N;;;;;\n1F86E;WIDE-HEADED SOUTH EAST BARB ARROW;So;0;ON;;;;;N;;;;;\n1F86F;WIDE-HEADED SOUTH WEST BARB ARROW;So;0;ON;;;;;N;;;;;\n1F870;WIDE-HEADED LEFTWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;\n1F871;WIDE-HEADED UPWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;\n1F872;WIDE-HEADED RIGHTWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;\n1F873;WIDE-HEADED DOWNWARDS MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;\n1F874;WIDE-HEADED NORTH WEST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;\n1F875;WIDE-HEADED NORTH EAST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;\n1F876;WIDE-HEADED SOUTH EAST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;\n1F877;WIDE-HEADED SOUTH WEST MEDIUM BARB ARROW;So;0;ON;;;;;N;;;;;\n1F878;WIDE-HEADED LEFTWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F879;WIDE-HEADED UPWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F87A;WIDE-HEADED RIGHTWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F87B;WIDE-HEADED DOWNWARDS HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F87C;WIDE-HEADED NORTH WEST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F87D;WIDE-HEADED NORTH EAST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F87E;WIDE-HEADED SOUTH EAST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F87F;WIDE-HEADED SOUTH WEST HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F880;WIDE-HEADED LEFTWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F881;WIDE-HEADED UPWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F882;WIDE-HEADED RIGHTWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F883;WIDE-HEADED DOWNWARDS VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F884;WIDE-HEADED NORTH WEST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F885;WIDE-HEADED NORTH EAST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F886;WIDE-HEADED SOUTH EAST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F887;WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW;So;0;ON;;;;;N;;;;;\n1F890;LEFTWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F891;UPWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F892;RIGHTWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F893;DOWNWARDS TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F894;LEFTWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F895;UPWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F896;RIGHTWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F897;DOWNWARDS WHITE ARROW WITHIN TRIANGLE ARROWHEAD;So;0;ON;;;;;N;;;;;\n1F898;LEFTWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;;\n1F899;UPWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;;\n1F89A;RIGHTWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;;\n1F89B;DOWNWARDS ARROW WITH NOTCHED TAIL;So;0;ON;;;;;N;;;;;\n1F89C;HEAVY ARROW SHAFT WIDTH ONE;So;0;ON;;;;;N;;;;;\n1F89D;HEAVY ARROW SHAFT WIDTH TWO THIRDS;So;0;ON;;;;;N;;;;;\n1F89E;HEAVY ARROW SHAFT WIDTH ONE HALF;So;0;ON;;;;;N;;;;;\n1F89F;HEAVY ARROW SHAFT WIDTH ONE THIRD;So;0;ON;;;;;N;;;;;\n1F8A0;LEFTWARDS BOTTOM-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;\n1F8A1;RIGHTWARDS BOTTOM SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;\n1F8A2;LEFTWARDS TOP SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;\n1F8A3;RIGHTWARDS TOP SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;\n1F8A4;LEFTWARDS LEFT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;\n1F8A5;RIGHTWARDS RIGHT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;\n1F8A6;LEFTWARDS RIGHT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;\n1F8A7;RIGHTWARDS LEFT-SHADED WHITE ARROW;So;0;ON;;;;;N;;;;;\n1F8A8;LEFTWARDS BACK-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;;\n1F8A9;RIGHTWARDS BACK-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;;\n1F8AA;LEFTWARDS FRONT-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;;\n1F8AB;RIGHTWARDS FRONT-TILTED SHADOWED WHITE ARROW;So;0;ON;;;;;N;;;;;\n1F8AC;WHITE ARROW SHAFT WIDTH ONE;So;0;ON;;;;;N;;;;;\n1F8AD;WHITE ARROW SHAFT WIDTH TWO THIRDS;So;0;ON;;;;;N;;;;;\n1F900;CIRCLED CROSS FORMEE WITH FOUR DOTS;So;0;ON;;;;;N;;;;;\n1F901;CIRCLED CROSS FORMEE WITH TWO DOTS;So;0;ON;;;;;N;;;;;\n1F902;CIRCLED CROSS FORMEE;So;0;ON;;;;;N;;;;;\n1F903;LEFT HALF CIRCLE WITH FOUR DOTS;So;0;ON;;;;;N;;;;;\n1F904;LEFT HALF CIRCLE WITH THREE DOTS;So;0;ON;;;;;N;;;;;\n1F905;LEFT HALF CIRCLE WITH TWO DOTS;So;0;ON;;;;;N;;;;;\n1F906;LEFT HALF CIRCLE WITH DOT;So;0;ON;;;;;N;;;;;\n1F907;LEFT HALF CIRCLE;So;0;ON;;;;;N;;;;;\n1F908;DOWNWARD FACING HOOK;So;0;ON;;;;;N;;;;;\n1F909;DOWNWARD FACING NOTCHED HOOK;So;0;ON;;;;;N;;;;;\n1F90A;DOWNWARD FACING HOOK WITH DOT;So;0;ON;;;;;N;;;;;\n1F90B;DOWNWARD FACING NOTCHED HOOK WITH DOT;So;0;ON;;;;;N;;;;;\n1F90D;WHITE HEART;So;0;ON;;;;;N;;;;;\n1F90E;BROWN HEART;So;0;ON;;;;;N;;;;;\n1F90F;PINCHING HAND;So;0;ON;;;;;N;;;;;\n1F910;ZIPPER-MOUTH FACE;So;0;ON;;;;;N;;;;;\n1F911;MONEY-MOUTH FACE;So;0;ON;;;;;N;;;;;\n1F912;FACE WITH THERMOMETER;So;0;ON;;;;;N;;;;;\n1F913;NERD FACE;So;0;ON;;;;;N;;;;;\n1F914;THINKING FACE;So;0;ON;;;;;N;;;;;\n1F915;FACE WITH HEAD-BANDAGE;So;0;ON;;;;;N;;;;;\n1F916;ROBOT FACE;So;0;ON;;;;;N;;;;;\n1F917;HUGGING FACE;So;0;ON;;;;;N;;;;;\n1F918;SIGN OF THE HORNS;So;0;ON;;;;;N;;;;;\n1F919;CALL ME HAND;So;0;ON;;;;;N;;;;;\n1F91A;RAISED BACK OF HAND;So;0;ON;;;;;N;;;;;\n1F91B;LEFT-FACING FIST;So;0;ON;;;;;N;;;;;\n1F91C;RIGHT-FACING FIST;So;0;ON;;;;;N;;;;;\n1F91D;HANDSHAKE;So;0;ON;;;;;N;;;;;\n1F91E;HAND WITH INDEX AND MIDDLE FINGERS CROSSED;So;0;ON;;;;;N;;;;;\n1F91F;I LOVE YOU HAND SIGN;So;0;ON;;;;;N;;;;;\n1F920;FACE WITH COWBOY HAT;So;0;ON;;;;;N;;;;;\n1F921;CLOWN FACE;So;0;ON;;;;;N;;;;;\n1F922;NAUSEATED FACE;So;0;ON;;;;;N;;;;;\n1F923;ROLLING ON THE FLOOR LAUGHING;So;0;ON;;;;;N;;;;;\n1F924;DROOLING FACE;So;0;ON;;;;;N;;;;;\n1F925;LYING FACE;So;0;ON;;;;;N;;;;;\n1F926;FACE PALM;So;0;ON;;;;;N;;;;;\n1F927;SNEEZING FACE;So;0;ON;;;;;N;;;;;\n1F928;FACE WITH ONE EYEBROW RAISED;So;0;ON;;;;;N;;;;;\n1F929;GRINNING FACE WITH STAR EYES;So;0;ON;;;;;N;;;;;\n1F92A;GRINNING FACE WITH ONE LARGE AND ONE SMALL EYE;So;0;ON;;;;;N;;;;;\n1F92B;FACE WITH FINGER COVERING CLOSED LIPS;So;0;ON;;;;;N;;;;;\n1F92C;SERIOUS FACE WITH SYMBOLS COVERING MOUTH;So;0;ON;;;;;N;;;;;\n1F92D;SMILING FACE WITH SMILING EYES AND HAND COVERING MOUTH;So;0;ON;;;;;N;;;;;\n1F92E;FACE WITH OPEN MOUTH VOMITING;So;0;ON;;;;;N;;;;;\n1F92F;SHOCKED FACE WITH EXPLODING HEAD;So;0;ON;;;;;N;;;;;\n1F930;PREGNANT WOMAN;So;0;ON;;;;;N;;;;;\n1F931;BREAST-FEEDING;So;0;ON;;;;;N;;;;;\n1F932;PALMS UP TOGETHER;So;0;ON;;;;;N;;;;;\n1F933;SELFIE;So;0;ON;;;;;N;;;;;\n1F934;PRINCE;So;0;ON;;;;;N;;;;;\n1F935;MAN IN TUXEDO;So;0;ON;;;;;N;;;;;\n1F936;MOTHER CHRISTMAS;So;0;ON;;;;;N;;;;;\n1F937;SHRUG;So;0;ON;;;;;N;;;;;\n1F938;PERSON DOING CARTWHEEL;So;0;ON;;;;;N;;;;;\n1F939;JUGGLING;So;0;ON;;;;;N;;;;;\n1F93A;FENCER;So;0;ON;;;;;N;;;;;\n1F93B;MODERN PENTATHLON;So;0;ON;;;;;N;;;;;\n1F93C;WRESTLERS;So;0;ON;;;;;N;;;;;\n1F93D;WATER POLO;So;0;ON;;;;;N;;;;;\n1F93E;HANDBALL;So;0;ON;;;;;N;;;;;\n1F93F;DIVING MASK;So;0;ON;;;;;N;;;;;\n1F940;WILTED FLOWER;So;0;ON;;;;;N;;;;;\n1F941;DRUM WITH DRUMSTICKS;So;0;ON;;;;;N;;;;;\n1F942;CLINKING GLASSES;So;0;ON;;;;;N;;;;;\n1F943;TUMBLER GLASS;So;0;ON;;;;;N;;;;;\n1F944;SPOON;So;0;ON;;;;;N;;;;;\n1F945;GOAL NET;So;0;ON;;;;;N;;;;;\n1F946;RIFLE;So;0;ON;;;;;N;;;;;\n1F947;FIRST PLACE MEDAL;So;0;ON;;;;;N;;;;;\n1F948;SECOND PLACE MEDAL;So;0;ON;;;;;N;;;;;\n1F949;THIRD PLACE MEDAL;So;0;ON;;;;;N;;;;;\n1F94A;BOXING GLOVE;So;0;ON;;;;;N;;;;;\n1F94B;MARTIAL ARTS UNIFORM;So;0;ON;;;;;N;;;;;\n1F94C;CURLING STONE;So;0;ON;;;;;N;;;;;\n1F94D;LACROSSE STICK AND BALL;So;0;ON;;;;;N;;;;;\n1F94E;SOFTBALL;So;0;ON;;;;;N;;;;;\n1F94F;FLYING DISC;So;0;ON;;;;;N;;;;;\n1F950;CROISSANT;So;0;ON;;;;;N;;;;;\n1F951;AVOCADO;So;0;ON;;;;;N;;;;;\n1F952;CUCUMBER;So;0;ON;;;;;N;;;;;\n1F953;BACON;So;0;ON;;;;;N;;;;;\n1F954;POTATO;So;0;ON;;;;;N;;;;;\n1F955;CARROT;So;0;ON;;;;;N;;;;;\n1F956;BAGUETTE BREAD;So;0;ON;;;;;N;;;;;\n1F957;GREEN SALAD;So;0;ON;;;;;N;;;;;\n1F958;SHALLOW PAN OF FOOD;So;0;ON;;;;;N;;;;;\n1F959;STUFFED FLATBREAD;So;0;ON;;;;;N;;;;;\n1F95A;EGG;So;0;ON;;;;;N;;;;;\n1F95B;GLASS OF MILK;So;0;ON;;;;;N;;;;;\n1F95C;PEANUTS;So;0;ON;;;;;N;;;;;\n1F95D;KIWIFRUIT;So;0;ON;;;;;N;;;;;\n1F95E;PANCAKES;So;0;ON;;;;;N;;;;;\n1F95F;DUMPLING;So;0;ON;;;;;N;;;;;\n1F960;FORTUNE COOKIE;So;0;ON;;;;;N;;;;;\n1F961;TAKEOUT BOX;So;0;ON;;;;;N;;;;;\n1F962;CHOPSTICKS;So;0;ON;;;;;N;;;;;\n1F963;BOWL WITH SPOON;So;0;ON;;;;;N;;;;;\n1F964;CUP WITH STRAW;So;0;ON;;;;;N;;;;;\n1F965;COCONUT;So;0;ON;;;;;N;;;;;\n1F966;BROCCOLI;So;0;ON;;;;;N;;;;;\n1F967;PIE;So;0;ON;;;;;N;;;;;\n1F968;PRETZEL;So;0;ON;;;;;N;;;;;\n1F969;CUT OF MEAT;So;0;ON;;;;;N;;;;;\n1F96A;SANDWICH;So;0;ON;;;;;N;;;;;\n1F96B;CANNED FOOD;So;0;ON;;;;;N;;;;;\n1F96C;LEAFY GREEN;So;0;ON;;;;;N;;;;;\n1F96D;MANGO;So;0;ON;;;;;N;;;;;\n1F96E;MOON CAKE;So;0;ON;;;;;N;;;;;\n1F96F;BAGEL;So;0;ON;;;;;N;;;;;\n1F970;SMILING FACE WITH SMILING EYES AND THREE HEARTS;So;0;ON;;;;;N;;;;;\n1F971;YAWNING FACE;So;0;ON;;;;;N;;;;;\n1F973;FACE WITH PARTY HORN AND PARTY HAT;So;0;ON;;;;;N;;;;;\n1F974;FACE WITH UNEVEN EYES AND WAVY MOUTH;So;0;ON;;;;;N;;;;;\n1F975;OVERHEATED FACE;So;0;ON;;;;;N;;;;;\n1F976;FREEZING FACE;So;0;ON;;;;;N;;;;;\n1F97A;FACE WITH PLEADING EYES;So;0;ON;;;;;N;;;;;\n1F97B;SARI;So;0;ON;;;;;N;;;;;\n1F97C;LAB COAT;So;0;ON;;;;;N;;;;;\n1F97D;GOGGLES;So;0;ON;;;;;N;;;;;\n1F97E;HIKING BOOT;So;0;ON;;;;;N;;;;;\n1F97F;FLAT SHOE;So;0;ON;;;;;N;;;;;\n1F980;CRAB;So;0;ON;;;;;N;;;;;\n1F981;LION FACE;So;0;ON;;;;;N;;;;;\n1F982;SCORPION;So;0;ON;;;;;N;;;;;\n1F983;TURKEY;So;0;ON;;;;;N;;;;;\n1F984;UNICORN FACE;So;0;ON;;;;;N;;;;;\n1F985;EAGLE;So;0;ON;;;;;N;;;;;\n1F986;DUCK;So;0;ON;;;;;N;;;;;\n1F987;BAT;So;0;ON;;;;;N;;;;;\n1F988;SHARK;So;0;ON;;;;;N;;;;;\n1F989;OWL;So;0;ON;;;;;N;;;;;\n1F98A;FOX FACE;So;0;ON;;;;;N;;;;;\n1F98B;BUTTERFLY;So;0;ON;;;;;N;;;;;\n1F98C;DEER;So;0;ON;;;;;N;;;;;\n1F98D;GORILLA;So;0;ON;;;;;N;;;;;\n1F98E;LIZARD;So;0;ON;;;;;N;;;;;\n1F98F;RHINOCEROS;So;0;ON;;;;;N;;;;;\n1F990;SHRIMP;So;0;ON;;;;;N;;;;;\n1F991;SQUID;So;0;ON;;;;;N;;;;;\n1F992;GIRAFFE FACE;So;0;ON;;;;;N;;;;;\n1F993;ZEBRA FACE;So;0;ON;;;;;N;;;;;\n1F994;HEDGEHOG;So;0;ON;;;;;N;;;;;\n1F995;SAUROPOD;So;0;ON;;;;;N;;;;;\n1F996;T-REX;So;0;ON;;;;;N;;;;;\n1F997;CRICKET;So;0;ON;;;;;N;;;;;\n1F998;KANGAROO;So;0;ON;;;;;N;;;;;\n1F999;LLAMA;So;0;ON;;;;;N;;;;;\n1F99A;PEACOCK;So;0;ON;;;;;N;;;;;\n1F99B;HIPPOPOTAMUS;So;0;ON;;;;;N;;;;;\n1F99C;PARROT;So;0;ON;;;;;N;;;;;\n1F99D;RACCOON;So;0;ON;;;;;N;;;;;\n1F99E;LOBSTER;So;0;ON;;;;;N;;;;;\n1F99F;MOSQUITO;So;0;ON;;;;;N;;;;;\n1F9A0;MICROBE;So;0;ON;;;;;N;;;;;\n1F9A1;BADGER;So;0;ON;;;;;N;;;;;\n1F9A2;SWAN;So;0;ON;;;;;N;;;;;\n1F9A5;SLOTH;So;0;ON;;;;;N;;;;;\n1F9A6;OTTER;So;0;ON;;;;;N;;;;;\n1F9A7;ORANGUTAN;So;0;ON;;;;;N;;;;;\n1F9A8;SKUNK;So;0;ON;;;;;N;;;;;\n1F9A9;FLAMINGO;So;0;ON;;;;;N;;;;;\n1F9AA;OYSTER;So;0;ON;;;;;N;;;;;\n1F9AE;GUIDE DOG;So;0;ON;;;;;N;;;;;\n1F9AF;PROBING CANE;So;0;ON;;;;;N;;;;;\n1F9B0;EMOJI COMPONENT RED HAIR;So;0;ON;;;;;N;;;;;\n1F9B1;EMOJI COMPONENT CURLY HAIR;So;0;ON;;;;;N;;;;;\n1F9B2;EMOJI COMPONENT BALD;So;0;ON;;;;;N;;;;;\n1F9B3;EMOJI COMPONENT WHITE HAIR;So;0;ON;;;;;N;;;;;\n1F9B4;BONE;So;0;ON;;;;;N;;;;;\n1F9B5;LEG;So;0;ON;;;;;N;;;;;\n1F9B6;FOOT;So;0;ON;;;;;N;;;;;\n1F9B7;TOOTH;So;0;ON;;;;;N;;;;;\n1F9B8;SUPERHERO;So;0;ON;;;;;N;;;;;\n1F9B9;SUPERVILLAIN;So;0;ON;;;;;N;;;;;\n1F9BA;SAFETY VEST;So;0;ON;;;;;N;;;;;\n1F9BB;EAR WITH HEARING AID;So;0;ON;;;;;N;;;;;\n1F9BC;MOTORIZED WHEELCHAIR;So;0;ON;;;;;N;;;;;\n1F9BD;MANUAL WHEELCHAIR;So;0;ON;;;;;N;;;;;\n1F9BE;MECHANICAL ARM;So;0;ON;;;;;N;;;;;\n1F9BF;MECHANICAL LEG;So;0;ON;;;;;N;;;;;\n1F9C0;CHEESE WEDGE;So;0;ON;;;;;N;;;;;\n1F9C1;CUPCAKE;So;0;ON;;;;;N;;;;;\n1F9C2;SALT SHAKER;So;0;ON;;;;;N;;;;;\n1F9C3;BEVERAGE BOX;So;0;ON;;;;;N;;;;;\n1F9C4;GARLIC;So;0;ON;;;;;N;;;;;\n1F9C5;ONION;So;0;ON;;;;;N;;;;;\n1F9C6;FALAFEL;So;0;ON;;;;;N;;;;;\n1F9C7;WAFFLE;So;0;ON;;;;;N;;;;;\n1F9C8;BUTTER;So;0;ON;;;;;N;;;;;\n1F9C9;MATE DRINK;So;0;ON;;;;;N;;;;;\n1F9CA;ICE CUBE;So;0;ON;;;;;N;;;;;\n1F9CD;STANDING PERSON;So;0;ON;;;;;N;;;;;\n1F9CE;KNEELING PERSON;So;0;ON;;;;;N;;;;;\n1F9CF;DEAF PERSON;So;0;ON;;;;;N;;;;;\n1F9D0;FACE WITH MONOCLE;So;0;ON;;;;;N;;;;;\n1F9D1;ADULT;So;0;ON;;;;;N;;;;;\n1F9D2;CHILD;So;0;ON;;;;;N;;;;;\n1F9D3;OLDER ADULT;So;0;ON;;;;;N;;;;;\n1F9D4;BEARDED PERSON;So;0;ON;;;;;N;;;;;\n1F9D5;PERSON WITH HEADSCARF;So;0;ON;;;;;N;;;;;\n1F9D6;PERSON IN STEAMY ROOM;So;0;ON;;;;;N;;;;;\n1F9D7;PERSON CLIMBING;So;0;ON;;;;;N;;;;;\n1F9D8;PERSON IN LOTUS POSITION;So;0;ON;;;;;N;;;;;\n1F9D9;MAGE;So;0;ON;;;;;N;;;;;\n1F9DA;FAIRY;So;0;ON;;;;;N;;;;;\n1F9DB;VAMPIRE;So;0;ON;;;;;N;;;;;\n1F9DC;MERPERSON;So;0;ON;;;;;N;;;;;\n1F9DD;ELF;So;0;ON;;;;;N;;;;;\n1F9DE;GENIE;So;0;ON;;;;;N;;;;;\n1F9DF;ZOMBIE;So;0;ON;;;;;N;;;;;\n1F9E0;BRAIN;So;0;ON;;;;;N;;;;;\n1F9E1;ORANGE HEART;So;0;ON;;;;;N;;;;;\n1F9E2;BILLED CAP;So;0;ON;;;;;N;;;;;\n1F9E3;SCARF;So;0;ON;;;;;N;;;;;\n1F9E4;GLOVES;So;0;ON;;;;;N;;;;;\n1F9E5;COAT;So;0;ON;;;;;N;;;;;\n1F9E6;SOCKS;So;0;ON;;;;;N;;;;;\n1F9E7;RED GIFT ENVELOPE;So;0;ON;;;;;N;;;;;\n1F9E8;FIRECRACKER;So;0;ON;;;;;N;;;;;\n1F9E9;JIGSAW PUZZLE PIECE;So;0;ON;;;;;N;;;;;\n1F9EA;TEST TUBE;So;0;ON;;;;;N;;;;;\n1F9EB;PETRI DISH;So;0;ON;;;;;N;;;;;\n1F9EC;DNA DOUBLE HELIX;So;0;ON;;;;;N;;;;;\n1F9ED;COMPASS;So;0;ON;;;;;N;;;;;\n1F9EE;ABACUS;So;0;ON;;;;;N;;;;;\n1F9EF;FIRE EXTINGUISHER;So;0;ON;;;;;N;;;;;\n1F9F0;TOOLBOX;So;0;ON;;;;;N;;;;;\n1F9F1;BRICK;So;0;ON;;;;;N;;;;;\n1F9F2;MAGNET;So;0;ON;;;;;N;;;;;\n1F9F3;LUGGAGE;So;0;ON;;;;;N;;;;;\n1F9F4;LOTION BOTTLE;So;0;ON;;;;;N;;;;;\n1F9F5;SPOOL OF THREAD;So;0;ON;;;;;N;;;;;\n1F9F6;BALL OF YARN;So;0;ON;;;;;N;;;;;\n1F9F7;SAFETY PIN;So;0;ON;;;;;N;;;;;\n1F9F8;TEDDY BEAR;So;0;ON;;;;;N;;;;;\n1F9F9;BROOM;So;0;ON;;;;;N;;;;;\n1F9FA;BASKET;So;0;ON;;;;;N;;;;;\n1F9FB;ROLL OF PAPER;So;0;ON;;;;;N;;;;;\n1F9FC;BAR OF SOAP;So;0;ON;;;;;N;;;;;\n1F9FD;SPONGE;So;0;ON;;;;;N;;;;;\n1F9FE;RECEIPT;So;0;ON;;;;;N;;;;;\n1F9FF;NAZAR AMULET;So;0;ON;;;;;N;;;;;\n1FA00;NEUTRAL CHESS KING;So;0;ON;;;;;N;;;;;\n1FA01;NEUTRAL CHESS QUEEN;So;0;ON;;;;;N;;;;;\n1FA02;NEUTRAL CHESS ROOK;So;0;ON;;;;;N;;;;;\n1FA03;NEUTRAL CHESS BISHOP;So;0;ON;;;;;N;;;;;\n1FA04;NEUTRAL CHESS KNIGHT;So;0;ON;;;;;N;;;;;\n1FA05;NEUTRAL CHESS PAWN;So;0;ON;;;;;N;;;;;\n1FA06;WHITE CHESS KNIGHT ROTATED FORTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;\n1FA07;BLACK CHESS KNIGHT ROTATED FORTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;\n1FA08;NEUTRAL CHESS KNIGHT ROTATED FORTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;\n1FA09;WHITE CHESS KING ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA0A;WHITE CHESS QUEEN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA0B;WHITE CHESS ROOK ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA0C;WHITE CHESS BISHOP ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA0D;WHITE CHESS KNIGHT ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA0E;WHITE CHESS PAWN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA0F;BLACK CHESS KING ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA10;BLACK CHESS QUEEN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA11;BLACK CHESS ROOK ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA12;BLACK CHESS BISHOP ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA13;BLACK CHESS KNIGHT ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA14;BLACK CHESS PAWN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA15;NEUTRAL CHESS KING ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA16;NEUTRAL CHESS QUEEN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA17;NEUTRAL CHESS ROOK ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA18;NEUTRAL CHESS BISHOP ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA19;NEUTRAL CHESS KNIGHT ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA1A;NEUTRAL CHESS PAWN ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA1B;WHITE CHESS KNIGHT ROTATED ONE HUNDRED THIRTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;\n1FA1C;BLACK CHESS KNIGHT ROTATED ONE HUNDRED THIRTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;\n1FA1D;NEUTRAL CHESS KNIGHT ROTATED ONE HUNDRED THIRTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;\n1FA1E;WHITE CHESS TURNED KING;So;0;ON;;;;;N;;;;;\n1FA1F;WHITE CHESS TURNED QUEEN;So;0;ON;;;;;N;;;;;\n1FA20;WHITE CHESS TURNED ROOK;So;0;ON;;;;;N;;;;;\n1FA21;WHITE CHESS TURNED BISHOP;So;0;ON;;;;;N;;;;;\n1FA22;WHITE CHESS TURNED KNIGHT;So;0;ON;;;;;N;;;;;\n1FA23;WHITE CHESS TURNED PAWN;So;0;ON;;;;;N;;;;;\n1FA24;BLACK CHESS TURNED KING;So;0;ON;;;;;N;;;;;\n1FA25;BLACK CHESS TURNED QUEEN;So;0;ON;;;;;N;;;;;\n1FA26;BLACK CHESS TURNED ROOK;So;0;ON;;;;;N;;;;;\n1FA27;BLACK CHESS TURNED BISHOP;So;0;ON;;;;;N;;;;;\n1FA28;BLACK CHESS TURNED KNIGHT;So;0;ON;;;;;N;;;;;\n1FA29;BLACK CHESS TURNED PAWN;So;0;ON;;;;;N;;;;;\n1FA2A;NEUTRAL CHESS TURNED KING;So;0;ON;;;;;N;;;;;\n1FA2B;NEUTRAL CHESS TURNED QUEEN;So;0;ON;;;;;N;;;;;\n1FA2C;NEUTRAL CHESS TURNED ROOK;So;0;ON;;;;;N;;;;;\n1FA2D;NEUTRAL CHESS TURNED BISHOP;So;0;ON;;;;;N;;;;;\n1FA2E;NEUTRAL CHESS TURNED KNIGHT;So;0;ON;;;;;N;;;;;\n1FA2F;NEUTRAL CHESS TURNED PAWN;So;0;ON;;;;;N;;;;;\n1FA30;WHITE CHESS KNIGHT ROTATED TWO HUNDRED TWENTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;\n1FA31;BLACK CHESS KNIGHT ROTATED TWO HUNDRED TWENTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;\n1FA32;NEUTRAL CHESS KNIGHT ROTATED TWO HUNDRED TWENTY-FIVE DEGREES;So;0;ON;;;;;N;;;;;\n1FA33;WHITE CHESS KING ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA34;WHITE CHESS QUEEN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA35;WHITE CHESS ROOK ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA36;WHITE CHESS BISHOP ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA37;WHITE CHESS KNIGHT ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA38;WHITE CHESS PAWN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA39;BLACK CHESS KING ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA3A;BLACK CHESS QUEEN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA3B;BLACK CHESS ROOK ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA3C;BLACK CHESS BISHOP ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA3D;BLACK CHESS KNIGHT ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA3E;BLACK CHESS PAWN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA3F;NEUTRAL CHESS KING ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA40;NEUTRAL CHESS QUEEN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA41;NEUTRAL CHESS ROOK ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA42;NEUTRAL CHESS BISHOP ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA43;NEUTRAL CHESS KNIGHT ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA44;NEUTRAL CHESS PAWN ROTATED TWO HUNDRED SEVENTY DEGREES;So;0;ON;;;;;N;;;;;\n1FA45;WHITE CHESS KNIGHT ROTATED THREE HUNDRED FIFTEEN DEGREES;So;0;ON;;;;;N;;;;;\n1FA46;BLACK CHESS KNIGHT ROTATED THREE HUNDRED FIFTEEN DEGREES;So;0;ON;;;;;N;;;;;\n1FA47;NEUTRAL CHESS KNIGHT ROTATED THREE HUNDRED FIFTEEN DEGREES;So;0;ON;;;;;N;;;;;\n1FA48;WHITE CHESS EQUIHOPPER;So;0;ON;;;;;N;;;;;\n1FA49;BLACK CHESS EQUIHOPPER;So;0;ON;;;;;N;;;;;\n1FA4A;NEUTRAL CHESS EQUIHOPPER;So;0;ON;;;;;N;;;;;\n1FA4B;WHITE CHESS EQUIHOPPER ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA4C;BLACK CHESS EQUIHOPPER ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA4D;NEUTRAL CHESS EQUIHOPPER ROTATED NINETY DEGREES;So;0;ON;;;;;N;;;;;\n1FA4E;WHITE CHESS KNIGHT-QUEEN;So;0;ON;;;;;N;;;;;\n1FA4F;WHITE CHESS KNIGHT-ROOK;So;0;ON;;;;;N;;;;;\n1FA50;WHITE CHESS KNIGHT-BISHOP;So;0;ON;;;;;N;;;;;\n1FA51;BLACK CHESS KNIGHT-QUEEN;So;0;ON;;;;;N;;;;;\n1FA52;BLACK CHESS KNIGHT-ROOK;So;0;ON;;;;;N;;;;;\n1FA53;BLACK CHESS KNIGHT-BISHOP;So;0;ON;;;;;N;;;;;\n1FA60;XIANGQI RED GENERAL;So;0;ON;;;;;N;;;;;\n1FA61;XIANGQI RED MANDARIN;So;0;ON;;;;;N;;;;;\n1FA62;XIANGQI RED ELEPHANT;So;0;ON;;;;;N;;;;;\n1FA63;XIANGQI RED HORSE;So;0;ON;;;;;N;;;;;\n1FA64;XIANGQI RED CHARIOT;So;0;ON;;;;;N;;;;;\n1FA65;XIANGQI RED CANNON;So;0;ON;;;;;N;;;;;\n1FA66;XIANGQI RED SOLDIER;So;0;ON;;;;;N;;;;;\n1FA67;XIANGQI BLACK GENERAL;So;0;ON;;;;;N;;;;;\n1FA68;XIANGQI BLACK MANDARIN;So;0;ON;;;;;N;;;;;\n1FA69;XIANGQI BLACK ELEPHANT;So;0;ON;;;;;N;;;;;\n1FA6A;XIANGQI BLACK HORSE;So;0;ON;;;;;N;;;;;\n1FA6B;XIANGQI BLACK CHARIOT;So;0;ON;;;;;N;;;;;\n1FA6C;XIANGQI BLACK CANNON;So;0;ON;;;;;N;;;;;\n1FA6D;XIANGQI BLACK SOLDIER;So;0;ON;;;;;N;;;;;\n1FA70;BALLET SHOES;So;0;ON;;;;;N;;;;;\n1FA71;ONE-PIECE SWIMSUIT;So;0;ON;;;;;N;;;;;\n1FA72;BRIEFS;So;0;ON;;;;;N;;;;;\n1FA73;SHORTS;So;0;ON;;;;;N;;;;;\n1FA78;DROP OF BLOOD;So;0;ON;;;;;N;;;;;\n1FA79;ADHESIVE BANDAGE;So;0;ON;;;;;N;;;;;\n1FA7A;STETHOSCOPE;So;0;ON;;;;;N;;;;;\n1FA80;YO-YO;So;0;ON;;;;;N;;;;;\n1FA81;KITE;So;0;ON;;;;;N;;;;;\n1FA82;PARACHUTE;So;0;ON;;;;;N;;;;;\n1FA90;RINGED PLANET;So;0;ON;;;;;N;;;;;\n1FA91;CHAIR;So;0;ON;;;;;N;;;;;\n1FA92;RAZOR;So;0;ON;;;;;N;;;;;\n1FA93;AXE;So;0;ON;;;;;N;;;;;\n1FA94;DIYA LAMP;So;0;ON;;;;;N;;;;;\n1FA95;BANJO;So;0;ON;;;;;N;;;;;\n20000;<CJK Ideograph Extension B, First>;Lo;0;L;;;;;N;;;;;\n2A6D6;<CJK Ideograph Extension B, Last>;Lo;0;L;;;;;N;;;;;\n2A700;<CJK Ideograph Extension C, First>;Lo;0;L;;;;;N;;;;;\n2B734;<CJK Ideograph Extension C, Last>;Lo;0;L;;;;;N;;;;;\n2B740;<CJK Ideograph Extension D, First>;Lo;0;L;;;;;N;;;;;\n2B81D;<CJK Ideograph Extension D, Last>;Lo;0;L;;;;;N;;;;;\n2B820;<CJK Ideograph Extension E, First>;Lo;0;L;;;;;N;;;;;\n2CEA1;<CJK Ideograph Extension E, Last>;Lo;0;L;;;;;N;;;;;\n2CEB0;<CJK Ideograph Extension F, First>;Lo;0;L;;;;;N;;;;;\n2EBE0;<CJK Ideograph Extension F, Last>;Lo;0;L;;;;;N;;;;;\n2F800;CJK COMPATIBILITY IDEOGRAPH-2F800;Lo;0;L;4E3D;;;;N;;;;;\n2F801;CJK COMPATIBILITY IDEOGRAPH-2F801;Lo;0;L;4E38;;;;N;;;;;\n2F802;CJK COMPATIBILITY IDEOGRAPH-2F802;Lo;0;L;4E41;;;;N;;;;;\n2F803;CJK COMPATIBILITY IDEOGRAPH-2F803;Lo;0;L;20122;;;;N;;;;;\n2F804;CJK COMPATIBILITY IDEOGRAPH-2F804;Lo;0;L;4F60;;;;N;;;;;\n2F805;CJK COMPATIBILITY IDEOGRAPH-2F805;Lo;0;L;4FAE;;;;N;;;;;\n2F806;CJK COMPATIBILITY IDEOGRAPH-2F806;Lo;0;L;4FBB;;;;N;;;;;\n2F807;CJK COMPATIBILITY IDEOGRAPH-2F807;Lo;0;L;5002;;;;N;;;;;\n2F808;CJK COMPATIBILITY IDEOGRAPH-2F808;Lo;0;L;507A;;;;N;;;;;\n2F809;CJK COMPATIBILITY IDEOGRAPH-2F809;Lo;0;L;5099;;;;N;;;;;\n2F80A;CJK COMPATIBILITY IDEOGRAPH-2F80A;Lo;0;L;50E7;;;;N;;;;;\n2F80B;CJK COMPATIBILITY IDEOGRAPH-2F80B;Lo;0;L;50CF;;;;N;;;;;\n2F80C;CJK COMPATIBILITY IDEOGRAPH-2F80C;Lo;0;L;349E;;;;N;;;;;\n2F80D;CJK COMPATIBILITY IDEOGRAPH-2F80D;Lo;0;L;2063A;;;;N;;;;;\n2F80E;CJK COMPATIBILITY IDEOGRAPH-2F80E;Lo;0;L;514D;;;;N;;;;;\n2F80F;CJK COMPATIBILITY IDEOGRAPH-2F80F;Lo;0;L;5154;;;;N;;;;;\n2F810;CJK COMPATIBILITY IDEOGRAPH-2F810;Lo;0;L;5164;;;;N;;;;;\n2F811;CJK COMPATIBILITY IDEOGRAPH-2F811;Lo;0;L;5177;;;;N;;;;;\n2F812;CJK COMPATIBILITY IDEOGRAPH-2F812;Lo;0;L;2051C;;;;N;;;;;\n2F813;CJK COMPATIBILITY IDEOGRAPH-2F813;Lo;0;L;34B9;;;;N;;;;;\n2F814;CJK COMPATIBILITY IDEOGRAPH-2F814;Lo;0;L;5167;;;;N;;;;;\n2F815;CJK COMPATIBILITY IDEOGRAPH-2F815;Lo;0;L;518D;;;;N;;;;;\n2F816;CJK COMPATIBILITY IDEOGRAPH-2F816;Lo;0;L;2054B;;;;N;;;;;\n2F817;CJK COMPATIBILITY IDEOGRAPH-2F817;Lo;0;L;5197;;;;N;;;;;\n2F818;CJK COMPATIBILITY IDEOGRAPH-2F818;Lo;0;L;51A4;;;;N;;;;;\n2F819;CJK COMPATIBILITY IDEOGRAPH-2F819;Lo;0;L;4ECC;;;;N;;;;;\n2F81A;CJK COMPATIBILITY IDEOGRAPH-2F81A;Lo;0;L;51AC;;;;N;;;;;\n2F81B;CJK COMPATIBILITY IDEOGRAPH-2F81B;Lo;0;L;51B5;;;;N;;;;;\n2F81C;CJK COMPATIBILITY IDEOGRAPH-2F81C;Lo;0;L;291DF;;;;N;;;;;\n2F81D;CJK COMPATIBILITY IDEOGRAPH-2F81D;Lo;0;L;51F5;;;;N;;;;;\n2F81E;CJK COMPATIBILITY IDEOGRAPH-2F81E;Lo;0;L;5203;;;;N;;;;;\n2F81F;CJK COMPATIBILITY IDEOGRAPH-2F81F;Lo;0;L;34DF;;;;N;;;;;\n2F820;CJK COMPATIBILITY IDEOGRAPH-2F820;Lo;0;L;523B;;;;N;;;;;\n2F821;CJK COMPATIBILITY IDEOGRAPH-2F821;Lo;0;L;5246;;;;N;;;;;\n2F822;CJK COMPATIBILITY IDEOGRAPH-2F822;Lo;0;L;5272;;;;N;;;;;\n2F823;CJK COMPATIBILITY IDEOGRAPH-2F823;Lo;0;L;5277;;;;N;;;;;\n2F824;CJK COMPATIBILITY IDEOGRAPH-2F824;Lo;0;L;3515;;;;N;;;;;\n2F825;CJK COMPATIBILITY IDEOGRAPH-2F825;Lo;0;L;52C7;;;;N;;;;;\n2F826;CJK COMPATIBILITY IDEOGRAPH-2F826;Lo;0;L;52C9;;;;N;;;;;\n2F827;CJK COMPATIBILITY IDEOGRAPH-2F827;Lo;0;L;52E4;;;;N;;;;;\n2F828;CJK COMPATIBILITY IDEOGRAPH-2F828;Lo;0;L;52FA;;;;N;;;;;\n2F829;CJK COMPATIBILITY IDEOGRAPH-2F829;Lo;0;L;5305;;;;N;;;;;\n2F82A;CJK COMPATIBILITY IDEOGRAPH-2F82A;Lo;0;L;5306;;;;N;;;;;\n2F82B;CJK COMPATIBILITY IDEOGRAPH-2F82B;Lo;0;L;5317;;;;N;;;;;\n2F82C;CJK COMPATIBILITY IDEOGRAPH-2F82C;Lo;0;L;5349;;;;N;;;;;\n2F82D;CJK COMPATIBILITY IDEOGRAPH-2F82D;Lo;0;L;5351;;;;N;;;;;\n2F82E;CJK COMPATIBILITY IDEOGRAPH-2F82E;Lo;0;L;535A;;;;N;;;;;\n2F82F;CJK COMPATIBILITY IDEOGRAPH-2F82F;Lo;0;L;5373;;;;N;;;;;\n2F830;CJK COMPATIBILITY IDEOGRAPH-2F830;Lo;0;L;537D;;;;N;;;;;\n2F831;CJK COMPATIBILITY IDEOGRAPH-2F831;Lo;0;L;537F;;;;N;;;;;\n2F832;CJK COMPATIBILITY IDEOGRAPH-2F832;Lo;0;L;537F;;;;N;;;;;\n2F833;CJK COMPATIBILITY IDEOGRAPH-2F833;Lo;0;L;537F;;;;N;;;;;\n2F834;CJK COMPATIBILITY IDEOGRAPH-2F834;Lo;0;L;20A2C;;;;N;;;;;\n2F835;CJK COMPATIBILITY IDEOGRAPH-2F835;Lo;0;L;7070;;;;N;;;;;\n2F836;CJK COMPATIBILITY IDEOGRAPH-2F836;Lo;0;L;53CA;;;;N;;;;;\n2F837;CJK COMPATIBILITY IDEOGRAPH-2F837;Lo;0;L;53DF;;;;N;;;;;\n2F838;CJK COMPATIBILITY IDEOGRAPH-2F838;Lo;0;L;20B63;;;;N;;;;;\n2F839;CJK COMPATIBILITY IDEOGRAPH-2F839;Lo;0;L;53EB;;;;N;;;;;\n2F83A;CJK COMPATIBILITY IDEOGRAPH-2F83A;Lo;0;L;53F1;;;;N;;;;;\n2F83B;CJK COMPATIBILITY IDEOGRAPH-2F83B;Lo;0;L;5406;;;;N;;;;;\n2F83C;CJK COMPATIBILITY IDEOGRAPH-2F83C;Lo;0;L;549E;;;;N;;;;;\n2F83D;CJK COMPATIBILITY IDEOGRAPH-2F83D;Lo;0;L;5438;;;;N;;;;;\n2F83E;CJK COMPATIBILITY IDEOGRAPH-2F83E;Lo;0;L;5448;;;;N;;;;;\n2F83F;CJK COMPATIBILITY IDEOGRAPH-2F83F;Lo;0;L;5468;;;;N;;;;;\n2F840;CJK COMPATIBILITY IDEOGRAPH-2F840;Lo;0;L;54A2;;;;N;;;;;\n2F841;CJK COMPATIBILITY IDEOGRAPH-2F841;Lo;0;L;54F6;;;;N;;;;;\n2F842;CJK COMPATIBILITY IDEOGRAPH-2F842;Lo;0;L;5510;;;;N;;;;;\n2F843;CJK COMPATIBILITY IDEOGRAPH-2F843;Lo;0;L;5553;;;;N;;;;;\n2F844;CJK COMPATIBILITY IDEOGRAPH-2F844;Lo;0;L;5563;;;;N;;;;;\n2F845;CJK COMPATIBILITY IDEOGRAPH-2F845;Lo;0;L;5584;;;;N;;;;;\n2F846;CJK COMPATIBILITY IDEOGRAPH-2F846;Lo;0;L;5584;;;;N;;;;;\n2F847;CJK COMPATIBILITY IDEOGRAPH-2F847;Lo;0;L;5599;;;;N;;;;;\n2F848;CJK COMPATIBILITY IDEOGRAPH-2F848;Lo;0;L;55AB;;;;N;;;;;\n2F849;CJK COMPATIBILITY IDEOGRAPH-2F849;Lo;0;L;55B3;;;;N;;;;;\n2F84A;CJK COMPATIBILITY IDEOGRAPH-2F84A;Lo;0;L;55C2;;;;N;;;;;\n2F84B;CJK COMPATIBILITY IDEOGRAPH-2F84B;Lo;0;L;5716;;;;N;;;;;\n2F84C;CJK COMPATIBILITY IDEOGRAPH-2F84C;Lo;0;L;5606;;;;N;;;;;\n2F84D;CJK COMPATIBILITY IDEOGRAPH-2F84D;Lo;0;L;5717;;;;N;;;;;\n2F84E;CJK COMPATIBILITY IDEOGRAPH-2F84E;Lo;0;L;5651;;;;N;;;;;\n2F84F;CJK COMPATIBILITY IDEOGRAPH-2F84F;Lo;0;L;5674;;;;N;;;;;\n2F850;CJK COMPATIBILITY IDEOGRAPH-2F850;Lo;0;L;5207;;;;N;;;;;\n2F851;CJK COMPATIBILITY IDEOGRAPH-2F851;Lo;0;L;58EE;;;;N;;;;;\n2F852;CJK COMPATIBILITY IDEOGRAPH-2F852;Lo;0;L;57CE;;;;N;;;;;\n2F853;CJK COMPATIBILITY IDEOGRAPH-2F853;Lo;0;L;57F4;;;;N;;;;;\n2F854;CJK COMPATIBILITY IDEOGRAPH-2F854;Lo;0;L;580D;;;;N;;;;;\n2F855;CJK COMPATIBILITY IDEOGRAPH-2F855;Lo;0;L;578B;;;;N;;;;;\n2F856;CJK COMPATIBILITY IDEOGRAPH-2F856;Lo;0;L;5832;;;;N;;;;;\n2F857;CJK COMPATIBILITY IDEOGRAPH-2F857;Lo;0;L;5831;;;;N;;;;;\n2F858;CJK COMPATIBILITY IDEOGRAPH-2F858;Lo;0;L;58AC;;;;N;;;;;\n2F859;CJK COMPATIBILITY IDEOGRAPH-2F859;Lo;0;L;214E4;;;;N;;;;;\n2F85A;CJK COMPATIBILITY IDEOGRAPH-2F85A;Lo;0;L;58F2;;;;N;;;;;\n2F85B;CJK COMPATIBILITY IDEOGRAPH-2F85B;Lo;0;L;58F7;;;;N;;;;;\n2F85C;CJK COMPATIBILITY IDEOGRAPH-2F85C;Lo;0;L;5906;;;;N;;;;;\n2F85D;CJK COMPATIBILITY IDEOGRAPH-2F85D;Lo;0;L;591A;;;;N;;;;;\n2F85E;CJK COMPATIBILITY IDEOGRAPH-2F85E;Lo;0;L;5922;;;;N;;;;;\n2F85F;CJK COMPATIBILITY IDEOGRAPH-2F85F;Lo;0;L;5962;;;;N;;;;;\n2F860;CJK COMPATIBILITY IDEOGRAPH-2F860;Lo;0;L;216A8;;;;N;;;;;\n2F861;CJK COMPATIBILITY IDEOGRAPH-2F861;Lo;0;L;216EA;;;;N;;;;;\n2F862;CJK COMPATIBILITY IDEOGRAPH-2F862;Lo;0;L;59EC;;;;N;;;;;\n2F863;CJK COMPATIBILITY IDEOGRAPH-2F863;Lo;0;L;5A1B;;;;N;;;;;\n2F864;CJK COMPATIBILITY IDEOGRAPH-2F864;Lo;0;L;5A27;;;;N;;;;;\n2F865;CJK COMPATIBILITY IDEOGRAPH-2F865;Lo;0;L;59D8;;;;N;;;;;\n2F866;CJK COMPATIBILITY IDEOGRAPH-2F866;Lo;0;L;5A66;;;;N;;;;;\n2F867;CJK COMPATIBILITY IDEOGRAPH-2F867;Lo;0;L;36EE;;;;N;;;;;\n2F868;CJK COMPATIBILITY IDEOGRAPH-2F868;Lo;0;L;36FC;;;;N;;;;;\n2F869;CJK COMPATIBILITY IDEOGRAPH-2F869;Lo;0;L;5B08;;;;N;;;;;\n2F86A;CJK COMPATIBILITY IDEOGRAPH-2F86A;Lo;0;L;5B3E;;;;N;;;;;\n2F86B;CJK COMPATIBILITY IDEOGRAPH-2F86B;Lo;0;L;5B3E;;;;N;;;;;\n2F86C;CJK COMPATIBILITY IDEOGRAPH-2F86C;Lo;0;L;219C8;;;;N;;;;;\n2F86D;CJK COMPATIBILITY IDEOGRAPH-2F86D;Lo;0;L;5BC3;;;;N;;;;;\n2F86E;CJK COMPATIBILITY IDEOGRAPH-2F86E;Lo;0;L;5BD8;;;;N;;;;;\n2F86F;CJK COMPATIBILITY IDEOGRAPH-2F86F;Lo;0;L;5BE7;;;;N;;;;;\n2F870;CJK COMPATIBILITY IDEOGRAPH-2F870;Lo;0;L;5BF3;;;;N;;;;;\n2F871;CJK COMPATIBILITY IDEOGRAPH-2F871;Lo;0;L;21B18;;;;N;;;;;\n2F872;CJK COMPATIBILITY IDEOGRAPH-2F872;Lo;0;L;5BFF;;;;N;;;;;\n2F873;CJK COMPATIBILITY IDEOGRAPH-2F873;Lo;0;L;5C06;;;;N;;;;;\n2F874;CJK COMPATIBILITY IDEOGRAPH-2F874;Lo;0;L;5F53;;;;N;;;;;\n2F875;CJK COMPATIBILITY IDEOGRAPH-2F875;Lo;0;L;5C22;;;;N;;;;;\n2F876;CJK COMPATIBILITY IDEOGRAPH-2F876;Lo;0;L;3781;;;;N;;;;;\n2F877;CJK COMPATIBILITY IDEOGRAPH-2F877;Lo;0;L;5C60;;;;N;;;;;\n2F878;CJK COMPATIBILITY IDEOGRAPH-2F878;Lo;0;L;5C6E;;;;N;;;;;\n2F879;CJK COMPATIBILITY IDEOGRAPH-2F879;Lo;0;L;5CC0;;;;N;;;;;\n2F87A;CJK COMPATIBILITY IDEOGRAPH-2F87A;Lo;0;L;5C8D;;;;N;;;;;\n2F87B;CJK COMPATIBILITY IDEOGRAPH-2F87B;Lo;0;L;21DE4;;;;N;;;;;\n2F87C;CJK COMPATIBILITY IDEOGRAPH-2F87C;Lo;0;L;5D43;;;;N;;;;;\n2F87D;CJK COMPATIBILITY IDEOGRAPH-2F87D;Lo;0;L;21DE6;;;;N;;;;;\n2F87E;CJK COMPATIBILITY IDEOGRAPH-2F87E;Lo;0;L;5D6E;;;;N;;;;;\n2F87F;CJK COMPATIBILITY IDEOGRAPH-2F87F;Lo;0;L;5D6B;;;;N;;;;;\n2F880;CJK COMPATIBILITY IDEOGRAPH-2F880;Lo;0;L;5D7C;;;;N;;;;;\n2F881;CJK COMPATIBILITY IDEOGRAPH-2F881;Lo;0;L;5DE1;;;;N;;;;;\n2F882;CJK COMPATIBILITY IDEOGRAPH-2F882;Lo;0;L;5DE2;;;;N;;;;;\n2F883;CJK COMPATIBILITY IDEOGRAPH-2F883;Lo;0;L;382F;;;;N;;;;;\n2F884;CJK COMPATIBILITY IDEOGRAPH-2F884;Lo;0;L;5DFD;;;;N;;;;;\n2F885;CJK COMPATIBILITY IDEOGRAPH-2F885;Lo;0;L;5E28;;;;N;;;;;\n2F886;CJK COMPATIBILITY IDEOGRAPH-2F886;Lo;0;L;5E3D;;;;N;;;;;\n2F887;CJK COMPATIBILITY IDEOGRAPH-2F887;Lo;0;L;5E69;;;;N;;;;;\n2F888;CJK COMPATIBILITY IDEOGRAPH-2F888;Lo;0;L;3862;;;;N;;;;;\n2F889;CJK COMPATIBILITY IDEOGRAPH-2F889;Lo;0;L;22183;;;;N;;;;;\n2F88A;CJK COMPATIBILITY IDEOGRAPH-2F88A;Lo;0;L;387C;;;;N;;;;;\n2F88B;CJK COMPATIBILITY IDEOGRAPH-2F88B;Lo;0;L;5EB0;;;;N;;;;;\n2F88C;CJK COMPATIBILITY IDEOGRAPH-2F88C;Lo;0;L;5EB3;;;;N;;;;;\n2F88D;CJK COMPATIBILITY IDEOGRAPH-2F88D;Lo;0;L;5EB6;;;;N;;;;;\n2F88E;CJK COMPATIBILITY IDEOGRAPH-2F88E;Lo;0;L;5ECA;;;;N;;;;;\n2F88F;CJK COMPATIBILITY IDEOGRAPH-2F88F;Lo;0;L;2A392;;;;N;;;;;\n2F890;CJK COMPATIBILITY IDEOGRAPH-2F890;Lo;0;L;5EFE;;;9;N;;;;;\n2F891;CJK COMPATIBILITY IDEOGRAPH-2F891;Lo;0;L;22331;;;;N;;;;;\n2F892;CJK COMPATIBILITY IDEOGRAPH-2F892;Lo;0;L;22331;;;;N;;;;;\n2F893;CJK COMPATIBILITY IDEOGRAPH-2F893;Lo;0;L;8201;;;;N;;;;;\n2F894;CJK COMPATIBILITY IDEOGRAPH-2F894;Lo;0;L;5F22;;;;N;;;;;\n2F895;CJK COMPATIBILITY IDEOGRAPH-2F895;Lo;0;L;5F22;;;;N;;;;;\n2F896;CJK COMPATIBILITY IDEOGRAPH-2F896;Lo;0;L;38C7;;;;N;;;;;\n2F897;CJK COMPATIBILITY IDEOGRAPH-2F897;Lo;0;L;232B8;;;;N;;;;;\n2F898;CJK COMPATIBILITY IDEOGRAPH-2F898;Lo;0;L;261DA;;;;N;;;;;\n2F899;CJK COMPATIBILITY IDEOGRAPH-2F899;Lo;0;L;5F62;;;;N;;;;;\n2F89A;CJK COMPATIBILITY IDEOGRAPH-2F89A;Lo;0;L;5F6B;;;;N;;;;;\n2F89B;CJK COMPATIBILITY IDEOGRAPH-2F89B;Lo;0;L;38E3;;;;N;;;;;\n2F89C;CJK COMPATIBILITY IDEOGRAPH-2F89C;Lo;0;L;5F9A;;;;N;;;;;\n2F89D;CJK COMPATIBILITY IDEOGRAPH-2F89D;Lo;0;L;5FCD;;;;N;;;;;\n2F89E;CJK COMPATIBILITY IDEOGRAPH-2F89E;Lo;0;L;5FD7;;;;N;;;;;\n2F89F;CJK COMPATIBILITY IDEOGRAPH-2F89F;Lo;0;L;5FF9;;;;N;;;;;\n2F8A0;CJK COMPATIBILITY IDEOGRAPH-2F8A0;Lo;0;L;6081;;;;N;;;;;\n2F8A1;CJK COMPATIBILITY IDEOGRAPH-2F8A1;Lo;0;L;393A;;;;N;;;;;\n2F8A2;CJK COMPATIBILITY IDEOGRAPH-2F8A2;Lo;0;L;391C;;;;N;;;;;\n2F8A3;CJK COMPATIBILITY IDEOGRAPH-2F8A3;Lo;0;L;6094;;;;N;;;;;\n2F8A4;CJK COMPATIBILITY IDEOGRAPH-2F8A4;Lo;0;L;226D4;;;;N;;;;;\n2F8A5;CJK COMPATIBILITY IDEOGRAPH-2F8A5;Lo;0;L;60C7;;;;N;;;;;\n2F8A6;CJK COMPATIBILITY IDEOGRAPH-2F8A6;Lo;0;L;6148;;;;N;;;;;\n2F8A7;CJK COMPATIBILITY IDEOGRAPH-2F8A7;Lo;0;L;614C;;;;N;;;;;\n2F8A8;CJK COMPATIBILITY IDEOGRAPH-2F8A8;Lo;0;L;614E;;;;N;;;;;\n2F8A9;CJK COMPATIBILITY IDEOGRAPH-2F8A9;Lo;0;L;614C;;;;N;;;;;\n2F8AA;CJK COMPATIBILITY IDEOGRAPH-2F8AA;Lo;0;L;617A;;;;N;;;;;\n2F8AB;CJK COMPATIBILITY IDEOGRAPH-2F8AB;Lo;0;L;618E;;;;N;;;;;\n2F8AC;CJK COMPATIBILITY IDEOGRAPH-2F8AC;Lo;0;L;61B2;;;;N;;;;;\n2F8AD;CJK COMPATIBILITY IDEOGRAPH-2F8AD;Lo;0;L;61A4;;;;N;;;;;\n2F8AE;CJK COMPATIBILITY IDEOGRAPH-2F8AE;Lo;0;L;61AF;;;;N;;;;;\n2F8AF;CJK COMPATIBILITY IDEOGRAPH-2F8AF;Lo;0;L;61DE;;;;N;;;;;\n2F8B0;CJK COMPATIBILITY IDEOGRAPH-2F8B0;Lo;0;L;61F2;;;;N;;;;;\n2F8B1;CJK COMPATIBILITY IDEOGRAPH-2F8B1;Lo;0;L;61F6;;;;N;;;;;\n2F8B2;CJK COMPATIBILITY IDEOGRAPH-2F8B2;Lo;0;L;6210;;;;N;;;;;\n2F8B3;CJK COMPATIBILITY IDEOGRAPH-2F8B3;Lo;0;L;621B;;;;N;;;;;\n2F8B4;CJK COMPATIBILITY IDEOGRAPH-2F8B4;Lo;0;L;625D;;;;N;;;;;\n2F8B5;CJK COMPATIBILITY IDEOGRAPH-2F8B5;Lo;0;L;62B1;;;;N;;;;;\n2F8B6;CJK COMPATIBILITY IDEOGRAPH-2F8B6;Lo;0;L;62D4;;;;N;;;;;\n2F8B7;CJK COMPATIBILITY IDEOGRAPH-2F8B7;Lo;0;L;6350;;;;N;;;;;\n2F8B8;CJK COMPATIBILITY IDEOGRAPH-2F8B8;Lo;0;L;22B0C;;;;N;;;;;\n2F8B9;CJK COMPATIBILITY IDEOGRAPH-2F8B9;Lo;0;L;633D;;;;N;;;;;\n2F8BA;CJK COMPATIBILITY IDEOGRAPH-2F8BA;Lo;0;L;62FC;;;;N;;;;;\n2F8BB;CJK COMPATIBILITY IDEOGRAPH-2F8BB;Lo;0;L;6368;;;;N;;;;;\n2F8BC;CJK COMPATIBILITY IDEOGRAPH-2F8BC;Lo;0;L;6383;;;;N;;;;;\n2F8BD;CJK COMPATIBILITY IDEOGRAPH-2F8BD;Lo;0;L;63E4;;;;N;;;;;\n2F8BE;CJK COMPATIBILITY IDEOGRAPH-2F8BE;Lo;0;L;22BF1;;;;N;;;;;\n2F8BF;CJK COMPATIBILITY IDEOGRAPH-2F8BF;Lo;0;L;6422;;;;N;;;;;\n2F8C0;CJK COMPATIBILITY IDEOGRAPH-2F8C0;Lo;0;L;63C5;;;;N;;;;;\n2F8C1;CJK COMPATIBILITY IDEOGRAPH-2F8C1;Lo;0;L;63A9;;;;N;;;;;\n2F8C2;CJK COMPATIBILITY IDEOGRAPH-2F8C2;Lo;0;L;3A2E;;;;N;;;;;\n2F8C3;CJK COMPATIBILITY IDEOGRAPH-2F8C3;Lo;0;L;6469;;;;N;;;;;\n2F8C4;CJK COMPATIBILITY IDEOGRAPH-2F8C4;Lo;0;L;647E;;;;N;;;;;\n2F8C5;CJK COMPATIBILITY IDEOGRAPH-2F8C5;Lo;0;L;649D;;;;N;;;;;\n2F8C6;CJK COMPATIBILITY IDEOGRAPH-2F8C6;Lo;0;L;6477;;;;N;;;;;\n2F8C7;CJK COMPATIBILITY IDEOGRAPH-2F8C7;Lo;0;L;3A6C;;;;N;;;;;\n2F8C8;CJK COMPATIBILITY IDEOGRAPH-2F8C8;Lo;0;L;654F;;;;N;;;;;\n2F8C9;CJK COMPATIBILITY IDEOGRAPH-2F8C9;Lo;0;L;656C;;;;N;;;;;\n2F8CA;CJK COMPATIBILITY IDEOGRAPH-2F8CA;Lo;0;L;2300A;;;;N;;;;;\n2F8CB;CJK COMPATIBILITY IDEOGRAPH-2F8CB;Lo;0;L;65E3;;;;N;;;;;\n2F8CC;CJK COMPATIBILITY IDEOGRAPH-2F8CC;Lo;0;L;66F8;;;;N;;;;;\n2F8CD;CJK COMPATIBILITY IDEOGRAPH-2F8CD;Lo;0;L;6649;;;;N;;;;;\n2F8CE;CJK COMPATIBILITY IDEOGRAPH-2F8CE;Lo;0;L;3B19;;;;N;;;;;\n2F8CF;CJK COMPATIBILITY IDEOGRAPH-2F8CF;Lo;0;L;6691;;;;N;;;;;\n2F8D0;CJK COMPATIBILITY IDEOGRAPH-2F8D0;Lo;0;L;3B08;;;;N;;;;;\n2F8D1;CJK COMPATIBILITY IDEOGRAPH-2F8D1;Lo;0;L;3AE4;;;;N;;;;;\n2F8D2;CJK COMPATIBILITY IDEOGRAPH-2F8D2;Lo;0;L;5192;;;;N;;;;;\n2F8D3;CJK COMPATIBILITY IDEOGRAPH-2F8D3;Lo;0;L;5195;;;;N;;;;;\n2F8D4;CJK COMPATIBILITY IDEOGRAPH-2F8D4;Lo;0;L;6700;;;;N;;;;;\n2F8D5;CJK COMPATIBILITY IDEOGRAPH-2F8D5;Lo;0;L;669C;;;;N;;;;;\n2F8D6;CJK COMPATIBILITY IDEOGRAPH-2F8D6;Lo;0;L;80AD;;;;N;;;;;\n2F8D7;CJK COMPATIBILITY IDEOGRAPH-2F8D7;Lo;0;L;43D9;;;;N;;;;;\n2F8D8;CJK COMPATIBILITY IDEOGRAPH-2F8D8;Lo;0;L;6717;;;;N;;;;;\n2F8D9;CJK COMPATIBILITY IDEOGRAPH-2F8D9;Lo;0;L;671B;;;;N;;;;;\n2F8DA;CJK COMPATIBILITY IDEOGRAPH-2F8DA;Lo;0;L;6721;;;;N;;;;;\n2F8DB;CJK COMPATIBILITY IDEOGRAPH-2F8DB;Lo;0;L;675E;;;;N;;;;;\n2F8DC;CJK COMPATIBILITY IDEOGRAPH-2F8DC;Lo;0;L;6753;;;;N;;;;;\n2F8DD;CJK COMPATIBILITY IDEOGRAPH-2F8DD;Lo;0;L;233C3;;;;N;;;;;\n2F8DE;CJK COMPATIBILITY IDEOGRAPH-2F8DE;Lo;0;L;3B49;;;;N;;;;;\n2F8DF;CJK COMPATIBILITY IDEOGRAPH-2F8DF;Lo;0;L;67FA;;;;N;;;;;\n2F8E0;CJK COMPATIBILITY IDEOGRAPH-2F8E0;Lo;0;L;6785;;;;N;;;;;\n2F8E1;CJK COMPATIBILITY IDEOGRAPH-2F8E1;Lo;0;L;6852;;;;N;;;;;\n2F8E2;CJK COMPATIBILITY IDEOGRAPH-2F8E2;Lo;0;L;6885;;;;N;;;;;\n2F8E3;CJK COMPATIBILITY IDEOGRAPH-2F8E3;Lo;0;L;2346D;;;;N;;;;;\n2F8E4;CJK COMPATIBILITY IDEOGRAPH-2F8E4;Lo;0;L;688E;;;;N;;;;;\n2F8E5;CJK COMPATIBILITY IDEOGRAPH-2F8E5;Lo;0;L;681F;;;;N;;;;;\n2F8E6;CJK COMPATIBILITY IDEOGRAPH-2F8E6;Lo;0;L;6914;;;;N;;;;;\n2F8E7;CJK COMPATIBILITY IDEOGRAPH-2F8E7;Lo;0;L;3B9D;;;;N;;;;;\n2F8E8;CJK COMPATIBILITY IDEOGRAPH-2F8E8;Lo;0;L;6942;;;;N;;;;;\n2F8E9;CJK COMPATIBILITY IDEOGRAPH-2F8E9;Lo;0;L;69A3;;;;N;;;;;\n2F8EA;CJK COMPATIBILITY IDEOGRAPH-2F8EA;Lo;0;L;69EA;;;;N;;;;;\n2F8EB;CJK COMPATIBILITY IDEOGRAPH-2F8EB;Lo;0;L;6AA8;;;;N;;;;;\n2F8EC;CJK COMPATIBILITY IDEOGRAPH-2F8EC;Lo;0;L;236A3;;;;N;;;;;\n2F8ED;CJK COMPATIBILITY IDEOGRAPH-2F8ED;Lo;0;L;6ADB;;;;N;;;;;\n2F8EE;CJK COMPATIBILITY IDEOGRAPH-2F8EE;Lo;0;L;3C18;;;;N;;;;;\n2F8EF;CJK COMPATIBILITY IDEOGRAPH-2F8EF;Lo;0;L;6B21;;;;N;;;;;\n2F8F0;CJK COMPATIBILITY IDEOGRAPH-2F8F0;Lo;0;L;238A7;;;;N;;;;;\n2F8F1;CJK COMPATIBILITY IDEOGRAPH-2F8F1;Lo;0;L;6B54;;;;N;;;;;\n2F8F2;CJK COMPATIBILITY IDEOGRAPH-2F8F2;Lo;0;L;3C4E;;;;N;;;;;\n2F8F3;CJK COMPATIBILITY IDEOGRAPH-2F8F3;Lo;0;L;6B72;;;;N;;;;;\n2F8F4;CJK COMPATIBILITY IDEOGRAPH-2F8F4;Lo;0;L;6B9F;;;;N;;;;;\n2F8F5;CJK COMPATIBILITY IDEOGRAPH-2F8F5;Lo;0;L;6BBA;;;;N;;;;;\n2F8F6;CJK COMPATIBILITY IDEOGRAPH-2F8F6;Lo;0;L;6BBB;;;;N;;;;;\n2F8F7;CJK COMPATIBILITY IDEOGRAPH-2F8F7;Lo;0;L;23A8D;;;;N;;;;;\n2F8F8;CJK COMPATIBILITY IDEOGRAPH-2F8F8;Lo;0;L;21D0B;;;;N;;;;;\n2F8F9;CJK COMPATIBILITY IDEOGRAPH-2F8F9;Lo;0;L;23AFA;;;;N;;;;;\n2F8FA;CJK COMPATIBILITY IDEOGRAPH-2F8FA;Lo;0;L;6C4E;;;;N;;;;;\n2F8FB;CJK COMPATIBILITY IDEOGRAPH-2F8FB;Lo;0;L;23CBC;;;;N;;;;;\n2F8FC;CJK COMPATIBILITY IDEOGRAPH-2F8FC;Lo;0;L;6CBF;;;;N;;;;;\n2F8FD;CJK COMPATIBILITY IDEOGRAPH-2F8FD;Lo;0;L;6CCD;;;;N;;;;;\n2F8FE;CJK COMPATIBILITY IDEOGRAPH-2F8FE;Lo;0;L;6C67;;;;N;;;;;\n2F8FF;CJK COMPATIBILITY IDEOGRAPH-2F8FF;Lo;0;L;6D16;;;;N;;;;;\n2F900;CJK COMPATIBILITY IDEOGRAPH-2F900;Lo;0;L;6D3E;;;;N;;;;;\n2F901;CJK COMPATIBILITY IDEOGRAPH-2F901;Lo;0;L;6D77;;;;N;;;;;\n2F902;CJK COMPATIBILITY IDEOGRAPH-2F902;Lo;0;L;6D41;;;;N;;;;;\n2F903;CJK COMPATIBILITY IDEOGRAPH-2F903;Lo;0;L;6D69;;;;N;;;;;\n2F904;CJK COMPATIBILITY IDEOGRAPH-2F904;Lo;0;L;6D78;;;;N;;;;;\n2F905;CJK COMPATIBILITY IDEOGRAPH-2F905;Lo;0;L;6D85;;;;N;;;;;\n2F906;CJK COMPATIBILITY IDEOGRAPH-2F906;Lo;0;L;23D1E;;;;N;;;;;\n2F907;CJK COMPATIBILITY IDEOGRAPH-2F907;Lo;0;L;6D34;;;;N;;;;;\n2F908;CJK COMPATIBILITY IDEOGRAPH-2F908;Lo;0;L;6E2F;;;;N;;;;;\n2F909;CJK COMPATIBILITY IDEOGRAPH-2F909;Lo;0;L;6E6E;;;;N;;;;;\n2F90A;CJK COMPATIBILITY IDEOGRAPH-2F90A;Lo;0;L;3D33;;;;N;;;;;\n2F90B;CJK COMPATIBILITY IDEOGRAPH-2F90B;Lo;0;L;6ECB;;;;N;;;;;\n2F90C;CJK COMPATIBILITY IDEOGRAPH-2F90C;Lo;0;L;6EC7;;;;N;;;;;\n2F90D;CJK COMPATIBILITY IDEOGRAPH-2F90D;Lo;0;L;23ED1;;;;N;;;;;\n2F90E;CJK COMPATIBILITY IDEOGRAPH-2F90E;Lo;0;L;6DF9;;;;N;;;;;\n2F90F;CJK COMPATIBILITY IDEOGRAPH-2F90F;Lo;0;L;6F6E;;;;N;;;;;\n2F910;CJK COMPATIBILITY IDEOGRAPH-2F910;Lo;0;L;23F5E;;;;N;;;;;\n2F911;CJK COMPATIBILITY IDEOGRAPH-2F911;Lo;0;L;23F8E;;;;N;;;;;\n2F912;CJK COMPATIBILITY IDEOGRAPH-2F912;Lo;0;L;6FC6;;;;N;;;;;\n2F913;CJK COMPATIBILITY IDEOGRAPH-2F913;Lo;0;L;7039;;;;N;;;;;\n2F914;CJK COMPATIBILITY IDEOGRAPH-2F914;Lo;0;L;701E;;;;N;;;;;\n2F915;CJK COMPATIBILITY IDEOGRAPH-2F915;Lo;0;L;701B;;;;N;;;;;\n2F916;CJK COMPATIBILITY IDEOGRAPH-2F916;Lo;0;L;3D96;;;;N;;;;;\n2F917;CJK COMPATIBILITY IDEOGRAPH-2F917;Lo;0;L;704A;;;;N;;;;;\n2F918;CJK COMPATIBILITY IDEOGRAPH-2F918;Lo;0;L;707D;;;;N;;;;;\n2F919;CJK COMPATIBILITY IDEOGRAPH-2F919;Lo;0;L;7077;;;;N;;;;;\n2F91A;CJK COMPATIBILITY IDEOGRAPH-2F91A;Lo;0;L;70AD;;;;N;;;;;\n2F91B;CJK COMPATIBILITY IDEOGRAPH-2F91B;Lo;0;L;20525;;;;N;;;;;\n2F91C;CJK COMPATIBILITY IDEOGRAPH-2F91C;Lo;0;L;7145;;;;N;;;;;\n2F91D;CJK COMPATIBILITY IDEOGRAPH-2F91D;Lo;0;L;24263;;;;N;;;;;\n2F91E;CJK COMPATIBILITY IDEOGRAPH-2F91E;Lo;0;L;719C;;;;N;;;;;\n2F91F;CJK COMPATIBILITY IDEOGRAPH-2F91F;Lo;0;L;243AB;;;;N;;;;;\n2F920;CJK COMPATIBILITY IDEOGRAPH-2F920;Lo;0;L;7228;;;;N;;;;;\n2F921;CJK COMPATIBILITY IDEOGRAPH-2F921;Lo;0;L;7235;;;;N;;;;;\n2F922;CJK COMPATIBILITY IDEOGRAPH-2F922;Lo;0;L;7250;;;;N;;;;;\n2F923;CJK COMPATIBILITY IDEOGRAPH-2F923;Lo;0;L;24608;;;;N;;;;;\n2F924;CJK COMPATIBILITY IDEOGRAPH-2F924;Lo;0;L;7280;;;;N;;;;;\n2F925;CJK COMPATIBILITY IDEOGRAPH-2F925;Lo;0;L;7295;;;;N;;;;;\n2F926;CJK COMPATIBILITY IDEOGRAPH-2F926;Lo;0;L;24735;;;;N;;;;;\n2F927;CJK COMPATIBILITY IDEOGRAPH-2F927;Lo;0;L;24814;;;;N;;;;;\n2F928;CJK COMPATIBILITY IDEOGRAPH-2F928;Lo;0;L;737A;;;;N;;;;;\n2F929;CJK COMPATIBILITY IDEOGRAPH-2F929;Lo;0;L;738B;;;;N;;;;;\n2F92A;CJK COMPATIBILITY IDEOGRAPH-2F92A;Lo;0;L;3EAC;;;;N;;;;;\n2F92B;CJK COMPATIBILITY IDEOGRAPH-2F92B;Lo;0;L;73A5;;;;N;;;;;\n2F92C;CJK COMPATIBILITY IDEOGRAPH-2F92C;Lo;0;L;3EB8;;;;N;;;;;\n2F92D;CJK COMPATIBILITY IDEOGRAPH-2F92D;Lo;0;L;3EB8;;;;N;;;;;\n2F92E;CJK COMPATIBILITY IDEOGRAPH-2F92E;Lo;0;L;7447;;;;N;;;;;\n2F92F;CJK COMPATIBILITY IDEOGRAPH-2F92F;Lo;0;L;745C;;;;N;;;;;\n2F930;CJK COMPATIBILITY IDEOGRAPH-2F930;Lo;0;L;7471;;;;N;;;;;\n2F931;CJK COMPATIBILITY IDEOGRAPH-2F931;Lo;0;L;7485;;;;N;;;;;\n2F932;CJK COMPATIBILITY IDEOGRAPH-2F932;Lo;0;L;74CA;;;;N;;;;;\n2F933;CJK COMPATIBILITY IDEOGRAPH-2F933;Lo;0;L;3F1B;;;;N;;;;;\n2F934;CJK COMPATIBILITY IDEOGRAPH-2F934;Lo;0;L;7524;;;;N;;;;;\n2F935;CJK COMPATIBILITY IDEOGRAPH-2F935;Lo;0;L;24C36;;;;N;;;;;\n2F936;CJK COMPATIBILITY IDEOGRAPH-2F936;Lo;0;L;753E;;;;N;;;;;\n2F937;CJK COMPATIBILITY IDEOGRAPH-2F937;Lo;0;L;24C92;;;;N;;;;;\n2F938;CJK COMPATIBILITY IDEOGRAPH-2F938;Lo;0;L;7570;;;;N;;;;;\n2F939;CJK COMPATIBILITY IDEOGRAPH-2F939;Lo;0;L;2219F;;;;N;;;;;\n2F93A;CJK COMPATIBILITY IDEOGRAPH-2F93A;Lo;0;L;7610;;;;N;;;;;\n2F93B;CJK COMPATIBILITY IDEOGRAPH-2F93B;Lo;0;L;24FA1;;;;N;;;;;\n2F93C;CJK COMPATIBILITY IDEOGRAPH-2F93C;Lo;0;L;24FB8;;;;N;;;;;\n2F93D;CJK COMPATIBILITY IDEOGRAPH-2F93D;Lo;0;L;25044;;;;N;;;;;\n2F93E;CJK COMPATIBILITY IDEOGRAPH-2F93E;Lo;0;L;3FFC;;;;N;;;;;\n2F93F;CJK COMPATIBILITY IDEOGRAPH-2F93F;Lo;0;L;4008;;;;N;;;;;\n2F940;CJK COMPATIBILITY IDEOGRAPH-2F940;Lo;0;L;76F4;;;;N;;;;;\n2F941;CJK COMPATIBILITY IDEOGRAPH-2F941;Lo;0;L;250F3;;;;N;;;;;\n2F942;CJK COMPATIBILITY IDEOGRAPH-2F942;Lo;0;L;250F2;;;;N;;;;;\n2F943;CJK COMPATIBILITY IDEOGRAPH-2F943;Lo;0;L;25119;;;;N;;;;;\n2F944;CJK COMPATIBILITY IDEOGRAPH-2F944;Lo;0;L;25133;;;;N;;;;;\n2F945;CJK COMPATIBILITY IDEOGRAPH-2F945;Lo;0;L;771E;;;;N;;;;;\n2F946;CJK COMPATIBILITY IDEOGRAPH-2F946;Lo;0;L;771F;;;;N;;;;;\n2F947;CJK COMPATIBILITY IDEOGRAPH-2F947;Lo;0;L;771F;;;;N;;;;;\n2F948;CJK COMPATIBILITY IDEOGRAPH-2F948;Lo;0;L;774A;;;;N;;;;;\n2F949;CJK COMPATIBILITY IDEOGRAPH-2F949;Lo;0;L;4039;;;;N;;;;;\n2F94A;CJK COMPATIBILITY IDEOGRAPH-2F94A;Lo;0;L;778B;;;;N;;;;;\n2F94B;CJK COMPATIBILITY IDEOGRAPH-2F94B;Lo;0;L;4046;;;;N;;;;;\n2F94C;CJK COMPATIBILITY IDEOGRAPH-2F94C;Lo;0;L;4096;;;;N;;;;;\n2F94D;CJK COMPATIBILITY IDEOGRAPH-2F94D;Lo;0;L;2541D;;;;N;;;;;\n2F94E;CJK COMPATIBILITY IDEOGRAPH-2F94E;Lo;0;L;784E;;;;N;;;;;\n2F94F;CJK COMPATIBILITY IDEOGRAPH-2F94F;Lo;0;L;788C;;;;N;;;;;\n2F950;CJK COMPATIBILITY IDEOGRAPH-2F950;Lo;0;L;78CC;;;;N;;;;;\n2F951;CJK COMPATIBILITY IDEOGRAPH-2F951;Lo;0;L;40E3;;;;N;;;;;\n2F952;CJK COMPATIBILITY IDEOGRAPH-2F952;Lo;0;L;25626;;;;N;;;;;\n2F953;CJK COMPATIBILITY IDEOGRAPH-2F953;Lo;0;L;7956;;;;N;;;;;\n2F954;CJK COMPATIBILITY IDEOGRAPH-2F954;Lo;0;L;2569A;;;;N;;;;;\n2F955;CJK COMPATIBILITY IDEOGRAPH-2F955;Lo;0;L;256C5;;;;N;;;;;\n2F956;CJK COMPATIBILITY IDEOGRAPH-2F956;Lo;0;L;798F;;;;N;;;;;\n2F957;CJK COMPATIBILITY IDEOGRAPH-2F957;Lo;0;L;79EB;;;;N;;;;;\n2F958;CJK COMPATIBILITY IDEOGRAPH-2F958;Lo;0;L;412F;;;;N;;;;;\n2F959;CJK COMPATIBILITY IDEOGRAPH-2F959;Lo;0;L;7A40;;;;N;;;;;\n2F95A;CJK COMPATIBILITY IDEOGRAPH-2F95A;Lo;0;L;7A4A;;;;N;;;;;\n2F95B;CJK COMPATIBILITY IDEOGRAPH-2F95B;Lo;0;L;7A4F;;;;N;;;;;\n2F95C;CJK COMPATIBILITY IDEOGRAPH-2F95C;Lo;0;L;2597C;;;;N;;;;;\n2F95D;CJK COMPATIBILITY IDEOGRAPH-2F95D;Lo;0;L;25AA7;;;;N;;;;;\n2F95E;CJK COMPATIBILITY IDEOGRAPH-2F95E;Lo;0;L;25AA7;;;;N;;;;;\n2F95F;CJK COMPATIBILITY IDEOGRAPH-2F95F;Lo;0;L;7AEE;;;;N;;;;;\n2F960;CJK COMPATIBILITY IDEOGRAPH-2F960;Lo;0;L;4202;;;;N;;;;;\n2F961;CJK COMPATIBILITY IDEOGRAPH-2F961;Lo;0;L;25BAB;;;;N;;;;;\n2F962;CJK COMPATIBILITY IDEOGRAPH-2F962;Lo;0;L;7BC6;;;;N;;;;;\n2F963;CJK COMPATIBILITY IDEOGRAPH-2F963;Lo;0;L;7BC9;;;;N;;;;;\n2F964;CJK COMPATIBILITY IDEOGRAPH-2F964;Lo;0;L;4227;;;;N;;;;;\n2F965;CJK COMPATIBILITY IDEOGRAPH-2F965;Lo;0;L;25C80;;;;N;;;;;\n2F966;CJK COMPATIBILITY IDEOGRAPH-2F966;Lo;0;L;7CD2;;;;N;;;;;\n2F967;CJK COMPATIBILITY IDEOGRAPH-2F967;Lo;0;L;42A0;;;;N;;;;;\n2F968;CJK COMPATIBILITY IDEOGRAPH-2F968;Lo;0;L;7CE8;;;;N;;;;;\n2F969;CJK COMPATIBILITY IDEOGRAPH-2F969;Lo;0;L;7CE3;;;;N;;;;;\n2F96A;CJK COMPATIBILITY IDEOGRAPH-2F96A;Lo;0;L;7D00;;;;N;;;;;\n2F96B;CJK COMPATIBILITY IDEOGRAPH-2F96B;Lo;0;L;25F86;;;;N;;;;;\n2F96C;CJK COMPATIBILITY IDEOGRAPH-2F96C;Lo;0;L;7D63;;;;N;;;;;\n2F96D;CJK COMPATIBILITY IDEOGRAPH-2F96D;Lo;0;L;4301;;;;N;;;;;\n2F96E;CJK COMPATIBILITY IDEOGRAPH-2F96E;Lo;0;L;7DC7;;;;N;;;;;\n2F96F;CJK COMPATIBILITY IDEOGRAPH-2F96F;Lo;0;L;7E02;;;;N;;;;;\n2F970;CJK COMPATIBILITY IDEOGRAPH-2F970;Lo;0;L;7E45;;;;N;;;;;\n2F971;CJK COMPATIBILITY IDEOGRAPH-2F971;Lo;0;L;4334;;;;N;;;;;\n2F972;CJK COMPATIBILITY IDEOGRAPH-2F972;Lo;0;L;26228;;;;N;;;;;\n2F973;CJK COMPATIBILITY IDEOGRAPH-2F973;Lo;0;L;26247;;;;N;;;;;\n2F974;CJK COMPATIBILITY IDEOGRAPH-2F974;Lo;0;L;4359;;;;N;;;;;\n2F975;CJK COMPATIBILITY IDEOGRAPH-2F975;Lo;0;L;262D9;;;;N;;;;;\n2F976;CJK COMPATIBILITY IDEOGRAPH-2F976;Lo;0;L;7F7A;;;;N;;;;;\n2F977;CJK COMPATIBILITY IDEOGRAPH-2F977;Lo;0;L;2633E;;;;N;;;;;\n2F978;CJK COMPATIBILITY IDEOGRAPH-2F978;Lo;0;L;7F95;;;;N;;;;;\n2F979;CJK COMPATIBILITY IDEOGRAPH-2F979;Lo;0;L;7FFA;;;;N;;;;;\n2F97A;CJK COMPATIBILITY IDEOGRAPH-2F97A;Lo;0;L;8005;;;;N;;;;;\n2F97B;CJK COMPATIBILITY IDEOGRAPH-2F97B;Lo;0;L;264DA;;;;N;;;;;\n2F97C;CJK COMPATIBILITY IDEOGRAPH-2F97C;Lo;0;L;26523;;;;N;;;;;\n2F97D;CJK COMPATIBILITY IDEOGRAPH-2F97D;Lo;0;L;8060;;;;N;;;;;\n2F97E;CJK COMPATIBILITY IDEOGRAPH-2F97E;Lo;0;L;265A8;;;;N;;;;;\n2F97F;CJK COMPATIBILITY IDEOGRAPH-2F97F;Lo;0;L;8070;;;;N;;;;;\n2F980;CJK COMPATIBILITY IDEOGRAPH-2F980;Lo;0;L;2335F;;;;N;;;;;\n2F981;CJK COMPATIBILITY IDEOGRAPH-2F981;Lo;0;L;43D5;;;;N;;;;;\n2F982;CJK COMPATIBILITY IDEOGRAPH-2F982;Lo;0;L;80B2;;;;N;;;;;\n2F983;CJK COMPATIBILITY IDEOGRAPH-2F983;Lo;0;L;8103;;;;N;;;;;\n2F984;CJK COMPATIBILITY IDEOGRAPH-2F984;Lo;0;L;440B;;;;N;;;;;\n2F985;CJK COMPATIBILITY IDEOGRAPH-2F985;Lo;0;L;813E;;;;N;;;;;\n2F986;CJK COMPATIBILITY IDEOGRAPH-2F986;Lo;0;L;5AB5;;;;N;;;;;\n2F987;CJK COMPATIBILITY IDEOGRAPH-2F987;Lo;0;L;267A7;;;;N;;;;;\n2F988;CJK COMPATIBILITY IDEOGRAPH-2F988;Lo;0;L;267B5;;;;N;;;;;\n2F989;CJK COMPATIBILITY IDEOGRAPH-2F989;Lo;0;L;23393;;;;N;;;;;\n2F98A;CJK COMPATIBILITY IDEOGRAPH-2F98A;Lo;0;L;2339C;;;;N;;;;;\n2F98B;CJK COMPATIBILITY IDEOGRAPH-2F98B;Lo;0;L;8201;;;;N;;;;;\n2F98C;CJK COMPATIBILITY IDEOGRAPH-2F98C;Lo;0;L;8204;;;;N;;;;;\n2F98D;CJK COMPATIBILITY IDEOGRAPH-2F98D;Lo;0;L;8F9E;;;;N;;;;;\n2F98E;CJK COMPATIBILITY IDEOGRAPH-2F98E;Lo;0;L;446B;;;;N;;;;;\n2F98F;CJK COMPATIBILITY IDEOGRAPH-2F98F;Lo;0;L;8291;;;;N;;;;;\n2F990;CJK COMPATIBILITY IDEOGRAPH-2F990;Lo;0;L;828B;;;;N;;;;;\n2F991;CJK COMPATIBILITY IDEOGRAPH-2F991;Lo;0;L;829D;;;;N;;;;;\n2F992;CJK COMPATIBILITY IDEOGRAPH-2F992;Lo;0;L;52B3;;;;N;;;;;\n2F993;CJK COMPATIBILITY IDEOGRAPH-2F993;Lo;0;L;82B1;;;;N;;;;;\n2F994;CJK COMPATIBILITY IDEOGRAPH-2F994;Lo;0;L;82B3;;;;N;;;;;\n2F995;CJK COMPATIBILITY IDEOGRAPH-2F995;Lo;0;L;82BD;;;;N;;;;;\n2F996;CJK COMPATIBILITY IDEOGRAPH-2F996;Lo;0;L;82E6;;;;N;;;;;\n2F997;CJK COMPATIBILITY IDEOGRAPH-2F997;Lo;0;L;26B3C;;;;N;;;;;\n2F998;CJK COMPATIBILITY IDEOGRAPH-2F998;Lo;0;L;82E5;;;;N;;;;;\n2F999;CJK COMPATIBILITY IDEOGRAPH-2F999;Lo;0;L;831D;;;;N;;;;;\n2F99A;CJK COMPATIBILITY IDEOGRAPH-2F99A;Lo;0;L;8363;;;;N;;;;;\n2F99B;CJK COMPATIBILITY IDEOGRAPH-2F99B;Lo;0;L;83AD;;;;N;;;;;\n2F99C;CJK COMPATIBILITY IDEOGRAPH-2F99C;Lo;0;L;8323;;;;N;;;;;\n2F99D;CJK COMPATIBILITY IDEOGRAPH-2F99D;Lo;0;L;83BD;;;;N;;;;;\n2F99E;CJK COMPATIBILITY IDEOGRAPH-2F99E;Lo;0;L;83E7;;;;N;;;;;\n2F99F;CJK COMPATIBILITY IDEOGRAPH-2F99F;Lo;0;L;8457;;;;N;;;;;\n2F9A0;CJK COMPATIBILITY IDEOGRAPH-2F9A0;Lo;0;L;8353;;;;N;;;;;\n2F9A1;CJK COMPATIBILITY IDEOGRAPH-2F9A1;Lo;0;L;83CA;;;;N;;;;;\n2F9A2;CJK COMPATIBILITY IDEOGRAPH-2F9A2;Lo;0;L;83CC;;;;N;;;;;\n2F9A3;CJK COMPATIBILITY IDEOGRAPH-2F9A3;Lo;0;L;83DC;;;;N;;;;;\n2F9A4;CJK COMPATIBILITY IDEOGRAPH-2F9A4;Lo;0;L;26C36;;;;N;;;;;\n2F9A5;CJK COMPATIBILITY IDEOGRAPH-2F9A5;Lo;0;L;26D6B;;;;N;;;;;\n2F9A6;CJK COMPATIBILITY IDEOGRAPH-2F9A6;Lo;0;L;26CD5;;;;N;;;;;\n2F9A7;CJK COMPATIBILITY IDEOGRAPH-2F9A7;Lo;0;L;452B;;;;N;;;;;\n2F9A8;CJK COMPATIBILITY IDEOGRAPH-2F9A8;Lo;0;L;84F1;;;;N;;;;;\n2F9A9;CJK COMPATIBILITY IDEOGRAPH-2F9A9;Lo;0;L;84F3;;;;N;;;;;\n2F9AA;CJK COMPATIBILITY IDEOGRAPH-2F9AA;Lo;0;L;8516;;;;N;;;;;\n2F9AB;CJK COMPATIBILITY IDEOGRAPH-2F9AB;Lo;0;L;273CA;;;;N;;;;;\n2F9AC;CJK COMPATIBILITY IDEOGRAPH-2F9AC;Lo;0;L;8564;;;;N;;;;;\n2F9AD;CJK COMPATIBILITY IDEOGRAPH-2F9AD;Lo;0;L;26F2C;;;;N;;;;;\n2F9AE;CJK COMPATIBILITY IDEOGRAPH-2F9AE;Lo;0;L;455D;;;;N;;;;;\n2F9AF;CJK COMPATIBILITY IDEOGRAPH-2F9AF;Lo;0;L;4561;;;;N;;;;;\n2F9B0;CJK COMPATIBILITY IDEOGRAPH-2F9B0;Lo;0;L;26FB1;;;;N;;;;;\n2F9B1;CJK COMPATIBILITY IDEOGRAPH-2F9B1;Lo;0;L;270D2;;;;N;;;;;\n2F9B2;CJK COMPATIBILITY IDEOGRAPH-2F9B2;Lo;0;L;456B;;;;N;;;;;\n2F9B3;CJK COMPATIBILITY IDEOGRAPH-2F9B3;Lo;0;L;8650;;;;N;;;;;\n2F9B4;CJK COMPATIBILITY IDEOGRAPH-2F9B4;Lo;0;L;865C;;;;N;;;;;\n2F9B5;CJK COMPATIBILITY IDEOGRAPH-2F9B5;Lo;0;L;8667;;;;N;;;;;\n2F9B6;CJK COMPATIBILITY IDEOGRAPH-2F9B6;Lo;0;L;8669;;;;N;;;;;\n2F9B7;CJK COMPATIBILITY IDEOGRAPH-2F9B7;Lo;0;L;86A9;;;;N;;;;;\n2F9B8;CJK COMPATIBILITY IDEOGRAPH-2F9B8;Lo;0;L;8688;;;;N;;;;;\n2F9B9;CJK COMPATIBILITY IDEOGRAPH-2F9B9;Lo;0;L;870E;;;;N;;;;;\n2F9BA;CJK COMPATIBILITY IDEOGRAPH-2F9BA;Lo;0;L;86E2;;;;N;;;;;\n2F9BB;CJK COMPATIBILITY IDEOGRAPH-2F9BB;Lo;0;L;8779;;;;N;;;;;\n2F9BC;CJK COMPATIBILITY IDEOGRAPH-2F9BC;Lo;0;L;8728;;;;N;;;;;\n2F9BD;CJK COMPATIBILITY IDEOGRAPH-2F9BD;Lo;0;L;876B;;;;N;;;;;\n2F9BE;CJK COMPATIBILITY IDEOGRAPH-2F9BE;Lo;0;L;8786;;;;N;;;;;\n2F9BF;CJK COMPATIBILITY IDEOGRAPH-2F9BF;Lo;0;L;45D7;;;;N;;;;;\n2F9C0;CJK COMPATIBILITY IDEOGRAPH-2F9C0;Lo;0;L;87E1;;;;N;;;;;\n2F9C1;CJK COMPATIBILITY IDEOGRAPH-2F9C1;Lo;0;L;8801;;;;N;;;;;\n2F9C2;CJK COMPATIBILITY IDEOGRAPH-2F9C2;Lo;0;L;45F9;;;;N;;;;;\n2F9C3;CJK COMPATIBILITY IDEOGRAPH-2F9C3;Lo;0;L;8860;;;;N;;;;;\n2F9C4;CJK COMPATIBILITY IDEOGRAPH-2F9C4;Lo;0;L;8863;;;;N;;;;;\n2F9C5;CJK COMPATIBILITY IDEOGRAPH-2F9C5;Lo;0;L;27667;;;;N;;;;;\n2F9C6;CJK COMPATIBILITY IDEOGRAPH-2F9C6;Lo;0;L;88D7;;;;N;;;;;\n2F9C7;CJK COMPATIBILITY IDEOGRAPH-2F9C7;Lo;0;L;88DE;;;;N;;;;;\n2F9C8;CJK COMPATIBILITY IDEOGRAPH-2F9C8;Lo;0;L;4635;;;;N;;;;;\n2F9C9;CJK COMPATIBILITY IDEOGRAPH-2F9C9;Lo;0;L;88FA;;;;N;;;;;\n2F9CA;CJK COMPATIBILITY IDEOGRAPH-2F9CA;Lo;0;L;34BB;;;;N;;;;;\n2F9CB;CJK COMPATIBILITY IDEOGRAPH-2F9CB;Lo;0;L;278AE;;;;N;;;;;\n2F9CC;CJK COMPATIBILITY IDEOGRAPH-2F9CC;Lo;0;L;27966;;;;N;;;;;\n2F9CD;CJK COMPATIBILITY IDEOGRAPH-2F9CD;Lo;0;L;46BE;;;;N;;;;;\n2F9CE;CJK COMPATIBILITY IDEOGRAPH-2F9CE;Lo;0;L;46C7;;;;N;;;;;\n2F9CF;CJK COMPATIBILITY IDEOGRAPH-2F9CF;Lo;0;L;8AA0;;;;N;;;;;\n2F9D0;CJK COMPATIBILITY IDEOGRAPH-2F9D0;Lo;0;L;8AED;;;;N;;;;;\n2F9D1;CJK COMPATIBILITY IDEOGRAPH-2F9D1;Lo;0;L;8B8A;;;;N;;;;;\n2F9D2;CJK COMPATIBILITY IDEOGRAPH-2F9D2;Lo;0;L;8C55;;;;N;;;;;\n2F9D3;CJK COMPATIBILITY IDEOGRAPH-2F9D3;Lo;0;L;27CA8;;;;N;;;;;\n2F9D4;CJK COMPATIBILITY IDEOGRAPH-2F9D4;Lo;0;L;8CAB;;;;N;;;;;\n2F9D5;CJK COMPATIBILITY IDEOGRAPH-2F9D5;Lo;0;L;8CC1;;;;N;;;;;\n2F9D6;CJK COMPATIBILITY IDEOGRAPH-2F9D6;Lo;0;L;8D1B;;;;N;;;;;\n2F9D7;CJK COMPATIBILITY IDEOGRAPH-2F9D7;Lo;0;L;8D77;;;;N;;;;;\n2F9D8;CJK COMPATIBILITY IDEOGRAPH-2F9D8;Lo;0;L;27F2F;;;;N;;;;;\n2F9D9;CJK COMPATIBILITY IDEOGRAPH-2F9D9;Lo;0;L;20804;;;;N;;;;;\n2F9DA;CJK COMPATIBILITY IDEOGRAPH-2F9DA;Lo;0;L;8DCB;;;;N;;;;;\n2F9DB;CJK COMPATIBILITY IDEOGRAPH-2F9DB;Lo;0;L;8DBC;;;;N;;;;;\n2F9DC;CJK COMPATIBILITY IDEOGRAPH-2F9DC;Lo;0;L;8DF0;;;;N;;;;;\n2F9DD;CJK COMPATIBILITY IDEOGRAPH-2F9DD;Lo;0;L;208DE;;;;N;;;;;\n2F9DE;CJK COMPATIBILITY IDEOGRAPH-2F9DE;Lo;0;L;8ED4;;;;N;;;;;\n2F9DF;CJK COMPATIBILITY IDEOGRAPH-2F9DF;Lo;0;L;8F38;;;;N;;;;;\n2F9E0;CJK COMPATIBILITY IDEOGRAPH-2F9E0;Lo;0;L;285D2;;;;N;;;;;\n2F9E1;CJK COMPATIBILITY IDEOGRAPH-2F9E1;Lo;0;L;285ED;;;;N;;;;;\n2F9E2;CJK COMPATIBILITY IDEOGRAPH-2F9E2;Lo;0;L;9094;;;;N;;;;;\n2F9E3;CJK COMPATIBILITY IDEOGRAPH-2F9E3;Lo;0;L;90F1;;;;N;;;;;\n2F9E4;CJK COMPATIBILITY IDEOGRAPH-2F9E4;Lo;0;L;9111;;;;N;;;;;\n2F9E5;CJK COMPATIBILITY IDEOGRAPH-2F9E5;Lo;0;L;2872E;;;;N;;;;;\n2F9E6;CJK COMPATIBILITY IDEOGRAPH-2F9E6;Lo;0;L;911B;;;;N;;;;;\n2F9E7;CJK COMPATIBILITY IDEOGRAPH-2F9E7;Lo;0;L;9238;;;;N;;;;;\n2F9E8;CJK COMPATIBILITY IDEOGRAPH-2F9E8;Lo;0;L;92D7;;;;N;;;;;\n2F9E9;CJK COMPATIBILITY IDEOGRAPH-2F9E9;Lo;0;L;92D8;;;;N;;;;;\n2F9EA;CJK COMPATIBILITY IDEOGRAPH-2F9EA;Lo;0;L;927C;;;;N;;;;;\n2F9EB;CJK COMPATIBILITY IDEOGRAPH-2F9EB;Lo;0;L;93F9;;;;N;;;;;\n2F9EC;CJK COMPATIBILITY IDEOGRAPH-2F9EC;Lo;0;L;9415;;;;N;;;;;\n2F9ED;CJK COMPATIBILITY IDEOGRAPH-2F9ED;Lo;0;L;28BFA;;;;N;;;;;\n2F9EE;CJK COMPATIBILITY IDEOGRAPH-2F9EE;Lo;0;L;958B;;;;N;;;;;\n2F9EF;CJK COMPATIBILITY IDEOGRAPH-2F9EF;Lo;0;L;4995;;;;N;;;;;\n2F9F0;CJK COMPATIBILITY IDEOGRAPH-2F9F0;Lo;0;L;95B7;;;;N;;;;;\n2F9F1;CJK COMPATIBILITY IDEOGRAPH-2F9F1;Lo;0;L;28D77;;;;N;;;;;\n2F9F2;CJK COMPATIBILITY IDEOGRAPH-2F9F2;Lo;0;L;49E6;;;;N;;;;;\n2F9F3;CJK COMPATIBILITY IDEOGRAPH-2F9F3;Lo;0;L;96C3;;;;N;;;;;\n2F9F4;CJK COMPATIBILITY IDEOGRAPH-2F9F4;Lo;0;L;5DB2;;;;N;;;;;\n2F9F5;CJK COMPATIBILITY IDEOGRAPH-2F9F5;Lo;0;L;9723;;;;N;;;;;\n2F9F6;CJK COMPATIBILITY IDEOGRAPH-2F9F6;Lo;0;L;29145;;;;N;;;;;\n2F9F7;CJK COMPATIBILITY IDEOGRAPH-2F9F7;Lo;0;L;2921A;;;;N;;;;;\n2F9F8;CJK COMPATIBILITY IDEOGRAPH-2F9F8;Lo;0;L;4A6E;;;;N;;;;;\n2F9F9;CJK COMPATIBILITY IDEOGRAPH-2F9F9;Lo;0;L;4A76;;;;N;;;;;\n2F9FA;CJK COMPATIBILITY IDEOGRAPH-2F9FA;Lo;0;L;97E0;;;;N;;;;;\n2F9FB;CJK COMPATIBILITY IDEOGRAPH-2F9FB;Lo;0;L;2940A;;;;N;;;;;\n2F9FC;CJK COMPATIBILITY IDEOGRAPH-2F9FC;Lo;0;L;4AB2;;;;N;;;;;\n2F9FD;CJK COMPATIBILITY IDEOGRAPH-2F9FD;Lo;0;L;29496;;;;N;;;;;\n2F9FE;CJK COMPATIBILITY IDEOGRAPH-2F9FE;Lo;0;L;980B;;;;N;;;;;\n2F9FF;CJK COMPATIBILITY IDEOGRAPH-2F9FF;Lo;0;L;980B;;;;N;;;;;\n2FA00;CJK COMPATIBILITY IDEOGRAPH-2FA00;Lo;0;L;9829;;;;N;;;;;\n2FA01;CJK COMPATIBILITY IDEOGRAPH-2FA01;Lo;0;L;295B6;;;;N;;;;;\n2FA02;CJK COMPATIBILITY IDEOGRAPH-2FA02;Lo;0;L;98E2;;;;N;;;;;\n2FA03;CJK COMPATIBILITY IDEOGRAPH-2FA03;Lo;0;L;4B33;;;;N;;;;;\n2FA04;CJK COMPATIBILITY IDEOGRAPH-2FA04;Lo;0;L;9929;;;;N;;;;;\n2FA05;CJK COMPATIBILITY IDEOGRAPH-2FA05;Lo;0;L;99A7;;;;N;;;;;\n2FA06;CJK COMPATIBILITY IDEOGRAPH-2FA06;Lo;0;L;99C2;;;;N;;;;;\n2FA07;CJK COMPATIBILITY IDEOGRAPH-2FA07;Lo;0;L;99FE;;;;N;;;;;\n2FA08;CJK COMPATIBILITY IDEOGRAPH-2FA08;Lo;0;L;4BCE;;;;N;;;;;\n2FA09;CJK COMPATIBILITY IDEOGRAPH-2FA09;Lo;0;L;29B30;;;;N;;;;;\n2FA0A;CJK COMPATIBILITY IDEOGRAPH-2FA0A;Lo;0;L;9B12;;;;N;;;;;\n2FA0B;CJK COMPATIBILITY IDEOGRAPH-2FA0B;Lo;0;L;9C40;;;;N;;;;;\n2FA0C;CJK COMPATIBILITY IDEOGRAPH-2FA0C;Lo;0;L;9CFD;;;;N;;;;;\n2FA0D;CJK COMPATIBILITY IDEOGRAPH-2FA0D;Lo;0;L;4CCE;;;;N;;;;;\n2FA0E;CJK COMPATIBILITY IDEOGRAPH-2FA0E;Lo;0;L;4CED;;;;N;;;;;\n2FA0F;CJK COMPATIBILITY IDEOGRAPH-2FA0F;Lo;0;L;9D67;;;;N;;;;;\n2FA10;CJK COMPATIBILITY IDEOGRAPH-2FA10;Lo;0;L;2A0CE;;;;N;;;;;\n2FA11;CJK COMPATIBILITY IDEOGRAPH-2FA11;Lo;0;L;4CF8;;;;N;;;;;\n2FA12;CJK COMPATIBILITY IDEOGRAPH-2FA12;Lo;0;L;2A105;;;;N;;;;;\n2FA13;CJK COMPATIBILITY IDEOGRAPH-2FA13;Lo;0;L;2A20E;;;;N;;;;;\n2FA14;CJK COMPATIBILITY IDEOGRAPH-2FA14;Lo;0;L;2A291;;;;N;;;;;\n2FA15;CJK COMPATIBILITY IDEOGRAPH-2FA15;Lo;0;L;9EBB;;;;N;;;;;\n2FA16;CJK COMPATIBILITY IDEOGRAPH-2FA16;Lo;0;L;4D56;;;;N;;;;;\n2FA17;CJK COMPATIBILITY IDEOGRAPH-2FA17;Lo;0;L;9EF9;;;;N;;;;;\n2FA18;CJK COMPATIBILITY IDEOGRAPH-2FA18;Lo;0;L;9EFE;;;;N;;;;;\n2FA19;CJK COMPATIBILITY IDEOGRAPH-2FA19;Lo;0;L;9F05;;;;N;;;;;\n2FA1A;CJK COMPATIBILITY IDEOGRAPH-2FA1A;Lo;0;L;9F0F;;;;N;;;;;\n2FA1B;CJK COMPATIBILITY IDEOGRAPH-2FA1B;Lo;0;L;9F16;;;;N;;;;;\n2FA1C;CJK COMPATIBILITY IDEOGRAPH-2FA1C;Lo;0;L;9F3B;;;;N;;;;;\n2FA1D;CJK COMPATIBILITY IDEOGRAPH-2FA1D;Lo;0;L;2A600;;;;N;;;;;\nE0001;LANGUAGE TAG;Cf;0;BN;;;;;N;;;;;\nE0020;TAG SPACE;Cf;0;BN;;;;;N;;;;;\nE0021;TAG EXCLAMATION MARK;Cf;0;BN;;;;;N;;;;;\nE0022;TAG QUOTATION MARK;Cf;0;BN;;;;;N;;;;;\nE0023;TAG NUMBER SIGN;Cf;0;BN;;;;;N;;;;;\nE0024;TAG DOLLAR SIGN;Cf;0;BN;;;;;N;;;;;\nE0025;TAG PERCENT SIGN;Cf;0;BN;;;;;N;;;;;\nE0026;TAG AMPERSAND;Cf;0;BN;;;;;N;;;;;\nE0027;TAG APOSTROPHE;Cf;0;BN;;;;;N;;;;;\nE0028;TAG LEFT PARENTHESIS;Cf;0;BN;;;;;N;;;;;\nE0029;TAG RIGHT PARENTHESIS;Cf;0;BN;;;;;N;;;;;\nE002A;TAG ASTERISK;Cf;0;BN;;;;;N;;;;;\nE002B;TAG PLUS SIGN;Cf;0;BN;;;;;N;;;;;\nE002C;TAG COMMA;Cf;0;BN;;;;;N;;;;;\nE002D;TAG HYPHEN-MINUS;Cf;0;BN;;;;;N;;;;;\nE002E;TAG FULL STOP;Cf;0;BN;;;;;N;;;;;\nE002F;TAG SOLIDUS;Cf;0;BN;;;;;N;;;;;\nE0030;TAG DIGIT ZERO;Cf;0;BN;;;;;N;;;;;\nE0031;TAG DIGIT ONE;Cf;0;BN;;;;;N;;;;;\nE0032;TAG DIGIT TWO;Cf;0;BN;;;;;N;;;;;\nE0033;TAG DIGIT THREE;Cf;0;BN;;;;;N;;;;;\nE0034;TAG DIGIT FOUR;Cf;0;BN;;;;;N;;;;;\nE0035;TAG DIGIT FIVE;Cf;0;BN;;;;;N;;;;;\nE0036;TAG DIGIT SIX;Cf;0;BN;;;;;N;;;;;\nE0037;TAG DIGIT SEVEN;Cf;0;BN;;;;;N;;;;;\nE0038;TAG DIGIT EIGHT;Cf;0;BN;;;;;N;;;;;\nE0039;TAG DIGIT NINE;Cf;0;BN;;;;;N;;;;;\nE003A;TAG COLON;Cf;0;BN;;;;;N;;;;;\nE003B;TAG SEMICOLON;Cf;0;BN;;;;;N;;;;;\nE003C;TAG LESS-THAN SIGN;Cf;0;BN;;;;;N;;;;;\nE003D;TAG EQUALS SIGN;Cf;0;BN;;;;;N;;;;;\nE003E;TAG GREATER-THAN SIGN;Cf;0;BN;;;;;N;;;;;\nE003F;TAG QUESTION MARK;Cf;0;BN;;;;;N;;;;;\nE0040;TAG COMMERCIAL AT;Cf;0;BN;;;;;N;;;;;\nE0041;TAG LATIN CAPITAL LETTER A;Cf;0;BN;;;;;N;;;;;\nE0042;TAG LATIN CAPITAL LETTER B;Cf;0;BN;;;;;N;;;;;\nE0043;TAG LATIN CAPITAL LETTER C;Cf;0;BN;;;;;N;;;;;\nE0044;TAG LATIN CAPITAL LETTER D;Cf;0;BN;;;;;N;;;;;\nE0045;TAG LATIN CAPITAL LETTER E;Cf;0;BN;;;;;N;;;;;\nE0046;TAG LATIN CAPITAL LETTER F;Cf;0;BN;;;;;N;;;;;\nE0047;TAG LATIN CAPITAL LETTER G;Cf;0;BN;;;;;N;;;;;\nE0048;TAG LATIN CAPITAL LETTER H;Cf;0;BN;;;;;N;;;;;\nE0049;TAG LATIN CAPITAL LETTER I;Cf;0;BN;;;;;N;;;;;\nE004A;TAG LATIN CAPITAL LETTER J;Cf;0;BN;;;;;N;;;;;\nE004B;TAG LATIN CAPITAL LETTER K;Cf;0;BN;;;;;N;;;;;\nE004C;TAG LATIN CAPITAL LETTER L;Cf;0;BN;;;;;N;;;;;\nE004D;TAG LATIN CAPITAL LETTER M;Cf;0;BN;;;;;N;;;;;\nE004E;TAG LATIN CAPITAL LETTER N;Cf;0;BN;;;;;N;;;;;\nE004F;TAG LATIN CAPITAL LETTER O;Cf;0;BN;;;;;N;;;;;\nE0050;TAG LATIN CAPITAL LETTER P;Cf;0;BN;;;;;N;;;;;\nE0051;TAG LATIN CAPITAL LETTER Q;Cf;0;BN;;;;;N;;;;;\nE0052;TAG LATIN CAPITAL LETTER R;Cf;0;BN;;;;;N;;;;;\nE0053;TAG LATIN CAPITAL LETTER S;Cf;0;BN;;;;;N;;;;;\nE0054;TAG LATIN CAPITAL LETTER T;Cf;0;BN;;;;;N;;;;;\nE0055;TAG LATIN CAPITAL LETTER U;Cf;0;BN;;;;;N;;;;;\nE0056;TAG LATIN CAPITAL LETTER V;Cf;0;BN;;;;;N;;;;;\nE0057;TAG LATIN CAPITAL LETTER W;Cf;0;BN;;;;;N;;;;;\nE0058;TAG LATIN CAPITAL LETTER X;Cf;0;BN;;;;;N;;;;;\nE0059;TAG LATIN CAPITAL LETTER Y;Cf;0;BN;;;;;N;;;;;\nE005A;TAG LATIN CAPITAL LETTER Z;Cf;0;BN;;;;;N;;;;;\nE005B;TAG LEFT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;;\nE005C;TAG REVERSE SOLIDUS;Cf;0;BN;;;;;N;;;;;\nE005D;TAG RIGHT SQUARE BRACKET;Cf;0;BN;;;;;N;;;;;\nE005E;TAG CIRCUMFLEX ACCENT;Cf;0;BN;;;;;N;;;;;\nE005F;TAG LOW LINE;Cf;0;BN;;;;;N;;;;;\nE0060;TAG GRAVE ACCENT;Cf;0;BN;;;;;N;;;;;\nE0061;TAG LATIN SMALL LETTER A;Cf;0;BN;;;;;N;;;;;\nE0062;TAG LATIN SMALL LETTER B;Cf;0;BN;;;;;N;;;;;\nE0063;TAG LATIN SMALL LETTER C;Cf;0;BN;;;;;N;;;;;\nE0064;TAG LATIN SMALL LETTER D;Cf;0;BN;;;;;N;;;;;\nE0065;TAG LATIN SMALL LETTER E;Cf;0;BN;;;;;N;;;;;\nE0066;TAG LATIN SMALL LETTER F;Cf;0;BN;;;;;N;;;;;\nE0067;TAG LATIN SMALL LETTER G;Cf;0;BN;;;;;N;;;;;\nE0068;TAG LATIN SMALL LETTER H;Cf;0;BN;;;;;N;;;;;\nE0069;TAG LATIN SMALL LETTER I;Cf;0;BN;;;;;N;;;;;\nE006A;TAG LATIN SMALL LETTER J;Cf;0;BN;;;;;N;;;;;\nE006B;TAG LATIN SMALL LETTER K;Cf;0;BN;;;;;N;;;;;\nE006C;TAG LATIN SMALL LETTER L;Cf;0;BN;;;;;N;;;;;\nE006D;TAG LATIN SMALL LETTER M;Cf;0;BN;;;;;N;;;;;\nE006E;TAG LATIN SMALL LETTER N;Cf;0;BN;;;;;N;;;;;\nE006F;TAG LATIN SMALL LETTER O;Cf;0;BN;;;;;N;;;;;\nE0070;TAG LATIN SMALL LETTER P;Cf;0;BN;;;;;N;;;;;\nE0071;TAG LATIN SMALL LETTER Q;Cf;0;BN;;;;;N;;;;;\nE0072;TAG LATIN SMALL LETTER R;Cf;0;BN;;;;;N;;;;;\nE0073;TAG LATIN SMALL LETTER S;Cf;0;BN;;;;;N;;;;;\nE0074;TAG LATIN SMALL LETTER T;Cf;0;BN;;;;;N;;;;;\nE0075;TAG LATIN SMALL LETTER U;Cf;0;BN;;;;;N;;;;;\nE0076;TAG LATIN SMALL LETTER V;Cf;0;BN;;;;;N;;;;;\nE0077;TAG LATIN SMALL LETTER W;Cf;0;BN;;;;;N;;;;;\nE0078;TAG LATIN SMALL LETTER X;Cf;0;BN;;;;;N;;;;;\nE0079;TAG LATIN SMALL LETTER Y;Cf;0;BN;;;;;N;;;;;\nE007A;TAG LATIN SMALL LETTER Z;Cf;0;BN;;;;;N;;;;;\nE007B;TAG LEFT CURLY BRACKET;Cf;0;BN;;;;;N;;;;;\nE007C;TAG VERTICAL LINE;Cf;0;BN;;;;;N;;;;;\nE007D;TAG RIGHT CURLY BRACKET;Cf;0;BN;;;;;N;;;;;\nE007E;TAG TILDE;Cf;0;BN;;;;;N;;;;;\nE007F;CANCEL TAG;Cf;0;BN;;;;;N;;;;;\nE0100;VARIATION SELECTOR-17;Mn;0;NSM;;;;;N;;;;;\nE0101;VARIATION SELECTOR-18;Mn;0;NSM;;;;;N;;;;;\nE0102;VARIATION SELECTOR-19;Mn;0;NSM;;;;;N;;;;;\nE0103;VARIATION SELECTOR-20;Mn;0;NSM;;;;;N;;;;;\nE0104;VARIATION SELECTOR-21;Mn;0;NSM;;;;;N;;;;;\nE0105;VARIATION SELECTOR-22;Mn;0;NSM;;;;;N;;;;;\nE0106;VARIATION SELECTOR-23;Mn;0;NSM;;;;;N;;;;;\nE0107;VARIATION SELECTOR-24;Mn;0;NSM;;;;;N;;;;;\nE0108;VARIATION SELECTOR-25;Mn;0;NSM;;;;;N;;;;;\nE0109;VARIATION SELECTOR-26;Mn;0;NSM;;;;;N;;;;;\nE010A;VARIATION SELECTOR-27;Mn;0;NSM;;;;;N;;;;;\nE010B;VARIATION SELECTOR-28;Mn;0;NSM;;;;;N;;;;;\nE010C;VARIATION SELECTOR-29;Mn;0;NSM;;;;;N;;;;;\nE010D;VARIATION SELECTOR-30;Mn;0;NSM;;;;;N;;;;;\nE010E;VARIATION SELECTOR-31;Mn;0;NSM;;;;;N;;;;;\nE010F;VARIATION SELECTOR-32;Mn;0;NSM;;;;;N;;;;;\nE0110;VARIATION SELECTOR-33;Mn;0;NSM;;;;;N;;;;;\nE0111;VARIATION SELECTOR-34;Mn;0;NSM;;;;;N;;;;;\nE0112;VARIATION SELECTOR-35;Mn;0;NSM;;;;;N;;;;;\nE0113;VARIATION SELECTOR-36;Mn;0;NSM;;;;;N;;;;;\nE0114;VARIATION SELECTOR-37;Mn;0;NSM;;;;;N;;;;;\nE0115;VARIATION SELECTOR-38;Mn;0;NSM;;;;;N;;;;;\nE0116;VARIATION SELECTOR-39;Mn;0;NSM;;;;;N;;;;;\nE0117;VARIATION SELECTOR-40;Mn;0;NSM;;;;;N;;;;;\nE0118;VARIATION SELECTOR-41;Mn;0;NSM;;;;;N;;;;;\nE0119;VARIATION SELECTOR-42;Mn;0;NSM;;;;;N;;;;;\nE011A;VARIATION SELECTOR-43;Mn;0;NSM;;;;;N;;;;;\nE011B;VARIATION SELECTOR-44;Mn;0;NSM;;;;;N;;;;;\nE011C;VARIATION SELECTOR-45;Mn;0;NSM;;;;;N;;;;;\nE011D;VARIATION SELECTOR-46;Mn;0;NSM;;;;;N;;;;;\nE011E;VARIATION SELECTOR-47;Mn;0;NSM;;;;;N;;;;;\nE011F;VARIATION SELECTOR-48;Mn;0;NSM;;;;;N;;;;;\nE0120;VARIATION SELECTOR-49;Mn;0;NSM;;;;;N;;;;;\nE0121;VARIATION SELECTOR-50;Mn;0;NSM;;;;;N;;;;;\nE0122;VARIATION SELECTOR-51;Mn;0;NSM;;;;;N;;;;;\nE0123;VARIATION SELECTOR-52;Mn;0;NSM;;;;;N;;;;;\nE0124;VARIATION SELECTOR-53;Mn;0;NSM;;;;;N;;;;;\nE0125;VARIATION SELECTOR-54;Mn;0;NSM;;;;;N;;;;;\nE0126;VARIATION SELECTOR-55;Mn;0;NSM;;;;;N;;;;;\nE0127;VARIATION SELECTOR-56;Mn;0;NSM;;;;;N;;;;;\nE0128;VARIATION SELECTOR-57;Mn;0;NSM;;;;;N;;;;;\nE0129;VARIATION SELECTOR-58;Mn;0;NSM;;;;;N;;;;;\nE012A;VARIATION SELECTOR-59;Mn;0;NSM;;;;;N;;;;;\nE012B;VARIATION SELECTOR-60;Mn;0;NSM;;;;;N;;;;;\nE012C;VARIATION SELECTOR-61;Mn;0;NSM;;;;;N;;;;;\nE012D;VARIATION SELECTOR-62;Mn;0;NSM;;;;;N;;;;;\nE012E;VARIATION SELECTOR-63;Mn;0;NSM;;;;;N;;;;;\nE012F;VARIATION SELECTOR-64;Mn;0;NSM;;;;;N;;;;;\nE0130;VARIATION SELECTOR-65;Mn;0;NSM;;;;;N;;;;;\nE0131;VARIATION SELECTOR-66;Mn;0;NSM;;;;;N;;;;;\nE0132;VARIATION SELECTOR-67;Mn;0;NSM;;;;;N;;;;;\nE0133;VARIATION SELECTOR-68;Mn;0;NSM;;;;;N;;;;;\nE0134;VARIATION SELECTOR-69;Mn;0;NSM;;;;;N;;;;;\nE0135;VARIATION SELECTOR-70;Mn;0;NSM;;;;;N;;;;;\nE0136;VARIATION SELECTOR-71;Mn;0;NSM;;;;;N;;;;;\nE0137;VARIATION SELECTOR-72;Mn;0;NSM;;;;;N;;;;;\nE0138;VARIATION SELECTOR-73;Mn;0;NSM;;;;;N;;;;;\nE0139;VARIATION SELECTOR-74;Mn;0;NSM;;;;;N;;;;;\nE013A;VARIATION SELECTOR-75;Mn;0;NSM;;;;;N;;;;;\nE013B;VARIATION SELECTOR-76;Mn;0;NSM;;;;;N;;;;;\nE013C;VARIATION SELECTOR-77;Mn;0;NSM;;;;;N;;;;;\nE013D;VARIATION SELECTOR-78;Mn;0;NSM;;;;;N;;;;;\nE013E;VARIATION SELECTOR-79;Mn;0;NSM;;;;;N;;;;;\nE013F;VARIATION SELECTOR-80;Mn;0;NSM;;;;;N;;;;;\nE0140;VARIATION SELECTOR-81;Mn;0;NSM;;;;;N;;;;;\nE0141;VARIATION SELECTOR-82;Mn;0;NSM;;;;;N;;;;;\nE0142;VARIATION SELECTOR-83;Mn;0;NSM;;;;;N;;;;;\nE0143;VARIATION SELECTOR-84;Mn;0;NSM;;;;;N;;;;;\nE0144;VARIATION SELECTOR-85;Mn;0;NSM;;;;;N;;;;;\nE0145;VARIATION SELECTOR-86;Mn;0;NSM;;;;;N;;;;;\nE0146;VARIATION SELECTOR-87;Mn;0;NSM;;;;;N;;;;;\nE0147;VARIATION SELECTOR-88;Mn;0;NSM;;;;;N;;;;;\nE0148;VARIATION SELECTOR-89;Mn;0;NSM;;;;;N;;;;;\nE0149;VARIATION SELECTOR-90;Mn;0;NSM;;;;;N;;;;;\nE014A;VARIATION SELECTOR-91;Mn;0;NSM;;;;;N;;;;;\nE014B;VARIATION SELECTOR-92;Mn;0;NSM;;;;;N;;;;;\nE014C;VARIATION SELECTOR-93;Mn;0;NSM;;;;;N;;;;;\nE014D;VARIATION SELECTOR-94;Mn;0;NSM;;;;;N;;;;;\nE014E;VARIATION SELECTOR-95;Mn;0;NSM;;;;;N;;;;;\nE014F;VARIATION SELECTOR-96;Mn;0;NSM;;;;;N;;;;;\nE0150;VARIATION SELECTOR-97;Mn;0;NSM;;;;;N;;;;;\nE0151;VARIATION SELECTOR-98;Mn;0;NSM;;;;;N;;;;;\nE0152;VARIATION SELECTOR-99;Mn;0;NSM;;;;;N;;;;;\nE0153;VARIATION SELECTOR-100;Mn;0;NSM;;;;;N;;;;;\nE0154;VARIATION SELECTOR-101;Mn;0;NSM;;;;;N;;;;;\nE0155;VARIATION SELECTOR-102;Mn;0;NSM;;;;;N;;;;;\nE0156;VARIATION SELECTOR-103;Mn;0;NSM;;;;;N;;;;;\nE0157;VARIATION SELECTOR-104;Mn;0;NSM;;;;;N;;;;;\nE0158;VARIATION SELECTOR-105;Mn;0;NSM;;;;;N;;;;;\nE0159;VARIATION SELECTOR-106;Mn;0;NSM;;;;;N;;;;;\nE015A;VARIATION SELECTOR-107;Mn;0;NSM;;;;;N;;;;;\nE015B;VARIATION SELECTOR-108;Mn;0;NSM;;;;;N;;;;;\nE015C;VARIATION SELECTOR-109;Mn;0;NSM;;;;;N;;;;;\nE015D;VARIATION SELECTOR-110;Mn;0;NSM;;;;;N;;;;;\nE015E;VARIATION SELECTOR-111;Mn;0;NSM;;;;;N;;;;;\nE015F;VARIATION SELECTOR-112;Mn;0;NSM;;;;;N;;;;;\nE0160;VARIATION SELECTOR-113;Mn;0;NSM;;;;;N;;;;;\nE0161;VARIATION SELECTOR-114;Mn;0;NSM;;;;;N;;;;;\nE0162;VARIATION SELECTOR-115;Mn;0;NSM;;;;;N;;;;;\nE0163;VARIATION SELECTOR-116;Mn;0;NSM;;;;;N;;;;;\nE0164;VARIATION SELECTOR-117;Mn;0;NSM;;;;;N;;;;;\nE0165;VARIATION SELECTOR-118;Mn;0;NSM;;;;;N;;;;;\nE0166;VARIATION SELECTOR-119;Mn;0;NSM;;;;;N;;;;;\nE0167;VARIATION SELECTOR-120;Mn;0;NSM;;;;;N;;;;;\nE0168;VARIATION SELECTOR-121;Mn;0;NSM;;;;;N;;;;;\nE0169;VARIATION SELECTOR-122;Mn;0;NSM;;;;;N;;;;;\nE016A;VARIATION SELECTOR-123;Mn;0;NSM;;;;;N;;;;;\nE016B;VARIATION SELECTOR-124;Mn;0;NSM;;;;;N;;;;;\nE016C;VARIATION SELECTOR-125;Mn;0;NSM;;;;;N;;;;;\nE016D;VARIATION SELECTOR-126;Mn;0;NSM;;;;;N;;;;;\nE016E;VARIATION SELECTOR-127;Mn;0;NSM;;;;;N;;;;;\nE016F;VARIATION SELECTOR-128;Mn;0;NSM;;;;;N;;;;;\nE0170;VARIATION SELECTOR-129;Mn;0;NSM;;;;;N;;;;;\nE0171;VARIATION SELECTOR-130;Mn;0;NSM;;;;;N;;;;;\nE0172;VARIATION SELECTOR-131;Mn;0;NSM;;;;;N;;;;;\nE0173;VARIATION SELECTOR-132;Mn;0;NSM;;;;;N;;;;;\nE0174;VARIATION SELECTOR-133;Mn;0;NSM;;;;;N;;;;;\nE0175;VARIATION SELECTOR-134;Mn;0;NSM;;;;;N;;;;;\nE0176;VARIATION SELECTOR-135;Mn;0;NSM;;;;;N;;;;;\nE0177;VARIATION SELECTOR-136;Mn;0;NSM;;;;;N;;;;;\nE0178;VARIATION SELECTOR-137;Mn;0;NSM;;;;;N;;;;;\nE0179;VARIATION SELECTOR-138;Mn;0;NSM;;;;;N;;;;;\nE017A;VARIATION SELECTOR-139;Mn;0;NSM;;;;;N;;;;;\nE017B;VARIATION SELECTOR-140;Mn;0;NSM;;;;;N;;;;;\nE017C;VARIATION SELECTOR-141;Mn;0;NSM;;;;;N;;;;;\nE017D;VARIATION SELECTOR-142;Mn;0;NSM;;;;;N;;;;;\nE017E;VARIATION SELECTOR-143;Mn;0;NSM;;;;;N;;;;;\nE017F;VARIATION SELECTOR-144;Mn;0;NSM;;;;;N;;;;;\nE0180;VARIATION SELECTOR-145;Mn;0;NSM;;;;;N;;;;;\nE0181;VARIATION SELECTOR-146;Mn;0;NSM;;;;;N;;;;;\nE0182;VARIATION SELECTOR-147;Mn;0;NSM;;;;;N;;;;;\nE0183;VARIATION SELECTOR-148;Mn;0;NSM;;;;;N;;;;;\nE0184;VARIATION SELECTOR-149;Mn;0;NSM;;;;;N;;;;;\nE0185;VARIATION SELECTOR-150;Mn;0;NSM;;;;;N;;;;;\nE0186;VARIATION SELECTOR-151;Mn;0;NSM;;;;;N;;;;;\nE0187;VARIATION SELECTOR-152;Mn;0;NSM;;;;;N;;;;;\nE0188;VARIATION SELECTOR-153;Mn;0;NSM;;;;;N;;;;;\nE0189;VARIATION SELECTOR-154;Mn;0;NSM;;;;;N;;;;;\nE018A;VARIATION SELECTOR-155;Mn;0;NSM;;;;;N;;;;;\nE018B;VARIATION SELECTOR-156;Mn;0;NSM;;;;;N;;;;;\nE018C;VARIATION SELECTOR-157;Mn;0;NSM;;;;;N;;;;;\nE018D;VARIATION SELECTOR-158;Mn;0;NSM;;;;;N;;;;;\nE018E;VARIATION SELECTOR-159;Mn;0;NSM;;;;;N;;;;;\nE018F;VARIATION SELECTOR-160;Mn;0;NSM;;;;;N;;;;;\nE0190;VARIATION SELECTOR-161;Mn;0;NSM;;;;;N;;;;;\nE0191;VARIATION SELECTOR-162;Mn;0;NSM;;;;;N;;;;;\nE0192;VARIATION SELECTOR-163;Mn;0;NSM;;;;;N;;;;;\nE0193;VARIATION SELECTOR-164;Mn;0;NSM;;;;;N;;;;;\nE0194;VARIATION SELECTOR-165;Mn;0;NSM;;;;;N;;;;;\nE0195;VARIATION SELECTOR-166;Mn;0;NSM;;;;;N;;;;;\nE0196;VARIATION SELECTOR-167;Mn;0;NSM;;;;;N;;;;;\nE0197;VARIATION SELECTOR-168;Mn;0;NSM;;;;;N;;;;;\nE0198;VARIATION SELECTOR-169;Mn;0;NSM;;;;;N;;;;;\nE0199;VARIATION SELECTOR-170;Mn;0;NSM;;;;;N;;;;;\nE019A;VARIATION SELECTOR-171;Mn;0;NSM;;;;;N;;;;;\nE019B;VARIATION SELECTOR-172;Mn;0;NSM;;;;;N;;;;;\nE019C;VARIATION SELECTOR-173;Mn;0;NSM;;;;;N;;;;;\nE019D;VARIATION SELECTOR-174;Mn;0;NSM;;;;;N;;;;;\nE019E;VARIATION SELECTOR-175;Mn;0;NSM;;;;;N;;;;;\nE019F;VARIATION SELECTOR-176;Mn;0;NSM;;;;;N;;;;;\nE01A0;VARIATION SELECTOR-177;Mn;0;NSM;;;;;N;;;;;\nE01A1;VARIATION SELECTOR-178;Mn;0;NSM;;;;;N;;;;;\nE01A2;VARIATION SELECTOR-179;Mn;0;NSM;;;;;N;;;;;\nE01A3;VARIATION SELECTOR-180;Mn;0;NSM;;;;;N;;;;;\nE01A4;VARIATION SELECTOR-181;Mn;0;NSM;;;;;N;;;;;\nE01A5;VARIATION SELECTOR-182;Mn;0;NSM;;;;;N;;;;;\nE01A6;VARIATION SELECTOR-183;Mn;0;NSM;;;;;N;;;;;\nE01A7;VARIATION SELECTOR-184;Mn;0;NSM;;;;;N;;;;;\nE01A8;VARIATION SELECTOR-185;Mn;0;NSM;;;;;N;;;;;\nE01A9;VARIATION SELECTOR-186;Mn;0;NSM;;;;;N;;;;;\nE01AA;VARIATION SELECTOR-187;Mn;0;NSM;;;;;N;;;;;\nE01AB;VARIATION SELECTOR-188;Mn;0;NSM;;;;;N;;;;;\nE01AC;VARIATION SELECTOR-189;Mn;0;NSM;;;;;N;;;;;\nE01AD;VARIATION SELECTOR-190;Mn;0;NSM;;;;;N;;;;;\nE01AE;VARIATION SELECTOR-191;Mn;0;NSM;;;;;N;;;;;\nE01AF;VARIATION SELECTOR-192;Mn;0;NSM;;;;;N;;;;;\nE01B0;VARIATION SELECTOR-193;Mn;0;NSM;;;;;N;;;;;\nE01B1;VARIATION SELECTOR-194;Mn;0;NSM;;;;;N;;;;;\nE01B2;VARIATION SELECTOR-195;Mn;0;NSM;;;;;N;;;;;\nE01B3;VARIATION SELECTOR-196;Mn;0;NSM;;;;;N;;;;;\nE01B4;VARIATION SELECTOR-197;Mn;0;NSM;;;;;N;;;;;\nE01B5;VARIATION SELECTOR-198;Mn;0;NSM;;;;;N;;;;;\nE01B6;VARIATION SELECTOR-199;Mn;0;NSM;;;;;N;;;;;\nE01B7;VARIATION SELECTOR-200;Mn;0;NSM;;;;;N;;;;;\nE01B8;VARIATION SELECTOR-201;Mn;0;NSM;;;;;N;;;;;\nE01B9;VARIATION SELECTOR-202;Mn;0;NSM;;;;;N;;;;;\nE01BA;VARIATION SELECTOR-203;Mn;0;NSM;;;;;N;;;;;\nE01BB;VARIATION SELECTOR-204;Mn;0;NSM;;;;;N;;;;;\nE01BC;VARIATION SELECTOR-205;Mn;0;NSM;;;;;N;;;;;\nE01BD;VARIATION SELECTOR-206;Mn;0;NSM;;;;;N;;;;;\nE01BE;VARIATION SELECTOR-207;Mn;0;NSM;;;;;N;;;;;\nE01BF;VARIATION SELECTOR-208;Mn;0;NSM;;;;;N;;;;;\nE01C0;VARIATION SELECTOR-209;Mn;0;NSM;;;;;N;;;;;\nE01C1;VARIATION SELECTOR-210;Mn;0;NSM;;;;;N;;;;;\nE01C2;VARIATION SELECTOR-211;Mn;0;NSM;;;;;N;;;;;\nE01C3;VARIATION SELECTOR-212;Mn;0;NSM;;;;;N;;;;;\nE01C4;VARIATION SELECTOR-213;Mn;0;NSM;;;;;N;;;;;\nE01C5;VARIATION SELECTOR-214;Mn;0;NSM;;;;;N;;;;;\nE01C6;VARIATION SELECTOR-215;Mn;0;NSM;;;;;N;;;;;\nE01C7;VARIATION SELECTOR-216;Mn;0;NSM;;;;;N;;;;;\nE01C8;VARIATION SELECTOR-217;Mn;0;NSM;;;;;N;;;;;\nE01C9;VARIATION SELECTOR-218;Mn;0;NSM;;;;;N;;;;;\nE01CA;VARIATION SELECTOR-219;Mn;0;NSM;;;;;N;;;;;\nE01CB;VARIATION SELECTOR-220;Mn;0;NSM;;;;;N;;;;;\nE01CC;VARIATION SELECTOR-221;Mn;0;NSM;;;;;N;;;;;\nE01CD;VARIATION SELECTOR-222;Mn;0;NSM;;;;;N;;;;;\nE01CE;VARIATION SELECTOR-223;Mn;0;NSM;;;;;N;;;;;\nE01CF;VARIATION SELECTOR-224;Mn;0;NSM;;;;;N;;;;;\nE01D0;VARIATION SELECTOR-225;Mn;0;NSM;;;;;N;;;;;\nE01D1;VARIATION SELECTOR-226;Mn;0;NSM;;;;;N;;;;;\nE01D2;VARIATION SELECTOR-227;Mn;0;NSM;;;;;N;;;;;\nE01D3;VARIATION SELECTOR-228;Mn;0;NSM;;;;;N;;;;;\nE01D4;VARIATION SELECTOR-229;Mn;0;NSM;;;;;N;;;;;\nE01D5;VARIATION SELECTOR-230;Mn;0;NSM;;;;;N;;;;;\nE01D6;VARIATION SELECTOR-231;Mn;0;NSM;;;;;N;;;;;\nE01D7;VARIATION SELECTOR-232;Mn;0;NSM;;;;;N;;;;;\nE01D8;VARIATION SELECTOR-233;Mn;0;NSM;;;;;N;;;;;\nE01D9;VARIATION SELECTOR-234;Mn;0;NSM;;;;;N;;;;;\nE01DA;VARIATION SELECTOR-235;Mn;0;NSM;;;;;N;;;;;\nE01DB;VARIATION SELECTOR-236;Mn;0;NSM;;;;;N;;;;;\nE01DC;VARIATION SELECTOR-237;Mn;0;NSM;;;;;N;;;;;\nE01DD;VARIATION SELECTOR-238;Mn;0;NSM;;;;;N;;;;;\nE01DE;VARIATION SELECTOR-239;Mn;0;NSM;;;;;N;;;;;\nE01DF;VARIATION SELECTOR-240;Mn;0;NSM;;;;;N;;;;;\nE01E0;VARIATION SELECTOR-241;Mn;0;NSM;;;;;N;;;;;\nE01E1;VARIATION SELECTOR-242;Mn;0;NSM;;;;;N;;;;;\nE01E2;VARIATION SELECTOR-243;Mn;0;NSM;;;;;N;;;;;\nE01E3;VARIATION SELECTOR-244;Mn;0;NSM;;;;;N;;;;;\nE01E4;VARIATION SELECTOR-245;Mn;0;NSM;;;;;N;;;;;\nE01E5;VARIATION SELECTOR-246;Mn;0;NSM;;;;;N;;;;;\nE01E6;VARIATION SELECTOR-247;Mn;0;NSM;;;;;N;;;;;\nE01E7;VARIATION SELECTOR-248;Mn;0;NSM;;;;;N;;;;;\nE01E8;VARIATION SELECTOR-249;Mn;0;NSM;;;;;N;;;;;\nE01E9;VARIATION SELECTOR-250;Mn;0;NSM;;;;;N;;;;;\nE01EA;VARIATION SELECTOR-251;Mn;0;NSM;;;;;N;;;;;\nE01EB;VARIATION SELECTOR-252;Mn;0;NSM;;;;;N;;;;;\nE01EC;VARIATION SELECTOR-253;Mn;0;NSM;;;;;N;;;;;\nE01ED;VARIATION SELECTOR-254;Mn;0;NSM;;;;;N;;;;;\nE01EE;VARIATION SELECTOR-255;Mn;0;NSM;;;;;N;;;;;\nE01EF;VARIATION SELECTOR-256;Mn;0;NSM;;;;;N;;;;;\nF0000;<Plane 15 Private Use, First>;Co;0;L;;;;;N;;;;;\nFFFFD;<Plane 15 Private Use, Last>;Co;0;L;;;;;N;;;;;\n100000;<Plane 16 Private Use, First>;Co;0;L;;;;;N;;;;;\n10FFFD;<Plane 16 Private Use, Last>;Co;0;L;;;;;N;;;;;\n"
  },
  {
    "path": "react_juce/duktape/src-input/builtins.yaml",
    "content": "#\n#  Built-in objects\n#\n\n# YAML conventions:\n#\n#   - Indent by two, indent lists of objects too.\n#   - Quoted used for keys, explicit string values, hex data, attributes.\n#     Not used for classes, built-in ID values, etc, unless necessary.\n#   - Double quotes used throughout to allow escaping.\n#\n# Top level object format is mostly self explanatory, a few notes:\n#\n#    - The \"id\" string is used for referencing objects from property table\n#    - Class names must match array in genbuiltins.py\n#    - If the top level object is a function:\n#      - varargs: if true, function is vararg (nargs = DUK_VARARGS)\n#      - nargs: nargs (ignored if varargs true); if missing, default from 'length' property\n#      - magic: see below\n#      - native: native function name\n#      - callable: true/false, depending on function\n#      - constructable: true/false, depending on function\n#      - special_call: true/false, used for .call(), .apply(), etc which\n#        need special casing in runtime call handling\n#    - To disable an object without removing its metadata, you can\n#      use 'disable: true'.\n#    - If the object is dependent on Duktape configuration, you can make the\n#      object optional using e.g. 'present_if: DUK_USE_BUFFEROBJECT_SUPPORT'.\n#      If the value is a list, the object is present if all listed options are\n#      enabled (logical AND).\n#    - If the object needs a DUK_BIDX_xxx define in Duktape source code, which\n#      also implies it'll get a slot in thr->builtins[] array, use 'bidx: true'.\n#\n# Property format:\n#\n#    - key: verbatim string key, codepoints U+0000...U+00FF map to bytes,\n#           so that \\u0082 is 0x82 prefix, \\u00FF is 0xFF prefix, etc.  Key\n#           can also be a symbol, with the same format as for symbol values.\n#    - value: see below\n#    - attributes: string of format /w?e?c?a?/, e.g. \"wc\" is writable and\n#                  configurable\n#        + w: writable\n#        + e: enumerable\n#        + c: configurable\n#        + a: accessor (determined automatically, not necessary to give explicitly)\n#    - auto_lightfunc: if true (which is default), function property may be\n#      automatically converted to a lightfunc if other automatic lightfunc\n#      conversion criteria are met; use \"auto_lightfunc: false\" to prevent\n#      lightfunc conversion\n#    - May also have feature tags like \"es6: true\" to indicate property\n#      is related to a specific standard\n#    - To disable a property without removing its metadata, you can use\n#      'disable: true'.\n#    - If the property is dependent on Duktape configuration, you can make the\n#      property optional using e.g. 'present_if: DUK_USE_BUFFEROBJECT_SUPPORT'.\n#      List of options is interpreted as for objects (logical AND).\n#\n# Property value format:\n#\n#    - ECMAScript undefined:\n#      - type: undefined\n#    - Plain YAML/JSON null (parses as Python None)\n#      - treated as ECMAScript null\n#    - Plain string:\n#      - treated as plain string, string data as with keys\n#    - Plain symbol:\n#      - type: symbol\n#      - variant: global, wellknown, hidden, userhidden\n#      - string: symbol string without any prefix\n#      - NOTE: ES2015 well-known symbols are local symbols with 'string' as\n#        their description, and a fixed suffix never overlapping with\n#        runtime local symbols\n#      - NOTE: \"hidden symbols\" are Duktape specific internal properties\n#        (called just internal properties in 1.x)\n#    - Plain number:\n#      - treated as a fastint/ieee double\n#    - IEEE double:\n#      - type: double\n#      - bytes: IEEE bytes in big endian format, hex encoded\n#      - NOTE: if you define a NaN, make sure it is in the Duktape normalized\n#        form (see bi_global 'NaN' property): otherwise strange things will\n#        happen with packed duk_tval\n#    - Buffer:\n#      - type: buffer\n#      - NOTE: not supported yet, type is reserved\n#    - Pointer:\n#      - type: pointer\n#      - NOTE: not supported yet, type is reserved\n#    - Lightfunc:\n#      - type: lightfunc\n#      - native: native function name\n#      - magic: -128 to 127\n#      - length: 0 to 15\n#      - nargs: 0 to 14; or varargs: true\n#      - varargs: if true, target has variable arguments\n#    - Reference to a built-in object:\n#      - type: object\n#        id: ID string of target object\n#    - Accessor (setter/getter):\n#      - type: accessor\n#      - getter_id: object ID of getter\n#      - setter_id: object ID of setter\n#    - Native function shorthand; alternative to defining a function as a\n#      native object and referencing it using an ID:\n#      - type: function (implicitly callable)\n#      - callable: default is true\n#      - constructable: default is false\n#      - native: native function name\n#      - length: function .length (optional, defaults to 0)\n#      - nargs: function nargs (optional, defaults to length)\n#      - varargs: if true, function is vararg (nargs = DUK_VARARGS)\n#      - magic: magic value for function (see below)\n#      - name: optional, provides .name property (non-writable, non-enumerable, non-configurable)\n#      - special_call: recognized in shorthand\n#    - Accessor (setter/getter) shorthand:\n#      - type: accessor\n#      - callable: default is true\n#      - constructable: default is false\n#      - getter: native function name\n#      - setter: native function name\n#      - getter_magic: magic value for getter\n#      - setter_magic: magic value for setter\n#      - getter_nargs: nargs value for getter\n#      - setter_nargs: nargs value for setter\n#      - getter_length: length value for getter (0 if missing)\n#      - setter_length: length value for setter (0 if missing)\n#    - Structured object shorthand:\n#      - type: structured\n#      - value: arbitrary JSON-like value\n#      - NOTE: value is converted into object(s) with properties\n#        similarly to JSON.parse() results: properties will be\n#        writable, enumerable, and configurable, inherit from\n#        Object.prototype, etc.\n#\n# Magic format:\n#\n#    - Plain number: direct magic value\n#    - Array iterator magic:\n#      - type: array_iter\n#      - funcname: function name, e.g. \"forEach\"\n#    - Built-in object index:\n#      - type: bidx\n#      - id: id of built-object, idx to thr->builtins[]\n#    - One-argument math function:\n#      - type: math_onearg\n#      - funcname: name of function, e.g. \"cos\"\n#    - Two-argument math function:\n#      - type: math_twoarg\n#      - funcname: name of function, e.g. \"atan2\"\n#    - Typed array constructor\n#      - type: typedarray_constructor\n#      - elem: element type, e.g. \"int8\"\n#      - shift: shift for element size (0 = 1 byte element, 2 = 4 byte element etc)\n\nobjects:\n\n  # internal prototype: implementation specific\n  #  Smjs: Object.prototype\n  #  Rhino: Object.prototype\n  #  V8: *not* Object.prototype, but prototype chain includes Object.prototype\n  # external prototype: apparently not set\n  # external constructor: apparently not set\n  # internal class: implemented specific\n  #  Smjs: \"global\"\n  #  Rhino: \"global\"\n  #  V8: \"global\"\n  #\n  # E5 Sections B.2.1 and B.2.2 describe non-standard properties which are\n  # included below but flagged as extensions.\n\n  - id: bi_global\n    class: global\n    internal_prototype: bi_object_prototype\n    bidx: true\n\n    properties:\n      # 'global' binding giving easy to access to the global object.\n      # Not yet standard, see https://github.com/tc39/proposal-global.\n      - key: \"global\"\n        value:\n          type: object\n          id: bi_global\n        attributes: \"wc\"\n        # This could be stripped when DUK_USE_GLOBAL_BUILTIN is disabled\n        # but keep for now (the property is quite fundamental).\n        present_if: DUK_USE_GLOBAL_BINDING\n\n      - key: \"NaN\"\n        value:\n          type: double\n          bytes: \"7ff8000000000000\"  # DBL_NAN\n        attributes: \"\"\n        present_if: DUK_USE_GLOBAL_BUILTIN\n      - key: \"Infinity\"\n        value:\n          type: double\n          bytes: \"7ff0000000000000\"  # DBL_POSITIVE_INFINITY\n        attributes: \"\"\n        present_if: DUK_USE_GLOBAL_BUILTIN\n      - key: \"undefined\"\n        value:\n          type: undefined\n        attributes: \"\"\n        # This could be stripped when DUK_USE_GLOBAL_BUILTIN is disabled\n        # (\"void 0\" is the same and safer) but it's commonly used so keep.\n\n      - key: \"Object\"\n        value:\n          type: object\n          id: bi_object_constructor\n        present_if: DUK_USE_OBJECT_BUILTIN\n      - key: \"Function\"\n        value:\n          type: object\n          id: bi_function_constructor\n        present_if: DUK_USE_FUNCTION_BUILTIN\n      - key: \"Array\"\n        value:\n          type: object\n          id: bi_array_constructor\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"String\"\n        value:\n          type: object\n          id: bi_string_constructor\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"Boolean\"\n        value:\n          type: object\n          id: bi_boolean_constructor\n        present_if: DUK_USE_BOOLEAN_BUILTIN\n      - key: \"Number\"\n        value:\n          type: object\n          id: bi_number_constructor\n        present_if: DUK_USE_NUMBER_BUILTIN\n      - key: \"Date\"\n        value:\n          type: object\n          id: bi_date_constructor\n        present_if: DUK_USE_DATE_BUILTIN\n      - key: \"RegExp\"\n        value:\n          type: object\n          id: bi_regexp_constructor\n        present_if: DUK_USE_REGEXP_SUPPORT\n      - key: \"Error\"\n        value:\n          type: object\n          id: bi_error_constructor\n      - key: \"EvalError\"\n        value:\n          type: object\n          id: bi_eval_error_constructor\n      - key: \"RangeError\"\n        value:\n          type: object\n          id: bi_range_error_constructor\n      - key: \"ReferenceError\"\n        value:\n          type: object\n          id: bi_reference_error_constructor\n      - key: \"SyntaxError\"\n        value:\n          type: object\n          id: bi_syntax_error_constructor\n      - key: \"TypeError\"\n        value:\n          type: object\n          id: bi_type_error_constructor\n      - key: \"URIError\"\n        value:\n          type: object\n          id: bi_uri_error_constructor\n      - key: \"Math\"\n        value:\n          type: object\n          id: bi_math\n        present_if: DUK_USE_MATH_BUILTIN\n      - key: \"JSON\"\n        value:\n          type: object\n          id: bi_json\n        present_if: DUK_USE_JSON_BUILTIN\n\n      # Duktape specific\n      - key: \"Duktape\"\n        value:\n          type: object\n          id: bi_duktape\n        duktape: true\n        # Remains present even when disabled: needed for error augmentation internally.\n        #present_if: DUK_USE_DUKTAPE_BUILTIN\n\n      # ES2015\n      - key: \"Proxy\"\n        value:\n          type: object\n          id: bi_proxy_constructor\n        es6: true\n        present_if: DUK_USE_ES6_PROXY\n      - key: \"Reflect\"\n        value:\n          type: object\n          id: bi_reflect\n        es6: true\n        present_if: DUK_USE_REFLECT_BUILTIN\n      - key: \"Symbol\"\n        value:\n          type: object\n          id: bi_symbol_constructor\n        es6: true\n        present_if: DUK_USE_SYMBOL_BUILTIN\n      - key: \"Promise\"\n        value:\n          type: object\n          id: bi_promise_constructor\n        es6: true\n        present_if: DUK_USE_PROMISE_BUILTIN\n\n      # Node.js Buffer\n      - key: \"Buffer\"\n        value:\n          type: object\n          id: bi_nodejs_buffer_constructor\n        nodejs_buffer: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n      # TypedArray\n      - key: \"ArrayBuffer\"\n        value:\n          type: object\n          id: bi_arraybuffer_constructor\n        typedarray: true\n        es6: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n      - key: \"DataView\"\n        value:\n          type: object\n          id: bi_dataview_constructor\n        typedarray: true\n        es6: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n      - key: \"Int8Array\"\n        value:\n          type: object\n          id: bi_int8array_constructor\n        typedarray: true\n        es6: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n      - key: \"Uint8Array\"\n        value:\n          type: object\n          id: bi_uint8array_constructor\n        typedarray: true\n        es6: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n      - key: \"Uint8ClampedArray\"\n        value:\n          type: object\n          id: bi_uint8clampedarray_constructor\n        typedarray: true\n        es6: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n      - key: \"Int16Array\"\n        value:\n          type: object\n          id: bi_int16array_constructor\n        typedarray: true\n        es6: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n      - key: \"Uint16Array\"\n        value:\n          type: object\n          id: bi_uint16array_constructor\n        typedarray: true\n        es6: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n      - key: \"Int32Array\"\n        value:\n          type: object\n          id: bi_int32array_constructor\n        typedarray: true\n        es6: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n      - key: \"Uint32Array\"\n        value:\n          type: object\n          id: bi_uint32array_constructor\n        typedarray: true\n        es6: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n      - key: \"Float32Array\"\n        value:\n          type: object\n          id: bi_float32array_constructor\n        typedarray: true\n        es6: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n      - key: \"Float64Array\"\n        value:\n          type: object\n          id: bi_float64array_constructor\n        typedarray: true\n        es6: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n      # Functions\n      - key: \"eval\"\n        value:\n          type: function\n          native: duk_bi_global_object_eval\n          length: 1\n          magic: 15  # see duk_js_call.c\n          special_call: true\n        auto_lightfunc: false  # automatic lightfunc conversion clashes with internal implementation\n        present_if: DUK_USE_GLOBAL_BUILTIN\n      - key: \"parseInt\"\n        value:\n          type: object\n          id: bi_parse_int\n        present_if: DUK_USE_GLOBAL_BUILTIN\n      - key: \"parseFloat\"\n        value:\n          type: object\n          id: bi_parse_float\n        present_if: DUK_USE_GLOBAL_BUILTIN\n      - key: \"isNaN\"\n        value:\n          type: function\n          native: duk_bi_global_object_is_nan\n          length: 1\n        present_if: DUK_USE_GLOBAL_BUILTIN\n      - key: \"isFinite\"\n        value:\n          type: function\n          native: duk_bi_global_object_is_finite\n          length: 1\n        present_if: DUK_USE_GLOBAL_BUILTIN\n      - key: \"decodeURI\"\n        value:\n          type: function\n          native: duk_bi_global_object_decode_uri\n          length: 1\n        present_if: DUK_USE_GLOBAL_BUILTIN\n      - key: \"decodeURIComponent\"\n        value:\n          type: function\n          native: duk_bi_global_object_decode_uri_component\n          length: 1\n        present_if: DUK_USE_GLOBAL_BUILTIN\n      - key: \"encodeURI\"\n        value:\n          type: function\n          native: duk_bi_global_object_encode_uri\n          length: 1\n        present_if: DUK_USE_GLOBAL_BUILTIN\n      - key: \"encodeURIComponent\"\n        value:\n          type: function\n          native: duk_bi_global_object_encode_uri_component\n          length: 1\n        present_if: DUK_USE_GLOBAL_BUILTIN\n\n      # Non-standard extensions: E5 Sections B.2.1 and B.2.2\n      #\n      # \"length\" is not specified explicitly in E5 but it follows the\n      # general argument count rule.  V8 also agrees on the lengths.\n\n      - key: \"escape\"\n        value:\n          type: function\n          native: duk_bi_global_object_escape\n          length: 1\n        section_b: true\n        present_if:\n          - DUK_USE_SECTION_B\n          - DUK_USE_GLOBAL_BUILTIN\n      - key: \"unescape\"\n        value:\n          type: function\n          native: duk_bi_global_object_unescape\n          length: 1\n        section_b: true\n        present_if:\n          - DUK_USE_SECTION_B\n          - DUK_USE_GLOBAL_BUILTIN\n\n      # Encoding API: https://encoding.spec.whatwg.org/\n      - key: \"TextEncoder\"\n        value:\n          type: object\n          id: bi_textencoder_constructor\n        encoding_api: true\n        present_if: DUK_USE_ENCODING_BUILTINS\n      - key: \"TextDecoder\"\n        value:\n          type: object\n          id: bi_textdecoder_constructor\n        encoding_api: true\n        present_if: DUK_USE_ENCODING_BUILTINS\n\n      # High resolution time API: https://www.w3.org/TR/hr-time/\n      # Firefox and Chrome: accessor with 'ec' attributes, setter\n      # allows overwrite.\n      # Use data property with 'wec' for now.\n      - key: \"performance\"\n        value:\n          type: object\n          id: bi_performance\n        attributes: \"wec\"\n        performance_api: true\n        present_if: DUK_USE_PERFORMANCE_BUILTIN\n\n  - id: bi_parse_int\n    class: Function\n    internal_prototype: bi_function_prototype\n    native: duk_bi_global_object_parse_int\n    callable: true\n    constructable: false\n    bidx: false\n    present_if: DUK_USE_OBJECT_BUILTIN\n\n    properties:\n      - key: \"length\"\n        value: 2\n        attributes: \"c\"\n\n  - id: bi_parse_float\n    class: Function\n    internal_prototype: bi_function_prototype\n    native: duk_bi_global_object_parse_float\n    callable: true\n    constructable: false\n    bidx: false\n    present_if: DUK_USE_OBJECT_BUILTIN\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n\n  - id: bi_global_env\n    class: ObjEnv\n    duktape: true\n    bidx: true\n\n    # The internal 'target' property is now part of duk_hobjenv and handled\n    # specially by RAM built-in init code.  ROM built-ins provide an explicit\n    # initializer based on these properties.\n\n    objenv_target: bi_global\n    objenv_has_this: 0\n\n    properties: []\n\n  - id: bi_object_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    native: duk_bi_object_constructor\n    callable: true\n    constructable: true\n    bidx: true\n    present_if: DUK_USE_OBJECT_BUILTIN\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_object_prototype\n        attributes: \"\"\n      - key: \"name\"\n        value: \"Object\"\n        attributes: \"c\"\n\n      - key: \"getPrototypeOf\"\n        value:\n          type: function\n          native: duk_bi_object_getprototype_shared\n          length: 1\n          magic: 1\n      - key: \"setPrototypeOf\"\n        value:\n          type: function\n          native: duk_bi_object_setprototype_shared\n          length: 2\n          magic: 1\n        es6: true\n      - key: \"getOwnPropertyDescriptor\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_get_own_property_descriptor\n          length: 2\n          magic: 0\n      - key: \"getOwnPropertyNames\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_keys_shared\n          length: 1\n          magic: 1\n      - key: \"assign\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_assign\n          length: 2\n          varargs: true\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"create\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_create\n          length: 2\n      - key: \"defineProperty\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_define_property\n          length: 3\n          magic: 0\n      - key: \"defineProperties\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_define_properties\n          length: 2\n      - key: \"seal\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_seal_freeze_shared\n          length: 1\n          magic: 0\n      - key: \"freeze\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_seal_freeze_shared\n          length: 1\n          magic: 1\n      - key: \"preventExtensions\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_prevent_extensions\n          length: 1\n          magic: 0\n      - key: \"isSealed\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_is_sealed_frozen_shared\n          length: 1\n          magic: 0\n      - key: \"isFrozen\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_is_sealed_frozen_shared\n          length: 1\n          magic: 1\n      - key: \"isExtensible\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_is_extensible\n          length: 1\n          magic: 0\n      - key: \"keys\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_keys_shared\n          length: 1\n          magic: 0\n      - key: \"getOwnPropertySymbols\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_keys_shared\n          length: 1\n          magic: 2\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"is\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_is\n          length: 2\n          nargs: 2\n        es6: true\n        present_if: DUK_USE_ES6\n\n  - id: bi_object_prototype\n    class: Object\n    # internal_prototype: null\n    bidx: true\n    # Present even when DUK_USE_OBJECT_BUILTIN disabled.\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_object_constructor\n        attributes: \"wc\"\n        present_if: DUK_USE_OBJECT_BUILTIN\n\n      - key: \"__proto__\"\n        value:\n          type: accessor\n          getter: duk_bi_object_getprototype_shared\n          setter: duk_bi_object_setprototype_shared\n          getter_nargs: 0\n          setter_nargs: 1\n          getter_magic: 0\n          setter_magic: 0\n        attributes: \"c\"  # configurable in ES2015, also V8\n        es6: true  # also non-standard legacy\n        present_if: DUK_USE_OBJECT_BUILTIN\n\n      - key: \"toString\"\n        value:\n          type: function\n          native: duk_bi_object_prototype_to_string\n          length: 0\n        present_if: DUK_USE_OBJECT_BUILTIN\n      - key: \"toLocaleString\"\n        value:\n          type: function\n          native: duk_bi_object_prototype_to_locale_string\n          length: 0\n        present_if: DUK_USE_OBJECT_BUILTIN\n      - key: \"valueOf\"\n        value:\n          type: function\n          native: duk_bi_object_prototype_value_of\n          length: 0\n        present_if: DUK_USE_OBJECT_BUILTIN\n      - key: \"hasOwnProperty\"\n        value:\n          type: function\n          native: duk_bi_object_prototype_has_own_property\n          length: 1\n        present_if: DUK_USE_OBJECT_BUILTIN\n      - key: \"isPrototypeOf\"\n        value:\n          type: function\n          native: duk_bi_object_prototype_is_prototype_of\n          length: 1\n        present_if: DUK_USE_OBJECT_BUILTIN\n      - key: \"propertyIsEnumerable\"\n        value:\n          type: function\n          native: duk_bi_object_prototype_property_is_enumerable\n          length: 1\n        present_if: DUK_USE_OBJECT_BUILTIN\n\n      # __defineGetter, __defineSetter__, __lookupGetter__, __lookupSetter__: ES2017 Annex B\n      # https://tc39.github.io/ecma262/#sec-additional-properties-of-the-object.prototype-object\n\n      - key: \"__defineGetter__\"\n        value:\n          type: function\n          native: duk_bi_object_prototype_defineaccessor\n          length: 2\n          magic: 0  # define getter\n        present_if: DUK_USE_ES8\n      - key: \"__defineSetter__\"\n        value:\n          type: function\n          native: duk_bi_object_prototype_defineaccessor\n          length: 2\n          magic: 1  # define setter\n        present_if: DUK_USE_ES8\n      - key: \"__lookupGetter__\"\n        value:\n          type: function\n          native: duk_bi_object_prototype_lookupaccessor\n          length: 1\n          magic: 0  # lookup getter\n        present_if: DUK_USE_ES8\n      - key: \"__lookupSetter__\"\n        value:\n          type: function\n          native: duk_bi_object_prototype_lookupaccessor\n          length: 1\n          magic: 1  # lookup setter\n        present_if: DUK_USE_ES8\n\n  - id: bi_function_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    varargs: true\n    native: duk_bi_function_constructor\n    callable: true\n    constructable: true\n    bidx: true\n    present_if: DUK_USE_FUNCTION_BUILTIN\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_function_prototype\n        attributes: \"\"\n      - key: \"name\"\n        value: \"Function\"\n        attributes: \"c\"\n\n  # Note, unlike other prototype objects, Function.prototype is itself\n  # a Function and callable.  When invoked, it accepts any arguments\n  # and returns undefined.  It cannot be called as a constructor.\n  # See E5 Section 15.3.4.\n  - id: bi_function_prototype\n    class: Function\n    internal_prototype: bi_object_prototype\n    native: duk_bi_function_prototype\n    callable: true\n    constructable: false\n    bidx: true\n    nargs: 0  # given explicitly because .length is optional\n    # Present even when DUK_USE_FUNCTION_BUILTIN disabled.\n\n    properties:\n      - key: \"length\"\n        value: 0\n        attributes: \"c\"\n        present_if: DUK_USE_FUNCTION_BUILTIN\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_function_constructor\n        attributes: \"wc\"\n        present_if: DUK_USE_FUNCTION_BUILTIN\n\n      # In ES2015 Function.prototype.name is not writable, but is configurable.\n      - key: \"name\"\n        value: \"\"\n        attributes: \"c\"\n        #present_if: DUK_USE_FUNCTION_BUILTIN  # Kept even when prototype is otherwise empty to guarantee a .name for functions\n\n      # test262 ch15/15.3/15.3.4/15.3.4.2/S15.3.4.2_A11 checks that Function.prototype.toString.length\n      # is zero, cannot find specification support for that but 0 is a good value.\n      - key: \"toString\"\n        value:\n          type: function\n          native: duk_bi_function_prototype_to_string\n          length: 0\n        present_if: DUK_USE_FUNCTION_BUILTIN\n      - key: \"apply\"\n        value:\n          type: function\n          native: duk_bi_function_prototype_apply\n          length: 2\n          magic: 1  # see duk_js_call.c\n          special_call: true\n        auto_lightfunc: false  # automatic lightfunc conversion clashes with internal implementation\n        present_if: DUK_USE_FUNCTION_BUILTIN\n      - key: \"call\"\n        value:\n          type: function\n          native: duk_bi_function_prototype_call\n          length: 1\n          magic: 0  # see duk_js_call.c\n          varargs: true\n          special_call: true\n        auto_lightfunc: false  # automatic lightfunc conversion clashes with internal implementation\n        present_if: DUK_USE_FUNCTION_BUILTIN\n      - key: \"bind\"\n        value:\n          type: function\n          native: duk_bi_function_prototype_bind\n          length: 1\n          varargs: true\n        present_if: DUK_USE_FUNCTION_BUILTIN\n\n      # ES2015\n      - key:  # @@hasInstance\n          type: symbol\n          variant: wellknown\n          string: \"Symbol.hasInstance\"\n        value:\n          type: function\n          native: duk_bi_function_prototype_hasinstance\n          length: 1\n        attributes: \"\"\n        es6: true\n        present_if: DUK_USE_SYMBOL_BUILTIN\n\n  # Duktape specific %NativeFunctionPrototype% which provides some getters.\n  #\n  - id: bi_native_function_prototype\n    class: Object\n    internal_prototype: bi_function_prototype\n    native: duk_bi_function_prototype\n    bidx: true\n    duktape: true\n    # Present even when DUK_USE_FUNCTION_BUILTIN disabled.\n\n    properties:\n      - key: \"length\"\n        value:\n          type: accessor\n          getter: duk_bi_native_function_length\n          getter_nargs: 0\n          getter_magic: 0\n          # Setter undefined: direct write fails (defineProperty() works).\n          # This mimics ES2015 function (own property) .length which is\n          # not writable but configurable.\n        attributes: \"c\"\n        #present_if: DUK_USE_FUNCTION_BUILTIN  # Kept to guarantee a .length for lightfuncs\n      - key: \"name\"\n        value:\n          type: accessor\n          getter: duk_bi_native_function_name\n          getter_nargs: 0\n          getter_magic: 0\n          # Setter undefined: direct write fails (defineProperty() works).\n          # This mimics ES2015 function (own property) .name which is\n          # not writable but configurable.\n        attributes: \"c\"\n        #present_if: DUK_USE_FUNCTION_BUILTIN  # Kept to guarantee a .name for lightfuncs\n\n  - id: bi_array_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    varargs: true\n    native: duk_bi_array_constructor\n    callable: true\n    constructable: true\n    bidx: true\n    present_if: DUK_USE_ARRAY_BUILTIN\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_array_prototype\n        attributes: \"\"\n      - key: \"name\"\n        value: \"Array\"\n        attributes: \"c\"\n      - key: \"isArray\"\n        value:\n          type: function\n          native: duk_bi_array_constructor_is_array\n          length: 1\n\n      #- key:  # @@species\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.species\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_array_prototype\n    class: Array\n    internal_prototype: bi_object_prototype\n    bidx: true\n    # Present even when DUK_USE_ARRAY_BUILTIN disabled.\n\n    # An array prototype is an Array itself.  It has a length property initialized to 0,\n    # with property attributes: writable, non-configurable, non-enumerable.  The attributes\n    # are not specified very explicitly for the prototype, but are given for Array instances\n    # in E5 Section 15.4.5.2 (and this matches the behavior of e.g. V8).\n\n    properties:\n      # With duk_harray added to the internal representation, .length is now virtual.\n      #- key: \"length\"\n      #  value: 0\n      #  attributes: \"w\"\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_array_constructor\n        attributes: \"wc\"\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"toString\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_to_string\n          length: 0\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"toLocaleString\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_join_shared\n          length: 0\n          magic: 1  # magic: to_locale_string, here 1\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"concat\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_concat\n          length: 1\n          varargs: true\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"join\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_join_shared\n          length: 1\n          magic: 0  # magic: to_locale_string, here 0\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"pop\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_pop\n          length: 0\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"push\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_push\n          length: 1\n          varargs: true\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"reverse\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_reverse\n          length: 0\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"shift\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_shift\n          length: 0\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"slice\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_slice\n          length: 2\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"sort\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_sort\n          length: 1\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"splice\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_splice\n          length: 2\n          varargs: true\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"unshift\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_unshift\n          length: 1\n          varargs: true\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"indexOf\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_indexof_shared\n          length: 1\n          varargs: true\n          magic: 1  # magic: idx_step = +1\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"lastIndexOf\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_indexof_shared\n          length: 1\n          varargs: true\n          magic: -1  # magic: idx_step = -1\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"every\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_iter_shared\n          length: 1\n          nargs: 2\n          magic:\n            type: array_iter\n            funcname: \"every\"  # BI_ARRAY_ITER_EVERY\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"some\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_iter_shared\n          length: 1\n          nargs: 2\n          magic:\n            type: array_iter\n            funcname: \"some\"  # BI_ARRAY_ITER_SOME\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"forEach\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_iter_shared\n          length: 1\n          nargs: 2\n          magic:\n            type: array_iter\n            funcname: \"forEach\"  # BI_ARRAY_ITER_FOREACH\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"map\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_iter_shared\n          length: 1\n          nargs: 2\n          magic:\n            type: array_iter\n            funcname: \"map\"  # BI_ARRAY_ITER_MAP\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"filter\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_iter_shared\n          length: 1\n          nargs: 2\n          magic:\n            type: array_iter\n            funcname: filter  # BI_ARRAY_ITER_FILTER\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"reduce\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_reduce_shared\n          length: 1\n          varargs: true\n          magic: 1  # magic: idx_step = +1\n        present_if: DUK_USE_ARRAY_BUILTIN\n      - key: \"reduceRight\"\n        value:\n          type: function\n          native: duk_bi_array_prototype_reduce_shared\n          length: 1\n          varargs: true\n          magic: -1  # magic: idx_step = -1\n        present_if: DUK_USE_ARRAY_BUILTIN\n\n      #- key:  # @@iterator\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.iterator\"\n      #  value: XXX\n      #  es6: true\n      #- key:  # @@unscopables\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.unscopables\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_string_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    varargs: true\n    native: duk_bi_string_constructor\n    callable: true\n    constructable: true\n    bidx: true\n    present_if: DUK_USE_STRING_BUILTIN\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_string_prototype\n        attributes: \"\"\n      - key: \"name\"\n        value: \"String\"\n        attributes: \"c\"\n\n      - key: \"fromCharCode\"\n        value:\n          type: function\n          native: duk_bi_string_constructor_from_char_code\n          length: 1\n          varargs: true\n      - key: \"fromCodePoint\"\n        value:\n          type: function\n          native: duk_bi_string_constructor_from_code_point\n          length: 1\n          varargs: true\n        present_if: DUK_USE_ES6\n\n  - id: bi_string_prototype\n    class: String\n    internal_prototype: bi_object_prototype\n    bidx: true\n    # Present even when DUK_USE_STRING_BUILTIN disabled.\n\n    # String prototype is a String instance and must have length value 0.\n    # This is supplied by the String instance virtual properties and does\n    # not need to be included in init data.\n    #\n    # Unlike Array.prototype.length, String.prototype.length has the default\n    # \"length\" attributes of built-in objects: non-writable, non-enumerable,\n    # non-configurable.\n\n    #length: 0,  # omitted; non-writable, non-enumerable, non-configurable\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_string_constructor\n        attributes: \"wc\"\n        present_if: DUK_USE_STRING_BUILTIN\n\n      # Internal empty string value.  Note that this value is not writable\n      # which prevents a String instance's internal value also from being\n      # written with standard methods.  The internal code creating String\n      # instances has no such issues.\n      - key:\n          type: symbol\n          variant: hidden\n          string: \"Value\"\n        value: \"\"\n        attributes: \"\"\n        duktape: true\n\n      - key: \"toString\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_to_string\n          length: 0\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"valueOf\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_to_string  # share native function, behavior is identical\n          length: 0\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"charAt\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_char_at\n          length: 1\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"charCodeAt\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_char_code_at\n          length: 1\n          magic: 0\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"codePointAt\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_char_code_at\n          length: 1\n          magic: 1\n        es6: true\n        present_if:\n          - DUK_USE_ES6\n          - DUK_USE_STRING_BUILTIN\n      - key: \"concat\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_concat\n          length: 1\n          varargs: true\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"indexOf\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_indexof_shared\n          length: 1\n          nargs: 2\n          magic: 0  # magic = 0 -> indexOf\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"lastIndexOf\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_indexof_shared\n          length: 1\n          nargs: 2\n          magic: 1  # magic = 1 -> lastIndexOf\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"localeCompare\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_locale_compare\n          length: 1\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"match\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_match\n          length: 1\n        present_if:\n          - DUK_USE_STRING_BUILTIN\n          - DUK_USE_REGEXP_SUPPORT\n      - key: \"replace\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_replace\n          length: 2\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"search\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_search\n          length: 1\n        present_if:\n          - DUK_USE_STRING_BUILTIN\n          - DUK_USE_REGEXP_SUPPORT\n      - key: \"slice\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_slice\n          length: 2\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"split\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_split\n          length: 2\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"substring\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_substring\n          length: 2\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"toLowerCase\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_caseconv_shared\n          length: 0\n          magic: 0  # magic = uppercase\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"toLocaleLowerCase\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_caseconv_shared\n          length: 0\n          magic: 0  # magic = uppercase; no locale specific conversion now\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"toUpperCase\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_caseconv_shared\n          length: 0\n          magic: 1  # magic = uppercase\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"toLocaleUpperCase\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_caseconv_shared\n          length: 0\n          magic: 1  # magic = uppercase; no locale specific conversion now\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"trim\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_trim\n          length: 0\n        present_if: DUK_USE_STRING_BUILTIN\n      - key: \"repeat\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_repeat\n          length: 1\n          nargs: 1\n        present_if:\n          - DUK_USE_ES6\n          - DUK_USE_STRING_BUILTIN\n      - key: \"startsWith\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_startswith_endswith\n          length: 1\n          nargs: 2\n          magic: 0  # 0=startsWith\n        present_if:\n          - DUK_USE_ES6\n          - DUK_USE_STRING_BUILTIN\n      - key: \"endsWith\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_startswith_endswith\n          length: 1\n          nargs: 2\n          magic: 1  # 1=endsWith\n        present_if:\n          - DUK_USE_ES6\n          - DUK_USE_STRING_BUILTIN\n      - key: \"includes\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_includes\n          length: 1\n          nargs: 2\n        present_if:\n          - DUK_USE_ES6\n          - DUK_USE_STRING_BUILTIN\n\n      # Non-standard extension: E5 Section B.2.3\n\n      - key: \"substr\"\n        value:\n          type: function\n          native: duk_bi_string_prototype_substr\n          length: 2\n        section_b: true\n        present_if:\n          - DUK_USE_STRING_BUILTIN\n          - DUK_USE_SECTION_B\n\n      #- key:  # @@iterator\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.iterator\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_boolean_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    native: duk_bi_boolean_constructor\n    callable: true\n    constructable: true\n    bidx: true\n    present_if: DUK_USE_BOOLEAN_BUILTIN\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_boolean_prototype\n        attributes: \"\"\n      - key: \"name\"\n        value: \"Boolean\"\n        attributes: \"c\"\n\n  - id: bi_boolean_prototype\n    class: Boolean\n    internal_prototype: bi_object_prototype\n    bidx: true\n    # Present even when DUK_USE_BOOLEAN_BUILTIN disabled.\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_boolean_constructor\n        attributes: \"wc\"\n        present_if: DUK_USE_BOOLEAN_BUILTIN\n\n      # Internal false boolean value.  Note that this value is not writable\n      # which prevents a Boolean instance's internal value also from being\n      # written with standard methods.  The internal code creating Boolean\n      # instances has no such issues.\n      - key:\n          type: symbol\n          variant: hidden\n          string: \"Value\"\n        value: false\n        attributes: \"\"\n        duktape: true\n\n      - key: \"toString\"\n        value:\n          type: function\n          native: duk_bi_boolean_prototype_tostring_shared\n          length: 0\n          magic: 1  # magic = coerce_tostring\n        present_if: DUK_USE_BOOLEAN_BUILTIN\n      - key: \"valueOf\"\n        value:\n          type: function\n          native: duk_bi_boolean_prototype_tostring_shared\n          length: 0\n          magic: 0  # magic = coerce_tostring\n        present_if: DUK_USE_BOOLEAN_BUILTIN\n\n  - id: bi_number_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    varargs: true\n    native: duk_bi_number_constructor\n    callable: true\n    constructable: true\n    bidx: true\n    present_if: DUK_USE_NUMBER_BUILTIN\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_number_prototype\n        attributes: \"\"\n      - key: \"name\"\n        value: \"Number\"\n        attributes: \"c\"\n      - key: \"MAX_VALUE\"\n        value:\n          type: double\n          bytes: \"7fefffffffffffff\"  # DBL_MAX_DOUBLE\n        attributes: \"\"\n      - key: \"MIN_VALUE\"\n        value:\n          type: double\n          bytes: \"0000000000000001\"  # DBL_MIN_DOUBLE\n        attributes: \"\"\n      - key: \"NaN\"\n        value:\n          type: double\n          bytes: \"7ff8000000000000\"  # DBL_NAN\n        attributes: \"\"\n      - key: \"POSITIVE_INFINITY\"\n        value:\n          type: double\n          bytes: \"7ff0000000000000\"  # DBL_POSITIVE_INFINITY\n        attributes: \"\"\n      - key: \"NEGATIVE_INFINITY\"\n        value:\n          type: double\n          bytes: \"fff0000000000000\"  # DBL_NEGATIVE_INFINITY\n        attributes: \"\"\n      - key: \"EPSILON\"\n        value:\n          type: double\n          bytes: \"3cb0000000000000\"   # 3ff0000000000001 - 3ff0000000000000 = 3cb0000000000000\n        attributes: \"\"\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"MAX_SAFE_INTEGER\"\n        value:\n          # >>> struct.pack('>d', 9007199254740991.0).encode('hex')\n          # '433fffffffffffff'\n          type: double\n          bytes: \"433fffffffffffff\"\n        attributes: \"\"\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"MIN_SAFE_INTEGER\"\n        value:\n          # >>> struct.pack('>d', -9007199254740991.0).encode('hex')\n          # 'c33fffffffffffff'\n          type: double\n          bytes: \"c33fffffffffffff\"\n        attributes: \"\"\n        es6: true\n        present_if: DUK_USE_ES6\n\n      - key: \"isFinite\"\n        value:\n          type: function\n          native: duk_bi_number_check_shared\n          length: 1\n          magic: 0\n        attributes: \"wc\"\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"isInteger\"\n        value:\n          type: function\n          native: duk_bi_number_check_shared\n          length: 1\n          magic: 1\n        attributes: \"wc\"\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"isNaN\"\n        value:\n          type: function\n          native: duk_bi_number_check_shared\n          length: 1\n          magic: 2\n        attributes: \"wc\"\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"isSafeInteger\"\n        value:\n          type: function\n          native: duk_bi_number_check_shared\n          length: 1\n          magic: 3\n        attributes: \"wc\"\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"parseInt\"  # Must map to the exactly same object as global parseInt()\n        value:\n          type: object\n          id: bi_parse_int\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"parseFloat\"  # Must map to the exactly same object as global parseFloat()\n        value:\n          type: object\n          id: bi_parse_float\n        es6: true\n        present_if: DUK_USE_ES6\n\n  - id: bi_number_prototype\n    class: Number\n    internal_prototype: bi_object_prototype\n    bidx: true\n    # Present even when DUK_USE_NUMBER_BUILTIN disabled.\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_number_constructor\n        attributes: \"wc\"\n        present_if: DUK_USE_NUMBER_BUILTIN\n\n    # Internal 0.0 number value.  Note that this value is not writable\n    # which prevents a Number instance's internal value also from being\n    # written with standard methods.  The internal code creating Number\n    # instances has no such issues.\n    #\n    # Number.prototype is a Number itself in ES5.1 and ES2016+.  It was\n    # briefly made a non-Number in ES2015 but this change was reverted\n    # in ES2016.\n      - key:\n          type: symbol\n          variant: hidden\n          string: \"Value\"\n        value: 0.0\n        attributes: \"\"\n        duktape: true\n\n      - key: \"toString\"\n        value:\n          type: function\n          native: duk_bi_number_prototype_to_string\n          length: 1\n        present_if: DUK_USE_NUMBER_BUILTIN\n      - key: \"toLocaleString\"\n        value:\n          type: function\n          native: duk_bi_number_prototype_to_locale_string\n          length: 1\n        present_if: DUK_USE_NUMBER_BUILTIN\n      - key: \"valueOf\"\n        value:\n          type: function\n          native: duk_bi_number_prototype_value_of\n          length: 0\n        present_if: DUK_USE_NUMBER_BUILTIN\n      - key: \"toFixed\"\n        value:\n          type: function\n          native: duk_bi_number_prototype_to_fixed\n          length: 1\n        present_if: DUK_USE_NUMBER_BUILTIN\n      - key: \"toExponential\"\n        value:\n          type: function\n          native: duk_bi_number_prototype_to_exponential\n          length: 1\n        present_if: DUK_USE_NUMBER_BUILTIN\n      - key: \"toPrecision\"\n        value:\n          type: function\n          native: duk_bi_number_prototype_to_precision\n          length: 1\n        present_if: DUK_USE_NUMBER_BUILTIN\n\n  - id: bi_date_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    varargs: true\n    native: duk_bi_date_constructor\n    callable: true\n    constructable: true\n    bidx: true\n    present_if: DUK_USE_DATE_BUILTIN\n\n    properties:\n      - key: \"length\"\n        value: 7\n        attributes: \"c\"\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_date_prototype\n        attributes: \"\"\n      - key: \"name\"\n        value: \"Date\"\n        attributes: \"c\"\n\n      - key: \"parse\"\n        value:\n          type: function\n          native: duk_bi_date_constructor_parse\n          length: 1\n      - key: \"UTC\"\n        value:\n          type: function\n          native: duk_bi_date_constructor_utc\n          length: 7\n          varargs: true\n      - key: \"now\"\n        value:\n          type: function\n          native: duk_bi_date_constructor_now\n          length: 0\n\n  - id: bi_date_prototype\n    class: Date\n    internal_prototype: bi_object_prototype\n    bidx: true\n    present_if: DUK_USE_DATE_BUILTIN\n\n    # The Date prototype is an instance of Date with [[PrimitiveValue]] NaN.\n    #\n    # Setters with optional arguments must be varargs functions because\n    # they must detect the number of parameters actually given (cannot\n    # assume parameters not given are undefined).\n    #\n    # Date.prototype.valueOf() and Date.prototype.getTime() have identical\n    # behavior so they share the same C function, but have different\n    # function instances.\n    #\n    # Getters, setters, and string conversion functions use shared native\n    # helpers and the function \"magic\" value is used to pass flags and\n    # parameters to the helpers.\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_date_constructor\n        attributes: \"wc\"\n\n      # Internal date value (E5 Section 15.9.5).\n      #\n      # Note: the value is writable, as you can e.g. do the following (V8):\n      #  > Date.prototype.toString()\n      #  \"Invalid Date\"\n      #  > Date.prototype.setYear(2010)\n      #  1262296800000\n      #  > Date.prototype.toString()\n      #  \"Fri Jan 01 2010 00:00:00 GMT+0200 (EET)\"\n\n      - key:\n          type: symbol\n          variant: hidden\n          string: \"Value\"\n        value:\n          type: double\n          bytes: \"7ff8000000000000\"  # DBL_NAN\n        attributes: \"w\"\n        duktape: true\n\n      # NOTE: The magic values for Date prototype are special.  The actual control\n      # flags needed for the built-ins don't fit into LIGHTFUNC magic field, so\n      # the values here are indices to duk__date_magics[] in duk_bi_date.c which\n      # contains the actual control flags.  Magic values here must be kept in strict\n      # sync with duk_bi_date.c!\n\n      - key: \"toString\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_tostring_shared\n          length: 0\n          magic: 0\n      - key: \"toDateString\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_tostring_shared\n          length: 0\n          magic: 1\n      - key: \"toTimeString\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_tostring_shared\n          length: 0\n          magic: 2\n      - key: \"toLocaleString\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_tostring_shared\n          length: 0\n          magic: 3\n      - key: \"toLocaleDateString\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_tostring_shared\n          length: 0\n          magic: 4\n      - key: \"toLocaleTimeString\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_tostring_shared\n          length: 0\n          magic: 5\n      - key: \"toUTCString\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_tostring_shared\n          length: 0\n          magic: 6\n      - key: \"toISOString\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_tostring_shared\n          length: 0\n          magic: 7\n      - key: \"toJSON\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_to_json\n          length: 1\n      - key: \"valueOf\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_value_of\n          length: 0\n      - key: \"getTime\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_value_of  # Native function shared on purpose\n          length: 0\n      - key: \"getFullYear\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 8\n      - key: \"getUTCFullYear\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 9\n      - key: \"getMonth\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 10\n      - key: \"getUTCMonth\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 11\n      - key: \"getDate\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 12\n      - key: \"getUTCDate\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 13\n      - key: \"getDay\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 14\n      - key: \"getUTCDay\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 15\n      - key: \"getHours\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 16\n      - key: \"getUTCHours\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 17\n      - key: \"getMinutes\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 18\n      - key: \"getUTCMinutes\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 19\n      - key: \"getSeconds\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 20\n      - key: \"getUTCSeconds\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 21\n      - key: \"getMilliseconds\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 22\n      - key: \"getUTCMilliseconds\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 23\n      - key: \"getTimezoneOffset\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_timezone_offset\n          length: 0\n      - key: \"setTime\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_time\n          length: 1\n      - key: \"setMilliseconds\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_shared\n          length: 1\n          magic: 24\n      - key: \"setUTCMilliseconds\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_shared\n          length: 1\n          magic: 25\n      - key: \"setSeconds\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_shared\n          length: 2\n          varargs: true\n          magic: 26\n      - key: \"setUTCSeconds\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_shared\n          length: 2\n          varargs: true\n          magic: 27\n      - key: \"setMinutes\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_shared\n          length: 3\n          varargs: true\n          magic: 28\n      - key: \"setUTCMinutes\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_shared\n          length: 3\n          varargs: true\n          magic: 29\n      - key: \"setHours\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_shared\n          length: 4\n          varargs: true\n          magic: 30\n      - key: \"setUTCHours\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_shared\n          length: 4\n          varargs: true\n          magic: 31\n      - key: \"setDate\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_shared\n          length: 1\n          magic: 32\n      - key: \"setUTCDate\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_shared\n          length: 1\n          magic: 33\n      - key: \"setMonth\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_shared\n          length: 2\n          varargs: true\n          magic: 34\n      - key: \"setUTCMonth\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_shared\n          length: 2\n          varargs: true\n          magic: 35\n      - key: \"setFullYear\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_shared\n          length: 3\n          varargs: true\n          magic: 36\n      - key: \"setUTCFullYear\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_shared\n          length: 3\n          varargs: true\n          magic: 37\n      # Note: toGMTString() is required to initially be the same Function\n      # object as the initial Date.prototype.toUTCString.  In other words\n      # the following must compare true:\n      #\n      #   Date.prototype.toGMTString === Date.prototype.toUTCString.\n      #\n      # This is currently handled using a small tweak in duk_hthread_builtins.c\n      # (for RAM objects) and genbuiltins.py (for ROM objects).\n      #\n      # Note that while Smjs respects the requirement in E5 Section B.2.6,\n      # V8 does not.\n      - key: \"toGMTString\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_tostring_shared\n          length: 0\n          magic: 6\n        section_b: true\n\n      # Non-standard extensions: E5 Section B.2.4, B.2.5, B.2.6\n      #\n      # \"length\" values are not given explicitly but follows the general rule.\n      # The lengths below agree with V8.\n\n      - key: \"getYear\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_get_shared\n          length: 0\n          magic: 38\n        section_b: true\n      - key: \"setYear\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_set_shared\n          length: 1\n          magic: 39\n        section_b: true\n\n      - key:  # @@toPrimitive\n          type: symbol\n          variant: wellknown\n          string: \"Symbol.toPrimitive\"\n        value:\n          type: function\n          native: duk_bi_date_prototype_toprimitive\n          length: 1\n          name: \"[Symbol.toPrimitive]\"\n        attributes: \"c\"\n        es6: true\n        present_if: DUK_USE_SYMBOL_BUILTIN\n\n  - id: bi_regexp_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    native: duk_bi_regexp_constructor\n    callable: true\n    constructable: true\n    bidx: true\n    present_if: DUK_USE_REGEXP_SUPPORT\n\n    properties:\n      - key: \"length\"\n        value: 2\n        attributes: \"c\"\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_regexp_prototype\n        attributes: \"\"\n      - key: \"name\"\n        value: \"RegExp\"\n        attributes: \"c\"\n\n      #- key:  # @@species\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.species\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_regexp_prototype\n    class: Object  # Object in ES2015; RegExp in ES5\n    internal_prototype: bi_object_prototype\n    bidx: true\n    present_if: DUK_USE_REGEXP_SUPPORT\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_regexp_constructor\n        attributes: \"wc\"\n\n      # In ES2015 RegExp.prototype is no longer a RegExp instance.\n\n      # \"lastIndex\" is writable, even in the RegExp.prototype object.\n      # This matches at least V8.\n      - key: \"lastIndex\"\n        value: 0\n        attributes: \"w\"\n\n      - key: \"exec\"\n        value:\n          type: function\n          native: duk_bi_regexp_prototype_exec\n          length: 1\n      - key: \"test\"\n        value:\n          type: function\n          native: duk_bi_regexp_prototype_test\n          length: 1\n      - key: \"toString\"\n        value:\n          type: function\n          native: duk_bi_regexp_prototype_tostring\n          length: 0\n\n      # In ES2015 .source, .global, .ignoreCase, etc are accessors.\n      # .flags is ES2015 but must be present because the constructor now\n      # relies on its presence for e.g. new RegExp(/foo/gim).\n\n      - key: \"flags\"\n        value:\n          type: accessor\n          getter: duk_bi_regexp_prototype_flags\n          getter_nargs: 0\n          getter_magic: 0\n          # setter undefined\n        attributes: \"c\"\n        es6: true\n\n      - key: \"source\"\n        value:\n          type: accessor\n          getter: duk_bi_regexp_prototype_shared_getter\n          getter_nargs: 0\n          getter_magic: 16  # default case in shared getter (value quite arbitrary)\n          # setter undefined\n        attributes: \"c\"\n      - key: \"global\"\n        value:\n          type: accessor\n          getter: duk_bi_regexp_prototype_shared_getter\n          getter_nargs: 0\n          getter_magic: 0\n          # setter undefined\n        attributes: \"c\"\n      - key: \"ignoreCase\"\n        value:\n          type: accessor\n          getter: duk_bi_regexp_prototype_shared_getter\n          getter_nargs: 0\n          getter_magic: 1\n          # setter undefined\n        attributes: \"c\"\n      - key: \"multiline\"\n        value:\n          type: accessor\n          getter: duk_bi_regexp_prototype_shared_getter\n          getter_nargs: 0\n          getter_magic: 2\n          # setter undefined\n        attributes: \"c\"\n      # .sticky and .unicode commented out; don't provide until implemented\n      # to avoid interfering with application feature detection code\n      #- key: \"sticky\"\n      #  value:\n      #    type: accessor\n      #    getter: duk_bi_regexp_prototype_shared_getter\n      #    getter_nargs: 0\n      #    getter_magic: 3\n      #    # setter undefined\n      #  attributes: \"c\"\n      #  es6: true\n      #  present_if: DUK_USE_ES6\n      #- key: \"unicode\"\n      #  value:\n      #    type: accessor\n      #    getter: duk_bi_regexp_prototype_shared_getter\n      #    getter_nargs: 0\n      #    getter_magic: 4\n      #    # setter undefined\n      #  attributes: \"c\"\n      #  es6: true\n      #  present_if: DUK_USE_ES6\n\n      #- key:  # @@match\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.match\"\n      #  value: XXX\n      #  es6: true\n      #- key:  # @@replace\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.replace\"\n      #  value: XXX\n      #  es6: true\n      #- key:  # @@search\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.search\"\n      #  value: XXX\n      #  es6: true\n      #- key:  # @@split\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.split\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_error_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    native: duk_bi_error_constructor_shared\n    callable: true\n    constructable: true\n    magic:\n      type: bidx\n      id: bi_error_prototype\n    bidx: true\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_error_prototype\n        attributes: \"\"\n      - key: \"name\"\n        value: \"Error\"\n        attributes: \"c\"\n\n  - id: bi_error_prototype\n    class: Error\n    internal_prototype: bi_object_prototype\n    bidx: true\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_error_constructor\n        attributes: \"wc\"\n\n      # Standard properties; property attributes:\n      #\n      # \"message\" is writable and deletable.  This matches the default\n      # attributes of \"wc\".  V8 and Smjs both match this.\n      #\n      # \"name\" is writable and deletable.  This matches the default\n      # attributes too.  Smjs behaves like this, but in V8 \"name\" is\n      # non-writable:\n      #\n      #  > Object.getOwnPropertyDescriptor(Error.prototype, \"name\")\n      #  { value: \"Error\",\n      #    writable: false,\n      #    enumerable: false,\n      #    configurable: false }\n      #\n      # We go with the standard attributes (\"wc\").\n\n      - key: \"name\"\n        value: \"Error\"\n      - key: \"message\"\n        value: \"\"\n\n      # Custom properties\n\n      - key: \"stack\"\n        value:\n          type: accessor\n          getter: duk_bi_error_prototype_stack_getter\n          setter: duk_bi_error_prototype_stack_setter\n          getter_nargs: 0\n          setter_nargs: 1\n          getter_magic: 0\n          setter_magic: 0\n        attributes: \"c\"\n        duktape: true\n      - key: \"fileName\"\n        value:\n          type: accessor\n          getter: duk_bi_error_prototype_filename_getter\n          setter: duk_bi_error_prototype_filename_setter\n          getter_nargs: 0\n          setter_nargs: 1\n          getter_magic: 0\n          setter_magic: 0\n        attributes: \"c\"\n        duktape: true\n      - key: \"lineNumber\"\n        value:\n          type: accessor\n          getter: duk_bi_error_prototype_linenumber_getter\n          setter: duk_bi_error_prototype_linenumber_setter\n          getter_nargs: 0\n          setter_nargs: 1\n          getter_magic: 0\n          setter_magic: 0\n        attributes: \"c\"\n        duktape: true\n\n      - key: \"toString\"\n        value:\n          type: function\n          native: duk_bi_error_prototype_to_string\n          length: 0\n\n  # NOTE: Error subclass prototypes have an empty \"message\" property, even\n  # though one is inherited already from Error prototype (E5 Section 15.11.7.10).\n  #\n  # V8 does not respect this: Error subclasses (\"native Errors\" in E5 spec)\n  # do not have a \"message\" property at all.  Also, in V8 their \"name\" property\n  # is not writable and configurable as E5 requires.\n\n  - id: bi_eval_error_constructor\n    class: Function\n    internal_prototype: bi_error_constructor\n    native: duk_bi_error_constructor_shared\n    callable: true\n    constructable: true\n    magic:\n      type: bidx\n      id: bi_eval_error_prototype\n    bidx: true\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_eval_error_prototype\n        attributes: \"\"\n      - key: \"name\"\n        value: \"EvalError\"\n        attributes: \"c\"\n\n  - id: bi_eval_error_prototype\n    class: Error\n    internal_prototype: bi_error_prototype\n    bidx: true\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_eval_error_constructor\n        attributes: \"wc\"\n      - key: \"name\"\n        value: \"EvalError\"\n      - key: \"message\"\n        value: \"\"\n\n  - id: bi_range_error_constructor\n    class: Function\n    internal_prototype: bi_error_constructor\n    native: duk_bi_error_constructor_shared\n    callable: true\n    constructable: true\n    magic:\n      type: bidx\n      id: bi_range_error_prototype\n    bidx: true\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_range_error_prototype\n        attributes: \"\"\n      - key: \"name\"\n        value: \"RangeError\"\n        attributes: \"c\"\n\n  - id: bi_range_error_prototype\n    class: Error\n    internal_prototype: bi_error_prototype\n    bidx: true\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_range_error_constructor\n        attributes: \"wc\"\n      - key: \"name\"\n        value: \"RangeError\"\n      - key: \"message\"\n        value: \"\"\n\n  - id: bi_reference_error_constructor\n    class: Function\n    internal_prototype: bi_error_constructor\n    native: duk_bi_error_constructor_shared\n    callable: true\n    constructable: true\n    magic:\n      type: bidx\n      id: bi_reference_error_prototype\n    bidx: true\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_reference_error_prototype\n        attributes: \"\"\n      - key: \"name\"\n        value: \"ReferenceError\"\n        attributes: \"c\"\n\n  - id: bi_reference_error_prototype\n    class: Error\n    internal_prototype: bi_error_prototype\n    bidx: true\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_reference_error_constructor\n        attributes: \"wc\"\n      - key: \"name\"\n        value: \"ReferenceError\"\n      - key: \"message\"\n        value: \"\"\n\n  - id: bi_syntax_error_constructor\n    class: Function\n    internal_prototype: bi_error_constructor\n    native: duk_bi_error_constructor_shared\n    callable: true\n    constructable: true\n    magic:\n      type: bidx\n      id: bi_syntax_error_prototype\n    bidx: true\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_syntax_error_prototype\n        attributes: \"\"\n      - key: \"name\"\n        value: \"SyntaxError\"\n        attributes: \"c\"\n\n  - id: bi_syntax_error_prototype\n    class: Error\n    internal_prototype: bi_error_prototype\n    bidx: true\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_syntax_error_constructor\n        attributes: \"wc\"\n      - key: \"name\"\n        value: \"SyntaxError\"\n      - key: \"message\"\n        value: \"\"\n\n  - id: bi_type_error_constructor\n    class: Function\n    internal_prototype: bi_error_constructor\n    native: duk_bi_error_constructor_shared\n    callable: true\n    constructable: true\n    magic:\n      type: bidx\n      id: bi_type_error_prototype\n    bidx: true\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_type_error_prototype\n        attributes: \"\"\n      - key: \"name\"\n        value: \"TypeError\"\n        attributes: \"c\"\n\n  - id: bi_type_error_prototype\n    class: Error\n    internal_prototype: bi_error_prototype\n    bidx: true\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_type_error_constructor\n        attributes: \"wc\"\n      - key: \"name\"\n        value: \"TypeError\"\n      - key: \"message\"\n        value: \"\"\n\n  - id: bi_uri_error_constructor\n    class: Function\n    internal_prototype: bi_error_constructor\n    native: duk_bi_error_constructor_shared\n    callable: true\n    constructable: true\n    magic:\n      type: bidx\n      id: bi_uri_error_prototype\n    bidx: true\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_uri_error_prototype\n        attributes: \"\"\n      - key: \"name\"\n        value: \"URIError\"\n        attributes: \"c\"\n\n  - id: bi_uri_error_prototype\n    class: Error\n    internal_prototype: bi_error_prototype\n    bidx: true\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_uri_error_constructor\n        attributes: \"wc\"\n      - key: \"name\"\n        value: \"URIError\"\n      - key: \"message\"\n        value: \"\"\n\n  - id: bi_math\n    class: Math\n    internal_prototype: bi_object_prototype\n    bidx: false\n    present_if: DUK_USE_MATH_BUILTIN\n\n    # apparently no external \"prototype\" property\n    # apparently no external \"constructor\" property\n\n    properties:\n      - key: \"E\"\n        value:\n          type: double\n          bytes: \"4005bf0a8b145769\"  # DBL_E\n        attributes: \"\"\n      - key: \"LN10\"\n        value:\n          type: double\n          bytes: \"40026bb1bbb55516\"  # DBL_LN10\n        attributes: \"\"\n      - key: \"LN2\"\n        value:\n          type: double\n          bytes: \"3fe62e42fefa39ef\"  # DBL_LN2\n        attributes: \"\"\n      - key: \"LOG2E\"\n        value:\n          type: double\n          bytes: \"3ff71547652b82fe\"  # DBL_LOG2E\n        attributes: \"\"\n      - key: \"LOG10E\"\n        value:\n          type: double\n          bytes: \"3fdbcb7b1526e50e\"  # DBL_LOG10E\n        attributes: \"\"\n      - key: \"PI\"\n        value:\n          type: double\n          bytes: \"400921fb54442d18\"  # DBL_PI\n        attributes: \"\"\n      - key: \"SQRT1_2\"\n        value:\n          type: double\n          bytes: \"3fe6a09e667f3bcd\"  # DBL_SQRT1_2\n        attributes: \"\"\n      - key: \"SQRT2\"\n        value:\n          type: double\n          bytes: \"3ff6a09e667f3bcd\"  # DBL_SQRT2\n        attributes: \"\"\n\n      - key: \"abs\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"fabs\"\n      - key: \"acos\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"acos\"\n      - key: \"asin\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"asin\"\n      - key: \"atan\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"atan\"\n      - key: \"atan2\"\n        value:\n          type: function\n          native: duk_bi_math_object_twoarg_shared\n          length: 2\n          magic:\n            type: math_twoarg\n            funcname: \"atan2\"\n      - key: \"cbrt\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"cbrt\"\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"ceil\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"ceil\"\n      - key: \"clz32\"\n        value:\n          type: function\n          native: duk_bi_math_object_clz32\n          length: 1\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"cos\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"cos\"\n      - key: \"exp\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"exp\"\n      - key: \"floor\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"floor\"\n      - key: \"hypot\"\n        value:\n          type: function\n          native: duk_bi_math_object_hypot\n          length: 2\n          varargs: true\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"imul\"\n        value:\n          type: function\n          native: duk_bi_math_object_imul\n          length: 2\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"log\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"log\"\n      - key: \"log2\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"log2\"\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"log10\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"log10\"\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"max\"\n        value:\n          type: function\n          native: duk_bi_math_object_max\n          length: 2\n          varargs: true\n      - key: \"min\"\n        value:\n          type: function\n          native: duk_bi_math_object_min\n          length: 2\n          varargs: true\n      - key: \"pow\"\n        value:\n          type: function\n          native: duk_bi_math_object_twoarg_shared\n          length: 2\n          magic:\n            type: math_twoarg\n            funcname: \"pow\"\n      - key: \"random\"\n        value:\n          type: function\n          native: duk_bi_math_object_random\n          length: 0\n      - key: \"round\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"round\"\n      - key: \"sign\"\n        value:\n          type: function\n          native: duk_bi_math_object_sign\n          length: 1\n        es6: true\n        present_if: DUK_USE_ES6\n      - key: \"sin\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"sin\"\n      - key: \"sqrt\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"sqrt\"\n      - key: \"tan\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"tan\"\n      - key: \"trunc\"\n        value:\n          type: function\n          native: duk_bi_math_object_onearg_shared\n          length: 1\n          magic:\n            type: math_onearg\n            funcname: \"trunc\"\n        es6: true\n        present_if: DUK_USE_ES6\n      - key:\n          type: symbol\n          variant: wellknown\n          string: \"Symbol.toStringTag\"\n        value: \"Math\"\n        attributes: \"c\"\n        es6: true\n        present_if: DUK_USE_SYMBOL_BUILTIN\n\n  - id: bi_json\n    class: JSON\n    internal_prototype: bi_object_prototype\n    bidx: false\n    present_if:\n      - DUK_USE_JSON_BUILTIN\n      - DUK_USE_JSON_SUPPORT\n\n    # apparently no external \"prototype\" property\n    # apparently no external \"constructor\" property\n\n    properties:\n      - key: \"parse\"\n        value:\n          type: function\n          native: duk_bi_json_object_parse\n          length: 2\n      - key: \"stringify\"\n        value:\n          type: function\n          native: duk_bi_json_object_stringify\n          length: 3\n\n      #- key:  # @@toStringTag\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.toStringTag\"\n      #  value: XXX\n      #  es6: true\n      #  present_if: DUK_USE_SYMBOL_BUILTIN\n\n  # E5 Section 13.2.3\n  - id: bi_type_error_thrower\n    class: Function\n    internal_prototype: bi_function_prototype\n    native: duk_bi_type_error_thrower\n    callable: true\n    constructable: false  # This is not clearly specified, but [[Construct]] is not set in E5 Section 13.2.3.\n    bidx: true\n\n    properties:\n      - key: \"length\"\n        value: 0\n        attributes: \"c\"\n      # Custom name, matches V8; ES2016 describes %ThrowTypeError% as being\n      # anonymous.\n      - key: \"name\"\n        value: \"ThrowTypeError\"\n        attributes: \"c\"\n        duktape: true\n\n  #\n  #  Duktape-specific built-ins\n  #\n\n  - id: bi_duktape\n    class: Object\n    internal_prototype: bi_object_prototype\n    duktape: true\n    bidx: true\n    #present_if: DUK_USE_DUKTAPE_BUILTIN  # Present even when properties disabled, error augmentation relies on it\n\n    # There are a few properties not listed here:\n    #   - \"version\" is added from parameter file automatically.\n    #   - \"env\" is added dynamically at runtime.\n\n    properties:\n      - key: \"Pointer\"\n        value:\n          type: object\n          id: bi_pointer_constructor\n        duktape: true\n        present_if: DUK_USE_DUKTAPE_BUILTIN\n      - key: \"Thread\"\n        value:\n          type: object\n          id: bi_thread_constructor\n        duktape: true\n        present_if:\n          - DUK_USE_COROUTINE_SUPPORT\n          - DUK_USE_DUKTAPE_BUILTIN\n      - key: \"info\"\n        value:\n          type: function\n          native: duk_bi_duktape_object_info\n          length: 1\n        duktape: true\n        present_if: DUK_USE_DUKTAPE_BUILTIN\n      - key: \"act\"\n        value:\n          type: function\n          native: duk_bi_duktape_object_act\n          length: 1\n        duktape: true\n        present_if: DUK_USE_DUKTAPE_BUILTIN\n      - key: \"gc\"\n        value:\n          type: function\n          native: duk_bi_duktape_object_gc\n          length: 1\n        duktape: true\n        present_if: DUK_USE_DUKTAPE_BUILTIN\n      - key: \"fin\"\n        value:\n          type: function\n          native: duk_bi_duktape_object_fin\n          length: 0\n          varargs: true\n        duktape: true\n        present_if:\n          - DUK_USE_FINALIZER_SUPPORT\n          - DUK_USE_DUKTAPE_BUILTIN\n      - key: \"enc\"\n        value:\n          type: function\n          native: duk_bi_duktape_object_enc\n          length: 0\n          varargs: true\n        duktape: true\n        present_if: DUK_USE_DUKTAPE_BUILTIN\n      - key: \"dec\"\n        value:\n          type: function\n          native: duk_bi_duktape_object_dec\n          length: 0\n          varargs: true\n        duktape: true\n        present_if: DUK_USE_DUKTAPE_BUILTIN\n      - key: \"compact\"\n        value:\n          type: function\n          native: duk_bi_duktape_object_compact\n          length: 1\n        duktape: true\n        present_if: DUK_USE_DUKTAPE_BUILTIN\n\n  - id: bi_thread_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    varargs: true\n    native: duk_bi_thread_constructor\n    callable: true\n    constructable: true\n    duktape: true\n    bidx: false\n    present_if: DUK_USE_COROUTINE_SUPPORT\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n        duktape: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_thread_prototype\n        attributes: \"\"\n        duktape: true\n      - key: \"name\"\n        value: \"Thread\"\n        attributes: \"c\"\n        duktape: true\n\n      # \"yield\" is a reserved word but does not prevent its use as a property name\n      - key: \"yield\"\n        value:\n          type: function\n          native: duk_bi_thread_yield\n          length: 2\n        duktape: true\n        auto_lightfunc: false  # automatic lightfunc conversion clashes with internal implementation\n        present_if: DUK_USE_COROUTINE_SUPPORT\n      - key: \"resume\"\n        value:\n          type: function\n          native: duk_bi_thread_resume\n          length: 3\n        duktape: true\n        auto_lightfunc: false  # automatic lightfunc conversion clashes with internal implementation\n        present_if: DUK_USE_COROUTINE_SUPPORT\n      - key: \"current\"\n        value:\n          type: function\n          native: duk_bi_thread_current\n          length: 0\n        duktape: true\n        present_if: DUK_USE_COROUTINE_SUPPORT\n\n  - id: bi_thread_prototype\n    class: Object\n    internal_prototype: bi_object_prototype\n    duktape: true\n    bidx: true\n    # Present even when DUK_USE_DUKTAPE_BUILTIN disabled.\n\n    # Must be present even if coroutines are disabled for inheritance.\n    # Because Duktape.Thread.prototype is missing, the only way to access\n    # the prototype to e.g. add methods is to look it up from a thread\n    # instance.\n\n    # Note: we don't keep up with the E5 convention that prototype objects\n    # are some faux instances of their type (e.g. Date.prototype is a Date\n    # instance).\n    #\n    # Also, we don't currently have a \"constructor\" property because there is\n    # no explicit constructor object.\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_thread_constructor\n        attributes: \"wc\"\n        duktape: true\n        present_if:\n          - DUK_USE_COROUTINE_SUPPORT\n          - DUK_USE_DUKTAPE_BUILTIN\n\n      # toString() and valueOf() are inherited from Object.prototype\n\n  - id: bi_pointer_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    varargs: true\n    native: duk_bi_pointer_constructor\n    callable: true\n    constructable: true\n    duktape: true\n    bidx: false\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n        duktape: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_pointer_prototype\n        attributes: \"\"\n        duktape: true\n      - key: \"name\"\n        value: \"Pointer\"\n        attributes: \"c\"\n        duktape: true\n\n  - id: bi_pointer_prototype\n    class: Pointer\n    internal_prototype: bi_object_prototype\n    duktape: true\n    bidx: true\n    # Present even when DUK_USE_DUKTAPE_BUILTIN disabled.\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_pointer_constructor\n        attributes: \"wc\"\n        duktape: true\n        present_if: DUK_USE_DUKTAPE_BUILTIN\n\n      - key: \"toString\"\n        value:\n          type: function\n          native: duk_bi_pointer_prototype_tostring_shared\n          length: 0\n          magic: 1  # magic = to_string\n        duktape: true\n        present_if: DUK_USE_DUKTAPE_BUILTIN\n      - key: \"valueOf\"\n        value:\n          type: function\n          native: duk_bi_pointer_prototype_tostring_shared\n          length: 0\n          magic: 0  # magic = to_string\n        duktape: true\n        present_if: DUK_USE_DUKTAPE_BUILTIN\n\n  # This is an Error *instance* used to avoid allocation when a \"double error\" occurs.\n  # The object is \"frozen and sealed\" to avoid code accidentally modifying the instance.\n  # This is important because the error is rethrown as is.\n\n  - id: bi_double_error\n    class: Error\n    internal_prototype: bi_error_prototype\n    extensible: false\n    duktape: true\n    bidx: true\n\n    # Note: this is the only non-extensible built-in, so there is special\n    # post-tweak in duk_hthread_builtins.c to handle this.\n\n    properties:\n      - key: \"name\"\n        value: \"DoubleError\"\n        attributes: \"\"\n        duktape: true\n      - key: \"message\"\n        value: \"error in error handling\"\n        attributes: \"\"\n        duktape: true\n\n  #\n  #  ES2015\n  #\n\n  - id: bi_proxy_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    # no external prototype\n    native: duk_bi_proxy_constructor\n    callable: true\n    constructable: true\n    es6: true\n    bidx: false\n    present_if: DUK_USE_ES6_PROXY\n\n    properties:\n      - key: \"length\"\n        value: 2\n        attributes: \"c\"\n        es6: true\n      - key: \"name\"\n        value: \"Proxy\"\n        attributes: \"c\"\n        es6: true\n      #- key: \"revocable\"\n      #  value:\n      #    type: function\n      #    native: duk_bi_proxy_constructor_revocable\n      #    length: 2\n      #  es6: true\n\n  - id: bi_reflect\n    class: Object\n    internal_prototype: bi_object_prototype\n    bidx: false\n    present_if: DUK_USE_REFLECT_BUILTIN\n\n    properties:\n      - key: \"apply\"\n        value:\n          type: function\n          native: duk_bi_reflect_apply\n          length: 3\n          magic: 2  # see duk_js_call.c\n          special_call: true\n        auto_lightfunc: false  # automatic lightfunc conversion clashes with internal implementation\n        es6: true\n      - key: \"construct\"\n        value:\n          type: function\n          native: duk_bi_reflect_construct\n          length: 2\n          magic: 3  # see duk_js_call.c\n          special_call: true\n        auto_lightfunc: false  # automatic lightfunc conversion clashes with internal implementation\n        es6: true\n      - key: \"defineProperty\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_define_property\n          length: 3\n          magic: 1\n        es6: true\n      - key: \"deleteProperty\"\n        value:\n          type: function\n          native: duk_bi_reflect_object_delete_property\n          length: 2\n        es6: true\n      - key: \"get\"\n        value:\n          type: function\n          native: duk_bi_reflect_object_get\n          length: 2\n          varargs: true\n        es6: true\n      - key: \"getOwnPropertyDescriptor\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_get_own_property_descriptor\n          length: 2\n          magic: 1\n        es6: true\n      - key: \"getPrototypeOf\"\n        value:\n          type: function\n          native: duk_bi_object_getprototype_shared\n          length: 1\n          magic: 2\n        es6: true\n      - key: \"has\"\n        value:\n          type: function\n          native: duk_bi_reflect_object_has\n          length: 2\n        es6: true\n      - key: \"isExtensible\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_is_extensible\n          length: 1\n          magic: 1\n        es6: true\n      - key: \"ownKeys\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_keys_shared\n          length: 1\n          magic: 3\n        es6: true\n      - key: \"preventExtensions\"\n        value:\n          type: function\n          native: duk_bi_object_constructor_prevent_extensions\n          length: 1\n          magic: 1\n        es6: true\n      - key: \"set\"\n        value:\n          type: function\n          native: duk_bi_reflect_object_set\n          length: 3\n          varargs: true\n        es6: true\n      - key: \"setPrototypeOf\"\n        value:\n          type: function\n          native: duk_bi_object_setprototype_shared\n          length: 2\n          magic: 2\n        es6: true\n\n  - id: bi_symbol_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    native: duk_bi_symbol_constructor_shared\n    callable: true\n    constructable: false  # new Symbol() not allowed\n    es6: true\n    nargs: 1\n    magic: 0\n    bidx: false\n    present_if: DUK_USE_SYMBOL_BUILTIN\n\n    properties:\n      - key: \"length\"\n        value: 0\n        attributes: \"c\"\n        es6: true\n      - key: \"name\"\n        value: \"Symbol\"\n        attributes: \"c\"\n        es6: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_symbol_prototype\n        attributes: \"\"\n        es6: true\n\n      - key: \"for\"\n        value:\n          type: function\n          native: duk_bi_symbol_constructor_shared\n          magic: 1\n          length: 1\n          nargs: 1\n        attributes: \"wc\"\n        es6: true\n      - key: \"keyFor\"\n        value:\n          type: function\n          native: duk_bi_symbol_key_for\n          length: 1\n          nargs: 1\n        attributes: \"wc\"\n        es6: true\n\n      - key: \"hasInstance\"\n        value:\n          type: symbol\n          variant: wellknown\n          string: \"Symbol.hasInstance\"\n        attributes: \"\"\n        es6: true\n        present_if: DUK_USE_SYMBOL_BUILTIN\n      - key: \"isConcatSpreadable\"\n        value:\n          type: symbol\n          variant: wellknown\n          string: \"Symbol.isConcatSpreadable\"\n        attributes: \"\"\n        es6: true\n      - key: \"iterator\"\n        value:\n          type: symbol\n          variant: wellknown\n          string: \"Symbol.iterator\"\n        attributes: \"\"\n        es6: true\n        present_if: DUK_USE_SYMBOL_BUILTIN\n      #- key: \"match\"\n      #  value:\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.match\"\n      #  attributes: \"\"\n      #  es6: true\n      #- key: \"replace\"\n      #  value:\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.replace\"\n      #  attributes: \"\"\n      #  es6: true\n      #- key: \"search\"\n      #  value:\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.search\"\n      #  attributes: \"\"\n      #  es6: true\n      #- key: \"species\"\n      #  value:\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.species\"\n      #  attributes: \"\"\n      #  es6: true\n      #- key: \"split\"\n      #  value:\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.split\"\n      #  attributes: \"\"\n      #  es6: true\n      - key: \"toPrimitive\"\n        value:\n          type: symbol\n          variant: wellknown\n          string: \"Symbol.toPrimitive\"\n        attributes: \"\"\n        es6: true\n      - key: \"toStringTag\"\n        value:\n          type: symbol\n          variant: wellknown\n          string: \"Symbol.toStringTag\"\n        attributes: \"\"\n        es6: true\n      #- key: \"unscopables\"\n      #  value:\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.unscopables\"\n      #  attributes: \"\"\n      #  es6: true\n\n  - id: bi_symbol_prototype\n    class: Object\n    internal_prototype: bi_object_prototype\n    es6: true\n    bidx: true\n    # Present even when DUK_USE_SYMBOL_BUILTIN disabled so that symbol values\n    # created from C code can inherit through the Symbol prototype.\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_symbol_constructor\n        attributes: \"wc\"\n        es6: true\n        present_if: DUK_USE_SYMBOL_BUILTIN\n\n      - key: \"toString\"\n        value:\n          type: function\n          native: duk_bi_symbol_tostring_shared\n          nargs: 0\n          magic: 0\n        attributes: \"wc\"\n        es6: true\n        present_if: DUK_USE_SYMBOL_BUILTIN\n      - key: \"valueOf\"\n        value:\n          type: function\n          native: duk_bi_symbol_tostring_shared\n          nargs: 0\n          magic: 1\n        attributes: \"wc\"\n        es6: true\n        present_if: DUK_USE_SYMBOL_BUILTIN\n      - key:  # @@toPrimitive\n          type: symbol\n          variant: wellknown\n          string: \"Symbol.toPrimitive\"\n        value:\n          type: function\n          native: duk_bi_symbol_toprimitive\n          nargs: 0  # hint is ignored\n          length: 0\n          name: \"[Symbol.toPrimitive]\"\n        attributes: \"c\"\n        es6: true\n        present_if: DUK_USE_SYMBOL_BUILTIN\n      - key:  # @@toStringTag\n          type: symbol\n          variant: wellknown\n          string: \"Symbol.toStringTag\"\n        value: \"Symbol\"\n        attributes: \"c\"\n        es6: true\n        present_if: DUK_USE_SYMBOL_BUILTIN\n\n  - id: bi_promise_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    native: duk_bi_promise_constructor\n    callable: true\n    constructable: true\n    es6: true\n    nargs: 1\n    magic: 0\n    bidx: false\n    present_if: DUK_USE_PROMISE_BUILTIN\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n        es6: true\n      - key: \"name\"\n        value: \"Promise\"\n        attributes: \"c\"\n        es6: true\n      - key: 'prototype'\n        value:\n          type: object\n          id: bi_promise_prototype\n        attributes: \"\"\n        es6: true\n      - key: 'all'\n        value:\n          type: function\n          native: duk_bi_promise_all\n          length: 1\n          varargs: false\n        attributes: 'wc'\n        es6: true\n      - key: 'race'\n        value:\n          type: function\n          native: duk_bi_promise_race\n          length: 1\n          varargs: false\n        attributes: 'wc'\n        es6: true\n      - key: 'reject'\n        value:\n          type: function\n          native: duk_bi_promise_reject\n          length: 1\n          varargs: false\n        attributes: 'wc'\n        es6: true\n      - key: 'resolve'\n        value:\n          type: function\n          native: duk_bi_promise_resolve\n          length: 1\n          varargs: false\n        attributes: 'wc'\n        es6: true\n      # @@species\n      # 'defer' is obsolete and not implemented:\n      # https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/Promise.jsm/Deferred.\n      # 'accept' is obsolete and not implemented:\n      #https://bugs.chromium.org/p/v8/issues/detail?id=3238\n      # 'try': https://github.com/tc39/proposal-promise-try\n\n  - id: bi_promise_prototype\n    class: Object\n    internal_prototype: bi_object_prototype\n    es6: true\n    bidx: true\n    present_if: DUK_USE_PROMISE_BUILTIN\n\n    properties:\n      - key: 'constructor'\n        value:\n          type: object\n          id: bi_promise_constructor\n        attributes: \"wc\"\n        es6: true\n      - key: 'catch'\n        value:\n          type: function\n          native: duk_bi_promise_catch\n          length: 1\n          varargs: false\n        attributes: 'wc'\n        es6: true\n      - key: 'then'\n        value:\n          type: function\n          native: duk_bi_promise_then\n          length: 2\n          varargs: false\n        attributes: 'wc'\n        es6: true\n      # @@toStringTag\n      # 'chain' is an obsolete variant of .then and not implemented:\n      # https://stackoverflow.com/questions/34713965/the-feature-of-method-promise-prototype-chain-in-chrome\n\n      # 'finally': https://github.com/tc39/proposal-promise-finally\n\n  #\n  #  TypedArray\n  #\n\n  - id: bi_arraybuffer_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    varargs: false\n    native: duk_bi_arraybuffer_constructor\n    callable: true\n    constructable: true\n    typedarray: true\n    es6: true\n    bidx: false\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"length\"\n        value: 1\n        attributes: \"c\"\n        typedarray: true\n        es6: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_arraybuffer_prototype\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"name\"\n        value: \"ArrayBuffer\"\n        attributes: \"c\"\n        es6: true\n      - key: \"isView\"\n        value:\n          type: function\n          native: duk_bi_arraybuffer_isview\n          length: 1\n          varargs: false\n        typedarray: true\n        es6: true\n\n      #- key:  # @@species\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.species\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_arraybuffer_prototype\n    class: Object\n    internal_prototype: bi_object_prototype\n    typedarray: true\n    es6: true\n    bidx: true\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"byteLength\"\n        value:\n          type: accessor\n          getter: duk_bi_typedarray_bytelength_getter  # XXX: more lenient than required by spec now\n          getter_nargs: 0\n          getter_magic: 0\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_arraybuffer_constructor\n        attributes: \"wc\"\n        typedarray: true\n        es6: true\n      - key: \"slice\"\n        value:\n          type: function\n          native: duk_bi_buffer_slice_shared\n          length: 2\n          varargs: false\n          magic: 2  # magic: 0x01=isView, 0x02=create copy, 0x04=Node.js Buffer special\n        typedarray: true\n        es6: true\n\n      #- key:  # @@toStringTag\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.toStringTag\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_dataview_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    varargs: false\n    native: duk_bi_dataview_constructor\n    callable: true\n    constructable: true\n    typedarray: true\n    es6: true\n    bidx: false\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"length\"\n        value: 3\n        attributes: \"c\"\n        typedarray: true\n        es6: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_dataview_prototype\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"name\"\n        value: \"DataView\"\n        attributes: \"c\"\n        es6: true\n\n      #- key:  # @@species\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.species\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_dataview_prototype\n    class: Object\n    internal_prototype: bi_object_prototype\n    typedarray: true\n    es6: true\n    bidx: true\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"byteLength\"\n        value:\n          type: accessor\n          getter: duk_bi_typedarray_bytelength_getter\n          getter_nargs: 0\n          getter_magic: 0\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"byteOffset\"\n        value:\n          type: accessor\n          getter: duk_bi_typedarray_byteoffset_getter\n          getter_nargs: 0\n          getter_magic: 0\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"buffer\"\n        value:\n          type: accessor\n          getter: duk_bi_typedarray_buffer_getter\n          getter_nargs: 0\n          getter_magic: 0\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_dataview_constructor\n        attributes: \"wc\"\n        typedarray: true\n        es6: true\n\n      # Int8/Uint8 get/set calls don't have a little endian argument\n      # but length/nargs must provide it for the shared helper anyway.\n\n      - key: \"getInt8\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"8bit\"\n            signed: true\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n      - key: \"getUint8\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"8bit\"\n            signed: false\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n      - key: \"getInt16\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"16bit\"\n            signed: true\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n      - key: \"getUint16\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"16bit\"\n            signed: false\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n      - key: \"getInt32\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"32bit\"\n            signed: true\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n      - key: \"getUint32\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"32bit\"\n            signed: false\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n      - key: \"getFloat32\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"float\"\n            signed: false\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n      - key: \"getFloat64\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"double\"\n            signed: false\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n      - key: \"setInt8\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"8bit\"\n            signed: true\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n      - key: \"setUint8\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"8bit\"\n            signed: false\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n      - key: \"setInt16\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"16bit\"\n            signed: true\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n      - key: \"setUint16\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"16bit\"\n            signed: false\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n      - key: \"setInt32\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"32bit\"\n            signed: true\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n      - key: \"setUint32\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"32bit\"\n            signed: false\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n      - key: \"setFloat32\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"float\"\n            signed: false\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n      - key: \"setFloat64\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"double\"\n            signed: false\n            bigendian: false\n            typedarray: true\n        typedarray: true\n        es6: true\n\n      #- key:  # @@toStringTag\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.toStringTag\"\n      #  value: XXX\n      #  es6: true\n\n  # %TypedArray% constructor\n  # Prototype object providing properties shared by all TypedArray\n  # constructors.  Callable, but duk_bi_typedarray_constructor()\n  # rejects normal calls with TypeError; not constructable which\n  # rejects constructor calls with TypeError.\n  - id: bi_typedarray_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    varargs: false\n    native: duk_bi_typedarray_constructor\n    callable: true\n    constructable: false\n    nargs: 0\n    magic: 0\n    typedarray: true\n    es6: true\n    bidx: false\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"length\"\n        value: 0\n        attributes: \"c\"\n        typedarray: true\n        es6: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_typedarray_prototype\n        attributes: \"\"\n        es6: true\n      - key: \"name\"\n        value: \"TypedArray\"\n        attributes: \"c\"\n        es6: true\n\n      # .from\n      # .of\n      # @@species getter\n\n  # %TypedArrayPrototype%\n  # Custom prototype object providing properties shared by all TypedArray\n  # instances (reduces built-in object count).  The view specific prototypes\n  # (such as Uint8Array.prototype) are still needed so that e.g. instanceof\n  # will work properly.\n\n  - id: bi_typedarray_prototype\n    class: Object\n    internal_prototype: bi_object_prototype\n    # no external_prototype (specific views provide it)\n    typedarray: true\n    es6: true\n    bidx: false\n    # Present even when DUK_USE_BUFFEROBJECT_SUPPORT is disabled\n    # to support plain buffers.\n\n    properties:\n      - key: \"byteLength\"\n        value:\n          type: accessor\n          getter: duk_bi_typedarray_bytelength_getter\n          getter_nargs: 0\n          getter_magic: 0\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"byteOffset\"\n        value:\n          type: accessor\n          getter: duk_bi_typedarray_byteoffset_getter\n          getter_nargs: 0\n          getter_magic: 0\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"buffer\"\n        value:\n          type: accessor\n          getter: duk_bi_typedarray_buffer_getter\n          getter_nargs: 0\n          getter_magic: 0\n        attributes: \"\"\n        typedarray: true\n        es6: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT  # missing without bufferobject support\n      - key: \"set\"\n        value:\n          type: function\n          native: duk_bi_typedarray_set\n          length: 2\n          varargs: false\n        typedarray: true\n        es6: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n      - key: \"subarray\"\n        value:\n          type: function\n          native: duk_bi_buffer_slice_shared\n          length: 2\n          varargs: false\n          magic: 1  # magic: 0x01=isView, 0x02=create copy, 0x04=Node.js Buffer special\n        typedarray: true\n        es6: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n      #- key:  # @@iterator\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.iterator\"\n      #  value: XXX\n      #  es6: true\n      #  present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n      #- key:  # @@toStringTag\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.toStringTag\"\n      #  value: XXX\n      #  es6: true\n      #  present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n  - id: bi_int8array_constructor\n    class: Function\n    internal_prototype: bi_typedarray_constructor\n    varargs: false\n    native: duk_bi_typedarray_constructor\n    callable: true\n    constructable: true\n    magic:\n      type: typedarray_constructor\n      elem: \"int8\"\n      shift: 0\n    typedarray: true\n    es6: true\n    bidx: false\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"length\"\n        value: 3\n        attributes: \"c\"\n        typedarray: true\n        es6: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_int8array_prototype\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"name\"\n        value: \"Int8Array\"\n        attributes: \"c\"\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 1\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n      #- key:  # @@species\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.species\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_int8array_prototype\n    internal_prototype: bi_typedarray_prototype\n    class: Object\n    typedarray: true\n    es6: true\n    bidx: true\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_int8array_constructor\n        attributes: \"wc\"\n        typedarray: true\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 1\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n  - id: bi_uint8array_constructor\n    class: Function\n    internal_prototype: bi_typedarray_constructor\n    varargs: false\n    native: duk_bi_typedarray_constructor\n    callable: true\n    constructable: true\n    magic:\n      type: typedarray_constructor\n      elem: \"uint8\"\n      shift: 0\n    typedarray: true\n    es6: true\n    bidx: false\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"length\"\n        value: 3\n        attributes: \"c\"\n        typedarray: true\n        es6: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_uint8array_prototype\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"name\"\n        value: \"Uint8Array\"\n        attributes: \"c\"\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 1\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n      # Duktape custom: allocate a plain buffer, return value is always\n      # a freshly allocated fixed plain buffer.\n      - key: \"allocPlain\"\n        value:\n          type: function\n          native: duk_bi_uint8array_allocplain\n          length: 1\n          varargs: false\n        duktape: true\n\n      # Duktape custom: get plain buffer underlying a buffer object.\n      - key: \"plainOf\"\n        value:\n          type: function\n          native: duk_bi_uint8array_plainof\n          length: 1\n          varargs: false\n        duktape: true\n\n      #- key:  # @@species\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.species\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_uint8array_prototype\n    class: Object\n    internal_prototype: bi_typedarray_prototype\n    typedarray: true\n    es6: true\n    bidx: true\n    # Present even when DUK_USE_BUFFEROBJECT_SUPPORT is disabled\n    # to support plain buffers.\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_uint8array_constructor\n        attributes: \"wc\"\n        typedarray: true\n        es6: true\n        present_if: DUK_USE_BUFFEROBJECT_SUPPORT  # missing without bufferobject support\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 1\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n  - id: bi_uint8clampedarray_constructor\n    class: Function\n    internal_prototype: bi_typedarray_constructor\n    varargs: false\n    native: duk_bi_typedarray_constructor\n    callable: true\n    constructable: true\n    magic:\n      type: typedarray_constructor\n      elem: \"uint8clamped\"\n      shift: 0\n    typedarray: true\n    es6: true\n    bidx: false\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"length\"\n        value: 3\n        attributes: \"c\"\n        typedarray: true\n        es6: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_uint8clampedarray_prototype\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"name\"\n        value: \"Uint8ClampedArray\"\n        attributes: \"c\"\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 1\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n      #- key:  # @@species\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.species\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_uint8clampedarray_prototype\n    class: Object\n    internal_prototype: bi_typedarray_prototype\n    typedarray: true\n    es6: true\n    bidx: true\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_uint8clampedarray_constructor\n        attributes: \"wc\"\n        typedarray: true\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 1\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n  - id: bi_int16array_constructor\n    class: Function\n    internal_prototype: bi_typedarray_constructor\n    varargs: false\n    native: duk_bi_typedarray_constructor\n    callable: true\n    constructable: true\n    magic:\n      type: typedarray_constructor\n      elem: \"int16\"\n      shift: 1\n    typedarray: true\n    es6: true\n    bidx: false\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"length\"\n        value: 3\n        attributes: \"c\"\n        typedarray: true\n        es6: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_int16array_prototype\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"name\"\n        value: \"Int16Array\"\n        attributes: \"c\"\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 2\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n      #- key:  # @@species\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.species\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_int16array_prototype\n    class: Object\n    internal_prototype: bi_typedarray_prototype\n    typedarray: true\n    es6: true\n    bidx: true\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_int16array_constructor\n        attributes: \"wc\"\n        typedarray: true\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 2\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n  - id: bi_uint16array_constructor\n    class: Function\n    internal_prototype: bi_typedarray_constructor\n    varargs: false\n    native: duk_bi_typedarray_constructor\n    callable: true\n    constructable: true\n    magic:\n      type: typedarray_constructor\n      elem: \"uint16\"\n      shift: 1\n    typedarray: true\n    es6: true\n    bidx: false\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"length\"\n        value: 3\n        attributes: \"c\"\n        typedarray: true\n        es6: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_uint16array_prototype\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"name\"\n        value: \"Uint16Array\"\n        attributes: \"c\"\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 2\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n      #- key:  # @@species\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.species\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_uint16array_prototype\n    class: Object\n    internal_prototype: bi_typedarray_prototype\n    typedarray: true\n    es6: true\n    bidx: true\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_uint16array_constructor\n        attributes: \"wc\"\n        typedarray: true\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 2\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n  - id: bi_int32array_constructor\n    class: Function\n    internal_prototype: bi_typedarray_constructor\n    varargs: false\n    native: duk_bi_typedarray_constructor\n    callable: true\n    constructable: true\n    magic:\n      type: typedarray_constructor\n      elem: \"int32\"\n      shift: 2\n    typedarray: true\n    es6: true\n    bidx: false\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"length\"\n        value: 3\n        attributes: \"c\"\n        typedarray: true\n        es6: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_int32array_prototype\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"name\"\n        value: \"Int32Array\"\n        attributes: \"c\"\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 4\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n      #- key:  # @@species\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.species\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_int32array_prototype\n    class: Object\n    internal_prototype: bi_typedarray_prototype\n    typedarray: true\n    es6: true\n    bidx: true\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_int32array_constructor\n        attributes: \"wc\"\n        typedarray: true\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 4\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n  - id: bi_uint32array_constructor\n    class: Function\n    internal_prototype: bi_typedarray_constructor\n    varargs: false\n    native: duk_bi_typedarray_constructor\n    callable: true\n    constructable: true\n    magic:\n      type: typedarray_constructor\n      elem: \"uint32\"\n      shift: 2\n    typedarray: true\n    es6: true\n    bidx: false\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"length\"\n        value: 3\n        attributes: \"c\"\n        typedarray: true\n        es6: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_uint32array_prototype\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"name\"\n        value: \"Uint32Array\"\n        attributes: \"c\"\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 4\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n      #- key:  # @@species\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.species\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_uint32array_prototype\n    class: Object\n    internal_prototype: bi_typedarray_prototype\n    typedarray: true\n    es6: true\n    bidx: true\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_uint32array_constructor\n        attributes: \"wc\"\n        typedarray: true\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 4\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n  - id: bi_float32array_constructor\n    class: Function\n    internal_prototype: bi_typedarray_constructor\n    varargs: false\n    native: duk_bi_typedarray_constructor\n    callable: true\n    constructable: true\n    magic:\n      type: typedarray_constructor\n      elem: \"float32\"\n      shift: 2\n    typedarray: true\n    es6: true\n    bidx: false\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"length\"\n        value: 3\n        attributes: \"c\"\n        typedarray: true\n        es6: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_float32array_prototype\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"name\"\n        value: \"Float32Array\"\n        attributes: \"c\"\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 4\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n      #- key:  # @@species\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.species\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_float32array_prototype\n    class: Object\n    internal_prototype: bi_typedarray_prototype\n    typedarray: true\n    es6: true\n    bidx: true\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_float32array_constructor\n        attributes: \"wc\"\n        typedarray: true\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 4\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n  - id: bi_float64array_constructor\n    class: Function\n    internal_prototype: bi_typedarray_constructor\n    varargs: false\n    native: duk_bi_typedarray_constructor\n    callable: true\n    constructable: true\n    magic:\n      type: typedarray_constructor\n      elem: \"float64\"\n      shift: 3\n    typedarray: true\n    es6: true\n    bidx: false\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"length\"\n        value: 3\n        attributes: \"c\"\n        typedarray: true\n        es6: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_float64array_prototype\n        attributes: \"\"\n        typedarray: true\n        es6: true\n      - key: \"name\"\n        value: \"Float64Array\"\n        attributes: \"c\"\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 8\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n      #- key:  # @@species\n      #    type: symbol\n      #    variant: wellknown\n      #    string: \"Symbol.species\"\n      #  value: XXX\n      #  es6: true\n\n  - id: bi_float64array_prototype\n    class: Object\n    internal_prototype: bi_typedarray_prototype\n    typedarray: true\n    es6: true\n    bidx: true\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_float64array_constructor\n        attributes: \"wc\"\n        typedarray: true\n        es6: true\n      - key: \"BYTES_PER_ELEMENT\"\n        value: 8\n        attributes: \"\"\n        typedarray: true\n        es6: true\n\n  #\n  #  Node.js Buffer\n  #\n\n  - id: bi_nodejs_buffer_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    varargs: false\n    native: duk_bi_nodejs_buffer_constructor\n    callable: true\n    constructable: true\n    nodejs_buffer: true\n    bidx: false\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"length\"\n        value: 2\n        attributes: \"c\"\n        nodejs_buffer: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_nodejs_buffer_prototype\n        attributes: \"\"\n        nodejs_buffer: true\n      - key: \"name\"\n        value: \"Buffer\"\n        attributes: \"c\"\n        nodejs_buffer: true\n\n      - key: \"concat\"\n        value:\n          type: function\n          native: duk_bi_nodejs_buffer_concat\n          length: 2\n          varargs: false\n        nodejs_buffer: true\n      - key: \"isEncoding\"\n        value:\n          type: function\n          native: duk_bi_nodejs_buffer_is_encoding\n          length: 1\n          varargs:\n        nodejs_buffer: true\n      - key: \"isBuffer\"\n        value:\n          type: function\n          native: duk_bi_nodejs_buffer_is_buffer\n          length: 1\n          varargs: false\n        nodejs_buffer: true\n      - key: \"byteLength\"\n        value:\n          type: function\n          native: duk_bi_nodejs_buffer_byte_length\n          length: 2\n          varargs: false\n        nodejs_buffer: true\n      - key: \"compare\"\n        value:\n          type: function\n          native: duk_bi_buffer_compare_shared\n          length: 2\n          varargs: false\n          magic: 3  # magic: 0x02=static call + 0x01=compare = 0x03\n        nodejs_buffer: true\n\n  - id: bi_nodejs_buffer_prototype\n    internal_prototype: bi_uint8array_prototype\n    class: Object\n    nodejs_buffer: true\n    bidx: true\n    present_if: DUK_USE_BUFFEROBJECT_SUPPORT\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_nodejs_buffer_constructor\n        attributes: \"wc\"\n        nodejs_buffer: true\n\n      - key: \"readUInt8\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"8bit\"\n            signed: false\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readInt8\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"8bit\"\n            signed: true\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readUInt16LE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"16bit\"\n            signed: false\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readUInt16BE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"16bit\"\n            signed: false\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readInt16LE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"16bit\"\n            signed: true\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readInt16BE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"16bit\"\n            signed: true\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readUInt32LE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"32bit\"\n            signed: false\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readUInt32BE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"32bit\"\n            signed: false\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readInt32LE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"32bit\"\n            signed: true\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readInt32BE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"32bit\"\n            signed: true\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readFloatLE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"float\"\n            signed: false\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readFloatBE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"float\"\n            signed: false\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readDoubleLE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"double\"\n            signed: false\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readDoubleBE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 2\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"double\"\n            signed: false\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readUIntLE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"varint\"\n            signed: false\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readUIntBE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"varint\"\n            signed: false\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readIntLE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"varint\"\n            signed: true\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"readIntBE\"\n        value:\n          type: function\n          native: duk_bi_buffer_readfield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_readfield\n            elem: \"varint\"\n            signed: true\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeUInt8\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"8bit\"\n            signed: false\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeInt8\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"8bit\"\n            signed: true\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeUInt16LE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"16bit\"\n            signed: false\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeUInt16BE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"16bit\"\n            signed: false\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeInt16LE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"16bit\"\n            signed: true\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeInt16BE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"16bit\"\n            signed: true\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeUInt32LE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"32bit\"\n            signed: false\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeUInt32BE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"32bit\"\n            signed: false\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeInt32LE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"32bit\"\n            signed: true\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeInt32BE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"32bit\"\n            signed: true\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeFloatLE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"float\"\n            signed: false\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeFloatBE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"float\"\n            signed: false\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeDoubleLE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"double\"\n            signed: false\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeDoubleBE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 3\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"double\"\n            signed: false\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeUIntLE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 4\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"varint\"\n            signed: false\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeUIntBE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 4\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"varint\"\n            signed: false\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeIntLE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 4\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"varint\"\n            signed: true\n            bigendian: false\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"writeIntBE\"\n        value:\n          type: function\n          native: duk_bi_buffer_writefield\n          length: 4\n          varargs: false\n          magic:\n            type: buffer_writefield\n            elem: \"varint\"\n            signed: true\n            bigendian: true\n            typedarray: false\n        nodejs_buffer: true\n      - key: \"toString\"\n        value:\n          type: function\n          native: duk_bi_nodejs_buffer_tostring\n          length: 3\n          varargs: false\n        nodejs_buffer: true\n      - key: \"toJSON\"\n        value:\n          type: function\n          native: duk_bi_nodejs_buffer_tojson\n          length: 0\n          varargs: false\n        nodejs_buffer: true\n      - key: \"fill\"\n        value:\n          type: function\n          native: duk_bi_nodejs_buffer_fill\n          length: 3\n          varargs: false\n        nodejs_buffer: true\n      - key: \"equals\"\n        value:\n          type: function\n          native: duk_bi_buffer_compare_shared\n          length: 1\n          varargs: false\n          magic: 0  # magic = 0: equals\n        nodejs_buffer: true\n      - key: \"compare\"\n        value:\n          type: function\n          native: duk_bi_buffer_compare_shared\n          length: 1\n          varargs: false\n          magic: 1  # magic = 1: compare\n        nodejs_buffer: true\n      - key: \"copy\"\n        value:\n          type: function\n          native: duk_bi_nodejs_buffer_copy\n          length: 4\n          varargs: false\n        nodejs_buffer: true\n      - key: \"slice\"\n        value:\n          type: function\n          native: duk_bi_buffer_slice_shared\n          length: 2\n          varargs: false\n          magic: 5  # magic: 0x01=isView, 0x02=create copy, 0x04=Node.js Buffer special\n        nodejs_buffer: true\n      - key: \"write\"\n        value:\n          type: function\n          native: duk_bi_nodejs_buffer_write\n          length: 4\n          varargs: false\n        nodejs_buffer: true\n\n  #\n  #  Encoding API\n  #\n\n  - id: bi_textencoder_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    nargs: 0\n    native: duk_bi_textencoder_constructor\n    callable: true\n    constructable: true\n    bidx: false\n    encoding_api: true\n    present_if: DUK_USE_ENCODING_BUILTINS\n\n    properties:\n      - key: \"length\"\n        value: 0\n        attributes: \"c\"\n        encoding_api: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_textencoder_prototype\n        attributes: \"\"\n        encoding_api: true\n      - key: \"name\"\n        value: \"TextEncoder\"\n        attributes: \"c\"\n        encoding_api: true\n\n  - id: bi_textencoder_prototype\n    internal_prototype: bi_object_prototype\n    class: Object\n    bidx: false\n    encoding_api: true\n    present_if: DUK_USE_ENCODING_BUILTINS\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_textencoder_constructor\n        attributes: \"wc\"\n        encoding_api: true\n      - key: \"encoding\"\n        value:\n          type: accessor\n          getter: duk_bi_textencoder_prototype_encoding_getter\n          getter_nargs: 0\n          getter_magic: 0\n        attributes: \"ec\"\n        encoding_api: true\n      - key: \"encode\"\n        value:\n          type: function\n          native: duk_bi_textencoder_prototype_encode\n          length: 0\n          nargs: 1\n        attributes: \"wec\"\n        encoding_api: true\n\n  - id: bi_textdecoder_constructor\n    class: Function\n    internal_prototype: bi_function_prototype\n    nargs: 2\n    native: duk_bi_textdecoder_constructor\n    callable: true\n    constructable: true\n    bidx: false\n    encoding_api: true\n    present_if: DUK_USE_ENCODING_BUILTINS\n\n    properties:\n      - key: \"length\"\n        value: 0\n        attributes: \"c\"\n        encoding_api: true\n      - key: \"prototype\"\n        value:\n          type: object\n          id: bi_textdecoder_prototype\n        attributes: \"\"\n        encoding_api: true\n      - key: \"name\"\n        value: \"TextDecoder\"\n        attributes: \"c\"\n        encoding_api: true\n\n  - id: bi_textdecoder_prototype\n    internal_prototype: bi_object_prototype\n    class: Object\n    bidx: false\n    encoding_api: true\n    present_if: DUK_USE_ENCODING_BUILTINS\n\n    properties:\n      - key: \"constructor\"\n        value:\n          type: object\n          id: bi_textdecoder_constructor\n        attributes: \"wc\"\n        encoding_api: true\n      - key: \"encoding\"\n        value:\n          type: accessor\n          getter: duk_bi_textdecoder_prototype_shared_getter\n          getter_nargs: 0\n          getter_magic: 0  # 0=encoding\n        attributes: \"ec\"\n        encoding_api: true\n      - key: \"fatal\"\n        value:\n          type: accessor\n          getter: duk_bi_textdecoder_prototype_shared_getter\n          getter_nargs: 0\n          getter_magic: 1  # 1=fatal\n        attributes: \"ec\"\n        encoding_api: true\n      - key: \"ignoreBOM\"\n        value:\n          type: accessor\n          getter: duk_bi_textdecoder_prototype_shared_getter\n          getter_nargs: 0\n          getter_magic: 2  # 2=ignoreBOM\n        attributes: \"ec\"\n        encoding_api: true\n      - key: \"decode\"\n        value:\n          type: function\n          native: duk_bi_textdecoder_prototype_decode\n          length: 0\n          nargs: 2\n        attributes: \"wec\"\n        encoding_api: true\n\n  - id: bi_performance\n    internal_prototype: bi_object_prototype\n    class: Object\n    bidx: false\n    performance_api: true\n    present_if: DUK_USE_PERFORMANCE_BUILTIN\n\n    properties:\n      # Firefox and Chrome: data property with 'wec' attributes,\n      # inherited from PerformancePrototype.  Use own data property\n      # for now.\n      - key: \"now\"\n        value:\n          type: function\n          native: duk_bi_performance_now\n          length: 0\n          nargs: 0\n        attributes: \"wec\"\n        performance_api: true\n      # Missing until semantics decided.\n      #- key: \"timeOrigin\"\n      #  value:\n      #    type: accessor\n      #    getter: duk_bi_performance_timeorigin_getter\n      #    getter_nargs: 0\n      #    getter_magic: 0\n      #  attributes: \"ec\"  # check\n      #  performance_api: true\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_alloc_default.c",
    "content": "/*\n *  Default allocation functions.\n *\n *  Assumes behavior such as malloc allowing zero size, yielding\n *  a NULL or a unique pointer which is a no-op for free.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS)\nDUK_INTERNAL void *duk_default_alloc_function(void *udata, duk_size_t size) {\n\tvoid *res;\n\tDUK_UNREF(udata);\n\tres = DUK_ANSI_MALLOC(size);\n\tDUK_DDD(DUK_DDDPRINT(\"default alloc function: %lu -> %p\",\n\t                     (unsigned long) size, (void *) res));\n\treturn res;\n}\n\nDUK_INTERNAL void *duk_default_realloc_function(void *udata, void *ptr, duk_size_t newsize) {\n\tvoid *res;\n\tDUK_UNREF(udata);\n\tres = DUK_ANSI_REALLOC(ptr, newsize);\n\tDUK_DDD(DUK_DDDPRINT(\"default realloc function: %p %lu -> %p\",\n\t                     (void *) ptr, (unsigned long) newsize, (void *) res));\n\treturn res;\n}\n\nDUK_INTERNAL void duk_default_free_function(void *udata, void *ptr) {\n\tDUK_DDD(DUK_DDDPRINT(\"default free function: %p\", (void *) ptr));\n\tDUK_UNREF(udata);\n\tDUK_ANSI_FREE(ptr);\n}\n#endif  /* DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_api_buffer.c",
    "content": "/*\n *  Buffer\n */\n\n#include \"duk_internal.h\"\n\nDUK_EXTERNAL void *duk_resize_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t new_size) {\n\tduk_hbuffer_dynamic *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer_dynamic *) duk_require_hbuffer(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tif (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\t/* Maximum size check is handled by callee. */\n\tduk_hbuffer_resize(thr, h, new_size);\n\n\treturn DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h);\n}\n\nDUK_EXTERNAL void *duk_steal_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tduk_hbuffer_dynamic *h;\n\tvoid *ptr;\n\tduk_size_t sz;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer_dynamic *) duk_require_hbuffer(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tif (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\t/* Forget the previous allocation, setting size to 0 and alloc to\n\t * NULL.  Caller is responsible for freeing the previous allocation.\n\t * Getting the allocation and clearing it is done in the same API\n\t * call to avoid any chance of a realloc.\n\t */\n\tptr = DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h);\n\tsz = DUK_HBUFFER_DYNAMIC_GET_SIZE(h);\n\tif (out_size) {\n\t\t*out_size = sz;\n\t}\n\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(thr->heap, h);\n\tDUK_HBUFFER_DYNAMIC_SET_SIZE(h, 0);\n\n\treturn ptr;\n}\n\nDUK_EXTERNAL void duk_config_buffer(duk_hthread *thr, duk_idx_t idx, void *ptr, duk_size_t len) {\n\tduk_hbuffer_external *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer_external *) duk_require_hbuffer(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tif (!DUK_HBUFFER_HAS_EXTERNAL(h)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h));\n\n\tDUK_HBUFFER_EXTERNAL_SET_DATA_PTR(thr->heap, h, ptr);\n\tDUK_HBUFFER_EXTERNAL_SET_SIZE(h, len);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_api_bytecode.c",
    "content": "/*\n *  Bytecode dump/load\n *\n *  The bytecode load primitive is more important performance-wise than the\n *  dump primitive.\n *\n *  Unlike most Duktape API calls, bytecode dump/load is not guaranteed to be\n *  memory safe for invalid arguments - caller beware!  There's little point\n *  in trying to achieve memory safety unless bytecode instructions are also\n *  validated which is not easy to do with indirect register references etc.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_BYTECODE_DUMP_SUPPORT)\n\n#define DUK__SER_MARKER  0xbf\n#define DUK__SER_STRING  0x00\n#define DUK__SER_NUMBER  0x01\n#define DUK__BYTECODE_INITIAL_ALLOC 256\n#define DUK__NO_FORMALS  0xffffffffUL\n\n/*\n *  Dump/load helpers, xxx_raw() helpers do no buffer checks\n */\n\nDUK_LOCAL duk_uint8_t *duk__load_string_raw(duk_hthread *thr, duk_uint8_t *p) {\n\tduk_uint32_t len;\n\n\tlen = DUK_RAW_READ_U32_BE(p);\n\tduk_push_lstring(thr, (const char *) p, len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__load_buffer_raw(duk_hthread *thr, duk_uint8_t *p) {\n\tduk_uint32_t len;\n\tduk_uint8_t *buf;\n\n\tlen = DUK_RAW_READ_U32_BE(p);\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) len);\n\tDUK_ASSERT(buf != NULL);\n\tduk_memcpy((void *) buf, (const void *) p, (size_t) len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_hstring_raw(duk_uint8_t *p, duk_hstring *h) {\n\tduk_size_t len;\n\tduk_uint32_t tmp32;\n\n\tDUK_ASSERT(h != NULL);\n\n\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\tDUK_ASSERT(len <= 0xffffffffUL);  /* string limits */\n\ttmp32 = (duk_uint32_t) len;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\tduk_memcpy((void *) p,\n\t           (const void *) DUK_HSTRING_GET_DATA(h),\n\t           len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_hbuffer_raw(duk_hthread *thr, duk_uint8_t *p, duk_hbuffer *h) {\n\tduk_size_t len;\n\tduk_uint32_t tmp32;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\tDUK_UNREF(thr);\n\n\tlen = DUK_HBUFFER_GET_SIZE(h);\n\tDUK_ASSERT(len <= 0xffffffffUL);  /* buffer limits */\n\ttmp32 = (duk_uint32_t) len;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\t/* When len == 0, buffer data pointer may be NULL. */\n\tduk_memcpy_unsafe((void *) p,\n\t                  (const void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h),\n\t                  len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_string_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx) {\n\tduk_hstring *h_str;\n\tduk_tval *tv;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_STRING(tv)) {\n\t\th_str = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h_str != NULL);\n\t} else {\n\t\th_str = DUK_HTHREAD_STRING_EMPTY_STRING(thr);\n\t\tDUK_ASSERT(h_str != NULL);\n\t}\n\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(h_str), p);\n\tp = duk__dump_hstring_raw(p, h_str);\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_buffer_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx) {\n\tduk_tval *tv;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h_buf;\n\t\th_buf = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h_buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFFER_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HBUFFER_GET_SIZE(h_buf), p);\n\t\tp = duk__dump_hbuffer_raw(thr, p, h_buf);\n\t} else {\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\t\tDUK_RAW_WRITE_U32_BE(p, 0);\n\t}\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_uint32_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx, duk_uint32_t def_value) {\n\tduk_tval *tv;\n\tduk_uint32_t val;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_NUMBER(tv)) {\n\t\tval = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv);\n\t} else {\n\t\tval = def_value;\n\t}\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\tDUK_RAW_WRITE_U32_BE(p, val);\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_varmap(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func) {\n\tduk_hobject *h;\n\n\th = duk_hobject_get_varmap(thr, (duk_hobject *) func);\n\tif (h != NULL) {\n\t\tduk_uint_fast32_t i;\n\n\t\t/* We know _Varmap only has own properties so walk property\n\t\t * table directly.  We also know _Varmap is dense and all\n\t\t * values are numbers; assert for these.  GC and finalizers\n\t\t * shouldn't affect _Varmap so side effects should be fine.\n\t\t */\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\t\tduk_hstring *key;\n\t\t\tduk_tval *tv_val;\n\t\t\tduk_uint32_t val;\n\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, h, i);\n\t\t\tDUK_ASSERT(key != NULL);  /* _Varmap is dense */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, h, i));\n\t\t\ttv_val = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, h, i);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_val));  /* known to be number; in fact an integer */\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv_val));\n\t\t\tDUK_ASSERT(DUK_TVAL_GET_FASTINT(tv_val) == (duk_int64_t) DUK_TVAL_GET_FASTINT_U32(tv_val));  /* known to be 32-bit */\n\t\t\tval = DUK_TVAL_GET_FASTINT_U32(tv_val);\n#else\n\t\t\tval = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv_val);\n#endif\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(key) + 4U, p);\n\t\t\tp = duk__dump_hstring_raw(p, key);\n\t\t\tDUK_RAW_WRITE_U32_BE(p, val);\n\t\t}\n\t}\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\tDUK_RAW_WRITE_U32_BE(p, 0);  /* end of _Varmap */\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_formals(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func) {\n\tduk_harray *h;\n\n\th = duk_hobject_get_formals(thr, (duk_hobject *) func);\n\tif (h != NULL) {\n\t\tduk_uint32_t i;\n\n\t\t/* Here we rely on _Formals being a dense array containing\n\t\t * strings.  This should be the case unless _Formals has been\n\t\t * tweaked by the application (which we don't support right\n\t\t * now).\n\t\t */\n\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\t\tDUK_ASSERT(h->length != DUK__NO_FORMALS);  /* limits */\n\t\tDUK_RAW_WRITE_U32_BE(p, h->length);\n\n\t\tfor (i = 0; i < h->length; i++) {\n\t\t\tduk_tval *tv_val;\n\t\t\tduk_hstring *varname;\n\n\t\t\ttv_val = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, (duk_hobject *) h, i);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_val));\n\n\t\t\tvarname = DUK_TVAL_GET_STRING(tv_val);\n\t\t\tDUK_ASSERT(varname != NULL);\n\t\t\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(varname) >= 1);\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(varname), p);\n\t\t\tp = duk__dump_hstring_raw(p, varname);\n\t\t}\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"dumping function without _Formals, emit marker to indicate missing _Formals\"));\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\t\tDUK_RAW_WRITE_U32_BE(p, DUK__NO_FORMALS);  /* marker: no formals */\n\t}\n\treturn p;\n}\n\nstatic duk_uint8_t *duk__dump_func(duk_hthread *thr, duk_hcompfunc *func, duk_bufwriter_ctx *bw_ctx, duk_uint8_t *p) {\n\tduk_tval *tv, *tv_end;\n\tduk_instr_t *ins, *ins_end;\n\tduk_hobject **fn, **fn_end;\n\tduk_hstring *h_str;\n\tduk_uint32_t count_instr;\n\tduk_uint32_t tmp32;\n\tduk_uint16_t tmp16;\n\tduk_double_t d;\n\n\tDUK_DD(DUK_DDPRINT(\"dumping function %p to %p: \"\n\t                   \"consts=[%p,%p[ (%ld bytes, %ld items), \"\n\t                   \"funcs=[%p,%p[ (%ld bytes, %ld items), \"\n\t                   \"code=[%p,%p[ (%ld bytes, %ld items)\",\n\t                   (void *) func,\n\t                   (void *) p,\n\t                   (void *) DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CONSTS_SIZE(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CONSTS_COUNT(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_FUNCS_SIZE(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_CODE_END(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CODE_SIZE(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CODE_COUNT(thr->heap, func)));\n\n\tDUK_ASSERT(DUK_USE_ESBC_MAX_BYTES <= 0x7fffffffUL);  /* ensures no overflow */\n\tcount_instr = (duk_uint32_t) DUK_HCOMPFUNC_GET_CODE_COUNT(thr->heap, func);\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 3U * 4U + 2U * 2U + 3U * 4U + count_instr * 4U, p);\n\n\t/* Fixed header info. */\n\ttmp32 = count_instr;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp32 = (duk_uint32_t) DUK_HCOMPFUNC_GET_CONSTS_COUNT(thr->heap, func);\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp32 = (duk_uint32_t) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, func);\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp16 = func->nregs;\n\tDUK_RAW_WRITE_U16_BE(p, tmp16);\n\ttmp16 = func->nargs;\n\tDUK_RAW_WRITE_U16_BE(p, tmp16);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\ttmp32 = func->start_line;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp32 = func->end_line;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n#else\n\tDUK_RAW_WRITE_U32_BE(p, 0);\n\tDUK_RAW_WRITE_U32_BE(p, 0);\n#endif\n\ttmp32 = DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) func);  /* masks flags, only duk_hobject flags */\n\ttmp32 &= ~(DUK_HOBJECT_FLAG_HAVE_FINALIZER);  /* finalizer flag is lost */\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\n\t/* Bytecode instructions: endian conversion needed unless\n\t * platform is big endian.\n\t */\n\tins = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, func);\n\tins_end = DUK_HCOMPFUNC_GET_CODE_END(thr->heap, func);\n\tDUK_ASSERT((duk_size_t) (ins_end - ins) == (duk_size_t) count_instr);\n#if defined(DUK_USE_INTEGER_BE)\n\tduk_memcpy_unsafe((void *) p, (const void *) ins, (size_t) (ins_end - ins));\n\tp += (size_t) (ins_end - ins);\n#else\n\twhile (ins != ins_end) {\n\t\ttmp32 = (duk_uint32_t) (*ins);\n\t\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\t\tins++;\n\t}\n#endif\n\n\t/* Constants: variable size encoding. */\n\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, func);\n\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, func);\n\twhile (tv != tv_end) {\n\t\t/* constants are strings or numbers now */\n\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv) ||\n\t\t           DUK_TVAL_IS_NUMBER(tv));\n\n\t\tif (DUK_TVAL_IS_STRING(tv)) {\n\t\t\th_str = DUK_TVAL_GET_STRING(tv);\n\t\t\tDUK_ASSERT(h_str != NULL);\n\t\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1U + 4U + DUK_HSTRING_GET_BYTELEN(h_str), p);\n\t\t\t*p++ = DUK__SER_STRING;\n\t\t\tp = duk__dump_hstring_raw(p, h_str);\n\t\t} else {\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1U + 8U, p);\n\t\t\t*p++ = DUK__SER_NUMBER;\n\t\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t\t\tDUK_RAW_WRITE_DOUBLE_BE(p, d);\n\t\t}\n\t\ttv++;\n\t}\n\n\t/* Inner functions recursively. */\n\tfn = (duk_hobject **) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, func);\n\tfn_end = (duk_hobject **) DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, func);\n\twhile (fn != fn_end) {\n\t\t/* XXX: This causes recursion up to inner function depth\n\t\t * which is normally not an issue, e.g. mark-and-sweep uses\n\t\t * a recursion limiter to avoid C stack issues.  Avoiding\n\t\t * this would mean some sort of a work list or just refusing\n\t\t * to serialize deep functions.\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(*fn));\n\t\tp = duk__dump_func(thr, (duk_hcompfunc *) *fn, bw_ctx, p);\n\t\tfn++;\n\t}\n\n\t/* Lexenv and varenv are not dumped. */\n\n\t/* Object extra properties.\n\t *\n\t * There are some difference between function templates and functions.\n\t * For example, function templates don't have .length and nargs is\n\t * normally used to instantiate the functions.\n\t */\n\n\tp = duk__dump_uint32_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_LENGTH, (duk_uint32_t) func->nargs);\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tp = duk__dump_string_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_NAME);\n#endif\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tp = duk__dump_string_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_FILE_NAME);\n#endif\n#if defined(DUK_USE_PC2LINE)\n\tp = duk__dump_buffer_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_INT_PC2LINE);\n#endif\n\tp = duk__dump_varmap(thr, p, bw_ctx, (duk_hobject *) func);\n\tp = duk__dump_formals(thr, p, bw_ctx, (duk_hobject *) func);\n\n\tDUK_DD(DUK_DDPRINT(\"serialized function %p -> final pointer %p\", (void *) func, (void *) p));\n\n\treturn p;\n}\n\n/* Load a function from bytecode.  The function object returned here must\n * match what is created by duk_js_push_closure() with respect to its flags,\n * properties, etc.\n *\n * NOTE: there are intentionally no input buffer length / bound checks.\n * Adding them would be easy but wouldn't ensure memory safety as untrusted\n * or broken bytecode is unsafe during execution unless the opcodes themselves\n * are validated (which is quite complex, especially for indirect opcodes).\n */\n\n#define DUK__ASSERT_LEFT(n) do { \\\n\t\tDUK_ASSERT((duk_size_t) (p_end - p) >= (duk_size_t) (n)); \\\n\t} while (0)\n\nstatic duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t *p_end) {\n\tduk_hcompfunc *h_fun;\n\tduk_hbuffer *h_data;\n\tduk_size_t data_size;\n\tduk_uint32_t count_instr, count_const, count_funcs;\n\tduk_uint32_t n;\n\tduk_uint32_t tmp32;\n\tduk_small_uint_t const_type;\n\tduk_uint8_t *fun_data;\n\tduk_uint8_t *q;\n\tduk_idx_t idx_base;\n\tduk_tval *tv1;\n\tduk_uarridx_t arr_idx;\n\tduk_uarridx_t arr_limit;\n\tduk_hobject *func_env;\n\tduk_bool_t need_pop;\n\n\t/* XXX: There's some overlap with duk_js_closure() here, but\n\t * seems difficult to share code.  Ensure that the final function\n\t * looks the same as created by duk_js_closure().\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"loading function, p=%p, p_end=%p\", (void *) p, (void *) p_end));\n\n\tDUK__ASSERT_LEFT(3 * 4);\n\tcount_instr = DUK_RAW_READ_U32_BE(p);\n\tcount_const = DUK_RAW_READ_U32_BE(p);\n\tcount_funcs = DUK_RAW_READ_U32_BE(p);\n\n\tdata_size = sizeof(duk_tval) * count_const +\n\t            sizeof(duk_hobject *) * count_funcs +\n\t            sizeof(duk_instr_t) * count_instr;\n\n\tDUK_DD(DUK_DDPRINT(\"instr=%ld, const=%ld, funcs=%ld, data_size=%ld\",\n\t                   (long) count_instr, (long) count_const,\n\t                   (long) count_const, (long) data_size));\n\n\t/* Value stack is used to ensure reachability of constants and\n\t * inner functions being loaded.  Require enough space to handle\n\t * large functions correctly.\n\t */\n\tduk_require_stack(thr, (duk_idx_t) (2 + count_const + count_funcs));\n\tidx_base = duk_get_top(thr);\n\n\t/* Push function object, init flags etc.  This must match\n\t * duk_js_push_closure() quite carefully.\n\t */\n\th_fun = duk_push_hcompfunc(thr);\n\tDUK_ASSERT(h_fun != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) h_fun));\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, h_fun) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, h_fun) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, h_fun) == NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_fun) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\n\th_fun->nregs = DUK_RAW_READ_U16_BE(p);\n\th_fun->nargs = DUK_RAW_READ_U16_BE(p);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\th_fun->start_line = DUK_RAW_READ_U32_BE(p);\n\th_fun->end_line = DUK_RAW_READ_U32_BE(p);\n#else\n\tp += 8;  /* skip line info */\n#endif\n\n\t/* duk_hcompfunc flags; quite version specific */\n\ttmp32 = DUK_RAW_READ_U32_BE(p);\n\tDUK_HEAPHDR_SET_FLAGS((duk_heaphdr *) h_fun, tmp32);  /* masks flags to only change duk_hobject flags */\n\n\t/* standard prototype (no need to set here, already set) */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_fun) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#if 0\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, &h_fun->obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#endif\n\n\t/* assert just a few critical flags */\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h_fun) == DUK_HTYPE_OBJECT);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&h_fun->obj));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_IS_PROXY(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(&h_fun->obj));\n\n\t/* Create function 'data' buffer but don't attach it yet. */\n\tfun_data = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, data_size);\n\tDUK_ASSERT(fun_data != NULL);\n\n\t/* Load bytecode instructions. */\n\tDUK_ASSERT(sizeof(duk_instr_t) == 4);\n\tDUK__ASSERT_LEFT(count_instr * sizeof(duk_instr_t));\n#if defined(DUK_USE_INTEGER_BE)\n\tq = fun_data + sizeof(duk_tval) * count_const + sizeof(duk_hobject *) * count_funcs;\n\tduk_memcpy((void *) q,\n\t           (const void *) p,\n\t           sizeof(duk_instr_t) * count_instr);\n\tp += sizeof(duk_instr_t) * count_instr;\n#else\n\tq = fun_data + sizeof(duk_tval) * count_const + sizeof(duk_hobject *) * count_funcs;\n\tfor (n = count_instr; n > 0; n--) {\n\t\t*((duk_instr_t *) (void *) q) = DUK_RAW_READ_U32_BE(p);\n\t\tq += sizeof(duk_instr_t);\n\t}\n#endif\n\n\t/* Load constants onto value stack but don't yet copy to buffer. */\n\tfor (n = count_const; n > 0; n--) {\n\t\tDUK__ASSERT_LEFT(1);\n\t\tconst_type = DUK_RAW_READ_U8(p);\n\t\tswitch (const_type) {\n\t\tcase DUK__SER_STRING: {\n\t\t\tp = duk__load_string_raw(thr, p);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK__SER_NUMBER: {\n\t\t\t/* Important to do a fastint check so that constants are\n\t\t\t * properly read back as fastints.\n\t\t\t */\n\t\t\tduk_tval tv_tmp;\n\t\t\tduk_double_t val;\n\t\t\tDUK__ASSERT_LEFT(8);\n\t\t\tval = DUK_RAW_READ_DOUBLE_BE(p);\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(&tv_tmp, val);\n\t\t\tduk_push_tval(thr, &tv_tmp);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tgoto format_error;\n\t\t}\n\t\t}\n\t}\n\n\t/* Load inner functions to value stack, but don't yet copy to buffer. */\n\tfor (n = count_funcs; n > 0; n--) {\n\t\tp = duk__load_func(thr, p, p_end);\n\t\tif (p == NULL) {\n\t\t\tgoto format_error;\n\t\t}\n\t}\n\n\t/* With constants and inner functions on value stack, we can now\n\t * atomically finish the function 'data' buffer, bump refcounts,\n\t * etc.\n\t *\n\t * Here we take advantage of the value stack being just a duk_tval\n\t * array: we can just memcpy() the constants as long as we incref\n\t * them afterwards.\n\t */\n\n\th_data = (duk_hbuffer *) duk_known_hbuffer(thr, idx_base + 1);\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC(h_data));\n\tDUK_HCOMPFUNC_SET_DATA(thr->heap, h_fun, h_data);\n\tDUK_HBUFFER_INCREF(thr, h_data);\n\n\ttv1 = duk_get_tval(thr, idx_base + 2);  /* may be NULL if no constants or inner funcs */\n\tDUK_ASSERT((count_const == 0 && count_funcs == 0) || tv1 != NULL);\n\n\tq = fun_data;\n\tduk_memcpy_unsafe((void *) q, (const void *) tv1, sizeof(duk_tval) * count_const);\n\tfor (n = count_const; n > 0; n--) {\n\t\tDUK_TVAL_INCREF_FAST(thr, (duk_tval *) (void *) q);  /* no side effects */\n\t\tq += sizeof(duk_tval);\n\t}\n\ttv1 += count_const;\n\n\tDUK_HCOMPFUNC_SET_FUNCS(thr->heap, h_fun, (duk_hobject **) (void *) q);\n\tfor (n = count_funcs; n > 0; n--) {\n\t\tduk_hobject *h_obj;\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv1));\n\t\th_obj = DUK_TVAL_GET_OBJECT(tv1);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\ttv1++;\n\t\tDUK_HOBJECT_INCREF(thr, h_obj);\n\n\t\t*((duk_hobject **) (void *) q) = h_obj;\n\t\tq += sizeof(duk_hobject *);\n\t}\n\n\tDUK_HCOMPFUNC_SET_BYTECODE(thr->heap, h_fun, (duk_instr_t *) (void *) q);\n\n\t/* The function object is now reachable and refcounts are fine,\n\t * so we can pop off all the temporaries.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"function is reachable, reset top; func: %!iT\", duk_get_tval(thr, idx_base)));\n\tduk_set_top(thr, idx_base + 1);\n\n\t/* Setup function properties. */\n\ttmp32 = DUK_RAW_READ_U32_BE(p);\n\tduk_push_u32(thr, tmp32);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tp = duk__load_string_raw(thr, p);  /* -> [ func funcname ] */\n\tfunc_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\tDUK_ASSERT(func_env != NULL);\n\tneed_pop = 0;\n\tif (DUK_HOBJECT_HAS_NAMEBINDING((duk_hobject *) h_fun)) {\n\t\t/* Original function instance/template had NAMEBINDING.\n\t\t * Must create a lexical environment on loading to allow\n\t\t * recursive functions like 'function foo() { foo(); }'.\n\t\t */\n\t\tduk_hdecenv *new_env;\n\n\t\tnew_env = duk_hdecenv_alloc(thr,\n\t\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\t\tDUK_ASSERT(new_env != NULL);\n\t\tDUK_ASSERT(new_env->thread == NULL);  /* Closed. */\n\t\tDUK_ASSERT(new_env->varmap == NULL);\n\t\tDUK_ASSERT(new_env->regbase_byteoff == 0);\n\t\tDUK_HDECENV_ASSERT_VALID(new_env);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, func_env);\n\t\tDUK_HOBJECT_INCREF(thr, func_env);\n\n\t\tfunc_env = (duk_hobject *) new_env;\n\n\t\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\n\t\tduk_dup_m2(thr);                                  /* -> [ func funcname env funcname ] */\n\t\tduk_dup(thr, idx_base);                           /* -> [ func funcname env funcname func ] */\n\t\tduk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_NONE);  /* -> [ func funcname env ] */\n\n\t\tneed_pop = 1;  /* Need to pop env, but -after- updating h_fun and increfs. */\n\t}\n\tDUK_ASSERT(func_env != NULL);\n\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, h_fun, func_env);\n\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, h_fun, func_env);\n\tDUK_HOBJECT_INCREF(thr, func_env);\n\tDUK_HOBJECT_INCREF(thr, func_env);\n\tif (need_pop) {\n\t\tduk_pop(thr);\n\t}\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n#endif  /* DUK_USE_FUNC_NAME_PROPERTY */\n\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tp = duk__load_string_raw(thr, p);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C);\n#endif  /* DUK_USE_FUNC_FILENAME_PROPERTY */\n\n\tif (DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) h_fun)) {\n\t\t/* Restore empty external .prototype only for constructable\n\t\t * functions.  The prototype object should inherit from\n\t\t * Object.prototype.\n\t\t */\n\t\tduk_push_object(thr);\n\t\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\t\tduk_dup_m2(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC);  /* func.prototype.constructor = func */\n\t\tduk_compact_m1(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W);\n\t}\n\n#if defined(DUK_USE_PC2LINE)\n\tp = duk__load_buffer_raw(thr, p);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_WC);\n#endif  /* DUK_USE_PC2LINE */\n\n\tduk_push_bare_object(thr);  /* _Varmap */\n\tfor (;;) {\n\t\t/* XXX: awkward */\n\t\tp = duk__load_string_raw(thr, p);\n\t\tif (duk_get_length(thr, -1) == 0) {\n\t\t\tduk_pop(thr);\n\t\t\tbreak;\n\t\t}\n\t\ttmp32 = DUK_RAW_READ_U32_BE(p);\n\t\tduk_push_u32(thr, tmp32);\n\t\tduk_put_prop(thr, -3);\n\t}\n\tduk_compact_m1(thr);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VARMAP, DUK_PROPDESC_FLAGS_NONE);\n\n\t/* _Formals may have been missing in the original function, which is\n\t * handled using a marker length.\n\t */\n\tarr_limit = DUK_RAW_READ_U32_BE(p);\n\tif (arr_limit != DUK__NO_FORMALS) {\n\t\tduk_push_bare_array(thr);  /* _Formals */\n\t\tfor (arr_idx = 0; arr_idx < arr_limit; arr_idx++) {\n\t\t\tp = duk__load_string_raw(thr, p);\n\t\t\tduk_put_prop_index(thr, -2, arr_idx);\n\t\t}\n\t\tduk_compact_m1(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_FORMALS, DUK_PROPDESC_FLAGS_NONE);\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"no _Formals in dumped function\"));\n\t}\n\n\t/* Return with final function pushed on stack top. */\n\tDUK_DD(DUK_DDPRINT(\"final loaded function: %!iT\", duk_get_tval(thr, -1)));\n\tDUK_ASSERT_TOP(thr, idx_base + 1);\n\treturn p;\n\n format_error:\n\treturn NULL;\n}\n\nDUK_EXTERNAL void duk_dump_function(duk_hthread *thr) {\n\tduk_hcompfunc *func;\n\tduk_bufwriter_ctx bw_ctx_alloc;\n\tduk_bufwriter_ctx *bw_ctx = &bw_ctx_alloc;\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Bound functions don't have all properties so we'd either need to\n\t * lookup the non-bound target function or reject bound functions.\n\t * For now, bound functions are rejected with TypeError.\n\t */\n\tfunc = duk_require_hcompfunc(thr, -1);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&func->obj));\n\n\t/* Estimating the result size beforehand would be costly, so\n\t * start with a reasonable size and extend as needed.\n\t */\n\tDUK_BW_INIT_PUSHBUF(thr, bw_ctx, DUK__BYTECODE_INITIAL_ALLOC);\n\tp = DUK_BW_GET_PTR(thr, bw_ctx);\n\t*p++ = DUK__SER_MARKER;\n\tp = duk__dump_func(thr, func, bw_ctx, p);\n\tDUK_BW_SET_PTR(thr, bw_ctx, p);\n\tDUK_BW_COMPACT(thr, bw_ctx);\n\n\tDUK_DD(DUK_DDPRINT(\"serialized result: %!T\", duk_get_tval(thr, -1)));\n\n\tduk_remove_m2(thr);  /* [ ... func buf ] -> [ ... buf ] */\n}\n\nDUK_EXTERNAL void duk_load_function(duk_hthread *thr) {\n\tduk_uint8_t *p_buf, *p, *p_end;\n\tduk_size_t sz;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tp_buf = (duk_uint8_t *) duk_require_buffer(thr, -1, &sz);\n\tDUK_ASSERT(p_buf != NULL);\n\n\t/* The caller is responsible for being sure that bytecode being loaded\n\t * is valid and trusted.  Invalid bytecode can cause memory unsafe\n\t * behavior directly during loading or later during bytecode execution\n\t * (instruction validation would be quite complex to implement).\n\t *\n\t * This signature check is the only sanity check for detecting\n\t * accidental invalid inputs.  The initial byte ensures no ordinary\n\t * string or Symbol will be accepted by accident.\n\t */\n\tp = p_buf;\n\tp_end = p_buf + sz;\n\tif (sz < 1 || p[0] != DUK__SER_MARKER) {\n\t\tgoto format_error;\n\t}\n\tp++;\n\n\tp = duk__load_func(thr, p, p_end);\n\tif (p == NULL) {\n\t\tgoto format_error;\n\t}\n\n\tduk_remove_m2(thr);  /* [ ... buf func ] -> [ ... func ] */\n\treturn;\n\n format_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BYTECODE);\n\tDUK_WO_NORETURN(return;);\n}\n\n#else  /* DUK_USE_BYTECODE_DUMP_SUPPORT */\n\nDUK_EXTERNAL void duk_dump_function(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_load_function(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n#endif  /* DUK_USE_BYTECODE_DUMP_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_api_call.c",
    "content": "/*\n *  Calls.\n *\n *  Protected variants should avoid ever throwing an error.  Must be careful\n *  to catch errors related to value stack manipulation and property lookup,\n *  not just the call itself.\n *\n *  The only exception is when arguments are insane, e.g. nargs/nrets are out\n *  of bounds; in such cases an error is thrown for two reasons.  First, we\n *  can't always respect the value stack input/output guarantees in such cases\n *  so the caller would end up with the value stack in an unexpected state.\n *  Second, an attempt to create an error might itself fail (although this\n *  could be avoided by pushing a preallocated object/string or a primitive\n *  value).\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Helpers\n */\n\nstruct duk__pcall_prop_args {\n\tduk_idx_t obj_idx;\n\tduk_idx_t nargs;\n\tduk_small_uint_t call_flags;\n};\ntypedef struct duk__pcall_prop_args duk__pcall_prop_args;\n\nstruct duk__pcall_method_args {\n\tduk_idx_t nargs;\n\tduk_small_uint_t call_flags;\n};\ntypedef struct duk__pcall_method_args duk__pcall_method_args;\n\nstruct duk__pcall_args {\n\tduk_idx_t nargs;\n\tduk_small_uint_t call_flags;\n};\ntypedef struct duk__pcall_args duk__pcall_args;\n\n/* Compute and validate idx_func for a certain 'nargs' and 'other'\n * parameter count (1 or 2, depending on whether 'this' binding is\n * present).\n */\nDUK_LOCAL duk_idx_t duk__call_get_idx_func(duk_hthread *thr, duk_idx_t nargs, duk_idx_t other) {\n\tduk_idx_t idx_func;\n\n\t/* XXX: byte arithmetic? */\n\n\tDUK_ASSERT(other >= 0);\n\n\tidx_func = duk_get_top(thr) - nargs - other;\n\tif (DUK_UNLIKELY((idx_func | nargs) < 0)) {  /* idx_func < 0 || nargs < 0; OR sign bits */\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\treturn idx_func;\n}\n\n/* Compute idx_func, assume index will be valid.  This is a valid assumption\n * for protected calls: nargs < 0 is checked explicitly and duk_safe_call()\n * validates the argument count.\n */\nDUK_LOCAL duk_idx_t duk__call_get_idx_func_unvalidated(duk_hthread *thr, duk_idx_t nargs, duk_idx_t other) {\n\tduk_idx_t idx_func;\n\n\t/* XXX: byte arithmetic? */\n\n\tDUK_ASSERT(nargs >= 0);\n\tDUK_ASSERT(other >= 0);\n\n\tidx_func = duk_get_top(thr) - nargs - other;\n\tDUK_ASSERT(idx_func >= 0);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\treturn idx_func;\n}\n\n/* Prepare value stack for a method call through an object property.\n * May currently throw an error e.g. when getting the property.\n */\nDUK_LOCAL void duk__call_prop_prep_stack(duk_hthread *thr, duk_idx_t normalized_obj_idx, duk_idx_t nargs) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(nargs >= 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__call_prop_prep_stack, normalized_obj_idx=%ld, nargs=%ld, stacktop=%ld\",\n\t                     (long) normalized_obj_idx, (long) nargs, (long) duk_get_top(thr)));\n\n\t/* [... key arg1 ... argN] */\n\n\t/* duplicate key */\n\tduk_dup(thr, -nargs - 1);  /* Note: -nargs alone would fail for nargs == 0, this is OK */\n\t(void) duk_get_prop(thr, normalized_obj_idx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"func: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\tif (DUK_UNLIKELY(!duk_is_callable(thr, -1))) {\n\t\tduk_tval *tv_base;\n\t\tduk_tval *tv_key;\n\n\t\t/* tv_targ is passed on stack top (at index -1). */\n\t\ttv_base = DUK_GET_TVAL_POSIDX(thr, normalized_obj_idx);\n\t\ttv_key = DUK_GET_TVAL_NEGIDX(thr, -nargs - 2);\n\t\tDUK_ASSERT(tv_base >= thr->valstack_bottom && tv_base < thr->valstack_top);\n\t\tDUK_ASSERT(tv_key >= thr->valstack_bottom && tv_key < thr->valstack_top);\n\n\t\tduk_call_setup_propcall_error(thr, tv_base, tv_key);\n\t}\n#endif\n\n\t/* [... key arg1 ... argN func] */\n\n\tduk_replace(thr, -nargs - 2);\n\n\t/* [... func arg1 ... argN] */\n\n\tduk_dup(thr, normalized_obj_idx);\n\tduk_insert(thr, -nargs - 1);\n\n\t/* [... func this arg1 ... argN] */\n}\n\nDUK_EXTERNAL void duk_call(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_small_uint_t call_flags;\n\tduk_idx_t idx_func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx_func = duk__call_get_idx_func(thr, nargs, 1);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tduk_insert_undefined(thr, idx_func + 1);\n\n\tcall_flags = 0;  /* not protected, respect reclimit, not constructor */\n\tduk_handle_call_unprotected(thr, idx_func, call_flags);\n}\n\nDUK_EXTERNAL void duk_call_method(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_small_uint_t call_flags;\n\tduk_idx_t idx_func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx_func = duk__call_get_idx_func(thr, nargs, 2);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tcall_flags = 0;  /* not protected, respect reclimit, not constructor */\n\tduk_handle_call_unprotected(thr, idx_func, call_flags);\n}\n\nDUK_EXTERNAL void duk_call_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t nargs) {\n\t/*\n\t *  XXX: if duk_handle_call() took values through indices, this could be\n\t *  made much more sensible.  However, duk_handle_call() needs to fudge\n\t *  the 'this' and 'func' values to handle bound functions, which is now\n\t *  done \"in-place\", so this is not a trivial change.\n\t */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);  /* make absolute */\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk__call_prop_prep_stack(thr, obj_idx, nargs);\n\n\tduk_call_method(thr, nargs);\n}\n\nDUK_LOCAL duk_ret_t duk__pcall_raw(duk_hthread *thr, void *udata) {\n\tduk__pcall_args *args;\n\tduk_idx_t idx_func;\n\tduk_int_t ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\targs = (duk__pcall_args *) udata;\n\tidx_func = duk__call_get_idx_func_unvalidated(thr, args->nargs, 1);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tduk_insert_undefined(thr, idx_func + 1);\n\n\tret = duk_handle_call_unprotected(thr, idx_func, args->call_flags);\n\tDUK_ASSERT(ret == 0);\n\tDUK_UNREF(ret);\n\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_pcall(duk_hthread *thr, duk_idx_t nargs) {\n\tduk__pcall_args args;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\targs.nargs = nargs;\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\targs.call_flags = 0;\n\n\treturn duk_safe_call(thr, duk__pcall_raw, (void *) &args /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);\n}\n\nDUK_LOCAL duk_ret_t duk__pcall_method_raw(duk_hthread *thr, void *udata) {\n\tduk__pcall_method_args *args;\n\tduk_idx_t idx_func;\n\tduk_int_t ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\targs = (duk__pcall_method_args *) udata;\n\n\tidx_func = duk__call_get_idx_func_unvalidated(thr, args->nargs, 2);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tret = duk_handle_call_unprotected(thr, idx_func, args->call_flags);\n\tDUK_ASSERT(ret == 0);\n\tDUK_UNREF(ret);\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_int_t duk_pcall_method_flags(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags) {\n\tduk__pcall_method_args args;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\targs.nargs = nargs;\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\targs.call_flags = call_flags;\n\n\treturn duk_safe_call(thr, duk__pcall_method_raw, (void *) &args /*udata*/, nargs + 2 /*nargs*/, 1 /*nrets*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_pcall_method(duk_hthread *thr, duk_idx_t nargs) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_pcall_method_flags(thr, nargs, 0);\n}\n\nDUK_LOCAL duk_ret_t duk__pcall_prop_raw(duk_hthread *thr, void *udata) {\n\tduk__pcall_prop_args *args;\n\tduk_idx_t obj_idx;\n\tduk_int_t ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\targs = (duk__pcall_prop_args *) udata;\n\n\tobj_idx = duk_require_normalize_index(thr, args->obj_idx);  /* make absolute */\n\tduk__call_prop_prep_stack(thr, obj_idx, args->nargs);\n\n\tret = duk_handle_call_unprotected_nargs(thr, args->nargs, args->call_flags);\n\tDUK_ASSERT(ret == 0);\n\tDUK_UNREF(ret);\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_pcall_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t nargs) {\n\tduk__pcall_prop_args args;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\targs.obj_idx = obj_idx;\n\targs.nargs = nargs;\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\targs.call_flags = 0;\n\n\treturn duk_safe_call(thr, duk__pcall_prop_raw, (void *) &args /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_safe_call(duk_hthread *thr, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* nargs condition; fail if: top - bottom < nargs\n\t *                      <=>  top < bottom + nargs\n\t * nrets condition; fail if: end - (top - nargs) < nrets\n\t *                      <=>  end - top + nargs < nrets\n\t *                      <=>  end + nargs < top + nrets\n\t */\n\t/* XXX: check for any reserve? */\n\n\tif (DUK_UNLIKELY((nargs | nrets) < 0 ||  /* nargs < 0 || nrets < 0; OR sign bits */\n\t                 thr->valstack_top < thr->valstack_bottom + nargs ||        /* nargs too large compared to top */\n\t                 thr->valstack_end + nargs < thr->valstack_top + nrets)) {  /* nrets too large compared to reserve */\n\t\tDUK_D(DUK_DPRINT(\"not enough stack reserve for safe call or invalid arguments: \"\n\t\t                 \"nargs=%ld < 0 (?), nrets=%ld < 0 (?), top=%ld < bottom=%ld + nargs=%ld (?), \"\n\t\t                 \"end=%ld + nargs=%ld < top=%ld + nrets=%ld (?)\",\n\t\t                  (long) nargs,\n\t\t                  (long) nrets,\n\t\t                  (long) (thr->valstack_top - thr->valstack),\n\t\t                  (long) (thr->valstack_bottom - thr->valstack),\n\t\t                  (long) nargs,\n\t\t                  (long) (thr->valstack_end - thr->valstack),\n\t\t                  (long) nargs,\n\t\t                  (long) (thr->valstack_top - thr->valstack),\n\t\t                  (long) nrets));\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\n\trc = duk_handle_safe_call(thr,           /* thread */\n\t                          func,          /* func */\n\t                          udata,         /* udata */\n\t                          nargs,         /* num_stack_args */\n\t                          nrets);        /* num_stack_res */\n\n\treturn rc;\n}\n\nDUK_EXTERNAL void duk_new(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_idx_t idx_func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx_func = duk__call_get_idx_func(thr, nargs, 1);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tduk_push_object(thr);  /* default instance; internal proto updated by call handling */\n\tduk_insert(thr, idx_func + 1);\n\n\tduk_handle_call_unprotected(thr, idx_func, DUK_CALL_FLAG_CONSTRUCT);\n}\n\nDUK_LOCAL duk_ret_t duk__pnew_helper(duk_hthread *thr, void *udata) {\n\tduk_idx_t nargs;\n\n\tDUK_ASSERT(udata != NULL);\n\tnargs = *((duk_idx_t *) udata);\n\n\tduk_new(thr, nargs);\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_pnew(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* For now, just use duk_safe_call() to wrap duk_new().  We can't\n\t * simply use a protected duk_handle_call() because pushing the\n\t * default instance might throw.\n\t */\n\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\n\trc = duk_safe_call(thr, duk__pnew_helper, (void *) &nargs /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);\n\treturn rc;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_constructor_call(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\treturn ((act->flags & DUK_ACT_FLAG_CONSTRUCT) != 0 ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL void duk_require_constructor_call(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (!duk_is_constructor_call(thr)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_CONSTRUCT_ONLY);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_strict_call(duk_hthread *thr) {\n\tduk_activation *act;\n\n\t/* For user code this could just return 1 (strict) always\n\t * because all Duktape/C functions are considered strict,\n\t * and strict is also the default when nothing is running.\n\t * However, Duktape may call this function internally when\n\t * the current activation is an ECMAScript function, so\n\t * this cannot be replaced by a 'return 1' without fixing\n\t * the internal call sites.\n\t */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\treturn ((act->flags & DUK_ACT_FLAG_STRICT) != 0 ? 1 : 0);\n\t} else {\n\t\t/* Strict by default. */\n\t\treturn 1;\n\t}\n}\n\n/*\n *  Duktape/C function magic\n */\n\nDUK_EXTERNAL duk_int_t duk_get_current_magic(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_hobject *func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act) {\n\t\tfunc = DUK_ACT_GET_FUNC(act);\n\t\tif (!func) {\n\t\t\tduk_tval *tv = &act->tv_func;\n\t\t\tduk_small_uint_t lf_flags;\n\t\t\tlf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv);\n\t\t\treturn (duk_int_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags);\n\t\t}\n\t\tDUK_ASSERT(func != NULL);\n\n\t\tif (DUK_HOBJECT_IS_NATFUNC(func)) {\n\t\t\tduk_hnatfunc *nf = (duk_hnatfunc *) func;\n\t\t\treturn (duk_int_t) nf->magic;\n\t\t}\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_int_t duk_get_magic(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (!DUK_HOBJECT_HAS_NATFUNC(h)) {\n\t\t\tgoto type_error;\n\t\t}\n\t\treturn (duk_int_t) ((duk_hnatfunc *) h)->magic;\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_small_uint_t lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv);\n\t\treturn (duk_int_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags);\n\t}\n\n\t/* fall through */\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_UNEXPECTED_TYPE);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_EXTERNAL void duk_set_magic(duk_hthread *thr, duk_idx_t idx, duk_int_t magic) {\n\tduk_hnatfunc *nf;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tnf = duk_require_hnatfunc(thr, idx);\n\tDUK_ASSERT(nf != NULL);\n\tnf->magic = (duk_int16_t) magic;\n}\n\n/*\n *  Misc helpers\n */\n\n/* Resolve a bound function on value stack top to a non-bound target\n * (leave other values as is).\n */\nDUK_INTERNAL void duk_resolve_nonbound_function(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_HTHREAD_ASSERT_VALID(thr);\n\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(h)) {\n\t\t\tduk_push_tval(thr, &((duk_hboundfunc *) (void *) h)->target);\n\t\t\tduk_replace(thr, -2);\n#if 0\n\t\t\tDUK_TVAL_SET_TVAL(tv, &((duk_hboundfunc *) h)->target);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tDUK_HOBJECT_DECREF_NORZ(thr, h);\n#endif\n\t\t\t/* Rely on Function.prototype.bind() on never creating a bound\n\t\t\t * function whose target is not proper.  This is now safe\n\t\t\t * because the target is not even an internal property but a\n\t\t\t * struct member.\n\t\t\t */\n\t\t\tDUK_ASSERT(duk_is_lightfunc(thr, -1) || duk_is_callable(thr, -1));\n\t\t}\n\t}\n\n\t/* Lightfuncs cannot be bound but are always callable and\n\t * constructable.\n\t */\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_api_codec.c",
    "content": "/*\n *  Encoding and decoding basic formats: hex, base64.\n *\n *  These are in-place operations which may allow an optimized implementation.\n *\n *  Base-64: https://tools.ietf.org/html/rfc4648#section-4\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Misc helpers\n */\n\n/* Shared handling for encode/decode argument.  Fast path handling for\n * buffer and string values because they're the most common.  In particular,\n * avoid creating a temporary string or buffer when possible.  Return value\n * is guaranteed to be non-NULL, even for zero length input.\n */\nDUK_LOCAL const duk_uint8_t *duk__prep_codec_arg(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tconst void *def_ptr = (const void *) out_len;  /* Any non-NULL pointer will do. */\n\tconst void *ptr;\n\tduk_bool_t isbuffer;\n\n\tDUK_ASSERT(out_len != NULL);\n\tDUK_ASSERT(def_ptr != NULL);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx));  /* checked by caller */\n\n\tptr = (const void *) duk_get_buffer_data_raw(thr, idx, out_len, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, &isbuffer);\n\tif (isbuffer) {\n\t\tDUK_ASSERT(ptr != NULL || *out_len == 0U);\n\t\tif (DUK_UNLIKELY(ptr == NULL)) {\n\t\t\tptr = def_ptr;\n\t\t}\n\t\tDUK_ASSERT(ptr != NULL);\n\t} else {\n\t\t/* For strings a non-NULL pointer is always guaranteed because\n\t\t * at least a NUL will be present.\n\t\t */\n\t\tptr = (const void *) duk_to_lstring(thr, idx, out_len);\n\t\tDUK_ASSERT(ptr != NULL);\n\t}\n\tDUK_ASSERT(ptr != NULL);\n\treturn (const duk_uint8_t *) ptr;\n}\n\n/*\n *  Base64\n */\n\n#if defined(DUK_USE_BASE64_SUPPORT)\n/* Bytes emitted for number of padding characters in range [0,4]. */\nDUK_LOCAL const duk_int8_t duk__base64_decode_nequal_step[5] = {\n\t3,   /* #### -> 24 bits, emit 3 bytes */\n\t2,   /* ###= -> 18 bits, emit 2 bytes */\n\t1,   /* ##== -> 12 bits, emit 1 byte */\n\t-1,  /* #=== -> 6 bits, error */\n\t0,   /* ==== -> 0 bits, emit 0 bytes */\n};\n\n#if defined(DUK_USE_BASE64_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__base64_enctab_fast[64] = {\n\t0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, 0x50U,  /* A...P */\n\t0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, 0x58U, 0x59U, 0x5aU, 0x61U, 0x62U, 0x63U, 0x64U, 0x65U, 0x66U,  /* Q...f */\n\t0x67U, 0x68U, 0x69U, 0x6aU, 0x6bU, 0x6cU, 0x6dU, 0x6eU, 0x6fU, 0x70U, 0x71U, 0x72U, 0x73U, 0x74U, 0x75U, 0x76U,  /* g...v */\n\t0x77U, 0x78U, 0x79U, 0x7aU, 0x30U, 0x31U, 0x32U, 0x33U, 0x34U, 0x35U, 0x36U, 0x37U, 0x38U, 0x39U, 0x2bU, 0x2fU   /* w.../ */\n};\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\n#if defined(DUK_USE_BASE64_FASTPATH)\n/* Decode table for one byte of input:\n *   -1 = allowed whitespace\n *   -2 = padding\n *   -3 = error\n *    0...63 decoded bytes\n */\nDUK_LOCAL const duk_int8_t duk__base64_dectab_fast[256] = {\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -1, -1, -3, -3, -1, -3, -3,  /* 0x00...0x0f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0x10...0x1f */\n\t-1, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, 62, -3, -3, -3, 63,  /* 0x20...0x2f */\n\t52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -3, -3, -3, -2, -3, -3,  /* 0x30...0x3f */\n\t-3,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,  /* 0x40...0x4f */\n\t15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -3, -3, -3, -3, -3,  /* 0x50...0x5f */\n\t-3, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,  /* 0x60...0x6f */\n\t41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -3, -3, -3, -3, -3,  /* 0x70...0x7f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0x80...0x8f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0x90...0x9f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xa0...0xaf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xb0...0xbf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xc0...0xcf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xd0...0xdf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xe0...0xef */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3   /* 0xf0...0xff */\n};\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\n#if defined(DUK_USE_BASE64_FASTPATH)\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_3(const duk_uint8_t *src, duk_uint8_t *dst) {\n\tduk_uint_t t;\n\n\tt = (duk_uint_t) src[0];\n\tt = (t << 8) + (duk_uint_t) src[1];\n\tt = (t << 8) + (duk_uint_t) src[2];\n\n\tdst[0] = duk__base64_enctab_fast[t >> 18];\n\tdst[1] = duk__base64_enctab_fast[(t >> 12) & 0x3fU];\n\tdst[2] = duk__base64_enctab_fast[(t >> 6) & 0x3fU];\n\tdst[3] = duk__base64_enctab_fast[t & 0x3fU];\n\n#if 0\n\t/* Tested: not faster on x64, most likely due to aliasing between\n\t * output and input index computation.\n\t */\n\t/* aaaaaabb bbbbcccc ccdddddd */\n\tdst[0] = duk__base64_enctab_fast[(src[0] >> 2) & 0x3fU];\n\tdst[1] = duk__base64_enctab_fast[((src[0] << 4) & 0x30U) | ((src[1] >> 4) & 0x0fU)];\n\tdst[2] = duk__base64_enctab_fast[((src[1] << 2) & 0x3fU) | ((src[2] >> 6) & 0x03U)];\n\tdst[3] = duk__base64_enctab_fast[src[2] & 0x3fU];\n#endif\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_2(const duk_uint8_t *src, duk_uint8_t *dst) {\n\tduk_uint_t t;\n\n\tt = (duk_uint_t) src[0];\n\tt = (t << 8) + (duk_uint_t) src[1];\n\tdst[0] = duk__base64_enctab_fast[t >> 10];           /* XXXXXX-- -------- */\n\tdst[1] = duk__base64_enctab_fast[(t >> 4) & 0x3fU];  /* ------XX XXXX---- */\n\tdst[2] = duk__base64_enctab_fast[(t << 2) & 0x3fU];  /* -------- ----XXXX */\n\tdst[3] = DUK_ASC_EQUALS;\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_1(const duk_uint8_t *src, duk_uint8_t *dst) {\n\tduk_uint_t t;\n\n\tt = (duk_uint_t) src[0];\n\tdst[0] = duk__base64_enctab_fast[t >> 2];            /* XXXXXX-- */\n\tdst[1] = duk__base64_enctab_fast[(t << 4) & 0x3fU];  /* ------XX */\n\tdst[2] = DUK_ASC_EQUALS;\n\tdst[3] = DUK_ASC_EQUALS;\n}\n\nDUK_LOCAL void duk__base64_encode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst) {\n\tduk_size_t n;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t *q;\n\n\tn = srclen;\n\tp = src;\n\tq = dst;\n\n\tif (n >= 16U) {\n\t\t/* Fast path, unrolled by 4, allows interleaving.  Process\n\t\t * 12-byte input chunks which encode to 16-char output chunks.\n\t\t * Only enter when at least one block is emitted (avoids div+mul\n\t\t * for short inputs too).\n\t\t */\n\t\tconst duk_uint8_t *p_end_fast;\n\n\t\tp_end_fast = p + ((n / 12U) * 12U);\n\t\tDUK_ASSERT(p_end_fast >= p + 12);\n\t\tdo {\n\t\t\tduk__base64_encode_fast_3(p, q);\n\t\t\tduk__base64_encode_fast_3(p + 3, q + 4);\n\t\t\tduk__base64_encode_fast_3(p + 6, q + 8);\n\t\t\tduk__base64_encode_fast_3(p + 9, q + 12);\n\t\t\tp += 12;\n\t\t\tq += 16;\n\t\t} while (DUK_LIKELY(p != p_end_fast));\n\n\t\tDUK_ASSERT(src + srclen >= p);\n\t\tn = (duk_size_t) (src + srclen - p);\n\t\tDUK_ASSERT(n < 12U);\n\t}\n\n\t/* Remainder. */\n\twhile (n >= 3U) {\n\t\tduk__base64_encode_fast_3(p, q);\n\t\tp += 3;\n\t\tq += 4;\n\t\tn -= 3U;\n\t}\n\tDUK_ASSERT(n == 0U || n == 1U || n == 2U);\n\tif (n == 1U) {\n\t\tduk__base64_encode_fast_1(p, q);\n#if 0  /* Unnecessary. */\n\t\tp += 1;\n\t\tq += 4;\n\t\tn -= 1U;\n#endif\n\t} else if (n == 2U) {\n\t\tduk__base64_encode_fast_2(p, q);\n#if 0  /* Unnecessary. */\n\t\tp += 2;\n\t\tq += 4;\n\t\tn -= 2U;\n#endif\n\t} else {\n\t\tDUK_ASSERT(n == 0U);  /* nothing to do */\n\t\t;\n\t}\n}\n#else  /* DUK_USE_BASE64_FASTPATH */\nDUK_LOCAL void duk__base64_encode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst) {\n\tduk_small_uint_t i, npad;\n\tduk_uint_t t, x, y;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint8_t *q;\n\n\tp = src;\n\tp_end = src + srclen;\n\tq = dst;\n\tnpad = 0U;\n\n\twhile (p < p_end) {\n\t\t/* Read 3 bytes into 't', padded by zero. */\n\t\tt = 0;\n\t\tfor (i = 0; i < 3; i++) {\n\t\t\tt = t << 8;\n\t\t\tif (p < p_end) {\n\t\t\t\tt += (duk_uint_t) (*p++);\n\t\t\t} else {\n\t\t\t\t/* This only happens on the last loop and we're\n\t\t\t\t * guaranteed to exit on the next loop.\n\t\t\t\t */\n\t\t\t\tnpad++;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(npad <= 2U);\n\n\t\t/* Emit 4 encoded characters.  If npad > 0, some of the\n\t\t * chars will be incorrect (zero bits) but we fix up the\n\t\t * padding after the loop.  A straightforward 64-byte\n\t\t * lookup would be faster and cleaner, but this is shorter.\n\t\t */\n\t\tfor (i = 0; i < 4; i++) {\n\t\t\tx = ((t >> 18) & 0x3fU);\n\t\t\tt = t << 6;\n\n\t\t\tif (x <= 51U) {\n\t\t\t\tif (x <= 25) {\n\t\t\t\t\ty = x + DUK_ASC_UC_A;\n\t\t\t\t} else {\n\t\t\t\t\ty = x - 26 + DUK_ASC_LC_A;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (x <= 61U) {\n\t\t\t\t\ty = x - 52 + DUK_ASC_0;\n\t\t\t\t} else if (x == 62) {\n\t\t\t\t\ty = DUK_ASC_PLUS;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(x == 63);\n\t\t\t\t\ty = DUK_ASC_SLASH;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t*q++ = (duk_uint8_t) y;\n\t\t}\n\t}\n\n\t/* Handle padding by rewriting 0-2 bogus characters at the end.\n\t *\n\t *  Missing bytes    npad     base64 example\n\t *    0               0         ####\n\t *    1               1         ###=\n\t *    2               2         ##==\n\t */\n\tDUK_ASSERT(npad <= 2U);\n\twhile (npad > 0U) {\n\t\t*(q - npad) = DUK_ASC_EQUALS;\n\t\tnpad--;\n\t}\n}\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\n#if defined(DUK_USE_BASE64_FASTPATH)\nDUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst, duk_uint8_t **out_dst_final) {\n\tduk_int_t x;\n\tduk_uint_t t;\n\tduk_small_uint_t n_equal;\n\tduk_int8_t step;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint8_t *p_end_safe;\n\tduk_uint8_t *q;\n\n\tDUK_ASSERT(src != NULL);  /* Required by pointer arithmetic below, which fails for NULL. */\n\n\tp = src;\n\tp_end = src + srclen;\n\tp_end_safe = p_end - 8;  /* If 'src <= src_end_safe', safe to read 8 bytes. */\n\tq = dst;\n\n\t/* Alternate between a fast path which processes clean groups with no\n\t * padding or whitespace, and a slow path which processes one arbitrary\n\t * group and then re-enters the fast path.  This handles e.g. base64\n\t * with newlines reasonably well because the majority of a line is in\n\t * the fast path.\n\t */\n\tfor (;;) {\n\t\t/* Fast path, on each loop handle two 4-char input groups.\n\t\t * If both are clean, emit 6 bytes and continue.  If first\n\t\t * is clean, emit 3 bytes and drop out; otherwise emit\n\t\t * nothing and drop out.  This approach could be extended to\n\t\t * more groups per loop, but for inputs with e.g. periodic\n\t\t * newlines (which are common) it might not be an improvement.\n\t\t */\n\t\twhile (DUK_LIKELY(p <= p_end_safe)) {\n\t\t\tduk_int_t t1, t2;\n\n\t\t\t/* The lookup byte is intentionally sign extended to\n\t\t\t * (at least) 32 bits and then ORed.  This ensures\n\t\t\t * that is at least 1 byte is negative, the highest\n\t\t\t * bit of the accumulator will be set at the end and\n\t\t\t * we don't need to check every byte.\n\t\t\t *\n\t\t\t * Read all input bytes first before writing output\n\t\t\t * bytes to minimize aliasing.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast loop: p=%p, p_end_safe=%p, p_end=%p\",\n\t\t\t                     (const void *) p, (const void *) p_end_safe, (const void *) p_end));\n\n\t\t\tt1 = (duk_int_t) duk__base64_dectab_fast[p[0]];\n\t\t\tt1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[1]];\n\t\t\tt1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[2]];\n\t\t\tt1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[3]];\n\n\t\t\tt2 = (duk_int_t) duk__base64_dectab_fast[p[4]];\n\t\t\tt2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[5]];\n\t\t\tt2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[6]];\n\t\t\tt2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[7]];\n\n\t\t\tq[0] = (duk_uint8_t) (((duk_uint_t) t1 >> 16) & 0xffU);\n\t\t\tq[1] = (duk_uint8_t) (((duk_uint_t) t1 >> 8) & 0xffU);\n\t\t\tq[2] = (duk_uint8_t) ((duk_uint_t) t1 & 0xffU);\n\n\t\t\tq[3] = (duk_uint8_t) (((duk_uint_t) t2 >> 16) & 0xffU);\n\t\t\tq[4] = (duk_uint8_t) (((duk_uint_t) t2 >> 8) & 0xffU);\n\t\t\tq[5] = (duk_uint8_t) ((duk_uint_t) t2 & 0xffU);\n\n\t\t\t/* Optimistic check using one branch. */\n\t\t\tif (DUK_LIKELY((t1 | t2) >= 0)) {\n\t\t\t\tp += 8;\n\t\t\t\tq += 6;\n\t\t\t} else if (t1 >= 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast loop first group was clean, second was not, process one slow path group\"));\n\t\t\t\tDUK_ASSERT(t2 < 0);\n\t\t\t\tp += 4;\n\t\t\t\tq += 3;\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast loop first group was not clean, second does not matter, process one slow path group\"));\n\t\t\t\tDUK_ASSERT(t1 < 0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}  /* fast path */\n\n\t\t/* Slow path step 1: try to scan a 4-character encoded group,\n\t\t * end-of-input, or start-of-padding.  We exit with:\n\t\t *   1. n_chars == 4: full group, no padding, no end-of-input.\n\t\t *   2. n_chars < 4: partial group (may also be 0), encountered\n\t\t *      padding or end of input.\n\t\t *\n\t\t * The accumulator is initialized to 1; this allows us to detect\n\t\t * a full group by comparing >= 0x1000000 without an extra\n\t\t * counter variable.\n\t\t */\n\t\tt = 1UL;\n\t\tfor (;;) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slow loop: p=%p, p_end=%p, t=%lu\",\n\t\t\t                     (const void *) p, (const void *) p_end, (unsigned long) t));\n\n\t\t\tif (DUK_LIKELY(p < p_end)) {\n\t\t\t\tx = duk__base64_dectab_fast[*p++];\n\t\t\t\tif (DUK_LIKELY(x >= 0)) {\n\t\t\t\t\tDUK_ASSERT(x >= 0 && x <= 63);\n\t\t\t\t\tt = (t << 6) + (duk_uint_t) x;\n\t\t\t\t\tif (t >= 0x1000000UL) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} else if (x == -1) {\n\t\t\t\t\tcontinue;  /* allowed ascii whitespace */\n\t\t\t\t} else if (x == -2) {\n\t\t\t\t\tp--;\n\t\t\t\t\tbreak;  /* start of padding */\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(x == -3);\n\t\t\t\t\tgoto decode_error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tbreak;  /* end of input */\n\t\t\t}\n\t\t}  /* slow path step 1 */\n\n\t\t/* Complete the padding by simulating pad characters,\n\t\t * regardless of actual input padding chars.\n\t\t */\n\t\tn_equal = 0;\n\t\twhile (t < 0x1000000UL) {\n\t\t\tt = (t << 6) + 0U;\n\t\t\tn_equal++;\n\t\t}\n\n\t\t/* Slow path step 2: deal with full/partial group, padding,\n\t\t * etc.  Note that for num chars in [0,3] we intentionally emit\n\t\t * 3 bytes but don't step forward that much, buffer space is\n\t\t * guaranteed in setup.\n\t\t *\n\t\t *  num chars:\n\t\t *   0      ####   no output (= step 0)\n\t\t *   1      #===   reject, 6 bits of data\n\t\t *   2      ##==   12 bits of data, output 1 byte (= step 1)\n\t\t *   3      ###=   18 bits of data, output 2 bytes (= step 2)\n\t\t *   4      ####   24 bits of data, output 3 bytes (= step 3)\n\t\t */\n\t\tq[0] = (duk_uint8_t) ((t >> 16) & 0xffU);\n\t\tq[1] = (duk_uint8_t) ((t >> 8) & 0xffU);\n\t\tq[2] = (duk_uint8_t) (t & 0xffU);\n\n\t\tDUK_ASSERT(n_equal <= 4);\n\t\tstep = duk__base64_decode_nequal_step[n_equal];\n\t\tif (DUK_UNLIKELY(step < 0)) {\n\t\t\tgoto decode_error;\n\t\t}\n\t\tq += step;\n\n\t\t/* Slow path step 3: read and ignore padding and whitespace\n\t\t * until (a) next non-padding and non-whitespace character\n\t\t * after which we resume the fast path, or (b) end of input.\n\t\t * This allows us to accept missing, partial, full, and extra\n\t\t * padding cases uniformly.  We also support concatenated\n\t\t * base-64 documents because we resume scanning afterwards.\n\t\t *\n\t\t * Note that to support concatenated documents well, the '='\n\t\t * padding found inside the input must also allow for 'extra'\n\t\t * padding.  For example, 'Zm===' decodes to 'f' and has one\n\t\t * extra padding char.  So, 'Zm===Zm' should decode 'ff', even\n\t\t * though the standard break-up would be 'Zm==' + '=Zm' which\n\t\t * doesn't make sense.\n\t\t *\n\t\t * We also accept prepended padding like '==Zm9', because it\n\t\t * is equivalent to an empty document with extra padding ('==')\n\t\t * followed by a valid document.\n\t\t */\n\n\t\tfor (;;) {\n\t\t\tif (DUK_UNLIKELY(p >= p_end)) {\n\t\t\t\tgoto done;\n\t\t\t}\n\t\t\tx = duk__base64_dectab_fast[*p++];\n\t\t\tif (x == -1 || x == -2) {\n\t\t\t\t;  /* padding or whitespace, keep eating */\n\t\t\t} else {\n\t\t\t\tp--;\n\t\t\t\tbreak;  /* backtrack and go back to fast path, even for -1 */\n\t\t\t}\n\t\t}  /* slow path step 3 */\n\t}  /* outer fast+slow path loop */\n\n done:\n\tDUK_DDD(DUK_DDDPRINT(\"done; p=%p, p_end=%p\",\n\t                     (const void *) p, (const void *) p_end));\n\n\tDUK_ASSERT(p == p_end);\n\n\t*out_dst_final = q;\n\treturn 1;\n\n decode_error:\n\treturn 0;\n}\n#else  /* DUK_USE_BASE64_FASTPATH */\nDUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst, duk_uint8_t **out_dst_final) {\n\tduk_uint_t t, x;\n\tduk_int_t y;\n\tduk_int8_t step;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint8_t *q;\n\t/* 0x09, 0x0a, or 0x0d */\n\tduk_uint32_t mask_white = (1U << 9) | (1U << 10) | (1U << 13);\n\n\t/* 't' tracks progress of the decoded group:\n\t *\n\t *  t == 1             no valid chars yet\n\t *  t >= 0x40          1x6 = 6 bits shifted in\n\t *  t >= 0x1000        2x6 = 12 bits shifted in\n\t *  t >= 0x40000       3x6 = 18 bits shifted in\n\t *  t >= 0x1000000     4x6 = 24 bits shifted in\n\t *\n\t * By initializing t=1 there's no need for a separate counter for\n\t * the number of characters found so far.\n\t */\n\tp = src;\n\tp_end = src + srclen;\n\tq = dst;\n\tt = 1UL;\n\n\tfor (;;) {\n\t\tduk_small_uint_t n_equal;\n\n\t\tDUK_ASSERT(t >= 1U);\n\t\tif (p >= p_end) {\n\t\t\t/* End of input: if input exists, treat like\n\t\t\t * start of padding, finish the block, then\n\t\t\t * re-enter here to see we're done.\n\t\t\t */\n\t\t\tif (t == 1U) {\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tgoto simulate_padding;\n\t\t\t}\n\t\t}\n\n\t\tx = *p++;\n\n\t\tif (x >= 0x41U) {\n\t\t\t/* Valid: a-z and A-Z. */\n\t\t\tDUK_ASSERT(x >= 0x41U && x <= 0xffU);\n\t\t\tif (x >= 0x61U && x <= 0x7aU) {\n\t\t\t\ty = (duk_int_t) x - 0x61 + 26;\n\t\t\t} else if (x <= 0x5aU) {\n\t\t\t\ty = (duk_int_t) x - 0x41;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t} else if (x >= 0x30U) {\n\t\t\t/* Valid: 0-9 and =. */\n\t\t\tDUK_ASSERT(x >= 0x30U && x <= 0x40U);\n\t\t\tif (x <= 0x39U) {\n\t\t\t\ty = (duk_int_t) x - 0x30 + 52;\n\t\t\t} else if (x == 0x3dU) {\n\t\t\t\t/* Skip padding and whitespace unless we're in the\n\t\t\t\t * middle of a block.  Otherwise complete group by\n\t\t\t\t * simulating shifting in the correct padding.\n\t\t\t\t */\n\t\t\t\tif (t == 1U) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tgoto simulate_padding;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t} else if (x >= 0x20U) {\n\t\t\t/* Valid: +, /, and 0x20 whitespace. */\n\t\t\tDUK_ASSERT(x >= 0x20U && x <= 0x2fU);\n\t\t\tif (x == 0x2bU) {\n\t\t\t\ty = 62;\n\t\t\t} else if (x == 0x2fU) {\n\t\t\t\ty = 63;\n\t\t\t} else if (x == 0x20U) {\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t} else {\n\t\t\t/* Valid: whitespace. */\n\t\t\tduk_uint32_t m;\n\t\t\tDUK_ASSERT(x < 0x20U);  /* 0x00 to 0x1f */\n\t\t\tm = (1U << x);\n\t\t\tif (mask_white & m) {\n\t\t\t\t/* Allow basic ASCII whitespace. */\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t}\n\n\t\tDUK_ASSERT(y >= 0 && y <= 63);\n\t\tt = (t << 6) + (duk_uint_t) y;\n\t\tif (t < 0x1000000UL) {\n\t\t\tcontinue;\n\t\t}\n\t\t/* fall through; no padding will be added */\n\n\t simulate_padding:\n\t\tn_equal = 0;\n\t\twhile (t < 0x1000000UL) {\n\t\t\tt = (t << 6) + 0U;\n\t\t\tn_equal++;\n\t\t}\n\n\t\t/* Output 3 bytes from 't' and advance as needed. */\n\t\tq[0] = (duk_uint8_t) ((t >> 16) & 0xffU);\n\t\tq[1] = (duk_uint8_t) ((t >> 8) & 0xffU);\n\t\tq[2] = (duk_uint8_t) (t & 0xffU);\n\n\t\tDUK_ASSERT(n_equal <= 4U);\n\t\tstep = duk__base64_decode_nequal_step[n_equal];\n\t\tif (step < 0) {\n\t\t\tgoto decode_error;\n\t\t}\n\t\tq += step;\n\n\t\t/* Re-enter loop.  The actual padding characters are skipped\n\t\t * by the main loop.  This handles cases like missing, partial,\n\t\t * full, and extra padding, and allows parsing of concatenated\n\t\t * documents (with extra padding) like: Zm===Zm.  Also extra\n\t\t * prepended padding is accepted: ===Zm9v.\n\t\t */\n\t\tt = 1U;\n\t}\n\tDUK_ASSERT(t == 1UL);\n\n\t*out_dst_final = q;\n\treturn 1;\n\n decode_error:\n\treturn 0;\n}\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\nDUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *src;\n\tduk_size_t srclen;\n\tduk_size_t dstlen;\n\tduk_uint8_t *dst;\n\tconst char *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tsrc = duk__prep_codec_arg(thr, idx, &srclen);\n\tDUK_ASSERT(src != NULL);\n\n\t/* Compute exact output length.  Computation must not wrap; this\n\t * limit works for 32-bit size_t:\n\t * >>> srclen = 3221225469\n\t * >>> '%x' % ((srclen + 2) / 3 * 4)\n\t * 'fffffffc'\n\t */\n\tif (srclen > 3221225469UL) {\n\t\tgoto type_error;\n\t}\n\tdstlen = (srclen + 2U) / 3U * 4U;\n\tdst = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, dstlen);\n\n\tduk__base64_encode_helper((const duk_uint8_t *) src, srclen, dst);\n\n\tret = duk_buffer_to_string(thr, -1);  /* Safe, result is ASCII. */\n\tduk_replace(thr, idx);\n\treturn ret;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_BASE64_ENCODE_FAILED);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *src;\n\tduk_size_t srclen;\n\tduk_size_t dstlen;\n\tduk_uint8_t *dst;\n\tduk_uint8_t *dst_final;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tsrc = duk__prep_codec_arg(thr, idx, &srclen);\n\tDUK_ASSERT(src != NULL);\n\n\t/* Round up and add safety margin.  Avoid addition before division to\n\t * avoid possibility of wrapping.  Margin includes +3 for rounding up,\n\t * and +3 for one extra group: the decoder may emit and then backtrack\n\t * a full group (3 bytes) from zero-sized input for technical reasons.\n\t * Similarly, 'xx' may ecause 1+3 = bytes to be emitted and then\n\t * backtracked.\n\t */\n\tdstlen = (srclen / 4) * 3 + 6;  /* upper limit, assuming no whitespace etc */\n\tdst = (duk_uint8_t *) duk_push_dynamic_buffer(thr, dstlen);\n\t/* Note: for dstlen=0, dst may be NULL */\n\n\tif (!duk__base64_decode_helper((const duk_uint8_t *) src, srclen, dst, &dst_final)) {\n\t\tgoto type_error;\n\t}\n\n\t/* XXX: convert to fixed buffer? */\n\t(void) duk_resize_buffer(thr, -1, (duk_size_t) (dst_final - dst));\n\tduk_replace(thr, idx);\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_BASE64_DECODE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n#else  /* DUK_USE_BASE64_SUPPORT */\nDUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_BASE64_SUPPORT */\n\n/*\n *  Hex\n */\n\n#if defined(DUK_USE_HEX_SUPPORT)\nDUK_EXTERNAL const char *duk_hex_encode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *inp;\n\tduk_size_t len;\n\tduk_size_t i;\n\tduk_uint8_t *buf;\n\tconst char *ret;\n#if defined(DUK_USE_HEX_FASTPATH)\n\tduk_size_t len_safe;\n\tduk_uint16_t *p16;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tinp = duk__prep_codec_arg(thr, idx, &len);\n\tDUK_ASSERT(inp != NULL);\n\n\t/* Fixed buffer, no zeroing because we'll fill all the data. */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len * 2);\n\tDUK_ASSERT(buf != NULL);\n\n#if defined(DUK_USE_HEX_FASTPATH)\n\tDUK_ASSERT((((duk_size_t) buf) & 0x01U) == 0);   /* pointer is aligned, guaranteed for fixed buffer */\n\tp16 = (duk_uint16_t *) (void *) buf;\n\tlen_safe = len & ~0x03U;\n\tfor (i = 0; i < len_safe; i += 4) {\n\t\tp16[0] = duk_hex_enctab[inp[i]];\n\t\tp16[1] = duk_hex_enctab[inp[i + 1]];\n\t\tp16[2] = duk_hex_enctab[inp[i + 2]];\n\t\tp16[3] = duk_hex_enctab[inp[i + 3]];\n\t\tp16 += 4;\n\t}\n\tfor (; i < len; i++) {\n\t\t*p16++ = duk_hex_enctab[inp[i]];\n\t}\n#else  /* DUK_USE_HEX_FASTPATH */\n\tfor (i = 0; i < len; i++) {\n\t\tduk_small_uint_t t;\n\t\tt = (duk_small_uint_t) inp[i];\n\t\tbuf[i*2 + 0] = duk_lc_digits[t >> 4];\n\t\tbuf[i*2 + 1] = duk_lc_digits[t & 0x0f];\n\t}\n#endif  /* DUK_USE_HEX_FASTPATH */\n\n\t/* XXX: Using a string return value forces a string intern which is\n\t * not always necessary.  As a rough performance measure, hex encode\n\t * time for tests/perf/test-hex-encode.js dropped from ~35s to ~15s\n\t * without string coercion.  Change to returning a buffer and let the\n\t * caller coerce to string if necessary?\n\t */\n\n\tret = duk_buffer_to_string(thr, -1);  /* Safe, result is ASCII. */\n\tduk_replace(thr, idx);\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *inp;\n\tduk_size_t len;\n\tduk_size_t i;\n\tduk_int_t t;\n\tduk_uint8_t *buf;\n#if defined(DUK_USE_HEX_FASTPATH)\n\tduk_int_t chk;\n\tduk_uint8_t *p;\n\tduk_size_t len_safe;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tinp = duk__prep_codec_arg(thr, idx, &len);\n\tDUK_ASSERT(inp != NULL);\n\n\tif (len & 0x01) {\n\t\tgoto type_error;\n\t}\n\n\t/* Fixed buffer, no zeroing because we'll fill all the data. */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len / 2);\n\tDUK_ASSERT(buf != NULL);\n\n#if defined(DUK_USE_HEX_FASTPATH)\n\tp = buf;\n\tlen_safe = len & ~0x07U;\n\tfor (i = 0; i < len_safe; i += 8) {\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 1]]);\n\t\tchk = t;\n\t\tp[0] = (duk_uint8_t) t;\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 2]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 3]]);\n\t\tchk |= t;\n\t\tp[1] = (duk_uint8_t) t;\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 4]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 5]]);\n\t\tchk |= t;\n\t\tp[2] = (duk_uint8_t) t;\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 6]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 7]]);\n\t\tchk |= t;\n\t\tp[3] = (duk_uint8_t) t;\n\t\tp += 4;\n\n\t\t/* Check if any lookup above had a negative result. */\n\t\tif (DUK_UNLIKELY(chk < 0)) {\n\t\t\tgoto type_error;\n\t\t}\n\t}\n\tfor (; i < len; i += 2) {\n\t\t/* First cast to duk_int_t to sign extend, second cast to\n\t\t * duk_uint_t to avoid signed left shift, and final cast to\n\t\t * duk_int_t result type.\n\t\t */\n\t\tt = (duk_int_t) ((((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i]]) << 4U) |\n\t\t                 ((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i + 1]]));\n\t\tif (DUK_UNLIKELY(t < 0)) {\n\t\t\tgoto type_error;\n\t\t}\n\t\t*p++ = (duk_uint8_t) t;\n\t}\n#else  /* DUK_USE_HEX_FASTPATH */\n\tfor (i = 0; i < len; i += 2) {\n\t\t/* For invalid characters the value -1 gets extended to\n\t\t * at least 16 bits.  If either nybble is invalid, the\n\t\t * resulting 't' will be < 0.\n\t\t */\n\t\tt = (duk_int_t) ((((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i]]) << 4U) |\n\t\t                 ((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i + 1]]));\n\t\tif (DUK_UNLIKELY(t < 0)) {\n\t\t\tgoto type_error;\n\t\t}\n\t\tbuf[i >> 1] = (duk_uint8_t) t;\n\t}\n#endif  /* DUK_USE_HEX_FASTPATH */\n\n\tduk_replace(thr, idx);\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_HEX_DECODE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n#else  /* DUK_USE_HEX_SUPPORT */\nDUK_EXTERNAL const char *duk_hex_encode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\nDUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_HEX_SUPPORT */\n\n/*\n *  JSON\n */\n\n#if defined(DUK_USE_JSON_SUPPORT)\nDUK_EXTERNAL const char *duk_json_encode(duk_hthread *thr, duk_idx_t idx) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t top_at_entry;\n#endif\n\tconst char *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\ttop_at_entry = duk_get_top(thr);\n#endif\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tduk_bi_json_stringify_helper(thr,\n\t                             idx /*idx_value*/,\n\t                             DUK_INVALID_INDEX /*idx_replacer*/,\n\t                             DUK_INVALID_INDEX /*idx_space*/,\n\t                             0 /*flags*/);\n\tDUK_ASSERT(duk_is_string(thr, -1));\n\tduk_replace(thr, idx);\n\tret = duk_get_string(thr, idx);\n\n\tDUK_ASSERT(duk_get_top(thr) == top_at_entry);\n\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_json_decode(duk_hthread *thr, duk_idx_t idx) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t top_at_entry;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\ttop_at_entry = duk_get_top(thr);\n#endif\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tduk_bi_json_parse_helper(thr,\n\t                         idx /*idx_value*/,\n\t                         DUK_INVALID_INDEX /*idx_reviver*/,\n\t                         0 /*flags*/);\n\tduk_replace(thr, idx);\n\n\tDUK_ASSERT(duk_get_top(thr) == top_at_entry);\n}\n#else  /* DUK_USE_JSON_SUPPORT */\nDUK_EXTERNAL const char *duk_json_encode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_EXTERNAL void duk_json_decode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_JSON_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_api_compile.c",
    "content": "/*\n *  Compilation and evaluation\n */\n\n#include \"duk_internal.h\"\n\ntypedef struct duk__compile_raw_args duk__compile_raw_args;\nstruct duk__compile_raw_args {\n\tduk_size_t src_length;  /* should be first on 64-bit platforms */\n\tconst duk_uint8_t *src_buffer;\n\tduk_uint_t flags;\n};\n\n/* Eval is just a wrapper now. */\nDUK_EXTERNAL duk_int_t duk_eval_raw(duk_hthread *thr, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: strictness is *not* inherited from the current Duktape/C.\n\t * This would be confusing because the current strictness state\n\t * depends on whether we're running inside a Duktape/C activation\n\t * (= strict mode) or outside of any activation (= non-strict mode).\n\t * See tests/api/test-eval-strictness.c for more discussion.\n\t */\n\n\t/* [ ... source? filename? ] (depends on flags) */\n\n\trc = duk_compile_raw(thr, src_buffer, src_length, flags | DUK_COMPILE_EVAL);  /* may be safe, or non-safe depending on flags */\n\n\t/* [ ... closure/error ] */\n\n\tif (rc != DUK_EXEC_SUCCESS) {\n\t\trc = DUK_EXEC_ERROR;\n\t\tgoto got_rc;\n\t}\n\n\tduk_push_global_object(thr);  /* explicit 'this' binding, see GH-164 */\n\n\tif (flags & DUK_COMPILE_SAFE) {\n\t\trc = duk_pcall_method(thr, 0);\n\t} else {\n\t\tduk_call_method(thr, 0);\n\t\trc = DUK_EXEC_SUCCESS;\n\t}\n\n\t/* [ ... result/error ] */\n\n got_rc:\n\tif (flags & DUK_COMPILE_NORESULT) {\n\t\tduk_pop(thr);\n\t}\n\n\treturn rc;\n}\n\n/* Helper which can be called both directly and with duk_safe_call(). */\nDUK_LOCAL duk_ret_t duk__do_compile(duk_hthread *thr, void *udata) {\n\tduk__compile_raw_args *comp_args;\n\tduk_uint_t flags;\n\tduk_hcompfunc *h_templ;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\t/* Note: strictness is not inherited from the current Duktape/C\n\t * context.  Otherwise it would not be possible to compile\n\t * non-strict code inside a Duktape/C activation (which is\n\t * always strict now).  See tests/api/test-eval-strictness.c\n\t * for discussion.\n\t */\n\n\t/* [ ... source? filename? ] (depends on flags) */\n\n\tcomp_args = (duk__compile_raw_args *) udata;\n\tflags = comp_args->flags;\n\n\tif (flags & DUK_COMPILE_NOFILENAME) {\n\t\t/* Automatic filename: 'eval' or 'input'. */\n\t\tduk_push_hstring_stridx(thr, (flags & DUK_COMPILE_EVAL) ? DUK_STRIDX_EVAL : DUK_STRIDX_INPUT);\n\t}\n\n\t/* [ ... source? filename ] */\n\n\tif (!comp_args->src_buffer) {\n\t\tduk_hstring *h_sourcecode;\n\n\t\th_sourcecode = duk_get_hstring(thr, -2);\n\t\tif ((flags & DUK_COMPILE_NOSOURCE) ||  /* args incorrect */\n\t\t    (h_sourcecode == NULL)) {          /* e.g. duk_push_string_file_raw() pushed undefined */\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_NO_SOURCECODE);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tDUK_ASSERT(h_sourcecode != NULL);\n\t\tcomp_args->src_buffer = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_sourcecode);\n\t\tcomp_args->src_length = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sourcecode);\n\t}\n\tDUK_ASSERT(comp_args->src_buffer != NULL);\n\n\tif (flags & DUK_COMPILE_FUNCTION) {\n\t\tflags |= DUK_COMPILE_EVAL | DUK_COMPILE_FUNCEXPR;\n\t}\n\n\t/* [ ... source? filename ] */\n\n\tduk_js_compile(thr, comp_args->src_buffer, comp_args->src_length, flags);\n\n\t/* [ ... source? func_template ] */\n\n\tif (flags & DUK_COMPILE_NOSOURCE) {\n\t\t;\n\t} else {\n\t\tduk_remove_m2(thr);\n\t}\n\n\t/* [ ... func_template ] */\n\n\th_templ = (duk_hcompfunc *) duk_known_hobject(thr, -1);\n\tduk_js_push_closure(thr,\n\t                   h_templ,\n\t                   thr->builtins[DUK_BIDX_GLOBAL_ENV],\n\t                   thr->builtins[DUK_BIDX_GLOBAL_ENV],\n\t                   1 /*add_auto_proto*/);\n\tduk_remove_m2(thr);   /* -> [ ... closure ] */\n\n\t/* [ ... closure ] */\n\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_compile_raw(duk_hthread *thr, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) {\n\tduk__compile_raw_args comp_args_alloc;\n\tduk__compile_raw_args *comp_args = &comp_args_alloc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif ((flags & DUK_COMPILE_STRLEN) && (src_buffer != NULL)) {\n\t\t/* String length is computed here to avoid multiple evaluation\n\t\t * of a macro argument in the calling side.\n\t\t */\n\t\tsrc_length = DUK_STRLEN(src_buffer);\n\t}\n\n\tcomp_args->src_buffer = (const duk_uint8_t *) src_buffer;\n\tcomp_args->src_length = src_length;\n\tcomp_args->flags = flags;\n\n\t/* [ ... source? filename? ] (depends on flags) */\n\n\tif (flags & DUK_COMPILE_SAFE) {\n\t\tduk_int_t rc;\n\t\tduk_int_t nargs;\n\t\tduk_int_t nrets = 1;\n\n\t\t/* Arguments can be: [ source? filename? &comp_args] so that\n\t\t * nargs is 1 to 3.  Call site encodes the correct nargs count\n\t\t * directly into flags.\n\t\t */\n\t\tnargs = flags & 0x07;\n\t\tDUK_ASSERT(nargs == ((flags & DUK_COMPILE_NOSOURCE) ? 0 : 1) +\n\t\t                    ((flags & DUK_COMPILE_NOFILENAME) ? 0 : 1));\n\t\trc = duk_safe_call(thr, duk__do_compile, (void *) comp_args, nargs, nrets);\n\n\t\t/* [ ... closure ] */\n\t\treturn rc;\n\t}\n\n\t(void) duk__do_compile(thr, (void *) comp_args);\n\n\t/* [ ... closure ] */\n\treturn DUK_EXEC_SUCCESS;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_api_debug.c",
    "content": "/*\n *  Debugging related API calls\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_JSON_SUPPORT)\nDUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr) {\n\tduk_idx_t idx;\n\tduk_idx_t top;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* We don't duk_require_stack() here now, but rely on the caller having\n\t * enough space.\n\t */\n\n\ttop = duk_get_top(thr);\n\tduk_push_bare_array(thr);\n\tfor (idx = 0; idx < top; idx++) {\n\t\tduk_dup(thr, idx);\n\t\tduk_put_prop_index(thr, -2, (duk_uarridx_t) idx);\n\t}\n\n\t/* XXX: conversion errors should not propagate outwards.\n\t * Perhaps values need to be coerced individually?\n\t */\n\tduk_bi_json_stringify_helper(thr,\n\t                             duk_get_top_index(thr),  /*idx_value*/\n\t                             DUK_INVALID_INDEX,  /*idx_replacer*/\n\t                             DUK_INVALID_INDEX,  /*idx_space*/\n\t                             DUK_JSON_FLAG_EXT_CUSTOM |\n\t                             DUK_JSON_FLAG_ASCII_ONLY |\n\t                             DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/);\n\n\tduk_push_sprintf(thr, \"ctx: top=%ld, stack=%s\", (long) top, (const char *) duk_safe_to_string(thr, -1));\n\tduk_replace(thr, -3);  /* [ ... arr jsonx(arr) res ] -> [ ... res jsonx(arr) ] */\n\tduk_pop(thr);\n\tDUK_ASSERT(duk_is_string(thr, -1));\n}\n#else  /* DUK_USE_JSON_SUPPORT */\nDUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_JSON_SUPPORT */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\nDUK_EXTERNAL void duk_debugger_attach(duk_hthread *thr,\n                                      duk_debug_read_function read_cb,\n                                      duk_debug_write_function write_cb,\n                                      duk_debug_peek_function peek_cb,\n                                      duk_debug_read_flush_function read_flush_cb,\n                                      duk_debug_write_flush_function write_flush_cb,\n                                      duk_debug_request_function request_cb,\n                                      duk_debug_detached_function detached_cb,\n                                      void *udata) {\n\tduk_heap *heap;\n\tconst char *str;\n\tduk_size_t len;\n\n\t/* XXX: should there be an error or an automatic detach if\n\t * already attached?\n\t */\n\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_attach()\"));\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(read_cb != NULL);\n\tDUK_ASSERT(write_cb != NULL);\n\t/* Other callbacks are optional. */\n\n\theap = thr->heap;\n\theap->dbg_read_cb = read_cb;\n\theap->dbg_write_cb = write_cb;\n\theap->dbg_peek_cb = peek_cb;\n\theap->dbg_read_flush_cb = read_flush_cb;\n\theap->dbg_write_flush_cb = write_flush_cb;\n\theap->dbg_request_cb = request_cb;\n\theap->dbg_detached_cb = detached_cb;\n\theap->dbg_udata = udata;\n\theap->dbg_have_next_byte = 0;\n\n\t/* Start in paused state. */\n\theap->dbg_processing = 0;\n\theap->dbg_state_dirty = 0;\n\theap->dbg_force_restart = 0;\n\theap->dbg_pause_flags = 0;\n\theap->dbg_pause_act = NULL;\n\theap->dbg_pause_startline = 0;\n\theap->dbg_exec_counter = 0;\n\theap->dbg_last_counter = 0;\n\theap->dbg_last_time = 0.0;\n\tduk_debug_set_paused(heap);  /* XXX: overlap with fields above */\n\n\t/* Send version identification and flush right afterwards.  Note that\n\t * we must write raw, unframed bytes here.\n\t */\n\tduk_push_sprintf(thr, \"%ld %ld %s %s\\n\",\n\t                 (long) DUK_DEBUG_PROTOCOL_VERSION,\n\t                 (long) DUK_VERSION,\n\t                 (const char *) DUK_GIT_DESCRIBE,\n\t                 (const char *) DUK_USE_TARGET_INFO);\n\tstr = duk_get_lstring(thr, -1, &len);\n\tDUK_ASSERT(str != NULL);\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) str, len);\n\tduk_debug_write_flush(thr);\n\tduk_pop(thr);\n}\n\nDUK_EXTERNAL void duk_debugger_detach(duk_hthread *thr) {\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_detach()\"));\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\t/* Can be called multiple times with no harm. */\n\tduk_debug_do_detach(thr->heap);\n}\n\nDUK_EXTERNAL void duk_debugger_cooperate(duk_hthread *thr) {\n\tduk_bool_t processed_messages;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tif (!duk_debug_is_attached(thr->heap)) {\n\t\treturn;\n\t}\n\tif (thr->callstack_curr != NULL || thr->heap->dbg_processing) {\n\t\t/* Calling duk_debugger_cooperate() while Duktape is being\n\t\t * called into is not supported.  This is not a 100% check\n\t\t * but prevents any damage in most cases.\n\t\t */\n\t\treturn;\n\t}\n\n\tprocessed_messages = duk_debug_process_messages(thr, 1 /*no_block*/);\n\tDUK_UNREF(processed_messages);\n}\n\nDUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_hthread *thr, duk_idx_t nvalues) {\n\tduk_idx_t top;\n\tduk_idx_t idx;\n\tduk_bool_t ret = 0;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_notify() with nvalues=%ld\", (long) nvalues));\n\n\ttop = duk_get_top(thr);\n\tif (top < nvalues) {\n\t\tDUK_ERROR_RANGE(thr, \"not enough stack values for notify\");\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tduk_debug_write_notify(thr, DUK_DBG_CMD_APPNOTIFY);\n\t\tfor (idx = top - nvalues; idx < top; idx++) {\n\t\t\tduk_tval *tv = DUK_GET_TVAL_POSIDX(thr, idx);\n\t\t\tduk_debug_write_tval(thr, tv);\n\t\t}\n\t\tduk_debug_write_eom(thr);\n\n\t\t/* Return non-zero (true) if we have a good reason to believe\n\t\t * the notify was delivered; if we're still attached at least\n\t\t * a transport error was not indicated by the transport write\n\t\t * callback.  This is not a 100% guarantee of course.\n\t\t */\n\t\tif (duk_debug_is_attached(thr->heap)) {\n\t\t\tret = 1;\n\t\t}\n\t}\n\tduk_pop_n(thr, nvalues);\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_debugger_pause(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_pause()\"));\n\n\t/* Treat like a debugger statement: ignore when not attached. */\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tif (duk_debug_is_paused(thr->heap)) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_debugger_pause() called when already paused; ignoring\"));\n\t\t} else {\n\t\t\tduk_debug_set_paused(thr->heap);\n\n\t\t\t/* Pause on the next opcode executed.  This is always safe to do even\n\t\t\t * inside the debugger message loop: the interrupt counter will be reset\n\t\t\t * to its proper value when the message loop exits.\n\t\t\t */\n\t\t\tthr->interrupt_init = 1;\n\t\t\tthr->interrupt_counter = 0;\n\t\t}\n\t}\n}\n\n#else  /* DUK_USE_DEBUGGER_SUPPORT */\n\nDUK_EXTERNAL void duk_debugger_attach(duk_hthread *thr,\n                                      duk_debug_read_function read_cb,\n                                      duk_debug_write_function write_cb,\n                                      duk_debug_peek_function peek_cb,\n                                      duk_debug_read_flush_function read_flush_cb,\n                                      duk_debug_write_flush_function write_flush_cb,\n                                      duk_debug_request_function request_cb,\n                                      duk_debug_detached_function detached_cb,\n                                      void *udata) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(read_cb);\n\tDUK_UNREF(write_cb);\n\tDUK_UNREF(peek_cb);\n\tDUK_UNREF(read_flush_cb);\n\tDUK_UNREF(write_flush_cb);\n\tDUK_UNREF(request_cb);\n\tDUK_UNREF(detached_cb);\n\tDUK_UNREF(udata);\n\tDUK_ERROR_TYPE(thr, \"no debugger support\");\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_debugger_detach(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_TYPE(thr, \"no debugger support\");\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_debugger_cooperate(duk_hthread *thr) {\n\t/* nop */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n}\n\nDUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_hthread *thr, duk_idx_t nvalues) {\n\tduk_idx_t top;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttop = duk_get_top(thr);\n\tif (top < nvalues) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* No debugger support, just pop values. */\n\tduk_pop_n(thr, nvalues);\n\treturn 0;\n}\n\nDUK_EXTERNAL void duk_debugger_pause(duk_hthread *thr) {\n\t/* Treat like debugger statement: nop */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n}\n\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_api_heap.c",
    "content": "/*\n *  Heap creation and destruction\n */\n\n#include \"duk_internal.h\"\n\ntypedef struct duk_internal_thread_state duk_internal_thread_state;\n\nstruct duk_internal_thread_state {\n\tduk_ljstate lj;\n\tduk_bool_t creating_error;\n\tduk_hthread *curr_thread;\n\tduk_int_t call_recursion_depth;\n};\n\nDUK_EXTERNAL duk_hthread *duk_create_heap(duk_alloc_function alloc_func,\n                                          duk_realloc_function realloc_func,\n                                          duk_free_function free_func,\n                                          void *heap_udata,\n                                          duk_fatal_function fatal_handler) {\n\tduk_heap *heap = NULL;\n\tduk_hthread *thr;\n\n\t/* Assume that either all memory funcs are NULL or non-NULL, mixed\n\t * cases will now be unsafe.\n\t */\n\n\t/* XXX: just assert non-NULL values here and make caller arguments\n\t * do the defaulting to the default implementations (smaller code)?\n\t */\n\n\tif (!alloc_func) {\n\t\tDUK_ASSERT(realloc_func == NULL);\n\t\tDUK_ASSERT(free_func == NULL);\n#if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS)\n\t\talloc_func = duk_default_alloc_function;\n\t\trealloc_func = duk_default_realloc_function;\n\t\tfree_func = duk_default_free_function;\n#else\n\t\tDUK_D(DUK_DPRINT(\"no allocation functions given and no default providers\"));\n\t\treturn NULL;\n#endif\n\t} else {\n\t\tDUK_ASSERT(realloc_func != NULL);\n\t\tDUK_ASSERT(free_func != NULL);\n\t}\n\n\tif (!fatal_handler) {\n\t\tfatal_handler = duk_default_fatal_handler;\n\t}\n\n\tDUK_ASSERT(alloc_func != NULL);\n\tDUK_ASSERT(realloc_func != NULL);\n\tDUK_ASSERT(free_func != NULL);\n\tDUK_ASSERT(fatal_handler != NULL);\n\n\theap = duk_heap_alloc(alloc_func, realloc_func, free_func, heap_udata, fatal_handler);\n\tif (!heap) {\n\t\treturn NULL;\n\t}\n\tthr = heap->heap_thread;\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\treturn thr;\n}\n\nDUK_EXTERNAL void duk_destroy_heap(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tif (!thr) {\n\t\treturn;\n\t}\n\tDUK_ASSERT_API_ENTRY(thr);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tduk_heap_free(heap);\n}\n\nDUK_EXTERNAL void duk_suspend(duk_hthread *thr, duk_thread_state *state) {\n\tduk_internal_thread_state *snapshot = (duk_internal_thread_state *) (void *) state;\n\tduk_heap *heap;\n\tduk_ljstate *lj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(state != NULL);  /* unvalidated */\n\n\t/* Currently not supported when called from within a finalizer.\n\t * If that is done, the finalizer will remain running indefinitely,\n\t * preventing other finalizers from executing.  The assert is a bit\n\t * wider, checking that it would be OK to run pending finalizers.\n\t */\n\tDUK_ASSERT(thr->heap->pf_prevent_count == 0);\n\n\t/* Currently not supported to duk_suspend() from an errCreate()\n\t * call.\n\t */\n\tDUK_ASSERT(thr->heap->creating_error == 0);\n\n\theap = thr->heap;\n\tlj = &heap->lj;\n\n\tduk_push_tval(thr, &lj->value1);\n\tduk_push_tval(thr, &lj->value2);\n\n\t/* XXX: creating_error == 0 is asserted above, so no need to store. */\n\tduk_memcpy((void *) &snapshot->lj, (const void *) lj, sizeof(duk_ljstate));\n\tsnapshot->creating_error = heap->creating_error;\n\tsnapshot->curr_thread = heap->curr_thread;\n\tsnapshot->call_recursion_depth = heap->call_recursion_depth;\n\n\tlj->jmpbuf_ptr = NULL;\n\tlj->type = DUK_LJ_TYPE_UNKNOWN;\n\tDUK_TVAL_SET_UNDEFINED(&lj->value1);\n\tDUK_TVAL_SET_UNDEFINED(&lj->value2);\n\theap->creating_error = 0;\n\theap->curr_thread = NULL;\n\theap->call_recursion_depth = 0;\n}\n\nDUK_EXTERNAL void duk_resume(duk_hthread *thr, const duk_thread_state *state) {\n\tconst duk_internal_thread_state *snapshot = (const duk_internal_thread_state *) (const void *) state;\n\tduk_heap *heap;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(state != NULL);  /* unvalidated */\n\n\t/* Shouldn't be necessary if duk_suspend() is called before\n\t * duk_resume(), but assert in case API sequence is incorrect.\n\t */\n\tDUK_ASSERT(thr->heap->pf_prevent_count == 0);\n\tDUK_ASSERT(thr->heap->creating_error == 0);\n\n\theap = thr->heap;\n\n\tduk_memcpy((void *) &heap->lj, (const void *) &snapshot->lj, sizeof(duk_ljstate));\n\theap->creating_error = snapshot->creating_error;\n\theap->curr_thread = snapshot->curr_thread;\n\theap->call_recursion_depth = snapshot->call_recursion_depth;\n\n\tduk_pop_2(thr);\n}\n\n/* XXX: better place for this */\nDUK_EXTERNAL void duk_set_global_object(duk_hthread *thr) {\n\tduk_hobject *h_glob;\n\tduk_hobject *h_prev_glob;\n\tduk_hobjenv *h_env;\n\tduk_hobject *h_prev_env;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_D(DUK_DPRINT(\"replace global object with: %!T\", duk_get_tval(thr, -1)));\n\n\th_glob = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(h_glob != NULL);\n\n\t/*\n\t *  Replace global object.\n\t */\n\n\th_prev_glob = thr->builtins[DUK_BIDX_GLOBAL];\n\tDUK_UNREF(h_prev_glob);\n\tthr->builtins[DUK_BIDX_GLOBAL] = h_glob;\n\tDUK_HOBJECT_INCREF(thr, h_glob);\n\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, h_prev_glob);  /* side effects, in theory (referenced by global env) */\n\n\t/*\n\t *  Replace lexical environment for global scope\n\t *\n\t *  Create a new object environment for the global lexical scope.\n\t *  We can't just reset the _Target property of the current one,\n\t *  because the lexical scope is shared by other threads with the\n\t *  same (initial) built-ins.\n\t */\n\n\th_env = duk_hobjenv_alloc(thr,\n\t                          DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                          DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\tDUK_ASSERT(h_env != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_env) == NULL);\n\n\tDUK_ASSERT(h_env->target == NULL);\n\tDUK_ASSERT(h_glob != NULL);\n\th_env->target = h_glob;\n\tDUK_HOBJECT_INCREF(thr, h_glob);\n\tDUK_ASSERT(h_env->has_this == 0);\n\n\t/* [ ... new_glob ] */\n\n\th_prev_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\tthr->builtins[DUK_BIDX_GLOBAL_ENV] = (duk_hobject *) h_env;\n\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) h_env);\n\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, h_prev_env);  /* side effects */\n\tDUK_UNREF(h_env);  /* without refcounts */\n\tDUK_UNREF(h_prev_env);\n\n\t/* [ ... new_glob ] */\n\n\tduk_pop(thr);\n\n\t/* [ ... ] */\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_api_inspect.c",
    "content": "/*\n *  Inspection\n */\n\n#include \"duk_internal.h\"\n\n/* For footprint efficient multiple value setting: arrays are much better than\n * varargs, format string with parsing is often better than string pointer arrays.\n */\nDUK_LOCAL void duk__inspect_multiple_uint(duk_hthread *thr, const char *fmt, duk_int_t *vals) {\n\tduk_int_t val;\n\tconst char *p;\n\tconst char *p_curr;\n\tduk_size_t len;\n\n\tfor (p = fmt;;) {\n\t\tlen = DUK_STRLEN(p);\n\t\tp_curr = p;\n\t\tp += len + 1;\n\t\tif (len == 0) {\n\t\t\t/* Double NUL (= empty key) terminates. */\n\t\t\tbreak;\n\t\t}\n\t\tval = *vals++;\n\t\tif (val >= 0) {\n\t\t\t/* Negative values are markers to skip key. */\n\t\t\tduk_push_string(thr, p_curr);\n\t\t\tduk_push_int(thr, val);\n\t\t\tduk_put_prop(thr, -3);\n\t\t}\n\t}\n}\n\n/* Raw helper to extract internal information / statistics about a value.\n * The return value is an object with properties that are version specific.\n * The properties must not expose anything that would lead to security\n * issues (e.g. exposing compiled function 'data' buffer might be an issue).\n * Currently only counts and sizes and such are given so there shouldn't\n * be security implications.\n */\n\n#define DUK__IDX_TYPE     0\n#define DUK__IDX_ITAG     1\n#define DUK__IDX_REFC     2\n#define DUK__IDX_HBYTES   3\n#define DUK__IDX_CLASS    4\n#define DUK__IDX_PBYTES   5\n#define DUK__IDX_ESIZE    6\n#define DUK__IDX_ENEXT    7\n#define DUK__IDX_ASIZE    8\n#define DUK__IDX_HSIZE    9\n#define DUK__IDX_BCBYTES  10\n#define DUK__IDX_DBYTES   11\n#define DUK__IDX_TSTATE   12\n#define DUK__IDX_VARIANT  13\n\nDUK_EXTERNAL void duk_inspect_value(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_heaphdr *h;\n\t/* The temporary values should be in an array rather than individual\n\t * variables which (in practice) ensures that the compiler won't map\n\t * them to registers and emit a lot of unnecessary shuffling code.\n\t */\n\tduk_int_t vals[14];\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Assume two's complement and set everything to -1. */\n\tduk_memset((void *) &vals, (int) 0xff, sizeof(vals));\n\tDUK_ASSERT(vals[DUK__IDX_TYPE] == -1);  /* spot check one */\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\th = (DUK_TVAL_IS_HEAP_ALLOCATED(tv) ? DUK_TVAL_GET_HEAPHDR(tv) : NULL);\n\n\tvals[DUK__IDX_TYPE] = duk_get_type_tval(tv);\n\tvals[DUK__IDX_ITAG] = (duk_int_t) DUK_TVAL_GET_TAG(tv);\n\n\tduk_push_bare_object(thr);  /* Invalidates 'tv'. */\n\ttv = NULL;\n\n\tif (h == NULL) {\n\t\tgoto finish;\n\t}\n\tduk_push_pointer(thr, (void *) h);\n\tduk_put_prop_literal(thr, -2, \"hptr\");\n\n#if 0\n\t/* Covers a lot of information, e.g. buffer and string variants. */\n\tduk_push_uint(thr, (duk_uint_t) DUK_HEAPHDR_GET_FLAGS(h));\n\tduk_put_prop_literal(thr, -2, \"hflags\");\n#endif\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tvals[DUK__IDX_REFC] = (duk_int_t) DUK_HEAPHDR_GET_REFCOUNT(h);\n#endif\n\tvals[DUK__IDX_VARIANT] = 0;\n\n\t/* Heaphdr size and additional allocation size, followed by\n\t * type specific stuff (with varying value count).\n\t */\n\tswitch ((duk_small_int_t) DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h_str = (duk_hstring *) h;\n\t\tvals[DUK__IDX_HBYTES] = (duk_int_t) (sizeof(duk_hstring) + DUK_HSTRING_GET_BYTELEN(h_str) + 1);\n#if defined(DUK_USE_HSTRING_EXTDATA)\n\t\tif (DUK_HSTRING_HAS_EXTDATA(h_str)) {\n\t\t\tvals[DUK__IDX_VARIANT] = 1;\n\t\t}\n#endif\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h_obj = (duk_hobject *) h;\n\n\t\t/* XXX: variants here are maybe pointless; class is enough? */\n\t\tif (DUK_HOBJECT_IS_ARRAY(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_harray);\n\t\t} else if (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hcompfunc);\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hnatfunc);\n\t\t} else if (DUK_HOBJECT_IS_THREAD(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hthread);\n\t\t\tvals[DUK__IDX_TSTATE] = ((duk_hthread *) h_obj)->state;\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hbufobj);\n\t\t\t/* XXX: some size information */\n#endif\n\t\t} else {\n\t\t\tvals[DUK__IDX_HBYTES] = (duk_small_uint_t) sizeof(duk_hobject);\n\t\t}\n\n\t\tvals[DUK__IDX_CLASS] = (duk_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h_obj);\n\t\tvals[DUK__IDX_PBYTES] = (duk_int_t) DUK_HOBJECT_P_ALLOC_SIZE(h_obj);\n\t\tvals[DUK__IDX_ESIZE] = (duk_int_t) DUK_HOBJECT_GET_ESIZE(h_obj);\n\t\tvals[DUK__IDX_ENEXT] = (duk_int_t) DUK_HOBJECT_GET_ENEXT(h_obj);\n\t\tvals[DUK__IDX_ASIZE] = (duk_int_t) DUK_HOBJECT_GET_ASIZE(h_obj);\n\t\tvals[DUK__IDX_HSIZE] = (duk_int_t) DUK_HOBJECT_GET_HSIZE(h_obj);\n\n\t\t/* Note: e_next indicates the number of gc-reachable entries\n\t\t * in the entry part, and also indicates the index where the\n\t\t * next new property would be inserted.  It does *not* indicate\n\t\t * the number of non-NULL keys present in the object.  That\n\t\t * value could be counted separately but requires a pass through\n\t\t * the key list.\n\t\t */\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tduk_hbuffer *h_data = (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(thr->heap, (duk_hcompfunc *) h_obj);\n\t\t\tvals[DUK__IDX_BCBYTES] = (duk_int_t) (h_data ? DUK_HBUFFER_GET_SIZE(h_data) : 0);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h_buf = (duk_hbuffer *) h;\n\n\t\tif (DUK_HBUFFER_HAS_DYNAMIC(h_buf)) {\n\t\t\tif (DUK_HBUFFER_HAS_EXTERNAL(h_buf)) {\n\t\t\t\tvals[DUK__IDX_VARIANT] = 2;  /* buffer variant 2: external */\n\t\t\t\tvals[DUK__IDX_HBYTES] = (duk_uint_t) (sizeof(duk_hbuffer_external));\n\t\t\t} else {\n\t\t\t\t/* When alloc_size == 0 the second allocation may not\n\t\t\t\t * actually exist.\n\t\t\t\t */\n\t\t\t\tvals[DUK__IDX_VARIANT] = 1;  /* buffer variant 1: dynamic */\n\t\t\t\tvals[DUK__IDX_HBYTES] = (duk_uint_t) (sizeof(duk_hbuffer_dynamic));\n\t\t\t}\n\t\t\tvals[DUK__IDX_DBYTES] = (duk_int_t) (DUK_HBUFFER_GET_SIZE(h_buf));\n\t\t} else {\n\t\t\tDUK_ASSERT(vals[DUK__IDX_VARIANT] == 0);  /* buffer variant 0: fixed */\n\t\t\tvals[DUK__IDX_HBYTES] = (duk_int_t) (sizeof(duk_hbuffer_fixed) + DUK_HBUFFER_GET_SIZE(h_buf));\n\t\t}\n\t\tbreak;\n\t}\n\t}\n\n finish:\n\tduk__inspect_multiple_uint(thr,\n\t    \"type\" \"\\x00\" \"itag\" \"\\x00\" \"refc\" \"\\x00\" \"hbytes\" \"\\x00\" \"class\" \"\\x00\"\n\t    \"pbytes\" \"\\x00\" \"esize\" \"\\x00\" \"enext\" \"\\x00\" \"asize\" \"\\x00\" \"hsize\" \"\\x00\"\n\t    \"bcbytes\" \"\\x00\" \"dbytes\" \"\\x00\" \"tstate\" \"\\x00\" \"variant\" \"\\x00\" \"\\x00\",\n\t    (duk_int_t *) &vals);\n}\n\nDUK_EXTERNAL void duk_inspect_callstack_entry(duk_hthread *thr, duk_int_t level) {\n\tduk_activation *act;\n\tduk_uint_fast32_t pc;\n\tduk_uint_fast32_t line;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* -1   = top callstack entry\n\t * -2   = caller of level -1\n\t * etc\n\t */\n\tact = duk_hthread_get_activation_for_level(thr, level);\n\tif (act == NULL) {\n\t\tduk_push_undefined(thr);\n\t\treturn;\n\t}\n\tduk_push_bare_object(thr);\n\n\t/* Relevant PC is just before current one because PC is\n\t * post-incremented.  This should match what error augment\n\t * code does.\n\t */\n\tpc = duk_hthread_get_act_prev_pc(thr, act);\n\n\tduk_push_tval(thr, &act->tv_func);\n\n\tduk_push_uint(thr, (duk_uint_t) pc);\n\tduk_put_prop_stridx_short(thr, -3, DUK_STRIDX_PC);\n\n#if defined(DUK_USE_PC2LINE)\n\tline = duk_hobject_pc2line_query(thr, -1, pc);\n#else\n\tline = 0;\n#endif\n\tduk_push_uint(thr, (duk_uint_t) line);\n\tduk_put_prop_stridx_short(thr, -3, DUK_STRIDX_LINE_NUMBER);\n\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_LC_FUNCTION);\n\t/* Providing access to e.g. act->lex_env would be dangerous: these\n\t * internal structures must never be accessible to the application.\n\t * Duktape relies on them having consistent data, and this consistency\n\t * is only asserted for, not checked for.\n\t */\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_api_internal.h",
    "content": "/*\n *  Internal API calls which have (stack and other) semantics similar\n *  to the public API.\n */\n\n#if !defined(DUK_API_INTERNAL_H_INCLUDED)\n#define DUK_API_INTERNAL_H_INCLUDED\n\n/* duk_push_sprintf constants */\n#define DUK_PUSH_SPRINTF_INITIAL_SIZE  256L\n#define DUK_PUSH_SPRINTF_SANITY_LIMIT  (1L * 1024L * 1024L * 1024L)\n\n/* Flag ORed to err_code to indicate __FILE__ / __LINE__ is not\n * blamed as source of error for error fileName / lineNumber.\n */\n#define DUK_ERRCODE_FLAG_NOBLAME_FILELINE  (1L << 24)\n\n/* Current convention is to use duk_size_t for value stack sizes and global indices,\n * and duk_idx_t for local frame indices.\n */\nDUK_INTERNAL_DECL void duk_valstack_grow_check_throw(duk_hthread *thr, duk_size_t min_bytes);\nDUK_INTERNAL_DECL duk_bool_t duk_valstack_grow_check_nothrow(duk_hthread *thr, duk_size_t min_bytes);\nDUK_INTERNAL_DECL void duk_valstack_shrink_check_nothrow(duk_hthread *thr, duk_bool_t snug);\n\nDUK_INTERNAL_DECL void duk_copy_tvals_incref(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_size_t count);\n\nDUK_INTERNAL_DECL duk_tval *duk_reserve_gap(duk_hthread *thr, duk_idx_t idx_base, duk_idx_t count);\n\nDUK_INTERNAL_DECL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_set_top_and_wipe(duk_hthread *thr, duk_idx_t top, duk_idx_t idx_wipe_start);\n\nDUK_INTERNAL_DECL void duk_dup_0(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_1(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_2(duk_hthread *thr);\n/* duk_dup_m1() would be same as duk_dup_top() */\nDUK_INTERNAL_DECL void duk_dup_m2(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_m3(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_m4(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_remove_unsafe(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_remove_m2(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_remove_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count);\nDUK_INTERNAL_DECL void duk_remove_n_unsafe(duk_hthread *thr, duk_idx_t idx, duk_idx_t count);\n\nDUK_INTERNAL_DECL duk_int_t duk_get_type_tval(duk_tval *tv);\nDUK_INTERNAL_DECL duk_uint_t duk_get_type_mask_tval(duk_tval *tv);\n\n#if defined(DUK_USE_VERBOSE_ERRORS) && defined(DUK_USE_PARANOID_ERRORS)\nDUK_INTERNAL_DECL const char *duk_get_type_name(duk_hthread *thr, duk_idx_t idx);\n#endif\nDUK_INTERNAL_DECL duk_small_uint_t duk_get_class_number(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_tval *duk_get_tval(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_tval *duk_get_tval_or_unused(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_tval *duk_require_tval(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_push_tval(duk_hthread *thr, duk_tval *tv);\n\n/* Push the current 'this' binding; throw TypeError if binding is not object\n * coercible (CheckObjectCoercible).\n */\nDUK_INTERNAL_DECL void duk_push_this_check_object_coercible(duk_hthread *thr);\n\n/* duk_push_this() + CheckObjectCoercible() + duk_to_object() */\nDUK_INTERNAL_DECL duk_hobject *duk_push_this_coercible_to_object(duk_hthread *thr);\n\n/* duk_push_this() + CheckObjectCoercible() + duk_to_string() */\nDUK_INTERNAL_DECL duk_hstring *duk_push_this_coercible_to_string(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_hstring *duk_push_uint_to_hstring(duk_hthread *thr, duk_uint_t i);\n\n/* Get a borrowed duk_tval pointer to the current 'this' binding.  Caller must\n * make sure there's an active callstack entry.  Note that the returned pointer\n * is unstable with regards to side effects.\n */\nDUK_INTERNAL_DECL duk_tval *duk_get_borrowed_this_tval(duk_hthread *thr);\n\n/* XXX: add fastint support? */\n#define duk_push_u64(thr,val) \\\n\tduk_push_number((thr), (duk_double_t) (val))\n#define duk_push_i64(thr,val) \\\n\tduk_push_number((thr), (duk_double_t) (val))\n\n/* duk_push_(u)int() is guaranteed to support at least (un)signed 32-bit range */\n#define duk_push_u32(thr,val) \\\n\tduk_push_uint((thr), (duk_uint_t) (val))\n#define duk_push_i32(thr,val) \\\n\tduk_push_int((thr), (duk_int_t) (val))\n\n/* sometimes stack and array indices need to go on the stack */\n#define duk_push_idx(thr,val) \\\n\tduk_push_int((thr), (duk_int_t) (val))\n#define duk_push_uarridx(thr,val) \\\n\tduk_push_uint((thr), (duk_uint_t) (val))\n#define duk_push_size_t(thr,val) \\\n\tduk_push_uint((thr), (duk_uint_t) (val))  /* XXX: assumed to fit for now */\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_string_notsymbol(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_callable_tval(duk_hthread *thr, duk_tval *tv);\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_bare_object(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hstring *duk_get_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hstring *duk_get_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL const char *duk_get_string_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hobject *duk_get_hobject(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hbuffer *duk_get_hbuffer(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hthread *duk_get_hthread(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_get_hcompfunc(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_get_hnatfunc(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL void *duk_get_buffer_data_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len, duk_bool_t throw_flag, duk_bool_t *out_isbuffer);\n\nDUK_INTERNAL_DECL duk_hobject *duk_get_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum);\n\nDUK_INTERNAL_DECL duk_hobject *duk_get_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask);\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask);\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject_accept_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask);\n#define duk_require_hobject_promote_lfunc(thr,idx) \\\n\tduk_require_hobject_promote_mask((thr), (idx), DUK_TYPE_MASK_LIGHTFUNC)\n#define duk_get_hobject_promote_lfunc(thr,idx) \\\n\tduk_get_hobject_promote_mask((thr), (idx), DUK_TYPE_MASK_LIGHTFUNC)\n\n#if 0  /*unused*/\nDUK_INTERNAL_DECL void *duk_get_voidptr(duk_hthread *thr, duk_idx_t idx);\n#endif\n\nDUK_INTERNAL_DECL duk_hstring *duk_known_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hobject *duk_known_hobject(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hbuffer *duk_known_hbuffer(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_known_hcompfunc(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_known_hnatfunc(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_double_t duk_to_number_tval(duk_hthread *thr, duk_tval *tv);\n\nDUK_INTERNAL_DECL duk_hstring *duk_to_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hstring *duk_to_hstring_m1(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_hstring *duk_to_hstring_acceptsymbol(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hobject *duk_to_hobject(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_double_t duk_to_number_m1(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_double_t duk_to_number_m2(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_bool_t duk_to_boolean_top_pop(duk_hthread *thr);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* only needed by debugger for now */\nDUK_INTERNAL_DECL duk_hstring *duk_safe_to_hstring(duk_hthread *thr, duk_idx_t idx);\n#endif\nDUK_INTERNAL_DECL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects);\n\nDUK_INTERNAL_DECL duk_int_t duk_to_int_clamped_raw(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped);  /* out_clamped=NULL, RangeError if outside range */\nDUK_INTERNAL_DECL duk_int_t duk_to_int_clamped(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval);\nDUK_INTERNAL_DECL duk_int_t duk_to_int_check_range(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL_DECL duk_uint8_t duk_to_uint8clamped(duk_hthread *thr, duk_idx_t idx);\n#endif\nDUK_INTERNAL_DECL duk_hstring *duk_to_property_key_hstring(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hstring *duk_require_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hstring *duk_require_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL const char *duk_require_lstring_notsymbol(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len);\nDUK_INTERNAL_DECL const char *duk_require_string_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hbuffer *duk_require_hbuffer(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hthread *duk_require_hthread(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_require_hcompfunc(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_require_hnatfunc(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum);\n\nDUK_INTERNAL_DECL void duk_push_hstring(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_push_hstring_stridx(duk_hthread *thr, duk_small_uint_t stridx);\nDUK_INTERNAL_DECL void duk_push_hstring_empty(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_push_hobject(duk_hthread *thr, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_push_hbuffer(duk_hthread *thr, duk_hbuffer *h);\n#define duk_push_hthread(thr,h) \\\n\tduk_push_hobject((thr), (duk_hobject *) (h))\n#define duk_push_hnatfunc(thr,h) \\\n\tduk_push_hobject((thr), (duk_hobject *) (h))\nDUK_INTERNAL_DECL void duk_push_hobject_bidx(duk_hthread *thr, duk_small_int_t builtin_idx);\nDUK_INTERNAL_DECL duk_hobject *duk_push_object_helper(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx);\nDUK_INTERNAL_DECL duk_hobject *duk_push_object_helper_proto(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_hobject *proto);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_push_hcompfunc(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_hboundfunc *duk_push_hboundfunc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_push_c_function_builtin(duk_hthread *thr, duk_c_function func, duk_int_t nargs);\nDUK_INTERNAL_DECL void duk_push_c_function_builtin_noconstruct(duk_hthread *thr, duk_c_function func, duk_int_t nargs);\n\n/* XXX: duk_push_harray() and duk_push_hcompfunc() are inconsistent with\n * duk_push_hobject() etc which don't create a new value.\n */\nDUK_INTERNAL_DECL duk_harray *duk_push_harray(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_harray *duk_push_harray_with_size(duk_hthread *thr, duk_uint32_t size);\nDUK_INTERNAL_DECL duk_tval *duk_push_harray_with_size_outptr(duk_hthread *thr, duk_uint32_t size);\n\nDUK_INTERNAL_DECL void duk_push_string_funcptr(duk_hthread *thr, duk_uint8_t *ptr, duk_size_t sz);\nDUK_INTERNAL_DECL void duk_push_lightfunc_name_raw(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags);\nDUK_INTERNAL_DECL void duk_push_lightfunc_name(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL void duk_push_lightfunc_tostring(duk_hthread *thr, duk_tval *tv);\n#if 0  /* not used yet */\nDUK_INTERNAL_DECL void duk_push_hnatfunc_name(duk_hthread *thr, duk_hnatfunc *h);\n#endif\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL_DECL duk_hbufobj *duk_push_bufobj_raw(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx);\n#endif\n\nDUK_INTERNAL_DECL void *duk_push_fixed_buffer_nozero(duk_hthread *thr, duk_size_t len);\nDUK_INTERNAL_DECL void *duk_push_fixed_buffer_zero(duk_hthread *thr, duk_size_t len);\n\nDUK_INTERNAL_DECL const char *duk_push_string_readable(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL const char *duk_push_string_tval_readable(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL const char *duk_push_string_tval_readable_error(duk_hthread *thr, duk_tval *tv);\n\n/* The duk_xxx_prop_stridx_short() variants expect their arguments to be short\n * enough to be packed into a single 32-bit integer argument.  Argument limits\n * vary per call; typically 16 bits are assigned to the signed value stack index\n * and the stridx.  In practice these work well for footprint with constant\n * arguments and such call sites are also easiest to verify to be correct.\n */\n\nDUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [] -> [val] */\nDUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_get_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t duk_get_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\nDUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_boolean(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop);  /* [] -> [] */\n\nDUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop(duk_hthread *thr, duk_idx_t obj_idx);\nDUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);\nDUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_xget_owndataprop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t duk_xget_owndataprop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n\nDUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [val] -> [] */\nDUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_put_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t duk_put_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n\nDUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [] -> [] */\n#if 0  /* Too few call sites to be useful. */\nDUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_del_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((obj_idx) >= -0x8000L && (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((stridx) >= 0 && (stridx) <= 0xffffL), \\\n\t duk_del_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n#endif\n#define duk_del_prop_stridx_short(thr,obj_idx,stridx) \\\n\tduk_del_prop_stridx((thr), (obj_idx), (stridx))\n\nDUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [] -> [] */\n#if 0  /* Too few call sites to be useful. */\nDUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_has_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((obj_idx) >= -0x8000L && (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((stridx) >= 0 && (stridx) <= 0xffffL), \\\n\t duk_has_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n#endif\n#define duk_has_prop_stridx_short(thr,obj_idx,stridx) \\\n\tduk_has_prop_stridx((thr), (obj_idx), (stridx))\n\nDUK_INTERNAL_DECL void duk_xdef_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t desc_flags);  /* [key val] -> [] */\n\nDUK_INTERNAL_DECL void duk_xdef_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags);  /* [val] -> [] */\n\n/* XXX: Because stridx and desc_flags have a limited range, this call could\n * always pack stridx and desc_flags into a single argument.\n */\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags);  /* [val] -> [] */\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_xdef_prop_stridx_short(thr,obj_idx,stridx,desc_flags) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x80L && (duk_int_t) (obj_idx) <= 0x7fL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (desc_flags) >= 0 && (duk_int_t) (desc_flags) <= 0xffL), \\\n\t duk_xdef_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 24) + (((duk_uint_t) (stridx)) << 8) + (duk_uint_t) (desc_flags)))\n\n#define duk_xdef_prop_wec(thr,obj_idx) \\\n\tduk_xdef_prop((thr), (obj_idx), DUK_PROPDESC_FLAGS_WEC)\n#define duk_xdef_prop_index_wec(thr,obj_idx,arr_idx) \\\n\tduk_xdef_prop_index((thr), (obj_idx), (arr_idx), DUK_PROPDESC_FLAGS_WEC)\n#define duk_xdef_prop_stridx_wec(thr,obj_idx,stridx) \\\n\tduk_xdef_prop_stridx((thr), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC)\n#define duk_xdef_prop_stridx_short_wec(thr,obj_idx,stridx) \\\n\tduk_xdef_prop_stridx_short((thr), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC)\n\n#if 0  /*unused*/\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx_builtin(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags);  /* [] -> [] */\n#endif\n\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx_thrower(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);  /* [] -> [] */\n\nDUK_INTERNAL_DECL duk_bool_t duk_get_method_stridx(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t stridx);\n\nDUK_INTERNAL_DECL void duk_pack(duk_hthread *thr, duk_idx_t count);\nDUK_INTERNAL_DECL duk_idx_t duk_unpack_array_like(duk_hthread *thr, duk_idx_t idx);\n#if 0\nDUK_INTERNAL_DECL void duk_unpack(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL void duk_push_symbol_descriptive_string(duk_hthread *thr, duk_hstring *h);\n\nDUK_INTERNAL_DECL void duk_resolve_nonbound_function(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_idx_t duk_get_top_require_min(duk_hthread *thr, duk_idx_t min_top);\nDUK_INTERNAL_DECL duk_idx_t duk_get_top_index_unsafe(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count);\nDUK_INTERNAL_DECL void duk_pop_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_2_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_3_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count);\nDUK_INTERNAL_DECL void duk_pop_nodecref_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_2_nodecref_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_3_nodecref_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_undefined(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_compact_m1(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_seal_freeze_raw(duk_hthread *thr, duk_idx_t obj_idx, duk_bool_t is_freeze);\n\nDUK_INTERNAL_DECL void duk_insert_undefined(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_insert_undefined_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count);\n\nDUK_INTERNAL_DECL void duk_concat_2(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_int_t duk_pcall_method_flags(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags);\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL_DECL void duk_to_primitive_ordinary(duk_hthread *thr, duk_idx_t idx, duk_int_t hint);\n#endif\n\nDUK_INTERNAL_DECL void duk_clear_prototype(duk_hthread *thr, duk_idx_t idx);\n\n/* Raw internal valstack access macros: access is unsafe so call site\n * must have a guarantee that the index is valid.  When that is the case,\n * using these macro results in faster and smaller code than duk_get_tval().\n * Both 'ctx' and 'idx' are evaluted multiple times, but only for asserts.\n */\n#define DUK_ASSERT_VALID_NEGIDX(thr,idx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (idx) < 0), DUK_ASSERT_EXPR(duk_is_valid_index((thr), (idx))))\n#define DUK_ASSERT_VALID_POSIDX(thr,idx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (idx) >= 0), DUK_ASSERT_EXPR(duk_is_valid_index((thr), (idx))))\n#define DUK_GET_TVAL_NEGIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_NEGIDX((thr),(idx)), ((duk_hthread *) (thr))->valstack_top + (idx))\n#define DUK_GET_TVAL_POSIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_POSIDX((thr),(idx)), ((duk_hthread *) (thr))->valstack_bottom + (idx))\n#define DUK_GET_HOBJECT_NEGIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_NEGIDX((thr),(idx)), DUK_TVAL_GET_OBJECT(((duk_hthread *) (thr))->valstack_top + (idx)))\n#define DUK_GET_HOBJECT_POSIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_POSIDX((thr),(idx)), DUK_TVAL_GET_OBJECT(((duk_hthread *) (thr))->valstack_bottom + (idx)))\n\n#define DUK_GET_THIS_TVAL_PTR(thr) \\\n\t(DUK_ASSERT_EXPR((thr)->valstack_bottom > (thr)->valstack), \\\n\t (thr)->valstack_bottom - 1)\n\nDUK_INTERNAL_DECL duk_double_t duk_time_get_ecmascript_time(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_double_t duk_time_get_ecmascript_time_nofrac(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr);\n\n#endif  /* DUK_API_INTERNAL_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_api_memory.c",
    "content": "/*\n *  Memory calls.\n */\n\n#include \"duk_internal.h\"\n\nDUK_EXTERNAL void *duk_alloc_raw(duk_hthread *thr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn DUK_ALLOC_RAW(thr->heap, size);\n}\n\nDUK_EXTERNAL void duk_free_raw(duk_hthread *thr, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_FREE_RAW(thr->heap, ptr);\n}\n\nDUK_EXTERNAL void *duk_realloc_raw(duk_hthread *thr, void *ptr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn DUK_REALLOC_RAW(thr->heap, ptr, size);\n}\n\nDUK_EXTERNAL void *duk_alloc(duk_hthread *thr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn DUK_ALLOC(thr->heap, size);\n}\n\nDUK_EXTERNAL void duk_free(duk_hthread *thr, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_FREE_CHECKED(thr, ptr);\n}\n\nDUK_EXTERNAL void *duk_realloc(duk_hthread *thr, void *ptr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/*\n\t *  Note: since this is an exposed API call, there should be\n\t *  no way a mark-and-sweep could have a side effect on the\n\t *  memory allocation behind 'ptr'; the pointer should never\n\t *  be something that Duktape wants to change.\n\t *\n\t *  Thus, no need to use DUK_REALLOC_INDIRECT (and we don't\n\t *  have the storage location here anyway).\n\t */\n\n\treturn DUK_REALLOC(thr->heap, ptr, size);\n}\n\nDUK_EXTERNAL void duk_get_memory_functions(duk_hthread *thr, duk_memory_functions *out_funcs) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(out_funcs != NULL);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\theap = thr->heap;\n\tout_funcs->alloc_func = heap->alloc_func;\n\tout_funcs->realloc_func = heap->realloc_func;\n\tout_funcs->free_func = heap->free_func;\n\tout_funcs->udata = heap->heap_udata;\n}\n\nDUK_EXTERNAL void duk_gc(duk_hthread *thr, duk_uint_t flags) {\n\tduk_heap *heap;\n\tduk_small_uint_t ms_flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep requested by application\"));\n\tDUK_ASSERT(DUK_GC_COMPACT == DUK_MS_FLAG_EMERGENCY);  /* Compact flag is 1:1 with emergency flag which forces compaction. */\n\tms_flags = (duk_small_uint_t) flags;\n\tduk_heap_mark_and_sweep(heap, ms_flags);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_api_object.c",
    "content": "/*\n *  Object handling: property access and other support functions.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Property handling\n *\n *  The API exposes only the most common property handling functions.\n *  The caller can invoke ECMAScript built-ins for full control (e.g.\n *  defineProperty, getOwnPropertyDescriptor).\n */\n\nDUK_EXTERNAL duk_bool_t duk_get_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property get right now.\n\t */\n\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, -1);\n\n\trc = duk_hobject_getprop(thr, tv_obj, tv_key);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\t/* a value is left on stack regardless of rc */\n\n\tduk_remove_m2(thr);  /* remove key */\n\tDUK_ASSERT(duk_is_undefined(thr, -1) || rc == 1);\n\treturn rc;  /* 1 if property found, 0 otherwise */\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk_get_prop(thr, obj_idx);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_get_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk_get_prop(thr, obj_idx);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_get_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_get_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_get_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n\nDUK_INTERNAL duk_bool_t duk_get_prop_stridx_boolean(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop) {\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\trc = duk_get_prop_stridx(thr, obj_idx, stridx);\n\tif (out_has_prop) {\n\t\t*out_has_prop = rc;\n\t}\n\treturn duk_to_boolean_top_pop(thr);\n}\n\n/* This get variant is for internal use, it differs from standard\n * duk_get_prop() in that:\n *   - Object argument must be an object (primitive values not supported).\n *   - Key argument must be a string (no coercion).\n *   - Only own properties are checked (no inheritance).  Only \"entry part\"\n *     properties are checked (not array index properties).\n *   - Property must be a plain data property, not a getter.\n *   - Proxy traps are not triggered.\n */\nDUK_INTERNAL duk_bool_t duk_xget_owndataprop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_hobject *h_obj;\n\tduk_hstring *h_key;\n\tduk_tval *tv_val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property get right now.\n\t */\n\n\th_obj = duk_get_hobject(thr, obj_idx);\n\tif (h_obj == NULL) {\n\t\treturn 0;\n\t}\n\th_key = duk_require_hstring(thr, -1);\n\n\ttv_val = duk_hobject_find_entry_tval_ptr(thr->heap, h_obj, h_key);\n\tif (tv_val == NULL) {\n\t\treturn 0;\n\t}\n\n\tduk_push_tval(thr, tv_val);\n\tduk_remove_m2(thr);  /* remove key */\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_bool_t duk_xget_owndataprop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_xget_owndataprop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_xget_owndataprop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_xget_owndataprop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                   (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n\nDUK_LOCAL duk_bool_t duk__put_prop_shared(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t idx_key) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_tval *tv_val;\n\tduk_bool_t throw_flag;\n\tduk_bool_t rc;\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property put right now (putprop protects\n\t * against it internally).\n\t */\n\n\t/* Key and value indices are either (-2, -1) or (-1, -2).  Given idx_key,\n\t * idx_val is always (idx_key ^ 0x01).\n\t */\n\tDUK_ASSERT((idx_key == -2 && (idx_key ^ 1) == -1) ||\n\t           (idx_key == -1 && (idx_key ^ 1) == -2));\n\t/* XXX: Direct access; faster validation. */\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, idx_key);\n\ttv_val = duk_require_tval(thr, idx_key ^ 1);\n\tthrow_flag = duk_is_strict_call(thr);\n\n\trc = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, throw_flag);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\n\tduk_pop_2(thr);  /* remove key and value */\n\treturn rc;  /* 1 if property found, 0 otherwise */\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__put_prop_shared(thr, obj_idx, -2);\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\t/* Careful here and with other duk_put_prop_xxx() helpers: the\n\t * target object and the property value may be in the same value\n\t * stack slot (unusual, but still conceptually clear).\n\t */\n\tobj_idx = duk_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_put_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\n\nDUK_INTERNAL duk_bool_t duk_put_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\nDUK_INTERNAL duk_bool_t duk_put_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_put_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t throw_flag;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property delete right now.\n\t */\n\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, -1);\n\tthrow_flag = duk_is_strict_call(thr);\n\n\trc = duk_hobject_delprop(thr, tv_obj, tv_key, throw_flag);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\n\tduk_pop(thr);  /* remove key */\n\treturn rc;\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk_del_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk_del_prop(thr, obj_idx);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_del_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk_del_prop(thr, obj_idx);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk_del_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk_del_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_del_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_del_prop(thr, obj_idx);\n}\n\n#if 0\nDUK_INTERNAL duk_bool_t duk_del_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_del_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_has_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property existence check right now.\n\t */\n\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, -1);\n\n\trc = duk_hobject_hasprop(thr, tv_obj, tv_key);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\n\tduk_pop(thr);  /* remove key */\n\treturn rc;  /* 1 if property found, 0 otherwise */\n}\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk_has_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk_has_prop(thr, obj_idx);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_has_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk_has_prop(thr, obj_idx);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk_has_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk_has_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_has_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_has_prop(thr, obj_idx);\n}\n\n#if 0\nDUK_INTERNAL duk_bool_t duk_has_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_has_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n#endif\n\n/* Define own property without inheritance lookups and such.  This differs from\n * [[DefineOwnProperty]] because special behaviors (like Array 'length') are\n * not invoked by this method.  The caller must be careful to invoke any such\n * behaviors if necessary.\n */\nDUK_INTERNAL void duk_xdef_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\tkey = duk_to_property_key_hstring(thr, -2);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(duk_require_tval(thr, -1) != NULL);\n\n\tduk_hobject_define_property_internal(thr, obj, key, desc_flags);\n\n\tduk_pop(thr);  /* pop key */\n}\n\nDUK_INTERNAL void duk_xdef_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\n\tduk_hobject_define_property_internal_arridx(thr, obj, arr_idx, desc_flags);\n\t/* value popped by call */\n}\n\nDUK_INTERNAL void duk_xdef_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\tkey = DUK_HTHREAD_GET_STRING(thr, stridx);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(duk_require_tval(thr, -1) != NULL);\n\n\tduk_hobject_define_property_internal(thr, obj, key, desc_flags);\n\t/* value popped by call */\n}\n\nDUK_INTERNAL void duk_xdef_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\tduk_xdef_prop_stridx(thr, (duk_idx_t) (duk_int8_t) (packed_args >> 24),\n\t                          (duk_small_uint_t) (packed_args >> 8) & 0xffffUL,\n\t                          (duk_small_uint_t) (packed_args & 0xffL));\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL void duk_xdef_prop_stridx_builtin(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\tDUK_ASSERT_BIDX_VALID(builtin_idx);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\tkey = DUK_HTHREAD_GET_STRING(thr, stridx);\n\tDUK_ASSERT(key != NULL);\n\n\tduk_push_hobject(thr, thr->builtins[builtin_idx]);\n\tduk_hobject_define_property_internal(thr, obj, key, desc_flags);\n\t/* value popped by call */\n}\n#endif\n\n/* This is a rare property helper; it sets the global thrower (E5 Section 13.2.3)\n * setter/getter into an object property.  This is needed by the 'arguments'\n * object creation code, function instance creation code, and Function.prototype.bind().\n */\n\nDUK_INTERNAL void duk_xdef_prop_stridx_thrower(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring_stridx(thr, stridx);\n\tduk_push_hobject_bidx(thr, DUK_BIDX_TYPE_ERROR_THROWER);\n\tduk_dup_top(thr);\n\tduk_def_prop(thr, obj_idx, DUK_DEFPROP_HAVE_SETTER | DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_FORCE);  /* attributes always 0 */\n}\n\n/* Object.getOwnPropertyDescriptor() equivalent C binding. */\nDUK_EXTERNAL void duk_get_prop_desc(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(flags);  /* no flags defined yet */\n\n\tduk_hobject_object_get_own_property_descriptor(thr, obj_idx);  /* [ ... key ] -> [ ... desc ] */\n}\n\n/* Object.defineProperty() equivalent C binding. */\nDUK_EXTERNAL void duk_def_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t flags) {\n\tduk_idx_t idx_base;\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_idx_t idx_value;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\tduk_uint_t is_data_desc;\n\tduk_uint_t is_acc_desc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\n\tis_data_desc = flags & (DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE);\n\tis_acc_desc = flags & (DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER);\n\tif (is_data_desc && is_acc_desc) {\n\t\t/* \"Have\" flags must not be conflicting so that they would\n\t\t * apply to both a plain property and an accessor at the same\n\t\t * time.\n\t\t */\n\t\tgoto fail_invalid_desc;\n\t}\n\n\tidx_base = duk_get_top_index(thr);\n\tif (flags & DUK_DEFPROP_HAVE_SETTER) {\n\t\tduk_require_type_mask(thr, idx_base, DUK_TYPE_MASK_UNDEFINED |\n\t\t                                     DUK_TYPE_MASK_OBJECT |\n\t\t                                     DUK_TYPE_MASK_LIGHTFUNC);\n\t\tset = duk_get_hobject_promote_lfunc(thr, idx_base);\n\t\tif (set != NULL && !DUK_HOBJECT_IS_CALLABLE(set)) {\n\t\t\tgoto fail_not_callable;\n\t\t}\n\t\tidx_base--;\n\t} else {\n\t\tset = NULL;\n\t}\n\tif (flags & DUK_DEFPROP_HAVE_GETTER) {\n\t\tduk_require_type_mask(thr, idx_base, DUK_TYPE_MASK_UNDEFINED |\n\t\t                                     DUK_TYPE_MASK_OBJECT |\n\t\t                                     DUK_TYPE_MASK_LIGHTFUNC);\n\t\tget = duk_get_hobject_promote_lfunc(thr, idx_base);\n\t\tif (get != NULL && !DUK_HOBJECT_IS_CALLABLE(get)) {\n\t\t\tgoto fail_not_callable;\n\t\t}\n\t\tidx_base--;\n\t} else {\n\t\tget = NULL;\n\t}\n\tif (flags & DUK_DEFPROP_HAVE_VALUE) {\n\t\tidx_value = idx_base;\n\t\tidx_base--;\n\t} else {\n\t\tidx_value = (duk_idx_t) -1;\n\t}\n\tkey = duk_to_property_key_hstring(thr, idx_base);\n\tDUK_ASSERT(key != NULL);\n\n\tduk_require_valid_index(thr, idx_base);\n\n\tduk_hobject_define_property_helper(thr,\n\t                                   flags /*defprop_flags*/,\n\t                                   obj,\n\t                                   key,\n\t                                   idx_value,\n\t                                   get,\n\t                                   set,\n\t                                   1 /*throw_flag*/);\n\n\t/* Clean up stack */\n\n\tduk_set_top(thr, idx_base);\n\n\t/* [ ... obj ... ] */\n\n\treturn;\n\n fail_invalid_desc:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_DESCRIPTOR);\n\tDUK_WO_NORETURN(return;);\n\n fail_not_callable:\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Object related\n */\n\nDUK_EXTERNAL void duk_compact(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, obj_idx);\n\tif (obj) {\n\t\t/* Note: this may fail, caller should protect the call if necessary */\n\t\tduk_hobject_compact_props(thr, obj);\n\t}\n}\n\nDUK_INTERNAL void duk_compact_m1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_compact(thr, -1);\n}\n\n/* XXX: the duk_hobject_enum.c stack APIs should be reworked */\n\nDUK_EXTERNAL void duk_enum(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t enum_flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_dup(thr, obj_idx);\n\tduk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tduk_hobject_enumerator_create(thr, enum_flags);   /* [target] -> [enum] */\n}\n\nDUK_EXTERNAL duk_bool_t duk_next(duk_hthread *thr, duk_idx_t enum_index, duk_bool_t get_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_require_hobject(thr, enum_index);\n\tduk_dup(thr, enum_index);\n\treturn duk_hobject_enumerator_next(thr, get_value);\n}\n\nDUK_INTERNAL void duk_seal_freeze_raw(duk_hthread *thr, duk_idx_t obj_idx, duk_bool_t is_freeze) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, obj_idx);\n\tDUK_ASSERT(tv != NULL);\n\n\t/* Seal/freeze are quite rare in practice so it'd be nice to get the\n\t * correct behavior simply via automatic promotion (at the cost of some\n\t * memory churn).  However, the promoted objects don't behave the same,\n\t * e.g. promoted lightfuncs are extensible.\n\t */\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_BUFFER:\n\t\t/* Plain buffer: already sealed, but not frozen (and can't be frozen\n\t\t * because index properties can't be made non-writable.\n\t\t */\n\t\tif (is_freeze) {\n\t\t\tgoto fail_cannot_freeze;\n\t\t}\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\t/* Lightfunc: already sealed and frozen, success. */\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (is_freeze && DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\t/* Buffer objects cannot be frozen because there's no internal\n\t\t\t * support for making virtual array indices non-writable.\n\t\t\t */\n\t\t\tDUK_DD(DUK_DDPRINT(\"cannot freeze a buffer object\"));\n\t\t\tgoto fail_cannot_freeze;\n\t\t}\n\t\tduk_hobject_object_seal_freeze_helper(thr, h, is_freeze);\n\n\t\t/* Sealed and frozen objects cannot gain any more properties,\n\t\t * so this is a good time to compact them.\n\t\t */\n\t\tduk_hobject_compact_props(thr, h);\n\t\tbreak;\n\tdefault:\n\t\t/* ES2015 Sections 19.1.2.5, 19.1.2.17 */\n\t\tbreak;\n\t}\n\treturn;\n\n fail_cannot_freeze:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);  /* XXX: proper error message */\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_seal(duk_hthread *thr, duk_idx_t obj_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_seal_freeze_raw(thr, obj_idx, 0 /*is_freeze*/);\n}\n\nDUK_EXTERNAL void duk_freeze(duk_hthread *thr, duk_idx_t obj_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_seal_freeze_raw(thr, obj_idx, 1 /*is_freeze*/);\n}\n\n/*\n *  Helpers for writing multiple properties\n */\n\nDUK_EXTERNAL void duk_put_function_list(duk_hthread *thr, duk_idx_t obj_idx, const duk_function_list_entry *funcs) {\n\tconst duk_function_list_entry *ent = funcs;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tif (ent != NULL) {\n\t\twhile (ent->key != NULL) {\n\t\t\tduk_push_c_function(thr, ent->value, ent->nargs);\n\t\t\tduk_put_prop_string(thr, obj_idx, ent->key);\n\t\t\tent++;\n\t\t}\n\t}\n}\n\nDUK_EXTERNAL void duk_put_number_list(duk_hthread *thr, duk_idx_t obj_idx, const duk_number_list_entry *numbers) {\n\tconst duk_number_list_entry *ent = numbers;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tif (ent != NULL) {\n\t\twhile (ent->key != NULL) {\n\t\t\ttv = thr->valstack_top++;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));  /* value stack init policy */\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv, ent->value);  /* no need for decref/incref */\n\t\t\tduk_put_prop_string(thr, obj_idx, ent->key);\n\t\t\tent++;\n\t\t}\n\t}\n}\n\n/*\n *  Shortcut for accessing global object properties\n */\n\nDUK_EXTERNAL duk_bool_t duk_get_global_string(duk_hthread *thr, const char *key) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_string(thr, -1, key);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_global_lstring(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_lstring(thr, -1, key, key_len);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_get_global_literal_raw(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_literal_raw(thr, -1, key, key_len);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_get_global_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_heapptr(thr, -1, ptr);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n\n\nDUK_EXTERNAL duk_bool_t duk_put_global_string(duk_hthread *thr, const char *key) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_string(thr, -2, key);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_global_lstring(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_lstring(thr, -2, key, key_len);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_put_global_literal_raw(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_literal_raw(thr, -2, key, key_len);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_put_global_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_heapptr(thr, -2, ptr);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n\n/*\n *  ES2015 GetMethod()\n */\n\nDUK_INTERNAL duk_bool_t duk_get_method_stridx(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t stridx) {\n\t(void) duk_get_prop_stridx(thr, idx, stridx);\n\tif (duk_is_null_or_undefined(thr, -1)) {\n\t\tduk_pop_nodecref_unsafe(thr);\n\t\treturn 0;\n\t}\n\tif (!duk_is_callable(thr, -1)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 1;\n}\n\n/*\n *  Object prototype\n */\n\nDUK_EXTERNAL void duk_get_prototype(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\n\t/* XXX: shared helper for duk_push_hobject_or_undefined()? */\n\tproto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, obj);\n\tif (proto) {\n\t\tduk_push_hobject(thr, proto);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n}\n\nDUK_EXTERNAL void duk_set_prototype(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\tduk_require_type_mask(thr, -1, DUK_TYPE_MASK_UNDEFINED |\n\t                               DUK_TYPE_MASK_OBJECT);\n\tproto = duk_get_hobject(thr, -1);\n\t/* proto can also be NULL here (allowed explicitly) */\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);  /* XXX: \"read only object\"? */\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, obj, proto);\n\n\tduk_pop(thr);\n}\n\nDUK_INTERNAL void duk_clear_prototype(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);  /* XXX: \"read only object\"? */\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, obj, NULL);\n}\n\nDUK_INTERNAL duk_bool_t duk_is_bare_object(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\n\tproto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, obj);\n\treturn (proto == NULL);\n}\n\n/*\n *  Object finalizer\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n/* XXX: these could be implemented as macros calling an internal function\n * directly.\n * XXX: same issue as with Duktape.fin: there's no way to delete the property\n * now (just set it to undefined).\n */\nDUK_EXTERNAL void duk_get_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* This get intentionally walks the inheritance chain at present,\n\t * which matches how the effective finalizer property is also\n\t * looked up in GC.\n\t */\n\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_INT_FINALIZER);\n}\n\nDUK_EXTERNAL void duk_set_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\tduk_bool_t callable;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hobject(thr, idx);  /* Get before 'put' so that 'idx' is correct. */\n\tcallable = duk_is_callable(thr, -1);\n\n\t/* At present finalizer is stored as a hidden Symbol, with normal\n\t * inheritance and access control.  As a result, finalizer cannot\n\t * currently be set on a non-extensible (sealed or frozen) object.\n\t * It might be useful to allow it.\n\t */\n\tduk_put_prop_stridx(thr, idx, DUK_STRIDX_INT_FINALIZER);\n\n\t/* In addition to setting the finalizer property, keep a \"have\n\t * finalizer\" flag in duk_hobject in sync so that refzero can do\n\t * a very quick finalizer check by walking the prototype chain\n\t * and checking the flag alone.  (Note that this means that just\n\t * setting _Finalizer on an object won't affect finalizer checks.)\n\t *\n\t * NOTE: if the argument is a Proxy object, this flag will be set\n\t * on the Proxy, not the target.  As a result, the target won't get\n\t * a finalizer flag and the Proxy also won't be finalized as there's\n\t * an explicit Proxy check in finalization now.\n\t */\n\tif (callable) {\n\t\tDUK_HOBJECT_SET_HAVE_FINALIZER(h);\n\t} else {\n\t\tDUK_HOBJECT_CLEAR_HAVE_FINALIZER(h);\n\t}\n}\n#else  /* DUK_USE_FINALIZER_SUPPORT */\nDUK_EXTERNAL void duk_get_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_set_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_api_random.c",
    "content": "/*\n *  Random numbers\n */\n\n#include \"duk_internal.h\"\n\nDUK_EXTERNAL duk_double_t duk_random(duk_hthread *thr) {\n\treturn (duk_double_t) DUK_UTIL_GET_RANDOM_DOUBLE(thr);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_api_stack.c",
    "content": "/*\n *  API calls related to general value stack manipulation: resizing the value\n *  stack, pushing and popping values, type checking and reading values,\n *  coercing values, etc.\n *\n *  Also contains internal functions (such as duk_get_tval()), defined\n *  in duk_api_internal.h, with semantics similar to the public API.\n */\n\n/* XXX: repetition of stack pre-checks -> helper or macro or inline */\n/* XXX: shared api error strings, and perhaps even throw code for rare cases? */\n\n#include \"duk_internal.h\"\n\n/*\n *  Forward declarations\n */\n\nDUK_LOCAL_DECL duk_idx_t duk__push_c_function_raw(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_uint_t flags, duk_small_uint_t proto_bidx);\n\n/*\n *  Global state for working around missing variadic macros\n */\n\n#if !defined(DUK_USE_VARIADIC_MACROS)\nDUK_EXTERNAL const char *duk_api_global_filename = NULL;\nDUK_EXTERNAL duk_int_t duk_api_global_line = 0;\n#endif\n\n/*\n *  Misc helpers\n */\n\nDUK_LOCAL const char * const duk__symbol_type_strings[4] = {\n\t\"hidden\", \"global\", \"local\", \"wellknown\"\n};\n\n#if !defined(DUK_USE_PACKED_TVAL)\nDUK_LOCAL const duk_uint_t duk__type_from_tag[] = {\n\tDUK_TYPE_NUMBER,\n\tDUK_TYPE_NUMBER,  /* fastint */\n\tDUK_TYPE_UNDEFINED,\n\tDUK_TYPE_NULL,\n\tDUK_TYPE_BOOLEAN,\n\tDUK_TYPE_POINTER,\n\tDUK_TYPE_LIGHTFUNC,\n\tDUK_TYPE_NONE,\n\tDUK_TYPE_STRING,\n\tDUK_TYPE_OBJECT,\n\tDUK_TYPE_BUFFER,\n};\nDUK_LOCAL const duk_uint_t duk__type_mask_from_tag[] = {\n\tDUK_TYPE_MASK_NUMBER,\n\tDUK_TYPE_MASK_NUMBER,  /* fastint */\n\tDUK_TYPE_MASK_UNDEFINED,\n\tDUK_TYPE_MASK_NULL,\n\tDUK_TYPE_MASK_BOOLEAN,\n\tDUK_TYPE_MASK_POINTER,\n\tDUK_TYPE_MASK_LIGHTFUNC,\n\tDUK_TYPE_MASK_NONE,\n\tDUK_TYPE_MASK_STRING,\n\tDUK_TYPE_MASK_OBJECT,\n\tDUK_TYPE_MASK_BUFFER,\n};\n#endif  /* !DUK_USE_PACKED_TVAL */\n\n/* Assert that there's room for one value. */\n#define DUK__ASSERT_SPACE() do { \\\n\t\tDUK_ASSERT(!(thr->valstack_top >= thr->valstack_end)); \\\n\t} while (0)\n\n/* Check that there's room to push one value. */\n#if defined(DUK_USE_VALSTACK_UNSAFE)\n/* Faster but value stack overruns are memory unsafe. */\n#define DUK__CHECK_SPACE() DUK__ASSERT_SPACE()\n#else\n#define DUK__CHECK_SPACE() do { \\\n\t\tif (DUK_UNLIKELY(thr->valstack_top >= thr->valstack_end)) { \\\n\t\t\tDUK_ERROR_RANGE_PUSH_BEYOND(thr); \\\n\t\t} \\\n\t} while (0)\n#endif\n\nDUK_LOCAL duk_small_uint_t duk__get_symbol_type(duk_hstring *h) {\n\tconst duk_uint8_t *data;\n\tduk_size_t len;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HSTRING_HAS_SYMBOL(h));\n\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(h) >= 1);  /* always true, symbol prefix */\n\n\tdata = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\tDUK_ASSERT(len >= 1);\n\n\t/* XXX: differentiate between 0x82 and 0xff (hidden vs. internal?)? */\n\n\tif (data[0] == 0xffU) {\n\t\treturn DUK_SYMBOL_TYPE_HIDDEN;\n\t} else if (data[0] == 0x82U) {\n\t\treturn DUK_SYMBOL_TYPE_HIDDEN;\n\t} else if (data[0] == 0x80U) {\n\t\treturn DUK_SYMBOL_TYPE_GLOBAL;\n\t} else if (data[len - 1] != 0xffU) {\n\t\treturn DUK_SYMBOL_TYPE_LOCAL;\n\t} else {\n\t\treturn DUK_SYMBOL_TYPE_WELLKNOWN;\n\t}\n}\n\nDUK_LOCAL const char *duk__get_symbol_type_string(duk_hstring *h) {\n\tduk_small_uint_t idx;\n\tidx = duk__get_symbol_type(h);\n\tDUK_ASSERT(idx < sizeof(duk__symbol_type_strings));\n\treturn duk__symbol_type_strings[idx];\n}\n\nDUK_LOCAL_DECL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t tag);\n\nDUK_LOCAL duk_int_t duk__api_coerce_d2i(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value, duk_bool_t require) {\n\tduk_tval *tv;\n\tduk_small_int_t c;\n\tduk_double_t d;\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\t/*\n\t *  Special cases like NaN and +/- Infinity are handled explicitly\n\t *  because a plain C coercion from double to int handles these cases\n\t *  in undesirable ways.  For instance, NaN may coerce to INT_MIN\n\t *  (not zero), and INT_MAX + 1 may coerce to INT_MIN (not INT_MAX).\n\t *\n\t *  This double-to-int coercion differs from ToInteger() because it\n\t *  has a finite range (ToInteger() allows e.g. +/- Infinity).  It\n\t *  also differs from ToInt32() because the INT_MIN/INT_MAX clamping\n\t *  depends on the size of the int type on the platform.  In particular,\n\t *  on platforms with a 64-bit int type, the full range is allowed.\n\t */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tduk_int64_t t = DUK_TVAL_GET_FASTINT(tv);\n#if (DUK_INT_MAX <= 0x7fffffffL)\n\t\t/* Clamping only necessary for 32-bit ints. */\n\t\tif (t < DUK_INT_MIN) {\n\t\t\tt = DUK_INT_MIN;\n\t\t} else if (t > DUK_INT_MAX) {\n\t\t\tt = DUK_INT_MAX;\n\t\t}\n#endif\n\t\treturn (duk_int_t) t;\n\t}\n#endif\n\n\tif (DUK_TVAL_IS_NUMBER(tv)) {\n\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\t\tif (c == DUK_FP_NAN) {\n\t\t\treturn 0;\n\t\t} else if (d < (duk_double_t) DUK_INT_MIN) {\n\t\t\t/* covers -Infinity */\n\t\t\treturn DUK_INT_MIN;\n\t\t} else if (d > (duk_double_t) DUK_INT_MAX) {\n\t\t\t/* covers +Infinity */\n\t\t\treturn DUK_INT_MAX;\n\t\t} else {\n\t\t\t/* coerce towards zero */\n\t\t\treturn (duk_int_t) d;\n\t\t}\n\t}\n\n\tif (require) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"number\", DUK_STR_NOT_NUMBER);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\treturn def_value;\n}\n\nDUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value, duk_bool_t require) {\n\tduk_tval *tv;\n\tduk_small_int_t c;\n\tduk_double_t d;\n\n\t/* Same as above but for unsigned int range. */\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tduk_int64_t t = DUK_TVAL_GET_FASTINT(tv);\n\t\tif (t < 0) {\n\t\t\tt = 0;\n\t\t}\n#if (DUK_UINT_MAX <= 0xffffffffUL)\n\t\t/* Clamping only necessary for 32-bit ints. */\n\t\telse if (t > DUK_UINT_MAX) {\n\t\t\tt = DUK_UINT_MAX;\n\t\t}\n#endif\n\t\treturn (duk_uint_t) t;\n\t}\n#endif\n\n\tif (DUK_TVAL_IS_NUMBER(tv)) {\n\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\t\tif (c == DUK_FP_NAN) {\n\t\t\treturn 0;\n\t\t} else if (d < 0.0) {\n\t\t\t/* covers -Infinity */\n\t\t\treturn (duk_uint_t) 0;\n\t\t} else if (d > (duk_double_t) DUK_UINT_MAX) {\n\t\t\t/* covers +Infinity */\n\t\t\treturn (duk_uint_t) DUK_UINT_MAX;\n\t\t} else {\n\t\t\t/* coerce towards zero */\n\t\t\treturn (duk_uint_t) d;\n\t\t}\n\t}\n\n\tif (require) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"number\", DUK_STR_NOT_NUMBER);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\treturn def_value;\n}\n\n/*\n *  Stack index validation/normalization and getting a stack duk_tval ptr.\n *\n *  These are called by many API entrypoints so the implementations must be\n *  fast and \"inlined\".\n *\n *  There's some repetition because of this; keep the functions in sync.\n */\n\nDUK_EXTERNAL duk_idx_t duk_normalize_index(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\t/* Care must be taken to avoid pointer wrapping in the index\n\t * validation.  For instance, on a 32-bit platform with 8-byte\n\t * duk_tval the index 0x20000000UL would wrap the memory space\n\t * once.\n\t */\n\n\t/* Assume value stack sizes (in elements) fits into duk_idx_t. */\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\t/* since index non-negative */\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn (duk_idx_t) uidx;\n\t}\n\treturn DUK_INVALID_INDEX;\n}\n\nDUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn (duk_idx_t) uidx;\n\t}\n\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_tval *duk_get_tval(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn thr->valstack_bottom + uidx;\n\t}\n\treturn NULL;\n}\n\n/* Variant of duk_get_tval() which is guaranteed to return a valid duk_tval\n * pointer.  When duk_get_tval() would return NULL, this variant returns a\n * pointer to a duk_tval with tag DUK_TAG_UNUSED.  This allows the call site\n * to avoid an unnecessary NULL check which sometimes leads to better code.\n * The return duk_tval is read only (at least for the UNUSED value).\n */\nDUK_LOCAL const duk_tval_unused duk__const_tval_unused = DUK_TVAL_UNUSED_INITIALIZER();\n\nDUK_INTERNAL duk_tval *duk_get_tval_or_unused(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval(thr, idx);\n\tif (tv != NULL) {\n\t\treturn tv;\n\t}\n\treturn (duk_tval *) DUK_LOSE_CONST(&duk__const_tval_unused);\n}\n\nDUK_INTERNAL duk_tval *duk_require_tval(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\t/* Use unsigned arithmetic to optimize comparison. */\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn thr->valstack_bottom + uidx;\n\t}\n\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/* Non-critical. */\nDUK_EXTERNAL duk_bool_t duk_is_valid_index(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\treturn (duk_normalize_index(thr, idx) >= 0);\n}\n\n/* Non-critical. */\nDUK_EXTERNAL void duk_require_valid_index(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tif (DUK_UNLIKELY(duk_normalize_index(thr, idx) < 0)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\n/*\n *  Value stack top handling\n */\n\nDUK_EXTERNAL duk_idx_t duk_get_top(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n}\n\n/* Internal helper to get current top but to require a minimum top value\n * (TypeError if not met).\n */\nDUK_INTERNAL duk_idx_t duk_get_top_require_min(duk_hthread *thr, duk_idx_t min_top) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tif (DUK_UNLIKELY(ret < min_top)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn ret;\n}\n\n/* Set stack top within currently allocated range, but don't reallocate.\n * This is performance critical especially for call handling, so whenever\n * changing, profile and look at generated code.\n */\nDUK_EXTERNAL void duk_set_top(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t vs_limit;\n\tduk_uidx_t uidx;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tvs_limit = (duk_uidx_t) (thr->valstack_end - thr->valstack_bottom);\n\n\tif (idx < 0) {\n\t\t/* Negative indices are always within allocated stack but\n\t\t * must not go below zero index.\n\t\t */\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\t/* Positive index can be higher than valstack top but must\n\t\t * not go above allocated stack (equality is OK).\n\t\t */\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_limit);\n\n#if defined(DUK_USE_VALSTACK_UNSAFE)\n\tDUK_ASSERT(uidx <= vs_limit);\n\tDUK_UNREF(vs_limit);\n#else\n\tif (DUK_UNLIKELY(uidx > vs_limit)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\tDUK_ASSERT(uidx <= vs_limit);\n\n\t/* Handle change in value stack top.  Respect value stack\n\t * initialization policy: 'undefined' above top.  Note that\n\t * DECREF may cause a side effect that reallocates valstack,\n\t * so must relookup after DECREF.\n\t */\n\n\tif (uidx >= vs_size) {\n\t\t/* Stack size increases or stays the same. */\n#if defined(DUK_USE_ASSERTIONS)\n\t\tduk_uidx_t count;\n\n\t\tcount = uidx - vs_size;\n\t\twhile (count != 0) {\n\t\t\tcount--;\n\t\t\ttv = thr->valstack_top + count;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\t}\n#endif\n\t\tthr->valstack_top = thr->valstack_bottom + uidx;\n\t} else {\n\t\t/* Stack size decreases. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\tDUK_ASSERT(count > 0);\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);  /* Because count > 0. */\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n\t\tDUK_REFZERO_CHECK_FAST(thr);\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\t}\n}\n\n/* Internal variant with a non-negative index and no runtime size checks. */\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_set_top(thr, idx);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t uidx;\n\tduk_uidx_t vs_size;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_bottom);\n\tDUK_ASSERT(idx >= 0);\n\tDUK_ASSERT(idx <= (duk_idx_t) (thr->valstack_end - thr->valstack_bottom));\n\n\t/* XXX: byte arithmetic */\n\tuidx = (duk_uidx_t) idx;\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\n\tif (uidx >= vs_size) {\n\t\t/* Stack size increases or stays the same. */\n#if defined(DUK_USE_ASSERTIONS)\n\t\tduk_uidx_t count;\n\n\t\tcount = uidx - vs_size;\n\t\twhile (count != 0) {\n\t\t\tcount--;\n\t\t\ttv = thr->valstack_top + count;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\t}\n#endif\n\t\tthr->valstack_top = thr->valstack_bottom + uidx;\n\t} else {\n\t\t/* Stack size decreases. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\tDUK_ASSERT(count > 0);\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);  /* Because count > 0. */\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n\t\tDUK_REFZERO_CHECK_FAST(thr);\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\t}\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/* Internal helper: set top to 'top', and set [idx_wipe_start,top[ to\n * 'undefined' (doing nothing if idx_wipe_start == top).  Indices are\n * positive and within value stack reserve.  This is used by call handling.\n */\nDUK_INTERNAL void duk_set_top_and_wipe(duk_hthread *thr, duk_idx_t top, duk_idx_t idx_wipe_start) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(top >= 0);\n\tDUK_ASSERT(idx_wipe_start >= 0);\n\tDUK_ASSERT(idx_wipe_start <= top);\n\tDUK_ASSERT(thr->valstack_bottom + top <= thr->valstack_end);\n\tDUK_ASSERT(thr->valstack_bottom + idx_wipe_start <= thr->valstack_end);\n\n\tduk_set_top_unsafe(thr, idx_wipe_start);\n\tduk_set_top_unsafe(thr, top);\n}\n\nDUK_EXTERNAL duk_idx_t duk_get_top_index(duk_hthread *thr) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;\n\tif (DUK_UNLIKELY(ret < 0)) {\n\t\t/* Return invalid index; if caller uses this without checking\n\t\t * in another API call, the index won't map to a valid stack\n\t\t * entry.\n\t\t */\n\t\treturn DUK_INVALID_INDEX;\n\t}\n\treturn ret;\n}\n\n/* Internal variant: call assumes there is at least one element on the value\n * stack frame; this is only asserted for.\n */\nDUK_INTERNAL duk_idx_t duk_get_top_index_unsafe(duk_hthread *thr) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_idx_t duk_require_top_index(duk_hthread *thr) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;\n\tif (DUK_UNLIKELY(ret < 0)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, -1);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn ret;\n}\n\n/*\n *  Value stack resizing.\n *\n *  This resizing happens above the current \"top\": the value stack can be\n *  grown or shrunk, but the \"top\" is not affected.  The value stack cannot\n *  be resized to a size below the current reserve.\n *\n *  The low level reallocation primitive must carefully recompute all value\n *  stack pointers, and must also work if ALL pointers are NULL.  The resize\n *  is quite tricky because the valstack realloc may cause a mark-and-sweep,\n *  which may run finalizers.  Running finalizers may resize the valstack\n *  recursively (the same value stack we're working on).  So, after realloc\n *  returns, we know that the valstack bottom, top, and reserve should still\n *  be the same (there should not be live values above the \"top\"), but its\n *  underlying size, alloc_end, and base pointer may have changed.\n *\n *  'new_size' is known to be <= DUK_USE_VALSTACK_LIMIT, which ensures that\n *  size_t and pointer arithmetic won't wrap in duk__resize_valstack().\n */\n\n/* Low level valstack resize primitive, used for both grow and shrink.  All\n * adjustments for slack etc have already been done.  Doesn't throw but does\n * have allocation side effects.\n */\nDUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__resize_valstack(duk_hthread *thr, duk_size_t new_size) {\n\tduk_tval *pre_valstack;\n\tduk_tval *pre_bottom;\n\tduk_tval *pre_top;\n\tduk_tval *pre_end;\n\tduk_tval *pre_alloc_end;\n\tduk_ptrdiff_t ptr_diff;\n\tduk_tval *new_valstack;\n\tduk_size_t new_alloc_size;\n\tduk_tval *tv_prev_alloc_end;\n\tduk_tval *p;\n\n\tDUK_HTHREAD_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack) <= new_size);  /* can't resize below 'top' */\n\tDUK_ASSERT(new_size <= DUK_USE_VALSTACK_LIMIT);  /* valstack limit caller has check, prevents wrapping */\n\tDUK_ASSERT(new_size <= DUK_SIZE_MAX / sizeof(duk_tval));  /* specific assert for wrapping */\n\n\t/* Pre-realloc pointer copies for asserts and debug logs. */\n\tpre_valstack = thr->valstack;\n\tpre_bottom = thr->valstack_bottom;\n\tpre_top = thr->valstack_top;\n\tpre_end = thr->valstack_end;\n\tpre_alloc_end = thr->valstack_alloc_end;\n\n\tDUK_UNREF(pre_valstack);\n\tDUK_UNREF(pre_bottom);\n\tDUK_UNREF(pre_top);\n\tDUK_UNREF(pre_end);\n\tDUK_UNREF(pre_alloc_end);\n\n\t/* If finalizer torture enabled, force base pointer change every time\n\t * when it would be allowed.\n\t */\n#if defined(DUK_USE_FINALIZER_TORTURE)\n\tif (thr->heap->pf_prevent_count == 0) {\n\t\tduk_hthread_valstack_torture_realloc(thr);\n\t}\n#endif\n\n\t/* Allocate a new valstack using DUK_REALLOC_DIRECT() to deal with\n\t * a side effect changing the base pointer.\n\t */\n\tnew_alloc_size = sizeof(duk_tval) * new_size;\n\tnew_valstack = (duk_tval *) DUK_REALLOC_INDIRECT(thr->heap, duk_hthread_get_valstack_ptr, (void *) thr, new_alloc_size);\n\tif (DUK_UNLIKELY(new_valstack == NULL)) {\n\t\t/* Because new_size != 0, if condition doesn't need to be\n\t\t * (new_valstack != NULL || new_size == 0).\n\t\t */\n\t\tDUK_ASSERT(new_size != 0);\n\t\tDUK_D(DUK_DPRINT(\"failed to resize valstack to %lu entries (%lu bytes)\",\n\t\t                 (unsigned long) new_size, (unsigned long) new_alloc_size));\n\t\treturn 0;\n\t}\n\n\t/* Debug log any changes in pointer(s) by side effects.  These don't\n\t * necessarily imply any incorrect behavior, but should be rare in\n\t * practice.\n\t */\n#if defined(DUK_USE_DEBUG)\n\tif (thr->valstack != pre_valstack) {\n\t\tDUK_D(DUK_DPRINT(\"valstack base pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_valstack, (void *) thr->valstack));\n\t}\n\tif (thr->valstack_bottom != pre_bottom) {\n\t\tDUK_D(DUK_DPRINT(\"valstack bottom pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_bottom, (void *) thr->valstack_bottom));\n\t}\n\tif (thr->valstack_top != pre_top) {\n\t\tDUK_D(DUK_DPRINT(\"valstack top pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_top, (void *) thr->valstack_top));\n\t}\n\tif (thr->valstack_end != pre_end) {\n\t\tDUK_D(DUK_DPRINT(\"valstack end pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_end, (void *) thr->valstack_end));\n\t}\n\tif (thr->valstack_alloc_end != pre_alloc_end) {\n\t\tDUK_D(DUK_DPRINT(\"valstack alloc_end pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_alloc_end, (void *) thr->valstack_alloc_end));\n\t}\n#endif\n\n\t/* Assertions: offsets for bottom, top, and end (reserve) must not\n\t * have changed even with side effects because they are always\n\t * restored in unwind.  For alloc_end there's no guarantee: it may\n\t * have grown or shrunk (but remain above 'end').\n\t */\n\tDUK_ASSERT(thr->valstack_bottom - thr->valstack == pre_bottom - pre_valstack);\n\tDUK_ASSERT(thr->valstack_top - thr->valstack == pre_top - pre_valstack);\n\tDUK_ASSERT(thr->valstack_end - thr->valstack == pre_end - pre_valstack);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\n\t/* Write new pointers.  Most pointers can be handled as a pointer\n\t * difference.\n\t */\n\tptr_diff = (duk_ptrdiff_t) ((duk_uint8_t *) new_valstack - (duk_uint8_t *) thr->valstack);\n\ttv_prev_alloc_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_alloc_end + ptr_diff);\n\tthr->valstack = new_valstack;\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + ptr_diff);\n\tthr->valstack_top = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_top + ptr_diff);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_end + ptr_diff);\n\tthr->valstack_alloc_end = (duk_tval *) (void *) ((duk_uint8_t *) new_valstack + new_alloc_size);\n\n\t/* Assertions: pointer sanity after pointer updates. */\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\n\tDUK_D(DUK_DPRINT(\"resized valstack %lu -> %lu elements (%lu -> %lu bytes): \"\n\t                 \"base=%p -> %p, bottom=%p -> %p (%ld), top=%p -> %p (%ld), \"\n\t                 \"end=%p -> %p (%ld), alloc_end=%p -> %p (%ld);\"\n\t                 \" tv_prev_alloc_end=%p (-> %ld inits; <0 means shrink)\",\n\t                 (unsigned long) (pre_alloc_end - pre_valstack),\n\t                 (unsigned long) new_size,\n\t                 (unsigned long) ((duk_uint8_t *) pre_alloc_end - (duk_uint8_t *) pre_valstack),\n\t                 (unsigned long) new_alloc_size,\n\t                 (void *) pre_valstack, (void *) thr->valstack,\n\t                 (void *) pre_bottom, (void *) thr->valstack_bottom, (long) (thr->valstack_bottom - thr->valstack),\n\t                 (void *) pre_top, (void *) thr->valstack_top, (long) (thr->valstack_top - thr->valstack),\n\t                 (void *) pre_end, (void *) thr->valstack_end, (long) (thr->valstack_end - thr->valstack),\n\t                 (void *) pre_alloc_end, (void *) thr->valstack_alloc_end, (long) (thr->valstack_alloc_end - thr->valstack),\n\t                 (void *) tv_prev_alloc_end, (long) (thr->valstack_alloc_end - tv_prev_alloc_end)));\n\n\t/* If allocation grew, init any new slots to 'undefined'. */\n\tp = tv_prev_alloc_end;\n\twhile (p < thr->valstack_alloc_end) {\n\t\t/* Never executed if new size is smaller. */\n\t\tDUK_TVAL_SET_UNDEFINED(p);\n\t\tp++;\n\t}\n\n\t/* Assert for value stack initialization policy. */\n#if defined(DUK_USE_ASSERTIONS)\n\tp = thr->valstack_top;\n\twhile (p < thr->valstack_alloc_end) {\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(p));\n\t\tp++;\n\t}\n#endif\n\n\treturn 1;\n}\n\nDUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__valstack_grow(duk_hthread *thr, duk_size_t min_bytes, duk_bool_t throw_on_error) {\n\tduk_size_t min_size;\n\tduk_size_t new_size;\n\n\tDUK_ASSERT(min_bytes / sizeof(duk_tval) * sizeof(duk_tval) == min_bytes);\n\tmin_size = min_bytes / sizeof(duk_tval);  /* from bytes to slots */\n\n#if defined(DUK_USE_VALSTACK_GROW_SHIFT)\n\t/* New size is minimum size plus a proportional slack, e.g. shift of\n\t * 2 means a 25% slack.\n\t */\n\tnew_size = min_size + (min_size >> DUK_USE_VALSTACK_GROW_SHIFT);\n#else\n\t/* New size is tight with no slack.  This is sometimes preferred in\n\t * low memory environments.\n\t */\n\tnew_size = min_size;\n#endif\n\n\tif (DUK_UNLIKELY(new_size > DUK_USE_VALSTACK_LIMIT || new_size < min_size /*wrap*/)) {\n\t\t/* Note: may be triggered even if minimal new_size would not reach the limit,\n\t\t * plan limit accordingly.\n\t\t */\n\t\tif (throw_on_error) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_VALSTACK_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\treturn 0;\n\t}\n\n\tif (duk__resize_valstack(thr, new_size) == 0) {\n\t\tif (throw_on_error) {\n\t\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\treturn 0;\n\t}\n\n\tthr->valstack_end = thr->valstack + min_size;\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\n\treturn 1;\n}\n\n/* Hot, inlined value stack grow check.  Because value stack almost never\n * grows, the actual resize call is in a NOINLINE helper.\n */\nDUK_INTERNAL DUK_INLINE void duk_valstack_grow_check_throw(duk_hthread *thr, duk_size_t min_bytes) {\n\tduk_tval *tv;\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + min_bytes);\n\tif (DUK_LIKELY(thr->valstack_end >= tv)) {\n\t\treturn;\n\t}\n\tif (DUK_LIKELY(thr->valstack_alloc_end >= tv)) {\n\t\t/* Values in [valstack_top,valstack_alloc_end[ are initialized\n\t\t * to 'undefined' so we can just move the end pointer.\n\t\t */\n\t\tthr->valstack_end = tv;\n\t\treturn;\n\t}\n\t(void) duk__valstack_grow(thr, min_bytes, 1 /*throw_on_error*/);\n}\n\n/* Hot, inlined value stack grow check which doesn't throw. */\nDUK_INTERNAL DUK_INLINE duk_bool_t duk_valstack_grow_check_nothrow(duk_hthread *thr, duk_size_t min_bytes) {\n\tduk_tval *tv;\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + min_bytes);\n\tif (DUK_LIKELY(thr->valstack_end >= tv)) {\n\t\treturn 1;\n\t}\n\tif (DUK_LIKELY(thr->valstack_alloc_end >= tv)) {\n\t\tthr->valstack_end = tv;\n\t\treturn 1;\n\t}\n\treturn duk__valstack_grow(thr, min_bytes, 0 /*throw_on_error*/);\n}\n\n/* Value stack shrink check, called from mark-and-sweep. */\nDUK_INTERNAL void duk_valstack_shrink_check_nothrow(duk_hthread *thr, duk_bool_t snug) {\n\tduk_size_t alloc_bytes;\n\tduk_size_t reserve_bytes;\n\tduk_size_t shrink_bytes;\n\n\talloc_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_alloc_end - (duk_uint8_t *) thr->valstack);\n\treserve_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tDUK_ASSERT(alloc_bytes >= reserve_bytes);\n\n\t/* We're free to shrink the value stack allocation down to\n\t * reserve_bytes but not more.  If 'snug' (emergency GC)\n\t * shrink whatever we can.  Otherwise only shrink if the new\n\t * size would be considerably smaller.\n\t */\n\n#if defined(DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT)\n\tif (snug) {\n\t\tshrink_bytes = reserve_bytes;\n\t} else {\n\t\tduk_size_t proportion, slack;\n\n\t\t/* Require that value stack shrinks by at least X% of its\n\t\t * current size.  For example, shift of 2 means at least\n\t\t * 25%.  The proportion is computed as bytes and may not\n\t\t * be a multiple of sizeof(duk_tval); that's OK here.\n\t\t */\n\t\tproportion = alloc_bytes >> DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT;\n\t\tif (alloc_bytes - reserve_bytes < proportion) {\n\t\t\t/* Too little would be freed, do nothing. */\n\t\t\treturn;\n\t\t}\n\n\t\t/* Keep a slack after shrinking.  The slack is again a\n\t\t * proportion of the current size (the proportion should\n\t\t * of course be smaller than the check proportion above).\n\t\t */\n#if defined(DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT)\n\t\tDUK_ASSERT(DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT > DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT);\n\t\tslack = alloc_bytes >> DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT;\n#else\n\t\tslack = 0;\n#endif\n\t\tshrink_bytes = reserve_bytes +\n\t\t               slack / sizeof(duk_tval) * sizeof(duk_tval);  /* multiple of duk_tval */\n\t}\n#else  /* DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT */\n\t/* Always snug, useful in some low memory environments. */\n\tDUK_UNREF(snug);\n\tshrink_bytes = reserve_bytes;\n#endif  /* DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT */\n\n\tDUK_D(DUK_DPRINT(\"valstack shrink check: alloc_bytes=%ld, reserve_bytes=%ld, shrink_bytes=%ld (unvalidated)\",\n\t                 (long) alloc_bytes, (long) reserve_bytes, (long) shrink_bytes));\n\tDUK_ASSERT(shrink_bytes >= reserve_bytes);\n\tif (shrink_bytes >= alloc_bytes) {\n\t\t/* Skip if shrink target is same as current one (or higher,\n\t\t * though that shouldn't happen in practice).\n\t\t */\n\t\treturn;\n\t}\n\tDUK_ASSERT(shrink_bytes / sizeof(duk_tval) * sizeof(duk_tval) == shrink_bytes);\n\n\tDUK_D(DUK_DPRINT(\"valstack shrink check: decided to shrink, snug: %ld\", (long) snug));\n\n\tduk__resize_valstack(thr, shrink_bytes / sizeof(duk_tval));\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_stack(duk_hthread *thr, duk_idx_t extra) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\n\tif (DUK_UNLIKELY(extra < 0 || extra > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (extra < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\textra = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\textra = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) extra + DUK_VALSTACK_INTERNAL_EXTRA);\n\treturn duk_valstack_grow_check_nothrow(thr, min_new_bytes);\n}\n\nDUK_EXTERNAL void duk_require_stack(duk_hthread *thr, duk_idx_t extra) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\n\tif (DUK_UNLIKELY(extra < 0 || extra > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (extra < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\textra = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\textra = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) extra + DUK_VALSTACK_INTERNAL_EXTRA);\n\tduk_valstack_grow_check_throw(thr, min_new_bytes);\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_stack_top(duk_hthread *thr, duk_idx_t top) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (DUK_UNLIKELY(top < 0 || top > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (top < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\ttop = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\ttop = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tDUK_ASSERT(top >= 0);\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) top + DUK_VALSTACK_INTERNAL_EXTRA);\n\treturn duk_valstack_grow_check_nothrow(thr, min_new_bytes);\n}\n\nDUK_EXTERNAL void duk_require_stack_top(duk_hthread *thr, duk_idx_t top) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (DUK_UNLIKELY(top < 0 || top > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (top < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\ttop = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\ttop = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tDUK_ASSERT(top >= 0);\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) top + DUK_VALSTACK_INTERNAL_EXTRA);\n\tduk_valstack_grow_check_throw(thr, min_new_bytes);\n}\n\n/*\n *  Basic stack manipulation: swap, dup, insert, replace, etc\n */\n\nDUK_EXTERNAL void duk_swap(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n\tduk_tval tv_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_require_tval(thr, idx1);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, idx2);\n\tDUK_ASSERT(tv2 != NULL);\n\n\t/* If tv1==tv2 this is a NOP, no check is needed */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv1);\n\tDUK_TVAL_SET_TVAL(tv1, tv2);\n\tDUK_TVAL_SET_TVAL(tv2, &tv_tmp);\n}\n\nDUK_EXTERNAL void duk_swap_top(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_swap(thr, idx, -1);\n}\n\nDUK_EXTERNAL void duk_dup(duk_hthread *thr, duk_idx_t from_idx) {\n\tduk_tval *tv_from;\n\tduk_tval *tv_to;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\n\ttv_from = duk_require_tval(thr, from_idx);\n\ttv_to = thr->valstack_top++;\n\tDUK_ASSERT(tv_from != NULL);\n\tDUK_ASSERT(tv_to != NULL);\n\tDUK_TVAL_SET_TVAL(tv_to, tv_from);\n\tDUK_TVAL_INCREF(thr, tv_to);  /* no side effects */\n}\n\nDUK_EXTERNAL void duk_dup_top(duk_hthread *thr) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_dup(thr, -1);\n#else\n\tduk_tval *tv_from;\n\tduk_tval *tv_to;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\n\tif (DUK_UNLIKELY(thr->valstack_top - thr->valstack_bottom <= 0)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, -1);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\ttv_from = thr->valstack_top - 1;\n\ttv_to = thr->valstack_top++;\n\tDUK_ASSERT(tv_from != NULL);\n\tDUK_ASSERT(tv_to != NULL);\n\tDUK_TVAL_SET_TVAL(tv_to, tv_from);\n\tDUK_TVAL_INCREF(thr, tv_to);  /* no side effects */\n#endif\n}\n\nDUK_INTERNAL void duk_dup_0(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, 0);\n}\nDUK_INTERNAL void duk_dup_1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, 1);\n}\nDUK_INTERNAL void duk_dup_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, 2);\n}\nDUK_INTERNAL void duk_dup_m2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, -2);\n}\nDUK_INTERNAL void duk_dup_m3(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, -3);\n}\nDUK_INTERNAL void duk_dup_m4(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, -4);\n}\n\nDUK_EXTERNAL void duk_insert(duk_hthread *thr, duk_idx_t to_idx) {\n\tduk_tval *p;\n\tduk_tval *q;\n\tduk_tval tv_tmp;\n\tduk_size_t nbytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tp = duk_require_tval(thr, to_idx);\n\tDUK_ASSERT(p != NULL);\n\tq = duk_require_tval(thr, -1);\n\tDUK_ASSERT(q != NULL);\n\n\tDUK_ASSERT(q >= p);\n\n\t/*              nbytes\n\t *           <--------->\n\t *    [ ... | p | x | x | q ]\n\t * => [ ... | q | p | x | x ]\n\t */\n\n\tnbytes = (duk_size_t) (((duk_uint8_t *) q) - ((duk_uint8_t *) p));  /* Note: 'q' is top-1 */\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk_insert: to_idx=%ld, p=%p, q=%p, nbytes=%lu\",\n\t                     (long) to_idx, (void *) p, (void *) q, (unsigned long) nbytes));\n\n\t/* No net refcount changes.  No need to special case nbytes == 0\n\t * (p == q).\n\t */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, q);\n\tduk_memmove((void *) (p + 1), (const void *) p, (size_t) nbytes);\n\tDUK_TVAL_SET_TVAL(p, &tv_tmp);\n}\n\nDUK_INTERNAL void duk_insert_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(idx >= 0);  /* Doesn't support negative indices. */\n\n\tduk_push_undefined(thr);\n\tduk_insert(thr, idx);\n}\n\nDUK_INTERNAL void duk_insert_undefined_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) {\n\tduk_tval *tv, *tv_end;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(idx >= 0);  /* Doesn't support negative indices or count. */\n\tDUK_ASSERT(count >= 0);\n\n\ttv = duk_reserve_gap(thr, idx, count);\n\ttv_end = tv + count;\n\twhile (tv != tv_end) {\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t\ttv++;\n\t}\n}\n\nDUK_EXTERNAL void duk_replace(duk_hthread *thr, duk_idx_t to_idx) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n\tduk_tval tv_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, to_idx);\n\tDUK_ASSERT(tv2 != NULL);\n\n\t/* For tv1 == tv2, both pointing to stack top, the end result\n\t * is same as duk_pop(thr).\n\t */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv2);\n\tDUK_TVAL_SET_TVAL(tv2, tv1);\n\tDUK_TVAL_SET_UNDEFINED(tv1);\n\tthr->valstack_top--;\n\tDUK_TVAL_DECREF(thr, &tv_tmp);  /* side effects */\n}\n\nDUK_EXTERNAL void duk_copy(duk_hthread *thr, duk_idx_t from_idx, duk_idx_t to_idx) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_require_tval(thr, from_idx);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, to_idx);\n\tDUK_ASSERT(tv2 != NULL);\n\n\t/* For tv1 == tv2, this is a no-op (no explicit check needed). */\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv2, tv1);  /* side effects */\n}\n\nDUK_EXTERNAL void duk_remove(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *p;\n\tduk_tval *q;\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_tval tv_tmp;\n#endif\n\tduk_size_t nbytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tp = duk_require_tval(thr, idx);\n\tDUK_ASSERT(p != NULL);\n\tq = duk_require_tval(thr, -1);\n\tDUK_ASSERT(q != NULL);\n\n\tDUK_ASSERT(q >= p);\n\n\t/*              nbytes            zero size case\n\t *           <--------->\n\t *    [ ... | p | x | x | q ]     [ ... | p==q ]\n\t * => [ ... | x | x | q ]         [ ... ]\n\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* use a temp: decref only when valstack reachable values are correct */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, p);\n#endif\n\n\tnbytes = (duk_size_t) (((duk_uint8_t *) q) - ((duk_uint8_t *) p));  /* Note: 'q' is top-1 */\n\tduk_memmove((void *) p, (const void *) (p + 1), (size_t) nbytes);\n\n\tDUK_TVAL_SET_UNDEFINED(q);\n\tthr->valstack_top--;\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_DECREF(thr, &tv_tmp);  /* side effects */\n#endif\n}\n\nDUK_INTERNAL void duk_remove_unsafe(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_remove(thr, idx);  /* XXX: no optimization for now */\n}\n\nDUK_INTERNAL void duk_remove_m2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_remove(thr, -2);\n}\n\nDUK_INTERNAL void duk_remove_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) {\n#if defined(DUK_USE_PREFER_SIZE)\n\t/* XXX: maybe too slow even when preferring size? */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT(idx >= 0);\n\n\twhile (count-- > 0) {\n\t\tduk_remove(thr, idx);\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_tval *tv_newtop;\n\tduk_tval *tv;\n\tduk_size_t bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT(idx >= 0);\n\n\ttv_dst = thr->valstack_bottom + idx;\n\tDUK_ASSERT(tv_dst <= thr->valstack_top);\n\ttv_src = tv_dst + count;\n\tDUK_ASSERT(tv_src <= thr->valstack_top);\n\tbytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) tv_src);\n\n\tfor (tv = tv_dst; tv < tv_src; tv++) {\n\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t}\n\n\tduk_memmove((void *) tv_dst, (const void *) tv_src, bytes);\n\n\ttv_newtop = thr->valstack_top - count;\n\tfor (tv = tv_newtop; tv < thr->valstack_top; tv++) {\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t}\n\tthr->valstack_top = tv_newtop;\n\n\t/* When not preferring size, only NORZ macros are used; caller\n\t * is expected to DUK_REFZERO_CHECK().\n\t */\n#endif  /* DUK_USE_PREFER_SIZE */\n}\n\nDUK_INTERNAL void duk_remove_n_unsafe(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_remove_n(thr, idx, count);  /* XXX: no optimization for now */\n}\n\n/*\n *  Stack slice primitives\n */\n\nDUK_EXTERNAL void duk_xcopymove_raw(duk_hthread *to_thr, duk_hthread *from_thr, duk_idx_t count, duk_bool_t is_copy) {\n\tvoid *src;\n\tduk_size_t nbytes;\n\tduk_tval *p;\n\tduk_tval *q;\n\n\t/* XXX: several pointer comparison issues here */\n\n\tDUK_ASSERT_API_ENTRY(to_thr);\n\tDUK_CTX_ASSERT_VALID(to_thr);\n\tDUK_CTX_ASSERT_VALID(from_thr);\n\tDUK_ASSERT(to_thr->heap == from_thr->heap);\n\n\tif (DUK_UNLIKELY(to_thr == from_thr)) {\n\t\tDUK_ERROR_TYPE(to_thr, DUK_STR_INVALID_CONTEXT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tif (DUK_UNLIKELY((duk_uidx_t) count > (duk_uidx_t) DUK_USE_VALSTACK_LIMIT)) {\n\t\t/* Maximum value check ensures 'nbytes' won't wrap below.\n\t\t * Also handles negative count.\n\t\t */\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(to_thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(count >= 0);\n\n\tnbytes = sizeof(duk_tval) * (duk_size_t) count;\n\tif (DUK_UNLIKELY(nbytes == 0)) {\n\t\treturn;\n\t}\n\tDUK_ASSERT(to_thr->valstack_top <= to_thr->valstack_end);\n\tif (DUK_UNLIKELY((duk_size_t) ((duk_uint8_t *) to_thr->valstack_end - (duk_uint8_t *) to_thr->valstack_top) < nbytes)) {\n\t\tDUK_ERROR_RANGE_PUSH_BEYOND(to_thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tsrc = (void *) ((duk_uint8_t *) from_thr->valstack_top - nbytes);\n\tif (DUK_UNLIKELY(src < (void *) from_thr->valstack_bottom)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(to_thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* Copy values (no overlap even if to_thr == from_thr; that's not\n\t * allowed now anyway).\n\t */\n\tDUK_ASSERT(nbytes > 0);\n\tduk_memcpy((void *) to_thr->valstack_top, (const void *) src, (size_t) nbytes);\n\n\tp = to_thr->valstack_top;\n\tto_thr->valstack_top = (duk_tval *) (void *) (((duk_uint8_t *) p) + nbytes);\n\n\tif (is_copy) {\n\t\t/* Incref copies, keep originals. */\n\t\tq = to_thr->valstack_top;\n\t\twhile (p < q) {\n\t\t\tDUK_TVAL_INCREF(to_thr, p);  /* no side effects */\n\t\t\tp++;\n\t\t}\n\t} else {\n\t\t/* No net refcount change. */\n\t\tp = from_thr->valstack_top;\n\t\tq = (duk_tval *) (void *) (((duk_uint8_t *) p) - nbytes);\n\t\tfrom_thr->valstack_top = q;\n\n\t\twhile (p > q) {\n\t\t\tp--;\n\t\t\tDUK_TVAL_SET_UNDEFINED(p);\n\t\t\t/* XXX: fast primitive to set a bunch of values to UNDEFINED */\n\t\t}\n\t}\n}\n\n/* Internal helper: reserve a gap of 'count' elements at 'idx_base' and return a\n * pointer to the gap.  Values in the gap are garbage and MUST be initialized by\n * the caller before any side effects may occur.  The caller must ensure there's\n * enough stack reserve for 'count' values.\n */\nDUK_INTERNAL duk_tval *duk_reserve_gap(duk_hthread *thr, duk_idx_t idx_base, duk_idx_t count) {\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_size_t gap_bytes;\n\tduk_size_t copy_bytes;\n\n\t/* Caller is responsible for ensuring there's enough preallocated\n\t * value stack.\n\t */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_end - thr->valstack_top) >= (duk_size_t) count);\n\n\ttv_src = thr->valstack_bottom + idx_base;\n\tgap_bytes = (duk_size_t) count * sizeof(duk_tval);\n\ttv_dst = (duk_tval *) (void *) ((duk_uint8_t *) tv_src + gap_bytes);\n\tcopy_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) tv_src);\n\tthr->valstack_top = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_top + gap_bytes);\n\tduk_memmove((void *) tv_dst, (const void *) tv_src, copy_bytes);\n\n\t/* Values in the gap are left as garbage: caller must fill them in\n\t * and INCREF them before any side effects.\n\t */\n\treturn tv_src;\n}\n\n/*\n *  Get/opt/require\n */\n\nDUK_EXTERNAL void duk_require_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_UNDEFINED(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"undefined\", DUK_STR_NOT_UNDEFINED);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_EXTERNAL void duk_require_null(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_NULL(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"null\", DUK_STR_NOT_NULL);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_bool_t duk__get_boolean_raw(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) {\n\tduk_bool_t ret;\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BOOLEAN(tv)) {\n\t\tret = DUK_TVAL_GET_BOOLEAN(tv);\n\t\tDUK_ASSERT(ret == 0 || ret == 1);\n\t} else {\n\t\tret = def_value;\n\t\t/* Not guaranteed to be 0 or 1. */\n\t}\n\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_boolean_raw(thr, idx, 0);  /* default: false */\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_boolean_default(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_boolean_raw(thr, idx, def_value);\n}\n\nDUK_EXTERNAL duk_bool_t duk_require_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_LIKELY(DUK_TVAL_IS_BOOLEAN(tv))) {\n\t\tret = DUK_TVAL_GET_BOOLEAN(tv);\n\t\tDUK_ASSERT(ret == 0 || ret == 1);\n\t\treturn ret;\n\t} else {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"boolean\", DUK_STR_NOT_BOOLEAN);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n}\n\nDUK_EXTERNAL duk_bool_t duk_opt_boolean(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_boolean(thr, idx);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_double_t duk__get_number_raw(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {\n\tduk_double_union ret;\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tret.d = (duk_double_t) DUK_TVAL_GET_FASTINT(tv);  /* XXX: cast trick */\n\t}\n\telse\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv)) {\n\t\t/* When using packed duk_tval, number must be in NaN-normalized form\n\t\t * for it to be a duk_tval, so no need to normalize.  NOP for unpacked\n\t\t * duk_tval.\n\t\t */\n\t\tret.d = DUK_TVAL_GET_DOUBLE(tv);\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&ret));\n\t} else {\n\t\tret.d = def_value;\n\t\t/* Default value (including NaN) may not be normalized. */\n\t}\n\n\treturn ret.d;\n}\n\nDUK_EXTERNAL duk_double_t duk_get_number(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_number_raw(thr, idx, DUK_DOUBLE_NAN);  /* default: NaN */\n}\n\nDUK_EXTERNAL duk_double_t duk_get_number_default(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_number_raw(thr, idx, def_value);\n}\n\nDUK_EXTERNAL duk_double_t duk_require_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_double_union ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_NUMBER(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"number\", DUK_STR_NOT_NUMBER);\n\t\tDUK_WO_NORETURN(return 0.0;);\n\t}\n\n\tret.d = DUK_TVAL_GET_NUMBER(tv);\n\n\t/* When using packed duk_tval, number must be in NaN-normalized form\n\t * for it to be a duk_tval, so no need to normalize.  NOP for unpacked\n\t * duk_tval.\n\t */\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&ret));\n\treturn ret.d;\n}\n\nDUK_EXTERNAL duk_double_t duk_opt_number(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\t/* User provided default is not NaN normalized. */\n\t\treturn def_value;\n\t}\n\treturn duk_require_number(thr, idx);\n}\n\nDUK_EXTERNAL duk_int_t duk_get_int(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_get_uint(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_get_int_default(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, def_value, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_get_uint_default(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, def_value, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_require_int(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 1 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_require_uint(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 1 /*require*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_opt_int(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_int(thr, idx);\n}\n\nDUK_EXTERNAL duk_uint_t duk_opt_uint(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_uint(thr, idx);\n}\n\nDUK_EXTERNAL const char *duk_get_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tduk_hstring *h;\n\tconst char *ret;\n\tduk_size_t len;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\t\tret = (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\tlen = 0;\n\t\tret = NULL;\n\t}\n\n\tif (out_len != NULL) {\n\t\t*out_len = len;\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL const char *duk_require_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\tif (out_len) {\n\t\t*out_len = DUK_HSTRING_GET_BYTELEN(h);\n\t}\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_INTERNAL const char *duk_require_lstring_notsymbol(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hstring_notsymbol(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\tif (out_len) {\n\t\t*out_len = DUK_HSTRING_GET_BYTELEN(h);\n\t}\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_EXTERNAL const char *duk_get_string(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\treturn NULL;\n\t}\n}\n\nDUK_EXTERNAL const char *duk_opt_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\tif (out_len != NULL) {\n\t\t\t*out_len = def_len;\n\t\t}\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_lstring(thr, idx, out_len);\n}\n\nDUK_EXTERNAL const char *duk_opt_string(duk_hthread *thr, duk_idx_t idx, const char *def_ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_string(thr, idx);\n}\n\nDUK_EXTERNAL const char *duk_get_lstring_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len) {\n\tduk_hstring *h;\n\tconst char *ret;\n\tduk_size_t len;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\t\tret = (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\tlen = def_len;\n\t\tret = def_ptr;\n\t}\n\n\tif (out_len != NULL) {\n\t\t*out_len = len;\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL const char *duk_get_string_default(duk_hthread *thr, duk_idx_t idx, const char *def_value) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\treturn def_value;\n\t}\n}\n\nDUK_INTERNAL const char *duk_get_string_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring_notsymbol(thr, idx);\n\tif (h) {\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\treturn NULL;\n\t}\n}\n\nDUK_EXTERNAL const char *duk_require_string(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_require_lstring(thr, idx, NULL);\n}\n\nDUK_INTERNAL const char *duk_require_string_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hstring_notsymbol(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_EXTERNAL void duk_require_object(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_OBJECT(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"object\", DUK_STR_NOT_OBJECT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_LOCAL void *duk__get_pointer_raw(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tduk_tval *tv;\n\tvoid *p;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (!DUK_TVAL_IS_POINTER(tv)) {\n\t\treturn def_value;\n\t}\n\n\tp = DUK_TVAL_GET_POINTER(tv);  /* may be NULL */\n\treturn p;\n}\n\nDUK_EXTERNAL void *duk_get_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_pointer_raw(thr, idx, NULL /*def_value*/);\n}\n\nDUK_EXTERNAL void *duk_opt_pointer(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_pointer(thr, idx);\n}\n\nDUK_EXTERNAL void *duk_get_pointer_default(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_pointer_raw(thr, idx, def_value);\n}\n\nDUK_EXTERNAL void *duk_require_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *p;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: here we must be wary of the fact that a pointer may be\n\t * valid and be a NULL.\n\t */\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_POINTER(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"pointer\", DUK_STR_NOT_POINTER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\tp = DUK_TVAL_GET_POINTER(tv);  /* may be NULL */\n\treturn p;\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL void *duk_get_voidptr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_heaphdr *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (!DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\treturn NULL;\n\t}\n\n\th = DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(h != NULL);\n\treturn (void *) h;\n}\n#endif\n\nDUK_LOCAL void *duk__get_buffer_helper(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size, duk_bool_t throw_flag) {\n\tduk_hbuffer *h;\n\tvoid *ret;\n\tduk_size_t len;\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tif (out_size != NULL) {\n\t\t*out_size = 0;\n\t}\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_LIKELY(DUK_TVAL_IS_BUFFER(tv))) {\n\t\th = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tlen = DUK_HBUFFER_GET_SIZE(h);\n\t\tret = DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);\n\t} else {\n\t\tif (throw_flag) {\n\t\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"buffer\", DUK_STR_NOT_BUFFER);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t\tlen = def_size;\n\t\tret = def_ptr;\n\t}\n\n\tif (out_size != NULL) {\n\t\t*out_size = len;\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL void *duk_get_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_buffer_helper(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/);\n}\n\nDUK_EXTERNAL void *duk_opt_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\tif (out_size != NULL) {\n\t\t\t*out_size = def_size;\n\t\t}\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_buffer(thr, idx, out_size);\n}\n\nDUK_EXTERNAL void *duk_get_buffer_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_buffer_helper(thr, idx, out_size, def_ptr, def_len, 0 /*throw_flag*/);\n}\n\nDUK_EXTERNAL void *duk_require_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_buffer_helper(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 1 /*throw_flag*/);\n}\n\n/* Get the active buffer data area for a plain buffer or a buffer object.\n * Return NULL if the the value is not a buffer.  Note that a buffer may\n * have a NULL data pointer when its size is zero, the optional 'out_isbuffer'\n * argument allows caller to detect this reliably.\n */\nDUK_INTERNAL void *duk_get_buffer_data_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size, duk_bool_t throw_flag, duk_bool_t *out_isbuffer) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (out_isbuffer != NULL) {\n\t\t*out_isbuffer = 0;\n\t}\n\tif (out_size != NULL) {\n\t\t*out_size = def_size;\n\t}\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (out_size != NULL) {\n\t\t\t*out_size = DUK_HBUFFER_GET_SIZE(h);\n\t\t}\n\t\tif (out_isbuffer != NULL) {\n\t\t\t*out_isbuffer = 1;\n\t\t}\n\t\treturn (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);  /* may be NULL (but only if size is 0) */\n\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\telse if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\t/* XXX: this is probably a useful shared helper: for a\n\t\t\t * duk_hbufobj, get a validated buffer pointer/length.\n\t\t\t */\n\t\t\tduk_hbufobj *h_bufobj = (duk_hbufobj *) h;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t\t\tif (h_bufobj->buf != NULL &&\n\t\t\t    DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {\n\t\t\t\tduk_uint8_t *p;\n\n\t\t\t\tp = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf);\n\t\t\t\tif (out_size != NULL) {\n\t\t\t\t\t*out_size = (duk_size_t) h_bufobj->length;\n\t\t\t\t}\n\t\t\t\tif (out_isbuffer != NULL) {\n\t\t\t\t\t*out_isbuffer = 1;\n\t\t\t\t}\n\t\t\t\treturn (void *) (p + h_bufobj->offset);\n\t\t\t}\n\t\t\t/* if slice not fully valid, treat as error */\n\t\t}\n\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\tif (throw_flag) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"buffer\", DUK_STR_NOT_BUFFER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn def_ptr;\n}\n\nDUK_EXTERNAL void *duk_get_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_buffer_data_raw(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, NULL);\n}\n\nDUK_EXTERNAL void *duk_get_buffer_data_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_buffer_data_raw(thr, idx, out_size, def_ptr, def_size, 0 /*throw_flag*/, NULL);\n}\n\nDUK_EXTERNAL void *duk_opt_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\tif (out_size != NULL) {\n\t\t\t*out_size = def_size;\n\t\t}\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_buffer_data(thr, idx, out_size);\n}\n\nDUK_EXTERNAL void *duk_require_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_buffer_data_raw(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 1 /*throw_flag*/, NULL);\n}\n\n/* Raw helper for getting a value from the stack, checking its tag.\n * The tag cannot be a number because numbers don't have an internal\n * tag in the packed representation.\n */\n\nDUK_LOCAL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t tag) {\n\tduk_tval *tv;\n\tduk_heaphdr *ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_GET_TAG(tv) != tag) {\n\t\treturn (duk_heaphdr *) NULL;\n\t}\n\n\tret = DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(ret != NULL);  /* tagged null pointers should never occur */\n\treturn ret;\n\n}\n\nDUK_INTERNAL duk_hstring *duk_get_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n}\n\nDUK_INTERNAL duk_hstring *duk_get_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n\tif (DUK_UNLIKELY(h && DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\treturn NULL;\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_require_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"string\", DUK_STR_NOT_STRING);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_require_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n\tif (DUK_UNLIKELY(h == NULL || DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"string\", DUK_STR_NOT_STRING);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_get_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n}\n\nDUK_INTERNAL duk_hobject *duk_require_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"object\", DUK_STR_NOT_OBJECT);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hbuffer *duk_get_hbuffer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn (duk_hbuffer *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_BUFFER);\n}\n\nDUK_INTERNAL duk_hbuffer *duk_require_hbuffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hbuffer *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_BUFFER);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"buffer\", DUK_STR_NOT_BUFFER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hthread *duk_get_hthread(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_THREAD(h))) {\n\t\th = NULL;\n\t}\n\treturn (duk_hthread *) h;\n}\n\nDUK_INTERNAL duk_hthread *duk_require_hthread(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_THREAD(h)))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"thread\", DUK_STR_NOT_THREAD);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn (duk_hthread *) h;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_get_hcompfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_COMPFUNC(h))) {\n\t\th = NULL;\n\t}\n\treturn (duk_hcompfunc *) h;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_require_hcompfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_COMPFUNC(h)))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"compiledfunction\", DUK_STR_NOT_COMPFUNC);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn (duk_hcompfunc *) h;\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_get_hnatfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_NATFUNC(h))) {\n\t\th = NULL;\n\t}\n\treturn (duk_hnatfunc *) h;\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_require_hnatfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_NATFUNC(h)))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"nativefunction\", DUK_STR_NOT_NATFUNC);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn (duk_hnatfunc *) h;\n}\n\nDUK_EXTERNAL duk_c_function duk_get_c_function(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\tduk_hnatfunc *f;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_OBJECT(tv))) {\n\t\treturn NULL;\n\t}\n\th = DUK_TVAL_GET_OBJECT(tv);\n\tDUK_ASSERT(h != NULL);\n\n\tif (DUK_UNLIKELY(!DUK_HOBJECT_IS_NATFUNC(h))) {\n\t\treturn NULL;\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_HAS_NATFUNC(h));\n\tf = (duk_hnatfunc *) h;\n\n\treturn f->func;\n}\n\nDUK_EXTERNAL duk_c_function duk_opt_c_function(duk_hthread *thr, duk_idx_t idx, duk_c_function def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_c_function(thr, idx);\n}\n\nDUK_EXTERNAL duk_c_function duk_get_c_function_default(duk_hthread *thr, duk_idx_t idx, duk_c_function def_value) {\n\tduk_c_function ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_c_function(thr, idx);\n\tif (ret != NULL) {\n\t\treturn ret;\n\t}\n\n\treturn def_value;\n}\n\nDUK_EXTERNAL duk_c_function duk_require_c_function(duk_hthread *thr, duk_idx_t idx) {\n\tduk_c_function ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_c_function(thr, idx);\n\tif (DUK_UNLIKELY(!ret)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"nativefunction\", DUK_STR_NOT_NATFUNC);\n\t\tDUK_WO_NORETURN(return ret;);\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_require_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tif (DUK_UNLIKELY(!duk_is_function(thr, idx))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"function\", DUK_STR_NOT_FUNCTION);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_EXTERNAL void duk_require_constructable(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hobject_accept_mask(thr, idx, DUK_TYPE_MASK_LIGHTFUNC);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_HAS_CONSTRUCTABLE(h))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"constructable\", DUK_STR_NOT_CONSTRUCTABLE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\t/* Lightfuncs (h == NULL) are constructable. */\n}\n\nDUK_EXTERNAL duk_hthread *duk_get_context(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_get_hthread(thr, idx);\n}\n\nDUK_EXTERNAL duk_hthread *duk_require_context(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_require_hthread(thr, idx);\n}\n\nDUK_EXTERNAL duk_hthread *duk_opt_context(duk_hthread *thr, duk_idx_t idx, duk_hthread *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_context(thr, idx);\n}\n\nDUK_EXTERNAL duk_hthread *duk_get_context_default(duk_hthread *thr, duk_idx_t idx, duk_hthread *def_value) {\n\tduk_hthread *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_context(thr, idx);\n\tif (ret != NULL) {\n\t\treturn ret;\n\t}\n\n\treturn def_value;\n}\n\nDUK_EXTERNAL void *duk_get_heapptr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_HEAP_ALLOCATED(tv))) {\n\t\treturn (void *) NULL;\n\t}\n\n\tret = (void *) DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(ret != NULL);\n\treturn ret;\n}\n\nDUK_EXTERNAL void *duk_opt_heapptr(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_heapptr(thr, idx);\n}\n\nDUK_EXTERNAL void *duk_get_heapptr_default(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tvoid *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_heapptr(thr, idx);\n\tif (ret != NULL) {\n\t\treturn ret;\n\t}\n\n\treturn def_value;\n}\n\nDUK_EXTERNAL void *duk_require_heapptr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_HEAP_ALLOCATED(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"heapobject\", DUK_STR_UNEXPECTED_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\tret = (void *) DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(ret != NULL);\n\treturn ret;\n}\n\n/* Internal helper for getting/requiring a duk_hobject with possible promotion. */\nDUK_LOCAL duk_hobject *duk__get_hobject_promote_mask_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tduk_uint_t val_mask;\n\tduk_hobject *res;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tres = duk_get_hobject(thr, idx);  /* common case, not promoted */\n\tif (DUK_LIKELY(res != NULL)) {\n\t\tDUK_ASSERT(res != NULL);\n\t\treturn res;\n\t}\n\n\tval_mask = duk_get_type_mask(thr, idx);\n\tif (val_mask & type_mask) {\n\t\tif (type_mask & DUK_TYPE_MASK_PROMOTE) {\n\t\t\tres = duk_to_hobject(thr, idx);\n\t\t\tDUK_ASSERT(res != NULL);\n\t\t\treturn res;\n\t\t} else {\n\t\t\treturn NULL;  /* accept without promoting */\n\t\t}\n\t}\n\n\tif (type_mask & DUK_TYPE_MASK_THROW) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"object\", DUK_STR_NOT_OBJECT);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn NULL;\n}\n\n/* Get a duk_hobject * at 'idx'; if the value is not an object but matches the\n * supplied 'type_mask', promote it to an object and return the duk_hobject *.\n * This is useful for call sites which want an object but also accept a plain\n * buffer and/or a lightfunc which gets automatically promoted to an object.\n * Return value is NULL if value is neither an object nor a plain type allowed\n * by the mask.\n */\nDUK_INTERNAL duk_hobject *duk_get_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_PROMOTE);\n}\n\n/* Like duk_get_hobject_promote_mask() but throw a TypeError instead of\n * returning a NULL.\n */\nDUK_INTERNAL duk_hobject *duk_require_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_THROW | DUK_TYPE_MASK_PROMOTE);\n}\n\n/* Require a duk_hobject * at 'idx'; if the value is not an object but matches the\n * supplied 'type_mask', return a NULL instead.  Otherwise throw a TypeError.\n */\nDUK_INTERNAL duk_hobject *duk_require_hobject_accept_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_THROW);\n}\n\nDUK_INTERNAL duk_hobject *duk_get_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_DISABLE(classnum >= 0);  /* unsigned */\n\tDUK_ASSERT(classnum <= DUK_HOBJECT_CLASS_MAX);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h) != classnum)) {\n\t\th = NULL;\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_require_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_DISABLE(classnum >= 0);  /* unsigned */\n\tDUK_ASSERT(classnum <= DUK_HOBJECT_CLASS_MAX);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h) == classnum))) {\n\t\tduk_hstring *h_class;\n\t\th_class = DUK_HTHREAD_GET_STRING(thr, DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum));\n\t\tDUK_UNREF(h_class);\n\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, (const char *) DUK_HSTRING_GET_DATA(h_class), DUK_STR_UNEXPECTED_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_EXTERNAL duk_size_t duk_get_length(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\tcase DUK_TAG_BOOLEAN:\n\tcase DUK_TAG_POINTER:\n\t\treturn 0;\n#if defined(DUK_USE_PREFER_SIZE)\n\t/* String and buffer have a virtual non-configurable .length property\n\t * which is within size_t range so it can be looked up without specific\n\t * type checks.  Lightfuncs inherit from %NativeFunctionPrototype%\n\t * which provides an inherited .length accessor; it could be overwritten\n\t * to produce unexpected types or values, but just number convert and\n\t * duk_size_t cast for now.\n\t */\n\tcase DUK_TAG_STRING:\n\tcase DUK_TAG_BUFFER:\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tduk_size_t ret;\n\t\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n\t\tret = (duk_size_t) duk_to_number_m1(thr);\n\t\tduk_pop_unsafe(thr);\n\t\treturn ret;\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn (duk_size_t) DUK_HSTRING_GET_CHARLEN(h);\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (duk_size_t) DUK_HBUFFER_GET_SIZE(h);\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* We could look up the length from the lightfunc duk_tval,\n\t\t * but since Duktape 2.2 lightfunc .length comes from\n\t\t * %NativeFunctionPrototype% which can be overridden, so\n\t\t * look up the property explicitly.\n\t\t */\n\t\tduk_size_t ret;\n\t\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n\t\tret = (duk_size_t) duk_to_number_m1(thr);\n\t\tduk_pop_unsafe(thr);\n\t\treturn ret;\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (duk_size_t) duk_hobject_get_length(thr, h);\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* number or 'unused' */\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv) || DUK_TVAL_IS_UNUSED(tv));\n\t\treturn 0;\n\t}\n\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  duk_known_xxx() helpers\n *\n *  Used internally when we're 100% sure that a certain index is valid and\n *  contains an object of a certain type.  For example, if we duk_push_object()\n *  we can then safely duk_known_hobject(thr, -1).  These helpers just assert\n *  for the index and type, and if the assumptions are not valid, memory unsafe\n *  behavior happens.\n */\n\nDUK_LOCAL duk_heaphdr *duk__known_heaphdr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_heaphdr *h;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tif (idx < 0) {\n\t\ttv = thr->valstack_top + idx;\n\t} else {\n\t\ttv = thr->valstack_bottom + idx;\n\t}\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\tDUK_ASSERT(tv < thr->valstack_top);\n\th = DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(h != NULL);\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_known_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hstring(thr, idx) != NULL);\n\treturn (duk_hstring *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hobject *duk_known_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hobject(thr, idx) != NULL);\n\treturn (duk_hobject *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hbuffer *duk_known_hbuffer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hbuffer(thr, idx) != NULL);\n\treturn (duk_hbuffer *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_known_hcompfunc(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hcompfunc(thr, idx) != NULL);\n\treturn (duk_hcompfunc *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_known_hnatfunc(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hnatfunc(thr, idx) != NULL);\n\treturn (duk_hnatfunc *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_EXTERNAL void duk_set_length(duk_hthread *thr, duk_idx_t idx, duk_size_t len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_normalize_index(thr, idx);\n\tduk_push_uint(thr, (duk_uint_t) len);\n\tduk_put_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n}\n\n/*\n *  Conversions and coercions\n *\n *  The conversion/coercions are in-place operations on the value stack.\n *  Some operations are implemented here directly, while others call a\n *  helper in duk_js_ops.c after validating arguments.\n */\n\n/* E5 Section 8.12.8 */\n\nDUK_LOCAL duk_bool_t duk__defaultvalue_coerce_attempt(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t func_stridx) {\n\tif (duk_get_prop_stridx(thr, idx, func_stridx)) {\n\t\t/* [ ... func ] */\n\t\tif (duk_is_callable(thr, -1)) {\n\t\t\tduk_dup(thr, idx);         /* -> [ ... func this ] */\n\t\t\tduk_call_method(thr, 0);     /* -> [ ... retval ] */\n\t\t\tif (duk_is_primitive(thr, -1)) {\n\t\t\t\tduk_replace(thr, idx);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\t/* [ ... retval ]; popped below */\n\t\t}\n\t}\n\tduk_pop_unsafe(thr);  /* [ ... func/retval ] -> [ ... ] */\n\treturn 0;\n}\n\nDUK_EXTERNAL void duk_to_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n}\n\nDUK_EXTERNAL void duk_to_null(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tDUK_TVAL_SET_NULL_UPDREF(thr, tv);  /* side effects */\n}\n\n/* E5 Section 9.1 */\nDUK_LOCAL const char * const duk__toprim_hint_strings[3] = {\n\t\"default\", \"string\", \"number\"\n};\nDUK_LOCAL void duk__to_primitive_helper(duk_hthread *thr, duk_idx_t idx, duk_int_t hint, duk_bool_t check_symbol) {\n\t/* Inline initializer for coercers[] is not allowed by old compilers like BCC. */\n\tduk_small_uint_t coercers[2];\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(hint == DUK_HINT_NONE || hint == DUK_HINT_NUMBER || hint == DUK_HINT_STRING);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\t/* If already primitive, return as is. */\n\tif (!duk_check_type_mask(thr, idx, DUK_TYPE_MASK_OBJECT |\n\t                                   DUK_TYPE_MASK_LIGHTFUNC |\n\t                                   DUK_TYPE_MASK_BUFFER)) {\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* duk_to_string() relies on this behavior */\n\t\treturn;\n\t}\n\n\t/* @@toPrimitive lookup.  Also do for plain buffers and lightfuncs\n\t * which mimic objects.\n\t */\n\tif (check_symbol && duk_get_method_stridx(thr, idx, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE)) {\n\t\tDUK_ASSERT(hint >= 0 && (duk_size_t) hint < sizeof(duk__toprim_hint_strings) / sizeof(const char *));\n\t\tduk_dup(thr, idx);\n\t\tduk_push_string(thr, duk__toprim_hint_strings[hint]);\n\t\tduk_call_method(thr, 1);  /* [ ... method value hint ] -> [ ... res] */\n\t\tif (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT |\n\t                                         DUK_TYPE_MASK_LIGHTFUNC |\n\t\t                                 DUK_TYPE_MASK_BUFFER)) {\n\t\t\tgoto fail;\n\t\t}\n\t\tduk_replace(thr, idx);\n\t\treturn;\n\t}\n\n\t/* Objects are coerced based on E5 specification.\n\t * Lightfuncs are coerced because they behave like\n\t * objects even if they're internally a primitive\n\t * type.  Same applies to plain buffers, which behave\n\t * like ArrayBuffer objects since Duktape 2.x.\n\t */\n\n\t/* Hint magic for Date is unnecessary in ES2015 because of\n\t * Date.prototype[@@toPrimitive].  However, it is needed if\n\t * symbol support is not enabled.\n\t */\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\tif (hint == DUK_HINT_NONE) {\n\t\thint = DUK_HINT_NUMBER;\n\t}\n#else  /* DUK_USE_SYMBOL_BUILTIN */\n\tif (hint == DUK_HINT_NONE) {\n\t\tduk_small_uint_t class_number;\n\n\t\tclass_number = duk_get_class_number(thr, idx);\n\t\tif (class_number == DUK_HOBJECT_CLASS_DATE) {\n\t\t\thint = DUK_HINT_STRING;\n\t\t} else {\n\t\t\thint = DUK_HINT_NUMBER;\n\t\t}\n\t}\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n\n\tcoercers[0] = DUK_STRIDX_VALUE_OF;\n\tcoercers[1] = DUK_STRIDX_TO_STRING;\n\tif (hint == DUK_HINT_STRING) {\n\t\tcoercers[0] = DUK_STRIDX_TO_STRING;\n\t\tcoercers[1] = DUK_STRIDX_VALUE_OF;\n\t}\n\n\tif (duk__defaultvalue_coerce_attempt(thr, idx, coercers[0])) {\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* duk_to_string() relies on this behavior */\n\t\treturn;\n\t}\n\n\tif (duk__defaultvalue_coerce_attempt(thr, idx, coercers[1])) {\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* duk_to_string() relies on this behavior */\n\t\treturn;\n\t}\n\n fail:\n\tDUK_ERROR_TYPE(thr, DUK_STR_TOPRIMITIVE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_to_primitive(duk_hthread *thr, duk_idx_t idx, duk_int_t hint) {\n\tduk__to_primitive_helper(thr, idx, hint, 1 /*check_symbol*/);\n}\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL void duk_to_primitive_ordinary(duk_hthread *thr, duk_idx_t idx, duk_int_t hint) {\n\tduk__to_primitive_helper(thr, idx, hint, 0 /*check_symbol*/);\n}\n#endif\n\n/* E5 Section 9.2 */\nDUK_EXTERNAL duk_bool_t duk_to_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_bool_t val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tval = duk_js_toboolean(tv);\n\tDUK_ASSERT(val == 0 || val == 1);\n\n\t/* Note: no need to re-lookup tv, conversion is side effect free. */\n\tDUK_ASSERT(tv != NULL);\n\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv, val);  /* side effects */\n\treturn val;\n}\n\nDUK_INTERNAL duk_bool_t duk_to_boolean_top_pop(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_bool_t val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tval = duk_js_toboolean(tv);\n\tDUK_ASSERT(val == 0 || val == 1);\n\n\tduk_pop_unsafe(thr);\n\treturn val;\n}\n\nDUK_EXTERNAL duk_double_t duk_to_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_double_t d;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: No need to normalize; the whole operation could be inlined here to\n\t * avoid 'tv' re-lookup.\n\t */\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\td = duk_js_tonumber(thr, tv);  /* XXX: fastint coercion? now result will always be a non-fastint */\n\n\t/* ToNumber() may have side effects so must relookup 'tv'. */\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d);  /* side effects */\n\treturn d;\n}\n\nDUK_INTERNAL duk_double_t duk_to_number_m1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_number(thr, -1);\n}\nDUK_INTERNAL duk_double_t duk_to_number_m2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_number(thr, -2);\n}\n\nDUK_INTERNAL duk_double_t duk_to_number_tval(duk_hthread *thr, duk_tval *tv) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_double_t res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_tval(thr, tv);\n\tres = duk_to_number_m1(thr);\n\tduk_pop_unsafe(thr);\n\treturn res;\n#else\n\tduk_double_t res;\n\tduk_tval *tv_dst;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ASSERT_SPACE();\n\n\ttv_dst = thr->valstack_top++;\n\tDUK_TVAL_SET_TVAL(tv_dst, tv);\n\tDUK_TVAL_INCREF(thr, tv_dst);  /* decref not necessary */\n\tres = duk_to_number_m1(thr);  /* invalidates tv_dst */\n\n\ttv_dst = --thr->valstack_top;\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_dst));\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv_dst));  /* plain number */\n\tDUK_TVAL_SET_UNDEFINED(tv_dst);  /* valstack init policy */\n\n\treturn res;\n#endif\n}\n\n/* XXX: combine all the integer conversions: they share everything\n * but the helper function for coercion.\n */\n\ntypedef duk_double_t (*duk__toint_coercer)(duk_hthread *thr, duk_tval *tv);\n\nDUK_LOCAL duk_double_t duk__to_int_uint_helper(duk_hthread *thr, duk_idx_t idx, duk__toint_coercer coerce_func) {\n\tduk_tval *tv;\n\tduk_double_t d;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_FASTINT)\n\t/* If argument is a fastint, guarantee that it remains one.\n\t * There's no downgrade check for other cases.\n\t */\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\t/* XXX: Unnecessary conversion back and forth. */\n\t\treturn (duk_double_t) DUK_TVAL_GET_FASTINT(tv);\n\t}\n#endif\n\td = coerce_func(thr, tv);\n\n\t/* XXX: fastint? */\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d);  /* side effects */\n\treturn d;\n}\n\nDUK_EXTERNAL duk_int_t duk_to_int(duk_hthread *thr, duk_idx_t idx) {\n\t/* Value coercion (in stack): ToInteger(), E5 Section 9.4,\n\t * API return value coercion: custom.\n\t */\n\tDUK_ASSERT_API_ENTRY(thr);\n\t(void) duk__to_int_uint_helper(thr, idx, duk_js_tointeger);\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_to_uint(duk_hthread *thr, duk_idx_t idx) {\n\t/* Value coercion (in stack): ToInteger(), E5 Section 9.4,\n\t * API return value coercion: custom.\n\t */\n\tDUK_ASSERT_API_ENTRY(thr);\n\t(void) duk__to_int_uint_helper(thr, idx, duk_js_tointeger);\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_int32_t duk_to_int32(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_int32_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tret = duk_js_toint32(thr, tv);\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_I32_UPDREF(thr, tv, ret);  /* side effects */\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_uint32_t duk_to_uint32(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_uint32_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tret = duk_js_touint32(thr, tv);\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_U32_UPDREF(thr, tv, ret);  /* side effects */\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_uint16_t duk_to_uint16(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_uint16_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tret = duk_js_touint16(thr, tv);\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_U32_UPDREF(thr, tv, ret);  /* side effects */\n\treturn ret;\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Special coercion for Uint8ClampedArray. */\nDUK_INTERNAL duk_uint8_t duk_to_uint8clamped(duk_hthread *thr, duk_idx_t idx) {\n\tduk_double_t d;\n\tduk_double_t t;\n\tduk_uint8_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: Simplify this algorithm, should be possible to come up with\n\t * a shorter and faster algorithm by inspecting IEEE representation\n\t * directly.\n\t */\n\n\td = duk_to_number(thr, idx);\n\tif (d <= 0.0) {\n\t\treturn 0;\n\t} else if (d >= 255) {\n\t\treturn 255;\n\t} else if (DUK_ISNAN(d)) {\n\t\t/* Avoid NaN-to-integer coercion as it is compiler specific. */\n\t\treturn 0;\n\t}\n\n\tt = d - DUK_FLOOR(d);\n\tif (t == 0.5) {\n\t\t/* Exact halfway, round to even. */\n\t\tret = (duk_uint8_t) d;\n\t\tret = (ret + 1) & 0xfe;  /* Example: d=3.5, t=0.5 -> ret = (3 + 1) & 0xfe = 4 & 0xfe = 4\n\t\t                          * Example: d=4.5, t=0.5 -> ret = (4 + 1) & 0xfe = 5 & 0xfe = 4\n\t\t                          */\n\t} else {\n\t\t/* Not halfway, round to nearest. */\n\t\tret = (duk_uint8_t) (d + 0.5);\n\t}\n\treturn ret;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_EXTERNAL const char *duk_to_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_to_string(thr, idx);\n\tDUK_ASSERT(duk_is_string(thr, idx));\n\treturn duk_require_lstring(thr, idx, out_len);\n}\n\nDUK_LOCAL duk_ret_t duk__safe_to_string_raw(duk_hthread *thr, void *udata) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(udata);\n\n\t(void) duk_to_string(thr, -1);\n\treturn 1;\n}\n\nDUK_EXTERNAL const char *duk_safe_to_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\t/* We intentionally ignore the duk_safe_call() return value and only\n\t * check the output type.  This way we don't also need to check that\n\t * the returned value is indeed a string in the success case.\n\t */\n\n\tduk_dup(thr, idx);\n\t(void) duk_safe_call(thr, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\tif (!duk_is_string(thr, -1)) {\n\t\t/* Error: try coercing error to string once. */\n\t\t(void) duk_safe_call(thr, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\t\tif (!duk_is_string(thr, -1)) {\n\t\t\t/* Double error */\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_ERROR);\n\t\t} else {\n\t\t\t;\n\t\t}\n\t} else {\n\t\t/* String; may be a symbol, accepted. */\n\t\t;\n\t}\n\tDUK_ASSERT(duk_is_string(thr, -1));\n\n\tduk_replace(thr, idx);\n\tDUK_ASSERT(duk_get_string(thr, idx) != NULL);\n\treturn duk_get_lstring(thr, idx, out_len);\n}\n\nDUK_EXTERNAL const char *duk_to_stacktrace(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tidx = duk_require_normalize_index(thr, idx);\n\n\t/* The expected argument to the call is an Error object.  The stack\n\t * trace is extracted without an inheritance-based instanceof check\n\t * so that one can also extract the stack trace of a foreign error\n\t * created in another Realm.  Accept only a string .stack property.\n\t */\n\tif (duk_is_object(thr, idx)) {\n\t\t(void) duk_get_prop_string(thr, idx, \"stack\");\n\t\tif (duk_is_string(thr, -1)) {\n\t\t\tduk_replace(thr, idx);\n\t\t} else {\n\t\t\tduk_pop(thr);\n\t\t}\n\t}\n\n\treturn duk_to_string(thr, idx);\n}\n\nDUK_LOCAL duk_ret_t duk__safe_to_stacktrace_raw(duk_hthread *thr, void *udata) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(udata);\n\n\t(void) duk_to_stacktrace(thr, -1);\n\n\treturn 1;\n}\n\nDUK_EXTERNAL const char *duk_safe_to_stacktrace(duk_hthread *thr, duk_idx_t idx) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tidx = duk_require_normalize_index(thr, idx);\n\n\tduk_dup(thr, idx);\n\trc = duk_safe_call(thr, duk__safe_to_stacktrace_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\tif (rc != 0) {\n\t\t/* Coercion failed.  Try to coerce the coercion itself error\n\t\t * to a stack trace once.  If that also fails, return a fixed,\n\t\t * preallocated 'Error' string to avoid potential infinite loop.\n\t\t */\n\t\trc = duk_safe_call(thr, duk__safe_to_stacktrace_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\t\tif (rc != 0) {\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_ERROR);\n\t\t}\n\t}\n\tduk_replace(thr, idx);\n\n\treturn duk_get_string(thr, idx);\n}\n\nDUK_INTERNAL duk_hstring *duk_to_property_key_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_to_primitive(thr, idx, DUK_HINT_STRING);  /* needed for e.g. Symbol objects */\n\th = duk_get_hstring(thr, idx);\n\tif (h == NULL) {\n\t\t/* The \"is string?\" check may seem unnecessary, but as things\n\t\t * are duk_to_hstring() invokes ToString() which fails for\n\t\t * symbols.  But since symbols are already strings for Duktape\n\t\t * C API, we check for that before doing the coercion.\n\t\t */\n\t\th = duk_to_hstring(thr, idx);\n\t}\n\tDUK_ASSERT(h != NULL);\n\treturn h;\n}\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* only needed by debugger for now */\nDUK_INTERNAL duk_hstring *duk_safe_to_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_safe_to_string(thr, idx);\n\tDUK_ASSERT(duk_is_string(thr, idx));\n\tDUK_ASSERT(duk_get_hstring(thr, idx) != NULL);\n\treturn duk_known_hstring(thr, idx);\n}\n#endif\n\n/* Push Object.prototype.toString() output for 'tv'. */\n#if 0  /* See XXX note why this variant doesn't work. */\nDUK_INTERNAL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects) {\n\tduk_uint_t stridx_bidx = 0;  /* (prototype_bidx << 16) + default_tag_stridx */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Conceptually for any non-undefined/null value we should do a\n\t * ToObject() coercion and look up @@toStringTag (from the object\n\t * prototype) to see if a custom tag should be used.  Avoid the\n\t * actual conversion by doing a prototype lookup without the object\n\t * coercion.  However, see problem below.\n\t */\n\n\tduk_push_literal(thr, \"[object \");  /* -> [ ... \"[object\" ] */\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:  /* Treat like 'undefined', shouldn't happen. */\n\tcase DUK_TAG_UNDEFINED: {\n\t\tstridx_bidx = DUK_STRIDX_UC_UNDEFINED;\n\t\tgoto use_stridx;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tstridx_bidx = DUK_STRIDX_UC_NULL;\n\t\tgoto use_stridx;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tstridx_bidx = (DUK_BIDX_BOOLEAN_PROTOTYPE << 16) + DUK_STRIDX_UC_BOOLEAN;\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tstridx_bidx = (DUK_BIDX_POINTER_PROTOTYPE << 16) + DUK_STRIDX_UC_POINTER;\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tstridx_bidx = (DUK_BIDX_FUNCTION_PROTOTYPE << 16) + DUK_STRIDX_UC_FUNCTION;\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\t/* Even without DUK_USE_SYMBOL_BUILTIN the Symbol\n\t\t\t * prototype exists so we can lookup @@toStringTag\n\t\t\t * and provide [object Symbol] for symbol values\n\t\t\t * created from C code.\n\t\t\t */\n\t\t\tstridx_bidx = (DUK_BIDX_SYMBOL_PROTOTYPE << 16) + DUK_STRIDX_UC_SYMBOL;\n\t\t} else {\n\t\t\tstridx_bidx = (DUK_BIDX_STRING_PROTOTYPE << 16) + DUK_STRIDX_UC_STRING;\n\t\t}\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_push_tval(thr, tv);\n\t\tstridx_bidx = 0xffffffffUL;  /* Marker value. */\n\t\tgoto use_pushed_object;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\tstridx_bidx = (DUK_BIDX_UINT8ARRAY_PROTOTYPE << 16) + DUK_STRIDX_UINT8_ARRAY;\n\t\tgoto use_proto_bidx;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\t/* Fall through to generic number case. */\n#endif\n\tdefault: {\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));  /* number (maybe fastint) */\n\t\tstridx_bidx = (DUK_BIDX_NUMBER_PROTOTYPE << 16) + DUK_STRIDX_UC_NUMBER;\n\t\tgoto use_proto_bidx;\n\t}\n\t}\n\tDUK_ASSERT(0);  /* Never here. */\n\n use_proto_bidx:\n\tDUK_ASSERT_BIDX_VALID((stridx_bidx >> 16) & 0xffffUL);\n\tduk_push_hobject(thr, thr->builtins[(stridx_bidx >> 16) & 0xffffUL]);\n\t/* Fall through. */\n\n use_pushed_object:\n\t/* [ ... \"[object\" obj ] */\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t/* XXX: better handling with avoid_side_effects == 1; lookup tval\n\t * without Proxy or getter side effects, and use it in sanitized\n\t * form if it's a string.\n\t */\n\tif (!avoid_side_effects) {\n\t\t/* XXX: The problem with using the prototype object as the\n\t\t * lookup base is that if @@toStringTag is a getter, its\n\t\t * 'this' binding must be the ToObject() coerced input value,\n\t\t * not the prototype object of the type.\n\t\t */\n\t\t(void) duk_get_prop_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG);\n\t\tif (duk_is_string_notsymbol(thr, -1)) {\n\t\t\tduk_remove_m2(thr);\n\t\t\tgoto finish;\n\t\t}\n\t\tduk_pop_unsafe(thr);\n\t}\n#endif\n\n\tif (stridx_bidx == 0xffffffffUL) {\n\t\tduk_hobject *h_obj;\n\t\tduk_small_uint_t classnum;\n\n\t\th_obj = duk_known_hobject(thr, -1);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tclassnum = DUK_HOBJECT_GET_CLASS_NUMBER(h_obj);\n\t\tstridx_bidx = DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum);\n\t} else {\n\t\t/* stridx_bidx already has the desired fallback stridx. */\n\t\t;\n\t}\n\tduk_pop_unsafe(thr);\n\t/* Fall through. */\n\n use_stridx:\n\t/* [ ... \"[object\" ] */\n\tduk_push_hstring_stridx(thr, stridx_bidx & 0xffffUL);\n\n finish:\n\t/* [ ... \"[object\" tag ] */\n\tduk_push_literal(thr, \"]\");\n\tduk_concat(thr, 3);  /* [ ... \"[object\" tag \"]\" ] -> [ ... res ] */\n}\n#endif  /* 0 */\n\nDUK_INTERNAL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects) {\n\tduk_hobject *h_obj;\n\tduk_small_uint_t classnum;\n\tduk_small_uint_t stridx;\n\tduk_tval tv_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\t/* Stabilize 'tv', duk_push_literal() may trigger side effects. */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv);\n\ttv = &tv_tmp;\n\n\t/* Conceptually for any non-undefined/null value we should do a\n\t * ToObject() coercion and look up @@toStringTag (from the object\n\t * prototype) to see if a custom result should be used.  We'd like to\n\t * avoid the actual conversion, but even for primitive types the\n\t * prototype may have @@toStringTag.  What's worse, the @@toStringTag\n\t * property may be a getter that must get the object coerced value\n\t * (not the prototype) as its 'this' binding.\n\t *\n\t * For now, do an actual object coercion.  This could be avoided by\n\t * doing a side effect free lookup to see if a getter would be invoked.\n\t * If not, the value can be read directly and the object coercion could\n\t * be avoided.  This may not be worth it in practice, because\n\t * Object.prototype.toString() is usually not performance critical.\n\t */\n\n\tduk_push_literal(thr, \"[object \");  /* -> [ ... \"[object\" ] */\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:  /* Treat like 'undefined', shouldn't happen. */\n\tcase DUK_TAG_UNDEFINED: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_UNDEFINED);\n\t\tgoto finish;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_NULL);\n\t\tgoto finish;\n\t}\n\t}\n\n\tduk_push_tval(thr, tv);\n\ttv = NULL;  /* Invalidated by ToObject(). */\n\tduk_to_object(thr, -1);\n\n\t/* [ ... \"[object\" obj ] */\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t/* XXX: better handling with avoid_side_effects == 1; lookup tval\n\t * without Proxy or getter side effects, and use it in sanitized\n\t * form if it's a string.\n\t */\n\tif (!avoid_side_effects) {\n\t\t(void) duk_get_prop_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG);\n\t\tif (duk_is_string_notsymbol(thr, -1)) {\n\t\t\tduk_remove_m2(thr);\n\t\t\tgoto finish;\n\t\t}\n\t\tduk_pop_unsafe(thr);\n\t}\n#else\n\tDUK_UNREF(avoid_side_effects);\n#endif\n\n\th_obj = duk_known_hobject(thr, -1);\n\tDUK_ASSERT(h_obj != NULL);\n\tclassnum = DUK_HOBJECT_GET_CLASS_NUMBER(h_obj);\n\tstridx = DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum);\n\tduk_pop_unsafe(thr);\n\tduk_push_hstring_stridx(thr, stridx);\n\n finish:\n\t/* [ ... \"[object\" tag ] */\n\tduk_push_literal(thr, \"]\");\n\tduk_concat(thr, 3);  /* [ ... \"[object\" tag \"]\" ] -> [ ... res ] */\n}\n\n/* XXX: other variants like uint, u32 etc */\nDUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped) {\n\tduk_tval *tv;\n\tduk_tval tv_tmp;\n\tduk_double_t d, dmin, dmax;\n\tduk_int_t res;\n\tduk_bool_t clamped = 0;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\td = duk_js_tointeger(thr, tv);  /* E5 Section 9.4, ToInteger() */\n\n\tdmin = (duk_double_t) minval;\n\tdmax = (duk_double_t) maxval;\n\n\tif (d < dmin) {\n\t\tclamped = 1;\n\t\tres = minval;\n\t\td = dmin;\n\t} else if (d > dmax) {\n\t\tclamped = 1;\n\t\tres = maxval;\n\t\td = dmax;\n\t} else {\n\t\tres = (duk_int_t) d;\n\t}\n\tDUK_UNREF(d);  /* SCANBUILD: with suitable dmin/dmax limits 'd' is unused */\n\t/* 'd' and 'res' agree here */\n\n\t/* Relookup in case duk_js_tointeger() ends up e.g. coercing an object. */\n\ttv = duk_get_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);  /* not popped by side effect */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv);\n#if defined(DUK_USE_FASTINT)\n#if (DUK_INT_MAX <= 0x7fffffffL)\n\tDUK_TVAL_SET_I32(tv, res);\n#else\n\t/* Clamping needed if duk_int_t is 64 bits. */\n\tif (res >= DUK_FASTINT_MIN && res <= DUK_FASTINT_MAX) {\n\t\tDUK_TVAL_SET_FASTINT(tv, res);\n\t} else {\n\t\tDUK_TVAL_SET_NUMBER(tv, d);\n\t}\n#endif\n#else\n\tDUK_TVAL_SET_NUMBER(tv, d);  /* no need to incref */\n#endif\n\tDUK_TVAL_DECREF(thr, &tv_tmp);  /* side effects */\n\n\tif (out_clamped) {\n\t\t*out_clamped = clamped;\n\t} else {\n\t\t/* coerced value is updated to value stack even when RangeError thrown */\n\t\tif (clamped) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_NUMBER_OUTSIDE_RANGE);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t}\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_int_t duk_to_int_clamped(duk_hthread *thr, duk_idx_t idx, duk_idx_t minval, duk_idx_t maxval) {\n\tduk_bool_t dummy;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_to_int_clamped_raw(thr, idx, minval, maxval, &dummy);\n}\n\nDUK_INTERNAL duk_int_t duk_to_int_check_range(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_int_clamped_raw(thr, idx, minval, maxval, NULL);  /* out_clamped==NULL -> RangeError if outside range */\n}\n\nDUK_EXTERNAL const char *duk_to_string(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_LC_UNDEFINED);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_LC_NULL);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tif (DUK_TVAL_GET_BOOLEAN(tv)) {\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_TRUE);\n\t\t} else {\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_FALSE);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\t/* Nop for actual strings, TypeError for Symbols.\n\t\t * Because various internals rely on ToString() coercion of\n\t\t * internal strings, -allow- (NOP) string coercion for hidden\n\t\t * symbols.\n\t\t */\n#if 1\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CANNOT_STRING_COERCE_SYMBOL);\n\t\t\tDUK_WO_NORETURN(goto skip_replace;);\n\t\t} else {\n\t\t\tgoto skip_replace;\n\t\t}\n#else\n\t\tgoto skip_replace;\n#endif\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: /* Go through Uint8Array.prototype.toString() for coercion. */\n\tcase DUK_TAG_OBJECT: {\n\t\t/* Plain buffers: go through ArrayBuffer.prototype.toString()\n\t\t * for coercion.\n\t\t *\n\t\t * Symbol objects: duk_to_primitive() results in a plain symbol\n\t\t * value, and duk_to_string() then causes a TypeError.\n\t\t */\n\t\tduk_to_primitive(thr, idx, DUK_HINT_STRING);\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* ToPrimitive() must guarantee */\n\t\tDUK_ASSERT(!duk_is_object(thr, idx));\n\t\treturn duk_to_string(thr, idx);  /* Note: recursive call */\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tvoid *ptr = DUK_TVAL_GET_POINTER(tv);\n\t\tif (ptr != NULL) {\n\t\t\tduk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) ptr);\n\t\t} else {\n\t\t\t/* Represent a null pointer as 'null' to be consistent with\n\t\t\t * the JX format variant.  Native '%p' format for a NULL\n\t\t\t * pointer may be e.g. '(nil)'.\n\t\t\t */\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_LC_NULL);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Should match Function.prototype.toString() */\n\t\tduk_push_lightfunc_tostring(thr, tv);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tduk_push_tval(thr, tv);\n\t\tduk_numconv_stringify(thr,\n\t\t                      10 /*radix*/,\n\t\t                      0 /*precision:shortest*/,\n\t\t                      0 /*force_exponential*/);\n\t\tbreak;\n\t}\n\t}\n\n\tduk_replace(thr, idx);\n\n skip_replace:\n\tDUK_ASSERT(duk_is_string(thr, idx));\n\treturn duk_require_string(thr, idx);\n}\n\nDUK_INTERNAL duk_hstring *duk_to_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_to_string(thr, idx);\n\tret = duk_get_hstring(thr, idx);\n\tDUK_ASSERT(ret != NULL);\n\treturn ret;\n}\n\nDUK_INTERNAL duk_hstring *duk_to_hstring_m1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_hstring(thr, -1);\n}\n\nDUK_INTERNAL duk_hstring *duk_to_hstring_acceptsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_hstring(thr, idx);\n\tif (DUK_UNLIKELY(ret && DUK_HSTRING_HAS_SYMBOL(ret))) {\n\t\treturn ret;\n\t}\n\treturn duk_to_hstring(thr, idx);\n}\n\n/* Convert a plain buffer or any buffer object into a string, using the buffer\n * bytes 1:1 in the internal string representation.  For views the active byte\n * slice (not element slice interpreted as an initializer) is used.  This is\n * necessary in Duktape 2.x because ToString(plainBuffer) no longer creates a\n * string with the same bytes as in the buffer but rather (usually)\n * '[object ArrayBuffer]'.\n */\nDUK_EXTERNAL const char *duk_buffer_to_string(duk_hthread *thr, duk_idx_t idx) {\n\tvoid *ptr_src;\n\tduk_size_t len;\n\tconst char *res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\tptr_src = duk_require_buffer_data(thr, idx, &len);\n\tDUK_ASSERT(ptr_src != NULL || len == 0);\n\n\tres = duk_push_lstring(thr, (const char *) ptr_src, len);\n\tduk_replace(thr, idx);\n\treturn res;\n}\n\nDUK_EXTERNAL void *duk_to_buffer_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, duk_uint_t mode) {\n\tduk_hbuffer *h_buf;\n\tconst duk_uint8_t *src_data;\n\tduk_size_t src_size;\n\tduk_uint8_t *dst_data;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\th_buf = duk_get_hbuffer(thr, idx);\n\tif (h_buf != NULL) {\n\t\t/* Buffer is kept as is, with the fixed/dynamic nature of the\n\t\t * buffer only changed if requested.  An external buffer\n\t\t * is converted into a non-external dynamic buffer in a\n\t\t * duk_to_dynamic_buffer() call.\n\t\t */\n\t\tduk_uint_t tmp;\n\t\tduk_uint8_t *tmp_ptr;\n\n\t\ttmp_ptr = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_buf);\n\t\tsrc_data = (const duk_uint8_t *) tmp_ptr;\n\t\tsrc_size = DUK_HBUFFER_GET_SIZE(h_buf);\n\n\t\ttmp = (DUK_HBUFFER_HAS_DYNAMIC(h_buf) ? DUK_BUF_MODE_DYNAMIC : DUK_BUF_MODE_FIXED);\n\t\tif ((tmp == mode && !DUK_HBUFFER_HAS_EXTERNAL(h_buf)) ||\n\t\t    mode == DUK_BUF_MODE_DONTCARE) {\n\t\t\t/* Note: src_data may be NULL if input is a zero-size\n\t\t\t * dynamic buffer.\n\t\t\t */\n\t\t\tdst_data = tmp_ptr;\n\t\t\tgoto skip_copy;\n\t\t}\n\t} else {\n\t\t/* Non-buffer value is first ToString() coerced, then converted\n\t\t * to a buffer (fixed buffer is used unless a dynamic buffer is\n\t\t * explicitly requested).  Symbols are rejected with a TypeError.\n\t\t * XXX: C API could maybe allow symbol-to-buffer coercion?\n\t\t */\n\t\tsrc_data = (const duk_uint8_t *) duk_to_lstring(thr, idx, &src_size);\n\t}\n\n\tdst_data = (duk_uint8_t *) duk_push_buffer(thr, src_size, (mode == DUK_BUF_MODE_DYNAMIC) /*dynamic*/);\n\t/* dst_data may be NULL if size is zero. */\n\tduk_memcpy_unsafe((void *) dst_data, (const void *) src_data, (size_t) src_size);\n\n\tduk_replace(thr, idx);\n skip_copy:\n\n\tif (out_size) {\n\t\t*out_size = src_size;\n\t}\n\treturn dst_data;\n}\n\nDUK_EXTERNAL void *duk_to_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\tcase DUK_TAG_BOOLEAN:\n\t\tres = NULL;\n\t\tbreak;\n\tcase DUK_TAG_POINTER:\n\t\tres = DUK_TVAL_GET_POINTER(tv);\n\t\tbreak;\n\tcase DUK_TAG_STRING:\n\tcase DUK_TAG_OBJECT:\n\tcase DUK_TAG_BUFFER:\n\t\t/* Heap allocated: return heap pointer which is NOT useful\n\t\t * for the caller, except for debugging.\n\t\t */\n\t\tres = (void *) DUK_TVAL_GET_HEAPHDR(tv);\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\t/* Function pointers do not always cast correctly to void *\n\t\t * (depends on memory and segmentation model for instance),\n\t\t * so they coerce to NULL.\n\t\t */\n\t\tres = NULL;\n\t\tbreak;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tres = NULL;\n\t\tbreak;\n\t}\n\n\tduk_push_pointer(thr, res);\n\tduk_replace(thr, idx);\n\treturn res;\n}\n\nDUK_LOCAL void duk__push_func_from_lightfunc(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags) {\n\tduk_idx_t nargs;\n\tduk_uint_t flags = 0;   /* shared flags for a subset of types */\n\tduk_small_uint_t lf_len;\n\tduk_hnatfunc *nf;\n\n\tnargs = (duk_idx_t) DUK_LFUNC_FLAGS_GET_NARGS(lf_flags);\n\tif (nargs == DUK_LFUNC_NARGS_VARARGS) {\n\t\tnargs = (duk_idx_t) DUK_VARARGS;\n\t}\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\t(void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE);\n\n\tlf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags);\n\tif ((duk_idx_t) lf_len != nargs) {\n\t\t/* Explicit length is only needed if it differs from 'nargs'. */\n\t\tduk_push_int(thr, (duk_int_t) lf_len);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tduk_push_lightfunc_name_raw(thr, func, lf_flags);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n#endif\n\n\tnf = duk_known_hnatfunc(thr, -1);\n\tnf->magic = (duk_int16_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags);\n}\n\nDUK_EXTERNAL void duk_to_object(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_uint_t flags = 0;   /* shared flags for a subset of types */\n\tduk_small_int_t proto = 0;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n#if !defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tcase DUK_TAG_BUFFER:  /* With no bufferobject support, don't object coerce. */\n#endif\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL: {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_OBJECT_COERCIBLE);\n\t\tDUK_WO_NORETURN(return;);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BOOLEAN);\n\t\tproto = DUK_BIDX_BOOLEAN_PROTOTYPE;\n\t\tgoto create_object;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_SYMBOL);\n\t\t\tproto = DUK_BIDX_SYMBOL_PROTOTYPE;\n\t\t} else {\n\t\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t\t        DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ |\n\t\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_STRING);\n\t\t\tproto = DUK_BIDX_STRING_PROTOTYPE;\n\t\t}\n\t\tgoto create_object;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\t/* nop */\n\t\tbreak;\n\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tcase DUK_TAG_BUFFER: {\n\t\t/* A plain buffer object coerces to a full ArrayBuffer which\n\t\t * is not fully transparent behavior (ToObject() should be a\n\t\t * nop for an object).  This behavior matches lightfuncs which\n\t\t * also coerce to an equivalent Function object.  There are\n\t\t * also downsides to defining ToObject(plainBuffer) as a no-op;\n\t\t * for example duk_to_hobject() could result in a NULL pointer.\n\t\t */\n\t\tduk_hbuffer *h_buf;\n\n\t\th_buf = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h_buf != NULL);\n\t\tduk_hbufobj_push_uint8array_from_plain(thr, h_buf);\n\t\tgoto replace_value;\n\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\tcase DUK_TAG_POINTER: {\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER);\n\t\tproto = DUK_BIDX_POINTER_PROTOTYPE;\n\t\tgoto create_object;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Lightfunc coerces to a Function instance with concrete\n\t\t * properties.  Since 'length' is virtual for Duktape/C\n\t\t * functions, don't need to define that.  The result is made\n\t\t * extensible to mimic what happens to strings in object\n\t\t * coercion:\n\t\t *\n\t\t *   > Object.isExtensible(Object('foo'))\n\t\t *   true\n\t\t */\n\t\tduk_small_uint_t lf_flags;\n\t\tduk_c_function func;\n\n\t\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);\n\t\tduk__push_func_from_lightfunc(thr, func, lf_flags);\n\t\tgoto replace_value;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_NUMBER);\n\t\tproto = DUK_BIDX_NUMBER_PROTOTYPE;\n\t\tgoto create_object;\n\t}\n\t}\n\tDUK_ASSERT(duk_is_object(thr, idx));\n\treturn;\n\n create_object:\n\t(void) duk_push_object_helper(thr, flags, proto);\n\n\t/* Note: Boolean prototype's internal value property is not writable,\n\t * but duk_xdef_prop_stridx() disregards the write protection.  Boolean\n\t * instances are immutable.\n\t *\n\t * String and buffer special behaviors are already enabled which is not\n\t * ideal, but a write to the internal value is not affected by them.\n\t */\n\tduk_dup(thr, idx);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\n replace_value:\n\tduk_replace(thr, idx);\n\tDUK_ASSERT(duk_is_object(thr, idx));\n}\n\nDUK_INTERNAL duk_hobject *duk_to_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_to_object(thr, idx);\n\tret = duk_known_hobject(thr, idx);\n\treturn ret;\n}\n\n/*\n *  Type checking\n */\n\nDUK_LOCAL duk_bool_t duk__tag_check(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t tag) {\n\tduk_tval *tv;\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\treturn (DUK_TVAL_GET_TAG(tv) == tag);\n}\n\nDUK_LOCAL duk_bool_t duk__obj_flag_any_default_false(duk_hthread *thr, duk_idx_t idx, duk_uint_t flag_mask) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, idx);\n\tif (obj) {\n\t\treturn (DUK_HEAPHDR_CHECK_FLAG_BITS((duk_heaphdr *) obj, flag_mask) ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_INTERNAL duk_int_t duk_get_type_tval(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_PACKED_TVAL)\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:\n\t\treturn DUK_TYPE_NONE;\n\tcase DUK_TAG_UNDEFINED:\n\t\treturn DUK_TYPE_UNDEFINED;\n\tcase DUK_TAG_NULL:\n\t\treturn DUK_TYPE_NULL;\n\tcase DUK_TAG_BOOLEAN:\n\t\treturn DUK_TYPE_BOOLEAN;\n\tcase DUK_TAG_STRING:\n\t\treturn DUK_TYPE_STRING;\n\tcase DUK_TAG_OBJECT:\n\t\treturn DUK_TYPE_OBJECT;\n\tcase DUK_TAG_BUFFER:\n\t\treturn DUK_TYPE_BUFFER;\n\tcase DUK_TAG_POINTER:\n\t\treturn DUK_TYPE_POINTER;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\treturn DUK_TYPE_LIGHTFUNC;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* Note: number has no explicit tag (in 8-byte representation) */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\treturn DUK_TYPE_NUMBER;\n\t}\n#else  /* DUK_USE_PACKED_TVAL */\n\tDUK_ASSERT(DUK_TVAL_IS_VALID_TAG(tv));\n\tDUK_ASSERT(sizeof(duk__type_from_tag) / sizeof(duk_uint_t) == DUK_TAG_MAX - DUK_TAG_MIN + 1);\n\treturn (duk_int_t) duk__type_from_tag[DUK_TVAL_GET_TAG(tv) - DUK_TAG_MIN];\n#endif  /* DUK_USE_PACKED_TVAL */\n}\n\nDUK_EXTERNAL duk_int_t duk_get_type(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\treturn duk_get_type_tval(tv);\n}\n\n#if defined(DUK_USE_VERBOSE_ERRORS) && defined(DUK_USE_PARANOID_ERRORS)\nDUK_LOCAL const char * const duk__type_names[] = {\n\t\"none\",\n\t\"undefined\",\n\t\"null\",\n\t\"boolean\",\n\t\"number\",\n\t\"string\",\n\t\"object\",\n\t\"buffer\",\n\t\"pointer\",\n\t\"lightfunc\"\n};\n\nDUK_INTERNAL const char *duk_get_type_name(duk_hthread *thr, duk_idx_t idx) {\n\tduk_int_t type_tag;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttype_tag = duk_get_type(thr, idx);\n\tDUK_ASSERT(type_tag >= DUK_TYPE_MIN && type_tag <= DUK_TYPE_MAX);\n\tDUK_ASSERT(DUK_TYPE_MIN == 0 && sizeof(duk__type_names) / sizeof(const char *) == DUK_TYPE_MAX + 1);\n\n\treturn duk__type_names[type_tag];\n}\n#endif  /* DUK_USE_VERBOSE_ERRORS && DUK_USE_PARANOID_ERRORS */\n\nDUK_INTERNAL duk_small_uint_t duk_get_class_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_OBJECT:\n\t\tobj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(obj != NULL);\n\t\treturn DUK_HOBJECT_GET_CLASS_NUMBER(obj);\n\tcase DUK_TAG_BUFFER:\n\t\t/* Buffers behave like Uint8Array objects. */\n\t\treturn DUK_HOBJECT_CLASS_UINT8ARRAY;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\t/* Lightfuncs behave like Function objects. */\n\t\treturn DUK_HOBJECT_CLASS_FUNCTION;\n\tdefault:\n\t\t/* Primitive or UNUSED, no class number. */\n\t\treturn DUK_HOBJECT_CLASS_NONE;\n\t}\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_type(duk_hthread *thr, duk_idx_t idx, duk_int_t type) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_get_type(thr, idx) == type) ? 1 : 0;\n}\n\nDUK_INTERNAL duk_uint_t duk_get_type_mask_tval(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_PACKED_TVAL)\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:\n\t\treturn DUK_TYPE_MASK_NONE;\n\tcase DUK_TAG_UNDEFINED:\n\t\treturn DUK_TYPE_MASK_UNDEFINED;\n\tcase DUK_TAG_NULL:\n\t\treturn DUK_TYPE_MASK_NULL;\n\tcase DUK_TAG_BOOLEAN:\n\t\treturn DUK_TYPE_MASK_BOOLEAN;\n\tcase DUK_TAG_STRING:\n\t\treturn DUK_TYPE_MASK_STRING;\n\tcase DUK_TAG_OBJECT:\n\t\treturn DUK_TYPE_MASK_OBJECT;\n\tcase DUK_TAG_BUFFER:\n\t\treturn DUK_TYPE_MASK_BUFFER;\n\tcase DUK_TAG_POINTER:\n\t\treturn DUK_TYPE_MASK_POINTER;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\treturn DUK_TYPE_MASK_LIGHTFUNC;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* Note: number has no explicit tag (in 8-byte representation) */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\treturn DUK_TYPE_MASK_NUMBER;\n\t}\n#else  /* DUK_USE_PACKED_TVAL */\n\tDUK_ASSERT(DUK_TVAL_IS_VALID_TAG(tv));\n\tDUK_ASSERT(sizeof(duk__type_mask_from_tag) / sizeof(duk_uint_t) == DUK_TAG_MAX - DUK_TAG_MIN + 1);\n\treturn duk__type_mask_from_tag[DUK_TVAL_GET_TAG(tv) - DUK_TAG_MIN];\n#endif  /* DUK_USE_PACKED_TVAL */\n}\n\nDUK_EXTERNAL duk_uint_t duk_get_type_mask(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\treturn duk_get_type_mask_tval(tv);\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_type_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (DUK_LIKELY((duk_get_type_mask(thr, idx) & mask) != 0U)) {\n\t\treturn 1;\n\t}\n\tif (mask & DUK_TYPE_MASK_THROW) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_UNEXPECTED_TYPE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_UNDEFINED);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_null(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_NULL);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_BOOLEAN);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/*\n\t *  Number is special because it doesn't have a specific\n\t *  tag in the 8-byte representation.\n\t */\n\n\t/* XXX: shorter version for unpacked representation? */\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\treturn DUK_TVAL_IS_NUMBER(tv);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_nan(duk_hthread *thr, duk_idx_t idx) {\n\t/* XXX: This will now return false for non-numbers, even though they would\n\t * coerce to NaN (as a general rule).  In particular, duk_get_number()\n\t * returns a NaN for non-numbers, so should this function also return\n\t * true for non-numbers?\n\t */\n\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\t/* XXX: for packed duk_tval an explicit \"is number\" check is unnecessary */\n\tif (!DUK_TVAL_IS_NUMBER(tv)) {\n\t\treturn 0;\n\t}\n\treturn (duk_bool_t) DUK_ISNAN(DUK_TVAL_GET_NUMBER(tv));\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_string(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_STRING);\n}\n\nDUK_INTERNAL duk_bool_t duk_is_string_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_hstring_notsymbol(thr, idx) != NULL;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_object(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_OBJECT);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_BUFFER);\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\treturn 1;\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\nDUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_is_buffer(thr, idx);\n}\n\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_EXTERNAL duk_bool_t duk_is_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_POINTER);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_lightfunc(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_LIGHTFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_symbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\th = duk_get_hstring(thr, idx);\n\t/* Use DUK_LIKELY() here because caller may be more likely to type\n\t * check an expected symbol than not.\n\t */\n\tif (DUK_LIKELY(h != NULL && DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_array(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, idx);\n\tif (obj) {\n\t\treturn (DUK_HOBJECT_GET_CLASS_NUMBER(obj) == DUK_HOBJECT_CLASS_ARRAY ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_function(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn DUK_HOBJECT_HAS_CALLABLE(h) ? 1 : 0;\n\t}\n\tif (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_INTERNAL duk_bool_t duk_is_callable_tval(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_UNREF(thr);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn DUK_HOBJECT_HAS_CALLABLE(h) ? 1 : 0;\n\t}\n\tif (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_constructable(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn DUK_HOBJECT_HAS_CONSTRUCTABLE(h) ? 1 : 0;\n\t}\n\tif (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_c_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__obj_flag_any_default_false(thr,\n\t                                       idx,\n\t                                       DUK_HOBJECT_FLAG_NATFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_ecmascript_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__obj_flag_any_default_false(thr,\n\t                                       idx,\n\t                                       DUK_HOBJECT_FLAG_COMPFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_bound_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__obj_flag_any_default_false(thr,\n\t                                       idx,\n\t                                       DUK_HOBJECT_FLAG_BOUNDFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_thread(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, idx);\n\tif (obj) {\n\t\treturn (DUK_HOBJECT_GET_CLASS_NUMBER(obj) == DUK_HOBJECT_CLASS_THREAD ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_fixed_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HBUFFER_HAS_DYNAMIC(h) ? 0 : 1);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_dynamic_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h) ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_external_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HBUFFER_HAS_DYNAMIC(h) && DUK_HBUFFER_HAS_EXTERNAL(h) ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_errcode_t duk_get_error_code(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hobject(thr, idx);\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (!h) {\n\t\t\treturn DUK_ERR_NONE;\n\t\t}\n\n\t\t/* XXX: something more convenient? */\n\n\t\tif (h == thr->builtins[DUK_BIDX_EVAL_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_EVAL_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_RANGE_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_RANGE_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_REFERENCE_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_REFERENCE_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_SYNTAX_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_SYNTAX_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_TYPE_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_TYPE_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_URI_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_URI_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_ERROR;\n\t\t}\n\n\t\th = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t} while (--sanity > 0);\n\n\treturn DUK_ERR_NONE;\n}\n\n/*\n *  Pushers\n */\n\nDUK_INTERNAL void duk_push_tval(duk_hthread *thr, duk_tval *tv) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_TVAL(tv_slot, tv);\n\tDUK_TVAL_INCREF(thr, tv);  /* no side effects */\n}\n\nDUK_EXTERNAL void duk_push_undefined(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\t/* Because value stack init policy is 'undefined above top',\n\t * we don't need to write, just assert.\n\t */\n\tthr->valstack_top++;\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));\n}\n\nDUK_EXTERNAL void duk_push_null(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NULL(tv_slot);\n}\n\nDUK_EXTERNAL void duk_push_boolean(duk_hthread *thr, duk_bool_t val) {\n\tduk_tval *tv_slot;\n\tduk_small_int_t b;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\tb = (val ? 1 : 0);  /* ensure value is 1 or 0 (not other non-zero) */\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_BOOLEAN(tv_slot, b);\n}\n\nDUK_EXTERNAL void duk_push_true(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_BOOLEAN_TRUE(tv_slot);\n}\n\nDUK_EXTERNAL void duk_push_false(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_BOOLEAN_FALSE(tv_slot);\n}\n\n/* normalize NaN which may not match our canonical internal NaN */\nDUK_EXTERNAL void duk_push_number(duk_hthread *thr, duk_double_t val) {\n\tduk_tval *tv_slot;\n\tduk_double_union du;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\tdu.d = val;\n\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, du.d);\n}\n\nDUK_EXTERNAL void duk_push_int(duk_hthread *thr, duk_int_t val) {\n#if defined(DUK_USE_FASTINT)\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n#if DUK_INT_MAX <= 0x7fffffffL\n\tDUK_TVAL_SET_I32(tv_slot, (duk_int32_t) val);\n#else\n\tif (val >= DUK_FASTINT_MIN && val <= DUK_FASTINT_MAX) {\n\t\tDUK_TVAL_SET_FASTINT(tv_slot, (duk_int64_t) val);\n\t} else {\n\t\tduk_double_t = (duk_double_t) val;\n\t\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n\t}\n#endif\n#else  /* DUK_USE_FASTINT */\n\tduk_tval *tv_slot;\n\tduk_double_t d;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\td = (duk_double_t) val;\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n#endif  /* DUK_USE_FASTINT */\n}\n\nDUK_EXTERNAL void duk_push_uint(duk_hthread *thr, duk_uint_t val) {\n#if defined(DUK_USE_FASTINT)\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n#if DUK_UINT_MAX <= 0xffffffffUL\n\tDUK_TVAL_SET_U32(tv_slot, (duk_uint32_t) val);\n#else\n\tif (val <= DUK_FASTINT_MAX) {  /* val is unsigned so >= 0 */\n\t\t/* XXX: take advantage of val being unsigned, no need to mask */\n\t\tDUK_TVAL_SET_FASTINT(tv_slot, (duk_int64_t) val);\n\t} else {\n\t\tduk_double_t = (duk_double_t) val;\n\t\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n\t}\n#endif\n#else  /* DUK_USE_FASTINT */\n\tduk_tval *tv_slot;\n\tduk_double_t d;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\td = (duk_double_t) val;\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n#endif  /* DUK_USE_FASTINT */\n}\n\nDUK_EXTERNAL void duk_push_nan(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\tduk_double_union du;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\tDUK_DBLUNION_SET_NAN(&du);\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, du.d);\n}\n\nDUK_EXTERNAL const char *duk_push_lstring(duk_hthread *thr, const char *str, duk_size_t len) {\n\tduk_hstring *h;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Check stack before interning (avoid hanging temp). */\n\tDUK__CHECK_SPACE();\n\n\t/* NULL with zero length represents an empty string; NULL with higher\n\t * length is also now treated like an empty string although it is\n\t * a bit dubious.  This is unlike duk_push_string() which pushes a\n\t * 'null' if the input string is a NULL.\n\t */\n\tif (DUK_UNLIKELY(str == NULL)) {\n\t\tlen = 0U;\n\t}\n\n\t/* Check for maximum string length. */\n\tif (DUK_UNLIKELY(len > DUK_HSTRING_MAX_BYTELEN)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_STRING_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\th = duk_heap_strtable_intern_checked(thr, (const duk_uint8_t *) str, (duk_uint32_t) len);\n\tDUK_ASSERT(h != NULL);\n\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_STRING(tv_slot, h);\n\tDUK_HSTRING_INCREF(thr, h);  /* no side effects */\n\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_EXTERNAL const char *duk_push_string(duk_hthread *thr, const char *str) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (str) {\n\t\treturn duk_push_lstring(thr, str, DUK_STRLEN(str));\n\t} else {\n\t\tduk_push_null(thr);\n\t\treturn NULL;\n\t}\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_EXTERNAL const char *duk_push_literal_raw(duk_hthread *thr, const char *str, duk_size_t len) {\n\tduk_hstring *h;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(str != NULL);\n\tDUK_ASSERT(str[len] == (char) 0);\n\n\t/* Check for maximum string length. */\n\tif (DUK_UNLIKELY(len > DUK_HSTRING_MAX_BYTELEN)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_STRING_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\th = duk_heap_strtable_intern_literal_checked(thr, (const duk_uint8_t *) str, (duk_uint32_t) len);\n\tDUK_ASSERT(h != NULL);\n\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_STRING(tv_slot, h);\n\tDUK_HSTRING_INCREF(thr, h);  /* no side effects */\n\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n#else  /* DUK_USE_LITCACHE_SIZE */\nDUK_EXTERNAL const char *duk_push_literal_raw(duk_hthread *thr, const char *str, duk_size_t len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(str != NULL);\n\tDUK_ASSERT(str[len] == (char) 0);\n\n\treturn duk_push_lstring(thr, str, len);\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n#endif  /* !DUK_USE_PREFER_SIZE */\n\nDUK_EXTERNAL void duk_push_pointer(duk_hthread *thr, void *val) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_POINTER(tv_slot, val);\n}\n\nDUK_INTERNAL duk_hstring *duk_push_uint_to_hstring(duk_hthread *thr, duk_uint_t i) {\n\tduk_hstring *h_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: this could be a direct DUK_SPRINTF to a buffer followed by duk_push_string() */\n\tduk_push_uint(thr, (duk_uint_t) i);\n\th_tmp = duk_to_hstring_m1(thr);\n\tDUK_ASSERT(h_tmp != NULL);\n\treturn h_tmp;\n}\n\nDUK_LOCAL void duk__push_this_helper(duk_hthread *thr, duk_small_uint_t check_object_coercible) {\n\tduk_tval *tv_slot;\n\n\tDUK__CHECK_SPACE();\n\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* because of valstack init policy */\n\ttv_slot = thr->valstack_top++;\n\n\tif (DUK_UNLIKELY(thr->callstack_curr == NULL)) {\n\t\tif (check_object_coercible) {\n\t\t\tgoto type_error;\n\t\t}\n\t\t/* 'undefined' already on stack top */\n\t} else {\n\t\tduk_tval *tv;\n\n\t\t/* 'this' binding is just before current activation's bottom */\n\t\tDUK_ASSERT(thr->valstack_bottom > thr->valstack);\n\t\ttv = thr->valstack_bottom - 1;\n\t\tif (check_object_coercible &&\n\t\t    (DUK_TVAL_IS_UNDEFINED(tv) || DUK_TVAL_IS_NULL(tv))) {\n\t\t\t/* XXX: better macro for DUK_TVAL_IS_UNDEFINED_OR_NULL(tv) */\n\t\t\tgoto type_error;\n\t\t}\n\n\t\tDUK_TVAL_SET_TVAL(tv_slot, tv);\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t}\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_OBJECT_COERCIBLE);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_push_this(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 0 /*check_object_coercible*/);\n}\n\nDUK_INTERNAL void duk_push_this_check_object_coercible(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 1 /*check_object_coercible*/);\n}\n\nDUK_INTERNAL duk_hobject *duk_push_this_coercible_to_object(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 1 /*check_object_coercible*/);\n\th = duk_to_hobject(thr, -1);\n\tDUK_ASSERT(h != NULL);\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_push_this_coercible_to_string(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 1 /*check_object_coercible*/);\n\treturn duk_to_hstring_m1(thr);  /* This will reject all Symbol values; accepts Symbol objects. */\n}\n\nDUK_INTERNAL duk_tval *duk_get_borrowed_this_tval(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->callstack_top > 0);  /* caller required to know */\n\tDUK_ASSERT(thr->callstack_curr != NULL);  /* caller required to know */\n\tDUK_ASSERT(thr->valstack_bottom > thr->valstack);  /* consequence of above */\n\tDUK_ASSERT(thr->valstack_bottom - 1 >= thr->valstack);  /* 'this' binding exists */\n\n\treturn thr->valstack_bottom - 1;\n}\n\nDUK_EXTERNAL void duk_push_new_target(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* https://www.ecma-international.org/ecma-262/6.0/#sec-meta-properties-runtime-semantics-evaluation\n\t * https://www.ecma-international.org/ecma-262/6.0/#sec-getnewtarget\n\t *\n\t * No newTarget support now, so as a first approximation\n\t * use the resolved (non-bound) target function.\n\t *\n\t * Check CONSTRUCT flag from current function, or if running\n\t * direct eval, from a non-direct-eval parent (with possibly\n\t * more than one nested direct eval).  An alternative to this\n\t * would be to store [[NewTarget]] as a hidden symbol of the\n\t * lexical scope, and then just look up that variable.\n\t *\n\t * Calls from the application will either be for an empty\n\t * call stack, or a Duktape/C function as the top activation.\n\t */\n\n\tact = thr->callstack_curr;\n\tfor (;;) {\n\t\tif (act == NULL) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (act->flags & DUK_ACT_FLAG_CONSTRUCT) {\n\t\t\tduk_push_tval(thr, &act->tv_func);\n\t\t\treturn;\n\t\t} else if (act->flags & DUK_ACT_FLAG_DIRECT_EVAL) {\n\t\t\tact = act->parent;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tduk_push_undefined(thr);\n}\n\nDUK_EXTERNAL void duk_push_current_function(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\tduk_push_tval(thr, &act->tv_func);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n}\n\nDUK_EXTERNAL void duk_push_current_thread(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (thr->heap->curr_thread) {\n\t\tduk_push_hobject(thr, (duk_hobject *) thr->heap->curr_thread);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n}\n\nDUK_EXTERNAL void duk_push_global_object(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_hobject_bidx(thr, DUK_BIDX_GLOBAL);\n}\n\n/* XXX: size optimize */\nDUK_LOCAL void duk__push_stash(duk_hthread *thr) {\n\tif (!duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"creating heap/global/thread stash on first use\"));\n\t\tduk_pop_unsafe(thr);\n\t\tduk_push_bare_object(thr);\n\t\tduk_dup_top(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_C);  /* [ ... parent stash stash ] -> [ ... parent stash ] */\n\t}\n\tduk_remove_m2(thr);\n}\n\nDUK_EXTERNAL void duk_push_heap_stash(duk_hthread *thr) {\n\tduk_heap *heap;\n\tDUK_ASSERT_API_ENTRY(thr);\n\theap = thr->heap;\n\tDUK_ASSERT(heap->heap_object != NULL);\n\tduk_push_hobject(thr, heap->heap_object);\n\tduk__push_stash(thr);\n}\n\nDUK_EXTERNAL void duk_push_global_stash(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_push_global_object(thr);\n\tduk__push_stash(thr);\n}\n\nDUK_EXTERNAL void duk_push_thread_stash(duk_hthread *thr, duk_hthread *target_thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tif (DUK_UNLIKELY(target_thr == NULL)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tduk_push_hobject(thr, (duk_hobject *) target_thr);\n\tduk__push_stash(thr);\n}\n\n/* XXX: duk_ssize_t would be useful here */\nDUK_LOCAL duk_int_t duk__try_push_vsprintf(duk_hthread *thr, void *buf, duk_size_t sz, const char *fmt, va_list ap) {\n\tduk_int_t len;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(thr);\n\n\t/* NUL terminator handling doesn't matter here */\n\tlen = DUK_VSNPRINTF((char *) buf, sz, fmt, ap);\n\tif (len < (duk_int_t) sz) {\n\t\t/* Return value of 'sz' or more indicates output was (potentially)\n\t\t * truncated.\n\t\t */\n\t\treturn (duk_int_t) len;\n\t}\n\treturn -1;\n}\n\nDUK_EXTERNAL const char *duk_push_vsprintf(duk_hthread *thr, const char *fmt, va_list ap) {\n\tduk_uint8_t stack_buf[DUK_PUSH_SPRINTF_INITIAL_SIZE];\n\tduk_size_t sz = DUK_PUSH_SPRINTF_INITIAL_SIZE;\n\tduk_bool_t pushed_buf = 0;\n\tvoid *buf;\n\tduk_int_t len;  /* XXX: duk_ssize_t */\n\tconst char *res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* special handling of fmt==NULL */\n\tif (!fmt) {\n\t\tduk_hstring *h_str;\n\t\tduk_push_hstring_empty(thr);\n\t\th_str = duk_known_hstring(thr, -1);\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h_str);\n\t}\n\n\t/* initial estimate based on format string */\n\tsz = DUK_STRLEN(fmt) + 16;  /* format plus something to avoid just missing */\n\tif (sz < DUK_PUSH_SPRINTF_INITIAL_SIZE) {\n\t\tsz = DUK_PUSH_SPRINTF_INITIAL_SIZE;\n\t}\n\tDUK_ASSERT(sz > 0);\n\n\t/* Try to make do with a stack buffer to avoid allocating a temporary buffer.\n\t * This works 99% of the time which is quite nice.\n\t */\n\tfor (;;) {\n\t\tva_list ap_copy;  /* copied so that 'ap' can be reused */\n\n\t\tif (sz <= sizeof(stack_buf)) {\n\t\t\tbuf = stack_buf;\n\t\t} else if (!pushed_buf) {\n\t\t\tpushed_buf = 1;\n\t\t\tbuf = duk_push_dynamic_buffer(thr, sz);\n\t\t} else {\n\t\t\tbuf = duk_resize_buffer(thr, -1, sz);\n\t\t}\n\t\tDUK_ASSERT(buf != NULL);\n\n\t\tDUK_VA_COPY(ap_copy, ap);\n\t\tlen = duk__try_push_vsprintf(thr, buf, sz, fmt, ap_copy);\n\t\tva_end(ap_copy);\n\t\tif (len >= 0) {\n\t\t\tbreak;\n\t\t}\n\n\t\t/* failed, resize and try again */\n\t\tsz = sz * 2;\n\t\tif (DUK_UNLIKELY(sz >= DUK_PUSH_SPRINTF_SANITY_LIMIT)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t}\n\n\t/* Cannot use duk_buffer_to_string() on the buffer because it is\n\t * usually larger than 'len'; 'buf' is also usually a stack buffer.\n\t */\n\tres = duk_push_lstring(thr, (const char *) buf, (duk_size_t) len);  /* [ buf? res ] */\n\tif (pushed_buf) {\n\t\tduk_remove_m2(thr);\n\t}\n\treturn res;\n}\n\nDUK_EXTERNAL const char *duk_push_sprintf(duk_hthread *thr, const char *fmt, ...) {\n\tva_list ap;\n\tconst char *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* allow fmt==NULL */\n\tva_start(ap, fmt);\n\tret = duk_push_vsprintf(thr, fmt, ap);\n\tva_end(ap);\n\n\treturn ret;\n}\n\nDUK_INTERNAL duk_hobject *duk_push_object_helper(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx) {\n\tduk_tval *tv_slot;\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(prototype_bidx == -1 ||\n\t           (prototype_bidx >= 0 && prototype_bidx < DUK_NUM_BUILTINS));\n\n\tDUK__CHECK_SPACE();\n\n\th = duk_hobject_alloc(thr, hobject_flags_and_class);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"created object with flags: 0x%08lx\", (unsigned long) h->hdr.h_flags));\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, h);\n\tDUK_HOBJECT_INCREF(thr, h);  /* no side effects */\n\tthr->valstack_top++;\n\n\t/* object is now reachable */\n\n\tif (prototype_bidx >= 0) {\n\t\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, h, thr->builtins[prototype_bidx]);\n\t} else {\n\t\tDUK_ASSERT(prototype_bidx == -1);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h) == NULL);\n\t}\n\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_push_object_helper_proto(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_hobject *proto) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_push_object_helper(thr, hobject_flags_and_class, -1);\n\tDUK_ASSERT(h != NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, h, proto);\n\treturn h;\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_object(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              DUK_BIDX_OBJECT_PROTOTYPE);\n\treturn duk_get_top_index_unsafe(thr);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_array(duk_hthread *thr) {\n\tduk_uint_t flags;\n\tduk_harray *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_ARRAY_PART |\n\t        DUK_HOBJECT_FLAG_EXOTIC_ARRAY |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAY);\n\n\tobj = duk_harray_alloc(thr, flags);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[DUK_BIDX_ARRAY_PROTOTYPE]);\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);  /* XXX: could preallocate with refcount = 1 */\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\tDUK_ASSERT(obj->length == 0);  /* Array .length starts at zero. */\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_bare_array(duk_hthread *thr) {\n\tduk_uint_t flags;\n\tduk_harray *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_ARRAY_PART |\n\t        DUK_HOBJECT_FLAG_EXOTIC_ARRAY |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAY);\n\n\tobj = duk_harray_alloc(thr, flags);\n\tDUK_ASSERT(obj != NULL);\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);  /* XXX: could preallocate with refcount = 1 */\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\tDUK_ASSERT(obj->length == 0);  /* Array .length starts at zero. */\n\treturn ret;\n}\n\nDUK_INTERNAL duk_harray *duk_push_harray(duk_hthread *thr) {\n\t/* XXX: API call could do this directly, cast to void in API macro. */\n\tduk_harray *a;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_push_array(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(thr->valstack_top - 1));\n\ta = (duk_harray *) DUK_TVAL_GET_OBJECT(thr->valstack_top - 1);\n\tDUK_ASSERT(a != NULL);\n\treturn a;\n}\n\n/* Push a duk_harray with preallocated size (.length also set to match size).\n * Caller may then populate array part of the duk_harray directly.\n */\nDUK_INTERNAL duk_harray *duk_push_harray_with_size(duk_hthread *thr, duk_uint32_t size) {\n\tduk_harray *a;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ta = duk_push_harray(thr);\n\n\tduk_hobject_realloc_props(thr,\n\t                          (duk_hobject *) a,\n\t                          0,\n\t                          size,\n\t                          0,\n\t                          0);\n\ta->length = size;\n\treturn a;\n}\n\nDUK_INTERNAL duk_tval *duk_push_harray_with_size_outptr(duk_hthread *thr, duk_uint32_t size) {\n\tduk_harray *a;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ta = duk_push_harray_with_size(thr, size);\n\tDUK_ASSERT(a != NULL);\n\treturn DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_thread_raw(duk_hthread *thr, duk_uint_t flags) {\n\tduk_hthread *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\tobj = duk_hthread_alloc(thr,\n\t                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_THREAD));\n\tDUK_ASSERT(obj != NULL);\n\tobj->state = DUK_HTHREAD_STATE_INACTIVE;\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* Nothing to initialize, strs[] is in ROM. */\n#else\n#if defined(DUK_USE_HEAPPTR16)\n\tobj->strs16 = thr->strs16;\n#else\n\tobj->strs = thr->strs;\n#endif\n#endif\n\tDUK_DDD(DUK_DDDPRINT(\"created thread object with flags: 0x%08lx\", (unsigned long) obj->obj.hdr.h_flags));\n\n\t/* make the new thread reachable */\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HTHREAD_INCREF(thr, obj);\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\t/* important to do this *after* pushing, to make the thread reachable for gc */\n\tif (DUK_UNLIKELY(!duk_hthread_init_stacks(thr->heap, obj))) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* initialize built-ins - either by copying or creating new ones */\n\tif (flags & DUK_THREAD_NEW_GLOBAL_ENV) {\n\t\tduk_hthread_create_builtin_objects(obj);\n\t} else {\n\t\tduk_hthread_copy_builtin_objects(thr, obj);\n\t}\n\n\t/* default prototype */\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, obj->builtins[DUK_BIDX_THREAD_PROTOTYPE]);\n\n\t/* Initial stack size satisfies the stack slack constraints so there\n\t * is no need to require stack here.\n\t */\n\tDUK_ASSERT(DUK_VALSTACK_INITIAL_SIZE >=\n\t           DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\n\treturn ret;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_push_hcompfunc(duk_hthread *thr) {\n\tduk_hcompfunc *obj;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\t/* Template functions are not strictly constructable (they don't\n\t * have a \"prototype\" property for instance), so leave the\n\t * DUK_HOBJECT_FLAG_CONSRUCTABLE flag cleared here.\n\t */\n\n\tobj = duk_hcompfunc_alloc(thr,\n\t                          DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                          DUK_HOBJECT_FLAG_CALLABLE |\n\t                          DUK_HOBJECT_FLAG_COMPFUNC |\n\t                          DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION));\n\tif (DUK_UNLIKELY(obj == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"created compiled function object with flags: 0x%08lx\", (unsigned long) obj->obj.hdr.h_flags));\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\tthr->valstack_top++;\n\n\t/* default prototype */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) obj) == NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\n\treturn obj;\n}\n\nDUK_INTERNAL duk_hboundfunc *duk_push_hboundfunc(duk_hthread *thr) {\n\tduk_hboundfunc *obj;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\tobj = duk_hboundfunc_alloc(thr->heap,\n\t                           DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                           DUK_HOBJECT_FLAG_BOUNDFUNC |\n\t                           DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t                           DUK_HOBJECT_FLAG_CALLABLE |\n\t                           DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION));\n\tif (!obj) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\n\t/* Prototype is left as NULL because the caller always sets it (and\n\t * it depends on the target function).\n\t */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) obj) == NULL);\n\n\treturn obj;\n}\n\nDUK_LOCAL duk_idx_t duk__push_c_function_raw(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_uint_t flags, duk_small_uint_t proto_bidx) {\n\tduk_hnatfunc *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\tduk_int16_t func_nargs;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tDUK__CHECK_SPACE();\n\n\tif (DUK_UNLIKELY(func == NULL)) {\n\t\tgoto api_error;\n\t}\n\tif (nargs >= 0 && nargs < DUK_HNATFUNC_NARGS_MAX) {\n\t\tfunc_nargs = (duk_int16_t) nargs;\n\t} else if (nargs == DUK_VARARGS) {\n\t\tfunc_nargs = DUK_HNATFUNC_NARGS_VARARGS;\n\t} else {\n\t\tgoto api_error;\n\t}\n\n\tobj = duk_hnatfunc_alloc(thr, flags);\n\tDUK_ASSERT(obj != NULL);\n\n\tobj->func = func;\n\tobj->nargs = func_nargs;\n\n\tDUK_DDD(DUK_DDDPRINT(\"created native function object with flags: 0x%08lx, nargs=%ld\",\n\t                     (unsigned long) obj->obj.hdr.h_flags, (long) obj->nargs));\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\tDUK_ASSERT_BIDX_VALID(proto_bidx);\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[proto_bidx]);\n\treturn ret;\n\n api_error:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_c_function(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\n\t/* Default prototype is a Duktape specific %NativeFunctionPrototype%\n\t * which provides .length and .name getters.\n\t */\n\treturn duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE);\n}\n\nDUK_INTERNAL void duk_push_c_function_builtin(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\n\t/* Must use Function.prototype for standard built-in functions. */\n\t(void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_FUNCTION_PROTOTYPE);\n}\n\nDUK_INTERNAL void duk_push_c_function_builtin_noconstruct(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\n\t/* Must use Function.prototype for standard built-in functions. */\n\t(void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_FUNCTION_PROTOTYPE);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_c_lightfunc(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_idx_t length, duk_int_t magic) {\n\tduk_small_uint_t lf_flags;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\tif (nargs >= DUK_LFUNC_NARGS_MIN && nargs <= DUK_LFUNC_NARGS_MAX) {\n\t\t/* as is */\n\t} else if (nargs == DUK_VARARGS) {\n\t\tnargs = DUK_LFUNC_NARGS_VARARGS;\n\t} else {\n\t\tgoto api_error;\n\t}\n\tif (DUK_UNLIKELY(!(length >= DUK_LFUNC_LENGTH_MIN && length <= DUK_LFUNC_LENGTH_MAX))) {\n\t\tgoto api_error;\n\t}\n\tif (DUK_UNLIKELY(!(magic >= DUK_LFUNC_MAGIC_MIN && magic <= DUK_LFUNC_MAGIC_MAX))) {\n\t\tgoto api_error;\n\t}\n\n\tlf_flags = DUK_LFUNC_FLAGS_PACK((duk_small_int_t) magic, (duk_small_uint_t) length, (duk_small_uint_t) nargs);\n\ttv_slot = thr->valstack_top++;\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_slot));\n\tDUK_TVAL_SET_LIGHTFUNC(tv_slot, func, lf_flags);\n\tDUK_ASSERT(tv_slot >= thr->valstack_bottom);\n\treturn (duk_idx_t) (tv_slot - thr->valstack_bottom);\n\n api_error:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_hbufobj *duk_push_bufobj_raw(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx) {\n\tduk_hbufobj *obj;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(prototype_bidx >= 0);\n\n\tDUK__CHECK_SPACE();\n\n\tobj = duk_hbufobj_alloc(thr, hobject_flags_and_class);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[prototype_bidx]);\n\tDUK_HBUFOBJ_ASSERT_VALID(obj);\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\tthr->valstack_top++;\n\n\treturn obj;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* XXX: There's quite a bit of overlap with buffer creation handling in\n * duk_bi_buffer.c.  Look for overlap and refactor.\n */\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK__PACK_ARGS(classnum,protobidx,elemtype,elemshift,istypedarray) \\\n\t(((classnum) << 24) | ((protobidx) << 16) | ((elemtype) << 8) | ((elemshift) << 4) | (istypedarray))\n\nstatic const duk_uint32_t duk__bufobj_flags_lookup[] = {\n\t/* Node.js Buffers are Uint8Array instances which inherit from Buffer.prototype. */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_ARRAYBUFFER,       DUK_BIDX_ARRAYBUFFER_PROTOTYPE,       DUK_HBUFOBJ_ELEM_UINT8,        0, 0),  /* DUK_BUFOBJ_ARRAYBUFFER */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8ARRAY,        DUK_BIDX_NODEJS_BUFFER_PROTOTYPE,     DUK_HBUFOBJ_ELEM_UINT8,        0, 1),  /* DUK_BUFOBJ_NODEJS_BUFFER */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_DATAVIEW,          DUK_BIDX_DATAVIEW_PROTOTYPE,          DUK_HBUFOBJ_ELEM_UINT8,        0, 0),  /* DUK_BUFOBJ_DATAVIEW */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT8ARRAY,         DUK_BIDX_INT8ARRAY_PROTOTYPE,         DUK_HBUFOBJ_ELEM_INT8,         0, 1),  /* DUK_BUFOBJ_INT8ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8ARRAY,        DUK_BIDX_UINT8ARRAY_PROTOTYPE,        DUK_HBUFOBJ_ELEM_UINT8,        0, 1),  /* DUK_BUFOBJ_UINT8ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY, DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE, DUK_HBUFOBJ_ELEM_UINT8CLAMPED, 0, 1),  /* DUK_BUFOBJ_UINT8CLAMPEDARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT16ARRAY,        DUK_BIDX_INT16ARRAY_PROTOTYPE,        DUK_HBUFOBJ_ELEM_INT16,        1, 1),  /* DUK_BUFOBJ_INT16ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT16ARRAY,       DUK_BIDX_UINT16ARRAY_PROTOTYPE,       DUK_HBUFOBJ_ELEM_UINT16,       1, 1),  /* DUK_BUFOBJ_UINT16ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT32ARRAY,        DUK_BIDX_INT32ARRAY_PROTOTYPE,        DUK_HBUFOBJ_ELEM_INT32,        2, 1),  /* DUK_BUFOBJ_INT32ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT32ARRAY,       DUK_BIDX_UINT32ARRAY_PROTOTYPE,       DUK_HBUFOBJ_ELEM_UINT32,       2, 1),  /* DUK_BUFOBJ_UINT32ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_FLOAT32ARRAY,      DUK_BIDX_FLOAT32ARRAY_PROTOTYPE,      DUK_HBUFOBJ_ELEM_FLOAT32,      2, 1),  /* DUK_BUFOBJ_FLOAT32ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_FLOAT64ARRAY,      DUK_BIDX_FLOAT64ARRAY_PROTOTYPE,      DUK_HBUFOBJ_ELEM_FLOAT64,      3, 1)   /* DUK_BUFOBJ_FLOAT64ARRAY */\n};\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags) {\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_hobject *h_arraybuf;\n\tduk_uint32_t tmp;\n\tduk_uint_t classnum;\n\tduk_uint_t protobidx;\n\tduk_uint_t lookupidx;\n\tduk_uint_t uint_offset, uint_length, uint_added;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* The underlying types for offset/length in duk_hbufobj is\n\t * duk_uint_t; make sure argument values fit.\n\t */\n\tuint_offset = (duk_uint_t) byte_offset;\n\tuint_length = (duk_uint_t) byte_length;\n\tif (sizeof(duk_size_t) != sizeof(duk_uint_t)) {\n\t\tif (DUK_UNLIKELY((duk_size_t) uint_offset != byte_offset || (duk_size_t) uint_length != byte_length)) {\n\t\t\tgoto range_error;\n\t\t}\n\t}\n\n\tDUK_ASSERT_DISABLE(flags >= 0);  /* flags is unsigned */\n\tlookupidx = flags;\n\tif (DUK_UNLIKELY(lookupidx >= sizeof(duk__bufobj_flags_lookup) / sizeof(duk_uint32_t))) {\n\t\tgoto arg_error;\n\t}\n\ttmp = duk__bufobj_flags_lookup[lookupidx];\n\tclassnum = tmp >> 24;\n\tprotobidx = (tmp >> 16) & 0xff;\n\n\th_arraybuf = duk_get_hobject(thr, idx_buffer);\n\tif (h_arraybuf != NULL &&  /* argument is an object */\n\t    flags != DUK_BUFOBJ_ARRAYBUFFER &&  /* creating a view */\n\t    DUK_HOBJECT_GET_CLASS_NUMBER(h_arraybuf) == DUK_HOBJECT_CLASS_ARRAYBUFFER  /* argument is ArrayBuffer */) {\n\t\tduk_uint_t tmp_offset;\n\n\t\tDUK_HBUFOBJ_ASSERT_VALID((duk_hbufobj *) h_arraybuf);\n\t\th_val = ((duk_hbufobj *) h_arraybuf)->buf;\n\t\tif (DUK_UNLIKELY(h_val == NULL)) {\n\t\t\tgoto arg_error;\n\t\t}\n\n\t\ttmp_offset = uint_offset + ((duk_hbufobj *) h_arraybuf)->offset;\n\t\tif (DUK_UNLIKELY(tmp_offset < uint_offset)) {\n\t\t\tgoto range_error;\n\t\t}\n\t\tuint_offset = tmp_offset;\n\n\t\t/* Note intentional difference to new TypedArray(): we allow\n\t\t * caller to create an uncovered typed array (which is memory\n\t\t * safe); new TypedArray() rejects it.\n\t\t */\n\t} else {\n\t\t/* Handle unexpected object arguments here too, for nice error\n\t\t * messages.\n\t\t */\n\t\th_arraybuf = NULL;\n\t\th_val = duk_require_hbuffer(thr, idx_buffer);\n\t}\n\n\t/* Wrap check for offset+length. */\n\tuint_added = uint_offset + uint_length;\n\tif (DUK_UNLIKELY(uint_added < uint_offset)) {\n\t\tgoto range_error;\n\t}\n\tDUK_ASSERT(uint_added >= uint_offset && uint_added >= uint_length);\n\n\tDUK_ASSERT(h_val != NULL);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(classnum),\n\t                               (duk_small_int_t) protobidx);\n\tDUK_ASSERT(h_bufobj != NULL);\n\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\th_bufobj->buf_prop = h_arraybuf;\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, h_arraybuf);\n\th_bufobj->offset = uint_offset;\n\th_bufobj->length = uint_length;\n\th_bufobj->shift = (tmp >> 4) & 0x0f;\n\th_bufobj->elem_type = (tmp >> 8) & 0xff;\n\th_bufobj->is_typedarray = tmp & 0x0f;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t/* TypedArray views need an automatic ArrayBuffer which must be\n\t * provided as .buffer property of the view.  The ArrayBuffer is\n\t * referenced via duk_hbufobj->buf_prop and an inherited .buffer\n\t * accessor returns it.  The ArrayBuffer is created lazily on first\n\t * access if necessary so we don't need to do anything more here.\n\t */\n\treturn;\n\n range_error:\n\tDUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARGS);\n\tDUK_WO_NORETURN(return;);\n\n arg_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_ARGS);\n\tDUK_WO_NORETURN(return;);\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\nDUK_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx_buffer);\n\tDUK_UNREF(byte_offset);\n\tDUK_UNREF(byte_length);\n\tDUK_UNREF(flags);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_EXTERNAL duk_idx_t duk_push_error_object_va_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap) {\n\tduk_hobject *proto;\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tduk_small_uint_t augment_flags;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_UNREF(filename);\n\tDUK_UNREF(line);\n\n\t/* Error code also packs a tracedata related flag. */\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\taugment_flags = 0;\n\tif (err_code & DUK_ERRCODE_FLAG_NOBLAME_FILELINE) {\n\t\taugment_flags = DUK_AUGMENT_FLAG_NOBLAME_FILELINE;\n\t}\n#endif\n\terr_code = err_code & (~DUK_ERRCODE_FLAG_NOBLAME_FILELINE);\n\n\t/* error gets its 'name' from the prototype */\n\tproto = duk_error_prototype_from_code(thr, err_code);\n\t(void) duk_push_object_helper_proto(thr,\n\t                                    DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                    DUK_HOBJECT_FLAG_FASTREFS |\n\t                                    DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ERROR),\n\t                                    proto);\n\n\t/* ... and its 'message' from an instance property */\n\tif (fmt) {\n\t\tduk_push_vsprintf(thr, fmt, ap);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);\n\t} else {\n\t\t/* If no explicit message given, put error code into message field\n\t\t * (as a number).  This is not fully in keeping with the ECMAScript\n\t\t * error model because messages are supposed to be strings (Error\n\t\t * constructors use ToString() on their argument).  However, it's\n\t\t * probably more useful than having a separate 'code' property.\n\t\t */\n\t\tduk_push_int(thr, err_code);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);\n\t}\n\n\t/* XXX: .code = err_code disabled, not sure if useful */\n\n\t/* Creation time error augmentation */\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\t/* filename may be NULL in which case file/line is not recorded */\n\tduk_err_augment_error_create(thr, thr, filename, line, augment_flags);  /* may throw an error */\n#endif\n\n\treturn duk_get_top_index_unsafe(thr);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_error_object_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...) {\n\tva_list ap;\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tva_start(ap, fmt);\n\tret = duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\n#if !defined(DUK_USE_VARIADIC_MACROS)\nDUK_EXTERNAL duk_idx_t duk_push_error_object_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, ...) {\n\tconst char *filename = duk_api_global_filename;\n\tduk_int_t line = duk_api_global_line;\n\tva_list ap;\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_api_global_filename = NULL;\n\tduk_api_global_line = 0;\n\tva_start(ap, fmt);\n\tret = duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\nDUK_EXTERNAL void *duk_push_buffer_raw(duk_hthread *thr, duk_size_t size, duk_small_uint_t flags) {\n\tduk_tval *tv_slot;\n\tduk_hbuffer *h;\n\tvoid *buf_data;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\t/* Check for maximum buffer length. */\n\tif (DUK_UNLIKELY(size > DUK_HBUFFER_MAX_BYTELEN)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_BUFFER_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\th = duk_hbuffer_alloc(thr->heap, size, flags, &buf_data);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_BUFFER(tv_slot, h);\n\tDUK_HBUFFER_INCREF(thr, h);\n\tthr->valstack_top++;\n\n\treturn (void *) buf_data;\n}\n\nDUK_INTERNAL void *duk_push_fixed_buffer_nozero(duk_hthread *thr, duk_size_t len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_push_buffer_raw(thr, len, DUK_BUF_FLAG_NOZERO);\n}\n\nDUK_INTERNAL void *duk_push_fixed_buffer_zero(duk_hthread *thr, duk_size_t len) {\n\tvoid *ptr;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tptr = duk_push_buffer_raw(thr, len, 0);\n\tDUK_ASSERT(ptr != NULL);\n#if !defined(DUK_USE_ZERO_BUFFER_DATA)\n\t/* ES2015 requires zeroing even when DUK_USE_ZERO_BUFFER_DATA\n\t * is not set.\n\t */\n\tduk_memzero((void *) ptr, (size_t) len);\n#endif\n\treturn ptr;\n}\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_EXTERNAL duk_idx_t duk_push_proxy(duk_hthread *thr, duk_uint_t proxy_flags) {\n\tduk_hobject *h_target;\n\tduk_hobject *h_handler;\n\tduk_hproxy *h_proxy;\n\tduk_tval *tv_slot;\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(proxy_flags);\n\n\t/* DUK__CHECK_SPACE() unnecessary because the Proxy is written to\n\t * value stack in-place.\n\t */\n#if 0\n\tDUK__CHECK_SPACE();\n#endif\n\n\t/* Reject a proxy object as the target because it would need\n\t * special handling in property lookups.  (ES2015 has no such\n\t * restriction.)\n\t */\n\th_target = duk_require_hobject_promote_mask(thr, -2, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(h_target != NULL);\n\tif (DUK_HOBJECT_IS_PROXY(h_target)) {\n\t\tgoto fail_args;\n\t}\n\n\t/* Reject a proxy object as the handler because it would cause\n\t * potentially unbounded recursion.  (ES2015 has no such\n\t * restriction.)\n\t *\n\t * There's little practical reason to use a lightfunc or a plain\n\t * buffer as the handler table: one could only provide traps via\n\t * their prototype objects (Function.prototype and ArrayBuffer.prototype).\n\t * Even so, as lightfuncs and plain buffers mimic their object\n\t * counterparts, they're promoted and accepted here.\n\t */\n\th_handler = duk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(h_handler != NULL);\n\tif (DUK_HOBJECT_IS_PROXY(h_handler)) {\n\t\tgoto fail_args;\n\t}\n\n\t/* XXX: Proxy object currently has no prototype, so ToPrimitive()\n\t * coercion fails which is a bit confusing.\n\t */\n\n\t/* CALLABLE and CONSTRUCTABLE flags are copied from the (initial)\n\t * target, see ES2015 Sections 9.5.15 and 9.5.13.\n\t */\n\tflags = DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h_target) &\n\t        (DUK_HOBJECT_FLAG_CALLABLE | DUK_HOBJECT_FLAG_CONSTRUCTABLE);\n\tflags |= DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t         DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ;\n\tif (flags & DUK_HOBJECT_FLAG_CALLABLE) {\n\t\tflags |= DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION) |\n\t\t         DUK_HOBJECT_FLAG_SPECIAL_CALL;\n\t} else {\n\t\tflags |= DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT);\n\t}\n\n\th_proxy = duk_hproxy_alloc(thr, flags);\n\tDUK_ASSERT(h_proxy != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_proxy) == NULL);\n\n\t/* Initialize Proxy target and handler references; avoid INCREF\n\t * by stealing the value stack refcounts via direct value stack\n\t * manipulation.  INCREF is needed for the Proxy itself however.\n\t */\n\tDUK_ASSERT(h_target != NULL);\n\th_proxy->target = h_target;\n\tDUK_ASSERT(h_handler != NULL);\n\th_proxy->handler = h_handler;\n\tDUK_HPROXY_ASSERT_VALID(h_proxy);\n\n\tDUK_ASSERT(duk_get_hobject(thr, -2) == h_target);\n\tDUK_ASSERT(duk_get_hobject(thr, -1) == h_handler);\n\ttv_slot = thr->valstack_top - 2;\n\tDUK_ASSERT(tv_slot >= thr->valstack_bottom);\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) h_proxy);\n\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) h_proxy);\n\ttv_slot++;\n\tDUK_TVAL_SET_UNDEFINED(tv_slot);  /* [ ... target handler ] -> [ ... proxy undefined ] */\n\tthr->valstack_top = tv_slot;      /* -> [ ... proxy ] */\n\n\tDUK_DD(DUK_DDPRINT(\"created Proxy: %!iT\", duk_get_tval(thr, -1)));\n\n\treturn (duk_idx_t) (thr->valstack_top - thr->valstack_bottom - 1);\n\n fail_args:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n#else  /* DUK_USE_ES6_PROXY */\nDUK_EXTERNAL duk_idx_t duk_push_proxy(duk_hthread *thr, duk_uint_t proxy_flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(proxy_flags);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_LOCAL void duk__validate_push_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_heaphdr *h;\n\tduk_heaphdr *curr;\n\tduk_bool_t found = 0;\n\n\th = (duk_heaphdr *) ptr;\n\tif (h == NULL) {\n\t\t/* Allowed. */\n\t\treturn;\n\t}\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\n\t/* One particular problem case is where an object has been\n\t * queued for finalization but the finalizer hasn't yet been\n\t * executed.\n\t *\n\t * Corner case: we're running in a finalizer for object X, and\n\t * user code calls duk_push_heapptr() for X itself.  In this\n\t * case X will be in finalize_list, and we can detect the case\n\t * by seeing that X's FINALIZED flag is set (which is done before\n\t * the finalizer starts executing).\n\t */\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tfor (curr = thr->heap->finalize_list;\n\t     curr != NULL;\n\t     curr = DUK_HEAPHDR_GET_NEXT(thr->heap, curr)) {\n\t\t/* FINALIZABLE is set for all objects on finalize_list\n\t\t * except for an object being finalized right now.  So\n\t\t * can't assert here.\n\t\t */\n#if 0\n\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZABLE(curr));\n#endif\n\n\t\tif (curr == h) {\n\t\t\tif (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) h)) {\n\t\t\t\t/* Object is currently being finalized. */\n\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\tfound = 1;\n\t\t\t} else {\n\t\t\t\t/* Not being finalized but on finalize_list,\n\t\t\t\t * allowed since Duktape 2.1.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\tfound = 1;\n\t\t\t}\n\t\t}\n\t}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* Because refzero_list is now processed to completion inline with\n\t * no side effects, it's always empty here.\n\t */\n\tDUK_ASSERT(thr->heap->refzero_list == NULL);\n#endif\n\n\t/* If not present in finalize_list (or refzero_list), it\n\t * must be either in heap_allocated or the string table.\n\t */\n\tif (DUK_HEAPHDR_IS_STRING(h)) {\n\t\tduk_uint32_t i;\n\t\tduk_hstring *str;\n\t\tduk_heap *heap = thr->heap;\n\n\t\tDUK_ASSERT(found == 0);\n\t\tfor (i = 0; i < heap->st_size; i++) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\t\tstr = DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, heap->strtable16[i]);\n#else\n\t\t\tstr = heap->strtable[i];\n#endif\n\t\t\twhile (str != NULL) {\n\t\t\t\tif (str == (duk_hstring *) h) {\n\t\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\t\tfound = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tstr = str->hdr.h_next;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(found != 0);\n\t} else {\n\t\tfor (curr = thr->heap->heap_allocated;\n\t\t     curr != NULL;\n\t\t     curr = DUK_HEAPHDR_GET_NEXT(thr->heap, curr)) {\n\t\t\tif (curr == h) {\n\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\tfound = 1;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(found != 0);\n\t}\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\nDUK_EXTERNAL duk_idx_t duk_push_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_idx_t ret;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Reviving an object using a heap pointer is a dangerous API\n\t * operation: if the application doesn't guarantee that the\n\t * pointer target is always reachable, difficult-to-diagnose\n\t * problems may ensue.  Try to validate the 'ptr' argument to\n\t * the extent possible.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__validate_push_heapptr(thr, ptr);\n#endif\n\n\tDUK__CHECK_SPACE();\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\ttv = thr->valstack_top++;\n\n\tif (ptr == NULL) {\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\treturn ret;\n\t}\n\n\tDUK_HEAPHDR_ASSERT_VALID((duk_heaphdr *) ptr);\n\n\t/* If the argument is on finalize_list it has technically been\n\t * unreachable before duk_push_heapptr() but it's still safe to\n\t * push it.  Starting from Duktape 2.1 allow application code to\n\t * do so.  There are two main cases:\n\t *\n\t *   (1) The object is on the finalize_list and we're called by\n\t *       the finalizer for the object being finalized.  In this\n\t *       case do nothing: finalize_list handling will deal with\n\t *       the object queueing.  This is detected by the object not\n\t *       having a FINALIZABLE flag despite being on the finalize_list;\n\t *       the flag is cleared for the object being finalized only.\n\t *\n\t *   (2) The object is on the finalize_list but is not currently\n\t *       being processed.  In this case the object can be queued\n\t *       back to heap_allocated with a few flags cleared, in effect\n\t *       cancelling the finalizer.\n\t */\n\tif (DUK_UNLIKELY(DUK_HEAPHDR_HAS_FINALIZABLE((duk_heaphdr *) ptr))) {\n\t\tduk_heaphdr *curr;\n\n\t\tDUK_D(DUK_DPRINT(\"duk_push_heapptr() with a pointer on finalize_list, autorescue\"));\n\n\t\tcurr = (duk_heaphdr *) ptr;\n\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\n\t\t/* Because FINALIZED is set prior to finalizer call, it will\n\t\t * be set for the object being currently finalized, but not\n\t\t * for other objects on finalize_list.\n\t\t */\n\t\tDUK_HEAPHDR_CLEAR_FINALIZED(curr);\n\n\t\t/* Dequeue object from finalize_list and queue it back to\n\t\t * heap_allocated.\n\t\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) >= 1);  /* Preincremented on finalize_list insert. */\n\t\tDUK_HEAPHDR_PREDEC_REFCOUNT(curr);\n#endif\n\t\tDUK_HEAP_REMOVE_FROM_FINALIZE_LIST(thr->heap, curr);\n\t\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(thr->heap, curr);\n\n\t\t/* Continue with the rest. */\n\t}\n\n\tswitch (DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) ptr)) {\n\tcase DUK_HTYPE_STRING:\n\t\tDUK_TVAL_SET_STRING(tv, (duk_hstring *) ptr);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tDUK_TVAL_SET_OBJECT(tv, (duk_hobject *) ptr);\n\t\tbreak;\n\tdefault:\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) ptr) == DUK_HTYPE_BUFFER);\n\t\tDUK_TVAL_SET_BUFFER(tv, (duk_hbuffer *) ptr);\n\t\tbreak;\n\t}\n\n\tDUK_HEAPHDR_INCREF(thr, (duk_heaphdr *) ptr);\n\n\treturn ret;\n}\n\n/* Push object with no prototype, i.e. a \"bare\" object. */\nDUK_EXTERNAL duk_idx_t duk_push_bare_object(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              -1);  /* no prototype */\n\treturn duk_get_top_index_unsafe(thr);\n}\n\nDUK_INTERNAL void duk_push_hstring(duk_hthread *thr, duk_hstring *h) {\n\tduk_tval tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_TVAL_SET_STRING(&tv, h);\n\tduk_push_tval(thr, &tv);\n}\n\nDUK_INTERNAL void duk_push_hstring_stridx(duk_hthread *thr, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n}\n\nDUK_INTERNAL void duk_push_hstring_empty(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, DUK_STRIDX_EMPTY_STRING));\n}\n\nDUK_INTERNAL void duk_push_hobject(duk_hthread *thr, duk_hobject *h) {\n\tduk_tval tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_TVAL_SET_OBJECT(&tv, h);\n\tduk_push_tval(thr, &tv);\n}\n\nDUK_INTERNAL void duk_push_hbuffer(duk_hthread *thr, duk_hbuffer *h) {\n\tduk_tval tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_TVAL_SET_BUFFER(&tv, h);\n\tduk_push_tval(thr, &tv);\n}\n\nDUK_INTERNAL void duk_push_hobject_bidx(duk_hthread *thr, duk_small_int_t builtin_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(builtin_idx >= 0 && builtin_idx < DUK_NUM_BUILTINS);\n\tDUK_ASSERT(thr->builtins[builtin_idx] != NULL);\n\n\tduk_push_hobject(thr, thr->builtins[builtin_idx]);\n}\n\n/*\n *  Poppers\n */\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_n_unsafe_raw(duk_hthread *thr, duk_idx_t count) {\n\tduk_tval *tv;\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_tval *tv_end;\n#endif\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) count);\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\ttv = thr->valstack_top;\n\ttv_end = tv - count;\n\twhile (tv != tv_end) {\n\t\ttv--;\n\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t}\n\tthr->valstack_top = tv;\n\tDUK_REFZERO_CHECK_FAST(thr);\n#else\n\ttv = thr->valstack_top;\n\twhile (count > 0) {\n\t\tcount--;\n\t\ttv--;\n\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t}\n\tthr->valstack_top = tv;\n#endif\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n\nDUK_EXTERNAL void duk_pop_n(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\n\tif (DUK_UNLIKELY((duk_uidx_t) (thr->valstack_top - thr->valstack_bottom) < (duk_uidx_t) count)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(count >= 0);\n\n\tduk__pop_n_unsafe_raw(thr, count);\n}\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, count);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk__pop_n_unsafe_raw(thr, count);\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/* Pop N elements without DECREF (in effect \"stealing\" any actual refcounts). */\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) count);\n\n\ttv = thr->valstack_top;\n\twhile (count > 0) {\n\t\tcount--;\n\t\ttv--;\n\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t}\n\tthr->valstack_top = tv;\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#else  /* DUK_USE_REFERENCE_COUNTING */\nDUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, count);\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/* Popping one element is called so often that when footprint is not an issue,\n * compile a specialized function for it.\n */\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL void duk_pop(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, 1);\n}\nDUK_INTERNAL void duk_pop_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, 1);\n}\nDUK_INTERNAL void duk_pop_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_nodecref_unsafe(thr, 1);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_unsafe_raw(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);\n\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n#else\n\tDUK_TVAL_SET_UNDEFINED(tv);\n#endif\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\nDUK_EXTERNAL void duk_pop(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tif (DUK_UNLIKELY(thr->valstack_top == thr->valstack_bottom)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk__pop_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk__pop_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_nodecref_unsafe(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);\n\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\tDUK_TVAL_SET_UNDEFINED(tv);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_pop_undefined(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_nodecref_unsafe(thr);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_pop_undefined(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);\n\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));\n\tthr->valstack_top--;\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL void duk_pop_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, 2);\n}\nDUK_INTERNAL void duk_pop_2_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, 2);\n}\nDUK_INTERNAL void duk_pop_2_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_nodecref_unsafe(thr, 2);\n}\n#else\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_2_unsafe_raw(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 2);\n\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n#else\n\tDUK_TVAL_SET_UNDEFINED(tv);\n#endif\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n#else\n\tDUK_TVAL_SET_UNDEFINED(tv);\n#endif\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\nDUK_EXTERNAL void duk_pop_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tif (DUK_UNLIKELY(thr->valstack_top - 2 < thr->valstack_bottom)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk__pop_2_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_2_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk__pop_2_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_2_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 2);\n\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 2));\n\tthr->valstack_top -= 2;\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\nDUK_EXTERNAL void duk_pop_3(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, 3);\n}\n\nDUK_INTERNAL void duk_pop_3_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, 3);\n}\n\nDUK_INTERNAL void duk_pop_3_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_nodecref_unsafe(thr, 3);\n}\n\n/*\n *  Pack and unpack (pack value stack entries into an array and vice versa)\n */\n\n/* XXX: pack index range? array index offset? */\n/* XXX: need ability to pack into a bare array? */\nDUK_INTERNAL void duk_pack(duk_hthread *thr, duk_idx_t count) {\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_tval *tv_curr;\n\tduk_tval *tv_limit;\n\tduk_idx_t top;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\ttop = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT(top >= 0);\n\tif (DUK_UNLIKELY((duk_uidx_t) count > (duk_uidx_t) top)) {\n\t\t/* Also handles negative count. */\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(count >= 0);\n\n\t/* Wrapping is controlled by the check above: value stack top can be\n\t * at most DUK_USE_VALSTACK_LIMIT which is low enough so that\n\t * multiplying with sizeof(duk_tval) won't wrap.\n\t */\n\tDUK_ASSERT(count >= 0 && count <= (duk_idx_t) DUK_USE_VALSTACK_LIMIT);\n\tDUK_ASSERT((duk_size_t) count <= DUK_SIZE_MAX / sizeof(duk_tval));  /* no wrapping */\n\n\ttv_dst = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) count);  /* XXX: uninitialized would be OK */\n\tDUK_ASSERT(count == 0 || tv_dst != NULL);\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\t/* Copy value stack values directly to the array part without\n\t * any refcount updates: net refcount changes are zero.\n\t */\n\ttv_src = thr->valstack_top - count - 1;\n\tduk_memcpy_unsafe((void *) tv_dst, (const void *) tv_src, (size_t) count * sizeof(duk_tval));\n\n\t/* Overwrite result array to final value stack location and wipe\n\t * the rest; no refcount operations needed.\n\t */\n\n\ttv_dst = tv_src;  /* when count == 0, same as tv_src (OK) */\n\ttv_src = thr->valstack_top - 1;\n\tDUK_TVAL_SET_TVAL(tv_dst, tv_src);\n\n\t/* XXX: internal helper to wipe a value stack segment? */\n\ttv_curr = tv_dst + 1;\n\ttv_limit = thr->valstack_top;\n\twhile (tv_curr != tv_limit) {\n\t\t/* Wipe policy: keep as 'undefined'. */\n\t\tDUK_TVAL_SET_UNDEFINED(tv_curr);\n\t\ttv_curr++;\n\t}\n\tthr->valstack_top = tv_dst + 1;\n}\n\nDUK_INTERNAL duk_idx_t duk_unpack_array_like(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tif (DUK_LIKELY(DUK_TVAL_IS_OBJECT(tv))) {\n\t\tduk_hobject *h;\n\t\tduk_uint32_t len;\n\t\tduk_uint32_t i;\n\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_UNREF(h);\n\n#if defined(DUK_USE_ARRAY_FASTPATH)  /* close enough */\n\t\tif (DUK_LIKELY(DUK_HOBJECT_IS_ARRAY(h) &&\n\t\t               ((duk_harray *) h)->length <= DUK_HOBJECT_GET_ASIZE(h))) {\n\t\t\tduk_harray *h_arr;\n\t\t\tduk_tval *tv_src;\n\t\t\tduk_tval *tv_dst;\n\n\t\t\th_arr = (duk_harray *) h;\n\t\t\tlen = h_arr->length;\n\t\t\tif (DUK_UNLIKELY(len >= 0x80000000UL)) {\n\t\t\t\tgoto fail_over_2g;\n\t\t\t}\n\t\t\tduk_require_stack(thr, (duk_idx_t) len);\n\n\t\t\t/* The potential allocation in duk_require_stack() may\n\t\t\t * run a finalizer which modifies the argArray so that\n\t\t\t * e.g. becomes sparse.  So, we need to recheck that the\n\t\t\t * array didn't change size and that there's still a\n\t\t\t * valid backing array part.\n\t\t\t *\n\t\t\t * XXX: alternatively, could prevent finalizers for the\n\t\t\t * duration.\n\t\t\t */\n\t\t\tif (DUK_UNLIKELY(len != h_arr->length ||\n\t\t\t                 h_arr->length > DUK_HOBJECT_GET_ASIZE((duk_hobject *) h_arr))) {\n\t\t\t\tgoto skip_fast;\n\t\t\t}\n\n\t\t\t/* Main fast path: arguments array is almost always\n\t\t\t * an actual array (though it might also be an arguments\n\t\t\t * object).\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path for %ld elements\", (long) h_arr->length));\n\t\t\ttv_src = DUK_HOBJECT_A_GET_BASE(thr->heap, h);\n\t\t\ttv_dst = thr->valstack_top;\n\t\t\twhile (len-- > 0) {\n\t\t\t\tDUK_ASSERT(tv_dst < thr->valstack_end);\n\t\t\t\tif (DUK_UNLIKELY(DUK_TVAL_IS_UNUSED(tv_src))) {\n\t\t\t\t\t/* Gaps are very unlikely.  Skip over them,\n\t\t\t\t\t * without an ancestor lookup (technically\n\t\t\t\t\t * not compliant).\n\t\t\t\t\t */\n\t\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_dst));  /* valstack policy */\n\t\t\t\t} else {\n\t\t\t\t\tDUK_TVAL_SET_TVAL(tv_dst, tv_src);\n\t\t\t\t\tDUK_TVAL_INCREF(thr, tv_dst);\n\t\t\t\t}\n\t\t\t\ttv_src++;\n\t\t\t\ttv_dst++;\n\t\t\t}\n\t\t\tDUK_ASSERT(tv_dst <= thr->valstack_end);\n\t\t\tthr->valstack_top = tv_dst;\n\t\t\treturn (duk_idx_t) h_arr->length;\n\t\t}\n\t skip_fast:\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\n\t\t/* Slow path: actual lookups.  The initial 'length' lookup\n\t\t * decides the output length, regardless of side effects that\n\t\t * may resize or change the argArray while we read the\n\t\t * indices.\n\t\t */\n\t\tidx = duk_normalize_index(thr, idx);\n\t\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n\t\tlen = duk_to_uint32(thr, -1);  /* ToUint32() coercion required */\n\t\tif (DUK_UNLIKELY(len >= 0x80000000UL)) {\n\t\t\tgoto fail_over_2g;\n\t\t}\n\t\tduk_pop_unsafe(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"slow path for %ld elements\", (long) len));\n\n\t\tduk_require_stack(thr, (duk_idx_t) len);\n\t\tfor (i = 0; i < len; i++) {\n\t\t\tduk_get_prop_index(thr, idx, (duk_uarridx_t) i);\n\t\t}\n\t\treturn (duk_idx_t) len;\n\t} else if (DUK_TVAL_IS_UNDEFINED(tv) || DUK_TVAL_IS_NULL(tv)) {\n\t\treturn 0;\n\t}\n\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n\n fail_over_2g:\n\tDUK_ERROR_RANGE_INVALID_LENGTH(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/*\n *  Error throwing\n */\n\nDUK_EXTERNAL void duk_throw_raw(duk_hthread *thr) {\n\tduk_tval *tv_val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\n\tif (DUK_UNLIKELY(thr->valstack_top == thr->valstack_bottom)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* Errors are augmented when they are created, not when they are\n\t * thrown or re-thrown.  The current error handler, however, runs\n\t * just before an error is thrown.\n\t */\n\n\t/* Sync so that augmentation sees up-to-date activations, NULL\n\t * thr->ptr_curr_pc so that it's not used if side effects occur\n\t * in augmentation or longjmp handling.\n\t */\n\tduk_hthread_sync_and_null_currpc(thr);\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (API): %!dT (before throw augment)\", (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_err_augment_error_throw(thr);\n#endif\n\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (API): %!dT (after throw augment)\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\ttv_val = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, tv_val);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_err_check_debugger_integration(thr);\n#endif\n\n\t/* thr->heap->lj.jmpbuf_ptr is checked by duk_err_longjmp() so we don't\n\t * need to check that here.  If the value is NULL, a fatal error occurs\n\t * because we can't return.\n\t */\n\n\tduk_err_longjmp(thr);\n\tDUK_UNREACHABLE();\n}\n\nDUK_EXTERNAL void duk_fatal_raw(duk_hthread *thr, const char *err_msg) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->heap->fatal_func != NULL);\n\n\tDUK_D(DUK_DPRINT(\"fatal error occurred: %s\", err_msg ? err_msg : \"NULL\"));\n\n\t/* fatal_func should be noreturn, but noreturn declarations on function\n\t * pointers has a very spotty support apparently so it's not currently\n\t * done.\n\t */\n\tthr->heap->fatal_func(thr->heap->heap_udata, err_msg);\n\n\t/* If the fatal handler returns, all bets are off.  It'd be nice to\n\t * print something here but since we don't want to depend on stdio,\n\t * there's no way to do so portably.\n\t */\n\tDUK_D(DUK_DPRINT(\"fatal error handler returned, all bets are off!\"));\n\tfor (;;) {\n\t\t/* loop forever, don't return (function marked noreturn) */\n\t}\n}\n\nDUK_EXTERNAL void duk_error_va_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\t(void) duk_throw(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_error_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...) {\n\tva_list ap;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tva_start(ap, fmt);\n\tduk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\tva_end(ap);\n\t(void) duk_throw(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n#if !defined(DUK_USE_VARIADIC_MACROS)\nDUK_NORETURN(DUK_LOCAL_DECL void duk__throw_error_from_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, va_list ap));\n\nDUK_LOCAL void duk__throw_error_from_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, va_list ap) {\n\tconst char *filename;\n\tduk_int_t line;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tfilename = duk_api_global_filename;\n\tline = duk_api_global_line;\n\tduk_api_global_filename = NULL;\n\tduk_api_global_line = 0;\n\n\tduk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\t(void) duk_throw(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n#define DUK__ERROR_STASH_SHARED(code) do { \\\n\t\tva_list ap; \\\n\t\tva_start(ap, fmt); \\\n\t\tduk__throw_error_from_stash(thr, (code), fmt, ap); \\\n\t\tva_end(ap); \\\n\t\tDUK_WO_NORETURN(return 0;); \\\n\t} while (0)\n\nDUK_EXTERNAL duk_ret_t duk_error_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(err_code);\n}\nDUK_EXTERNAL duk_ret_t duk_generic_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_eval_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_EVAL_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_range_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_RANGE_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_reference_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_REFERENCE_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_syntax_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_SYNTAX_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_type_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_TYPE_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_uri_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_URI_ERROR);\n}\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n/*\n *  Comparison\n */\n\nDUK_EXTERNAL duk_bool_t duk_equals(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_get_tval(thr, idx1);\n\ttv2 = duk_get_tval(thr, idx2);\n\tif ((tv1 == NULL) || (tv2 == NULL)) {\n\t\treturn 0;\n\t}\n\n\t/* Coercion may be needed, the helper handles that by pushing the\n\t * tagged values to the stack.\n\t */\n\treturn duk_js_equals(thr, tv1, tv2);\n}\n\nDUK_EXTERNAL duk_bool_t duk_strict_equals(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_get_tval(thr, idx1);\n\ttv2 = duk_get_tval(thr, idx2);\n\tif ((tv1 == NULL) || (tv2 == NULL)) {\n\t\treturn 0;\n\t}\n\n\t/* No coercions or other side effects, so safe */\n\treturn duk_js_strict_equals(tv1, tv2);\n}\n\nDUK_EXTERNAL duk_bool_t duk_samevalue(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_get_tval(thr, idx1);\n\ttv2 = duk_get_tval(thr, idx2);\n\tif ((tv1 == NULL) || (tv2 == NULL)) {\n\t\treturn 0;\n\t}\n\n\t/* No coercions or other side effects, so safe */\n\treturn duk_js_samevalue(tv1, tv2);\n}\n\n/*\n *  instanceof\n */\n\nDUK_EXTERNAL duk_bool_t duk_instanceof(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Index validation is strict, which differs from duk_equals().\n\t * The strict behavior mimics how instanceof itself works, e.g.\n\t * it is a TypeError if rval is not a -callable- object.  It would\n\t * be somewhat inconsistent if rval would be allowed to be\n\t * non-existent without a TypeError.\n\t */\n\ttv1 = duk_require_tval(thr, idx1);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, idx2);\n\tDUK_ASSERT(tv2 != NULL);\n\n\treturn duk_js_instanceof(thr, tv1, tv2);\n}\n\n/*\n *  Lightfunc\n */\n\nDUK_INTERNAL void duk_push_lightfunc_name_raw(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags) {\n\t/* Lightfunc name, includes Duktape/C native function pointer, which\n\t * can often be used to locate the function from a symbol table.\n\t * The name also includes the 16-bit duk_tval flags field because it\n\t * includes the magic value.  Because a single native function often\n\t * provides different functionality depending on the magic value, it\n\t * seems reasonably to include it in the name.\n\t *\n\t * On the other hand, a complicated name increases string table\n\t * pressure in low memory environments (but only when function name\n\t * is accessed).\n\t */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_literal(thr, \"light_\");\n\tduk_push_string_funcptr(thr, (duk_uint8_t *) &func, sizeof(func));\n\tduk_push_sprintf(thr, \"_%04x\", (unsigned int) lf_flags);\n\tduk_concat(thr, 3);\n}\n\nDUK_INTERNAL void duk_push_lightfunc_name(duk_hthread *thr, duk_tval *tv) {\n\tduk_c_function func;\n\tduk_small_uint_t lf_flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv));\n\n\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);\n\tduk_push_lightfunc_name_raw(thr, func, lf_flags);\n}\n\nDUK_INTERNAL void duk_push_lightfunc_tostring(duk_hthread *thr, duk_tval *tv) {\n\tduk_c_function func;\n\tduk_small_uint_t lf_flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv));\n\n\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);  /* read before 'tv' potentially invalidated */\n\tduk_push_literal(thr, \"function \");\n\tduk_push_lightfunc_name_raw(thr, func, lf_flags);\n\tduk_push_literal(thr, \"() { [lightfunc code] }\");\n\tduk_concat(thr, 3);\n}\n\n/*\n *  Function pointers\n *\n *  Printing function pointers is non-portable, so we do that by hex printing\n *  bytes from memory.\n */\n\nDUK_INTERNAL void duk_push_string_funcptr(duk_hthread *thr, duk_uint8_t *ptr, duk_size_t sz) {\n\tduk_uint8_t buf[32 * 2];\n\tduk_uint8_t *p, *q;\n\tduk_small_uint_t i;\n\tduk_small_uint_t t;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(sz <= 32);  /* sanity limit for function pointer size */\n\n\tp = buf;\n#if defined(DUK_USE_INTEGER_LE)\n\tq = ptr + sz;\n#else\n\tq = ptr;\n#endif\n\tfor (i = 0; i < sz; i++) {\n#if defined(DUK_USE_INTEGER_LE)\n\t\tt = *(--q);\n#else\n\t\tt = *(q++);\n#endif\n\t\t*p++ = duk_lc_digits[t >> 4];\n\t\t*p++ = duk_lc_digits[t & 0x0f];\n\t}\n\n\tduk_push_lstring(thr, (const char *) buf, sz * 2);\n}\n\n/*\n *  Push readable string summarizing duk_tval.  The operation is side effect\n *  free and will only throw from internal errors (e.g. out of memory).\n *  This is used by e.g. property access code to summarize a key/base safely,\n *  and is not intended to be fast (but small and safe).\n */\n\n/* String limits for summary strings. */\n#define DUK__READABLE_SUMMARY_MAXCHARS 96  /* maximum supported by helper */\n#define DUK__READABLE_STRING_MAXCHARS  32  /* for strings/symbols */\n#define DUK__READABLE_ERRMSG_MAXCHARS  96  /* for error messages */\n\n/* String sanitizer which escapes ASCII control characters and a few other\n * ASCII characters, passes Unicode as is, and replaces invalid UTF-8 with\n * question marks.  No errors are thrown for any input string, except in out\n * of memory situations.\n */\nDUK_LOCAL void duk__push_hstring_readable_unicode(duk_hthread *thr, duk_hstring *h_input, duk_small_uint_t maxchars) {\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_uint8_t buf[DUK_UNICODE_MAX_XUTF8_LENGTH * DUK__READABLE_SUMMARY_MAXCHARS +\n\t                2 /*quotes*/ + 3 /*periods*/];\n\tduk_uint8_t *q;\n\tduk_ucodepoint_t cp;\n\tduk_small_uint_t nchars;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(h_input != NULL);\n\tDUK_ASSERT(maxchars <= DUK__READABLE_SUMMARY_MAXCHARS);\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\tq = buf;\n\n\tnchars = 0;\n\t*q++ = (duk_uint8_t) DUK_ASC_SINGLEQUOTE;\n\tfor (;;) {\n\t\tif (p >= p_end) {\n\t\t\tbreak;\n\t\t}\n\t\tif (nchars == maxchars) {\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_PERIOD;\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_PERIOD;\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_PERIOD;\n\t\t\tbreak;\n\t\t}\n\t\tif (duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp)) {\n\t\t\tif (cp < 0x20 || cp == 0x7f || cp == DUK_ASC_SINGLEQUOTE || cp == DUK_ASC_BACKSLASH) {\n\t\t\t\tDUK_ASSERT(DUK_UNICODE_MAX_XUTF8_LENGTH >= 4);  /* estimate is valid */\n\t\t\t\tDUK_ASSERT((cp >> 4) <= 0x0f);\n\t\t\t\t*q++ = (duk_uint8_t) DUK_ASC_BACKSLASH;\n\t\t\t\t*q++ = (duk_uint8_t) DUK_ASC_LC_X;\n\t\t\t\t*q++ = (duk_uint8_t) duk_lc_digits[cp >> 4];\n\t\t\t\t*q++ = (duk_uint8_t) duk_lc_digits[cp & 0x0f];\n\t\t\t} else {\n\t\t\t\tq += duk_unicode_encode_xutf8(cp, q);\n\t\t\t}\n\t\t} else {\n\t\t\tp++;  /* advance manually */\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_QUESTION;\n\t\t}\n\t\tnchars++;\n\t}\n\t*q++ = (duk_uint8_t) DUK_ASC_SINGLEQUOTE;\n\n\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) (q - buf));\n}\n\nDUK_LOCAL const char *duk__push_string_tval_readable(duk_hthread *thr, duk_tval *tv, duk_bool_t error_aware) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\t/* 'tv' may be NULL */\n\n\tif (tv == NULL) {\n\t\tduk_push_literal(thr, \"none\");\n\t} else {\n\t\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\t\tcase DUK_TAG_STRING: {\n\t\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\t\tif (DUK_HSTRING_HAS_SYMBOL(h)) {\n\t\t\t\t/* XXX: string summary produces question marks\n\t\t\t\t * so this is not very ideal.\n\t\t\t\t */\n\t\t\t\tduk_push_literal(thr, \"[Symbol \");\n\t\t\t\tduk_push_string(thr, duk__get_symbol_type_string(h));\n\t\t\t\tduk_push_literal(thr, \" \");\n\t\t\t\tduk__push_hstring_readable_unicode(thr, h, DUK__READABLE_STRING_MAXCHARS);\n\t\t\t\tduk_push_literal(thr, \"]\");\n\t\t\t\tduk_concat(thr, 5);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tduk__push_hstring_readable_unicode(thr, h, DUK__READABLE_STRING_MAXCHARS);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_OBJECT: {\n\t\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\t\tDUK_ASSERT(h != NULL);\n\n\t\t\tif (error_aware &&\n\t\t\t    duk_hobject_prototype_chain_contains(thr, h, thr->builtins[DUK_BIDX_ERROR_PROTOTYPE], 1 /*ignore_loop*/)) {\n\t\t\t\t/* Get error message in a side effect free way if\n\t\t\t\t * possible; if not, summarize as a generic object.\n\t\t\t\t * Error message currently gets quoted.\n\t\t\t\t */\n\t\t\t\t/* XXX: better internal getprop call; get without side effects\n\t\t\t\t * but traverse inheritance chain.\n\t\t\t\t */\n\t\t\t\tduk_tval *tv_msg;\n\t\t\t\ttv_msg = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, h, DUK_STRIDX_MESSAGE);\n\t\t\t\tif (tv_msg != NULL && DUK_TVAL_IS_STRING(tv_msg)) {\n\t\t\t\t\t/* It's critical to avoid recursion so\n\t\t\t\t\t * only summarize a string .message.\n\t\t\t\t\t */\n\t\t\t\t\tduk__push_hstring_readable_unicode(thr, DUK_TVAL_GET_STRING(tv_msg), DUK__READABLE_ERRMSG_MAXCHARS);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tduk_push_class_string_tval(thr, tv, 1 /*avoid_side_effects*/);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_BUFFER: {\n\t\t\t/* While plain buffers mimic Uint8Arrays, they summarize differently.\n\t\t\t * This is useful so that the summarized string accurately reflects the\n\t\t\t * internal type which may matter for figuring out bugs etc.\n\t\t\t */\n\t\t\t/* XXX: Hex encoded, length limited buffer summary here? */\n\t\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\t\tDUK_ASSERT(h != NULL);\n\t\t\tduk_push_sprintf(thr, \"[buffer:%ld]\", (long) DUK_HBUFFER_GET_SIZE(h));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_POINTER: {\n\t\t\t/* Surround with parentheses like in JX, ensures NULL pointer\n\t\t\t * is distinguishable from null value (\"(null)\" vs \"null\").\n\t\t\t */\n\t\t\tduk_push_tval(thr, tv);\n\t\t\tduk_push_sprintf(thr, \"(%s)\", duk_to_string(thr, -1));\n\t\t\tduk_remove_m2(thr);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tduk_push_tval(thr, tv);\n\t\t\tbreak;\n\t\t}\n\t\t}\n\t}\n\n\treturn duk_to_string(thr, -1);\n}\nDUK_INTERNAL const char *duk_push_string_tval_readable(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__push_string_tval_readable(thr, tv, 0 /*error_aware*/);\n}\n\nDUK_INTERNAL const char *duk_push_string_readable(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_push_string_tval_readable(thr, duk_get_tval(thr, idx));\n}\n\nDUK_INTERNAL const char *duk_push_string_tval_readable_error(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__push_string_tval_readable(thr, tv, 1 /*error_aware*/);\n}\n\nDUK_INTERNAL void duk_push_symbol_descriptive_string(duk_hthread *thr, duk_hstring *h) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint8_t *q;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* .toString() */\n\tduk_push_literal(thr, \"Symbol(\");\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tp_end = p + DUK_HSTRING_GET_BYTELEN(h);\n\tDUK_ASSERT(p[0] == 0xff || (p[0] & 0xc0) == 0x80);\n\tp++;\n\tfor (q = p; q < p_end; q++) {\n\t\tif (*q == 0xffU) {\n\t\t\t/* Terminate either at end-of-string (but NUL MUST\n\t\t\t * be accepted without terminating description) or\n\t\t\t * 0xFF, which is used to mark start of unique trailer\n\t\t\t * (and cannot occur in CESU-8 / extended UTF-8).\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\t}\n\tduk_push_lstring(thr, (const char *) p, (duk_size_t) (q - p));\n\tduk_push_literal(thr, \")\");\n\tduk_concat(thr, 3);\n}\n\n/*\n *  Functions\n */\n\n#if 0  /* not used yet */\nDUK_INTERNAL void duk_push_hnatfunc_name(duk_hthread *thr, duk_hnatfunc *h) {\n\tduk_c_function func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h));\n\n\tduk_push_sprintf(thr, \"native_\");\n\tfunc = h->func;\n\tduk_push_string_funcptr(thr, (duk_uint8_t *) &func, sizeof(func));\n\tduk_push_sprintf(thr, \"_%04x_%04x\",\n\t                 (unsigned int) (duk_uint16_t) h->nargs,\n\t                 (unsigned int) (duk_uint16_t) h->magic);\n\tduk_concat(thr, 3);\n}\n#endif\n\n/*\n *  duk_tval slice copy\n */\n\nDUK_INTERNAL void duk_copy_tvals_incref(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_size_t count) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n\tDUK_ASSERT(count * sizeof(duk_tval) >= count);  /* no wrap */\n\n\tduk_memcpy_unsafe((void *) tv_dst, (const void *) tv_src, count * sizeof(duk_tval));\n\n\ttv = tv_dst;\n\twhile (count-- > 0) {\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\ttv++;\n\t}\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_api_string.c",
    "content": "/*\n *  String manipulation\n */\n\n#include \"duk_internal.h\"\n\nDUK_LOCAL void duk__concat_and_join_helper(duk_hthread *thr, duk_idx_t count_in, duk_bool_t is_join) {\n\tduk_uint_t count;\n\tduk_uint_t i;\n\tduk_size_t idx;\n\tduk_size_t len;\n\tduk_hstring *h;\n\tduk_uint8_t *buf;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tif (DUK_UNLIKELY(count_in <= 0)) {\n\t\tif (count_in < 0) {\n\t\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tDUK_ASSERT(count_in == 0);\n\t\tduk_push_hstring_empty(thr);\n\t\treturn;\n\t}\n\tcount = (duk_uint_t) count_in;\n\n\tif (is_join) {\n\t\tduk_size_t t1, t2, limit;\n\t\th = duk_to_hstring(thr, -((duk_idx_t) count) - 1);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* A bit tricky overflow test, see doc/code-issues.rst. */\n\t\tt1 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);\n\t\tt2 = (duk_size_t) (count - 1);\n\t\tlimit = (duk_size_t) DUK_HSTRING_MAX_BYTELEN;\n\t\tif (DUK_UNLIKELY(t2 != 0 && t1 > limit / t2)) {\n\t\t\t/* Combined size of separators already overflows. */\n\t\t\tgoto error_overflow;\n\t\t}\n\t\tlen = (duk_size_t) (t1 * t2);\n\t} else {\n\t\tlen = (duk_size_t) 0;\n\t}\n\n\tfor (i = count; i >= 1; i--) {\n\t\tduk_size_t new_len;\n\t\th = duk_to_hstring(thr, -((duk_idx_t) i));\n\t\tnew_len = len + (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);\n\n\t\t/* Impose a string maximum length, need to handle overflow\n\t\t * correctly.\n\t\t */\n\t\tif (new_len < len ||  /* wrapped */\n\t\t    new_len > (duk_size_t) DUK_HSTRING_MAX_BYTELEN) {\n\t\t\tgoto error_overflow;\n\t\t}\n\t\tlen = new_len;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"join/concat %lu strings, total length %lu bytes\",\n\t                     (unsigned long) count, (unsigned long) len));\n\n\t/* Use stack allocated buffer to ensure reachability in errors\n\t * (e.g. intern error).\n\t */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len);\n\tDUK_ASSERT(buf != NULL);\n\n\t/* [ ... (sep) str1 str2 ... strN buf ] */\n\n\tidx = 0;\n\tfor (i = count; i >= 1; i--) {\n\t\tif (is_join && i != count) {\n\t\t\th = duk_require_hstring(thr, -((duk_idx_t) count) - 2);  /* extra -1 for buffer */\n\t\t\tduk_memcpy(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\t\t\tidx += DUK_HSTRING_GET_BYTELEN(h);\n\t\t}\n\t\th = duk_require_hstring(thr, -((duk_idx_t) i) - 1);  /* extra -1 for buffer */\n\t\tduk_memcpy(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\t\tidx += DUK_HSTRING_GET_BYTELEN(h);\n\t}\n\n\tDUK_ASSERT(idx == len);\n\n\t/* [ ... (sep) str1 str2 ... strN buf ] */\n\n\t/* Get rid of the strings early to minimize memory use before intern. */\n\n\tif (is_join) {\n\t\tduk_replace(thr, -((duk_idx_t) count) - 2);  /* overwrite sep */\n\t\tduk_pop_n(thr, (duk_idx_t) count);\n\t} else {\n\t\tduk_replace(thr, -((duk_idx_t) count) - 1);  /* overwrite str1 */\n\t\tduk_pop_n(thr, (duk_idx_t) (count - 1));\n\t}\n\n\t/* [ ... buf ] */\n\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if inputs are safe. */\n\n\t/* [ ... res ] */\n\treturn;\n\n error_overflow:\n\tDUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_concat(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__concat_and_join_helper(thr, count, 0 /*is_join*/);\n}\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_concat_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_concat(thr, 2);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_concat_2(duk_hthread *thr) {\n\tduk_hstring *h1;\n\tduk_hstring *h2;\n\tduk_uint8_t *buf;\n\tduk_size_t len1;\n\tduk_size_t len2;\n\tduk_size_t len;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_top(thr) >= 2);  /* Trusted caller. */\n\n\th1 = duk_to_hstring(thr, -2);\n\th2 = duk_to_hstring(thr, -1);\n\tlen1 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1);\n\tlen2 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2);\n\tlen = len1 + len2;\n\tif (DUK_UNLIKELY(len < len1 ||  /* wrapped */\n\t                 len > (duk_size_t) DUK_HSTRING_MAX_BYTELEN)) {\n\t\tgoto error_overflow;\n\t}\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len);\n\tDUK_ASSERT(buf != NULL);\n\n\tduk_memcpy((void *) buf, (const void *) DUK_HSTRING_GET_DATA(h1), (size_t) len1);\n\tduk_memcpy((void *) (buf + len1), (const void *) DUK_HSTRING_GET_DATA(h2), (size_t) len2);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if inputs are safe. */\n\n\t/* [ ... str1 str2 buf ] */\n\n\tduk_replace(thr, -3);\n\tduk_pop_unsafe(thr);\n\treturn;\n\n error_overflow:\n\tDUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\nDUK_EXTERNAL void duk_join(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__concat_and_join_helper(thr, count, 1 /*is_join*/);\n}\n\n/* XXX: could map/decode be unified with duk_unicode_support.c code?\n * Case conversion needs also the character surroundings though.\n */\n\nDUK_EXTERNAL void duk_decode_string(duk_hthread *thr, duk_idx_t idx, duk_decode_char_function callback, void *udata) {\n\tduk_hstring *h_input;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th_input = duk_require_hstring(thr, idx);  /* Accept symbols. */\n\tDUK_ASSERT(h_input != NULL);\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\n\tfor (;;) {\n\t\tif (p >= p_end) {\n\t\t\tbreak;\n\t\t}\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end);\n\t\tcallback(udata, cp);\n\t}\n}\n\nDUK_EXTERNAL void duk_map_string(duk_hthread *thr, duk_idx_t idx, duk_map_char_function callback, void *udata) {\n\tduk_hstring *h_input;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_normalize_index(thr, idx);\n\n\th_input = duk_require_hstring(thr, idx);  /* Accept symbols. */\n\tDUK_ASSERT(h_input != NULL);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input));  /* Reasonable output estimate. */\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\n\tfor (;;) {\n\t\t/* XXX: could write output in chunks with fewer ensure calls,\n\t\t * but relative benefit would be small here.\n\t\t */\n\n\t\tif (p >= p_end) {\n\t\t\tbreak;\n\t\t}\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end);\n\t\tcp = callback(udata, cp);\n\n\t\tDUK_BW_WRITE_ENSURE_XUTF8(thr, bw, cp);\n\t}\n\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe, extended UTF-8 encoded. */\n\tduk_replace(thr, idx);\n}\n\nDUK_EXTERNAL void duk_substring(duk_hthread *thr, duk_idx_t idx, duk_size_t start_offset, duk_size_t end_offset) {\n\tduk_hstring *h;\n\tduk_hstring *res;\n\tduk_size_t start_byte_offset;\n\tduk_size_t end_byte_offset;\n\tduk_size_t charlen;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);  /* Accept symbols. */\n\th = duk_require_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tcharlen = DUK_HSTRING_GET_CHARLEN(h);\n\tif (end_offset >= charlen) {\n\t\tend_offset = charlen;\n\t}\n\tif (start_offset > end_offset) {\n\t\tstart_offset = end_offset;\n\t}\n\n\tDUK_ASSERT_DISABLE(start_offset >= 0);\n\tDUK_ASSERT(start_offset <= end_offset && start_offset <= DUK_HSTRING_GET_CHARLEN(h));\n\tDUK_ASSERT_DISABLE(end_offset >= 0);\n\tDUK_ASSERT(end_offset >= start_offset && end_offset <= DUK_HSTRING_GET_CHARLEN(h));\n\n\t/* Guaranteed by string limits. */\n\tDUK_ASSERT(start_offset <= DUK_UINT32_MAX);\n\tDUK_ASSERT(end_offset <= DUK_UINT32_MAX);\n\n\tstart_byte_offset = (duk_size_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) start_offset);\n\tend_byte_offset = (duk_size_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) end_offset);\n\n\tDUK_ASSERT(end_byte_offset >= start_byte_offset);\n\tDUK_ASSERT(end_byte_offset - start_byte_offset <= DUK_UINT32_MAX);  /* Guaranteed by string limits. */\n\n\t/* No size check is necessary. */\n\tres = duk_heap_strtable_intern_checked(thr,\n\t                                       DUK_HSTRING_GET_DATA(h) + start_byte_offset,\n\t                                       (duk_uint32_t) (end_byte_offset - start_byte_offset));\n\n\tduk_push_hstring(thr, res);\n\tduk_replace(thr, idx);\n}\n\n/* XXX: this is quite clunky.  Add Unicode helpers to scan backwards and\n * forwards with a callback to process codepoints?\n */\nDUK_EXTERNAL void duk_trim(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p, *p_start, *p_end, *p_tmp1, *p_tmp2;  /* pointers for scanning */\n\tconst duk_uint8_t *q_start, *q_end;  /* start (incl) and end (excl) of trimmed part */\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);  /* Accept symbols. */\n\th = duk_require_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tp_start = DUK_HSTRING_GET_DATA(h);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h);\n\n\tp = p_start;\n\twhile (p < p_end) {\n\t\tp_tmp1 = p;\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p_tmp1, p_start, p_end);\n\t\tif (!(duk_unicode_is_whitespace(cp) || duk_unicode_is_line_terminator(cp))) {\n\t\t\tbreak;\n\t\t}\n\t\tp = p_tmp1;\n\t}\n\tq_start = p;\n\tif (p == p_end) {\n\t\t/* Entire string is whitespace. */\n\t\tq_end = p;\n\t\tgoto scan_done;\n\t}\n\n\tp = p_end;\n\twhile (p > p_start) {\n\t\tp_tmp1 = p;\n\t\twhile (p > p_start) {\n\t\t\tp--;\n\t\t\tif (((*p) & 0xc0) != 0x80) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tp_tmp2 = p;\n\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p_tmp2, p_start, p_end);\n\t\tif (!(duk_unicode_is_whitespace(cp) || duk_unicode_is_line_terminator(cp))) {\n\t\t\tp = p_tmp1;\n\t\t\tbreak;\n\t\t}\n\t}\n\tq_end = p;\n\n scan_done:\n\t/* This may happen when forward and backward scanning disagree\n\t * (possible for non-extended-UTF-8 strings).\n\t */\n\tif (q_end < q_start) {\n\t\tq_end = q_start;\n\t}\n\n\tDUK_ASSERT(q_start >= p_start && q_start <= p_end);\n\tDUK_ASSERT(q_end >= p_start && q_end <= p_end);\n\tDUK_ASSERT(q_end >= q_start);\n\n\tDUK_DDD(DUK_DDDPRINT(\"trim: p_start=%p, p_end=%p, q_start=%p, q_end=%p\",\n\t                     (const void *) p_start, (const void *) p_end,\n\t                     (const void *) q_start, (const void *) q_end));\n\n\tif (q_start == p_start && q_end == p_end) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"nothing was trimmed: avoid interning (hashing etc)\"));\n\t\treturn;\n\t}\n\n\tduk_push_lstring(thr, (const char *) q_start, (duk_size_t) (q_end - q_start));\n\tduk_replace(thr, idx);\n}\n\nDUK_EXTERNAL duk_codepoint_t duk_char_code_at(duk_hthread *thr, duk_idx_t idx, duk_size_t char_offset) {\n\tduk_hstring *h;\n\tduk_ucodepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: Share code with String.prototype.charCodeAt?  Main difference\n\t * is handling of clamped offsets.\n\t */\n\n\th = duk_require_hstring(thr, idx);  /* Accept symbols. */\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_ASSERT_DISABLE(char_offset >= 0);  /* Always true, arg is unsigned. */\n\tif (char_offset >= DUK_HSTRING_GET_CHARLEN(h)) {\n\t\treturn 0;\n\t}\n\n\tDUK_ASSERT(char_offset <= DUK_UINT_MAX);  /* Guaranteed by string limits. */\n\tcp = duk_hstring_char_code_at_raw(thr, h, (duk_uint_t) char_offset, 0 /*surrogate_aware*/);\n\treturn (duk_codepoint_t) cp;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_api_time.c",
    "content": "/*\n *  Date/time.\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL duk_double_t duk_time_get_ecmascript_time(duk_hthread *thr) {\n\t/* ECMAScript time, with millisecond fractions.  Exposed via\n\t * duk_get_now() for example.\n\t */\n\tDUK_UNREF(thr);\n\treturn (duk_double_t) DUK_USE_DATE_GET_NOW(thr);\n}\n\nDUK_INTERNAL duk_double_t duk_time_get_ecmascript_time_nofrac(duk_hthread *thr) {\n\t/* ECMAScript time without millisecond fractions.  Exposed via\n\t * the Date built-in which doesn't allow fractions.\n\t */\n\tDUK_UNREF(thr);\n\treturn (duk_double_t) DUK_FLOOR(DUK_USE_DATE_GET_NOW(thr));\n}\n\nDUK_INTERNAL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr) {\n\tDUK_UNREF(thr);\n#if defined(DUK_USE_GET_MONOTONIC_TIME)\n\treturn (duk_double_t) DUK_USE_GET_MONOTONIC_TIME(thr);\n#else\n\treturn (duk_double_t) DUK_USE_DATE_GET_NOW(thr);\n#endif\n}\n\nDUK_EXTERNAL duk_double_t duk_get_now(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n\n\t/* This API intentionally allows millisecond fractions. */\n\treturn duk_time_get_ecmascript_time(thr);\n}\n\n#if 0  /* XXX: worth exposing? */\nDUK_EXTERNAL duk_double_t duk_get_monotonic_time(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n\n\treturn duk_time_get_monotonic_time(thr);\n}\n#endif\n\nDUK_EXTERNAL void duk_time_to_components(duk_hthread *thr, duk_double_t timeval, duk_time_components *comp) {\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(comp != NULL);  /* XXX: or check? */\n\tDUK_UNREF(thr);\n\n\t/* Convert as one-based, but change month to zero-based to match the\n\t * ECMAScript Date built-in behavior 1:1.\n\t */\n\tflags = DUK_DATE_FLAG_ONEBASED | DUK_DATE_FLAG_NAN_TO_ZERO;\n\n\tduk_bi_date_timeval_to_parts(timeval, parts, dparts, flags);\n\n\t/* XXX: sub-millisecond accuracy for the API */\n\n\tDUK_ASSERT(dparts[DUK_DATE_IDX_MONTH] >= 1.0 && dparts[DUK_DATE_IDX_MONTH] <= 12.0);\n\tcomp->year = dparts[DUK_DATE_IDX_YEAR];\n\tcomp->month = dparts[DUK_DATE_IDX_MONTH] - 1.0;\n\tcomp->day = dparts[DUK_DATE_IDX_DAY];\n\tcomp->hours = dparts[DUK_DATE_IDX_HOUR];\n\tcomp->minutes = dparts[DUK_DATE_IDX_MINUTE];\n\tcomp->seconds = dparts[DUK_DATE_IDX_SECOND];\n\tcomp->milliseconds = dparts[DUK_DATE_IDX_MILLISECOND];\n\tcomp->weekday = dparts[DUK_DATE_IDX_WEEKDAY];\n}\n\nDUK_EXTERNAL duk_double_t duk_components_to_time(duk_hthread *thr, duk_time_components *comp) {\n\tduk_double_t d;\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(comp != NULL);  /* XXX: or check? */\n\tDUK_UNREF(thr);\n\n\t/* Match Date constructor behavior (with UTC time).  Month is given\n\t * as zero-based.  Day-of-month is given as one-based so normalize\n\t * it to zero-based as the internal conversion helpers expects all\n\t * components to be zero-based.\n\t */\n\tflags = 0;\n\n\t/* XXX: expensive conversion; use array format in API instead, or unify\n\t * time provider and time API to use same struct?\n\t */\n\n\tdparts[DUK_DATE_IDX_YEAR] = comp->year;\n\tdparts[DUK_DATE_IDX_MONTH] = comp->month;\n\tdparts[DUK_DATE_IDX_DAY] = comp->day - 1.0;\n\tdparts[DUK_DATE_IDX_HOUR] = comp->hours;\n\tdparts[DUK_DATE_IDX_MINUTE] = comp->minutes;\n\tdparts[DUK_DATE_IDX_SECOND] = comp->seconds;\n\tdparts[DUK_DATE_IDX_MILLISECOND] = comp->milliseconds;\n\tdparts[DUK_DATE_IDX_WEEKDAY] = 0;  /* ignored */\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, flags);\n\n\treturn d;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_array.c",
    "content": "/*\n *  Array built-ins\n *\n *  Most Array built-ins are intentionally generic in ECMAScript, and are\n *  intended to work even when the 'this' binding is not an Array instance.\n *  This ECMAScript feature is also used by much real world code.  For this\n *  reason the implementations here don't assume exotic Array behavior or\n *  e.g. presence of a .length property.  However, some algorithms have a\n *  fast path for duk_harray backed actual Array instances, enabled when\n *  footprint is not a concern.\n *\n *  XXX: the \"Throw\" flag should be set for (almost?) all [[Put]] and\n *  [[Delete]] operations, but it's currently false throughout.  Go through\n *  all put/delete cases and check throw flag use.  Need a new API primitive\n *  which allows throws flag to be specified.\n *\n *  XXX: array lengths above 2G won't work reliably.  There are many places\n *  where one needs a full signed 32-bit range ([-0xffffffff, 0xffffffff],\n *  i.e. -33- bits).  Although array 'length' cannot be written to be outside\n *  the unsigned 32-bit range (E5.1 Section 15.4.5.1 throws a RangeError if so)\n *  some intermediate values may be above 0xffffffff and this may not be always\n *  correctly handled now (duk_uint32_t is not enough for all algorithms).\n *  For instance, push() can legitimately write entries beyond length 0xffffffff\n *  and cause a RangeError only at the end.  To do this properly, the current\n *  push() implementation tracks the array index using a 'double' instead of a\n *  duk_uint32_t (which is somewhat awkward).  See test-bi-array-push-maxlen.js.\n *\n *  On using \"put\" vs. \"def\" prop\n *  =============================\n *\n *  Code below must be careful to use the appropriate primitive as it matters\n *  for compliance.  When using \"put\" there may be inherited properties in\n *  Array.prototype which cause side effects when values are written.  When\n *  using \"define\" there are no such side effects, and many test262 test cases\n *  check for this (for real world code, such side effects are very rare).\n *  Both \"put\" and \"define\" are used in the E5.1 specification; as a rule,\n *  \"put\" is used when modifying an existing array (or a non-array 'this'\n *  binding) and \"define\" for setting values into a fresh result array.\n */\n\n#include \"duk_internal.h\"\n\n/* Perform an intermediate join when this many elements have been pushed\n * on the value stack.\n */\n#define  DUK__ARRAY_MID_JOIN_LIMIT  4096\n\n#if defined(DUK_USE_ARRAY_BUILTIN)\n\n/*\n *  Shared helpers.\n */\n\n/* Shared entry code for many Array built-ins: the 'this' binding is pushed\n * on the value stack and object coerced, and the current .length is returned.\n * Note that length is left on stack (it could be popped, but that's not\n * usually necessary because call handling will clean it up automatically).\n */\nDUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32(duk_hthread *thr) {\n\tduk_uint32_t len;\n\n\t/* XXX: push more directly? */\n\t(void) duk_push_this_coercible_to_object(thr);\n\tDUK_HOBJECT_ASSERT_VALID(duk_get_hobject(thr, -1));\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_LENGTH);\n\tlen = duk_to_uint32(thr, -1);\n\n\t/* -> [ ... ToObject(this) ToUint32(length) ] */\n\treturn len;\n}\n\nDUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32_limited(duk_hthread *thr) {\n\t/* Range limited to [0, 0x7fffffff] range, i.e. range that can be\n\t * represented with duk_int32_t.  Use this when the method doesn't\n\t * handle the full 32-bit unsigned range correctly.\n\t */\n\tduk_uint32_t ret = duk__push_this_obj_len_u32(thr);\n\tif (DUK_UNLIKELY(ret >= 0x80000000UL)) {\n\t\tDUK_ERROR_RANGE_INVALID_LENGTH(thr);\n\t\tDUK_WO_NORETURN(return 0U;);\n\t}\n\treturn ret;\n}\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\n/* Check if 'this' binding is an Array instance (duk_harray) which satisfies\n * a few other guarantees for fast path operation.  The fast path doesn't\n * need to handle all operations, even for duk_harrays, but must handle a\n * significant fraction to improve performance.  Return a non-NULL duk_harray\n * pointer when all fast path criteria are met, NULL otherwise.\n */\nDUK_LOCAL duk_harray *duk__arraypart_fastpath_this(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\tduk_uint_t flags_mask, flags_bits, flags_value;\n\n\tDUK_ASSERT(thr->valstack_bottom > thr->valstack);  /* because call in progress */\n\ttv = DUK_GET_THIS_TVAL_PTR(thr);\n\n\t/* Fast path requires that 'this' is a duk_harray.  Read only arrays\n\t * (ROM backed) are also rejected for simplicity.\n\t */\n\tif (!DUK_TVAL_IS_OBJECT(tv)) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject array fast path: not an object\"));\n\t\treturn NULL;\n\t}\n\th = DUK_TVAL_GET_OBJECT(tv);\n\tDUK_ASSERT(h != NULL);\n\tflags_mask = DUK_HOBJECT_FLAG_ARRAY_PART | \\\n\t             DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \\\n\t             DUK_HEAPHDR_FLAG_READONLY;\n\tflags_bits = DUK_HOBJECT_FLAG_ARRAY_PART | \\\n\t             DUK_HOBJECT_FLAG_EXOTIC_ARRAY;\n\tflags_value = DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) h);\n\tif ((flags_value & flags_mask) != flags_bits) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject array fast path: object flag check failed\"));\n\t\treturn NULL;\n\t}\n\n\t/* In some cases a duk_harray's 'length' may be larger than the\n\t * current array part allocation.  Avoid the fast path in these\n\t * cases, so that all fast path code can safely assume that all\n\t * items in the range [0,length[ are backed by the current array\n\t * part allocation.\n\t */\n\tif (((duk_harray *) h)->length > DUK_HOBJECT_GET_ASIZE(h)) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject array fast path: length > array part size\"));\n\t\treturn NULL;\n\t}\n\n\t/* Guarantees for fast path. */\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0 || DUK_HOBJECT_A_GET_BASE(thr->heap, h) != NULL);\n\tDUK_ASSERT(((duk_harray *) h)->length <= DUK_HOBJECT_GET_ASIZE(h));\n\n\tDUK_DD(DUK_DDPRINT(\"array fast path allowed for: %!O\", (duk_heaphdr *) h));\n\treturn (duk_harray *) h;\n}\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_constructor(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_harray *a;\n\tduk_double_t d;\n\tduk_uint32_t len;\n\tduk_uint32_t len_prealloc;\n\n\tnargs = duk_get_top(thr);\n\n\tif (nargs == 1 && duk_is_number(thr, 0)) {\n\t\t/* XXX: expensive check (also shared elsewhere - so add a shared internal API call?) */\n\t\td = duk_get_number(thr, 0);\n\t\tlen = duk_to_uint32(thr, 0);\n\t\tif (((duk_double_t) len) != d) {\n\t\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t\t}\n\n\t\t/* For small lengths create a dense preallocated array.\n\t\t * For large arrays preallocate an initial part.\n\t\t */\n\t\tlen_prealloc = len < 64 ? len : 64;\n\t\ta = duk_push_harray_with_size(thr, len_prealloc);\n\t\tDUK_ASSERT(a != NULL);\n\t\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\t\ta->length = len;\n\t\treturn 1;\n\t}\n\n\tduk_pack(thr, nargs);\n\treturn 1;\n}\n\n/*\n *  isArray()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_constructor_is_array(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\th = duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_ARRAY);\n\tduk_push_boolean(thr, (h != NULL));\n\treturn 1;\n}\n\n/*\n *  toString()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_to_string(duk_hthread *thr) {\n\t(void) duk_push_this_coercible_to_object(thr);\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_JOIN);\n\n\t/* [ ... this func ] */\n\tif (!duk_is_callable(thr, -1)) {\n\t\t/* Fall back to the initial (original) Object.toString().  We don't\n\t\t * currently have pointers to the built-in functions, only the top\n\t\t * level global objects (like \"Array\") so this is now done in a bit\n\t\t * of a hacky manner.  It would be cleaner to push the (original)\n\t\t * function and use duk_call_method().\n\t\t */\n\n\t\t/* XXX: 'this' will be ToObject() coerced twice, which is incorrect\n\t\t * but should have no visible side effects.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"this.join is not callable, fall back to (original) Object.toString\"));\n\t\tduk_set_top(thr, 0);\n\t\treturn duk_bi_object_prototype_to_string(thr);  /* has access to 'this' binding */\n\t}\n\n\t/* [ ... this func ] */\n\n\tduk_insert(thr, -2);\n\n\t/* [ ... func this ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"calling: func=%!iT, this=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_call_method(thr, 0);\n\n\treturn 1;\n}\n\n/*\n *  concat()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_concat(duk_hthread *thr) {\n\tduk_idx_t i, n;\n\tduk_uint32_t j, idx, len;\n\tduk_hobject *h;\n\tduk_size_t tmp_len;\n\n\t/* XXX: In ES2015 Array .length can be up to 2^53-1.  The current\n\t * implementation is limited to 2^32-1.\n\t */\n\n\t/* XXX: Fast path for array 'this' and array element. */\n\n\t/* XXX: The insert here is a bit expensive if there are a lot of items.\n\t * It could also be special cased in the outermost for loop quite easily\n\t * (as the element is dup()'d anyway).\n\t */\n\n\t(void) duk_push_this_coercible_to_object(thr);\n\tduk_insert(thr, 0);\n\tn = duk_get_top(thr);\n\tduk_push_array(thr);  /* -> [ ToObject(this) item1 ... itemN arr ] */\n\n\t/* NOTE: The Array special behaviors are NOT invoked by duk_xdef_prop_index()\n\t * (which differs from the official algorithm).  If no error is thrown, this\n\t * doesn't matter as the length is updated at the end.  However, if an error\n\t * is thrown, the length will be unset.  That shouldn't matter because the\n\t * caller won't get a reference to the intermediate value.\n\t */\n\n\tidx = 0;\n\tfor (i = 0; i < n; i++) {\n\t\tduk_bool_t spreadable;\n\t\tduk_bool_t need_has_check;\n\n\t\tDUK_ASSERT_TOP(thr, n + 1);\n\n\t\t/* [ ToObject(this) item1 ... itemN arr ] */\n\n\t\th = duk_get_hobject(thr, i);\n\n\t\tif (h == NULL) {\n\t\t\tspreadable = 0;\n\t\t} else {\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t\t\tduk_get_prop_stridx(thr, i, DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE);\n\t\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\t\tspreadable = (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY);\n\t\t\t} else {\n\t\t\t\tspreadable = duk_to_boolean(thr, -1);\n\t\t\t}\n\t\t\tduk_pop_nodecref_unsafe(thr);\n#else\n\t\t\tspreadable = (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY);\n#endif\n\t\t}\n\n\t\tif (!spreadable) {\n\t\t\tduk_dup(thr, i);\n\t\t\tduk_xdef_prop_index_wec(thr, -2, idx);\n\t\t\tidx++;\n\t\t\tif (DUK_UNLIKELY(idx == 0U)) {\n\t\t\t\t/* Index after update is 0, and index written\n\t\t\t\t * was 0xffffffffUL which is no longer a valid\n\t\t\t\t * array index.\n\t\t\t\t */\n\t\t\t\tgoto fail_wrap;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_ASSERT(duk_is_object(thr, i));\n\t\tneed_has_check = (DUK_HOBJECT_IS_PROXY(h) != 0);  /* Always 0 w/o Proxy support. */\n\n\t\t/* [ ToObject(this) item1 ... itemN arr ] */\n\n\t\ttmp_len = duk_get_length(thr, i);\n\t\tlen = (duk_uint32_t) tmp_len;\n\t\tif (DUK_UNLIKELY(tmp_len != (duk_size_t) len)) {\n\t\t\tgoto fail_wrap;\n\t\t}\n\t\tif (DUK_UNLIKELY(idx + len < idx)) {\n\t\t\t/* Result length must be at most 0xffffffffUL to be\n\t\t\t * a valid 32-bit array index.\n\t\t\t */\n\t\t\tgoto fail_wrap;\n\t\t}\n\t\tfor (j = 0; j < len; j++) {\n\t\t\t/* For a Proxy element, an explicit 'has' check is\n\t\t\t * needed to allow the Proxy to present gaps.\n\t\t\t */\n\t\t\tif (need_has_check) {\n\t\t\t\tif (duk_has_prop_index(thr, i, j)) {\n\t\t\t\t\tduk_get_prop_index(thr, i, j);\n\t\t\t\t\tduk_xdef_prop_index_wec(thr, -2, idx);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (duk_get_prop_index(thr, i, j)) {\n\t\t\t\t\tduk_xdef_prop_index_wec(thr, -2, idx);\n\t\t\t\t} else {\n\t\t\t\t\tduk_pop_undefined(thr);\n\t\t\t\t}\n\t\t\t}\n\t\t\tidx++;\n\t\t\tDUK_ASSERT(idx != 0U);  /* Wrap check above. */\n\t\t}\n\t}\n\n\t/* ES5.1 has a specification \"bug\" in that nonexistent trailing\n\t * elements don't affect the result .length.  Test262 and other\n\t * engines disagree, and the specification bug was fixed in ES2015\n\t * (see NOTE 1 in https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.concat).\n\t */\n\tduk_push_uarridx(thr, idx);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\n\tDUK_ASSERT_TOP(thr, n + 1);\n\treturn 1;\n\n fail_wrap:\n\tDUK_ERROR_RANGE_INVALID_LENGTH(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/*\n *  join(), toLocaleString()\n *\n *  Note: checking valstack is necessary, but only in the per-element loop.\n *\n *  Note: the trivial approach of pushing all the elements on the value stack\n *  and then calling duk_join() fails when the array contains a large number\n *  of elements.  This problem can't be offloaded to duk_join() because the\n *  elements to join must be handled here and have special handling.  Current\n *  approach is to do intermediate joins with very large number of elements.\n *  There is no fancy handling; the prefix gets re-joined multiple times.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_join_shared(duk_hthread *thr) {\n\tduk_uint32_t len, count;\n\tduk_uint32_t idx;\n\tduk_small_int_t to_locale_string = duk_get_current_magic(thr);\n\tduk_idx_t valstack_required;\n\n\t/* For join(), nargs is 1.  For toLocaleString(), nargs is 0 and\n\t * setting the top essentially pushes an undefined to the stack,\n\t * thus defaulting to a comma separator.\n\t */\n\tduk_set_top(thr, 1);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tduk_pop_undefined(thr);\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_COMMA);\n\t} else {\n\t\tduk_to_string(thr, 0);\n\t}\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\n\t/* [ sep ToObject(this) len ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"sep=%!T, this=%!T, len=%lu\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1),\n\t                     (unsigned long) len));\n\n\t/* The extra (+4) is tight. */\n\tvalstack_required = (duk_idx_t) ((len >= DUK__ARRAY_MID_JOIN_LIMIT ?\n\t                                  DUK__ARRAY_MID_JOIN_LIMIT : len) + 4);\n\tduk_require_stack(thr, valstack_required);\n\n\tduk_dup_0(thr);\n\n\t/* [ sep ToObject(this) len sep ] */\n\n\tcount = 0;\n\tidx = 0;\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"join idx=%ld\", (long) idx));\n\t\tif (count >= DUK__ARRAY_MID_JOIN_LIMIT ||   /* intermediate join to avoid valstack overflow */\n\t\t    idx >= len) { /* end of loop (careful with len==0) */\n\t\t\t/* [ sep ToObject(this) len sep str0 ... str(count-1) ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"mid/final join, count=%ld, idx=%ld, len=%ld\",\n\t\t\t                     (long) count, (long) idx, (long) len));\n\t\t\tduk_join(thr, (duk_idx_t) count);  /* -> [ sep ToObject(this) len str ] */\n\t\t\tduk_dup_0(thr);                    /* -> [ sep ToObject(this) len str sep ] */\n\t\t\tduk_insert(thr, -2);               /* -> [ sep ToObject(this) len sep str ] */\n\t\t\tcount = 1;\n\t\t}\n\t\tif (idx >= len) {\n\t\t\t/* if true, the stack already contains the final result */\n\t\t\tbreak;\n\t\t}\n\n\t\tduk_get_prop_index(thr, 1, (duk_uarridx_t) idx);\n\t\tif (duk_is_null_or_undefined(thr, -1)) {\n\t\t\tduk_pop_nodecref_unsafe(thr);\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tif (to_locale_string) {\n\t\t\t\tduk_to_object(thr, -1);\n\t\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_LOCALE_STRING);\n\t\t\t\tduk_insert(thr, -2);  /* -> [ ... toLocaleString ToObject(val) ] */\n\t\t\t\tduk_call_method(thr, 0);\n\t\t\t}\n\t\t\tduk_to_string(thr, -1);\n\t\t}\n\n\t\tcount++;\n\t\tidx++;\n\t}\n\n\t/* [ sep ToObject(this) len sep result ] */\n\n\treturn 1;\n}\n\n/*\n *  pop(), push()\n */\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\nDUK_LOCAL duk_ret_t duk__array_pop_fastpath(duk_hthread *thr, duk_harray *h_arr) {\n\tduk_tval *tv_arraypart;\n\tduk_tval *tv_val;\n\tduk_uint32_t len;\n\n\ttv_arraypart = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) h_arr);\n\tlen = h_arr->length;\n\tif (len <= 0) {\n\t\t/* nop, return undefined */\n\t\treturn 0;\n\t}\n\n\tlen--;\n\th_arr->length = len;\n\n\t/* Fast path doesn't check for an index property inherited from\n\t * Array.prototype.  This is quite often acceptable; if not,\n\t * disable fast path.\n\t */\n\tDUK_ASSERT_VS_SPACE(thr);\n\ttv_val = tv_arraypart + len;\n\tif (DUK_TVAL_IS_UNUSED(tv_val)) {\n\t\t/* No net refcount change.  Value stack already has\n\t\t * 'undefined' based on value stack init policy.\n\t\t */\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv_val));\n\t} else {\n\t\t/* No net refcount change. */\n\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv_val);\n\t\tDUK_TVAL_SET_UNUSED(tv_val);\n\t}\n\tthr->valstack_top++;\n\n\t/* XXX: there's no shrink check in the fast path now */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_pop(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t idx;\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\tduk_harray *h_arr;\n#endif\n\n\tDUK_ASSERT_TOP(thr, 0);\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\th_arr = duk__arraypart_fastpath_this(thr);\n\tif (h_arr) {\n\t\treturn duk__array_pop_fastpath(thr, h_arr);\n\t}\n#endif\n\n\t/* XXX: Merge fastpath check into a related call (push this, coerce length, etc)? */\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tif (len == 0) {\n\t\tduk_push_int(thr, 0);\n\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\t\treturn 0;\n\t}\n\tidx = len - 1;\n\n\tduk_get_prop_index(thr, 0, (duk_uarridx_t) idx);\n\tduk_del_prop_index(thr, 0, (duk_uarridx_t) idx);\n\tduk_push_u32(thr, idx);\n\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\treturn 1;\n}\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\nDUK_LOCAL duk_ret_t duk__array_push_fastpath(duk_hthread *thr, duk_harray *h_arr) {\n\tduk_tval *tv_arraypart;\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_uint32_t len;\n\tduk_idx_t i, n;\n\n\tlen = h_arr->length;\n\ttv_arraypart = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) h_arr);\n\n\tn = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT(n >= 0);\n\tDUK_ASSERT((duk_uint32_t) n <= DUK_UINT32_MAX);\n\tif (DUK_UNLIKELY(len + (duk_uint32_t) n < len)) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.push() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);  /* != 0 return value returned as is by caller */\n\t}\n\tif (len + (duk_uint32_t) n > DUK_HOBJECT_GET_ASIZE((duk_hobject *) h_arr)) {\n\t\t/* Array part would need to be extended.  Rely on slow path\n\t\t * for now.\n\t\t *\n\t\t * XXX: Rework hobject code a bit and add extend support.\n\t\t */\n\t\treturn 0;\n\t}\n\n\ttv_src = thr->valstack_bottom;\n\ttv_dst = tv_arraypart + len;\n\tfor (i = 0; i < n; i++) {\n\t\t/* No net refcount change; reset value stack values to\n\t\t * undefined to satisfy value stack init policy.\n\t\t */\n\t\tDUK_TVAL_SET_TVAL(tv_dst, tv_src);\n\t\tDUK_TVAL_SET_UNDEFINED(tv_src);\n\t\ttv_src++;\n\t\ttv_dst++;\n\t}\n\tthr->valstack_top = thr->valstack_bottom;\n\tlen += (duk_uint32_t) n;\n\th_arr->length = len;\n\n\tDUK_ASSERT((duk_uint_t) len == len);\n\tduk_push_uint(thr, (duk_uint_t) len);\n\treturn 1;\n}\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_push(duk_hthread *thr) {\n\t/* Note: 'this' is not necessarily an Array object.  The push()\n\t * algorithm is supposed to work for other kinds of objects too,\n\t * so the algorithm has e.g. an explicit update for the 'length'\n\t * property which is normally \"magical\" in arrays.\n\t */\n\n\tduk_uint32_t len;\n\tduk_idx_t i, n;\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\tduk_harray *h_arr;\n#endif\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\th_arr = duk__arraypart_fastpath_this(thr);\n\tif (h_arr) {\n\t\tduk_ret_t rc;\n\t\trc = duk__array_push_fastpath(thr, h_arr);\n\t\tif (rc != 0) {\n\t\t\treturn rc;\n\t\t}\n\t\tDUK_DD(DUK_DDPRINT(\"array push() fast path exited, resize case\"));\n\t}\n#endif\n\n\tn = duk_get_top(thr);\n\tlen = duk__push_this_obj_len_u32(thr);\n\n\t/* [ arg1 ... argN obj length ] */\n\n\t/* Technically Array.prototype.push() can create an Array with length\n\t * longer than 2^32-1, i.e. outside the 32-bit range.  The final length\n\t * is *not* wrapped to 32 bits in the specification.\n\t *\n\t * This implementation tracks length with a uint32 because it's much\n\t * more practical.\n\t *\n\t * See: test-bi-array-push-maxlen.js.\n\t */\n\n\tif (len + (duk_uint32_t) n < len) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.push() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t}\n\n\tfor (i = 0; i < n; i++) {\n\t\tduk_dup(thr, i);\n\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) (len + (duk_uint32_t) i));\n\t}\n\tlen += (duk_uint32_t) n;\n\n\tduk_push_u32(thr, len);\n\tduk_dup_top(thr);\n\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH);\n\n\t/* [ arg1 ... argN obj length new_length ] */\n\treturn 1;\n}\n\n/*\n *  sort()\n *\n *  Currently qsort with random pivot.  This is now really, really slow,\n *  because there is no fast path for array parts.\n *\n *  Signed indices are used because qsort() leaves and degenerate cases\n *  may use a negative offset.\n */\n\nDUK_LOCAL duk_small_int_t duk__array_sort_compare(duk_hthread *thr, duk_int_t idx1, duk_int_t idx2) {\n\tduk_bool_t have1, have2;\n\tduk_bool_t undef1, undef2;\n\tduk_small_int_t ret;\n\tduk_idx_t idx_obj = 1;  /* fixed offsets in valstack */\n\tduk_idx_t idx_fn = 0;\n\tduk_hstring *h1, *h2;\n\n\t/* Fast exit if indices are identical.  This is valid for a non-existent property,\n\t * for an undefined value, and almost always for ToString() coerced comparison of\n\t * arbitrary values (corner cases where this is not the case include e.g. a an\n\t * object with varying ToString() coercion).\n\t *\n\t * The specification does not prohibit \"caching\" of values read from the array, so\n\t * assuming equality for comparing an index with itself falls into the category of\n\t * \"caching\".\n\t *\n\t * Also, compareFn may be inconsistent, so skipping a call to compareFn here may\n\t * have an effect on the final result.  The specification does not require any\n\t * specific behavior for inconsistent compare functions, so again, this fast path\n\t * is OK.\n\t */\n\n\tif (idx1 == idx2) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__array_sort_compare: idx1=%ld, idx2=%ld -> indices identical, quick exit\",\n\t\t                     (long) idx1, (long) idx2));\n\t\treturn 0;\n\t}\n\n\thave1 = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) idx1);\n\thave2 = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) idx2);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__array_sort_compare: idx1=%ld, idx2=%ld, have1=%ld, have2=%ld, val1=%!T, val2=%!T\",\n\t                     (long) idx1, (long) idx2, (long) have1, (long) have2,\n\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (have1) {\n\t\tif (have2) {\n\t\t\t;\n\t\t} else {\n\t\t\tret = -1;\n\t\t\tgoto pop_ret;\n\t\t}\n\t} else {\n\t\tif (have2) {\n\t\t\tret = 1;\n\t\t\tgoto pop_ret;\n\t\t} else {\n\t\t\tret = 0;\n\t\t\tgoto pop_ret;\n\t\t}\n\t}\n\n\tundef1 = duk_is_undefined(thr, -2);\n\tundef2 = duk_is_undefined(thr, -1);\n\tif (undef1) {\n\t\tif (undef2) {\n\t\t\tret = 0;\n\t\t\tgoto pop_ret;\n\t\t} else {\n\t\t\tret = 1;\n\t\t\tgoto pop_ret;\n\t\t}\n\t} else {\n\t\tif (undef2) {\n\t\t\tret = -1;\n\t\t\tgoto pop_ret;\n\t\t} else {\n\t\t\t;\n\t\t}\n\t}\n\n\tif (!duk_is_undefined(thr, idx_fn)) {\n\t\tduk_double_t d;\n\n\t\t/* No need to check callable; duk_call() will do that. */\n\t\tduk_dup(thr, idx_fn);    /* -> [ ... x y fn ] */\n\t\tduk_insert(thr, -3);     /* -> [ ... fn x y ] */\n\t\tduk_call(thr, 2);        /* -> [ ... res ] */\n\n\t\t/* ES5 is a bit vague about what to do if the return value is\n\t\t * not a number.  ES2015 provides a concrete description:\n\t\t * http://www.ecma-international.org/ecma-262/6.0/#sec-sortcompare.\n\t\t */\n\n\t\td = duk_to_number_m1(thr);\n\t\tif (d < 0.0) {\n\t\t\tret = -1;\n\t\t} else if (d > 0.0) {\n\t\t\tret = 1;\n\t\t} else {\n\t\t\t/* Because NaN compares to false, NaN is handled here\n\t\t\t * without an explicit check above.\n\t\t\t */\n\t\t\tret = 0;\n\t\t}\n\n\t\tduk_pop_nodecref_unsafe(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> result %ld (from comparefn, after coercion)\", (long) ret));\n\t\treturn ret;\n\t}\n\n\t/* string compare is the default (a bit oddly) */\n\n\t/* XXX: any special handling for plain array; causes repeated coercion now? */\n\th1 = duk_to_hstring(thr, -2);\n\th2 = duk_to_hstring_m1(thr);\n\tDUK_ASSERT(h1 != NULL);\n\tDUK_ASSERT(h2 != NULL);\n\n\tret = duk_js_string_compare(h1, h2);  /* retval is directly usable */\n\tgoto pop_ret;\n\n pop_ret:\n\tduk_pop_2_unsafe(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"-> result %ld\", (long) ret));\n\treturn ret;\n}\n\nDUK_LOCAL void duk__array_sort_swap(duk_hthread *thr, duk_int_t l, duk_int_t r) {\n\tduk_bool_t have_l, have_r;\n\tduk_idx_t idx_obj = 1;  /* fixed offset in valstack */\n\n\tif (l == r) {\n\t\treturn;\n\t}\n\n\t/* swap elements; deal with non-existent elements correctly */\n\thave_l = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) l);\n\thave_r = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) r);\n\n\tif (have_r) {\n\t\t/* right exists, [[Put]] regardless whether or not left exists */\n\t\tduk_put_prop_index(thr, idx_obj, (duk_uarridx_t) l);\n\t} else {\n\t\tduk_del_prop_index(thr, idx_obj, (duk_uarridx_t) l);\n\t\tduk_pop_undefined(thr);\n\t}\n\n\tif (have_l) {\n\t\tduk_put_prop_index(thr, idx_obj, (duk_uarridx_t) r);\n\t} else {\n\t\tduk_del_prop_index(thr, idx_obj, (duk_uarridx_t) r);\n\t\tduk_pop_undefined(thr);\n\t}\n}\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n/* Debug print which visualizes the qsort partitioning process. */\nDUK_LOCAL void duk__debuglog_qsort_state(duk_hthread *thr, duk_int_t lo, duk_int_t hi, duk_int_t pivot) {\n\tchar buf[4096];\n\tchar *ptr = buf;\n\tduk_int_t i, n;\n\tn = (duk_int_t) duk_get_length(thr, 1);\n\tif (n > 4000) {\n\t\tn = 4000;\n\t}\n\t*ptr++ = '[';\n\tfor (i = 0; i < n; i++) {\n\t\tif (i == pivot) {\n\t\t\t*ptr++ = '|';\n\t\t} else if (i == lo) {\n\t\t\t*ptr++ = '<';\n\t\t} else if (i == hi) {\n\t\t\t*ptr++ = '>';\n\t\t} else if (i >= lo && i <= hi) {\n\t\t\t*ptr++ = '-';\n\t\t} else {\n\t\t\t*ptr++ = ' ';\n\t\t}\n\t}\n\t*ptr++ = ']';\n\t*ptr++ = '\\0';\n\n\tDUK_DDD(DUK_DDDPRINT(\"%s   (lo=%ld, hi=%ld, pivot=%ld)\",\n\t                     (const char *) buf, (long) lo, (long) hi, (long) pivot));\n}\n#endif\n\nDUK_LOCAL void duk__array_qsort(duk_hthread *thr, duk_int_t lo, duk_int_t hi) {\n\tduk_int_t p, l, r;\n\n\t/* The lo/hi indices may be crossed and hi < 0 is possible at entry. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__array_qsort: lo=%ld, hi=%ld, obj=%!T\",\n\t                     (long) lo, (long) hi, (duk_tval *) duk_get_tval(thr, 1)));\n\n\tDUK_ASSERT_TOP(thr, 3);\n\n\t/* In some cases it may be that lo > hi, or hi < 0; these\n\t * degenerate cases happen e.g. for empty arrays, and in\n\t * recursion leaves.\n\t */\n\n\t/* trivial cases */\n\tif (hi - lo < 1) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"degenerate case, return immediately\"));\n\t\treturn;\n\t}\n\tDUK_ASSERT(hi > lo);\n\tDUK_ASSERT(hi - lo + 1 >= 2);\n\n\t/* randomized pivot selection */\n\tp = lo + (duk_int_t) (DUK_UTIL_GET_RANDOM_DOUBLE(thr) * (duk_double_t) (hi - lo + 1));\n\tDUK_ASSERT(p >= lo && p <= hi);\n\tDUK_DDD(DUK_DDDPRINT(\"lo=%ld, hi=%ld, chose pivot p=%ld\", (long) lo, (long) hi, (long) p));\n\n\t/* move pivot out of the way */\n\tduk__array_sort_swap(thr, p, lo);\n\tp = lo;\n\tDUK_DDD(DUK_DDDPRINT(\"pivot moved out of the way: %!T\", (duk_tval *) duk_get_tval(thr, 1)));\n\n\tl = lo + 1;\n\tr = hi;\n\tfor (;;) {\n\t\t/* find elements to swap */\n\t\tfor (;;) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"left scan: l=%ld, r=%ld, p=%ld\",\n\t\t\t                     (long) l, (long) r, (long) p));\n\t\t\tif (l >= hi) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (duk__array_sort_compare(thr, l, p) >= 0) {  /* !(l < p) */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tl++;\n\t\t}\n\t\tfor (;;) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"right scan: l=%ld, r=%ld, p=%ld\",\n\t\t\t                     (long) l, (long) r, (long) p));\n\t\t\tif (r <= lo) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (duk__array_sort_compare(thr, p, r) >= 0) {  /* !(p < r) */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tr--;\n\t\t}\n\t\tif (l >= r) {\n\t\t\tgoto done;\n\t\t}\n\t\tDUK_ASSERT(l < r);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"swap %ld and %ld\", (long) l, (long) r));\n\n\t\tduk__array_sort_swap(thr, l, r);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"after swap: %!T\", (duk_tval *) duk_get_tval(thr, 1)));\n\t\tl++;\n\t\tr--;\n\t}\n done:\n\t/* Note that 'l' and 'r' may cross, i.e. r < l */\n\tDUK_ASSERT(l >= lo && l <= hi);\n\tDUK_ASSERT(r >= lo && r <= hi);\n\n\t/* XXX: there's no explicit recursion bound here now.  For the average\n\t * qsort recursion depth O(log n) that's not really necessary: e.g. for\n\t * 2**32 recursion depth would be about 32 which is OK.  However, qsort\n\t * worst case recursion depth is O(n) which may be a problem.\n\t */\n\n\t/* move pivot to its final place */\n\tDUK_DDD(DUK_DDDPRINT(\"before final pivot swap: %!T\", (duk_tval *) duk_get_tval(thr, 1)));\n\tduk__array_sort_swap(thr, lo, r);\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\tduk__debuglog_qsort_state(thr, lo, hi, r);\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"recurse: pivot=%ld, obj=%!T\", (long) r, (duk_tval *) duk_get_tval(thr, 1)));\n\tduk__array_qsort(thr, lo, r - 1);\n\tduk__array_qsort(thr, r + 1, hi);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_sort(duk_hthread *thr) {\n\tduk_uint32_t len;\n\n\t/* XXX: len >= 0x80000000 won't work below because a signed type\n\t * is needed by qsort.\n\t */\n\tlen = duk__push_this_obj_len_u32_limited(thr);\n\n\t/* stack[0] = compareFn\n\t * stack[1] = ToObject(this)\n\t * stack[2] = ToUint32(length)\n\t */\n\n\tif (len > 0) {\n\t\t/* avoid degenerate cases, so that (len - 1) won't underflow */\n\t\tduk__array_qsort(thr, (duk_int_t) 0, (duk_int_t) (len - 1));\n\t}\n\n\tDUK_ASSERT_TOP(thr, 3);\n\tduk_pop_nodecref_unsafe(thr);\n\treturn 1;  /* return ToObject(this) */\n}\n\n/*\n *  splice()\n */\n\n/* XXX: this compiles to over 500 bytes now, even without special handling\n * for an array part.  Uses signed ints so does not handle full array range correctly.\n */\n\n/* XXX: can shift() / unshift() use the same helper?\n *   shift() is (close to?) <--> splice(0, 1)\n *   unshift is (close to?) <--> splice(0, 0, [items])?\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_uint32_t len_u32;\n\tduk_int_t len;\n\tduk_bool_t have_delcount;\n\tduk_int_t item_count;\n\tduk_int_t act_start;\n\tduk_int_t del_count;\n\tduk_int_t i, n;\n\n\tDUK_UNREF(have_delcount);\n\n\tnargs = duk_get_top(thr);\n\tif (nargs < 2) {\n\t\tduk_set_top(thr, 2);\n\t\tnargs = 2;\n\t\thave_delcount = 0;\n\t} else {\n\t\thave_delcount = 1;\n\t}\n\n\t/* XXX: len >= 0x80000000 won't work below because we need to be\n\t * able to represent -len.\n\t */\n\tlen_u32 = duk__push_this_obj_len_u32_limited(thr);\n\tlen = (duk_int_t) len_u32;\n\tDUK_ASSERT(len >= 0);\n\n\tact_start = duk_to_int_clamped(thr, 0, -len, len);\n\tif (act_start < 0) {\n\t\tact_start = len + act_start;\n\t}\n\tDUK_ASSERT(act_start >= 0 && act_start <= len);\n\n#if defined(DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT)\n\tif (have_delcount) {\n#endif\n\t\tdel_count = duk_to_int_clamped(thr, 1, 0, len - act_start);\n#if defined(DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT)\n\t} else {\n\t\t/* E5.1 standard behavior when deleteCount is not given would be\n\t\t * to treat it just like if 'undefined' was given, which coerces\n\t\t * ultimately to 0.  Real world behavior is to splice to the end\n\t\t * of array, see test-bi-array-proto-splice-no-delcount.js.\n\t\t */\n\t\tdel_count = len - act_start;\n\t}\n#endif\n\n\tDUK_ASSERT(nargs >= 2);\n\titem_count = (duk_int_t) (nargs - 2);\n\n\tDUK_ASSERT(del_count >= 0 && del_count <= len - act_start);\n\tDUK_ASSERT(del_count + act_start <= len);\n\n\t/* For now, restrict result array into 32-bit length range. */\n\tif (((duk_double_t) len) - ((duk_double_t) del_count) + ((duk_double_t) item_count) > (duk_double_t) DUK_UINT32_MAX) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.splice() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t}\n\n\tduk_push_array(thr);\n\n\t/* stack[0] = start\n\t * stack[1] = deleteCount\n\t * stack[2...nargs-1] = items\n\t * stack[nargs] = ToObject(this)               -3\n\t * stack[nargs+1] = ToUint32(length)           -2\n\t * stack[nargs+2] = result array               -1\n\t */\n\n\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t/* Step 9: copy elements-to-be-deleted into the result array */\n\n\tfor (i = 0; i < del_count; i++) {\n\t\tif (duk_get_prop_index(thr, -3, (duk_uarridx_t) (act_start + i))) {\n\t\t\tduk_xdef_prop_index_wec(thr, -2, (duk_uarridx_t) i);  /* throw flag irrelevant (false in std alg) */\n\t\t} else {\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\t}\n\tduk_push_u32(thr, (duk_uint32_t) del_count);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\n\t/* Steps 12 and 13: reorganize elements to make room for itemCount elements */\n\n\tif (item_count < del_count) {\n\t\t/*    [ A B C D E F G H ]    rel_index = 2, del_count 3, item count 1\n\t\t * -> [ A B F G H ]          (conceptual intermediate step)\n\t\t * -> [ A B . F G H ]        (placeholder marked)\n\t\t *    [ A B C F G H ]        (actual result at this point, C will be replaced)\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t\tn = len - del_count;\n\t\tfor (i = act_start; i < n; i++) {\n\t\t\tif (duk_get_prop_index(thr, -3, (duk_uarridx_t) (i + del_count))) {\n\t\t\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) (i + item_count));\n\t\t\t} else {\n\t\t\t\tduk_pop_undefined(thr);\n\t\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) (i + item_count));\n\t\t\t}\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t\t/* loop iterator init and limit changed from standard algorithm */\n\t\tn = len - del_count + item_count;\n\t\tfor (i = len - 1; i >= n; i--) {\n\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) i);\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\t} else if (item_count > del_count) {\n\t\t/*    [ A B C D E F G H ]    rel_index = 2, del_count 3, item count 4\n\t\t * -> [ A B F G H ]          (conceptual intermediate step)\n\t\t * -> [ A B . . . . F G H ]  (placeholder marked)\n\t\t *    [ A B C D E F F G H ]  (actual result at this point)\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t\t/* loop iterator init and limit changed from standard algorithm */\n\t\tfor (i = len - del_count - 1; i >= act_start; i--) {\n\t\t\tif (duk_get_prop_index(thr, -3, (duk_uarridx_t) (i + del_count))) {\n\t\t\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) (i + item_count));\n\t\t\t} else {\n\t\t\t\tduk_pop_undefined(thr);\n\t\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) (i + item_count));\n\t\t\t}\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\t} else {\n\t\t/*    [ A B C D E F G H ]    rel_index = 2, del_count 3, item count 3\n\t\t * -> [ A B F G H ]          (conceptual intermediate step)\n\t\t * -> [ A B . . . F G H ]    (placeholder marked)\n\t\t *    [ A B C D E F G H ]    (actual result at this point)\n\t\t */\n\t}\n\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t/* Step 15: insert itemCount elements into the hole made above */\n\n\tfor (i = 0; i < item_count; i++) {\n\t\tduk_dup(thr, i + 2);  /* args start at index 2 */\n\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) (act_start + i));\n\t}\n\n\t/* Step 16: update length; note that the final length may be above 32 bit range\n\t * (but we checked above that this isn't the case here)\n\t */\n\n\tduk_push_u32(thr, (duk_uint32_t) (len - del_count + item_count));\n\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH);\n\n\t/* result array is already at the top of stack */\n\tDUK_ASSERT_TOP(thr, nargs + 3);\n\treturn 1;\n}\n\n/*\n *  reverse()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_reverse(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t middle;\n\tduk_uint32_t lower, upper;\n\tduk_bool_t have_lower, have_upper;\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tmiddle = len / 2;\n\n\t/* If len <= 1, middle will be 0 and for-loop bails out\n\t * immediately (0 < 0 -> false).\n\t */\n\n\tfor (lower = 0; lower < middle; lower++) {\n\t\tDUK_ASSERT(len >= 2);\n\t\tDUK_ASSERT_TOP(thr, 2);\n\n\t\tDUK_ASSERT(len >= lower + 1);\n\t\tupper = len - lower - 1;\n\n\t\thave_lower = duk_get_prop_index(thr, -2, (duk_uarridx_t) lower);\n\t\thave_upper = duk_get_prop_index(thr, -3, (duk_uarridx_t) upper);\n\n\t\t/* [ ToObject(this) ToUint32(length) lowerValue upperValue ] */\n\n\t\tif (have_upper) {\n\t\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) lower);\n\t\t} else {\n\t\t\tduk_del_prop_index(thr, -4, (duk_uarridx_t) lower);\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\n\t\tif (have_lower) {\n\t\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) upper);\n\t\t} else {\n\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) upper);\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t}\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_pop_unsafe(thr);  /* -> [ ToObject(this) ] */\n\treturn 1;\n}\n\n/*\n *  slice()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_slice(duk_hthread *thr) {\n\tduk_uint32_t len_u32;\n\tduk_int_t len;\n\tduk_int_t start, end;\n\tduk_int_t i;\n\tduk_uarridx_t idx;\n\tduk_uint32_t res_length = 0;\n\n\t/* XXX: len >= 0x80000000 won't work below because we need to be\n\t * able to represent -len.\n\t */\n\tlen_u32 = duk__push_this_obj_len_u32_limited(thr);\n\tlen = (duk_int_t) len_u32;\n\tDUK_ASSERT(len >= 0);\n\n\tduk_push_array(thr);\n\n\t/* stack[0] = start\n\t * stack[1] = end\n\t * stack[2] = ToObject(this)\n\t * stack[3] = ToUint32(length)\n\t * stack[4] = result array\n\t */\n\n\tstart = duk_to_int_clamped(thr, 0, -len, len);\n\tif (start < 0) {\n\t\tstart = len + start;\n\t}\n\t/* XXX: could duk_is_undefined() provide defaulting undefined to 'len'\n\t * (the upper limit)?\n\t */\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend = len;\n\t} else {\n\t\tend = duk_to_int_clamped(thr, 1, -len, len);\n\t\tif (end < 0) {\n\t\t\tend = len + end;\n\t\t}\n\t}\n\tDUK_ASSERT(start >= 0 && start <= len);\n\tDUK_ASSERT(end >= 0 && end <= len);\n\n\tidx = 0;\n\tfor (i = start; i < end; i++) {\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t\tif (duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\tduk_xdef_prop_index_wec(thr, 4, idx);\n\t\t\tres_length = idx + 1;\n\t\t} else {\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\t\tidx++;\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t}\n\n\tduk_push_u32(thr, res_length);\n\tduk_xdef_prop_stridx_short(thr, 4, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\n\tDUK_ASSERT_TOP(thr, 5);\n\treturn 1;\n}\n\n/*\n *  shift()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_shift(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t i;\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tif (len == 0) {\n\t\tduk_push_int(thr, 0);\n\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\t\treturn 0;\n\t}\n\n\tduk_get_prop_index(thr, 0, 0);\n\n\t/* stack[0] = object (this)\n\t * stack[1] = ToUint32(length)\n\t * stack[2] = elem at index 0 (retval)\n\t */\n\n\tfor (i = 1; i < len; i++) {\n\t\tDUK_ASSERT_TOP(thr, 3);\n\t\tif (duk_get_prop_index(thr, 0, (duk_uarridx_t) i)) {\n\t\t\t/* fromPresent = true */\n\t\t\tduk_put_prop_index(thr, 0, (duk_uarridx_t) (i - 1));\n\t\t} else {\n\t\t\t/* fromPresent = false */\n\t\t\tduk_del_prop_index(thr, 0, (duk_uarridx_t) (i - 1));\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\t}\n\tduk_del_prop_index(thr, 0, (duk_uarridx_t) (len - 1));\n\n\tduk_push_u32(thr, (duk_uint32_t) (len - 1));\n\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\n\tDUK_ASSERT_TOP(thr, 3);\n\treturn 1;\n}\n\n/*\n *  unshift()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_unshift(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_uint32_t len;\n\tduk_uint32_t i;\n\n\tnargs = duk_get_top(thr);\n\tlen = duk__push_this_obj_len_u32(thr);\n\n\t/* stack[0...nargs-1] = unshift args (vararg)\n\t * stack[nargs] = ToObject(this)\n\t * stack[nargs+1] = ToUint32(length)\n\t */\n\n\tDUK_ASSERT_TOP(thr, nargs + 2);\n\n\t/* Note: unshift() may operate on indices above unsigned 32-bit range\n\t * and the final length may be >= 2**32.  However, we restrict the\n\t * final result to 32-bit range for practicality.\n\t */\n\n\tif (len + (duk_uint32_t) nargs < len) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.unshift() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t}\n\n\ti = len;\n\twhile (i > 0) {\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t\ti--;\n\t\t/* k+argCount-1; note that may be above 32-bit range */\n\n\t\tif (duk_get_prop_index(thr, -2, (duk_uarridx_t) i)) {\n\t\t\t/* fromPresent = true */\n\t\t\t/* [ ... ToObject(this) ToUint32(length) val ] */\n\t\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) (i + (duk_uint32_t) nargs));  /* -> [ ... ToObject(this) ToUint32(length) ] */\n\t\t} else {\n\t\t\t/* fromPresent = false */\n\t\t\t/* [ ... ToObject(this) ToUint32(length) val ] */\n\t\t\tduk_pop_undefined(thr);\n\t\t\tduk_del_prop_index(thr, -2, (duk_uarridx_t) (i + (duk_uint32_t) nargs));  /* -> [ ... ToObject(this) ToUint32(length) ] */\n\t\t}\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t}\n\n\tfor (i = 0; i < (duk_uint32_t) nargs; i++) {\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t\tduk_dup(thr, (duk_idx_t) i);  /* -> [ ... ToObject(this) ToUint32(length) arg[i] ] */\n\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) i);\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t}\n\n\tDUK_ASSERT_TOP(thr, nargs + 2);\n\tduk_push_u32(thr, len + (duk_uint32_t) nargs);\n\tduk_dup_top(thr);  /* -> [ ... ToObject(this) ToUint32(length) final_len final_len ] */\n\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH);\n\treturn 1;\n}\n\n/*\n *  indexOf(), lastIndexOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_indexof_shared(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_int_t i, len;\n\tduk_int_t from_idx;\n\tduk_small_int_t idx_step = duk_get_current_magic(thr);  /* idx_step is +1 for indexOf, -1 for lastIndexOf */\n\n\t/* lastIndexOf() needs to be a vararg function because we must distinguish\n\t * between an undefined fromIndex and a \"not given\" fromIndex; indexOf() is\n\t * made vararg for symmetry although it doesn't strictly need to be.\n\t */\n\n\tnargs = duk_get_top(thr);\n\tduk_set_top(thr, 2);\n\n\t/* XXX: must be able to represent -len */\n\tlen = (duk_int_t) duk__push_this_obj_len_u32_limited(thr);\n\tif (len == 0) {\n\t\tgoto not_found;\n\t}\n\n\t/* Index clamping is a bit tricky, we must ensure that we'll only iterate\n\t * through elements that exist and that the specific requirements from E5.1\n\t * Sections 15.4.4.14 and 15.4.4.15 are fulfilled; especially:\n\t *\n\t *   - indexOf: clamp to [-len,len], negative handling -> [0,len],\n\t *     if clamped result is len, for-loop bails out immediately\n\t *\n\t *   - lastIndexOf: clamp to [-len-1, len-1], negative handling -> [-1, len-1],\n\t *     if clamped result is -1, for-loop bails out immediately\n\t *\n\t * If fromIndex is not given, ToInteger(undefined) = 0, which is correct\n\t * for indexOf() but incorrect for lastIndexOf().  Hence special handling,\n\t * and why lastIndexOf() needs to be a vararg function.\n\t */\n\n\tif (nargs >= 2) {\n\t\t/* indexOf: clamp fromIndex to [-len, len]\n\t\t * (if fromIndex == len, for-loop terminates directly)\n\t\t *\n\t\t * lastIndexOf: clamp fromIndex to [-len - 1, len - 1]\n\t\t * (if clamped to -len-1 -> fromIndex becomes -1, terminates for-loop directly)\n\t\t */\n\t\tfrom_idx = duk_to_int_clamped(thr,\n\t\t                              1,\n\t\t                              (idx_step > 0 ? -len : -len - 1),\n\t\t                              (idx_step > 0 ? len : len - 1));\n\t\tif (from_idx < 0) {\n\t\t\t/* for lastIndexOf, result may be -1 (mark immediate termination) */\n\t\t\tfrom_idx = len + from_idx;\n\t\t}\n\t} else {\n\t\t/* for indexOf, ToInteger(undefined) would be 0, i.e. correct, but\n\t\t * handle both indexOf and lastIndexOf specially here.\n\t\t */\n\t\tif (idx_step > 0) {\n\t\t\tfrom_idx = 0;\n\t\t} else {\n\t\t\tfrom_idx = len - 1;\n\t\t}\n\t}\n\n\t/* stack[0] = searchElement\n\t * stack[1] = fromIndex\n\t * stack[2] = object\n\t * stack[3] = length (not needed, but not popped above)\n\t */\n\n\tfor (i = from_idx; i >= 0 && i < len; i += idx_step) {\n\t\tDUK_ASSERT_TOP(thr, 4);\n\n\t\tif (duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t\tif (duk_strict_equals(thr, 0, 4)) {\n\t\t\t\tduk_push_int(thr, i);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\tduk_pop_unsafe(thr);\n\t}\n\n not_found:\n\tduk_push_int(thr, -1);\n\treturn 1;\n}\n\n/*\n *  every(), some(), forEach(), map(), filter()\n */\n\n#define DUK__ITER_EVERY    0\n#define DUK__ITER_SOME     1\n#define DUK__ITER_FOREACH  2\n#define DUK__ITER_MAP      3\n#define DUK__ITER_FILTER   4\n\n/* XXX: This helper is a bit awkward because the handling for the different iteration\n * callers is quite different.  This now compiles to a bit less than 500 bytes, so with\n * 5 callers the net result is about 100 bytes / caller.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_iter_shared(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t i;\n\tduk_uarridx_t k;\n\tduk_bool_t bval;\n\tduk_small_int_t iter_type = duk_get_current_magic(thr);\n\tduk_uint32_t res_length = 0;\n\n\t/* each call this helper serves has nargs==2 */\n\tDUK_ASSERT_TOP(thr, 2);\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tduk_require_callable(thr, 0);\n\t/* if thisArg not supplied, behave as if undefined was supplied */\n\n\tif (iter_type == DUK__ITER_MAP || iter_type == DUK__ITER_FILTER) {\n\t\tduk_push_array(thr);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n\n\t/* stack[0] = callback\n\t * stack[1] = thisArg\n\t * stack[2] = object\n\t * stack[3] = ToUint32(length)  (unused, but avoid unnecessary pop)\n\t * stack[4] = result array (or undefined)\n\t */\n\n\tk = 0;  /* result index for filter() */\n\tfor (i = 0; i < len; i++) {\n\t\tDUK_ASSERT_TOP(thr, 5);\n\n\t\tif (!duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\t/* For 'map' trailing missing elements don't invoke the\n\t\t\t * callback but count towards the result length.\n\t\t\t */\n\t\t\tif (iter_type == DUK__ITER_MAP) {\n\t\t\t\tres_length = i + 1;\n\t\t\t}\n\t\t\tduk_pop_undefined(thr);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* The original value needs to be preserved for filter(), hence\n\t\t * this funny order.  We can't re-get the value because of side\n\t\t * effects.\n\t\t */\n\n\t\tduk_dup_0(thr);\n\t\tduk_dup_1(thr);\n\t\tduk_dup_m3(thr);\n\t\tduk_push_u32(thr, i);\n\t\tduk_dup_2(thr);  /* [ ... val callback thisArg val i obj ] */\n\t\tduk_call_method(thr, 3); /* -> [ ... val retval ] */\n\n\t\tswitch (iter_type) {\n\t\tcase DUK__ITER_EVERY:\n\t\t\tbval = duk_to_boolean(thr, -1);\n\t\t\tif (!bval) {\n\t\t\t\t/* stack top contains 'false' */\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase DUK__ITER_SOME:\n\t\t\tbval = duk_to_boolean(thr, -1);\n\t\t\tif (bval) {\n\t\t\t\t/* stack top contains 'true' */\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase DUK__ITER_FOREACH:\n\t\t\t/* nop */\n\t\t\tbreak;\n\t\tcase DUK__ITER_MAP:\n\t\t\tduk_dup_top(thr);\n\t\t\tduk_xdef_prop_index_wec(thr, 4, (duk_uarridx_t) i);  /* retval to result[i] */\n\t\t\tres_length = i + 1;\n\t\t\tbreak;\n\t\tcase DUK__ITER_FILTER:\n\t\t\tbval = duk_to_boolean(thr, -1);\n\t\t\tif (bval) {\n\t\t\t\tduk_dup_m2(thr);  /* orig value */\n\t\t\t\tduk_xdef_prop_index_wec(thr, 4, (duk_uarridx_t) k);\n\t\t\t\tk++;\n\t\t\t\tres_length = k;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tduk_pop_2_unsafe(thr);\n\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t}\n\n\tswitch (iter_type) {\n\tcase DUK__ITER_EVERY:\n\t\tduk_push_true(thr);\n\t\tbreak;\n\tcase DUK__ITER_SOME:\n\t\tduk_push_false(thr);\n\t\tbreak;\n\tcase DUK__ITER_FOREACH:\n\t\tduk_push_undefined(thr);\n\t\tbreak;\n\tcase DUK__ITER_MAP:\n\tcase DUK__ITER_FILTER:\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t\tDUK_ASSERT(duk_is_array(thr, -1));  /* topmost element is the result array already */\n\t\tduk_push_u32(thr, res_length);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\t\tbreak;\n\tdefault:\n\t\tDUK_UNREACHABLE();\n\t\tbreak;\n\t}\n\n\treturn 1;\n}\n\n/*\n *  reduce(), reduceRight()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_reduce_shared(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_bool_t have_acc;\n\tduk_uint32_t i, len;\n\tduk_small_int_t idx_step = duk_get_current_magic(thr);  /* idx_step is +1 for reduce, -1 for reduceRight */\n\n\t/* We're a varargs function because we need to detect whether\n\t * initialValue was given or not.\n\t */\n\tnargs = duk_get_top(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"nargs=%ld\", (long) nargs));\n\n\tduk_set_top(thr, 2);\n\tlen = duk__push_this_obj_len_u32(thr);\n\tduk_require_callable(thr, 0);\n\n\t/* stack[0] = callback fn\n\t * stack[1] = initialValue\n\t * stack[2] = object (coerced this)\n\t * stack[3] = length (not needed, but not popped above)\n\t * stack[4] = accumulator\n\t */\n\n\thave_acc = 0;\n\tif (nargs >= 2) {\n\t\tduk_dup_1(thr);\n\t\thave_acc = 1;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"have_acc=%ld, acc=%!T\",\n\t                     (long) have_acc, (duk_tval *) duk_get_tval(thr, 3)));\n\n\t/* For len == 0, i is initialized to len - 1 which underflows.\n\t * The condition (i < len) will then exit the for-loop on the\n\t * first round which is correct.  Similarly, loop termination\n\t * happens by i underflowing.\n\t */\n\n\tfor (i = (idx_step >= 0 ? 0 : len - 1);\n\t     i < len;  /* i >= 0 would always be true */\n\t     i += (duk_uint32_t) idx_step) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"i=%ld, len=%ld, have_acc=%ld, top=%ld, acc=%!T\",\n\t\t                     (long) i, (long) len, (long) have_acc,\n\t\t                     (long) duk_get_top(thr),\n\t\t                     (duk_tval *) duk_get_tval(thr, 4)));\n\n\t\tDUK_ASSERT((have_acc && duk_get_top(thr) == 5) ||\n\t\t           (!have_acc && duk_get_top(thr) == 4));\n\n\t\tif (!duk_has_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!have_acc) {\n\t\t\tDUK_ASSERT_TOP(thr, 4);\n\t\t\tduk_get_prop_index(thr, 2, (duk_uarridx_t) i);\n\t\t\thave_acc = 1;\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t} else {\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_dup(thr, 4);\n\t\t\tduk_get_prop_index(thr, 2, (duk_uarridx_t) i);\n\t\t\tduk_push_u32(thr, i);\n\t\t\tduk_dup_2(thr);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"calling reduce function: func=%!T, prev=%!T, curr=%!T, idx=%!T, obj=%!T\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -5), (duk_tval *) duk_get_tval(thr, -4),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -3), (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tduk_call(thr, 4);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> result: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tduk_replace(thr, 4);\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t}\n\t}\n\n\tif (!have_acc) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tDUK_ASSERT_TOP(thr, 5);\n\treturn 1;\n}\n\n#endif  /* DUK_USE_ARRAY_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_boolean.c",
    "content": "/*\n *  Boolean built-ins\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_BOOLEAN_BUILTIN)\n\n/* Shared helper to provide toString() and valueOf().  Checks 'this', gets\n * the primitive value to stack top, and optionally coerces with ToString().\n */\nDUK_INTERNAL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\tduk_small_int_t coerce_tostring = duk_get_current_magic(thr);\n\n\t/* XXX: there is room to use a shared helper here, many built-ins\n\t * check the 'this' type, and if it's an object, check its class,\n\t * then get its internal value, etc.\n\t */\n\n\tduk_push_this(thr);\n\ttv = duk_get_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_BOOLEAN(tv)) {\n\t\tgoto type_ok;\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_BOOLEAN) {\n\t\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t\t\tDUK_ASSERT(duk_is_boolean(thr, -1));\n\t\t\tgoto type_ok;\n\t\t}\n\t}\n\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t/* never here */\n\n type_ok:\n\tif (coerce_tostring) {\n\t\tduk_to_string(thr, -1);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_boolean_constructor(duk_hthread *thr) {\n\tduk_hobject *h_this;\n\n\tduk_to_boolean(thr, 0);\n\n\tif (duk_is_constructor_call(thr)) {\n\t\t/* XXX: helper; rely on Boolean.prototype as being non-writable, non-configurable */\n\t\tduk_push_this(thr);\n\t\th_this = duk_known_hobject(thr, -1);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE]);\n\n\t\tDUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_BOOLEAN);\n\n\t\tduk_dup_0(thr);  /* -> [ val obj val ] */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);  /* XXX: proper flags? */\n\t}  /* unbalanced stack */\n\n\treturn 1;\n}\n\n#endif  /* DUK_USE_BOOLEAN_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_buffer.c",
    "content": "/*\n *  ES2015 TypedArray and Node.js Buffer built-ins\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Helpers for buffer handling, enabled with DUK_USE_BUFFEROBJECT_SUPPORT.\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Map class number (minus DUK_HOBJECT_CLASS_BUFOBJ_MIN) to a bidx for the\n * default internal prototype.\n */\nstatic const duk_uint8_t duk__buffer_proto_from_classnum[] = {\n\tDUK_BIDX_ARRAYBUFFER_PROTOTYPE,\n\tDUK_BIDX_DATAVIEW_PROTOTYPE,\n\tDUK_BIDX_INT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE,\n\tDUK_BIDX_INT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_INT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT64ARRAY_PROTOTYPE\n};\n\n/* Map DUK_HBUFOBJ_ELEM_xxx to duk_hobject class number.\n * Sync with duk_hbufobj.h and duk_hobject.h.\n */\nstatic const duk_uint8_t duk__buffer_class_from_elemtype[9] = {\n\tDUK_HOBJECT_CLASS_UINT8ARRAY,\n\tDUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY,\n\tDUK_HOBJECT_CLASS_INT8ARRAY,\n\tDUK_HOBJECT_CLASS_UINT16ARRAY,\n\tDUK_HOBJECT_CLASS_INT16ARRAY,\n\tDUK_HOBJECT_CLASS_UINT32ARRAY,\n\tDUK_HOBJECT_CLASS_INT32ARRAY,\n\tDUK_HOBJECT_CLASS_FLOAT32ARRAY,\n\tDUK_HOBJECT_CLASS_FLOAT64ARRAY\n};\n\n/* Map DUK_HBUFOBJ_ELEM_xxx to prototype object built-in index.\n * Sync with duk_hbufobj.h.\n */\nstatic const duk_uint8_t duk__buffer_proto_from_elemtype[9] = {\n\tDUK_BIDX_UINT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE,\n\tDUK_BIDX_INT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_INT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_INT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT64ARRAY_PROTOTYPE\n};\n\n/* Map DUK__FLD_xxx to byte size. */\nstatic const duk_uint8_t duk__buffer_nbytes_from_fldtype[6] = {\n\t1,  /* DUK__FLD_8BIT */\n\t2,  /* DUK__FLD_16BIT */\n\t4,  /* DUK__FLD_32BIT */\n\t4,  /* DUK__FLD_FLOAT */\n\t8,  /* DUK__FLD_DOUBLE */\n\t0   /* DUK__FLD_VARINT; not relevant here */\n};\n\n/* Bitfield for each DUK_HBUFOBJ_ELEM_xxx indicating which element types\n * are compatible with a blind byte copy for the TypedArray set() method (also\n * used for TypedArray constructor).  Array index is target buffer elem type,\n * bitfield indicates compatible source types.  The types must have same byte\n * size and they must be coercion compatible.\n */\n#if !defined(DUK_USE_PREFER_SIZE)\nstatic duk_uint16_t duk__buffer_elemtype_copy_compatible[9] = {\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT8 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT8) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_UINT8CLAMPED) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT8),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT8CLAMPED\n\t * Note: INT8 is -not- copy compatible, e.g. -1 would coerce to 0x00.\n\t */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT8) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_UINT8CLAMPED),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_INT8 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT8) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_UINT8CLAMPED) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT8),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT16 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT16) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT16),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_INT16 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT16) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT16),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT32 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT32) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT32),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_INT32 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT32) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT32),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_FLOAT32 */\n\t(1U << DUK_HBUFOBJ_ELEM_FLOAT32),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_FLOAT64 */\n\t(1U << DUK_HBUFOBJ_ELEM_FLOAT64)\n};\n#endif  /* !DUK_USE_PREFER_SIZE */\n\nDUK_LOCAL duk_hbufobj *duk__hbufobj_promote_this(duk_hthread *thr) {\n\tduk_tval *tv_dst;\n\tduk_hbufobj *res;\n\n\tduk_push_this(thr);\n\tDUK_ASSERT(duk_is_buffer(thr, -1));\n\tres = (duk_hbufobj *) duk_to_hobject(thr, -1);\n\tDUK_HBUFOBJ_ASSERT_VALID(res);\n\tDUK_DD(DUK_DDPRINT(\"promoted 'this' automatically to an ArrayBuffer: %!iT\", duk_get_tval(thr, -1)));\n\n\ttv_dst = duk_get_borrowed_this_tval(thr);\n\tDUK_TVAL_SET_OBJECT_UPDREF(thr, tv_dst, (duk_hobject *) res);\n\tduk_pop(thr);\n\n\treturn res;\n}\n\n#define DUK__BUFOBJ_FLAG_THROW    (1 << 0)\n#define DUK__BUFOBJ_FLAG_PROMOTE  (1 << 1)\n\n/* Shared helper.  When DUK__BUFOBJ_FLAG_PROMOTE is given, the return value is\n * always a duk_hbufobj *.  Without the flag the return value can also be a\n * plain buffer, and the caller must check for it using DUK_HEAPHDR_IS_BUFFER().\n */\nDUK_LOCAL duk_heaphdr *duk__getrequire_bufobj_this(duk_hthread *thr, duk_small_uint_t flags) {\n\tduk_tval *tv;\n\tduk_hbufobj *h_this;\n\n\tDUK_ASSERT(thr != NULL);\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_this = (duk_hbufobj *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_this != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h_this)) {\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\t\t\treturn (duk_heaphdr *) h_this;\n\t\t}\n\t} else if (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tif (flags & DUK__BUFOBJ_FLAG_PROMOTE) {\n\t\t\t/* Promote a plain buffer to a Uint8Array.  This is very\n\t\t\t * inefficient but allows plain buffer to be used wherever an\n\t\t\t * Uint8Array is used with very small cost; hot path functions\n\t\t\t * like index read/write calls should provide direct buffer\n\t\t\t * support to avoid promotion.\n\t\t\t */\n\t\t\t/* XXX: make this conditional to a flag if call sites need it? */\n\t\t\th_this = duk__hbufobj_promote_this(thr);\n\t\t\tDUK_ASSERT(h_this != NULL);\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\t\t\treturn (duk_heaphdr *) h_this;\n\t\t} else {\n\t\t\t/* XXX: ugly, share return pointer for duk_hbuffer. */\n\t\t\treturn (duk_heaphdr *) DUK_TVAL_GET_BUFFER(tv);\n\t\t}\n\t}\n\n\tif (flags & DUK__BUFOBJ_FLAG_THROW) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_BUFFER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn NULL;\n}\n\n/* Check that 'this' is a duk_hbufobj and return a pointer to it. */\nDUK_LOCAL duk_hbufobj *duk__get_bufobj_this(duk_hthread *thr) {\n\treturn (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_PROMOTE);\n}\n\n/* Check that 'this' is a duk_hbufobj and return a pointer to it\n * (NULL if not).\n */\nDUK_LOCAL duk_hbufobj *duk__require_bufobj_this(duk_hthread *thr) {\n\treturn (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW | DUK__BUFOBJ_FLAG_PROMOTE);\n}\n\n/* Check that value is a duk_hbufobj and return a pointer to it. */\nDUK_LOCAL duk_hbufobj *duk__require_bufobj_value(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hbufobj *h_obj;\n\n\t/* Don't accept relative indices now. */\n\tDUK_ASSERT(idx >= 0);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_obj = (duk_hbufobj *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h_obj)) {\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_obj);\n\t\t\treturn h_obj;\n\t\t}\n\t} else if (DUK_TVAL_IS_BUFFER(tv)) {\n\t\th_obj = (duk_hbufobj *) duk_to_hobject(thr, idx);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tDUK_HBUFOBJ_ASSERT_VALID(h_obj);\n\t\treturn h_obj;\n\t}\n\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_BUFFER);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_LOCAL void duk__set_bufobj_buffer(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_hbuffer *h_val) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tDUK_ASSERT(h_bufobj->buf == NULL);  /* no need to decref */\n\tDUK_ASSERT(h_val != NULL);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\tDUK_UNREF(thr);\n\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\th_bufobj->length = (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_val);\n\tDUK_ASSERT(h_bufobj->shift == 0);\n\tDUK_ASSERT(h_bufobj->elem_type == DUK_HBUFOBJ_ELEM_UINT8);\n\tDUK_ASSERT(h_bufobj->is_typedarray == 0);\n\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n}\n\n/* Shared offset/length coercion helper. */\nDUK_LOCAL void duk__resolve_offset_opt_length(duk_hthread *thr,\n                                              duk_hbufobj *h_bufarg,\n                                              duk_idx_t idx_offset,\n                                              duk_idx_t idx_length,\n                                              duk_uint_t *out_offset,\n                                              duk_uint_t *out_length,\n                                              duk_bool_t throw_flag) {\n\tduk_int_t offset_signed;\n\tduk_int_t length_signed;\n\tduk_uint_t offset;\n\tduk_uint_t length;\n\n\toffset_signed = duk_to_int(thr, idx_offset);\n\tif (offset_signed < 0) {\n\t\tgoto fail_range;\n\t}\n\toffset = (duk_uint_t) offset_signed;\n\tif (offset > h_bufarg->length) {\n\t\tgoto fail_range;\n\t}\n\tDUK_ASSERT_DISABLE(offset >= 0);  /* unsigned */\n\tDUK_ASSERT(offset <= h_bufarg->length);\n\n\tif (duk_is_undefined(thr, idx_length)) {\n\t\tDUK_ASSERT(h_bufarg->length >= offset);\n\t\tlength = h_bufarg->length - offset;  /* >= 0 */\n\t} else {\n\t\tlength_signed = duk_to_int(thr, idx_length);\n\t\tif (length_signed < 0) {\n\t\t\tgoto fail_range;\n\t\t}\n\t\tlength = (duk_uint_t) length_signed;\n\t\tDUK_ASSERT(h_bufarg->length >= offset);\n\t\tif (length > h_bufarg->length - offset) {\n\t\t\t/* Unlike for negative arguments, some call sites\n\t\t\t * want length to be clamped if it's positive.\n\t\t\t */\n\t\t\tif (throw_flag) {\n\t\t\t\tgoto fail_range;\n\t\t\t} else {\n\t\t\t\tlength = h_bufarg->length - offset;\n\t\t\t}\n\t\t}\n\t}\n\tDUK_ASSERT_DISABLE(length >= 0);  /* unsigned */\n\tDUK_ASSERT(offset + length <= h_bufarg->length);\n\n\t*out_offset = offset;\n\t*out_length = length;\n\treturn;\n\n fail_range:\n\tDUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARGS);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Shared lenient buffer length clamping helper.  No negative indices, no\n * element/byte shifting.\n */\nDUK_LOCAL void duk__clamp_startend_nonegidx_noshift(duk_hthread *thr,\n                                                    duk_int_t buffer_length,\n                                                    duk_idx_t idx_start,\n                                                    duk_idx_t idx_end,\n                                                    duk_int_t *out_start_offset,\n                                                    duk_int_t *out_end_offset) {\n\tduk_int_t start_offset;\n\tduk_int_t end_offset;\n\n\tDUK_ASSERT(out_start_offset != NULL);\n\tDUK_ASSERT(out_end_offset != NULL);\n\n\t/* undefined coerces to zero which is correct */\n\tstart_offset = duk_to_int_clamped(thr, idx_start, 0, buffer_length);\n\tif (duk_is_undefined(thr, idx_end)) {\n\t\tend_offset = buffer_length;\n\t} else {\n\t\tend_offset = duk_to_int_clamped(thr, idx_end, start_offset, buffer_length);\n\t}\n\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(start_offset <= buffer_length);\n\tDUK_ASSERT(end_offset >= 0);\n\tDUK_ASSERT(end_offset <= buffer_length);\n\tDUK_ASSERT(start_offset <= end_offset);\n\n\t*out_start_offset = start_offset;\n\t*out_end_offset = end_offset;\n}\n\n/* Shared lenient buffer length clamping helper.  Indices are treated as\n * element indices (though output values are byte offsets) which only\n * really matters for TypedArray views as other buffer object have a zero\n * shift.  Negative indices are counted from end of input slice; crossed\n * indices are clamped to zero length; and final indices are clamped\n * against input slice.  Used for e.g. ArrayBuffer slice().\n */\nDUK_LOCAL void duk__clamp_startend_negidx_shifted(duk_hthread *thr,\n                                                  duk_int_t buffer_length,\n                                                  duk_uint8_t buffer_shift,\n                                                  duk_idx_t idx_start,\n                                                  duk_idx_t idx_end,\n                                                  duk_int_t *out_start_offset,\n                                                  duk_int_t *out_end_offset) {\n\tduk_int_t start_offset;\n\tduk_int_t end_offset;\n\n\tDUK_ASSERT(out_start_offset != NULL);\n\tDUK_ASSERT(out_end_offset != NULL);\n\n\tbuffer_length >>= buffer_shift;  /* as (full) elements */\n\n\t/* Resolve start/end offset as element indices first; arguments\n\t * at idx_start/idx_end are element offsets.  Working with element\n\t * indices first also avoids potential for wrapping.\n\t */\n\n\tstart_offset = duk_to_int(thr, idx_start);\n\tif (start_offset < 0) {\n\t\tstart_offset = buffer_length + start_offset;\n\t}\n\tif (duk_is_undefined(thr, idx_end)) {\n\t\tend_offset = buffer_length;\n\t} else {\n\t\tend_offset = duk_to_int(thr, idx_end);\n\t\tif (end_offset < 0) {\n\t\t\tend_offset = buffer_length + end_offset;\n\t\t}\n\t}\n\t/* Note: start_offset/end_offset can still be < 0 here. */\n\n\tif (start_offset < 0) {\n\t\tstart_offset = 0;\n\t} else if (start_offset > buffer_length) {\n\t\tstart_offset = buffer_length;\n\t}\n\tif (end_offset < start_offset) {\n\t\tend_offset = start_offset;\n\t} else if (end_offset > buffer_length) {\n\t\tend_offset = buffer_length;\n\t}\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(start_offset <= buffer_length);\n\tDUK_ASSERT(end_offset >= 0);\n\tDUK_ASSERT(end_offset <= buffer_length);\n\tDUK_ASSERT(start_offset <= end_offset);\n\n\t/* Convert indices to byte offsets. */\n\tstart_offset <<= buffer_shift;\n\tend_offset <<= buffer_shift;\n\n\t*out_start_offset = start_offset;\n\t*out_end_offset = end_offset;\n}\n\nDUK_INTERNAL void duk_hbufobj_promote_plain(duk_hthread *thr, duk_idx_t idx) {\n\tif (duk_is_buffer(thr, idx)) {\n\t\tduk_to_object(thr, idx);\n\t}\n}\n\nDUK_INTERNAL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_hbuffer *h_buf) {\n\t/* Push Uint8Array which will share the same underlying buffer as\n\t * the plain buffer argument.  Also create an ArrayBuffer with the\n\t * same backing for the result .buffer property.\n\t */\n\n\tduk_push_hbuffer(thr, h_buf);\n\tduk_push_buffer_object(thr, -1, 0, (duk_size_t) DUK_HBUFFER_GET_SIZE(h_buf), DUK_BUFOBJ_UINT8ARRAY);\n\tduk_remove_m2(thr);\n\n#if 0\n\t/* More verbose equivalent; maybe useful if e.g. .buffer is omitted. */\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_UINT8ARRAY),\n\t                               DUK_BIDX_UINT8ARRAY_PROTOTYPE);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tduk__set_bufobj_buffer(thr, h_bufobj, h_buf);\n\th_bufobj->is_typedarray = 1;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\th_arrbuf = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),\n\t                               DUK_BIDX_ARRAYBUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_arrbuf != NULL);\n\tduk__set_bufobj_buffer(thr, h_arrbuf, h_buf);\n\tDUK_ASSERT(h_arrbuf->is_typedarray == 0);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_arrbuf);\n\n\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\th_bufobj->buf_prop = (duk_hobject *) h_arrbuf;\n\tDUK_ASSERT(h_arrbuf != NULL);\n\tDUK_HBUFOBJ_INCREF(thr, h_arrbuf);\n\tduk_pop(thr);\n#endif\n}\n\n/* Indexed read helper for buffer objects, also called from outside this file. */\nDUK_INTERNAL void duk_hbufobj_push_validated_read(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size) {\n\tduk_double_union du;\n\n\tDUK_ASSERT(elem_size > 0);\n\tduk_memcpy((void *) du.uc, (const void *) p, (size_t) elem_size);\n\n\tswitch (h_bufobj->elem_type) {\n\tcase DUK_HBUFOBJ_ELEM_UINT8:\n\tcase DUK_HBUFOBJ_ELEM_UINT8CLAMPED:\n\t\tduk_push_uint(thr, (duk_uint_t) du.uc[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT8:\n\t\tduk_push_int(thr, (duk_int_t) (duk_int8_t) du.uc[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT16:\n\t\tduk_push_uint(thr, (duk_uint_t) du.us[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT16:\n\t\tduk_push_int(thr, (duk_int_t) (duk_int16_t) du.us[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT32:\n\t\tduk_push_uint(thr, (duk_uint_t) du.ui[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT32:\n\t\tduk_push_int(thr, (duk_int_t) (duk_int32_t) du.ui[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT32:\n\t\tduk_push_number(thr, (duk_double_t) du.f[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT64:\n\t\tduk_push_number(thr, (duk_double_t) du.d);\n\t\tbreak;\n\tdefault:\n\t\tDUK_UNREACHABLE();\n\t}\n}\n\n/* Indexed write helper for buffer objects, also called from outside this file. */\nDUK_INTERNAL void duk_hbufobj_validated_write(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size) {\n\tduk_double_union du;\n\n\t/* NOTE! Caller must ensure that any side effects from the\n\t * coercions below are safe.  If that cannot be guaranteed\n\t * (which is normally the case), caller must coerce the\n\t * argument using duk_to_number() before any pointer\n\t * validations; the result of duk_to_number() always coerces\n\t * without side effects here.\n\t */\n\n\tswitch (h_bufobj->elem_type) {\n\tcase DUK_HBUFOBJ_ELEM_UINT8:\n\t\tdu.uc[0] = (duk_uint8_t) duk_to_uint32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT8CLAMPED:\n\t\tdu.uc[0] = (duk_uint8_t) duk_to_uint8clamped(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT8:\n\t\tdu.uc[0] = (duk_uint8_t) duk_to_int32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT16:\n\t\tdu.us[0] = (duk_uint16_t) duk_to_uint32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT16:\n\t\tdu.us[0] = (duk_uint16_t) duk_to_int32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT32:\n\t\tdu.ui[0] = (duk_uint32_t) duk_to_uint32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT32:\n\t\tdu.ui[0] = (duk_uint32_t) duk_to_int32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT32:\n\t\t/* A double-to-float cast is undefined behavior in C99 if\n\t\t * the cast is out-of-range, so use a helper.  Example:\n\t\t * runtime error: value -1e+100 is outside the range of representable values of type 'float'\n\t\t */\n\t\tdu.f[0] = duk_double_to_float_t(duk_to_number_m1(thr));\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT64:\n\t\tdu.d = (duk_double_t) duk_to_number_m1(thr);\n\t\tbreak;\n\tdefault:\n\t\tDUK_UNREACHABLE();\n\t}\n\n\tDUK_ASSERT(elem_size > 0);\n\tduk_memcpy((void *) p, (const void *) du.uc, (size_t) elem_size);\n}\n\n/* Helper to create a fixed buffer from argument value at index 0.\n * Node.js and allocPlain() compatible.\n */\nDUK_LOCAL duk_hbuffer *duk__hbufobj_fixed_from_argvalue(duk_hthread *thr) {\n\tduk_int_t len;\n\tduk_int_t i;\n\tduk_size_t buf_size;\n\tduk_uint8_t *buf;\n\n\tswitch (duk_get_type(thr, 0)) {\n\tcase DUK_TYPE_NUMBER: {\n\t\tlen = duk_to_int_clamped(thr, 0, 0, DUK_INT_MAX);\n\t\t(void) duk_push_fixed_buffer_zero(thr, (duk_size_t) len);\n\t\tbreak;\n\t}\n\tcase DUK_TYPE_BUFFER: { /* Treat like Uint8Array. */\n\t\tgoto slow_copy;\n\t}\n\tcase DUK_TYPE_OBJECT: {\n\t\tduk_hobject *h;\n\t\tduk_hbufobj *h_bufobj;\n\n\t\t/* For Node.js Buffers \"Passing an ArrayBuffer returns a Buffer\n\t\t * that shares allocated memory with the given ArrayBuffer.\"\n\t\t * https://nodejs.org/api/buffer.html#buffer_buffer_from_buffer_alloc_and_buffer_allocunsafe\n\t\t */\n\n\t\th = duk_known_hobject(thr, 0);\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ(h));\n\t\t\th_bufobj = (duk_hbufobj *) h;\n\t\t\tif (DUK_UNLIKELY(h_bufobj->buf == NULL)) {\n\t\t\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(h_bufobj->offset != 0 || h_bufobj->length != DUK_HBUFFER_GET_SIZE(h_bufobj->buf))) {\n\t\t\t\t/* No support for ArrayBuffers with slice\n\t\t\t\t * offset/length.\n\t\t\t\t */\n\t\t\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t\t}\n\t\t\tduk_push_hbuffer(thr, h_bufobj->buf);\n\t\t\treturn h_bufobj->buf;\n\t\t}\n\t\tgoto slow_copy;\n\t}\n\tcase DUK_TYPE_STRING: {\n\t\t/* ignore encoding for now */\n\t\tduk_require_hstring_notsymbol(thr, 0);\n\t\tduk_dup_0(thr);\n\t\t(void) duk_to_buffer(thr, -1, &buf_size);\n\t\tbreak;\n\t}\n\tdefault:\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n done:\n\tDUK_ASSERT(duk_is_buffer(thr, -1));\n\treturn duk_known_hbuffer(thr, -1);\n\n slow_copy:\n\t/* XXX: fast path for typed arrays and other buffer objects? */\n\n\t(void) duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\tlen = duk_to_int_clamped(thr, -1, 0, DUK_INT_MAX);\n\tduk_pop(thr);\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) len);  /* no zeroing, all indices get initialized */\n\tfor (i = 0; i < len; i++) {\n\t\t/* XXX: fast path for array or buffer arguments? */\n\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);\n\t\tbuf[i] = (duk_uint8_t) (duk_to_uint32(thr, -1) & 0xffU);\n\t\tduk_pop(thr);\n\t}\n\tgoto done;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer constructor\n *\n *  Node.js Buffers are just Uint8Arrays with internal prototype set to\n *  Buffer.prototype so they're handled otherwise the same as Uint8Array.\n *  However, the constructor arguments are very different so a separate\n *  constructor entry point is used.\n */\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_hthread *thr) {\n\tduk_hbuffer *h_buf;\n\n\th_buf = duk__hbufobj_fixed_from_argvalue(thr);\n\tDUK_ASSERT(h_buf != NULL);\n\n\tduk_push_buffer_object(thr,\n\t                       -1,\n\t                       0,\n\t                       DUK_HBUFFER_FIXED_GET_SIZE((duk_hbuffer_fixed *) (void *) h_buf),\n\t                       DUK_BUFOBJ_UINT8ARRAY);\n\tduk_push_hobject_bidx(thr, DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);\n\tduk_set_prototype(thr, -2);\n\n\t/* XXX: a more direct implementation */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  ArrayBuffer, DataView, and TypedArray constructors\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_arraybuffer_constructor(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_int_t len;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tduk_require_constructor_call(thr);\n\n\tlen = duk_to_int(thr, 0);\n\tif (len < 0) {\n\t\tgoto fail_length;\n\t}\n\t(void) duk_push_fixed_buffer_zero(thr, (duk_size_t) len);\n\th_val = (duk_hbuffer *) duk_known_hbuffer(thr, -1);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),\n\t                               DUK_BIDX_ARRAYBUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_bufobj != NULL);\n\n\tduk__set_bufobj_buffer(thr, h_bufobj, h_val);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\treturn 1;\n\n fail_length:\n\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\n/* Format of magic, bits:\n *   0...1: elem size shift (0-3)\n *   2...5: elem type (DUK_HBUFOBJ_ELEM_xxx)\n *\n * XXX: add prototype bidx explicitly to magic instead of using a mapping?\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hobject *h_obj;\n\tduk_hbufobj *h_bufobj = NULL;\n\tduk_hbufobj *h_bufarg = NULL;\n\tduk_hbuffer *h_val;\n\tduk_small_uint_t magic;\n\tduk_small_uint_t shift;\n\tduk_small_uint_t elem_type;\n\tduk_small_uint_t elem_size;\n\tduk_small_uint_t class_num;\n\tduk_small_uint_t proto_bidx;\n\tduk_uint_t align_mask;\n\tduk_uint_t elem_length;\n\tduk_int_t elem_length_signed;\n\tduk_uint_t byte_length;\n\tduk_small_uint_t copy_mode;\n\n\t/* XXX: The same copy helpers could be shared with at least some\n\t * buffer functions.\n\t */\n\n\tduk_require_constructor_call(thr);\n\n\t/* We could fit built-in index into magic but that'd make the magic\n\t * number dependent on built-in numbering (genbuiltins.py doesn't\n\t * handle that yet).  So map both class and prototype from the\n\t * element type.\n\t */\n\tmagic = (duk_small_uint_t) duk_get_current_magic(thr);\n\tshift = magic & 0x03U;               /* bits 0...1: shift */\n\telem_type = (magic >> 2) & 0x0fU;    /* bits 2...5: type */\n\telem_size = 1U << shift;\n\talign_mask = elem_size - 1;\n\tDUK_ASSERT(elem_type < sizeof(duk__buffer_proto_from_elemtype) / sizeof(duk_uint8_t));\n\tproto_bidx = duk__buffer_proto_from_elemtype[elem_type];\n\tDUK_ASSERT(proto_bidx < DUK_NUM_BUILTINS);\n\tDUK_ASSERT(elem_type < sizeof(duk__buffer_class_from_elemtype) / sizeof(duk_uint8_t));\n\tclass_num = duk__buffer_class_from_elemtype[elem_type];\n\n\tDUK_DD(DUK_DDPRINT(\"typedarray constructor, magic=%d, shift=%d, elem_type=%d, \"\n\t                   \"elem_size=%d, proto_bidx=%d, class_num=%d\",\n\t                   (int) magic, (int) shift, (int) elem_type, (int) elem_size,\n\t                   (int) proto_bidx, (int) class_num));\n\n\t/* Argument variants.  When the argument is an ArrayBuffer a view to\n\t * the same buffer is created; otherwise a new ArrayBuffer is always\n\t * created.\n\t */\n\n\t/* XXX: initial iteration to treat a plain buffer like an ArrayBuffer:\n\t * coerce to an ArrayBuffer object and use that as .buffer.  The underlying\n\t * buffer will be the same but result .buffer !== inputPlainBuffer.\n\t */\n\tduk_hbufobj_promote_plain(thr, 0);\n\n\ttv = duk_get_tval(thr, 0);\n\tDUK_ASSERT(tv != NULL);  /* arg count */\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_obj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_obj != NULL);\n\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\t\t/* ArrayBuffer: unlike any other argument variant, create\n\t\t\t * a view into the existing buffer.\n\t\t\t */\n\n\t\t\tduk_int_t byte_offset_signed;\n\t\t\tduk_uint_t byte_offset;\n\n\t\t\th_bufarg = (duk_hbufobj *) h_obj;\n\n\t\t\tbyte_offset_signed = duk_to_int(thr, 1);\n\t\t\tif (byte_offset_signed < 0) {\n\t\t\t\tgoto fail_arguments;\n\t\t\t}\n\t\t\tbyte_offset = (duk_uint_t) byte_offset_signed;\n\t\t\tif (byte_offset > h_bufarg->length ||\n\t\t\t    (byte_offset & align_mask) != 0) {\n\t\t\t\t/* Must be >= 0 and multiple of element size. */\n\t\t\t\tgoto fail_arguments;\n\t\t\t}\n\t\t\tif (duk_is_undefined(thr, 2)) {\n\t\t\t\tDUK_ASSERT(h_bufarg->length >= byte_offset);\n\t\t\t\tbyte_length = h_bufarg->length - byte_offset;\n\t\t\t\tif ((byte_length & align_mask) != 0) {\n\t\t\t\t\t/* Must be element size multiple from\n\t\t\t\t\t * start offset to end of buffer.\n\t\t\t\t\t */\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t\telem_length = (byte_length >> shift);\n\t\t\t} else {\n\t\t\t\telem_length_signed = duk_to_int(thr, 2);\n\t\t\t\tif (elem_length_signed < 0) {\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t\telem_length = (duk_uint_t) elem_length_signed;\n\t\t\t\tbyte_length = elem_length << shift;\n\t\t\t\tif ((byte_length >> shift) != elem_length) {\n\t\t\t\t\t/* Byte length would overflow. */\n\t\t\t\t\t/* XXX: easier check with less code? */\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(h_bufarg->length >= byte_offset);\n\t\t\t\tif (byte_length > h_bufarg->length - byte_offset) {\n\t\t\t\t\t/* Not enough data. */\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t}\n\t\t\tDUK_UNREF(elem_length);\n\t\t\tDUK_ASSERT_DISABLE(byte_offset >= 0);\n\t\t\tDUK_ASSERT(byte_offset <= h_bufarg->length);\n\t\t\tDUK_ASSERT_DISABLE(byte_length >= 0);\n\t\t\tDUK_ASSERT(byte_offset + byte_length <= h_bufarg->length);\n\t\t\tDUK_ASSERT((elem_length << shift) == byte_length);\n\n\t\t\th_bufobj = duk_push_bufobj_raw(thr,\n\t\t\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t\t\t                               DUK_HOBJECT_CLASS_AS_FLAGS(class_num),\n\t\t\t                               (duk_small_int_t) proto_bidx);\n\t\t\th_val = h_bufarg->buf;\n\t\t\tif (h_val == NULL) {\n\t\t\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t}\n\t\t\th_bufobj->buf = h_val;\n\t\t\tDUK_HBUFFER_INCREF(thr, h_val);\n\t\t\th_bufobj->offset = h_bufarg->offset + byte_offset;\n\t\t\th_bufobj->length = byte_length;\n\t\t\th_bufobj->shift = (duk_uint8_t) shift;\n\t\t\th_bufobj->elem_type = (duk_uint8_t) elem_type;\n\t\t\th_bufobj->is_typedarray = 1;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t\t\t/* Set .buffer to the argument ArrayBuffer. */\n\t\t\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\t\t\th_bufobj->buf_prop = (duk_hobject *) h_bufarg;\n\t\t\tDUK_ASSERT(h_bufarg != NULL);\n\t\t\tDUK_HBUFOBJ_INCREF(thr, h_bufarg);\n\t\t\treturn 1;\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\t/* TypedArray (or other non-ArrayBuffer duk_hbufobj).\n\t\t\t * Conceptually same behavior as for an Array-like argument,\n\t\t\t * with a few fast paths.\n\t\t\t */\n\n\t\t\th_bufarg = (duk_hbufobj *) h_obj;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufarg);\n\t\t\telem_length_signed = (duk_int_t) (h_bufarg->length >> h_bufarg->shift);\n\t\t\tif (h_bufarg->buf == NULL) {\n\t\t\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t}\n\n\t\t\t/* Select copy mode.  Must take into account element\n\t\t\t * compatibility and validity of the underlying source\n\t\t\t * buffer.\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"selecting copy mode for bufobj arg, \"\n\t\t\t                     \"src byte_length=%ld, src shift=%d, \"\n\t\t\t                     \"src/dst elem_length=%ld; \"\n\t\t\t                     \"dst shift=%d -> dst byte_length=%ld\",\n\t\t\t                     (long) h_bufarg->length, (int) h_bufarg->shift,\n\t\t\t                     (long) elem_length_signed, (int) shift,\n\t\t\t                     (long) (elem_length_signed << shift)));\n\n\t\t\tcopy_mode = 2;  /* default is explicit index read/write copy */\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t/* With a size optimized build copy_mode 2 is enough.\n\t\t\t * Modes 0 and 1 are faster but conceptually the same.\n\t\t\t */\n\t\t\tDUK_ASSERT(elem_type < sizeof(duk__buffer_elemtype_copy_compatible) / sizeof(duk_uint16_t));\n\t\t\tif (DUK_HBUFOBJ_VALID_SLICE(h_bufarg)) {\n\t\t\t\tif ((duk__buffer_elemtype_copy_compatible[elem_type] & (1 << h_bufarg->elem_type)) != 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"source/target are copy compatible, memcpy\"));\n\t\t\t\t\tDUK_ASSERT(shift == h_bufarg->shift);  /* byte sizes will match */\n\t\t\t\t\tcopy_mode = 0;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"source/target not copy compatible but valid, fast copy\"));\n\t\t\t\t\tcopy_mode = 1;\n\t\t\t\t}\n\t\t\t}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\t\t} else {\n\t\t\t/* Array or Array-like */\n\t\t\telem_length_signed = (duk_int_t) duk_get_length(thr, 0);\n\t\t\tcopy_mode = 2;\n\t\t}\n\t} else {\n\t\t/* Non-object argument is simply int coerced, matches\n\t\t * V8 behavior (except for \"null\", which we coerce to\n\t\t * 0 but V8 TypeErrors).\n\t\t */\n\t\telem_length_signed = duk_to_int(thr, 0);\n\t\tcopy_mode = 3;\n\t}\n\tif (elem_length_signed < 0) {\n\t\tgoto fail_arguments;\n\t}\n\telem_length = (duk_uint_t) elem_length_signed;\n\tbyte_length = (duk_uint_t) (elem_length << shift);\n\tif ((byte_length >> shift) != elem_length) {\n\t\t/* Byte length would overflow. */\n\t\t/* XXX: easier check with less code? */\n\t\tgoto fail_arguments;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"elem_length=%ld, byte_length=%ld\",\n\t                     (long) elem_length, (long) byte_length));\n\n\t/* ArrayBuffer argument is handled specially above; the rest of the\n\t * argument variants are handled by shared code below.\n\t *\n\t * ArrayBuffer in h_bufobj->buf_prop is intentionally left unset.\n\t * It will be automatically created by the .buffer accessor on\n\t * first access.\n\t */\n\n\t/* Push the resulting view object on top of a plain fixed buffer. */\n\t(void) duk_push_fixed_buffer(thr, byte_length);\n\th_val = duk_known_hbuffer(thr, -1);\n\tDUK_ASSERT(h_val != NULL);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(class_num),\n\t                               (duk_small_int_t) proto_bidx);\n\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\tDUK_ASSERT(h_bufobj->offset == 0);\n\th_bufobj->length = byte_length;\n\th_bufobj->shift = (duk_uint8_t) shift;\n\th_bufobj->elem_type = (duk_uint8_t) elem_type;\n\th_bufobj->is_typedarray = 1;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t/* Copy values, the copy method depends on the arguments.\n\t *\n\t * Copy mode decision may depend on the validity of the underlying\n\t * buffer of the source argument; there must be no harmful side effects\n\t * from there to here for copy_mode to still be valid.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"copy mode: %d\", (int) copy_mode));\n\tswitch (copy_mode) {\n\t\t/* Copy modes 0 and 1 can be omitted in size optimized build,\n\t\t * copy mode 2 handles them (but more slowly).\n\t\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tcase 0: {\n\t\t/* Use byte copy. */\n\n\t\tduk_uint8_t *p_src;\n\t\tduk_uint8_t *p_dst;\n\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\t\tDUK_ASSERT(h_bufobj->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufobj));\n\t\tDUK_ASSERT(h_bufarg != NULL);\n\t\tDUK_ASSERT(h_bufarg->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufarg));\n\n\t\tp_dst = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj);\n\t\tp_src = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using memcpy: p_src=%p, p_dst=%p, byte_length=%ld\",\n\t\t                     (void *) p_src, (void *) p_dst, (long) byte_length));\n\n\t\tduk_memcpy_unsafe((void *) p_dst, (const void *) p_src, (size_t) byte_length);\n\t\tbreak;\n\t}\n\tcase 1: {\n\t\t/* Copy values through direct validated reads and writes. */\n\n\t\tduk_small_uint_t src_elem_size;\n\t\tduk_small_uint_t dst_elem_size;\n\t\tduk_uint8_t *p_src;\n\t\tduk_uint8_t *p_src_end;\n\t\tduk_uint8_t *p_dst;\n\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\t\tDUK_ASSERT(h_bufobj->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufobj));\n\t\tDUK_ASSERT(h_bufarg != NULL);\n\t\tDUK_ASSERT(h_bufarg->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufarg));\n\n\t\tsrc_elem_size = (duk_small_uint_t) (1U << h_bufarg->shift);\n\t\tdst_elem_size = elem_size;\n\n\t\tp_src = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg);\n\t\tp_dst = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj);\n\t\tp_src_end = p_src + h_bufarg->length;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using fast copy: p_src=%p, p_src_end=%p, p_dst=%p, \"\n\t\t                     \"src_elem_size=%d, dst_elem_size=%d\",\n\t\t                     (void *) p_src, (void *) p_src_end, (void *) p_dst,\n\t\t                     (int) src_elem_size, (int) dst_elem_size));\n\n\t\twhile (p_src != p_src_end) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path per element copy loop: \"\n\t\t\t                     \"p_src=%p, p_src_end=%p, p_dst=%p\",\n\t\t\t                     (void *) p_src, (void *) p_src_end, (void *) p_dst));\n\t\t\t/* A validated read() is always a number, so it's write coercion\n\t\t\t * is always side effect free an won't invalidate pointers etc.\n\t\t\t */\n\t\t\tduk_hbufobj_push_validated_read(thr, h_bufarg, p_src, src_elem_size);\n\t\t\tduk_hbufobj_validated_write(thr, h_bufobj, p_dst, dst_elem_size);\n\t\t\tduk_pop(thr);\n\t\t\tp_src += src_elem_size;\n\t\t\tp_dst += dst_elem_size;\n\t\t}\n\t\tbreak;\n\t}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\tcase 2: {\n\t\t/* Copy values by index reads and writes.  Let virtual\n\t\t * property handling take care of coercion.\n\t\t */\n\t\tduk_uint_t i;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using slow copy\"));\n\n\t\tfor (i = 0; i < elem_length; i++) {\n\t\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);\n\t\t\tduk_put_prop_index(thr, -2, (duk_uarridx_t) i);\n\t\t}\n\t\tbreak;\n\t}\n\tdefault:\n\tcase 3: {\n\t\t/* No copy, leave zero bytes in the buffer.  There's no\n\t\t * ambiguity with Float32/Float64 because zero bytes also\n\t\t * represent 0.0.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using no copy\"));\n\t\tbreak;\n\t}\n\t}\n\n\treturn 1;\n\n fail_arguments:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n/* When bufferobject support is disabled, new Uint8Array() could still be\n * supported to create a plain fixed buffer.  Disabled for now.\n */\n#if 0\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) {\n\tduk_int_t elem_length_signed;\n\tduk_uint_t byte_length;\n\n\t/* XXX: The same copy helpers could be shared with at least some\n\t * buffer functions.\n\t */\n\n\tduk_require_constructor_call(thr);\n\n\telem_length_signed = duk_require_int(thr, 0);\n\tif (elem_length_signed < 0) {\n\t\tgoto fail_arguments;\n\t}\n\tbyte_length = (duk_uint_t) elem_length_signed;\n\n\t(void) duk_push_fixed_buffer_zero(thr, (duk_size_t) byte_length);\n\treturn 1;\n\n fail_arguments:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* 0 */\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_dataview_constructor(duk_hthread *thr) {\n\tduk_hbufobj *h_bufarg;\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_uint_t offset;\n\tduk_uint_t length;\n\n\tduk_require_constructor_call(thr);\n\n\th_bufarg = duk__require_bufobj_value(thr, 0);\n\tDUK_ASSERT(h_bufarg != NULL);\n\tif (DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *) h_bufarg) != DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tduk__resolve_offset_opt_length(thr, h_bufarg, 1, 2, &offset, &length, 1 /*throw_flag*/);\n\tDUK_ASSERT(offset <= h_bufarg->length);\n\tDUK_ASSERT(offset + length <= h_bufarg->length);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATAVIEW),\n\t                               DUK_BIDX_DATAVIEW_PROTOTYPE);\n\n\th_val = h_bufarg->buf;\n\tif (h_val == NULL) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\th_bufobj->offset = h_bufarg->offset + offset;\n\th_bufobj->length = length;\n\tDUK_ASSERT(h_bufobj->shift == 0);\n\tDUK_ASSERT(h_bufobj->elem_type == DUK_HBUFOBJ_ELEM_UINT8);\n\tDUK_ASSERT(h_bufobj->is_typedarray == 0);\n\n\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\th_bufobj->buf_prop = (duk_hobject *) h_bufarg;\n\tDUK_ASSERT(h_bufarg != NULL);\n\tDUK_HBUFOBJ_INCREF(thr, h_bufarg);\n\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  ArrayBuffer.isView()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_arraybuffer_isview(duk_hthread *thr) {\n\tduk_hobject *h_obj;\n\tduk_bool_t ret = 0;\n\n\tif (duk_is_buffer(thr, 0)) {\n\t\tret = 1;\n\t} else {\n\t\th_obj = duk_get_hobject(thr, 0);\n\t\tif (h_obj != NULL && DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\t/* DataView needs special casing: ArrayBuffer.isView() is\n\t\t\t * true, but ->is_typedarray is 0.\n\t\t\t */\n\t\t\tret = ((duk_hbufobj *) h_obj)->is_typedarray ||\n\t\t\t      (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_DATAVIEW);\n\t\t}\n\t}\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Uint8Array.allocPlain()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_uint8array_allocplain(duk_hthread *thr) {\n\tduk__hbufobj_fixed_from_argvalue(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Uint8Array.plainOf()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_uint8array_plainof(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\t/* Avoid churn if argument is already a plain buffer. */\n\tif (duk_is_buffer(thr, 0)) {\n\t\treturn 1;\n\t}\n#endif\n\n\t/* Promotes plain buffers to ArrayBuffers, so for a plain buffer\n\t * argument we'll create a pointless temporary (but still work\n\t * correctly).\n\t */\n\th_bufobj = duk__require_bufobj_value(thr, 0);\n\tif (h_bufobj->buf == NULL) {\n\t\tduk_push_undefined(thr);\n\t} else {\n\t\tduk_push_hbuffer(thr, h_bufobj->buf);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer: toString([encoding], [start], [end])\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_int_t start_offset, end_offset;\n\tduk_uint8_t *buf_slice;\n\tduk_size_t slice_length;\n\n\th_this = duk__get_bufobj_this(thr);\n\tif (h_this == NULL) {\n\t\t/* XXX: happens e.g. when evaluating: String(Buffer.prototype). */\n\t\tduk_push_literal(thr, \"[object Object]\");\n\t\treturn 1;\n\t}\n\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\n\t/* Ignore encoding for now. */\n\n\tduk__clamp_startend_nonegidx_noshift(thr,\n\t                                     (duk_int_t) h_this->length,\n\t                                     1 /*idx_start*/,\n\t                                     2 /*idx_end*/,\n\t                                     &start_offset,\n\t                                     &end_offset);\n\n\tslice_length = (duk_size_t) (end_offset - start_offset);\n\tbuf_slice = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, slice_length);  /* all bytes initialized below */\n\tDUK_ASSERT(buf_slice != NULL);\n\n\t/* Neutered or uncovered, TypeError. */\n\tif (h_this->buf == NULL ||\n\t    !DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, (duk_size_t) start_offset + slice_length)) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* XXX: ideally we wouldn't make a copy but a view into the buffer for the\n\t * decoding process.  Or the decoding helper could be changed to accept\n\t * the slice info (a buffer pointer is NOT a good approach because guaranteeing\n\t * its stability is difficult).\n\t */\n\n\tDUK_ASSERT(DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, (duk_size_t) start_offset + slice_length));\n\tduk_memcpy_unsafe((void *) buf_slice,\n\t                  (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + start_offset),\n\t                  (size_t) slice_length);\n\n\t/* Use the equivalent of: new TextEncoder().encode(this) to convert the\n\t * string.  Result will be valid UTF-8; non-CESU-8 inputs are currently\n\t * interpreted loosely.  Value stack convention is a bit odd for now.\n\t */\n\tduk_replace(thr, 0);\n\tduk_set_top(thr, 1);\n\treturn duk_textdecoder_decode_utf8_nodejs(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype: toJSON()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_uint8_t *buf;\n\tduk_uint_t i, n;\n\tduk_tval *tv;\n\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\n\tif (h_this->buf == NULL || !DUK_HBUFOBJ_VALID_SLICE(h_this)) {\n\t\t/* Serialize uncovered backing buffer as a null; doesn't\n\t\t * really matter as long we're memory safe.\n\t\t */\n\t\tduk_push_null(thr);\n\t\treturn 1;\n\t}\n\n\tduk_push_object(thr);\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_BUFFER);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_TYPE);\n\n\t/* XXX: uninitialized would be OK */\n\tDUK_ASSERT_DISABLE((duk_size_t) h_this->length <= (duk_size_t) DUK_UINT32_MAX);\n\ttv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) h_this->length);  /* XXX: needs revision with >4G buffers */\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\tDUK_ASSERT(h_this->buf != NULL);\n\tbuf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this);\n\tfor (i = 0, n = h_this->length; i < n; i++) {\n\t\tDUK_TVAL_SET_U32(tv + i, (duk_uint32_t) buf[i]);  /* no need for decref or incref */\n\t}\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_DATA);\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.equals()\n *  Node.js Buffer.prototype.compare()\n *  Node.js Buffer.compare()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_buffer_compare_shared(duk_hthread *thr) {\n\tduk_small_uint_t magic;\n\tduk_hbufobj *h_bufarg1;\n\tduk_hbufobj *h_bufarg2;\n\tduk_small_int_t comp_res;\n\n\t/* XXX: keep support for plain buffers and non-Node.js buffers? */\n\n\tmagic = (duk_small_uint_t) duk_get_current_magic(thr);\n\tif (magic & 0x02U) {\n\t\t/* Static call style. */\n\t\th_bufarg1 = duk__require_bufobj_value(thr, 0);\n\t\th_bufarg2 = duk__require_bufobj_value(thr, 1);\n\t} else {\n\t\th_bufarg1 = duk__require_bufobj_this(thr);\n\t\th_bufarg2 = duk__require_bufobj_value(thr, 0);\n\t}\n\tDUK_ASSERT(h_bufarg1 != NULL);\n\tDUK_ASSERT(h_bufarg2 != NULL);\n\n\t/* We want to compare the slice/view areas of the arguments.\n\t * If either slice/view is invalid (underlying buffer is shorter)\n\t * ensure equals() is false, but otherwise the only thing that\n\t * matters is to be memory safe.\n\t */\n\n\tif (DUK_HBUFOBJ_VALID_SLICE(h_bufarg1) &&\n\t    DUK_HBUFOBJ_VALID_SLICE(h_bufarg2)) {\n\t\tcomp_res = duk_js_data_compare((const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufarg1->buf) + h_bufarg1->offset,\n\t\t                               (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufarg2->buf) + h_bufarg2->offset,\n\t\t                               (duk_size_t) h_bufarg1->length,\n\t\t                               (duk_size_t) h_bufarg2->length);\n\t} else {\n\t\tcomp_res = -1;  /* either nonzero value is ok */\n\t}\n\n\tif (magic & 0x01U) {\n\t\t/* compare: similar to string comparison but for buffer data. */\n\t\tduk_push_int(thr, comp_res);\n\t} else {\n\t\t/* equals */\n\t\tduk_push_boolean(thr, (comp_res == 0));\n\t}\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.fill()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tconst duk_uint8_t *fill_str_ptr;\n\tduk_size_t fill_str_len;\n\tduk_uint8_t fill_value;\n\tduk_int_t fill_offset;\n\tduk_int_t fill_end;\n\tduk_size_t fill_length;\n\tduk_uint8_t *p;\n\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\tif (h_this->buf == NULL) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* [ value offset end ] */\n\n\tif (duk_is_string_notsymbol(thr, 0)) {\n\t\tfill_str_ptr = (const duk_uint8_t *) duk_get_lstring(thr, 0, &fill_str_len);\n\t\tDUK_ASSERT(fill_str_ptr != NULL);\n\t} else {\n\t\t/* Symbols get ToNumber() coerced and cause TypeError. */\n\t\tfill_value = (duk_uint8_t) duk_to_uint32(thr, 0);\n\t\tfill_str_ptr = (const duk_uint8_t *) &fill_value;\n\t\tfill_str_len = 1;\n\t}\n\n\t/* Fill offset handling is more lenient than in Node.js. */\n\n\tduk__clamp_startend_nonegidx_noshift(thr,\n\t                                     (duk_int_t) h_this->length,\n\t                                     1 /*idx_start*/,\n\t                                     2 /*idx_end*/,\n\t                                     &fill_offset,\n\t                                     &fill_end);\n\n\tDUK_DDD(DUK_DDDPRINT(\"fill: fill_value=%02x, fill_offset=%ld, fill_end=%ld, view length=%ld\",\n\t                     (unsigned int) fill_value, (long) fill_offset, (long) fill_end, (long) h_this->length));\n\n\tDUK_ASSERT(fill_end - fill_offset >= 0);\n\tDUK_ASSERT(h_this->buf != NULL);\n\n\tp = (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + fill_offset);\n\tfill_length = (duk_size_t) (fill_end - fill_offset);\n\tif (fill_str_len == 1) {\n\t\t/* Handle single character fills as memset() even when\n\t\t * the fill data comes from a one-char argument.\n\t\t */\n\t\tduk_memset_unsafe((void *) p, (int) fill_str_ptr[0], (size_t) fill_length);\n\t} else if (fill_str_len > 1) {\n\t\tduk_size_t i, n, t;\n\n\t\tfor (i = 0, n = (duk_size_t) (fill_end - fill_offset), t = 0; i < n; i++) {\n\t\t\tp[i] = fill_str_ptr[t++];\n\t\t\tif (t >= fill_str_len) {\n\t\t\t\tt = 0;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"zero size fill pattern, ignore silently\"));\n\t}\n\n\t/* Return the Buffer to allow chaining: b.fill(0x11).fill(0x22, 3, 5).toString() */\n\tduk_push_this(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.write(string, [offset], [length], [encoding])\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_write(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_uint_t offset;\n\tduk_uint_t length;\n\tconst duk_uint8_t *str_data;\n\tduk_size_t str_len;\n\n\t/* XXX: very inefficient support for plain buffers */\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\n\t/* Argument must be a string, e.g. a buffer is not allowed. */\n\tstr_data = (const duk_uint8_t *) duk_require_lstring_notsymbol(thr, 0, &str_len);\n\n\tduk__resolve_offset_opt_length(thr, h_this, 1, 2, &offset, &length, 0 /*throw_flag*/);\n\tDUK_ASSERT(offset <= h_this->length);\n\tDUK_ASSERT(offset + length <= h_this->length);\n\n\t/* XXX: encoding is ignored now. */\n\n\tif (length > str_len) {\n\t\tlength = (duk_uint_t) str_len;\n\t}\n\n\tif (DUK_HBUFOBJ_VALID_SLICE(h_this)) {\n\t\t/* Cannot overlap. */\n\t\tduk_memcpy_unsafe((void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + offset),\n\t\t                  (const void *) str_data,\n\t\t                  (size_t) length);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"write() target buffer is not covered, silent ignore\"));\n\t}\n\n\tduk_push_uint(thr, length);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.copy()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_hbufobj *h_bufarg;\n\tduk_int_t source_length;\n\tduk_int_t target_length;\n\tduk_int_t target_start, source_start, source_end;\n\tduk_uint_t target_ustart, source_ustart, source_uend;\n\tduk_uint_t copy_size = 0;\n\n\t/* [ targetBuffer targetStart sourceStart sourceEnd ] */\n\n\th_this = duk__require_bufobj_this(thr);\n\th_bufarg = duk__require_bufobj_value(thr, 0);\n\tDUK_ASSERT(h_this != NULL);\n\tDUK_ASSERT(h_bufarg != NULL);\n\tsource_length = (duk_int_t) h_this->length;\n\ttarget_length = (duk_int_t) h_bufarg->length;\n\n\ttarget_start = duk_to_int(thr, 1);\n\tsource_start = duk_to_int(thr, 2);\n\tif (duk_is_undefined(thr, 3)) {\n\t\tsource_end = source_length;\n\t} else {\n\t\tsource_end = duk_to_int(thr, 3);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"checking copy args: target_start=%ld, target_length=%ld, \"\n\t                     \"source_start=%ld, source_end=%ld, source_length=%ld\",\n\t                     (long) target_start, (long) h_bufarg->length,\n\t                     (long) source_start, (long) source_end, (long) source_length));\n\n\t/* This behavior mostly mimics Node.js now. */\n\n\tif (source_start < 0 || source_end < 0 || target_start < 0) {\n\t\t/* Negative offsets cause a RangeError. */\n\t\tgoto fail_bounds;\n\t}\n\tsource_ustart = (duk_uint_t) source_start;\n\tsource_uend = (duk_uint_t) source_end;\n\ttarget_ustart = (duk_uint_t) target_start;\n\tif (source_ustart >= source_uend ||  /* crossed offsets or zero size */\n\t    source_ustart >= (duk_uint_t) source_length ||  /* source out-of-bounds (but positive) */\n\t    target_ustart >= (duk_uint_t) target_length) {  /* target out-of-bounds (but positive) */\n\t\tgoto silent_ignore;\n\t}\n\tif (source_uend >= (duk_uint_t) source_length) {\n\t\t/* Source end clamped silently to available length. */\n\t\tsource_uend = (duk_uint_t) source_length;\n\t}\n\tcopy_size = source_uend - source_ustart;\n\tif (target_ustart + copy_size > (duk_uint_t) target_length) {\n\t\t/* Clamp to target's end if too long.\n\t\t *\n\t\t * NOTE: there's no overflow possibility in the comparison;\n\t\t * both target_ustart and copy_size are >= 0 and based on\n\t\t * values in duk_int_t range.  Adding them as duk_uint_t\n\t\t * values is then guaranteed not to overflow.\n\t\t */\n\t\tDUK_ASSERT(target_ustart + copy_size >= target_ustart);  /* no overflow */\n\t\tDUK_ASSERT(target_ustart + copy_size >= copy_size);  /* no overflow */\n\t\tcopy_size = (duk_uint_t) target_length - target_ustart;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"making copy: target_ustart=%lu source_ustart=%lu copy_size=%lu\",\n\t                     (unsigned long) target_ustart, (unsigned long) source_ustart,\n\t                     (unsigned long) copy_size));\n\n\tDUK_ASSERT(copy_size >= 1);\n\tDUK_ASSERT(source_ustart <= (duk_uint_t) source_length);\n\tDUK_ASSERT(source_ustart + copy_size <= (duk_uint_t) source_length);\n\tDUK_ASSERT(target_ustart <= (duk_uint_t) target_length);\n\tDUK_ASSERT(target_ustart + copy_size <= (duk_uint_t) target_length);\n\n\t/* Ensure copy is covered by underlying buffers. */\n\tDUK_ASSERT(h_bufarg->buf != NULL);  /* length check */\n\tDUK_ASSERT(h_this->buf != NULL);    /* length check */\n\tif (DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufarg, target_ustart + copy_size) &&\n\t    DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, source_ustart + copy_size)) {\n\t\t/* Must use memmove() because copy area may overlap (source and target\n\t\t * buffer may be the same, or from different slices.\n\t\t */\n\t\tduk_memmove_unsafe((void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg) + target_ustart),\n\t\t                   (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + source_ustart),\n\t\t                   (size_t) copy_size);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"buffer copy not covered by underlying buffer(s), ignoring\"));\n\t}\n\n silent_ignore:\n\t/* Return value is like write(), number of bytes written.\n\t * The return value matters because of code like:\n\t * \"off += buf.copy(...)\".\n         */\n\tduk_push_uint(thr, copy_size);\n\treturn 1;\n\n fail_bounds:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  TypedArray.prototype.set()\n *\n *  TypedArray set() is pretty interesting to implement because:\n *\n *    - The source argument may be a plain array or a typedarray.  If the\n *      source is a TypedArray, values are decoded and re-encoded into the\n *      target (not as a plain byte copy).  This may happen even when the\n *      element byte size is the same, e.g. integer values may be re-encoded\n *      into floats.\n *\n *    - Source and target may refer to the same underlying buffer, so that\n *      the set() operation may overlap.  The specification requires that this\n *      must work as if a copy was made before the operation.  Note that this\n *      is NOT a simple memmove() situation because the source and target\n *      byte sizes may be different -- e.g. a 4-byte source (Int8Array) may\n *      expand to a 16-byte target (Uint32Array) so that the target overlaps\n *      the source both from beginning and the end (unlike in typical memmove).\n *\n *    - Even if 'buf' pointers of the source and target differ, there's no\n *      guarantee that their memory areas don't overlap.  This may be the\n *      case with external buffers.\n *\n *  Even so, it is nice to optimize for the common case:\n *\n *    - Source and target separate buffers or non-overlapping.\n *\n *    - Source and target have a compatible type so that a plain byte copy\n *      is possible.  Note that while e.g. uint8 and int8 are compatible\n *      (coercion one way or another doesn't change the byte representation),\n *      e.g. int8 and uint8clamped are NOT compatible when writing int8\n *      values into uint8clamped typedarray (-1 would clamp to 0 for instance).\n *\n *  See test-bi-typedarray-proto-set.js.\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_hobject *h_obj;\n\tduk_uarridx_t i, n;\n\tduk_int_t offset_signed;\n\tduk_uint_t offset_elems;\n\tduk_uint_t offset_bytes;\n\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\n\tif (h_this->buf == NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"source neutered, skip copy\"));\n\t\treturn 0;\n\t}\n\n\tduk_hbufobj_promote_plain(thr, 0);\n\th_obj = duk_require_hobject(thr, 0);\n\n\t/* XXX: V8 throws a TypeError for negative values.  Would it\n\t * be more useful to interpret negative offsets here from the\n\t * end of the buffer too?\n\t */\n\toffset_signed = duk_to_int(thr, 1);\n\tif (offset_signed < 0) {\n\t\t/* For some reason this is a TypeError (at least in V8). */\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\toffset_elems = (duk_uint_t) offset_signed;\n\toffset_bytes = offset_elems << h_this->shift;\n\tif ((offset_bytes >> h_this->shift) != offset_elems) {\n\t\t/* Byte length would overflow. */\n\t\t/* XXX: easier check with less code? */\n\t\tgoto fail_args;\n\t}\n\tif (offset_bytes > h_this->length) {\n\t\t/* Equality may be OK but >length not.  Checking\n\t\t * this explicitly avoids some overflow cases\n\t\t * below.\n\t\t */\n\t\tgoto fail_args;\n\t}\n\tDUK_ASSERT(offset_bytes <= h_this->length);\n\n\t/* Fast path: source is a TypedArray (or any bufobj). */\n\n\tif (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\tduk_hbufobj *h_bufarg;\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\tduk_uint16_t comp_mask;\n#endif\n\t\tduk_small_int_t no_overlap = 0;\n\t\tduk_uint_t src_length;\n\t\tduk_uint_t dst_length;\n\t\tduk_uint_t dst_length_elems;\n\t\tduk_uint8_t *p_src_base;\n\t\tduk_uint8_t *p_src_end;\n\t\tduk_uint8_t *p_src;\n\t\tduk_uint8_t *p_dst_base;\n\t\tduk_uint8_t *p_dst;\n\t\tduk_small_uint_t src_elem_size;\n\t\tduk_small_uint_t dst_elem_size;\n\n\t\th_bufarg = (duk_hbufobj *) h_obj;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufarg);\n\n\t\tif (h_bufarg->buf == NULL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"target neutered, skip copy\"));\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* Nominal size check. */\n\t\tsrc_length = h_bufarg->length;  /* bytes in source */\n\t\tdst_length_elems = (src_length >> h_bufarg->shift);  /* elems in source and dest */\n\t\tdst_length = dst_length_elems << h_this->shift;  /* bytes in dest */\n\t\tif ((dst_length >> h_this->shift) != dst_length_elems) {\n\t\t\t/* Byte length would overflow. */\n\t\t\t/* XXX: easier check with less code? */\n\t\t\tgoto fail_args;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"nominal size check: src_length=%ld, dst_length=%ld\",\n\t\t                     (long) src_length, (long) dst_length));\n\t\tDUK_ASSERT(offset_bytes <= h_this->length);\n\t\tif (dst_length > h_this->length - offset_bytes) {\n\t\t\t/* Overflow not an issue because subtraction is used on the right\n\t\t\t * side and guaranteed to be >= 0.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copy exceeds target buffer nominal length\"));\n\t\t\tgoto fail_args;\n\t\t}\n\t\tif (!DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, offset_bytes + dst_length)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copy not covered by underlying target buffer, ignore\"));\n\t\t\treturn 0;\n\t\t}\n\n\t\tp_src_base = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg);\n\t\tp_dst_base = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + offset_bytes;\n\n\t\t/* Check actual underlying buffers for validity and that they\n\t\t * cover the copy.  No side effects are allowed after the check\n\t\t * so that the validity status doesn't change.\n\t\t */\n\t\tif (!DUK_HBUFOBJ_VALID_SLICE(h_this) ||\n\t\t    !DUK_HBUFOBJ_VALID_SLICE(h_bufarg)) {\n\t\t\t/* The condition could be more narrow and check for the\n\t\t\t * copy area only, but there's no need for fine grained\n\t\t\t * behavior when the underlying buffer is misconfigured.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"source and/or target not covered by underlying buffer, skip copy\"));\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* We want to do a straight memory copy if possible: this is\n\t\t * an important operation because .set() is the TypedArray\n\t\t * way to copy chunks of memory.  However, because set()\n\t\t * conceptually works in terms of elements, not all views are\n\t\t * compatible with direct byte copying.\n\t\t *\n\t\t * If we do manage a direct copy, the \"overlap issue\" handled\n\t\t * below can just be solved using memmove() because the source\n\t\t * and destination element sizes are necessarily equal.\n\t\t */\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\tDUK_ASSERT(h_this->elem_type < sizeof(duk__buffer_elemtype_copy_compatible) / sizeof(duk_uint16_t));\n\t\tcomp_mask = duk__buffer_elemtype_copy_compatible[h_this->elem_type];\n\t\tif (comp_mask & (1 << h_bufarg->elem_type)) {\n\t\t\tDUK_ASSERT(src_length == dst_length);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path: able to use memmove() because views are compatible\"));\n\t\t\tduk_memmove_unsafe((void *) p_dst_base, (const void *) p_src_base, (size_t) dst_length);\n\t\t\treturn 0;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"fast path: views are not compatible with a byte copy, copy by item\"));\n#endif  /* !DUK_USE_PREFER_SIZE */\n\n\t\t/* We want to avoid making a copy to process set() but that's\n\t\t * not always possible: the source and the target may overlap\n\t\t * and because element sizes are different, the overlap cannot\n\t\t * always be handled with a memmove() or choosing the copy\n\t\t * direction in a certain way.  For example, if source type is\n\t\t * uint8 and target type is uint32, the target area may exceed\n\t\t * the source area from both ends!\n\t\t *\n\t\t * Note that because external buffers may point to the same\n\t\t * memory areas, we must ultimately make this check using\n\t\t * pointers.\n\t\t *\n\t\t * NOTE: careful with side effects: any side effect may cause\n\t\t * a buffer resize (or external buffer pointer/length update)!\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"overlap check: p_src_base=%p, src_length=%ld, \"\n\t\t                     \"p_dst_base=%p, dst_length=%ld\",\n\t\t                     (void *) p_src_base, (long) src_length,\n\t\t                     (void *) p_dst_base, (long) dst_length));\n\n\t\tif (p_src_base >= p_dst_base + dst_length ||  /* source starts after dest ends */\n\t\t    p_src_base + src_length <= p_dst_base) {   /* source ends before dest starts */\n\t\t\tno_overlap = 1;\n\t\t}\n\n\t\tif (!no_overlap) {\n\t\t\t/* There's overlap: the desired end result is that\n\t\t\t * conceptually a copy is made to avoid \"trampling\"\n\t\t\t * of source data by destination writes.  We make\n\t\t\t * an actual temporary copy to handle this case.\n\t\t\t */\n\t\t\tduk_uint8_t *p_src_copy;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"there is overlap, make a copy of the source\"));\n\t\t\tp_src_copy = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, src_length);\n\t\t\tDUK_ASSERT(p_src_copy != NULL);\n\t\t\tduk_memcpy_unsafe((void *) p_src_copy, (const void *) p_src_base, (size_t) src_length);\n\n\t\t\tp_src_base = p_src_copy;  /* use p_src_base from now on */\n\t\t}\n\t\t/* Value stack intentionally mixed size here. */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"after overlap check: p_src_base=%p, src_length=%ld, \"\n\t\t                     \"p_dst_base=%p, dst_length=%ld, valstack top=%ld\",\n\t\t                     (void *) p_src_base, (long) src_length,\n\t\t                     (void *) p_dst_base, (long) dst_length,\n\t\t                     (long) duk_get_top(thr)));\n\n\t\t/* Ready to make the copy.  We must proceed element by element\n\t\t * and must avoid any side effects that might cause the buffer\n\t\t * validity check above to become invalid.\n\t\t *\n\t\t * Although we work through the value stack here, only plain\n\t\t * numbers are handled which should be side effect safe.\n\t\t */\n\n\t\tsrc_elem_size = (duk_small_uint_t) (1U << h_bufarg->shift);\n\t\tdst_elem_size = (duk_small_uint_t) (1U << h_this->shift);\n\t\tp_src = p_src_base;\n\t\tp_dst = p_dst_base;\n\t\tp_src_end = p_src_base + src_length;\n\n\t\twhile (p_src != p_src_end) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path per element copy loop: \"\n\t\t\t                     \"p_src=%p, p_src_end=%p, p_dst=%p\",\n\t\t\t                     (void *) p_src, (void *) p_src_end, (void *) p_dst));\n\t\t\t/* A validated read() is always a number, so it's write coercion\n\t\t\t * is always side effect free an won't invalidate pointers etc.\n\t\t\t */\n\t\t\tduk_hbufobj_push_validated_read(thr, h_bufarg, p_src, src_elem_size);\n\t\t\tduk_hbufobj_validated_write(thr, h_this, p_dst, dst_elem_size);\n\t\t\tduk_pop(thr);\n\t\t\tp_src += src_elem_size;\n\t\t\tp_dst += dst_elem_size;\n\t\t}\n\n\t\treturn 0;\n\t} else {\n\t\t/* Slow path: quite slow, but we save space by using the property code\n\t\t * to write coerce target values.  We don't need to worry about overlap\n\t\t * here because the source is not a TypedArray.\n\t\t *\n\t\t * We could use the bufobj write coercion helper but since the\n\t\t * property read may have arbitrary side effects, full validity checks\n\t\t * would be needed for every element anyway.\n\t\t */\n\n\t\tn = (duk_uarridx_t) duk_get_length(thr, 0);\n\t\tDUK_ASSERT(offset_bytes <= h_this->length);\n\t\tif ((n << h_this->shift) > h_this->length - offset_bytes) {\n\t\t\t/* Overflow not an issue because subtraction is used on the right\n\t\t\t * side and guaranteed to be >= 0.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copy exceeds target buffer nominal length\"));\n\t\t\tgoto fail_args;\n\t\t}\n\n\t\t/* There's no need to check for buffer validity status for the\n\t\t * target here: the property access code will do that for each\n\t\t * element.  Moreover, if we did check the validity here, side\n\t\t * effects from reading the source argument might invalidate\n\t\t * the results anyway.\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t\tduk_push_this(thr);\n\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk_get_prop_index(thr, 0, i);\n\t\t\tduk_put_prop_index(thr, 2, offset_elems + i);\n\t\t}\n\t}\n\n\treturn 0;\n\n fail_args:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.slice([start], [end])\n *  ArrayBuffer.prototype.slice(begin, [end])\n *  TypedArray.prototype.subarray(begin, [end])\n *\n *  The API calls are almost identical; negative indices are counted from end\n *  of buffer, and final indices are clamped (allowing crossed indices).  Main\n *  differences:\n *\n *    - Copy/view behavior; Node.js .slice() and TypedArray .subarray() create\n *      views, ArrayBuffer .slice() creates a copy\n *\n *    - Resulting object has a different class and prototype depending on the\n *      call (or 'this' argument)\n *\n *    - TypedArray .subarray() arguments are element indices, not byte offsets\n *\n *    - Plain buffer argument creates a plain buffer slice\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL void duk__arraybuffer_plain_slice(duk_hthread *thr, duk_hbuffer *h_val) {\n\tduk_int_t start_offset, end_offset;\n\tduk_uint_t slice_length;\n\tduk_uint8_t *p_copy;\n\tduk_size_t copy_length;\n\n\tduk__clamp_startend_negidx_shifted(thr,\n\t                                   (duk_int_t) DUK_HBUFFER_GET_SIZE(h_val),\n\t                                   0 /*buffer_shift*/,\n\t                                   0 /*idx_start*/,\n\t                                   1 /*idx_end*/,\n\t                                   &start_offset,\n\t                                   &end_offset);\n\tDUK_ASSERT(end_offset <= (duk_int_t) DUK_HBUFFER_GET_SIZE(h_val));\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(end_offset >= start_offset);\n\tslice_length = (duk_uint_t) (end_offset - start_offset);\n\n\tp_copy = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) slice_length);\n\tDUK_ASSERT(p_copy != NULL);\n\tcopy_length = slice_length;\n\n\tduk_memcpy_unsafe((void *) p_copy,\n\t                  (const void *) ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_val) + start_offset),\n\t                  copy_length);\n}\n#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Shared helper for slice/subarray operation.\n * Magic: 0x01=isView, 0x02=copy, 0x04=Node.js Buffer special handling.\n */\nDUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_hthread *thr) {\n\tduk_small_int_t magic;\n\tduk_small_uint_t res_class_num;\n\tduk_small_int_t res_proto_bidx;\n\tduk_hbufobj *h_this;\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_int_t start_offset, end_offset;\n\tduk_uint_t slice_length;\n\tduk_tval *tv;\n\n\t/* [ start end ] */\n\n\tmagic = duk_get_current_magic(thr);\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\t/* For plain buffers return a plain buffer slice. */\n\t\th_val = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h_val != NULL);\n\n\t\tif (magic & 0x02) {\n\t\t\t/* Make copy: ArrayBuffer.prototype.slice() uses this. */\n\t\t\tduk__arraybuffer_plain_slice(thr, h_val);\n\t\t\treturn 1;\n\t\t} else {\n\t\t\t/* View into existing buffer: cannot be done if the\n\t\t\t * result is a plain buffer because there's no slice\n\t\t\t * info.  So return an ArrayBuffer instance; coerce\n\t\t\t * the 'this' binding into an object and behave as if\n\t\t\t * the original call was for an Object-coerced plain\n\t\t\t * buffer (handled automatically by duk__require_bufobj_this()).\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slice() doesn't handle view into plain buffer, coerce 'this' to ArrayBuffer object\"));\n\t\t\t/* fall through */\n\t\t}\n\t}\n\ttv = NULL;  /* No longer valid nor needed. */\n\n\th_this = duk__require_bufobj_this(thr);\n\n\t/* Slice offsets are element (not byte) offsets, which only matters\n\t * for TypedArray views, Node.js Buffer and ArrayBuffer have shift\n\t * zero so byte and element offsets are the same.  Negative indices\n\t * are counted from end of slice, crossed indices are allowed (and\n\t * result in zero length result), and final values are clamped\n\t * against the current slice.  There's intentionally no check\n\t * against the underlying buffer here.\n\t */\n\n\tduk__clamp_startend_negidx_shifted(thr,\n\t                                   (duk_int_t) h_this->length,\n\t                                   (duk_uint8_t) h_this->shift,\n\t                                   0 /*idx_start*/,\n\t                                   1 /*idx_end*/,\n\t                                   &start_offset,\n\t                                   &end_offset);\n\tDUK_ASSERT(end_offset >= start_offset);\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(end_offset >= 0);\n\tslice_length = (duk_uint_t) (end_offset - start_offset);\n\n\t/* The resulting buffer object gets the same class and prototype as\n\t * the buffer in 'this', e.g. if the input is a Uint8Array the\n\t * result is a Uint8Array; if the input is a Float32Array, the\n\t * result is a Float32Array.  The result internal prototype should\n\t * be the default prototype for the class (e.g. initial value of\n\t * Uint8Array.prototype), not copied from the argument (Duktape 1.x\n\t * did that).\n\t *\n\t * Node.js Buffers have special handling: they're Uint8Arrays as far\n\t * as the internal class is concerned, so the new Buffer should also\n\t * be an Uint8Array but inherit from Buffer.prototype.\n\t */\n\tres_class_num = DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *) h_this);\n\tDUK_ASSERT(res_class_num >= DUK_HOBJECT_CLASS_BUFOBJ_MIN);  /* type check guarantees */\n\tDUK_ASSERT(res_class_num <= DUK_HOBJECT_CLASS_BUFOBJ_MAX);\n\tres_proto_bidx = duk__buffer_proto_from_classnum[res_class_num - DUK_HOBJECT_CLASS_BUFOBJ_MIN];\n\tif (magic & 0x04) {\n\t\tres_proto_bidx = DUK_BIDX_NODEJS_BUFFER_PROTOTYPE;\n\t}\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(res_class_num),\n\t                               res_proto_bidx);\n\tDUK_ASSERT(h_bufobj != NULL);\n\n\tDUK_ASSERT(h_bufobj->length == 0);\n\th_bufobj->shift = h_this->shift;  /* inherit */\n\th_bufobj->elem_type = h_this->elem_type;  /* inherit */\n\th_bufobj->is_typedarray = magic & 0x01;\n\tDUK_ASSERT(h_bufobj->is_typedarray == 0 || h_bufobj->is_typedarray == 1);\n\n\th_val = h_this->buf;\n\tif (h_val == NULL) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tif (magic & 0x02) {\n\t\t/* non-zero: make copy */\n\t\tduk_uint8_t *p_copy;\n\t\tduk_size_t copy_length;\n\n\t\tp_copy = (duk_uint8_t *) duk_push_fixed_buffer_zero(thr, (duk_size_t) slice_length);  /* must be zeroed, not all bytes always copied */\n\t\tDUK_ASSERT(p_copy != NULL);\n\n\t\t/* Copy slice, respecting underlying buffer limits; remainder\n\t\t * is left as zero.\n\t\t */\n\t\tcopy_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, slice_length);\n\t\tduk_memcpy_unsafe((void *) p_copy,\n\t\t                  (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + start_offset),\n\t\t                  copy_length);\n\n\t\th_val = duk_known_hbuffer(thr, -1);\n\n\t\th_bufobj->buf = h_val;\n\t\tDUK_HBUFFER_INCREF(thr, h_val);\n\t\th_bufobj->length = slice_length;\n\t\tDUK_ASSERT(h_bufobj->offset == 0);\n\n\t\tduk_pop(thr);  /* reachable so pop OK */\n\t} else {\n\t\th_bufobj->buf = h_val;\n\t\tDUK_HBUFFER_INCREF(thr, h_val);\n\t\th_bufobj->length = slice_length;\n\t\th_bufobj->offset = h_this->offset + (duk_uint_t) start_offset;\n\n\t\t/* Copy the .buffer property, needed for TypedArray.prototype.subarray().\n\t\t *\n\t\t * XXX: limit copy only for TypedArray classes specifically?\n\t\t */\n\n\t\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\t\th_bufobj->buf_prop = h_this->buf_prop;  /* may be NULL */\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, (duk_hobject *) h_bufobj->buf_prop);\n\t}\n\t/* unbalanced stack on purpose */\n\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.isEncoding()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_encoding(duk_hthread *thr) {\n\tconst char *encoding;\n\n\t/* only accept lowercase 'utf8' now. */\n\n\tencoding = duk_to_string(thr, 0);\n\tDUK_ASSERT(duk_is_string(thr, 0));  /* guaranteed by duk_to_string() */\n\tduk_push_boolean(thr, DUK_STRCMP(encoding, \"utf8\") == 0);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.isBuffer()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_hthread *thr) {\n\tduk_hobject *h;\n\tduk_hobject *h_proto;\n\tduk_bool_t ret = 0;\n\n\tDUK_ASSERT(duk_get_top(thr) >= 1);  /* nargs */\n\th = duk_get_hobject(thr, 0);\n\tif (h != NULL) {\n\t\th_proto = thr->builtins[DUK_BIDX_NODEJS_BUFFER_PROTOTYPE];\n\t\tDUK_ASSERT(h_proto != NULL);\n\n\t\th = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t\tif (h != NULL) {\n\t\t\tret = duk_hobject_prototype_chain_contains(thr, h, h_proto, 0 /*ignore_loop*/);\n\t\t}\n\t}\n\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.byteLength()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_byte_length(duk_hthread *thr) {\n\tconst char *str;\n\tduk_size_t len;\n\n\t/* At the moment Buffer(<str>) will just use the string bytes as\n\t * is (ignoring encoding), so we return the string length here\n\t * unconditionally.\n\t */\n\n\t/* XXX: to be revised; Old Node.js behavior just coerces any buffer\n\t * values to string:\n\t * $ node\n\t * > Buffer.byteLength(new Uint32Array(10))\n\t * 20\n\t * > Buffer.byteLength(new Uint32Array(100))\n\t * 20\n\t * (The 20 comes from '[object Uint32Array]'.length\n\t */\n\n\tstr = duk_to_lstring(thr, 0, &len);\n\tDUK_UNREF(str);\n\tduk_push_size_t(thr, len);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.concat()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_hthread *thr) {\n\tduk_hobject *h_arg;\n\tduk_uint_t total_length;\n\tduk_hbufobj *h_bufobj;\n\tduk_hbufobj *h_bufres;\n\tduk_hbuffer *h_val;\n\tduk_uint_t i, n;\n\tduk_uint8_t *p;\n\tduk_size_t space_left;\n\tduk_size_t copy_size;\n\n\t/* Node.js accepts only actual Arrays. */\n\th_arg = duk_require_hobject(thr, 0);\n\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h_arg) != DUK_HOBJECT_CLASS_ARRAY) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* Compute result length and validate argument buffers. */\n\tn = (duk_uint_t) duk_get_length(thr, 0);\n\ttotal_length = 0;\n\tfor (i = 0; i < n; i++) {\n\t\t/* Neutered checks not necessary here: neutered buffers have\n\t\t * zero 'length' so we'll effectively skip them.\n\t\t */\n\t\tDUK_ASSERT_TOP(thr, 2);  /* [ array totalLength ] */\n\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);  /* -> [ array totalLength buf ] */\n\t\th_bufobj = duk__require_bufobj_value(thr, 2);\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\t\ttotal_length += h_bufobj->length;\n\t\tif (DUK_UNLIKELY(total_length < h_bufobj->length)) {\n\t\t\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);  /* Wrapped. */\n\t\t}\n\t\tduk_pop(thr);\n\t}\n\t/* In Node.js v0.12.1 a 1-element array is special and won't create a\n\t * copy, this was fixed later so an explicit check no longer needed.\n\t */\n\n\t/* User totalLength overrides a computed length, but we'll check\n\t * every copy in the copy loop.  Note that duk_to_int() can\n\t * technically have arbitrary side effects so we need to recheck\n\t * the buffers in the copy loop.\n\t */\n\tif (!duk_is_undefined(thr, 1) && n > 0) {\n\t\t/* For n == 0, Node.js ignores totalLength argument and\n\t\t * returns a zero length buffer.\n\t\t */\n\t\tduk_int_t total_length_signed;\n\t\ttotal_length_signed = duk_to_int(thr, 1);\n\t\tif (total_length_signed < 0) {\n\t\t\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n\t\t}\n\t\ttotal_length = (duk_uint_t) total_length_signed;\n\t}\n\n\th_bufres = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_UINT8ARRAY),\n\t                               DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_bufres != NULL);\n\n\tp = (duk_uint8_t *) duk_push_fixed_buffer_zero(thr, total_length);  /* must be zeroed, all bytes not necessarily written over */\n\tDUK_ASSERT(p != NULL);\n\tspace_left = (duk_size_t) total_length;\n\n\tfor (i = 0; i < n; i++) {\n\t\tDUK_ASSERT_TOP(thr, 4);  /* [ array totalLength bufres buf ] */\n\n\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);\n\t\th_bufobj = duk__require_bufobj_value(thr, 4);\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\n\t\tcopy_size = h_bufobj->length;\n\t\tif (copy_size > space_left) {\n\t\t\tcopy_size = space_left;\n\t\t}\n\n\t\tif (h_bufobj->buf != NULL &&\n\t\t    DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {\n\t\t\tduk_memcpy_unsafe((void *) p,\n\t\t\t                  (const void *) DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj),\n\t\t\t                  copy_size);\n\t\t} else {\n\t\t\t/* Just skip, leaving zeroes in the result. */\n\t\t\t;\n\t\t}\n\t\tp += copy_size;\n\t\tspace_left -= copy_size;\n\n\t\tduk_pop(thr);\n\t}\n\n\th_val = duk_known_hbuffer(thr, -1);\n\n\tduk__set_bufobj_buffer(thr, h_bufres, h_val);\n\th_bufres->is_typedarray = 1;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufres);\n\n\tduk_pop(thr);  /* pop plain buffer, now reachable through h_bufres */\n\n\treturn 1;  /* return h_bufres */\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Shared readfield and writefield methods\n *\n *  The readfield/writefield methods need support for endianness and field\n *  types.  All offsets are byte based so no offset shifting is needed.\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Format of magic, bits:\n *   0...1: field type; 0=uint8, 1=uint16, 2=uint32, 3=float, 4=double, 5=unused, 6=unused, 7=unused\n *       3: endianness: 0=little, 1=big\n *       4: signed: 1=yes, 0=no\n *       5: typedarray: 1=yes, 0=no\n */\n#define  DUK__FLD_8BIT         0\n#define  DUK__FLD_16BIT        1\n#define  DUK__FLD_32BIT        2\n#define  DUK__FLD_FLOAT        3\n#define  DUK__FLD_DOUBLE       4\n#define  DUK__FLD_VARINT       5\n#define  DUK__FLD_BIGENDIAN    (1 << 3)\n#define  DUK__FLD_SIGNED       (1 << 4)\n#define  DUK__FLD_TYPEDARRAY   (1 << 5)\n\n/* XXX: split into separate functions for each field type? */\nDUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_hthread *thr) {\n\tduk_small_int_t magic = (duk_small_int_t) duk_get_current_magic(thr);\n\tduk_small_int_t magic_ftype;\n\tduk_small_int_t magic_bigendian;\n\tduk_small_int_t magic_signed;\n\tduk_small_int_t magic_typedarray;\n\tduk_small_int_t endswap;\n\tduk_hbufobj *h_this;\n\tduk_bool_t no_assert;\n\tduk_int_t offset_signed;\n\tduk_uint_t offset;\n\tduk_uint_t buffer_length;\n\tduk_uint_t check_length;\n\tduk_uint8_t *buf;\n\tduk_double_union du;\n\n\tmagic_ftype = magic & 0x0007;\n\tmagic_bigendian = magic & 0x0008;\n\tmagic_signed = magic & 0x0010;\n\tmagic_typedarray = magic & 0x0020;\n\n\th_this = duk__require_bufobj_this(thr);  /* XXX: very inefficient for plain buffers */\n\tDUK_ASSERT(h_this != NULL);\n\tbuffer_length = h_this->length;\n\n\t/* [ offset noAssert                 ], when ftype != DUK__FLD_VARINT */\n\t/* [ offset fieldByteLength noAssert ], when ftype == DUK__FLD_VARINT */\n\t/* [ offset littleEndian             ], when DUK__FLD_TYPEDARRAY (regardless of ftype) */\n\n\t/* Handle TypedArray vs. Node.js Buffer arg differences */\n\tif (magic_typedarray) {\n\t\tno_assert = 0;\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = !duk_to_boolean(thr, 1);  /* 1=little endian */\n#else\n\t\tendswap = duk_to_boolean(thr, 1);  /* 1=little endian */\n#endif\n\t} else {\n\t\tno_assert = duk_to_boolean(thr, (magic_ftype == DUK__FLD_VARINT) ? 2 : 1);\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = magic_bigendian;\n#else\n\t\tendswap = !magic_bigendian;\n#endif\n\t}\n\n\t/* Offset is coerced first to signed integer range and then to unsigned.\n\t * This ensures we can add a small byte length (1-8) to the offset in\n\t * bound checks and not wrap.\n\t */\n\toffset_signed = duk_to_int(thr, 0);\n\toffset = (duk_uint_t) offset_signed;\n\tif (offset_signed < 0) {\n\t\tgoto fail_bounds;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"readfield, buffer_length=%ld, offset=%ld, no_assert=%d, \"\n\t                     \"magic=%04x, magic_fieldtype=%d, magic_bigendian=%d, magic_signed=%d, \"\n\t                     \"endswap=%d\",\n\t                     (long) buffer_length, (long) offset, (int) no_assert,\n\t                     (unsigned int) magic, (int) magic_ftype, (int) (magic_bigendian >> 3),\n\t                     (int) (magic_signed >> 4), (int) endswap));\n\n\t/* Update 'buffer_length' to be the effective, safe limit which\n\t * takes into account the underlying buffer.  This value will be\n\t * potentially invalidated by any side effect.\n\t */\n\tcheck_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, buffer_length);\n\tDUK_DDD(DUK_DDDPRINT(\"buffer_length=%ld, check_length=%ld\",\n\t                     (long) buffer_length, (long) check_length));\n\n\tif (h_this->buf) {\n\t\tbuf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this);\n\t} else {\n\t\t/* Neutered.  We could go into the switch-case safely with\n\t\t * buf == NULL because check_length == 0.  To avoid scanbuild\n\t\t * warnings, fail directly instead.\n\t\t */\n\t\tDUK_ASSERT(check_length == 0);\n\t\tgoto fail_neutered;\n\t}\n\tDUK_ASSERT(buf != NULL);\n\n\tswitch (magic_ftype) {\n\tcase DUK__FLD_8BIT: {\n\t\tduk_uint8_t tmp;\n\t\tif (offset + 1U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\ttmp = buf[offset];\n\t\tif (magic_signed) {\n\t\t\tduk_push_int(thr, (duk_int_t) ((duk_int8_t) tmp));\n\t\t} else {\n\t\t\tduk_push_uint(thr, (duk_uint_t) tmp);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK__FLD_16BIT: {\n\t\tduk_uint16_t tmp;\n\t\tif (offset + 2U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 2);\n\t\ttmp = du.us[0];\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP16(tmp);\n\t\t}\n\t\tif (magic_signed) {\n\t\t\tduk_push_int(thr, (duk_int_t) ((duk_int16_t) tmp));\n\t\t} else {\n\t\t\tduk_push_uint(thr, (duk_uint_t) tmp);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK__FLD_32BIT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 4);\n\t\ttmp = du.ui[0];\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t}\n\t\tif (magic_signed) {\n\t\t\tduk_push_int(thr, (duk_int_t) ((duk_int32_t) tmp));\n\t\t} else {\n\t\t\tduk_push_uint(thr, (duk_uint_t) tmp);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK__FLD_FLOAT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 4);\n\t\tif (endswap) {\n\t\t\ttmp = du.ui[0];\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t\tdu.ui[0] = tmp;\n\t\t}\n\t\tduk_push_number(thr, (duk_double_t) du.f[0]);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_DOUBLE: {\n\t\tif (offset + 8U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 8);\n\t\tif (endswap) {\n\t\t\tDUK_DBLUNION_BSWAP64(&du);\n\t\t}\n\t\tduk_push_number(thr, (duk_double_t) du.d);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_VARINT: {\n\t\t/* Node.js Buffer variable width integer field.  We don't really\n\t\t * care about speed here, so aim for shortest algorithm.\n\t\t */\n\t\tduk_int_t field_bytelen;\n\t\tduk_int_t i, i_step, i_end;\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_int64_t tmp;\n\t\tduk_small_uint_t shift_tmp;\n#else\n\t\tduk_double_t tmp;\n\t\tduk_small_int_t highbyte;\n#endif\n\t\tconst duk_uint8_t *p;\n\n\t\tfield_bytelen = duk_get_int(thr, 1);  /* avoid side effects! */\n\t\tif (field_bytelen < 1 || field_bytelen > 6) {\n\t\t\tgoto fail_field_length;\n\t\t}\n\t\tif (offset + (duk_uint_t) field_bytelen > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tp = (const duk_uint8_t *) (buf + offset);\n\n\t\t/* Slow gathering of value using either 64-bit arithmetic\n\t\t * or IEEE doubles if 64-bit types not available.  Handling\n\t\t * of negative numbers is a bit non-obvious in both cases.\n\t\t */\n\n\t\tif (magic_bigendian) {\n\t\t\t/* Gather in big endian */\n\t\t\ti = 0;\n\t\t\ti_step = 1;\n\t\t\ti_end = field_bytelen;  /* one i_step over */\n\t\t} else {\n\t\t\t/* Gather in little endian */\n\t\t\ti = field_bytelen - 1;\n\t\t\ti_step = -1;\n\t\t\ti_end = -1;  /* one i_step over */\n\t\t}\n\n#if defined(DUK_USE_64BIT_OPS)\n\t\ttmp = 0;\n\t\tdo {\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\ttmp = (tmp << 8) + (duk_int64_t) p[i];\n\t\t\ti += i_step;\n\t\t} while (i != i_end);\n\n\t\tif (magic_signed) {\n\t\t\t/* Shift to sign extend.  Left shift must be unsigned\n\t\t\t * to avoid undefined behavior; right shift must be\n\t\t\t * signed to sign extend properly.\n\t\t\t */\n\t\t\tshift_tmp = (duk_small_uint_t) (64U - (duk_small_uint_t) field_bytelen * 8U);\n\t\t\ttmp = (duk_int64_t) ((duk_uint64_t) tmp << shift_tmp) >> shift_tmp;\n\t\t}\n\n\t\tduk_push_i64(thr, tmp);\n#else\n\t\thighbyte = p[i];\n\t\tif (magic_signed && (highbyte & 0x80) != 0) {\n\t\t\t/* 0xff => 255 - 256 = -1; 0x80 => 128 - 256 = -128 */\n\t\t\ttmp = (duk_double_t) (highbyte - 256);\n\t\t} else {\n\t\t\ttmp = (duk_double_t) highbyte;\n\t\t}\n\t\tfor (;;) {\n\t\t\ti += i_step;\n\t\t\tif (i == i_end) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\ttmp = (tmp * 256.0) + (duk_double_t) p[i];\n\t\t}\n\n\t\tduk_push_number(thr, tmp);\n#endif\n\t\tbreak;\n\t}\n\tdefault: {  /* should never happen but default here */\n\t\tgoto fail_bounds;\n\t}\n\t}\n\n\treturn 1;\n\n fail_neutered:\n fail_field_length:\n fail_bounds:\n\tif (no_assert) {\n\t\t/* Node.js return value for noAssert out-of-bounds reads is\n\t\t * usually (but not always) NaN.  Return NaN consistently.\n\t\t */\n\t\tduk_push_nan(thr);\n\t\treturn 1;\n\t}\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* XXX: split into separate functions for each field type? */\nDUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_hthread *thr) {\n\tduk_small_int_t magic = (duk_small_int_t) duk_get_current_magic(thr);\n\tduk_small_int_t magic_ftype;\n\tduk_small_int_t magic_bigendian;\n\tduk_small_int_t magic_signed;\n\tduk_small_int_t magic_typedarray;\n\tduk_small_int_t endswap;\n\tduk_hbufobj *h_this;\n\tduk_bool_t no_assert;\n\tduk_int_t offset_signed;\n\tduk_uint_t offset;\n\tduk_uint_t buffer_length;\n\tduk_uint_t check_length;\n\tduk_uint8_t *buf;\n\tduk_double_union du;\n\tduk_int_t nbytes = 0;\n\n\tmagic_ftype = magic & 0x0007;\n\tmagic_bigendian = magic & 0x0008;\n\tmagic_signed = magic & 0x0010;\n\tmagic_typedarray = magic & 0x0020;\n\tDUK_UNREF(magic_signed);\n\n\th_this = duk__require_bufobj_this(thr);  /* XXX: very inefficient for plain buffers */\n\tDUK_ASSERT(h_this != NULL);\n\tbuffer_length = h_this->length;\n\n\t/* [ value  offset noAssert                 ], when ftype != DUK__FLD_VARINT */\n\t/* [ value  offset fieldByteLength noAssert ], when ftype == DUK__FLD_VARINT */\n\t/* [ offset value  littleEndian             ], when DUK__FLD_TYPEDARRAY (regardless of ftype) */\n\n\t/* Handle TypedArray vs. Node.js Buffer arg differences */\n\tif (magic_typedarray) {\n\t\tno_assert = 0;\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = !duk_to_boolean(thr, 2);  /* 1=little endian */\n#else\n\t\tendswap = duk_to_boolean(thr, 2);  /* 1=little endian */\n#endif\n\t\tduk_swap(thr, 0, 1);  /* offset/value order different from Node.js */\n\t} else {\n\t\tno_assert = duk_to_boolean(thr, (magic_ftype == DUK__FLD_VARINT) ? 3 : 2);\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = magic_bigendian;\n#else\n\t\tendswap = !magic_bigendian;\n#endif\n\t}\n\n\t/* Offset is coerced first to signed integer range and then to unsigned.\n\t * This ensures we can add a small byte length (1-8) to the offset in\n\t * bound checks and not wrap.\n\t */\n\toffset_signed = duk_to_int(thr, 1);\n\toffset = (duk_uint_t) offset_signed;\n\n\t/* We need 'nbytes' even for a failed offset; return value must be\n\t * (offset + nbytes) even when write fails due to invalid offset.\n\t */\n\tif (magic_ftype != DUK__FLD_VARINT) {\n\t\tDUK_ASSERT(magic_ftype >= 0 && magic_ftype < (duk_small_int_t) (sizeof(duk__buffer_nbytes_from_fldtype) / sizeof(duk_uint8_t)));\n\t\tnbytes = duk__buffer_nbytes_from_fldtype[magic_ftype];\n\t} else {\n\t\tnbytes = duk_get_int(thr, 2);\n\t\tif (nbytes < 1 || nbytes > 6) {\n\t\t\tgoto fail_field_length;\n\t\t}\n\t}\n\tDUK_ASSERT(nbytes >= 1 && nbytes <= 8);\n\n\t/* Now we can check offset validity. */\n\tif (offset_signed < 0) {\n\t\tgoto fail_bounds;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"writefield, value=%!T, buffer_length=%ld, offset=%ld, no_assert=%d, \"\n\t                     \"magic=%04x, magic_fieldtype=%d, magic_bigendian=%d, magic_signed=%d, \"\n\t                     \"endswap=%d\",\n\t                     duk_get_tval(thr, 0), (long) buffer_length, (long) offset, (int) no_assert,\n\t                     (unsigned int) magic, (int) magic_ftype, (int) (magic_bigendian >> 3),\n\t                     (int) (magic_signed >> 4), (int) endswap));\n\n\t/* Coerce value to a number before computing check_length, so that\n\t * the field type specific coercion below can't have side effects\n\t * that would invalidate check_length.\n\t */\n\tduk_to_number(thr, 0);\n\n\t/* Update 'buffer_length' to be the effective, safe limit which\n\t * takes into account the underlying buffer.  This value will be\n\t * potentially invalidated by any side effect.\n\t */\n\tcheck_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, buffer_length);\n\tDUK_DDD(DUK_DDDPRINT(\"buffer_length=%ld, check_length=%ld\",\n\t                     (long) buffer_length, (long) check_length));\n\n\tif (h_this->buf) {\n\t\tbuf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this);\n\t} else {\n\t\t/* Neutered.  We could go into the switch-case safely with\n\t\t * buf == NULL because check_length == 0.  To avoid scanbuild\n\t\t * warnings, fail directly instead.\n\t\t */\n\t\tDUK_ASSERT(check_length == 0);\n\t\tgoto fail_neutered;\n\t}\n\tDUK_ASSERT(buf != NULL);\n\n\tswitch (magic_ftype) {\n\tcase DUK__FLD_8BIT: {\n\t\tif (offset + 1U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\t/* sign doesn't matter when writing */\n\t\tbuf[offset] = (duk_uint8_t) duk_to_uint32(thr, 0);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_16BIT: {\n\t\tduk_uint16_t tmp;\n\t\tif (offset + 2U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\ttmp = (duk_uint16_t) duk_to_uint32(thr, 0);\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP16(tmp);\n\t\t}\n\t\tdu.us[0] = tmp;\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 2);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_32BIT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\ttmp = (duk_uint32_t) duk_to_uint32(thr, 0);\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t}\n\t\tdu.ui[0] = tmp;\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 4);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_FLOAT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tdu.f[0] = (duk_float_t) duk_to_number(thr, 0);\n\t\tif (endswap) {\n\t\t\ttmp = du.ui[0];\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t\tdu.ui[0] = tmp;\n\t\t}\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 4);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_DOUBLE: {\n\t\tif (offset + 8U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tdu.d = (duk_double_t) duk_to_number(thr, 0);\n\t\tif (endswap) {\n\t\t\tDUK_DBLUNION_BSWAP64(&du);\n\t\t}\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 8);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_VARINT: {\n\t\t/* Node.js Buffer variable width integer field.  We don't really\n\t\t * care about speed here, so aim for shortest algorithm.\n\t\t */\n\t\tduk_int_t field_bytelen;\n\t\tduk_int_t i, i_step, i_end;\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_int64_t tmp;\n#else\n\t\tduk_double_t tmp;\n#endif\n\t\tduk_uint8_t *p;\n\n\t\tfield_bytelen = (duk_int_t) nbytes;\n\t\tif (offset + (duk_uint_t) field_bytelen > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\n\t\t/* Slow writing of value using either 64-bit arithmetic\n\t\t * or IEEE doubles if 64-bit types not available.  There's\n\t\t * no special sign handling when writing varints.\n\t\t */\n\n\t\tif (magic_bigendian) {\n\t\t\t/* Write in big endian */\n\t\t\ti = field_bytelen;  /* one i_step added at top of loop */\n\t\t\ti_step = -1;\n\t\t\ti_end = 0;\n\t\t} else {\n\t\t\t/* Write in little endian */\n\t\t\ti = -1;  /* one i_step added at top of loop */\n\t\t\ti_step = 1;\n\t\t\ti_end = field_bytelen - 1;\n\t\t}\n\n\t\t/* XXX: The duk_to_number() cast followed by integer coercion\n\t\t * is platform specific so NaN, +/- Infinity, and out-of-bounds\n\t\t * values result in platform specific output now.\n\t\t * See: test-bi-nodejs-buffer-proto-varint-special.js\n\t\t */\n\n#if defined(DUK_USE_64BIT_OPS)\n\t\ttmp = (duk_int64_t) duk_to_number(thr, 0);\n\t\tp = (duk_uint8_t *) (buf + offset);\n\t\tdo {\n\t\t\ti += i_step;\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\tp[i] = (duk_uint8_t) (tmp & 0xff);\n\t\t\ttmp = tmp >> 8;  /* unnecessary shift for last byte */\n\t\t} while (i != i_end);\n#else\n\t\ttmp = duk_to_number(thr, 0);\n\t\tp = (duk_uint8_t *) (buf + offset);\n\t\tdo {\n\t\t\ti += i_step;\n\t\t\ttmp = DUK_FLOOR(tmp);\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\tp[i] = (duk_uint8_t) (DUK_FMOD(tmp, 256.0));\n\t\t\ttmp = tmp / 256.0;  /* unnecessary div for last byte */\n\t\t} while (i != i_end);\n#endif\n\t\tbreak;\n\t}\n\tdefault: {  /* should never happen but default here */\n\t\tgoto fail_bounds;\n\t}\n\t}\n\n\t/* Node.js Buffer: return offset + #bytes written (i.e. next\n\t * write offset).\n\t */\n\tif (magic_typedarray) {\n\t\t/* For TypedArrays 'undefined' return value is specified\n\t\t * by ES2015 (matches V8).\n\t\t */\n\t\treturn 0;\n\t}\n\tduk_push_uint(thr, offset + (duk_uint_t) nbytes);\n\treturn 1;\n\n fail_neutered:\n fail_field_length:\n fail_bounds:\n\tif (no_assert) {\n\t\t/* Node.js return value for failed writes is offset + #bytes\n\t\t * that would have been written.\n\t\t */\n\t\t/* XXX: for negative input offsets, 'offset' will be a large\n\t\t * positive value so the result here is confusing.\n\t\t */\n\t\tif (magic_typedarray) {\n\t\t\treturn 0;\n\t\t}\n\t\tduk_push_uint(thr, offset + (duk_uint_t) nbytes);\n\t\treturn 1;\n\t}\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Accessors for .buffer, .byteLength, .byteOffset\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL duk_hbufobj *duk__autospawn_arraybuffer(duk_hthread *thr, duk_hbuffer *h_buf) {\n\tduk_hbufobj *h_res;\n\n\th_res = duk_push_bufobj_raw(thr,\n\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                            DUK_HOBJECT_FLAG_BUFOBJ |\n\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),\n\t                            DUK_BIDX_ARRAYBUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_res != NULL);\n\tDUK_UNREF(h_res);\n\n\tduk__set_bufobj_buffer(thr, h_res, h_buf);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_res);\n\tDUK_ASSERT(h_res->buf_prop == NULL);\n\treturn h_res;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n\th_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW /*flags*/);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tif (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *) h_bufobj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"autospawn ArrayBuffer for plain buffer\"));\n\t\t(void) duk__autospawn_arraybuffer(thr, (duk_hbuffer *) h_bufobj);\n\t\treturn 1;\n\t} else {\n\t\tif (h_bufobj->buf_prop == NULL &&\n\t\t    DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *) h_bufobj) != DUK_HOBJECT_CLASS_ARRAYBUFFER &&\n\t\t    h_bufobj->buf != NULL) {\n\t\t\tduk_hbufobj *h_arrbuf;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"autospawn ArrayBuffer for typed array or DataView\"));\n\t\t\th_arrbuf = duk__autospawn_arraybuffer(thr, h_bufobj->buf);\n\n\t\t\tif (h_bufobj->buf_prop == NULL) {\n\t\t\t\t/* Must recheck buf_prop, in case ArrayBuffer\n\t\t\t\t * alloc had a side effect which already filled\n\t\t\t\t * it!\n\t\t\t\t */\n\n\t\t\t\t/* Set ArrayBuffer's .byteOffset and .byteLength based\n\t\t\t\t * on the view so that Arraybuffer[view.byteOffset]\n\t\t\t\t * matches view[0].\n\t\t\t\t */\n\t\t\t\th_arrbuf->offset = 0;\n\t\t\t\tDUK_ASSERT(h_bufobj->offset + h_bufobj->length >= h_bufobj->offset);  /* Wrap check on creation. */\n\t\t\t\th_arrbuf->length = h_bufobj->offset + h_bufobj->length;\n\t\t\t\tDUK_ASSERT(h_arrbuf->buf_prop == NULL);\n\n\t\t\t\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\t\t\t\th_bufobj->buf_prop = (duk_hobject *) h_arrbuf;\n\t\t\t\tDUK_HBUFOBJ_INCREF(thr, h_arrbuf);  /* Now reachable and accounted for. */\n\t\t\t}\n\n\t\t\t/* Left on stack; pushed for the second time below (OK). */\n\t\t}\n\t\tif (h_bufobj->buf_prop) {\n\t\t\tduk_push_hobject(thr, h_bufobj->buf_prop);\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n\th_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW /*flags*/);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tif (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *) h_bufobj)) {\n\t\tduk_push_uint(thr, 0);\n\t} else {\n\t\t/* If neutered must return 0; offset is zeroed during\n\t\t * neutering.\n\t\t */\n\t\tduk_push_uint(thr, h_bufobj->offset);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n\th_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW /*flags*/);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tif (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *) h_bufobj)) {\n\t\tduk_hbuffer *h_buf;\n\n\t\th_buf = (duk_hbuffer *) h_bufobj;\n\t\tDUK_ASSERT(DUK_HBUFFER_GET_SIZE(h_buf) <= DUK_UINT_MAX);  /* Buffer limits. */\n\t\tduk_push_uint(thr, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_buf));\n\t} else {\n\t\t/* If neutered must return 0; length is zeroed during\n\t\t * neutering.\n\t\t */\n\t\tduk_push_uint(thr, h_bufobj->length);\n\t}\n\treturn 1;\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n/* No .buffer getter without ArrayBuffer support. */\n#if 0\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_hthread *thr) {\n\treturn 0;\n}\n#endif\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_hthread *thr) {\n\tduk_push_uint(thr, 0);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_hthread *thr) {\n\tduk_hbuffer *h_buf;\n\n\t/* XXX: helper? */\n\tduk_push_this(thr);\n\th_buf = duk_require_hbuffer(thr, -1);\n\tduk_push_uint(thr, DUK_HBUFFER_GET_SIZE(h_buf));\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_date.c",
    "content": "/*\n *  Date built-ins\n *\n *  Unlike most built-ins, Date has some platform dependencies for getting\n *  UTC time, converting between UTC and local time, and parsing and\n *  formatting time values.  These are all abstracted behind DUK_USE_xxx\n *  config options.  There are built-in platform specific providers for\n *  POSIX and Windows, but external providers can also be used.\n *\n *  See doc/datetime.rst.\n *\n */\n\n#include \"duk_internal.h\"\n\n/* XXX: currently defines unnecessary symbols when DUK_USE_DATE_BUILTIN is disabled. */\n\n/*\n *  Forward declarations\n */\n\nDUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval_tzoffset(duk_hthread *thr, duk_small_uint_t flags, duk_int_t *out_tzoffset);\nDUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval(duk_hthread *thr, duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__twodigit_year_fixup(duk_hthread *thr, duk_idx_t idx_val);\nDUK_LOCAL_DECL duk_ret_t duk__set_this_timeval_from_dparts(duk_hthread *thr, duk_double_t *dparts, duk_small_uint_t flags);\n\n/*\n *  Other file level defines\n */\n\n/* Debug macro to print all parts and dparts (used manually because of debug level). */\n#define  DUK__DPRINT_PARTS_AND_DPARTS(parts,dparts)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"parts: %ld %ld %ld %ld %ld %ld %ld %ld, dparts: %lf %lf %lf %lf %lf %lf %lf %lf\", \\\n\t\t                 (long) (parts)[0], (long) (parts)[1], \\\n\t\t                 (long) (parts)[2], (long) (parts)[3], \\\n\t\t                 (long) (parts)[4], (long) (parts)[5], \\\n\t\t                 (long) (parts)[6], (long) (parts)[7], \\\n\t\t                 (double) (dparts)[0], (double) (dparts)[1], \\\n\t\t                 (double) (dparts)[2], (double) (dparts)[3], \\\n\t\t                 (double) (dparts)[4], (double) (dparts)[5], \\\n\t\t                 (double) (dparts)[6], (double) (dparts)[7])); \\\n\t} while (0)\n#define  DUK__DPRINT_PARTS(parts)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"parts: %ld %ld %ld %ld %ld %ld %ld %ld\", \\\n\t\t                 (long) (parts)[0], (long) (parts)[1], \\\n\t\t                 (long) (parts)[2], (long) (parts)[3], \\\n\t\t                 (long) (parts)[4], (long) (parts)[5], \\\n\t\t                 (long) (parts)[6], (long) (parts)[7])); \\\n\t} while (0)\n#define  DUK__DPRINT_DPARTS(dparts)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"dparts: %lf %lf %lf %lf %lf %lf %lf %lf\", \\\n\t\t                 (double) (dparts)[0], (double) (dparts)[1], \\\n\t\t                 (double) (dparts)[2], (double) (dparts)[3], \\\n\t\t                 (double) (dparts)[4], (double) (dparts)[5], \\\n\t\t                 (double) (dparts)[6], (double) (dparts)[7])); \\\n\t} while (0)\n\n/* Equivalent year for DST calculations outside [1970,2038[ range, see\n * E5 Section 15.9.1.8.  Equivalent year has the same leap-year-ness and\n * starts with the same weekday on Jan 1.\n * https://bugzilla.mozilla.org/show_bug.cgi?id=351066\n */\n#define DUK__YEAR(x) ((duk_uint8_t) ((x) - 1970))\nDUK_LOCAL duk_uint8_t duk__date_equivyear[14] = {\n#if 1\n\t/* This is based on V8 EquivalentYear() algorithm (see util/genequivyear.py):\n\t * http://code.google.com/p/v8/source/browse/trunk/src/date.h#146\n\t */\n\n\t/* non-leap year: sunday, monday, ... */\n\tDUK__YEAR(2023), DUK__YEAR(2035), DUK__YEAR(2019), DUK__YEAR(2031),\n\tDUK__YEAR(2015), DUK__YEAR(2027), DUK__YEAR(2011),\n\n\t/* leap year: sunday, monday, ... */\n\tDUK__YEAR(2012), DUK__YEAR(2024), DUK__YEAR(2008), DUK__YEAR(2020),\n\tDUK__YEAR(2032), DUK__YEAR(2016), DUK__YEAR(2028)\n#endif\n\n#if 0\n\t/* This is based on Rhino EquivalentYear() algorithm:\n\t * https://github.com/mozilla/rhino/blob/f99cc11d616f0cdda2c42bde72b3484df6182947/src/org/mozilla/javascript/NativeDate.java\n\t */\n\n\t/* non-leap year: sunday, monday, ... */\n\tDUK__YEAR(1978), DUK__YEAR(1973), DUK__YEAR(1985), DUK__YEAR(1986),\n\tDUK__YEAR(1981), DUK__YEAR(1971), DUK__YEAR(1977),\n\n\t/* leap year: sunday, monday, ... */\n\tDUK__YEAR(1984), DUK__YEAR(1996), DUK__YEAR(1980), DUK__YEAR(1992),\n\tDUK__YEAR(1976), DUK__YEAR(1988), DUK__YEAR(1972)\n#endif\n};\n\n/*\n *  ISO 8601 subset parser.\n */\n\n/* Parser part count. */\n#define DUK__NUM_ISO8601_PARSER_PARTS  9\n\n/* Parser part indices. */\n#define DUK__PI_YEAR         0\n#define DUK__PI_MONTH        1\n#define DUK__PI_DAY          2\n#define DUK__PI_HOUR         3\n#define DUK__PI_MINUTE       4\n#define DUK__PI_SECOND       5\n#define DUK__PI_MILLISECOND  6\n#define DUK__PI_TZHOUR       7\n#define DUK__PI_TZMINUTE     8\n\n/* Parser part masks. */\n#define DUK__PM_YEAR         (1 << DUK__PI_YEAR)\n#define DUK__PM_MONTH        (1 << DUK__PI_MONTH)\n#define DUK__PM_DAY          (1 << DUK__PI_DAY)\n#define DUK__PM_HOUR         (1 << DUK__PI_HOUR)\n#define DUK__PM_MINUTE       (1 << DUK__PI_MINUTE)\n#define DUK__PM_SECOND       (1 << DUK__PI_SECOND)\n#define DUK__PM_MILLISECOND  (1 << DUK__PI_MILLISECOND)\n#define DUK__PM_TZHOUR       (1 << DUK__PI_TZHOUR)\n#define DUK__PM_TZMINUTE     (1 << DUK__PI_TZMINUTE)\n\n/* Parser separator indices. */\n#define DUK__SI_PLUS         0\n#define DUK__SI_MINUS        1\n#define DUK__SI_T            2\n#define DUK__SI_SPACE        3\n#define DUK__SI_COLON        4\n#define DUK__SI_PERIOD       5\n#define DUK__SI_Z            6\n#define DUK__SI_NUL          7\n\n/* Parser separator masks. */\n#define DUK__SM_PLUS         (1 << DUK__SI_PLUS)\n#define DUK__SM_MINUS        (1 << DUK__SI_MINUS)\n#define DUK__SM_T            (1 << DUK__SI_T)\n#define DUK__SM_SPACE        (1 << DUK__SI_SPACE)\n#define DUK__SM_COLON        (1 << DUK__SI_COLON)\n#define DUK__SM_PERIOD       (1 << DUK__SI_PERIOD)\n#define DUK__SM_Z            (1 << DUK__SI_Z)\n#define DUK__SM_NUL          (1 << DUK__SI_NUL)\n\n/* Rule control flags. */\n#define DUK__CF_NEG          (1 << 0)  /* continue matching, set neg_tzoffset flag */\n#define DUK__CF_ACCEPT       (1 << 1)  /* accept string */\n#define DUK__CF_ACCEPT_NUL   (1 << 2)  /* accept string if next char is NUL (otherwise reject) */\n\n#define DUK__PACK_RULE(partmask,sepmask,nextpart,flags)  \\\n\t((duk_uint32_t) (partmask) + \\\n\t (((duk_uint32_t) (sepmask)) << 9) + \\\n\t (((duk_uint32_t) (nextpart)) << 17) + \\\n\t (((duk_uint32_t) (flags)) << 21))\n\n#define DUK__UNPACK_RULE(rule,var_nextidx,var_flags)  do { \\\n\t\t(var_nextidx) = (duk_small_uint_t) (((rule) >> 17) & 0x0f); \\\n\t\t(var_flags) = (duk_small_uint_t) ((rule) >> 21); \\\n\t} while (0)\n\n#define DUK__RULE_MASK_PART_SEP  0x1ffffUL\n\n/* Matching separator index is used in the control table */\nDUK_LOCAL const duk_uint8_t duk__parse_iso8601_seps[] = {\n\tDUK_ASC_PLUS /*0*/, DUK_ASC_MINUS /*1*/, DUK_ASC_UC_T /*2*/, DUK_ASC_SPACE /*3*/,\n\tDUK_ASC_COLON /*4*/, DUK_ASC_PERIOD /*5*/, DUK_ASC_UC_Z /*6*/, DUK_ASC_NUL /*7*/\n};\n\n/* Rule table: first matching rule is used to determine what to do next. */\nDUK_LOCAL const duk_uint32_t duk__parse_iso8601_control[] = {\n\tDUK__PACK_RULE(DUK__PM_YEAR, DUK__SM_MINUS, DUK__PI_MONTH, 0),\n\tDUK__PACK_RULE(DUK__PM_MONTH, DUK__SM_MINUS, DUK__PI_DAY, 0),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY, DUK__SM_T | DUK__SM_SPACE, DUK__PI_HOUR, 0),\n\tDUK__PACK_RULE(DUK__PM_HOUR, DUK__SM_COLON, DUK__PI_MINUTE, 0),\n\tDUK__PACK_RULE(DUK__PM_MINUTE, DUK__SM_COLON, DUK__PI_SECOND, 0),\n\tDUK__PACK_RULE(DUK__PM_SECOND, DUK__SM_PERIOD, DUK__PI_MILLISECOND, 0),\n\tDUK__PACK_RULE(DUK__PM_TZHOUR, DUK__SM_COLON, DUK__PI_TZMINUTE, 0),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_PLUS, DUK__PI_TZHOUR, 0),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_MINUS, DUK__PI_TZHOUR, DUK__CF_NEG),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_Z, 0, DUK__CF_ACCEPT_NUL),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND | DUK__PM_TZHOUR /*Note2*/ | DUK__PM_TZMINUTE, DUK__SM_NUL, 0, DUK__CF_ACCEPT)\n\n\t/* Note1: the specification doesn't require matching a time form with\n\t *        just hours (\"HH\"), but we accept it here, e.g. \"2012-01-02T12Z\".\n\t *\n\t * Note2: the specification doesn't require matching a timezone offset\n\t *        with just hours (\"HH\"), but accept it here, e.g. \"2012-01-02T03:04:05+02\"\n\t */\n};\n\nDUK_LOCAL duk_bool_t duk__parse_string_iso8601_subset(duk_hthread *thr, const char *str) {\n\tduk_int_t parts[DUK__NUM_ISO8601_PARSER_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t d;\n\tconst duk_uint8_t *p;\n\tduk_small_uint_t part_idx = 0;\n\tduk_int_t accum = 0;\n\tduk_small_uint_t ndigits = 0;\n\tduk_bool_t neg_year = 0;\n\tduk_bool_t neg_tzoffset = 0;\n\tduk_uint_fast8_t ch;\n\tduk_small_uint_t i;\n\n\t/* During parsing, month and day are one-based; set defaults here. */\n\tduk_memzero(parts, sizeof(parts));\n\tDUK_ASSERT(parts[DUK_DATE_IDX_YEAR] == 0);  /* don't care value, year is mandatory */\n\tparts[DUK_DATE_IDX_MONTH] = 1;\n\tparts[DUK_DATE_IDX_DAY] = 1;\n\n\t/* Special handling for year sign. */\n\tp = (const duk_uint8_t *) str;\n\tch = p[0];\n\tif (ch == DUK_ASC_PLUS) {\n\t\tp++;\n\t} else if (ch == DUK_ASC_MINUS) {\n\t\tneg_year = 1;\n\t\tp++;\n\t}\n\n\tfor (;;) {\n\t\tch = *p++;\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsing, part_idx=%ld, char=%ld ('%c')\",\n\t\t                     (long) part_idx, (long) ch,\n\t\t                     (int) ((ch >= 0x20 && ch <= 0x7e) ? ch : DUK_ASC_QUESTION)));\n\n\t\tif (ch >= DUK_ASC_0 && ch <= DUK_ASC_9) {\n\t\t\tif (ndigits >= 9) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"too many digits -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tif (part_idx == DUK__PI_MILLISECOND && ndigits >= 3) {\n\t\t\t\t/* ignore millisecond fractions after 3 */\n\t\t\t} else {\n\t\t\t\taccum = accum * 10 + ((duk_int_t) ch) - ((duk_int_t) DUK_ASC_0) + 0x00;\n\t\t\t\tndigits++;\n\t\t\t}\n\t\t} else {\n\t\t\tduk_uint_fast32_t match_val;\n\t\t\tduk_small_uint_t sep_idx;\n\n\t\t\tif (ndigits <= 0) {\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tif (part_idx == DUK__PI_MILLISECOND) {\n\t\t\t\t/* complete the millisecond field */\n\t\t\t\twhile (ndigits < 3) {\n\t\t\t\t\taccum *= 10;\n\t\t\t\t\tndigits++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tparts[part_idx] = accum;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"wrote part %ld -> value %ld\", (long) part_idx, (long) accum));\n\n\t\t\taccum = 0;\n\t\t\tndigits = 0;\n\n\t\t\tfor (i = 0; i < (duk_small_uint_t) (sizeof(duk__parse_iso8601_seps) / sizeof(duk_uint8_t)); i++) {\n\t\t\t\tif (duk__parse_iso8601_seps[i] == ch) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (i == (duk_small_uint_t) (sizeof(duk__parse_iso8601_seps) / sizeof(duk_uint8_t))) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"separator character doesn't match -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\n\t\t\tsep_idx = i;\n\t\t\tmatch_val = (1UL << part_idx) + (1UL << (sep_idx + 9));  /* match against rule part/sep bits */\n\n\t\t\tfor (i = 0; i < (duk_small_uint_t) (sizeof(duk__parse_iso8601_control) / sizeof(duk_uint32_t)); i++) {\n\t\t\t\tduk_uint_fast32_t rule = duk__parse_iso8601_control[i];\n\t\t\t\tduk_small_uint_t nextpart;\n\t\t\t\tduk_small_uint_t cflags;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"part_idx=%ld, sep_idx=%ld, match_val=0x%08lx, considering rule=0x%08lx\",\n\t\t\t\t                     (long) part_idx, (long) sep_idx,\n\t\t\t\t                     (unsigned long) match_val, (unsigned long) rule));\n\n\t\t\t\tif ((rule & match_val) != match_val) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tDUK__UNPACK_RULE(rule, nextpart, cflags);\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rule match -> part_idx=%ld, sep_idx=%ld, match_val=0x%08lx, \"\n\t\t\t\t                     \"rule=0x%08lx -> nextpart=%ld, cflags=0x%02lx\",\n\t\t\t\t                     (long) part_idx, (long) sep_idx,\n\t\t\t\t                     (unsigned long) match_val, (unsigned long) rule,\n\t\t\t\t                     (long) nextpart, (unsigned long) cflags));\n\n\t\t\t\tif (cflags & DUK__CF_NEG) {\n\t\t\t\t\tneg_tzoffset = 1;\n\t\t\t\t}\n\n\t\t\t\tif (cflags & DUK__CF_ACCEPT) {\n\t\t\t\t\tgoto accept;\n\t\t\t\t}\n\n\t\t\t\tif (cflags & DUK__CF_ACCEPT_NUL) {\n\t\t\t\t\tDUK_ASSERT(*(p - 1) != (char) 0);\n\t\t\t\t\tif (*p == DUK_ASC_NUL) {\n\t\t\t\t\t\tgoto accept;\n\t\t\t\t\t}\n\t\t\t\t\tgoto reject;\n\t\t\t\t}\n\n\t\t\t\tpart_idx = nextpart;\n\t\t\t\tbreak;\n\t\t\t}  /* rule match */\n\n\t\t\tif (i == (duk_small_uint_t) (sizeof(duk__parse_iso8601_control) / sizeof(duk_uint32_t))) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"no rule matches -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\n\t\t\tif (ch == 0) {\n\t\t\t\t/* This shouldn't be necessary, but check just in case\n\t\t\t\t * to avoid any chance of overruns.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"NUL after rule matching (should not happen) -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t}  /* if-digit-else-ctrl */\n\t}  /* char loop */\n\n\t/* We should never exit the loop above. */\n\tDUK_UNREACHABLE();\n\n reject:\n\tDUK_DDD(DUK_DDDPRINT(\"reject\"));\n\treturn 0;\n\n accept:\n\tDUK_DDD(DUK_DDDPRINT(\"accept\"));\n\n\t/* Apply timezone offset to get the main parts in UTC */\n\tif (neg_year) {\n\t\tparts[DUK__PI_YEAR] = -parts[DUK__PI_YEAR];\n\t}\n\tif (neg_tzoffset) {\n\t\tparts[DUK__PI_HOUR] += parts[DUK__PI_TZHOUR];\n\t\tparts[DUK__PI_MINUTE] += parts[DUK__PI_TZMINUTE];\n\t} else {\n\t\tparts[DUK__PI_HOUR] -= parts[DUK__PI_TZHOUR];\n\t\tparts[DUK__PI_MINUTE] -= parts[DUK__PI_TZMINUTE];\n\t}\n\tparts[DUK__PI_MONTH] -= 1;  /* zero-based month */\n\tparts[DUK__PI_DAY] -= 1;  /* zero-based day */\n\n\t/* Use double parts, they tolerate unnormalized time.\n\t *\n\t * Note: DUK_DATE_IDX_WEEKDAY is initialized with a bogus value (DUK__PI_TZHOUR)\n\t * on purpose.  It won't be actually used by duk_bi_date_get_timeval_from_dparts(),\n\t * but will make the value initialized just in case, and avoid any\n\t * potential for Valgrind issues.\n\t */\n\tfor (i = 0; i < DUK_DATE_IDX_NUM_PARTS; i++) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"part[%ld] = %ld\", (long) i, (long) parts[i]));\n\t\tdparts[i] = parts[i];\n\t}\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);\n\tduk_push_number(thr, d);\n\treturn 1;\n}\n\n/*\n *  Date/time parsing helper.\n *\n *  Parse a datetime string into a time value.  We must first try to parse\n *  the input according to the standard format in E5.1 Section 15.9.1.15.\n *  If that fails, we can try to parse using custom parsing, which can\n *  either be platform neutral (custom code) or platform specific (using\n *  existing platform API calls).\n *\n *  Note in particular that we must parse whatever toString(), toUTCString(),\n *  and toISOString() can produce; see E5.1 Section 15.9.4.2.\n *\n *  Returns 1 to allow tail calling.\n *\n *  There is much room for improvement here with respect to supporting\n *  alternative datetime formats.  For instance, V8 parses '2012-01-01' as\n *  UTC and '2012/01/01' as local time.\n */\n\nDUK_LOCAL duk_ret_t duk__parse_string(duk_hthread *thr, const char *str) {\n\t/* XXX: there is a small risk here: because the ISO 8601 parser is\n\t * very loose, it may end up parsing some datetime values which\n\t * would be better parsed with a platform specific parser.\n\t */\n\n\tDUK_ASSERT(str != NULL);\n\tDUK_DDD(DUK_DDDPRINT(\"parse datetime from string '%s'\", (const char *) str));\n\n\tif (duk__parse_string_iso8601_subset(thr, str) != 0) {\n\t\treturn 1;\n\t}\n\n#if defined(DUK_USE_DATE_PARSE_STRING)\n\t/* Contract, either:\n\t * - Push value on stack and return 1\n\t * - Don't push anything on stack and return 0\n\t */\n\n\tif (DUK_USE_DATE_PARSE_STRING(thr, str) != 0) {\n\t\treturn 1;\n\t}\n#else\n\t/* No platform-specific parsing, this is not an error. */\n#endif\n\n\tduk_push_nan(thr);\n\treturn 1;\n}\n\n/*\n *  Calendar helpers\n *\n *  Some helpers are used for getters and can operate on normalized values\n *  which can be represented with 32-bit signed integers.  Other helpers are\n *  needed by setters and operate on un-normalized double values, must watch\n *  out for non-finite numbers etc.\n */\n\nDUK_LOCAL duk_uint8_t duk__days_in_month[12] = {\n\t(duk_uint8_t) 31, (duk_uint8_t) 28, (duk_uint8_t) 31, (duk_uint8_t) 30,\n\t(duk_uint8_t) 31, (duk_uint8_t) 30, (duk_uint8_t) 31, (duk_uint8_t) 31,\n\t(duk_uint8_t) 30, (duk_uint8_t) 31, (duk_uint8_t) 30, (duk_uint8_t) 31\n};\n\n/* Maximum iteration count for computing UTC-to-local time offset when\n * creating an ECMAScript time value from local parts.\n */\n#define DUK__LOCAL_TZOFFSET_MAXITER   4\n\n/* Because 'day since epoch' can be negative and is used to compute weekday\n * using a modulo operation, add this multiple of 7 to avoid negative values\n * when year is below 1970 epoch.  ECMAScript time values are restricted to\n * +/- 100 million days from epoch, so this adder fits nicely into 32 bits.\n * Round to a multiple of 7 (= floor(100000000 / 7) * 7) and add margin.\n */\n#define DUK__WEEKDAY_MOD_ADDER  (20000000 * 7)  /* 0x08583b00 */\n\nDUK_INTERNAL duk_bool_t duk_bi_date_is_leap_year(duk_int_t year) {\n\tif ((year % 4) != 0) {\n\t\treturn 0;\n\t}\n\tif ((year % 100) != 0) {\n\t\treturn 1;\n\t}\n\tif ((year % 400) != 0) {\n\t\treturn 0;\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_bool_t duk_bi_date_timeval_in_valid_range(duk_double_t x) {\n\treturn (x >= -DUK_DATE_MSEC_100M_DAYS && x <= DUK_DATE_MSEC_100M_DAYS);\n}\n\nDUK_INTERNAL duk_bool_t duk_bi_date_timeval_in_leeway_range(duk_double_t x) {\n\treturn (x >= -DUK_DATE_MSEC_100M_DAYS_LEEWAY && x <= DUK_DATE_MSEC_100M_DAYS_LEEWAY);\n}\n\nDUK_INTERNAL duk_bool_t duk_bi_date_year_in_valid_range(duk_double_t x) {\n\treturn (x >= DUK_DATE_MIN_ECMA_YEAR && x <= DUK_DATE_MAX_ECMA_YEAR);\n}\n\nDUK_LOCAL duk_double_t duk__timeclip(duk_double_t x) {\n\tif (!DUK_ISFINITE(x)) {\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\n\tif (!duk_bi_date_timeval_in_valid_range(x)) {\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\n\tx = duk_js_tointeger_number(x);\n\n\t/* Here we'd have the option to normalize -0 to +0. */\n\treturn x;\n}\n\n/* Integer division which floors also negative values correctly. */\nDUK_LOCAL duk_int_t duk__div_floor(duk_int_t a, duk_int_t b) {\n\tDUK_ASSERT(b > 0);\n\tif (a >= 0) {\n\t\treturn a / b;\n\t} else {\n\t\t/* e.g. a = -4, b = 5  -->  -4 - 5 + 1 / 5  -->  -8 / 5  -->  -1\n\t\t *      a = -5, b = 5  -->  -5 - 5 + 1 / 5  -->  -9 / 5  -->  -1\n\t\t *      a = -6, b = 5  -->  -6 - 5 + 1 / 5  -->  -10 / 5  -->  -2\n\t\t */\n\t\treturn (a - b + 1) / b;\n\t}\n}\n\n/* Compute day number of the first day of a given year. */\nDUK_LOCAL duk_int_t duk__day_from_year(duk_int_t year) {\n\t/* Note: in integer arithmetic, (x / 4) is same as floor(x / 4) for non-negative\n\t * values, but is incorrect for negative ones.\n\t */\n\treturn 365 * (year - 1970)\n\t       + duk__div_floor(year - 1969, 4)\n\t       - duk__div_floor(year - 1901, 100)\n\t       + duk__div_floor(year - 1601, 400);\n}\n\n/* Given a day number, determine year and day-within-year. */\nDUK_LOCAL duk_int_t duk__year_from_day(duk_int_t day, duk_small_int_t *out_day_within_year) {\n\tduk_int_t year;\n\tduk_int_t diff_days;\n\n\t/* estimate year upwards (towards positive infinity), then back down;\n\t * two iterations should be enough\n\t */\n\n\tif (day >= 0) {\n\t\tyear = 1970 + day / 365;\n\t} else {\n\t\tyear = 1970 + day / 366;\n\t}\n\n\tfor (;;) {\n\t\tdiff_days = duk__day_from_year(year) - day;\n\t\tDUK_DDD(DUK_DDDPRINT(\"year=%ld day=%ld, diff_days=%ld\", (long) year, (long) day, (long) diff_days));\n\t\tif (diff_days <= 0) {\n\t\t\tDUK_ASSERT(-diff_days < 366);  /* fits into duk_small_int_t */\n\t\t\t*out_day_within_year = -diff_days;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"--> year=%ld, day-within-year=%ld\",\n\t\t\t                     (long) year, (long) *out_day_within_year));\n\t\t\tDUK_ASSERT(*out_day_within_year >= 0);\n\t\t\tDUK_ASSERT(*out_day_within_year < (duk_bi_date_is_leap_year(year) ? 366 : 365));\n\t\t\treturn year;\n\t\t}\n\n\t\t/* Note: this is very tricky; we must never 'overshoot' the\n\t\t * correction downwards.\n\t\t */\n\t\tyear -= 1 + (diff_days - 1) / 366;  /* conservative */\n\t}\n}\n\n/* Given a (year, month, day-within-month) triple, compute day number.\n * The input triple is un-normalized and may contain non-finite values.\n */\nDUK_LOCAL duk_double_t duk__make_day(duk_double_t year, duk_double_t month, duk_double_t day) {\n\tduk_int_t day_num;\n\tduk_bool_t is_leap;\n\tduk_small_int_t i, n;\n\n\t/* Assume that year, month, day are all coerced to whole numbers.\n\t * They may also be NaN or infinity, in which case this function\n\t * must return NaN or infinity to ensure time value becomes NaN.\n\t * If 'day' is NaN, the final return will end up returning a NaN,\n\t * so it doesn't need to be checked here.\n\t */\n\n\tif (!DUK_ISFINITE(year) || !DUK_ISFINITE(month)) {\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\n\tyear += DUK_FLOOR(month / 12.0);\n\n\tmonth = DUK_FMOD(month, 12.0);\n\tif (month < 0.0) {\n\t\t/* handle negative values */\n\t\tmonth += 12.0;\n\t}\n\n\t/* The algorithm in E5.1 Section 15.9.1.12 normalizes month, but\n\t * does not normalize the day-of-month (nor check whether or not\n\t * it is finite) because it's not necessary for finding the day\n\t * number which matches the (year,month) pair.\n\t *\n\t * We assume that duk__day_from_year() is exact here.\n\t *\n\t * Without an explicit infinity / NaN check in the beginning,\n\t * day_num would be a bogus integer here.\n\t *\n\t * It's possible for 'year' to be out of integer range here.\n\t * If so, we need to return NaN without integer overflow.\n\t * This fixes test-bug-setyear-overflow.js.\n\t */\n\n\tif (!duk_bi_date_year_in_valid_range(year)) {\n\t\tDUK_DD(DUK_DDPRINT(\"year not in ecmascript valid range, avoid integer overflow: %lf\", (double) year));\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\tday_num = duk__day_from_year((duk_int_t) year);\n\tis_leap = duk_bi_date_is_leap_year((duk_int_t) year);\n\n\tn = (duk_small_int_t) month;\n\tfor (i = 0; i < n; i++) {\n\t\tday_num += duk__days_in_month[i];\n\t\tif (i == 1 && is_leap) {\n\t\t\tday_num++;\n\t\t}\n\t}\n\n\t/* If 'day' is NaN, returns NaN. */\n\treturn (duk_double_t) day_num + day;\n}\n\n/* Split time value into parts.  The time value may contain fractions (it may\n * come from duk_time_to_components() API call) which are truncated.  Possible\n * local time adjustment has already been applied when reading the time value.\n */\nDUK_INTERNAL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts, duk_double_t *dparts, duk_small_uint_t flags) {\n\tduk_double_t d1, d2;\n\tduk_int_t t1, t2;\n\tduk_int_t day_since_epoch;\n\tduk_int_t year;  /* does not fit into 16 bits */\n\tduk_small_int_t day_in_year;\n\tduk_small_int_t month;\n\tduk_small_int_t day;\n\tduk_small_int_t dim;\n\tduk_int_t jan1_since_epoch;\n\tduk_small_int_t jan1_weekday;\n\tduk_int_t equiv_year;\n\tduk_small_uint_t i;\n\tduk_bool_t is_leap;\n\tduk_small_int_t arridx;\n\n\tDUK_ASSERT(DUK_ISFINITE(d));    /* caller checks */\n\td = DUK_FLOOR(d);  /* remove fractions if present */\n\tDUK_ASSERT(DUK_FLOOR(d) == d);\n\n\t/* The timevalue must be in valid ECMAScript range, but since a local\n\t * time offset can be applied, we need to allow a +/- 24h leeway to\n\t * the value.  In other words, although the UTC time is within the\n\t * ECMAScript range, the local part values can be just outside of it.\n\t */\n\tDUK_UNREF(duk_bi_date_timeval_in_leeway_range);\n\tDUK_ASSERT(duk_bi_date_timeval_in_leeway_range(d));\n\n\t/* These computations are guaranteed to be exact for the valid\n\t * E5 time value range, assuming milliseconds without fractions.\n\t */\n\td1 = (duk_double_t) DUK_FMOD(d, (double) DUK_DATE_MSEC_DAY);\n\tif (d1 < 0.0) {\n\t\t/* deal with negative values */\n\t\td1 += (duk_double_t) DUK_DATE_MSEC_DAY;\n\t}\n\td2 = DUK_FLOOR((double) (d / (duk_double_t) DUK_DATE_MSEC_DAY));\n\tDUK_ASSERT(d2 * ((duk_double_t) DUK_DATE_MSEC_DAY) + d1 == d);\n\t/* now expected to fit into a 32-bit integer */\n\tt1 = (duk_int_t) d1;\n\tt2 = (duk_int_t) d2;\n\tday_since_epoch = t2;\n\tDUK_ASSERT((duk_double_t) t1 == d1);\n\tDUK_ASSERT((duk_double_t) t2 == d2);\n\n\t/* t1 = milliseconds within day (fits 32 bit)\n\t * t2 = day number from epoch (fits 32 bit, may be negative)\n\t */\n\n\tparts[DUK_DATE_IDX_MILLISECOND] = t1 % 1000; t1 /= 1000;\n\tparts[DUK_DATE_IDX_SECOND] = t1 % 60; t1 /= 60;\n\tparts[DUK_DATE_IDX_MINUTE] = t1 % 60; t1 /= 60;\n\tparts[DUK_DATE_IDX_HOUR] = t1;\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MILLISECOND] >= 0 && parts[DUK_DATE_IDX_MILLISECOND] <= 999);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_SECOND] >= 0 && parts[DUK_DATE_IDX_SECOND] <= 59);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MINUTE] >= 0 && parts[DUK_DATE_IDX_MINUTE] <= 59);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_HOUR] >= 0 && parts[DUK_DATE_IDX_HOUR] <= 23);\n\n\tDUK_DDD(DUK_DDDPRINT(\"d=%lf, d1=%lf, d2=%lf, t1=%ld, t2=%ld, parts: hour=%ld min=%ld sec=%ld msec=%ld\",\n\t                     (double) d, (double) d1, (double) d2, (long) t1, (long) t2,\n\t                     (long) parts[DUK_DATE_IDX_HOUR],\n\t                     (long) parts[DUK_DATE_IDX_MINUTE],\n\t                     (long) parts[DUK_DATE_IDX_SECOND],\n\t                     (long) parts[DUK_DATE_IDX_MILLISECOND]));\n\n\t/* This assert depends on the input parts representing time inside\n\t * the ECMAScript range.\n\t */\n\tDUK_ASSERT(t2 + DUK__WEEKDAY_MOD_ADDER >= 0);\n\tparts[DUK_DATE_IDX_WEEKDAY] = (t2 + 4 + DUK__WEEKDAY_MOD_ADDER) % 7;  /* E5.1 Section 15.9.1.6 */\n\tDUK_ASSERT(parts[DUK_DATE_IDX_WEEKDAY] >= 0 && parts[DUK_DATE_IDX_WEEKDAY] <= 6);\n\n\tyear = duk__year_from_day(t2, &day_in_year);\n\tday = day_in_year;\n\tis_leap = duk_bi_date_is_leap_year(year);\n\tfor (month = 0; month < 12; month++) {\n\t\tdim = duk__days_in_month[month];\n\t\tif (month == 1 && is_leap) {\n\t\t\tdim++;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"month=%ld, dim=%ld, day=%ld\",\n\t\t                     (long) month, (long) dim, (long) day));\n\t\tif (day < dim) {\n\t\t\tbreak;\n\t\t}\n\t\tday -= dim;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"final month=%ld\", (long) month));\n\tDUK_ASSERT(month >= 0 && month <= 11);\n\tDUK_ASSERT(day >= 0 && day <= 31);\n\n\t/* Equivalent year mapping, used to avoid DST trouble when platform\n\t * may fail to provide reasonable DST answers for dates outside the\n\t * ordinary range (e.g. 1970-2038).  An equivalent year has the same\n\t * leap-year-ness as the original year and begins on the same weekday\n\t * (Jan 1).\n\t *\n\t * The year 2038 is avoided because there seem to be problems with it\n\t * on some platforms.  The year 1970 is also avoided as there were\n\t * practical problems with it; an equivalent year is used for it too,\n\t * which breaks some DST computations for 1970 right now, see e.g.\n\t * test-bi-date-tzoffset-brute-fi.js.\n\t */\n\tif ((flags & DUK_DATE_FLAG_EQUIVYEAR) && (year < 1971 || year > 2037)) {\n\t\tDUK_ASSERT(is_leap == 0 || is_leap == 1);\n\n\t\tjan1_since_epoch = day_since_epoch - day_in_year;  /* day number for Jan 1 since epoch */\n\t\tDUK_ASSERT(jan1_since_epoch + DUK__WEEKDAY_MOD_ADDER >= 0);\n\t\tjan1_weekday = (jan1_since_epoch + 4 + DUK__WEEKDAY_MOD_ADDER) % 7;  /* E5.1 Section 15.9.1.6 */\n\t\tDUK_ASSERT(jan1_weekday >= 0 && jan1_weekday <= 6);\n\t\tarridx = jan1_weekday;\n\t\tif (is_leap) {\n\t\t\tarridx += 7;\n\t\t}\n\t\tDUK_ASSERT(arridx >= 0 && arridx < (duk_small_int_t) (sizeof(duk__date_equivyear) / sizeof(duk_uint8_t)));\n\n\t\tequiv_year = (duk_int_t) duk__date_equivyear[arridx] + 1970;\n\t\tyear = equiv_year;\n\t\tDUK_DDD(DUK_DDDPRINT(\"equiv year mapping, year=%ld, day_in_year=%ld, day_since_epoch=%ld, \"\n\t\t                     \"jan1_since_epoch=%ld, jan1_weekday=%ld -> equiv year %ld\",\n\t\t                     (long) year, (long) day_in_year, (long) day_since_epoch,\n\t\t                     (long) jan1_since_epoch, (long) jan1_weekday, (long) equiv_year));\n\t}\n\n\tparts[DUK_DATE_IDX_YEAR] = year;\n\tparts[DUK_DATE_IDX_MONTH] = month;\n\tparts[DUK_DATE_IDX_DAY] = day;\n\n\tif (flags & DUK_DATE_FLAG_ONEBASED) {\n\t\tparts[DUK_DATE_IDX_MONTH]++;  /* zero-based -> one-based */\n\t\tparts[DUK_DATE_IDX_DAY]++;    /* -\"\"- */\n\t}\n\n\tif (dparts != NULL) {\n\t\tfor (i = 0; i < DUK_DATE_IDX_NUM_PARTS; i++) {\n\t\t\tdparts[i] = (duk_double_t) parts[i];\n\t\t}\n\t}\n}\n\n/* Compute time value from (double) parts.  The parts can be either UTC\n * or local time; if local, they need to be (conceptually) converted into\n * UTC time.  The parts may represent valid or invalid time, and may be\n * wildly out of range (but may cancel each other and still come out in\n * the valid Date range).\n */\nDUK_INTERNAL duk_double_t duk_bi_date_get_timeval_from_dparts(duk_double_t *dparts, duk_small_uint_t flags) {\n#if defined(DUK_USE_PARANOID_DATE_COMPUTATION)\n\t/* See comments below on MakeTime why these are volatile. */\n\tvolatile duk_double_t tmp_time;\n\tvolatile duk_double_t tmp_day;\n\tvolatile duk_double_t d;\n#else\n\tduk_double_t tmp_time;\n\tduk_double_t tmp_day;\n\tduk_double_t d;\n#endif\n\tduk_small_uint_t i;\n\tduk_int_t tzoff, tzoffprev1, tzoffprev2;\n\n\t/* Expects 'this' at top of stack on entry. */\n\n\t/* Coerce all finite parts with ToInteger().  ToInteger() must not\n\t * be called for NaN/Infinity because it will convert e.g. NaN to\n\t * zero.  If ToInteger() has already been called, this has no side\n\t * effects and is idempotent.\n\t *\n\t * Don't read dparts[DUK_DATE_IDX_WEEKDAY]; it will cause Valgrind\n\t * issues if the value is uninitialized.\n\t */\n\tfor (i = 0; i <= DUK_DATE_IDX_MILLISECOND; i++) {\n\t\t/* SCANBUILD: scan-build complains here about assigned value\n\t\t * being garbage or undefined.  This is correct but operating\n\t\t * on undefined values has no ill effect and is ignored by the\n\t\t * caller in the case where this happens.\n\t\t */\n\t\td = dparts[i];\n\t\tif (DUK_ISFINITE(d)) {\n\t\t\tdparts[i] = duk_js_tointeger_number(d);\n\t\t}\n\t}\n\n\t/* Use explicit steps in computation to try to ensure that\n\t * computation happens with intermediate results coerced to\n\t * double values (instead of using something more accurate).\n\t * E.g. E5.1 Section 15.9.1.11 requires use of IEEE 754\n\t * rules (= ECMAScript '+' and '*' operators).\n\t *\n\t * Without 'volatile' even this approach fails on some platform\n\t * and compiler combinations.  For instance, gcc 4.8.1 on Ubuntu\n\t * 64-bit, with -m32 and without -std=c99, test-bi-date-canceling.js\n\t * would fail because of some optimizations when computing tmp_time\n\t * (MakeTime below).  Adding 'volatile' to tmp_time solved this\n\t * particular problem (annoyingly, also adding debug prints or\n\t * running the executable under valgrind hides it).\n\t */\n\n\t/* MakeTime */\n\ttmp_time = 0.0;\n\ttmp_time += dparts[DUK_DATE_IDX_HOUR] * ((duk_double_t) DUK_DATE_MSEC_HOUR);\n\ttmp_time += dparts[DUK_DATE_IDX_MINUTE] * ((duk_double_t) DUK_DATE_MSEC_MINUTE);\n\ttmp_time += dparts[DUK_DATE_IDX_SECOND] * ((duk_double_t) DUK_DATE_MSEC_SECOND);\n\ttmp_time += dparts[DUK_DATE_IDX_MILLISECOND];\n\n\t/* MakeDay */\n\ttmp_day = duk__make_day(dparts[DUK_DATE_IDX_YEAR], dparts[DUK_DATE_IDX_MONTH], dparts[DUK_DATE_IDX_DAY]);\n\n\t/* MakeDate */\n\td = tmp_day * ((duk_double_t) DUK_DATE_MSEC_DAY) + tmp_time;\n\n\tDUK_DDD(DUK_DDDPRINT(\"time=%lf day=%lf --> timeval=%lf\",\n\t                     (double) tmp_time, (double) tmp_day, (double) d));\n\n\t/* Optional UTC conversion. */\n\tif (flags & DUK_DATE_FLAG_LOCALTIME) {\n\t\t/* DUK_USE_DATE_GET_LOCAL_TZOFFSET() needs to be called with a\n\t\t * time value computed from UTC parts.  At this point we only\n\t\t * have 'd' which is a time value computed from local parts, so\n\t\t * it is off by the UTC-to-local time offset which we don't know\n\t\t * yet.  The current solution for computing the UTC-to-local\n\t\t * time offset is to iterate a few times and detect a fixed\n\t\t * point or a two-cycle loop (or a sanity iteration limit),\n\t\t * see test-bi-date-local-parts.js and test-bi-date-tzoffset-basic-fi.js.\n\t\t *\n\t\t * E5.1 Section 15.9.1.9:\n\t\t * UTC(t) = t - LocalTZA - DaylightSavingTA(t - LocalTZA)\n\t\t *\n\t\t * For NaN/inf, DUK_USE_DATE_GET_LOCAL_TZOFFSET() returns 0.\n\t\t */\n\n#if 0\n\t\t/* Old solution: don't iterate, incorrect */\n\t\ttzoff = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);\n\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset w/o iteration, tzoff=%ld\", (long) tzoff));\n\t\td -= tzoff * 1000L;\n\t\tDUK_UNREF(tzoffprev1);\n\t\tDUK_UNREF(tzoffprev2);\n#endif\n\n\t\t/* Iteration solution */\n\t\ttzoff = 0;\n\t\ttzoffprev1 = 999999999L;  /* invalid value which never matches */\n\t\tfor (i = 0; i < DUK__LOCAL_TZOFFSET_MAXITER; i++) {\n\t\t\ttzoffprev2 = tzoffprev1;\n\t\t\ttzoffprev1 = tzoff;\n\t\t\ttzoff = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d - tzoff * 1000L);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration, i=%d, tzoff=%ld, tzoffprev1=%ld tzoffprev2=%ld\",\n\t\t\t                     (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2));\n\t\t\tif (tzoff == tzoffprev1) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration finished, i=%d, tzoff=%ld, tzoffprev1=%ld, tzoffprev2=%ld\",\n\t\t\t\t                     (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2));\n\t\t\t\tbreak;\n\t\t\t} else if (tzoff == tzoffprev2) {\n\t\t\t\t/* Two value cycle, see e.g. test-bi-date-tzoffset-basic-fi.js.\n\t\t\t\t * In these cases, favor a higher tzoffset to get a consistent\n\t\t\t\t * result which is independent of iteration count.  Not sure if\n\t\t\t\t * this is a generically correct solution.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration two-value cycle, i=%d, tzoff=%ld, tzoffprev1=%ld, tzoffprev2=%ld\",\n\t\t\t\t                     (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2));\n\t\t\t\tif (tzoffprev1 > tzoff) {\n\t\t\t\t\ttzoff = tzoffprev1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration, tzoff=%ld\", (long) tzoff));\n\t\td -= tzoff * 1000L;\n\t}\n\n\t/* TimeClip(), which also handles Infinity -> NaN conversion */\n\td = duk__timeclip(d);\n\n\treturn d;\n}\n\n/*\n *  API oriented helpers\n */\n\n/* Push 'this' binding, check that it is a Date object; then push the\n * internal time value.  At the end, stack is: [ ... this timeval ].\n * Returns the time value.  Local time adjustment is done if requested.\n */\nDUK_LOCAL duk_double_t duk__push_this_get_timeval_tzoffset(duk_hthread *thr, duk_small_uint_t flags, duk_int_t *out_tzoffset) {\n\tduk_hobject *h;\n\tduk_double_t d;\n\tduk_int_t tzoffset = 0;\n\n\tduk_push_this(thr);\n\th = duk_get_hobject(thr, -1);  /* XXX: getter with class check, useful in built-ins */\n\tif (h == NULL || DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_DATE) {\n\t\tDUK_ERROR_TYPE(thr, \"expected Date\");\n\t\tDUK_WO_NORETURN(return 0.0;);\n\t}\n\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\td = duk_to_number_m1(thr);\n\tduk_pop(thr);\n\n\tif (DUK_ISNAN(d)) {\n\t\tif (flags & DUK_DATE_FLAG_NAN_TO_ZERO) {\n\t\t\td = 0.0;\n\t\t}\n\t\tif (flags & DUK_DATE_FLAG_NAN_TO_RANGE_ERROR) {\n\t\t\tDUK_ERROR_RANGE(thr, \"Invalid Date\");\n\t\t\tDUK_WO_NORETURN(return 0.0;);\n\t\t}\n\t}\n\t/* if no NaN handling flag, may still be NaN here, but not Inf */\n\tDUK_ASSERT(!DUK_ISINF(d));\n\n\tif (flags & DUK_DATE_FLAG_LOCALTIME) {\n\t\t/* Note: DST adjustment is determined using UTC time.\n\t\t * If 'd' is NaN, tzoffset will be 0.\n\t\t */\n\t\ttzoffset = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);  /* seconds */\n\t\td += tzoffset * 1000L;\n\t}\n\tif (out_tzoffset) {\n\t\t*out_tzoffset = tzoffset;\n\t}\n\n\t/* [ ... this ] */\n\treturn d;\n}\n\nDUK_LOCAL duk_double_t duk__push_this_get_timeval(duk_hthread *thr, duk_small_uint_t flags) {\n\treturn duk__push_this_get_timeval_tzoffset(thr, flags, NULL);\n}\n\n/* Set timeval to 'this' from dparts, push the new time value onto the\n * value stack and return 1 (caller can then tail call us).  Expects\n * the value stack to contain 'this' on the stack top.\n */\nDUK_LOCAL duk_ret_t duk__set_this_timeval_from_dparts(duk_hthread *thr, duk_double_t *dparts, duk_small_uint_t flags) {\n\tduk_double_t d;\n\n\t/* [ ... this ] */\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, flags);\n\tduk_push_number(thr, d);  /* -> [ ... this timeval_new ] */\n\tduk_dup_top(thr);         /* -> [ ... this timeval_new timeval_new ] */\n\n\t/* Must force write because e.g. .setYear() must work even when\n\t * the Date instance is frozen.\n\t */\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\n\t/* Stack top: new time value, return 1 to allow tail calls. */\n\treturn 1;\n}\n\n/* 'out_buf' must be at least DUK_BI_DATE_ISO8601_BUFSIZE long. */\nDUK_LOCAL void duk__format_parts_iso8601(duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags, duk_uint8_t *out_buf) {\n\tchar yearstr[8];   /* \"-123456\\0\" */\n\tchar tzstr[8];     /* \"+11:22\\0\" */\n\tchar sep = (flags & DUK_DATE_FLAG_SEP_T) ? DUK_ASC_UC_T : DUK_ASC_SPACE;\n\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MONTH] >= 1 && parts[DUK_DATE_IDX_MONTH] <= 12);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_DAY] >= 1 && parts[DUK_DATE_IDX_DAY] <= 31);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_YEAR] >= -999999 && parts[DUK_DATE_IDX_YEAR] <= 999999);\n\n\t/* Note: %06d for positive value, %07d for negative value to include\n\t * sign and 6 digits.\n\t */\n\tDUK_SNPRINTF(yearstr,\n\t             sizeof(yearstr),\n\t             (parts[DUK_DATE_IDX_YEAR] >= 0 && parts[DUK_DATE_IDX_YEAR] <= 9999) ? \"%04ld\" :\n\t                    ((parts[DUK_DATE_IDX_YEAR] >= 0) ? \"+%06ld\" : \"%07ld\"),\n\t             (long) parts[DUK_DATE_IDX_YEAR]);\n\tyearstr[sizeof(yearstr) - 1] = (char) 0;\n\n\tif (flags & DUK_DATE_FLAG_LOCALTIME) {\n\t\t/* tzoffset seconds are dropped; 16 bits suffice for\n\t\t * time offset in minutes\n\t\t */\n\t\tconst char *fmt;\n\t\tduk_small_int_t tmp, arg_hours, arg_minutes;\n\n\t\tif (tzoffset >= 0) {\n\t\t\ttmp = tzoffset;\n\t\t\tfmt = \"+%02d:%02d\";\n\t\t} else {\n\t\t\ttmp = -tzoffset;\n\t\t\tfmt = \"-%02d:%02d\";\n\t\t}\n\t\ttmp = tmp / 60;\n\t\targ_hours = tmp / 60;\n\t\targ_minutes = tmp % 60;\n\t\tDUK_ASSERT(arg_hours <= 24);  /* Even less is actually guaranteed for a valid tzoffset. */\n\t\targ_hours = arg_hours & 0x3f;  /* For [0,24] this is a no-op, but fixes GCC 7 warning, see https://github.com/svaarala/duktape/issues/1602. */\n\n\t\tDUK_SNPRINTF(tzstr, sizeof(tzstr), fmt, (int) arg_hours, (int) arg_minutes);\n\t\ttzstr[sizeof(tzstr) - 1] = (char) 0;\n\t} else {\n\t\ttzstr[0] = DUK_ASC_UC_Z;\n\t\ttzstr[1] = (char) 0;\n\t}\n\n\t/* Unlike year, the other parts fit into 16 bits so %d format\n\t * is portable.\n\t */\n\tif ((flags & DUK_DATE_FLAG_TOSTRING_DATE) && (flags & DUK_DATE_FLAG_TOSTRING_TIME)) {\n\t\tDUK_SPRINTF((char *) out_buf, \"%s-%02d-%02d%c%02d:%02d:%02d.%03d%s\",\n\t\t            (const char *) yearstr, (int) parts[DUK_DATE_IDX_MONTH], (int) parts[DUK_DATE_IDX_DAY], (int) sep,\n\t\t            (int) parts[DUK_DATE_IDX_HOUR], (int) parts[DUK_DATE_IDX_MINUTE],\n\t\t            (int) parts[DUK_DATE_IDX_SECOND], (int) parts[DUK_DATE_IDX_MILLISECOND], (const char *) tzstr);\n\t} else if (flags & DUK_DATE_FLAG_TOSTRING_DATE) {\n\t\tDUK_SPRINTF((char *) out_buf, \"%s-%02d-%02d\",\n\t\t            (const char *) yearstr, (int) parts[DUK_DATE_IDX_MONTH], (int) parts[DUK_DATE_IDX_DAY]);\n\t} else {\n\t\tDUK_ASSERT(flags & DUK_DATE_FLAG_TOSTRING_TIME);\n\t\tDUK_SPRINTF((char *) out_buf, \"%02d:%02d:%02d.%03d%s\",\n\t\t            (int) parts[DUK_DATE_IDX_HOUR], (int) parts[DUK_DATE_IDX_MINUTE],\n\t\t            (int) parts[DUK_DATE_IDX_SECOND], (int) parts[DUK_DATE_IDX_MILLISECOND],\n\t\t            (const char *) tzstr);\n\t}\n}\n\n/* Helper for string conversion calls: check 'this' binding, get the\n * internal time value, and format date and/or time in a few formats.\n * Return value allows tail calls.\n */\nDUK_LOCAL duk_ret_t duk__to_string_helper(duk_hthread *thr, duk_small_uint_t flags) {\n\tduk_double_t d;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_int_t tzoffset;  /* seconds, doesn't fit into 16 bits */\n\tduk_bool_t rc;\n\tduk_uint8_t buf[DUK_BI_DATE_ISO8601_BUFSIZE];\n\n\tDUK_UNREF(rc);  /* unreferenced with some options */\n\n\td = duk__push_this_get_timeval_tzoffset(thr, flags, &tzoffset);\n\tif (DUK_ISNAN(d)) {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_INVALID_DATE);\n\t\treturn 1;\n\t}\n\tDUK_ASSERT(DUK_ISFINITE(d));\n\n\t/* formatters always get one-based month/day-of-month */\n\tduk_bi_date_timeval_to_parts(d, parts, NULL, DUK_DATE_FLAG_ONEBASED);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MONTH] >= 1 && parts[DUK_DATE_IDX_MONTH] <= 12);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_DAY] >= 1 && parts[DUK_DATE_IDX_DAY] <= 31);\n\n\tif (flags & DUK_DATE_FLAG_TOSTRING_LOCALE) {\n\t\t/* try locale specific formatter; if it refuses to format the\n\t\t * string, fall back to an ISO 8601 formatted value in local\n\t\t * time.\n\t\t */\n#if defined(DUK_USE_DATE_FORMAT_STRING)\n\t\t/* Contract, either:\n\t\t * - Push string to value stack and return 1\n\t\t * - Don't push anything and return 0\n\t\t */\n\n\t\trc = DUK_USE_DATE_FORMAT_STRING(thr, parts, tzoffset, flags);\n\t\tif (rc != 0) {\n\t\t\treturn 1;\n\t\t}\n#else\n\t\t/* No locale specific formatter; this is OK, we fall back\n\t\t * to ISO 8601.\n\t\t */\n#endif\n\t}\n\n\t/* Different calling convention than above used because the helper\n\t * is shared.\n\t */\n\tduk__format_parts_iso8601(parts, tzoffset, flags, buf);\n\tduk_push_string(thr, (const char *) buf);\n\treturn 1;\n}\n\n/* Helper for component getter calls: check 'this' binding, get the\n * internal time value, split it into parts (either as UTC time or\n * local time), push a specified component as a return value to the\n * value stack and return 1 (caller can then tail call us).\n */\nDUK_LOCAL duk_ret_t duk__get_part_helper(duk_hthread *thr, duk_small_uint_t flags_and_idx) {\n\tduk_double_t d;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_small_uint_t idx_part = (duk_small_uint_t) (flags_and_idx >> DUK_DATE_FLAG_VALUE_SHIFT);  /* unpack args */\n\n\tDUK_ASSERT_DISABLE(idx_part >= 0);  /* unsigned */\n\tDUK_ASSERT(idx_part < DUK_DATE_IDX_NUM_PARTS);\n\n\td = duk__push_this_get_timeval(thr, flags_and_idx);\n\tif (DUK_ISNAN(d)) {\n\t\tduk_push_nan(thr);\n\t\treturn 1;\n\t}\n\tDUK_ASSERT(DUK_ISFINITE(d));\n\n\tduk_bi_date_timeval_to_parts(d, parts, NULL, flags_and_idx);  /* no need to mask idx portion */\n\n\t/* Setter APIs detect special year numbers (0...99) and apply a +1900\n\t * only in certain cases.  The legacy getYear() getter applies -1900\n\t * unconditionally.\n\t */\n\tduk_push_int(thr, (flags_and_idx & DUK_DATE_FLAG_SUB1900) ? parts[idx_part] - 1900 : parts[idx_part]);\n\treturn 1;\n}\n\n/* Helper for component setter calls: check 'this' binding, get the\n * internal time value, split it into parts (either as UTC time or\n * local time), modify one or more components as specified, recompute\n * the time value, set it as the internal value.  Finally, push the\n * new time value as a return value to the value stack and return 1\n * (caller can then tail call us).\n */\nDUK_LOCAL duk_ret_t duk__set_part_helper(duk_hthread *thr, duk_small_uint_t flags_and_maxnargs) {\n\tduk_double_t d;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_idx_t nargs;\n\tduk_small_uint_t maxnargs = (duk_small_uint_t) (flags_and_maxnargs >> DUK_DATE_FLAG_VALUE_SHIFT);  /* unpack args */\n\tduk_small_uint_t idx_first, idx;\n\tduk_small_uint_t i;\n\n\tnargs = duk_get_top(thr);\n\td = duk__push_this_get_timeval(thr, flags_and_maxnargs);\n\tDUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));\n\n\tif (DUK_ISFINITE(d)) {\n\t\tduk_bi_date_timeval_to_parts(d, parts, dparts, flags_and_maxnargs);\n\t} else {\n\t\t/* NaN timevalue: we need to coerce the arguments, but\n\t\t * the resulting internal timestamp needs to remain NaN.\n\t\t * This works but is not pretty: parts and dparts will\n\t\t * be partially uninitialized, but we only write to them.\n\t\t */\n\t}\n\n\t/*\n\t *  Determining which datetime components to overwrite based on\n\t *  stack arguments is a bit complicated, but important to factor\n\t *  out from setters themselves for compactness.\n\t *\n\t *  If DUK_DATE_FLAG_TIMESETTER, maxnargs indicates setter type:\n\t *\n\t *   1 -> millisecond\n\t *   2 -> second, [millisecond]\n\t *   3 -> minute, [second], [millisecond]\n\t *   4 -> hour, [minute], [second], [millisecond]\n\t *\n\t *  Else:\n\t *\n\t *   1 -> date\n\t *   2 -> month, [date]\n\t *   3 -> year, [month], [date]\n\t *\n\t *  By comparing nargs and maxnargs (and flags) we know which\n\t *  components to override.  We rely on part index ordering.\n\t */\n\n\tif (flags_and_maxnargs & DUK_DATE_FLAG_TIMESETTER) {\n\t\tDUK_ASSERT(maxnargs >= 1 && maxnargs <= 4);\n\t\tidx_first = DUK_DATE_IDX_MILLISECOND - (maxnargs - 1);\n\t} else {\n\t\tDUK_ASSERT(maxnargs >= 1 && maxnargs <= 3);\n\t\tidx_first = DUK_DATE_IDX_DAY - (maxnargs - 1);\n\t}\n\tDUK_ASSERT_DISABLE(idx_first >= 0);  /* unsigned */\n\tDUK_ASSERT(idx_first < DUK_DATE_IDX_NUM_PARTS);\n\n\tfor (i = 0; i < maxnargs; i++) {\n\t\tif ((duk_idx_t) i >= nargs) {\n\t\t\t/* no argument given -> leave components untouched */\n\t\t\tbreak;\n\t\t}\n\t\tidx = idx_first + i;\n\t\tDUK_ASSERT_DISABLE(idx >= 0);  /* unsigned */\n\t\tDUK_ASSERT(idx < DUK_DATE_IDX_NUM_PARTS);\n\n\t\tif (idx == DUK_DATE_IDX_YEAR && (flags_and_maxnargs & DUK_DATE_FLAG_YEAR_FIXUP)) {\n\t\t\tduk__twodigit_year_fixup(thr, (duk_idx_t) i);\n\t\t}\n\n\t\tdparts[idx] = duk_to_number(thr, (duk_idx_t) i);\n\n\t\tif (idx == DUK_DATE_IDX_DAY) {\n\t\t\t/* Day-of-month is one-based in the API, but zero-based\n\t\t\t * internally, so fix here.  Note that month is zero-based\n\t\t\t * both in the API and internally.\n\t\t\t */\n\t\t\t/* SCANBUILD: complains about use of uninitialized values.\n\t\t\t * The complaint is correct, but operating in undefined\n\t\t\t * values here is intentional in some cases and the caller\n\t\t\t * ignores the results.\n\t\t\t */\n\t\t\tdparts[idx] -= 1.0;\n\t\t}\n\t}\n\n\t/* Leaves new timevalue on stack top and returns 1, which is correct\n\t * for part setters.\n\t */\n\tif (DUK_ISFINITE(d)) {\n\t\treturn duk__set_this_timeval_from_dparts(thr, dparts, flags_and_maxnargs);\n\t} else {\n\t\t/* Internal timevalue is already NaN, so don't touch it. */\n\t\tduk_push_nan(thr);\n\t\treturn 1;\n\t}\n}\n\n/* Apply ToNumber() to specified index; if ToInteger(val) in [0,99], add\n * 1900 and replace value at idx_val.\n */\nDUK_LOCAL void duk__twodigit_year_fixup(duk_hthread *thr, duk_idx_t idx_val) {\n\tduk_double_t d;\n\n\t/* XXX: idx_val would fit into 16 bits, but using duk_small_uint_t\n\t * might not generate better code due to casting.\n\t */\n\n\t/* E5 Sections 15.9.3.1, B.2.4, B.2.5 */\n\tduk_to_number(thr, idx_val);\n\tif (duk_is_nan(thr, idx_val)) {\n\t\treturn;\n\t}\n\tduk_dup(thr, idx_val);\n\tduk_to_int(thr, -1);\n\td = duk_get_number(thr, -1);  /* get as double to handle huge numbers correctly */\n\tif (d >= 0.0 && d <= 99.0) {\n\t\td += 1900.0;\n\t\tduk_push_number(thr, d);\n\t\tduk_replace(thr, idx_val);\n\t}\n\tduk_pop(thr);\n}\n\n/* Set datetime parts from stack arguments, defaulting any missing values.\n * Day-of-week is not set; it is not required when setting the time value.\n */\nDUK_LOCAL void duk__set_parts_from_args(duk_hthread *thr, duk_double_t *dparts, duk_idx_t nargs) {\n\tduk_double_t d;\n\tduk_small_uint_t i;\n\tduk_small_uint_t idx;\n\n\t/* Causes a ToNumber() coercion, but doesn't break coercion order since\n\t * year is coerced first anyway.\n\t */\n\tduk__twodigit_year_fixup(thr, 0);\n\n\t/* There are at most 7 args, but we use 8 here so that also\n\t * DUK_DATE_IDX_WEEKDAY gets initialized (to zero) to avoid the potential\n\t * for any Valgrind gripes later.\n\t */\n\tfor (i = 0; i < 8; i++) {\n\t\t/* Note: rely on index ordering */\n\t\tidx = DUK_DATE_IDX_YEAR + i;\n\t\tif ((duk_idx_t) i < nargs) {\n\t\t\td = duk_to_number(thr, (duk_idx_t) i);\n\t\t\tif (idx == DUK_DATE_IDX_DAY) {\n\t\t\t\t/* Convert day from one-based to zero-based (internal).  This may\n\t\t\t\t * cause the day part to be negative, which is OK.\n\t\t\t\t */\n\t\t\t\td -= 1.0;\n\t\t\t}\n\t\t} else {\n\t\t\t/* All components default to 0 except day-of-month which defaults\n\t\t\t * to 1.  However, because our internal day-of-month is zero-based,\n\t\t\t * it also defaults to zero here.\n\t\t\t */\n\t\t\td = 0.0;\n\t\t}\n\t\tdparts[idx] = d;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"parts from args -> %lf %lf %lf %lf %lf %lf %lf %lf\",\n\t                     (double) dparts[0], (double) dparts[1],\n\t                     (double) dparts[2], (double) dparts[3],\n\t                     (double) dparts[4], (double) dparts[5],\n\t                     (double) dparts[6], (double) dparts[7]));\n}\n\n/*\n *  Indirect magic value lookup for Date methods.\n *\n *  Date methods don't put their control flags into the function magic value\n *  because they wouldn't fit into a LIGHTFUNC's magic field.  Instead, the\n *  magic value is set to an index pointing to the array of control flags\n *  below.\n *\n *  This must be kept in strict sync with genbuiltins.py!\n */\n\nstatic duk_uint16_t duk__date_magics[] = {\n\t/* 0: toString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 1: toDateString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 2: toTimeString */\n\tDUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 3: toLocaleString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 4: toLocaleDateString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 5: toLocaleTimeString */\n\tDUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 6: toUTCString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME,\n\n\t/* 7: toISOString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_NAN_TO_RANGE_ERROR + DUK_DATE_FLAG_SEP_T,\n\n\t/* 8: getFullYear */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 9: getUTCFullYear */\n\t0 + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 10: getMonth */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MONTH << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 11: getUTCMonth */\n\t0 + (DUK_DATE_IDX_MONTH << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 12: getDate */\n\tDUK_DATE_FLAG_ONEBASED + DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_DAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 13: getUTCDate */\n\tDUK_DATE_FLAG_ONEBASED + (DUK_DATE_IDX_DAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 14: getDay */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_WEEKDAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 15: getUTCDay */\n\t0 + (DUK_DATE_IDX_WEEKDAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 16: getHours */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_HOUR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 17: getUTCHours */\n\t0 + (DUK_DATE_IDX_HOUR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 18: getMinutes */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MINUTE << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 19: getUTCMinutes */\n\t0 + (DUK_DATE_IDX_MINUTE << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 20: getSeconds */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_SECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 21: getUTCSeconds */\n\t0 + (DUK_DATE_IDX_SECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 22: getMilliseconds */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MILLISECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 23: getUTCMilliseconds */\n\t0 + (DUK_DATE_IDX_MILLISECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 24: setMilliseconds */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 25: setUTCMilliseconds */\n\tDUK_DATE_FLAG_TIMESETTER + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 26: setSeconds */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 27: setUTCSeconds */\n\tDUK_DATE_FLAG_TIMESETTER + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 28: setMinutes */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 29: setUTCMinutes */\n\tDUK_DATE_FLAG_TIMESETTER + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 30: setHours */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (4 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 31: setUTCHours */\n\tDUK_DATE_FLAG_TIMESETTER + (4 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 32: setDate */\n\tDUK_DATE_FLAG_LOCALTIME + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 33: setUTCDate */\n\t0 + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 34: setMonth */\n\tDUK_DATE_FLAG_LOCALTIME + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 35: setUTCMonth */\n\t0 + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 36: setFullYear */\n\tDUK_DATE_FLAG_NAN_TO_ZERO + DUK_DATE_FLAG_LOCALTIME + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 37: setUTCFullYear */\n\tDUK_DATE_FLAG_NAN_TO_ZERO + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 38: getYear */\n\tDUK_DATE_FLAG_LOCALTIME + DUK_DATE_FLAG_SUB1900 + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 39: setYear */\n\tDUK_DATE_FLAG_NAN_TO_ZERO + DUK_DATE_FLAG_YEAR_FIXUP + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n};\n\nDUK_LOCAL duk_small_uint_t duk__date_get_indirect_magic(duk_hthread *thr) {\n\tduk_small_uint_t magicidx = (duk_small_uint_t) duk_get_current_magic(thr);\n\tDUK_ASSERT(magicidx < (duk_small_int_t) (sizeof(duk__date_magics) / sizeof(duk_uint16_t)));\n\treturn (duk_small_uint_t) duk__date_magics[magicidx];\n}\n\n#if defined(DUK_USE_DATE_BUILTIN)\n/*\n *  Constructor calls\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor(duk_hthread *thr) {\n\tduk_idx_t nargs = duk_get_top(thr);\n\tduk_bool_t is_cons = duk_is_constructor_call(thr);\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t d;\n\n\tDUK_DDD(DUK_DDDPRINT(\"Date constructor, nargs=%ld, is_cons=%ld\", (long) nargs, (long) is_cons));\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATE),\n\t                              DUK_BIDX_DATE_PROTOTYPE);\n\n\t/* Unlike most built-ins, the internal [[PrimitiveValue]] of a Date\n\t * is mutable.\n\t */\n\n\tif (nargs == 0 || !is_cons) {\n\t\td = duk__timeclip(duk_time_get_ecmascript_time_nofrac(thr));\n\t\tduk_push_number(thr, d);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\t\tif (!is_cons) {\n\t\t\t/* called as a normal function: return new Date().toString() */\n\t\t\tduk_to_string(thr, -1);\n\t\t}\n\t\treturn 1;\n\t} else if (nargs == 1) {\n\t\tconst char *str;\n\t\tduk_to_primitive(thr, 0, DUK_HINT_NONE);\n\t\tstr = duk_get_string_notsymbol(thr, 0);\n\t\tif (str) {\n\t\t\tduk__parse_string(thr, str);\n\t\t\tduk_replace(thr, 0);  /* may be NaN */\n\t\t}\n\t\td = duk__timeclip(duk_to_number(thr, 0));  /* symbols fail here */\n\t\tduk_push_number(thr, d);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\t\treturn 1;\n\t}\n\n\tduk__set_parts_from_args(thr, dparts, nargs);\n\n\t/* Parts are in local time, convert when setting. */\n\n\t(void) duk__set_this_timeval_from_dparts(thr, dparts, DUK_DATE_FLAG_LOCALTIME /*flags*/);  /* -> [ ... this timeval ] */\n\tduk_pop(thr);  /* -> [ ... this ] */\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor_parse(duk_hthread *thr) {\n\treturn duk__parse_string(thr, duk_to_string(thr, 0));\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor_utc(duk_hthread *thr) {\n\tduk_idx_t nargs = duk_get_top(thr);\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t d;\n\n\t/* Behavior for nargs < 2 is implementation dependent: currently we'll\n\t * set a NaN time value (matching V8 behavior) in this case.\n\t */\n\n\tif (nargs < 2) {\n\t\tduk_push_nan(thr);\n\t} else {\n\t\tduk__set_parts_from_args(thr, dparts, nargs);\n\t\td = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);\n\t\tduk_push_number(thr, d);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor_now(duk_hthread *thr) {\n\tduk_double_t d;\n\n\td = duk_time_get_ecmascript_time_nofrac(thr);\n\tDUK_ASSERT(duk__timeclip(d) == d);  /* TimeClip() should never be necessary */\n\tduk_push_number(thr, d);\n\treturn 1;\n}\n\n/*\n *  String/JSON conversions\n *\n *  Human readable conversions are now basically ISO 8601 with a space\n *  (instead of 'T') as the date/time separator.  This is a good baseline\n *  and is platform independent.\n *\n *  A shared native helper to provide many conversions.  Magic value contains\n *  a set of flags.  The helper provides:\n *\n *    toString()\n *    toDateString()\n *    toTimeString()\n *    toLocaleString()\n *    toLocaleDateString()\n *    toLocaleTimeString()\n *    toUTCString()\n *    toISOString()\n *\n *  Notes:\n *\n *    - Date.prototype.toGMTString() and Date.prototype.toUTCString() are\n *      required to be the same ECMAScript function object (!), so it is\n *      omitted from here.\n *\n *    - Date.prototype.toUTCString(): E5.1 specification does not require a\n *      specific format, but result should be human readable.  The\n *      specification suggests using ISO 8601 format with a space (instead\n *      of 'T') separator if a more human readable format is not available.\n *\n *    - Date.prototype.toISOString(): unlike other conversion functions,\n *      toISOString() requires a RangeError for invalid date values.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_tostring_shared(duk_hthread *thr) {\n\tduk_small_uint_t flags = duk__date_get_indirect_magic(thr);\n\treturn duk__to_string_helper(thr, flags);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_value_of(duk_hthread *thr) {\n\t/* This native function is also used for Date.prototype.getTime()\n\t * as their behavior is identical.\n\t */\n\n\tduk_double_t d = duk__push_this_get_timeval(thr, 0 /*flags*/);  /* -> [ this ] */\n\tDUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));\n\tduk_push_number(thr, d);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_to_json(duk_hthread *thr) {\n\t/* Note: toJSON() is a generic function which works even if 'this'\n\t * is not a Date.  The sole argument is ignored.\n\t */\n\n\tduk_push_this(thr);\n\tduk_to_object(thr, -1);\n\n\tduk_dup_top(thr);\n\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);\n\tif (duk_is_number(thr, -1)) {\n\t\tduk_double_t d = duk_get_number(thr, -1);\n\t\tif (!DUK_ISFINITE(d)) {\n\t\t\tduk_push_null(thr);\n\t\t\treturn 1;\n\t\t}\n\t}\n\tduk_pop(thr);\n\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_ISO_STRING);\n\tduk_dup_m2(thr);  /* -> [ O toIsoString O ] */\n\tduk_call_method(thr, 0);\n\treturn 1;\n}\n\n/*\n *  Getters.\n *\n *  Implementing getters is quite easy.  The internal time value is either\n *  NaN, or represents milliseconds (without fractions) from Jan 1, 1970.\n *  The internal time value can be converted to integer parts, and each\n *  part will be normalized and will fit into a 32-bit signed integer.\n *\n *  A shared native helper to provide all getters.  Magic value contains\n *  a set of flags and also packs the date component index argument.  The\n *  helper provides:\n *\n *    getFullYear()\n *    getUTCFullYear()\n *    getMonth()\n *    getUTCMonth()\n *    getDate()\n *    getUTCDate()\n *    getDay()\n *    getUTCDay()\n *    getHours()\n *    getUTCHours()\n *    getMinutes()\n *    getUTCMinutes()\n *    getSeconds()\n *    getUTCSeconds()\n *    getMilliseconds()\n *    getUTCMilliseconds()\n *    getYear()\n *\n *  Notes:\n *\n *    - Date.prototype.getDate(): 'date' means day-of-month, and is\n *      zero-based in internal calculations but public API expects it to\n *      be one-based.\n *\n *    - Date.prototype.getTime() and Date.prototype.valueOf() have identical\n *      behavior.  They have separate function objects, but share the same C\n *      function (duk_bi_date_prototype_value_of).\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_shared(duk_hthread *thr) {\n\tduk_small_uint_t flags_and_idx = duk__date_get_indirect_magic(thr);\n\treturn duk__get_part_helper(thr, flags_and_idx);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_timezone_offset(duk_hthread *thr) {\n\t/*\n\t *  Return (t - LocalTime(t)) in minutes:\n\t *\n\t *    t - LocalTime(t) = t - (t + LocalTZA + DaylightSavingTA(t))\n\t *                     = -(LocalTZA + DaylightSavingTA(t))\n\t *\n\t *  where DaylightSavingTA() is checked for time 't'.\n\t *\n\t *  Note that the sign of the result is opposite to common usage,\n\t *  e.g. for EE(S)T which normally is +2h or +3h from UTC, this\n\t *  function returns -120 or -180.\n\t *\n\t */\n\n\tduk_double_t d;\n\tduk_int_t tzoffset;\n\n\t/* Note: DST adjustment is determined using UTC time. */\n\td = duk__push_this_get_timeval(thr, 0 /*flags*/);\n\tDUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));\n\tif (DUK_ISNAN(d)) {\n\t\tduk_push_nan(thr);\n\t} else {\n\t\tDUK_ASSERT(DUK_ISFINITE(d));\n\t\ttzoffset = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);\n\t\tduk_push_int(thr, -tzoffset / 60);\n\t}\n\treturn 1;\n}\n\n/*\n *  Setters.\n *\n *  Setters are a bit more complicated than getters.  Component setters\n *  break down the current time value into its (normalized) component\n *  parts, replace one or more components with -unnormalized- new values,\n *  and the components are then converted back into a time value.  As an\n *  example of using unnormalized values:\n *\n *    var d = new Date(1234567890);\n *\n *  is equivalent to:\n *\n *    var d = new Date(0);\n *    d.setUTCMilliseconds(1234567890);\n *\n *  A shared native helper to provide almost all setters.  Magic value\n *  contains a set of flags and also packs the \"maxnargs\" argument.  The\n *  helper provides:\n *\n *    setMilliseconds()\n *    setUTCMilliseconds()\n *    setSeconds()\n *    setUTCSeconds()\n *    setMinutes()\n *    setUTCMinutes()\n *    setHours()\n *    setUTCHours()\n *    setDate()\n *    setUTCDate()\n *    setMonth()\n *    setUTCMonth()\n *    setFullYear()\n *    setUTCFullYear()\n *    setYear()\n *\n *  Notes:\n *\n *    - Date.prototype.setYear() (Section B addition): special year check\n *      is omitted.  NaN / Infinity will just flow through and ultimately\n *      result in a NaN internal time value.\n *\n *    - Date.prototype.setYear() does not have optional arguments for\n *      setting month and day-in-month (like setFullYear()), but we indicate\n *      'maxnargs' to be 3 to get the year written to the correct component\n *      index in duk__set_part_helper().  The function has nargs == 1, so only\n *      the year will be set regardless of actual argument count.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_shared(duk_hthread *thr) {\n\tduk_small_uint_t flags_and_maxnargs = duk__date_get_indirect_magic(thr);\n\treturn duk__set_part_helper(thr, flags_and_maxnargs);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_time(duk_hthread *thr) {\n\tduk_double_t d;\n\n\t(void) duk__push_this_get_timeval(thr, 0 /*flags*/); /* -> [ timeval this ] */\n\td = duk__timeclip(duk_to_number(thr, 0));\n\tduk_push_number(thr, d);\n\tduk_dup_top(thr);\n\t/* Must force write because .setTime() must work even when\n\t * the Date instance is frozen.\n\t */\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\t/* -> [ timeval this timeval ] */\n\n\treturn 1;\n}\n\n/*\n *  Misc.\n */\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_toprimitive(duk_hthread *thr) {\n\tduk_size_t hintlen;\n\tconst char *hintstr;\n\tduk_int_t hint;\n\n\t/* Invokes OrdinaryToPrimitive() with suitable hint.  Note that the\n\t * method is generic, and works on non-Date arguments too.\n\t *\n\t * https://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype-@@toprimitive\n\t */\n\n\tduk_push_this(thr);\n\tduk_require_object(thr, -1);\n\tDUK_ASSERT_TOP(thr, 2);\n\n\thintstr = duk_require_lstring(thr, 0, &hintlen);\n\tif ((hintlen == 6 && DUK_STRCMP(hintstr, \"string\") == 0) ||\n\t    (hintlen == 7 && DUK_STRCMP(hintstr, \"default\") == 0)) {\n\t\thint = DUK_HINT_STRING;\n\t} else if (hintlen == 6 && DUK_STRCMP(hintstr, \"number\") == 0) {\n\t\thint = DUK_HINT_NUMBER;\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tduk_to_primitive_ordinary(thr, -1, hint);\n\treturn 1;\n}\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n\n#endif  /* DUK_USE_DATE_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_date_unix.c",
    "content": "/*\n *  Unix-like Date providers\n *\n *  Generally useful Unix / POSIX / ANSI Date providers.\n */\n\n#include \"duk_internal.h\"\n\n/* The necessary #includes are in place in duk_config.h. */\n\n/* Buffer sizes for some UNIX calls.  Larger than strictly necessary\n * to avoid Valgrind errors.\n */\n#define DUK__STRPTIME_BUF_SIZE  64\n#define DUK__STRFTIME_BUF_SIZE  64\n\n#if defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)\n/* Get current ECMAScript time (= UNIX/Posix time, but in milliseconds). */\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_gettimeofday(void) {\n\tstruct timeval tv;\n\tduk_double_t d;\n\n\tif (gettimeofday(&tv, NULL) != 0) {\n\t\tDUK_D(DUK_DPRINT(\"gettimeofday() failed\"));\n\t\treturn 0.0;\n\t}\n\n\t/* As of Duktape 2.2.0 allow fractions. */\n\td = ((duk_double_t) tv.tv_sec) * 1000.0 +\n\t    ((duk_double_t) tv.tv_usec) / 1000.0;\n\n\treturn d;\n}\n#endif  /* DUK_USE_DATE_NOW_GETTIMEOFDAY */\n\n#if defined(DUK_USE_DATE_NOW_TIME)\n/* Not a very good provider: only full seconds are available. */\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_time(void) {\n\ttime_t t;\n\n\tt = time(NULL);\n\tif (t == (time_t) -1) {\n\t\tDUK_D(DUK_DPRINT(\"time() failed\"));\n\t\treturn 0.0;\n\t}\n\treturn ((duk_double_t) t) * 1000.0;\n}\n#endif  /* DUK_USE_DATE_NOW_TIME */\n\n#if defined(DUK_USE_DATE_TZO_GMTIME) || defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S)\n/* Get local time offset (in seconds) for a certain (UTC) instant 'd'. */\nDUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d) {\n\ttime_t t, t1, t2;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tstruct tm tms[2];\n#if defined(DUK_USE_DATE_TZO_GMTIME)\n\tstruct tm *tm_ptr;\n#endif\n\n\t/* For NaN/inf, the return value doesn't matter. */\n\tif (!DUK_ISFINITE(d)) {\n\t\treturn 0;\n\t}\n\n\t/* If not within ECMAScript range, some integer time calculations\n\t * won't work correctly (and some asserts will fail), so bail out\n\t * if so.  This fixes test-bug-date-insane-setyear.js.  There is\n\t * a +/- 24h leeway in this range check to avoid a test262 corner\n\t * case documented in test-bug-date-timeval-edges.js.\n\t */\n\tif (!duk_bi_date_timeval_in_leeway_range(d)) {\n\t\tDUK_DD(DUK_DDPRINT(\"timeval not within valid range, skip tzoffset computation to avoid integer overflows\"));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  This is a bit tricky to implement portably.  The result depends\n\t *  on the timestamp (specifically, DST depends on the timestamp).\n\t *  If e.g. UNIX APIs are used, they'll have portability issues with\n\t *  very small and very large years.\n\t *\n\t *  Current approach:\n\t *\n\t *  - Stay within portable UNIX limits by using equivalent year mapping.\n\t *    Avoid year 1970 and 2038 as some conversions start to fail, at\n\t *    least on some platforms.  Avoiding 1970 means that there are\n\t *    currently DST discrepancies for 1970.\n\t *\n\t *  - Create a UTC and local time breakdowns from 't'.  Then create\n\t *    a time_t using gmtime() and localtime() and compute the time\n\t *    difference between the two.\n\t *\n\t *  Equivalent year mapping (E5 Section 15.9.1.8):\n\t *\n\t *    If the host environment provides functionality for determining\n\t *    daylight saving time, the implementation of ECMAScript is free\n\t *    to map the year in question to an equivalent year (same\n\t *    leap-year-ness and same starting week day for the year) for which\n\t *    the host environment provides daylight saving time information.\n\t *    The only restriction is that all equivalent years should produce\n\t *    the same result.\n\t *\n\t *  This approach is quite reasonable but not entirely correct, e.g.\n\t *  the specification also states (E5 Section 15.9.1.8):\n\t *\n\t *    The implementation of ECMAScript should not try to determine\n\t *    whether the exact time was subject to daylight saving time, but\n\t *    just whether daylight saving time would have been in effect if\n\t *    the _current daylight saving time algorithm_ had been used at the\n\t *    time.  This avoids complications such as taking into account the\n\t *    years that the locale observed daylight saving time year round.\n\t *\n\t *  Since we rely on the platform APIs for conversions between local\n\t *  time and UTC, we can't guarantee the above.  Rather, if the platform\n\t *  has historical DST rules they will be applied.  This seems to be the\n\t *  general preferred direction in ECMAScript standardization (or at least\n\t *  implementations) anyway, and even the equivalent year mapping should\n\t *  be disabled if the platform is known to handle DST properly for the\n\t *  full ECMAScript range.\n\t *\n\t *  The following has useful discussion and links:\n\t *\n\t *    https://bugzilla.mozilla.org/show_bug.cgi?id=351066\n\t */\n\n\tduk_bi_date_timeval_to_parts(d, parts, dparts, DUK_DATE_FLAG_EQUIVYEAR /*flags*/);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_YEAR] >= 1970 && parts[DUK_DATE_IDX_YEAR] <= 2038);\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);\n\tDUK_ASSERT(d >= 0 && d < 2147483648.0 * 1000.0);  /* unsigned 31-bit range */\n\tt = (time_t) (d / 1000.0);\n\tDUK_DDD(DUK_DDDPRINT(\"timeval: %lf -> time_t %ld\", (double) d, (long) t));\n\n\tduk_memzero((void *) tms, sizeof(struct tm) * 2);\n\n#if defined(DUK_USE_DATE_TZO_GMTIME_R)\n\t(void) gmtime_r(&t, &tms[0]);\n\t(void) localtime_r(&t, &tms[1]);\n#elif defined(DUK_USE_DATE_TZO_GMTIME_S)\n\t(void) gmtime_s(&t, &tms[0]);\n\t(void) localtime_s(&t, &tms[1]);\n#elif defined(DUK_USE_DATE_TZO_GMTIME)\n\ttm_ptr = gmtime(&t);\n\tduk_memcpy((void *) &tms[0], tm_ptr, sizeof(struct tm));\n\ttm_ptr = localtime(&t);\n\tduk_memcpy((void *) &tms[1], tm_ptr, sizeof(struct tm));\n#else\n#error internal error\n#endif\n\tDUK_DDD(DUK_DDDPRINT(\"gmtime result: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,\"\n\t                     \"wday:%ld,yday:%ld,isdst:%ld}\",\n\t                     (long) tms[0].tm_sec, (long) tms[0].tm_min, (long) tms[0].tm_hour,\n\t                     (long) tms[0].tm_mday, (long) tms[0].tm_mon, (long) tms[0].tm_year,\n\t                     (long) tms[0].tm_wday, (long) tms[0].tm_yday, (long) tms[0].tm_isdst));\n\tDUK_DDD(DUK_DDDPRINT(\"localtime result: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,\"\n\t                     \"wday:%ld,yday:%ld,isdst:%ld}\",\n\t                     (long) tms[1].tm_sec, (long) tms[1].tm_min, (long) tms[1].tm_hour,\n\t                     (long) tms[1].tm_mday, (long) tms[1].tm_mon, (long) tms[1].tm_year,\n\t                     (long) tms[1].tm_wday, (long) tms[1].tm_yday, (long) tms[1].tm_isdst));\n\n\t/* tm_isdst is both an input and an output to mktime(), use 0 to\n\t * avoid DST handling in mktime():\n\t * - https://github.com/svaarala/duktape/issues/406\n\t * - http://stackoverflow.com/questions/8558919/mktime-and-tm-isdst\n\t */\n\ttms[0].tm_isdst = 0;\n\ttms[1].tm_isdst = 0;\n\tt1 = mktime(&tms[0]);  /* UTC */\n\tt2 = mktime(&tms[1]);  /* local */\n\tif (t1 == (time_t) -1 || t2 == (time_t) -1) {\n\t\t/* This check used to be for (t < 0) but on some platforms\n\t\t * time_t is unsigned and apparently the proper way to detect\n\t\t * an mktime() error return is the cast above.  See e.g.:\n\t\t * http://pubs.opengroup.org/onlinepubs/009695299/functions/mktime.html\n\t\t */\n\t\tgoto mktime_error;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"t1=%ld (utc), t2=%ld (local)\", (long) t1, (long) t2));\n\n\t/* Compute final offset in seconds, positive if local time ahead of\n\t * UTC (returned value is UTC-to-local offset).\n\t *\n\t * difftime() returns a double, so coercion to int generates quite\n\t * a lot of code.  Direct subtraction is not portable, however.\n\t * XXX: allow direct subtraction on known platforms.\n\t */\n#if 0\n\treturn (duk_int_t) (t2 - t1);\n#endif\n\treturn (duk_int_t) difftime(t2, t1);\n\n mktime_error:\n\t/* XXX: return something more useful, so that caller can throw? */\n\tDUK_D(DUK_DPRINT(\"mktime() failed, d=%lf\", (double) d));\n\treturn 0;\n}\n#endif  /* DUK_USE_DATE_TZO_GMTIME */\n\n#if defined(DUK_USE_DATE_PRS_STRPTIME)\nDUK_INTERNAL duk_bool_t duk_bi_date_parse_string_strptime(duk_hthread *thr, const char *str) {\n\tstruct tm tm;\n\ttime_t t;\n\tchar buf[DUK__STRPTIME_BUF_SIZE];\n\n\t/* Copy to buffer with slack to avoid Valgrind gripes from strptime. */\n\tDUK_ASSERT(str != NULL);\n\tduk_memzero(buf, sizeof(buf));  /* valgrind whine without this */\n\tDUK_SNPRINTF(buf, sizeof(buf), \"%s\", (const char *) str);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parsing: '%s'\", (const char *) buf));\n\n\tduk_memzero(&tm, sizeof(tm));\n\tif (strptime((const char *) buf, \"%c\", &tm) != NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"before mktime: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,\"\n\t\t                     \"wday:%ld,yday:%ld,isdst:%ld}\",\n\t\t                     (long) tm.tm_sec, (long) tm.tm_min, (long) tm.tm_hour,\n\t\t                     (long) tm.tm_mday, (long) tm.tm_mon, (long) tm.tm_year,\n\t\t                     (long) tm.tm_wday, (long) tm.tm_yday, (long) tm.tm_isdst));\n\t\ttm.tm_isdst = -1;  /* negative: dst info not available */\n\n\t\tt = mktime(&tm);\n\t\tDUK_DDD(DUK_DDDPRINT(\"mktime() -> %ld\", (long) t));\n\t\tif (t >= 0) {\n\t\t\tduk_push_number(thr, ((duk_double_t) t) * 1000.0);\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n#endif  /* DUK_USE_DATE_PRS_STRPTIME */\n\n#if defined(DUK_USE_DATE_PRS_GETDATE)\nDUK_INTERNAL duk_bool_t duk_bi_date_parse_string_getdate(duk_hthread *thr, const char *str) {\n\tstruct tm tm;\n\tduk_small_int_t rc;\n\ttime_t t;\n\n\t/* For this to work, DATEMSK must be set, so this is not very\n\t * convenient for an embeddable interpreter.\n\t */\n\n\tduk_memzero(&tm, sizeof(struct tm));\n\trc = (duk_small_int_t) getdate_r(str, &tm);\n\tDUK_DDD(DUK_DDDPRINT(\"getdate_r() -> %ld\", (long) rc));\n\n\tif (rc == 0) {\n\t\tt = mktime(&tm);\n\t\tDUK_DDD(DUK_DDDPRINT(\"mktime() -> %ld\", (long) t));\n\t\tif (t >= 0) {\n\t\t\tduk_push_number(thr, (duk_double_t) t);\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n#endif  /* DUK_USE_DATE_PRS_GETDATE */\n\n#if defined(DUK_USE_DATE_FMT_STRFTIME)\nDUK_INTERNAL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags) {\n\tchar buf[DUK__STRFTIME_BUF_SIZE];\n\tstruct tm tm;\n\tconst char *fmt;\n\n\tDUK_UNREF(tzoffset);\n\n\t/* If the platform doesn't support the entire ECMAScript range, we need\n\t * to return 0 so that the caller can fall back to the default formatter.\n\t *\n\t * For now, assume that if time_t is 8 bytes or more, the whole ECMAScript\n\t * range is supported.  For smaller time_t values (4 bytes in practice),\n\t * assumes that the signed 32-bit range is supported.\n\t *\n\t * XXX: detect this more correctly per platform.  The size of time_t is\n\t * probably not an accurate guarantee of strftime() supporting or not\n\t * supporting a large time range (the full ECMAScript range).\n\t */\n\tif (sizeof(time_t) < 8 &&\n\t    (parts[DUK_DATE_IDX_YEAR] < 1970 || parts[DUK_DATE_IDX_YEAR] > 2037)) {\n\t\t/* be paranoid for 32-bit time values (even avoiding negative ones) */\n\t\treturn 0;\n\t}\n\n\tduk_memzero(&tm, sizeof(tm));\n\ttm.tm_sec = parts[DUK_DATE_IDX_SECOND];\n\ttm.tm_min = parts[DUK_DATE_IDX_MINUTE];\n\ttm.tm_hour = parts[DUK_DATE_IDX_HOUR];\n\ttm.tm_mday = parts[DUK_DATE_IDX_DAY];       /* already one-based */\n\ttm.tm_mon = parts[DUK_DATE_IDX_MONTH] - 1;  /* one-based -> zero-based */\n\ttm.tm_year = parts[DUK_DATE_IDX_YEAR] - 1900;\n\ttm.tm_wday = parts[DUK_DATE_IDX_WEEKDAY];\n\ttm.tm_isdst = 0;\n\n\tduk_memzero(buf, sizeof(buf));\n\tif ((flags & DUK_DATE_FLAG_TOSTRING_DATE) && (flags & DUK_DATE_FLAG_TOSTRING_TIME)) {\n\t\tfmt = \"%c\";\n\t} else if (flags & DUK_DATE_FLAG_TOSTRING_DATE) {\n\t\tfmt = \"%x\";\n\t} else {\n\t\tDUK_ASSERT(flags & DUK_DATE_FLAG_TOSTRING_TIME);\n\t\tfmt = \"%X\";\n\t}\n\t(void) strftime(buf, sizeof(buf) - 1, fmt, &tm);\n\tDUK_ASSERT(buf[sizeof(buf) - 1] == 0);\n\n\tduk_push_string(thr, buf);\n\treturn 1;\n}\n#endif  /* DUK_USE_DATE_FMT_STRFTIME */\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)\nDUK_INTERNAL duk_double_t duk_bi_date_get_monotonic_time_clock_gettime(void) {\n\tstruct timespec ts;\n\n\tif (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {\n\t\treturn (duk_double_t) ts.tv_sec * 1000.0 + (duk_double_t) ts.tv_nsec / 1000000.0;\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"clock_gettime(CLOCK_MONOTONIC) failed\"));\n\t\treturn 0.0;\n\t}\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_date_windows.c",
    "content": "/*\n *  Windows Date providers\n *\n *  Platform specific links:\n *\n *    - http://msdn.microsoft.com/en-us/library/windows/desktop/ms725473(v=vs.85).aspx\n */\n\n#include \"duk_internal.h\"\n\n/* The necessary #includes are in place in duk_config.h. */\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS) || defined(DUK_USE_DATE_TZO_WINDOWS)\n/* Shared Windows helpers. */\nDUK_LOCAL void duk__convert_systime_to_ularge(const SYSTEMTIME *st, ULARGE_INTEGER *res) {\n\tFILETIME ft;\n\tif (SystemTimeToFileTime(st, &ft) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"SystemTimeToFileTime() failed, returning 0\"));\n\t\tres->QuadPart = 0;\n\t} else {\n\t\tres->LowPart = ft.dwLowDateTime;\n\t\tres->HighPart = ft.dwHighDateTime;\n\t}\n}\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\nDUK_LOCAL void duk__convert_filetime_to_ularge(const FILETIME *ft, ULARGE_INTEGER *res) {\n\tres->LowPart = ft->dwLowDateTime;\n\tres->HighPart = ft->dwHighDateTime;\n}\n#endif  /* DUK_USE_DATE_NOW_WINDOWS_SUBMS */\n\nDUK_LOCAL void duk__set_systime_jan1970(SYSTEMTIME *st) {\n\tduk_memzero((void *) st, sizeof(*st));\n\tst->wYear = 1970;\n\tst->wMonth = 1;\n\tst->wDayOfWeek = 4;  /* not sure whether or not needed; Thursday */\n\tst->wDay = 1;\n\tDUK_ASSERT(st->wHour == 0);\n\tDUK_ASSERT(st->wMinute == 0);\n\tDUK_ASSERT(st->wSecond == 0);\n\tDUK_ASSERT(st->wMilliseconds == 0);\n}\n#endif  /* defined(DUK_USE_DATE_NOW_WINDOWS) || defined(DUK_USE_DATE_TZO_WINDOWS) */\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS)\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_windows(void) {\n\t/* Suggested step-by-step method from documentation of RtlTimeToSecondsSince1970:\n\t * http://msdn.microsoft.com/en-us/library/windows/desktop/ms724928(v=vs.85).aspx\n\t */\n\tSYSTEMTIME st1, st2;\n\tULARGE_INTEGER tmp1, tmp2;\n\n\tGetSystemTime(&st1);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1);\n\n\tduk__set_systime_jan1970(&st2);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);\n\n\t/* Difference is in 100ns units, convert to milliseconds, keeping\n\t * fractions since Duktape 2.2.0.  This is only theoretical because\n\t * SYSTEMTIME is limited to milliseconds.\n\t */\n\treturn (duk_double_t) ((LONGLONG) tmp1.QuadPart - (LONGLONG) tmp2.QuadPart) / 10000.0;\n}\n#endif  /* DUK_USE_DATE_NOW_WINDOWS */\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_windows_subms(void) {\n\t/* Variant of the basic algorithm using GetSystemTimePreciseAsFileTime()\n\t * for more accuracy.\n\t */\n\tFILETIME ft1;\n\tSYSTEMTIME st2;\n\tULARGE_INTEGER tmp1, tmp2;\n\n\tGetSystemTimePreciseAsFileTime(&ft1);\n\tduk__convert_filetime_to_ularge((const FILETIME *) &ft1, &tmp1);\n\n\tduk__set_systime_jan1970(&st2);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);\n\n\t/* Difference is in 100ns units, convert to milliseconds, keeping\n\t * fractions since Duktape 2.2.0.\n\t */\n\treturn (duk_double_t) ((LONGLONG) tmp1.QuadPart - (LONGLONG) tmp2.QuadPart) / 10000.0;\n}\n#endif  /* DUK_USE_DATE_NOW_WINDOWS */\n\n#if defined(DUK_USE_DATE_TZO_WINDOWS)\nDUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d) {\n\tSYSTEMTIME st1;\n\tSYSTEMTIME st2;\n\tSYSTEMTIME st3;\n\tULARGE_INTEGER tmp1;\n\tULARGE_INTEGER tmp2;\n\tULARGE_INTEGER tmp3;\n\tFILETIME ft1;\n\n\t/* XXX: handling of timestamps outside Windows supported range.\n\t * How does Windows deal with dates before 1600?  Does windows\n\t * support all ECMAScript years (like -200000 and +200000)?\n\t * Should equivalent year mapping be used here too?  If so, use\n\t * a shared helper (currently integrated into timeval-to-parts).\n\t */\n\n\t/* Use the approach described in \"Remarks\" of FileTimeToLocalFileTime:\n\t * http://msdn.microsoft.com/en-us/library/windows/desktop/ms724277(v=vs.85).aspx\n\t */\n\n\tduk__set_systime_jan1970(&st1);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1);\n\ttmp2.QuadPart = (ULONGLONG) (d * 10000.0);  /* millisec -> 100ns units since jan 1, 1970 */\n\ttmp2.QuadPart += tmp1.QuadPart;             /* input 'd' in Windows UTC, 100ns units */\n\n\tft1.dwLowDateTime = tmp2.LowPart;\n\tft1.dwHighDateTime = tmp2.HighPart;\n\tif (FileTimeToSystemTime((const FILETIME *) &ft1, &st2) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"FileTimeToSystemTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tif (SystemTimeToTzSpecificLocalTime((LPTIME_ZONE_INFORMATION) NULL, &st2, &st3) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"SystemTimeToTzSpecificLocalTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st3, &tmp3);\n\n\t/* Positive if local time ahead of UTC. */\n\treturn (duk_int_t) (((LONGLONG) tmp3.QuadPart - (LONGLONG) tmp2.QuadPart) / DUK_I64_CONSTANT(10000000));  /* seconds */\n}\n#endif  /* DUK_USE_DATE_TZO_WINDOWS */\n\n#if defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST)\nDUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_t d) {\n\tSYSTEMTIME st1;\n\tSYSTEMTIME st2;\n\tFILETIME ft1;\n\tFILETIME ft2;\n\tULARGE_INTEGER tmp1;\n\tULARGE_INTEGER tmp2;\n\n\t/* Do a similar computation to duk_bi_date_get_local_tzoffset_windows\n\t * but without accounting for daylight savings time.  Use this on\n\t * Windows platforms (like Durango) that don't support the\n\t * SystemTimeToTzSpecificLocalTime() call.\n\t */\n\n\t/* current time not needed for this computation */\n\tDUK_UNREF(d);\n\n\tduk__set_systime_jan1970(&st1);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1);\n\n\tft1.dwLowDateTime = tmp1.LowPart;\n\tft1.dwHighDateTime = tmp1.HighPart;\n\tif (FileTimeToLocalFileTime((const FILETIME *) &ft1, &ft2) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"FileTimeToLocalFileTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tif (FileTimeToSystemTime((const FILETIME *) &ft2, &st2) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"FileTimeToSystemTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);\n\n\treturn (duk_int_t) (((LONGLONG) tmp2.QuadPart - (LONGLONG) tmp1.QuadPart) / DUK_I64_CONSTANT(10000000));  /* seconds */\n}\n#endif  /* DUK_USE_DATE_TZO_WINDOWS_NO_DST */\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC)\nDUK_INTERNAL duk_double_t duk_bi_date_get_monotonic_time_windows_qpc(void) {\n\tLARGE_INTEGER count, freq;\n\n\t/* There are legacy issues with QueryPerformanceCounter():\n\t * - Potential jumps: https://support.microsoft.com/en-us/help/274323/performance-counter-value-may-unexpectedly-leap-forward\n\t * - Differences between cores (XP): https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx#qpc_support_in_windows_versions\n\t *\n\t * We avoid these by enabling QPC by default only for Vista or later.\n\t */\n\n\tif (QueryPerformanceCounter(&count) && QueryPerformanceFrequency(&freq)) {\n\t\t/* XXX: QueryPerformanceFrequency() can be cached */\n\t\treturn (duk_double_t) count.QuadPart / (duk_double_t) freq.QuadPart * 1000.0;\n\t} else {\n\t\t/* MSDN: \"On systems that run Windows XP or later, the function\n\t\t * will always succeed and will thus never return zero.\"\n\t\t * Provide minimal error path just in case user enables this\n\t\t * feature in pre-XP Windows.\n\t\t */\n\t\treturn 0.0;\n\t}\n}\n#endif  /* DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_duktape.c",
    "content": "/*\n *  Duktape built-ins\n *\n *  Size optimization note: it might seem that vararg multipurpose functions\n *  like fin(), enc(), and dec() are not very size optimal, but using a single\n *  user-visible ECMAScript function saves a lot of run-time footprint; each\n *  Function instance takes >100 bytes.  Using a shared native helper and a\n *  'magic' value won't save much if there are multiple Function instances\n *  anyway.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_DUKTAPE_BUILTIN)\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_info(duk_hthread *thr) {\n\tduk_inspect_value(thr, -1);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_act(duk_hthread *thr) {\n\tduk_int_t level;\n\n\tlevel = duk_to_int(thr, 0);\n\tduk_inspect_callstack_entry(thr, level);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_gc(duk_hthread *thr) {\n\tduk_small_uint_t flags;\n\n\tflags = (duk_small_uint_t) duk_get_uint(thr, 0);\n\tduk_heap_mark_and_sweep(thr->heap, flags);\n\n\t/* XXX: Not sure what the best return value would be in the API.\n\t * Return true for now.\n\t */\n\tduk_push_true(thr);\n\treturn 1;\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_fin(duk_hthread *thr) {\n\t(void) duk_require_hobject(thr, 0);\n\tif (duk_get_top(thr) >= 2) {\n\t\t/* Set: currently a finalizer is disabled by setting it to\n\t\t * undefined; this does not remove the property at the moment.\n\t\t * The value could be type checked to be either a function\n\t\t * or something else; if something else, the property could\n\t\t * be deleted.  Must use duk_set_finalizer() to keep\n\t\t * DUK_HOBJECT_FLAG_HAVE_FINALIZER in sync.\n\t\t */\n\t\tduk_set_top(thr, 2);\n\t\tduk_set_finalizer(thr, 0);\n\t\treturn 0;\n\t} else {\n\t\t/* Get. */\n\t\tDUK_ASSERT(duk_get_top(thr) == 1);\n\t\tduk_get_finalizer(thr, 0);\n\t\treturn 1;\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_enc(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\t/* Vararg function: must be careful to check/require arguments.\n\t * The JSON helpers accept invalid indices and treat them like\n\t * non-existent optional parameters.\n\t */\n\n\th_str = duk_require_hstring(thr, 0);  /* Could reject symbols, but no point: won't match comparisons. */\n\tduk_require_valid_index(thr, 1);\n\n\tif (h_str == DUK_HTHREAD_STRING_HEX(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_hex_encode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t} else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_base64_encode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX)\n\t} else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {\n\t\tduk_bi_json_stringify_helper(thr,\n\t\t                             1 /*idx_value*/,\n\t\t                             2 /*idx_replacer*/,\n\t\t                             3 /*idx_space*/,\n\t\t                             DUK_JSON_FLAG_EXT_CUSTOM |\n\t\t                             DUK_JSON_FLAG_ASCII_ONLY |\n\t\t                             DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/);\n#endif\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC)\n\t} else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {\n\t\tduk_bi_json_stringify_helper(thr,\n\t\t                             1 /*idx_value*/,\n\t\t                             2 /*idx_replacer*/,\n\t\t                             3 /*idx_space*/,\n\t\t                             DUK_JSON_FLAG_EXT_COMPATIBLE |\n\t\t                             DUK_JSON_FLAG_ASCII_ONLY /*flags*/);\n#endif\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_dec(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\t/* Vararg function: must be careful to check/require arguments.\n\t * The JSON helpers accept invalid indices and treat them like\n\t * non-existent optional parameters.\n\t */\n\n\th_str = duk_require_hstring(thr, 0);  /* Could reject symbols, but no point: won't match comparisons */\n\tduk_require_valid_index(thr, 1);\n\n\tif (h_str == DUK_HTHREAD_STRING_HEX(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_hex_decode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t} else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_base64_decode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX)\n\t} else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {\n\t\tduk_bi_json_parse_helper(thr,\n\t\t                         1 /*idx_value*/,\n\t\t                         2 /*idx_replacer*/,\n\t\t                         DUK_JSON_FLAG_EXT_CUSTOM /*flags*/);\n#endif\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC)\n\t} else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {\n\t\tduk_bi_json_parse_helper(thr,\n\t\t                         1 /*idx_value*/,\n\t\t                         2 /*idx_replacer*/,\n\t\t                         DUK_JSON_FLAG_EXT_COMPATIBLE /*flags*/);\n#endif\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\treturn 1;\n}\n\n/*\n *  Compact an object\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_compact(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 1);\n\tduk_compact(thr, 0);\n\treturn 1;  /* return the argument object */\n}\n\n#endif  /* DUK_USE_DUKTAPE_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_encoding.c",
    "content": "/*\n *  WHATWG Encoding API built-ins\n *\n *  API specification: https://encoding.spec.whatwg.org/#api\n *  Web IDL: https://www.w3.org/TR/WebIDL/\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Data structures for encoding/decoding\n */\n\ntypedef struct {\n\tduk_uint8_t *out;      /* where to write next byte(s) */\n\tduk_codepoint_t lead;  /* lead surrogate */\n} duk__encode_context;\n\ntypedef struct {\n\t/* UTF-8 decoding state */\n\tduk_codepoint_t codepoint;  /* built up incrementally */\n\tduk_uint8_t upper;          /* max value of next byte (decode error otherwise) */\n\tduk_uint8_t lower;          /* min value of next byte (ditto) */\n\tduk_uint8_t needed;         /* how many more bytes we need */\n\tduk_uint8_t bom_handled;    /* BOM seen or no longer expected */\n\n\t/* Decoder configuration */\n\tduk_uint8_t fatal;\n\tduk_uint8_t ignore_bom;\n} duk__decode_context;\n\n/* The signed duk_codepoint_t type is used to signal a decoded codepoint\n * (>= 0) or various other states using negative values.\n */\n#define DUK__CP_CONTINUE   (-1)  /* continue to next byte, no completed codepoint */\n#define DUK__CP_ERROR      (-2)  /* decoding error */\n#define DUK__CP_RETRY      (-3)  /* decoding error; retry last byte */\n\n/*\n *  Raw helpers for encoding/decoding\n */\n\n/* Emit UTF-8 (= CESU-8) encoded U+FFFD (replacement char), i.e. ef bf bd. */\nDUK_LOCAL duk_uint8_t *duk__utf8_emit_repl(duk_uint8_t *ptr) {\n\t*ptr++ = 0xef;\n\t*ptr++ = 0xbf;\n\t*ptr++ = 0xbd;\n\treturn ptr;\n}\n\nDUK_LOCAL void duk__utf8_decode_init(duk__decode_context *dec_ctx) {\n\t/* (Re)init the decoding state of 'dec_ctx' but leave decoder\n\t * configuration fields untouched.\n\t */\n\tdec_ctx->codepoint = 0x0000L;\n\tdec_ctx->upper = 0xbf;\n\tdec_ctx->lower = 0x80;\n\tdec_ctx->needed = 0;\n\tdec_ctx->bom_handled = 0;\n}\n\nDUK_LOCAL duk_codepoint_t duk__utf8_decode_next(duk__decode_context *dec_ctx, duk_uint8_t x) {\n\t/*\n\t *  UTF-8 algorithm based on the Encoding specification:\n\t *  https://encoding.spec.whatwg.org/#utf-8-decoder\n\t *\n\t *  Two main states: decoding initial byte vs. decoding continuation\n\t *  bytes.  Shortest length encoding is validated by restricting the\n\t *  allowed range of first continuation byte using 'lower' and 'upper'.\n\t */\n\n\tif (dec_ctx->needed == 0) {\n\t\t/* process initial byte */\n\t\tif (x <= 0x7f) {\n\t\t\t/* U+0000-U+007F, 1 byte (ASCII) */\n\t\t\treturn (duk_codepoint_t) x;\n\t\t} else if (x >= 0xc2 && x <= 0xdf) {\n\t\t\t/* U+0080-U+07FF, 2 bytes */\n\t\t\tdec_ctx->needed = 1;\n\t\t\tdec_ctx->codepoint = x & 0x1f;\n\t\t\tDUK_ASSERT(dec_ctx->lower == 0x80);\n\t\t\tDUK_ASSERT(dec_ctx->upper == 0xbf);\n\t\t\treturn DUK__CP_CONTINUE;\n\t\t} else if (x >= 0xe0 && x <= 0xef) {\n\t\t\t/* U+0800-U+FFFF, 3 bytes */\n\t\t\tif (x == 0xe0) {\n\t\t\t\tdec_ctx->lower = 0xa0;\n\t\t\t\tDUK_ASSERT(dec_ctx->upper == 0xbf);\n\t\t\t} else if (x == 0xed) {\n\t\t\t\tDUK_ASSERT(dec_ctx->lower == 0x80);\n\t\t\t\tdec_ctx->upper = 0x9f;\n\t\t\t}\n\t\t\tdec_ctx->needed = 2;\n\t\t\tdec_ctx->codepoint = x & 0x0f;\n\t\t\treturn DUK__CP_CONTINUE;\n\t\t} else if (x >= 0xf0 && x <= 0xf4) {\n\t\t\t/* U+010000-U+10FFFF, 4 bytes */\n\t\t\tif (x == 0xf0) {\n\t\t\t\tdec_ctx->lower = 0x90;\n\t\t\t\tDUK_ASSERT(dec_ctx->upper == 0xbf);\n\t\t\t} else if (x == 0xf4) {\n\t\t\t\tDUK_ASSERT(dec_ctx->lower == 0x80);\n\t\t\t\tdec_ctx->upper = 0x8f;\n\t\t\t}\n\t\t\tdec_ctx->needed = 3;\n\t\t\tdec_ctx->codepoint = x & 0x07;\n\t\t\treturn DUK__CP_CONTINUE;\n\t\t} else {\n\t\t\t/* not a legal initial byte */\n\t\t\treturn DUK__CP_ERROR;\n\t\t}\n\t} else {\n\t\t/* process continuation byte */\n\t\tif (x >= dec_ctx->lower && x <= dec_ctx->upper) {\n\t\t\tdec_ctx->lower = 0x80;\n\t\t\tdec_ctx->upper = 0xbf;\n\t\t\tdec_ctx->codepoint = (dec_ctx->codepoint << 6) | (x & 0x3f);\n\t\t\tif (--dec_ctx->needed > 0) {\n\t\t\t\t/* need more bytes */\n\t\t\t\treturn DUK__CP_CONTINUE;\n\t\t\t} else {\n\t\t\t\t/* got a codepoint */\n\t\t\t\tduk_codepoint_t ret;\n\t\t\t\tDUK_ASSERT(dec_ctx->codepoint <= 0x10ffffL);  /* Decoding rules guarantee. */\n\t\t\t\tret = dec_ctx->codepoint;\n\t\t\t\tdec_ctx->codepoint = 0x0000L;\n\t\t\t\tdec_ctx->needed = 0;\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} else {\n\t\t\t/* We just encountered an illegal UTF-8 continuation byte.  This might\n\t\t\t * be the initial byte of the next character; if we return a plain\n\t\t\t * error status and the decoder is in replacement mode, the character\n\t\t\t * will be masked.  We still need to alert the caller to the error\n\t\t\t * though.\n\t\t\t */\n\t\t\tdec_ctx->codepoint = 0x0000L;\n\t\t\tdec_ctx->needed = 0;\n\t\t\tdec_ctx->lower = 0x80;\n\t\t\tdec_ctx->upper = 0xbf;\n\t\t\treturn DUK__CP_RETRY;\n\t\t}\n\t}\n}\n\n#if defined(DUK_USE_ENCODING_BUILTINS)\nDUK_LOCAL void duk__utf8_encode_char(void *udata, duk_codepoint_t codepoint) {\n\tduk__encode_context *enc_ctx;\n\n\tDUK_ASSERT(codepoint >= 0);\n\tenc_ctx = (duk__encode_context *) udata;\n\tDUK_ASSERT(enc_ctx != NULL);\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\tif (codepoint <= 0x7f && enc_ctx->lead == 0x0000L) {\n\t\t/* Fast path for ASCII. */\n\t\t*enc_ctx->out++ = (duk_uint8_t) codepoint;\n\t\treturn;\n\t}\n#endif\n\n\tif (DUK_UNLIKELY(codepoint > 0x10ffffL)) {\n\t\t/* cannot legally encode in UTF-8 */\n\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t} else if (codepoint >= 0xd800L && codepoint <= 0xdfffL) {\n\t\tif (codepoint <= 0xdbffL) {\n\t\t\t/* high surrogate */\n\t\t\tduk_codepoint_t prev_lead = enc_ctx->lead;\n\t\t\tenc_ctx->lead = codepoint;\n\t\t\tif (prev_lead == 0x0000L) {\n\t\t\t\t/* high surrogate, no output */\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\t/* consecutive high surrogates, consider first one unpaired */\n\t\t\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\t}\n\t\t} else {\n\t\t\t/* low surrogate */\n\t\t\tif (enc_ctx->lead != 0x0000L) {\n\t\t\t\tcodepoint = (duk_codepoint_t) (0x010000L + ((enc_ctx->lead - 0xd800L) << 10) + (codepoint - 0xdc00L));\n\t\t\t\tenc_ctx->lead = 0x0000L;\n\t\t\t} else {\n\t\t\t\t/* unpaired low surrogate */\n\t\t\t\tDUK_ASSERT(enc_ctx->lead == 0x0000L);\n\t\t\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif (enc_ctx->lead != 0x0000L) {\n\t\t\t/* unpaired high surrogate: emit replacement character and the input codepoint */\n\t\t\tenc_ctx->lead = 0x0000L;\n\t\t\tenc_ctx->out = duk__utf8_emit_repl(enc_ctx->out);\n\t\t}\n\t}\n\n\t/* Codepoint may be original input, a decoded surrogate pair, or may\n\t * have been replaced with U+FFFD.\n\t */\n\tenc_ctx->out += duk_unicode_encode_xutf8((duk_ucodepoint_t) codepoint, enc_ctx->out);\n}\n#endif  /* DUK_USE_ENCODING_BUILTINS */\n\n/* Shared helper for buffer-to-string using a TextDecoder() compatible UTF-8\n * decoder.\n */\nDUK_LOCAL duk_ret_t duk__decode_helper(duk_hthread *thr, duk__decode_context *dec_ctx) {\n\tconst duk_uint8_t *input;\n\tduk_size_t len = 0;\n\tduk_size_t len_tmp;\n\tduk_bool_t stream = 0;\n\tduk_codepoint_t codepoint;\n\tduk_uint8_t *output;\n\tconst duk_uint8_t *in;\n\tduk_uint8_t *out;\n\n\tDUK_ASSERT(dec_ctx != NULL);\n\n\t/* Careful with input buffer pointer: any side effects involving\n\t * code execution (e.g. getters, coercion calls, and finalizers)\n\t * may cause a resize and invalidate a pointer we've read.  This\n\t * is why the pointer is actually looked up at the last minute.\n\t * Argument validation must still happen first to match WHATWG\n\t * required side effect order.\n\t */\n\n\tif (duk_is_undefined(thr, 0)) {\n\t\tduk_push_fixed_buffer_nozero(thr, 0);\n\t\tduk_replace(thr, 0);\n\t}\n\t(void) duk_require_buffer_data(thr, 0, &len);  /* Need 'len', avoid pointer. */\n\n\tif (duk_check_type_mask(thr, 1, DUK_TYPE_MASK_UNDEFINED |\n\t                                DUK_TYPE_MASK_NULL |\n\t                                DUK_TYPE_MASK_NONE)) {\n\t\t/* Use defaults, treat missing value like undefined. */\n\t} else {\n\t\tduk_require_type_mask(thr, 1, DUK_TYPE_MASK_UNDEFINED |\n\t                                      DUK_TYPE_MASK_NULL |\n\t                                      DUK_TYPE_MASK_LIGHTFUNC |\n\t                                      DUK_TYPE_MASK_BUFFER |\n\t\t                              DUK_TYPE_MASK_OBJECT);\n\t\tif (duk_get_prop_literal(thr, 1, \"stream\")) {\n\t\t\tstream = duk_to_boolean(thr, -1);\n\t\t}\n\t}\n\n\t/* Allowance is 3*len in the general case because all bytes may potentially\n\t * become U+FFFD.  If the first byte completes a non-BMP codepoint it will\n\t * decode to a CESU-8 surrogate pair (6 bytes) so we allow 3 extra bytes to\n\t * compensate: (1*3)+3 = 6.  Non-BMP codepoints are safe otherwise because\n\t * the 4->6 expansion is well under the 3x allowance.\n\t *\n\t * XXX: As with TextEncoder, need a better buffer allocation strategy here.\n\t */\n\tif (len >= (DUK_HBUFFER_MAX_BYTELEN / 3) - 3) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_RESULT_TOO_LONG);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\toutput = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, 3 + (3 * len));  /* used parts will be always manually written over */\n\n\tinput = (const duk_uint8_t *) duk_get_buffer_data(thr, 0, &len_tmp);\n\tDUK_ASSERT(input != NULL || len == 0);\n\tif (DUK_UNLIKELY(len != len_tmp)) {\n\t\t/* Very unlikely but possible: source buffer was resized by\n\t\t * a side effect when fixed buffer was pushed.  Output buffer\n\t\t * may not be large enough to hold output, so just fail if\n\t\t * length has changed.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"input buffer resized by side effect, fail\"));\n\t\tgoto fail_type;\n\t}\n\n\t/* From this point onwards it's critical that no side effect occur\n\t * which may disturb 'input': finalizer execution, property accesses,\n\t * active coercions, etc.  Even an allocation related mark-and-sweep\n\t * may affect the pointer because it may trigger a pending finalizer.\n\t */\n\n\tin = input;\n\tout = output;\n\twhile (in < input + len) {\n\t\tcodepoint = duk__utf8_decode_next(dec_ctx, *in++);\n\t\tif (codepoint < 0) {\n\t\t\tif (codepoint == DUK__CP_CONTINUE) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* Decoding error with or without retry. */\n\t\t\tDUK_ASSERT(codepoint == DUK__CP_ERROR || codepoint == DUK__CP_RETRY);\n\t\t\tif (codepoint == DUK__CP_RETRY) {\n\t\t\t\t--in;  /* retry last byte */\n\t\t\t}\n\t\t\t/* replacement mode: replace with U+FFFD */\n\t\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\tif (dec_ctx->fatal) {\n\t\t\t\t/* fatal mode: throw a TypeError */\n\t\t\t\tgoto fail_type;\n\t\t\t}\n\t\t\t/* Continue with 'codepoint', Unicode replacement. */\n\t\t}\n\t\tDUK_ASSERT(codepoint >= 0x0000L && codepoint <= 0x10ffffL);\n\n\t\tif (!dec_ctx->bom_handled) {\n\t\t\tdec_ctx->bom_handled = 1;\n\t\t\tif (codepoint == 0xfeffL && !dec_ctx->ignore_bom) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tout += duk_unicode_encode_cesu8((duk_ucodepoint_t) codepoint, out);\n\t\tDUK_ASSERT(out <= output + (3 + (3 * len)));\n\t}\n\n\tif (!stream) {\n\t\tif (dec_ctx->needed != 0) {\n\t\t\t/* truncated sequence at end of buffer */\n\t\t\tif (dec_ctx->fatal) {\n\t\t\t\tgoto fail_type;\n\t\t\t} else {\n\t\t\t\tout += duk_unicode_encode_cesu8(DUK_UNICODE_CP_REPLACEMENT_CHARACTER, out);\n\t\t\t\tDUK_ASSERT(out <= output + (3 + (3 * len)));\n\t\t\t}\n\t\t}\n\t\tduk__utf8_decode_init(dec_ctx);  /* Initialize decoding state for potential reuse. */\n\t}\n\n\t/* Output buffer is fixed and thus stable even if there had been\n\t * side effects (which there shouldn't be).\n\t */\n\tduk_push_lstring(thr, (const char *) output, (duk_size_t) (out - output));\n\treturn 1;\n\n fail_type:\n\tDUK_ERROR_TYPE(thr, DUK_STR_UTF8_DECODE_FAILED);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/*\n *  Built-in bindings\n */\n\n#if defined(DUK_USE_ENCODING_BUILTINS)\nDUK_INTERNAL duk_ret_t duk_bi_textencoder_constructor(duk_hthread *thr) {\n\t/* TextEncoder currently requires no persistent state, so the constructor\n\t * does nothing on purpose.\n\t */\n\n\tduk_require_constructor_call(thr);\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encoding_getter(duk_hthread *thr) {\n\tduk_push_literal(thr, \"utf-8\");\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encode(duk_hthread *thr) {\n\tduk__encode_context enc_ctx;\n\tduk_size_t len;\n\tduk_size_t final_len;\n\tduk_uint8_t *output;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tlen = 0;\n\t} else {\n\t\tduk_hstring *h_input;\n\n\t\th_input = duk_to_hstring(thr, 0);\n\t\tDUK_ASSERT(h_input != NULL);\n\n\t\tlen = (duk_size_t) DUK_HSTRING_GET_CHARLEN(h_input);\n\t\tif (len >= DUK_HBUFFER_MAX_BYTELEN / 3) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_RESULT_TOO_LONG);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t}\n\n\t/* Allowance is 3*len because all bytes can potentially be replaced with\n\t * U+FFFD -- which rather inconveniently encodes to 3 bytes in UTF-8.\n\t * Rely on dynamic buffer data pointer stability: no other code has\n\t * access to the data pointer.\n\t *\n\t * XXX: The buffer allocation strategy used here is rather inefficient.\n\t * Maybe switch to a chunk-based strategy, or preprocess the string to\n\t * figure out the space needed ahead of time?\n\t */\n\tDUK_ASSERT(3 * len >= len);\n\toutput = (duk_uint8_t *) duk_push_dynamic_buffer(thr, 3 * len);\n\n\tif (len > 0) {\n\t\tDUK_ASSERT(duk_is_string(thr, 0));  /* True if len > 0. */\n\n\t\t/* XXX: duk_decode_string() is used to process the input\n\t\t * string.  For standard ECMAScript strings, represented\n\t\t * internally as CESU-8, this is fine.  However, behavior\n\t\t * beyond CESU-8 is not very strict: codepoints using an\n\t\t * extended form of UTF-8 are also accepted, and invalid\n\t\t * codepoint sequences (which are allowed in Duktape strings)\n\t\t * are not handled as well as they could (e.g. invalid\n\t\t * continuation bytes may mask following codepoints).\n\t\t * This is how ECMAScript code would also see such strings.\n\t\t * Maybe replace duk_decode_string() with an explicit strict\n\t\t * CESU-8 decoder here?\n\t\t */\n\t\tenc_ctx.lead = 0x0000L;\n\t\tenc_ctx.out = output;\n\t\tduk_decode_string(thr, 0, duk__utf8_encode_char, (void *) &enc_ctx);\n\t\tif (enc_ctx.lead != 0x0000L) {\n\t\t\t/* unpaired high surrogate at end of string */\n\t\t\tenc_ctx.out = duk__utf8_emit_repl(enc_ctx.out);\n\t\t\tDUK_ASSERT(enc_ctx.out <= output + (3 * len));\n\t\t}\n\n\t\t/* The output buffer is usually very much oversized, so shrink it to\n\t\t * actually needed size.  Pointer stability assumed up to this point.\n\t\t */\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t\tDUK_ASSERT(output == (duk_uint8_t *) duk_get_buffer_data(thr, -1, NULL));\n\n\t\tfinal_len = (duk_size_t) (enc_ctx.out - output);\n\t\tduk_resize_buffer(thr, -1, final_len);\n\t\t/* 'output' and 'enc_ctx.out' are potentially invalidated by the resize. */\n\t} else {\n\t\tfinal_len = 0;\n\t}\n\n\t/* Standard WHATWG output is a Uint8Array.  Here the Uint8Array will\n\t * be backed by a dynamic buffer which differs from e.g. Uint8Arrays\n\t * created as 'new Uint8Array(N)'.  ECMAScript code won't see the\n\t * difference but C code will.  When bufferobjects are not supported,\n\t * returns a plain dynamic buffer.\n\t */\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tduk_push_buffer_object(thr, -1, 0, final_len, DUK_BUFOBJ_UINT8ARRAY);\n#endif\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textdecoder_constructor(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\tduk_bool_t fatal = 0;\n\tduk_bool_t ignore_bom = 0;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_require_constructor_call(thr);\n\tif (!duk_is_undefined(thr, 0)) {\n\t\t/* XXX: For now ignore 'label' (encoding identifier). */\n\t\tduk_to_string(thr, 0);\n\t}\n\tif (!duk_is_null_or_undefined(thr, 1)) {\n\t\tif (duk_get_prop_literal(thr, 1, \"fatal\")) {\n\t\t\tfatal = duk_to_boolean(thr, -1);\n\t\t}\n\t\tif (duk_get_prop_literal(thr, 1, \"ignoreBOM\")) {\n\t\t\tignore_bom = duk_to_boolean(thr, -1);\n\t\t}\n\t}\n\n\tduk_push_this(thr);\n\n\t/* The decode context is not assumed to be zeroed; all fields are\n\t * initialized explicitly.\n\t */\n\tdec_ctx = (duk__decode_context *) duk_push_fixed_buffer(thr, sizeof(duk__decode_context));\n\tdec_ctx->fatal = (duk_uint8_t) fatal;\n\tdec_ctx->ignore_bom = (duk_uint8_t) ignore_bom;\n\tduk__utf8_decode_init(dec_ctx);  /* Initializes remaining fields. */\n\n\tduk_put_prop_literal(thr, -2, DUK_INTERNAL_SYMBOL(\"Context\"));\n\treturn 0;\n}\n\n/* Get TextDecoder context from 'this'; leaves garbage on stack. */\nDUK_LOCAL duk__decode_context *duk__get_textdecoder_context(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\tduk_push_this(thr);\n\tduk_get_prop_literal(thr, -1, DUK_INTERNAL_SYMBOL(\"Context\"));\n\tdec_ctx = (duk__decode_context *) duk_require_buffer(thr, -1, NULL);\n\tDUK_ASSERT(dec_ctx != NULL);\n\treturn dec_ctx;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\tduk_int_t magic;\n\n\tdec_ctx = duk__get_textdecoder_context(thr);\n\tmagic = duk_get_current_magic(thr);\n\tswitch (magic) {\n\tcase 0:\n\t\t/* Encoding is now fixed, so _Context lookup is only needed to\n\t\t * validate the 'this' binding (TypeError if not TextDecoder-like).\n\t\t */\n\t\tduk_push_literal(thr, \"utf-8\");\n\t\tbreak;\n\tcase 1:\n\t\tduk_push_boolean(thr, dec_ctx->fatal);\n\t\tbreak;\n\tdefault:\n\t\tduk_push_boolean(thr, dec_ctx->ignore_bom);\n\t\tbreak;\n\t}\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\n\tdec_ctx = duk__get_textdecoder_context(thr);\n\treturn duk__decode_helper(thr, dec_ctx);\n}\n#endif  /* DUK_USE_ENCODING_BUILTINS */\n\n/*\n *  Internal helper for Node.js Buffer\n */\n\n/* Internal helper used for Node.js Buffer .toString().  Value stack convention\n * is currently odd: it mimics TextDecoder .decode() so that argument must be at\n * index 0, and decode options (not present for Buffer) at index 1.  Return value\n * is a Duktape/C function return value.\n */\nDUK_INTERNAL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_hthread *thr) {\n\tduk__decode_context dec_ctx;\n\n\tdec_ctx.fatal = 0;  /* use replacement chars */\n\tdec_ctx.ignore_bom = 1;  /* ignore BOMs (matches Node.js Buffer .toString()) */\n\tduk__utf8_decode_init(&dec_ctx);\n\n\treturn duk__decode_helper(thr, &dec_ctx);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_error.c",
    "content": "/*\n *  Error built-ins\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL duk_ret_t duk_bi_error_constructor_shared(duk_hthread *thr) {\n\t/* Behavior for constructor and non-constructor call is\n\t * the same except for augmenting the created error.  When\n\t * called as a constructor, the caller (duk_new()) will handle\n\t * augmentation; when called as normal function, we need to do\n\t * it here.\n\t */\n\n\tduk_small_int_t bidx_prototype = duk_get_current_magic(thr);\n\n\t/* same for both error and each subclass like TypeError */\n\tduk_uint_t flags_and_class = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                             DUK_HOBJECT_FLAG_FASTREFS |\n\t                             DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ERROR);\n\n\t(void) duk_push_object_helper(thr, flags_and_class, bidx_prototype);\n\n\t/* If message is undefined, the own property 'message' is not set at\n\t * all to save property space.  An empty message is inherited anyway.\n\t */\n\tif (!duk_is_undefined(thr, 0)) {\n\t\tduk_to_string(thr, 0);\n\t\tduk_dup_0(thr);  /* [ message error message ] */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);\n\t}\n\n\t/* Augment the error if called as a normal function.  __FILE__ and __LINE__\n\t * are not desirable in this case.\n\t */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tif (!duk_is_constructor_call(thr)) {\n\t\tduk_err_augment_error_create(thr, thr, NULL, 0, DUK_AUGMENT_FLAG_NOBLAME_FILELINE);\n\t}\n#endif\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_to_string(duk_hthread *thr) {\n\t/* XXX: optimize with more direct internal access */\n\n\tduk_push_this(thr);\n\t(void) duk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\n\t/* [ ... this ] */\n\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME);\n\tif (duk_is_undefined(thr, -1)) {\n\t\tduk_pop(thr);\n\t\tduk_push_literal(thr, \"Error\");\n\t} else {\n\t\tduk_to_string(thr, -1);\n\t}\n\n\t/* [ ... this name ] */\n\n\t/* XXX: Are steps 6 and 7 in E5 Section 15.11.4.4 duplicated by\n\t * accident or are they actually needed?  The first ToString()\n\t * could conceivably return 'undefined'.\n\t */\n\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE);\n\tif (duk_is_undefined(thr, -1)) {\n\t\tduk_pop(thr);\n\t\tduk_push_hstring_empty(thr);\n\t} else {\n\t\tduk_to_string(thr, -1);\n\t}\n\n\t/* [ ... this name message ] */\n\n\tif (duk_get_length(thr, -2) == 0) {\n\t\t/* name is empty -> return message */\n\t\treturn 1;\n\t}\n\tif (duk_get_length(thr, -1) == 0) {\n\t\t/* message is empty -> return name */\n\t\tduk_pop(thr);\n\t\treturn 1;\n\t}\n\tduk_push_literal(thr, \": \");\n\tduk_insert(thr, -2);  /* ... name ': ' message */\n\tduk_concat(thr, 3);\n\n\treturn 1;\n}\n\n#if defined(DUK_USE_TRACEBACKS)\n\n/*\n *  Traceback handling\n *\n *  The unified helper decodes the traceback and produces various requested\n *  outputs.  It should be optimized for size, and may leave garbage on stack,\n *  only the topmost return value matters.  For instance, traceback separator\n *  and decoded strings are pushed even when looking for filename only.\n *\n *  NOTE: although _Tracedata is an internal property, user code can currently\n *  write to the array (or replace it with something other than an array).\n *  The code below must tolerate arbitrary _Tracedata.  It can throw errors\n *  etc, but cannot cause a segfault or memory unsafe behavior.\n */\n\n/* constants arbitrary, chosen for small loads */\n#define DUK__OUTPUT_TYPE_TRACEBACK   (-1)\n#define DUK__OUTPUT_TYPE_FILENAME    0\n#define DUK__OUTPUT_TYPE_LINENUMBER  1\n\nDUK_LOCAL duk_ret_t duk__error_getter_helper(duk_hthread *thr, duk_small_int_t output_type) {\n\tduk_idx_t idx_td;\n\tduk_small_int_t i;  /* traceback depth fits into 16 bits */\n\tduk_small_int_t t;  /* stack type fits into 16 bits */\n\tduk_small_int_t count_func = 0;  /* traceback depth ensures fits into 16 bits */\n\tconst char *str_tailcall = \" tailcall\";\n\tconst char *str_strict = \" strict\";\n\tconst char *str_construct = \" construct\";\n\tconst char *str_prevyield = \" preventsyield\";\n\tconst char *str_directeval = \" directeval\";\n\tconst char *str_empty = \"\";\n\n\tDUK_ASSERT_TOP(thr, 0);  /* fixed arg count */\n\n\tduk_push_this(thr);\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_TRACEDATA);\n\tidx_td = duk_get_top_index(thr);\n\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_NEWLINE_4SPACE);\n\tduk_push_this(thr);\n\n\t/* [ ... this tracedata sep this ] */\n\n\t/* XXX: skip null filename? */\n\n\tif (duk_check_type(thr, idx_td, DUK_TYPE_OBJECT)) {\n\t\t/* Current tracedata contains 2 entries per callstack entry. */\n\t\tfor (i = 0; ; i += 2) {\n\t\t\tduk_int_t pc;\n\t\t\tduk_uint_t line;\n\t\t\tduk_uint_t flags;\n\t\t\tduk_double_t d;\n\t\t\tconst char *funcname;\n\t\t\tconst char *filename;\n\t\t\tduk_hobject *h_func;\n\t\t\tduk_hstring *h_name;\n\n\t\t\tduk_require_stack(thr, 5);\n\t\t\tduk_get_prop_index(thr, idx_td, (duk_uarridx_t) i);\n\t\t\tduk_get_prop_index(thr, idx_td, (duk_uarridx_t) (i + 1));\n\t\t\td = duk_to_number_m1(thr);\n\t\t\tpc = duk_double_to_int_t(DUK_FMOD(d, DUK_DOUBLE_2TO32));\n\t\t\tflags = duk_double_to_uint_t(DUK_FLOOR(d / DUK_DOUBLE_2TO32));\n\t\t\tt = (duk_small_int_t) duk_get_type(thr, -2);\n\n\t\t\tif (t == DUK_TYPE_OBJECT || t == DUK_TYPE_LIGHTFUNC) {\n\t\t\t\t/*\n\t\t\t\t *  ECMAScript/native function call or lightfunc call\n\t\t\t\t */\n\n\t\t\t\tcount_func++;\n\n\t\t\t\t/* [ ... v1(func) v2(pc+flags) ] */\n\n\t\t\t\t/* These may be systematically omitted by Duktape\n\t\t\t\t * with certain config options, but allow user to\n\t\t\t\t * set them on a case-by-case basis.\n\t\t\t\t */\n\t\t\t\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME);\n\t\t\t\tduk_get_prop_stridx_short(thr, -3, DUK_STRIDX_FILE_NAME);\n\n#if defined(DUK_USE_PC2LINE)\n\t\t\t\tline = (duk_uint_t) duk_hobject_pc2line_query(thr, -4, (duk_uint_fast32_t) pc);\n#else\n\t\t\t\tline = 0;\n#endif\n\n\t\t\t\t/* [ ... v1 v2 name filename ] */\n\n\t\t\t\t/* When looking for .fileName/.lineNumber, blame first\n\t\t\t\t * function which has a .fileName.\n\t\t\t\t */\n\t\t\t\tif (duk_is_string_notsymbol(thr, -1)) {\n\t\t\t\t\tif (output_type == DUK__OUTPUT_TYPE_FILENAME) {\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t} else if (output_type == DUK__OUTPUT_TYPE_LINENUMBER) {\n\t\t\t\t\t\tduk_push_uint(thr, line);\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* XXX: Change 'anon' handling here too, to use empty string for anonymous functions? */\n\t\t\t\t/* XXX: Could be improved by coercing to a readable duk_tval (especially string escaping) */\n\t\t\t\th_name = duk_get_hstring_notsymbol(thr, -2);  /* may be NULL */\n\t\t\t\tfuncname = (h_name == NULL || h_name == DUK_HTHREAD_STRING_EMPTY_STRING(thr)) ?\n\t\t\t\t           \"[anon]\" : (const char *) DUK_HSTRING_GET_DATA(h_name);\n\t\t\t\tfilename = duk_get_string_notsymbol(thr, -1);\n\t\t\t\tfilename = filename ? filename : \"\";\n\t\t\t\tDUK_ASSERT(funcname != NULL);\n\t\t\t\tDUK_ASSERT(filename != NULL);\n\n\t\t\t\th_func = duk_get_hobject(thr, -4);  /* NULL for lightfunc */\n\n\t\t\t\tif (h_func == NULL) {\n\t\t\t\t\tduk_push_sprintf(thr, \"at %s light%s%s%s%s%s\",\n\t\t\t\t\t                 (const char *) funcname,\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));\n\t\t\t\t} else if (DUK_HOBJECT_HAS_NATFUNC(h_func)) {\n\t\t\t\t\tduk_push_sprintf(thr, \"at %s (%s) native%s%s%s%s%s\",\n\t\t\t\t\t                 (const char *) funcname,\n\t\t\t\t\t                 (const char *) filename,\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));\n\t\t\t\t} else {\n\t\t\t\t\tduk_push_sprintf(thr, \"at %s (%s:%lu)%s%s%s%s%s\",\n\t\t\t\t\t                 (const char *) funcname,\n\t\t\t\t\t                 (const char *) filename,\n\t\t\t\t\t                 (unsigned long) line,\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));\n\t\t\t\t}\n\t\t\t\tduk_replace(thr, -5);   /* [ ... v1 v2 name filename str ] -> [ ... str v2 name filename ] */\n\t\t\t\tduk_pop_3(thr);         /* -> [ ... str ] */\n\t\t\t} else if (t == DUK_TYPE_STRING) {\n\t\t\t\tconst char *str_file;\n\n\t\t\t\t/*\n\t\t\t\t *  __FILE__ / __LINE__ entry, here 'pc' is line number directly.\n\t\t\t\t *  Sometimes __FILE__ / __LINE__ is reported as the source for\n\t\t\t\t *  the error (fileName, lineNumber), sometimes not.\n\t\t\t\t */\n\n\t\t\t\t/* [ ... v1(filename) v2(line+flags) ] */\n\n\t\t\t\t/* When looking for .fileName/.lineNumber, blame compilation\n\t\t\t\t * or C call site unless flagged not to do so.\n\t\t\t\t */\n\t\t\t\tif (!(flags & DUK_TB_FLAG_NOBLAME_FILELINE)) {\n\t\t\t\t\tif (output_type == DUK__OUTPUT_TYPE_FILENAME) {\n\t\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t} else if (output_type == DUK__OUTPUT_TYPE_LINENUMBER) {\n\t\t\t\t\t\tduk_push_int(thr, pc);\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* Tracedata is trusted but avoid any risk of using a NULL\n\t\t\t\t * for %s format because it has undefined behavior.  Symbols\n\t\t\t\t * don't need to be explicitly rejected as they pose no memory\n\t\t\t\t * safety issues.\n\t\t\t\t */\n\t\t\t\tstr_file = (const char *) duk_get_string(thr, -2);\n\t\t\t\tduk_push_sprintf(thr, \"at [anon] (%s:%ld) internal\",\n\t\t\t\t                 (const char *) (str_file ? str_file : \"null\"), (long) pc);\n\t\t\t\tduk_replace(thr, -3);  /* [ ... v1 v2 str ] -> [ ... str v2 ] */\n\t\t\t\tduk_pop(thr);          /* -> [ ... str ] */\n\t\t\t} else {\n\t\t\t\t/* unknown, ignore */\n\t\t\t\tduk_pop_2(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (count_func >= DUK_USE_TRACEBACK_DEPTH) {\n\t\t\t/* Possibly truncated; there is no explicit truncation\n\t\t\t * marker so this is the best we can do.\n\t\t\t */\n\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_BRACKETED_ELLIPSIS);\n\t\t}\n\t}\n\n\t/* [ ... this tracedata sep this str1 ... strN ] */\n\n\tif (output_type != DUK__OUTPUT_TYPE_TRACEBACK) {\n\t\treturn 0;\n\t} else {\n\t\t/* The 'this' after 'sep' will get ToString() coerced by\n\t\t * duk_join() automatically.  We don't want to do that\n\t\t * coercion when providing .fileName or .lineNumber (GH-254).\n\t\t */\n\t\tduk_join(thr, duk_get_top(thr) - (idx_td + 2) /*count, not including sep*/);\n\t\treturn 1;\n\t}\n}\n\n/* XXX: Output type could be encoded into native function 'magic' value to\n * save space.  For setters the stridx could be encoded into 'magic'.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter(duk_hthread *thr) {\n\treturn duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_TRACEBACK);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter(duk_hthread *thr) {\n\treturn duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_FILENAME);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_hthread *thr) {\n\treturn duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_LINENUMBER);\n}\n\n#else  /* DUK_USE_TRACEBACKS */\n\n/*\n *  Traceback handling when tracebacks disabled.\n *\n *  The fileName / lineNumber stubs are now necessary because built-in\n *  data will include the accessor properties in Error.prototype.  If those\n *  are removed for builds without tracebacks, these can also be removed.\n *  'stack' should still be present and produce a ToString() equivalent:\n *  this is useful for user code which prints a stacktrace and expects to\n *  see something useful.  A normal stacktrace also begins with a ToString()\n *  of the error so this makes sense.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter(duk_hthread *thr) {\n\t/* XXX: remove this native function and map 'stack' accessor\n\t * to the toString() implementation directly.\n\t */\n\treturn duk_bi_error_prototype_to_string(thr);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter(duk_hthread *thr) {\n\tDUK_UNREF(thr);\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_hthread *thr) {\n\tDUK_UNREF(thr);\n\treturn 0;\n}\n\n#endif  /* DUK_USE_TRACEBACKS */\n\nDUK_LOCAL duk_ret_t duk__error_setter_helper(duk_hthread *thr, duk_small_uint_t stridx_key) {\n\t/* Attempt to write 'stack', 'fileName', 'lineNumber' works as if\n\t * user code called Object.defineProperty() to create an overriding\n\t * own property.  This allows user code to overwrite .fileName etc\n\t * intuitively as e.g. \"err.fileName = 'dummy'\" as one might expect.\n\t * See https://github.com/svaarala/duktape/issues/387.\n\t */\n\n\tDUK_ASSERT_TOP(thr, 1);  /* fixed arg count: value */\n\n\tduk_push_this(thr);\n\tduk_push_hstring_stridx(thr, stridx_key);\n\tduk_dup_0(thr);\n\n\t/* [ ... obj key value ] */\n\n\tDUK_DD(DUK_DDPRINT(\"error setter: %!T %!T %!T\",\n\t                   duk_get_tval(thr, -3), duk_get_tval(thr, -2), duk_get_tval(thr, -1)));\n\n\tduk_def_prop(thr, -3, DUK_DEFPROP_HAVE_VALUE |\n\t                      DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE |\n\t                      DUK_DEFPROP_HAVE_ENUMERABLE | /*not enumerable*/\n\t                      DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE);\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_setter(duk_hthread *thr) {\n\treturn duk__error_setter_helper(thr, DUK_STRIDX_STACK);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_setter(duk_hthread *thr) {\n\treturn duk__error_setter_helper(thr, DUK_STRIDX_FILE_NAME);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_setter(duk_hthread *thr) {\n\treturn duk__error_setter_helper(thr, DUK_STRIDX_LINE_NUMBER);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_function.c",
    "content": "/*\n *  Function built-ins\n */\n\n#include \"duk_internal.h\"\n\n/* Needed even when Function built-in is disabled. */\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype(duk_hthread *thr) {\n\t/* ignore arguments, return undefined (E5 Section 15.3.4) */\n\tDUK_UNREF(thr);\n\treturn 0;\n}\n\n#if defined(DUK_USE_FUNCTION_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_function_constructor(duk_hthread *thr) {\n\tduk_hstring *h_sourcecode;\n\tduk_idx_t nargs;\n\tduk_idx_t i;\n\tduk_small_uint_t comp_flags;\n\tduk_hcompfunc *func;\n\tduk_hobject *outer_lex_env;\n\tduk_hobject *outer_var_env;\n\n\t/* normal and constructor calls have identical semantics */\n\n\tnargs = duk_get_top(thr);\n\tfor (i = 0; i < nargs; i++) {\n\t\tduk_to_string(thr, i);  /* Rejects Symbols during coercion. */\n\t}\n\n\tif (nargs == 0) {\n\t\tduk_push_hstring_empty(thr);\n\t\tduk_push_hstring_empty(thr);\n\t} else if (nargs == 1) {\n\t\t/* XXX: cover this with the generic >1 case? */\n\t\tduk_push_hstring_empty(thr);\n\t} else {\n\t\tduk_insert(thr, 0);   /* [ arg1 ... argN-1 body] -> [body arg1 ... argN-1] */\n\t\tduk_push_literal(thr, \",\");\n\t\tduk_insert(thr, 1);\n\t\tduk_join(thr, nargs - 1);\n\t}\n\n\t/* [ body formals ], formals is comma separated list that needs to be parsed */\n\n\tDUK_ASSERT_TOP(thr, 2);\n\n\t/* XXX: this placeholder is not always correct, but use for now.\n\t * It will fail in corner cases; see test-dev-func-cons-args.js.\n\t */\n\tduk_push_literal(thr, \"function(\");\n\tduk_dup_1(thr);\n\tduk_push_literal(thr, \"){\");\n\tduk_dup_0(thr);\n\tduk_push_literal(thr, \"\\n}\");  /* Newline is important to handle trailing // comment. */\n\tduk_concat(thr, 5);\n\n\t/* [ body formals source ] */\n\n\tDUK_ASSERT_TOP(thr, 3);\n\n\t/* strictness is not inherited, intentional */\n\tcomp_flags = DUK_COMPILE_FUNCEXPR;\n\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_COMPILE);  /* XXX: copy from caller? */  /* XXX: ignored now */\n\th_sourcecode = duk_require_hstring(thr, -2);  /* no symbol check needed; -2 is concat'd code */\n\tduk_js_compile(thr,\n\t               (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_sourcecode),\n\t               (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sourcecode),\n\t               comp_flags);\n\n\t/* Force .name to 'anonymous' (ES2015). */\n\tduk_push_literal(thr, \"anonymous\");\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n\n\tfunc = (duk_hcompfunc *) duk_known_hobject(thr, -1);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) func));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) func));\n\n\t/* [ body formals source template ] */\n\n\t/* only outer_lex_env matters, as functions always get a new\n\t * variable declaration environment.\n\t */\n\n\touter_lex_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\touter_var_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\n\tduk_js_push_closure(thr, func, outer_var_env, outer_lex_env, 1 /*add_auto_proto*/);\n\n\t/* [ body formals source template closure ] */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_FUNCTION_BUILTIN */\n\n#if defined(DUK_USE_FUNCTION_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_to_string(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\t/*\n\t *  E5 Section 15.3.4.2 places few requirements on the output of\n\t *  this function: the result is implementation dependent, must\n\t *  follow FunctionDeclaration syntax (in particular, must have a\n\t *  name even for anonymous functions or functions with empty name).\n\t *  The output does NOT need to compile into anything useful.\n\t *\n\t *  E6 Section 19.2.3.5 changes the requirements completely: the\n\t *  result must either eval() to a functionally equivalent object\n\t *  OR eval() to a SyntaxError.\n\t *\n\t *  We opt for the SyntaxError approach for now, with a syntax that\n\t *  mimics V8's native function syntax:\n\t *\n\t *      'function cos() { [native code] }'\n\t *\n\t *  but extended with [ecmascript code], [bound code], and\n\t *  [lightfunc code].\n\t */\n\n\tduk_push_this(thr);\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *obj = DUK_TVAL_GET_OBJECT(tv);\n\t\tconst char *func_name;\n\n\t\t/* Function name: missing/undefined is mapped to empty string,\n\t\t * otherwise coerce to string.  No handling for invalid identifier\n\t\t * characters or e.g. '{' in the function name.  This doesn't\n\t\t * really matter as long as a SyntaxError results.  Technically\n\t\t * if the name contained a suitable prefix followed by '//' it\n\t\t * might cause the result to parse without error.\n\t\t */\n\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME);\n\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\tfunc_name = \"\";\n\t\t} else {\n\t\t\tfunc_name = duk_to_string(thr, -1);\n\t\t\tDUK_ASSERT(func_name != NULL);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(obj)) {\n\t\t\tduk_push_sprintf(thr, \"function %s() { [ecmascript code] }\", (const char *) func_name);\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(obj)) {\n\t\t\tduk_push_sprintf(thr, \"function %s() { [native code] }\", (const char *) func_name);\n\t\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(obj)) {\n\t\t\tduk_push_sprintf(thr, \"function %s() { [bound code] }\", (const char *) func_name);\n\t\t} else {\n\t\t\tgoto type_error;\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_push_lightfunc_tostring(thr, tv);\n\t} else {\n\t\tgoto type_error;\n\t}\n\n\treturn 1;\n\n type_error:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n#endif\n\n/* Always present because the native function pointer is needed in call\n * handling.\n */\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_call(duk_hthread *thr) {\n\t/* .call() is dealt with in call handling by simulating its\n\t * effects so this function is actually never called.\n\t */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_apply(duk_hthread *thr) {\n\t/* Like .call(), never actually called. */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_apply(duk_hthread *thr) {\n\t/* Like .call(), never actually called. */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_construct(duk_hthread *thr) {\n\t/* Like .call(), never actually called. */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\n#if defined(DUK_USE_FUNCTION_BUILTIN)\n/* Create a bound function which points to a target function which may\n * be bound or non-bound.  If the target is bound, the argument lists\n * and 'this' binding of the functions are merged and the resulting\n * function points directly to the non-bound target.\n */\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_bind(duk_hthread *thr) {\n\tduk_hboundfunc *h_bound;\n\tduk_idx_t nargs;  /* bound args, not counting 'this' binding */\n\tduk_idx_t bound_nargs;\n\tduk_int_t bound_len;\n\tduk_tval *tv_prevbound;\n\tduk_idx_t n_prevbound;\n\tduk_tval *tv_res;\n\tduk_tval *tv_tmp;\n\n\t/* XXX: C API call, e.g. duk_push_bound_function(thr, target_idx, nargs); */\n\n\t/* Vararg function, careful arg handling, e.g. thisArg may not\n\t * be present.\n\t */\n\tnargs = duk_get_top(thr) - 1;  /* actual args, not counting 'this' binding */\n\tif (nargs < 0) {\n\t\tnargs++;\n\t\tduk_push_undefined(thr);\n\t}\n\tDUK_ASSERT(nargs >= 0);\n\n\t/* Limit 'nargs' for bound functions to guarantee arithmetic\n\t * below will never wrap.\n\t */\n\tif (nargs > (duk_idx_t) DUK_HBOUNDFUNC_MAX_ARGS) {\n\t\tDUK_DCERROR_RANGE_INVALID_COUNT(thr);\n\t}\n\n\tduk_push_this(thr);\n\tduk_require_callable(thr, -1);\n\n\t/* [ thisArg arg1 ... argN func ]  (thisArg+args == nargs+1 total) */\n\tDUK_ASSERT_TOP(thr, nargs + 2);\n\n\t/* Create bound function object. */\n\th_bound = duk_push_hboundfunc(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&h_bound->target));\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&h_bound->this_binding));\n\tDUK_ASSERT(h_bound->args == NULL);\n\tDUK_ASSERT(h_bound->nargs == 0);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_bound) == NULL);\n\n\t/* [ thisArg arg1 ... argN func boundFunc ] */\n\n\t/* If the target is a bound function, argument lists must be\n\t * merged.  The 'this' binding closest to the target function\n\t * wins because in call handling the 'this' gets replaced over\n\t * and over again until we call the non-bound function.\n\t */\n\ttv_prevbound = NULL;\n\tn_prevbound = 0;\n\ttv_tmp = DUK_GET_TVAL_POSIDX(thr, 0);\n\tDUK_TVAL_SET_TVAL(&h_bound->this_binding, tv_tmp);\n\ttv_tmp = DUK_GET_TVAL_NEGIDX(thr, -2);\n\tDUK_TVAL_SET_TVAL(&h_bound->target, tv_tmp);\n\n\tif (DUK_TVAL_IS_OBJECT(tv_tmp)) {\n\t\tduk_hobject *h_target;\n\t\tduk_hobject *bound_proto;\n\n\t\th_target = DUK_TVAL_GET_OBJECT(tv_tmp);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(h_target));\n\n\t\t/* Internal prototype must be copied from the target.\n\t\t * For lightfuncs Function.prototype is used and is already\n\t\t * in place.\n\t\t */\n\t\tbound_proto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_target);\n\t\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) h_bound, bound_proto);\n\n\t\t/* The 'strict' flag is copied to get the special [[Get]] of E5.1\n\t\t * Section 15.3.5.4 to apply when a 'caller' value is a strict bound\n\t\t * function.  Not sure if this is correct, because the specification\n\t\t * is a bit ambiguous on this point but it would make sense.\n\t\t */\n\t\t/* Strictness is inherited from target. */\n\t\tif (DUK_HOBJECT_HAS_STRICT(h_target)) {\n\t\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_bound);\n\t\t}\n\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(h_target)) {\n\t\t\tduk_hboundfunc *h_boundtarget;\n\n\t\t\th_boundtarget = (duk_hboundfunc *) (void *) h_target;\n\n\t\t\t/* The final function should always be non-bound, unless\n\t\t\t * there's a bug in the internals.  Assert for it.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(&h_boundtarget->target) ||\n\t\t\t           (DUK_TVAL_IS_OBJECT(&h_boundtarget->target) &&\n\t\t\t            DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(&h_boundtarget->target)) &&\n\t\t\t            !DUK_HOBJECT_IS_BOUNDFUNC(DUK_TVAL_GET_OBJECT(&h_boundtarget->target))));\n\n\t\t\tDUK_TVAL_SET_TVAL(&h_bound->target, &h_boundtarget->target);\n\t\t\tDUK_TVAL_SET_TVAL(&h_bound->this_binding, &h_boundtarget->this_binding);\n\n\t\t\ttv_prevbound = h_boundtarget->args;\n\t\t\tn_prevbound = h_boundtarget->nargs;\n\t\t}\n\t} else {\n\t\t/* Lightfuncs are always strict. */\n\t\tduk_hobject *bound_proto;\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_tmp));\n\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_bound);\n\t\tbound_proto = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];\n\t\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) h_bound, bound_proto);\n\t}\n\n\tDUK_TVAL_INCREF(thr, &h_bound->target);  /* old values undefined, no decref needed */\n\tDUK_TVAL_INCREF(thr, &h_bound->this_binding);\n\n\tbound_nargs = n_prevbound + nargs;\n\tif (bound_nargs > (duk_idx_t) DUK_HBOUNDFUNC_MAX_ARGS) {\n\t\tDUK_DCERROR_RANGE_INVALID_COUNT(thr);\n\t}\n\ttv_res = (duk_tval *) DUK_ALLOC_CHECKED(thr, ((duk_size_t) bound_nargs) * sizeof(duk_tval));\n\tDUK_ASSERT(tv_res != NULL || bound_nargs == 0);\n\tDUK_ASSERT(h_bound->args == NULL);\n\tDUK_ASSERT(h_bound->nargs == 0);\n\th_bound->args = tv_res;\n\th_bound->nargs = bound_nargs;\n\n\tDUK_ASSERT(n_prevbound >= 0);\n\tduk_copy_tvals_incref(thr, tv_res, tv_prevbound, (duk_size_t) n_prevbound);\n\tDUK_ASSERT(nargs >= 0);\n\tduk_copy_tvals_incref(thr, tv_res + n_prevbound, DUK_GET_TVAL_POSIDX(thr, 1), (duk_size_t) nargs);\n\n\t/* [ thisArg arg1 ... argN func boundFunc ] */\n\n\t/* Bound function 'length' property is interesting.\n\t * For lightfuncs, simply read the virtual property.\n\t */\n\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH);\n\tbound_len = duk_get_int(thr, -1);  /* ES2015: no coercion */\n\tif (bound_len < nargs) {\n\t\tbound_len = 0;\n\t} else {\n\t\tbound_len -= nargs;\n\t}\n\tif (sizeof(duk_int_t) > 4 && bound_len > (duk_int_t) DUK_UINT32_MAX) {\n\t\tbound_len = (duk_int_t) DUK_UINT32_MAX;\n\t}\n\tduk_pop(thr);\n\tDUK_ASSERT(bound_len >= 0);\n\ttv_tmp = thr->valstack_top++;\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_tmp));\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv_tmp));\n\tDUK_TVAL_SET_U32(tv_tmp, (duk_uint32_t) bound_len);  /* in-place update, fastint */\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);  /* attrs in E6 Section 9.2.4 */\n\n\t/* XXX: could these be virtual? */\n\t/* Caller and arguments must use the same thrower, [[ThrowTypeError]]. */\n\tduk_xdef_prop_stridx_thrower(thr, -1, DUK_STRIDX_CALLER);\n\tduk_xdef_prop_stridx_thrower(thr, -1, DUK_STRIDX_LC_ARGUMENTS);\n\n\t/* Function name and fileName (non-standard). */\n\tduk_push_literal(thr, \"bound \");  /* ES2015 19.2.3.2. */\n\tduk_get_prop_stridx(thr, -3, DUK_STRIDX_NAME);\n\tif (!duk_is_string_notsymbol(thr, -1)) {\n\t\t/* ES2015 has requirement to check that .name of target is a string\n\t\t * (also must check for Symbol); if not, targetName should be the\n\t\t * empty string.  ES2015 19.2.3.2.\n\t\t */\n\t\tduk_pop(thr);\n\t\tduk_push_hstring_empty(thr);\n\t}\n\tduk_concat(thr, 2);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C);\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"created bound function: %!iT\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\treturn 1;\n}\n#endif  /* DUK_USE_FUNCTION_BUILTIN */\n\n/* %NativeFunctionPrototype% .length getter. */\nDUK_INTERNAL duk_ret_t duk_bi_native_function_length(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hnatfunc *h;\n\tduk_int16_t func_nargs;\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = (duk_hnatfunc *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (!DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h)) {\n\t\t\tgoto fail_type;\n\t\t}\n\t\tfunc_nargs = h->nargs;\n\t\tduk_push_int(thr, func_nargs == DUK_HNATFUNC_NARGS_VARARGS ? 0 : func_nargs);\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_small_uint_t lf_flags;\n\t\tduk_small_uint_t lf_len;\n\n\t\tlf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv);\n\t\tlf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags);\n\t\tduk_push_uint(thr, lf_len);\n\t} else {\n\t\tgoto fail_type;\n\t}\n\treturn 1;\n\n fail_type:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n\n/* %NativeFunctionPrototype% .name getter. */\nDUK_INTERNAL duk_ret_t duk_bi_native_function_name(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hnatfunc *h;\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = (duk_hnatfunc *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (!DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h)) {\n\t\t\tgoto fail_type;\n\t\t}\n#if 0\n\t\tduk_push_hnatfunc_name(thr, h);\n#endif\n\t\tduk_push_hstring_empty(thr);\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_push_lightfunc_name(thr, tv);\n\t} else {\n\t\tgoto fail_type;\n\t}\n\treturn 1;\n\n fail_type:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_hasinstance(duk_hthread *thr) {\n\t/* This binding: RHS, stack index 0: LHS. */\n\tduk_bool_t ret;\n\n\tret = duk_js_instanceof_ordinary(thr, DUK_GET_TVAL_POSIDX(thr, 0), DUK_GET_THIS_TVAL_PTR(thr));\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_global.c",
    "content": "/*\n *  Global object built-ins\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Encoding/decoding helpers\n */\n\n/* XXX: Could add fast path (for each transform callback) with direct byte\n * lookups (no shifting) and no explicit check for x < 0x80 before table\n * lookup.\n */\n\n/* Macros for creating and checking bitmasks for character encoding.\n * Bit number is a bit counterintuitive, but minimizes code size.\n */\n#define DUK__MKBITS(a,b,c,d,e,f,g,h)  ((duk_uint8_t) ( \\\n\t((a) << 0) | ((b) << 1) | ((c) << 2) | ((d) << 3) | \\\n\t((e) << 4) | ((f) << 5) | ((g) << 6) | ((h) << 7) \\\n\t))\n#define DUK__CHECK_BITMASK(table,cp)  ((table)[(cp) >> 3] & (1 << ((cp) & 0x07)))\n\n/* E5.1 Section 15.1.3.3: uriReserved + uriUnescaped + '#' */\nDUK_LOCAL const duk_uint8_t duk__encode_uriunescaped_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 1, 0, 1, 1, 0, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x20-0x2f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 0, 1, 0, 1),  /* 0x30-0x3f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x40-0x4f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x60-0x6f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 1, 0),  /* 0x70-0x7f */\n};\n\n/* E5.1 Section 15.1.3.4: uriUnescaped */\nDUK_LOCAL const duk_uint8_t duk__encode_uricomponent_unescaped_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 1, 0, 0, 0, 0, 0, 1), DUK__MKBITS(1, 1, 1, 0, 0, 1, 1, 0),  /* 0x20-0x2f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 0, 0, 0, 0, 0, 0),  /* 0x30-0x3f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x40-0x4f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x60-0x6f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 1, 0),  /* 0x70-0x7f */\n};\n\n/* E5.1 Section 15.1.3.1: uriReserved + '#' */\nDUK_LOCAL const duk_uint8_t duk__decode_uri_reserved_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 0, 0, 1, 1, 0, 1, 0), DUK__MKBITS(0, 0, 0, 1, 1, 0, 0, 1),  /* 0x20-0x2f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 1, 1, 0, 1, 0, 1),  /* 0x30-0x3f */\n\tDUK__MKBITS(1, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x40-0x4f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x60-0x6f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x70-0x7f */\n};\n\n/* E5.1 Section 15.1.3.2: empty */\nDUK_LOCAL const duk_uint8_t duk__decode_uri_component_reserved_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x20-0x2f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x30-0x3f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x40-0x4f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x60-0x6f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x70-0x7f */\n};\n\n#if defined(DUK_USE_SECTION_B)\n/* E5.1 Section B.2.2, step 7. */\nDUK_LOCAL const duk_uint8_t duk__escape_unescaped_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 1, 1, 0, 1, 1, 1),  /* 0x20-0x2f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 0, 0, 0, 0, 0, 0),  /* 0x30-0x3f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x40-0x4f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x60-0x6f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 0)   /* 0x70-0x7f */\n};\n#endif  /* DUK_USE_SECTION_B */\n\ntypedef struct {\n\tduk_hthread *thr;\n\tduk_hstring *h_str;\n\tduk_bufwriter_ctx bw;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p_end;\n} duk__transform_context;\n\ntypedef void (*duk__transform_callback)(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp);\n\n/* XXX: refactor and share with other code */\nDUK_LOCAL duk_small_int_t duk__decode_hex_escape(const duk_uint8_t *p, duk_small_int_t n) {\n\tduk_small_int_t ch;\n\tduk_small_int_t t = 0;\n\n\twhile (n > 0) {\n\t\tt = t * 16;\n\t\tch = (duk_small_int_t) duk_hex_dectab[*p++];\n\t\tif (DUK_LIKELY(ch >= 0)) {\n\t\t\tt += ch;\n\t\t} else {\n\t\t\treturn -1;\n\t\t}\n\t\tn--;\n\t}\n\treturn t;\n}\n\nDUK_LOCAL int duk__transform_helper(duk_hthread *thr, duk__transform_callback callback, const void *udata) {\n\tduk__transform_context tfm_ctx_alloc;\n\tduk__transform_context *tfm_ctx = &tfm_ctx_alloc;\n\tduk_codepoint_t cp;\n\n\ttfm_ctx->thr = thr;\n\n\ttfm_ctx->h_str = duk_to_hstring(thr, 0);\n\tDUK_ASSERT(tfm_ctx->h_str != NULL);\n\n\tDUK_BW_INIT_PUSHBUF(thr, &tfm_ctx->bw, DUK_HSTRING_GET_BYTELEN(tfm_ctx->h_str));  /* initial size guess */\n\n\ttfm_ctx->p_start = DUK_HSTRING_GET_DATA(tfm_ctx->h_str);\n\ttfm_ctx->p_end = tfm_ctx->p_start + DUK_HSTRING_GET_BYTELEN(tfm_ctx->h_str);\n\ttfm_ctx->p = tfm_ctx->p_start;\n\n\twhile (tfm_ctx->p < tfm_ctx->p_end) {\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &tfm_ctx->p, tfm_ctx->p_start, tfm_ctx->p_end);\n\t\tcallback(tfm_ctx, udata, cp);\n\t}\n\n\tDUK_BW_COMPACT(thr, &tfm_ctx->bw);\n\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if transform is safe. */\n\treturn 1;\n}\n\nDUK_LOCAL void duk__transform_callback_encode_uri(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tduk_uint8_t xutf8_buf[DUK_UNICODE_MAX_XUTF8_LENGTH];\n\tduk_small_int_t len;\n\tduk_codepoint_t cp1, cp2;\n\tduk_small_int_t i, t;\n\tconst duk_uint8_t *unescaped_table = (const duk_uint8_t *) udata;\n\n\t/* UTF-8 encoded bytes escaped as %xx%xx%xx... -> 3 * nbytes.\n\t * Codepoint range is restricted so this is a slightly too large\n\t * but doesn't matter.\n\t */\n\tDUK_BW_ENSURE(tfm_ctx->thr, &tfm_ctx->bw, 3 * DUK_UNICODE_MAX_XUTF8_LENGTH);\n\n\tif (cp < 0) {\n\t\tgoto uri_error;\n\t} else if ((cp < 0x80L) && DUK__CHECK_BITMASK(unescaped_table, cp)) {\n\t\tDUK_BW_WRITE_RAW_U8(tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t) cp);\n\t\treturn;\n\t} else if (cp >= 0xdc00L && cp <= 0xdfffL) {\n\t\tgoto uri_error;\n\t} else if (cp >= 0xd800L && cp <= 0xdbffL) {\n\t\t/* Needs lookahead */\n\t\tif (duk_unicode_decode_xutf8(tfm_ctx->thr, &tfm_ctx->p, tfm_ctx->p_start, tfm_ctx->p_end, (duk_ucodepoint_t *) &cp2) == 0) {\n\t\t\tgoto uri_error;\n\t\t}\n\t\tif (!(cp2 >= 0xdc00L && cp2 <= 0xdfffL)) {\n\t\t\tgoto uri_error;\n\t\t}\n\t\tcp1 = cp;\n\t\tcp = (duk_codepoint_t) (((cp1 - 0xd800L) << 10) + (cp2 - 0xdc00L) + 0x10000L);\n\t} else if (cp > 0x10ffffL) {\n\t\t/* Although we can allow non-BMP characters (they'll decode\n\t\t * back into surrogate pairs), we don't allow extended UTF-8\n\t\t * characters; they would encode to URIs which won't decode\n\t\t * back because of strict UTF-8 checks in URI decoding.\n\t\t * (However, we could just as well allow them here.)\n\t\t */\n\t\tgoto uri_error;\n\t} else {\n\t\t/* Non-BMP characters within valid UTF-8 range: encode as is.\n\t\t * They'll decode back into surrogate pairs if the escaped\n\t\t * output is decoded.\n\t\t */\n\t\t;\n\t}\n\n\tlen = duk_unicode_encode_xutf8((duk_ucodepoint_t) cp, xutf8_buf);\n\tfor (i = 0; i < len; i++) {\n\t\tt = (duk_small_int_t) xutf8_buf[i];\n\t\tDUK_BW_WRITE_RAW_U8_3(tfm_ctx->thr,\n\t\t                      &tfm_ctx->bw,\n\t\t                      DUK_ASC_PERCENT,\n\t\t                      (duk_uint8_t) duk_uc_nybbles[t >> 4],\n                                      (duk_uint8_t) duk_uc_nybbles[t & 0x0f]);\n\t}\n\n\treturn;\n\n uri_error:\n\tDUK_ERROR_URI(tfm_ctx->thr, DUK_STR_INVALID_INPUT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__transform_callback_decode_uri(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tconst duk_uint8_t *reserved_table = (const duk_uint8_t *) udata;\n\tduk_small_uint_t utf8_blen;\n\tduk_codepoint_t min_cp;\n\tduk_small_int_t t;  /* must be signed */\n\tduk_small_uint_t i;\n\n\t/* Maximum write size: XUTF8 path writes max DUK_UNICODE_MAX_XUTF8_LENGTH,\n\t * percent escape path writes max two times CESU-8 encoded BMP length.\n\t */\n\tDUK_BW_ENSURE(tfm_ctx->thr,\n\t              &tfm_ctx->bw,\n\t              (DUK_UNICODE_MAX_XUTF8_LENGTH >= 2 * DUK_UNICODE_MAX_CESU8_BMP_LENGTH ?\n\t              DUK_UNICODE_MAX_XUTF8_LENGTH : DUK_UNICODE_MAX_CESU8_BMP_LENGTH));\n\n\tif (cp == (duk_codepoint_t) '%') {\n\t\tconst duk_uint8_t *p = tfm_ctx->p;\n\t\tduk_size_t left = (duk_size_t) (tfm_ctx->p_end - p);  /* bytes left */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"percent encoding, left=%ld\", (long) left));\n\n\t\tif (left < 2) {\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tt = duk__decode_hex_escape(p, 2);\n\t\tDUK_DDD(DUK_DDDPRINT(\"first byte: %ld\", (long) t));\n\t\tif (t < 0) {\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tif (t < 0x80) {\n\t\t\tif (DUK__CHECK_BITMASK(reserved_table, t)) {\n\t\t\t\t/* decode '%xx' to '%xx' if decoded char in reserved set */\n\t\t\t\tDUK_ASSERT(tfm_ctx->p - 1 >= tfm_ctx->p_start);\n\t\t\t\tDUK_BW_WRITE_RAW_U8_3(tfm_ctx->thr,\n\t\t\t\t                      &tfm_ctx->bw,\n\t\t\t\t                      DUK_ASC_PERCENT,\n\t\t\t\t                      p[0],\n\t\t\t\t                      p[1]);\n\t\t\t} else {\n\t\t\t\tDUK_BW_WRITE_RAW_U8(tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t) t);\n\t\t\t}\n\t\t\ttfm_ctx->p += 2;\n\t\t\treturn;\n\t\t}\n\n\t\t/* Decode UTF-8 codepoint from a sequence of hex escapes.  The\n\t\t * first byte of the sequence has been decoded to 't'.\n\t\t *\n\t\t * Note that UTF-8 validation must be strict according to the\n\t\t * specification: E5.1 Section 15.1.3, decode algorithm step\n\t\t * 4.d.vii.8.  URIError from non-shortest encodings is also\n\t\t * specifically noted in the spec.\n\t\t */\n\n\t\tDUK_ASSERT(t >= 0x80);\n\t\tif (t < 0xc0) {\n\t\t\t/* continuation byte */\n\t\t\tgoto uri_error;\n\t\t} else if (t < 0xe0) {\n\t\t\t/* 110x xxxx; 2 bytes */\n\t\t\tutf8_blen = 2;\n\t\t\tmin_cp = 0x80L;\n\t\t\tcp = t & 0x1f;\n\t\t} else if (t < 0xf0) {\n\t\t\t/* 1110 xxxx; 3 bytes */\n\t\t\tutf8_blen = 3;\n\t\t\tmin_cp = 0x800L;\n\t\t\tcp = t & 0x0f;\n\t\t} else if (t < 0xf8) {\n\t\t\t/* 1111 0xxx; 4 bytes */\n\t\t\tutf8_blen = 4;\n\t\t\tmin_cp = 0x10000L;\n\t\t\tcp = t & 0x07;\n\t\t} else {\n\t\t\t/* extended utf-8 not allowed for URIs */\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tif (left < utf8_blen * 3 - 1) {\n\t\t\t/* '%xx%xx...%xx', p points to char after first '%' */\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tp += 3;\n\t\tfor (i = 1; i < utf8_blen; i++) {\n\t\t\t/* p points to digit part ('%xy', p points to 'x') */\n\t\t\tt = duk__decode_hex_escape(p, 2);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"i=%ld utf8_blen=%ld cp=%ld t=0x%02lx\",\n\t\t\t                     (long) i, (long) utf8_blen, (long) cp, (unsigned long) t));\n\t\t\tif (t < 0) {\n\t\t\t\tgoto uri_error;\n\t\t\t}\n\t\t\tif ((t & 0xc0) != 0x80) {\n\t\t\t\tgoto uri_error;\n\t\t\t}\n\t\t\tcp = (cp << 6) + (t & 0x3f);\n\t\t\tp += 3;\n\t\t}\n\t\tp--;  /* p overshoots */\n\t\ttfm_ctx->p = p;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"final cp=%ld, min_cp=%ld\", (long) cp, (long) min_cp));\n\n\t\tif (cp < min_cp || cp > 0x10ffffL || (cp >= 0xd800L && cp <= 0xdfffL)) {\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\t/* The E5.1 algorithm checks whether or not a decoded codepoint\n\t\t * is below 0x80 and perhaps may be in the \"reserved\" set.\n\t\t * This seems pointless because the single byte UTF-8 case is\n\t\t * handled separately, and non-shortest encodings are rejected.\n\t\t * So, 'cp' cannot be below 0x80 here, and thus cannot be in\n\t\t * the reserved set.\n\t\t */\n\n\t\t/* utf-8 validation ensures these */\n\t\tDUK_ASSERT(cp >= 0x80L && cp <= 0x10ffffL);\n\n\t\tif (cp >= 0x10000L) {\n\t\t\tcp -= 0x10000L;\n\t\t\tDUK_ASSERT(cp < 0x100000L);\n\n\t\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, ((cp >> 10) + 0xd800L));\n\t\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, ((cp & 0x03ffL) + 0xdc00L));\n\t\t} else {\n\t\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp);\n\t\t}\n\t} else {\n\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp);\n\t}\n\treturn;\n\n uri_error:\n\tDUK_ERROR_URI(tfm_ctx->thr, DUK_STR_INVALID_INPUT);\n\tDUK_WO_NORETURN(return;);\n}\n\n#if defined(DUK_USE_SECTION_B)\nDUK_LOCAL void duk__transform_callback_escape(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tDUK_UNREF(udata);\n\n\tDUK_BW_ENSURE(tfm_ctx->thr, &tfm_ctx->bw, 6);\n\n\tif (cp < 0) {\n\t\tgoto esc_error;\n\t} else if ((cp < 0x80L) && DUK__CHECK_BITMASK(duk__escape_unescaped_table, cp)) {\n\t\tDUK_BW_WRITE_RAW_U8(tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t) cp);\n\t} else if (cp < 0x100L) {\n\t\tDUK_BW_WRITE_RAW_U8_3(tfm_ctx->thr,\n\t\t                      &tfm_ctx->bw,\n\t\t                      (duk_uint8_t) DUK_ASC_PERCENT,\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp >> 4],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp & 0x0f]);\n\t} else if (cp < 0x10000L) {\n\t\tDUK_BW_WRITE_RAW_U8_6(tfm_ctx->thr,\n\t\t                      &tfm_ctx->bw,\n\t\t                      (duk_uint8_t) DUK_ASC_PERCENT,\n\t\t                      (duk_uint8_t) DUK_ASC_LC_U,\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp >> 12],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[(cp >> 8) & 0x0f],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[(cp >> 4) & 0x0f],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp & 0x0f]);\n\t} else {\n\t\t/* Characters outside BMP cannot be escape()'d.  We could\n\t\t * encode them as surrogate pairs (for codepoints inside\n\t\t * valid UTF-8 range, but not extended UTF-8).  Because\n\t\t * escape() and unescape() are legacy functions, we don't.\n\t\t */\n\t\tgoto esc_error;\n\t}\n\n\treturn;\n\n esc_error:\n\tDUK_ERROR_TYPE(tfm_ctx->thr, DUK_STR_INVALID_INPUT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__transform_callback_unescape(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tduk_small_int_t t;\n\n\tDUK_UNREF(udata);\n\n\tif (cp == (duk_codepoint_t) '%') {\n\t\tconst duk_uint8_t *p = tfm_ctx->p;\n\t\tduk_size_t left = (duk_size_t) (tfm_ctx->p_end - p);  /* bytes left */\n\n\t\tif (left >= 5 && p[0] == 'u' &&\n\t\t    ((t = duk__decode_hex_escape(p + 1, 4)) >= 0)) {\n\t\t\tcp = (duk_codepoint_t) t;\n\t\t\ttfm_ctx->p += 5;\n\t\t} else if (left >= 2 &&\n\t\t           ((t = duk__decode_hex_escape(p, 2)) >= 0)) {\n\t\t\tcp = (duk_codepoint_t) t;\n\t\t\ttfm_ctx->p += 2;\n\t\t}\n\t}\n\n\tDUK_BW_WRITE_ENSURE_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp);\n}\n#endif  /* DUK_USE_SECTION_B */\n\n/*\n *  Eval\n *\n *  Eval needs to handle both a \"direct eval\" and an \"indirect eval\".\n *  Direct eval handling needs access to the caller's activation so that its\n *  lexical environment can be accessed.  A direct eval is only possible from\n *  ECMAScript code; an indirect eval call is possible also from C code.\n *  When an indirect eval call is made from C code, there may not be a\n *  calling activation at all which needs careful handling.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_activation *act_caller;\n\tduk_activation *act_eval;\n\tduk_hcompfunc *func;\n\tduk_hobject *outer_lex_env;\n\tduk_hobject *outer_var_env;\n\tduk_bool_t this_to_global = 1;\n\tduk_small_uint_t comp_flags;\n\tduk_int_t level = -2;\n\tduk_small_uint_t call_flags;\n\n\tDUK_ASSERT(duk_get_top(thr) == 1 || duk_get_top(thr) == 2);  /* 2 when called by debugger */\n\tDUK_ASSERT(thr->callstack_top >= 1);  /* at least this function exists */\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT((thr->callstack_curr->flags & DUK_ACT_FLAG_DIRECT_EVAL) == 0 || /* indirect eval */\n\t           (thr->callstack_top >= 2));  /* if direct eval, calling activation must exist */\n\n\t/*\n\t *  callstack_top - 1 --> this function\n\t *  callstack_top - 2 --> caller (may not exist)\n\t *\n\t *  If called directly from C, callstack_top might be 1.  If calling\n\t *  activation doesn't exist, call must be indirect.\n\t */\n\n\th = duk_get_hstring_notsymbol(thr, 0);\n\tif (!h) {\n\t\t/* Symbol must be returned as is, like any non-string values. */\n\t\treturn 1;  /* return arg as-is */\n\t}\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* NOTE: level is used only by the debugger and should never be present\n\t * for an ECMAScript eval().\n\t */\n\tDUK_ASSERT(level == -2);  /* by default, use caller's environment */\n\tif (duk_get_top(thr) >= 2 && duk_is_number(thr, 1)) {\n\t\tlevel = duk_get_int(thr, 1);\n\t}\n\tDUK_ASSERT(level <= -2);  /* This is guaranteed by debugger code. */\n#endif\n\n\t/* [ source ] */\n\n\tcomp_flags = DUK_COMPILE_EVAL;\n\tact_eval = thr->callstack_curr;  /* this function */\n\tDUK_ASSERT(act_eval != NULL);\n\tact_caller = duk_hthread_get_activation_for_level(thr, level);\n\tif (act_caller != NULL) {\n\t\t/* Have a calling activation, check for direct eval (otherwise\n\t\t * assume indirect eval.\n\t\t */\n\t\tif ((act_caller->flags & DUK_ACT_FLAG_STRICT) &&\n\t\t    (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL)) {\n\t\t\t/* Only direct eval inherits strictness from calling code\n\t\t\t * (E5.1 Section 10.1.1).\n\t\t\t */\n\t\t\tcomp_flags |= DUK_COMPILE_STRICT;\n\t\t}\n\t} else {\n\t\tDUK_ASSERT((act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) == 0);\n\t}\n\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_INPUT);  /* XXX: copy from caller? */\n\tduk_js_compile(thr,\n\t               (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h),\n\t               (duk_size_t) DUK_HSTRING_GET_BYTELEN(h),\n\t               comp_flags);\n\tfunc = (duk_hcompfunc *) duk_known_hobject(thr, -1);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) func));\n\n\t/* [ source template ] */\n\n\t/* E5 Section 10.4.2 */\n\n\tif (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) {\n\t\tDUK_ASSERT(thr->callstack_top >= 2);\n\t\tDUK_ASSERT(act_caller != NULL);\n\t\tif (act_caller->lex_env == NULL) {\n\t\t\tDUK_ASSERT(act_caller->var_env == NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"delayed environment initialization\"));\n\n\t\t\t/* this may have side effects, so re-lookup act */\n\t\t\tduk_js_init_activation_environment_records_delayed(thr, act_caller);\n\t\t}\n\t\tDUK_ASSERT(act_caller->lex_env != NULL);\n\t\tDUK_ASSERT(act_caller->var_env != NULL);\n\n\t\tthis_to_global = 0;\n\n\t\tif (DUK_HOBJECT_HAS_STRICT((duk_hobject *) func)) {\n\t\t\tduk_hdecenv *new_env;\n\t\t\tduk_hobject *act_lex_env;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"direct eval call to a strict function -> \"\n\t\t\t                     \"var_env and lex_env to a fresh env, \"\n\t\t\t                     \"this_binding to caller's this_binding\"));\n\n\t\t\tact_lex_env = act_caller->lex_env;\n\n\t\t\tnew_env = duk_hdecenv_alloc(thr,\n\t\t\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\t\t\tDUK_ASSERT(new_env != NULL);\n\t\t\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, act_lex_env);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, act_lex_env);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new_env allocated: %!iO\", (duk_heaphdr *) new_env));\n\n\t\t\touter_lex_env = (duk_hobject *) new_env;\n\t\t\touter_var_env = (duk_hobject *) new_env;\n\n\t\t\tduk_insert(thr, 0);  /* stash to bottom of value stack to keep new_env reachable for duration of eval */\n\n\t\t\t/* compiler's responsibility */\n\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV((duk_hobject *) func));\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"direct eval call to a non-strict function -> \"\n\t\t\t                     \"var_env and lex_env to caller's envs, \"\n\t\t\t                     \"this_binding to caller's this_binding\"));\n\n\t\t\touter_lex_env = act_caller->lex_env;\n\t\t\touter_var_env = act_caller->var_env;\n\n\t\t\t/* compiler's responsibility */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV((duk_hobject *) func));\n\t\t}\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"indirect eval call -> var_env and lex_env to \"\n\t\t                     \"global object, this_binding to global object\"));\n\n\t\tthis_to_global = 1;\n\t\touter_lex_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t\touter_var_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t}\n\n\t/* Eval code doesn't need an automatic .prototype object. */\n\tduk_js_push_closure(thr, func, outer_var_env, outer_lex_env, 0 /*add_auto_proto*/);\n\n\t/* [ env? source template closure ] */\n\n\tif (this_to_global) {\n\t\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\t\tduk_push_hobject_bidx(thr, DUK_BIDX_GLOBAL);\n\t} else {\n\t\tduk_tval *tv;\n\t\tDUK_ASSERT(thr->callstack_top >= 2);\n\t\tDUK_ASSERT(act_caller != NULL);\n\t\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act_caller->bottom_byteoff - sizeof(duk_tval));  /* this is just beneath bottom */\n\t\tDUK_ASSERT(tv >= thr->valstack);\n\t\tduk_push_tval(thr, tv);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"eval -> lex_env=%!iO, var_env=%!iO, this_binding=%!T\",\n\t                     (duk_heaphdr *) outer_lex_env,\n\t                     (duk_heaphdr *) outer_var_env,\n\t                     duk_get_tval(thr, -1)));\n\n\t/* [ env? source template closure this ] */\n\n\tcall_flags = 0;\n\tif (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) {\n\t\t/* Set DIRECT_EVAL flag for the call; it's not strictly\n\t\t * needed for the 'inner' eval call (the eval body) but\n\t\t * current new.target implementation expects to find it\n\t\t * so it can traverse direct eval chains up to the real\n\t\t * calling function.\n\t\t */\n\t\tcall_flags |= DUK_CALL_FLAG_DIRECT_EVAL;\n\t}\n\tduk_handle_call_unprotected_nargs(thr, 0, call_flags);\n\n\t/* [ env? source template result ] */\n\n\treturn 1;\n}\n\n/*\n *  Parsing of ints and floats\n */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_parse_int(duk_hthread *thr) {\n\tduk_int32_t radix;\n\tduk_small_uint_t s2n_flags;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, 0);  /* Reject symbols. */\n\n\tradix = duk_to_int32(thr, 1);\n\n\t/* While parseInt() recognizes 0xdeadbeef, it doesn't recognize\n\t * ES2015 0o123 or 0b10001.\n\t */\n\ts2n_flags = DUK_S2N_FLAG_TRIM_WHITE |\n\t            DUK_S2N_FLAG_ALLOW_GARBAGE |\n\t            DUK_S2N_FLAG_ALLOW_PLUS |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |\n\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT;\n\n\t/* Specification stripPrefix maps to DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT.\n\t *\n\t * Don't autodetect octals (from leading zeroes), require user code to\n\t * provide an explicit radix 8 for parsing octal.  See write-up from Mozilla:\n\t * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt#ECMAScript_5_Removes_Octal_Interpretation\n\t */\n\n\tif (radix != 0) {\n\t\tif (radix < 2 || radix > 36) {\n\t\t\tgoto ret_nan;\n\t\t}\n\t\tif (radix != 16) {\n\t\t\ts2n_flags &= ~DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT;\n\t\t}\n\t} else {\n\t\tradix = 10;\n\t}\n\n\tduk_dup_0(thr);\n\tduk_numconv_parse(thr, (duk_small_int_t) radix, s2n_flags);\n\treturn 1;\n\n ret_nan:\n\tduk_push_nan(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_parse_float(duk_hthread *thr) {\n\tduk_small_uint_t s2n_flags;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\tduk_to_string(thr, 0);  /* Reject symbols. */\n\n\t/* XXX: check flags */\n\ts2n_flags = DUK_S2N_FLAG_TRIM_WHITE |\n\t            DUK_S2N_FLAG_ALLOW_EXP |\n\t            DUK_S2N_FLAG_ALLOW_GARBAGE |\n\t            DUK_S2N_FLAG_ALLOW_PLUS |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |\n\t            DUK_S2N_FLAG_ALLOW_INF |\n\t            DUK_S2N_FLAG_ALLOW_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO;\n\n\tduk_numconv_parse(thr, 10 /*radix*/, s2n_flags);\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n/*\n *  Number checkers\n */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_is_nan(duk_hthread *thr) {\n\tduk_double_t d = duk_to_number(thr, 0);\n\tduk_push_boolean(thr, (duk_bool_t) DUK_ISNAN(d));\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_is_finite(duk_hthread *thr) {\n\tduk_double_t d = duk_to_number(thr, 0);\n\tduk_push_boolean(thr, (duk_bool_t) DUK_ISFINITE(d));\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n/*\n *  URI handling\n */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_decode_uri(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_decode_uri, (const void *) duk__decode_uri_reserved_table);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_decode_uri_component(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_decode_uri, (const void *) duk__decode_uri_component_reserved_table);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_encode_uri(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_encode_uri, (const void *) duk__encode_uriunescaped_table);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_encode_uri_component(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_encode_uri, (const void *) duk__encode_uricomponent_unescaped_table);\n}\n\n#if defined(DUK_USE_SECTION_B)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_escape(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_escape, (const void *) NULL);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_unescape(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_unescape, (const void *) NULL);\n}\n#endif  /* DUK_USE_SECTION_B */\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_json.c",
    "content": "/*\n *  JSON built-ins.\n *\n *  See doc/json.rst.\n *\n *  Codepoints are handled as duk_uint_fast32_t to ensure that the full\n *  unsigned 32-bit range is supported.  This matters to e.g. JX.\n *\n *  Input parsing doesn't do an explicit end-of-input check at all.  This is\n *  safe: input string data is always NUL-terminated (0x00) and valid JSON\n *  inputs never contain plain NUL characters, so that as long as syntax checks\n *  are correct, we'll never read past the NUL.  This approach reduces code size\n *  and improves parsing performance, but it's critical that syntax checks are\n *  indeed correct!\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_JSON_SUPPORT)\n\n/*\n *  Local defines and forward declarations.\n */\n\n#define DUK__JSON_DECSTR_BUFSIZE 128\n#define DUK__JSON_DECSTR_CHUNKSIZE 64\n#define DUK__JSON_ENCSTR_CHUNKSIZE 64\n#define DUK__JSON_STRINGIFY_BUFSIZE 128\n#define DUK__JSON_MAX_ESC_LEN 10  /* '\\Udeadbeef' */\n\nDUK_LOCAL_DECL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx);\n#if defined(DUK_USE_JX)\nDUK_LOCAL_DECL duk_uint8_t duk__dec_peek(duk_json_dec_ctx *js_ctx);\n#endif\nDUK_LOCAL_DECL duk_uint8_t duk__dec_get(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL duk_uint8_t duk__dec_get_nonwhite(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n);\nDUK_LOCAL_DECL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx);\nDUK_LOCAL_DECL void duk__dec_string(duk_json_dec_ctx *js_ctx);\n#if defined(DUK_USE_JX)\nDUK_LOCAL_DECL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_pointer(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_buffer(duk_json_dec_ctx *js_ctx);\n#endif\nDUK_LOCAL_DECL void duk__dec_number(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_object(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_array(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_value(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx);\n\nDUK_LOCAL_DECL void duk__emit_1(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch);\nDUK_LOCAL_DECL void duk__emit_2(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch1, duk_uint_fast8_t ch2);\nDUK_LOCAL_DECL void duk__unemit_1(duk_json_enc_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__emit_hstring(duk_json_enc_ctx *js_ctx, duk_hstring *h);\n#if defined(DUK_USE_FASTINT)\nDUK_LOCAL_DECL void duk__emit_cstring(duk_json_enc_ctx *js_ctx, const char *p);\n#endif\nDUK_LOCAL_DECL void duk__emit_stridx(duk_json_enc_ctx *js_ctx, duk_small_uint_t stridx);\nDUK_LOCAL_DECL duk_uint8_t *duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uint_fast32_t cp, duk_uint8_t *q);\nDUK_LOCAL_DECL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k);\nDUK_LOCAL_DECL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str);\nDUK_LOCAL_DECL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top);\nDUK_LOCAL_DECL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top);\nDUK_LOCAL_DECL void duk__enc_object(duk_json_enc_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__enc_array(duk_json_enc_ctx *js_ctx);\nDUK_LOCAL_DECL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder);\nDUK_LOCAL_DECL duk_bool_t duk__enc_allow_into_proplist(duk_tval *tv);\nDUK_LOCAL_DECL void duk__enc_double(duk_json_enc_ctx *js_ctx);\n#if defined(DUK_USE_FASTINT)\nDUK_LOCAL_DECL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv);\n#endif\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL_DECL void duk__enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h);\nDUK_LOCAL_DECL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL_DECL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj);\n#endif\n#endif\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\nDUK_LOCAL_DECL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h);\n#endif\nDUK_LOCAL_DECL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth);\n\n/*\n *  Helper tables\n */\n\n#if defined(DUK_USE_JSON_QUOTESTRING_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_quotestr_lookup[256] = {\n\t/* 0x00 ... 0x7f: as is\n\t * 0x80: escape generically\n\t * 0x81: slow path\n\t * 0xa0 ... 0xff: backslash + one char\n\t */\n\n\t0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xe2, 0xf4, 0xee, 0x80, 0xe6, 0xf2, 0x80, 0x80,\n\t0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,\n\t0x20, 0x21, 0xa2, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,\n\t0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,\n\t0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,\n\t0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0xdc, 0x5d, 0x5e, 0x5f,\n\t0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81\n};\n#else  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\nDUK_LOCAL const duk_uint8_t duk__json_quotestr_esc[14] = {\n\tDUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL,\n\tDUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL,\n\tDUK_ASC_LC_B, DUK_ASC_LC_T, DUK_ASC_LC_N, DUK_ASC_NUL,\n\tDUK_ASC_LC_F, DUK_ASC_LC_R\n};\n#endif  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\n\n#if defined(DUK_USE_JSON_DECSTRING_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_decstr_lookup[256] = {\n\t/* 0x00: slow path\n\t * other: as is\n\t */\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x20, 0x21, 0x00, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,\n\t0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,\n\t0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,\n\t0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x00, 0x5d, 0x5e, 0x5f,\n\t0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,\n\t0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,\n\t0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,\n\t0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,\n\t0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,\n\t0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,\n\t0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,\n\t0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,\n\t0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff\n};\n#endif  /* DUK_USE_JSON_DECSTRING_FASTPATH */\n\n#if defined(DUK_USE_JSON_EATWHITE_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_eatwhite_lookup[256] = {\n\t/* 0x00: finish (non-white)\n\t * 0x01: continue\n\t */\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\n#endif  /* DUK_USE_JSON_EATWHITE_FASTPATH */\n\n#if defined(DUK_USE_JSON_DECNUMBER_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_decnumber_lookup[256] = {\n\t/* 0x00: finish (not part of number)\n\t * 0x01: continue\n\t */\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00,\n\t0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\n#endif  /* DUK_USE_JSON_DECNUMBER_FASTPATH */\n\n/*\n *  Parsing implementation.\n *\n *  JSON lexer is now separate from duk_lexer.c because there are numerous\n *  small differences making it difficult to share the lexer.\n *\n *  The parser here works with raw bytes directly; this works because all\n *  JSON delimiters are ASCII characters.  Invalid xUTF-8 encoded values\n *  inside strings will be passed on without normalization; this is not a\n *  compliance concern because compliant inputs will always be valid\n *  CESU-8 encodings.\n */\n\nDUK_LOCAL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx) {\n\t/* Shared handler to minimize parser size.  Cause will be\n\t * hidden, unfortunately, but we'll have an offset which\n\t * is often quite enough.\n\t */\n\tDUK_ERROR_FMT1(js_ctx->thr, DUK_ERR_SYNTAX_ERROR, DUK_STR_FMT_INVALID_JSON,\n\t               (long) (js_ctx->p - js_ctx->p_start));\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx) {\n\tconst duk_uint8_t *p;\n\tduk_uint8_t t;\n\n\tp = js_ctx->p;\n\tfor (;;) {\n\t\tDUK_ASSERT(p <= js_ctx->p_end);\n\t\tt = *p;\n\n#if defined(DUK_USE_JSON_EATWHITE_FASTPATH)\n\t\t/* This fast path is pretty marginal in practice.\n\t\t * XXX: candidate for removal.\n\t\t */\n\t\tDUK_ASSERT(duk__json_eatwhite_lookup[0x00] == 0x00);  /* end-of-input breaks */\n\t\tif (duk__json_eatwhite_lookup[t] == 0) {\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_JSON_EATWHITE_FASTPATH */\n\t\tif (!(t == 0x20 || t == 0x0a || t == 0x0d || t == 0x09)) {\n\t\t\t/* NUL also comes here.  Comparison order matters, 0x20\n\t\t\t * is most common whitespace.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_JSON_EATWHITE_FASTPATH */\n\t\tp++;\n\t}\n\tjs_ctx->p = p;\n}\n\n#if defined(DUK_USE_JX)\nDUK_LOCAL duk_uint8_t duk__dec_peek(duk_json_dec_ctx *js_ctx) {\n\tDUK_ASSERT(js_ctx->p <= js_ctx->p_end);\n\treturn *js_ctx->p;\n}\n#endif\n\nDUK_LOCAL duk_uint8_t duk__dec_get(duk_json_dec_ctx *js_ctx) {\n\tDUK_ASSERT(js_ctx->p <= js_ctx->p_end);\n\treturn *js_ctx->p++;\n}\n\nDUK_LOCAL duk_uint8_t duk__dec_get_nonwhite(duk_json_dec_ctx *js_ctx) {\n\tduk__dec_eat_white(js_ctx);\n\treturn duk__dec_get(js_ctx);\n}\n\n/* For JX, expressing the whole unsigned 32-bit range matters. */\nDUK_LOCAL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n) {\n\tduk_small_uint_t i;\n\tduk_uint_fast32_t res = 0;\n\tduk_uint8_t x;\n\tduk_small_int_t t;\n\n\tfor (i = 0; i < n; i++) {\n\t\t/* XXX: share helper from lexer; duk_lexer.c / hexval(). */\n\n\t\tx = duk__dec_get(js_ctx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"decode_hex_escape: i=%ld, n=%ld, res=%ld, x=%ld\",\n\t\t                     (long) i, (long) n, (long) res, (long) x));\n\n\t\t/* x == 0x00 (EOF) causes syntax_error */\n\t\tDUK_ASSERT(duk_hex_dectab[0] == -1);\n\t\tt = duk_hex_dectab[x & 0xff];\n\t\tif (DUK_LIKELY(t >= 0)) {\n\t\t\tres = (res * 16) + (duk_uint_fast32_t) t;\n\t\t} else {\n\t\t\t/* catches EOF and invalid digits */\n\t\t\tgoto syntax_error;\n\t\t}\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"final hex decoded value: %ld\", (long) res));\n\treturn res;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n\treturn 0;\n}\n\nDUK_LOCAL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t x, y;\n\n\t/* First character has already been eaten and checked by the caller.\n\t * We can scan until a NUL in stridx string because no built-in strings\n\t * have internal NULs.\n\t */\n\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\th = DUK_HTHREAD_GET_STRING(js_ctx->thr, stridx);\n\tDUK_ASSERT(h != NULL);\n\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h) + 1;\n\tDUK_ASSERT(*(js_ctx->p - 1) == *(p - 1));  /* first character has been matched */\n\n\tfor (;;) {\n\t\tx = *p;\n\t\tif (x == 0) {\n\t\t\tbreak;\n\t\t}\n\t\ty = duk__dec_get(js_ctx);\n\t\tif (x != y) {\n\t\t\t/* Catches EOF of JSON input. */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\tp++;\n\t}\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\nDUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_uint8_t **ext_p) {\n\tduk_uint_fast32_t cp;\n\n\t/* EOF (-1) will be cast to an unsigned value first\n\t * and then re-cast for the switch.  In any case, it\n\t * will match the default case (syntax error).\n\t */\n\tcp = (duk_uint_fast32_t) duk__dec_get(js_ctx);\n\tswitch (cp) {\n\tcase DUK_ASC_BACKSLASH: break;\n\tcase DUK_ASC_DOUBLEQUOTE: break;\n\tcase DUK_ASC_SLASH: break;\n\tcase DUK_ASC_LC_T: cp = 0x09; break;\n\tcase DUK_ASC_LC_N: cp = 0x0a; break;\n\tcase DUK_ASC_LC_R: cp = 0x0d; break;\n\tcase DUK_ASC_LC_F: cp = 0x0c; break;\n\tcase DUK_ASC_LC_B: cp = 0x08; break;\n\tcase DUK_ASC_LC_U: {\n\t\tcp = duk__dec_decode_hex_escape(js_ctx, 4);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_JX)\n\tcase DUK_ASC_UC_U: {\n\t\tif (js_ctx->flag_ext_custom) {\n\t\t\tcp = duk__dec_decode_hex_escape(js_ctx, 8);\n\t\t} else {\n\t\t\treturn 1;  /* syntax error */\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LC_X: {\n\t\tif (js_ctx->flag_ext_custom) {\n\t\t\tcp = duk__dec_decode_hex_escape(js_ctx, 2);\n\t\t} else {\n\t\t\treturn 1;  /* syntax error */\n\t\t}\n\t\tbreak;\n\t}\n#endif  /* DUK_USE_JX */\n\tdefault:\n\t\t/* catches EOF (0x00) */\n\t\treturn 1;  /* syntax error */\n\t}\n\n\tDUK_RAW_WRITE_XUTF8(*ext_p, cp);\n\n\treturn 0;\n}\n\nDUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tduk_uint8_t *q;\n\n\t/* '\"' was eaten by caller */\n\n\t/* Note that we currently parse -bytes-, not codepoints.\n\t * All non-ASCII extended UTF-8 will encode to bytes >= 0x80,\n\t * so they'll simply pass through (valid UTF-8 or not).\n\t */\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(js_ctx->thr, bw, DUK__JSON_DECSTR_BUFSIZE);\n\tq = DUK_BW_GET_PTR(js_ctx->thr, bw);\n\n#if defined(DUK_USE_JSON_DECSTRING_FASTPATH)\n\tfor (;;) {\n\t\tduk_small_uint_t safe;\n\t\tduk_uint8_t b, x;\n\t\tconst duk_uint8_t *p;\n\n\t\t/* Select a safe loop count where no output checks are\n\t\t * needed assuming we won't encounter escapes.  Input\n\t\t * bound checks are not necessary as a NUL (guaranteed)\n\t\t * will cause a SyntaxError before we read out of bounds.\n\t\t */\n\n\t\tsafe = DUK__JSON_DECSTR_CHUNKSIZE;\n\n\t\t/* Ensure space for 1:1 output plus one escape. */\n\t\tq = DUK_BW_ENSURE_RAW(js_ctx->thr, bw, safe + DUK_UNICODE_MAX_XUTF8_LENGTH, q);\n\n\t\tp = js_ctx->p;  /* temp copy, write back for next loop */\n\t\tfor (;;) {\n\t\t\tif (safe == 0) {\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tsafe--;\n\n\t\t\t/* End of input (NUL) goes through slow path and causes SyntaxError. */\n\t\t\tDUK_ASSERT(duk__json_decstr_lookup[0] == 0x00);\n\n\t\t\tb = *p++;\n\t\t\tx = (duk_small_int_t) duk__json_decstr_lookup[b];\n\t\t\tif (DUK_LIKELY(x != 0)) {\n\t\t\t\t/* Fast path, decode as is. */\n\t\t\t\t*q++ = b;\n\t\t\t} else if (b == DUK_ASC_DOUBLEQUOTE) {\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tgoto found_quote;\n\t\t\t} else if (b == DUK_ASC_BACKSLASH) {\n\t\t\t\t/* We've ensured space for one escaped input; then\n\t\t\t\t * bail out and recheck (this makes escape handling\n\t\t\t\t * quite slow but it's uncommon).\n\t\t\t\t */\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tif (duk__dec_string_escape(js_ctx, &q) != 0) {\n\t\t\t\t\tgoto syntax_error;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t}\n\t}\n found_quote:\n#else  /* DUK_USE_JSON_DECSTRING_FASTPATH */\n\tfor (;;) {\n\t\tduk_uint8_t x;\n\n\t\tq = DUK_BW_ENSURE_RAW(js_ctx->thr, bw, DUK_UNICODE_MAX_XUTF8_LENGTH, q);\n\n\t\tx = duk__dec_get(js_ctx);\n\n\t\tif (x == DUK_ASC_DOUBLEQUOTE) {\n\t\t\tbreak;\n\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\tif (duk__dec_string_escape(js_ctx, &q) != 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t} else if (x < 0x20) {\n\t\t\t/* catches EOF (NUL) */\n\t\t\tgoto syntax_error;\n\t\t} else {\n\t\t\t*q++ = (duk_uint8_t) x;\n\t\t}\n\t}\n#endif  /* DUK_USE_JSON_DECSTRING_FASTPATH */\n\n\tDUK_BW_SETPTR_AND_COMPACT(js_ctx->thr, bw, q);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if input string is safe. */\n\n\t/* [ ... str ] */\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\n#if defined(DUK_USE_JX)\n/* Decode a plain string consisting entirely of identifier characters.\n * Used to parse plain keys (e.g. \"foo: 123\").\n */\nDUK_LOCAL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p;\n\tduk_small_int_t x;\n\n\t/* Caller has already eaten the first char so backtrack one byte. */\n\n\tjs_ctx->p--;  /* safe */\n\tp = js_ctx->p;\n\n\t/* Here again we parse bytes, and non-ASCII UTF-8 will cause end of\n\t * parsing (which is correct except if there are non-shortest encodings).\n\t * There is also no need to check explicitly for end of input buffer as\n\t * the input is NUL padded and NUL will exit the parsing loop.\n\t *\n\t * Because no unescaping takes place, we can just scan to the end of the\n\t * plain string and intern from the input buffer.\n\t */\n\n\tfor (;;) {\n\t\tx = *p;\n\n\t\t/* There is no need to check the first character specially here\n\t\t * (i.e. reject digits): the caller only accepts valid initial\n\t\t * characters and won't call us if the first character is a digit.\n\t\t * This also ensures that the plain string won't be empty.\n\t\t */\n\n\t\tif (!duk_unicode_is_identifier_part((duk_codepoint_t) x)) {\n\t\t\tbreak;\n\t\t}\n\t\tp++;\n\t}\n\n\tduk_push_lstring(thr, (const char *) js_ctx->p, (duk_size_t) (p - js_ctx->p));\n\tjs_ctx->p = p;\n\n\t/* [ ... str ] */\n}\n#endif  /* DUK_USE_JX */\n\n#if defined(DUK_USE_JX)\nDUK_LOCAL void duk__dec_pointer(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p;\n\tduk_small_int_t x;\n\tvoid *voidptr;\n\n\t/* Caller has already eaten the first character ('(') which we don't need. */\n\n\tp = js_ctx->p;\n\n\tfor (;;) {\n\t\tx = *p;\n\n\t\t/* Assume that the native representation never contains a closing\n\t\t * parenthesis.\n\t\t */\n\n\t\tif (x == DUK_ASC_RPAREN) {\n\t\t\tbreak;\n\t\t} else if (x <= 0) {\n\t\t\t/* NUL term or -1 (EOF), NUL check would suffice */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\tp++;\n\t}\n\n\t/* There is no need to NUL delimit the sscanf() call: trailing garbage is\n\t * ignored and there is always a NUL terminator which will force an error\n\t * if no error is encountered before it.  It's possible that the scan\n\t * would scan further than between [js_ctx->p,p[ though and we'd advance\n\t * by less than the scanned value.\n\t *\n\t * Because pointers are platform specific, a failure to scan a pointer\n\t * results in a null pointer which is a better placeholder than a missing\n\t * value or an error.\n\t */\n\n\tvoidptr = NULL;\n\t(void) DUK_SSCANF((const char *) js_ctx->p, DUK_STR_FMT_PTR, &voidptr);\n\tduk_push_pointer(thr, voidptr);\n\tjs_ctx->p = p + 1;  /* skip ')' */\n\n\t/* [ ... ptr ] */\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n#endif  /* DUK_USE_JX */\n\n#if defined(DUK_USE_JX)\nDUK_LOCAL void duk__dec_buffer(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t *buf;\n\tduk_size_t src_len;\n\tduk_small_int_t x;\n\n\t/* Caller has already eaten the first character ('|') which we don't need. */\n\n\tp = js_ctx->p;\n\n\t/* XXX: Would be nice to share the fast path loop from duk_hex_decode()\n\t * and avoid creating a temporary buffer.  However, there are some\n\t * differences which prevent trivial sharing:\n\t *\n\t *   - Pipe char detection\n\t *   - EOF detection\n\t *   - Unknown length of input and output\n\t *\n\t * The best approach here would be a bufwriter and a reasonaly sized\n\t * safe inner loop (e.g. 64 output bytes at a time).\n\t */\n\n\tfor (;;) {\n\t\tx = *p;\n\n\t\t/* This loop intentionally does not ensure characters are valid\n\t\t * ([0-9a-fA-F]) because the hex decode call below will do that.\n\t\t */\n\t\tif (x == DUK_ASC_PIPE) {\n\t\t\tbreak;\n\t\t} else if (x <= 0) {\n\t\t\t/* NUL term or -1 (EOF), NUL check would suffice */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\tp++;\n\t}\n\n\t/* XXX: this is not very nice; unnecessary copy is made. */\n\tsrc_len = (duk_size_t) (p - js_ctx->p);\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, src_len);\n\tDUK_ASSERT(buf != NULL);\n\tduk_memcpy((void *) buf, (const void *) js_ctx->p, src_len);\n\tduk_hex_decode(thr, -1);\n\n\tjs_ctx->p = p + 1;  /* skip '|' */\n\n\t/* [ ... buf ] */\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n#endif  /* DUK_USE_JX */\n\n/* Parse a number, other than NaN or +/- Infinity */\nDUK_LOCAL void duk__dec_number(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t x;\n\tduk_small_uint_t s2n_flags;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_number\"));\n\n\tp_start = js_ctx->p;\n\n\t/* First pass parse is very lenient (e.g. allows '1.2.3') and extracts a\n\t * string for strict number parsing.\n\t */\n\n\tp = js_ctx->p;\n\tfor (;;) {\n\t\tx = *p;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse_number: p_start=%p, p=%p, p_end=%p, x=%ld\",\n\t\t                     (const void *) p_start, (const void *) p,\n\t\t                     (const void *) js_ctx->p_end, (long) x));\n\n#if defined(DUK_USE_JSON_DECNUMBER_FASTPATH)\n\t\t/* This fast path is pretty marginal in practice.\n\t\t * XXX: candidate for removal.\n\t\t */\n\t\tDUK_ASSERT(duk__json_decnumber_lookup[0x00] == 0x00);  /* end-of-input breaks */\n\t\tif (duk__json_decnumber_lookup[x] == 0) {\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_JSON_DECNUMBER_FASTPATH */\n\t\tif (!((x >= DUK_ASC_0 && x <= DUK_ASC_9) ||\n\t\t      (x == DUK_ASC_PERIOD || x == DUK_ASC_LC_E ||\n\t\t       x == DUK_ASC_UC_E || x == DUK_ASC_MINUS || x == DUK_ASC_PLUS))) {\n\t\t\t/* Plus sign must be accepted for positive exponents\n\t\t\t * (e.g. '1.5e+2').  This clause catches NULs.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_JSON_DECNUMBER_FASTPATH */\n\t\tp++;  /* safe, because matched (NUL causes a break) */\n\t}\n\tjs_ctx->p = p;\n\n\tDUK_ASSERT(js_ctx->p > p_start);\n\tduk_push_lstring(thr, (const char *) p_start, (duk_size_t) (p - p_start));\n\n\ts2n_flags = DUK_S2N_FLAG_ALLOW_EXP |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |  /* but don't allow leading plus */\n\t            DUK_S2N_FLAG_ALLOW_FRAC;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_number: string before parsing: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_numconv_parse(thr, 10 /*radix*/, s2n_flags);\n\tif (duk_is_nan(thr, -1)) {\n\t\tduk__dec_syntax_error(js_ctx);\n\t}\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\tDUK_DDD(DUK_DDDPRINT(\"parse_number: final number: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* [ ... num ] */\n}\n\nDUK_LOCAL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_require_stack(thr, DUK_JSON_DEC_REQSTACK);\n\n\t/* c recursion check */\n\n\tDUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0);  /* unsigned */\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tif (js_ctx->recursion_depth >= js_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_JSONDEC_RECLIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tjs_ctx->recursion_depth++;\n}\n\nDUK_LOCAL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx) {\n\t/* c recursion check */\n\n\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tjs_ctx->recursion_depth--;\n}\n\nDUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_int_t key_count;  /* XXX: a \"first\" flag would suffice */\n\tduk_uint8_t x;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_object\"));\n\n\tduk__dec_objarr_entry(js_ctx);\n\n\tduk_push_object(thr);\n\n\t/* Initial '{' has been checked and eaten by caller. */\n\n\tkey_count = 0;\n\tfor (;;) {\n\t\tx = duk__dec_get_nonwhite(js_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse_object: obj=%!T, x=%ld, key_count=%ld\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t\t                     (long) x, (long) key_count));\n\n\t\t/* handle comma and closing brace */\n\n\t\tif (x == DUK_ASC_COMMA && key_count > 0) {\n\t\t\t/* accept comma, expect new value */\n\t\t\tx = duk__dec_get_nonwhite(js_ctx);\n\t\t} else if (x == DUK_ASC_RCURLY) {\n\t\t\t/* eat closing brace */\n\t\t\tbreak;\n\t\t} else if (key_count == 0) {\n\t\t\t/* accept anything, expect first value (EOF will be\n\t\t\t * caught by key parsing below.\n\t\t\t */\n\t\t\t;\n\t\t} else {\n\t\t\t/* catches EOF (NUL) and initial comma */\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/* parse key and value */\n\n\t\tif (x == DUK_ASC_DOUBLEQUOTE) {\n\t\t\tduk__dec_string(js_ctx);\n#if defined(DUK_USE_JX)\n\t\t} else if (js_ctx->flag_ext_custom &&\n\t\t           duk_unicode_is_identifier_start((duk_codepoint_t) x)) {\n\t\t\tduk__dec_plain_string(js_ctx);\n#endif\n\t\t} else {\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/* [ ... obj key ] */\n\n\t\tx = duk__dec_get_nonwhite(js_ctx);\n\t\tif (x != DUK_ASC_COLON) {\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\tduk__dec_value(js_ctx);\n\n\t\t/* [ ... obj key val ] */\n\n\t\tduk_xdef_prop_wec(thr, -3);\n\n\t\t/* [ ... obj ] */\n\n\t\tkey_count++;\n\t}\n\n\t/* [ ... obj ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_object: final object is %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__dec_objarr_exit(js_ctx);\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\nDUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_uarridx_t arr_idx;\n\tduk_uint8_t x;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_array\"));\n\n\tduk__dec_objarr_entry(js_ctx);\n\n\tduk_push_array(thr);\n\n\t/* Initial '[' has been checked and eaten by caller. */\n\n\tarr_idx = 0;\n\tfor (;;) {\n\t\tx = duk__dec_get_nonwhite(js_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse_array: arr=%!T, x=%ld, arr_idx=%ld\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t\t                     (long) x, (long) arr_idx));\n\n\t\t/* handle comma and closing bracket */\n\n\t\tif ((x == DUK_ASC_COMMA) && (arr_idx != 0)) {\n\t\t\t/* accept comma, expect new value */\n\t\t\t;\n\t\t} else if (x == DUK_ASC_RBRACKET) {\n\t\t\t/* eat closing bracket */\n\t\t\tbreak;\n\t\t} else if (arr_idx == 0) {\n\t\t\t/* accept anything, expect first value (EOF will be\n\t\t\t * caught by duk__dec_value() below.\n\t\t\t */\n\t\t\tjs_ctx->p--;  /* backtrack (safe) */\n\t\t} else {\n\t\t\t/* catches EOF (NUL) and initial comma */\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/* parse value */\n\n\t\tduk__dec_value(js_ctx);\n\n\t\t/* [ ... arr val ] */\n\n\t\tduk_xdef_prop_index_wec(thr, -2, arr_idx);\n\t\tarr_idx++;\n\t}\n\n\t/* Must set 'length' explicitly when using duk_xdef_prop_xxx() to\n\t * set the values.\n\t */\n\n\tduk_set_length(thr, -1, arr_idx);\n\n\t/* [ ... arr ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_array: final array is %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__dec_objarr_exit(js_ctx);\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\nDUK_LOCAL void duk__dec_value(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_uint8_t x;\n\n\tx = duk__dec_get_nonwhite(js_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_value: initial x=%ld\", (long) x));\n\n\t/* Note: duk__dec_req_stridx() backtracks one char */\n\n\tif (x == DUK_ASC_DOUBLEQUOTE) {\n\t\tduk__dec_string(js_ctx);\n\t} else if ((x >= DUK_ASC_0 && x <= DUK_ASC_9) || (x == DUK_ASC_MINUS)) {\n#if defined(DUK_USE_JX)\n\t\tif (js_ctx->flag_ext_custom && x == DUK_ASC_MINUS && duk__dec_peek(js_ctx) == DUK_ASC_UC_I) {\n\t\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_MINUS_INFINITY);  /* \"-Infinity\", '-' has been eaten */\n\t\t\tduk_push_number(thr, -DUK_DOUBLE_INFINITY);\n\t\t} else {\n#else\n\t\t{  /* unconditional block */\n#endif\n\t\t\t/* We already ate 'x', so backup one byte. */\n\t\t\tjs_ctx->p--;  /* safe */\n\t\t\tduk__dec_number(js_ctx);\n\t\t}\n\t} else if (x == DUK_ASC_LC_T) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_TRUE);\n\t\tduk_push_true(thr);\n\t} else if (x == DUK_ASC_LC_F) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_FALSE);\n\t\tduk_push_false(thr);\n\t} else if (x == DUK_ASC_LC_N) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_NULL);\n\t\tduk_push_null(thr);\n#if defined(DUK_USE_JX)\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_LC_U) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_UNDEFINED);\n\t\tduk_push_undefined(thr);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_N) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_NAN);\n\t\tduk_push_nan(thr);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_I) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_INFINITY);\n\t\tduk_push_number(thr, DUK_DOUBLE_INFINITY);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_LPAREN) {\n\t\tduk__dec_pointer(js_ctx);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_PIPE) {\n\t\tduk__dec_buffer(js_ctx);\n#endif\n\t} else if (x == DUK_ASC_LCURLY) {\n\t\tduk__dec_object(js_ctx);\n\t} else if (x == DUK_ASC_LBRACKET) {\n\t\tduk__dec_array(js_ctx);\n\t} else {\n\t\t/* catches EOF (NUL) */\n\t\tgoto syntax_error;\n\t}\n\n\tduk__dec_eat_white(js_ctx);\n\n\t/* [ ... val ] */\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\n/* Recursive value reviver, implements the Walk() algorithm.  No C recursion\n * check is done here because the initial parsing step will already ensure\n * there is a reasonable limit on C recursion depth and hence object depth.\n */\nDUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hobject *h;\n\tduk_uarridx_t i, arr_len;\n\n\tDUK_DDD(DUK_DDDPRINT(\"walk: top=%ld, holder=%!T, name=%!T\",\n\t                     (long) duk_get_top(thr),\n\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk_dup_top(thr);\n\tduk_get_prop(thr, -3);  /* -> [ ... holder name val ] */\n\n\th = duk_get_hobject(thr, -1);\n\tif (h != NULL) {\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tarr_len = (duk_uarridx_t) duk_get_length(thr, -1);\n\t\t\tfor (i = 0; i < arr_len; i++) {\n\t\t\t\t/* [ ... holder name val ] */\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"walk: array, top=%ld, i=%ld, arr_len=%ld, holder=%!T, name=%!T, val=%!T\",\n\t\t\t\t                     (long) duk_get_top(thr), (long) i, (long) arr_len,\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -3), (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t\tduk_dup_top(thr);\n\t\t\t\t(void) duk_push_uint_to_hstring(thr, (duk_uint_t) i);  /* -> [ ... holder name val val ToString(i) ] */\n\t\t\t\tduk__dec_reviver_walk(js_ctx);  /* -> [ ... holder name val new_elem ] */\n\n\t\t\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\tduk_del_prop_index(thr, -1, i);\n\t\t\t\t} else {\n\t\t\t\t\t/* XXX: duk_xdef_prop_index_wec() would be more appropriate\n\t\t\t\t\t * here but it currently makes some assumptions that might\n\t\t\t\t\t * not hold (e.g. that previous property is not an accessor).\n\t\t\t\t\t */\n\t\t\t\t\tduk_put_prop_index(thr, -2, i);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t/* [ ... holder name val ] */\n\t\t\tduk_enum(thr, -1, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/);\n\t\t\twhile (duk_next(thr, -1 /*enum_index*/, 0 /*get_value*/)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"walk: object, top=%ld, holder=%!T, name=%!T, val=%!T, enum=%!iT, obj_key=%!T\",\n\t\t\t\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, -5),\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -4), (duk_tval *) duk_get_tval(thr, -3),\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t\t/* [ ... holder name val enum obj_key ] */\n\t\t\t\tduk_dup_m3(thr);\n\t\t\t\tduk_dup_m2(thr);\n\n\t\t\t\t/* [ ... holder name val enum obj_key val obj_key ] */\n\t\t\t\tduk__dec_reviver_walk(js_ctx);\n\n\t\t\t\t/* [ ... holder name val enum obj_key new_elem ] */\n\t\t\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\tduk_del_prop(thr, -3);\n\t\t\t\t} else {\n\t\t\t\t\t/* XXX: duk_xdef_prop_index_wec() would be more appropriate\n\t\t\t\t\t * here but it currently makes some assumptions that might\n\t\t\t\t\t * not hold (e.g. that previous property is not an accessor).\n\t\t\t\t\t *\n\t\t\t\t\t * Using duk_put_prop() works incorrectly with '__proto__'\n\t\t\t\t\t * if the own property with that name has been deleted.  This\n\t\t\t\t\t * does not happen normally, but a clever reviver can trigger\n\t\t\t\t\t * that, see complex reviver case in: test-bug-json-parse-__proto__.js.\n\t\t\t\t\t */\n\t\t\t\t\tduk_put_prop(thr, -4);\n\t\t\t\t}\n\t\t\t}\n\t\t\tduk_pop(thr);  /* pop enum */\n\t\t}\n\t}\n\n\t/* [ ... holder name val ] */\n\n\tduk_dup(thr, js_ctx->idx_reviver);\n\tduk_insert(thr, -4);  /* -> [ ... reviver holder name val ] */\n\tduk_call_method(thr, 2);  /* -> [ ... res ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"walk: top=%ld, result=%!T\",\n\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, -1)));\n}\n\n/*\n *  Stringify implementation.\n */\n\n#define DUK__EMIT_1(js_ctx,ch)          duk__emit_1((js_ctx), (duk_uint_fast8_t) (ch))\n#define DUK__EMIT_2(js_ctx,ch1,ch2)     duk__emit_2((js_ctx), (duk_uint_fast8_t) (ch1), (duk_uint_fast8_t) (ch2))\n#define DUK__EMIT_HSTR(js_ctx,h)        duk__emit_hstring((js_ctx), (h))\n#if defined(DUK_USE_FASTINT) || defined(DUK_USE_JX) || defined(DUK_USE_JC)\n#define DUK__EMIT_CSTR(js_ctx,p)        duk__emit_cstring((js_ctx), (p))\n#endif\n#define DUK__EMIT_STRIDX(js_ctx,i)      duk__emit_stridx((js_ctx), (i))\n#define DUK__UNEMIT_1(js_ctx)           duk__unemit_1((js_ctx))\n\nDUK_LOCAL void duk__emit_1(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch) {\n\tDUK_BW_WRITE_ENSURE_U8(js_ctx->thr, &js_ctx->bw, ch);\n}\n\nDUK_LOCAL void duk__emit_2(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch1, duk_uint_fast8_t ch2) {\n\tDUK_BW_WRITE_ENSURE_U8_2(js_ctx->thr, &js_ctx->bw, ch1, ch2);\n}\n\nDUK_LOCAL void duk__emit_hstring(duk_json_enc_ctx *js_ctx, duk_hstring *h) {\n\tDUK_BW_WRITE_ENSURE_HSTRING(js_ctx->thr, &js_ctx->bw, h);\n}\n\n#if defined(DUK_USE_FASTINT) || defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL void duk__emit_cstring(duk_json_enc_ctx *js_ctx, const char *str) {\n\tDUK_BW_WRITE_ENSURE_CSTRING(js_ctx->thr, &js_ctx->bw, str);\n}\n#endif\n\nDUK_LOCAL void duk__emit_stridx(duk_json_enc_ctx *js_ctx, duk_small_uint_t stridx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\th = DUK_HTHREAD_GET_STRING(js_ctx->thr, stridx);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_BW_WRITE_ENSURE_HSTRING(js_ctx->thr, &js_ctx->bw, h);\n}\n\nDUK_LOCAL void duk__unemit_1(duk_json_enc_ctx *js_ctx) {\n\tDUK_ASSERT(DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw) >= 1);\n\tDUK_BW_ADD_PTR(js_ctx->thr, &js_ctx->bw, -1);\n}\n\n#define DUK__MKESC(nybbles,esc1,esc2)  \\\n\t(((duk_uint_fast32_t) (nybbles)) << 16) | \\\n\t(((duk_uint_fast32_t) (esc1)) << 8) | \\\n\t((duk_uint_fast32_t) (esc2))\n\nDUK_LOCAL duk_uint8_t *duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uint_fast32_t cp, duk_uint8_t *q) {\n\tduk_uint_fast32_t tmp;\n\tduk_small_uint_t dig;\n\n\tDUK_UNREF(js_ctx);\n\n\t/* Caller ensures space for at least DUK__JSON_MAX_ESC_LEN. */\n\n\t/* Select appropriate escape format automatically, and set 'tmp' to a\n\t * value encoding both the escape format character and the nybble count:\n\t *\n\t *   (nybble_count << 16) | (escape_char1) | (escape_char2)\n\t */\n\n#if defined(DUK_USE_JX)\n\tif (DUK_LIKELY(cp < 0x100UL)) {\n\t\tif (DUK_UNLIKELY(js_ctx->flag_ext_custom != 0U)) {\n\t\t\ttmp = DUK__MKESC(2, DUK_ASC_BACKSLASH, DUK_ASC_LC_X);\n\t\t} else {\n\t\t\ttmp = DUK__MKESC(4, DUK_ASC_BACKSLASH, DUK_ASC_LC_U);\n\t\t}\n\t} else\n#endif\n\tif (DUK_LIKELY(cp < 0x10000UL)) {\n\t\ttmp = DUK__MKESC(4, DUK_ASC_BACKSLASH, DUK_ASC_LC_U);\n\t} else {\n#if defined(DUK_USE_JX)\n\t\tif (DUK_LIKELY(js_ctx->flag_ext_custom != 0U)) {\n\t\t\ttmp = DUK__MKESC(8, DUK_ASC_BACKSLASH, DUK_ASC_UC_U);\n\t\t} else\n#endif\n\t\t{\n\t\t\t/* In compatible mode and standard JSON mode, output\n\t\t\t * something useful for non-BMP characters.  This won't\n\t\t\t * roundtrip but will still be more or less readable and\n\t\t\t * more useful than an error.\n\t\t\t */\n\t\t\ttmp = DUK__MKESC(8, DUK_ASC_UC_U, DUK_ASC_PLUS);\n\t\t}\n\t}\n\n\t*q++ = (duk_uint8_t) ((tmp >> 8) & 0xff);\n\t*q++ = (duk_uint8_t) (tmp & 0xff);\n\n\ttmp = tmp >> 16;\n\twhile (tmp > 0) {\n\t\ttmp--;\n\t\tdig = (duk_small_uint_t) ((cp >> (4 * tmp)) & 0x0f);\n\t\t*q++ = duk_lc_digits[dig];\n\t}\n\n\treturn q;\n}\n\nDUK_LOCAL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k) {\n\tconst duk_int8_t *p, *p_start, *p_end;  /* Note: intentionally signed. */\n\tduk_size_t k_len;\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT(k != NULL);\n\n\t/* Accept ASCII strings which conform to identifier requirements\n\t * as being emitted without key quotes.  Since we only accept ASCII\n\t * there's no need for actual decoding: 'p' is intentionally signed\n\t * so that bytes >= 0x80 extend to negative values and are rejected\n\t * as invalid identifier codepoints.\n\t */\n\n\tif (js_ctx->flag_avoid_key_quotes) {\n\t\tk_len = DUK_HSTRING_GET_BYTELEN(k);\n\t\tp_start = (const duk_int8_t *) DUK_HSTRING_GET_DATA(k);\n\t\tp_end = p_start + k_len;\n\t\tp = p_start;\n\n\t\tif (p == p_end) {\n\t\t\t/* Zero length string is not accepted without quotes */\n\t\t\tgoto quote_normally;\n\t\t}\n\t\tcp = (duk_codepoint_t) (*p++);\n\t\tif (DUK_UNLIKELY(!duk_unicode_is_identifier_start(cp))) {\n\t\t\tgoto quote_normally;\n\t\t}\n\t\twhile (p < p_end) {\n\t\t\tcp = (duk_codepoint_t) (*p++);\n\t\t\tif (DUK_UNLIKELY(!duk_unicode_is_identifier_part(cp))) {\n\t\t\t\tgoto quote_normally;\n\t\t\t}\n\t\t}\n\n\t\t/* This seems faster than emitting bytes one at a time and\n\t\t * then potentially rewinding.\n\t\t */\n\t\tDUK__EMIT_HSTR(js_ctx, k);\n\t\treturn;\n\t}\n\n quote_normally:\n\tduk__enc_quote_string(js_ctx, k);\n}\n\n/* The Quote(value) operation: quote a string.\n *\n * Stack policy: [ ] -> [ ].\n */\n\nDUK_LOCAL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p, *p_start, *p_end, *p_now, *p_tmp;\n\tduk_uint8_t *q;\n\tduk_ucodepoint_t cp;  /* typed for duk_unicode_decode_xutf8() */\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_quote_string: h_str=%!O\", (duk_heaphdr *) h_str));\n\n\tDUK_ASSERT(h_str != NULL);\n\tp_start = DUK_HSTRING_GET_DATA(h_str);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_str);\n\tp = p_start;\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_DOUBLEQUOTE);\n\n\t/* Encode string in small chunks, estimating the maximum expansion so that\n\t * there's no need to ensure space while processing the chunk.\n\t */\n\n\twhile (p < p_end) {\n\t\tduk_size_t left, now, space;\n\n\t\tleft = (duk_size_t) (p_end - p);\n\t\tnow = (left > DUK__JSON_ENCSTR_CHUNKSIZE ?\n\t\t       DUK__JSON_ENCSTR_CHUNKSIZE : left);\n\n\t\t/* Maximum expansion per input byte is 6:\n\t\t *   - invalid UTF-8 byte causes \"\\uXXXX\" to be emitted (6/1 = 6).\n\t\t *   - 2-byte UTF-8 encodes as \"\\uXXXX\" (6/2 = 3).\n\t\t *   - 4-byte UTF-8 encodes as \"\\Uxxxxxxxx\" (10/4 = 2.5).\n\t\t */\n\t\tspace = now * 6;\n\t\tq = DUK_BW_ENSURE_GETPTR(thr, &js_ctx->bw, space);\n\n\t\tp_now = p + now;\n\n\t\twhile (p < p_now) {\n#if defined(DUK_USE_JSON_QUOTESTRING_FASTPATH)\n\t\t\tduk_uint8_t b;\n\n\t\t\tb = duk__json_quotestr_lookup[*p++];\n\t\t\tif (DUK_LIKELY(b < 0x80)) {\n\t\t\t\t/* Most input bytes go through here. */\n\t\t\t\t*q++ = b;\n\t\t\t} else if (b >= 0xa0) {\n\t\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t\t\t*q++ = (duk_uint8_t) (b - 0x80);\n\t\t\t} else if (b == 0x80) {\n\t\t\t\tcp = (duk_ucodepoint_t) (*(p - 1));\n\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t} else if (b == 0x7f && js_ctx->flag_ascii_only) {\n\t\t\t\t/* 0x7F is special */\n\t\t\t\tDUK_ASSERT(b == 0x81);\n\t\t\t\tcp = (duk_ucodepoint_t) 0x7f;\n\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(b == 0x81);\n\t\t\t\tp--;\n\n\t\t\t\t/* slow path is shared */\n#else  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\n\t\t\tcp = *p;\n\n\t\t\tif (DUK_LIKELY(cp <= 0x7f)) {\n\t\t\t\t/* ascii fast path: avoid decoding utf-8 */\n\t\t\t\tp++;\n\t\t\t\tif (cp == 0x22 || cp == 0x5c) {\n\t\t\t\t\t/* double quote or backslash */\n\t\t\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t\t\t\t*q++ = (duk_uint8_t) cp;\n\t\t\t\t} else if (cp < 0x20) {\n\t\t\t\t\tduk_uint_fast8_t esc_char;\n\n\t\t\t\t\t/* This approach is a bit shorter than a straight\n\t\t\t\t\t * if-else-ladder and also a bit faster.\n\t\t\t\t\t */\n\t\t\t\t\tif (cp < (sizeof(duk__json_quotestr_esc) / sizeof(duk_uint8_t)) &&\n\t\t\t\t\t    (esc_char = duk__json_quotestr_esc[cp]) != 0) {\n\t\t\t\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t\t\t\t\t*q++ = (duk_uint8_t) esc_char;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t\t\t}\n\t\t\t\t} else if (cp == 0x7f && js_ctx->flag_ascii_only) {\n\t\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t\t} else {\n\t\t\t\t\t/* any other printable -> as is */\n\t\t\t\t\t*q++ = (duk_uint8_t) cp;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* slow path is shared */\n#endif  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\n\n\t\t\t\t/* slow path decode */\n\n\t\t\t\t/* If XUTF-8 decoding fails, treat the offending byte as a codepoint directly\n\t\t\t\t * and go forward one byte.  This is of course very lossy, but allows some kind\n\t\t\t\t * of output to be produced even for internal strings which don't conform to\n\t\t\t\t * XUTF-8.  All standard ECMAScript strings are always CESU-8, so this behavior\n\t\t\t\t * does not violate the ECMAScript specification.  The behavior is applied to\n\t\t\t\t * all modes, including ECMAScript standard JSON.  Because the current XUTF-8\n\t\t\t\t * decoding is not very strict, this behavior only really affects initial bytes\n\t\t\t\t * and truncated codepoints.\n\t\t\t\t *\n\t\t\t\t * Another alternative would be to scan forwards to start of next codepoint\n\t\t\t\t * (or end of input) and emit just one replacement codepoint.\n\t\t\t\t */\n\n\t\t\t\tp_tmp = p;\n\t\t\t\tif (!duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp)) {\n\t\t\t\t\t/* Decode failed. */\n\t\t\t\t\tcp = *p_tmp;\n\t\t\t\t\tp = p_tmp + 1;\n\t\t\t\t}\n\n#if defined(DUK_USE_NONSTD_JSON_ESC_U2028_U2029)\n\t\t\t\tif (js_ctx->flag_ascii_only || cp == 0x2028 || cp == 0x2029) {\n#else\n\t\t\t\tif (js_ctx->flag_ascii_only) {\n#endif\n\t\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t\t} else {\n\t\t\t\t\t/* as is */\n\t\t\t\t\tDUK_RAW_WRITE_XUTF8(q, cp);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tDUK_BW_SET_PTR(thr, &js_ctx->bw, q);\n\t}\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_DOUBLEQUOTE);\n}\n\n/* Encode a double (checked by caller) from stack top.  Stack top may be\n * replaced by serialized string but is not popped (caller does that).\n */\nDUK_LOCAL void duk__enc_double(duk_json_enc_ctx *js_ctx) {\n\tduk_hthread *thr;\n\tduk_tval *tv;\n\tduk_double_t d;\n\tduk_small_int_t c;\n\tduk_small_int_t s;\n\tduk_small_uint_t stridx;\n\tduk_small_uint_t n2s_flags;\n\tduk_hstring *h_str;\n\n\tDUK_ASSERT(js_ctx != NULL);\n\tthr = js_ctx->thr;\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Caller must ensure 'tv' is indeed a double and not a fastint! */\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\td = DUK_TVAL_GET_DOUBLE(tv);\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\ts = (duk_small_int_t) DUK_SIGNBIT(d);\n\tDUK_UNREF(s);\n\n\tif (DUK_LIKELY(!(c == DUK_FP_INFINITE || c == DUK_FP_NAN))) {\n\t\tDUK_ASSERT(DUK_ISFINITE(d));\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t/* Negative zero needs special handling in JX/JC because\n\t\t * it would otherwise serialize to '0', not '-0'.\n\t\t */\n\t\tif (DUK_UNLIKELY(c == DUK_FP_ZERO && s != 0 &&\n\t\t                 (js_ctx->flag_ext_custom_or_compatible))) {\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_MINUS_ZERO);  /* '-0' */\n\t\t} else\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\t\t{\n\t\t\tn2s_flags = 0;\n\t\t\t/* [ ... number ] -> [ ... string ] */\n\t\t\tduk_numconv_stringify(thr, 10 /*radix*/, 0 /*digits*/, n2s_flags);\n\t\t}\n\t\th_str = duk_known_hstring(thr, -1);\n\t\tDUK__EMIT_HSTR(js_ctx, h_str);\n\t\treturn;\n\t}\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tif (!(js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM |\n\t                       DUK_JSON_FLAG_EXT_COMPATIBLE))) {\n\t\tstridx = DUK_STRIDX_LC_NULL;\n\t} else if (c == DUK_FP_NAN) {\n\t\tstridx = js_ctx->stridx_custom_nan;\n\t} else if (s == 0) {\n\t\tstridx = js_ctx->stridx_custom_posinf;\n\t} else {\n\t\tstridx = js_ctx->stridx_custom_neginf;\n\t}\n#else\n\tstridx = DUK_STRIDX_LC_NULL;\n#endif\n\tDUK__EMIT_STRIDX(js_ctx, stridx);\n}\n\n#if defined(DUK_USE_FASTINT)\n/* Encode a fastint from duk_tval ptr, no value stack effects. */\nDUK_LOCAL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv) {\n\tduk_int64_t v;\n\n\t/* Fastint range is signed 48-bit so longest value is -2^47 = -140737488355328\n\t * (16 chars long), longest signed 64-bit value is -2^63 = -9223372036854775808\n\t * (20 chars long).  Alloc space for 64-bit range to be safe.\n\t */\n\tduk_uint8_t buf[20 + 1];\n\n\t/* Caller must ensure 'tv' is indeed a fastint! */\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\tv = DUK_TVAL_GET_FASTINT(tv);\n\n\t/* XXX: There are no format strings in duk_config.h yet, could add\n\t * one for formatting duk_int64_t.  For now, assumes \"%lld\" and that\n\t * \"long long\" type exists.  Could also rely on C99 directly but that\n\t * won't work for older MSVC.\n\t */\n\tDUK_SPRINTF((char *) buf, \"%lld\", (long long) v);\n\tDUK__EMIT_CSTR(js_ctx, (const char *) buf);\n}\n#endif\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n#if defined(DUK_USE_HEX_FASTPATH)\nDUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) {\n\tduk_uint8_t *q;\n\tduk_uint16_t *q16;\n\tduk_small_uint_t x;\n\tduk_size_t i, len_safe;\n#if !defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)\n\tduk_bool_t shift_dst;\n#endif\n\n\t/* Unlike in duk_hex_encode() 'dst' is not necessarily aligned by 2.\n\t * For platforms where unaligned accesses are not allowed, shift 'dst'\n\t * ahead by 1 byte to get alignment and then duk_memmove() the result\n\t * in place.  The faster encoding loop makes up the difference.\n\t * There's always space for one extra byte because a terminator always\n\t * follows the hex data and that's been accounted for by the caller.\n\t */\n\n#if defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)\n\tq16 = (duk_uint16_t *) (void *) dst;\n#else\n\tshift_dst = (duk_bool_t) (((duk_size_t) dst) & 0x01U);\n\tif (shift_dst) {\n\t\tDUK_DD(DUK_DDPRINT(\"unaligned accesses not possible, dst not aligned -> step to dst + 1\"));\n\t\tq16 = (duk_uint16_t *) (void *) (dst + 1);\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"unaligned accesses not possible, dst is aligned\"));\n\t\tq16 = (duk_uint16_t *) (void *) dst;\n\t}\n\tDUK_ASSERT((((duk_size_t) q16) & 0x01U) == 0);\n#endif\n\n\tlen_safe = src_len & ~0x03U;\n\tfor (i = 0; i < len_safe; i += 4) {\n\t\tq16[0] = duk_hex_enctab[src[i]];\n\t\tq16[1] = duk_hex_enctab[src[i + 1]];\n\t\tq16[2] = duk_hex_enctab[src[i + 2]];\n\t\tq16[3] = duk_hex_enctab[src[i + 3]];\n\t\tq16 += 4;\n\t}\n\tq = (duk_uint8_t *) q16;\n\n#if !defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)\n\tif (shift_dst) {\n\t\tq--;\n\t\tduk_memmove((void *) dst, (const void *) (dst + 1), 2 * len_safe);\n\t\tDUK_ASSERT(dst + 2 * len_safe == q);\n\t}\n#endif\n\n\tfor (; i < src_len; i++) {\n\t\tx = src[i];\n\t\t*q++ = duk_lc_digits[x >> 4];\n\t\t*q++ = duk_lc_digits[x & 0x0f];\n\t}\n\n\treturn q;\n}\n#else  /* DUK_USE_HEX_FASTPATH */\nDUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint8_t *q;\n\tduk_small_uint_t x;\n\n\tp = src;\n\tp_end = src + src_len;\n\tq = dst;\n\twhile (p != p_end) {\n\t\tx = *p++;\n\t\t*q++ = duk_lc_digits[x >> 4];\n\t\t*q++ = duk_lc_digits[x & 0x0f];\n\t}\n\n\treturn q;\n}\n#endif  /* DUK_USE_HEX_FASTPATH */\n\nDUK_LOCAL void duk__enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_data, duk_size_t buf_len) {\n\tduk_hthread *thr;\n\tduk_uint8_t *q;\n\tduk_size_t space;\n\n\tthr = js_ctx->thr;\n\n\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);  /* caller checks */\n\tDUK_ASSERT(js_ctx->flag_ext_custom_or_compatible);\n\n\t/* Buffer values are encoded in (lowercase) hex to make the\n\t * binary data readable.  Base64 or similar would be more\n\t * compact but less readable, and the point of JX/JC\n\t * variants is to be as useful to a programmer as possible.\n\t */\n\n\t/* The #if defined() clutter here needs to handle the three\n\t * cases: (1) JX+JC, (2) JX only, (3) JC only.\n\t */\n\n\t/* Note: space must cater for both JX and JC. */\n\tspace = 9 + buf_len * 2 + 2;\n\tDUK_ASSERT(DUK_HBUFFER_MAX_BYTELEN <= 0x7ffffffeUL);\n\tDUK_ASSERT((space - 2) / 2 >= buf_len);  /* overflow not possible, buffer limits */\n\tq = DUK_BW_ENSURE_GETPTR(thr, &js_ctx->bw, space);\n\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\tif (js_ctx->flag_ext_custom)\n#endif\n#if defined(DUK_USE_JX)\n\t{\n\t\t*q++ = DUK_ASC_PIPE;\n\t\tq = duk__enc_buffer_data_hex(buf_data, buf_len, q);\n\t\t*q++ = DUK_ASC_PIPE;\n\n\t}\n#endif\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\telse\n#endif\n#if defined(DUK_USE_JC)\n\t{\n\t\tDUK_ASSERT(js_ctx->flag_ext_compatible);\n\t\tduk_memcpy((void *) q, (const void *) \"{\\\"_buf\\\":\\\"\", 9);  /* len: 9 */\n\t\tq += 9;\n\t\tq = duk__enc_buffer_data_hex(buf_data, buf_len, q);\n\t\t*q++ = DUK_ASC_DOUBLEQUOTE;\n\t\t*q++ = DUK_ASC_RCURLY;\n\t}\n#endif\n\n\tDUK_BW_SET_PTR(thr, &js_ctx->bw, q);\n}\n\nDUK_LOCAL void duk__enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) {\n\tduk__enc_buffer_data(js_ctx,\n\t                     (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(js_ctx->thr->heap, h),\n\t                     (duk_size_t) DUK_HBUFFER_GET_SIZE(h));\n}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\nDUK_LOCAL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) {\n\tduk_size_t i, n;\n\tconst duk_uint8_t *buf;\n\tduk_uint8_t *q;\n\n\tn = DUK_HBUFFER_GET_SIZE(h);\n\tif (n == 0) {\n\t\tDUK__EMIT_2(js_ctx, DUK_ASC_LCURLY, DUK_ASC_RCURLY);\n\t\treturn;\n\t}\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);\n\n\t/* Maximum encoded length with 32-bit index: 1 + 10 + 2 + 3 + 1 + 1 = 18,\n\t * with 64-bit index: 1 + 20 + 2 + 3 + 1 + 1 = 28.  32 has some slack.\n\t *\n\t * Note that because the output buffer is reallocated from time to time,\n\t * side effects (such as finalizers) affecting the buffer 'h' must be\n\t * disabled.  This is the case in the JSON.stringify() fast path.\n\t */\n\n\tbuf = (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(js_ctx->thr->heap, h);\n\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth + 1);\n\t\t\tq = DUK_BW_ENSURE_GETPTR(js_ctx->thr, &js_ctx->bw, 32);\n\t\t\tq += DUK_SPRINTF((char *) q, \"\\\"%lu\\\": %u,\", (unsigned long) i, (unsigned int) buf[i]);\n\t\t\tDUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, q);\n\t\t}\n\t} else {\n\t\tq = DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw);\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tq = DUK_BW_ENSURE_RAW(js_ctx->thr, &js_ctx->bw, 32, q);\n\t\t\tq += DUK_SPRINTF((char *) q, \"\\\"%lu\\\":%u,\", (unsigned long) i, (unsigned int) buf[i]);\n\t\t}\n\t\tDUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, q);\n\t}\n\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\n\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t}\n\tDUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);\n}\n#endif  /* DUK_USE_JSON_STRINGIFY_FASTPATH */\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr) {\n\tchar buf[64];  /* XXX: how to figure correct size? */\n\tconst char *fmt;\n\n\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);  /* caller checks */\n\tDUK_ASSERT(js_ctx->flag_ext_custom_or_compatible);\n\n\tduk_memzero(buf, sizeof(buf));\n\n\t/* The #if defined() clutter here needs to handle the three\n\t * cases: (1) JX+JC, (2) JX only, (3) JC only.\n\t */\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\tif (js_ctx->flag_ext_custom)\n#endif\n#if defined(DUK_USE_JX)\n\t{\n\t\tfmt = ptr ? \"(%p)\" : \"(null)\";\n\t}\n#endif\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\telse\n#endif\n#if defined(DUK_USE_JC)\n\t{\n\t\tDUK_ASSERT(js_ctx->flag_ext_compatible);\n\t\tfmt = ptr ? \"{\\\"_ptr\\\":\\\"%p\\\"}\" : \"{\\\"_ptr\\\":\\\"null\\\"}\";\n\t}\n#endif\n\n\t/* When ptr == NULL, the format argument is unused. */\n\tDUK_SNPRINTF(buf, sizeof(buf) - 1, fmt, ptr);  /* must not truncate */\n\tDUK__EMIT_CSTR(js_ctx, buf);\n}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj) {\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\tif (h_bufobj->buf == NULL || !DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t} else {\n\t\t/* Handle both full and partial slice (as long as covered). */\n\t\tduk__enc_buffer_data(js_ctx,\n\t\t                     (duk_uint8_t *) DUK_HBUFOBJ_GET_SLICE_BASE(js_ctx->thr->heap, h_bufobj),\n\t\t                     (duk_size_t) h_bufobj->length);\n\t}\n}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* Indent helper.  Calling code relies on js_ctx->recursion_depth also being\n * directly related to indent depth.\n */\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) {\n\tDUK_ASSERT(js_ctx->h_gap != NULL);\n\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) > 0);  /* caller guarantees */\n\n\tDUK__EMIT_1(js_ctx, 0x0a);\n\twhile (depth-- > 0) {\n\t\tDUK__EMIT_HSTR(js_ctx, js_ctx->h_gap);\n\t}\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) {\n\tconst duk_uint8_t *gap_data;\n\tduk_size_t gap_len;\n\tduk_size_t avail_bytes;   /* bytes of indent available for copying */\n\tduk_size_t need_bytes;    /* bytes of indent still needed */\n\tduk_uint8_t *p_start;\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT(js_ctx->h_gap != NULL);\n\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) > 0);  /* caller guarantees */\n\n\tDUK__EMIT_1(js_ctx, 0x0a);\n\tif (DUK_UNLIKELY(depth == 0)) {\n\t\treturn;\n\t}\n\n\t/* To handle deeper indents efficiently, make use of copies we've\n\t * already emitted.  In effect we can emit a sequence of 1, 2, 4,\n\t * 8, etc copies, and then finish the last run.  Byte counters\n\t * avoid multiply with gap_len on every loop.\n\t */\n\n\tgap_data = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(js_ctx->h_gap);\n\tgap_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap);\n\tDUK_ASSERT(gap_len > 0);\n\n\tneed_bytes = gap_len * depth;\n\tp = DUK_BW_ENSURE_GETPTR(js_ctx->thr, &js_ctx->bw, need_bytes);\n\tp_start = p;\n\n\tduk_memcpy((void *) p, (const void *) gap_data, (size_t) gap_len);\n\tp += gap_len;\n\tavail_bytes = gap_len;\n\tDUK_ASSERT(need_bytes >= gap_len);\n\tneed_bytes -= gap_len;\n\n\twhile (need_bytes >= avail_bytes) {\n\t\tduk_memcpy((void *) p, (const void *) p_start, (size_t) avail_bytes);\n\t\tp += avail_bytes;\n\t\tneed_bytes -= avail_bytes;\n\t\tavail_bytes <<= 1;\n\t}\n\n\tDUK_ASSERT(need_bytes < avail_bytes);  /* need_bytes may be zero */\n\tduk_memcpy((void *) p, (const void *) p_start, (size_t) need_bytes);\n\tp += need_bytes;\n\t/*avail_bytes += need_bytes*/\n\n\tDUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, p);\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/* Shared entry handling for object/array serialization. */\nDUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hobject *h_target;\n\tduk_uint_fast32_t i, n;\n\n\t*entry_top = duk_get_top(thr);\n\n\tduk_require_stack(thr, DUK_JSON_ENC_REQSTACK);\n\n\t/* Loop check using a hybrid approach: a fixed-size visited[] array\n\t * with overflow in a loop check object.\n\t */\n\n\th_target = duk_known_hobject(thr, -1);  /* object or array */\n\n\tn = js_ctx->recursion_depth;\n\tif (DUK_UNLIKELY(n > DUK_JSON_ENC_LOOPARRAY)) {\n\t\tn = DUK_JSON_ENC_LOOPARRAY;\n\t}\n\tfor (i = 0; i < n; i++) {\n\t\tif (DUK_UNLIKELY(js_ctx->visiting[i] == h_target)) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"slow path loop detect\"));\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CYCLIC_INPUT);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t}\n\tif (js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY) {\n\t\tjs_ctx->visiting[js_ctx->recursion_depth] = h_target;\n\t} else {\n\t\tduk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) h_target);\n\t\tduk_dup_top(thr);  /* -> [ ... voidp voidp ] */\n\t\tif (duk_has_prop(thr, js_ctx->idx_loop)) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CYCLIC_INPUT);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tduk_push_true(thr);  /* -> [ ... voidp true ] */\n\t\tduk_put_prop(thr, js_ctx->idx_loop);  /* -> [ ... ] */\n\t}\n\n\t/* C recursion check. */\n\n\tDUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0);  /* unsigned */\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tif (js_ctx->recursion_depth >= js_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_JSONENC_RECLIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tjs_ctx->recursion_depth++;\n\n\tDUK_DDD(DUK_DDDPRINT(\"shared entry finished: top=%ld, loop=%!T\",\n\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop)));\n}\n\n/* Shared exit handling for object/array serialization. */\nDUK_LOCAL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hobject *h_target;\n\n\t/* C recursion check. */\n\n\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tjs_ctx->recursion_depth--;\n\n\t/* Loop check. */\n\n\th_target = duk_known_hobject(thr, *entry_top - 1);  /* original target at entry_top - 1 */\n\n\tif (js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY) {\n\t\t/* Previous entry was inside visited[], nothing to do. */\n\t} else {\n\t\tduk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) h_target);\n\t\tduk_del_prop(thr, js_ctx->idx_loop);  /* -> [ ... ] */\n\t}\n\n\t/* Restore stack top after unbalanced code paths. */\n\tduk_set_top(thr, *entry_top);\n\n\tDUK_DDD(DUK_DDDPRINT(\"shared entry finished: top=%ld, loop=%!T\",\n\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop)));\n}\n\n/* The JO(value) operation: encode object.\n *\n * Stack policy: [ object ] -> [ object ].\n */\nDUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hstring *h_key;\n\tduk_idx_t entry_top;\n\tduk_idx_t idx_obj;\n\tduk_idx_t idx_keys;\n\tduk_bool_t emitted;\n\tduk_uarridx_t arr_len, i;\n\tduk_size_t prev_size;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_object: obj=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__enc_objarr_entry(js_ctx, &entry_top);\n\n\tidx_obj = entry_top - 1;\n\n\tif (js_ctx->idx_proplist >= 0) {\n\t\tidx_keys = js_ctx->idx_proplist;\n\t} else {\n\t\t/* XXX: would be nice to enumerate an object at specified index */\n\t\tduk_dup(thr, idx_obj);\n\t\t(void) duk_hobject_get_enumerated_keys(thr, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/);  /* [ ... target ] -> [ ... target keys ] */\n\t\tidx_keys = duk_require_normalize_index(thr, -1);\n\t\t/* leave stack unbalanced on purpose */\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"idx_keys=%ld, h_keys=%!T\",\n\t                     (long) idx_keys, (duk_tval *) duk_get_tval(thr, idx_keys)));\n\n\t/* Steps 8-10 have been merged to avoid a \"partial\" variable. */\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);\n\n\t/* XXX: keys is an internal object with all keys to be processed\n\t * in its (gapless) array part.  Because nobody can touch the keys\n\t * object, we could iterate its array part directly (keeping in mind\n\t * that it can be reallocated).\n\t */\n\n\tarr_len = (duk_uarridx_t) duk_get_length(thr, idx_keys);\n\temitted = 0;\n\tfor (i = 0; i < arr_len; i++) {\n\t\tduk_get_prop_index(thr, idx_keys, i);  /* -> [ ... key ] */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"object property loop: holder=%!T, key=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_obj),\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\th_key = duk_known_hstring(thr, -1);\n\t\tDUK_ASSERT(h_key != NULL);\n\t\tDUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(h_key));  /* proplist filtering; enum options */\n\n\t\tprev_size = DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw);\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t\tduk__enc_key_autoquote(js_ctx, h_key);\n\t\t\tDUK__EMIT_2(js_ctx, DUK_ASC_COLON, DUK_ASC_SPACE);\n\t\t} else {\n\t\t\tduk__enc_key_autoquote(js_ctx, h_key);\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COLON);\n\t\t}\n\n\t\t/* [ ... key ] */\n\n\t\tif (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_obj) == 0)) {\n\t\t\t/* Value would yield 'undefined', so skip key altogether.\n\t\t\t * Side effects have already happened.\n\t\t\t */\n\t\t\tDUK_BW_SET_SIZE(js_ctx->thr, &js_ctx->bw, prev_size);\n\t\t} else {\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\t\temitted = 1;\n\t\t}\n\n\t\t/* [ ... ] */\n\t}\n\n\tif (emitted) {\n\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t}\n\t}\n\tDUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);\n\n\tduk__enc_objarr_exit(js_ctx, &entry_top);\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n}\n\n/* The JA(value) operation: encode array.\n *\n * Stack policy: [ array ] -> [ array ].\n */\nDUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_idx_t entry_top;\n\tduk_idx_t idx_arr;\n\tduk_bool_t emitted;\n\tduk_uarridx_t i, arr_len;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_array: array=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__enc_objarr_entry(js_ctx, &entry_top);\n\n\tidx_arr = entry_top - 1;\n\n\t/* Steps 8-10 have been merged to avoid a \"partial\" variable. */\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_LBRACKET);\n\n\tarr_len = (duk_uarridx_t) duk_get_length(thr, idx_arr);\n\temitted = 0;\n\tfor (i = 0; i < arr_len; i++) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"array entry loop: array=%!T, index=%ld, arr_len=%ld\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_arr),\n\t\t                     (long) i, (long) arr_len));\n\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t}\n\n\t\t(void) duk_push_uint_to_hstring(thr, (duk_uint_t) i);  /* -> [ ... key ] */\n\n\t\t/* [ ... key ] */\n\n\t\tif (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_arr) == 0)) {\n\t\t\t/* Value would normally be omitted, replace with 'null'. */\n\t\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\t} else {\n\t\t\t;\n\t\t}\n\n\t\t/* [ ... ] */\n\n\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\temitted = 1;\n\t}\n\n\tif (emitted) {\n\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t}\n\t}\n\tDUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET);\n\n\tduk__enc_objarr_exit(js_ctx, &entry_top);\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n}\n\n/* The Str(key, holder) operation.\n *\n * Stack policy: [ ... key ] -> [ ... ]\n */\nDUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_tval *tv;\n\tduk_tval *tv_holder;\n\tduk_tval *tv_key;\n\tduk_small_int_t c;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_value: idx_holder=%ld, holder=%!T, key=%!T\",\n\t                     (long) idx_holder, (duk_tval *) duk_get_tval(thr, idx_holder),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\ttv_holder = DUK_GET_TVAL_POSIDX(thr, idx_holder);\n\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_holder));\n\ttv_key = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_key));\n\tDUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(DUK_TVAL_GET_STRING(tv_key)));  /* Caller responsible. */\n\t(void) duk_hobject_getprop(thr, tv_holder, tv_key);\n\n\t/* -> [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* Standard JSON checks for .toJSON() only for actual objects; for\n\t * example, setting Number.prototype.toJSON and then serializing a\n\t * number won't invoke the .toJSON() method.  However, lightfuncs and\n\t * plain buffers mimic objects so we check for their .toJSON() method.\n\t */\n\tif (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT |\n\t                                 DUK_TYPE_MASK_LIGHTFUNC |\n\t                                 DUK_TYPE_MASK_BUFFER)) {\n\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_JSON);\n\t\tif (duk_is_callable(thr, -1)) {  /* toJSON() can also be a lightfunc */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is object, has callable toJSON() -> call it\"));\n\t\t\t/* XXX: duk_dup_unvalidated(thr, -2) etc. */\n\t\t\tduk_dup_m2(thr);          /* -> [ ... key val toJSON val ] */\n\t\t\tduk_dup_m4(thr);          /* -> [ ... key val toJSON val key ] */\n\t\t\tduk_call_method(thr, 1);  /* -> [ ... key val val' ] */\n\t\t\tduk_remove_m2(thr);       /* -> [ ... key val' ] */\n\t\t} else {\n\t\t\tduk_pop(thr);             /* -> [ ... key val ] */\n\t\t}\n\t}\n\n\t/* [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (js_ctx->h_replacer) {\n\t\t/* XXX: Here a \"slice copy\" would be useful. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"replacer is set, call replacer\"));\n\t\tduk_push_hobject(thr, js_ctx->h_replacer);  /* -> [ ... key val replacer ] */\n\t\tduk_dup(thr, idx_holder);                   /* -> [ ... key val replacer holder ] */\n\t\tduk_dup_m4(thr);                            /* -> [ ... key val replacer holder key ] */\n\t\tduk_dup_m4(thr);                            /* -> [ ... key val replacer holder key val ] */\n\t\tduk_call_method(thr, 2);                    /* -> [ ... key val val' ] */\n\t\tduk_remove_m2(thr);                         /* -> [ ... key val' ] */\n\t}\n\n\t/* [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h) &&\n\t\t    js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE)) {\n\t\t\t/* With JX/JC a bufferobject gets serialized specially. */\n\t\t\tduk_hbufobj *h_bufobj;\n\t\t\th_bufobj = (duk_hbufobj *) h;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\t\t\tduk__enc_bufobj(js_ctx, h_bufobj);\n\t\t\tgoto pop2_emitted;\n\t\t}\n\t\t/* Otherwise bufferobjects get serialized as normal objects. */\n#endif  /* JX || JC */\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t\tc = (duk_small_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h);\n\t\tswitch (c) {\n\t\tcase DUK_HOBJECT_CLASS_NUMBER: {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is a Number object -> coerce with ToNumber()\"));\n\t\t\tduk_to_number_m1(thr);\n\t\t\t/* The coercion potentially invokes user .valueOf() and .toString()\n\t\t\t * but can't result in a function value because ToPrimitive() would\n\t\t\t * reject such a result: test-dev-json-stringify-coercion-1.js.\n\t\t\t */\n\t\t\tDUK_ASSERT(!duk_is_callable(thr, -1));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_HOBJECT_CLASS_STRING: {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is a String object -> coerce with ToString()\"));\n\t\t\tduk_to_string(thr, -1);\n\t\t\t/* Same coercion behavior as for Number. */\n\t\t\tDUK_ASSERT(!duk_is_callable(thr, -1));\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tcase DUK_HOBJECT_CLASS_POINTER:\n#endif\n\t\tcase DUK_HOBJECT_CLASS_BOOLEAN: {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is a Boolean/Buffer/Pointer object -> get internal value\"));\n\t\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t\t\tduk_remove_m2(thr);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\t/* Normal object which doesn't get automatically coerced to a\n\t\t\t * primitive value.  Functions are checked for specially.  The\n\t\t\t * primitive value coercions for Number, String, Pointer, and\n\t\t\t * Boolean can't result in functions so suffices to check here.\n\t\t\t * Symbol objects are handled like plain objects (their primitive\n\t\t\t * value is NOT looked up like for e.g. String objects).\n\t\t\t */\n\t\t\tDUK_ASSERT(h != NULL);\n\t\t\tif (DUK_HOBJECT_IS_CALLABLE(h)) {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t\t\tif (js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM |\n\t\t\t\t                     DUK_JSON_FLAG_EXT_COMPATIBLE)) {\n\t\t\t\t\t/* We only get here when doing non-standard JSON encoding */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> function allowed, serialize to custom format\"));\n\t\t\t\t\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);\n\t\t\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function);\n\t\t\t\t\tgoto pop2_emitted;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> will result in undefined (function)\"));\n\t\t\t\t\tgoto pop2_undef;\n\t\t\t\t}\n#else  /* DUK_USE_JX || DUK_USE_JC */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> will result in undefined (function)\"));\n\t\t\t\tgoto pop2_undef;\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\t\t\t}\n\t\t}\n\t\t}  /* end switch */\n\t}\n\n\t/* [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (duk_check_type_mask(thr, -1, js_ctx->mask_for_undefined)) {\n\t\t/* will result in undefined */\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> will result in undefined (type mask check)\"));\n\t\tgoto pop2_undef;\n\t}\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t/* When JX/JC not in use, the type mask above will avoid this case if needed. */\n\tcase DUK_TAG_UNDEFINED: {\n\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined);\n\t\tbreak;\n\t}\n#endif\n\tcase DUK_TAG_NULL: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_TVAL_GET_BOOLEAN(tv) ?\n\t\t                 DUK_STRIDX_TRUE : DUK_STRIDX_FALSE);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t/* When JX/JC not in use, the type mask above will avoid this case if needed. */\n\tcase DUK_TAG_POINTER: {\n\t\tduk__enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv));\n\t\tbreak;\n\t}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tgoto pop2_undef;\n\t\t}\n\t\tduk__enc_quote_string(js_ctx, h);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* Function values are handled completely above (including\n\t\t * coercion results):\n\t\t */\n\t\tDUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE(h));\n\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tduk__enc_array(js_ctx);\n\t\t} else {\n\t\t\tduk__enc_object(js_ctx);\n\t\t}\n\t\tbreak;\n\t}\n\t/* Because plain buffers mimics Uint8Array, they have enumerable\n\t * index properties [0,byteLength[.  Because JSON only serializes\n\t * enumerable own properties, no properties can be serialized for\n\t * plain buffers (all virtual properties are non-enumerable).  However,\n\t * there may be a .toJSON() method which was already handled above.\n\t */\n\tcase DUK_TAG_BUFFER: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tduk__enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv));\n\t\t\tbreak;\n\t\t}\n#endif\n\n\t\t/* Could implement a fastpath, but the fast path would need\n\t\t * to handle realloc side effects correctly.\n\t\t */\n\t\tduk_to_object(thr, -1);\n\t\tduk__enc_object(js_ctx);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t/* We only get here when doing non-standard JSON encoding */\n\t\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);\n\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function);\n#else\n\t\t/* Standard JSON omits functions */\n\t\tDUK_UNREACHABLE();\n#endif\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\t/* Number serialization has a significant impact relative to\n\t\t * other fast path code, so careful fast path for fastints.\n\t\t */\n\t\tduk__enc_fastint_tval(js_ctx, tv);\n\t\tbreak;\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\t/* XXX: A fast path for usual integers would be useful when\n\t\t * fastint support is not enabled.\n\t\t */\n\t\tduk__enc_double(js_ctx);\n\t\tbreak;\n\t}\n\t}\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n pop2_emitted:\n#endif\n\tduk_pop_2(thr); /* [ ... key val ] -> [ ... ] */\n\treturn 1;  /* emitted */\n\n pop2_undef:\n\tduk_pop_2(thr);  /* [ ... key val ] -> [ ... ] */\n\treturn 0;  /* not emitted */\n}\n\n/* E5 Section 15.12.3, main algorithm, step 4.b.ii steps 1-4. */\nDUK_LOCAL duk_bool_t duk__enc_allow_into_proplist(duk_tval *tv) {\n\tduk_small_int_t c;\n\n\t/* XXX: some kind of external internal type checker?\n\t * - type mask; symbol flag; class mask\n\t */\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_STRING(tv)) {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn 1;\n\t} else if (DUK_TVAL_IS_NUMBER(tv)) {\n\t\treturn 1;\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tc = (duk_small_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h);\n\t\tif (c == DUK_HOBJECT_CLASS_STRING || c == DUK_HOBJECT_CLASS_NUMBER) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n/*\n *  JSON.stringify() fast path\n *\n *  Otherwise supports full JSON, JX, and JC features, but bails out on any\n *  possible side effect which might change the value being serialized.  The\n *  fast path can take advantage of the fact that the value being serialized\n *  is unchanged so that we can walk directly through property tables etc.\n */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\nDUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, duk_tval *tv) {\n\tduk_uint_fast32_t i, n;\n\n\tDUK_DDD(DUK_DDDPRINT(\"stringify fast: %!T\", tv));\n\n\tDUK_ASSERT(js_ctx != NULL);\n\tDUK_ASSERT(js_ctx->thr != NULL);\n\n#if 0 /* disabled for now */\n restart_match:\n#endif\n\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible) {\n\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined);\n\t\t\tbreak;\n\t\t} else {\n\t\t\tgoto emit_undefined;\n\t\t}\n#else\n\t\tgoto emit_undefined;\n#endif\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_TVAL_GET_BOOLEAN(tv) ?\n\t\t                 DUK_STRIDX_TRUE : DUK_STRIDX_FALSE);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tgoto emit_undefined;\n\t\t}\n\t\tduk__enc_quote_string(js_ctx, h);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *obj;\n\t\tduk_tval *tv_val;\n\t\tduk_bool_t emitted = 0;\n\t\tduk_uint32_t c_bit, c_all, c_array, c_unbox, c_undef,\n\t\t             c_func, c_bufobj, c_object, c_abort;\n\n\t\t/* For objects JSON.stringify() only looks for own, enumerable\n\t\t * properties which is nice for the fast path here.\n\t\t *\n\t\t * For arrays JSON.stringify() uses [[Get]] so it will actually\n\t\t * inherit properties during serialization!  This fast path\n\t\t * supports gappy arrays as long as there's no actual inherited\n\t\t * property (which might be a getter etc).\n\t\t *\n\t\t * Since recursion only happens for objects, we can have both\n\t\t * recursion and loop checks here.  We use a simple, depth-limited\n\t\t * loop check in the fast path because the object-based tracking\n\t\t * is very slow (when tested, it accounted for 50% of fast path\n\t\t * execution time for input data with a lot of small objects!).\n\t\t */\n\n\t\t/* XXX: for real world code, could just ignore array inheritance\n\t\t * and only look at array own properties.\n\t\t */\n\n\t\t/* We rely on a few object flag / class number relationships here,\n\t\t * assert for them.\n\t\t */\n\n\t\tobj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(obj != NULL);\n\t\tDUK_HOBJECT_ASSERT_VALID(obj);\n\n\t\t/* Once recursion depth is increased, exit path must decrease\n\t\t * it (though it's OK to abort the fast path).\n\t\t */\n\n\t\tDUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0);  /* unsigned */\n\t\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\t\tif (js_ctx->recursion_depth >= js_ctx->recursion_limit) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"fast path recursion limit\"));\n\t\t\tDUK_ERROR_RANGE(js_ctx->thr, DUK_STR_JSONDEC_RECLIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\n\t\tfor (i = 0, n = (duk_uint_fast32_t) js_ctx->recursion_depth; i < n; i++) {\n\t\t\tif (DUK_UNLIKELY(js_ctx->visiting[i] == obj)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"fast path loop detect\"));\n\t\t\t\tDUK_ERROR_TYPE(js_ctx->thr, DUK_STR_CYCLIC_INPUT);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\n\t\t/* Guaranteed by recursion_limit setup so we don't have to\n\t\t * check twice.\n\t\t */\n\t\tDUK_ASSERT(js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY);\n\t\tjs_ctx->visiting[js_ctx->recursion_depth] = obj;\n\t\tjs_ctx->recursion_depth++;\n\n\t\t/* If object has a .toJSON() property, we can't be certain\n\t\t * that it wouldn't mutate any value arbitrarily, so bail\n\t\t * out of the fast path.\n\t\t *\n\t\t * If an object is a Proxy we also can't avoid side effects\n\t\t * so abandon.\n\t\t */\n\t\t/* XXX: non-callable .toJSON() doesn't need to cause an abort\n\t\t * but does at the moment, probably not worth fixing.\n\t\t */\n\t\tif (duk_hobject_hasprop_raw(js_ctx->thr, obj, DUK_HTHREAD_STRING_TO_JSON(js_ctx->thr)) ||\n\t\t    DUK_HOBJECT_IS_PROXY(obj)) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"object has a .toJSON property or object is a Proxy, abort fast path\"));\n\t\t\tgoto abort_fastpath;\n\t\t}\n\n\t\t/* We could use a switch-case for the class number but it turns out\n\t\t * a small if-else ladder on class masks is better.  The if-ladder\n\t\t * should be in order of relevancy.\n\t\t */\n\n\t\t/* XXX: move masks to js_ctx? they don't change during one\n\t\t * fast path invocation.\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_CLASS_MAX <= 31);\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tc_all = DUK_HOBJECT_CMASK_ALL;\n\t\t\tc_array = DUK_HOBJECT_CMASK_ARRAY;\n\t\t\tc_unbox = DUK_HOBJECT_CMASK_NUMBER |\n\t\t\t          DUK_HOBJECT_CMASK_STRING |\n\t\t\t          DUK_HOBJECT_CMASK_BOOLEAN |\n\t\t\t          DUK_HOBJECT_CMASK_POINTER;  /* Symbols are not unboxed. */\n\t\t\tc_func = DUK_HOBJECT_CMASK_FUNCTION;\n\t\t\tc_bufobj = DUK_HOBJECT_CMASK_ALL_BUFOBJS;\n\t\t\tc_undef = 0;\n\t\t\tc_abort = 0;\n\t\t\tc_object = c_all & ~(c_array | c_unbox | c_func | c_bufobj | c_undef | c_abort);\n\t\t}\n\t\telse\n#endif\n\t\t{\n\t\t\tc_all = DUK_HOBJECT_CMASK_ALL;\n\t\t\tc_array = DUK_HOBJECT_CMASK_ARRAY;\n\t\t\tc_unbox = DUK_HOBJECT_CMASK_NUMBER |\n\t\t\t          DUK_HOBJECT_CMASK_STRING |\n\t\t\t          DUK_HOBJECT_CMASK_BOOLEAN;  /* Symbols are not unboxed. */\n\t\t\tc_func = 0;\n\t\t\tc_bufobj = 0;\n\t\t\tc_undef = DUK_HOBJECT_CMASK_FUNCTION |\n\t\t\t          DUK_HOBJECT_CMASK_POINTER;\n\t\t\t/* As the fast path doesn't currently properly support\n\t\t\t * duk_hbufobj virtual properties, abort fast path if\n\t\t\t * we encounter them in plain JSON mode.\n\t\t\t */\n\t\t\tc_abort = DUK_HOBJECT_CMASK_ALL_BUFOBJS;\n\t\t\tc_object = c_all & ~(c_array | c_unbox | c_func | c_bufobj | c_undef | c_abort);\n\t\t}\n\n\t\tc_bit = (duk_uint32_t) DUK_HOBJECT_GET_CLASS_MASK(obj);\n\t\tif (c_bit & c_object) {\n\t\t\t/* All other object types. */\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);\n\n\t\t\t/* A non-Array object should not have an array part in practice.\n\t\t\t * But since it is supported internally (and perhaps used at some\n\t\t\t * point), check and abandon if that's the case.\n\t\t\t */\n\t\t\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"non-Array object has array part, abort fast path\"));\n\t\t\t\tgoto abort_fastpath;\n\t\t\t}\n\n\t\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\t\tduk_hstring *k;\n\t\t\t\tduk_size_t prev_size;\n\n\t\t\t\tk = DUK_HOBJECT_E_GET_KEY(js_ctx->thr->heap, obj, i);\n\t\t\t\tif (!k) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (DUK_HSTRING_HAS_ARRIDX(k)) {\n\t\t\t\t\t/* If an object has array index keys we would need\n\t\t\t\t\t * to sort them into the ES2015 enumeration order to\n\t\t\t\t\t * be consistent with the slow path.  Abort the fast\n\t\t\t\t\t * path and handle in the slow path for now.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"property key is an array index, abort fast path\"));\n\t\t\t\t\tgoto abort_fastpath;\n\t\t\t\t}\n\t\t\t\tif (!DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(js_ctx->thr->heap, obj, i)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(js_ctx->thr->heap, obj, i)) {\n\t\t\t\t\t/* Getter might have arbitrary side effects,\n\t\t\t\t\t * so bail out.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"property is an accessor, abort fast path\"));\n\t\t\t\t\tgoto abort_fastpath;\n\t\t\t\t}\n\t\t\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(k))) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\ttv_val = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(js_ctx->thr->heap, obj, i);\n\n\t\t\t\tprev_size = DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw);\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t\t\t\tduk__enc_key_autoquote(js_ctx, k);\n\t\t\t\t\tDUK__EMIT_2(js_ctx, DUK_ASC_COLON, DUK_ASC_SPACE);\n\t\t\t\t} else {\n\t\t\t\t\tduk__enc_key_autoquote(js_ctx, k);\n\t\t\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COLON);\n\t\t\t\t}\n\n\t\t\t\tif (duk__json_stringify_fast_value(js_ctx, tv_val) == 0) {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"prop value not supported, rewind key and colon\"));\n\t\t\t\t\tDUK_BW_SET_SIZE(js_ctx->thr, &js_ctx->bw, prev_size);\n\t\t\t\t} else {\n\t\t\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\t\t\t\temitted = 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* If any non-Array value had enumerable virtual own\n\t\t\t * properties, they should be serialized here (actually,\n\t\t\t * before the explicit properties).  Standard types don't.\n\t\t\t */\n\n\t\t\tif (emitted) {\n\t\t\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\t\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t\t\t}\n\t\t\t}\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);\n\t\t} else if (c_bit & c_array) {\n\t\t\tduk_uint_fast32_t arr_len;\n\t\t\tduk_uint_fast32_t asize;\n\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_LBRACKET);\n\n\t\t\t/* Assume arrays are dense in the fast path. */\n\t\t\tif (!DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"Array object is sparse, abort fast path\"));\n\t\t\t\tgoto abort_fastpath;\n\t\t\t}\n\n\t\t\tarr_len = (duk_uint_fast32_t) ((duk_harray *) obj)->length;\n\t\t\tasize = (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(obj);\n\t\t\t/* Array part may be larger than 'length'; if so, iterate\n\t\t\t * only up to array 'length'.  Array part may also be smaller\n\t\t\t * than 'length' in some cases.\n\t\t\t */\n\t\t\tfor (i = 0; i < arr_len; i++) {\n\t\t\t\tduk_tval *tv_arrval;\n\t\t\t\tduk_hstring *h_tmp;\n\t\t\t\tduk_bool_t has_inherited;\n\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t\t\t}\n\n\t\t\t\tif (DUK_LIKELY(i < asize)) {\n\t\t\t\t\ttv_arrval = DUK_HOBJECT_A_GET_VALUE_PTR(js_ctx->thr->heap, obj, i);\n\t\t\t\t\tif (DUK_LIKELY(!DUK_TVAL_IS_UNUSED(tv_arrval))) {\n\t\t\t\t\t\t/* Expected case: element is present. */\n\t\t\t\t\t\tif (duk__json_stringify_fast_value(js_ctx, tv_arrval) == 0) {\n\t\t\t\t\t\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tgoto elem_done;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* Gap in array; check for inherited property,\n\t\t\t\t * bail out if one exists.  This should be enough\n\t\t\t\t * to support gappy arrays for all practical code.\n\t\t\t\t */\n\n\t\t\t\th_tmp = duk_push_uint_to_hstring(js_ctx->thr, (duk_uint_t) i);\n\t\t\t\thas_inherited = duk_hobject_hasprop_raw(js_ctx->thr, obj, h_tmp);\n\t\t\t\tduk_pop(js_ctx->thr);\n\t\t\t\tif (has_inherited) {\n\t\t\t\t\tDUK_D(DUK_DPRINT(\"gap in array, conflicting inherited property, abort fast path\"));\n\t\t\t\t\tgoto abort_fastpath;\n\t\t\t\t}\n\n\t\t\t\t/* Ordinary gap, undefined encodes to 'null' in\n\t\t\t\t * standard JSON, but JX/JC use their form for\n\t\t\t\t * undefined to better preserve the typing.\n\t\t\t\t */\n\t\t\t\tDUK_D(DUK_DPRINT(\"gap in array, no conflicting inherited property, remain on fast path\"));\n#if defined(DUK_USE_JX)\n\t\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined);\n#else\n\t\t\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n#endif\n\t\t\t\t/* fall through */\n\n\t\t\t elem_done:\n\t\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\t\t\temitted = 1;\n\t\t\t}\n\n\t\t\tif (emitted) {\n\t\t\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\t\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t\t\t}\n\t\t\t}\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET);\n\t\t} else if (c_bit & c_unbox) {\n\t\t\t/* Certain boxed types are required to go through\n\t\t\t * automatic unboxing.  Rely on internal value being\n\t\t\t * sane (to avoid infinite recursion).\n\t\t\t */\n\t\t\tDUK_ASSERT((c_bit & DUK_HOBJECT_CMASK_SYMBOL) == 0);  /* Symbols are not unboxed. */\n\n#if 1\n\t\t\t/* The code below is incorrect if .toString() or .valueOf() have\n\t\t\t * have been overridden.  The correct approach would be to look up\n\t\t\t * the method(s) and if they resolve to the built-in function we\n\t\t\t * can safely bypass it and look up the internal value directly.\n\t\t\t * Unimplemented for now, abort fast path for boxed values.\n\t\t\t */\n\t\t\tgoto abort_fastpath;\n#else  /* disabled */\n\t\t\t/* Disabled until fixed, see above. */\n\t\t\tduk_tval *tv_internal;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"auto unboxing in fast path\"));\n\n\t\t\ttv_internal = duk_hobject_get_internal_value_tval_ptr(js_ctx->thr->heap, obj);\n\t\t\tDUK_ASSERT(tv_internal != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_internal) ||\n\t\t\t           DUK_TVAL_IS_NUMBER(tv_internal) ||\n\t\t\t           DUK_TVAL_IS_BOOLEAN(tv_internal) ||\n\t\t\t           DUK_TVAL_IS_POINTER(tv_internal));\n\n\t\t\ttv = tv_internal;\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\t\t\tjs_ctx->recursion_depth--;  /* required to keep recursion depth correct */\n\t\t\tgoto restart_match;\n#endif  /* disabled */\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t} else if (c_bit & c_func) {\n\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t} else if (c_bit & c_bufobj) {\n\t\t\tduk__enc_bufobj(js_ctx, (duk_hbufobj *) obj);\n#endif\n#endif\n\t\t} else if (c_bit & c_abort) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"abort fast path for unsupported type\"));\n\t\t\tgoto abort_fastpath;\n\t\t} else {\n\t\t\tDUK_ASSERT((c_bit & c_undef) != 0);\n\n\t\t\t/* Must decrease recursion depth before returning. */\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\t\t\tjs_ctx->recursion_depth--;\n\t\t\tgoto emit_undefined;\n\t\t}\n\n\t\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\t\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\t\tjs_ctx->recursion_depth--;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\t/* Plain buffers are treated like Uint8Arrays: they have\n\t\t * enumerable indices.  Other virtual properties are not\n\t\t * enumerable, and inherited properties are not serialized.\n\t\t * However, there can be a replacer (not relevant here) or\n\t\t * a .toJSON() method (which we need to check for explicitly).\n\t\t */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (duk_hobject_hasprop_raw(js_ctx->thr,\n\t\t                            js_ctx->thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE],\n\t\t                            DUK_HTHREAD_STRING_TO_JSON(js_ctx->thr))) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"value is a plain buffer and there's an inherited .toJSON, abort fast path\"));\n\t\t\tgoto abort_fastpath;\n\t\t}\n#endif\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tduk__enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv));\n\t\t\tbreak;\n\t\t}\n#endif\n\n\t\t/* Plain buffers mimic Uint8Arrays, and have enumerable index\n\t\t * properties.\n\t\t */\n\t\tduk__enc_buffer_json_fastpath(js_ctx, DUK_TVAL_GET_BUFFER(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_POINTER: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tduk__enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv));\n\t\t\tbreak;\n\t\t} else {\n\t\t\tgoto emit_undefined;\n\t\t}\n#else\n\t\tgoto emit_undefined;\n#endif\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* A lightfunc might also inherit a .toJSON() so just bail out. */\n\t\t/* XXX: Could just lookup .toJSON() and continue in fast path,\n\t\t * as it would almost never be defined.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"value is a lightfunc, abort fast path\"));\n\t\tgoto abort_fastpath;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT: {\n\t\t/* Number serialization has a significant impact relative to\n\t\t * other fast path code, so careful fast path for fastints.\n\t\t */\n\t\tduk__enc_fastint_tval(js_ctx, tv);\n\t\tbreak;\n\t}\n#endif\n\tdefault: {\n\t\t/* XXX: A fast path for usual integers would be useful when\n\t\t * fastint support is not enabled.\n\t\t */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\n\t\t/* XXX: Stack discipline is annoying, could be changed in numconv. */\n\t\tduk_push_tval(js_ctx->thr, tv);\n\t\tduk__enc_double(js_ctx);\n\t\tduk_pop(js_ctx->thr);\n\n#if 0\n\t\t/* Could also rely on native sprintf(), but it will handle\n\t\t * values like NaN, Infinity, -0, exponent notation etc in\n\t\t * a JSON-incompatible way.\n\t\t */\n\t\tduk_double_t d;\n\t\tchar buf[64];\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\t\td = DUK_TVAL_GET_DOUBLE(tv);\n\t\tDUK_SPRINTF(buf, \"%lg\", d);\n\t\tDUK__EMIT_CSTR(js_ctx, buf);\n#endif\n\t}\n\t}\n\treturn 1;  /* not undefined */\n\n emit_undefined:\n\treturn 0;  /* value was undefined/unsupported */\n\n abort_fastpath:\n\t/* Error message doesn't matter: the error is ignored anyway. */\n\tDUK_DD(DUK_DDPRINT(\"aborting fast path\"));\n\tDUK_ERROR_INTERNAL(js_ctx->thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_LOCAL duk_ret_t duk__json_stringify_fast(duk_hthread *thr, void *udata) {\n\tduk_json_enc_ctx *js_ctx;\n\tduk_tval *tv;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(udata != NULL);\n\n\tjs_ctx = (duk_json_enc_ctx *) udata;\n\tDUK_ASSERT(js_ctx != NULL);\n\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tif (duk__json_stringify_fast_value(js_ctx, tv) == 0) {\n\t\tDUK_DD(DUK_DDPRINT(\"top level value not supported, fail fast path\"));\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);  /* Error message is ignored, so doesn't matter. */\n\t}\n\n\treturn 0;\n}\n#endif  /* DUK_USE_JSON_STRINGIFY_FASTPATH */\n\n/*\n *  Top level wrappers\n */\n\nDUK_INTERNAL\nvoid duk_bi_json_parse_helper(duk_hthread *thr,\n                              duk_idx_t idx_value,\n                              duk_idx_t idx_reviver,\n                              duk_small_uint_t flags) {\n\tduk_json_dec_ctx js_ctx_alloc;\n\tduk_json_dec_ctx *js_ctx = &js_ctx_alloc;\n\tduk_hstring *h_text;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top = duk_get_top(thr);\n#endif\n\n\t/* negative top-relative indices not allowed now */\n\tDUK_ASSERT(idx_value == DUK_INVALID_INDEX || idx_value >= 0);\n\tDUK_ASSERT(idx_reviver == DUK_INVALID_INDEX || idx_reviver >= 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON parse start: text=%!T, reviver=%!T, flags=0x%08lx, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_reviver),\n\t                     (unsigned long) flags,\n\t                     (long) duk_get_top(thr)));\n\n\tduk_memzero(&js_ctx_alloc, sizeof(js_ctx_alloc));\n\tjs_ctx->thr = thr;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t/* nothing now */\n#endif\n\tjs_ctx->recursion_limit = DUK_USE_JSON_DEC_RECLIMIT;\n\tDUK_ASSERT(js_ctx->recursion_depth == 0);\n\n\t/* Flag handling currently assumes that flags are consistent.  This is OK\n\t * because the call sites are now strictly controlled.\n\t */\n\n\tjs_ctx->flags = flags;\n#if defined(DUK_USE_JX)\n\tjs_ctx->flag_ext_custom = flags & DUK_JSON_FLAG_EXT_CUSTOM;\n#endif\n#if defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_compatible = flags & DUK_JSON_FLAG_EXT_COMPATIBLE;\n#endif\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_custom_or_compatible = flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE);\n#endif\n\n\th_text = duk_to_hstring(thr, idx_value);  /* coerce in-place; rejects Symbols */\n\tDUK_ASSERT(h_text != NULL);\n\n\t/* JSON parsing code is allowed to read [p_start,p_end]: p_end is\n\t * valid and points to the string NUL terminator (which is always\n\t * guaranteed for duk_hstrings.\n\t */\n\tjs_ctx->p_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_text);\n\tjs_ctx->p = js_ctx->p_start;\n\tjs_ctx->p_end = ((const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_text)) +\n\t                DUK_HSTRING_GET_BYTELEN(h_text);\n\tDUK_ASSERT(*(js_ctx->p_end) == 0x00);\n\n\tduk__dec_value(js_ctx);  /* -> [ ... value ] */\n\n\t/* Trailing whitespace has been eaten by duk__dec_value(), so if\n\t * we're not at end of input here, it's a SyntaxError.\n\t */\n\n\tif (js_ctx->p != js_ctx->p_end) {\n\t\tduk__dec_syntax_error(js_ctx);\n\t}\n\n\tif (duk_is_callable(thr, idx_reviver)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"applying reviver: %!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_reviver)));\n\n\t\tjs_ctx->idx_reviver = idx_reviver;\n\n\t\tduk_push_object(thr);\n\t\tduk_dup_m2(thr);  /* -> [ ... val root val ] */\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_EMPTY_STRING);  /* default attrs ok */\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_EMPTY_STRING);  /* -> [ ... val root \"\" ] */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"start reviver walk, root=%!T, name=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\tduk__dec_reviver_walk(js_ctx);  /* [ ... val root \"\" ] -> [ ... val val' ] */\n\t\tduk_remove_m2(thr);             /* -> [ ... val' ] */\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"reviver does not exist or is not callable: %!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_reviver)));\n\t}\n\n\t/* Final result is at stack top. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON parse end: text=%!T, reviver=%!T, flags=0x%08lx, result=%!T, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_reviver),\n\t                     (unsigned long) flags,\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (long) duk_get_top(thr)));\n\n\tDUK_ASSERT(duk_get_top(thr) == entry_top + 1);\n}\n\nDUK_INTERNAL\nvoid duk_bi_json_stringify_helper(duk_hthread *thr,\n                                  duk_idx_t idx_value,\n                                  duk_idx_t idx_replacer,\n                                  duk_idx_t idx_space,\n                                  duk_small_uint_t flags) {\n\tduk_json_enc_ctx js_ctx_alloc;\n\tduk_json_enc_ctx *js_ctx = &js_ctx_alloc;\n\tduk_hobject *h;\n\tduk_idx_t idx_holder;\n\tduk_idx_t entry_top;\n\n\t/* negative top-relative indices not allowed now */\n\tDUK_ASSERT(idx_value == DUK_INVALID_INDEX || idx_value >= 0);\n\tDUK_ASSERT(idx_replacer == DUK_INVALID_INDEX || idx_replacer >= 0);\n\tDUK_ASSERT(idx_space == DUK_INVALID_INDEX || idx_space >= 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON stringify start: value=%!T, replacer=%!T, space=%!T, flags=0x%08lx, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_replacer),\n\t                     (duk_tval *) duk_get_tval(thr, idx_space),\n\t                     (unsigned long) flags,\n\t                     (long) duk_get_top(thr)));\n\n\tentry_top = duk_get_top(thr);\n\n\t/*\n\t *  Context init\n\t */\n\n\tduk_memzero(&js_ctx_alloc, sizeof(js_ctx_alloc));\n\tjs_ctx->thr = thr;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tjs_ctx->h_replacer = NULL;\n\tjs_ctx->h_gap = NULL;\n#endif\n\tjs_ctx->idx_proplist = -1;\n\n\t/* Flag handling currently assumes that flags are consistent.  This is OK\n\t * because the call sites are now strictly controlled.\n\t */\n\n\tjs_ctx->flags = flags;\n\tjs_ctx->flag_ascii_only = flags & DUK_JSON_FLAG_ASCII_ONLY;\n\tjs_ctx->flag_avoid_key_quotes = flags & DUK_JSON_FLAG_AVOID_KEY_QUOTES;\n#if defined(DUK_USE_JX)\n\tjs_ctx->flag_ext_custom = flags & DUK_JSON_FLAG_EXT_CUSTOM;\n#endif\n#if defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_compatible = flags & DUK_JSON_FLAG_EXT_COMPATIBLE;\n#endif\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_custom_or_compatible = flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE);\n#endif\n\n\t/* The #if defined() clutter here handles the JX/JC enable/disable\n\t * combinations properly.\n\t */\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tjs_ctx->stridx_custom_undefined = DUK_STRIDX_LC_NULL;  /* standard JSON; array gaps */\n#if defined(DUK_USE_JX)\n\tif (flags & DUK_JSON_FLAG_EXT_CUSTOM) {\n\t\tjs_ctx->stridx_custom_undefined = DUK_STRIDX_LC_UNDEFINED;\n\t\tjs_ctx->stridx_custom_nan = DUK_STRIDX_NAN;\n\t\tjs_ctx->stridx_custom_neginf = DUK_STRIDX_MINUS_INFINITY;\n\t\tjs_ctx->stridx_custom_posinf = DUK_STRIDX_INFINITY;\n\t\tjs_ctx->stridx_custom_function =\n\t\t        (flags & DUK_JSON_FLAG_AVOID_KEY_QUOTES) ?\n\t\t                DUK_STRIDX_JSON_EXT_FUNCTION2 :\n\t\t                DUK_STRIDX_JSON_EXT_FUNCTION1;\n\t}\n#endif  /* DUK_USE_JX */\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\telse\n#endif  /* DUK_USE_JX && DUK_USE_JC */\n#if defined(DUK_USE_JC)\n\tif (js_ctx->flags & DUK_JSON_FLAG_EXT_COMPATIBLE) {\n\t\tjs_ctx->stridx_custom_undefined = DUK_STRIDX_JSON_EXT_UNDEFINED;\n\t\tjs_ctx->stridx_custom_nan = DUK_STRIDX_JSON_EXT_NAN;\n\t\tjs_ctx->stridx_custom_neginf = DUK_STRIDX_JSON_EXT_NEGINF;\n\t\tjs_ctx->stridx_custom_posinf = DUK_STRIDX_JSON_EXT_POSINF;\n\t\tjs_ctx->stridx_custom_function = DUK_STRIDX_JSON_EXT_FUNCTION1;\n\t}\n#endif  /* DUK_USE_JC */\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tif (js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM |\n\t                     DUK_JSON_FLAG_EXT_COMPATIBLE)) {\n\t\tDUK_ASSERT(js_ctx->mask_for_undefined == 0);  /* already zero */\n\t}\n\telse\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\t{\n\t\t/* Plain buffer is treated like ArrayBuffer and serialized.\n\t\t * Lightfuncs are treated like objects, but JSON explicitly\n\t\t * skips serializing Function objects so we can just reject\n\t\t * lightfuncs here.\n\t\t */\n\t\tjs_ctx->mask_for_undefined = DUK_TYPE_MASK_UNDEFINED |\n\t\t                             DUK_TYPE_MASK_POINTER |\n\t\t                             DUK_TYPE_MASK_LIGHTFUNC;\n\t}\n\n\tDUK_BW_INIT_PUSHBUF(thr, &js_ctx->bw, DUK__JSON_STRINGIFY_BUFSIZE);\n\n\tjs_ctx->idx_loop = duk_push_bare_object(thr);\n\tDUK_ASSERT(js_ctx->idx_loop >= 0);\n\n\t/* [ ... buf loop ] */\n\n\t/*\n\t *  Process replacer/proplist (2nd argument to JSON.stringify)\n\t */\n\n\th = duk_get_hobject(thr, idx_replacer);\n\tif (h != NULL) {\n\t\tif (DUK_HOBJECT_IS_CALLABLE(h)) {\n\t\t\tjs_ctx->h_replacer = h;\n\t\t} else if (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\t/* Here the specification requires correct array index enumeration\n\t\t\t * which is a bit tricky for sparse arrays (it is handled by the\n\t\t\t * enum setup code).  We now enumerate ancestors too, although the\n\t\t\t * specification is not very clear on whether that is required.\n\t\t\t */\n\n\t\t\tduk_uarridx_t plist_idx = 0;\n\t\t\tduk_small_uint_t enum_flags;\n\n\t\t\tjs_ctx->idx_proplist = duk_push_array(thr);  /* XXX: array internal? */\n\n\t\t\tenum_flags = DUK_ENUM_ARRAY_INDICES_ONLY |\n\t\t\t             DUK_ENUM_SORT_ARRAY_INDICES;  /* expensive flag */\n\t\t\tduk_enum(thr, idx_replacer, enum_flags);\n\t\t\twhile (duk_next(thr, -1 /*enum_index*/, 1 /*get_value*/)) {\n\t\t\t\t/* [ ... proplist enum_obj key val ] */\n\t\t\t\tif (duk__enc_allow_into_proplist(duk_get_tval(thr, -1))) {\n\t\t\t\t\t/* XXX: duplicates should be eliminated here */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proplist enum: key=%!T, val=%!T --> accept\",\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\t\t\tduk_to_string(thr, -1);  /* extra coercion of strings is OK */\n\t\t\t\t\tduk_put_prop_index(thr, -4, plist_idx);  /* -> [ ... proplist enum_obj key ] */\n\t\t\t\t\tplist_idx++;\n\t\t\t\t\tduk_pop(thr);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proplist enum: key=%!T, val=%!T --> reject\",\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\t\t\tduk_pop_2(thr);\n\t\t\t\t}\n                        }\n                        duk_pop(thr);  /* pop enum */\n\n\t\t\t/* [ ... proplist ] */\n\t\t}\n\t}\n\n\t/* [ ... buf loop (proplist) ] */\n\n\t/*\n\t *  Process space (3rd argument to JSON.stringify)\n\t */\n\n\th = duk_get_hobject(thr, idx_space);\n\tif (h != NULL) {\n\t\tduk_small_uint_t c = DUK_HOBJECT_GET_CLASS_NUMBER(h);\n\t\tif (c == DUK_HOBJECT_CLASS_NUMBER) {\n\t\t\tduk_to_number(thr, idx_space);\n\t\t} else if (c == DUK_HOBJECT_CLASS_STRING) {\n\t\t\tduk_to_string(thr, idx_space);\n\t\t}\n\t}\n\n\tif (duk_is_number(thr, idx_space)) {\n\t\tduk_small_int_t nspace;\n\t\t/* spaces[] must be static to allow initializer with old compilers like BCC */\n\t\tstatic const char spaces[10] = {\n\t\t\tDUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE,\n\t\t\tDUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE,\n\t\t\tDUK_ASC_SPACE, DUK_ASC_SPACE\n\t\t};  /* XXX: helper */\n\n\t\t/* ToInteger() coercion; NaN -> 0, infinities are clamped to 0 and 10 */\n\t\tnspace = (duk_small_int_t) duk_to_int_clamped(thr, idx_space, 0 /*minval*/, 10 /*maxval*/);\n\t\tDUK_ASSERT(nspace >= 0 && nspace <= 10);\n\n\t\tduk_push_lstring(thr, spaces, (duk_size_t) nspace);\n\t\tjs_ctx->h_gap = duk_known_hstring(thr, -1);\n\t\tDUK_ASSERT(js_ctx->h_gap != NULL);\n\t} else if (duk_is_string_notsymbol(thr, idx_space)) {\n\t\tduk_dup(thr, idx_space);\n\t\tduk_substring(thr, -1, 0, 10);  /* clamp to 10 chars */\n\t\tjs_ctx->h_gap = duk_known_hstring(thr, -1);\n\t} else {\n\t\t/* nop */\n\t}\n\n\tif (js_ctx->h_gap != NULL) {\n\t\t/* If gap is empty, behave as if not given at all.  Check\n\t\t * against byte length because character length is more\n\t\t * expensive.\n\t\t */\n\t\tif (DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) == 0) {\n\t\t\tjs_ctx->h_gap = NULL;\n\t\t}\n\t}\n\n\t/* [ ... buf loop (proplist) (gap) ] */\n\n\t/*\n\t *  Fast path: assume no mutation, iterate object property tables\n\t *  directly; bail out if that assumption doesn't hold.\n\t */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\n\tif (js_ctx->h_replacer == NULL &&  /* replacer is a mutation risk */\n\t    js_ctx->idx_proplist == -1) {  /* proplist is very rare */\n\t\tduk_int_t pcall_rc;\n\t\tduk_small_uint_t prev_ms_base_flags;\n\n\t\tDUK_DD(DUK_DDPRINT(\"try JSON.stringify() fast path\"));\n\n\t\t/* Use recursion_limit to ensure we don't overwrite js_ctx->visiting[]\n\t\t * array so we don't need two counter checks in the fast path.  The\n\t\t * slow path has a much larger recursion limit which we'll use if\n\t\t * necessary.\n\t\t */\n\t\tDUK_ASSERT(DUK_USE_JSON_ENC_RECLIMIT >= DUK_JSON_ENC_LOOPARRAY);\n\t\tjs_ctx->recursion_limit = DUK_JSON_ENC_LOOPARRAY;\n\t\tDUK_ASSERT(js_ctx->recursion_depth == 0);\n\n\t\t/* Execute the fast path in a protected call.  If any error is thrown,\n\t\t * fall back to the slow path.  This includes e.g. recursion limit\n\t\t * because the fast path has a smaller recursion limit (and simpler,\n\t\t * limited loop detection).\n\t\t */\n\n\t\tduk_dup(thr, idx_value);\n\n\t\t/* Must prevent finalizers which may have arbitrary side effects. */\n\t\tprev_ms_base_flags = thr->heap->ms_base_flags;\n\t\tthr->heap->ms_base_flags |=\n\t\t        DUK_MS_FLAG_NO_OBJECT_COMPACTION;      /* Avoid attempt to compact any objects. */\n\t\tthr->heap->pf_prevent_count++;                 /* Prevent finalizers. */\n\t\tDUK_ASSERT(thr->heap->pf_prevent_count != 0);  /* Wrap. */\n\n\t\tpcall_rc = duk_safe_call(thr, duk__json_stringify_fast, (void *) js_ctx /*udata*/, 1 /*nargs*/, 0 /*nret*/);\n\n\t\tDUK_ASSERT(thr->heap->pf_prevent_count > 0);\n\t\tthr->heap->pf_prevent_count--;\n\t\tthr->heap->ms_base_flags = prev_ms_base_flags;\n\n\t\tif (pcall_rc == DUK_EXEC_SUCCESS) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"fast path successful\"));\n\t\t\tDUK_BW_PUSH_AS_STRING(thr, &js_ctx->bw);\n\t\t\tgoto replace_finished;\n\t\t}\n\n\t\t/* We come here for actual aborts (like encountering .toJSON())\n\t\t * but also for recursion/loop errors.  Bufwriter size can be\n\t\t * kept because we'll probably need at least as much as we've\n\t\t * allocated so far.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"fast path failed, serialize using slow path instead\"));\n\t\tDUK_BW_RESET_SIZE(thr, &js_ctx->bw);\n\t\tjs_ctx->recursion_depth = 0;\n\t}\n#endif\n\n\t/*\n\t *  Create wrapper object and serialize\n\t */\n\n\tidx_holder = duk_push_object(thr);\n\tduk_dup(thr, idx_value);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_EMPTY_STRING);\n\n\tDUK_DDD(DUK_DDDPRINT(\"before: flags=0x%08lx, loop=%!T, replacer=%!O, \"\n\t                     \"proplist=%!T, gap=%!O, holder=%!T\",\n\t                     (unsigned long) js_ctx->flags,\n\t                     (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop),\n\t                     (duk_heaphdr *) js_ctx->h_replacer,\n\t                     (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(thr, js_ctx->idx_proplist) : NULL),\n\t                     (duk_heaphdr *) js_ctx->h_gap,\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* serialize the wrapper with empty string key */\n\n\tduk_push_hstring_empty(thr);\n\n\t/* [ ... buf loop (proplist) (gap) holder \"\" ] */\n\n\tjs_ctx->recursion_limit = DUK_USE_JSON_ENC_RECLIMIT;\n\tDUK_ASSERT(js_ctx->recursion_depth == 0);\n\n\tif (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_holder) == 0)) {  /* [ ... holder key ] -> [ ... holder ] */\n\t\t/* Result is undefined. */\n\t\tduk_push_undefined(thr);\n\t} else {\n\t\t/* Convert buffer to result string. */\n\t\tDUK_BW_PUSH_AS_STRING(thr, &js_ctx->bw);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"after: flags=0x%08lx, loop=%!T, replacer=%!O, \"\n\t                     \"proplist=%!T, gap=%!O, holder=%!T\",\n\t                     (unsigned long) js_ctx->flags,\n\t                     (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop),\n\t                     (duk_heaphdr *) js_ctx->h_replacer,\n\t                     (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(thr, js_ctx->idx_proplist) : NULL),\n\t                     (duk_heaphdr *) js_ctx->h_gap,\n\t                     (duk_tval *) duk_get_tval(thr, idx_holder)));\n\n\t/* The stack has a variable shape here, so force it to the\n\t * desired one explicitly.\n\t */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\n replace_finished:\n#endif\n\tduk_replace(thr, entry_top);\n\tduk_set_top(thr, entry_top + 1);\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON stringify end: value=%!T, replacer=%!T, space=%!T, \"\n\t                     \"flags=0x%08lx, result=%!T, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_replacer),\n\t                     (duk_tval *) duk_get_tval(thr, idx_space),\n\t                     (unsigned long) flags,\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (long) duk_get_top(thr)));\n\n\tDUK_ASSERT(duk_get_top(thr) == entry_top + 1);\n}\n\n#if defined(DUK_USE_JSON_BUILTIN)\n\n/*\n *  Entry points\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_json_object_parse(duk_hthread *thr) {\n\tduk_bi_json_parse_helper(thr,\n\t                         0 /*idx_value*/,\n\t                         1 /*idx_replacer*/,\n\t                         0 /*flags*/);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_json_object_stringify(duk_hthread *thr) {\n\tduk_bi_json_stringify_helper(thr,\n\t                             0 /*idx_value*/,\n\t                             1 /*idx_replacer*/,\n\t                             2 /*idx_space*/,\n\t                             0 /*flags*/);\n\treturn 1;\n}\n\n#endif  /* DUK_USE_JSON_BUILTIN */\n\n#endif  /* DUK_USE_JSON_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_math.c",
    "content": "/*\n *  Math built-ins\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_MATH_BUILTIN)\n\n/*\n *  Use static helpers which can work with math.h functions matching\n *  the following signatures. This is not portable if any of these math\n *  functions is actually a macro.\n *\n *  Typing here is intentionally 'double' wherever values interact with\n *  the standard library APIs.\n */\n\ntypedef double (*duk__one_arg_func)(double);\ntypedef double (*duk__two_arg_func)(double, double);\n\nDUK_LOCAL duk_ret_t duk__math_minmax(duk_hthread *thr, duk_double_t initial, duk__two_arg_func min_max) {\n\tduk_idx_t n = duk_get_top(thr);\n\tduk_idx_t i;\n\tduk_double_t res = initial;\n\tduk_double_t t;\n\n\t/*\n\t *  Note: fmax() does not match the E5 semantics.  E5 requires\n\t *  that if -any- input to Math.max() is a NaN, the result is a\n\t *  NaN.  fmax() will return a NaN only if -both- inputs are NaN.\n\t *  Same applies to fmin().\n\t *\n\t *  Note: every input value must be coerced with ToNumber(), even\n\t *  if we know the result will be a NaN anyway: ToNumber() may have\n\t *  side effects for which even order of evaluation matters.\n\t */\n\n\tfor (i = 0; i < n; i++) {\n\t\tt = duk_to_number(thr, i);\n\t\tif (DUK_FPCLASSIFY(t) == DUK_FP_NAN || DUK_FPCLASSIFY(res) == DUK_FP_NAN) {\n\t\t\t/* Note: not normalized, but duk_push_number() will normalize */\n\t\t\tres = (duk_double_t) DUK_DOUBLE_NAN;\n\t\t} else {\n\t\t\tres = (duk_double_t) min_max(res, (double) t);\n\t\t}\n\t}\n\n\tduk_push_number(thr, res);\n\treturn 1;\n}\n\nDUK_LOCAL double duk__fmin_fixed(double x, double y) {\n\t/* fmin() with args -0 and +0 is not guaranteed to return\n\t * -0 as ECMAScript requires.\n\t */\n\tif (x == 0 && y == 0) {\n\t\tduk_double_union du1, du2;\n\t\tdu1.d = x;\n\t\tdu2.d = y;\n\n\t\t/* Already checked to be zero so these must hold, and allow us\n\t\t * to check for \"x is -0 or y is -0\" by ORing the high parts\n\t\t * for comparison.\n\t\t */\n\t\tDUK_ASSERT(du1.ui[DUK_DBL_IDX_UI0] == 0 || du1.ui[DUK_DBL_IDX_UI0] == 0x80000000UL);\n\t\tDUK_ASSERT(du2.ui[DUK_DBL_IDX_UI0] == 0 || du2.ui[DUK_DBL_IDX_UI0] == 0x80000000UL);\n\n\t\t/* XXX: what's the safest way of creating a negative zero? */\n\t\tif ((du1.ui[DUK_DBL_IDX_UI0] | du2.ui[DUK_DBL_IDX_UI0]) != 0) {\n\t\t\t/* Enter here if either x or y (or both) is -0. */\n\t\t\treturn -0.0;\n\t\t} else {\n\t\t\treturn +0.0;\n\t\t}\n\t}\n\treturn duk_double_fmin(x, y);\n}\n\nDUK_LOCAL double duk__fmax_fixed(double x, double y) {\n\t/* fmax() with args -0 and +0 is not guaranteed to return\n\t * +0 as ECMAScript requires.\n\t */\n\tif (x == 0 && y == 0) {\n\t\tif (DUK_SIGNBIT(x) == 0 || DUK_SIGNBIT(y) == 0) {\n\t\t\treturn +0.0;\n\t\t} else {\n\t\t\treturn -0.0;\n\t\t}\n\t}\n\treturn duk_double_fmax(x, y);\n}\n\n#if defined(DUK_USE_ES6)\nDUK_LOCAL double duk__cbrt(double x) {\n\t/* cbrt() is C99.  To avoid hassling embedders with the need to provide a\n\t * cube root function, we can get by with pow().  The result is not\n\t * identical, but that's OK: ES2015 says it's implementation-dependent.\n\t */\n\n#if defined(DUK_CBRT)\n\t/* cbrt() matches ES2015 requirements. */\n\treturn DUK_CBRT(x);\n#else\n\tduk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\n\t/* pow() does not, however. */\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE || c == DUK_FP_ZERO) {\n\t\treturn x;\n\t}\n\tif (DUK_SIGNBIT(x)) {\n\t\treturn -DUK_POW(-x, 1.0 / 3.0);\n\t} else {\n\t\treturn DUK_POW(x, 1.0 / 3.0);\n\t}\n#endif\n}\n\nDUK_LOCAL double duk__log2(double x) {\n#if defined(DUK_LOG2)\n\treturn DUK_LOG2(x);\n#else\n\treturn DUK_LOG(x) * DUK_DOUBLE_LOG2E;\n#endif\n}\n\nDUK_LOCAL double duk__log10(double x) {\n#if defined(DUK_LOG10)\n\treturn DUK_LOG10(x);\n#else\n\treturn DUK_LOG(x) * DUK_DOUBLE_LOG10E;\n#endif\n}\n\nDUK_LOCAL double duk__trunc(double x) {\n#if defined(DUK_TRUNC)\n\treturn DUK_TRUNC(x);\n#else\n\t/* Handles -0 correctly: -0.0 matches 'x >= 0.0' but floor()\n\t * is required to return -0 when the argument is -0.\n\t */\n\treturn x >= 0.0 ? DUK_FLOOR(x) : DUK_CEIL(x);\n#endif\n}\n#endif  /* DUK_USE_ES6 */\n\nDUK_LOCAL double duk__round_fixed(double x) {\n\t/* Numbers half-way between integers must be rounded towards +Infinity,\n\t * e.g. -3.5 must be rounded to -3 (not -4).  When rounded to zero, zero\n\t * sign must be set appropriately.  E5.1 Section 15.8.2.15.\n\t *\n\t * Note that ANSI C round() is \"round to nearest integer, away from zero\",\n\t * which is incorrect for negative values.  Here we make do with floor().\n\t */\n\n\tduk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE || c == DUK_FP_ZERO) {\n\t\treturn x;\n\t}\n\n\t/*\n\t *  x is finite and non-zero\n\t *\n\t *  -1.6 -> floor(-1.1) -> -2\n\t *  -1.5 -> floor(-1.0) -> -1  (towards +Inf)\n\t *  -1.4 -> floor(-0.9) -> -1\n\t *  -0.5 -> -0.0               (special case)\n\t *  -0.1 -> -0.0               (special case)\n\t *  +0.1 -> +0.0               (special case)\n\t *  +0.5 -> floor(+1.0) -> 1   (towards +Inf)\n\t *  +1.4 -> floor(+1.9) -> 1\n\t *  +1.5 -> floor(+2.0) -> 2   (towards +Inf)\n\t *  +1.6 -> floor(+2.1) -> 2\n\t */\n\n\tif (x >= -0.5 && x < 0.5) {\n\t\t/* +0.5 is handled by floor, this is on purpose */\n\t\tif (x < 0.0) {\n\t\t\treturn -0.0;\n\t\t} else {\n\t\t\treturn +0.0;\n\t\t}\n\t}\n\n\treturn DUK_FLOOR(x + 0.5);\n}\n\n/* Wrappers for calling standard math library methods.  These may be required\n * on platforms where one or more of the math built-ins are defined as macros\n * or inline functions and are thus not suitable to be used as function pointers.\n */\n#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)\nDUK_LOCAL double duk__fabs(double x) {\n\treturn DUK_FABS(x);\n}\nDUK_LOCAL double duk__acos(double x) {\n\treturn DUK_ACOS(x);\n}\nDUK_LOCAL double duk__asin(double x) {\n\treturn DUK_ASIN(x);\n}\nDUK_LOCAL double duk__atan(double x) {\n\treturn DUK_ATAN(x);\n}\nDUK_LOCAL double duk__ceil(double x) {\n\treturn DUK_CEIL(x);\n}\nDUK_LOCAL double duk__cos(double x) {\n\treturn DUK_COS(x);\n}\nDUK_LOCAL double duk__exp(double x) {\n\treturn DUK_EXP(x);\n}\nDUK_LOCAL double duk__floor(double x) {\n\treturn DUK_FLOOR(x);\n}\nDUK_LOCAL double duk__log(double x) {\n\treturn DUK_LOG(x);\n}\nDUK_LOCAL double duk__sin(double x) {\n\treturn DUK_SIN(x);\n}\nDUK_LOCAL double duk__sqrt(double x) {\n\treturn DUK_SQRT(x);\n}\nDUK_LOCAL double duk__tan(double x) {\n\treturn DUK_TAN(x);\n}\nDUK_LOCAL double duk__atan2_fixed(double x, double y) {\n#if defined(DUK_USE_ATAN2_WORKAROUNDS)\n\t/* Specific fixes to common atan2() implementation issues:\n\t * - test-bug-mingw-math-issues.js\n\t */\n\tif (DUK_ISINF(x) && DUK_ISINF(y)) {\n\t\tif (DUK_SIGNBIT(x)) {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn -2.356194490192345;\n\t\t\t} else {\n\t\t\t\treturn -0.7853981633974483;\n\t\t\t}\n\t\t} else {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn 2.356194490192345;\n\t\t\t} else {\n\t\t\t\treturn 0.7853981633974483;\n\t\t\t}\n\t\t}\n\t}\n#else\n\t/* Some ISO C assumptions. */\n\tDUK_ASSERT(DUK_ATAN2(DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY) == 0.7853981633974483);\n\tDUK_ASSERT(DUK_ATAN2(-DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY) == -0.7853981633974483);\n\tDUK_ASSERT(DUK_ATAN2(DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY) == 2.356194490192345);\n\tDUK_ASSERT(DUK_ATAN2(-DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY) == -2.356194490192345);\n#endif\n\n\treturn DUK_ATAN2(x, y);\n}\n#endif  /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */\n\n/* order must match constants in genbuiltins.py */\nDUK_LOCAL const duk__one_arg_func duk__one_arg_funcs[] = {\n#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)\n\tduk__fabs,\n\tduk__acos,\n\tduk__asin,\n\tduk__atan,\n\tduk__ceil,\n\tduk__cos,\n\tduk__exp,\n\tduk__floor,\n\tduk__log,\n\tduk__round_fixed,\n\tduk__sin,\n\tduk__sqrt,\n\tduk__tan,\n#if defined(DUK_USE_ES6)\n\tduk__cbrt,\n\tduk__log2,\n\tduk__log10,\n\tduk__trunc\n#endif\n#else  /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */\n\tDUK_FABS,\n\tDUK_ACOS,\n\tDUK_ASIN,\n\tDUK_ATAN,\n\tDUK_CEIL,\n\tDUK_COS,\n\tDUK_EXP,\n\tDUK_FLOOR,\n\tDUK_LOG,\n\tduk__round_fixed,\n\tDUK_SIN,\n\tDUK_SQRT,\n\tDUK_TAN,\n#if defined(DUK_USE_ES6)\n\tduk__cbrt,\n\tduk__log2,\n\tduk__log10,\n\tduk__trunc\n#endif\n#endif  /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */\n};\n\n/* order must match constants in genbuiltins.py */\nDUK_LOCAL const duk__two_arg_func duk__two_arg_funcs[] = {\n#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)\n\tduk__atan2_fixed,\n\tduk_js_arith_pow\n#else\n\tduk__atan2_fixed,\n\tduk_js_arith_pow\n#endif\n};\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_onearg_shared(duk_hthread *thr) {\n\tduk_small_int_t fun_idx = duk_get_current_magic(thr);\n\tduk__one_arg_func fun;\n\tduk_double_t arg1;\n\n\tDUK_ASSERT(fun_idx >= 0);\n\tDUK_ASSERT(fun_idx < (duk_small_int_t) (sizeof(duk__one_arg_funcs) / sizeof(duk__one_arg_func)));\n\targ1 = duk_to_number(thr, 0);\n\tfun = duk__one_arg_funcs[fun_idx];\n\tduk_push_number(thr, (duk_double_t) fun((double) arg1));\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_twoarg_shared(duk_hthread *thr) {\n\tduk_small_int_t fun_idx = duk_get_current_magic(thr);\n\tduk__two_arg_func fun;\n\tduk_double_t arg1;\n\tduk_double_t arg2;\n\n\tDUK_ASSERT(fun_idx >= 0);\n\tDUK_ASSERT(fun_idx < (duk_small_int_t) (sizeof(duk__two_arg_funcs) / sizeof(duk__two_arg_func)));\n\targ1 = duk_to_number(thr, 0);  /* explicit ordered evaluation to match coercion semantics */\n\targ2 = duk_to_number(thr, 1);\n\tfun = duk__two_arg_funcs[fun_idx];\n\tduk_push_number(thr, (duk_double_t) fun((double) arg1, (double) arg2));\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_max(duk_hthread *thr) {\n\treturn duk__math_minmax(thr, -DUK_DOUBLE_INFINITY, duk__fmax_fixed);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_min(duk_hthread *thr) {\n\treturn duk__math_minmax(thr, DUK_DOUBLE_INFINITY, duk__fmin_fixed);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_random(duk_hthread *thr) {\n\tduk_push_number(thr, (duk_double_t) DUK_UTIL_GET_RANDOM_DOUBLE(thr));\n\treturn 1;\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_hypot(duk_hthread *thr) {\n\t/*\n\t *  E6 Section 20.2.2.18: Math.hypot\n\t *\n\t *  - If no arguments are passed, the result is +0.\n\t *  - If any argument is +inf, the result is +inf.\n\t *  - If any argument is -inf, the result is +inf.\n\t *  - If no argument is +inf or -inf, and any argument is NaN, the result is\n\t *    NaN.\n\t *  - If all arguments are either +0 or -0, the result is +0.\n\t */\n\n\tduk_idx_t nargs;\n\tduk_idx_t i;\n\tduk_bool_t found_nan;\n\tduk_double_t max;\n\tduk_double_t sum, summand;\n\tduk_double_t comp, prelim;\n\tduk_double_t t;\n\n\tnargs = duk_get_top(thr);\n\n\t/* Find the highest value.  Also ToNumber() coerces. */\n\tmax = 0.0;\n\tfound_nan = 0;\n\tfor (i = 0; i < nargs; i++) {\n\t\tt = DUK_FABS(duk_to_number(thr, i));\n\t\tif (DUK_FPCLASSIFY(t) == DUK_FP_NAN) {\n\t\t\tfound_nan = 1;\n\t\t} else {\n\t\t\tmax = duk_double_fmax(max, t);\n\t\t}\n\t}\n\n\t/* Early return cases. */\n\tif (max == DUK_DOUBLE_INFINITY) {\n\t\tduk_push_number(thr, DUK_DOUBLE_INFINITY);\n\t\treturn 1;\n\t} else if (found_nan) {\n\t\tduk_push_number(thr, DUK_DOUBLE_NAN);\n\t\treturn 1;\n\t} else if (max == 0.0) {\n\t\tduk_push_number(thr, 0.0);\n\t\t/* Otherwise we'd divide by zero. */\n\t\treturn 1;\n\t}\n\n\t/* Use Kahan summation and normalize to the highest value to minimize\n\t * floating point rounding error and avoid overflow.\n\t *\n\t * https://en.wikipedia.org/wiki/Kahan_summation_algorithm\n\t */\n\tsum = 0.0;\n\tcomp = 0.0;\n\tfor (i = 0; i < nargs; i++) {\n\t\tt = DUK_FABS(duk_get_number(thr, i)) / max;\n\t\tsummand = (t * t) - comp;\n\t\tprelim = sum + summand;\n\t\tcomp = (prelim - sum) - summand;\n\t\tsum = prelim;\n\t}\n\n\tduk_push_number(thr, (duk_double_t) DUK_SQRT(sum) * max);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_sign(duk_hthread *thr) {\n\tduk_double_t d;\n\n\td = duk_to_number(thr, 0);\n\tif (duk_double_is_nan(d)) {\n\t\tDUK_ASSERT(duk_is_nan(thr, -1));\n\t\treturn 1;  /* NaN input -> return NaN */\n\t}\n\tif (d == 0.0) {\n\t\t/* Zero sign kept, i.e. -0 -> -0, +0 -> +0. */\n\t\treturn 1;\n\t}\n\tduk_push_int(thr, (d > 0.0 ? 1 : -1));\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_clz32(duk_hthread *thr) {\n\tduk_uint32_t x;\n\tduk_small_uint_t i;\n\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_uint32_t mask;\n\n\tx = duk_to_uint32(thr, 0);\n\tfor (i = 0, mask = 0x80000000UL; mask != 0; mask >>= 1) {\n\t\tif (x & mask) {\n\t\t\tbreak;\n\t\t}\n\t\ti++;\n\t}\n\tDUK_ASSERT(i <= 32);\n\tduk_push_uint(thr, i);\n\treturn 1;\n#else  /* DUK_USE_PREFER_SIZE */\n\ti = 0;\n\tx = duk_to_uint32(thr, 0);\n\tif (x & 0xffff0000UL) {\n\t\tx >>= 16;\n\t} else {\n\t\ti += 16;\n\t}\n\tif (x & 0x0000ff00UL) {\n\t\tx >>= 8;\n\t} else {\n\t\ti += 8;\n\t}\n\tif (x & 0x000000f0UL) {\n\t\tx >>= 4;\n\t} else {\n\t\ti += 4;\n\t}\n\tif (x & 0x0000000cUL) {\n\t\tx >>= 2;\n\t} else {\n\t\ti += 2;\n\t}\n\tif (x & 0x00000002UL) {\n\t\tx >>= 1;\n\t} else {\n\t\ti += 1;\n\t}\n\tif (x & 0x00000001UL) {\n\t\t;\n\t} else {\n\t\ti += 1;\n\t}\n\tDUK_ASSERT(i <= 32);\n\tduk_push_uint(thr, i);\n\treturn 1;\n#endif  /* DUK_USE_PREFER_SIZE */\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_imul(duk_hthread *thr) {\n\tduk_uint32_t x, y, z;\n\n\tx = duk_to_uint32(thr, 0);\n\ty = duk_to_uint32(thr, 1);\n\tz = x * y;\n\n\t/* While arguments are ToUint32() coerced and the multiplication\n\t * is unsigned as such, the final result is curiously interpreted\n\t * as a signed 32-bit value.\n\t */\n\tduk_push_i32(thr, (duk_int32_t) z);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#endif  /* DUK_USE_MATH_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_number.c",
    "content": "/*\n *  Number built-ins\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_NUMBER_BUILTIN)\n\nDUK_LOCAL duk_double_t duk__push_this_number_plain(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\t/* Number built-in accepts a plain number or a Number object (whose\n\t * internal value is operated on).  Other types cause TypeError.\n\t */\n\n\tduk_push_this(thr);\n\tif (duk_is_number(thr, -1)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"plain number value: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\t\tgoto done;\n\t}\n\th = duk_get_hobject(thr, -1);\n\tif (!h ||\n\t    (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_NUMBER)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"unacceptable this value: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\t\tDUK_ERROR_TYPE(thr, \"number expected\");\n\t\tDUK_WO_NORETURN(return 0.0;);\n\t}\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\tDUK_DDD(DUK_DDDPRINT(\"number object: %!T, internal value: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_remove_m2(thr);\n\n done:\n\treturn duk_get_number(thr, -1);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_constructor(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_hobject *h_this;\n\n\t/*\n\t *  The Number constructor uses ToNumber(arg) for number coercion\n\t *  (coercing an undefined argument to NaN).  However, if the\n\t *  argument is not given at all, +0 must be used instead.  To do\n\t *  this, a vararg function is used.\n\t */\n\n\tnargs = duk_get_top(thr);\n\tif (nargs == 0) {\n\t\tduk_push_int(thr, 0);\n\t}\n\tduk_to_number(thr, 0);\n\tduk_set_top(thr, 1);\n\tDUK_ASSERT_TOP(thr, 1);\n\n\tif (!duk_is_constructor_call(thr)) {\n\t\treturn 1;\n\t}\n\n\t/*\n\t *  E5 Section 15.7.2.1 requires that the constructed object\n\t *  must have the original Number.prototype as its internal\n\t *  prototype.  However, since Number.prototype is non-writable\n\t *  and non-configurable, this doesn't have to be enforced here:\n\t *  The default object (bound to 'this') is OK, though we have\n\t *  to change its class.\n\t *\n\t *  Internal value set to ToNumber(arg) or +0; if no arg given,\n\t *  ToNumber(undefined) = NaN, so special treatment is needed\n\t *  (above).  String internal value is immutable.\n\t */\n\n\t/* XXX: helper */\n\tduk_push_this(thr);\n\th_this = duk_known_hobject(thr, -1);\n\tDUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_NUMBER);\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE]);\n\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_this) == DUK_HOBJECT_CLASS_NUMBER);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_this));\n\n\tduk_dup_0(thr);  /* -> [ val obj val ] */\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\treturn 0;  /* no return value -> don't replace created value */\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_value_of(duk_hthread *thr) {\n\t(void) duk__push_this_number_plain(thr);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_string(duk_hthread *thr) {\n\tduk_small_int_t radix;\n\tduk_small_uint_t n2s_flags;\n\n\t(void) duk__push_this_number_plain(thr);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tradix = 10;\n\t} else {\n\t\tradix = (duk_small_int_t) duk_to_int_check_range(thr, 0, 2, 36);\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"radix=%ld\", (long) radix));\n\n\tn2s_flags = 0;\n\n\tduk_numconv_stringify(thr,\n\t                      radix /*radix*/,\n\t                      0 /*digits*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_locale_string(duk_hthread *thr) {\n\t/* XXX: just use toString() for now; permitted although not recommended.\n\t * nargs==1, so radix is passed to toString().\n\t */\n\treturn duk_bi_number_prototype_to_string(thr);\n}\n\n/*\n *  toFixed(), toExponential(), toPrecision()\n */\n\n/* XXX: shared helper for toFixed(), toExponential(), toPrecision()? */\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_fixed(duk_hthread *thr) {\n\tduk_small_int_t frac_digits;\n\tduk_double_t d;\n\tduk_small_int_t c;\n\tduk_small_uint_t n2s_flags;\n\n\t/* In ES5.1 frac_digits is coerced first; in ES2015 the 'this number\n\t * value' check is done first.\n\t */\n\td = duk__push_this_number_plain(thr);\n\tfrac_digits = (duk_small_int_t) duk_to_int_check_range(thr, 0, 0, 20);\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\tgoto use_to_string;\n\t}\n\n\tif (d >= 1.0e21 || d <= -1.0e21) {\n\t\tgoto use_to_string;\n\t}\n\n\tn2s_flags = DUK_N2S_FLAG_FIXED_FORMAT |\n\t            DUK_N2S_FLAG_FRACTION_DIGITS;\n\n\tduk_numconv_stringify(thr,\n\t                      10 /*radix*/,\n\t                      frac_digits /*digits*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n\n use_to_string:\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, -1);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_exponential(duk_hthread *thr) {\n\tduk_bool_t frac_undefined;\n\tduk_small_int_t frac_digits;\n\tduk_double_t d;\n\tduk_small_int_t c;\n\tduk_small_uint_t n2s_flags;\n\n\td = duk__push_this_number_plain(thr);\n\n\tfrac_undefined = duk_is_undefined(thr, 0);\n\tduk_to_int(thr, 0);  /* for side effects */\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\tgoto use_to_string;\n\t}\n\n\tfrac_digits = (duk_small_int_t) duk_to_int_check_range(thr, 0, 0, 20);\n\n\tn2s_flags = DUK_N2S_FLAG_FORCE_EXP |\n\t           (frac_undefined ? 0 : DUK_N2S_FLAG_FIXED_FORMAT);\n\n\tduk_numconv_stringify(thr,\n\t                      10 /*radix*/,\n\t                      frac_digits + 1 /*leading digit + fractions*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n\n use_to_string:\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, -1);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_precision(duk_hthread *thr) {\n\t/* The specification has quite awkward order of coercion and\n\t * checks for toPrecision().  The operations below are a bit\n\t * reordered, within constraints of observable side effects.\n\t */\n\n\tduk_double_t d;\n\tduk_small_int_t prec;\n\tduk_small_int_t c;\n\tduk_small_uint_t n2s_flags;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\n\td = duk__push_this_number_plain(thr);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tgoto use_to_string;\n\t}\n\tDUK_ASSERT_TOP(thr, 2);\n\n\tduk_to_int(thr, 0);  /* for side effects */\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\tgoto use_to_string;\n\t}\n\n\tprec = (duk_small_int_t) duk_to_int_check_range(thr, 0, 1, 21);\n\n\tn2s_flags = DUK_N2S_FLAG_FIXED_FORMAT |\n\t            DUK_N2S_FLAG_NO_ZERO_PAD;\n\n\tduk_numconv_stringify(thr,\n\t                      10 /*radix*/,\n\t                      prec /*digits*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n\n use_to_string:\n\t/* Used when precision is undefined; also used for NaN (-> \"NaN\"),\n\t * and +/- infinity (-> \"Infinity\", \"-Infinity\").\n\t */\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, -1);\n\treturn 1;\n}\n\n/*\n *  ES2015 isFinite() etc\n */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_number_check_shared(duk_hthread *thr) {\n\tduk_int_t magic;\n\tduk_bool_t ret = 0;\n\n\tif (duk_is_number(thr, 0)) {\n\t\tduk_double_t d;\n\n\t\tmagic = duk_get_current_magic(thr);\n\t\td = duk_get_number(thr, 0);\n\n\t\tswitch (magic) {\n\t\tcase 0:  /* isFinite() */\n\t\t\tret = duk_double_is_finite(d);\n\t\t\tbreak;\n\t\tcase 1:  /* isInteger() */\n\t\t\tret = duk_double_is_integer(d);\n\t\t\tbreak;\n\t\tcase 2:  /* isNaN() */\n\t\t\tret = duk_double_is_nan(d);\n\t\t\tbreak;\n\t\tdefault:  /* isSafeInteger() */\n\t\t\tDUK_ASSERT(magic == 3);\n\t\t\tret = duk_double_is_safe_integer(d);\n\t\t}\n\t}\n\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#endif  /* DUK_USE_NUMBER_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_object.c",
    "content": "/*\n *  Object built-ins\n */\n\n#include \"duk_internal.h\"\n\n/* Needed even when Object built-in disabled. */\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_string(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\ttv = DUK_HTHREAD_THIS_PTR(thr);\n\tduk_push_class_string_tval(thr, tv, 0 /*avoid_side_effects*/);\n\treturn 1;\n}\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor(duk_hthread *thr) {\n\tduk_uint_t arg_mask;\n\n\targ_mask = duk_get_type_mask(thr, 0);\n\n\tif (!duk_is_constructor_call(thr) &&  /* not a constructor call */\n\t    ((arg_mask & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED)) == 0)) {  /* and argument not null or undefined */\n\t\tduk_to_object(thr, 0);\n\t\treturn 1;\n\t}\n\n\t/* Pointer and buffer primitive values are treated like other\n\t * primitives values which have a fully fledged object counterpart:\n\t * promote to an object value.  Lightfuncs and plain buffers are\n\t * coerced with ToObject() even they could also be returned as is.\n\t */\n\tif (arg_mask & (DUK_TYPE_MASK_OBJECT |\n\t                DUK_TYPE_MASK_STRING |\n\t                DUK_TYPE_MASK_BOOLEAN |\n\t                DUK_TYPE_MASK_NUMBER |\n\t                DUK_TYPE_MASK_POINTER |\n\t                DUK_TYPE_MASK_BUFFER |\n\t                DUK_TYPE_MASK_LIGHTFUNC)) {\n\t\t/* For DUK_TYPE_OBJECT the coercion is a no-op and could\n\t\t * be checked for explicitly, but Object(obj) calls are\n\t\t * not very common so opt for minimal footprint.\n\t\t */\n\t\tduk_to_object(thr, 0);\n\t\treturn 1;\n\t}\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              DUK_BIDX_OBJECT_PROTOTYPE);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) && defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_assign(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_int_t idx;\n\n\tnargs = duk_get_top_require_min(thr, 1 /*min_top*/);\n\n\tduk_to_object(thr, 0);\n\tfor (idx = 1; idx < nargs; idx++) {\n\t\t/* E7 19.1.2.1 (step 4a) */\n\t\tif (duk_is_null_or_undefined(thr, idx)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* duk_enum() respects ES2015+ [[OwnPropertyKeys]] ordering, which is\n\t\t * convenient here.\n\t\t */\n\t\tduk_to_object(thr, idx);\n\t\tduk_enum(thr, idx, DUK_ENUM_OWN_PROPERTIES_ONLY);\n\t\twhile (duk_next(thr, -1, 1 /*get_value*/)) {\n\t\t\t/* [ target ... enum key value ] */\n\t\t\tduk_put_prop(thr, 0);\n\t\t\t/* [ target ... enum ] */\n\t\t}\n\t\t/* Could pop enumerator, but unnecessary because of duk_set_top()\n\t\t * below.\n\t\t */\n\t}\n\n\tduk_set_top(thr, 1);\n\treturn 1;\n}\n#endif\n\n#if defined(DUK_USE_OBJECT_BUILTIN) && defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_is(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_push_boolean(thr, duk_samevalue(thr, 0, 1));\n\treturn 1;\n}\n#endif\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_create(duk_hthread *thr) {\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tduk_hbufobj_promote_plain(thr, 0);\n#endif\n\tproto = duk_require_hobject_accept_mask(thr, 0, DUK_TYPE_MASK_NULL);\n\tDUK_ASSERT(proto != NULL || duk_is_null(thr, 0));\n\n\t(void) duk_push_object_helper_proto(thr,\n\t                                    DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                    DUK_HOBJECT_FLAG_FASTREFS |\n\t                                    DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                                    proto);\n\n\tif (!duk_is_undefined(thr, 1)) {\n\t\t/* [ O Properties obj ] */\n\n\t\tduk_replace(thr, 0);\n\n\t\t/* [ obj Properties ] */\n\n\t\t/* Just call the \"original\" Object.defineProperties() to\n\t\t * finish up.\n\t\t */\n\n\t\treturn duk_bi_object_constructor_define_properties(thr);\n\t}\n\n\t/* [ O Properties obj ] */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_hthread *thr) {\n\tduk_small_uint_t pass;\n\tduk_uint_t defprop_flags;\n\tduk_hobject *obj;\n\tduk_idx_t idx_value;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\n\t/* Lightfunc and plain buffer handling by ToObject() coercion. */\n\tobj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(obj != NULL);\n\n\tduk_to_object(thr, 1);        /* properties object */\n\n\tDUK_DDD(DUK_DDDPRINT(\"target=%!iT, properties=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\n\t/*\n\t *  Two pass approach to processing the property descriptors.\n\t *  On first pass validate and normalize all descriptors before\n\t *  any changes are made to the target object.  On second pass\n\t *  make the actual modifications to the target object.\n\t *\n\t *  Right now we'll just use the same normalize/validate helper\n\t *  on both passes, ignoring its outputs on the first pass.\n\t */\n\n\tfor (pass = 0; pass < 2; pass++) {\n\t\tduk_set_top(thr, 2);  /* -> [ hobject props ] */\n\t\tduk_enum(thr, 1, DUK_ENUM_OWN_PROPERTIES_ONLY | DUK_ENUM_INCLUDE_SYMBOLS /*enum_flags*/);\n\n\t\tfor (;;) {\n\t\t\tduk_hstring *key;\n\n\t\t\t/* [ hobject props enum(props) ] */\n\n\t\t\tduk_set_top(thr, 3);\n\n\t\t\tif (!duk_next(thr, 2, 1 /*get_value*/)) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> key=%!iT, desc=%!iT\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t/* [ hobject props enum(props) key desc ] */\n\n\t\t\tduk_hobject_prepare_property_descriptor(thr,\n\t\t\t                                        4 /*idx_desc*/,\n\t\t\t                                        &defprop_flags,\n\t\t\t                                        &idx_value,\n\t\t\t                                        &get,\n\t\t\t                                        &set);\n\n\t\t\t/* [ hobject props enum(props) key desc [multiple values] ] */\n\n\t\t\tif (pass == 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* This allows symbols on purpose. */\n\t\t\tkey = duk_known_hstring(thr, 3);\n\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\tduk_hobject_define_property_helper(thr,\n\t\t\t                                   defprop_flags,\n\t\t\t                                   obj,\n\t\t\t                                   key,\n\t\t\t                                   idx_value,\n\t\t\t                                   get,\n\t\t\t                                   set,\n\t\t\t                                   1 /*throw_flag*/);\n\t\t}\n\t}\n\n\t/*\n\t *  Return target object\n\t */\n\n\tduk_dup_0(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_seal_freeze_shared(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 1);\n\n\tduk_seal_freeze_raw(thr, 0, (duk_bool_t) duk_get_current_magic(thr) /*is_freeze*/);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_sealed_frozen_shared(duk_hthread *thr) {\n\tduk_hobject *h;\n\tduk_bool_t is_frozen;\n\tduk_uint_t mask;\n\n\tis_frozen = (duk_bool_t) duk_get_current_magic(thr);\n\tmask = duk_get_type_mask(thr, 0);\n\tif (mask & (DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER)) {\n\t\tDUK_ASSERT(is_frozen == 0 || is_frozen == 1);\n\t\tduk_push_boolean(thr, (mask & DUK_TYPE_MASK_LIGHTFUNC) ?\n\t\t                          1 :               /* lightfunc always frozen and sealed */\n\t\t                          (is_frozen ^ 1)); /* buffer sealed but not frozen (index props writable) */\n\t} else {\n\t\t/* ES2015 Sections 19.1.2.12, 19.1.2.13: anything other than an object\n\t\t * is considered to be already sealed and frozen.\n\t\t */\n\t\th = duk_get_hobject(thr, 0);\n\t\tduk_push_boolean(thr, (h == NULL) ||\n\t\t                      duk_hobject_object_is_sealed_frozen_helper(thr, h, is_frozen /*is_frozen*/));\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_locale_string(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 0);\n\t(void) duk_push_this_coercible_to_object(thr);\n\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_TO_STRING);\n#if 0  /* This is mentioned explicitly in the E5.1 spec, but duk_call_method() checks for it in practice. */\n\tduk_require_callable(thr, 1);\n#endif\n\tduk_dup_0(thr);  /* -> [ O toString O ] */\n\tduk_call_method(thr, 0);  /* XXX: call method tail call? */\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_value_of(duk_hthread *thr) {\n\t/* For lightfuncs and plain buffers, returns Object() coerced. */\n\t(void) duk_push_this_coercible_to_object(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_hthread *thr) {\n\tduk_hobject *h_v;\n\tduk_hobject *h_obj;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\n\th_v = duk_get_hobject(thr, 0);\n\tif (!h_v) {\n\t\tduk_push_false(thr);  /* XXX: tail call: return duk_push_false(thr) */\n\t\treturn 1;\n\t}\n\n\th_obj = duk_push_this_coercible_to_object(thr);\n\tDUK_ASSERT(h_obj != NULL);\n\n\t/* E5.1 Section 15.2.4.6, step 3.a, lookup proto once before compare.\n\t * Prototype loops should cause an error to be thrown.\n\t */\n\tduk_push_boolean(thr, duk_hobject_prototype_chain_contains(thr, DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_v), h_obj, 0 /*ignore_loop*/));\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_has_own_property(duk_hthread *thr) {\n\treturn (duk_ret_t) duk_hobject_object_ownprop_helper(thr, 0 /*required_desc_flags*/);\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_property_is_enumerable(duk_hthread *thr) {\n\treturn (duk_ret_t) duk_hobject_object_ownprop_helper(thr, DUK_PROPDESC_FLAG_ENUMERABLE /*required_desc_flags*/);\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\n/* Shared helper to implement Object.getPrototypeOf,\n * Object.prototype.__proto__ getter, and Reflect.getPrototypeOf.\n *\n * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-get-object.prototype.__proto__\n */\nDUK_INTERNAL duk_ret_t duk_bi_object_getprototype_shared(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: __proto__ getter\n\t *  magic = 1: Object.getPrototypeOf()\n\t *  magic = 2: Reflect.getPrototypeOf()\n\t */\n\n\tduk_hobject *h;\n\tduk_hobject *proto;\n\tduk_tval *tv;\n\tduk_int_t magic;\n\n\tmagic = duk_get_current_magic(thr);\n\n\tif (magic == 0) {\n\t\tDUK_ASSERT_TOP(thr, 0);\n\t\tduk_push_this_coercible_to_object(thr);\n\t}\n\tDUK_ASSERT(duk_get_top(thr) >= 1);\n\tif (magic < 2) {\n\t\t/* ES2015 Section 19.1.2.9, step 1 */\n\t\tduk_to_object(thr, 0);\n\t}\n\ttv = DUK_GET_TVAL_POSIDX(thr, 0);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_BUFFER:\n\t\tproto = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\tproto = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tproto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t\tbreak;\n\tdefault:\n\t\t/* This implicitly handles CheckObjectCoercible() caused\n\t\t * TypeError.\n\t\t */\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\tif (proto != NULL) {\n\t\tduk_push_hobject(thr, proto);\n\t} else {\n\t\tduk_push_null(thr);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\n/* Shared helper to implement ES2015 Object.setPrototypeOf,\n * Object.prototype.__proto__ setter, and Reflect.setPrototypeOf.\n *\n * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-get-object.prototype.__proto__\n * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.setprototypeof\n */\nDUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: __proto__ setter\n\t *  magic = 1: Object.setPrototypeOf()\n\t *  magic = 2: Reflect.setPrototypeOf()\n\t */\n\n\tduk_hobject *h_obj;\n\tduk_hobject *h_new_proto;\n\tduk_hobject *h_curr;\n\tduk_ret_t ret_success = 1;  /* retval for success path */\n\tduk_uint_t mask;\n\tduk_int_t magic;\n\n\t/* Preliminaries for __proto__ and setPrototypeOf (E6 19.1.2.18 steps 1-4). */\n\tmagic = duk_get_current_magic(thr);\n\tif (magic == 0) {\n\t\tduk_push_this_check_object_coercible(thr);\n\t\tduk_insert(thr, 0);\n\t\tif (!duk_check_type_mask(thr, 1, DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_OBJECT)) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* __proto__ setter returns 'undefined' on success unlike the\n\t\t * setPrototypeOf() call which returns the target object.\n\t\t */\n\t\tret_success = 0;\n\t} else {\n\t\tif (magic == 1) {\n\t\t\tduk_require_object_coercible(thr, 0);\n\t\t} else {\n\t\t\tduk_require_hobject_accept_mask(thr, 0,\n\t\t\t                                DUK_TYPE_MASK_LIGHTFUNC |\n\t\t\t                                DUK_TYPE_MASK_BUFFER);\n\t\t}\n\t\tduk_require_type_mask(thr, 1, DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_OBJECT);\n\t}\n\n\th_new_proto = duk_get_hobject(thr, 1);\n\t/* h_new_proto may be NULL */\n\n\tmask = duk_get_type_mask(thr, 0);\n\tif (mask & (DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER)) {\n\t\tduk_hobject *curr_proto;\n\t\tcurr_proto = thr->builtins[(mask & DUK_TYPE_MASK_LIGHTFUNC) ?\n\t\t                               DUK_BIDX_FUNCTION_PROTOTYPE :\n\t\t                               DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tif (h_new_proto == curr_proto) {\n\t\t\tgoto skip;\n\t\t}\n\t\tgoto fail_nonextensible;\n\t}\n\th_obj = duk_get_hobject(thr, 0);\n\tif (h_obj == NULL) {\n\t\tgoto skip;\n\t}\n\tDUK_ASSERT(h_obj != NULL);\n\n\t/* [[SetPrototypeOf]] standard behavior, E6 9.1.2. */\n\t/* TODO: implement Proxy object support here */\n\n\tif (h_new_proto == DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_obj)) {\n\t\tgoto skip;\n\t}\n\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(h_obj)) {\n\t\tgoto fail_nonextensible;\n\t}\n\tfor (h_curr = h_new_proto; h_curr != NULL; h_curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_curr)) {\n\t\t/* Loop prevention. */\n\t\tif (h_curr == h_obj) {\n\t\t\tgoto fail_loop;\n\t\t}\n\t}\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h_obj, h_new_proto);\n\t/* fall thru */\n\n skip:\n\tduk_set_top(thr, 1);\n\tif (magic == 2) {\n\t\tduk_push_true(thr);\n\t}\n\treturn ret_success;\n\n fail_nonextensible:\n fail_loop:\n\tif (magic != 2) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t} else {\n\t\tduk_push_false(thr);\n\t\treturn 1;\n\t}\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: Object.defineProperty()\n\t *  magic = 1: Reflect.defineProperty()\n\t */\n\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\tduk_idx_t idx_value;\n\tduk_uint_t defprop_flags;\n\tduk_small_uint_t magic;\n\tduk_bool_t throw_flag;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"Object.defineProperty(): ctx=%p obj=%!T key=%!T desc=%!T\",\n\t                     (void *) thr,\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1),\n\t                     (duk_tval *) duk_get_tval(thr, 2)));\n\n\t/* [ obj key desc ] */\n\n\tmagic = (duk_small_uint_t) duk_get_current_magic(thr);\n\n\t/* Lightfuncs are currently supported by coercing to a temporary\n\t * Function object; changes will be allowed (the coerced value is\n\t * extensible) but will be lost.  Same for plain buffers.\n\t */\n\tobj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(obj != NULL);\n\tkey = duk_to_property_key_hstring(thr, 1);\n\t(void) duk_require_hobject(thr, 2);\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(duk_get_hobject(thr, 2) != NULL);\n\n\t/*\n\t *  Validate and convert argument property descriptor (an ECMAScript\n\t *  object) into a set of defprop_flags and possibly property value,\n\t *  getter, and/or setter values on the value stack.\n\t *\n\t *  Lightfunc set/get values are coerced to full Functions.\n\t */\n\n\tduk_hobject_prepare_property_descriptor(thr,\n\t                                        2 /*idx_desc*/,\n\t                                        &defprop_flags,\n\t                                        &idx_value,\n\t                                        &get,\n\t                                        &set);\n\n\t/*\n\t *  Use Object.defineProperty() helper for the actual operation.\n\t */\n\n\tDUK_ASSERT(magic == 0U || magic == 1U);\n\tthrow_flag = magic ^ 1U;\n\tret = duk_hobject_define_property_helper(thr,\n\t                                         defprop_flags,\n\t                                         obj,\n\t                                         key,\n\t                                         idx_value,\n\t                                         get,\n\t                                         set,\n\t                                         throw_flag);\n\n\t/* Ignore the normalize/validate helper outputs on the value stack,\n\t * they're popped automatically.\n\t */\n\n\tif (magic == 0U) {\n\t\t/* Object.defineProperty(): return target object. */\n\t\tduk_push_hobject(thr, obj);\n\t} else {\n\t\t/* Reflect.defineProperty(): return success/fail. */\n\t\tduk_push_boolean(thr, ret);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_get_own_property_descriptor(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 2);\n\n\t/* ES2015 Section 19.1.2.6, step 1 */\n\tif (duk_get_current_magic(thr) == 0) {\n\t\tduk_to_object(thr, 0);\n\t}\n\n\t/* [ obj key ] */\n\n\tduk_hobject_object_get_own_property_descriptor(thr, -2);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_extensible(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: Object.isExtensible()\n\t *  magic = 1: Reflect.isExtensible()\n\t */\n\n\tduk_hobject *h;\n\n\tif (duk_get_current_magic(thr) == 0) {\n\t\th = duk_get_hobject(thr, 0);\n\t} else {\n\t\t/* Reflect.isExtensible(): throw if non-object, but we accept lightfuncs\n\t\t * and plain buffers here because they pretend to be objects.\n\t\t */\n\t\th = duk_require_hobject_accept_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\t}\n\n\tduk_push_boolean(thr, (h != NULL) && DUK_HOBJECT_HAS_EXTENSIBLE(h));\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\n/* Shared helper for various key/symbol listings, magic:\n * 0=Object.keys()\n * 1=Object.getOwnPropertyNames(),\n * 2=Object.getOwnPropertySymbols(),\n * 3=Reflect.ownKeys()\n */\nDUK_LOCAL const duk_small_uint_t duk__object_keys_enum_flags[4] = {\n\t/* Object.keys() */\n\tDUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR,\n\n\t/* Object.getOwnPropertyNames() */\n\tDUK_ENUM_INCLUDE_NONENUMERABLE |\n\t    DUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR,\n\n\t/* Object.getOwnPropertySymbols() */\n\tDUK_ENUM_INCLUDE_SYMBOLS |\n\t    DUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_EXCLUDE_STRINGS |\n\t    DUK_ENUM_INCLUDE_NONENUMERABLE |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR,\n\n\t/* Reflect.ownKeys() */\n\tDUK_ENUM_INCLUDE_SYMBOLS |\n\t    DUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_INCLUDE_NONENUMERABLE |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR\n};\n\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_keys_shared(duk_hthread *thr) {\n\tduk_hobject *obj;\n#if defined(DUK_USE_ES6_PROXY)\n\tduk_hobject *h_proxy_target;\n\tduk_hobject *h_proxy_handler;\n\tduk_hobject *h_trap_result;\n#endif\n\tduk_small_uint_t enum_flags;\n\tduk_int_t magic;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\n\tmagic = duk_get_current_magic(thr);\n\tif (magic == 3) {\n\t\t/* ES2015 Section 26.1.11 requires a TypeError for non-objects.  Lightfuncs\n\t\t * and plain buffers pretend to be objects, so accept those too.\n\t\t */\n\t\tobj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\t} else {\n\t\t/* ES2015: ToObject coerce. */\n\t\tobj = duk_to_hobject(thr, 0);\n\t}\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(obj);\n\n\t/* XXX: proxy chains */\n\n#if defined(DUK_USE_ES6_PROXY)\n\t/* XXX: better sharing of code between proxy target call sites */\n\tif (DUK_LIKELY(!duk_hobject_proxy_check(obj,\n\t                                        &h_proxy_target,\n\t                                        &h_proxy_handler))) {\n\t\tgoto skip_proxy;\n\t}\n\n\tduk_push_hobject(thr, h_proxy_handler);\n\tif (!duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_OWN_KEYS)) {\n\t\t/* Careful with reachability here: don't pop 'obj' before pushing\n\t\t * proxy target.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"no ownKeys trap, get keys of target instead\"));\n\t\tduk_pop_2(thr);\n\t\tduk_push_hobject(thr, h_proxy_target);\n\t\tduk_replace(thr, 0);\n\t\tDUK_ASSERT_TOP(thr, 1);\n\t\tgoto skip_proxy;\n\t}\n\n\t/* [ obj handler trap ] */\n\tduk_insert(thr, -2);\n\tduk_push_hobject(thr, h_proxy_target);  /* -> [ obj trap handler target ] */\n\tduk_call_method(thr, 1 /*nargs*/);      /* -> [ obj trap_result ] */\n\th_trap_result = duk_require_hobject(thr, -1);\n\tDUK_UNREF(h_trap_result);\n\n\tmagic = duk_get_current_magic(thr);\n\tDUK_ASSERT(magic >= 0 && magic < (duk_int_t) (sizeof(duk__object_keys_enum_flags) / sizeof(duk_small_uint_t)));\n\tenum_flags = duk__object_keys_enum_flags[magic];\n\n\tduk_proxy_ownkeys_postprocess(thr, h_proxy_target, enum_flags);\n\treturn 1;\n\n skip_proxy:\n#endif  /* DUK_USE_ES6_PROXY */\n\n\tDUK_ASSERT_TOP(thr, 1);\n\tmagic = duk_get_current_magic(thr);\n\tDUK_ASSERT(magic >= 0 && magic < (duk_int_t) (sizeof(duk__object_keys_enum_flags) / sizeof(duk_small_uint_t)));\n\tenum_flags = duk__object_keys_enum_flags[magic];\n\treturn duk_hobject_get_enumerated_keys(thr, enum_flags);\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: Object.preventExtensions()\n\t *  magic = 1: Reflect.preventExtensions()\n\t */\n\n\tduk_hobject *h;\n\tduk_uint_t mask;\n\tduk_int_t magic;\n\n\tmagic = duk_get_current_magic(thr);\n\n\t/* Silent success for lightfuncs and plain buffers always. */\n\tmask = DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER;\n\n\t/* Object.preventExtensions() silent success for non-object. */\n\tif (magic == 0) {\n\t\tmask |= DUK_TYPE_MASK_UNDEFINED |\n\t\t        DUK_TYPE_MASK_NULL |\n\t\t        DUK_TYPE_MASK_BOOLEAN |\n\t\t        DUK_TYPE_MASK_NUMBER |\n\t\t        DUK_TYPE_MASK_STRING |\n\t\t        DUK_TYPE_MASK_POINTER;\n\t}\n\n\tif (duk_check_type_mask(thr, 0, mask)) {\n\t\t/* Not an object, already non-extensible so always success. */\n\t\tgoto done;\n\t}\n\th = duk_require_hobject(thr, 0);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_HOBJECT_CLEAR_EXTENSIBLE(h);\n\n\t/* A non-extensible object cannot gain any more properties,\n\t * so this is a good time to compact.\n\t */\n\tduk_hobject_compact_props(thr, h);\n\n done:\n\tif (magic == 1) {\n\t\tduk_push_true(thr);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n/*\n *  __defineGetter__, __defineSetter__, __lookupGetter__, __lookupSetter__\n */\n\n#if defined(DUK_USE_ES8)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_defineaccessor(duk_hthread *thr) {\n\tduk_push_this(thr);\n\tduk_insert(thr, 0);\n\tduk_to_object(thr, 0);\n\tduk_require_callable(thr, 2);\n\n\t/* [ ToObject(this) key getter/setter ] */\n\n\t/* ToPropertyKey() coercion is not needed, duk_def_prop() does it. */\n\tduk_def_prop(thr, 0, DUK_DEFPROP_SET_ENUMERABLE |\n\t                     DUK_DEFPROP_SET_CONFIGURABLE |\n\t                     (duk_get_current_magic(thr) ? DUK_DEFPROP_HAVE_SETTER : DUK_DEFPROP_HAVE_GETTER));\n\treturn 0;\n}\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_lookupaccessor(duk_hthread *thr) {\n\tduk_uint_t sanity;\n\n\tduk_push_this(thr);\n\tduk_to_object(thr, -1);\n\n\t/* XXX: Prototype walk (with sanity) should be a core property\n\t * operation, could add a flag to e.g. duk_get_prop_desc().\n\t */\n\n\t/* ToPropertyKey() coercion is not needed, duk_get_prop_desc() does it. */\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\twhile (!duk_is_undefined(thr, -1)) {\n\t\t/* [ key obj ] */\n\t\tduk_dup(thr, 0);\n\t\tduk_get_prop_desc(thr, 1, 0 /*flags*/);\n\t\tif (!duk_is_undefined(thr, -1)) {\n\t\t\tduk_get_prop_stridx(thr, -1, (duk_get_current_magic(thr) != 0 ? DUK_STRIDX_SET : DUK_STRIDX_GET));\n\t\t\treturn 1;\n\t\t}\n\t\tduk_pop(thr);\n\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\n\t\tduk_get_prototype(thr, -1);\n\t\tduk_remove(thr, -2);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_ES8 */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_performance.c",
    "content": "/*\n *  High resolution time API (performance.now() et al)\n *\n *  API specification: https://encoding.spec.whatwg.org/#ap://www.w3.org/TR/hr-time/\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_PERFORMANCE_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_performance_now(duk_hthread *thr) {\n\t/* From API spec:\n\t * The DOMHighResTimeStamp type is used to store a time value in\n\t * milliseconds, measured relative from the time origin, global\n\t * monotonic clock, or a time value that represents a duration\n\t * between two DOMHighResTimeStamp's.\n\t */\n\tduk_push_number(thr, duk_time_get_monotonic_time(thr));\n\treturn 1;\n}\n\n#if 0  /* Missing until semantics decided. */\nDUK_INTERNAL duk_ret_t duk_bi_performance_timeorigin_getter(duk_hthread *thr) {\n\t/* No decision yet how to handle timeOrigins, e.g. should one be\n\t * initialized per heap, or per global object set.  See\n\t * https://www.w3.org/TR/hr-time/#time-origin.\n\t */\n\tduk_push_uint(thr, 0);\n\treturn 1;\n}\n#endif  /* 0 */\n#endif  /* DUK_USE_PERFORMANCE_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_pointer.c",
    "content": "/*\n *  Pointer built-ins\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_pointer_constructor(duk_hthread *thr) {\n\t/* XXX: this behavior is quite useless now; it would be nice to be able\n\t * to create pointer values from e.g. numbers or strings.  Numbers are\n\t * problematic on 64-bit platforms though.  Hex encoded strings?\n\t */\n\tif (duk_get_top(thr) == 0) {\n\t\tduk_push_pointer(thr, NULL);\n\t} else {\n\t\tduk_to_pointer(thr, 0);\n\t}\n\tDUK_ASSERT(duk_is_pointer(thr, 0));\n\tduk_set_top(thr, 1);\n\n\tif (duk_is_constructor_call(thr)) {\n\t\t(void) duk_push_object_helper(thr,\n\t\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER),\n\t\t                              DUK_BIDX_POINTER_PROTOTYPE);\n\n\t\t/* Pointer object internal value is immutable. */\n\t\tduk_dup_0(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\t/* Note: unbalanced stack on purpose */\n\n\treturn 1;\n}\n\n/*\n *  toString(), valueOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_small_int_t to_string = duk_get_current_magic(thr);\n\n\tduk_push_this(thr);\n\ttv = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_POINTER(tv)) {\n\t\t/* nop */\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* Must be a \"pointer object\", i.e. class \"Pointer\" */\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_POINTER) {\n\t\t\tgoto type_error;\n\t\t}\n\n\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t} else {\n\t\tgoto type_error;\n\t}\n\n\tif (to_string) {\n\t\tduk_to_string(thr, -1);\n\t}\n\treturn 1;\n\n type_error:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_promise.c",
    "content": "/*\n *  Promise built-in\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_PROMISE_BUILTIN)\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_constructor(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_all(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_race(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_reject(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_resolve(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_catch(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_then(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\n#endif  /* DUK_USE_PROMISE_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_protos.h",
    "content": "/*\n *  Prototypes for built-in functions not automatically covered by the\n *  header declarations emitted by genbuiltins.py.\n */\n\n#if !defined(DUK_BUILTIN_PROTOS_H_INCLUDED)\n#define DUK_BUILTIN_PROTOS_H_INCLUDED\n\n/* Buffer size needed for ISO 8601 formatting.\n * Accurate value is 32 + 1 for NUL termination:\n *   >>> len('+123456-01-23T12:34:56.123+12:34')\n *   32\n * Include additional space to be safe.\n */\n#define  DUK_BI_DATE_ISO8601_BUFSIZE  40\n\n/* Helpers exposed for internal use */\nDUK_INTERNAL_DECL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts, duk_double_t *dparts, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_timeval_from_dparts(duk_double_t *dparts, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_is_leap_year(duk_int_t year);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_timeval_in_valid_range(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_year_in_valid_range(duk_double_t year);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_timeval_in_leeway_range(duk_double_t x);\n/* Built-in providers */\n#if defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_gettimeofday(void);\n#endif\n#if defined(DUK_USE_DATE_NOW_TIME)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_time(void);\n#endif\n#if defined(DUK_USE_DATE_NOW_WINDOWS)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows(void);\n#endif\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows_subms(void);\n#endif\n#if defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S) || defined(DUK_USE_DATE_TZO_GMTIME)\nDUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d);\n#endif\n#if defined(DUK_USE_DATE_TZO_WINDOWS)\nDUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d);\n#endif\n#if defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST)\nDUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_t d);\n#endif\n#if defined(DUK_USE_DATE_PRS_STRPTIME)\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_strptime(duk_hthread *thr, const char *str);\n#endif\n#if defined(DUK_USE_DATE_PRS_GETDATE)\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_getdate(duk_hthread *thr, const char *str);\n#endif\n#if defined(DUK_USE_DATE_FMT_STRFTIME)\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags);\n#endif\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_monotonic_time_clock_gettime(void);\n#endif\n#if defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_monotonic_time_windows_qpc(void);\n#endif\n\nDUK_INTERNAL_DECL\nvoid duk_bi_json_parse_helper(duk_hthread *thr,\n                              duk_idx_t idx_value,\n                              duk_idx_t idx_reviver,\n                              duk_small_uint_t flags);\nDUK_INTERNAL_DECL\nvoid duk_bi_json_stringify_helper(duk_hthread *thr,\n                                  duk_idx_t idx_value,\n                                  duk_idx_t idx_replacer,\n                                  duk_idx_t idx_space,\n                                  duk_small_uint_t flags);\n\nDUK_INTERNAL_DECL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_hthread *thr);\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL_DECL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h_proxy_target, duk_uint_t flags);\n#endif\n\n#endif  /* DUK_BUILTIN_PROTOS_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_proxy.c",
    "content": "/*\n *  Proxy built-in (ES2015)\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_ES6_PROXY)\n/* Post-process a Proxy ownKeys() result at stack top.  Push a cleaned up\n * array of valid result keys (strings or symbols).  TypeError for invalid\n * values.  Flags are shared with duk_enum().\n */\nDUK_INTERNAL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h_proxy_target, duk_uint_t flags) {\n\tduk_uarridx_t i, len, idx;\n\tduk_propdesc desc;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(h_proxy_target != NULL);\n\n\tlen = (duk_uarridx_t) duk_get_length(thr, -1);\n\tidx = 0;\n\tduk_push_array(thr);\n\t/* XXX: preallocated dense array, fill in directly */\n\tfor (i = 0; i < len; i++) {\n\t\tduk_hstring *h;\n\n\t\t/* [ obj trap_result res_arr ] */\n\t\t(void) duk_get_prop_index(thr, -2, i);\n\t\th = duk_get_hstring(thr, -1);\n\t\tif (h == NULL) {\n\t\t\tDUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\n\t\tif (!(flags & DUK_ENUM_INCLUDE_NONENUMERABLE)) {\n\t\t\t/* No support for 'getOwnPropertyDescriptor' trap yet,\n\t\t\t * so check enumerability always from target object\n\t\t\t * descriptor.\n\t\t\t */\n\t\t\tif (duk_hobject_get_own_propdesc(thr, h_proxy_target, duk_known_hstring(thr, -1), &desc, 0 /*flags*/)) {\n\t\t\t\tif ((desc.flags & DUK_PROPDESC_FLAG_ENUMERABLE) == 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore non-enumerable property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\t\tgoto skip_key;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore non-existent property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t}\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tif (!(flags & DUK_ENUM_INCLUDE_SYMBOLS)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore symbol property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t\tif (DUK_HSTRING_HAS_HIDDEN(h) && !(flags & DUK_ENUM_INCLUDE_HIDDEN)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore hidden symbol property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t} else {\n\t\t\tif (flags & DUK_ENUM_EXCLUDE_STRINGS) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore string property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t}\n\n\t\t/* [ obj trap_result res_arr propname ] */\n\t\tduk_put_prop_index(thr, -2, idx++);\n\t\tcontinue;\n\n\t skip_key:\n\t\tduk_pop(thr);\n\t\tcontinue;\n\t}\n\n\t/* XXX: Missing trap result validation for non-configurable target keys\n\t * (must be present), for non-extensible target all target keys must be\n\t * present and no extra keys can be present.\n\t * http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys\n\t */\n\n\t/* XXX: The key enumerability check should trigger the \"getOwnPropertyDescriptor\"\n\t * trap which has not yet been implemented.  In the absence of such a trap,\n\t * the enumerability should be checked from the target object; this is\n\t * handled above.\n\t */\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL duk_ret_t duk_bi_proxy_constructor(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 2);  /* [ target handler ] */\n\n\tduk_require_constructor_call(thr);\n\tduk_push_proxy(thr, 0 /*flags*/);  /* [ target handler ] -> [ proxy ] */\n\treturn 1;  /* replacement */\n}\n#endif  /* DUK_USE_ES6_PROXY */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_reflect.c",
    "content": "/*\n *  'Reflect' built-in (ES2016 Section 26.1)\n *  http://www.ecma-international.org/ecma-262/7.0/#sec-reflect-object\n *\n *  Many Reflect built-in functions are provided by shared helpers in\n *  duk_bi_object.c or duk_bi_function.c.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_delete_property(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\n\t/* [ target key ] */\n\n\tDUK_ASSERT(thr != NULL);\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\tret = duk_hobject_delprop(thr, tv_obj, tv_key, 0 /*throw_flag*/);\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_get(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_idx_t nargs;\n\n\tDUK_ASSERT(thr != NULL);\n\tnargs = duk_get_top_require_min(thr, 2 /*min_top*/);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\tif (nargs >= 3 && !duk_strict_equals(thr, 0, 2)) {\n\t\t/* XXX: [[Get]] receiver currently unsupported */\n\t\tDUK_ERROR_UNSUPPORTED(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* [ target key receiver? ...? ] */\n\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\t(void) duk_hobject_getprop(thr, tv_obj, tv_key);  /* This could also be a duk_get_prop(). */\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_has(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT_TOP(thr, 2);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\n\t/* [ target key ] */\n\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\tret = duk_hobject_hasprop(thr, tv_obj, tv_key);\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_set(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_tval *tv_val;\n\tduk_idx_t nargs;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\tnargs = duk_get_top_require_min(thr, 3 /*min_top*/);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\tif (nargs >= 4 && !duk_strict_equals(thr, 0, 3)) {\n\t\t/* XXX: [[Set]] receiver currently unsupported */\n\t\tDUK_ERROR_UNSUPPORTED(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* [ target key value receiver? ...? ] */\n\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\ttv_val = DUK_GET_TVAL_POSIDX(thr, 2);\n\tret = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, 0 /*throw_flag*/);\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_REFLECT_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_regexp.c",
    "content": "/*\n *  RegExp built-ins\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\nDUK_LOCAL void duk__get_this_regexp(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\tduk_push_this(thr);\n\th = duk_require_hobject_with_class(thr, -1, DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_ASSERT(h != NULL);\n\tDUK_UNREF(h);\n\tduk_insert(thr, 0);  /* prepend regexp to valstack 0 index */\n}\n\n/* XXX: much to improve (code size) */\nDUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_hthread *thr) {\n\tduk_hobject *h_pattern;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\th_pattern = duk_get_hobject(thr, 0);\n\n\tif (!duk_is_constructor_call(thr) &&\n\t    h_pattern != NULL &&\n\t    DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP &&\n\t    duk_is_undefined(thr, 1)) {\n\t\t/* Called as a function, pattern has [[Class]] \"RegExp\" and\n\t\t * flags is undefined -> return object as is.\n\t\t */\n\t\t/* XXX: ES2015 has a NewTarget SameValue() check which is not\n\t\t * yet implemented.\n\t\t */\n\t\tduk_dup_0(thr);\n\t\treturn 1;\n\t}\n\n\t/* Else functionality is identical for function call and constructor\n\t * call.\n\t */\n\n\tif (h_pattern != NULL &&\n\t    DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP) {\n\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_SOURCE);\n\t\tif (duk_is_undefined(thr, 1)) {\n\t\t\t/* In ES5 one would need to read the flags individually;\n\t\t\t * in ES2015 just read .flags.\n\t\t\t */\n\t\t\tduk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS);\n\t\t} else {\n\t\t\t/* In ES2015 allowed; overrides argument RegExp flags. */\n\t\t\tduk_dup_1(thr);\n\t\t}\n\t} else {\n\t\tif (duk_is_undefined(thr, 0)) {\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_to_string(thr, -1);  /* Rejects Symbols. */\n\t\t}\n\t\tif (duk_is_undefined(thr, 1)) {\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tduk_dup_1(thr);\n\t\t\tduk_to_string(thr, -1);  /* Rejects Symbols. */\n\t\t}\n\n\t\t/* [ ... pattern flags ] */\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"RegExp constructor/function call, pattern=%!T, flags=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* [ ... pattern flags ] (both uncoerced) */\n\n\tduk_to_string(thr, -2);\n\tduk_to_string(thr, -1);\n\tduk_regexp_compile(thr);\n\n\t/* [ ... bytecode escaped_source ] */\n\n\tduk_regexp_create_instance(thr);\n\n\t/* [ ... RegExp ] */\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_exec(duk_hthread *thr) {\n\tduk__get_this_regexp(thr);\n\n\t/* [ regexp input ] */\n\n\tduk_regexp_match(thr);\n\n\t/* [ result ] */\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_test(duk_hthread *thr) {\n\tduk__get_this_regexp(thr);\n\n\t/* [ regexp input ] */\n\n\t/* result object is created and discarded; wasteful but saves code space */\n\tduk_regexp_match(thr);\n\n\t/* [ result ] */\n\n\tduk_push_boolean(thr, (duk_is_null(thr, -1) ? 0 : 1));\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_tostring(duk_hthread *thr) {\n\t/* This must be generic in ES2015 and later. */\n\tDUK_ASSERT_TOP(thr, 0);\n\tduk_push_this(thr);\n\tduk_push_literal(thr, \"/\");\n\tduk_get_prop_stridx(thr, 0, DUK_STRIDX_SOURCE);\n\tduk_dup_m2(thr);  /* another \"/\" */\n\tduk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS);\n\tduk_concat(thr, 4);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_flags(duk_hthread *thr) {\n\t/* .flags is ES2015 but present even when ES2015 bindings are\n\t * disabled because the constructor relies on it.\n\t */\n\tduk_uint8_t buf[8];  /* enough for all flags + NUL */\n\tduk_uint8_t *p = buf;\n\n\t/* .flags is generic and works on any object. */\n\tduk_push_this(thr);\n\t(void) duk_require_hobject(thr, -1);\n\tif (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL)) {\n\t\t*p++ = DUK_ASC_LC_G;\n\t}\n\tif (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_IGNORE_CASE, NULL)) {\n\t\t*p++ = DUK_ASC_LC_I;\n\t}\n\tif (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_MULTILINE, NULL)) {\n\t\t*p++ = DUK_ASC_LC_M;\n\t}\n\t/* .unicode: to be added */\n\t/* .sticky: to be added */\n\t*p++ = DUK_ASC_NUL;\n\tDUK_ASSERT((duk_size_t) (p - buf) <= sizeof(buf));\n\n\tduk_push_string(thr, (const char *) buf);\n\treturn 1;\n}\n\n/* Shared helper for providing .source, .global, .multiline, etc getters. */\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_hthread *thr) {\n\tduk_hstring *h_bc;\n\tduk_small_uint_t re_flags;\n\tduk_hobject *h;\n\tduk_int_t magic;\n\n\tDUK_ASSERT_TOP(thr, 0);\n\n\tduk_push_this(thr);\n\th = duk_require_hobject(thr, -1);\n\tmagic = duk_get_current_magic(thr);\n\n\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_REGEXP) {\n\t\tduk_xget_owndataprop_stridx_short(thr, 0, DUK_STRIDX_INT_SOURCE);\n\t\tduk_xget_owndataprop_stridx_short(thr, 0, DUK_STRIDX_INT_BYTECODE);\n\t\th_bc = duk_require_hstring(thr, -1);\n\t\tre_flags = (duk_small_uint_t) DUK_HSTRING_GET_DATA(h_bc)[0];  /* Safe even if h_bc length is 0 (= NUL) */\n\t\tduk_pop(thr);\n\t} else if (h == thr->builtins[DUK_BIDX_REGEXP_PROTOTYPE]) {\n\t\t/* In ES2015 and ES2016 a TypeError would be thrown here.\n\t\t * However, this had real world issues so ES2017 draft\n\t\t * allows RegExp.prototype specifically, returning '(?:)'\n\t\t * for .source and undefined for all flags.\n\t\t */\n\t\tif (magic != 16 /* .source */) {\n\t\t\treturn 0;\n\t\t}\n\t\tduk_push_literal(thr, \"(?:)\");  /* .source handled by switch-case */\n\t\tre_flags = 0;\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* [ regexp source ] */\n\n\tswitch (magic) {\n\tcase 0: {  /* global */\n\t\tduk_push_boolean(thr, (re_flags & DUK_RE_FLAG_GLOBAL));\n\t\tbreak;\n\t}\n\tcase 1: {  /* ignoreCase */\n\t\tduk_push_boolean(thr, (re_flags & DUK_RE_FLAG_IGNORE_CASE));\n\t\tbreak;\n\t}\n\tcase 2: {  /* multiline */\n\t\tduk_push_boolean(thr, (re_flags & DUK_RE_FLAG_MULTILINE));\n\t\tbreak;\n\t}\n#if 0\n\t/* Don't provide until implemented to avoid interfering with feature\n\t * detection in user code.\n\t */\n\tcase 3:    /* sticky */\n\tcase 4: {  /* unicode */\n\t\tduk_push_false(thr);\n\t\tbreak;\n\t}\n#endif\n\tdefault: {  /* source */\n\t\t/* leave 'source' on top */\n\t\tbreak;\n\t}\n\t}\n\n\treturn 1;\n}\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_string.c",
    "content": "/*\n *  String built-ins\n *\n *  Most String built-ins must only accept strings (or String objects).\n *  Symbols, represented internally as strings, must be generally rejected.\n *  The duk_push_this_coercible_to_string() helper does this automatically.\n */\n\n/* XXX: There are several limitations in the current implementation for\n * strings with >= 0x80000000UL characters.  In some cases one would need\n * to be able to represent the range [-0xffffffff,0xffffffff] and so on.\n * Generally character and byte length are assumed to fit into signed 32\n * bits (< 0x80000000UL).  Places with issues are not marked explicitly\n * below in all cases, look for signed type usage (duk_int_t etc) for\n * offsets/lengths.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_STRING_BUILTIN)\n\n/*\n *  Helpers\n */\n\nDUK_LOCAL duk_hstring *duk__str_tostring_notregexp(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tif (duk_get_class_number(thr, idx) == DUK_HOBJECT_CLASS_REGEXP) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\th = duk_to_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\treturn h;\n}\n\nDUK_LOCAL duk_int_t duk__str_search_shared(duk_hthread *thr, duk_hstring *h_this, duk_hstring *h_search, duk_int_t start_cpos, duk_bool_t backwards) {\n\tduk_int_t cpos;\n\tduk_int_t bpos;\n\tconst duk_uint8_t *p_start, *p_end, *p;\n\tconst duk_uint8_t *q_start;\n\tduk_int_t q_blen;\n\tduk_uint8_t firstbyte;\n\tduk_uint8_t t;\n\n\tcpos = start_cpos;\n\n\t/* Empty searchstring always matches; cpos must be clamped here.\n\t * (If q_blen were < 0 due to clamped coercion, it would also be\n\t * caught here.)\n\t */\n\tq_start = DUK_HSTRING_GET_DATA(h_search);\n\tq_blen = (duk_int_t) DUK_HSTRING_GET_BYTELEN(h_search);\n\tif (q_blen <= 0) {\n\t\treturn cpos;\n\t}\n\tDUK_ASSERT(q_blen > 0);\n\n\tbpos = (duk_int_t) duk_heap_strcache_offset_char2byte(thr, h_this, (duk_uint32_t) cpos);\n\n\tp_start = DUK_HSTRING_GET_DATA(h_this);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_this);\n\tp = p_start + bpos;\n\n\t/* This loop is optimized for size.  For speed, there should be\n\t * two separate loops, and we should ensure that memcmp() can be\n\t * used without an extra \"will searchstring fit\" check.  Doing\n\t * the preconditioning for 'p' and 'p_end' is easy but cpos\n\t * must be updated if 'p' is wound back (backward scanning).\n\t */\n\n\tfirstbyte = q_start[0];  /* leading byte of match string */\n\twhile (p <= p_end && p >= p_start) {\n\t\tt = *p;\n\n\t\t/* For ECMAScript strings, this check can only match for\n\t\t * initial UTF-8 bytes (not continuation bytes).  For other\n\t\t * strings all bets are off.\n\t\t */\n\n\t\tif ((t == firstbyte) && ((duk_size_t) (p_end - p) >= (duk_size_t) q_blen)) {\n\t\t\tDUK_ASSERT(q_blen > 0);\n\t\t\tif (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {\n\t\t\t\treturn cpos;\n\t\t\t}\n\t\t}\n\n\t\t/* track cpos while scanning */\n\t\tif (backwards) {\n\t\t\t/* when going backwards, we decrement cpos 'early';\n\t\t\t * 'p' may point to a continuation byte of the char\n\t\t\t * at offset 'cpos', but that's OK because we'll\n\t\t\t * backtrack all the way to the initial byte.\n\t\t\t */\n\t\t\tif ((t & 0xc0) != 0x80) {\n\t\t\t\tcpos--;\n\t\t\t}\n\t\t\tp--;\n\t\t} else {\n\t\t\tif ((t & 0xc0) != 0x80) {\n\t\t\t\tcpos++;\n\t\t\t}\n\t\t\tp++;\n\t\t}\n\t}\n\n\t/* Not found.  Empty string case is handled specially above. */\n\treturn -1;\n}\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_constructor(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_uint_t flags;\n\n\t/* String constructor needs to distinguish between an argument not given at all\n\t * vs. given as 'undefined'.  We're a vararg function to handle this properly.\n\t */\n\n\t/* XXX: copy current activation flags to thr, including current magic,\n\t * is_constructor_call etc.  This takes a few bytes in duk_hthread but\n\t * makes call sites smaller (there are >30 is_constructor_call and get\n\t * current magic call sites.\n\t */\n\n\tif (duk_get_top(thr) == 0) {\n\t\tduk_push_hstring_empty(thr);\n\t} else {\n\t\th = duk_to_hstring_acceptsymbol(thr, 0);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h) && !duk_is_constructor_call(thr))) {\n\t\t\tduk_push_symbol_descriptive_string(thr, h);\n\t\t\tduk_replace(thr, 0);\n\t\t}\n\t}\n\tduk_to_string(thr, 0);  /* catches symbol argument for constructor call */\n\tDUK_ASSERT(duk_is_string(thr, 0));\n\tduk_set_top(thr, 1);  /* Top may be 1 or larger. */\n\n\tif (duk_is_constructor_call(thr)) {\n\t\t/* String object internal value is immutable */\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_STRING);\n\t\tduk_push_object_helper(thr, flags, DUK_BIDX_STRING_PROTOTYPE);\n\t\tduk_dup_0(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\t/* Note: unbalanced stack on purpose */\n\n\treturn 1;\n}\n\nDUK_LOCAL duk_ret_t duk__construct_from_codepoints(duk_hthread *thr, duk_bool_t nonbmp) {\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tduk_idx_t i, n;\n\tduk_ucodepoint_t cp;\n\n\t/* XXX: It would be nice to build the string directly but ToUint16()\n\t * coercion is needed so a generic helper would not be very\n\t * helpful (perhaps coerce the value stack first here and then\n\t * build a string from a duk_tval number sequence in one go?).\n\t */\n\n\tn = duk_get_top(thr);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, (duk_size_t) n);  /* initial estimate for ASCII only codepoints */\n\n\tfor (i = 0; i < n; i++) {\n\t\t/* XXX: could improve bufwriter handling to write multiple codepoints\n\t\t * with one ensure call but the relative benefit would be quite small.\n\t\t */\n\n\t\tif (nonbmp) {\n\t\t\t/* ES2015 requires that (1) SameValue(cp, ToInteger(cp)) and\n\t\t\t * (2) cp >= 0 and cp <= 0x10ffff.  This check does not\n\t\t\t * implement the steps exactly but the outcome should be\n\t\t\t * the same.\n\t\t\t */\n\t\t\tduk_int32_t i32 = 0;\n\t\t\tif (!duk_is_whole_get_int32(duk_to_number(thr, i), &i32) ||\n\t\t\t    i32 < 0 || i32 > 0x10ffffL) {\n\t\t\t\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n\t\t\t}\n\t\t\tDUK_ASSERT(i32 >= 0 && i32 <= 0x10ffffL);\n\t\t\tcp = (duk_ucodepoint_t) i32;\n\t\t\tDUK_BW_WRITE_ENSURE_CESU8(thr, bw, cp);\n\t\t} else {\n#if defined(DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT)\n\t\t\t/* ToUint16() coercion is mandatory in the E5.1 specification, but\n\t\t\t * this non-compliant behavior makes more sense because we support\n\t\t\t * non-BMP codepoints.  Don't use CESU-8 because that'd create\n\t\t\t * surrogate pairs.\n\t\t\t */\n\t\t\tcp = (duk_ucodepoint_t) duk_to_uint32(thr, i);\n\t\t\tDUK_BW_WRITE_ENSURE_XUTF8(thr, bw, cp);\n#else\n\t\t\tcp = (duk_ucodepoint_t) duk_to_uint16(thr, i);\n\t\t\tDUK_ASSERT(cp >= 0 && cp <= 0x10ffffL);\n\t\t\tDUK_BW_WRITE_ENSURE_CESU8(thr, bw, cp);\n#endif\n\t\t}\n\t}\n\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe, extended UTF-8 or CESU-8 encoded. */\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_string_constructor_from_char_code(duk_hthread *thr) {\n\treturn duk__construct_from_codepoints(thr, 0 /*nonbmp*/);\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_constructor_from_code_point(duk_hthread *thr) {\n\treturn duk__construct_from_codepoints(thr, 1 /*nonbmp*/);\n}\n#endif\n\n/*\n *  toString(), valueOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_to_string(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tduk_push_this(thr);\n\ttv = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_STRING(tv)) {\n\t\t/* return as is */\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* Must be a \"string object\", i.e. class \"String\" */\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_STRING) {\n\t\t\tgoto type_error;\n\t\t}\n\n\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\t} else {\n\t\tgoto type_error;\n\t}\n\n\t(void) duk_require_hstring_notsymbol(thr, -1);  /* Reject symbols (and wrapped symbols). */\n\treturn 1;\n\n type_error:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n\n/*\n *  Character and charcode access\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_at(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t pos;\n\n\t/* XXX: faster implementation */\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tpos = duk_to_int(thr, 0);\n\n\tif (sizeof(duk_size_t) >= sizeof(duk_uint_t)) {\n\t\t/* Cast to duk_size_t works in this case:\n\t\t * - If pos < 0, (duk_size_t) pos will always be\n\t\t *   >= max_charlen, and result will be the empty string\n\t\t *   (see duk_substring()).\n\t\t * - If pos >= 0, pos + 1 cannot wrap.\n\t\t */\n\t\tDUK_ASSERT((duk_size_t) DUK_INT_MIN >= DUK_HSTRING_MAX_BYTELEN);\n\t\tDUK_ASSERT((duk_size_t) DUK_INT_MAX + 1U > (duk_size_t) DUK_INT_MAX);\n\t\tduk_substring(thr, -1, (duk_size_t) pos, (duk_size_t) pos + 1U);\n\t} else {\n\t\t/* If size_t is smaller than int, explicit bounds checks\n\t\t * are needed because an int may wrap multiple times.\n\t\t */\n\t\tif (DUK_UNLIKELY(pos < 0 || (duk_uint_t) pos >= (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h))) {\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tduk_substring(thr, -1, (duk_size_t) pos, (duk_size_t) pos + 1U);\n\t\t}\n\t}\n\n\treturn 1;\n}\n\n/* Magic: 0=charCodeAt, 1=codePointAt */\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_code_at(duk_hthread *thr) {\n\tduk_int_t pos;\n\tduk_hstring *h;\n\tduk_bool_t clamped;\n\tduk_uint32_t cp;\n\tduk_int_t magic;\n\n\t/* XXX: faster implementation */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arg=%!T\", (duk_tval *) duk_get_tval(thr, 0)));\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tpos = duk_to_int_clamped_raw(thr,\n\t                             0 /*index*/,\n\t                             0 /*min(incl)*/,\n\t                             (duk_int_t) DUK_HSTRING_GET_CHARLEN(h) - 1 /*max(incl)*/,\n\t                             &clamped /*out_clamped*/);\n#if defined(DUK_USE_ES6)\n\tmagic = duk_get_current_magic(thr);\n#else\n\tDUK_ASSERT(duk_get_current_magic(thr) == 0);\n\tmagic = 0;\n#endif\n\tif (clamped) {\n\t\t/* For out-of-bounds indices .charCodeAt() returns NaN and\n\t\t * .codePointAt() returns undefined.\n\t\t */\n\t\tif (magic != 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tduk_push_nan(thr);\n\t} else {\n\t\tDUK_ASSERT(pos >= 0);\n\t\tcp = (duk_uint32_t) duk_hstring_char_code_at_raw(thr, h, (duk_uint_t) pos, (duk_bool_t) magic /*surrogate_aware*/);\n\t\tduk_push_u32(thr, cp);\n\t}\n\treturn 1;\n}\n\n/*\n *  substring(), substr(), slice()\n */\n\n/* XXX: any chance of merging these three similar but still slightly\n * different algorithms so that footprint would be reduced?\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_substring(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t start_pos, end_pos;\n\tduk_int_t len;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\n\t/* [ start end str ] */\n\n\tstart_pos = duk_to_int_clamped(thr, 0, 0, len);\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend_pos = len;\n\t} else {\n\t\tend_pos = duk_to_int_clamped(thr, 1, 0, len);\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\tDUK_ASSERT(end_pos >= 0 && end_pos <= len);\n\n\tif (start_pos > end_pos) {\n\t\tduk_int_t tmp = start_pos;\n\t\tstart_pos = end_pos;\n\t\tend_pos = tmp;\n\t}\n\n\tDUK_ASSERT(end_pos >= start_pos);\n\n\tduk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);\n\treturn 1;\n}\n\n#if defined(DUK_USE_SECTION_B)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_substr(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t start_pos, end_pos;\n\tduk_int_t len;\n\n\t/* Unlike non-obsolete String calls, substr() algorithm in E5.1\n\t * specification will happily coerce undefined and null to strings\n\t * (\"undefined\" and \"null\").\n\t */\n\tduk_push_this(thr);\n\th = duk_to_hstring_m1(thr);  /* Reject Symbols. */\n\tDUK_ASSERT(h != NULL);\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\n\t/* [ start length str ] */\n\n\t/* The implementation for computing of start_pos and end_pos differs\n\t * from the standard algorithm, but is intended to result in the exactly\n\t * same behavior.  This is not always obvious.\n\t */\n\n\t/* combines steps 2 and 5; -len ensures max() not needed for step 5 */\n\tstart_pos = duk_to_int_clamped(thr, 0, -len, len);\n\tif (start_pos < 0) {\n\t\tstart_pos = len + start_pos;\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\n\t/* combines steps 3, 6; step 7 is not needed */\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend_pos = len;\n\t} else {\n\t\tDUK_ASSERT(start_pos <= len);\n\t\tend_pos = start_pos + duk_to_int_clamped(thr, 1, 0, len - start_pos);\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\tDUK_ASSERT(end_pos >= 0 && end_pos <= len);\n\tDUK_ASSERT(end_pos >= start_pos);\n\n\tduk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);\n\treturn 1;\n}\n#endif  /* DUK_USE_SECTION_B */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_slice(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t start_pos, end_pos;\n\tduk_int_t len;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\n\t/* [ start end str ] */\n\n\tstart_pos = duk_to_int_clamped(thr, 0, -len, len);\n\tif (start_pos < 0) {\n\t\tstart_pos = len + start_pos;\n\t}\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend_pos = len;\n\t} else {\n\t\tend_pos = duk_to_int_clamped(thr, 1, -len, len);\n\t\tif (end_pos < 0) {\n\t\t\tend_pos = len + end_pos;\n\t\t}\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\tDUK_ASSERT(end_pos >= 0 && end_pos <= len);\n\n\tif (end_pos < start_pos) {\n\t\tend_pos = start_pos;\n\t}\n\n\tDUK_ASSERT(end_pos >= start_pos);\n\n\tduk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);\n\treturn 1;\n}\n\n/*\n *  Case conversion\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_caseconv_shared(duk_hthread *thr) {\n\tduk_small_int_t uppercase = duk_get_current_magic(thr);\n\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk_unicode_case_convert_string(thr, (duk_bool_t) uppercase);\n\treturn 1;\n}\n\n/*\n *  indexOf() and lastIndexOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_indexof_shared(duk_hthread *thr) {\n\tduk_hstring *h_this;\n\tduk_hstring *h_search;\n\tduk_int_t clen_this;\n\tduk_int_t cpos;\n\tduk_small_uint_t is_lastindexof = (duk_small_uint_t) duk_get_current_magic(thr);  /* 0=indexOf, 1=lastIndexOf */\n\n\th_this = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_this != NULL);\n\tclen_this = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h_this);\n\n\th_search = duk_to_hstring(thr, 0);\n\tDUK_ASSERT(h_search != NULL);\n\n\tduk_to_number(thr, 1);\n\tif (duk_is_nan(thr, 1) && is_lastindexof) {\n\t\t/* indexOf: NaN should cause pos to be zero.\n\t\t * lastIndexOf: NaN should cause pos to be +Infinity\n\t\t * (and later be clamped to len).\n\t\t */\n\t\tcpos = clen_this;\n\t} else {\n\t\tcpos = duk_to_int_clamped(thr, 1, 0, clen_this);\n\t}\n\n\tcpos = duk__str_search_shared(thr, h_this, h_search, cpos, is_lastindexof /*backwards*/);\n\tduk_push_int(thr, cpos);\n\treturn 1;\n}\n\n/*\n *  replace()\n */\n\n/* XXX: the current implementation works but is quite clunky; it compiles\n * to almost 1,4kB of x86 code so it needs to be simplified (better approach,\n * shared helpers, etc).  Some ideas for refactoring:\n *\n * - a primitive to convert a string into a regexp matcher (reduces matching\n *   code at the cost of making matching much slower)\n * - use replace() as a basic helper for match() and split(), which are both\n *   much simpler\n * - API call to get_prop and to_boolean\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {\n\tduk_hstring *h_input;\n\tduk_hstring *h_match;\n\tduk_hstring *h_search;\n\tduk_hobject *h_re;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tduk_bool_t is_regexp;\n\tduk_bool_t is_global;\n#endif\n\tduk_bool_t is_repl_func;\n\tduk_uint32_t match_start_coff, match_start_boff;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tduk_int_t match_caps;\n#endif\n\tduk_uint32_t prev_match_end_boff;\n\tconst duk_uint8_t *r_start, *r_end, *r;   /* repl string scan */\n\tduk_size_t tmp_sz;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\th_input = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_input != NULL);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input));  /* input size is good output starting point */\n\n\tDUK_ASSERT_TOP(thr, 4);\n\n\t/* stack[0] = search value\n\t * stack[1] = replace value\n\t * stack[2] = input string\n\t * stack[3] = result buffer\n\t */\n\n\th_re = duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_REGEXP);\n\tif (h_re) {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tis_regexp = 1;\n\t\tis_global = duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL);\n\n\t\tif (is_global) {\n\t\t\t/* start match from beginning */\n\t\t\tduk_push_int(thr, 0);\n\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t}\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\tDUK_DCERROR_UNSUPPORTED(thr);\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t} else {\n\t\tduk_to_string(thr, 0);  /* rejects symbols */\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tis_regexp = 0;\n\t\tis_global = 0;\n#endif\n\t}\n\n\tif (duk_is_function(thr, 1)) {\n\t\tis_repl_func = 1;\n\t\tr_start = NULL;\n\t\tr_end = NULL;\n\t} else {\n\t\tduk_hstring *h_repl;\n\n\t\tis_repl_func = 0;\n\t\th_repl = duk_to_hstring(thr, 1);  /* reject symbols */\n\t\tDUK_ASSERT(h_repl != NULL);\n\t\tr_start = DUK_HSTRING_GET_DATA(h_repl);\n\t\tr_end = r_start + DUK_HSTRING_GET_BYTELEN(h_repl);\n\t}\n\n\tprev_match_end_boff = 0;\n\n\tfor (;;) {\n\t\t/*\n\t\t *  If matching with a regexp:\n\t\t *    - non-global RegExp: lastIndex not touched on a match, zeroed\n\t\t *      on a non-match\n\t\t *    - global RegExp: on match, lastIndex will be updated by regexp\n\t\t *      executor to point to next char after the matching part (so that\n\t\t *      characters in the matching part are not matched again)\n\t\t *\n\t\t *  If matching with a string:\n\t\t *    - always non-global match, find first occurrence\n\t\t *\n\t\t *  We need:\n\t\t *    - The character offset of start-of-match for the replacer function\n\t\t *    - The byte offsets for start-of-match and end-of-match to implement\n\t\t *      the replacement values $&, $`, and $', and to copy non-matching\n\t\t *      input string portions (including header and trailer) verbatim.\n\t\t *\n\t\t *  NOTE: the E5.1 specification is a bit vague how the RegExp should\n\t\t *  behave in the replacement process; e.g. is matching done first for\n\t\t *  all matches (in the global RegExp case) before any replacer calls\n\t\t *  are made?  See: test-bi-string-proto-replace.js for discussion.\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, 4);\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (is_regexp) {\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_dup_2(thr);\n\t\t\tduk_regexp_match(thr);  /* [ ... regexp input ] -> [ res_obj ] */\n\t\t\tif (!duk_is_object(thr, -1)) {\n\t\t\t\tduk_pop(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX);\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tmatch_start_coff = duk_get_uint(thr, -1);\n\t\t\tduk_pop(thr);\n\n\t\t\tduk_get_prop_index(thr, -1, 0);\n\t\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\t\t\th_match = duk_known_hstring(thr, -1);\n\t\t\tduk_pop(thr);  /* h_match is borrowed, remains reachable through match_obj */\n\n\t\t\tif (DUK_HSTRING_GET_BYTELEN(h_match) == 0) {\n\t\t\t\t/* This should be equivalent to match() algorithm step 8.f.iii.2:\n\t\t\t\t * detect an empty match and allow it, but don't allow it twice.\n\t\t\t\t */\n\t\t\t\tduk_uint32_t last_index;\n\n\t\t\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\t\tlast_index = (duk_uint32_t) duk_get_uint(thr, -1);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"empty match, bump lastIndex: %ld -> %ld\",\n\t\t\t\t                     (long) last_index, (long) (last_index + 1)));\n\t\t\t\tduk_pop(thr);\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) (last_index + 1));\n\t\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\t}\n\n\t\t\tDUK_ASSERT(duk_get_length(thr, -1) <= DUK_INT_MAX);  /* string limits */\n\t\t\tmatch_caps = (duk_int_t) duk_get_length(thr, -1);\n\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\tconst duk_uint8_t *p_start, *p_end, *p;   /* input string scan */\n\t\t\tconst duk_uint8_t *q_start;               /* match string */\n\t\t\tduk_size_t q_blen;\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\tDUK_ASSERT(!is_global);  /* single match always */\n#endif\n\n\t\t\tp_start = DUK_HSTRING_GET_DATA(h_input);\n\t\t\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\t\t\tp = p_start;\n\n\t\t\th_search = duk_known_hstring(thr, 0);\n\t\t\tq_start = DUK_HSTRING_GET_DATA(h_search);\n\t\t\tq_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_search);\n\n\t\t\tp_end -= q_blen;  /* ensure full memcmp() fits in while */\n\n\t\t\tmatch_start_coff = 0;\n\n\t\t\twhile (p <= p_end) {\n\t\t\t\tDUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + DUK_HSTRING_GET_BYTELEN(h_input));\n\t\t\t\tif (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {\n\t\t\t\t\tduk_dup_0(thr);\n\t\t\t\t\th_match = duk_known_hstring(thr, -1);\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t\t\tmatch_caps = 0;\n#endif\n\t\t\t\t\tgoto found;\n\t\t\t\t}\n\n\t\t\t\t/* track utf-8 non-continuation bytes */\n\t\t\t\tif ((p[0] & 0xc0) != 0x80) {\n\t\t\t\t\tmatch_start_coff++;\n\t\t\t\t}\n\t\t\t\tp++;\n\t\t\t}\n\n\t\t\t/* not found */\n\t\t\tbreak;\n\t\t}\n\t found:\n\n\t\t/* stack[0] = search value\n\t\t * stack[1] = replace value\n\t\t * stack[2] = input string\n\t\t * stack[3] = result buffer\n\t\t * stack[4] = regexp match OR match string\n\t\t */\n\n\t\tmatch_start_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h_input, match_start_coff);\n\n\t\ttmp_sz = (duk_size_t) (match_start_boff - prev_match_end_boff);\n\t\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff, tmp_sz);\n\n\t\tprev_match_end_boff = match_start_boff + DUK_HSTRING_GET_BYTELEN(h_match);\n\n\t\tif (is_repl_func) {\n\t\t\tduk_idx_t idx_args;\n\t\t\tduk_hstring *h_repl;\n\n\t\t\t/* regexp res_obj is at index 4 */\n\n\t\t\tduk_dup_1(thr);\n\t\t\tidx_args = duk_get_top(thr);\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\tif (is_regexp) {\n\t\t\t\tduk_int_t idx;\n\t\t\t\tduk_require_stack(thr, match_caps + 2);\n\t\t\t\tfor (idx = 0; idx < match_caps; idx++) {\n\t\t\t\t\t/* match followed by capture(s) */\n\t\t\t\t\tduk_get_prop_index(thr, 4, (duk_uarridx_t) idx);\n\t\t\t\t}\n\t\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t\t/* match == search string, by definition */\n\t\t\t\tduk_dup_0(thr);\n\t\t\t}\n\t\t\tduk_push_uint(thr, (duk_uint_t) match_start_coff);\n\t\t\tduk_dup_2(thr);\n\n\t\t\t/* [ ... replacer match [captures] match_char_offset input ] */\n\n\t\t\tduk_call(thr, duk_get_top(thr) - idx_args);\n\t\t\th_repl = duk_to_hstring_m1(thr);  /* -> [ ... repl_value ] */\n\t\t\tDUK_ASSERT(h_repl != NULL);\n\n\t\t\tDUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_repl);\n\n\t\t\tduk_pop(thr);  /* repl_value */\n\t\t} else {\n\t\t\tr = r_start;\n\n\t\t\twhile (r < r_end) {\n\t\t\t\tduk_int_t ch1;\n\t\t\t\tduk_int_t ch2;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t\tduk_int_t ch3;\n#endif\n\t\t\t\tduk_size_t left;\n\n\t\t\t\tch1 = *r++;\n\t\t\t\tif (ch1 != DUK_ASC_DOLLAR) {\n\t\t\t\t\tgoto repl_write;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(r <= r_end);\n\t\t\t\tleft = (duk_size_t) (r_end - r);\n\n\t\t\t\tif (left <= 0) {\n\t\t\t\t\tgoto repl_write;\n\t\t\t\t}\n\n\t\t\t\tch2 = r[0];\n\t\t\t\tswitch (ch2) {\n\t\t\t\tcase DUK_ASC_DOLLAR: {\n\t\t\t\t\tch1 = (1 << 8) + DUK_ASC_DOLLAR;\n\t\t\t\t\tgoto repl_write;\n\t\t\t\t}\n\t\t\t\tcase DUK_ASC_AMP: {\n\t\t\t\t\tDUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_match);\n\t\t\t\t\tr++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcase DUK_ASC_GRAVE: {\n\t\t\t\t\ttmp_sz = (duk_size_t) match_start_boff;\n\t\t\t\t\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input), tmp_sz);\n\t\t\t\t\tr++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcase DUK_ASC_SINGLEQUOTE: {\n\t\t\t\t\tduk_uint32_t match_end_boff;\n\n\t\t\t\t\t/* Use match charlen instead of bytelen, just in case the input and\n\t\t\t\t\t * match codepoint encodings would have different lengths.\n\t\t\t\t\t */\n\t\t\t\t\t/* XXX: charlen computed here, and also in char2byte helper. */\n\t\t\t\t\tmatch_end_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr,\n\t\t\t\t\t                                                                   h_input,\n\t\t\t\t\t                                                                   match_start_coff + (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h_match));\n\n\t\t\t\t\ttmp_sz = (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - match_end_boff);\n\t\t\t\t\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + match_end_boff, tmp_sz);\n\t\t\t\t\tr++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tdefault: {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t\t\tduk_int_t capnum, captmp, capadv;\n\t\t\t\t\t/* XXX: optional check, match_caps is zero if no regexp,\n\t\t\t\t\t * so dollar will be interpreted literally anyway.\n\t\t\t\t\t */\n\n\t\t\t\t\tif (!is_regexp) {\n\t\t\t\t\t\tgoto repl_write;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!(ch2 >= DUK_ASC_0 && ch2 <= DUK_ASC_9)) {\n\t\t\t\t\t\tgoto repl_write;\n\t\t\t\t\t}\n\t\t\t\t\tcapnum = ch2 - DUK_ASC_0;\n\t\t\t\t\tcapadv = 1;\n\n\t\t\t\t\tif (left >= 2) {\n\t\t\t\t\t\tch3 = r[1];\n\t\t\t\t\t\tif (ch3 >= DUK_ASC_0 && ch3 <= DUK_ASC_9) {\n\t\t\t\t\t\t\tcaptmp = capnum * 10 + (ch3 - DUK_ASC_0);\n\t\t\t\t\t\t\tif (captmp < match_caps) {\n\t\t\t\t\t\t\t\tcapnum = captmp;\n\t\t\t\t\t\t\t\tcapadv = 2;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (capnum > 0 && capnum < match_caps) {\n\t\t\t\t\t\tDUK_ASSERT(is_regexp != 0);  /* match_caps == 0 without regexps */\n\n\t\t\t\t\t\t/* regexp res_obj is at offset 4 */\n\t\t\t\t\t\tduk_get_prop_index(thr, 4, (duk_uarridx_t) capnum);\n\t\t\t\t\t\tif (duk_is_string(thr, -1)) {\n\t\t\t\t\t\t\tduk_hstring *h_tmp_str;\n\n\t\t\t\t\t\t\th_tmp_str = duk_known_hstring(thr, -1);\n\n\t\t\t\t\t\t\tDUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_tmp_str);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t/* undefined -> skip (replaced with empty) */\n\t\t\t\t\t\t}\n\t\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\t\tr += capadv;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgoto repl_write;\n\t\t\t\t\t}\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t\t\tgoto repl_write;  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t\t}  /* default case */\n\t\t\t\t}  /* switch (ch2) */\n\n\t\t\t repl_write:\n\t\t\t\t/* ch1 = (r_increment << 8) + byte */\n\n\t\t\t\tDUK_BW_WRITE_ENSURE_U8(thr, bw, (duk_uint8_t) (ch1 & 0xff));\n\t\t\t\tr += ch1 >> 8;\n\t\t\t}  /* while repl */\n\t\t}  /* if (is_repl_func) */\n\n\t\tduk_pop(thr);  /* pop regexp res_obj or match string */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (!is_global) {\n#else\n\t\t{  /* unconditionally; is_global==0 */\n#endif\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* trailer */\n\ttmp_sz = (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - prev_match_end_boff);\n\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff, tmp_sz);\n\n\tDUK_ASSERT_TOP(thr, 4);\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if inputs are safe. */\n\treturn 1;\n}\n\n/*\n *  split()\n */\n\n/* XXX: very messy now, but works; clean up, remove unused variables (nomimally\n * used so compiler doesn't complain).\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {\n\tduk_hstring *h_input;\n\tduk_hstring *h_sep;\n\tduk_uint32_t limit;\n\tduk_uint32_t arr_idx;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tduk_bool_t is_regexp;\n#endif\n\tduk_bool_t matched;  /* set to 1 if any match exists (needed for empty input special case) */\n\tduk_uint32_t prev_match_end_coff, prev_match_end_boff;\n\tduk_uint32_t match_start_boff, match_start_coff;\n\tduk_uint32_t match_end_boff, match_end_coff;\n\n\th_input = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_input != NULL);\n\n\tduk_push_array(thr);\n\n\tif (duk_is_undefined(thr, 1)) {\n\t\tlimit = 0xffffffffUL;\n\t} else {\n\t\tlimit = duk_to_uint32(thr, 1);\n\t}\n\n\tif (limit == 0) {\n\t\treturn 1;\n\t}\n\n\t/* If the separator is a RegExp, make a \"clone\" of it.  The specification\n\t * algorithm calls [[Match]] directly for specific indices; we emulate this\n\t * by tweaking lastIndex and using a \"force global\" variant of duk_regexp_match()\n\t * which will use global-style matching even when the RegExp itself is non-global.\n\t */\n\n\tif (duk_is_undefined(thr, 0)) {\n\t\t/* The spec algorithm first does \"R = ToString(separator)\" before checking\n\t\t * whether separator is undefined.  Since this is side effect free, we can\n\t\t * skip the ToString() here.\n\t\t */\n\t\tduk_dup_2(thr);\n\t\tduk_put_prop_index(thr, 3, 0);\n\t\treturn 1;\n\t} else if (duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_REGEXP) != NULL) {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tduk_push_hobject_bidx(thr, DUK_BIDX_REGEXP_CONSTRUCTOR);\n\t\tduk_dup_0(thr);\n\t\tduk_new(thr, 1);  /* [ ... RegExp val ] -> [ ... res ] */\n\t\tduk_replace(thr, 0);\n\t\t/* lastIndex is initialized to zero by new RegExp() */\n\t\tis_regexp = 1;\n#else\n\t\tDUK_DCERROR_UNSUPPORTED(thr);\n#endif\n\t} else {\n\t\tduk_to_string(thr, 0);\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tis_regexp = 0;\n#endif\n\t}\n\n\t/* stack[0] = separator (string or regexp)\n\t * stack[1] = limit\n\t * stack[2] = input string\n\t * stack[3] = result array\n\t */\n\n\tprev_match_end_boff = 0;\n\tprev_match_end_coff = 0;\n\tarr_idx = 0;\n\tmatched = 0;\n\n\tfor (;;) {\n\t\t/*\n\t\t *  The specification uses RegExp [[Match]] to attempt match at specific\n\t\t *  offsets.  We don't have such a primitive, so we use an actual RegExp\n\t\t *  and tweak lastIndex.  Since the RegExp may be non-global, we use a\n\t\t *  special variant which forces global-like behavior for matching.\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, 4);\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (is_regexp) {\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_dup_2(thr);\n\t\t\tduk_regexp_match_force_global(thr);  /* [ ... regexp input ] -> [ res_obj ] */\n\t\t\tif (!duk_is_object(thr, -1)) {\n\t\t\t\tduk_pop(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched = 1;\n\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX);\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tmatch_start_coff = duk_get_uint(thr, -1);\n\t\t\tmatch_start_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h_input, match_start_coff);\n\t\t\tduk_pop(thr);\n\n\t\t\tif (match_start_coff == DUK_HSTRING_GET_CHARLEN(h_input)) {\n\t\t\t\t/* don't allow an empty match at the end of the string */\n\t\t\t\tduk_pop(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tmatch_end_coff = duk_get_uint(thr, -1);\n\t\t\tmatch_end_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h_input, match_end_coff);\n\t\t\tduk_pop(thr);\n\n\t\t\t/* empty match -> bump and continue */\n\t\t\tif (prev_match_end_boff == match_end_boff) {\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) (match_end_coff + 1));\n\t\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\t\tduk_pop(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\tconst duk_uint8_t *p_start, *p_end, *p;   /* input string scan */\n\t\t\tconst duk_uint8_t *q_start;               /* match string */\n\t\t\tduk_size_t q_blen, q_clen;\n\n\t\t\tp_start = DUK_HSTRING_GET_DATA(h_input);\n\t\t\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\t\t\tp = p_start + prev_match_end_boff;\n\n\t\t\th_sep = duk_known_hstring(thr, 0);  /* symbol already rejected above */\n\t\t\tq_start = DUK_HSTRING_GET_DATA(h_sep);\n\t\t\tq_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sep);\n\t\t\tq_clen = (duk_size_t) DUK_HSTRING_GET_CHARLEN(h_sep);\n\n\t\t\tp_end -= q_blen;  /* ensure full memcmp() fits in while */\n\n\t\t\tmatch_start_coff = prev_match_end_coff;\n\n\t\t\tif (q_blen == 0) {\n\t\t\t\t/* Handle empty separator case: it will always match, and always\n\t\t\t\t * triggers the check in step 13.c.iii initially.  Note that we\n\t\t\t\t * must skip to either end of string or start of first codepoint,\n\t\t\t\t * skipping over any continuation bytes!\n\t\t\t\t *\n\t\t\t\t * Don't allow an empty string to match at the end of the input.\n\t\t\t\t */\n\n\t\t\t\tmatched = 1;  /* empty separator can always match */\n\n\t\t\t\tmatch_start_coff++;\n\t\t\t\tp++;\n\t\t\t\twhile (p < p_end) {\n\t\t\t\t\tif ((p[0] & 0xc0) != 0x80) {\n\t\t\t\t\t\tgoto found;\n\t\t\t\t\t}\n\t\t\t\t\tp++;\n\t\t\t\t}\n\t\t\t\tgoto not_found;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(q_blen > 0 && q_clen > 0);\n\t\t\twhile (p <= p_end) {\n\t\t\t\tDUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + DUK_HSTRING_GET_BYTELEN(h_input));\n\t\t\t\tDUK_ASSERT(q_blen > 0);  /* no issues with empty memcmp() */\n\t\t\t\tif (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {\n\t\t\t\t\t/* never an empty match, so step 13.c.iii can't be triggered */\n\t\t\t\t\tgoto found;\n\t\t\t\t}\n\n\t\t\t\t/* track utf-8 non-continuation bytes */\n\t\t\t\tif ((p[0] & 0xc0) != 0x80) {\n\t\t\t\t\tmatch_start_coff++;\n\t\t\t\t}\n\t\t\t\tp++;\n\t\t\t}\n\n\t\t not_found:\n\t\t\t/* not found */\n\t\t\tbreak;\n\n\t\t found:\n\t\t\tmatched = 1;\n\t\t\tmatch_start_boff = (duk_uint32_t) (p - p_start);\n\t\t\tmatch_end_coff = (duk_uint32_t) (match_start_coff + q_clen);  /* constrained by string length */\n\t\t\tmatch_end_boff = (duk_uint32_t) (match_start_boff + q_blen);  /* ditto */\n\n\t\t\t/* empty match (may happen with empty separator) -> bump and continue */\n\t\t\tif (prev_match_end_boff == match_end_boff) {\n\t\t\t\tprev_match_end_boff++;\n\t\t\t\tprev_match_end_coff++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}  /* if (is_regexp) */\n\n\t\t/* stack[0] = separator (string or regexp)\n\t\t * stack[1] = limit\n\t\t * stack[2] = input string\n\t\t * stack[3] = result array\n\t\t * stack[4] = regexp res_obj (if is_regexp)\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"split; match_start b=%ld,c=%ld, match_end b=%ld,c=%ld, prev_end b=%ld,c=%ld\",\n\t\t                     (long) match_start_boff, (long) match_start_coff,\n\t\t                     (long) match_end_boff, (long) match_end_coff,\n\t\t                     (long) prev_match_end_boff, (long) prev_match_end_coff));\n\n\t\tduk_push_lstring(thr,\n\t\t                 (const char *) (DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff),\n\t\t                 (duk_size_t) (match_start_boff - prev_match_end_boff));\n\t\tduk_put_prop_index(thr, 3, arr_idx);\n\t\tarr_idx++;\n\t\tif (arr_idx >= limit) {\n\t\t\tgoto hit_limit;\n\t\t}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (is_regexp) {\n\t\t\tduk_size_t i, len;\n\n\t\t\tlen = duk_get_length(thr, 4);\n\t\t\tfor (i = 1; i < len; i++) {\n\t\t\t\tDUK_ASSERT(i <= DUK_UARRIDX_MAX);  /* cannot have >4G captures */\n\t\t\t\tduk_get_prop_index(thr, 4, (duk_uarridx_t) i);\n\t\t\t\tduk_put_prop_index(thr, 3, arr_idx);\n\t\t\t\tarr_idx++;\n\t\t\t\tif (arr_idx >= limit) {\n\t\t\t\t\tgoto hit_limit;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_pop(thr);\n\t\t\t/* lastIndex already set up for next match */\n\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t/* no action */\n\t\t}\n\n\t\tprev_match_end_boff = match_end_boff;\n\t\tprev_match_end_coff = match_end_coff;\n\t\tcontinue;\n\t}  /* for */\n\n\t/* Combined step 11 (empty string special case) and 14-15. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"split trailer; prev_end b=%ld,c=%ld\",\n\t                     (long) prev_match_end_boff, (long) prev_match_end_coff));\n\n\tif (DUK_HSTRING_GET_BYTELEN(h_input) > 0 || !matched) {\n\t\t/* Add trailer if:\n\t\t *   a) non-empty input\n\t\t *   b) empty input and no (zero size) match found (step 11)\n\t\t */\n\n\t\tduk_push_lstring(thr,\n\t\t                 (const char *) DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff,\n\t\t                 (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - prev_match_end_boff));\n\t\tduk_put_prop_index(thr, 3, arr_idx);\n\t\t/* No arr_idx update or limit check */\n\t}\n\n\treturn 1;\n\n hit_limit:\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tif (is_regexp) {\n\t\tduk_pop(thr);\n\t}\n#endif\n\n\treturn 1;\n}\n\n/*\n *  Various\n */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_LOCAL void duk__to_regexp_helper(duk_hthread *thr, duk_idx_t idx, duk_bool_t force_new) {\n\tduk_hobject *h;\n\n\t/* Shared helper for match() steps 3-4, search() steps 3-4. */\n\n\tDUK_ASSERT(idx >= 0);\n\n\tif (force_new) {\n\t\tgoto do_new;\n\t}\n\n\th = duk_get_hobject_with_class(thr, idx, DUK_HOBJECT_CLASS_REGEXP);\n\tif (!h) {\n\t\tgoto do_new;\n\t}\n\treturn;\n\n do_new:\n\tduk_push_hobject_bidx(thr, DUK_BIDX_REGEXP_CONSTRUCTOR);\n\tduk_dup(thr, idx);\n\tduk_new(thr, 1);  /* [ ... RegExp val ] -> [ ... res ] */\n\tduk_replace(thr, idx);\n}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_search(duk_hthread *thr) {\n\t/* Easiest way to implement the search required by the specification\n\t * is to do a RegExp test() with lastIndex forced to zero.  To avoid\n\t * side effects on the argument, \"clone\" the RegExp if a RegExp was\n\t * given as input.\n\t *\n\t * The global flag of the RegExp should be ignored; setting lastIndex\n\t * to zero (which happens when \"cloning\" the RegExp) should have an\n\t * equivalent effect.\n\t */\n\n\tDUK_ASSERT_TOP(thr, 1);\n\t(void) duk_push_this_coercible_to_string(thr);  /* at index 1 */\n\tduk__to_regexp_helper(thr, 0 /*index*/, 1 /*force_new*/);\n\n\t/* stack[0] = regexp\n\t * stack[1] = string\n\t */\n\n\t/* Avoid using RegExp.prototype methods, as they're writable and\n\t * configurable and may have been changed.\n\t */\n\n\tduk_dup_0(thr);\n\tduk_dup_1(thr);  /* [ ... re_obj input ] */\n\tduk_regexp_match(thr);  /* -> [ ... res_obj ] */\n\n\tif (!duk_is_object(thr, -1)) {\n\t\tduk_push_int(thr, -1);\n\t\treturn 1;\n\t}\n\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX);\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\treturn 1;\n}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_match(duk_hthread *thr) {\n\tduk_bool_t global;\n\tduk_int_t prev_last_index;\n\tduk_int_t this_index;\n\tduk_int_t arr_idx;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk__to_regexp_helper(thr, 0 /*index*/, 0 /*force_new*/);\n\tglobal = duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL);\n\tDUK_ASSERT_TOP(thr, 2);\n\n\t/* stack[0] = regexp\n\t * stack[1] = string\n\t */\n\n\tif (!global) {\n\t\tduk_regexp_match(thr);  /* -> [ res_obj ] */\n\t\treturn 1;  /* return 'res_obj' */\n\t}\n\n\t/* Global case is more complex. */\n\n\t/* [ regexp string ] */\n\n\tduk_push_int(thr, 0);\n\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\tduk_push_array(thr);\n\n\t/* [ regexp string res_arr ] */\n\n\tprev_last_index = 0;\n\tarr_idx = 0;\n\n\tfor (;;) {\n\t\tDUK_ASSERT_TOP(thr, 3);\n\n\t\tduk_dup_0(thr);\n\t\tduk_dup_1(thr);\n\t\tduk_regexp_match(thr);  /* -> [ ... regexp string ] -> [ ... res_obj ] */\n\n\t\tif (!duk_is_object(thr, -1)) {\n\t\t\tduk_pop(thr);\n\t\t\tbreak;\n\t\t}\n\n\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\tthis_index = duk_get_int(thr, -1);\n\t\tduk_pop(thr);\n\n\t\tif (this_index == prev_last_index) {\n\t\t\tthis_index++;\n\t\t\tduk_push_int(thr, this_index);\n\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t}\n\t\tprev_last_index = this_index;\n\n\t\tduk_get_prop_index(thr, -1, 0);  /* match string */\n\t\tduk_put_prop_index(thr, 2, (duk_uarridx_t) arr_idx);\n\t\tarr_idx++;\n\t\tduk_pop(thr);  /* res_obj */\n\t}\n\n\tif (arr_idx == 0) {\n\t\tduk_push_null(thr);\n\t}\n\n\treturn 1;  /* return 'res_arr' or 'null' */\n}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_concat(duk_hthread *thr) {\n\t/* duk_concat() coerces arguments with ToString() in correct order */\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk_insert(thr, 0);  /* this is relatively expensive */\n\tduk_concat(thr, duk_get_top(thr));\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_trim(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 0);\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk_trim(thr, 0);\n\tDUK_ASSERT_TOP(thr, 1);\n\treturn 1;\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_hthread *thr) {\n\tduk_hstring *h_input;\n\tduk_size_t input_blen;\n\tduk_size_t result_len;\n\tduk_int_t count_signed;\n\tduk_uint_t count;\n\tconst duk_uint8_t *src;\n\tduk_uint8_t *buf;\n\tduk_uint8_t *p;\n\tduk_double_t d;\n#if !defined(DUK_USE_PREFER_SIZE)\n\tduk_size_t copy_size;\n\tduk_uint8_t *p_end;\n#endif\n\n\tDUK_ASSERT_TOP(thr, 1);\n\th_input = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_input != NULL);\n\tinput_blen = DUK_HSTRING_GET_BYTELEN(h_input);\n\n\t/* Count is ToNumber() coerced; +Infinity must be always rejected\n\t * (even if input string is zero length), as well as negative values\n\t * and -Infinity.  -Infinity doesn't require an explicit check\n\t * because duk_get_int() clamps it to DUK_INT_MIN which gets rejected\n\t * as a negative value (regardless of input string length).\n\t */\n\td = duk_to_number(thr, 0);\n\tif (duk_double_is_posinf(d)) {\n\t\tgoto fail_range;\n\t}\n\tcount_signed = duk_get_int(thr, 0);\n\tif (count_signed < 0) {\n\t\tgoto fail_range;\n\t}\n\tcount = (duk_uint_t) count_signed;\n\n\t/* Overflow check for result length. */\n\tresult_len = count * input_blen;\n\tif (count != 0 && result_len / count != input_blen) {\n\t\tgoto fail_range;\n\t}\n\n\t/* Temporary fixed buffer, later converted to string. */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, result_len);\n\tDUK_ASSERT(buf != NULL);\n\tsrc = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tDUK_ASSERT(src != NULL);\n\n#if defined(DUK_USE_PREFER_SIZE)\n\tp = buf;\n\twhile (count-- > 0) {\n\t\tduk_memcpy((void *) p, (const void *) src, input_blen);  /* copy size may be zero, but pointers are valid */\n\t\tp += input_blen;\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\t/* Take advantage of already copied pieces to speed up the process\n\t * especially for small repeated strings.\n\t */\n\tp = buf;\n\tp_end = p + result_len;\n\tcopy_size = input_blen;\n\tfor (;;) {\n\t\tduk_size_t remain = (duk_size_t) (p_end - p);\n\t\tDUK_DDD(DUK_DDDPRINT(\"remain=%ld, copy_size=%ld, input_blen=%ld, result_len=%ld\",\n\t\t                     (long) remain, (long) copy_size, (long) input_blen,\n\t\t                     (long) result_len));\n\t\tif (remain <= copy_size) {\n\t\t\t/* If result_len is zero, this case is taken and does\n\t\t\t * a zero size copy (with valid pointers).\n\t\t\t */\n\t\t\tduk_memcpy((void *) p, (const void *) src, remain);\n\t\t\tbreak;\n\t\t} else {\n\t\t\tduk_memcpy((void *) p, (const void *) src, copy_size);\n\t\t\tp += copy_size;\n\t\t}\n\n\t\tsrc = (const duk_uint8_t *) buf;  /* Use buf as source for larger copies. */\n\t\tcopy_size = (duk_size_t) (p - buf);\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n\t/* XXX: It would be useful to be able to create a duk_hstring with\n\t * a certain byte size whose data area wasn't initialized and which\n\t * wasn't in the string table yet.  This would allow a string to be\n\t * constructed directly without a buffer temporary and when it was\n\t * finished, it could be injected into the string table.  Currently\n\t * this isn't possible because duk_hstrings are only tracked by the\n\t * intern table (they are not in heap_allocated).\n\t */\n\n\tduk_buffer_to_string(thr, -1);  /* Safe if input is safe. */\n\treturn 1;\n\n fail_range:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_ES6 */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_locale_compare(duk_hthread *thr) {\n\tduk_hstring *h1;\n\tduk_hstring *h2;\n\tduk_size_t h1_len, h2_len, prefix_len;\n\tduk_small_int_t ret = 0;\n\tduk_small_int_t rc;\n\n\t/* The current implementation of localeCompare() is simply a codepoint\n\t * by codepoint comparison, implemented with a simple string compare\n\t * because UTF-8 should preserve codepoint ordering (assuming valid\n\t * shortest UTF-8 encoding).\n\t *\n\t * The specification requires that the return value must be related\n\t * to the sort order: e.g. negative means that 'this' comes before\n\t * 'that' in sort order.  We assume an ascending sort order.\n\t */\n\n\t/* XXX: could share code with duk_js_ops.c, duk_js_compare_helper */\n\n\th1 = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h1 != NULL);\n\n\th2 = duk_to_hstring(thr, 0);\n\tDUK_ASSERT(h2 != NULL);\n\n\th1_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1);\n\th2_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2);\n\tprefix_len = (h1_len <= h2_len ? h1_len : h2_len);\n\n\trc = (duk_small_int_t) duk_memcmp((const void *) DUK_HSTRING_GET_DATA(h1),\n\t                                  (const void *) DUK_HSTRING_GET_DATA(h2),\n\t                                  (size_t) prefix_len);\n\n\tif (rc < 0) {\n\t\tret = -1;\n\t\tgoto done;\n\t} else if (rc > 0) {\n\t\tret = 1;\n\t\tgoto done;\n\t}\n\n\t/* prefix matches, lengths matter now */\n\tif (h1_len > h2_len) {\n\t\tret = 1;\n\t\tgoto done;\n\t} else if (h1_len == h2_len) {\n\t\tDUK_ASSERT(ret == 0);\n\t\tgoto done;\n\t}\n\tret = -1;\n\tgoto done;\n\n done:\n\tduk_push_int(thr, (duk_int_t) ret);\n\treturn 1;\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_hthread *thr) {\n\tduk_int_t magic;\n\tduk_hstring *h;\n\tduk_hstring *h_search;\n\tduk_size_t blen_search;\n\tconst duk_uint8_t *p_cmp_start;\n\tduk_bool_t result;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\th_search = duk__str_tostring_notregexp(thr, 0);\n\tDUK_ASSERT(h_search != NULL);\n\n\tmagic = duk_get_current_magic(thr);\n\n\tp_cmp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tblen_search = DUK_HSTRING_GET_BYTELEN(h_search);\n\n\tif (duk_is_undefined(thr, 1)) {\n\t\tif (magic) {\n\t\t\tp_cmp_start = p_cmp_start + DUK_HSTRING_GET_BYTELEN(h) - blen_search;\n\t\t} else {\n\t\t\t/* p_cmp_start already OK */\n\t\t}\n\t} else {\n\t\tduk_int_t len;\n\t\tduk_int_t pos;\n\n\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= DUK_INT_MAX);\n\t\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\t\tpos = duk_to_int_clamped(thr, 1, 0, len);\n\t\tDUK_ASSERT(pos >= 0 && pos <= len);\n\n\t\tif (magic) {\n\t\t\tp_cmp_start -= blen_search;  /* Conceptually subtracted last, but do already here. */\n\t\t}\n\t\tDUK_ASSERT(pos >= 0 && pos <= len);\n\n\t\tp_cmp_start += duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) pos);\n\t}\n\n\t/* The main comparison can be done using a memcmp() rather than\n\t * doing codepoint comparisons: for CESU-8 strings there is a\n\t * canonical representation for every codepoint.  But we do need\n\t * to deal with the char/byte offset translation to find the\n\t * comparison range.\n\t */\n\n\tresult = 0;\n\tif (p_cmp_start >= DUK_HSTRING_GET_DATA(h) &&\n\t    (duk_size_t) (p_cmp_start - (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h)) + blen_search <= DUK_HSTRING_GET_BYTELEN(h)) {\n\t\tif (duk_memcmp((const void *) p_cmp_start,\n\t\t               (const void *) DUK_HSTRING_GET_DATA(h_search),\n\t\t               (size_t) blen_search) == 0) {\n\t\t\tresult = 1;\n\t\t}\n\t}\n\n\tduk_push_boolean(thr, result);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_includes(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_hstring *h_search;\n\tduk_int_t len;\n\tduk_int_t pos;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\th_search = duk__str_tostring_notregexp(thr, 0);\n\tDUK_ASSERT(h_search != NULL);\n\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\tpos = duk_to_int_clamped(thr, 1, 0, len);\n\tDUK_ASSERT(pos >= 0 && pos <= len);\n\n\tpos = duk__str_search_shared(thr, h, h_search, pos, 0 /*backwards*/);\n\tduk_push_boolean(thr, pos >= 0);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n#endif  /* DUK_USE_STRING_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_symbol.c",
    "content": "/*\n *  Symbol built-in\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_constructor_shared(duk_hthread *thr) {\n\tconst duk_uint8_t *desc;\n\tduk_size_t len;\n\tduk_uint8_t *buf;\n\tduk_uint8_t *p;\n\tduk_int_t magic;\n\n\tmagic = duk_get_current_magic(thr);\n\tif (duk_is_undefined(thr, 0) && (magic == 0)) {\n\t\t/* Symbol() accepts undefined and empty string, but they are\n\t\t * treated differently.\n\t\t */\n\t\tdesc = NULL;\n\t\tlen = 0;\n\t} else {\n\t\t/* Symbol.for() coerces undefined to 'undefined' */\n\t\tdesc = (const duk_uint8_t *) duk_to_lstring(thr, 0, &len);\n\t}\n\n\t/* Maximum symbol data length:\n\t *   +1    initial byte (0x80 or 0x81)\n\t *   +len  description\n\t *   +1    0xff after description, before unique suffix\n\t *   +17   autogenerated unique suffix: 'ffffffff-ffffffff' is longest\n\t *   +1    0xff after unique suffix for symbols with undefined description\n\t */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer(thr, 1 + len + 1 + 17 + 1);\n\tDUK_ASSERT(buf != NULL);\n\tp = buf + 1;\n\tDUK_ASSERT(desc != NULL || len == 0);  /* may be NULL if len is 0 */\n\tduk_memcpy_unsafe((void *) p, (const void *) desc, len);\n\tp += len;\n\tif (magic == 0) {\n\t\t/* Symbol(): create unique symbol.  Use two 32-bit values\n\t\t * to avoid dependency on 64-bit types and 64-bit integer\n\t\t * formatting (at least for now).\n\t\t */\n\t\tif (++thr->heap->sym_counter[0] == 0) {\n\t\t\tthr->heap->sym_counter[1]++;\n\t\t}\n\t\tp += DUK_SPRINTF((char *) p, \"\\xFF\" \"%lx-%lx\",\n\t\t                 (unsigned long) thr->heap->sym_counter[1],\n\t\t                 (unsigned long) thr->heap->sym_counter[0]);\n\t\tif (desc == NULL) {\n\t\t\t/* Special case for 'undefined' description, trailing\n\t\t\t * 0xff distinguishes from empty string description,\n\t\t\t * but needs minimal special case handling elsewhere.\n\t\t\t */\n\t\t\t*p++ = 0xff;\n\t\t}\n\t\tbuf[0] = 0x81;\n\t} else {\n\t\t/* Symbol.for(): create a global symbol */\n\t\tbuf[0] = 0x80;\n\t}\n\n\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) (p - buf));\n\tDUK_DDD(DUK_DDDPRINT(\"created symbol: %!T\", duk_get_tval(thr, -1)));\n\treturn 1;\n}\n\nDUK_LOCAL duk_hstring *duk__auto_unbox_symbol(duk_hthread *thr, duk_tval *tv_arg) {\n\tduk_tval *tv;\n\tduk_hobject *h_obj;\n\tduk_hstring *h_str;\n\n\tDUK_ASSERT(tv_arg != NULL);\n\n\t/* XXX: add internal helper: duk_auto_unbox_tval(thr, tv, mask); */\n\t/* XXX: add internal helper: duk_auto_unbox(thr, tv, idx); */\n\n\ttv = tv_arg;\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_obj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_SYMBOL) {\n\t\t\ttv = duk_hobject_get_internal_value_tval_ptr(thr->heap, h_obj);\n\t\t\tif (tv == NULL) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t} else {\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\tif (!DUK_TVAL_IS_STRING(tv)) {\n\t\treturn NULL;\n\t}\n\th_str = DUK_TVAL_GET_STRING(tv);\n\tDUK_ASSERT(h_str != NULL);\n\n\t/* Here symbol is more expected than not. */\n\tif (DUK_UNLIKELY(!DUK_HSTRING_HAS_SYMBOL(h_str))) {\n\t\treturn NULL;\n\t}\n\n\treturn h_str;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_tostring_shared(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\th_str = duk__auto_unbox_symbol(thr, DUK_HTHREAD_THIS_PTR(thr));\n\tif (h_str == NULL) {\n\t\treturn DUK_RET_TYPE_ERROR;\n\t}\n\n\tif (duk_get_current_magic(thr) == 0) {\n\t\t/* .toString() */\n\t\tduk_push_symbol_descriptive_string(thr, h_str);\n\t} else {\n\t\t/* .valueOf() */\n\t\tduk_push_hstring(thr, h_str);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_key_for(duk_hthread *thr) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p;\n\n\t/* Argument must be a symbol but not checked here.  The initial byte\n\t * check will catch non-symbol strings.\n\t */\n\th = duk_require_hstring(thr, 0);\n\tDUK_ASSERT(h != NULL);\n\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tDUK_ASSERT(p != NULL);\n\n\t/* Even for zero length strings there's at least one NUL byte so\n\t * we can safely check the initial byte.\n\t */\n\tif (p[0] == 0x80) {\n\t\t/* Global symbol, return its key (bytes just after the initial byte). */\n\t\tduk_push_lstring(thr, (const char *) (p + 1), (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h) - 1));\n\t\treturn 1;\n\t} else if (p[0] == 0x81 || p[0] == 0x82 || p[0] == 0xff) {\n\t\t/* Local symbol or hidden symbol, return undefined. */\n\t\treturn 0;\n\t}\n\n\t/* Covers normal strings and unknown initial bytes. */\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_toprimitive(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\th_str = duk__auto_unbox_symbol(thr, DUK_HTHREAD_THIS_PTR(thr));\n\tif (h_str == NULL) {\n\t\treturn DUK_RET_TYPE_ERROR;\n\t}\n\tduk_push_hstring(thr, h_str);\n\treturn 1;\n}\n\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_thread.c",
    "content": "/*\n *  Thread builtins\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Constructor\n */\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_constructor(duk_hthread *thr) {\n\tduk_hthread *new_thr;\n\tduk_hobject *func;\n\n\t/* Check that the argument is callable; this is not 100% because we\n\t * don't allow native functions to be a thread's initial function.\n\t * Resume will reject such functions in any case.\n\t */\n\t/* XXX: need a duk_require_func_promote_lfunc() */\n\tfunc = duk_require_hobject_promote_lfunc(thr, 0);\n\tDUK_ASSERT(func != NULL);\n\tduk_require_callable(thr, 0);\n\n\tduk_push_thread(thr);\n\tnew_thr = (duk_hthread *) duk_known_hobject(thr, -1);\n\tnew_thr->state = DUK_HTHREAD_STATE_INACTIVE;\n\n\t/* push initial function call to new thread stack; this is\n\t * picked up by resume().\n\t */\n\tduk_push_hobject(new_thr, func);\n\n\treturn 1;  /* return thread */\n}\n#endif\n\n/*\n *  Resume a thread.\n *\n *  The thread must be in resumable state, either (a) new thread which hasn't\n *  yet started, or (b) a thread which has previously yielded.  This method\n *  must be called from an ECMAScript function.\n *\n *  Args:\n *    - thread\n *    - value\n *    - isError (defaults to false)\n *\n *  Note: yield and resume handling is currently asymmetric.\n */\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) {\n\tduk_hthread *thr = (duk_hthread *) ctx;\n\tduk_hthread *thr_resume;\n\tduk_hobject *caller_func;\n\tduk_small_uint_t is_error;\n\n\tDUK_DDD(DUK_DDDPRINT(\"Duktape.Thread.resume(): thread=%!T, value=%!T, is_error=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1),\n\t                     (duk_tval *) duk_get_tval(thr, 2)));\n\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\tDUK_ASSERT(thr->heap->curr_thread == thr);\n\n\tthr_resume = duk_require_hthread(thr, 0);\n\tDUK_ASSERT(duk_get_top(thr) == 3);\n\tis_error = (duk_small_uint_t) duk_to_boolean_top_pop(thr);\n\tDUK_ASSERT(duk_get_top(thr) == 2);\n\n\t/* [ thread value ] */\n\n\t/*\n\t *  Thread state and calling context checks\n\t */\n\n\tif (thr->callstack_top < 2) {\n\t\tDUK_DD(DUK_DDPRINT(\"resume state invalid: callstack should contain at least 2 entries (caller and Duktape.Thread.resume)\"));\n\t\tgoto state_error;\n\t}\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);  /* us */\n\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL);  /* caller */\n\n\tcaller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent);\n\tif (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) {\n\t\tDUK_DD(DUK_DDPRINT(\"resume state invalid: caller must be ECMAScript code\"));\n\t\tgoto state_error;\n\t}\n\n\t/* Note: there is no requirement that: 'thr->callstack_preventcount == 1'\n\t * like for yield.\n\t */\n\n\tif (thr_resume->state != DUK_HTHREAD_STATE_INACTIVE &&\n\t    thr_resume->state != DUK_HTHREAD_STATE_YIELDED) {\n\t\tDUK_DD(DUK_DDPRINT(\"resume state invalid: target thread must be INACTIVE or YIELDED\"));\n\t\tgoto state_error;\n\t}\n\n\tDUK_ASSERT(thr_resume->state == DUK_HTHREAD_STATE_INACTIVE ||\n\t           thr_resume->state == DUK_HTHREAD_STATE_YIELDED);\n\n\t/* Further state-dependent pre-checks */\n\n\tif (thr_resume->state == DUK_HTHREAD_STATE_YIELDED) {\n\t\t/* no pre-checks now, assume a previous yield() has left things in\n\t\t * tip-top shape (longjmp handler will assert for these).\n\t\t */\n\t} else {\n\t\tduk_hobject *h_fun;\n\n\t\tDUK_ASSERT(thr_resume->state == DUK_HTHREAD_STATE_INACTIVE);\n\n\t\t/* The initial function must be an ECMAScript function (but\n\t\t * can be bound).  We must make sure of that before we longjmp\n\t\t * because an error in the RESUME handler call processing will\n\t\t * not be handled very cleanly.\n\t\t */\n\t\tif ((thr_resume->callstack_top != 0) ||\n\t\t    (thr_resume->valstack_top - thr_resume->valstack != 1)) {\n\t\t\tgoto state_error;\n\t\t}\n\n\t\tduk_push_tval(thr, DUK_GET_TVAL_NEGIDX(thr_resume, -1));\n\t\tduk_resolve_nonbound_function(thr);\n\t\th_fun = duk_require_hobject(thr, -1);  /* reject lightfuncs on purpose */\n\t\tif (!DUK_HOBJECT_IS_CALLABLE(h_fun) || !DUK_HOBJECT_IS_COMPFUNC(h_fun)) {\n\t\t\tgoto state_error;\n\t\t}\n\t\tduk_pop(thr);\n\t}\n\n#if 0\n\t/* This check would prevent a heap destruction time finalizer from\n\t * launching a coroutine, which would ensure that during finalization\n\t * 'thr' would always equal heap_thread.  Normal runtime finalizers\n\t * run with ms_running == 0, i.e. outside mark-and-sweep.  See GH-2030.\n\t */\n\tif (thr->heap->ms_running) {\n\t\tDUK_D(DUK_DPRINT(\"refuse Duktape.Thread.resume() when ms_running != 0\"));\n\t\tgoto state_error;\n\t}\n#endif\n\n\t/*\n\t *  The error object has been augmented with a traceback and other\n\t *  info from its creation point -- usually another thread.  The\n\t *  error handler is called here right before throwing, but it also\n\t *  runs in the resumer's thread.  It might be nice to get a traceback\n\t *  from the resumee but this is not the case now.\n\t */\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\tif (is_error) {\n\t\tDUK_ASSERT_TOP(thr, 2);  /* value (error) is at stack top */\n\t\tduk_err_augment_error_throw(thr);  /* in resumer's context */\n\t}\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\tif (is_error) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"RESUME ERROR: thread=%!T, value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\t} else if (thr_resume->state == DUK_HTHREAD_STATE_YIELDED) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"RESUME NORMAL: thread=%!T, value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"RESUME INITIAL: thread=%!T, value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\t}\n#endif\n\n\tthr->heap->lj.type = DUK_LJ_TYPE_RESUME;\n\n\t/* lj value2: thread */\n\tDUK_ASSERT(thr->valstack_bottom < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value2, &thr->valstack_bottom[0]);  /* side effects */\n\n\t/* lj value1: value */\n\tDUK_ASSERT(thr->valstack_bottom + 1 < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, &thr->valstack_bottom[1]);  /* side effects */\n\tDUK_TVAL_CHKFAST_INPLACE_SLOW(&thr->heap->lj.value1);\n\n\tthr->heap->lj.iserror = is_error;\n\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* call is from executor, so we know we have a jmpbuf */\n\tduk_err_longjmp(thr);  /* execution resumes in bytecode executor */\n\tDUK_UNREACHABLE();\n\t/* Never here, fall through to error (from compiler point of view). */\n\n state_error:\n\tDUK_DCERROR_TYPE_INVALID_STATE(thr);\n}\n#endif\n\n/*\n *  Yield the current thread.\n *\n *  The thread must be in yieldable state: it must have a resumer, and there\n *  must not be any yield-preventing calls (native calls and constructor calls,\n *  currently) in the thread's call stack (otherwise a resume would not be\n *  possible later).  This method must be called from an ECMAScript function.\n *\n *  Args:\n *    - value\n *    - isError (defaults to false)\n *\n *  Note: yield and resume handling is currently asymmetric.\n */\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_hthread *thr) {\n\tduk_hobject *caller_func;\n\tduk_small_uint_t is_error;\n\n\tDUK_DDD(DUK_DDDPRINT(\"Duktape.Thread.yield(): value=%!T, is_error=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\tDUK_ASSERT(thr->heap->curr_thread == thr);\n\n\tDUK_ASSERT(duk_get_top(thr) == 2);\n\tis_error = (duk_small_uint_t) duk_to_boolean_top_pop(thr);\n\tDUK_ASSERT(duk_get_top(thr) == 1);\n\n\t/* [ value ] */\n\n\t/*\n\t *  Thread state and calling context checks\n\t */\n\n\tif (!thr->resumer) {\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: current thread must have a resumer\"));\n\t\tgoto state_error;\n\t}\n\tDUK_ASSERT(thr->resumer->state == DUK_HTHREAD_STATE_RESUMED);\n\n\tif (thr->callstack_top < 2) {\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: callstack should contain at least 2 entries (caller and Duktape.Thread.yield)\"));\n\t\tgoto state_error;\n\t}\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);  /* us */\n\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL);  /* caller */\n\n\tcaller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent);\n\tif (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) {\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: caller must be ECMAScript code\"));\n\t\tgoto state_error;\n\t}\n\n\tDUK_ASSERT(thr->callstack_preventcount >= 1);  /* should never be zero, because we (Duktape.Thread.yield) are on the stack */\n\tif (thr->callstack_preventcount != 1) {\n\t\t/* Note: the only yield-preventing call is Duktape.Thread.yield(), hence check for 1, not 0 */\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: there must be no yield-preventing calls in current thread callstack (preventcount is %ld)\",\n\t\t                   (long) thr->callstack_preventcount));\n\t\tgoto state_error;\n\t}\n\n\t/*\n\t *  The error object has been augmented with a traceback and other\n\t *  info from its creation point -- usually the current thread.\n\t *  The error handler, however, is called right before throwing\n\t *  and runs in the yielder's thread.\n\t */\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\tif (is_error) {\n\t\tDUK_ASSERT_TOP(thr, 1);  /* value (error) is at stack top */\n\t\tduk_err_augment_error_throw(thr);  /* in yielder's context */\n\t}\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\tif (is_error) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"YIELD ERROR: value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0)));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"YIELD NORMAL: value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0)));\n\t}\n#endif\n\n\t/*\n\t *  Process yield\n\t *\n\t *  After longjmp(), processing continues in bytecode executor longjmp\n\t *  handler, which will e.g. update thr->resumer to NULL.\n\t */\n\n\tthr->heap->lj.type = DUK_LJ_TYPE_YIELD;\n\n\t/* lj value1: value */\n\tDUK_ASSERT(thr->valstack_bottom < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, &thr->valstack_bottom[0]);  /* side effects */\n\tDUK_TVAL_CHKFAST_INPLACE_SLOW(&thr->heap->lj.value1);\n\n\tthr->heap->lj.iserror = is_error;\n\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* call is from executor, so we know we have a jmpbuf */\n\tduk_err_longjmp(thr);  /* execution resumes in bytecode executor */\n\tDUK_UNREACHABLE();\n\t/* Never here, fall through to error (from compiler point of view). */\n\n state_error:\n\tDUK_DCERROR_TYPE_INVALID_STATE(thr);\n}\n#endif\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_current(duk_hthread *thr) {\n\tduk_push_current_thread(thr);\n\treturn 1;\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_bi_thrower.c",
    "content": "/*\n *  Type error thrower, E5 Section 13.2.3.\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL duk_ret_t duk_bi_type_error_thrower(duk_hthread *thr) {\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_dblunion.h",
    "content": "/*\n *  Union to access IEEE double memory representation, indexes for double\n *  memory representation, and some macros for double manipulation.\n *\n *  Also used by packed duk_tval.  Use a union for bit manipulation to\n *  minimize aliasing issues in practice.  The C99 standard does not\n *  guarantee that this should work, but it's a very widely supported\n *  practice for low level manipulation.\n *\n *  IEEE double format summary:\n *\n *    seeeeeee eeeeffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n *       A        B        C        D        E        F        G        H\n *\n *    s       sign bit\n *    eee...  exponent field\n *    fff...  fraction\n *\n *  See http://en.wikipedia.org/wiki/Double_precision_floating-point_format.\n *\n *  NaNs are represented as exponent 0x7ff and mantissa != 0.  The NaN is a\n *  signaling NaN when the highest bit of the mantissa is zero, and a quiet\n *  NaN when the highest bit is set.\n *\n *  At least three memory layouts are relevant here:\n *\n *    A B C D E F G H    Big endian (e.g. 68k)           DUK_USE_DOUBLE_BE\n *    H G F E D C B A    Little endian (e.g. x86)        DUK_USE_DOUBLE_LE\n *    D C B A H G F E    Mixed/cross endian (e.g. ARM)   DUK_USE_DOUBLE_ME\n *\n *  ARM is a special case: ARM double values are in mixed/cross endian\n *  format while ARM duk_uint64_t values are in standard little endian\n *  format (H G F E D C B A).  When a double is read as a duk_uint64_t\n *  from memory, the register will contain the (logical) value\n *  E F G H A B C D.  This requires some special handling below.\n *\n *  Indexes of various types (8-bit, 16-bit, 32-bit) in memory relative to\n *  the logical (big endian) order:\n *\n *  byte order      duk_uint8_t    duk_uint16_t     duk_uint32_t\n *    BE             01234567         0123               01\n *    LE             76543210         3210               10\n *    ME (ARM)       32107654         1032               01\n *\n *  Some processors may alter NaN values in a floating point load+store.\n *  For instance, on X86 a FLD + FSTP may convert a signaling NaN to a\n *  quiet one.  This is catastrophic when NaN space is used in packed\n *  duk_tval values.  See: misc/clang_aliasing.c.\n */\n\n#if !defined(DUK_DBLUNION_H_INCLUDED)\n#define DUK_DBLUNION_H_INCLUDED\n\n/*\n *  Union for accessing double parts, also serves as packed duk_tval\n */\n\nunion duk_double_union {\n\tdouble d;\n\tfloat f[2];\n#if defined(DUK_USE_64BIT_OPS)\n\tduk_uint64_t ull[1];\n#endif\n\tduk_uint32_t ui[2];\n\tduk_uint16_t us[4];\n\tduk_uint8_t uc[8];\n#if defined(DUK_USE_PACKED_TVAL)\n\tvoid *vp[2];  /* used by packed duk_tval, assumes sizeof(void *) == 4 */\n#endif\n};\n\ntypedef union duk_double_union duk_double_union;\n\n/*\n *  Indexes of various types with respect to big endian (logical) layout\n */\n\n#if defined(DUK_USE_DOUBLE_LE)\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBL_IDX_ULL0   0\n#endif\n#define DUK_DBL_IDX_UI0    1\n#define DUK_DBL_IDX_UI1    0\n#define DUK_DBL_IDX_US0    3\n#define DUK_DBL_IDX_US1    2\n#define DUK_DBL_IDX_US2    1\n#define DUK_DBL_IDX_US3    0\n#define DUK_DBL_IDX_UC0    7\n#define DUK_DBL_IDX_UC1    6\n#define DUK_DBL_IDX_UC2    5\n#define DUK_DBL_IDX_UC3    4\n#define DUK_DBL_IDX_UC4    3\n#define DUK_DBL_IDX_UC5    2\n#define DUK_DBL_IDX_UC6    1\n#define DUK_DBL_IDX_UC7    0\n#define DUK_DBL_IDX_VP0    DUK_DBL_IDX_UI0  /* packed tval */\n#define DUK_DBL_IDX_VP1    DUK_DBL_IDX_UI1  /* packed tval */\n#elif defined(DUK_USE_DOUBLE_BE)\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBL_IDX_ULL0   0\n#endif\n#define DUK_DBL_IDX_UI0    0\n#define DUK_DBL_IDX_UI1    1\n#define DUK_DBL_IDX_US0    0\n#define DUK_DBL_IDX_US1    1\n#define DUK_DBL_IDX_US2    2\n#define DUK_DBL_IDX_US3    3\n#define DUK_DBL_IDX_UC0    0\n#define DUK_DBL_IDX_UC1    1\n#define DUK_DBL_IDX_UC2    2\n#define DUK_DBL_IDX_UC3    3\n#define DUK_DBL_IDX_UC4    4\n#define DUK_DBL_IDX_UC5    5\n#define DUK_DBL_IDX_UC6    6\n#define DUK_DBL_IDX_UC7    7\n#define DUK_DBL_IDX_VP0    DUK_DBL_IDX_UI0  /* packed tval */\n#define DUK_DBL_IDX_VP1    DUK_DBL_IDX_UI1  /* packed tval */\n#elif defined(DUK_USE_DOUBLE_ME)\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBL_IDX_ULL0   0  /* not directly applicable, byte order differs from a double */\n#endif\n#define DUK_DBL_IDX_UI0    0\n#define DUK_DBL_IDX_UI1    1\n#define DUK_DBL_IDX_US0    1\n#define DUK_DBL_IDX_US1    0\n#define DUK_DBL_IDX_US2    3\n#define DUK_DBL_IDX_US3    2\n#define DUK_DBL_IDX_UC0    3\n#define DUK_DBL_IDX_UC1    2\n#define DUK_DBL_IDX_UC2    1\n#define DUK_DBL_IDX_UC3    0\n#define DUK_DBL_IDX_UC4    7\n#define DUK_DBL_IDX_UC5    6\n#define DUK_DBL_IDX_UC6    5\n#define DUK_DBL_IDX_UC7    4\n#define DUK_DBL_IDX_VP0    DUK_DBL_IDX_UI0  /* packed tval */\n#define DUK_DBL_IDX_VP1    DUK_DBL_IDX_UI1  /* packed tval */\n#else\n#error internal error\n#endif\n\n/*\n *  Helper macros for reading/writing memory representation parts, used\n *  by duk_numconv.c and duk_tval.h.\n */\n\n#define DUK_DBLUNION_SET_DOUBLE(u,v)  do {  \\\n\t\t(u)->d = (v); \\\n\t} while (0)\n\n#define DUK_DBLUNION_SET_HIGH32(u,v)  do {  \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) (v); \\\n\t} while (0)\n\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = (duk_uint64_t) (v); \\\n\t} while (0)\n#else\n#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = ((duk_uint64_t) (v)) << 32; \\\n\t} while (0)\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v)  do { \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) (v); \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0; \\\n\t} while (0)\n#endif  /* DUK_USE_64BIT_OPS */\n\n#define DUK_DBLUNION_SET_LOW32(u,v)  do {  \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (v); \\\n\t} while (0)\n\n#define DUK_DBLUNION_GET_DOUBLE(u)  ((u)->d)\n#define DUK_DBLUNION_GET_HIGH32(u)  ((u)->ui[DUK_DBL_IDX_UI0])\n#define DUK_DBLUNION_GET_LOW32(u)   ((u)->ui[DUK_DBL_IDX_UI1])\n\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK_DBLUNION_SET_UINT64(u,v)  do { \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) ((v) >> 32); \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (v); \\\n\t} while (0)\n#define DUK_DBLUNION_GET_UINT64(u) \\\n\t((((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI0]) << 32) | \\\n\t ((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI1]))\n#else\n#define DUK_DBLUNION_SET_UINT64(u,v)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = (duk_uint64_t) (v); \\\n\t} while (0)\n#define DUK_DBLUNION_GET_UINT64(u)  ((u)->ull[DUK_DBL_IDX_ULL0])\n#endif\n#define DUK_DBLUNION_SET_INT64(u,v) DUK_DBLUNION_SET_UINT64((u), (duk_uint64_t) (v))\n#define DUK_DBLUNION_GET_INT64(u)   ((duk_int64_t) DUK_DBLUNION_GET_UINT64((u)))\n#endif  /* DUK_USE_64BIT_OPS */\n\n/*\n *  Double NaN manipulation macros related to NaN normalization needed when\n *  using the packed duk_tval representation.  NaN normalization is necessary\n *  to keep double values compatible with the duk_tval format.\n *\n *  When packed duk_tval is used, the NaN space is used to store pointers\n *  and other tagged values in addition to NaNs.  Actual NaNs are normalized\n *  to a specific quiet NaN.  The macros below are used by the implementation\n *  to check and normalize NaN values when they might be created.  The macros\n *  are essentially NOPs when the non-packed duk_tval representation is used.\n *\n *  A FULL check is exact and checks all bits.  A NOTFULL check is used by\n *  the packed duk_tval and works correctly for all NaNs except those that\n *  begin with 0x7ff0.  Since the 'normalized NaN' values used with packed\n *  duk_tval begin with 0x7ff8, the partial check is reliable when packed\n *  duk_tval is used.  The 0x7ff8 prefix means the normalized NaN will be a\n *  quiet NaN regardless of its remaining lower bits.\n *\n *  The ME variant below is specifically for ARM byte order, which has the\n *  feature that while doubles have a mixed byte order (32107654), unsigned\n *  long long values has a little endian byte order (76543210).  When writing\n *  a logical double value through a ULL pointer, the 32-bit words need to be\n *  swapped; hence the #if defined()s below for ULL writes with DUK_USE_DOUBLE_ME.\n *  This is not full ARM support but suffices for some environments.\n */\n\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n/* Macros for 64-bit ops + mixed endian doubles. */\n#define DUK__DBLUNION_SET_NAN_FULL(u)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x000000007ff80000); \\\n\t} while (0)\n#define DUK__DBLUNION_IS_NAN_FULL(u) \\\n\t((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000)) && \\\n\t ((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0xffffffff000fffff)) != 0))\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff80000))\n#define DUK__DBLUNION_IS_ANYINF(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x000000007ff00000))\n#define DUK__DBLUNION_IS_POSINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff00000))\n#define DUK__DBLUNION_IS_NEGINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x00000000fff00000))\n#define DUK__DBLUNION_IS_ANYZERO(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_POSZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_NEGZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000080000000))\n#else\n/* Macros for 64-bit ops + big/little endian doubles. */\n#define DUK__DBLUNION_SET_NAN_FULL(u)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x7ff8000000000000); \\\n\t} while (0)\n#define DUK__DBLUNION_IS_NAN_FULL(u) \\\n\t((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000)) && \\\n\t ((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0x000fffffffffffff)) != 0))\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff8000000000000))\n#define DUK__DBLUNION_IS_ANYINF(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x7ff0000000000000))\n#define DUK__DBLUNION_IS_POSINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff0000000000000))\n#define DUK__DBLUNION_IS_NEGINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0xfff0000000000000))\n#define DUK__DBLUNION_IS_ANYZERO(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_POSZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_NEGZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x8000000000000000))\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n/* Macros for no 64-bit ops, any endianness. */\n#define DUK__DBLUNION_SET_NAN_FULL(u)  do { \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) 0x7ff80000UL; \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0x00000000UL; \\\n\t} while (0)\n#define DUK__DBLUNION_IS_NAN_FULL(u) \\\n\t((((u)->ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL) && \\\n\t (((u)->ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) != 0 || \\\n          (u)->ui[DUK_DBL_IDX_UI1] != 0))\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff80000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_ANYINF(u) \\\n\t((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x7ff00000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_POSINF(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff00000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_NEGINF(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0xfff00000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_ANYZERO(u) \\\n\t((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x00000000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_POSZERO(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x00000000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_NEGZERO(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x80000000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#endif  /* DUK_USE_64BIT_OPS */\n\n#define DUK__DBLUNION_SET_NAN_NOTFULL(u)  do { \\\n\t\t(u)->us[DUK_DBL_IDX_US0] = 0x7ff8UL; \\\n\t} while (0)\n\n#define DUK__DBLUNION_IS_NAN_NOTFULL(u) \\\n\t/* E == 0x7ff, topmost four bits of F != 0 => assume NaN */ \\\n\t((((u)->us[DUK_DBL_IDX_US0] & 0x7ff0UL) == 0x7ff0UL) && \\\n\t (((u)->us[DUK_DBL_IDX_US0] & 0x000fUL) != 0x0000UL))\n\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL(u) \\\n\t/* E == 0x7ff, F == 8 => normalized NaN */ \\\n\t((u)->us[DUK_DBL_IDX_US0] == 0x7ff8UL)\n\n#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL(u)  do { \\\n\t\tif (DUK__DBLUNION_IS_NAN_FULL((u))) { \\\n\t\t\tDUK__DBLUNION_SET_NAN_FULL((u)); \\\n\t\t} \\\n\t} while (0)\n\n#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL(u)  do { \\\n\t\tif (DUK__DBLUNION_IS_NAN_NOTFULL((u))) { \\\n\t\t\tDUK__DBLUNION_SET_NAN_NOTFULL((u)); \\\n\t\t} \\\n\t} while (0)\n\n/* Concrete macros for NaN handling used by the implementation internals.\n * Chosen so that they match the duk_tval representation: with a packed\n * duk_tval, ensure NaNs are properly normalized; with a non-packed duk_tval\n * these are essentially NOPs.\n */\n\n#if defined(DUK_USE_PACKED_TVAL)\n#if defined(DUK_USE_FULL_TVAL)\n#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u)  DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL((u))\n#define DUK_DBLUNION_IS_NAN(u)               DUK__DBLUNION_IS_NAN_FULL((u))\n#define DUK_DBLUNION_IS_NORMALIZED_NAN(u)    DUK__DBLUNION_IS_NORMALIZED_NAN_FULL((u))\n#define DUK_DBLUNION_SET_NAN(d)              DUK__DBLUNION_SET_NAN_FULL((d))\n#else\n#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u)  DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL((u))\n#define DUK_DBLUNION_IS_NAN(u)               DUK__DBLUNION_IS_NAN_NOTFULL((u))\n#define DUK_DBLUNION_IS_NORMALIZED_NAN(u)    DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL((u))\n#define DUK_DBLUNION_SET_NAN(d)              DUK__DBLUNION_SET_NAN_NOTFULL((d))\n#endif\n#define DUK_DBLUNION_IS_NORMALIZED(u) \\\n\t(!DUK_DBLUNION_IS_NAN((u)) ||  /* either not a NaN */ \\\n\t DUK_DBLUNION_IS_NORMALIZED_NAN((u)))  /* or is a normalized NaN */\n#else  /* DUK_USE_PACKED_TVAL */\n#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u)  /* nop: no need to normalize */\n#define DUK_DBLUNION_IS_NAN(u)               DUK__DBLUNION_IS_NAN_FULL((u))  /* (DUK_ISNAN((u)->d)) */\n#define DUK_DBLUNION_IS_NORMALIZED_NAN(u)    DUK__DBLUNION_IS_NAN_FULL((u))  /* (DUK_ISNAN((u)->d)) */\n#define DUK_DBLUNION_IS_NORMALIZED(u)        1  /* all doubles are considered normalized */\n#define DUK_DBLUNION_SET_NAN(u)  do { \\\n\t\t/* in non-packed representation we don't care about which NaN is used */ \\\n\t\t(u)->d = DUK_DOUBLE_NAN; \\\n\t} while (0)\n#endif  /* DUK_USE_PACKED_TVAL */\n\n#define DUK_DBLUNION_IS_ANYINF(u) DUK__DBLUNION_IS_ANYINF((u))\n#define DUK_DBLUNION_IS_POSINF(u) DUK__DBLUNION_IS_POSINF((u))\n#define DUK_DBLUNION_IS_NEGINF(u) DUK__DBLUNION_IS_NEGINF((u))\n\n#define DUK_DBLUNION_IS_ANYZERO(u) DUK__DBLUNION_IS_ANYZERO((u))\n#define DUK_DBLUNION_IS_POSZERO(u) DUK__DBLUNION_IS_POSZERO((u))\n#define DUK_DBLUNION_IS_NEGZERO(u) DUK__DBLUNION_IS_NEGZERO((u))\n\n/* XXX: native 64-bit byteswaps when available */\n\n/* 64-bit byteswap, same operation independent of target endianness. */\n#define DUK_DBLUNION_BSWAP64(u) do { \\\n\t\tduk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \\\n\t\tduk__bswaptmp1 = (u)->ui[0]; \\\n\t\tduk__bswaptmp2 = (u)->ui[1]; \\\n\t\tduk__bswaptmp1 = DUK_BSWAP32(duk__bswaptmp1); \\\n\t\tduk__bswaptmp2 = DUK_BSWAP32(duk__bswaptmp2); \\\n\t\t(u)->ui[0] = duk__bswaptmp2; \\\n\t\t(u)->ui[1] = duk__bswaptmp1; \\\n\t} while (0)\n\n/* Byteswap an IEEE double in the duk_double_union from host to network\n * order.  For a big endian target this is a no-op.\n */\n#if defined(DUK_USE_DOUBLE_LE)\n#define DUK_DBLUNION_DOUBLE_HTON(u) do { \\\n\t\tduk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \\\n\t\tduk__bswaptmp1 = (u)->ui[0]; \\\n\t\tduk__bswaptmp2 = (u)->ui[1]; \\\n\t\tduk__bswaptmp1 = DUK_BSWAP32(duk__bswaptmp1); \\\n\t\tduk__bswaptmp2 = DUK_BSWAP32(duk__bswaptmp2); \\\n\t\t(u)->ui[0] = duk__bswaptmp2; \\\n\t\t(u)->ui[1] = duk__bswaptmp1; \\\n\t} while (0)\n#elif defined(DUK_USE_DOUBLE_ME)\n#define DUK_DBLUNION_DOUBLE_HTON(u) do { \\\n\t\tduk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \\\n\t\tduk__bswaptmp1 = (u)->ui[0]; \\\n\t\tduk__bswaptmp2 = (u)->ui[1]; \\\n\t\tduk__bswaptmp1 = DUK_BSWAP32(duk__bswaptmp1); \\\n\t\tduk__bswaptmp2 = DUK_BSWAP32(duk__bswaptmp2); \\\n\t\t(u)->ui[0] = duk__bswaptmp1; \\\n\t\t(u)->ui[1] = duk__bswaptmp2; \\\n\t} while (0)\n#elif defined(DUK_USE_DOUBLE_BE)\n#define DUK_DBLUNION_DOUBLE_HTON(u) do { } while (0)\n#else\n#error internal error, double endianness insane\n#endif\n\n/* Reverse operation is the same. */\n#define DUK_DBLUNION_DOUBLE_NTOH(u) DUK_DBLUNION_DOUBLE_HTON((u))\n\n/* Some sign bit helpers. */\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBLUNION_HAS_SIGNBIT(u) (((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x8000000000000000)) != 0)\n#define DUK_DBLUNION_GET_SIGNBIT(u) (((u)->ull[DUK_DBL_IDX_ULL0] >> 63U))\n#else\n#define DUK_DBLUNION_HAS_SIGNBIT(u) (((u)->ui[DUK_DBL_IDX_UI0] & 0x80000000UL) != 0)\n#define DUK_DBLUNION_GET_SIGNBIT(u) (((u)->ui[DUK_DBL_IDX_UI0] >> 31U))\n#endif\n\n#endif  /* DUK_DBLUNION_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_debug.h",
    "content": "/*\n *  Debugging macros, DUK_DPRINT() and its variants in particular.\n *\n *  DUK_DPRINT() allows formatted debug prints, and supports standard\n *  and Duktape specific formatters.  See duk_debug_vsnprintf.c for details.\n *\n *  DUK_D(x), DUK_DD(x), and DUK_DDD(x) are used together with log macros\n *  for technical reasons.  They are concretely used to hide 'x' from the\n *  compiler when the corresponding log level is disabled.  This allows\n *  clean builds on non-C99 compilers, at the cost of more verbose code.\n *  Examples:\n *\n *    DUK_D(DUK_DPRINT(\"foo\"));\n *    DUK_DD(DUK_DDPRINT(\"foo\"));\n *    DUK_DDD(DUK_DDDPRINT(\"foo\"));\n *\n *  This approach is preferable to the old \"double parentheses\" hack because\n *  double parentheses make the C99 solution worse: __FILE__ and __LINE__ can\n *  no longer be added transparently without going through globals, which\n *  works poorly with threading.\n */\n\n#if !defined(DUK_DEBUG_H_INCLUDED)\n#define DUK_DEBUG_H_INCLUDED\n\n#if defined(DUK_USE_DEBUG)\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0)\n#define DUK_D(x) x\n#else\n#define DUK_D(x) do { } while (0) /* omit */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n#define DUK_DD(x) x\n#else\n#define DUK_DD(x) do { } while (0) /* omit */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK_DDD(x) x\n#else\n#define DUK_DDD(x) do { } while (0) /* omit */\n#endif\n\n/*\n *  Exposed debug macros: debugging enabled\n */\n\n#if defined(DUK_USE_VARIADIC_MACROS)\n\n/* Note: combining __FILE__, __LINE__, and __func__ into fmt would be\n * possible compile time, but waste some space with shared function names.\n */\n#define DUK__DEBUG_LOG(lev,...)  duk_debug_log((duk_int_t) (lev), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, DUK_FUNC_MACRO, __VA_ARGS__);\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0)\n#define DUK_DPRINT(...)          DUK__DEBUG_LOG(DUK_LEVEL_DEBUG, __VA_ARGS__)\n#else\n#define DUK_DPRINT(...)\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n#define DUK_DDPRINT(...)         DUK__DEBUG_LOG(DUK_LEVEL_DDEBUG, __VA_ARGS__)\n#else\n#define DUK_DDPRINT(...)\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK_DDDPRINT(...)        DUK__DEBUG_LOG(DUK_LEVEL_DDDEBUG, __VA_ARGS__)\n#else\n#define DUK_DDDPRINT(...)\n#endif\n\n#else  /* DUK_USE_VARIADIC_MACROS */\n\n#define DUK__DEBUG_STASH(lev)    \\\n\t(void) DUK_SNPRINTF(duk_debug_file_stash, DUK_DEBUG_STASH_SIZE, \"%s\", (const char *) DUK_FILE_MACRO), \\\n\t(void) (duk_debug_file_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), \\\n\t(void) (duk_debug_line_stash = (duk_int_t) DUK_LINE_MACRO), \\\n\t(void) DUK_SNPRINTF(duk_debug_func_stash, DUK_DEBUG_STASH_SIZE, \"%s\", (const char *) DUK_FUNC_MACRO), \\\n\t(void) (duk_debug_func_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), \\\n\t(void) (duk_debug_level_stash = (lev))\n\n/* Without variadic macros resort to comma expression trickery to handle debug\n * prints.  This generates a lot of harmless warnings.  These hacks are not\n * needed normally because DUK_D() and friends will hide the entire debug log\n * statement from the compiler.\n */\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0)\n#define DUK_DPRINT  DUK__DEBUG_STASH(DUK_LEVEL_DEBUG), (void) duk_debug_log  /* args go here in parens */\n#else\n#define DUK_DPRINT  0 && /* args go here as a comma expression in parens */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n#define DUK_DDPRINT  DUK__DEBUG_STASH(DUK_LEVEL_DDEBUG), (void) duk_debug_log  /* args go here in parens */\n#else\n#define DUK_DDPRINT  0 && /* args */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK_DDDPRINT  DUK__DEBUG_STASH(DUK_LEVEL_DDDEBUG), (void) duk_debug_log  /* args go here in parens */\n#else\n#define DUK_DDDPRINT  0 && /* args */\n#endif\n\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n#else  /* DUK_USE_DEBUG */\n\n/*\n *  Exposed debug macros: debugging disabled\n */\n\n#define DUK_D(x) do { } while (0) /* omit */\n#define DUK_DD(x) do { } while (0) /* omit */\n#define DUK_DDD(x) do { } while (0) /* omit */\n\n#if defined(DUK_USE_VARIADIC_MACROS)\n\n#define DUK_DPRINT(...)\n#define DUK_DDPRINT(...)\n#define DUK_DDDPRINT(...)\n\n#else  /* DUK_USE_VARIADIC_MACROS */\n\n#define DUK_DPRINT    0 && /* args go here as a comma expression in parens */\n#define DUK_DDPRINT   0 && /* args */\n#define DUK_DDDPRINT  0 && /* args */\n\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n#endif  /* DUK_USE_DEBUG */\n\n/*\n *  Structs\n */\n\n#if defined(DUK_USE_DEBUG)\nstruct duk_fixedbuffer {\n\tduk_uint8_t *buffer;\n\tduk_size_t length;\n\tduk_size_t offset;\n\tduk_bool_t truncated;\n};\n#endif\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_INTERNAL_DECL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const char *format, va_list ap);\n#if 0  /*unused*/\nDUK_INTERNAL_DECL duk_int_t duk_debug_snprintf(char *str, duk_size_t size, const char *format, ...);\n#endif\nDUK_INTERNAL_DECL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_uint8_t *fptr, duk_size_t fptr_size);\n\n#if defined(DUK_USE_VARIADIC_MACROS)\nDUK_INTERNAL_DECL void duk_debug_log(duk_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...);\n#else  /* DUK_USE_VARIADIC_MACROS */\n/* parameter passing, not thread safe */\n#define DUK_DEBUG_STASH_SIZE  128\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL_DECL duk_int_t duk_debug_line_stash;\nDUK_INTERNAL_DECL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL_DECL duk_int_t duk_debug_level_stash;\n#endif\nDUK_INTERNAL_DECL void duk_debug_log(const char *fmt, ...);\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\nDUK_INTERNAL_DECL void duk_fb_put_bytes(duk_fixedbuffer *fb, const duk_uint8_t *buffer, duk_size_t length);\nDUK_INTERNAL_DECL void duk_fb_put_byte(duk_fixedbuffer *fb, duk_uint8_t x);\nDUK_INTERNAL_DECL void duk_fb_put_cstring(duk_fixedbuffer *fb, const char *x);\nDUK_INTERNAL_DECL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...);\nDUK_INTERNAL_DECL void duk_fb_put_funcptr(duk_fixedbuffer *fb, duk_uint8_t *fptr, duk_size_t fptr_size);\nDUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);\n\n#endif  /* DUK_USE_DEBUG */\n\n#endif  /* DUK_DEBUG_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_debug_fixedbuffer.c",
    "content": "/*\n *  Fixed buffer helper useful for debugging, requires no allocation\n *  which is critical for debugging.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_DEBUG)\n\nDUK_INTERNAL void duk_fb_put_bytes(duk_fixedbuffer *fb, const duk_uint8_t *buffer, duk_size_t length) {\n\tduk_size_t avail;\n\tduk_size_t copylen;\n\n\tavail = (fb->offset >= fb->length ? (duk_size_t) 0 : (duk_size_t) (fb->length - fb->offset));\n\tif (length > avail) {\n\t\tcopylen = avail;\n\t\tfb->truncated = 1;\n\t} else {\n\t\tcopylen = length;\n\t}\n\tduk_memcpy_unsafe(fb->buffer + fb->offset, buffer, copylen);\n\tfb->offset += copylen;\n}\n\nDUK_INTERNAL void duk_fb_put_byte(duk_fixedbuffer *fb, duk_uint8_t x) {\n\tduk_fb_put_bytes(fb, (const duk_uint8_t *) &x, 1);\n}\n\nDUK_INTERNAL void duk_fb_put_cstring(duk_fixedbuffer *fb, const char *x) {\n\tduk_fb_put_bytes(fb, (const duk_uint8_t *) x, (duk_size_t) DUK_STRLEN(x));\n}\n\nDUK_INTERNAL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...) {\n\tduk_size_t avail;\n\tva_list ap;\n\n\tva_start(ap, fmt);\n\tavail = (fb->offset >= fb->length ? (duk_size_t) 0 : (duk_size_t) (fb->length - fb->offset));\n\tif (avail > 0) {\n\t\tduk_int_t res = (duk_int_t) DUK_VSNPRINTF((char *) (fb->buffer + fb->offset), avail, fmt, ap);\n\t\tif (res < 0) {\n\t\t\t/* error */\n\t\t} else if ((duk_size_t) res >= avail) {\n\t\t\t/* (maybe) truncated */\n\t\t\tfb->offset += avail;\n\t\t\tif ((duk_size_t) res > avail) {\n\t\t\t\t/* actual chars dropped (not just NUL term) */\n\t\t\t\tfb->truncated = 1;\n\t\t\t}\n\t\t} else {\n\t\t\t/* normal */\n\t\t\tfb->offset += (duk_size_t) res;\n\t\t}\n\t}\n\tva_end(ap);\n}\n\nDUK_INTERNAL void duk_fb_put_funcptr(duk_fixedbuffer *fb, duk_uint8_t *fptr, duk_size_t fptr_size) {\n\tchar buf[64+1];\n\tduk_debug_format_funcptr(buf, sizeof(buf), fptr, fptr_size);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\tduk_fb_put_cstring(fb, buf);\n}\n\nDUK_INTERNAL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb) {\n\treturn (fb->offset >= fb->length);\n}\n\n#endif  /* DUK_USE_DEBUG */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_debug_macros.c",
    "content": "/*\n *  Debugging macro calls.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_DEBUG)\n\n/*\n *  Debugging enabled\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdarg.h>\n\n#if !defined(DUK_USE_DEBUG_WRITE)\n#error debugging enabled (DUK_USE_DEBUG) but DUK_USE_DEBUG_WRITE not defined\n#endif\n\n#define DUK__DEBUG_BUFSIZE  DUK_USE_DEBUG_BUFSIZE\n\n#if defined(DUK_USE_VARIADIC_MACROS)\n\nDUK_INTERNAL void duk_debug_log(duk_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...) {\n\tva_list ap;\n\tlong arg_level;\n\tconst char *arg_file;\n\tlong arg_line;\n\tconst char *arg_func;\n\tconst char *arg_msg;\n\tchar buf[DUK__DEBUG_BUFSIZE];\n\n\tva_start(ap, fmt);\n\n\tduk_memzero((void *) buf, (size_t) DUK__DEBUG_BUFSIZE);\n\tduk_debug_vsnprintf(buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap);\n\n\targ_level = (long) level;\n\targ_file = (const char *) file;\n\targ_line = (long) line;\n\targ_func = (const char *) func;\n\targ_msg = (const char *) buf;\n\tDUK_USE_DEBUG_WRITE(arg_level, arg_file, arg_line, arg_func, arg_msg);\n\n\tva_end(ap);\n}\n\n#else  /* DUK_USE_VARIADIC_MACROS */\n\nDUK_INTERNAL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL duk_int_t duk_debug_line_stash;\nDUK_INTERNAL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL duk_int_t duk_debug_level_stash;\n\nDUK_INTERNAL void duk_debug_log(const char *fmt, ...) {\n\tva_list ap;\n\tlong arg_level;\n\tconst char *arg_file;\n\tlong arg_line;\n\tconst char *arg_func;\n\tconst char *arg_msg;\n\tchar buf[DUK__DEBUG_BUFSIZE];\n\n\tva_start(ap, fmt);\n\n\tduk_memzero((void *) buf, (size_t) DUK__DEBUG_BUFSIZE);\n\tduk_debug_vsnprintf(buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap);\n\n\targ_level = (long) duk_debug_level_stash;\n\targ_file = (const char *) duk_debug_file_stash;\n\targ_line = (long) duk_debug_line_stash;\n\targ_func = (const char *) duk_debug_func_stash;\n\targ_msg = (const char *) buf;\n\tDUK_USE_DEBUG_WRITE(arg_level, arg_file, arg_line, arg_func, arg_msg);\n\n\tva_end(ap);\n}\n\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n#else  /* DUK_USE_DEBUG */\n\n/*\n *  Debugging disabled\n */\n\n#endif  /* DUK_USE_DEBUG */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_debug_vsnprintf.c",
    "content": "/*\n *  Custom formatter for debug printing, allowing Duktape specific data\n *  structures (such as tagged values and heap objects) to be printed with\n *  a nice format string.  Because debug printing should not affect execution\n *  state, formatting here must be independent of execution (see implications\n *  below) and must not allocate memory.\n *\n *  Custom format tags begin with a '%!' to safely distinguish them from\n *  standard format tags.  The following conversions are supported:\n *\n *     %!T    tagged value (duk_tval *)\n *     %!O    heap object (duk_heaphdr *)\n *     %!I    decoded bytecode instruction\n *     %!X    bytecode instruction opcode name (arg is long)\n *     %!C    catcher (duk_catcher *)\n *     %!A    activation (duk_activation *)\n *\n *  Everything is serialized in a JSON-like manner.  The default depth is one\n *  level, internal prototype is not followed, and internal properties are not\n *  serialized.  The following modifiers change this behavior:\n *\n *     @      print pointers\n *     #      print binary representations (where applicable)\n *     d      deep traversal of own properties (not prototype)\n *     p      follow prototype chain (useless without 'd')\n *     i      include internal properties (other than prototype)\n *     x      hexdump buffers\n *     h      heavy formatting\n *\n *  For instance, the following serializes objects recursively, but does not\n *  follow the prototype chain nor print internal properties: \"%!dO\".\n *\n *  Notes:\n *\n *    * Standard snprintf return value semantics seem to vary.  This\n *      implementation returns the number of bytes it actually wrote\n *      (excluding the null terminator).  If retval == buffer size,\n *      output was truncated (except for corner cases).\n *\n *    * Output format is intentionally different from ECMAScript\n *      formatting requirements, as formatting here serves debugging\n *      of internals.\n *\n *    * Depth checking (and updating) is done in each type printer\n *      separately, to allow them to call each other freely.\n *\n *    * Some pathological structures might take ages to print (e.g.\n *      self recursion with 100 properties pointing to the object\n *      itself).  To guard against these, each printer also checks\n *      whether the output buffer is full; if so, early exit.\n *\n *    * Reference loops are detected using a loop stack.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_DEBUG)\n\n#include <stdio.h>\n#include <stdarg.h>\n#include <string.h>\n\n/* list of conversion specifiers that terminate a format tag;\n * this is unfortunately guesswork.\n */\n#define DUK__ALLOWED_STANDARD_SPECIFIERS  \"diouxXeEfFgGaAcsCSpnm\"\n\n/* maximum length of standard format tag that we support */\n#define DUK__MAX_FORMAT_TAG_LENGTH  32\n\n/* heapobj recursion depth when deep printing is selected */\n#define DUK__DEEP_DEPTH_LIMIT  8\n\n/* maximum recursion depth for loop detection stacks */\n#define DUK__LOOP_STACK_DEPTH  256\n\n/* must match bytecode defines now; build autogenerate? */\nDUK_LOCAL const char * const duk__bc_optab[256] = {\n\t\"LDREG\", \"STREG\", \"JUMP\", \"LDCONST\", \"LDINT\", \"LDINTX\", \"LDTHIS\", \"LDUNDEF\",\n\t\"LDNULL\", \"LDTRUE\", \"LDFALSE\", \"GETVAR\", \"BNOT\", \"LNOT\", \"UNM\", \"UNP\",\n\t\"EQ_RR\", \"EQ_CR\", \"EQ_RC\", \"EQ_CC\", \"NEQ_RR\", \"NEQ_CR\", \"NEQ_RC\", \"NEQ_CC\",\n\t\"SEQ_RR\", \"SEQ_CR\", \"SEQ_RC\", \"SEQ_CC\", \"SNEQ_RR\", \"SNEQ_CR\", \"SNEQ_RC\", \"SNEQ_CC\",\n\n\t\"GT_RR\", \"GT_CR\", \"GT_RC\", \"GT_CC\", \"GE_RR\", \"GE_CR\", \"GE_RC\", \"GE_CC\",\n\t\"LT_RR\", \"LT_CR\", \"LT_RC\", \"LT_CC\", \"LE_RR\", \"LE_CR\", \"LE_RC\", \"LE_CC\",\n\t\"IFTRUE_R\", \"IFTRUE_C\", \"IFFALSE_R\", \"IFFALSE_C\", \"ADD_RR\", \"ADD_CR\", \"ADD_RC\", \"ADD_CC\",\n\t\"SUB_RR\", \"SUB_CR\", \"SUB_RC\", \"SUB_CC\", \"MUL_RR\", \"MUL_CR\", \"MUL_RC\", \"MUL_CC\",\n\n\t\"DIV_RR\", \"DIV_CR\", \"DIV_RC\", \"DIV_CC\", \"MOD_RR\", \"MOD_CR\", \"MOD_RC\", \"MOD_CC\",\n\t\"EXP_RR\", \"EXP_CR\", \"EXP_RC\", \"EXP_CC\", \"BAND_RR\", \"BAND_CR\", \"BAND_RC\", \"BAND_CC\",\n\t\"BOR_RR\", \"BOR_CR\", \"BOR_RC\", \"BOR_CC\", \"BXOR_RR\", \"BXOR_CR\", \"BXOR_RC\", \"BXOR_CC\",\n\t\"BASL_RR\", \"BASL_CR\", \"BASL_RC\", \"BASL_CC\", \"BLSR_RR\", \"BLSR_CR\", \"BLSR_RC\", \"BLSR_CC\",\n\n\t\"BASR_RR\", \"BASR_CR\", \"BASR_RC\", \"BASR_CC\", \"INSTOF_RR\", \"INSTOF_CR\", \"INSTOF_RC\", \"INSTOF_CC\",\n\t\"IN_RR\", \"IN_CR\", \"IN_RC\", \"IN_CC\", \"GETPROP_RR\", \"GETPROP_CR\", \"GETPROP_RC\", \"GETPROP_CC\",\n\t\"PUTPROP_RR\", \"PUTPROP_CR\", \"PUTPROP_RC\", \"PUTPROP_CC\", \"DELPROP_RR\", \"DELPROP_CR\", \"DELPROP_RC\", \"DELPROP_CC\",\n\t\"PREINCR\", \"PREDECR\", \"POSTINCR\", \"POSTDECR\", \"PREINCV\", \"PREDECV\", \"POSTINCV\", \"POSTDECV\",\n\n\t\"PREINCP_RR\", \"PREINCP_CR\", \"PREINCP_RC\", \"PREINCP_CC\", \"PREDECP_RR\", \"PREDECP_CR\", \"PREDECP_RC\", \"PREDECP_CC\",\n\t\"POSTINCP_RR\", \"POSTINCP_CR\", \"POSTINCP_RC\", \"POSTINCP_CC\", \"POSTDECP_RR\", \"POSTDECP_CR\", \"POSTDECP_RC\", \"POSTDECP_CC\",\n\t\"DECLVAR_RR\", \"DECLVAR_CR\", \"DECLVAR_RC\", \"DECLVAR_CC\", \"REGEXP_RR\", \"REGEXP_RC\", \"REGEXP_CR\", \"REGEXP_CC\",\n\t\"CLOSURE\", \"TYPEOF\", \"TYPEOFID\", \"PUTVAR\", \"DELVAR\", \"RETREG\", \"RETUNDEF\", \"RETCONST\",\n\n\t\"RETCONSTN\", \"LABEL\", \"ENDLABEL\", \"BREAK\", \"CONTINUE\", \"TRYCATCH\", \"ENDTRY\", \"ENDCATCH\",\n\t\"ENDFIN\", \"THROW\", \"INVLHS\", \"CSREG\", \"CSVAR_RR\", \"CSVAR_CR\", \"CSVAR_RC\", \"CSVAR_CC\",\n\t\"CALL0\", \"CALL1\", \"CALL2\", \"CALL3\", \"CALL4\", \"CALL5\", \"CALL6\", \"CALL7\",\n\t\"CALL8\", \"CALL9\", \"CALL10\", \"CALL11\", \"CALL12\", \"CALL13\", \"CALL14\", \"CALL15\",\n\n\t\"NEWOBJ\", \"NEWARR\", \"MPUTOBJ\", \"MPUTOBJI\", \"INITSET\", \"INITGET\", \"MPUTARR\", \"MPUTARRI\",\n\t\"SETALEN\", \"INITENUM\", \"NEXTENUM\", \"NEWTARGET\", \"DEBUGGER\", \"NOP\", \"INVALID\", \"UNUSED207\",\n\t\"GETPROPC_RR\", \"GETPROPC_CR\", \"GETPROPC_RC\", \"GETPROPC_CC\", \"UNUSED212\", \"UNUSED213\", \"UNUSED214\", \"UNUSED215\",\n\t\"UNUSED216\", \"UNUSED217\", \"UNUSED218\", \"UNUSED219\", \"UNUSED220\", \"UNUSED221\", \"UNUSED222\", \"UNUSED223\",\n\n\t\"UNUSED224\", \"UNUSED225\", \"UNUSED226\", \"UNUSED227\", \"UNUSED228\", \"UNUSED229\", \"UNUSED230\", \"UNUSED231\",\n\t\"UNUSED232\", \"UNUSED233\", \"UNUSED234\", \"UNUSED235\", \"UNUSED236\", \"UNUSED237\", \"UNUSED238\", \"UNUSED239\",\n\t\"UNUSED240\", \"UNUSED241\", \"UNUSED242\", \"UNUSED243\", \"UNUSED244\", \"UNUSED245\", \"UNUSED246\", \"UNUSED247\",\n\t\"UNUSED248\", \"UNUSED249\", \"UNUSED250\", \"UNUSED251\", \"UNUSED252\", \"UNUSED253\", \"UNUSED254\", \"UNUSED255\"\n};\n\ntypedef struct duk__dprint_state duk__dprint_state;\nstruct duk__dprint_state {\n\tduk_fixedbuffer *fb;\n\n\t/* loop_stack_index could be perhaps be replaced by 'depth', but it's nice\n\t * to not couple these two mechanisms unnecessarily.\n\t */\n\tduk_hobject *loop_stack[DUK__LOOP_STACK_DEPTH];\n\tduk_int_t loop_stack_index;\n\tduk_int_t loop_stack_limit;\n\n\tduk_int_t depth;\n\tduk_int_t depth_limit;\n\n\tduk_bool_t pointer;\n\tduk_bool_t heavy;\n\tduk_bool_t binary;\n\tduk_bool_t follow_proto;\n\tduk_bool_t internal;\n\tduk_bool_t hexdump;\n};\n\n/* helpers */\nDUK_LOCAL_DECL void duk__print_hstring(duk__dprint_state *st, duk_hstring *k, duk_bool_t quotes);\nDUK_LOCAL_DECL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h);\nDUK_LOCAL_DECL void duk__print_hbuffer(duk__dprint_state *st, duk_hbuffer *h);\nDUK_LOCAL_DECL void duk__print_tval(duk__dprint_state *st, duk_tval *tv);\nDUK_LOCAL_DECL void duk__print_instr(duk__dprint_state *st, duk_instr_t ins);\nDUK_LOCAL_DECL void duk__print_heaphdr(duk__dprint_state *st, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__print_shared_heaphdr(duk__dprint_state *st, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__print_shared_heaphdr_string(duk__dprint_state *st, duk_heaphdr_string *h);\n\nDUK_LOCAL void duk__print_shared_heaphdr(duk__dprint_state *st, duk_heaphdr *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"(%p)\", (void *) h);\n\t}\n\n\tif (!h) {\n\t\treturn;\n\t}\n\n\tif (st->binary) {\n\t\tduk_size_t i;\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET);\n\t\tfor (i = 0; i < (duk_size_t) sizeof(*h); i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) ((duk_uint8_t *)h)[i]);\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET);\n\t}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)  /* currently implicitly also DUK_USE_DOUBLE_LINKED_HEAP */\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_next=%p,h_prev=%p,h_refcount=%lu,h_flags=%08lx,type=%ld,\"\n\t\t               \"reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (void *) DUK_HEAPHDR_GET_NEXT(NULL, h),\n\t\t               (void *) DUK_HEAPHDR_GET_PREV(NULL, h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS(h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE(h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED(h) ? 1 : 0));\n\t}\n#else\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_next=%p,h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (void *) DUK_HEAPHDR_GET_NEXT(NULL, h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS(h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE(h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED(h) ? 1 : 0));\n\t}\n#endif\n}\n\nDUK_LOCAL void duk__print_shared_heaphdr_string(duk__dprint_state *st, duk_heaphdr_string *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"(%p)\", (void *) h);\n\t}\n\n\tif (!h) {\n\t\treturn;\n\t}\n\n\tif (st->binary) {\n\t\tduk_size_t i;\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET);\n\t\tfor (i = 0; i < (duk_size_t) sizeof(*h); i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) ((duk_uint8_t *)h)[i]);\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET);\n\t}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_refcount=%lu,h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (unsigned long) DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) h) ? 1 : 0));\n\t}\n#else\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) h) ? 1 : 0));\n\t}\n#endif\n}\n\nDUK_LOCAL void duk__print_hstring(duk__dprint_state *st, duk_hstring *h, duk_bool_t quotes) {\n\tduk_fixedbuffer *fb = st->fb;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\n\t/* terminal type: no depth check */\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tduk__print_shared_heaphdr_string(st, &h->hdr);\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tp = DUK_HSTRING_GET_DATA(h);\n\tp_end = p + DUK_HSTRING_GET_BYTELEN(h);\n\n\tif (p_end > p && p[0] == DUK_ASC_UNDERSCORE) {\n\t\t/* If property key begins with underscore, encode it with\n\t\t * forced quotes (e.g. \"_Foo\") to distinguish it from encoded\n\t\t * internal properties (e.g. \\x82Bar -> _Bar).\n\t\t */\n\t\tquotes = 1;\n\t}\n\n\tif (quotes) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_DOUBLEQUOTE);\n\t}\n\twhile (p < p_end) {\n\t\tduk_uint8_t ch = *p++;\n\n\t\t/* two special escapes: '\\' and '\"', other printables as is */\n\t\tif (ch == '\\\\') {\n\t\t\tduk_fb_sprintf(fb, \"\\\\\\\\\");\n\t\t} else if (ch == '\"') {\n\t\t\tduk_fb_sprintf(fb, \"\\\\\\\"\");\n\t\t} else if (ch >= 0x20 && ch <= 0x7e) {\n\t\t\tduk_fb_put_byte(fb, ch);\n\t\t} else if (ch == 0x82 && !quotes) {\n\t\t\t/* encode \\x82Bar as _Bar if no quotes are\n\t\t\t * applied, this is for readable internal keys.\n\t\t\t */\n\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_UNDERSCORE);\n\t\t} else {\n\t\t\tduk_fb_sprintf(fb, \"\\\\x%02lx\", (unsigned long) ch);\n\t\t}\n\t}\n\tif (quotes) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_DOUBLEQUOTE);\n\t}\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* XXX: limit to quoted strings only, to save keys from being cluttered? */\n\tduk_fb_sprintf(fb, \"/%lu\", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(&h->hdr));\n#endif\n}\n\n#define DUK__COMMA()  do { \\\n\t\tif (first) { \\\n\t\t\tfirst = 0; \\\n\t\t} else { \\\n\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COMMA); \\\n\t\t} \\\n\t} while (0)\n\nDUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\tduk_uint_fast32_t i;\n\tduk_tval *tv;\n\tduk_hstring *key;\n\tduk_bool_t first = 1;\n\tconst char *brace1 = \"{\";\n\tconst char *brace2 = \"}\";\n\tduk_bool_t pushed_loopstack = 0;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tduk__print_shared_heaphdr(st, &h->hdr);\n\n\tif (h && DUK_HOBJECT_HAS_ARRAY_PART(h)) {\n\t\tbrace1 = \"[\";\n\t\tbrace2 = \"]\";\n\t}\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\tgoto finished;\n\t}\n\n\tif (st->depth >= st->depth_limit) {\n\t\tconst char *subtype = \"generic\";\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\t\tsubtype = \"compfunc\";\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\t\tsubtype = \"natfunc\";\n\t\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\t\tsubtype = \"thread\";\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\tsubtype = \"bufobj\";\n\t\t} else if (DUK_HOBJECT_IS_ARRAY(h)) {\n\t\t\tsubtype = \"array\";\n\t\t}\n\t\tduk_fb_sprintf(fb, \"%sobject/%s %p%s\", (const char *) brace1, subtype, (void *) h, (const char *) brace2);\n\t\treturn;\n\t}\n\n\tfor (i = 0; i < (duk_uint_fast32_t) st->loop_stack_index; i++) {\n\t\tif (st->loop_stack[i] == h) {\n\t\t\tduk_fb_sprintf(fb, \"%sLOOP:%p%s\", (const char *) brace1, (void *) h, (const char *) brace2);\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/* after this, return paths should 'goto finished' for decrement */\n\tst->depth++;\n\n\tif (st->loop_stack_index >= st->loop_stack_limit) {\n\t\tduk_fb_sprintf(fb, \"%sOUT-OF-LOOP-STACK%s\", (const char *) brace1, (const char *) brace2);\n\t\tgoto finished;\n\t}\n\tst->loop_stack[st->loop_stack_index++] = h;\n\tpushed_loopstack = 1;\n\n\t/*\n\t *  Notation: double underscore used for internal properties which are not\n\t *  stored in the property allocation (e.g. '__valstack').\n\t */\n\n\tduk_fb_put_cstring(fb, brace1);\n\n\tif (DUK_HOBJECT_GET_PROPS(NULL, h)) {\n\t\tduk_uint32_t a_limit;\n\n\t\ta_limit = DUK_HOBJECT_GET_ASIZE(h);\n\t\tif (st->internal) {\n\t\t\t/* dump all allocated entries, unused entries print as 'unused',\n\t\t\t * note that these may extend beyond current 'length' and look\n\t\t\t * a bit funny.\n\t\t\t */\n\t\t} else {\n\t\t\t/* leave out trailing 'unused' elements */\n\t\t\twhile (a_limit > 0) {\n\t\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(NULL, h, a_limit - 1);\n\t\t\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ta_limit--;\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < a_limit; i++) {\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(NULL, h, i);\n\t\t\tDUK__COMMA();\n\t\t\tduk__print_tval(st, tv);\n\t\t}\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(NULL, h, i);\n\t\t\tif (!key) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!st->internal && DUK_HSTRING_HAS_HIDDEN(key)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tDUK__COMMA();\n\t\t\tduk__print_hstring(st, key, 0);\n\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COLON);\n\t\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(NULL, h, i)) {\n\t\t\t\tduk_fb_sprintf(fb, \"[get:%p,set:%p]\",\n\t\t\t\t               (void *) DUK_HOBJECT_E_GET_VALUE(NULL, h, i).a.get,\n\t\t\t\t               (void *) DUK_HOBJECT_E_GET_VALUE(NULL, h, i).a.set);\n\t\t\t} else {\n\t\t\t\ttv = &DUK_HOBJECT_E_GET_VALUE(NULL, h, i).v;\n\t\t\t\tduk__print_tval(st, tv);\n\t\t\t}\n\t\t\tif (st->heavy) {\n\t\t\t\tduk_fb_sprintf(fb, \"<%02lx>\", (unsigned long) DUK_HOBJECT_E_GET_FLAGS(NULL, h, i));\n\t\t\t}\n\t\t}\n\t}\n\tif (st->internal) {\n\t\tif (DUK_HOBJECT_IS_ARRAY(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__array:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXTENSIBLE(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__extensible:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_CONSTRUCTABLE(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__constructable:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__boundfunc:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_COMPFUNC(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__compfunc:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NATFUNC(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__natfunc:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_BUFOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__bufobj:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_IS_THREAD(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__thread:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_ARRAY_PART(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__array_part:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_STRICT(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__strict:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NOTAIL(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__notail:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NEWENV(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__newenv:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NAMEBINDING(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__namebinding:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_CREATEARGS(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__createargs:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_array:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_stringobj:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_arguments:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_bufobj:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_proxyobj:true\");\n\t\t}\n\t}\n\n\tif (st->internal && DUK_HOBJECT_IS_ARRAY(h)) {\n\t\tduk_harray *a = (duk_harray *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__length:%ld\", (long) a->length);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__length_nonwritable:%ld\", (long) a->length_nonwritable);\n\t} else if (st->internal && DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__data:\");\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(NULL, f));\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__lexenv:\"); duk__print_hobject(st, DUK_HCOMPFUNC_GET_LEXENV(NULL, f));\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__varenv:\"); duk__print_hobject(st, DUK_HCOMPFUNC_GET_VARENV(NULL, f));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__nregs:%ld\", (long) f->nregs);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__nargs:%ld\", (long) f->nargs);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__start_line:%ld\", (long) f->start_line);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__end_line:%ld\", (long) f->end_line);\n#endif\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__data:\");\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(NULL, f));\n\t} else if (st->internal && DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\tduk_hnatfunc *f = (duk_hnatfunc *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__func:\");\n\t\tduk_fb_put_funcptr(fb, (duk_uint8_t *) &f->func, sizeof(f->func));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__nargs:%ld\", (long) f->nargs);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__magic:%ld\", (long) f->magic);\n\t} else if (st->internal && DUK_HOBJECT_IS_DECENV(h)) {\n\t\tduk_hdecenv *e = (duk_hdecenv *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__thread:\"); duk__print_hobject(st, (duk_hobject *) e->thread);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__varmap:\"); duk__print_hobject(st, (duk_hobject *) e->varmap);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__regbase_byteoff:%ld\", (long) e->regbase_byteoff);\n\t} else if (st->internal && DUK_HOBJECT_IS_OBJENV(h)) {\n\t\tduk_hobjenv *e = (duk_hobjenv *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__target:\"); duk__print_hobject(st, (duk_hobject *) e->target);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__has_this:%ld\", (long) e->has_this);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t} else if (st->internal && DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\tduk_hbufobj *b = (duk_hbufobj *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__buf:\");\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) b->buf);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__buf_prop:\");\n\t\tduk__print_hobject(st, (duk_hobject *) b->buf_prop);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__offset:%ld\", (long) b->offset);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__length:%ld\", (long) b->length);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__shift:%ld\", (long) b->shift);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__elemtype:%ld\", (long) b->elem_type);\n#endif\n\t} else if (st->internal && DUK_HOBJECT_IS_PROXY(h)) {\n\t\tduk_hproxy *p = (duk_hproxy *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__target:\");\n\t\tduk__print_hobject(st, p->target);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__handler:\");\n\t\tduk__print_hobject(st, p->handler);\n\t} else if (st->internal && DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__ptr_curr_pc:%p\", (void *) t->ptr_curr_pc);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__heap:%p\", (void *) t->heap);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__strict:%ld\", (long) t->strict);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__state:%ld\", (long) t->state);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__unused1:%ld\", (long) t->unused1);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__unused2:%ld\", (long) t->unused2);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack:%p\", (void *) t->valstack);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_end:%p/%ld\", (void *) t->valstack_end, (long) (t->valstack_end - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_alloc_end:%p/%ld\", (void *) t->valstack_alloc_end, (long) (t->valstack_alloc_end - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_bottom:%p/%ld\", (void *) t->valstack_bottom, (long) (t->valstack_bottom - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_top:%p/%ld\", (void *) t->valstack_top, (long) (t->valstack_top - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__callstack_curr:%p\", (void *) t->callstack_curr);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__callstack_top:%ld\", (long) t->callstack_top);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__callstack_preventcount:%ld\", (long) t->callstack_preventcount);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__resumer:\"); duk__print_hobject(st, (duk_hobject *) t->resumer);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__compile_ctx:%p\", (void *) t->compile_ctx);\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__interrupt_counter:%ld\", (long) t->interrupt_counter);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__interrupt_init:%ld\", (long) t->interrupt_init);\n#endif\n\n\t\t/* XXX: print built-ins array? */\n\n\t}\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tif (st->internal) {\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__refcount:%lu\", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h));\n\t}\n#endif\n\tif (st->internal) {\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__class:%ld\", (long) DUK_HOBJECT_GET_CLASS_NUMBER(h));\n\t}\n\n\tDUK__COMMA(); duk_fb_sprintf(fb, \"__heapptr:%p\", (void *) h);  /* own pointer */\n\n\t/* prototype should be last, for readability */\n\tif (DUK_HOBJECT_GET_PROTOTYPE(NULL, h)) {\n\t\tif (st->follow_proto) {\n\t\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__prototype:\"); duk__print_hobject(st, DUK_HOBJECT_GET_PROTOTYPE(NULL, h));\n\t\t} else {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__prototype:%p\", (void *) DUK_HOBJECT_GET_PROTOTYPE(NULL, h));\n\t\t}\n\t}\n\n\tduk_fb_put_cstring(fb, brace2);\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (st->heavy && DUK_HOBJECT_GET_HSIZE(h) > 0) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LANGLE);\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_HSIZE(h); i++) {\n\t\t\tduk_uint_t h_idx = DUK_HOBJECT_H_GET_INDEX(NULL, h, i);\n\t\t\tif (i > 0) {\n\t\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COMMA);\n\t\t\t}\n\t\t\tif (h_idx == DUK_HOBJECT_HASHIDX_UNUSED) {\n\t\t\t\tduk_fb_sprintf(fb, \"u\");\n\t\t\t} else if (h_idx == DUK_HOBJECT_HASHIDX_DELETED) {\n\t\t\t\tduk_fb_sprintf(fb, \"d\");\n\t\t\t} else {\n\t\t\t\tduk_fb_sprintf(fb, \"%ld\", (long) h_idx);\n\t\t\t}\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RANGLE);\n\t}\n#endif\n\n finished:\n\tst->depth--;\n\tif (pushed_loopstack) {\n\t\tst->loop_stack_index--;\n\t\tst->loop_stack[st->loop_stack_index] = NULL;\n\t}\n}\n\nDUK_LOCAL void duk__print_hbuffer(duk__dprint_state *st, duk_hbuffer *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\tduk_size_t i, n;\n\tduk_uint8_t *p;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\t/* terminal type: no depth check */\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tif (DUK_HBUFFER_HAS_DYNAMIC(h)) {\n\t\tif (DUK_HBUFFER_HAS_EXTERNAL(h)) {\n\t\t\tduk_hbuffer_external *g = (duk_hbuffer_external *) h;\n\t\t\tduk_fb_sprintf(fb, \"buffer:external:%p:%ld\",\n\t\t\t               (void *) DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(NULL, g),\n\t\t\t               (long) DUK_HBUFFER_EXTERNAL_GET_SIZE(g));\n\t\t} else {\n\t\t\tduk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h;\n\t\t\tduk_fb_sprintf(fb, \"buffer:dynamic:%p:%ld\",\n\t\t\t               (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(NULL, g),\n\t\t\t               (long) DUK_HBUFFER_DYNAMIC_GET_SIZE(g));\n\t\t}\n\t} else {\n\t\tduk_fb_sprintf(fb, \"buffer:fixed:%ld\", (long) DUK_HBUFFER_GET_SIZE(h));\n\t}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_fb_sprintf(fb, \"/%lu\", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(&h->hdr));\n#endif\n\n\tif (st->hexdump) {\n\t\tduk_fb_sprintf(fb, \"=[\");\n\t\tn = DUK_HBUFFER_GET_SIZE(h);\n\t\tp = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(NULL, h);\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) p[i]);\n\t\t}\n\t\tduk_fb_sprintf(fb, \"]\");\n\t}\n}\n\nDUK_LOCAL void duk__print_heaphdr(duk__dprint_state *st, duk_heaphdr *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING:\n\t\tduk__print_hstring(st, (duk_hstring *) h, 1);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tduk__print_hobject(st, (duk_hobject *) h);\n\t\tbreak;\n\tcase DUK_HTYPE_BUFFER:\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) h);\n\t\tbreak;\n\tdefault:\n\t\tduk_fb_sprintf(fb, \"[unknown htype %ld]\", (long) DUK_HEAPHDR_GET_TYPE(h));\n\t\tbreak;\n\t}\n}\n\nDUK_LOCAL void duk__print_tval(duk__dprint_state *st, duk_tval *tv) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\t/* depth check is done when printing an actual type */\n\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"(%p)\", (void *) tv);\n\t}\n\n\tif (!tv) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tif (st->binary) {\n\t\tduk_size_t i;\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET);\n\t\tfor (i = 0; i < (duk_size_t) sizeof(*tv); i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) ((duk_uint8_t *)tv)[i]);\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET);\n\t}\n\n\tif (st->heavy) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LANGLE);\n\t}\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\tduk_fb_put_cstring(fb, \"undefined\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_UNUSED: {\n\t\tduk_fb_put_cstring(fb, \"unused\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tduk_fb_put_cstring(fb, \"null\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tduk_fb_put_cstring(fb, DUK_TVAL_GET_BOOLEAN(tv) ? \"true\" : \"false\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\t/* Note: string is a terminal heap object, so no depth check here */\n\t\tduk__print_hstring(st, DUK_TVAL_GET_STRING(tv), 1);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk__print_hobject(st, DUK_TVAL_GET_OBJECT(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\tduk__print_hbuffer(st, DUK_TVAL_GET_BUFFER(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tduk_fb_sprintf(fb, \"pointer:%p\", (void *) DUK_TVAL_GET_POINTER(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tduk_c_function func;\n\t\tduk_small_uint_t lf_flags;\n\n\t\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);\n\t\tduk_fb_sprintf(fb, \"lightfunc:\");\n\t\tduk_fb_put_funcptr(fb, (duk_uint8_t *) &func, sizeof(func));\n\t\tduk_fb_sprintf(fb, \":%04lx\", (long) lf_flags);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tduk_fb_sprintf(fb, \"%.18g_F\", (double) DUK_TVAL_GET_NUMBER(tv));\n\t\tbreak;\n#endif\n\tdefault: {\n\t\t/* IEEE double is approximately 16 decimal digits; print a couple extra */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tduk_fb_sprintf(fb, \"%.18g\", (double) DUK_TVAL_GET_NUMBER(tv));\n\t\tbreak;\n\t}\n\t}\n\tif (st->heavy) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RANGLE);\n\t}\n}\n\nDUK_LOCAL void duk__print_instr(duk__dprint_state *st, duk_instr_t ins) {\n\tduk_fixedbuffer *fb = st->fb;\n\tduk_small_int_t op;\n\tconst char *op_name;\n\n\top = (duk_small_int_t) DUK_DEC_OP(ins);\n\top_name = duk__bc_optab[op];\n\n\t/* XXX: option to fix opcode length so it lines up nicely */\n\n\tif (op == DUK_OP_JUMP) {\n\t\tduk_int_t diff1 = (duk_int_t) (DUK_DEC_ABC(ins) - DUK_BC_JUMP_BIAS);  /* from next pc */\n\t\tduk_int_t diff2 = diff1 + 1;                                          /* from curr pc */\n\n\t\tduk_fb_sprintf(fb, \"%s %ld (to pc%c%ld)\",\n\t\t               (const char *) op_name, (long) diff1,\n\t\t               (int) (diff2 >= 0 ? '+' : '-'),  /* char format: use int */\n\t\t               (long) (diff2 >= 0 ? diff2 : -diff2));\n\t} else {\n\t\tduk_fb_sprintf(fb, \"%s %ld, %ld, %ld\",\n\t\t               (const char *) op_name, (long) DUK_DEC_A(ins),\n\t\t               (long) DUK_DEC_B(ins), (long) DUK_DEC_C(ins));\n\t}\n}\n\nDUK_LOCAL void duk__print_opcode(duk__dprint_state *st, duk_small_int_t opcode) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (opcode < DUK_BC_OP_MIN || opcode > DUK_BC_OP_MAX) {\n\t\tduk_fb_sprintf(fb, \"?(%ld)\", (long) opcode);\n\t} else {\n\t\tduk_fb_sprintf(fb, \"%s\", (const char *) duk__bc_optab[opcode]);\n\t}\n}\n\nDUK_LOCAL void duk__print_catcher(duk__dprint_state *st, duk_catcher *cat) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tif (!cat) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tduk_fb_sprintf(fb, \"[catcher ptr=%p parent=%p varname=%p pc_base=%p, idx_base=%ld, flags=0x%08lx]\",\n\t               (void *) cat,\n\t               (void *) cat->parent, (void *) cat->h_varname, (void *) cat->pc_base,\n\t\t       (long) cat->idx_base, (unsigned long) cat->flags);\n}\n\n\nDUK_LOCAL void duk__print_activation(duk__dprint_state *st, duk_activation *act) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tif (!act) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\t/* prev_caller: conditional, omitted on purpose, it's rarely used. */\n\t/* prev_line: conditional, omitted on purpose (but would be nice). */\n\tduk_fb_sprintf(fb, \"[activation ptr=%p tv_func=<omit> func=%p parent=%p var_env=%p lex_env=%p cat=%p curr_pc=%p bottom_byteoff=%ld retval_byteoff=%ld reserve_byteoff=%ld flags=%ld]\",\n\t               (void *) act,\n\t               (void *) act->func, (void *) act->parent, (void *) act->var_env,\n\t\t       (void *) act->lex_env, (void *) act->cat, (void *) act->curr_pc,\n\t\t       (long) act->bottom_byteoff, (long) act->retval_byteoff, (long) act->reserve_byteoff,\n\t\t       (long) act->flags);\n}\n\nDUK_INTERNAL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const char *format, va_list ap) {\n\tduk_fixedbuffer fb;\n\tconst char *p = format;\n\tconst char *p_end = p + DUK_STRLEN(format);\n\tduk_int_t retval;\n\n\tduk_memzero(&fb, sizeof(fb));\n\tfb.buffer = (duk_uint8_t *) str;\n\tfb.length = size;\n\tfb.offset = 0;\n\tfb.truncated = 0;\n\n\twhile (p < p_end) {\n\t\tchar ch = *p++;\n\t\tconst char *p_begfmt = NULL;\n\t\tduk_bool_t got_exclamation = 0;\n\t\tduk_bool_t got_long = 0;  /* %lf, %ld etc */\n\t\tduk__dprint_state st;\n\n\t\tif (ch != DUK_ASC_PERCENT) {\n\t\t\tduk_fb_put_byte(&fb, (duk_uint8_t) ch);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/*\n\t\t *  Format tag parsing.  Since we don't understand all the\n\t\t *  possible format tags allowed, we just scan for a terminating\n\t\t *  specifier and keep track of relevant modifiers that we do\n\t\t *  understand.  See man 3 printf.\n\t\t */\n\n\t\tduk_memzero(&st, sizeof(st));\n\t\tst.fb = &fb;\n\t\tst.depth = 0;\n\t\tst.depth_limit = 1;\n\t\tst.loop_stack_index = 0;\n\t\tst.loop_stack_limit = DUK__LOOP_STACK_DEPTH;\n\n\t\tp_begfmt = p - 1;\n\t\twhile (p < p_end) {\n\t\t\tch = *p++;\n\n\t\t\tif (ch == DUK_ASC_STAR) {\n\t\t\t\t/* unsupported: would consume multiple args */\n\t\t\t\tgoto format_error;\n\t\t\t} else if (ch == DUK_ASC_PERCENT) {\n\t\t\t\tduk_fb_put_byte(&fb, (duk_uint8_t) DUK_ASC_PERCENT);\n\t\t\t\tbreak;\n\t\t\t} else if (ch == DUK_ASC_EXCLAMATION) {\n\t\t\t\tgot_exclamation = 1;\n\t\t\t} else if (!got_exclamation && ch == DUK_ASC_LC_L) {\n\t\t\t\tgot_long = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_D) {\n\t\t\t\tst.depth_limit = DUK__DEEP_DEPTH_LIMIT;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_P) {\n\t\t\t\tst.follow_proto = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_I) {\n\t\t\t\tst.internal = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_X) {\n\t\t\t\tst.hexdump = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_H) {\n\t\t\t\tst.heavy = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_ATSIGN) {\n\t\t\t\tst.pointer = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_HASH) {\n\t\t\t\tst.binary = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_T) {\n\t\t\t\tduk_tval *t = va_arg(ap, duk_tval *);\n\t\t\t\tif (st.pointer && !st.heavy) {\n\t\t\t\t\tduk_fb_sprintf(&fb, \"(%p)\", (void *) t);\n\t\t\t\t}\n\t\t\t\tduk__print_tval(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_O) {\n\t\t\t\tduk_heaphdr *t = va_arg(ap, duk_heaphdr *);\n\t\t\t\tif (st.pointer && !st.heavy) {\n\t\t\t\t\tduk_fb_sprintf(&fb, \"(%p)\", (void *) t);\n\t\t\t\t}\n\t\t\t\tduk__print_heaphdr(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_I) {\n\t\t\t\tduk_instr_t t = va_arg(ap, duk_instr_t);\n\t\t\t\tduk__print_instr(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_X) {\n\t\t\t\tlong t = va_arg(ap, long);\n\t\t\t\tduk__print_opcode(&st, (duk_small_int_t) t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_C) {\n\t\t\t\tduk_catcher *t = va_arg(ap, duk_catcher *);\n\t\t\t\tduk__print_catcher(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_A) {\n\t\t\t\tduk_activation *t = va_arg(ap, duk_activation *);\n\t\t\t\tduk__print_activation(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (!got_exclamation && strchr(DUK__ALLOWED_STANDARD_SPECIFIERS, (int) ch)) {\n\t\t\t\tchar fmtbuf[DUK__MAX_FORMAT_TAG_LENGTH];\n\t\t\t\tduk_size_t fmtlen;\n\n\t\t\t\tDUK_ASSERT(p >= p_begfmt);\n\t\t\t\tfmtlen = (duk_size_t) (p - p_begfmt);\n\t\t\t\tif (fmtlen >= sizeof(fmtbuf)) {\n\t\t\t\t\t/* format is too large, abort */\n\t\t\t\t\tgoto format_error;\n\t\t\t\t}\n\t\t\t\tduk_memzero(fmtbuf, sizeof(fmtbuf));\n\t\t\t\tduk_memcpy(fmtbuf, p_begfmt, fmtlen);\n\n\t\t\t\t/* assume exactly 1 arg, which is why '*' is forbidden; arg size still\n\t\t\t\t * depends on type though.\n\t\t\t\t */\n\n\t\t\t\tif (ch == DUK_ASC_LC_F || ch == DUK_ASC_LC_G || ch == DUK_ASC_LC_E) {\n\t\t\t\t\t/* %f and %lf both consume a 'long' */\n\t\t\t\t\tdouble arg = va_arg(ap, double);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_D && got_long) {\n\t\t\t\t\t/* %ld */\n\t\t\t\t\tlong arg = va_arg(ap, long);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_D) {\n\t\t\t\t\t/* %d; only 16 bits are guaranteed */\n\t\t\t\t\tint arg = va_arg(ap, int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_U && got_long) {\n\t\t\t\t\t/* %lu */\n\t\t\t\t\tunsigned long arg = va_arg(ap, unsigned long);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_U) {\n\t\t\t\t\t/* %u; only 16 bits are guaranteed */\n\t\t\t\t\tunsigned int arg = va_arg(ap, unsigned int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_X && got_long) {\n\t\t\t\t\t/* %lx */\n\t\t\t\t\tunsigned long arg = va_arg(ap, unsigned long);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_X) {\n\t\t\t\t\t/* %x; only 16 bits are guaranteed */\n\t\t\t\t\tunsigned int arg = va_arg(ap, unsigned int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_S) {\n\t\t\t\t\t/* %s */\n\t\t\t\t\tconst char *arg = va_arg(ap, const char *);\n\t\t\t\t\tif (arg == NULL) {\n\t\t\t\t\t\t/* '%s' and NULL is not portable, so special case\n\t\t\t\t\t\t * it for debug printing.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk_fb_sprintf(&fb, \"NULL\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t\t}\n\t\t\t\t} else if (ch == DUK_ASC_LC_P) {\n\t\t\t\t\t/* %p */\n\t\t\t\t\tvoid *arg = va_arg(ap, void *);\n\t\t\t\t\tif (arg == NULL) {\n\t\t\t\t\t\t/* '%p' and NULL is portable, but special case it\n\t\t\t\t\t\t * anyway to get a standard NULL marker in logs.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk_fb_sprintf(&fb, \"NULL\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t\t}\n\t\t\t\t} else if (ch == DUK_ASC_LC_C) {\n\t\t\t\t\t/* '%c', passed concretely as int */\n\t\t\t\t\tint arg = va_arg(ap, int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else {\n\t\t\t\t\t/* Should not happen. */\n\t\t\t\t\tduk_fb_sprintf(&fb, \"INVALID-FORMAT(%s)\", (const char *) fmtbuf);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t/* ignore */\n\t\t\t}\n\t\t}\n\t}\n\tgoto done;\n\n format_error:\n\tduk_fb_put_cstring(&fb, \"FMTERR\");\n\t/* fall through */\n\n done:\n\tretval = (duk_int_t) fb.offset;\n\tduk_fb_put_byte(&fb, (duk_uint8_t) 0);\n\n\t/* return total chars written excluding terminator */\n\treturn retval;\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL duk_int_t duk_debug_snprintf(char *str, duk_size_t size, const char *format, ...) {\n\tduk_int_t retval;\n\tva_list ap;\n\tva_start(ap, format);\n\tretval = duk_debug_vsnprintf(str, size, format, ap);\n\tva_end(ap);\n\treturn retval;\n}\n#endif\n\n/* Formatting function pointers is tricky: there is no standard pointer for\n * function pointers and the size of a function pointer may depend on the\n * specific pointer type.  This helper formats a function pointer based on\n * its memory layout to get something useful on most platforms.\n */\nDUK_INTERNAL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_uint8_t *fptr, duk_size_t fptr_size) {\n\tduk_size_t i;\n\tduk_uint8_t *p = (duk_uint8_t *) buf;\n\tduk_uint8_t *p_end = (duk_uint8_t *) (buf + buf_size - 1);\n\n\tDUK_ASSERT(buf != NULL);\n\tduk_memzero(buf, buf_size);\n\n\tfor (i = 0; i < fptr_size; i++) {\n\t\tduk_int_t left = (duk_int_t) (p_end - p);\n\t\tduk_uint8_t ch;\n\t\tif (left <= 0) {\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Quite approximate but should be useful for little and big endian. */\n#if defined(DUK_USE_INTEGER_BE)\n\t\tch = fptr[i];\n#else\n\t\tch = fptr[fptr_size - 1 - i];\n#endif\n\t\tp += DUK_SNPRINTF((char *) p, (duk_size_t) left, \"%02lx\", (unsigned long) ch);\n\t}\n}\n\n#endif  /* DUK_USE_DEBUG */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_debugger.c",
    "content": "/*\n *  Duktape debugger\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\n/*\n *  Assert helpers\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n#define DUK__DBG_TPORT_ENTER() do { \\\n\t\tDUK_ASSERT(heap->dbg_calling_transport == 0); \\\n\t\theap->dbg_calling_transport = 1; \\\n\t} while (0)\n#define DUK__DBG_TPORT_EXIT() do { \\\n\t\tDUK_ASSERT(heap->dbg_calling_transport == 1); \\\n\t\theap->dbg_calling_transport = 0; \\\n\t} while (0)\n#else\n#define DUK__DBG_TPORT_ENTER() do {} while (0)\n#define DUK__DBG_TPORT_EXIT() do {} while (0)\n#endif\n\n/*\n *  Helper structs\n */\n\ntypedef union {\n\tvoid *p;\n\tduk_uint_t b[1];\n\t/* Use b[] to access the size of the union, which is strictly not\n\t * correct.  Can't use fixed size unless there's feature detection\n\t * for pointer byte size.\n\t */\n} duk__ptr_union;\n\n/*\n *  Detach handling\n */\n\n#define DUK__SET_CONN_BROKEN(thr,reason) do { \\\n\t\t/* For now shared handler is fine. */ \\\n\t\tduk__debug_do_detach1((thr)->heap, (reason)); \\\n\t} while (0)\n\nDUK_LOCAL void duk__debug_do_detach1(duk_heap *heap, duk_int_t reason) {\n\t/* Can be called multiple times with no harm.  Mark the transport\n\t * bad (dbg_read_cb == NULL) and clear state except for the detached\n\t * callback and the udata field.  The detached callback is delayed\n\t * to the message loop so that it can be called between messages;\n\t * this avoids corner cases related to immediate debugger reattach\n\t * inside the detached callback.\n\t */\n\n\tif (heap->dbg_detaching) {\n\t\tDUK_D(DUK_DPRINT(\"debugger already detaching, ignore detach1\"));\n\t\treturn;\n\t}\n\n\tDUK_D(DUK_DPRINT(\"debugger transport detaching, marking transport broken\"));\n\n\theap->dbg_detaching = 1;  /* prevent multiple in-progress detaches */\n\n\tif (heap->dbg_write_cb != NULL) {\n\t\tduk_hthread *thr;\n\n\t\tthr = heap->heap_thread;\n\t\tDUK_ASSERT(thr != NULL);\n\n\t\tduk_debug_write_notify(thr, DUK_DBG_CMD_DETACHING);\n\t\tduk_debug_write_int(thr, reason);\n\t\tduk_debug_write_eom(thr);\n\t}\n\n\theap->dbg_read_cb = NULL;\n\theap->dbg_write_cb = NULL;\n\theap->dbg_peek_cb = NULL;\n\theap->dbg_read_flush_cb = NULL;\n\theap->dbg_write_flush_cb = NULL;\n\theap->dbg_request_cb = NULL;\n\t/* heap->dbg_detached_cb: keep */\n\t/* heap->dbg_udata: keep */\n\t/* heap->dbg_processing: keep on purpose to avoid debugger re-entry in detaching state */\n\theap->dbg_state_dirty = 0;\n\theap->dbg_force_restart = 0;\n\theap->dbg_pause_flags = 0;\n\theap->dbg_pause_act = NULL;\n\theap->dbg_pause_startline = 0;\n\theap->dbg_have_next_byte = 0;\n\tduk_debug_clear_paused(heap);  /* XXX: some overlap with field inits above */\n\theap->dbg_state_dirty = 0;     /* XXX: clear_paused sets dirty; rework? */\n\n\t/* Ensure there are no stale active breakpoint pointers.\n\t * Breakpoint list is currently kept - we could empty it\n\t * here but we'd need to handle refcounts correctly, and\n\t * we'd need a 'thr' reference for that.\n\t *\n\t * XXX: clear breakpoint on either attach or detach?\n\t */\n\theap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;\n}\n\nDUK_LOCAL void duk__debug_do_detach2(duk_heap *heap) {\n\tduk_debug_detached_function detached_cb;\n\tvoid *detached_udata;\n\tduk_hthread *thr;\n\n\tthr = heap->heap_thread;\n\tif (thr == NULL) {\n\t\tDUK_ASSERT(heap->dbg_detached_cb == NULL);\n\t\treturn;\n\t}\n\n\t/* Safe to call multiple times. */\n\n\tdetached_cb = heap->dbg_detached_cb;\n\tdetached_udata = heap->dbg_udata;\n\theap->dbg_detached_cb = NULL;\n\theap->dbg_udata = NULL;\n\n\tif (detached_cb) {\n\t\t/* Careful here: state must be wiped before the call\n\t\t * so that we can cleanly handle a re-attach from\n\t\t * inside the callback.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"detached during message loop, delayed call to detached_cb\"));\n\t\tdetached_cb(thr, detached_udata);\n\t}\n\n\theap->dbg_detaching = 0;\n}\n\nDUK_INTERNAL void duk_debug_do_detach(duk_heap *heap) {\n\tduk__debug_do_detach1(heap, 0);\n\tduk__debug_do_detach2(heap);\n}\n\n/* Called on a read/write error: NULL all callbacks except the detached\n * callback so that we never accidentally call them after a read/write\n * error has been indicated.  This is especially important for the transport\n * I/O callbacks to fulfill guaranteed callback semantics.\n */\nDUK_LOCAL void duk__debug_null_most_callbacks(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\n\theap = thr->heap;\n\tDUK_D(DUK_DPRINT(\"transport read/write error, NULL all callbacks expected detached\"));\n\theap->dbg_read_cb = NULL;\n\theap->dbg_write_cb = NULL;  /* this is especially critical to avoid another write call in detach1() */\n\theap->dbg_peek_cb = NULL;\n\theap->dbg_read_flush_cb = NULL;\n\theap->dbg_write_flush_cb = NULL;\n\theap->dbg_request_cb = NULL;\n\t/* keep heap->dbg_detached_cb */\n}\n\n/*\n *  Pause handling\n */\n\nDUK_LOCAL void duk__debug_set_pause_state(duk_hthread *thr, duk_heap *heap, duk_small_uint_t pause_flags) {\n\tduk_uint_fast32_t line;\n\n\tline = duk_debug_curr_line(thr);\n\tif (line == 0) {\n\t\t/* No line info for current function. */\n\t\tduk_small_uint_t updated_flags;\n\n\t\tupdated_flags = pause_flags & ~(DUK_PAUSE_FLAG_LINE_CHANGE);\n\t\tDUK_D(DUK_DPRINT(\"no line info for current activation, disable line-based pause flags: 0x%08lx -> 0x%08lx\",\n\t\t                 (long) pause_flags, (long) updated_flags));\n\t\tpause_flags = updated_flags;\n\t}\n\n\theap->dbg_pause_flags = pause_flags;\n\theap->dbg_pause_act = thr->callstack_curr;\n\theap->dbg_pause_startline = (duk_uint32_t) line;\n\theap->dbg_state_dirty = 1;\n\n\tDUK_D(DUK_DPRINT(\"set state for automatic pause triggers, flags=0x%08lx, act=%p, startline=%ld\",\n\t                 (long) heap->dbg_pause_flags, (void *) heap->dbg_pause_act,\n\t                 (long) heap->dbg_pause_startline));\n}\n\n/*\n *  Debug connection peek and flush primitives\n */\n\nDUK_INTERNAL duk_bool_t duk_debug_read_peek(duk_hthread *thr) {\n\tduk_heap *heap;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to peek in detached state, return zero (= no data)\"));\n\t\treturn 0;\n\t}\n\tif (heap->dbg_peek_cb == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"no peek callback, return zero (= no data)\"));\n\t\treturn 0;\n\t}\n\n\tDUK__DBG_TPORT_ENTER();\n\tret = (duk_bool_t) (heap->dbg_peek_cb(heap->dbg_udata) > 0);\n\tDUK__DBG_TPORT_EXIT();\n\treturn ret;\n}\n\nDUK_INTERNAL void duk_debug_read_flush(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to read flush in detached state, ignore\"));\n\t\treturn;\n\t}\n\tif (heap->dbg_read_flush_cb == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"no read flush callback, ignore\"));\n\t\treturn;\n\t}\n\n\tDUK__DBG_TPORT_ENTER();\n\theap->dbg_read_flush_cb(heap->dbg_udata);\n\tDUK__DBG_TPORT_EXIT();\n}\n\nDUK_INTERNAL void duk_debug_write_flush(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to write flush in detached state, ignore\"));\n\t\treturn;\n\t}\n\tif (heap->dbg_write_flush_cb == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"no write flush callback, ignore\"));\n\t\treturn;\n\t}\n\n\tDUK__DBG_TPORT_ENTER();\n\theap->dbg_write_flush_cb(heap->dbg_udata);\n\tDUK__DBG_TPORT_EXIT();\n}\n\n/*\n *  Debug connection skip primitives\n */\n\n/* Skip fully. */\nDUK_INTERNAL void duk_debug_skip_bytes(duk_hthread *thr, duk_size_t length) {\n\tduk_uint8_t dummy[64];\n\tduk_size_t now;\n\n\tDUK_ASSERT(thr != NULL);\n\n\twhile (length > 0) {\n\t\tnow = (length > sizeof(dummy) ? sizeof(dummy) : length);\n\t\tduk_debug_read_bytes(thr, dummy, now);\n\t\tlength -= now;\n\t}\n}\n\nDUK_INTERNAL void duk_debug_skip_byte(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\t(void) duk_debug_read_byte(thr);\n}\n\n/*\n *  Debug connection read primitives\n */\n\n/* Peek ahead in the stream one byte. */\nDUK_INTERNAL uint8_t duk_debug_peek_byte(duk_hthread *thr) {\n\t/* It is important not to call this if the last byte read was an EOM.\n\t * Reading ahead in this scenario would cause unnecessary blocking if\n\t * another message is not available.\n\t */\n\n\tduk_uint8_t x;\n\n\tx = duk_debug_read_byte(thr);\n\tthr->heap->dbg_have_next_byte = 1;\n\tthr->heap->dbg_next_byte = x;\n\treturn x;\n}\n\n/* Read fully. */\nDUK_INTERNAL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_size_t length) {\n\tduk_heap *heap;\n\tduk_uint8_t *p;\n\tduk_size_t left;\n\tduk_size_t got;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(data != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to read %ld bytes in detached state, return zero data\", (long) length));\n\t\tgoto fail;\n\t}\n\n\t/* NOTE: length may be zero */\n\tp = data;\n\tif (length >= 1 && heap->dbg_have_next_byte) {\n\t\theap->dbg_have_next_byte = 0;\n\t\t*p++ = heap->dbg_next_byte;\n\t}\n\tfor (;;) {\n\t\tleft = (duk_size_t) ((data + length) - p);\n\t\tif (left == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tDUK_ASSERT(heap->dbg_read_cb != NULL);\n\t\tDUK_ASSERT(left >= 1);\n#if defined(DUK_USE_DEBUGGER_TRANSPORT_TORTURE)\n\t\tleft = 1;\n#endif\n\t\tDUK__DBG_TPORT_ENTER();\n\t\tgot = heap->dbg_read_cb(heap->dbg_udata, (char *) p, left);\n\t\tDUK__DBG_TPORT_EXIT();\n\n\t\tif (got == 0 || got > left) {\n\t\t\tDUK_D(DUK_DPRINT(\"connection error during read, return zero data\"));\n\t\t\tduk__debug_null_most_callbacks(thr);  /* avoid calling write callback in detach1() */\n\t\t\tDUK__SET_CONN_BROKEN(thr, 1);\n\t\t\tgoto fail;\n\t\t}\n\t\tp += got;\n\t}\n\treturn;\n\n fail:\n\tduk_memzero((void *) data, (size_t) length);\n}\n\nDUK_INTERNAL duk_uint8_t duk_debug_read_byte(duk_hthread *thr) {\n\tduk_uint8_t x;\n\n\tx = 0;  /* just in case callback is broken and won't write 'x' */\n\tduk_debug_read_bytes(thr, &x, 1);\n\treturn x;\n}\n\nDUK_LOCAL duk_uint32_t duk__debug_read_uint32_raw(duk_hthread *thr) {\n\tduk_uint8_t buf[4];\n\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_read_bytes(thr, buf, 4);\n\treturn ((duk_uint32_t) buf[0] << 24) |\n\t       ((duk_uint32_t) buf[1] << 16) |\n\t       ((duk_uint32_t) buf[2] << 8) |\n\t       (duk_uint32_t) buf[3];\n}\n\nDUK_LOCAL duk_int32_t duk__debug_read_int32_raw(duk_hthread *thr) {\n\treturn (duk_int32_t) duk__debug_read_uint32_raw(thr);\n}\n\nDUK_LOCAL duk_uint16_t duk__debug_read_uint16_raw(duk_hthread *thr) {\n\tduk_uint8_t buf[2];\n\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_read_bytes(thr, buf, 2);\n\treturn ((duk_uint16_t) buf[0] << 8) |\n\t       (duk_uint16_t) buf[1];\n}\n\nDUK_INTERNAL duk_int32_t duk_debug_read_int(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\tduk_small_uint_t t;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x >= 0xc0) {\n\t\tt = duk_debug_read_byte(thr);\n\t\treturn (duk_int32_t) (((x - 0xc0) << 8) + t);\n\t} else if (x >= 0x80) {\n\t\treturn (duk_int32_t) (x - 0x80);\n\t} else if (x == DUK_DBG_IB_INT4) {\n\t\treturn (duk_int32_t) duk__debug_read_uint32_raw(thr);\n\t}\n\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode int\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn 0;\n}\n\nDUK_LOCAL duk_hstring *duk__debug_read_hstring_raw(duk_hthread *thr, duk_uint32_t len) {\n\tduk_uint8_t buf[31];\n\tduk_uint8_t *p;\n\n\tif (len <= sizeof(buf)) {\n\t\tduk_debug_read_bytes(thr, buf, (duk_size_t) len);\n\t\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) len);\n\t} else {\n\t\tp = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len);  /* zero for paranoia */\n\t\tDUK_ASSERT(p != NULL);\n\t\tduk_debug_read_bytes(thr, p, (duk_size_t) len);\n\t\t(void) duk_buffer_to_string(thr, -1);  /* Safety relies on debug client, which is OK. */\n\t}\n\n\treturn duk_require_hstring(thr, -1);\n}\n\nDUK_INTERNAL duk_hstring *duk_debug_read_hstring(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\tduk_uint32_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x >= 0x60 && x <= 0x7f) {\n\t\t/* For short strings, use a fixed temp buffer. */\n\t\tlen = (duk_uint32_t) (x - 0x60);\n\t} else if (x == DUK_DBG_IB_STR2) {\n\t\tlen = (duk_uint32_t) duk__debug_read_uint16_raw(thr);\n\t} else if (x == DUK_DBG_IB_STR4) {\n\t\tlen = (duk_uint32_t) duk__debug_read_uint32_raw(thr);\n\t} else {\n\t\tgoto fail;\n\t}\n\n\treturn duk__debug_read_hstring_raw(thr, len);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode int\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\tduk_push_hstring_empty(thr);  /* always push some string */\n\treturn duk_require_hstring(thr, -1);\n}\n\nDUK_LOCAL duk_hbuffer *duk__debug_read_hbuffer_raw(duk_hthread *thr, duk_uint32_t len) {\n\tduk_uint8_t *p;\n\n\tp = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len);  /* zero for paranoia */\n\tDUK_ASSERT(p != NULL);\n\tduk_debug_read_bytes(thr, p, (duk_size_t) len);\n\n\treturn duk_require_hbuffer(thr, -1);\n}\n\nDUK_LOCAL void *duk__debug_read_pointer_raw(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\tduk__ptr_union pu;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x != sizeof(pu)) {\n\t\tgoto fail;\n\t}\n\tduk_debug_read_bytes(thr, (duk_uint8_t *) &pu.p, sizeof(pu));\n#if defined(DUK_USE_INTEGER_LE)\n\tduk_byteswap_bytes((duk_uint8_t *) pu.b, sizeof(pu));\n#endif\n\treturn (void *) pu.p;\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode pointer\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn (void *) NULL;\n}\n\nDUK_LOCAL duk_double_t duk__debug_read_double_raw(duk_hthread *thr) {\n\tduk_double_union du;\n\n\tDUK_ASSERT(sizeof(du.uc) == 8);\n\tduk_debug_read_bytes(thr, (duk_uint8_t *) du.uc, sizeof(du.uc));\n\tDUK_DBLUNION_DOUBLE_NTOH(&du);\n\treturn du.d;\n}\n\n#if 0\nDUK_INTERNAL duk_heaphdr *duk_debug_read_heapptr(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x != DUK_DBG_IB_HEAPPTR) {\n\t\tgoto fail;\n\t}\n\n\treturn (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode heapptr\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn NULL;\n}\n#endif\n\nDUK_INTERNAL duk_heaphdr *duk_debug_read_any_ptr(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tswitch (x) {\n\tcase DUK_DBG_IB_OBJECT:\n\tcase DUK_DBG_IB_POINTER:\n\tcase DUK_DBG_IB_HEAPPTR:\n\t\t/* Accept any pointer-like value; for 'object' dvalue, read\n\t\t * and ignore the class number.\n\t\t */\n\t\tif (x == DUK_DBG_IB_OBJECT) {\n\t\t\tduk_debug_skip_byte(thr);\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tgoto fail;\n\t}\n\n\treturn (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode any pointer (object, pointer, heapptr)\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_tval *duk_debug_read_tval(duk_hthread *thr) {\n\tduk_uint8_t x;\n\tduk_uint_t t;\n\tduk_uint32_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\n\tif (x >= 0xc0) {\n\t\tt = (duk_uint_t) (x - 0xc0);\n\t\tt = (t << 8) + duk_debug_read_byte(thr);\n\t\tduk_push_uint(thr, (duk_uint_t) t);\n\t\tgoto return_ptr;\n\t}\n\tif (x >= 0x80) {\n\t\tduk_push_uint(thr, (duk_uint_t) (x - 0x80));\n\t\tgoto return_ptr;\n\t}\n\tif (x >= 0x60) {\n\t\tlen = (duk_uint32_t) (x - 0x60);\n\t\tduk__debug_read_hstring_raw(thr, len);\n\t\tgoto return_ptr;\n\t}\n\n\tswitch (x) {\n\tcase DUK_DBG_IB_INT4: {\n\t\tduk_int32_t i = duk__debug_read_int32_raw(thr);\n\t\tduk_push_i32(thr, i);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_STR4: {\n\t\tlen = duk__debug_read_uint32_raw(thr);\n\t\tduk__debug_read_hstring_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_STR2: {\n\t\tlen = duk__debug_read_uint16_raw(thr);\n\t\tduk__debug_read_hstring_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_BUF4: {\n\t\tlen = duk__debug_read_uint32_raw(thr);\n\t\tduk__debug_read_hbuffer_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_BUF2: {\n\t\tlen = duk__debug_read_uint16_raw(thr);\n\t\tduk__debug_read_hbuffer_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_UNDEFINED: {\n\t\tduk_push_undefined(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_NULL: {\n\t\tduk_push_null(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_TRUE: {\n\t\tduk_push_true(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_FALSE: {\n\t\tduk_push_false(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_NUMBER: {\n\t\tduk_double_t d;\n\t\td = duk__debug_read_double_raw(thr);\n\t\tduk_push_number(thr, d);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_OBJECT: {\n\t\tduk_heaphdr *h;\n\t\tduk_debug_skip_byte(thr);\n\t\th = (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\t\tduk_push_heapptr(thr, (void *) h);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_POINTER: {\n\t\tvoid *ptr;\n\t\tptr = duk__debug_read_pointer_raw(thr);\n\t\tduk_push_pointer(thr, ptr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_LIGHTFUNC: {\n\t\t/* XXX: Not needed for now, so not implemented.  Note that\n\t\t * function pointers may have different size/layout than\n\t\t * a void pointer.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"reading lightfunc values unimplemented\"));\n\t\tgoto fail;\n\t}\n\tcase DUK_DBG_IB_HEAPPTR: {\n\t\tduk_heaphdr *h;\n\t\th = (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\t\tduk_push_heapptr(thr, (void *) h);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_UNUSED:  /* unused: not accepted in inbound messages */\n\tdefault:\n\t\tgoto fail;\n\t}\n\n return_ptr:\n\treturn DUK_GET_TVAL_NEGIDX(thr, -1);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode tval\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn NULL;\n}\n\n/*\n *  Debug connection write primitives\n */\n\n/* Write fully. */\nDUK_INTERNAL void duk_debug_write_bytes(duk_hthread *thr, const duk_uint8_t *data, duk_size_t length) {\n\tduk_heap *heap;\n\tconst duk_uint8_t *p;\n\tduk_size_t left;\n\tduk_size_t got;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(length == 0 || data != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_write_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to write %ld bytes in detached state, ignore\", (long) length));\n\t\treturn;\n\t}\n\tif (length == 0) {\n\t\t/* Avoid doing an actual write callback with length == 0,\n\t\t * because that's reserved for a write flush.\n\t\t */\n\t\treturn;\n\t}\n\tDUK_ASSERT(data != NULL);\n\n\tp = data;\n\tfor (;;) {\n\t\tleft = (duk_size_t) ((data + length) - p);\n\t\tif (left == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tDUK_ASSERT(heap->dbg_write_cb != NULL);\n\t\tDUK_ASSERT(left >= 1);\n#if defined(DUK_USE_DEBUGGER_TRANSPORT_TORTURE)\n\t\tleft = 1;\n#endif\n\t\tDUK__DBG_TPORT_ENTER();\n\t\tgot = heap->dbg_write_cb(heap->dbg_udata, (const char *) p, left);\n\t\tDUK__DBG_TPORT_EXIT();\n\n\t\tif (got == 0 || got > left) {\n\t\t\tduk__debug_null_most_callbacks(thr);  /* avoid calling write callback in detach1() */\n\t\t\tDUK_D(DUK_DPRINT(\"connection error during write\"));\n\t\t\tDUK__SET_CONN_BROKEN(thr, 1);\n\t\t\treturn;\n\t\t}\n\t\tp += got;\n\t}\n}\n\nDUK_INTERNAL void duk_debug_write_byte(duk_hthread *thr, duk_uint8_t x) {\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &x, 1);\n}\n\nDUK_INTERNAL void duk_debug_write_unused(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_UNUSED);\n}\n\nDUK_INTERNAL void duk_debug_write_undefined(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_UNDEFINED);\n}\n\n#if defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL void duk_debug_write_null(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_NULL);\n}\n#endif\n\nDUK_INTERNAL void duk_debug_write_boolean(duk_hthread *thr, duk_uint_t val) {\n\tduk_debug_write_byte(thr, val ? DUK_DBG_IB_TRUE : DUK_DBG_IB_FALSE);\n}\n\n/* Write signed 32-bit integer. */\nDUK_INTERNAL void duk_debug_write_int(duk_hthread *thr, duk_int32_t x) {\n\tduk_uint8_t buf[5];\n\tduk_size_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tif (x >= 0 && x <= 0x3fL) {\n\t\tbuf[0] = (duk_uint8_t) (0x80 + x);\n\t\tlen = 1;\n\t} else if (x >= 0 && x <= 0x3fffL) {\n\t\tbuf[0] = (duk_uint8_t) (0xc0 + (x >> 8));\n\t\tbuf[1] = (duk_uint8_t) (x & 0xff);\n\t\tlen = 2;\n\t} else {\n\t\t/* Signed integers always map to 4 bytes now. */\n\t\tbuf[0] = (duk_uint8_t) DUK_DBG_IB_INT4;\n\t\tbuf[1] = (duk_uint8_t) ((x >> 24) & 0xff);\n\t\tbuf[2] = (duk_uint8_t) ((x >> 16) & 0xff);\n\t\tbuf[3] = (duk_uint8_t) ((x >> 8) & 0xff);\n\t\tbuf[4] = (duk_uint8_t) (x & 0xff);\n\t\tlen = 5;\n\t}\n\tduk_debug_write_bytes(thr, buf, len);\n}\n\n/* Write unsigned 32-bit integer. */\nDUK_INTERNAL void duk_debug_write_uint(duk_hthread *thr, duk_uint32_t x) {\n\t/* The debugger protocol doesn't support a plain integer encoding for\n\t * the full 32-bit unsigned range (only 32-bit signed).  For now,\n\t * unsigned 32-bit values simply written as signed ones.  This is not\n\t * a concrete issue except for 32-bit heaphdr fields.  Proper solutions\n\t * would be to (a) write such integers as IEEE doubles or (b) add an\n\t * unsigned 32-bit dvalue.\n\t */\n\tif (x >= 0x80000000UL) {\n\t\tDUK_D(DUK_DPRINT(\"writing unsigned integer 0x%08lx as signed integer\",\n\t\t                 (long) x));\n\t}\n\tduk_debug_write_int(thr, (duk_int32_t) x);\n}\n\nDUK_INTERNAL void duk_debug_write_strbuf(duk_hthread *thr, const char *data, duk_size_t length, duk_uint8_t marker_base) {\n\tduk_uint8_t buf[5];\n\tduk_size_t buflen;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(length == 0 || data != NULL);\n\n\tif (length <= 0x1fUL && marker_base == DUK_DBG_IB_STR4) {\n\t\t/* For strings, special form for short lengths. */\n\t\tbuf[0] = (duk_uint8_t) (0x60 + length);\n\t\tbuflen = 1;\n\t} else if (length <= 0xffffUL) {\n\t\tbuf[0] = (duk_uint8_t) (marker_base + 1);\n\t\tbuf[1] = (duk_uint8_t) (length >> 8);\n\t\tbuf[2] = (duk_uint8_t) (length & 0xff);\n\t\tbuflen = 3;\n\t} else {\n\t\tbuf[0] = (duk_uint8_t) marker_base;\n\t\tbuf[1] = (duk_uint8_t) (length >> 24);\n\t\tbuf[2] = (duk_uint8_t) ((length >> 16) & 0xff);\n\t\tbuf[3] = (duk_uint8_t) ((length >> 8) & 0xff);\n\t\tbuf[4] = (duk_uint8_t) (length & 0xff);\n\t\tbuflen = 5;\n\t}\n\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) buf, buflen);\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) data, length);\n}\n\nDUK_INTERNAL void duk_debug_write_string(duk_hthread *thr, const char *data, duk_size_t length) {\n\tduk_debug_write_strbuf(thr, data, length, DUK_DBG_IB_STR4);\n}\n\nDUK_INTERNAL void duk_debug_write_cstring(duk_hthread *thr, const char *data) {\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_write_string(thr,\n\t                       data,\n\t                       data ? DUK_STRLEN(data) : 0);\n}\n\nDUK_INTERNAL void duk_debug_write_hstring(duk_hthread *thr, duk_hstring *h) {\n\tDUK_ASSERT(thr != NULL);\n\n\t/* XXX: differentiate null pointer from empty string? */\n\tduk_debug_write_string(thr,\n\t                       (h != NULL ? (const char *) DUK_HSTRING_GET_DATA(h) : NULL),\n\t                       (h != NULL ? (duk_size_t) DUK_HSTRING_GET_BYTELEN(h) : 0));\n}\n\nDUK_LOCAL void duk__debug_write_hstring_safe_top(duk_hthread *thr) {\n\tduk_debug_write_hstring(thr, duk_safe_to_hstring(thr, -1));\n}\n\nDUK_INTERNAL void duk_debug_write_buffer(duk_hthread *thr, const char *data, duk_size_t length) {\n\tduk_debug_write_strbuf(thr, data, length, DUK_DBG_IB_BUF4);\n}\n\nDUK_INTERNAL void duk_debug_write_hbuffer(duk_hthread *thr, duk_hbuffer *h) {\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_write_buffer(thr,\n\t                       (h != NULL ? (const char *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h) : NULL),\n\t                       (h != NULL ? (duk_size_t) DUK_HBUFFER_GET_SIZE(h) : 0));\n}\n\nDUK_LOCAL void duk__debug_write_pointer_raw(duk_hthread *thr, void *ptr, duk_uint8_t ibyte) {\n\tduk_uint8_t buf[2];\n\tduk__ptr_union pu;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(sizeof(ptr) >= 1 && sizeof(ptr) <= 16);\n\t/* ptr may be NULL */\n\n\tbuf[0] = ibyte;\n\tbuf[1] = sizeof(pu);\n\tduk_debug_write_bytes(thr, buf, 2);\n\tpu.p = (void *) ptr;\n#if defined(DUK_USE_INTEGER_LE)\n\tduk_byteswap_bytes((duk_uint8_t *) pu.b, sizeof(pu));\n#endif\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &pu.p, (duk_size_t) sizeof(pu));\n}\n\nDUK_INTERNAL void duk_debug_write_pointer(duk_hthread *thr, void *ptr) {\n\tduk__debug_write_pointer_raw(thr, ptr, DUK_DBG_IB_POINTER);\n}\n\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP) || defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL void duk_debug_write_heapptr(duk_hthread *thr, duk_heaphdr *h) {\n\tduk__debug_write_pointer_raw(thr, (void *) h, DUK_DBG_IB_HEAPPTR);\n}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP || DUK_USE_DEBUGGER_INSPECT */\n\nDUK_INTERNAL void duk_debug_write_hobject(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint8_t buf[3];\n\tduk__ptr_union pu;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(sizeof(obj) >= 1 && sizeof(obj) <= 16);\n\tDUK_ASSERT(obj != NULL);\n\n\tbuf[0] = DUK_DBG_IB_OBJECT;\n\tbuf[1] = (duk_uint8_t) DUK_HOBJECT_GET_CLASS_NUMBER(obj);\n\tbuf[2] = sizeof(pu);\n\tduk_debug_write_bytes(thr, buf, 3);\n\tpu.p = (void *) obj;\n#if defined(DUK_USE_INTEGER_LE)\n\tduk_byteswap_bytes((duk_uint8_t *) pu.b, sizeof(pu));\n#endif\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &pu.p, (duk_size_t) sizeof(pu));\n}\n\nDUK_INTERNAL void duk_debug_write_tval(duk_hthread *thr, duk_tval *tv) {\n\tduk_c_function lf_func;\n\tduk_small_uint_t lf_flags;\n\tduk_uint8_t buf[4];\n\tduk_double_union du1;\n\tduk_double_union du2;\n\tduk_int32_t i32;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\t\tduk_debug_write_byte(thr, DUK_DBG_IB_UNDEFINED);\n\t\tbreak;\n\tcase DUK_TAG_UNUSED:\n\t\tduk_debug_write_byte(thr, DUK_DBG_IB_UNUSED);\n\t\tbreak;\n\tcase DUK_TAG_NULL:\n\t\tduk_debug_write_byte(thr, DUK_DBG_IB_NULL);\n\t\tbreak;\n\tcase DUK_TAG_BOOLEAN:\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv) == 0 ||\n\t\t           DUK_TVAL_GET_BOOLEAN(tv) == 1);\n\t\tduk_debug_write_boolean(thr, DUK_TVAL_GET_BOOLEAN(tv));\n\t\tbreak;\n\tcase DUK_TAG_POINTER:\n\t\tduk_debug_write_pointer(thr, (void *) DUK_TVAL_GET_POINTER(tv));\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\tDUK_TVAL_GET_LIGHTFUNC(tv, lf_func, lf_flags);\n\t\tbuf[0] = DUK_DBG_IB_LIGHTFUNC;\n\t\tbuf[1] = (duk_uint8_t) (lf_flags >> 8);\n\t\tbuf[2] = (duk_uint8_t) (lf_flags & 0xff);\n\t\tbuf[3] = sizeof(lf_func);\n\t\tduk_debug_write_bytes(thr, buf, 4);\n\t\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &lf_func, sizeof(lf_func));\n\t\tbreak;\n\tcase DUK_TAG_STRING:\n\t\tduk_debug_write_hstring(thr, DUK_TVAL_GET_STRING(tv));\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\tduk_debug_write_hobject(thr, DUK_TVAL_GET_OBJECT(tv));\n\t\tbreak;\n\tcase DUK_TAG_BUFFER:\n\t\tduk_debug_write_hbuffer(thr, DUK_TVAL_GET_BUFFER(tv));\n\t\tbreak;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* Numbers are normalized to big (network) endian.  We can\n\t\t * (but are not required) to use integer dvalues when there's\n\t\t * no loss of precision.\n\t\t *\n\t\t * XXX: share check with other code; this check is slow but\n\t\t * reliable and doesn't require careful exponent/mantissa\n\t\t * mask tricks as in the fastint downgrade code.\n\t\t */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tdu1.d = DUK_TVAL_GET_NUMBER(tv);\n\t\ti32 = (duk_int32_t) du1.d;\n\t\tdu2.d = (duk_double_t) i32;\n\n\t\tDUK_DD(DUK_DDPRINT(\"i32=%ld du1=%02x%02x%02x%02x%02x%02x%02x%02x \"\n\t\t                   \"du2=%02x%02x%02x%02x%02x%02x%02x%02x\",\n\t\t                   (long) i32,\n\t\t                   (unsigned int) du1.uc[0], (unsigned int) du1.uc[1],\n\t\t                   (unsigned int) du1.uc[2], (unsigned int) du1.uc[3],\n\t\t                   (unsigned int) du1.uc[4], (unsigned int) du1.uc[5],\n\t\t                   (unsigned int) du1.uc[6], (unsigned int) du1.uc[7],\n\t\t                   (unsigned int) du2.uc[0], (unsigned int) du2.uc[1],\n\t\t                   (unsigned int) du2.uc[2], (unsigned int) du2.uc[3],\n\t\t                   (unsigned int) du2.uc[4], (unsigned int) du2.uc[5],\n\t\t                   (unsigned int) du2.uc[6], (unsigned int) du2.uc[7]));\n\n\t\tif (duk_memcmp((const void *) du1.uc, (const void *) du2.uc, sizeof(du1.uc)) == 0) {\n\t\t\tduk_debug_write_int(thr, i32);\n\t\t} else {\n\t\t\tDUK_DBLUNION_DOUBLE_HTON(&du1);\n\t\t\tduk_debug_write_byte(thr, DUK_DBG_IB_NUMBER);\n\t\t\tduk_debug_write_bytes(thr, (const duk_uint8_t *) du1.uc, sizeof(du1.uc));\n\t\t}\n\t}\n}\n\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP)\n/* Variant for writing duk_tvals so that any heap allocated values are\n * written out as tagged heap pointers.\n */\nDUK_LOCAL void duk__debug_write_tval_heapptr(duk_hthread *thr, duk_tval *tv) {\n\tif (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tduk_debug_write_heapptr(thr, h);\n\t} else {\n\t\tduk_debug_write_tval(thr, tv);\n\t}\n}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP */\n\n/*\n *  Debug connection message write helpers\n */\n\n#if 0  /* unused */\nDUK_INTERNAL void duk_debug_write_request(duk_hthread *thr, duk_small_uint_t command) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_REQUEST);\n\tduk_debug_write_int(thr, command);\n}\n#endif\n\nDUK_INTERNAL void duk_debug_write_reply(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_REPLY);\n}\n\nDUK_INTERNAL void duk_debug_write_error_eom(duk_hthread *thr, duk_small_uint_t err_code, const char *msg) {\n\t/* Allow NULL 'msg' */\n\tduk_debug_write_byte(thr, DUK_DBG_IB_ERROR);\n\tduk_debug_write_int(thr, (duk_int32_t) err_code);\n\tduk_debug_write_cstring(thr, msg);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_INTERNAL void duk_debug_write_notify(duk_hthread *thr, duk_small_uint_t command) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_NOTIFY);\n\tduk_debug_write_int(thr, (duk_int32_t) command);\n}\n\nDUK_INTERNAL void duk_debug_write_eom(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_EOM);\n\n\t/* As an initial implementation, write flush after every EOM (and the\n\t * version identifier).  A better implementation would flush only when\n\t * Duktape is finished processing messages so that a flush only happens\n\t * after all outbound messages are finished on that occasion.\n\t */\n\tduk_debug_write_flush(thr);\n}\n\n/*\n *  Status message and helpers\n */\n\nDUK_INTERNAL duk_uint_fast32_t duk_debug_curr_line(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_uint_fast32_t line;\n\tduk_uint_fast32_t pc;\n\n\tact = thr->callstack_curr;\n\tif (act == NULL) {\n\t\treturn 0;\n\t}\n\n\t/* We're conceptually between two opcodes; act->pc indicates the next\n\t * instruction to be executed.  This is usually the correct pc/line to\n\t * indicate in Status.  (For the 'debugger' statement this now reports\n\t * the pc/line after the debugger statement because the debugger opcode\n\t * has already been executed.)\n\t */\n\n\tpc = duk_hthread_get_act_curr_pc(thr, act);\n\n\t/* XXX: this should be optimized to be a raw query and avoid valstack\n\t * operations if possible.\n\t */\n\tduk_push_tval(thr, &act->tv_func);\n\tline = duk_hobject_pc2line_query(thr, -1, pc);\n\tduk_pop(thr);\n\treturn line;\n}\n\nDUK_INTERNAL void duk_debug_send_status(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tduk_debug_write_notify(thr, DUK_DBG_CMD_STATUS);\n\tduk_debug_write_int(thr, (DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) ? 1 : 0));\n\n\tact = thr->callstack_curr;\n\tif (act == NULL) {\n\t\tduk_debug_write_undefined(thr);\n\t\tduk_debug_write_undefined(thr);\n\t\tduk_debug_write_int(thr, 0);\n\t\tduk_debug_write_int(thr, 0);\n\t} else {\n\t\tduk_push_tval(thr, &act->tv_func);\n\t\tduk_get_prop_literal(thr, -1, \"fileName\");\n\t\tduk__debug_write_hstring_safe_top(thr);\n\t\tduk_get_prop_literal(thr, -2, \"name\");\n\t\tduk__debug_write_hstring_safe_top(thr);\n\t\tduk_pop_3(thr);\n\t\t/* Report next pc/line to be executed. */\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) duk_debug_curr_line(thr));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) duk_hthread_get_act_curr_pc(thr, act));\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n\n#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)\nDUK_INTERNAL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal) {\n\t/*\n\t *  NFY <int: 5> <int: fatal> <str: msg> <str: filename> <int: linenumber> EOM\n\t */\n\n\tduk_activation *act;\n\tduk_uint32_t pc;\n\n\tDUK_ASSERT(thr->valstack_top > thr->valstack);  /* At least: ... [err] */\n\n\tduk_debug_write_notify(thr, DUK_DBG_CMD_THROW);\n\tduk_debug_write_int(thr, (duk_int32_t) fatal);\n\n\t/* Report thrown value to client coerced to string */\n\tduk_dup_top(thr);\n\tduk__debug_write_hstring_safe_top(thr);\n\tduk_pop(thr);\n\n\tif (duk_is_error(thr, -1)) {\n\t\t/* Error instance, use augmented error data directly */\n\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME);\n\t\tduk__debug_write_hstring_safe_top(thr);\n\t\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_LINE_NUMBER);\n\t\tduk_debug_write_uint(thr, duk_get_uint(thr, -1));\n\t\tduk_pop_2(thr);\n\t} else {\n\t\t/* For anything other than an Error instance, we calculate the\n\t\t * error location directly from the current activation if one\n\t\t * exists.\n\t\t */\n\t\tact = thr->callstack_curr;\n\t\tif (act != NULL) {\n\t\t\tduk_push_tval(thr, &act->tv_func);\n\t\t\tduk_get_prop_literal(thr, -1, \"fileName\");\n\t\t\tduk__debug_write_hstring_safe_top(thr);\n\t\t\tpc = (duk_uint32_t) duk_hthread_get_act_prev_pc(thr, act);\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) duk_hobject_pc2line_query(thr, -2, pc));\n\t\t\tduk_pop_2(thr);\n\t\t} else {\n\t\t\t/* Can happen if duk_throw() is called on an empty\n\t\t\t * callstack.\n\t\t\t */\n\t\t\tduk_debug_write_cstring(thr, \"\");\n\t\t\tduk_debug_write_uint(thr, 0);\n\t\t}\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n#endif  /* DUK_USE_DEBUGGER_THROW_NOTIFY */\n\n/*\n *  Debug message processing\n */\n\n/* Skip dvalue. */\nDUK_LOCAL duk_bool_t duk__debug_skip_dvalue(duk_hthread *thr) {\n\tduk_uint8_t x;\n\tduk_uint32_t len;\n\n\tx = duk_debug_read_byte(thr);\n\n\tif (x >= 0xc0) {\n\t\tduk_debug_skip_byte(thr);\n\t\treturn 0;\n\t}\n\tif (x >= 0x80) {\n\t\treturn 0;\n\t}\n\tif (x >= 0x60) {\n\t\tduk_debug_skip_bytes(thr, (duk_size_t) (x - 0x60));\n\t\treturn 0;\n\t}\n\tswitch(x) {\n\tcase DUK_DBG_IB_EOM:\n\t\treturn 1;  /* Return 1: got EOM */\n\tcase DUK_DBG_IB_REQUEST:\n\tcase DUK_DBG_IB_REPLY:\n\tcase DUK_DBG_IB_ERROR:\n\tcase DUK_DBG_IB_NOTIFY:\n\t\tbreak;\n\tcase DUK_DBG_IB_INT4:\n\t\t(void) duk__debug_read_uint32_raw(thr);\n\t\tbreak;\n\tcase DUK_DBG_IB_STR4:\n\tcase DUK_DBG_IB_BUF4:\n\t\tlen = duk__debug_read_uint32_raw(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_STR2:\n\tcase DUK_DBG_IB_BUF2:\n\t\tlen = duk__debug_read_uint16_raw(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_UNUSED:\n\tcase DUK_DBG_IB_UNDEFINED:\n\tcase DUK_DBG_IB_NULL:\n\tcase DUK_DBG_IB_TRUE:\n\tcase DUK_DBG_IB_FALSE:\n\t\tbreak;\n\tcase DUK_DBG_IB_NUMBER:\n\t\tduk_debug_skip_bytes(thr, 8);\n\t\tbreak;\n\tcase DUK_DBG_IB_OBJECT:\n\t\tduk_debug_skip_byte(thr);\n\t\tlen = duk_debug_read_byte(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_POINTER:\n\tcase DUK_DBG_IB_HEAPPTR:\n\t\tlen = duk_debug_read_byte(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_LIGHTFUNC:\n\t\tduk_debug_skip_bytes(thr, 2);\n\t\tlen = duk_debug_read_byte(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tdefault:\n\t\tgoto fail;\n\t}\n\n\treturn 0;\n\n fail:\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn 1;  /* Pretend like we got EOM */\n}\n\n/* Skip dvalues to EOM. */\nDUK_LOCAL void duk__debug_skip_to_eom(duk_hthread *thr) {\n\tfor (;;) {\n\t\tif (duk__debug_skip_dvalue(thr)) {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/* Read and validate a call stack index.  If index is invalid, write out an\n * error message and return zero.\n */\nDUK_LOCAL duk_int32_t duk__debug_read_validate_csindex(duk_hthread *thr) {\n\tduk_int32_t level;\n\tlevel = duk_debug_read_int(thr);\n\tif (level >= 0 || -level > (duk_int32_t) thr->callstack_top) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid callstack index\");\n\t\treturn 0;  /* zero indicates failure */\n\t}\n\treturn level;\n}\n\n/* Read a call stack index and lookup the corresponding duk_activation.\n * If index is invalid, write out an error message and return NULL.\n */\nDUK_LOCAL duk_activation *duk__debug_read_level_get_activation(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_int32_t level;\n\n\tlevel = duk_debug_read_int(thr);\n\tact = duk_hthread_get_activation_for_level(thr, level);\n\tif (act == NULL) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid callstack index\");\n\t}\n\treturn act;\n}\n\n/*\n *  Simple commands\n */\n\nDUK_LOCAL void duk__debug_handle_basic_info(duk_hthread *thr, duk_heap *heap) {\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command Version\"));\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_int(thr, DUK_VERSION);\n\tduk_debug_write_cstring(thr, DUK_GIT_DESCRIBE);\n\tduk_debug_write_cstring(thr, DUK_USE_TARGET_INFO);\n#if defined(DUK_USE_DOUBLE_LE)\n\tduk_debug_write_int(thr, 1);\n#elif defined(DUK_USE_DOUBLE_ME)\n\tduk_debug_write_int(thr, 2);\n#elif defined(DUK_USE_DOUBLE_BE)\n\tduk_debug_write_int(thr, 3);\n#else\n\tduk_debug_write_int(thr, 0);\n#endif\n\tduk_debug_write_int(thr, (duk_int_t) sizeof(void *));\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_trigger_status(duk_hthread *thr, duk_heap *heap) {\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command TriggerStatus\"));\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n\theap->dbg_state_dirty = 1;\n}\n\nDUK_LOCAL void duk__debug_handle_pause(duk_hthread *thr, duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"debug command Pause\"));\n\tduk_debug_set_paused(heap);\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_resume(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_uint_t pause_flags;\n\n\tDUK_D(DUK_DPRINT(\"debug command Resume\"));\n\n\tduk_debug_clear_paused(heap);\n\n\tpause_flags = 0;\n#if 0  /* manual testing */\n\tpause_flags |= DUK_PAUSE_FLAG_ONE_OPCODE;\n\tpause_flags |= DUK_PAUSE_FLAG_CAUGHT_ERROR;\n\tpause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;\n#endif\n#if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)\n\tpause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;\n#endif\n\n\tduk__debug_set_pause_state(thr, heap, pause_flags);\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_step(duk_hthread *thr, duk_heap *heap, duk_int32_t cmd) {\n\tduk_small_uint_t pause_flags;\n\n\tDUK_D(DUK_DPRINT(\"debug command StepInto/StepOver/StepOut: %d\", (int) cmd));\n\n\tif (cmd == DUK_DBG_CMD_STEPINTO) {\n\t\tpause_flags = DUK_PAUSE_FLAG_LINE_CHANGE |\n\t\t              DUK_PAUSE_FLAG_FUNC_ENTRY |\n\t\t              DUK_PAUSE_FLAG_FUNC_EXIT;\n\t} else if (cmd == DUK_DBG_CMD_STEPOVER) {\n\t\tpause_flags = DUK_PAUSE_FLAG_LINE_CHANGE |\n\t\t              DUK_PAUSE_FLAG_FUNC_EXIT;\n\t} else {\n\t\tDUK_ASSERT(cmd == DUK_DBG_CMD_STEPOUT);\n\t\tpause_flags = DUK_PAUSE_FLAG_FUNC_EXIT;\n\t}\n#if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)\n\tpause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;\n#endif\n\n\t/* If current activation doesn't have line information, line-based\n\t * pause flags are automatically disabled.  As a result, e.g.\n\t * StepInto will then pause on (native) function entry or exit.\n\t */\n\tduk_debug_clear_paused(heap);\n\tduk__debug_set_pause_state(thr, heap, pause_flags);\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_list_break(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_int_t i;\n\n\tDUK_D(DUK_DPRINT(\"debug command ListBreak\"));\n\tduk_debug_write_reply(thr);\n\tfor (i = 0; i < (duk_small_int_t) heap->dbg_breakpoint_count; i++) {\n\t\tduk_debug_write_hstring(thr, heap->dbg_breakpoints[i].filename);\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) heap->dbg_breakpoints[i].line);\n\t}\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_add_break(duk_hthread *thr, duk_heap *heap) {\n\tduk_hstring *filename;\n\tduk_uint32_t linenumber;\n\tduk_small_int_t idx;\n\n\tDUK_UNREF(heap);\n\n\tfilename = duk_debug_read_hstring(thr);\n\tlinenumber = (duk_uint32_t) duk_debug_read_int(thr);\n\tDUK_D(DUK_DPRINT(\"debug command AddBreak: %!O:%ld\", (duk_hobject *) filename, (long) linenumber));\n\tidx = duk_debug_add_breakpoint(thr, filename, linenumber);\n\tif (idx >= 0) {\n\t\tduk_debug_write_reply(thr);\n\t\tduk_debug_write_int(thr, (duk_int32_t) idx);\n\t\tduk_debug_write_eom(thr);\n\t} else {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_TOOMANY, \"no space for breakpoint\");\n\t}\n}\n\nDUK_LOCAL void duk__debug_handle_del_break(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_uint_t idx;\n\n\tDUK_UNREF(heap);\n\n\tDUK_D(DUK_DPRINT(\"debug command DelBreak\"));\n\tidx = (duk_small_uint_t) duk_debug_read_int(thr);\n\tif (duk_debug_remove_breakpoint(thr, idx)) {\n\t\tduk_debug_write_reply(thr);\n\t\tduk_debug_write_eom(thr);\n\t} else {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid breakpoint index\");\n\t}\n}\n\nDUK_LOCAL void duk__debug_handle_get_var(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hstring *str;\n\tduk_bool_t rc;\n\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command GetVar\"));\n\n\tact = duk__debug_read_level_get_activation(thr);\n\tif (act == NULL) {\n\t\treturn;\n\t}\n\tstr = duk_debug_read_hstring(thr);  /* push to stack */\n\tDUK_ASSERT(str != NULL);\n\n\trc = duk_js_getvar_activation(thr, act, str, 0);\n\n\tduk_debug_write_reply(thr);\n\tif (rc) {\n\t\tduk_debug_write_int(thr, 1);\n\t\tDUK_ASSERT(duk_get_tval(thr, -2) != NULL);\n\t\tduk_debug_write_tval(thr, duk_get_tval(thr, -2));\n\t} else {\n\t\tduk_debug_write_int(thr, 0);\n\t\tduk_debug_write_unused(thr);\n\t}\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_put_var(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hstring *str;\n\tduk_tval *tv;\n\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command PutVar\"));\n\n\tact = duk__debug_read_level_get_activation(thr);\n\tif (act == NULL) {\n\t\treturn;\n\t}\n\tstr = duk_debug_read_hstring(thr);  /* push to stack */\n\tDUK_ASSERT(str != NULL);\n\ttv = duk_debug_read_tval(thr);\n\tif (tv == NULL) {\n\t\t/* detached */\n\t\treturn;\n\t}\n\n\tduk_js_putvar_activation(thr, act, str, tv, 0);\n\n\t/* XXX: Current putvar implementation doesn't have a success flag,\n\t * add one and send to debug client?\n\t */\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_get_call_stack(duk_hthread *thr, duk_heap *heap) {\n\tduk_hthread *curr_thr = thr;\n\tduk_activation *curr_act;\n\tduk_uint_fast32_t pc;\n\tduk_uint_fast32_t line;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_UNREF(heap);\n\n\tduk_debug_write_reply(thr);\n\twhile (curr_thr != NULL) {\n\t\tfor (curr_act = curr_thr->callstack_curr; curr_act != NULL; curr_act = curr_act->parent) {\n\t\t\t/* PC/line semantics here are:\n\t\t\t *   - For callstack top we're conceptually between two\n\t\t\t *     opcodes and current PC indicates next line to\n\t\t\t *     execute, so report that (matches Status).\n\t\t\t *   - For other activations we're conceptually still\n\t\t\t *     executing the instruction at PC-1, so report that\n\t\t\t *     (matches error stacktrace behavior).\n\t\t\t *   - See: https://github.com/svaarala/duktape/issues/281\n\t\t\t */\n\n\t\t\t/* XXX: optimize to use direct reads, i.e. avoid\n\t\t\t * value stack operations.\n\t\t\t */\n\t\t\tduk_push_tval(thr, &curr_act->tv_func);\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME);\n\t\t\tduk__debug_write_hstring_safe_top(thr);\n\t\t\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME);\n\t\t\tduk__debug_write_hstring_safe_top(thr);\n\t\t\tpc = duk_hthread_get_act_curr_pc(thr, curr_act);\n\t\t\tif (curr_act != curr_thr->callstack_curr && pc > 0) {\n\t\t\t\tpc--;\n\t\t\t}\n\t\t\tline = duk_hobject_pc2line_query(thr, -3, pc);\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) line);\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) pc);\n\t\t\tduk_pop_3(thr);\n\t\t}\n\t\tcurr_thr = curr_thr->resumer;\n\t}\n\t/* SCANBUILD: warning about 'thr' potentially being NULL here,\n\t * warning is incorrect because thr != NULL always here.\n\t */\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_get_locals(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hstring *varname;\n\n\tDUK_UNREF(heap);\n\n\tact = duk__debug_read_level_get_activation(thr);\n\tif (act == NULL) {\n\t\treturn;\n\t}\n\n\tduk_debug_write_reply(thr);\n\n\t/* XXX: several nice-to-have improvements here:\n\t *   - Use direct reads avoiding value stack operations\n\t *   - Avoid triggering getters, indicate getter values to debug client\n\t *   - If side effects are possible, add error catching\n\t */\n\n\tif (DUK_TVAL_IS_OBJECT(&act->tv_func)) {\n\t\tduk_hobject *h_func = DUK_TVAL_GET_OBJECT(&act->tv_func);\n\t\tduk_hobject *h_varmap;\n\n\t\th_varmap = duk_hobject_get_varmap(thr, h_func);\n\t\tif (h_varmap != NULL) {\n\t\t\tduk_push_hobject(thr, h_varmap);\n\t\t\tduk_enum(thr, -1, 0 /*enum_flags*/);\n\t\t\twhile (duk_next(thr, -1 /*enum_index*/, 0 /*get_value*/)) {\n\t\t\t\tvarname = duk_known_hstring(thr, -1);\n\n\t\t\t\tduk_js_getvar_activation(thr, act, varname, 0 /*throw_flag*/);\n\t\t\t\t/* [ ... func varmap enum key value this ] */\n\t\t\t\tduk_debug_write_hstring(thr, duk_get_hstring(thr, -3));\n\t\t\t\tduk_debug_write_tval(thr, duk_get_tval(thr, -2));\n\t\t\t\tduk_pop_3(thr);  /* -> [ ... func varmap enum ] */\n\t\t\t}\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"varmap missing in GetLocals, ignore\"));\n\t\t}\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"varmap is not an object in GetLocals, ignore\"));\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_uint_t call_flags;\n\tduk_int_t call_ret;\n\tduk_small_int_t eval_err;\n\tduk_bool_t direct_eval;\n\tduk_int32_t level;\n\tduk_idx_t idx_func;\n\n\tDUK_UNREF(heap);\n\n\tDUK_D(DUK_DPRINT(\"debug command Eval\"));\n\n\t/* The eval code is executed within the lexical environment of a specified\n\t * activation.  For now, use global object eval() function, with the eval\n\t * considered a 'direct call to eval'.\n\t *\n\t * Callstack index for debug commands only affects scope -- the callstack\n\t * as seen by, e.g. Duktape.act() will be the same regardless.\n\t */\n\n\t/* nargs == 2 so we can pass a callstack index to eval(). */\n\tidx_func = duk_get_top(thr);\n\tduk_push_c_function(thr, duk_bi_global_object_eval, 2 /*nargs*/);\n\tduk_push_undefined(thr);  /* 'this' binding shouldn't matter here */\n\n\t/* Read callstack index, if non-null. */\n\tif (duk_debug_peek_byte(thr) == DUK_DBG_IB_NULL) {\n\t\tdirect_eval = 0;\n\t\tlevel = -1;  /* Not needed, but silences warning. */\n\t\t(void) duk_debug_read_byte(thr);\n\t} else {\n\t\tdirect_eval = 1;\n\t\tlevel = duk__debug_read_validate_csindex(thr);\n\t\tif (level == 0) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\tDUK_ASSERT(!direct_eval ||\n\t           (level < 0 && -level <= (duk_int32_t) thr->callstack_top));\n\n\t(void) duk_debug_read_hstring(thr);\n\tif (direct_eval) {\n\t\tduk_push_int(thr, level - 1);  /* compensate for eval() call */\n\t}\n\n\t/* [ ... eval \"eval\" eval_input level? ] */\n\n\tcall_flags = 0;\n\tif (direct_eval) {\n\t\tduk_activation *act;\n\t\tduk_hobject *fun;\n\n\t\tact = duk_hthread_get_activation_for_level(thr, level);\n\t\tif (act != NULL) {\n\t\t\tfun = DUK_ACT_GET_FUNC(act);\n\t\t\tif (fun != NULL && DUK_HOBJECT_IS_COMPFUNC(fun)) {\n\t\t\t\t/* Direct eval requires that there's a current\n\t\t\t\t * activation and it is an ECMAScript function.\n\t\t\t\t * When Eval is executed from e.g. cooperate API\n\t\t\t\t * call we'll need to do an indirect eval instead.\n\t\t\t\t */\n\t\t\t\tcall_flags |= DUK_CALL_FLAG_DIRECT_EVAL;\n\t\t\t}\n\t\t}\n\t}\n\n\tcall_ret = duk_pcall_method_flags(thr, duk_get_top(thr) - (idx_func + 2), call_flags);\n\n\tif (call_ret == DUK_EXEC_SUCCESS) {\n\t\teval_err = 0;\n\t\t/* Use result value as is. */\n\t} else {\n\t\t/* For errors a string coerced result is most informative\n\t\t * right now, as the debug client doesn't have the capability\n\t\t * to traverse the error object.\n\t\t */\n\t\teval_err = 1;\n\t\tduk_safe_to_string(thr, -1);\n\t}\n\n\t/* [ ... result ] */\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_int(thr, (duk_int32_t) eval_err);\n\tDUK_ASSERT(duk_get_tval(thr, -1) != NULL);\n\tduk_debug_write_tval(thr, duk_get_tval(thr, -1));\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_detach(duk_hthread *thr, duk_heap *heap) {\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command Detach\"));\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n\n\tDUK_D(DUK_DPRINT(\"debug connection detached, mark broken\"));\n\tDUK__SET_CONN_BROKEN(thr, 0);  /* not an error */\n}\n\nDUK_LOCAL void duk__debug_handle_apprequest(duk_hthread *thr, duk_heap *heap) {\n\tduk_idx_t old_top;\n\n\tDUK_D(DUK_DPRINT(\"debug command AppRequest\"));\n\n\told_top = duk_get_top(thr);  /* save stack top */\n\n\tif (heap->dbg_request_cb != NULL) {\n\t\tduk_idx_t nrets;\n\t\tduk_idx_t nvalues = 0;\n\t\tduk_idx_t top, idx;\n\n\t\t/* Read tvals from the message and push them onto the valstack,\n\t\t * then call the request callback to process the request.\n\t\t */\n\t\twhile (duk_debug_peek_byte(thr) != DUK_DBG_IB_EOM) {\n\t\t\tduk_tval *tv;\n\t\t\tif (!duk_check_stack(thr, 1)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"failed to allocate space for request dvalue(s)\"));\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\ttv = duk_debug_read_tval(thr);  /* push to stack */\n\t\t\tif (tv == NULL) {\n\t\t\t\t/* detached */\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnvalues++;\n\t\t}\n\t\tDUK_ASSERT(duk_get_top(thr) == old_top + nvalues);\n\n\t\t/* Request callback should push values for reply to client onto valstack */\n\t\tDUK_D(DUK_DPRINT(\"calling into AppRequest request_cb with nvalues=%ld, old_top=%ld, top=%ld\",\n\t\t                 (long) nvalues, (long) old_top, (long) duk_get_top(thr)));\n\t\tnrets = heap->dbg_request_cb(thr, heap->dbg_udata, nvalues);\n\t\tDUK_D(DUK_DPRINT(\"returned from AppRequest request_cb; nvalues=%ld -> nrets=%ld, old_top=%ld, top=%ld\",\n\t\t                 (long) nvalues, (long) nrets, (long) old_top, (long) duk_get_top(thr)));\n\t\tif (nrets >= 0) {\n\t\t\tDUK_ASSERT(duk_get_top(thr) >= old_top + nrets);\n\t\t\tif (duk_get_top(thr) < old_top + nrets) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"AppRequest callback doesn't match value stack configuration, \"\n\t\t\t\t                 \"top=%ld < old_top=%ld + nrets=%ld; \"\n\t\t\t\t                 \"this might mean it's unsafe to continue!\",\n\t\t\t\t                 (long) duk_get_top(thr), (long) old_top, (long) nrets));\n\t\t\t\tgoto fail;\n\t\t\t}\n\n\t\t\t/* Reply with tvals pushed by request callback */\n\t\t\tduk_debug_write_byte(thr, DUK_DBG_IB_REPLY);\n\t\t\ttop = duk_get_top(thr);\n\t\t\tfor (idx = top - nrets; idx < top; idx++) {\n\t\t\t\tduk_debug_write_tval(thr, DUK_GET_TVAL_POSIDX(thr, idx));\n\t\t\t}\n\t\t\tduk_debug_write_eom(thr);\n\t\t} else {\n\t\t\tDUK_ASSERT(duk_get_top(thr) >= old_top + 1);\n\t\t\tif (duk_get_top(thr) < old_top + 1) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"request callback return value doesn't match value stack configuration\"));\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_APPLICATION, duk_get_string(thr, -1));\n\t\t}\n\n\t\tduk_set_top(thr, old_top);  /* restore stack top */\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"no request callback, treat AppRequest as unsupported\"));\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNSUPPORTED, \"AppRequest unsupported by target\");\n\t}\n\n\treturn;\n\n fail:\n\tduk_set_top(thr, old_top);  /* restore stack top */\n\tDUK__SET_CONN_BROKEN(thr, 1);\n}\n\n/*\n *  DumpHeap command\n */\n\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP)\n/* XXX: this has some overlap with object inspection; remove this and make\n * DumpHeap return lists of heapptrs instead?\n */\nDUK_LOCAL void duk__debug_dump_heaphdr(duk_hthread *thr, duk_heap *heap, duk_heaphdr *hdr) {\n\tDUK_UNREF(heap);\n\n\tduk_debug_write_heapptr(thr, hdr);\n\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HEAPHDR_GET_TYPE(hdr));\n\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HEAPHDR_GET_FLAGS_RAW(hdr));\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HEAPHDR_GET_REFCOUNT(hdr));\n#else\n\tduk_debug_write_int(thr, (duk_int32_t) -1);\n#endif\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(hdr)) {\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h = (duk_hstring *) hdr;\n\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_BYTELEN(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_CHARLEN(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_HASH(h));\n\t\tduk_debug_write_hstring(thr, h);\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h = (duk_hobject *) hdr;\n\t\tduk_hstring *k;\n\t\tduk_uint_fast32_t i;\n\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_CLASS_NUMBER(h));\n\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(heap, h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_ESIZE(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_ENEXT(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_ASIZE(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_HSIZE(h));\n\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_E_GET_FLAGS(heap, h, i));\n\t\t\tk = DUK_HOBJECT_E_GET_KEY(heap, h, i);\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) k);\n\t\t\tif (k == NULL) {\n\t\t\t\tduk_debug_write_int(thr, 0);  /* isAccessor */\n\t\t\t\tduk_debug_write_unused(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)) {\n\t\t\t\tduk_debug_write_int(thr, 1);  /* isAccessor */\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.get);\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.set);\n\t\t\t} else {\n\t\t\t\tduk_debug_write_int(thr, 0);  /* isAccessor */\n\n\t\t\t\tduk__debug_write_tval_heapptr(thr, &DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->v);\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(h); i++) {\n\t\t\t/* Note: array dump will include elements beyond\n\t\t\t * 'length'.\n\t\t\t */\n\t\t\tduk__debug_write_tval_heapptr(thr, DUK_HOBJECT_A_GET_VALUE_PTR(heap, h, i));\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h = (duk_hbuffer *) hdr;\n\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HBUFFER_GET_SIZE(h));\n\t\tduk_debug_write_buffer(thr, (const char *) DUK_HBUFFER_GET_DATA_PTR(heap, h), (duk_size_t) DUK_HBUFFER_GET_SIZE(h));\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tDUK_D(DUK_DPRINT(\"invalid htype: %d\", (int) DUK_HEAPHDR_GET_TYPE(hdr)));\n\t}\n\t}\n}\n\nDUK_LOCAL void duk__debug_dump_heap_allocated(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\n\thdr = heap->heap_allocated;\n\twhile (hdr != NULL) {\n\t\tduk__debug_dump_heaphdr(thr, heap, hdr);\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n}\n\nDUK_LOCAL void duk__debug_dump_strtab(duk_hthread *thr, duk_heap *heap) {\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\n\tfor (i = 0; i < heap->st_size; i++) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\th = DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, heap->strtable16[i]);\n#else\n\t\th = heap->strtable[i];\n#endif\n\t\twhile (h != NULL) {\n\t\t\tduk__debug_dump_heaphdr(thr, heap, (duk_heaphdr *) h);\n\t\t\th = h->hdr.h_next;\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__debug_handle_dump_heap(duk_hthread *thr, duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"debug command DumpHeap\"));\n\n\tduk_debug_write_reply(thr);\n\tduk__debug_dump_heap_allocated(thr, heap);\n\tduk__debug_dump_strtab(thr, heap);\n\tduk_debug_write_eom(thr);\n}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP */\n\nDUK_LOCAL void duk__debug_handle_get_bytecode(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hcompfunc *fun = NULL;\n\tduk_size_t i, n;\n\tduk_tval *tv;\n\tduk_hobject **fn;\n\tduk_int32_t level = -1;\n\tduk_uint8_t ibyte;\n\n\tDUK_UNREF(heap);\n\n\tDUK_D(DUK_DPRINT(\"debug command GetBytecode\"));\n\n\tibyte = duk_debug_peek_byte(thr);\n\tif (ibyte != DUK_DBG_IB_EOM) {\n\t\ttv = duk_debug_read_tval(thr);\n\t\tif (tv == NULL) {\n\t\t\t/* detached */\n\t\t\treturn;\n\t\t}\n\t\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\t\t/* tentative, checked later */\n\t\t\tfun = (duk_hcompfunc *) DUK_TVAL_GET_OBJECT(tv);\n\t\t\tDUK_ASSERT(fun != NULL);\n\t\t} else if (DUK_TVAL_IS_NUMBER(tv)) {\n\t\t\tlevel = (duk_int32_t) DUK_TVAL_GET_NUMBER(tv);\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"invalid argument to GetBytecode: %!T\", tv));\n\t\t\tgoto fail_args;\n\t\t}\n\t}\n\n\tif (fun == NULL) {\n\t\tact = duk_hthread_get_activation_for_level(thr, level);\n\t\tif (act == NULL) {\n\t\t\tgoto fail_index;\n\t\t}\n\t\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\t}\n\n\tif (fun == NULL || !DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun)) {\n\t\tDUK_D(DUK_DPRINT(\"invalid argument to GetBytecode: %!O\", fun));\n\t\tgoto fail_args;\n\t}\n\tDUK_ASSERT(fun != NULL && DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun));\n\n\tduk_debug_write_reply(thr);\n\tn = DUK_HCOMPFUNC_GET_CONSTS_COUNT(heap, fun);\n\tduk_debug_write_int(thr, (duk_int32_t) n);\n\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, fun);\n\tfor (i = 0; i < n; i++) {\n\t\tduk_debug_write_tval(thr, tv);\n\t\ttv++;\n\t}\n\tn = DUK_HCOMPFUNC_GET_FUNCS_COUNT(heap, fun);\n\tduk_debug_write_int(thr, (duk_int32_t) n);\n\tfn = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, fun);\n\tfor (i = 0; i < n; i++) {\n\t\tduk_debug_write_hobject(thr, *fn);\n\t\tfn++;\n\t}\n\tduk_debug_write_string(thr,\n\t                       (const char *) DUK_HCOMPFUNC_GET_CODE_BASE(heap, fun),\n\t                       (duk_size_t) DUK_HCOMPFUNC_GET_CODE_SIZE(heap, fun));\n\tduk_debug_write_eom(thr);\n\treturn;\n\n fail_args:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid argument\");\n\treturn;\n\n fail_index:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid callstack index\");\n\treturn;\n}\n\n/*\n *  Object inspection commands: GetHeapObjInfo, GetObjPropDesc,\n *  GetObjPropDescRange\n */\n\n#if defined(DUK_USE_DEBUGGER_INSPECT)\n\n#if 0 /* pruned */\nDUK_LOCAL const char * const duk__debug_getinfo_heaphdr_keys[] = {\n\t\"reachable\",\n\t\"temproot\",\n\t\"finalizable\",\n\t\"finalized\",\n\t\"readonly\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_heaphdr_masks[] = {\n\tDUK_HEAPHDR_FLAG_REACHABLE,\n\tDUK_HEAPHDR_FLAG_TEMPROOT,\n\tDUK_HEAPHDR_FLAG_FINALIZABLE,\n\tDUK_HEAPHDR_FLAG_FINALIZED,\n\tDUK_HEAPHDR_FLAG_READONLY,\n\t0  /* terminator */\n};\n#endif\nDUK_LOCAL const char * const duk__debug_getinfo_hstring_keys[] = {\n#if 0\n\t\"arridx\",\n\t\"symbol\",\n\t\"hidden\",\n\t\"reserved_word\",\n\t\"strict_reserved_word\",\n\t\"eval_or_arguments\",\n#endif\n\t\"extdata\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_hstring_masks[] = {\n#if 0\n\tDUK_HSTRING_FLAG_ARRIDX,\n\tDUK_HSTRING_FLAG_SYMBOL,\n\tDUK_HSTRING_FLAG_HIDDEN,\n\tDUK_HSTRING_FLAG_RESERVED_WORD,\n\tDUK_HSTRING_FLAG_STRICT_RESERVED_WORD,\n\tDUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS,\n#endif\n\tDUK_HSTRING_FLAG_EXTDATA,\n\t0  /* terminator */\n};\nDUK_LOCAL const char * const duk__debug_getinfo_hobject_keys[] = {\n\t\"extensible\",\n\t\"constructable\",\n\t\"callable\",\n\t\"boundfunc\",\n\t\"compfunc\",\n\t\"natfunc\",\n\t\"bufobj\",\n\t\"fastrefs\",\n\t\"array_part\",\n\t\"strict\",\n\t\"notail\",\n\t\"newenv\",\n\t\"namebinding\",\n\t\"createargs\",\n\t\"have_finalizer\",\n\t\"exotic_array\",\n\t\"exotic_stringobj\",\n\t\"exotic_arguments\",\n\t\"exotic_proxyobj\",\n\t\"special_call\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_hobject_masks[] = {\n\tDUK_HOBJECT_FLAG_EXTENSIBLE,\n\tDUK_HOBJECT_FLAG_CONSTRUCTABLE,\n\tDUK_HOBJECT_FLAG_CALLABLE,\n\tDUK_HOBJECT_FLAG_BOUNDFUNC,\n\tDUK_HOBJECT_FLAG_COMPFUNC,\n\tDUK_HOBJECT_FLAG_NATFUNC,\n\tDUK_HOBJECT_FLAG_BUFOBJ,\n\tDUK_HOBJECT_FLAG_FASTREFS,\n\tDUK_HOBJECT_FLAG_ARRAY_PART,\n\tDUK_HOBJECT_FLAG_STRICT,\n\tDUK_HOBJECT_FLAG_NOTAIL,\n\tDUK_HOBJECT_FLAG_NEWENV,\n\tDUK_HOBJECT_FLAG_NAMEBINDING,\n\tDUK_HOBJECT_FLAG_CREATEARGS,\n\tDUK_HOBJECT_FLAG_HAVE_FINALIZER,\n\tDUK_HOBJECT_FLAG_EXOTIC_ARRAY,\n\tDUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ,\n\tDUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS,\n\tDUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ,\n\tDUK_HOBJECT_FLAG_SPECIAL_CALL,\n\t0  /* terminator */\n};\nDUK_LOCAL const char * const duk__debug_getinfo_hbuffer_keys[] = {\n\t\"dynamic\",\n\t\"external\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_hbuffer_masks[] = {\n\tDUK_HBUFFER_FLAG_DYNAMIC,\n\tDUK_HBUFFER_FLAG_EXTERNAL,\n\t0  /* terminator */\n};\n\nDUK_LOCAL void duk__debug_getinfo_flags_key(duk_hthread *thr, const char *key) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n}\n\nDUK_LOCAL void duk__debug_getinfo_prop_uint(duk_hthread *thr, const char *key, duk_uint_t val) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n\tduk_debug_write_uint(thr, val);\n}\n\nDUK_LOCAL void duk__debug_getinfo_prop_int(duk_hthread *thr, const char *key, duk_int_t val) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n\tduk_debug_write_int(thr, val);\n}\n\nDUK_LOCAL void duk__debug_getinfo_prop_bool(duk_hthread *thr, const char *key, duk_bool_t val) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n\tduk_debug_write_boolean(thr, val);\n}\n\nDUK_LOCAL void duk__debug_getinfo_bitmask(duk_hthread *thr, const char * const * keys, duk_uint_t *masks, duk_uint_t flags) {\n\tconst char *key;\n\tduk_uint_t mask;\n\n\tfor (;;) {\n\t\tmask = *masks++;\n\t\tif (mask == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tkey = *keys++;\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tDUK_DD(DUK_DDPRINT(\"inspect bitmask: key=%s, mask=0x%08lx, flags=0x%08lx\", key, (unsigned long) mask, (unsigned long) flags));\n\t\tduk__debug_getinfo_prop_bool(thr, key, flags & mask);\n\t}\n}\n\n/* Inspect a property using a virtual index into a conceptual property list\n * consisting of (1) all array part items from [0,a_size[ (even when above\n * .length) and (2) all entry part items from [0,e_next[.  Unused slots are\n * indicated using dvalue 'unused'.\n */\nDUK_LOCAL duk_bool_t duk__debug_getprop_index(duk_hthread *thr, duk_heap *heap, duk_hobject *h_obj, duk_uint_t idx) {\n\tduk_uint_t a_size;\n\tduk_tval *tv;\n\tduk_hstring *h_key;\n\tduk_hobject *h_getset;\n\tduk_uint_t flags;\n\n\tDUK_UNREF(heap);\n\n\ta_size = DUK_HOBJECT_GET_ASIZE(h_obj);\n\tif (idx < a_size) {\n\t\tduk_debug_write_uint(thr, DUK_PROPDESC_FLAGS_WEC);\n\t\tduk_debug_write_uint(thr, idx);\n\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(heap, h_obj, idx);\n\t\tduk_debug_write_tval(thr, tv);\n\t\treturn 1;\n\t}\n\n\tidx -= a_size;\n\tif (idx >= DUK_HOBJECT_GET_ENEXT(h_obj)) {\n\t\treturn 0;\n\t}\n\n\th_key = DUK_HOBJECT_E_GET_KEY(heap, h_obj, idx);\n\tif (h_key == NULL) {\n\t\tduk_debug_write_uint(thr, 0);\n\t\tduk_debug_write_null(thr);\n\t\tduk_debug_write_unused(thr);\n\t\treturn 1;\n\t}\n\n\tflags = DUK_HOBJECT_E_GET_FLAGS(heap, h_obj, idx);\n\tif (DUK_HSTRING_HAS_SYMBOL(h_key)) {\n\t\tflags |= DUK_DBG_PROPFLAG_SYMBOL;\n\t}\n\tif (DUK_HSTRING_HAS_HIDDEN(h_key)) {\n\t\tflags |= DUK_DBG_PROPFLAG_HIDDEN;\n\t}\n\tduk_debug_write_uint(thr, flags);\n\tduk_debug_write_hstring(thr, h_key);\n\tif (flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\th_getset = DUK_HOBJECT_E_GET_VALUE_GETTER(heap, h_obj, idx);\n\t\tif (h_getset) {\n\t\t\tduk_debug_write_hobject(thr, h_getset);\n\t\t} else {\n\t\t\tduk_debug_write_null(thr);\n\t\t}\n\t\th_getset = DUK_HOBJECT_E_GET_VALUE_SETTER(heap, h_obj, idx);\n\t\tif (h_getset) {\n\t\t\tduk_debug_write_hobject(thr, h_getset);\n\t\t} else {\n\t\t\tduk_debug_write_null(thr);\n\t\t}\n\t} else {\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, h_obj, idx);\n\t\tduk_debug_write_tval(thr, tv);\n\t}\n\treturn 1;\n}\n\nDUK_LOCAL void duk__debug_handle_get_heap_obj_info(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *h;\n\n\tDUK_D(DUK_DPRINT(\"debug command GetHeapObjInfo\"));\n\tDUK_UNREF(heap);\n\n\tDUK_ASSERT(sizeof(duk__debug_getinfo_hstring_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hstring_masks) / sizeof(duk_uint_t) - 1);\n\tDUK_ASSERT(sizeof(duk__debug_getinfo_hobject_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hobject_masks) / sizeof(duk_uint_t) - 1);\n\tDUK_ASSERT(sizeof(duk__debug_getinfo_hbuffer_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hbuffer_masks) / sizeof(duk_uint_t) - 1);\n\n\th = duk_debug_read_any_ptr(thr);\n\tif (!h) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid target\");\n\t\treturn;\n\t}\n\n\tduk_debug_write_reply(thr);\n\n\t/* As with all inspection code, we rely on the debug client providing\n\t * a valid, non-stale pointer: there's no portable way to safely\n\t * validate the pointer here.\n\t */\n\n\tduk__debug_getinfo_flags_key(thr, \"heapptr\");\n\tduk_debug_write_heapptr(thr, h);\n\n\t/* XXX: comes out as signed now */\n\tduk__debug_getinfo_prop_uint(thr, \"heaphdr_flags\", (duk_uint_t) DUK_HEAPHDR_GET_FLAGS(h));\n\tduk__debug_getinfo_prop_uint(thr, \"heaphdr_type\", (duk_uint_t) DUK_HEAPHDR_GET_TYPE(h));\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__debug_getinfo_prop_uint(thr, \"refcount\", (duk_uint_t) DUK_HEAPHDR_GET_REFCOUNT(h));\n#endif\n#if 0 /* pruned */\n\tduk__debug_getinfo_bitmask(thr,\n\t                           duk__debug_getinfo_heaphdr_keys,\n\t                           duk__debug_getinfo_heaphdr_masks,\n\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n#endif\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h_str;\n\n\t\th_str = (duk_hstring *) h;\n\t\tduk__debug_getinfo_bitmask(thr,\n\t\t                           duk__debug_getinfo_hstring_keys,\n\t\t                           duk__debug_getinfo_hstring_masks,\n\t\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n\t\tduk__debug_getinfo_prop_uint(thr, \"bytelen\", (duk_uint_t) DUK_HSTRING_GET_BYTELEN(h_str));\n\t\tduk__debug_getinfo_prop_uint(thr, \"charlen\", (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h_str));\n\t\tduk__debug_getinfo_prop_uint(thr, \"hash\", (duk_uint_t) DUK_HSTRING_GET_HASH(h_str));\n\t\tduk__debug_getinfo_flags_key(thr, \"data\");\n\t\tduk_debug_write_hstring(thr, h_str);\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h_obj;\n\t\tduk_hobject *h_proto;\n\n\t\th_obj = (duk_hobject *) h;\n\t\th_proto = DUK_HOBJECT_GET_PROTOTYPE(heap, h_obj);\n\n\t\t/* duk_hobject specific fields. */\n\t\tduk__debug_getinfo_bitmask(thr,\n\t\t                           duk__debug_getinfo_hobject_keys,\n\t\t                           duk__debug_getinfo_hobject_masks,\n\t\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n\t\tduk__debug_getinfo_prop_uint(thr, \"class_number\", DUK_HOBJECT_GET_CLASS_NUMBER(h_obj));\n\t\tduk__debug_getinfo_flags_key(thr, \"class_name\");\n\t\tduk_debug_write_hstring(thr, DUK_HOBJECT_GET_CLASS_STRING(heap, h_obj));\n\t\tduk__debug_getinfo_flags_key(thr, \"prototype\");\n\t\tif (h_proto != NULL) {\n\t\t\tduk_debug_write_hobject(thr, h_proto);\n\t\t} else {\n\t\t\tduk_debug_write_null(thr);\n\t\t}\n\t\tduk__debug_getinfo_flags_key(thr, \"props\");\n\t\tduk_debug_write_pointer(thr, (void *) DUK_HOBJECT_GET_PROPS(heap, h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"e_size\", (duk_uint_t) DUK_HOBJECT_GET_ESIZE(h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"e_next\", (duk_uint_t) DUK_HOBJECT_GET_ENEXT(h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"a_size\", (duk_uint_t) DUK_HOBJECT_GET_ASIZE(h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"h_size\", (duk_uint_t) DUK_HOBJECT_GET_HSIZE(h_obj));\n\n\t\tif (DUK_HOBJECT_IS_ARRAY(h_obj)) {\n\t\t\tduk_harray *h_arr;\n\t\t\th_arr = (duk_harray *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"length\", (duk_uint_t) h_arr->length);\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"length_nonwritable\", h_arr->length_nonwritable);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_NATFUNC(h_obj)) {\n\t\t\tduk_hnatfunc *h_fun;\n\t\t\th_fun = (duk_hnatfunc *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_int(thr, \"nargs\", h_fun->nargs);\n\t\t\tduk__debug_getinfo_prop_int(thr, \"magic\", h_fun->magic);\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"varargs\", h_fun->magic == DUK_HNATFUNC_NARGS_VARARGS);\n\t\t\t/* Native function pointer may be different from a void pointer,\n\t\t\t * and we serialize it from memory directly now (no byte swapping etc).\n\t\t\t */\n\t\t\tduk__debug_getinfo_flags_key(thr, \"funcptr\");\n\t\t\tduk_debug_write_buffer(thr, (const char *) &h_fun->func, sizeof(h_fun->func));\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tduk_hcompfunc *h_fun;\n\t\t\tduk_hbuffer *h_buf;\n\t\t\tduk_hobject *h_lexenv;\n\t\t\tduk_hobject *h_varenv;\n\t\t\th_fun = (duk_hcompfunc *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_int(thr, \"nregs\", h_fun->nregs);\n\t\t\tduk__debug_getinfo_prop_int(thr, \"nargs\", h_fun->nargs);\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"lex_env\");\n\t\t\th_lexenv = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, h_fun);\n\t\t\tif (h_lexenv != NULL) {\n\t\t\t\tduk_debug_write_hobject(thr, h_lexenv);\n\t\t\t} else {\n\t\t\t\tduk_debug_write_null(thr);\n\t\t\t}\n\t\t\tduk__debug_getinfo_flags_key(thr, \"var_env\");\n\t\t\th_varenv = DUK_HCOMPFUNC_GET_VARENV(thr->heap, h_fun);\n\t\t\tif (h_varenv != NULL) {\n\t\t\t\tduk_debug_write_hobject(thr, h_varenv);\n\t\t\t} else {\n\t\t\t\tduk_debug_write_null(thr);\n\t\t\t}\n\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"start_line\", h_fun->start_line);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"end_line\", h_fun->end_line);\n\t\t\th_buf = (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(thr->heap, h_fun);\n\t\t\tif (h_buf != NULL) {\n\t\t\t\tduk__debug_getinfo_flags_key(thr, \"data\");\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) h_buf);\n\t\t\t}\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_BOUNDFUNC(h_obj)) {\n\t\t\tduk_hboundfunc *h_bfun;\n\t\t\th_bfun = (duk_hboundfunc *) (void *) h_obj;\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"target\");\n\t\t\tduk_debug_write_tval(thr, &h_bfun->target);\n\t\t\tduk__debug_getinfo_flags_key(thr, \"this_binding\");\n\t\t\tduk_debug_write_tval(thr, &h_bfun->this_binding);\n\t\t\tduk__debug_getinfo_flags_key(thr, \"nargs\");\n\t\t\tduk_debug_write_int(thr, h_bfun->nargs);\n\t\t\t/* h_bfun->args not exposed now */\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_THREAD(h_obj)) {\n\t\t\t/* XXX: Currently no inspection of threads, e.g. value stack, call\n\t\t\t * stack, catch stack, etc.\n\t\t\t */\n\t\t\tduk_hthread *h_thr;\n\t\t\th_thr = (duk_hthread *) h_obj;\n\t\t\tDUK_UNREF(h_thr);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_DECENV(h_obj)) {\n\t\t\tduk_hdecenv *h_env;\n\t\t\th_env = (duk_hdecenv *) h_obj;\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"thread\");\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->thread));\n\t\t\tduk__debug_getinfo_flags_key(thr, \"varmap\");\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->varmap));\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"regbase\", (duk_uint_t) h_env->regbase_byteoff);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_OBJENV(h_obj)) {\n\t\t\tduk_hobjenv *h_env;\n\t\t\th_env = (duk_hobjenv *) h_obj;\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"target\");\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->target));\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"has_this\", h_env->has_this);\n\t\t}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\tduk_hbufobj *h_bufobj;\n\t\t\th_bufobj = (duk_hbufobj *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"slice_offset\", h_bufobj->offset);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"slice_length\", h_bufobj->length);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"elem_shift\", (duk_uint_t) h_bufobj->shift);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"elem_type\", (duk_uint_t) h_bufobj->elem_type);\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"is_typedarray\", (duk_uint_t) h_bufobj->is_typedarray);\n\t\t\tif (h_bufobj->buf != NULL) {\n\t\t\t\tduk__debug_getinfo_flags_key(thr, \"buffer\");\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) h_bufobj->buf);\n\t\t\t}\n\t\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h_buf;\n\n\t\th_buf = (duk_hbuffer *) h;\n\t\tduk__debug_getinfo_bitmask(thr,\n\t\t                           duk__debug_getinfo_hbuffer_keys,\n\t\t                           duk__debug_getinfo_hbuffer_masks,\n\t\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n\t\tduk__debug_getinfo_prop_uint(thr, \"size\", (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_buf));\n\t\tduk__debug_getinfo_flags_key(thr, \"dataptr\");\n\t\tduk_debug_write_pointer(thr, (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_buf));\n\t\tduk__debug_getinfo_flags_key(thr, \"data\");\n\t\tduk_debug_write_hbuffer(thr, h_buf);  /* tolerates NULL h_buf */\n\t\tbreak;\n\t}\n\tdefault: {\n\t\t/* Since we already started writing the reply, just emit nothing. */\n\t\tDUK_D(DUK_DPRINT(\"inspect target pointer has invalid heaphdr type\"));\n\t}\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_get_obj_prop_desc(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *h;\n\tduk_hobject *h_obj;\n\tduk_hstring *h_key;\n\tduk_propdesc desc;\n\n\tDUK_D(DUK_DPRINT(\"debug command GetObjPropDesc\"));\n\tDUK_UNREF(heap);\n\n\th = duk_debug_read_any_ptr(thr);\n\tif (!h) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid target\");\n\t\treturn;\n\t}\n\th_key = duk_debug_read_hstring(thr);\n\tif (h == NULL || DUK_HEAPHDR_GET_TYPE(h) != DUK_HTYPE_OBJECT || h_key == NULL) {\n\t\tgoto fail_args;\n\t}\n\th_obj = (duk_hobject *) h;\n\n\tif (duk_hobject_get_own_propdesc(thr, h_obj, h_key, &desc, 0 /*flags*/)) {\n\t\tduk_int_t virtual_idx;\n\t\tduk_bool_t rc;\n\n\t\t/* To use the shared helper need the virtual index. */\n\t\tDUK_ASSERT(desc.e_idx >= 0 || desc.a_idx >= 0);\n\t\tvirtual_idx = (desc.a_idx >= 0 ? desc.a_idx :\n\t\t               (duk_int_t) DUK_HOBJECT_GET_ASIZE(h_obj) + desc.e_idx);\n\n\t\tduk_debug_write_reply(thr);\n\t\trc = duk__debug_getprop_index(thr, heap, h_obj, (duk_uint_t) virtual_idx);\n\t\tDUK_ASSERT(rc == 1);\n\t\tDUK_UNREF(rc);\n\t\tduk_debug_write_eom(thr);\n\t} else {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"not found\");\n\t}\n\treturn;\n\n fail_args:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid args\");\n}\n\nDUK_LOCAL void duk__debug_handle_get_obj_prop_desc_range(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *h;\n\tduk_hobject *h_obj;\n\tduk_uint_t idx, idx_start, idx_end;\n\n\tDUK_D(DUK_DPRINT(\"debug command GetObjPropDescRange\"));\n\tDUK_UNREF(heap);\n\n\th = duk_debug_read_any_ptr(thr);\n\tidx_start = (duk_uint_t) duk_debug_read_int(thr);\n\tidx_end = (duk_uint_t) duk_debug_read_int(thr);\n\tif (h == NULL || DUK_HEAPHDR_GET_TYPE(h) != DUK_HTYPE_OBJECT) {\n\t\tgoto fail_args;\n\t}\n\th_obj = (duk_hobject *) h;\n\n\t/* The index range space is conceptually the array part followed by the\n\t * entry part.  Unlike normal enumeration all slots are exposed here as\n\t * is and return 'unused' if the slots are not in active use.  In particular\n\t * the array part is included for the full a_size regardless of what the\n\t * array .length is.\n\t */\n\n\tduk_debug_write_reply(thr);\n\tfor (idx = idx_start; idx < idx_end; idx++) {\n\t\tif (!duk__debug_getprop_index(thr, heap, h_obj, idx)) {\n\t\t\tbreak;\n\t\t}\n\t}\n\tduk_debug_write_eom(thr);\n\treturn;\n\n fail_args:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid args\");\n}\n\n#endif  /* DUK_USE_DEBUGGER_INSPECT */\n\n/*\n *  Process incoming debug requests\n *\n *  Individual request handlers can push temporaries on the value stack and\n *  rely on duk__debug_process_message() to restore the value stack top\n *  automatically.\n */\n\n/* Process one debug message.  Automatically restore value stack top to its\n * entry value, so that individual message handlers don't need exact value\n * stack handling which is convenient.\n */\nDUK_LOCAL void duk__debug_process_message(duk_hthread *thr) {\n\tduk_heap *heap;\n\tduk_uint8_t x;\n\tduk_int32_t cmd;\n\tduk_idx_t entry_top;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tentry_top = duk_get_top(thr);\n\n\tx = duk_debug_read_byte(thr);\n\tswitch (x) {\n\tcase DUK_DBG_IB_REQUEST: {\n\t\tcmd = duk_debug_read_int(thr);\n\t\tswitch (cmd) {\n\t\tcase DUK_DBG_CMD_BASICINFO: {\n\t\t\tduk__debug_handle_basic_info(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_TRIGGERSTATUS: {\n\t\t\tduk__debug_handle_trigger_status(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_PAUSE: {\n\t\t\tduk__debug_handle_pause(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_RESUME: {\n\t\t\tduk__debug_handle_resume(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_STEPINTO:\n\t\tcase DUK_DBG_CMD_STEPOVER:\n\t\tcase DUK_DBG_CMD_STEPOUT: {\n\t\t\tduk__debug_handle_step(thr, heap, cmd);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_LISTBREAK: {\n\t\t\tduk__debug_handle_list_break(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_ADDBREAK: {\n\t\t\tduk__debug_handle_add_break(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_DELBREAK: {\n\t\t\tduk__debug_handle_del_break(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETVAR: {\n\t\t\tduk__debug_handle_get_var(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_PUTVAR: {\n\t\t\tduk__debug_handle_put_var(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETCALLSTACK: {\n\t\t\tduk__debug_handle_get_call_stack(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETLOCALS: {\n\t\t\tduk__debug_handle_get_locals(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_EVAL: {\n\t\t\tduk__debug_handle_eval(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_DETACH: {\n\t\t\t/* The actual detached_cb call is postponed to message loop so\n\t\t\t * we don't need any special precautions here (just skip to EOM\n\t\t\t * on the already closed connection).\n\t\t\t */\n\t\t\tduk__debug_handle_detach(thr, heap);\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP)\n\t\tcase DUK_DBG_CMD_DUMPHEAP: {\n\t\t\tduk__debug_handle_dump_heap(thr, heap);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP */\n\t\tcase DUK_DBG_CMD_GETBYTECODE: {\n\t\t\tduk__debug_handle_get_bytecode(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_APPREQUEST: {\n\t\t\tduk__debug_handle_apprequest(thr, heap);\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_DEBUGGER_INSPECT)\n\t\tcase DUK_DBG_CMD_GETHEAPOBJINFO: {\n\t\t\tduk__debug_handle_get_heap_obj_info(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETOBJPROPDESC: {\n\t\t\tduk__debug_handle_get_obj_prop_desc(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETOBJPROPDESCRANGE: {\n\t\t\tduk__debug_handle_get_obj_prop_desc_range(thr, heap);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_DEBUGGER_INSPECT */\n\t\tdefault: {\n\t\t\tDUK_D(DUK_DPRINT(\"debug command unsupported: %d\", (int) cmd));\n\t\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNSUPPORTED, \"unsupported command\");\n\t\t}\n\t\t}  /* switch cmd */\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_REPLY: {\n\t\tDUK_D(DUK_DPRINT(\"debug reply, skipping\"));\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_ERROR: {\n\t\tDUK_D(DUK_DPRINT(\"debug error, skipping\"));\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_NOTIFY: {\n\t\tDUK_D(DUK_DPRINT(\"debug notify, skipping\"));\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tDUK_D(DUK_DPRINT(\"invalid initial byte, drop connection: %d\", (int) x));\n\t\tgoto fail;\n\t}\n\t}  /* switch initial byte */\n\n\tDUK_ASSERT(duk_get_top(thr) >= entry_top);\n\tduk_set_top(thr, entry_top);\n\tduk__debug_skip_to_eom(thr);\n\treturn;\n\n fail:\n\tDUK_ASSERT(duk_get_top(thr) >= entry_top);\n\tduk_set_top(thr, entry_top);\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn;\n}\n\nDUK_LOCAL void duk__check_resend_status(duk_hthread *thr) {\n\tif (thr->heap->dbg_read_cb != NULL && thr->heap->dbg_state_dirty) {\n\t\tduk_debug_send_status(thr);\n\t\tthr->heap->dbg_state_dirty = 0;\n\t}\n}\n\nDUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t no_block) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top;\n#endif\n\tduk_bool_t retval = 0;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\n\tDUK_D(DUK_DPRINT(\"process debug messages: read_cb=%s, no_block=%ld, detaching=%ld, processing=%ld\",\n\t                 thr->heap->dbg_read_cb ? \"not NULL\" : \"NULL\", (long) no_block,\n\t                 (long) thr->heap->dbg_detaching, (long) thr->heap->dbg_processing));\n\tDUK_DD(DUK_DDPRINT(\"top at entry: %ld\", (long) duk_get_top(thr)));\n\n\t/* thr->heap->dbg_detaching may be != 0 if a debugger write outside\n\t * the message loop caused a transport error and detach1() to run.\n\t */\n\tDUK_ASSERT(thr->heap->dbg_detaching == 0 || thr->heap->dbg_detaching == 1);\n\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\tthr->heap->dbg_processing = 1;\n\n\t/* Ensure dirty state causes a Status even if never process any\n\t * messages.  This is expected by the bytecode executor when in\n\t * the running state.\n\t */\n\tduk__check_resend_status(thr);\n\n\tfor (;;) {\n\t\t/* Process messages until we're no longer paused or we peek\n\t\t * and see there's nothing to read right now.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"top at loop top: %ld\", (long) duk_get_top(thr)));\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 1);\n\n\t\twhile (thr->heap->dbg_read_cb == NULL && thr->heap->dbg_detaching) {\n\t\t\t/* Detach is pending; can be triggered from outside the\n\t\t\t * debugger loop (e.g. Status notify write error) or by\n\t\t\t * previous message handling.  Call detached callback\n\t\t\t * here, in a controlled state, to ensure a possible\n\t\t\t * reattach inside the detached_cb is handled correctly.\n\t\t\t *\n\t\t\t * Recheck for detach in a while loop: an immediate\n\t\t\t * reattach involves a call to duk_debugger_attach()\n\t\t\t * which writes a debugger handshake line immediately\n\t\t\t * inside the API call.  If the transport write fails\n\t\t\t * for that handshake, we can immediately end up in a\n\t\t\t * \"transport broken, detaching\" case several times here.\n\t\t\t * Loop back until we're either cleanly attached or\n\t\t\t * fully detached.\n\t\t\t *\n\t\t\t * NOTE: Reset dbg_processing = 1 forcibly, in case we\n\t\t\t * re-attached; duk_debugger_attach() sets dbg_processing\n\t\t\t * to 0 at the moment.\n\t\t\t */\n\n\t\t\tDUK_D(DUK_DPRINT(\"detach pending (dbg_read_cb == NULL, dbg_detaching != 0), call detach2\"));\n\n\t\t\tduk__debug_do_detach2(thr->heap);\n\t\t\tthr->heap->dbg_processing = 1;  /* may be set to 0 by duk_debugger_attach() inside callback */\n\n\t\t\tDUK_D(DUK_DPRINT(\"after detach2 (and possible reattach): dbg_read_cb=%s, dbg_detaching=%ld\",\n\t\t\t                 thr->heap->dbg_read_cb ? \"not NULL\" : \"NULL\", (long) thr->heap->dbg_detaching));\n\t\t}\n\t\tDUK_ASSERT(thr->heap->dbg_detaching == 0);  /* true even with reattach */\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 1);  /* even after a detach and possible reattach */\n\n\t\tif (thr->heap->dbg_read_cb == NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"debug connection broken (and not detaching), stop processing messages\"));\n\t\t\tbreak;\n\t\t}\n\n\t\tif (!DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || no_block) {\n\t\t\tif (!duk_debug_read_peek(thr)) {\n\t\t\t\t/* Note: peek cannot currently trigger a detach\n\t\t\t\t * so the dbg_detaching == 0 assert outside the\n\t\t\t\t * loop is correct.\n\t\t\t\t */\n\t\t\t\tDUK_D(DUK_DPRINT(\"processing debug message, peek indicated no data, stop processing messages\"));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_D(DUK_DPRINT(\"processing debug message, peek indicated there is data, handle it\"));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"paused, process debug message, blocking if necessary\"));\n\t\t}\n\n\t\tduk__check_resend_status(thr);\n\t\tduk__debug_process_message(thr);\n\t\tduk__check_resend_status(thr);\n\n\t\tretval = 1;  /* processed one or more messages */\n\t}\n\n\tDUK_ASSERT(thr->heap->dbg_detaching == 0);\n\tDUK_ASSERT(thr->heap->dbg_processing == 1);\n\tthr->heap->dbg_processing = 0;\n\n\t/* As an initial implementation, read flush after exiting the message\n\t * loop.  If transport is broken, this is a no-op (with debug logs).\n\t */\n\tduk_debug_read_flush(thr);  /* this cannot initiate a detach */\n\tDUK_ASSERT(thr->heap->dbg_detaching == 0);\n\n\tDUK_DD(DUK_DDPRINT(\"top at exit: %ld\", (long) duk_get_top(thr)));\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Easy to get wrong, so assert for it. */\n\tDUK_ASSERT(entry_top == duk_get_top(thr));\n#endif\n\n\treturn retval;\n}\n\n/*\n *  Halt execution helper\n */\n\n/* Halt execution and enter a debugger message loop until execution is resumed\n * by the client.  PC for the current activation may be temporarily decremented\n * so that the \"current\" instruction will be shown by the client.  This helper\n * is callable from anywhere, also outside bytecode executor.\n */\n\nDUK_INTERNAL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev_pc) {\n\tduk_activation *act;\n\tduk_hcompfunc *fun;\n\tduk_instr_t *old_pc = NULL;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(duk_debug_is_attached(thr->heap));\n\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\tDUK_ASSERT(!duk_debug_is_paused(thr->heap));\n\n\tduk_debug_set_paused(thr->heap);\n\n\tact = thr->callstack_curr;\n\n\t/* NOTE: act may be NULL if an error is thrown outside of any activation,\n\t * which may happen in the case of, e.g. syntax errors.\n\t */\n\n\t/* Decrement PC if that was requested, this requires a PC sync. */\n\tif (act != NULL) {\n\t\tduk_hthread_sync_currpc(thr);\n\t\told_pc = act->curr_pc;\n\t\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\n\t\t/* Short circuit if is safe: if act->curr_pc != NULL, 'fun' is\n\t\t * guaranteed to be a non-NULL ECMAScript function.\n\t\t */\n\t\tDUK_ASSERT(act->curr_pc == NULL ||\n\t\t           (fun != NULL && DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun)));\n\t\tif (use_prev_pc &&\n\t\t    act->curr_pc != NULL &&\n\t\t    act->curr_pc > DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, fun)) {\n\t\t\tact->curr_pc--;\n\t\t}\n\t}\n\n\t/* Process debug messages until we are no longer paused. */\n\n\t/* NOTE: This is a bit fragile.  It's important to ensure that\n\t * duk_debug_process_messages() never throws an error or\n\t * act->curr_pc will never be reset.\n\t */\n\n\tthr->heap->dbg_state_dirty = 1;\n\twhile (DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap)) {\n\t\tDUK_ASSERT(duk_debug_is_attached(thr->heap));\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\t\tduk_debug_process_messages(thr, 0 /*no_block*/);\n\t}\n\n\t/* XXX: Decrementing and restoring act->curr_pc works now, but if the\n\t * debugger message loop gains the ability to adjust the current PC\n\t * (e.g. a forced jump) restoring the PC here will break.  Another\n\t * approach would be to use a state flag for the \"decrement 1 from\n\t * topmost activation's PC\" and take it into account whenever dealing\n\t * with PC values.\n\t */\n\tif (act != NULL) {\n\t\tact->curr_pc = old_pc;  /* restore PC */\n\t}\n}\n\n/*\n *  Breakpoint management\n */\n\nDUK_INTERNAL duk_small_int_t duk_debug_add_breakpoint(duk_hthread *thr, duk_hstring *filename, duk_uint32_t line) {\n\tduk_heap *heap;\n\tduk_breakpoint *b;\n\n\t/* Caller must trigger recomputation of active breakpoint list.  To\n\t * ensure stale values are not used if that doesn't happen, clear the\n\t * active breakpoint list here.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(filename != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_breakpoint_count >= DUK_HEAP_MAX_BREAKPOINTS) {\n\t\tDUK_D(DUK_DPRINT(\"failed to add breakpoint for %O:%ld, all breakpoint slots used\",\n\t\t                 (duk_heaphdr *) filename, (long) line));\n\t\treturn -1;\n\t}\n\theap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;\n\tb = heap->dbg_breakpoints + (heap->dbg_breakpoint_count++);\n\tb->filename = filename;\n\tb->line = line;\n\tDUK_HSTRING_INCREF(thr, filename);\n\n\treturn (duk_small_int_t) (heap->dbg_breakpoint_count - 1);  /* index */\n}\n\nDUK_INTERNAL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_small_uint_t breakpoint_index) {\n\tduk_heap *heap;\n\tduk_hstring *h;\n\tduk_breakpoint *b;\n\tduk_size_t move_size;\n\n\t/* Caller must trigger recomputation of active breakpoint list.  To\n\t * ensure stale values are not used if that doesn't happen, clear the\n\t * active breakpoint list here.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(duk_debug_is_attached(thr->heap));\n\tDUK_ASSERT_DISABLE(breakpoint_index >= 0);  /* unsigned */\n\n\tif (breakpoint_index >= heap->dbg_breakpoint_count) {\n\t\tDUK_D(DUK_DPRINT(\"invalid breakpoint index: %ld\", (long) breakpoint_index));\n\t\treturn 0;\n\t}\n\tb = heap->dbg_breakpoints + breakpoint_index;\n\n\th = b->filename;\n\tDUK_ASSERT(h != NULL);\n\n\tmove_size = sizeof(duk_breakpoint) * (heap->dbg_breakpoint_count - breakpoint_index - 1);\n\tduk_memmove((void *) b,\n\t            (const void *) (b + 1),\n\t            (size_t) move_size);\n\n\theap->dbg_breakpoint_count--;\n\theap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;\n\n\tDUK_HSTRING_DECREF(thr, h);  /* side effects */\n\tDUK_UNREF(h);  /* w/o refcounting */\n\n\t/* Breakpoint entries above the used area are left as garbage. */\n\n\treturn 1;\n}\n\n/*\n *  Misc state management\n */\n\nDUK_INTERNAL duk_bool_t duk_debug_is_attached(duk_heap *heap) {\n\treturn (heap->dbg_read_cb != NULL);\n}\n\nDUK_INTERNAL duk_bool_t duk_debug_is_paused(duk_heap *heap) {\n\treturn (DUK_HEAP_HAS_DEBUGGER_PAUSED(heap) != 0);\n}\n\nDUK_INTERNAL void duk_debug_set_paused(duk_heap *heap) {\n\tif (duk_debug_is_paused(heap)) {\n\t\tDUK_D(DUK_DPRINT(\"trying to set paused state when already paused, ignoring\"));\n\t} else {\n\t\tDUK_HEAP_SET_DEBUGGER_PAUSED(heap);\n\t\theap->dbg_state_dirty = 1;\n\t\tduk_debug_clear_pause_state(heap);\n\t\tDUK_ASSERT(heap->ms_running == 0);  /* debugger can't be triggered within mark-and-sweep */\n\t\theap->ms_running = 2;  /* prevent mark-and-sweep, prevent refzero queueing */\n\t\theap->ms_prevent_count++;\n\t\tDUK_ASSERT(heap->ms_prevent_count != 0);  /* Wrap. */\n\t\tDUK_ASSERT(heap->heap_thread != NULL);\n\t}\n}\n\nDUK_INTERNAL void duk_debug_clear_paused(duk_heap *heap) {\n\tif (duk_debug_is_paused(heap)) {\n\t\tDUK_HEAP_CLEAR_DEBUGGER_PAUSED(heap);\n\t\theap->dbg_state_dirty = 1;\n\t\tduk_debug_clear_pause_state(heap);\n\t\tDUK_ASSERT(heap->ms_running == 2);\n\t\tDUK_ASSERT(heap->ms_prevent_count > 0);\n\t\theap->ms_prevent_count--;\n\t\theap->ms_running = 0;\n\t\tDUK_ASSERT(heap->heap_thread != NULL);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"trying to clear paused state when not paused, ignoring\"));\n\t}\n}\n\nDUK_INTERNAL void duk_debug_clear_pause_state(duk_heap *heap) {\n\theap->dbg_pause_flags = 0;\n\theap->dbg_pause_act = NULL;\n\theap->dbg_pause_startline = 0;\n}\n\n#else  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/* No debugger support. */\n\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_debugger.h",
    "content": "#if !defined(DUK_DEBUGGER_H_INCLUDED)\n#define DUK_DEBUGGER_H_INCLUDED\n\n/* Debugger protocol version is defined in the public API header. */\n\n/* Initial bytes for markers. */\n#define DUK_DBG_IB_EOM                   0x00\n#define DUK_DBG_IB_REQUEST               0x01\n#define DUK_DBG_IB_REPLY                 0x02\n#define DUK_DBG_IB_ERROR                 0x03\n#define DUK_DBG_IB_NOTIFY                0x04\n\n/* Other initial bytes. */\n#define DUK_DBG_IB_INT4                  0x10\n#define DUK_DBG_IB_STR4                  0x11\n#define DUK_DBG_IB_STR2                  0x12\n#define DUK_DBG_IB_BUF4                  0x13\n#define DUK_DBG_IB_BUF2                  0x14\n#define DUK_DBG_IB_UNUSED                0x15\n#define DUK_DBG_IB_UNDEFINED             0x16\n#define DUK_DBG_IB_NULL                  0x17\n#define DUK_DBG_IB_TRUE                  0x18\n#define DUK_DBG_IB_FALSE                 0x19\n#define DUK_DBG_IB_NUMBER                0x1a\n#define DUK_DBG_IB_OBJECT                0x1b\n#define DUK_DBG_IB_POINTER               0x1c\n#define DUK_DBG_IB_LIGHTFUNC             0x1d\n#define DUK_DBG_IB_HEAPPTR               0x1e\n/* The short string/integer initial bytes starting from 0x60 don't have\n * defines now.\n */\n\n/* Error codes. */\n#define DUK_DBG_ERR_UNKNOWN              0x00\n#define DUK_DBG_ERR_UNSUPPORTED          0x01\n#define DUK_DBG_ERR_TOOMANY              0x02\n#define DUK_DBG_ERR_NOTFOUND             0x03\n#define DUK_DBG_ERR_APPLICATION          0x04\n\n/* Commands and notifys initiated by Duktape. */\n#define DUK_DBG_CMD_STATUS               0x01\n#define DUK_DBG_CMD_UNUSED_2             0x02  /* Duktape 1.x: print notify */\n#define DUK_DBG_CMD_UNUSED_3             0x03  /* Duktape 1.x: alert notify */\n#define DUK_DBG_CMD_UNUSED_4             0x04  /* Duktape 1.x: log notify */\n#define DUK_DBG_CMD_THROW                0x05\n#define DUK_DBG_CMD_DETACHING            0x06\n#define DUK_DBG_CMD_APPNOTIFY            0x07\n\n/* Commands initiated by debug client. */\n#define DUK_DBG_CMD_BASICINFO            0x10\n#define DUK_DBG_CMD_TRIGGERSTATUS        0x11\n#define DUK_DBG_CMD_PAUSE                0x12\n#define DUK_DBG_CMD_RESUME               0x13\n#define DUK_DBG_CMD_STEPINTO             0x14\n#define DUK_DBG_CMD_STEPOVER             0x15\n#define DUK_DBG_CMD_STEPOUT              0x16\n#define DUK_DBG_CMD_LISTBREAK            0x17\n#define DUK_DBG_CMD_ADDBREAK             0x18\n#define DUK_DBG_CMD_DELBREAK             0x19\n#define DUK_DBG_CMD_GETVAR               0x1a\n#define DUK_DBG_CMD_PUTVAR               0x1b\n#define DUK_DBG_CMD_GETCALLSTACK         0x1c\n#define DUK_DBG_CMD_GETLOCALS            0x1d\n#define DUK_DBG_CMD_EVAL                 0x1e\n#define DUK_DBG_CMD_DETACH               0x1f\n#define DUK_DBG_CMD_DUMPHEAP             0x20\n#define DUK_DBG_CMD_GETBYTECODE          0x21\n#define DUK_DBG_CMD_APPREQUEST           0x22\n#define DUK_DBG_CMD_GETHEAPOBJINFO       0x23\n#define DUK_DBG_CMD_GETOBJPROPDESC       0x24\n#define DUK_DBG_CMD_GETOBJPROPDESCRANGE  0x25\n\n/* The low 8 bits map directly to duk_hobject.h DUK_PROPDESC_FLAG_xxx.\n * The remaining flags are specific to the debugger.\n */\n#define DUK_DBG_PROPFLAG_SYMBOL          (1U << 8)\n#define DUK_DBG_PROPFLAG_HIDDEN          (1U << 9)\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL_DECL void duk_debug_do_detach(duk_heap *heap);\n\nDUK_INTERNAL_DECL duk_bool_t duk_debug_read_peek(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_write_flush(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_debug_skip_bytes(duk_hthread *thr, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_skip_byte(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_size_t length);\nDUK_INTERNAL_DECL duk_uint8_t duk_debug_read_byte(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_int32_t duk_debug_read_int(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_hstring *duk_debug_read_hstring(duk_hthread *thr);\n/* XXX: exposed duk_debug_read_pointer */\n/* XXX: exposed duk_debug_read_buffer */\n/* XXX: exposed duk_debug_read_hbuffer */\n#if 0\nDUK_INTERNAL_DECL duk_heaphdr *duk_debug_read_heapptr(duk_hthread *thr);\n#endif\n#if defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL_DECL duk_heaphdr *duk_debug_read_any_ptr(duk_hthread *thr);\n#endif\nDUK_INTERNAL_DECL duk_tval *duk_debug_read_tval(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_debug_write_bytes(duk_hthread *thr, const duk_uint8_t *data, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_write_byte(duk_hthread *thr, duk_uint8_t x);\nDUK_INTERNAL_DECL void duk_debug_write_unused(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_write_undefined(duk_hthread *thr);\n#if defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL_DECL void duk_debug_write_null(duk_hthread *thr);\n#endif\nDUK_INTERNAL_DECL void duk_debug_write_boolean(duk_hthread *thr, duk_uint_t val);\nDUK_INTERNAL_DECL void duk_debug_write_int(duk_hthread *thr, duk_int32_t x);\nDUK_INTERNAL_DECL void duk_debug_write_uint(duk_hthread *thr, duk_uint32_t x);\nDUK_INTERNAL_DECL void duk_debug_write_string(duk_hthread *thr, const char *data, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_write_cstring(duk_hthread *thr, const char *data);\nDUK_INTERNAL_DECL void duk_debug_write_hstring(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_debug_write_buffer(duk_hthread *thr, const char *data, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_write_hbuffer(duk_hthread *thr, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_debug_write_pointer(duk_hthread *thr, void *ptr);\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP) || defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL_DECL void duk_debug_write_heapptr(duk_hthread *thr, duk_heaphdr *h);\n#endif\nDUK_INTERNAL_DECL void duk_debug_write_hobject(duk_hthread *thr, duk_hobject *obj);\nDUK_INTERNAL_DECL void duk_debug_write_tval(duk_hthread *thr, duk_tval *tv);\n#if 0  /* unused */\nDUK_INTERNAL_DECL void duk_debug_write_request(duk_hthread *thr, duk_small_uint_t command);\n#endif\nDUK_INTERNAL_DECL void duk_debug_write_reply(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_write_error_eom(duk_hthread *thr, duk_small_uint_t err_code, const char *msg);\nDUK_INTERNAL_DECL void duk_debug_write_notify(duk_hthread *thr, duk_small_uint_t command);\nDUK_INTERNAL_DECL void duk_debug_write_eom(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_debug_curr_line(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_send_status(duk_hthread *thr);\n#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)\nDUK_INTERNAL_DECL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal);\n#endif\n\nDUK_INTERNAL_DECL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev_pc);\nDUK_INTERNAL_DECL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t no_block);\n\nDUK_INTERNAL_DECL duk_small_int_t duk_debug_add_breakpoint(duk_hthread *thr, duk_hstring *filename, duk_uint32_t line);\nDUK_INTERNAL_DECL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_small_uint_t breakpoint_index);\n\nDUK_INTERNAL_DECL duk_bool_t duk_debug_is_attached(duk_heap *heap);\nDUK_INTERNAL_DECL duk_bool_t duk_debug_is_paused(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_debug_set_paused(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_debug_clear_paused(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_debug_clear_pause_state(duk_heap *heap);\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n#endif  /* DUK_DEBUGGER_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_error.h",
    "content": "/*\n *  Error handling macros, assertion macro, error codes.\n *\n *  There are three types of 'errors':\n *\n *    1. Ordinary errors relative to a thread, cause a longjmp, catchable.\n *    2. Fatal errors relative to a heap, cause fatal handler to be called.\n *    3. Fatal errors without context, cause the default (not heap specific)\n *       fatal handler to be called.\n *\n *  Fatal errors without context are used by debug code such as assertions.\n *  By providing a fatal error handler for a Duktape heap, user code can\n *  avoid fatal errors without context in non-debug builds.\n */\n\n#if !defined(DUK_ERROR_H_INCLUDED)\n#define DUK_ERROR_H_INCLUDED\n\n/*\n *  Error codes: defined in duktape.h\n *\n *  Error codes are used as a shorthand to throw exceptions from inside\n *  the implementation.  The appropriate ECMAScript object is constructed\n *  based on the code.  ECMAScript code throws objects directly.  The error\n *  codes are defined in the public API header because they are also used\n *  by calling code.\n */\n\n/*\n *  Normal error\n *\n *  Normal error is thrown with a longjmp() through the current setjmp()\n *  catchpoint record in the duk_heap.  The 'curr_thread' of the duk_heap\n *  identifies the throwing thread.\n *\n *  Error formatting is usually unnecessary.  The error macros provide a\n *  zero argument version (no formatting) and separate macros for small\n *  argument counts.  Variadic macros are not used to avoid portability\n *  issues and avoid the need for stash-based workarounds when they're not\n *  available.  Vararg calls are avoided for non-formatted error calls\n *  because vararg call sites are larger than normal, and there are a lot\n *  of call sites with no formatting.\n *\n *  Note that special formatting provided by debug macros is NOT available.\n *\n *  The _RAW variants allow the caller to specify file and line.  This makes\n *  it easier to write checked calls which want to use the call site of the\n *  checked function, not the error macro call inside the checked function.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\n/* Because there are quite many call sites, pack error code (require at most\n * 8-bit) into a single argument.\n */\n#define DUK_ERROR(thr,err,msg) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (msg)); \\\n\t} while (0)\n#define DUK_ERROR_RAW(thr,file,line,err,msg) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (msg)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT1(thr,err,fmt,arg1) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT1(thr,file,line,err,fmt,arg1) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT2(thr,err,fmt,arg1,arg2) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT2(thr,file,line,err,fmt,arg1,arg2) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT3(thr,err,fmt,arg1,arg2,arg3) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT3(thr,file,line,err,fmt,arg1,arg2,arg3) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT4(thr,err,fmt,arg1,arg2,arg3,arg4) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3), (arg4)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT4(thr,file,line,err,fmt,arg1,arg2,arg3,arg4) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3), (arg4)); \\\n\t} while (0)\n\n#else  /* DUK_USE_VERBOSE_ERRORS */\n\n#define DUK_ERROR(thr,err,msg)                    duk_err_handle_error((thr), (err))\n#define DUK_ERROR_RAW(thr,file,line,err,msg)      duk_err_handle_error((thr), (err))\n\n#define DUK_ERROR_FMT1(thr,err,fmt,arg1) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT1(thr,file,line,err,fmt,arg1) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#define DUK_ERROR_FMT2(thr,err,fmt,arg1,arg2) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT2(thr,file,line,err,fmt,arg1,arg2) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#define DUK_ERROR_FMT3(thr,err,fmt,arg1,arg2,arg3) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT3(thr,file,line,err,fmt,arg1,arg2,arg3) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#define DUK_ERROR_FMT4(thr,err,fmt,arg1,arg2,arg3,arg4) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT4(thr,file,line,err,fmt,arg1,arg2,arg3,arg4) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n/*\n *  Fatal error without context\n *\n *  The macro is an expression to make it compatible with DUK_ASSERT_EXPR().\n */\n\n#define DUK_FATAL_WITHOUT_CONTEXT(msg) \\\n\tduk_default_fatal_handler(NULL, (msg))\n\n/*\n *  Error throwing helpers\n *\n *  The goal is to provide verbose and configurable error messages.  Call\n *  sites should be clean in source code and compile to a small footprint.\n *  Small footprint is also useful for performance because small cold paths\n *  reduce code cache pressure.  Adding macros here only makes sense if there\n *  are enough call sites to get concrete benefits.\n *\n *  DUK_ERROR_xxx() macros are generic and can be used anywhere.\n *\n *  DUK_DCERROR_xxx() macros can only be used in Duktape/C functions where\n *  the \"return DUK_RET_xxx;\" shorthand is available for low memory targets.\n *  The DUK_DCERROR_xxx() macros always either throw or perform a\n *  'return DUK_RET_xxx' from the calling function.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n/* Verbose errors with key/value summaries (non-paranoid) or without key/value\n * summaries (paranoid, for some security sensitive environments), the paranoid\n * vs. non-paranoid distinction affects only a few specific errors.\n */\n#if defined(DUK_USE_PARANOID_ERRORS)\n#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \\\n\t\tduk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx), (expectname)); \\\n\t} while (0)\n#else  /* DUK_USE_PARANOID_ERRORS */\n#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \\\n\t\tduk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx), (expectname)); \\\n\t} while (0)\n#endif  /* DUK_USE_PARANOID_ERRORS */\n\n#define DUK_ERROR_INTERNAL(thr) do { \\\n\t\tduk_err_error_internal((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_INTERNAL(thr) do { \\\n\t\tDUK_ERROR_INTERNAL((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_ALLOC_FAILED(thr) do { \\\n\t\tduk_err_error_alloc_failed((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_ERROR_UNSUPPORTED(thr) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_ERROR, DUK_STR_UNSUPPORTED); \\\n\t} while (0)\n#define DUK_DCERROR_UNSUPPORTED(thr) do { \\\n\t\tDUK_ERROR_UNSUPPORTED((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_ERROR(thr,msg) do { \\\n\t\tduk_err_error((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INDEX(thr,idx) do { \\\n\t\tduk_err_range_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) do { \\\n\t\tduk_err_range_push_beyond((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tDUK_ERROR_RANGE((thr), DUK_STR_INVALID_ARGS); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tDUK_ERROR_RANGE_INVALID_ARGS((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tDUK_ERROR_RANGE((thr), DUK_STR_INVALID_COUNT); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tDUK_ERROR_RANGE_INVALID_COUNT((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tDUK_ERROR_RANGE((thr), DUK_STR_INVALID_LENGTH); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tDUK_ERROR_RANGE_INVALID_LENGTH((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_RANGE(thr,msg) do { \\\n\t\tduk_err_range((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_EVAL(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_EVAL_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_REFERENCE(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_REFERENCE_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_SYNTAX(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_SYNTAX_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tduk_err_type_invalid_args((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tDUK_ERROR_TYPE_INVALID_ARGS((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tduk_err_type_invalid_state((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tDUK_ERROR_TYPE_INVALID_STATE((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tduk_err_type_invalid_trap_result((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tDUK_ERROR_TYPE((thr), DUK_STR_INVALID_TRAP_RESULT); \\\n\t} while (0)\n#define DUK_ERROR_TYPE(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_TYPE_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_URI(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_URI_ERROR, (msg)); \\\n\t} while (0)\n#else  /* DUK_USE_VERBOSE_ERRORS */\n/* Non-verbose errors for low memory targets: no file, line, or message. */\n\n#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n\n#define DUK_ERROR_INTERNAL(thr) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_INTERNAL(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_ALLOC_FAILED(thr) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_ERROR_UNSUPPORTED(thr) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_UNSUPPORTED(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_ERROR(thr,msg) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INDEX(thr,idx) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_RANGE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_RANGE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_RANGE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_RANGE(thr,msg) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_ERROR_EVAL(thr,msg) do { \\\n\t\tduk_err_eval((thr)); \\\n\t} while (0)\n#define DUK_ERROR_REFERENCE(thr,msg) do { \\\n\t\tduk_err_reference((thr)); \\\n\t} while (0)\n#define DUK_ERROR_SYNTAX(thr,msg) do { \\\n\t\tduk_err_syntax((thr)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_TYPE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_TYPE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE(thr,msg) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_ERROR_URI(thr,msg) do { \\\n\t\tduk_err_uri((thr)); \\\n\t} while (0)\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n/*\n *  Assert macro: failure causes a fatal error.\n *\n *  NOTE: since the assert macro doesn't take a heap/context argument, there's\n *  no way to look up a heap/context specific fatal error handler which may have\n *  been given by the application.  Instead, assertion failures always use the\n *  internal default fatal error handler; it can be replaced via duk_config.h\n *  and then applies to all Duktape heaps.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n\n/* The message should be a compile time constant without formatting (less risk);\n * we don't care about assertion text size because they're not used in production\n * builds.\n */\n#define DUK_ASSERT(x)  do { \\\n\tif (!(x)) { \\\n\t\tDUK_FATAL_WITHOUT_CONTEXT(\"assertion failed: \" #x \\\n\t\t\t\" (\" DUK_FILE_MACRO \":\" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) \")\"); \\\n\t} \\\n\t} while (0)\n\n/* Assertion compatible inside a comma expression, evaluates to void. */\n#define DUK_ASSERT_EXPR(x) \\\n\t((void) ((x) ? 0 : (DUK_FATAL_WITHOUT_CONTEXT(\"assertion failed: \" #x \\\n\t\t\t\t\" (\" DUK_FILE_MACRO \":\" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) \")\"), 0)))\n\n#else  /* DUK_USE_ASSERTIONS */\n\n#define DUK_ASSERT(x)  do { /* assertion omitted */ } while (0)\n\n#define DUK_ASSERT_EXPR(x)  ((void) 0)\n\n#endif  /* DUK_USE_ASSERTIONS */\n\n/* this variant is used when an assert would generate a compile warning by\n * being always true (e.g. >= 0 comparison for an unsigned value\n */\n#define DUK_ASSERT_DISABLE(x)  do { /* assertion disabled */ } while (0)\n\n/*\n *  Assertion helpers\n */\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h)  do { \\\n\t\tDUK_ASSERT((h) == NULL || DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) (h)) > 0); \\\n\t} while (0)\n#define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv)  do { \\\n\t\tif ((tv) != NULL && DUK_TVAL_IS_HEAP_ALLOCATED((tv))) { \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(DUK_TVAL_GET_HEAPHDR((tv))) > 0); \\\n\t\t} \\\n\t} while (0)\n#else\n#define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h)  /* no refcount check */\n#define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv)    /* no refcount check */\n#endif\n\n#define DUK_ASSERT_TOP(ctx,n)  DUK_ASSERT((duk_idx_t) duk_get_top((ctx)) == (duk_idx_t) (n))\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_PACKED_TVAL)\n#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval)  do { \\\n\t\tduk_double_union duk__assert_tmp_du; \\\n\t\tduk__assert_tmp_du.d = (dval); \\\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&duk__assert_tmp_du)); \\\n\t} while (0)\n#else\n#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval)  /* nop */\n#endif\n\n#define DUK_ASSERT_VS_SPACE(thr) \\\n\tDUK_ASSERT(thr->valstack_top < thr->valstack_end)\n\n/*\n *  Helper to initialize a memory area (e.g. struct) with garbage when\n *  assertions enabled.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n#define DUK_ASSERT_SET_GARBAGE(ptr,size) do { \\\n\t\tduk_memset_unsafe((void *) (ptr), 0x5a, size); \\\n\t} while (0)\n#else\n#define DUK_ASSERT_SET_GARBAGE(ptr,size) do {} while (0)\n#endif\n\n/*\n *  Helper for valstack space\n *\n *  Caller of DUK_ASSERT_VALSTACK_SPACE() estimates the number of free stack entries\n *  required for its own use, and any child calls which are not (a) Duktape API calls\n *  or (b) Duktape calls which involve extending the valstack (e.g. getter call).\n */\n\n#define DUK_VALSTACK_ASSERT_EXTRA  5  /* this is added to checks to allow for Duktape\n                                       * API calls in addition to function's own use\n                                       */\n#if defined(DUK_USE_ASSERTIONS)\n#define DUK_ASSERT_VALSTACK_SPACE(thr,n)   do { \\\n\t\tDUK_ASSERT((thr) != NULL); \\\n\t\tDUK_ASSERT((thr)->valstack_end - (thr)->valstack_top >= (n) + DUK_VALSTACK_ASSERT_EXTRA); \\\n\t} while (0)\n#else\n#define DUK_ASSERT_VALSTACK_SPACE(thr,n)   /* no valstack space check */\n#endif\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *msg));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error_fmt(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *fmt, ...));\n#else  /* DUK_USE_VERBOSE_ERRORS */\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error(duk_hthread *thr, duk_errcode_t code));\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code, const char *msg, const char *filename, duk_int_t line));\n#else\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code));\n#endif\n\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t rc));\n\n#define DUK_AUGMENT_FLAG_NOBLAME_FILELINE  (1U << 0)  /* if set, don't blame C file/line for .fileName and .lineNumber */\n#define DUK_AUGMENT_FLAG_SKIP_ONE          (1U << 1)  /* if set, skip topmost activation in traceback construction */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_INTERNAL_DECL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *filename, duk_int_t line, duk_small_uint_t flags);\n#endif\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\nDUK_INTERNAL_DECL void duk_err_augment_error_throw(duk_hthread *thr);\n#endif\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name));\n#else\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name));\n#endif\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error_alloc_failed(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range_push_beyond(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_args(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_state(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_trap_result(duk_hthread *thr, const char *filename, duk_int_t linenumber));\n#else  /* DUK_VERBOSE_ERRORS */\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_eval(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_reference(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_syntax(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_uri(duk_hthread *thr));\n#endif /* DUK_VERBOSE_ERRORS */\n\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_longjmp(duk_hthread *thr));\n\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_default_fatal_handler(void *udata, const char *msg));\n\nDUK_INTERNAL_DECL void duk_err_setup_ljstate1(duk_hthread *thr, duk_small_uint_t lj_type, duk_tval *tv_val);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL_DECL void duk_err_check_debugger_integration(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_errcode_t err_code);\n\n#endif  /* DUK_ERROR_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_error_augment.c",
    "content": "/*\n *  Augmenting errors at their creation site and their throw site.\n *\n *  When errors are created, traceback data is added by built-in code\n *  and a user error handler (if defined) can process or replace the\n *  error.  Similarly, when errors are thrown, a user error handler\n *  (if defined) can process or replace the error.\n *\n *  Augmentation and other processing at error creation time is nice\n *  because an error is only created once, but it may be thrown and\n *  rethrown multiple times.  User error handler registered for processing\n *  an error at its throw site must be careful to handle rethrowing in\n *  a useful manner.\n *\n *  Error augmentation may throw an internal error (e.g. alloc error).\n *\n *  ECMAScript allows throwing any values, so all values cannot be\n *  augmented.  Currently, the built-in augmentation at error creation\n *  only augments error values which are Error instances (= have the\n *  built-in Error.prototype in their prototype chain) and are also\n *  extensible.  User error handlers have no limitations in this respect.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Helper for calling a user error handler.\n *\n *  'thr' must be the currently active thread; the error handler is called\n *  in its context.  The valstack of 'thr' must have the error value on\n *  top, and will be replaced by another error value based on the return\n *  value of the error handler.\n *\n *  The helper calls duk_handle_call() recursively in protected mode.\n *  Before that call happens, no longjmps should happen; as a consequence,\n *  we must assume that the valstack contains enough temporary space for\n *  arguments and such.\n *\n *  While the error handler runs, any errors thrown will not trigger a\n *  recursive error handler call (this is implemented using a heap level\n *  flag which will \"follow\" through any coroutines resumed inside the\n *  error handler).  If the error handler is not callable or throws an\n *  error, the resulting error replaces the original error (for Duktape\n *  internal errors, duk_error_throw.c further substitutes this error with\n *  a DoubleError which is not ideal).  This would be easy to change and\n *  even signal to the caller.\n *\n *  The user error handler is stored in 'Duktape.errCreate' or\n *  'Duktape.errThrow' depending on whether we're augmenting the error at\n *  creation or throw time.  There are several alternatives to this approach,\n *  see doc/error-objects.rst for discussion.\n *\n *  Note: since further longjmp()s may occur while calling the error handler\n *  (for many reasons, e.g. a labeled 'break' inside the handler), the\n *  caller can make no assumptions on the thr->heap->lj state after the\n *  call (this affects especially duk_error_throw.c).  This is not an issue\n *  as long as the caller writes to the lj state only after the error handler\n *  finishes.\n */\n\n#if defined(DUK_USE_ERRTHROW) || defined(DUK_USE_ERRCREATE)\nDUK_LOCAL void duk__err_augment_user(duk_hthread *thr, duk_small_uint_t stridx_cb) {\n\tduk_tval *tv_hnd;\n\tduk_int_t rc;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT_STRIDX_VALID(stridx_cb);\n\n\tif (thr->heap->augmenting_error) {\n\t\tDUK_D(DUK_DPRINT(\"recursive call to error augmentation, ignore\"));\n\t\treturn;\n\t}\n\n\t/*\n\t *  Check whether or not we have an error handler.\n\t *\n\t *  We must be careful of not triggering an error when looking up the\n\t *  property.  For instance, if the property is a getter, we don't want\n\t *  to call it, only plain values are allowed.  The value, if it exists,\n\t *  is not checked.  If the value is not a function, a TypeError happens\n\t *  when it is called and that error replaces the original one.\n\t */\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, 4);  /* 3 entries actually needed below */\n\n\t/* [ ... errval ] */\n\n\tif (thr->builtins[DUK_BIDX_DUKTAPE] == NULL) {\n\t\t/* When creating built-ins, some of the built-ins may not be set\n\t\t * and we want to tolerate that when throwing errors.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"error occurred when DUK_BIDX_DUKTAPE is NULL, ignoring\"));\n\t\treturn;\n\t}\n\ttv_hnd = duk_hobject_find_entry_tval_ptr_stridx(thr->heap,\n\t                                                thr->builtins[DUK_BIDX_DUKTAPE],\n\t                                                stridx_cb);\n\tif (tv_hnd == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"error handler does not exist or is not a plain value: %!T\",\n\t\t                   (duk_tval *) tv_hnd));\n\t\treturn;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"error handler dump (callability not checked): %!T\",\n\t                     (duk_tval *) tv_hnd));\n\tduk_push_tval(thr, tv_hnd);\n\n\t/* [ ... errval errhandler ] */\n\n\tduk_insert(thr, -2);  /* -> [ ... errhandler errval ] */\n\tduk_push_undefined(thr);\n\tduk_insert(thr, -2);  /* -> [ ... errhandler undefined(= this) errval ] */\n\n\t/* [ ... errhandler undefined errval ] */\n\n\t/*\n\t *  heap->augmenting_error prevents recursive re-entry and also causes\n\t *  call handling to use a larger (but not unbounded) call stack limit\n\t *  for the duration of error augmentation.\n\t *\n\t *  We ignore errors now: a success return and an error value both\n\t *  replace the original error value.  (This would be easy to change.)\n\t */\n\n\tDUK_ASSERT(thr->heap->augmenting_error == 0);\n\tthr->heap->augmenting_error = 1;\n\n\trc = duk_pcall_method(thr, 1);\n\tDUK_UNREF(rc);  /* no need to check now: both success and error are OK */\n\n\tDUK_ASSERT(thr->heap->augmenting_error == 1);\n\tthr->heap->augmenting_error = 0;\n\n\t/* [ ... errval ] */\n}\n#endif  /* DUK_USE_ERRTHROW || DUK_USE_ERRCREATE */\n\n/*\n *  Add ._Tracedata to an error on the stack top.\n */\n\n#if defined(DUK_USE_TRACEBACKS)\nDUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {\n\tduk_activation *act;\n\tduk_int_t depth;\n\tduk_int_t arr_size;\n\tduk_tval *tv;\n\tduk_hstring *s;\n\tduk_uint32_t u32;\n\tduk_double_t d;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr_callstack != NULL);\n\n\t/* [ ... error ] */\n\n\t/*\n\t *  The traceback format is pretty arcane in an attempt to keep it compact\n\t *  and cheap to create.  It may change arbitrarily from version to version.\n\t *  It should be decoded/accessed through version specific accessors only.\n\t *\n\t *  See doc/error-objects.rst.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"adding traceback to object: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* Preallocate array to correct size, so that we can just write out\n\t * the _Tracedata values into the array part.\n\t */\n\tact = thr->callstack_curr;\n\tdepth = DUK_USE_TRACEBACK_DEPTH;\n\tDUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX);  /* callstack limits */\n\tif (depth > (duk_int_t) thr_callstack->callstack_top) {\n\t\tdepth = (duk_int_t) thr_callstack->callstack_top;\n\t}\n\tif (depth > 0) {\n\t\tif (flags & DUK_AUGMENT_FLAG_SKIP_ONE) {\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\tact = act->parent;\n\t\t\tdepth--;\n\t\t}\n\t}\n\tarr_size = depth * 2;\n\tif (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) {\n\t\tarr_size += 2;\n\t}\n\tif (c_filename) {\n\t\t/* We need the C filename to be interned before getting the\n\t\t * array part pointer to avoid any GC interference while the\n\t\t * array part is populated.\n\t\t */\n\t\tduk_push_string(thr, c_filename);\n\t\tarr_size += 2;\n\t}\n\n\t/* XXX: Uninitialized would be OK.  Maybe add internal primitive to\n\t * push bare duk_harray with size?\n\t */\n\tDUK_D(DUK_DPRINT(\"preallocated _Tracedata to %ld items\", (long) arr_size));\n\ttv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) arr_size);\n\tduk_clear_prototype(thr, -1);\n\tDUK_ASSERT(duk_is_bare_object(thr, -1));\n\tDUK_ASSERT(arr_size == 0 || tv != NULL);\n\n\t/* Compiler SyntaxErrors (and other errors) come first, and are\n\t * blamed by default (not flagged \"noblame\").\n\t */\n\tif (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) {\n\t\ts = thr->compile_ctx->h_filename;\n\t\tDUK_TVAL_SET_STRING(tv, s);\n\t\tDUK_HSTRING_INCREF(thr, s);\n\t\ttv++;\n\n\t\tu32 = (duk_uint32_t) thr->compile_ctx->curr_token.start_line;  /* (flags<<32) + (line), flags = 0 */\n\t\tDUK_TVAL_SET_U32(tv, u32);\n\t\ttv++;\n\t}\n\n\t/* Filename/line from C macros (__FILE__, __LINE__) are added as an\n\t * entry with a special format: (string, number).  The number contains\n\t * the line and flags.\n\t */\n\n\t/* [ ... error c_filename? arr ] */\n\n\tif (c_filename) {\n\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(thr->valstack_top - 2));\n\t\ts = DUK_TVAL_GET_STRING(thr->valstack_top - 2);  /* interned c_filename */\n\t\tDUK_ASSERT(s != NULL);\n\t\tDUK_TVAL_SET_STRING(tv, s);\n\t\tDUK_HSTRING_INCREF(thr, s);\n\t\ttv++;\n\n\t\td = ((flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE) ? ((duk_double_t) DUK_TB_FLAG_NOBLAME_FILELINE) * DUK_DOUBLE_2TO32 : 0.0) +\n\t\t    (duk_double_t) c_line;\n\t\tDUK_TVAL_SET_DOUBLE(tv, d);\n\t\ttv++;\n\t}\n\n\t/* Traceback depth doesn't take into account the filename/line\n\t * special handling above (intentional).\n\t */\n\tfor (; depth-- > 0; act = act->parent) {\n\t\tduk_uint32_t pc;\n\t\tduk_tval *tv_src;\n\n\t\t/* [... arr] */\n\n\t\tDUK_ASSERT(act != NULL);  /* depth check above, assumes book-keeping is correct */\n\t\tDUK_ASSERT_DISABLE(act->pc >= 0);  /* unsigned */\n\n\t\t/* Add function object. */\n\t\ttv_src = &act->tv_func;  /* object (function) or lightfunc */\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_src) || DUK_TVAL_IS_LIGHTFUNC(tv_src));\n\t\tDUK_TVAL_SET_TVAL(tv, tv_src);\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\ttv++;\n\n\t\t/* Add a number containing: pc, activation flags.\n\t\t *\n\t\t * PC points to next instruction, find offending PC.  Note that\n\t\t * PC == 0 for native code.\n\t\t */\n\t\tpc = (duk_uint32_t) duk_hthread_get_act_prev_pc(thr_callstack, act);\n\t\tDUK_ASSERT_DISABLE(pc >= 0);  /* unsigned */\n\t\tDUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32);  /* assume PC is at most 32 bits and non-negative */\n\t\td = ((duk_double_t) act->flags) * DUK_DOUBLE_2TO32 + (duk_double_t) pc;\n\t\tDUK_TVAL_SET_DOUBLE(tv, d);\n\t\ttv++;\n\t}\n\n#if defined(DUK_USE_ASSERTIONS)\n\t{\n\t\tduk_harray *a;\n\t\ta = (duk_harray *) duk_known_hobject(thr, -1);\n\t\tDUK_ASSERT(a != NULL);\n\t\tDUK_ASSERT((duk_uint32_t) (tv - DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a)) == a->length);\n\t\tDUK_ASSERT(a->length == (duk_uint32_t) arr_size);\n\t\tDUK_ASSERT(duk_is_bare_object(thr, -1));\n\t}\n#endif\n\n\t/* [ ... error c_filename? arr ] */\n\n\tif (c_filename) {\n\t\tduk_remove_m2(thr);\n\t}\n\n\t/* [ ... error arr ] */\n\n\tduk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INT_TRACEDATA);  /* -> [ ... error ] */\n}\n#endif  /* DUK_USE_TRACEBACKS */\n\n/*\n *  Add .fileName and .lineNumber to an error on the stack top.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE) && !defined(DUK_USE_TRACEBACKS)\nDUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_int_t entry_top;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\n\t/*\n\t *  If tracebacks are disabled, 'fileName' and 'lineNumber' are added\n\t *  as plain own properties.  Since Error.prototype has accessors of\n\t *  the same name, we need to define own properties directly (cannot\n\t *  just use e.g. duk_put_prop_stridx).  Existing properties are not\n\t *  overwritten in case they already exist.\n\t */\n\n\tif (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) {\n\t\t/* Compiler SyntaxError (or other error) gets the primary blame.\n\t\t * Currently no flag to prevent blaming.\n\t\t */\n\t\tduk_push_uint(thr, (duk_uint_t) thr->compile_ctx->curr_token.start_line);\n\t\tduk_push_hstring(thr, thr->compile_ctx->h_filename);\n\t} else if (c_filename && (flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE) == 0) {\n\t\t/* C call site gets blamed next, unless flagged not to do so.\n\t\t * XXX: file/line is disabled in minimal builds, so disable this\n\t\t * too when appropriate.\n\t\t */\n\t\tduk_push_int(thr, c_line);\n\t\tduk_push_string(thr, c_filename);\n\t} else {\n\t\t/* Finally, blame the innermost callstack entry which has a\n\t\t * .fileName property.\n\t\t */\n\t\tduk_small_uint_t depth;\n\t\tduk_uint32_t ecma_line;\n\t\tduk_activation *act;\n\n\t\tDUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX);  /* callstack limits */\n\t\tdepth = DUK_USE_TRACEBACK_DEPTH;\n\t\tif (depth > thr_callstack->callstack_top) {\n\t\t\tdepth = thr_callstack->callstack_top;\n\t\t}\n\t\tfor (act = thr_callstack->callstack_curr; depth-- > 0; act = act->parent) {\n\t\t\tduk_hobject *func;\n\t\t\tduk_uint32_t pc;\n\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\tfunc = DUK_ACT_GET_FUNC(act);\n\t\t\tif (func == NULL) {\n\t\t\t\t/* Lightfunc, not blamed now. */\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* PC points to next instruction, find offending PC,\n\t\t\t * PC == 0 for native code.\n\t\t\t */\n\t\t\tpc = duk_hthread_get_act_prev_pc(thr, act);  /* thr argument only used for thr->heap, so specific thread doesn't matter */\n\t\t\tDUK_UNREF(pc);\n\t\t\tDUK_ASSERT_DISABLE(pc >= 0);  /* unsigned */\n\t\t\tDUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32);  /* assume PC is at most 32 bits and non-negative */\n\n\t\t\tduk_push_hobject(thr, func);\n\n\t\t\t/* [ ... error func ] */\n\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME);\n\t\t\tif (!duk_is_string_notsymbol(thr, -1)) {\n\t\t\t\tduk_pop_2(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* [ ... error func fileName ] */\n\n\t\t\tecma_line = 0;\n#if defined(DUK_USE_PC2LINE)\n\t\t\tif (DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\t\t\tecma_line = duk_hobject_pc2line_query(thr, -2, (duk_uint_fast32_t) pc);\n\t\t\t} else {\n\t\t\t\t/* Native function, no relevant lineNumber. */\n\t\t\t}\n#endif  /* DUK_USE_PC2LINE */\n\t\t\tduk_push_u32(thr, ecma_line);\n\n\t\t\t/* [ ... error func fileName lineNumber ] */\n\n\t\t\tduk_replace(thr, -3);\n\n\t\t\t/* [ ... error lineNumber fileName ] */\n\t\t\tgoto define_props;\n\t\t}\n\n\t\t/* No activation matches, use undefined for both .fileName and\n\t\t * .lineNumber (matches what we do with a _Tracedata based\n\t\t * no-match lookup.\n\t\t */\n\t\tduk_push_undefined(thr);\n\t\tduk_push_undefined(thr);\n\t}\n\n define_props:\n\t/* [ ... error lineNumber fileName ] */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(duk_get_top(thr) == entry_top + 2);\n#endif\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LINE_NUMBER, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE);\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE && !DUK_USE_TRACEBACKS */\n\n/*\n *  Add line number to a compiler error.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_LOCAL void duk__add_compiler_error_line(duk_hthread *thr) {\n\n\t/* Append a \"(line NNN)\" to the \"message\" property of any error\n\t * thrown during compilation.  Usually compilation errors are\n\t * SyntaxErrors but they can also be out-of-memory errors and\n\t * the like.\n\t */\n\n\t/* [ ... error ] */\n\n\tDUK_ASSERT(duk_is_object(thr, -1));\n\n\tif (!(thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL)) {\n\t\treturn;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"compile error, before adding line info: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_MESSAGE)) {\n\t\tduk_push_sprintf(thr, \" (line %ld)\", (long) thr->compile_ctx->curr_token.start_line);\n\t\tduk_concat(thr, 2);\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE);\n\t} else {\n\t\tduk_pop(thr);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"compile error, after adding line info: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE */\n\n/*\n *  Augment an error being created using Duktape specific properties\n *  like _Tracedata or .fileName/.lineNumber.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_LOCAL void duk__err_augment_builtin_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_hobject *obj, duk_small_uint_t flags) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_int_t entry_top;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_UNREF(obj);  /* unreferenced w/o tracebacks */\n\n\tduk__add_compiler_error_line(thr);\n\n#if defined(DUK_USE_TRACEBACKS)\n\t/* If tracebacks are enabled, the '_Tracedata' property is the only\n\t * thing we need: 'fileName' and 'lineNumber' are virtual properties\n\t * which use '_Tracedata'.  (Check _Tracedata only as own property.)\n\t */\n\tif (duk_hobject_find_entry_tval_ptr_stridx(thr->heap, obj, DUK_STRIDX_INT_TRACEDATA) != NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"error value already has a '_Tracedata' property, not modifying it\"));\n\t} else {\n\t\tduk__add_traceback(thr, thr_callstack, c_filename, c_line, flags);\n\t}\n#else\n\t/* Without tracebacks the concrete .fileName and .lineNumber need\n\t * to be added directly.\n\t */\n\tduk__add_fileline(thr, thr_callstack, c_filename, c_line, flags);\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(duk_get_top(thr) == entry_top);\n#endif\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE */\n\n/*\n *  Augment an error at creation time with _Tracedata/fileName/lineNumber\n *  and allow a user error handler (if defined) to process/replace the error.\n *  The error to be augmented is at the stack top.\n *\n *  thr: thread containing the error value\n *  thr_callstack: thread which should be used for generating callstack etc.\n *  c_filename: C __FILE__ related to the error\n *  c_line: C __LINE__ related to the error\n *  flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE:\n *      if true, don't fileName/line as error source, otherwise use traceback\n *      (needed because user code filename/line are reported but internal ones\n *      are not)\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_INTERNAL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr_callstack != NULL);\n\n\t/* [ ... error ] */\n\n\t/*\n\t *  Criteria for augmenting:\n\t *\n\t *   - augmentation enabled in build (naturally)\n\t *   - error value internal prototype chain contains the built-in\n\t *     Error prototype object (i.e. 'val instanceof Error')\n\t *\n\t *  Additional criteria for built-in augmenting:\n\t *\n\t *   - error value is an extensible object\n\t */\n\n\tobj = duk_get_hobject(thr, -1);\n\tif (!obj) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"value is not an object, skip both built-in and user augment\"));\n\t\treturn;\n\t}\n\tif (!duk_hobject_prototype_chain_contains(thr, obj, thr->builtins[DUK_BIDX_ERROR_PROTOTYPE], 1 /*ignore_loop*/)) {\n\t\t/* If the value has a prototype loop, it's critical not to\n\t\t * throw here.  Instead, assume the value is not to be\n\t\t * augmented.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"value is not an error instance, skip both built-in and user augment\"));\n\t\treturn;\n\t}\n\tif (DUK_HOBJECT_HAS_EXTENSIBLE(obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"error meets criteria, built-in augment\"));\n\t\tduk__err_augment_builtin_create(thr, thr_callstack, c_filename, c_line, obj, flags);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"error does not meet criteria, no built-in augment\"));\n\t}\n\n\t/* [ ... error ] */\n\n#if defined(DUK_USE_ERRCREATE)\n\tduk__err_augment_user(thr, DUK_STRIDX_ERR_CREATE);\n#endif\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE */\n\n/*\n *  Augment an error at throw time; allow a user error handler (if defined)\n *  to process/replace the error.  The error to be augmented is at the\n *  stack top.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\nDUK_INTERNAL void duk_err_augment_error_throw(duk_hthread *thr) {\n#if defined(DUK_USE_ERRTHROW)\n\tduk__err_augment_user(thr, DUK_STRIDX_ERR_THROW);\n#endif  /* DUK_USE_ERRTHROW */\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_THROW */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_error_longjmp.c",
    "content": "/*\n *  Do a longjmp call, calling the fatal error handler if no\n *  catchpoint exists.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_minimal(duk_hthread *thr));\nDUK_LOCAL void duk__uncaught_minimal(duk_hthread *thr) {\n\t(void) duk_fatal(thr, \"uncaught error\");\n\tDUK_WO_NORETURN(return;);\n}\n#endif\n\n#if 0\nDUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_readable(duk_hthread *thr));\nDUK_LOCAL void duk__uncaught_readable(duk_hthread *thr) {\n\tconst char *summary;\n\tchar buf[DUK_USE_FATAL_MAXLEN];\n\n\tsummary = duk_push_string_tval_readable(thr, &thr->heap->lj.value1);\n\tDUK_SNPRINTF(buf, sizeof(buf), \"uncaught: %s\", summary);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\t(void) duk_fatal(thr, (const char *) buf);\n\tDUK_WO_NORETURN(return;);\n}\n#endif\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_error_aware(duk_hthread *thr));\nDUK_LOCAL void duk__uncaught_error_aware(duk_hthread *thr) {\n\tconst char *summary;\n\tchar buf[DUK_USE_FATAL_MAXLEN];\n\n\tsummary = duk_push_string_tval_readable_error(thr, &thr->heap->lj.value1);\n\tDUK_ASSERT(summary != NULL);\n\tDUK_SNPRINTF(buf, sizeof(buf), \"uncaught: %s\", summary);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\t(void) duk_fatal(thr, (const char *) buf);\n\tDUK_WO_NORETURN(return;);\n}\n#endif\n\nDUK_INTERNAL void duk_err_longjmp(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"longjmp error: type=%d iserror=%d value1=%!T value2=%!T\",\n\t                   (int) thr->heap->lj.type, (int) thr->heap->lj.iserror,\n\t                   &thr->heap->lj.value1, &thr->heap->lj.value2));\n\n\t/* Prevent finalizer execution during error handling.  All error\n\t * handling sites will process pending finalizers once error handling\n\t * is complete and we're ready for the side effects.  Does not prevent\n\t * refzero freeing or mark-and-sweep during error handling.\n\t *\n\t * NOTE: when we come here some calling code may have used DECREF\n\t * NORZ macros without an explicit DUK_REFZERO_CHECK_xxx() call.\n\t * We don't want to do it here because it would just check for\n\t * pending finalizers and we prevent that explicitly.  Instead,\n\t * the error catcher will run the finalizers once error handling\n\t * is complete.\n\t */\n\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\n\tthr->heap->pf_prevent_count++;\n\tDUK_ASSERT(thr->heap->pf_prevent_count != 0);  /* Wrap. */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* XXX: set this immediately when longjmp state is set */\n\tDUK_ASSERT(thr->heap->error_not_allowed == 0);  /* Detect error within critical section. */\n\tthr->heap->error_not_allowed = 1;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"about to longjmp, pf_prevent_count=%ld\", (long) thr->heap->pf_prevent_count));\n\n\t/* If we don't have a jmpbuf_ptr, there is little we can do except\n\t * cause a fatal error.  The caller's expectation is that we never\n\t * return.\n\t */\n\tif (!thr->heap->lj.jmpbuf_ptr) {\n\t\tDUK_D(DUK_DPRINT(\"uncaught error: type=%d iserror=%d value1=%!T value2=%!T\",\n\t\t                 (int) thr->heap->lj.type, (int) thr->heap->lj.iserror,\n\t\t                 &thr->heap->lj.value1, &thr->heap->lj.value2));\n\n#if defined(DUK_USE_PREFER_SIZE)\n\t\tduk__uncaught_minimal(thr);\n#else\n\t\tduk__uncaught_error_aware(thr);\n#endif\n\t\tDUK_UNREACHABLE();\n\t}\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\tthrow duk_internal_exception();  /* dummy */\n#else\n\tDUK_LONGJMP(thr->heap->lj.jmpbuf_ptr->jb);\n#endif\n\n\tDUK_UNREACHABLE();\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_error_macros.c",
    "content": "/*\n *  Error and fatal handling.\n */\n\n#include \"duk_internal.h\"\n\n#define DUK__ERRFMT_BUFSIZE  256  /* size for formatting buffers */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\nDUK_INTERNAL DUK_COLD void duk_err_handle_error_fmt(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *fmt, ...) {\n\tva_list ap;\n\tchar msg[DUK__ERRFMT_BUFSIZE];\n\tva_start(ap, fmt);\n\t(void) DUK_VSNPRINTF(msg, sizeof(msg), fmt, ap);\n\tmsg[sizeof(msg) - 1] = (char) 0;\n\tduk_err_create_and_throw(thr, (duk_errcode_t) (line_and_code >> 24), msg, filename, (duk_int_t) (line_and_code & 0x00ffffffL));\n\tva_end(ap);  /* dead code, but ensures portability (see Linux man page notes) */\n}\n\nDUK_INTERNAL DUK_COLD void duk_err_handle_error(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *msg) {\n\tduk_err_create_and_throw(thr, (duk_errcode_t) (line_and_code >> 24), msg, filename, (duk_int_t) (line_and_code & 0x00ffffffL));\n}\n\n#else  /* DUK_USE_VERBOSE_ERRORS */\n\nDUK_INTERNAL DUK_COLD void duk_err_handle_error(duk_hthread *thr, duk_errcode_t code) {\n\tduk_err_create_and_throw(thr, code);\n}\n\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n/*\n *  Error throwing helpers\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\nDUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) {\n\tDUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, \"%s required, found %s (stack index %ld)\",\n\t                   expect_name, duk_get_type_name(thr, idx), (long) idx);\n}\n#else\nDUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) {\n\tDUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, \"%s required, found %s (stack index %ld)\",\n\t                   expect_name, duk_push_string_readable(thr, idx), (long) idx);\n}\n#endif\nDUK_INTERNAL DUK_COLD void duk_err_error_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, DUK_STR_INTERNAL_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_error_alloc_failed(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, DUK_STR_ALLOC_FAILED);\n}\nDUK_INTERNAL DUK_COLD void duk_err_error(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, message);\n}\nDUK_INTERNAL DUK_COLD void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, message);\n}\nDUK_INTERNAL DUK_COLD void duk_err_range_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx) {\n\tDUK_ERROR_RAW_FMT1(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, \"invalid stack index %ld\", (long) (idx));\n}\nDUK_INTERNAL DUK_COLD void duk_err_range_push_beyond(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, DUK_STR_PUSH_BEYOND_ALLOC_STACK);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type_invalid_args(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_ARGS);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type_invalid_state(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_STATE);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type_invalid_trap_result(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_TRAP_RESULT);\n}\n#else\n/* The file/line arguments are NULL and 0, they're ignored by DUK_ERROR_RAW()\n * when non-verbose errors are used.\n */\n\nDUK_NORETURN(DUK_LOCAL_DECL void duk__err_shared(duk_hthread *thr, duk_errcode_t code));\nDUK_LOCAL void duk__err_shared(duk_hthread *thr, duk_errcode_t code) {\n\tDUK_ERROR_RAW(thr, NULL, 0, code, NULL);\n}\nDUK_INTERNAL DUK_COLD void duk_err_error(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_range(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_RANGE_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_eval(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_EVAL_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_reference(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_REFERENCE_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_syntax(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_SYNTAX_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_TYPE_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_uri(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_URI_ERROR);\n}\n#endif\n\n/*\n *  Default fatal error handler\n */\n\nDUK_INTERNAL DUK_COLD void duk_default_fatal_handler(void *udata, const char *msg) {\n\tDUK_UNREF(udata);\n\tDUK_UNREF(msg);\n\n\tmsg = msg ? msg : \"NULL\";\n\n#if defined(DUK_USE_FATAL_HANDLER)\n\t/* duk_config.h provided a custom default fatal handler. */\n\tDUK_D(DUK_DPRINT(\"custom default fatal error handler called: %s\", msg));\n\tDUK_USE_FATAL_HANDLER(udata, msg);\n#elif defined(DUK_USE_CPP_EXCEPTIONS)\n\t/* With C++ use a duk_fatal_exception which user code can catch in\n\t * a natural way.\n\t */\n\tDUK_D(DUK_DPRINT(\"built-in default C++ fatal error handler called: %s\", msg));\n\tthrow duk_fatal_exception(msg);\n#else\n\t/* Default behavior is to abort() on error.  There's no printout\n\t * which makes this awkward, so it's always recommended to use an\n\t * explicit fatal error handler.\n\t *\n\t * ====================================================================\n\t * NOTE: If you are seeing this, you are most likely dealing with an\n\t * uncaught error.  You should provide a fatal error handler in Duktape\n\t * heap creation, and should consider using a protected call as your\n\t * first call into an empty Duktape context to properly handle errors.\n\t * See:\n\t *   - http://duktape.org/guide.html#error-handling\n\t *   - http://wiki.duktape.org/HowtoFatalErrors.html\n\t *   - http://duktape.org/api.html#taglist-protected\n\t * ====================================================================\n\t */\n\tDUK_D(DUK_DPRINT(\"built-in default fatal error handler called: %s\", msg));\n\tDUK_ABORT();\n#endif\n\n\tDUK_D(DUK_DPRINT(\"fatal error handler returned, enter forever loop\"));\n\tfor (;;) {\n\t\t/* Loop forever to ensure we don't return. */\n\t}\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_error_misc.c",
    "content": "/*\n *  Error helpers\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Helper to walk the thread chain and see if there is an active error\n *  catcher.  Protected calls or finally blocks aren't considered catching.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_LOCAL duk_bool_t duk__have_active_catcher(duk_hthread *thr) {\n\t/* As noted above, a protected API call won't be counted as a\n\t * catcher.  This is usually convenient, e.g. in the case of a top-\n\t * level duk_pcall(), but may not always be desirable.  Perhaps add\n\t * an argument to treat them as catchers?\n\t */\n\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tfor (; thr != NULL; thr = thr->resumer) {\n\t\tfor (act = thr->callstack_curr; act != NULL; act = act->parent) {\n\t\t\tfor (cat = act->cat; cat != NULL; cat = cat->parent) {\n\t\t\t\tif (DUK_CAT_HAS_CATCH_ENABLED(cat)) {\n\t\t\t\t\treturn 1;  /* all we need to know */\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn 0;\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/*\n *  Get prototype object for an integer error code.\n */\n\nDUK_INTERNAL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_errcode_t code) {\n\tswitch (code) {\n\tcase DUK_ERR_EVAL_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_EVAL_ERROR_PROTOTYPE];\n\tcase DUK_ERR_RANGE_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_RANGE_ERROR_PROTOTYPE];\n\tcase DUK_ERR_REFERENCE_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_REFERENCE_ERROR_PROTOTYPE];\n\tcase DUK_ERR_SYNTAX_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_SYNTAX_ERROR_PROTOTYPE];\n\tcase DUK_ERR_TYPE_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_TYPE_ERROR_PROTOTYPE];\n\tcase DUK_ERR_URI_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_URI_ERROR_PROTOTYPE];\n\tcase DUK_ERR_ERROR:\n\tdefault:\n\t\treturn thr->builtins[DUK_BIDX_ERROR_PROTOTYPE];\n\t}\n}\n\n/*\n *  Helper for debugger throw notify and pause-on-uncaught integration.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL void duk_err_check_debugger_integration(duk_hthread *thr) {\n\tduk_bool_t uncaught;\n\tduk_tval *tv_obj;\n\n\t/* If something is thrown with the debugger attached and nobody will\n\t * catch it, execution is paused before the longjmp, turning over\n\t * control to the debug client.  This allows local state to be examined\n\t * before the stack is unwound.  Errors are not intercepted when debug\n\t * message loop is active (e.g. for Eval).\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\t/* XXX: Allow customizing the pause and notify behavior at runtime\n\t * using debugger runtime flags.  For now the behavior is fixed using\n\t * config options.\n\t */\n\n\tif (!duk_debug_is_attached(thr->heap) ||\n\t    thr->heap->dbg_processing ||\n\t    thr->heap->lj.type != DUK_LJ_TYPE_THROW ||\n\t    thr->heap->creating_error) {\n\t\tDUK_D(DUK_DPRINT(\"skip debugger error integration; not attached, debugger processing, not THROW, or error thrown while creating error\"));\n\t\treturn;\n\t}\n\n\t/* Don't intercept a DoubleError, we may have caused the initial double\n\t * fault and attempting to intercept it will cause us to be called\n\t * recursively and exhaust the C stack.  (This should no longer happen\n\t * for the initial throw because DoubleError path doesn't do a debugger\n\t * integration check, but it might happen for rethrows.)\n\t */\n\ttv_obj = &thr->heap->lj.value1;\n\tif (DUK_TVAL_IS_OBJECT(tv_obj) && DUK_TVAL_GET_OBJECT(tv_obj) == thr->builtins[DUK_BIDX_DOUBLE_ERROR]) {\n\t\tDUK_D(DUK_DPRINT(\"built-in DoubleError instance (re)thrown, not intercepting\"));\n\t\treturn;\n\t}\n\n\tuncaught = !duk__have_active_catcher(thr);\n\n\t/* Debugger code expects the value at stack top.  This also serves\n\t * as a backup: we need to store/restore the longjmp state because\n\t * when the debugger is paused Eval commands may be executed and\n\t * they can arbitrarily clobber the longjmp state.\n\t */\n\tduk_push_tval(thr, tv_obj);\n\n\t/* Store and reset longjmp state. */\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\tDUK_TVAL_DECREF_NORZ(thr, tv_obj);\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value2));  /* Always for THROW type. */\n\tDUK_TVAL_SET_UNDEFINED(tv_obj);\n\tthr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)\n\t/* Report it to the debug client */\n\tDUK_D(DUK_DPRINT(\"throw with debugger attached, report to client\"));\n\tduk_debug_send_throw(thr, uncaught);\n#endif\n\n\tif (uncaught) {\n\t\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_UNCAUGHT_ERROR) {\n\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by uncaught error\"));\n\t\t\tduk_debug_halt_execution(thr, 1 /*use_prev_pc*/);\n\t\t}\n\t} else {\n\t\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_CAUGHT_ERROR) {\n\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by caught error\"));\n\t\t\tduk_debug_halt_execution(thr, 1 /*use_prev_pc*/);\n\t\t}\n\t}\n\n\t/* Restore longjmp state. */\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\tthr->heap->lj.type = DUK_LJ_TYPE_THROW;\n\ttv_obj = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value1));\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value2));\n\tDUK_TVAL_SET_TVAL(&thr->heap->lj.value1, tv_obj);\n\tDUK_TVAL_INCREF(thr, tv_obj);\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\n\tduk_pop(thr);\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/*\n *  Helpers for setting up heap longjmp state.\n */\n\nDUK_INTERNAL void duk_err_setup_ljstate1(duk_hthread *thr, duk_small_uint_t lj_type, duk_tval *tv_val) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(tv_val != NULL);\n\n\tDUK_ASSERT_LJSTATE_UNSET(heap);\n\n\theap->lj.type = lj_type;\n\tDUK_TVAL_SET_TVAL(&heap->lj.value1, tv_val);\n\tDUK_TVAL_INCREF(thr, tv_val);\n\n\tDUK_ASSERT_LJSTATE_SET(heap);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_error_throw.c",
    "content": "/*\n *  Create and throw an ECMAScript error object based on a code and a message.\n *\n *  Used when we throw errors internally.  ECMAScript generated error objects\n *  are created by ECMAScript code, and the throwing is handled by the bytecode\n *  executor.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Create and throw an error (originating from Duktape internally)\n *\n *  Push an error object on top of the stack, possibly throw augmenting\n *  the error, and finally longjmp.\n *\n *  If an error occurs while we're dealing with the current error, we might\n *  enter an infinite recursion loop.  This is prevented by detecting a\n *  \"double fault\" through the heap->creating_error flag; the recursion\n *  then stops at the second level.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code, const char *msg, const char *filename, duk_int_t line) {\n#else\nDUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code) {\n#endif\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\tDUK_DD(DUK_DDPRINT(\"duk_err_create_and_throw(): code=%ld, msg=%s, filename=%s, line=%ld\",\n\t                   (long) code, (const char *) msg,\n\t                   (const char *) filename, (long) line));\n#else\n\tDUK_DD(DUK_DDPRINT(\"duk_err_create_and_throw(): code=%ld\", (long) code));\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Even though nested call is possible because we throw an error when\n\t * trying to create an error, the potential errors must happen before\n\t * the longjmp state is configured.\n\t */\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\t/* Sync so that augmentation sees up-to-date activations, NULL\n\t * thr->ptr_curr_pc so that it's not used if side effects occur\n\t * in augmentation or longjmp handling.\n\t */\n\tduk_hthread_sync_and_null_currpc(thr);\n\n\t/*\n\t *  Create and push an error object onto the top of stack.\n\t *  The error is potentially augmented before throwing.\n\t *\n\t *  If a \"double error\" occurs, use a fixed error instance\n\t *  to avoid further trouble.\n\t */\n\n\tif (thr->heap->creating_error) {\n\t\tduk_tval tv_val;\n\t\tduk_hobject *h_err;\n\n\t\tthr->heap->creating_error = 0;\n\n\t\th_err = thr->builtins[DUK_BIDX_DOUBLE_ERROR];\n\t\tif (h_err != NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"double fault detected -> use built-in fixed 'double error' instance\"));\n\t\t\tDUK_TVAL_SET_OBJECT(&tv_val, h_err);\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"double fault detected; there is no built-in fixed 'double error' instance \"\n\t\t\t                 \"-> use the error code as a number\"));\n\t\t\tDUK_TVAL_SET_I32(&tv_val, (duk_int32_t) code);\n\t\t}\n\n\t\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, &tv_val);\n\n\t\t/* No augmentation to avoid any allocations or side effects. */\n\t} else {\n\t\t/* Prevent infinite recursion.  Extra call stack and C\n\t\t * recursion headroom (see GH-191) is added for augmentation.\n\t\t * That is now signalled by heap->augmenting error and taken\n\t\t * into account in call handling without an explicit limit bump.\n\t\t */\n\t\tthr->heap->creating_error = 1;\n\n\t\tduk_require_stack(thr, 1);\n\n\t\t/* XXX: usually unnecessary '%s' formatting here, but cannot\n\t\t * use 'msg' as a format string directly.\n\t\t */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\tduk_push_error_object_raw(thr,\n\t\t                          code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t\t                          filename,\n\t\t                          line,\n\t\t                          \"%s\",\n\t\t                          (const char *) msg);\n#else\n\t\tduk_push_error_object_raw(thr,\n\t\t                          code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t\t                          NULL,\n\t\t                          0,\n\t\t                          NULL);\n#endif\n\n\t\t/* Note that an alloc error may happen during error augmentation.\n\t\t * This may happen both when the original error is an alloc error\n\t\t * and when it's something else.  Because any error in augmentation\n\t\t * must be handled correctly anyway, there's no special check for\n\t\t * avoiding it for alloc errors (this differs from Duktape 1.x).\n\t\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\t\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (INTERNAL): %!iT (before throw augment)\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\tduk_err_augment_error_throw(thr);\n#endif\n\n\t\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, DUK_GET_TVAL_NEGIDX(thr, -1));\n\t\tthr->heap->creating_error = 0;\n\n\t\t/* Error is now created and we assume no errors can occur any\n\t\t * more.  Check for debugger Throw integration only when the\n\t\t * error is complete.  If we enter debugger message loop,\n\t\t * creating_error must be 0 so that errors can be thrown in\n\t\t * the paused state, e.g. in Eval commands.\n\t\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tduk_err_check_debugger_integration(thr);\n#endif\n\t}\n\n\t/*\n\t *  Finally, longjmp\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (INTERNAL): %!iT, %!iT (after throw augment)\",\n\t                     (duk_tval *) &thr->heap->lj.value1, (duk_tval *) &thr->heap->lj.value2));\n\n\tduk_err_longjmp(thr);\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  Helper for C function call negative return values.\n */\n\nDUK_INTERNAL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t rc) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(rc < 0);\n\n\t/*\n\t *  The __FILE__ and __LINE__ information is intentionally not used in the\n\t *  creation of the error object, as it isn't useful in the tracedata.  The\n\t *  tracedata still contains the function which returned the negative return\n\t *  code, and having the file/line of this function isn't very useful.\n\t *\n\t *  The error messages for DUK_RET_xxx shorthand are intentionally very\n\t *  minimal: they're only really useful for low memory targets.\n\t */\n\n\tduk_error_raw(thr, -rc, NULL, 0, \"error (rc %ld)\", (long) rc);\n\tDUK_WO_NORETURN(return;);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_exception.h",
    "content": "/*\n *  Exceptions for Duktape internal throws when C++ exceptions are used\n *  for long control transfers.\n */\n\n#if !defined(DUK_EXCEPTION_H_INCLUDED)\n#define DUK_EXCEPTION_H_INCLUDED\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n/* Internal exception used as a setjmp-longjmp replacement.  User code should\n * NEVER see or catch this exception, so it doesn't inherit from any base\n * class which should minimize the chance of user code accidentally catching\n * the exception.\n */\nclass duk_internal_exception {\n\t/* intentionally empty */\n};\n\n/* Fatal error, thrown as a specific C++ exception with C++ exceptions\n * enabled.  It is unsafe to continue; doing so may cause crashes or memory\n * leaks.  This is intended to be either uncaught, or caught by user code\n * aware of the \"unsafe to continue\" semantics.\n */\nclass duk_fatal_exception : public virtual std::runtime_error {\n public:\n\tduk_fatal_exception(const char *message) : std::runtime_error(message) {}\n};\n#endif\n\n#endif  /* DUK_EXCEPTION_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_forwdecl.h",
    "content": "/*\n *  Forward declarations for all Duktape structures.\n */\n\n#if !defined(DUK_FORWDECL_H_INCLUDED)\n#define DUK_FORWDECL_H_INCLUDED\n\n/*\n *  Forward declarations\n */\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\nclass duk_internal_exception;\n#else\nstruct duk_jmpbuf;\n#endif\n\n/* duk_tval intentionally skipped */\nstruct duk_heaphdr;\nstruct duk_heaphdr_string;\nstruct duk_harray;\nstruct duk_hstring;\nstruct duk_hstring_external;\nstruct duk_hobject;\nstruct duk_hcompfunc;\nstruct duk_hnatfunc;\nstruct duk_hboundfunc;\nstruct duk_hthread;\nstruct duk_hbufobj;\nstruct duk_hdecenv;\nstruct duk_hobjenv;\nstruct duk_hproxy;\nstruct duk_hbuffer;\nstruct duk_hbuffer_fixed;\nstruct duk_hbuffer_dynamic;\nstruct duk_hbuffer_external;\n\nstruct duk_propaccessor;\nunion duk_propvalue;\nstruct duk_propdesc;\n\nstruct duk_heap;\nstruct duk_breakpoint;\n\nstruct duk_activation;\nstruct duk_catcher;\nstruct duk_ljstate;\nstruct duk_strcache_entry;\nstruct duk_litcache_entry;\nstruct duk_strtab_entry;\n\n#if defined(DUK_USE_DEBUG)\nstruct duk_fixedbuffer;\n#endif\n\nstruct duk_bitdecoder_ctx;\nstruct duk_bitencoder_ctx;\nstruct duk_bufwriter_ctx;\n\nstruct duk_token;\nstruct duk_re_token;\nstruct duk_lexer_point;\nstruct duk_lexer_ctx;\nstruct duk_lexer_codepoint;\n\nstruct duk_compiler_instr;\nstruct duk_compiler_func;\nstruct duk_compiler_ctx;\n\nstruct duk_re_matcher_ctx;\nstruct duk_re_compiler_ctx;\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n/* no typedef */\n#else\ntypedef struct duk_jmpbuf duk_jmpbuf;\n#endif\n\n/* duk_tval intentionally skipped */\ntypedef struct duk_heaphdr duk_heaphdr;\ntypedef struct duk_heaphdr_string duk_heaphdr_string;\ntypedef struct duk_harray duk_harray;\ntypedef struct duk_hstring duk_hstring;\ntypedef struct duk_hstring_external duk_hstring_external;\ntypedef struct duk_hobject duk_hobject;\ntypedef struct duk_hcompfunc duk_hcompfunc;\ntypedef struct duk_hnatfunc duk_hnatfunc;\ntypedef struct duk_hboundfunc duk_hboundfunc;\ntypedef struct duk_hthread duk_hthread;\ntypedef struct duk_hbufobj duk_hbufobj;\ntypedef struct duk_hdecenv duk_hdecenv;\ntypedef struct duk_hobjenv duk_hobjenv;\ntypedef struct duk_hproxy duk_hproxy;\ntypedef struct duk_hbuffer duk_hbuffer;\ntypedef struct duk_hbuffer_fixed duk_hbuffer_fixed;\ntypedef struct duk_hbuffer_dynamic duk_hbuffer_dynamic;\ntypedef struct duk_hbuffer_external duk_hbuffer_external;\n\ntypedef struct duk_propaccessor duk_propaccessor;\ntypedef union duk_propvalue duk_propvalue;\ntypedef struct duk_propdesc duk_propdesc;\n\ntypedef struct duk_heap duk_heap;\ntypedef struct duk_breakpoint duk_breakpoint;\n\ntypedef struct duk_activation duk_activation;\ntypedef struct duk_catcher duk_catcher;\ntypedef struct duk_ljstate duk_ljstate;\ntypedef struct duk_strcache_entry duk_strcache_entry;\ntypedef struct duk_litcache_entry duk_litcache_entry;\ntypedef struct duk_strtab_entry duk_strtab_entry;\n\n#if defined(DUK_USE_DEBUG)\ntypedef struct duk_fixedbuffer duk_fixedbuffer;\n#endif\n\ntypedef struct duk_bitdecoder_ctx duk_bitdecoder_ctx;\ntypedef struct duk_bitencoder_ctx duk_bitencoder_ctx;\ntypedef struct duk_bufwriter_ctx duk_bufwriter_ctx;\n\ntypedef struct duk_token duk_token;\ntypedef struct duk_re_token duk_re_token;\ntypedef struct duk_lexer_point duk_lexer_point;\ntypedef struct duk_lexer_ctx duk_lexer_ctx;\ntypedef struct duk_lexer_codepoint duk_lexer_codepoint;\n\ntypedef struct duk_compiler_instr duk_compiler_instr;\ntypedef struct duk_compiler_func duk_compiler_func;\ntypedef struct duk_compiler_ctx duk_compiler_ctx;\n\ntypedef struct duk_re_matcher_ctx duk_re_matcher_ctx;\ntypedef struct duk_re_compiler_ctx duk_re_compiler_ctx;\n\n#endif  /* DUK_FORWDECL_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_harray.h",
    "content": "/*\n *  Array object representation, used for actual Array instances.\n *\n *  All objects with the exotic array behavior (which must coincide with having\n *  internal class array) MUST be duk_harrays.  No other object can be a\n *  duk_harray.  However, duk_harrays may not always have an array part.\n */\n\n#if !defined(DUK_HARRAY_H_INCLUDED)\n#define DUK_HARRAY_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_harray_assert_valid(duk_harray *h);\n#define DUK_HARRAY_ASSERT_VALID(h)  do { duk_harray_assert_valid((h)); } while (0)\n#else\n#define DUK_HARRAY_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n#define DUK_HARRAY_LENGTH_WRITABLE(h)         (!(h)->length_nonwritable)\n#define DUK_HARRAY_LENGTH_NONWRITABLE(h)      ((h)->length_nonwritable)\n#define DUK_HARRAY_SET_LENGTH_WRITABLE(h)     do { (h)->length_nonwritable = 0; } while (0)\n#define DUK_HARRAY_SET_LENGTH_NONWRITABLE(h)  do { (h)->length_nonwritable = 1; } while (0)\n\nstruct duk_harray {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Array .length.\n\t *\n\t * At present Array .length may be smaller, equal, or even larger\n\t * than the allocated underlying array part.  Fast path code must\n\t * always take this into account carefully.\n\t */\n\tduk_uint32_t length;\n\n\t/* Array .length property attributes.  The property is always\n\t * non-enumerable and non-configurable.  It's initially writable\n\t * but per Object.defineProperty() rules it can be made non-writable\n\t * even if it is non-configurable.  Thus we need to track the\n\t * writability explicitly.\n\t *\n\t * XXX: this field to be eliminated and moved into duk_hobject\n\t * flags field to save space.\n\t */\n\tduk_bool_t length_nonwritable;\n};\n\n#endif  /* DUK_HARRAY_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hboundfunc.h",
    "content": "/*\n *  Bound function representation.\n */\n\n#if !defined(DUK_HBOUNDFUNC_H_INCLUDED)\n#define DUK_HBOUNDFUNC_H_INCLUDED\n\n/* Artificial limit for args length.  Ensures arithmetic won't overflow\n * 32 bits when combining bound functions.\n */\n#define DUK_HBOUNDFUNC_MAX_ARGS 0x20000000UL\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hboundfunc_assert_valid(duk_hboundfunc *h);\n#define DUK_HBOUNDFUNC_ASSERT_VALID(h)  do { duk_hboundfunc_assert_valid((h)); } while (0)\n#else\n#define DUK_HBOUNDFUNC_ASSERT_VALID(h)  do {} while (0)\n#endif\n\nstruct duk_hboundfunc {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Final target function, stored as duk_tval so that lightfunc can be\n\t * represented too.\n\t */\n\tduk_tval target;\n\n\t/* This binding. */\n\tduk_tval this_binding;\n\n\t/* Arguments to prepend. */\n\tduk_tval *args;  /* Separate allocation. */\n\tduk_idx_t nargs;\n};\n\n#endif  /* DUK_HBOUNDFUNC_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hbuffer.h",
    "content": "/*\n *  Heap buffer representation.\n *\n *  Heap allocated user data buffer which is either:\n *\n *    1. A fixed size buffer (data follows header statically)\n *    2. A dynamic size buffer (data pointer follows header)\n *\n *  The data pointer for a variable size buffer of zero size may be NULL.\n */\n\n#if !defined(DUK_HBUFFER_H_INCLUDED)\n#define DUK_HBUFFER_H_INCLUDED\n\n/*\n *  Flags\n *\n *  Fixed buffer:     0\n *  Dynamic buffer:   DUK_HBUFFER_FLAG_DYNAMIC\n *  External buffer:  DUK_HBUFFER_FLAG_DYNAMIC | DUK_HBUFFER_FLAG_EXTERNAL\n */\n\n#define DUK_HBUFFER_FLAG_DYNAMIC                  DUK_HEAPHDR_USER_FLAG(0)    /* buffer is behind a pointer, dynamic or external */\n#define DUK_HBUFFER_FLAG_EXTERNAL                 DUK_HEAPHDR_USER_FLAG(1)    /* buffer pointer is to an externally allocated buffer */\n\n#define DUK_HBUFFER_HAS_DYNAMIC(x)                DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)\n#define DUK_HBUFFER_HAS_EXTERNAL(x)               DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL)\n\n#define DUK_HBUFFER_SET_DYNAMIC(x)                DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)\n#define DUK_HBUFFER_SET_EXTERNAL(x)               DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL)\n\n#define DUK_HBUFFER_CLEAR_DYNAMIC(x)              DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)\n#define DUK_HBUFFER_CLEAR_EXTERNAL(x)             DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL)\n\n/*\n *  Misc defines\n */\n\n/* Impose a maximum buffer length for now.  Restricted artificially to\n * ensure resize computations or adding a heap header length won't\n * overflow size_t and that a signed duk_int_t can hold a buffer\n * length.  The limit should be synchronized with DUK_HSTRING_MAX_BYTELEN.\n */\n\n#if defined(DUK_USE_BUFLEN16)\n#define DUK_HBUFFER_MAX_BYTELEN                   (0x0000ffffUL)\n#else\n/* Intentionally not 0x7fffffffUL; at least JSON code expects that\n * 2*len + 2 fits in 32 bits.\n */\n#define DUK_HBUFFER_MAX_BYTELEN                   (0x7ffffffeUL)\n#endif\n\n/*\n *  Field access\n */\n\n#if defined(DUK_USE_BUFLEN16)\n/* size stored in duk_heaphdr unused flag bits */\n#define DUK_HBUFFER_GET_SIZE(x)     ((x)->hdr.h_flags >> 16)\n#define DUK_HBUFFER_SET_SIZE(x,v)   do { \\\n\t\tduk_size_t duk__v; \\\n\t\tduk__v = (v); \\\n\t\tDUK_ASSERT(duk__v <= 0xffffUL); \\\n\t\t(x)->hdr.h_flags = ((x)->hdr.h_flags & 0x0000ffffUL) | (((duk_uint32_t) duk__v) << 16); \\\n\t} while (0)\n#define DUK_HBUFFER_ADD_SIZE(x,dv)  do { \\\n\t\t(x)->hdr.h_flags += ((dv) << 16); \\\n\t} while (0)\n#define DUK_HBUFFER_SUB_SIZE(x,dv)  do { \\\n\t\t(x)->hdr.h_flags -= ((dv) << 16); \\\n\t} while (0)\n#else\n#define DUK_HBUFFER_GET_SIZE(x)     (((duk_hbuffer *) (x))->size)\n#define DUK_HBUFFER_SET_SIZE(x,v)   do { \\\n\t\t((duk_hbuffer *) (x))->size = (v); \\\n\t} while (0)\n#define DUK_HBUFFER_ADD_SIZE(x,dv)  do { \\\n\t\t(x)->size += (dv); \\\n\t} while (0)\n#define DUK_HBUFFER_SUB_SIZE(x,dv)  do { \\\n\t\t(x)->size -= (dv); \\\n\t} while (0)\n#endif\n\n#define DUK_HBUFFER_FIXED_GET_SIZE(x)       DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x))\n#define DUK_HBUFFER_FIXED_SET_SIZE(x,v)     DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x))\n\n#define DUK_HBUFFER_DYNAMIC_GET_SIZE(x)     DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x))\n#define DUK_HBUFFER_DYNAMIC_SET_SIZE(x,v)   DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x), (v))\n#define DUK_HBUFFER_DYNAMIC_ADD_SIZE(x,dv)  DUK_HBUFFER_ADD_SIZE((duk_hbuffer *) (x), (dv))\n#define DUK_HBUFFER_DYNAMIC_SUB_SIZE(x,dv)  DUK_HBUFFER_SUB_SIZE((duk_hbuffer *) (x), (dv))\n\n#define DUK_HBUFFER_EXTERNAL_GET_SIZE(x)    DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x))\n#define DUK_HBUFFER_EXTERNAL_SET_SIZE(x,v)  DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x), (v))\n\n#define DUK_HBUFFER_FIXED_GET_DATA_PTR(heap,x)    ((duk_uint8_t *) (((duk_hbuffer_fixed *) (void *) (x)) + 1))\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap,x) \\\n\t((void *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, ((duk_heaphdr *) (x))->h_extra16))\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t((duk_heaphdr *) (x))->h_extra16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t((duk_heaphdr *) (x))->h_extra16 = 0;  /* assume 0 <=> NULL */ \\\n\t} while (0)\n#else\n#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap,x)       ((x)->curr_alloc)\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t(x)->curr_alloc = (void *) (v); \\\n\t} while (0)\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t(x)->curr_alloc = (void *) NULL; \\\n\t} while (0)\n#endif\n\n/* No pointer compression because pointer is potentially outside of\n * Duktape heap.\n */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap,x) \\\n\t((void *) (x)->curr_alloc)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t(x)->curr_alloc = (void *) (v); \\\n\t} while (0)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t(x)->curr_alloc = (void *) NULL; \\\n\t} while (0)\n#else\n#define DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap,x) \\\n\t((void *) (x)->curr_alloc)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t(x)->curr_alloc = (void *) (v); \\\n\t} while (0)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t(x)->curr_alloc = (void *) NULL; \\\n\t} while (0)\n#endif\n\n/* Get a pointer to the current buffer contents (matching current allocation\n * size).  May be NULL for zero size dynamic/external buffer.\n */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HBUFFER_GET_DATA_PTR(heap,x)  ( \\\n\tDUK_HBUFFER_HAS_DYNAMIC((x)) ? \\\n\t\t( \\\n\t\t\tDUK_HBUFFER_HAS_EXTERNAL((x)) ? \\\n\t\t\t\tDUK_HBUFFER_EXTERNAL_GET_DATA_PTR((heap), (duk_hbuffer_external *) (x)) : \\\n\t\t\t\tDUK_HBUFFER_DYNAMIC_GET_DATA_PTR((heap), (duk_hbuffer_dynamic *) (x)) \\\n\t\t) : \\\n\t\tDUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (void *) (x)) \\\n\t)\n#else\n/* Without heap pointer compression duk_hbuffer_dynamic and duk_hbuffer_external\n * have the same layout so checking for fixed vs. dynamic (or external) is enough.\n */\n#define DUK_HBUFFER_GET_DATA_PTR(heap,x)  ( \\\n\tDUK_HBUFFER_HAS_DYNAMIC((x)) ? \\\n\t\tDUK_HBUFFER_DYNAMIC_GET_DATA_PTR((heap), (duk_hbuffer_dynamic *) (x)) : \\\n\t\tDUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (void *) (x)) \\\n\t)\n#endif\n\n/* Validity assert. */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hbuffer_assert_valid(duk_hbuffer *h);\n#define DUK_HBUFFER_ASSERT_VALID(h)  do { duk_hbuffer_assert_valid((h)); } while (0)\n#else\n#define DUK_HBUFFER_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Structs\n */\n\n/* Shared prefix for all buffer types. */\nstruct duk_hbuffer {\n\tduk_heaphdr hdr;\n\n\t/* It's not strictly necessary to track the current size, but\n\t * it is useful for writing robust native code.\n\t */\n\n\t/* Current size. */\n#if defined(DUK_USE_BUFLEN16)\n\t/* Stored in duk_heaphdr unused flags. */\n#else\n\tduk_size_t size;\n#endif\n\n\t/*\n\t *  Data following the header depends on the DUK_HBUFFER_FLAG_DYNAMIC\n\t *  flag.\n\t *\n\t *  If the flag is clear (the buffer is a fixed size one), the buffer\n\t *  data follows the header directly, consisting of 'size' bytes.\n\t *\n\t *  If the flag is set, the actual buffer is allocated separately, and\n\t *  a few control fields follow the header.  Specifically:\n\t *\n\t *    - a \"void *\" pointing to the current allocation\n\t *    - a duk_size_t indicating the full allocated size (always >= 'size')\n\t *\n\t *  If DUK_HBUFFER_FLAG_EXTERNAL is set, the buffer has been allocated\n\t *  by user code, so that Duktape won't be able to resize it and won't\n\t *  free it.  This allows buffers to point to e.g. an externally\n\t *  allocated structure such as a frame buffer.\n\t *\n\t *  Unlike strings, no terminator byte (NUL) is guaranteed after the\n\t *  data.  This would be convenient, but would pad aligned user buffers\n\t *  unnecessarily upwards in size.  For instance, if user code requested\n\t *  a 64-byte dynamic buffer, 65 bytes would actually be allocated which\n\t *  would then potentially round upwards to perhaps 68 or 72 bytes.\n\t */\n};\n\n/* Fixed buffer; data follows struct, with proper alignment guaranteed by\n * struct size.\n */\n#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)\n#pragma pack(push, 8)\n#endif\nstruct duk_hbuffer_fixed {\n\t/* A union is used here as a portable struct size / alignment trick:\n\t * by adding a 32-bit or a 64-bit (unused) union member, the size of\n\t * the struct is effectively forced to be a multiple of 4 or 8 bytes\n\t * (respectively) without increasing the size of the struct unless\n\t * necessary.\n\t */\n\tunion {\n\t\tstruct {\n\t\t\tduk_heaphdr hdr;\n#if defined(DUK_USE_BUFLEN16)\n\t\t\t/* Stored in duk_heaphdr unused flags. */\n#else\n\t\t\tduk_size_t size;\n#endif\n\t\t} s;\n#if (DUK_USE_ALIGN_BY == 4)\n\t\tduk_uint32_t dummy_for_align4;\n#elif (DUK_USE_ALIGN_BY == 8)\n\t\tduk_double_t dummy_for_align8_1;\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_uint64_t dummy_for_align8_2;\n#endif\n#elif (DUK_USE_ALIGN_BY == 1)\n\t\t/* no extra padding */\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\t} u;\n\n\t/*\n\t *  Data follows the struct header.  The struct size is padded by the\n\t *  compiler based on the struct members.  This guarantees that the\n\t *  buffer data will be aligned-by-4 but not necessarily aligned-by-8.\n\t *\n\t *  On platforms where alignment does not matter, the struct padding\n\t *  could be removed (if there is any).  On platforms where alignment\n\t *  by 8 is required, the struct size must be forced to be a multiple\n\t *  of 8 by some means.  Without it, some user code may break, and also\n\t *  Duktape itself breaks (e.g. the compiler stores duk_tvals in a\n\t *  dynamic buffer).\n\t */\n}\n#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_GCC_ATTR)\n__attribute__ ((aligned (8)))\n#elif (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_CLANG_ATTR)\n__attribute__ ((aligned (8)))\n#endif\n;\n#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)\n#pragma pack(pop)\n#endif\n\n/* Dynamic buffer with 'curr_alloc' pointing to a dynamic area allocated using\n * heap allocation primitives.  Also used for external buffers when low memory\n * options are not used.\n */\nstruct duk_hbuffer_dynamic {\n\tduk_heaphdr hdr;\n\n#if defined(DUK_USE_BUFLEN16)\n\t/* Stored in duk_heaphdr unused flags. */\n#else\n\tduk_size_t size;\n#endif\n\n#if defined(DUK_USE_HEAPPTR16)\n\t/* Stored in duk_heaphdr h_extra16. */\n#else\n\tvoid *curr_alloc;  /* may be NULL if alloc_size == 0 */\n#endif\n\n\t/*\n\t *  Allocation size for 'curr_alloc' is alloc_size.  There is no\n\t *  automatic NUL terminator for buffers (see above for rationale).\n\t *\n\t *  'curr_alloc' is explicitly allocated with heap allocation\n\t *  primitives and will thus always have alignment suitable for\n\t *  e.g. duk_tval and an IEEE double.\n\t */\n};\n\n/* External buffer with 'curr_alloc' managed by user code and pointing to an\n * arbitrary address.  When heap pointer compression is not used, this struct\n * has the same layout as duk_hbuffer_dynamic.\n */\nstruct duk_hbuffer_external {\n\tduk_heaphdr hdr;\n\n#if defined(DUK_USE_BUFLEN16)\n\t/* Stored in duk_heaphdr unused flags. */\n#else\n\tduk_size_t size;\n#endif\n\n\t/* Cannot be compressed as a heap pointer because may point to\n\t * an arbitrary address.\n\t */\n\tvoid *curr_alloc;  /* may be NULL if alloc_size == 0 */\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk_small_uint_t flags, void **out_bufdata);\nDUK_INTERNAL_DECL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud);  /* indirect allocs */\n\n/* dynamic buffer ops */\nDUK_INTERNAL_DECL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf, duk_size_t new_size);\nDUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *buf);\n\n#endif  /* DUK_HBUFFER_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hbuffer_alloc.c",
    "content": "/*\n *  duk_hbuffer allocation and freeing.\n */\n\n#include \"duk_internal.h\"\n\n/* Allocate a new duk_hbuffer of a certain type and return a pointer to it\n * (NULL on error).  Write buffer data pointer to 'out_bufdata' (only if\n * allocation successful).\n */\nDUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk_small_uint_t flags, void **out_bufdata) {\n\tduk_hbuffer *res = NULL;\n\tduk_size_t header_size;\n\tduk_size_t alloc_size;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(out_bufdata != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"allocate hbuffer\"));\n\n\t/* Size sanity check.  Should not be necessary because caller is\n\t * required to check this, but we don't want to cause a segfault\n\t * if the size wraps either in duk_size_t computation or when\n\t * storing the size in a 16-bit field.\n\t */\n\tif (size > DUK_HBUFFER_MAX_BYTELEN) {\n\t\tDUK_D(DUK_DPRINT(\"hbuffer alloc failed: size too large: %ld\", (long) size));\n\t\treturn NULL;  /* no need to write 'out_bufdata' */\n\t}\n\n\tif (flags & DUK_BUF_FLAG_EXTERNAL) {\n\t\theader_size = sizeof(duk_hbuffer_external);\n\t\talloc_size = sizeof(duk_hbuffer_external);\n\t} else if (flags & DUK_BUF_FLAG_DYNAMIC) {\n\t\theader_size = sizeof(duk_hbuffer_dynamic);\n\t\talloc_size = sizeof(duk_hbuffer_dynamic);\n\t} else {\n\t\theader_size = sizeof(duk_hbuffer_fixed);\n\t\talloc_size = sizeof(duk_hbuffer_fixed) + size;\n\t\tDUK_ASSERT(alloc_size >= sizeof(duk_hbuffer_fixed));  /* no wrapping */\n\t}\n\n\tres = (duk_hbuffer *) DUK_ALLOC(heap, alloc_size);\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\tgoto alloc_error;\n\t}\n\n\t/* zero everything unless requested not to do so */\n#if defined(DUK_USE_ZERO_BUFFER_DATA)\n\tduk_memzero((void *) res,\n\t            (flags & DUK_BUF_FLAG_NOZERO) ? header_size : alloc_size);\n#else\n\tduk_memzero((void *) res, header_size);\n#endif\n\n\tif (flags & DUK_BUF_FLAG_EXTERNAL) {\n\t\tduk_hbuffer_external *h;\n\t\th = (duk_hbuffer_external *) res;\n\t\tDUK_UNREF(h);\n\t\t*out_bufdata = NULL;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_HEAPPTR16)\n/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */\n#else\n\t\tDUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap, h, NULL);\n#endif\n#endif\n\t\tDUK_ASSERT(DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap, h) == NULL);\n\t} else if (flags & DUK_BUF_FLAG_DYNAMIC) {\n\t\tduk_hbuffer_dynamic *h = (duk_hbuffer_dynamic *) res;\n\t\tvoid *ptr;\n\n\t\tif (size > 0) {\n\t\t\tDUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL));  /* alloc external with size zero */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"dynamic buffer with nonzero size, alloc actual buffer\"));\n#if defined(DUK_USE_ZERO_BUFFER_DATA)\n\t\t\tptr = DUK_ALLOC_ZEROED(heap, size);\n#else\n\t\t\tptr = DUK_ALLOC(heap, size);\n#endif\n\t\t\tif (DUK_UNLIKELY(ptr == NULL)) {\n\t\t\t\t/* Because size > 0, NULL check is correct */\n\t\t\t\tgoto alloc_error;\n\t\t\t}\n\t\t\t*out_bufdata = ptr;\n\n\t\t\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, ptr);\n\t\t} else {\n\t\t\t*out_bufdata = NULL;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_HEAPPTR16)\n/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */\n#else\n\t\t\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, NULL);\n#endif\n#endif\n\t\t\tDUK_ASSERT(DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, h) == NULL);\n\t\t}\n\t} else {\n\t\t*out_bufdata = (void *) ((duk_hbuffer_fixed *) (void *) res + 1);\n\t}\n\n\tDUK_HBUFFER_SET_SIZE(res, size);\n\n\tDUK_HEAPHDR_SET_TYPE(&res->hdr, DUK_HTYPE_BUFFER);\n\tif (flags & DUK_BUF_FLAG_DYNAMIC) {\n\t\tDUK_HBUFFER_SET_DYNAMIC(res);\n\t\tif (flags & DUK_BUF_FLAG_EXTERNAL) {\n\t\t\tDUK_HBUFFER_SET_EXTERNAL(res);\n\t\t}\n\t} else {\n\t\tDUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL));\n\t}\n        DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &res->hdr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"allocated hbuffer: %p\", (void *) res));\n\treturn res;\n\n alloc_error:\n\tDUK_DD(DUK_DDPRINT(\"hbuffer allocation failed\"));\n\n\tDUK_FREE(heap, res);\n\treturn NULL;  /* no need to write 'out_bufdata' */\n}\n\n/* For indirect allocs. */\n\nDUK_INTERNAL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud) {\n\tduk_hbuffer_dynamic *buf = (duk_hbuffer_dynamic *) ud;\n\tDUK_UNREF(heap);\n\treturn (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, buf);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hbuffer_assert.c",
    "content": "/*\n *  duk_hbuffer assertion helpers\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_ASSERTIONS)\n\nDUK_INTERNAL void duk_hbuffer_assert_valid(duk_hbuffer *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hbuffer_ops.c",
    "content": "/*\n *  duk_hbuffer operations such as resizing and inserting/appending data to\n *  a dynamic buffer.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Resizing\n */\n\nDUK_INTERNAL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf, duk_size_t new_size) {\n\tvoid *res;\n\tduk_size_t prev_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf));\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf));\n\n\t/*\n\t *  Maximum size check\n\t */\n\n\tif (new_size > DUK_HBUFFER_MAX_BYTELEN) {\n\t\tDUK_ERROR_RANGE(thr, \"buffer too long\");\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/*\n\t *  Note: use indirect realloc variant just in case mark-and-sweep\n\t *  (finalizers) might resize this same buffer during garbage\n\t *  collection.\n\t */\n\n\tres = DUK_REALLOC_INDIRECT(thr->heap, duk_hbuffer_get_dynalloc_ptr, (void *) buf, new_size);\n\tif (DUK_LIKELY(res != NULL || new_size == 0)) {\n\t\t/* 'res' may be NULL if new allocation size is 0. */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"resized dynamic buffer %p:%ld -> %p:%ld\",\n\t\t                     (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, buf),\n\t\t                     (long) DUK_HBUFFER_DYNAMIC_GET_SIZE(buf),\n\t\t                     (void *) res,\n\t\t                     (long) new_size));\n\n\t\t/*\n\t\t *  The entire allocated buffer area, regardless of actual used\n\t\t *  size, is kept zeroed in resizes for simplicity.  If the buffer\n\t\t *  is grown, zero the new part.\n\t\t */\n\n\t\tprev_size = DUK_HBUFFER_DYNAMIC_GET_SIZE(buf);\n\t\tif (new_size > prev_size) {\n\t\t\tDUK_ASSERT(new_size - prev_size > 0);\n#if defined(DUK_USE_ZERO_BUFFER_DATA)\n\t\t\tduk_memzero((void *) ((char *) res + prev_size),\n\t\t\t            (duk_size_t) (new_size - prev_size));\n#endif\n\t\t}\n\n\t\tDUK_HBUFFER_DYNAMIC_SET_SIZE(buf, new_size);\n\t\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR(thr->heap, buf, res);\n\t} else {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_ASSERT(res != NULL || new_size == 0);\n}\n\nDUK_INTERNAL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *buf) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf));\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf));\n\n\tduk_hbuffer_resize(thr, buf, 0);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hbufobj.h",
    "content": "/*\n *  Heap Buffer object representation.  Used for all Buffer variants.\n */\n\n#if !defined(DUK_HBUFOBJ_H_INCLUDED)\n#define DUK_HBUFOBJ_H_INCLUDED\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\n/* All element accessors are host endian now (driven by TypedArray spec). */\n#define DUK_HBUFOBJ_ELEM_UINT8           0\n#define DUK_HBUFOBJ_ELEM_UINT8CLAMPED    1\n#define DUK_HBUFOBJ_ELEM_INT8            2\n#define DUK_HBUFOBJ_ELEM_UINT16          3\n#define DUK_HBUFOBJ_ELEM_INT16           4\n#define DUK_HBUFOBJ_ELEM_UINT32          5\n#define DUK_HBUFOBJ_ELEM_INT32           6\n#define DUK_HBUFOBJ_ELEM_FLOAT32         7\n#define DUK_HBUFOBJ_ELEM_FLOAT64         8\n#define DUK_HBUFOBJ_ELEM_MAX             8\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hbufobj_assert_valid(duk_hbufobj *h);\n#define DUK_HBUFOBJ_ASSERT_VALID(h)  do { duk_hbufobj_assert_valid((h)); } while (0)\n#else\n#define DUK_HBUFOBJ_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/* Get the current data pointer (caller must ensure buf != NULL) as a\n * duk_uint8_t ptr.  Note that the result may be NULL if the underlying\n * buffer has zero size and is not a fixed buffer.\n */\n#define DUK_HBUFOBJ_GET_SLICE_BASE(heap,h) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t(((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR((heap), (h)->buf)) + (h)->offset))\n\n/* True if slice is full, i.e. offset is zero and length covers the entire\n * buffer.  This status may change independently of the duk_hbufobj if\n * the underlying buffer is dynamic and changes without the hbufobj\n * being changed.\n */\n#define DUK_HBUFOBJ_FULL_SLICE(h) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset == 0 && (h)->length == DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n/* Validate that the whole slice [0,length[ is contained in the underlying\n * buffer.  Caller must ensure 'buf' != NULL.\n */\n#define DUK_HBUFOBJ_VALID_SLICE(h) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset + (h)->length <= DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n/* Validate byte read/write for virtual 'offset', i.e. check that the\n * offset, taking into account h->offset, is within the underlying\n * buffer size.  This is a safety check which is needed to ensure\n * that even a misconfigured duk_hbufobj never causes memory unsafe\n * behavior (e.g. if an underlying dynamic buffer changes after being\n * setup).  Caller must ensure 'buf' != NULL.\n */\n#define DUK_HBUFOBJ_VALID_BYTEOFFSET_INCL(h,off) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset + (off) < DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n#define DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h,off) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset + (off) <= DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n/* Clamp an input byte length (already assumed to be within the nominal\n * duk_hbufobj 'length') to the current dynamic buffer limits to yield\n * a byte length limit that's safe for memory accesses.  This value can\n * be invalidated by any side effect because it may trigger a user\n * callback that resizes the underlying buffer.\n */\n#define DUK_HBUFOBJ_CLAMP_BYTELENGTH(h,len) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), \\\n\tduk_hbufobj_clamp_bytelength((h), (len)))\n\n/* Typed arrays have virtual indices, ArrayBuffer and DataView do not. */\n#define DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h)  ((h)->is_typedarray)\n\nstruct duk_hbufobj {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Underlying buffer (refcounted), may be NULL. */\n\tduk_hbuffer *buf;\n\n\t/* .buffer reference to an ArrayBuffer, may be NULL. */\n\tduk_hobject *buf_prop;\n\n\t/* Slice and accessor information.\n\t *\n\t * Because the underlying buffer may be dynamic, these may be\n\t * invalidated by the buffer being modified so that both offset\n\t * and length should be validated before every access.  Behavior\n\t * when the underlying buffer has changed doesn't need to be clean:\n\t * virtual 'length' doesn't need to be affected, reads can return\n\t * zero/NaN, and writes can be ignored.\n\t *\n\t * Note that a data pointer cannot be precomputed because 'buf' may\n\t * be dynamic and its pointer unstable.\n\t */\n\n\tduk_uint_t offset;       /* byte offset to buf */\n\tduk_uint_t length;       /* byte index limit for element access, exclusive */\n\tduk_uint8_t shift;       /* element size shift:\n\t                          *   0 = u8/i8\n\t                          *   1 = u16/i16\n\t                          *   2 = u32/i32/float\n\t                          *   3 = double\n\t                          */\n\tduk_uint8_t elem_type;   /* element type */\n\tduk_uint8_t is_typedarray;\n};\n\nDUK_INTERNAL_DECL duk_uint_t duk_hbufobj_clamp_bytelength(duk_hbufobj *h_bufobj, duk_uint_t len);\nDUK_INTERNAL_DECL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_hbuffer *h_buf);\nDUK_INTERNAL_DECL void duk_hbufobj_push_validated_read(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);\nDUK_INTERNAL_DECL void duk_hbufobj_validated_write(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);\nDUK_INTERNAL_DECL void duk_hbufobj_promote_plain(duk_hthread *thr, duk_idx_t idx);\n\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* nothing */\n\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n#endif  /* DUK_HBUFOBJ_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hbufobj_misc.c",
    "content": "#include \"duk_internal.h\"\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_uint_t duk_hbufobj_clamp_bytelength(duk_hbufobj *h_bufobj, duk_uint_t len) {\n\tduk_uint_t buf_size;\n\tduk_uint_t buf_avail;\n\n\tDUK_ASSERT(h_bufobj != NULL);\n\tDUK_ASSERT(h_bufobj->buf != NULL);\n\n\tbuf_size = (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_bufobj->buf);\n\tif (h_bufobj->offset > buf_size) {\n\t\t/* Slice starting point is beyond current length. */\n\t\treturn 0;\n\t}\n\tbuf_avail = buf_size - h_bufobj->offset;\n\n\treturn buf_avail >= len ? len : buf_avail;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hcompfunc.h",
    "content": "/*\n *  Heap compiled function (ECMAScript function) representation.\n *\n *  There is a single data buffer containing the ECMAScript function's\n *  bytecode, constants, and inner functions.\n */\n\n#if !defined(DUK_HCOMPFUNC_H_INCLUDED)\n#define DUK_HCOMPFUNC_H_INCLUDED\n\n/*\n *  Field accessor macros\n */\n\n/* XXX: casts could be improved, especially for GET/SET DATA */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HCOMPFUNC_GET_DATA(heap,h) \\\n\t((duk_hbuffer_fixed *) (void *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->data16))\n#define DUK_HCOMPFUNC_SET_DATA(heap,h,v) do { \\\n\t\t(h)->data16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_FUNCS(heap,h)  \\\n\t((duk_hobject **) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->funcs16)))\n#define DUK_HCOMPFUNC_SET_FUNCS(heap,h,v)  do { \\\n\t\t(h)->funcs16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_BYTECODE(heap,h)  \\\n\t((duk_instr_t *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->bytecode16)))\n#define DUK_HCOMPFUNC_SET_BYTECODE(heap,h,v)  do { \\\n\t\t(h)->bytecode16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_LEXENV(heap,h)  \\\n\t((duk_hobject *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->lex_env16)))\n#define DUK_HCOMPFUNC_SET_LEXENV(heap,h,v)  do { \\\n\t\t(h)->lex_env16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_VARENV(heap,h)  \\\n\t((duk_hobject *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->var_env16)))\n#define DUK_HCOMPFUNC_SET_VARENV(heap,h,v)  do { \\\n\t\t(h)->var_env16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#else\n#define DUK_HCOMPFUNC_GET_DATA(heap,h)  ((duk_hbuffer_fixed *) (void *) (h)->data)\n#define DUK_HCOMPFUNC_SET_DATA(heap,h,v) do { \\\n\t\t(h)->data = (duk_hbuffer *) (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_FUNCS(heap,h)  ((h)->funcs)\n#define DUK_HCOMPFUNC_SET_FUNCS(heap,h,v)  do { \\\n\t\t(h)->funcs = (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_BYTECODE(heap,h)  ((h)->bytecode)\n#define DUK_HCOMPFUNC_SET_BYTECODE(heap,h,v)  do { \\\n\t\t(h)->bytecode = (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_LEXENV(heap,h)  ((h)->lex_env)\n#define DUK_HCOMPFUNC_SET_LEXENV(heap,h,v)  do { \\\n\t\t(h)->lex_env = (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_VARENV(heap,h)  ((h)->var_env)\n#define DUK_HCOMPFUNC_SET_VARENV(heap,h,v)  do { \\\n\t\t(h)->var_env = (v); \\\n\t} while (0)\n#endif\n\n/*\n *  Accessor macros for function specific data areas\n */\n\n/* Note: assumes 'data' is always a fixed buffer */\n#define DUK_HCOMPFUNC_GET_BUFFER_BASE(heap,h)  \\\n\tDUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPFUNC_GET_DATA((heap), (h)))\n\n#define DUK_HCOMPFUNC_GET_CONSTS_BASE(heap,h)  \\\n\t((duk_tval *) (void *) DUK_HCOMPFUNC_GET_BUFFER_BASE((heap), (h)))\n\n#define DUK_HCOMPFUNC_GET_FUNCS_BASE(heap,h)  \\\n\tDUK_HCOMPFUNC_GET_FUNCS((heap), (h))\n\n#define DUK_HCOMPFUNC_GET_CODE_BASE(heap,h)  \\\n\tDUK_HCOMPFUNC_GET_BYTECODE((heap), (h))\n\n#define DUK_HCOMPFUNC_GET_CONSTS_END(heap,h)  \\\n\t((duk_tval *) (void *) DUK_HCOMPFUNC_GET_FUNCS((heap), (h)))\n\n#define DUK_HCOMPFUNC_GET_FUNCS_END(heap,h)  \\\n\t((duk_hobject **) (void *) DUK_HCOMPFUNC_GET_BYTECODE((heap), (h)))\n\n/* XXX: double evaluation of DUK_HCOMPFUNC_GET_DATA() */\n#define DUK_HCOMPFUNC_GET_CODE_END(heap,h)  \\\n\t((duk_instr_t *) (void *) (DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPFUNC_GET_DATA((heap), (h))) + \\\n\t                DUK_HBUFFER_GET_SIZE((duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA((heap), h))))\n\n#define DUK_HCOMPFUNC_GET_CONSTS_SIZE(heap,h)  \\\n\t( \\\n\t (duk_size_t) \\\n\t ( \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CONSTS_END((heap), (h))) - \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CONSTS_BASE((heap), (h))) \\\n\t ) \\\n\t)\n\n#define DUK_HCOMPFUNC_GET_FUNCS_SIZE(heap,h)  \\\n\t( \\\n\t (duk_size_t) \\\n\t ( \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_FUNCS_END((heap), (h))) - \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_FUNCS_BASE((heap), (h))) \\\n\t ) \\\n\t)\n\n#define DUK_HCOMPFUNC_GET_CODE_SIZE(heap,h)  \\\n\t( \\\n\t (duk_size_t) \\\n\t ( \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CODE_END((heap),(h))) - \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CODE_BASE((heap),(h))) \\\n\t ) \\\n\t)\n\n#define DUK_HCOMPFUNC_GET_CONSTS_COUNT(heap,h)  \\\n\t((duk_size_t) (DUK_HCOMPFUNC_GET_CONSTS_SIZE((heap), (h)) / sizeof(duk_tval)))\n\n#define DUK_HCOMPFUNC_GET_FUNCS_COUNT(heap,h)  \\\n\t((duk_size_t) (DUK_HCOMPFUNC_GET_FUNCS_SIZE((heap), (h)) / sizeof(duk_hobject *)))\n\n#define DUK_HCOMPFUNC_GET_CODE_COUNT(heap,h)  \\\n\t((duk_size_t) (DUK_HCOMPFUNC_GET_CODE_SIZE((heap), (h)) / sizeof(duk_instr_t)))\n\n/*\n *  Validity assert\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hcompfunc_assert_valid(duk_hcompfunc *h);\n#define DUK_HCOMPFUNC_ASSERT_VALID(h)  do { duk_hcompfunc_assert_valid((h)); } while (0)\n#else\n#define DUK_HCOMPFUNC_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Main struct\n */\n\nstruct duk_hcompfunc {\n\t/* shared object part */\n\tduk_hobject obj;\n\n\t/*\n\t *  Pointers to function data area for faster access.  Function\n\t *  data is a buffer shared between all closures of the same\n\t *  \"template\" function.  The data buffer is always fixed (non-\n\t *  dynamic, hence stable), with a layout as follows:\n\t *\n\t *    constants (duk_tval)\n\t *    inner functions (duk_hobject *)\n\t *    bytecode (duk_instr_t)\n\t *\n\t *  Note: bytecode end address can be computed from 'data' buffer\n\t *  size.  It is not strictly necessary functionally, assuming\n\t *  bytecode never jumps outside its allocated area.  However,\n\t *  it's a safety/robustness feature for avoiding the chance of\n\t *  executing random data as bytecode due to a compiler error.\n\t *\n\t *  Note: values in the data buffer must be incref'd (they will\n\t *  be decref'd on release) for every compiledfunction referring\n\t *  to the 'data' element.\n\t */\n\n\t/* Data area, fixed allocation, stable data ptrs. */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t data16;\n#else\n\tduk_hbuffer *data;\n#endif\n\n\t/* No need for constants pointer (= same as data).\n\t *\n\t * When using 16-bit packing alignment to 4 is nice.  'funcs' will be\n\t * 4-byte aligned because 'constants' are duk_tvals.  For now the\n\t * inner function pointers are not compressed, so that 'bytecode' will\n\t * also be 4-byte aligned.\n\t */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t funcs16;\n\tduk_uint16_t bytecode16;\n#else\n\tduk_hobject **funcs;\n\tduk_instr_t *bytecode;\n#endif\n\n\t/* Lexenv: lexical environment of closure, NULL for templates.\n\t * Varenv: variable environment of closure, NULL for templates.\n\t */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t lex_env16;\n\tduk_uint16_t var_env16;\n#else\n\tduk_hobject *lex_env;\n\tduk_hobject *var_env;\n#endif\n\n\t/*\n\t *  'nregs' registers are allocated on function entry, at most 'nargs'\n\t *  are initialized to arguments, and the rest to undefined.  Arguments\n\t *  above 'nregs' are not mapped to registers.  All registers in the\n\t *  active stack range must be initialized because they are GC reachable.\n\t *  'nargs' is needed so that if the function is given more than 'nargs'\n\t *  arguments, the additional arguments do not 'clobber' registers\n\t *  beyond 'nregs' which must be consistently initialized to undefined.\n\t *\n\t *  Usually there is no need to know which registers are mapped to\n\t *  local variables.  Registers may be allocated to variable in any\n\t *  way (even including gaps).  However, a register-variable mapping\n\t *  must be the same for the duration of the function execution and\n\t *  the register cannot be used for anything else.\n\t *\n\t *  When looking up variables by name, the '_Varmap' map is used.\n\t *  When an activation closes, registers mapped to arguments are\n\t *  copied into the environment record based on the same map.  The\n\t *  reverse map (from register to variable) is not currently needed\n\t *  at run time, except for debugging, so it is not maintained.\n\t */\n\n\tduk_uint16_t nregs;                /* regs to allocate */\n\tduk_uint16_t nargs;                /* number of arguments allocated to regs */\n\n\t/*\n\t *  Additional control information is placed into the object itself\n\t *  as internal properties to avoid unnecessary fields for the\n\t *  majority of functions.  The compiler tries to omit internal\n\t *  control fields when possible.\n\t *\n\t *  Function templates:\n\t *\n\t *    {\n\t *      name: \"func\",    // declaration, named function expressions\n\t *      fileName: <debug info for creating nice errors>\n\t *      _Varmap: { \"arg1\": 0, \"arg2\": 1, \"varname\": 2 },\n\t *      _Formals: [ \"arg1\", \"arg2\" ],\n\t *      _Source: \"function func(arg1, arg2) { ... }\",\n\t *      _Pc2line: <debug info for pc-to-line mapping>,\n\t *    }\n\t *\n\t *  Function instances:\n\t *\n\t *    {\n\t *      length: 2,\n\t *      prototype: { constructor: <func> },\n\t *      caller: <thrower>,\n\t *      arguments: <thrower>,\n\t *      name: \"func\",    // declaration, named function expressions\n\t *      fileName: <debug info for creating nice errors>\n\t *      _Varmap: { \"arg1\": 0, \"arg2\": 1, \"varname\": 2 },\n\t *      _Formals: [ \"arg1\", \"arg2\" ],\n\t *      _Source: \"function func(arg1, arg2) { ... }\",\n\t *      _Pc2line: <debug info for pc-to-line mapping>,\n\t *    }\n\t *\n\t *  More detailed description of these properties can be found\n\t *  in the documentation.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* Line number range for function.  Needed during debugging to\n\t * determine active breakpoints.\n\t */\n\tduk_uint32_t start_line;\n\tduk_uint32_t end_line;\n#endif\n};\n\n#endif  /* DUK_HCOMPFUNC_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_heap.h",
    "content": "/*\n *  Heap structure.\n *\n *  Heap contains allocated heap objects, interned strings, and built-in\n *  strings for one or more threads.\n */\n\n#if !defined(DUK_HEAP_H_INCLUDED)\n#define DUK_HEAP_H_INCLUDED\n\n/* alloc function typedefs in duktape.h */\n\n/*\n *  Heap flags\n */\n\n#define DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED            (1U << 0)  /* mark-and-sweep marking reached a recursion limit and must use multi-pass marking */\n#define DUK_HEAP_FLAG_INTERRUPT_RUNNING                        (1U << 1)  /* executor interrupt running (used to avoid nested interrupts) */\n#define DUK_HEAP_FLAG_FINALIZER_NORESCUE                       (1U << 2)  /* heap destruction ongoing, finalizer rescue no longer possible */\n#define DUK_HEAP_FLAG_DEBUGGER_PAUSED                          (1U << 3)  /* debugger is paused: talk with debug client until step/resume */\n\n#define DUK__HEAP_HAS_FLAGS(heap,bits)               ((heap)->flags & (bits))\n#define DUK__HEAP_SET_FLAGS(heap,bits)  do { \\\n\t\t(heap)->flags |= (bits); \\\n\t} while (0)\n#define DUK__HEAP_CLEAR_FLAGS(heap,bits)  do { \\\n\t\t(heap)->flags &= ~(bits); \\\n\t} while (0)\n\n#define DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap)   DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)\n#define DUK_HEAP_HAS_INTERRUPT_RUNNING(heap)               DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)\n#define DUK_HEAP_HAS_FINALIZER_NORESCUE(heap)              DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE)\n#define DUK_HEAP_HAS_DEBUGGER_PAUSED(heap)                 DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED)\n\n#define DUK_HEAP_SET_MARKANDSWEEP_RECLIMIT_REACHED(heap)   DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)\n#define DUK_HEAP_SET_INTERRUPT_RUNNING(heap)               DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)\n#define DUK_HEAP_SET_FINALIZER_NORESCUE(heap)              DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE)\n#define DUK_HEAP_SET_DEBUGGER_PAUSED(heap)                 DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED)\n\n#define DUK_HEAP_CLEAR_MARKANDSWEEP_RECLIMIT_REACHED(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)\n#define DUK_HEAP_CLEAR_INTERRUPT_RUNNING(heap)             DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)\n#define DUK_HEAP_CLEAR_FINALIZER_NORESCUE(heap)            DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE)\n#define DUK_HEAP_CLEAR_DEBUGGER_PAUSED(heap)               DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED)\n\n/*\n *  Longjmp types, also double as identifying continuation type for a rethrow (in 'finally')\n */\n\n#define DUK_LJ_TYPE_UNKNOWN      0    /* unused */\n#define DUK_LJ_TYPE_THROW        1    /* value1 -> error object */\n#define DUK_LJ_TYPE_YIELD        2    /* value1 -> yield value, iserror -> error / normal */\n#define DUK_LJ_TYPE_RESUME       3    /* value1 -> resume value, value2 -> resumee thread, iserror -> error/normal */\n#define DUK_LJ_TYPE_BREAK        4    /* value1 -> label number, pseudo-type to indicate a break continuation (for ENDFIN) */\n#define DUK_LJ_TYPE_CONTINUE     5    /* value1 -> label number, pseudo-type to indicate a continue continuation (for ENDFIN) */\n#define DUK_LJ_TYPE_RETURN       6    /* value1 -> return value, pseudo-type to indicate a return continuation (for ENDFIN) */\n#define DUK_LJ_TYPE_NORMAL       7    /* no value, pseudo-type to indicate a normal continuation (for ENDFIN) */\n\n/*\n *  Mark-and-sweep flags\n *\n *  These are separate from heap level flags now but could be merged.\n *  The heap structure only contains a 'base mark-and-sweep flags'\n *  field and the GC caller can impose further flags.\n */\n\n/* Emergency mark-and-sweep: try extra hard, even at the cost of\n * performance.\n */\n#define DUK_MS_FLAG_EMERGENCY                (1U << 0)\n\n/* Voluntary mark-and-sweep: triggered periodically. */\n#define DUK_MS_FLAG_VOLUNTARY                (1U << 1)\n\n/* Postpone rescue decisions for reachable objects with FINALIZED set.\n * Used during finalize_list processing to avoid incorrect rescue\n * decisions due to finalize_list being a reachability root.\n */\n#define DUK_MS_FLAG_POSTPONE_RESCUE          (1U << 2)\n\n/* Don't compact objects; needed during object property table resize\n * to prevent a recursive resize.  It would suffice to protect only the\n * current object being resized, but this is not yet implemented.\n */\n#define DUK_MS_FLAG_NO_OBJECT_COMPACTION     (1U << 3)\n\n/*\n *  Thread switching\n *\n *  To switch heap->curr_thread, use the macro below so that interrupt counters\n *  get updated correctly.  The macro allows a NULL target thread because that\n *  happens e.g. in call handling.\n */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n#define DUK_HEAP_SWITCH_THREAD(heap,newthr)  duk_heap_switch_thread((heap), (newthr))\n#else\n#define DUK_HEAP_SWITCH_THREAD(heap,newthr)  do { \\\n\t\t(heap)->curr_thread = (newthr); \\\n\t} while (0)\n#endif\n\n/*\n *  Stats\n */\n\n#if defined(DUK_USE_DEBUG)\n#define DUK_STATS_INC(heap,fieldname) do { \\\n\t\t(heap)->fieldname += 1; \\\n\t} while (0)\n#else\n#define DUK_STATS_INC(heap,fieldname) do {} while (0)\n#endif\n\n/*\n *  Other heap related defines\n */\n\n/* Mark-and-sweep interval is relative to combined count of objects and\n * strings kept in the heap during the latest mark-and-sweep pass.\n * Fixed point .8 multiplier and .0 adder.  Trigger count (interval) is\n * decreased by each (re)allocation attempt (regardless of size), and each\n * refzero processed object.\n *\n * 'SKIP' indicates how many (re)allocations to wait until a retry if\n * GC is skipped because there is no thread do it with yet (happens\n * only during init phases).\n */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT              12800L  /* 50x heap size */\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD               1024L\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_SKIP              256L\n#else\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT              256L    /* 1x heap size */\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD               1024L\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_SKIP              256L\n#endif\n\n/* GC torture. */\n#if defined(DUK_USE_GC_TORTURE)\n#define DUK_GC_TORTURE(heap) do { duk_heap_mark_and_sweep((heap), 0); } while (0)\n#else\n#define DUK_GC_TORTURE(heap) do { } while (0)\n#endif\n\n/* Stringcache is used for speeding up char-offset-to-byte-offset\n * translations for non-ASCII strings.\n */\n#define DUK_HEAP_STRCACHE_SIZE                            4\n#define DUK_HEAP_STRINGCACHE_NOCACHE_LIMIT                16  /* strings up to the this length are not cached */\n\n/* Some list management macros. */\n#define DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap,hdr)     duk_heap_insert_into_heap_allocated((heap), (hdr))\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_HEAP_REMOVE_FROM_HEAP_ALLOCATED(heap,hdr)     duk_heap_remove_from_heap_allocated((heap), (hdr))\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n#define DUK_HEAP_INSERT_INTO_FINALIZE_LIST(heap,hdr)      duk_heap_insert_into_finalize_list((heap), (hdr))\n#define DUK_HEAP_REMOVE_FROM_FINALIZE_LIST(heap,hdr)      duk_heap_remove_from_finalize_list((heap), (hdr))\n#endif\n\n/*\n *  Built-in strings\n */\n\n/* heap string indices are autogenerated in duk_strings.h */\n#if defined(DUK_USE_ROM_STRINGS)\n#define DUK_HEAP_GET_STRING(heap,idx) \\\n\t((duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_stridx[(idx)]))\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HEAP_GET_STRING(heap,idx) \\\n\t((duk_hstring *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (heap)->strs16[(idx)]))\n#else\n#define DUK_HEAP_GET_STRING(heap,idx) \\\n\t((heap)->strs[(idx)])\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n/*\n *  Raw memory calls: relative to heap, but no GC interaction\n */\n\n#define DUK_ALLOC_RAW(heap,size) \\\n\t((heap)->alloc_func((heap)->heap_udata, (size)))\n\n#define DUK_REALLOC_RAW(heap,ptr,newsize) \\\n\t((heap)->realloc_func((heap)->heap_udata, (void *) (ptr), (newsize)))\n\n#define DUK_FREE_RAW(heap,ptr) \\\n\t((heap)->free_func((heap)->heap_udata, (void *) (ptr)))\n\n/*\n *  Memory calls: relative to heap, GC interaction, but no error throwing.\n *\n *  XXX: Currently a mark-and-sweep triggered by memory allocation will run\n *  using the heap->heap_thread.  This thread is also used for running\n *  mark-and-sweep finalization; this is not ideal because it breaks the\n *  isolation between multiple global environments.\n *\n *  Notes:\n *\n *    - DUK_FREE() is required to ignore NULL and any other possible return\n *      value of a zero-sized alloc/realloc (same as ANSI C free()).\n *\n *    - There is no DUK_REALLOC_ZEROED because we don't assume to know the\n *      old size.  Caller must zero the reallocated memory.\n *\n *    - DUK_REALLOC_INDIRECT() must be used when a mark-and-sweep triggered\n *      by an allocation failure might invalidate the original 'ptr', thus\n *      causing a realloc retry to use an invalid pointer.  Example: we're\n *      reallocating the value stack and a finalizer resizes the same value\n *      stack during mark-and-sweep.  The indirect variant requests for the\n *      current location of the pointer being reallocated using a callback\n *      right before every realloc attempt; this circuitous approach is used\n *      to avoid strict aliasing issues in a more straightforward indirect\n *      pointer (void **) approach.  Note: the pointer in the storage\n *      location is read but is NOT updated; the caller must do that.\n */\n\n/* callback for indirect reallocs, request for current pointer */\ntypedef void *(*duk_mem_getptr)(duk_heap *heap, void *ud);\n\n#define DUK_ALLOC(heap,size)                            duk_heap_mem_alloc((heap), (size))\n#define DUK_ALLOC_ZEROED(heap,size)                     duk_heap_mem_alloc_zeroed((heap), (size))\n#define DUK_REALLOC(heap,ptr,newsize)                   duk_heap_mem_realloc((heap), (ptr), (newsize))\n#define DUK_REALLOC_INDIRECT(heap,cb,ud,newsize)        duk_heap_mem_realloc_indirect((heap), (cb), (ud), (newsize))\n#define DUK_FREE(heap,ptr)                              duk_heap_mem_free((heap), (ptr))\n\n/*\n *  Checked allocation, relative to a thread\n *\n *  DUK_FREE_CHECKED() doesn't actually throw, but accepts a 'thr' argument\n *  for convenience.\n */\n\n#define DUK_ALLOC_CHECKED(thr,size)                     duk_heap_mem_alloc_checked((thr), (size))\n#define DUK_ALLOC_CHECKED_ZEROED(thr,size)              duk_heap_mem_alloc_checked_zeroed((thr), (size))\n#define DUK_FREE_CHECKED(thr,ptr)                       duk_heap_mem_free((thr)->heap, (ptr))\n\n/*\n *  Memory constants\n */\n\n#define DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT           10  /* Retry allocation after mark-and-sweep for this\n                                                              * many times.  A single mark-and-sweep round is\n                                                              * not guaranteed to free all unreferenced memory\n                                                              * because of finalization (in fact, ANY number of\n                                                              * rounds is strictly not enough).\n                                                              */\n\n#define DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT  3  /* Starting from this round, use emergency mode\n                                                              * for mark-and-sweep.\n                                                              */\n\n/*\n *  Debugger support\n */\n\n/* Maximum number of breakpoints.  Only breakpoints that are set are\n * consulted so increasing this has no performance impact.\n */\n#define DUK_HEAP_MAX_BREAKPOINTS          16\n\n/* Opcode interval for a Date-based status/peek rate limit check.  Only\n * relevant when debugger is attached.  Requesting a timestamp may be a\n * slow operation on some platforms so this shouldn't be too low.  On the\n * other hand a high value makes Duktape react to a pause request slowly.\n */\n#define DUK_HEAP_DBG_RATELIMIT_OPCODES    4000\n\n/* Milliseconds between status notify and transport peeks. */\n#define DUK_HEAP_DBG_RATELIMIT_MILLISECS  200\n\n/* Debugger pause flags. */\n#define DUK_PAUSE_FLAG_ONE_OPCODE        (1U << 0)   /* pause when a single opcode has been executed */\n#define DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE (1U << 1)   /* one opcode pause actually active; artifact of current implementation */\n#define DUK_PAUSE_FLAG_LINE_CHANGE       (1U << 2)   /* pause when current line number changes */\n#define DUK_PAUSE_FLAG_FUNC_ENTRY        (1U << 3)   /* pause when entering a function */\n#define DUK_PAUSE_FLAG_FUNC_EXIT         (1U << 4)   /* pause when exiting current function */\n#define DUK_PAUSE_FLAG_CAUGHT_ERROR      (1U << 5)   /* pause when about to throw an error that is caught */\n#define DUK_PAUSE_FLAG_UNCAUGHT_ERROR    (1U << 6)   /* pause when about to throw an error that won't be caught */\n\nstruct duk_breakpoint {\n\tduk_hstring *filename;\n\tduk_uint32_t line;\n};\n\n/*\n *  String cache should ideally be at duk_hthread level, but that would\n *  cause string finalization to slow down relative to the number of\n *  threads; string finalization must check the string cache for \"weak\"\n *  references to the string being finalized to avoid dead pointers.\n *\n *  Thus, string caches are now at the heap level now.\n */\n\nstruct duk_strcache_entry {\n\tduk_hstring *h;\n\tduk_uint32_t bidx;\n\tduk_uint32_t cidx;\n};\n\n/*\n *  Longjmp state, contains the information needed to perform a longjmp.\n *  Longjmp related values are written to value1, value2, and iserror.\n */\n\nstruct duk_ljstate {\n\tduk_jmpbuf *jmpbuf_ptr;   /* current setjmp() catchpoint */\n\tduk_small_uint_t type;    /* longjmp type */\n\tduk_bool_t iserror;       /* isError flag for yield */\n\tduk_tval value1;          /* 1st related value (type specific) */\n\tduk_tval value2;          /* 2nd related value (type specific) */\n};\n\n#define DUK_ASSERT_LJSTATE_UNSET(heap) do { \\\n\t\tDUK_ASSERT(heap != NULL); \\\n\t\tDUK_ASSERT(heap->lj.type == DUK_LJ_TYPE_UNKNOWN); \\\n\t\tDUK_ASSERT(heap->lj.iserror == 0); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&heap->lj.value1)); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&heap->lj.value2)); \\\n\t} while (0)\n#define DUK_ASSERT_LJSTATE_SET(heap) do { \\\n\t\tDUK_ASSERT(heap != NULL); \\\n\t\tDUK_ASSERT(heap->lj.type != DUK_LJ_TYPE_UNKNOWN); \\\n\t} while (0)\n\n/*\n *  Literal intern cache\n */\n\nstruct duk_litcache_entry {\n\tconst duk_uint8_t *addr;\n\tduk_hstring *h;\n};\n\n/*\n *  Main heap structure\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_heap_assert_valid(duk_heap *heap);\n#define DUK_HEAP_ASSERT_VALID(heap)  do { duk_heap_assert_valid((heap)); } while (0)\n#else\n#define DUK_HEAP_ASSERT_VALID(heap)  do {} while (0)\n#endif\n\nstruct duk_heap {\n\tduk_small_uint_t flags;\n\n\t/* Allocator functions. */\n\tduk_alloc_function alloc_func;\n\tduk_realloc_function realloc_func;\n\tduk_free_function free_func;\n\n\t/* Heap udata, used for allocator functions but also for other heap\n\t * level callbacks like fatal function, pointer compression, etc.\n\t */\n\tvoid *heap_udata;\n\n\t/* Fatal error handling, called e.g. when a longjmp() is needed but\n\t * lj.jmpbuf_ptr is NULL.  fatal_func must never return; it's not\n\t * declared as \"noreturn\" because doing that for typedefs is a bit\n\t * challenging portability-wise.\n\t */\n\tduk_fatal_function fatal_func;\n\n\t/* Main list of allocated heap objects.  Objects are either here,\n\t * in finalize_list waiting for processing, or in refzero_list\n\t * temporarily while a DECREF refzero cascade finishes.\n\t */\n\tduk_heaphdr *heap_allocated;\n\n\t/* Temporary work list for freeing a cascade of objects when a DECREF\n\t * (or DECREF_NORZ) encounters a zero refcount.  Using a work list\n\t * allows fixed C stack size when refcounts go to zero for a chain of\n\t * objects.  Outside of DECREF this is always a NULL because DECREF is\n\t * processed without side effects (only memory free calls).\n\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_heaphdr *refzero_list;\n#endif\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t/* Work list for objects to be finalized. */\n\tduk_heaphdr *finalize_list;\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Object whose finalizer is executing right now (no nesting). */\n\tduk_heaphdr *currently_finalizing;\n#endif\n#endif\n\n\t/* Freelist for duk_activations and duk_catchers. */\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\tduk_activation *activation_free;\n#endif\n#if defined(DUK_USE_CACHE_CATCHER)\n\tduk_catcher *catcher_free;\n#endif\n\n\t/* Voluntary mark-and-sweep trigger counter.  Intentionally signed\n\t * because we continue decreasing the value when voluntary GC cannot\n\t * run.\n\t */\n#if defined(DUK_USE_VOLUNTARY_GC)\n\tduk_int_t ms_trigger_counter;\n#endif\n\n\t/* Mark-and-sweep recursion control: too deep recursion causes\n\t * multi-pass processing to avoid growing C stack without bound.\n\t */\n\tduk_uint_t ms_recursion_depth;\n\n\t/* Mark-and-sweep flags automatically active (used for critical sections). */\n\tduk_small_uint_t ms_base_flags;\n\n\t/* Mark-and-sweep running flag.  Prevents re-entry, and also causes\n\t * refzero events to be ignored (= objects won't be queued to refzero_list).\n\t *\n\t * 0: mark-and-sweep not running\n\t * 1: mark-and-sweep is running\n\t * 2: heap destruction active or debugger active, prevent mark-and-sweep\n\t *    and refzero processing (but mark-and-sweep not itself running)\n\t */\n\tduk_uint_t ms_running;\n\n\t/* Mark-and-sweep prevent count, stacking.  Used to avoid M&S side\n\t * effects (besides finalizers which are controlled separately) such\n\t * as compacting the string table or object property tables.  This\n\t * is also bumped when ms_running is set to prevent recursive re-entry.\n\t * Can also be bumped when mark-and-sweep is not running.\n\t */\n\tduk_uint_t ms_prevent_count;\n\n\t/* Finalizer processing prevent count, stacking.  Bumped when finalizers\n\t * are processed to prevent recursive finalizer processing (first call site\n\t * processing finalizers handles all finalizers until the list is empty).\n\t * Can also be bumped explicitly to prevent finalizer execution.\n\t */\n\tduk_uint_t pf_prevent_count;\n\n\t/* When processing finalize_list, don't actually run finalizers but\n\t * queue finalizable objects back to heap_allocated as is.  This is\n\t * used during heap destruction to deal with finalizers that keep\n\t * on creating more finalizable garbage.\n\t */\n\tduk_uint_t pf_skip_finalizers;\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Set when we're in a critical path where an error throw would cause\n\t * e.g. sandboxing/protected call violations or state corruption.  This\n\t * is just used for asserts.\n\t */\n\tduk_bool_t error_not_allowed;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Set when heap is still being initialized, helps with writing\n\t * some assertions.\n\t */\n\tduk_bool_t heap_initializing;\n#endif\n\n\t/* Marker for detecting internal \"double faults\", errors thrown when\n\t * we're trying to create an error object, see duk_error_throw.c.\n\t */\n\tduk_bool_t creating_error;\n\n\t/* Marker for indicating we're calling a user error augmentation\n\t * (errCreate/errThrow) function.  Errors created/thrown during\n\t * such a call are not augmented.\n\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tduk_bool_t augmenting_error;\n#endif\n\n\t/* Longjmp state. */\n\tduk_ljstate lj;\n\n\t/* Heap thread, used internally and for finalization. */\n\tduk_hthread *heap_thread;\n\n\t/* Current running thread. */\n\tduk_hthread *curr_thread;\n\n\t/* Heap level \"stash\" object (e.g., various reachability roots). */\n\tduk_hobject *heap_object;\n\n\t/* duk_handle_call / duk_handle_safe_call recursion depth limiting */\n\tduk_int_t call_recursion_depth;\n\tduk_int_t call_recursion_limit;\n\n\t/* Mix-in value for computing string hashes; should be reasonably unpredictable. */\n\tduk_uint32_t hash_seed;\n\n\t/* Random number state for duk_util_tinyrandom.c. */\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\n#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS)\n\tduk_uint32_t rnd_state;  /* State for Shamir's three-op algorithm */\n#else\n\tduk_uint64_t rnd_state[2];  /* State for xoroshiro128+ */\n#endif\n#endif\n\n\t/* Counter for unique local symbol creation. */\n\t/* XXX: When 64-bit types are available, it would be more efficient to\n\t * use a duk_uint64_t at least for incrementing but maybe also for\n\t * string formatting in the Symbol constructor.\n\t */\n\tduk_uint32_t sym_counter[2];\n\n\t/* For manual debugging: instruction count based on executor and\n\t * interrupt counter book-keeping.  Inspect debug logs to see how\n\t * they match up.\n\t */\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\tduk_int_t inst_count_exec;\n\tduk_int_t inst_count_interrupt;\n#endif\n\n\t/* Debugger state. */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* Callbacks and udata; dbg_read_cb != NULL is used to indicate attached state. */\n\tduk_debug_read_function dbg_read_cb;                /* required, NULL implies detached */\n\tduk_debug_write_function dbg_write_cb;              /* required */\n\tduk_debug_peek_function dbg_peek_cb;\n\tduk_debug_read_flush_function dbg_read_flush_cb;\n\tduk_debug_write_flush_function dbg_write_flush_cb;\n\tduk_debug_request_function dbg_request_cb;\n\tduk_debug_detached_function dbg_detached_cb;\n\tvoid *dbg_udata;\n\n\t/* The following are only relevant when debugger is attached. */\n\tduk_bool_t dbg_processing;              /* currently processing messages or breakpoints: don't enter message processing recursively (e.g. no breakpoints when processing debugger eval) */\n\tduk_bool_t dbg_state_dirty;             /* resend state next time executor is about to run */\n\tduk_bool_t dbg_force_restart;           /* force executor restart to recheck breakpoints; used to handle function returns (see GH-303) */\n\tduk_bool_t dbg_detaching;               /* debugger detaching; used to avoid calling detach handler recursively */\n\tduk_small_uint_t dbg_pause_flags;       /* flags for automatic pause behavior */\n\tduk_activation *dbg_pause_act;          /* activation related to pause behavior (pause on line change, function entry/exit) */\n\tduk_uint32_t dbg_pause_startline;       /* starting line number for line change related pause behavior */\n\tduk_breakpoint dbg_breakpoints[DUK_HEAP_MAX_BREAKPOINTS];  /* breakpoints: [0,breakpoint_count[ gc reachable */\n\tduk_small_uint_t dbg_breakpoint_count;\n\tduk_breakpoint *dbg_breakpoints_active[DUK_HEAP_MAX_BREAKPOINTS + 1];  /* currently active breakpoints: NULL term, borrowed pointers */\n\t/* XXX: make active breakpoints actual copies instead of pointers? */\n\n\t/* These are for rate limiting Status notifications and transport peeking. */\n\tduk_uint_t dbg_exec_counter;            /* cumulative opcode execution count (overflows are OK) */\n\tduk_uint_t dbg_last_counter;            /* value of dbg_exec_counter when we last did a Date-based check */\n\tduk_double_t dbg_last_time;             /* time when status/peek was last done (Date-based rate limit) */\n\n\t/* Used to support single-byte stream lookahead. */\n\tduk_bool_t dbg_have_next_byte;\n\tduk_uint8_t dbg_next_byte;\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_bool_t dbg_calling_transport;       /* transport call in progress, calling into Duktape forbidden */\n#endif\n\n\t/* String intern table (weak refs). */\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable16;\n#else\n\tduk_hstring **strtable;\n#endif\n\tduk_uint32_t st_mask;    /* mask for lookup, st_size - 1 */\n\tduk_uint32_t st_size;    /* stringtable size */\n#if (DUK_USE_STRTAB_MINSIZE != DUK_USE_STRTAB_MAXSIZE)\n\tduk_uint32_t st_count;   /* string count for resize load factor checks */\n#endif\n\tduk_bool_t st_resizing;  /* string table is being resized; avoid recursive resize */\n\n\t/* String access cache (codepoint offset -> byte offset) for fast string\n\t * character looping; 'weak' reference which needs special handling in GC.\n\t */\n\tduk_strcache_entry strcache[DUK_HEAP_STRCACHE_SIZE];\n\n#if defined(DUK_USE_LITCACHE_SIZE)\n\t/* Literal intern cache.  When enabled, strings interned as literals\n\t * (e.g. duk_push_literal()) will be pinned and cached for the lifetime\n\t * of the heap.\n\t */\n\tduk_litcache_entry litcache[DUK_USE_LITCACHE_SIZE];\n#endif\n\n\t/* Built-in strings. */\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* No field needed when strings are in ROM. */\n#else\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t strs16[DUK_HEAP_NUM_STRINGS];\n#else\n\tduk_hstring *strs[DUK_HEAP_NUM_STRINGS];\n#endif\n#endif\n\n\t/* Stats. */\n#if defined(DUK_USE_DEBUG)\n\tduk_int_t stats_exec_opcodes;\n\tduk_int_t stats_exec_interrupt;\n\tduk_int_t stats_exec_throw;\n\tduk_int_t stats_call_all;\n\tduk_int_t stats_call_tailcall;\n\tduk_int_t stats_call_ecmatoecma;\n\tduk_int_t stats_safecall_all;\n\tduk_int_t stats_safecall_nothrow;\n\tduk_int_t stats_safecall_throw;\n\tduk_int_t stats_ms_try_count;\n\tduk_int_t stats_ms_skip_count;\n\tduk_int_t stats_ms_emergency_count;\n\tduk_int_t stats_strtab_intern_hit;\n\tduk_int_t stats_strtab_intern_miss;\n\tduk_int_t stats_strtab_resize_check;\n\tduk_int_t stats_strtab_resize_grow;\n\tduk_int_t stats_strtab_resize_shrink;\n\tduk_int_t stats_strtab_litcache_hit;\n\tduk_int_t stats_strtab_litcache_miss;\n\tduk_int_t stats_strtab_litcache_pin;\n\tduk_int_t stats_object_realloc_props;\n\tduk_int_t stats_object_abandon_array;\n\tduk_int_t stats_getownpropdesc_count;\n\tduk_int_t stats_getownpropdesc_hit;\n\tduk_int_t stats_getownpropdesc_miss;\n\tduk_int_t stats_getpropdesc_count;\n\tduk_int_t stats_getpropdesc_hit;\n\tduk_int_t stats_getpropdesc_miss;\n\tduk_int_t stats_getprop_all;\n\tduk_int_t stats_getprop_arrayidx;\n\tduk_int_t stats_getprop_bufobjidx;\n\tduk_int_t stats_getprop_bufferidx;\n\tduk_int_t stats_getprop_bufferlen;\n\tduk_int_t stats_getprop_stringidx;\n\tduk_int_t stats_getprop_stringlen;\n\tduk_int_t stats_getprop_proxy;\n\tduk_int_t stats_getprop_arguments;\n\tduk_int_t stats_putprop_all;\n\tduk_int_t stats_putprop_arrayidx;\n\tduk_int_t stats_putprop_bufobjidx;\n\tduk_int_t stats_putprop_bufferidx;\n\tduk_int_t stats_putprop_proxy;\n\tduk_int_t stats_getvar_all;\n\tduk_int_t stats_putvar_all;\n\tduk_int_t stats_envrec_delayedcreate;\n\tduk_int_t stats_envrec_create;\n\tduk_int_t stats_envrec_newenv;\n\tduk_int_t stats_envrec_oldenv;\n\tduk_int_t stats_envrec_pushclosure;\n#endif\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL\nduk_heap *duk_heap_alloc(duk_alloc_function alloc_func,\n                         duk_realloc_function realloc_func,\n                         duk_free_function free_func,\n                         void *heap_udata,\n                         duk_fatal_function fatal_func);\nDUK_INTERNAL_DECL void duk_heap_free(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_free_hobject(duk_heap *heap, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_free_hbuffer(duk_heap *heap, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_free_hstring(duk_heap *heap, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr);\n\nDUK_INTERNAL_DECL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphdr *hdr);\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL_DECL void duk_heap_remove_from_heap_allocated(duk_heap *heap, duk_heaphdr *hdr);\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL_DECL void duk_heap_insert_into_finalize_list(duk_heap *heap, duk_heaphdr *hdr);\nDUK_INTERNAL_DECL void duk_heap_remove_from_finalize_list(duk_heap *heap, duk_heaphdr *hdr);\n#endif\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL duk_bool_t duk_heap_in_heap_allocated(duk_heap *heap, duk_heaphdr *ptr);\n#endif\n#if defined(DUK_USE_INTERRUPT_COUNTER)\nDUK_INTERNAL_DECL void duk_heap_switch_thread(duk_heap *heap, duk_hthread *new_thr);\n#endif\n\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen);\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t len);\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_literal_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen);\n#endif\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_u32(duk_heap *heap, duk_uint32_t val);\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_u32_checked(duk_hthread *thr, duk_uint32_t val);\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL_DECL void duk_heap_strtable_unlink(duk_heap *heap, duk_hstring *h);\n#endif\nDUK_INTERNAL_DECL void duk_heap_strtable_unlink_prev(duk_heap *heap, duk_hstring *h, duk_hstring *prev);\nDUK_INTERNAL_DECL void duk_heap_strtable_force_resize(duk_heap *heap);\nDUK_INTERNAL void duk_heap_strtable_free(duk_heap *heap);\n#if defined(DUK_USE_DEBUG)\nDUK_INTERNAL void duk_heap_strtable_dump(duk_heap *heap);\n#endif\n\nDUK_INTERNAL_DECL void duk_heap_strcache_string_remove(duk_heap *heap, duk_hstring *h);\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *thr, duk_hstring *h, duk_uint_fast32_t char_offset);\n\n#if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS)\nDUK_INTERNAL_DECL void *duk_default_alloc_function(void *udata, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_default_realloc_function(void *udata, void *ptr, duk_size_t newsize);\nDUK_INTERNAL_DECL void duk_default_free_function(void *udata, void *ptr);\n#endif\n\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc(duk_heap *heap, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc_zeroed(duk_heap *heap, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc_checked(duk_hthread *thr, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc_checked_zeroed(duk_hthread *thr, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, duk_size_t newsize);\nDUK_INTERNAL_DECL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize);\nDUK_INTERNAL_DECL void duk_heap_mem_free(duk_heap *heap, void *ptr);\n\nDUK_INTERNAL_DECL void duk_heap_free_freelists(duk_heap *heap);\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL_DECL void duk_heap_run_finalizer(duk_heap *heap, duk_hobject *obj);\nDUK_INTERNAL_DECL void duk_heap_process_finalize_list(duk_heap *heap);\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_INTERNAL_DECL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags);\n\nDUK_INTERNAL_DECL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len);\n\n#endif  /* DUK_HEAP_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_heap_alloc.c",
    "content": "/*\n *  duk_heap allocation and freeing.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_ROM_STRINGS)\n/* Fixed seed value used with ROM strings. */\n#define DUK__FIXED_HASH_SEED       0xabcd1234\n#endif\n\n/*\n *  Free a heap object.\n *\n *  Free heap object and its internal (non-heap) pointers.  Assumes that\n *  caller has removed the object from heap allocated list or the string\n *  intern table, and any weak references (which strings may have) have\n *  been already dealt with.\n */\n\nDUK_INTERNAL void duk_free_hobject(duk_heap *heap, duk_hobject *h) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_FREE(heap, DUK_HOBJECT_GET_PROPS(heap, h));\n\n\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tDUK_UNREF(f);\n\t\t/* Currently nothing to free; 'data' is a heap object */\n\t} else if (DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\tduk_hnatfunc *f = (duk_hnatfunc *) h;\n\t\tDUK_UNREF(f);\n\t\t/* Currently nothing to free */\n\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tduk_activation *act;\n\n\t\tDUK_FREE(heap, t->valstack);\n\n\t\t/* Don't free h->resumer because it exists in the heap.\n\t\t * Callstack entries also contain function pointers which\n\t\t * are not freed for the same reason.  They are decref\n\t\t * finalized and the targets are freed if necessary based\n\t\t * on their refcount (or reachability).\n\t\t */\n\t\tfor (act = t->callstack_curr; act != NULL;) {\n\t\t\tduk_activation *act_next;\n\t\t\tduk_catcher *cat;\n\n\t\t\tfor (cat = act->cat; cat != NULL;) {\n\t\t\t\tduk_catcher *cat_next;\n\n\t\t\t\tcat_next = cat->parent;\n\t\t\t\tDUK_FREE(heap, (void *) cat);\n\t\t\t\tcat = cat_next;\n\t\t\t}\n\n\t\t\tact_next = act->parent;\n\t\t\tDUK_FREE(heap, (void *) act);\n\t\t\tact = act_next;\n\t\t}\n\n\t\t/* XXX: with 'caller' property the callstack would need\n\t\t * to be unwound to update the 'caller' properties of\n\t\t * functions in the callstack.\n\t\t */\n\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {\n\t\tduk_hboundfunc *f = (duk_hboundfunc *) (void *) h;\n\n\t\tDUK_FREE(heap, f->args);\n\t}\n\n\tDUK_FREE(heap, (void *) h);\n}\n\nDUK_INTERNAL void duk_free_hbuffer(duk_heap *heap, duk_hbuffer *h) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n\tif (DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h)) {\n\t\tduk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h;\n\t\tDUK_DDD(DUK_DDDPRINT(\"free dynamic buffer %p\", (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, g)));\n\t\tDUK_FREE(heap, DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, g));\n\t}\n\tDUK_FREE(heap, (void *) h);\n}\n\nDUK_INTERNAL void duk_free_hstring(duk_heap *heap, duk_hstring *h) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_UNREF(heap);\n\tDUK_UNREF(h);\n\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_FREE)\n\tif (DUK_HSTRING_HAS_EXTDATA(h)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"free extstr: hstring %!O, extdata: %p\",\n\t\t                     h, DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) h)));\n\t\tDUK_USE_EXTSTR_FREE(heap->heap_udata, (const void *) DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) h));\n\t}\n#endif\n\tDUK_FREE(heap, (void *) h);\n}\n\nDUK_INTERNAL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr) {\n\tDUK_ASSERT(heap);\n\tDUK_ASSERT(hdr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"free heaphdr %p, htype %ld\", (void *) hdr, (long) DUK_HEAPHDR_GET_TYPE(hdr)));\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(hdr)) {\n\tcase DUK_HTYPE_STRING:\n\t\tduk_free_hstring(heap, (duk_hstring *) hdr);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tduk_free_hobject(heap, (duk_hobject *) hdr);\n\t\tbreak;\n\tdefault:\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) == DUK_HTYPE_BUFFER);\n\t\tduk_free_hbuffer(heap, (duk_hbuffer *) hdr);\n\t}\n\n}\n\n/*\n *  Free the heap.\n *\n *  Frees heap-related non-heap-tracked allocations such as the\n *  string intern table; then frees the heap allocated objects;\n *  and finally frees the heap structure itself.  Reference counts\n *  and GC markers are ignored (and not updated) in this process,\n *  and finalizers won't be called.\n *\n *  The heap pointer and heap object pointers must not be used\n *  after this call.\n */\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\nDUK_LOCAL duk_size_t duk__heap_free_activation_freelist(duk_heap *heap) {\n\tduk_activation *act;\n\tduk_activation *act_next;\n\tduk_size_t count_act = 0;\n\n\tfor (act = heap->activation_free; act != NULL;) {\n\t\tact_next = act->parent;\n\t\tDUK_FREE(heap, (void *) act);\n\t\tact = act_next;\n#if defined(DUK_USE_DEBUG)\n\t\tcount_act++;\n#endif\n\t}\n\theap->activation_free = NULL;  /* needed when called from mark-and-sweep */\n\treturn count_act;\n}\n#endif  /* DUK_USE_CACHE_ACTIVATION */\n\n#if defined(DUK_USE_CACHE_CATCHER)\nDUK_LOCAL duk_size_t duk__heap_free_catcher_freelist(duk_heap *heap) {\n\tduk_catcher *cat;\n\tduk_catcher *cat_next;\n\tduk_size_t count_cat = 0;\n\n\tfor (cat = heap->catcher_free; cat != NULL;) {\n\t\tcat_next = cat->parent;\n\t\tDUK_FREE(heap, (void *) cat);\n\t\tcat = cat_next;\n#if defined(DUK_USE_DEBUG)\n\t\tcount_cat++;\n#endif\n\t}\n\theap->catcher_free = NULL;  /* needed when called from mark-and-sweep */\n\n\treturn count_cat;\n}\n#endif  /* DUK_USE_CACHE_CATCHER */\n\nDUK_INTERNAL void duk_heap_free_freelists(duk_heap *heap) {\n\tduk_size_t count_act = 0;\n\tduk_size_t count_cat = 0;\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\tcount_act = duk__heap_free_activation_freelist(heap);\n#endif\n#if defined(DUK_USE_CACHE_CATCHER)\n\tcount_cat = duk__heap_free_catcher_freelist(heap);\n#endif\n\tDUK_UNREF(heap);\n\tDUK_UNREF(count_act);\n\tDUK_UNREF(count_cat);\n\n\tDUK_D(DUK_DPRINT(\"freed %ld activation freelist entries, %ld catcher freelist entries\",\n\t                 (long) count_act, (long) count_cat));\n}\n\nDUK_LOCAL void duk__free_allocated(duk_heap *heap) {\n\tduk_heaphdr *curr;\n\tduk_heaphdr *next;\n\n\tcurr = heap->heap_allocated;\n\twhile (curr) {\n\t\t/* We don't log or warn about freeing zero refcount objects\n\t\t * because they may happen with finalizer processing.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"FINALFREE (allocated): %!iO\",\n\t\t                     (duk_heaphdr *) curr));\n\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\tduk_heap_free_heaphdr_raw(heap, curr);\n\t\tcurr = next;\n\t}\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__free_finalize_list(duk_heap *heap) {\n\tduk_heaphdr *curr;\n\tduk_heaphdr *next;\n\n\tcurr = heap->finalize_list;\n\twhile (curr) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"FINALFREE (finalize_list): %!iO\",\n\t\t                     (duk_heaphdr *) curr));\n\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\tduk_heap_free_heaphdr_raw(heap, curr);\n\t\tcurr = next;\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_LOCAL void duk__free_stringtable(duk_heap *heap) {\n\t/* strings are only tracked by stringtable */\n\tduk_heap_strtable_free(heap);\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__free_run_finalizers(duk_heap *heap) {\n\tduk_heaphdr *curr;\n\tduk_uint_t round_no;\n\tduk_size_t count_all;\n\tduk_size_t count_finalized;\n\tduk_size_t curr_limit;\n\n\tDUK_ASSERT(heap != NULL);\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* refzero not running -> must be empty */\n#endif\n\tDUK_ASSERT(heap->finalize_list == NULL);  /* mark-and-sweep last pass */\n\n\tif (heap->heap_thread == NULL) {\n\t\t/* May happen when heap allocation fails right off.  There\n\t\t * cannot be any finalizable objects in this case.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"no heap_thread in heap destruct, assume no finalizable objects\"));\n\t\treturn;\n\t}\n\n\t/* Prevent finalize_list processing and mark-and-sweep entirely.\n\t * Setting ms_running != 0 also prevents refzero handling from moving\n\t * objects away from the heap_allocated list.  The flag name is a bit\n\t * misleading here.\n\t *\n\t * Use a distinct value for ms_running here (== 2) so that assertions\n\t * can detect this situation separate from the normal runtime\n\t * mark-and-sweep case.  This allows better assertions (GH-2030).\n\t */\n\tDUK_ASSERT(heap->pf_prevent_count == 0);\n\tDUK_ASSERT(heap->ms_running == 0);\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\theap->pf_prevent_count = 1;\n\theap->ms_running = 2;  /* Use distinguishable value. */\n\theap->ms_prevent_count = 1;  /* Bump, because mark-and-sweep assumes it's bumped when ms_running is set. */\n\n\tcurr_limit = 0;  /* suppress warning, not used */\n\tfor (round_no = 0; ; round_no++) {\n\t\tcurr = heap->heap_allocated;\n\t\tcount_all = 0;\n\t\tcount_finalized = 0;\n\t\twhile (curr) {\n\t\t\tcount_all++;\n\t\t\tif (DUK_HEAPHDR_IS_OBJECT(curr)) {\n\t\t\t\t/* Only objects in heap_allocated may have finalizers.  Check that\n\t\t\t\t * the object itself has a _Finalizer property (own or inherited)\n\t\t\t\t * so that we don't execute finalizers for e.g. Proxy objects.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(curr != NULL);\n\n\t\t\t\tif (DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) curr)) {\n\t\t\t\t\tif (!DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) curr)) {\n\t\t\t\t\t\tDUK_ASSERT(DUK_HEAP_HAS_FINALIZER_NORESCUE(heap));  /* maps to finalizer 2nd argument */\n\t\t\t\t\t\tduk_heap_run_finalizer(heap, (duk_hobject *) curr);\n\t\t\t\t\t\tcount_finalized++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurr = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\t}\n\n\t\t/* Each round of finalizer execution may spawn new finalizable objects\n\t\t * which is normal behavior for some applications.  Allow multiple\n\t\t * rounds of finalization, but use a shrinking limit based on the\n\t\t * first round to detect the case where a runaway finalizer creates\n\t\t * an unbounded amount of new finalizable objects.  Finalizer rescue\n\t\t * is not supported: the semantics are unclear because most of the\n\t\t * objects being finalized here are already reachable.  The finalizer\n\t\t * is given a boolean to indicate that rescue is not possible.\n\t\t *\n\t\t * See discussion in: https://github.com/svaarala/duktape/pull/473\n\t\t */\n\n\t\tif (round_no == 0) {\n\t\t\t/* Cannot wrap: each object is at least 8 bytes so count is\n\t\t\t * at most 1/8 of that.\n\t\t\t */\n\t\t\tcurr_limit = count_all * 2;\n\t\t} else {\n\t\t\tcurr_limit = (curr_limit * 3) / 4;   /* Decrease by 25% every round */\n\t\t}\n\t\tDUK_D(DUK_DPRINT(\"finalizer round %ld complete, %ld objects, tried to execute %ld finalizers, current limit is %ld\",\n\t\t                 (long) round_no, (long) count_all, (long) count_finalized, (long) curr_limit));\n\n\t\tif (count_finalized == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"no more finalizable objects, forced finalization finished\"));\n\t\t\tbreak;\n\t\t}\n\t\tif (count_finalized >= curr_limit) {\n\t\t\tDUK_D(DUK_DPRINT(\"finalizer count above limit, potentially runaway finalizer; skip remaining finalizers\"));\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tDUK_ASSERT(heap->ms_running == 2);\n\tDUK_ASSERT(heap->pf_prevent_count == 1);\n\theap->ms_running = 0;\n\theap->pf_prevent_count = 0;\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_INTERNAL void duk_heap_free(duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"free heap: %p\", (void *) heap));\n\n#if defined(DUK_USE_DEBUG)\n\tduk_heap_strtable_dump(heap);\n#endif\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* Detach a debugger if attached (can be called multiple times)\n\t * safely.\n\t */\n\t/* XXX: Add a flag to reject an attempt to re-attach?  Otherwise\n\t * the detached callback may immediately reattach.\n\t */\n\tduk_debug_do_detach(heap);\n#endif\n\n\t/* Execute finalizers before freeing the heap, even for reachable\n\t * objects.  This gives finalizers the chance to free any native\n\t * resources like file handles, allocations made outside Duktape,\n\t * etc.  This is quite tricky to get right, so that all finalizer\n\t * guarantees are honored.\n\t *\n\t * Run mark-and-sweep a few times just in case (unreachable object\n\t * finalizers run already here).  The last round must rescue objects\n\t * from the previous round without running any more finalizers.  This\n\t * ensures rescued objects get their FINALIZED flag cleared so that\n\t * their finalizer is called once more in forced finalization to\n\t * satisfy finalizer guarantees.  However, we don't want to run any\n\t * more finalizers because that'd required one more loop, and so on.\n\t *\n\t * XXX: this perhaps requires an execution time limit.\n\t */\n\tDUK_D(DUK_DPRINT(\"execute finalizers before freeing heap\"));\n\tDUK_ASSERT(heap->pf_skip_finalizers == 0);\n\tDUK_D(DUK_DPRINT(\"forced gc #1 in heap destruction\"));\n\tduk_heap_mark_and_sweep(heap, 0);\n\tDUK_D(DUK_DPRINT(\"forced gc #2 in heap destruction\"));\n\tduk_heap_mark_and_sweep(heap, 0);\n\tDUK_D(DUK_DPRINT(\"forced gc #3 in heap destruction (don't run finalizers)\"));\n\theap->pf_skip_finalizers = 1;\n\tduk_heap_mark_and_sweep(heap, 0);  /* Skip finalizers; queue finalizable objects to heap_allocated. */\n\n\t/* There are never objects in refzero_list at this point, or at any\n\t * point beyond a DECREF (even a DECREF_NORZ).  Since Duktape 2.1\n\t * refzero_list processing is side effect free, so it is always\n\t * processed to completion by a DECREF initially triggering a zero\n\t * refcount.\n\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always processed to completion inline. */\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tDUK_ASSERT(heap->finalize_list == NULL);  /* Last mark-and-sweep with skip_finalizers. */\n#endif\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tDUK_D(DUK_DPRINT(\"run finalizers for remaining finalizable objects\"));\n\tDUK_HEAP_SET_FINALIZER_NORESCUE(heap);  /* Rescue no longer supported. */\n\tduk__free_run_finalizers(heap);\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n\t/* Note: heap->heap_thread, heap->curr_thread, and heap->heap_object\n\t * are on the heap allocated list.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"freeing temporary freelists\"));\n\tduk_heap_free_freelists(heap);\n\n\tDUK_D(DUK_DPRINT(\"freeing heap_allocated of heap: %p\", (void *) heap));\n\tduk__free_allocated(heap);\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always processed to completion inline. */\n#endif\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tDUK_D(DUK_DPRINT(\"freeing finalize_list of heap: %p\", (void *) heap));\n\tduk__free_finalize_list(heap);\n#endif\n\n\tDUK_D(DUK_DPRINT(\"freeing string table of heap: %p\", (void *) heap));\n\tduk__free_stringtable(heap);\n\n\tDUK_D(DUK_DPRINT(\"freeing heap structure: %p\", (void *) heap));\n\theap->free_func(heap->heap_udata, heap);\n}\n\n/*\n *  Allocate a heap.\n *\n *  String table is initialized with built-in strings from genbuiltins.py,\n *  either by dynamically creating the strings or by referring to ROM strings.\n */\n\n#if defined(DUK_USE_ROM_STRINGS)\nDUK_LOCAL duk_bool_t duk__init_heap_strings(duk_heap *heap) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_small_uint_t i;\n#endif\n\n\tDUK_UNREF(heap);\n\n\t/* With ROM-based strings, heap->strs[] and thr->strs[] are omitted\n\t * so nothing to initialize for strs[].\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tfor (i = 0; i < sizeof(duk_rom_strings_lookup) / sizeof(const duk_hstring *); i++) {\n\t\tconst duk_hstring *h;\n\t\tduk_uint32_t hash;\n\n\t\th = duk_rom_strings_lookup[i];\n\t\twhile (h != NULL) {\n\t\t\thash = duk_heap_hashstring(heap, (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\t\t\tDUK_DD(DUK_DDPRINT(\"duk_rom_strings_lookup[%d] -> hash 0x%08lx, computed 0x%08lx\",\n\t\t\t                   (int) i, (unsigned long) DUK_HSTRING_GET_HASH(h), (unsigned long) hash));\n\t\t\tDUK_ASSERT(hash == (duk_uint32_t) DUK_HSTRING_GET_HASH(h));\n\n\t\t\th = (const duk_hstring *) h->hdr.h_next;\n\t\t}\n\t}\n#endif\n\treturn 1;\n}\n#else  /* DUK_USE_ROM_STRINGS */\n\nDUK_LOCAL duk_bool_t duk__init_heap_strings(duk_heap *heap) {\n\tduk_bitdecoder_ctx bd_ctx;\n\tduk_bitdecoder_ctx *bd = &bd_ctx;  /* convenience */\n\tduk_small_uint_t i;\n\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tbd->data = (const duk_uint8_t *) duk_strings_data;\n\tbd->length = (duk_size_t) DUK_STRDATA_DATA_LENGTH;\n\n\tfor (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) {\n\t\tduk_uint8_t tmp[DUK_STRDATA_MAX_STRLEN];\n\t\tduk_small_uint_t len;\n\t\tduk_hstring *h;\n\n\t\tlen = duk_bd_decode_bitpacked_string(bd, tmp);\n\n\t\t/* No need to length check string: it will never exceed even\n\t\t * the 16-bit length maximum.\n\t\t */\n\t\tDUK_ASSERT(len <= 0xffffUL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"intern built-in string %ld\", (long) i));\n\t\th = duk_heap_strtable_intern(heap, tmp, len);\n\t\tif (!h) {\n\t\t\tgoto failed;\n\t\t}\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h));\n\n\t\t/* Special flags checks.  Since these strings are always\n\t\t * reachable and a string cannot appear twice in the string\n\t\t * table, there's no need to check/set these flags elsewhere.\n\t\t * The 'internal' flag is set by string intern code.\n\t\t */\n\t\tif (i == DUK_STRIDX_EVAL || i == DUK_STRIDX_LC_ARGUMENTS) {\n\t\t\tDUK_HSTRING_SET_EVAL_OR_ARGUMENTS(h);\n\t\t}\n\t\tif (i >= DUK_STRIDX_START_RESERVED && i < DUK_STRIDX_END_RESERVED) {\n\t\t\tDUK_HSTRING_SET_RESERVED_WORD(h);\n\t\t\tif (i >= DUK_STRIDX_START_STRICT_RESERVED) {\n\t\t\t\tDUK_HSTRING_SET_STRICT_RESERVED_WORD(h);\n\t\t\t}\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"interned: %!O\", (duk_heaphdr *) h));\n\n\t\t/* XXX: The incref macro takes a thread pointer but doesn't\n\t\t * use it right now.\n\t\t */\n\t\tDUK_HSTRING_INCREF(_never_referenced_, h);\n\n#if defined(DUK_USE_HEAPPTR16)\n\t\theap->strs16[i] = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) h);\n#else\n\t\theap->strs[i] = h;\n#endif\n\t}\n\n\treturn 1;\n\n failed:\n\treturn 0;\n}\n#endif  /* DUK_USE_ROM_STRINGS */\n\nDUK_LOCAL duk_bool_t duk__init_heap_thread(duk_heap *heap) {\n\tduk_hthread *thr;\n\n\tDUK_D(DUK_DPRINT(\"heap init: alloc heap thread\"));\n\tthr = duk_hthread_alloc_unchecked(heap,\n\t                                  DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                  DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_THREAD));\n\tif (thr == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"failed to alloc heap_thread\"));\n\t\treturn 0;\n\t}\n\tthr->state = DUK_HTHREAD_STATE_INACTIVE;\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* No strs[] pointer. */\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n\tthr->strs16 = heap->strs16;\n#else\n\tthr->strs = heap->strs;\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n\theap->heap_thread = thr;\n\tDUK_HTHREAD_INCREF(thr, thr);  /* Note: first argument not really used */\n\n\t/* 'thr' is now reachable */\n\n\tDUK_D(DUK_DPRINT(\"heap init: init heap thread stacks\"));\n\tif (!duk_hthread_init_stacks(heap, thr)) {\n\t\treturn 0;\n\t}\n\n\t/* XXX: this may now fail, and is not handled correctly */\n\tduk_hthread_create_builtin_objects(thr);\n\n\t/* default prototype */\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) thr, thr->builtins[DUK_BIDX_THREAD_PROTOTYPE]);\n\n\treturn 1;\n}\n\n#if defined(DUK_USE_DEBUG)\n#define DUK__DUMPSZ(t)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"\" #t \"=%ld\", (long) sizeof(t))); \\\n\t} while (0)\n\n/* These is not 100% because format would need to be non-portable \"long long\".\n * Also print out as doubles to catch cases where the \"long\" type is not wide\n * enough; the limits will then not be printed accurately but the magnitude\n * will be correct.\n */\n#define DUK__DUMPLM_SIGNED_RAW(t,a,b)  do { \\\n\t\tDUK_D(DUK_DPRINT(t \"=[%ld,%ld]=[%lf,%lf]\", \\\n\t\t                 (long) (a), (long) (b), \\\n\t\t                 (double) (a), (double) (b))); \\\n\t} while (0)\n#define DUK__DUMPLM_UNSIGNED_RAW(t,a,b)  do { \\\n\t\tDUK_D(DUK_DPRINT(t \"=[%lu,%lu]=[%lf,%lf]\", \\\n\t\t                 (unsigned long) (a), (unsigned long) (b), \\\n\t\t                 (double) (a), (double) (b))); \\\n\t} while (0)\n#define DUK__DUMPLM_SIGNED(t)  do { \\\n\t\tDUK__DUMPLM_SIGNED_RAW(\"DUK_\" #t \"_{MIN,MAX}\", DUK_##t##_MIN, DUK_##t##_MAX); \\\n\t} while (0)\n#define DUK__DUMPLM_UNSIGNED(t)  do { \\\n\t\tDUK__DUMPLM_UNSIGNED_RAW(\"DUK_\" #t \"_{MIN,MAX}\", DUK_##t##_MIN, DUK_##t##_MAX); \\\n\t} while (0)\n\nDUK_LOCAL void duk__dump_type_sizes(void) {\n\tDUK_D(DUK_DPRINT(\"sizeof()\"));\n\n\t/* basic platform types */\n\tDUK__DUMPSZ(char);\n\tDUK__DUMPSZ(short);\n\tDUK__DUMPSZ(int);\n\tDUK__DUMPSZ(long);\n\tDUK__DUMPSZ(double);\n\tDUK__DUMPSZ(void *);\n\tDUK__DUMPSZ(size_t);\n\n\t/* basic types from duk_features.h */\n\tDUK__DUMPSZ(duk_uint8_t);\n\tDUK__DUMPSZ(duk_int8_t);\n\tDUK__DUMPSZ(duk_uint16_t);\n\tDUK__DUMPSZ(duk_int16_t);\n\tDUK__DUMPSZ(duk_uint32_t);\n\tDUK__DUMPSZ(duk_int32_t);\n\tDUK__DUMPSZ(duk_uint64_t);\n\tDUK__DUMPSZ(duk_int64_t);\n\tDUK__DUMPSZ(duk_uint_least8_t);\n\tDUK__DUMPSZ(duk_int_least8_t);\n\tDUK__DUMPSZ(duk_uint_least16_t);\n\tDUK__DUMPSZ(duk_int_least16_t);\n\tDUK__DUMPSZ(duk_uint_least32_t);\n\tDUK__DUMPSZ(duk_int_least32_t);\n#if defined(DUK_USE_64BIT_OPS)\n\tDUK__DUMPSZ(duk_uint_least64_t);\n\tDUK__DUMPSZ(duk_int_least64_t);\n#endif\n\tDUK__DUMPSZ(duk_uint_fast8_t);\n\tDUK__DUMPSZ(duk_int_fast8_t);\n\tDUK__DUMPSZ(duk_uint_fast16_t);\n\tDUK__DUMPSZ(duk_int_fast16_t);\n\tDUK__DUMPSZ(duk_uint_fast32_t);\n\tDUK__DUMPSZ(duk_int_fast32_t);\n#if defined(DUK_USE_64BIT_OPS)\n\tDUK__DUMPSZ(duk_uint_fast64_t);\n\tDUK__DUMPSZ(duk_int_fast64_t);\n#endif\n\tDUK__DUMPSZ(duk_uintptr_t);\n\tDUK__DUMPSZ(duk_intptr_t);\n\tDUK__DUMPSZ(duk_uintmax_t);\n\tDUK__DUMPSZ(duk_intmax_t);\n\tDUK__DUMPSZ(duk_double_t);\n\n\t/* important chosen base types */\n\tDUK__DUMPSZ(duk_int_t);\n\tDUK__DUMPSZ(duk_uint_t);\n\tDUK__DUMPSZ(duk_int_fast_t);\n\tDUK__DUMPSZ(duk_uint_fast_t);\n\tDUK__DUMPSZ(duk_small_int_t);\n\tDUK__DUMPSZ(duk_small_uint_t);\n\tDUK__DUMPSZ(duk_small_int_fast_t);\n\tDUK__DUMPSZ(duk_small_uint_fast_t);\n\n\t/* some derived types */\n\tDUK__DUMPSZ(duk_codepoint_t);\n\tDUK__DUMPSZ(duk_ucodepoint_t);\n\tDUK__DUMPSZ(duk_idx_t);\n\tDUK__DUMPSZ(duk_errcode_t);\n\tDUK__DUMPSZ(duk_uarridx_t);\n\n\t/* tval */\n\tDUK__DUMPSZ(duk_double_union);\n\tDUK__DUMPSZ(duk_tval);\n\n\t/* structs from duk_forwdecl.h */\n\tDUK__DUMPSZ(duk_jmpbuf);  /* just one 'int' for C++ exceptions */\n\tDUK__DUMPSZ(duk_heaphdr);\n\tDUK__DUMPSZ(duk_heaphdr_string);\n\tDUK__DUMPSZ(duk_hstring);\n\tDUK__DUMPSZ(duk_hstring_external);\n\tDUK__DUMPSZ(duk_hobject);\n\tDUK__DUMPSZ(duk_harray);\n\tDUK__DUMPSZ(duk_hcompfunc);\n\tDUK__DUMPSZ(duk_hnatfunc);\n\tDUK__DUMPSZ(duk_hdecenv);\n\tDUK__DUMPSZ(duk_hobjenv);\n\tDUK__DUMPSZ(duk_hthread);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tDUK__DUMPSZ(duk_hbufobj);\n#endif\n\tDUK__DUMPSZ(duk_hproxy);\n\tDUK__DUMPSZ(duk_hbuffer);\n\tDUK__DUMPSZ(duk_hbuffer_fixed);\n\tDUK__DUMPSZ(duk_hbuffer_dynamic);\n\tDUK__DUMPSZ(duk_hbuffer_external);\n\tDUK__DUMPSZ(duk_propaccessor);\n\tDUK__DUMPSZ(duk_propvalue);\n\tDUK__DUMPSZ(duk_propdesc);\n\tDUK__DUMPSZ(duk_heap);\n\tDUK__DUMPSZ(duk_activation);\n\tDUK__DUMPSZ(duk_catcher);\n\tDUK__DUMPSZ(duk_strcache_entry);\n\tDUK__DUMPSZ(duk_litcache_entry);\n\tDUK__DUMPSZ(duk_ljstate);\n\tDUK__DUMPSZ(duk_fixedbuffer);\n\tDUK__DUMPSZ(duk_bitdecoder_ctx);\n\tDUK__DUMPSZ(duk_bitencoder_ctx);\n\tDUK__DUMPSZ(duk_token);\n\tDUK__DUMPSZ(duk_re_token);\n\tDUK__DUMPSZ(duk_lexer_point);\n\tDUK__DUMPSZ(duk_lexer_ctx);\n\tDUK__DUMPSZ(duk_compiler_instr);\n\tDUK__DUMPSZ(duk_compiler_func);\n\tDUK__DUMPSZ(duk_compiler_ctx);\n\tDUK__DUMPSZ(duk_re_matcher_ctx);\n\tDUK__DUMPSZ(duk_re_compiler_ctx);\n}\nDUK_LOCAL void duk__dump_type_limits(void) {\n\tDUK_D(DUK_DPRINT(\"limits\"));\n\n\t/* basic types */\n\tDUK__DUMPLM_SIGNED(INT8);\n\tDUK__DUMPLM_UNSIGNED(UINT8);\n\tDUK__DUMPLM_SIGNED(INT_FAST8);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST8);\n\tDUK__DUMPLM_SIGNED(INT_LEAST8);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST8);\n\tDUK__DUMPLM_SIGNED(INT16);\n\tDUK__DUMPLM_UNSIGNED(UINT16);\n\tDUK__DUMPLM_SIGNED(INT_FAST16);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST16);\n\tDUK__DUMPLM_SIGNED(INT_LEAST16);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST16);\n\tDUK__DUMPLM_SIGNED(INT32);\n\tDUK__DUMPLM_UNSIGNED(UINT32);\n\tDUK__DUMPLM_SIGNED(INT_FAST32);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST32);\n\tDUK__DUMPLM_SIGNED(INT_LEAST32);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST32);\n#if defined(DUK_USE_64BIT_OPS)\n\tDUK__DUMPLM_SIGNED(INT64);\n\tDUK__DUMPLM_UNSIGNED(UINT64);\n\tDUK__DUMPLM_SIGNED(INT_FAST64);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST64);\n\tDUK__DUMPLM_SIGNED(INT_LEAST64);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST64);\n#endif\n\tDUK__DUMPLM_SIGNED(INTPTR);\n\tDUK__DUMPLM_UNSIGNED(UINTPTR);\n\tDUK__DUMPLM_SIGNED(INTMAX);\n\tDUK__DUMPLM_UNSIGNED(UINTMAX);\n\n\t/* derived types */\n\tDUK__DUMPLM_SIGNED(INT);\n\tDUK__DUMPLM_UNSIGNED(UINT);\n\tDUK__DUMPLM_SIGNED(INT_FAST);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST);\n\tDUK__DUMPLM_SIGNED(SMALL_INT);\n\tDUK__DUMPLM_UNSIGNED(SMALL_UINT);\n\tDUK__DUMPLM_SIGNED(SMALL_INT_FAST);\n\tDUK__DUMPLM_UNSIGNED(SMALL_UINT_FAST);\n}\n\nDUK_LOCAL void duk__dump_misc_options(void) {\n\tDUK_D(DUK_DPRINT(\"DUK_VERSION: %ld\", (long) DUK_VERSION));\n\tDUK_D(DUK_DPRINT(\"DUK_GIT_DESCRIBE: %s\", DUK_GIT_DESCRIBE));\n\tDUK_D(DUK_DPRINT(\"OS string: %s\", DUK_USE_OS_STRING));\n\tDUK_D(DUK_DPRINT(\"architecture string: %s\", DUK_USE_ARCH_STRING));\n\tDUK_D(DUK_DPRINT(\"compiler string: %s\", DUK_USE_COMPILER_STRING));\n\tDUK_D(DUK_DPRINT(\"debug level: %ld\", (long) DUK_USE_DEBUG_LEVEL));\n#if defined(DUK_USE_PACKED_TVAL)\n\tDUK_D(DUK_DPRINT(\"DUK_USE_PACKED_TVAL: yes\"));\n#else\n\tDUK_D(DUK_DPRINT(\"DUK_USE_PACKED_TVAL: no\"));\n#endif\n#if defined(DUK_USE_VARIADIC_MACROS)\n\tDUK_D(DUK_DPRINT(\"DUK_USE_VARIADIC_MACROS: yes\"));\n#else\n\tDUK_D(DUK_DPRINT(\"DUK_USE_VARIADIC_MACROS: no\"));\n#endif\n#if defined(DUK_USE_INTEGER_LE)\n\tDUK_D(DUK_DPRINT(\"integer endianness: little\"));\n#elif defined(DUK_USE_INTEGER_ME)\n\tDUK_D(DUK_DPRINT(\"integer endianness: mixed\"));\n#elif defined(DUK_USE_INTEGER_BE)\n\tDUK_D(DUK_DPRINT(\"integer endianness: big\"));\n#else\n\tDUK_D(DUK_DPRINT(\"integer endianness: ???\"));\n#endif\n#if defined(DUK_USE_DOUBLE_LE)\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: little\"));\n#elif defined(DUK_USE_DOUBLE_ME)\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: mixed\"));\n#elif defined(DUK_USE_DOUBLE_BE)\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: big\"));\n#else\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: ???\"));\n#endif\n}\n#endif  /* DUK_USE_DEBUG */\n\nDUK_INTERNAL\nduk_heap *duk_heap_alloc(duk_alloc_function alloc_func,\n                         duk_realloc_function realloc_func,\n                         duk_free_function free_func,\n                         void *heap_udata,\n                         duk_fatal_function fatal_func) {\n\tduk_heap *res = NULL;\n\tduk_uint32_t st_initsize;\n\n\tDUK_D(DUK_DPRINT(\"allocate heap\"));\n\n\t/*\n\t *  Random config sanity asserts\n\t */\n\n\tDUK_ASSERT(DUK_USE_STRTAB_MINSIZE >= 64);\n\n\tDUK_ASSERT((DUK_HTYPE_STRING & 0x01U) == 0);\n\tDUK_ASSERT((DUK_HTYPE_BUFFER & 0x01U) == 0);\n\tDUK_ASSERT((DUK_HTYPE_OBJECT & 0x01U) == 1);  /* DUK_HEAPHDR_IS_OBJECT() relies ont his. */\n\n\t/*\n\t *  Debug dump type sizes\n\t */\n\n#if defined(DUK_USE_DEBUG)\n\tduk__dump_misc_options();\n\tduk__dump_type_sizes();\n\tduk__dump_type_limits();\n#endif\n\n\t/*\n\t *  If selftests enabled, run them as early as possible.\n\t */\n\n#if defined(DUK_USE_SELF_TESTS)\n\tDUK_D(DUK_DPRINT(\"run self tests\"));\n\tif (duk_selftest_run_tests(alloc_func, realloc_func, free_func, heap_udata) > 0) {\n\t\tfatal_func(heap_udata, \"self test(s) failed\");\n\t}\n\tDUK_D(DUK_DPRINT(\"self tests passed\"));\n#endif\n\n\t/*\n\t *  Important assert-like checks that should be enabled even\n\t *  when assertions are otherwise not enabled.\n\t */\n\n#if defined(DUK_USE_EXEC_REGCONST_OPTIMIZE)\n\t/* Can't check sizeof() using preprocessor so explicit check.\n\t * This will be optimized away in practice; unfortunately a\n\t * warning is generated on some compilers as a result.\n\t */\n#if defined(DUK_USE_PACKED_TVAL)\n\tif (sizeof(duk_tval) != 8) {\n#else\n\tif (sizeof(duk_tval) != 16) {\n#endif\n\t\tfatal_func(heap_udata, \"sizeof(duk_tval) not 8 or 16, cannot use DUK_USE_EXEC_REGCONST_OPTIMIZE option\");\n\t}\n#endif  /* DUK_USE_EXEC_REGCONST_OPTIMIZE */\n\n\t/*\n\t *  Computed values (e.g. INFINITY)\n\t */\n\n#if defined(DUK_USE_COMPUTED_NAN)\n\tdo {\n\t\t/* Workaround for some exotic platforms where NAN is missing\n\t\t * and the expression (0.0 / 0.0) does NOT result in a NaN.\n\t\t * Such platforms use the global 'duk_computed_nan' which must\n\t\t * be initialized at runtime.  Use 'volatile' to ensure that\n\t\t * the compiler will actually do the computation and not try\n\t\t * to do constant folding which might result in the original\n\t\t * problem.\n\t\t */\n\t\tvolatile double dbl1 = 0.0;\n\t\tvolatile double dbl2 = 0.0;\n\t\tduk_computed_nan = dbl1 / dbl2;\n\t} while (0);\n#endif\n\n#if defined(DUK_USE_COMPUTED_INFINITY)\n\tdo {\n\t\t/* Similar workaround for INFINITY. */\n\t\tvolatile double dbl1 = 1.0;\n\t\tvolatile double dbl2 = 0.0;\n\t\tduk_computed_infinity = dbl1 / dbl2;\n\t} while (0);\n#endif\n\n\t/*\n\t *  Allocate heap struct\n\t *\n\t *  Use a raw call, all macros expect the heap to be initialized\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 1)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"alloc duk_heap object\"));\n\tres = (duk_heap *) alloc_func(heap_udata, sizeof(duk_heap));\n\tif (!res) {\n\t\tgoto failed;\n\t}\n\n\t/*\n\t *  Zero the struct, and start initializing roughly in order\n\t */\n\n\tduk_memzero(res, sizeof(*res));\n#if defined(DUK_USE_ASSERTIONS)\n\tres->heap_initializing = 1;\n#endif\n\n\t/* explicit NULL inits */\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->heap_udata = NULL;\n\tres->heap_allocated = NULL;\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tres->refzero_list = NULL;\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tres->finalize_list = NULL;\n#if defined(DUK_USE_ASSERTIONS)\n\tres->currently_finalizing = NULL;\n#endif\n#endif\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\tres->activation_free = NULL;\n#endif\n#if defined(DUK_USE_CACHE_CATCHER)\n\tres->catcher_free = NULL;\n#endif\n\tres->heap_thread = NULL;\n\tres->curr_thread = NULL;\n\tres->heap_object = NULL;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tres->strtable16 = NULL;\n#else\n\tres->strtable = NULL;\n#endif\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* no res->strs[] */\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n\t/* res->strs16[] is zeroed and zero decodes to NULL, so no NULL inits. */\n#else\n\t{\n\t\tduk_small_uint_t i;\n\t        for (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) {\n\t\t\tres->strs[i] = NULL;\n\t        }\n\t}\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tres->dbg_read_cb = NULL;\n\tres->dbg_write_cb = NULL;\n\tres->dbg_peek_cb = NULL;\n\tres->dbg_read_flush_cb = NULL;\n\tres->dbg_write_flush_cb = NULL;\n\tres->dbg_request_cb = NULL;\n\tres->dbg_udata = NULL;\n\tres->dbg_pause_act = NULL;\n#endif\n#endif  /* DUK_USE_EXPLICIT_NULL_INIT */\n\n\tres->alloc_func = alloc_func;\n\tres->realloc_func = realloc_func;\n\tres->free_func = free_func;\n\tres->heap_udata = heap_udata;\n\tres->fatal_func = fatal_func;\n\n\t/* XXX: for now there's a pointer packing zero assumption, i.e.\n\t * NULL <=> compressed pointer 0.  If this is removed, may need\n\t * to precompute e.g. null16 here.\n\t */\n\n\t/* res->ms_trigger_counter == 0 -> now causes immediate GC; which is OK */\n\n\t/* Prevent mark-and-sweep and finalizer execution until heap is completely\n\t * initialized.\n\t */\n\tDUK_ASSERT(res->ms_prevent_count == 0);\n\tDUK_ASSERT(res->pf_prevent_count == 0);\n\tres->ms_prevent_count = 1;\n\tres->pf_prevent_count = 1;\n\tDUK_ASSERT(res->ms_running == 0);\n\n\tres->call_recursion_depth = 0;\n\tres->call_recursion_limit = DUK_USE_NATIVE_CALL_RECLIMIT;\n\n\t/* XXX: use the pointer as a seed for now: mix in time at least */\n\n\t/* The casts through duk_uintptr_t is to avoid the following GCC warning:\n\t *\n\t *   warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]\n\t *\n\t * This still generates a /Wp64 warning on VS2010 when compiling for x86.\n\t */\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* XXX: make a common DUK_USE_ option, and allow custom fixed seed? */\n\tDUK_D(DUK_DPRINT(\"using rom strings, force heap hash_seed to fixed value 0x%08lx\", (long) DUK__FIXED_HASH_SEED));\n\tres->hash_seed = (duk_uint32_t) DUK__FIXED_HASH_SEED;\n#else  /* DUK_USE_ROM_STRINGS */\n\tres->hash_seed = (duk_uint32_t) (duk_uintptr_t) res;\n#if !defined(DUK_USE_STRHASH_DENSE)\n\tres->hash_seed ^= 5381;  /* Bernstein hash init value is normally 5381; XOR it in in case pointer low bits are 0 */\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->lj.jmpbuf_ptr = NULL;\n#endif\n\tDUK_ASSERT(res->lj.type == DUK_LJ_TYPE_UNKNOWN);  /* zero */\n\tDUK_ASSERT(res->lj.iserror == 0);\n\tDUK_TVAL_SET_UNDEFINED(&res->lj.value1);\n\tDUK_TVAL_SET_UNDEFINED(&res->lj.value2);\n\n\tDUK_ASSERT_LJSTATE_UNSET(res);\n\n\t/*\n\t *  Init stringtable: fixed variant\n\t */\n\n\tst_initsize = DUK_USE_STRTAB_MINSIZE;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tres->strtable16 = (duk_uint16_t *) alloc_func(heap_udata, sizeof(duk_uint16_t) * st_initsize);\n\tif (res->strtable16 == NULL) {\n\t\tgoto failed;\n\t}\n#else\n\tres->strtable = (duk_hstring **) alloc_func(heap_udata, sizeof(duk_hstring *) * st_initsize);\n\tif (res->strtable == NULL) {\n\t\tgoto failed;\n\t}\n#endif\n\tres->st_size = st_initsize;\n\tres->st_mask = st_initsize - 1;\n#if (DUK_USE_STRTAB_MINSIZE != DUK_USE_STRTAB_MAXSIZE)\n\tDUK_ASSERT(res->st_count == 0);\n#endif\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t/* zero assumption */\n\tduk_memzero(res->strtable16, sizeof(duk_uint16_t) * st_initsize);\n#else\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t{\n\t\tduk_uint32_t i;\n\t        for (i = 0; i < st_initsize; i++) {\n\t\t\tres->strtable[i] = NULL;\n\t        }\n\t}\n#else\n\tduk_memzero(res->strtable, sizeof(duk_hstring *) * st_initsize);\n#endif  /* DUK_USE_EXPLICIT_NULL_INIT */\n#endif  /* DUK_USE_STRTAB_PTRCOMP */\n\n\t/*\n\t *  Init stringcache\n\t */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t{\n\t\tduk_uint_t i;\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tres->strcache[i].h = NULL;\n\t\t}\n\t}\n#endif\n\n\t/*\n\t *  Init litcache\n\t */\n#if defined(DUK_USE_LITCACHE_SIZE)\n\tDUK_ASSERT(DUK_USE_LITCACHE_SIZE > 0);\n\tDUK_ASSERT(DUK_IS_POWER_OF_TWO((duk_uint_t) DUK_USE_LITCACHE_SIZE));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t{\n\t\tduk_uint_t i;\n\t\tfor (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) {\n\t\t\tres->litcache[i].addr = NULL;\n\t\t\tres->litcache[i].h = NULL;\n\t\t}\n\t}\n#endif\n#endif  /* DUK_USE_LITCACHE_SIZE */\n\n\t/* XXX: error handling is incomplete.  It would be cleanest if\n\t * there was a setjmp catchpoint, so that all init code could\n\t * freely throw errors.  If that were the case, the return code\n\t * passing here could be removed.\n\t */\n\n\t/*\n\t *  Init built-in strings\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 2)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"heap init: initialize heap strings\"));\n\tif (!duk__init_heap_strings(res)) {\n\t\tgoto failed;\n\t}\n\n\t/*\n\t *  Init the heap thread\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 3)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"heap init: initialize heap thread\"));\n\tif (!duk__init_heap_thread(res)) {\n\t\tgoto failed;\n\t}\n\n\t/*\n\t *  Init the heap object\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 4)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"heap init: initialize heap object\"));\n\tDUK_ASSERT(res->heap_thread != NULL);\n\tres->heap_object = duk_hobject_alloc_unchecked(res, DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                                    DUK_HOBJECT_FLAG_FASTREFS |\n\t                                                    DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT));\n\tif (res->heap_object == NULL) {\n\t\tgoto failed;\n\t}\n\tDUK_HOBJECT_INCREF(res->heap_thread, res->heap_object);\n\n\t/*\n\t *  Odds and ends depending on the heap thread\n\t */\n\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\n#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS)\n\tres->rnd_state = (duk_uint32_t) duk_time_get_ecmascript_time(res->heap_thread);\n\tduk_util_tinyrandom_prepare_seed(res->heap_thread);\n#else\n\tres->rnd_state[0] = (duk_uint64_t) duk_time_get_ecmascript_time(res->heap_thread);\n\tDUK_ASSERT(res->rnd_state[1] == 0);  /* Not filled here, filled in by seed preparation. */\n#if 0  /* Manual test values matching misc/xoroshiro128plus_test.c. */\n\tres->rnd_state[0] = DUK_U64_CONSTANT(0xdeadbeef12345678);\n\tres->rnd_state[1] = DUK_U64_CONSTANT(0xcafed00d12345678);\n#endif\n\tduk_util_tinyrandom_prepare_seed(res->heap_thread);\n\t/* Mix in heap pointer: this ensures that if two Duktape heaps are\n\t * created on the same millisecond, they get a different PRNG\n\t * sequence (unless e.g. virtual memory addresses cause also the\n\t * heap object pointer to be the same).\n\t */\n\t{\n\t\tduk_uint64_t tmp_u64;\n\t\ttmp_u64 = 0;\n\t\tduk_memcpy((void *) &tmp_u64,\n\t\t           (const void *) &res,\n\t\t           (size_t) (sizeof(void *) >= sizeof(duk_uint64_t) ? sizeof(duk_uint64_t) : sizeof(void *)));\n\t\tres->rnd_state[1] ^= tmp_u64;\n\t}\n\tdo {\n\t\tduk_small_uint_t i;\n\t\tfor (i = 0; i < 10; i++) {\n\t\t\t/* Throw away a few initial random numbers just in\n\t\t\t * case.  Probably unnecessary due to SplitMix64\n\t\t\t * preparation.\n\t\t\t */\n\t\t\t(void) duk_util_tinyrandom_get_double(res->heap_thread);\n\t\t}\n\t} while (0);\n#endif\n#endif\n\n\t/*\n\t *  Allow finalizer and mark-and-sweep processing.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"heap init: allow finalizer/mark-and-sweep processing\"));\n\tDUK_ASSERT(res->ms_prevent_count == 1);\n\tDUK_ASSERT(res->pf_prevent_count == 1);\n\tres->ms_prevent_count = 0;\n\tres->pf_prevent_count = 0;\n\tDUK_ASSERT(res->ms_running == 0);\n#if defined(DUK_USE_ASSERTIONS)\n\tres->heap_initializing = 0;\n#endif\n\n\t/*\n\t *  All done.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"allocated heap: %p\", (void *) res));\n\treturn res;\n\n failed:\n\tDUK_D(DUK_DPRINT(\"heap allocation failed\"));\n\n\tif (res != NULL) {\n\t\t/* Assumes that allocated pointers and alloc funcs are valid\n\t\t * if res exists.\n\t\t */\n\t\tDUK_ASSERT(res->ms_prevent_count == 1);\n\t\tDUK_ASSERT(res->pf_prevent_count == 1);\n\t\tDUK_ASSERT(res->ms_running == 0);\n\t\tif (res->heap_thread != NULL) {\n\t\t\tres->ms_prevent_count = 0;\n\t\t\tres->pf_prevent_count = 0;\n\t\t}\n#if defined(DUK_USE_ASSERTIONS)\n\t\tres->heap_initializing = 0;\n#endif\n\n\t\tDUK_ASSERT(res->alloc_func != NULL);\n\t\tDUK_ASSERT(res->realloc_func != NULL);\n\t\tDUK_ASSERT(res->free_func != NULL);\n\t\tduk_heap_free(res);\n\t}\n\n\treturn NULL;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_heap_finalize.c",
    "content": "/*\n *  Finalizer handling.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\n/*\n *  Fake torture finalizer.\n */\n\n#if defined(DUK_USE_FINALIZER_TORTURE)\nDUK_LOCAL duk_ret_t duk__fake_global_finalizer(duk_hthread *thr) {\n\tDUK_DD(DUK_DDPRINT(\"fake global torture finalizer executed\"));\n\n\t/* Require a lot of stack to force a value stack grow/shrink. */\n\tduk_require_stack(thr, 100000);\n\n\t/* Force a reallocation with pointer change for value stack\n\t * to maximize side effects.\n\t */\n\tduk_hthread_valstack_torture_realloc(thr);\n\n\t/* Inner function call, error throw. */\n\tduk_eval_string_noresult(thr,\n\t\t\"(function dummy() {\\n\"\n\t\t\"    dummy.prototype = null;  /* break reference loop */\\n\"\n\t\t\"    try {\\n\"\n\t\t\"        throw 'fake-finalizer-dummy-error';\\n\"\n\t\t\"    } catch (e) {\\n\"\n\t\t\"        void e;\\n\"\n\t\t\"    }\\n\"\n\t\t\"})()\");\n\n\t/* The above creates garbage (e.g. a function instance).  Because\n\t * the function/prototype reference loop is broken, it gets collected\n\t * immediately by DECREF.  If Function.prototype has a _Finalizer\n\t * property (happens in some test cases), the garbage gets queued to\n\t * finalize_list.  This still won't cause an infinite loop because\n\t * the torture finalizer is called once per finalize_list run and\n\t * the garbage gets handled in the same run.  (If the garbage needs\n\t * mark-and-sweep collection, an infinite loop might ensue.)\n\t */\n\treturn 0;\n}\n\nDUK_LOCAL void duk__run_global_torture_finalizer(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Avoid fake finalization when callstack limit is near.  Otherwise\n\t * a callstack limit error will be created, then refzero'ed.  The\n\t * +5 headroom is conservative.\n\t */\n\tif (thr->heap->call_recursion_depth + 5 >= thr->heap->call_recursion_limit ||\n\t    thr->callstack_top + 5 >= DUK_USE_CALLSTACK_LIMIT) {\n\t\tDUK_D(DUK_DPRINT(\"skip global torture finalizer, too little headroom for call recursion or call stack size\"));\n\t\treturn;\n\t}\n\n\t/* Run fake finalizer.  Avoid creating unnecessary garbage. */\n\tduk_push_c_function(thr, duk__fake_global_finalizer, 0 /*nargs*/);\n\t(void) duk_pcall(thr, 0 /*nargs*/);\n\tduk_pop(thr);\n}\n#endif  /* DUK_USE_FINALIZER_TORTURE */\n\n/*\n *  Process the finalize_list to completion.\n *\n *  An object may be placed on finalize_list by either refcounting or\n *  mark-and-sweep.  The refcount of objects placed by refcounting will be\n *  zero; the refcount of objects placed by mark-and-sweep is > 0.  In both\n *  cases the refcount is bumped by 1 artificially so that a REFZERO event\n *  can never happen while an object is waiting for finalization.  Without\n *  this bump a REFZERO could now happen because user code may call\n *  duk_push_heapptr() and then pop a value even when it's on finalize_list.\n *\n *  List processing assumes refcounts are kept up-to-date at all times, so\n *  that once the finalizer returns, a zero refcount is a reliable reason to\n *  free the object immediately rather than place it back to the heap.  This\n *  is the case because we run outside of refzero_list processing so that\n *  DECREF cascades are handled fully inline.\n *\n *  For mark-and-sweep queued objects (had_zero_refcount false) the object\n *  may be freed immediately if its refcount is zero after the finalizer call\n *  (i.e. finalizer removed the reference loop for the object).  If not, the\n *  next mark-and-sweep will collect the object unless it has become reachable\n *  (i.e. rescued) by that time and its refcount hasn't fallen to zero before\n *  that.  Mark-and-sweep detects these objects because their FINALIZED flag\n *  is set.\n *\n *  There's an inherent limitation for mark-and-sweep finalizer rescuing: an\n *  object won't get refinalized if (1) it's rescued, but (2) becomes\n *  unreachable before mark-and-sweep has had time to notice it.  The next\n *  mark-and-sweep round simply doesn't have any information of whether the\n *  object has been unreachable the whole time or not (the only way to get\n *  that information would be a mark-and-sweep pass for *every finalized\n *  object*).  This is awkward for the application because the mark-and-sweep\n *  round is not generally visible or under full application control.\n *\n *  For refcount queued objects (had_zero_refcount true) the object is either\n *  immediately freed or rescued, and waiting for a mark-and-sweep round is not\n *  necessary (or desirable); FINALIZED is cleared when a rescued object is\n *  queued back to heap_allocated.  The object is eligible for finalization\n *  again (either via refcounting or mark-and-sweep) immediately after being\n *  rescued.  If a refcount finalized object is placed into an unreachable\n *  reference loop by its finalizer, it will get collected by mark-and-sweep\n *  and currently the finalizer will execute again.\n *\n *  There's a special case where:\n *\n *    - Mark-and-sweep queues an object to finalize_list for finalization.\n *    - The finalizer is executed, FINALIZED is set, and object is queued\n *      back to heap_allocated, waiting for a new mark-and-sweep round.\n *    - The object's refcount drops to zero before mark-and-sweep has a\n *      chance to run another round and make a rescue/free decision.\n *\n *  This is now handled by refzero code: if an object has a finalizer but\n *  FINALIZED is already set, the object is freed without finalizer processing.\n *  The outcome is the same as if mark-and-sweep was executed at that point;\n *  mark-and-sweep would also free the object without another finalizer run.\n *  This could also be changed so that the refzero-triggered finalizer *IS*\n *  executed: being refzero collected implies someone has operated on the\n *  object so it hasn't been totally unreachable the whole time.  This would\n *  risk a finalizer loop however.\n */\n\nDUK_INTERNAL void duk_heap_process_finalize_list(duk_heap *heap) {\n\tduk_heaphdr *curr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count = 0;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk_heap_process_finalize_list: %p\", (void *) heap));\n\n\tif (heap->pf_prevent_count != 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"skip finalize_list processing: pf_prevent_count != 0\"));\n\t\treturn;\n\t}\n\n\t/* Heap alloc prevents mark-and-sweep before heap_thread is ready. */\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(heap->heap_thread->valstack != NULL);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);\n#endif\n\n\tDUK_ASSERT(heap->pf_prevent_count == 0);\n\theap->pf_prevent_count = 1;\n\n\t/* Mark-and-sweep no longer needs to be prevented when running\n\t * finalizers: mark-and-sweep skips any rescue decisions if there\n\t * are any objects in finalize_list when mark-and-sweep is entered.\n\t * This protects finalized objects from incorrect rescue decisions\n\t * caused by finalize_list being a reachability root and only\n\t * partially processed.  Freeing decisions are not postponed.\n\t */\n\n\t/* When finalizer torture is enabled, make a fake finalizer call with\n\t * maximum side effects regardless of whether finalize_list is empty.\n\t */\n#if defined(DUK_USE_FINALIZER_TORTURE)\n\tduk__run_global_torture_finalizer(heap->heap_thread);\n#endif\n\n\t/* Process finalize_list until it becomes empty.  There's currently no\n\t * protection against a finalizer always creating more garbage.\n\t */\n\twhile ((curr = heap->finalize_list) != NULL) {\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tduk_bool_t queue_back;\n#endif\n\n\t\tDUK_DD(DUK_DDPRINT(\"processing finalize_list entry: %p -> %!iO\", (void *) curr, curr));\n\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);  /* Only objects have finalizers. */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(curr));\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(curr));\n\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZABLE(curr));  /* All objects on finalize_list will have this flag (except object being finalized right now). */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));   /* Queueing code ensures. */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(curr));  /* ROM objects never get freed (or finalized). */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\tDUK_ASSERT(heap->currently_finalizing == NULL);\n\t\theap->currently_finalizing = curr;\n#endif\n\n\t\t/* Clear FINALIZABLE for object being finalized, so that\n\t\t * duk_push_heapptr() can properly ignore the object.\n\t\t */\n\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\n\t\tif (DUK_LIKELY(!heap->pf_skip_finalizers)) {\n\t\t\t/* Run the finalizer, duk_heap_run_finalizer() sets\n\t\t\t * and checks for FINALIZED to prevent the finalizer\n\t\t\t * from executing multiple times per finalization cycle.\n\t\t\t * (This safeguard shouldn't be actually needed anymore).\n\t\t\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tduk_bool_t had_zero_refcount;\n#endif\n\n\t\t\t/* The object's refcount is >0 throughout so it won't be\n\t\t\t * refzero processed prematurely.\n\t\t\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) >= 1);\n\t\t\thad_zero_refcount = (DUK_HEAPHDR_GET_REFCOUNT(curr) == 1);  /* Preincremented on finalize_list insert. */\n#endif\n\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));\n\t\t\tduk_heap_run_finalizer(heap, (duk_hobject *) curr);  /* must never longjmp */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZED(curr));\n\t\t\t/* XXX: assert that object is still in finalize_list\n\t\t\t * when duk_push_heapptr() allows automatic rescue.\n\t\t\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tDUK_DD(DUK_DDPRINT(\"refcount after finalizer (includes bump): %ld\", (long) DUK_HEAPHDR_GET_REFCOUNT(curr)));\n\t\t\tif (DUK_HEAPHDR_GET_REFCOUNT(curr) == 1) {  /* Only artificial bump in refcount? */\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tif (had_zero_refcount) {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"finalized object's refcount is zero -> free immediately (refcount queued)\"));\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"finalized object's refcount is zero -> free immediately (mark-and-sweep queued)\"));\n\t\t\t\t}\n#endif\n\t\t\t\tqueue_back = 0;\n\t\t\t} else\n#endif\n\t\t\t{\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t\tqueue_back = 1;\n\t\t\t\tif (had_zero_refcount) {\n\t\t\t\t\t/* When finalization is triggered\n\t\t\t\t\t * by refzero and we queue the object\n\t\t\t\t\t * back, clear FINALIZED right away\n\t\t\t\t\t * so that the object can be refinalized\n\t\t\t\t\t * immediately if necessary.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_HEAPHDR_CLEAR_FINALIZED(curr);\n\t\t\t\t}\n#endif\n\t\t\t}\n\t\t} else {\n\t\t\t/* Used during heap destruction: don't actually run finalizers\n\t\t\t * because we're heading into forced finalization.  Instead,\n\t\t\t * queue finalizable objects back to the heap_allocated list.\n\t\t\t */\n\t\t\tDUK_D(DUK_DPRINT(\"skip finalizers flag set, queue object to heap_allocated without finalizing\"));\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tqueue_back = 1;\n#endif\n\t\t}\n\n\t\t/* Dequeue object from finalize_list.  Note that 'curr' may no\n\t\t * longer be finalize_list head because new objects may have\n\t\t * been queued to the list.  As a result we can't optimize for\n\t\t * the single-linked heap case and must scan the list for\n\t\t * removal, typically the scan is very short however.\n\t\t */\n\t\tDUK_HEAP_REMOVE_FROM_FINALIZE_LIST(heap, curr);\n\n\t\t/* Queue back to heap_allocated or free immediately. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tif (queue_back) {\n\t\t\t/* FINALIZED is only cleared if object originally\n\t\t\t * queued for finalization by refcounting.  For\n\t\t\t * mark-and-sweep FINALIZED is left set, so that\n\t\t\t * next mark-and-sweep round can make a rescue/free\n\t\t\t * decision.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) >= 1);\n\t\t\tDUK_HEAPHDR_PREDEC_REFCOUNT(curr);  /* Remove artificial refcount bump. */\n\t\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\t\t\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, curr);\n\t\t} else {\n\t\t\t/* No need to remove the refcount bump here. */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);  /* currently, always the case */\n\t\t\tDUK_DD(DUK_DDPRINT(\"refcount finalize after finalizer call: %!O\", curr));\n\t\t\tduk_hobject_refcount_finalize_norz(heap, (duk_hobject *) curr);\n\t\t\tduk_free_hobject(heap, (duk_hobject *) curr);\n\t\t\tDUK_DD(DUK_DDPRINT(\"freed hobject after finalization: %p\", (void *) curr));\n\t\t}\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\t\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, curr);\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_DEBUG)\n\t\tcount++;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\tDUK_ASSERT(heap->currently_finalizing != NULL);\n\t\theap->currently_finalizing = NULL;\n#endif\n\t}\n\n\t/* finalize_list will always be processed completely. */\n\tDUK_ASSERT(heap->finalize_list == NULL);\n\n#if 0\n\t/* While NORZ macros are used above, this is unnecessary because the\n\t * only pending side effects are now finalizers, and finalize_list is\n\t * empty.\n\t */\n\tDUK_REFZERO_CHECK_SLOW(heap->heap_thread);\n#endif\n\n\t/* Prevent count may be bumped while finalizers run, but should always\n\t * be reliably unbumped by the time we get here.\n\t */\n\tDUK_ASSERT(heap->pf_prevent_count == 1);\n\theap->pf_prevent_count = 0;\n\n#if defined(DUK_USE_DEBUG)\n\tDUK_DD(DUK_DDPRINT(\"duk_heap_process_finalize_list: %ld finalizers called\", (long) count));\n#endif\n}\n\n/*\n *  Run an duk_hobject finalizer.  Must never throw an uncaught error\n *  (but may throw caught errors).\n *\n *  There is no return value.  Any return value or error thrown by\n *  the finalizer is ignored (although errors are debug logged).\n *\n *  Notes:\n *\n *    - The finalizer thread 'top' assertions are there because it is\n *      critical that strict stack policy is observed (i.e. no cruft\n *      left on the finalizer stack).\n */\n\nDUK_LOCAL duk_ret_t duk__finalize_helper(duk_hthread *thr, void *udata) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_UNREF(udata);\n\n\tDUK_DDD(DUK_DDDPRINT(\"protected finalization helper running\"));\n\n\t/* [... obj] */\n\n\t/* _Finalizer property is read without checking if the value is\n\t * callable or even exists.  This is intentional, and handled\n\t * by throwing an error which is caught by the safe call wrapper.\n\t *\n\t * XXX: Finalizer lookup should traverse the prototype chain (to allow\n\t * inherited finalizers) but should not invoke accessors or proxy object\n\t * behavior.  At the moment this lookup will invoke proxy behavior, so\n\t * caller must ensure that this function is not called if the target is\n\t * a Proxy.\n\t */\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_FINALIZER);  /* -> [... obj finalizer] */\n\tduk_dup_m2(thr);\n\tduk_push_boolean(thr, DUK_HEAP_HAS_FINALIZER_NORESCUE(thr->heap));\n\tDUK_DDD(DUK_DDDPRINT(\"calling finalizer\"));\n\tduk_call(thr, 2);  /* [ ... obj finalizer obj heapDestruct ]  -> [ ... obj retval ] */\n\tDUK_DDD(DUK_DDDPRINT(\"finalizer returned successfully\"));\n\treturn 0;\n\n\t/* Note: we rely on duk_safe_call() to fix up the stack for the caller,\n\t * so we don't need to pop stuff here.  There is no return value;\n\t * caller determines rescued status based on object refcount.\n\t */\n}\n\nDUK_INTERNAL void duk_heap_run_finalizer(duk_heap *heap, duk_hobject *obj) {\n\tduk_hthread *thr;\n\tduk_ret_t rc;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"running duk_hobject finalizer for object: %p\", (void *) obj));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tthr = heap->heap_thread;\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(heap->heap_thread, 1);\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\t/*\n\t *  Get and call the finalizer.  All of this must be wrapped\n\t *  in a protected call, because even getting the finalizer\n\t *  may trigger an error (getter may throw one, for instance).\n\t */\n\n\t/* ROM objects could inherit a finalizer, but they are never deemed\n\t * unreachable by mark-and-sweep, and their refcount never falls to 0.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\n\t/* Duktape 2.1: finalize_list never contains objects with FINALIZED\n\t * set, so no need to check here.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) obj));\n#if 0\n\tif (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) obj)) {\n\t\tDUK_D(DUK_DPRINT(\"object already finalized, avoid running finalizer twice: %!O\", obj));\n\t\treturn;\n\t}\n#endif\n\tDUK_HEAPHDR_SET_FINALIZED((duk_heaphdr *) obj);  /* ensure never re-entered until rescue cycle complete */\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (DUK_HOBJECT_IS_PROXY(obj)) {\n\t\t/* This may happen if duk_set_finalizer() or Duktape.fin() is\n\t\t * called for a Proxy object.  In such cases the fast finalizer\n\t\t * flag will be set on the Proxy, not the target, and neither\n\t\t * will be finalized.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"object is a Proxy, skip finalizer call\"));\n\t\treturn;\n\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\tduk_push_hobject(thr, obj);  /* this also increases refcount by one */\n\trc = duk_safe_call(thr, duk__finalize_helper, NULL /*udata*/, 0 /*nargs*/, 1 /*nrets*/);  /* -> [... obj retval/error] */\n\tDUK_ASSERT_TOP(thr, entry_top + 2);  /* duk_safe_call discipline */\n\n\tif (rc != DUK_EXEC_SUCCESS) {\n\t\t/* Note: we ask for one return value from duk_safe_call to get this\n\t\t * error debugging here.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"wrapped finalizer call failed for object %p (ignored); error: %!T\",\n\t\t                 (void *) obj, (duk_tval *) duk_get_tval(thr, -1)));\n\t}\n\tduk_pop_2(thr);  /* -> [...] */\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n}\n\n#else  /* DUK_USE_FINALIZER_SUPPORT */\n\n/* nothing */\n\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_heap_hashstring.c",
    "content": "/*\n *  String hash computation (interning).\n *\n *  String hashing is performance critical because a string hash is computed\n *  for all new strings which are candidates to be added to the string table.\n *  However, strings actually added to the string table go through a codepoint\n *  length calculation which dominates performance because it goes through\n *  every byte of the input string (but only for strings added).\n *\n *  The string hash algorithm should be fast, but on the other hand provide\n *  good enough hashes to ensure both string table and object property table\n *  hash tables work reasonably well (i.e., there aren't too many collisions\n *  with real world inputs).  Unless the hash is cryptographic, it's always\n *  possible to craft inputs with maximal hash collisions.\n *\n *  NOTE: The hash algorithms must match tools/dukutil.py:duk_heap_hashstring()\n *  for ROM string support!\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_STRHASH_DENSE)\n/* Constants for duk_hashstring(). */\n#define DUK__STRHASH_SHORTSTRING   4096L\n#define DUK__STRHASH_MEDIUMSTRING  (256L * 1024L)\n#define DUK__STRHASH_BLOCKSIZE     256L\n\nDUK_INTERNAL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len) {\n\tduk_uint32_t hash;\n\n\t/* Use Murmurhash2 directly for short strings, and use \"block skipping\"\n\t * for long strings: hash an initial part and then sample the rest of\n\t * the string with reasonably sized chunks.  An initial offset for the\n\t * sampling is computed based on a hash of the initial part of the string;\n\t * this is done to (usually) avoid the case where all long strings have\n\t * certain offset ranges which are never sampled.\n\t *\n\t * Skip should depend on length and bound the total time to roughly\n\t * logarithmic.  With current values:\n\t *\n\t *   1M string => 256 * 241 = 61696 bytes (0.06M) of hashing\n\t *   1G string => 256 * 16321 = 4178176 bytes (3.98M) of hashing\n\t *\n\t * XXX: It would be better to compute the skip offset more \"smoothly\"\n\t * instead of having a few boundary values.\n\t */\n\n\t/* note: mixing len into seed improves hashing when skipping */\n\tduk_uint32_t str_seed = heap->hash_seed ^ ((duk_uint32_t) len);\n\n\tif (len <= DUK__STRHASH_SHORTSTRING) {\n\t\thash = duk_util_hashbytes(str, len, str_seed);\n\t} else {\n\t\tduk_size_t off;\n\t\tduk_size_t skip;\n\n\t\tif (len <= DUK__STRHASH_MEDIUMSTRING) {\n\t\t\tskip = (duk_size_t) (16 * DUK__STRHASH_BLOCKSIZE + DUK__STRHASH_BLOCKSIZE);\n\t\t} else {\n\t\t\tskip = (duk_size_t) (256 * DUK__STRHASH_BLOCKSIZE + DUK__STRHASH_BLOCKSIZE);\n\t\t}\n\n\t\thash = duk_util_hashbytes(str, (duk_size_t) DUK__STRHASH_SHORTSTRING, str_seed);\n\t\toff = DUK__STRHASH_SHORTSTRING + (skip * (hash % 256)) / 256;\n\n\t\t/* XXX: inefficient loop */\n\t\twhile (off < len) {\n\t\t\tduk_size_t left = len - off;\n\t\t\tduk_size_t now = (duk_size_t) (left > DUK__STRHASH_BLOCKSIZE ? DUK__STRHASH_BLOCKSIZE : left);\n\t\t\thash ^= duk_util_hashbytes(str + off, now, str_seed);\n\t\t\toff += skip;\n\t\t}\n\t}\n\n#if defined(DUK_USE_STRHASH16)\n\t/* Truncate to 16 bits here, so that a computed hash can be compared\n\t * against a hash stored in a 16-bit field.\n\t */\n\thash &= 0x0000ffffUL;\n#endif\n\treturn hash;\n}\n#else  /* DUK_USE_STRHASH_DENSE */\nDUK_INTERNAL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len) {\n\tduk_uint32_t hash;\n\tduk_size_t step;\n\tduk_size_t off;\n\n\t/* Slightly modified \"Bernstein hash\" from:\n\t *\n\t *     http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx\n\t *\n\t * Modifications: string skipping and reverse direction similar to\n\t * Lua 5.1.5, and different hash initializer.\n\t *\n\t * The reverse direction ensures last byte it always included in the\n\t * hash which is a good default as changing parts of the string are\n\t * more often in the suffix than in the prefix.\n\t */\n\n\thash = heap->hash_seed ^ ((duk_uint32_t) len);  /* Bernstein hash init value is normally 5381 */\n\tstep = (len >> DUK_USE_STRHASH_SKIP_SHIFT) + 1;\n\tfor (off = len; off >= step; off -= step) {\n\t\tDUK_ASSERT(off >= 1);  /* off >= step, and step >= 1 */\n\t\thash = (hash * 33) + str[off - 1];\n\t}\n\n#if defined(DUK_USE_STRHASH16)\n\t/* Truncate to 16 bits here, so that a computed hash can be compared\n\t * against a hash stored in a 16-bit field.\n\t */\n\thash &= 0x0000ffffUL;\n#endif\n\treturn hash;\n}\n#endif  /* DUK_USE_STRHASH_DENSE */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_heap_markandsweep.c",
    "content": "/*\n *  Mark-and-sweep garbage collection.\n */\n\n#include \"duk_internal.h\"\n\nDUK_LOCAL_DECL void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__mark_heaphdr_nonnull(duk_heap *heap, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__mark_tval(duk_heap *heap, duk_tval *tv);\nDUK_LOCAL_DECL void duk__mark_tvals(duk_heap *heap, duk_tval *tv, duk_idx_t count);\n\n/*\n *  Marking functions for heap types: mark children recursively.\n */\n\nDUK_LOCAL void duk__mark_hstring(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\tDUK_UNREF(h);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_hstring: %p\", (void *) h));\n\tDUK_ASSERT(h);\n\tDUK_HSTRING_ASSERT_VALID(h);\n\n\t/* nothing to process */\n}\n\nDUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {\n\tduk_uint_fast32_t i;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_hobject: %p\", (void *) h));\n\n\tDUK_ASSERT(h);\n\tDUK_HOBJECT_ASSERT_VALID(h);\n\n\t/* XXX: use advancing pointers instead of index macros -> faster and smaller? */\n\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\tduk_hstring *key = DUK_HOBJECT_E_GET_KEY(heap, h, i);\n\t\tif (key == NULL) {\n\t\t\tcontinue;\n\t\t}\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) key);\n\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)) {\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.get);\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.set);\n\t\t} else {\n\t\t\tduk__mark_tval(heap, &DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->v);\n\t\t}\n\t}\n\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(h); i++) {\n\t\tduk__mark_tval(heap, DUK_HOBJECT_A_GET_VALUE_PTR(heap, h, i));\n\t}\n\n\t/* Hash part is a 'weak reference' and does not contribute. */\n\n\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(heap, h));\n\n\t/* Fast path for objects which don't have a subclass struct, or have a\n\t * subclass struct but nothing that needs marking in the subclass struct.\n\t */\n\tif (DUK_HOBJECT_HAS_FASTREFS(h)) {\n\t\tDUK_ASSERT(DUK_HOBJECT_ALLOWS_FASTREFS(h));\n\t\treturn;\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_PROHIBITS_FASTREFS(h));\n\n\t/* XXX: reorg, more common first */\n\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tduk_tval *tv, *tv_end;\n\t\tduk_hobject **fn, **fn_end;\n\n\t\tDUK_HCOMPFUNC_ASSERT_VALID(f);\n\n\t\t/* 'data' is reachable through every compiled function which\n\t\t * contains a reference.\n\t\t */\n\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_DATA(heap, f));\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_LEXENV(heap, f));\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_VARENV(heap, f));\n\n\t\tif (DUK_HCOMPFUNC_GET_DATA(heap, f) != NULL) {\n\t\t\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, f);\n\t\t\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(heap, f);\n\t\t\twhile (tv < tv_end) {\n\t\t\t\tduk__mark_tval(heap, tv);\n\t\t\t\ttv++;\n\t\t\t}\n\n\t\t\tfn = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, f);\n\t\t\tfn_end = DUK_HCOMPFUNC_GET_FUNCS_END(heap, f);\n\t\t\twhile (fn < fn_end) {\n\t\t\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) *fn);\n\t\t\t\tfn++;\n\t\t\t}\n\t\t} else {\n\t\t\t/* May happen in some out-of-memory corner cases. */\n\t\t\tDUK_D(DUK_DPRINT(\"duk_hcompfunc 'data' is NULL, skipping marking\"));\n\t\t}\n\t} else if (DUK_HOBJECT_IS_DECENV(h)) {\n\t\tduk_hdecenv *e = (duk_hdecenv *) h;\n\t\tDUK_HDECENV_ASSERT_VALID(e);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) e->thread);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) e->varmap);\n\t} else if (DUK_HOBJECT_IS_OBJENV(h)) {\n\t\tduk_hobjenv *e = (duk_hobjenv *) h;\n\t\tDUK_HOBJENV_ASSERT_VALID(e);\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) e->target);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\tduk_hbufobj *b = (duk_hbufobj *) h;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(b);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) b->buf);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) b->buf_prop);\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {\n\t\tduk_hboundfunc *f = (duk_hboundfunc *) (void *) h;\n\t\tDUK_HBOUNDFUNC_ASSERT_VALID(f);\n\t\tduk__mark_tval(heap, &f->target);\n\t\tduk__mark_tval(heap, &f->this_binding);\n\t\tduk__mark_tvals(heap, f->args, f->nargs);\n#if defined(DUK_USE_ES6_PROXY)\n\t} else if (DUK_HOBJECT_IS_PROXY(h)) {\n\t\tduk_hproxy *p = (duk_hproxy *) h;\n\t\tDUK_HPROXY_ASSERT_VALID(p);\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) p->target);\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) p->handler);\n#endif  /* DUK_USE_ES6_PROXY */\n\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tduk_activation *act;\n\t\tduk_tval *tv;\n\n\t\tDUK_HTHREAD_ASSERT_VALID(t);\n\n\t\ttv = t->valstack;\n\t\twhile (tv < t->valstack_top) {\n\t\t\tduk__mark_tval(heap, tv);\n\t\t\ttv++;\n\t\t}\n\n\t\tfor (act = t->callstack_curr; act != NULL; act = act->parent) {\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_ACT_GET_FUNC(act));\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) act->var_env);\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) act->lex_env);\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) act->prev_caller);\n#endif\n#if 0  /* nothing now */\n\t\t\tfor (cat = act->cat; cat != NULL; cat = cat->parent) {\n\t\t\t}\n#endif\n\t\t}\n\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) t->resumer);\n\n\t\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) t->builtins[i]);\n\t\t}\n\t} else {\n\t\t/* We may come here if the object should have a FASTREFS flag\n\t\t * but it's missing for some reason.  Assert for never getting\n\t\t * here; however, other than performance, this is harmless.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"missing FASTREFS flag for: %!iO\", h));\n\t\tDUK_ASSERT(0);\n\t}\n}\n\n/* Mark any duk_heaphdr type.  Recursion tracking happens only here. */\nDUK_LOCAL void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_heaphdr %p, type %ld\",\n\t                     (void *) h,\n\t                     (h != NULL ? (long) DUK_HEAPHDR_GET_TYPE(h) : (long) -1)));\n\n\t/* XXX: add non-null variant? */\n\tif (h == NULL) {\n\t\treturn;\n\t}\n\n\tDUK_HEAPHDR_ASSERT_VALID(h);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(h) || DUK_HEAPHDR_HAS_REACHABLE(h));\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\tif (!DUK_HEAPHDR_HAS_READONLY(h)) {\n\t\th->h_assert_refcount++;  /* Comparison refcount: bump even if already reachable. */\n\t}\n#endif\n\tif (DUK_HEAPHDR_HAS_REACHABLE(h)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"already marked reachable, skip\"));\n\t\treturn;\n\t}\n#if defined(DUK_USE_ROM_OBJECTS)\n\t/* READONLY objects always have REACHABLE set, so the check above\n\t * will prevent READONLY objects from being marked here.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(h));\n#endif\n\n\tDUK_HEAPHDR_SET_REACHABLE(h);\n\n\tif (heap->ms_recursion_depth >= DUK_USE_MARK_AND_SWEEP_RECLIMIT) {\n\t\tDUK_D(DUK_DPRINT(\"mark-and-sweep recursion limit reached, marking as temproot: %p\", (void *) h));\n\t\tDUK_HEAP_SET_MARKANDSWEEP_RECLIMIT_REACHED(heap);\n\t\tDUK_HEAPHDR_SET_TEMPROOT(h);\n\t\treturn;\n\t}\n\n\theap->ms_recursion_depth++;\n\tDUK_ASSERT(heap->ms_recursion_depth != 0);  /* Wrap. */\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING:\n\t\tduk__mark_hstring(heap, (duk_hstring *) h);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tduk__mark_hobject(heap, (duk_hobject *) h);\n\t\tbreak;\n\tcase DUK_HTYPE_BUFFER:\n\t\t/* nothing to mark */\n\t\tbreak;\n\tdefault:\n\t\tDUK_D(DUK_DPRINT(\"attempt to mark heaphdr %p with invalid htype %ld\", (void *) h, (long) DUK_HEAPHDR_GET_TYPE(h)));\n\t\tDUK_UNREACHABLE();\n\t}\n\n\tDUK_ASSERT(heap->ms_recursion_depth > 0);\n\theap->ms_recursion_depth--;\n}\n\nDUK_LOCAL void duk__mark_tval(duk_heap *heap, duk_tval *tv) {\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_tval %p\", (void *) tv));\n\tif (tv == NULL) {\n\t\treturn;\n\t}\n\tDUK_TVAL_ASSERT_VALID(tv);\n\tif (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\tduk_heaphdr *h;\n\t\th = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tduk__mark_heaphdr_nonnull(heap, h);\n\t}\n}\n\nDUK_LOCAL void duk__mark_tvals(duk_heap *heap, duk_tval *tv, duk_idx_t count) {\n\tDUK_ASSERT(count == 0 || tv != NULL);\n\n\twhile (count-- > 0) {\n\t\tDUK_TVAL_ASSERT_VALID(tv);\n\t\tif (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\t\tduk_heaphdr *h;\n\t\t\th = DUK_TVAL_GET_HEAPHDR(tv);\n\t\t\tDUK_ASSERT(h != NULL);\n\t\t\tduk__mark_heaphdr_nonnull(heap, h);\n\t\t}\n\t\ttv++;\n\t}\n}\n\n/* Mark any duk_heaphdr type, caller guarantees a non-NULL pointer. */\nDUK_LOCAL void duk__mark_heaphdr_nonnull(duk_heap *heap, duk_heaphdr *h) {\n\t/* For now, just call the generic handler.  Change when call sites\n\t * are changed too.\n\t */\n\tduk__mark_heaphdr(heap, h);\n}\n\n/*\n *  Mark the heap.\n */\n\nDUK_LOCAL void duk__mark_roots_heap(duk_heap *heap) {\n\tduk_small_uint_t i;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_roots_heap: %p\", (void *) heap));\n\n\tduk__mark_heaphdr(heap, (duk_heaphdr *) heap->heap_thread);\n\tduk__mark_heaphdr(heap, (duk_heaphdr *) heap->heap_object);\n\n\tfor (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) {\n\t\tduk_hstring *h = DUK_HEAP_GET_STRING(heap, i);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) h);\n\t}\n\n\tduk__mark_tval(heap, &heap->lj.value1);\n\tduk__mark_tval(heap, &heap->lj.value2);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tfor (i = 0; i < heap->dbg_breakpoint_count; i++) {\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) heap->dbg_breakpoints[i].filename);\n\t}\n#endif\n}\n\n/*\n *  Mark unreachable, finalizable objects.\n *\n *  Such objects will be moved aside and their finalizers run later.  They\n *  have to be treated as reachability roots for their properties etc to\n *  remain allocated.  This marking is only done for unreachable values which\n *  would be swept later.\n *\n *  Objects are first marked FINALIZABLE and only then marked as reachability\n *  roots; otherwise circular references might be handled inconsistently.\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__mark_finalizable(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\tduk_size_t count_finalizable = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_finalizable: %p\", (void *) heap));\n\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\n\thdr = heap->heap_allocated;\n\twhile (hdr != NULL) {\n\t\t/* A finalizer is looked up from the object and up its\n\t\t * prototype chain (which allows inherited finalizers).\n\t\t * The finalizer is checked for using a duk_hobject flag\n\t\t * which is kept in sync with the presence and callability\n\t\t * of a _Finalizer hidden symbol.\n\t\t */\n\n\t\tif (!DUK_HEAPHDR_HAS_REACHABLE(hdr) &&\n\t\t    DUK_HEAPHDR_IS_OBJECT(hdr) &&\n\t\t    !DUK_HEAPHDR_HAS_FINALIZED(hdr) &&\n\t\t    DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) hdr)) {\n\t\t\t/* heaphdr:\n\t\t\t *  - is not reachable\n\t\t\t *  - is an object\n\t\t\t *  - is not a finalized object waiting for rescue/keep decision\n\t\t\t *  - has a finalizer\n\t\t\t */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"unreachable heap object will be \"\n\t\t\t                   \"finalized -> mark as finalizable \"\n\t\t\t                   \"and treat as a reachability root: %p\",\n\t\t\t                   (void *) hdr));\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(hdr));\n\t\t\tDUK_HEAPHDR_SET_FINALIZABLE(hdr);\n\t\t\tcount_finalizable++;\n\t\t}\n\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n\n\tif (count_finalizable == 0) {\n\t\treturn;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"marked %ld heap objects as finalizable, now mark them reachable\",\n\t                   (long) count_finalizable));\n\n\thdr = heap->heap_allocated;\n\twhile (hdr != NULL) {\n\t\tif (DUK_HEAPHDR_HAS_FINALIZABLE(hdr)) {\n\t\t\tduk__mark_heaphdr_nonnull(heap, hdr);\n\t\t}\n\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n\n\t/* Caller will finish the marking process if we hit a recursion limit. */\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Mark objects on finalize_list.\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__mark_finalize_list(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_finalize_list = 0;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_finalize_list: %p\", (void *) heap));\n\n\thdr = heap->finalize_list;\n\twhile (hdr != NULL) {\n\t\tduk__mark_heaphdr_nonnull(heap, hdr);\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n#if defined(DUK_USE_DEBUG)\n\t\tcount_finalize_list++;\n#endif\n\t}\n\n#if defined(DUK_USE_DEBUG)\n\tif (count_finalize_list > 0) {\n\t\tDUK_D(DUK_DPRINT(\"marked %ld objects on the finalize_list as reachable (previous finalizer run skipped)\",\n\t\t                 (long) count_finalize_list));\n\t}\n#endif\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Fallback marking handler if recursion limit is reached.\n *\n *  Iterates 'temproots' until recursion limit is no longer hit.  Temproots\n *  can be in heap_allocated or finalize_list; refzero_list is now always\n *  empty for mark-and-sweep.  A temproot may occur in finalize_list now if\n *  there are objects on the finalize_list and user code creates a reference\n *  from an object in heap_allocated to the object in finalize_list (which is\n *  now allowed), and it happened to coincide with the recursion depth limit.\n *\n *  This is a slow scan, but guarantees that we finish with a bounded C stack.\n *\n *  Note that nodes may have been marked as temproots before this scan begun,\n *  OR they may have been marked during the scan (as we process nodes\n *  recursively also during the scan).  This is intended behavior.\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__handle_temproot(duk_heap *heap, duk_heaphdr *hdr, duk_size_t *count) {\n#else\nDUK_LOCAL void duk__handle_temproot(duk_heap *heap, duk_heaphdr *hdr) {\n#endif\n\tDUK_ASSERT(hdr != NULL);\n\n\tif (!DUK_HEAPHDR_HAS_TEMPROOT(hdr)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"not a temp root: %p\", (void *) hdr));\n\t\treturn;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"found a temp root: %p\", (void *) hdr));\n\tDUK_HEAPHDR_CLEAR_TEMPROOT(hdr);\n\tDUK_HEAPHDR_CLEAR_REACHABLE(hdr);  /* Done so that duk__mark_heaphdr() works correctly. */\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\thdr->h_assert_refcount--;  /* Same node visited twice. */\n#endif\n\tduk__mark_heaphdr_nonnull(heap, hdr);\n\n#if defined(DUK_USE_DEBUG)\n\t(*count)++;\n#endif\n}\n\nDUK_LOCAL void duk__mark_temproots_by_heap_scan(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_temproots_by_heap_scan: %p\", (void *) heap));\n\n\twhile (DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap)) {\n\t\tDUK_DD(DUK_DDPRINT(\"recursion limit reached, doing heap scan to continue from temproots\"));\n\n#if defined(DUK_USE_DEBUG)\n\t\tcount = 0;\n#endif\n\t\tDUK_HEAP_CLEAR_MARKANDSWEEP_RECLIMIT_REACHED(heap);\n\n\t\thdr = heap->heap_allocated;\n\t\twhile (hdr) {\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk__handle_temproot(heap, hdr, &count);\n#else\n\t\t\tduk__handle_temproot(heap, hdr);\n#endif\n\t\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t\t}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\thdr = heap->finalize_list;\n\t\twhile (hdr) {\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk__handle_temproot(heap, hdr, &count);\n#else\n\t\t\tduk__handle_temproot(heap, hdr);\n#endif\n\t\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t\t}\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\t\tDUK_DD(DUK_DDPRINT(\"temproot mark heap scan processed %ld temp roots\", (long) count));\n#endif\n\t}\n}\n\n/*\n *  Finalize refcounts for heap elements just about to be freed.\n *  This must be done for all objects before freeing to avoid any\n *  stale pointer dereferences.\n *\n *  Note that this must deduce the set of objects to be freed\n *  identically to duk__sweep_heap().\n */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_LOCAL void duk__finalize_refcounts(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"duk__finalize_refcounts: heap=%p\", (void *) heap));\n\n\thdr = heap->heap_allocated;\n\twhile (hdr) {\n\t\tif (!DUK_HEAPHDR_HAS_REACHABLE(hdr)) {\n\t\t\t/*\n\t\t\t *  Unreachable object about to be swept.  Finalize target refcounts\n\t\t\t *  (objects which the unreachable object points to) without doing\n\t\t\t *  refzero processing.  Recursive decrefs are also prevented when\n\t\t\t *  refzero processing is disabled.\n\t\t\t *\n\t\t\t *  Value cannot be a finalizable object, as they have been made\n\t\t\t *  temporarily reachable for this round.\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"unreachable object, refcount finalize before sweeping: %p\", (void *) hdr));\n\n\t\t\t/* Finalize using heap->heap_thread; DECREF has a\n\t\t\t * suppress check for mark-and-sweep which is based\n\t\t\t * on heap->ms_running.\n\t\t\t */\n\t\t\tduk_heaphdr_refcount_finalize_norz(heap, hdr);\n\t\t}\n\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/*\n *  Clear (reachable) flags of finalize_list.\n *\n *  We could mostly do in the sweep phase when we move objects from the\n *  heap into the finalize_list.  However, if a finalizer run is skipped\n *  during a mark-and-sweep, the objects on the finalize_list will be marked\n *  reachable during the next mark-and-sweep.  Since they're already on the\n *  finalize_list, no-one will be clearing their REACHABLE flag so we do it\n *  here.  (This now overlaps with the sweep handling in a harmless way.)\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__clear_finalize_list_flags(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__clear_finalize_list_flags: %p\", (void *) heap));\n\n\thdr = heap->finalize_list;\n\twhile (hdr) {\n\t\tDUK_HEAPHDR_CLEAR_REACHABLE(hdr);\n#if defined(DUK_USE_ASSERTIONS)\n\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZABLE(hdr) || \\\n\t\t           (heap->currently_finalizing == hdr));\n#endif\n\t\t/* DUK_HEAPHDR_FLAG_FINALIZED may be set. */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(hdr));\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Sweep stringtable.\n */\n\nDUK_LOCAL void duk__sweep_stringtable(duk_heap *heap, duk_size_t *out_count_keep) {\n\tduk_hstring *h;\n\tduk_hstring *prev;\n\tduk_uint32_t i;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_free = 0;\n#endif\n\tduk_size_t count_keep = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__sweep_stringtable: %p\", (void *) heap));\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tif (heap->strtable16 == NULL) {\n#else\n\tif (heap->strtable == NULL) {\n#endif\n\t\tgoto done;\n\t}\n\n\tfor (i = 0; i < heap->st_size; i++) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\th = DUK_USE_HEAPPTR_DEC16(heap->heap_udata, heap->strtable16[i]);\n#else\n\t\th = heap->strtable[i];\n#endif\n\t\tprev = NULL;\n\t\twhile (h != NULL) {\n\t\t\tduk_hstring *next;\n\t\t\tnext = h->hdr.h_next;\n\n\t\t\tif (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h))\n\t\t\t{\n\t\t\t\tDUK_HEAPHDR_CLEAR_REACHABLE((duk_heaphdr *) h);\n\t\t\t\tcount_keep++;\n\t\t\t\tprev = h;\n\t\t\t} else {\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tcount_free++;\n#endif\n\n\t\t\t\t/* For pinned strings the refcount has been\n\t\t\t\t * bumped.  We could unbump it here before\n\t\t\t\t * freeing, but that's actually not necessary\n\t\t\t\t * except for assertions.\n\t\t\t\t */\n#if 0\n\t\t\t\tif (DUK_HSTRING_HAS_PINNED_LITERAL(h)) {\n\t\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) > 0U);\n\t\t\t\t\tDUK_HSTRING_DECREF_NORZ(heap->heap_thread, h);\n\t\t\t\t\tDUK_HSTRING_CLEAR_PINNED_LITERAL(h);\n\t\t\t\t}\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t\t/* Non-zero refcounts should not happen for unreachable strings,\n\t\t\t\t * because we refcount finalize all unreachable objects which\n\t\t\t\t * should have decreased unreachable string refcounts to zero\n\t\t\t\t * (even for cycles).  However, pinned strings have a +1 bump.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) ==\n\t\t\t\t           DUK_HSTRING_HAS_PINNED_LITERAL(h) ? 1U : 0U);\n#endif\n\n\t\t\t\t/* Deal with weak references first. */\n\t\t\t\tduk_heap_strcache_string_remove(heap, (duk_hstring *) h);\n\n\t\t\t\t/* Remove the string from the string table. */\n\t\t\t\tduk_heap_strtable_unlink_prev(heap, (duk_hstring *) h, (duk_hstring *) prev);\n\n\t\t\t\t/* Free inner references (these exist e.g. when external\n\t\t\t\t * strings are enabled) and the struct itself.\n\t\t\t\t */\n\t\t\t\tduk_free_hstring(heap, (duk_hstring *) h);\n\n\t\t\t\t/* Don't update 'prev'; it should be last string kept. */\n\t\t\t}\n\n\t\t\th = next;\n\t\t}\n\t}\n\n done:\n#if defined(DUK_USE_DEBUG)\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep sweep stringtable: %ld freed, %ld kept\",\n\t                 (long) count_free, (long) count_keep));\n#endif\n\t*out_count_keep = count_keep;\n}\n\n/*\n *  Sweep heap.\n */\n\nDUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_small_uint_t flags, duk_size_t *out_count_keep) {\n\tduk_heaphdr *prev;  /* last element that was left in the heap */\n\tduk_heaphdr *curr;\n\tduk_heaphdr *next;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_free = 0;\n\tduk_size_t count_finalize = 0;\n\tduk_size_t count_rescue = 0;\n#endif\n\tduk_size_t count_keep = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__sweep_heap: %p\", (void *) heap));\n\n\tprev = NULL;\n\tcurr = heap->heap_allocated;\n\theap->heap_allocated = NULL;\n\twhile (curr) {\n\t\t/* Strings and ROM objects are never placed on the heap allocated list. */\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) != DUK_HTYPE_STRING);\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(curr));\n\n\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\n\t\tif (DUK_HEAPHDR_HAS_REACHABLE(curr)) {\n\t\t\t/*\n\t\t\t *  Reachable object:\n\t\t\t *    - If FINALIZABLE -> actually unreachable (but marked\n\t\t\t *      artificially reachable), queue to finalize_list.\n\t\t\t *    - If !FINALIZABLE but FINALIZED -> rescued after\n\t\t\t *      finalizer execution.\n\t\t\t *    - Otherwise just a normal, reachable object.\n\t\t\t *\n\t\t\t *  Objects which are kept are queued to heap_allocated\n\t\t\t *  tail (we're essentially filtering heap_allocated in\n\t\t\t *  practice).\n\t\t\t */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\t\tif (DUK_UNLIKELY(DUK_HEAPHDR_HAS_FINALIZABLE(curr))) {\n\t\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));\n\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable, finalizable --> move to finalize_list: %p\", (void *) curr));\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(curr);  /* Bump refcount so that refzero never occurs when pending a finalizer call. */\n#endif\n\t\t\t\tDUK_HEAP_INSERT_INTO_FINALIZE_LIST(heap, curr);\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tcount_finalize++;\n#endif\n\t\t\t}\n\t\t\telse\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\t\t\t{\n\t\t\t\tif (DUK_UNLIKELY(DUK_HEAPHDR_HAS_FINALIZED(curr))) {\n\t\t\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(curr));\n\t\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);\n\n\t\t\t\t\tif (flags & DUK_MS_FLAG_POSTPONE_RESCUE) {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable, finalized, but postponing rescue decisions --> keep object (with FINALIZED set): %!iO\", curr));\n\t\t\t\t\t\tcount_keep++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable, finalized --> rescued after finalization: %p\", (void *) curr));\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\t\t\t\t\tDUK_HEAPHDR_CLEAR_FINALIZED(curr);\n#endif\n#if defined(DUK_USE_DEBUG)\n\t\t\t\t\t\tcount_rescue++;\n#endif\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable --> keep: %!iO\", curr));\n\t\t\t\t\tcount_keep++;\n\t\t\t\t}\n\n\t\t\t\tif (prev != NULL) {\n\t\t\t\t\tDUK_ASSERT(heap->heap_allocated != NULL);\n\t\t\t\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, curr);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(heap->heap_allocated == NULL);\n\t\t\t\t\theap->heap_allocated = curr;\n\t\t\t\t}\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\t\t\t\tDUK_HEAPHDR_SET_PREV(heap, curr, prev);\n#endif\n\t\t\t\tDUK_HEAPHDR_ASSERT_LINKS(heap, prev);\n\t\t\t\tDUK_HEAPHDR_ASSERT_LINKS(heap, curr);\n\t\t\t\tprev = curr;\n\t\t\t}\n\n\t\t\t/*\n\t\t\t *  Shrink check for value stacks here.  We're inside\n\t\t\t *  ms_prevent_count protection which prevents recursive\n\t\t\t *  mark-and-sweep and refzero finalizers, so there are\n\t\t\t *  no side effects that would affect the heap lists.\n\t\t\t */\n\t\t\tif (DUK_HEAPHDR_IS_OBJECT(curr) && DUK_HOBJECT_IS_THREAD((duk_hobject *) curr)) {\n\t\t\t\tduk_hthread *thr_curr = (duk_hthread *) curr;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"value stack shrink check for thread: %!O\", curr));\n\t\t\t\tduk_valstack_shrink_check_nothrow(thr_curr, flags & DUK_MS_FLAG_EMERGENCY /*snug*/);\n\t\t\t}\n\n\t\t\tDUK_HEAPHDR_CLEAR_REACHABLE(curr);\n\t\t\t/* Keep FINALIZED if set, used if rescue decisions are postponed. */\n\t\t\t/* Keep FINALIZABLE for objects on finalize_list. */\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(curr));\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Unreachable object:\n\t\t\t *    - If FINALIZED, object was finalized but not\n\t\t\t *      rescued.  This doesn't affect freeing.\n\t\t\t *    - Otherwise normal unreachable object.\n\t\t\t *\n\t\t\t *  There's no guard preventing a FINALIZED object\n\t\t\t *  from being freed while finalizers execute: the\n\t\t\t *  artificial finalize_list reachability roots can't\n\t\t\t *  cause an incorrect free decision (but can cause\n\t\t\t *  an incorrect rescue decision).\n\t\t\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t/* Non-zero refcounts should not happen because we refcount\n\t\t\t * finalize all unreachable objects which should cancel out\n\t\t\t * refcounts (even for cycles).\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) == 0);\n#endif\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(curr));\n\n#if defined(DUK_USE_DEBUG)\n\t\t\tif (DUK_HEAPHDR_HAS_FINALIZED(curr)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; unreachable, finalized --> finalized object not rescued: %p\", (void *) curr));\n\t\t\t} else {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; not reachable --> free: %p\", (void *) curr));\n\t\t\t}\n\n#endif\n\n\t\t\t/* Note: object cannot be a finalizable unreachable object, as\n\t\t\t * they have been marked temporarily reachable for this round,\n\t\t\t * and are handled above.\n\t\t\t */\n\n#if defined(DUK_USE_DEBUG)\n\t\t\tcount_free++;\n#endif\n\n\t\t\t/* Weak refs should be handled here, but no weak refs for\n\t\t\t * any non-string objects exist right now.\n\t\t\t */\n\n\t\t\t/* Free object and all auxiliary (non-heap) allocs. */\n\t\t\tduk_heap_free_heaphdr_raw(heap, curr);\n\t\t}\n\n\t\tcurr = next;\n\t}\n\n\tif (prev != NULL) {\n\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, NULL);\n\t}\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, prev);\n\n#if defined(DUK_USE_DEBUG)\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep sweep objects (non-string): %ld freed, %ld kept, %ld rescued, %ld queued for finalization\",\n\t                 (long) count_free, (long) count_keep, (long) count_rescue, (long) count_finalize));\n#endif\n\t*out_count_keep = count_keep;\n}\n\n/*\n *  Litcache helpers.\n */\n\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_LOCAL void duk__wipe_litcache(duk_heap *heap) {\n\tduk_uint_t i;\n\tduk_litcache_entry *e;\n\n\te = heap->litcache;\n\tfor (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) {\n\t\te->addr = NULL;\n\t\t/* e->h does not need to be invalidated: when e->addr is\n\t\t * NULL, e->h is considered garbage.\n\t\t */\n\t\te++;\n\t}\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n\n/*\n *  Object compaction.\n *\n *  Compaction is assumed to never throw an error.\n */\n\nDUK_LOCAL int duk__protected_compact_object(duk_hthread *thr, void *udata) {\n\tduk_hobject *obj;\n\t/* XXX: for threads, compact stacks? */\n\n\tDUK_UNREF(udata);\n\tobj = duk_known_hobject(thr, -1);\n\tduk_hobject_compact_props(thr, obj);\n\treturn 0;\n}\n\n#if defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__compact_object_list(duk_heap *heap, duk_hthread *thr, duk_heaphdr *start, duk_size_t *p_count_check, duk_size_t *p_count_compact, duk_size_t *p_count_bytes_saved) {\n#else\nDUK_LOCAL void duk__compact_object_list(duk_heap *heap, duk_hthread *thr, duk_heaphdr *start) {\n#endif\n\tduk_heaphdr *curr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t old_size, new_size;\n#endif\n\tduk_hobject *obj;\n\n\tDUK_UNREF(heap);\n\n\tcurr = start;\n\twhile (curr) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"mark-and-sweep compact: %p\", (void *) curr));\n\n\t\tif (DUK_HEAPHDR_GET_TYPE(curr) != DUK_HTYPE_OBJECT) {\n\t\t\tgoto next;\n\t\t}\n\t\tobj = (duk_hobject *) curr;\n\n#if defined(DUK_USE_DEBUG)\n\t\told_size = DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_ASIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_HSIZE(obj));\n#endif\n\n\t\tDUK_DD(DUK_DDPRINT(\"compact object: %p\", (void *) obj));\n\t\tduk_push_hobject(thr, obj);\n\t\t/* XXX: disable error handlers for duration of compaction? */\n\t\tduk_safe_call(thr, duk__protected_compact_object, NULL, 1, 0);\n\n#if defined(DUK_USE_DEBUG)\n\t\tnew_size = DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_ASIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_HSIZE(obj));\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\t\t(*p_count_compact)++;\n\t\t(*p_count_bytes_saved) += (duk_size_t) (old_size - new_size);\n#endif\n\n\t next:\n\t\tcurr = DUK_HEAPHDR_GET_NEXT(heap, curr);\n#if defined(DUK_USE_DEBUG)\n\t\t(*p_count_check)++;\n#endif\n\t}\n}\n\nDUK_LOCAL void duk__compact_objects(duk_heap *heap) {\n\t/* XXX: which lists should participate?  to be finalized? */\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_check = 0;\n\tduk_size_t count_compact = 0;\n\tduk_size_t count_bytes_saved = 0;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"duk__compact_objects: %p\", (void *) heap));\n\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\n#if defined(DUK_USE_DEBUG)\n\tduk__compact_object_list(heap, heap->heap_thread, heap->heap_allocated, &count_check, &count_compact, &count_bytes_saved);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__compact_object_list(heap, heap->heap_thread, heap->finalize_list, &count_check, &count_compact, &count_bytes_saved);\n#endif\n#else\n\tduk__compact_object_list(heap, heap->heap_thread, heap->heap_allocated);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__compact_object_list(heap, heap->heap_thread, heap->finalize_list);\n#endif\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always handled to completion inline in DECREF. */\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep compact objects: %ld checked, %ld compaction attempts, %ld bytes saved by compaction\",\n\t                 (long) count_check, (long) count_compact, (long) count_bytes_saved));\n#endif\n}\n\n/*\n *  Assertion helpers.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\ntypedef void (*duk__gc_heaphdr_assert)(duk_heap *heap, duk_heaphdr *h);\ntypedef void (*duk__gc_hstring_assert)(duk_heap *heap, duk_hstring *h);\n\nDUK_LOCAL void duk__assert_walk_list(duk_heap *heap, duk_heaphdr *start, duk__gc_heaphdr_assert func) {\n\tduk_heaphdr *curr;\n\tfor (curr = start; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) {\n\t\tfunc(heap, curr);\n\t}\n}\n\nDUK_LOCAL void duk__assert_walk_strtable(duk_heap *heap, duk__gc_hstring_assert func) {\n\tduk_uint32_t i;\n\n\tfor (i = 0; i < heap->st_size; i++) {\n\t\tduk_hstring *h;\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\th = DUK_USE_HEAPPTR_DEC16(heap->heap_udata, heap->strtable16[i]);\n#else\n\t\th = heap->strtable[i];\n#endif\n\t\twhile (h != NULL) {\n\t\t\tfunc(heap, h);\n\t\t\th = h->hdr.h_next;\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__assert_heaphdr_flags_cb(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(h));\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(h));\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(h));\n\t/* may have FINALIZED */\n}\nDUK_LOCAL void duk__assert_heaphdr_flags(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__assert_heaphdr_flags_cb);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always handled to completion inline in DECREF. */\n#endif\n\t/* XXX: Assertions for finalize_list? */\n}\n\nDUK_LOCAL void duk__assert_validity_cb1(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tDUK_ASSERT(DUK_HEAPHDR_IS_OBJECT(h) || DUK_HEAPHDR_IS_BUFFER(h));\n\tduk_heaphdr_assert_valid_subclassed(h);\n}\nDUK_LOCAL void duk__assert_validity_cb2(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\tDUK_ASSERT(DUK_HEAPHDR_IS_STRING((duk_heaphdr *) h));\n\tduk_heaphdr_assert_valid_subclassed((duk_heaphdr *) h);\n}\nDUK_LOCAL void duk__assert_validity(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__assert_validity_cb1);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__assert_walk_list(heap, heap->finalize_list, duk__assert_validity_cb1);\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__assert_walk_list(heap, heap->refzero_list, duk__assert_validity_cb1);\n#endif\n\tduk__assert_walk_strtable(heap, duk__assert_validity_cb2);\n}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_LOCAL void duk__assert_valid_refcounts_cb(duk_heap *heap, duk_heaphdr *h) {\n\t/* Cannot really assert much w.r.t. refcounts now. */\n\n\tDUK_UNREF(heap);\n\tif (DUK_HEAPHDR_GET_REFCOUNT(h) == 0 &&\n\t    DUK_HEAPHDR_HAS_FINALIZED(h)) {\n\t\t/* An object may be in heap_allocated list with a zero\n\t\t * refcount if it has just been finalized and is waiting\n\t\t * to be collected by the next cycle.\n\t\t * (This doesn't currently happen however.)\n\t\t */\n\t} else if (DUK_HEAPHDR_GET_REFCOUNT(h) == 0) {\n\t\t/* An object may be in heap_allocated list with a zero\n\t\t * refcount also if it is a temporary object created\n\t\t * during debugger paused state.  It will get collected\n\t\t * by mark-and-sweep based on its reachability status\n\t\t * (presumably not reachable because refcount is 0).\n\t\t */\n\t}\n\tDUK_ASSERT_DISABLE(DUK_HEAPHDR_GET_REFCOUNT(h) >= 0);  /* Unsigned. */\n}\nDUK_LOCAL void duk__assert_valid_refcounts(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__assert_valid_refcounts_cb);\n}\n\nDUK_LOCAL void duk__clear_assert_refcounts_cb1(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\th->h_assert_refcount = 0;\n}\nDUK_LOCAL void duk__clear_assert_refcounts_cb2(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\t((duk_heaphdr *) h)->h_assert_refcount = 0;\n}\nDUK_LOCAL void duk__clear_assert_refcounts(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__clear_assert_refcounts_cb1);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__assert_walk_list(heap, heap->finalize_list, duk__clear_assert_refcounts_cb1);\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__assert_walk_list(heap, heap->refzero_list, duk__clear_assert_refcounts_cb1);\n#endif\n\tduk__assert_walk_strtable(heap, duk__clear_assert_refcounts_cb2);\n}\n\nDUK_LOCAL void duk__check_refcount_heaphdr(duk_heaphdr *hdr) {\n\tduk_bool_t count_ok;\n\tduk_size_t expect_refc;\n\n\t/* The refcount check only makes sense for reachable objects on\n\t * heap_allocated or string table, after the sweep phase.  Prior to\n\t * sweep phase refcounts will include references that are not visible\n\t * via reachability roots.\n\t *\n\t * Because we're called after the sweep phase, all heap objects on\n\t * heap_allocated are reachable.  REACHABLE flags have already been\n\t * cleared so we can't check them.\n\t */\n\n\t/* ROM objects have intentionally incorrect refcount (1), but we won't\n\t * check them.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(hdr));\n\n\texpect_refc = hdr->h_assert_refcount;\n\tif (DUK_HEAPHDR_IS_STRING(hdr) && DUK_HSTRING_HAS_PINNED_LITERAL((duk_hstring *) hdr)) {\n\t\texpect_refc++;\n\t}\n\tcount_ok = ((duk_size_t) DUK_HEAPHDR_GET_REFCOUNT(hdr) == expect_refc);\n\tif (!count_ok) {\n\t\tDUK_D(DUK_DPRINT(\"refcount mismatch for: %p: header=%ld counted=%ld --> %!iO\",\n\t\t                 (void *) hdr, (long) DUK_HEAPHDR_GET_REFCOUNT(hdr),\n\t\t                 (long) hdr->h_assert_refcount, hdr));\n\t\tDUK_ASSERT(0);\n\t}\n}\n\nDUK_LOCAL void duk__check_assert_refcounts_cb1(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tduk__check_refcount_heaphdr(h);\n}\nDUK_LOCAL void duk__check_assert_refcounts_cb2(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\tduk__check_refcount_heaphdr((duk_heaphdr *) h);\n}\nDUK_LOCAL void duk__check_assert_refcounts(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__check_assert_refcounts_cb1);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__assert_walk_list(heap, heap->finalize_list, duk__check_assert_refcounts_cb1);\n#endif\n\t/* XXX: Assert anything for refzero_list? */\n\tduk__assert_walk_strtable(heap, duk__check_assert_refcounts_cb2);\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_LOCAL void duk__assert_litcache_nulls(duk_heap *heap) {\n\tduk_uint_t i;\n\tduk_litcache_entry *e;\n\n\te = heap->litcache;\n\tfor (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) {\n\t\t/* Entry addresses were NULLed before mark-and-sweep, check\n\t\t * that they're still NULL afterwards to ensure no pointers\n\t\t * were recorded through any side effects.\n\t\t */\n\t\tDUK_ASSERT(e->addr == NULL);\n\t}\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n#endif  /* DUK_USE_ASSERTIONS */\n\n/*\n *  Stats dump.\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__dump_stats(duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"stats executor: opcodes=%ld, interrupt=%ld, throw=%ld\",\n\t                 (long) heap->stats_exec_opcodes, (long) heap->stats_exec_interrupt,\n\t                 (long) heap->stats_exec_throw));\n\tDUK_D(DUK_DPRINT(\"stats call: all=%ld, tailcall=%ld, ecmatoecma=%ld\",\n\t                 (long) heap->stats_call_all, (long) heap->stats_call_tailcall,\n\t                 (long) heap->stats_call_ecmatoecma));\n\tDUK_D(DUK_DPRINT(\"stats safecall: all=%ld, nothrow=%ld, throw=%ld\",\n\t                 (long) heap->stats_safecall_all, (long) heap->stats_safecall_nothrow,\n\t                 (long) heap->stats_safecall_throw));\n\tDUK_D(DUK_DPRINT(\"stats mark-and-sweep: try_count=%ld, skip_count=%ld, emergency_count=%ld\",\n\t                 (long) heap->stats_ms_try_count, (long) heap->stats_ms_skip_count,\n\t                 (long) heap->stats_ms_emergency_count));\n\tDUK_D(DUK_DPRINT(\"stats stringtable: intern_hit=%ld, intern_miss=%ld, \"\n\t                 \"resize_check=%ld, resize_grow=%ld, resize_shrink=%ld, \"\n\t                 \"litcache_hit=%ld, litcache_miss=%ld, litcache_pin=%ld\",\n\t                 (long) heap->stats_strtab_intern_hit, (long) heap->stats_strtab_intern_miss,\n\t                 (long) heap->stats_strtab_resize_check, (long) heap->stats_strtab_resize_grow,\n\t                 (long) heap->stats_strtab_resize_shrink, (long) heap->stats_strtab_litcache_hit,\n\t                 (long) heap->stats_strtab_litcache_miss, (long) heap->stats_strtab_litcache_pin));\n\tDUK_D(DUK_DPRINT(\"stats object: realloc_props=%ld, abandon_array=%ld\",\n\t                 (long) heap->stats_object_realloc_props, (long) heap->stats_object_abandon_array));\n\tDUK_D(DUK_DPRINT(\"stats getownpropdesc: count=%ld, hit=%ld, miss=%ld\",\n\t                 (long) heap->stats_getownpropdesc_count, (long) heap->stats_getownpropdesc_hit,\n\t                 (long) heap->stats_getownpropdesc_miss));\n\tDUK_D(DUK_DPRINT(\"stats getpropdesc: count=%ld, hit=%ld, miss=%ld\",\n\t                 (long) heap->stats_getpropdesc_count, (long) heap->stats_getpropdesc_hit,\n\t                 (long) heap->stats_getpropdesc_miss));\n\tDUK_D(DUK_DPRINT(\"stats getprop: all=%ld, arrayidx=%ld, bufobjidx=%ld, \"\n\t                 \"bufferidx=%ld, bufferlen=%ld, stringidx=%ld, stringlen=%ld, \"\n\t                 \"proxy=%ld, arguments=%ld\",\n\t                 (long) heap->stats_getprop_all, (long) heap->stats_getprop_arrayidx,\n\t                 (long) heap->stats_getprop_bufobjidx, (long) heap->stats_getprop_bufferidx,\n\t                 (long) heap->stats_getprop_bufferlen, (long) heap->stats_getprop_stringidx,\n\t                 (long) heap->stats_getprop_stringlen, (long) heap->stats_getprop_proxy,\n\t                 (long) heap->stats_getprop_arguments));\n\tDUK_D(DUK_DPRINT(\"stats putprop: all=%ld, arrayidx=%ld, bufobjidx=%ld, \"\n\t                 \"bufferidx=%ld, proxy=%ld\",\n\t                 (long) heap->stats_putprop_all, (long) heap->stats_putprop_arrayidx,\n\t                 (long) heap->stats_putprop_bufobjidx, (long) heap->stats_putprop_bufferidx,\n\t                 (long) heap->stats_putprop_proxy));\n\tDUK_D(DUK_DPRINT(\"stats getvar: all=%ld\",\n\t                 (long) heap->stats_getvar_all));\n\tDUK_D(DUK_DPRINT(\"stats putvar: all=%ld\",\n\t                 (long) heap->stats_putvar_all));\n\tDUK_D(DUK_DPRINT(\"stats envrec: delayedcreate=%ld, create=%ld, newenv=%ld, oldenv=%ld, pushclosure=%ld\",\n\t                 (long) heap->stats_envrec_delayedcreate,\n\t                 (long) heap->stats_envrec_create,\n\t                 (long) heap->stats_envrec_newenv,\n\t                 (long) heap->stats_envrec_oldenv,\n\t                 (long) heap->stats_envrec_pushclosure));\n}\n#endif  /* DUK_USE_DEBUG */\n\n/*\n *  Main mark-and-sweep function.\n *\n *  'flags' represents the features requested by the caller.  The current\n *  heap->ms_base_flags is ORed automatically into the flags; the base flags\n *  mask typically prevents certain mark-and-sweep operation to avoid trouble.\n */\n\nDUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags) {\n\tduk_size_t count_keep_obj;\n\tduk_size_t count_keep_str;\n#if defined(DUK_USE_VOLUNTARY_GC)\n\tduk_size_t tmp;\n#endif\n\n\tDUK_STATS_INC(heap, stats_ms_try_count);\n#if defined(DUK_USE_DEBUG)\n\tif (flags & DUK_MS_FLAG_EMERGENCY) {\n\t\tDUK_STATS_INC(heap, stats_ms_emergency_count);\n\t}\n#endif\n\n\t/* If debugger is paused, garbage collection is disabled by default.\n\t * This is achieved by bumping ms_prevent_count when becoming paused.\n\t */\n\tDUK_ASSERT(!DUK_HEAP_HAS_DEBUGGER_PAUSED(heap) || heap->ms_prevent_count > 0);\n\n\t/* Prevention/recursion check as soon as possible because we may\n\t * be called a number of times when voluntary mark-and-sweep is\n\t * pending.\n\t */\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject recursive mark-and-sweep\"));\n\t\tDUK_STATS_INC(heap, stats_ms_skip_count);\n\t\treturn;\n\t}\n\tDUK_ASSERT(heap->ms_running == 0);  /* ms_prevent_count is bumped when ms_running is set */\n\n\t/* Heap_thread is used during mark-and-sweep for refcount finalization\n\t * (it's also used for finalizer execution once mark-and-sweep is\n\t * complete).  Heap allocation code ensures heap_thread is set and\n\t * properly initialized before setting ms_prevent_count to 0.\n\t */\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(heap->heap_thread->valstack != NULL);\n\n\tDUK_D(DUK_DPRINT(\"garbage collect (mark-and-sweep) starting, requested flags: 0x%08lx, effective flags: 0x%08lx\",\n\t                 (unsigned long) flags, (unsigned long) (flags | heap->ms_base_flags)));\n\n\tflags |= heap->ms_base_flags;\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tif (heap->finalize_list != NULL) {\n\t\tflags |= DUK_MS_FLAG_POSTPONE_RESCUE;\n\t}\n#endif\n\n\t/*\n\t *  Assertions before\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\tDUK_ASSERT(heap->ms_running == 0);\n\tDUK_ASSERT(!DUK_HEAP_HAS_DEBUGGER_PAUSED(heap));\n\tDUK_ASSERT(!DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap));\n\tDUK_ASSERT(heap->ms_recursion_depth == 0);\n\tduk__assert_heaphdr_flags(heap);\n\tduk__assert_validity(heap);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* Note: heap->refzero_free_running may be true; a refcount\n\t * finalizer may trigger a mark-and-sweep.\n\t */\n\tduk__assert_valid_refcounts(heap);\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n#endif  /* DUK_USE_ASSERTIONS */\n\n\t/*\n\t *  Begin\n\t */\n\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\tDUK_ASSERT(heap->ms_running == 0);\n\theap->ms_prevent_count = 1;\n\theap->ms_running = 1;\n\n\t/*\n\t *  Free activation/catcher freelists on every mark-and-sweep for now.\n\t *  This is an initial rough draft; ideally we'd keep count of the\n\t *  freelist size and free only excess entries.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"freeing temporary freelists\"));\n\tduk_heap_free_freelists(heap);\n\n\t/*\n\t *  Mark roots, hoping that recursion limit is not normally hit.\n\t *  If recursion limit is hit, run additional reachability rounds\n\t *  starting from \"temproots\" until marking is complete.\n\t *\n\t *  Marking happens in two phases: first we mark actual reachability\n\t *  roots (and run \"temproots\" to complete the process).  Then we\n\t *  check which objects are unreachable and are finalizable; such\n\t *  objects are marked as FINALIZABLE and marked as reachability\n\t *  (and \"temproots\" is run again to complete the process).\n\t *\n\t *  The heap finalize_list must also be marked as a reachability root.\n\t *  There may be objects on the list from a previous round if the\n\t *  previous run had finalizer skip flag.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__clear_assert_refcounts(heap);\n#endif\n#if defined(DUK_USE_LITCACHE_SIZE)\n\tduk__wipe_litcache(heap);\n#endif\n\tduk__mark_roots_heap(heap);               /* Mark main reachability roots. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);   /* Always handled to completion inline in DECREF. */\n#endif\n\tduk__mark_temproots_by_heap_scan(heap);   /* Temproots. */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__mark_finalizable(heap);              /* Mark finalizable as reachability roots. */\n\tduk__mark_finalize_list(heap);            /* Mark finalizer work list as reachability roots. */\n#endif\n\tduk__mark_temproots_by_heap_scan(heap);   /* Temproots. */\n\n\t/*\n\t *  Sweep garbage and remove marking flags, and move objects with\n\t *  finalizers to the finalizer work list.\n\t *\n\t *  Objects to be swept need to get their refcounts finalized before\n\t *  they are swept.  In other words, their target object refcounts\n\t *  need to be decreased.  This has to be done before freeing any\n\t *  objects to avoid decref'ing dangling pointers (which may happen\n\t *  even without bugs, e.g. with reference loops)\n\t *\n\t *  Because strings don't point to other heap objects, similar\n\t *  finalization is not necessary for strings.\n\t */\n\n\t/* XXX: more emergency behavior, e.g. find smaller hash sizes etc */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__finalize_refcounts(heap);\n#endif\n\tduk__sweep_heap(heap, flags, &count_keep_obj);\n\tduk__sweep_stringtable(heap, &count_keep_str);\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__check_assert_refcounts(heap);\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);   /* Always handled to completion inline in DECREF. */\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__clear_finalize_list_flags(heap);\n#endif\n\n\t/*\n\t *  Object compaction (emergency only).\n\t *\n\t *  Object compaction is a separate step after sweeping, as there is\n\t *  more free memory for it to work with.  Also, currently compaction\n\t *  may insert new objects into the heap allocated list and the string\n\t *  table which we don't want to do during a sweep (the reachability\n\t *  flags of such objects would be incorrect).  The objects inserted\n\t *  are currently:\n\t *\n\t *    - a temporary duk_hbuffer for a new properties allocation\n\t *    - if array part is abandoned, string keys are interned\n\t *\n\t *  The object insertions go to the front of the list, so they do not\n\t *  cause an infinite loop (they are not compacted).\n\t *\n\t *  At present compaction is not allowed when mark-and-sweep runs\n\t *  during error handling because it involves a duk_safe_call()\n\t *  interfering with error state.\n\t */\n\n\tif ((flags & DUK_MS_FLAG_EMERGENCY) &&\n\t    !(flags & DUK_MS_FLAG_NO_OBJECT_COMPACTION)) {\n\t\tif (heap->lj.type != DUK_LJ_TYPE_UNKNOWN) {\n\t\t\tDUK_D(DUK_DPRINT(\"lj.type (%ld) not DUK_LJ_TYPE_UNKNOWN, skip object compaction\", (long) heap->lj.type));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"object compaction\"));\n\t\t\tduk__compact_objects(heap);\n\t\t}\n\t}\n\n\t/*\n\t *  String table resize check.\n\t *\n\t *  This is mainly useful in emergency GC: if the string table load\n\t *  factor is really low for some reason, we can shrink the string\n\t *  table to a smaller size and free some memory in the process.\n\t *  Only execute in emergency GC.  String table has internal flags\n\t *  to protect against recursive resizing if this mark-and-sweep pass\n\t *  was triggered by a string table resize.\n\t */\n\n\tif (flags & DUK_MS_FLAG_EMERGENCY) {\n\t\tDUK_D(DUK_DPRINT(\"stringtable resize check in emergency gc\"));\n\t\tduk_heap_strtable_force_resize(heap);\n\t}\n\n\t/*\n\t *  Finish\n\t */\n\n\tDUK_ASSERT(heap->ms_prevent_count == 1);\n\tDUK_ASSERT(heap->ms_running == 1);\n\theap->ms_prevent_count = 0;\n\theap->ms_running = 0;\n\n\t/*\n\t *  Assertions after\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\tDUK_ASSERT(!DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap));\n\tDUK_ASSERT(heap->ms_recursion_depth == 0);\n\tduk__assert_heaphdr_flags(heap);\n\tduk__assert_validity(heap);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* Note: heap->refzero_free_running may be true; a refcount\n\t * finalizer may trigger a mark-and-sweep.\n\t */\n\tduk__assert_valid_refcounts(heap);\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n#if defined(DUK_USE_LITCACHE_SIZE)\n\tduk__assert_litcache_nulls(heap);\n#endif  /* DUK_USE_LITCACHE_SIZE */\n#endif  /* DUK_USE_ASSERTIONS */\n\n\t/*\n\t *  Reset trigger counter\n\t */\n\n#if defined(DUK_USE_VOLUNTARY_GC)\n\ttmp = (count_keep_obj + count_keep_str) / 256;\n\theap->ms_trigger_counter = (duk_int_t) (\n\t    (tmp * DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT) +\n\t    DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD);\n\tDUK_D(DUK_DPRINT(\"garbage collect (mark-and-sweep) finished: %ld objects kept, %ld strings kept, trigger reset to %ld\",\n\t                 (long) count_keep_obj, (long) count_keep_str, (long) heap->ms_trigger_counter));\n#else\n\tDUK_D(DUK_DPRINT(\"garbage collect (mark-and-sweep) finished: %ld objects kept, %ld strings kept, no voluntary trigger\",\n\t                 (long) count_keep_obj, (long) count_keep_str));\n#endif\n\n\t/*\n\t *  Stats dump\n\t */\n\n#if defined(DUK_USE_DEBUG)\n\tduk__dump_stats(heap);\n#endif\n\n\t/*\n\t *  Finalize objects in the finalization work list.  Finalized\n\t *  objects are queued back to heap_allocated with FINALIZED set.\n\t *\n\t *  Since finalizers may cause arbitrary side effects, they are\n\t *  prevented e.g. during string table and object property allocation\n\t *  resizing using heap->pf_prevent_count.  In this case the objects\n\t *  remain in the finalization work list after mark-and-sweep exits\n\t *  and they may be finalized on the next pass or any DECREF checking\n\t *  for finalize_list.\n\t *\n\t *  As of Duktape 2.1 finalization happens outside mark-and-sweep\n\t *  protection.  Mark-and-sweep is allowed while the finalize_list\n\t *  is being processed, but no rescue decisions are done while the\n\t *  process is on-going.  This avoids incorrect rescue decisions\n\t *  if an object is considered reachable (and thus rescued) because\n\t *  of a reference via finalize_list (which is considered a reachability\n\t *  root).  When finalize_list is being processed, reachable objects\n\t *  with FINALIZED set will just keep their FINALIZED flag for later\n\t *  mark-and-sweep processing.\n\t *\n\t *  This could also be handled (a bit better) by having a more refined\n\t *  notion of reachability for rescue/free decisions.\n\t *\n\t *  XXX: avoid finalizer execution when doing emergency GC?\n\t */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t/* Attempt to process finalize_list, pf_prevent_count check\n\t * is inside the target.\n\t */\n\tduk_heap_process_finalize_list(heap);\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_heap_memory.c",
    "content": "/*\n *  Memory allocation handling.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Voluntary GC check\n */\n\n#if defined(DUK_USE_VOLUNTARY_GC)\nDUK_LOCAL DUK_INLINE void duk__check_voluntary_gc(duk_heap *heap) {\n\tif (DUK_UNLIKELY(--(heap)->ms_trigger_counter < 0)) {\n#if defined(DUK_USE_DEBUG)\n\t\tif (heap->ms_prevent_count == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"triggering voluntary mark-and-sweep\"));\n\t\t} else {\n\t\t\tDUK_DD(DUK_DDPRINT(\"gc blocked -> skip voluntary mark-and-sweep now\"));\n\t\t}\n#endif\n\n\t\t/* Prevention checks in the call target handle cases where\n\t\t * voluntary GC is not allowed.  The voluntary GC trigger\n\t\t * counter is only rewritten if mark-and-sweep actually runs.\n\t\t */\n\t\tduk_heap_mark_and_sweep(heap, DUK_MS_FLAG_VOLUNTARY /*flags*/);\n\t}\n}\n#define DUK__VOLUNTARY_PERIODIC_GC(heap)  do { duk__check_voluntary_gc((heap)); } while (0)\n#else\n#define DUK__VOLUNTARY_PERIODIC_GC(heap)  /* no voluntary gc */\n#endif  /* DUK_USE_VOLUNTARY_GC */\n\n/*\n *  Allocate memory with garbage collection\n */\n\nDUK_INTERNAL void *duk_heap_mem_alloc(duk_heap *heap, duk_size_t size) {\n\tvoid *res;\n\tduk_small_int_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT_DISABLE(size >= 0);\n\n\t/*\n\t *  Voluntary periodic GC (if enabled)\n\t */\n\n\tDUK__VOLUNTARY_PERIODIC_GC(heap);\n\n\t/*\n\t *  First attempt\n\t */\n\n#if defined(DUK_USE_GC_TORTURE)\n\t/* Simulate alloc failure on every alloc, except when mark-and-sweep\n\t * is running.\n\t */\n\tif (heap->ms_prevent_count == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"gc torture enabled, pretend that first alloc attempt fails\"));\n\t\tres = NULL;\n\t\tDUK_UNREF(res);\n\t\tgoto skip_attempt;\n\t}\n#endif\n\tres = heap->alloc_func(heap->heap_udata, size);\n\tif (DUK_LIKELY(res || size == 0)) {\n\t\t/* For zero size allocations NULL is allowed. */\n\t\treturn res;\n\t}\n#if defined(DUK_USE_GC_TORTURE)\n skip_attempt:\n#endif\n\n\tDUK_D(DUK_DPRINT(\"first alloc attempt failed, attempt to gc and retry\"));\n\n#if 0\n\t/*\n\t *  Avoid a GC if GC is already running.  This can happen at a late\n\t *  stage in a GC when we try to e.g. resize the stringtable\n\t *  or compact objects.\n\t *\n\t *  NOTE: explicit handling isn't actually be needed: if the GC is\n\t *  not allowed, duk_heap_mark_and_sweep() will reject it for every\n\t *  attempt in the loop below, resulting in a NULL same as here.\n\t */\n\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_alloc() failed, gc in progress (gc skipped), alloc size %ld\", (long) size));\n\t\treturn NULL;\n\t}\n#endif\n\n\t/*\n\t *  Retry with several GC attempts.  Initial attempts are made without\n\t *  emergency mode; later attempts use emergency mode which minimizes\n\t *  memory allocations forcibly.\n\t */\n\n\tfor (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) {\n\t\tduk_small_uint_t flags;\n\n\t\tflags = 0;\n\t\tif (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) {\n\t\t\tflags |= DUK_MS_FLAG_EMERGENCY;\n\t\t}\n\n\t\tduk_heap_mark_and_sweep(heap, flags);\n\n\t\tres = heap->alloc_func(heap->heap_udata, size);\n\t\tif (res) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_alloc() succeeded after gc (pass %ld), alloc size %ld\",\n\t\t\t                 (long) (i + 1), (long) size));\n\t\t\treturn res;\n\t\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"duk_heap_mem_alloc() failed even after gc, alloc size %ld\", (long) size));\n\treturn NULL;\n}\n\nDUK_INTERNAL void *duk_heap_mem_alloc_zeroed(duk_heap *heap, duk_size_t size) {\n\tvoid *res;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT_DISABLE(size >= 0);\n\n\tres = DUK_ALLOC(heap, size);\n\tif (DUK_LIKELY(res != NULL)) {\n\t\tduk_memzero(res, size);\n\t}\n\treturn res;\n}\n\nDUK_INTERNAL void *duk_heap_mem_alloc_checked(duk_hthread *thr, duk_size_t size) {\n\tvoid *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tres = duk_heap_mem_alloc(thr->heap, size);\n\tif (DUK_LIKELY(res != NULL || size == 0)) {\n\t\treturn res;\n\t}\n\tDUK_ERROR_ALLOC_FAILED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_INTERNAL void *duk_heap_mem_alloc_checked_zeroed(duk_hthread *thr, duk_size_t size) {\n\tvoid *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tres = duk_heap_mem_alloc_zeroed(thr->heap, size);\n\tif (DUK_LIKELY(res != NULL || size == 0)) {\n\t\treturn res;\n\t}\n\tDUK_ERROR_ALLOC_FAILED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Reallocate memory with garbage collection\n */\n\nDUK_INTERNAL void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, duk_size_t newsize) {\n\tvoid *res;\n\tduk_small_int_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\t/* ptr may be NULL */\n\tDUK_ASSERT_DISABLE(newsize >= 0);\n\n\t/*\n\t *  Voluntary periodic GC (if enabled)\n\t */\n\n\tDUK__VOLUNTARY_PERIODIC_GC(heap);\n\n\t/*\n\t *  First attempt\n\t */\n\n#if defined(DUK_USE_GC_TORTURE)\n\t/* Simulate alloc failure on every realloc, except when mark-and-sweep\n\t * is running.\n\t */\n\tif (heap->ms_prevent_count == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"gc torture enabled, pretend that first realloc attempt fails\"));\n\t\tres = NULL;\n\t\tDUK_UNREF(res);\n\t\tgoto skip_attempt;\n\t}\n#endif\n\tres = heap->realloc_func(heap->heap_udata, ptr, newsize);\n\tif (DUK_LIKELY(res || newsize == 0)) {\n\t\t/* For zero size allocations NULL is allowed. */\n\t\treturn res;\n\t}\n#if defined(DUK_USE_GC_TORTURE)\n skip_attempt:\n#endif\n\n\tDUK_D(DUK_DPRINT(\"first realloc attempt failed, attempt to gc and retry\"));\n\n#if 0\n\t/*\n\t *  Avoid a GC if GC is already running.  See duk_heap_mem_alloc().\n\t */\n\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc() failed, gc in progress (gc skipped), alloc size %ld\", (long) newsize));\n\t\treturn NULL;\n\t}\n#endif\n\n\t/*\n\t *  Retry with several GC attempts.  Initial attempts are made without\n\t *  emergency mode; later attempts use emergency mode which minimizes\n\t *  memory allocations forcibly.\n\t */\n\n\tfor (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) {\n\t\tduk_small_uint_t flags;\n\n\t\tflags = 0;\n\t\tif (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) {\n\t\t\tflags |= DUK_MS_FLAG_EMERGENCY;\n\t\t}\n\n\t\tduk_heap_mark_and_sweep(heap, flags);\n\n\t\tres = heap->realloc_func(heap->heap_udata, ptr, newsize);\n\t\tif (res || newsize == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc() succeeded after gc (pass %ld), alloc size %ld\",\n\t\t\t                 (long) (i + 1), (long) newsize));\n\t\t\treturn res;\n\t\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc() failed even after gc, alloc size %ld\", (long) newsize));\n\treturn NULL;\n}\n\n/*\n *  Reallocate memory with garbage collection, using a callback to provide\n *  the current allocated pointer.  This variant is used when a mark-and-sweep\n *  (e.g. finalizers) might change the original pointer.\n */\n\nDUK_INTERNAL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize) {\n\tvoid *res;\n\tduk_small_int_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT_DISABLE(newsize >= 0);\n\n\t/*\n\t *  Voluntary periodic GC (if enabled)\n\t */\n\n\tDUK__VOLUNTARY_PERIODIC_GC(heap);\n\n\t/*\n\t *  First attempt\n\t */\n\n#if defined(DUK_USE_GC_TORTURE)\n\t/* Simulate alloc failure on every realloc, except when mark-and-sweep\n\t * is running.\n\t */\n\tif (heap->ms_prevent_count == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"gc torture enabled, pretend that first indirect realloc attempt fails\"));\n\t\tres = NULL;\n\t\tDUK_UNREF(res);\n\t\tgoto skip_attempt;\n\t}\n#endif\n\tres = heap->realloc_func(heap->heap_udata, cb(heap, ud), newsize);\n\tif (DUK_LIKELY(res || newsize == 0)) {\n\t\t/* For zero size allocations NULL is allowed. */\n\t\treturn res;\n\t}\n#if defined(DUK_USE_GC_TORTURE)\n skip_attempt:\n#endif\n\n\tDUK_D(DUK_DPRINT(\"first indirect realloc attempt failed, attempt to gc and retry\"));\n\n#if 0\n\t/*\n\t *  Avoid a GC if GC is already running.  See duk_heap_mem_alloc().\n\t */\n\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc_indirect() failed, gc in progress (gc skipped), alloc size %ld\", (long) newsize));\n\t\treturn NULL;\n\t}\n#endif\n\n\t/*\n\t *  Retry with several GC attempts.  Initial attempts are made without\n\t *  emergency mode; later attempts use emergency mode which minimizes\n\t *  memory allocations forcibly.\n\t */\n\n\tfor (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) {\n\t\tduk_small_uint_t flags;\n\n#if defined(DUK_USE_DEBUG)\n\t\tvoid *ptr_pre;\n\t\tvoid *ptr_post;\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\t\tptr_pre = cb(heap, ud);\n#endif\n\t\tflags = 0;\n\t\tif (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) {\n\t\t\tflags |= DUK_MS_FLAG_EMERGENCY;\n\t\t}\n\n\t\tduk_heap_mark_and_sweep(heap, flags);\n#if defined(DUK_USE_DEBUG)\n\t\tptr_post = cb(heap, ud);\n\t\tif (ptr_pre != ptr_post) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"realloc base pointer changed by mark-and-sweep: %p -> %p\",\n\t\t\t                   (void *) ptr_pre, (void *) ptr_post));\n\t\t}\n#endif\n\n\t\t/* Note: key issue here is to re-lookup the base pointer on every attempt.\n\t\t * The pointer being reallocated may change after every mark-and-sweep.\n\t\t */\n\n\t\tres = heap->realloc_func(heap->heap_udata, cb(heap, ud), newsize);\n\t\tif (res || newsize == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc_indirect() succeeded after gc (pass %ld), alloc size %ld\",\n\t\t\t                 (long) (i + 1), (long) newsize));\n\t\t\treturn res;\n\t\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc_indirect() failed even after gc, alloc size %ld\", (long) newsize));\n\treturn NULL;\n}\n\n/*\n *  Free memory\n */\n\nDUK_INTERNAL void duk_heap_mem_free(duk_heap *heap, void *ptr) {\n\tDUK_ASSERT(heap != NULL);\n\t/* ptr may be NULL */\n\n\t/* Must behave like a no-op with NULL and any pointer returned from\n\t * malloc/realloc with zero size.\n\t */\n\theap->free_func(heap->heap_udata, ptr);\n\n\t/* Never perform a GC (even voluntary) in a memory free, otherwise\n\t * all call sites doing frees would need to deal with the side effects.\n\t * No need to update voluntary GC counter either.\n\t */\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_heap_misc.c",
    "content": "/*\n *  Support functions for duk_heap.\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphdr *hdr) {\n\tduk_heaphdr *root;\n\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) != DUK_HTYPE_STRING);\n\n\troot = heap->heap_allocated;\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tif (root != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, root) == NULL);\n\t\tDUK_HEAPHDR_SET_PREV(heap, root, hdr);\n\t}\n\tDUK_HEAPHDR_SET_PREV(heap, hdr, NULL);\n#endif\n\tDUK_HEAPHDR_SET_NEXT(heap, hdr, root);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, hdr);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, root);\n\theap->heap_allocated = hdr;\n}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL void duk_heap_remove_from_heap_allocated(duk_heap *heap, duk_heaphdr *hdr) {\n\tduk_heaphdr *prev;\n\tduk_heaphdr *next;\n\n\t/* Strings are in string table. */\n\tDUK_ASSERT(hdr != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) != DUK_HTYPE_STRING);\n\n\t/* Target 'hdr' must be in heap_allocated (not e.g. finalize_list).\n\t * If not, heap lists will become corrupted so assert early for it.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\t{\n\t\tduk_heaphdr *tmp;\n\t\tfor (tmp = heap->heap_allocated; tmp != NULL; tmp = DUK_HEAPHDR_GET_NEXT(heap, tmp)) {\n\t\t\tif (tmp == hdr) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(tmp == hdr);\n\t}\n#endif\n\n\t/* Read/write only once to minimize pointer compression calls. */\n\tprev = DUK_HEAPHDR_GET_PREV(heap, hdr);\n\tnext = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\n\tif (prev != NULL) {\n\t\tDUK_ASSERT(heap->heap_allocated != hdr);\n\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, next);\n\t} else {\n\t\tDUK_ASSERT(heap->heap_allocated == hdr);\n\t\theap->heap_allocated = next;\n\t}\n\tif (next != NULL) {\n\t\tDUK_HEAPHDR_SET_PREV(heap, next, prev);\n\t} else {\n\t\t;\n\t}\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL void duk_heap_insert_into_finalize_list(duk_heap *heap, duk_heaphdr *hdr) {\n\tduk_heaphdr *root;\n\n\troot = heap->finalize_list;\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tDUK_HEAPHDR_SET_PREV(heap, hdr, NULL);\n\tif (root != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, root) == NULL);\n\t\tDUK_HEAPHDR_SET_PREV(heap, root, hdr);\n\t}\n#endif\n\tDUK_HEAPHDR_SET_NEXT(heap, hdr, root);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, hdr);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, root);\n\theap->finalize_list = hdr;\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL void duk_heap_remove_from_finalize_list(duk_heap *heap, duk_heaphdr *hdr) {\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tduk_heaphdr *next;\n\tduk_heaphdr *prev;\n\n\tnext = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\tprev = DUK_HEAPHDR_GET_PREV(heap, hdr);\n\tif (next != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, next) == hdr);\n\t\tDUK_HEAPHDR_SET_PREV(heap, next, prev);\n\t}\n\tif (prev == NULL) {\n\t\tDUK_ASSERT(hdr == heap->finalize_list);\n\t\theap->finalize_list = next;\n\t} else {\n\t\tDUK_ASSERT(hdr != heap->finalize_list);\n\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, next);\n\t}\n#else\n\tduk_heaphdr *next;\n\tduk_heaphdr *curr;\n\n\t/* Random removal is expensive: we need to locate the previous element\n\t * because we don't have a 'prev' pointer.\n\t */\n\tcurr = heap->finalize_list;\n\tif (curr == hdr) {\n\t\theap->finalize_list = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t} else {\n\t\tDUK_ASSERT(hdr != heap->finalize_list);\n\t\tfor (;;) {\n\t\t\tDUK_ASSERT(curr != NULL);  /* Caller responsibility. */\n\n\t\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\t\tif (next == hdr) {\n\t\t\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t\t\t\tDUK_HEAPHDR_SET_NEXT(heap, curr, next);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n#endif\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL duk_bool_t duk_heap_in_heap_allocated(duk_heap *heap, duk_heaphdr *ptr) {\n\tduk_heaphdr *curr;\n\tDUK_ASSERT(heap != NULL);\n\n\tfor (curr = heap->heap_allocated; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) {\n\t\tif (curr == ptr) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\nDUK_INTERNAL void duk_heap_switch_thread(duk_heap *heap, duk_hthread *new_thr) {\n\tduk_hthread *curr_thr;\n\n\tDUK_ASSERT(heap != NULL);\n\n\tif (new_thr != NULL) {\n\t\tcurr_thr = heap->curr_thread;\n\t\tif (curr_thr == NULL) {\n\t\t\t/* For initial entry use default value; zero forces an\n\t\t\t * interrupt before executing the first insturction.\n\t\t\t */\n\t\t\tDUK_DD(DUK_DDPRINT(\"switch thread, initial entry, init default interrupt counter\"));\n\t\t\tnew_thr->interrupt_counter = 0;\n\t\t\tnew_thr->interrupt_init = 0;\n\t\t} else {\n\t\t\t/* Copy interrupt counter/init value state to new thread (if any).\n\t\t\t * It's OK for new_thr to be the same as curr_thr.\n\t\t\t */\n#if defined(DUK_USE_DEBUG)\n\t\t\tif (new_thr != curr_thr) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"switch thread, not initial entry, copy interrupt counter\"));\n\t\t\t}\n#endif\n\t\t\tnew_thr->interrupt_counter = curr_thr->interrupt_counter;\n\t\t\tnew_thr->interrupt_init = curr_thr->interrupt_init;\n\t\t}\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"switch thread, new thread is NULL, no interrupt counter changes\"));\n\t}\n\n\theap->curr_thread = new_thr;  /* may be NULL */\n}\n#endif  /* DUK_USE_INTERRUPT_COUNTER */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL void duk_heap_assert_valid(duk_heap *heap) {\n\tDUK_ASSERT(heap != NULL);\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_heap_refcount.c",
    "content": "/*\n *  Reference counting implementation.\n *\n *  INCREF/DECREF, finalization and freeing of objects whose refcount reaches\n *  zero (refzero).  These operations are very performance sensitive, so\n *  various small tricks are used in an attempt to maximize speed.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\n#if !defined(DUK_USE_DOUBLE_LINKED_HEAP)\n#error internal error, reference counting requires a double linked heap\n#endif\n\n/*\n *  Heap object refcount finalization.\n *\n *  When an object is about to be freed, all other objects it refers to must\n *  be decref'd.  Refcount finalization does NOT free the object or its inner\n *  allocations (mark-and-sweep shares these helpers), it just manipulates\n *  the refcounts.\n *\n *  Note that any of the DECREFs may cause a refcount to drop to zero.  If so,\n *  the object won't be refzero processed inline, but will just be queued to\n *  refzero_list and processed by an earlier caller working on refzero_list,\n *  eliminating C recursion from even long refzero cascades.  If refzero\n *  finalization is triggered by mark-and-sweep, refzero conditions are ignored\n *  (objects are not even queued to refzero_list) because mark-and-sweep deals\n *  with them; refcounts are still updated so that they remain in sync with\n *  actual references.\n */\n\nDUK_LOCAL void duk__decref_tvals_norz(duk_hthread *thr, duk_tval *tv, duk_idx_t count) {\n\tDUK_ASSERT(count == 0 || tv != NULL);\n\n\twhile (count-- > 0) {\n\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t\ttv++;\n\t}\n}\n\nDUK_INTERNAL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject *h) {\n\tduk_hthread *thr;\n\tduk_uint_fast32_t i;\n\tduk_uint_fast32_t n;\n\tduk_propvalue *p_val;\n\tduk_tval *p_tv;\n\tduk_hstring **p_key;\n\tduk_uint8_t *p_flag;\n\tduk_hobject *h_proto;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(h);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h) == DUK_HTYPE_OBJECT);\n\n\tthr = heap->heap_thread;\n\tDUK_ASSERT(thr != NULL);\n\n\tp_key = DUK_HOBJECT_E_GET_KEY_BASE(heap, h);\n\tp_val = DUK_HOBJECT_E_GET_VALUE_BASE(heap, h);\n\tp_flag = DUK_HOBJECT_E_GET_FLAGS_BASE(heap, h);\n\tn = DUK_HOBJECT_GET_ENEXT(h);\n\twhile (n-- > 0) {\n\t\tduk_hstring *key;\n\n\t\tkey = p_key[n];\n\t\tif (DUK_UNLIKELY(key == NULL)) {\n\t\t\tcontinue;\n\t\t}\n\t\tDUK_HSTRING_DECREF_NORZ(thr, key);\n\t\tif (DUK_UNLIKELY(p_flag[n] & DUK_PROPDESC_FLAG_ACCESSOR)) {\n\t\t\tduk_hobject *h_getset;\n\t\t\th_getset = p_val[n].a.get;\n\t\t\tDUK_ASSERT(h_getset == NULL || DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_getset));\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h_getset);\n\t\t\th_getset = p_val[n].a.set;\n\t\t\tDUK_ASSERT(h_getset == NULL || DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_getset));\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h_getset);\n\t\t} else {\n\t\t\tduk_tval *tv_val;\n\t\t\ttv_val = &p_val[n].v;\n\t\t\tDUK_TVAL_DECREF_NORZ(thr, tv_val);\n\t\t}\n\t}\n\n\tp_tv = DUK_HOBJECT_A_GET_BASE(heap, h);\n\tn = DUK_HOBJECT_GET_ASIZE(h);\n\twhile (n-- > 0) {\n\t\tduk_tval *tv_val;\n\t\ttv_val = p_tv + n;\n\t\tDUK_TVAL_DECREF_NORZ(thr, tv_val);\n\t}\n\n\t/* Hash part is a 'weak reference' and doesn't contribute to refcounts. */\n\n\th_proto = (duk_hobject *) DUK_HOBJECT_GET_PROTOTYPE(heap, h);\n\tDUK_ASSERT(h_proto == NULL || DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_proto));\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h_proto);\n\n\t/* XXX: Object subclass tests are quite awkward at present, ideally\n\t * we should be able to switch-case here with a dense index (subtype\n\t * number or something).  For now, fast path plain objects and arrays\n\t * and bit test the rest individually.\n\t */\n\n\tif (DUK_HOBJECT_HAS_FASTREFS(h)) {\n\t\t/* Plain object or array, nothing more to do.  While a\n\t\t * duk_harray has additional fields, none of them need\n\t\t * DECREF updates.\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_ALLOWS_FASTREFS(h));\n\t\treturn;\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_PROHIBITS_FASTREFS(h));\n\n\t/* Slow path: special object, start bit checks from most likely. */\n\n\t/* XXX: reorg, more common first */\n\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tduk_tval *tv, *tv_end;\n\t\tduk_hobject **funcs, **funcs_end;\n\n\t\tDUK_HCOMPFUNC_ASSERT_VALID(f);\n\n\t\tif (DUK_LIKELY(DUK_HCOMPFUNC_GET_DATA(heap, f) != NULL)) {\n\t\t\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, f);\n\t\t\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(heap, f);\n\t\t\twhile (tv < tv_end) {\n\t\t\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t\t\t\ttv++;\n\t\t\t}\n\n\t\t\tfuncs = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, f);\n\t\t\tfuncs_end = DUK_HCOMPFUNC_GET_FUNCS_END(heap, f);\n\t\t\twhile (funcs < funcs_end) {\n\t\t\t\tduk_hobject *h_func;\n\t\t\t\th_func = *funcs;\n\t\t\t\tDUK_ASSERT(h_func != NULL);\n\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_func));\n\t\t\t\tDUK_HCOMPFUNC_DECREF_NORZ(thr, (duk_hcompfunc *) h_func);\n\t\t\t\tfuncs++;\n\t\t\t}\n\t\t} else {\n\t\t\t/* May happen in some out-of-memory corner cases. */\n\t\t\tDUK_D(DUK_DPRINT(\"duk_hcompfunc 'data' is NULL, skipping decref\"));\n\t\t}\n\n\t\tDUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_heaphdr *) DUK_HCOMPFUNC_GET_LEXENV(heap, f));\n\t\tDUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_heaphdr *) DUK_HCOMPFUNC_GET_VARENV(heap, f));\n\t\tDUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(heap, f));\n\t} else if (DUK_HOBJECT_IS_DECENV(h)) {\n\t\tduk_hdecenv *e = (duk_hdecenv *) h;\n\t\tDUK_HDECENV_ASSERT_VALID(e);\n\t\tDUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr, e->thread);\n\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, e->varmap);\n\t} else if (DUK_HOBJECT_IS_OBJENV(h)) {\n\t\tduk_hobjenv *e = (duk_hobjenv *) h;\n\t\tDUK_HOBJENV_ASSERT_VALID(e);\n\t\tDUK_ASSERT(e->target != NULL);  /* Required for object environments. */\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, e->target);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\tduk_hbufobj *b = (duk_hbufobj *) h;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(b);\n\t\tDUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr, (duk_hbuffer *) b->buf);\n\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) b->buf_prop);\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {\n\t\tduk_hboundfunc *f = (duk_hboundfunc *) (void *) h;\n\t\tDUK_HBOUNDFUNC_ASSERT_VALID(f);\n\t\tDUK_TVAL_DECREF_NORZ(thr, &f->target);\n\t\tDUK_TVAL_DECREF_NORZ(thr, &f->this_binding);\n\t\tduk__decref_tvals_norz(thr, f->args, f->nargs);\n#if defined(DUK_USE_ES6_PROXY)\n\t} else if (DUK_HOBJECT_IS_PROXY(h)) {\n\t\tduk_hproxy *p = (duk_hproxy *) h;\n\t\tDUK_HPROXY_ASSERT_VALID(p);\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, p->target);\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, p->handler);\n#endif  /* DUK_USE_ES6_PROXY */\n\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tduk_activation *act;\n\t\tduk_tval *tv;\n\n\t\tDUK_HTHREAD_ASSERT_VALID(t);\n\n\t\ttv = t->valstack;\n\t\twhile (tv < t->valstack_top) {\n\t\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t\t\ttv++;\n\t\t}\n\n\t\tfor (act = t->callstack_curr; act != NULL; act = act->parent) {\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) DUK_ACT_GET_FUNC(act));\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->var_env);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->lex_env);\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->prev_caller);\n#endif\n#if 0  /* nothing now */\n\t\t\tfor (cat = act->cat; cat != NULL; cat = cat->parent) {\n\t\t\t}\n#endif\n\t\t}\n\n\n\t\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) t->builtins[i]);\n\t\t}\n\n\t\tDUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr, (duk_hthread *) t->resumer);\n\t} else {\n\t\t/* We may come here if the object should have a FASTREFS flag\n\t\t * but it's missing for some reason.  Assert for never getting\n\t\t * here; however, other than performance, this is harmless.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"missing FASTREFS flag for: %!iO\", h));\n\t\tDUK_ASSERT(0);\n\t}\n}\n\nDUK_INTERNAL void duk_heaphdr_refcount_finalize_norz(duk_heap *heap, duk_heaphdr *hdr) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(hdr != NULL);\n\n\tif (DUK_HEAPHDR_IS_OBJECT(hdr)) {\n\t\tduk_hobject_refcount_finalize_norz(heap, (duk_hobject *) hdr);\n\t}\n\t/* DUK_HTYPE_BUFFER: nothing to finalize */\n\t/* DUK_HTYPE_STRING: nothing to finalize */\n}\n\n/*\n *  Refzero processing for duk_hobject: queue a refzero'ed object to either\n *  finalize_list or refzero_list and process the relevent list(s) if\n *  necessary.\n *\n *  Refzero_list is single linked, with only 'prev' pointers set and valid.\n *  All 'next' pointers are intentionally left as garbage.  This doesn't\n *  matter because refzero_list is processed to completion before any other\n *  code (like mark-and-sweep) might walk the list.\n *\n *  In more detail:\n *\n *  - On first insert refzero_list is NULL and the new object becomes the\n *    first and only element on the list; duk__refcount_free_pending() is\n *    called and it starts processing the list from the initial element,\n *    i.e. the list tail.\n *\n *  - As each object is refcount finalized, new objects may be queued to\n *    refzero_list head.  Their 'next' pointers are left as garbage, but\n *    'prev' points are set correctly, with the element at refzero_list\n *    having a NULL 'prev' pointer.  The fact that refzero_list is non-NULL\n *    is used to reject (1) recursive duk__refcount_free_pending() and\n *    (2) finalize_list processing calls.\n *\n *  - When we're done with the current object, read its 'prev' pointer and\n *    free the object.  If 'prev' is NULL, we've reached head of list and are\n *    done: set refzero_list to NULL and process pending finalizers.  Otherwise\n *    continue processing the list.\n *\n *  A refzero cascade is free of side effects because it only involves\n *  queueing more objects and freeing memory; finalizer execution is blocked\n *  in the code path queueing objects to finalize_list.  As a result the\n *  initial refzero call (which triggers duk__refcount_free_pending()) must\n *  check finalize_list so that finalizers are executed snappily.\n *\n *  If finalize_list processing starts first, refzero may occur while we're\n *  processing finalizers.  That's fine: that particular refzero cascade is\n *  handled to completion without side effects.  Once the cascade is complete,\n *  we'll run pending finalizers but notice that we're already doing that and\n *  return.\n *\n *  This could be expanded to allow incremental freeing: just bail out\n *  early and resume at a future alloc/decref/refzero.  However, if that\n *  were done, the list structure would need to be kept consistent at all\n *  times, mark-and-sweep would need to handle refzero_list, etc.\n */\n\nDUK_LOCAL void duk__refcount_free_pending(duk_heap *heap) {\n\tduk_heaphdr *curr;\n#if defined(DUK_USE_DEBUG)\n\tduk_int_t count = 0;\n#endif\n\n\tDUK_ASSERT(heap != NULL);\n\n\tcurr = heap->refzero_list;\n\tDUK_ASSERT(curr != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, curr) == NULL);  /* We're called on initial insert only. */\n\t/* curr->next is GARBAGE. */\n\n\tdo {\n\t\tduk_heaphdr *prev;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"refzero processing %p: %!O\", (void *) curr, (duk_heaphdr *) curr));\n\n#if defined(DUK_USE_DEBUG)\n\t\tcount++;\n#endif\n\n\t\tDUK_ASSERT(curr != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);  /* currently, always the case */\n\t\t/* FINALIZED may be set; don't care about flags here. */\n\n\t\t/* Refcount finalize 'curr'.  Refzero_list must be non-NULL\n\t\t * here to prevent recursive entry to duk__refcount_free_pending().\n\t\t */\n\t\tDUK_ASSERT(heap->refzero_list != NULL);\n\t\tduk_hobject_refcount_finalize_norz(heap, (duk_hobject *) curr);\n\n\t\tprev = DUK_HEAPHDR_GET_PREV(heap, curr);\n\t\tDUK_ASSERT((prev == NULL && heap->refzero_list == curr) || \\\n\t\t           (prev != NULL && heap->refzero_list != curr));\n\t\t/* prev->next is intentionally not updated and is garbage. */\n\n\t\tduk_free_hobject(heap, (duk_hobject *) curr);  /* Invalidates 'curr'. */\n\n\t\tcurr = prev;\n\t} while (curr != NULL);\n\n\theap->refzero_list = NULL;\n\n\tDUK_DD(DUK_DDPRINT(\"refzero processed %ld objects\", (long) count));\n}\n\nDUK_LOCAL DUK_INLINE void duk__refcount_refzero_hobject(duk_heap *heap, duk_hobject *obj, duk_bool_t skip_free_pending) {\n\tduk_heaphdr *hdr;\n\tduk_heaphdr *root;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) obj) == DUK_HTYPE_OBJECT);\n\n\thdr = (duk_heaphdr *) obj;\n\n\t/* Refzero'd objects must be in heap_allocated.  They can't be in\n\t * finalize_list because all objects on finalize_list have an\n\t * artificial +1 refcount bump.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(duk_heap_in_heap_allocated(heap, (duk_heaphdr *) obj));\n#endif\n\n\tDUK_HEAP_REMOVE_FROM_HEAP_ALLOCATED(heap, hdr);\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t/* This finalizer check MUST BE side effect free.  It should also be\n\t * as fast as possible because it's applied to every object freed.\n\t */\n\tif (DUK_UNLIKELY(DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) hdr) != 0U)) {\n\t\t/* Special case: FINALIZED may be set if mark-and-sweep queued\n\t\t * object for finalization, the finalizer was executed (and\n\t\t * FINALIZED set), mark-and-sweep hasn't yet processed the\n\t\t * object again, but its refcount drops to zero.  Free without\n\t\t * running the finalizer again.\n\t\t */\n\t\tif (DUK_HEAPHDR_HAS_FINALIZED(hdr)) {\n\t\t\tDUK_D(DUK_DPRINT(\"refzero'd object has finalizer and FINALIZED is set -> free\"));\n\t\t} else {\n\t\t\t/* Set FINALIZABLE flag so that all objects on finalize_list\n\t\t\t * will have it set and are thus detectable based on the\n\t\t\t * flag alone.\n\t\t\t */\n\t\t\tDUK_HEAPHDR_SET_FINALIZABLE(hdr);\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(hdr));\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t/* Bump refcount on finalize_list insert so that a\n\t\t\t * refzero can never occur when an object is waiting\n\t\t\t * for its finalizer call.  Refzero might otherwise\n\t\t\t * now happen because we allow duk_push_heapptr() for\n\t\t\t * objects pending finalization.\n\t\t\t */\n\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(hdr);\n#endif\n\t\t\tDUK_HEAP_INSERT_INTO_FINALIZE_LIST(heap, hdr);\n\n\t\t\t/* Process finalizers unless skipping is explicitly\n\t\t\t * requested (NORZ) or refzero_list is being processed\n\t\t\t * (avoids side effects during a refzero cascade).\n\t\t\t * If refzero_list is processed, the initial refzero\n\t\t\t * call will run pending finalizers when refzero_list\n\t\t\t * is done.\n\t\t\t */\n\t\t\tif (!skip_free_pending && heap->refzero_list == NULL) {\n\t\t\t\tduk_heap_process_finalize_list(heap);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n\t/* No need to finalize, free object via refzero_list. */\n\n\troot = heap->refzero_list;\n\n\tDUK_HEAPHDR_SET_PREV(heap, hdr, NULL);\n\t/* 'next' is left as GARBAGE. */\n\theap->refzero_list = hdr;\n\n\tif (root == NULL) {\n\t\t/* Object is now queued.  Refzero_list was NULL so\n\t\t * no-one is currently processing it; do it here.\n\t\t * With refzero processing just doing a cascade of\n\t\t * free calls, we can process it directly even when\n\t\t * NORZ macros are used: there are no side effects.\n\t\t */\n\t\tduk__refcount_free_pending(heap);\n\t\tDUK_ASSERT(heap->refzero_list == NULL);\n\n\t\t/* Process finalizers only after the entire cascade\n\t\t * is finished.  In most cases there's nothing to\n\t\t * finalize, so fast path check to avoid a call.\n\t\t */\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\tif (!skip_free_pending && DUK_UNLIKELY(heap->finalize_list != NULL)) {\n\t\t\tduk_heap_process_finalize_list(heap);\n\t\t}\n#endif\n\t} else {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, root) == NULL);\n\t\tDUK_HEAPHDR_SET_PREV(heap, root, hdr);\n\n\t\t/* Object is now queued.  Because refzero_list was\n\t\t * non-NULL, it's already being processed by someone\n\t\t * in the C call stack, so we're done.\n\t\t */\n\t}\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_refzero_check_fast(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->heap->refzero_list == NULL);  /* Processed to completion inline. */\n\n\tif (DUK_UNLIKELY(thr->heap->finalize_list != NULL)) {\n\t\tduk_heap_process_finalize_list(thr->heap);\n\t}\n}\n\nDUK_INTERNAL void duk_refzero_check_slow(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->heap->refzero_list == NULL);  /* Processed to completion inline. */\n\n\tif (DUK_UNLIKELY(thr->heap->finalize_list != NULL)) {\n\t\tduk_heap_process_finalize_list(thr->heap);\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Refzero processing for duk_hstring.\n */\n\nDUK_LOCAL DUK_INLINE void duk__refcount_refzero_hstring(duk_heap *heap, duk_hstring *str) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(str != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) str) == DUK_HTYPE_STRING);\n\n\tduk_heap_strcache_string_remove(heap, str);\n\tduk_heap_strtable_unlink(heap, str);\n\tduk_free_hstring(heap, str);\n}\n\n/*\n *  Refzero processing for duk_hbuffer.\n */\n\nDUK_LOCAL DUK_INLINE void duk__refcount_refzero_hbuffer(duk_heap *heap, duk_hbuffer *buf) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) buf) == DUK_HTYPE_BUFFER);\n\n\tDUK_HEAP_REMOVE_FROM_HEAP_ALLOCATED(heap, (duk_heaphdr *) buf);\n\tduk_free_hbuffer(heap, buf);\n}\n\n/*\n *  Incref and decref functions.\n *\n *  Decref may trigger immediate refzero handling, which may free and finalize\n *  an arbitrary number of objects (a \"DECREF cascade\").\n *\n *  Refzero handling is skipped entirely if (1) mark-and-sweep is running or\n *  (2) execution is paused in the debugger.  The objects are left in the heap,\n *  and will be freed by mark-and-sweep or eventual heap destruction.\n *\n *  This is necessary during mark-and-sweep because refcounts are also updated\n *  during the sweep phase (otherwise objects referenced by a swept object\n *  would have incorrect refcounts) which then calls here.  This could be\n *  avoided by using separate decref macros in mark-and-sweep; however,\n *  mark-and-sweep also calls finalizers which would use the ordinary decref\n *  macros anyway.\n *\n *  We can't process refzeros (= free objects) when the debugger is running\n *  as the debugger might make an object unreachable but still continue\n *  inspecting it (or even cause it to be pushed back).  So we must rely on\n *  mark-and-sweep to collect them.\n *\n *  The DUK__RZ_SUPPRESS_CHECK() condition is also used in heap destruction\n *  when running finalizers for remaining objects: the flag prevents objects\n *  from being moved around in heap linked lists while that's being done.\n *\n *  The suppress condition is important to performance.\n */\n\n#define DUK__RZ_SUPPRESS_ASSERT1() do { \\\n\t\tDUK_ASSERT(thr != NULL); \\\n\t\tDUK_ASSERT(thr->heap != NULL); \\\n\t\t/* When mark-and-sweep runs, heap_thread must exist. */ \\\n\t\tDUK_ASSERT(thr->heap->ms_running == 0 || thr->heap->heap_thread != NULL); \\\n\t\t/* In normal operation finalizers are executed with ms_running == 0 \\\n\t\t * so we should never see ms_running == 1 and thr != heap_thread. \\\n\t\t * In heap destruction finalizers are executed with ms_running != 0 \\\n\t\t * to e.g. prevent refzero; a special value ms_running == 2 is used \\\n\t\t * in that case so it can be distinguished from the normal runtime \\\n\t\t * case, and allows a stronger assertion here (GH-2030). \\\n\t\t */ \\\n\t\tDUK_ASSERT(!(thr->heap->ms_running == 1 && thr != thr->heap->heap_thread)); \\\n\t\t/* We may be called when the heap is initializing and we process \\\n\t\t * refzeros normally, but mark-and-sweep and finalizers are prevented \\\n\t\t * if that's the case. \\\n\t\t */ \\\n\t\tDUK_ASSERT(thr->heap->heap_initializing == 0 || thr->heap->ms_prevent_count > 0); \\\n\t\tDUK_ASSERT(thr->heap->heap_initializing == 0 || thr->heap->pf_prevent_count > 0); \\\n\t} while (0)\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n#define DUK__RZ_SUPPRESS_ASSERT2() do { \\\n\t\t/* When debugger is paused, ms_running is set. */ \\\n\t\tDUK_ASSERT(!DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || thr->heap->ms_running != 0); \\\n\t} while (0)\n#define DUK__RZ_SUPPRESS_COND()  (heap->ms_running != 0)\n#else\n#define DUK__RZ_SUPPRESS_ASSERT2() do { } while (0)\n#define DUK__RZ_SUPPRESS_COND()  (heap->ms_running != 0)\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n#define DUK__RZ_SUPPRESS_CHECK() do { \\\n\t\tDUK__RZ_SUPPRESS_ASSERT1(); \\\n\t\tDUK__RZ_SUPPRESS_ASSERT2(); \\\n\t\tif (DUK_UNLIKELY(DUK__RZ_SUPPRESS_COND())) { \\\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"refzero handling suppressed (not even queued) when mark-and-sweep running, object: %p\", (void *) h)); \\\n\t\t\treturn; \\\n\t\t} \\\n\t} while (0)\n\n#define DUK__RZ_STRING() do { \\\n\t\tduk__refcount_refzero_hstring(heap, (duk_hstring *) h); \\\n\t} while (0)\n#define DUK__RZ_BUFFER() do { \\\n\t\tduk__refcount_refzero_hbuffer(heap, (duk_hbuffer *) h); \\\n\t} while (0)\n#define DUK__RZ_OBJECT() do { \\\n\t\tduk__refcount_refzero_hobject(heap, (duk_hobject *) h, skip_free_pending); \\\n\t} while (0)\n\n/* XXX: test the effect of inlining here vs. NOINLINE in refzero helpers */\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n#define DUK__RZ_INLINE DUK_ALWAYS_INLINE\n#else\n#define DUK__RZ_INLINE /*nop*/\n#endif\n\nDUK_LOCAL DUK__RZ_INLINE void duk__hstring_refzero_helper(duk_hthread *thr, duk_hstring *h) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\tDUK__RZ_SUPPRESS_CHECK();\n\tDUK__RZ_STRING();\n}\n\nDUK_LOCAL DUK__RZ_INLINE void duk__hbuffer_refzero_helper(duk_hthread *thr, duk_hbuffer *h) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\tDUK__RZ_SUPPRESS_CHECK();\n\tDUK__RZ_BUFFER();\n}\n\nDUK_LOCAL DUK__RZ_INLINE void duk__hobject_refzero_helper(duk_hthread *thr, duk_hobject *h, duk_bool_t skip_free_pending) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\tDUK__RZ_SUPPRESS_CHECK();\n\tDUK__RZ_OBJECT();\n}\n\nDUK_LOCAL DUK__RZ_INLINE void duk__heaphdr_refzero_helper(duk_hthread *thr, duk_heaphdr *h, duk_bool_t skip_free_pending) {\n\tduk_heap *heap;\n\tduk_small_uint_t htype;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\thtype = (duk_small_uint_t) DUK_HEAPHDR_GET_TYPE(h);\n\tDUK_DDD(DUK_DDDPRINT(\"ms_running=%ld, heap_thread=%p\", (long) thr->heap->ms_running, thr->heap->heap_thread));\n\tDUK__RZ_SUPPRESS_CHECK();\n\n\tswitch (htype) {\n\tcase DUK_HTYPE_STRING:\n\t\t/* Strings have no internal references but do have \"weak\"\n\t\t * references in the string cache.  Also note that strings\n\t\t * are not on the heap_allocated list like other heap\n\t\t * elements.\n\t\t */\n\n\t\tDUK__RZ_STRING();\n\t\tbreak;\n\n\tcase DUK_HTYPE_OBJECT:\n\t\t/* Objects have internal references.  Must finalize through\n\t\t * the \"refzero\" work list.\n\t\t */\n\n\t\tDUK__RZ_OBJECT();\n\t\tbreak;\n\n\tdefault:\n\t\t/* Buffers have no internal references.  However, a dynamic\n\t\t * buffer has a separate allocation for the buffer.  This is\n\t\t * freed by duk_heap_free_heaphdr_raw().\n\t\t */\n\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(h) == DUK_HTYPE_BUFFER);\n\t\tDUK__RZ_BUFFER();\n\t\tbreak;\n\t}\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h) {\n\tduk__heaphdr_refzero_helper(thr, h, 0 /*skip_free_pending*/);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_heaphdr_refzero_norz(duk_hthread *thr, duk_heaphdr *h) {\n\tduk__heaphdr_refzero_helper(thr, h, 1 /*skip_free_pending*/);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hstring_refzero(duk_hthread *thr, duk_hstring *h) {\n\tduk__hstring_refzero_helper(thr, h);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hbuffer_refzero(duk_hthread *thr, duk_hbuffer *h) {\n\tduk__hbuffer_refzero_helper(thr, h);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hobject_refzero(duk_hthread *thr, duk_hobject *h) {\n\tduk__hobject_refzero_helper(thr, h, 0 /*skip_free_pending*/);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hobject_refzero_norz(duk_hthread *thr, duk_hobject *h) {\n\tduk__hobject_refzero_helper(thr, h, 1 /*skip_free_pending*/);\n}\n\n#if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\nDUK_INTERNAL void duk_tval_incref(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\t\tDUK_ASSERT_DISABLE(h->h_refcount >= 0);\n\t\tDUK_HEAPHDR_PREINC_REFCOUNT(h);\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) != 0);  /* No wrapping. */\n\t}\n}\n\nDUK_INTERNAL void duk_tval_decref(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) >= 1);\n#if 0\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(h) != 0) {\n\t\t\treturn;\n\t\t}\n\t\tduk_heaphdr_refzero(thr, h);\n#else\n\t\tduk_heaphdr_decref(thr, h);\n#endif\n\t}\n}\n\nDUK_INTERNAL void duk_tval_decref_norz(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) >= 1);\n#if 0\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(h) != 0) {\n\t\t\treturn;\n\t\t}\n\t\tduk_heaphdr_refzero_norz(thr, h);\n#else\n\t\tduk_heaphdr_decref_norz(thr, h);\n#endif\n\t}\n}\n#endif  /* !DUK_USE_FAST_REFCOUNT_DEFAULT */\n\n#define DUK__DECREF_ASSERTS() do { \\\n\t\tDUK_ASSERT(thr != NULL); \\\n\t\tDUK_ASSERT(thr->heap != NULL); \\\n\t\tDUK_ASSERT(h != NULL); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID((duk_heaphdr *) h)); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) >= 1); \\\n\t} while (0)\n#if defined(DUK_USE_ROM_OBJECTS)\n#define DUK__INCREF_SHARED() do { \\\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t\tDUK_HEAPHDR_PREINC_REFCOUNT((duk_heaphdr *) h); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) != 0);  /* No wrapping. */ \\\n\t} while (0)\n#define DUK__DECREF_SHARED() do { \\\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT((duk_heaphdr *) h) != 0) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t} while (0)\n#else\n#define DUK__INCREF_SHARED() do { \\\n\t\tDUK_HEAPHDR_PREINC_REFCOUNT((duk_heaphdr *) h); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) != 0);  /* No wrapping. */ \\\n\t} while (0)\n#define DUK__DECREF_SHARED() do { \\\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT((duk_heaphdr *) h) != 0) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t} while (0)\n#endif\n\n#if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n/* This will in practice be inlined because it's just an INC instructions\n * and a bit test + INC when ROM objects are enabled.\n */\nDUK_INTERNAL void duk_heaphdr_incref(duk_heaphdr *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\tDUK_ASSERT_DISABLE(DUK_HEAPHDR_GET_REFCOUNT(h) >= 0);\n\n\tDUK__INCREF_SHARED();\n}\n\nDUK_INTERNAL void duk_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_heaphdr_refzero(thr, h);\n\n\t/* Forced mark-and-sweep when GC torture enabled; this could happen\n\t * on any DECREF (but not DECREF_NORZ).\n\t */\n\tDUK_GC_TORTURE(thr->heap);\n}\nDUK_INTERNAL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_heaphdr_refzero_norz(thr, h);\n}\n#endif  /* !DUK_USE_FAST_REFCOUNT_DEFAULT */\n\n#if 0  /* Not needed. */\nDUK_INTERNAL void duk_hstring_decref(duk_hthread *thr, duk_hstring *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hstring_refzero(thr, h);\n}\nDUK_INTERNAL void duk_hstring_decref_norz(duk_hthread *thr, duk_hstring *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hstring_refzero_norz(thr, h);\n}\nDUK_INTERNAL void duk_hbuffer_decref(duk_hthread *thr, duk_hbuffer *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hbuffer_refzero(thr, h);\n}\nDUK_INTERNAL void duk_hbuffer_decref_norz(duk_hthread *thr, duk_hbuffer *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hbuffer_refzero_norz(thr, h);\n}\nDUK_INTERNAL void duk_hobject_decref(duk_hthread *thr, duk_hobject *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hobject_refzero(thr, h);\n}\nDUK_INTERNAL void duk_hobject_decref_norz(duk_hthread *thr, duk_hobject *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hobject_refzero_norz(thr, h);\n}\n#endif\n\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\n/* no refcounting */\n\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_heap_stringcache.c",
    "content": "/*\n *  String cache.\n *\n *  Provides a cache to optimize indexed string lookups.  The cache keeps\n *  track of (byte offset, char offset) states for a fixed number of strings.\n *  Otherwise we'd need to scan from either end of the string, as we store\n *  strings in (extended) UTF-8.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Delete references to given hstring from the heap string cache.\n *\n *  String cache references are 'weak': they are not counted towards\n *  reference counts, nor serve as roots for mark-and-sweep.  When an\n *  object is about to be freed, such references need to be removed.\n */\n\nDUK_INTERNAL void duk_heap_strcache_string_remove(duk_heap *heap, duk_hstring *h) {\n\tduk_uint_t i;\n\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\tduk_strcache_entry *c = heap->strcache + i;\n\t\tif (c->h == h) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"deleting weak strcache reference to hstring %p from heap %p\",\n\t\t\t                   (void *) h, (void *) heap));\n\t\t\tc->h = NULL;\n\n\t\t\t/* XXX: the string shouldn't appear twice, but we now loop to the\n\t\t\t * end anyway; if fixed, add a looping assertion to ensure there\n\t\t\t * is no duplicate.\n\t\t\t */\n\t\t}\n\t}\n}\n\n/*\n *  String scanning helpers\n *\n *  All bytes other than UTF-8 continuation bytes ([0x80,0xbf]) are\n *  considered to contribute a character.  This must match how string\n *  character length is computed.\n */\n\nDUK_LOCAL const duk_uint8_t *duk__scan_forwards(const duk_uint8_t *p, const duk_uint8_t *q, duk_uint_fast32_t n) {\n\twhile (n > 0) {\n\t\tfor (;;) {\n\t\t\tp++;\n\t\t\tif (p >= q) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\tif ((*p & 0xc0) != 0x80) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tn--;\n\t}\n\treturn p;\n}\n\nDUK_LOCAL const duk_uint8_t *duk__scan_backwards(const duk_uint8_t *p, const duk_uint8_t *q, duk_uint_fast32_t n) {\n\twhile (n > 0) {\n\t\tfor (;;) {\n\t\t\tp--;\n\t\t\tif (p < q) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\tif ((*p & 0xc0) != 0x80) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tn--;\n\t}\n\treturn p;\n}\n\n/*\n *  Convert char offset to byte offset\n *\n *  Avoid using the string cache if possible: for ASCII strings byte and\n *  char offsets are equal and for short strings direct scanning may be\n *  better than using the string cache (which may evict a more important\n *  entry).\n *\n *  Typing now assumes 32-bit string byte/char offsets (duk_uint_fast32_t).\n *  Better typing might be to use duk_size_t.\n *\n *  Caller should ensure 'char_offset' is within the string bounds [0,charlen]\n *  (endpoint is inclusive).  If this is not the case, no memory unsafe\n *  behavior will happen but an error will be thrown.\n */\n\nDUK_INTERNAL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *thr, duk_hstring *h, duk_uint_fast32_t char_offset) {\n\tduk_heap *heap;\n\tduk_strcache_entry *sce;\n\tduk_uint_fast32_t byte_offset;\n\tduk_uint_t i;\n\tduk_bool_t use_cache;\n\tduk_uint_fast32_t dist_start, dist_end, dist_sce;\n\tduk_uint_fast32_t char_length;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint8_t *p_found;\n\n\t/*\n\t *  For ASCII strings, the answer is simple.\n\t */\n\n\tif (DUK_LIKELY(DUK_HSTRING_IS_ASCII(h))) {\n\t\treturn char_offset;\n\t}\n\n\tchar_length = (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h);\n\tDUK_ASSERT(char_offset <= char_length);\n\n\tif (DUK_LIKELY(DUK_HSTRING_IS_ASCII(h))) {\n\t\t/* Must recheck because the 'is ascii' flag may be set\n\t\t * lazily.  Alternatively, we could just compare charlen\n\t\t * to bytelen.\n\t\t */\n\t\treturn char_offset;\n\t}\n\n\t/*\n\t *  For non-ASCII strings, we need to scan forwards or backwards\n\t *  from some starting point.  The starting point may be the start\n\t *  or end of the string, or some cached midpoint in the string\n\t *  cache.\n\t *\n\t *  For \"short\" strings we simply scan without checking or updating\n\t *  the cache.  For longer strings we check and update the cache as\n\t *  necessary, inserting a new cache entry if none exists.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string %p, char_offset=%ld, clen=%ld, blen=%ld\",\n\t                     (void *) h, (long) char_offset,\n\t                     (long) DUK_HSTRING_GET_CHARLEN(h),\n\t                     (long) DUK_HSTRING_GET_BYTELEN(h)));\n\n\theap = thr->heap;\n\tsce = NULL;\n\tuse_cache = (char_length > DUK_HEAP_STRINGCACHE_NOCACHE_LIMIT);\n\n\tif (use_cache) {\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t\tDUK_DDD(DUK_DDDPRINT(\"stringcache before char2byte (using cache):\"));\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tduk_strcache_entry *c = heap->strcache + i;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"  [%ld] -> h=%p, cidx=%ld, bidx=%ld\",\n\t\t\t                     (long) i, (void *) c->h, (long) c->cidx, (long) c->bidx));\n\t\t}\n#endif\n\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tduk_strcache_entry *c = heap->strcache + i;\n\n\t\t\tif (c->h == h) {\n\t\t\t\tsce = c;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t/*\n\t *  Scan from shortest distance:\n\t *    - start of string\n\t *    - end of string\n\t *    - cache entry (if exists)\n\t */\n\n\tDUK_ASSERT(DUK_HSTRING_GET_CHARLEN(h) >= char_offset);\n\tdist_start = char_offset;\n\tdist_end = char_length - char_offset;\n\tdist_sce = 0; DUK_UNREF(dist_sce);  /* initialize for debug prints, needed if sce==NULL */\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tp_end = (const duk_uint8_t *) (p_start + DUK_HSTRING_GET_BYTELEN(h));\n\tp_found = NULL;\n\n\tif (sce) {\n\t\tif (char_offset >= sce->cidx) {\n\t\t\tdist_sce = char_offset - sce->cidx;\n\t\t\tif ((dist_sce <= dist_start) && (dist_sce <= dist_end)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t\t\t                     \"scan forwards from sce\",\n\t\t\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\t\t\tp_found = duk__scan_forwards(p_start + sce->bidx,\n\t\t\t\t                             p_end,\n\t\t\t\t                             dist_sce);\n\t\t\t\tgoto scan_done;\n\t\t\t}\n\t\t} else {\n\t\t\tdist_sce = sce->cidx - char_offset;\n\t\t\tif ((dist_sce <= dist_start) && (dist_sce <= dist_end)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t\t\t                     \"scan backwards from sce\",\n\t\t\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\t\t\tp_found = duk__scan_backwards(p_start + sce->bidx,\n\t\t\t\t                              p_start,\n\t\t\t\t                              dist_sce);\n\t\t\t\tgoto scan_done;\n\t\t\t}\n\t\t}\n\t}\n\n\t/* no sce, or sce scan not best */\n\n\tif (dist_start <= dist_end) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t                     \"scan forwards from string start\",\n\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\tp_found = duk__scan_forwards(p_start,\n\t\t                             p_end,\n\t\t                             dist_start);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t                     \"scan backwards from string end\",\n\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\tp_found = duk__scan_backwards(p_end,\n\t\t                              p_start,\n\t\t                              dist_end);\n\t}\n\n scan_done:\n\n\tif (DUK_UNLIKELY(p_found == NULL)) {\n\t\t/* Scan error: this shouldn't normally happen; it could happen if\n\t\t * string is not valid UTF-8 data, and clen/blen are not consistent\n\t\t * with the scanning algorithm.\n\t\t */\n\t\tgoto scan_error;\n\t}\n\n\tDUK_ASSERT(p_found >= p_start);\n\tDUK_ASSERT(p_found <= p_end);  /* may be equal */\n\tbyte_offset = (duk_uint32_t) (p_found - p_start);\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> string %p, cidx %ld -> bidx %ld\",\n\t                     (void *) h, (long) char_offset, (long) byte_offset));\n\n\t/*\n\t *  Update cache entry (allocating if necessary), and move the\n\t *  cache entry to the first place (in an \"LRU\" policy).\n\t */\n\n\tif (use_cache) {\n\t\t/* update entry, allocating if necessary */\n\t\tif (!sce) {\n\t\t\tsce = heap->strcache + DUK_HEAP_STRCACHE_SIZE - 1;  /* take last entry */\n\t\t\tsce->h = h;\n\t\t}\n\t\tDUK_ASSERT(sce != NULL);\n\t\tsce->bidx = (duk_uint32_t) (p_found - p_start);\n\t\tsce->cidx = (duk_uint32_t) char_offset;\n\n\t\t/* LRU: move our entry to first */\n\t\tif (sce > &heap->strcache[0]) {\n\t\t\t/*\n\t\t\t *   A                  C\n\t\t\t *   B                  A\n\t\t\t *   C <- sce    ==>    B\n\t\t\t *   D                  D\n\t\t\t */\n\t\t\tduk_strcache_entry tmp;\n\n\t\t\ttmp = *sce;\n\t\t\tduk_memmove((void *) (&heap->strcache[1]),\n\t\t\t            (const void *) (&heap->strcache[0]),\n\t\t\t            (size_t) (((char *) sce) - ((char *) &heap->strcache[0])));\n\t\t\theap->strcache[0] = tmp;\n\n\t\t\t/* 'sce' points to the wrong entry here, but is no longer used */\n\t\t}\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t\tDUK_DDD(DUK_DDDPRINT(\"stringcache after char2byte (using cache):\"));\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tduk_strcache_entry *c = heap->strcache + i;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"  [%ld] -> h=%p, cidx=%ld, bidx=%ld\",\n\t\t\t                     (long) i, (void *) c->h, (long) c->cidx, (long) c->bidx));\n\t\t}\n#endif\n\t}\n\n\treturn byte_offset;\n\n scan_error:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_heap_stringtable.c",
    "content": "/*\n *  Heap string table handling, string interning.\n */\n\n#include \"duk_internal.h\"\n\n/* Resize checks not needed if minsize == maxsize, typical for low memory\n * targets.\n */\n#define DUK__STRTAB_RESIZE_CHECK\n#if (DUK_USE_STRTAB_MINSIZE == DUK_USE_STRTAB_MAXSIZE)\n#undef DUK__STRTAB_RESIZE_CHECK\n#endif\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n#define DUK__HEAPPTR_ENC16(heap,ptr)    DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (ptr))\n#define DUK__HEAPPTR_DEC16(heap,val)    DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (val))\n#define DUK__GET_STRTABLE(heap)         ((heap)->strtable16)\n#else\n#define DUK__HEAPPTR_ENC16(heap,ptr)    (ptr)\n#define DUK__HEAPPTR_DEC16(heap,val)    (val)\n#define DUK__GET_STRTABLE(heap)         ((heap)->strtable)\n#endif\n\n#define DUK__STRTAB_U32_MAX_STRLEN      10               /* 4'294'967'295 */\n\n/*\n *  Debug dump stringtable.\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_INTERNAL void duk_heap_strtable_dump(duk_heap *heap) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable;\n#else\n\tduk_hstring **strtable;\n#endif\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_size_t count_total = 0;\n\tduk_size_t count_chain;\n\tduk_size_t count_chain_min = DUK_SIZE_MAX;\n\tduk_size_t count_chain_max = 0;\n\tduk_size_t count_len[8];  /* chain lengths from 0 to 7 */\n\n\tif (heap == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"string table, heap=NULL\"));\n\t\treturn;\n\t}\n\n\tstrtable = DUK__GET_STRTABLE(heap);\n\tif (strtable == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"string table, strtab=NULL\"));\n\t\treturn;\n\t}\n\n\tduk_memzero((void *) count_len, sizeof(count_len));\n\tfor (i = 0; i < heap->st_size; i++) {\n\t\th = DUK__HEAPPTR_DEC16(heap, strtable[i]);\n\t\tcount_chain = 0;\n\t\twhile (h != NULL) {\n\t\t\tcount_chain++;\n\t\t\th = h->hdr.h_next;\n\t\t}\n\t\tif (count_chain < sizeof(count_len) / sizeof(duk_size_t)) {\n\t\t\tcount_len[count_chain]++;\n\t\t}\n\t\tcount_chain_max = (count_chain > count_chain_max ? count_chain : count_chain_max);\n\t\tcount_chain_min = (count_chain < count_chain_min ? count_chain : count_chain_min);\n\t\tcount_total += count_chain;\n\t}\n\n\tDUK_D(DUK_DPRINT(\"string table, strtab=%p, count=%lu, chain min=%lu max=%lu avg=%lf: \"\n\t                 \"counts: %lu %lu %lu %lu %lu %lu %lu %lu ...\",\n\t                 (void *) heap->strtable, (unsigned long) count_total,\n\t                 (unsigned long) count_chain_min, (unsigned long) count_chain_max,\n\t                 (double) count_total / (double) heap->st_size,\n\t                 (unsigned long) count_len[0], (unsigned long) count_len[1],\n\t                 (unsigned long) count_len[2], (unsigned long) count_len[3],\n\t                 (unsigned long) count_len[4], (unsigned long) count_len[5],\n\t                 (unsigned long) count_len[6], (unsigned long) count_len[7]));\n}\n#endif  /* DUK_USE_DEBUG */\n\n/*\n *  Assertion helper to ensure strtable is populated correctly.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_LOCAL void duk__strtable_assert_checks(duk_heap *heap) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable;\n#else\n\tduk_hstring **strtable;\n#endif\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_size_t count = 0;\n\n\tDUK_ASSERT(heap != NULL);\n\n\tstrtable = DUK__GET_STRTABLE(heap);\n\tif (strtable != NULL) {\n\t\tDUK_ASSERT(heap->st_size != 0);\n\t\tDUK_ASSERT(heap->st_mask == heap->st_size - 1);\n\n\t\tfor (i = 0; i < heap->st_size; i++) {\n\t\t\th = DUK__HEAPPTR_DEC16(heap, strtable[i]);\n\t\t\twhile (h != NULL) {\n\t\t\t\tDUK_ASSERT((DUK_HSTRING_GET_HASH(h) & heap->st_mask) == i);\n\t\t\t\tcount++;\n\t\t\t\th = h->hdr.h_next;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_ASSERT(heap->st_size == 0);\n\t\tDUK_ASSERT(heap->st_mask == 0);\n\t}\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tDUK_ASSERT(count == (duk_size_t) heap->st_count);\n#endif\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\n/*\n *  Allocate and initialize a duk_hstring.\n *\n *  Returns a NULL if allocation or initialization fails for some reason.\n *\n *  The string won't be inserted into the string table and isn't tracked in\n *  any way (link pointers will be NULL).  The caller must place the string\n *  into the string table without any risk of a longjmp, otherwise the string\n *  is leaked.\n */\n\nDUK_LOCAL duk_hstring *duk__strtable_alloc_hstring(duk_heap *heap,\n                                                   const duk_uint8_t *str,\n                                                   duk_uint32_t blen,\n                                                   duk_uint32_t strhash,\n                                                   const duk_uint8_t *extdata) {\n\tduk_hstring *res;\n\tconst duk_uint8_t *data;\n#if !defined(DUK_USE_HSTRING_ARRIDX)\n\tduk_uarridx_t dummy;\n#endif\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_UNREF(extdata);\n\n#if defined(DUK_USE_STRLEN16)\n\t/* If blen <= 0xffffUL, clen is also guaranteed to be <= 0xffffUL. */\n\tif (blen > 0xffffUL) {\n\t\tDUK_D(DUK_DPRINT(\"16-bit string blen/clen active and blen over 16 bits, reject intern\"));\n\t\tgoto alloc_error;\n\t}\n#endif\n\n\t/* XXX: Memzeroing the allocated structure is not really necessary\n\t * because we could just initialize all fields explicitly (almost\n\t * all fields are initialized explicitly anyway).\n\t */\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK)\n\tif (extdata) {\n\t\tres = (duk_hstring *) DUK_ALLOC(heap, sizeof(duk_hstring_external));\n\t\tif (DUK_UNLIKELY(res == NULL)) {\n\t\t\tgoto alloc_error;\n\t\t}\n\t\tduk_memzero(res, sizeof(duk_hstring_external));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\tDUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr);\n#endif\n\t\tDUK_HEAPHDR_SET_TYPE_AND_FLAGS(&res->hdr, DUK_HTYPE_STRING, DUK_HSTRING_FLAG_EXTDATA);\n\n\t\tDUK_ASSERT(extdata[blen] == 0);  /* Application responsibility. */\n\t\tdata = extdata;\n\t\t((duk_hstring_external *) res)->extdata = extdata;\n\t} else\n#endif  /* DUK_USE_HSTRING_EXTDATA && DUK_USE_EXTSTR_INTERN_CHECK */\n\t{\n\t\tduk_uint8_t *data_tmp;\n\n\t\t/* NUL terminate for convenient C access */\n\t\tDUK_ASSERT(sizeof(duk_hstring) + blen + 1 > blen);  /* No wrap, limits ensure. */\n\t\tres = (duk_hstring *) DUK_ALLOC(heap, sizeof(duk_hstring) + blen + 1);\n\t\tif (DUK_UNLIKELY(res == NULL)) {\n\t\t\tgoto alloc_error;\n\t\t}\n\t\tduk_memzero(res, sizeof(duk_hstring));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\tDUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr);\n#endif\n\t\tDUK_HEAPHDR_SET_TYPE_AND_FLAGS(&res->hdr, DUK_HTYPE_STRING, 0);\n\n\t\tdata_tmp = (duk_uint8_t *) (res + 1);\n\t\tduk_memcpy(data_tmp, str, blen);\n\t\tdata_tmp[blen] = (duk_uint8_t) 0;\n\t\tdata = (const duk_uint8_t *) data_tmp;\n\t}\n\n\tDUK_HSTRING_SET_BYTELEN(res, blen);\n\tDUK_HSTRING_SET_HASH(res, strhash);\n\n\tDUK_ASSERT(!DUK_HSTRING_HAS_ARRIDX(res));\n#if defined(DUK_USE_HSTRING_ARRIDX)\n\tres->arridx = duk_js_to_arrayindex_string(data, blen);\n\tif (res->arridx != DUK_HSTRING_NO_ARRAY_INDEX) {\n#else\n\tdummy = duk_js_to_arrayindex_string(data, blen);\n\tif (dummy != DUK_HSTRING_NO_ARRAY_INDEX) {\n#endif\n\t\t/* Array index strings cannot be symbol strings,\n\t\t * and they're always pure ASCII so blen == clen.\n\t\t */\n\t\tDUK_HSTRING_SET_ARRIDX(res);\n\t\tDUK_HSTRING_SET_ASCII(res);\n\t\tDUK_ASSERT(duk_unicode_unvalidated_utf8_length(data, (duk_size_t) blen) == blen);\n\t} else {\n\t\t/* Because 'data' is NUL-terminated, we don't need a\n\t\t * blen > 0 check here.  For NUL (0x00) the symbol\n\t\t * checks will be false.\n\t\t */\n\t\tif (DUK_UNLIKELY(data[0] >= 0x80U)) {\n\t\t\tif (data[0] <= 0x81) {\n\t\t\t\tDUK_HSTRING_SET_SYMBOL(res);\n\t\t\t} else if (data[0] == 0x82U || data[0] == 0xffU) {\n\t\t\t\tDUK_HSTRING_SET_HIDDEN(res);\n\t\t\t\tDUK_HSTRING_SET_SYMBOL(res);\n\t\t\t}\n\t\t}\n\n\t\t/* Using an explicit 'ASCII' flag has larger footprint (one call site\n\t\t * only) but is quite useful for the case when there's no explicit\n\t\t * 'clen' in duk_hstring.\n\t\t *\n\t\t * The flag is set lazily for RAM strings.\n\t\t */\n\t\tDUK_ASSERT(!DUK_HSTRING_HAS_ASCII(res));\n\n#if defined(DUK_USE_HSTRING_LAZY_CLEN)\n\t\t/* Charlen initialized to 0, updated on-the-fly. */\n#else\n\t\tduk_hstring_init_charlen(res);  /* Also sets ASCII flag. */\n#endif\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"interned string, hash=0x%08lx, blen=%ld, has_arridx=%ld, has_extdata=%ld\",\n\t                     (unsigned long) DUK_HSTRING_GET_HASH(res),\n\t                     (long) DUK_HSTRING_GET_BYTELEN(res),\n\t                     (long) (DUK_HSTRING_HAS_ARRIDX(res) ? 1 : 0),\n\t                     (long) (DUK_HSTRING_HAS_EXTDATA(res) ? 1 : 0)));\n\n\tDUK_ASSERT(res != NULL);\n\treturn res;\n\n alloc_error:\n\treturn NULL;\n}\n\n/*\n *  Grow strtable allocation in-place.\n */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL void duk__strtable_grow_inplace(duk_heap *heap) {\n\tduk_uint32_t new_st_size;\n\tduk_uint32_t old_st_size;\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_hstring *next;\n\tduk_hstring *prev;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *new_ptr;\n\tduk_uint16_t *new_ptr_high;\n#else\n\tduk_hstring **new_ptr;\n\tduk_hstring **new_ptr_high;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"grow in-place: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size * 2));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->st_resizing == 1);\n\tDUK_ASSERT(heap->st_size >= 2);\n\tDUK_ASSERT((heap->st_size & (heap->st_size - 1)) == 0);  /* 2^N */\n\tDUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL);\n\n\tDUK_STATS_INC(heap, stats_strtab_resize_grow);\n\n\tnew_st_size = heap->st_size << 1U;\n\tDUK_ASSERT(new_st_size > heap->st_size);  /* No overflow. */\n\n\t/* Reallocate the strtable first and then work in-place to rehash\n\t * strings.  We don't need an indirect allocation here: even if GC\n\t * is triggered to satisfy the allocation, recursive strtable resize\n\t * is prevented by flags.  This is also why we don't need to use\n\t * DUK_REALLOC_INDIRECT().\n\t */\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tnew_ptr = (duk_uint16_t *) DUK_REALLOC(heap, heap->strtable16, sizeof(duk_uint16_t) * new_st_size);\n#else\n\tnew_ptr = (duk_hstring **) DUK_REALLOC(heap, heap->strtable, sizeof(duk_hstring *) * new_st_size);\n#endif\n\tif (DUK_UNLIKELY(new_ptr == NULL)) {\n\t\t/* If realloc fails we can continue normally: the string table\n\t\t * won't \"fill up\" although chains will gradually get longer.\n\t\t * When string insertions continue, we'll quite soon try again\n\t\t * with no special handling.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"string table grow failed, ignoring\"));\n\t\treturn;\n\t}\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\theap->strtable16 = new_ptr;\n#else\n\theap->strtable = new_ptr;\n#endif\n\n\t/* Rehash a single bucket into two separate ones.  When we grow\n\t * by x2 the highest 'new' bit determines whether a string remains\n\t * in its old position (bit is 0) or goes to a new one (bit is 1).\n\t */\n\n\told_st_size = heap->st_size;\n\tnew_ptr_high = new_ptr + old_st_size;\n\tfor (i = 0; i < old_st_size; i++) {\n\t\tduk_hstring *new_root;\n\t\tduk_hstring *new_root_high;\n\n\t\th = DUK__HEAPPTR_DEC16(heap, new_ptr[i]);\n\t\tnew_root = h;\n\t\tnew_root_high = NULL;\n\n\t\tprev = NULL;\n\t\twhile (h != NULL) {\n\t\t\tduk_uint32_t mask;\n\n\t\t\tDUK_ASSERT((DUK_HSTRING_GET_HASH(h) & heap->st_mask) == i);\n\t\t\tnext = h->hdr.h_next;\n\n\t\t\t/* Example: if previous size was 256, previous mask is 0xFF\n\t\t\t * and size is 0x100 which corresponds to the new bit that\n\t\t\t * comes into play.\n\t\t\t */\n\t\t\tDUK_ASSERT(heap->st_mask == old_st_size - 1);\n\t\t\tmask = old_st_size;\n\t\t\tif (DUK_HSTRING_GET_HASH(h) & mask) {\n\t\t\t\tif (prev != NULL) {\n\t\t\t\t\tprev->hdr.h_next = h->hdr.h_next;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(h == new_root);\n\t\t\t\t\tnew_root = h->hdr.h_next;\n\t\t\t\t}\n\n\t\t\t\th->hdr.h_next = new_root_high;\n\t\t\t\tnew_root_high = h;\n\t\t\t} else {\n\t\t\t\tprev = h;\n\t\t\t}\n\t\t\th = next;\n\t\t}\n\n\t\tnew_ptr[i] = DUK__HEAPPTR_ENC16(heap, new_root);\n\t\tnew_ptr_high[i] = DUK__HEAPPTR_ENC16(heap, new_root_high);\n\t}\n\n\theap->st_size = new_st_size;\n\theap->st_mask = new_st_size - 1;\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__strtable_assert_checks(heap);\n#endif\n}\n#endif  /* DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Shrink strtable allocation in-place.\n */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL void duk__strtable_shrink_inplace(duk_heap *heap) {\n\tduk_uint32_t new_st_size;\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_hstring *other;\n\tduk_hstring *root;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *old_ptr;\n\tduk_uint16_t *old_ptr_high;\n\tduk_uint16_t *new_ptr;\n#else\n\tduk_hstring **old_ptr;\n\tduk_hstring **old_ptr_high;\n\tduk_hstring **new_ptr;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"shrink in-place: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size / 2));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->st_resizing == 1);\n\tDUK_ASSERT(heap->st_size >= 2);\n\tDUK_ASSERT((heap->st_size & (heap->st_size - 1)) == 0);  /* 2^N */\n\tDUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL);\n\n\tDUK_STATS_INC(heap, stats_strtab_resize_shrink);\n\n\tnew_st_size = heap->st_size >> 1U;\n\n\t/* Combine two buckets into a single one.  When we shrink, one hash\n\t * bit (highest) disappears.\n\t */\n\told_ptr = DUK__GET_STRTABLE(heap);\n\told_ptr_high = old_ptr + new_st_size;\n\tfor (i = 0; i < new_st_size; i++) {\n\t\th = DUK__HEAPPTR_DEC16(heap, old_ptr[i]);\n\t\tother = DUK__HEAPPTR_DEC16(heap, old_ptr_high[i]);\n\n\t\tif (h == NULL) {\n\t\t\t/* First chain is empty, so use second one as is. */\n\t\t\troot = other;\n\t\t} else {\n\t\t\t/* Find end of first chain, and link in the second. */\n\t\t\troot = h;\n\t\t\twhile (h->hdr.h_next != NULL) {\n\t\t\t\th = h->hdr.h_next;\n\t\t\t}\n\t\t\th->hdr.h_next = other;\n\t\t}\n\n\t\told_ptr[i] = DUK__HEAPPTR_ENC16(heap, root);\n\t}\n\n\theap->st_size = new_st_size;\n\theap->st_mask = new_st_size - 1;\n\n\t/* The strtable is now consistent and we can realloc safely.  Even\n\t * if side effects cause string interning or removal the strtable\n\t * updates are safe.  Recursive resize has been prevented by caller.\n\t * This is also why we don't need to use DUK_REALLOC_INDIRECT().\n\t *\n\t * We assume a realloc() to a smaller size is guaranteed to succeed.\n\t * It would be relatively straightforward to handle the error by\n\t * essentially performing a \"grow\" step to recover.\n\t */\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tnew_ptr = (duk_uint16_t *) DUK_REALLOC(heap, heap->strtable16, sizeof(duk_uint16_t) * new_st_size);\n\tDUK_ASSERT(new_ptr != NULL);\n\theap->strtable16 = new_ptr;\n#else\n\tnew_ptr = (duk_hstring **) DUK_REALLOC(heap, heap->strtable, sizeof(duk_hstring *) * new_st_size);\n\tDUK_ASSERT(new_ptr != NULL);\n\theap->strtable = new_ptr;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__strtable_assert_checks(heap);\n#endif\n}\n#endif  /* DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Grow/shrink check.\n */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL DUK_COLD DUK_NOINLINE void duk__strtable_resize_check(duk_heap *heap) {\n\tduk_uint32_t load_factor;  /* fixed point */\n\n\tDUK_ASSERT(heap != NULL);\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tDUK_ASSERT(heap->strtable16 != NULL);\n#else\n\tDUK_ASSERT(heap->strtable != NULL);\n#endif\n\n\tDUK_STATS_INC(heap, stats_strtab_resize_check);\n\n\t/* Prevent recursive resizing. */\n\tif (DUK_UNLIKELY(heap->st_resizing != 0U)) {\n\t\tDUK_D(DUK_DPRINT(\"prevent recursive strtable resize\"));\n\t\treturn;\n\t}\n\n\theap->st_resizing = 1;\n\n\tDUK_ASSERT(heap->st_size >= 16U);\n\tDUK_ASSERT((heap->st_size >> 4U) >= 1);\n\tload_factor = heap->st_count / (heap->st_size >> 4U);\n\n\tDUK_DD(DUK_DDPRINT(\"resize check string table: size=%lu, count=%lu, load_factor=%lu (fixed point .4; float %lf)\",\n\t                   (unsigned long) heap->st_size, (unsigned long) heap->st_count,\n\t                   (unsigned long) load_factor,\n\t                   (double) heap->st_count / (double) heap->st_size));\n\n\tif (load_factor >= DUK_USE_STRTAB_GROW_LIMIT) {\n\t\tif (heap->st_size >= DUK_USE_STRTAB_MAXSIZE) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"want to grow strtable (based on load factor) but already maximum size\"));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"grow string table: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size * 2));\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk_heap_strtable_dump(heap);\n#endif\n\t\t\tduk__strtable_grow_inplace(heap);\n\t\t}\n\t} else if (load_factor <= DUK_USE_STRTAB_SHRINK_LIMIT) {\n\t\tif (heap->st_size <= DUK_USE_STRTAB_MINSIZE) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"want to shrink strtable (based on load factor) but already minimum size\"));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"shrink string table: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size / 2));\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk_heap_strtable_dump(heap);\n#endif\n\t\t\tduk__strtable_shrink_inplace(heap);\n\t\t}\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"no need for strtable resize\"));\n\t}\n\n\theap->st_resizing = 0;\n}\n#endif  /* DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Torture grow/shrink: unconditionally grow and shrink back.\n */\n\n#if defined(DUK_USE_STRTAB_TORTURE) && defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL void duk__strtable_resize_torture(duk_heap *heap) {\n\tduk_uint32_t old_st_size;\n\n\tDUK_ASSERT(heap != NULL);\n\n\told_st_size = heap->st_size;\n\tif (old_st_size >= DUK_USE_STRTAB_MAXSIZE) {\n\t\treturn;\n\t}\n\n\theap->st_resizing = 1;\n\tduk__strtable_grow_inplace(heap);\n\tif (heap->st_size > old_st_size) {\n\t\tduk__strtable_shrink_inplace(heap);\n\t}\n\theap->st_resizing = 0;\n}\n#endif  /* DUK_USE_STRTAB_TORTURE && DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Raw intern; string already checked not to be present.\n */\n\nDUK_LOCAL duk_hstring *duk__strtable_do_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen, duk_uint32_t strhash) {\n\tduk_hstring *res;\n\tconst duk_uint8_t *extdata;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *slot;\n#else\n\tduk_hstring **slot;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"do_intern: heap=%p, str=%p, blen=%lu, strhash=%lx, st_size=%lu, st_count=%lu, load=%lf\",\n\t                     (void *) heap, (const void *) str, (unsigned long) blen, (unsigned long) strhash,\n\t                     (unsigned long) heap->st_size, (unsigned long) heap->st_count,\n\t                     (double) heap->st_count / (double) heap->st_size));\n\n\tDUK_ASSERT(heap != NULL);\n\n\t/* Prevent any side effects on the string table and the caller provided\n\t * str/blen arguments while interning is in progress.  For example, if\n\t * the caller provided str/blen from a dynamic buffer, a finalizer\n\t * might resize or modify that dynamic buffer, invalidating the call\n\t * arguments.\n\t *\n\t * While finalizers must be prevented, mark-and-sweep itself is fine.\n\t * Recursive string table resize is prevented explicitly here.\n\t */\n\n\theap->pf_prevent_count++;\n\tDUK_ASSERT(heap->pf_prevent_count != 0);  /* Wrap. */\n\n#if defined(DUK_USE_STRTAB_TORTURE) && defined(DUK__STRTAB_RESIZE_CHECK)\n\tduk__strtable_resize_torture(heap);\n#endif\n\n\t/* String table grow/shrink check.  Because of chaining (and no\n\t * accumulation issues as with hash probe chains and DELETED\n\t * markers) there's never a mandatory need to resize right now.\n\t * Check for the resize only periodically, based on st_count\n\t * bit pattern.  Because string table removal doesn't do a shrink\n\t * check, we do that also here.\n\t *\n\t * Do the resize and possible grow/shrink before the new duk_hstring\n\t * has been allocated.  Otherwise we may trigger a GC when the result\n\t * duk_hstring is not yet strongly referenced.\n\t */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tif (DUK_UNLIKELY((heap->st_count & DUK_USE_STRTAB_RESIZE_CHECK_MASK) == 0)) {\n\t\tduk__strtable_resize_check(heap);\n\t}\n#endif\n\n\t/* External string check (low memory optimization). */\n\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK)\n\textdata = (const duk_uint8_t *) DUK_USE_EXTSTR_INTERN_CHECK(heap->heap_udata, (void *) DUK_LOSE_CONST(str), (duk_size_t) blen);\n#else\n\textdata = (const duk_uint8_t *) NULL;\n#endif\n\n\t/* Allocate and initialize string, not yet linked.  This may cause a\n\t * GC which may cause other strings to be interned and inserted into\n\t * the string table before we insert our string.  Finalizer execution\n\t * is disabled intentionally to avoid a finalizer from e.g. resizing\n\t * a buffer used as a data area for 'str'.\n\t */\n\n\tres = duk__strtable_alloc_hstring(heap, str, blen, strhash, extdata);\n\n\t/* Allow side effects again: GC must be avoided until duk_hstring\n\t * result (if successful) has been INCREF'd.\n\t */\n\tDUK_ASSERT(heap->pf_prevent_count > 0);\n\theap->pf_prevent_count--;\n\n\t/* Alloc error handling. */\n\n\tif (DUK_UNLIKELY(res == NULL)) {\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK)\n\t\tif (extdata != NULL) {\n\t\t\tDUK_USE_EXTSTR_FREE(heap->heap_udata, (const void *) extdata);\n\t\t}\n#endif\n\t\treturn NULL;\n\t}\n\n\t/* Insert into string table. */\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tslot = heap->strtable16 + (strhash & heap->st_mask);\n#else\n\tslot = heap->strtable + (strhash & heap->st_mask);\n#endif\n\tDUK_ASSERT(res->hdr.h_next == NULL);  /* This is the case now, but unnecessary zeroing/NULLing. */\n\tres->hdr.h_next = DUK__HEAPPTR_DEC16(heap, *slot);\n\t*slot = DUK__HEAPPTR_ENC16(heap, res);\n\n\t/* Update string count only for successful inserts. */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\theap->st_count++;\n#endif\n\n\t/* The duk_hstring is in the string table but is not yet strongly\n\t * reachable.  Calling code MUST NOT make any allocations or other\n\t * side effects before the duk_hstring has been INCREF'd and made\n\t * reachable.\n\t */\n\n\treturn res;\n}\n\n/*\n *  Intern a string from str/blen, returning either an existing duk_hstring\n *  or adding a new one into the string table.  The input string does -not-\n *  need to be NUL terminated.\n *\n *  The input 'str' argument may point to a Duktape managed data area such as\n *  the data area of a dynamic buffer.  It's crucial to avoid any side effects\n *  that might affect the data area (e.g. resize the dynamic buffer, or write\n *  to the buffer) before the string is fully interned.\n */\n\n#if defined(DUK_USE_ROM_STRINGS)\nDUK_LOCAL duk_hstring *duk__strtab_romstring_lookup(duk_heap *heap, const duk_uint8_t *str, duk_size_t blen, duk_uint32_t strhash) {\n\tduk_size_t lookup_hash;\n\tduk_hstring *curr;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_UNREF(heap);\n\n\tlookup_hash = (blen << 4);\n\tif (blen > 0) {\n\t\tlookup_hash += str[0];\n\t}\n\tlookup_hash &= 0xff;\n\n\tcurr = (duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_lookup[lookup_hash]);\n\twhile (curr != NULL) {\n\t\t/* Unsafe memcmp() because for zero blen, str may be NULL. */\n\t\tif (strhash == DUK_HSTRING_GET_HASH(curr) &&\n\t\t    blen == DUK_HSTRING_GET_BYTELEN(curr) &&\n\t\t    duk_memcmp_unsafe((const void *) str, (const void *) DUK_HSTRING_GET_DATA(curr), blen) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"intern check: rom string: %!O, computed hash 0x%08lx, rom hash 0x%08lx\",\n\t\t\t                     curr, (unsigned long) strhash, (unsigned long) DUK_HSTRING_GET_HASH(curr)));\n\t\t\treturn curr;\n\t\t}\n\t\tcurr = curr->hdr.h_next;\n\t}\n\n\treturn NULL;\n}\n#endif  /* DUK_USE_ROM_STRINGS */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uint32_t strhash;\n\tduk_hstring *h;\n\n\tDUK_DDD(DUK_DDDPRINT(\"intern check: heap=%p, str=%p, blen=%lu\", (void *) heap, (const void *) str, (unsigned long) blen));\n\n\t/* Preliminaries. */\n\n\t/* XXX: maybe just require 'str != NULL' even for zero size? */\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(blen == 0 || str != NULL);\n\tDUK_ASSERT(blen <= DUK_HSTRING_MAX_BYTELEN);  /* Caller is responsible for ensuring this. */\n\tstrhash = duk_heap_hashstring(heap, str, (duk_size_t) blen);\n\n\t/* String table lookup. */\n\n\tDUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL);\n\tDUK_ASSERT(heap->st_size > 0);\n\tDUK_ASSERT(heap->st_size == heap->st_mask + 1);\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\th = DUK__HEAPPTR_DEC16(heap, heap->strtable16[strhash & heap->st_mask]);\n#else\n\th = heap->strtable[strhash & heap->st_mask];\n#endif\n\twhile (h != NULL) {\n\t\tif (DUK_HSTRING_GET_HASH(h) == strhash &&\n\t\t    DUK_HSTRING_GET_BYTELEN(h) == blen &&\n\t\t    duk_memcmp_unsafe((const void *) str, (const void *) DUK_HSTRING_GET_DATA(h), (size_t) blen) == 0) {\n\t\t\t/* Found existing entry. */\n\t\t\tDUK_STATS_INC(heap, stats_strtab_intern_hit);\n\t\t\treturn h;\n\t\t}\n\t\th = h->hdr.h_next;\n\t}\n\n\t/* ROM table lookup.  Because this lookup is slower, do it only after\n\t * RAM lookup.  This works because no ROM string is ever interned into\n\t * the RAM string table.\n\t */\n\n#if defined(DUK_USE_ROM_STRINGS)\n\th = duk__strtab_romstring_lookup(heap, str, blen, strhash);\n\tif (h != NULL) {\n\t\tDUK_STATS_INC(heap, stats_strtab_intern_hit);\n\t\treturn h;\n\t}\n#endif\n\n\t/* Not found in string table; insert. */\n\n\tDUK_STATS_INC(heap, stats_strtab_intern_miss);\n\th = duk__strtable_do_intern(heap, str, blen, strhash);\n\treturn h;  /* may be NULL */\n}\n\n/*\n *  Intern a string from u32.\n */\n\n/* XXX: Could arrange some special handling because we know that the result\n * will have an arridx flag and an ASCII flag, won't need a clen check, etc.\n */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_u32(duk_heap *heap, duk_uint32_t val) {\n\tduk_uint8_t buf[DUK__STRTAB_U32_MAX_STRLEN];\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT(heap != NULL);\n\n\t/* This is smaller and faster than a %lu sprintf. */\n\tp = buf + sizeof(buf);\n\tdo {\n\t\tp--;\n\t\t*p = duk_lc_digits[val % 10];\n\t\tval = val / 10;\n\t} while (val != 0);  /* For val == 0, emit exactly one '0'. */\n\tDUK_ASSERT(p >= buf);\n\n\treturn duk_heap_strtable_intern(heap, (const duk_uint8_t *) p, (duk_uint32_t) ((buf + sizeof(buf)) - p));\n}\n\n/*\n *  Checked convenience variants.\n *\n *  XXX: Because the main use case is for the checked variants, make them the\n *  main functionality and provide a safe variant separately (it is only needed\n *  during heap init).  The problem with that is that longjmp state and error\n *  creation must already be possible to throw.\n */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_hstring *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(blen == 0 || str != NULL);\n\n\tres = duk_heap_strtable_intern(thr->heap, str, blen);\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn res;\n}\n\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_LOCAL duk_uint_t duk__strtable_litcache_key(const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uintptr_t key;\n\n\tDUK_ASSERT(DUK_USE_LITCACHE_SIZE > 0);\n\tDUK_ASSERT(DUK_IS_POWER_OF_TWO((duk_uint_t) DUK_USE_LITCACHE_SIZE));\n\n\tkey = (duk_uintptr_t) blen ^ (duk_uintptr_t) str;\n\tkey &= (duk_uintptr_t) (DUK_USE_LITCACHE_SIZE - 1);  /* Assumes size is power of 2. */\n\t/* Due to masking, cast is in 32-bit range. */\n\tDUK_ASSERT(key <= DUK_UINT_MAX);\n\treturn (duk_uint_t) key;\n}\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_literal_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uint_t key;\n\tduk_litcache_entry *ent;\n\tduk_hstring *h;\n\n\t/* Fast path check: literal exists in literal cache. */\n\tkey = duk__strtable_litcache_key(str, blen);\n\tent = thr->heap->litcache + key;\n\tif (ent->addr == str) {\n\t\tDUK_DD(DUK_DDPRINT(\"intern check for cached, pinned literal: str=%p, blen=%ld -> duk_hstring %!O\",\n\t\t                   (const void *) str, (long) blen, (duk_heaphdr *) ent->h));\n\t\tDUK_ASSERT(ent->h != NULL);\n\t\tDUK_ASSERT(DUK_HSTRING_HAS_PINNED_LITERAL(ent->h));\n\t\tDUK_STATS_INC(thr->heap, stats_strtab_litcache_hit);\n\t\treturn ent->h;\n\t}\n\n\t/* Intern and update (overwrite) cache entry. */\n\th = duk_heap_strtable_intern_checked(thr, str, blen);\n\tent->addr = str;\n\tent->h = h;\n\tDUK_STATS_INC(thr->heap, stats_strtab_litcache_miss);\n\n\t/* Pin the duk_hstring until the next mark-and-sweep.  This means\n\t * litcache entries don't need to be invalidated until the next\n\t * mark-and-sweep as their target duk_hstring is not freed before\n\t * the mark-and-sweep happens.  The pin remains even if the literal\n\t * cache entry is overwritten, and is still useful to avoid string\n\t * table traffic.\n\t */\n\tif (!DUK_HSTRING_HAS_PINNED_LITERAL(h)) {\n\t\tDUK_DD(DUK_DDPRINT(\"pin duk_hstring because it is a literal: %!O\", (duk_heaphdr *) h));\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h));\n\t\tDUK_HSTRING_INCREF(thr, h);\n\t\tDUK_HSTRING_SET_PINNED_LITERAL(h);\n\t\tDUK_STATS_INC(thr->heap, stats_strtab_litcache_pin);\n\t}\n\n\treturn h;\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_u32_checked(duk_hthread *thr, duk_uint32_t val) {\n\tduk_hstring *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tres = duk_heap_strtable_intern_u32(thr->heap, val);\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn res;\n}\n\n/*\n *  Remove (unlink) a string from the string table.\n *\n *  Just unlinks the duk_hstring, leaving link pointers as garbage.\n *  Caller must free the string itself.\n */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n/* Unlink without a 'prev' pointer. */\nDUK_INTERNAL void duk_heap_strtable_unlink(duk_heap *heap, duk_hstring *h) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *slot;\n#else\n\tduk_hstring **slot;\n#endif\n\tduk_hstring *other;\n\tduk_hstring *prev;\n\n\tDUK_DDD(DUK_DDDPRINT(\"remove: heap=%p, h=%p, blen=%lu, strhash=%lx\",\n\t                     (void *) heap, (void *) h,\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_BYTELEN(h) : 0),\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_HASH(h) : 0)));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tDUK_ASSERT(heap->st_count > 0);\n\theap->st_count--;\n#endif\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tslot = heap->strtable16 + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#else\n\tslot = heap->strtable + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#endif\n\tother = DUK__HEAPPTR_DEC16(heap, *slot);\n\tDUK_ASSERT(other != NULL);  /* At least argument string is in the chain. */\n\n\tprev = NULL;\n\twhile (other != h) {\n\t\tprev = other;\n\t\tother = other->hdr.h_next;\n\t\tDUK_ASSERT(other != NULL);  /* We'll eventually find 'h'. */\n\t}\n\tif (prev != NULL) {\n\t\t/* Middle of list. */\n\t\tprev->hdr.h_next = h->hdr.h_next;\n\t} else {\n\t\t/* Head of list. */\n\t\t*slot = DUK__HEAPPTR_ENC16(heap, h->hdr.h_next);\n\t}\n\n\t/* There's no resize check on a string free.  The next string\n\t * intern will do one.\n\t */\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/* Unlink with a 'prev' pointer. */\nDUK_INTERNAL void duk_heap_strtable_unlink_prev(duk_heap *heap, duk_hstring *h, duk_hstring *prev) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *slot;\n#else\n\tduk_hstring **slot;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"remove: heap=%p, prev=%p, h=%p, blen=%lu, strhash=%lx\",\n\t                     (void *) heap, (void *) prev, (void *) h,\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_BYTELEN(h) : 0),\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_HASH(h) : 0)));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(prev == NULL || prev->hdr.h_next == h);\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tDUK_ASSERT(heap->st_count > 0);\n\theap->st_count--;\n#endif\n\n\tif (prev != NULL) {\n\t\t/* Middle of list. */\n\t\tprev->hdr.h_next = h->hdr.h_next;\n\t} else {\n\t\t/* Head of list. */\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\tslot = heap->strtable16 + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#else\n\t\tslot = heap->strtable + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#endif\n\t\tDUK_ASSERT(DUK__HEAPPTR_DEC16(heap, *slot) == h);\n\t\t*slot = DUK__HEAPPTR_ENC16(heap, h->hdr.h_next);\n\t}\n}\n\n/*\n *  Force string table resize check in mark-and-sweep.\n */\n\nDUK_INTERNAL void duk_heap_strtable_force_resize(duk_heap *heap) {\n\t/* Does only one grow/shrink step if needed.  The heap->st_resizing\n\t * flag protects against recursive resizing.\n\t */\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_UNREF(heap);\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tif (heap->strtable16 != NULL) {\n#else\n\tif (heap->strtable != NULL) {\n#endif\n\t\tduk__strtable_resize_check(heap);\n\t}\n#endif\n}\n\n/*\n *  Free strings in the string table and the string table itself.\n */\n\nDUK_INTERNAL void duk_heap_strtable_free(duk_heap *heap) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable;\n\tduk_uint16_t *st;\n#else\n\tduk_hstring **strtable;\n\tduk_hstring **st;\n#endif\n\tduk_hstring *h;\n\n\tDUK_ASSERT(heap != NULL);\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__strtable_assert_checks(heap);\n#endif\n\n\t/* Strtable can be NULL if heap init fails.  However, in that case\n\t * heap->st_size is 0, so strtable == strtable_end and we skip the\n\t * loop without a special check.\n\t */\n\tstrtable = DUK__GET_STRTABLE(heap);\n\tst = strtable + heap->st_size;\n\tDUK_ASSERT(strtable != NULL || heap->st_size == 0);\n\n\twhile (strtable != st) {\n\t\t--st;\n\t\th = DUK__HEAPPTR_DEC16(heap, *st);\n\t\twhile (h) {\n\t\t\tduk_hstring *h_next;\n\t\t\th_next = h->hdr.h_next;\n\n\t\t\t/* Strings may have inner refs (extdata) in some cases. */\n\t\t\tduk_free_hstring(heap, h);\n\n\t\t\th = h_next;\n\t\t}\n\t}\n\n\tDUK_FREE(heap, strtable);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_heaphdr.h",
    "content": "/*\n *  Heap header definition and assorted macros, including ref counting.\n *  Access all fields through the accessor macros.\n */\n\n#if !defined(DUK_HEAPHDR_H_INCLUDED)\n#define DUK_HEAPHDR_H_INCLUDED\n\n/*\n *  Common heap header\n *\n *  All heap objects share the same flags and refcount fields.  Objects other\n *  than strings also need to have a single or double linked list pointers\n *  for insertion into the \"heap allocated\" list.  Strings have single linked\n *  list pointers for string table chaining.\n *\n *  Technically, 'h_refcount' must be wide enough to guarantee that it cannot\n *  wrap; otherwise objects might be freed incorrectly after wrapping.  The\n *  default refcount field is 32 bits even on 64-bit systems: while that's in\n *  theory incorrect, the Duktape heap needs to be larger than 64GB for the\n *  count to actually wrap (assuming 16-byte duk_tvals).  This is very unlikely\n *  to ever be an issue, but if it is, disabling DUK_USE_REFCOUNT32 causes\n *  Duktape to use size_t for refcounts which should always be safe.\n *\n *  Heap header size on 32-bit platforms: 8 bytes without reference counting,\n *  16 bytes with reference counting.\n *\n *  Note that 'raw' macros such as DUK_HEAPHDR_GET_REFCOUNT() are not\n *  defined without DUK_USE_REFERENCE_COUNTING, so caller must #if defined()\n *  around them.\n */\n\n/* XXX: macro for shared header fields (avoids some padding issues) */\n\nstruct duk_heaphdr {\n\tduk_uint32_t h_flags;\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#if defined(DUK_USE_ASSERTIONS)\n\t/* When assertions enabled, used by mark-and-sweep for refcount\n\t * validation.  Largest reasonable type; also detects overflows.\n\t */\n\tduk_size_t h_assert_refcount;\n#endif\n#if defined(DUK_USE_REFCOUNT16)\n\tduk_uint16_t h_refcount;\n#elif defined(DUK_USE_REFCOUNT32)\n\tduk_uint32_t h_refcount;\n#else\n\tduk_size_t h_refcount;\n#endif\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t h_next16;\n#else\n\tduk_heaphdr *h_next;\n#endif\n\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\t/* refcounting requires direct heap frees, which in turn requires a dual linked heap */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t h_prev16;\n#else\n\tduk_heaphdr *h_prev;\n#endif\n#endif\n\n\t/* When DUK_USE_HEAPPTR16 (and DUK_USE_REFCOUNT16) is in use, the\n\t * struct won't align nicely to 4 bytes.  This 16-bit extra field\n\t * is added to make the alignment clean; the field can be used by\n\t * heap objects when 16-bit packing is used.  This field is now\n\t * conditional to DUK_USE_HEAPPTR16 only, but it is intended to be\n\t * used with DUK_USE_REFCOUNT16 and DUK_USE_DOUBLE_LINKED_HEAP;\n\t * this only matter to low memory environments anyway.\n\t */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t h_extra16;\n#endif\n};\n\nstruct duk_heaphdr_string {\n\t/* 16 bits would be enough for shared heaphdr flags and duk_hstring\n\t * flags.  The initial parts of duk_heaphdr_string and duk_heaphdr\n\t * must match so changing the flags field size here would be quite\n\t * awkward.  However, to minimize struct size, we can pack at least\n\t * 16 bits of duk_hstring data into the flags field.\n\t */\n\tduk_uint32_t h_flags;\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#if defined(DUK_USE_ASSERTIONS)\n\t/* When assertions enabled, used by mark-and-sweep for refcount\n\t * validation.  Largest reasonable type; also detects overflows.\n\t */\n\tduk_size_t h_assert_refcount;\n#endif\n#if defined(DUK_USE_REFCOUNT16)\n\tduk_uint16_t h_refcount;\n\tduk_uint16_t h_strextra16;  /* round out to 8 bytes */\n#elif defined(DUK_USE_REFCOUNT32)\n\tduk_uint32_t h_refcount;\n#else\n\tduk_size_t h_refcount;\n#endif\n#else\n\tduk_uint16_t h_strextra16;\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n\tduk_hstring *h_next;\n\t/* No 'h_prev' pointer for strings. */\n};\n\n#define DUK_HEAPHDR_FLAGS_TYPE_MASK      0x00000003UL\n#define DUK_HEAPHDR_FLAGS_FLAG_MASK      (~DUK_HEAPHDR_FLAGS_TYPE_MASK)\n\n                                             /* 2 bits for heap type */\n#define DUK_HEAPHDR_FLAGS_HEAP_START     2   /* 5 heap flags */\n#define DUK_HEAPHDR_FLAGS_USER_START     7   /* 25 user flags */\n\n#define DUK_HEAPHDR_HEAP_FLAG_NUMBER(n)  (DUK_HEAPHDR_FLAGS_HEAP_START + (n))\n#define DUK_HEAPHDR_USER_FLAG_NUMBER(n)  (DUK_HEAPHDR_FLAGS_USER_START + (n))\n#define DUK_HEAPHDR_HEAP_FLAG(n)         (1UL << (DUK_HEAPHDR_FLAGS_HEAP_START + (n)))\n#define DUK_HEAPHDR_USER_FLAG(n)         (1UL << (DUK_HEAPHDR_FLAGS_USER_START + (n)))\n\n#define DUK_HEAPHDR_FLAG_REACHABLE       DUK_HEAPHDR_HEAP_FLAG(0)  /* mark-and-sweep: reachable */\n#define DUK_HEAPHDR_FLAG_TEMPROOT        DUK_HEAPHDR_HEAP_FLAG(1)  /* mark-and-sweep: children not processed */\n#define DUK_HEAPHDR_FLAG_FINALIZABLE     DUK_HEAPHDR_HEAP_FLAG(2)  /* mark-and-sweep: finalizable (on current pass) */\n#define DUK_HEAPHDR_FLAG_FINALIZED       DUK_HEAPHDR_HEAP_FLAG(3)  /* mark-and-sweep: finalized (on previous pass) */\n#define DUK_HEAPHDR_FLAG_READONLY        DUK_HEAPHDR_HEAP_FLAG(4)  /* read-only object, in code section */\n\n#define DUK_HTYPE_MIN                    0\n#define DUK_HTYPE_STRING                 0\n#define DUK_HTYPE_OBJECT                 1\n#define DUK_HTYPE_BUFFER                 2\n#define DUK_HTYPE_MAX                    2\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HEAPHDR_GET_NEXT(heap,h) \\\n\t((duk_heaphdr *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->h_next16))\n#define DUK_HEAPHDR_SET_NEXT(heap,h,val)   do { \\\n\t\t(h)->h_next16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) val); \\\n\t} while (0)\n#else\n#define DUK_HEAPHDR_GET_NEXT(heap,h)  ((h)->h_next)\n#define DUK_HEAPHDR_SET_NEXT(heap,h,val)   do { \\\n\t\t(h)->h_next = (val); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HEAPHDR_GET_PREV(heap,h) \\\n\t((duk_heaphdr *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->h_prev16))\n#define DUK_HEAPHDR_SET_PREV(heap,h,val)   do { \\\n\t\t(h)->h_prev16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (val)); \\\n\t} while (0)\n#else\n#define DUK_HEAPHDR_GET_PREV(heap,h)       ((h)->h_prev)\n#define DUK_HEAPHDR_SET_PREV(heap,h,val)   do { \\\n\t\t(h)->h_prev = (val); \\\n\t} while (0)\n#endif\n#endif\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_HEAPHDR_GET_REFCOUNT(h)   ((h)->h_refcount)\n#define DUK_HEAPHDR_SET_REFCOUNT(h,val)  do { \\\n\t\t(h)->h_refcount = (val); \\\n\t\tDUK_ASSERT((h)->h_refcount == (val));  /* No truncation. */ \\\n\t} while (0)\n#define DUK_HEAPHDR_PREINC_REFCOUNT(h)  (++(h)->h_refcount)  /* result: updated refcount */\n#define DUK_HEAPHDR_PREDEC_REFCOUNT(h)  (--(h)->h_refcount)  /* result: updated refcount */\n#else\n/* refcount macros not defined without refcounting, caller must #if defined() now */\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/*\n *  Note: type is treated as a field separate from flags, so some masking is\n *  involved in the macros below.\n */\n\n#define DUK_HEAPHDR_GET_FLAGS_RAW(h)  ((h)->h_flags)\n#define DUK_HEAPHDR_SET_FLAGS_RAW(h,val)  do { \\\n\t\t(h)->h_flags = (val); } \\\n\t}\n#define DUK_HEAPHDR_GET_FLAGS(h)      ((h)->h_flags & DUK_HEAPHDR_FLAGS_FLAG_MASK)\n#define DUK_HEAPHDR_SET_FLAGS(h,val)  do { \\\n\t\t(h)->h_flags = ((h)->h_flags & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) | (val); \\\n\t} while (0)\n#define DUK_HEAPHDR_GET_TYPE(h)       ((h)->h_flags & DUK_HEAPHDR_FLAGS_TYPE_MASK)\n#define DUK_HEAPHDR_SET_TYPE(h,val)   do { \\\n\t\t(h)->h_flags = ((h)->h_flags & ~(DUK_HEAPHDR_FLAGS_TYPE_MASK)) | (val); \\\n\t} while (0)\n\n/* Comparison for type >= DUK_HTYPE_MIN skipped; because DUK_HTYPE_MIN is zero\n * and the comparison is unsigned, it's always true and generates warnings.\n */\n#define DUK_HEAPHDR_HTYPE_VALID(h)    ( \\\n\tDUK_HEAPHDR_GET_TYPE((h)) <= DUK_HTYPE_MAX \\\n\t)\n\n#define DUK_HEAPHDR_SET_TYPE_AND_FLAGS(h,tval,fval)  do { \\\n\t\t(h)->h_flags = ((tval) & DUK_HEAPHDR_FLAGS_TYPE_MASK) | \\\n\t\t               ((fval) & DUK_HEAPHDR_FLAGS_FLAG_MASK); \\\n\t} while (0)\n\n#define DUK_HEAPHDR_SET_FLAG_BITS(h,bits)  do { \\\n\t\tDUK_ASSERT(((bits) & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) == 0); \\\n\t\t(h)->h_flags |= (bits); \\\n\t} while (0)\n\n#define DUK_HEAPHDR_CLEAR_FLAG_BITS(h,bits)  do { \\\n\t\tDUK_ASSERT(((bits) & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) == 0); \\\n\t\t(h)->h_flags &= ~((bits)); \\\n\t} while (0)\n\n#define DUK_HEAPHDR_CHECK_FLAG_BITS(h,bits)  (((h)->h_flags & (bits)) != 0)\n\n#define DUK_HEAPHDR_SET_REACHABLE(h)      DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_REACHABLE)\n#define DUK_HEAPHDR_CLEAR_REACHABLE(h)    DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_REACHABLE)\n#define DUK_HEAPHDR_HAS_REACHABLE(h)      DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_REACHABLE)\n\n#define DUK_HEAPHDR_SET_TEMPROOT(h)       DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_TEMPROOT)\n#define DUK_HEAPHDR_CLEAR_TEMPROOT(h)     DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_TEMPROOT)\n#define DUK_HEAPHDR_HAS_TEMPROOT(h)       DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_TEMPROOT)\n\n#define DUK_HEAPHDR_SET_FINALIZABLE(h)    DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZABLE)\n#define DUK_HEAPHDR_CLEAR_FINALIZABLE(h)  DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZABLE)\n#define DUK_HEAPHDR_HAS_FINALIZABLE(h)    DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZABLE)\n\n#define DUK_HEAPHDR_SET_FINALIZED(h)      DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZED)\n#define DUK_HEAPHDR_CLEAR_FINALIZED(h)    DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZED)\n#define DUK_HEAPHDR_HAS_FINALIZED(h)      DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZED)\n\n#define DUK_HEAPHDR_SET_READONLY(h)       DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_READONLY)\n#define DUK_HEAPHDR_CLEAR_READONLY(h)     DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_READONLY)\n#define DUK_HEAPHDR_HAS_READONLY(h)       DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_READONLY)\n\n/* get or set a range of flags; m=first bit number, n=number of bits */\n#define DUK_HEAPHDR_GET_FLAG_RANGE(h,m,n)  (((h)->h_flags >> (m)) & ((1UL << (n)) - 1UL))\n\n#define DUK_HEAPHDR_SET_FLAG_RANGE(h,m,n,v)  do { \\\n\t\t(h)->h_flags = \\\n\t\t\t((h)->h_flags & (~(((1UL << (n)) - 1UL) << (m)))) \\\n\t\t\t| ((v) << (m)); \\\n\t} while (0)\n\n/* init pointer fields to null */\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n#define DUK_HEAPHDR_INIT_NULLS(h)       do { \\\n\t\tDUK_HEAPHDR_SET_NEXT((h), (void *) NULL); \\\n\t\tDUK_HEAPHDR_SET_PREV((h), (void *) NULL); \\\n\t} while (0)\n#else\n#define DUK_HEAPHDR_INIT_NULLS(h)       do { \\\n\t\tDUK_HEAPHDR_SET_NEXT((h), (void *) NULL); \\\n\t} while (0)\n#endif\n\n#define DUK_HEAPHDR_STRING_INIT_NULLS(h)  do { \\\n\t\t(h)->h_next = NULL; \\\n\t} while (0)\n\n/*\n *  Type tests\n */\n\n/* Take advantage of the fact that for DUK_HTYPE_xxx numbers the lowest bit\n * is only set for DUK_HTYPE_OBJECT (= 1).\n */\n#if 0\n#define DUK_HEAPHDR_IS_OBJECT(h) (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_OBJECT)\n#endif\n#define DUK_HEAPHDR_IS_OBJECT(h) ((h)->h_flags & 0x01UL)\n#define DUK_HEAPHDR_IS_STRING(h) (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_STRING)\n#define DUK_HEAPHDR_IS_BUFFER(h) (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_BUFFER)\n\n/*\n *  Assert helpers\n */\n\n/* Check that prev/next links are consistent: if e.g. h->prev is != NULL,\n * h->prev->next should point back to h.\n */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_heaphdr_assert_valid_subclassed(duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_assert_valid(duk_heaphdr *h);\n#define DUK_HEAPHDR_ASSERT_LINKS(heap,h)  do { duk_heaphdr_assert_links((heap), (h)); } while (0)\n#define DUK_HEAPHDR_ASSERT_VALID(h)  do { duk_heaphdr_assert_valid((h)); } while (0)\n#else\n#define DUK_HEAPHDR_ASSERT_LINKS(heap,h)  do {} while (0)\n#define DUK_HEAPHDR_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n#endif  /* DUK_HEAPHDR_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_heaphdr_assert.c",
    "content": "/*\n *  duk_heaphdr assertion helpers\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_ASSERTIONS)\n\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\nDUK_INTERNAL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tif (h != NULL) {\n\t\tduk_heaphdr *h_prev, *h_next;\n\t\th_prev = DUK_HEAPHDR_GET_PREV(heap, h);\n\t\th_next = DUK_HEAPHDR_GET_NEXT(heap, h);\n\t\tDUK_ASSERT(h_prev == NULL || (DUK_HEAPHDR_GET_NEXT(heap, h_prev) == h));\n\t\tDUK_ASSERT(h_next == NULL || (DUK_HEAPHDR_GET_PREV(heap, h_next) == h));\n\t}\n}\n#else\nDUK_INTERNAL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tDUK_UNREF(h);\n}\n#endif\n\nDUK_INTERNAL void duk_heaphdr_assert_valid(duk_heaphdr *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n}\n\n/* Assert validity of a heaphdr, including all subclasses. */\nDUK_INTERNAL void duk_heaphdr_assert_valid_subclassed(duk_heaphdr *h) {\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h_obj = (duk_hobject *) h;\n\t\tDUK_HOBJECT_ASSERT_VALID(h_obj);\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tDUK_HCOMPFUNC_ASSERT_VALID((duk_hcompfunc *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h_obj)) {\n\t\t\tDUK_HNATFUNC_ASSERT_VALID((duk_hnatfunc *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_DECENV(h_obj)) {\n\t\t\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_OBJENV(h_obj)) {\n\t\t\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID((duk_hbufobj *) h_obj);\n#endif\n\t\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h_obj)) {\n\t\t\tDUK_HBOUNDFUNC_ASSERT_VALID((duk_hboundfunc *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_PROXY(h_obj)) {\n\t\t\tDUK_HPROXY_ASSERT_VALID((duk_hproxy *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_THREAD(h_obj)) {\n\t\t\tDUK_HTHREAD_ASSERT_VALID((duk_hthread *) h_obj);\n\t\t} else {\n\t\t\t/* Just a plain object. */\n\t\t\t;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h_str = (duk_hstring *) h;\n\t\tDUK_HSTRING_ASSERT_VALID(h_str);\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h_buf = (duk_hbuffer *) h;\n\t\tDUK_HBUFFER_ASSERT_VALID(h_buf);\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tDUK_ASSERT(0);\n\t}\n\t}\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_henv.h",
    "content": "/*\n *  Environment object representation.\n */\n\n#if !defined(DUK_HENV_H_INCLUDED)\n#define DUK_HENV_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hdecenv_assert_valid(duk_hdecenv *h);\nDUK_INTERNAL_DECL void duk_hobjenv_assert_valid(duk_hobjenv *h);\n#define DUK_HDECENV_ASSERT_VALID(h)  do { duk_hdecenv_assert_valid((h)); } while (0)\n#define DUK_HOBJENV_ASSERT_VALID(h)  do { duk_hobjenv_assert_valid((h)); } while (0)\n#else\n#define DUK_HDECENV_ASSERT_VALID(h)  do {} while (0)\n#define DUK_HOBJENV_ASSERT_VALID(h)  do {} while (0)\n#endif\n\nstruct duk_hdecenv {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* These control variables provide enough information to access live\n\t * variables for a closure that is still open.  If thread == NULL,\n\t * the record is closed and the identifiers are in the property table.\n\t */\n\tduk_hthread *thread;\n\tduk_hobject *varmap;\n\tduk_size_t regbase_byteoff;\n};\n\nstruct duk_hobjenv {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Target object and 'this' binding for object binding. */\n\tduk_hobject *target;\n\n\t/* The 'target' object is used as a this binding in only some object\n\t * environments.  For example, the global environment does not provide\n\t * a this binding, but a with statement does.\n\t */\n\tduk_bool_t has_this;\n};\n\n#endif  /* DUK_HENV_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hnatfunc.h",
    "content": "/*\n *  Heap native function representation.\n */\n\n#if !defined(DUK_HNATFUNC_H_INCLUDED)\n#define DUK_HNATFUNC_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hnatfunc_assert_valid(duk_hnatfunc *h);\n#define DUK_HNATFUNC_ASSERT_VALID(h)  do { duk_hnatfunc_assert_valid((h)); } while (0)\n#else\n#define DUK_HNATFUNC_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n#define DUK_HNATFUNC_NARGS_VARARGS  ((duk_int16_t) -1)\n#define DUK_HNATFUNC_NARGS_MAX      ((duk_int16_t) 0x7fff)\n\nstruct duk_hnatfunc {\n\t/* shared object part */\n\tduk_hobject obj;\n\n\tduk_c_function func;\n\tduk_int16_t nargs;\n\tduk_int16_t magic;\n\n\t/* The 'magic' field allows an opaque 16-bit field to be accessed by the\n\t * Duktape/C function.  This allows, for instance, the same native function\n\t * to be used for a set of very similar functions, with the 'magic' field\n\t * providing the necessary non-argument flags / values to guide the behavior\n\t * of the native function.  The value is signed on purpose: it is easier to\n\t * convert a signed value to unsigned (simply AND with 0xffff) than vice\n\t * versa.\n\t *\n\t * Note: cannot place nargs/magic into the heaphdr flags, because\n\t * duk_hobject takes almost all flags already.\n\t */\n};\n\n#endif  /* DUK_HNATFUNC_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hobject.h",
    "content": "/*\n *  Heap object representation.\n *\n *  Heap objects are used for ECMAScript objects, arrays, and functions,\n *  but also for internal control like declarative and object environment\n *  records.  Compiled functions, native functions, and threads are also\n *  objects but with an extended C struct.\n *\n *  Objects provide the required ECMAScript semantics and exotic behaviors\n *  especially for property access.\n *\n *  Properties are stored in three conceptual parts:\n *\n *    1. A linear 'entry part' contains ordered key-value-attributes triples\n *       and is the main method of string properties.\n *\n *    2. An optional linear 'array part' is used for array objects to store a\n *       (dense) range of [0,N[ array indexed entries with default attributes\n *       (writable, enumerable, configurable).  If the array part would become\n *       sparse or non-default attributes are required, the array part is\n *       abandoned and moved to the 'entry part'.\n *\n *    3. An optional 'hash part' is used to optimize lookups of the entry\n *       part; it is used only for objects with sufficiently many properties\n *       and can be abandoned without loss of information.\n *\n *  These three conceptual parts are stored in a single memory allocated area.\n *  This minimizes memory allocation overhead but also means that all three\n *  parts are resized together, and makes property access a bit complicated.\n */\n\n#if !defined(DUK_HOBJECT_H_INCLUDED)\n#define DUK_HOBJECT_H_INCLUDED\n\n/* Object flags.  Make sure this stays in sync with debugger object\n * inspection code.\n */\n\n/* XXX: some flags are object subtype specific (e.g. common to all function\n * subtypes, duk_harray, etc) and could be reused for different subtypes.\n */\n#define DUK_HOBJECT_FLAG_EXTENSIBLE            DUK_HEAPHDR_USER_FLAG(0)   /* object is extensible */\n#define DUK_HOBJECT_FLAG_CONSTRUCTABLE         DUK_HEAPHDR_USER_FLAG(1)   /* object is constructable */\n#define DUK_HOBJECT_FLAG_CALLABLE              DUK_HEAPHDR_USER_FLAG(2)   /* object is callable */\n#define DUK_HOBJECT_FLAG_BOUNDFUNC             DUK_HEAPHDR_USER_FLAG(3)   /* object established using Function.prototype.bind() */\n#define DUK_HOBJECT_FLAG_COMPFUNC              DUK_HEAPHDR_USER_FLAG(4)   /* object is a compiled function (duk_hcompfunc) */\n#define DUK_HOBJECT_FLAG_NATFUNC               DUK_HEAPHDR_USER_FLAG(5)   /* object is a native function (duk_hnatfunc) */\n#define DUK_HOBJECT_FLAG_BUFOBJ                DUK_HEAPHDR_USER_FLAG(6)   /* object is a buffer object (duk_hbufobj) (always exotic) */\n#define DUK_HOBJECT_FLAG_FASTREFS              DUK_HEAPHDR_USER_FLAG(7)   /* object has no fields needing DECREF/marking beyond base duk_hobject header */\n#define DUK_HOBJECT_FLAG_ARRAY_PART            DUK_HEAPHDR_USER_FLAG(8)   /* object has an array part (a_size may still be 0) */\n#define DUK_HOBJECT_FLAG_STRICT                DUK_HEAPHDR_USER_FLAG(9)   /* function: function object is strict */\n#define DUK_HOBJECT_FLAG_NOTAIL                DUK_HEAPHDR_USER_FLAG(10)  /* function: function must not be tail called */\n#define DUK_HOBJECT_FLAG_NEWENV                DUK_HEAPHDR_USER_FLAG(11)  /* function: create new environment when called (see duk_hcompfunc) */\n#define DUK_HOBJECT_FLAG_NAMEBINDING           DUK_HEAPHDR_USER_FLAG(12)  /* function: create binding for func name (function templates only, used for named function expressions) */\n#define DUK_HOBJECT_FLAG_CREATEARGS            DUK_HEAPHDR_USER_FLAG(13)  /* function: create an arguments object on function call */\n#define DUK_HOBJECT_FLAG_HAVE_FINALIZER        DUK_HEAPHDR_USER_FLAG(14)  /* object has a callable (own) finalizer property */\n#define DUK_HOBJECT_FLAG_EXOTIC_ARRAY          DUK_HEAPHDR_USER_FLAG(15)  /* 'Array' object, array length and index exotic behavior */\n#define DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ      DUK_HEAPHDR_USER_FLAG(16)  /* 'String' object, array index exotic behavior */\n#define DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS      DUK_HEAPHDR_USER_FLAG(17)  /* 'Arguments' object and has arguments exotic behavior (non-strict callee) */\n#define DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ       DUK_HEAPHDR_USER_FLAG(18)  /* 'Proxy' object */\n#define DUK_HOBJECT_FLAG_SPECIAL_CALL          DUK_HEAPHDR_USER_FLAG(19)  /* special casing in call behavior, for .call(), .apply(), etc. */\n\n#define DUK_HOBJECT_FLAG_CLASS_BASE            DUK_HEAPHDR_USER_FLAG_NUMBER(20)\n#define DUK_HOBJECT_FLAG_CLASS_BITS            5\n\n#define DUK_HOBJECT_GET_CLASS_NUMBER(h)        \\\n\tDUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS)\n#define DUK_HOBJECT_SET_CLASS_NUMBER(h,v)      \\\n\tDUK_HEAPHDR_SET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS, (v))\n\n#define DUK_HOBJECT_GET_CLASS_MASK(h)          \\\n\t(1UL << DUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS))\n\n/* Macro for creating flag initializer from a class number.\n * Unsigned type cast is needed to avoid warnings about coercing\n * a signed integer to an unsigned one; the largest class values\n * have the highest bit (bit 31) set which causes this.\n */\n#define DUK_HOBJECT_CLASS_AS_FLAGS(v)          (((duk_uint_t) (v)) << DUK_HOBJECT_FLAG_CLASS_BASE)\n\n/* E5 Section 8.6.2 + custom classes */\n#define DUK_HOBJECT_CLASS_NONE                 0\n#define DUK_HOBJECT_CLASS_OBJECT               1\n#define DUK_HOBJECT_CLASS_ARRAY                2\n#define DUK_HOBJECT_CLASS_FUNCTION             3\n#define DUK_HOBJECT_CLASS_ARGUMENTS            4\n#define DUK_HOBJECT_CLASS_BOOLEAN              5\n#define DUK_HOBJECT_CLASS_DATE                 6\n#define DUK_HOBJECT_CLASS_ERROR                7\n#define DUK_HOBJECT_CLASS_JSON                 8\n#define DUK_HOBJECT_CLASS_MATH                 9\n#define DUK_HOBJECT_CLASS_NUMBER               10\n#define DUK_HOBJECT_CLASS_REGEXP               11\n#define DUK_HOBJECT_CLASS_STRING               12\n#define DUK_HOBJECT_CLASS_GLOBAL               13\n#define DUK_HOBJECT_CLASS_SYMBOL               14\n#define DUK_HOBJECT_CLASS_OBJENV               15  /* custom */\n#define DUK_HOBJECT_CLASS_DECENV               16  /* custom */\n#define DUK_HOBJECT_CLASS_POINTER              17  /* custom */\n#define DUK_HOBJECT_CLASS_THREAD               18  /* custom; implies DUK_HOBJECT_IS_THREAD */\n#define DUK_HOBJECT_CLASS_BUFOBJ_MIN           19\n#define DUK_HOBJECT_CLASS_ARRAYBUFFER          19  /* implies DUK_HOBJECT_IS_BUFOBJ */\n#define DUK_HOBJECT_CLASS_DATAVIEW             20\n#define DUK_HOBJECT_CLASS_INT8ARRAY            21\n#define DUK_HOBJECT_CLASS_UINT8ARRAY           22\n#define DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY    23\n#define DUK_HOBJECT_CLASS_INT16ARRAY           24\n#define DUK_HOBJECT_CLASS_UINT16ARRAY          25\n#define DUK_HOBJECT_CLASS_INT32ARRAY           26\n#define DUK_HOBJECT_CLASS_UINT32ARRAY          27\n#define DUK_HOBJECT_CLASS_FLOAT32ARRAY         28\n#define DUK_HOBJECT_CLASS_FLOAT64ARRAY         29\n#define DUK_HOBJECT_CLASS_BUFOBJ_MAX           29\n#define DUK_HOBJECT_CLASS_MAX                  29\n\n/* Class masks. */\n#define DUK_HOBJECT_CMASK_ALL                  ((1UL << (DUK_HOBJECT_CLASS_MAX + 1)) - 1UL)\n#define DUK_HOBJECT_CMASK_NONE                 (1UL << DUK_HOBJECT_CLASS_NONE)\n#define DUK_HOBJECT_CMASK_ARGUMENTS            (1UL << DUK_HOBJECT_CLASS_ARGUMENTS)\n#define DUK_HOBJECT_CMASK_ARRAY                (1UL << DUK_HOBJECT_CLASS_ARRAY)\n#define DUK_HOBJECT_CMASK_BOOLEAN              (1UL << DUK_HOBJECT_CLASS_BOOLEAN)\n#define DUK_HOBJECT_CMASK_DATE                 (1UL << DUK_HOBJECT_CLASS_DATE)\n#define DUK_HOBJECT_CMASK_ERROR                (1UL << DUK_HOBJECT_CLASS_ERROR)\n#define DUK_HOBJECT_CMASK_FUNCTION             (1UL << DUK_HOBJECT_CLASS_FUNCTION)\n#define DUK_HOBJECT_CMASK_JSON                 (1UL << DUK_HOBJECT_CLASS_JSON)\n#define DUK_HOBJECT_CMASK_MATH                 (1UL << DUK_HOBJECT_CLASS_MATH)\n#define DUK_HOBJECT_CMASK_NUMBER               (1UL << DUK_HOBJECT_CLASS_NUMBER)\n#define DUK_HOBJECT_CMASK_OBJECT               (1UL << DUK_HOBJECT_CLASS_OBJECT)\n#define DUK_HOBJECT_CMASK_REGEXP               (1UL << DUK_HOBJECT_CLASS_REGEXP)\n#define DUK_HOBJECT_CMASK_STRING               (1UL << DUK_HOBJECT_CLASS_STRING)\n#define DUK_HOBJECT_CMASK_GLOBAL               (1UL << DUK_HOBJECT_CLASS_GLOBAL)\n#define DUK_HOBJECT_CMASK_SYMBOL               (1UL << DUK_HOBJECT_CLASS_SYMBOL)\n#define DUK_HOBJECT_CMASK_OBJENV               (1UL << DUK_HOBJECT_CLASS_OBJENV)\n#define DUK_HOBJECT_CMASK_DECENV               (1UL << DUK_HOBJECT_CLASS_DECENV)\n#define DUK_HOBJECT_CMASK_POINTER              (1UL << DUK_HOBJECT_CLASS_POINTER)\n#define DUK_HOBJECT_CMASK_ARRAYBUFFER          (1UL << DUK_HOBJECT_CLASS_ARRAYBUFFER)\n#define DUK_HOBJECT_CMASK_DATAVIEW             (1UL << DUK_HOBJECT_CLASS_DATAVIEW)\n#define DUK_HOBJECT_CMASK_INT8ARRAY            (1UL << DUK_HOBJECT_CLASS_INT8ARRAY)\n#define DUK_HOBJECT_CMASK_UINT8ARRAY           (1UL << DUK_HOBJECT_CLASS_UINT8ARRAY)\n#define DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY    (1UL << DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY)\n#define DUK_HOBJECT_CMASK_INT16ARRAY           (1UL << DUK_HOBJECT_CLASS_INT16ARRAY)\n#define DUK_HOBJECT_CMASK_UINT16ARRAY          (1UL << DUK_HOBJECT_CLASS_UINT16ARRAY)\n#define DUK_HOBJECT_CMASK_INT32ARRAY           (1UL << DUK_HOBJECT_CLASS_INT32ARRAY)\n#define DUK_HOBJECT_CMASK_UINT32ARRAY          (1UL << DUK_HOBJECT_CLASS_UINT32ARRAY)\n#define DUK_HOBJECT_CMASK_FLOAT32ARRAY         (1UL << DUK_HOBJECT_CLASS_FLOAT32ARRAY)\n#define DUK_HOBJECT_CMASK_FLOAT64ARRAY         (1UL << DUK_HOBJECT_CLASS_FLOAT64ARRAY)\n\n#define DUK_HOBJECT_CMASK_ALL_BUFOBJS \\\n\t(DUK_HOBJECT_CMASK_ARRAYBUFFER | \\\n\t DUK_HOBJECT_CMASK_DATAVIEW | \\\n\t DUK_HOBJECT_CMASK_INT8ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT8ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY | \\\n\t DUK_HOBJECT_CMASK_INT16ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT16ARRAY | \\\n\t DUK_HOBJECT_CMASK_INT32ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT32ARRAY | \\\n\t DUK_HOBJECT_CMASK_FLOAT32ARRAY | \\\n\t DUK_HOBJECT_CMASK_FLOAT64ARRAY)\n\n#define DUK_HOBJECT_IS_OBJENV(h)               (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_OBJENV)\n#define DUK_HOBJECT_IS_DECENV(h)               (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_DECENV)\n#define DUK_HOBJECT_IS_ENV(h)                  (DUK_HOBJECT_IS_OBJENV((h)) || DUK_HOBJECT_IS_DECENV((h)))\n#define DUK_HOBJECT_IS_ARRAY(h)                DUK_HOBJECT_HAS_EXOTIC_ARRAY((h))  /* Rely on class Array <=> exotic Array */\n#define DUK_HOBJECT_IS_BOUNDFUNC(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_IS_COMPFUNC(h)             DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_IS_NATFUNC(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_IS_BUFOBJ(h)               DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#else\n#define DUK_HOBJECT_IS_BUFOBJ(h)               0\n#endif\n#define DUK_HOBJECT_IS_THREAD(h)               (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_THREAD)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_IS_PROXY(h)                DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ((h))\n#else\n#define DUK_HOBJECT_IS_PROXY(h)                0\n#endif\n\n#define DUK_HOBJECT_IS_NONBOUND_FUNCTION(h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \\\n                                                        DUK_HOBJECT_FLAG_COMPFUNC | \\\n                                                        DUK_HOBJECT_FLAG_NATFUNC)\n\n#define DUK_HOBJECT_IS_FUNCTION(h)             DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \\\n                                                        DUK_HOBJECT_FLAG_BOUNDFUNC | \\\n                                                        DUK_HOBJECT_FLAG_COMPFUNC | \\\n                                                        DUK_HOBJECT_FLAG_NATFUNC)\n\n#define DUK_HOBJECT_IS_CALLABLE(h)             DUK_HOBJECT_HAS_CALLABLE((h))\n\n/* Object has any exotic behavior(s). */\n#define DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS      (DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | \\\n                                                DUK_HOBJECT_FLAG_BUFOBJ | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#define DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR(h)     DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS)\n\n/* Object has any virtual properties (not counting Proxy behavior). */\n#define DUK_HOBJECT_VIRTUAL_PROPERTY_FLAGS     (DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | \\\n                                                DUK_HOBJECT_FLAG_BUFOBJ)\n#define DUK_HOBJECT_HAS_VIRTUAL_PROPERTIES(h)  DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_VIRTUAL_PROPERTY_FLAGS)\n\n#define DUK_HOBJECT_HAS_EXTENSIBLE(h)          DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)\n#define DUK_HOBJECT_HAS_CONSTRUCTABLE(h)       DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)\n#define DUK_HOBJECT_HAS_CALLABLE(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE)\n#define DUK_HOBJECT_HAS_BOUNDFUNC(h)           DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_HAS_COMPFUNC(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_HAS_NATFUNC(h)             DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_HAS_BUFOBJ(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#else\n#define DUK_HOBJECT_HAS_BUFOBJ(h)              0\n#endif\n#define DUK_HOBJECT_HAS_FASTREFS(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)\n#define DUK_HOBJECT_HAS_ARRAY_PART(h)          DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)\n#define DUK_HOBJECT_HAS_STRICT(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)\n#define DUK_HOBJECT_HAS_NOTAIL(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)\n#define DUK_HOBJECT_HAS_NEWENV(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)\n#define DUK_HOBJECT_HAS_NAMEBINDING(h)         DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)\n#define DUK_HOBJECT_HAS_CREATEARGS(h)          DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)\n#define DUK_HOBJECT_HAS_HAVE_FINALIZER(h)      DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER)\n#define DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)        DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)\n#define DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)\n#define DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)     DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#else\n#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)     0\n#endif\n#define DUK_HOBJECT_HAS_SPECIAL_CALL(h)        DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)\n\n#define DUK_HOBJECT_SET_EXTENSIBLE(h)          DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)\n#define DUK_HOBJECT_SET_CONSTRUCTABLE(h)       DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)\n#define DUK_HOBJECT_SET_CALLABLE(h)            DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE)\n#define DUK_HOBJECT_SET_BOUNDFUNC(h)           DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_SET_COMPFUNC(h)            DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_SET_NATFUNC(h)             DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_SET_BUFOBJ(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#endif\n#define DUK_HOBJECT_SET_FASTREFS(h)            DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)\n#define DUK_HOBJECT_SET_ARRAY_PART(h)          DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)\n#define DUK_HOBJECT_SET_STRICT(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)\n#define DUK_HOBJECT_SET_NOTAIL(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)\n#define DUK_HOBJECT_SET_NEWENV(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)\n#define DUK_HOBJECT_SET_NAMEBINDING(h)         DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)\n#define DUK_HOBJECT_SET_CREATEARGS(h)          DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)\n#define DUK_HOBJECT_SET_HAVE_FINALIZER(h)      DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER)\n#define DUK_HOBJECT_SET_EXOTIC_ARRAY(h)        DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)\n#define DUK_HOBJECT_SET_EXOTIC_STRINGOBJ(h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)\n#define DUK_HOBJECT_SET_EXOTIC_ARGUMENTS(h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_SET_EXOTIC_PROXYOBJ(h)     DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#endif\n#define DUK_HOBJECT_SET_SPECIAL_CALL(h)        DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)\n\n#define DUK_HOBJECT_CLEAR_EXTENSIBLE(h)        DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)\n#define DUK_HOBJECT_CLEAR_CONSTRUCTABLE(h)     DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)\n#define DUK_HOBJECT_CLEAR_CALLABLE(h)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE)\n#define DUK_HOBJECT_CLEAR_BOUNDFUNC(h)         DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_CLEAR_COMPFUNC(h)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_CLEAR_NATFUNC(h)           DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_CLEAR_BUFOBJ(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#endif\n#define DUK_HOBJECT_CLEAR_FASTREFS(h)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)\n#define DUK_HOBJECT_CLEAR_ARRAY_PART(h)        DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)\n#define DUK_HOBJECT_CLEAR_STRICT(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)\n#define DUK_HOBJECT_CLEAR_NOTAIL(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)\n#define DUK_HOBJECT_CLEAR_NEWENV(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)\n#define DUK_HOBJECT_CLEAR_NAMEBINDING(h)       DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)\n#define DUK_HOBJECT_CLEAR_CREATEARGS(h)        DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)\n#define DUK_HOBJECT_CLEAR_HAVE_FINALIZER(h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER)\n#define DUK_HOBJECT_CLEAR_EXOTIC_ARRAY(h)      DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)\n#define DUK_HOBJECT_CLEAR_EXOTIC_STRINGOBJ(h)  DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)\n#define DUK_HOBJECT_CLEAR_EXOTIC_ARGUMENTS(h)  DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_CLEAR_EXOTIC_PROXYOBJ(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#endif\n#define DUK_HOBJECT_CLEAR_SPECIAL_CALL(h)      DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)\n\n/* Object can/cannot use FASTREFS, i.e. has no strong reference fields beyond\n * duk_hobject base header.  This is used just for asserts so doesn't need to\n * be optimized.\n */\n#define DUK_HOBJECT_PROHIBITS_FASTREFS(h) \\\n\t(DUK_HOBJECT_IS_COMPFUNC((h)) || DUK_HOBJECT_IS_DECENV((h)) || DUK_HOBJECT_IS_OBJENV((h)) || \\\n\t DUK_HOBJECT_IS_BUFOBJ((h)) || DUK_HOBJECT_IS_THREAD((h)) || DUK_HOBJECT_IS_PROXY((h)) || \\\n\t DUK_HOBJECT_IS_BOUNDFUNC((h)))\n#define DUK_HOBJECT_ALLOWS_FASTREFS(h) (!DUK_HOBJECT_PROHIBITS_FASTREFS((h)))\n\n/* Flags used for property attributes in duk_propdesc and packed flags.\n * Must fit into 8 bits.\n */\n#define DUK_PROPDESC_FLAG_WRITABLE              (1U << 0)    /* E5 Section 8.6.1 */\n#define DUK_PROPDESC_FLAG_ENUMERABLE            (1U << 1)    /* E5 Section 8.6.1 */\n#define DUK_PROPDESC_FLAG_CONFIGURABLE          (1U << 2)    /* E5 Section 8.6.1 */\n#define DUK_PROPDESC_FLAG_ACCESSOR              (1U << 3)    /* accessor */\n#define DUK_PROPDESC_FLAG_VIRTUAL               (1U << 4)    /* property is virtual: used in duk_propdesc, never stored\n                                                             * (used by e.g. buffer virtual properties)\n                                                             */\n#define DUK_PROPDESC_FLAGS_MASK                 (DUK_PROPDESC_FLAG_WRITABLE | \\\n                                                 DUK_PROPDESC_FLAG_ENUMERABLE | \\\n                                                 DUK_PROPDESC_FLAG_CONFIGURABLE | \\\n                                                 DUK_PROPDESC_FLAG_ACCESSOR)\n\n/* Additional flags which are passed in the same flags argument as property\n * flags but are not stored in object properties.\n */\n#define DUK_PROPDESC_FLAG_NO_OVERWRITE          (1U << 4)    /* internal define property: skip write silently if exists */\n\n/* Convenience defines for property attributes. */\n#define DUK_PROPDESC_FLAGS_NONE                 0\n#define DUK_PROPDESC_FLAGS_W                    (DUK_PROPDESC_FLAG_WRITABLE)\n#define DUK_PROPDESC_FLAGS_E                    (DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_PROPDESC_FLAGS_C                    (DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_PROPDESC_FLAGS_WE                   (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_PROPDESC_FLAGS_WC                   (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_PROPDESC_FLAGS_EC                   (DUK_PROPDESC_FLAG_ENUMERABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_PROPDESC_FLAGS_WEC                  (DUK_PROPDESC_FLAG_WRITABLE | \\\n                                                 DUK_PROPDESC_FLAG_ENUMERABLE | \\\n                                                 DUK_PROPDESC_FLAG_CONFIGURABLE)\n\n/* Flags for duk_hobject_get_own_propdesc() and variants. */\n#define DUK_GETDESC_FLAG_PUSH_VALUE          (1U << 0)  /* push value to stack */\n#define DUK_GETDESC_FLAG_IGNORE_PROTOLOOP    (1U << 1)  /* don't throw for prototype loop */\n\n/*\n *  Macro for object validity check\n *\n *  Assert for currently guaranteed relations between flags, for instance.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hobject_assert_valid(duk_hobject *h);\n#define DUK_HOBJECT_ASSERT_VALID(h)  do { duk_hobject_assert_valid((h)); } while (0)\n#else\n#define DUK_HOBJECT_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Macros to access the 'props' allocation.\n */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HOBJECT_GET_PROPS(heap,h) \\\n\t((duk_uint8_t *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, ((duk_heaphdr *) (h))->h_extra16))\n#define DUK_HOBJECT_SET_PROPS(heap,h,x) do { \\\n\t\t((duk_heaphdr *) (h))->h_extra16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \\\n\t} while (0)\n#else\n#define DUK_HOBJECT_GET_PROPS(heap,h) \\\n\t((h)->props)\n#define DUK_HOBJECT_SET_PROPS(heap,h,x) do { \\\n\t\t(h)->props = (duk_uint8_t *) (x); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_HOBJECT_LAYOUT_1)\n/* LAYOUT 1 */\n#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \\\n\t((duk_hstring **) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) \\\n\t))\n#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \\\n\t((duk_propvalue *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_hstring *) \\\n\t))\n#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \\\n\t((duk_uint8_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \\\n\t))\n#define DUK_HOBJECT_A_GET_BASE(heap,h) \\\n\t((duk_tval *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) \\\n\t))\n#define DUK_HOBJECT_H_GET_BASE(heap,h) \\\n\t((duk_uint32_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \\\n\t( \\\n\t\t(n_ent) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t(n_arr) * sizeof(duk_tval) + \\\n\t\t(n_hash) * sizeof(duk_uint32_t) \\\n\t)\n#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash)  do { \\\n\t\t(set_e_k) = (duk_hstring **) (void *) (p_base); \\\n\t\t(set_e_pv) = (duk_propvalue *) (void *) ((set_e_k) + (n_ent)); \\\n\t\t(set_e_f) = (duk_uint8_t *) (void *) ((set_e_pv) + (n_ent)); \\\n\t\t(set_a) = (duk_tval *) (void *) ((set_e_f) + (n_ent)); \\\n\t\t(set_h) = (duk_uint32_t *) (void *) ((set_a) + (n_arr)); \\\n\t} while (0)\n#elif defined(DUK_USE_HOBJECT_LAYOUT_2)\n/* LAYOUT 2 */\n#if (DUK_USE_ALIGN_BY == 4)\n#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) ((4 - (e_sz)) & 0x03)\n#elif (DUK_USE_ALIGN_BY == 8)\n#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) ((8 - (e_sz)) & 0x07)\n#elif (DUK_USE_ALIGN_BY == 1)\n#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) 0\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \\\n\t((duk_hstring **) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) \\\n\t))\n#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \\\n\t((duk_propvalue *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) \\\n\t))\n#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \\\n\t((duk_uint8_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \\\n\t))\n#define DUK_HOBJECT_A_GET_BASE(heap,h) \\\n\t((duk_tval *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t\tDUK_HOBJECT_E_FLAG_PADDING(DUK_HOBJECT_GET_ESIZE((h))) \\\n\t))\n#define DUK_HOBJECT_H_GET_BASE(heap,h) \\\n\t((duk_uint32_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t\tDUK_HOBJECT_E_FLAG_PADDING(DUK_HOBJECT_GET_ESIZE((h))) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \\\n\t( \\\n\t\t(n_ent) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\tDUK_HOBJECT_E_FLAG_PADDING((n_ent)) + \\\n\t\t(n_arr) * sizeof(duk_tval) + \\\n\t\t(n_hash) * sizeof(duk_uint32_t) \\\n\t)\n#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash)  do { \\\n\t\t(set_e_pv) = (duk_propvalue *) (void *) (p_base); \\\n\t\t(set_e_k) = (duk_hstring **) (void *) ((set_e_pv) + (n_ent)); \\\n\t\t(set_e_f) = (duk_uint8_t *) (void *) ((set_e_k) + (n_ent)); \\\n\t\t(set_a) = (duk_tval *) (void *) (((duk_uint8_t *) (set_e_f)) + \\\n\t\t                                 sizeof(duk_uint8_t) * (n_ent) + \\\n\t\t                                 DUK_HOBJECT_E_FLAG_PADDING((n_ent))); \\\n\t\t(set_h) = (duk_uint32_t *) (void *) ((set_a) + (n_arr)); \\\n\t} while (0)\n#elif defined(DUK_USE_HOBJECT_LAYOUT_3)\n/* LAYOUT 3 */\n#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \\\n\t((duk_hstring **) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \\\n\t((duk_propvalue *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) \\\n\t))\n#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \\\n\t((duk_uint8_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_propvalue) + sizeof(duk_hstring *)) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) + \\\n\t\t\tDUK_HOBJECT_GET_HSIZE((h)) * sizeof(duk_uint32_t) \\\n\t))\n#define DUK_HOBJECT_A_GET_BASE(heap,h) \\\n\t((duk_tval *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) \\\n\t))\n#define DUK_HOBJECT_H_GET_BASE(heap,h) \\\n\t((duk_uint32_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_propvalue) + sizeof(duk_hstring *)) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \\\n\t( \\\n\t\t(n_ent) * (sizeof(duk_propvalue) + sizeof(duk_hstring *) + sizeof(duk_uint8_t)) + \\\n\t\t(n_arr) * sizeof(duk_tval) + \\\n\t\t(n_hash) * sizeof(duk_uint32_t) \\\n\t)\n#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash)  do { \\\n\t\t(set_e_pv) = (duk_propvalue *) (void *) (p_base); \\\n\t\t(set_a) = (duk_tval *) (void *) ((set_e_pv) + (n_ent)); \\\n\t\t(set_e_k) = (duk_hstring **) (void *) ((set_a) + (n_arr)); \\\n\t\t(set_h) = (duk_uint32_t *) (void *) ((set_e_k) + (n_ent)); \\\n\t\t(set_e_f) = (duk_uint8_t *) (void *) ((set_h) + (n_hash)); \\\n\t} while (0)\n#else\n#error invalid hobject layout defines\n#endif  /* hobject property layout */\n\n#define DUK_HOBJECT_P_ALLOC_SIZE(h) \\\n\tDUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE((h)), DUK_HOBJECT_GET_ASIZE((h)), DUK_HOBJECT_GET_HSIZE((h)))\n\n#define DUK_HOBJECT_E_GET_KEY(heap,h,i)              (DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_KEY_PTR(heap,h,i)          (&DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_VALUE(heap,h,i)            (DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_VALUE_PTR(heap,h,i)        (&DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_VALUE_TVAL(heap,h,i)       (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)\n#define DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap,h,i)   (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)\n#define DUK_HOBJECT_E_GET_VALUE_GETTER(heap,h,i)     (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)\n#define DUK_HOBJECT_E_GET_VALUE_GETTER_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)\n#define DUK_HOBJECT_E_GET_VALUE_SETTER(heap,h,i)     (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)\n#define DUK_HOBJECT_E_GET_VALUE_SETTER_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)\n#define DUK_HOBJECT_E_GET_FLAGS(heap,h,i)            (DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_FLAGS_PTR(heap,h,i)        (&DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_A_GET_VALUE(heap,h,i)            (DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_A_GET_VALUE_PTR(heap,h,i)        (&DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_H_GET_INDEX(heap,h,i)            (DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_H_GET_INDEX_PTR(heap,h,i)        (&DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])\n\n#define DUK_HOBJECT_E_SET_KEY(heap,h,i,k)  do { \\\n\t\tDUK_HOBJECT_E_GET_KEY((heap), (h), (i)) = (k); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)) = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE_TVAL(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE_GETTER(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE_SETTER(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_FLAGS(heap,h,i,f)  do { \\\n\t\tDUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) = (duk_uint8_t) (f); \\\n\t} while (0)\n#define DUK_HOBJECT_A_SET_VALUE(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_A_GET_VALUE((heap), (h), (i)) = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_A_SET_VALUE_TVAL(heap,h,i,v) \\\n\tDUK_HOBJECT_A_SET_VALUE((heap), (h), (i), (v))  /* alias for above */\n#define DUK_HOBJECT_H_SET_INDEX(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_H_GET_INDEX((heap), (h), (i)) = (v); \\\n\t} while (0)\n\n#define DUK_HOBJECT_E_SET_FLAG_BITS(heap,h,i,mask)  do { \\\n\t\tDUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] |= (mask); \\\n\t} while (0)\n\n#define DUK_HOBJECT_E_CLEAR_FLAG_BITS(heap,h,i,mask)  do { \\\n\t\tDUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] &= ~(mask); \\\n\t} while (0)\n\n#define DUK_HOBJECT_E_SLOT_IS_WRITABLE(heap,h,i)     ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_WRITABLE) != 0)\n#define DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(heap,h,i)   ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)\n#define DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)\n#define DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap,h,i)     ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ACCESSOR) != 0)\n\n#define DUK_HOBJECT_E_SLOT_SET_WRITABLE(heap,h,i)        DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)\n#define DUK_HOBJECT_E_SLOT_SET_ENUMERABLE(heap,h,i)      DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_HOBJECT_E_SLOT_SET_CONFIGURABLE(heap,h,i)    DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_HOBJECT_E_SLOT_SET_ACCESSOR(heap,h,i)        DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)\n\n#define DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(heap,h,i)      DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)\n#define DUK_HOBJECT_E_SLOT_CLEAR_ENUMERABLE(heap,h,i)    DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_HOBJECT_E_SLOT_CLEAR_CONFIGURABLE(heap,h,i)  DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(heap,h,i)      DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)\n\n#define DUK_PROPDESC_IS_WRITABLE(p)             (((p)->flags & DUK_PROPDESC_FLAG_WRITABLE) != 0)\n#define DUK_PROPDESC_IS_ENUMERABLE(p)           (((p)->flags & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)\n#define DUK_PROPDESC_IS_CONFIGURABLE(p)         (((p)->flags & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)\n#define DUK_PROPDESC_IS_ACCESSOR(p)             (((p)->flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0)\n\n#define DUK_HOBJECT_HASHIDX_UNUSED              0xffffffffUL\n#define DUK_HOBJECT_HASHIDX_DELETED             0xfffffffeUL\n\n/*\n *  Macros for accessing size fields\n */\n\n#if defined(DUK_USE_OBJSIZES16)\n#define DUK_HOBJECT_GET_ESIZE(h) ((h)->e_size16)\n#define DUK_HOBJECT_SET_ESIZE(h,v) do { (h)->e_size16 = (v); } while (0)\n#define DUK_HOBJECT_GET_ENEXT(h) ((h)->e_next16)\n#define DUK_HOBJECT_SET_ENEXT(h,v) do { (h)->e_next16 = (v); } while (0)\n#define DUK_HOBJECT_POSTINC_ENEXT(h) ((h)->e_next16++)\n#define DUK_HOBJECT_GET_ASIZE(h) ((h)->a_size16)\n#define DUK_HOBJECT_SET_ASIZE(h,v) do { (h)->a_size16 = (v); } while (0)\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n#define DUK_HOBJECT_GET_HSIZE(h) ((h)->h_size16)\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { (h)->h_size16 = (v); } while (0)\n#else\n#define DUK_HOBJECT_GET_HSIZE(h) 0\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { DUK_ASSERT((v) == 0); } while (0)\n#endif\n#else\n#define DUK_HOBJECT_GET_ESIZE(h) ((h)->e_size)\n#define DUK_HOBJECT_SET_ESIZE(h,v) do { (h)->e_size = (v); } while (0)\n#define DUK_HOBJECT_GET_ENEXT(h) ((h)->e_next)\n#define DUK_HOBJECT_SET_ENEXT(h,v) do { (h)->e_next = (v); } while (0)\n#define DUK_HOBJECT_POSTINC_ENEXT(h) ((h)->e_next++)\n#define DUK_HOBJECT_GET_ASIZE(h) ((h)->a_size)\n#define DUK_HOBJECT_SET_ASIZE(h,v) do { (h)->a_size = (v); } while (0)\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n#define DUK_HOBJECT_GET_HSIZE(h) ((h)->h_size)\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { (h)->h_size = (v); } while (0)\n#else\n#define DUK_HOBJECT_GET_HSIZE(h) 0\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { DUK_ASSERT((v) == 0); } while (0)\n#endif\n#endif\n\n/*\n *  Misc\n */\n\n/* Maximum prototype traversal depth.  Sanity limit which handles e.g.\n * prototype loops (even complex ones like 1->2->3->4->2->3->4->2->3->4).\n */\n#define DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY      10000L\n\n/*\n *  ECMAScript [[Class]]\n */\n\n/* range check not necessary because all 4-bit values are mapped */\n#define DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(n)  duk_class_number_to_stridx[(n)]\n\n#define DUK_HOBJECT_GET_CLASS_STRING(heap,h)          \\\n\tDUK_HEAP_GET_STRING( \\\n\t\t(heap), \\\n\t\tDUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(DUK_HOBJECT_GET_CLASS_NUMBER((h))) \\\n\t)\n\n/*\n *  Macros for property handling\n */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HOBJECT_GET_PROTOTYPE(heap,h) \\\n\t((duk_hobject *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->prototype16))\n#define DUK_HOBJECT_SET_PROTOTYPE(heap,h,x) do { \\\n\t\t(h)->prototype16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \\\n\t} while (0)\n#else\n#define DUK_HOBJECT_GET_PROTOTYPE(heap,h) \\\n\t((h)->prototype)\n#define DUK_HOBJECT_SET_PROTOTYPE(heap,h,x) do { \\\n\t\t(h)->prototype = (x); \\\n\t} while (0)\n#endif\n\n/* Set prototype, DECREF earlier value, INCREF new value (tolerating NULLs). */\n#define DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr,h,p)       duk_hobject_set_prototype_updref((thr), (h), (p))\n\n/* Set initial prototype, assume NULL previous prototype, INCREF new value,\n * tolerate NULL.\n */\n#define DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr,h,proto) do { \\\n\t\tduk_hthread *duk__thr = (thr); \\\n\t\tduk_hobject *duk__obj = (h); \\\n\t\tduk_hobject *duk__proto = (proto); \\\n\t\tDUK_UNREF(duk__thr); \\\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(duk__thr->heap, duk__obj) == NULL); \\\n\t\tDUK_HOBJECT_SET_PROTOTYPE(duk__thr->heap, duk__obj, duk__proto); \\\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(duk__thr, duk__proto); \\\n\t} while (0)\n\n/*\n *  Finalizer check\n */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HOBJECT_HAS_FINALIZER_FAST(heap,h) duk_hobject_has_finalizer_fast_raw((heap), (h))\n#else\n#define DUK_HOBJECT_HAS_FINALIZER_FAST(heap,h) duk_hobject_has_finalizer_fast_raw((h))\n#endif\n\n/*\n *  Resizing and hash behavior\n */\n\n/* Sanity limit on max number of properties (allocated, not necessarily used).\n * This is somewhat arbitrary, but if we're close to 2**32 properties some\n * algorithms will fail (e.g. hash size selection, next prime selection).\n * Also, we use negative array/entry table indices to indicate 'not found',\n * so anything above 0x80000000 will cause trouble now.\n */\n#if defined(DUK_USE_OBJSIZES16)\n#define DUK_HOBJECT_MAX_PROPERTIES       0x0000ffffUL\n#else\n#define DUK_HOBJECT_MAX_PROPERTIES       0x3fffffffUL   /* 2**30-1 ~= 1G properties */\n#endif\n\n/* internal align target for props allocation, must be 2*n for some n */\n#if (DUK_USE_ALIGN_BY == 4)\n#define DUK_HOBJECT_ALIGN_TARGET         4\n#elif (DUK_USE_ALIGN_BY == 8)\n#define DUK_HOBJECT_ALIGN_TARGET         8\n#elif (DUK_USE_ALIGN_BY == 1)\n#define DUK_HOBJECT_ALIGN_TARGET         1\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\n/*\n *  PC-to-line constants\n */\n\n#define DUK_PC2LINE_SKIP    64\n\n/* maximum length for a SKIP-1 diffstream: 35 bits per entry, rounded up to bytes */\n#define DUK_PC2LINE_MAX_DIFF_LENGTH    (((DUK_PC2LINE_SKIP - 1) * 35 + 7) / 8)\n\n/*\n *  Struct defs\n */\n\nstruct duk_propaccessor {\n\tduk_hobject *get;\n\tduk_hobject *set;\n};\n\nunion duk_propvalue {\n\t/* The get/set pointers could be 16-bit pointer compressed but it\n\t * would make no difference on 32-bit platforms because duk_tval is\n\t * 8 bytes or more anyway.\n\t */\n\tduk_tval v;\n\tduk_propaccessor a;\n};\n\nstruct duk_propdesc {\n\t/* read-only values 'lifted' for ease of use */\n\tduk_small_uint_t flags;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\n\t/* for updating (all are set to < 0 for virtual properties) */\n\tduk_int_t e_idx;  /* prop index in 'entry part', < 0 if not there */\n\tduk_int_t h_idx;  /* prop index in 'hash part', < 0 if not there */\n\tduk_int_t a_idx;  /* prop index in 'array part', < 0 if not there */\n};\n\nstruct duk_hobject {\n\tduk_heaphdr hdr;\n\n\t/*\n\t *  'props' contains {key,value,flags} entries, optional array entries, and\n\t *  an optional hash lookup table for non-array entries in a single 'sliced'\n\t *  allocation.  There are several layout options, which differ slightly in\n\t *  generated code size/speed and alignment/padding; duk_features.h selects\n\t *  the layout used.\n\t *\n\t *  Layout 1 (DUK_USE_HOBJECT_LAYOUT_1):\n\t *\n\t *    e_size * sizeof(duk_hstring *)         bytes of   entry keys (e_next gc reachable)\n\t *    e_size * sizeof(duk_propvalue)         bytes of   entry values (e_next gc reachable)\n\t *    e_size * sizeof(duk_uint8_t)           bytes of   entry flags (e_next gc reachable)\n\t *    a_size * sizeof(duk_tval)              bytes of   (opt) array values (plain only) (all gc reachable)\n\t *    h_size * sizeof(duk_uint32_t)          bytes of   (opt) hash indexes to entries (e_size),\n\t *                                                      0xffffffffUL = unused, 0xfffffffeUL = deleted\n\t *\n\t *  Layout 2 (DUK_USE_HOBJECT_LAYOUT_2):\n\t *\n\t *    e_size * sizeof(duk_propvalue)         bytes of   entry values (e_next gc reachable)\n\t *    e_size * sizeof(duk_hstring *)         bytes of   entry keys (e_next gc reachable)\n\t *    e_size * sizeof(duk_uint8_t) + pad     bytes of   entry flags (e_next gc reachable)\n\t *    a_size * sizeof(duk_tval)              bytes of   (opt) array values (plain only) (all gc reachable)\n\t *    h_size * sizeof(duk_uint32_t)          bytes of   (opt) hash indexes to entries (e_size),\n\t *                                                      0xffffffffUL = unused, 0xfffffffeUL = deleted\n\t *\n\t *  Layout 3 (DUK_USE_HOBJECT_LAYOUT_3):\n\t *\n\t *    e_size * sizeof(duk_propvalue)         bytes of   entry values (e_next gc reachable)\n\t *    a_size * sizeof(duk_tval)              bytes of   (opt) array values (plain only) (all gc reachable)\n\t *    e_size * sizeof(duk_hstring *)         bytes of   entry keys (e_next gc reachable)\n\t *    h_size * sizeof(duk_uint32_t)          bytes of   (opt) hash indexes to entries (e_size),\n\t *                                                      0xffffffffUL = unused, 0xfffffffeUL = deleted\n\t *    e_size * sizeof(duk_uint8_t)           bytes of   entry flags (e_next gc reachable)\n\t *\n\t *  In layout 1, the 'e_next' count is rounded to 4 or 8 on platforms\n\t *  requiring 4 or 8 byte alignment.  This ensures proper alignment\n\t *  for the entries, at the cost of memory footprint.  However, it's\n\t *  probably preferable to use another layout on such platforms instead.\n\t *\n\t *  In layout 2, the key and value parts are swapped to avoid padding\n\t *  the key array on platforms requiring alignment by 8.  The flags part\n\t *  is padded to get alignment for array entries.  The 'e_next' count does\n\t *  not need to be rounded as in layout 1.\n\t *\n\t *  In layout 3, entry values and array values are always aligned properly,\n\t *  and assuming pointers are at most 8 bytes, so are the entry keys.  Hash\n\t *  indices will be properly aligned (assuming pointers are at least 4 bytes).\n\t *  Finally, flags don't need additional alignment.  This layout provides\n\t *  compact allocations without padding (even on platforms with alignment\n\t *  requirements) at the cost of a bit slower lookups.\n\t *\n\t *  Objects with few keys don't have a hash index; keys are looked up linearly,\n\t *  which is cache efficient because the keys are consecutive.  Larger objects\n\t *  have a hash index part which contains integer indexes to the entries part.\n\t *\n\t *  A single allocation reduces memory allocation overhead but requires more\n\t *  work when any part needs to be resized.  A sliced allocation for entries\n\t *  makes linear key matching faster on most platforms (more locality) and\n\t *  skimps on flags size (which would be followed by 3 bytes of padding in\n\t *  most architectures if entries were placed in a struct).\n\t *\n\t *  'props' also contains internal properties distinguished with a non-BMP\n\t *  prefix.  Often used properties should be placed early in 'props' whenever\n\t *  possible to make accessing them as fast a possible.\n\t */\n\n#if defined(DUK_USE_HEAPPTR16)\n\t/* Located in duk_heaphdr h_extra16.  Subclasses of duk_hobject (like\n\t * duk_hcompfunc) are not free to use h_extra16 for this reason.\n\t */\n#else\n\tduk_uint8_t *props;\n#endif\n\n\t/* prototype: the only internal property lifted outside 'e' as it is so central */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t prototype16;\n#else\n\tduk_hobject *prototype;\n#endif\n\n#if defined(DUK_USE_OBJSIZES16)\n\tduk_uint16_t e_size16;\n\tduk_uint16_t e_next16;\n\tduk_uint16_t a_size16;\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tduk_uint16_t h_size16;\n#endif\n#else\n\tduk_uint32_t e_size;  /* entry part size */\n\tduk_uint32_t e_next;  /* index for next new key ([0,e_next[ are gc reachable) */\n\tduk_uint32_t a_size;  /* array part size (entirely gc reachable) */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tduk_uint32_t h_size;  /* hash part size or 0 if unused */\n#endif\n#endif\n};\n\n/*\n *  Exposed data\n */\n\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL duk_uint8_t duk_class_number_to_stridx[32];\n#endif  /* !DUK_SINGLE_FILE */\n\n/*\n *  Prototypes\n */\n\n/* alloc and init */\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_harray *duk_harray_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_hcompfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_hnatfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hboundfunc *duk_hboundfunc_alloc(duk_heap *heap, duk_uint_t hobject_flags);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL_DECL duk_hbufobj *duk_hbufobj_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\n#endif\nDUK_INTERNAL_DECL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hthread *duk_hthread_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hdecenv *duk_hdecenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hobjenv *duk_hobjenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hproxy *duk_hproxy_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\n\n/* resize */\nDUK_INTERNAL_DECL void duk_hobject_realloc_props(duk_hthread *thr,\n                                                 duk_hobject *obj,\n                                                 duk_uint32_t new_e_size,\n                                                 duk_uint32_t new_a_size,\n                                                 duk_uint32_t new_h_size,\n                                                 duk_bool_t abandon_array);\nDUK_INTERNAL_DECL void duk_hobject_resize_entrypart(duk_hthread *thr,\n                                                    duk_hobject *obj,\n                                                    duk_uint32_t new_e_size);\n#if 0  /*unused*/\nDUK_INTERNAL_DECL void duk_hobject_resize_arraypart(duk_hthread *thr,\n                                                    duk_hobject *obj,\n                                                    duk_uint32_t new_a_size);\n#endif\n\n/* low-level property functions */\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_find_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_get_own_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags);\n\n/* core property functions */\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_tval *tv_val, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key);\n\n/* internal property functions */\n#define DUK_DELPROP_FLAG_THROW  (1U << 0)\n#define DUK_DELPROP_FLAG_FORCE  (1U << 1)\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key);\nDUK_INTERNAL_DECL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags);\nDUK_INTERNAL_DECL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj);\n#if defined(DUK_USE_HEAPPTR16)\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_heap *heap, duk_hobject *obj);\n#else\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_hobject *obj);\n#endif\n\n/* helpers for defineProperty() and defineProperties() */\nDUK_INTERNAL_DECL void duk_hobject_prepare_property_descriptor(duk_hthread *thr,\n                                                               duk_idx_t idx_in,\n                                                               duk_uint_t *out_defprop_flags,\n                                                               duk_idx_t *out_idx_value,\n                                                               duk_hobject **out_getter,\n                                                               duk_hobject **out_setter);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,\n                                                                duk_uint_t defprop_flags,\n                                                                duk_hobject *obj,\n                                                                duk_hstring *key,\n                                                                duk_idx_t idx_value,\n                                                                duk_hobject *get,\n                                                                duk_hobject *set,\n                                                                duk_bool_t throw_flag);\n\n/* Object built-in methods */\nDUK_INTERNAL_DECL void duk_hobject_object_get_own_property_descriptor(duk_hthread *thr, duk_idx_t obj_idx);\nDUK_INTERNAL_DECL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_object_ownprop_helper(duk_hthread *thr, duk_small_uint_t required_desc_flags);\n\n/* internal properties */\nDUK_INTERNAL_DECL duk_tval *duk_hobject_get_internal_value_tval_ptr(duk_heap *heap, duk_hobject *obj);\nDUK_INTERNAL_DECL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *heap, duk_hobject *obj);\nDUK_INTERNAL_DECL duk_harray *duk_hobject_get_formals(duk_hthread *thr, duk_hobject *obj);\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_get_varmap(duk_hthread *thr, duk_hobject *obj);\n\n/* hobject management functions */\nDUK_INTERNAL_DECL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj);\n\n/* ES2015 proxy */\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_proxy_check(duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler);\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_resolve_proxy_target(duk_hobject *obj);\n#endif\n\n/* enumeration */\nDUK_INTERNAL_DECL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint_t enum_flags);\nDUK_INTERNAL_DECL duk_ret_t duk_hobject_get_enumerated_keys(duk_hthread *thr, duk_small_uint_t enum_flags);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_enumerator_next(duk_hthread *thr, duk_bool_t get_value);\n\n/* macros */\nDUK_INTERNAL_DECL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject *h, duk_hobject *p);\n\n/* pc2line */\n#if defined(DUK_USE_PC2LINE)\nDUK_INTERNAL_DECL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr *instrs, duk_uint_fast32_t length);\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_hobject_pc2line_query(duk_hthread *thr, duk_idx_t idx_func, duk_uint_fast32_t pc);\n#endif\n\n/* misc */\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, duk_hobject *h, duk_hobject *p, duk_bool_t ignore_loop);\n\n#if !defined(DUK_USE_OBJECT_BUILTIN)\n/* These declarations are needed when related built-in is disabled and\n * genbuiltins.py won't automatically emit the declerations.\n */\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_string(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_hthread *thr);\n#endif\n\n#endif  /* DUK_HOBJECT_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hobject_alloc.c",
    "content": "/*\n *  Hobject allocation.\n *\n *  Provides primitive allocation functions for all object types (plain object,\n *  compiled function, native function, thread).  The object return is not yet\n *  in \"heap allocated\" list and has a refcount of zero, so caller must careful.\n */\n\n/* XXX: In most cases there's no need for plain allocation without pushing\n * to the value stack.  Maybe rework contract?\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Helpers.\n */\n\nDUK_LOCAL void duk__init_object_parts(duk_heap *heap, duk_uint_t hobject_flags, duk_hobject *obj) {\n\tDUK_ASSERT(obj != NULL);\n\t/* Zeroed by caller. */\n\n\tobj->hdr.h_flags = hobject_flags | DUK_HTYPE_OBJECT;\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(&obj->hdr) == DUK_HTYPE_OBJECT);  /* Assume zero shift. */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tDUK_HOBJECT_SET_PROTOTYPE(heap, obj, NULL);\n\tDUK_HOBJECT_SET_PROPS(heap, obj, NULL);\n#endif\n#if defined(DUK_USE_HEAPPTR16)\n\t/* Zero encoded pointer is required to match NULL. */\n\tDUK_HEAPHDR_SET_NEXT(heap, &obj->hdr, NULL);\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tDUK_HEAPHDR_SET_PREV(heap, &obj->hdr, NULL);\n#endif\n#endif\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, &obj->hdr);\n\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &obj->hdr);\n\n\t/* obj->props is intentionally left as NULL, and duk_hobject_props.c must deal\n\t * with this properly.  This is intentional: empty objects consume a minimum\n\t * amount of memory.  Further, an initial allocation might fail and cause\n\t * 'obj' to \"leak\" (require a mark-and-sweep) since it is not reachable yet.\n\t */\n}\n\nDUK_LOCAL void *duk__hobject_alloc_init(duk_hthread *thr, duk_uint_t hobject_flags, duk_size_t size) {\n\tvoid *res;\n\n\tres = (void *) DUK_ALLOC_CHECKED_ZEROED(thr, size);\n\tDUK_ASSERT(res != NULL);\n\tduk__init_object_parts(thr->heap, hobject_flags, (duk_hobject *) res);\n\treturn res;\n}\n\n/*\n *  Allocate an duk_hobject.\n *\n *  The allocated object has no allocation for properties; the caller may\n *  want to force a resize if a desired size is known.\n *\n *  The allocated object has zero reference count and is not reachable.\n *  The caller MUST make the object reachable and increase its reference\n *  count before invoking any operation that might require memory allocation.\n */\n\nDUK_INTERNAL duk_hobject *duk_hobject_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags) {\n\tduk_hobject *res;\n\n\tDUK_ASSERT(heap != NULL);\n\n\t/* different memory layout, alloc size, and init */\n\tDUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_COMPFUNC) == 0);\n\tDUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_NATFUNC) == 0);\n\tDUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_BOUNDFUNC) == 0);\n\n\tres = (duk_hobject *) DUK_ALLOC_ZEROED(heap, sizeof(duk_hobject));\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\treturn NULL;\n\t}\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(res));\n\n\tduk__init_object_parts(heap, hobject_flags, res);\n\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(res));\n\treturn res;\n}\n\nDUK_INTERNAL duk_hobject *duk_hobject_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hobject *res;\n\n\tres = (duk_hobject *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hobject));\n\treturn res;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_hcompfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hcompfunc *res;\n\n\tres = (duk_hcompfunc *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hcompfunc));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_HEAPPTR16)\n\t/* NULL pointer is required to encode to zero, so memset is enough. */\n#else\n\tres->data = NULL;\n\tres->funcs = NULL;\n\tres->bytecode = NULL;\n#endif\n\tres->lex_env = NULL;\n\tres->var_env = NULL;\n#endif\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_hnatfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hnatfunc *res;\n\n\tres = (duk_hnatfunc *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hnatfunc));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->func = NULL;\n#endif\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hboundfunc *duk_hboundfunc_alloc(duk_heap *heap, duk_uint_t hobject_flags) {\n\tduk_hboundfunc *res;\n\n\tres = (duk_hboundfunc *) DUK_ALLOC(heap, sizeof(duk_hboundfunc));\n\tif (!res) {\n\t\treturn NULL;\n\t}\n\tduk_memzero(res, sizeof(duk_hboundfunc));\n\n\tduk__init_object_parts(heap, hobject_flags, &res->obj);\n\n\tDUK_TVAL_SET_UNDEFINED(&res->target);\n\tDUK_TVAL_SET_UNDEFINED(&res->this_binding);\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->args = NULL;\n#endif\n\n\treturn res;\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_hbufobj *duk_hbufobj_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hbufobj *res;\n\n\tres = (duk_hbufobj *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hbufobj));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->buf = NULL;\n\tres->buf_prop = NULL;\n#endif\n\n\tDUK_HBUFOBJ_ASSERT_VALID(res);\n\treturn res;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* Allocate a new thread.\n *\n * Leaves the built-ins array uninitialized.  The caller must either\n * initialize a new global context or share existing built-ins from\n * another thread.\n */\nDUK_INTERNAL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags) {\n\tduk_hthread *res;\n\n\tres = (duk_hthread *) DUK_ALLOC(heap, sizeof(duk_hthread));\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\treturn NULL;\n\t}\n\tduk_memzero(res, sizeof(duk_hthread));\n\n\tduk__init_object_parts(heap, hobject_flags, &res->obj);\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->ptr_curr_pc = NULL;\n\tres->heap = NULL;\n\tres->valstack = NULL;\n\tres->valstack_end = NULL;\n\tres->valstack_alloc_end = NULL;\n\tres->valstack_bottom = NULL;\n\tres->valstack_top = NULL;\n\tres->callstack_curr = NULL;\n\tres->resumer = NULL;\n\tres->compile_ctx = NULL,\n#if defined(DUK_USE_HEAPPTR16)\n\tres->strs16 = NULL;\n#else\n\tres->strs = NULL;\n#endif\n\t{\n\t\tduk_small_uint_t i;\n\t\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\t\tres->builtins[i] = NULL;\n\t\t}\n\t}\n#endif\n\t/* When nothing is running, API calls are in non-strict mode. */\n\tDUK_ASSERT(res->strict == 0);\n\n\tres->heap = heap;\n\n\t/* XXX: Any reason not to merge duk_hthread_alloc.c here? */\n\treturn res;\n}\n\nDUK_INTERNAL duk_hthread *duk_hthread_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hthread *res;\n\n\tres = duk_hthread_alloc_unchecked(thr->heap, hobject_flags);\n\tif (res == NULL) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn res;\n}\n\nDUK_INTERNAL duk_harray *duk_harray_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_harray *res;\n\n\tres = (duk_harray *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_harray));\n\n\tDUK_ASSERT(res->length == 0);\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hdecenv *duk_hdecenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hdecenv *res;\n\n\tres = (duk_hdecenv *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hdecenv));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->thread = NULL;\n\tres->varmap = NULL;\n#endif\n\n\tDUK_ASSERT(res->thread == NULL);\n\tDUK_ASSERT(res->varmap == NULL);\n\tDUK_ASSERT(res->regbase_byteoff == 0);\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hobjenv *duk_hobjenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hobjenv *res;\n\n\tres = (duk_hobjenv *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hobjenv));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->target = NULL;\n#endif\n\n\tDUK_ASSERT(res->target == NULL);\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hproxy *duk_hproxy_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hproxy *res;\n\n\tres = (duk_hproxy *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hproxy));\n\n\t/* Leave ->target and ->handler uninitialized, as caller will always\n\t * explicitly initialize them before any side effects are possible.\n\t */\n\n\treturn res;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hobject_assert.c",
    "content": "/*\n *  duk_hobject and subclass assertion helpers\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_ASSERTIONS)\n\nDUK_INTERNAL void duk_hobject_assert_valid(duk_hobject *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE(h) ||\n\t           DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FUNCTION);\n\tDUK_ASSERT(!DUK_HOBJECT_IS_BUFOBJ(h) ||\n\t           (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAYBUFFER ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_DATAVIEW ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT8ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT8ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT16ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT16ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT32ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT32ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FLOAT32ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FLOAT64ARRAY));\n\t/* Object is an Array <=> object has exotic array behavior */\n\tDUK_ASSERT((DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY && DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)) ||\n\t           (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_ARRAY && !DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)));\n}\n\nDUK_INTERNAL void duk_harray_assert_valid(duk_harray *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) h));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY((duk_hobject *) h));\n}\n\nDUK_INTERNAL void duk_hboundfunc_assert_valid(duk_hboundfunc *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_BOUNDFUNC((duk_hobject *) h));\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(&h->target) ||\n\t           (DUK_TVAL_IS_OBJECT(&h->target) &&\n\t            DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(&h->target))));\n\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(&h->this_binding));\n\tDUK_ASSERT(h->nargs == 0 || h->args != NULL);\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL void duk_hbufobj_assert_valid(duk_hbufobj *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(h->shift <= 3);\n\tDUK_ASSERT(h->elem_type <= DUK_HBUFOBJ_ELEM_MAX);\n\tDUK_ASSERT((h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT8) ||\n\t           (h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT8CLAMPED) ||\n\t           (h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_INT8) ||\n\t           (h->shift == 1 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT16) ||\n\t           (h->shift == 1 && h->elem_type == DUK_HBUFOBJ_ELEM_INT16) ||\n\t           (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT32) ||\n\t           (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_INT32) ||\n\t           (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_FLOAT32) ||\n\t           (h->shift == 3 && h->elem_type == DUK_HBUFOBJ_ELEM_FLOAT64));\n\tDUK_ASSERT(h->is_typedarray == 0 || h->is_typedarray == 1);\n\tDUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h));\n\tif (h->buf == NULL) {\n\t\tDUK_ASSERT(h->offset == 0);\n\t\tDUK_ASSERT(h->length == 0);\n\t} else {\n\t\t/* No assertions for offset or length; in particular,\n\t\t * it's OK for length to be longer than underlying\n\t\t * buffer.  Just ensure they don't wrap when added.\n\t\t */\n\t\tDUK_ASSERT(h->offset + h->length >= h->offset);\n\t}\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_INTERNAL void duk_hcompfunc_assert_valid(duk_hcompfunc *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\nDUK_INTERNAL void duk_hnatfunc_assert_valid(duk_hnatfunc *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\nDUK_INTERNAL void duk_hdecenv_assert_valid(duk_hdecenv *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_DECENV((duk_hobject *) h));\n\tDUK_ASSERT(h->thread == NULL || h->varmap != NULL);\n}\n\nDUK_INTERNAL void duk_hobjenv_assert_valid(duk_hobjenv *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_OBJENV((duk_hobject *) h));\n\tDUK_ASSERT(h->target != NULL);\n\tDUK_ASSERT(h->has_this == 0 || h->has_this == 1);\n}\n\nDUK_INTERNAL void duk_hproxy_assert_valid(duk_hproxy *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(h->target != NULL);\n\tDUK_ASSERT(h->handler != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ((duk_hobject *) h));\n}\n\nDUK_INTERNAL void duk_hthread_assert_valid(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) thr) == DUK_HTYPE_OBJECT);\n\tDUK_ASSERT(DUK_HOBJECT_IS_THREAD((duk_hobject *) thr));\n\tDUK_ASSERT(thr->unused1 == 0);\n\tDUK_ASSERT(thr->unused2 == 0);\n}\n\nDUK_INTERNAL void duk_ctx_assert_valid(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_HTHREAD_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack != NULL);\n\tDUK_ASSERT(thr->valstack_bottom != NULL);\n\tDUK_ASSERT(thr->valstack_top != NULL);\n\tDUK_ASSERT(thr->valstack_end != NULL);\n\tDUK_ASSERT(thr->valstack_alloc_end != NULL);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hobject_class.c",
    "content": "/*\n *  Hobject ECMAScript [[Class]].\n */\n\n#include \"duk_internal.h\"\n\n#if (DUK_STRIDX_UC_ARGUMENTS > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_BOOLEAN > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_DATE > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_ERROR > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_FUNCTION > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_JSON > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_MATH > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_NUMBER > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_OBJECT > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_REG_EXP > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_STRING > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_GLOBAL > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_OBJ_ENV > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_DEC_ENV > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_POINTER > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_THREAD > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_ARRAY_BUFFER > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_DATA_VIEW > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_INT8_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT8_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT8_CLAMPED_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_INT16_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT16_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_INT32_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT32_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_FLOAT32_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_FLOAT64_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_EMPTY_STRING > 255)\n#error constant too large\n#endif\n\n/* Note: assumes that these string indexes are 8-bit, genstrings.py must ensure that */\nDUK_INTERNAL duk_uint8_t duk_class_number_to_stridx[32] = {\n\tDUK_STRIDX_EMPTY_STRING,  /* NONE, intentionally empty */\n\tDUK_STRIDX_UC_OBJECT,\n\tDUK_STRIDX_ARRAY,\n\tDUK_STRIDX_UC_FUNCTION,\n\tDUK_STRIDX_UC_ARGUMENTS,\n\tDUK_STRIDX_UC_BOOLEAN,\n\tDUK_STRIDX_DATE,\n\tDUK_STRIDX_UC_ERROR,\n\tDUK_STRIDX_JSON,\n\tDUK_STRIDX_MATH,\n\tDUK_STRIDX_UC_NUMBER,\n\tDUK_STRIDX_REG_EXP,\n\tDUK_STRIDX_UC_STRING,\n\tDUK_STRIDX_GLOBAL,\n\tDUK_STRIDX_UC_SYMBOL,\n\tDUK_STRIDX_OBJ_ENV,\n\tDUK_STRIDX_DEC_ENV,\n\tDUK_STRIDX_UC_POINTER,\n\tDUK_STRIDX_UC_THREAD,\n\tDUK_STRIDX_ARRAY_BUFFER,\n\tDUK_STRIDX_DATA_VIEW,\n\tDUK_STRIDX_INT8_ARRAY,\n\tDUK_STRIDX_UINT8_ARRAY,\n\tDUK_STRIDX_UINT8_CLAMPED_ARRAY,\n\tDUK_STRIDX_INT16_ARRAY,\n\tDUK_STRIDX_UINT16_ARRAY,\n\tDUK_STRIDX_INT32_ARRAY,\n\tDUK_STRIDX_UINT32_ARRAY,\n\tDUK_STRIDX_FLOAT32_ARRAY,\n\tDUK_STRIDX_FLOAT64_ARRAY,\n\tDUK_STRIDX_EMPTY_STRING,  /* UNUSED, intentionally empty */\n\tDUK_STRIDX_EMPTY_STRING,  /* UNUSED, intentionally empty */\n};\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hobject_enum.c",
    "content": "/*\n *  Object enumeration support.\n *\n *  Creates an internal enumeration state object to be used e.g. with for-in\n *  enumeration.  The state object contains a snapshot of target object keys\n *  and internal control state for enumeration.  Enumerator flags allow caller\n *  to e.g. request internal/non-enumerable properties, and to enumerate only\n *  \"own\" properties.\n *\n *  Also creates the result value for e.g. Object.keys() based on the same\n *  internal structure.\n *\n *  This snapshot-based enumeration approach is used to simplify enumeration:\n *  non-snapshot-based approaches are difficult to reconcile with mutating\n *  the enumeration target, running multiple long-lived enumerators at the\n *  same time, garbage collection details, etc.  The downside is that the\n *  enumerator object is memory inefficient especially for iterating arrays.\n */\n\n#include \"duk_internal.h\"\n\n/* XXX: identify enumeration target with an object index (not top of stack) */\n\n/* First enumerated key index in enumerator object, must match exactly the\n * number of control properties inserted to the enumerator.\n */\n#define DUK__ENUM_START_INDEX  2\n\n/* Current implementation suffices for ES2015 for now because there's no symbol\n * sorting, so commented out for now.\n */\n\n/*\n *  Helper to sort enumeration keys using a callback for pairwise duk_hstring\n *  comparisons.  The keys are in the enumeration object entry part, starting\n *  from DUK__ENUM_START_INDEX, and the entry part is dense.  Entry part values\n *  are all \"true\", e.g. \"1\" -> true, \"3\" -> true, \"foo\" -> true, \"2\" -> true,\n *  so it suffices to just switch keys without switching values.\n *\n *  ES2015 [[OwnPropertyKeys]] enumeration order for ordinary objects:\n *  (1) array indices in ascending order,\n *  (2) non-array-index keys in insertion order, and\n *  (3) symbols in insertion order.\n *  http://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys.\n *\n *  This rule is applied to \"own properties\" at each inheritance level;\n *  non-duplicate parent keys always follow child keys.  For example,\n *  an inherited array index will enumerate -after- a symbol in the\n *  child.\n *\n *  Insertion sort is used because (1) it's simple and compact, (2) works\n *  in-place, (3) minimizes operations if data is already nearly sorted,\n *  (4) doesn't reorder elements considered equal.\n *  http://en.wikipedia.org/wiki/Insertion_sort\n */\n\n/* Sort key, must hold array indices, \"not array index\" marker, and one more\n * higher value for symbols.\n */\n#if !defined(DUK_USE_SYMBOL_BUILTIN)\ntypedef duk_uint32_t duk__sort_key_t;\n#elif defined(DUK_USE_64BIT_OPS)\ntypedef duk_uint64_t duk__sort_key_t;\n#else\ntypedef duk_double_t duk__sort_key_t;\n#endif\n\n/* Get sort key for a duk_hstring. */\nDUK_LOCAL duk__sort_key_t duk__hstring_sort_key(duk_hstring *x) {\n\tduk__sort_key_t val;\n\n\t/* For array indices [0,0xfffffffe] use the array index as is.\n\t * For strings, use 0xffffffff, the marker 'arridx' already in\n\t * duk_hstring.  For symbols, any value above 0xffffffff works,\n\t * as long as it is the same for all symbols; currently just add\n\t * the masked flag field into the arridx temporary.\n\t */\n\tDUK_ASSERT(x != NULL);\n\tDUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(x) || DUK_HSTRING_GET_ARRIDX_FAST(x) == DUK_HSTRING_NO_ARRAY_INDEX);\n\n\tval = (duk__sort_key_t) DUK_HSTRING_GET_ARRIDX_FAST(x);\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\tval = val + (duk__sort_key_t) (DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) x) & DUK_HSTRING_FLAG_SYMBOL);\n#endif\n\n\treturn (duk__sort_key_t) val;\n}\n\n/* Insert element 'b' after element 'a'? */\nDUK_LOCAL duk_bool_t duk__sort_compare_es6(duk_hstring *a, duk_hstring *b, duk__sort_key_t val_b) {\n\tduk__sort_key_t val_a;\n\n\tDUK_ASSERT(a != NULL);\n\tDUK_ASSERT(b != NULL);\n\tDUK_UNREF(b);  /* Not actually needed now, val_b suffices. */\n\n\tval_a = duk__hstring_sort_key(a);\n\n\tif (val_a > val_b) {\n\t\treturn 0;\n\t} else {\n\t\treturn 1;\n\t}\n}\n\nDUK_LOCAL void duk__sort_enum_keys_es6(duk_hthread *thr, duk_hobject *h_obj, duk_int_fast32_t idx_start, duk_int_fast32_t idx_end) {\n\tduk_hstring **keys;\n\tduk_int_fast32_t idx;\n\n\tDUK_ASSERT(h_obj != NULL);\n\tDUK_ASSERT(idx_start >= DUK__ENUM_START_INDEX);\n\tDUK_ASSERT(idx_end >= idx_start);\n\tDUK_UNREF(thr);\n\n\tif (idx_end <= idx_start + 1) {\n\t\treturn;  /* Zero or one element(s). */\n\t}\n\n\tkeys = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, h_obj);\n\n\tfor (idx = idx_start + 1; idx < idx_end; idx++) {\n\t\tduk_hstring *h_curr;\n\t\tduk_int_fast32_t idx_insert;\n\t\tduk__sort_key_t val_curr;\n\n\t\th_curr = keys[idx];\n\t\tDUK_ASSERT(h_curr != NULL);\n\n\t\t/* Scan backwards for insertion place.  This works very well\n\t\t * when the elements are nearly in order which is the common\n\t\t * (and optimized for) case.\n\t\t */\n\n\t\tval_curr = duk__hstring_sort_key(h_curr);  /* Remains same during scanning. */\n\t\tfor (idx_insert = idx - 1; idx_insert >= idx_start; idx_insert--) {\n\t\t\tduk_hstring *h_insert;\n\t\t\th_insert = keys[idx_insert];\n\t\t\tDUK_ASSERT(h_insert != NULL);\n\n\t\t\tif (duk__sort_compare_es6(h_insert, h_curr, val_curr)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t/* If we're out of indices, idx_insert == idx_start - 1 and idx_insert++\n\t\t * brings us back to idx_start.\n\t\t */\n\t\tidx_insert++;\n\t\tDUK_ASSERT(idx_insert >= 0 && idx_insert <= idx);\n\n\t\t/*        .-- p_insert   .-- p_curr\n\t\t *        v              v\n\t\t *  | ... | insert | ... | curr\n\t\t */\n\n\t\t/* This could also done when the keys are in order, i.e.\n\t\t * idx_insert == idx.  The result would be an unnecessary\n\t\t * memmove() but we use an explicit check because the keys\n\t\t * are very often in order already.\n\t\t */\n\t\tif (idx != idx_insert) {\n\t\t\tduk_memmove((void *) (keys + idx_insert + 1),\n\t\t\t            (const void *) (keys + idx_insert),\n\t\t\t            ((size_t) (idx - idx_insert) * sizeof(duk_hstring *)));\n\t\t\tkeys[idx_insert] = h_curr;\n\t\t}\n\t}\n}\n\n/*\n *  Create an internal enumerator object E, which has its keys ordered\n *  to match desired enumeration ordering.  Also initialize internal control\n *  properties for enumeration.\n *\n *  Note: if an array was used to hold enumeration keys instead, an array\n *  scan would be needed to eliminate duplicates found in the prototype chain.\n */\n\nDUK_LOCAL void duk__add_enum_key(duk_hthread *thr, duk_hstring *k) {\n\t/* 'k' may be unreachable on entry so must push without any\n\t * potential for GC.\n\t */\n\tduk_push_hstring(thr, k);\n\tduk_push_true(thr);\n\tduk_put_prop(thr, -3);\n}\n\nDUK_LOCAL void duk__add_enum_key_stridx(duk_hthread *thr, duk_small_uint_t stridx) {\n\tduk__add_enum_key(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n}\n\nDUK_INTERNAL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint_t enum_flags) {\n\tduk_hobject *enum_target;\n\tduk_hobject *curr;\n\tduk_hobject *res;\n#if defined(DUK_USE_ES6_PROXY)\n\tduk_hobject *h_proxy_target;\n\tduk_hobject *h_proxy_handler;\n\tduk_hobject *h_trap_result;\n#endif\n\tduk_uint_fast32_t i, len;  /* used for array, stack, and entry indices */\n\tduk_uint_fast32_t sort_start_index;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tenum_target = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(enum_target != NULL);\n\n\tduk_push_bare_object(thr);\n\tres = duk_known_hobject(thr, -1);\n\n\t/* [enum_target res] */\n\n\t/* Target must be stored so that we can recheck whether or not\n\t * keys still exist when we enumerate.  This is not done if the\n\t * enumeration result comes from a proxy trap as there is no\n\t * real object to check against.\n\t */\n\tduk_push_hobject(thr, enum_target);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_TARGET);  /* Target is bare, plain put OK. */\n\n\t/* Initialize index so that we skip internal control keys. */\n\tduk_push_int(thr, DUK__ENUM_START_INDEX);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_NEXT);  /* Target is bare, plain put OK. */\n\n\t/*\n\t *  Proxy object handling\n\t */\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (DUK_LIKELY((enum_flags & DUK_ENUM_NO_PROXY_BEHAVIOR) != 0)) {\n\t\tgoto skip_proxy;\n\t}\n\tif (DUK_LIKELY(!duk_hobject_proxy_check(enum_target,\n\t                                        &h_proxy_target,\n\t                                        &h_proxy_handler))) {\n\t\tgoto skip_proxy;\n\t}\n\n\t/* XXX: share code with Object.keys() Proxy handling */\n\n\t/* In ES2015 for-in invoked the \"enumerate\" trap; in ES2016 \"enumerate\"\n\t * has been obsoleted and \"ownKeys\" is used instead.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"proxy enumeration\"));\n\tduk_push_hobject(thr, h_proxy_handler);\n\tif (!duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_OWN_KEYS)) {\n\t\t/* No need to replace the 'enum_target' value in stack, only the\n\t\t * enum_target reference.  This also ensures that the original\n\t\t * enum target is reachable, which keeps the proxy and the proxy\n\t\t * target reachable.  We do need to replace the internal _Target.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"no ownKeys trap, enumerate proxy target instead\"));\n\t\tDUK_DDD(DUK_DDDPRINT(\"h_proxy_target=%!O\", (duk_heaphdr *) h_proxy_target));\n\t\tenum_target = h_proxy_target;\n\n\t\tduk_push_hobject(thr, enum_target);  /* -> [ ... enum_target res handler undefined target ] */\n\t\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_INT_TARGET);  /* Target is bare, plain put OK. */\n\n\t\tduk_pop_2(thr);  /* -> [ ... enum_target res ] */\n\t\tgoto skip_proxy;\n\t}\n\n\t/* [ ... enum_target res handler trap ] */\n\tduk_insert(thr, -2);\n\tduk_push_hobject(thr, h_proxy_target);    /* -> [ ... enum_target res trap handler target ] */\n\tduk_call_method(thr, 1 /*nargs*/);        /* -> [ ... enum_target res trap_result ] */\n\th_trap_result = duk_require_hobject(thr, -1);\n\tDUK_UNREF(h_trap_result);\n\n\tduk_proxy_ownkeys_postprocess(thr, h_proxy_target, enum_flags);\n\t/* -> [ ... enum_target res trap_result keys_array ] */\n\n\t/* Copy cleaned up trap result keys into the enumerator object. */\n\t/* XXX: result is a dense array; could make use of that. */\n\tDUK_ASSERT(duk_is_array(thr, -1));\n\tlen = (duk_uint_fast32_t) duk_get_length(thr, -1);\n\tfor (i = 0; i < len; i++) {\n\t\t(void) duk_get_prop_index(thr, -1, (duk_uarridx_t) i);\n\t\tDUK_ASSERT(duk_is_string(thr, -1));  /* postprocess cleaned up */\n\t\t/* [ ... enum_target res trap_result keys_array val ] */\n\t\tduk_push_true(thr);\n\t\t/* [ ... enum_target res trap_result keys_array val true ] */\n\t\tduk_put_prop(thr, -5);\n\t}\n\t/* [ ... enum_target res trap_result keys_array ] */\n\tduk_pop_2(thr);\n\tduk_remove_m2(thr);\n\n\t/* [ ... res ] */\n\n\t/* The internal _Target property is kept pointing to the original\n\t * enumeration target (the proxy object), so that the enumerator\n\t * 'next' operation can read property values if so requested.  The\n\t * fact that the _Target is a proxy disables key existence check\n\t * during enumeration.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"proxy enumeration, final res: %!O\", (duk_heaphdr *) res));\n\tgoto compact_and_return;\n\n skip_proxy:\n#endif  /* DUK_USE_ES6_PROXY */\n\n\tcurr = enum_target;\n\tsort_start_index = DUK__ENUM_START_INDEX;\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(res) == DUK__ENUM_START_INDEX);\n\twhile (curr) {\n\t\tduk_uint_fast32_t sort_end_index;\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\tduk_bool_t need_sort = 0;\n#endif\n\t\tduk_bool_t cond;\n\n\t\t/* Enumeration proceeds by inheritance level.  Virtual\n\t\t * properties need to be handled specially, followed by\n\t\t * array part, and finally entry part.\n\t\t *\n\t\t * If there are array index keys in the entry part or any\n\t\t * other risk of the ES2015 [[OwnPropertyKeys]] order being\n\t\t * violated, need_sort is set and an explicit ES2015 sort is\n\t\t * done for the inheritance level.\n\t\t */\n\n\t\t/* XXX: inheriting from proxy */\n\n\t\t/*\n\t\t *  Virtual properties.\n\t\t *\n\t\t *  String and buffer indices are virtual and always enumerable,\n\t\t *  'length' is virtual and non-enumerable.  Array and arguments\n\t\t *  object props have special behavior but are concrete.\n\t\t *\n\t\t *  String and buffer objects don't have an array part so as long\n\t\t *  as virtual array index keys are enumerated first, we don't\n\t\t *  need to set need_sort.\n\t\t */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tcond = DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr) || DUK_HOBJECT_IS_BUFOBJ(curr);\n#else\n\t\tcond = DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr);\n#endif\n\t\tcond = cond && !(enum_flags & DUK_ENUM_EXCLUDE_STRINGS);\n\t\tif (cond) {\n\t\t\tduk_bool_t have_length = 1;\n\n\t\t\t/* String and buffer enumeration behavior is identical now,\n\t\t\t * so use shared handler.\n\t\t\t */\n\t\t\tif (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr)) {\n\t\t\t\tduk_hstring *h_val;\n\t\t\t\th_val = duk_hobject_get_internal_value_string(thr->heap, curr);\n\t\t\t\tDUK_ASSERT(h_val != NULL);  /* string objects must not created without internal value */\n\t\t\t\tlen = (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h_val);\n\t\t\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t\telse {\n\t\t\t\tduk_hbufobj *h_bufobj;\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ(curr));\n\t\t\t\th_bufobj = (duk_hbufobj *) curr;\n\n\t\t\t\tif (h_bufobj == NULL || !h_bufobj->is_typedarray) {\n\t\t\t\t\t/* Zero length seems like a good behavior for neutered buffers.\n\t\t\t\t\t * ArrayBuffer (non-view) and DataView don't have index properties\n\t\t\t\t\t * or .length property.\n\t\t\t\t\t */\n\t\t\t\t\tlen = 0;\n\t\t\t\t\thave_length = 0;\n\t\t\t\t} else {\n\t\t\t\t\t/* There's intentionally no check for\n\t\t\t\t\t * current underlying buffer length.\n\t\t\t\t\t */\n\t\t\t\t\tlen = (duk_uint_fast32_t) (h_bufobj->length >> h_bufobj->shift);\n\t\t\t\t}\n\t\t\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\tduk_hstring *k;\n\n\t\t\t\t/* This is a bit fragile: the string is not\n\t\t\t\t * reachable until it is pushed by the helper.\n\t\t\t\t */\n\t\t\t\tk = duk_heap_strtable_intern_u32_checked(thr, (duk_uint32_t) i);\n\t\t\t\tDUK_ASSERT(k);\n\n\t\t\t\tduk__add_enum_key(thr, k);\n\n\t\t\t\t/* [enum_target res] */\n\t\t\t}\n\n\t\t\t/* 'length' and other virtual properties are not\n\t\t\t * enumerable, but are included if non-enumerable\n\t\t\t * properties are requested.\n\t\t\t */\n\n\t\t\tif (have_length && (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE)) {\n\t\t\t\tduk__add_enum_key_stridx(thr, DUK_STRIDX_LENGTH);\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t *  Array part\n\t\t */\n\n\t\tcond = !(enum_flags & DUK_ENUM_EXCLUDE_STRINGS);\n\t\tif (cond) {\n\t\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(curr); i++) {\n\t\t\t\tduk_hstring *k;\n\t\t\t\tduk_tval *tv;\n\n\t\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, curr, i);\n\t\t\t\tif (DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tk = duk_heap_strtable_intern_u32_checked(thr, (duk_uint32_t) i);  /* Fragile reachability. */\n\t\t\t\tDUK_ASSERT(k);\n\n\t\t\t\tduk__add_enum_key(thr, k);\n\n\t\t\t\t/* [enum_target res] */\n\t\t\t}\n\n\t\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(curr)) {\n\t\t\t\t/* Array .length comes after numeric indices. */\n\t\t\t\tif (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) {\n\t\t\t\t\tduk__add_enum_key_stridx(thr, DUK_STRIDX_LENGTH);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t *  Entries part\n\t\t */\n\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(curr); i++) {\n\t\t\tduk_hstring *k;\n\n\t\t\tk = DUK_HOBJECT_E_GET_KEY(thr->heap, curr, i);\n\t\t\tif (!k) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!(enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) &&\n\t\t\t    !DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(thr->heap, curr, i)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(k))) {\n\t\t\t\tif (!(enum_flags & DUK_ENUM_INCLUDE_HIDDEN) &&\n\t\t\t\t    DUK_HSTRING_HAS_HIDDEN(k)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!(enum_flags & DUK_ENUM_INCLUDE_SYMBOLS)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t\tneed_sort = 1;\n#endif\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(!DUK_HSTRING_HAS_HIDDEN(k));  /* would also have symbol flag */\n\t\t\t\tif (enum_flags & DUK_ENUM_EXCLUDE_STRINGS) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (DUK_HSTRING_HAS_ARRIDX(k)) {\n\t\t\t\t/* This in currently only possible if the\n\t\t\t\t * object has no array part: the array part\n\t\t\t\t * is exhaustive when it is present.\n\t\t\t\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t\tneed_sort = 1;\n#endif\n\t\t\t} else {\n\t\t\t\tif (enum_flags & DUK_ENUM_ARRAY_INDICES_ONLY) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, curr, i) ||\n\t\t\t           !DUK_TVAL_IS_UNUSED(&DUK_HOBJECT_E_GET_VALUE_PTR(thr->heap, curr, i)->v));\n\n\t\t\tduk__add_enum_key(thr, k);\n\n\t\t\t/* [enum_target res] */\n\t\t}\n\n\t\t/* Sort enumerated keys according to ES2015 requirements for\n\t\t * the \"inheritance level\" just processed.  This is far from\n\t\t * optimal, ES2015 semantics could be achieved more efficiently\n\t\t * by handling array index string keys (and symbol keys)\n\t\t * specially above in effect doing the sort inline.\n\t\t *\n\t\t * Skip the sort if array index sorting is requested because\n\t\t * we must consider all keys, also inherited, so an explicit\n\t\t * sort is done for the whole result after we're done with the\n\t\t * prototype chain.\n\t\t *\n\t\t * Also skip the sort if need_sort == 0, i.e. we know for\n\t\t * certain that the enumerated order is already correct.\n\t\t */\n\t\tsort_end_index = DUK_HOBJECT_GET_ENEXT(res);\n\n\t\tif (!(enum_flags & DUK_ENUM_SORT_ARRAY_INDICES)) {\n#if defined(DUK_USE_PREFER_SIZE)\n\t\t\tduk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) sort_start_index, (duk_int_fast32_t) sort_end_index);\n#else\n\t\t\tif (need_sort) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"need to sort\"));\n\t\t\t\tduk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) sort_start_index, (duk_int_fast32_t) sort_end_index);\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"no need to sort\"));\n\t\t\t}\n#endif\n\t\t}\n\n\t\tsort_start_index = sort_end_index;\n\n\t\tif (enum_flags & DUK_ENUM_OWN_PROPERTIES_ONLY) {\n\t\t\tbreak;\n\t\t}\n\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t}\n\n\t/* [enum_target res] */\n\n\tduk_remove_m2(thr);\n\n\t/* [res] */\n\n\tif (enum_flags & DUK_ENUM_SORT_ARRAY_INDICES) {\n\t\t/* Some E5/E5.1 algorithms require that array indices are iterated\n\t\t * in a strictly ascending order.  This is the case for e.g.\n\t\t * Array.prototype.forEach() and JSON.stringify() PropertyList\n\t\t * handling.  The caller can request an explicit sort in these\n\t\t * cases.\n\t\t */\n\n\t\t/* Sort to ES2015 order which works for pure array incides but\n\t\t * also for mixed keys.\n\t\t */\n\t\tduk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) DUK__ENUM_START_INDEX, (duk_int_fast32_t) DUK_HOBJECT_GET_ENEXT(res));\n\t}\n\n#if defined(DUK_USE_ES6_PROXY)\n compact_and_return:\n#endif\n\t/* compact; no need to seal because object is internal */\n\tduk_hobject_compact_props(thr, res);\n\n\tDUK_DDD(DUK_DDDPRINT(\"created enumerator object: %!iT\", (duk_tval *) duk_get_tval(thr, -1)));\n}\n\n/*\n *  Returns non-zero if a key and/or value was enumerated, and:\n *\n *   [enum] -> [key]        (get_value == 0)\n *   [enum] -> [key value]  (get_value == 1)\n *\n *  Returns zero without pushing anything on the stack otherwise.\n */\nDUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_hthread *thr, duk_bool_t get_value) {\n\tduk_hobject *e;\n\tduk_hobject *enum_target;\n\tduk_hstring *res = NULL;\n\tduk_uint_fast32_t idx;\n\tduk_bool_t check_existence;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* [... enum] */\n\n\te = duk_require_hobject(thr, -1);\n\n\t/* XXX use get tval ptr, more efficient */\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_NEXT);\n\tidx = (duk_uint_fast32_t) duk_require_uint(thr, -1);\n\tduk_pop(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"enumeration: index is: %ld\", (long) idx));\n\n\t/* Enumeration keys are checked against the enumeration target (to see\n\t * that they still exist).  In the proxy enumeration case _Target will\n\t * be the proxy, and checking key existence against the proxy is not\n\t * required (or sensible, as the keys may be fully virtual).\n\t */\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_TARGET);\n\tenum_target = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(enum_target != NULL);\n#if defined(DUK_USE_ES6_PROXY)\n\tcheck_existence = (!DUK_HOBJECT_IS_PROXY(enum_target));\n#else\n\tcheck_existence = 1;\n#endif\n\tduk_pop(thr);  /* still reachable */\n\n\tDUK_DDD(DUK_DDDPRINT(\"getting next enum value, enum_target=%!iO, enumerator=%!iT\",\n\t                     (duk_heaphdr *) enum_target, (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* no array part */\n\tfor (;;) {\n\t\tduk_hstring *k;\n\n\t\tif (idx >= DUK_HOBJECT_GET_ENEXT(e)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"enumeration: ran out of elements\"));\n\t\t\tbreak;\n\t\t}\n\n\t\t/* we know these because enum objects are internally created */\n\t\tk = DUK_HOBJECT_E_GET_KEY(thr->heap, e, idx);\n\t\tDUK_ASSERT(k != NULL);\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, e, idx));\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(&DUK_HOBJECT_E_GET_VALUE(thr->heap, e, idx).v));\n\n\t\tidx++;\n\n\t\t/* recheck that the property still exists */\n\t\tif (check_existence && !duk_hobject_hasprop_raw(thr, enum_target, k)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property deleted during enumeration, skip\"));\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"enumeration: found element, key: %!O\", (duk_heaphdr *) k));\n\t\tres = k;\n\t\tbreak;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"enumeration: updating next index to %ld\", (long) idx));\n\n\tduk_push_u32(thr, (duk_uint32_t) idx);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_NEXT);\n\n\t/* [... enum] */\n\n\tif (res) {\n\t\tduk_push_hstring(thr, res);\n\t\tif (get_value) {\n\t\t\tduk_push_hobject(thr, enum_target);\n\t\t\tduk_dup_m2(thr);       /* -> [... enum key enum_target key] */\n\t\t\tduk_get_prop(thr, -2); /* -> [... enum key enum_target val] */\n\t\t\tduk_remove_m2(thr);    /* -> [... enum key val] */\n\t\t\tduk_remove(thr, -3);   /* -> [... key val] */\n\t\t} else {\n\t\t\tduk_remove_m2(thr);    /* -> [... key] */\n\t\t}\n\t\treturn 1;\n\t} else {\n\t\tduk_pop(thr);  /* -> [...] */\n\t\treturn 0;\n\t}\n}\n\n/*\n *  Get enumerated keys in an ECMAScript array.  Matches Object.keys() behavior\n *  described in E5 Section 15.2.3.14.\n */\n\nDUK_INTERNAL duk_ret_t duk_hobject_get_enumerated_keys(duk_hthread *thr, duk_small_uint_t enum_flags) {\n\tduk_hobject *e;\n\tduk_hstring **keys;\n\tduk_tval *tv;\n\tduk_uint_fast32_t count;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(duk_get_hobject(thr, -1) != NULL);\n\n\t/* Create a temporary enumerator to get the (non-duplicated) key list;\n\t * the enumerator state is initialized without being needed, but that\n\t * has little impact.\n\t */\n\n\tduk_hobject_enumerator_create(thr, enum_flags);\n\te = duk_known_hobject(thr, -1);\n\n\t/* [enum_target enum res] */\n\n\t/* Create dense result array to exact size. */\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(e) >= DUK__ENUM_START_INDEX);\n\tcount = (duk_uint32_t) (DUK_HOBJECT_GET_ENEXT(e) - DUK__ENUM_START_INDEX);\n\n\t/* XXX: uninit would be OK */\n\ttv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) count);\n\tDUK_ASSERT(count == 0 || tv != NULL);\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\t/* Fill result array, no side effects. */\n\n\tkeys = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, e);\n\tkeys += DUK__ENUM_START_INDEX;\n\n\twhile (count-- > 0) {\n\t\tduk_hstring *k;\n\n\t\tk = *keys++;\n\t\tDUK_ASSERT(k != NULL);  /* enumerator must have no keys deleted */\n\n\t\tDUK_TVAL_SET_STRING(tv, k);\n\t\ttv++;\n\t\tDUK_HSTRING_INCREF(thr, k);\n\t}\n\n\t/* [enum_target enum res] */\n\tduk_remove_m2(thr);\n\n\t/* [enum_target res] */\n\n\treturn 1;  /* return 1 to allow callers to tail call */\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hobject_misc.c",
    "content": "/*\n *  Misc support functions\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, duk_hobject *h, duk_hobject *p, duk_bool_t ignore_loop) {\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* False if the object is NULL or the prototype 'p' is NULL.\n\t * In particular, false if both are NULL (don't compare equal).\n\t */\n\tif (h == NULL || p == NULL) {\n\t\treturn 0;\n\t}\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (h == p) {\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (sanity-- == 0) {\n\t\t\tif (ignore_loop) {\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\t\th = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t} while (h);\n\n\treturn 0;\n}\n\nDUK_INTERNAL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject *h, duk_hobject *p) {\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_hobject *tmp;\n\n\tDUK_ASSERT(h);\n\ttmp = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, h, p);\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, p);  /* avoid problems if p == h->prototype */\n\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);\n#else\n\tDUK_ASSERT(h);\n\tDUK_UNREF(thr);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, h, p);\n#endif\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hobject_pc2line.c",
    "content": "/*\n *  Helpers for creating and querying pc2line debug data, which\n *  converts a bytecode program counter to a source line number.\n *\n *  The run-time pc2line data is bit-packed, and documented in:\n *\n *    doc/function-objects.rst\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_PC2LINE)\n\n/* Generate pc2line data for an instruction sequence, leaving a buffer on stack top. */\nDUK_INTERNAL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr *instrs, duk_uint_fast32_t length) {\n\tduk_hbuffer_dynamic *h_buf;\n\tduk_bitencoder_ctx be_ctx_alloc;\n\tduk_bitencoder_ctx *be_ctx = &be_ctx_alloc;\n\tduk_uint32_t *hdr;\n\tduk_size_t new_size;\n\tduk_uint_fast32_t num_header_entries;\n\tduk_uint_fast32_t curr_offset;\n\tduk_int_fast32_t curr_line, next_line, diff_line;\n\tduk_uint_fast32_t curr_pc;\n\tduk_uint_fast32_t hdr_index;\n\n\tDUK_ASSERT(length <= DUK_COMPILER_MAX_BYTECODE_LENGTH);\n\n\tnum_header_entries = (length + DUK_PC2LINE_SKIP - 1) / DUK_PC2LINE_SKIP;\n\tcurr_offset = (duk_uint_fast32_t) (sizeof(duk_uint32_t) + num_header_entries * sizeof(duk_uint32_t) * 2);\n\n\tduk_push_dynamic_buffer(thr, (duk_size_t) curr_offset);\n\th_buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, -1);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h_buf) && !DUK_HBUFFER_HAS_EXTERNAL(h_buf));\n\n\thdr = (duk_uint32_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h_buf);\n\tDUK_ASSERT(hdr != NULL);\n\thdr[0] = (duk_uint32_t) length;  /* valid pc range is [0, length[ */\n\n\tcurr_pc = 0U;\n\twhile (curr_pc < length) {\n\t\tnew_size = (duk_size_t) (curr_offset + DUK_PC2LINE_MAX_DIFF_LENGTH);\n\t\tduk_hbuffer_resize(thr, h_buf, new_size);\n\n\t\thdr = (duk_uint32_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h_buf);\n\t\tDUK_ASSERT(hdr != NULL);\n\t\tDUK_ASSERT(curr_pc < length);\n\t\thdr_index = 1 + (curr_pc / DUK_PC2LINE_SKIP) * 2;\n\t\tcurr_line = (duk_int_fast32_t) instrs[curr_pc].line;\n\t\thdr[hdr_index + 0] = (duk_uint32_t) curr_line;\n\t\thdr[hdr_index + 1] = (duk_uint32_t) curr_offset;\n\n#if 0\n\t\tDUK_DDD(DUK_DDDPRINT(\"hdr[%ld]: pc=%ld line=%ld offset=%ld\",\n\t\t                     (long) (curr_pc / DUK_PC2LINE_SKIP),\n\t\t                     (long) curr_pc,\n\t\t                     (long) hdr[hdr_index + 0],\n\t\t                     (long) hdr[hdr_index + 1]));\n#endif\n\n\t\tduk_memzero(be_ctx, sizeof(*be_ctx));\n\t\tbe_ctx->data = ((duk_uint8_t *) hdr) + curr_offset;\n\t\tbe_ctx->length = (duk_size_t) DUK_PC2LINE_MAX_DIFF_LENGTH;\n\n\t\tfor (;;) {\n\t\t\tcurr_pc++;\n\t\t\tif ( ((curr_pc % DUK_PC2LINE_SKIP) == 0) ||  /* end of diff run */\n\t\t\t     (curr_pc >= length) ) {                 /* end of bytecode */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_ASSERT(curr_pc < length);\n\t\t\tnext_line = (duk_int32_t) instrs[curr_pc].line;\n\t\t\tdiff_line = next_line - curr_line;\n\n#if 0\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"curr_line=%ld, next_line=%ld -> diff_line=%ld\",\n\t\t\t                     (long) curr_line, (long) next_line, (long) diff_line));\n#endif\n\n\t\t\tif (diff_line == 0) {\n\t\t\t\t/* 0 */\n\t\t\t\tduk_be_encode(be_ctx, 0, 1);\n\t\t\t} else if (diff_line >= 1 && diff_line <= 4) {\n\t\t\t\t/* 1 0 <2 bits> */\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) ((0x02 << 2) + (diff_line - 1)), 4);\n\t\t\t} else if (diff_line >= -0x80 && diff_line <= 0x7f) {\n\t\t\t\t/* 1 1 0 <8 bits> */\n\t\t\t\tDUK_ASSERT(diff_line + 0x80 >= 0 && diff_line + 0x80 <= 0xff);\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) ((0x06 << 8) + (diff_line + 0x80)), 11);\n\t\t\t} else {\n\t\t\t\t/* 1 1 1 <32 bits>\n\t\t\t\t * Encode in two parts to avoid bitencode 24-bit limitation\n\t\t\t\t */\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) ((0x07 << 16) + ((next_line >> 16) & 0xffff)), 19);\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) (next_line & 0xffff), 16);\n\t\t\t}\n\n\t\t\tcurr_line = next_line;\n\t\t}\n\n\t\tduk_be_finish(be_ctx);\n\t\tDUK_ASSERT(!be_ctx->truncated);\n\n\t\t/* be_ctx->offset == length of encoded bitstream */\n\t\tcurr_offset += (duk_uint_fast32_t) be_ctx->offset;\n\t}\n\n\t/* compact */\n\tnew_size = (duk_size_t) curr_offset;\n\tduk_hbuffer_resize(thr, h_buf, new_size);\n\n\t(void) duk_to_fixed_buffer(thr, -1, NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"final pc2line data: pc_limit=%ld, length=%ld, %lf bits/opcode --> %!ixT\",\n\t                     (long) length, (long) new_size, (double) new_size * 8.0 / (double) length,\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n}\n\n/* PC is unsigned.  If caller does PC arithmetic and gets a negative result,\n * it will map to a large PC which is out of bounds and causes a zero to be\n * returned.\n */\nDUK_LOCAL duk_uint_fast32_t duk__hobject_pc2line_query_raw(duk_hthread *thr, duk_hbuffer_fixed *buf, duk_uint_fast32_t pc) {\n\tduk_bitdecoder_ctx bd_ctx_alloc;\n\tduk_bitdecoder_ctx *bd_ctx = &bd_ctx_alloc;\n\tduk_uint32_t *hdr;\n\tduk_uint_fast32_t start_offset;\n\tduk_uint_fast32_t pc_limit;\n\tduk_uint_fast32_t hdr_index;\n\tduk_uint_fast32_t pc_base;\n\tduk_uint_fast32_t n;\n\tduk_uint_fast32_t curr_line;\n\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) buf) && !DUK_HBUFFER_HAS_EXTERNAL((duk_hbuffer *) buf));\n\tDUK_UNREF(thr);\n\n\t/*\n\t *  Use the index in the header to find the right starting point\n\t */\n\n\thdr_index = pc / DUK_PC2LINE_SKIP;\n\tpc_base = hdr_index * DUK_PC2LINE_SKIP;\n\tn = pc - pc_base;\n\n\tif (DUK_HBUFFER_FIXED_GET_SIZE(buf) <= sizeof(duk_uint32_t)) {\n\t\tDUK_DD(DUK_DDPRINT(\"pc2line lookup failed: buffer is smaller than minimal header\"));\n\t\tgoto pc2line_error;\n\t}\n\n\thdr = (duk_uint32_t *) (void *) DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, buf);\n\tpc_limit = hdr[0];\n\tif (pc >= pc_limit) {\n\t\t/* Note: pc is unsigned and cannot be negative */\n\t\tDUK_DD(DUK_DDPRINT(\"pc2line lookup failed: pc out of bounds (pc=%ld, limit=%ld)\",\n\t\t                   (long) pc, (long) pc_limit));\n\t\tgoto pc2line_error;\n\t}\n\n\tcurr_line = hdr[1 + hdr_index * 2];\n\tstart_offset = hdr[1 + hdr_index * 2 + 1];\n\tif ((duk_size_t) start_offset > DUK_HBUFFER_FIXED_GET_SIZE(buf)) {\n\t\tDUK_DD(DUK_DDPRINT(\"pc2line lookup failed: start_offset out of bounds (start_offset=%ld, buffer_size=%ld)\",\n\t\t                   (long) start_offset, (long) DUK_HBUFFER_GET_SIZE((duk_hbuffer *) buf)));\n\t\tgoto pc2line_error;\n\t}\n\n\t/*\n\t *  Iterate the bitstream (line diffs) until PC is reached\n\t */\n\n\tduk_memzero(bd_ctx, sizeof(*bd_ctx));\n\tbd_ctx->data = ((duk_uint8_t *) hdr) + start_offset;\n\tbd_ctx->length = (duk_size_t) (DUK_HBUFFER_FIXED_GET_SIZE(buf) - start_offset);\n\n#if 0\n\tDUK_DDD(DUK_DDDPRINT(\"pc2line lookup: pc=%ld -> hdr_index=%ld, pc_base=%ld, n=%ld, start_offset=%ld\",\n\t                     (long) pc, (long) hdr_index, (long) pc_base, (long) n, (long) start_offset));\n#endif\n\n\twhile (n > 0) {\n#if 0\n\t\tDUK_DDD(DUK_DDDPRINT(\"lookup: n=%ld, curr_line=%ld\", (long) n, (long) curr_line));\n#endif\n\n\t\tif (duk_bd_decode_flag(bd_ctx)) {\n\t\t\tif (duk_bd_decode_flag(bd_ctx)) {\n\t\t\t\tif (duk_bd_decode_flag(bd_ctx)) {\n\t\t\t\t\t/* 1 1 1 <32 bits> */\n\t\t\t\t\tduk_uint_fast32_t t;\n\t\t\t\t\tt = duk_bd_decode(bd_ctx, 16);  /* workaround: max nbits = 24 now */\n\t\t\t\t\tt = (t << 16) + duk_bd_decode(bd_ctx, 16);\n\t\t\t\t\tcurr_line = t;\n\t\t\t\t} else {\n\t\t\t\t\t/* 1 1 0 <8 bits> */\n\t\t\t\t\tduk_uint_fast32_t t;\n\t\t\t\t\tt = duk_bd_decode(bd_ctx, 8);\n\t\t\t\t\tcurr_line = curr_line + t - 0x80;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* 1 0 <2 bits> */\n\t\t\t\tduk_uint_fast32_t t;\n\t\t\t\tt = duk_bd_decode(bd_ctx, 2);\n\t\t\t\tcurr_line = curr_line + t + 1;\n\t\t\t}\n\t\t} else {\n\t\t\t/* 0: no change */\n\t\t}\n\n\t\tn--;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"pc2line lookup result: pc %ld -> line %ld\", (long) pc, (long) curr_line));\n\treturn curr_line;\n\n pc2line_error:\n\tDUK_D(DUK_DPRINT(\"pc2line conversion failed for pc=%ld\", (long) pc));\n\treturn 0;\n}\n\nDUK_INTERNAL duk_uint_fast32_t duk_hobject_pc2line_query(duk_hthread *thr, duk_idx_t idx_func, duk_uint_fast32_t pc) {\n\tduk_hbuffer_fixed *pc2line;\n\tduk_uint_fast32_t line;\n\n\t/* XXX: now that pc2line is used by the debugger quite heavily in\n\t * checked execution, this should be optimized to avoid value stack\n\t * and perhaps also implement some form of pc2line caching (see\n\t * future work in debugger.rst).\n\t */\n\n\tduk_xget_owndataprop_stridx_short(thr, idx_func, DUK_STRIDX_INT_PC2LINE);\n\tpc2line = (duk_hbuffer_fixed *) (void *) duk_get_hbuffer(thr, -1);\n\tif (pc2line != NULL) {\n\t\tDUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) pc2line) && !DUK_HBUFFER_HAS_EXTERNAL((duk_hbuffer *) pc2line));\n\t\tline = duk__hobject_pc2line_query_raw(thr, pc2line, (duk_uint_fast32_t) pc);\n\t} else {\n\t\tline = 0;\n\t}\n\tduk_pop(thr);\n\n\treturn line;\n}\n\n#endif  /* DUK_USE_PC2LINE */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hobject_props.c",
    "content": "/*\n *  duk_hobject property access functionality.\n *\n *  This is very central functionality for size, performance, and compliance.\n *  It is also rather intricate; see hobject-algorithms.rst for discussion on\n *  the algorithms and memory-management.rst for discussion on refcounts and\n *  side effect issues.\n *\n *  Notes:\n *\n *    - It might be tempting to assert \"refcount nonzero\" for objects\n *      being operated on, but that's not always correct: objects with\n *      a zero refcount may be operated on by the refcount implementation\n *      (finalization) for instance.  Hence, no refcount assertions are made.\n *\n *    - Many operations (memory allocation, identifier operations, etc)\n *      may cause arbitrary side effects (e.g. through GC and finalization).\n *      These side effects may invalidate duk_tval pointers which point to\n *      areas subject to reallocation (like value stack).  Heap objects\n *      themselves have stable pointers.  Holding heap object pointers or\n *      duk_tval copies is not problematic with respect to side effects;\n *      care must be taken when holding and using argument duk_tval pointers.\n *\n *    - If a finalizer is executed, it may operate on the the same object\n *      we're currently dealing with.  For instance, the finalizer might\n *      delete a certain property which has already been looked up and\n *      confirmed to exist.  Ideally finalizers would be disabled if GC\n *      happens during property access.  At the moment property table realloc\n *      disables finalizers, and all DECREFs may cause arbitrary changes so\n *      handle DECREF carefully.\n *\n *    - The order of operations for a DECREF matters.  When DECREF is executed,\n *      the entire object graph must be consistent; note that a refzero may\n *      lead to a mark-and-sweep through a refcount finalizer.  Use NORZ macros\n *      and an explicit DUK_REFZERO_CHECK_xxx() if achieving correct order is hard.\n */\n\n/*\n *  XXX: array indices are mostly typed as duk_uint32_t here; duk_uarridx_t\n *  might be more appropriate.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Local defines\n */\n\n#define DUK__NO_ARRAY_INDEX             DUK_HSTRING_NO_ARRAY_INDEX\n\n/* Marker values for hash part. */\n#define DUK__HASH_UNUSED                DUK_HOBJECT_HASHIDX_UNUSED\n#define DUK__HASH_DELETED               DUK_HOBJECT_HASHIDX_DELETED\n\n/* Valstack space that suffices for all local calls, excluding any recursion\n * into ECMAScript or Duktape/C calls (Proxy, getters, etc).\n */\n#define DUK__VALSTACK_SPACE             10\n\n/* Valstack space allocated especially for proxy lookup which does a\n * recursive property lookup.\n */\n#define DUK__VALSTACK_PROXY_LOOKUP      20\n\n/*\n *  Local prototypes\n */\n\nDUK_LOCAL_DECL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc);\nDUK_LOCAL_DECL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc, duk_bool_t throw_flag);\nDUK_LOCAL_DECL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc);\n\nDUK_LOCAL_DECL duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr, duk_hobject *obj, duk_uint32_t old_len, duk_uint32_t new_len, duk_bool_t force_flag, duk_uint32_t *out_result_len);\nDUK_LOCAL_DECL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject *obj);\n\nDUK_LOCAL_DECL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags);\nDUK_LOCAL_DECL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_uint32_t arr_idx, duk_propdesc *out_desc, duk_small_uint_t flags);\n\nDUK_LOCAL_DECL void duk__abandon_array_part(duk_hthread *thr, duk_hobject *obj);\nDUK_LOCAL_DECL void duk__grow_props_for_array_item(duk_hthread *thr, duk_hobject *obj, duk_uint32_t highest_arr_idx);\n\n/*\n *  Misc helpers\n */\n\n/* Convert a duk_tval number (caller checks) to a 32-bit index.  Returns\n * DUK__NO_ARRAY_INDEX if the number is not whole or not a valid array\n * index.\n */\n/* XXX: for fastints, could use a variant which assumes a double duk_tval\n * (and doesn't need to check for fastint again).\n */\nDUK_LOCAL duk_uint32_t duk__tval_number_to_arr_idx(duk_tval *tv) {\n\tduk_double_t dbl;\n\tduk_uint32_t idx;\n\n\tDUK_ASSERT(tv != NULL);\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\n\t/* -0 is accepted here as index 0 because ToString(-0) == \"0\" which is\n\t * in canonical form and thus an array index.\n\t */\n\tdbl = DUK_TVAL_GET_NUMBER(tv);\n\tidx = (duk_uint32_t) dbl;\n\tif ((duk_double_t) idx == dbl) {\n\t        /* Is whole and within 32 bit range.  If the value happens to be 0xFFFFFFFF,\n\t\t * it's not a valid array index but will then match DUK__NO_ARRAY_INDEX.\n\t\t */\n\t\treturn idx;\n\t}\n\treturn DUK__NO_ARRAY_INDEX;\n}\n\n#if defined(DUK_USE_FASTINT)\n/* Convert a duk_tval fastint (caller checks) to a 32-bit index. */\nDUK_LOCAL duk_uint32_t duk__tval_fastint_to_arr_idx(duk_tval *tv) {\n\tduk_int64_t t;\n\n\tDUK_ASSERT(tv != NULL);\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\n\tt = DUK_TVAL_GET_FASTINT(tv);\n\tif (((duk_uint64_t) t & ~DUK_U64_CONSTANT(0xffffffff)) != 0) {\n\t\t/* Catches >0x100000000 and negative values. */\n\t\treturn DUK__NO_ARRAY_INDEX;\n\t}\n\n\t/* If the value happens to be 0xFFFFFFFF, it's not a valid array index\n\t * but will then match DUK__NO_ARRAY_INDEX.\n\t */\n\treturn (duk_uint32_t) t;\n}\n#endif  /* DUK_USE_FASTINT */\n\n/* Convert a duk_tval on the value stack (in a trusted index we don't validate)\n * to a string or symbol using ES2015 ToPropertyKey():\n * http://www.ecma-international.org/ecma-262/6.0/#sec-topropertykey.\n *\n * Also check if it's a valid array index and return that (or DUK__NO_ARRAY_INDEX\n * if not).\n */\nDUK_LOCAL duk_uint32_t duk__to_property_key(duk_hthread *thr, duk_idx_t idx, duk_hstring **out_h) {\n\tduk_uint32_t arr_idx;\n\tduk_hstring *h;\n\tduk_tval *tv_dst;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(out_h != NULL);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx));\n\tDUK_ASSERT(idx < 0);\n\n\t/* XXX: The revised ES2015 ToPropertyKey() handling (ES5.1 was just\n\t * ToString()) involves a ToPrimitive(), a symbol check, and finally\n\t * a ToString().  Figure out the best way to have a good fast path\n\t * but still be compliant and share code.\n\t */\n\n\ttv_dst = DUK_GET_TVAL_NEGIDX(thr, idx);  /* intentionally unvalidated */\n\tif (DUK_TVAL_IS_STRING(tv_dst)) {\n\t\t/* Most important path: strings and plain symbols are used as\n\t\t * is.  For symbols the array index check below is unnecessary\n\t\t * (they're never valid array indices) but checking that the\n\t\t * string is a symbol would make the plain string path slower\n\t\t * unnecessarily.\n\t\t */\n\t\th = DUK_TVAL_GET_STRING(tv_dst);\n\t} else {\n\t\th = duk_to_property_key_hstring(thr, idx);\n\t}\n\tDUK_ASSERT(h != NULL);\n\t*out_h = h;\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_FAST(h);\n\treturn arr_idx;\n}\n\nDUK_LOCAL duk_uint32_t duk__push_tval_to_property_key(duk_hthread *thr, duk_tval *tv_key, duk_hstring **out_h) {\n\tduk_push_tval(thr, tv_key);  /* XXX: could use an unsafe push here */\n\treturn duk__to_property_key(thr, -1, out_h);\n}\n\n/* String is an own (virtual) property of a plain buffer. */\nDUK_LOCAL duk_bool_t duk__key_is_plain_buf_ownprop(duk_hthread *thr, duk_hbuffer *buf, duk_hstring *key, duk_uint32_t arr_idx) {\n\tDUK_UNREF(thr);\n\n\t/* Virtual index properties.  Checking explicitly for\n\t * 'arr_idx != DUK__NO_ARRAY_INDEX' is not necessary\n\t * because DUK__NO_ARRAY_INDEXi is always larger than\n\t * maximum allowed buffer size.\n\t */\n\tDUK_ASSERT(DUK__NO_ARRAY_INDEX >= DUK_HBUFFER_GET_SIZE(buf));\n\tif (arr_idx < DUK_HBUFFER_GET_SIZE(buf)) {\n\t\treturn 1;\n\t}\n\n\t/* Other virtual properties. */\n\treturn (key == DUK_HTHREAD_STRING_LENGTH(thr));\n}\n\n/*\n *  Helpers for managing property storage size\n */\n\n/* Get default hash part size for a certain entry part size. */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\nDUK_LOCAL duk_uint32_t duk__get_default_h_size(duk_uint32_t e_size) {\n\tDUK_ASSERT(e_size <= DUK_HOBJECT_MAX_PROPERTIES);\n\n\tif (e_size >= DUK_USE_HOBJECT_HASH_PROP_LIMIT) {\n\t\tduk_uint32_t res;\n\t\tduk_uint32_t tmp;\n\n\t\t/* Hash size should be 2^N where N is chosen so that 2^N is\n\t\t * larger than e_size.  Extra shifting is used to ensure hash\n\t\t * is relatively sparse.\n\t\t */\n\t\ttmp = e_size;\n\t\tres = 2;  /* Result will be 2 ** (N + 1). */\n\t\twhile (tmp >= 0x40) {\n\t\t\ttmp >>= 6;\n\t\t\tres <<= 6;\n\t\t}\n\t\twhile (tmp != 0) {\n\t\t\ttmp >>= 1;\n\t\t\tres <<= 1;\n\t\t}\n\t\tDUK_ASSERT((DUK_HOBJECT_MAX_PROPERTIES << 2U) > DUK_HOBJECT_MAX_PROPERTIES);  /* Won't wrap, even shifted by 2. */\n\t\tDUK_ASSERT(res > e_size);\n\t\treturn res;\n\t} else {\n\t\treturn 0;\n\t}\n}\n#endif  /* USE_PROP_HASH_PART */\n\n/* Get minimum entry part growth for a certain size. */\nDUK_LOCAL duk_uint32_t duk__get_min_grow_e(duk_uint32_t e_size) {\n\tduk_uint32_t res;\n\n\tres = (e_size + DUK_USE_HOBJECT_ENTRY_MINGROW_ADD) / DUK_USE_HOBJECT_ENTRY_MINGROW_DIVISOR;\n\tDUK_ASSERT(res >= 1);  /* important for callers */\n\treturn res;\n}\n\n/* Get minimum array part growth for a certain size. */\nDUK_LOCAL duk_uint32_t duk__get_min_grow_a(duk_uint32_t a_size) {\n\tduk_uint32_t res;\n\n\tres = (a_size + DUK_USE_HOBJECT_ARRAY_MINGROW_ADD) / DUK_USE_HOBJECT_ARRAY_MINGROW_DIVISOR;\n\tDUK_ASSERT(res >= 1);  /* important for callers */\n\treturn res;\n}\n\n/* Count actually used entry part entries (non-NULL keys). */\nDUK_LOCAL duk_uint32_t duk__count_used_e_keys(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint_fast32_t i;\n\tduk_uint_fast32_t n = 0;\n\tduk_hstring **e;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(thr);\n\n\te = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, obj);\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tif (*e++) {\n\t\t\tn++;\n\t\t}\n\t}\n\treturn (duk_uint32_t) n;\n}\n\n/* Count actually used array part entries and array minimum size.\n * NOTE: 'out_min_size' can be computed much faster by starting from the\n * end and breaking out early when finding first used entry, but this is\n * not needed now.\n */\nDUK_LOCAL void duk__compute_a_stats(duk_hthread *thr, duk_hobject *obj, duk_uint32_t *out_used, duk_uint32_t *out_min_size) {\n\tduk_uint_fast32_t i;\n\tduk_uint_fast32_t used = 0;\n\tduk_uint_fast32_t highest_idx = (duk_uint_fast32_t) -1;  /* see below */\n\tduk_tval *a;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(out_used != NULL);\n\tDUK_ASSERT(out_min_size != NULL);\n\tDUK_UNREF(thr);\n\n\ta = DUK_HOBJECT_A_GET_BASE(thr->heap, obj);\n\tfor (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\tduk_tval *tv = a++;\n\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\tused++;\n\t\t\thighest_idx = i;\n\t\t}\n\t}\n\n\t/* Initial value for highest_idx is -1 coerced to unsigned.  This\n\t * is a bit odd, but (highest_idx + 1) will then wrap to 0 below\n\t * for out_min_size as intended.\n\t */\n\n\t*out_used = (duk_uint32_t) used;\n\t*out_min_size = (duk_uint32_t) (highest_idx + 1);  /* 0 if no used entries */\n}\n\n/* Check array density and indicate whether or not the array part should be abandoned. */\nDUK_LOCAL duk_bool_t duk__abandon_array_density_check(duk_uint32_t a_used, duk_uint32_t a_size) {\n\t/*\n\t *  Array abandon check; abandon if:\n\t *\n\t *    new_used / new_size < limit\n\t *    new_used < limit * new_size        || limit is 3 bits fixed point\n\t *    new_used < limit' / 8 * new_size   || *8\n\t *    8*new_used < limit' * new_size     || :8\n\t *    new_used < limit' * (new_size / 8)\n\t *\n\t *  Here, new_used = a_used, new_size = a_size.\n\t *\n\t *  Note: some callers use approximate values for a_used and/or a_size\n\t *  (e.g. dropping a '+1' term).  This doesn't affect the usefulness\n\t *  of the check, but may confuse debugging.\n\t */\n\n\treturn (a_used < DUK_USE_HOBJECT_ARRAY_ABANDON_LIMIT * (a_size >> 3));\n}\n\n/* Fast check for extending array: check whether or not a slow density check is required. */\nDUK_LOCAL duk_bool_t duk__abandon_array_slow_check_required(duk_uint32_t arr_idx, duk_uint32_t old_size) {\n\t/*\n\t *  In a fast check we assume old_size equals old_used (i.e., existing\n\t *  array is fully dense).\n\t *\n\t *  Slow check if:\n\t *\n\t *    (new_size - old_size) / old_size > limit\n\t *    new_size - old_size > limit * old_size\n\t *    new_size > (1 + limit) * old_size        || limit' is 3 bits fixed point\n\t *    new_size > (1 + (limit' / 8)) * old_size || * 8\n\t *    8 * new_size > (8 + limit') * old_size   || : 8\n\t *    new_size > (8 + limit') * (old_size / 8)\n\t *    new_size > limit'' * (old_size / 8)      || limit'' = 9 -> max 25% increase\n\t *    arr_idx + 1 > limit'' * (old_size / 8)\n\t *\n\t *  This check doesn't work well for small values, so old_size is rounded\n\t *  up for the check (and the '+ 1' of arr_idx can be ignored in practice):\n\t *\n\t *    arr_idx > limit'' * ((old_size + 7) / 8)\n\t */\n\n\treturn (arr_idx > DUK_USE_HOBJECT_ARRAY_FAST_RESIZE_LIMIT * ((old_size + 7) >> 3));\n}\n\nDUK_LOCAL duk_bool_t duk__abandon_array_check(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) {\n\tduk_uint32_t min_size;\n\tduk_uint32_t old_used;\n\tduk_uint32_t old_size;\n\n\tif (!duk__abandon_array_slow_check_required(arr_idx, DUK_HOBJECT_GET_ASIZE(obj))) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"=> fast resize is OK\"));\n\t\treturn 0;\n\t}\n\n\tduk__compute_a_stats(thr, obj, &old_used, &old_size);\n\n\tDUK_DDD(DUK_DDDPRINT(\"abandon check, array stats: old_used=%ld, old_size=%ld, arr_idx=%ld\",\n\t                     (long) old_used, (long) old_size, (long) arr_idx));\n\n\tmin_size = arr_idx + 1;\n#if defined(DUK_USE_OBJSIZES16)\n\tif (min_size > DUK_UINT16_MAX) {\n\t\tgoto do_abandon;\n\t}\n#endif\n\tDUK_UNREF(min_size);\n\n\t/* Note: intentionally use approximations to shave a few instructions:\n\t *   a_used = old_used  (accurate: old_used + 1)\n\t *   a_size = arr_idx   (accurate: arr_idx + 1)\n\t */\n\tif (duk__abandon_array_density_check(old_used, arr_idx)) {\n\t\tDUK_DD(DUK_DDPRINT(\"write to new array entry beyond current length, \"\n\t\t                   \"decided to abandon array part (would become too sparse)\"));\n\n\t\t/* Abandoning requires a props allocation resize and\n\t\t * 'rechecks' the valstack, invalidating any existing\n\t\t * valstack value pointers.\n\t\t */\n\t\tgoto do_abandon;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"=> decided to keep array part\"));\n\treturn 0;\n\n do_abandon:\n\tduk__abandon_array_part(thr, obj);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\treturn 1;\n}\n\nDUK_LOCAL duk_tval *duk__obtain_arridx_slot_slowpath(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) {\n\t/*\n\t *  Array needs to grow, but we don't want it becoming too sparse.\n\t *  If it were to become sparse, abandon array part, moving all\n\t *  array entries into the entries part (for good).\n\t *\n\t *  Since we don't keep track of actual density (used vs. size) of\n\t *  the array part, we need to estimate somehow.  The check is made\n\t *  in two parts:\n\t *\n\t *    - Check whether the resize need is small compared to the\n\t *      current size (relatively); if so, resize without further\n\t *      checking (essentially we assume that the original part is\n\t *      \"dense\" so that the result would be dense enough).\n\t *\n\t *    - Otherwise, compute the resize using an actual density\n\t *      measurement based on counting the used array entries.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"write to new array requires array resize, decide whether to do a \"\n\t                     \"fast resize without abandon check (arr_idx=%ld, old_size=%ld)\",\n\t                     (long) arr_idx, (long) DUK_HOBJECT_GET_ASIZE(obj)));\n\n\tif (DUK_UNLIKELY(duk__abandon_array_check(thr, arr_idx, obj) != 0)) {\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\treturn NULL;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"write to new array entry beyond current length, \"\n\t                   \"decided to extend current allocation\"));\n\n\t/* In principle it's possible to run out of memory extending the\n\t * array but with the allocation going through if we were to abandon\n\t * the array part and try again.  In practice this should be rare\n\t * because abandoned arrays have a higher per-entry footprint.\n\t */\n\n\tduk__grow_props_for_array_item(thr, obj, arr_idx);\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\tDUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(obj));\n\treturn DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n}\n\nDUK_LOCAL DUK_INLINE duk_tval *duk__obtain_arridx_slot(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) {\n\tif (DUK_LIKELY(arr_idx < DUK_HOBJECT_GET_ASIZE(obj))) {\n\t\treturn DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n\t} else {\n\t\treturn duk__obtain_arridx_slot_slowpath(thr, arr_idx, obj);\n\t}\n}\n\n/*\n *  Proxy helpers\n */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL duk_bool_t duk_hobject_proxy_check(duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler) {\n\tduk_hproxy *h_proxy;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(out_target != NULL);\n\tDUK_ASSERT(out_handler != NULL);\n\n\t/* Caller doesn't need to check exotic proxy behavior (but does so for\n\t * some fast paths).\n\t */\n\tif (DUK_LIKELY(!DUK_HOBJECT_IS_PROXY(obj))) {\n\t\treturn 0;\n\t}\n\th_proxy = (duk_hproxy *) obj;\n\tDUK_HPROXY_ASSERT_VALID(h_proxy);\n\n\tDUK_ASSERT(h_proxy->handler != NULL);\n\tDUK_ASSERT(h_proxy->target != NULL);\n\t*out_handler = h_proxy->handler;\n\t*out_target = h_proxy->target;\n\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n/* Get Proxy target object.  If the argument is not a Proxy, return it as is.\n * If a Proxy is revoked, an error is thrown.\n */\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL duk_hobject *duk_hobject_resolve_proxy_target(duk_hobject *obj) {\n\tDUK_ASSERT(obj != NULL);\n\n\t/* Resolve Proxy targets until Proxy chain ends.  No explicit check for\n\t * a Proxy loop: user code cannot create such a loop (it would only be\n\t * possible by editing duk_hproxy references directly).\n\t */\n\n\twhile (DUK_HOBJECT_IS_PROXY(obj)) {\n\t\tduk_hproxy *h_proxy;\n\n\t\th_proxy = (duk_hproxy *) obj;\n\t\tDUK_HPROXY_ASSERT_VALID(h_proxy);\n\t\tobj = h_proxy->target;\n\t\tDUK_ASSERT(obj != NULL);\n\t}\n\n\tDUK_ASSERT(obj != NULL);\n\treturn obj;\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_LOCAL duk_bool_t duk__proxy_check_prop(duk_hthread *thr, duk_hobject *obj, duk_small_uint_t stridx_trap, duk_tval *tv_key, duk_hobject **out_target) {\n\tduk_hobject *h_handler;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\tDUK_ASSERT(out_target != NULL);\n\n\tif (!duk_hobject_proxy_check(obj, out_target, &h_handler)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(*out_target != NULL);\n\tDUK_ASSERT(h_handler != NULL);\n\n\t/* XXX: At the moment Duktape accesses internal keys like _Finalizer using a\n\t * normal property set/get which would allow a proxy handler to interfere with\n\t * such behavior and to get access to internal key strings.  This is not a problem\n\t * as such because internal key strings can be created in other ways too (e.g.\n\t * through buffers).  The best fix is to change Duktape internal lookups to\n\t * skip proxy behavior.  Until that, internal property accesses bypass the\n\t * proxy and are applied to the target (as if the handler did not exist).\n\t * This has some side effects, see test-bi-proxy-internal-keys.js.\n\t */\n\n\tif (DUK_TVAL_IS_STRING(tv_key)) {\n\t\tduk_hstring *h_key = (duk_hstring *) DUK_TVAL_GET_STRING(tv_key);\n\t\tDUK_ASSERT(h_key != NULL);\n\t\tif (DUK_HSTRING_HAS_HIDDEN(h_key)) {\n\t\t\t/* Symbol accesses must go through proxy lookup in ES2015.\n\t\t\t * Hidden symbols behave like Duktape 1.x internal keys\n\t\t\t * and currently won't.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"hidden key, skip proxy handler and apply to target\"));\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* The handler is looked up with a normal property lookup; it may be an\n\t * accessor or the handler object itself may be a proxy object.  If the\n\t * handler is a proxy, we need to extend the valstack as we make a\n\t * recursive proxy check without a function call in between (in fact\n\t * there is no limit to the potential recursion here).\n\t *\n\t * (For sanity, proxy creation rejects another proxy object as either\n\t * the handler or the target at the moment so recursive proxy cases\n\t * are not realized now.)\n\t */\n\n\t/* XXX: C recursion limit if proxies are allowed as handler/target values */\n\n\tduk_require_stack(thr, DUK__VALSTACK_PROXY_LOOKUP);\n\tduk_push_hobject(thr, h_handler);\n\tif (duk_get_prop_stridx_short(thr, -1, stridx_trap)) {\n\t\t/* -> [ ... handler trap ] */\n\t\tduk_insert(thr, -2);  /* -> [ ... trap handler ] */\n\n\t\t/* stack prepped for func call: [ ... trap handler ] */\n\t\treturn 1;\n\t} else {\n\t\tduk_pop_2_unsafe(thr);\n\t\treturn 0;\n\t}\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n/*\n *  Reallocate property allocation, moving properties to the new allocation.\n *\n *  Includes key compaction, rehashing, and can also optionally abandon\n *  the array part, 'migrating' array entries into the beginning of the\n *  new entry part.\n *\n *  There is no support for in-place reallocation or just compacting keys\n *  without resizing the property allocation.  This is intentional to keep\n *  code size minimal, but would be useful future work.\n *\n *  The implementation is relatively straightforward, except for the array\n *  abandonment process.  Array abandonment requires that new string keys\n *  are interned, which may trigger GC.  All keys interned so far must be\n *  reachable for GC at all times and correctly refcounted for; valstack is\n *  used for that now.\n *\n *  Also, a GC triggered during this reallocation process must not interfere\n *  with the object being resized.  This is currently controlled by preventing\n *  finalizers (as they may affect ANY object) and object compaction in\n *  mark-and-sweep.  It would suffice to protect only this particular object\n *  from compaction, however.  DECREF refzero cascades are side effect free\n *  and OK.\n *\n *  Note: because we need to potentially resize the valstack (as part\n *  of abandoning the array part), any tval pointers to the valstack\n *  will become invalid after this call.\n */\n\nDUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,\n                                            duk_hobject *obj,\n                                            duk_uint32_t new_e_size,\n                                            duk_uint32_t new_a_size,\n                                            duk_uint32_t new_h_size,\n                                            duk_bool_t abandon_array) {\n\tduk_small_uint_t prev_ms_base_flags;\n\tduk_uint32_t new_alloc_size;\n\tduk_uint32_t new_e_size_adjusted;\n\tduk_uint8_t *new_p;\n\tduk_hstring **new_e_k;\n\tduk_propvalue *new_e_pv;\n\tduk_uint8_t *new_e_f;\n\tduk_tval *new_a;\n\tduk_uint32_t *new_h;\n\tduk_uint32_t new_e_next;\n\tduk_uint_fast32_t i;\n\tduk_size_t array_copy_size;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_bool_t prev_error_not_allowed;\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(!abandon_array || new_a_size == 0);  /* if abandon_array, new_a_size must be 0 */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL || (DUK_HOBJECT_GET_ESIZE(obj) == 0 && DUK_HOBJECT_GET_ASIZE(obj) == 0));\n\tDUK_ASSERT(new_h_size == 0 || new_h_size >= new_e_size);  /* required to guarantee success of rehashing,\n\t                                                           * intentionally use unadjusted new_e_size\n\t                                                           */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_object_realloc_props);\n\n\t/*\n\t *  Pre resize assertions.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* XXX: pre-checks (such as no duplicate keys) */\n#endif\n\n\t/*\n\t *  For property layout 1, tweak e_size to ensure that the whole entry\n\t *  part (key + val + flags) is a suitable multiple for alignment\n\t *  (platform specific).\n\t *\n\t *  Property layout 2 does not require this tweaking and is preferred\n\t *  on low RAM platforms requiring alignment.\n\t */\n\n#if defined(DUK_USE_HOBJECT_LAYOUT_2) || defined(DUK_USE_HOBJECT_LAYOUT_3)\n\tDUK_DDD(DUK_DDDPRINT(\"using layout 2 or 3, no need to pad e_size: %ld\", (long) new_e_size));\n\tnew_e_size_adjusted = new_e_size;\n#elif defined(DUK_USE_HOBJECT_LAYOUT_1) && (DUK_HOBJECT_ALIGN_TARGET == 1)\n\tDUK_DDD(DUK_DDDPRINT(\"using layout 1, but no need to pad e_size: %ld\", (long) new_e_size));\n\tnew_e_size_adjusted = new_e_size;\n#elif defined(DUK_USE_HOBJECT_LAYOUT_1) && ((DUK_HOBJECT_ALIGN_TARGET == 4) || (DUK_HOBJECT_ALIGN_TARGET == 8))\n\tnew_e_size_adjusted = (new_e_size + (duk_uint32_t) DUK_HOBJECT_ALIGN_TARGET - 1U) &\n\t                      (~((duk_uint32_t) DUK_HOBJECT_ALIGN_TARGET - 1U));\n\tDUK_DDD(DUK_DDDPRINT(\"using layout 1, and alignment target is %ld, adjusted e_size: %ld -> %ld\",\n\t                     (long) DUK_HOBJECT_ALIGN_TARGET, (long) new_e_size, (long) new_e_size_adjusted));\n\tDUK_ASSERT(new_e_size_adjusted >= new_e_size);\n#else\n#error invalid hobject layout defines\n#endif\n\n\t/*\n\t *  Debug logging after adjustment.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"attempt to resize hobject %p props (%ld -> %ld bytes), from {p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld} to \"\n\t                     \"{e_size=%ld,a_size=%ld,h_size=%ld}, abandon_array=%ld, unadjusted new_e_size=%ld\",\n\t                     (void *) obj,\n\t                     (long) DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t                                                       DUK_HOBJECT_GET_ASIZE(obj),\n\t                                                       DUK_HOBJECT_GET_HSIZE(obj)),\n\t                     (long) DUK_HOBJECT_P_COMPUTE_SIZE(new_e_size_adjusted, new_a_size, new_h_size),\n\t                     (void *) DUK_HOBJECT_GET_PROPS(thr->heap, obj),\n\t                     (long) DUK_HOBJECT_GET_ESIZE(obj),\n\t                     (long) DUK_HOBJECT_GET_ENEXT(obj),\n\t                     (long) DUK_HOBJECT_GET_ASIZE(obj),\n\t                     (long) DUK_HOBJECT_GET_HSIZE(obj),\n\t                     (long) new_e_size_adjusted,\n\t                     (long) new_a_size,\n\t                     (long) new_h_size,\n\t                     (long) abandon_array,\n\t                     (long) new_e_size));\n\n\t/*\n\t *  Property count check.  This is the only point where we ensure that\n\t *  we don't get more (allocated) property space that we can handle.\n\t *  There aren't hard limits as such, but some algorithms may fail\n\t *  if we get too close to the 4G property limit.\n\t *\n\t *  Since this works based on allocation size (not actually used size),\n\t *  the limit is a bit approximate but good enough in practice.\n\t */\n\n\tif (new_e_size_adjusted + new_a_size > DUK_HOBJECT_MAX_PROPERTIES) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size_adjusted > DUK_UINT16_MAX || new_a_size > DUK_UINT16_MAX) {\n\t\t/* If caller gave us sizes larger than what we can store,\n\t\t * fail memory safely with an internal error rather than\n\t\t * truncating the sizes.\n\t\t */\n\t\tDUK_ERROR_INTERNAL(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\t/*\n\t *  Compute new alloc size and alloc new area.\n\t *\n\t *  The new area is not tracked in the heap at all, so it's critical\n\t *  we get to free/keep it in a controlled manner.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Whole path must be error throw free, but we may be called from\n\t * within error handling so can't assert for error_not_allowed == 0.\n\t */\n\tprev_error_not_allowed = thr->heap->error_not_allowed;\n\tthr->heap->error_not_allowed = 1;\n#endif\n\tprev_ms_base_flags = thr->heap->ms_base_flags;\n\tthr->heap->ms_base_flags |=\n\t        DUK_MS_FLAG_NO_OBJECT_COMPACTION;      /* Avoid attempt to compact the current object (all objects really). */\n\tthr->heap->pf_prevent_count++;                 /* Avoid finalizers. */\n\tDUK_ASSERT(thr->heap->pf_prevent_count != 0);  /* Wrap. */\n\n\tnew_alloc_size = DUK_HOBJECT_P_COMPUTE_SIZE(new_e_size_adjusted, new_a_size, new_h_size);\n\tDUK_DDD(DUK_DDDPRINT(\"new hobject allocation size is %ld\", (long) new_alloc_size));\n\tif (new_alloc_size == 0) {\n\t\tDUK_ASSERT(new_e_size_adjusted == 0);\n\t\tDUK_ASSERT(new_a_size == 0);\n\t\tDUK_ASSERT(new_h_size == 0);\n\t\tnew_p = NULL;\n\t} else {\n\t\t/* Alloc may trigger mark-and-sweep but no compaction, and\n\t\t * cannot throw.\n\t\t */\n#if 0  /* XXX: inject test */\n\t\tif (1) {\n\t\t\tnew_p = NULL;\n\t\t\tgoto alloc_failed;\n\t\t}\n#endif\n\t\tnew_p = (duk_uint8_t *) DUK_ALLOC(thr->heap, new_alloc_size);\n\t\tif (new_p == NULL) {\n\t\t\t/* NULL always indicates alloc failure because\n\t\t\t * new_alloc_size > 0.\n\t\t\t */\n\t\t\tgoto alloc_failed;\n\t\t}\n\t}\n\n\t/* Set up pointers to the new property area: this is hidden behind a macro\n\t * because it is memory layout specific.\n\t */\n\tDUK_HOBJECT_P_SET_REALLOC_PTRS(new_p, new_e_k, new_e_pv, new_e_f, new_a, new_h,\n\t                               new_e_size_adjusted, new_a_size, new_h_size);\n\tDUK_UNREF(new_h);  /* happens when hash part dropped */\n\tnew_e_next = 0;\n\n\t/* if new_p == NULL, all of these pointers are NULL */\n\tDUK_ASSERT((new_p != NULL) ||\n\t           (new_e_k == NULL && new_e_pv == NULL && new_e_f == NULL &&\n\t            new_a == NULL && new_h == NULL));\n\n\tDUK_DDD(DUK_DDDPRINT(\"new alloc size %ld, new_e_k=%p, new_e_pv=%p, new_e_f=%p, new_a=%p, new_h=%p\",\n\t                     (long) new_alloc_size, (void *) new_e_k, (void *) new_e_pv, (void *) new_e_f,\n\t                     (void *) new_a, (void *) new_h));\n\n\t/*\n\t *  Migrate array part to start of entries if requested.\n\t *\n\t *  Note: from an enumeration perspective the order of entry keys matters.\n\t *  Array keys should appear wherever they appeared before the array abandon\n\t *  operation.  (This no longer matters much because keys are ES2015 sorted.)\n\t */\n\n\tif (abandon_array) {\n\t\t/* Assuming new_a_size == 0, and that entry part contains\n\t\t * no conflicting keys, refcounts do not need to be adjusted for\n\t\t * the values, as they remain exactly the same.\n\t\t *\n\t\t * The keys, however, need to be interned, incref'd, and be\n\t\t * reachable for GC.  Any intern attempt may trigger a GC and\n\t\t * claim any non-reachable strings, so every key must be reachable\n\t\t * at all times.  Refcounts must be correct to satisfy refcount\n\t\t * assertions.\n\t\t *\n\t\t * A longjmp must not occur here, as the new_p allocation would\n\t\t * leak.  Refcounts would come out correctly as the interned\n\t\t * strings are valstack tracked.\n\t\t */\n\t\tDUK_ASSERT(new_a_size == 0);\n\n\t\tDUK_STATS_INC(thr->heap, stats_object_abandon_array);\n\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_tval *tv2;\n\t\t\tduk_hstring *key;\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);\n\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\t\tif (DUK_TVAL_IS_UNUSED(tv1)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(new_p != NULL && new_e_k != NULL &&\n\t\t\t           new_e_pv != NULL && new_e_f != NULL);\n\n\t\t\t/*\n\t\t\t *  Intern key via the valstack to ensure reachability behaves\n\t\t\t *  properly.  We must avoid longjmp's here so use non-checked\n\t\t\t *  primitives.\n\t\t\t *\n\t\t\t *  Note: duk_check_stack() potentially reallocs the valstack,\n\t\t\t *  invalidating any duk_tval pointers to valstack.  Callers\n\t\t\t *  must be careful.\n\t\t\t */\n\n#if 0  /* XXX: inject test */\n\t\t\tif (1) {\n\t\t\t\tgoto abandon_error;\n\t\t\t}\n#endif\n\t\t\t/* Never shrinks; auto-adds DUK_VALSTACK_INTERNAL_EXTRA, which\n\t\t\t * is generous.\n\t\t\t */\n\t\t\tif (!duk_check_stack(thr, 1)) {\n\t\t\t\tgoto abandon_error;\n\t\t\t}\n\t\t\tDUK_ASSERT_VALSTACK_SPACE(thr, 1);\n\t\t\tkey = duk_heap_strtable_intern_u32(thr->heap, (duk_uint32_t) i);\n\t\t\tif (key == NULL) {\n\t\t\t\tgoto abandon_error;\n\t\t\t}\n\t\t\tduk_push_hstring(thr, key);  /* keep key reachable for GC etc; guaranteed not to fail */\n\n\t\t\t/* Key is now reachable in the valstack, don't INCREF\n\t\t\t * the new allocation yet (we'll steal the refcounts\n\t\t\t * from the value stack once all keys are done).\n\t\t\t */\n\n\t\t\tnew_e_k[new_e_next] = key;\n\t\t\ttv2 = &new_e_pv[new_e_next].v;  /* array entries are all plain values */\n\t\t\tDUK_TVAL_SET_TVAL(tv2, tv1);\n\t\t\tnew_e_f[new_e_next] = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t                      DUK_PROPDESC_FLAG_ENUMERABLE |\n\t\t\t                      DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\tnew_e_next++;\n\n\t\t\t/* Note: new_e_next matches pushed temp key count, and nothing can\n\t\t\t * fail above between the push and this point.\n\t\t\t */\n\t\t}\n\n\t\t/* Steal refcounts from value stack. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"abandon array: pop %ld key temps from valstack\", (long) new_e_next));\n\t\tduk_pop_n_nodecref_unsafe(thr, (duk_idx_t) new_e_next);\n\t}\n\n\t/*\n\t *  Copy keys and values in the entry part (compacting them at the same time).\n\t */\n\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tduk_hstring *key;\n\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);\n\n\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);\n\t\tif (key == NULL) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_ASSERT(new_p != NULL && new_e_k != NULL &&\n\t\t           new_e_pv != NULL && new_e_f != NULL);\n\n\t\tnew_e_k[new_e_next] = key;\n\t\tnew_e_pv[new_e_next] = DUK_HOBJECT_E_GET_VALUE(thr->heap, obj, i);\n\t\tnew_e_f[new_e_next] = DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, i);\n\t\tnew_e_next++;\n\t}\n\t/* the entries [new_e_next, new_e_size_adjusted[ are left uninitialized on purpose (ok, not gc reachable) */\n\n\t/*\n\t *  Copy array elements to new array part.  If the new array part is\n\t *  larger, initialize the unused entries as UNUSED because they are\n\t *  GC reachable.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Caller must have decref'd values above new_a_size (if that is necessary). */\n\tif (!abandon_array) {\n\t\tfor (i = new_a_size; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\t\tduk_tval *tv;\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv));\n\t\t}\n\t}\n#endif\n\tif (new_a_size > DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\tarray_copy_size = sizeof(duk_tval) * DUK_HOBJECT_GET_ASIZE(obj);\n\t} else {\n\t\tarray_copy_size = sizeof(duk_tval) * new_a_size;\n\t}\n\n\tDUK_ASSERT(new_a != NULL || array_copy_size == 0U);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL || array_copy_size == 0U);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) > 0 || array_copy_size == 0U);\n\tduk_memcpy_unsafe((void *) new_a,\n\t                  (const void *) DUK_HOBJECT_A_GET_BASE(thr->heap, obj),\n\t                  array_copy_size);\n\n\tfor (i = DUK_HOBJECT_GET_ASIZE(obj); i < new_a_size; i++) {\n\t\tduk_tval *tv = &new_a[i];\n\t\tDUK_TVAL_SET_UNUSED(tv);\n\t}\n\n\t/*\n\t *  Rebuild the hash part always from scratch (guaranteed to finish\n\t *  as long as caller gave consistent parameters).\n\t *\n\t *  Any resize of hash part requires rehashing.  In addition, by rehashing\n\t *  get rid of any elements marked deleted (DUK__HASH_DELETED) which is critical\n\t *  to ensuring the hash part never fills up.\n\t */\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (new_h_size == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"no hash part, no rehash\"));\n\t} else {\n\t\tduk_uint32_t mask;\n\n\t\tDUK_ASSERT(new_h != NULL);\n\n\t\t/* fill new_h with u32 0xff = UNUSED */\n\t\tDUK_ASSERT(new_h_size > 0);\n\t\tduk_memset(new_h, 0xff, sizeof(duk_uint32_t) * new_h_size);\n\n\t\tDUK_ASSERT(new_e_next <= new_h_size);  /* equality not actually possible */\n\n\t\tmask = new_h_size - 1;\n\t\tfor (i = 0; i < new_e_next; i++) {\n\t\t\tduk_hstring *key = new_e_k[i];\n\t\t\tduk_uint32_t j, step;\n\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tj = DUK_HSTRING_GET_HASH(key) & mask;\n\t\t\tstep = 1;  /* Cache friendly but clustering prone. */\n\n\t\t\tfor (;;) {\n\t\t\t\tDUK_ASSERT(new_h[j] != DUK__HASH_DELETED);  /* should never happen */\n\t\t\t\tif (new_h[j] == DUK__HASH_UNUSED) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rebuild hit %ld -> %ld\", (long) j, (long) i));\n\t\t\t\t\tnew_h[j] = (duk_uint32_t) i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rebuild miss %ld, step %ld\", (long) j, (long) step));\n\t\t\t\tj = (j + step) & mask;\n\n\t\t\t\t/* Guaranteed to finish (hash is larger than #props). */\n\t\t\t}\n\t\t}\n\t}\n#endif  /* DUK_USE_HOBJECT_HASH_PART */\n\n\t/*\n\t *  Nice debug log.\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"resized hobject %p props (%ld -> %ld bytes), from {p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld} to \"\n\t                   \"{p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld}, abandon_array=%ld, unadjusted new_e_size=%ld\",\n\t                   (void *) obj,\n\t                   (long) DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t                                                     DUK_HOBJECT_GET_ASIZE(obj),\n\t                                                     DUK_HOBJECT_GET_HSIZE(obj)),\n\t                   (long) new_alloc_size,\n\t                   (void *) DUK_HOBJECT_GET_PROPS(thr->heap, obj),\n\t                   (long) DUK_HOBJECT_GET_ESIZE(obj),\n\t                   (long) DUK_HOBJECT_GET_ENEXT(obj),\n\t                   (long) DUK_HOBJECT_GET_ASIZE(obj),\n\t                   (long) DUK_HOBJECT_GET_HSIZE(obj),\n\t                   (void *) new_p,\n\t                   (long) new_e_size_adjusted,\n\t                   (long) new_e_next,\n\t                   (long) new_a_size,\n\t                   (long) new_h_size,\n\t                   (long) abandon_array,\n\t                   (long) new_e_size));\n\n\t/*\n\t *  All done, switch properties ('p') allocation to new one.\n\t */\n\n\tDUK_FREE_CHECKED(thr, DUK_HOBJECT_GET_PROPS(thr->heap, obj));  /* NULL obj->p is OK */\n\tDUK_HOBJECT_SET_PROPS(thr->heap, obj, new_p);\n\tDUK_HOBJECT_SET_ESIZE(obj, new_e_size_adjusted);\n\tDUK_HOBJECT_SET_ENEXT(obj, new_e_next);\n\tDUK_HOBJECT_SET_ASIZE(obj, new_a_size);\n\tDUK_HOBJECT_SET_HSIZE(obj, new_h_size);\n\n\t/* Clear array part flag only after switching. */\n\tif (abandon_array) {\n\t\tDUK_HOBJECT_CLEAR_ARRAY_PART(obj);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"resize result: %!O\", (duk_heaphdr *) obj));\n\n\tDUK_ASSERT(thr->heap->pf_prevent_count > 0);\n\tthr->heap->pf_prevent_count--;\n\tthr->heap->ms_base_flags = prev_ms_base_flags;\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->heap->error_not_allowed == 1);\n\tthr->heap->error_not_allowed = prev_error_not_allowed;\n#endif\n\n\t/*\n\t *  Post resize assertions.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* XXX: post-checks (such as no duplicate keys) */\n#endif\n\treturn;\n\n\t/*\n\t *  Abandon array failed.  We don't need to DECREF anything\n\t *  because the references in the new allocation are not\n\t *  INCREF'd until abandon is complete.  The string interned\n\t *  keys are on the value stack and are handled normally by\n\t *  unwind.\n\t */\n\n abandon_error:\n alloc_failed:\n\tDUK_D(DUK_DPRINT(\"object property table resize failed\"));\n\n\tDUK_FREE_CHECKED(thr, new_p);  /* OK for NULL. */\n\n\tthr->heap->pf_prevent_count--;\n\tthr->heap->ms_base_flags = prev_ms_base_flags;\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->heap->error_not_allowed == 1);\n\tthr->heap->error_not_allowed = prev_error_not_allowed;\n#endif\n\n\tDUK_ERROR_ALLOC_FAILED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Helpers to resize properties allocation on specific needs.\n */\n\nDUK_INTERNAL void duk_hobject_resize_entrypart(duk_hthread *thr,\n                                               duk_hobject *obj,\n                                               duk_uint32_t new_e_size) {\n\tduk_uint32_t old_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_h_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\told_e_size = DUK_HOBJECT_GET_ESIZE(obj);\n\tif (old_e_size > new_e_size) {\n\t\tnew_e_size = old_e_size;\n\t}\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tnew_h_size = duk__get_default_h_size(new_e_size);\n#else\n\tnew_h_size = 0;\n#endif\n\tnew_a_size = DUK_HOBJECT_GET_ASIZE(obj);\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);\n}\n\n/* Grow entry part allocation for one additional entry. */\nDUK_LOCAL void duk__grow_props_for_new_entry_item(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint32_t old_e_used;  /* actually used, non-NULL entries */\n\tduk_uint32_t new_e_size_minimum;\n\tduk_uint32_t new_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_h_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\t/* Duktape 0.11.0 and prior tried to optimize the resize by not\n\t * counting the number of actually used keys prior to the resize.\n\t * This worked mostly well but also caused weird leak-like behavior\n\t * as in: test-bug-object-prop-alloc-unbounded.js.  So, now we count\n\t * the keys explicitly to compute the new entry part size.\n\t */\n\n\told_e_used = duk__count_used_e_keys(thr, obj);\n\tnew_e_size_minimum = old_e_used + 1;\n\tnew_e_size = old_e_used + duk__get_min_grow_e(old_e_used);\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tnew_h_size = duk__get_default_h_size(new_e_size);\n#else\n\tnew_h_size = 0;\n#endif\n\tnew_a_size = DUK_HOBJECT_GET_ASIZE(obj);\n\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size > DUK_UINT16_MAX) {\n\t\tnew_e_size = DUK_UINT16_MAX;\n\t}\n\tif (new_h_size > DUK_UINT16_MAX) {\n\t\tnew_h_size = DUK_UINT16_MAX;\n\t}\n\tif (new_a_size > DUK_UINT16_MAX) {\n\t\tnew_a_size = DUK_UINT16_MAX;\n\t}\n#endif\n\tDUK_ASSERT(new_h_size == 0 || new_h_size >= new_e_size);\n\n\tif (!(new_e_size >= new_e_size_minimum)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);\n}\n\n/* Grow array part for a new highest array index. */\nDUK_LOCAL void duk__grow_props_for_array_item(duk_hthread *thr, duk_hobject *obj, duk_uint32_t highest_arr_idx) {\n\tduk_uint32_t new_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_a_size_minimum;\n\tduk_uint32_t new_h_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(highest_arr_idx >= DUK_HOBJECT_GET_ASIZE(obj));\n\n\tnew_e_size = DUK_HOBJECT_GET_ESIZE(obj);\n\tnew_h_size = DUK_HOBJECT_GET_HSIZE(obj);\n\tnew_a_size_minimum = highest_arr_idx + 1;\n\tnew_a_size = highest_arr_idx + duk__get_min_grow_a(highest_arr_idx);\n\tDUK_ASSERT(new_a_size >= highest_arr_idx + 1);  /* duk__get_min_grow_a() is always >= 1 */\n\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size > DUK_UINT16_MAX) {\n\t\tnew_e_size = DUK_UINT16_MAX;\n\t}\n\tif (new_h_size > DUK_UINT16_MAX) {\n\t\tnew_h_size = DUK_UINT16_MAX;\n\t}\n\tif (new_a_size > DUK_UINT16_MAX) {\n\t\tnew_a_size = DUK_UINT16_MAX;\n\t}\n#endif\n\n\tif (!(new_a_size >= new_a_size_minimum)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);\n}\n\n/* Abandon array part, moving array entries into entries part.\n * This requires a props resize, which is a heavy operation.\n * We also compact the entries part while we're at it, although\n * this is not strictly required.\n */\nDUK_LOCAL void duk__abandon_array_part(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint32_t new_e_size_minimum;\n\tduk_uint32_t new_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_h_size;\n\tduk_uint32_t e_used;  /* actually used, non-NULL keys */\n\tduk_uint32_t a_used;\n\tduk_uint32_t a_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\te_used = duk__count_used_e_keys(thr, obj);\n\tduk__compute_a_stats(thr, obj, &a_used, &a_size);\n\n\t/*\n\t *  Must guarantee all actually used array entries will fit into\n\t *  new entry part.  Add one growth step to ensure we don't run out\n\t *  of space right away.\n\t */\n\n\tnew_e_size_minimum = e_used + a_used;\n\tnew_e_size = new_e_size_minimum + duk__get_min_grow_e(new_e_size_minimum);\n\tnew_a_size = 0;\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tnew_h_size = duk__get_default_h_size(new_e_size);\n#else\n\tnew_h_size = 0;\n#endif\n\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size > DUK_UINT16_MAX) {\n\t\tnew_e_size = DUK_UINT16_MAX;\n\t}\n\tif (new_h_size > DUK_UINT16_MAX) {\n\t\tnew_h_size = DUK_UINT16_MAX;\n\t}\n\tif (new_a_size > DUK_UINT16_MAX) {\n\t\tnew_a_size = DUK_UINT16_MAX;\n\t}\n#endif\n\n\tif (!(new_e_size >= new_e_size_minimum)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"abandon array part for hobject %p, \"\n\t                   \"array stats before: e_used=%ld, a_used=%ld, a_size=%ld; \"\n\t                   \"resize to e_size=%ld, a_size=%ld, h_size=%ld\",\n\t                   (void *) obj, (long) e_used, (long) a_used, (long) a_size,\n\t                   (long) new_e_size, (long) new_a_size, (long) new_h_size));\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 1);\n}\n\n/*\n *  Compact an object.  Minimizes allocation size for objects which are\n *  not likely to be extended.  This is useful for internal and non-\n *  extensible objects, but can also be called for non-extensible objects.\n *  May abandon the array part if it is computed to be too sparse.\n *\n *  This call is relatively expensive, as it needs to scan both the\n *  entries and the array part.\n *\n *  The call may fail due to allocation error.\n */\n\nDUK_INTERNAL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint32_t e_size;       /* currently used -> new size */\n\tduk_uint32_t a_size;       /* currently required */\n\tduk_uint32_t a_used;       /* actually used */\n\tduk_uint32_t h_size;\n\tduk_bool_t abandon_array;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"ignore attempt to compact a rom object\"));\n\t\treturn;\n\t}\n#endif\n\n\te_size = duk__count_used_e_keys(thr, obj);\n\tduk__compute_a_stats(thr, obj, &a_used, &a_size);\n\n\tDUK_DD(DUK_DDPRINT(\"compacting hobject, used e keys %ld, used a keys %ld, min a size %ld, \"\n\t                   \"resized array density would be: %ld/%ld = %lf\",\n\t                   (long) e_size, (long) a_used, (long) a_size,\n\t                   (long) a_used, (long) a_size,\n\t                   (double) a_used / (double) a_size));\n\n\tif (duk__abandon_array_density_check(a_used, a_size)) {\n\t\tDUK_DD(DUK_DDPRINT(\"decided to abandon array during compaction, a_used=%ld, a_size=%ld\",\n\t\t                   (long) a_used, (long) a_size));\n\t\tabandon_array = 1;\n\t\te_size += a_used;\n\t\ta_size = 0;\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"decided to keep array during compaction\"));\n\t\tabandon_array = 0;\n\t}\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (e_size >= DUK_USE_HOBJECT_HASH_PROP_LIMIT) {\n\t\th_size = duk__get_default_h_size(e_size);\n\t} else {\n\t\th_size = 0;\n\t}\n#else\n\th_size = 0;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"compacting hobject -> new e_size %ld, new a_size=%ld, new h_size=%ld, abandon_array=%ld\",\n\t                   (long) e_size, (long) a_size, (long) h_size, (long) abandon_array));\n\n\tduk_hobject_realloc_props(thr, obj, e_size, a_size, h_size, abandon_array);\n}\n\n/*\n *  Find an existing key from entry part either by linear scan or by\n *  using the hash index (if it exists).\n *\n *  Sets entry index (and possibly the hash index) to output variables,\n *  which allows the caller to update the entry and hash entries in-place.\n *  If entry is not found, both values are set to -1.  If entry is found\n *  but there is no hash part, h_idx is set to -1.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_find_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx) {\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(e_idx != NULL);\n\tDUK_ASSERT(h_idx != NULL);\n\tDUK_UNREF(heap);\n\n\tif (DUK_LIKELY(DUK_HOBJECT_GET_HSIZE(obj) == 0))\n\t{\n\t\t/* Linear scan: more likely because most objects are small.\n\t\t * This is an important fast path.\n\t\t *\n\t\t * XXX: this might be worth inlining for property lookups.\n\t\t */\n\t\tduk_uint_fast32_t i;\n\t\tduk_uint_fast32_t n;\n\t\tduk_hstring **h_keys_base;\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk_hobject_find_entry() using linear scan for lookup\"));\n\n\t\th_keys_base = DUK_HOBJECT_E_GET_KEY_BASE(heap, obj);\n\t\tn = DUK_HOBJECT_GET_ENEXT(obj);\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tif (h_keys_base[i] == key) {\n\t\t\t\t*e_idx = (duk_int_t) i;\n\t\t\t\t*h_idx = -1;\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t}\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\telse\n\t{\n\t\t/* hash lookup */\n\t\tduk_uint32_t n;\n\t\tduk_uint32_t i, step;\n\t\tduk_uint32_t *h_base;\n\t\tduk_uint32_t mask;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk_hobject_find_entry() using hash part for lookup\"));\n\n\t\th_base = DUK_HOBJECT_H_GET_BASE(heap, obj);\n\t\tn = DUK_HOBJECT_GET_HSIZE(obj);\n\t\tmask = n - 1;\n\t\ti = DUK_HSTRING_GET_HASH(key) & mask;\n\t\tstep = 1;  /* Cache friendly but clustering prone. */\n\n\t\tfor (;;) {\n\t\t\tduk_uint32_t t;\n\n\t\t\tDUK_ASSERT_DISABLE(i >= 0);  /* unsigned */\n\t\t\tDUK_ASSERT(i < DUK_HOBJECT_GET_HSIZE(obj));\n\t\t\tt = h_base[i];\n\t\t\tDUK_ASSERT(t == DUK__HASH_UNUSED || t == DUK__HASH_DELETED ||\n\t\t\t           (t < DUK_HOBJECT_GET_ESIZE(obj)));  /* t >= 0 always true, unsigned */\n\n\t\t\tif (t == DUK__HASH_UNUSED) {\n\t\t\t\tbreak;\n\t\t\t} else if (t == DUK__HASH_DELETED) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"lookup miss (deleted) i=%ld, t=%ld\",\n\t\t\t\t                     (long) i, (long) t));\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(t < DUK_HOBJECT_GET_ESIZE(obj));\n\t\t\t\tif (DUK_HOBJECT_E_GET_KEY(heap, obj, t) == key) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"lookup hit i=%ld, t=%ld -> key %p\",\n\t\t\t\t\t                     (long) i, (long) t, (void *) key));\n\t\t\t\t\t*e_idx = (duk_int_t) t;\n\t\t\t\t\t*h_idx = (duk_int_t) i;\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"lookup miss i=%ld, t=%ld\",\n\t\t\t\t                     (long) i, (long) t));\n\t\t\t}\n\t\t\ti = (i + step) & mask;\n\n\t\t\t/* Guaranteed to finish (hash is larger than #props). */\n\t\t}\n\t}\n#endif  /* DUK_USE_HOBJECT_HASH_PART */\n\n\t/* Not found, leave e_idx and h_idx unset. */\n\treturn 0;\n}\n\n/* For internal use: get non-accessor entry value */\nDUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key) {\n\tduk_int_t e_idx;\n\tduk_int_t h_idx;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_UNREF(heap);\n\n\tif (duk_hobject_find_entry(heap, obj, key, &e_idx, &h_idx)) {\n\t\tDUK_ASSERT(e_idx >= 0);\n\t\tif (!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {\n\t\t\treturn DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);\n\t\t}\n\t}\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx) {\n\treturn duk_hobject_find_entry_tval_ptr(heap, obj, DUK_HEAP_GET_STRING(heap, stridx));\n}\n\n/* For internal use: get non-accessor entry value and attributes */\nDUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs) {\n\tduk_int_t e_idx;\n\tduk_int_t h_idx;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_attrs != NULL);\n\tDUK_UNREF(heap);\n\n\tif (duk_hobject_find_entry(heap, obj, key, &e_idx, &h_idx)) {\n\t\tDUK_ASSERT(e_idx >= 0);\n\t\tif (!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {\n\t\t\t*out_attrs = DUK_HOBJECT_E_GET_FLAGS(heap, obj, e_idx);\n\t\t\treturn DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);\n\t\t}\n\t}\n\t/* If not found, out_attrs is left unset. */\n\treturn NULL;\n}\n\n/* For internal use: get array part value */\nDUK_INTERNAL duk_tval *duk_hobject_find_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(heap);\n\n\tif (!DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\treturn NULL;\n\t}\n\tif (i >= DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\treturn NULL;\n\t}\n\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(heap, obj, i);\n\treturn tv;\n}\n\n/*\n *  Allocate and initialize a new entry, resizing the properties allocation\n *  if necessary.  Returns entry index (e_idx) or throws an error if alloc fails.\n *\n *  Sets the key of the entry (increasing the key's refcount), and updates\n *  the hash part if it exists.  Caller must set value and flags, and update\n *  the entry value refcount.  A decref for the previous value is not necessary.\n */\n\nDUK_LOCAL duk_int_t duk__hobject_alloc_entry_checked(duk_hthread *thr, duk_hobject *obj, duk_hstring *key) {\n\tduk_uint32_t idx;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(obj) <= DUK_HOBJECT_GET_ESIZE(obj));\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* key must not already exist in entry part */\n\t{\n\t\tduk_uint_fast32_t i;\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != key);\n\t\t}\n\t}\n#endif\n\n\tif (DUK_HOBJECT_GET_ENEXT(obj) >= DUK_HOBJECT_GET_ESIZE(obj)) {\n\t\t/* only need to guarantee 1 more slot, but allocation growth is in chunks */\n\t\tDUK_DDD(DUK_DDDPRINT(\"entry part full, allocate space for one more entry\"));\n\t\tduk__grow_props_for_new_entry_item(thr, obj);\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(obj) < DUK_HOBJECT_GET_ESIZE(obj));\n\tidx = DUK_HOBJECT_POSTINC_ENEXT(obj);\n\n\t/* previous value is assumed to be garbage, so don't touch it */\n\tDUK_HOBJECT_E_SET_KEY(thr->heap, obj, idx, key);\n\tDUK_HSTRING_INCREF(thr, key);\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (DUK_UNLIKELY(DUK_HOBJECT_GET_HSIZE(obj) > 0)) {\n\t\tduk_uint32_t n, mask;\n\t\tduk_uint32_t i, step;\n\t\tduk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(thr->heap, obj);\n\n\t\tn = DUK_HOBJECT_GET_HSIZE(obj);\n\t\tmask = n - 1;\n\t\ti = DUK_HSTRING_GET_HASH(key) & mask;\n\t\tstep = 1;  /* Cache friendly but clustering prone. */\n\n\t\tfor (;;) {\n\t\t\tduk_uint32_t t = h_base[i];\n\t\t\tif (t == DUK__HASH_UNUSED || t == DUK__HASH_DELETED) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__hobject_alloc_entry_checked() inserted key into hash part, %ld -> %ld\",\n\t\t\t\t                     (long) i, (long) idx));\n\t\t\t\tDUK_ASSERT_DISABLE(i >= 0);  /* unsigned */\n\t\t\t\tDUK_ASSERT(i < DUK_HOBJECT_GET_HSIZE(obj));\n\t\t\t\tDUK_ASSERT_DISABLE(idx >= 0);\n\t\t\t\tDUK_ASSERT(idx < DUK_HOBJECT_GET_ESIZE(obj));\n\t\t\t\th_base[i] = idx;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__hobject_alloc_entry_checked() miss %ld\", (long) i));\n\t\t\ti = (i + step) & mask;\n\n\t\t\t/* Guaranteed to finish (hash is larger than #props). */\n\t\t}\n\t}\n#endif  /* DUK_USE_HOBJECT_HASH_PART */\n\n\t/* Note: we could return the hash index here too, but it's not\n\t * needed right now.\n\t */\n\n\tDUK_ASSERT_DISABLE(idx >= 0);\n\tDUK_ASSERT(idx < DUK_HOBJECT_GET_ESIZE(obj));\n\tDUK_ASSERT(idx < DUK_HOBJECT_GET_ENEXT(obj));\n\treturn (duk_int_t) idx;\n}\n\n/*\n *  Object internal value\n *\n *  Returned value is guaranteed to be reachable / incref'd, caller does not need\n *  to incref OR decref.  No proxies or accessors are invoked, no prototype walk.\n */\n\nDUK_INTERNAL duk_tval *duk_hobject_get_internal_value_tval_ptr(duk_heap *heap, duk_hobject *obj) {\n\treturn duk_hobject_find_entry_tval_ptr_stridx(heap, obj, DUK_STRIDX_INT_VALUE);\n}\n\nDUK_LOCAL duk_heaphdr *duk_hobject_get_internal_value_heaphdr(duk_heap *heap, duk_hobject *obj) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\ttv = duk_hobject_get_internal_value_tval_ptr(heap, obj);\n\tif (tv != NULL) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn h;\n\t}\n\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *heap, duk_hobject *obj) {\n\tduk_hstring *h;\n\n\th = (duk_hstring *) duk_hobject_get_internal_value_heaphdr(heap, obj);\n\tif (h != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_IS_STRING((duk_heaphdr *) h));\n\t}\n\treturn h;\n}\n\nDUK_LOCAL duk_hobject *duk__hobject_get_entry_object_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(heap, obj, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn h;\n\t}\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_harray *duk_hobject_get_formals(duk_hthread *thr, duk_hobject *obj) {\n\tduk_harray *h;\n\n\th = (duk_harray *) duk__hobject_get_entry_object_stridx(thr->heap, obj, DUK_STRIDX_INT_FORMALS);\n\tif (h != NULL) {\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) h));\n\t\tDUK_ASSERT(h->length <= DUK_HOBJECT_GET_ASIZE((duk_hobject *) h));\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_hobject_get_varmap(duk_hthread *thr, duk_hobject *obj) {\n\tduk_hobject *h;\n\n\th = duk__hobject_get_entry_object_stridx(thr->heap, obj, DUK_STRIDX_INT_VARMAP);\n\treturn h;\n}\n\n/*\n *  Arguments handling helpers (argument map mainly).\n *\n *  An arguments object has exotic behavior for some numeric indices.\n *  Accesses may translate to identifier operations which may have\n *  arbitrary side effects (potentially invalidating any duk_tval\n *  pointers).\n */\n\n/* Lookup 'key' from arguments internal 'map', perform a variable lookup\n * if mapped, and leave the result on top of stack (and return non-zero).\n * Used in E5 Section 10.6 algorithms [[Get]] and [[GetOwnProperty]].\n */\nDUK_LOCAL\nduk_bool_t duk__lookup_arguments_map(duk_hthread *thr,\n                                     duk_hobject *obj,\n                                     duk_hstring *key,\n                                     duk_propdesc *temp_desc,\n                                     duk_hobject **out_map,\n                                     duk_hobject **out_varenv) {\n\tduk_hobject *map;\n\tduk_hobject *varenv;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments map lookup: thr=%p, obj=%p, key=%p, temp_desc=%p \"\n\t                     \"(obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (void *) temp_desc,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tif (!duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_MAP(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> no 'map'\"));\n\t\treturn 0;\n\t}\n\n\tmap = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(map != NULL);\n\tduk_pop_unsafe(thr);  /* map is reachable through obj */\n\n\tif (!duk_hobject_get_own_propdesc(thr, map, key, temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> 'map' exists, but key not in map\"));\n\t\treturn 0;\n\t}\n\n\t/* [... varname] */\n\tDUK_DDD(DUK_DDDPRINT(\"-> 'map' exists, and contains key, key is mapped to argument/variable binding %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\tDUK_ASSERT(duk_is_string(thr, -1));  /* guaranteed when building arguments */\n\n\t/* get varenv for varname (callee's declarative lexical environment) */\n\trc = duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_VARENV(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE);\n\tDUK_UNREF(rc);\n\tDUK_ASSERT(rc != 0);  /* arguments MUST have an initialized lexical environment reference */\n\tvarenv = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(varenv != NULL);\n\tduk_pop_unsafe(thr);  /* varenv remains reachable through 'obj' */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments varenv is: %!dO\", (duk_heaphdr *) varenv));\n\n\t/* success: leave varname in stack */\n\t*out_map = map;\n\t*out_varenv = varenv;\n\treturn 1;  /* [... varname] */\n}\n\n/* Lookup 'key' from arguments internal 'map', and leave replacement value\n * on stack top if mapped (and return non-zero).\n * Used in E5 Section 10.6 algorithm for [[GetOwnProperty]] (used by [[Get]]).\n */\nDUK_LOCAL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc) {\n\tduk_hobject *map;\n\tduk_hobject *varenv;\n\tduk_hstring *varname;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk__lookup_arguments_map(thr, obj, key, temp_desc, &map, &varenv)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arguments: key not mapped, no exotic get behavior\"));\n\t\treturn 0;\n\t}\n\n\t/* [... varname] */\n\n\tvarname = duk_require_hstring(thr, -1);\n\tDUK_ASSERT(varname != NULL);\n\tduk_pop_unsafe(thr);  /* varname is still reachable */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments object automatic getvar for a bound variable; \"\n\t                     \"key=%!O, varname=%!O\",\n\t                     (duk_heaphdr *) key,\n\t                     (duk_heaphdr *) varname));\n\n\t(void) duk_js_getvar_envrec(thr, varenv, varname, 1 /*throw*/);\n\n\t/* [... value this_binding] */\n\n\tduk_pop_unsafe(thr);\n\n\t/* leave result on stack top */\n\treturn 1;\n}\n\n/* Lookup 'key' from arguments internal 'map', perform a variable write if mapped.\n * Used in E5 Section 10.6 algorithm for [[DefineOwnProperty]] (used by [[Put]]).\n * Assumes stack top contains 'put' value (which is NOT popped).\n */\nDUK_LOCAL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc, duk_bool_t throw_flag) {\n\tduk_hobject *map;\n\tduk_hobject *varenv;\n\tduk_hstring *varname;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk__lookup_arguments_map(thr, obj, key, temp_desc, &map, &varenv)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arguments: key not mapped, no exotic put behavior\"));\n\t\treturn;\n\t}\n\n\t/* [... put_value varname] */\n\n\tvarname = duk_require_hstring(thr, -1);\n\tDUK_ASSERT(varname != NULL);\n\tduk_pop_unsafe(thr);  /* varname is still reachable */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments object automatic putvar for a bound variable; \"\n\t                     \"key=%!O, varname=%!O, value=%!T\",\n\t                     (duk_heaphdr *) key,\n\t                     (duk_heaphdr *) varname,\n\t                     (duk_tval *) duk_require_tval(thr, -1)));\n\n\t/* [... put_value] */\n\n\t/*\n\t *  Note: although arguments object variable mappings are only established\n\t *  for non-strict functions (and a call to a non-strict function created\n\t *  the arguments object in question), an inner strict function may be doing\n\t *  the actual property write.  Hence the throw_flag applied here comes from\n\t *  the property write call.\n\t */\n\n\tduk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(thr, -1), throw_flag);\n\n\t/* [... put_value] */\n}\n\n/* Lookup 'key' from arguments internal 'map', delete mapping if found.\n * Used in E5 Section 10.6 algorithm for [[Delete]].  Note that the\n * variable/argument itself (where the map points) is not deleted.\n */\nDUK_LOCAL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc) {\n\tduk_hobject *map;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_MAP(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arguments: key not mapped, no exotic delete behavior\"));\n\t\treturn;\n\t}\n\n\tmap = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(map != NULL);\n\tduk_pop_unsafe(thr);  /* map is reachable through obj */\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> have 'map', delete key %!O from map (if exists)); ignore result\",\n\t                     (duk_heaphdr *) key));\n\n\t/* Note: no recursion issue, we can trust 'map' to behave */\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR(map));\n\tDUK_DDD(DUK_DDDPRINT(\"map before deletion: %!O\", (duk_heaphdr *) map));\n\t(void) duk_hobject_delprop_raw(thr, map, key, 0);  /* ignore result */\n\tDUK_DDD(DUK_DDDPRINT(\"map after deletion: %!O\", (duk_heaphdr *) map));\n}\n\n/*\n *  ECMAScript compliant [[GetOwnProperty]](P), for internal use only.\n *\n *  If property is found:\n *    - Fills descriptor fields to 'out_desc'\n *    - If DUK_GETDESC_FLAG_PUSH_VALUE is set, pushes a value related to the\n *      property onto the stack ('undefined' for accessor properties).\n *    - Returns non-zero\n *\n *  If property is not found:\n *    - 'out_desc' is left in untouched state (possibly garbage)\n *    - Nothing is pushed onto the stack (not even with DUK_GETDESC_FLAG_PUSH_VALUE\n *      set)\n *    - Returns zero\n *\n *  Notes:\n *\n *    - Getting a property descriptor may cause an allocation (and hence\n *      GC) to take place, hence reachability and refcount of all related\n *      values matter.  Reallocation of value stack, properties, etc may\n *      invalidate many duk_tval pointers (concretely, those which reside\n *      in memory areas subject to reallocation).  However, heap object\n *      pointers are never affected (heap objects have stable pointers).\n *\n *    - The value of a plain property is always reachable and has a non-zero\n *      reference count.\n *\n *    - The value of a virtual property is not necessarily reachable from\n *      elsewhere and may have a refcount of zero.  Hence we push it onto\n *      the valstack for the caller, which ensures it remains reachable\n *      while it is needed.\n *\n *    - There are no virtual accessor properties.  Hence, all getters and\n *      setters are always related to concretely stored properties, which\n *      ensures that the get/set functions in the resulting descriptor are\n *      reachable and have non-zero refcounts.  Should there be virtual\n *      accessor properties later, this would need to change.\n */\n\nDUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_uint32_t arr_idx, duk_propdesc *out_desc, duk_small_uint_t flags) {\n\tduk_tval *tv;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk_hobject_get_own_propdesc: thr=%p, obj=%p, key=%p, out_desc=%p, flags=%lx, \"\n\t                     \"arr_idx=%ld (obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (void *) out_desc,\n\t                     (long) flags, (long) arr_idx,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_desc != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_getownpropdesc_count);\n\n\t/* Each code path returning 1 (= found) must fill in all the output\n\t * descriptor fields.  We don't do it beforehand because it'd be\n\t * unnecessary work if the property isn't found and would happen\n\t * multiple times for an inheritance chain.\n\t */\n\tDUK_ASSERT_SET_GARBAGE(out_desc, sizeof(*out_desc));\n#if 0\n\tout_desc->flags = 0;\n\tout_desc->get = NULL;\n\tout_desc->set = NULL;\n\tout_desc->e_idx = -1;\n\tout_desc->h_idx = -1;\n\tout_desc->a_idx = -1;\n#endif\n\n\t/*\n\t *  Try entries part first because it's the common case.\n\t *\n\t *  Array part lookups are usually handled by the array fast path, and\n\t *  are not usually inherited.  Array and entry parts never contain the\n\t *  same keys so the entry part vs. array part order doesn't matter.\n\t */\n\n\tif (duk_hobject_find_entry(thr->heap, obj, key, &out_desc->e_idx, &out_desc->h_idx)) {\n\t\tduk_int_t e_idx = out_desc->e_idx;\n\t\tDUK_ASSERT(out_desc->e_idx >= 0);\n\t\tout_desc->a_idx = -1;\n\t\tout_desc->flags = DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, e_idx);\n\t\tout_desc->get = NULL;\n\t\tout_desc->set = NULL;\n\t\tif (DUK_UNLIKELY(out_desc->flags & DUK_PROPDESC_FLAG_ACCESSOR)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found accessor property in entry part\"));\n\t\t\tout_desc->get = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, e_idx);\n\t\t\tout_desc->set = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, e_idx);\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t/* a dummy undefined value is pushed to make valstack\n\t\t\t\t * behavior uniform for caller\n\t\t\t\t */\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t}\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found plain property in entry part\"));\n\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\tduk_push_tval(thr, tv);\n\t\t\t}\n\t\t}\n\t\tgoto prop_found;\n\t}\n\n\t/*\n\t *  Try array part.\n\t */\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj) && arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\tif (arr_idx < DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n\t\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found in array part\"));\n\t\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t\tduk_push_tval(thr, tv);\n\t\t\t\t}\n\t\t\t\t/* implicit attributes */\n\t\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t\t                  DUK_PROPDESC_FLAG_CONFIGURABLE |\n\t\t\t\t                  DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t\tout_desc->get = NULL;\n\t\t\t\tout_desc->set = NULL;\n\t\t\t\tout_desc->e_idx = -1;\n\t\t\t\tout_desc->h_idx = -1;\n\t\t\t\tout_desc->a_idx = (duk_int_t) arr_idx;  /* XXX: limit 2G due to being signed */\n\t\t\t\tgoto prop_found;\n\t\t\t}\n\t\t}\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> not found as a concrete property\"));\n\n\t/*\n\t *  Not found as a concrete property, check for virtual properties.\n\t */\n\n\tif (!DUK_HOBJECT_HAS_VIRTUAL_PROPERTIES(obj)) {\n\t\t/* Quick skip. */\n\t\tgoto prop_not_found;\n\t}\n\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\tduk_harray *a;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array object exotic property get for key: %!O, arr_idx: %ld\",\n\t\t                     (duk_heaphdr *) key, (long) arr_idx));\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, key is 'length', length exotic behavior\"));\n\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) a->length);\n\t\t\t}\n\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\tif (DUK_HARRAY_LENGTH_WRITABLE(a)) {\n\t\t\t\tout_desc->flags |= DUK_PROPDESC_FLAG_WRITABLE;\n\t\t\t}\n\t\t\tout_desc->get = NULL;\n\t\t\tout_desc->set = NULL;\n\t\t\tout_desc->e_idx = -1;\n\t\t\tout_desc->h_idx = -1;\n\t\t\tout_desc->a_idx = -1;\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t}\n\t} else if (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"string object exotic property get for key: %!O, arr_idx: %ld\",\n\t\t                     (duk_heaphdr *) key, (long) arr_idx));\n\n\t\t/* XXX: charlen; avoid multiple lookups? */\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t\tduk_hstring *h_val;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index exists\"));\n\n\t\t\th_val = duk_hobject_get_internal_value_string(thr->heap, obj);\n\t\t\tDUK_ASSERT(h_val);\n\t\t\tif (arr_idx < DUK_HSTRING_GET_CHARLEN(h_val)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, array index inside string\"));\n\t\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t\tduk_push_hstring(thr, h_val);\n\t\t\t\t\tduk_substring(thr, -1, arr_idx, arr_idx + 1);  /* [str] -> [substr] */\n\t\t\t\t}\n\t\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_ENUMERABLE |  /* E5 Section 15.5.5.2 */\n\t\t\t\t                  DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\t\tout_desc->get = NULL;\n\t\t\t\tout_desc->set = NULL;\n\t\t\t\tout_desc->e_idx = -1;\n\t\t\t\tout_desc->h_idx = -1;\n\t\t\t\tout_desc->a_idx = -1;\n\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t\t} else {\n\t\t\t\t/* index is above internal string length -> property is fully normal */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index outside string -> normal property\"));\n\t\t\t}\n\t\t} else if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tduk_hstring *h_val;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, key is 'length', length exotic behavior\"));\n\n\t\t\th_val = duk_hobject_get_internal_value_string(thr->heap, obj);\n\t\t\tDUK_ASSERT(h_val != NULL);\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h_val));\n\t\t\t}\n\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;  /* E5 Section 15.5.5.1 */\n\t\t\tout_desc->get = NULL;\n\t\t\tout_desc->set = NULL;\n\t\t\tout_desc->e_idx = -1;\n\t\t\tout_desc->h_idx = -1;\n\t\t\tout_desc->a_idx = -1;\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t}\n\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\telse if (DUK_HOBJECT_IS_BUFOBJ(obj)) {\n\t\tduk_hbufobj *h_bufobj;\n\t\tduk_uint_t byte_off;\n\t\tduk_small_uint_t elem_size;\n\n\t\th_bufobj = (duk_hbufobj *) obj;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\t\tDUK_DDD(DUK_DDDPRINT(\"bufobj property get for key: %!O, arr_idx: %ld\",\n\t\t                     (duk_heaphdr *) key, (long) arr_idx));\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index exists\"));\n\n\t\t\t/* Careful with wrapping: arr_idx upshift may easily wrap, whereas\n\t\t\t * length downshift won't.\n\t\t\t */\n\t\t\tif (arr_idx < (h_bufobj->length >> h_bufobj->shift)) {\n\t\t\t\tbyte_off = arr_idx << h_bufobj->shift;  /* no wrap assuming h_bufobj->length is valid */\n\t\t\t\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\t\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t\tduk_uint8_t *data;\n\n\t\t\t\t\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\t\t\t\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\t\t\t\t\tduk_hbufobj_push_validated_read(thr, h_bufobj, data, elem_size);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (read zero)\"));\n\t\t\t\t\t\tduk_push_uint(thr, 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t\t                  DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(obj) != DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\t\t\t\t/* ArrayBuffer indices are non-standard and are\n\t\t\t\t\t * non-enumerable to avoid their serialization.\n\t\t\t\t\t */\n\t\t\t\t\tout_desc->flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t\t}\n\t\t\t\tout_desc->get = NULL;\n\t\t\t\tout_desc->set = NULL;\n\t\t\t\tout_desc->e_idx = -1;\n\t\t\t\tout_desc->h_idx = -1;\n\t\t\t\tout_desc->a_idx = -1;\n\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\t\tgoto prop_found_noexotic;  /* cannot be e.g. arguments exotic, since exotic 'traits' are mutually exclusive */\n\t\t\t} else {\n\t\t\t\t/* index is above internal buffer length -> property is fully normal */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index outside buffer -> normal property\"));\n\t\t\t}\n\t\t} else if (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, key is 'length', length exotic behavior\"));\n\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t/* Length in elements: take into account shift, but\n\t\t\t\t * intentionally don't check the underlying buffer here.\n\t\t\t\t */\n\t\t\t\tduk_push_uint(thr, h_bufobj->length >> h_bufobj->shift);\n\t\t\t}\n\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\tout_desc->get = NULL;\n\t\t\tout_desc->set = NULL;\n\t\t\tout_desc->e_idx = -1;\n\t\t\tout_desc->h_idx = -1;\n\t\t\tout_desc->a_idx = -1;\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t}\n\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\t/* Array properties have exotic behavior but they are concrete,\n\t * so no special handling here.\n\t *\n\t * Arguments exotic behavior (E5 Section 10.6, [[GetOwnProperty]]\n\t * is only relevant as a post-check implemented below; hence no\n\t * check here.\n\t */\n\n\t/*\n\t *  Not found as concrete or virtual.\n\t */\n\n prop_not_found:\n\tDUK_DDD(DUK_DDDPRINT(\"-> not found (virtual, entry part, or array part)\"));\n\tDUK_STATS_INC(thr->heap, stats_getownpropdesc_miss);\n\treturn 0;\n\n\t/*\n\t *  Found.\n\t *\n\t *  Arguments object has exotic post-processing, see E5 Section 10.6,\n\t *  description of [[GetOwnProperty]] variant for arguments.\n\t */\n\n prop_found:\n\tDUK_DDD(DUK_DDDPRINT(\"-> property found, checking for arguments exotic post-behavior\"));\n\n\t/* Notes:\n\t *  - Only numbered indices are relevant, so arr_idx fast reject is good\n\t *    (this is valid unless there are more than 4**32-1 arguments).\n\t *  - Since variable lookup has no side effects, this can be skipped if\n\t *    DUK_GETDESC_FLAG_PUSH_VALUE is not set.\n\t */\n\n\tif (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) &&\n\t                 arr_idx != DUK__NO_ARRAY_INDEX &&\n\t                 (flags & DUK_GETDESC_FLAG_PUSH_VALUE))) {\n\t\tduk_propdesc temp_desc;\n\n\t\t/* Magically bound variable cannot be an accessor.  However,\n\t\t * there may be an accessor property (or a plain property) in\n\t\t * place with magic behavior removed.  This happens e.g. when\n\t\t * a magic property is redefined with defineProperty().\n\t\t * Cannot assert for \"not accessor\" here.\n\t\t */\n\n\t\t/* replaces top of stack with new value if necessary */\n\t\tDUK_ASSERT((flags & DUK_GETDESC_FLAG_PUSH_VALUE) != 0);\n\n\t\t/* This can perform a variable lookup but only into a declarative\n\t\t * environment which has no side effects.\n\t\t */\n\t\tif (duk__check_arguments_map_for_get(thr, obj, key, &temp_desc)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> arguments exotic behavior overrides result: %!T -> %!T\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\t/* [... old_result result] -> [... result] */\n\t\t\tduk_remove_m2(thr);\n\t\t}\n\t}\n\n prop_found_noexotic:\n\tDUK_STATS_INC(thr->heap, stats_getownpropdesc_hit);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_bool_t duk_hobject_get_own_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_desc != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\treturn duk__get_own_propdesc_raw(thr, obj, key, DUK_HSTRING_GET_ARRIDX_SLOW(key), out_desc, flags);\n}\n\n/*\n *  ECMAScript compliant [[GetProperty]](P), for internal use only.\n *\n *  If property is found:\n *    - Fills descriptor fields to 'out_desc'\n *    - If DUK_GETDESC_FLAG_PUSH_VALUE is set, pushes a value related to the\n *      property onto the stack ('undefined' for accessor properties).\n *    - Returns non-zero\n *\n *  If property is not found:\n *    - 'out_desc' is left in untouched state (possibly garbage)\n *    - Nothing is pushed onto the stack (not even with DUK_GETDESC_FLAG_PUSH_VALUE\n *      set)\n *    - Returns zero\n *\n *  May cause arbitrary side effects and invalidate (most) duk_tval\n *  pointers.\n */\n\nDUK_LOCAL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags) {\n\tduk_hobject *curr;\n\tduk_uint32_t arr_idx;\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_desc != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_getpropdesc_count);\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__get_propdesc: thr=%p, obj=%p, key=%p, out_desc=%p, flags=%lx, \"\n\t                     \"arr_idx=%ld (obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (void *) out_desc,\n\t                     (long) flags, (long) arr_idx,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tcurr = obj;\n\tDUK_ASSERT(curr != NULL);\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (duk__get_own_propdesc_raw(thr, curr, key, arr_idx, out_desc, flags)) {\n\t\t\t/* stack contains value (if requested), 'out_desc' is set */\n\t\t\tDUK_STATS_INC(thr->heap, stats_getpropdesc_hit);\n\t\t\treturn 1;\n\t\t}\n\n\t\t/* not found in 'curr', next in prototype chain; impose max depth */\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tif (flags & DUK_GETDESC_FLAG_IGNORE_PROTOLOOP) {\n\t\t\t\t/* treat like property not found */\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t} while (curr != NULL);\n\n\t/* out_desc is left untouched (possibly garbage), caller must use return\n\t * value to determine whether out_desc can be looked up\n\t */\n\n\tDUK_STATS_INC(thr->heap, stats_getpropdesc_miss);\n\treturn 0;\n}\n\n/*\n *  Shallow fast path checks for accessing array elements with numeric\n *  indices.  The goal is to try to avoid coercing an array index to an\n *  (interned) string for the most common lookups, in particular, for\n *  standard Array objects.\n *\n *  Interning is avoided but only for a very narrow set of cases:\n *    - Object has array part, index is within array allocation, and\n *      value is not unused (= key exists)\n *    - Object has no interfering exotic behavior (e.g. arguments or\n *      string object exotic behaviors interfere, array exotic\n *      behavior does not).\n *\n *  Current shortcoming: if key does not exist (even if it is within\n *  the array allocation range) a slow path lookup with interning is\n *  always required.  This can probably be fixed so that there is a\n *  quick fast path for non-existent elements as well, at least for\n *  standard Array objects.\n */\n\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\nDUK_LOCAL duk_tval *duk__getprop_shallow_fastpath_array_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key) {\n\tduk_tval *tv;\n\tduk_uint32_t idx;\n\n\tDUK_UNREF(thr);\n\n\tif (!(DUK_HOBJECT_HAS_ARRAY_PART(obj) &&\n\t     !DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) &&\n\t     !DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj) &&\n\t     !DUK_HOBJECT_IS_BUFOBJ(obj) &&\n\t     !DUK_HOBJECT_IS_PROXY(obj))) {\n\t\t/* Must have array part and no conflicting exotic behaviors.\n\t\t * Doesn't need to have array special behavior, e.g. Arguments\n\t\t * object has array part.\n\t\t */\n\t\treturn NULL;\n\t}\n\n\t/* Arrays never have other exotic behaviors. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"fast path attempt (no exotic string/arguments/buffer \"\n\t                     \"behavior, object has array part)\"));\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"key is not a number\"));\n\t\treturn NULL;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside object 'a_size'.\n\t */\n\n\tif (idx >= DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"key is not an array index or outside array part\"));\n\t\treturn NULL;\n\t}\n\tDUK_ASSERT(idx != 0xffffffffUL);\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\t/* XXX: for array instances we could take a shortcut here and assume\n\t * Array.prototype doesn't contain an array index property.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"key is a valid array index and inside array part\"));\n\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, idx);\n\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> fast path successful\"));\n\t\treturn tv;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"fast path attempt failed, fall back to slow path\"));\n\treturn NULL;\n}\n\nDUK_LOCAL duk_bool_t duk__putprop_shallow_fastpath_array_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val) {\n\tduk_tval *tv;\n\tduk_harray *a;\n\tduk_uint32_t idx;\n\tduk_uint32_t old_len, new_len;\n\n\tif (!(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj) &&\n\t      DUK_HOBJECT_HAS_ARRAY_PART(obj) &&\n\t      DUK_HOBJECT_HAS_EXTENSIBLE(obj))) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));  /* caller ensures */\n\n\ta = (duk_harray *) obj;\n\tDUK_HARRAY_ASSERT_VALID(a);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"key is not a number\"));\n\t\treturn 0;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside object 'a_size'.\n\t */\n\n\tif (idx >= DUK_HOBJECT_GET_ASIZE(obj)) {  /* for resizing of array part, use slow path */\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(idx != 0xffffffffUL);\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\told_len = a->length;\n\n\tif (idx >= old_len) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"write new array entry requires length update \"\n\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t                     (long) idx, (long) old_len));\n\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a)) {\n\t\t\t/* The correct behavior here is either a silent error\n\t\t\t * or a TypeError, depending on strictness.  Fall back\n\t\t\t * to the slow path to handle the situation.\n\t\t\t */\n\t\t\treturn 0;\n\t\t}\n\t\tnew_len = idx + 1;\n\n\t\t((duk_harray *) obj)->length = new_len;\n\t}\n\n\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, idx);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val);  /* side effects */\n\n\tDUK_DDD(DUK_DDDPRINT(\"array fast path success for index %ld\", (long) idx));\n\treturn 1;\n}\n#endif  /* DUK_USE_ARRAY_PROP_FASTPATH */\n\n/*\n *  Fast path for bufobj getprop/putprop\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL duk_bool_t duk__getprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key) {\n\tduk_uint32_t idx;\n\tduk_hbufobj *h_bufobj;\n\tduk_uint_t byte_off;\n\tduk_small_uint_t elem_size;\n\tduk_uint8_t *data;\n\n\tif (!DUK_HOBJECT_IS_BUFOBJ(obj)) {\n\t\treturn 0;\n\t}\n\th_bufobj = (duk_hbufobj *) obj;\n\tif (!DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\treturn 0;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\treturn 0;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside bufobj length.\n\t */\n\n\t/* Careful with wrapping (left shifting idx would be unsafe). */\n\tif (idx >= (h_bufobj->length >> h_bufobj->shift)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\tbyte_off = idx << h_bufobj->shift;  /* no wrap assuming h_bufobj->length is valid */\n\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\n\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\tduk_hbufobj_push_validated_read(thr, h_bufobj, data, elem_size);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (read zero)\"));\n\t\tduk_push_uint(thr, 0);\n\t}\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL duk_bool_t duk__putprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val) {\n\tduk_uint32_t idx;\n\tduk_hbufobj *h_bufobj;\n\tduk_uint_t byte_off;\n\tduk_small_uint_t elem_size;\n\tduk_uint8_t *data;\n\n\tif (!(DUK_HOBJECT_IS_BUFOBJ(obj) &&\n\t      DUK_TVAL_IS_NUMBER(tv_val))) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));  /* caller ensures; rom objects are never bufobjs now */\n\n\th_bufobj = (duk_hbufobj *) obj;\n\tif (!DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\treturn 0;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\treturn 0;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside bufobj length.\n\t */\n\n\t/* Careful with wrapping (left shifting idx would be unsafe). */\n\tif (idx >= (h_bufobj->length >> h_bufobj->shift)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\tbyte_off = idx << h_bufobj->shift;  /* no wrap assuming h_bufobj->length is valid */\n\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\n\t/* Value is required to be a number in the fast path so there\n\t * are no side effects in write coercion.\n\t */\n\tduk_push_tval(thr, tv_val);\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\n\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\tduk_hbufobj_validated_write(thr, h_bufobj, data, elem_size);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (write skipped)\"));\n\t}\n\n\tduk_pop_unsafe(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  GETPROP: ECMAScript property read.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) {\n\tduk_tval tv_obj_copy;\n\tduk_tval tv_key_copy;\n\tduk_hobject *curr = NULL;\n\tduk_hstring *key = NULL;\n\tduk_uint32_t arr_idx = DUK__NO_ARRAY_INDEX;\n\tduk_propdesc desc;\n\tduk_uint_t sanity;\n\n\tDUK_DDD(DUK_DDDPRINT(\"getprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key,\n\t                     (duk_tval *) tv_obj, (duk_tval *) tv_key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_getprop_all);\n\n\t/*\n\t *  Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of\n\t *  them being invalidated by a valstack resize.\n\t *\n\t *  XXX: this is now an overkill for many fast paths.  Rework this\n\t *  to be faster (although switching to a valstack discipline might\n\t *  be a better solution overall).\n\t */\n\n\tDUK_TVAL_SET_TVAL(&tv_obj_copy, tv_obj);\n\tDUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);\n\ttv_obj = &tv_obj_copy;\n\ttv_key = &tv_key_copy;\n\n\t/*\n\t *  Coercion and fast path processing\n\t */\n\n\tswitch (DUK_TVAL_GET_TAG(tv_obj)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL: {\n\t\t/* Note: unconditional throw */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is undefined or null -> reject\"));\n#if defined(DUK_USE_PARANOID_ERRORS)\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\t\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot read property %s of %s\",\n\t\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\t\tDUK_WO_NORETURN(return 0;);\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a boolean, start lookup from boolean prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);\n\t\tduk_int_t pop_count;\n\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\t/* Symbols (ES2015 or hidden) don't have virtual properties. */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a symbol, start lookup from symbol prototype\"));\n\t\t\tcurr = thr->builtins[DUK_BIDX_SYMBOL_PROTOTYPE];\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_FASTINT)\n\t\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\t\tarr_idx = duk__tval_fastint_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a fast-path fastint; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else\n#endif\n\t\tif (DUK_TVAL_IS_NUMBER(tv_key)) {\n\t\t\tarr_idx = duk__tval_number_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a fast-path number; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t\tpop_count = 1;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {\n\t\t\tduk_pop_n_unsafe(thr, pop_count);\n\t\t\tduk_push_hstring(thr, h);\n\t\t\tduk_substring(thr, -1, arr_idx, arr_idx + 1);  /* [str] -> [substr] */\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_stringidx);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is string, key is an index inside string length \"\n\t\t\t                     \"after coercion -> return char)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (pop_count == 0) {\n\t\t\t/* This is a pretty awkward control flow, but we need to recheck the\n\t\t\t * key coercion here.\n\t\t\t */\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tduk_pop_unsafe(thr);  /* [key] -> [] */\n\t\t\tduk_push_uint(thr, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h));  /* [] -> [res] */\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_stringlen);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is string, key is 'length' after coercion -> \"\n\t\t\t                     \"return string length)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a string, start lookup from string prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_STRING_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_OBJECT: {\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\n\t\tduk_tval *tmp;\n#endif\n\n\t\tcurr = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(curr != NULL);\n\n\t\t/* XXX: array .length fast path (important in e.g. loops)? */\n\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\n\t\ttmp = duk__getprop_shallow_fastpath_array_tval(thr, curr, tv_key);\n\t\tif (tmp) {\n\t\t\tduk_push_tval(thr, tmp);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is object, key is a number, array part \"\n\t\t\t                     \"fast path)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_arrayidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (duk__getprop_fastpath_bufobj_tval(thr, curr, tv_key) != 0) {\n\t\t\t/* Read value pushed on stack. */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is bufobj, key is a number, bufobj \"\n\t\t\t                     \"fast path)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_bufobjidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(curr))) {\n\t\t\tduk_hobject *h_target;\n\n\t\t\tif (duk__proxy_check_prop(thr, curr, DUK_STRIDX_GET, tv_key, &h_target)) {\n\t\t\t\t/* -> [ ... trap handler ] */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'get' for key %!T\", (duk_tval *) tv_key));\n\t\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_proxy);\n\t\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\t\tduk_push_tval(thr, tv_key);       /* P */\n\t\t\t\tduk_push_tval(thr, tv_obj);       /* Receiver: Proxy object */\n\t\t\t\tduk_call_method(thr, 3 /*nargs*/);\n\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\t\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\t\t\t\tduk_tval *tv_hook = duk_require_tval(thr, -3);  /* value from hook */\n\t\t\t\t\tduk_tval *tv_targ = duk_require_tval(thr, -1);  /* value from target */\n\t\t\t\t\tduk_bool_t datadesc_reject;\n\t\t\t\t\tduk_bool_t accdesc_reject;\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'get': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; tv_hook=%!T, tv_targ=%!T, desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (duk_tval *) tv_hook, (duk_tval *) tv_targ,\n\t\t\t\t\t                     (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\n\t\t\t\t\tdatadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) &&\n\t\t\t\t\t                  !duk_js_samevalue(tv_hook, tv_targ);\n\t\t\t\t\taccdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                 !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                 (desc.get == NULL) &&\n\t\t\t\t\t                 !DUK_TVAL_IS_UNDEFINED(tv_hook);\n\t\t\t\t\tif (datadesc_reject || accdesc_reject) {\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\n\t\t\t\t\tduk_pop_2_unsafe(thr);\n\t\t\t\t} else {\n\t\t\t\t\tduk_pop_unsafe(thr);\n\t\t\t\t}\n\t\t\t\treturn 1;  /* return value */\n\t\t\t}\n\n\t\t\tcurr = h_target;  /* resume lookup from target */\n\t\t\tDUK_TVAL_SET_OBJECT(tv_obj, curr);\n\t\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(curr)) {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_arguments);\n\t\t\tif (duk__check_arguments_map_for_get(thr, curr, key, &desc)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is object with arguments exotic behavior, \"\n\t\t\t\t                     \"key matches magically bound property -> skip standard \"\n\t\t\t\t                     \"Get with replacement value)\",\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t\t/* no need for 'caller' post-check, because 'key' must be an array index */\n\n\t\t\t\tduk_remove_m2(thr);  /* [key result] -> [result] */\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tgoto lookup;  /* avoid double coercion */\n\t\t}\n\t\tbreak;\n\t}\n\n\t/* Buffer has virtual properties similar to string, but indexed values\n\t * are numbers, not 1-byte buffers/strings which would perform badly.\n\t */\n\tcase DUK_TAG_BUFFER: {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);\n\t\tduk_int_t pop_count;\n\n\t\t/*\n\t\t *  Because buffer values are often looped over, a number fast path\n\t\t *  is important.\n\t\t */\n\n#if defined(DUK_USE_FASTINT)\n\t\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\t\tarr_idx = duk__tval_fastint_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path fastint; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t}\n\t\telse\n#endif\n\t\tif (DUK_TVAL_IS_NUMBER(tv_key)) {\n\t\t\tarr_idx = duk__tval_number_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path number; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t\tpop_count = 1;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HBUFFER_GET_SIZE(h)) {\n\t\t\tduk_pop_n_unsafe(thr, pop_count);\n\t\t\tduk_push_uint(thr, ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h))[arr_idx]);\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_bufferidx);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is buffer, key is an index inside buffer length \"\n\t\t\t                     \"after coercion -> return byte as number)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (pop_count == 0) {\n\t\t\t/* This is a pretty awkward control flow, but we need to recheck the\n\t\t\t * key coercion here.\n\t\t\t */\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tduk_pop_unsafe(thr);  /* [key] -> [] */\n\t\t\tduk_push_uint(thr, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h));  /* [] -> [res] */\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_bufferlen);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is buffer, key is 'length' \"\n\t\t\t                     \"after coercion -> return buffer length)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a buffer, start lookup from Uint8Array prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_POINTER: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a pointer, start lookup from pointer prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Lightfuncs inherit getter .name and .length from %NativeFunctionPrototype%. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a lightfunc, start lookup from function prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE];\n\t\tbreak;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a number, start lookup from number prototype\"));\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_obj));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_obj));\n\t\tcurr = thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE];\n\t\tbreak;\n\t}\n\t}\n\n\t/* key coercion (unless already coerced above) */\n\tDUK_ASSERT(key == NULL);\n\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\tDUK_ASSERT(key != NULL);\n\t/*\n\t *  Property lookup\n\t */\n\n lookup:\n\t/* [key] (coerced) */\n\tDUK_ASSERT(curr != NULL);\n\tDUK_ASSERT(key != NULL);\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (!duk__get_own_propdesc_raw(thr, curr, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\t\tgoto next_in_chain;\n\t\t}\n\n\t\tif (desc.get != NULL) {\n\t\t\t/* accessor with defined getter */\n\t\t\tDUK_ASSERT((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0);\n\n\t\t\tduk_pop_unsafe(thr);              /* [key undefined] -> [key] */\n\t\t\tduk_push_hobject(thr, desc.get);\n\t\t\tduk_push_tval(thr, tv_obj);       /* note: original, uncoerced base */\n#if defined(DUK_USE_NONSTD_GETTER_KEY_ARGUMENT)\n\t\t\tduk_dup_m3(thr);\n\t\t\tduk_call_method(thr, 1);          /* [key getter this key] -> [key retval] */\n#else\n\t\t\tduk_call_method(thr, 0);          /* [key getter this] -> [key retval] */\n#endif\n\t\t} else {\n\t\t\t/* [key value] or [key undefined] */\n\n\t\t\t/* data property or accessor without getter */\n\t\t\tDUK_ASSERT(((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) == 0) ||\n\t\t\t           (desc.get == NULL));\n\n\t\t\t/* if accessor without getter, return value is undefined */\n\t\t\tDUK_ASSERT(((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) == 0) ||\n\t\t\t           duk_is_undefined(thr, -1));\n\n\t\t\t/* Note: for an accessor without getter, falling through to\n\t\t\t * check for \"caller\" exotic behavior is unnecessary as\n\t\t\t * \"undefined\" will never activate the behavior.  But it does\n\t\t\t * no harm, so we'll do it anyway.\n\t\t\t */\n\t\t}\n\n\t\tgoto found;  /* [key result] */\n\n\t next_in_chain:\n\t\t/* XXX: option to pretend property doesn't exist if sanity limit is\n\t\t * hit might be useful.\n\t\t */\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t} while (curr != NULL);\n\n\t/*\n\t *  Not found\n\t */\n\n\tduk_to_undefined(thr, -1);  /* [key] -> [undefined] (default value) */\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (not found)\", (duk_tval *) duk_get_tval(thr, -1)));\n\treturn 0;\n\n\t/*\n\t *  Found; post-processing (Function and arguments objects)\n\t */\n\n found:\n\t/* [key result] */\n\n#if !defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t/* Special behavior for 'caller' property of (non-bound) function objects\n\t * and non-strict Arguments objects: if 'caller' -value- (!) is a strict\n\t * mode function, throw a TypeError (E5 Sections 15.3.5.4, 10.6).\n\t * Quite interestingly, a non-strict function with no formal arguments\n\t * will get an arguments object -without- special 'caller' behavior!\n\t *\n\t * The E5.1 spec is a bit ambiguous if this special behavior applies when\n\t * a bound function is the base value (not the 'caller' value): Section\n\t * 15.3.4.5 (describing bind()) states that [[Get]] for bound functions\n\t * matches that of Section 15.3.5.4 ([[Get]] for Function instances).\n\t * However, Section 13.3.5.4 has \"NOTE: Function objects created using\n\t * Function.prototype.bind use the default [[Get]] internal method.\"\n\t * The current implementation assumes this means that bound functions\n\t * should not have the special [[Get]] behavior.\n\t *\n\t * The E5.1 spec is also a bit unclear if the TypeError throwing is\n\t * applied if the 'caller' value is a strict bound function.  The\n\t * current implementation will throw even for both strict non-bound\n\t * and strict bound functions.\n\t *\n\t * See test-dev-strict-func-as-caller-prop-value.js for quite extensive\n\t * tests.\n\t *\n\t * This exotic behavior is disabled when the non-standard 'caller' property\n\t * is enabled, as it conflicts with the free use of 'caller'.\n\t */\n\tif (key == DUK_HTHREAD_STRING_CALLER(thr) &&\n\t    DUK_TVAL_IS_OBJECT(tv_obj)) {\n\t\tduk_hobject *orig = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(orig != NULL);\n\n\t\tif (DUK_HOBJECT_IS_NONBOUND_FUNCTION(orig) ||\n\t\t    DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(orig)) {\n\t\t\tduk_hobject *h;\n\n\t\t\t/* XXX: The TypeError is currently not applied to bound\n\t\t\t * functions because the 'strict' flag is not copied by\n\t\t\t * bind().  This may or may not be correct, the specification\n\t\t\t * only refers to the value being a \"strict mode Function\n\t\t\t * object\" which is ambiguous.\n\t\t\t */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(orig));\n\n\t\t\th = duk_get_hobject(thr, -1);  /* NULL if not an object */\n\t\t\tif (h &&\n\t\t\t    DUK_HOBJECT_IS_FUNCTION(h) &&\n\t\t\t    DUK_HOBJECT_HAS_STRICT(h)) {\n\t\t\t\t/* XXX: sufficient to check 'strict', assert for 'is function' */\n\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_STRICT_CALLER_READ);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\t}\n#endif   /* !DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */\n\n\tduk_remove_m2(thr);  /* [key result] -> [result] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (found)\", (duk_tval *) duk_get_tval(thr, -1)));\n\treturn 1;\n}\n\n/*\n *  HASPROP: ECMAScript property existence check (\"in\" operator).\n *\n *  Interestingly, the 'in' operator does not do any coercion of\n *  the target object.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) {\n\tduk_tval tv_key_copy;\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_uint32_t arr_idx;\n\tduk_bool_t rc;\n\tduk_propdesc desc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"hasprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key,\n\t                     (duk_tval *) tv_obj, (duk_tval *) tv_key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);\n\ttv_key = &tv_key_copy;\n\n\t/*\n\t *  The 'in' operator requires an object as its right hand side,\n\t *  throwing a TypeError unconditionally if this is not the case.\n\t *\n\t *  However, lightfuncs need to behave like fully fledged objects\n\t *  here to be maximally transparent, so we need to handle them\n\t *  here.  Same goes for plain buffers which behave like ArrayBuffers.\n\t */\n\n\t/* XXX: Refactor key coercion so that it's only called once.  It can't\n\t * be trivially lifted here because the object must be type checked\n\t * first.\n\t */\n\n\tif (DUK_TVAL_IS_OBJECT(tv_obj)) {\n\t\tobj = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(obj != NULL);\n\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t} else if (DUK_TVAL_IS_BUFFER(tv_obj)) {\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\tif (duk__key_is_plain_buf_ownprop(thr, DUK_TVAL_GET_BUFFER(tv_obj), key, arr_idx)) {\n\t\t\trc = 1;\n\t\t\tgoto pop_and_return;\n\t\t}\n\t\tobj = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) {\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\n\t\t/* If not found, resume existence check from %NativeFunctionPrototype%.\n\t\t * We can just substitute the value in this case; nothing will\n\t\t * need the original base value (as would be the case with e.g.\n\t\t * setters/getters.\n\t\t */\n\t\tobj = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE];\n\t} else {\n\t\t/* Note: unconditional throw */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is not an object -> reject\"));\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* XXX: fast path for arrays? */\n\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(arr_idx);\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(obj))) {\n\t\tduk_hobject *h_target;\n\t\tduk_bool_t tmp_bool;\n\n\t\t/* XXX: the key in 'key in obj' is string coerced before we're called\n\t\t * (which is the required behavior in E5/E5.1/E6) so the key is a string\n\t\t * here already.\n\t\t */\n\n\t\tif (duk__proxy_check_prop(thr, obj, DUK_STRIDX_HAS, tv_key, &h_target)) {\n\t\t\t/* [ ... key trap handler ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'has' for key %!T\", (duk_tval *) tv_key));\n\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\tduk_push_tval(thr, tv_key);       /* P */\n\t\t\tduk_call_method(thr, 2 /*nargs*/);\n\t\t\ttmp_bool = duk_to_boolean_top_pop(thr);\n\t\t\tif (!tmp_bool) {\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'has': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\t\t\t\t\t/* XXX: Extensibility check for target uses IsExtensible().  If we\n\t\t\t\t\t * implemented the isExtensible trap and didn't reject proxies as\n\t\t\t\t\t * proxy targets, it should be respected here.\n\t\t\t\t\t */\n\t\t\t\t\tif (!((desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&  /* property is configurable and */\n\t\t\t\t\t      DUK_HOBJECT_HAS_EXTENSIBLE(h_target))) {          /* ... target is extensible */\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_pop_unsafe(thr);  /* [ key ] -> [] */\n\t\t\treturn tmp_bool;\n\t\t}\n\n\t\tobj = h_target;  /* resume check from proxy target */\n\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t/* XXX: inline into a prototype walking loop? */\n\n\trc = duk__get_propdesc(thr, obj, key, &desc, 0 /*flags*/);  /* don't push value */\n\t/* fall through */\n\n pop_and_return:\n\tduk_pop_unsafe(thr);  /* [ key ] -> [] */\n\treturn rc;\n}\n\n/*\n *  HASPROP variant used internally.\n *\n *  This primitive must never throw an error, callers rely on this.\n *  In particular, don't throw an error for prototype loops; instead,\n *  pretend like the property doesn't exist if a prototype sanity limit\n *  is reached.\n *\n *  Does not implement proxy behavior: if applied to a proxy object,\n *  returns key existence on the proxy object itself.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key) {\n\tduk_propdesc dummy;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\treturn duk__get_propdesc(thr, obj, key, &dummy, DUK_GETDESC_FLAG_IGNORE_PROTOLOOP);  /* don't push value */\n}\n\n/*\n *  Helper: handle Array object 'length' write which automatically\n *  deletes properties, see E5 Section 15.4.5.1, step 3.  This is\n *  quite tricky to get right.\n *\n *  Used by duk_hobject_putprop().\n */\n\n/* Coerce a new .length candidate to a number and check that it's a valid\n * .length.\n */\nDUK_LOCAL duk_uint32_t duk__to_new_array_length_checked(duk_hthread *thr, duk_tval *tv) {\n\tduk_uint32_t res;\n\tduk_double_t d;\n\n#if !defined(DUK_USE_PREFER_SIZE)\n#if defined(DUK_USE_FASTINT)\n\t/* When fastints are enabled, the most interesting case is assigning\n\t * a fastint to .length (e.g. arr.length = 0).\n\t */\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\t/* Very common case. */\n\t\tduk_int64_t fi;\n\t\tfi = DUK_TVAL_GET_FASTINT(tv);\n\t\tif (fi < 0 || fi > DUK_I64_CONSTANT(0xffffffff)) {\n\t\t\tgoto fail_range;\n\t\t}\n\t\treturn (duk_uint32_t) fi;\n\t}\n#else  /* DUK_USE_FASTINT */\n\t/* When fastints are not enabled, the most interesting case is any\n\t * number.\n\t */\n\tif (DUK_TVAL_IS_DOUBLE(tv)) {\n\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t}\n#endif  /* DUK_USE_FASTINT */\n\telse\n#endif  /* !DUK_USE_PREFER_SIZE */\n\t{\n\t\t/* In all other cases, and when doing a size optimized build,\n\t\t * fall back to the comprehensive handler.\n\t\t */\n\t\td = duk_js_tonumber(thr, tv);\n\t}\n\n\t/* Refuse to update an Array's 'length' to a value outside the\n\t * 32-bit range.  Negative zero is accepted as zero.\n\t */\n\tres = duk_double_to_uint32_t(d);\n\tif ((duk_double_t) res != d) {\n\t\tgoto fail_range;\n\t}\n\n\treturn res;\n\n fail_range:\n\tDUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARRAY_LENGTH);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Delete elements required by a smaller length, taking into account\n * potentially non-configurable elements.  Returns non-zero if all\n * elements could be deleted, and zero if all or some elements could\n * not be deleted.  Also writes final \"target length\" to 'out_result_len'.\n * This is the length value that should go into the 'length' property\n * (must be set by the caller).  Never throws an error.\n */\nDUK_LOCAL\nduk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr,\n                                                duk_hobject *obj,\n                                                duk_uint32_t old_len,\n                                                duk_uint32_t new_len,\n                                                duk_bool_t force_flag,\n                                                duk_uint32_t *out_result_len) {\n\tduk_uint32_t target_len;\n\tduk_uint_fast32_t i;\n\tduk_uint32_t arr_idx;\n\tduk_hstring *key;\n\tduk_tval *tv;\n\tduk_bool_t rc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"new array length smaller than old (%ld -> %ld), \"\n\t                     \"probably need to remove elements\",\n\t                     (long) old_len, (long) new_len));\n\n\t/*\n\t *  New length is smaller than old length, need to delete properties above\n\t *  the new length.\n\t *\n\t *  If array part exists, this is straightforward: array entries cannot\n\t *  be non-configurable so this is guaranteed to work.\n\t *\n\t *  If array part does not exist, array-indexed values are scattered\n\t *  in the entry part, and some may not be configurable (preventing length\n\t *  from becoming lower than their index + 1).  To handle the algorithm\n\t *  in E5 Section 15.4.5.1, step l correctly, we scan the entire property\n\t *  set twice.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(new_len < old_len);\n\tDUK_ASSERT(out_result_len != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj));\n\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY(obj));\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t/*\n\t\t *  All defined array-indexed properties are in the array part\n\t\t *  (we assume the array part is comprehensive), and all array\n\t\t *  entries are writable, configurable, and enumerable.  Thus,\n\t\t *  nothing can prevent array entries from being deleted.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"have array part, easy case\"));\n\n\t\tif (old_len < DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\t\t/* XXX: assertion that entries >= old_len are already unused */\n\t\t\ti = old_len;\n\t\t} else {\n\t\t\ti = DUK_HOBJECT_GET_ASIZE(obj);\n\t\t}\n\t\tDUK_ASSERT(i <= DUK_HOBJECT_GET_ASIZE(obj));\n\n\t\twhile (i > new_len) {\n\t\t\ti--;\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\t\tDUK_TVAL_SET_UNUSED_UPDREF(thr, tv);  /* side effects */\n\t\t}\n\n\t\t*out_result_len = new_len;\n\t\treturn 1;\n\t} else {\n\t\t/*\n\t\t *  Entries part is a bit more complex.\n\t\t */\n\n\t\t/* Stage 1: find highest preventing non-configurable entry (if any).\n\t\t * When forcing, ignore non-configurability.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"no array part, slow case\"));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part, stage 1: find target_len \"\n\t\t                     \"(highest preventing non-configurable entry (if any))\"));\n\n\t\ttarget_len = new_len;\n\t\tif (force_flag) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part; force flag -> skip stage 1\"));\n\t\t\tgoto skip_stage1;\n\t\t}\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);\n\t\t\tif (!key) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: null key\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!DUK_HSTRING_HAS_ARRIDX(key)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key not an array index\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(key));  /* XXX: macro checks for array index flag, which is unnecessary here */\n\t\t\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\t\t\tDUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX);\n\t\t\tDUK_ASSERT(arr_idx < old_len);  /* consistency requires this */\n\n\t\t\tif (arr_idx < new_len) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key is array index %ld, below new_len\",\n\t\t\t\t                     (long) i, (long) arr_idx));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(thr->heap, obj, i)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key is a relevant array index %ld, but configurable\",\n\t\t\t\t                     (long) i, (long) arr_idx));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* relevant array index is non-configurable, blocks write */\n\t\t\tif (arr_idx >= target_len) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"entry at index %ld has arr_idx %ld, is not configurable, \"\n\t\t\t\t                     \"update target_len %ld -> %ld\",\n\t\t\t\t                     (long) i, (long) arr_idx, (long) target_len,\n\t\t\t\t                     (long) (arr_idx + 1)));\n\t\t\t\ttarget_len = arr_idx + 1;\n\t\t\t}\n\t\t}\n\t skip_stage1:\n\n\t\t/* stage 2: delete configurable entries above target length */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"old_len=%ld, new_len=%ld, target_len=%ld\",\n\t\t                     (long) old_len, (long) new_len, (long) target_len));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part, stage 2: remove \"\n\t\t                     \"entries >= target_len\"));\n\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);\n\t\t\tif (!key) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: null key\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!DUK_HSTRING_HAS_ARRIDX(key)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key not an array index\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(key));  /* XXX: macro checks for array index flag, which is unnecessary here */\n\t\t\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\t\t\tDUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX);\n\t\t\tDUK_ASSERT(arr_idx < old_len);  /* consistency requires this */\n\n\t\t\tif (arr_idx < target_len) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key is array index %ld, below target_len\",\n\t\t\t\t                     (long) i, (long) arr_idx));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tDUK_ASSERT(force_flag || DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(thr->heap, obj, i));  /* stage 1 guarantees */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"delete entry index %ld: key is array index %ld\",\n\t\t\t                     (long) i, (long) arr_idx));\n\n\t\t\t/*\n\t\t\t *  Slow delete, but we don't care as we're already in a very slow path.\n\t\t\t *  The delete always succeeds: key has no exotic behavior, property\n\t\t\t *  is configurable, and no resize occurs.\n\t\t\t */\n\t\t\trc = duk_hobject_delprop_raw(thr, obj, key, force_flag ? DUK_DELPROP_FLAG_FORCE : 0);\n\t\t\tDUK_UNREF(rc);\n\t\t\tDUK_ASSERT(rc != 0);\n\t\t}\n\n\t\t/* stage 3: update length (done by caller), decide return code */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part, stage 3: update length (done by caller)\"));\n\n\t\t*out_result_len = target_len;\n\n\t\tif (target_len == new_len) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"target_len matches new_len, return success\"));\n\t\t\treturn 1;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"target_len does not match new_len (some entry prevented \"\n\t\t                     \"full length adjustment), return error\"));\n\t\treturn 0;\n\t}\n\n\tDUK_UNREACHABLE();\n}\n\n/* XXX: is valstack top best place for argument? */\nDUK_LOCAL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject *obj) {\n\tduk_harray *a;\n\tduk_uint32_t old_len;\n\tduk_uint32_t new_len;\n\tduk_uint32_t result_len;\n\tduk_bool_t rc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"handling a put operation to array 'length' exotic property, \"\n\t                     \"new val: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj));\n\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY(obj));\n\ta = (duk_harray *) obj;\n\tDUK_HARRAY_ASSERT_VALID(a);\n\n\tDUK_ASSERT(duk_is_valid_index(thr, -1));\n\n\t/*\n\t *  Get old and new length\n\t */\n\n\told_len = a->length;\n\tnew_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_NEGIDX(thr, -1));\n\tDUK_DDD(DUK_DDDPRINT(\"old_len=%ld, new_len=%ld\", (long) old_len, (long) new_len));\n\n\t/*\n\t *  Writability check\n\t */\n\n\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"length is not writable, fail\"));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  New length not lower than old length => no changes needed\n\t *  (not even array allocation).\n\t */\n\n\tif (new_len >= old_len) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"new length is same or higher than old length, just update length, no deletions\"));\n\t\ta->length = new_len;\n\t\treturn 1;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"new length is lower than old length, probably must delete entries\"));\n\n\t/*\n\t *  New length lower than old length => delete elements, then\n\t *  update length.\n\t *\n\t *  Note: even though a bunch of elements have been deleted, the 'desc' is\n\t *  still valid as properties haven't been resized (and entries compacted).\n\t */\n\n\trc = duk__handle_put_array_length_smaller(thr, obj, old_len, new_len, 0 /*force_flag*/, &result_len);\n\tDUK_ASSERT(result_len >= new_len && result_len <= old_len);\n\n\ta->length = result_len;\n\n\t/* XXX: shrink array allocation or entries compaction here? */\n\n\treturn rc;\n}\n\n/*\n *  PUTPROP: ECMAScript property write.\n *\n *  Unlike ECMAScript primitive which returns nothing, returns 1 to indicate\n *  success and 0 to indicate failure (assuming throw is not set).\n *\n *  This is an extremely tricky function.  Some examples:\n *\n *    * Currently a decref may trigger a GC, which may compact an object's\n *      property allocation.  Consequently, any entry indices (e_idx) will\n *      be potentially invalidated by a decref.\n *\n *    * Exotic behaviors (strings, arrays, arguments object) require,\n *      among other things:\n *\n *      - Preprocessing before and postprocessing after an actual property\n *        write.  For example, array index write requires pre-checking the\n *        array 'length' property for access control, and may require an\n *        array 'length' update after the actual write has succeeded (but\n *        not if it fails).\n *\n *      - Deletion of multiple entries, as a result of array 'length' write.\n *\n *    * Input values are taken as pointers which may point to the valstack.\n *      If valstack is resized because of the put (this may happen at least\n *      when the array part is abandoned), the pointers can be invalidated.\n *      (We currently make a copy of all of the input values to avoid issues.)\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_tval *tv_val, duk_bool_t throw_flag) {\n\tduk_tval tv_obj_copy;\n\tduk_tval tv_key_copy;\n\tduk_tval tv_val_copy;\n\tduk_hobject *orig = NULL;  /* NULL if tv_obj is primitive */\n\tduk_hobject *curr;\n\tduk_hstring *key = NULL;\n\tduk_propdesc desc;\n\tduk_tval *tv;\n\tduk_uint32_t arr_idx;\n\tduk_bool_t rc;\n\tduk_int_t e_idx;\n\tduk_uint_t sanity;\n\tduk_uint32_t new_array_length = 0;  /* 0 = no update */\n\n\tDUK_DDD(DUK_DDDPRINT(\"putprop: thr=%p, obj=%p, key=%p, val=%p, throw=%ld \"\n\t                     \"(obj -> %!T, key -> %!T, val -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key, (void *) tv_val,\n\t                     (long) throw_flag, (duk_tval *) tv_obj, (duk_tval *) tv_key, (duk_tval *) tv_val));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\tDUK_ASSERT(tv_val != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_putprop_all);\n\n\t/*\n\t *  Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of\n\t *  them being invalidated by a valstack resize.\n\t *\n\t *  XXX: this is an overkill for some paths, so optimize this later\n\t *  (or maybe switch to a stack arguments model entirely).\n\t */\n\n\tDUK_TVAL_SET_TVAL(&tv_obj_copy, tv_obj);\n\tDUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);\n\tDUK_TVAL_SET_TVAL(&tv_val_copy, tv_val);\n\ttv_obj = &tv_obj_copy;\n\ttv_key = &tv_key_copy;\n\ttv_val = &tv_val_copy;\n\n\t/*\n\t *  Coercion and fast path processing.\n\t */\n\n\tswitch (DUK_TVAL_GET_TAG(tv_obj)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL: {\n\t\t/* Note: unconditional throw */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is undefined or null -> reject (object=%!iT)\",\n\t\t                     (duk_tval *) tv_obj));\n#if defined(DUK_USE_PARANOID_ERRORS)\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\t\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot write property %s of %s\",\n\t\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\t\tDUK_WO_NORETURN(return 0;);\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a boolean, start lookup from boolean prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);\n\n\t\t/*\n\t\t *  Note: currently no fast path for array index writes.\n\t\t *  They won't be possible anyway as strings are immutable.\n\t\t */\n\n\t\tDUK_ASSERT(key == NULL);\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\t/* Symbols (ES2015 or hidden) don't have virtual properties. */\n\t\t\tcurr = thr->builtins[DUK_BIDX_SYMBOL_PROTOTYPE];\n\t\t\tgoto lookup;\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_writable;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {\n\t\t\tgoto fail_not_writable;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a string, start lookup from string prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_STRING_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_OBJECT: {\n\t\torig = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(orig != NULL);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\t\t/* With this check in place fast paths won't need read-only\n\t\t * object checks.  This is technically incorrect if there are\n\t\t * setters that cause no writes to ROM objects, but current\n\t\t * built-ins don't have such setters.\n\t\t */\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"attempt to putprop on read-only target object\"));\n\t\t\tgoto fail_not_writable_no_pop;  /* Must avoid duk_pop() in exit path */\n\t\t}\n#endif\n\n\t\t/* The fast path for array property put is not fully compliant:\n\t\t * If one places conflicting number-indexed properties into\n\t\t * Array.prototype (for example, a non-writable Array.prototype[7])\n\t\t * the fast path will incorrectly ignore them.\n\t\t *\n\t\t * This fast path could be made compliant by falling through\n\t\t * to the slow path if the previous value was UNUSED.  This would\n\t\t * also remove the need to check for extensibility.  Right now a\n\t\t * non-extensible array is slower than an extensible one as far\n\t\t * as writes are concerned.\n\t\t *\n\t\t * The fast path behavior is documented in more detail here:\n\t\t * tests/ecmascript/test-misc-array-fast-write.js\n\t\t */\n\n\t\t/* XXX: array .length? */\n\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\n\t\tif (duk__putprop_shallow_fastpath_array_tval(thr, orig, tv_key, tv_val) != 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array fast path success\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_arrayidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (duk__putprop_fastpath_bufobj_tval(thr, orig, tv_key, tv_val) != 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base is bufobj, key is a number, bufobj fast path\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_bufobjidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(orig))) {\n\t\t\tduk_hobject *h_target;\n\t\t\tduk_bool_t tmp_bool;\n\n\t\t\tif (duk__proxy_check_prop(thr, orig, DUK_STRIDX_SET, tv_key, &h_target)) {\n\t\t\t\t/* -> [ ... trap handler ] */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'set' for key %!T\", (duk_tval *) tv_key));\n\t\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_proxy);\n\t\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\t\tduk_push_tval(thr, tv_key);       /* P */\n\t\t\t\tduk_push_tval(thr, tv_val);       /* V */\n\t\t\t\tduk_push_tval(thr, tv_obj);       /* Receiver: Proxy object */\n\t\t\t\tduk_call_method(thr, 4 /*nargs*/);\n\t\t\t\ttmp_bool = duk_to_boolean_top_pop(thr);\n\t\t\t\tif (!tmp_bool) {\n\t\t\t\t\tgoto fail_proxy_rejected;\n\t\t\t\t}\n\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\t\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\t\t\t\tduk_tval *tv_targ = duk_require_tval(thr, -1);\n\t\t\t\t\tduk_bool_t datadesc_reject;\n\t\t\t\t\tduk_bool_t accdesc_reject;\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'set': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; tv_val=%!T, tv_targ=%!T, desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (duk_tval *) tv_val, (duk_tval *) tv_targ,\n\t\t\t\t\t                     (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\n\t\t\t\t\tdatadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) &&\n\t\t\t\t\t                  !duk_js_samevalue(tv_val, tv_targ);\n\t\t\t\t\taccdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                 !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                 (desc.set == NULL);\n\t\t\t\t\tif (datadesc_reject || accdesc_reject) {\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\n\t\t\t\t\tduk_pop_2_unsafe(thr);\n\t\t\t\t} else {\n\t\t\t\t\tduk_pop_unsafe(thr);\n\t\t\t\t}\n\t\t\t\treturn 1;  /* success */\n\t\t\t}\n\n\t\t\torig = h_target;  /* resume write to target */\n\t\t\tDUK_TVAL_SET_OBJECT(tv_obj, orig);\n\t\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t\tcurr = orig;\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_BUFFER: {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);\n\t\tduk_int_t pop_count = 0;\n\n\t\t/*\n\t\t *  Because buffer values may be looped over and read/written\n\t\t *  from, an array index fast path is important.\n\t\t */\n\n#if defined(DUK_USE_FASTINT)\n\t\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\t\tarr_idx = duk__tval_fastint_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path fastint; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else\n#endif\n\t\tif (DUK_TVAL_IS_NUMBER(tv_key)) {\n\t\t\tarr_idx = duk__tval_number_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path number; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t\tpop_count = 1;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HBUFFER_GET_SIZE(h)) {\n\t\t\tduk_uint8_t *data;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"writing to buffer data at index %ld\", (long) arr_idx));\n\t\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);\n\n\t\t\t/* XXX: duk_to_int() ensures we'll get 8 lowest bits as\n\t\t\t * as input is within duk_int_t range (capped outside it).\n\t\t\t */\n#if defined(DUK_USE_FASTINT)\n\t\t\t/* Buffer writes are often integers. */\n\t\t\tif (DUK_TVAL_IS_FASTINT(tv_val)) {\n\t\t\t\tdata[arr_idx] = (duk_uint8_t) DUK_TVAL_GET_FASTINT_U32(tv_val);\n\t\t\t}\n\t\t\telse\n#endif\n\t\t\t{\n\t\t\t\tduk_push_tval(thr, tv_val);\n\t\t\t\tdata[arr_idx] = (duk_uint8_t) duk_to_uint32(thr, -1);\n\t\t\t\tpop_count++;\n\t\t\t}\n\n\t\t\tduk_pop_n_unsafe(thr, pop_count);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"result: success (buffer data write)\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_bufferidx);\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (pop_count == 0) {\n\t\t\t/* This is a pretty awkward control flow, but we need to recheck the\n\t\t\t * key coercion here.\n\t\t\t */\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_writable;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a buffer, start lookup from Uint8Array prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_POINTER: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a pointer, start lookup from pointer prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Lightfuncs have no own properties and are considered non-extensible.\n\t\t * However, the write may be captured by an inherited setter which\n\t\t * means we can't stop the lookup here.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a lightfunc, start lookup from function prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE];\n\t\tbreak;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a number, start lookup from number prototype\"));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_obj));\n\t\tcurr = thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE];\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_ASSERT(key == NULL);\n\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\tDUK_ASSERT(key != NULL);\n\n lookup:\n\n\t/*\n\t *  Check whether the property already exists in the prototype chain.\n\t *  Note that the actual write goes into the original base object\n\t *  (except if an accessor property captures the write).\n\t */\n\n\t/* [key] */\n\n\tDUK_ASSERT(curr != NULL);\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (!duk__get_own_propdesc_raw(thr, curr, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\t\tgoto next_in_chain;\n\t\t}\n\n\t\tif (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t/*\n\t\t\t *  Found existing accessor property (own or inherited).\n\t\t\t *  Call setter with 'this' set to orig, and value as the only argument.\n\t\t\t *  Setter calls are OK even for ROM objects.\n\t\t\t *\n\t\t\t *  Note: no exotic arguments object behavior, because [[Put]] never\n\t\t\t *  calls [[DefineOwnProperty]] (E5 Section 8.12.5, step 5.b).\n\t\t\t */\n\n\t\t\tduk_hobject *setter;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"put to an own or inherited accessor, calling setter\"));\n\n\t\t\tsetter = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, curr, desc.e_idx);\n\t\t\tif (!setter) {\n\t\t\t\tgoto fail_no_setter;\n\t\t\t}\n\t\t\tduk_push_hobject(thr, setter);\n\t\t\tduk_push_tval(thr, tv_obj);  /* note: original, uncoerced base */\n\t\t\tduk_push_tval(thr, tv_val);  /* [key setter this val] */\n#if defined(DUK_USE_NONSTD_SETTER_KEY_ARGUMENT)\n\t\t\tduk_dup_m4(thr);\n\t\t\tduk_call_method(thr, 2);     /* [key setter this val key] -> [key retval] */\n#else\n\t\t\tduk_call_method(thr, 1);     /* [key setter this val] -> [key retval] */\n#endif\n\t\t\tduk_pop_unsafe(thr);         /* ignore retval -> [key] */\n\t\t\tgoto success_no_arguments_exotic;\n\t\t}\n\n\t\tif (orig == NULL) {\n\t\t\t/*\n\t\t\t *  Found existing own or inherited plain property, but original\n\t\t\t *  base is a primitive value.\n\t\t\t */\n\t\t\tDUK_DD(DUK_DDPRINT(\"attempt to create a new property in a primitive base object\"));\n\t\t\tgoto fail_base_primitive;\n\t\t}\n\n\t\tif (curr != orig) {\n\t\t\t/*\n\t\t\t *  Found existing inherited plain property.\n\t\t\t *  Do an access control check, and if OK, write\n\t\t\t *  new property to 'orig'.\n\t\t\t */\n\t\t\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(orig)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing inherited plain property, but original object is not extensible\"));\n\t\t\t\tgoto fail_not_extensible;\n\t\t\t}\n\t\t\tif (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing inherited plain property, original object is extensible, but inherited property is not writable\"));\n\t\t\t\tgoto fail_not_writable;\n\t\t\t}\n\t\t\tDUK_DD(DUK_DDPRINT(\"put to new property, object extensible, inherited property found and is writable\"));\n\t\t\tgoto create_new;\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Found existing own (non-inherited) plain property.\n\t\t\t *  Do an access control check and update in place.\n\t\t\t */\n\n\t\t\tif (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing own (non-inherited) plain property, but property is not writable\"));\n\t\t\t\tgoto fail_not_writable;\n\t\t\t}\n\t\t\tif (desc.flags & DUK_PROPDESC_FLAG_VIRTUAL) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing own (non-inherited) virtual property, property is writable\"));\n\n\t\t\t\tif (DUK_HOBJECT_IS_ARRAY(curr)) {\n\t\t\t\t\t/*\n\t\t\t\t\t *  Write to 'length' of an array is a very complex case\n\t\t\t\t\t *  handled in a helper which updates both the array elements\n\t\t\t\t\t *  and writes the new 'length'.  The write may result in an\n\t\t\t\t\t *  unconditional RangeError or a partial write (indicated\n\t\t\t\t\t *  by a return code).\n\t\t\t\t\t *\n\t\t\t\t\t *  Note: the helper has an unnecessary writability check\n\t\t\t\t\t *  for 'length', we already know it is writable.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_ASSERT(key == DUK_HTHREAD_STRING_LENGTH(thr));  /* only virtual array property */\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"writing existing 'length' property to array exotic, invoke complex helper\"));\n\n\t\t\t\t\t/* XXX: the helper currently assumes stack top contains new\n\t\t\t\t\t * 'length' value and the whole calling convention is not very\n\t\t\t\t\t * compatible with what we need.\n\t\t\t\t\t */\n\n\t\t\t\t\tduk_push_tval(thr, tv_val);  /* [key val] */\n\t\t\t\t\trc = duk__handle_put_array_length(thr, orig);\n\t\t\t\t\tduk_pop_unsafe(thr);  /* [key val] -> [key] */\n\t\t\t\t\tif (!rc) {\n\t\t\t\t\t\tgoto fail_array_length_partial;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* key is 'length', cannot match argument exotic behavior */\n\t\t\t\t\tgoto success_no_arguments_exotic;\n\t\t\t\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t\t\telse if (DUK_HOBJECT_IS_BUFOBJ(curr)) {\n\t\t\t\t\tduk_hbufobj *h_bufobj;\n\t\t\t\t\tduk_uint_t byte_off;\n\t\t\t\t\tduk_small_uint_t elem_size;\n\n\t\t\t\t\th_bufobj = (duk_hbufobj *) curr;\n\t\t\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"writable virtual property is in buffer object\"));\n\n\t\t\t\t\t/* Careful with wrapping: arr_idx upshift may easily wrap, whereas\n\t\t\t\t\t * length downshift won't.\n\t\t\t\t\t */\n\t\t\t\t\tif (arr_idx < (h_bufobj->length >> h_bufobj->shift) && DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\t\t\t\t\tduk_uint8_t *data;\n\t\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"writing to buffer data at index %ld\", (long) arr_idx));\n\n\t\t\t\t\t\tDUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX);  /* index/length check guarantees */\n\t\t\t\t\t\tbyte_off = arr_idx << h_bufobj->shift;       /* no wrap assuming h_bufobj->length is valid */\n\t\t\t\t\t\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\n\t\t\t\t\t\t/* Coerce to number before validating pointers etc so that the\n\t\t\t\t\t\t * number coercions in duk_hbufobj_validated_write() are\n\t\t\t\t\t\t * guaranteed to be side effect free and not invalidate the\n\t\t\t\t\t\t * pointer checks we do here.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk_push_tval(thr, tv_val);\n\t\t\t\t\t\t(void) duk_to_number_m1(thr);\n\n\t\t\t\t\t\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\t\t\t\t\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\t\t\t\t\t\tduk_hbufobj_validated_write(thr, h_bufobj, data, elem_size);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (write skipped)\"));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tduk_pop_unsafe(thr);\n\t\t\t\t\t\tgoto success_no_arguments_exotic;\n\t\t\t\t\t}\n\t\t\t\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\t\t\t\tDUK_D(DUK_DPRINT(\"should not happen, key %!O\", key));\n\t\t\t\tgoto fail_internal;  /* should not happen */\n\t\t\t}\n\t\t\tDUK_DD(DUK_DDPRINT(\"put to existing own plain property, property is writable\"));\n\t\t\tgoto update_old;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\n\t next_in_chain:\n\t\t/* XXX: option to pretend property doesn't exist if sanity limit is\n\t\t * hit might be useful.\n\t\t */\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t} while (curr != NULL);\n\n\t/*\n\t *  Property not found in prototype chain.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"property not found in prototype chain\"));\n\n\tif (orig == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to create a new property in a primitive base object\"));\n\t\tgoto fail_base_primitive;\n\t}\n\n\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(orig)) {\n\t\tDUK_DD(DUK_DDPRINT(\"put to a new property (not found in prototype chain), but original object not extensible\"));\n\t\tgoto fail_not_extensible;\n\t}\n\n\tgoto create_new;\n\n update_old:\n\n\t/*\n\t *  Update an existing property of the base object.\n\t */\n\n\t/* [key] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"update an existing property of the original object\"));\n\n\tDUK_ASSERT(orig != NULL);\n#if defined(DUK_USE_ROM_OBJECTS)\n\t/* This should not happen because DUK_TAG_OBJECT case checks\n\t * for this already, but check just in case.\n\t */\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {\n\t\tgoto fail_not_writable;\n\t}\n#endif\n\n\t/* Although there are writable virtual properties (e.g. plain buffer\n\t * and buffer object number indices), they are handled before we come\n\t * here.\n\t */\n\tDUK_ASSERT((desc.flags & DUK_PROPDESC_FLAG_VIRTUAL) == 0);\n\tDUK_ASSERT(desc.a_idx >= 0 || desc.e_idx >= 0);\n\n\t/* Array own property .length is handled above. */\n\tDUK_ASSERT(!(DUK_HOBJECT_IS_ARRAY(orig) && key == DUK_HTHREAD_STRING_LENGTH(thr)));\n\n\tif (desc.e_idx >= 0) {\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, desc.e_idx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"previous entry value: %!iT\", (duk_tval *) tv));\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val);  /* side effects; e_idx may be invalidated */\n\t\t/* don't touch property attributes or hash part */\n\t\tDUK_DD(DUK_DDPRINT(\"put to an existing entry at index %ld -> new value %!iT\",\n\t\t                   (long) desc.e_idx, (duk_tval *) tv));\n\t} else {\n\t\t/* Note: array entries are always writable, so the writability check\n\t\t * above is pointless for them.  The check could be avoided with some\n\t\t * refactoring but is probably not worth it.\n\t\t */\n\n\t\tDUK_ASSERT(desc.a_idx >= 0);\n\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, orig, desc.a_idx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"previous array value: %!iT\", (duk_tval *) tv));\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val);  /* side effects; a_idx may be invalidated */\n\t\tDUK_DD(DUK_DDPRINT(\"put to an existing array entry at index %ld -> new value %!iT\",\n\t\t                   (long) desc.a_idx, (duk_tval *) tv));\n\t}\n\n\t/* Regardless of whether property is found in entry or array part,\n\t * it may have arguments exotic behavior (array indices may reside\n\t * in entry part for abandoned / non-existent array parts).\n\t */\n\tgoto success_with_arguments_exotic;\n\n create_new:\n\n\t/*\n\t *  Create a new property in the original object.\n\t *\n\t *  Exotic properties need to be reconsidered here from a write\n\t *  perspective (not just property attributes perspective).\n\t *  However, the property does not exist in the object already,\n\t *  so this limits the kind of exotic properties that apply.\n\t */\n\n\t/* [key] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"create new property to original object\"));\n\n\tDUK_ASSERT(orig != NULL);\n\n\t/* Array own property .length is handled above. */\n\tDUK_ASSERT(!(DUK_HOBJECT_IS_ARRAY(orig) && key == DUK_HTHREAD_STRING_LENGTH(thr)));\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\t/* This should not happen because DUK_TAG_OBJECT case checks\n\t * for this already, but check just in case.\n\t */\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {\n\t\tgoto fail_not_writable;\n\t}\n#endif\n\n\t/* Not possible because array object 'length' is present\n\t * from its creation and cannot be deleted, and is thus\n\t * caught as an existing property above.\n\t */\n\tDUK_ASSERT(!(DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig) &&\n\t             key == DUK_HTHREAD_STRING_LENGTH(thr)));\n\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig) &&\n\t    arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t/* automatic length update */\n\t\tduk_uint32_t old_len;\n\t\tduk_harray *a;\n\n\t\ta = (duk_harray *) orig;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\told_len = a->length;\n\n\t\tif (arr_idx >= old_len) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"write new array entry requires length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\n\t\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"attempt to extend array, but array 'length' is not writable\"));\n\t\t\t\tgoto fail_not_writable;\n\t\t\t}\n\n\t\t\t/* Note: actual update happens once write has been completed\n\t\t\t * without error below.  The write should always succeed\n\t\t\t * from a specification viewpoint, but we may e.g. run out\n\t\t\t * of memory.  It's safer in this order.\n\t\t\t */\n\n\t\t\tDUK_ASSERT(arr_idx != 0xffffffffUL);\n\t\t\tnew_array_length = arr_idx + 1;  /* flag for later write */\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"write new array entry does not require length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\t\t}\n\t}\n\n /* write_to_array_part: */\n\n\t/*\n\t *  Write to array part?\n\t *\n\t *  Note: array abandonding requires a property resize which uses\n\t *  'rechecks' valstack for temporaries and may cause any existing\n\t *  valstack pointers to be invalidated.  To protect against this,\n\t *  tv_obj, tv_key, and tv_val are copies of the original inputs.\n\t */\n\n\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(orig)) {\n\t\ttv = duk__obtain_arridx_slot(thr, arr_idx, orig);\n\t\tif (tv == NULL) {\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(orig));\n\t\t\tgoto write_to_entry_part;\n\t\t}\n\n\t\t/* prev value must be unused, no decref */\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_TVAL_SET_TVAL(tv, tv_val);\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\tDUK_DD(DUK_DDPRINT(\"put to new array entry: %ld -> %!T\",\n\t\t                   (long) arr_idx, (duk_tval *) tv));\n\n\t\t/* Note: array part values are [[Writable]], [[Enumerable]],\n\t\t * and [[Configurable]] which matches the required attributes\n\t\t * here.\n\t\t */\n\t\tgoto entry_updated;\n\t}\n\n write_to_entry_part:\n\n\t/*\n\t *  Write to entry part\n\t */\n\n\t/* entry allocation updates hash part and increases the key\n\t * refcount; may need a props allocation resize but doesn't\n\t * 'recheck' the valstack.\n\t */\n\te_idx = duk__hobject_alloc_entry_checked(thr, orig, key);\n\tDUK_ASSERT(e_idx >= 0);\n\n\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, e_idx);\n\t/* prev value can be garbage, no decref */\n\tDUK_TVAL_SET_TVAL(tv, tv_val);\n\tDUK_TVAL_INCREF(thr, tv);\n\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, orig, e_idx, DUK_PROPDESC_FLAGS_WEC);\n\tgoto entry_updated;\n\n entry_updated:\n\n\t/*\n\t *  Possible pending array length update, which must only be done\n\t *  if the actual entry write succeeded.\n\t */\n\n\tif (new_array_length > 0) {\n\t\t/* Note: zero works as a \"no update\" marker because the new length\n\t\t * can never be zero after a new property is written.\n\t\t */\n\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"write successful, pending array length update to: %ld\",\n\t\t                     (long) new_array_length));\n\n\t\t((duk_harray *) orig)->length = new_array_length;\n\t}\n\n\t/*\n\t *  Arguments exotic behavior not possible for new properties: all\n\t *  magically bound properties are initially present in the arguments\n\t *  object, and if they are deleted, the binding is also removed from\n\t *  parameter map.\n\t */\n\n\tgoto success_no_arguments_exotic;\n\n success_with_arguments_exotic:\n\n\t/*\n\t *  Arguments objects have exotic [[DefineOwnProperty]] which updates\n\t *  the internal 'map' of arguments for writes to currently mapped\n\t *  arguments.  More conretely, writes to mapped arguments generate\n\t *  a write to a bound variable.\n\t *\n\t *  The [[Put]] algorithm invokes [[DefineOwnProperty]] for existing\n\t *  data properties and new properties, but not for existing accessors.\n\t *  Hence, in E5 Section 10.6 ([[DefinedOwnProperty]] algorithm), we\n\t *  have a Desc with 'Value' (and possibly other properties too), and\n\t *  we end up in step 5.b.i.\n\t */\n\n\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t    DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(orig)) {\n\t\t/* Note: only numbered indices are relevant, so arr_idx fast reject\n\t\t * is good (this is valid unless there are more than 4**32-1 arguments).\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"putprop successful, arguments exotic behavior needed\"));\n\n\t\t/* Note: we can reuse 'desc' here */\n\n\t\t/* XXX: top of stack must contain value, which helper doesn't touch,\n\t\t * rework to use tv_val directly?\n\t\t */\n\n\t\tduk_push_tval(thr, tv_val);\n\t\t(void) duk__check_arguments_map_for_put(thr, orig, key, &desc, throw_flag);\n\t\tduk_pop_unsafe(thr);\n\t}\n\t/* fall thru */\n\n success_no_arguments_exotic:\n\t/* shared exit path now */\n\tDUK_DDD(DUK_DDDPRINT(\"result: success\"));\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 1;\n\n#if defined(DUK_USE_ES6_PROXY)\n fail_proxy_rejected:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, proxy rejects\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\t/* Note: no key on stack */\n\treturn 0;\n#endif\n\n fail_base_primitive:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, base primitive\"));\n\tif (throw_flag) {\n#if defined(DUK_USE_PARANOID_ERRORS)\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\t\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot write property %s of %s\",\n\t\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_not_extensible:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, not extensible\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_not_writable:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, not writable\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n#if defined(DUK_USE_ROM_OBJECTS)\n fail_not_writable_no_pop:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, not writable\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n#endif\n\n fail_array_length_partial:\n\tDUK_DD(DUK_DDPRINT(\"result: error, array length write only partially successful\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_no_setter:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, accessor property without setter\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_SETTER_UNDEFINED);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_internal:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, internal\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_INTERNAL(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n}\n\n/*\n *  ECMAScript compliant [[Delete]](P, Throw).\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags) {\n\tduk_propdesc desc;\n\tduk_tval *tv;\n\tduk_uint32_t arr_idx;\n\tduk_bool_t throw_flag;\n\tduk_bool_t force_flag;\n\n\tthrow_flag = (flags & DUK_DELPROP_FLAG_THROW);\n\tforce_flag = (flags & DUK_DELPROP_FLAG_FORCE);\n\n\tDUK_DDD(DUK_DDDPRINT(\"delprop_raw: thr=%p, obj=%p, key=%p, throw=%ld, force=%ld (obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (long) throw_flag, (long) force_flag,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);\n\n\t/* 0 = don't push current value */\n\tif (!duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\tDUK_DDD(DUK_DDDPRINT(\"property not found, succeed always\"));\n\t\tgoto success;\n\t}\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to delprop on read-only target object\"));\n\t\tgoto fail_not_configurable;\n\t}\n#endif\n\n\tif ((desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) == 0 && !force_flag) {\n\t\tgoto fail_not_configurable;\n\t}\n\tif (desc.a_idx < 0 && desc.e_idx < 0) {\n\t\t/* Currently there are no deletable virtual properties, but\n\t\t * with force_flag we might attempt to delete one.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"delete failed: property found, force flag, but virtual (and implicitly non-configurable)\"));\n\t\tgoto fail_virtual;\n\t}\n\n\tif (desc.a_idx >= 0) {\n\t\tDUK_ASSERT(desc.e_idx < 0);\n\n\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx);\n\t\tDUK_TVAL_SET_UNUSED_UPDREF(thr, tv);  /* side effects */\n\t\tgoto success;\n\t} else {\n\t\tDUK_ASSERT(desc.a_idx < 0);\n\n\t\t/* remove hash entry (no decref) */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\t\tif (desc.h_idx >= 0) {\n\t\t\tduk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(thr->heap, obj);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"removing hash entry at h_idx %ld\", (long) desc.h_idx));\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) > 0);\n\t\t\tDUK_ASSERT((duk_uint32_t) desc.h_idx < DUK_HOBJECT_GET_HSIZE(obj));\n\t\t\th_base[desc.h_idx] = DUK__HASH_DELETED;\n\t\t} else {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) == 0);\n\t\t}\n#else\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) == 0);\n#endif\n\n\t\t/* Remove value.  This requires multiple writes so avoid side\n\t\t * effects via no-refzero macros so that e_idx is not\n\t\t * invalidated.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"before removing value, e_idx %ld, key %p, key at slot %p\",\n\t\t                     (long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)));\n\t\tDUK_DDD(DUK_DDDPRINT(\"removing value at e_idx %ld\", (long) desc.e_idx));\n\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx)) {\n\t\t\tduk_hobject *tmp;\n\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, desc.e_idx);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, desc.e_idx, NULL);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, desc.e_idx);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, desc.e_idx, NULL);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\t\t} else {\n\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t\t}\n#if 0\n\t\t/* Not strictly necessary because if key == NULL, flag MUST be ignored. */\n\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, 0);\n#endif\n\n\t\t/* Remove key. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"before removing key, e_idx %ld, key %p, key at slot %p\",\n\t\t                     (long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)));\n\t\tDUK_DDD(DUK_DDDPRINT(\"removing key at e_idx %ld\", (long) desc.e_idx));\n\t\tDUK_ASSERT(key == DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx));\n\t\tDUK_HOBJECT_E_SET_KEY(thr->heap, obj, desc.e_idx, NULL);\n\t\tDUK_HSTRING_DECREF_NORZ(thr, key);\n\n\t\t/* Trigger refzero side effects only when we're done as a\n\t\t * finalizer might operate on the object and affect the\n\t\t * e_idx we're supposed to use.\n\t\t */\n\t\tDUK_REFZERO_CHECK_SLOW(thr);\n\t\tgoto success;\n\t}\n\n\tDUK_UNREACHABLE();\n\n success:\n\t/*\n\t *  Argument exotic [[Delete]] behavior (E5 Section 10.6) is\n\t *  a post-check, keeping arguments internal 'map' in sync with\n\t *  any successful deletes (note that property does not need to\n\t *  exist for delete to 'succeed').\n\t *\n\t *  Delete key from 'map'.  Since 'map' only contains array index\n\t *  keys, we can use arr_idx for a fast skip.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"delete successful, check for arguments exotic behavior\"));\n\n\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)) {\n\t\t/* Note: only numbered indices are relevant, so arr_idx fast reject\n\t\t * is good (this is valid unless there are more than 4**32-1 arguments).\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"delete successful, arguments exotic behavior needed\"));\n\n\t\t/* Note: we can reuse 'desc' here */\n\t\t(void) duk__check_arguments_map_for_delete(thr, obj, key, &desc);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"delete successful\"));\n\treturn 1;\n\n fail_virtual:  /* just use the same \"not configurable\" error message */\n fail_not_configurable:\n\tDUK_DDD(DUK_DDDPRINT(\"delete failed: property found, not configurable\"));\n\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n}\n\n/*\n *  DELPROP: ECMAScript property deletion.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_bool_t throw_flag) {\n\tduk_hstring *key = NULL;\n#if defined(DUK_USE_ES6_PROXY)\n\tduk_propdesc desc;\n#endif\n\tduk_int_t entry_top;\n\tduk_uint32_t arr_idx = DUK__NO_ARRAY_INDEX;\n\tduk_bool_t rc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"delprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key,\n\t                     (duk_tval *) tv_obj, (duk_tval *) tv_key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\t/* Storing the entry top is cheaper here to ensure stack is correct at exit,\n\t * as there are several paths out.\n\t */\n\tentry_top = duk_get_top(thr);\n\n\tif (DUK_TVAL_IS_UNDEFINED(tv_obj) ||\n\t    DUK_TVAL_IS_NULL(tv_obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is undefined or null -> reject\"));\n\t\tgoto fail_invalid_base_uncond;\n\t}\n\n\tduk_push_tval(thr, tv_obj);\n\tduk_push_tval(thr, tv_key);\n\n\ttv_obj = DUK_GET_TVAL_NEGIDX(thr, -2);\n\tif (DUK_TVAL_IS_OBJECT(tv_obj)) {\n\t\tduk_hobject *obj = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(obj != NULL);\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(obj))) {\n\t\t\tduk_hobject *h_target;\n\t\t\tduk_bool_t tmp_bool;\n\n\t\t\t/* Note: proxy handling must happen before key is string coerced. */\n\n\t\t\tif (duk__proxy_check_prop(thr, obj, DUK_STRIDX_DELETE_PROPERTY, tv_key, &h_target)) {\n\t\t\t\t/* -> [ ... obj key trap handler ] */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'deleteProperty' for key %!T\", (duk_tval *) tv_key));\n\t\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\t\tduk_dup_m4(thr);  /* P */\n\t\t\t\tduk_call_method(thr, 2 /*nargs*/);\n\t\t\t\ttmp_bool = duk_to_boolean_top_pop(thr);\n\t\t\t\tif (!tmp_bool) {\n\t\t\t\t\tgoto fail_proxy_rejected;  /* retval indicates delete failed */\n\t\t\t\t}\n\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\t\t\t\ttv_key = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\t\t\t\tduk_small_int_t desc_reject;\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'deleteProperty': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\n\t\t\t\t\tdesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE);\n\t\t\t\t\tif (desc_reject) {\n\t\t\t\t\t\t/* unconditional */\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\trc = 1;  /* success */\n\t\t\t\tgoto done_rc;\n\t\t\t}\n\n\t\t\tobj = h_target;  /* resume delete to target */\n\t\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\trc = duk_hobject_delprop_raw(thr, obj, key, throw_flag ? DUK_DELPROP_FLAG_THROW : 0);\n\t\tgoto done_rc;\n\t} else if (DUK_TVAL_IS_STRING(tv_obj)) {\n\t\t/* String has .length and array index virtual properties\n\t\t * which can't be deleted.  No need for a symbol check;\n\t\t * no offending virtual symbols exist.\n\t\t */\n\t\t/* XXX: unnecessary string coercion for array indices,\n\t\t * intentional to keep small.\n\t\t */\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\t} else if (DUK_TVAL_IS_BUFFER(tv_obj)) {\n\t\t/* XXX: unnecessary string coercion for array indices,\n\t\t * intentional to keep small; some overlap with string\n\t\t * handling.\n\t\t */\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HBUFFER_GET_SIZE(h)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) {\n\t\t/* Lightfunc has no virtual properties since Duktape 2.2\n\t\t * so success.  Still must coerce key for side effects.\n\t\t */\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\t\tDUK_UNREF(key);\n\t}\n\n\t/* non-object base, no offending virtual property */\n\trc = 1;\n\tgoto done_rc;\n\n done_rc:\n\tduk_set_top_unsafe(thr, entry_top);\n\treturn rc;\n\n fail_invalid_base_uncond:\n\t/* Note: unconditional throw */\n\tDUK_ASSERT(duk_get_top(thr) == entry_top);\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot delete property %s of %s\",\n\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\tDUK_WO_NORETURN(return 0;);\n\n#if defined(DUK_USE_ES6_PROXY)\n fail_proxy_rejected:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_set_top_unsafe(thr, entry_top);\n\treturn 0;\n#endif\n\n fail_not_configurable:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_set_top_unsafe(thr, entry_top);\n\treturn 0;\n}\n\n/*\n *  Internal helper to define a property with specific flags, ignoring\n *  normal semantics such as extensibility, write protection etc.\n *  Overwrites any existing value and attributes unless caller requests\n *  that value only be updated if it doesn't already exists.\n *\n *  Does not support:\n *    - virtual properties (error if write attempted)\n *    - getter/setter properties (error if write attempted)\n *    - non-default (!= WEC) attributes for array entries (error if attempted)\n *    - array abandoning: if array part exists, it is always extended\n *    - array 'length' updating\n *\n *  Stack: [... in_val] -> []\n *\n *  Used for e.g. built-in initialization and environment record\n *  operations.\n */\n\nDUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags) {\n\tduk_propdesc desc;\n\tduk_uint32_t arr_idx;\n\tduk_int_t e_idx;\n\tduk_tval *tv1 = NULL;\n\tduk_tval *tv2 = NULL;\n\tduk_small_uint_t propflags = flags & DUK_PROPDESC_FLAGS_MASK;  /* mask out flags not actually stored */\n\n\tDUK_DDD(DUK_DDDPRINT(\"define new property (internal): thr=%p, obj=%!O, key=%!O, flags=0x%02lx, val=%!T\",\n\t                     (void *) thr, (duk_heaphdr *) obj, (duk_heaphdr *) key,\n\t                     (unsigned long) flags, (duk_tval *) duk_get_tval(thr, -1)));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\tDUK_ASSERT(duk_is_valid_index(thr, -1));  /* contains value */\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\n\tif (duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\tif (desc.e_idx >= 0) {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the entry part -> skip as requested\"));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the entry part -> update value and attributes\"));\n\t\t\tif (DUK_UNLIKELY(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx))) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"existing property is an accessor, not supported\"));\n\t\t\t\tgoto error_internal;\n\t\t\t}\n\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, propflags);\n\t\t\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);\n\t\t} else if (desc.a_idx >= 0) {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the array part -> skip as requested\"));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the array part -> update value (assert attributes)\"));\n\t\t\tif (propflags != DUK_PROPDESC_FLAGS_WEC) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"existing property in array part, but propflags not WEC (0x%02lx)\",\n\t\t\t\t                 (unsigned long) propflags));\n\t\t\t\tgoto error_internal;\n\t\t\t}\n\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx);\n\t\t} else {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists but is virtual -> skip as requested\"));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\t\t\tduk_uint32_t new_len;\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tduk_uint32_t prev_len;\n\t\t\t\tprev_len = ((duk_harray *) obj)->length;\n#endif\n\t\t\t\tnew_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_NEGIDX(thr, -1));\n\t\t\t\t((duk_harray *) obj)->length = new_len;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"internal define property for array .length: %ld -> %ld\",\n\t\t\t\t                   (long) prev_len, (long) ((duk_harray *) obj)->length));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tDUK_DD(DUK_DDPRINT(\"property already exists but is virtual -> failure\"));\n\t\t\tgoto error_virtual;\n\t\t}\n\n\t\tgoto write_value;\n\t}\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property does not exist, object has array part -> possibly extend array part and write value (assert attributes)\"));\n\t\t\tDUK_ASSERT(propflags == DUK_PROPDESC_FLAGS_WEC);\n\n\t\t\ttv1 = duk__obtain_arridx_slot(thr, arr_idx, obj);\n\t\t\tif (tv1 == NULL) {\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\t\t\tgoto write_to_entry_part;\n\t\t\t}\n\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n\t\t\tgoto write_value;\n\t\t}\n\t}\n\n write_to_entry_part:\n\tDUK_DDD(DUK_DDDPRINT(\"property does not exist, object belongs in entry part -> allocate new entry and write value and attributes\"));\n\te_idx = duk__hobject_alloc_entry_checked(thr, obj, key);  /* increases key refcount */\n\tDUK_ASSERT(e_idx >= 0);\n\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, propflags);\n\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);\n\t/* new entry: previous value is garbage; set to undefined to share write_value */\n\tDUK_TVAL_SET_UNDEFINED(tv1);\n\tgoto write_value;\n\n write_value:\n\t/* tv1 points to value storage */\n\n\ttv2 = duk_require_tval(thr, -1);  /* late lookup, avoid side effects */\n\tDUK_DDD(DUK_DDDPRINT(\"writing/updating value: %!T -> %!T\",\n\t                     (duk_tval *) tv1, (duk_tval *) tv2));\n\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\tgoto pop_exit;\n\n pop_exit:\n\tduk_pop_unsafe(thr);  /* remove in_val */\n\treturn;\n\n error_virtual:  /* share error message */\n error_internal:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Fast path for defining array indexed values without interning the key.\n *  This is used by e.g. code for Array prototype and traceback creation so\n *  must avoid interning.\n */\n\nDUK_INTERNAL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags) {\n\tduk_hstring *key;\n\tduk_tval *tv1, *tv2;\n\n\tDUK_DDD(DUK_DDDPRINT(\"define new property (internal) arr_idx fast path: thr=%p, obj=%!O, \"\n\t                     \"arr_idx=%ld, flags=0x%02lx, val=%!T\",\n\t                     (void *) thr, obj, (long) arr_idx, (unsigned long) flags,\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj) &&\n\t    arr_idx != DUK__NO_ARRAY_INDEX &&\n\t    flags == DUK_PROPDESC_FLAGS_WEC) {\n\t\tDUK_ASSERT((flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) == 0);  /* covered by comparison */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"define property to array part (property may or may not exist yet)\"));\n\n\t\ttv1 = duk__obtain_arridx_slot(thr, arr_idx, obj);\n\t\tif (tv1 == NULL) {\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\t\tgoto write_slow;\n\t\t}\n\t\ttv2 = duk_require_tval(thr, -1);\n\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\n\t\tduk_pop_unsafe(thr);  /* [ ...val ] -> [ ... ] */\n\t\treturn;\n\t}\n\n write_slow:\n\tDUK_DDD(DUK_DDDPRINT(\"define property fast path didn't work, use slow path\"));\n\n\tkey = duk_push_uint_to_hstring(thr, (duk_uint_t) arr_idx);\n\tDUK_ASSERT(key != NULL);\n\tduk_insert(thr, -2);  /* [ ... val key ] -> [ ... key val ] */\n\n\tduk_hobject_define_property_internal(thr, obj, key, flags);\n\n\tduk_pop_unsafe(thr);  /* [ ... key ] -> [ ... ] */\n}\n\n/*\n *  Internal helpers for managing object 'length'\n */\n\nDUK_INTERNAL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj) {\n\tduk_double_t val;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(obj != NULL);\n\n\t/* Fast path for Arrays. */\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\treturn ((duk_harray *) obj)->length;\n\t}\n\n\t/* Slow path, .length can be e.g. accessor, obj can be a Proxy, etc. */\n\tduk_push_hobject(thr, obj);\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_LENGTH);\n\t(void) duk_hobject_getprop(thr,\n\t                           DUK_GET_TVAL_NEGIDX(thr, -2),\n\t                           DUK_GET_TVAL_NEGIDX(thr, -1));\n\tval = duk_to_number_m1(thr);\n\tduk_pop_3_unsafe(thr);\n\n\t/* This isn't part of ECMAScript semantics; return a value within\n\t * duk_size_t range, or 0 otherwise.\n\t */\n\tif (val >= 0.0 && val <= (duk_double_t) DUK_SIZE_MAX) {\n\t\treturn (duk_size_t) val;\n\t}\n\treturn 0;\n}\n\n/*\n *  Fast finalizer check for an object.  Walks the prototype chain, checking\n *  for finalizer presence using DUK_HOBJECT_FLAG_HAVE_FINALIZER which is kept\n *  in sync with the actual property when setting/removing the finalizer.\n */\n\n#if defined(DUK_USE_HEAPPTR16)\nDUK_INTERNAL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_heap *heap, duk_hobject *obj) {\n#else\nDUK_INTERNAL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_hobject *obj) {\n#endif\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(obj != NULL);\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_HAS_HAVE_FINALIZER(obj))) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_D(DUK_DPRINT(\"prototype loop when checking for finalizer existence; returning false\"));\n\t\t\treturn 0;\n\t\t}\n#if defined(DUK_USE_HEAPPTR16)\n\t\tDUK_ASSERT(heap != NULL);\n\t\tobj = DUK_HOBJECT_GET_PROTOTYPE(heap, obj);\n#else\n\t\tobj = DUK_HOBJECT_GET_PROTOTYPE(NULL, obj);  /* 'heap' arg ignored */\n#endif\n\t} while (obj != NULL);\n\n\treturn 0;\n}\n\n/*\n *  Object.getOwnPropertyDescriptor()  (E5 Sections 15.2.3.3, 8.10.4)\n *\n *  [ ... key ] -> [ ... desc/undefined ]\n */\n\nDUK_INTERNAL void duk_hobject_object_get_own_property_descriptor(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_propdesc pd;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tobj = duk_require_hobject_promote_mask(thr, obj_idx, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tkey = duk_to_property_key_hstring(thr, -1);\n\tDUK_ASSERT(key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk_hobject_get_own_propdesc(thr, obj, key, &pd, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tduk_push_undefined(thr);\n\t\tduk_remove_m2(thr);\n\t\treturn;\n\t}\n\n\tduk_push_object(thr);\n\n\t/* [ ... key value desc ] */\n\n\tif (DUK_PROPDESC_IS_ACCESSOR(&pd)) {\n\t\t/* If a setter/getter is missing (undefined), the descriptor must\n\t\t * still have the property present with the value 'undefined'.\n\t\t */\n\t\tif (pd.get) {\n\t\t\tduk_push_hobject(thr, pd.get);\n\t\t} else {\n\t\t\tduk_push_undefined(thr);\n\t\t}\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_GET);\n\t\tif (pd.set) {\n\t\t\tduk_push_hobject(thr, pd.set);\n\t\t} else {\n\t\t\tduk_push_undefined(thr);\n\t\t}\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_SET);\n\t} else {\n\t\tduk_dup_m2(thr);\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_VALUE);\n\t\tduk_push_boolean(thr, DUK_PROPDESC_IS_WRITABLE(&pd));\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_WRITABLE);\n\t}\n\tduk_push_boolean(thr, DUK_PROPDESC_IS_ENUMERABLE(&pd));\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_ENUMERABLE);\n\tduk_push_boolean(thr, DUK_PROPDESC_IS_CONFIGURABLE(&pd));\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_CONFIGURABLE);\n\n\t/* [ ... key value desc ] */\n\n\tduk_replace(thr, -3);\n\tduk_pop_unsafe(thr);  /* -> [ ... desc ] */\n}\n\n/*\n *  NormalizePropertyDescriptor() related helper.\n *\n *  Internal helper which validates and normalizes a property descriptor\n *  represented as an ECMAScript object (e.g. argument to defineProperty()).\n *  The output of this conversion is a set of defprop_flags and possibly\n *  some values pushed on the value stack to (1) ensure borrowed pointers\n *  remain valid, and (2) avoid unnecessary pops for footprint reasons.\n *  Caller must manage stack top carefully because the number of values\n *  pushed depends on the input property descriptor.\n *\n *  The original descriptor object must not be altered in the process.\n */\n\n/* XXX: very basic optimization -> duk_get_prop_stridx_top */\n\nDUK_INTERNAL\nvoid duk_hobject_prepare_property_descriptor(duk_hthread *thr,\n                                             duk_idx_t idx_in,\n                                             duk_uint_t *out_defprop_flags,\n                                             duk_idx_t *out_idx_value,\n                                             duk_hobject **out_getter,\n                                             duk_hobject **out_setter) {\n\tduk_idx_t idx_value = -1;\n\tduk_hobject *getter = NULL;\n\tduk_hobject *setter = NULL;\n\tduk_bool_t is_data_desc = 0;\n\tduk_bool_t is_acc_desc = 0;\n\tduk_uint_t defprop_flags = 0;\n\n\tDUK_ASSERT(out_defprop_flags != NULL);\n\tDUK_ASSERT(out_idx_value != NULL);\n\tDUK_ASSERT(out_getter != NULL);\n\tDUK_ASSERT(out_setter != NULL);\n\tDUK_ASSERT(idx_in <= 0x7fffL);  /* short variants would be OK, but not used to avoid shifts */\n\n\t/* Must be an object, otherwise TypeError (E5.1 Section 8.10.5, step 1). */\n\tidx_in = duk_require_normalize_index(thr, idx_in);\n\t(void) duk_require_hobject(thr, idx_in);\n\n\t/* The coercion order must match the ToPropertyDescriptor() algorithm\n\t * so that side effects in coercion happen in the correct order.\n\t * (This order also happens to be compatible with duk_def_prop(),\n\t * although it doesn't matter in practice.)\n\t */\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_VALUE)) {\n\t\tis_data_desc = 1;\n\t\tdefprop_flags |= DUK_DEFPROP_HAVE_VALUE;\n\t\tidx_value = duk_get_top_index(thr);\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_WRITABLE)) {\n\t\tis_data_desc = 1;\n\t\tif (duk_to_boolean_top_pop(thr)) {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE;\n\t\t} else {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_WRITABLE;\n\t\t}\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_GET)) {\n\t\tduk_tval *tv = duk_require_tval(thr, -1);\n\t\tduk_hobject *h_get;\n\n\t\tif (DUK_TVAL_IS_UNDEFINED(tv)) {\n\t\t\t/* undefined is accepted */\n\t\t\tDUK_ASSERT(getter == NULL);\n\t\t} else {\n\t\t\t/* NOTE: lightfuncs are coerced to full functions because\n\t\t\t * lightfuncs don't fit into a property value slot.  This\n\t\t\t * has some side effects, see test-dev-lightfunc-accessor.js.\n\t\t\t */\n\t\t\th_get = duk_get_hobject_promote_lfunc(thr, -1);\n\t\t\tif (h_get == NULL || !DUK_HOBJECT_IS_CALLABLE(h_get)) {\n\t\t\t\tgoto type_error;\n\t\t\t}\n\t\t\tgetter = h_get;\n\t\t}\n\t\tis_acc_desc = 1;\n\t\tdefprop_flags |= DUK_DEFPROP_HAVE_GETTER;\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_SET)) {\n\t\tduk_tval *tv = duk_require_tval(thr, -1);\n\t\tduk_hobject *h_set;\n\n\t\tif (DUK_TVAL_IS_UNDEFINED(tv)) {\n\t\t\t/* undefined is accepted */\n\t\t\tDUK_ASSERT(setter == NULL);\n\t\t}  else {\n\t\t\t/* NOTE: lightfuncs are coerced to full functions because\n\t\t\t * lightfuncs don't fit into a property value slot.  This\n\t\t\t * has some side effects, see test-dev-lightfunc-accessor.js.\n\t\t\t */\n\t\t\th_set = duk_get_hobject_promote_lfunc(thr, -1);\n\t\t\tif (h_set == NULL || !DUK_HOBJECT_IS_CALLABLE(h_set)) {\n\t\t\t\tgoto type_error;\n\t\t\t}\n\t\t\tsetter = h_set;\n\t\t}\n\t\tis_acc_desc = 1;\n\t\tdefprop_flags |= DUK_DEFPROP_HAVE_SETTER;\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_ENUMERABLE)) {\n\t\tif (duk_to_boolean_top_pop(thr)) {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE;\n\t\t} else {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE;\n\t\t}\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_CONFIGURABLE)) {\n\t\tif (duk_to_boolean_top_pop(thr)) {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE;\n\t\t} else {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE;\n\t\t}\n\t}\n\n\tif (is_data_desc && is_acc_desc) {\n\t\tgoto type_error;\n\t}\n\n\t*out_defprop_flags = defprop_flags;\n\t*out_idx_value = idx_value;\n\t*out_getter = getter;\n\t*out_setter = setter;\n\n\t/* [ ... [multiple values] ] */\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_DESCRIPTOR);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Object.defineProperty() related helper (E5 Section 15.2.3.6).\n *  Also handles ES2015 Reflect.defineProperty().\n *\n *  Inlines all [[DefineOwnProperty]] exotic behaviors.\n *\n *  Note: ECMAScript compliant [[DefineOwnProperty]](P, Desc, Throw) is not\n *  implemented directly, but Object.defineProperty() serves its purpose.\n *  We don't need the [[DefineOwnProperty]] internally and we don't have a\n *  property descriptor with 'missing values' so it's easier to avoid it\n *  entirely.\n *\n *  Note: this is only called for actual objects, not primitive values.\n *  This must support virtual properties for full objects (e.g. Strings)\n *  but not for plain values (e.g. strings).  Lightfuncs, even though\n *  primitive in a sense, are treated like objects and accepted as target\n *  values.\n */\n\n/* XXX: this is a major target for size optimization */\nDUK_INTERNAL\nduk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,\n                                              duk_uint_t defprop_flags,\n                                              duk_hobject *obj,\n                                              duk_hstring *key,\n                                              duk_idx_t idx_value,\n                                              duk_hobject *get,\n                                              duk_hobject *set,\n                                              duk_bool_t throw_flag) {\n\tduk_uint32_t arr_idx;\n\tduk_tval tv;\n\tduk_bool_t has_enumerable;\n\tduk_bool_t has_configurable;\n\tduk_bool_t has_writable;\n\tduk_bool_t has_value;\n\tduk_bool_t has_get;\n\tduk_bool_t has_set;\n\tduk_bool_t is_enumerable;\n\tduk_bool_t is_configurable;\n\tduk_bool_t is_writable;\n\tduk_bool_t force_flag;\n\tduk_small_uint_t new_flags;\n\tduk_propdesc curr;\n\tduk_uint32_t arridx_new_array_length;  /* != 0 => post-update for array 'length' (used when key is an array index) */\n\tduk_uint32_t arrlen_old_len;\n\tduk_uint32_t arrlen_new_len;\n\tduk_bool_t pending_write_protect;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\t/* idx_value may be < 0 (no value), set and get may be NULL */\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\t/* All the flags fit in 16 bits, so will fit into duk_bool_t. */\n\n\thas_writable = (defprop_flags & DUK_DEFPROP_HAVE_WRITABLE);\n\thas_enumerable = (defprop_flags & DUK_DEFPROP_HAVE_ENUMERABLE);\n\thas_configurable = (defprop_flags & DUK_DEFPROP_HAVE_CONFIGURABLE);\n\thas_value = (defprop_flags & DUK_DEFPROP_HAVE_VALUE);\n\thas_get = (defprop_flags & DUK_DEFPROP_HAVE_GETTER);\n\thas_set = (defprop_flags & DUK_DEFPROP_HAVE_SETTER);\n\tis_writable = (defprop_flags & DUK_DEFPROP_WRITABLE);\n\tis_enumerable = (defprop_flags & DUK_DEFPROP_ENUMERABLE);\n\tis_configurable = (defprop_flags & DUK_DEFPROP_CONFIGURABLE);\n\tforce_flag = (defprop_flags & DUK_DEFPROP_FORCE);\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\n\tarridx_new_array_length = 0;\n\tpending_write_protect = 0;\n\tarrlen_old_len = 0;\n\tarrlen_new_len = 0;\n\n\tDUK_DDD(DUK_DDDPRINT(\"has_enumerable=%ld is_enumerable=%ld \"\n\t                     \"has_configurable=%ld is_configurable=%ld \"\n\t                     \"has_writable=%ld is_writable=%ld \"\n\t                     \"has_value=%ld value=%!T \"\n\t                     \"has_get=%ld get=%p=%!O \"\n\t                     \"has_set=%ld set=%p=%!O \"\n\t                     \"arr_idx=%ld throw_flag=!%ld\",\n\t                     (long) has_enumerable, (long) is_enumerable,\n\t                     (long) has_configurable, (long) is_configurable,\n\t                     (long) has_writable, (long) is_writable,\n\t                     (long) has_value, (duk_tval *) (idx_value >= 0 ? duk_get_tval(thr, idx_value) : NULL),\n\t                     (long) has_get, (void *) get, (duk_heaphdr *) get,\n\t                     (long) has_set, (void *) set, (duk_heaphdr *) set,\n\t                     (long) arr_idx, (long) throw_flag));\n\n\t/*\n\t *  Array exotic behaviors can be implemented at this point.  The local variables\n\t *  are essentially a 'value copy' of the input descriptor (Desc), which is modified\n\t *  by the Array [[DefineOwnProperty]] (E5 Section 15.4.5.1).\n\t */\n\n\tif (!DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\tgoto skip_array_exotic;\n\t}\n\n\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\tduk_harray *a;\n\n\t\t/* E5 Section 15.4.5.1, step 3, steps a - i are implemented here, j - n at the end */\n\t\tif (!has_value) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"exotic array behavior for 'length', but no value in descriptor -> normal behavior\"));\n\t\t\tgoto skip_array_exotic;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"exotic array behavior for 'length', value present in descriptor -> exotic behavior\"));\n\n\t\t/*\n\t\t *  Get old and new length\n\t\t */\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\t\tarrlen_old_len = a->length;\n\n\t\tDUK_ASSERT(idx_value >= 0);\n\t\tarrlen_new_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_POSIDX(thr, idx_value));\n\t\tduk_push_u32(thr, arrlen_new_len);\n\t\tduk_replace(thr, idx_value);  /* step 3.e: replace 'Desc.[[Value]]' */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"old_len=%ld, new_len=%ld\", (long) arrlen_old_len, (long) arrlen_new_len));\n\n\t\tif (arrlen_new_len >= arrlen_old_len) {\n\t\t\t/* standard behavior, step 3.f.i */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new length is same or higher as previous => standard behavior\"));\n\t\t\tgoto skip_array_exotic;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"new length is smaller than previous => exotic post behavior\"));\n\n\t\t/* XXX: consolidated algorithm step 15.f -> redundant? */\n\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a) && !force_flag) {\n\t\t\t/* Array .length is always non-configurable; if it's also\n\t\t\t * non-writable, don't allow it to be written.\n\t\t\t */\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\n\t\t/* steps 3.h and 3.i */\n\t\tif (has_writable && !is_writable) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"desc writable is false, force it back to true, and flag pending write protect\"));\n\t\t\tis_writable = 1;\n\t\t\tpending_write_protect = 1;\n\t\t}\n\n\t\t/* remaining actual steps are carried out if standard DefineOwnProperty succeeds */\n\t} else if (arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t/* XXX: any chance of unifying this with the 'length' key handling? */\n\n\t\t/* E5 Section 15.4.5.1, step 4 */\n\t\tduk_uint32_t old_len;\n\t\tduk_harray *a;\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\told_len = a->length;\n\n\t\tif (arr_idx >= old_len) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty requires array length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\n\t\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a) && !force_flag) {\n\t\t\t\t/* Array .length is always non-configurable, so\n\t\t\t\t * if it's also non-writable, don't allow a value\n\t\t\t\t * write.  With force flag allow writing.\n\t\t\t\t */\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\n\t\t\t/* actual update happens once write has been completed without\n\t\t\t * error below.\n\t\t\t */\n\t\t\tDUK_ASSERT(arr_idx != 0xffffffffUL);\n\t\t\tarridx_new_array_length = arr_idx + 1;\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty does not require length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld) -> standard behavior\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\t\t}\n\t}\n skip_array_exotic:\n\n\t/* XXX: There is currently no support for writing buffer object\n\t * indexed elements here.  Attempt to do so will succeed and\n\t * write a concrete property into the buffer object.  This should\n\t * be fixed at some point but because buffers are a custom feature\n\t * anyway, this is relatively unimportant.\n\t */\n\n\t/*\n\t *  Actual Object.defineProperty() default algorithm.\n\t */\n\n\t/*\n\t *  First check whether property exists; if not, simple case.  This covers\n\t *  steps 1-4.\n\t */\n\n\tif (!duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"property does not exist\"));\n\n\t\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(obj) && !force_flag) {\n\t\t\tgoto fail_not_extensible;\n\t\t}\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\t\t/* ROM objects are never extensible but force flag may\n\t\t * allow us to come here anyway.\n\t\t */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj) || !DUK_HOBJECT_HAS_EXTENSIBLE(obj));\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\t\tDUK_D(DUK_DPRINT(\"attempt to define property on a read-only target object\"));\n\t\t\tgoto fail_not_configurable;\n\t\t}\n#endif\n\n\t\t/* XXX: share final setting code for value and flags?  difficult because\n\t\t * refcount code is different.  Share entry allocation?  But can't allocate\n\t\t * until array index checked.\n\t\t */\n\n\t\t/* steps 4.a and 4.b are tricky */\n\t\tif (has_set || has_get) {\n\t\t\tduk_int_t e_idx;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"create new accessor property\"));\n\n\t\t\tDUK_ASSERT(has_set || set == NULL);\n\t\t\tDUK_ASSERT(has_get || get == NULL);\n\t\t\tDUK_ASSERT(!has_value);\n\t\t\tDUK_ASSERT(!has_writable);\n\n\t\t\tnew_flags = DUK_PROPDESC_FLAG_ACCESSOR;  /* defaults, E5 Section 8.6.1, Table 7 */\n\t\t\tif (has_enumerable && is_enumerable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t}\n\t\t\tif (has_configurable && is_configurable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t}\n\n\t\t\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"accessor cannot go to array part, abandon array\"));\n\t\t\t\tduk__abandon_array_part(thr, obj);\n\t\t\t}\n\n\t\t\t/* write to entry part */\n\t\t\te_idx = duk__hobject_alloc_entry_checked(thr, obj, key);\n\t\t\tDUK_ASSERT(e_idx >= 0);\n\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, e_idx, get);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, e_idx, set);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, get);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, set);\n\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags);\n\t\t\tgoto success_exotics;\n\t\t} else {\n\t\t\tduk_int_t e_idx;\n\t\t\tduk_tval *tv2;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"create new data property\"));\n\n\t\t\tDUK_ASSERT(!has_set);\n\t\t\tDUK_ASSERT(!has_get);\n\n\t\t\tnew_flags = 0;  /* defaults, E5 Section 8.6.1, Table 7 */\n\t\t\tif (has_writable && is_writable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_WRITABLE;\n\t\t\t}\n\t\t\tif (has_enumerable && is_enumerable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t}\n\t\t\tif (has_configurable && is_configurable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t}\n\t\t\tif (has_value) {\n\t\t\t\tduk_tval *tv_tmp = duk_require_tval(thr, idx_value);\n\t\t\t\tDUK_TVAL_SET_TVAL(&tv, tv_tmp);\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_UNDEFINED(&tv);  /* default value */\n\t\t\t}\n\n\t\t\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tif (new_flags == DUK_PROPDESC_FLAGS_WEC) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"new data property attributes match array defaults, attempt to write to array part\"));\n\t\t\t\t\ttv2 = duk__obtain_arridx_slot(thr, arr_idx, obj);\n\t\t\t\t\tif (tv2 == NULL) {\n\t\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"failed writing to array part, abandoned array\"));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"success in writing to array part\"));\n\t\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\t\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv2));\n\t\t\t\t\t\tDUK_TVAL_SET_TVAL(tv2, &tv);\n\t\t\t\t\t\tDUK_TVAL_INCREF(thr, tv2);\n\t\t\t\t\t\tgoto success_exotics;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"new data property cannot go to array part, abandon array\"));\n\t\t\t\t\tduk__abandon_array_part(thr, obj);\n\t\t\t\t}\n\t\t\t\t/* fall through */\n\t\t\t}\n\n\t\t\t/* write to entry part */\n\t\t\te_idx = duk__hobject_alloc_entry_checked(thr, obj, key);\n\t\t\tDUK_ASSERT(e_idx >= 0);\n\t\t\ttv2 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);\n\t\t\tDUK_TVAL_SET_TVAL(tv2, &tv);\n\t\t\tDUK_TVAL_INCREF(thr, tv2);\n\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags);\n\t\t\tgoto success_exotics;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\t}\n\n\t/* we currently assume virtual properties are not configurable (as none of them are) */\n\tDUK_ASSERT((curr.e_idx >= 0 || curr.a_idx >= 0) || !(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE));\n\n\t/* [obj key desc value get set curr_value] */\n\n\t/*\n\t *  Property already exists.  Steps 5-6 detect whether any changes need\n\t *  to be made.\n\t */\n\n\tif (has_enumerable) {\n\t\tif (is_enumerable) {\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE)) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t}\n\t}\n\tif (has_configurable) {\n\t\tif (is_configurable) {\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE)) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t}\n\t}\n\tif (has_value) {\n\t\tduk_tval *tmp1;\n\t\tduk_tval *tmp2;\n\n\t\t/* attempt to change from accessor to data property */\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tgoto need_check;\n\t\t}\n\n\t\ttmp1 = duk_require_tval(thr, -1);         /* curr value */\n\t\ttmp2 = duk_require_tval(thr, idx_value);  /* new value */\n\t\tif (!duk_js_samevalue(tmp1, tmp2)) {\n\t\t\tgoto need_check;\n\t\t}\n\t}\n\tif (has_writable) {\n\t\t/* attempt to change from accessor to data property */\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tgoto need_check;\n\t\t}\n\n\t\tif (is_writable) {\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_WRITABLE) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t}\n\t}\n\tif (has_set) {\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tif (set != curr.set) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tgoto need_check;\n\t\t}\n\t}\n\tif (has_get) {\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tif (get != curr.get) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tgoto need_check;\n\t\t}\n\t}\n\n\t/* property exists, either 'desc' is empty, or all values\n\t * match (SameValue)\n\t */\n\tgoto success_no_exotics;\n\n need_check:\n\n\t/*\n\t *  Some change(s) need to be made.  Steps 7-11.\n\t */\n\n\t/* shared checks for all descriptor types */\n\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\tif (has_configurable && is_configurable) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\t\tif (has_enumerable) {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE) {\n\t\t\t\tif (!is_enumerable) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (is_enumerable) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Virtual properties don't have backing so they can't mostly be\n\t * edited.  Some virtual properties are, however, writable: for\n\t * example, virtual index properties of buffer objects and Array\n\t * instance .length.  These are not configurable so the checks\n\t * above mostly cover attempts to change them, except when the\n\t * duk_def_prop() call is used with DUK_DEFPROP_FORCE; even in\n\t * that case we can't forcibly change the property attributes\n\t * because they don't have concrete backing.\n\t */\n\n\t/* XXX: for ROM objects too it'd be best if value modify was\n\t * allowed if the value matches SameValue.\n\t */\n\t/* Reject attempt to change a read-only object. */\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to define property on read-only target object\"));\n\t\tgoto fail_not_configurable;\n\t}\n#endif\n\n\t/* descriptor type specific checks */\n\tif (has_set || has_get) {\n\t\t/* IsAccessorDescriptor(desc) == true */\n\t\tDUK_ASSERT(!has_writable);\n\t\tDUK_ASSERT(!has_value);\n\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t/* curr and desc are accessors */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tif (has_set && set != curr.set) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t\tif (has_get && get != curr.get) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tduk_bool_t rc;\n\t\t\tduk_tval *tv1;\n\n\t\t\t/* curr is data, desc is accessor */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"convert property to accessor property\"));\n\t\t\tif (curr.a_idx >= 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property to convert is stored in an array entry, abandon array and re-lookup\"));\n\t\t\t\tduk__abandon_array_part(thr, obj);\n\t\t\t\tduk_pop_unsafe(thr);  /* remove old value */\n\t\t\t\trc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);\n\t\t\t\tDUK_UNREF(rc);\n\t\t\t\tDUK_ASSERT(rc != 0);\n\t\t\t\tDUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);\n\t\t\t}\n\t\t\tif (curr.e_idx < 0) {\n\t\t\t\tDUK_ASSERT(curr.a_idx < 0 && curr.e_idx < 0);\n\t\t\t\tgoto fail_virtual;  /* safeguard for virtual property */\n\t\t\t}\n\n\t\t\tDUK_ASSERT(curr.e_idx >= 0);\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\n\t\t\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv1);  /* XXX: just decref */\n\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_HOBJECT_E_SLOT_SET_ACCESSOR(thr->heap, obj, curr.e_idx);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"flags after data->accessor conversion: 0x%02lx\",\n\t\t\t                     (unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));\n\t\t\t/* Update curr.flags; faster than a re-lookup. */\n\t\t\tcurr.flags &= ~DUK_PROPDESC_FLAG_WRITABLE;\n\t\t\tcurr.flags |= DUK_PROPDESC_FLAG_ACCESSOR;\n\t\t}\n\t} else if (has_value || has_writable) {\n\t\t/* IsDataDescriptor(desc) == true */\n\t\tDUK_ASSERT(!has_set);\n\t\tDUK_ASSERT(!has_get);\n\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tduk_hobject *tmp;\n\n\t\t\t/* curr is accessor, desc is data */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\n\t\t\t/* curr is accessor -> cannot be in array part. */\n\t\t\tDUK_ASSERT(curr.a_idx < 0);\n\t\t\tif (curr.e_idx < 0) {\n\t\t\t\tgoto fail_virtual;  /* safeguard; no virtual accessors now */\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"convert property to data property\"));\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\n\t\t\tDUK_TVAL_SET_UNDEFINED(DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx));\n\t\t\tDUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(thr->heap, obj, curr.e_idx);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"flags after accessor->data conversion: 0x%02lx\",\n\t\t\t                     (unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));\n\n\t\t\t/* Update curr.flags; faster than a re-lookup. */\n\t\t\tcurr.flags &= ~(DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ACCESSOR);\n\t\t} else {\n\t\t\t/* curr and desc are data */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && has_writable && is_writable) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t\t/* Note: changing from writable to non-writable is OK */\n\t\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && has_value) {\n\t\t\t\t\tduk_tval *tmp1 = duk_require_tval(thr, -1);         /* curr value */\n\t\t\t\t\tduk_tval *tmp2 = duk_require_tval(thr, idx_value);  /* new value */\n\t\t\t\t\tif (!duk_js_samevalue(tmp1, tmp2)) {\n\t\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\t/* IsGenericDescriptor(desc) == true; this means in practice that 'desc'\n\t\t * only has [[Enumerable]] or [[Configurable]] flag updates, which are\n\t\t * allowed at this point.\n\t\t */\n\n\t\tDUK_ASSERT(!has_value && !has_writable && !has_get && !has_set);\n\t}\n\n\t/*\n\t *  Start doing property attributes updates.  Steps 12-13.\n\t *\n\t *  Start by computing new attribute flags without writing yet.\n\t *  Property type conversion is done above if necessary.\n\t */\n\n\tnew_flags = curr.flags;\n\n\tif (has_enumerable) {\n\t\tif (is_enumerable) {\n\t\t\tnew_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t} else {\n\t\t\tnew_flags &= ~DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t}\n\t}\n\tif (has_configurable) {\n\t\tif (is_configurable) {\n\t\t\tnew_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t} else {\n\t\t\tnew_flags &= ~DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t}\n\t}\n\tif (has_writable) {\n\t\tif (is_writable) {\n\t\t\tnew_flags |= DUK_PROPDESC_FLAG_WRITABLE;\n\t\t} else {\n\t\t\tnew_flags &= ~DUK_PROPDESC_FLAG_WRITABLE;\n\t\t}\n\t}\n\n\t/* XXX: write protect after flag? -> any chance of handling it here? */\n\n\tDUK_DDD(DUK_DDDPRINT(\"new flags that we want to write: 0x%02lx\",\n\t                     (unsigned long) new_flags));\n\n\t/*\n\t *  Check whether we need to abandon an array part (if it exists)\n\t */\n\n\tif (curr.a_idx >= 0) {\n\t\tduk_bool_t rc;\n\n\t\tDUK_ASSERT(curr.e_idx < 0);\n\n\t\tif (new_flags == DUK_PROPDESC_FLAGS_WEC) {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index, new property attributes match array defaults, update in-place\"));\n\n\t\t\tDUK_ASSERT(curr.flags == DUK_PROPDESC_FLAGS_WEC);  /* must have been, since in array part */\n\t\t\tDUK_ASSERT(!has_set);\n\t\t\tDUK_ASSERT(!has_get);\n\t\t\tDUK_ASSERT(idx_value >= 0);  /* must be: if attributes match and we get here the value must differ (otherwise no change) */\n\n\t\t\ttv2 = duk_require_tval(thr, idx_value);\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, curr.a_idx);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects; may invalidate a_idx */\n\t\t\tgoto success_exotics;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array index, new property attributes do not match array defaults, abandon array and re-lookup\"));\n\t\tduk__abandon_array_part(thr, obj);\n\t\tduk_pop_unsafe(thr);  /* remove old value */\n\t\trc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);\n\t\tDUK_UNREF(rc);\n\t\tDUK_ASSERT(rc != 0);\n\t\tDUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"updating existing property in entry part\"));\n\n\t/* Array case is handled comprehensively above: either in entry\n\t * part or a virtual property.\n\t */\n\tDUK_ASSERT(curr.a_idx < 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"update existing property attributes\"));\n\tif (curr.e_idx >= 0) {\n\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, curr.e_idx, new_flags);\n\t} else {\n\t\t/* For Array .length the only allowed transition is for .length\n\t\t * to become non-writable.\n\t\t */\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\t\tduk_harray *a;\n\t\t\ta = (duk_harray *) obj;\n\t\t\tDUK_DD(DUK_DDPRINT(\"Object.defineProperty() attribute update for duk_harray .length -> %02lx\", (unsigned long) new_flags));\n\t\t\tDUK_HARRAY_ASSERT_VALID(a);\n\t\t\tif ((new_flags & DUK_PROPDESC_FLAGS_EC) != (curr.flags & DUK_PROPDESC_FLAGS_EC)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"Object.defineProperty() attempt to change virtual array .length enumerable or configurable attribute, fail\"));\n\t\t\t\tgoto fail_virtual;\n\t\t\t}\n\t\t\tif (new_flags & DUK_PROPDESC_FLAG_WRITABLE) {\n\t\t\t\tDUK_HARRAY_SET_LENGTH_WRITABLE(a);\n\t\t\t} else {\n\t\t\t\tDUK_HARRAY_SET_LENGTH_NONWRITABLE(a);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (has_set) {\n\t\tduk_hobject *tmp;\n\n\t\t/* Virtual properties are non-configurable but with a 'force'\n\t\t * flag we might come here so check explicitly for virtual.\n\t\t */\n\t\tif (curr.e_idx < 0) {\n\t\t\tgoto fail_virtual;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"update existing property setter\"));\n\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\n\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);\n\t\tDUK_UNREF(tmp);\n\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, set);\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, set);\n\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);  /* side effects; may invalidate e_idx */\n\t}\n\tif (has_get) {\n\t\tduk_hobject *tmp;\n\n\t\tif (curr.e_idx < 0) {\n\t\t\tgoto fail_virtual;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"update existing property getter\"));\n\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\n\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);\n\t\tDUK_UNREF(tmp);\n\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, get);\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, get);\n\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);  /* side effects; may invalidate e_idx */\n\t}\n\tif (has_value) {\n\t\tduk_tval *tv1, *tv2;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"update existing property value\"));\n\n\t\tif (curr.e_idx >= 0) {\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\t\t\ttv2 = duk_require_tval(thr, idx_value);\n\t\t\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects; may invalidate e_idx */\n\t\t} else {\n\t\t\tDUK_ASSERT(curr.a_idx < 0);  /* array part case handled comprehensively previously */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"Object.defineProperty(), value update for virtual property\"));\n\t\t\t/* XXX: Uint8Array and other typed array virtual writes not currently\n\t\t\t * handled.\n\t\t\t */\n\t\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\t\t\tduk_harray *a;\n\t\t\t\ta = (duk_harray *) obj;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"Object.defineProperty() value update for duk_harray .length -> %ld\", (long) arrlen_new_len));\n\t\t\t\tDUK_HARRAY_ASSERT_VALID(a);\n\t\t\t\ta->length = arrlen_new_len;\n\t\t\t} else {\n\t\t\t\tgoto fail_virtual;  /* should not happen */\n\t\t\t}\n\t\t}\n\t}\n\n\t/*\n\t *  Standard algorithm succeeded without errors, check for exotic post-behaviors.\n\t *\n\t *  Arguments exotic behavior in E5 Section 10.6 occurs after the standard\n\t *  [[DefineOwnProperty]] has completed successfully.\n\t *\n\t *  Array exotic behavior in E5 Section 15.4.5.1 is implemented partly\n\t *  prior to the default [[DefineOwnProperty]], but:\n\t *    - for an array index key (e.g. \"10\") the final 'length' update occurs here\n\t *    - for 'length' key the element deletion and 'length' update occurs here\n\t */\n\n success_exotics:\n\n\t/* curr.a_idx or curr.e_idx may have been invalidated by side effects\n\t * above.\n\t */\n\n\t/* [obj key desc value get set curr_value] */\n\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\tduk_harray *a;\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\tif (arridx_new_array_length > 0) {\n\t\t\t/*\n\t\t\t *  Note: zero works as a \"no update\" marker because the new length\n\t\t\t *  can never be zero after a new property is written.\n\t\t\t */\n\n\t\t\t/* E5 Section 15.4.5.1, steps 4.e.i - 4.e.ii */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, pending array length update to: %ld\",\n\t\t\t                     (long) arridx_new_array_length));\n\n\t\t\ta->length = arridx_new_array_length;\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && arrlen_new_len < arrlen_old_len) {\n\t\t\t/*\n\t\t\t *  E5 Section 15.4.5.1, steps 3.k - 3.n.  The order at the end combines\n\t\t\t *  the error case 3.l.iii and the success case 3.m-3.n.\n\t\t\t */\n\n\t\t\t/* XXX: investigate whether write protect can be handled above, if we\n\t\t\t * just update length here while ignoring its protected status\n\t\t\t */\n\n\t\t\tduk_uint32_t result_len;\n\t\t\tduk_bool_t rc;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key is 'length', exotic array behavior, \"\n\t\t\t                     \"doing array element deletion and length update\"));\n\n\t\t\trc = duk__handle_put_array_length_smaller(thr, obj, arrlen_old_len, arrlen_new_len, force_flag, &result_len);\n\n\t\t\t/* update length (curr points to length, and we assume it's still valid) */\n\t\t\tDUK_ASSERT(result_len >= arrlen_new_len && result_len <= arrlen_old_len);\n\n\t\t\ta->length = result_len;\n\n\t\t\tif (pending_write_protect) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"setting array length non-writable (pending writability update)\"));\n\t\t\t\tDUK_HARRAY_SET_LENGTH_NONWRITABLE(a);\n\t\t\t}\n\n\t\t\t/* XXX: shrink array allocation or entries compaction here? */\n\t\t\tif (!rc) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"array length write only partially successful\"));\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\t\t}\n\t} else if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)) {\n\t\tduk_hobject *map;\n\t\tduk_hobject *varenv;\n\n\t\tDUK_ASSERT(arridx_new_array_length == 0);\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj));  /* traits are separate; in particular, arguments not an array */\n\n\t\tmap = NULL;\n\t\tvarenv = NULL;\n\t\tif (!duk__lookup_arguments_map(thr, obj, key, &curr, &map, &varenv)) {\n\t\t\tgoto success_no_exotics;\n\t\t}\n\t\tDUK_ASSERT(map != NULL);\n\t\tDUK_ASSERT(varenv != NULL);\n\n\t\t/* [obj key desc value get set curr_value varname] */\n\n\t\tif (has_set || has_get) {\n\t\t\t/* = IsAccessorDescriptor(Desc) */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map' \"\n\t\t\t                     \"changed to an accessor, delete arguments binding\"));\n\n\t\t\t(void) duk_hobject_delprop_raw(thr, map, key, 0);  /* ignore result */\n\t\t} else {\n\t\t\t/* Note: this order matters (final value before deleting map entry must be done) */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map', \"\n\t\t\t                     \"check for value update / binding deletion\"));\n\n\t\t\tif (has_value) {\n\t\t\t\tduk_hstring *varname;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map', \"\n\t\t\t\t                     \"update bound value (variable/argument)\"));\n\n\t\t\t\tvarname = duk_require_hstring(thr, -1);\n\t\t\t\tDUK_ASSERT(varname != NULL);\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"arguments object automatic putvar for a bound variable; \"\n\t\t\t\t                     \"key=%!O, varname=%!O, value=%!T\",\n\t\t\t\t                     (duk_heaphdr *) key,\n\t\t\t\t                     (duk_heaphdr *) varname,\n\t\t\t\t                     (duk_tval *) duk_require_tval(thr, idx_value)));\n\n\t\t\t\t/* strict flag for putvar comes from our caller (currently: fixed) */\n\t\t\t\tduk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(thr, idx_value), 1 /*throw_flag*/);\n\t\t\t}\n\t\t\tif (has_writable && !is_writable) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map', \"\n\t\t\t\t                     \"changed to non-writable, delete arguments binding\"));\n\n\t\t\t\t(void) duk_hobject_delprop_raw(thr, map, key, 0);  /* ignore result */\n\t\t\t}\n\t\t}\n\n\t\t/* 'varname' is in stack in this else branch, leaving an unbalanced stack below,\n\t\t * but this doesn't matter now.\n\t\t */\n\t}\n\n success_no_exotics:\n\t/* Some code paths use NORZ macros for simplicity, ensure refzero\n\t * handling is completed.\n\t */\n\tDUK_REFZERO_CHECK_SLOW(thr);\n\treturn 1;\n\n fail_not_extensible:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n\n fail_virtual:  /* just use the same \"not configurable\" error message\" */\n fail_not_configurable:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n}\n\n/*\n *  Object.prototype.hasOwnProperty() and Object.prototype.propertyIsEnumerable().\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_object_ownprop_helper(duk_hthread *thr, duk_small_uint_t required_desc_flags) {\n\tduk_hstring *h_v;\n\tduk_hobject *h_obj;\n\tduk_propdesc desc;\n\tduk_bool_t ret;\n\n\t/* coercion order matters */\n\th_v = duk_to_hstring_acceptsymbol(thr, 0);\n\tDUK_ASSERT(h_v != NULL);\n\n\th_obj = duk_push_this_coercible_to_object(thr);\n\tDUK_ASSERT(h_obj != NULL);\n\n\tret = duk_hobject_get_own_propdesc(thr, h_obj, h_v, &desc, 0 /*flags*/);  /* don't push value */\n\n\tduk_push_boolean(thr, ret && ((desc.flags & required_desc_flags) == required_desc_flags));\n\treturn 1;\n}\n\n/*\n *  Object.seal() and Object.freeze()  (E5 Sections 15.2.3.8 and 15.2.3.9)\n *\n *  Since the algorithms are similar, a helper provides both functions.\n *  Freezing is essentially sealing + making plain properties non-writable.\n *\n *  Note: virtual (non-concrete) properties which are non-configurable but\n *  writable would pose some problems, but such properties do not currently\n *  exist (all virtual properties are non-configurable and non-writable).\n *  If they did exist, the non-configurability does NOT prevent them from\n *  becoming non-writable.  However, this change should be recorded somehow\n *  so that it would turn up (e.g. when getting the property descriptor),\n *  requiring some additional flags in the object.\n */\n\nDUK_INTERNAL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze) {\n\tduk_uint_fast32_t i;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to seal/freeze a readonly object, reject\"));\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\t/*\n\t *  Abandon array part because all properties must become non-configurable.\n\t *  Note that this is now done regardless of whether this is always the case\n\t *  (skips check, but performance problem if caller would do this many times\n\t *  for the same object; not likely).\n\t */\n\n\tduk__abandon_array_part(thr, obj);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) == 0);\n\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tduk_uint8_t *fp;\n\n\t\t/* since duk__abandon_array_part() causes a resize, there should be no gaps in keys */\n\t\tDUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != NULL);\n\n\t\t/* avoid multiple computations of flags address; bypasses macros */\n\t\tfp = DUK_HOBJECT_E_GET_FLAGS_PTR(thr->heap, obj, i);\n\t\tif (is_freeze && !((*fp) & DUK_PROPDESC_FLAG_ACCESSOR)) {\n\t\t\t*fp &= ~(DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE);\n\t\t} else {\n\t\t\t*fp &= ~DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t}\n\t}\n\n\tDUK_HOBJECT_CLEAR_EXTENSIBLE(obj);\n\n\t/* no need to compact since we already did that in duk__abandon_array_part()\n\t * (regardless of whether an array part existed or not.\n\t */\n\n\treturn;\n}\n\n/*\n *  Object.isSealed() and Object.isFrozen()  (E5 Sections 15.2.3.11, 15.2.3.13)\n *\n *  Since the algorithms are similar, a helper provides both functions.\n *  Freezing is essentially sealing + making plain properties non-writable.\n *\n *  Note: all virtual (non-concrete) properties are currently non-configurable\n *  and non-writable (and there are no accessor virtual properties), so they don't\n *  need to be considered here now.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen) {\n\tduk_uint_fast32_t i;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(thr);\n\n\t/* Note: no allocation pressure, no need to check refcounts etc */\n\n\t/* must not be extensible */\n\tif (DUK_HOBJECT_HAS_EXTENSIBLE(obj)) {\n\t\treturn 0;\n\t}\n\n\t/* all virtual properties are non-configurable and non-writable */\n\n\t/* entry part must not contain any configurable properties, or\n\t * writable properties (if is_frozen).\n\t */\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tduk_small_uint_t flags;\n\n\t\tif (!DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* avoid multiple computations of flags address; bypasses macros */\n\t\tflags = (duk_small_uint_t) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, i);\n\n\t\tif (flags & DUK_PROPDESC_FLAG_CONFIGURABLE) {\n\t\t\treturn 0;\n\t\t}\n\t\tif (is_frozen &&\n\t\t    !(flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t    (flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* array part must not contain any non-unused properties, as they would\n\t * be configurable and writable.\n\t */\n\tfor (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\tduk_tval *tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\treturn 1;\n}\n\n/*\n *  Object.preventExtensions() and Object.isExtensible()  (E5 Sections 15.2.3.10, 15.2.3.13)\n *\n *  Not needed, implemented by macros DUK_HOBJECT_{HAS,CLEAR,SET}_EXTENSIBLE\n *  and the Object built-in bindings.\n */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hproxy.h",
    "content": "/*\n *  Proxy object representation.\n */\n\n#if !defined(DUK_HPROXY_H_INCLUDED)\n#define DUK_HPROXY_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hproxy_assert_valid(duk_hproxy *h);\n#define DUK_HPROXY_ASSERT_VALID(h)  do { duk_hproxy_assert_valid((h)); } while (0)\n#else\n#define DUK_HPROXY_ASSERT_VALID(h)  do {} while (0)\n#endif\n\nstruct duk_hproxy {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Proxy target object. */\n\tduk_hobject *target;\n\n\t/* Proxy handlers (traps). */\n\tduk_hobject *handler;\n};\n\n#endif  /* DUK_HPROXY_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hstring.h",
    "content": "/*\n *  Heap string representation.\n *\n *  Strings are byte sequences ordinarily stored in extended UTF-8 format,\n *  allowing values larger than the official UTF-8 range (used internally)\n *  and also allowing UTF-8 encoding of surrogate pairs (CESU-8 format).\n *  Strings may also be invalid UTF-8 altogether which is the case e.g. with\n *  strings used as internal property names and raw buffers converted to\n *  strings.  In such cases the 'clen' field contains an inaccurate value.\n *\n *  ECMAScript requires support for 32-bit long strings.  However, since each\n *  16-bit codepoint can take 3 bytes in CESU-8, this representation can only\n *  support about 1.4G codepoint long strings in extreme cases.  This is not\n *  really a practical issue.\n */\n\n#if !defined(DUK_HSTRING_H_INCLUDED)\n#define DUK_HSTRING_H_INCLUDED\n\n/* Impose a maximum string length for now.  Restricted artificially to\n * ensure adding a heap header length won't overflow size_t.  The limit\n * should be synchronized with DUK_HBUFFER_MAX_BYTELEN.\n *\n * E5.1 makes provisions to support strings longer than 4G characters.\n * This limit should be eliminated on 64-bit platforms (and increased\n * closer to maximum support on 32-bit platforms).\n */\n\n#if defined(DUK_USE_STRLEN16)\n#define DUK_HSTRING_MAX_BYTELEN                     (0x0000ffffUL)\n#else\n#define DUK_HSTRING_MAX_BYTELEN                     (0x7fffffffUL)\n#endif\n\n/* XXX: could add flags for \"is valid CESU-8\" (ECMAScript compatible strings),\n * \"is valid UTF-8\", \"is valid extended UTF-8\" (internal strings are not,\n * regexp bytecode is), and \"contains non-BMP characters\".  These are not\n * needed right now.\n */\n\n/* With lowmem builds the high 16 bits of duk_heaphdr are used for other\n * purposes, so this leaves 7 duk_heaphdr flags and 9 duk_hstring flags.\n */\n#define DUK_HSTRING_FLAG_ASCII                      DUK_HEAPHDR_USER_FLAG(0)  /* string is ASCII, clen == blen */\n#define DUK_HSTRING_FLAG_ARRIDX                     DUK_HEAPHDR_USER_FLAG(1)  /* string is a valid array index */\n#define DUK_HSTRING_FLAG_SYMBOL                     DUK_HEAPHDR_USER_FLAG(2)  /* string is a symbol (invalid utf-8) */\n#define DUK_HSTRING_FLAG_HIDDEN                     DUK_HEAPHDR_USER_FLAG(3)  /* string is a hidden symbol (implies symbol, Duktape 1.x internal string) */\n#define DUK_HSTRING_FLAG_RESERVED_WORD              DUK_HEAPHDR_USER_FLAG(4)  /* string is a reserved word (non-strict) */\n#define DUK_HSTRING_FLAG_STRICT_RESERVED_WORD       DUK_HEAPHDR_USER_FLAG(5)  /* string is a reserved word (strict) */\n#define DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS          DUK_HEAPHDR_USER_FLAG(6)  /* string is 'eval' or 'arguments' */\n#define DUK_HSTRING_FLAG_EXTDATA                    DUK_HEAPHDR_USER_FLAG(7)  /* string data is external (duk_hstring_external) */\n#define DUK_HSTRING_FLAG_PINNED_LITERAL             DUK_HEAPHDR_USER_FLAG(8)  /* string is a literal, and pinned */\n\n#define DUK_HSTRING_HAS_ASCII(x)                    DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII)\n#define DUK_HSTRING_HAS_ARRIDX(x)                   DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX)\n#define DUK_HSTRING_HAS_SYMBOL(x)                   DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL)\n#define DUK_HSTRING_HAS_HIDDEN(x)                   DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN)\n#define DUK_HSTRING_HAS_RESERVED_WORD(x)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD)\n#define DUK_HSTRING_HAS_STRICT_RESERVED_WORD(x)     DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD)\n#define DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(x)        DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS)\n#define DUK_HSTRING_HAS_EXTDATA(x)                  DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA)\n#define DUK_HSTRING_HAS_PINNED_LITERAL(x)           DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL)\n\n#define DUK_HSTRING_SET_ASCII(x)                    DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII)\n#define DUK_HSTRING_SET_ARRIDX(x)                   DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX)\n#define DUK_HSTRING_SET_SYMBOL(x)                   DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL)\n#define DUK_HSTRING_SET_HIDDEN(x)                   DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN)\n#define DUK_HSTRING_SET_RESERVED_WORD(x)            DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD)\n#define DUK_HSTRING_SET_STRICT_RESERVED_WORD(x)     DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD)\n#define DUK_HSTRING_SET_EVAL_OR_ARGUMENTS(x)        DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS)\n#define DUK_HSTRING_SET_EXTDATA(x)                  DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA)\n#define DUK_HSTRING_SET_PINNED_LITERAL(x)           DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL)\n\n#define DUK_HSTRING_CLEAR_ASCII(x)                  DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII)\n#define DUK_HSTRING_CLEAR_ARRIDX(x)                 DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX)\n#define DUK_HSTRING_CLEAR_SYMBOL(x)                 DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL)\n#define DUK_HSTRING_CLEAR_HIDDEN(x)                 DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN)\n#define DUK_HSTRING_CLEAR_RESERVED_WORD(x)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD)\n#define DUK_HSTRING_CLEAR_STRICT_RESERVED_WORD(x)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD)\n#define DUK_HSTRING_CLEAR_EVAL_OR_ARGUMENTS(x)      DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS)\n#define DUK_HSTRING_CLEAR_EXTDATA(x)                DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA)\n#define DUK_HSTRING_CLEAR_PINNED_LITERAL(x)         DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL)\n\n#if 0  /* Slightly smaller code without explicit flag, but explicit flag\n        * is very useful when 'clen' is dropped.\n        */\n#define DUK_HSTRING_IS_ASCII(x)                     (DUK_HSTRING_GET_BYTELEN((x)) == DUK_HSTRING_GET_CHARLEN((x)))\n#endif\n#define DUK_HSTRING_IS_ASCII(x)                     DUK_HSTRING_HAS_ASCII((x))  /* lazily set! */\n#define DUK_HSTRING_IS_EMPTY(x)                     (DUK_HSTRING_GET_BYTELEN((x)) == 0)\n\n#if defined(DUK_USE_STRHASH16)\n#define DUK_HSTRING_GET_HASH(x)                     ((x)->hdr.h_flags >> 16)\n#define DUK_HSTRING_SET_HASH(x,v) do { \\\n\t\t(x)->hdr.h_flags = ((x)->hdr.h_flags & 0x0000ffffUL) | ((v) << 16); \\\n\t} while (0)\n#else\n#define DUK_HSTRING_GET_HASH(x)                     ((x)->hash)\n#define DUK_HSTRING_SET_HASH(x,v) do { \\\n\t\t(x)->hash = (v); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_STRLEN16)\n#define DUK_HSTRING_GET_BYTELEN(x)                  ((x)->hdr.h_strextra16)\n#define DUK_HSTRING_SET_BYTELEN(x,v) do { \\\n\t\t(x)->hdr.h_strextra16 = (v); \\\n\t} while (0)\n#if defined(DUK_USE_HSTRING_CLEN)\n#define DUK_HSTRING_GET_CHARLEN(x)                  duk_hstring_get_charlen((x))\n#define DUK_HSTRING_SET_CHARLEN(x,v) do { \\\n\t\t(x)->clen16 = (v); \\\n\t} while (0)\n#else\n#define DUK_HSTRING_GET_CHARLEN(x)                  duk_hstring_get_charlen((x))\n#define DUK_HSTRING_SET_CHARLEN(x,v) do { \\\n\t\tDUK_ASSERT(0);  /* should never be called */ \\\n\t} while (0)\n#endif\n#else\n#define DUK_HSTRING_GET_BYTELEN(x)                  ((x)->blen)\n#define DUK_HSTRING_SET_BYTELEN(x,v) do { \\\n\t\t(x)->blen = (v); \\\n\t} while (0)\n#define DUK_HSTRING_GET_CHARLEN(x)                  duk_hstring_get_charlen((x))\n#define DUK_HSTRING_SET_CHARLEN(x,v) do { \\\n\t\t(x)->clen = (v); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_HSTRING_EXTDATA)\n#define DUK_HSTRING_GET_EXTDATA(x) \\\n\t((x)->extdata)\n#define DUK_HSTRING_GET_DATA(x) \\\n\t(DUK_HSTRING_HAS_EXTDATA((x)) ? \\\n\t\tDUK_HSTRING_GET_EXTDATA((const duk_hstring_external *) (x)) : ((const duk_uint8_t *) ((x) + 1)))\n#else\n#define DUK_HSTRING_GET_DATA(x) \\\n\t((const duk_uint8_t *) ((x) + 1))\n#endif\n\n#define DUK_HSTRING_GET_DATA_END(x) \\\n\t(DUK_HSTRING_GET_DATA((x)) + (x)->blen)\n\n/* Marker value; in E5 2^32-1 is not a valid array index (2^32-2 is highest\n * valid).\n */\n#define DUK_HSTRING_NO_ARRAY_INDEX  (0xffffffffUL)\n\n#if defined(DUK_USE_HSTRING_ARRIDX)\n#define DUK_HSTRING_GET_ARRIDX_FAST(h)  ((h)->arridx)\n#define DUK_HSTRING_GET_ARRIDX_SLOW(h)  ((h)->arridx)\n#else\n/* Get array index related to string (or return DUK_HSTRING_NO_ARRAY_INDEX);\n * avoids helper call if string has no array index value.\n */\n#define DUK_HSTRING_GET_ARRIDX_FAST(h)  \\\n\t(DUK_HSTRING_HAS_ARRIDX((h)) ? duk_js_to_arrayindex_hstring_fast_known((h)) : DUK_HSTRING_NO_ARRAY_INDEX)\n\n/* Slower but more compact variant. */\n#define DUK_HSTRING_GET_ARRIDX_SLOW(h)  \\\n\t(duk_js_to_arrayindex_hstring_fast((h)))\n#endif\n\n/* XXX: these actually fit into duk_hstring */\n#define DUK_SYMBOL_TYPE_HIDDEN 0\n#define DUK_SYMBOL_TYPE_GLOBAL 1\n#define DUK_SYMBOL_TYPE_LOCAL 2\n#define DUK_SYMBOL_TYPE_WELLKNOWN 3\n\n/* Assertion for duk_hstring validity. */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hstring_assert_valid(duk_hstring *h);\n#define DUK_HSTRING_ASSERT_VALID(h)  do { duk_hstring_assert_valid((h)); } while (0)\n#else\n#define DUK_HSTRING_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Misc\n */\n\nstruct duk_hstring {\n\t/* Smaller heaphdr than for other objects, because strings are held\n\t * in string intern table which requires no link pointers.  Much of\n\t * the 32-bit flags field is unused by flags, so we can stuff a 16-bit\n\t * field in there.\n\t */\n\tduk_heaphdr_string hdr;\n\n\t/* String hash. */\n#if defined(DUK_USE_STRHASH16)\n\t/* If 16-bit hash is in use, stuff it into duk_heaphdr_string flags. */\n#else\n\tduk_uint32_t hash;\n#endif\n\n\t/* Precomputed array index (or DUK_HSTRING_NO_ARRAY_INDEX). */\n#if defined(DUK_USE_HSTRING_ARRIDX)\n\tduk_uarridx_t arridx;\n#endif\n\n\t/* Length in bytes (not counting NUL term). */\n#if defined(DUK_USE_STRLEN16)\n\t/* placed in duk_heaphdr_string */\n#else\n\tduk_uint32_t blen;\n#endif\n\n\t/* Length in codepoints (must be E5 compatible). */\n#if defined(DUK_USE_STRLEN16)\n#if defined(DUK_USE_HSTRING_CLEN)\n\tduk_uint16_t clen16;\n#else\n\t/* computed live */\n#endif\n#else\n\tduk_uint32_t clen;\n#endif\n\n\t/*\n\t *  String data of 'blen+1' bytes follows (+1 for NUL termination\n\t *  convenience for C API).  No alignment needs to be guaranteed\n\t *  for strings, but fields above should guarantee alignment-by-4\n\t *  (but not alignment-by-8).\n\t */\n};\n\n/* The external string struct is defined even when the feature is inactive. */\nstruct duk_hstring_external {\n\tduk_hstring str;\n\n\t/*\n\t *  For an external string, the NUL-terminated string data is stored\n\t *  externally.  The user must guarantee that data behind this pointer\n\t *  doesn't change while it's used.\n\t */\n\n\tconst duk_uint8_t *extdata;\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, duk_uint_t pos, duk_bool_t surrogate_aware);\nDUK_INTERNAL_DECL duk_bool_t duk_hstring_equals_ascii_cstring(duk_hstring *h, const char *cstr);\nDUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);\n#if !defined(DUK_USE_HSTRING_LAZY_CLEN)\nDUK_INTERNAL_DECL void duk_hstring_init_charlen(duk_hstring *h);\n#endif\n\n#endif  /* DUK_HSTRING_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hstring_assert.c",
    "content": "/*\n *  duk_hstring assertion helpers.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_ASSERTIONS)\n\nDUK_INTERNAL void duk_hstring_assert_valid(duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hstring_misc.c",
    "content": "/*\n *  Misc support functions\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  duk_hstring charCodeAt, with and without surrogate awareness\n */\n\nDUK_INTERNAL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, duk_uint_t pos, duk_bool_t surrogate_aware) {\n\tduk_uint32_t boff;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_ucodepoint_t cp1;\n\tduk_ucodepoint_t cp2;\n\n\t/* Caller must check character offset to be inside the string. */\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT_DISABLE(pos >= 0);  /* unsigned */\n\tDUK_ASSERT(pos < (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h));\n\n\tboff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint32_t) pos);\n\tDUK_DDD(DUK_DDDPRINT(\"charCodeAt: pos=%ld -> boff=%ld, str=%!O\",\n\t                     (long) pos, (long) boff, (duk_heaphdr *) h));\n\tDUK_ASSERT_DISABLE(boff >= 0);\n\tDUK_ASSERT(boff < DUK_HSTRING_GET_BYTELEN(h));\n\n\tp_start = DUK_HSTRING_GET_DATA(h);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h);\n\tp = p_start + boff;\n\tDUK_DDD(DUK_DDDPRINT(\"p_start=%p, p_end=%p, p=%p\",\n\t                     (const void *) p_start, (const void *) p_end,\n\t                     (const void *) p));\n\n\t/* For invalid UTF-8 (never happens for standard ECMAScript strings)\n\t * return U+FFFD replacement character.\n\t */\n\tif (duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp1)) {\n\t\tif (surrogate_aware && cp1 >= 0xd800UL && cp1 <= 0xdbffUL) {\n\t\t\t/* The decode helper is memory safe even if 'cp1' was\n\t\t\t * decoded at the end of the string and 'p' is no longer\n\t\t\t * within string memory range.\n\t\t\t */\n\t\t\tcp2 = 0;  /* If call fails, this is left untouched and won't match cp2 check. */\n\t\t\t(void) duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp2);\n\t\t\tif (cp2 >= 0xdc00UL && cp2 <= 0xdfffUL) {\n\t\t\t\tcp1 = (duk_ucodepoint_t) (((cp1 - 0xd800UL) << 10) + (cp2 - 0xdc00UL) + 0x10000UL);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tcp1 = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t}\n\n\treturn cp1;\n}\n\n/*\n *  duk_hstring charlen, when lazy charlen disabled\n */\n\n#if !defined(DUK_USE_HSTRING_LAZY_CLEN)\n#if !defined(DUK_USE_HSTRING_CLEN)\n#error non-lazy duk_hstring charlen but DUK_USE_HSTRING_CLEN not set\n#endif\nDUK_INTERNAL void duk_hstring_init_charlen(duk_hstring *h) {\n\tduk_uint32_t clen;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(!DUK_HSTRING_HAS_ASCII(h));\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h));\n\n\tclen = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n#if defined(DUK_USE_STRLEN16)\n\tDUK_ASSERT(clen <= 0xffffUL);  /* Bytelength checked during interning. */\n\th->clen16 = (duk_uint16_t) clen;\n#else\n\th->clen = (duk_uint32_t) clen;\n#endif\n\tif (DUK_LIKELY(clen == DUK_HSTRING_GET_BYTELEN(h))) {\n\t\tDUK_HSTRING_SET_ASCII(h);\n\t}\n}\n\nDUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {\n#if defined(DUK_USE_STRLEN16)\n\treturn h->clen16;\n#else\n\treturn h->clen;\n#endif\n}\n#endif  /* !DUK_USE_HSTRING_LAZY_CLEN */\n\n/*\n *  duk_hstring charlen, when lazy charlen enabled\n */\n\n#if defined(DUK_USE_HSTRING_LAZY_CLEN)\n#if defined(DUK_USE_HSTRING_CLEN)\nDUK_LOCAL DUK_COLD duk_size_t duk__hstring_get_charlen_slowpath(duk_hstring *h) {\n\tduk_size_t res;\n\n\tDUK_ASSERT(h->clen == 0);  /* Checked by caller. */\n\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* ROM strings have precomputed clen, but if the computed clen is zero\n\t * we can still come here and can't write anything.\n\t */\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) {\n\t\treturn 0;\n\t}\n#endif\n\n\tres = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n#if defined(DUK_USE_STRLEN16)\n\tDUK_ASSERT(res <= 0xffffUL);  /* Bytelength checked during interning. */\n\th->clen16 = (duk_uint16_t) res;\n#else\n\th->clen = (duk_uint32_t) res;\n#endif\n\tif (DUK_LIKELY(res == DUK_HSTRING_GET_BYTELEN(h))) {\n\t\tDUK_HSTRING_SET_ASCII(h);\n\t}\n\treturn res;\n}\n#else  /* DUK_USE_HSTRING_CLEN */\nDUK_LOCAL duk_size_t duk__hstring_get_charlen_slowpath(duk_hstring *h) {\n\tif (DUK_LIKELY(DUK_HSTRING_HAS_ASCII(h))) {\n\t\t/* Most practical strings will go here. */\n\t\treturn DUK_HSTRING_GET_BYTELEN(h);\n\t} else {\n\t\t/* ASCII flag is lazy, so set it here. */\n\t\tduk_size_t res;\n\n\t\t/* XXX: here we could use the strcache to speed up the\n\t\t * computation (matters for 'i < str.length' loops).\n\t\t */\n\n\t\tres = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\n#if defined(DUK_USE_ROM_STRINGS)\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) {\n\t\t\t/* For ROM strings, can't write anything; ASCII flag\n\t\t\t * is preset so we don't need to update it.\n\t\t\t */\n\t\t\treturn res;\n\t\t}\n#endif\n\t\tif (DUK_LIKELY(res == DUK_HSTRING_GET_BYTELEN(h))) {\n\t\t\tDUK_HSTRING_SET_ASCII(h);\n\t\t}\n\t\treturn res;\n\t}\n}\n#endif  /* DUK_USE_HSTRING_CLEN */\n\n#if defined(DUK_USE_HSTRING_CLEN)\nDUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {\n#if defined(DUK_USE_STRLEN16)\n\tif (DUK_LIKELY(h->clen16 != 0)) {\n\t\treturn h->clen16;\n\t}\n#else\n\tif (DUK_LIKELY(h->clen != 0)) {\n\t\treturn h->clen;\n\t}\n#endif\n\treturn duk__hstring_get_charlen_slowpath(h);\n}\n#else  /* DUK_USE_HSTRING_CLEN */\nDUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {\n\t/* Always use slow path. */\n\treturn duk__hstring_get_charlen_slowpath(h);\n}\n#endif  /* DUK_USE_HSTRING_CLEN */\n#endif  /* DUK_USE_HSTRING_LAZY_CLEN */\n\n/*\n *  Compare duk_hstring to an ASCII cstring.\n */\n\nDUK_INTERNAL duk_bool_t duk_hstring_equals_ascii_cstring(duk_hstring *h, const char *cstr) {\n\tduk_size_t len;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(cstr != NULL);\n\n\tlen = DUK_STRLEN(cstr);\n\tif (len != DUK_HSTRING_GET_BYTELEN(h)) {\n\t\treturn 0;\n\t}\n\tif (duk_memcmp((const void *) cstr, (const void *) DUK_HSTRING_GET_DATA(h), len) == 0) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hthread.h",
    "content": "/*\n *  Heap thread object representation.\n *\n *  duk_hthread is also the 'context' for public API functions via a\n *  different typedef.  Most API calls operate on the topmost frame\n *  of the value stack only.\n */\n\n#if !defined(DUK_HTHREAD_H_INCLUDED)\n#define DUK_HTHREAD_H_INCLUDED\n\n/*\n *  Stack constants\n */\n\n/* Initial valstack size, roughly 0.7kiB. */\n#define DUK_VALSTACK_INITIAL_SIZE       96U\n\n/* Internal extra elements assumed on function entry, always added to\n * user-defined 'extra' for e.g. the duk_check_stack() call.\n */\n#define DUK_VALSTACK_INTERNAL_EXTRA     32U\n\n/* Number of elements guaranteed to be user accessible (in addition to call\n * arguments) on Duktape/C function entry.  This is the major public API\n * commitment.\n */\n#define DUK_VALSTACK_API_ENTRY_MINIMUM  DUK_API_ENTRY_STACK\n\n/*\n *  Activation defines\n */\n\n#define DUK_ACT_FLAG_STRICT             (1U << 0)  /* function executes in strict mode */\n#define DUK_ACT_FLAG_TAILCALLED         (1U << 1)  /* activation has tail called one or more times */\n#define DUK_ACT_FLAG_CONSTRUCT          (1U << 2)  /* function executes as a constructor (called via \"new\") */\n#define DUK_ACT_FLAG_PREVENT_YIELD      (1U << 3)  /* activation prevents yield (native call or \"new\") */\n#define DUK_ACT_FLAG_DIRECT_EVAL        (1U << 4)  /* activation is a direct eval call */\n#define DUK_ACT_FLAG_CONSTRUCT_PROXY    (1U << 5)  /* activation is for Proxy 'construct' call, special return value handling */\n#define DUK_ACT_FLAG_BREAKPOINT_ACTIVE  (1U << 6)  /* activation has active breakpoint(s) */\n\n#define DUK_ACT_GET_FUNC(act)           ((act)->func)\n\n/*\n *  Flags for __FILE__ / __LINE__ registered into tracedata\n */\n\n#define DUK_TB_FLAG_NOBLAME_FILELINE    (1U << 0)  /* don't report __FILE__ / __LINE__ as fileName/lineNumber */\n\n/*\n *  Catcher defines\n */\n\n/* XXX: remove catcher type entirely */\n\n/* flags field: LLLLLLFT, L = label (24 bits), F = flags (4 bits), T = type (4 bits) */\n#define DUK_CAT_TYPE_MASK            0x0000000fUL\n#define DUK_CAT_TYPE_BITS            4\n#define DUK_CAT_LABEL_MASK           0xffffff00UL\n#define DUK_CAT_LABEL_BITS           24\n#define DUK_CAT_LABEL_SHIFT          8\n\n#define DUK_CAT_FLAG_CATCH_ENABLED          (1U << 4)   /* catch part will catch */\n#define DUK_CAT_FLAG_FINALLY_ENABLED        (1U << 5)   /* finally part will catch */\n#define DUK_CAT_FLAG_CATCH_BINDING_ENABLED  (1U << 6)   /* request to create catch binding */\n#define DUK_CAT_FLAG_LEXENV_ACTIVE          (1U << 7)   /* catch or with binding is currently active */\n\n#define DUK_CAT_TYPE_UNKNOWN         0\n#define DUK_CAT_TYPE_TCF             1\n#define DUK_CAT_TYPE_LABEL           2\n\n#define DUK_CAT_GET_TYPE(c)          ((c)->flags & DUK_CAT_TYPE_MASK)\n#define DUK_CAT_GET_LABEL(c)         (((c)->flags & DUK_CAT_LABEL_MASK) >> DUK_CAT_LABEL_SHIFT)\n\n#define DUK_CAT_HAS_CATCH_ENABLED(c)           ((c)->flags & DUK_CAT_FLAG_CATCH_ENABLED)\n#define DUK_CAT_HAS_FINALLY_ENABLED(c)         ((c)->flags & DUK_CAT_FLAG_FINALLY_ENABLED)\n#define DUK_CAT_HAS_CATCH_BINDING_ENABLED(c)   ((c)->flags & DUK_CAT_FLAG_CATCH_BINDING_ENABLED)\n#define DUK_CAT_HAS_LEXENV_ACTIVE(c)           ((c)->flags & DUK_CAT_FLAG_LEXENV_ACTIVE)\n\n#define DUK_CAT_SET_CATCH_ENABLED(c)    do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_CATCH_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_SET_FINALLY_ENABLED(c)  do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_FINALLY_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_SET_CATCH_BINDING_ENABLED(c)    do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_CATCH_BINDING_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_SET_LEXENV_ACTIVE(c)    do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_LEXENV_ACTIVE; \\\n\t} while (0)\n\n#define DUK_CAT_CLEAR_CATCH_ENABLED(c)    do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_CATCH_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_CLEAR_FINALLY_ENABLED(c)  do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_FINALLY_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_CLEAR_CATCH_BINDING_ENABLED(c)    do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_CATCH_BINDING_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_CLEAR_LEXENV_ACTIVE(c)    do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_LEXENV_ACTIVE; \\\n\t} while (0)\n\n/*\n *  Thread defines\n */\n\n#if defined(DUK_USE_ROM_STRINGS)\n#define DUK_HTHREAD_GET_STRING(thr,idx) \\\n\t((duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_stridx[(idx)]))\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HTHREAD_GET_STRING(thr,idx) \\\n\t((duk_hstring *) DUK_USE_HEAPPTR_DEC16((thr)->heap->heap_udata, (thr)->strs16[(idx)]))\n#else\n#define DUK_HTHREAD_GET_STRING(thr,idx) \\\n\t((thr)->strs[(idx)])\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n/* values for the state field */\n#define DUK_HTHREAD_STATE_INACTIVE     1   /* thread not currently running */\n#define DUK_HTHREAD_STATE_RUNNING      2   /* thread currently running (only one at a time) */\n#define DUK_HTHREAD_STATE_RESUMED      3   /* thread resumed another thread (active but not running) */\n#define DUK_HTHREAD_STATE_YIELDED      4   /* thread has yielded */\n#define DUK_HTHREAD_STATE_TERMINATED   5   /* thread has terminated */\n\n/* Executor interrupt default interval when nothing else requires a\n * smaller value.  The default interval must be small enough to allow\n * for reasonable execution timeout checking but large enough to keep\n * impact on execution performance low.\n */\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n#define DUK_HTHREAD_INTCTR_DEFAULT     (256L * 1024L)\n#endif\n\n/*\n *  Assert context is valid: non-NULL pointer, fields look sane.\n *\n *  This is used by public API call entrypoints to catch invalid 'ctx' pointers\n *  as early as possible; invalid 'ctx' pointers cause very odd and difficult to\n *  diagnose behavior so it's worth checking even when the check is not 100%.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n/* Assertions for internals. */\nDUK_INTERNAL_DECL void duk_hthread_assert_valid(duk_hthread *thr);\n#define DUK_HTHREAD_ASSERT_VALID(thr)  do { duk_hthread_assert_valid((thr)); } while (0)\n\n/* Assertions for public API calls; a bit stronger. */\nDUK_INTERNAL_DECL void duk_ctx_assert_valid(duk_hthread *thr);\n#define DUK_CTX_ASSERT_VALID(thr)  do { duk_ctx_assert_valid((thr)); } while (0)\n#else\n#define DUK_HTHREAD_ASSERT_VALID(thr)  do {} while (0)\n#define DUK_CTX_ASSERT_VALID(thr)  do {} while (0)\n#endif\n\n/* Assertions for API call entry specifically.  Checks 'ctx' but also may\n * check internal state (e.g. not in a debugger transport callback).\n */\n#define DUK_ASSERT_API_ENTRY(thr) do { \\\n\t\tDUK_CTX_ASSERT_VALID((thr)); \\\n\t\tDUK_ASSERT((thr)->heap != NULL); \\\n\t\tDUK_ASSERT((thr)->heap->dbg_calling_transport == 0); \\\n\t} while (0)\n\n/*\n *  Assertion helpers.\n */\n\n#define DUK_ASSERT_STRIDX_VALID(val) \\\n\tDUK_ASSERT((duk_uint_t) (val) < DUK_HEAP_NUM_STRINGS)\n\n#define DUK_ASSERT_BIDX_VALID(val) \\\n\tDUK_ASSERT((duk_uint_t) (val) < DUK_NUM_BUILTINS)\n\n/*\n *  Misc\n */\n\n/* Fast access to 'this' binding.  Assumes there's a call in progress. */\n#define DUK_HTHREAD_THIS_PTR(thr) \\\n\t(DUK_ASSERT_EXPR((thr) != NULL), \\\n\t DUK_ASSERT_EXPR((thr)->valstack_bottom > (thr)->valstack), \\\n\t (thr)->valstack_bottom - 1)\n\n/*\n *  Struct defines\n */\n\n/* Fields are ordered for alignment/packing. */\nstruct duk_activation {\n\tduk_tval tv_func;       /* borrowed: full duk_tval for function being executed; for lightfuncs */\n\tduk_hobject *func;      /* borrowed: function being executed; for bound function calls, this is the final, real function, NULL for lightfuncs */\n\tduk_activation *parent; /* previous (parent) activation (or NULL if none) */\n\tduk_hobject *var_env;   /* current variable environment (may be NULL if delayed) */\n\tduk_hobject *lex_env;   /* current lexical environment (may be NULL if delayed) */\n\tduk_catcher *cat;       /* current catcher (or NULL) */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t/* Previous value of 'func' caller, restored when unwound.  Only in use\n\t * when 'func' is non-strict.\n\t */\n\tduk_hobject *prev_caller;\n#endif\n\n\tduk_instr_t *curr_pc;   /* next instruction to execute (points to 'func' bytecode, stable pointer), NULL for native calls */\n\n\t/* bottom_byteoff and retval_byteoff are only used for book-keeping\n\t * of ECMAScript-initiated calls, to allow returning to an ECMAScript\n\t * function properly.\n\t */\n\n\t/* Bottom of valstack for this activation, used to reset\n\t * valstack_bottom on return; offset is absolute.  There's\n\t * no need to track 'top' because native call handling deals\n\t * with that using locals, and for ECMAScript returns 'nregs'\n\t * indicates the necessary top.\n\t */\n\tduk_size_t bottom_byteoff;\n\n\t/* Return value when returning to this activation (points to caller\n\t * reg, not callee reg); offset is absolute (only set if activation is\n\t * not topmost).\n\t *\n\t * Note: bottom_byteoff is always set, while retval_byteoff is only\n\t * applicable for activations below the topmost one.  Currently\n\t * retval_byteoff for the topmost activation is considered garbage\n\t * (and it not initialized on entry or cleared on return; may contain\n\t * previous or garbage values).\n\t */\n\tduk_size_t retval_byteoff;\n\n\t/* Current 'this' binding is the value just below bottom.\n\t * Previously, 'this' binding was handled with an index to the\n\t * (calling) valstack.  This works for everything except tail\n\t * calls, which must not \"accumulate\" valstack temps.\n\t */\n\n\t/* Value stack reserve (valstack_end) byte offset to be restored\n\t * when returning to this activation.  Only used by the bytecode\n\t * executor.\n\t */\n\tduk_size_t reserve_byteoff;\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_uint32_t prev_line; /* needed for stepping */\n#endif\n\n\tduk_small_uint_t flags;\n};\n\nstruct duk_catcher {\n\tduk_catcher *parent;            /* previous (parent) catcher (or NULL if none) */\n\tduk_hstring *h_varname;         /* borrowed reference to catch variable name (or NULL if none) */\n\t                                /* (reference is valid as long activation exists) */\n\tduk_instr_t *pc_base;           /* resume execution from pc_base or pc_base+1 (points to 'func' bytecode, stable pointer) */\n\tduk_size_t idx_base;            /* idx_base and idx_base+1 get completion value and type */\n\tduk_uint32_t flags;             /* type and control flags, label number */\n\t/* XXX: could pack 'flags' and 'idx_base' to same value in practice,\n\t * on 32-bit targets this would make duk_catcher 16 bytes.\n\t */\n};\n\nstruct duk_hthread {\n\t/* Shared object part */\n\tduk_hobject obj;\n\n\t/* Pointer to bytecode executor's 'curr_pc' variable.  Used to copy\n\t * the current PC back into the topmost activation when activation\n\t * state is about to change (or \"syncing\" is otherwise needed).  This\n\t * is rather awkward but important for performance, see execution.rst.\n\t */\n\tduk_instr_t **ptr_curr_pc;\n\n\t/* Backpointers. */\n\tduk_heap *heap;\n\n\t/* Current strictness flag: affects API calls. */\n\tduk_uint8_t strict;\n\n\t/* Thread state. */\n\tduk_uint8_t state;\n\tduk_uint8_t unused1;\n\tduk_uint8_t unused2;\n\n\t/* XXX: Valstack and callstack are currently assumed to have non-NULL\n\t * pointers.  Relaxing this would not lead to big benefits (except\n\t * perhaps for terminated threads).\n\t */\n\n\t/* Value stack: these are expressed as pointers for faster stack\n\t * manipulation.  [valstack,valstack_top[ is GC-reachable,\n\t * [valstack_top,valstack_alloc_end[ is not GC-reachable but kept\n\t * initialized as 'undefined'.  [valstack,valstack_end[ is the\n\t * guaranteed/reserved space and the valstack cannot be resized to\n\t * a smaller size.  [valstack_end,valstack_alloc_end[ is currently\n\t * allocated slack that can be used to grow the current guaranteed\n\t * space but may be shrunk away without notice.\n\t *\n\t *\n\t * <----------------------- guaranteed --->\n\t *                                        <---- slack --->\n\t *               <--- frame --->\n\t * .-------------+=============+----------+--------------.\n\t * |xxxxxxxxxxxxx|yyyyyyyyyyyyy|uuuuuuuuuu|uuuuuuuuuuuuuu|\n\t * `-------------+=============+----------+--------------'\n\t *\n\t * ^             ^             ^          ^              ^\n\t * |             |             |          |              |\n\t * valstack      bottom        top        end            alloc_end\n\t *\n\t *     xxx = arbitrary values, below current frame\n\t *     yyy = arbitrary values, inside current frame\n\t *     uuu = outside active value stack, initialized to 'undefined'\n\t */\n\tduk_tval *valstack;                     /* start of valstack allocation */\n\tduk_tval *valstack_end;                 /* end of valstack reservation/guarantee (exclusive) */\n\tduk_tval *valstack_alloc_end;           /* end of valstack allocation */\n\tduk_tval *valstack_bottom;              /* bottom of current frame */\n\tduk_tval *valstack_top;                 /* top of current frame (exclusive) */\n\n\t/* Call stack, represented as a linked list starting from the current\n\t * activation (or NULL if nothing is active).\n\t */\n\tduk_activation *callstack_curr;         /* current activation (or NULL if none) */\n\tduk_size_t callstack_top;               /* number of activation records in callstack (0 if none) */\n\tduk_size_t callstack_preventcount;      /* number of activation records in callstack preventing a yield */\n\n\t/* Yield/resume book-keeping. */\n\tduk_hthread *resumer;                   /* who resumed us (if any) */\n\n\t/* Current compiler state (if any), used for augmenting SyntaxErrors. */\n\tduk_compiler_ctx *compile_ctx;\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\t/* Interrupt counter for triggering a slow path check for execution\n\t * timeout, debugger interaction such as breakpoints, etc.  The value\n\t * is valid for the current running thread, and both the init and\n\t * counter values are copied whenever a thread switch occurs.  It's\n\t * important for the counter to be conveniently accessible for the\n\t * bytecode executor inner loop for performance reasons.\n\t */\n\tduk_int_t interrupt_counter;    /* countdown state */\n\tduk_int_t interrupt_init;       /* start value for current countdown */\n#endif\n\n\t/* Builtin-objects; may or may not be shared with other threads,\n\t * threads existing in different \"compartments\" will have different\n\t * built-ins.  Must be stored on a per-thread basis because there\n\t * is no intermediate structure for a thread group / compartment.\n\t * This takes quite a lot of space, currently 43x4 = 172 bytes on\n\t * 32-bit platforms.\n\t *\n\t * In some cases the builtins array could be ROM based, but it's\n\t * sometimes edited (e.g. for sandboxing) so it's better to keep\n\t * this array in RAM.\n\t */\n\tduk_hobject *builtins[DUK_NUM_BUILTINS];\n\n\t/* Convenience copies from heap/vm for faster access. */\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* No field needed when strings are in ROM. */\n#else\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t *strs16;\n#else\n\tduk_hstring **strs;\n#endif\n#endif\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_hthread_copy_builtin_objects(duk_hthread *thr_from, duk_hthread *thr_to);\nDUK_INTERNAL_DECL void duk_hthread_create_builtin_objects(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_terminate(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_activation *duk_hthread_activation_alloc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_activation_free(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_hthread_activation_unwind_norz(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_activation_unwind_reuse_norz(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_activation *duk_hthread_get_activation_for_level(duk_hthread *thr, duk_int_t level);\n\nDUK_INTERNAL_DECL duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_catcher_free(duk_hthread *thr, duk_catcher *cat);\nDUK_INTERNAL_DECL void duk_hthread_catcher_unwind_norz(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_hthread_catcher_unwind_nolexenv_norz(duk_hthread *thr, duk_activation *act);\n\n#if defined(DUK_USE_FINALIZER_TORTURE)\nDUK_INTERNAL_DECL void duk_hthread_valstack_torture_realloc(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud);  /* indirect allocs */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_hthread_get_act_curr_pc(duk_hthread *thr, duk_activation *act);\n#endif\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_hthread_get_act_prev_pc(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_hthread_sync_currpc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_sync_and_null_currpc(duk_hthread *thr);\n\n#endif  /* DUK_HTHREAD_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hthread_alloc.c",
    "content": "/*\n *  duk_hthread allocation and freeing.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Allocate initial stacks for a thread.  Note that 'thr' must be reachable\n *  as a garbage collection may be triggered by the allocation attempts.\n *  Returns zero (without leaking memory) if init fails.\n */\n\nDUK_INTERNAL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr) {\n\tduk_size_t alloc_size;\n\tduk_size_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->valstack == NULL);\n\tDUK_ASSERT(thr->valstack_end == NULL);\n\tDUK_ASSERT(thr->valstack_alloc_end == NULL);\n\tDUK_ASSERT(thr->valstack_bottom == NULL);\n\tDUK_ASSERT(thr->valstack_top == NULL);\n\tDUK_ASSERT(thr->callstack_curr == NULL);\n\n\t/* valstack */\n\tDUK_ASSERT(DUK_VALSTACK_API_ENTRY_MINIMUM <= DUK_VALSTACK_INITIAL_SIZE);\n\talloc_size = sizeof(duk_tval) * DUK_VALSTACK_INITIAL_SIZE;\n\tthr->valstack = (duk_tval *) DUK_ALLOC(heap, alloc_size);\n\tif (!thr->valstack) {\n\t\tgoto fail;\n\t}\n\tduk_memzero(thr->valstack, alloc_size);\n\tthr->valstack_end = thr->valstack + DUK_VALSTACK_API_ENTRY_MINIMUM;\n\tthr->valstack_alloc_end = thr->valstack + DUK_VALSTACK_INITIAL_SIZE;\n\tthr->valstack_bottom = thr->valstack;\n\tthr->valstack_top = thr->valstack;\n\n\tfor (i = 0; i < DUK_VALSTACK_INITIAL_SIZE; i++) {\n\t\tDUK_TVAL_SET_UNDEFINED(&thr->valstack[i]);\n\t}\n\n\treturn 1;\n\n fail:\n\tDUK_FREE(heap, thr->valstack);\n\tDUK_ASSERT(thr->callstack_curr == NULL);\n\n\tthr->valstack = NULL;\n\treturn 0;\n}\n\n/* For indirect allocs. */\n\nDUK_INTERNAL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud) {\n\tduk_hthread *thr = (duk_hthread *) ud;\n\tDUK_UNREF(heap);\n\treturn (void *) thr->valstack;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hthread_builtins.c",
    "content": "/*\n *  Initialize built-in objects.  Current thread must have a valstack\n *  and initialization errors may longjmp, so a setjmp() catch point\n *  must exist.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Encoding constants, must match genbuiltins.py\n */\n\n#define DUK__PROP_FLAGS_BITS             3\n#define DUK__LENGTH_PROP_BITS            3\n#define DUK__NARGS_BITS                  3\n#define DUK__PROP_TYPE_BITS              3\n\n#define DUK__NARGS_VARARGS_MARKER        0x07\n\n#define DUK__PROP_TYPE_DOUBLE            0\n#define DUK__PROP_TYPE_STRING            1\n#define DUK__PROP_TYPE_STRIDX            2\n#define DUK__PROP_TYPE_BUILTIN           3\n#define DUK__PROP_TYPE_UNDEFINED         4\n#define DUK__PROP_TYPE_BOOLEAN_TRUE      5\n#define DUK__PROP_TYPE_BOOLEAN_FALSE     6\n#define DUK__PROP_TYPE_ACCESSOR          7\n\n/*\n *  Create built-in objects by parsing an init bitstream generated\n *  by genbuiltins.py.\n */\n\n#if defined(DUK_USE_ROM_OBJECTS)\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) || defined(DUK_USE_ROM_GLOBAL_INHERIT)\nDUK_LOCAL void duk__duplicate_ram_global_object(duk_hthread *thr) {\n\tduk_hobject *h_global;\n#if defined(DUK_USE_ROM_GLOBAL_CLONE)\n\tduk_hobject *h_oldglobal;\n\tduk_uint8_t *props;\n\tduk_size_t alloc_size;\n#endif\n\tduk_hobject *h_objenv;\n\n\t/* XXX: refactor into internal helper, duk_clone_hobject() */\n\n#if defined(DUK_USE_ROM_GLOBAL_INHERIT)\n\t/* Inherit from ROM-based global object: less RAM usage, less transparent. */\n\th_global = duk_push_object_helper(thr,\n\t                                  DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                  DUK_HOBJECT_FLAG_FASTREFS |\n\t                                  DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL),\n\t                                  DUK_BIDX_GLOBAL);\n\tDUK_ASSERT(h_global != NULL);\n#elif defined(DUK_USE_ROM_GLOBAL_CLONE)\n\t/* Clone the properties of the ROM-based global object to create a\n\t * fully RAM-based global object.  Uses more memory than the inherit\n\t * model but more compliant.\n\t */\n\th_global = duk_push_object_helper(thr,\n\t                                  DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                  DUK_HOBJECT_FLAG_FASTREFS |\n\t                                  DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL),\n\t                                  DUK_BIDX_OBJECT_PROTOTYPE);\n\tDUK_ASSERT(h_global != NULL);\n\th_oldglobal = thr->builtins[DUK_BIDX_GLOBAL];\n\tDUK_ASSERT(h_oldglobal != NULL);\n\n\t/* Copy the property table verbatim; this handles attributes etc.\n\t * For ROM objects it's not necessary (or possible) to update\n\t * refcounts so leave them as is.\n\t */\n\talloc_size = DUK_HOBJECT_P_ALLOC_SIZE(h_oldglobal);\n\tDUK_ASSERT(alloc_size > 0);\n\tprops = DUK_ALLOC_CHECKED(thr, alloc_size);\n\tDUK_ASSERT(props != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, h_oldglobal) != NULL);\n\tduk_memcpy((void *) props, (const void *) DUK_HOBJECT_GET_PROPS(thr->heap, h_oldglobal), alloc_size);\n\n\t/* XXX: keep property attributes or tweak them here?\n\t * Properties will now be non-configurable even when they're\n\t * normally configurable for the global object.\n\t */\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, h_global) == NULL);\n\tDUK_HOBJECT_SET_PROPS(thr->heap, h_global, props);\n\tDUK_HOBJECT_SET_ESIZE(h_global, DUK_HOBJECT_GET_ESIZE(h_oldglobal));\n\tDUK_HOBJECT_SET_ENEXT(h_global, DUK_HOBJECT_GET_ENEXT(h_oldglobal));\n\tDUK_HOBJECT_SET_ASIZE(h_global, DUK_HOBJECT_GET_ASIZE(h_oldglobal));\n\tDUK_HOBJECT_SET_HSIZE(h_global, DUK_HOBJECT_GET_HSIZE(h_oldglobal));\n#else\n#error internal error in config defines\n#endif\n\n\tduk_hobject_compact_props(thr, h_global);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE((duk_heaphdr *) thr->builtins[DUK_BIDX_GLOBAL]));  /* no need to decref: ROM object */\n\tthr->builtins[DUK_BIDX_GLOBAL] = h_global;\n\tDUK_HOBJECT_INCREF(thr, h_global);\n\tDUK_D(DUK_DPRINT(\"duplicated global object: %!O\", h_global));\n\n\t/* Create a fresh object environment for the global scope.  This is\n\t * needed so that the global scope points to the newly created RAM-based\n\t * global object.\n\t */\n\th_objenv = (duk_hobject *) duk_hobjenv_alloc(thr,\n\t                                             DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                             DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\tDUK_ASSERT(h_objenv != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_objenv) == NULL);\n\tduk_push_hobject(thr, h_objenv);\n\n\tDUK_ASSERT(h_global != NULL);\n\t((duk_hobjenv *) h_objenv)->target = h_global;\n\tDUK_HOBJECT_INCREF(thr, h_global);\n\tDUK_ASSERT(((duk_hobjenv *) h_objenv)->has_this == 0);\n\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL_ENV] != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE((duk_heaphdr *) thr->builtins[DUK_BIDX_GLOBAL_ENV]));  /* no need to decref: ROM object */\n\tthr->builtins[DUK_BIDX_GLOBAL_ENV] = h_objenv;\n\tDUK_HOBJECT_INCREF(thr, h_objenv);\n\tDUK_D(DUK_DPRINT(\"duplicated global env: %!O\", h_objenv));\n\n\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) h_objenv);\n\n\tduk_pop_2(thr);  /* Pop global object and global env. */\n}\n#endif  /* DUK_USE_ROM_GLOBAL_CLONE || DUK_USE_ROM_GLOBAL_INHERIT */\n\nDUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {\n\t/* Setup builtins from ROM objects.  All heaps/threads will share\n\t * the same readonly objects.\n\t */\n\tduk_small_uint_t i;\n\n\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\tduk_hobject *h;\n\t\th = (duk_hobject *) DUK_LOSE_CONST(duk_rom_builtins_bidx[i]);\n\t\tDUK_ASSERT(h != NULL);\n\t\tthr->builtins[i] = h;\n\t}\n\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) || defined(DUK_USE_ROM_GLOBAL_INHERIT)\n\t/* By default the global object is read-only which is often much\n\t * more of an issue than having read-only built-in objects (like\n\t * RegExp, Date, etc).  Use a RAM-based copy of the global object\n\t * and the global environment object for convenience.\n\t */\n\tduk__duplicate_ram_global_object(thr);\n#endif\n}\n#else  /* DUK_USE_ROM_OBJECTS */\nDUK_LOCAL void duk__push_stridx(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\tduk_small_uint_t n;\n\n\tn = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\tDUK_ASSERT_DISABLE(n >= 0);  /* unsigned */\n\tDUK_ASSERT(n < DUK_HEAP_NUM_STRINGS);\n\tduk_push_hstring_stridx(thr, n);\n}\nDUK_LOCAL void duk__push_string(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\t/* XXX: built-ins data could provide a maximum length that is\n\t * actually needed; bitpacked max length is now 256 bytes.\n\t */\n\tduk_uint8_t tmp[DUK_BD_BITPACKED_STRING_MAXLEN];\n\tduk_small_uint_t len;\n\n\tlen = duk_bd_decode_bitpacked_string(bd, tmp);\n\tduk_push_lstring(thr, (const char *) tmp, (duk_size_t) len);\n}\nDUK_LOCAL void duk__push_stridx_or_string(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\tduk_small_uint_t n;\n\n\tn = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\tif (n == 0) {\n\t\tduk__push_string(thr, bd);\n\t} else {\n\t\tn--;\n\t\tDUK_ASSERT(n < DUK_HEAP_NUM_STRINGS);\n\t\tduk_push_hstring_stridx(thr, n);\n\t}\n}\nDUK_LOCAL void duk__push_double(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\tduk_double_union du;\n\tduk_small_uint_t i;\n\n\tfor (i = 0; i < 8; i++) {\n\t\t/* Encoding endianness must match target memory layout,\n\t\t * build scripts and genbuiltins.py must ensure this.\n\t\t */\n\t\tdu.uc[i] = (duk_uint8_t) duk_bd_decode(bd, 8);\n\t}\n\n\tduk_push_number(thr, du.d);  /* push operation normalizes NaNs */\n}\n\nDUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {\n\tduk_bitdecoder_ctx bd_ctx;\n\tduk_bitdecoder_ctx *bd = &bd_ctx;  /* convenience */\n\tduk_hobject *h;\n\tduk_small_uint_t i, j;\n\n\tDUK_D(DUK_DPRINT(\"INITBUILTINS BEGIN: DUK_NUM_BUILTINS=%d, DUK_NUM_BUILTINS_ALL=%d\", (int) DUK_NUM_BUILTINS, (int) DUK_NUM_ALL_BUILTINS));\n\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tbd->data = (const duk_uint8_t *) duk_builtins_data;\n\tbd->length = (duk_size_t) DUK_BUILTINS_DATA_LENGTH;\n\n\t/*\n\t *  First create all built-in bare objects on the empty valstack.\n\t *\n\t *  Built-ins in the index range [0,DUK_NUM_BUILTINS-1] have value\n\t *  stack indices matching their eventual thr->builtins[] index.\n\t *\n\t *  Built-ins in the index range [DUK_NUM_BUILTINS,DUK_NUM_ALL_BUILTINS]\n\t *  will exist on the value stack during init but won't be placed\n\t *  into thr->builtins[].  These are objects referenced in some way\n\t *  from thr->builtins[] roots but which don't need to be indexed by\n\t *  Duktape through thr->builtins[] (e.g. user custom objects).\n\t *\n\t *  Internal prototypes will be incorrect (NULL) at this stage.\n\t */\n\n\tduk_require_stack(thr, DUK_NUM_ALL_BUILTINS);\n\n\tDUK_DD(DUK_DDPRINT(\"create empty built-ins\"));\n\tDUK_ASSERT_TOP(thr, 0);\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tduk_small_uint_t class_num;\n\t\tduk_small_int_t len = -1;  /* must be signed */\n\n\t\tclass_num = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tlen = (duk_small_int_t) duk_bd_decode_flagged_signed(bd, DUK__LENGTH_PROP_BITS, (duk_int32_t) -1 /*def_value*/);\n\n\t\tif (class_num == DUK_HOBJECT_CLASS_FUNCTION) {\n\t\t\tduk_small_uint_t natidx;\n\t\t\tduk_small_int_t c_nargs;  /* must hold DUK_VARARGS */\n\t\t\tduk_c_function c_func;\n\t\t\tduk_int16_t magic;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"len=%ld\", (long) len));\n\t\t\tDUK_ASSERT(len >= 0);\n\n\t\t\tnatidx = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\tDUK_ASSERT(natidx != 0);\n\t\t\tc_func = duk_bi_native_functions[natidx];\n\t\t\tDUK_ASSERT(c_func != NULL);\n\n\t\t\tc_nargs = (duk_small_int_t) duk_bd_decode_flagged_signed(bd, DUK__NARGS_BITS, len /*def_value*/);\n\t\t\tif (c_nargs == DUK__NARGS_VARARGS_MARKER) {\n\t\t\t\tc_nargs = DUK_VARARGS;\n\t\t\t}\n\n\t\t\t/* XXX: set magic directly here? (it could share the c_nargs arg) */\n\t\t\t(void) duk_push_c_function_builtin(thr, c_func, c_nargs);\n\t\t\th = duk_known_hobject(thr, -1);\n\n\t\t\t/* Currently all built-in native functions are strict.\n\t\t\t * duk_push_c_function() now sets strict flag, so\n\t\t\t * assert for it.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_STRICT(h));\n\n\t\t\t/* XXX: function properties */\n\n\t\t\tduk__push_stridx_or_string(thr, bd);\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\t\t\tduk_xdef_prop_stridx_short(thr,\n\t\t\t                           -2,\n\t\t\t                           DUK_STRIDX_NAME,\n\t\t\t                           DUK_PROPDESC_FLAGS_C);\n#else\n\t\t\tduk_pop(thr);  /* Not very ideal but good enough for now. */\n#endif\n\n\t\t\t/* Almost all global level Function objects are constructable\n\t\t\t * but not all: Function.prototype is a non-constructable,\n\t\t\t * callable Function.\n\t\t\t */\n\t\t\tif (duk_bd_decode_flag(bd)) {\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_CONSTRUCTABLE(h));\n\t\t\t} else {\n\t\t\t\tDUK_HOBJECT_CLEAR_CONSTRUCTABLE(h);\n\t\t\t}\n\n\t\t\t/* Cast converts magic to 16-bit signed value */\n\t\t\tmagic = (duk_int16_t) duk_bd_decode_varuint(bd);\n\t\t\t((duk_hnatfunc *) h)->magic = magic;\n\t\t} else if (class_num == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tduk_push_array(thr);\n\t\t} else if (class_num == DUK_HOBJECT_CLASS_OBJENV) {\n\t\t\tduk_hobjenv *env;\n\t\t\tduk_hobject *global;\n\n\t\t\tDUK_ASSERT(i == DUK_BIDX_GLOBAL_ENV);\n\t\t\tDUK_ASSERT(DUK_BIDX_GLOBAL_ENV > DUK_BIDX_GLOBAL);\n\n\t\t\tenv = duk_hobjenv_alloc(thr,\n\t                                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\t\t\tDUK_ASSERT(env->target == NULL);\n\t\t\tduk_push_hobject(thr, (duk_hobject *) env);\n\n\t\t\tglobal = duk_known_hobject(thr, DUK_BIDX_GLOBAL);\n\t\t\tDUK_ASSERT(global != NULL);\n\t\t\tenv->target = global;\n\t\t\tDUK_HOBJECT_INCREF(thr, global);\n\t\t\tDUK_ASSERT(env->has_this == 0);\n\n\t\t\tDUK_HOBJENV_ASSERT_VALID(env);\n\t\t} else {\n\t\t\tDUK_ASSERT(class_num != DUK_HOBJECT_CLASS_DECENV);\n\n\t\t\t(void) duk_push_object_helper(thr,\n\t\t\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t\t\t                              DUK_HOBJECT_FLAG_EXTENSIBLE,\n\t\t\t                              -1);  /* no prototype or class yet */\n\n\t\t}\n\n\t\th = duk_known_hobject(thr, -1);\n\t\tDUK_HOBJECT_SET_CLASS_NUMBER(h, class_num);\n\n\t\tif (i < DUK_NUM_BUILTINS) {\n\t\t\tthr->builtins[i] = h;\n\t\t\tDUK_HOBJECT_INCREF(thr, &h->hdr);\n\t\t}\n\n\t\tif (len >= 0) {\n\t\t\t/* In ES2015+ built-in function object .length property\n\t\t\t * has property attributes C (configurable only):\n\t\t\t * http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-standard-built-in-objects\n\t\t\t *\n\t\t\t * Array.prototype remains an Array instance in ES2015+\n\t\t\t * and its length has attributes W (writable only).\n\t\t\t * Because .length is now virtual for duk_harray, it is\n\t\t\t * not encoded explicitly in init data.\n\t\t\t */\n\n\t\t\tDUK_ASSERT(class_num != DUK_HOBJECT_CLASS_ARRAY);  /* .length is virtual */\n\t\t\tduk_push_int(thr, len);\n\t\t\tduk_xdef_prop_stridx_short(thr,\n\t\t\t                           -2,\n\t\t\t                           DUK_STRIDX_LENGTH,\n\t\t\t                           DUK_PROPDESC_FLAGS_C);\n\t\t}\n\n\t\t/* enable exotic behaviors last */\n\n\t\tif (class_num == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(h));  /* set by duk_push_array() */\n\t\t}\n\t\tif (class_num == DUK_HOBJECT_CLASS_STRING) {\n\t\t\tDUK_HOBJECT_SET_EXOTIC_STRINGOBJ(h);\n\t\t}\n\n\t\t/* some assertions */\n\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h));\n\t\t/* DUK_HOBJECT_FLAG_CONSTRUCTABLE varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_COMPFUNC(h));\n\t\t/* DUK_HOBJECT_FLAG_NATFUNC varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_IS_PROXY(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(h) || class_num == DUK_HOBJECT_CLASS_ARRAY);\n\t\t/* DUK_HOBJECT_FLAG_STRICT varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(h) ||  /* all native functions have NEWENV */\n\t\t           DUK_HOBJECT_HAS_NEWENV(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NAMEBINDING(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(h));\n\t\t/* DUK_HOBJECT_FLAG_EXOTIC_ARRAY varies */\n\t\t/* DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"created built-in %ld, class=%ld, length=%ld\", (long) i, (long) class_num, (long) len));\n\t}\n\n\t/*\n\t *  Then decode the builtins init data (see genbuiltins.py) to\n\t *  init objects.  Internal prototypes are set at this stage,\n\t *  with thr->builtins[] populated.\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"initialize built-in object properties\"));\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tduk_small_uint_t t;\n\t\tduk_small_uint_t num;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"initializing built-in object at index %ld\", (long) i));\n\t\th = duk_known_hobject(thr, (duk_idx_t) i);\n\n\t\tt = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tif (t > 0) {\n\t\t\tt--;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"set internal prototype: built-in %ld\", (long) t));\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, duk_known_hobject(thr, (duk_idx_t) t));\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\t\t/* Standard native built-ins cannot inherit from\n\t\t\t * %NativeFunctionPrototype%, they are required to\n\t\t\t * inherit from Function.prototype directly.\n\t\t\t */\n\t\t\tDUK_ASSERT(thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE] != NULL);\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\t\t}\n\n\t\tt = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tif (t > 0) {\n\t\t\t/* 'prototype' property for all built-in objects (which have it) has attributes:\n\t\t\t *  [[Writable]] = false,\n\t\t\t *  [[Enumerable]] = false,\n\t\t\t *  [[Configurable]] = false\n\t\t\t */\n\t\t\tt--;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"set external prototype: built-in %ld\", (long) t));\n\t\t\tduk_dup(thr, (duk_idx_t) t);\n\t\t\tduk_xdef_prop_stridx(thr, (duk_idx_t) i, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_NONE);\n\t\t}\n\n\t\tt = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tif (t > 0) {\n\t\t\t/* 'constructor' property for all built-in objects (which have it) has attributes:\n\t\t\t *  [[Writable]] = true,\n\t\t\t *  [[Enumerable]] = false,\n\t\t\t *  [[Configurable]] = true\n\t\t\t */\n\t\t\tt--;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"set external constructor: built-in %ld\", (long) t));\n\t\t\tduk_dup(thr, (duk_idx_t) t);\n\t\t\tduk_xdef_prop_stridx(thr, (duk_idx_t) i, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC);\n\t\t}\n\n\t\t/* normal valued properties */\n\t\tnum = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tDUK_DDD(DUK_DDDPRINT(\"built-in object %ld, %ld normal valued properties\", (long) i, (long) num));\n\t\tfor (j = 0; j < num; j++) {\n\t\t\tduk_small_uint_t defprop_flags;\n\n\t\t\tduk__push_stridx_or_string(thr, bd);\n\n\t\t\t/*\n\t\t\t *  Property attribute defaults are defined in E5 Section 15 (first\n\t\t\t *  few pages); there is a default for all properties and a special\n\t\t\t *  default for 'length' properties.  Variation from the defaults is\n\t\t\t *  signaled using a single flag bit in the bitstream.\n\t\t\t */\n\n\t\t\tdefprop_flags = (duk_small_uint_t) duk_bd_decode_flagged(bd,\n\t\t\t                                                         DUK__PROP_FLAGS_BITS,\n\t\t\t                                                         (duk_uint32_t) DUK_PROPDESC_FLAGS_WC);\n\t\t\tdefprop_flags |= DUK_DEFPROP_FORCE |\n\t\t\t                 DUK_DEFPROP_HAVE_VALUE |\n\t\t\t                 DUK_DEFPROP_HAVE_WRITABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_ENUMERABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_CONFIGURABLE;  /* Defaults for data properties. */\n\n\t\t\t/* The writable, enumerable, configurable flags in prop_flags\n\t\t\t * match both duk_def_prop() and internal property flags.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_WRITABLE == DUK_DEFPROP_WRITABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_ENUMERABLE == DUK_DEFPROP_ENUMERABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_CONFIGURABLE == DUK_DEFPROP_CONFIGURABLE);\n\n\t\t\tt = (duk_small_uint_t) duk_bd_decode(bd, DUK__PROP_TYPE_BITS);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"built-in %ld, normal-valued property %ld, key %!T, flags 0x%02lx, type %ld\",\n\t\t\t                     (long) i, (long) j, duk_get_tval(thr, -1), (unsigned long) defprop_flags, (long) t));\n\n\t\t\tswitch (t) {\n\t\t\tcase DUK__PROP_TYPE_DOUBLE: {\n\t\t\t\tduk__push_double(thr, bd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_STRING: {\n\t\t\t\tduk__push_string(thr, bd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_STRIDX: {\n\t\t\t\tduk__push_stridx(thr, bd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_BUILTIN: {\n\t\t\t\tduk_small_uint_t bidx;\n\n\t\t\t\tbidx = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_dup(thr, (duk_idx_t) bidx);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_UNDEFINED: {\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_BOOLEAN_TRUE: {\n\t\t\t\tduk_push_true(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_BOOLEAN_FALSE: {\n\t\t\t\tduk_push_false(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_ACCESSOR: {\n\t\t\t\tduk_small_uint_t natidx_getter = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_small_uint_t natidx_setter = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_small_uint_t accessor_magic = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_c_function c_func_getter;\n\t\t\t\tduk_c_function c_func_setter;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"built-in accessor property: objidx=%ld, key=%!T, getteridx=%ld, setteridx=%ld, flags=0x%04lx\",\n\t\t\t\t                     (long) i, duk_get_tval(thr, -1), (long) natidx_getter, (long) natidx_setter, (unsigned long) defprop_flags));\n\n\t\t\t\tc_func_getter = duk_bi_native_functions[natidx_getter];\n\t\t\t\tif (c_func_getter != NULL) {\n\t\t\t\t\tduk_push_c_function_builtin_noconstruct(thr, c_func_getter, 0);  /* always 0 args */\n\t\t\t\t\tduk_set_magic(thr, -1, (duk_int_t) accessor_magic);\n\t\t\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_GETTER;\n\t\t\t\t}\n\t\t\t\tc_func_setter = duk_bi_native_functions[natidx_setter];\n\t\t\t\tif (c_func_setter != NULL) {\n\t\t\t\t\tduk_push_c_function_builtin_noconstruct(thr, c_func_setter, 1);  /* always 1 arg */\n\t\t\t\t\tduk_set_magic(thr, -1, (duk_int_t) accessor_magic);\n\t\t\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_SETTER;\n\t\t\t\t}\n\n\t\t\t\t/* Writable flag doesn't make sense for an accessor. */\n\t\t\t\tDUK_ASSERT((defprop_flags & DUK_PROPDESC_FLAG_WRITABLE) == 0);  /* genbuiltins.py ensures */\n\n\t\t\t\tdefprop_flags &= ~(DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE);\n\t\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t/* exhaustive */\n\t\t\t\tDUK_UNREACHABLE();\n\t\t\t}\n\t\t\t}\n\n\t\t\tduk_def_prop(thr, (duk_idx_t) i, defprop_flags);\n\t\t\tDUK_ASSERT_TOP(thr, DUK_NUM_ALL_BUILTINS);\n\t\t}\n\n\t\t/* native function properties */\n\t\tnum = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tDUK_DDD(DUK_DDDPRINT(\"built-in object %ld, %ld function valued properties\", (long) i, (long) num));\n\t\tfor (j = 0; j < num; j++) {\n\t\t\tduk_hstring *h_key;\n\t\t\tduk_small_uint_t natidx;\n\t\t\tduk_int_t c_nargs;  /* must hold DUK_VARARGS */\n\t\t\tduk_small_uint_t c_length;\n\t\t\tduk_int16_t magic;\n\t\t\tduk_c_function c_func;\n\t\t\tduk_hnatfunc *h_func;\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t\tduk_small_int_t lightfunc_eligible;\n#endif\n\t\t\tduk_small_uint_t defprop_flags;\n\n\t\t\tduk__push_stridx_or_string(thr, bd);\n\t\t\th_key = duk_known_hstring(thr, -1);\n\t\t\tDUK_UNREF(h_key);\n\t\t\tnatidx = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\n\t\t\tc_length = (duk_small_uint_t) duk_bd_decode(bd, DUK__LENGTH_PROP_BITS);\n\t\t\tc_nargs = (duk_int_t) duk_bd_decode_flagged(bd, DUK__NARGS_BITS, (duk_uint32_t) c_length /*def_value*/);\n\t\t\tif (c_nargs == DUK__NARGS_VARARGS_MARKER) {\n\t\t\t\tc_nargs = DUK_VARARGS;\n\t\t\t}\n\n\t\t\tc_func = duk_bi_native_functions[natidx];\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"built-in %ld, function-valued property %ld, key %!O, natidx %ld, length %ld, nargs %ld\",\n\t\t\t                     (long) i, (long) j, (duk_heaphdr *) h_key, (long) natidx, (long) c_length,\n\t\t\t                     (c_nargs == DUK_VARARGS ? (long) -1 : (long) c_nargs)));\n\n\t\t\t/* Cast converts magic to 16-bit signed value */\n\t\t\tmagic = (duk_int16_t) duk_bd_decode_varuint(bd);\n\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t\tlightfunc_eligible =\n\t\t\t\t((c_nargs >= DUK_LFUNC_NARGS_MIN && c_nargs <= DUK_LFUNC_NARGS_MAX) || (c_nargs == DUK_VARARGS)) &&\n\t\t\t\t(c_length <= DUK_LFUNC_LENGTH_MAX) &&\n\t\t\t\t(magic >= DUK_LFUNC_MAGIC_MIN && magic <= DUK_LFUNC_MAGIC_MAX);\n\n\t\t\t/* These functions have trouble working as lightfuncs.\n\t\t\t * Some of them have specific asserts and some may have\n\t\t         * additional properties (e.g. 'require.id' may be written).\n\t\t\t */\n\t\t\tif (c_func == duk_bi_global_object_eval) {\n\t\t\t\tlightfunc_eligible = 0;\n\t\t\t}\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\t\t\tif (c_func == duk_bi_thread_yield ||\n\t\t\t    c_func == duk_bi_thread_resume) {\n\t\t\t\tlightfunc_eligible = 0;\n\t\t\t}\n#endif\n\t\t\tif (c_func == duk_bi_function_prototype_call ||\n\t\t\t    c_func == duk_bi_function_prototype_apply ||\n\t\t\t    c_func == duk_bi_reflect_apply ||\n\t\t\t    c_func == duk_bi_reflect_construct) {\n\t\t\t\tlightfunc_eligible = 0;\n\t\t\t}\n\n\t\t\tif (lightfunc_eligible) {\n\t\t\t\tduk_tval tv_lfunc;\n\t\t\t\tduk_small_uint_t lf_nargs = (duk_small_uint_t) (c_nargs == DUK_VARARGS ? DUK_LFUNC_NARGS_VARARGS : c_nargs);\n\t\t\t\tduk_small_uint_t lf_flags = DUK_LFUNC_FLAGS_PACK(magic, c_length, lf_nargs);\n\t\t\t\tDUK_TVAL_SET_LIGHTFUNC(&tv_lfunc, c_func, lf_flags);\n\t\t\t\tduk_push_tval(thr, &tv_lfunc);\n\t\t\t\tDUK_D(DUK_DPRINT(\"built-in function eligible as light function: i=%d, j=%d c_length=%ld, c_nargs=%ld, magic=%ld -> %!iT\", (int) i, (int) j, (long) c_length, (long) c_nargs, (long) magic, duk_get_tval(thr, -1)));\n\t\t\t\tgoto lightfunc_skip;\n\t\t\t}\n\n\t\t\tDUK_D(DUK_DPRINT(\"built-in function NOT ELIGIBLE as light function: i=%d, j=%d c_length=%ld, c_nargs=%ld, magic=%ld\", (int) i, (int) j, (long) c_length, (long) c_nargs, (long) magic));\n#endif  /* DUK_USE_LIGHTFUNC_BUILTINS */\n\n\t\t\t/* [ (builtin objects) name ] */\n\n\t\t\tduk_push_c_function_builtin_noconstruct(thr, c_func, c_nargs);\n\t\t\th_func = duk_known_hnatfunc(thr, -1);\n\t\t\tDUK_UNREF(h_func);\n\n\t\t\t/* XXX: add into init data? */\n\n\t\t\t/* Special call handling, not described in init data. */\n\t\t\tif (c_func == duk_bi_global_object_eval ||\n\t\t\t    c_func == duk_bi_function_prototype_call ||\n\t\t\t    c_func == duk_bi_function_prototype_apply ||\n\t\t\t    c_func == duk_bi_reflect_apply ||\n\t\t\t    c_func == duk_bi_reflect_construct) {\n\t\t\t\tDUK_HOBJECT_SET_SPECIAL_CALL((duk_hobject *) h_func);\n\t\t\t}\n\n\t\t\t/* Currently all built-in native functions are strict.\n\t\t\t * This doesn't matter for many functions, but e.g.\n\t\t\t * String.prototype.charAt (and other string functions)\n\t\t\t * rely on being strict so that their 'this' binding is\n\t\t\t * not automatically coerced.\n\t\t\t */\n\t\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_func);\n\n\t\t\t/* No built-in functions are constructable except the top\n\t\t\t * level ones (Number, etc).\n\t\t\t */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) h_func));\n\n\t\t\t/* XXX: any way to avoid decoding magic bit; there are quite\n\t\t\t * many function properties and relatively few with magic values.\n\t\t\t */\n\t\t\th_func->magic = magic;\n\n\t\t\t/* [ (builtin objects) name func ] */\n\n\t\t\tduk_push_uint(thr, c_length);\n\t\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);\n\n\t\t\tduk_dup_m2(thr);\n\t\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n\n\t\t\t/* XXX: other properties of function instances; 'arguments', 'caller'. */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"built-in object %ld, function property %ld -> %!T\",\n\t\t\t                   (long) i, (long) j, (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t/* [ (builtin objects) name func ] */\n\n\t\t\t/*\n\t\t\t *  The default property attributes are correct for all\n\t\t\t *  function valued properties of built-in objects now.\n\t\t\t */\n\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t lightfunc_skip:\n#endif\n\n\t\t\tdefprop_flags = (duk_small_uint_t) duk_bd_decode_flagged(bd,\n\t\t\t                                                         DUK__PROP_FLAGS_BITS,\n\t\t\t                                                         (duk_uint32_t) DUK_PROPDESC_FLAGS_WC);\n\t\t\tdefprop_flags |= DUK_DEFPROP_FORCE |\n\t\t\t                 DUK_DEFPROP_HAVE_VALUE |\n\t\t\t                 DUK_DEFPROP_HAVE_WRITABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_ENUMERABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_CONFIGURABLE;\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_WRITABLE == DUK_DEFPROP_WRITABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_ENUMERABLE == DUK_DEFPROP_ENUMERABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_CONFIGURABLE == DUK_DEFPROP_CONFIGURABLE);\n\n\t\t\tduk_def_prop(thr, (duk_idx_t) i, defprop_flags);\n\n\t\t\t/* [ (builtin objects) ] */\n\t\t}\n\t}\n\n\t/*\n\t *  Special post-tweaks, for cases not covered by the init data format.\n\t *\n\t *  - Set Date.prototype.toGMTString to Date.prototype.toUTCString.\n\t *    toGMTString is required to have the same Function object as\n\t *    toUTCString in E5 Section B.2.6.  Note that while Smjs respects\n\t *    this, V8 does not (the Function objects are distinct).\n\t *\n\t *  - Make DoubleError non-extensible.\n\t *\n\t *  - Add info about most important effective compile options to Duktape.\n\t *\n\t *  - Possibly remove some properties (values or methods) which are not\n\t *    desirable with current feature options but are not currently\n\t *    conditional in init data.\n\t */\n\n#if defined(DUK_USE_DATE_BUILTIN)\n\tduk_get_prop_stridx_short(thr, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_UTC_STRING);\n\tduk_xdef_prop_stridx_short(thr, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_GMT_STRING, DUK_PROPDESC_FLAGS_WC);\n#endif\n\n\th = duk_known_hobject(thr, DUK_BIDX_DOUBLE_ERROR);\n\tDUK_HOBJECT_CLEAR_EXTENSIBLE(h);\n\n#if !defined(DUK_USE_ES6_OBJECT_PROTO_PROPERTY)\n\tDUK_DD(DUK_DDPRINT(\"delete Object.prototype.__proto__ built-in which is not enabled in features\"));\n\t(void) duk_hobject_delprop_raw(thr, thr->builtins[DUK_BIDX_OBJECT_PROTOTYPE], DUK_HTHREAD_STRING___PROTO__(thr), DUK_DELPROP_FLAG_THROW);\n#endif\n\n#if !defined(DUK_USE_ES6_OBJECT_SETPROTOTYPEOF)\n\tDUK_DD(DUK_DDPRINT(\"delete Object.setPrototypeOf built-in which is not enabled in features\"));\n\t(void) duk_hobject_delprop_raw(thr, thr->builtins[DUK_BIDX_OBJECT_CONSTRUCTOR], DUK_HTHREAD_STRING_SET_PROTOTYPE_OF(thr), DUK_DELPROP_FLAG_THROW);\n#endif\n\n\t/* XXX: relocate */\n\tduk_push_string(thr,\n\t\t\t/* Endianness indicator */\n#if defined(DUK_USE_INTEGER_LE)\n\t                \"l\"\n#elif defined(DUK_USE_INTEGER_BE)\n\t                \"b\"\n#elif defined(DUK_USE_INTEGER_ME)  /* integer mixed endian not really used now */\n\t                \"m\"\n#else\n\t                \"?\"\n#endif\n#if defined(DUK_USE_DOUBLE_LE)\n\t                \"l\"\n#elif defined(DUK_USE_DOUBLE_BE)\n\t                \"b\"\n#elif defined(DUK_USE_DOUBLE_ME)\n\t                \"m\"\n#else\n\t                \"?\"\n#endif\n\t                \" \"\n\t\t\t/* Packed or unpacked tval */\n#if defined(DUK_USE_PACKED_TVAL)\n\t                \"p\"\n#else\n\t                \"u\"\n#endif\n#if defined(DUK_USE_FASTINT)\n\t\t\t\"f\"\n#endif\n\t\t\t\" \"\n\t\t\t/* Low memory/performance options */\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\t\t\"s\"\n#endif\n#if !defined(DUK_USE_HEAPPTR16) && !defined(DUK_DATAPTR16) && !defined(DUK_FUNCPTR16)\n\t\t\t\"n\"\n#endif\n#if defined(DUK_USE_HEAPPTR16)\n\t\t\t\"h\"\n#endif\n#if defined(DUK_USE_DATAPTR16)\n\t\t\t\"d\"\n#endif\n#if defined(DUK_USE_FUNCPTR16)\n\t\t\t\"f\"\n#endif\n#if defined(DUK_USE_REFCOUNT16)\n\t\t\t\"R\"\n#endif\n#if defined(DUK_USE_STRHASH16)\n\t\t\t\"H\"\n#endif\n#if defined(DUK_USE_STRLEN16)\n\t\t\t\"S\"\n#endif\n#if defined(DUK_USE_BUFLEN16)\n\t\t\t\"B\"\n#endif\n#if defined(DUK_USE_OBJSIZES16)\n\t\t\t\"O\"\n#endif\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t\t\"L\"\n#endif\n#if defined(DUK_USE_ROM_STRINGS) || defined(DUK_USE_ROM_OBJECTS)\n\t\t\t/* XXX: This won't be shown in practice now\n\t\t\t * because this code is not run when builtins\n\t\t\t * are in ROM.\n\t\t\t */\n\t\t\t\"Z\"\n#endif\n#if defined(DUK_USE_LITCACHE_SIZE)\n\t\t\t\"l\"\n#endif\n\t                \" \"\n\t\t\t/* Object property allocation layout */\n#if defined(DUK_USE_HOBJECT_LAYOUT_1)\n\t\t\t\"p1\"\n#elif defined(DUK_USE_HOBJECT_LAYOUT_2)\n\t\t\t\"p2\"\n#elif defined(DUK_USE_HOBJECT_LAYOUT_3)\n\t\t\t\"p3\"\n#else\n\t\t\t\"p?\"\n#endif\n\t\t\t\" \"\n\t\t\t/* Alignment guarantee */\n#if (DUK_USE_ALIGN_BY == 4)\n\t\t\t\"a4\"\n#elif (DUK_USE_ALIGN_BY == 8)\n\t\t\t\"a8\"\n#elif (DUK_USE_ALIGN_BY == 1)\n\t\t\t\"a1\"\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\t\t\t\" \"\n\t\t\t/* Architecture, OS, and compiler strings */\n\t                DUK_USE_ARCH_STRING\n\t\t\t\" \"\n\t                DUK_USE_OS_STRING\n\t\t\t\" \"\n\t                DUK_USE_COMPILER_STRING);\n\tduk_xdef_prop_stridx_short(thr, DUK_BIDX_DUKTAPE, DUK_STRIDX_ENV, DUK_PROPDESC_FLAGS_WC);\n\n\t/*\n\t *  Since built-ins are not often extended, compact them.\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"compact built-ins\"));\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tduk_hobject_compact_props(thr, duk_known_hobject(thr, (duk_idx_t) i));\n\t}\n\n\tDUK_D(DUK_DPRINT(\"INITBUILTINS END\"));\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tDUK_DD(DUK_DDPRINT(\"built-in object %ld after initialization and compacting: %!@iO\",\n\t\t                   (long) i, (duk_heaphdr *) duk_require_hobject(thr, (duk_idx_t) i)));\n\t}\n#endif\n\n\t/*\n\t *  Pop built-ins from stack: they are now INCREF'd and\n\t *  reachable from the builtins[] array or indirectly\n\t *  through builtins[].\n\t */\n\n\tduk_set_top(thr, 0);\n\tDUK_ASSERT_TOP(thr, 0);\n}\n#endif  /* DUK_USE_ROM_OBJECTS */\n\nDUK_INTERNAL void duk_hthread_copy_builtin_objects(duk_hthread *thr_from, duk_hthread *thr_to) {\n\tduk_small_uint_t i;\n\n\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\tthr_to->builtins[i] = thr_from->builtins[i];\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr_to, thr_to->builtins[i]);  /* side effect free */\n\t}\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hthread_misc.c",
    "content": "/*\n *  Thread support.\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL void duk_hthread_terminate(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\twhile (thr->callstack_curr != NULL) {\n\t\tduk_hthread_activation_unwind_norz(thr);\n\t}\n\n\tthr->valstack_bottom = thr->valstack;\n\tduk_set_top(thr, 0);  /* unwinds valstack, updating refcounts */\n\n\tthr->state = DUK_HTHREAD_STATE_TERMINATED;\n\n\t/* Here we could remove references to built-ins, but it may not be\n\t * worth the effort because built-ins are quite likely to be shared\n\t * with another (unterminated) thread, and terminated threads are also\n\t * usually garbage collected quite quickly.\n\t *\n\t * We could also shrink the value stack here, but that also may not\n\t * be worth the effort for the same reason.\n\t */\n\n\tDUK_REFZERO_CHECK_SLOW(thr);\n}\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_curr_pc(duk_hthread *thr, duk_activation *act) {\n\tduk_instr_t *bcode;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_UNREF(thr);\n\n\t/* XXX: store 'bcode' pointer to activation for faster lookup? */\n\tif (act->func && DUK_HOBJECT_IS_COMPFUNC(act->func)) {\n\t\tbcode = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) (act->func));\n\t\treturn (duk_uint_fast32_t) (act->curr_pc - bcode);\n\t}\n\treturn 0;\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\nDUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_prev_pc(duk_hthread *thr, duk_activation *act) {\n\tduk_instr_t *bcode;\n\tduk_uint_fast32_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_UNREF(thr);\n\n\tif (act->func && DUK_HOBJECT_IS_COMPFUNC(act->func)) {\n\t\tbcode = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) (act->func));\n\t\tret = (duk_uint_fast32_t) (act->curr_pc - bcode);\n\t\tif (ret > 0) {\n\t\t\tret--;\n\t\t}\n\t\treturn ret;\n\t}\n\treturn 0;\n}\n\n/* Write bytecode executor's curr_pc back to topmost activation (if any). */\nDUK_INTERNAL void duk_hthread_sync_currpc(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tif (thr->ptr_curr_pc != NULL) {\n\t\t/* ptr_curr_pc != NULL only when bytecode executor is active. */\n\t\tDUK_ASSERT(thr->callstack_top > 0);\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tact = thr->callstack_curr;\n\t\tDUK_ASSERT(act != NULL);\n\t\tact->curr_pc = *thr->ptr_curr_pc;\n\t}\n}\n\nDUK_INTERNAL void duk_hthread_sync_and_null_currpc(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tif (thr->ptr_curr_pc != NULL) {\n\t\t/* ptr_curr_pc != NULL only when bytecode executor is active. */\n\t\tDUK_ASSERT(thr->callstack_top > 0);\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tact = thr->callstack_curr;\n\t\tDUK_ASSERT(act != NULL);\n\t\tact->curr_pc = *thr->ptr_curr_pc;\n\t\tthr->ptr_curr_pc = NULL;\n\t}\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_hthread_stacks.c",
    "content": "/*\n *  Thread stack (mainly call stack) primitives: allocation of activations,\n *  unwinding catchers and activations, etc.\n *\n *  Value stack handling is a part of the API implementation.\n */\n\n#include \"duk_internal.h\"\n\n/* Unwind the topmost catcher of the current activation (caller must check that\n * both exist) without side effects.\n */\nDUK_INTERNAL void duk_hthread_catcher_unwind_norz(duk_hthread *thr, duk_activation *act) {\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(act->cat != NULL);  /* caller must check */\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"unwinding catch stack entry %p (lexenv check is done)\", (void *) cat));\n\n\tif (DUK_CAT_HAS_LEXENV_ACTIVE(cat)) {\n\t\tduk_hobject *env;\n\n\t\tenv = act->lex_env;             /* current lex_env of the activation (created for catcher) */\n\t\tDUK_ASSERT(env != NULL);        /* must be, since env was created when catcher was created */\n\t\tact->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, env);  /* prototype is lex_env before catcher created */\n\t\tDUK_HOBJECT_INCREF(thr, act->lex_env);\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, env);\n\n\t\t/* There is no need to decref anything else than 'env': if 'env'\n\t\t * becomes unreachable, refzero will handle decref'ing its prototype.\n\t\t */\n\t}\n\n\tact->cat = cat->parent;\n\tduk_hthread_catcher_free(thr, cat);\n}\n\n/* Same as above, but caller is certain no catcher-related lexenv may exist. */\nDUK_INTERNAL void duk_hthread_catcher_unwind_nolexenv_norz(duk_hthread *thr, duk_activation *act) {\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(act->cat != NULL);  /* caller must check */\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"unwinding catch stack entry %p (lexenv check is not done)\", (void *) cat));\n\n\tDUK_ASSERT(!DUK_CAT_HAS_LEXENV_ACTIVE(cat));\n\n\tact->cat = cat->parent;\n\tduk_hthread_catcher_free(thr, cat);\n}\n\nDUK_LOCAL\n#if defined(DUK_USE_CACHE_CATCHER)\nDUK_NOINLINE\n#endif\nduk_catcher *duk__hthread_catcher_alloc_slow(duk_hthread *thr) {\n\tduk_catcher *cat;\n\n\tcat = (duk_catcher *) DUK_ALLOC_CHECKED(thr, sizeof(duk_catcher));\n\tDUK_ASSERT(cat != NULL);\n\treturn cat;\n}\n\n#if defined(DUK_USE_CACHE_CATCHER)\nDUK_INTERNAL DUK_INLINE duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr) {\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tcat = thr->heap->catcher_free;\n\tif (DUK_LIKELY(cat != NULL)) {\n\t\tthr->heap->catcher_free = cat->parent;\n\t\treturn cat;\n\t}\n\n\treturn duk__hthread_catcher_alloc_slow(thr);\n}\n#else  /* DUK_USE_CACHE_CATCHER */\nDUK_INTERNAL duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr) {\n\treturn duk__hthread_catcher_alloc_slow(thr);\n}\n#endif  /* DUK_USE_CACHE_CATCHER */\n\nDUK_INTERNAL void duk_hthread_catcher_free(duk_hthread *thr, duk_catcher *cat) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(cat != NULL);\n\n#if defined(DUK_USE_CACHE_CATCHER)\n\t/* Unconditional caching for now; freed in mark-and-sweep. */\n\tcat->parent = thr->heap->catcher_free;\n\tthr->heap->catcher_free = cat;\n#else\n\tDUK_FREE_CHECKED(thr, (void *) cat);\n#endif\n}\n\nDUK_LOCAL\n#if defined(DUK_USE_CACHE_ACTIVATION)\nDUK_NOINLINE\n#endif\nduk_activation *duk__hthread_activation_alloc_slow(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tact = (duk_activation *) DUK_ALLOC_CHECKED(thr, sizeof(duk_activation));\n\tDUK_ASSERT(act != NULL);\n\treturn act;\n}\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\nDUK_INTERNAL DUK_INLINE duk_activation *duk_hthread_activation_alloc(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tact = thr->heap->activation_free;\n\tif (DUK_LIKELY(act != NULL)) {\n\t\tthr->heap->activation_free = act->parent;\n\t\treturn act;\n\t}\n\n\treturn duk__hthread_activation_alloc_slow(thr);\n}\n#else  /* DUK_USE_CACHE_ACTIVATION */\nDUK_INTERNAL duk_activation *duk_hthread_activation_alloc(duk_hthread *thr) {\n\treturn duk__hthread_activation_alloc_slow(thr);\n}\n#endif  /* DUK_USE_CACHE_ACTIVATION */\n\n\nDUK_INTERNAL void duk_hthread_activation_free(duk_hthread *thr, duk_activation *act) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\t/* Unconditional caching for now; freed in mark-and-sweep. */\n\tact->parent = thr->heap->activation_free;\n\tthr->heap->activation_free = act;\n#else\n\tDUK_FREE_CHECKED(thr, (void *) act);\n#endif\n}\n\n/* Internal helper: process the unwind for the topmost activation of a thread,\n * but leave the duk_activation in place for possible tailcall reuse.\n */\nDUK_LOCAL void duk__activation_unwind_nofree_norz(duk_hthread *thr) {\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_heap *heap;\n#endif\n\tduk_activation *act;\n\tduk_hobject *func;\n\tduk_hobject *tmp;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->callstack_curr != NULL);  /* caller must check */\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\t/* With lightfuncs, act 'func' may be NULL. */\n\n\t/* With duk_activation records allocated separately, 'act' is a stable\n\t * pointer and not affected by side effects.\n\t */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t/*\n\t *  Restore 'caller' property for non-strict callee functions.\n\t */\n\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tif (func != NULL && !DUK_HOBJECT_HAS_STRICT(func)) {\n\t\tduk_tval *tv_caller;\n\t\tduk_tval tv_tmp;\n\t\tduk_hobject *h_tmp;\n\n\t\ttv_caller = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, func, DUK_STRIDX_CALLER);\n\n\t\t/* The act->prev_caller should only be set if the entry for 'caller'\n\t\t * exists (as it is only set in that case, and the property is not\n\t\t * configurable), but handle all the cases anyway.\n\t\t */\n\n\t\tif (tv_caller) {\n\t\t\tDUK_TVAL_SET_TVAL(&tv_tmp, tv_caller);\n\t\t\tif (act->prev_caller) {\n\t\t\t\t/* Just transfer the refcount from act->prev_caller to tv_caller,\n\t\t\t\t * so no need for a refcount update.  This is the expected case.\n\t\t\t\t */\n\t\t\t\tDUK_TVAL_SET_OBJECT(tv_caller, act->prev_caller);\n\t\t\t\tact->prev_caller = NULL;\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_NULL(tv_caller);   /* no incref needed */\n\t\t\t\tDUK_ASSERT(act->prev_caller == NULL);\n\t\t\t}\n\t\t\tDUK_TVAL_DECREF_NORZ(thr, &tv_tmp);\n\t\t} else {\n\t\t\th_tmp = act->prev_caller;\n\t\t\tif (h_tmp) {\n\t\t\t\tact->prev_caller = NULL;\n\t\t\t\tDUK_HOBJECT_DECREF_NORZ(thr, h_tmp);\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(act->prev_caller == NULL);\n\t}\n#endif\n\n\t/*\n\t *  Unwind debugger state.  If we unwind while stepping\n\t *  (for any step type), pause execution.  This is the\n\t *  only place explicitly handling a step out.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\theap = thr->heap;\n\tif (heap->dbg_pause_act == thr->callstack_curr) {\n\t\tif (heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_EXIT) {\n\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by function exit\"));\n\t\t\tduk_debug_set_paused(heap);\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"unwound past dbg_pause_act, set to NULL\"));\n\t\t\theap->dbg_pause_act = NULL;  /* avoid stale pointers */\n\t\t}\n\t\tDUK_ASSERT(heap->dbg_pause_act == NULL);\n\t}\n#endif\n\n\t/*\n\t *  Unwind catchers.\n\t *\n\t *  Since there are no references in the catcher structure,\n\t *  unwinding is quite simple.  The only thing we need to\n\t *  look out for is popping a possible lexical environment\n\t *  established for an active catch clause.\n\t */\n\n\twhile (act->cat != NULL) {\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t}\n\n\t/*\n\t *  Close environment record(s) if they exist.\n\t *\n\t *  Only variable environments are closed.  If lex_env != var_env, it\n\t *  cannot currently contain any register bound declarations.\n\t *\n\t *  Only environments created for a NEWENV function are closed.  If an\n\t *  environment is created for e.g. an eval call, it must not be closed.\n\t */\n\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tif (func != NULL && !DUK_HOBJECT_HAS_NEWENV(func)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"skip closing environments, envs not owned by this activation\"));\n\t\tgoto skip_env_close;\n\t}\n\t/* func is NULL for lightfunc */\n\n\t/* Catch sites are required to clean up their environments\n\t * in FINALLY part before propagating, so this should\n\t * always hold here.\n\t */\n\tDUK_ASSERT(act->lex_env == act->var_env);\n\n\t/* XXX: Closing the environment record copies values from registers\n\t * into the scope object.  It's side effect free as such, but may\n\t * currently run out of memory which causes an error throw.  This is\n\t * an actual sandboxing problem for error unwinds, and needs to be\n\t * fixed e.g. by preallocating the scope property slots.\n\t */\n\tif (act->var_env != NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"closing var_env record %p -> %!O\",\n\t\t                     (void *) act->var_env, (duk_heaphdr *) act->var_env));\n\t\tduk_js_close_environment_record(thr, act->var_env);\n\t}\n\n skip_env_close:\n\n\t/*\n\t *  Update preventcount\n\t */\n\n\tif (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) {\n\t\tDUK_ASSERT(thr->callstack_preventcount >= 1);\n\t\tthr->callstack_preventcount--;\n\t}\n\n\t/*\n\t *  Reference count updates, using NORZ macros so we don't\n\t *  need to handle side effects.\n\t *\n\t *  duk_activation pointers like act->var_env are intentionally\n\t *  left as garbage and not NULLed.  Without side effects they\n\t *  can't be used when the values are dangling/garbage.\n\t */\n\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, act->var_env);\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, act->lex_env);\n\ttmp = DUK_ACT_GET_FUNC(act);\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\tDUK_UNREF(tmp);\n}\n\n/* Unwind topmost duk_activation of a thread, caller must ensure that an\n * activation exists.  The call is side effect free, except that scope\n * closure may currently throw an out-of-memory error.\n */\nDUK_INTERNAL void duk_hthread_activation_unwind_norz(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tduk__activation_unwind_nofree_norz(thr);\n\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tact = thr->callstack_curr;\n\tthr->callstack_curr = act->parent;\n\tthr->callstack_top--;\n\n\t/* Ideally we'd restore value stack reserve here to caller's value.\n\t * This doesn't work for current unwind call sites however, because\n\t * the current (unwound) value stack top may be above the reserve.\n\t * Thus value stack reserve is restored by the call sites.\n\t */\n\n\t/* XXX: inline for performance builds? */\n\tduk_hthread_activation_free(thr, act);\n\n\t/* We could clear the book-keeping variables like retval_byteoff for\n\t * the topmost activation, but don't do so now as it's not necessary.\n\t */\n}\n\nDUK_INTERNAL void duk_hthread_activation_unwind_reuse_norz(duk_hthread *thr) {\n\tduk__activation_unwind_nofree_norz(thr);\n}\n\n/* Get duk_activation for given callstack level or NULL if level is invalid\n * or deeper than the call stack.  Level -1 refers to current activation, -2\n * to its caller, etc.  Starting from Duktape 2.2 finding the activation is\n * a linked list scan which gets more expensive the deeper the lookup is.\n */\nDUK_INTERNAL duk_activation *duk_hthread_get_activation_for_level(duk_hthread *thr, duk_int_t level) {\n\tduk_activation *act;\n\n\tif (level >= 0) {\n\t\treturn NULL;\n\t}\n\tact = thr->callstack_curr;\n\tfor (;;) {\n\t\tif (act == NULL) {\n\t\t\treturn act;\n\t\t}\n\t\tif (level == -1) {\n\t\t\treturn act;\n\t\t}\n\t\tlevel++;\n\t\tact = act->parent;\n\t}\n\t/* never here */\n}\n\n#if defined(DUK_USE_FINALIZER_TORTURE)\nDUK_INTERNAL void duk_hthread_valstack_torture_realloc(duk_hthread *thr) {\n\tduk_size_t alloc_size;\n\tduk_tval *new_ptr;\n\tduk_ptrdiff_t alloc_end_off;\n\tduk_ptrdiff_t end_off;\n\tduk_ptrdiff_t bottom_off;\n\tduk_ptrdiff_t top_off;\n\n\tif (thr->valstack == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"skip valstack torture realloc, valstack is NULL\"));\n\t\treturn;\n\t}\n\n\talloc_end_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_alloc_end - (duk_uint8_t *) thr->valstack);\n\tend_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tbottom_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);\n\ttop_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack);\n\talloc_size = (duk_size_t) alloc_end_off;\n\tif (alloc_size == 0) {\n\t\tDUK_D(DUK_DPRINT(\"skip valstack torture realloc, alloc_size is zero\"));\n\t\treturn;\n\t}\n\n\t/* Use DUK_ALLOC_RAW() to avoid side effects. */\n\tnew_ptr = (duk_tval *) DUK_ALLOC_RAW(thr->heap, alloc_size);\n\tif (new_ptr != NULL) {\n\t\tduk_memcpy((void *) new_ptr, (const void *) thr->valstack, alloc_size);\n\t\tduk_memset((void *) thr->valstack, 0x55, alloc_size);\n\t\tDUK_FREE_CHECKED(thr, (void *) thr->valstack);\n\t\tthr->valstack = new_ptr;\n\t\tthr->valstack_alloc_end = (duk_tval *) ((duk_uint8_t *) new_ptr + alloc_end_off);\n\t\tthr->valstack_end = (duk_tval *) ((duk_uint8_t *) new_ptr + end_off);\n\t\tthr->valstack_bottom = (duk_tval *) ((duk_uint8_t *) new_ptr + bottom_off);\n\t\tthr->valstack_top = (duk_tval *) ((duk_uint8_t *) new_ptr + top_off);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"failed to realloc valstack for torture, ignore\"));\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_TORTURE */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_internal.h",
    "content": "/*\n *  Top-level include file to be used for all (internal) source files.\n *\n *  Source files should not include individual header files, as they\n *  have not been designed to be individually included.\n */\n\n#if !defined(DUK_INTERNAL_H_INCLUDED)\n#define DUK_INTERNAL_H_INCLUDED\n\n/*\n *  The 'duktape.h' header provides the public API, but also handles all\n *  compiler and platform specific feature detection, Duktape feature\n *  resolution, inclusion of system headers, etc.  These have been merged\n *  because the public API is also dependent on e.g. detecting appropriate\n *  C types which is quite platform/compiler specific especially for a non-C99\n *  build.  The public API is also dependent on the resolved feature set.\n *\n *  Some actions taken by the merged header (such as including system headers)\n *  are not appropriate for building a user application.  The define\n *  DUK_COMPILING_DUKTAPE allows the merged header to skip/include some\n *  sections depending on what is being built.\n */\n\n#define DUK_COMPILING_DUKTAPE\n#include \"duktape.h\"\n\n/*\n *  Duktape includes (other than duk_features.h)\n *\n *  The header files expect to be included in an order which satisfies header\n *  dependencies correctly (the headers themselves don't include any other\n *  includes).  Forward declarations are used to break circular struct/typedef\n *  dependencies.\n */\n\n#include \"duk_dblunion.h\"\n#include \"duk_replacements.h\"\n#include \"duk_jmpbuf.h\"\n#include \"duk_exception.h\"\n#include \"duk_forwdecl.h\"\n#include \"duk_tval.h\"      /* builtins need e.g. duk_tval tag definitions */\n#include \"duk_builtins.h\"  /* autogenerated: strings and built-in object init data */\n\n#include \"duk_util.h\"\n#include \"duk_strings.h\"\n#include \"duk_js_bytecode.h\"\n#include \"duk_lexer.h\"\n#include \"duk_js_compiler.h\"\n#include \"duk_regexp.h\"\n#include \"duk_heaphdr.h\"\n#include \"duk_refcount.h\"\n#include \"duk_api_internal.h\"\n#include \"duk_hstring.h\"\n#include \"duk_hobject.h\"\n#include \"duk_hcompfunc.h\"\n#include \"duk_hnatfunc.h\"\n#include \"duk_hboundfunc.h\"\n#include \"duk_hbufobj.h\"\n#include \"duk_hthread.h\"\n#include \"duk_harray.h\"\n#include \"duk_henv.h\"\n#include \"duk_hbuffer.h\"\n#include \"duk_hproxy.h\"\n#include \"duk_heap.h\"\n#include \"duk_debugger.h\"\n#include \"duk_debug.h\"\n#include \"duk_error.h\"\n#include \"duk_unicode.h\"\n#include \"duk_json.h\"\n#include \"duk_js.h\"\n#include \"duk_numconv.h\"\n#include \"duk_bi_protos.h\"\n#include \"duk_selftest.h\"\n\n#endif  /* DUK_INTERNAL_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_jmpbuf.h",
    "content": "/*\n *  Wrapper for jmp_buf.\n *\n *  This is used because jmp_buf is an array type for backward compatibility.\n *  Wrapping jmp_buf in a struct makes pointer references, sizeof, etc,\n *  behave more intuitively.\n *\n *  http://en.wikipedia.org/wiki/Setjmp.h#Member_types\n */\n\n#if !defined(DUK_JMPBUF_H_INCLUDED)\n#define DUK_JMPBUF_H_INCLUDED\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\nstruct duk_jmpbuf {\n\tduk_small_int_t dummy;  /* unused */\n};\n#else\nstruct duk_jmpbuf {\n\tDUK_JMPBUF_TYPE jb;\n};\n#endif\n\n#endif  /* DUK_JMPBUF_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_js.h",
    "content": "/*\n *  ECMAScript execution, support primitives.\n */\n\n#if !defined(DUK_JS_H_INCLUDED)\n#define DUK_JS_H_INCLUDED\n\n/* Flags for call handling.  Lowest flags must match bytecode DUK_BC_CALL_FLAG_xxx 1:1. */\n#define DUK_CALL_FLAG_TAILCALL                 (1U << 0)  /* setup for a tail call */\n#define DUK_CALL_FLAG_CONSTRUCT                (1U << 1)  /* constructor call (i.e. called as 'new Foo()') */\n#define DUK_CALL_FLAG_CALLED_AS_EVAL           (1U << 2)  /* call was made using the identifier 'eval' */\n#define DUK_CALL_FLAG_ALLOW_ECMATOECMA         (1U << 3)  /* ecma-to-ecma call with executor reuse is possible */\n#define DUK_CALL_FLAG_DIRECT_EVAL              (1U << 4)  /* call is a direct eval call */\n#define DUK_CALL_FLAG_CONSTRUCT_PROXY          (1U << 5)  /* handled via 'construct' proxy trap, check return value invariant(s) */\n#define DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED (1U << 6)  /* prototype of 'default instance' updated, temporary flag in call handling */\n\n/* Flags for duk_js_equals_helper(). */\n#define DUK_EQUALS_FLAG_SAMEVALUE            (1U << 0)  /* use SameValue instead of non-strict equality */\n#define DUK_EQUALS_FLAG_STRICT               (1U << 1)  /* use strict equality instead of non-strict equality */\n\n/* Flags for duk_js_compare_helper(). */\n#define DUK_COMPARE_FLAG_NEGATE              (1U << 0)  /* negate result */\n#define DUK_COMPARE_FLAG_EVAL_LEFT_FIRST     (1U << 1)  /* eval left argument first */\n\n/* conversions, coercions, comparison, etc */\nDUK_INTERNAL_DECL duk_bool_t duk_js_toboolean(duk_tval *tv);\nDUK_INTERNAL_DECL duk_double_t duk_js_tonumber(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_double_t duk_js_tointeger_number(duk_double_t x);\nDUK_INTERNAL_DECL duk_double_t duk_js_tointeger(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_uint32_t duk_js_touint32(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_int32_t duk_js_toint32(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_uint16_t duk_js_touint16(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_string(const duk_uint8_t *str, duk_uint32_t blen);\n#if !defined(DUK_USE_HSTRING_ARRIDX)\nDUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_hstring_fast_known(duk_hstring *h);\nDUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_hstring_fast(duk_hstring *h);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_small_int_t duk_js_data_compare(const duk_uint8_t *buf1, const duk_uint8_t *buf2, duk_size_t len1, duk_size_t len2);\nDUK_INTERNAL_DECL duk_small_int_t duk_js_string_compare(duk_hstring *h1, duk_hstring *h2);\n#if 0  /* unused */\nDUK_INTERNAL_DECL duk_small_int_t duk_js_buffer_compare(duk_heap *heap, duk_hbuffer *h1, duk_hbuffer *h2);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL_DECL duk_bool_t duk_js_instanceof_ordinary(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_in(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);\nDUK_INTERNAL_DECL duk_small_uint_t duk_js_typeof_stridx(duk_tval *tv_x);\n\n/* arithmetic */\nDUK_INTERNAL_DECL double duk_js_arith_pow(double x, double y);\nDUK_INTERNAL_DECL double duk_js_arith_mod(double x, double y);\n\n#define duk_js_equals(thr,tv_x,tv_y) \\\n\tduk_js_equals_helper((thr), (tv_x), (tv_y), 0)\n#define duk_js_strict_equals(tv_x,tv_y) \\\n\tduk_js_equals_helper(NULL, (tv_x), (tv_y), DUK_EQUALS_FLAG_STRICT)\n#define duk_js_samevalue(tv_x,tv_y) \\\n\tduk_js_equals_helper(NULL, (tv_x), (tv_y), DUK_EQUALS_FLAG_SAMEVALUE)\n\n/* E5 Sections 11.8.1, 11.8.5; x < y */\n#define duk_js_lessthan(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_x), (tv_Y), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST)\n\n/* E5 Sections 11.8.2, 11.8.5; x > y  -->  y < x */\n#define duk_js_greaterthan(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_y), (tv_x), 0)\n\n/* E5 Sections 11.8.3, 11.8.5; x <= y  -->  not (x > y)  -->  not (y < x) */\n#define duk_js_lessthanorequal(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_y), (tv_x), DUK_COMPARE_FLAG_NEGATE)\n\n/* E5 Sections 11.8.4, 11.8.5; x >= y  -->  not (x < y) */\n#define duk_js_greaterthanorequal(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_x), (tv_y), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST | DUK_COMPARE_FLAG_NEGATE)\n\n/* identifiers and environment handling */\n#if 0  /*unused*/\nDUK_INTERNAL duk_bool_t duk_js_hasvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_getvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL duk_bool_t duk_js_getvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL void duk_js_putvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name, duk_tval *val, duk_bool_t strict);\nDUK_INTERNAL_DECL void duk_js_putvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_tval *val, duk_bool_t strict);\n#if 0  /*unused*/\nDUK_INTERNAL_DECL duk_bool_t duk_js_delvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_delvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name);\nDUK_INTERNAL_DECL duk_bool_t duk_js_declvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_tval *val, duk_small_uint_t prop_flags, duk_bool_t is_func_decl);\nDUK_INTERNAL_DECL void duk_js_init_activation_environment_records_delayed(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject *env);\nDUK_INTERNAL_DECL duk_hobject *duk_create_activation_environment_record(duk_hthread *thr, duk_hobject *func, duk_size_t bottom_byteoff);\nDUK_INTERNAL_DECL void duk_js_push_closure(duk_hthread *thr,\n                                           duk_hcompfunc *fun_temp,\n                                           duk_hobject *outer_var_env,\n                                           duk_hobject *outer_lex_env,\n                                           duk_bool_t add_auto_proto);\n\n/* call handling */\nDUK_INTERNAL_DECL void duk_native_stack_check(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_int_t duk_handle_call_unprotected(duk_hthread *thr, duk_idx_t idx_func, duk_small_uint_t call_flags);\nDUK_INTERNAL_DECL duk_int_t duk_handle_call_unprotected_nargs(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags);\nDUK_INTERNAL_DECL duk_int_t duk_handle_safe_call(duk_hthread *thr, duk_safe_call_function func, void *udata, duk_idx_t num_stack_args, duk_idx_t num_stack_res);\nDUK_INTERNAL_DECL void duk_call_construct_postprocess(duk_hthread *thr, duk_small_uint_t proxy_invariant);\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_INTERNAL_DECL void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_base, duk_tval *tv_key);\n#endif\n\n/* bytecode execution */\nDUK_INTERNAL_DECL void duk_js_execute_bytecode(duk_hthread *exec_thr);\n\n#endif  /* DUK_JS_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_js_arith.c",
    "content": "/*\n *  Shared helpers for arithmetic operations\n */\n\n#include \"duk_internal.h\"\n\n/* ECMAScript modulus ('%') does not match IEEE 754 \"remainder\" operation\n * (implemented by remainder() in C99) but does seem to match ANSI C fmod().\n * Compare E5 Section 11.5.3 and \"man fmod\".\n */\nDUK_INTERNAL double duk_js_arith_mod(double d1, double d2) {\n#if defined(DUK_USE_POW_WORKAROUNDS)\n\t/* Specific fixes to common fmod() implementation issues:\n\t * - test-bug-mingw-math-issues.js\n\t */\n\tif (DUK_ISINF(d2)) {\n\t\tif (DUK_ISINF(d1)) {\n\t\t\treturn DUK_DOUBLE_NAN;\n\t\t} else {\n\t\t\treturn d1;\n\t\t}\n\t} else if (d1 == 0.0) {\n\t\t/* d1 +/-0 is returned as is (preserving sign) except when\n\t\t * d2 is zero or NaN.\n\t\t */\n\t\tif (d2 == 0.0 || DUK_ISNAN(d2)) {\n\t\t\treturn DUK_DOUBLE_NAN;\n\t\t} else {\n\t\t\treturn d1;\n\t\t}\n\t}\n#else\n\t/* Some ISO C assumptions. */\n\tDUK_ASSERT(DUK_FMOD(1.0, DUK_DOUBLE_INFINITY) == 1.0);\n\tDUK_ASSERT(DUK_FMOD(-1.0, DUK_DOUBLE_INFINITY) == -1.0);\n\tDUK_ASSERT(DUK_FMOD(1.0, -DUK_DOUBLE_INFINITY) == 1.0);\n\tDUK_ASSERT(DUK_FMOD(-1.0, -DUK_DOUBLE_INFINITY) == -1.0);\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_FMOD(0.0, 1.0) == 0.0 && DUK_SIGNBIT(DUK_FMOD(0.0, 1.0)) == 0);\n\tDUK_ASSERT(DUK_FMOD(-0.0, 1.0) == 0.0 && DUK_SIGNBIT(DUK_FMOD(-0.0, 1.0)) != 0);\n\tDUK_ASSERT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY)) == 0);\n\tDUK_ASSERT(DUK_FMOD(-0.0, DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(-0.0, DUK_DOUBLE_INFINITY)) != 0);\n\tDUK_ASSERT(DUK_FMOD(0.0, -DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY)) == 0);\n\tDUK_ASSERT(DUK_FMOD(-0.0, -DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(-0.0, -DUK_DOUBLE_INFINITY)) != 0);\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, 0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, 0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, -0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, -0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, DUK_DOUBLE_NAN)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, DUK_DOUBLE_NAN)));\n#endif\n\n\treturn (duk_double_t) DUK_FMOD((double) d1, (double) d2);\n}\n\n/* Shared helper for Math.pow() and exponentiation operator. */\nDUK_INTERNAL double duk_js_arith_pow(double x, double y) {\n\t/* The ANSI C pow() semantics differ from ECMAScript.\n\t *\n\t * E.g. when x==1 and y is +/- infinite, the ECMAScript required\n\t * result is NaN, while at least Linux pow() returns 1.\n\t */\n\n\tduk_small_int_t cx, cy, sx;\n\n\tDUK_UNREF(cx);\n\tDUK_UNREF(sx);\n\tcy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\n\tif (cy == DUK_FP_NAN) {\n\t\tgoto ret_nan;\n\t}\n\tif (DUK_FABS(x) == 1.0 && cy == DUK_FP_INFINITE) {\n\t\tgoto ret_nan;\n\t}\n\n#if defined(DUK_USE_POW_WORKAROUNDS)\n\t/* Specific fixes to common pow() implementation issues:\n\t *   - test-bug-netbsd-math-pow.js: NetBSD 6.0 on x86 (at least)\n\t *   - test-bug-mingw-math-issues.js\n\t */\n\tcx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (cx == DUK_FP_ZERO && y < 0.0) {\n\t\tsx = (duk_small_int_t) DUK_SIGNBIT(x);\n\t\tif (sx == 0) {\n\t\t\t/* Math.pow(+0,y) should be Infinity when y<0.  NetBSD pow()\n\t\t\t * returns -Infinity instead when y is <0 and finite.  The\n\t\t\t * if-clause also catches y == -Infinity (which works even\n\t\t\t * without the fix).\n\t\t\t */\n\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t} else {\n\t\t\t/* Math.pow(-0,y) where y<0 should be:\n\t\t\t *   - -Infinity if y<0 and an odd integer\n\t\t\t *   - Infinity if y<0 but not an odd integer\n\t\t\t * NetBSD pow() returns -Infinity for all finite y<0.  The\n\t\t\t * if-clause also catches y == -Infinity (which works even\n\t\t\t * without the fix).\n\t\t\t */\n\n\t\t\t/* fmod() return value has same sign as input (negative) so\n\t\t\t * the result here will be in the range ]-2,0], -1 indicates\n\t\t\t * odd.  If x is -Infinity, NaN is returned and the odd check\n\t\t\t * always concludes \"not odd\" which results in desired outcome.\n\t\t\t */\n\t\t\tdouble tmp = DUK_FMOD(y, 2);\n\t\t\tif (tmp == -1.0) {\n\t\t\t\treturn -DUK_DOUBLE_INFINITY;\n\t\t\t} else {\n\t\t\t\t/* Not odd, or y == -Infinity */\n\t\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t\t}\n\t\t}\n\t} else if (cx == DUK_FP_NAN) {\n\t\tif (y == 0.0) {\n\t\t\t/* NaN ** +/- 0 should always be 1, but is NaN on\n\t\t\t * at least some Cygwin/MinGW versions.\n\t\t\t */\n\t\t\treturn 1.0;\n\t\t}\n\t}\n#else\n\t/* Some ISO C assumptions. */\n\tDUK_ASSERT(DUK_POW(DUK_DOUBLE_NAN, 0.0) == 1.0);\n\tDUK_ASSERT(DUK_ISINF(DUK_POW(0.0, -1.0)) && DUK_SIGNBIT(DUK_POW(0.0, -1.0)) == 0);\n\tDUK_ASSERT(DUK_ISINF(DUK_POW(-0.0, -2.0)) && DUK_SIGNBIT(DUK_POW(-0.0, -2.0)) == 0);\n\tDUK_ASSERT(DUK_ISINF(DUK_POW(-0.0, -3.0)) && DUK_SIGNBIT(DUK_POW(-0.0, -3.0)) != 0);\n#endif\n\n\treturn DUK_POW(x, y);\n\n ret_nan:\n\treturn DUK_DOUBLE_NAN;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_js_bytecode.h",
    "content": "/*\n *  ECMAScript bytecode\n */\n\n#if !defined(DUK_JS_BYTECODE_H_INCLUDED)\n#define DUK_JS_BYTECODE_H_INCLUDED\n\n/*\n *  Bytecode instruction layout\n *  ===========================\n *\n *  Instructions are unsigned 32-bit integers divided as follows:\n *\n *  !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! !\n *  !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!\n *  +-----------------------------------------------+---------------+\n *  !       C       !       B       !       A       !       OP      !\n *  +-----------------------------------------------+---------------+\n *\n *  OP (8 bits):  opcode (DUK_OP_*), access should be fastest\n *                consecutive opcodes allocated when opcode needs flags\n *   A (8 bits):  typically a target register number\n *   B (8 bits):  typically first source register/constant number\n *   C (8 bits):  typically second source register/constant number\n *\n *  Some instructions combine BC or ABC together for larger parameter values.\n *  Signed integers (e.g. jump offsets) are encoded as unsigned, with an\n *  opcode specific bias.\n *\n *  Some opcodes have flags which are handled by allocating consecutive\n *  opcodes to make space for 1-N flags.  Flags can also be e.g. in the 'A'\n *  field when there's room for the specific opcode.\n *\n *  For example, if three flags were needed, they could be allocated from\n *  the opcode field as follows:\n *\n *  !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! !\n *  !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!\n *  +-----------------------------------------------+---------------+\n *  !       C       !       B       !       A       !    OP   !Z!Y!X!\n *  +-----------------------------------------------+---------------+\n *\n *  Some opcodes accept a reg/const argument which is handled by allocating\n *  flags in the OP field, see DUK_BC_ISREG() and DUK_BC_ISCONST().  The\n *  following convention is shared by most opcodes, so that the compiler\n *  can handle reg/const flagging without opcode specific code paths:\n *\n *  !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! !\n *  !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!\n *  +-----------------------------------------------+---------------+\n *  !       C       !       B       !       A       !     OP    !Y!X!\n *  +-----------------------------------------------+---------------+\n *\n *    X  1=B is const, 0=B is reg\n *    Y  1=C is const, 0=C is reg\n *\n *    In effect OP, OP + 1, OP + 2, and OP + 3 are allocated from the\n *    8-bit opcode space for a single logical opcode.  The base opcode\n *    number should be divisible by 4.  If the opcode is called 'FOO'\n *    the following opcode constants would be defined:\n *\n *      DUK_OP_FOO     100       // base opcode number\n *      DUK_OP_FOO_RR  100       // FOO, B=reg, C=reg\n *      DUK_OP_FOO_CR  101       // FOO, B=const, C=reg\n *      DUK_OP_FOO_RC  102       // FOO, B=reg, C=const\n *      DUK_OP_FOO_CC  103       // FOO, B=const, C=const\n *\n *  If only B or C is a reg/const, the unused opcode combinations can be\n *  used for other opcodes (which take no reg/const argument).  However,\n *  such opcode values are initially reserved, at least while opcode space\n *  is available.  For example, if 'BAR' uses B for a register field and\n *  C is a reg/const:\n *\n *      DUK_OP_BAR            116    // base opcode number\n *      DUK_OP_BAR_RR         116    // BAR, B=reg, C=reg\n *      DUK_OP_BAR_CR_UNUSED  117    // unused, could be repurposed\n *      DUK_OP_BAR_RC         118    // BAR, B=reg, C=const\n *      DUK_OP_BAR_CC_UNUSED  119    // unused, could be repurposed\n *\n *  Macro naming is a bit misleading, e.g. \"ABC\" in macro name but the\n *  field layout is concretely \"CBA\" in the register.\n */\n\ntypedef duk_uint32_t duk_instr_t;\n\n#define DUK_BC_SHIFT_OP             0\n#define DUK_BC_SHIFT_A              8\n#define DUK_BC_SHIFT_B              16\n#define DUK_BC_SHIFT_C              24\n#define DUK_BC_SHIFT_BC             DUK_BC_SHIFT_B\n#define DUK_BC_SHIFT_ABC            DUK_BC_SHIFT_A\n\n#define DUK_BC_UNSHIFTED_MASK_OP    0xffUL\n#define DUK_BC_UNSHIFTED_MASK_A     0xffUL\n#define DUK_BC_UNSHIFTED_MASK_B     0xffUL\n#define DUK_BC_UNSHIFTED_MASK_C     0xffUL\n#define DUK_BC_UNSHIFTED_MASK_BC    0xffffUL\n#define DUK_BC_UNSHIFTED_MASK_ABC   0xffffffUL\n\n#define DUK_BC_SHIFTED_MASK_OP      (DUK_BC_UNSHIFTED_MASK_OP << DUK_BC_SHIFT_OP)\n#define DUK_BC_SHIFTED_MASK_A       (DUK_BC_UNSHIFTED_MASK_A << DUK_BC_SHIFT_A)\n#define DUK_BC_SHIFTED_MASK_B       (DUK_BC_UNSHIFTED_MASK_B << DUK_BC_SHIFT_B)\n#define DUK_BC_SHIFTED_MASK_C       (DUK_BC_UNSHIFTED_MASK_C << DUK_BC_SHIFT_C)\n#define DUK_BC_SHIFTED_MASK_BC      (DUK_BC_UNSHIFTED_MASK_BC << DUK_BC_SHIFT_BC)\n#define DUK_BC_SHIFTED_MASK_ABC     (DUK_BC_UNSHIFTED_MASK_ABC << DUK_BC_SHIFT_ABC)\n\n#define DUK_DEC_OP(x)               ((x) & 0xffUL)\n#define DUK_DEC_A(x)                (((x) >> 8) & 0xffUL)\n#define DUK_DEC_B(x)                (((x) >> 16) & 0xffUL)\n#define DUK_DEC_C(x)                (((x) >> 24) & 0xffUL)\n#define DUK_DEC_BC(x)               (((x) >> 16) & 0xffffUL)\n#define DUK_DEC_ABC(x)              (((x) >> 8) & 0xffffffUL)\n\n#define DUK_ENC_OP(op)              ((duk_instr_t) (op))\n#define DUK_ENC_OP_ABC(op,abc)      ((duk_instr_t) ( \\\n                                        (((duk_instr_t) (abc)) << 8) | \\\n                                        ((duk_instr_t) (op)) \\\n                                    ))\n#define DUK_ENC_OP_A_BC(op,a,bc)    ((duk_instr_t) ( \\\n                                        (((duk_instr_t) (bc)) << 16) | \\\n                                        (((duk_instr_t) (a)) << 8) | \\\n                                        ((duk_instr_t) (op)) \\\n                                    ))\n#define DUK_ENC_OP_A_B_C(op,a,b,c)  ((duk_instr_t) ( \\\n                                        (((duk_instr_t) (c)) << 24) | \\\n                                        (((duk_instr_t) (b)) << 16) | \\\n                                        (((duk_instr_t) (a)) << 8) | \\\n                                        ((duk_instr_t) (op)) \\\n                                    ))\n#define DUK_ENC_OP_A_B(op,a,b)      DUK_ENC_OP_A_B_C((op),(a),(b),0)\n#define DUK_ENC_OP_A(op,a)          DUK_ENC_OP_A_B_C((op),(a),0,0)\n#define DUK_ENC_OP_BC(op,bc)        DUK_ENC_OP_A_BC((op),0,(bc))\n\n/* Get opcode base value with B/C reg/const flags cleared. */\n#define DUK_BC_NOREGCONST_OP(op)    ((op) & 0xfc)\n\n/* Constants should be signed so that signed arithmetic involving them\n * won't cause values to be coerced accidentally to unsigned.\n */\n#define DUK_BC_OP_MIN               0\n#define DUK_BC_OP_MAX               0xffL\n#define DUK_BC_A_MIN                0\n#define DUK_BC_A_MAX                0xffL\n#define DUK_BC_B_MIN                0\n#define DUK_BC_B_MAX                0xffL\n#define DUK_BC_C_MIN                0\n#define DUK_BC_C_MAX                0xffL\n#define DUK_BC_BC_MIN               0\n#define DUK_BC_BC_MAX               0xffffL\n#define DUK_BC_ABC_MIN              0\n#define DUK_BC_ABC_MAX              0xffffffL\n\n/* Masks for B/C reg/const indicator in opcode field. */\n#define DUK_BC_REGCONST_B           (0x01UL)\n#define DUK_BC_REGCONST_C           (0x02UL)\n\n/* Misc. masks for opcode field. */\n#define DUK_BC_INCDECP_FLAG_DEC     (0x04UL)\n#define DUK_BC_INCDECP_FLAG_POST    (0x08UL)\n\n/* Opcodes. */\n#define DUK_OP_LDREG                0\n#define DUK_OP_STREG                1\n#define DUK_OP_JUMP                 2\n#define DUK_OP_LDCONST              3\n#define DUK_OP_LDINT                4\n#define DUK_OP_LDINTX               5\n#define DUK_OP_LDTHIS               6\n#define DUK_OP_LDUNDEF              7\n#define DUK_OP_LDNULL               8\n#define DUK_OP_LDTRUE               9\n#define DUK_OP_LDFALSE              10\n#define DUK_OP_GETVAR               11\n#define DUK_OP_BNOT                 12\n#define DUK_OP_LNOT                 13\n#define DUK_OP_UNM                  14\n#define DUK_OP_UNP                  15\n#define DUK_OP_EQ                   16\n#define DUK_OP_EQ_RR                16\n#define DUK_OP_EQ_CR                17\n#define DUK_OP_EQ_RC                18\n#define DUK_OP_EQ_CC                19\n#define DUK_OP_NEQ                  20\n#define DUK_OP_NEQ_RR               20\n#define DUK_OP_NEQ_CR               21\n#define DUK_OP_NEQ_RC               22\n#define DUK_OP_NEQ_CC               23\n#define DUK_OP_SEQ                  24\n#define DUK_OP_SEQ_RR               24\n#define DUK_OP_SEQ_CR               25\n#define DUK_OP_SEQ_RC               26\n#define DUK_OP_SEQ_CC               27\n#define DUK_OP_SNEQ                 28\n#define DUK_OP_SNEQ_RR              28\n#define DUK_OP_SNEQ_CR              29\n#define DUK_OP_SNEQ_RC              30\n#define DUK_OP_SNEQ_CC              31\n#define DUK_OP_GT                   32\n#define DUK_OP_GT_RR                32\n#define DUK_OP_GT_CR                33\n#define DUK_OP_GT_RC                34\n#define DUK_OP_GT_CC                35\n#define DUK_OP_GE                   36\n#define DUK_OP_GE_RR                36\n#define DUK_OP_GE_CR                37\n#define DUK_OP_GE_RC                38\n#define DUK_OP_GE_CC                39\n#define DUK_OP_LT                   40\n#define DUK_OP_LT_RR                40\n#define DUK_OP_LT_CR                41\n#define DUK_OP_LT_RC                42\n#define DUK_OP_LT_CC                43\n#define DUK_OP_LE                   44\n#define DUK_OP_LE_RR                44\n#define DUK_OP_LE_CR                45\n#define DUK_OP_LE_RC                46\n#define DUK_OP_LE_CC                47\n#define DUK_OP_IFTRUE               48\n#define DUK_OP_IFTRUE_R             48\n#define DUK_OP_IFTRUE_C             49\n#define DUK_OP_IFFALSE              50\n#define DUK_OP_IFFALSE_R            50\n#define DUK_OP_IFFALSE_C            51\n#define DUK_OP_ADD                  52\n#define DUK_OP_ADD_RR               52\n#define DUK_OP_ADD_CR               53\n#define DUK_OP_ADD_RC               54\n#define DUK_OP_ADD_CC               55\n#define DUK_OP_SUB                  56\n#define DUK_OP_SUB_RR               56\n#define DUK_OP_SUB_CR               57\n#define DUK_OP_SUB_RC               58\n#define DUK_OP_SUB_CC               59\n#define DUK_OP_MUL                  60\n#define DUK_OP_MUL_RR               60\n#define DUK_OP_MUL_CR               61\n#define DUK_OP_MUL_RC               62\n#define DUK_OP_MUL_CC               63\n#define DUK_OP_DIV                  64\n#define DUK_OP_DIV_RR               64\n#define DUK_OP_DIV_CR               65\n#define DUK_OP_DIV_RC               66\n#define DUK_OP_DIV_CC               67\n#define DUK_OP_MOD                  68\n#define DUK_OP_MOD_RR               68\n#define DUK_OP_MOD_CR               69\n#define DUK_OP_MOD_RC               70\n#define DUK_OP_MOD_CC               71\n#define DUK_OP_EXP                  72\n#define DUK_OP_EXP_RR               72\n#define DUK_OP_EXP_CR               73\n#define DUK_OP_EXP_RC               74\n#define DUK_OP_EXP_CC               75\n#define DUK_OP_BAND                 76\n#define DUK_OP_BAND_RR              76\n#define DUK_OP_BAND_CR              77\n#define DUK_OP_BAND_RC              78\n#define DUK_OP_BAND_CC              79\n#define DUK_OP_BOR                  80\n#define DUK_OP_BOR_RR               80\n#define DUK_OP_BOR_CR               81\n#define DUK_OP_BOR_RC               82\n#define DUK_OP_BOR_CC               83\n#define DUK_OP_BXOR                 84\n#define DUK_OP_BXOR_RR              84\n#define DUK_OP_BXOR_CR              85\n#define DUK_OP_BXOR_RC              86\n#define DUK_OP_BXOR_CC              87\n#define DUK_OP_BASL                 88\n#define DUK_OP_BASL_RR              88\n#define DUK_OP_BASL_CR              89\n#define DUK_OP_BASL_RC              90\n#define DUK_OP_BASL_CC              91\n#define DUK_OP_BLSR                 92\n#define DUK_OP_BLSR_RR              92\n#define DUK_OP_BLSR_CR              93\n#define DUK_OP_BLSR_RC              94\n#define DUK_OP_BLSR_CC              95\n#define DUK_OP_BASR                 96\n#define DUK_OP_BASR_RR              96\n#define DUK_OP_BASR_CR              97\n#define DUK_OP_BASR_RC              98\n#define DUK_OP_BASR_CC              99\n#define DUK_OP_INSTOF               100\n#define DUK_OP_INSTOF_RR            100\n#define DUK_OP_INSTOF_CR            101\n#define DUK_OP_INSTOF_RC            102\n#define DUK_OP_INSTOF_CC            103\n#define DUK_OP_IN                   104\n#define DUK_OP_IN_RR                104\n#define DUK_OP_IN_CR                105\n#define DUK_OP_IN_RC                106\n#define DUK_OP_IN_CC                107\n#define DUK_OP_GETPROP              108\n#define DUK_OP_GETPROP_RR           108\n#define DUK_OP_GETPROP_CR           109\n#define DUK_OP_GETPROP_RC           110\n#define DUK_OP_GETPROP_CC           111\n#define DUK_OP_PUTPROP              112\n#define DUK_OP_PUTPROP_RR           112\n#define DUK_OP_PUTPROP_CR           113\n#define DUK_OP_PUTPROP_RC           114\n#define DUK_OP_PUTPROP_CC           115\n#define DUK_OP_DELPROP              116\n#define DUK_OP_DELPROP_RR           116\n#define DUK_OP_DELPROP_CR_UNUSED    117  /* unused now */\n#define DUK_OP_DELPROP_RC           118\n#define DUK_OP_DELPROP_CC_UNUSED    119  /* unused now */\n#define DUK_OP_PREINCR              120  /* pre/post opcode values have constraints, */\n#define DUK_OP_PREDECR              121  /* see duk_js_executor.c and duk_js_compiler.c. */\n#define DUK_OP_POSTINCR             122\n#define DUK_OP_POSTDECR             123\n#define DUK_OP_PREINCV              124\n#define DUK_OP_PREDECV              125\n#define DUK_OP_POSTINCV             126\n#define DUK_OP_POSTDECV             127\n#define DUK_OP_PREINCP              128  /* pre/post inc/dec prop opcodes have constraints */\n#define DUK_OP_PREINCP_RR           128\n#define DUK_OP_PREINCP_CR           129\n#define DUK_OP_PREINCP_RC           130\n#define DUK_OP_PREINCP_CC           131\n#define DUK_OP_PREDECP              132\n#define DUK_OP_PREDECP_RR           132\n#define DUK_OP_PREDECP_CR           133\n#define DUK_OP_PREDECP_RC           134\n#define DUK_OP_PREDECP_CC           135\n#define DUK_OP_POSTINCP             136\n#define DUK_OP_POSTINCP_RR          136\n#define DUK_OP_POSTINCP_CR          137\n#define DUK_OP_POSTINCP_RC          138\n#define DUK_OP_POSTINCP_CC          139\n#define DUK_OP_POSTDECP             140\n#define DUK_OP_POSTDECP_RR          140\n#define DUK_OP_POSTDECP_CR          141\n#define DUK_OP_POSTDECP_RC          142\n#define DUK_OP_POSTDECP_CC          143\n#define DUK_OP_DECLVAR              144\n#define DUK_OP_DECLVAR_RR           144\n#define DUK_OP_DECLVAR_CR           145\n#define DUK_OP_DECLVAR_RC           146\n#define DUK_OP_DECLVAR_CC           147\n#define DUK_OP_REGEXP               148\n#define DUK_OP_REGEXP_RR            148\n#define DUK_OP_REGEXP_CR            149\n#define DUK_OP_REGEXP_RC            150\n#define DUK_OP_REGEXP_CC            151\n#define DUK_OP_CLOSURE              152\n#define DUK_OP_TYPEOF               153\n#define DUK_OP_TYPEOFID             154\n#define DUK_OP_PUTVAR               155\n#define DUK_OP_DELVAR               156\n#define DUK_OP_RETREG               157\n#define DUK_OP_RETUNDEF             158\n#define DUK_OP_RETCONST             159\n#define DUK_OP_RETCONSTN            160  /* return const without incref (e.g. number) */\n#define DUK_OP_LABEL                161\n#define DUK_OP_ENDLABEL             162\n#define DUK_OP_BREAK                163\n#define DUK_OP_CONTINUE             164\n#define DUK_OP_TRYCATCH             165\n#define DUK_OP_ENDTRY               166\n#define DUK_OP_ENDCATCH             167\n#define DUK_OP_ENDFIN               168\n#define DUK_OP_THROW                169\n#define DUK_OP_INVLHS               170\n#define DUK_OP_CSREG                171\n#define DUK_OP_CSVAR                172\n#define DUK_OP_CSVAR_RR             172\n#define DUK_OP_CSVAR_CR             173\n#define DUK_OP_CSVAR_RC             174\n#define DUK_OP_CSVAR_CC             175\n#define DUK_OP_CALL0                176  /* DUK_OP_CALL0 & 0x0F must be zero. */\n#define DUK_OP_CALL1                177\n#define DUK_OP_CALL2                178\n#define DUK_OP_CALL3                179\n#define DUK_OP_CALL4                180\n#define DUK_OP_CALL5                181\n#define DUK_OP_CALL6                182\n#define DUK_OP_CALL7                183\n#define DUK_OP_CALL8                184\n#define DUK_OP_CALL9                185\n#define DUK_OP_CALL10               186\n#define DUK_OP_CALL11               187\n#define DUK_OP_CALL12               188\n#define DUK_OP_CALL13               189\n#define DUK_OP_CALL14               190\n#define DUK_OP_CALL15               191\n#define DUK_OP_NEWOBJ               192\n#define DUK_OP_NEWARR               193\n#define DUK_OP_MPUTOBJ              194\n#define DUK_OP_MPUTOBJI             195\n#define DUK_OP_INITSET              196\n#define DUK_OP_INITGET              197\n#define DUK_OP_MPUTARR              198\n#define DUK_OP_MPUTARRI             199\n#define DUK_OP_SETALEN              200\n#define DUK_OP_INITENUM             201\n#define DUK_OP_NEXTENUM             202\n#define DUK_OP_NEWTARGET            203\n#define DUK_OP_DEBUGGER             204\n#define DUK_OP_NOP                  205\n#define DUK_OP_INVALID              206\n#define DUK_OP_UNUSED207            207\n#define DUK_OP_GETPROPC             208\n#define DUK_OP_GETPROPC_RR          208\n#define DUK_OP_GETPROPC_CR          209\n#define DUK_OP_GETPROPC_RC          210\n#define DUK_OP_GETPROPC_CC          211\n#define DUK_OP_UNUSED212            212\n#define DUK_OP_UNUSED213            213\n#define DUK_OP_UNUSED214            214\n#define DUK_OP_UNUSED215            215\n#define DUK_OP_UNUSED216            216\n#define DUK_OP_UNUSED217            217\n#define DUK_OP_UNUSED218            218\n#define DUK_OP_UNUSED219            219\n#define DUK_OP_UNUSED220            220\n#define DUK_OP_UNUSED221            221\n#define DUK_OP_UNUSED222            222\n#define DUK_OP_UNUSED223            223\n#define DUK_OP_UNUSED224            224\n#define DUK_OP_UNUSED225            225\n#define DUK_OP_UNUSED226            226\n#define DUK_OP_UNUSED227            227\n#define DUK_OP_UNUSED228            228\n#define DUK_OP_UNUSED229            229\n#define DUK_OP_UNUSED230            230\n#define DUK_OP_UNUSED231            231\n#define DUK_OP_UNUSED232            232\n#define DUK_OP_UNUSED233            233\n#define DUK_OP_UNUSED234            234\n#define DUK_OP_UNUSED235            235\n#define DUK_OP_UNUSED236            236\n#define DUK_OP_UNUSED237            237\n#define DUK_OP_UNUSED238            238\n#define DUK_OP_UNUSED239            239\n#define DUK_OP_UNUSED240            240\n#define DUK_OP_UNUSED241            241\n#define DUK_OP_UNUSED242            242\n#define DUK_OP_UNUSED243            243\n#define DUK_OP_UNUSED244            244\n#define DUK_OP_UNUSED245            245\n#define DUK_OP_UNUSED246            246\n#define DUK_OP_UNUSED247            247\n#define DUK_OP_UNUSED248            248\n#define DUK_OP_UNUSED249            249\n#define DUK_OP_UNUSED250            250\n#define DUK_OP_UNUSED251            251\n#define DUK_OP_UNUSED252            252\n#define DUK_OP_UNUSED253            253\n#define DUK_OP_UNUSED254            254\n#define DUK_OP_UNUSED255            255\n#define DUK_OP_NONE                 256  /* dummy value used as marker (doesn't fit in 8-bit field) */\n\n/* XXX: Allocate flags from opcode field?  Would take 16 opcode slots\n * but avoids shuffling in more cases.  Maybe not worth it.\n */\n/* DUK_OP_TRYCATCH flags in A. */\n#define DUK_BC_TRYCATCH_FLAG_HAVE_CATCH     (1U << 0)\n#define DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY   (1U << 1)\n#define DUK_BC_TRYCATCH_FLAG_CATCH_BINDING  (1U << 2)\n#define DUK_BC_TRYCATCH_FLAG_WITH_BINDING   (1U << 3)\n\n/* DUK_OP_DECLVAR flags in A; bottom bits are reserved for propdesc flags\n * (DUK_PROPDESC_FLAG_XXX).\n */\n#define DUK_BC_DECLVAR_FLAG_FUNC_DECL       (1U << 4)  /* function declaration */\n\n/* DUK_OP_CALLn flags, part of opcode field.  Three lowest bits must match\n * DUK_CALL_FLAG_xxx directly.\n */\n#define DUK_BC_CALL_FLAG_TAILCALL           (1U << 0)\n#define DUK_BC_CALL_FLAG_CONSTRUCT          (1U << 1)\n#define DUK_BC_CALL_FLAG_CALLED_AS_EVAL     (1U << 2)\n#define DUK_BC_CALL_FLAG_INDIRECT           (1U << 3)\n\n/* Misc constants and helper macros. */\n#define DUK_BC_LDINT_BIAS           (1L << 15)\n#define DUK_BC_LDINTX_SHIFT         16\n#define DUK_BC_JUMP_BIAS            (1L << 23)\n\n#endif  /* DUK_JS_BYTECODE_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_js_call.c",
    "content": "/*\n *  Call handling.\n *\n *  duk_handle_call_unprotected():\n *\n *    - Unprotected call to ECMAScript or Duktape/C function, from native\n *      code or bytecode executor.\n *\n *    - Also handles Ecma-to-Ecma calls which reuses a currently running\n *      executor instance to avoid native recursion.  Call setup is done\n *      normally, but just before calling the bytecode executor a special\n *      return code is used to indicate that a calling executor is reused.\n *\n *    - Also handles tailcalls, i.e. reuse of current duk_activation.\n *\n *    - Also handles setup for initial Duktape.Thread.resume().\n *\n *  duk_handle_safe_call():\n *\n *    - Protected C call within current activation.\n *\n *  setjmp() and local variables have a nasty interaction, see execution.rst;\n *  non-volatile locals modified after setjmp() call are not guaranteed to\n *  keep their value and can cause compiler or compiler version specific\n *  difficult to replicate issues.\n *\n *  See 'execution.rst'.\n */\n\n#include \"duk_internal.h\"\n\n/* XXX: heap->error_not_allowed for success path too? */\n\n/*\n *  Limit check helpers.\n */\n\n/* Check native stack space if DUK_USE_NATIVE_STACK_CHECK() defined. */\nDUK_INTERNAL void duk_native_stack_check(duk_hthread *thr) {\n#if defined(DUK_USE_NATIVE_STACK_CHECK)\n\tif (DUK_USE_NATIVE_STACK_CHECK() != 0) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_NATIVE_STACK_LIMIT);\n\t}\n#else\n\tDUK_UNREF(thr);\n#endif\n}\n\n/* Allow headroom for calls during error augmentation (see GH-191).\n * We allow space for 10 additional recursions, with one extra\n * for, e.g. a print() call at the deepest level, and an extra\n * +1 for protected call wrapping.\n */\n#define DUK__AUGMENT_CALL_RELAX_COUNT  (10 + 2)\n\n/* Stack space required by call handling entry. */\n#define DUK__CALL_HANDLING_REQUIRE_STACK  8\n\nDUK_LOCAL DUK_NOINLINE void duk__call_c_recursion_limit_check_slowpath(duk_hthread *thr) {\n\t/* When augmenting an error, the effective limit is a bit higher.\n\t * Check for it only if the fast path check fails.\n\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tif (thr->heap->augmenting_error) {\n\t\tif (thr->heap->call_recursion_depth < thr->heap->call_recursion_limit + DUK__AUGMENT_CALL_RELAX_COUNT) {\n\t\t\tDUK_D(DUK_DPRINT(\"C recursion limit reached but augmenting error and within relaxed limit\"));\n\t\t\treturn;\n\t\t}\n\t}\n#endif\n\n\tDUK_D(DUK_DPRINT(\"call prevented because C recursion limit reached\"));\n\tDUK_ERROR_RANGE(thr, DUK_STR_NATIVE_STACK_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__call_c_recursion_limit_check(duk_hthread *thr) {\n\tDUK_ASSERT(thr->heap->call_recursion_depth >= 0);\n\tDUK_ASSERT(thr->heap->call_recursion_depth <= thr->heap->call_recursion_limit);\n\n\tduk_native_stack_check(thr);\n\n\t/* This check is forcibly inlined because it's very cheap and almost\n\t * always passes.  The slow path is forcibly noinline.\n\t */\n\tif (DUK_LIKELY(thr->heap->call_recursion_depth < thr->heap->call_recursion_limit)) {\n\t\treturn;\n\t}\n\n\tduk__call_c_recursion_limit_check_slowpath(thr);\n}\n\nDUK_LOCAL DUK_NOINLINE void duk__call_callstack_limit_check_slowpath(duk_hthread *thr) {\n\t/* When augmenting an error, the effective limit is a bit higher.\n\t * Check for it only if the fast path check fails.\n\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tif (thr->heap->augmenting_error) {\n\t\tif (thr->callstack_top < DUK_USE_CALLSTACK_LIMIT + DUK__AUGMENT_CALL_RELAX_COUNT) {\n\t\t\tDUK_D(DUK_DPRINT(\"call stack limit reached but augmenting error and within relaxed limit\"));\n\t\t\treturn;\n\t\t}\n\t}\n#endif\n\n\t/* XXX: error message is a bit misleading: we reached a recursion\n\t * limit which is also essentially the same as a C callstack limit\n\t * (except perhaps with some relaxed threading assumptions).\n\t */\n\tDUK_D(DUK_DPRINT(\"call prevented because call stack limit reached\"));\n\tDUK_ERROR_RANGE(thr, DUK_STR_CALLSTACK_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__call_callstack_limit_check(duk_hthread *thr) {\n\t/* This check is forcibly inlined because it's very cheap and almost\n\t * always passes.  The slow path is forcibly noinline.\n\t */\n\tif (DUK_LIKELY(thr->callstack_top < DUK_USE_CALLSTACK_LIMIT)) {\n\t\treturn;\n\t}\n\n\tduk__call_callstack_limit_check_slowpath(thr);\n}\n\n/*\n *  Interrupt counter fixup (for development only).\n */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__interrupt_fixup(duk_hthread *thr, duk_hthread *entry_curr_thread) {\n\t/* Currently the bytecode executor and executor interrupt\n\t * instruction counts are off because we don't execute the\n\t * interrupt handler when we're about to exit from the initial\n\t * user call into Duktape.\n\t *\n\t * If we were to execute the interrupt handler here, the counts\n\t * would match.  You can enable this block manually to check\n\t * that this is the case.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n#if defined(DUK_USE_INTERRUPT_DEBUG_FIXUP)\n\tif (entry_curr_thread == NULL) {\n\t\tthr->interrupt_init = thr->interrupt_init - thr->interrupt_counter;\n\t\tthr->heap->inst_count_interrupt += thr->interrupt_init;\n\t\tDUK_DD(DUK_DDPRINT(\"debug test: updated interrupt count on exit to \"\n\t\t                   \"user code, instruction counts: executor=%ld, interrupt=%ld\",\n\t\t                   (long) thr->heap->inst_count_exec, (long) thr->heap->inst_count_interrupt));\n\t\tDUK_ASSERT(thr->heap->inst_count_exec == thr->heap->inst_count_interrupt);\n\t}\n#else\n\tDUK_UNREF(thr);\n\tDUK_UNREF(entry_curr_thread);\n#endif\n}\n#endif\n\n/*\n *  Arguments object creation.\n *\n *  Creating arguments objects involves many small details, see E5 Section\n *  10.6 for the specific requirements.  Much of the arguments object exotic\n *  behavior is implemented in duk_hobject_props.c, and is enabled by the\n *  object flag DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS.\n */\n\nDUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,\n                                            duk_hobject *func,\n                                            duk_hobject *varenv,\n                                            duk_idx_t idx_args) {\n\tduk_hobject *arg;          /* 'arguments' */\n\tduk_hobject *formals;      /* formals for 'func' (may be NULL if func is a C function) */\n\tduk_idx_t i_arg;\n\tduk_idx_t i_map;\n\tduk_idx_t i_mappednames;\n\tduk_idx_t i_formals;\n\tduk_idx_t i_argbase;\n\tduk_idx_t n_formals;\n\tduk_idx_t idx;\n\tduk_idx_t num_stack_args;\n\tduk_bool_t need_map;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_NONBOUND_FUNCTION(func));\n\tDUK_ASSERT(varenv != NULL);\n\n\t/* [ ... func this arg1(@idx_args) ... argN envobj ]\n\t * [ arg1(@idx_args) ... argN envobj ] (for tailcalls)\n\t */\n\n\tneed_map = 0;\n\n\ti_argbase = idx_args;\n\tnum_stack_args = duk_get_top(thr) - i_argbase - 1;\n\tDUK_ASSERT(i_argbase >= 0);\n\tDUK_ASSERT(num_stack_args >= 0);\n\n\tformals = (duk_hobject *) duk_hobject_get_formals(thr, (duk_hobject *) func);\n\tif (formals) {\n\t\tn_formals = (duk_idx_t) ((duk_harray *) formals)->length;\n\t\tduk_push_hobject(thr, formals);\n\t} else {\n\t\t/* This shouldn't happen without tampering of internal\n\t\t * properties: if a function accesses 'arguments', _Formals\n\t\t * is kept.  Check for the case anyway in case internal\n\t\t * properties have been modified manually.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"_Formals is undefined when creating arguments, use n_formals == 0\"));\n\t\tn_formals = 0;\n\t\tduk_push_undefined(thr);\n\t}\n\ti_formals = duk_require_top_index(thr);\n\n\tDUK_ASSERT(n_formals >= 0);\n\tDUK_ASSERT(formals != NULL || n_formals == 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"func=%!O, formals=%!O, n_formals=%ld\",\n\t                     (duk_heaphdr *) func, (duk_heaphdr *) formals,\n\t                     (long) n_formals));\n\n\t/* [ ... formals ] */\n\n\t/*\n\t *  Create required objects:\n\t *    - 'arguments' object: array-like, but not an array\n\t *    - 'map' object: internal object, tied to 'arguments' (bare)\n\t *    - 'mappedNames' object: temporary value used during construction (bare)\n\t */\n\n\targ = duk_push_object_helper(thr,\n\t                             DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                             DUK_HOBJECT_FLAG_FASTREFS |\n\t                             DUK_HOBJECT_FLAG_ARRAY_PART |\n\t                             DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARGUMENTS),\n\t                             DUK_BIDX_OBJECT_PROTOTYPE);\n\tDUK_ASSERT(arg != NULL);\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              -1);  /* no prototype */\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              -1);  /* no prototype */\n\ti_arg = duk_get_top(thr) - 3;\n\ti_map = i_arg + 1;\n\ti_mappednames = i_arg + 2;\n\tDUK_ASSERT(!duk_is_bare_object(thr, -3));  /* arguments */\n\tDUK_ASSERT(duk_is_bare_object(thr, -2));  /* map */\n\tDUK_ASSERT(duk_is_bare_object(thr, -1));  /* mappedNames */\n\n\t/* [ ... formals arguments map mappedNames ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"created arguments related objects: \"\n\t                     \"arguments at index %ld -> %!O \"\n\t                     \"map at index %ld -> %!O \"\n\t                     \"mappednames at index %ld -> %!O\",\n\t                     (long) i_arg, (duk_heaphdr *) duk_get_hobject(thr, i_arg),\n\t                     (long) i_map, (duk_heaphdr *) duk_get_hobject(thr, i_map),\n\t                     (long) i_mappednames, (duk_heaphdr *) duk_get_hobject(thr, i_mappednames)));\n\n\t/*\n\t *  Init arguments properties, map, etc.\n\t */\n\n\tduk_push_int(thr, num_stack_args);\n\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_WC);\n\n\t/*\n\t *  Init argument related properties.\n\t */\n\n\t/* step 11 */\n\tidx = num_stack_args - 1;\n\twhile (idx >= 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arg idx %ld, argbase=%ld, argidx=%ld\",\n\t\t                     (long) idx, (long) i_argbase, (long) (i_argbase + idx)));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"define arguments[%ld]=arg\", (long) idx));\n\t\tduk_dup(thr, i_argbase + idx);\n\t\tduk_xdef_prop_index_wec(thr, i_arg, (duk_uarridx_t) idx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"defined arguments[%ld]=arg\", (long) idx));\n\n\t\t/* step 11.c is relevant only if non-strict (checked in 11.c.ii) */\n\t\tif (!DUK_HOBJECT_HAS_STRICT(func) && idx < n_formals) {\n\t\t\tDUK_ASSERT(formals != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"strict function, index within formals (%ld < %ld)\",\n\t\t\t                     (long) idx, (long) n_formals));\n\n\t\t\tduk_get_prop_index(thr, i_formals, (duk_uarridx_t) idx);\n\t\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\n\t\t\tduk_dup_top(thr);  /* [ ... name name ] */\n\n\t\t\tif (!duk_has_prop(thr, i_mappednames)) {\n\t\t\t\t/* steps 11.c.ii.1 - 11.c.ii.4, but our internal book-keeping\n\t\t\t\t * differs from the reference model\n\t\t\t\t */\n\n\t\t\t\t/* [ ... name ] */\n\n\t\t\t\tneed_map = 1;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"set mappednames[%s]=%ld\",\n\t\t\t\t                     (const char *) duk_get_string(thr, -1),\n\t\t\t\t                     (long) idx));\n\t\t\t\tduk_dup_top(thr);                      /* name */\n\t\t\t\t(void) duk_push_uint_to_hstring(thr, (duk_uint_t) idx);  /* index */\n\t\t\t\tduk_xdef_prop_wec(thr, i_mappednames);  /* out of spec, must be configurable */\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"set map[%ld]=%s\",\n\t\t\t\t                     (long) idx,\n\t\t\t\t                     duk_get_string(thr, -1)));\n\t\t\t\tduk_dup_top(thr);         /* name */\n\t\t\t\tduk_xdef_prop_index_wec(thr, i_map, (duk_uarridx_t) idx);  /* out of spec, must be configurable */\n\t\t\t} else {\n\t\t\t\t/* duk_has_prop() popped the second 'name' */\n\t\t\t}\n\n\t\t\t/* [ ... name ] */\n\t\t\tduk_pop(thr);  /* pop 'name' */\n\t\t}\n\n\t\tidx--;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"actual arguments processed\"));\n\n\t/* step 12 */\n\tif (need_map) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"adding 'map' and 'varenv' to arguments object\"));\n\n\t\t/* should never happen for a strict callee */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(func));\n\n\t\tduk_dup(thr, i_map);\n\t\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_INT_MAP, DUK_PROPDESC_FLAGS_NONE);  /* out of spec, don't care */\n\n\t\t/* The variable environment for magic variable bindings needs to be\n\t\t * given by the caller and recorded in the arguments object.\n\t\t *\n\t\t * See E5 Section 10.6, the creation of setters/getters.\n\t\t *\n\t\t * The variable environment also provides access to the callee, so\n\t\t * an explicit (internal) callee property is not needed.\n\t\t */\n\n\t\tduk_push_hobject(thr, varenv);\n\t\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_INT_VARENV, DUK_PROPDESC_FLAGS_NONE);  /* out of spec, don't care */\n\t}\n\n\t/* steps 13-14 */\n\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t/* Callee/caller are throwers and are not deletable etc.  They\n\t\t * could be implemented as virtual properties, but currently\n\t\t * there is no support for virtual properties which are accessors\n\t\t * (only plain virtual properties).  This would not be difficult\n\t\t * to change in duk_hobject_props, but we can make the throwers\n\t\t * normal, concrete properties just as easily.\n\t\t *\n\t\t * Note that the specification requires that the *same* thrower\n\t\t * built-in object is used here!  See E5 Section 10.6 main\n\t\t * algoritm, step 14, and Section 13.2.3 which describes the\n\t\t * thrower.  See test case test-arguments-throwers.js.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"strict function, setting caller/callee to throwers\"));\n\n\t\t/* In ES2017 .caller is no longer set at all. */\n\t\tduk_xdef_prop_stridx_thrower(thr, i_arg, DUK_STRIDX_CALLEE);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-strict function, setting callee to actual value\"));\n\t\tduk_push_hobject(thr, func);\n\t\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_CALLEE, DUK_PROPDESC_FLAGS_WC);\n\t}\n\n\t/* set exotic behavior only after we're done */\n\tif (need_map) {\n\t\t/* Exotic behaviors are only enabled for arguments objects\n\t\t * which have a parameter map (see E5 Section 10.6 main\n\t\t * algorithm, step 12).\n\t\t *\n\t\t * In particular, a non-strict arguments object with no\n\t\t * mapped formals does *NOT* get exotic behavior, even\n\t\t * for e.g. \"caller\" property.  This seems counterintuitive\n\t\t * but seems to be the case.\n\t\t */\n\n\t\t/* cannot be strict (never mapped variables) */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(func));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"enabling exotic behavior for arguments object\"));\n\t\tDUK_HOBJECT_SET_EXOTIC_ARGUMENTS(arg);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"not enabling exotic behavior for arguments object\"));\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"final arguments related objects: \"\n\t                     \"arguments at index %ld -> %!O \"\n\t                     \"map at index %ld -> %!O \"\n\t                     \"mappednames at index %ld -> %!O\",\n\t                     (long) i_arg, (duk_heaphdr *) duk_get_hobject(thr, i_arg),\n\t                     (long) i_map, (duk_heaphdr *) duk_get_hobject(thr, i_map),\n\t                     (long) i_mappednames, (duk_heaphdr *) duk_get_hobject(thr, i_mappednames)));\n\n\t/* [ args(n) envobj formals arguments map mappednames ] */\n\n\tduk_pop_2(thr);\n\tduk_remove_m2(thr);\n\n\t/* [ args(n) envobj arguments ] */\n}\n\n/* Helper for creating the arguments object and adding it to the env record\n * on top of the value stack.\n */\nDUK_LOCAL void duk__handle_createargs_for_call(duk_hthread *thr,\n                                               duk_hobject *func,\n                                               duk_hobject *env,\n                                               duk_idx_t idx_args) {\n\tDUK_DDD(DUK_DDDPRINT(\"creating arguments object for function call\"));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_CREATEARGS(func));\n\n\t/* [ ... arg1 ... argN envobj ] */\n\n\tduk__create_arguments_object(thr,\n\t                             func,\n\t                             env,\n\t                             idx_args);\n\n\t/* [ ... arg1 ... argN envobj argobj ] */\n\n\tduk_xdef_prop_stridx_short(thr,\n\t                           -2,\n\t                           DUK_STRIDX_LC_ARGUMENTS,\n\t                           DUK_HOBJECT_HAS_STRICT(func) ? DUK_PROPDESC_FLAGS_E :   /* strict: non-deletable, non-writable */\n\t                                                          DUK_PROPDESC_FLAGS_WE);  /* non-strict: non-deletable, writable */\n\t/* [ ... arg1 ... argN envobj ] */\n}\n\n/*\n *  Helpers for constructor call handling.\n *\n *  There are two [[Construct]] operations in the specification:\n *\n *    - E5 Section 13.2.2: for Function objects\n *    - E5 Section 15.3.4.5.2: for \"bound\" Function objects\n *\n *  The chain of bound functions is resolved in Section 15.3.4.5.2,\n *  with arguments \"piling up\" until the [[Construct]] internal\n *  method is called on the final, actual Function object.  Note\n *  that the \"prototype\" property is looked up *only* from the\n *  final object, *before* calling the constructor.\n *\n *  Since Duktape 2.2 bound functions are represented with the\n *  duk_hboundfunc internal type, and bound function chains are\n *  collapsed when a bound function is created.  As a result, the\n *  direct target of a duk_hboundfunc is always non-bound and the\n *  this/argument lists have been resolved.\n *\n *  When constructing new Array instances, an unnecessary object is\n *  created and discarded now: the standard [[Construct]] creates an\n *  object, and calls the Array constructor.  The Array constructor\n *  returns an Array instance, which is used as the result value for\n *  the \"new\" operation; the object created before the Array constructor\n *  call is discarded.\n *\n *  This would be easy to fix, e.g. by knowing that the Array constructor\n *  will always create a replacement object and skip creating the fallback\n *  object in that case.\n */\n\n/* Update default instance prototype for constructor call. */\nDUK_LOCAL void duk__update_default_instance_proto(duk_hthread *thr, duk_idx_t idx_func) {\n\tduk_hobject *proto;\n\tduk_hobject *fallback;\n\n\tDUK_ASSERT(duk_is_constructable(thr, idx_func));\n\n\tduk_get_prop_stridx_short(thr, idx_func, DUK_STRIDX_PROTOTYPE);\n\tproto = duk_get_hobject(thr, -1);\n\tif (proto == NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"constructor has no 'prototype' property, or value not an object \"\n\t\t                     \"-> leave standard Object prototype as fallback prototype\"));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"constructor has 'prototype' property with object value \"\n\t\t                     \"-> set fallback prototype to that value: %!iO\", (duk_heaphdr *) proto));\n\t\t/* Original fallback (default instance) is untouched when\n\t\t * resolving bound functions etc.\n\t\t */\n\t\tfallback = duk_known_hobject(thr, idx_func + 1);\n\t\tDUK_ASSERT(fallback != NULL);\n\t\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, fallback, proto);\n\t}\n\tduk_pop(thr);\n}\n\n/* Postprocess: return value special handling, error augmentation. */\nDUK_INTERNAL void duk_call_construct_postprocess(duk_hthread *thr, duk_small_uint_t proxy_invariant) {\n\t/* Use either fallback (default instance) or retval depending\n\t * on retval type.  Needs to be called before unwind because\n\t * the default instance is read from the current (immutable)\n\t * 'this' binding.\n\t *\n\t * For Proxy 'construct' calls the return value must be an\n\t * Object (we accept object-like values like buffers and\n\t * lightfuncs too).  If not, TypeError.\n\t */\n\tif (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT |\n\t                                 DUK_TYPE_MASK_BUFFER |\n\t                                 DUK_TYPE_MASK_LIGHTFUNC)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"replacement value\"));\n\t} else {\n\t\tif (DUK_UNLIKELY(proxy_invariant != 0U)) {\n\t\t\t/* Proxy 'construct' return value invariant violated. */\n\t\t\tDUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\t/* XXX: direct value stack access */\n\t\tduk_pop(thr);\n\t\tduk_push_this(thr);\n\t}\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\t/* Augment created errors upon creation, not when they are thrown or\n\t * rethrown.  __FILE__ and __LINE__ are not desirable here; the call\n\t * stack reflects the caller which is correct.  Skip topmost, unwound\n\t * activation when creating a traceback.  If thr->ptr_curr_pc was !=\n\t * NULL we'd need to sync the current PC so that the traceback comes\n\t * out right; however it is always synced here so just assert for it.\n\t */\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\tduk_err_augment_error_create(thr, thr, NULL, 0, DUK_AUGMENT_FLAG_NOBLAME_FILELINE |\n\t                                                DUK_AUGMENT_FLAG_SKIP_ONE);\n#endif\n}\n\n/*\n *  Helper for handling a bound function when a call is being made.\n *\n *  Assumes that bound function chains have been \"collapsed\" so that either\n *  the target is non-bound or there is one bound function that points to a\n *  nonbound target.\n *\n *  Prepends the bound arguments to the value stack (at idx_func + 2).\n *  The 'this' binding is also updated if necessary (at idx_func + 1).\n *  Note that for constructor calls the 'this' binding is never updated by\n *  [[BoundThis]].\n */\n\nDUK_LOCAL void duk__handle_bound_chain_for_call(duk_hthread *thr,\n                                                duk_idx_t idx_func,\n                                                duk_bool_t is_constructor_call) {\n\tduk_tval *tv_func;\n\tduk_hobject *func;\n\tduk_idx_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* On entry, item at idx_func is a bound, non-lightweight function,\n\t * but we don't rely on that below.\n\t */\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\ttv_func = duk_require_tval(thr, idx_func);\n\tDUK_ASSERT(tv_func != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\n\t\t/* XXX: separate helper function, out of fast path? */\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {\n\t\t\tduk_hboundfunc *h_bound;\n\t\t\tduk_tval *tv_args;\n\t\t\tduk_tval *tv_gap;\n\n\t\t\th_bound = (duk_hboundfunc *) (void *) func;\n\t\t\ttv_args = h_bound->args;\n\t\t\tlen = h_bound->nargs;\n\t\t\tDUK_ASSERT(len == 0 || tv_args != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"bound function encountered, ptr=%p: %!T\",\n\t\t\t                     (void *) DUK_TVAL_GET_OBJECT(tv_func), tv_func));\n\n\t\t\t/* [ ... func this arg1 ... argN ] */\n\n\t\t\tif (is_constructor_call) {\n\t\t\t\t/* See: tests/ecmascript/test-spec-bound-constructor.js */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"constructor call: don't update this binding\"));\n\t\t\t} else {\n\t\t\t\t/* XXX: duk_replace_tval */\n\t\t\t\tduk_push_tval(thr, &h_bound->this_binding);\n\t\t\t\tduk_replace(thr, idx_func + 1);  /* idx_this = idx_func + 1 */\n\t\t\t}\n\n\t\t\t/* [ ... func this arg1 ... argN ] */\n\n\t\t\tduk_require_stack(thr, len);\n\n\t\t\ttv_gap = duk_reserve_gap(thr, idx_func + 2, len);\n\t\t\tduk_copy_tvals_incref(thr, tv_gap, tv_args, (duk_size_t) len);\n\n\t\t\t/* [ ... func this <bound args> arg1 ... argN ] */\n\n\t\t\tduk_push_tval(thr, &h_bound->target);\n\t\t\tduk_replace(thr, idx_func);  /* replace in stack */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"bound function handled, idx_func=%ld, curr func=%!T\",\n\t\t\t                     (long) idx_func, duk_get_tval(thr, idx_func)));\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {\n\t\t/* Lightweight function: never bound, so terminate. */\n\t\t;\n\t} else {\n\t\t/* Shouldn't happen, so ugly error is enough. */\n\t\tDUK_ERROR_INTERNAL(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\tDUK_DDD(DUK_DDDPRINT(\"final non-bound function is: %!T\", duk_get_tval(thr, idx_func)));\n\n#if defined(DUK_USE_ASSERTIONS)\n\ttv_func = duk_require_tval(thr, idx_func);\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func) || DUK_TVAL_IS_OBJECT(tv_func));\n\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func) ||\n\t\t           DUK_HOBJECT_HAS_NATFUNC(func) ||\n\t\t           DUK_HOBJECT_IS_PROXY(func));\n\t}\n#endif\n}\n\n/*\n *  Helper for inline handling of .call(), .apply(), and .construct().\n */\n\nDUK_LOCAL duk_bool_t duk__handle_specialfuncs_for_call(duk_hthread *thr, duk_idx_t idx_func, duk_hobject *func, duk_small_uint_t *call_flags, duk_bool_t first) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_c_function natfunc;\n#endif\n\tduk_tval *tv_args;\n\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT((*call_flags & DUK_CALL_FLAG_CONSTRUCT) == 0);  /* Caller. */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tnatfunc = ((duk_hnatfunc *) func)->func;\n\tDUK_ASSERT(natfunc != NULL);\n#endif\n\n\t/* On every round of function resolution at least target function and\n\t * 'this' binding are set.  We can assume that here, and must guarantee\n\t * it on exit.  Value stack reserve is extended for bound function and\n\t * .apply() unpacking so we don't need to extend it here when we need a\n\t * few slots.\n\t */\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\t/* Handle native 'eval' specially.  A direct eval check is only made\n\t * for the first resolution attempt; e.g. a bound eval call is -not-\n\t * a direct eval call.\n\t */\n\tif (DUK_UNLIKELY(((duk_hnatfunc *) func)->magic == 15)) {\n\t\t/* For now no special handling except for direct eval\n\t\t * detection.\n\t\t */\n\t\tDUK_ASSERT(((duk_hnatfunc *) func)->func == duk_bi_global_object_eval);\n\t\tif (first && (*call_flags & DUK_CALL_FLAG_CALLED_AS_EVAL)) {\n\t\t\t*call_flags = (*call_flags & ~DUK_CALL_FLAG_CALLED_AS_EVAL) | DUK_CALL_FLAG_DIRECT_EVAL;\n\t\t}\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\t\treturn 1;  /* stop resolving */\n\t}\n\n\t/* Handle special functions based on the DUK_HOBJECT_FLAG_SPECIAL_CALL\n\t * flag; their magic value is used for switch-case.\n\t *\n\t * NOTE: duk_unpack_array_like() reserves value stack space\n\t * for the result values (unlike most other value stack calls).\n\t */\n\tswitch (((duk_hnatfunc *) func)->magic) {\n\tcase 0: {  /* 0=Function.prototype.call() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Function.prototype.call()  [removed]\n\t\t * idx_func + 1: this binding for .call (target function)\n\t\t * idx_func + 2: 1st argument to .call, desired 'this' binding\n\t\t * idx_func + 3: 2nd argument to .call, desired 1st argument for ultimate target\n\t\t * ...\n\t\t *\n\t\t * Remove idx_func + 0 to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding\n\t\t * idx_func + 2: call arguments\n\t\t * ...\n\t\t */\n\t\tDUK_ASSERT(natfunc == duk_bi_function_prototype_call);\n\t\tduk_remove_unsafe(thr, idx_func);\n\t\ttv_args = thr->valstack_bottom + idx_func + 2;\n\t\tif (thr->valstack_top < tv_args) {\n\t\t\tDUK_ASSERT(tv_args <= thr->valstack_end);\n\t\t\tthr->valstack_top = tv_args;  /* at least target function and 'this' binding present */\n\t\t}\n\t\tbreak;\n\t}\n\tcase 1: {  /* 1=Function.prototype.apply() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Function.prototype.apply()  [removed]\n\t\t * idx_func + 1: this binding for .apply (target function)\n\t\t * idx_func + 2: 1st argument to .apply, desired 'this' binding\n\t\t * idx_func + 3: 2nd argument to .apply, argArray\n\t\t * [anything after this MUST be ignored]\n\t\t *\n\t\t * Remove idx_func + 0 and unpack the argArray to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding\n\t\t * idx_func + 2: call arguments\n\t\t * ...\n\t\t */\n\t\tDUK_ASSERT(natfunc == duk_bi_function_prototype_apply);\n\t\tduk_remove_unsafe(thr, idx_func);\n\t\tgoto apply_shared;\n\t}\n#if defined(DUK_USE_REFLECT_BUILTIN)\n\tcase 2: {  /* 2=Reflect.apply() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Reflect.apply()  [removed]\n\t\t * idx_func + 1: this binding for .apply (ignored, usually Reflect)  [removed]\n\t\t * idx_func + 2: 1st argument to .apply, target function\n\t\t * idx_func + 3: 2nd argument to .apply, desired 'this' binding\n\t\t * idx_func + 4: 3rd argument to .apply, argArray\n\t\t * [anything after this MUST be ignored]\n\t\t *\n\t\t * Remove idx_func + 0 and idx_func + 1, and unpack the argArray to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding\n\t\t * idx_func + 2: call arguments\n\t\t * ...\n\t\t */\n\t\tDUK_ASSERT(natfunc == duk_bi_reflect_apply);\n\t\tduk_remove_n_unsafe(thr, idx_func, 2);\n\t\tgoto apply_shared;\n\t}\n\tcase 3: {  /* 3=Reflect.construct() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Reflect.construct()  [removed]\n\t\t * idx_func + 1: this binding for .construct (ignored, usually Reflect)  [removed]\n\t\t * idx_func + 2: 1st argument to .construct, target function\n\t\t * idx_func + 3: 2nd argument to .construct, argArray\n\t\t * idx_func + 4: 3rd argument to .construct, newTarget\n\t\t * [anything after this MUST be ignored]\n\t\t *\n\t\t * Remove idx_func + 0 and idx_func + 1, unpack the argArray,\n\t\t * and insert default instance (prototype not yet updated), to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding (default instance)\n\t\t * idx_func + 2: constructor call arguments\n\t\t * ...\n\t\t *\n\t\t * Call flags must be updated to reflect the fact that we're\n\t\t * now dealing with a constructor call, and e.g. the 'this'\n\t\t * binding cannot be overwritten if the target is bound.\n\t\t *\n\t\t * newTarget is checked but not yet passed onwards.\n\t\t */\n\n\t\tduk_idx_t top;\n\n\t\tDUK_ASSERT(natfunc == duk_bi_reflect_construct);\n\t\t*call_flags |= DUK_CALL_FLAG_CONSTRUCT;\n\t\tduk_remove_n_unsafe(thr, idx_func, 2);\n\t\ttop = duk_get_top(thr);\n\t\tif (!duk_is_constructable(thr, idx_func)) {\n\t\t\t/* Target constructability must be checked before\n\t\t\t * unpacking argArray (which may cause side effects).\n\t\t\t * Just return; caller will throw the error.\n\t\t\t */\n\t\t\tduk_set_top_unsafe(thr, idx_func + 2);  /* satisfy asserts */\n\t\t\tbreak;\n\t\t}\n\t\tduk_push_object(thr);\n\t\tduk_insert(thr, idx_func + 1);  /* default instance */\n\n\t\t/* [ ... func default_instance argArray newTarget? ] */\n\n\t\ttop = duk_get_top(thr);\n\t\tif (top < idx_func + 3) {\n\t\t\t/* argArray is a mandatory argument for Reflect.construct(). */\n\t\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tif (top > idx_func + 3) {\n\t\t\tif (!duk_strict_equals(thr, idx_func, idx_func + 3)) {\n\t\t\t\t/* XXX: [[Construct]] newTarget currently unsupported */\n\t\t\t\tDUK_ERROR_UNSUPPORTED(thr);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t\tduk_set_top_unsafe(thr, idx_func + 3);  /* remove any args beyond argArray */\n\t\t}\n\t\tDUK_ASSERT(duk_get_top(thr) == idx_func + 3);\n\t\tDUK_ASSERT(duk_is_valid_index(thr, idx_func + 2));\n\t\t(void) duk_unpack_array_like(thr, idx_func + 2);  /* XXX: should also remove target to be symmetric with duk_pack()? */\n\t\tduk_remove(thr, idx_func + 2);\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\t\tbreak;\n\t}\n#endif  /* DUK_USE_REFLECT_BUILTIN */\n\tdefault: {\n\t\tDUK_ASSERT(0);\n\t\tDUK_UNREACHABLE();\n\t}\n\t}\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\treturn 0;  /* keep resolving */\n\n apply_shared:\n\ttv_args = thr->valstack_bottom + idx_func + 2;\n\tif (thr->valstack_top <= tv_args) {\n\t\tDUK_ASSERT(tv_args <= thr->valstack_end);\n\t\tthr->valstack_top = tv_args;  /* at least target func and 'this' binding present */\n\t\t/* No need to check for argArray. */\n\t} else {\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 3);  /* idx_func + 2 covered above */\n\t\tif (thr->valstack_top > tv_args + 1) {\n\t\t\tduk_set_top_unsafe(thr, idx_func + 3);  /* remove any args beyond argArray */\n\t\t}\n\t\tDUK_ASSERT(duk_is_valid_index(thr, idx_func + 2));\n\t\tif (!duk_is_callable(thr, idx_func)) {\n\t\t\t/* Avoid unpack side effects if the target isn't callable.\n\t\t\t * Calling code will throw the actual error.\n\t\t\t */\n\t\t} else {\n\t\t\t(void) duk_unpack_array_like(thr, idx_func + 2);\n\t\t\tduk_remove(thr, idx_func + 2);\n\t\t}\n\t}\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\treturn 0;  /* keep resolving */\n}\n\n/*\n *  Helper for Proxy handling.\n */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_LOCAL void duk__handle_proxy_for_call(duk_hthread *thr, duk_idx_t idx_func, duk_hproxy *h_proxy, duk_small_uint_t *call_flags) {\n\tduk_bool_t rc;\n\n\t/* Value stack:\n\t * idx_func + 0: Proxy object\n\t * idx_func + 1: this binding for call\n\t * idx_func + 2: 1st argument for call\n\t * idx_func + 3: 2nd argument for call\n\t * ...\n\t *\n\t * If Proxy doesn't have a trap for the call ('apply' or 'construct'),\n\t * replace Proxy object with target object.\n\t *\n\t * If we're dealing with a normal call and the Proxy has an 'apply'\n\t * trap, manipulate value stack to:\n\t *\n\t * idx_func + 0: trap\n\t * idx_func + 1: Proxy's handler\n\t * idx_func + 2: Proxy's target\n\t * idx_func + 3: this binding for call (from idx_func + 1)\n\t * idx_func + 4: call arguments packed to an array\n\t *\n\t * If we're dealing with a constructor call and the Proxy has a\n\t * 'construct' trap, manipulate value stack to:\n\t *\n\t * idx_func + 0: trap\n\t * idx_func + 1: Proxy's handler\n\t * idx_func + 2: Proxy's target\n\t * idx_func + 3: call arguments packed to an array\n\t * idx_func + 4: newTarget == Proxy object here\n\t *\n\t * As we don't yet have proper newTarget support, the newTarget at\n\t * idx_func + 3 is just the original constructor being called, i.e.\n\t * the Proxy object (not the target).  Note that the default instance\n\t * (original 'this' binding) is dropped and ignored.\n\t */\n\n\tduk_push_hobject(thr, h_proxy->handler);\n\trc = duk_get_prop_stridx_short(thr, -1, (*call_flags & DUK_CALL_FLAG_CONSTRUCT) ? DUK_STRIDX_CONSTRUCT : DUK_STRIDX_APPLY);\n\tif (rc == 0) {\n\t\t/* Not found, continue to target.  If this is a construct\n\t\t * call, update default instance prototype using the Proxy,\n\t\t * not the target.\n\t\t */\n\t\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\t\tif (!(*call_flags & DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED)) {\n\t\t\t\t*call_flags |= DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED;\n\t\t\t\tduk__update_default_instance_proto(thr, idx_func);\n\t\t\t}\n\t\t}\n\t\tduk_pop_2(thr);\n\t\tduk_push_hobject(thr, h_proxy->target);\n\t\tduk_replace(thr, idx_func);\n\t\treturn;\n\t}\n\n\t/* Here we must be careful not to replace idx_func while\n\t * h_proxy is still needed, otherwise h_proxy may become\n\t * dangling.  This could be improved e.g. using a\n\t * duk_pack_slice() with a freeform slice.\n\t */\n\n\t/* Here:\n\t * idx_func + 0: Proxy object\n\t * idx_func + 1: this binding for call\n\t * idx_func + 2: 1st argument for call\n\t * idx_func + 3: 2nd argument for call\n\t * ...\n\t * idx_func + N: handler\n\t * idx_func + N + 1: trap\n\t */\n\n\tduk_insert(thr, idx_func + 1);\n\tduk_insert(thr, idx_func + 2);\n\tduk_push_hobject(thr, h_proxy->target);\n\tduk_insert(thr, idx_func + 3);\n\tduk_pack(thr, duk_get_top(thr) - (idx_func + 5));\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\t/* Here:\n\t * idx_func + 0: Proxy object\n\t * idx_func + 1: trap\n\t * idx_func + 2: Proxy's handler\n\t * idx_func + 3: Proxy's target\n\t * idx_func + 4: this binding for call\n\t * idx_func + 5: arguments array\n\t */\n\tDUK_ASSERT(duk_get_top(thr) == idx_func + 6);\n\n\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\t*call_flags |= DUK_CALL_FLAG_CONSTRUCT_PROXY;  /* Enable 'construct' trap return invariant check. */\n\t\t*call_flags &= ~(DUK_CALL_FLAG_CONSTRUCT);     /* Resume as non-constructor call to the trap. */\n\n\t\t/* 'apply' args: target, thisArg, argArray\n\t\t * 'construct' args: target, argArray, newTarget\n\t\t */\n\t\tduk_remove(thr, idx_func + 4);\n\t\tduk_push_hobject(thr, (duk_hobject *) h_proxy);\n\t}\n\n\t/* Finalize value stack layout by removing Proxy reference. */\n\tduk_remove(thr, idx_func);\n\th_proxy = NULL;  /* invalidated */\n\tDUK_ASSERT(duk_get_top(thr) == idx_func + 5);\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n/*\n *  Helper for setting up var_env and lex_env of an activation,\n *  assuming it does NOT have the DUK_HOBJECT_FLAG_NEWENV flag.\n */\n\nDUK_LOCAL void duk__handle_oldenv_for_call(duk_hthread *thr,\n                                           duk_hobject *func,\n                                           duk_activation *act) {\n\tduk_hcompfunc *f;\n\tduk_hobject *h_lex;\n\tduk_hobject *h_var;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV(func));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(func));\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(func));\n\tDUK_UNREF(thr);\n\n\tf = (duk_hcompfunc *) func;\n\th_lex = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f);\n\th_var = DUK_HCOMPFUNC_GET_VARENV(thr->heap, f);\n\tDUK_ASSERT(h_lex != NULL);  /* Always true for closures (not for templates) */\n\tDUK_ASSERT(h_var != NULL);\n\tact->lex_env = h_lex;\n\tact->var_env = h_var;\n\tDUK_HOBJECT_INCREF(thr, h_lex);\n\tDUK_HOBJECT_INCREF(thr, h_var);\n}\n\n/*\n *  Helper for updating callee 'caller' property.\n */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\nDUK_LOCAL void duk__update_func_caller_prop(duk_hthread *thr, duk_hobject *func) {\n\tduk_tval *tv_caller;\n\tduk_hobject *h_tmp;\n\tduk_activation *act_callee;\n\tduk_activation *act_caller;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));  /* bound chain resolved */\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\n\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t/* Strict functions don't get their 'caller' updated. */\n\t\treturn;\n\t}\n\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tact_callee = thr->callstack_curr;\n\tDUK_ASSERT(act_callee != NULL);\n\tact_caller = (thr->callstack_top >= 2 ? act_callee->parent : NULL);\n\n\t/* XXX: check .caller writability? */\n\n\t/* Backup 'caller' property and update its value. */\n\ttv_caller = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, func, DUK_STRIDX_CALLER);\n\tif (tv_caller) {\n\t\t/* If caller is global/eval code, 'caller' should be set to\n\t\t * 'null'.\n\t\t *\n\t\t * XXX: there is no exotic flag to infer this correctly now.\n\t\t * The NEWENV flag is used now which works as intended for\n\t\t * everything (global code, non-strict eval code, and functions)\n\t\t * except strict eval code.  Bound functions are never an issue\n\t\t * because 'func' has been resolved to a non-bound function.\n\t\t */\n\n\t\tif (act_caller != NULL) {\n\t\t\t/* act_caller->func may be NULL in some finalization cases,\n\t\t\t * just treat like we don't know the caller.\n\t\t\t */\n\t\t\tif (act_caller->func && !DUK_HOBJECT_HAS_NEWENV(act_caller->func)) {\n\t\t\t\t/* Setting to NULL causes 'caller' to be set to\n\t\t\t\t * 'null' as desired.\n\t\t\t\t */\n\t\t\t\tact_caller = NULL;\n\t\t\t}\n\t\t}\n\n\t\tif (DUK_TVAL_IS_OBJECT(tv_caller)) {\n\t\t\th_tmp = DUK_TVAL_GET_OBJECT(tv_caller);\n\t\t\tDUK_ASSERT(h_tmp != NULL);\n\t\t\tact_callee->prev_caller = h_tmp;\n\n\t\t\t/* Previous value doesn't need refcount changes because its ownership\n\t\t\t * is transferred to prev_caller.\n\t\t\t */\n\n\t\t\tif (act_caller != NULL) {\n\t\t\t\tDUK_ASSERT(act_caller->func != NULL);\n\t\t\t\tDUK_TVAL_SET_OBJECT(tv_caller, act_caller->func);\n\t\t\t\tDUK_TVAL_INCREF(thr, tv_caller);\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_NULL(tv_caller);  /* no incref */\n\t\t\t}\n\t\t} else {\n\t\t\t/* 'caller' must only take on 'null' or function value */\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_caller));\n\t\t\tDUK_ASSERT(act_callee->prev_caller == NULL);\n\t\t\tif (act_caller != NULL && act_caller->func) {\n\t\t\t\t/* Tolerate act_caller->func == NULL which happens in\n\t\t\t\t * some finalization cases; treat like unknown caller.\n\t\t\t\t */\n\t\t\t\tDUK_TVAL_SET_OBJECT(tv_caller, act_caller->func);\n\t\t\t\tDUK_TVAL_INCREF(thr, tv_caller);\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_NULL(tv_caller);  /* no incref */\n\t\t\t}\n\t\t}\n\t}\n}\n#endif  /* DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */\n\n/*\n *  Shared helpers for resolving the final, non-bound target function of the\n *  call and the effective 'this' binding.  Resolves bound functions and\n *  applies .call(), .apply(), and .construct() inline.\n *\n *  Proxy traps are also handled inline so that if the target is a Proxy with\n *  a 'call' or 'construct' trap, the trap handler is called with a modified\n *  argument list.\n *\n *  Once the bound function / .call() / .apply() / .construct() sequence has\n *  been resolved, the value at idx_func + 1 may need coercion described in\n *  E5 Section 10.4.3.\n *\n *  A call that begins as a non-constructor call may be converted into a\n *  constructor call during the resolution process if Reflect.construct()\n *  is invoked.  This is handled by updating the caller's call_flags.\n *\n *  For global and eval code (E5 Sections 10.4.1 and 10.4.2), we assume\n *  that the caller has provided the correct 'this' binding explicitly\n *  when calling, i.e.:\n *\n *    - global code: this=global object\n *    - direct eval: this=copy from eval() caller's this binding\n *    - other eval:  this=global object\n *\n *  The 'this' coercion may cause a recursive function call with arbitrary\n *  side effects, because ToObject() may be called.\n */\n\nDUK_LOCAL DUK_INLINE void duk__coerce_nonstrict_this_binding(duk_hthread *thr, duk_idx_t idx_this) {\n\tduk_tval *tv_this;\n\tduk_hobject *obj_global;\n\n\ttv_this = thr->valstack_bottom + idx_this;\n\tswitch (DUK_TVAL_GET_TAG(tv_this)) {\n\tcase DUK_TAG_OBJECT:\n\t\tDUK_DDD(DUK_DDDPRINT(\"this binding: non-strict, object -> use directly\"));\n\t\tbreak;\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\t\tDUK_DDD(DUK_DDDPRINT(\"this binding: non-strict, undefined/null -> use global object\"));\n\t\tobj_global = thr->builtins[DUK_BIDX_GLOBAL];\n\t\t/* XXX: avoid this check somehow */\n\t\tif (DUK_LIKELY(obj_global != NULL)) {\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_this));  /* no need to decref previous value */\n\t\t\tDUK_TVAL_SET_OBJECT(tv_this, obj_global);\n\t\t\tDUK_HOBJECT_INCREF(thr, obj_global);\n\t\t} else {\n\t\t\t/* This may only happen if built-ins are being \"torn down\".\n\t\t\t * This behavior is out of specification scope.\n\t\t\t */\n\t\t\tDUK_D(DUK_DPRINT(\"this binding: wanted to use global object, but it is NULL -> using undefined instead\"));\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_this));  /* no need to decref previous value */\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv_this);  /* nothing to incref */\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\t/* Plain buffers and lightfuncs are object coerced.  Lightfuncs\n\t\t * very rarely come here however, because the call target would\n\t\t * need to be a non-strict non-lightfunc (lightfuncs are considered\n\t\t * strict) with an explicit lightfunc 'this' binding.\n\t\t */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_this));\n\t\tDUK_DDD(DUK_DDDPRINT(\"this binding: non-strict, not object/undefined/null -> use ToObject(value)\"));\n\t\tduk_to_object(thr, idx_this);  /* may have side effects */\n\t\tbreak;\n\t}\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_bool_t duk__resolve_target_fastpath_check(duk_hthread *thr, duk_idx_t idx_func, duk_hobject **out_func, duk_small_uint_t call_flags) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tDUK_UNREF(thr);\n\tDUK_UNREF(idx_func);\n\tDUK_UNREF(out_func);\n\tDUK_UNREF(call_flags);\n#else  /* DUK_USE_PREFER_SIZE */\n\tduk_tval *tv_func;\n\tduk_hobject *func;\n\n\tif (DUK_UNLIKELY(call_flags & DUK_CALL_FLAG_CONSTRUCT)) {\n\t\treturn 0;\n\t}\n\n\ttv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);\n\tDUK_ASSERT(tv_func != NULL);\n\n\tif (DUK_LIKELY(DUK_TVAL_IS_OBJECT(tv_func))) {\n\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\t\tif (DUK_HOBJECT_IS_CALLABLE(func) &&\n\t\t    !DUK_HOBJECT_HAS_BOUNDFUNC(func) &&\n\t\t    !DUK_HOBJECT_HAS_SPECIAL_CALL(func)) {\n\t\t\t*out_func = func;\n\n\t\t\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t\t\t/* Strict function: no 'this' coercion. */\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tduk__coerce_nonstrict_this_binding(thr, idx_func + 1);\n\t\t\treturn 1;\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {\n\t\t*out_func = NULL;\n\n\t\t/* Lightfuncs are considered strict, so 'this' binding is\n\t\t * used as is.  They're never bound, always constructable,\n\t\t * and never special functions.\n\t\t */\n\t\treturn 1;\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\treturn 0;  /* let slow path deal with it */\n}\n\nDUK_LOCAL duk_hobject *duk__resolve_target_func_and_this_binding(duk_hthread *thr,\n                                                                 duk_idx_t idx_func,\n                                                                 duk_small_uint_t *call_flags) {\n\tduk_tval *tv_func;\n\tduk_hobject *func;\n\tduk_bool_t first;\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\tfor (first = 1;; first = 0) {\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\t\ttv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);\n\t\tDUK_ASSERT(tv_func != NULL);\n\n\t\tDUK_DD(DUK_DDPRINT(\"target func: %!iT\", tv_func));\n\n\t\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\n\t\t\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\t\t\tif (DUK_UNLIKELY(!DUK_HOBJECT_HAS_CONSTRUCTABLE(func))) {\n\t\t\t\t\tgoto not_constructable;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (DUK_UNLIKELY(!DUK_HOBJECT_IS_CALLABLE(func))) {\n\t\t\t\t\tgoto not_callable;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (DUK_LIKELY(!DUK_HOBJECT_HAS_BOUNDFUNC(func) &&\n\t\t\t               !DUK_HOBJECT_HAS_SPECIAL_CALL(func) &&\n\t\t\t               !DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(func))) {\n\t\t\t\t/* Common case, so test for using a single bitfield test.\n\t\t\t\t * Break out to handle this coercion etc.\n\t\t\t\t */\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/* XXX: could set specialcall for boundfuncs too, simplify check above */\n\n\t\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_SPECIAL_CALL(func));\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_IS_NATFUNC(func));\n\n\t\t\t\t/* Callable/constructable flags are the same\n\t\t\t\t * for the bound function and its target, so\n\t\t\t\t * we don't need to check them here, we can\n\t\t\t\t * check them from the target only.\n\t\t\t\t */\n\t\t\t\tduk__handle_bound_chain_for_call(thr, idx_func, *call_flags & DUK_CALL_FLAG_CONSTRUCT);\n\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(duk_require_tval(thr, idx_func)) ||\n\t\t\t\t           DUK_TVAL_IS_LIGHTFUNC(duk_require_tval(thr, idx_func)));\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_SPECIAL_CALL(func));\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\t\t\tif (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(func)) {\n\t\t\t\t\t/* If no trap, resume processing from Proxy trap.\n\t\t\t\t\t * If trap exists, helper converts call into a trap\n\t\t\t\t\t * call; this may change a constructor call into a\n\t\t\t\t\t * normal (non-constructor) trap call.  We must\n\t\t\t\t\t * continue processing even when a trap is found as\n\t\t\t\t\t * the trap may be bound.\n\t\t\t\t\t */\n\t\t\t\t\tduk__handle_proxy_for_call(thr, idx_func, (duk_hproxy *) func, call_flags);\n\t\t\t\t}\n\t\t\t\telse\n#endif\n\t\t\t\t{\n\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(func));\n\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_CALLABLE(func));\n\t\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CONSTRUCTABLE(func));\n\t\t\t\t\t/* Constructable check already done above. */\n\n\t\t\t\t\tif (duk__handle_specialfuncs_for_call(thr, idx_func, func, call_flags, first) != 0) {\n\t\t\t\t\t\t/* Encountered native eval call, normal call\n\t\t\t\t\t\t * context.  Break out, handle this coercion etc.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* Retry loop. */\n\t\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {\n\t\t\t/* Lightfuncs are:\n\t\t\t *   - Always strict, so no 'this' coercion.\n\t\t\t *   - Always callable.\n\t\t\t *   - Always constructable.\n\t\t\t *   - Never specialfuncs.\n\t\t\t */\n\t\t\tfunc = NULL;\n\t\t\tgoto finished;\n\t\t} else {\n\t\t\tgoto not_callable;\n\t\t}\n\t}\n\n\tDUK_ASSERT(func != NULL);\n\n\tif (!DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t/* Non-strict target needs 'this' coercion.\n\t\t * This has potential side effects invalidating\n\t\t * 'tv_func'.\n\t\t */\n\t\tduk__coerce_nonstrict_this_binding(thr, idx_func + 1);\n\t}\n\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tif (!(*call_flags & DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED)) {\n\t\t\t*call_flags |= DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED;\n\t\t\tduk__update_default_instance_proto(thr, idx_func);\n\t\t}\n\t}\n\n finished:\n\n#if defined(DUK_USE_ASSERTIONS)\n\t{\n\t\tduk_tval *tv_tmp;\n\n\t\ttv_tmp = duk_get_tval(thr, idx_func);\n\t\tDUK_ASSERT(tv_tmp != NULL);\n\n\t\tDUK_ASSERT((DUK_TVAL_IS_OBJECT(tv_tmp) && DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(tv_tmp))) ||\n\t\t           DUK_TVAL_IS_LIGHTFUNC(tv_tmp));\n\t\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\t\tDUK_ASSERT(func == NULL || (DUK_HOBJECT_IS_COMPFUNC(func) ||\n\t\t                            DUK_HOBJECT_IS_NATFUNC(func)));\n\t\tDUK_ASSERT(func == NULL || (DUK_HOBJECT_HAS_CONSTRUCTABLE(func) ||\n\t\t                            (*call_flags & DUK_CALL_FLAG_CONSTRUCT) == 0));\n\t}\n#endif\n\n\treturn func;\n\n not_callable:\n\tDUK_ASSERT(tv_func != NULL);\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t/* GETPROPC delayed error handling: when target is not callable,\n\t * GETPROPC replaces idx_func+0 with a non-callable wrapper object\n\t * with a hidden Symbol to signify it's to be handled here.  If\n\t * found, unwrap the original Error and throw it as is here.  The\n\t * hidden Symbol is only checked as an own property, not inherited\n\t * (which would be dangerous).\n\t */\n\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\tduk_tval *tv_wrap = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, DUK_TVAL_GET_OBJECT(tv_func), DUK_STRIDX_INT_TARGET);\n\t\tif (tv_wrap != NULL) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"delayed error from GETPROPC: %!T\", tv_wrap));\n\t\t\tduk_push_tval(thr, tv_wrap);\n\t\t\t(void) duk_throw(thr);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t}\n#endif\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not callable\", duk_get_type_name(thr, idx_func));\n#else\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not callable\", duk_push_string_tval_readable(thr, tv_func));\n#endif\n#else\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);\n#endif\n\tDUK_WO_NORETURN(return NULL;);\n\n not_constructable:\n\t/* For now GETPROPC delayed error not needed for constructor calls. */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not constructable\", duk_get_type_name(thr, idx_func));\n#else\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not constructable\", duk_push_string_tval_readable(thr, tv_func));\n#endif\n#else\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONSTRUCTABLE);\n#endif\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Manipulate value stack so that exactly 'num_stack_rets' return\n *  values are at 'idx_retbase' in every case, assuming there are\n *  'rc' return values on top of stack.\n *\n *  This is a bit tricky, because the called C function operates in\n *  the same activation record and may have e.g. popped the stack\n *  empty (below idx_retbase).\n */\n\nDUK_LOCAL void duk__safe_call_adjust_valstack(duk_hthread *thr, duk_idx_t idx_retbase, duk_idx_t num_stack_rets, duk_idx_t num_actual_rets) {\n\tduk_idx_t idx_rcbase;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(idx_retbase >= 0);\n\tDUK_ASSERT(num_stack_rets >= 0);\n\tDUK_ASSERT(num_actual_rets >= 0);\n\n\tidx_rcbase = duk_get_top(thr) - num_actual_rets;  /* base of known return values */\n\tif (DUK_UNLIKELY(idx_rcbase < 0)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_CFUNC_RC);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"adjust valstack after func call: \"\n\t                     \"num_stack_rets=%ld, num_actual_rets=%ld, stack_top=%ld, idx_retbase=%ld, idx_rcbase=%ld\",\n\t                     (long) num_stack_rets, (long) num_actual_rets, (long) duk_get_top(thr),\n\t                     (long) idx_retbase, (long) idx_rcbase));\n\n\tDUK_ASSERT(idx_rcbase >= 0);  /* caller must check */\n\n\t/* Space for num_stack_rets was reserved before the safe call.\n\t * Because value stack reserve cannot shrink except in call returns,\n\t * the reserve is still in place.  Adjust valstack, carefully\n\t * ensuring we don't overstep the reserve.\n\t */\n\n\t/* Match idx_rcbase with idx_retbase so that the return values\n\t * start at the correct index.\n\t */\n\tif (idx_rcbase > idx_retbase) {\n\t\tduk_idx_t count = idx_rcbase - idx_retbase;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"elements at/after idx_retbase have enough to cover func retvals \"\n\t\t                     \"(idx_retbase=%ld, idx_rcbase=%ld)\", (long) idx_retbase, (long) idx_rcbase));\n\n\t\t/* Remove values between irc_rcbase (start of intended return\n\t\t * values) and idx_retbase to lower return values to idx_retbase.\n\t\t */\n\t\tDUK_ASSERT(count > 0);\n\t\tduk_remove_n(thr, idx_retbase, count);  /* may be NORZ */\n\t} else {\n\t\tduk_idx_t count = idx_retbase - idx_rcbase;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"not enough elements at/after idx_retbase to cover func retvals \"\n\t\t                     \"(idx_retbase=%ld, idx_rcbase=%ld)\", (long) idx_retbase, (long) idx_rcbase));\n\n\t\t/* Insert 'undefined' at idx_rcbase (start of intended return\n\t\t * values) to lift return values to idx_retbase.\n\t\t */\n\t\tDUK_ASSERT(count >= 0);\n\t\tDUK_ASSERT(thr->valstack_end - thr->valstack_top >= count);  /* reserve cannot shrink */\n\t\tduk_insert_undefined_n(thr, idx_rcbase, count);\n\t}\n\n\t/* Chop extra retvals away / extend with undefined. */\n\tduk_set_top_unsafe(thr, idx_retbase + num_stack_rets);\n}\n\n/*\n *  Activation setup for tailcalls and non-tailcalls.\n */\n\n#if defined(DUK_USE_TAILCALL)\nDUK_LOCAL duk_small_uint_t duk__call_setup_act_attempt_tailcall(duk_hthread *thr,\n                                                                duk_small_uint_t call_flags,\n                                                                duk_idx_t idx_func,\n                                                                duk_hobject *func,\n                                                                duk_size_t entry_valstack_bottom_byteoff,\n                                                                duk_size_t entry_valstack_end_byteoff,\n                                                                duk_idx_t *out_nargs,\n                                                                duk_idx_t *out_nregs,\n                                                                duk_size_t *out_vs_min_bytes,\n                                                                duk_activation **out_act) {\n\tduk_activation *act;\n\tduk_tval *tv1, *tv2;\n\tduk_idx_t idx_args;\n\tduk_small_uint_t flags1, flags2;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_activation *prev_pause_act;\n#endif\n\n\tDUK_UNREF(entry_valstack_end_byteoff);\n\n\t/* Tailcall cannot be flagged to resume calls, and a\n\t * previous frame must exist.\n\t */\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\t*out_act = act;\n\n\tif (func == NULL || !DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by target not being ecma function\"));\n\t\treturn 0;\n\t}\n\tif (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by current activation having DUK_ACT_FLAG_PREVENT_YIELD\"));\n\t\treturn 0;\n\t}\n\t/* Tailcall is only allowed if current and candidate\n\t * function have identical return value handling.  There\n\t * are three possible return value handling cases:\n\t *   1. Normal function call, no special return value handling.\n\t *   2. Constructor call, return value replacement object check.\n\t *   3. Proxy 'construct' trap call, return value invariant check.\n\t */\n\tflags1 = (duk_small_uint_t) ((act->flags & DUK_ACT_FLAG_CONSTRUCT) ? 1 : 0)\n#if defined(DUK_USE_ES6_PROXY)\n\t         | (duk_small_uint_t) ((act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) ? 2 : 0)\n#endif\n\t         ;\n\tflags2 = (duk_small_uint_t) ((call_flags & DUK_CALL_FLAG_CONSTRUCT) ? 1 : 0)\n#if defined(DUK_USE_ES6_PROXY)\n\t         | (duk_small_uint_t) ((call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) ? 2 : 0);\n#endif\n\t         ;\n\tif (flags1 != flags2) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by incompatible return value handling\"));\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(((act->flags & DUK_ACT_FLAG_CONSTRUCT) && (call_flags & DUK_CALL_FLAG_CONSTRUCT)) ||\n\t           (!(act->flags & DUK_ACT_FLAG_CONSTRUCT) && !(call_flags & DUK_CALL_FLAG_CONSTRUCT)));\n\tDUK_ASSERT(((act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) && (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY)) ||\n\t           (!(act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) && !(call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY)));\n\tif (DUK_HOBJECT_HAS_NOTAIL(func)) {\n\t\t/* See: test-bug-tailcall-preventyield-assert.c. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by function having a notail flag\"));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  Tailcall handling\n\t *\n\t *  Although the callstack entry is reused, we need to explicitly unwind\n\t *  the current activation (or simulate an unwind).  In particular, the\n\t *  current activation must be closed, otherwise something like\n\t *  test-bug-reduce-judofyr.js results.  Also catchers need to be unwound\n\t *  because there may be non-error-catching label entries in valid tail calls.\n\t *\n\t *  Special attention is needed for debugger and pause behavior when\n\t *  reusing an activation.\n\t *    - Disable StepOut processing for the activation unwind because\n\t *      we reuse the activation, see:\n\t *      https://github.com/svaarala/duktape/issues/1684.\n\t *    - Disable line change pause flag permanently if act == dbg_pause_act\n\t *      (if set) because it would no longer be relevant, see:\n\t *      https://github.com/svaarala/duktape/issues/1726,\n\t *      https://github.com/svaarala/duktape/issues/1786.\n\t *    - Check for function entry (e.g. StepInto) pause flag here, because\n\t *      the executor pause check won't trigger due to shared activation, see:\n\t *      https://github.com/svaarala/duktape/issues/1726.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"is tail call, reusing activation at callstack top, at index %ld\",\n                             (long) (thr->callstack_top - 1)));\n\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(func));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));\n\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\tDUK_ASSERT(call_flags & DUK_CALL_FLAG_ALLOW_ECMATOECMA);\n\n\t/* Unwind the topmost callstack entry before reusing it.  This\n\t * also unwinds the catchers related to the topmost entry.\n\t */\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (act == thr->heap->dbg_pause_act) {\n\t\tthr->heap->dbg_pause_flags &= ~DUK_PAUSE_FLAG_LINE_CHANGE;\n\t}\n\n\tprev_pause_act = thr->heap->dbg_pause_act;\n\tthr->heap->dbg_pause_act = NULL;\n\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_ENTRY) {\n\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by function entry (tailcall)\"));\n\t\tduk_debug_set_paused(thr->heap);\n\t}\n#endif\n\tduk_hthread_activation_unwind_reuse_norz(thr);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tthr->heap->dbg_pause_act = prev_pause_act;\n#endif\n\tDUK_ASSERT(act == thr->callstack_curr);\n\n\t/* XXX: We could restore the caller's value stack reserve\n\t * here, as if we did an actual unwind-and-call.  Without\n\t * the restoration, value stack reserve may remain higher\n\t * than would otherwise be possible until we return to a\n\t * non-tailcall.\n\t */\n\n\t/* Then reuse the unwound activation. */\n\tact->cat = NULL;\n\tact->var_env = NULL;\n\tact->lex_env = NULL;\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));\n\tact->func = func;  /* don't want an intermediate exposed state with func == NULL */\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\tact->prev_caller = NULL;\n#endif\n\t/* don't want an intermediate exposed state with invalid pc */\n\tact->curr_pc = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) func);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tact->prev_line = 0;\n#endif\n\tDUK_TVAL_SET_OBJECT(&act->tv_func, func);  /* borrowed, no refcount */\n\tDUK_HOBJECT_INCREF(thr, func);\n\n\tact->flags = DUK_ACT_FLAG_TAILCALLED;\n\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\tact->flags |= DUK_ACT_FLAG_STRICT;\n\t}\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT;\n\t}\n#if defined(DUK_USE_ES6_PROXY)\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT_PROXY;\n\t}\n#endif\n\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) == func);      /* already updated */\n\tDUK_ASSERT(act->var_env == NULL);\n\tDUK_ASSERT(act->lex_env == NULL);\n\tact->bottom_byteoff = entry_valstack_bottom_byteoff;  /* tail call -> reuse current \"frame\" */\n#if 0\n\t/* Topmost activation retval_byteoff is considered garbage, no need to init. */\n\tact->retval_byteoff = 0;\n#endif\n\t/* Filled in when final reserve is known, dummy value doesn't matter\n\t * even in error unwind because reserve_byteoff is only used when\n\t * returning to -this- activation.\n\t */\n\tact->reserve_byteoff = 0;\n\n\t/*\n\t *  Manipulate valstack so that args are on the current bottom and the\n\t *  previous caller's 'this' binding (which is the value preceding the\n\t *  current bottom) is replaced with the new 'this' binding:\n\t *\n\t *       [ ... this_old | (crud) func this_new arg1 ... argN ]\n\t *  -->  [ ... this_new | arg1 ... argN ]\n\t *\n\t *  For tail calling to work properly, the valstack bottom must not grow\n\t *  here; otherwise crud would accumulate on the valstack.\n\t */\n\n\ttv1 = thr->valstack_bottom - 1;\n\ttv2 = thr->valstack_bottom + idx_func + 1;\n\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);  /* tv1 is -below- valstack_bottom */\n\tDUK_ASSERT(tv2 >= thr->valstack_bottom && tv2 < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\n\tidx_args = idx_func + 2;\n\tduk_remove_n(thr, 0, idx_args);  /* may be NORZ */\n\n\tidx_func = 0; DUK_UNREF(idx_func);  /* really 'not applicable' anymore, should not be referenced after this */\n\tidx_args = 0;\n\n\t*out_nargs = ((duk_hcompfunc *) func)->nargs;\n\t*out_nregs = ((duk_hcompfunc *) func)->nregs;\n\tDUK_ASSERT(*out_nregs >= 0);\n\tDUK_ASSERT(*out_nregs >= *out_nargs);\n\t*out_vs_min_bytes = entry_valstack_bottom_byteoff + sizeof(duk_tval) * ((duk_size_t) *out_nregs + DUK_VALSTACK_INTERNAL_EXTRA);\n\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n#if defined(DUK_USE_TAILCALL)\n#error incorrect options: tail calls enabled with function caller property\n#endif\n\t/* XXX: This doesn't actually work properly for tail calls, so\n\t * tail calls are disabled when DUK_USE_NONSTD_FUNC_CALLER_PROPERTY\n\t * is in use.\n\t */\n\tduk__update_func_caller_prop(thr, func);\n#endif\n\n\t/* [ ... this_new | arg1 ... argN ] */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_TAILCALL */\n\nDUK_LOCAL void duk__call_setup_act_not_tailcall(duk_hthread *thr,\n                                                duk_small_uint_t call_flags,\n                                                duk_idx_t idx_func,\n                                                duk_hobject *func,\n                                                duk_size_t entry_valstack_bottom_byteoff,\n                                                duk_size_t entry_valstack_end_byteoff,\n                                                duk_idx_t *out_nargs,\n                                                duk_idx_t *out_nregs,\n                                                duk_size_t *out_vs_min_bytes,\n                                                duk_activation **out_act) {\n\tduk_activation *act;\n\tduk_activation *new_act;\n\n\tDUK_UNREF(entry_valstack_end_byteoff);\n\n\tDUK_DDD(DUK_DDDPRINT(\"not a tail call, pushing a new activation to callstack, to index %ld\",\n\t                     (long) (thr->callstack_top)));\n\n\tduk__call_callstack_limit_check(thr);\n\tnew_act = duk_hthread_activation_alloc(thr);\n\tDUK_ASSERT(new_act != NULL);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\t/*\n\t\t *  Update return value stack index of current activation (if any).\n\t\t *\n\t\t *  Although it might seem this is not necessary (bytecode executor\n\t\t *  does this for ECMAScript-to-ECMAScript calls; other calls are\n\t\t *  handled here), this turns out to be necessary for handling yield\n\t\t *  and resume.  For them, an ECMAScript-to-native call happens, and\n\t\t *  the ECMAScript call's retval_byteoff must be set for things to work.\n\t\t */\n\n\t\tact->retval_byteoff = entry_valstack_bottom_byteoff + (duk_size_t) idx_func * sizeof(duk_tval);\n\t}\n\n\tnew_act->parent = act;\n\tthr->callstack_curr = new_act;\n\tthr->callstack_top++;\n\tact = new_act;\n\t*out_act = act;\n\n\tDUK_ASSERT(thr->valstack_top > thr->valstack_bottom);  /* at least effective 'this' */\n\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\n\tact->cat = NULL;\n\n\tact->flags = 0;\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT;\n\t}\n#if defined(DUK_USE_ES6_PROXY)\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT_PROXY;\n\t}\n#endif\n\tif (call_flags & DUK_CALL_FLAG_DIRECT_EVAL) {\n\t\tact->flags |= DUK_ACT_FLAG_DIRECT_EVAL;\n\t}\n\n\t/* start of arguments: idx_func + 2. */\n\tact->func = func;  /* NULL for lightfunc */\n\tif (DUK_LIKELY(func != NULL)) {\n\t\tDUK_TVAL_SET_OBJECT(&act->tv_func, func);  /* borrowed, no refcount */\n\t\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t\tact->flags |= DUK_ACT_FLAG_STRICT;\n\t\t}\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\t\t*out_nargs = ((duk_hcompfunc *) func)->nargs;\n\t\t\t*out_nregs = ((duk_hcompfunc *) func)->nregs;\n\t\t\tDUK_ASSERT(*out_nregs >= 0);\n\t\t\tDUK_ASSERT(*out_nregs >= *out_nargs);\n\t\t\t*out_vs_min_bytes = entry_valstack_bottom_byteoff +\n\t\t\t\tsizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nregs + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t} else {\n\t\t\t/* True because of call target lookup checks. */\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(func));\n\n\t\t\t*out_nargs = ((duk_hnatfunc *) func)->nargs;\n\t\t\t*out_nregs = *out_nargs;\n\t\t\tif (*out_nargs >= 0) {\n\t\t\t\t*out_vs_min_bytes = entry_valstack_bottom_byteoff +\n\t\t\t\t\tsizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nregs + DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t\t} else {\n\t\t\t\t/* Vararg function. */\n\t\t\t\tduk_size_t valstack_top_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - ((duk_uint8_t *) thr->valstack));\n\t\t\t\t*out_vs_min_bytes = valstack_top_byteoff +\n\t\t\t\t\tsizeof(duk_tval) * (DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tduk_small_uint_t lf_flags;\n\t\tduk_tval *tv_func;\n\n\t\tact->flags |= DUK_ACT_FLAG_STRICT;\n\n\t\ttv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);\n\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func));\n\t\tDUK_TVAL_SET_TVAL(&act->tv_func, tv_func);  /* borrowed, no refcount */\n\n\t\tlf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv_func);\n\t\t*out_nargs = DUK_LFUNC_FLAGS_GET_NARGS(lf_flags);\n\t\tif (*out_nargs != DUK_LFUNC_NARGS_VARARGS) {\n\t\t\t*out_vs_min_bytes = entry_valstack_bottom_byteoff +\n\t\t\t\tsizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nargs + DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t} else {\n\t\t\tduk_size_t valstack_top_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - ((duk_uint8_t *) thr->valstack));\n\t\t\t*out_vs_min_bytes = valstack_top_byteoff +\n\t\t\t\tsizeof(duk_tval) * (DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t\t*out_nargs = -1;  /* vararg */\n\t\t}\n\t\t*out_nregs = *out_nargs;\n\t}\n\n\tact->var_env = NULL;\n\tact->lex_env = NULL;\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\tact->prev_caller = NULL;\n#endif\n\tact->curr_pc = NULL;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tact->prev_line = 0;\n#endif\n\tact->bottom_byteoff = entry_valstack_bottom_byteoff + sizeof(duk_tval) * ((duk_size_t) idx_func + 2U);\n#if 0\n\tact->retval_byteoff = 0;   /* topmost activation retval_byteoff is considered garbage, no need to init */\n#endif\n\t/* Filled in when final reserve is known, dummy value doesn't matter\n\t * even in error unwind because reserve_byteoff is only used when\n\t * returning to -this- activation.\n\t */\n\tact->reserve_byteoff = 0;  /* filled in by caller */\n\n\t/* XXX: Is this INCREF necessary? 'func' is always a borrowed\n\t * reference reachable through the value stack?  If changed, stack\n\t * unwind code also needs to be fixed to match.\n\t */\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, func);  /* act->func */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\tif (func) {\n\t\tduk__update_func_caller_prop(thr, func);\n\t}\n#endif\n}\n\n/*\n *  Environment setup.\n */\n\nDUK_LOCAL void duk__call_env_setup(duk_hthread *thr, duk_hobject *func, duk_activation *act, duk_idx_t idx_args) {\n\tduk_hobject *env;\n\n\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));  /* bound function has already been resolved */\n\n\tif (DUK_LIKELY(func != NULL)) {\n\t\tif (DUK_LIKELY(DUK_HOBJECT_HAS_NEWENV(func))) {\n\t\t\tDUK_STATS_INC(thr->heap, stats_envrec_newenv);\n\t\t\tif (DUK_LIKELY(!DUK_HOBJECT_HAS_CREATEARGS(func))) {\n\t\t\t\t/* Use a new environment but there's no 'arguments' object;\n\t\t\t\t * delayed environment initialization.  This is the most\n\t\t\t\t * common case.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(act->lex_env == NULL);\n\t\t\t\tDUK_ASSERT(act->var_env == NULL);\n\t\t\t} else {\n\t\t\t\t/* Use a new environment and there's an 'arguments' object.\n\t\t\t\t * We need to initialize it right now.\n\t\t\t\t */\n\n\t\t\t\t/* third arg: absolute index (to entire valstack) of bottom_byteoff of new activation */\n\t\t\t\tenv = duk_create_activation_environment_record(thr, func, act->bottom_byteoff);\n\t\t\t\tDUK_ASSERT(env != NULL);\n\n\t\t\t\t/* [ ... func this arg1 ... argN envobj ] */\n\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_CREATEARGS(func));\n\t\t\t\tduk__handle_createargs_for_call(thr, func, env, idx_args);\n\n\t\t\t\t/* [ ... func this arg1 ... argN envobj ] */\n\n\t\t\t\tact->lex_env = env;\n\t\t\t\tact->var_env = env;\n\t\t\t\tDUK_HOBJECT_INCREF(thr, env);\n\t\t\t\tDUK_HOBJECT_INCREF(thr, env);  /* XXX: incref by count (2) directly */\n\t\t\t\tduk_pop(thr);\n\t\t\t}\n\t\t} else {\n\t\t\t/* Use existing env (e.g. for non-strict eval); cannot have\n\t\t\t * an own 'arguments' object (but can refer to an existing one).\n\t\t\t */\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(func));\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_envrec_oldenv);\n\t\t\tduk__handle_oldenv_for_call(thr, func, act);\n\n\t\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\t\tDUK_ASSERT(act->var_env != NULL);\n\t\t}\n\t} else {\n\t\t/* Lightfuncs are always native functions and have \"newenv\". */\n\t\tDUK_ASSERT(act->lex_env == NULL);\n\t\tDUK_ASSERT(act->var_env == NULL);\n\t\tDUK_STATS_INC(thr->heap, stats_envrec_newenv);\n\t}\n}\n\n/*\n *  Misc shared helpers.\n */\n\n/* Check thread state, update current thread. */\nDUK_LOCAL void duk__call_thread_state_update(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\tif (DUK_LIKELY(thr == thr->heap->curr_thread)) {\n\t\tif (DUK_UNLIKELY(thr->state != DUK_HTHREAD_STATE_RUNNING)) {\n\t\t\t/* Should actually never happen, but check anyway. */\n\t\t\tgoto thread_state_error;\n\t\t}\n\t} else {\n\t\tDUK_ASSERT(thr->heap->curr_thread == NULL ||\n\t\t           thr->heap->curr_thread->state == DUK_HTHREAD_STATE_RUNNING);\n\t\tif (DUK_UNLIKELY(thr->state != DUK_HTHREAD_STATE_INACTIVE)) {\n\t\t\tgoto thread_state_error;\n\t\t}\n\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, thr);\n\t\tthr->state = DUK_HTHREAD_STATE_RUNNING;\n\n\t\t/* Multiple threads may be simultaneously in the RUNNING\n\t\t * state, but not in the same \"resume chain\".\n\t\t */\n\t}\n\tDUK_ASSERT(thr->heap->curr_thread == thr);\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\treturn;\n\n thread_state_error:\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"invalid thread state (%ld)\", (long) thr->state);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Main unprotected call handler, handles:\n *\n *    - All combinations of native/ECMAScript caller and native/ECMAScript\n *      target.\n *\n *    - Optimized ECMAScript-to-ECMAScript call where call handling only\n *      sets up a new duk_activation but reuses an existing bytecode executor\n *      (the caller) without native recursion.\n *\n *    - Tailcalls, where an activation is reused without increasing call\n *      stack (duk_activation) depth.\n *\n *    - Setup for an initial Duktape.Thread.resume().\n *\n *  The call handler doesn't provide any protection guarantees, protected calls\n *  must be implemented e.g. by wrapping the call in a duk_safe_call().\n *  Call setup may fail at any stage, even when the new activation is in\n *  place; the only guarantee is that the state is consistent for unwinding.\n */\n\nDUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,\n                                         duk_idx_t idx_func,\n                                         duk_small_uint_t call_flags) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_activation *entry_act;\n\tduk_size_t entry_callstack_top;\n#endif\n\tduk_size_t entry_valstack_bottom_byteoff;\n\tduk_size_t entry_valstack_end_byteoff;\n\tduk_int_t entry_call_recursion_depth;\n\tduk_hthread *entry_curr_thread;\n\tduk_uint_fast8_t entry_thread_state;\n\tduk_instr_t **entry_ptr_curr_pc;\n\tduk_idx_t idx_args;\n\tduk_idx_t nargs;            /* # argument registers target function wants (< 0 => \"as is\") */\n\tduk_idx_t nregs;            /* # total registers target function wants on entry (< 0 => \"as is\") */\n\tduk_size_t vs_min_bytes;    /* minimum value stack size (bytes) for handling call */\n\tduk_hobject *func;          /* 'func' on stack (borrowed reference) */\n\tduk_activation *act;\n\tduk_ret_t rc;\n\tduk_small_uint_t use_tailcall;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\t/* Asserts for heap->curr_thread omitted: it may be NULL, 'thr', or\n\t * any other thread (e.g. when heap thread is used to run finalizers).\n\t */\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\tDUK_ASSERT(idx_func >= 0);\n\n\tDUK_STATS_INC(thr->heap, stats_call_all);\n\n\t/* If a tail call:\n\t *   - an ECMAScript activation must be on top of the callstack\n\t *   - there cannot be any catch stack entries that would catch\n\t *     a return\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tif (call_flags & DUK_CALL_FLAG_TAILCALL) {\n\t\tduk_activation *tmp_act;\n\t\tduk_catcher *tmp_cat;\n\n\t\tDUK_ASSERT(thr->callstack_top >= 1);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\t\t/* No entry in the catch stack which would actually catch a\n\t\t * throw can refer to the callstack entry being reused.\n\t\t * There *can* be catch stack entries referring to the current\n\t\t * callstack entry as long as they don't catch (e.g. label sites).\n\t\t */\n\n\t\ttmp_act = thr->callstack_curr;\n\t\tfor (tmp_cat = tmp_act->cat; tmp_cat != NULL; tmp_cat = tmp_cat->parent) {\n\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(tmp_cat) == DUK_CAT_TYPE_LABEL); /* a non-catching entry */\n\t\t}\n\t}\n#endif  /* DUK_USE_ASSERTIONS */\n\n\t/*\n\t *  Store entry state.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_act = thr->callstack_curr;\n\tentry_callstack_top = thr->callstack_top;\n#endif\n\tentry_valstack_bottom_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);\n\tentry_valstack_end_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tentry_call_recursion_depth = thr->heap->call_recursion_depth;\n\tentry_curr_thread = thr->heap->curr_thread;  /* may be NULL if first call */\n\tentry_thread_state = thr->state;\n\tentry_ptr_curr_pc = thr->ptr_curr_pc;  /* may be NULL */\n\n\t/* If thr->ptr_curr_pc is set, sync curr_pc to act->pc.  Then NULL\n\t * thr->ptr_curr_pc so that it's not accidentally used with an incorrect\n\t * activation when side effects occur.\n\t */\n\tduk_hthread_sync_and_null_currpc(thr);\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"duk__handle_call_raw: thr=%p, idx_func=%ld, \"\n\t                   \"call_flags=0x%08lx (constructor=%ld), \"\n\t                   \"valstack_top=%ld, idx_func=%ld, idx_args=%ld, rec_depth=%ld/%ld, \"\n\t                   \"entry_valstack_bottom_byteoff=%ld, entry_valstack_end_byteoff=%ld, \"\n\t                   \"entry_call_recursion_depth=%ld, \"\n\t                   \"entry_curr_thread=%p, entry_thread_state=%ld\",\n\t                   (void *) thr,\n\t                   (long) idx_func,\n\t                   (unsigned long) call_flags,\n\t                   (long) ((call_flags & DUK_CALL_FLAG_CONSTRUCT) != 0 ? 1 : 0),\n\t                   (long) duk_get_top(thr),\n\t                   (long) idx_func,\n\t                   (long) (idx_func + 2),\n\t                   (long) thr->heap->call_recursion_depth,\n\t                   (long) thr->heap->call_recursion_limit,\n\t                   (long) entry_valstack_bottom_byteoff,\n\t                   (long) entry_valstack_end_byteoff,\n\t                   (long) entry_call_recursion_depth,\n\t                   (void *) entry_curr_thread,\n\t                   (long) entry_thread_state));\n\n\t/*\n\t *  Thread state check and book-keeping.\n\t */\n\n\tduk__call_thread_state_update(thr);\n\n\t/*\n\t *  Increase call recursion depth as early as possible so that if we\n\t *  enter a recursive call for any reason there's a backstop to native\n\t *  recursion.  This can happen e.g. for almost any property read\n\t *  because it may cause a getter call or a Proxy trap (GC and finalizers\n\t *  are not an issue because they are not recursive).  If we end up\n\t *  doing an Ecma-to-Ecma call, revert the increase.  (See GH-2032.)\n\t *\n\t *  For similar reasons, ensure there is a known value stack spare\n\t *  even before we actually prepare the value stack for the target\n\t *  function.  If this isn't done, early recursion may consume the\n\t *  value stack space.\n\t *\n\t *  XXX: Should bump yield preventcount early, for the same reason.\n\t */\n\n\tduk__call_c_recursion_limit_check(thr);\n\tthr->heap->call_recursion_depth++;\n\tduk_require_stack(thr, DUK__CALL_HANDLING_REQUIRE_STACK);\n\n\t/*\n\t *  Resolve final target function; handle bound functions and special\n\t *  functions like .call() and .apply().  Also figure out the effective\n\t *  'this' binding, which replaces the current value at idx_func + 1.\n\t */\n\n\tif (DUK_LIKELY(duk__resolve_target_fastpath_check(thr, idx_func, &func, call_flags) != 0U)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"fast path target resolve\"));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"slow path target resolve\"));\n\t\tfunc = duk__resolve_target_func_and_this_binding(thr, idx_func, &call_flags);\n\t}\n\tDUK_ASSERT(duk_get_top(thr) - idx_func >= 2);  /* at least func and this present */\n\n\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\tDUK_ASSERT(func == NULL || (DUK_HOBJECT_IS_COMPFUNC(func) ||\n\t                            DUK_HOBJECT_IS_NATFUNC(func)));\n\n\t/* [ ... func this arg1 ... argN ] */\n\n\t/*\n\t *  Setup a preliminary activation and figure out nargs/nregs and\n\t *  value stack minimum size.\n\t *\n\t *  Don't touch valstack_bottom or valstack_top yet so that Duktape API\n\t *  calls work normally.\n\t *\n\t *  Because 'act' is not zeroed, all fields must be filled in.\n\t */\n\n\t/* Should not be necessary, but initialize to silence warnings. */\n\tact = NULL;\n\tnargs = 0;\n\tnregs = 0;\n\tvs_min_bytes = 0;\n\n#if defined(DUK_USE_TAILCALL)\n\tuse_tailcall = (call_flags & DUK_CALL_FLAG_TAILCALL);\n\tif (use_tailcall) {\n\t\tuse_tailcall = duk__call_setup_act_attempt_tailcall(thr,\n\t\t                                                    call_flags,\n\t\t                                                    idx_func,\n\t\t                                                    func,\n\t\t                                                    entry_valstack_bottom_byteoff,\n\t\t                                                    entry_valstack_end_byteoff,\n\t\t                                                    &nargs,\n\t\t                                                    &nregs,\n\t\t                                                    &vs_min_bytes,\n\t\t                                                    &act);\n\t}\n#else\n\tDUK_ASSERT((call_flags & DUK_CALL_FLAG_TAILCALL) == 0);  /* compiler ensures this */\n\tuse_tailcall = 0;\n#endif\n\n\tif (use_tailcall) {\n\t\tidx_args = 0;\n\t\tDUK_STATS_INC(thr->heap, stats_call_tailcall);\n\t} else {\n\t\tduk__call_setup_act_not_tailcall(thr,\n\t\t                                 call_flags,\n\t\t                                 idx_func,\n\t\t                                 func,\n\t\t                                 entry_valstack_bottom_byteoff,\n\t\t                                 entry_valstack_end_byteoff,\n\t\t                                 &nargs,\n\t\t                                 &nregs,\n\t\t                                 &vs_min_bytes,\n\t\t                                 &act);\n\t\tidx_args = idx_func + 2;\n\t}\n\t/* After this point idx_func is no longer valid for tailcalls. */\n\n\tDUK_ASSERT(act != NULL);\n\n\t/* [ ... func this arg1 ... argN ] */\n\n\t/*\n\t *  Environment record creation and 'arguments' object creation.\n\t *  Named function expression name binding is handled by the\n\t *  compiler; the compiled function's parent env will contain\n\t *  the (immutable) binding already.\n\t *\n\t *  This handling is now identical for C and ECMAScript functions.\n\t *  C functions always have the 'NEWENV' flag set, so their\n\t *  environment record initialization is delayed (which is good).\n\t *\n\t *  Delayed creation (on demand) is handled in duk_js_var.c.\n\t */\n\n\tduk__call_env_setup(thr, func, act, idx_args);\n\n\t/* [ ... func this arg1 ... argN ] */\n\n\t/*\n\t *  Setup value stack: clamp to 'nargs', fill up to 'nregs',\n\t *  ensure value stack size matches target requirements, and\n\t *  switch value stack bottom.  Valstack top is kept.\n\t *\n\t *  Value stack can only grow here.\n\t */\n\n\tduk_valstack_grow_check_throw(thr, vs_min_bytes);\n\tact->reserve_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\n\tif (use_tailcall) {\n\t\tDUK_ASSERT(nregs >= 0);\n\t\tDUK_ASSERT(nregs >= nargs);\n\t\tduk_set_top_and_wipe(thr, nregs, nargs);\n\t} else {\n\t\tif (nregs >= 0) {\n\t\t\tDUK_ASSERT(nregs >= nargs);\n\t\t\tduk_set_top_and_wipe(thr, idx_func + 2 + nregs, idx_func + 2 + nargs);\n\t\t} else {\n\t\t\t;\n\t\t}\n\t\tthr->valstack_bottom = thr->valstack_bottom + idx_func + 2;\n\t}\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\n\t/*\n\t *  Make the actual call.  For Ecma-to-Ecma calls detect that\n\t *  setup is complete, then return with a status code that allows\n\t *  the caller to reuse the running executor.\n\t */\n\n\tif (func != NULL && DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\t/*\n\t\t *  ECMAScript call.\n\t\t */\n\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));\n\t\tact->curr_pc = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) func);\n\n\t\tif (call_flags & DUK_CALL_FLAG_ALLOW_ECMATOECMA) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"avoid native call, use existing executor\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_call_ecmatoecma);\n\t\t\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\t\t\tDUK_REFZERO_CHECK_FAST(thr);\n\t\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\t\tthr->heap->call_recursion_depth--;  /* No recursion increase for this case. */\n\t\t\treturn 1;  /* 1=reuse executor */\n\t\t}\n\t\tDUK_ASSERT(use_tailcall == 0);\n\n\t\t/* duk_hthread_activation_unwind_norz() will decrease this on unwind */\n\t\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\t\tact->flags |= DUK_ACT_FLAG_PREVENT_YIELD;\n\t\tthr->callstack_preventcount++;\n\n\t\t/* [ ... func this | arg1 ... argN ] ('this' must precede new bottom) */\n\n\t\t/*\n\t\t *  Bytecode executor call.\n\t\t *\n\t\t *  Execute bytecode, handling any recursive function calls and\n\t\t *  thread resumptions.  Returns when execution would return from\n\t\t *  the entry level activation.  When the executor returns, a\n\t\t *  single return value is left on the stack top.\n\t\t *\n\t\t *  The only possible longjmp() is an error (DUK_LJ_TYPE_THROW),\n\t\t *  other types are handled internally by the executor.\n\t\t */\n\n\t\t/* thr->ptr_curr_pc is set by bytecode executor early on entry */\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"entering bytecode execution\"));\n\t\tduk_js_execute_bytecode(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"returned from bytecode execution\"));\n\t} else {\n\t\t/*\n\t\t *  Native call.\n\t\t */\n\n\t\tDUK_ASSERT(func == NULL || ((duk_hnatfunc *) func)->func != NULL);\n\t\tDUK_ASSERT(use_tailcall == 0);\n\n\t\t/* [ ... func this | arg1 ... argN ] ('this' must precede new bottom) */\n\n\t\t/* duk_hthread_activation_unwind_norz() will decrease this on unwind */\n\t\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\t\tact->flags |= DUK_ACT_FLAG_PREVENT_YIELD;\n\t\tthr->callstack_preventcount++;\n\n\t\t/* For native calls must be NULL so we don't sync back */\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\n\t\t/* XXX: native funcptr could come out of call setup. */\n\t\tif (func) {\n\t\t\trc = ((duk_hnatfunc *) func)->func(thr);\n\t\t} else {\n\t\t\tduk_tval *tv_func;\n\t\t\tduk_c_function funcptr;\n\n\t\t\ttv_func = &act->tv_func;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func));\n\t\t\tfuncptr = DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv_func);\n\t\t\trc = funcptr(thr);\n\t\t}\n\n\t\t/* Automatic error throwing, retval check. */\n\n\t\tif (rc == 0) {\n\t\t\tDUK_ASSERT(thr->valstack < thr->valstack_end);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));\n\t\t\tthr->valstack_top++;\n\t\t} else if (rc == 1) {\n\t\t\t;\n\t\t} else if (rc < 0) {\n\t\t\tduk_error_throw_from_negative_rc(thr, rc);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t} else {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_CFUNC_RC);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t}\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\tDUK_ASSERT(use_tailcall == 0);\n\n\t/*\n\t *  Constructor call post processing.\n\t */\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (call_flags & (DUK_CALL_FLAG_CONSTRUCT | DUK_CALL_FLAG_CONSTRUCT_PROXY)) {\n\t\tduk_call_construct_postprocess(thr, call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY);\n\t}\n#else\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tduk_call_construct_postprocess(thr, 0);\n\t}\n#endif\n\n\t/*\n\t *  Unwind, restore valstack bottom and other book-keeping.\n\t */\n\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_curr->parent == entry_act);\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top + 1);\n\tduk_hthread_activation_unwind_norz(thr);\n\tDUK_ASSERT(thr->callstack_curr == entry_act);\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_bottom_byteoff);\n\t/* keep current valstack_top */\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_top - thr->valstack_bottom >= idx_func + 1);\n\n\t/* Return value handling. */\n\n\t/* [ ... func this (crud) retval ] */\n\n\t{\n\t\tduk_tval *tv_ret;\n\t\tduk_tval *tv_funret;\n\n\t\ttv_ret = thr->valstack_bottom + idx_func;\n\t\ttv_funret = thr->valstack_top - 1;\n#if defined(DUK_USE_FASTINT)\n\t\t/* Explicit check for fastint downgrade. */\n\t\tDUK_TVAL_CHKFAST_INPLACE_FAST(tv_funret);\n#endif\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv_ret, tv_funret);  /* side effects */\n\t}\n\n\tduk_set_top_unsafe(thr, idx_func + 1);\n\n\t/* [ ... retval ] */\n\n\t/* Restore caller's value stack reserve (cannot fail). */\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff >= (duk_uint8_t *) thr->valstack_top);\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff <= (duk_uint8_t *) thr->valstack_alloc_end);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff);\n\n\t/* XXX: Trial value stack shrink would be OK here, but we'd need\n\t * to prevent side effects of the potential realloc.\n\t */\n\n\t/* Restore entry thread executor curr_pc stack frame pointer. */\n\tthr->ptr_curr_pc = entry_ptr_curr_pc;\n\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread);  /* may be NULL */\n\tthr->state = (duk_uint8_t) entry_thread_state;\n\n\t/* Disabled assert: triggered with some torture tests. */\n#if 0\n\tDUK_ASSERT((thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread == NULL) ||  /* first call */\n\t           (thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread != NULL) ||  /* other call */\n\t           (thr->state == DUK_HTHREAD_STATE_RUNNING && thr->heap->curr_thread == thr));     /* current thread */\n#endif\n\n\tthr->heap->call_recursion_depth = entry_call_recursion_depth;\n\n\t/* If the debugger is active we need to force an interrupt so that\n\t * debugger breakpoints are rechecked.  This is important for function\n\t * calls caused by side effects (e.g. when doing a DUK_OP_GETPROP), see\n\t * GH-303.  Only needed for success path, error path always causes a\n\t * breakpoint recheck in the executor.  It would be enough to set this\n\t * only when returning to an ECMAScript activation, but setting the flag\n\t * on every return should have no ill effect.\n\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tDUK_DD(DUK_DDPRINT(\"returning with debugger enabled, force interrupt\"));\n\t\tDUK_ASSERT(thr->interrupt_counter <= thr->interrupt_init);\n\t\tthr->interrupt_init -= thr->interrupt_counter;\n\t\tthr->interrupt_counter = 0;\n\t\tthr->heap->dbg_force_restart = 1;\n\t}\n#endif\n\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\tduk__interrupt_fixup(thr, entry_curr_thread);\n#endif\n\n\t/* Restored by success path. */\n\tDUK_ASSERT(thr->heap->call_recursion_depth == entry_call_recursion_depth);\n\tDUK_ASSERT(thr->ptr_curr_pc == entry_ptr_curr_pc);\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\tDUK_REFZERO_CHECK_FAST(thr);\n\n\treturn 0;  /* 0=call handled inline */\n}\n\nDUK_INTERNAL duk_int_t duk_handle_call_unprotected_nargs(duk_hthread *thr,\n                                                         duk_idx_t nargs,\n                                                         duk_small_uint_t call_flags) {\n\tduk_idx_t idx_func;\n\tDUK_ASSERT(duk_get_top(thr) >= nargs + 2);\n\tidx_func = duk_get_top(thr) - (nargs + 2);\n\tDUK_ASSERT(idx_func >= 0);\n\treturn duk_handle_call_unprotected(thr, idx_func, call_flags);\n}\n\nDUK_INTERNAL duk_int_t duk_handle_call_unprotected(duk_hthread *thr,\n                                                   duk_idx_t idx_func,\n                                                   duk_small_uint_t call_flags) {\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\tDUK_ASSERT(idx_func >= 0);\n\treturn duk__handle_call_raw(thr, idx_func, call_flags);\n}\n\n/*\n *  duk_handle_safe_call(): make a \"C protected call\" within the\n *  current activation.\n *\n *  The allowed thread states for making a call are the same as for\n *  duk_handle_call_protected().\n *\n *  Even though this call is protected, errors are thrown for insane arguments\n *  and may result in a fatal error unless there's another protected call which\n *  catches such errors.\n *\n *  The error handling path should be error free, even for out-of-memory\n *  errors, to ensure safe sandboxing.  (As of Duktape 2.2.0 this is not\n *  yet the case for environment closing which may run out of memory, see\n *  XXX notes below.)\n */\n\nDUK_LOCAL void duk__handle_safe_call_inner(duk_hthread *thr,\n                                           duk_safe_call_function func,\n                                           void *udata,\n#if defined(DUK_USE_ASSERTIONS)\n                                           duk_size_t entry_valstack_bottom_byteoff,\n                                           duk_size_t entry_callstack_top,\n#endif\n                                           duk_hthread *entry_curr_thread,\n                                           duk_uint_fast8_t entry_thread_state,\n                                           duk_idx_t idx_retbase,\n                                           duk_idx_t num_stack_rets) {\n\tduk_ret_t rc;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\t/*\n\t *  Thread state check and book-keeping.\n\t */\n\n\tduk__call_thread_state_update(thr);\n\n\t/*\n\t *  Recursion limit check.\n\t */\n\n\tduk__call_c_recursion_limit_check(thr);\n\tthr->heap->call_recursion_depth++;\n\n\t/*\n\t *  Make the C call.\n\t */\n\n\trc = func(thr, udata);\n\n\tDUK_DDD(DUK_DDDPRINT(\"safe_call, func rc=%ld\", (long) rc));\n\n\t/*\n\t *  Valstack manipulation for results.\n\t */\n\n\t/* we're running inside the caller's activation, so no change in call/catch stack or valstack bottom */\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) == entry_valstack_bottom_byteoff);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\n\tif (DUK_UNLIKELY(rc < 0)) {\n\t\tduk_error_throw_from_negative_rc(thr, rc);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(rc >= 0);\n\n\tduk__safe_call_adjust_valstack(thr, idx_retbase, num_stack_rets, rc);  /* throws for insane rc */\n\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread);  /* may be NULL */\n\tthr->state = (duk_uint8_t) entry_thread_state;\n}\n\nDUK_LOCAL void duk__handle_safe_call_error(duk_hthread *thr,\n                                           duk_activation *entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n                                           duk_size_t entry_callstack_top,\n#endif\n                                           duk_hthread *entry_curr_thread,\n                                           duk_uint_fast8_t entry_thread_state,\n                                           duk_idx_t idx_retbase,\n                                           duk_idx_t num_stack_rets,\n                                           duk_size_t entry_valstack_bottom_byteoff,\n                                           duk_jmpbuf *old_jmpbuf_ptr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\t/*\n\t *  Error during call.  The error value is at heap->lj.value1.\n\t *\n\t *  The very first thing we do is restore the previous setjmp catcher.\n\t *  This means that any error in error handling will propagate outwards\n\t *  instead of causing a setjmp() re-entry above.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"error caught during protected duk_handle_safe_call()\"));\n\n\t/* Other longjmp types are handled by executor before propagating\n\t * the error here.\n\t */\n\tDUK_ASSERT(thr->heap->lj.type == DUK_LJ_TYPE_THROW);\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\n\t/* Either pointer may be NULL (at entry), so don't assert. */\n\tthr->heap->lj.jmpbuf_ptr = old_jmpbuf_ptr;\n\n\t/* XXX: callstack unwind may now throw an error when closing\n\t * scopes; this is a sandboxing issue, described in:\n\t * https://github.com/svaarala/duktape/issues/476\n\t */\n\t/* XXX: \"unwind to\" primitive? */\n\n\tDUK_ASSERT(thr->callstack_top >= entry_callstack_top);\n\twhile (thr->callstack_curr != entry_act) {\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tduk_hthread_activation_unwind_norz(thr);\n\t}\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\n\t/* Switch active thread before any side effects to avoid a\n\t * dangling curr_thread pointer.\n\t */\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread);  /* may be NULL */\n\tthr->state = (duk_uint8_t) entry_thread_state;\n\n\tDUK_ASSERT(thr->heap->curr_thread == entry_curr_thread);\n\tDUK_ASSERT(thr->state == entry_thread_state);\n\n\t/* Restore valstack bottom. */\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_bottom_byteoff);\n\n\t/* [ ... | (crud) ] */\n\n\t/* XXX: ensure space in valstack (now relies on internal reserve)? */\n\tduk_push_tval(thr, &thr->heap->lj.value1);\n\n\t/* [ ... | (crud) errobj ] */\n\n\tDUK_ASSERT(duk_get_top(thr) >= 1);  /* at least errobj must be on stack */\n\n\tduk__safe_call_adjust_valstack(thr, idx_retbase, num_stack_rets, 1);  /* 1 = num actual 'return values' */\n\n\t/* [ ... | ] or [ ... | errobj (M * undefined)] where M = num_stack_rets - 1 */\n\n\t/* Reset longjmp state. */\n\tthr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;\n\tthr->heap->lj.iserror = 0;\n\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, &thr->heap->lj.value1);\n\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, &thr->heap->lj.value2);\n\n\t/* Error handling complete, remove side effect protections.  Caller\n\t * will process pending finalizers.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->heap->error_not_allowed == 1);\n\tthr->heap->error_not_allowed = 0;\n#endif\n\tDUK_ASSERT(thr->heap->pf_prevent_count > 0);\n\tthr->heap->pf_prevent_count--;\n\tDUK_DD(DUK_DDPRINT(\"safe call error handled, pf_prevent_count updated to %ld\", (long) thr->heap->pf_prevent_count));\n\n\t/* thr->ptr_curr_pc is restored by\n\t * duk__handle_safe_call_shared_unwind() which is also used for\n\t * success path.\n\t */\n}\n\nDUK_LOCAL void duk__handle_safe_call_shared_unwind(duk_hthread *thr,\n                                                   duk_idx_t idx_retbase,\n                                                   duk_idx_t num_stack_rets,\n#if defined(DUK_USE_ASSERTIONS)\n                                                   duk_size_t entry_callstack_top,\n#endif\n                                                   duk_int_t entry_call_recursion_depth,\n                                                   duk_hthread *entry_curr_thread,\n                                                   duk_instr_t **entry_ptr_curr_pc) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(idx_retbase);\n\tDUK_UNREF(num_stack_rets);\n\tDUK_UNREF(entry_curr_thread);\n\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\n\t/* Restore entry thread executor curr_pc stack frame pointer.\n\t * XXX: would be enough to do in error path only, should nest\n\t * cleanly in success path.\n\t */\n\tthr->ptr_curr_pc = entry_ptr_curr_pc;\n\n\tthr->heap->call_recursion_depth = entry_call_recursion_depth;\n\n\t/* stack discipline consistency check */\n\tDUK_ASSERT(duk_get_top(thr) == idx_retbase + num_stack_rets);\n\n\t/* A debugger forced interrupt check is not needed here, as\n\t * problematic safe calls are not caused by side effects.\n\t */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\tduk__interrupt_fixup(thr, entry_curr_thread);\n#endif\n}\n\nDUK_INTERNAL duk_int_t duk_handle_safe_call(duk_hthread *thr,\n                                            duk_safe_call_function func,\n                                            void *udata,\n                                            duk_idx_t num_stack_args,\n                                            duk_idx_t num_stack_rets) {\n\tduk_activation *entry_act;\n\tduk_size_t entry_valstack_bottom_byteoff;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_size_t entry_valstack_end_byteoff;\n\tduk_size_t entry_callstack_top;\n\tduk_size_t entry_callstack_preventcount;\n#endif\n\tduk_int_t entry_call_recursion_depth;\n\tduk_hthread *entry_curr_thread;\n\tduk_uint_fast8_t entry_thread_state;\n\tduk_instr_t **entry_ptr_curr_pc;\n\tduk_jmpbuf *old_jmpbuf_ptr = NULL;\n\tduk_jmpbuf our_jmpbuf;\n\tduk_idx_t idx_retbase;\n\tduk_int_t retval;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(duk_get_top(thr) >= num_stack_args);  /* Caller ensures. */\n\n\tDUK_STATS_INC(thr->heap, stats_safecall_all);\n\n\t/* Value stack reserve handling: safe call assumes caller has reserved\n\t * space for nrets (assuming optimal unwind processing).  Value stack\n\t * reserve is not stored/restored as for normal calls because a safe\n\t * call conceptually happens in the same activation.\n\t */\n\n\t/* Careful with indices like '-x'; if 'x' is zero, it refers to bottom */\n\tentry_act = thr->callstack_curr;\n\tentry_valstack_bottom_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_valstack_end_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tentry_callstack_top = thr->callstack_top;\n\tentry_callstack_preventcount = thr->callstack_preventcount;\n#endif\n\tentry_call_recursion_depth = thr->heap->call_recursion_depth;\n\tentry_curr_thread = thr->heap->curr_thread;  /* may be NULL if first call */\n\tentry_thread_state = thr->state;\n\tentry_ptr_curr_pc = thr->ptr_curr_pc;  /* may be NULL */\n\tidx_retbase = duk_get_top(thr) - num_stack_args;  /* not a valid stack index if num_stack_args == 0 */\n\tDUK_ASSERT(idx_retbase >= 0);\n\n\tDUK_ASSERT((duk_idx_t) (thr->valstack_top - thr->valstack_bottom) >= num_stack_args);  /* Caller ensures. */\n\tDUK_ASSERT((duk_idx_t) (thr->valstack_end - (thr->valstack_bottom + idx_retbase)) >= num_stack_rets);  /* Caller ensures. */\n\n\t/* Cannot portably debug print a function pointer, hence 'func' not printed! */\n\tDUK_DD(DUK_DDPRINT(\"duk_handle_safe_call: thr=%p, num_stack_args=%ld, num_stack_rets=%ld, \"\n\t                   \"valstack_top=%ld, idx_retbase=%ld, rec_depth=%ld/%ld, \"\n\t                   \"entry_act=%p, entry_valstack_bottom_byteoff=%ld, entry_call_recursion_depth=%ld, \"\n\t                   \"entry_curr_thread=%p, entry_thread_state=%ld\",\n\t                   (void *) thr,\n\t                   (long) num_stack_args,\n\t                   (long) num_stack_rets,\n\t                   (long) duk_get_top(thr),\n\t                   (long) idx_retbase,\n\t                   (long) thr->heap->call_recursion_depth,\n\t                   (long) thr->heap->call_recursion_limit,\n\t                   (void *) entry_act,\n\t                   (long) entry_valstack_bottom_byteoff,\n\t                   (long) entry_call_recursion_depth,\n\t                   (void *) entry_curr_thread,\n\t                   (long) entry_thread_state));\n\n\t/* Setjmp catchpoint setup. */\n\told_jmpbuf_ptr = thr->heap->lj.jmpbuf_ptr;\n\tthr->heap->lj.jmpbuf_ptr = &our_jmpbuf;\n\n\t/* Prevent yields for the duration of the safe call.  This only\n\t * matters if the executor makes safe calls to functions that\n\t * yield, this doesn't currently happen.\n\t */\n\tthr->callstack_preventcount++;\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\ttry {\n#else\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr == &our_jmpbuf);\n\tif (DUK_SETJMP(our_jmpbuf.jb) == 0) {\n\t\t/* Success path. */\n#endif\n\t\tDUK_DDD(DUK_DDDPRINT(\"safe_call setjmp catchpoint setup complete\"));\n\n\t\tduk__handle_safe_call_inner(thr,\n\t\t                            func,\n\t\t                            udata,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t                            entry_valstack_bottom_byteoff,\n\t\t                            entry_callstack_top,\n#endif\n\t\t                            entry_curr_thread,\n\t\t                            entry_thread_state,\n\t\t                            idx_retbase,\n\t\t                            num_stack_rets);\n\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_nothrow);\n\n\t\t/* Either pointer may be NULL (at entry), so don't assert */\n\t\tthr->heap->lj.jmpbuf_ptr = old_jmpbuf_ptr;\n\n\t\t/* If calls happen inside the safe call, these are restored by\n\t\t * whatever calls are made.  Reserve cannot decrease.\n\t\t */\n\t\tDUK_ASSERT(thr->callstack_curr == entry_act);\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\n\t\tretval = DUK_EXEC_SUCCESS;\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t} catch (duk_internal_exception &exc) {\n\t\tDUK_UNREF(exc);\n#else\n\t} else {\n\t\t/* Error path. */\n#endif\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_throw);\n\n\t\tduk__handle_safe_call_error(thr,\n\t\t                            entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t                            entry_callstack_top,\n#endif\n\t\t                            entry_curr_thread,\n\t\t                            entry_thread_state,\n\t\t                            idx_retbase,\n\t\t                            num_stack_rets,\n\t\t                            entry_valstack_bottom_byteoff,\n\t\t                            old_jmpbuf_ptr);\n\n\t\tretval = DUK_EXEC_ERROR;\n\t}\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\tcatch (duk_fatal_exception &exc) {\n\t\tDUK_D(DUK_DPRINT(\"rethrow duk_fatal_exception\"));\n\t\tthrow;\n\t} catch (std::exception &exc) {\n\t\tconst char *what = exc.what();\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_throw);\n\t\tif (!what) {\n\t\t\twhat = \"unknown\";\n\t\t}\n\t\tDUK_D(DUK_DPRINT(\"unexpected c++ std::exception (perhaps thrown by user code)\"));\n\t\ttry {\n\t\t\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"caught invalid c++ std::exception '%s' (perhaps thrown by user code)\", what);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t} catch (duk_internal_exception exc) {\n\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ std::exception\"));\n\t\t\tDUK_UNREF(exc);\n\t\t\tduk__handle_safe_call_error(thr,\n\t\t\t                            entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t                            entry_callstack_top,\n#endif\n\t\t\t                            entry_curr_thread,\n\t\t\t                            entry_thread_state,\n\t\t\t                            idx_retbase,\n\t\t\t                            num_stack_rets,\n\t\t\t                            entry_valstack_bottom_byteoff,\n\t\t\t                            old_jmpbuf_ptr);\n\t\t\tretval = DUK_EXEC_ERROR;\n\t\t}\n\t} catch (...) {\n\t\tDUK_D(DUK_DPRINT(\"unexpected c++ exception (perhaps thrown by user code)\"));\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_throw);\n\t\ttry {\n\t\t\tDUK_ERROR_TYPE(thr, \"caught invalid c++ exception (perhaps thrown by user code)\");\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t} catch (duk_internal_exception exc) {\n\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ exception\"));\n\t\t\tDUK_UNREF(exc);\n\t\t\tduk__handle_safe_call_error(thr,\n\t\t\t                            entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t                            entry_callstack_top,\n#endif\n\t\t\t                            entry_curr_thread,\n\t\t\t                            entry_thread_state,\n\t\t\t                            idx_retbase,\n\t\t\t                            num_stack_rets,\n\t\t\t                            entry_valstack_bottom_byteoff,\n\t\t\t                            old_jmpbuf_ptr);\n\t\t\tretval = DUK_EXEC_ERROR;\n\t\t}\n\t}\n#endif\n\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr == old_jmpbuf_ptr);  /* success/error path both do this */\n\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\tduk__handle_safe_call_shared_unwind(thr,\n\t                                    idx_retbase,\n\t                                    num_stack_rets,\n#if defined(DUK_USE_ASSERTIONS)\n\t                                    entry_callstack_top,\n#endif\n\t                                    entry_call_recursion_depth,\n\t                                    entry_curr_thread,\n\t                                    entry_ptr_curr_pc);\n\n\t/* Restore preventcount. */\n\tthr->callstack_preventcount--;\n\tDUK_ASSERT(thr->callstack_preventcount == entry_callstack_preventcount);\n\n\t/* Final asserts. */\n\tDUK_ASSERT(thr->callstack_curr == entry_act);\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) == entry_valstack_bottom_byteoff);\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\tDUK_ASSERT(thr->heap->call_recursion_depth == entry_call_recursion_depth);\n\tDUK_ASSERT(thr->heap->curr_thread == entry_curr_thread);\n\tDUK_ASSERT(thr->state == entry_thread_state);\n\tDUK_ASSERT(thr->ptr_curr_pc == entry_ptr_curr_pc);\n\tDUK_ASSERT(duk_get_top(thr) == idx_retbase + num_stack_rets);\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\t/* Pending side effects. */\n\tDUK_REFZERO_CHECK_FAST(thr);\n\n\treturn retval;\n}\n\n/*\n *  Property-based call (foo.noSuch()) error setup: replace target function\n *  on stack top with a hidden Symbol tagged non-callable wrapper object\n *  holding the error.  The error gets thrown in call handling at the\n *  proper spot to follow ECMAScript semantics.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_INTERNAL DUK_NOINLINE DUK_COLD void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_base, duk_tval *tv_key) {\n\tconst char *str_targ, *str_key, *str_base;\n\tduk_idx_t entry_top;\n\n\tentry_top = duk_get_top(thr);\n\n\t/* [ <nargs> target ] */\n\n\t/* Must stabilize pointers first.  tv_targ is already on stack top. */\n\tduk_push_tval(thr, tv_base);\n\tduk_push_tval(thr, tv_key);\n\n\tDUK_GC_TORTURE(thr->heap);\n\n\tduk_push_bare_object(thr);\n\n\t/* [ <nargs> target base key {} ] */\n\n\t/* We only push a wrapped error, replacing the call target (at\n\t * idx_func) with the error to ensure side effects come out\n\t * correctly:\n\t * - Property read\n\t * - Call argument evaluation\n\t * - Callability check and error thrown\n\t *\n\t * A hidden Symbol on the wrapper object pushed above is used by\n\t * call handling to figure out the error is to be thrown as is.\n\t * It is CRITICAL that the hidden Symbol can never occur on a\n\t * user visible object that may get thrown.\n\t */\n\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tstr_targ = duk_get_type_name(thr, -4);\n\tstr_key = duk_get_type_name(thr, -2);\n\tstr_base = duk_get_type_name(thr, -3);\n\tduk_push_error_object(thr,\n\t                      DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t                      \"%s not callable (property %s of %s)\", str_targ, str_key, str_base);\n\tduk_xdef_prop_stridx(thr, -2, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE);  /* Marker property, reuse _Target. */\n\t/* [ <nargs> target base key { _Target: error } ] */\n\tduk_replace(thr, entry_top - 1);\n#else\n\tstr_targ = duk_push_string_readable(thr, -4);\n\tstr_key = duk_push_string_readable(thr, -3);\n\tstr_base = duk_push_string_readable(thr, -5);\n\tduk_push_error_object(thr,\n\t                      DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t                      \"%s not callable (property %s of %s)\", str_targ, str_key, str_base);\n\t/* [ <nargs> target base key {} str_targ str_key str_base error ] */\n\tduk_xdef_prop_stridx(thr, -5, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE);  /* Marker property, reuse _Target. */\n\t/* [ <nargs> target base key { _Target: error } str_targ str_key str_base ] */\n\tduk_swap(thr, -4, entry_top - 1);\n\t/* [ <nargs> { _Target: error } base key target str_targ str_key str_base ] */\n#endif\n\n\t/* [ <nregs> { _Target: error } <variable> */\n\tduk_set_top(thr, entry_top);\n\n\t/* [ <nregs> { _Target: error } */\n\tDUK_ASSERT(!duk_is_callable(thr, -1));  /* Critical so that call handling will throw the error. */\n}\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_js_compiler.c",
    "content": "/*\n *  ECMAScript compiler.\n *\n *  Parses an input string and generates a function template result.\n *  Compilation may happen in multiple contexts (global code, eval\n *  code, function code).\n *\n *  The parser uses a traditional top-down recursive parsing for the\n *  statement level, and an operator precedence based top-down approach\n *  for the expression level.  The attempt is to minimize the C stack\n *  depth.  Bytecode is generated directly without an intermediate\n *  representation (tree), at the cost of needing two (and sometimes\n *  three) passes over each function.\n *\n *  The top-down recursive parser functions are named \"duk__parse_XXX\".\n *\n *  Recursion limits are in key functions to prevent arbitrary C recursion:\n *  function body parsing, statement parsing, and expression parsing.\n *\n *  See doc/compiler.rst for discussion on the design.\n *\n *  A few typing notes:\n *\n *    - duk_regconst_t: signed, highest bit set (< 0) means constant,\n *      some call sites use -1 for \"none\" (equivalent to constant 0x7fffffff)\n *    - PC values: duk_int_t, negative values used as markers\n */\n\n#include \"duk_internal.h\"\n\n/* If highest bit of a register number is set, it refers to a constant instead.\n * When interpreted as a signed value, this means const values are always\n * negative (when interpreted as two's complement).  For example DUK__ISREG_TEMP()\n * uses this approach to avoid an explicit DUK__ISREG() check (the condition is\n * logically \"'x' is a register AND 'x' >= temp_first\").\n */\n#define DUK__CONST_MARKER                   DUK_REGCONST_CONST_MARKER\n#define DUK__REMOVECONST(x)                 ((x) & ~DUK__CONST_MARKER)\n#define DUK__ISREG(x)                       ((x) >= 0)\n#define DUK__ISCONST(x)                     ((x) < 0)\n#define DUK__ISREG_TEMP(comp_ctx,x)         ((duk_int32_t) (x) >= (duk_int32_t) ((comp_ctx)->curr_func.temp_first))   /* Check for x >= temp_first && x >= 0 by comparing as signed. */\n#define DUK__ISREG_NOTTEMP(comp_ctx,x)      ((duk_uint32_t) (x) < (duk_uint32_t) ((comp_ctx)->curr_func.temp_first))  /* Check for x >= 0 && x < temp_first by interpreting as unsigned. */\n#define DUK__GETTEMP(comp_ctx)              ((comp_ctx)->curr_func.temp_next)\n#define DUK__SETTEMP(comp_ctx,x)            ((comp_ctx)->curr_func.temp_next = (x))  /* dangerous: must only lower (temp_max not updated) */\n#define DUK__SETTEMP_CHECKMAX(comp_ctx,x)   duk__settemp_checkmax((comp_ctx),(x))\n#define DUK__ALLOCTEMP(comp_ctx)            duk__alloctemp((comp_ctx))\n#define DUK__ALLOCTEMPS(comp_ctx,count)     duk__alloctemps((comp_ctx),(count))\n\n/* Init value set size for array and object literals. */\n#define DUK__MAX_ARRAY_INIT_VALUES        20\n#define DUK__MAX_OBJECT_INIT_PAIRS        10\n\n/* XXX: hack, remove when const lookup is not O(n) */\n#define DUK__GETCONST_MAX_CONSTS_CHECK    256\n\n/* These limits are based on bytecode limits.  Max temps is limited\n * by duk_hcompfunc nargs/nregs fields being 16 bits.\n */\n#define DUK__MAX_CONSTS                   DUK_BC_BC_MAX\n#define DUK__MAX_FUNCS                    DUK_BC_BC_MAX\n#define DUK__MAX_TEMPS                    0xffffL\n\n/* Initial bytecode size allocation. */\n#if defined(DUK_USE_PREFER_SIZE)\n#define DUK__BC_INITIAL_INSTS             16\n#else\n#define DUK__BC_INITIAL_INSTS             256\n#endif\n\n#define DUK__RECURSION_INCREASE(comp_ctx,thr)  do { \\\n\t\tDUK_DDD(DUK_DDDPRINT(\"RECURSION INCREASE: %s:%ld\", (const char *) DUK_FILE_MACRO, (long) DUK_LINE_MACRO)); \\\n\t\tduk__comp_recursion_increase((comp_ctx)); \\\n\t} while (0)\n\n#define DUK__RECURSION_DECREASE(comp_ctx,thr)  do { \\\n\t\tDUK_DDD(DUK_DDDPRINT(\"RECURSION DECREASE: %s:%ld\", (const char *) DUK_FILE_MACRO, (long) DUK_LINE_MACRO)); \\\n\t\tduk__comp_recursion_decrease((comp_ctx)); \\\n\t} while (0)\n\n/* Value stack slot limits: these are quite approximate right now, and\n * because they overlap in control flow, some could be eliminated.\n */\n#define DUK__COMPILE_ENTRY_SLOTS          8\n#define DUK__FUNCTION_INIT_REQUIRE_SLOTS  16\n#define DUK__FUNCTION_BODY_REQUIRE_SLOTS  16\n#define DUK__PARSE_STATEMENTS_SLOTS       16\n#define DUK__PARSE_EXPR_SLOTS             16\n\n/* Temporary structure used to pass a stack allocated region through\n * duk_safe_call().\n */\ntypedef struct {\n\tduk_small_uint_t flags;\n\tduk_compiler_ctx comp_ctx_alloc;\n\tduk_lexer_point lex_pt_alloc;\n} duk__compiler_stkstate;\n\n/*\n *  Prototypes\n */\n\n/* lexing */\nDUK_LOCAL_DECL void duk__advance_helper(duk_compiler_ctx *comp_ctx, duk_small_int_t expect);\nDUK_LOCAL_DECL void duk__advance_expect(duk_compiler_ctx *comp_ctx, duk_small_int_t expect);\nDUK_LOCAL_DECL void duk__advance(duk_compiler_ctx *ctx);\n\n/* function helpers */\nDUK_LOCAL_DECL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ctx, duk_regconst_t *out_stmt_value_reg);\nDUK_LOCAL_DECL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx);\n\n/* code emission */\nDUK_LOCAL_DECL duk_int_t duk__get_current_pc(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_compiler_instr *duk__get_instr_ptr(duk_compiler_ctx *comp_ctx, duk_int_t pc);\nDUK_LOCAL_DECL void duk__emit(duk_compiler_ctx *comp_ctx, duk_instr_t ins);\nDUK_LOCAL_DECL void duk__emit_op_only(duk_compiler_ctx *comp_ctx, duk_small_uint_t op);\nDUK_LOCAL_DECL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b, duk_regconst_t c);\nDUK_LOCAL_DECL void duk__emit_a_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b);\nDUK_LOCAL_DECL void duk__emit_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b, duk_regconst_t c);\n#if 0  /* unused */\nDUK_LOCAL_DECL void duk__emit_a(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a);\nDUK_LOCAL_DECL void duk__emit_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b);\n#endif\nDUK_LOCAL_DECL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t bc);\nDUK_LOCAL_DECL void duk__emit_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t bc);\nDUK_LOCAL_DECL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t abc);\nDUK_LOCAL_DECL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val);\nDUK_LOCAL_DECL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val);\nDUK_LOCAL_DECL void duk__emit_jump(duk_compiler_ctx *comp_ctx, duk_int_t target_pc);\nDUK_LOCAL_DECL duk_int_t duk__emit_jump_empty(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc);\nDUK_LOCAL_DECL void duk__patch_jump(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc, duk_int_t target_pc);\nDUK_LOCAL_DECL void duk__patch_jump_here(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc);\nDUK_LOCAL_DECL void duk__patch_trycatch(duk_compiler_ctx *comp_ctx, duk_int_t ldconst_pc, duk_int_t trycatch_pc, duk_regconst_t reg_catch, duk_regconst_t const_varname, duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__emit_if_false_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst);\nDUK_LOCAL_DECL void duk__emit_if_true_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst);\nDUK_LOCAL_DECL void duk__emit_invalid(duk_compiler_ctx *comp_ctx);\n\n/* ivalue/ispec helpers */\nDUK_LOCAL_DECL void duk__ivalue_regconst(duk_ivalue *x, duk_regconst_t regconst);\nDUK_LOCAL_DECL void duk__ivalue_plain_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL void duk__ivalue_var_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL void duk__ivalue_var_hstring(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_hstring *h);\nDUK_LOCAL_DECL void duk__copy_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *src, duk_ispec *dst);\nDUK_LOCAL_DECL void duk__copy_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *src, duk_ivalue *dst);\nDUK_LOCAL_DECL duk_regconst_t duk__alloctemps(duk_compiler_ctx *comp_ctx, duk_small_int_t num);\nDUK_LOCAL_DECL duk_regconst_t duk__alloctemp(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, duk_regconst_t temp_next);\nDUK_LOCAL_DECL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL\nduk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                         duk_ispec *x,\n                                         duk_regconst_t forced_reg,\n                                         duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ispec *x, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL void duk__ivalue_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL void duk__ivalue_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL\nduk_regconst_t duk__ivalue_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                          duk_ivalue *x,\n                                          duk_regconst_t forced_reg,\n                                          duk_small_uint_t flags);\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\n#endif\nDUK_LOCAL_DECL void duk__ivalue_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_int_t forced_reg);\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\n\n/* identifier handling */\nDUK_LOCAL_DECL duk_regconst_t duk__lookup_active_register_binding(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *ctx, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname);\n\n/* label handling */\nDUK_LOCAL_DECL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_int_t pc_label, duk_int_t label_id);\nDUK_LOCAL_DECL void duk__update_label_flags(duk_compiler_ctx *comp_ctx, duk_int_t label_id, duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_bool_t is_break, duk_int_t *out_label_id, duk_int_t *out_label_catch_depth, duk_int_t *out_label_pc, duk_bool_t *out_is_closest);\nDUK_LOCAL_DECL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, duk_size_t len);\n\n/* top-down expression parser */\nDUK_LOCAL_DECL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_ivalue *res);\nDUK_LOCAL_DECL duk_small_uint_t duk__expr_lbp(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_bool_t duk__expr_is_empty(duk_compiler_ctx *comp_ctx);\n\n/* exprtop is the top level variant which resets nud/led counts */\nDUK_LOCAL_DECL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\nDUK_LOCAL_DECL void duk__exprtop(duk_compiler_ctx *ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n\n/* convenience helpers */\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__expr_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__expr_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\nDUK_LOCAL_DECL void duk__expr_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL duk_regconst_t duk__expr_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__expr_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\nDUK_LOCAL_DECL void duk__expr_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\nDUK_LOCAL_DECL void duk__expr_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\nDUK_LOCAL_DECL duk_regconst_t duk__exprtop_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__exprtop_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\nDUK_LOCAL_DECL void duk__exprtop_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL duk_regconst_t duk__exprtop_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#if 0  /* unused */\nDUK_LOCAL_DECL void duk__exprtop_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\n\n/* expression parsing helpers */\nDUK_LOCAL_DECL duk_int_t duk__parse_arguments(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\n\n/* statement parsing */\nDUK_LOCAL_DECL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname);\nDUK_LOCAL_DECL void duk__parse_var_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags);\nDUK_LOCAL_DECL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_if_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_do_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_while_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_break_or_continue_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_throw_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_bool_t allow_source_elem);\nDUK_LOCAL_DECL duk_int_t duk__stmt_label_site(duk_compiler_ctx *comp_ctx, duk_int_t label_id);\nDUK_LOCAL_DECL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_source_elem, duk_bool_t expect_eof, duk_bool_t regexp_after);\n\nDUK_LOCAL_DECL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expect_eof, duk_bool_t implicit_return_value, duk_bool_t regexp_after, duk_small_int_t expect_token);\nDUK_LOCAL_DECL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags);\nDUK_LOCAL_DECL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags);\n\n#define DUK__FUNC_FLAG_DECL            (1 << 0)   /* Parsing a function declaration. */\n#define DUK__FUNC_FLAG_GETSET          (1 << 1)   /* Parsing an object literal getter/setter. */\n#define DUK__FUNC_FLAG_METDEF          (1 << 2)   /* Parsing an object literal method definition shorthand. */\n#define DUK__FUNC_FLAG_PUSHNAME_PASS1  (1 << 3)   /* Push function name when creating template (first pass only). */\n#define DUK__FUNC_FLAG_USE_PREVTOKEN   (1 << 4)   /* Use prev_token to start function parsing (workaround for object literal). */\n\n/*\n *  Parser control values for tokens.  The token table is ordered by the\n *  DUK_TOK_XXX defines.\n *\n *  The binding powers are for lbp() use (i.e. for use in led() context).\n *  Binding powers are positive for typing convenience, and bits at the\n *  top should be reserved for flags.  Binding power step must be higher\n *  than 1 so that binding power \"lbp - 1\" can be used for right associative\n *  operators.  Currently a step of 2 is used (which frees one more bit for\n *  flags).\n */\n\n/* XXX: actually single step levels would work just fine, clean up */\n\n/* binding power \"levels\" (see doc/compiler.rst) */\n#define DUK__BP_INVALID                0             /* always terminates led() */\n#define DUK__BP_EOF                    2\n#define DUK__BP_CLOSING                4             /* token closes expression, e.g. ')', ']' */\n#define DUK__BP_FOR_EXPR               DUK__BP_CLOSING    /* bp to use when parsing a top level Expression */\n#define DUK__BP_COMMA                  6\n#define DUK__BP_ASSIGNMENT             8\n#define DUK__BP_CONDITIONAL            10\n#define DUK__BP_LOR                    12\n#define DUK__BP_LAND                   14\n#define DUK__BP_BOR                    16\n#define DUK__BP_BXOR                   18\n#define DUK__BP_BAND                   20\n#define DUK__BP_EQUALITY               22\n#define DUK__BP_RELATIONAL             24\n#define DUK__BP_SHIFT                  26\n#define DUK__BP_ADDITIVE               28\n#define DUK__BP_MULTIPLICATIVE         30\n#define DUK__BP_EXPONENTIATION         32\n#define DUK__BP_POSTFIX                34\n#define DUK__BP_CALL                   36\n#define DUK__BP_MEMBER                 38\n\n#define DUK__TOKEN_LBP_BP_MASK         0x1f\n#define DUK__TOKEN_LBP_FLAG_NO_REGEXP  (1 << 5)   /* regexp literal must not follow this token */\n#define DUK__TOKEN_LBP_FLAG_TERMINATES (1 << 6)   /* terminates expression; e.g. post-increment/-decrement */\n#define DUK__TOKEN_LBP_FLAG_UNUSED     (1 << 7)   /* unused */\n\n#define DUK__TOKEN_LBP_GET_BP(x)       ((duk_small_uint_t) (((x) & DUK__TOKEN_LBP_BP_MASK) * 2))\n\n#define DUK__MK_LBP(bp)                ((bp) >> 1)    /* bp is assumed to be even */\n#define DUK__MK_LBP_FLAGS(bp,flags)    (((bp) >> 1) | (flags))\n\nDUK_LOCAL const duk_uint8_t duk__token_lbp[] = {\n\tDUK__MK_LBP(DUK__BP_EOF),                                 /* DUK_TOK_EOF */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_IDENTIFIER */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_BREAK */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CASE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CATCH */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CONTINUE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DEBUGGER */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DEFAULT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DELETE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DO */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_ELSE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_FINALLY */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_FOR */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_FUNCTION */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_IF */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_IN */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_INSTANCEOF */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_NEW */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_RETURN */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SWITCH */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_THIS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_THROW */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_TRY */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_TYPEOF */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_VAR */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CONST */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_VOID */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_WHILE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_WITH */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CLASS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_ENUM */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_EXPORT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_EXTENDS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_IMPORT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SUPER */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_NULL */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_TRUE */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_FALSE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_GET */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SET */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_IMPLEMENTS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_INTERFACE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_LET */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PACKAGE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PRIVATE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PROTECTED */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PUBLIC */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_STATIC */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_YIELD */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_LCURLY */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_RCURLY */\n\tDUK__MK_LBP(DUK__BP_MEMBER),                              /* DUK_TOK_LBRACKET */\n\tDUK__MK_LBP_FLAGS(DUK__BP_CLOSING, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_RBRACKET */\n\tDUK__MK_LBP(DUK__BP_CALL),                                /* DUK_TOK_LPAREN */\n\tDUK__MK_LBP_FLAGS(DUK__BP_CLOSING, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_RPAREN */\n\tDUK__MK_LBP(DUK__BP_MEMBER),                              /* DUK_TOK_PERIOD */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SEMICOLON */\n\tDUK__MK_LBP(DUK__BP_COMMA),                               /* DUK_TOK_COMMA */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_LT */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_GT */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_LE */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_GE */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_EQ */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_NEQ */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_SEQ */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_SNEQ */\n\tDUK__MK_LBP(DUK__BP_ADDITIVE),                            /* DUK_TOK_ADD */\n\tDUK__MK_LBP(DUK__BP_ADDITIVE),                            /* DUK_TOK_SUB */\n\tDUK__MK_LBP(DUK__BP_MULTIPLICATIVE),                      /* DUK_TOK_MUL */\n\tDUK__MK_LBP(DUK__BP_MULTIPLICATIVE),                      /* DUK_TOK_DIV */\n\tDUK__MK_LBP(DUK__BP_MULTIPLICATIVE),                      /* DUK_TOK_MOD */\n\tDUK__MK_LBP(DUK__BP_EXPONENTIATION),                      /* DUK_TOK_EXP */\n\tDUK__MK_LBP_FLAGS(DUK__BP_POSTFIX, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_INCREMENT */\n\tDUK__MK_LBP_FLAGS(DUK__BP_POSTFIX, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_DECREMENT */\n\tDUK__MK_LBP(DUK__BP_SHIFT),                               /* DUK_TOK_ALSHIFT */\n\tDUK__MK_LBP(DUK__BP_SHIFT),                               /* DUK_TOK_ARSHIFT */\n\tDUK__MK_LBP(DUK__BP_SHIFT),                               /* DUK_TOK_RSHIFT */\n\tDUK__MK_LBP(DUK__BP_BAND),                                /* DUK_TOK_BAND */\n\tDUK__MK_LBP(DUK__BP_BOR),                                 /* DUK_TOK_BOR */\n\tDUK__MK_LBP(DUK__BP_BXOR),                                /* DUK_TOK_BXOR */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_LNOT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_BNOT */\n\tDUK__MK_LBP(DUK__BP_LAND),                                /* DUK_TOK_LAND */\n\tDUK__MK_LBP(DUK__BP_LOR),                                 /* DUK_TOK_LOR */\n\tDUK__MK_LBP(DUK__BP_CONDITIONAL),                         /* DUK_TOK_QUESTION */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_COLON */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_EQUALSIGN */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_ADD_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_SUB_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_MUL_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_DIV_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_MOD_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_EXP_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_ALSHIFT_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_ARSHIFT_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_RSHIFT_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_BAND_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_BOR_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_BXOR_EQ */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_NUMBER */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_STRING */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_REGEXP */\n};\n\n/*\n *  Misc helpers\n */\n\nDUK_LOCAL void duk__comp_recursion_increase(duk_compiler_ctx *comp_ctx) {\n\tDUK_ASSERT(comp_ctx != NULL);\n\tDUK_ASSERT(comp_ctx->recursion_depth >= 0);\n\tif (comp_ctx->recursion_depth >= comp_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_COMPILER_RECURSION_LIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tcomp_ctx->recursion_depth++;\n}\n\nDUK_LOCAL void duk__comp_recursion_decrease(duk_compiler_ctx *comp_ctx) {\n\tDUK_ASSERT(comp_ctx != NULL);\n\tDUK_ASSERT(comp_ctx->recursion_depth > 0);\n\tcomp_ctx->recursion_depth--;\n}\n\nDUK_LOCAL duk_bool_t duk__hstring_is_eval_or_arguments(duk_compiler_ctx *comp_ctx, duk_hstring *h) {\n\tDUK_UNREF(comp_ctx);\n\tDUK_ASSERT(h != NULL);\n\treturn DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(h);\n}\n\nDUK_LOCAL duk_bool_t duk__hstring_is_eval_or_arguments_in_strict_mode(duk_compiler_ctx *comp_ctx, duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n\treturn (comp_ctx->curr_func.is_strict &&\n\t        DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(h));\n}\n\n/*\n *  Parser duk__advance() token eating functions\n */\n\n/* XXX: valstack handling is awkward.  Add a valstack helper which\n * avoids dup():ing; valstack_copy(src, dst)?\n */\n\nDUK_LOCAL void duk__advance_helper(duk_compiler_ctx *comp_ctx, duk_small_int_t expect) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t regexp;\n\n\tDUK_ASSERT_DISABLE(comp_ctx->curr_token.t >= 0);  /* unsigned */\n\tDUK_ASSERT(comp_ctx->curr_token.t <= DUK_TOK_MAXVAL);  /* MAXVAL is inclusive */\n\n\t/*\n\t *  Use current token to decide whether a RegExp can follow.\n\t *\n\t *  We can use either 't' or 't_nores'; the latter would not\n\t *  recognize keywords.  Some keywords can be followed by a\n\t *  RegExp (e.g. \"return\"), so using 't' is better.  This is\n\t *  not trivial, see doc/compiler.rst.\n\t */\n\n\tregexp = 1;\n\tif (duk__token_lbp[comp_ctx->curr_token.t] & DUK__TOKEN_LBP_FLAG_NO_REGEXP) {\n\t\tregexp = 0;\n\t}\n\tif (comp_ctx->curr_func.reject_regexp_in_adv) {\n\t\tcomp_ctx->curr_func.reject_regexp_in_adv = 0;\n\t\tregexp = 0;\n\t}\n\tif (comp_ctx->curr_func.allow_regexp_in_adv) {\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 0;\n\t\tregexp = 1;\n\t}\n\n\tif (expect >= 0 && comp_ctx->curr_token.t != (duk_small_uint_t) expect) {\n\t\tDUK_D(DUK_DPRINT(\"parse error: expect=%ld, got=%ld\",\n\t\t                 (long) expect, (long) comp_ctx->curr_token.t));\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* make current token the previous; need to fiddle with valstack \"backing store\" */\n\tduk_memcpy(&comp_ctx->prev_token, &comp_ctx->curr_token, sizeof(duk_token));\n\tduk_copy(thr, comp_ctx->tok11_idx, comp_ctx->tok21_idx);\n\tduk_copy(thr, comp_ctx->tok12_idx, comp_ctx->tok22_idx);\n\n\t/* parse new token */\n\tduk_lexer_parse_js_input_element(&comp_ctx->lex,\n\t                                 &comp_ctx->curr_token,\n\t                                 comp_ctx->curr_func.is_strict,\n\t                                 regexp);\n\n\tDUK_DDD(DUK_DDDPRINT(\"advance: curr: tok=%ld/%ld,%ld,term=%ld,%!T,%!T \"\n\t                     \"prev: tok=%ld/%ld,%ld,term=%ld,%!T,%!T\",\n\t                     (long) comp_ctx->curr_token.t,\n\t                     (long) comp_ctx->curr_token.t_nores,\n\t                     (long) comp_ctx->curr_token.start_line,\n\t                     (long) comp_ctx->curr_token.lineterm,\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok11_idx),\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok12_idx),\n\t                     (long) comp_ctx->prev_token.t,\n\t                     (long) comp_ctx->prev_token.t_nores,\n\t                     (long) comp_ctx->prev_token.start_line,\n\t                     (long) comp_ctx->prev_token.lineterm,\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok21_idx),\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok22_idx)));\n}\n\n/* advance, expecting current token to be a specific token; parse next token in regexp context */\nDUK_LOCAL void duk__advance_expect(duk_compiler_ctx *comp_ctx, duk_small_int_t expect) {\n\tduk__advance_helper(comp_ctx, expect);\n}\n\n/* advance, whatever the current token is; parse next token in regexp context */\nDUK_LOCAL void duk__advance(duk_compiler_ctx *comp_ctx) {\n\tduk__advance_helper(comp_ctx, -1);\n}\n\n/*\n *  Helpers for duk_compiler_func.\n */\n\n/* init function state: inits valstack allocations */\nDUK_LOCAL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func = &comp_ctx->curr_func;\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_idx_t entry_top;\n\n\tentry_top = duk_get_top(thr);\n\n\tduk_memzero(func, sizeof(*func));  /* intentional overlap with earlier memzero */\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tfunc->h_name = NULL;\n\tfunc->h_consts = NULL;\n\tfunc->h_funcs = NULL;\n\tfunc->h_decls = NULL;\n\tfunc->h_labelnames = NULL;\n\tfunc->h_labelinfos = NULL;\n\tfunc->h_argnames = NULL;\n\tfunc->h_varmap = NULL;\n#endif\n\n\tduk_require_stack(thr, DUK__FUNCTION_INIT_REQUIRE_SLOTS);\n\n\tDUK_BW_INIT_PUSHBUF(thr, &func->bw_code, DUK__BC_INITIAL_INSTS * sizeof(duk_compiler_instr));\n\t/* code_idx = entry_top + 0 */\n\n\tduk_push_bare_array(thr);\n\tfunc->consts_idx = entry_top + 1;\n\tfunc->h_consts = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 1);\n\tDUK_ASSERT(func->h_consts != NULL);\n\n\tduk_push_bare_array(thr);\n\tfunc->funcs_idx = entry_top + 2;\n\tfunc->h_funcs = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 2);\n\tDUK_ASSERT(func->h_funcs != NULL);\n\tDUK_ASSERT(func->fnum_next == 0);\n\n\tduk_push_bare_array(thr);\n\tfunc->decls_idx = entry_top + 3;\n\tfunc->h_decls = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 3);\n\tDUK_ASSERT(func->h_decls != NULL);\n\n\tduk_push_bare_array(thr);\n\tfunc->labelnames_idx = entry_top + 4;\n\tfunc->h_labelnames = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 4);\n\tDUK_ASSERT(func->h_labelnames != NULL);\n\n\tduk_push_dynamic_buffer(thr, 0);\n\tfunc->labelinfos_idx = entry_top + 5;\n\tfunc->h_labelinfos = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, entry_top + 5);\n\tDUK_ASSERT(func->h_labelinfos != NULL);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(func->h_labelinfos) && !DUK_HBUFFER_HAS_EXTERNAL(func->h_labelinfos));\n\n\tduk_push_bare_array(thr);\n\tfunc->argnames_idx = entry_top + 6;\n\tfunc->h_argnames = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 6);\n\tDUK_ASSERT(func->h_argnames != NULL);\n\n\tduk_push_bare_object(thr);\n\tfunc->varmap_idx = entry_top + 7;\n\tfunc->h_varmap = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 7);\n\tDUK_ASSERT(func->h_varmap != NULL);\n}\n\n/* reset function state (prepare for pass 2) */\nDUK_LOCAL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func = &comp_ctx->curr_func;\n\tduk_hthread *thr = comp_ctx->thr;\n\n\t/* reset bytecode buffer but keep current size; pass 2 will\n\t * require same amount or more.\n\t */\n\tDUK_BW_RESET_SIZE(thr, &func->bw_code);\n\n\tduk_set_length(thr, func->consts_idx, 0);\n\t/* keep func->h_funcs; inner functions are not reparsed to avoid O(depth^2) parsing */\n\tfunc->fnum_next = 0;\n\t/* duk_set_length(thr, func->funcs_idx, 0); */\n\tduk_set_length(thr, func->labelnames_idx, 0);\n\tduk_hbuffer_reset(thr, func->h_labelinfos);\n\t/* keep func->h_argnames; it is fixed for all passes */\n\n\t/* truncated in case pass 3 needed */\n\tduk_push_bare_object(thr);\n\tduk_replace(thr, func->varmap_idx);\n\tfunc->h_varmap = DUK_GET_HOBJECT_POSIDX(thr, func->varmap_idx);\n\tDUK_ASSERT(func->h_varmap != NULL);\n}\n\n/* cleanup varmap from any null entries, compact it, etc; returns number\n * of final entries after cleanup.\n */\nDUK_LOCAL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hobject *h_varmap;\n\tduk_hstring *h_key;\n\tduk_tval *tv;\n\tduk_uint32_t i, e_next;\n\tduk_int_t ret;\n\n\t/* [ ... varmap ] */\n\n\th_varmap = DUK_GET_HOBJECT_NEGIDX(thr, -1);\n\tDUK_ASSERT(h_varmap != NULL);\n\n\tret = 0;\n\te_next = DUK_HOBJECT_GET_ENEXT(h_varmap);\n\tfor (i = 0; i < e_next; i++) {\n\t\th_key = DUK_HOBJECT_E_GET_KEY(thr->heap, h_varmap, i);\n\t\tif (!h_key) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, h_varmap, i));\n\n\t\t/* The entries can either be register numbers or 'null' values.\n\t\t * Thus, no need to DECREF them and get side effects.  DECREF'ing\n\t\t * the keys (strings) can cause memory to be freed but no side\n\t\t * effects as strings don't have finalizers.  This is why we can\n\t\t * rely on the object properties not changing from underneath us.\n\t\t */\n\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, h_varmap, i);\n\t\tif (!DUK_TVAL_IS_NUMBER(tv)) {\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv));\n\t\t\tDUK_HOBJECT_E_SET_KEY(thr->heap, h_varmap, i, NULL);\n\t\t\tDUK_HSTRING_DECREF(thr, h_key);\n\t\t\t/* when key is NULL, value is garbage so no need to set */\n\t\t} else {\n\t\t\tret++;\n\t\t}\n\t}\n\n\tduk_compact_m1(thr);\n\n\treturn ret;\n}\n\n/* Convert duk_compiler_func into a function template, leaving the result\n * on top of stack.\n */\n/* XXX: awkward and bloated asm -- use faster internal accesses */\nDUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func = &comp_ctx->curr_func;\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hcompfunc *h_res;\n\tduk_hbuffer_fixed *h_data;\n\tduk_size_t consts_count;\n\tduk_size_t funcs_count;\n\tduk_size_t code_count;\n\tduk_size_t code_size;\n\tduk_size_t data_size;\n\tduk_size_t i;\n\tduk_tval *p_const;\n\tduk_hobject **p_func;\n\tduk_instr_t *p_instr;\n\tduk_compiler_instr *q_instr;\n\tduk_tval *tv;\n\tduk_bool_t keep_varmap;\n\tduk_bool_t keep_formals;\n#if !defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_size_t formals_length;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"converting duk_compiler_func to function/template\"));\n\n\t/*\n\t *  Push result object and init its flags\n\t */\n\n\t/* Valstack should suffice here, required on function valstack init */\n\n\th_res = duk_push_hcompfunc(thr);\n\tDUK_ASSERT(h_res != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_res) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, (duk_hobject *) h_res, NULL);  /* Function templates are \"bare objects\". */\n\n\tif (func->is_function) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function -> set NEWENV\"));\n\t\tDUK_HOBJECT_SET_NEWENV((duk_hobject *) h_res);\n\n\t\tif (!func->is_arguments_shadowed) {\n\t\t\t/* arguments object would be accessible; note that shadowing\n\t\t\t * bindings are arguments or function declarations, neither\n\t\t\t * of which are deletable, so this is safe.\n\t\t\t */\n\n\t\t\tif (func->id_access_arguments || func->may_direct_eval) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"function may access 'arguments' object directly or \"\n\t\t\t\t                     \"indirectly -> set CREATEARGS\"));\n\t\t\t\tDUK_HOBJECT_SET_CREATEARGS((duk_hobject *) h_res);\n\t\t\t}\n\t\t}\n\t} else if (func->is_eval && func->is_strict) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"strict eval code -> set NEWENV\"));\n\t\tDUK_HOBJECT_SET_NEWENV((duk_hobject *) h_res);\n\t} else {\n\t\t/* non-strict eval: env is caller's env or global env (direct vs. indirect call)\n\t\t * global code: env is is global env\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-strict eval code or global code -> no NEWENV\"));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV((duk_hobject *) h_res));\n\t}\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tif (func->is_function && func->is_namebinding && func->h_name != NULL) {\n\t\t/* Object literal set/get functions have a name (property\n\t\t * name) but must not have a lexical name binding, see\n\t\t * test-bug-getset-func-name.js.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"function expression with a name -> set NAMEBINDING\"));\n\t\tDUK_HOBJECT_SET_NAMEBINDING((duk_hobject *) h_res);\n\t}\n#endif\n\n\tif (func->is_strict) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is strict -> set STRICT\"));\n\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_res);\n\t}\n\n\tif (func->is_notail) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is notail -> set NOTAIL\"));\n\t\tDUK_HOBJECT_SET_NOTAIL((duk_hobject *) h_res);\n\t}\n\n\tif (func->is_constructable) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is constructable -> set CONSTRUCTABLE\"));\n\t\tDUK_HOBJECT_SET_CONSTRUCTABLE((duk_hobject *) h_res);\n\t}\n\n\t/*\n\t *  Build function fixed size 'data' buffer, which contains bytecode,\n\t *  constants, and inner function references.\n\t *\n\t *  During the building phase 'data' is reachable but incomplete.\n\t *  Only incref's occur during building (no refzero or GC happens),\n\t *  so the building process is atomic.\n\t */\n\n\tconsts_count = duk_hobject_get_length(thr, func->h_consts);\n\tfuncs_count = duk_hobject_get_length(thr, func->h_funcs) / 3;\n\tcode_count = DUK_BW_GET_SIZE(thr, &func->bw_code) / sizeof(duk_compiler_instr);\n\tcode_size = code_count * sizeof(duk_instr_t);\n\n\tdata_size = consts_count * sizeof(duk_tval) +\n\t            funcs_count * sizeof(duk_hobject *) +\n\t            code_size;\n\n\tDUK_DDD(DUK_DDDPRINT(\"consts_count=%ld, funcs_count=%ld, code_size=%ld -> \"\n\t                     \"data_size=%ld*%ld + %ld*%ld + %ld = %ld\",\n\t                     (long) consts_count, (long) funcs_count, (long) code_size,\n\t                     (long) consts_count, (long) sizeof(duk_tval),\n\t                     (long) funcs_count, (long) sizeof(duk_hobject *),\n\t                     (long) code_size, (long) data_size));\n\n\tduk_push_fixed_buffer_nozero(thr, data_size);\n\th_data = (duk_hbuffer_fixed *) (void *) duk_known_hbuffer(thr, -1);\n\n\tDUK_HCOMPFUNC_SET_DATA(thr->heap, h_res, (duk_hbuffer *) h_data);\n\tDUK_HEAPHDR_INCREF(thr, h_data);\n\n\tp_const = (duk_tval *) (void *) DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, h_data);\n\tfor (i = 0; i < consts_count; i++) {\n\t\tDUK_ASSERT(i <= DUK_UARRIDX_MAX);  /* const limits */\n\t\ttv = duk_hobject_find_array_entry_tval_ptr(thr->heap, func->h_consts, (duk_uarridx_t) i);\n\t\tDUK_ASSERT(tv != NULL);\n\t\tDUK_TVAL_SET_TVAL(p_const, tv);\n\t\tp_const++;\n\t\tDUK_TVAL_INCREF(thr, tv);  /* may be a string constant */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"constant: %!T\", (duk_tval *) tv));\n\t}\n\n\tp_func = (duk_hobject **) p_const;\n\tDUK_HCOMPFUNC_SET_FUNCS(thr->heap, h_res, p_func);\n\tfor (i = 0; i < funcs_count; i++) {\n\t\tduk_hobject *h;\n\t\tDUK_ASSERT(i * 3 <= DUK_UARRIDX_MAX);  /* func limits */\n\t\ttv = duk_hobject_find_array_entry_tval_ptr(thr->heap, func->h_funcs, (duk_uarridx_t) (i * 3));\n\t\tDUK_ASSERT(tv != NULL);\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(h));\n\t\t*p_func++ = h;\n\t\tDUK_HOBJECT_INCREF(thr, h);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"inner function: %p -> %!iO\",\n\t\t                     (void *) h, (duk_heaphdr *) h));\n\t}\n\n\tp_instr = (duk_instr_t *) p_func;\n\tDUK_HCOMPFUNC_SET_BYTECODE(thr->heap, h_res, p_instr);\n\n\t/* copy bytecode instructions one at a time */\n\tq_instr = (duk_compiler_instr *) (void *) DUK_BW_GET_BASEPTR(thr, &func->bw_code);\n\tfor (i = 0; i < code_count; i++) {\n\t\tp_instr[i] = q_instr[i].ins;\n\t}\n\t/* Note: 'q_instr' is still used below */\n\n\tDUK_ASSERT((duk_uint8_t *) (p_instr + code_count) == DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, h_data) + data_size);\n\n\tduk_pop(thr);  /* 'data' (and everything in it) is reachable through h_res now */\n\n\t/*\n\t *  Init non-property result fields\n\t *\n\t *  'nregs' controls how large a register frame is allocated.\n\t *\n\t *  'nargs' controls how many formal arguments are written to registers:\n\t *  r0, ... r(nargs-1).  The remaining registers are initialized to\n\t *  undefined.\n\t */\n\n\tDUK_ASSERT(func->temp_max >= 0);\n\th_res->nregs = (duk_uint16_t) func->temp_max;\n\th_res->nargs = (duk_uint16_t) duk_hobject_get_length(thr, func->h_argnames);\n\tDUK_ASSERT(h_res->nregs >= h_res->nargs);  /* pass2 allocation handles this */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\th_res->start_line = (duk_uint32_t) func->min_line;\n\th_res->end_line = (duk_uint32_t) func->max_line;\n#endif\n\n\t/*\n\t *  Init object properties\n\t *\n\t *  Properties should be added in decreasing order of access frequency.\n\t *  (Not very critical for function templates.)\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"init function properties\"));\n\n\t/* [ ... res ] */\n\n\t/* _Varmap: omitted if function is guaranteed not to do a slow path\n\t * identifier access that might be caught by locally declared variables.\n\t * The varmap can also be omitted if it turns out empty of actual\n\t * register mappings after a cleanup.  When debugging is enabled, we\n\t * always need the varmap to be able to lookup variables at any point.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tDUK_DD(DUK_DDPRINT(\"keeping _Varmap because debugger support is enabled\"));\n\tkeep_varmap = 1;\n#else\n\tif (func->id_access_slow_own ||   /* directly uses slow accesses that may match own variables */\n\t    func->id_access_arguments ||  /* accesses 'arguments' directly */\n\t    func->may_direct_eval ||      /* may indirectly slow access through a direct eval */\n\t    funcs_count > 0) {            /* has inner functions which may slow access (XXX: this can be optimized by looking at the inner functions) */\n\t\tDUK_DD(DUK_DDPRINT(\"keeping _Varmap because of direct eval, slow path access that may match local variables, or presence of inner functions\"));\n\t\tkeep_varmap = 1;\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"dropping _Varmap\"));\n\t\tkeep_varmap = 0;\n\t}\n#endif\n\n\tif (keep_varmap) {\n\t\tduk_int_t num_used;\n\t\tduk_dup(thr, func->varmap_idx);\n\t\tnum_used = duk__cleanup_varmap(comp_ctx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"cleaned up varmap: %!T (num_used=%ld)\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) num_used));\n\n\t\tif (num_used > 0) {\n\t\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VARMAP, DUK_PROPDESC_FLAGS_NONE);\n\t\t} else {\n\t\t\tDUK_DD(DUK_DDPRINT(\"varmap is empty after cleanup -> no need to add\"));\n\t\t\tduk_pop(thr);\n\t\t}\n\t}\n\n\t/* _Formals: omitted if function is guaranteed not to need a (non-strict)\n\t * arguments object, and _Formals.length matches nargs exactly.\n\t *\n\t * Non-arrow functions can't see an outer function's 'argument' binding\n\t * (because they have their own), but arrow functions can.  When arrow\n\t * functions are added, this condition would need to be added:\n\t *     inner_arrow_funcs_count > 0   inner arrow functions may access 'arguments'\n\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tDUK_DD(DUK_DDPRINT(\"keeping _Formals because debugger support is enabled\"));\n\tkeep_formals = 1;\n#else\n\tformals_length = duk_get_length(thr, func->argnames_idx);\n\tif (formals_length != (duk_size_t) h_res->nargs) {\n\t\t/* Nargs not enough for closure .length: keep _Formals regardless\n\t\t * of its length.  Shouldn't happen in practice at the moment.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"keeping _Formals because _Formals.length != nargs\"));\n\t\tkeep_formals = 1;\n\t} else if ((func->id_access_arguments || func->may_direct_eval) &&\n\t           (formals_length > 0)) {\n\t\t/* Direct eval (may access 'arguments') or accesses 'arguments'\n\t\t * explicitly: keep _Formals unless it is zero length.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"keeping _Formals because of direct eval or explicit access to 'arguments', and _Formals.length != 0\"));\n\t\tkeep_formals = 1;\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"omitting _Formals, nargs matches _Formals.length, so no properties added\"));\n\t\tkeep_formals = 0;\n\t}\n#endif\n\n\tif (keep_formals) {\n\t\tduk_dup(thr, func->argnames_idx);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_FORMALS, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\n\t/* name */\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tif (func->h_name) {\n\t\tduk_push_hstring(thr, func->h_name);\n\t\tDUK_DD(DUK_DDPRINT(\"setting function template .name to %!T\", duk_get_tval(thr, -1)));\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_NONE);\n\t}\n#endif  /* DUK_USE_FUNC_NAME_PROPERTY */\n\n\t/* _Source */\n#if defined(DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY)\n\tif (0) {\n\t\t/* XXX: Currently function source code is not stored, as it is not\n\t\t * required by the standard.  Source code should not be stored by\n\t\t * default (user should enable it explicitly), and the source should\n\t\t * probably be compressed with a trivial text compressor; average\n\t\t * compression of 20-30% is quite easy to achieve even with a trivial\n\t\t * compressor (RLE + backwards lookup).\n\t\t *\n\t\t * Debugging needs source code to be useful: sometimes input code is\n\t\t * not found in files as it may be generated and then eval()'d, given\n\t\t * by dynamic C code, etc.\n\t\t *\n\t\t * Other issues:\n\t\t *\n\t\t *   - Need tokenizer indices for start and end to substring\n\t\t *   - Always normalize function declaration part?\n\t\t *   - If we keep _Formals, only need to store body\n\t\t */\n\n\t\t/*\n\t\t *  For global or eval code this is straightforward.  For functions\n\t\t *  created with the Function constructor we only get the source for\n\t\t *  the body and must manufacture the \"function ...\" part.\n\t\t *\n\t\t *  For instance, for constructed functions (v8):\n\t\t *\n\t\t *    > a = new Function(\"foo\", \"bar\", \"print(foo)\");\n\t\t *    [Function]\n\t\t *    > a.toString()\n\t\t *    'function anonymous(foo,bar) {\\nprint(foo)\\n}'\n\t\t *\n\t\t *  Similarly for e.g. getters (v8):\n\t\t *\n\t\t *    > x = { get a(foo,bar) { print(foo); } }\n\t\t *    { a: [Getter] }\n\t\t *    > Object.getOwnPropertyDescriptor(x, 'a').get.toString()\n\t\t *    'function a(foo,bar) { print(foo); }'\n\t\t */\n\n#if 0\n\t\tduk_push_literal(thr, \"XXX\");\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_SOURCE, DUK_PROPDESC_FLAGS_NONE);\n#endif\n\t}\n#endif  /* DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY */\n\n\t/* _Pc2line */\n#if defined(DUK_USE_PC2LINE)\n\tif (1) {\n\t\t/*\n\t\t *  Size-optimized pc->line mapping.\n\t\t */\n\n\t\tDUK_ASSERT(code_count <= DUK_COMPILER_MAX_BYTECODE_LENGTH);\n\t\tduk_hobject_pc2line_pack(thr, q_instr, (duk_uint_fast32_t) code_count);  /* -> pushes fixed buffer */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_NONE);\n\n\t\t/* XXX: if assertions enabled, walk through all valid PCs\n\t\t * and check line mapping.\n\t\t */\n\t}\n#endif  /* DUK_USE_PC2LINE */\n\n\t/* fileName */\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tif (comp_ctx->h_filename) {\n\t\t/*\n\t\t *  Source filename (or equivalent), for identifying thrown errors.\n\t\t */\n\n\t\tduk_push_hstring(thr, comp_ctx->h_filename);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_NONE);\n\t}\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"converted function: %!ixT\",\n\t                   (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/*\n\t *  Compact the function template.\n\t */\n\n\tduk_compact_m1(thr);\n\n\t/*\n\t *  Debug dumping\n\t */\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t{\n\t\tduk_hcompfunc *h;\n\t\tduk_instr_t *p, *p_start, *p_end;\n\n\t\th = (duk_hcompfunc *) duk_get_hobject(thr, -1);\n\t\tp_start = (duk_instr_t *) DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, h);\n\t\tp_end = (duk_instr_t *) DUK_HCOMPFUNC_GET_CODE_END(thr->heap, h);\n\n\t\tp = p_start;\n\t\twhile (p < p_end) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"BC %04ld: %!I        ; 0x%08lx op=%ld (%!X) a=%ld b=%ld c=%ld\",\n\t\t\t                     (long) (p - p_start),\n\t\t\t                     (duk_instr_t) (*p),\n\t\t\t                     (unsigned long) (*p),\n\t\t\t                     (long) DUK_DEC_OP(*p),\n\t\t\t                     (long) DUK_DEC_OP(*p),\n\t\t\t                     (long) DUK_DEC_A(*p),\n\t\t\t                     (long) DUK_DEC_B(*p),\n\t\t\t                     (long) DUK_DEC_C(*p)));\n\t\t\tp++;\n\t\t}\n\t}\n#endif\n}\n\n/*\n *  Code emission helpers\n *\n *  Some emission helpers understand the range of target and source reg/const\n *  values and automatically emit shuffling code if necessary.  This is the\n *  case when the slot in question (A, B, C) is used in the standard way and\n *  for opcodes the emission helpers explicitly understand (like DUK_OP_MPUTOBJ).\n *\n *  The standard way is that:\n *    - slot A is a target register\n *    - slot B is a source register/constant\n *    - slot C is a source register/constant\n *\n *  If a slot is used in a non-standard way the caller must indicate this\n *  somehow.  If a slot is used as a target instead of a source (or vice\n *  versa), this can be indicated with a flag to trigger proper shuffling\n *  (e.g. DUK__EMIT_FLAG_B_IS_TARGET).  If the value in the slot is not\n *  register/const related at all, the caller must ensure that the raw value\n *  fits into the corresponding slot so as to not trigger shuffling.  The\n *  caller must set a \"no shuffle\" flag to ensure compilation fails if\n *  shuffling were to be triggered because of an internal error.\n *\n *  For slots B and C the raw slot size is 9 bits but one bit is reserved for\n *  the reg/const indicator.  To use the full 9-bit range for a raw value,\n *  shuffling must be disabled with the DUK__EMIT_FLAG_NO_SHUFFLE_{B,C} flag.\n *  Shuffling is only done for A, B, and C slots, not the larger BC or ABC slots.\n *\n *  There is call handling specific understanding in the A-B-C emitter to\n *  convert call setup and call instructions into indirect ones if necessary.\n */\n\n/* Code emission flags, passed in the 'opcode' field.  Opcode + flags\n * fit into 16 bits for now, so use duk_small_uint_t.\n */\n#define DUK__EMIT_FLAG_NO_SHUFFLE_A      (1 << 8)\n#define DUK__EMIT_FLAG_NO_SHUFFLE_B      (1 << 9)\n#define DUK__EMIT_FLAG_NO_SHUFFLE_C      (1 << 10)\n#define DUK__EMIT_FLAG_A_IS_SOURCE       (1 << 11)  /* slot A is a source (default: target) */\n#define DUK__EMIT_FLAG_B_IS_TARGET       (1 << 12)  /* slot B is a target (default: source) */\n#define DUK__EMIT_FLAG_C_IS_TARGET       (1 << 13)  /* slot C is a target (default: source) */\n#define DUK__EMIT_FLAG_BC_REGCONST       (1 << 14)  /* slots B and C are reg/const */\n#define DUK__EMIT_FLAG_RESERVE_JUMPSLOT  (1 << 15)  /* reserve a jumpslot after instr before target spilling, used for NEXTENUM */\n\n/* XXX: macro smaller than call? */\nDUK_LOCAL duk_int_t duk__get_current_pc(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func;\n\tfunc = &comp_ctx->curr_func;\n\treturn (duk_int_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &func->bw_code) / sizeof(duk_compiler_instr));\n}\n\nDUK_LOCAL duk_compiler_instr *duk__get_instr_ptr(duk_compiler_ctx *comp_ctx, duk_int_t pc) {\n\tDUK_ASSERT(pc >= 0);\n\tDUK_ASSERT((duk_size_t) pc < (duk_size_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr)));\n\treturn ((duk_compiler_instr *) (void *) DUK_BW_GET_BASEPTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code)) + pc;\n}\n\n/* emit instruction; could return PC but that's not needed in the majority\n * of cases.\n */\nDUK_LOCAL void duk__emit(duk_compiler_ctx *comp_ctx, duk_instr_t ins) {\n#if defined(DUK_USE_PC2LINE)\n\tduk_int_t line;\n#endif\n\tduk_compiler_instr *instr;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__emit: 0x%08lx curr_token.start_line=%ld prev_token.start_line=%ld pc=%ld --> %!I\",\n\t                     (unsigned long) ins,\n\t                     (long) comp_ctx->curr_token.start_line,\n\t                     (long) comp_ctx->prev_token.start_line,\n\t                     (long) duk__get_current_pc(comp_ctx),\n\t                     (duk_instr_t) ins));\n\n\tinstr = (duk_compiler_instr *) (void *) DUK_BW_ENSURE_GETPTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, sizeof(duk_compiler_instr));\n\tDUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, sizeof(duk_compiler_instr));\n\n#if defined(DUK_USE_PC2LINE)\n\t/* The line number tracking is a bit inconsistent right now, which\n\t * affects debugger accuracy.  Mostly call sites emit opcodes when\n\t * they have parsed a token (say a terminating semicolon) and called\n\t * duk__advance().  In this case the line number of the previous\n\t * token is the most accurate one (except in prologue where\n\t * prev_token.start_line is 0).  This is probably not 100% correct\n\t * right now.\n\t */\n\t/* approximation, close enough */\n\tline = comp_ctx->prev_token.start_line;\n\tif (line == 0) {\n\t\tline = comp_ctx->curr_token.start_line;\n\t}\n#endif\n\n\tinstr->ins = ins;\n#if defined(DUK_USE_PC2LINE)\n\tinstr->line = (duk_uint32_t) line;\n#endif\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (line < comp_ctx->curr_func.min_line) {\n\t\tcomp_ctx->curr_func.min_line = line;\n\t}\n\tif (line > comp_ctx->curr_func.max_line) {\n\t\tcomp_ctx->curr_func.max_line = line;\n\t}\n#endif\n\n\t/* Limit checks for bytecode byte size and line number. */\n\tif (DUK_UNLIKELY(DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) > DUK_USE_ESBC_MAX_BYTES)) {\n\t\tgoto fail_bc_limit;\n\t}\n#if defined(DUK_USE_PC2LINE) && defined(DUK_USE_ESBC_LIMITS)\n#if defined(DUK_USE_BUFLEN16)\n\t/* Buffer length is bounded to 0xffff automatically, avoid compile warning. */\n\tif (DUK_UNLIKELY(line > DUK_USE_ESBC_MAX_LINENUMBER)) {\n\t\tgoto fail_bc_limit;\n\t}\n#else\n\tif (DUK_UNLIKELY(line > DUK_USE_ESBC_MAX_LINENUMBER)) {\n\t\tgoto fail_bc_limit;\n\t}\n#endif\n#endif\n\n\treturn;\n\n  fail_bc_limit:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_BYTECODE_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Update function min/max line from current token.  Needed to improve\n * function line range information for debugging, so that e.g. opening\n * curly brace is covered by line range even when no opcodes are emitted\n * for the line containing the brace.\n */\nDUK_LOCAL void duk__update_lineinfo_currtoken(duk_compiler_ctx *comp_ctx) {\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_int_t line;\n\n\tline = comp_ctx->curr_token.start_line;\n\tif (line == 0) {\n\t\treturn;\n\t}\n\tif (line < comp_ctx->curr_func.min_line) {\n\t\tcomp_ctx->curr_func.min_line = line;\n\t}\n\tif (line > comp_ctx->curr_func.max_line) {\n\t\tcomp_ctx->curr_func.max_line = line;\n\t}\n#else\n\tDUK_UNREF(comp_ctx);\n#endif\n}\n\nDUK_LOCAL void duk__emit_op_only(duk_compiler_ctx *comp_ctx, duk_small_uint_t op) {\n\tduk__emit(comp_ctx, DUK_ENC_OP_ABC(op, 0));\n}\n\n/* Important main primitive. */\nDUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b, duk_regconst_t c) {\n\tduk_instr_t ins = 0;\n\tduk_int_t a_out = -1;\n\tduk_int_t b_out = -1;\n\tduk_int_t c_out = -1;\n\tduk_int_t tmp;\n\tduk_small_uint_t op = op_flags & 0xffU;\n\n\tDUK_DDD(DUK_DDDPRINT(\"emit: op_flags=%04lx, a=%ld, b=%ld, c=%ld\",\n\t                     (unsigned long) op_flags, (long) a, (long) b, (long) c));\n\n\t/* We could rely on max temp/const checks: if they don't exceed BC\n\t * limit, nothing here can either (just asserts would be enough).\n\t * Currently we check for the limits, which provides additional\n\t * protection against creating invalid bytecode due to compiler\n\t * bugs.\n\t */\n\n\tDUK_ASSERT_DISABLE((op_flags & 0xff) >= DUK_BC_OP_MIN);  /* unsigned */\n\tDUK_ASSERT((op_flags & 0xff) <= DUK_BC_OP_MAX);\n\tDUK_ASSERT(DUK__ISREG(a));\n\tDUK_ASSERT(b != -1);  /* Not 'none'. */\n\tDUK_ASSERT(c != -1);  /* Not 'none'. */\n\n\t/* Input shuffling happens before the actual operation, while output\n\t * shuffling happens afterwards.  Output shuffling decisions are still\n\t * made at the same time to reduce branch clutter; output shuffle decisions\n\t * are recorded into X_out variables.\n\t */\n\n\t/* Slot A: currently no support for reg/const. */\n\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\tif (a <= DUK_BC_A_MAX && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A)) {\n#else\n\tif (a <= DUK_BC_A_MAX) {\n#endif\n\t\t;\n\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A) {\n\t\tDUK_D(DUK_DPRINT(\"out of regs: 'a' (reg) needs shuffling but shuffle prohibited, a: %ld\", (long) a));\n\t\tgoto error_outofregs;\n\t} else if (a <= DUK_BC_BC_MAX) {\n\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\ttmp = comp_ctx->curr_func.shuffle1;\n\t\tif (op_flags & DUK__EMIT_FLAG_A_IS_SOURCE) {\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, a));\n\t\t} else {\n\t\t\t/* Output shuffle needed after main operation */\n\t\t\ta_out = a;\n\n\t\t\t/* The DUK_OP_CSVAR output shuffle assumes shuffle registers are\n\t\t\t * consecutive.\n\t\t\t */\n\t\t\tDUK_ASSERT((comp_ctx->curr_func.shuffle1 == 0 && comp_ctx->curr_func.shuffle2 == 0) ||\n\t\t\t           (comp_ctx->curr_func.shuffle2 == comp_ctx->curr_func.shuffle1 + 1));\n\t\t\tif (op == DUK_OP_CSVAR) {\n\t\t\t\t/* For CSVAR the limit is one smaller because output shuffle\n\t\t\t\t * must be able to express 'a + 1' in BC.\n\t\t\t\t */\n\t\t\t\tif (a + 1 > DUK_BC_BC_MAX) {\n\t\t\t\t\tgoto error_outofregs;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ta = tmp;\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"out of regs: 'a' (reg) needs shuffling but does not fit into BC, a: %ld\", (long) a));\n\t\tgoto error_outofregs;\n\t}\n\n\t/* Slot B: reg/const support, mapped to bit 0 of opcode. */\n\n\tif ((b & DUK__CONST_MARKER) != 0) {\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B) == 0);\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_B_IS_TARGET) == 0);\n\t\tb = b & ~DUK__CONST_MARKER;\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (0) {\n#else\n\t\tif (b <= 0xff) {\n#endif\n\t\t\tif (op_flags & DUK__EMIT_FLAG_BC_REGCONST) {\n\t\t\t\t/* Opcode follows B/C reg/const convention. */\n\t\t\t\tDUK_ASSERT((op & 0x01) == 0);\n\t\t\t\tins |= DUK_ENC_OP_A_B_C(0x01, 0, 0, 0);  /* const flag for B */\n\t\t\t} else {\n\t\t\t\tDUK_D(DUK_DPRINT(\"B is const, opcode is not B/C reg/const: %x\", op_flags));\n\t\t\t}\n\t\t} else if (b <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle2;\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDCONST, tmp, b));\n\t\t\tb = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'b' (const) needs shuffling but does not fit into BC, b: %ld\", (long) b));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t} else {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (b <= 0xff && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B)) {\n#else\n\t\tif (b <= 0xff) {\n#endif\n\t\t\t;\n\t\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B) {\n\t\t\tif (b > DUK_BC_B_MAX) {\n\t\t\t\t/* Note: 0xff != DUK_BC_B_MAX */\n\t\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'b' (reg) needs shuffling but shuffle prohibited, b: %ld\", (long) b));\n\t\t\t\tgoto error_outofregs;\n\t\t\t}\n\t\t} else if (b <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle2;\n\t\t\tif (op_flags & DUK__EMIT_FLAG_B_IS_TARGET) {\n\t\t\t\t/* Output shuffle needed after main operation */\n\t\t\t\tb_out = b;\n\t\t\t}\n\t\t\tif (!(op_flags & DUK__EMIT_FLAG_B_IS_TARGET)) {\n\t\t\t\tif (op == DUK_OP_MPUTOBJ || op == DUK_OP_MPUTARR) {\n\t\t\t\t\t/* Special handling for MPUTOBJ/MPUTARR shuffling.\n\t\t\t\t\t * For each, slot B identifies the first register of a range\n\t\t\t\t\t * of registers, so normal shuffling won't work.  Instead,\n\t\t\t\t\t * an indirect version of the opcode is used.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_B_IS_TARGET) == 0);\n\t\t\t\t\tduk__emit_load_int32_noshuffle(comp_ctx, tmp, b);\n\t\t\t\t\tDUK_ASSERT(DUK_OP_MPUTOBJI == DUK_OP_MPUTOBJ + 1);\n\t\t\t\t\tDUK_ASSERT(DUK_OP_MPUTARRI == DUK_OP_MPUTARR + 1);\n\t\t\t\t\top_flags++;  /* indirect opcode follows direct */\n\t\t\t\t} else {\n\t\t\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, b));\n\t\t\t\t}\n\t\t\t}\n\t\t\tb = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'b' (reg) needs shuffling but does not fit into BC, b: %ld\", (long) b));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t}\n\n\t/* Slot C: reg/const support, mapped to bit 1 of opcode. */\n\n\tif ((c & DUK__CONST_MARKER) != 0) {\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C) == 0);\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_C_IS_TARGET) == 0);\n\t\tc = c & ~DUK__CONST_MARKER;\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (0) {\n#else\n\t\tif (c <= 0xff) {\n#endif\n\t\t\tif (op_flags & DUK__EMIT_FLAG_BC_REGCONST) {\n\t\t\t\t/* Opcode follows B/C reg/const convention. */\n\t\t\t\tDUK_ASSERT((op & 0x02) == 0);\n\t\t\t\tins |= DUK_ENC_OP_A_B_C(0x02, 0, 0, 0);  /* const flag for C */\n\t\t\t} else {\n\t\t\t\tDUK_D(DUK_DPRINT(\"C is const, opcode is not B/C reg/const: %x\", op_flags));\n\t\t\t}\n\t\t} else if (c <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle3;\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDCONST, tmp, c));\n\t\t\tc = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'c' (const) needs shuffling but does not fit into BC, c: %ld\", (long) c));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t} else {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (c <= 0xff && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C)) {\n#else\n\t\tif (c <= 0xff) {\n#endif\n\t\t\t;\n\t\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C) {\n\t\t\tif (c > DUK_BC_C_MAX) {\n\t\t\t\t/* Note: 0xff != DUK_BC_C_MAX */\n\t\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'c' (reg) needs shuffling but shuffle prohibited, c: %ld\", (long) c));\n\t\t\t\tgoto error_outofregs;\n\t\t\t}\n\t\t} else if (c <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle3;\n\t\t\tif (op_flags & DUK__EMIT_FLAG_C_IS_TARGET) {\n\t\t\t\t/* Output shuffle needed after main operation */\n\t\t\t\tc_out = c;\n\t\t\t} else {\n\t\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, c));\n\t\t\t}\n\t\t\tc = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'c' (reg) needs shuffling but does not fit into BC, c: %ld\", (long) c));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t}\n\n\t/* Main operation */\n\n\tDUK_ASSERT(a >= DUK_BC_A_MIN);\n\tDUK_ASSERT(a <= DUK_BC_A_MAX);\n\tDUK_ASSERT(b >= DUK_BC_B_MIN);\n\tDUK_ASSERT(b <= DUK_BC_B_MAX);\n\tDUK_ASSERT(c >= DUK_BC_C_MIN);\n\tDUK_ASSERT(c <= DUK_BC_C_MAX);\n\n\tins |= DUK_ENC_OP_A_B_C(op_flags & 0xff, a, b, c);\n\tduk__emit(comp_ctx, ins);\n\n\t/* NEXTENUM needs a jump slot right after the main instruction.\n\t * When the JUMP is taken, output spilling is not needed so this\n\t * workaround is possible.  The jump slot PC is exceptionally\n\t * plumbed through comp_ctx to minimize call sites.\n\t */\n\tif (op_flags & DUK__EMIT_FLAG_RESERVE_JUMPSLOT) {\n\t\tcomp_ctx->emit_jumpslot_pc = duk__get_current_pc(comp_ctx);\n\t\tduk__emit_abc(comp_ctx, DUK_OP_JUMP, 0);\n\t}\n\n\t/* Output shuffling: only one output register is realistically possible.\n\t *\n\t * (Zero would normally be an OK marker value: if the target register\n\t * was zero, it would never be shuffled.  But with DUK_USE_SHUFFLE_TORTURE\n\t * this is no longer true, so use -1 as a marker instead.)\n\t */\n\n\tif (a_out >= 0) {\n\t\tDUK_ASSERT(b_out < 0);\n\t\tDUK_ASSERT(c_out < 0);\n\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, a, a_out));\n\n\t\tif (op == DUK_OP_CSVAR) {\n\t\t\t/* Special handling for CSVAR shuffling.  The variable lookup\n\t\t\t * results in a <value, this binding> pair in successive\n\t\t\t * registers so use two shuffle registers and two output\n\t\t\t * loads.  (In practice this is dead code because temp/const\n\t\t\t * limit is reached first.)\n\t\t\t */\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, a + 1, a_out + 1));\n\t\t}\n\t} else if (b_out >= 0) {\n\t\tDUK_ASSERT(a_out < 0);\n\t\tDUK_ASSERT(c_out < 0);\n\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, b, b_out));\n\t} else if (c_out >= 0) {\n\t\tDUK_ASSERT(b_out < 0);\n\t\tDUK_ASSERT(c_out < 0);\n\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, c, c_out));\n\t}\n\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* For many of the helpers below it'd be technically correct to add\n * \"no shuffle\" flags for parameters passed in as zero.  For example,\n * duk__emit_a_b() should call duk__emit_a_b_c() with C set to 0, and\n * DUK__EMIT_FLAG_NO_SHUFFLE_C added to op_flags.  However, since the\n * C value is 0, it'll never get shuffled so adding the flag is just\n * unnecessary additional code.  This is unfortunately not true for\n * \"shuffle torture\" mode which needs special handling.\n */\n\nDUK_LOCAL void duk__emit_a_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_C;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, a, b, 0);\n}\n\nDUK_LOCAL void duk__emit_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b, duk_regconst_t c) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_A;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, 0, b, c);\n}\n\n#if 0  /* unused */\nDUK_LOCAL void duk__emit_a(duk_compiler_ctx *comp_ctx, int op_flags, int a) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_B | DUK__EMIT_FLAG_NO_SHUFFLE_C;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, a, 0, 0);\n}\n#endif\n\n#if 0  /* unused */\nDUK_LOCAL void duk__emit_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_NO_SHUFFLE_C;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, 0, b, 0);\n}\n#endif\n\nDUK_LOCAL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t bc) {\n\tduk_instr_t ins;\n\tduk_int_t tmp;\n\n\t/* allow caller to give a const number with the DUK__CONST_MARKER */\n\tDUK_ASSERT(bc != -1);  /* Not 'none'. */\n\tbc = bc & (~DUK__CONST_MARKER);\n\n\tDUK_ASSERT_DISABLE((op_flags & 0xff) >= DUK_BC_OP_MIN);  /* unsigned */\n\tDUK_ASSERT((op_flags & 0xff) <= DUK_BC_OP_MAX);\n\tDUK_ASSERT(bc >= DUK_BC_BC_MIN);\n\tDUK_ASSERT(bc <= DUK_BC_BC_MAX);\n\tDUK_ASSERT((bc & DUK__CONST_MARKER) == 0);\n\n\tif (bc <= DUK_BC_BC_MAX) {\n\t\t;\n\t} else {\n\t\t/* No BC shuffling now. */\n\t\tgoto error_outofregs;\n\t}\n\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\tif (a <= DUK_BC_A_MAX && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A)) {\n#else\n\tif (a <= DUK_BC_A_MAX) {\n#endif\n\t\tins = DUK_ENC_OP_A_BC(op_flags & 0xff, a, bc);\n\t\tduk__emit(comp_ctx, ins);\n\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A) {\n\t\tgoto error_outofregs;\n\t} else if ((op_flags & 0xf0U) == DUK_OP_CALL0) {\n\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\ttmp = comp_ctx->curr_func.shuffle1;\n\t\tduk__emit_load_int32_noshuffle(comp_ctx, tmp, a);\n\t\top_flags |= DUK_BC_CALL_FLAG_INDIRECT;\n\t\tins = DUK_ENC_OP_A_BC(op_flags & 0xff, tmp, bc);\n\t\tduk__emit(comp_ctx, ins);\n\t} else if (a <= DUK_BC_BC_MAX) {\n\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\ttmp = comp_ctx->curr_func.shuffle1;\n\t\tins = DUK_ENC_OP_A_BC(op_flags & 0xff, tmp, bc);\n\t\tif (op_flags & DUK__EMIT_FLAG_A_IS_SOURCE) {\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, a));\n\t\t\tduk__emit(comp_ctx, ins);\n\t\t} else {\n\t\t\tduk__emit(comp_ctx, ins);\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, tmp, a));\n\t\t}\n\t} else {\n\t\tgoto error_outofregs;\n\t}\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__emit_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t bc) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top |= DUK__EMIT_FLAG_NO_SHUFFLE_A;\n#endif\n\tduk__emit_a_bc(comp_ctx, op, 0, bc);\n}\n\nDUK_LOCAL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t abc) {\n\tduk_instr_t ins;\n\n\tDUK_ASSERT_DISABLE(op >= DUK_BC_OP_MIN);  /* unsigned */\n\tDUK_ASSERT(op <= DUK_BC_OP_MAX);\n\tDUK_ASSERT_DISABLE(abc >= DUK_BC_ABC_MIN);  /* unsigned */\n\tDUK_ASSERT(abc <= DUK_BC_ABC_MAX);\n\tDUK_ASSERT((abc & DUK__CONST_MARKER) == 0);\n\tDUK_ASSERT(abc != -1);  /* Not 'none'. */\n\n\tif (abc <= DUK_BC_ABC_MAX) {\n\t\t;\n\t} else {\n\t\tgoto error_outofregs;\n\t}\n\tins = DUK_ENC_OP_ABC(op, abc);\n\tDUK_DDD(DUK_DDDPRINT(\"duk__emit_abc: 0x%08lx line=%ld pc=%ld op=%ld (%!X) abc=%ld (%!I)\",\n\t                     (unsigned long) ins, (long) comp_ctx->curr_token.start_line,\n\t                     (long) duk__get_current_pc(comp_ctx), (long) op, (long) op,\n\t                     (long) abc, (duk_instr_t) ins));\n\tduk__emit(comp_ctx, ins);\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__emit_load_int32_raw(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val, duk_small_uint_t op_flags) {\n\t/* XXX: Shuffling support could be implemented here so that LDINT+LDINTX\n\t * would only shuffle once (instead of twice).  The current code works\n\t * though, and has a smaller compiler footprint.\n\t */\n\n\tif ((val >= (duk_int32_t) DUK_BC_BC_MIN - (duk_int32_t) DUK_BC_LDINT_BIAS) &&\n\t    (val <= (duk_int32_t) DUK_BC_BC_MAX - (duk_int32_t) DUK_BC_LDINT_BIAS)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"emit LDINT to reg %ld for %ld\", (long) reg, (long) val));\n\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDINT | op_flags, reg, (duk_regconst_t) (val + (duk_int32_t) DUK_BC_LDINT_BIAS));\n\t} else {\n\t\tduk_int32_t hi = val >> DUK_BC_LDINTX_SHIFT;\n\t\tduk_int32_t lo = val & ((((duk_int32_t) 1) << DUK_BC_LDINTX_SHIFT) - 1);\n\t\tDUK_ASSERT(lo >= 0);\n\t\tDUK_DDD(DUK_DDDPRINT(\"emit LDINT+LDINTX to reg %ld for %ld -> hi %ld, lo %ld\",\n\t\t                     (long) reg, (long) val, (long) hi, (long) lo));\n\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDINT | op_flags, reg, (duk_regconst_t) (hi + (duk_int32_t) DUK_BC_LDINT_BIAS));\n\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDINTX | op_flags, reg, (duk_regconst_t) lo);\n\t}\n}\n\nDUK_LOCAL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val) {\n\tduk__emit_load_int32_raw(comp_ctx, reg, val, 0 /*op_flags*/);\n}\n\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n/* Used by duk__emit*() calls so that we don't shuffle the loadints that\n * are needed to handle indirect opcodes.\n */\nDUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val) {\n\tduk__emit_load_int32_raw(comp_ctx, reg, val, DUK__EMIT_FLAG_NO_SHUFFLE_A /*op_flags*/);\n}\n#else\nDUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val) {\n\t/* When torture not enabled, can just use the same helper because\n\t * 'reg' won't get spilled.\n\t */\n\tDUK_ASSERT(reg <= DUK_BC_A_MAX);\n\tduk__emit_load_int32(comp_ctx, reg, val);\n}\n#endif\n\nDUK_LOCAL void duk__emit_jump(duk_compiler_ctx *comp_ctx, duk_int_t target_pc) {\n\tduk_int_t curr_pc;\n\tduk_int_t offset;\n\n\tcurr_pc = (duk_int_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr));\n\toffset = (duk_int_t) target_pc - (duk_int_t) curr_pc - 1;\n\tDUK_ASSERT(offset + DUK_BC_JUMP_BIAS >= DUK_BC_ABC_MIN);\n\tDUK_ASSERT(offset + DUK_BC_JUMP_BIAS <= DUK_BC_ABC_MAX);\n\tduk__emit_abc(comp_ctx, DUK_OP_JUMP, (duk_regconst_t) (offset + DUK_BC_JUMP_BIAS));\n}\n\nDUK_LOCAL duk_int_t duk__emit_jump_empty(duk_compiler_ctx *comp_ctx) {\n\tduk_int_t ret;\n\n\tret = duk__get_current_pc(comp_ctx);  /* useful for patching jumps later */\n\tduk__emit_op_only(comp_ctx, DUK_OP_JUMP);\n\treturn ret;\n}\n\n/* Insert an empty jump in the middle of code emitted earlier.  This is\n * currently needed for compiling for-in.\n */\nDUK_LOCAL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc) {\n#if defined(DUK_USE_PC2LINE)\n\tduk_int_t line;\n#endif\n\tduk_compiler_instr *instr;\n\tduk_size_t offset;\n\n\tDUK_ASSERT(jump_pc >= 0);\n\toffset = (duk_size_t) jump_pc * sizeof(duk_compiler_instr);\n\tinstr = (duk_compiler_instr *) (void *)\n\t        DUK_BW_INSERT_ENSURE_AREA(comp_ctx->thr,\n\t                                  &comp_ctx->curr_func.bw_code,\n\t                                  offset,\n\t                                  sizeof(duk_compiler_instr));\n\n#if defined(DUK_USE_PC2LINE)\n\tline = comp_ctx->curr_token.start_line;  /* approximation, close enough */\n#endif\n\tinstr->ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, 0);\n#if defined(DUK_USE_PC2LINE)\n\tinstr->line = (duk_uint32_t) line;\n#endif\n\n\tDUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, sizeof(duk_compiler_instr));\n\tif (DUK_UNLIKELY(DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) > DUK_USE_ESBC_MAX_BYTES)) {\n\t\tgoto fail_bc_limit;\n\t}\n\treturn;\n\n  fail_bc_limit:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_BYTECODE_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Does not assume that jump_pc contains a DUK_OP_JUMP previously; this is intentional\n * to allow e.g. an INVALID opcode be overwritten with a JUMP (label management uses this).\n */\nDUK_LOCAL void duk__patch_jump(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc, duk_int_t target_pc) {\n\tduk_compiler_instr *instr;\n\tduk_int_t offset;\n\n\t/* allow negative PCs, behave as a no-op */\n\tif (jump_pc < 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__patch_jump(): nop call, jump_pc=%ld (<0), target_pc=%ld\",\n\t\t                     (long) jump_pc, (long) target_pc));\n\t\treturn;\n\t}\n\tDUK_ASSERT(jump_pc >= 0);\n\n\t/* XXX: range assert */\n\tinstr = duk__get_instr_ptr(comp_ctx, jump_pc);\n\tDUK_ASSERT(instr != NULL);\n\n\t/* XXX: range assert */\n\toffset = target_pc - jump_pc - 1;\n\n\tinstr->ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, offset + DUK_BC_JUMP_BIAS);\n\tDUK_DDD(DUK_DDDPRINT(\"duk__patch_jump(): jump_pc=%ld, target_pc=%ld, offset=%ld\",\n\t                     (long) jump_pc, (long) target_pc, (long) offset));\n}\n\nDUK_LOCAL void duk__patch_jump_here(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc) {\n\tduk__patch_jump(comp_ctx, jump_pc, duk__get_current_pc(comp_ctx));\n}\n\nDUK_LOCAL void duk__patch_trycatch(duk_compiler_ctx *comp_ctx, duk_int_t ldconst_pc, duk_int_t trycatch_pc, duk_regconst_t reg_catch, duk_regconst_t const_varname, duk_small_uint_t flags) {\n\tduk_compiler_instr *instr;\n\n\tDUK_ASSERT(DUK__ISREG(reg_catch));\n\n\tinstr = duk__get_instr_ptr(comp_ctx, ldconst_pc);\n\tDUK_ASSERT(DUK_DEC_OP(instr->ins) == DUK_OP_LDCONST);\n\tDUK_ASSERT(instr != NULL);\n\tif (const_varname & DUK__CONST_MARKER) {\n\t\t/* Have a catch variable. */\n\t\tconst_varname = const_varname & (~DUK__CONST_MARKER);\n\t\tif (reg_catch > DUK_BC_BC_MAX || const_varname > DUK_BC_BC_MAX) {\n\t\t\t/* Catch attempts to use out-of-range reg/const.  Without this\n\t\t\t * check Duktape 0.12.0 could generate invalid code which caused\n\t\t\t * an assert failure on execution.  This error is triggered e.g.\n\t\t\t * for functions with a lot of constants and a try-catch statement.\n\t\t\t * Shuffling or opcode semantics change is needed to fix the issue.\n\t\t\t * See: test-bug-trycatch-many-constants.js.\n\t\t\t */\n\t\t\tDUK_D(DUK_DPRINT(\"failed to patch trycatch: flags=%ld, reg_catch=%ld, const_varname=%ld (0x%08lx)\",\n\t\t\t                 (long) flags, (long) reg_catch, (long) const_varname, (long) const_varname));\n\t\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tinstr->ins |= DUK_ENC_OP_A_BC(0, 0, const_varname);\n\t} else {\n\t\t/* No catch variable, e.g. a try-finally; replace LDCONST with\n\t\t * NOP to avoid a bogus LDCONST.\n\t\t */\n\t\tinstr->ins = DUK_ENC_OP(DUK_OP_NOP);\n\t}\n\n\tinstr = duk__get_instr_ptr(comp_ctx, trycatch_pc);\n\tDUK_ASSERT(instr != NULL);\n\tDUK_ASSERT_DISABLE(flags >= DUK_BC_A_MIN);\n\tDUK_ASSERT(flags <= DUK_BC_A_MAX);\n\tinstr->ins = DUK_ENC_OP_A_BC(DUK_OP_TRYCATCH, flags, reg_catch);\n}\n\nDUK_LOCAL void duk__emit_if_false_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst) {\n\tduk_small_uint_t op;\n\n\top = DUK__ISREG(regconst) ? DUK_OP_IFFALSE_R : DUK_OP_IFFALSE_C;\n\tduk__emit_bc(comp_ctx, op, regconst);  /* helper will remove const flag */\n}\n\nDUK_LOCAL void duk__emit_if_true_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst) {\n\tduk_small_uint_t op;\n\n\top = DUK__ISREG(regconst) ? DUK_OP_IFTRUE_R : DUK_OP_IFTRUE_C;\n\tduk__emit_bc(comp_ctx, op, regconst);  /* helper will remove const flag */\n}\n\nDUK_LOCAL void duk__emit_invalid(duk_compiler_ctx *comp_ctx) {\n\tduk__emit_op_only(comp_ctx, DUK_OP_INVALID);\n}\n\n/*\n *  Peephole optimizer for finished bytecode.\n *\n *  Does not remove opcodes; currently only straightens out unconditional\n *  jump chains which are generated by several control structures.\n */\n\nDUK_LOCAL void duk__peephole_optimize_bytecode(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_instr *bc;\n\tduk_small_uint_t iter;\n\tduk_int_t i, n;\n\tduk_int_t count_opt;\n\n\tbc = (duk_compiler_instr *) (void *) DUK_BW_GET_BASEPTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code);\n#if defined(DUK_USE_BUFLEN16)\n\t/* No need to assert, buffer size maximum is 0xffff. */\n#else\n\tDUK_ASSERT((duk_size_t) DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr) <= (duk_size_t) DUK_INT_MAX);  /* bytecode limits */\n#endif\n\tn = (duk_int_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr));\n\n\tfor (iter = 0; iter < DUK_COMPILER_PEEPHOLE_MAXITER; iter++) {\n\t\tcount_opt = 0;\n\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk_instr_t ins;\n\t\t\tduk_int_t target_pc1;\n\t\t\tduk_int_t target_pc2;\n\n\t\t\tins = bc[i].ins;\n\t\t\tif (DUK_DEC_OP(ins) != DUK_OP_JUMP) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttarget_pc1 = i + 1 + (duk_int_t) DUK_DEC_ABC(ins) - (duk_int_t) DUK_BC_JUMP_BIAS;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"consider jump at pc %ld; target_pc=%ld\", (long) i, (long) target_pc1));\n\t\t\tDUK_ASSERT(target_pc1 >= 0);\n\t\t\tDUK_ASSERT(target_pc1 < n);\n\n\t\t\t/* Note: if target_pc1 == i, we'll optimize a jump to itself.\n\t\t\t * This does not need to be checked for explicitly; the case\n\t\t\t * is rare and max iter breaks us out.\n\t\t\t */\n\n\t\t\tins = bc[target_pc1].ins;\n\t\t\tif (DUK_DEC_OP(ins) != DUK_OP_JUMP) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttarget_pc2 = target_pc1 + 1 + (duk_int_t) DUK_DEC_ABC(ins) - (duk_int_t) DUK_BC_JUMP_BIAS;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"optimizing jump at pc %ld; old target is %ld -> new target is %ld\",\n\t\t\t                     (long) i, (long) target_pc1, (long) target_pc2));\n\n\t\t\tbc[i].ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, target_pc2 - (i + 1) + DUK_BC_JUMP_BIAS);\n\n\t\t\tcount_opt++;\n\t\t}\n\n\t\tDUK_DD(DUK_DDPRINT(\"optimized %ld jumps on peephole round %ld\", (long) count_opt, (long) (iter + 1)));\n\n\t\tif (count_opt == 0) {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/*\n *  Intermediate value helpers\n */\n\n/* Flags for intermediate value coercions.  A flag for using a forced reg\n * is not needed, the forced_reg argument suffices and generates better\n * code (it is checked as it is used).\n */\n/* XXX: DUK__IVAL_FLAG_REQUIRE_SHORT is passed but not currently implemented\n * by ispec/ivalue operations.\n */\n#define DUK__IVAL_FLAG_ALLOW_CONST          (1 << 0)  /* allow a constant to be returned */\n#define DUK__IVAL_FLAG_REQUIRE_TEMP         (1 << 1)  /* require a (mutable) temporary as a result (or a const if allowed) */\n#define DUK__IVAL_FLAG_REQUIRE_SHORT        (1 << 2)  /* require a short (8-bit) reg/const which fits into bytecode B/C slot */\n\n/* XXX: some code might benefit from DUK__SETTEMP_IFTEMP(thr,x) */\n\n#if 0  /* enable manually for dumping */\n#define DUK__DUMP_ISPEC(compctx,ispec) do { duk__dump_ispec((compctx), (ispec)); } while (0)\n#define DUK__DUMP_IVALUE(compctx,ivalue) do { duk__dump_ivalue((compctx), (ivalue)); } while (0)\n\nDUK_LOCAL void duk__dump_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *x) {\n\tDUK_D(DUK_DPRINT(\"ispec dump: t=%ld regconst=0x%08lx, valstack_idx=%ld, value=%!T\",\n\t                 (long) x->t, (unsigned long) x->regconst, (long) x->valstack_idx,\n\t                 duk_get_tval(comp_ctx->thr, x->valstack_idx)));\n}\nDUK_LOCAL void duk__dump_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tDUK_D(DUK_DPRINT(\"ivalue dump: t=%ld op=%ld \"\n\t                 \"x1={t=%ld regconst=0x%08lx valstack_idx=%ld value=%!T} \"\n\t                 \"x2={t=%ld regconst=0x%08lx valstack_idx=%ld value=%!T}\",\n\t\t         (long) x->t, (long) x->op,\n\t                 (long) x->x1.t, (unsigned long) x->x1.regconst, (long) x->x1.valstack_idx,\n\t                 duk_get_tval(comp_ctx->thr, x->x1.valstack_idx),\n\t                 (long) x->x2.t, (unsigned long) x->x2.regconst, (long) x->x2.valstack_idx,\n\t                 duk_get_tval(comp_ctx->thr, x->x2.valstack_idx)));\n}\n#else\n#define DUK__DUMP_ISPEC(comp_ctx,x) do {} while (0)\n#define DUK__DUMP_IVALUE(comp_ctx,x) do {} while (0)\n#endif\n\nDUK_LOCAL void duk__ivalue_regconst(duk_ivalue *x, duk_regconst_t regconst) {\n\tx->t = DUK_IVAL_PLAIN;\n\tx->x1.t = DUK_ISPEC_REGCONST;\n\tx->x1.regconst = regconst;\n}\n\nDUK_LOCAL void duk__ivalue_plain_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tx->t = DUK_IVAL_PLAIN;\n\tx->x1.t = DUK_ISPEC_VALUE;\n\tduk_replace(comp_ctx->thr, x->x1.valstack_idx);\n}\n\nDUK_LOCAL void duk__ivalue_var_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tx->t = DUK_IVAL_VAR;\n\tx->x1.t = DUK_ISPEC_VALUE;\n\tduk_replace(comp_ctx->thr, x->x1.valstack_idx);\n}\n\nDUK_LOCAL_DECL void duk__ivalue_var_hstring(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n\tduk_push_hstring(comp_ctx->thr, h);\n\tduk__ivalue_var_fromstack(comp_ctx, x);\n}\n\nDUK_LOCAL void duk__copy_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *src, duk_ispec *dst) {\n\tdst->t = src->t;\n\tdst->regconst = src->regconst;\n\tduk_copy(comp_ctx->thr, src->valstack_idx, dst->valstack_idx);\n}\n\nDUK_LOCAL void duk__copy_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *src, duk_ivalue *dst) {\n\tdst->t = src->t;\n\tdst->op = src->op;\n\tdst->x1.t = src->x1.t;\n\tdst->x1.regconst = src->x1.regconst;\n\tdst->x2.t = src->x2.t;\n\tdst->x2.regconst = src->x2.regconst;\n\tduk_copy(comp_ctx->thr, src->x1.valstack_idx, dst->x1.valstack_idx);\n\tduk_copy(comp_ctx->thr, src->x2.valstack_idx, dst->x2.valstack_idx);\n}\n\nDUK_LOCAL duk_regconst_t duk__alloctemps(duk_compiler_ctx *comp_ctx, duk_small_int_t num) {\n\tduk_regconst_t res;\n\n\tres = comp_ctx->curr_func.temp_next;\n\tcomp_ctx->curr_func.temp_next += num;\n\n\tif (comp_ctx->curr_func.temp_next > DUK__MAX_TEMPS) {  /* == DUK__MAX_TEMPS is OK */\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_TEMP_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* maintain highest 'used' temporary, needed to figure out nregs of function */\n\tif (comp_ctx->curr_func.temp_next > comp_ctx->curr_func.temp_max) {\n\t\tcomp_ctx->curr_func.temp_max = comp_ctx->curr_func.temp_next;\n\t}\n\n\treturn res;\n}\n\nDUK_LOCAL duk_regconst_t duk__alloctemp(duk_compiler_ctx *comp_ctx) {\n\treturn duk__alloctemps(comp_ctx, 1);\n}\n\nDUK_LOCAL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, duk_regconst_t temp_next) {\n\tcomp_ctx->curr_func.temp_next = temp_next;\n\tif (temp_next > comp_ctx->curr_func.temp_max) {\n\t\tcomp_ctx->curr_func.temp_max = temp_next;\n\t}\n}\n\n/* get const for value at valstack top */\nDUK_LOCAL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_compiler_func *f = &comp_ctx->curr_func;\n\tduk_tval *tv1;\n\tduk_int_t i, n, n_check;\n\n\tn = (duk_int_t) duk_get_length(thr, f->consts_idx);\n\n\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(tv1 != NULL);\n\n#if defined(DUK_USE_FASTINT)\n\t/* Explicit check for fastint downgrade. */\n\tDUK_TVAL_CHKFAST_INPLACE_SLOW(tv1);\n#endif\n\n\t/* Sanity workaround for handling functions with a large number of\n\t * constants at least somewhat reasonably.  Otherwise checking whether\n\t * we already have the constant would grow very slow (as it is O(N^2)).\n\t */\n\tn_check = (n > DUK__GETCONST_MAX_CONSTS_CHECK ? DUK__GETCONST_MAX_CONSTS_CHECK : n);\n\tfor (i = 0; i < n_check; i++) {\n\t\tduk_tval *tv2 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, f->h_consts, i);\n\n\t\t/* Strict equality is NOT enough, because we cannot use the same\n\t\t * constant for e.g. +0 and -0.\n\t\t */\n\t\tif (duk_js_samevalue(tv1, tv2)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"reused existing constant for %!T -> const index %ld\",\n\t\t\t                     (duk_tval *) tv1, (long) i));\n\t\t\tduk_pop(thr);\n\t\t\treturn (duk_regconst_t) i | (duk_regconst_t) DUK__CONST_MARKER;\n\t\t}\n\t}\n\n\tif (n > DUK__MAX_CONSTS) {\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_CONST_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"allocating new constant for %!T -> const index %ld\",\n\t                     (duk_tval *) tv1, (long) n));\n\t(void) duk_put_prop_index(thr, f->consts_idx, (duk_uarridx_t) n);  /* invalidates tv1, tv2 */\n\treturn (duk_regconst_t) n | (duk_regconst_t) DUK__CONST_MARKER;\n}\n\nDUK_LOCAL duk_bool_t duk__const_needs_refcount(duk_compiler_ctx *comp_ctx, duk_regconst_t rc) {\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_compiler_func *f = &comp_ctx->curr_func;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT((rc & DUK__CONST_MARKER) == 0);  /* caller removes const marker */\n\t(void) duk_get_prop_index(comp_ctx->thr, f->consts_idx, (duk_uarridx_t) rc);\n\tret = !duk_is_number(comp_ctx->thr, -1);  /* now only number/string, so conservative check */\n\tduk_pop(comp_ctx->thr);\n\treturn ret;\n#else\n\tDUK_UNREF(comp_ctx);\n\tDUK_UNREF(rc);\n\tDUK_ASSERT((rc & DUK__CONST_MARKER) == 0);  /* caller removes const marker */\n\treturn 0;\n#endif\n}\n\n/* Get the value represented by an duk_ispec to a register or constant.\n * The caller can control the result by indicating whether or not:\n *\n *   (1) a constant is allowed (sometimes the caller needs the result to\n *       be in a register)\n *\n *   (2) a temporary register is required (usually when caller requires\n *       the register to be safely mutable; normally either a bound\n *       register or a temporary register are both OK)\n *\n *   (3) a forced register target needs to be used\n *\n * Bytecode may be emitted to generate the necessary value.  The return\n * value is either a register or a constant.\n */\n\nDUK_LOCAL\nduk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                         duk_ispec *x,\n                                         duk_regconst_t forced_reg,\n                                         duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__ispec_toregconst_raw(): x={%ld:%ld:%!T}, \"\n\t                     \"forced_reg=%ld, flags 0x%08lx: allow_const=%ld require_temp=%ld require_short=%ld\",\n\t                     (long) x->t,\n\t                     (long) x->regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->valstack_idx),\n\t                     (long) forced_reg,\n\t                     (unsigned long) flags,\n\t                     (long) ((flags & DUK__IVAL_FLAG_ALLOW_CONST) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_SHORT) ? 1 : 0)));\n\n\tswitch (x->t) {\n\tcase DUK_ISPEC_VALUE: {\n\t\tduk_tval *tv;\n\n\t\ttv = DUK_GET_TVAL_POSIDX(thr, x->valstack_idx);\n\t\tDUK_ASSERT(tv != NULL);\n\n\t\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\t\tcase DUK_TAG_UNDEFINED: {\n\t\t\t/* Note: although there is no 'undefined' literal, undefined\n\t\t\t * values can occur during compilation as a result of e.g.\n\t\t\t * the 'void' operator.\n\t\t\t */\n\t\t\tduk_regconst_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_LDUNDEF, dest);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_NULL: {\n\t\t\tduk_regconst_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_LDNULL, dest);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_BOOLEAN: {\n\t\t\tduk_regconst_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             (DUK_TVAL_GET_BOOLEAN(tv) ? DUK_OP_LDTRUE : DUK_OP_LDFALSE),\n\t\t\t             dest);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_POINTER: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_STRING: {\n\t\t\tduk_hstring *h;\n\t\t\tduk_regconst_t dest;\n\t\t\tduk_regconst_t constidx;\n\n\t\t\th = DUK_TVAL_GET_STRING(tv);\n\t\t\tDUK_UNREF(h);\n\t\t\tDUK_ASSERT(h != NULL);\n\n#if 0  /* XXX: to be implemented? */\n\t\t\t/* Use special opcodes to load short strings */\n\t\t\tif (DUK_HSTRING_GET_BYTELEN(h) <= 2) {\n\t\t\t\t/* Encode into a single opcode (18 bits can encode 1-2 bytes + length indicator) */\n\t\t\t} else if (DUK_HSTRING_GET_BYTELEN(h) <= 6) {\n\t\t\t\t/* Encode into a double constant (53 bits can encode 6*8 = 48 bits + 3-bit length */\n\t\t\t}\n#endif\n\t\t\tduk_dup(thr, x->valstack_idx);\n\t\t\tconstidx = duk__getconst(comp_ctx);\n\n\t\t\tif (flags & DUK__IVAL_FLAG_ALLOW_CONST) {\n\t\t\t\treturn constidx;\n\t\t\t}\n\n\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, constidx);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_OBJECT: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_BUFFER: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_LIGHTFUNC: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_FASTINT)\n\t\tcase DUK_TAG_FASTINT:\n#endif\n\t\tdefault: {\n\t\t\t/* number */\n\t\t\tduk_regconst_t dest;\n\t\t\tduk_regconst_t constidx;\n\t\t\tduk_double_t dval;\n\t\t\tduk_int32_t ival;\n\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\t\tdval = DUK_TVAL_GET_NUMBER(tv);\n\n\t\t\tif (!(flags & DUK__IVAL_FLAG_ALLOW_CONST)) {\n\t\t\t\t/* A number can be loaded either through a constant, using\n\t\t\t\t * LDINT, or using LDINT+LDINTX.  LDINT is always a size win,\n\t\t\t\t * LDINT+LDINTX is not if the constant is used multiple times.\n\t\t\t\t * Currently always prefer LDINT+LDINTX over a double constant.\n\t\t\t\t */\n\n\t\t\t\tif (duk_is_whole_get_int32_nonegzero(dval, &ival)) {\n\t\t\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\t\t\tduk__emit_load_int32(comp_ctx, dest, ival);\n\t\t\t\t\treturn dest;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_dup(thr, x->valstack_idx);\n\t\t\tconstidx = duk__getconst(comp_ctx);\n\n\t\t\tif (flags & DUK__IVAL_FLAG_ALLOW_CONST) {\n\t\t\t\treturn constidx;\n\t\t\t} else {\n\t\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, constidx);\n\t\t\t\treturn dest;\n\t\t\t}\n\t\t}\n\t\t}  /* end switch */\n\t\tgoto fail_internal;  /* never here */\n\t}\n\tcase DUK_ISPEC_REGCONST: {\n\t\tif (forced_reg >= 0) {\n\t\t\tif (DUK__ISCONST(x->regconst)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, forced_reg, x->regconst);\n\t\t\t} else if (x->regconst != forced_reg) {\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDREG, forced_reg, x->regconst);\n\t\t\t} else {\n\t\t\t\t; /* already in correct reg */\n\t\t\t}\n\t\t\treturn forced_reg;\n\t\t}\n\n\t\tDUK_ASSERT(forced_reg < 0);\n\t\tif (DUK__ISCONST(x->regconst)) {\n\t\t\tif (!(flags & DUK__IVAL_FLAG_ALLOW_CONST)) {\n\t\t\t\tduk_regconst_t dest = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, x->regconst);\n\t\t\t\treturn dest;\n\t\t\t}\n\t\t\treturn x->regconst;\n\t\t}\n\n\t\tDUK_ASSERT(forced_reg < 0 && !DUK__ISCONST(x->regconst));\n\t\tif ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) && !DUK__ISREG_TEMP(comp_ctx, x->regconst)) {\n\t\t\tduk_regconst_t dest = DUK__ALLOCTEMP(comp_ctx);\n\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDREG, dest, x->regconst);\n\t\t\treturn dest;\n\t\t}\n\t\treturn x->regconst;\n\t}\n\tdefault: {\n\t\tbreak;  /* never here */\n\t}\n\t}\n\n fail_internal:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_LOCAL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ispec *x, duk_regconst_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\t(void) duk__ispec_toregconst_raw(comp_ctx, x, forced_reg, 0 /*flags*/);\n}\n\n/* Coerce an duk_ivalue to a 'plain' value by generating the necessary\n * arithmetic operations, property access, or variable access bytecode.\n * The duk_ivalue argument ('x') is converted into a plain value as a\n * side effect.\n */\nDUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_regconst_t forced_reg) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__ivalue_toplain_raw(): x={t=%ld,op=%ld,x1={%ld:%ld:%!T},x2={%ld:%ld:%!T}}, \"\n\t                     \"forced_reg=%ld\",\n\t                     (long) x->t, (long) x->op,\n\t                     (long) x->x1.t, (long) x->x1.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x1.valstack_idx),\n\t                     (long) x->x2.t, (long) x->x2.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x2.valstack_idx),\n\t                     (long) forced_reg));\n\n\tswitch (x->t) {\n\tcase DUK_IVAL_PLAIN: {\n\t\treturn;\n\t}\n\t/* XXX: support unary arithmetic ivalues (useful?) */\n\tcase DUK_IVAL_ARITH: {\n\t\tduk_regconst_t arg1;\n\t\tduk_regconst_t arg2;\n\t\tduk_regconst_t dest;\n\t\tduk_tval *tv1;\n\t\tduk_tval *tv2;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"arith to plain conversion\"));\n\n\t\t/* inline arithmetic check for constant values */\n\t\t/* XXX: use the exactly same arithmetic function here as in executor */\n\t\tif (x->x1.t == DUK_ISPEC_VALUE && x->x2.t == DUK_ISPEC_VALUE && x->t == DUK_IVAL_ARITH) {\n\t\t\ttv1 = DUK_GET_TVAL_POSIDX(thr, x->x1.valstack_idx);\n\t\t\ttv2 = DUK_GET_TVAL_POSIDX(thr, x->x2.valstack_idx);\n\t\t\tDUK_ASSERT(tv1 != NULL);\n\t\t\tDUK_ASSERT(tv2 != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"arith: tv1=%!T, tv2=%!T\",\n\t\t\t                     (duk_tval *) tv1,\n\t\t\t                     (duk_tval *) tv2));\n\n\t\t\tif (DUK_TVAL_IS_NUMBER(tv1) && DUK_TVAL_IS_NUMBER(tv2)) {\n\t\t\t\tduk_double_t d1 = DUK_TVAL_GET_NUMBER(tv1);\n\t\t\t\tduk_double_t d2 = DUK_TVAL_GET_NUMBER(tv2);\n\t\t\t\tduk_double_t d3;\n\t\t\t\tduk_bool_t accept_fold = 1;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"arith inline check: d1=%lf, d2=%lf, op=%ld\",\n\t\t\t\t                     (double) d1, (double) d2, (long) x->op));\n\t\t\t\tswitch (x->op) {\n\t\t\t\tcase DUK_OP_ADD: {\n\t\t\t\t\td3 = d1 + d2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_SUB: {\n\t\t\t\t\td3 = d1 - d2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_MUL: {\n\t\t\t\t\td3 = d1 * d2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_DIV: {\n\t\t\t\t\t/* Division-by-zero is undefined\n\t\t\t\t\t * behavior, so rely on a helper.\n\t\t\t\t\t */\n\t\t\t\t\td3 = duk_double_div(d1, d2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_EXP: {\n\t\t\t\t\td3 = (duk_double_t) duk_js_arith_pow((double) d1, (double) d2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\td3 = 0.0;  /* Won't be used, but silence MSVC /W4 warning. */\n\t\t\t\t\taccept_fold = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (accept_fold) {\n\t\t\t\t\tduk_double_union du;\n\t\t\t\t\tdu.d = d3;\n\t\t\t\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\t\t\t\t\td3 = du.d;\n\n\t\t\t\t\tx->t = DUK_IVAL_PLAIN;\n\t\t\t\t\tDUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE);\n\t\t\t\t\tDUK_TVAL_SET_NUMBER(tv1, d3);  /* old value is number: no refcount */\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else if (x->op == DUK_OP_ADD && DUK_TVAL_IS_STRING(tv1) && DUK_TVAL_IS_STRING(tv2)) {\n\t\t\t\t/* Inline string concatenation.  No need to check for\n\t\t\t\t * symbols, as all inputs are valid ECMAScript strings.\n\t\t\t\t */\n\t\t\t\tduk_dup(thr, x->x1.valstack_idx);\n\t\t\t\tduk_dup(thr, x->x2.valstack_idx);\n\t\t\t\tduk_concat(thr, 2);\n\t\t\t\tduk_replace(thr, x->x1.valstack_idx);\n\t\t\t\tx->t = DUK_IVAL_PLAIN;\n\t\t\t\tDUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\targ1 = duk__ispec_toregconst_raw(comp_ctx, &x->x1, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\t\targ2 = duk__ispec_toregconst_raw(comp_ctx, &x->x2, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\n\t\t/* If forced reg, use it as destination.  Otherwise try to\n\t\t * use either coerced ispec if it is a temporary.\n\t\t */\n\t\tif (forced_reg >= 0) {\n\t\t\tdest = forced_reg;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg1)) {\n\t\t\tdest = arg1;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg2)) {\n\t\t\tdest = arg2;\n\t\t} else {\n\t\t\tdest = DUK__ALLOCTEMP(comp_ctx);\n\t\t}\n\n\t\tDUK_ASSERT(DUK__ISREG(dest));\n\t\tduk__emit_a_b_c(comp_ctx, x->op | DUK__EMIT_FLAG_BC_REGCONST, dest, arg1, arg2);\n\n\t\tduk__ivalue_regconst(x, dest);\n\t\treturn;\n\t}\n\tcase DUK_IVAL_PROP: {\n\t\t/* XXX: very similar to DUK_IVAL_ARITH - merge? */\n\t\tduk_regconst_t arg1;\n\t\tduk_regconst_t arg2;\n\t\tduk_regconst_t dest;\n\n\t\t/* Need a short reg/const, does not have to be a mutable temp. */\n\t\targ1 = duk__ispec_toregconst_raw(comp_ctx, &x->x1, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\t\targ2 = duk__ispec_toregconst_raw(comp_ctx, &x->x2, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\n\t\t/* Pick a destination register.  If either base value or key\n\t\t * happens to be a temp value, reuse it as the destination.\n\t\t *\n\t\t * XXX: The temp must be a \"mutable\" one, i.e. such that no\n\t\t * other expression is using it anymore.  Here this should be\n\t\t * the case because the value of a property access expression\n\t\t * is neither the base nor the key, but the lookup result.\n\t\t */\n\n\t\tif (forced_reg >= 0) {\n\t\t\tdest = forced_reg;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg1)) {\n\t\t\tdest = arg1;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg2)) {\n\t\t\tdest = arg2;\n\t\t} else {\n\t\t\tdest = DUK__ALLOCTEMP(comp_ctx);\n\t\t}\n\n\t\tduk__emit_a_b_c(comp_ctx,\n\t\t                DUK_OP_GETPROP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t                dest,\n\t\t                arg1,\n\t\t                arg2);\n\n\t\tduk__ivalue_regconst(x, dest);\n\t\treturn;\n\t}\n\tcase DUK_IVAL_VAR: {\n\t\t/* x1 must be a string */\n\t\tduk_regconst_t dest;\n\t\tduk_regconst_t reg_varbind;\n\t\tduk_regconst_t rc_varname;\n\n\t\tDUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE);\n\n\t\tduk_dup(thr, x->x1.valstack_idx);\n\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\tduk__ivalue_regconst(x, reg_varbind);\n\t\t} else {\n\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_GETVAR, dest, rc_varname);\n\t\t\tduk__ivalue_regconst(x, dest);\n\t\t}\n\t\treturn;\n\t}\n\tcase DUK_IVAL_NONE:\n\tdefault: {\n\t\tDUK_D(DUK_DPRINT(\"invalid ivalue type: %ld\", (long) x->t));\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* evaluate to plain value, no forced register (temp/bound reg both ok) */\nDUK_LOCAL void duk__ivalue_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tduk__ivalue_toplain_raw(comp_ctx, x, -1 /*forced_reg*/);\n}\n\n/* evaluate to final form (e.g. coerce GETPROP to code), throw away temp */\nDUK_LOCAL void duk__ivalue_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tduk_regconst_t temp;\n\n\t/* If duk__ivalue_toplain_raw() allocates a temp, forget it and\n\t * restore next temp state.\n\t */\n\ttemp = DUK__GETTEMP(comp_ctx);\n\tduk__ivalue_toplain_raw(comp_ctx, x, -1 /*forced_reg*/);\n\tDUK__SETTEMP(comp_ctx, temp);\n}\n\n/* Coerce an duk_ivalue to a register or constant; result register may\n * be a temp or a bound register.\n *\n * The duk_ivalue argument ('x') is converted into a regconst as a\n * side effect.\n */\nDUK_LOCAL\nduk_regconst_t duk__ivalue_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                          duk_ivalue *x,\n                                          duk_regconst_t forced_reg,\n                                          duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg;\n\tDUK_UNREF(thr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__ivalue_toregconst_raw(): x={t=%ld,op=%ld,x1={%ld:%ld:%!T},x2={%ld:%ld:%!T}}, \"\n\t                     \"forced_reg=%ld, flags 0x%08lx: allow_const=%ld require_temp=%ld require_short=%ld\",\n\t                     (long) x->t, (long) x->op,\n\t                     (long) x->x1.t, (long) x->x1.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x1.valstack_idx),\n\t                     (long) x->x2.t, (long) x->x2.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x2.valstack_idx),\n\t                     (long) forced_reg,\n\t                     (unsigned long) flags,\n\t                     (long) ((flags & DUK__IVAL_FLAG_ALLOW_CONST) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_SHORT) ? 1 : 0)));\n\n\t/* first coerce to a plain value */\n\tduk__ivalue_toplain_raw(comp_ctx, x, forced_reg);\n\tDUK_ASSERT(x->t == DUK_IVAL_PLAIN);\n\n\t/* then to a register */\n\treg = duk__ispec_toregconst_raw(comp_ctx, &x->x1, forced_reg, flags);\n\tduk__ivalue_regconst(x, reg);\n\n\treturn reg;\n}\n\nDUK_LOCAL duk_regconst_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, 0 /*flags*/);\n}\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__ivalue_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/);\n}\n#endif\n\nDUK_LOCAL void duk__ivalue_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_int_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\t(void) duk__ivalue_toregconst_raw(comp_ctx, x, forced_reg, 0 /*flags*/);\n}\n\nDUK_LOCAL duk_regconst_t duk__ivalue_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n}\n\nDUK_LOCAL duk_regconst_t duk__ivalue_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/);\n}\n\n/* The issues below can be solved with better flags */\n\n/* XXX: many operations actually want toforcedtemp() -- brand new temp? */\n/* XXX: need a toplain_ignore() which will only coerce a value to a temp\n * register if it might have a side effect.  Side-effect free values do not\n * need to be coerced.\n */\n\n/*\n *  Identifier handling\n */\n\nDUK_LOCAL duk_regconst_t duk__lookup_active_register_binding(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hstring *h_varname;\n\tduk_regconst_t ret;\n\n\tDUK_DDD(DUK_DDDPRINT(\"resolving identifier reference to '%!T'\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/*\n\t *  Special name handling\n\t */\n\n\th_varname = duk_known_hstring(thr, -1);\n\n\tif (h_varname == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"flagging function as accessing 'arguments'\"));\n\t\tcomp_ctx->curr_func.id_access_arguments = 1;\n\t}\n\n\t/*\n\t *  Inside one or more 'with' statements fall back to slow path always.\n\t *  (See e.g. test-stmt-with.js.)\n\t */\n\n\tif (comp_ctx->curr_func.with_depth > 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup inside a 'with' -> fall back to slow path\"));\n\t\tgoto slow_path_own;\n\t}\n\n\t/*\n\t *  Any catch bindings (\"catch (e)\") also affect identifier binding.\n\t *\n\t *  Currently, the varmap is modified for the duration of the catch\n\t *  clause to ensure any identifier accesses with the catch variable\n\t *  name will use slow path.\n\t */\n\n\tduk_get_prop(thr, comp_ctx->curr_func.varmap_idx);\n\tif (duk_is_number(thr, -1)) {\n\t\tret = duk_to_int(thr, -1);\n\t\tduk_pop(thr);\n\t} else {\n\t\tduk_pop(thr);\n\t\tif (comp_ctx->curr_func.catch_depth > 0 || comp_ctx->curr_func.with_depth > 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slow path access from inside a try-catch or with needs _Varmap\"));\n\t\t\tgoto slow_path_own;\n\t\t} else {\n\t\t\t/* In this case we're doing a variable lookup that doesn't\n\t\t\t * match our own variables, so _Varmap won't be needed at\n\t\t\t * run time.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slow path access outside of try-catch and with, no need for _Varmap\"));\n\t\t\tgoto slow_path_notown;\n\t\t}\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup -> reg %ld\", (long) ret));\n\treturn ret;\n\n slow_path_notown:\n\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup -> slow path, not own variable\"));\n\n\tcomp_ctx->curr_func.id_access_slow = 1;\n\treturn (duk_regconst_t) -1;\n\n slow_path_own:\n\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup -> slow path, may be own variable\"));\n\n\tcomp_ctx->curr_func.id_access_slow = 1;\n\tcomp_ctx->curr_func.id_access_slow_own = 1;\n\treturn (duk_regconst_t) -1;\n}\n\n/* Lookup an identifier name in the current varmap, indicating whether the\n * identifier is register-bound and if not, allocating a constant for the\n * identifier name.  Returns 1 if register-bound, 0 otherwise.  Caller can\n * also check (out_reg_varbind >= 0) to check whether or not identifier is\n * register bound.  The caller must NOT use out_rc_varname at all unless\n * return code is 0 or out_reg_varbind is < 0; this is becuase out_rc_varname\n * is unsigned and doesn't have a \"unused\" / none value.\n */\nDUK_LOCAL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *comp_ctx, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg_varbind;\n\tduk_regconst_t rc_varname;\n\n\t/* [ ... varname ] */\n\n\tduk_dup_top(thr);\n\treg_varbind = duk__lookup_active_register_binding(comp_ctx);\n\n\tif (reg_varbind >= 0) {\n\t\t*out_reg_varbind = reg_varbind;\n\t\t*out_rc_varname = 0;  /* duk_regconst_t is unsigned, so use 0 as dummy value (ignored by caller) */\n\t\tduk_pop(thr);\n\t\treturn 1;\n\t} else {\n\t\trc_varname = duk__getconst(comp_ctx);\n\t\t*out_reg_varbind = -1;\n\t\t*out_rc_varname = rc_varname;\n\t\treturn 0;\n\t}\n}\n\n/*\n *  Label handling\n *\n *  Labels are initially added with flags prohibiting both break and continue.\n *  When the statement type is finally uncovered (after potentially multiple\n *  labels), all the labels are updated to allow/prohibit break and continue.\n */\n\nDUK_LOCAL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_int_t pc_label, duk_int_t label_id) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_size_t n;\n\tduk_size_t new_size;\n\tduk_uint8_t *p;\n\tduk_labelinfo *li_start, *li;\n\n\t/* Duplicate (shadowing) labels are not allowed, except for the empty\n\t * labels (which are used as default labels for switch and iteration\n\t * statements).\n\t *\n\t * We could also allow shadowing of non-empty pending labels without any\n\t * other issues than breaking the required label shadowing requirements\n\t * of the E5 specification, see Section 12.12.\n\t */\n\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tli = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\tn = (duk_size_t) (li - li_start);\n\n\twhile (li > li_start) {\n\t\tli--;\n\n\t\tif (li->h_label == h_label && h_label != DUK_HTHREAD_STRING_EMPTY_STRING(thr)) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_DUPLICATE_LABEL);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t}\n\n\tduk_push_hstring(thr, h_label);\n\tDUK_ASSERT(n <= DUK_UARRIDX_MAX);  /* label limits */\n\t(void) duk_put_prop_index(thr, comp_ctx->curr_func.labelnames_idx, (duk_uarridx_t) n);\n\n\tnew_size = (n + 1) * sizeof(duk_labelinfo);\n\tduk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, new_size);\n\t/* XXX: slack handling, slow now */\n\n\t/* relookup after possible realloc */\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tDUK_UNREF(li_start);  /* silence scan-build warning */\n\tli = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\tli--;\n\n\t/* Labels can be used for iteration statements but also for other statements,\n\t * in particular a label can be used for a block statement.  All cases of a\n\t * named label accept a 'break' so that flag is set here.  Iteration statements\n\t * also allow 'continue', so that flag is updated when we figure out the\n\t * statement type.\n\t */\n\n\tli->flags = DUK_LABEL_FLAG_ALLOW_BREAK;\n\tli->label_id = label_id;\n\tli->h_label = h_label;\n\tli->catch_depth = comp_ctx->curr_func.catch_depth;   /* catch depth from current func */\n\tli->pc_label = pc_label;\n\n\tDUK_DDD(DUK_DDDPRINT(\"registered label: flags=0x%08lx, id=%ld, name=%!O, catch_depth=%ld, pc_label=%ld\",\n\t                     (unsigned long) li->flags, (long) li->label_id, (duk_heaphdr *) li->h_label,\n\t                     (long) li->catch_depth, (long) li->pc_label));\n}\n\n/* Update all labels with matching label_id. */\nDUK_LOCAL void duk__update_label_flags(duk_compiler_ctx *comp_ctx, duk_int_t label_id, duk_small_uint_t flags) {\n\tduk_uint8_t *p;\n\tduk_labelinfo *li_start, *li;\n\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(comp_ctx->thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tli = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\n\t/* Match labels starting from latest; once label_id no longer matches, we can\n\t * safely exit without checking the rest of the labels (only the topmost labels\n\t * are ever updated).\n\t */\n\twhile (li > li_start) {\n\t\tli--;\n\n\t\tif (li->label_id != label_id) {\n\t\t\tbreak;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"updating (overwriting) label flags for li=%p, label_id=%ld, flags=%ld\",\n\t\t                     (void *) li, (long) label_id, (long) flags));\n\n\t\tli->flags = flags;\n\t}\n}\n\n/* Lookup active label information.  Break/continue distinction is necessary to handle switch\n * statement related labels correctly: a switch will only catch a 'break', not a 'continue'.\n *\n * An explicit label cannot appear multiple times in the active set, but empty labels (unlabelled\n * iteration and switch statements) can.  A break will match the closest unlabelled or labelled\n * statement.  A continue will match the closest unlabelled or labelled iteration statement.  It is\n * a syntax error if a continue matches a labelled switch statement; because an explicit label cannot\n * be duplicated, the continue cannot match any valid label outside the switch.\n *\n * A side effect of these rules is that a LABEL statement related to a switch should never actually\n * catch a continue abrupt completion at run-time.  Hence an INVALID opcode can be placed in the\n * continue slot of the switch's LABEL statement.\n */\n\n/* XXX: awkward, especially the bunch of separate output values -> output struct? */\nDUK_LOCAL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_bool_t is_break, duk_int_t *out_label_id, duk_int_t *out_label_catch_depth, duk_int_t *out_label_pc, duk_bool_t *out_is_closest) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_uint8_t *p;\n\tduk_labelinfo *li_start, *li_end, *li;\n\tduk_bool_t match = 0;\n\n\tDUK_DDD(DUK_DDDPRINT(\"looking up active label: label='%!O', is_break=%ld\",\n\t                     (duk_heaphdr *) h_label, (long) is_break));\n\n\tDUK_UNREF(thr);\n\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tli_end = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\tli = li_end;\n\n\t/* Match labels starting from latest label because there can be duplicate empty\n\t * labels in the label set.\n\t */\n\twhile (li > li_start) {\n\t\tli--;\n\n\t\tif (li->h_label != h_label) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"labelinfo[%ld] ->'%!O' != %!O\",\n\t\t\t                     (long) (li - li_start),\n\t\t\t                     (duk_heaphdr *) li->h_label,\n\t\t\t                     (duk_heaphdr *) h_label));\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"labelinfo[%ld] -> '%!O' label name matches (still need to check type)\",\n\t\t                     (long) (li - li_start), (duk_heaphdr *) h_label));\n\n\t\t/* currently all labels accept a break, so no explicit check for it now */\n\t\tDUK_ASSERT(li->flags & DUK_LABEL_FLAG_ALLOW_BREAK);\n\n\t\tif (is_break) {\n\t\t\t/* break matches always */\n\t\t\tmatch = 1;\n\t\t\tbreak;\n\t\t} else if (li->flags & DUK_LABEL_FLAG_ALLOW_CONTINUE) {\n\t\t\t/* iteration statements allow continue */\n\t\t\tmatch = 1;\n\t\t\tbreak;\n\t\t} else {\n\t\t\t/* continue matched this label -- we can only continue if this is the empty\n\t\t\t * label, for which duplication is allowed, and thus there is hope of\n\t\t\t * finding a match deeper in the label stack.\n\t\t\t */\n\t\t\tif (h_label != DUK_HTHREAD_STRING_EMPTY_STRING(thr)) {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LABEL);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"continue matched an empty label which does not \"\n\t\t\t\t                     \"allow a continue -> continue lookup deeper in label stack\"));\n\t\t\t}\n\t\t}\n\t}\n\t/* XXX: match flag is awkward, rework */\n\tif (!match) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LABEL);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"label match: %!O -> label_id %ld, catch_depth=%ld, pc_label=%ld\",\n\t                     (duk_heaphdr *) h_label, (long) li->label_id,\n\t                     (long) li->catch_depth, (long) li->pc_label));\n\n\t*out_label_id = li->label_id;\n\t*out_label_catch_depth = li->catch_depth;\n\t*out_label_pc = li->pc_label;\n\t*out_is_closest = (li == li_end - 1);\n}\n\nDUK_LOCAL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, duk_size_t len) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\tduk_set_length(thr, comp_ctx->curr_func.labelnames_idx, len);\n\tduk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, sizeof(duk_labelinfo) * len);\n}\n\n/*\n *  Expression parsing: duk__expr_nud(), duk__expr_led(), duk__expr_lbp(), and helpers.\n *\n *  - duk__expr_nud(): (\"null denotation\"): process prev_token as a \"start\" of an expression (e.g. literal)\n *  - duk__expr_led(): (\"left denotation\"): process prev_token in the \"middle\" of an expression (e.g. operator)\n *  - duk__expr_lbp(): (\"left-binding power\"): return left-binding power of curr_token\n */\n\n/* object literal key tracking flags */\n#define DUK__OBJ_LIT_KEY_PLAIN  (1 << 0)  /* key encountered as a plain property */\n#define DUK__OBJ_LIT_KEY_GET    (1 << 1)  /* key encountered as a getter */\n#define DUK__OBJ_LIT_KEY_SET    (1 << 2)  /* key encountered as a setter */\n\nDUK_LOCAL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg_obj;                 /* result reg */\n\tduk_regconst_t reg_temp;                /* temp reg */\n\tduk_regconst_t temp_start;              /* temp reg value for start of loop */\n\tduk_small_uint_t max_init_values;  /* max # of values initialized in one MPUTARR set */\n\tduk_small_uint_t num_values;       /* number of values in current MPUTARR set */\n\tduk_uarridx_t curr_idx;            /* current (next) array index */\n\tduk_uarridx_t start_idx;           /* start array index of current MPUTARR set */\n\tduk_uarridx_t init_idx;            /* last array index explicitly initialized, +1 */\n\tduk_bool_t require_comma;          /* next loop requires a comma */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tduk_int_t pc_newarr;\n\tduk_compiler_instr *instr;\n#endif\n\n\t/* DUK_TOK_LBRACKET already eaten, current token is right after that */\n\tDUK_ASSERT(comp_ctx->prev_token.t == DUK_TOK_LBRACKET);\n\n\tmax_init_values = DUK__MAX_ARRAY_INIT_VALUES;  /* XXX: depend on available temps? */\n\n\treg_obj = DUK__ALLOCTEMP(comp_ctx);\n#if !defined(DUK_USE_PREFER_SIZE)\n\tpc_newarr = duk__get_current_pc(comp_ctx);\n#endif\n\tduk__emit_bc(comp_ctx, DUK_OP_NEWARR, reg_obj);  /* XXX: patch initial size hint afterwards? */\n\ttemp_start = DUK__GETTEMP(comp_ctx);\n\n\t/*\n\t *  Emit initializers in sets of maximum max_init_values.\n\t *  Corner cases such as single value initializers do not have\n\t *  special handling now.\n\t *\n\t *  Elided elements must not be emitted as 'undefined' values,\n\t *  because such values would be enumerable (which is incorrect).\n\t *  Also note that trailing elisions must be reflected in the\n\t *  length of the final array but cause no elements to be actually\n\t *  inserted.\n\t */\n\n\tcurr_idx = 0;\n\tinit_idx = 0;         /* tracks maximum initialized index + 1 */\n\tstart_idx = 0;\n\trequire_comma = 0;\n\n\tfor (;;) {\n\t\tnum_values = 0;\n\t\tDUK__SETTEMP(comp_ctx, temp_start);\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RBRACKET) {\n\t\t\tbreak;\n\t\t}\n\n\t\tfor (;;) {\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_RBRACKET) {\n\t\t\t\t/* the outer loop will recheck and exit */\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/* comma check */\n\t\t\tif (require_comma) {\n\t\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_COMMA) {\n\t\t\t\t\t/* comma after a value, expected */\n\t\t\t\t\tduk__advance(comp_ctx);\n\t\t\t\t\trequire_comma = 0;\n\t\t\t\t\tcontinue;\n\t\t\t\t} else {\n\t\t\t\t\tgoto syntax_error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_COMMA) {\n\t\t\t\t\t/* elision - flush */\n\t\t\t\t\tcurr_idx++;\n\t\t\t\t\tduk__advance(comp_ctx);\n\t\t\t\t\t/* if num_values > 0, MPUTARR emitted by outer loop after break */\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* else an array initializer element */\n\n\t\t\t/* initial index */\n\t\t\tif (num_values == 0) {\n\t\t\t\tstart_idx = curr_idx;\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_load_int32(comp_ctx, reg_temp, (duk_int32_t) start_idx);\n\t\t\t}\n\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);   /* alloc temp just in case, to update max temp */\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp);\n\t\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp /*forced_reg*/);\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\n\t\t\tnum_values++;\n\t\t\tcurr_idx++;\n\t\t\trequire_comma = 1;\n\n\t\t\tif (num_values >= max_init_values) {\n\t\t\t\t/* MPUTARR emitted by outer loop */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (num_values > 0) {\n\t\t\t/* - A is a source register (it's not a write target, but used\n\t\t\t *   to identify the target object) but can be shuffled.\n\t\t\t * - B cannot be shuffled normally because it identifies a range\n\t\t\t *   of registers, the emitter has special handling for this\n\t\t\t *   (the \"no shuffle\" flag must not be set).\n\t\t\t * - C is a non-register number and cannot be shuffled, but\n\t\t\t *   never needs to be.\n\t\t\t */\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_MPUTARR |\n\t\t\t                    DUK__EMIT_FLAG_NO_SHUFFLE_C |\n\t\t\t                    DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t                reg_obj,\n\t\t\t                temp_start,\n\t\t\t                (duk_regconst_t) (num_values + 1));\n\t\t\tinit_idx = start_idx + num_values;\n\n\t\t\t/* num_values and temp_start reset at top of outer loop */\n\t\t}\n\t}\n\n\t/* Update initil size for NEWARR, doesn't need to be exact and is\n\t * capped at A field limit.\n\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tinstr = duk__get_instr_ptr(comp_ctx, pc_newarr);\n\tinstr->ins |= DUK_ENC_OP_A(0, curr_idx > DUK_BC_A_MAX ? DUK_BC_A_MAX : curr_idx);\n#endif\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RBRACKET);\n\tduk__advance(comp_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"array literal done, curridx=%ld, initidx=%ld\",\n\t                     (long) curr_idx, (long) init_idx));\n\n\t/* trailing elisions? */\n\tif (curr_idx > init_idx) {\n\t\t/* yes, must set array length explicitly */\n\t\tDUK_DDD(DUK_DDDPRINT(\"array literal has trailing elisions which affect its length\"));\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk__emit_load_int32(comp_ctx, reg_temp, (duk_int_t) curr_idx);\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               DUK_OP_SETALEN | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t               reg_obj,\n\t\t               reg_temp);\n\t}\n\n\tDUK__SETTEMP(comp_ctx, temp_start);\n\n\tduk__ivalue_regconst(res, reg_obj);\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_ARRAY_LITERAL);\n\tDUK_WO_NORETURN(return;);\n}\n\ntypedef struct {\n\tduk_regconst_t reg_obj;\n\tduk_regconst_t temp_start;\n\tduk_small_uint_t num_pairs;\n\tduk_small_uint_t num_total_pairs;\n} duk__objlit_state;\n\nDUK_LOCAL void duk__objlit_flush_keys(duk_compiler_ctx *comp_ctx, duk__objlit_state *st) {\n\tif (st->num_pairs > 0) {\n\t\t/* - A is a source register (it's not a write target, but used\n\t\t *   to identify the target object) but can be shuffled.\n\t\t * - B cannot be shuffled normally because it identifies a range\n\t\t *   of registers, the emitter has special handling for this\n\t\t *   (the \"no shuffle\" flag must not be set).\n\t\t * - C is a non-register number and cannot be shuffled, but\n\t\t *   never needs to be.\n\t\t */\n\t\tDUK_ASSERT(st->num_pairs > 0);\n\t\tduk__emit_a_b_c(comp_ctx,\n\t\t                DUK_OP_MPUTOBJ |\n\t\t                    DUK__EMIT_FLAG_NO_SHUFFLE_C |\n\t\t                    DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t                st->reg_obj,\n\t\t                st->temp_start,\n\t\t                (duk_regconst_t) (st->num_pairs * 2));\n\t\tst->num_total_pairs += st->num_pairs;\n\t\tst->num_pairs = 0;\n\t}\n\tDUK__SETTEMP(comp_ctx, st->temp_start);\n}\n\nDUK_LOCAL duk_bool_t duk__objlit_load_key(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_token *tok, duk_regconst_t reg_temp) {\n\tif (tok->t_nores == DUK_TOK_IDENTIFIER || tok->t_nores == DUK_TOK_STRING) {\n\t\t/* same handling for identifiers and strings */\n\t\tDUK_ASSERT(tok->str1 != NULL);\n\t\tduk_push_hstring(comp_ctx->thr, tok->str1);\n\t} else if (tok->t == DUK_TOK_NUMBER) {\n\t\t/* numbers can be loaded as numbers and coerced on the fly */\n\t\tduk_push_number(comp_ctx->thr, tok->num);\n\t} else {\n\t\treturn 1;  /* error */\n\t}\n\n\tduk__ivalue_plain_fromstack(comp_ctx, res);\n\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\tduk__ivalue_toforcedreg(comp_ctx, res, reg_temp);\n\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\treturn 0;\n}\n\nDUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk__objlit_state st;\n\tduk_regconst_t reg_temp;          /* temp reg */\n\tduk_small_uint_t max_init_pairs;  /* max # of key-value pairs initialized in one MPUTOBJ set */\n\tduk_bool_t first;                 /* first value: comma must not precede the value */\n\tduk_bool_t is_set, is_get;        /* temps */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tduk_int_t pc_newobj;\n\tduk_compiler_instr *instr;\n#endif\n\n\tDUK_ASSERT(comp_ctx->prev_token.t == DUK_TOK_LCURLY);\n\n\tmax_init_pairs = DUK__MAX_OBJECT_INIT_PAIRS;  /* XXX: depend on available temps? */\n\n\tst.reg_obj = DUK__ALLOCTEMP(comp_ctx);    /* target object */\n\tst.temp_start = DUK__GETTEMP(comp_ctx);   /* start of MPUTOBJ argument list */\n\tst.num_pairs = 0;                         /* number of key/value pairs emitted for current MPUTOBJ set */\n\tst.num_total_pairs = 0;                   /* number of key/value pairs emitted overall */\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\tpc_newobj = duk__get_current_pc(comp_ctx);\n#endif\n\tduk__emit_bc(comp_ctx, DUK_OP_NEWOBJ, st.reg_obj);\n\n\t/*\n\t *  Emit initializers in sets of maximum max_init_pairs keys.\n\t *  Setter/getter is handled separately and terminates the\n\t *  current set of initializer values.  Corner cases such as\n\t *  single value initializers do not have special handling now.\n\t */\n\n\tfirst = 1;\n\tfor (;;) {\n\t\t/*\n\t\t *  ES5 and ES2015+ provide a lot of different PropertyDefinition\n\t\t *  formats, see http://www.ecma-international.org/ecma-262/6.0/#sec-object-initializer.\n\t\t *\n\t\t *  PropertyName can be IdentifierName (includes reserved words), a string\n\t\t *  literal, or a number literal.  Note that IdentifierName allows 'get' and\n\t\t *  'set' too, so we need to look ahead to the next token to distinguish:\n\t\t *\n\t\t *     { get : 1 }\n\t\t *\n\t\t *  and\n\t\t *\n\t\t *     { get foo() { return 1 } }\n\t\t *     { get get() { return 1 } }    // 'get' as getter propertyname\n\t\t *\n\t\t *  Finally, a trailing comma is allowed.\n\t\t *\n\t\t *  Key name is coerced to string at compile time (and ends up as a\n\t\t *  a string constant) even for numeric keys (e.g. \"{1:'foo'}\").\n\t\t *  These could be emitted using e.g. LDINT, but that seems hardly\n\t\t *  worth the effort and would increase code size.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"object literal loop, curr_token->t = %ld\",\n\t\t                     (long) comp_ctx->curr_token.t));\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (first) {\n\t\t\tfirst = 0;\n\t\t} else {\n\t\t\tif (comp_ctx->curr_token.t != DUK_TOK_COMMA) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t\tduk__advance(comp_ctx);\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\t\t/* trailing comma followed by rcurly */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* Advance to get one step of lookup. */\n\t\tduk__advance(comp_ctx);\n\n\t\t/* Flush current MPUTOBJ if enough many pairs gathered. */\n\t\tif (st.num_pairs >= max_init_pairs) {\n\t\t\tduk__objlit_flush_keys(comp_ctx, &st);\n\t\t\tDUK_ASSERT(st.num_pairs == 0);\n\t\t}\n\n\t\t/* Reset temp register state and reserve reg_temp and\n\t\t * reg_temp + 1 for handling the current property.\n\t\t */\n\t\tDUK__SETTEMP(comp_ctx, st.temp_start + 2 * (duk_regconst_t) st.num_pairs);\n\t\treg_temp = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\t\t/* NOTE: \"get\" and \"set\" are not officially ReservedWords and the lexer\n\t\t * currently treats them always like ordinary identifiers (DUK_TOK_GET\n\t\t * and DUK_TOK_SET are unused).  They need to be detected based on the\n\t\t * identifier string content.\n\t\t */\n\n\t\tis_get = (comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t          comp_ctx->prev_token.str1 == DUK_HTHREAD_STRING_GET(thr));\n\t\tis_set = (comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t          comp_ctx->prev_token.str1 == DUK_HTHREAD_STRING_SET(thr));\n\t\tif ((is_get || is_set) && comp_ctx->curr_token.t != DUK_TOK_COLON) {\n\t\t\t/* getter/setter */\n\t\t\tduk_int_t fnum;\n\n\t\t\tduk__objlit_flush_keys(comp_ctx, &st);\n\t\t\tDUK_ASSERT(DUK__GETTEMP(comp_ctx) == st.temp_start);  /* 2 regs are guaranteed to be allocated w.r.t. temp_max */\n\t\t\treg_temp = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\t\t\tif (duk__objlit_load_key(comp_ctx, res, &comp_ctx->curr_token, reg_temp) != 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\t/* curr_token = get/set name */\n\t\t\tfnum = duk__parse_func_like_fnum(comp_ctx, DUK__FUNC_FLAG_GETSET);\n\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CLOSURE,\n\t\t\t               st.temp_start + 1,\n\t\t\t               (duk_regconst_t) fnum);\n\n\t\t\t/* Slot C is used in a non-standard fashion (range of regs),\n\t\t\t * emitter code has special handling for it (must not set the\n\t\t\t * \"no shuffle\" flag).\n\t\t\t */\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t              (is_get ? DUK_OP_INITGET : DUK_OP_INITSET) | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t              st.reg_obj,\n\t\t\t              st.temp_start);   /* temp_start+0 = key, temp_start+1 = closure */\n\n\t\t\tDUK_ASSERT(st.num_pairs == 0);  /* temp state is reset on next loop */\n#if defined(DUK_USE_ES6)\n\t\t} else if (comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t           (comp_ctx->curr_token.t == DUK_TOK_COMMA || comp_ctx->curr_token.t == DUK_TOK_RCURLY)) {\n\t\t\tduk_bool_t load_rc;\n\n\t\t\tload_rc = duk__objlit_load_key(comp_ctx, res, &comp_ctx->prev_token, reg_temp);\n\t\t\tDUK_UNREF(load_rc);\n\t\t\tDUK_ASSERT(load_rc == 0);  /* always succeeds because token is identifier */\n\n\t\t\tduk__ivalue_var_hstring(comp_ctx, res, comp_ctx->prev_token.str1);\n\t\t\tDUK_ASSERT(DUK__GETTEMP(comp_ctx) == reg_temp + 1);\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_temp + 1);\n\n\t\t\tst.num_pairs++;\n\t\t} else if ((comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER ||\n\t\t            comp_ctx->prev_token.t == DUK_TOK_STRING ||\n\t\t            comp_ctx->prev_token.t == DUK_TOK_NUMBER) &&\n\t\t           comp_ctx->curr_token.t == DUK_TOK_LPAREN) {\n\t\t\tduk_int_t fnum;\n\n\t\t\t/* Parsing-wise there's a small hickup here: the token parsing\n\t\t\t * state is one step too advanced for the function parse helper\n\t\t\t * compared to other cases.  The current solution is an extra\n\t\t\t * flag to indicate whether function parsing should use the\n\t\t\t * current or the previous token to starting parsing from.\n\t\t\t */\n\n\t\t\tif (duk__objlit_load_key(comp_ctx, res, &comp_ctx->prev_token, reg_temp) != 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\tfnum = duk__parse_func_like_fnum(comp_ctx, DUK__FUNC_FLAG_USE_PREVTOKEN | DUK__FUNC_FLAG_METDEF);\n\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CLOSURE,\n\t\t\t               reg_temp + 1,\n\t\t\t               (duk_regconst_t) fnum);\n\n\t\t\tst.num_pairs++;\n#endif  /* DUK_USE_ES6 */\n\t\t} else {\n#if defined(DUK_USE_ES6)\n\t\t\tif (comp_ctx->prev_token.t == DUK_TOK_LBRACKET) {\n\t\t\t\t/* ES2015 computed property name.  Executor ToPropertyKey()\n\t\t\t\t * coerces the key at runtime.\n\t\t\t\t */\n\t\t\t\tDUK__SETTEMP(comp_ctx, reg_temp);\n\t\t\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_FOR_EXPR, reg_temp);\n\t\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_RBRACKET);\n\n\t\t\t\t/* XXX: If next token is '(' we're dealing with\n\t\t\t\t * the method shorthand with a computed name,\n\t\t\t\t * e.g. { [Symbol.for('foo')](a,b) {} }.  This\n\t\t\t\t * form is not yet supported and causes a\n\t\t\t\t * SyntaxError on the DUK_TOK_COLON check below.\n\t\t\t\t */\n\t\t\t}\n\t\t\telse\n#endif  /* DUK_USE_ES6 */\n\t\t\t{\n\t\t\t\tif (duk__objlit_load_key(comp_ctx, res, &comp_ctx->prev_token, reg_temp) != 0) {\n\t\t\t\t\tgoto syntax_error;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\t\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp + 1 /*forced_reg*/);\n\n\t\t\tst.num_pairs++;\n\t\t}\n\t}  /* property loop */\n\n\t/* Flush remaining properties. */\n\tduk__objlit_flush_keys(comp_ctx, &st);\n\tDUK_ASSERT(st.num_pairs == 0);\n\tDUK_ASSERT(DUK__GETTEMP(comp_ctx) == st.temp_start);\n\n\t/* Update initial size for NEWOBJ.  The init size doesn't need to be\n\t * exact as the purpose is just to avoid object resizes in common\n\t * cases.  The size is capped to field A limit, and will be too high\n\t * if the object literal contains duplicate keys (this is harmless but\n\t * increases memory traffic if the object is compacted later on).\n\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tinstr = duk__get_instr_ptr(comp_ctx, pc_newobj);\n\tinstr->ins |= DUK_ENC_OP_A(0, st.num_total_pairs > DUK_BC_A_MAX ? DUK_BC_A_MAX : st.num_total_pairs);\n#endif\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RCURLY);\n\tduk__advance(comp_ctx);  /* No RegExp after object literal. */\n\n\tduk__ivalue_regconst(res, st.reg_obj);\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_OBJECT_LITERAL);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Parse argument list.  Arguments are written to temps starting from\n * \"next temp\".  Returns number of arguments parsed.  Expects left paren\n * to be already eaten, and eats the right paren before returning.\n */\nDUK_LOCAL duk_int_t duk__parse_arguments(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_int_t nargs = 0;\n\tduk_regconst_t reg_temp;\n\n\t/* Note: expect that caller has already eaten the left paren */\n\n\tDUK_DDD(DUK_DDDPRINT(\"start parsing arguments, prev_token.t=%ld, curr_token.t=%ld\",\n\t                     (long) comp_ctx->prev_token.t, (long) comp_ctx->curr_token.t));\n\n\tfor (;;) {\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RPAREN) {\n\t\t\tbreak;\n\t\t}\n\t\tif (nargs > 0) {\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COMMA);\n\t\t}\n\n\t\t/* We want the argument expression value to go to \"next temp\"\n\t\t * without additional moves.  That should almost always be the\n\t\t * case, but we double check after expression parsing.\n\t\t *\n\t\t * This is not the cleanest possible approach.\n\t\t */\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);  /* bump up \"allocated\" reg count, just in case */\n\t\tDUK__SETTEMP(comp_ctx, reg_temp);\n\n\t\t/* binding power must be high enough to NOT allow comma expressions directly */\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp);  /* always allow 'in', coerce to 'tr' just in case */\n\n\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\t\tnargs++;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"argument #%ld written into reg %ld\", (long) nargs, (long) reg_temp));\n\t}\n\n\t/* eat the right paren */\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* RegExp mode does not matter. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing arguments\"));\n\n\treturn nargs;\n}\n\nDUK_LOCAL duk_bool_t duk__expr_is_empty(duk_compiler_ctx *comp_ctx) {\n\t/* empty expressions can be detected conveniently with nud/led counts */\n\treturn (comp_ctx->curr_func.nud_count == 0) &&\n\t       (comp_ctx->curr_func.led_count == 0);\n}\n\nDUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_token *tk;\n\tduk_regconst_t temp_at_entry;\n\tduk_small_uint_t tok;\n\tduk_uint32_t args;  /* temp variable to pass constants and flags to shared code */\n\n\t/*\n\t *  ctx->prev_token     token to process with duk__expr_nud()\n\t *  ctx->curr_token     updated by caller\n\t *\n\t *  Note: the token in the switch below has already been eaten.\n\t */\n\n\ttemp_at_entry = DUK__GETTEMP(comp_ctx);\n\n\tcomp_ctx->curr_func.nud_count++;\n\n\ttk = &comp_ctx->prev_token;\n\ttok = tk->t;\n\tres->t = DUK_IVAL_NONE;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__expr_nud(), prev_token.t=%ld, allow_in=%ld, paren_level=%ld\",\n\t                     (long) tk->t, (long) comp_ctx->curr_func.allow_in, (long) comp_ctx->curr_func.paren_level));\n\n\tswitch (tok) {\n\n\t/* PRIMARY EXPRESSIONS */\n\n\tcase DUK_TOK_THIS: {\n\t\tduk_regconst_t reg_temp;\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk__emit_bc(comp_ctx,\n\t\t             DUK_OP_LDTHIS,\n\t\t             reg_temp);\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\tcase DUK_TOK_IDENTIFIER: {\n\t\tduk__ivalue_var_hstring(comp_ctx, res, tk->str1);\n\t\treturn;\n\t}\n\tcase DUK_TOK_NULL: {\n\t\tduk_push_null(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_TRUE: {\n\t\tduk_push_true(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_FALSE: {\n\t\tduk_push_false(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_NUMBER: {\n\t\tduk_push_number(thr, tk->num);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_STRING: {\n\t\tDUK_ASSERT(tk->str1 != NULL);\n\t\tduk_push_hstring(thr, tk->str1);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_REGEXP: {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tduk_regconst_t reg_temp;\n\t\tduk_regconst_t rc_re_bytecode;  /* const */\n\t\tduk_regconst_t rc_re_source;    /* const */\n\n\t\tDUK_ASSERT(tk->str1 != NULL);\n\t\tDUK_ASSERT(tk->str2 != NULL);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"emitting regexp op, str1=%!O, str2=%!O\",\n\t\t                     (duk_heaphdr *) tk->str1,\n\t\t                     (duk_heaphdr *) tk->str2));\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk_push_hstring(thr, tk->str1);\n\t\tduk_push_hstring(thr, tk->str2);\n\n\t\t/* [ ... pattern flags ] */\n\n\t\tduk_regexp_compile(thr);\n\n\t\t/* [ ... escaped_source bytecode ] */\n\n\t\trc_re_bytecode = duk__getconst(comp_ctx);\n\t\trc_re_source = duk__getconst(comp_ctx);\n\n\t\tduk__emit_a_b_c(comp_ctx,\n\t\t                DUK_OP_REGEXP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t                reg_temp /*a*/,\n\t\t                rc_re_bytecode /*b*/,\n\t\t                rc_re_source /*c*/);\n\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\tgoto syntax_error;\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t}\n\tcase DUK_TOK_LBRACKET: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsing array literal\"));\n\t\tduk__nud_array_literal(comp_ctx, res);\n\t\treturn;\n\t}\n\tcase DUK_TOK_LCURLY: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsing object literal\"));\n\t\tduk__nud_object_literal(comp_ctx, res);\n\t\treturn;\n\t}\n\tcase DUK_TOK_LPAREN: {\n\t\tduk_bool_t prev_allow_in;\n\n\t\tcomp_ctx->curr_func.paren_level++;\n\t\tprev_allow_in = comp_ctx->curr_func.allow_in;\n\t\tcomp_ctx->curr_func.allow_in = 1; /* reset 'allow_in' for parenthesized expression */\n\n\t\tduk__expr(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);  /* Expression, terminates at a ')' */\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* No RegExp after parenthesized expression. */\n\t\tcomp_ctx->curr_func.allow_in = prev_allow_in;\n\t\tcomp_ctx->curr_func.paren_level--;\n\t\treturn;\n\t}\n\n\t/* MEMBER/NEW/CALL EXPRESSIONS */\n\n\tcase DUK_TOK_NEW: {\n\t\t/*\n\t\t *  Parsing an expression starting with 'new' is tricky because\n\t\t *  there are multiple possible productions deriving from\n\t\t *  LeftHandSideExpression which begin with 'new'.\n\t\t *\n\t\t *  We currently resort to one-token lookahead to distinguish the\n\t\t *  cases.  Hopefully this is correct.  The binding power must be\n\t\t *  such that parsing ends at an LPAREN (CallExpression) but not at\n\t\t *  a PERIOD or LBRACKET (MemberExpression).\n\t\t *\n\t\t *  See doc/compiler.rst for discussion on the parsing approach,\n\t\t *  and testcases/test-dev-new.js for a bunch of documented tests.\n\t\t */\n\n\t\tduk_regconst_t reg_target;\n\t\tduk_int_t nargs;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"begin parsing new expression\"));\n\n\t\treg_target = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n#if defined(DUK_USE_ES6)\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_PERIOD) {\n\t\t\t/* new.target */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new.target\"));\n\t\t\tduk__advance(comp_ctx);\n\t\t\tif (comp_ctx->curr_token.t_nores != DUK_TOK_IDENTIFIER ||\n\t\t\t    !duk_hstring_equals_ascii_cstring(comp_ctx->curr_token.str1, \"target\")) {\n\t\t\t\tgoto syntax_error_newtarget;\n\t\t\t}\n\t\t\tif (comp_ctx->curr_func.is_global) {\n\t\t\t\tgoto syntax_error_newtarget;\n\t\t\t}\n\t\t\tduk__advance(comp_ctx);\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_NEWTARGET,\n\t\t\t             reg_target);\n\t\t\tduk__ivalue_regconst(res, reg_target);\n\t\t\treturn;\n\t\t}\n#endif  /* DUK_USE_ES6 */\n\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_CALL /*rbp_flags*/, reg_target /*forced_reg*/);\n\t\tduk__emit_bc(comp_ctx, DUK_OP_NEWOBJ, reg_target + 1);  /* default instance */\n\t\tDUK__SETTEMP(comp_ctx, reg_target + 2);\n\n\t\t/* XXX: 'new obj.noSuch()' doesn't use GETPROPC now which\n\t\t * makes the error message worse than for obj.noSuch().\n\t\t */\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_LPAREN) {\n\t\t\t/* 'new' MemberExpression Arguments */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new expression has argument list\"));\n\t\t\tduk__advance(comp_ctx);\n\t\t\tnargs = duk__parse_arguments(comp_ctx, res);  /* parse args starting from \"next temp\", reg_target + 1 */\n\t\t\t/* right paren eaten */\n\t\t} else {\n\t\t\t/* 'new' MemberExpression */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new expression has no argument list\"));\n\t\t\tnargs = 0;\n\t\t}\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t              DUK_OP_CALL0 | DUK_BC_CALL_FLAG_CONSTRUCT,\n\t\t              nargs /*num_args*/,\n\t\t              reg_target /*target*/);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"end parsing new expression\"));\n\n\t\tduk__ivalue_regconst(res, reg_target);\n\t\treturn;\n\t}\n\n\t/* FUNCTION EXPRESSIONS */\n\n\tcase DUK_TOK_FUNCTION: {\n\t\t/* Function expression.  Note that any statement beginning with 'function'\n\t\t * is handled by the statement parser as a function declaration, or a\n\t\t * non-standard function expression/statement (or a SyntaxError).  We only\n\t\t * handle actual function expressions (occurring inside an expression) here.\n\t\t *\n\t\t * O(depth^2) parse count for inner functions is handled by recording a\n\t\t * lexer offset on the first compilation pass, so that the function can\n\t\t * be efficiently skipped on the second pass.  This is encapsulated into\n\t\t * duk__parse_func_like_fnum().\n\t\t */\n\n\t\tduk_regconst_t reg_temp;\n\t\tduk_int_t fnum;\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t/* curr_token follows 'function' */\n\t\tfnum = duk__parse_func_like_fnum(comp_ctx, 0 /*flags*/);\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsed inner function -> fnum %ld\", (long) fnum));\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               DUK_OP_CLOSURE,\n\t\t               reg_temp /*a*/,\n\t\t               (duk_regconst_t) fnum /*bc*/);\n\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\n\t/* UNARY EXPRESSIONS */\n\n\tcase DUK_TOK_DELETE: {\n\t\t/* Delete semantics are a bit tricky.  The description in E5 specification\n\t\t * is kind of confusing, because it distinguishes between resolvability of\n\t\t * a reference (which is only known at runtime) seemingly at compile time\n\t\t * (= SyntaxError throwing).\n\t\t */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\t/* not allowed in strict mode, regardless of whether resolves;\n\t\t\t * in non-strict mode DELVAR handles both non-resolving and\n\t\t\t * resolving cases (the specification description is a bit confusing).\n\t\t\t */\n\n\t\t\tduk_regconst_t reg_temp;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\tif (comp_ctx->curr_func.is_strict) {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_CANNOT_DELETE_IDENTIFIER);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\n\t\t\tDUK__SETTEMP(comp_ctx, temp_at_entry);\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\t/* register bound variables are non-configurable -> always false */\n\t\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t\t             DUK_OP_LDFALSE,\n\t\t\t\t             reg_temp);\n\t\t\t} else {\n\t\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\t\trc_varname = duk__getconst(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_DELVAR,\n\t\t\t\t               reg_temp,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\t\t\tduk__ivalue_regconst(res, reg_temp);\n\t\t} else if (res->t == DUK_IVAL_PROP) {\n\t\t\tduk_regconst_t reg_temp;\n\t\t\tduk_regconst_t reg_obj;\n\t\t\tduk_regconst_t rc_key;\n\n\t\t\tDUK__SETTEMP(comp_ctx, temp_at_entry);\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_DELPROP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_temp,\n\t\t\t                reg_obj,\n\t\t\t                rc_key);\n\n\t\t\tduk__ivalue_regconst(res, reg_temp);\n\t\t} else {\n\t\t\t/* non-Reference deletion is always 'true', even in strict mode */\n\t\t\tduk_push_true(thr);\n\t\t\tgoto plain_value;\n\t\t}\n\t\treturn;\n\t}\n\tcase DUK_TOK_VOID: {\n\t\tduk__expr_toplain_ignore(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tduk_push_undefined(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_TYPEOF: {\n\t\t/* 'typeof' must handle unresolvable references without throwing\n\t\t * a ReferenceError (E5 Section 11.4.3).  Register mapped values\n\t\t * will never be unresolvable so special handling is only required\n\t\t * when an identifier is a \"slow path\" one.\n\t\t */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\n\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\t\t\tduk_regconst_t reg_temp;\n\n\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\tif (!duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"typeof for an identifier name which could not be resolved \"\n\t\t\t\t                     \"at compile time, need to use special run-time handling\"));\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_TYPEOFID,\n\t\t\t\t               reg_temp,\n\t\t\t\t               rc_varname);\n\t\t\t\tduk__ivalue_regconst(res, reg_temp);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\targs = DUK_OP_TYPEOF;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_INCREMENT: {\n\t\targs = (DUK_OP_PREINCP << 8) + DUK_OP_PREINCR;\n\t\tgoto preincdec;\n\t}\n\tcase DUK_TOK_DECREMENT: {\n\t\targs = (DUK_OP_PREDECP << 8) + DUK_OP_PREDECR;\n\t\tgoto preincdec;\n\t}\n\tcase DUK_TOK_ADD: {\n\t\t/* unary plus */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE &&\n\t\t    duk_is_number(thr, res->x1.valstack_idx)) {\n\t\t\t/* unary plus of a number is identity */\n\t\t\treturn;\n\t\t}\n\t\targs = DUK_OP_UNP;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_SUB: {\n\t\t/* unary minus */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE &&\n\t\t    duk_is_number(thr, res->x1.valstack_idx)) {\n\t\t\t/* this optimization is important to handle negative literals\n\t\t\t * (which are not directly provided by the lexical grammar)\n\t\t\t */\n\t\t\tduk_tval *tv_num;\n\t\t\tduk_double_union du;\n\n\t\t\ttv_num = DUK_GET_TVAL_POSIDX(thr, res->x1.valstack_idx);\n\t\t\tDUK_ASSERT(tv_num != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_num));\n\t\t\tdu.d = DUK_TVAL_GET_NUMBER(tv_num);\n\t\t\tdu.d = -du.d;\n\t\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\t\t\tDUK_TVAL_SET_NUMBER(tv_num, du.d);\n\t\t\treturn;\n\t\t}\n\t\targs = DUK_OP_UNM;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_BNOT: {\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\targs = DUK_OP_BNOT;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_LNOT: {\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE) {\n\t\t\t/* Very minimal inlining to handle common idioms '!0' and '!1',\n\t\t\t * and also boolean arguments like '!false' and '!true'.\n\t\t\t */\n\t\t\tduk_tval *tv_val;\n\n\t\t\ttv_val = DUK_GET_TVAL_POSIDX(thr, res->x1.valstack_idx);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tif (DUK_TVAL_IS_NUMBER(tv_val)) {\n\t\t\t\tduk_double_t d;\n\t\t\t\td = DUK_TVAL_GET_NUMBER(tv_val);\n\t\t\t\tif (d == 0.0) {\n\t\t\t\t\t/* Matches both +0 and -0 on purpose. */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"inlined lnot: !0 -> true\"));\n\t\t\t\t\tDUK_TVAL_SET_BOOLEAN_TRUE(tv_val);\n\t\t\t\t\treturn;\n\t\t\t\t} else if (d == 1.0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"inlined lnot: !1 -> false\"));\n\t\t\t\t\tDUK_TVAL_SET_BOOLEAN_FALSE(tv_val);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else if (DUK_TVAL_IS_BOOLEAN(tv_val)) {\n\t\t\t\tduk_small_uint_t v;\n\t\t\t\tv = DUK_TVAL_GET_BOOLEAN(tv_val);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"inlined lnot boolean: %ld\", (long) v));\n\t\t\t\tDUK_ASSERT(v == 0 || v == 1);\n\t\t\t\tDUK_TVAL_SET_BOOLEAN(tv_val, v ^ 0x01);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\targs = DUK_OP_LNOT;\n\t\tgoto unary;\n\t}\n\n\t}  /* end switch */\n\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);\n\tDUK_WO_NORETURN(return;);\n\n unary:\n\t{\n\t\t/* Unary opcodes use just the 'BC' register source because it\n\t\t * matches current shuffle limits, and maps cleanly to 16 high\n\t\t * bits of the opcode.\n\t\t */\n\n\t\tduk_regconst_t reg_src, reg_res;\n\n\t\treg_src = duk__ivalue_toregconst_raw(comp_ctx, res, -1 /*forced_reg*/, 0 /*flags*/);\n\t\tif (DUK__ISREG_TEMP(comp_ctx, reg_src)) {\n\t\t\treg_res = reg_src;\n\t\t} else {\n\t\t\treg_res = DUK__ALLOCTEMP(comp_ctx);\n\t\t}\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t             args,\n\t\t             reg_res,\n\t\t             reg_src);\n\t\tduk__ivalue_regconst(res, reg_res);\n\t\treturn;\n\t}\n\n preincdec:\n\t{\n\t\t/* preincrement and predecrement */\n\t\tduk_regconst_t reg_res;\n\t\tduk_small_uint_t args_op1 = args & 0xff;  /* DUK_OP_PREINCR/DUK_OP_PREDECR */\n\t\tduk_small_uint_t args_op2 = args >> 8;    /* DUK_OP_PREINCP_RR/DUK_OP_PREDECP_RR */\n\n\t\t/* Specific assumptions for opcode numbering. */\n\t\tDUK_ASSERT(DUK_OP_PREINCR + 4 == DUK_OP_PREINCV);\n\t\tDUK_ASSERT(DUK_OP_PREDECR + 4 == DUK_OP_PREDECV);\n\n\t\treg_res = DUK__ALLOCTEMP(comp_ctx);\n\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\th_varname = duk_known_hstring(thr, res->x1.valstack_idx);\n\n\t\t\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               args_op1,  /* e.g. DUK_OP_PREINCR */\n\t\t\t\t               reg_res,\n\t\t\t\t               reg_varbind);\n\t\t\t} else {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t                args_op1 + 4,  /* e.g. DUK_OP_PREINCV */\n\t\t\t\t                reg_res,\n\t\t\t\t                rc_varname);\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"preincdec to '%!O' -> reg_varbind=%ld, rc_varname=%ld\",\n\t\t\t                     (duk_heaphdr *) h_varname, (long) reg_varbind, (long) rc_varname));\n\t\t} else if (res->t == DUK_IVAL_PROP) {\n\t\t\tduk_regconst_t reg_obj;  /* allocate to reg only (not const) */\n\t\t\tduk_regconst_t rc_key;\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                args_op2 | DUK__EMIT_FLAG_BC_REGCONST,  /* e.g. DUK_OP_PREINCP */\n\t\t\t                reg_res,\n\t\t\t                reg_obj,\n\t\t\t                rc_key);\n\t\t} else {\n\t\t\t/* Technically return value is not needed because INVLHS will\n\t\t\t * unconditially throw a ReferenceError.  Coercion is necessary\n\t\t\t * for proper semantics (consider ToNumber() called for an object).\n\t\t\t * Use DUK_OP_UNP with a dummy register to get ToNumber().\n\t\t\t */\n\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_res);\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_UNP,\n\t\t\t             reg_res);  /* for side effects, result ignored */\n\t\t\tduk__emit_op_only(comp_ctx,\n\t\t\t                  DUK_OP_INVLHS);\n\t\t}\n\t\tDUK__SETTEMP(comp_ctx, reg_res + 1);\n\t\tduk__ivalue_regconst(res, reg_res);\n\t\treturn;\n\t}\n\n plain_value:\n\t{\n\t\t/* Stack top contains plain value */\n\t\tduk__ivalue_plain_fromstack(comp_ctx, res);\n\t\treturn;\n\t}\n\n#if defined(DUK_USE_ES6)\n syntax_error_newtarget:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_NEWTARGET);\n\tDUK_WO_NORETURN(return;);\n#endif\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_EXPRESSION);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* XXX: add flag to indicate whether caller cares about return value; this\n * affects e.g. handling of assignment expressions.  This change needs API\n * changes elsewhere too.\n */\nDUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_token *tk;\n\tduk_small_uint_t tok;\n\tduk_uint32_t args;  /* temp variable to pass constants and flags to shared code */\n\n\t/*\n\t *  ctx->prev_token     token to process with duk__expr_led()\n\t *  ctx->curr_token     updated by caller\n\t */\n\n\tcomp_ctx->curr_func.led_count++;\n\n\t/* The token in the switch has already been eaten here */\n\ttk = &comp_ctx->prev_token;\n\ttok = tk->t;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__expr_led(), prev_token.t=%ld, allow_in=%ld, paren_level=%ld\",\n\t                     (long) tk->t, (long) comp_ctx->curr_func.allow_in, (long) comp_ctx->curr_func.paren_level));\n\n\t/* XXX: default priority for infix operators is duk__expr_lbp(tok) -> get it here? */\n\n\tswitch (tok) {\n\n\t/* PRIMARY EXPRESSIONS */\n\n\tcase DUK_TOK_PERIOD: {\n\t\t/* Property access expressions are critical for correct LHS ordering,\n\t\t * see comments in duk__expr()!\n\t\t *\n\t\t * A conservative approach would be to use duk__ivalue_totempconst()\n\t\t * for 'left'.  However, allowing a reg-bound variable seems safe here\n\t\t * and is nice because \"foo.bar\" is a common expression.  If the ivalue\n\t\t * is used in an expression a GETPROP will occur before any changes to\n\t\t * the base value can occur.  If the ivalue is used as an assignment\n\t\t * LHS, the assignment code will ensure the base value is safe from\n\t\t * RHS mutation.\n\t\t */\n\n\t\t/* XXX: This now coerces an identifier into a GETVAR to a temp, which\n\t\t * causes an extra LDREG in call setup.  It's sufficient to coerce to a\n\t\t * unary ivalue?\n\t\t */\n\t\tduk__ivalue_toplain(comp_ctx, left);\n\n\t\t/* NB: must accept reserved words as property name */\n\t\tif (comp_ctx->curr_token.t_nores != DUK_TOK_IDENTIFIER) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EXPECTED_IDENTIFIER);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\n\t\tres->t = DUK_IVAL_PROP;\n\t\tduk__copy_ispec(comp_ctx, &left->x1, &res->x1);  /* left.x1 -> res.x1 */\n\t\tDUK_ASSERT(comp_ctx->curr_token.str1 != NULL);\n\t\tduk_push_hstring(thr, comp_ctx->curr_token.str1);\n\t\tduk_replace(thr, res->x2.valstack_idx);\n\t\tres->x2.t = DUK_ISPEC_VALUE;\n\n\t\t/* special RegExp literal handling after IdentifierName */\n\t\tcomp_ctx->curr_func.reject_regexp_in_adv = 1;\n\n\t\tduk__advance(comp_ctx);\n\t\treturn;\n\t}\n\tcase DUK_TOK_LBRACKET: {\n\t\t/* Property access expressions are critical for correct LHS ordering,\n\t\t * see comments in duk__expr()!\n\t\t */\n\n\t\t/* XXX: optimize temp reg use */\n\t\t/* XXX: similar coercion issue as in DUK_TOK_PERIOD */\n\t\t/* XXX: coerce to regs? it might be better for enumeration use, where the\n\t\t * same PROP ivalue is used multiple times.  Or perhaps coerce PROP further\n\t\t * there?\n\t\t */\n\t\t/* XXX: for simple cases like x['y'] an unnecessary LDREG is\n\t\t * emitted for the base value; could avoid it if we knew that\n\t\t * the key expression is safe (e.g. just a single literal).\n\t\t */\n\n\t\t/* The 'left' value must not be a register bound variable\n\t\t * because it may be mutated during the rest of the expression\n\t\t * and E5.1 Section 11.2.1 specifies the order of evaluation\n\t\t * so that the base value is evaluated first.\n\t\t * See: test-bug-nested-prop-mutate.js.\n\t\t */\n\t\tduk__ivalue_totempconst(comp_ctx, left);\n\t\tduk__expr_toplain(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);  /* Expression, ']' terminates */\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RBRACKET);\n\n\t\tres->t = DUK_IVAL_PROP;\n\t\tduk__copy_ispec(comp_ctx, &res->x1, &res->x2);   /* res.x1 -> res.x2 */\n\t\tduk__copy_ispec(comp_ctx, &left->x1, &res->x1);  /* left.x1 -> res.x1 */\n\t\treturn;\n\t}\n\tcase DUK_TOK_LPAREN: {\n\t\t/* function call */\n\t\tduk_regconst_t reg_cs = DUK__ALLOCTEMPS(comp_ctx, 2);\n\t\tduk_int_t nargs;\n\t\tduk_small_uint_t call_op = DUK_OP_CALL0;\n\n\t\t/* XXX: attempt to get the call result to \"next temp\" whenever\n\t\t * possible to avoid unnecessary register shuffles.\n\t\t */\n\n\t\t/*\n\t\t *  Setup call: target and 'this' binding.  Three cases:\n\t\t *\n\t\t *    1. Identifier base (e.g. \"foo()\")\n\t\t *    2. Property base (e.g. \"foo.bar()\")\n\t\t *    3. Register base (e.g. \"foo()()\"; i.e. when a return value is a function)\n\t\t */\n\n\t\tif (left->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with identifier base\"));\n\n\t\t\th_varname = duk_known_hstring(thr, left->x1.valstack_idx);\n\t\t\tif (h_varname == DUK_HTHREAD_STRING_EVAL(thr)) {\n\t\t\t\t/* Potential direct eval call detected, flag the CALL\n\t\t\t\t * so that a run-time \"direct eval\" check is made and\n\t\t\t\t * special behavior may be triggered.  Note that this\n\t\t\t\t * does not prevent 'eval' from being register bound.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with identifier 'eval' \"\n\t\t\t\t                     \"-> using EVALCALL, marking function \"\n\t\t\t\t                     \"as may_direct_eval\"));\n\t\t\t\tcall_op |= DUK_BC_CALL_FLAG_CALLED_AS_EVAL;\n\t\t\t\tcomp_ctx->curr_func.may_direct_eval = 1;\n\t\t\t}\n\n\t\t\tduk_dup(thr, left->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t              DUK_OP_CSREG | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t              reg_varbind,\n\t\t\t\t              reg_cs + 0);\n\t\t\t} else {\n\t\t\t\t/* XXX: expand target register or constant field to\n\t\t\t\t * reduce shuffling.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(DUK__ISCONST(rc_varname));\n\t\t\t\tduk__emit_a_b(comp_ctx,\n\t\t\t\t              DUK_OP_CSVAR | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t              reg_cs + 0,\n\t\t\t\t              rc_varname);\n\t\t\t}\n\t\t} else if (left->t == DUK_IVAL_PROP) {\n\t\t\t/* Call through a property lookup, E5 Section 11.2.3, step 6.a.i,\n\t\t\t * E5 Section 10.4.3.  There used to be a separate CSPROP opcode\n\t\t\t * but a typical call setup took 3 opcodes (e.g. LDREG, LDCONST,\n\t\t\t * CSPROP) and the same can be achieved with ordinary loads.\n\t\t\t */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\t\tduk_regconst_t reg_key;\n#endif\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with property base\"));\n\n\t\t\t/* XXX: For Math.sin() this generates: LDCONST + LDREG +\n\t\t\t * GETPROPC + call.  The LDREG is unnecessary because LDCONST\n\t\t\t * could be loaded directly into reg_cs + 1.  This doesn't\n\t\t\t * happen now because a variable cannot be in left->x1 of a\n\t\t\t * DUK_IVAL_PROP.  We could notice that left->x1 is a temp\n\t\t\t * and reuse, but it would still be in the wrong position\n\t\t\t * (reg_cs + 0 rather than reg_cs + 1).\n\t\t\t */\n\t\t\tduk__ispec_toforcedreg(comp_ctx, &left->x1, reg_cs + 1);  /* base */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\t\treg_key = duk__ispec_toregconst_raw(comp_ctx, &left->x2, -1, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_GETPROPC | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_cs + 0,\n\t\t\t                reg_cs + 1,\n\t\t\t                reg_key);\n#else\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_cs + 0);  /* base[key] */\n#endif\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with register base\"));\n\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_cs + 0);\n#if 0\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CSREG | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t               reg_cs + 0,\n\t\t\t               reg_cs + 0);  /* in-place setup */\n#endif\n\t\t\t/* Because of in-place setup, REGCS is equivalent to\n\t\t\t * just this LDUNDEF.\n\t\t\t */\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_LDUNDEF, reg_cs + 1);\n\t\t}\n\n\t\tDUK__SETTEMP(comp_ctx, reg_cs + 2);\n\t\tnargs = duk__parse_arguments(comp_ctx, res);  /* parse args starting from \"next temp\" */\n\n\t\t/* Tailcalls are handled by back-patching the already emitted opcode\n\t\t * later in return statement parser.\n\t\t */\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               call_op,\n\t\t               (duk_regconst_t) nargs /*numargs*/,\n\t\t               reg_cs /*basereg*/);\n\t\tDUK__SETTEMP(comp_ctx, reg_cs + 1);    /* result in csreg */\n\n\t\tduk__ivalue_regconst(res, reg_cs);\n\t\treturn;\n\t}\n\n\t/* POSTFIX EXPRESSION */\n\n\tcase DUK_TOK_INCREMENT: {\n\t\targs = (DUK_OP_POSTINCP_RR << 16) + (DUK_OP_POSTINCR << 8) + 0;\n\t\tgoto postincdec;\n\t}\n\tcase DUK_TOK_DECREMENT: {\n\t\targs = (DUK_OP_POSTDECP_RR << 16) + (DUK_OP_POSTDECR << 8) + 0;\n\t\tgoto postincdec;\n\t}\n\n\t/* EXPONENTIATION EXPRESSION */\n\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\tcase DUK_TOK_EXP: {\n\t\targs = (DUK_OP_EXP << 8) + DUK__BP_EXPONENTIATION - 1;  /* UnaryExpression */\n\t\tgoto binary;\n\t}\n#endif\n\n\t/* MULTIPLICATIVE EXPRESSION */\n\n\tcase DUK_TOK_MUL: {\n\t\targs = (DUK_OP_MUL << 8) + DUK__BP_MULTIPLICATIVE;  /* ExponentiationExpression */\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_DIV: {\n\t\targs = (DUK_OP_DIV << 8) + DUK__BP_MULTIPLICATIVE;  /* ExponentiationExpression */\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_MOD: {\n\t\targs = (DUK_OP_MOD << 8) + DUK__BP_MULTIPLICATIVE;  /* ExponentiationExpression */\n\t\tgoto binary;\n\t}\n\n\t/* ADDITIVE EXPRESSION */\n\n\tcase DUK_TOK_ADD: {\n\t\targs = (DUK_OP_ADD << 8) + DUK__BP_ADDITIVE;  /* MultiplicativeExpression */\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_SUB: {\n\t\targs = (DUK_OP_SUB << 8) + DUK__BP_ADDITIVE;  /* MultiplicativeExpression */\n\t\tgoto binary;\n\t}\n\n\t/* SHIFT EXPRESSION */\n\n\tcase DUK_TOK_ALSHIFT: {\n\t\t/* << */\n\t\targs = (DUK_OP_BASL << 8) + DUK__BP_SHIFT;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_ARSHIFT: {\n\t\t/* >> */\n\t\targs = (DUK_OP_BASR << 8) + DUK__BP_SHIFT;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_RSHIFT: {\n\t\t/* >>> */\n\t\targs = (DUK_OP_BLSR << 8) + DUK__BP_SHIFT;\n\t\tgoto binary;\n\t}\n\n\t/* RELATIONAL EXPRESSION */\n\n\tcase DUK_TOK_LT: {\n\t\t/* < */\n\t\targs = (DUK_OP_LT << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_GT: {\n\t\targs = (DUK_OP_GT << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_LE: {\n\t\targs = (DUK_OP_LE << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_GE: {\n\t\targs = (DUK_OP_GE << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_INSTANCEOF: {\n\t\targs = (DUK_OP_INSTOF << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_IN: {\n\t\targs = (DUK_OP_IN << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\n\t/* EQUALITY EXPRESSION */\n\n\tcase DUK_TOK_EQ: {\n\t\targs = (DUK_OP_EQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_NEQ: {\n\t\targs = (DUK_OP_NEQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_SEQ: {\n\t\targs = (DUK_OP_SEQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_SNEQ: {\n\t\targs = (DUK_OP_SNEQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\n\t/* BITWISE EXPRESSIONS */\n\n\tcase DUK_TOK_BAND: {\n\t\targs = (DUK_OP_BAND << 8) + DUK__BP_BAND;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_BXOR: {\n\t\targs = (DUK_OP_BXOR << 8) + DUK__BP_BXOR;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_BOR: {\n\t\targs = (DUK_OP_BOR << 8) + DUK__BP_BOR;\n\t\tgoto binary;\n\t}\n\n\t/* LOGICAL EXPRESSIONS */\n\n\tcase DUK_TOK_LAND: {\n\t\t/* syntactically left-associative but parsed as right-associative */\n\t\targs = (1 << 8) + DUK__BP_LAND - 1;\n\t\tgoto binary_logical;\n\t}\n\tcase DUK_TOK_LOR: {\n\t\t/* syntactically left-associative but parsed as right-associative */\n\t\targs = (0 << 8) + DUK__BP_LOR - 1;\n\t\tgoto binary_logical;\n\t}\n\n\t/* CONDITIONAL EXPRESSION */\n\n\tcase DUK_TOK_QUESTION: {\n\t\t/* XXX: common reg allocation need is to reuse a sub-expression's temp reg,\n\t\t * but only if it really is a temp.  Nothing fancy here now.\n\t\t */\n\t\tduk_regconst_t reg_temp;\n\t\tduk_int_t pc_jump1;\n\t\tduk_int_t pc_jump2;\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_temp);\n\t\tduk__emit_if_true_skip(comp_ctx, reg_temp);\n\t\tpc_jump1 = duk__emit_jump_empty(comp_ctx);  /* jump to false */\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp /*forced_reg*/);  /* AssignmentExpression */\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\t\tpc_jump2 = duk__emit_jump_empty(comp_ctx);  /* jump to end */\n\t\tduk__patch_jump_here(comp_ctx, pc_jump1);\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp /*forced_reg*/);  /* AssignmentExpression */\n\t\tduk__patch_jump_here(comp_ctx, pc_jump2);\n\n\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\n\t/* ASSIGNMENT EXPRESSION */\n\n\tcase DUK_TOK_EQUALSIGN: {\n\t\t/*\n\t\t *  Assignments are right associative, allows e.g.\n\t\t *    a = 5;\n\t\t *    a += b = 9;   // same as a += (b = 9)\n\t\t *  -> expression value 14, a = 14, b = 9\n\t\t *\n\t\t *  Right associativiness is reflected in the BP for recursion,\n\t\t *  \"-1\" ensures assignment operations are allowed.\n\t\t *\n\t\t *  XXX: just use DUK__BP_COMMA (i.e. no need for 2-step bp levels)?\n\t\t */\n\t\targs = (DUK_OP_NONE << 8) + DUK__BP_ASSIGNMENT - 1;   /* DUK_OP_NONE marks a 'plain' assignment */\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_ADD_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_ADD << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_SUB_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_SUB << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_MUL_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_MUL << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_DIV_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_DIV << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_MOD_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_MOD << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\tcase DUK_TOK_EXP_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_EXP << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n#endif\n\tcase DUK_TOK_ALSHIFT_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BASL << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_ARSHIFT_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BASR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_RSHIFT_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BLSR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_BAND_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BAND << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_BOR_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BOR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_BXOR_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BXOR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\n\t/* COMMA */\n\n\tcase DUK_TOK_COMMA: {\n\t\t/* right associative */\n\n\t\tduk__ivalue_toplain_ignore(comp_ctx, left);  /* need side effects, not value */\n\t\tduk__expr_toplain(comp_ctx, res, DUK__BP_COMMA - 1 /*rbp_flags*/);\n\n\t\t/* return 'res' (of right part) as our result */\n\t\treturn;\n\t}\n\n\tdefault: {\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"parse error: unexpected token: %ld\", (long) tok));\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);\n\tDUK_WO_NORETURN(return;);\n\n#if 0\n\t/* XXX: shared handling for 'duk__expr_lhs'? */\n\tif (comp_ctx->curr_func.paren_level == 0 && XXX) {\n\t\tcomp_ctx->curr_func.duk__expr_lhs = 0;\n\t}\n#endif\n\n binary:\n\t/*\n\t *  Shared handling of binary operations\n\t *\n\t *  args = (opcode << 8) + rbp\n\t */\n\t{\n\t\tduk__ivalue_toplain(comp_ctx, left);\n\t\tduk__expr_toplain(comp_ctx, res, args & 0xff /*rbp_flags*/);\n\n\t\t/* combine left->x1 and res->x1 (right->x1, really) -> (left->x1 OP res->x1) */\n\t\tDUK_ASSERT(left->t == DUK_IVAL_PLAIN);\n\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN);\n\n\t\tres->t = DUK_IVAL_ARITH;\n\t\tres->op = (args >> 8) & 0xff;\n\n\t\tres->x2.t = res->x1.t;\n\t\tres->x2.regconst = res->x1.regconst;\n\t\tduk_copy(thr, res->x1.valstack_idx, res->x2.valstack_idx);\n\n\t\tres->x1.t = left->x1.t;\n\t\tres->x1.regconst = left->x1.regconst;\n\t\tduk_copy(thr, left->x1.valstack_idx, res->x1.valstack_idx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"binary op, res: t=%ld, x1.t=%ld, x1.regconst=0x%08lx, x2.t=%ld, x2.regconst=0x%08lx\",\n\t\t                     (long) res->t, (long) res->x1.t, (unsigned long) res->x1.regconst, (long) res->x2.t, (unsigned long) res->x2.regconst));\n\t\treturn;\n\t}\n\n binary_logical:\n\t/*\n\t *  Shared handling for logical AND and logical OR.\n\t *\n\t *  args = (truthval << 8) + rbp\n\t *\n\t *  Truthval determines when to skip right-hand-side.\n\t *  For logical AND truthval=1, for logical OR truthval=0.\n\t *\n\t *  See doc/compiler.rst for discussion on compiling logical\n\t *  AND and OR expressions.  The approach here is very simplistic,\n\t *  generating extra jumps and multiple evaluations of truth values,\n\t *  but generates code on-the-fly with only local back-patching.\n\t *\n\t *  Both logical AND and OR are syntactically left-associated.\n\t *  However, logical ANDs are compiled as right associative\n\t *  expressions, i.e. \"A && B && C\" as \"A && (B && C)\", to allow\n\t *  skip jumps to skip over the entire tail.  Similarly for logical OR.\n\t */\n\n\t{\n\t\tduk_regconst_t reg_temp;\n\t\tduk_int_t pc_jump;\n\t\tduk_small_uint_t args_truthval = args >> 8;\n\t\tduk_small_uint_t args_rbp = args & 0xff;\n\n\t\t/* XXX: unoptimal use of temps, resetting */\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_temp);\n\t\tDUK_ASSERT(DUK__ISREG(reg_temp));\n\t\tduk__emit_bc(comp_ctx,\n\t\t            (args_truthval ? DUK_OP_IFTRUE_R : DUK_OP_IFFALSE_R),\n\t\t            reg_temp);  /* skip jump conditionally */\n\t\tpc_jump = duk__emit_jump_empty(comp_ctx);\n\t\tduk__expr_toforcedreg(comp_ctx, res, args_rbp /*rbp_flags*/, reg_temp /*forced_reg*/);\n\t\tduk__patch_jump_here(comp_ctx, pc_jump);\n\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\n assign:\n\t/*\n\t *  Shared assignment expression handling\n\t *\n\t *  args = (opcode << 8) + rbp\n\t *\n\t *  If 'opcode' is DUK_OP_NONE, plain assignment without arithmetic.\n\t *  Syntactically valid left-hand-side forms which are not accepted as\n\t *  left-hand-side values (e.g. as in \"f() = 1\") must NOT cause a\n\t *  SyntaxError, but rather a run-time ReferenceError.\n\t *\n\t *  When evaluating X <op>= Y, the LHS (X) is conceptually evaluated\n\t *  to a temporary first.  The RHS is then evaluated.  Finally, the\n\t *  <op> is applied to the initial value of RHS (not the value after\n\t *  RHS evaluation), and written to X.  Doing so concretely generates\n\t *  inefficient code so we'd like to avoid the temporary when possible.\n\t *  See: https://github.com/svaarala/duktape/pull/992.\n\t *\n\t *  The expression value (final LHS value, written to RHS) is\n\t *  conceptually copied into a fresh temporary so that it won't\n\t *  change even if the LHS/RHS values change in outer expressions.\n\t *  For example, it'd be generally incorrect for the expression value\n\t *  to be the RHS register binding, unless there's a guarantee that it\n\t *  won't change during further expression evaluation.  Using the\n\t *  temporary concretely produces inefficient bytecode, so we try to\n\t *  avoid the extra temporary for some known-to-be-safe cases.\n\t *  Currently the only safe case we detect is a \"top level assignment\",\n\t *  for example \"x = y + z;\", where the assignment expression value is\n\t *  ignored.\n\t *  See: test-dev-assign-expr.js and test-bug-assign-mutate-gh381.js.\n\t */\n\n\t{\n\t\tduk_small_uint_t args_op = args >> 8;\n\t\tduk_small_uint_t args_rbp = args & 0xff;\n\t\tduk_bool_t toplevel_assign;\n\n\t\t/* XXX: here we need to know if 'left' is left-hand-side compatible.\n\t\t * That information is no longer available from current expr parsing\n\t\t * state; it would need to be carried into the 'left' ivalue or by\n\t\t * some other means.\n\t\t */\n\n\t\t/* A top-level assignment is e.g. \"x = y;\".  For these it's safe\n\t\t * to use the RHS as-is as the expression value, even if the RHS\n\t\t * is a reg-bound identifier.  The RHS ('res') is right associative\n\t\t * so it has consumed all other assignment level operations; the\n\t\t * only relevant lower binding power construct is comma operator\n\t\t * which will ignore the expression value provided here.  Usually\n\t\t * the top level assignment expression value is ignored, but it\n\t\t * is relevant for e.g. eval code.\n\t\t */\n\t\ttoplevel_assign = (comp_ctx->curr_func.nud_count == 1 && /* one token before */\n\t\t                   comp_ctx->curr_func.led_count == 1);  /* one operator (= assign) */\n\t\tDUK_DDD(DUK_DDDPRINT(\"assignment: nud_count=%ld, led_count=%ld, toplevel_assign=%ld\",\n\t\t                     (long) comp_ctx->curr_func.nud_count,\n\t\t                     (long) comp_ctx->curr_func.led_count,\n\t\t                     (long) toplevel_assign));\n\n\t\tif (left->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\tDUK_ASSERT(left->x1.t == DUK_ISPEC_VALUE);  /* LHS is already side effect free */\n\n\t\t\th_varname = duk_known_hstring(thr, left->x1.valstack_idx);\n\t\t\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\t\t\t/* E5 Section 11.13.1 (and others for other assignments), step 4. */\n\t\t\t\tgoto syntax_error_lvalue;\n\t\t\t}\n\t\t\tduk_dup(thr, left->x1.valstack_idx);\n\t\t\t(void) duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname);\n\n\t\t\tif (args_op == DUK_OP_NONE) {\n\t\t\t\tduk__expr(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\tif (toplevel_assign) {\n\t\t\t\t\t/* Any 'res' will do. */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"plain assignment, toplevel assign, use as is\"));\n\t\t\t\t} else {\n\t\t\t\t\t/* 'res' must be a plain ivalue, and not register-bound variable. */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"plain assignment, not toplevel assign, ensure not a reg-bound identifier\"));\n\t\t\t\t\tif (res->t != DUK_IVAL_PLAIN || (res->x1.t == DUK_ISPEC_REGCONST &&\n\t\t\t\t\t                                 DUK__ISREG_NOTTEMP(comp_ctx, res->x1.regconst))) {\n\t\t\t\t\t\tduk__ivalue_totempconst(comp_ctx, res);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* For X <op>= Y we need to evaluate the pre-op\n\t\t\t\t * value of X before evaluating the RHS: the RHS\n\t\t\t\t * can change X, but when we do <op> we must use\n\t\t\t\t * the pre-op value.\n\t\t\t\t */\n\t\t\t\tduk_regconst_t reg_temp;\n\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t\t\tif (reg_varbind >= 0) {\n\t\t\t\t\tduk_regconst_t reg_res;\n\t\t\t\t\tduk_regconst_t reg_src;\n\t\t\t\t\tduk_int_t pc_temp_load;\n\t\t\t\t\tduk_int_t pc_before_rhs;\n\t\t\t\t\tduk_int_t pc_after_rhs;\n\n\t\t\t\t\tif (toplevel_assign) {\n\t\t\t\t\t\t/* 'reg_varbind' is the operation result and can also\n\t\t\t\t\t\t * become the expression value for top level assignments\n\t\t\t\t\t\t * such as: \"var x; x += y;\".\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"<op>= expression is top level, write directly to reg_varbind\"));\n\t\t\t\t\t\treg_res = reg_varbind;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t/* Not safe to use 'reg_varbind' as assignment expression\n\t\t\t\t\t\t * value, so go through a temp.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"<op>= expression is not top level, write to reg_temp\"));\n\t\t\t\t\t\treg_res = reg_temp;  /* reg_res should be smallest possible */\n\t\t\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\t\t}\n\n\t\t\t\t\t/* Try to optimize X <op>= Y for reg-bound\n\t\t\t\t\t * variables.  Detect side-effect free RHS\n\t\t\t\t\t * narrowly by seeing whether it emits code.\n\t\t\t\t\t * If not, rewind the code emitter and overwrite\n\t\t\t\t\t * the unnecessary temp reg load.\n\t\t\t\t\t */\n\n\t\t\t\t\tpc_temp_load = duk__get_current_pc(comp_ctx);\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_LDREG,\n\t\t\t\t\t               reg_temp,\n\t\t\t\t\t               reg_varbind);\n\n\t\t\t\t\tpc_before_rhs = duk__get_current_pc(comp_ctx);\n\t\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\t\t\t\t\tpc_after_rhs = duk__get_current_pc(comp_ctx);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"pc_temp_load=%ld, pc_before_rhs=%ld, pc_after_rhs=%ld\",\n\t\t\t\t\t                   (long) pc_temp_load, (long) pc_before_rhs,\n\t\t\t\t\t                   (long) pc_after_rhs));\n\n\t\t\t\t\tif (pc_after_rhs == pc_before_rhs) {\n\t\t\t\t\t\t/* Note: if the reg_temp load generated shuffling\n\t\t\t\t\t\t * instructions, we may need to rewind more than\n\t\t\t\t\t\t * one instruction, so use explicit PC computation.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"rhs is side effect free, rewind and avoid unnecessary temp for reg-based <op>=\"));\n\t\t\t\t\t\tDUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, (pc_temp_load - pc_before_rhs) * (duk_int_t) sizeof(duk_compiler_instr));\n\t\t\t\t\t\treg_src = reg_varbind;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"rhs evaluation emitted code, not sure if rhs is side effect free; use temp reg for LHS\"));\n\t\t\t\t\t\treg_src = reg_temp;\n\t\t\t\t\t}\n\n\t\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t\t                args_op | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t\t                reg_res,\n\t\t\t\t\t                reg_src,\n\t\t\t\t\t                res->x1.regconst);\n\n\t\t\t\t\tres->x1.regconst = reg_res;\n\n\t\t\t\t\t/* Ensure compact use of temps. */\n\t\t\t\t\tif (DUK__ISREG_TEMP(comp_ctx, reg_res)) {\n\t\t\t\t\t\tDUK__SETTEMP(comp_ctx, reg_res + 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t/* When LHS is not register bound, always go through a\n\t\t\t\t\t * temporary.  No optimization for top level assignment.\n\t\t\t\t\t */\n\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_GETVAR,\n\t\t\t\t\t               reg_temp,\n\t\t\t\t\t               rc_varname);\n\n\t\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\n\t\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t\t                args_op | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t\t                reg_temp,\n\t\t\t\t\t                reg_temp,\n\t\t\t\t\t                res->x1.regconst);\n\t\t\t\t\tres->x1.regconst = reg_temp;\n\t\t\t\t}\n\n\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\t\t\t}\n\n\t\t\t/* At this point 'res' holds the potential expression value.\n\t\t\t * It can be basically any ivalue here, including a reg-bound\n\t\t\t * identifier (if code above deems it safe) or a unary/binary\n\t\t\t * operation.  Operations must be resolved to a side effect free\n\t\t\t * plain value, and the side effects must happen exactly once.\n\t\t\t */\n\n\t\t\tif (reg_varbind >= 0) {\n\t\t\t\tif (res->t != DUK_IVAL_PLAIN) {\n\t\t\t\t\t/* Resolve 'res' directly into the LHS binding, and use\n\t\t\t\t\t * that as the expression value if safe.  If not safe,\n\t\t\t\t\t * resolve to a temp/const and copy to LHS.\n\t\t\t\t\t */\n\t\t\t\t\tif (toplevel_assign) {\n\t\t\t\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, (duk_int_t) reg_varbind);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk__ivalue_totempconst(comp_ctx, res);\n\t\t\t\t\t\tduk__copy_ivalue(comp_ctx, res, left);  /* use 'left' as a temp */\n\t\t\t\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, (duk_int_t) reg_varbind);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t/* Use 'res' as the expression value (it's side effect\n\t\t\t\t\t * free and may be a plain value, a register, or a\n\t\t\t\t\t * constant) and write it to the LHS binding too.\n\t\t\t\t\t */\n\t\t\t\t\tduk__copy_ivalue(comp_ctx, res, left);  /* use 'left' as a temp */\n\t\t\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, (duk_int_t) reg_varbind);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* Only a reg fits into 'A' so coerce 'res' into a register\n\t\t\t\t * for PUTVAR.\n\t\t\t\t *\n\t\t\t\t * XXX: here the current A/B/C split is suboptimal: we could\n\t\t\t\t * just use 9 bits for reg_res (and support constants) and 17\n\t\t\t\t * instead of 18 bits for the varname const index.\n\t\t\t\t */\n\n\t\t\t\tduk__ivalue_toreg(comp_ctx, res);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t               res->x1.regconst,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\n\t\t\t/* 'res' contains expression value */\n\t\t} else if (left->t == DUK_IVAL_PROP) {\n\t\t\t/* E5 Section 11.13.1 (and others) step 4 never matches for prop writes -> no check */\n\t\t\tduk_regconst_t reg_obj;\n\t\t\tduk_regconst_t rc_key;\n\t\t\tduk_regconst_t rc_res;\n\t\t\tduk_regconst_t reg_temp;\n\n\t\t\t/* Property access expressions ('a[b]') are critical to correct\n\t\t\t * LHS evaluation ordering, see test-dev-assign-eval-order*.js.\n\t\t\t * We must make sure that the LHS target slot (base object and\n\t\t\t * key) don't change during RHS evaluation.  The only concrete\n\t\t\t * problem is a register reference to a variable-bound register\n\t\t\t * (i.e., non-temp).  Require temp regs for both key and base.\n\t\t\t *\n\t\t\t * Don't allow a constant for the object (even for a number\n\t\t\t * etc), as it goes into the 'A' field of the opcode.\n\t\t\t */\n\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx,\n\t\t\t                                    &left->x1,\n\t\t\t                                    -1 /*forced_reg*/,\n\t\t\t                                    DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/);\n\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx,\n\t\t\t                                   &left->x2,\n\t\t\t                                   -1 /*forced_reg*/,\n\t\t\t                                   DUK__IVAL_FLAG_REQUIRE_TEMP | DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\n\t\t\t/* Evaluate RHS only when LHS is safe. */\n\n\t\t\tif (args_op == DUK_OP_NONE) {\n\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\t\t\t\trc_res = res->x1.regconst;\n\t\t\t} else {\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                DUK_OP_GETPROP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                reg_temp,\n\t\t\t\t                reg_obj,\n\t\t\t\t                rc_key);\n\n\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                args_op | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                reg_temp,\n\t\t\t\t                reg_temp,\n\t\t\t\t                res->x1.regconst);\n\t\t\t\trc_res = reg_temp;\n\t\t\t}\n\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_obj,\n\t\t\t                rc_key,\n\t\t\t                rc_res);\n\n\t\t\tduk__ivalue_regconst(res, rc_res);\n\t\t} else {\n\t\t\t/* No support for lvalues returned from new or function call expressions.\n\t\t\t * However, these must NOT cause compile-time SyntaxErrors, but run-time\n\t\t\t * ReferenceErrors.  Both left and right sides of the assignment must be\n\t\t\t * evaluated before throwing a ReferenceError.  For instance:\n\t\t\t *\n\t\t\t *     f() = g();\n\t\t\t *\n\t\t\t * must result in f() being evaluated, then g() being evaluated, and\n\t\t\t * finally, a ReferenceError being thrown.  See E5 Section 11.13.1.\n\t\t\t */\n\n\t\t\tduk_regconst_t rc_res;\n\n\t\t\t/* First evaluate LHS fully to ensure all side effects are out. */\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, left);\n\n\t\t\t/* Then evaluate RHS fully (its value becomes the expression value too).\n\t\t\t * Technically we'd need the side effect safety check here too, but because\n\t\t\t * we always throw using INVLHS the result doesn't matter.\n\t\t\t */\n\t\t\trc_res = duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\n\t\t\tduk__emit_op_only(comp_ctx, DUK_OP_INVLHS);\n\n\t\t\tduk__ivalue_regconst(res, rc_res);\n\t\t}\n\n\t\treturn;\n\t}\n\n postincdec:\n\t{\n\t\t/*\n\t\t *  Post-increment/decrement will return the original value as its\n\t\t *  result value.  However, even that value will be coerced using\n\t\t *  ToNumber() which is quite awkward.  Specific bytecode opcodes\n\t\t *  are used to handle these semantics.\n\t\t *\n\t\t *  Note that post increment/decrement has a \"no LineTerminator here\"\n\t\t *  restriction.  This is handled by duk__expr_lbp(), which forcibly terminates\n\t\t *  the previous expression if a LineTerminator occurs before '++'/'--'.\n\t\t */\n\n\t\tduk_regconst_t reg_res;\n\t\tduk_small_uint_t args_op1 = (args >> 8) & 0xff;  /* DUK_OP_POSTINCR/DUK_OP_POSTDECR */\n\t\tduk_small_uint_t args_op2 = args >> 16;          /* DUK_OP_POSTINCP_RR/DUK_OP_POSTDECP_RR */\n\n\t\t/* Specific assumptions for opcode numbering. */\n\t\tDUK_ASSERT(DUK_OP_POSTINCR + 4 == DUK_OP_POSTINCV);\n\t\tDUK_ASSERT(DUK_OP_POSTDECR + 4 == DUK_OP_POSTDECV);\n\n\t\treg_res = DUK__ALLOCTEMP(comp_ctx);\n\n\t\tif (left->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\th_varname = duk_known_hstring(thr, left->x1.valstack_idx);\n\n\t\t\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\tduk_dup(thr, left->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               args_op1,  /* e.g. DUK_OP_POSTINCR */\n\t\t\t\t               reg_res,\n\t\t\t\t               reg_varbind);\n\t\t\t} else {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               args_op1 + 4,  /* e.g. DUK_OP_POSTINCV */\n\t\t\t\t               reg_res,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"postincdec to '%!O' -> reg_varbind=%ld, rc_varname=%ld\",\n\t\t\t                     (duk_heaphdr *) h_varname, (long) reg_varbind, (long) rc_varname));\n\t\t} else if (left->t == DUK_IVAL_PROP) {\n\t\t\tduk_regconst_t reg_obj;  /* allocate to reg only (not const) */\n\t\t\tduk_regconst_t rc_key;\n\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &left->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &left->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                args_op2 | DUK__EMIT_FLAG_BC_REGCONST,  /* e.g. DUK_OP_POSTINCP */\n\t\t\t                reg_res,\n\t\t\t                reg_obj,\n\t\t\t                rc_key);\n\t\t} else {\n\t\t\t/* Technically return value is not needed because INVLHS will\n\t\t\t * unconditially throw a ReferenceError.  Coercion is necessary\n\t\t\t * for proper semantics (consider ToNumber() called for an object).\n\t\t\t * Use DUK_OP_UNP with a dummy register to get ToNumber().\n\t\t\t */\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_res);\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_UNP,\n\t\t\t             reg_res);  /* for side effects, result ignored */\n\t\t\tduk__emit_op_only(comp_ctx,\n\t\t\t                  DUK_OP_INVLHS);\n\t\t}\n\n\t\tDUK__SETTEMP(comp_ctx, reg_res + 1);\n\t\tduk__ivalue_regconst(res, reg_res);\n\t\treturn;\n\t}\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_EXPRESSION);\n\tDUK_WO_NORETURN(return;);\n\n syntax_error_lvalue:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LVALUE);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL duk_small_uint_t duk__expr_lbp(duk_compiler_ctx *comp_ctx) {\n\tduk_small_uint_t tok = comp_ctx->curr_token.t;\n\n\tDUK_ASSERT_DISABLE(tok >= DUK_TOK_MINVAL);  /* unsigned */\n\tDUK_ASSERT(tok <= DUK_TOK_MAXVAL);\n\tDUK_ASSERT(sizeof(duk__token_lbp) == DUK_TOK_MAXVAL + 1);\n\n\t/* XXX: integrate support for this into led() instead?\n\t * Similar issue as post-increment/post-decrement.\n\t */\n\n\t/* prevent duk__expr_led() by using a binding power less than anything valid */\n\tif (tok == DUK_TOK_IN && !comp_ctx->curr_func.allow_in) {\n\t\treturn 0;\n\t}\n\n\tif ((tok == DUK_TOK_DECREMENT || tok == DUK_TOK_INCREMENT) &&\n\t    (comp_ctx->curr_token.lineterm)) {\n\t\t/* '++' or '--' in a post-increment/decrement position,\n\t\t * and a LineTerminator occurs between the operator and\n\t\t * the preceding expression.  Force the previous expr\n\t\t * to terminate, in effect treating e.g. \"a,b\\n++\" as\n\t\t * \"a,b;++\" (= SyntaxError).\n\t\t */\n\t\treturn 0;\n\t}\n\n\treturn DUK__TOKEN_LBP_GET_BP(duk__token_lbp[tok]);  /* format is bit packed */\n}\n\n/*\n *  Expression parsing.\n *\n *  Upon entry to 'expr' and its variants, 'curr_tok' is assumed to be the\n *  first token of the expression.  Upon exit, 'curr_tok' will be the first\n *  token not part of the expression (e.g. semicolon terminating an expression\n *  statement).\n */\n\n#define DUK__EXPR_RBP_MASK           0xff\n#define DUK__EXPR_FLAG_REJECT_IN     (1 << 8)   /* reject 'in' token (used for for-in) */\n#define DUK__EXPR_FLAG_ALLOW_EMPTY   (1 << 9)   /* allow empty expression */\n#define DUK__EXPR_FLAG_REQUIRE_INIT  (1 << 10)  /* require initializer for var/const */\n\n/* main expression parser function */\nDUK_LOCAL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_ivalue tmp_alloc;   /* 'res' is used for \"left\", and 'tmp' for \"right\" */\n\tduk_ivalue *tmp = &tmp_alloc;\n\tduk_small_uint_t rbp;\n\n\tDUK__RECURSION_INCREASE(comp_ctx, thr);\n\n\tduk_require_stack(thr, DUK__PARSE_EXPR_SLOTS);\n\n\t/* filter out flags from exprtop rbp_flags here to save space */\n\trbp = rbp_flags & DUK__EXPR_RBP_MASK;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__expr(), rbp_flags=%ld, rbp=%ld, allow_in=%ld, paren_level=%ld\",\n\t                     (long) rbp_flags, (long) rbp, (long) comp_ctx->curr_func.allow_in,\n\t                     (long) comp_ctx->curr_func.paren_level));\n\n\tduk_memzero(&tmp_alloc, sizeof(tmp_alloc));\n\ttmp->x1.valstack_idx = duk_get_top(thr);\n\ttmp->x2.valstack_idx = tmp->x1.valstack_idx + 1;\n\tduk_push_undefined(thr);\n\tduk_push_undefined(thr);\n\n\t/* XXX: where to release temp regs in intermediate expressions?\n\t * e.g. 1+2+3 -> don't inflate temp register count when parsing this.\n\t * that particular expression temp regs can be forced here.\n\t */\n\n\t/* XXX: increase ctx->expr_tokens here for every consumed token\n\t * (this would be a nice statistic)?\n\t */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON || comp_ctx->curr_token.t == DUK_TOK_RPAREN) {\n\t\t/* XXX: possibly incorrect handling of empty expression */\n\t\tDUK_DDD(DUK_DDDPRINT(\"empty expression\"));\n\t\tif (!(rbp_flags & DUK__EXPR_FLAG_ALLOW_EMPTY)) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EMPTY_EXPR_NOT_ALLOWED);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tduk_push_undefined(thr);\n\t\tduk__ivalue_plain_fromstack(comp_ctx, res);\n\t\tgoto cleanup;\n\t}\n\n\tduk__advance(comp_ctx);\n\tduk__expr_nud(comp_ctx, res);  /* reuse 'res' as 'left' */\n\twhile (rbp < duk__expr_lbp(comp_ctx)) {\n\t\tduk__advance(comp_ctx);\n\t\tduk__expr_led(comp_ctx, res, tmp);\n\t\tduk__copy_ivalue(comp_ctx, tmp, res);  /* tmp -> res */\n\t}\n\n cleanup:\n\t/* final result is already in 'res' */\n\n\tduk_pop_2(thr);\n\n\tDUK__RECURSION_DECREASE(comp_ctx, thr);\n}\n\nDUK_LOCAL void duk__exprtop(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\t/* Note: these variables must reside in 'curr_func' instead of the global\n\t * context: when parsing function expressions, expression parsing is nested.\n\t */\n\tcomp_ctx->curr_func.nud_count = 0;\n\tcomp_ctx->curr_func.led_count = 0;\n\tcomp_ctx->curr_func.paren_level = 0;\n\tcomp_ctx->curr_func.expr_lhs = 1;\n\tcomp_ctx->curr_func.allow_in = (rbp_flags & DUK__EXPR_FLAG_REJECT_IN ? 0 : 1);\n\n\tduk__expr(comp_ctx, res, rbp_flags);\n\n\tif (!(rbp_flags & DUK__EXPR_FLAG_ALLOW_EMPTY) && duk__expr_is_empty(comp_ctx)) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EMPTY_EXPR_NOT_ALLOWED);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\n/* A bunch of helpers (for size optimization) that combine duk__expr()/duk__exprtop()\n * and result conversions.\n *\n * Each helper needs at least 2-3 calls to make it worth while to wrap.\n */\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__expr_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toreg(comp_ctx, res);\n}\n#endif\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__expr_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_totemp(comp_ctx, res);\n}\n#endif\n\nDUK_LOCAL void duk__expr_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\tduk__expr(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toforcedreg(comp_ctx, res, forced_reg);\n}\n\nDUK_LOCAL duk_regconst_t duk__expr_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toregconst(comp_ctx, res);\n}\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__expr_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_totempconst(comp_ctx, res);\n}\n#endif\n\nDUK_LOCAL void duk__expr_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toplain(comp_ctx, res);\n}\n\nDUK_LOCAL void duk__expr_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toplain_ignore(comp_ctx, res);\n}\n\nDUK_LOCAL duk_regconst_t duk__exprtop_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toreg(comp_ctx, res);\n}\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__exprtop_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_totemp(comp_ctx, res);\n}\n#endif\n\nDUK_LOCAL void duk__exprtop_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toforcedreg(comp_ctx, res, forced_reg);\n}\n\nDUK_LOCAL duk_regconst_t duk__exprtop_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toregconst(comp_ctx, res);\n}\n\n#if 0  /* unused */\nDUK_LOCAL void duk__exprtop_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, int rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toplain_ignore(comp_ctx, res);\n}\n#endif\n\n/*\n *  Parse an individual source element (top level statement) or a statement.\n *\n *  Handles labeled statements automatically (peeling away labels before\n *  parsing an expression that follows the label(s)).\n *\n *  Upon entry, 'curr_tok' contains the first token of the statement (parsed\n *  in \"allow regexp literal\" mode).  Upon exit, 'curr_tok' contains the first\n *  token following the statement (if the statement has a terminator, this is\n *  the token after the terminator).\n */\n\n#define DUK__HAS_VAL                  (1 << 0)  /* stmt has non-empty value */\n#define DUK__HAS_TERM                 (1 << 1)  /* stmt has explicit/implicit semicolon terminator */\n#define DUK__ALLOW_AUTO_SEMI_ALWAYS   (1 << 2)  /* allow automatic semicolon even without lineterm (compatibility) */\n#define DUK__STILL_PROLOGUE           (1 << 3)  /* statement does not terminate directive prologue */\n#define DUK__IS_TERMINAL              (1 << 4)  /* statement is guaranteed to be terminal (control doesn't flow to next statement) */\n\n/* Parse a single variable declaration (e.g. \"i\" or \"i=10\").  A leading 'var'\n * has already been eaten.  These is no return value in 'res', it is used only\n * as a temporary.\n *\n * When called from 'for-in' statement parser, the initializer expression must\n * not allow the 'in' token.  The caller supply additional expression parsing\n * flags (like DUK__EXPR_FLAG_REJECT_IN) in 'expr_flags'.\n *\n * Finally, out_rc_varname and out_reg_varbind are updated to reflect where\n * the identifier is bound:\n *\n *    If register bound:      out_reg_varbind >= 0, out_rc_varname == 0 (ignore)\n *    If not register bound:  out_reg_varbind < 0, out_rc_varname >= 0\n *\n * These allow the caller to use the variable for further assignment, e.g.\n * as is done in 'for-in' parsing.\n */\n\nDUK_LOCAL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hstring *h_varname;\n\tduk_regconst_t reg_varbind;\n\tduk_regconst_t rc_varname;\n\n\t/* assume 'var' has been eaten */\n\n\t/* Note: Identifier rejects reserved words */\n\tif (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) {\n\t\tgoto syntax_error;\n\t}\n\th_varname = comp_ctx->curr_token.str1;\n\n\tDUK_ASSERT(h_varname != NULL);\n\n\t/* strict mode restrictions (E5 Section 12.2.1) */\n\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\tgoto syntax_error;\n\t}\n\n\t/* register declarations in first pass */\n\tif (comp_ctx->curr_func.in_scanning) {\n\t\tduk_uarridx_t n;\n\t\tDUK_DDD(DUK_DDDPRINT(\"register variable declaration %!O in pass 1\",\n\t\t                     (duk_heaphdr *) h_varname));\n\t\tn = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.decls_idx);\n\t\tduk_push_hstring(thr, h_varname);\n\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n);\n\t\tduk_push_int(thr, DUK_DECL_TYPE_VAR + (0 << 8));\n\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n + 1);\n\t}\n\n\tduk_push_hstring(thr, h_varname);  /* push before advancing to keep reachable */\n\n\t/* register binding lookup is based on varmap (even in first pass) */\n\tduk_dup_top(thr);\n\t(void) duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname);\n\n\tduk__advance(comp_ctx);  /* eat identifier */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_EQUALSIGN) {\n\t\tduk__advance(comp_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"vardecl, assign to '%!O' -> reg_varbind=%ld, rc_varname=%ld\",\n\t\t                     (duk_heaphdr *) h_varname, (long) reg_varbind, (long) rc_varname));\n\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_COMMA | expr_flags /*rbp_flags*/);  /* AssignmentExpression */\n\n\t\tif (reg_varbind >= 0) {\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_varbind);\n\t\t} else {\n\t\t\tduk_regconst_t reg_val;\n\t\t\treg_val = duk__ivalue_toreg(comp_ctx, res);\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t               reg_val,\n\t\t\t               rc_varname);\n\t\t}\n\t} else {\n\t\tif (expr_flags & DUK__EXPR_FLAG_REQUIRE_INIT) {\n\t\t\t/* Used for minimal 'const': initializer required. */\n\t\t\tgoto syntax_error;\n\t\t}\n\t}\n\n\tduk_pop(thr);  /* pop varname */\n\n\t*out_rc_varname = rc_varname;\n\t*out_reg_varbind = reg_varbind;\n\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_VAR_DECLARATION);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_var_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags) {\n\tduk_regconst_t reg_varbind;\n\tduk_regconst_t rc_varname;\n\n\tduk__advance(comp_ctx);  /* eat 'var' */\n\n\tfor (;;) {\n\t\t/* rc_varname and reg_varbind are ignored here */\n\t\tduk__parse_var_decl(comp_ctx, res, 0 | expr_flags, &reg_varbind, &rc_varname);\n\n\t\tif (comp_ctx->curr_token.t != DUK_TOK_COMMA) {\n\t\t\tbreak;\n\t\t}\n\t\tduk__advance(comp_ctx);\n\t}\n}\n\nDUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_int_t pc_v34_lhs;         /* start variant 3/4 left-hand-side code (L1 in doc/compiler.rst example) */\n\tduk_regconst_t temp_reset;    /* knock back \"next temp\" to this whenever possible */\n\tduk_regconst_t reg_temps;     /* preallocated temporaries (2) for variants 3 and 4 */\n\n\tDUK_DDD(DUK_DDDPRINT(\"start parsing a for/for-in statement\"));\n\n\t/* Two temporaries are preallocated here for variants 3 and 4 which need\n\t * registers which are never clobbered by expressions in the loop\n\t * (concretely: for the enumerator object and the next enumerated value).\n\t * Variants 1 and 2 \"release\" these temps.\n\t */\n\n\treg_temps = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\ttemp_reset = DUK__GETTEMP(comp_ctx);\n\n\t/*\n\t *  For/for-in main variants are:\n\t *\n\t *    1. for (ExpressionNoIn_opt; Expression_opt; Expression_opt) Statement\n\t *    2. for (var VariableDeclarationNoIn; Expression_opt; Expression_opt) Statement\n\t *    3. for (LeftHandSideExpression in Expression) Statement\n\t *    4. for (var VariableDeclarationNoIn in Expression) Statement\n\t *\n\t *  Parsing these without arbitrary lookahead or backtracking is relatively\n\t *  tricky but we manage to do so for now.\n\t *\n\t *  See doc/compiler.rst for a detailed discussion of control flow\n\t *  issues, evaluation order issues, etc.\n\t */\n\n\tduk__advance(comp_ctx);  /* eat 'for' */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\tDUK_DDD(DUK_DDDPRINT(\"detecting for/for-in loop variant, pc=%ld\", (long) duk__get_current_pc(comp_ctx)));\n\n\t/* a label site has been emitted by duk__parse_stmt() automatically\n\t * (it will also emit the ENDLABEL).\n\t */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_VAR) {\n\t\t/*\n\t\t *  Variant 2 or 4\n\t\t */\n\n\t\tduk_regconst_t reg_varbind;  /* variable binding register if register-bound (otherwise < 0) */\n\t\tduk_regconst_t rc_varname;   /* variable name reg/const, if variable not register-bound */\n\n\t\tduk__advance(comp_ctx);  /* eat 'var' */\n\t\tduk__parse_var_decl(comp_ctx, res, DUK__EXPR_FLAG_REJECT_IN, &reg_varbind, &rc_varname);\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_IN) {\n\t\t\t/*\n\t\t\t *  Variant 4\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 4: for (var VariableDeclarationNoIn in Expression) Statement\"));\n\t\t\tpc_v34_lhs = duk__get_current_pc(comp_ctx);  /* jump is inserted here */\n\t\t\tif (reg_varbind >= 0) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_LDREG,\n\t\t\t\t               reg_varbind,\n\t\t\t\t               reg_temps + 0);\n\t\t\t} else {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t               reg_temps + 0,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\t\t\tgoto parse_3_or_4;\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Variant 2\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 2: for (var VariableDeclarationNoIn; Expression_opt; Expression_opt) Statement\"));\n\t\t\tfor (;;) {\n\t\t\t\t/* more initializers */\n\t\t\t\tif (comp_ctx->curr_token.t != DUK_TOK_COMMA) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"variant 2 has another variable initializer\"));\n\n\t\t\t\tduk__advance(comp_ctx);  /* eat comma */\n\t\t\t\tduk__parse_var_decl(comp_ctx, res, DUK__EXPR_FLAG_REJECT_IN, &reg_varbind, &rc_varname);\n\t\t\t}\n\t\t\tgoto parse_1_or_2;\n\t\t}\n\t} else {\n\t\t/*\n\t\t *  Variant 1 or 3\n\t\t */\n\n\t\tpc_v34_lhs = duk__get_current_pc(comp_ctx);  /* jump is inserted here (variant 3) */\n\n\t\t/* Note that duk__exprtop() here can clobber any reg above current temp_next,\n\t\t * so any loop variables (e.g. enumerator) must be \"preallocated\".\n\t\t */\n\n\t\t/* don't coerce yet to a plain value (variant 3 needs special handling) */\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR | DUK__EXPR_FLAG_REJECT_IN | DUK__EXPR_FLAG_ALLOW_EMPTY /*rbp_flags*/);  /* Expression */\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_IN) {\n\t\t\t/*\n\t\t\t *  Variant 3\n\t\t\t */\n\n\t\t\t/* XXX: need to determine LHS type, and check that it is LHS compatible */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 3: for (LeftHandSideExpression in Expression) Statement\"));\n\t\t\tif (duk__expr_is_empty(comp_ctx)) {\n\t\t\t\tgoto syntax_error;  /* LeftHandSideExpression does not allow empty expression */\n\t\t\t}\n\n\t\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\t\tduk_regconst_t reg_varbind;\n\t\t\t\tduk_regconst_t rc_varname;\n\n\t\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_LDREG,\n\t\t\t\t\t               reg_varbind,\n\t\t\t\t\t               reg_temps + 0);\n\t\t\t\t} else {\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t\t               reg_temps + 0,\n\t\t\t\t\t               rc_varname);\n\t\t\t\t}\n\t\t\t} else if (res->t == DUK_IVAL_PROP) {\n\t\t\t\t/* Don't allow a constant for the object (even for a number etc), as\n\t\t\t\t * it goes into the 'A' field of the opcode.\n\t\t\t\t */\n\t\t\t\tduk_regconst_t reg_obj;\n\t\t\t\tduk_regconst_t rc_key;\n\t\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                reg_obj,\n\t\t\t\t                rc_key,\n\t\t\t\t                reg_temps + 0);\n\t\t\t} else {\n\t\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);  /* just in case */\n\t\t\t\tduk__emit_op_only(comp_ctx,\n\t\t\t\t                  DUK_OP_INVLHS);\n\t\t\t}\n\t\t\tgoto parse_3_or_4;\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Variant 1\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 1: for (ExpressionNoIn_opt; Expression_opt; Expression_opt) Statement\"));\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);\n\t\t\tgoto parse_1_or_2;\n\t\t}\n\t}\n\n parse_1_or_2:\n\t/*\n\t *  Parse variant 1 or 2.  The first part expression (which differs\n\t *  in the variants) has already been parsed and its code emitted.\n\t *\n\t *  reg_temps + 0: unused\n\t *  reg_temps + 1: unused\n\t */\n\t{\n\t\tduk_regconst_t rc_cond;\n\t\tduk_int_t pc_l1, pc_l2, pc_l3, pc_l4;\n\t\tduk_int_t pc_jumpto_l3, pc_jumpto_l4;\n\t\tduk_bool_t expr_c_empty;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"shared code for parsing variants 1 and 2\"));\n\n\t\t/* \"release\" preallocated temps since we won't need them */\n\t\ttemp_reset = reg_temps + 0;\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_SEMICOLON);\n\n\t\tpc_l1 = duk__get_current_pc(comp_ctx);\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR | DUK__EXPR_FLAG_ALLOW_EMPTY /*rbp_flags*/);  /* Expression_opt */\n\t\tif (duk__expr_is_empty(comp_ctx)) {\n\t\t\t/* no need to coerce */\n\t\t\tpc_jumpto_l3 = duk__emit_jump_empty(comp_ctx);  /* to body */\n\t\t\tpc_jumpto_l4 = -1;  /* omitted */\n\t\t} else {\n\t\t\trc_cond = duk__ivalue_toregconst(comp_ctx, res);\n\t\t\tduk__emit_if_false_skip(comp_ctx, rc_cond);\n\t\t\tpc_jumpto_l3 = duk__emit_jump_empty(comp_ctx);  /* to body */\n\t\t\tpc_jumpto_l4 = duk__emit_jump_empty(comp_ctx);  /* to exit */\n\t\t}\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_SEMICOLON);\n\n\t\tpc_l2 = duk__get_current_pc(comp_ctx);\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR | DUK__EXPR_FLAG_ALLOW_EMPTY /*rbp_flags*/);  /* Expression_opt */\n\t\tif (duk__expr_is_empty(comp_ctx)) {\n\t\t\t/* no need to coerce */\n\t\t\texpr_c_empty = 1;\n\t\t\t/* JUMP L1 omitted */\n\t\t} else {\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);\n\t\t\texpr_c_empty = 0;\n\t\t\tduk__emit_jump(comp_ctx, pc_l1);\n\t\t}\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\t\tpc_l3 = duk__get_current_pc(comp_ctx);\n\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\t\tif (expr_c_empty) {\n\t\t\tduk__emit_jump(comp_ctx, pc_l1);\n\t\t} else {\n\t\t\tduk__emit_jump(comp_ctx, pc_l2);\n\t\t}\n\t\t/* temp reset is not necessary after duk__parse_stmt(), which already does it */\n\n\t\tpc_l4 = duk__get_current_pc(comp_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"patching jumps: jumpto_l3: %ld->%ld, jumpto_l4: %ld->%ld, \"\n\t\t                     \"break: %ld->%ld, continue: %ld->%ld\",\n\t\t\t             (long) pc_jumpto_l3, (long) pc_l3, (long) pc_jumpto_l4, (long) pc_l4,\n\t\t                     (long) (pc_label_site + 1), (long) pc_l4, (long) (pc_label_site + 2), (long) pc_l2));\n\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l3, pc_l3);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l4, pc_l4);\n\t\tduk__patch_jump(comp_ctx,\n\t\t                pc_label_site + 1,\n\t\t                pc_l4);                         /* break jump */\n\t\tduk__patch_jump(comp_ctx,\n\t\t                pc_label_site + 2,\n\t\t                expr_c_empty ? pc_l1 : pc_l2);  /* continue jump */\n\t}\n\tgoto finished;\n\n parse_3_or_4:\n\t/*\n\t *  Parse variant 3 or 4.\n\t *\n\t *  For variant 3 (e.g. \"for (A in C) D;\") the code for A (except the\n\t *  final property/variable write) has already been emitted.  The first\n\t *  instruction of that code is at pc_v34_lhs; a JUMP needs to be inserted\n\t *  there to satisfy control flow needs.\n\t *\n\t *  For variant 4, if the variable declaration had an initializer\n\t *  (e.g. \"for (var A = B in C) D;\") the code for the assignment\n\t *  (B) has already been emitted.\n\t *\n\t *  Variables set before entering here:\n\t *\n\t *    pc_v34_lhs:    insert a \"JUMP L2\" here (see doc/compiler.rst example).\n\t *    reg_temps + 0: iteration target value (written to LHS)\n\t *    reg_temps + 1: enumerator object\n\t */\n\t{\n\t\tduk_int_t pc_l1, pc_l2, pc_l3, pc_l4, pc_l5;\n\t\tduk_int_t pc_jumpto_l2, pc_jumpto_l3, pc_jumpto_l4, pc_jumpto_l5;\n\t\tduk_regconst_t reg_target;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"shared code for parsing variants 3 and 4, pc_v34_lhs=%ld\", (long) pc_v34_lhs));\n\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\t/* First we need to insert a jump in the middle of previously\n\t\t * emitted code to get the control flow right.  No jumps can\n\t\t * cross the position where the jump is inserted.  See doc/compiler.rst\n\t\t * for discussion on the intricacies of control flow and side effects\n\t\t * for variants 3 and 4.\n\t\t */\n\n\t\tduk__insert_jump_entry(comp_ctx, pc_v34_lhs);\n\t\tpc_jumpto_l2 = pc_v34_lhs;  /* inserted jump */\n\t\tpc_l1 = pc_v34_lhs + 1;     /* +1, right after inserted jump */\n\n\t\t/* The code for writing reg_temps + 0 to the left hand side has already\n\t\t * been emitted.\n\t\t */\n\n\t\tpc_jumpto_l3 = duk__emit_jump_empty(comp_ctx);  /* -> loop body */\n\n\t\tduk__advance(comp_ctx);  /* eat 'in' */\n\n\t\t/* Parse enumeration target and initialize enumerator.  For 'null' and 'undefined',\n\t\t * INITENUM will creates a 'null' enumerator which works like an empty enumerator\n\t\t * (E5 Section 12.6.4, step 3).  Note that INITENUM requires the value to be in a\n\t\t * register (constant not allowed).\n\t\t */\n\n\t\tpc_l2 = duk__get_current_pc(comp_ctx);\n\t\treg_target = duk__exprtop_toreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);  /* Expression */\n\t\tduk__emit_b_c(comp_ctx,\n\t\t              DUK_OP_INITENUM | DUK__EMIT_FLAG_B_IS_TARGET,\n\t\t              reg_temps + 1,\n\t\t              reg_target);\n\t\tpc_jumpto_l4 = duk__emit_jump_empty(comp_ctx);\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\t\tpc_l3 = duk__get_current_pc(comp_ctx);\n\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\t\t/* temp reset is not necessary after duk__parse_stmt(), which already does it */\n\n\t\t/* NEXTENUM needs a jump slot right after the main opcode.\n\t\t * We need the code emitter to reserve the slot: if there's\n\t\t * target shuffling, the target shuffle opcodes must happen\n\t\t * after the jump slot (for NEXTENUM the shuffle opcodes are\n\t\t * not needed if the enum is finished).\n\t\t */\n\t\tpc_l4 = duk__get_current_pc(comp_ctx);\n\t\tduk__emit_b_c(comp_ctx,\n\t\t              DUK_OP_NEXTENUM | DUK__EMIT_FLAG_B_IS_TARGET | DUK__EMIT_FLAG_RESERVE_JUMPSLOT,\n\t\t              reg_temps + 0,\n\t\t              reg_temps + 1);\n\t\tpc_jumpto_l5 = comp_ctx->emit_jumpslot_pc;  /* NEXTENUM jump slot: executed when enum finished */\n\t\tduk__emit_jump(comp_ctx, pc_l1);  /* jump to next loop, using reg_v34_iter as iterated value */\n\n\t\tpc_l5 = duk__get_current_pc(comp_ctx);\n\n\t\t/* XXX: since the enumerator may be a memory expensive object,\n\t\t * perhaps clear it explicitly here?  If so, break jump must\n\t\t * go through this clearing operation.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"patching jumps: jumpto_l2: %ld->%ld, jumpto_l3: %ld->%ld, \"\n\t\t                     \"jumpto_l4: %ld->%ld, jumpto_l5: %ld->%ld, \"\n\t\t                     \"break: %ld->%ld, continue: %ld->%ld\",\n\t\t\t             (long) pc_jumpto_l2, (long) pc_l2, (long) pc_jumpto_l3, (long) pc_l3,\n\t\t\t             (long) pc_jumpto_l4, (long) pc_l4, (long) pc_jumpto_l5, (long) pc_l5,\n\t\t                     (long) (pc_label_site + 1), (long) pc_l5, (long) (pc_label_site + 2), (long) pc_l4));\n\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l2, pc_l2);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l3, pc_l3);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l4, pc_l4);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l5, pc_l5);\n\t\tduk__patch_jump(comp_ctx, pc_label_site + 1, pc_l5);  /* break jump */\n\t\tduk__patch_jump(comp_ctx, pc_label_site + 2, pc_l4);  /* continue jump */\n\t}\n\tgoto finished;\n\n finished:\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing a for/for-in statement\"));\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_FOR);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t temp_at_loop;\n\tduk_regconst_t rc_switch;    /* reg/const for switch value */\n\tduk_regconst_t rc_case;      /* reg/const for case value */\n\tduk_regconst_t reg_temp;     /* general temp register */\n\tduk_int_t pc_prevcase = -1;\n\tduk_int_t pc_prevstmt = -1;\n\tduk_int_t pc_default = -1;   /* -1 == not set, -2 == pending (next statement list) */\n\n\t/* Note: negative pc values are ignored when patching jumps, so no explicit checks needed */\n\n\t/*\n\t *  Switch is pretty complicated because of several conflicting concerns:\n\t *\n\t *    - Want to generate code without an intermediate representation,\n\t *      i.e., in one go\n\t *\n\t *    - Case selectors are expressions, not values, and may thus e.g. throw\n\t *      exceptions (which causes evaluation order concerns)\n\t *\n\t *    - Evaluation semantics of case selectors and default clause need to be\n\t *      carefully implemented to provide correct behavior even with case value\n\t *      side effects\n\t *\n\t *    - Fall through case and default clauses; avoiding dead JUMPs if case\n\t *      ends with an unconditional jump (a break or a continue)\n\t *\n\t *    - The same case value may occur multiple times, but evaluation rules\n\t *      only process the first match before switching to a \"propagation\" mode\n\t *      where case values are no longer evaluated\n\t *\n\t *  See E5 Section 12.11.  Also see doc/compiler.rst for compilation\n\t *  discussion.\n\t */\n\n\tduk__advance(comp_ctx);\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\trc_switch = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* RegExp mode does not matter. */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\n\tDUK_DDD(DUK_DDDPRINT(\"switch value in register %ld\", (long) rc_switch));\n\n\ttemp_at_loop = DUK__GETTEMP(comp_ctx);\n\n\tfor (;;) {\n\t\tduk_int_t num_stmts;\n\t\tduk_small_uint_t tok;\n\n\t\t/* sufficient for keeping temp reg numbers in check */\n\t\tDUK__SETTEMP(comp_ctx, temp_at_loop);\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\tbreak;\n\t\t}\n\n\t\t/*\n\t\t *  Parse a case or default clause.\n\t\t */\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_CASE) {\n\t\t\t/*\n\t\t\t *  Case clause.\n\t\t\t *\n\t\t\t *  Note: cannot use reg_case as a temp register (for SEQ target)\n\t\t\t *  because it may be a constant.\n\t\t\t */\n\n\t\t\tduk__patch_jump_here(comp_ctx, pc_prevcase);  /* chain jumps for case\n\t\t\t                                               * evaluation and checking\n\t\t\t                                               */\n\n\t\t\tduk__advance(comp_ctx);\n\t\t\trc_case = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_SEQ | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_temp,\n\t\t\t                rc_switch,\n\t\t\t                rc_case);\n\t\t\tduk__emit_if_true_skip(comp_ctx, reg_temp);\n\n\t\t\t/* jump to next case clause */\n\t\t\tpc_prevcase = duk__emit_jump_empty(comp_ctx);  /* no match, next case */\n\n\t\t\t/* statements go here (if any) on next loop */\n\t\t} else if (comp_ctx->curr_token.t == DUK_TOK_DEFAULT) {\n\t\t\t/*\n\t\t\t *  Default clause.\n\t\t\t */\n\n\t\t\tif (pc_default >= 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t\tduk__advance(comp_ctx);\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\n\t\t\t/* Fix for https://github.com/svaarala/duktape/issues/155:\n\t\t\t * If 'default' is first clause (detected by pc_prevcase < 0)\n\t\t\t * we need to ensure we stay in the matching chain.\n\t\t\t */\n\t\t\tif (pc_prevcase < 0) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"default clause is first, emit prevcase jump\"));\n\t\t\t\tpc_prevcase = duk__emit_jump_empty(comp_ctx);\n\t\t\t}\n\n\t\t\t/* default clause matches next statement list (if any) */\n\t\t\tpc_default = -2;\n\t\t} else {\n\t\t\t/* Code is not accepted before the first case/default clause */\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/*\n\t\t *  Parse code after the clause.  Possible terminators are\n\t\t *  'case', 'default', and '}'.\n\t\t *\n\t\t *  Note that there may be no code at all, not even an empty statement,\n\t\t *  between case clauses.  This must be handled just like an empty statement\n\t\t *  (omitting seemingly pointless JUMPs), to avoid situations like\n\t\t *  test-bug-case-fallthrough.js.\n\t\t */\n\n\t\tnum_stmts = 0;\n\t\tif (pc_default == -2) {\n\t\t\tpc_default = duk__get_current_pc(comp_ctx);\n\t\t}\n\n\t\t/* Note: this is correct even for default clause statements:\n\t\t * they participate in 'fall-through' behavior even if the\n\t\t * default clause is in the middle.\n\t\t */\n\t\tduk__patch_jump_here(comp_ctx, pc_prevstmt);  /* chain jumps for 'fall-through'\n\t\t                                               * after a case matches.\n\t\t                                               */\n\n\t\tfor (;;) {\n\t\t\ttok = comp_ctx->curr_token.t;\n\t\t\tif (tok == DUK_TOK_CASE || tok == DUK_TOK_DEFAULT ||\n\t\t\t    tok == DUK_TOK_RCURLY) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tnum_stmts++;\n\t\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\t\t}\n\n\t\t/* fall-through jump to next code of next case (backpatched) */\n\t\tpc_prevstmt = duk__emit_jump_empty(comp_ctx);\n\n\t\t/* XXX: would be nice to omit this jump when the jump is not\n\t\t * reachable, at least in the obvious cases (such as the case\n\t\t * ending with a 'break'.\n\t\t *\n\t\t * Perhaps duk__parse_stmt() could provide some info on whether\n\t\t * the statement is a \"dead end\"?\n\t\t *\n\t\t * If implemented, just set pc_prevstmt to -1 when not needed.\n\t\t */\n\t}\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RCURLY);\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance(comp_ctx);  /* Allow RegExp as part of next stmt. */\n\n\t/* default case control flow patchup; note that if pc_prevcase < 0\n\t * (i.e. no case clauses), control enters default case automatically.\n\t */\n\tif (pc_default >= 0) {\n\t\t/* default case exists: go there if no case matches */\n\t\tduk__patch_jump(comp_ctx, pc_prevcase, pc_default);\n\t} else {\n\t\t/* default case does not exist, or no statements present\n\t\t * after default case: finish case evaluation\n\t\t */\n\t\tduk__patch_jump_here(comp_ctx, pc_prevcase);\n\t}\n\n\t/* fall-through control flow patchup; note that pc_prevstmt may be\n\t * < 0 (i.e. no case clauses), in which case this is a no-op.\n\t */\n\tduk__patch_jump_here(comp_ctx, pc_prevstmt);\n\n\t/* continue jump not patched, an INVALID opcode remains there */\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 1);  /* break jump */\n\n\t/* Note: 'fast' breaks will jump to pc_label_site + 1, which will\n\t * then jump here.  The double jump will be eliminated by a\n\t * peephole pass, resulting in an optimal jump here.  The label\n\t * site jumps will remain in bytecode and will waste code size.\n\t */\n\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_SWITCH);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_if_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_regconst_t temp_reset;\n\tduk_regconst_t rc_cond;\n\tduk_int_t pc_jump_false;\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin parsing if statement\"));\n\n\ttemp_reset = DUK__GETTEMP(comp_ctx);\n\n\tduk__advance(comp_ctx);  /* eat 'if' */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\trc_cond = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_if_true_skip(comp_ctx, rc_cond);\n\tpc_jump_false = duk__emit_jump_empty(comp_ctx);  /* jump to end or else part */\n\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\n\t/* The 'else' ambiguity is resolved by 'else' binding to the innermost\n\t * construct, so greedy matching is correct here.\n\t */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_ELSE) {\n\t\tduk_int_t pc_jump_end;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"if has else part\"));\n\n\t\tduk__advance(comp_ctx);\n\n\t\tpc_jump_end = duk__emit_jump_empty(comp_ctx);  /* jump from true part to end */\n\t\tduk__patch_jump_here(comp_ctx, pc_jump_false);\n\n\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\n\t\tduk__patch_jump_here(comp_ctx, pc_jump_end);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"if does not have else part\"));\n\n\t\tduk__patch_jump_here(comp_ctx, pc_jump_false);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing if statement\"));\n}\n\nDUK_LOCAL void duk__parse_do_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_regconst_t rc_cond;\n\tduk_int_t pc_start;\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin parsing do statement\"));\n\n\tduk__advance(comp_ctx);  /* Eat 'do'; allow RegExp as part of next stmt. */\n\n\tpc_start = duk__get_current_pc(comp_ctx);\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 2);  /* continue jump */\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_WHILE);\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\trc_cond = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_if_false_skip(comp_ctx, rc_cond);\n\tduk__emit_jump(comp_ctx, pc_start);\n\t/* no need to reset temps, as we're finished emitting code */\n\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;  /* Allow RegExp as part of next stmt. */\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);\n\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 1);  /* break jump */\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing do statement\"));\n}\n\nDUK_LOCAL void duk__parse_while_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_regconst_t temp_reset;\n\tduk_regconst_t rc_cond;\n\tduk_int_t pc_start;\n\tduk_int_t pc_jump_false;\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin parsing while statement\"));\n\n\ttemp_reset = DUK__GETTEMP(comp_ctx);\n\n\tduk__advance(comp_ctx);  /* eat 'while' */\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\tpc_start = duk__get_current_pc(comp_ctx);\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 2);  /* continue jump */\n\n\trc_cond = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_if_true_skip(comp_ctx, rc_cond);\n\tpc_jump_false = duk__emit_jump_empty(comp_ctx);\n\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\tduk__emit_jump(comp_ctx, pc_start);\n\n\tduk__patch_jump_here(comp_ctx, pc_jump_false);\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 1);  /* break jump */\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing while statement\"));\n}\n\nDUK_LOCAL void duk__parse_break_or_continue_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t is_break = (comp_ctx->curr_token.t == DUK_TOK_BREAK);\n\tduk_int_t label_id;\n\tduk_int_t label_catch_depth;\n\tduk_int_t label_pc;  /* points to LABEL; pc+1 = jump site for break; pc+2 = jump site for continue */\n\tduk_bool_t label_is_closest;\n\n\tDUK_UNREF(res);\n\n\tduk__advance(comp_ctx);  /* eat 'break' or 'continue' */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON ||  /* explicit semi follows */\n\t    comp_ctx->curr_token.lineterm ||                /* automatic semi will be inserted */\n\t    comp_ctx->curr_token.allow_auto_semi) {         /* automatic semi will be inserted */\n\t\t/* break/continue without label */\n\n\t\tduk__lookup_active_label(comp_ctx, DUK_HTHREAD_STRING_EMPTY_STRING(thr), is_break, &label_id, &label_catch_depth, &label_pc, &label_is_closest);\n\t} else if (comp_ctx->curr_token.t == DUK_TOK_IDENTIFIER) {\n\t\t/* break/continue with label (label cannot be a reserved word, production is 'Identifier' */\n\t\tDUK_ASSERT(comp_ctx->curr_token.str1 != NULL);\n\t\tduk__lookup_active_label(comp_ctx, comp_ctx->curr_token.str1, is_break, &label_id, &label_catch_depth, &label_pc, &label_is_closest);\n\t\tduk__advance(comp_ctx);\n\t} else {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_BREAK_CONT_LABEL);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* Use a fast break/continue when possible.  A fast break/continue is\n\t * just a jump to the LABEL break/continue jump slot, which then jumps\n\t * to an appropriate place (for break, going through ENDLABEL correctly).\n\t * The peephole optimizer will optimize the jump to a direct one.\n\t */\n\n\tif (label_catch_depth == comp_ctx->curr_func.catch_depth &&\n\t    label_is_closest) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"break/continue: is_break=%ld, label_id=%ld, label_is_closest=%ld, \"\n\t\t                     \"label_catch_depth=%ld, catch_depth=%ld \"\n\t\t                     \"-> use fast variant (direct jump)\",\n\t\t                     (long) is_break, (long) label_id, (long) label_is_closest,\n\t\t                     (long) label_catch_depth, (long) comp_ctx->curr_func.catch_depth));\n\n\t\tduk__emit_jump(comp_ctx, label_pc + (is_break ? 1 : 2));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"break/continue: is_break=%ld, label_id=%ld, label_is_closest=%ld, \"\n\t\t                     \"label_catch_depth=%ld, catch_depth=%ld \"\n\t\t                     \"-> use slow variant (longjmp)\",\n\t\t                     (long) is_break, (long) label_id, (long) label_is_closest,\n\t\t                     (long) label_catch_depth, (long) comp_ctx->curr_func.catch_depth));\n\n\t\tduk__emit_bc(comp_ctx,\n\t\t             is_break ? DUK_OP_BREAK : DUK_OP_CONTINUE,\n\t\t             (duk_regconst_t) label_id);\n\t}\n}\n\nDUK_LOCAL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t rc_val;\n\n\tduk__advance(comp_ctx);  /* eat 'return' */\n\n\t/* A 'return' statement is only allowed inside an actual function body,\n\t * not as part of eval or global code.\n\t */\n\tif (!comp_ctx->curr_func.is_function) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_RETURN);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON ||  /* explicit semi follows */\n\t    comp_ctx->curr_token.lineterm ||                /* automatic semi will be inserted */\n\t    comp_ctx->curr_token.allow_auto_semi) {         /* automatic semi will be inserted */\n\t\tDUK_DDD(DUK_DDDPRINT(\"empty return value -> undefined\"));\n\t\tduk__emit_op_only(comp_ctx, DUK_OP_RETUNDEF);\n\t} else {\n\t\tduk_int_t pc_before_expr;\n\t\tduk_int_t pc_after_expr;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"return with a value\"));\n\n\t\tDUK_UNREF(pc_before_expr);\n\t\tDUK_UNREF(pc_after_expr);\n\n\t\tpc_before_expr = duk__get_current_pc(comp_ctx);\n\t\trc_val = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\t\tpc_after_expr = duk__get_current_pc(comp_ctx);\n\n\t\t/* Tail call check: if last opcode emitted was CALL, and\n\t\t * the context allows it, add a tailcall flag to the CALL.\n\t\t * This doesn't guarantee that a tail call will be allowed at\n\t\t * runtime, so the RETURN must still be emitted.  (Duktape\n\t\t * 0.10.0 avoided this and simulated a RETURN if a tail call\n\t\t * couldn't be used at runtime; but this didn't work\n\t\t * correctly with a thread yield/resume, see\n\t\t * test-bug-tailcall-thread-yield-resume.js for discussion.)\n\t\t *\n\t\t * In addition to the last opcode being CALL, we also need to\n\t\t * be sure that 'rc_val' is the result register of the CALL.\n\t\t * For instance, for the expression 'return 0, (function ()\n\t\t * { return 1; }), 2' the last opcode emitted is CALL (no\n\t\t * bytecode is emitted for '2') but 'rc_val' indicates\n\t\t * constant '2'.  Similarly if '2' is replaced by a register\n\t\t * bound variable, no opcodes are emitted but tail call would\n\t\t * be incorrect.\n\t\t *\n\t\t * This is tricky and easy to get wrong.  It would be best to\n\t\t * track enough expression metadata to check that 'rc_val' came\n\t\t * from that last CALL instruction.  We don't have that metadata\n\t\t * now, so we check that 'rc_val' is a temporary register result\n\t\t * (not a constant or a register bound variable).  There should\n\t\t * be no way currently for 'rc_val' to be a temporary for an\n\t\t * expression following the CALL instruction without emitting\n\t\t * some opcodes following the CALL.  This proxy check is used\n\t\t * below.\n\t\t *\n\t\t * See: test-bug-comma-expr-gh131.js.\n\t\t *\n\t\t * The non-standard 'caller' property disables tail calls\n\t\t * because they pose some special cases which haven't been\n\t\t * fixed yet.\n\t\t */\n\n#if defined(DUK_USE_TAILCALL)\n\t\tif (comp_ctx->curr_func.catch_depth == 0 &&   /* no catchers */\n\t\t    pc_after_expr > pc_before_expr) {         /* at least one opcode emitted */\n\t\t\tduk_compiler_instr *instr;\n\t\t\tduk_instr_t ins;\n\t\t\tduk_small_uint_t op;\n\n\t\t\tinstr = duk__get_instr_ptr(comp_ctx, pc_after_expr - 1);\n\t\t\tDUK_ASSERT(instr != NULL);\n\n\t\t\tins = instr->ins;\n\t\t\top = (duk_small_uint_t) DUK_DEC_OP(ins);\n\t\t\tif ((op & ~0x0fU) == DUK_OP_CALL0 &&\n\t\t\t    DUK__ISREG_TEMP(comp_ctx, rc_val) /* see above */) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"return statement detected a tail call opportunity: \"\n\t\t\t\t                     \"catch depth is 0, duk__exprtop() emitted >= 1 instructions, \"\n\t\t\t\t                     \"and last instruction is a CALL \"\n\t\t\t\t                     \"-> change to TAILCALL\"));\n\t\t\t\tins |= DUK_ENC_OP(DUK_BC_CALL_FLAG_TAILCALL);\n\t\t\t\tinstr->ins = ins;\n\t\t\t}\n\t\t}\n#endif  /* DUK_USE_TAILCALL */\n\n\t\tif (DUK__ISREG(rc_val)) {\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_RETREG, rc_val);\n\t\t} else {\n\t\t\trc_val = DUK__REMOVECONST(rc_val);\n\t\t\tif (duk__const_needs_refcount(comp_ctx, rc_val)) {\n\t\t\t\tduk__emit_bc(comp_ctx, DUK_OP_RETCONST, rc_val);\n\t\t\t} else {\n\t\t\t\tduk__emit_bc(comp_ctx, DUK_OP_RETCONSTN, rc_val);\n\t\t\t}\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__parse_throw_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_regconst_t reg_val;\n\n\tduk__advance(comp_ctx);  /* eat 'throw' */\n\n\t/* Unlike break/continue, throw statement does not allow an empty value. */\n\n\tif (comp_ctx->curr_token.lineterm) {\n\t\tDUK_ERROR_SYNTAX(comp_ctx->thr, DUK_STR_INVALID_THROW);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\treg_val = duk__exprtop_toreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_bc(comp_ctx,\n\t             DUK_OP_THROW,\n\t             reg_val);\n}\n\nDUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg_catch;      /* reg_catch+0 and reg_catch+1 are reserved for TRYCATCH */\n\tduk_regconst_t rc_varname = 0;\n\tduk_small_uint_t trycatch_flags = 0;\n\tduk_int_t pc_ldconst = -1;\n\tduk_int_t pc_trycatch = -1;\n\tduk_int_t pc_catch = -1;\n\tduk_int_t pc_finally = -1;\n\n\tDUK_UNREF(res);\n\n\t/*\n\t *  See the following documentation for discussion:\n\t *\n\t *    doc/execution.rst: control flow details\n\t *\n\t *  Try, catch, and finally \"parts\" are Blocks, not Statements, so\n\t *  they must always be delimited by curly braces.  This is unlike e.g.\n\t *  the if statement, which accepts any Statement.  This eliminates any\n\t *  questions of matching parts of nested try statements.  The Block\n\t *  parsing is implemented inline here (instead of calling out).\n\t *\n\t *  Finally part has a 'let scoped' variable, which requires a few kinks\n\t *  here.\n\t */\n\n\tcomp_ctx->curr_func.catch_depth++;\n\n\tduk__advance(comp_ctx);  /* eat 'try' */\n\n\treg_catch = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\t/* The target for this LDCONST may need output shuffling, but we assume\n\t * that 'pc_ldconst' will be the LDCONST that we can patch later.  This\n\t * should be the case because there's no input shuffling.  (If there's\n\t * no catch clause, this LDCONST will be replaced with a NOP.)\n\t */\n\tpc_ldconst = duk__get_current_pc(comp_ctx);\n\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, reg_catch, 0 /*patched later*/);\n\n\tpc_trycatch = duk__get_current_pc(comp_ctx);\n\tduk__emit_invalid(comp_ctx);  /* TRYCATCH, cannot emit now (not enough info) */\n\tduk__emit_invalid(comp_ctx);  /* jump for 'catch' case */\n\tduk__emit_invalid(comp_ctx);  /* jump for 'finally' case or end (if no finally) */\n\n\t/* try part */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\tduk__emit_op_only(comp_ctx, DUK_OP_ENDTRY);\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_CATCH) {\n\t\t/*\n\t\t *  The catch variable must be updated to reflect the new allocated\n\t\t *  register for the duration of the catch clause.  We need to store\n\t\t *  and restore the original value for the varmap entry (if any).\n\t\t */\n\n\t\t/*\n\t\t *  Note: currently register bindings must be fixed for the entire\n\t\t *  function.  So, even though the catch variable is in a register\n\t\t *  we know, we must use an explicit environment record and slow path\n\t\t *  accesses to read/write the catch binding to make closures created\n\t\t *  within the catch clause work correctly.  This restriction should\n\t\t *  be fixable (at least in common cases) later.\n\t\t *\n\t\t *  See: test-bug-catch-binding-2.js.\n\t\t *\n\t\t *  XXX: improve to get fast path access to most catch clauses.\n\t\t */\n\n\t\tduk_hstring *h_var;\n\t\tduk_int_t varmap_value;  /* for storing/restoring the varmap binding for catch variable */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"stack top at start of catch clause: %ld\", (long) duk_get_top(thr)));\n\n\t\ttrycatch_flags |= DUK_BC_TRYCATCH_FLAG_HAVE_CATCH;\n\n\t\tpc_catch = duk__get_current_pc(comp_ctx);\n\n\t\tduk__advance(comp_ctx);\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\t\tif (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) {\n\t\t\t/* Identifier, i.e. don't allow reserved words */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\th_var = comp_ctx->curr_token.str1;\n\t\tDUK_ASSERT(h_var != NULL);\n\n\t\tduk_push_hstring(thr, h_var);  /* keep in on valstack, use borrowed ref below */\n\n\t\tif (comp_ctx->curr_func.is_strict &&\n\t\t    ((h_var == DUK_HTHREAD_STRING_EVAL(thr)) ||\n\t\t     (h_var == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)))) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"catch identifier 'eval' or 'arguments' in strict mode -> SyntaxError\"));\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\tduk_dup_top(thr);\n\t\trc_varname = duk__getconst(comp_ctx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"catch clause, rc_varname=0x%08lx (%ld)\",\n\t\t                     (unsigned long) rc_varname, (long) rc_varname));\n\n\t\tduk__advance(comp_ctx);\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"varmap before modifying for catch clause: %!iT\",\n\t\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));\n\n\t\tduk_dup_top(thr);\n\t\tduk_get_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\tvarmap_value = -2;\n\t\t} else if (duk_is_null(thr, -1)) {\n\t\t\tvarmap_value = -1;\n\t\t} else {\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tvarmap_value = duk_get_int(thr, -1);\n\t\t\tDUK_ASSERT(varmap_value >= 0);\n\t\t}\n\t\tduk_pop(thr);\n\n#if 0\n\t\t/* It'd be nice to do something like this - but it doesn't\n\t\t * work for closures created inside the catch clause.\n\t\t */\n\t\tduk_dup_top(thr);\n\t\tduk_push_int(thr, (duk_int_t) (reg_catch + 0));\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);\n#endif\n\t\tduk_dup_top(thr);\n\t\tduk_push_null(thr);\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t               reg_catch + 0 /*value*/,\n\t\t               rc_varname /*varname*/);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"varmap before parsing catch clause: %!iT\",\n\t\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));\n\n\t\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\n\t\tif (varmap_value == -2) {\n\t\t\t/* not present */\n\t\t\tduk_del_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\t} else {\n\t\t\tif (varmap_value == -1) {\n\t\t\t\tduk_push_null(thr);\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(varmap_value >= 0);\n\t\t\t\tduk_push_int(thr, varmap_value);\n\t\t\t}\n\t\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\t}\n\t\t/* varname is popped by above code */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"varmap after restore catch clause: %!iT\",\n\t\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));\n\n\t\tduk__emit_op_only(comp_ctx,\n\t\t                  DUK_OP_ENDCATCH);\n\n\t\t/*\n\t\t *  XXX: for now, indicate that an expensive catch binding\n\t\t *  declarative environment is always needed.  If we don't\n\t\t *  need it, we don't need the const_varname either.\n\t\t */\n\n\t\ttrycatch_flags |= DUK_BC_TRYCATCH_FLAG_CATCH_BINDING;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"stack top at end of catch clause: %ld\", (long) duk_get_top(thr)));\n\t}\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_FINALLY) {\n\t\ttrycatch_flags |= DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY;\n\n\t\tpc_finally = duk__get_current_pc(comp_ctx);\n\n\t\tduk__advance(comp_ctx);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\t\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\t\tduk__emit_abc(comp_ctx,\n\t\t              DUK_OP_ENDFIN,\n\t\t              reg_catch);  /* rethrow */\n\t}\n\n\tif (!(trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) &&\n\t    !(trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY)) {\n\t\t/* must have catch and/or finally */\n\t\tgoto syntax_error;\n\t}\n\n\t/* If there's no catch block, rc_varname will be 0 and duk__patch_trycatch()\n\t * will replace the LDCONST with a NOP.  For any actual constant (including\n\t * constant 0) the DUK__CONST_MARKER flag will be set in rc_varname.\n\t */\n\n\tduk__patch_trycatch(comp_ctx,\n\t                    pc_ldconst,\n\t                    pc_trycatch,\n\t                    reg_catch,\n\t                    rc_varname,\n\t                    trycatch_flags);\n\n\tif (trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) {\n\t\tDUK_ASSERT(pc_catch >= 0);\n\t\tduk__patch_jump(comp_ctx, pc_trycatch + 1, pc_catch);\n\t}\n\n\tif (trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY) {\n\t\tDUK_ASSERT(pc_finally >= 0);\n\t\tduk__patch_jump(comp_ctx, pc_trycatch + 2, pc_finally);\n\t} else {\n\t\t/* without finally, the second jump slot is used to jump to end of stmt */\n\t\tduk__patch_jump_here(comp_ctx, pc_trycatch + 2);\n\t}\n\n\tcomp_ctx->curr_func.catch_depth--;\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_TRY);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_int_t pc_trycatch;\n\tduk_int_t pc_finished;\n\tduk_regconst_t reg_catch;\n\tduk_small_uint_t trycatch_flags;\n\n\tif (comp_ctx->curr_func.is_strict) {\n\t\tDUK_ERROR_SYNTAX(comp_ctx->thr, DUK_STR_WITH_IN_STRICT_MODE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tcomp_ctx->curr_func.catch_depth++;\n\n\tduk__advance(comp_ctx);  /* eat 'with' */\n\n\treg_catch = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\tduk__exprtop_toforcedreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/, reg_catch);\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\tpc_trycatch = duk__get_current_pc(comp_ctx);\n\ttrycatch_flags = DUK_BC_TRYCATCH_FLAG_WITH_BINDING;\n\tduk__emit_a_bc(comp_ctx,\n\t                DUK_OP_TRYCATCH | DUK__EMIT_FLAG_NO_SHUFFLE_A,\n\t                (duk_regconst_t) trycatch_flags /*a*/,\n\t                reg_catch /*bc*/);\n\tduk__emit_invalid(comp_ctx);  /* catch jump */\n\tduk__emit_invalid(comp_ctx);  /* finished jump */\n\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\tduk__emit_op_only(comp_ctx, DUK_OP_ENDTRY);\n\n\tpc_finished = duk__get_current_pc(comp_ctx);\n\n\tduk__patch_jump(comp_ctx, pc_trycatch + 2, pc_finished);\n\n\tcomp_ctx->curr_func.catch_depth--;\n}\n\nDUK_LOCAL duk_int_t duk__stmt_label_site(duk_compiler_ctx *comp_ctx, duk_int_t label_id) {\n\t/* if a site already exists, nop: max one label site per statement */\n\tif (label_id >= 0) {\n\t\treturn label_id;\n\t}\n\n\tlabel_id = comp_ctx->curr_func.label_next++;\n\tDUK_DDD(DUK_DDDPRINT(\"allocated new label id for label site: %ld\", (long) label_id));\n\n\tduk__emit_bc(comp_ctx,\n\t             DUK_OP_LABEL,\n\t             (duk_regconst_t) label_id);\n\tduk__emit_invalid(comp_ctx);\n\tduk__emit_invalid(comp_ctx);\n\n\treturn label_id;\n}\n\n/* Parse a single statement.\n *\n * Creates a label site (with an empty label) automatically for iteration\n * statements.  Also \"peels off\" any label statements for explicit labels.\n */\nDUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_bool_t allow_source_elem) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t dir_prol_at_entry;    /* directive prologue status at entry */\n\tduk_regconst_t temp_at_entry;\n\tduk_size_t labels_len_at_entry;\n\tduk_int_t pc_at_entry;           /* assumed to also be PC of \"LABEL\" */\n\tduk_int_t stmt_id;\n\tduk_small_uint_t stmt_flags = 0;\n\tduk_int_t label_id = -1;\n\tduk_small_uint_t tok;\n\tduk_bool_t test_func_decl;\n\n\tDUK__RECURSION_INCREASE(comp_ctx, thr);\n\n\ttemp_at_entry = DUK__GETTEMP(comp_ctx);\n\tpc_at_entry = duk__get_current_pc(comp_ctx);\n\tlabels_len_at_entry = duk_get_length(thr, comp_ctx->curr_func.labelnames_idx);\n\tstmt_id = comp_ctx->curr_func.stmt_next++;\n\tdir_prol_at_entry = comp_ctx->curr_func.in_directive_prologue;\n\n\tDUK_UNREF(stmt_id);\n\n\tDUK_DDD(DUK_DDDPRINT(\"parsing a statement, stmt_id=%ld, temp_at_entry=%ld, labels_len_at_entry=%ld, \"\n\t                     \"is_strict=%ld, in_directive_prologue=%ld, catch_depth=%ld\",\n\t                     (long) stmt_id, (long) temp_at_entry, (long) labels_len_at_entry,\n\t                     (long) comp_ctx->curr_func.is_strict, (long) comp_ctx->curr_func.in_directive_prologue,\n\t                     (long) comp_ctx->curr_func.catch_depth));\n\n\t/* The directive prologue flag is cleared by default so that it is\n\t * unset for any recursive statement parsing.  It is only \"revived\"\n\t * if a directive is detected.  (We could also make directives only\n\t * allowed if 'allow_source_elem' was true.)\n\t */\n\tcomp_ctx->curr_func.in_directive_prologue = 0;\n\n retry_parse:\n\n\tDUK_DDD(DUK_DDDPRINT(\"try stmt parse, stmt_id=%ld, label_id=%ld, allow_source_elem=%ld, catch_depth=%ld\",\n\t                     (long) stmt_id, (long) label_id, (long) allow_source_elem,\n\t                     (long) comp_ctx->curr_func.catch_depth));\n\n\t/*\n\t *  Detect iteration statements; if encountered, establish an\n\t *  empty label.\n\t */\n\n\ttok = comp_ctx->curr_token.t;\n\tif (tok == DUK_TOK_FOR || tok == DUK_TOK_DO || tok == DUK_TOK_WHILE ||\n\t    tok == DUK_TOK_SWITCH) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"iteration/switch statement -> add empty label\"));\n\n\t\tlabel_id = duk__stmt_label_site(comp_ctx, label_id);\n\t\tduk__add_label(comp_ctx,\n\t\t               DUK_HTHREAD_STRING_EMPTY_STRING(thr),\n\t\t               pc_at_entry /*pc_label*/,\n\t\t               label_id);\n\t}\n\n\t/*\n\t *  Main switch for statement / source element type.\n\t */\n\n\tswitch (comp_ctx->curr_token.t) {\n\tcase DUK_TOK_FUNCTION: {\n\t\t/*\n\t\t *  Function declaration, function expression, or (non-standard)\n\t\t *  function statement.\n\t\t *\n\t\t *  The E5 specification only allows function declarations at\n\t\t *  the top level (in \"source elements\").  An ExpressionStatement\n\t\t *  is explicitly not allowed to begin with a \"function\" keyword\n\t\t *  (E5 Section 12.4).  Hence any non-error semantics for such\n\t\t *  non-top-level statements are non-standard.  Duktape semantics\n\t\t *  for function statements are modelled after V8, see\n\t\t *  test-dev-func-decl-outside-top.js.\n\t\t */\n\t\ttest_func_decl = allow_source_elem;\n#if defined(DUK_USE_NONSTD_FUNC_STMT)\n\t\t/* Lenient: allow function declarations outside top level in\n\t\t * non-strict mode but reject them in strict mode.\n\t\t */\n\t\ttest_func_decl = test_func_decl || !comp_ctx->curr_func.is_strict;\n#endif  /* DUK_USE_NONSTD_FUNC_STMT */\n\t\t/* Strict: never allow function declarations outside top level. */\n\t\tif (test_func_decl) {\n\t\t\t/* FunctionDeclaration: not strictly a statement but handled as such.\n\t\t\t *\n\t\t\t * O(depth^2) parse count for inner functions is handled by recording a\n\t\t\t * lexer offset on the first compilation pass, so that the function can\n\t\t\t * be efficiently skipped on the second pass.  This is encapsulated into\n\t\t\t * duk__parse_func_like_fnum().\n\t\t\t */\n\n\t\t\tduk_int_t fnum;\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\tduk_idx_t top_before;\n#endif\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function declaration statement\"));\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\ttop_before = duk_get_top(thr);\n#endif\n\n\t\t\tduk__advance(comp_ctx);  /* eat 'function' */\n\t\t\tfnum = duk__parse_func_like_fnum(comp_ctx, DUK__FUNC_FLAG_DECL | DUK__FUNC_FLAG_PUSHNAME_PASS1);\n\n\t\t\t/* The value stack convention here is a bit odd: the function\n\t\t\t * name is only pushed on pass 1 (in_scanning), and is needed\n\t\t\t * to process function declarations.\n\t\t\t */\n\t\t\tif (comp_ctx->curr_func.in_scanning) {\n\t\t\t\tduk_uarridx_t n;\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t\tDUK_ASSERT(duk_get_top(thr) == top_before + 1);\n#endif\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"register function declaration %!T in pass 1, fnum %ld\",\n\t\t\t\t                     duk_get_tval(thr, -1), (long) fnum));\n\t\t\t\tn = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.decls_idx);\n\t\t\t\t/* funcname is at index -1 */\n\t\t\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n);\n\t\t\t\tduk_push_int(thr, (duk_int_t) (DUK_DECL_TYPE_FUNC + (fnum << 8)));\n\t\t\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n + 1);\n\t\t\t} else {\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t\tDUK_ASSERT(duk_get_top(thr) == top_before);\n#endif\n\t\t\t}\n\n\t\t\t/* no statement value (unlike function expression) */\n\t\t\tstmt_flags = 0;\n\t\t\tbreak;\n\t\t} else {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_FUNC_STMT_NOT_ALLOWED);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TOK_LCURLY: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"block statement\"));\n\t\tduk__advance(comp_ctx);\n\t\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\t\tif (label_id >= 0) {\n\t\t\tduk__patch_jump_here(comp_ctx, pc_at_entry + 1);  /* break jump */\n\t\t}\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_CONST: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"constant declaration statement\"));\n\t\tduk__parse_var_stmt(comp_ctx, res, DUK__EXPR_FLAG_REQUIRE_INIT /*expr_flags*/);\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_VAR: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"variable declaration statement\"));\n\t\tduk__parse_var_stmt(comp_ctx, res, 0 /*expr_flags*/);\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_SEMICOLON: {\n\t\t/* empty statement with an explicit semicolon */\n\t\tDUK_DDD(DUK_DDDPRINT(\"empty statement\"));\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_IF: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"if statement\"));\n\t\tduk__parse_if_stmt(comp_ctx, res);\n\t\tif (label_id >= 0) {\n\t\t\tduk__patch_jump_here(comp_ctx, pc_at_entry + 1);  /* break jump */\n\t\t}\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_DO: {\n\t\t/*\n\t\t *  Do-while statement is mostly trivial, but there is special\n\t\t *  handling for automatic semicolon handling (triggered by the\n\t\t *  DUK__ALLOW_AUTO_SEMI_ALWAYS) flag related to a bug filed at:\n\t\t *\n\t\t *    https://bugs.ecmascript.org/show_bug.cgi?id=8\n\t\t *\n\t\t *  See doc/compiler.rst for details.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"do statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK | DUK_LABEL_FLAG_ALLOW_CONTINUE);\n\t\tduk__parse_do_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__ALLOW_AUTO_SEMI_ALWAYS;  /* DUK__ALLOW_AUTO_SEMI_ALWAYS workaround */\n\t\tbreak;\n\t}\n\tcase DUK_TOK_WHILE: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"while statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK | DUK_LABEL_FLAG_ALLOW_CONTINUE);\n\t\tduk__parse_while_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_FOR: {\n\t\t/*\n\t\t *  For/for-in statement is complicated to parse because\n\t\t *  determining the statement type (three-part for vs. a\n\t\t *  for-in) requires potential backtracking.\n\t\t *\n\t\t *  See the helper for the messy stuff.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"for/for-in statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK | DUK_LABEL_FLAG_ALLOW_CONTINUE);\n\t\tduk__parse_for_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_CONTINUE:\n\tcase DUK_TOK_BREAK: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"break/continue statement\"));\n\t\tduk__parse_break_or_continue_stmt(comp_ctx, res);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__IS_TERMINAL;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_RETURN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"return statement\"));\n\t\tduk__parse_return_stmt(comp_ctx, res);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__IS_TERMINAL;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_WITH: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"with statement\"));\n\t\tcomp_ctx->curr_func.with_depth++;\n\t\tduk__parse_with_stmt(comp_ctx, res);\n\t\tif (label_id >= 0) {\n\t\t\tduk__patch_jump_here(comp_ctx, pc_at_entry + 1);  /* break jump */\n\t\t}\n\t\tcomp_ctx->curr_func.with_depth--;\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_SWITCH: {\n\t\t/*\n\t\t *  The switch statement is pretty messy to compile.\n\t\t *  See the helper for details.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"switch statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK);  /* don't allow continue */\n\t\tduk__parse_switch_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_THROW: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"throw statement\"));\n\t\tduk__parse_throw_stmt(comp_ctx, res);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__IS_TERMINAL;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_TRY: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"try statement\"));\n\t\tduk__parse_try_stmt(comp_ctx, res);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_DEBUGGER: {\n\t\tduk__advance(comp_ctx);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tDUK_DDD(DUK_DDDPRINT(\"debugger statement: debugging enabled, emit debugger opcode\"));\n\t\tduk__emit_op_only(comp_ctx, DUK_OP_DEBUGGER);\n#else\n\t\tDUK_DDD(DUK_DDDPRINT(\"debugger statement: ignored\"));\n#endif\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tdefault: {\n\t\t/*\n\t\t *  Else, must be one of:\n\t\t *    - ExpressionStatement, possibly a directive (String)\n\t\t *    - LabelledStatement (Identifier followed by ':')\n\t\t *\n\t\t *  Expressions beginning with 'function' keyword are covered by a case\n\t\t *  above (such expressions are not allowed in standard E5 anyway).\n\t\t *  Also expressions starting with '{' are interpreted as block\n\t\t *  statements.  See E5 Section 12.4.\n\t\t *\n\t\t *  Directive detection is tricky; see E5 Section 14.1 on directive\n\t\t *  prologue.  A directive is an expression statement with a single\n\t\t *  string literal and an explicit or automatic semicolon.  Escape\n\t\t *  characters are significant and no parens etc are allowed:\n\t\t *\n\t\t *    'use strict';          // valid 'use strict' directive\n\t\t *    'use\\u0020strict';     // valid directive, not a 'use strict' directive\n\t\t *    ('use strict');        // not a valid directive\n\t\t *\n\t\t *  The expression is determined to consist of a single string literal\n\t\t *  based on duk__expr_nud() and duk__expr_led() call counts.  The string literal\n\t\t *  of a 'use strict' directive is determined to lack any escapes based\n\t\t *  num_escapes count from the lexer.  Note that other directives may be\n\t\t *  allowed to contain escapes, so a directive with escapes does not\n\t\t *  terminate a directive prologue.\n\t\t *\n\t\t *  We rely on the fact that the expression parser will not emit any\n\t\t *  code for a single token expression.  However, it will generate an\n\t\t *  intermediate value which we will then successfully ignore.\n\t\t *\n\t\t *  A similar approach is used for labels.\n\t\t */\n\n\t\tduk_bool_t single_token;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"expression statement\"));\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\n\t\tsingle_token = (comp_ctx->curr_func.nud_count == 1 &&  /* one token */\n\t\t                comp_ctx->curr_func.led_count == 0);   /* no operators */\n\n\t\tif (single_token &&\n\t\t    comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t    comp_ctx->curr_token.t == DUK_TOK_COLON) {\n\t\t\t/*\n\t\t\t *  Detected label\n\t\t\t */\n\n\t\t\tduk_hstring *h_lab;\n\n\t\t\t/* expected ival */\n\t\t\tDUK_ASSERT(res->t == DUK_IVAL_VAR);\n\t\t\tDUK_ASSERT(res->x1.t == DUK_ISPEC_VALUE);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(duk_get_tval(thr, res->x1.valstack_idx)));\n\t\t\th_lab = comp_ctx->prev_token.str1;\n\t\t\tDUK_ASSERT(h_lab != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"explicit label site for label '%!O'\",\n\t\t\t                     (duk_heaphdr *) h_lab));\n\n\t\t\tduk__advance(comp_ctx);  /* eat colon */\n\n\t\t\tlabel_id = duk__stmt_label_site(comp_ctx, label_id);\n\n\t\t\tduk__add_label(comp_ctx,\n\t\t\t               h_lab,\n\t\t\t               pc_at_entry /*pc_label*/,\n\t\t\t               label_id);\n\n\t\t\t/* a statement following a label cannot be a source element\n\t\t\t * (a function declaration).\n\t\t\t */\n\t\t\tallow_source_elem = 0;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"label handled, retry statement parsing\"));\n\t\t\tgoto retry_parse;\n\t\t}\n\n\t\tstmt_flags = 0;\n\n\t\tif (dir_prol_at_entry &&                           /* still in prologue */\n\t\t    single_token &&                                /* single string token */\n\t\t    comp_ctx->prev_token.t == DUK_TOK_STRING) {\n\t\t\t/*\n\t\t\t *  Detected a directive\n\t\t\t */\n\t\t\tduk_hstring *h_dir;\n\n\t\t\t/* expected ival */\n\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN);\n\t\t\tDUK_ASSERT(res->x1.t == DUK_ISPEC_VALUE);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(duk_get_tval(thr, res->x1.valstack_idx)));\n\t\t\th_dir = comp_ctx->prev_token.str1;\n\t\t\tDUK_ASSERT(h_dir != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"potential directive: %!O\", h_dir));\n\n\t\t\tstmt_flags |= DUK__STILL_PROLOGUE;\n\n\t\t\t/* Note: escaped characters differentiate directives */\n\n\t\t\tif (comp_ctx->prev_token.num_escapes > 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"directive contains escapes: valid directive \"\n\t\t\t\t                     \"but we ignore such directives\"));\n\t\t\t} else {\n\t\t\t\t/*\n\t\t\t\t * The length comparisons are present to handle\n\t\t\t\t * strings like \"use strict\\u0000foo\" as required.\n\t\t\t\t */\n\n\t\t\t\tif (DUK_HSTRING_GET_BYTELEN(h_dir) == 10 &&\n\t\t\t\t    DUK_STRCMP((const char *) DUK_HSTRING_GET_DATA(h_dir), \"use strict\") == 0) {\n#if defined(DUK_USE_STRICT_DECL)\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"use strict directive detected: strict flag %ld -> %ld\",\n\t\t\t\t\t                     (long) comp_ctx->curr_func.is_strict, (long) 1));\n\t\t\t\t\tcomp_ctx->curr_func.is_strict = 1;\n#else\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"use strict detected but strict declarations disabled, ignoring\"));\n#endif\n\t\t\t\t} else if (DUK_HSTRING_GET_BYTELEN(h_dir) == 14 &&\n\t\t\t\t           DUK_STRCMP((const char *) DUK_HSTRING_GET_DATA(h_dir), \"use duk notail\") == 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"use duk notail directive detected: notail flag %ld -> %ld\",\n\t\t\t\t\t                     (long) comp_ctx->curr_func.is_notail, (long) 1));\n\t\t\t\t\tcomp_ctx->curr_func.is_notail = 1;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"unknown directive: '%!O', ignoring but not terminating \"\n\t\t\t\t\t                   \"directive prologue\", (duk_hobject *) h_dir));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-directive expression statement or no longer in prologue; \"\n\t\t\t                     \"prologue terminated if still active\"));\n                }\n\n\t\tstmt_flags |= DUK__HAS_VAL | DUK__HAS_TERM;\n\t}\n\t}  /* end switch (tok) */\n\n\t/*\n\t *  Statement value handling.\n\t *\n\t *  Global code and eval code has an implicit return value\n\t *  which comes from the last statement with a value\n\t *  (technically a non-\"empty\" continuation, which is\n\t *  different from an empty statement).\n\t *\n\t *  Since we don't know whether a later statement will\n\t *  override the value of the current statement, we need\n\t *  to coerce the statement value to a register allocated\n\t *  for implicit return values.  In other cases we need\n\t *  to coerce the statement value to a plain value to get\n\t *  any side effects out (consider e.g. \"foo.bar;\").\n\t */\n\n\t/* XXX: what about statements which leave a half-cooked value in 'res'\n\t * but have no stmt value?  Any such statements?\n\t */\n\n\tif (stmt_flags & DUK__HAS_VAL) {\n\t\tduk_regconst_t reg_stmt_value = comp_ctx->curr_func.reg_stmt_value;\n\t\tif (reg_stmt_value >= 0) {\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_stmt_value);\n\t\t} else {\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);\n\t\t}\n\t} else {\n\t\t;\n\t}\n\n\t/*\n\t *  Statement terminator check, including automatic semicolon\n\t *  handling.  After this step, 'curr_tok' should be the first\n\t *  token after a possible statement terminator.\n\t */\n\n\tif (stmt_flags & DUK__HAS_TERM) {\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"explicit semicolon terminates statement\"));\n\t\t\tduk__advance(comp_ctx);\n\t\t} else {\n\t\t\tif (comp_ctx->curr_token.allow_auto_semi) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"automatic semicolon terminates statement\"));\n\t\t\t} else if (stmt_flags & DUK__ALLOW_AUTO_SEMI_ALWAYS) {\n\t\t\t\t/* XXX: make this lenience dependent on flags or strictness? */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"automatic semicolon terminates statement (allowed for compatibility \"\n\t\t\t\t                     \"even though no lineterm present before next token)\"));\n\t\t\t} else {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_UNTERMINATED_STMT);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"statement has no terminator\"));\n\t}\n\n\t/*\n\t *  Directive prologue tracking.\n\t */\n\n\tif (stmt_flags & DUK__STILL_PROLOGUE) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"setting in_directive_prologue\"));\n\t\tcomp_ctx->curr_func.in_directive_prologue = 1;\n\t}\n\n\t/*\n\t *  Cleanups (all statement parsing flows through here).\n\t *\n\t *  Pop label site and reset labels.  Reset 'next temp' to value at\n\t *  entry to reuse temps.\n\t */\n\n\tif (label_id >= 0) {\n\t\tduk__emit_bc(comp_ctx,\n\t\t             DUK_OP_ENDLABEL,\n\t\t             (duk_regconst_t) label_id);\n\t}\n\n\tDUK__SETTEMP(comp_ctx, temp_at_entry);\n\n\tduk__reset_labels_to_length(comp_ctx, labels_len_at_entry);\n\n\t/* XXX: return indication of \"terminalness\" (e.g. a 'throw' is terminal) */\n\n\tDUK__RECURSION_DECREASE(comp_ctx, thr);\n}\n\n/*\n *  Parse a statement list.\n *\n *  Handles automatic semicolon insertion and implicit return value.\n *\n *  Upon entry, 'curr_tok' should contain the first token of the first\n *  statement (parsed in the \"allow regexp literal\" mode).  Upon exit,\n *  'curr_tok' contains the token following the statement list terminator\n *  (EOF or closing brace).\n */\n\nDUK_LOCAL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_source_elem, duk_bool_t expect_eof, duk_bool_t regexp_after) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_ivalue res_alloc;\n\tduk_ivalue *res = &res_alloc;\n\n\t/* Setup state.  Initial ivalue is 'undefined'. */\n\n\tduk_require_stack(thr, DUK__PARSE_STATEMENTS_SLOTS);\n\n\t/* XXX: 'res' setup can be moved to function body level; in fact, two 'res'\n\t * intermediate values suffice for parsing of each function.  Nesting is needed\n\t * for nested functions (which may occur inside expressions).\n\t */\n\n\tduk_memzero(&res_alloc, sizeof(res_alloc));\n\tres->t = DUK_IVAL_PLAIN;\n\tres->x1.t = DUK_ISPEC_VALUE;\n\tres->x1.valstack_idx = duk_get_top(thr);\n\tres->x2.valstack_idx = res->x1.valstack_idx + 1;\n\tduk_push_undefined(thr);\n\tduk_push_undefined(thr);\n\n\t/* Parse statements until a closing token (EOF or '}') is found. */\n\n\tfor (;;) {\n\t\t/* Check whether statement list ends. */\n\n\t\tif (expect_eof) {\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_EOF) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* Check statement type based on the first token type.\n\t\t *\n\t\t * Note: expression parsing helpers expect 'curr_tok' to\n\t\t * contain the first token of the expression upon entry.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"TOKEN %ld (non-whitespace, non-comment)\", (long) comp_ctx->curr_token.t));\n\n\t\tduk__parse_stmt(comp_ctx, res, allow_source_elem);\n\t}\n\n\t/* RegExp is allowed / not allowed depending on context.  For function\n\t * declarations RegExp is allowed because it follows a function\n\t * declaration statement and may appear as part of the next statement.\n\t * For function expressions RegExp is not allowed, and it's possible\n\t * to do something like '(function () {} / 123)'.\n\t */\n\tif (regexp_after) {\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t}\n\tduk__advance(comp_ctx);\n\n\t/* Tear down state. */\n\n\tduk_pop_2(thr);\n}\n\n/*\n *  Declaration binding instantiation conceptually happens when calling a\n *  function; for us it essentially means that function prologue.  The\n *  conceptual process is described in E5 Section 10.5.\n *\n *  We need to keep track of all encountered identifiers to (1) create an\n *  identifier-to-register map (\"varmap\"); and (2) detect duplicate\n *  declarations.  Identifiers which are not bound to registers still need\n *  to be tracked for detecting duplicates.  Currently such identifiers\n *  are put into the varmap with a 'null' value, which is later cleaned up.\n *\n *  To support functions with a large number of variable and function\n *  declarations, registers are not allocated beyond a certain limit;\n *  after that limit, variables and functions need slow path access.\n *  Arguments are currently always register bound, which imposes a hard\n *  (and relatively small) argument count limit.\n *\n *  Some bindings in E5 are not configurable (= deletable) and almost all\n *  are mutable (writable).  Exceptions are:\n *\n *    - The 'arguments' binding, established only if no shadowing argument\n *      or function declaration exists.  We handle 'arguments' creation\n *      and binding through an explicit slow path environment record.\n *\n *    - The \"name\" binding for a named function expression.  This is also\n *      handled through an explicit slow path environment record.\n */\n\n/* XXX: add support for variables to not be register bound always, to\n * handle cases with a very large number of variables?\n */\n\nDUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ctx, duk_regconst_t *out_stmt_value_reg) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hstring *h_name;\n\tduk_bool_t configurable_bindings;\n\tduk_uarridx_t num_args;\n\tduk_uarridx_t num_decls;\n\tduk_regconst_t rc_name;\n\tduk_small_uint_t declvar_flags;\n\tduk_uarridx_t i;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\n\t/*\n\t *  Preliminaries\n\t */\n\n\tconfigurable_bindings = comp_ctx->curr_func.is_eval;\n\tDUK_DDD(DUK_DDDPRINT(\"configurable_bindings=%ld\", (long) configurable_bindings));\n\n\t/* varmap is already in comp_ctx->curr_func.varmap_idx */\n\n\t/*\n\t *  Function formal arguments, always bound to registers\n\t *  (there's no support for shuffling them now).\n\t */\n\n\tnum_args = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.argnames_idx);\n\tDUK_DDD(DUK_DDDPRINT(\"num_args=%ld\", (long) num_args));\n\t/* XXX: check num_args */\n\n\tfor (i = 0; i < num_args; i++) {\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.argnames_idx, i);\n\t\th_name = duk_known_hstring(thr, -1);\n\n\t\tif (comp_ctx->curr_func.is_strict) {\n\t\t\tif (duk__hstring_is_eval_or_arguments(comp_ctx, h_name)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"arg named 'eval' or 'arguments' in strict mode -> SyntaxError\"));\n\t\t\t\tgoto error_argname;\n\t\t\t}\n\t\t\tduk_dup_top(thr);\n\t\t\tif (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duplicate arg name in strict mode -> SyntaxError\"));\n\t\t\t\tgoto error_argname;\n\t\t\t}\n\n\t\t\t/* Ensure argument name is not a reserved word in current\n\t\t\t * (final) strictness.  Formal argument parsing may not\n\t\t\t * catch reserved names if strictness changes during\n\t\t\t * parsing.\n\t\t\t *\n\t\t\t * We only need to do this in strict mode because non-strict\n\t\t\t * keyword are always detected in formal argument parsing.\n\t\t\t */\n\n\t\t\tif (DUK_HSTRING_HAS_STRICT_RESERVED_WORD(h_name)) {\n\t\t\t\tgoto error_argname;\n\t\t\t}\n\t\t}\n\n\t\t/* overwrite any previous binding of the same name; the effect is\n\t\t * that last argument of a certain name wins.\n\t\t */\n\n\t\t/* only functions can have arguments */\n\t\tDUK_ASSERT(comp_ctx->curr_func.is_function);\n\t\tduk_push_uarridx(thr, i);  /* -> [ ... name index ] */\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx); /* -> [ ... ] */\n\n\t\t/* no code needs to be emitted, the regs already have values */\n\t}\n\n\t/* use temp_next for tracking register allocations */\n\tDUK__SETTEMP_CHECKMAX(comp_ctx, (duk_regconst_t) num_args);\n\n\t/*\n\t *  After arguments, allocate special registers (like shuffling temps)\n\t */\n\n\tif (out_stmt_value_reg) {\n\t\t*out_stmt_value_reg = DUK__ALLOCTEMP(comp_ctx);\n\t}\n\tif (comp_ctx->curr_func.needs_shuffle) {\n\t\tduk_regconst_t shuffle_base = DUK__ALLOCTEMPS(comp_ctx, 3);\n\t\tcomp_ctx->curr_func.shuffle1 = shuffle_base;\n\t\tcomp_ctx->curr_func.shuffle2 = shuffle_base + 1;\n\t\tcomp_ctx->curr_func.shuffle3 = shuffle_base + 2;\n\t\tDUK_D(DUK_DPRINT(\"shuffle registers needed by function, allocated: %ld %ld %ld\",\n\t\t                 (long) comp_ctx->curr_func.shuffle1,\n\t\t                 (long) comp_ctx->curr_func.shuffle2,\n\t\t                 (long) comp_ctx->curr_func.shuffle3));\n\t}\n\tif (comp_ctx->curr_func.temp_next > 0x100) {\n\t\tDUK_D(DUK_DPRINT(\"not enough 8-bit regs: temp_next=%ld\", (long) comp_ctx->curr_func.temp_next));\n\t\tgoto error_outofregs;\n\t}\n\n\t/*\n\t *  Function declarations\n\t */\n\n\tnum_decls = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.decls_idx);\n\tDUK_DDD(DUK_DDDPRINT(\"num_decls=%ld -> %!T\",\n\t                     (long) num_decls,\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.decls_idx)));\n\tfor (i = 0; i < num_decls; i += 2) {\n\t\tduk_int_t decl_type;\n\t\tduk_int_t fnum;\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i + 1);  /* decl type */\n\t\tdecl_type = duk_to_int(thr, -1);\n\t\tfnum = decl_type >> 8;  /* XXX: macros */\n\t\tdecl_type = decl_type & 0xff;\n\t\tduk_pop(thr);\n\n\t\tif (decl_type != DUK_DECL_TYPE_FUNC) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i);  /* decl name */\n\n\t\t/* XXX: spilling */\n\t\tif (comp_ctx->curr_func.is_function) {\n\t\t\tduk_regconst_t reg_bind;\n\t\t\tduk_dup_top(thr);\n\t\t\tif (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) {\n\t\t\t\t/* shadowed; update value */\n\t\t\t\tduk_dup_top(thr);\n\t\t\t\tduk_get_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\t\t\treg_bind = duk_to_int(thr, -1);  /* [ ... name reg_bind ] */\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_CLOSURE,\n\t\t\t\t               reg_bind,\n\t\t\t\t               (duk_regconst_t) fnum);\n\t\t\t} else {\n\t\t\t\t/* function: always register bound */\n\t\t\t\treg_bind = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_CLOSURE,\n\t\t\t\t               reg_bind,\n\t\t\t\t               (duk_regconst_t) fnum);\n\t\t\t\tduk_push_int(thr, (duk_int_t) reg_bind);\n\t\t\t}\n\t\t} else {\n\t\t\t/* Function declaration for global/eval code is emitted even\n\t\t\t * for duplicates, because of E5 Section 10.5, step 5.e of\n\t\t\t * E5.1 (special behavior for variable bound to global object).\n\t\t\t *\n\t\t\t * DECLVAR will not re-declare a variable as such, but will\n\t\t\t * update the binding value.\n\t\t\t */\n\n\t\t\tduk_regconst_t reg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\tduk_dup_top(thr);\n\t\t\trc_name = duk__getconst(comp_ctx);\n\t\t\tduk_push_null(thr);\n\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CLOSURE,\n\t\t\t               reg_temp,\n\t\t\t               (duk_regconst_t) fnum);\n\n\t\t\tdeclvar_flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t                DUK_PROPDESC_FLAG_ENUMERABLE |\n\t\t\t                DUK_BC_DECLVAR_FLAG_FUNC_DECL;\n\n\t\t\tif (configurable_bindings) {\n\t\t\t\tdeclvar_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t}\n\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_DECLVAR | DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                (duk_regconst_t) declvar_flags /*flags*/,\n\t\t\t                rc_name /*name*/,\n\t\t\t                reg_temp /*value*/);\n\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp);  /* forget temp */\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"function declaration to varmap: %!T -> %!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n#if defined(DUK_USE_FASTINT)\n\t\tDUK_ASSERT(DUK_TVAL_IS_NULL(duk_get_tval(thr, -1)) || DUK_TVAL_IS_FASTINT(duk_get_tval(thr, -1)));\n#endif\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);  /* [ ... name reg/null ] -> [ ... ] */\n\t}\n\n\t/*\n\t *  'arguments' binding is special; if a shadowing argument or\n\t *  function declaration exists, an arguments object will\n\t *  definitely not be needed, regardless of whether the identifier\n\t *  'arguments' is referenced inside the function body.\n\t */\n\n\tif (duk_has_prop_stridx(thr, comp_ctx->curr_func.varmap_idx, DUK_STRIDX_LC_ARGUMENTS)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"'arguments' is shadowed by argument or function declaration \"\n\t\t                     \"-> arguments object creation can be skipped\"));\n\t\tcomp_ctx->curr_func.is_arguments_shadowed = 1;\n\t}\n\n\t/*\n\t *  Variable declarations.\n\t *\n\t *  Unlike function declarations, variable declaration values don't get\n\t *  assigned on entry.  If a binding of the same name already exists, just\n\t *  ignore it silently.\n\t */\n\n\tfor (i = 0; i < num_decls; i += 2) {\n\t\tduk_int_t decl_type;\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i + 1);  /* decl type */\n\t\tdecl_type = duk_to_int(thr, -1);\n\t\tdecl_type = decl_type & 0xff;\n\t\tduk_pop(thr);\n\n\t\tif (decl_type != DUK_DECL_TYPE_VAR) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i);  /* decl name */\n\n\t\tif (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) {\n\t\t\t/* shadowed, ignore */\n\t\t} else {\n\t\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i);  /* decl name */\n\t\t\th_name = duk_known_hstring(thr, -1);\n\n\t\t\tif (h_name == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr) &&\n\t\t\t    !comp_ctx->curr_func.is_arguments_shadowed) {\n\t\t\t\t/* E5 Section steps 7-8 */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"'arguments' not shadowed by a function declaration, \"\n\t\t\t\t                     \"but appears as a variable declaration -> treat as \"\n\t\t\t\t                     \"a no-op for variable declaration purposes\"));\n\t\t\t\tduk_pop(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* XXX: spilling */\n\t\t\tif (comp_ctx->curr_func.is_function) {\n\t\t\t\tduk_regconst_t reg_bind = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\t/* no need to init reg, it will be undefined on entry */\n\t\t\t\tduk_push_int(thr, (duk_int_t) reg_bind);\n\t\t\t} else {\n\t\t\t\tduk_dup_top(thr);\n\t\t\t\trc_name = duk__getconst(comp_ctx);\n\t\t\t\tduk_push_null(thr);\n\n\t\t\t\tdeclvar_flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t                        DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t\tif (configurable_bindings) {\n\t\t\t\t\tdeclvar_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t\t}\n\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                DUK_OP_DECLVAR | DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                (duk_regconst_t) declvar_flags /*flags*/,\n\t\t\t\t                rc_name /*name*/,\n\t\t\t\t                0 /*value*/);\n\t\t\t}\n\n\t\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);  /* [ ... name reg/null ] -> [ ... ] */\n\t\t}\n\t}\n\n\t/*\n\t *  Wrap up\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"varmap: %!T, is_arguments_shadowed=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx),\n\t                     (long) comp_ctx->curr_func.is_arguments_shadowed));\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n\n error_argname:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_ARG_NAME);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Parse a function-body-like expression (FunctionBody or Program\n *  in E5 grammar) using a two-pass parse.  The productions appear\n *  in the following contexts:\n *\n *    - function expression\n *    - function statement\n *    - function declaration\n *    - getter in object literal\n *    - setter in object literal\n *    - global code\n *    - eval code\n *    - Function constructor body\n *\n *  This function only parses the statement list of the body; the argument\n *  list and possible function name must be initialized by the caller.\n *  For instance, for Function constructor, the argument names are originally\n *  on the value stack.  The parsing of statements ends either at an EOF or\n *  a closing brace; this is controlled by an input flag.\n *\n *  Note that there are many differences affecting parsing and even code\n *  generation:\n *\n *    - Global and eval code have an implicit return value generated\n *      by the last statement; function code does not\n *\n *    - Global code, eval code, and Function constructor body end in\n *      an EOF, other bodies in a closing brace ('}')\n *\n *  Upon entry, 'curr_tok' is ignored and the function will pull in the\n *  first token on its own.  Upon exit, 'curr_tok' is the terminating\n *  token (EOF or closing brace).\n */\n\nDUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expect_eof, duk_bool_t implicit_return_value, duk_bool_t regexp_after, duk_small_int_t expect_token) {\n\tduk_compiler_func *func;\n\tduk_hthread *thr;\n\tduk_regconst_t reg_stmt_value = -1;\n\tduk_lexer_point lex_pt;\n\tduk_regconst_t temp_first;\n\tduk_small_int_t compile_round = 1;\n\n\tDUK_ASSERT(comp_ctx != NULL);\n\n\tthr = comp_ctx->thr;\n\tDUK_ASSERT(thr != NULL);\n\n\tfunc = &comp_ctx->curr_func;\n\tDUK_ASSERT(func != NULL);\n\n\tDUK__RECURSION_INCREASE(comp_ctx, thr);\n\n\tduk_require_stack(thr, DUK__FUNCTION_BODY_REQUIRE_SLOTS);\n\n\t/*\n\t *  Store lexer position for a later rewind\n\t */\n\n\tDUK_LEXER_GETPOINT(&comp_ctx->lex, &lex_pt);\n\n\t/*\n\t *  Program code (global and eval code) has an implicit return value\n\t *  from the last statement value (e.g. eval(\"1; 2+3;\") returns 3).\n\t *  This is not the case with functions.  If implicit statement return\n\t *  value is requested, all statements are coerced to a register\n\t *  allocated here, and used in the implicit return statement below.\n\t */\n\n\t/* XXX: this is pointless here because pass 1 is throw-away */\n\tif (implicit_return_value) {\n\t\treg_stmt_value = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t/* If an implicit return value is needed by caller, it must be\n\t\t * initialized to 'undefined' because we don't know whether any\n\t\t * non-empty (where \"empty\" is a continuation type, and different\n\t\t * from an empty statement) statements will be executed.\n\t\t *\n\t\t * However, since 1st pass is a throwaway one, no need to emit\n\t\t * it here.\n\t\t */\n#if 0\n\t\tduk__emit_bc(comp_ctx,\n\t\t             DUK_OP_LDUNDEF,\n\t\t             0);\n#endif\n\t}\n\n\t/*\n\t *  First pass.\n\t *\n\t *  Gather variable/function declarations needed for second pass.\n\t *  Code generated is dummy and discarded.\n\t */\n\n\tfunc->in_directive_prologue = 1;\n\tfunc->in_scanning = 1;\n\tfunc->may_direct_eval = 0;\n\tfunc->id_access_arguments = 0;\n\tfunc->id_access_slow = 0;\n\tfunc->id_access_slow_own = 0;\n\tfunc->reg_stmt_value = reg_stmt_value;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tfunc->min_line = DUK_INT_MAX;\n\tfunc->max_line = 0;\n#endif\n\n\t/* duk__parse_stmts() expects curr_tok to be set; parse in \"allow\n\t * regexp literal\" mode with current strictness.\n\t */\n\tif (expect_token >= 0) {\n\t\t/* Eating a left curly; regexp mode is allowed by left curly\n\t\t * based on duk__token_lbp[] automatically.\n\t\t */\n\t\tDUK_ASSERT(expect_token == DUK_TOK_LCURLY);\n\t\tduk__update_lineinfo_currtoken(comp_ctx);\n\t\tduk__advance_expect(comp_ctx, expect_token);\n\t} else {\n\t\t/* Need to set curr_token.t because lexing regexp mode depends on current\n\t\t * token type.  Zero value causes \"allow regexp\" mode.\n\t\t */\n\t\tcomp_ctx->curr_token.t = 0;\n\t\tduk__advance(comp_ctx);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin 1st pass\"));\n\tduk__parse_stmts(comp_ctx,\n\t                 1,             /* allow source elements */\n\t                 expect_eof,    /* expect EOF instead of } */\n\t                 regexp_after); /* regexp after */\n\tDUK_DDD(DUK_DDDPRINT(\"end 1st pass\"));\n\n\t/*\n\t *  Second (and possibly third) pass.\n\t *\n\t *  Generate actual code.  In most cases the need for shuffle\n\t *  registers is detected during pass 1, but in some corner cases\n\t *  we'll only detect it during pass 2 and a third pass is then\n\t *  needed (see GH-115).\n\t */\n\n\tfor (;;) {\n\t\tduk_bool_t needs_shuffle_before = comp_ctx->curr_func.needs_shuffle;\n\t\tcompile_round++;\n\n\t\t/*\n\t\t *  Rewind lexer.\n\t\t *\n\t\t *  duk__parse_stmts() expects curr_tok to be set; parse in \"allow regexp\n\t\t *  literal\" mode with current strictness.\n\t\t *\n\t\t *  curr_token line number info should be initialized for pass 2 before\n\t\t *  generating prologue, to ensure prologue bytecode gets nice line numbers.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"rewind lexer\"));\n\t\tDUK_LEXER_SETPOINT(&comp_ctx->lex, &lex_pt);\n\t\tcomp_ctx->curr_token.t = 0;  /* this is needed for regexp mode */\n\t\tcomp_ctx->curr_token.start_line = 0;  /* needed for line number tracking (becomes prev_token.start_line) */\n\t\tduk__advance(comp_ctx);\n\n\t\t/*\n\t\t *  Reset function state and perform register allocation, which creates\n\t\t *  'varmap' for second pass.  Function prologue for variable declarations,\n\t\t *  binding value initializations etc is emitted as a by-product.\n\t\t *\n\t\t *  Strict mode restrictions for duplicate and invalid argument\n\t\t *  names are checked here now that we know whether the function\n\t\t *  is actually strict.  See: test-dev-strict-mode-boundary.js.\n\t\t *\n\t\t *  Inner functions are compiled during pass 1 and are not reset.\n\t\t */\n\n\t\tduk__reset_func_for_pass2(comp_ctx);\n\t\tfunc->in_directive_prologue = 1;\n\t\tfunc->in_scanning = 0;\n\n\t\t/* must be able to emit code, alloc consts, etc. */\n\n\t\tduk__init_varmap_and_prologue_for_pass2(comp_ctx,\n\t\t                                        (implicit_return_value ? &reg_stmt_value : NULL));\n\t\tfunc->reg_stmt_value = reg_stmt_value;\n\n\t\ttemp_first = DUK__GETTEMP(comp_ctx);\n\n\t\tfunc->temp_first = temp_first;\n\t\tfunc->temp_next = temp_first;\n\t\tfunc->stmt_next = 0;\n\t\tfunc->label_next = 0;\n\n\t\t/* XXX: init or assert catch depth etc -- all values */\n\t\tfunc->id_access_arguments = 0;\n\t\tfunc->id_access_slow = 0;\n\t\tfunc->id_access_slow_own = 0;\n\n\t\t/*\n\t\t *  Check function name validity now that we know strictness.\n\t\t *  This only applies to function declarations and expressions,\n\t\t *  not setter/getter name.\n\t\t *\n\t\t *  See: test-dev-strict-mode-boundary.js\n\t\t */\n\n\t\tif (func->is_function && !func->is_setget && func->h_name != NULL) {\n\t\t\tif (func->is_strict) {\n\t\t\t\tif (duk__hstring_is_eval_or_arguments(comp_ctx, func->h_name)) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"func name is 'eval' or 'arguments' in strict mode\"));\n\t\t\t\t\tgoto error_funcname;\n\t\t\t\t}\n\t\t\t\tif (DUK_HSTRING_HAS_STRICT_RESERVED_WORD(func->h_name)) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"func name is a reserved word in strict mode\"));\n\t\t\t\t\tgoto error_funcname;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (DUK_HSTRING_HAS_RESERVED_WORD(func->h_name) &&\n\t\t\t\t    !DUK_HSTRING_HAS_STRICT_RESERVED_WORD(func->h_name)) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"func name is a reserved word in non-strict mode\"));\n\t\t\t\t\tgoto error_funcname;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t *  Second pass parsing.\n\t\t */\n\n\t\tif (implicit_return_value) {\n\t\t\t/* Default implicit return value. */\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_LDUNDEF,\n\t\t\t             0);\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"begin 2nd pass\"));\n\t\tduk__parse_stmts(comp_ctx,\n\t\t                 1,             /* allow source elements */\n\t\t                 expect_eof,    /* expect EOF instead of } */\n\t\t                 regexp_after); /* regexp after */\n\t\tDUK_DDD(DUK_DDDPRINT(\"end 2nd pass\"));\n\n\t\tduk__update_lineinfo_currtoken(comp_ctx);\n\n\t\tif (needs_shuffle_before == comp_ctx->curr_func.needs_shuffle) {\n\t\t\t/* Shuffle decision not changed. */\n\t\t\tbreak;\n\t\t}\n\t\tif (compile_round >= 3) {\n\t\t\t/* Should never happen but avoid infinite loop just in case. */\n\t\t\tDUK_D(DUK_DPRINT(\"more than 3 compile passes needed, should never happen\"));\n\t\t\tDUK_ERROR_INTERNAL(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tDUK_D(DUK_DPRINT(\"need additional round to compile function, round now %d\", (int) compile_round));\n\t}\n\n\t/*\n\t *  Emit a final RETURN.\n\t *\n\t *  It would be nice to avoid emitting an unnecessary \"return\" opcode\n\t *  if the current PC is not reachable.  However, this cannot be reliably\n\t *  detected; even if the previous instruction is an unconditional jump,\n\t *  there may be a previous jump which jumps to current PC (which is the\n\t *  case for iteration and conditional statements, for instance).\n\t */\n\n\t/* XXX: request a \"last statement is terminal\" from duk__parse_stmt() and duk__parse_stmts();\n\t * we could avoid the last RETURN if we could ensure there is no way to get here\n\t * (directly or via a jump)\n\t */\n\n\tDUK_ASSERT(comp_ctx->curr_func.catch_depth == 0);\n\tif (reg_stmt_value >= 0) {\n\t\tDUK_ASSERT(DUK__ISREG(reg_stmt_value));\n\t\tduk__emit_bc(comp_ctx, DUK_OP_RETREG, reg_stmt_value /*reg*/);\n\t} else {\n\t\tduk__emit_op_only(comp_ctx, DUK_OP_RETUNDEF);\n\t}\n\n\t/*\n\t *  Peephole optimize JUMP chains.\n\t */\n\n\tduk__peephole_optimize_bytecode(comp_ctx);\n\n\t/*\n\t *  comp_ctx->curr_func is now ready to be converted into an actual\n\t *  function template.\n\t */\n\n\tDUK__RECURSION_DECREASE(comp_ctx, thr);\n\treturn;\n\n error_funcname:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_FUNC_NAME);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Parse a function-like expression:\n *\n *    - function expression\n *    - function declaration\n *    - function statement (non-standard)\n *    - setter/getter\n *\n *  Adds the function to comp_ctx->curr_func function table and returns the\n *  function number.\n *\n *  On entry, curr_token points to:\n *\n *    - the token after 'function' for function expression/declaration/statement\n *    - the token after 'set' or 'get' for setter/getter\n */\n\n/* Parse formals. */\nDUK_LOCAL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t first = 1;\n\tduk_uarridx_t n;\n\n\tfor (;;) {\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RPAREN) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (first) {\n\t\t\t/* no comma */\n\t\t\tfirst = 0;\n\t\t} else {\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COMMA);\n\t\t}\n\n\t\t/* Note: when parsing a formal list in non-strict context, e.g.\n\t\t * \"implements\" is parsed as an identifier.  When the function is\n\t\t * later detected to be strict, the argument list must be rechecked\n\t\t * against a larger set of reserved words (that of strict mode).\n\t\t * This is handled by duk__parse_func_body().  Here we recognize\n\t\t * whatever tokens are considered reserved in current strictness\n\t\t * (which is not always enough).\n\t\t */\n\n\t\tif (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EXPECTED_IDENTIFIER);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_IDENTIFIER);\n\t\tDUK_ASSERT(comp_ctx->curr_token.str1 != NULL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"formal argument: %!O\",\n\t\t                     (duk_heaphdr *) comp_ctx->curr_token.str1));\n\n\t\t/* XXX: append primitive */\n\t\tduk_push_hstring(thr, comp_ctx->curr_token.str1);\n\t\tn = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.argnames_idx);\n\t\tduk_put_prop_index(thr, comp_ctx->curr_func.argnames_idx, n);\n\n\t\tduk__advance(comp_ctx);  /* eat identifier */\n\t}\n}\n\n/* Parse a function-like expression, assuming that 'comp_ctx->curr_func' is\n * correctly set up.  Assumes that curr_token is just after 'function' (or\n * 'set'/'get' etc).\n */\nDUK_LOCAL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_token *tok;\n\tduk_bool_t no_advance;\n\n\tDUK_ASSERT(comp_ctx->curr_func.num_formals == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_function == 1);\n\tDUK_ASSERT(comp_ctx->curr_func.is_eval == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_global == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_setget == ((flags & DUK__FUNC_FLAG_GETSET) != 0));\n\n\tduk__update_lineinfo_currtoken(comp_ctx);\n\n\t/*\n\t *  Function name (if any)\n\t *\n\t *  We don't check for prohibited names here, because we don't\n\t *  yet know whether the function will be strict.  Function body\n\t *  parsing handles this retroactively.\n\t *\n\t *  For function expressions and declarations function name must\n\t *  be an Identifer (excludes reserved words).  For setter/getter\n\t *  it is a PropertyName which allows reserved words and also\n\t *  strings and numbers (e.g. \"{ get 1() { ... } }\").\n\t *\n\t *  Function parsing may start either from prev_token or curr_token\n\t *  (object literal method definition uses prev_token for example).\n\t *  This is dealt with for the initial token.\n\t */\n\n\tno_advance = (flags & DUK__FUNC_FLAG_USE_PREVTOKEN);\n\tif (no_advance) {\n\t\ttok = &comp_ctx->prev_token;\n\t} else {\n\t\ttok = &comp_ctx->curr_token;\n\t}\n\n\tif (flags & DUK__FUNC_FLAG_GETSET) {\n\t\t/* PropertyName -> IdentifierName | StringLiteral | NumericLiteral */\n\t\tif (tok->t_nores == DUK_TOK_IDENTIFIER || tok->t == DUK_TOK_STRING) {\n\t\t\tduk_push_hstring(thr, tok->str1);       /* keep in valstack */\n\t\t} else if (tok->t == DUK_TOK_NUMBER) {\n\t\t\tduk_push_number(thr, tok->num);\n\t\t\tduk_to_string(thr, -1);\n\t\t} else {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_GETSET_NAME);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tcomp_ctx->curr_func.h_name = duk_known_hstring(thr, -1);  /* borrowed reference */\n\t} else {\n\t\t/* Function name is an Identifier (not IdentifierName), but we get\n\t\t * the raw name (not recognizing keywords) here and perform the name\n\t\t * checks only after pass 1.\n\t\t */\n\t\tif (tok->t_nores == DUK_TOK_IDENTIFIER) {\n\t\t\tduk_push_hstring(thr, tok->str1);       /* keep in valstack */\n\t\t\tcomp_ctx->curr_func.h_name = duk_known_hstring(thr, -1);  /* borrowed reference */\n\t\t} else {\n\t\t\t/* valstack will be unbalanced, which is OK */\n\t\t\tDUK_ASSERT((flags & DUK__FUNC_FLAG_GETSET) == 0);\n\t\t\tDUK_ASSERT(comp_ctx->curr_func.h_name == NULL);\n\t\t\tno_advance = 1;\n\t\t\tif (flags & DUK__FUNC_FLAG_DECL) {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_FUNC_NAME_REQUIRED);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t}\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"function name: %!O\",\n\t                   (duk_heaphdr *) comp_ctx->curr_func.h_name));\n\n\tif (!no_advance) {\n\t\tduk__advance(comp_ctx);\n\t}\n\n\t/*\n\t *  Formal argument list\n\t *\n\t *  We don't check for prohibited names or for duplicate argument\n\t *  names here, becase we don't yet know whether the function will\n\t *  be strict.  Function body parsing handles this retroactively.\n\t */\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\tduk__parse_func_formals(comp_ctx);\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RPAREN);\n\tduk__advance(comp_ctx);\n\n\t/*\n\t *  Parse function body\n\t */\n\n\tduk__parse_func_body(comp_ctx,\n\t                     0,   /* expect_eof */\n\t                     0,   /* implicit_return_value */\n\t                     flags & DUK__FUNC_FLAG_DECL, /* regexp_after */\n\t                     DUK_TOK_LCURLY);  /* expect_token */\n\n\t/*\n\t *  Convert duk_compiler_func to a function template and add it\n\t *  to the parent function table.\n\t */\n\n\tduk__convert_to_func_template(comp_ctx);  /* -> [ ... func ] */\n}\n\n/* Parse an inner function, adding the function template to the current function's\n * function table.  Return a function number to be used by the outer function.\n *\n * Avoiding O(depth^2) inner function parsing is handled here.  On the first pass,\n * compile and register the function normally into the 'funcs' array, also recording\n * a lexer point (offset/line) to the closing brace of the function.  On the second\n * pass, skip the function and return the same 'fnum' as on the first pass by using\n * a running counter.\n *\n * An unfortunate side effect of this is that when parsing the inner function, almost\n * nothing is known of the outer function, i.e. the inner function's scope.  We don't\n * need that information at the moment, but it would allow some optimizations if it\n * were used.\n */\nDUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_compiler_func old_func;\n\tduk_idx_t entry_top;\n\tduk_int_t fnum;\n\n\t/*\n\t *  On second pass, skip the function.\n\t */\n\n\tif (!comp_ctx->curr_func.in_scanning) {\n\t\tduk_lexer_point lex_pt;\n\n\t\tfnum = comp_ctx->curr_func.fnum_next++;\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 1));\n\t\tlex_pt.offset = (duk_size_t) duk_to_uint(thr, -1);\n\t\tduk_pop(thr);\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 2));\n\t\tlex_pt.line = duk_to_int(thr, -1);\n\t\tduk_pop(thr);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"second pass of an inner func, skip the function, reparse closing brace; lex offset=%ld, line=%ld\",\n\t\t                     (long) lex_pt.offset, (long) lex_pt.line));\n\n\t\tDUK_LEXER_SETPOINT(&comp_ctx->lex, &lex_pt);\n\t\tcomp_ctx->curr_token.t = 0;  /* this is needed for regexp mode */\n\t\tcomp_ctx->curr_token.start_line = 0;  /* needed for line number tracking (becomes prev_token.start_line) */\n\t\tduk__advance(comp_ctx);\n\n\t\t/* RegExp is not allowed after a function expression, e.g. in\n\t\t * (function () {} / 123).  A RegExp *is* allowed after a\n\t\t * function declaration!\n\t\t */\n\t\tif (flags & DUK__FUNC_FLAG_DECL) {\n\t\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t\t}\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RCURLY);\n\n\t\treturn fnum;\n\t}\n\n\t/*\n\t *  On first pass, perform actual parsing.  Remember valstack top on entry\n\t *  to restore it later, and switch to using a new function in comp_ctx.\n\t */\n\n\tentry_top = duk_get_top(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"before func: entry_top=%ld, curr_tok.start_offset=%ld\",\n\t                     (long) entry_top, (long) comp_ctx->curr_token.start_offset));\n\n\tduk_memcpy(&old_func, &comp_ctx->curr_func, sizeof(duk_compiler_func));\n\n\tduk_memzero(&comp_ctx->curr_func, sizeof(duk_compiler_func));\n\tduk__init_func_valstack_slots(comp_ctx);\n\tDUK_ASSERT(comp_ctx->curr_func.num_formals == 0);\n\n\t/* inherit initial strictness from parent */\n\tcomp_ctx->curr_func.is_strict = old_func.is_strict;\n\n\t/* XXX: It might be better to just store the flags into the curr_func\n\t * struct and use them as is without this flag interpretation step\n\t * here.\n\t */\n\tDUK_ASSERT(comp_ctx->curr_func.is_notail == 0);\n\tcomp_ctx->curr_func.is_function = 1;\n\tDUK_ASSERT(comp_ctx->curr_func.is_eval == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_global == 0);\n\tcomp_ctx->curr_func.is_setget = ((flags & DUK__FUNC_FLAG_GETSET) != 0);\n\tcomp_ctx->curr_func.is_namebinding = !(flags & (DUK__FUNC_FLAG_GETSET |\n\t                                                DUK__FUNC_FLAG_METDEF |\n\t                                                DUK__FUNC_FLAG_DECL));  /* no name binding for: declarations, objlit getset, objlit method def */\n\tcomp_ctx->curr_func.is_constructable = !(flags & (DUK__FUNC_FLAG_GETSET |\n\t                                                  DUK__FUNC_FLAG_METDEF));  /* not constructable: objlit getset, objlit method def */\n\n\t/*\n\t *  Parse inner function\n\t */\n\n\tduk__parse_func_like_raw(comp_ctx, flags);  /* pushes function template */\n\n\t/* prev_token.start_offset points to the closing brace here; when skipping\n\t * we're going to reparse the closing brace to ensure semicolon insertion\n\t * etc work as expected.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"after func: prev_tok.start_offset=%ld, curr_tok.start_offset=%ld\",\n\t                     (long) comp_ctx->prev_token.start_offset, (long) comp_ctx->curr_token.start_offset));\n\tDUK_ASSERT(comp_ctx->lex.input[comp_ctx->prev_token.start_offset] == (duk_uint8_t) DUK_ASC_RCURLY);\n\n\t/* XXX: append primitive */\n\tDUK_ASSERT(duk_get_length(thr, old_func.funcs_idx) == (duk_size_t) (old_func.fnum_next * 3));\n\tfnum = old_func.fnum_next++;\n\n\tif (fnum > DUK__MAX_FUNCS) {\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_FUNC_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* array writes autoincrement length */\n\t(void) duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3));\n\tduk_push_size_t(thr, comp_ctx->prev_token.start_offset);\n\t(void) duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 1));\n\tduk_push_int(thr, comp_ctx->prev_token.start_line);\n\t(void) duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 2));\n\n\t/*\n\t *  Cleanup: restore original function, restore valstack state.\n\t *\n\t *  Function declaration handling needs the function name to be pushed\n\t *  on the value stack.\n\t */\n\n\tif (flags & DUK__FUNC_FLAG_PUSHNAME_PASS1) {\n\t\tDUK_ASSERT(comp_ctx->curr_func.h_name != NULL);\n\t\tduk_push_hstring(thr, comp_ctx->curr_func.h_name);\n\t\tduk_replace(thr, entry_top);\n\t\tduk_set_top(thr, entry_top + 1);\n\t} else {\n\t\tduk_set_top(thr, entry_top);\n\t}\n\tduk_memcpy((void *) &comp_ctx->curr_func, (void *) &old_func, sizeof(duk_compiler_func));\n\n\treturn fnum;\n}\n\n/*\n *  Compile input string into an executable function template without\n *  arguments.\n *\n *  The string is parsed as the \"Program\" production of ECMAScript E5.\n *  Compilation context can be either global code or eval code (see E5\n *  Sections 14 and 15.1.2.1).\n *\n *  Input stack:  [ ... filename ]\n *  Output stack: [ ... func_template ]\n */\n\n/* XXX: source code property */\n\nDUK_LOCAL duk_ret_t duk__js_compile_raw(duk_hthread *thr, void *udata) {\n\tduk_hstring *h_filename;\n\tduk__compiler_stkstate *comp_stk;\n\tduk_compiler_ctx *comp_ctx;\n\tduk_lexer_point *lex_pt;\n\tduk_compiler_func *func;\n\tduk_idx_t entry_top;\n\tduk_bool_t is_strict;\n\tduk_bool_t is_eval;\n\tduk_bool_t is_funcexpr;\n\tduk_small_uint_t flags;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(udata != NULL);\n\n\t/*\n\t *  Arguments check\n\t */\n\n\tentry_top = duk_get_top(thr);\n\tDUK_ASSERT(entry_top >= 1);\n\n\tcomp_stk = (duk__compiler_stkstate *) udata;\n\tcomp_ctx = &comp_stk->comp_ctx_alloc;\n\tlex_pt = &comp_stk->lex_pt_alloc;\n\tDUK_ASSERT(comp_ctx != NULL);\n\tDUK_ASSERT(lex_pt != NULL);\n\n\tflags = comp_stk->flags;\n\tis_eval = (flags & DUK_COMPILE_EVAL ? 1 : 0);\n\tis_strict = (flags & DUK_COMPILE_STRICT ? 1 : 0);\n\tis_funcexpr = (flags & DUK_COMPILE_FUNCEXPR ? 1 : 0);\n\n\th_filename = duk_get_hstring(thr, -1);  /* may be undefined */\n\n\t/*\n\t *  Init compiler and lexer contexts\n\t */\n\n\tfunc = &comp_ctx->curr_func;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tcomp_ctx->thr = NULL;\n\tcomp_ctx->h_filename = NULL;\n\tcomp_ctx->prev_token.str1 = NULL;\n\tcomp_ctx->prev_token.str2 = NULL;\n\tcomp_ctx->curr_token.str1 = NULL;\n\tcomp_ctx->curr_token.str2 = NULL;\n#endif\n\n\tduk_require_stack(thr, DUK__COMPILE_ENTRY_SLOTS);\n\n\tduk_push_dynamic_buffer(thr, 0);       /* entry_top + 0 */\n\tduk_push_undefined(thr);               /* entry_top + 1 */\n\tduk_push_undefined(thr);               /* entry_top + 2 */\n\tduk_push_undefined(thr);               /* entry_top + 3 */\n\tduk_push_undefined(thr);               /* entry_top + 4 */\n\n\tcomp_ctx->thr = thr;\n\tcomp_ctx->h_filename = h_filename;\n\tcomp_ctx->tok11_idx = entry_top + 1;\n\tcomp_ctx->tok12_idx = entry_top + 2;\n\tcomp_ctx->tok21_idx = entry_top + 3;\n\tcomp_ctx->tok22_idx = entry_top + 4;\n\tcomp_ctx->recursion_limit = DUK_USE_COMPILER_RECLIMIT;\n\n\t/* comp_ctx->lex has been pre-initialized by caller: it has been\n\t * zeroed and input/input_length has been set.\n\t */\n\tcomp_ctx->lex.thr = thr;\n\t/* comp_ctx->lex.input and comp_ctx->lex.input_length filled by caller */\n\tcomp_ctx->lex.slot1_idx = comp_ctx->tok11_idx;\n\tcomp_ctx->lex.slot2_idx = comp_ctx->tok12_idx;\n\tcomp_ctx->lex.buf_idx = entry_top + 0;\n\tcomp_ctx->lex.buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, entry_top + 0);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(comp_ctx->lex.buf) && !DUK_HBUFFER_HAS_EXTERNAL(comp_ctx->lex.buf));\n\tcomp_ctx->lex.token_limit = DUK_COMPILER_TOKEN_LIMIT;\n\n\tlex_pt->offset = 0;\n\tlex_pt->line = 1;\n\tDUK_LEXER_SETPOINT(&comp_ctx->lex, lex_pt);    /* fills window */\n\tcomp_ctx->curr_token.start_line = 0;  /* needed for line number tracking (becomes prev_token.start_line) */\n\n\t/*\n\t *  Initialize function state for a zero-argument function\n\t */\n\n\tduk__init_func_valstack_slots(comp_ctx);\n\tDUK_ASSERT(func->num_formals == 0);\n\n\tif (is_funcexpr) {\n\t\t/* Name will be filled from function expression, not by caller.\n\t\t * This case is used by Function constructor and duk_compile()\n\t\t * API with the DUK_COMPILE_FUNCTION option.\n\t\t */\n\t\tDUK_ASSERT(func->h_name == NULL);\n\t} else {\n\t\tduk_push_hstring_stridx(thr, (is_eval ? DUK_STRIDX_EVAL :\n\t\t                                        DUK_STRIDX_GLOBAL));\n\t\tfunc->h_name = duk_get_hstring(thr, -1);\n\t}\n\n\t/*\n\t *  Parse a function body or a function-like expression, depending\n\t *  on flags.\n\t */\n\n\tDUK_ASSERT(func->is_setget == 0);\n\tfunc->is_strict = (duk_uint8_t) is_strict;\n\tDUK_ASSERT(func->is_notail == 0);\n\n\tif (is_funcexpr) {\n\t\tfunc->is_function = 1;\n\t\tDUK_ASSERT(func->is_eval == 0);\n\t\tDUK_ASSERT(func->is_global == 0);\n\t\tfunc->is_namebinding = 1;\n\t\tfunc->is_constructable = 1;\n\n\t\tduk__advance(comp_ctx);  /* init 'curr_token' */\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_FUNCTION);\n\t\t(void) duk__parse_func_like_raw(comp_ctx, 0 /*flags*/);\n\t} else {\n\t\tDUK_ASSERT(func->is_function == 0);\n\t\tDUK_ASSERT(is_eval == 0 || is_eval == 1);\n\t\tfunc->is_eval = (duk_uint8_t) is_eval;\n\t\tfunc->is_global = (duk_uint8_t) !is_eval;\n\t\tDUK_ASSERT(func->is_namebinding == 0);\n\t\tDUK_ASSERT(func->is_constructable == 0);\n\n\t\tduk__parse_func_body(comp_ctx,\n\t\t                     1,             /* expect_eof */\n\t\t                     1,             /* implicit_return_value */\n\t\t                     1,             /* regexp_after (does not matter) */\n\t\t                     -1);           /* expect_token */\n\t}\n\n\t/*\n\t *  Convert duk_compiler_func to a function template\n\t */\n\n\tduk__convert_to_func_template(comp_ctx);\n\n\t/*\n\t *  Wrapping duk_safe_call() will mangle the stack, just return stack top\n\t */\n\n\t/* [ ... filename (temps) func ] */\n\n\treturn 1;\n}\n\nDUK_INTERNAL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer, duk_size_t src_length, duk_small_uint_t flags) {\n\tduk__compiler_stkstate comp_stk;\n\tduk_compiler_ctx *prev_ctx;\n\tduk_ret_t safe_rc;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(src_buffer != NULL);\n\n\t/* preinitialize lexer state partially */\n\tduk_memzero(&comp_stk, sizeof(comp_stk));\n\tcomp_stk.flags = flags;\n\tDUK_LEXER_INITCTX(&comp_stk.comp_ctx_alloc.lex);\n\tcomp_stk.comp_ctx_alloc.lex.input = src_buffer;\n\tcomp_stk.comp_ctx_alloc.lex.input_length = src_length;\n\tcomp_stk.comp_ctx_alloc.lex.flags = flags;  /* Forward flags directly for now. */\n\n\t/* [ ... filename ] */\n\n\tprev_ctx = thr->compile_ctx;\n\tthr->compile_ctx = &comp_stk.comp_ctx_alloc;  /* for duk_error_augment.c */\n\tsafe_rc = duk_safe_call(thr, duk__js_compile_raw, (void *) &comp_stk /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\tthr->compile_ctx = prev_ctx;  /* must restore reliably before returning */\n\n\tif (safe_rc != DUK_EXEC_SUCCESS) {\n\t\tDUK_D(DUK_DPRINT(\"compilation failed: %!T\", duk_get_tval(thr, -1)));\n\t\t(void) duk_throw(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* [ ... template ] */\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_js_compiler.h",
    "content": "/*\n *  ECMAScript compiler.\n */\n\n#if !defined(DUK_JS_COMPILER_H_INCLUDED)\n#define DUK_JS_COMPILER_H_INCLUDED\n\n/* ECMAScript compiler limits */\n#define DUK_COMPILER_TOKEN_LIMIT           100000000L  /* 1e8: protects against deeply nested inner functions */\n\n/* maximum loopcount for peephole optimization */\n#define DUK_COMPILER_PEEPHOLE_MAXITER      3\n\n/* maximum bytecode length in instructions */\n#define DUK_COMPILER_MAX_BYTECODE_LENGTH   (256L * 1024L * 1024L)  /* 1 GB */\n\n/*\n *  Compiler intermediate values\n *\n *  Intermediate values describe either plain values (e.g. strings or\n *  numbers) or binary operations which have not yet been coerced into\n *  either a left-hand-side or right-hand-side role (e.g. object property).\n */\n\n#define DUK_IVAL_NONE          0   /* no value */\n#define DUK_IVAL_PLAIN         1   /* register, constant, or value */\n#define DUK_IVAL_ARITH         2   /* binary arithmetic; DUK_OP_ADD, DUK_OP_EQ, other binary ops */\n#define DUK_IVAL_PROP          3   /* property access */\n#define DUK_IVAL_VAR           4   /* variable access */\n\n#define DUK_ISPEC_NONE         0   /* no value */\n#define DUK_ISPEC_VALUE        1   /* value resides in 'valstack_idx' */\n#define DUK_ISPEC_REGCONST     2   /* value resides in a register or constant */\n\n/* Bit mask which indicates that a regconst is a constant instead of a register.\n * Chosen so that when a regconst is cast to duk_int32_t, all consts are\n * negative values.\n */\n#define DUK_REGCONST_CONST_MARKER    DUK_INT32_MIN  /* = -0x80000000 */\n\n/* Type to represent a reg/const reference during compilation, with <0\n * indicating a constant.  Some call sites also use -1 to indicate 'none'.\n */\ntypedef duk_int32_t duk_regconst_t;\n\ntypedef struct {\n\tduk_small_uint_t t;          /* DUK_ISPEC_XXX */\n\tduk_regconst_t regconst;\n\tduk_idx_t valstack_idx;      /* always set; points to a reserved valstack slot */\n} duk_ispec;\n\ntypedef struct {\n\t/*\n\t *  PLAIN: x1\n\t *  ARITH: x1 <op> x2\n\t *  PROP: x1.x2\n\t *  VAR: x1 (name)\n\t */\n\n\t/* XXX: can be optimized for smaller footprint esp. on 32-bit environments */\n\tduk_small_uint_t t;          /* DUK_IVAL_XXX */\n\tduk_small_uint_t op;         /* bytecode opcode for binary ops */\n\tduk_ispec x1;\n\tduk_ispec x2;\n} duk_ivalue;\n\n/*\n *  Bytecode instruction representation during compilation\n *\n *  Contains the actual instruction and (optionally) debug info.\n */\n\nstruct duk_compiler_instr {\n\tduk_instr_t ins;\n#if defined(DUK_USE_PC2LINE)\n\tduk_uint32_t line;\n#endif\n};\n\n/*\n *  Compiler state\n */\n\n#define DUK_LABEL_FLAG_ALLOW_BREAK       (1U << 0)\n#define DUK_LABEL_FLAG_ALLOW_CONTINUE    (1U << 1)\n\n#define DUK_DECL_TYPE_VAR                0\n#define DUK_DECL_TYPE_FUNC               1\n\n/* XXX: optimize to 16 bytes */\ntypedef struct {\n\tduk_small_uint_t flags;\n\tduk_int_t label_id;          /* numeric label_id (-1 reserved as marker) */\n\tduk_hstring *h_label;        /* borrowed label name */\n\tduk_int_t catch_depth;       /* catch depth at point of definition */\n\tduk_int_t pc_label;          /* pc of label statement:\n\t                              * pc+1: break jump site\n\t                              * pc+2: continue jump site\n\t                              */\n\n\t/* Fast jumps (which avoid longjmp) jump directly to the jump sites\n\t * which are always known even while the iteration/switch statement\n\t * is still being parsed.  A final peephole pass \"straightens out\"\n\t * the jumps.\n\t */\n} duk_labelinfo;\n\n/* Compiling state of one function, eventually converted to duk_hcompfunc */\nstruct duk_compiler_func {\n\t/* These pointers are at the start of the struct so that they pack\n\t * nicely.  Mixing pointers and integer values is bad on some\n\t * platforms (e.g. if int is 32 bits and pointers are 64 bits).\n\t */\n\n\tduk_bufwriter_ctx bw_code;          /* bufwriter for code */\n\n\tduk_hstring *h_name;                /* function name (borrowed reference), ends up in _name */\n\t/* h_code: held in bw_code */\n\tduk_hobject *h_consts;              /* array */\n\tduk_hobject *h_funcs;               /* array of function templates: [func1, offset1, line1, func2, offset2, line2]\n\t                                     * offset/line points to closing brace to allow skipping on pass 2\n\t                                     */\n\tduk_hobject *h_decls;               /* array of declarations: [ name1, val1, name2, val2, ... ]\n\t                                     * valN = (typeN) | (fnum << 8), where fnum is inner func number (0 for vars)\n\t                                     * record function and variable declarations in pass 1\n\t                                     */\n\tduk_hobject *h_labelnames;          /* array of active label names */\n\tduk_hbuffer_dynamic *h_labelinfos;  /* C array of duk_labelinfo */\n\tduk_hobject *h_argnames;            /* array of formal argument names (-> _Formals) */\n\tduk_hobject *h_varmap;              /* variable map for pass 2 (identifier -> register number or null (unmapped)) */\n\n\t/* Value stack indices for tracking objects. */\n\t/* code_idx: not needed */\n\tduk_idx_t consts_idx;\n\tduk_idx_t funcs_idx;\n\tduk_idx_t decls_idx;\n\tduk_idx_t labelnames_idx;\n\tduk_idx_t labelinfos_idx;\n\tduk_idx_t argnames_idx;\n\tduk_idx_t varmap_idx;\n\n\t/* Temp reg handling. */\n\tduk_regconst_t temp_first;           /* first register that is a temporary (below: variables) */\n\tduk_regconst_t temp_next;            /* next temporary register to allocate */\n\tduk_regconst_t temp_max;             /* highest value of temp_reg (temp_max - 1 is highest used reg) */\n\n\t/* Shuffle registers if large number of regs/consts. */\n\tduk_regconst_t shuffle1;\n\tduk_regconst_t shuffle2;\n\tduk_regconst_t shuffle3;\n\n\t/* Stats for current expression being parsed. */\n\tduk_int_t nud_count;\n\tduk_int_t led_count;\n\tduk_int_t paren_level;              /* parenthesis count, 0 = top level */\n\tduk_bool_t expr_lhs;                /* expression is left-hand-side compatible */\n\tduk_bool_t allow_in;                /* current paren level allows 'in' token */\n\n\t/* Misc. */\n\tduk_int_t stmt_next;                /* statement id allocation (running counter) */\n\tduk_int_t label_next;               /* label id allocation (running counter) */\n\tduk_int_t catch_depth;              /* catch stack depth */\n\tduk_int_t with_depth;               /* with stack depth (affects identifier lookups) */\n\tduk_int_t fnum_next;                /* inner function numbering */\n\tduk_int_t num_formals;              /* number of formal arguments */\n\tduk_regconst_t reg_stmt_value;      /* register for writing value of 'non-empty' statements (global or eval code), -1 is marker */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_int_t min_line;                 /* XXX: typing (duk_hcompfunc has duk_uint32_t) */\n\tduk_int_t max_line;\n#endif\n\n\t/* Status booleans. */\n\tduk_uint8_t is_function;             /* is an actual function (not global/eval code) */\n\tduk_uint8_t is_eval;                 /* is eval code */\n\tduk_uint8_t is_global;               /* is global code */\n\tduk_uint8_t is_namebinding;          /* needs a name binding */\n\tduk_uint8_t is_constructable;        /* result is constructable */\n\tduk_uint8_t is_setget;               /* is a setter/getter */\n\tduk_uint8_t is_strict;               /* function is strict */\n\tduk_uint8_t is_notail;               /* function must not be tail called */\n\tduk_uint8_t in_directive_prologue;   /* parsing in \"directive prologue\", recognize directives */\n\tduk_uint8_t in_scanning;             /* parsing in \"scanning\" phase (first pass) */\n\tduk_uint8_t may_direct_eval;         /* function may call direct eval */\n\tduk_uint8_t id_access_arguments;     /* function refers to 'arguments' identifier */\n\tduk_uint8_t id_access_slow;          /* function makes one or more slow path accesses that won't match own static variables */\n\tduk_uint8_t id_access_slow_own;      /* function makes one or more slow path accesses that may match own static variables */\n\tduk_uint8_t is_arguments_shadowed;   /* argument/function declaration shadows 'arguments' */\n\tduk_uint8_t needs_shuffle;           /* function needs shuffle registers */\n\tduk_uint8_t reject_regexp_in_adv;    /* reject RegExp literal on next advance() call; needed for handling IdentifierName productions */\n\tduk_uint8_t allow_regexp_in_adv;     /* allow RegExp literal on next advance() call */\n};\n\nstruct duk_compiler_ctx {\n\tduk_hthread *thr;\n\n\t/* filename being compiled (ends up in functions' '_filename' property) */\n\tduk_hstring *h_filename;            /* borrowed reference */\n\n\t/* lexing (tokenization) state (contains two valstack slot indices) */\n\tduk_lexer_ctx lex;\n\n\t/* current and previous token for parsing */\n\tduk_token prev_token;\n\tduk_token curr_token;\n\tduk_idx_t tok11_idx;                /* curr_token slot1 (matches 'lex' slot1_idx) */\n\tduk_idx_t tok12_idx;                /* curr_token slot2 (matches 'lex' slot2_idx) */\n\tduk_idx_t tok21_idx;                /* prev_token slot1 */\n\tduk_idx_t tok22_idx;                /* prev_token slot2 */\n\n\t/* recursion limit */\n\tduk_int_t recursion_depth;\n\tduk_int_t recursion_limit;\n\n\t/* code emission temporary */\n\tduk_int_t emit_jumpslot_pc;\n\n\t/* current function being compiled (embedded instead of pointer for more compact access) */\n\tduk_compiler_func curr_func;\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer, duk_size_t src_length, duk_small_uint_t flags);\n\n#endif  /* DUK_JS_COMPILER_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_js_executor.c",
    "content": "/*\n *  ECMAScript bytecode executor.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Local declarations.\n */\n\nDUK_LOCAL_DECL void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, duk_activation *entry_act);\n\n/*\n *  Misc helpers.\n */\n\n/* Forced inline declaration, only applied for performance oriented build. */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n#define DUK__INLINE_PERF\n#define DUK__NOINLINE_PERF\n#else\n#define DUK__INLINE_PERF DUK_ALWAYS_INLINE\n#define DUK__NOINLINE_PERF DUK_NOINLINE\n#endif\n\n/* Replace value stack top to value at 'tv_ptr'.  Optimize for\n * performance by only applying the net refcount change.\n */\n#define DUK__REPLACE_TO_TVPTR(thr,tv_ptr) do { \\\n\t\tduk_hthread *duk__thr; \\\n\t\tduk_tval *duk__tvsrc; \\\n\t\tduk_tval *duk__tvdst; \\\n\t\tduk_tval duk__tvtmp; \\\n\t\tduk__thr = (thr); \\\n\t\tduk__tvsrc = DUK_GET_TVAL_NEGIDX(duk__thr, -1); \\\n\t\tduk__tvdst = (tv_ptr); \\\n\t\tDUK_TVAL_SET_TVAL(&duk__tvtmp, duk__tvdst); \\\n\t\tDUK_TVAL_SET_TVAL(duk__tvdst, duk__tvsrc); \\\n\t\tDUK_TVAL_SET_UNDEFINED(duk__tvsrc);  /* value stack init policy */ \\\n\t\tduk__thr->valstack_top = duk__tvsrc; \\\n\t\tDUK_TVAL_DECREF(duk__thr, &duk__tvtmp); \\\n\t} while (0)\n\n/* XXX: candidate of being an internal shared API call */\n#if 0  /* unused */\nDUK_LOCAL void duk__push_tvals_incref_only(duk_hthread *thr, duk_tval *tv_src, duk_small_uint_fast_t count) {\n\tduk_tval *tv_dst;\n\tduk_size_t copy_size;\n\tduk_size_t i;\n\n\ttv_dst = thr->valstack_top;\n\tcopy_size = sizeof(duk_tval) * count;\n\tduk_memcpy((void *) tv_dst, (const void *) tv_src, copy_size);\n\tfor (i = 0; i < count; i++) {\n\t\tDUK_TVAL_INCREF(thr, tv_dst);\n\t\ttv_dst++;\n\t}\n\tthr->valstack_top = tv_dst;\n}\n#endif\n\n/*\n *  Arithmetic, binary, and logical helpers.\n *\n *  Note: there is no opcode for logical AND or logical OR; this is on\n *  purpose, because the evalution order semantics for them make such\n *  opcodes pretty pointless: short circuiting means they are most\n *  comfortably implemented as jumps.  However, a logical NOT opcode\n *  is useful.\n *\n *  Note: careful with duk_tval pointers here: they are potentially\n *  invalidated by any DECREF and almost any API call.  It's still\n *  preferable to work without making a copy but that's not always\n *  possible.\n */\n\nDUK_LOCAL DUK__INLINE_PERF duk_double_t duk__compute_mod(duk_double_t d1, duk_double_t d2) {\n\treturn (duk_double_t) duk_js_arith_mod((double) d1, (double) d2);\n}\n\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\nDUK_LOCAL DUK__INLINE_PERF duk_double_t duk__compute_exp(duk_double_t d1, duk_double_t d2) {\n\treturn (duk_double_t) duk_js_arith_pow((double) d1, (double) d2);\n}\n#endif\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_add(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_fast_t idx_z) {\n\t/*\n\t *  Addition operator is different from other arithmetic\n\t *  operations in that it also provides string concatenation.\n\t *  Hence it is implemented separately.\n\t *\n\t *  There is a fast path for number addition.  Other cases go\n\t *  through potentially multiple coercions as described in the\n\t *  E5 specification.  It may be possible to reduce the number\n\t *  of coercions, but this must be done carefully to preserve\n\t *  the exact semantics.\n\t *\n\t *  E5 Section 11.6.1.\n\t *\n\t *  Custom types also have special behavior implemented here.\n\t */\n\n\tduk_double_union du;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_x != NULL);  /* may be reg or const */\n\tDUK_ASSERT(tv_y != NULL);  /* may be reg or const */\n\tDUK_ASSERT_DISABLE(idx_z >= 0);  /* unsigned */\n\tDUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr));\n\n\t/*\n\t *  Fast paths\n\t */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\tduk_int64_t v1, v2, v3;\n\t\tduk_int32_t v3_hi;\n\t\tduk_tval *tv_z;\n\n\t\t/* Input values are signed 48-bit so we can detect overflow\n\t\t * reliably from high bits or just a comparison.\n\t\t */\n\n\t\tv1 = DUK_TVAL_GET_FASTINT(tv_x);\n\t\tv2 = DUK_TVAL_GET_FASTINT(tv_y);\n\t\tv3 = v1 + v2;\n\t\tv3_hi = (duk_int32_t) (v3 >> 32);\n\t\tif (DUK_LIKELY(v3_hi >= DUK_I64_CONSTANT(-0x8000) && v3_hi <= DUK_I64_CONSTANT(0x7fff))) {\n\t\t\ttv_z = thr->valstack_bottom + idx_z;\n\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, v3);  /* side effects */\n\t\t\treturn;\n\t\t} else {\n\t\t\t/* overflow, fall through */\n\t\t\t;\n\t\t}\n\t}\n#endif  /* DUK_USE_FASTINT */\n\n\tif (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) {\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tduk_tval *tv_z;\n#endif\n\n\t\tdu.d = DUK_TVAL_GET_NUMBER(tv_x) + DUK_TVAL_GET_NUMBER(tv_y);\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tduk_push_number(thr, du.d);  /* will NaN normalize result */\n\t\tduk_replace(thr, (duk_idx_t) idx_z);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\t\ttv_z = thr->valstack_bottom + idx_z;\n\t\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, du.d);  /* side effects */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\treturn;\n\t}\n\n\t/*\n\t *  Slow path: potentially requires function calls for coercion\n\t */\n\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\tduk_to_primitive(thr, -2, DUK_HINT_NONE);  /* side effects -> don't use tv_x, tv_y after */\n\tduk_to_primitive(thr, -1, DUK_HINT_NONE);\n\n\t/* Since Duktape 2.x plain buffers are treated like ArrayBuffer. */\n\tif (duk_is_string(thr, -2) || duk_is_string(thr, -1)) {\n\t\t/* Symbols shouldn't technically be handled here, but should\n\t\t * go into the default ToNumber() coercion path instead and\n\t\t * fail there with a TypeError.  However, there's a ToString()\n\t\t * in duk_concat_2() which also fails with TypeError so no\n\t\t * explicit check is needed.\n\t\t */\n\t\tduk_concat_2(thr);  /* [... s1 s2] -> [... s1+s2] */\n\t} else {\n\t\tduk_double_t d1, d2;\n\n\t\td1 = duk_to_number_m2(thr);\n\t\td2 = duk_to_number_m1(thr);\n\t\tDUK_ASSERT(duk_is_number(thr, -2));\n\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d1);\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d2);\n\n\t\tdu.d = d1 + d2;\n\t\tduk_pop_2_unsafe(thr);\n\t\tduk_push_number(thr, du.d);  /* will NaN normalize result */\n\t}\n\tduk_replace(thr, (duk_idx_t) idx_z);  /* side effects */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_binary_op(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_uint_fast_t idx_z, duk_small_uint_fast_t opcode) {\n\t/*\n\t *  Arithmetic operations other than '+' have number-only semantics\n\t *  and are implemented here.  The separate switch-case here means a\n\t *  \"double dispatch\" of the arithmetic opcode, but saves code space.\n\t *\n\t *  E5 Sections 11.5, 11.5.1, 11.5.2, 11.5.3, 11.6, 11.6.1, 11.6.2, 11.6.3.\n\t */\n\n\tduk_double_t d1, d2;\n\tduk_double_union du;\n\tduk_small_uint_fast_t opcode_shifted;\n#if defined(DUK_USE_FASTINT) || !defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_tval *tv_z;\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_x != NULL);  /* may be reg or const */\n\tDUK_ASSERT(tv_y != NULL);  /* may be reg or const */\n\tDUK_ASSERT_DISABLE(idx_z >= 0);  /* unsigned */\n\tDUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr));\n\n\topcode_shifted = opcode >> 2;  /* Get base opcode without reg/const modifiers. */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\tduk_int64_t v1, v2, v3;\n\t\tduk_int32_t v3_hi;\n\n\t\tv1 = DUK_TVAL_GET_FASTINT(tv_x);\n\t\tv2 = DUK_TVAL_GET_FASTINT(tv_y);\n\n\t\tswitch (opcode_shifted) {\n\t\tcase DUK_OP_SUB >> 2: {\n\t\t\tv3 = v1 - v2;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL >> 2: {\n\t\t\t/* Must ensure result is 64-bit (no overflow); a\n\t\t\t * simple and sufficient fast path is to allow only\n\t\t\t * 32-bit inputs.  Avoid zero inputs to avoid\n\t\t\t * negative zero issues (-1 * 0 = -0, for instance).\n\t\t\t */\n\t\t\tif (v1 >= DUK_I64_CONSTANT(-0x80000000) && v1 <= DUK_I64_CONSTANT(0x7fffffff) && v1 != 0 &&\n\t\t\t    v2 >= DUK_I64_CONSTANT(-0x80000000) && v2 <= DUK_I64_CONSTANT(0x7fffffff) && v2 != 0) {\n\t\t\t\tv3 = v1 * v2;\n\t\t\t} else {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV >> 2: {\n\t\t\t/* Don't allow a zero divisor.  Fast path check by\n\t\t\t * \"verifying\" with multiplication.  Also avoid zero\n\t\t\t * dividend to avoid negative zero issues (0 / -1 = -0\n\t\t\t * for instance).\n\t\t\t */\n\t\t\tif (v1 == 0 || v2 == 0) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tv3 = v1 / v2;\n\t\t\tif (v3 * v2 != v1) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD >> 2: {\n\t\t\t/* Don't allow a zero divisor.  Restrict both v1 and\n\t\t\t * v2 to positive values to avoid compiler specific\n\t\t\t * behavior.\n\t\t\t */\n\t\t\tif (v1 < 1 || v2 < 1) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tv3 = v1 % v2;\n\t\t\tDUK_ASSERT(v3 >= 0);\n\t\t\tDUK_ASSERT(v3 < v2);\n\t\t\tDUK_ASSERT(v1 - (v1 / v2) * v2 == v3);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\t/* Possible with DUK_OP_EXP. */\n\t\t\tgoto skip_fastint;\n\t\t}\n\t\t}\n\n\t\tv3_hi = (duk_int32_t) (v3 >> 32);\n\t\tif (DUK_LIKELY(v3_hi >= DUK_I64_CONSTANT(-0x8000) && v3_hi <= DUK_I64_CONSTANT(0x7fff))) {\n\t\t\ttv_z = thr->valstack_bottom + idx_z;\n\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, v3);  /* side effects */\n\t\t\treturn;\n\t\t}\n\t\t/* fall through if overflow etc */\n\t}\n skip_fastint:\n#endif  /* DUK_USE_FASTINT */\n\n\tif (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) {\n\t\t/* fast path */\n\t\td1 = DUK_TVAL_GET_NUMBER(tv_x);\n\t\td2 = DUK_TVAL_GET_NUMBER(tv_y);\n\t} else {\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\td1 = duk_to_number_m2(thr);  /* side effects */\n\t\td2 = duk_to_number_m1(thr);\n\t\tDUK_ASSERT(duk_is_number(thr, -2));\n\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d1);\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d2);\n\t\tduk_pop_2_unsafe(thr);\n\t}\n\n\tswitch (opcode_shifted) {\n\tcase DUK_OP_SUB >> 2: {\n\t\tdu.d = d1 - d2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_MUL >> 2: {\n\t\tdu.d = d1 * d2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_DIV >> 2: {\n\t\t/* Division-by-zero is undefined behavior, so\n\t\t * rely on a helper.\n\t\t */\n\t\tdu.d = duk_double_div(d1, d2);\n\t\tbreak;\n\t}\n\tcase DUK_OP_MOD >> 2: {\n\t\tdu.d = duk__compute_mod(d1, d2);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\tcase DUK_OP_EXP >> 2: {\n\t\tdu.d = duk__compute_exp(d1, d2);\n\t\tbreak;\n\t}\n#endif\n\tdefault: {\n\t\tDUK_UNREACHABLE();\n\t\tdu.d = DUK_DOUBLE_NAN;  /* should not happen */\n\t\tbreak;\n\t}\n\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_push_number(thr, du.d);  /* will NaN normalize result */\n\tduk_replace(thr, (duk_idx_t) idx_z);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t/* important to use normalized NaN with 8-byte tagged types */\n\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\ttv_z = thr->valstack_bottom + idx_z;\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, du.d);  /* side effects */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_bitwise_binary_op(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_fast_t idx_z, duk_small_uint_fast_t opcode) {\n\t/*\n\t *  Binary bitwise operations use different coercions (ToInt32, ToUint32)\n\t *  depending on the operation.  We coerce the arguments first using\n\t *  ToInt32(), and then cast to an 32-bit value if necessary.  Note that\n\t *  such casts must be correct even if there is no native 32-bit type\n\t *  (e.g., duk_int32_t and duk_uint32_t are 64-bit).\n\t *\n\t *  E5 Sections 11.10, 11.7.1, 11.7.2, 11.7.3\n\t */\n\n\tduk_int32_t i1, i2, i3;\n\tduk_uint32_t u1, u2, u3;\n#if defined(DUK_USE_FASTINT)\n\tduk_int64_t fi3;\n#else\n\tduk_double_t d3;\n#endif\n\tduk_small_uint_fast_t opcode_shifted;\n#if defined(DUK_USE_FASTINT) || !defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_tval *tv_z;\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_x != NULL);  /* may be reg or const */\n\tDUK_ASSERT(tv_y != NULL);  /* may be reg or const */\n\tDUK_ASSERT_DISABLE(idx_z >= 0);  /* unsigned */\n\tDUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr));\n\n\topcode_shifted = opcode >> 2;  /* Get base opcode without reg/const modifiers. */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\ti1 = (duk_int32_t) DUK_TVAL_GET_FASTINT_I32(tv_x);\n\t\ti2 = (duk_int32_t) DUK_TVAL_GET_FASTINT_I32(tv_y);\n\t}\n\telse\n#endif  /* DUK_USE_FASTINT */\n\t{\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\ti1 = duk_to_int32(thr, -2);\n\t\ti2 = duk_to_int32(thr, -1);\n\t\tduk_pop_2_unsafe(thr);\n\t}\n\n\tswitch (opcode_shifted) {\n\tcase DUK_OP_BAND >> 2: {\n\t\ti3 = i1 & i2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_BOR >> 2: {\n\t\ti3 = i1 | i2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_BXOR >> 2: {\n\t\ti3 = i1 ^ i2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_BASL >> 2: {\n\t\t/* Signed shift, named \"arithmetic\" (asl) because the result\n\t\t * is signed, e.g. 4294967295 << 1 -> -2.  Note that result\n\t\t * must be masked.\n\t\t */\n\n\t\tu2 = ((duk_uint32_t) i2) & 0xffffffffUL;\n\t\ti3 = (duk_int32_t) (((duk_uint32_t) i1) << (u2 & 0x1fUL));  /* E5 Section 11.7.1, steps 7 and 8 */\n\t\ti3 = i3 & ((duk_int32_t) 0xffffffffUL);                     /* Note: left shift, should mask */\n\t\tbreak;\n\t}\n\tcase DUK_OP_BASR >> 2: {\n\t\t/* signed shift */\n\n\t\tu2 = ((duk_uint32_t) i2) & 0xffffffffUL;\n\t\ti3 = i1 >> (u2 & 0x1fUL);                      /* E5 Section 11.7.2, steps 7 and 8 */\n\t\tbreak;\n\t}\n\tcase DUK_OP_BLSR >> 2: {\n\t\t/* unsigned shift */\n\n\t\tu1 = ((duk_uint32_t) i1) & 0xffffffffUL;\n\t\tu2 = ((duk_uint32_t) i2) & 0xffffffffUL;\n\n\t\t/* special result value handling */\n\t\tu3 = u1 >> (u2 & 0x1fUL);     /* E5 Section 11.7.2, steps 7 and 8 */\n#if defined(DUK_USE_FASTINT)\n\t\tfi3 = (duk_int64_t) u3;\n\t\tgoto fastint_result_set;\n#else\n\t\td3 = (duk_double_t) u3;\n\t\tgoto result_set;\n#endif\n\t}\n\tdefault: {\n\t\tDUK_UNREACHABLE();\n\t\ti3 = 0;  /* should not happen */\n\t\tbreak;\n\t}\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\t/* Result is always fastint compatible. */\n\t/* XXX: Set 32-bit result (but must then handle signed and\n\t * unsigned results separately).\n\t */\n\tfi3 = (duk_int64_t) i3;\n\n fastint_result_set:\n\ttv_z = thr->valstack_bottom + idx_z;\n\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, fi3);  /* side effects */\n#else  /* DUK_USE_FASTINT */\n\td3 = (duk_double_t) i3;\n\n result_set:\n\tDUK_ASSERT(!DUK_ISNAN(d3));            /* 'd3' is never NaN, so no need to normalize */\n\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d3);   /* always normalized */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_push_number(thr, d3);  /* would NaN normalize result, but unnecessary */\n\tduk_replace(thr, (duk_idx_t) idx_z);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\ttv_z = thr->valstack_bottom + idx_z;\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, d3);  /* side effects */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n#endif  /* DUK_USE_FASTINT */\n}\n\n/* In-place unary operation. */\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_unary_op(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst, duk_small_uint_fast_t opcode) {\n\t/*\n\t *  Arithmetic operations other than '+' have number-only semantics\n\t *  and are implemented here.  The separate switch-case here means a\n\t *  \"double dispatch\" of the arithmetic opcode, but saves code space.\n\t *\n\t *  E5 Sections 11.5, 11.5.1, 11.5.2, 11.5.3, 11.6, 11.6.1, 11.6.2, 11.6.3.\n\t */\n\n\tduk_tval *tv;\n\tduk_double_t d1;\n\tduk_double_union du;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(opcode == DUK_OP_UNM || opcode == DUK_OP_UNP);\n\tDUK_ASSERT_DISABLE(idx_src >= 0);\n\tDUK_ASSERT_DISABLE(idx_dst >= 0);\n\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tduk_int64_t v1, v2;\n\n\t\tv1 = DUK_TVAL_GET_FASTINT(tv);\n\t\tif (opcode == DUK_OP_UNM) {\n\t\t\t/* The smallest fastint is no longer 48-bit when\n\t\t\t * negated.  Positive zero becames negative zero\n\t\t\t * (cannot be represented) when negated.\n\t\t\t */\n\t\t\tif (DUK_LIKELY(v1 != DUK_FASTINT_MIN && v1 != 0)) {\n\t\t\t\tv2 = -v1;\n\t\t\t\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv, v2);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\t/* ToNumber() for a fastint is a no-op. */\n\t\t\tDUK_ASSERT(opcode == DUK_OP_UNP);\n\t\t\tv2 = v1;\n\t\t\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv, v2);\n\t\t\treturn;\n\t\t}\n\t\t/* fall through if overflow etc */\n\t}\n#endif  /* DUK_USE_FASTINT */\n\n\tif (DUK_TVAL_IS_NUMBER(tv)) {\n\t\td1 = DUK_TVAL_GET_NUMBER(tv);\n\t} else {\n\t\td1 = duk_to_number_tval(thr, tv);  /* side effects */\n\t}\n\n\tif (opcode == DUK_OP_UNP) {\n\t\t/* ToNumber() for a double is a no-op, but unary plus is\n\t\t * used to force a fastint check so do that here.\n\t\t */\n\t\tdu.d = d1;\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n#if defined(DUK_USE_FASTINT)\n\t\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t\tDUK_TVAL_SET_NUMBER_CHKFAST_UPDREF(thr, tv, du.d);  /* always 'fast', i.e. inlined */\n\t\treturn;\n#endif\n\t} else {\n\t\tDUK_ASSERT(opcode == DUK_OP_UNM);\n\t\tdu.d = -d1;\n\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);  /* mandatory if du.d is a NaN */\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\t}\n\n\t/* XXX: size optimize: push+replace? */\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv, du.d);\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_bitwise_not(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst) {\n\t/*\n\t *  E5 Section 11.4.8\n\t */\n\n\tduk_tval *tv;\n\tduk_int32_t i1, i2;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT_DISABLE(idx_src >= 0);\n\tDUK_ASSERT_DISABLE(idx_dst >= 0);\n\tDUK_ASSERT((duk_uint_t) idx_src < (duk_uint_t) duk_get_top(thr));\n\tDUK_ASSERT((duk_uint_t) idx_dst < (duk_uint_t) duk_get_top(thr));\n\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\ti1 = (duk_int32_t) DUK_TVAL_GET_FASTINT_I32(tv);\n\t}\n\telse\n#endif  /* DUK_USE_FASTINT */\n\t{\n\t\tduk_push_tval(thr, tv);\n\t\ti1 = duk_to_int32(thr, -1);  /* side effects */\n\t\tduk_pop_unsafe(thr);\n\t}\n\n\t/* Result is always fastint compatible. */\n\ti2 = ~i1;\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\tDUK_TVAL_SET_I32_UPDREF(thr, tv, i2);  /* side effects */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_logical_not(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst) {\n\t/*\n\t *  E5 Section 11.4.9\n\t */\n\n\tduk_tval *tv;\n\tduk_bool_t res;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT_DISABLE(idx_src >= 0);\n\tDUK_ASSERT_DISABLE(idx_dst >= 0);\n\tDUK_ASSERT((duk_uint_t) idx_src < (duk_uint_t) duk_get_top(thr));\n\tDUK_ASSERT((duk_uint_t) idx_dst < (duk_uint_t) duk_get_top(thr));\n\n\t/* ToBoolean() does not require any operations with side effects so\n\t * we can do it efficiently.  For footprint it would be better to use\n\t * duk_js_toboolean() and then push+replace to the result slot.\n\t */\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src);\n\tres = duk_js_toboolean(tv);  /* does not modify 'tv' */\n\tDUK_ASSERT(res == 0 || res == 1);\n\tres ^= 1;\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t/* XXX: size optimize: push+replace? */\n\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv, res);  /* side effects */\n}\n\n/* XXX: size optimized variant */\nDUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_reg_helper(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_small_uint_t op) {\n\tduk_double_t x, y, z;\n\n\t/* Two lowest bits of opcode are used to distinguish\n\t * variants.  Bit 0 = inc(0)/dec(1), bit 1 = pre(0)/post(1).\n\t */\n\tDUK_ASSERT((DUK_OP_PREINCR & 0x03) == 0x00);\n\tDUK_ASSERT((DUK_OP_PREDECR & 0x03) == 0x01);\n\tDUK_ASSERT((DUK_OP_POSTINCR & 0x03) == 0x02);\n\tDUK_ASSERT((DUK_OP_POSTDECR & 0x03) == 0x03);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_src)) {\n\t\tduk_int64_t x_fi, y_fi, z_fi;\n\t\tx_fi = DUK_TVAL_GET_FASTINT(tv_src);\n\t\tif (op & 0x01) {\n\t\t\tif (DUK_UNLIKELY(x_fi == DUK_FASTINT_MIN)) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\ty_fi = x_fi - 1;\n\t\t} else {\n\t\t\tif (DUK_UNLIKELY(x_fi == DUK_FASTINT_MAX)) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\ty_fi = x_fi + 1;\n\t\t}\n\n\t\tDUK_TVAL_SET_FASTINT(tv_src, y_fi);  /* no need for refcount update */\n\n\t\tz_fi = (op & 0x02) ? x_fi : y_fi;\n\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_dst, z_fi);  /* side effects */\n\t\treturn;\n\t}\n skip_fastint:\n#endif\n\tif (DUK_TVAL_IS_NUMBER(tv_src)) {\n\t\t/* Fast path for the case where the register\n\t\t * is a number (e.g. loop counter).\n\t\t */\n\n\t\tx = DUK_TVAL_GET_NUMBER(tv_src);\n\t\tif (op & 0x01) {\n\t\t\ty = x - 1.0;\n\t\t} else {\n\t\t\ty = x + 1.0;\n\t\t}\n\n\t\tDUK_TVAL_SET_NUMBER(tv_src, y);  /* no need for refcount update */\n\t} else {\n\t\t/* Preserve duk_tval pointer(s) across a potential valstack\n\t\t * resize by converting them into offsets temporarily.\n\t\t */\n\t\tduk_idx_t bc;\n\t\tduk_size_t off_dst;\n\n\t\toff_dst = (duk_size_t) ((duk_uint8_t *) tv_dst - (duk_uint8_t *) thr->valstack_bottom);\n\t\tbc = (duk_idx_t) (tv_src - thr->valstack_bottom);  /* XXX: pass index explicitly? */\n\t\ttv_src = NULL;  /* no longer referenced */\n\n\t\tx = duk_to_number(thr, bc);\n\t\tif (op & 0x01) {\n\t\t\ty = x - 1.0;\n\t\t} else {\n\t\t\ty = x + 1.0;\n\t\t}\n\n\t\tduk_push_number(thr, y);\n\t\tduk_replace(thr, bc);\n\n\t\ttv_dst = (duk_tval *) (void *) (((duk_uint8_t *) thr->valstack_bottom) + off_dst);\n\t}\n\n\tz = (op & 0x02) ? x : y;\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_dst, z);  /* side effects */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_var_helper(duk_hthread *thr, duk_small_uint_t idx_dst, duk_tval *tv_id, duk_small_uint_t op, duk_small_uint_t is_strict) {\n\tduk_activation *act;\n\tduk_double_t x, y;\n\tduk_hstring *name;\n\n\t/* XXX: The pre/post inc/dec for an identifier lookup is\n\t * missing the important fast path where the identifier\n\t * has a storage location e.g. in a scope object so that\n\t * it can be updated in-place.  In particular, the case\n\t * where the identifier has a storage location AND the\n\t * previous value is a number should be optimized because\n\t * it's side effect free.\n\t */\n\n\t/* Two lowest bits of opcode are used to distinguish\n\t * variants.  Bit 0 = inc(0)/dec(1), bit 1 = pre(0)/post(1).\n\t */\n\tDUK_ASSERT((DUK_OP_PREINCV & 0x03) == 0x00);\n\tDUK_ASSERT((DUK_OP_PREDECV & 0x03) == 0x01);\n\tDUK_ASSERT((DUK_OP_POSTINCV & 0x03) == 0x02);\n\tDUK_ASSERT((DUK_OP_POSTDECV & 0x03) == 0x03);\n\n\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_id));\n\tname = DUK_TVAL_GET_STRING(tv_id);\n\tDUK_ASSERT(name != NULL);\n\tact = thr->callstack_curr;\n\t(void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/);  /* -> [ ... val this ] */\n\n\t/* XXX: Fastint fast path would be useful here.  Also fastints\n\t * now lose their fastint status in current handling which is\n\t * not intuitive.\n\t */\n\n\tx = duk_to_number_m2(thr);\n\tif (op & 0x01) {\n\t\ty = x - 1.0;\n\t} else {\n\t\ty = x + 1.0;\n\t}\n\n\t/* [... x this] */\n\n\tif (op & 0x02) {\n\t\tduk_push_number(thr, y);  /* -> [ ... x this y ] */\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tduk_js_putvar_activation(thr, act, name, DUK_GET_TVAL_NEGIDX(thr, -1), is_strict);\n\t\tduk_pop_2_unsafe(thr);  /* -> [ ... x ] */\n\t} else {\n\t\tduk_pop_2_unsafe(thr);  /* -> [ ... ] */\n\t\tduk_push_number(thr, y);  /* -> [ ... y ] */\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tduk_js_putvar_activation(thr, act, name, DUK_GET_TVAL_NEGIDX(thr, -1), is_strict);\n\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_replace(thr, (duk_idx_t) idx_dst);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\tDUK__REPLACE_TO_TVPTR(thr, DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n}\n\n/*\n *  Longjmp and other control flow transfer for the bytecode executor.\n *\n *  The longjmp handler can handle all longjmp types: error, yield, and\n *  resume (pseudotypes are never actually thrown).\n *\n *  Error policy for longjmp: should not ordinarily throw errors; if errors\n *  occur (e.g. due to out-of-memory) they bubble outwards rather than being\n *  handled recursively.\n */\n\n#define DUK__LONGJMP_RESTART   0  /* state updated, restart bytecode execution */\n#define DUK__LONGJMP_RETHROW   1  /* exit bytecode executor by rethrowing an error to caller */\n\n#define DUK__RETHAND_RESTART   0  /* state updated, restart bytecode execution */\n#define DUK__RETHAND_FINISHED  1  /* exit bytecode execution with return value */\n\n/* XXX: optimize reconfig valstack operations so that resize, clamp, and setting\n * top are combined into one pass.\n */\n\n/* Reconfigure value stack for return to an ECMAScript function at\n * callstack top (caller unwinds).\n */\nDUK_LOCAL void duk__reconfig_valstack_ecma_return(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_hcompfunc *h_func;\n\tduk_idx_t clamp_top;\n\n\tDUK_ASSERT(thr != NULL);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act)));\n\n\t/* Clamp so that values at 'clamp_top' and above are wiped and won't\n\t * retain reachable garbage.  Then extend to 'nregs' because we're\n\t * returning to an ECMAScript function.\n\t */\n\n\th_func = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff);\n\tDUK_ASSERT(act->retval_byteoff >= act->bottom_byteoff);\n\tclamp_top = (duk_idx_t) ((act->retval_byteoff - act->bottom_byteoff + sizeof(duk_tval)) / sizeof(duk_tval));  /* +1 = one retval */\n\tduk_set_top_and_wipe(thr, h_func->nregs, clamp_top);\n\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack_end >= (duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\n\t/* XXX: a best effort shrink check would be OK here */\n}\n\n/* Reconfigure value stack for an ECMAScript catcher.  Use topmost catcher\n * in 'act'.\n */\nDUK_LOCAL void duk__reconfig_valstack_ecma_catcher(duk_hthread *thr, duk_activation *act) {\n\tduk_catcher *cat;\n\tduk_hcompfunc *h_func;\n\tduk_size_t idx_bottom;\n\tduk_idx_t clamp_top;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act)));\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\th_func = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff);\n\tidx_bottom = (duk_size_t) (thr->valstack_bottom - thr->valstack);\n\tDUK_ASSERT(cat->idx_base >= idx_bottom);\n\tclamp_top = (duk_idx_t) (cat->idx_base - idx_bottom + 2);  /* +2 = catcher value, catcher lj_type */\n\tduk_set_top_and_wipe(thr, h_func->nregs, clamp_top);\n\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack_end >= (duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\n\t/* XXX: a best effort shrink check would be OK here */\n}\n\n/* Set catcher regs: idx_base+0 = value, idx_base+1 = lj_type.\n * No side effects.\n */\nDUK_LOCAL void duk__set_catcher_regs_norz(duk_hthread *thr, duk_catcher *cat, duk_tval *tv_val_unstable, duk_small_uint_t lj_type) {\n\tduk_tval *tv1;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\n\ttv1 = thr->valstack + cat->idx_base;\n\tDUK_ASSERT(tv1 < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF_NORZ(thr, tv1, tv_val_unstable);\n\n\ttv1++;\n\tDUK_ASSERT(tv1 == thr->valstack + cat->idx_base + 1);\n\tDUK_ASSERT(tv1 < thr->valstack_top);\n\tDUK_TVAL_SET_U32_UPDREF_NORZ(thr, tv1, (duk_uint32_t) lj_type);\n}\n\nDUK_LOCAL void duk__handle_catch_part1(duk_hthread *thr, duk_tval *tv_val_unstable, duk_small_uint_t lj_type, volatile duk_bool_t *out_delayed_catch_setup) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_DD(DUK_DDPRINT(\"handle catch, part 1; act=%!A, cat=%!C\", act, act->cat));\n\n\tDUK_ASSERT(act->cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);\n\n\t/* The part1/part2 split could also be made here at the very top\n\t * of catch handling.  Value stack would be reconfigured inside\n\t * part2's protection.  Value stack reconfiguration should be free\n\t * of allocs, however.\n\t */\n\n\tduk__set_catcher_regs_norz(thr, act->cat, tv_val_unstable, lj_type);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tduk__reconfig_valstack_ecma_catcher(thr, act);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tact->curr_pc = cat->pc_base + 0;  /* +0 = catch */\n\n\t/*\n\t *  If the catch block has an automatic catch variable binding,\n\t *  we need to create a lexical environment for it which requires\n\t *  allocations.  Move out of \"error handling state\" before the\n\t *  allocations to avoid e.g. out-of-memory errors (leading to\n\t *  GH-2022 or similar).\n\t */\n\n\tif (DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"catcher has an automatic catch binding, handle in part 2\"));\n\t\t*out_delayed_catch_setup = 1;\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"catcher has no catch binding\"));\n\t}\n\n\tDUK_CAT_CLEAR_CATCH_ENABLED(cat);\n}\n\nDUK_LOCAL void duk__handle_catch_part2(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_hdecenv *new_env;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_DD(DUK_DDPRINT(\"handle catch, part 2; act=%!A, cat=%!C\", act, act->cat));\n\n\tDUK_ASSERT(act->cat != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);\n\tDUK_ASSERT(DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat));\n\tDUK_ASSERT(thr->valstack + cat->idx_base < thr->valstack_top);\n\n\t/*\n\t *  Create lexical environment for the catch clause, containing\n\t *  a binding for the caught value.\n\t *\n\t *  The binding is mutable (= writable) but not deletable.\n\t *  Step 4 for the catch production in E5 Section 12.14;\n\t *  no value is given for CreateMutableBinding 'D' argument,\n\t *  which implies the binding is not deletable.\n\t */\n\n\tif (act->lex_env == NULL) {\n\t\tDUK_ASSERT(act->var_env == NULL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"delayed environment initialization\"));\n\n\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t}\n\tDUK_ASSERT(act->lex_env != NULL);\n\tDUK_ASSERT(act->var_env != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\n\tnew_env = duk_hdecenv_alloc(thr,\n\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\tDUK_ASSERT(new_env != NULL);\n\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\tDUK_DDD(DUK_DDDPRINT(\"new_env allocated: %!iO\", (duk_heaphdr *) new_env));\n\n\t/* Note: currently the catch binding is handled without a register\n\t * binding because we don't support dynamic register bindings (they\n\t * must be fixed for an entire function).  So, there is no need to\n\t * record regbases etc.\n\t */\n\n\t/* [ ...env ] */\n\n\tDUK_ASSERT(cat->h_varname != NULL);\n\tduk_push_hstring(thr, cat->h_varname);\n\tDUK_ASSERT(thr->valstack + cat->idx_base < thr->valstack_top);\n\tduk_push_tval(thr, thr->valstack + cat->idx_base);\n\tduk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_W);  /* writable, not configurable */\n\n\t/* [ ... env ] */\n\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, act->lex_env);\n\tact->lex_env = (duk_hobject *) new_env;\n\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env);  /* reachable through activation */\n\t/* Net refcount change to act->lex_env is 0: incref for new_env's\n\t * prototype, decref for act->lex_env overwrite.\n\t */\n\n\tDUK_CAT_SET_LEXENV_ACTIVE(cat);\n\n\tduk_pop_unsafe(thr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"new_env finished: %!iO\", (duk_heaphdr *) new_env));\n}\n\nDUK_LOCAL void duk__handle_finally(duk_hthread *thr, duk_tval *tv_val_unstable, duk_small_uint_t lj_type) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(act->cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);\n\n\tduk__set_catcher_regs_norz(thr, act->cat, tv_val_unstable, lj_type);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tduk__reconfig_valstack_ecma_catcher(thr, act);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tact->curr_pc = cat->pc_base + 1;  /* +1 = finally */\n\n\tDUK_CAT_CLEAR_FINALLY_ENABLED(cat);\n}\n\nDUK_LOCAL void duk__handle_label(duk_hthread *thr, duk_small_uint_t lj_type) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(DUK_ACT_GET_FUNC(act)));\n\n\t/* +0 = break, +1 = continue */\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_LABEL);\n\n\tact->curr_pc = cat->pc_base + (lj_type == DUK_LJ_TYPE_CONTINUE ? 1 : 0);\n\n\t/* valstack should not need changes */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) ==\n\t           (duk_size_t) ((duk_hcompfunc *) DUK_ACT_GET_FUNC(act))->nregs);\n#endif\n}\n\n/* Called for handling both a longjmp() with type DUK_LJ_TYPE_YIELD and\n * when a RETURN opcode terminates a thread and yields to the resumer.\n * Caller unwinds so that top of callstack is the activation we return to.\n */\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_LOCAL void duk__handle_yield(duk_hthread *thr, duk_hthread *resumer, duk_tval *tv_val_unstable) {\n\tduk_activation *act_resumer;\n\tduk_tval *tv1;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(resumer != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\tact_resumer = resumer->callstack_curr;\n\tDUK_ASSERT(act_resumer != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act_resumer) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act_resumer)));  /* resume caller must be an ECMAScript func */\n\n\ttv1 = (duk_tval *) (void *) ((duk_uint8_t *) resumer->valstack + act_resumer->retval_byteoff);  /* return value from Duktape.Thread.resume() */\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv_val_unstable);  /* side effects */  /* XXX: avoid side effects */\n\n\tduk__reconfig_valstack_ecma_return(resumer);\n\n\t/* caller must change active thread, and set thr->resumer to NULL */\n}\n#endif  /* DUK_USE_COROUTINE_SUPPORT */\n\nDUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation *entry_act, volatile duk_bool_t *out_delayed_catch_setup) {\n\tduk_small_uint_t retval = DUK__LONGJMP_RESTART;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(entry_act != NULL);\n\n\t/* 'thr' is the current thread, as no-one resumes except us and we\n\t * switch 'thr' in that case.\n\t */\n\tDUK_ASSERT(thr == thr->heap->curr_thread);\n\n\t/*\n\t *  (Re)try handling the longjmp.\n\t *\n\t *  A longjmp handler may convert the longjmp to a different type and\n\t *  \"virtually\" rethrow by goto'ing to 'check_longjmp'.  Before the goto,\n\t *  the following must be updated:\n\t *    - the heap 'lj' state\n\t *    - 'thr' must reflect the \"throwing\" thread\n\t */\n\n check_longjmp:\n\n\tDUK_DD(DUK_DDPRINT(\"handling longjmp: type=%ld, value1=%!T, value2=%!T, iserror=%ld, top=%ld\",\n\t                   (long) thr->heap->lj.type,\n\t                   (duk_tval *) &thr->heap->lj.value1,\n\t                   (duk_tval *) &thr->heap->lj.value2,\n\t                   (long) thr->heap->lj.iserror,\n\t\t\t   (long) duk_get_top(thr)));\n\n\tswitch (thr->heap->lj.type) {\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\tcase DUK_LJ_TYPE_RESUME: {\n\t\t/*\n\t\t *  Note: lj.value1 is 'value', lj.value2 is 'resumee'.\n\t\t *  This differs from YIELD.\n\t\t */\n\n\t\tduk_tval *tv;\n\t\tduk_tval *tv2;\n\t\tduk_hthread *resumee;\n\n\t\t/* duk_bi_duk_object_yield() and duk_bi_duk_object_resume() ensure all of these are met */\n\n\t\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);                                                         /* unchanged by Duktape.Thread.resume() */\n\t\tDUK_ASSERT(thr->callstack_top >= 2);                                                                         /* ECMAScript activation + Duktape.Thread.resume() activation */\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL &&\n\t\t           DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)) &&\n\t\t           ((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->callstack_curr))->func == duk_bi_thread_resume);\n\n\t\ttv = &thr->heap->lj.value2;  /* resumee */\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));\n\t\tDUK_ASSERT(DUK_TVAL_GET_OBJECT(tv) != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_THREAD(DUK_TVAL_GET_OBJECT(tv)));\n\t\tresumee = (duk_hthread *) DUK_TVAL_GET_OBJECT(tv);\n\n\t\tDUK_ASSERT(resumee != NULL);\n\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\tDUK_ASSERT(resumee->state == DUK_HTHREAD_STATE_INACTIVE ||\n\t\t           resumee->state == DUK_HTHREAD_STATE_YIELDED);                                                     /* checked by Duktape.Thread.resume() */\n\t\tDUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_YIELDED ||\n\t\t           resumee->callstack_top >= 2);                                                                     /* YIELDED: ECMAScript activation + Duktape.Thread.yield() activation */\n\t\tDUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_YIELDED ||\n\t\t           (DUK_ACT_GET_FUNC(resumee->callstack_curr) != NULL &&\n\t\t            DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(resumee->callstack_curr)) &&\n\t\t            ((duk_hnatfunc *) DUK_ACT_GET_FUNC(resumee->callstack_curr))->func == duk_bi_thread_yield));\n\t\tDUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_INACTIVE ||\n\t\t           resumee->callstack_top == 0);                                                                     /* INACTIVE: no activation, single function value on valstack */\n\n\t\tif (thr->heap->lj.iserror) {\n\t\t\t/*\n\t\t\t *  Throw the error in the resumed thread's context; the\n\t\t\t *  error value is pushed onto the resumee valstack.\n\t\t\t *\n\t\t\t *  Note: the callstack of the target may empty in this case\n\t\t\t *  too (i.e. the target thread has never been resumed).  The\n\t\t\t *  value stack will contain the initial function in that case,\n\t\t\t *  which we simply ignore.\n\t\t\t */\n\n\t\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\t\tresumee->resumer = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tresumee->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tthr->state = DUK_HTHREAD_STATE_RESUMED;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumee);\n\t\t\tthr = resumee;\n\n\t\t\tthr->heap->lj.type = DUK_LJ_TYPE_THROW;\n\n\t\t\t/* thr->heap->lj.value1 is already the value to throw */\n\t\t\t/* thr->heap->lj.value2 is 'thread', will be wiped out at the end */\n\n\t\t\tDUK_ASSERT(thr->heap->lj.iserror);  /* already set */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> resume with an error, converted to a throw in the resumee, propagate\"));\n\t\t\tgoto check_longjmp;\n\t\t} else if (resumee->state == DUK_HTHREAD_STATE_YIELDED) {\n\t\t\t/* Unwind previous Duktape.Thread.yield() call.  The\n\t\t\t * activation remaining must always be an ECMAScript\n\t\t\t * call now (yield() accepts calls from ECMAScript\n\t\t\t * only).\n\t\t\t */\n\t\t\tduk_activation *act_resumee;\n\n\t\t\tDUK_ASSERT(resumee->callstack_top >= 2);\n\t\t\tact_resumee = resumee->callstack_curr;  /* Duktape.Thread.yield() */\n\t\t\tDUK_ASSERT(act_resumee != NULL);\n\t\t\tact_resumee = act_resumee->parent;      /* ECMAScript call site for yield() */\n\t\t\tDUK_ASSERT(act_resumee != NULL);\n\n\t\t\ttv = (duk_tval *) (void *) ((duk_uint8_t *) resumee->valstack + act_resumee->retval_byteoff);  /* return value from Duktape.Thread.yield() */\n\t\t\tDUK_ASSERT(tv >= resumee->valstack && tv < resumee->valstack_top);\n\t\t\ttv2 = &thr->heap->lj.value1;\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv2);  /* side effects */  /* XXX: avoid side effects */\n\n\t\t\tduk_hthread_activation_unwind_norz(resumee);  /* unwind to 'yield' caller */\n\t\t\t/* no need to unwind catch stack */\n\n\t\t\tduk__reconfig_valstack_ecma_return(resumee);\n\n\t\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\t\tresumee->resumer = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tresumee->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tthr->state = DUK_HTHREAD_STATE_RESUMED;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumee);\n#if 0\n\t\t\tthr = resumee;  /* not needed, as we exit right away */\n#endif\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> resume with a value, restart execution in resumee\"));\n\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\tgoto wipe_and_return;\n\t\t} else {\n\t\t\t/* Initial resume call. */\n\t\t\tduk_small_uint_t call_flags;\n\t\t\tduk_int_t setup_rc;\n\n\t\t\t/* resumee: [... initial_func]  (currently actually: [initial_func]) */\n\n\t\t\tduk_push_undefined(resumee);\n\t\t\ttv = &thr->heap->lj.value1;\n\t\t\tduk_push_tval(resumee, tv);\n\n\t\t\t/* resumee: [... initial_func undefined(= this) resume_value ] */\n\n\t\t\tcall_flags = DUK_CALL_FLAG_ALLOW_ECMATOECMA;  /* not tailcall, ecma-to-ecma (assumed to succeed) */\n\n\t\t\tsetup_rc = duk_handle_call_unprotected_nargs(resumee, 1 /*nargs*/, call_flags);\n\t\t\tif (setup_rc == 0) {\n\t\t\t\t/* This shouldn't happen; Duktape.Thread.resume()\n\t\t\t\t * should make sure of that.  If it does happen\n\t\t\t\t * this internal error will propagate out of the\n\t\t\t\t * executor which can be quite misleading.\n\t\t\t\t */\n\t\t\t\tDUK_ERROR_INTERNAL(thr);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\n\t\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\t\tresumee->resumer = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tresumee->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tthr->state = DUK_HTHREAD_STATE_RESUMED;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumee);\n#if 0\n\t\t\tthr = resumee;  /* not needed, as we exit right away */\n#endif\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> resume with a value, restart execution in resumee\"));\n\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\tgoto wipe_and_return;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\t\tbreak;  /* never here */\n\t}\n\n\tcase DUK_LJ_TYPE_YIELD: {\n\t\t/*\n\t\t *  Currently only allowed only if yielding thread has only\n\t\t *  ECMAScript activations (except for the Duktape.Thread.yield()\n\t\t *  call at the callstack top) and none of them constructor\n\t\t *  calls.\n\t\t *\n\t\t *  This excludes the 'entry' thread which will always have\n\t\t *  a preventcount > 0.\n\t\t */\n\n\t\tduk_hthread *resumer;\n\n\t\t/* duk_bi_duk_object_yield() and duk_bi_duk_object_resume() ensure all of these are met */\n\n#if 0  /* entry_thread not available for assert */\n\t\tDUK_ASSERT(thr != entry_thread);                                                                             /* Duktape.Thread.yield() should prevent */\n#endif\n\t\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);                                                         /* unchanged from Duktape.Thread.yield() */\n\t\tDUK_ASSERT(thr->callstack_top >= 2);                                                                         /* ECMAScript activation + Duktape.Thread.yield() activation */\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL &&\n\t\t           DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)) &&\n\t\t           ((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->callstack_curr))->func == duk_bi_thread_yield);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL &&\n\t\t           DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent)));                              /* an ECMAScript function */\n\n\t\tresumer = thr->resumer;\n\n\t\tDUK_ASSERT(resumer != NULL);\n\t\tDUK_ASSERT(resumer->state == DUK_HTHREAD_STATE_RESUMED);                                                     /* written by a previous RESUME handling */\n\t\tDUK_ASSERT(resumer->callstack_top >= 2);                                                                     /* ECMAScript activation + Duktape.Thread.resume() activation */\n\t\tDUK_ASSERT(resumer->callstack_curr != NULL);\n\t\tDUK_ASSERT(resumer->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack_curr) != NULL &&\n\t\t           DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr)) &&\n\t\t           ((duk_hnatfunc *) DUK_ACT_GET_FUNC(resumer->callstack_curr))->func == duk_bi_thread_resume);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack_curr->parent) != NULL &&\n\t\t           DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr->parent)));                            /* an ECMAScript function */\n\n\t\tif (thr->heap->lj.iserror) {\n\t\t\tthr->state = DUK_HTHREAD_STATE_YIELDED;\n\t\t\tthr->resumer = NULL;\n\t\t\tDUK_HTHREAD_DECREF_NORZ(thr, resumer);\n\t\t\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n\t\t\tthr = resumer;\n\n\t\t\tthr->heap->lj.type = DUK_LJ_TYPE_THROW;\n\t\t\t/* lj.value1 is already set */\n\t\t\tDUK_ASSERT(thr->heap->lj.iserror);  /* already set */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> yield an error, converted to a throw in the resumer, propagate\"));\n\t\t\tgoto check_longjmp;\n\t\t} else {\n\t\t\tduk_hthread_activation_unwind_norz(resumer);\n\t\t\tduk__handle_yield(thr, resumer, &thr->heap->lj.value1);\n\n\t\t\tthr->state = DUK_HTHREAD_STATE_YIELDED;\n\t\t\tthr->resumer = NULL;\n\t\t\tDUK_HTHREAD_DECREF_NORZ(thr, resumer);\n\t\t\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n#if 0\n\t\t\tthr = resumer;  /* not needed, as we exit right away */\n#endif\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> yield a value, restart execution in resumer\"));\n\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\tgoto wipe_and_return;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\t\tbreak;  /* never here */\n\t}\n#endif  /* DUK_USE_COROUTINE_SUPPORT */\n\n\tcase DUK_LJ_TYPE_THROW: {\n\t\t/*\n\t\t *  Three possible outcomes:\n\t\t *    * A try or finally catcher is found => resume there.\n\t\t *      (or)\n\t\t *    * The error propagates to the bytecode executor entry\n\t\t *      level (and we're in the entry thread) => rethrow\n\t\t *      with a new longjmp(), after restoring the previous\n\t\t *      catchpoint.\n\t\t *    * The error is not caught in the current thread, so\n\t\t *      the thread finishes with an error.  This works like\n\t\t *      a yielded error, except that the thread is finished\n\t\t *      and can no longer be resumed.  (There is always a\n\t\t *      resumer in this case.)\n\t\t *\n\t\t *  Note: until we hit the entry level, there can only be\n\t\t *  ECMAScript activations.\n\t\t */\n\n\t\tduk_activation *act;\n\t\tduk_catcher *cat;\n\t\tduk_hthread *resumer;\n\n\t\tfor (;;) {\n\t\t\tact = thr->callstack_curr;\n\t\t\tif (act == NULL) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tfor (;;) {\n\t\t\t\tcat = act->cat;\n\t\t\t\tif (cat == NULL) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (DUK_CAT_HAS_CATCH_ENABLED(cat)) {\n\t\t\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"before catch part 1: thr=%p, act=%p, cat=%p\",\n\t\t\t\t\t                     (void *) thr, (void *) act, (void *) act->cat));\n\t\t\t\t\tduk__handle_catch_part1(thr,\n\t\t\t\t\t                        &thr->heap->lj.value1,\n\t\t\t\t\t                        DUK_LJ_TYPE_THROW,\n\t\t\t\t\t\t\t        out_delayed_catch_setup);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"-> throw caught by a 'catch' clause, restart execution\"));\n\t\t\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\t\t\tgoto wipe_and_return;\n\t\t\t\t}\n\n\t\t\t\tif (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\t\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);\n\t\t\t\t\tDUK_ASSERT(!DUK_CAT_HAS_CATCH_ENABLED(cat));\n\n\t\t\t\t\tduk__handle_finally(thr,\n\t\t\t\t\t                    &thr->heap->lj.value1,\n\t\t\t\t\t                    DUK_LJ_TYPE_THROW);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"-> throw caught by a 'finally' clause, restart execution\"));\n\t\t\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\t\t\tgoto wipe_and_return;\n\t\t\t\t}\n\n\t\t\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t\t\t}\n\n\t\t\tif (act == entry_act) {\n\t\t\t\t/* Not caught by anything before entry level; rethrow and let the\n\t\t\t\t * final catcher finish unwinding (esp. value stack).\n\t\t\t\t */\n\t\t\t\tDUK_D(DUK_DPRINT(\"-> throw propagated up to entry level, rethrow and exit bytecode executor\"));\n\t\t\t\tretval = DUK__LONGJMP_RETHROW;\n\t\t\t\tgoto just_return;\n\t\t\t}\n\n\t\t\tduk_hthread_activation_unwind_norz(thr);\n\t\t}\n\n\t\tDUK_DD(DUK_DDPRINT(\"-> throw not caught by current thread, yield error to resumer and recheck longjmp\"));\n\n\t\t/* Not caught by current thread, thread terminates (yield error to resumer);\n\t\t * note that this may cause a cascade if the resumer terminates with an uncaught\n\t\t * exception etc (this is OK, but needs careful testing).\n\t\t */\n\n\t\tDUK_ASSERT(thr->resumer != NULL);\n\t\tDUK_ASSERT(thr->resumer->callstack_top >= 2);  /* ECMAScript activation + Duktape.Thread.resume() activation */\n\t\tDUK_ASSERT(thr->resumer->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->resumer->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent) != NULL &&\n\t\t           DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent)));  /* an ECMAScript function */\n\n\t\tresumer = thr->resumer;\n\n\t\t/* reset longjmp */\n\n\t\tDUK_ASSERT(thr->heap->lj.type == DUK_LJ_TYPE_THROW);  /* already set */\n\t\t/* lj.value1 already set */\n\n\t\tduk_hthread_terminate(thr);  /* updates thread state, minimizes its allocations */\n\t\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_TERMINATED);\n\n\t\tthr->resumer = NULL;\n\t\tDUK_HTHREAD_DECREF_NORZ(thr, resumer);\n\t\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n\t\tthr = resumer;\n\t\tgoto check_longjmp;\n\t}\n\n\tcase DUK_LJ_TYPE_BREAK:  /* pseudotypes, not used in actual longjmps */\n\tcase DUK_LJ_TYPE_CONTINUE:\n\tcase DUK_LJ_TYPE_RETURN:\n\tcase DUK_LJ_TYPE_NORMAL:\n\tdefault: {\n\t\t/* should never happen, but be robust */\n\t\tDUK_D(DUK_DPRINT(\"caught unknown longjmp type %ld, treat as internal error\", (long) thr->heap->lj.type));\n\t\tgoto convert_to_internal_error;\n\t}\n\n\t}  /* end switch */\n\n\tDUK_UNREACHABLE();\n\n wipe_and_return:\n\tDUK_DD(DUK_DDPRINT(\"handling longjmp done, wipe-and-return, top=%ld\",\n\t                   (long) duk_get_top(thr)));\n\tthr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;\n\tthr->heap->lj.iserror = 0;\n\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value1);  /* side effects */\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value2);  /* side effects */\n\n\tDUK_GC_TORTURE(thr->heap);\n\n just_return:\n\treturn retval;\n\n convert_to_internal_error:\n\t/* This could also be thrown internally (set the error, goto check_longjmp),\n\t * but it's better for internal errors to bubble outwards so that we won't\n\t * infinite loop in this catchpoint.\n\t */\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Handle a BREAK/CONTINUE opcode.  Avoid using longjmp() for BREAK/CONTINUE\n * handling because it has a measurable performance impact in ordinary\n * environments and an extreme impact in Emscripten (GH-342).\n */\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_break_or_continue(duk_hthread *thr,\n                                                                duk_uint_t label_id,\n                                                                duk_small_uint_t lj_type) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Find a matching label catcher or 'finally' catcher in\n\t * the same function, unwinding catchers as we go.\n\t *\n\t * A label catcher must always exist and will match unless\n\t * a 'finally' captures the break/continue first.  It is the\n\t * compiler's responsibility to ensure that labels are used\n\t * correctly.\n\t */\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\tfor (;;) {\n\t\tcat = act->cat;\n\t\tif (cat == NULL) {\n\t\t\tbreak;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"considering catcher %p: type=%ld label=%ld\",\n\t\t                     (void *) cat,\n\t\t                     (long) DUK_CAT_GET_TYPE(cat),\n\t\t                     (long) DUK_CAT_GET_LABEL(cat)));\n\n\t\t/* XXX: bit mask test; FINALLY <-> TCF, single bit mask would suffice? */\n\n\t\tif (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF &&\n\t\t    DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\t\tduk_tval tv_tmp;\n\n\t\t\tDUK_TVAL_SET_U32(&tv_tmp, (duk_uint32_t) label_id);\n\t\t\tduk__handle_finally(thr, &tv_tmp, lj_type);\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> break/continue caught by 'finally', restart execution\"));\n\t\t\treturn;\n\t\t}\n\t\tif (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_LABEL &&\n\t\t    (duk_uint_t) DUK_CAT_GET_LABEL(cat) == label_id) {\n\t\t\tduk__handle_label(thr, lj_type);\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> break/continue caught by a label catcher (in the same function), restart execution\"));\n\t\t\treturn;\n\t\t}\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t}\n\n\t/* Should never happen, but be robust. */\n\tDUK_D(DUK_DPRINT(\"-> break/continue not caught by anything in the current function (should never happen), throw internal error\"));\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Handle a RETURN opcode.  Avoid using longjmp() for return handling because\n * it has a measurable performance impact in ordinary environments and an extreme\n * impact in Emscripten (GH-342).  Return value is on value stack top.\n */\nDUK_LOCAL duk_small_uint_t duk__handle_return(duk_hthread *thr, duk_activation *entry_act) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\tduk_hthread *resumer;\n#endif\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\t/* We can directly access value stack here. */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(entry_act != NULL);\n\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\ttv1 = thr->valstack_top - 1;\n\tDUK_TVAL_CHKFAST_INPLACE_FAST(tv1);  /* fastint downgrade check for return values */\n\n\t/*\n\t *  Four possible outcomes:\n\t *\n\t *    1. A 'finally' in the same function catches the 'return'.\n\t *       It may continue to propagate when 'finally' is finished,\n\t *       or it may be neutralized by 'finally' (both handled by\n\t *       ENDFIN).\n\t *\n\t *    2. The return happens at the entry level of the bytecode\n\t *       executor, so return from the executor (in C stack).\n\t *\n\t *    3. There is a calling (ECMAScript) activation in the call\n\t *       stack => return to it, in the same executor instance.\n\t *\n\t *    4. There is no calling activation, and the thread is\n\t *       terminated.  There is always a resumer in this case,\n\t *       which gets the return value similarly to a 'yield'\n\t *       (except that the current thread can no longer be\n\t *       resumed).\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\tfor (;;) {\n\t\tcat = act->cat;\n\t\tif (cat == NULL) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF &&\n\t\t    DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\t\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\t\t\tduk__handle_finally(thr, thr->valstack_top - 1, DUK_LJ_TYPE_RETURN);\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> return caught by 'finally', restart execution\"));\n\t\t\treturn DUK__RETHAND_RESTART;\n\t\t}\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t}\n\n\tif (act == entry_act) {\n\t\t/* Return to the bytecode executor caller who will unwind stacks\n\t\t * and handle constructor post-processing.\n\t\t * Return value is already on the stack top: [ ... retval ].\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> return propagated up to entry level, exit bytecode executor\"));\n\t\treturn DUK__RETHAND_FINISHED;\n\t}\n\n\tif (thr->callstack_top >= 2) {\n\t\t/* There is a caller; it MUST be an ECMAScript caller (otherwise it would\n\t\t * match entry_act check).\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"return to ECMAScript caller, retval_byteoff=%ld, lj_value1=%!T\",\n\t\t                     (long) (thr->callstack_curr->parent->retval_byteoff),\n\t\t                     (duk_tval *) &thr->heap->lj.value1));\n\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent)));   /* must be ECMAScript */\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (thr->callstack_curr->flags & (DUK_ACT_FLAG_CONSTRUCT | DUK_ACT_FLAG_CONSTRUCT_PROXY)) {\n\t\t\tduk_call_construct_postprocess(thr, thr->callstack_curr->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY);  /* side effects */\n\t\t}\n#else\n\t\tif (thr->callstack_curr->flags & DUK_ACT_FLAG_CONSTRUCT) {\n\t\t\tduk_call_construct_postprocess(thr, 0);  /* side effects */\n\t\t}\n#endif\n\n\t\ttv1 = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + thr->callstack_curr->parent->retval_byteoff);\n\t\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\t\ttv2 = thr->valstack_top - 1;\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\n\t\t/* Catch stack unwind happens inline in callstack unwind. */\n\t\tduk_hthread_activation_unwind_norz(thr);\n\n\t\tduk__reconfig_valstack_ecma_return(thr);\n\n\t\tDUK_DD(DUK_DDPRINT(\"-> return not intercepted, restart execution in caller\"));\n\t\treturn DUK__RETHAND_RESTART;\n\t}\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\tDUK_DD(DUK_DDPRINT(\"no calling activation, thread finishes (similar to yield)\"));\n\n\tDUK_ASSERT(thr->resumer != NULL);\n\tDUK_ASSERT(thr->resumer->callstack_top >= 2);  /* ECMAScript activation + Duktape.Thread.resume() activation */\n\tDUK_ASSERT(thr->resumer->callstack_curr != NULL);\n\tDUK_ASSERT(thr->resumer->callstack_curr->parent != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr) != NULL &&\n\t\t\tDUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr)) &&\n\t\t\t((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->resumer->callstack_curr))->func == duk_bi_thread_resume);  /* Duktape.Thread.resume() */\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent) != NULL &&\n\t\t\tDUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent)));  /* an ECMAScript function */\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\tDUK_ASSERT(thr->resumer->state == DUK_HTHREAD_STATE_RESUMED);\n\n\tresumer = thr->resumer;\n\n\t/* Share yield longjmp handler.\n\t *\n\t * This sequence of steps is a bit fragile (see GH-1845):\n\t * - We need the return value from 'thr' (resumed thread) value stack.\n\t *   The termination unwinds its value stack, losing the value.\n\t * - We need a refcounted reference for 'thr', which may only exist\n\t *   in the caller value stack.  We can't unwind or reconfigure the\n\t *   caller's value stack without potentially freeing 'thr'.\n\t *\n\t * Current approach is to capture the 'thr' return value and store\n\t * a reference to 'thr' in the caller value stack temporarily.  This\n\t * keeps 'thr' reachable until final yield/return handling which\n\t * removes the references atomatically.\n\t */\n\n\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\tduk_hthread_activation_unwind_norz(resumer);  /* May remove last reference to 'thr', but is NORZ. */\n\tduk_push_tval(resumer, thr->valstack_top - 1);  /* Capture return value, side effect free. */\n\tduk_push_hthread(resumer, thr);  /* Make 'thr' reachable again, before side effects. */\n\n\tduk_hthread_terminate(thr);  /* Updates thread state, minimizes its allocations. */\n\tthr->resumer = NULL;\n\tDUK_HTHREAD_DECREF(thr, resumer);\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_TERMINATED);\n\n\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n\n\tDUK_ASSERT(resumer->valstack_top - 2 >= resumer->valstack_bottom);\n\tduk__handle_yield(thr, resumer, resumer->valstack_top - 2);\n\tthr = NULL;  /* 'thr' invalidated by call */\n\n#if 0\n\tthr = resumer;  /* not needed */\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"-> return not caught, thread terminated; handle like yield, restart execution in resumer\"));\n\treturn DUK__RETHAND_RESTART;\n#else\n\t/* Without coroutine support this case should never happen. */\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n#endif\n}\n\n/*\n *  Executor interrupt handling\n *\n *  The handler is called whenever the interrupt countdown reaches zero\n *  (or below).  The handler must perform whatever checks are activated,\n *  e.g. check for cumulative step count to impose an execution step\n *  limit or check for breakpoints or other debugger interaction.\n *\n *  When the actions are done, the handler must reinit the interrupt\n *  init and counter values.  The 'init' value must indicate how many\n *  bytecode instructions are executed before the next interrupt.  The\n *  counter must interface with the bytecode executor loop.  Concretely,\n *  the new init value is normally one higher than the new counter value.\n *  For instance, to execute exactly one bytecode instruction the init\n *  value is set to 1 and the counter to 0.  If an error is thrown by the\n *  interrupt handler, the counters are set to the same value (e.g. both\n *  to 0 to cause an interrupt when the next bytecode instruction is about\n *  to be executed after error handling).\n *\n *  Maintaining the init/counter value properly is important for accurate\n *  behavior.  For instance, executor step limit needs a cumulative step\n *  count which is simply computed as a sum of 'init' values.  This must\n *  work accurately even when single stepping.\n */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\n#define DUK__INT_NOACTION    0    /* no specific action, resume normal execution */\n#define DUK__INT_RESTART     1    /* must \"goto restart_execution\", e.g. breakpoints changed */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_immediate, duk_small_uint_t *out_interrupt_retval) {\n\tduk_activation *act;\n\tduk_breakpoint *bp;\n\tduk_breakpoint **bp_active;\n\tduk_uint_fast32_t line = 0;\n\tduk_bool_t process_messages;\n\tduk_bool_t processed_messages = 0;\n\n\tDUK_ASSERT(thr->heap->dbg_processing == 0);  /* don't re-enter e.g. during Eval */\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\t/* It might seem that replacing 'thr->heap' with just 'heap' below\n\t * might be a good idea, but it increases code size slightly\n\t * (probably due to unnecessary spilling) at least on x64.\n\t */\n\n\t/*\n\t *  Single opcode step check\n\t */\n\n\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE) {\n\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by one opcode step\"));\n\t\tduk_debug_set_paused(thr->heap);\n\t}\n\n\t/*\n\t *  Breakpoint and step state checks\n\t */\n\n\tif (act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE ||\n\t    (thr->heap->dbg_pause_act == thr->callstack_curr)) {\n\t\tline = duk_debug_curr_line(thr);\n\n\t\tif (act->prev_line != line) {\n\t\t\t/* Stepped?  Step out is handled by callstack unwind. */\n\t\t\tif ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) &&\n\t\t\t    (thr->heap->dbg_pause_act == thr->callstack_curr) &&\n\t\t\t    (line != thr->heap->dbg_pause_startline)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by line change, at line %ld\",\n\t\t\t\t                 (long) line));\n\t\t\t\tduk_debug_set_paused(thr->heap);\n\t\t\t}\n\n\t\t\t/* Check for breakpoints only on line transition.\n\t\t\t * Breakpoint is triggered when we enter the target\n\t\t\t * line from a different line, and the previous line\n\t\t\t * was within the same function.\n\t\t\t *\n\t\t\t * This condition is tricky: the condition used to be\n\t\t\t * that transition to -or across- the breakpoint line\n\t\t\t * triggered the breakpoint.  This seems intuitively\n\t\t\t * better because it handles breakpoints on lines with\n\t\t\t * no emitted opcodes; but this leads to the issue\n\t\t\t * described in: https://github.com/svaarala/duktape/issues/263.\n\t\t\t */\n\t\t\tbp_active = thr->heap->dbg_breakpoints_active;\n\t\t\tfor (;;) {\n\t\t\t\tbp = *bp_active++;\n\t\t\t\tif (bp == NULL) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tDUK_ASSERT(bp->filename != NULL);\n\t\t\t\tif (act->prev_line != bp->line && line == bp->line) {\n\t\t\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by breakpoint at %!O:%ld\",\n\t\t\t\t\t                 (duk_heaphdr *) bp->filename, (long) bp->line));\n\t\t\t\t\tduk_debug_set_paused(thr->heap);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t;\n\t\t}\n\n\t\tact->prev_line = (duk_uint32_t) line;\n\t}\n\n\t/*\n\t *  Rate limit check for sending status update or peeking into\n\t *  the debug transport.  Both can be expensive operations that\n\t *  we don't want to do on every opcode.\n\t *\n\t *  Making sure the interval remains reasonable on a wide variety\n\t *  of targets and bytecode is difficult without a timestamp, so\n\t *  we use a Date-provided timestamp for the rate limit check.\n\t *  But since it's also expensive to get a timestamp, a bytecode\n\t *  counter is used to rate limit getting timestamps.\n\t */\n\n\tprocess_messages = 0;\n\tif (thr->heap->dbg_state_dirty || DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || thr->heap->dbg_detaching) {\n\t\t/* Enter message processing loop for sending Status notifys and\n\t\t * to finish a pending detach.\n\t\t */\n\t\tprocess_messages = 1;\n\t}\n\n\t/* XXX: remove heap->dbg_exec_counter, use heap->inst_count_interrupt instead? */\n\tDUK_ASSERT(thr->interrupt_init >= 0);\n\tthr->heap->dbg_exec_counter += (duk_uint_t) thr->interrupt_init;\n\tif (thr->heap->dbg_exec_counter - thr->heap->dbg_last_counter >= DUK_HEAP_DBG_RATELIMIT_OPCODES) {\n\t\t/* Overflow of the execution counter is fine and doesn't break\n\t\t * anything here.\n\t\t */\n\n\t\tduk_double_t now, diff_last;\n\n\t\tthr->heap->dbg_last_counter = thr->heap->dbg_exec_counter;\n\t\tnow = duk_time_get_monotonic_time(thr);\n\n\t\tdiff_last = now - thr->heap->dbg_last_time;\n\t\tif (diff_last < 0.0 || diff_last >= (duk_double_t) DUK_HEAP_DBG_RATELIMIT_MILLISECS) {\n\t\t\t/* Monotonic time should not experience time jumps,\n\t\t\t * but the provider may be missing and we're actually\n\t\t\t * using ECMAScript time.  So, tolerate negative values\n\t\t\t * so that a time jump works reasonably.\n\t\t\t *\n\t\t\t * Same interval is now used for status sending and\n\t\t\t * peeking.\n\t\t\t */\n\n\t\t\tthr->heap->dbg_last_time = now;\n\t\t\tthr->heap->dbg_state_dirty = 1;\n\t\t\tprocess_messages = 1;\n\t\t}\n\t}\n\n\t/*\n\t *  Process messages and send status if necessary.\n\t *\n\t *  If we're paused, we'll block for new messages.  If we're not\n\t *  paused, we'll process anything we can peek but won't block\n\t *  for more.  Detach (and re-attach) handling is all localized\n\t *  to duk_debug_process_messages() too.\n\t *\n\t *  Debugger writes outside the message loop may cause debugger\n\t *  detach1 phase to run, after which dbg_read_cb == NULL and\n\t *  dbg_detaching != 0.  The message loop will finish the detach\n\t *  by running detach2 phase, so enter the message loop also when\n\t *  detaching.\n\t */\n\n\tif (process_messages) {\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\t\tprocessed_messages = duk_debug_process_messages(thr, 0 /*no_block*/);\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\t}\n\n\t/* Continue checked execution if there are breakpoints or we're stepping.\n\t * Also use checked execution if paused flag is active - it shouldn't be\n\t * because the debug message loop shouldn't terminate if it was.  Step out\n\t * is handled by callstack unwind and doesn't need checked execution.\n\t * Note that debugger may have detached due to error or explicit request\n\t * above, so we must recheck attach status.\n\t */\n\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t\tif (act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE ||\n\t\t    (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE) ||\n\t\t    ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) &&\n\t\t     thr->heap->dbg_pause_act == thr->callstack_curr) ||\n\t\t     DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap)) {\n\t\t\t*out_immediate = 1;\n\t\t}\n\n\t\t/* If we processed any debug messages breakpoints may have\n\t\t * changed; restart execution to re-check active breakpoints.\n\t\t */\n\t\tif (processed_messages) {\n\t\t\tDUK_D(DUK_DPRINT(\"processed debug messages, restart execution to recheck possibly changed breakpoints\"));\n\t\t\t*out_interrupt_retval = DUK__INT_RESTART;\n\t\t} else {\n\t\t\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE) {\n\t\t\t\t/* Set 'pause after one opcode' active only when we're\n\t\t\t\t * actually just about to execute code.\n\t\t\t\t */\n\t\t\t\tthr->heap->dbg_pause_flags |= DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"debugger became detached, resume normal execution\"));\n\t}\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\nDUK_LOCAL DUK__NOINLINE_PERF DUK_COLD duk_small_uint_t duk__executor_interrupt(duk_hthread *thr) {\n\tduk_int_t ctr;\n\tduk_activation *act;\n\tduk_hcompfunc *fun;\n\tduk_bool_t immediate = 0;\n\tduk_small_uint_t retval;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->callstack_top > 0);\n\n#if defined(DUK_USE_DEBUG)\n\tthr->heap->inst_count_interrupt += thr->interrupt_init;\n\tDUK_DD(DUK_DDPRINT(\"execution interrupt, counter=%ld, init=%ld, \"\n\t                   \"instruction counts: executor=%ld, interrupt=%ld\",\n\t                   (long) thr->interrupt_counter, (long) thr->interrupt_init,\n\t                   (long) thr->heap->inst_count_exec, (long) thr->heap->inst_count_interrupt));\n#endif\n\n\tretval = DUK__INT_NOACTION;\n\tctr = DUK_HTHREAD_INTCTR_DEFAULT;\n\n\t/*\n\t *  Avoid nested calls.  Concretely this happens during debugging, e.g.\n\t *  when we eval() an expression.\n\t *\n\t *  Also don't interrupt if we're currently doing debug processing\n\t *  (which can be initiated outside the bytecode executor) as this\n\t *  may cause the debugger to be called recursively.  Check required\n\t *  for correct operation of throw intercept and other \"exotic\" halting\n\t * scenarios.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (DUK_HEAP_HAS_INTERRUPT_RUNNING(thr->heap) || thr->heap->dbg_processing) {\n#else\n\tif (DUK_HEAP_HAS_INTERRUPT_RUNNING(thr->heap)) {\n#endif\n\t\tDUK_DD(DUK_DDPRINT(\"nested executor interrupt, ignoring\"));\n\n\t\t/* Set a high interrupt counter; the original executor\n\t\t * interrupt invocation will rewrite before exiting.\n\t\t */\n\t\tthr->interrupt_init = ctr;\n\t\tthr->interrupt_counter = ctr - 1;\n\t\treturn DUK__INT_NOACTION;\n\t}\n\tDUK_HEAP_SET_INTERRUPT_RUNNING(thr->heap);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC((duk_hobject *) fun));\n\n\tDUK_UNREF(fun);\n\n#if defined(DUK_USE_EXEC_TIMEOUT_CHECK)\n\t/*\n\t *  Execution timeout check\n\t */\n\n\tif (DUK_USE_EXEC_TIMEOUT_CHECK(thr->heap->heap_udata)) {\n\t\t/* Keep throwing an error whenever we get here.  The unusual values\n\t\t * are set this way because no instruction is ever executed, we just\n\t\t * throw an error until all try/catch/finally and other catchpoints\n\t\t * have been exhausted.  Duktape/C code gets control at each protected\n\t\t * call but whenever it enters back into Duktape the RangeError gets\n\t\t * raised.  User exec timeout check must consistently indicate a timeout\n\t\t * until we've fully bubbled out of Duktape.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"execution timeout, throwing a RangeError\"));\n\t\tthr->interrupt_init = 0;\n\t\tthr->interrupt_counter = 0;\n\t\tDUK_HEAP_CLEAR_INTERRUPT_RUNNING(thr->heap);\n\t\tDUK_ERROR_RANGE(thr, \"execution timeout\");\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n#endif  /* DUK_USE_EXEC_TIMEOUT_CHECK */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (!thr->heap->dbg_processing &&\n\t    (thr->heap->dbg_read_cb != NULL || thr->heap->dbg_detaching)) {\n\t\t/* Avoid recursive re-entry; enter when we're attached or\n\t\t * detaching (to finish off the pending detach).\n\t\t */\n\t\tduk__interrupt_handle_debugger(thr, &immediate, &retval);\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n\t/*\n\t *  Update the interrupt counter\n\t */\n\n\tif (immediate) {\n\t\t/* Cause an interrupt after executing one instruction. */\n\t\tctr = 1;\n\t}\n\n\t/* The counter value is one less than the init value: init value should\n\t * indicate how many instructions are executed before interrupt.  To\n\t * execute 1 instruction (after interrupt handler return), counter must\n\t * be 0.\n\t */\n\tDUK_ASSERT(ctr >= 1);\n\tthr->interrupt_init = ctr;\n\tthr->interrupt_counter = ctr - 1;\n\tDUK_HEAP_CLEAR_INTERRUPT_RUNNING(thr->heap);\n\n\treturn retval;\n}\n#endif  /* DUK_USE_INTERRUPT_COUNTER */\n\n/*\n *  Debugger handling for executor restart\n *\n *  Check for breakpoints, stepping, etc, and figure out if we should execute\n *  in checked or normal mode.  Note that we can't do this when an activation\n *  is created, because breakpoint status (and stepping status) may change\n *  later, so we must recheck every time we're executing an activation.\n *  This primitive should be side effect free to avoid changes during check.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_LOCAL void duk__executor_recheck_debugger(duk_hthread *thr, duk_activation *act, duk_hcompfunc *fun) {\n\tduk_heap *heap;\n\tduk_tval *tv_tmp;\n\tduk_hstring *filename;\n\tduk_small_uint_t bp_idx;\n\tduk_breakpoint **bp_active;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(fun != NULL);\n\n\theap = thr->heap;\n\tbp_active = heap->dbg_breakpoints_active;\n\tact->flags &= ~DUK_ACT_FLAG_BREAKPOINT_ACTIVE;\n\n\ttv_tmp = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) fun, DUK_STRIDX_FILE_NAME);\n\tif (tv_tmp && DUK_TVAL_IS_STRING(tv_tmp)) {\n\t\tfilename = DUK_TVAL_GET_STRING(tv_tmp);\n\n\t\t/* Figure out all active breakpoints.  A breakpoint is\n\t\t * considered active if the current function's fileName\n\t\t * matches the breakpoint's fileName, AND there is no\n\t\t * inner function that has matching line numbers\n\t\t * (otherwise a breakpoint would be triggered both\n\t\t * inside and outside of the inner function which would\n\t\t * be confusing).  Example:\n\t\t *\n\t\t *     function foo() {\n\t\t *         print('foo');\n\t\t *         function bar() {    <-.  breakpoints in these\n\t\t *             print('bar');     |  lines should not affect\n\t\t *         }                   <-'  foo() execution\n\t\t *         bar();\n\t\t *     }\n\t\t *\n\t\t * We need a few things that are only available when\n\t\t * debugger support is enabled: (1) a line range for\n\t\t * each function, and (2) access to the function\n\t\t * template to access the inner functions (and their\n\t\t * line ranges).\n\t\t *\n\t\t * It's important to have a narrow match for active\n\t\t * breakpoints so that we don't enter checked execution\n\t\t * when that's not necessary.  For instance, if we're\n\t\t * running inside a certain function and there's\n\t\t * breakpoint outside in (after the call site), we\n\t\t * don't want to slow down execution of the function.\n\t\t */\n\n\t\tfor (bp_idx = 0; bp_idx < heap->dbg_breakpoint_count; bp_idx++) {\n\t\t\tduk_breakpoint *bp = heap->dbg_breakpoints + bp_idx;\n\t\t\tduk_hobject **funcs, **funcs_end;\n\t\t\tduk_hcompfunc *inner_fun;\n\t\t\tduk_bool_t bp_match;\n\n\t\t\tif (bp->filename == filename &&\n\t\t\t    bp->line >= fun->start_line && bp->line <= fun->end_line) {\n\t\t\t\tbp_match = 1;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"breakpoint filename and line match: \"\n\t\t\t\t                   \"%s:%ld vs. %s (line %ld vs. %ld-%ld)\",\n\t\t\t\t                   DUK_HSTRING_GET_DATA(bp->filename),\n\t\t\t\t                   (long) bp->line,\n\t\t\t\t                   DUK_HSTRING_GET_DATA(filename),\n\t\t\t\t                   (long) bp->line,\n\t\t\t\t                   (long) fun->start_line,\n\t\t\t\t                   (long) fun->end_line));\n\n\t\t\t\tfuncs = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, fun);\n\t\t\t\tfuncs_end = DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, fun);\n\t\t\t\twhile (funcs != funcs_end) {\n\t\t\t\t\tinner_fun = (duk_hcompfunc *) *funcs;\n\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) inner_fun));\n\t\t\t\t\tif (bp->line >= inner_fun->start_line && bp->line <= inner_fun->end_line) {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"inner function masks ('captures') breakpoint\"));\n\t\t\t\t\t\tbp_match = 0;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tfuncs++;\n\t\t\t\t}\n\n\t\t\t\tif (bp_match) {\n\t\t\t\t\t/* No need to check for size of bp_active list,\n\t\t\t\t\t * it's always larger than maximum number of\n\t\t\t\t\t * breakpoints.\n\t\t\t\t\t */\n\t\t\t\t\tact->flags |= DUK_ACT_FLAG_BREAKPOINT_ACTIVE;\n\t\t\t\t\t*bp_active = heap->dbg_breakpoints + bp_idx;\n\t\t\t\t\tbp_active++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t*bp_active = NULL;  /* terminate */\n\n\tDUK_DD(DUK_DDPRINT(\"ACTIVE BREAKPOINTS: %ld\", (long) (bp_active - thr->heap->dbg_breakpoints_active)));\n\n\t/* Force pause if we were doing \"step into\" in another activation. */\n\tif ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_ENTRY) &&\n\t    thr->heap->dbg_pause_act != thr->callstack_curr) {\n\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by function entry\"));\n\t\tduk_debug_set_paused(thr->heap);\n\t}\n\n\t/* Force interrupt right away if we're paused or in \"checked mode\".\n\t * Step out is handled by callstack unwind.\n\t */\n\tif ((act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE) ||\n\t    DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) ||\n\t    ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) &&\n\t     thr->heap->dbg_pause_act == thr->callstack_curr)) {\n\t\t/* We'll need to interrupt early so recompute the init\n\t\t * counter to reflect the number of bytecode instructions\n\t\t * executed so that step counts for e.g. debugger rate\n\t\t * limiting are accurate.\n\t\t */\n\t\tDUK_ASSERT(thr->interrupt_counter <= thr->interrupt_init);\n\t\tthr->interrupt_init = thr->interrupt_init - thr->interrupt_counter;\n\t\tthr->interrupt_counter = 0;\n\t}\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/*\n *  Opcode handlers for opcodes with a lot of code and which are relatively\n *  rare; NOINLINE to reduce amount of code in main bytecode dispatcher.\n */\n\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_initset_initget(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_bool_t is_set = (DUK_DEC_OP(ins) == DUK_OP_INITSET);\n\tduk_uint_fast_t idx;\n\tduk_uint_t defprop_flags;\n\n\t/* A -> object register (acts as a source)\n\t * BC -> BC+0 contains key, BC+1 closure (value)\n\t */\n\n\t/* INITSET/INITGET are only used to initialize object literal keys.\n\t * There may be a previous propery in ES2015 because duplicate property\n\t * names are allowed.\n\t */\n\n\t/* This could be made more optimal by accessing internals directly. */\n\n\tidx = (duk_uint_fast_t) DUK_DEC_BC(ins);\n\tduk_dup(thr, (duk_idx_t) (idx + 0));  /* key */\n\tduk_dup(thr, (duk_idx_t) (idx + 1));  /* getter/setter */\n\tif (is_set) {\n\t        defprop_flags = DUK_DEFPROP_HAVE_SETTER |\n\t                        DUK_DEFPROP_FORCE |\n\t                        DUK_DEFPROP_SET_ENUMERABLE |\n\t                        DUK_DEFPROP_SET_CONFIGURABLE;\n\t} else {\n\t        defprop_flags = DUK_DEFPROP_HAVE_GETTER |\n\t                        DUK_DEFPROP_FORCE |\n\t                        DUK_DEFPROP_SET_ENUMERABLE |\n\t                        DUK_DEFPROP_SET_CONFIGURABLE;\n\t}\n\tduk_def_prop(thr, (duk_idx_t) DUK_DEC_A(ins), defprop_flags);\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_trycatch(duk_hthread *thr, duk_uint_fast32_t ins, duk_instr_t *curr_pc) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_tval *tv1;\n\tduk_small_uint_fast_t a;\n\tduk_small_uint_fast_t bc;\n\n\t/* A -> flags\n\t * BC -> reg_catch; base register for two registers used both during\n\t *       trycatch setup and when catch is triggered\n\t *\n\t *      If DUK_BC_TRYCATCH_FLAG_CATCH_BINDING set:\n\t *          reg_catch + 0: catch binding variable name (string).\n\t *          Automatic declarative environment is established for\n\t *          the duration of the 'catch' clause.\n\t *\n\t *      If DUK_BC_TRYCATCH_FLAG_WITH_BINDING set:\n\t *          reg_catch + 0: with 'target value', which is coerced to\n\t *          an object and then used as a bindind object for an\n\t *          environment record.  The binding is initialized here, for\n\t *          the 'try' clause.\n\t *\n\t * Note that a TRYCATCH generated for a 'with' statement has no\n\t * catch or finally parts.\n\t */\n\n\t/* XXX: TRYCATCH handling should be reworked to avoid creating\n\t * an explicit scope unless it is actually needed (e.g. function\n\t * instances or eval is executed inside the catch block).  This\n\t * rework is not trivial because the compiler doesn't have an\n\t * intermediate representation.  When the rework is done, the\n\t * opcode format can also be made more straightforward.\n\t */\n\n\t/* XXX: side effect handling is quite awkward here */\n\n\tDUK_DDD(DUK_DDDPRINT(\"TRYCATCH: reg_catch=%ld, have_catch=%ld, \"\n\t                     \"have_finally=%ld, catch_binding=%ld, with_binding=%ld (flags=0x%02lx)\",\n\t                     (long) DUK_DEC_BC(ins),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH ? 1 : 0),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY ? 1 : 0),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_CATCH_BINDING ? 1 : 0),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_WITH_BINDING ? 1 : 0),\n\t                     (unsigned long) DUK_DEC_A(ins)));\n\n\ta = DUK_DEC_A(ins);\n\tbc = DUK_DEC_BC(ins);\n\n\t/* Registers 'bc' and 'bc + 1' are written in longjmp handling\n\t * and if their previous values (which are temporaries) become\n\t * unreachable -and- have a finalizer, there'll be a function\n\t * call during error handling which is not supported now (GH-287).\n\t * Ensure that both 'bc' and 'bc + 1' have primitive values to\n\t * guarantee no finalizer calls in error handling.  Scrubbing also\n\t * ensures finalizers for the previous values run here rather than\n\t * later.  Error handling related values are also written to 'bc'\n\t * and 'bc + 1' but those values never become unreachable during\n\t * error handling, so there's no side effect problem even if the\n\t * error value has a finalizer.\n\t */\n\tduk_dup(thr, (duk_idx_t) bc);  /* Stabilize value. */\n\tduk_to_undefined(thr, (duk_idx_t) bc);\n\tduk_to_undefined(thr, (duk_idx_t) (bc + 1));\n\n\t/* Allocate catcher and populate it.  Doesn't have to\n\t * be fully atomic, but the catcher must be in a\n\t * consistent state if side effects (such as finalizer\n\t * calls) occur.\n\t */\n\n\tcat = duk_hthread_catcher_alloc(thr);\n\tDUK_ASSERT(cat != NULL);\n\n\tcat->flags = DUK_CAT_TYPE_TCF;\n\tcat->h_varname = NULL;\n\tcat->pc_base = (duk_instr_t *) curr_pc;  /* pre-incremented, points to first jump slot */\n\tcat->idx_base = (duk_size_t) (thr->valstack_bottom - thr->valstack) + bc;\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tcat->parent = act->cat;\n\tact->cat = cat;\n\n\tif (a & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) {\n\t\tcat->flags |= DUK_CAT_FLAG_CATCH_ENABLED;\n\t}\n\tif (a & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY) {\n\t\tcat->flags |= DUK_CAT_FLAG_FINALLY_ENABLED;\n\t}\n\tif (a & DUK_BC_TRYCATCH_FLAG_CATCH_BINDING) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"catch binding flag set to catcher\"));\n\t\tcat->flags |= DUK_CAT_FLAG_CATCH_BINDING_ENABLED;\n\t\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\n\t\t/* borrowed reference; although 'tv1' comes from a register,\n\t\t * its value was loaded using LDCONST so the constant will\n\t\t * also exist and be reachable.\n\t\t */\n\t\tcat->h_varname = DUK_TVAL_GET_STRING(tv1);\n\t} else if (a & DUK_BC_TRYCATCH_FLAG_WITH_BINDING) {\n\t\tduk_hobjenv *env;\n\t\tduk_hobject *target;\n\n\t\t/* Delayed env initialization for activation (if needed). */\n\t\tDUK_ASSERT(thr->callstack_top >= 1);\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t\tif (act->lex_env == NULL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"delayed environment initialization\"));\n\t\t\tDUK_ASSERT(act->var_env == NULL);\n\n\t\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\t\tDUK_UNREF(act);  /* 'act' is no longer accessed, scanbuild fix */\n\t\t}\n\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\tDUK_ASSERT(act->var_env != NULL);\n\n\t\t/* Coerce 'with' target. */\n\t\ttarget = duk_to_hobject(thr, -1);\n\t\tDUK_ASSERT(target != NULL);\n\n\t\t/* Create an object environment; it is not pushed\n\t\t * so avoid side effects very carefully until it is\n\t\t * referenced.\n\t\t */\n\t\tenv = duk_hobjenv_alloc(thr,\n\t\t                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\t\tDUK_ASSERT(env != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);\n\t\tenv->target = target;  /* always provideThis=true */\n\t\tDUK_HOBJECT_INCREF(thr, target);\n\t\tenv->has_this = 1;\n\t\tDUK_HOBJENV_ASSERT_VALID(env);\n\t\tDUK_DDD(DUK_DDDPRINT(\"environment for with binding: %!iO\", env));\n\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);\n\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) env, act->lex_env);\n\t\tact->lex_env = (duk_hobject *) env;  /* Now reachable. */\n\t\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) env);\n\t\t/* Net refcount change to act->lex_env is 0: incref for env's\n\t\t * prototype, decref for act->lex_env overwrite.\n\t\t */\n\n\t\t/* Set catcher lex_env active (affects unwind)\n\t\t * only when the whole setup is complete.\n\t\t */\n\t\tcat = act->cat;  /* XXX: better to relookup? not mandatory because 'cat' is stable */\n\t\tcat->flags |= DUK_CAT_FLAG_LEXENV_ACTIVE;\n\t} else {\n\t\t;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"TRYCATCH catcher: flags=0x%08lx, pc_base=%ld, \"\n\t                     \"idx_base=%ld, h_varname=%!O\",\n\t                     (unsigned long) cat->flags,\n\t                     (long) cat->pc_base, (long) cat->idx_base, (duk_heaphdr *) cat->h_varname));\n\n\tduk_pop_unsafe(thr);\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_instr_t *duk__handle_op_endtry(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_tval *tv1;\n\tduk_instr_t *pc_base;\n\n\tDUK_UNREF(ins);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);\n\n\tDUK_DDD(DUK_DDDPRINT(\"ENDTRY: clearing catch active flag (regardless of whether it was set or not)\"));\n\tDUK_CAT_CLEAR_CATCH_ENABLED(cat);\n\n\tpc_base = cat->pc_base;\n\n\tif (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDTRY: finally part is active, jump through 2nd jump slot with 'normal continuation'\"));\n\n\t\ttv1 = thr->valstack + cat->idx_base;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\ttv1 = thr->valstack + cat->idx_base + 1;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_U32_UPDREF(thr, tv1, (duk_uint32_t) DUK_LJ_TYPE_NORMAL);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\tDUK_CAT_CLEAR_FINALLY_ENABLED(cat);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDTRY: no finally part, dismantle catcher, jump through 2nd jump slot (to end of statement)\"));\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);  /* lexenv may be set for 'with' binding */\n\t\t/* no need to unwind callstack */\n\t}\n\n\treturn pc_base + 1;  /* new curr_pc value */\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_instr_t *duk__handle_op_endcatch(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_tval *tv1;\n\tduk_instr_t *pc_base;\n\n\tDUK_UNREF(ins);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(!DUK_CAT_HAS_CATCH_ENABLED(cat));  /* cleared before entering catch part */\n\n\tif (DUK_CAT_HAS_LEXENV_ACTIVE(cat)) {\n\t\tduk_hobject *prev_env;\n\n\t\t/* 'with' binding has no catch clause, so can't be here unless a normal try-catch */\n\t\tDUK_ASSERT(DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat));\n\t\tDUK_ASSERT(act->lex_env != NULL);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDCATCH: popping catcher part lexical environment\"));\n\n\t\tprev_env = act->lex_env;\n\t\tDUK_ASSERT(prev_env != NULL);\n\t\tact->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, prev_env);\n\t\tDUK_CAT_CLEAR_LEXENV_ACTIVE(cat);\n\t\tDUK_HOBJECT_INCREF(thr, act->lex_env);\n\t\tDUK_HOBJECT_DECREF(thr, prev_env);  /* side effects */\n\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t}\n\n\tpc_base = cat->pc_base;\n\n\tif (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDCATCH: finally part is active, jump through 2nd jump slot with 'normal continuation'\"));\n\n\t\ttv1 = thr->valstack + cat->idx_base;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\ttv1 = thr->valstack + cat->idx_base + 1;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_U32_UPDREF(thr, tv1, (duk_uint32_t) DUK_LJ_TYPE_NORMAL);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\tDUK_CAT_CLEAR_FINALLY_ENABLED(cat);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDCATCH: no finally part, dismantle catcher, jump through 2nd jump slot (to end of statement)\"));\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t\t/* no need to unwind callstack */\n\t}\n\n\treturn pc_base + 1;  /* new curr_pc value */\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_small_uint_t duk__handle_op_endfin(duk_hthread *thr, duk_uint_fast32_t ins, duk_activation *entry_act) {\n\tduk_activation *act;\n\tduk_tval *tv1;\n\tduk_uint_t reg_catch;\n\tduk_small_uint_t cont_type;\n\tduk_small_uint_t ret_result;\n\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\treg_catch = DUK_DEC_ABC(ins);\n\n\t/* CATCH flag may be enabled or disabled here; it may be enabled if\n\t * the statement has a catch block but the try block does not throw\n\t * an error.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: completion value=%!T, type=%!T\",\n\t                     (duk_tval *) (thr->valstack_bottom + reg_catch + 0),\n\t                     (duk_tval *) (thr->valstack_bottom + reg_catch + 1)));\n\n\ttv1 = thr->valstack_bottom + reg_catch + 1;  /* type */\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\tcont_type = (duk_small_uint_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\tcont_type = (duk_small_uint_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\n\ttv1--;  /* value */\n\n\tswitch (cont_type) {\n\tcase DUK_LJ_TYPE_NORMAL: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: finally part finishing with 'normal' (non-abrupt) completion -> \"\n\t\t                     \"dismantle catcher, resume execution after ENDFIN\"));\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t\t/* no need to unwind callstack */\n\t\treturn 0;  /* restart execution */\n\t}\n\tcase DUK_LJ_TYPE_RETURN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: finally part finishing with 'return' complation -> dismantle \"\n\t\t                     \"catcher, handle return, lj.value1=%!T\", tv1));\n\n\t\t/* Not necessary to unwind catch stack: return handling will\n\t\t * do it.  The finally flag of 'cat' is no longer set.  The\n\t\t * catch flag may be set, but it's not checked by return handling.\n\t\t */\n\n\t\tduk_push_tval(thr, tv1);\n\t\tret_result = duk__handle_return(thr, entry_act);\n\t\tif (ret_result == DUK__RETHAND_RESTART) {\n\t\t\treturn 0;  /* restart execution */\n\t\t}\n\t\tDUK_ASSERT(ret_result == DUK__RETHAND_FINISHED);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"exiting executor after ENDFIN and RETURN (pseudo) longjmp type\"));\n\t\treturn 1;  /* exit executor */\n\t}\n\tcase DUK_LJ_TYPE_BREAK:\n\tcase DUK_LJ_TYPE_CONTINUE: {\n\t\tduk_uint_t label_id;\n\t\tduk_small_uint_t lj_type;\n\n\t\t/* Not necessary to unwind catch stack: break/continue\n\t\t * handling will do it.  The finally flag of 'cat' is\n\t\t * no longer set.  The catch flag may be set, but it's\n\t\t * not checked by break/continue handling.\n\t\t */\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\tlabel_id = (duk_small_uint_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\t\tlabel_id = (duk_small_uint_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\tlj_type = cont_type;\n\t\tduk__handle_break_or_continue(thr, label_id, lj_type);\n\t\treturn 0;  /* restart execution */\n\t}\n\tdefault: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: finally part finishing with abrupt completion, lj_type=%ld -> \"\n\t\t                     \"dismantle catcher, re-throw error\",\n\t\t                     (long) cont_type));\n\n\t\tduk_err_setup_ljstate1(thr, (duk_small_uint_t) cont_type, tv1);\n\t\t/* No debugger Throw notify check on purpose (rethrow). */\n\n\t\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* always in executor */\n\t\tduk_err_longjmp(thr);\n\t\tDUK_UNREACHABLE();\n\t}\n\t}\n\n\tDUK_UNREACHABLE();\n\treturn 0;\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_initenum(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_small_uint_t b;\n\tduk_small_uint_t c;\n\n\t/*\n\t *  Enumeration semantics come from for-in statement, E5 Section 12.6.4.\n\t *  If called with 'null' or 'undefined', this opcode returns 'null' as\n\t *  the enumerator, which is special cased in NEXTENUM.  This simplifies\n\t *  the compiler part\n\t */\n\n\t/* B -> register for writing enumerator object\n\t * C -> value to be enumerated (register)\n\t */\n\tb = DUK_DEC_B(ins);\n\tc = DUK_DEC_C(ins);\n\n\tif (duk_is_null_or_undefined(thr, (duk_idx_t) c)) {\n\t\tduk_push_null(thr);\n\t\tduk_replace(thr, (duk_idx_t) b);\n\t} else {\n\t\tduk_dup(thr, (duk_idx_t) c);\n\t\tduk_to_object(thr, -1);\n\t\tduk_hobject_enumerator_create(thr, 0 /*enum_flags*/);  /* [ ... val ] --> [ ... enum ] */\n\t\tduk_replace(thr, (duk_idx_t) b);\n\t}\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_small_uint_t duk__handle_op_nextenum(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_small_uint_t b;\n\tduk_small_uint_t c;\n\tduk_small_uint_t pc_skip = 0;\n\n\t/*\n\t *  NEXTENUM checks whether the enumerator still has unenumerated\n\t *  keys.  If so, the next key is loaded to the target register\n\t *  and the next instruction is skipped.  Otherwise the next instruction\n\t *  will be executed, jumping out of the enumeration loop.\n\t */\n\n\t/* B -> target register for next key\n\t * C -> enum register\n\t */\n\tb = DUK_DEC_B(ins);\n\tc = DUK_DEC_C(ins);\n\n\tDUK_DDD(DUK_DDDPRINT(\"NEXTENUM: b->%!T, c->%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, (duk_idx_t) b),\n\t                     (duk_tval *) duk_get_tval(thr, (duk_idx_t) c)));\n\n\tif (duk_is_object(thr, (duk_idx_t) c)) {\n\t\t/* XXX: assert 'c' is an enumerator */\n\t\tduk_dup(thr, (duk_idx_t) c);\n\t\tif (duk_hobject_enumerator_next(thr, 0 /*get_value*/)) {\n\t\t\t/* [ ... enum ] -> [ ... next_key ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"enum active, next key is %!T, skip jump slot \",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tpc_skip = 1;\n\t\t} else {\n\t\t\t/* [ ... enum ] -> [ ... ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"enum finished, execute jump slot\"));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* valstack policy */\n\t\t\tthr->valstack_top++;\n\t\t}\n\t\tduk_replace(thr, (duk_idx_t) b);\n\t} else {\n\t\t/* 'null' enumerator case -> behave as with an empty enumerator */\n\t\tDUK_ASSERT(duk_is_null(thr, (duk_idx_t) c));\n\t\tDUK_DDD(DUK_DDDPRINT(\"enum is null, execute jump slot\"));\n\t}\n\n\treturn pc_skip;\n}\n\n/*\n *  Call handling helpers.\n */\n\nDUK_LOCAL duk_bool_t duk__executor_handle_call(duk_hthread *thr, duk_idx_t idx, duk_idx_t nargs, duk_small_uint_t call_flags) {\n\tduk_bool_t rc;\n\n\tduk_set_top_unsafe(thr, (duk_idx_t) (idx + nargs + 2));   /* [ ... func this arg1 ... argN ] */\n\n\t/* Attempt an Ecma-to-Ecma call setup.  If the call\n\t * target is (directly or indirectly) Reflect.construct(),\n\t * the call may change into a constructor call on the fly.\n\t */\n\trc = (duk_bool_t) duk_handle_call_unprotected(thr, idx, call_flags);\n\tif (rc != 0) {\n\t\t/* Ecma-to-ecma call possible, may or may not\n\t\t * be a tail call.  Avoid C recursion by\n\t\t * reusing current executor instance.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"ecma-to-ecma call setup possible, restart execution\"));\n\t\t/* curr_pc synced by duk_handle_call_unprotected() */\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\treturn rc;\n\t} else {\n\t\t/* Call was handled inline. */\n\t}\n\tDUK_ASSERT(thr->ptr_curr_pc != NULL);\n\treturn rc;\n}\n\n/*\n *  ECMAScript bytecode executor.\n *\n *  Resume execution for the current thread from its current activation.\n *  Returns when execution would return from the entry level activation,\n *  leaving a single return value on top of the stack.  Function calls\n *  and thread resumptions are handled internally.  If an error occurs,\n *  a longjmp() with type DUK_LJ_TYPE_THROW is called on the entry level\n *  setjmp() jmpbuf.\n *\n *  ECMAScript function calls and coroutine resumptions are handled\n *  internally (by the outer executor function) without recursive C calls.\n *  Other function calls are handled using duk_handle_call(), increasing\n *  C recursion depth.\n *\n *  Abrupt completions (= long control tranfers) are handled either\n *  directly by reconfiguring relevant stacks and restarting execution,\n *  or via a longjmp.  Longjmp-free handling is preferable for performance\n *  (especially Emscripten performance), and is used for: break, continue,\n *  and return.\n *\n *  For more detailed notes, see doc/execution.rst.\n *\n *  Also see doc/code-issues.rst for discussion of setjmp(), longjmp(),\n *  and volatile.\n */\n\n/* Presence of 'fun' is config based, there's a marginal performance\n * difference and the best option is architecture dependent.\n */\n#if defined(DUK_USE_EXEC_FUN_LOCAL)\n#define DUK__FUN()          fun\n#else\n#define DUK__FUN()          ((duk_hcompfunc *) DUK_ACT_GET_FUNC((thr)->callstack_curr))\n#endif\n\n/* Strict flag. */\n#define DUK__STRICT()       ((duk_small_uint_t) DUK_HOBJECT_HAS_STRICT((duk_hobject *) DUK__FUN()))\n\n/* Reg/const access macros: these are very footprint and performance sensitive\n * so modify with care.  Arguments are sometimes evaluated multiple times which\n * is not ideal.\n */\n#define DUK__REG(x)         (*(thr->valstack_bottom + (x)))\n#define DUK__REGP(x)        (thr->valstack_bottom + (x))\n#define DUK__CONST(x)       (*(consts + (x)))\n#define DUK__CONSTP(x)      (consts + (x))\n\n/* Reg/const access macros which take the 32-bit instruction and avoid an\n * explicit field decoding step by using shifts and masks.  These must be\n * kept in sync with duk_js_bytecode.h.  The shift/mask values are chosen\n * so that 'ins' can be shifted and masked and used as a -byte- offset\n * instead of a duk_tval offset which needs further shifting (which is an\n * issue on some, but not all, CPUs).\n */\n#define DUK__RCBIT_B           DUK_BC_REGCONST_B\n#define DUK__RCBIT_C           DUK_BC_REGCONST_C\n#if defined(DUK_USE_EXEC_REGCONST_OPTIMIZE)\n#if defined(DUK_USE_PACKED_TVAL)\n#define DUK__TVAL_SHIFT        3  /* sizeof(duk_tval) == 8 */\n#else\n#define DUK__TVAL_SHIFT        4  /* sizeof(duk_tval) == 16; not always the case so also asserted for */\n#endif\n#define DUK__SHIFT_A           (DUK_BC_SHIFT_A - DUK__TVAL_SHIFT)\n#define DUK__SHIFT_B           (DUK_BC_SHIFT_B - DUK__TVAL_SHIFT)\n#define DUK__SHIFT_C           (DUK_BC_SHIFT_C - DUK__TVAL_SHIFT)\n#define DUK__SHIFT_BC          (DUK_BC_SHIFT_BC - DUK__TVAL_SHIFT)\n#define DUK__MASK_A            (DUK_BC_UNSHIFTED_MASK_A << DUK__TVAL_SHIFT)\n#define DUK__MASK_B            (DUK_BC_UNSHIFTED_MASK_B << DUK__TVAL_SHIFT)\n#define DUK__MASK_C            (DUK_BC_UNSHIFTED_MASK_C << DUK__TVAL_SHIFT)\n#define DUK__MASK_BC           (DUK_BC_UNSHIFTED_MASK_BC << DUK__TVAL_SHIFT)\n#define DUK__BYTEOFF_A(ins)    (((ins) >> DUK__SHIFT_A) & DUK__MASK_A)\n#define DUK__BYTEOFF_B(ins)    (((ins) >> DUK__SHIFT_B) & DUK__MASK_B)\n#define DUK__BYTEOFF_C(ins)    (((ins) >> DUK__SHIFT_C) & DUK__MASK_C)\n#define DUK__BYTEOFF_BC(ins)   (((ins) >> DUK__SHIFT_BC) & DUK__MASK_BC)\n\n#define DUK__REGP_A(ins)       ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_A((ins))))\n#define DUK__REGP_B(ins)       ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_B((ins))))\n#define DUK__REGP_C(ins)       ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_C((ins))))\n#define DUK__REGP_BC(ins)      ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_BC((ins))))\n#define DUK__CONSTP_A(ins)     ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_A((ins))))\n#define DUK__CONSTP_B(ins)     ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_B((ins))))\n#define DUK__CONSTP_C(ins)     ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_C((ins))))\n#define DUK__CONSTP_BC(ins)    ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_BC((ins))))\n#define DUK__REGCONSTP_B(ins)  ((duk_tval *) (void *) ((duk_uint8_t *) (((ins) & DUK__RCBIT_B) ? consts : thr->valstack_bottom) + DUK__BYTEOFF_B((ins))))\n#define DUK__REGCONSTP_C(ins)  ((duk_tval *) (void *) ((duk_uint8_t *) (((ins) & DUK__RCBIT_C) ? consts : thr->valstack_bottom) + DUK__BYTEOFF_C((ins))))\n#else  /* DUK_USE_EXEC_REGCONST_OPTIMIZE */\n/* Safe alternatives, no assumption about duk_tval size. */\n#define DUK__REGP_A(ins)       DUK__REGP(DUK_DEC_A((ins)))\n#define DUK__REGP_B(ins)       DUK__REGP(DUK_DEC_B((ins)))\n#define DUK__REGP_C(ins)       DUK__REGP(DUK_DEC_C((ins)))\n#define DUK__REGP_BC(ins)      DUK__REGP(DUK_DEC_BC((ins)))\n#define DUK__CONSTP_A(ins)     DUK__CONSTP(DUK_DEC_A((ins)))\n#define DUK__CONSTP_B(ins)     DUK__CONSTP(DUK_DEC_B((ins)))\n#define DUK__CONSTP_C(ins)     DUK__CONSTP(DUK_DEC_C((ins)))\n#define DUK__CONSTP_BC(ins)    DUK__CONSTP(DUK_DEC_BC((ins)))\n#define DUK__REGCONSTP_B(ins)  ((((ins) & DUK__RCBIT_B) ? consts : thr->valstack_bottom) + DUK_DEC_B((ins)))\n#define DUK__REGCONSTP_C(ins)  ((((ins) & DUK__RCBIT_C) ? consts : thr->valstack_bottom) + DUK_DEC_C((ins)))\n#endif  /* DUK_USE_EXEC_REGCONST_OPTIMIZE */\n\n#if defined(DUK_USE_VERBOSE_EXECUTOR_ERRORS)\n#define DUK__INTERNAL_ERROR(msg)  do { \\\n\t\tDUK_ERROR_ERROR(thr, (msg)); \\\n\t\tDUK_WO_NORETURN(return;); \\\n\t} while (0)\n#else\n#define DUK__INTERNAL_ERROR(msg)  do { \\\n\t\tgoto internal_error; \\\n\t} while (0)\n#endif\n\n#define DUK__SYNC_CURR_PC()  do { \\\n\t\tduk_activation *duk__act; \\\n\t\tduk__act = thr->callstack_curr; \\\n\t\tduk__act->curr_pc = curr_pc; \\\n\t} while (0)\n#define DUK__SYNC_AND_NULL_CURR_PC()  do { \\\n\t\tduk_activation *duk__act; \\\n\t\tduk__act = thr->callstack_curr; \\\n\t\tduk__act->curr_pc = curr_pc; \\\n\t\tthr->ptr_curr_pc = NULL; \\\n\t} while (0)\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n#define DUK__LOOKUP_INDIRECT(idx) do { \\\n\t\t(idx) = (duk_uint_fast_t) duk_get_uint(thr, (duk_idx_t) (idx)); \\\n\t} while (0)\n#elif defined(DUK_USE_FASTINT)\n#define DUK__LOOKUP_INDIRECT(idx) do { \\\n\t\tduk_tval *tv_ind; \\\n\t\ttv_ind = DUK__REGP((idx)); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_ind)); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv_ind));  /* compiler guarantees */ \\\n\t\t(idx) = (duk_uint_fast_t) DUK_TVAL_GET_FASTINT_U32(tv_ind); \\\n\t} while (0)\n#else\n#define DUK__LOOKUP_INDIRECT(idx) do { \\\n\t\tduk_tval *tv_ind; \\\n\t\ttv_ind = DUK__REGP(idx); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_ind)); \\\n\t\tidx = (duk_uint_fast_t) DUK_TVAL_GET_NUMBER(tv_ind); \\\n\t} while (0)\n#endif\n\nDUK_LOCAL void duk__handle_executor_error(duk_heap *heap,\n                                          duk_activation *entry_act,\n                                          duk_int_t entry_call_recursion_depth,\n                                          duk_jmpbuf *entry_jmpbuf_ptr,\n                                          volatile duk_bool_t *out_delayed_catch_setup) {\n\tduk_small_uint_t lj_ret;\n\n\t/* Longjmp callers are required to sync-and-null thr->ptr_curr_pc\n\t * before longjmp.\n\t */\n\tDUK_ASSERT(heap->curr_thread != NULL);\n\tDUK_ASSERT(heap->curr_thread->ptr_curr_pc == NULL);\n\n\t/* XXX: signalling the need to shrink check (only if unwound) */\n\n\t/* Must be restored here to handle e.g. yields properly. */\n\theap->call_recursion_depth = entry_call_recursion_depth;\n\n\t/* Switch to caller's setjmp() catcher so that if an error occurs\n\t * during error handling, it is always propagated outwards instead\n\t * of causing an infinite loop in our own handler.\n\t */\n\theap->lj.jmpbuf_ptr = (duk_jmpbuf *) entry_jmpbuf_ptr;\n\n\tlj_ret = duk__handle_longjmp(heap->curr_thread, entry_act, out_delayed_catch_setup);\n\n\t/* Error handling complete, remove side effect protections.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(heap->error_not_allowed == 1);\n\theap->error_not_allowed = 0;\n#endif\n\tDUK_ASSERT(heap->pf_prevent_count > 0);\n\theap->pf_prevent_count--;\n\tDUK_DD(DUK_DDPRINT(\"executor error handled, pf_prevent_count updated to %ld\", (long) heap->pf_prevent_count));\n\n\tif (lj_ret == DUK__LONGJMP_RESTART) {\n\t\t/* Restart bytecode execution, possibly with a changed thread. */\n\t\tDUK_REFZERO_CHECK_SLOW(heap->curr_thread);\n\t} else {\n\t\t/* If an error is propagated, don't run refzero checks here.\n\t\t * The next catcher will deal with that.  Pf_prevent_count\n\t\t * will be re-bumped by the longjmp.\n\t\t */\n\n\t\tDUK_ASSERT(lj_ret == DUK__LONGJMP_RETHROW);  /* Rethrow error to calling state. */\n\t\tDUK_ASSERT(heap->lj.jmpbuf_ptr == entry_jmpbuf_ptr);  /* Longjmp handling has restored jmpbuf_ptr. */\n\n\t\t/* Thread may have changed, e.g. YIELD converted to THROW. */\n\t\tduk_err_longjmp(heap->curr_thread);\n\t\tDUK_UNREACHABLE();\n\t}\n}\n\n/* Outer executor with setjmp/longjmp handling. */\nDUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {\n\t/* Entry level info. */\n\tduk_hthread *entry_thread;\n\tduk_activation *entry_act;\n\tduk_int_t entry_call_recursion_depth;\n\tduk_jmpbuf *entry_jmpbuf_ptr;\n\tduk_jmpbuf our_jmpbuf;\n\tduk_heap *heap;\n\tvolatile duk_bool_t delayed_catch_setup = 0;\n\n\tDUK_ASSERT(exec_thr != NULL);\n\tDUK_ASSERT(exec_thr->heap != NULL);\n\tDUK_ASSERT(exec_thr->heap->curr_thread != NULL);\n\tDUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR((duk_heaphdr *) exec_thr);\n\tDUK_ASSERT(exec_thr->callstack_top >= 1);  /* at least one activation, ours */\n\tDUK_ASSERT(exec_thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(exec_thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(exec_thr->callstack_curr)));\n\n\tDUK_GC_TORTURE(exec_thr->heap);\n\n\tentry_thread = exec_thr;\n\theap = entry_thread->heap;\n\tentry_act = entry_thread->callstack_curr;\n\tDUK_ASSERT(entry_act != NULL);\n\tentry_call_recursion_depth = entry_thread->heap->call_recursion_depth;\n\tentry_jmpbuf_ptr = entry_thread->heap->lj.jmpbuf_ptr;\n\n\t/*\n\t *  Note: we currently assume that the setjmp() catchpoint is\n\t *  not re-entrant (longjmp() cannot be called more than once\n\t *  for a single setjmp()).\n\t *\n\t *  See doc/code-issues.rst for notes on variable assignment\n\t *  before and after setjmp().\n\t */\n\n\tfor (;;) {\n\t\theap->lj.jmpbuf_ptr = &our_jmpbuf;\n\t\tDUK_ASSERT(heap->lj.jmpbuf_ptr != NULL);\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\ttry {\n#else\n\t\tDUK_ASSERT(heap->lj.jmpbuf_ptr == &our_jmpbuf);\n\t\tif (DUK_SETJMP(our_jmpbuf.jb) == 0) {\n#endif\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"after setjmp, delayed catch setup: %ld\\n\", (long) delayed_catch_setup));\n\n\t\t\tif (DUK_UNLIKELY(delayed_catch_setup != 0)) {\n\t\t\t\tduk_hthread *thr = entry_thread->heap->curr_thread;\n\n\t\t\t\tdelayed_catch_setup = 0;\n\t\t\t\tduk__handle_catch_part2(thr);\n\t\t\t\tDUK_ASSERT(delayed_catch_setup == 0);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"top after delayed catch setup: %ld\", (long) duk_get_top(entry_thread)));\n\t\t\t}\n\n\t\t\t/* Execute bytecode until returned or longjmp(). */\n\t\t\tduk__js_execute_bytecode_inner(entry_thread, entry_act);\n\n\t\t\t/* Successful return: restore jmpbuf and return to caller. */\n\t\t\theap->lj.jmpbuf_ptr = entry_jmpbuf_ptr;\n\n\t\t\treturn;\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\t} catch (duk_internal_exception &exc) {\n#else\n\t\t} else {\n#endif\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\t\tDUK_UNREF(exc);\n#endif\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"longjmp caught by bytecode executor\"));\n\t\t\tDUK_STATS_INC(exec_thr->heap, stats_exec_throw);\n\n\t\t\tduk__handle_executor_error(heap,\n\t\t\t                           entry_act,\n\t\t\t                           entry_call_recursion_depth,\n\t\t\t                           entry_jmpbuf_ptr,\n\t\t\t\t\t\t   &delayed_catch_setup);\n\t\t}\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\tcatch (duk_fatal_exception &exc) {\n\t\t\tDUK_D(DUK_DPRINT(\"rethrow duk_fatal_exception\"));\n\t\t\tthrow;\n\t\t} catch (std::exception &exc) {\n\t\t\tconst char *what = exc.what();\n\t\t\tif (!what) {\n\t\t\t\twhat = \"unknown\";\n\t\t\t}\n\t\t\tDUK_D(DUK_DPRINT(\"unexpected c++ std::exception (perhaps thrown by user code)\"));\n\t\t\tDUK_STATS_INC(exec_thr->heap, stats_exec_throw);\n\t\t\ttry {\n\t\t\t\tDUK_ASSERT(heap->curr_thread != NULL);\n\t\t\t\tDUK_ERROR_FMT1(heap->curr_thread, DUK_ERR_TYPE_ERROR, \"caught invalid c++ std::exception '%s' (perhaps thrown by user code)\", what);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t} catch (duk_internal_exception exc) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ std::exception\"));\n\t\t\t\tDUK_UNREF(exc);\n\t\t\t\tduk__handle_executor_error(heap,\n\t\t\t\t                           entry_act,\n\t\t\t\t                           entry_call_recursion_depth,\n\t\t\t\t                           entry_jmpbuf_ptr,\n\t\t\t\t\t\t\t   &delayed_catch_setup);\n\t\t\t}\n\t\t} catch (...) {\n\t\t\tDUK_D(DUK_DPRINT(\"unexpected c++ exception (perhaps thrown by user code)\"));\n\t\t\tDUK_STATS_INC(exec_thr->heap, stats_exec_throw);\n\t\t\ttry {\n\t\t\t\tDUK_ASSERT(heap->curr_thread != NULL);\n\t\t\t\tDUK_ERROR_TYPE(heap->curr_thread, \"caught invalid c++ exception (perhaps thrown by user code)\");\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t} catch (duk_internal_exception exc) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ exception\"));\n\t\t\t\tDUK_UNREF(exc);\n\t\t\t\tduk__handle_executor_error(heap,\n\t\t\t\t                           entry_act,\n\t\t\t\t                           entry_call_recursion_depth,\n\t\t\t\t                           entry_jmpbuf_ptr,\n\t\t\t\t\t\t\t   &delayed_catch_setup);\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Inner executor, performance critical. */\nDUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, duk_activation *entry_act) {\n\t/* Current PC, accessed by other functions through thr->ptr_to_curr_pc.\n\t * Critical for performance.  It would be safest to make this volatile,\n\t * but that eliminates performance benefits; aliasing guarantees\n\t * should be enough though.\n\t */\n\tduk_instr_t *curr_pc;         /* bytecode has a stable pointer */\n\n\t/* Hot variables for interpretation.  Critical for performance,\n\t * but must add sparingly to minimize register shuffling.\n\t */\n\tduk_hthread *thr;             /* stable */\n\tduk_tval *consts;             /* stable */\n\tduk_uint_fast32_t ins;\n\t/* 'funcs' is quite rarely used, so no local for it */\n#if defined(DUK_USE_EXEC_FUN_LOCAL)\n\tduk_hcompfunc *fun;\n#else\n\t/* 'fun' is quite rarely used, so no local for it */\n#endif\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\tduk_int_t int_ctr;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_size_t valstack_top_base;    /* valstack top, should match before interpreting each op (no leftovers) */\n#endif\n\n\t/* Optimized reg/const access macros assume sizeof(duk_tval) to be\n\t * either 8 or 16.  Heap allocation checks this even without asserts\n\t * enabled now because it can't be autodetected in duk_config.h.\n\t */\n#if 1\n#if defined(DUK_USE_PACKED_TVAL)\n\tDUK_ASSERT(sizeof(duk_tval) == 8);\n#else\n\tDUK_ASSERT(sizeof(duk_tval) == 16);\n#endif\n#endif\n\n\tDUK_GC_TORTURE(entry_thread->heap);\n\n\t/*\n\t *  Restart execution by reloading thread state.\n\t *\n\t *  Note that 'thr' and any thread configuration may have changed,\n\t *  so all local variables are suspect and we need to reinitialize.\n\t *\n\t *  The number of local variables should be kept to a minimum: if\n\t *  the variables are spilled, they will need to be loaded from\n\t *  memory anyway.\n\t *\n\t *  Any 'goto restart_execution;' code path in opcode dispatch must\n\t *  ensure 'curr_pc' is synced back to act->curr_pc before the goto\n\t *  takes place.\n\t *\n\t *  The interpreter must be very careful with memory pointers, as\n\t *  many pointers are not guaranteed to be 'stable' and may be\n\t *  reallocated and relocated on-the-fly quite easily (e.g. by a\n\t *  memory allocation or a property access).\n\t *\n\t *  The following are assumed to have stable pointers:\n\t *    - the current thread\n\t *    - the current function\n\t *    - the bytecode, constant table, inner function table of the\n\t *      current function (as they are a part of the function allocation)\n\t *\n\t *  The following are assumed to have semi-stable pointers:\n\t *    - the current activation entry: stable as long as callstack\n\t *      is not changed (reallocated by growing or shrinking), or\n\t *      by any garbage collection invocation (through finalizers)\n\t *    - Note in particular that ANY DECREF can invalidate the\n\t *      activation pointer, so for the most part a fresh lookup\n\t *      is required\n\t *\n\t *  The following are not assumed to have stable pointers at all:\n\t *    - the value stack (registers) of the current thread\n\t *\n\t *  See execution.rst for discussion.\n\t */\n\n restart_execution:\n\n\t/* Lookup current thread; use the stable 'entry_thread' for this to\n\t * avoid clobber warnings.  Any valid, reachable 'thr' value would be\n\t * fine for this, so using 'entry_thread' is just to silence warnings.\n\t */\n\tthr = entry_thread->heap->curr_thread;\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\tDUK_GC_TORTURE(thr->heap);\n\n\tthr->ptr_curr_pc = &curr_pc;\n\n\t/* Relookup and initialize dispatch loop variables.  Debugger check. */\n\t{\n\t\tduk_activation *act;\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\tduk_hcompfunc *fun;\n#endif\n\n\t\t/* Assume interrupt init/counter are properly initialized here. */\n\t\t/* Assume that thr->valstack_bottom has been set-up before getting here. */\n\n\t\tact = thr->callstack_curr;\n\t\tDUK_ASSERT(act != NULL);\n\t\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\t\tDUK_ASSERT(fun != NULL);\n\t\tDUK_ASSERT(thr->valstack_top - thr->valstack_bottom == fun->nregs);\n\t\tconsts = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, fun);\n\t\tDUK_ASSERT(consts != NULL);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tif (DUK_UNLIKELY(duk_debug_is_attached(thr->heap) && !thr->heap->dbg_processing)) {\n\t\t\tduk__executor_recheck_debugger(thr, act, fun);\n\t\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\tvalstack_top_base = (duk_size_t) (thr->valstack_top - thr->valstack);\n#endif\n\n\t\t/* Set up curr_pc for opcode dispatch. */\n\t\tcurr_pc = act->curr_pc;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"restarting execution, thr %p, act idx %ld, fun %p,\"\n\t                   \"consts %p, funcs %p, lev %ld, regbot %ld, regtop %ld, \"\n\t                   \"preventcount=%ld\",\n\t                   (void *) thr,\n\t                   (long) (thr->callstack_top - 1),\n\t                   (void *) DUK__FUN(),\n\t                   (void *) DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, DUK__FUN()),\n\t                   (void *) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, DUK__FUN()),\n\t                   (long) (thr->callstack_top - 1),\n\t                   (long) (thr->valstack_bottom - thr->valstack),\n\t                   (long) (thr->valstack_top - thr->valstack),\n\t                   (long) thr->callstack_preventcount));\n\n\t/* Dispatch loop. */\n\n\tfor (;;) {\n\t\tduk_uint8_t op;\n\n\t\tDUK_ASSERT(thr->callstack_top >= 1);\n\t\tDUK_ASSERT(thr->valstack_top - thr->valstack_bottom == DUK__FUN()->nregs);\n\t\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack) == valstack_top_base);\n\n\t\t/* Executor interrupt counter check, used to implement breakpoints,\n\t\t * debugging interface, execution timeouts, etc.  The counter is heap\n\t\t * specific but is maintained in the current thread to make the check\n\t\t * as fast as possible.  The counter is copied back to the heap struct\n\t\t * whenever a thread switch occurs by the DUK_HEAP_SWITCH_THREAD() macro.\n\t\t */\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\t\tint_ctr = thr->interrupt_counter;\n\t\tif (DUK_LIKELY(int_ctr > 0)) {\n\t\t\tthr->interrupt_counter = int_ctr - 1;\n\t\t} else {\n\t\t\t/* Trigger at zero or below */\n\t\t\tduk_small_uint_t exec_int_ret;\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_exec_interrupt);\n\n\t\t\t/* Write curr_pc back for the debugger. */\n\t\t\t{\n\t\t\t\tduk_activation *act;\n\t\t\t\tDUK_ASSERT(thr->callstack_top > 0);\n\t\t\t\tact = thr->callstack_curr;\n\t\t\t\tDUK_ASSERT(act != NULL);\n\t\t\t\tact->curr_pc = (duk_instr_t *) curr_pc;\n\t\t\t}\n\n\t\t\t/* Forced restart caused by a function return; must recheck\n\t\t\t * debugger breakpoints before checking line transitions,\n\t\t\t * see GH-303.  Restart and then handle interrupt_counter\n\t\t\t * zero again.\n\t\t\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\t\tif (thr->heap->dbg_force_restart) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"dbg_force_restart flag forced restart execution\"));  /* GH-303 */\n\t\t\t\tthr->heap->dbg_force_restart = 0;\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n#endif\n\n\t\t\texec_int_ret = duk__executor_interrupt(thr);\n\t\t\tif (exec_int_ret == DUK__INT_RESTART) {\n\t\t\t\t/* curr_pc synced back above */\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n\t\t}\n#endif  /* DUK_USE_INTERRUPT_COUNTER */\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\t\t/* For cross-checking during development: ensure dispatch count\n\t\t * matches cumulative interrupt counter init value sums.\n\t\t */\n\t\tthr->heap->inst_count_exec++;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS) || defined(DUK_USE_DEBUG)\n\t\t{\n\t\t\tduk_activation *act;\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(curr_pc >= DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, DUK__FUN()));\n\t\t\tDUK_ASSERT(curr_pc < DUK_HCOMPFUNC_GET_CODE_END(thr->heap, DUK__FUN()));\n\t\t\tDUK_UNREF(act);  /* if debugging disabled */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"executing bytecode: pc=%ld, ins=0x%08lx, op=%ld, valstack_top=%ld/%ld, nregs=%ld  -->  %!I\",\n\t\t\t                     (long) (curr_pc - DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, DUK__FUN())),\n\t\t\t                     (unsigned long) *curr_pc,\n\t\t\t                     (long) DUK_DEC_OP(*curr_pc),\n\t\t\t                     (long) (thr->valstack_top - thr->valstack),\n\t\t\t                     (long) (thr->valstack_end - thr->valstack),\n\t\t\t                     (long) (DUK__FUN() ? DUK__FUN()->nregs : -1),\n\t\t\t                     (duk_instr_t) *curr_pc));\n\t\t}\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\t/* Quite heavy assert: check valstack policy.  Improper\n\t\t * shuffle instructions can write beyond valstack_top/end\n\t\t * so this check catches them in the act.\n\t\t */\n\t\t{\n\t\t\tduk_tval *tv;\n\t\t\ttv = thr->valstack_top;\n\t\t\twhile (tv != thr->valstack_end) {\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\t\t\ttv++;\n\t\t\t}\n\t\t}\n#endif\n\n\t\tins = *curr_pc++;\n\t\tDUK_STATS_INC(thr->heap, stats_exec_opcodes);\n\n\t\t/* Typing: use duk_small_(u)int_fast_t when decoding small\n\t\t * opcode fields (op, A, B, C, BC) which fit into 16 bits\n\t\t * and duk_(u)int_fast_t when decoding larger fields (e.g.\n\t\t * ABC).  Use unsigned variant by default, signed when the\n\t\t * value is used in signed arithmetic.  Using variable names\n\t\t * such as 'a', 'b', 'c', 'bc', etc makes it easier to spot\n\t\t * typing mismatches.\n\t\t */\n\n\t\t/* Switch based on opcode.  Cast to 8-bit unsigned value and\n\t\t * use a fully populated case clauses so that the compiler\n\t\t * will (at least usually) omit a bounds check.\n\t\t */\n\t\top = (duk_uint8_t) DUK_DEC_OP(ins);\n\t\tswitch (op) {\n\n\t\t/* Some useful macros.  These access inner executor variables\n\t\t * directly so they only apply within the executor.\n\t\t */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n#define DUK__REPLACE_TOP_A_BREAK() { goto replace_top_a; }\n#define DUK__REPLACE_TOP_BC_BREAK() { goto replace_top_bc; }\n#define DUK__REPLACE_BOOL_A_BREAK(bval) { \\\n\t\tduk_bool_t duk__bval; \\\n\t\tduk__bval = (bval); \\\n\t\tDUK_ASSERT(duk__bval == 0 || duk__bval == 1); \\\n\t\tduk_push_boolean(thr, duk__bval); \\\n\t\tDUK__REPLACE_TOP_A_BREAK(); \\\n\t}\n#else\n#define DUK__REPLACE_TOP_A_BREAK() { DUK__REPLACE_TO_TVPTR(thr, DUK__REGP_A(ins)); break; }\n#define DUK__REPLACE_TOP_BC_BREAK() { DUK__REPLACE_TO_TVPTR(thr, DUK__REGP_BC(ins)); break; }\n#define DUK__REPLACE_BOOL_A_BREAK(bval) { \\\n\t\tduk_bool_t duk__bval; \\\n\t\tduk_tval *duk__tvdst; \\\n\t\tduk__bval = (bval); \\\n\t\tDUK_ASSERT(duk__bval == 0 || duk__bval == 1); \\\n\t\tduk__tvdst = DUK__REGP_A(ins); \\\n\t\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, duk__tvdst, duk__bval); \\\n\t\tbreak; \\\n\t}\n#endif\n\n\t\t/* XXX: 12 + 12 bit variant might make sense too, for both reg and\n\t\t * const loads.\n\t\t */\n\n\t\t/* For LDREG, STREG, LDCONST footprint optimized variants would just\n\t\t * duk_dup() + duk_replace(), but because they're used quite a lot\n\t\t * they're currently intentionally not size optimized.\n\t\t */\n\t\tcase DUK_OP_LDREG: {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\ttv2 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv1, tv2);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_STREG: {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\ttv2 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv2, tv1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_LDCONST: {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\ttv2 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv1, tv2);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\n\t\t/* LDINT and LDINTX are intended to load an arbitrary signed\n\t\t * 32-bit value.  Only an LDINT+LDINTX sequence is supported.\n\t\t * This also guarantees all values remain fastints.\n\t\t */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_LDINT: {\n\t\t\tduk_int32_t val;\n\n\t\t\tval = (duk_int32_t) DUK_DEC_BC(ins) - (duk_int32_t) DUK_BC_LDINT_BIAS;\n\t\t\tduk_push_int(thr, val);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n\t\tcase DUK_OP_LDINTX: {\n\t\t\tduk_int32_t val;\n\n\t\t\tval = (duk_int32_t) duk_get_int(thr, DUK_DEC_A(ins));\n\t\t\tval = (val << DUK_BC_LDINTX_SHIFT) + (duk_int32_t) DUK_DEC_BC(ins);  /* no bias */\n\t\t\tduk_push_int(thr, val);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_LDINT: {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_int32_t val;\n\n\t\t\tval = (duk_int32_t) DUK_DEC_BC(ins) - (duk_int32_t) DUK_BC_LDINT_BIAS;\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_I32_UPDREF(thr, tv1, val);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDINTX: {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_int32_t val;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\t\tval = DUK_TVAL_GET_FASTINT_I32(tv1);\n#else\n\t\t\t/* XXX: fast double-to-int conversion, we know number is integer in [-0x80000000,0xffffffff]. */\n\t\t\tval = (duk_int32_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\t\tval = (duk_int32_t) ((duk_uint32_t) val << DUK_BC_LDINTX_SHIFT) + (duk_int32_t) DUK_DEC_BC(ins);  /* no bias */\n\t\t\tDUK_TVAL_SET_I32_UPDREF(thr, tv1, val);  /* side effects */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_LDTHIS: {\n\t\t\tduk_push_this(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\t\tcase DUK_OP_LDUNDEF: {\n\t\t\tduk_to_undefined(thr, (duk_idx_t) DUK_DEC_BC(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDNULL: {\n\t\t\tduk_to_null(thr, (duk_idx_t) DUK_DEC_BC(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDTRUE: {\n\t\t\tduk_push_true(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\t\tcase DUK_OP_LDFALSE: {\n\t\t\tduk_push_false(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_LDTHIS: {\n\t\t\t/* Note: 'this' may be bound to any value, not just an object */\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\ttv2 = thr->valstack_bottom - 1;  /* 'this binding' is just under bottom */\n\t\t\tDUK_ASSERT(tv2 >= thr->valstack);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv1, tv2);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDUNDEF: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDNULL: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_NULL_UPDREF(thr, tv1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDTRUE: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv1, 1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDFALSE: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv1, 0);  /* side effects */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\tcase DUK_OP_BNOT: {\n\t\t\tduk__vm_bitwise_not(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_LNOT: {\n\t\t\tduk__vm_logical_not(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_UNM:\n\t\tcase DUK_OP_UNP: {\n\t\t\tduk__vm_arith_unary_op(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins), op);\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_UNM: {\n\t\t\tduk__vm_arith_unary_op(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins), DUK_OP_UNM);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_UNP: {\n\t\t\tduk__vm_arith_unary_op(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins), DUK_OP_UNP);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_TYPEOF: {\n\t\t\tduk_small_uint_t stridx;\n\n\t\t\tstridx = duk_js_typeof_stridx(DUK__REGP_BC(ins));\n\t\t\tDUK_ASSERT_STRIDX_VALID(stridx);\n\t\t\tduk_push_hstring_stridx(thr, stridx);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_TYPEOF: {\n\t\t\tduk_tval *tv;\n\t\t\tduk_small_uint_t stridx;\n\t\t\tduk_hstring *h_str;\n\n\t\t\ttv = DUK__REGP_BC(ins);\n\t\t\tstridx = duk_js_typeof_stridx(tv);\n\t\t\tDUK_ASSERT_STRIDX_VALID(stridx);\n\t\t\th_str = DUK_HTHREAD_GET_STRING(thr, stridx);\n\t\t\ttv = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_STRING_UPDREF(thr, tv, h_str);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\tcase DUK_OP_TYPEOFID: {\n\t\t\tduk_small_uint_t stridx;\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_hstring *h_str;\n#endif\n\t\t\tduk_activation *act;\n\t\t\tduk_hstring *name;\n\t\t\tduk_tval *tv;\n\n\t\t\t/* A -> target register\n\t\t\t * BC -> constant index of identifier name\n\t\t\t */\n\n\t\t\ttv = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv));\n\t\t\tname = DUK_TVAL_GET_STRING(tv);\n\t\t\ttv = NULL;  /* lookup has side effects */\n\t\t\tact = thr->callstack_curr;\n\t\t\tif (duk_js_getvar_activation(thr, act, name, 0 /*throw*/)) {\n\t\t\t\t/* -> [... val this] */\n\t\t\t\ttv = DUK_GET_TVAL_NEGIDX(thr, -2);\n\t\t\t\tstridx = duk_js_typeof_stridx(tv);\n\t\t\t\ttv = NULL;  /* no longer needed */\n\t\t\t\tduk_pop_2_unsafe(thr);\n\t\t\t} else {\n\t\t\t\t/* unresolvable, no stack changes */\n\t\t\t\tstridx = DUK_STRIDX_LC_UNDEFINED;\n\t\t\t}\n\t\t\tDUK_ASSERT_STRIDX_VALID(stridx);\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_push_hstring_stridx(thr, stridx);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\t\th_str = DUK_HTHREAD_GET_STRING(thr, stridx);\n\t\t\ttv = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_STRING_UPDREF(thr, tv, h_str);\n\t\t\tbreak;\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\t}\n\n\t\t/* Equality: E5 Sections 11.9.1, 11.9.3 */\n\n#define DUK__EQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_equals(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__NEQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_equals(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\ttmp ^= 1; \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__SEQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_strict_equals((barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__SNEQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_strict_equals((barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\ttmp ^= 1; \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_EQ_RR:\n\t\tcase DUK_OP_EQ_CR:\n\t\tcase DUK_OP_EQ_RC:\n\t\tcase DUK_OP_EQ_CC:\n\t\t\tDUK__EQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_NEQ_RR:\n\t\tcase DUK_OP_NEQ_CR:\n\t\tcase DUK_OP_NEQ_RC:\n\t\tcase DUK_OP_NEQ_CC:\n\t\t\tDUK__NEQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_SEQ_RR:\n\t\tcase DUK_OP_SEQ_CR:\n\t\tcase DUK_OP_SEQ_RC:\n\t\tcase DUK_OP_SEQ_CC:\n\t\t\tDUK__SEQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_SNEQ_RR:\n\t\tcase DUK_OP_SNEQ_CR:\n\t\tcase DUK_OP_SNEQ_RC:\n\t\tcase DUK_OP_SNEQ_CC:\n\t\t\tDUK__SNEQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_EQ_RR:\n\t\t\tDUK__EQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_EQ_CR:\n\t\t\tDUK__EQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_EQ_RC:\n\t\t\tDUK__EQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_EQ_CC:\n\t\t\tDUK__EQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_NEQ_RR:\n\t\t\tDUK__NEQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_NEQ_CR:\n\t\t\tDUK__NEQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_NEQ_RC:\n\t\t\tDUK__NEQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_NEQ_CC:\n\t\t\tDUK__NEQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SEQ_RR:\n\t\t\tDUK__SEQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SEQ_CR:\n\t\t\tDUK__SEQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SEQ_RC:\n\t\t\tDUK__SEQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SEQ_CC:\n\t\t\tDUK__SEQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SNEQ_RR:\n\t\t\tDUK__SNEQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SNEQ_CR:\n\t\t\tDUK__SNEQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SNEQ_RC:\n\t\t\tDUK__SNEQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SNEQ_CC:\n\t\t\tDUK__SNEQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#define DUK__COMPARE_BODY(arg1,arg2,flags) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_compare_helper(thr, (arg1), (arg2), (flags)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__GT_BODY(barg,carg) DUK__COMPARE_BODY((carg), (barg), 0)\n#define DUK__GE_BODY(barg,carg) DUK__COMPARE_BODY((barg), (carg), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST | DUK_COMPARE_FLAG_NEGATE)\n#define DUK__LT_BODY(barg,carg) DUK__COMPARE_BODY((barg), (carg), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST)\n#define DUK__LE_BODY(barg,carg) DUK__COMPARE_BODY((carg), (barg), DUK_COMPARE_FLAG_NEGATE)\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_GT_RR:\n\t\tcase DUK_OP_GT_CR:\n\t\tcase DUK_OP_GT_RC:\n\t\tcase DUK_OP_GT_CC:\n\t\t\tDUK__GT_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_GE_RR:\n\t\tcase DUK_OP_GE_CR:\n\t\tcase DUK_OP_GE_RC:\n\t\tcase DUK_OP_GE_CC:\n\t\t\tDUK__GE_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_LT_RR:\n\t\tcase DUK_OP_LT_CR:\n\t\tcase DUK_OP_LT_RC:\n\t\tcase DUK_OP_LT_CC:\n\t\t\tDUK__LT_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_LE_RR:\n\t\tcase DUK_OP_LE_CR:\n\t\tcase DUK_OP_LE_RC:\n\t\tcase DUK_OP_LE_CC:\n\t\t\tDUK__LE_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_GT_RR:\n\t\t\tDUK__GT_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GT_CR:\n\t\t\tDUK__GT_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GT_RC:\n\t\t\tDUK__GT_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GT_CC:\n\t\t\tDUK__GT_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GE_RR:\n\t\t\tDUK__GE_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GE_CR:\n\t\t\tDUK__GE_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GE_RC:\n\t\t\tDUK__GE_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GE_CC:\n\t\t\tDUK__GE_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LT_RR:\n\t\t\tDUK__LT_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LT_CR:\n\t\t\tDUK__LT_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LT_RC:\n\t\t\tDUK__LT_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LT_CC:\n\t\t\tDUK__LT_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LE_RR:\n\t\t\tDUK__LE_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LE_CR:\n\t\t\tDUK__LE_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LE_RC:\n\t\t\tDUK__LE_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LE_CC:\n\t\t\tDUK__LE_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* No size optimized variant at present for IF. */\n\t\tcase DUK_OP_IFTRUE_R: {\n\t\t\tif (duk_js_toboolean(DUK__REGP_BC(ins)) != 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_IFTRUE_C: {\n\t\t\tif (duk_js_toboolean(DUK__CONSTP_BC(ins)) != 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_IFFALSE_R: {\n\t\t\tif (duk_js_toboolean(DUK__REGP_BC(ins)) == 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_IFFALSE_C: {\n\t\t\tif (duk_js_toboolean(DUK__CONSTP_BC(ins)) == 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_ADD_RR:\n\t\tcase DUK_OP_ADD_CR:\n\t\tcase DUK_OP_ADD_RC:\n\t\tcase DUK_OP_ADD_CC: {\n\t\t\t/* XXX: could leave value on stack top and goto replace_top_a; */\n\t\t\tduk__vm_arith_add(thr, DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_ADD_RR: {\n\t\t\tduk__vm_arith_add(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_ADD_CR: {\n\t\t\tduk__vm_arith_add(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_ADD_RC: {\n\t\t\tduk__vm_arith_add(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_ADD_CC: {\n\t\t\tduk__vm_arith_add(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_SUB_RR:\n\t\tcase DUK_OP_SUB_CR:\n\t\tcase DUK_OP_SUB_RC:\n\t\tcase DUK_OP_SUB_CC:\n\t\tcase DUK_OP_MUL_RR:\n\t\tcase DUK_OP_MUL_CR:\n\t\tcase DUK_OP_MUL_RC:\n\t\tcase DUK_OP_MUL_CC:\n\t\tcase DUK_OP_DIV_RR:\n\t\tcase DUK_OP_DIV_CR:\n\t\tcase DUK_OP_DIV_RC:\n\t\tcase DUK_OP_DIV_CC:\n\t\tcase DUK_OP_MOD_RR:\n\t\tcase DUK_OP_MOD_CR:\n\t\tcase DUK_OP_MOD_RC:\n\t\tcase DUK_OP_MOD_CC:\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tcase DUK_OP_EXP_RR:\n\t\tcase DUK_OP_EXP_CR:\n\t\tcase DUK_OP_EXP_RC:\n\t\tcase DUK_OP_EXP_CC:\n#endif  /* DUK_USE_ES7_EXP_OPERATOR */\n\t\t{\n\t\t\t/* XXX: could leave value on stack top and goto replace_top_a; */\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins), DUK_DEC_A(ins), op);\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_SUB_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_SUB_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_SUB_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_SUB_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tcase DUK_OP_EXP_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_EXP_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_EXP_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_EXP_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_ES7_EXP_OPERATOR */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_BAND_RR:\n\t\tcase DUK_OP_BAND_CR:\n\t\tcase DUK_OP_BAND_RC:\n\t\tcase DUK_OP_BAND_CC:\n\t\tcase DUK_OP_BOR_RR:\n\t\tcase DUK_OP_BOR_CR:\n\t\tcase DUK_OP_BOR_RC:\n\t\tcase DUK_OP_BOR_CC:\n\t\tcase DUK_OP_BXOR_RR:\n\t\tcase DUK_OP_BXOR_CR:\n\t\tcase DUK_OP_BXOR_RC:\n\t\tcase DUK_OP_BXOR_CC:\n\t\tcase DUK_OP_BASL_RR:\n\t\tcase DUK_OP_BASL_CR:\n\t\tcase DUK_OP_BASL_RC:\n\t\tcase DUK_OP_BASL_CC:\n\t\tcase DUK_OP_BLSR_RR:\n\t\tcase DUK_OP_BLSR_CR:\n\t\tcase DUK_OP_BLSR_RC:\n\t\tcase DUK_OP_BLSR_CC:\n\t\tcase DUK_OP_BASR_RR:\n\t\tcase DUK_OP_BASR_CR:\n\t\tcase DUK_OP_BASR_RC:\n\t\tcase DUK_OP_BASR_CC: {\n\t\t\t/* XXX: could leave value on stack top and goto replace_top_a; */\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins), DUK_DEC_A(ins), op);\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_BAND_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BAND_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BAND_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BAND_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* For INSTOF and IN, B is always a register. */\n#define DUK__INSTOF_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_instanceof(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__IN_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_in(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_INSTOF_RR:\n\t\tcase DUK_OP_INSTOF_CR:\n\t\tcase DUK_OP_INSTOF_RC:\n\t\tcase DUK_OP_INSTOF_CC:\n\t\t\tDUK__INSTOF_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_IN_RR:\n\t\tcase DUK_OP_IN_CR:\n\t\tcase DUK_OP_IN_RC:\n\t\tcase DUK_OP_IN_CC:\n\t\t\tDUK__IN_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_INSTOF_RR:\n\t\t\tDUK__INSTOF_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_INSTOF_CR:\n\t\t\tDUK__INSTOF_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_INSTOF_RC:\n\t\t\tDUK__INSTOF_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_INSTOF_CC:\n\t\t\tDUK__INSTOF_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_IN_RR:\n\t\t\tDUK__IN_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_IN_CR:\n\t\t\tDUK__IN_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_IN_RC:\n\t\t\tDUK__IN_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_IN_CC:\n\t\t\tDUK__IN_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* Pre/post inc/dec for register variables, important for loops. */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_PREINCR:\n\t\tcase DUK_OP_PREDECR:\n\t\tcase DUK_OP_POSTINCR:\n\t\tcase DUK_OP_POSTDECR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), op);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREINCV:\n\t\tcase DUK_OP_PREDECV:\n\t\tcase DUK_OP_POSTINCV:\n\t\tcase DUK_OP_POSTDECV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), op, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_PREINCR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_PREINCR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREDECR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_PREDECR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTINCR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_POSTINCR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTDECR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_POSTDECR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREINCV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_PREINCV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREDECV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_PREDECV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTINCV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_POSTINCV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTDECV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_POSTDECV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* XXX: Move to separate helper, optimize for perf/size separately. */\n\t\t/* Preinc/predec for object properties. */\n\t\tcase DUK_OP_PREINCP_RR:\n\t\tcase DUK_OP_PREINCP_CR:\n\t\tcase DUK_OP_PREINCP_RC:\n\t\tcase DUK_OP_PREINCP_CC:\n\t\tcase DUK_OP_PREDECP_RR:\n\t\tcase DUK_OP_PREDECP_CR:\n\t\tcase DUK_OP_PREDECP_RC:\n\t\tcase DUK_OP_PREDECP_CC:\n\t\tcase DUK_OP_POSTINCP_RR:\n\t\tcase DUK_OP_POSTINCP_CR:\n\t\tcase DUK_OP_POSTINCP_RC:\n\t\tcase DUK_OP_POSTINCP_CC:\n\t\tcase DUK_OP_POSTDECP_RR:\n\t\tcase DUK_OP_POSTDECP_CR:\n\t\tcase DUK_OP_POSTDECP_RC:\n\t\tcase DUK_OP_POSTDECP_CC: {\n\t\t\tduk_tval *tv_obj;\n\t\t\tduk_tval *tv_key;\n\t\t\tduk_tval *tv_val;\n\t\t\tduk_bool_t rc;\n\t\t\tduk_double_t x, y, z;\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_tval *tv_dst;\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t\t/* A -> target reg\n\t\t\t * B -> object reg/const (may be const e.g. in \"'foo'[1]\")\n\t\t\t * C -> key reg/const\n\t\t\t */\n\n\t\t\t/* Opcode bits 0-1 are used to distinguish reg/const variants.\n\t\t\t * Opcode bits 2-3 are used to distinguish inc/dec variants:\n\t\t\t * Bit 2 = inc(0)/dec(1), bit 3 = pre(0)/post(1).\n\t\t\t */\n\t\t\tDUK_ASSERT((DUK_OP_PREINCP_RR & 0x0c) == 0x00);\n\t\t\tDUK_ASSERT((DUK_OP_PREDECP_RR & 0x0c) == 0x04);\n\t\t\tDUK_ASSERT((DUK_OP_POSTINCP_RR & 0x0c) == 0x08);\n\t\t\tDUK_ASSERT((DUK_OP_POSTDECP_RR & 0x0c) == 0x0c);\n\n\t\t\ttv_obj = DUK__REGCONSTP_B(ins);\n\t\t\ttv_key = DUK__REGCONSTP_C(ins);\n\t\t\trc = duk_hobject_getprop(thr, tv_obj, tv_key);  /* -> [val] */\n\t\t\tDUK_UNREF(rc);  /* ignore */\n\t\t\ttv_obj = NULL;  /* invalidated */\n\t\t\ttv_key = NULL;  /* invalidated */\n\n\t\t\t/* XXX: Fastint fast path would be useful here.  Also fastints\n\t\t\t * now lose their fastint status in current handling which is\n\t\t\t * not intuitive.\n\t\t\t */\n\n\t\t\tx = duk_to_number_m1(thr);\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tif (ins & DUK_BC_INCDECP_FLAG_DEC) {\n\t\t\t\ty = x - 1.0;\n\t\t\t} else {\n\t\t\t\ty = x + 1.0;\n\t\t\t}\n\n\t\t\tduk_push_number(thr, y);\n\t\t\ttv_val = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\ttv_obj = DUK__REGCONSTP_B(ins);\n\t\t\ttv_key = DUK__REGCONSTP_C(ins);\n\t\t\trc = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, DUK__STRICT());\n\t\t\tDUK_UNREF(rc);  /* ignore */\n\t\t\ttv_obj = NULL;  /* invalidated */\n\t\t\ttv_key = NULL;  /* invalidated */\n\t\t\tduk_pop_unsafe(thr);\n\n\t\t\tz = (ins & DUK_BC_INCDECP_FLAG_POST) ? x : y;\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_push_number(thr, z);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n#else\n\t\t\ttv_dst = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_dst, z);\n\t\t\tbreak;\n#endif\n\t\t}\n\n\t\t/* XXX: GETPROP where object is 'this', GETPROPT?\n\t\t * Occurs relatively often in object oriented code.\n\t\t */\n\n#define DUK__GETPROP_BODY(barg,carg) { \\\n\t\t/* A -> target reg \\\n\t\t * B -> object reg/const (may be const e.g. in \"'foo'[1]\") \\\n\t\t * C -> key reg/const \\\n\t\t */ \\\n\t\t(void) duk_hobject_getprop(thr, (barg), (carg)); \\\n\t\tDUK__REPLACE_TOP_A_BREAK(); \\\n\t}\n#define DUK__GETPROPC_BODY(barg,carg) { \\\n\t\t/* Same as GETPROP but callability check for property-based calls. */ \\\n\t\tduk_tval *tv__targ; \\\n\t\t(void) duk_hobject_getprop(thr, (barg), (carg)); \\\n\t\tDUK_GC_TORTURE(thr->heap); \\\n\t\ttv__targ = DUK_GET_TVAL_NEGIDX(thr, -1); \\\n\t\tif (DUK_UNLIKELY(!duk_is_callable_tval(thr, tv__targ))) { \\\n\t\t\t/* Here we intentionally re-evaluate the macro \\\n\t\t\t * arguments to deal with potentially changed \\\n\t\t\t * valstack base pointer! \\\n\t\t\t */ \\\n\t\t\tduk_call_setup_propcall_error(thr, (barg), (carg)); \\\n\t\t} \\\n\t\tDUK__REPLACE_TOP_A_BREAK(); \\\n\t}\n#define DUK__PUTPROP_BODY(aarg,barg,carg) { \\\n\t\t/* A -> object reg \\\n\t\t * B -> key reg/const \\\n\t\t * C -> value reg/const \\\n\t\t * \\\n\t\t * Note: intentional difference to register arrangement \\\n\t\t * of e.g. GETPROP; 'A' must contain a register-only value. \\\n\t\t */ \\\n\t\t(void) duk_hobject_putprop(thr, (aarg), (barg), (carg), DUK__STRICT()); \\\n\t\tbreak; \\\n\t}\n#define DUK__DELPROP_BODY(barg,carg) { \\\n\t\t/* A -> result reg \\\n\t\t * B -> object reg \\\n\t\t * C -> key reg/const \\\n\t\t */ \\\n\t\tduk_bool_t rc; \\\n\t\trc = duk_hobject_delprop(thr, (barg), (carg), DUK__STRICT()); \\\n\t\tDUK_ASSERT(rc == 0 || rc == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(rc); \\\n\t}\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_GETPROP_RR:\n\t\tcase DUK_OP_GETPROP_CR:\n\t\tcase DUK_OP_GETPROP_RC:\n\t\tcase DUK_OP_GETPROP_CC:\n\t\t\tDUK__GETPROP_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\tcase DUK_OP_GETPROPC_RR:\n\t\tcase DUK_OP_GETPROPC_CR:\n\t\tcase DUK_OP_GETPROPC_RC:\n\t\tcase DUK_OP_GETPROPC_CC:\n\t\t\tDUK__GETPROPC_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#endif\n\t\tcase DUK_OP_PUTPROP_RR:\n\t\tcase DUK_OP_PUTPROP_CR:\n\t\tcase DUK_OP_PUTPROP_RC:\n\t\tcase DUK_OP_PUTPROP_CC:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_DELPROP_RR:\n\t\tcase DUK_OP_DELPROP_RC:  /* B is always reg */\n\t\t\tDUK__DELPROP_BODY(DUK__REGP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_GETPROP_RR:\n\t\t\tDUK__GETPROP_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROP_CR:\n\t\t\tDUK__GETPROP_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROP_RC:\n\t\t\tDUK__GETPROP_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GETPROP_CC:\n\t\t\tDUK__GETPROP_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\tcase DUK_OP_GETPROPC_RR:\n\t\t\tDUK__GETPROPC_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROPC_CR:\n\t\t\tDUK__GETPROPC_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROPC_RC:\n\t\t\tDUK__GETPROPC_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GETPROPC_CC:\n\t\t\tDUK__GETPROPC_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif\n\t\tcase DUK_OP_PUTPROP_RR:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_PUTPROP_CR:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_PUTPROP_RC:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_PUTPROP_CC:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_DELPROP_RR:  /* B is always reg */\n\t\t\tDUK__DELPROP_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_DELPROP_RC:\n\t\t\tDUK__DELPROP_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* No fast path for DECLVAR now, it's quite a rare instruction. */\n\t\tcase DUK_OP_DECLVAR_RR:\n\t\tcase DUK_OP_DECLVAR_CR:\n\t\tcase DUK_OP_DECLVAR_RC:\n\t\tcase DUK_OP_DECLVAR_CC: {\n\t\t\tduk_activation *act;\n\t\t\tduk_small_uint_fast_t a = DUK_DEC_A(ins);\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\t\t\tduk_small_uint_t prop_flags;\n\t\t\tduk_bool_t is_func_decl;\n\n\t\t\ttv1 = DUK__REGCONSTP_B(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\n\t\t\tis_func_decl = ((a & DUK_BC_DECLVAR_FLAG_FUNC_DECL) != 0);\n\n\t\t\t/* XXX: declvar takes an duk_tval pointer, which is awkward and\n\t\t\t * should be reworked.\n\t\t\t */\n\n\t\t\t/* Compiler is responsible for selecting property flags (configurability,\n\t\t\t * writability, etc).\n\t\t\t */\n\t\t\tprop_flags = a & DUK_PROPDESC_FLAGS_MASK;\n\n\t\t\tif (is_func_decl) {\n\t\t\t\tduk_push_tval(thr, DUK__REGCONSTP_C(ins));\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* valstack policy */\n\t\t\t\tthr->valstack_top++;\n\t\t\t}\n\t\t\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tif (duk_js_declvar_activation(thr, act, name, tv1, prop_flags, is_func_decl)) {\n\t\t\t\tif (is_func_decl) {\n\t\t\t\t\t/* Already declared, update value. */\n\t\t\t\t\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\t\t\t\tduk_js_putvar_activation(thr, act, name, tv1, DUK__STRICT());\n\t\t\t\t} else {\n\t\t\t\t\t/* Already declared but no initializer value\n\t\t\t\t\t * (e.g. 'var xyz;'), no-op.\n\t\t\t\t\t */\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t/* The compiler should never emit DUK_OP_REGEXP if there is no\n\t\t * regexp support.\n\t\t */\n\t\tcase DUK_OP_REGEXP_RR:\n\t\tcase DUK_OP_REGEXP_CR:\n\t\tcase DUK_OP_REGEXP_RC:\n\t\tcase DUK_OP_REGEXP_CC: {\n\t\t\t/* A -> target register\n\t\t\t * B -> bytecode (also contains flags)\n\t\t\t * C -> escaped source\n\t\t\t */\n\n\t\t\tduk_push_tval(thr, DUK__REGCONSTP_C(ins));\n\t\t\tduk_push_tval(thr, DUK__REGCONSTP_B(ins));  /* -> [ ... escaped_source bytecode ] */\n\t\t\tduk_regexp_create_instance(thr);   /* -> [ ... regexp_instance ] */\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n\t\t/* XXX: 'c' is unused, use whole BC, etc. */\n\t\tcase DUK_OP_CSVAR_RR:\n\t\tcase DUK_OP_CSVAR_CR:\n\t\tcase DUK_OP_CSVAR_RC:\n\t\tcase DUK_OP_CSVAR_CC: {\n\t\t\t/* The speciality of calling through a variable binding is that the\n\t\t\t * 'this' value may be provided by the variable lookup: E5 Section 6.b.i.\n\t\t\t *\n\t\t\t * The only (standard) case where the 'this' binding is non-null is when\n\t\t\t *   (1) the variable is found in an object environment record, and\n\t\t\t *   (2) that object environment record is a 'with' block.\n\t\t\t */\n\n\t\t\tduk_activation *act;\n\t\t\tduk_uint_fast_t idx;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\n\t\t\t/* A -> target registers (A, A + 1) for call setup\n\t\t\t * B -> identifier name, usually constant but can be a register due to shuffling\n\t\t\t */\n\n\t\t\ttv1 = DUK__REGCONSTP_B(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\t\t\tact = thr->callstack_curr;\n\t\t\t(void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/);  /* -> [... val this] */\n\n\t\t\tidx = (duk_uint_fast_t) DUK_DEC_A(ins);\n\n\t\t\t/* Could add direct value stack handling. */\n\t\t\tduk_replace(thr, (duk_idx_t) (idx + 1));  /* 'this' binding */\n\t\t\tduk_replace(thr, (duk_idx_t) idx);        /* variable value (function, we hope, not checked here) */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_CLOSURE: {\n\t\t\tduk_activation *act;\n\t\t\tduk_hcompfunc *fun_act;\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\t\t\tduk_hobject *fun_temp;\n\n\t\t\t/* A -> target reg\n\t\t\t * BC -> inner function index\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"CLOSURE to target register %ld, fnum %ld (count %ld)\",\n\t\t\t                     (long) DUK_DEC_A(ins), (long) DUK_DEC_BC(ins), (long) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, DUK__FUN())));\n\n\t\t\tDUK_ASSERT_DISABLE(bc >= 0); /* unsigned */\n\t\t\tDUK_ASSERT((duk_uint_t) bc < (duk_uint_t) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, DUK__FUN()));\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tfun_act = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\t\t\tfun_temp = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, fun_act)[bc];\n\t\t\tDUK_ASSERT(fun_temp != NULL);\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(fun_temp));\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"CLOSURE: function template is: %p -> %!O\",\n\t\t\t                     (void *) fun_temp, (duk_heaphdr *) fun_temp));\n\n\t\t\tif (act->lex_env == NULL) {\n\t\t\t\tDUK_ASSERT(act->var_env == NULL);\n\t\t\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\t\t\tact = thr->callstack_curr;\n\t\t\t}\n\t\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\t\tDUK_ASSERT(act->var_env != NULL);\n\n\t\t\t/* functions always have a NEWENV flag, i.e. they get a\n\t\t\t * new variable declaration environment, so only lex_env\n\t\t\t * matters here.\n\t\t\t */\n\t\t\tduk_js_push_closure(thr,\n\t\t\t                    (duk_hcompfunc *) fun_temp,\n\t\t\t                    act->var_env,\n\t\t\t                    act->lex_env,\n\t\t\t                    1 /*add_auto_proto*/);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_GETVAR: {\n\t\t\tduk_activation *act;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\n\t\t\ttv1 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\t(void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/);  /* -> [... val this] */\n\t\t\tduk_pop_unsafe(thr);  /* 'this' binding is not needed here */\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_PUTVAR: {\n\t\t\tduk_activation *act;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\n\t\t\ttv1 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\n\t\t\t/* XXX: putvar takes a duk_tval pointer, which is awkward and\n\t\t\t * should be reworked.\n\t\t\t */\n\n\t\t\ttv1 = DUK__REGP_A(ins);  /* val */\n\t\t\tact = thr->callstack_curr;\n\t\t\tduk_js_putvar_activation(thr, act, name, tv1, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_DELVAR: {\n\t\t\tduk_activation *act;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\t\t\tduk_bool_t rc;\n\n\t\t\ttv1 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\t\t\tact = thr->callstack_curr;\n\t\t\trc = duk_js_delvar_activation(thr, act, name);\n\t\t\tDUK__REPLACE_BOOL_A_BREAK(rc);\n\t\t}\n\n\t\tcase DUK_OP_JUMP: {\n\t\t\t/* Note: without explicit cast to signed, MSVC will\n\t\t\t * apparently generate a large positive jump when the\n\t\t\t * bias-corrected value would normally be negative.\n\t\t\t */\n\t\t\tcurr_pc += (duk_int_fast_t) DUK_DEC_ABC(ins) - (duk_int_fast_t) DUK_BC_JUMP_BIAS;\n\t\t\tbreak;\n\t\t}\n\n#define DUK__RETURN_SHARED() do { \\\n\t\tduk_small_uint_t ret_result; \\\n\t\t/* duk__handle_return() is guaranteed never to throw, except \\\n\t\t * for potential out-of-memory situations which will then \\\n\t\t * propagate out of the executor longjmp handler. \\\n\t\t */ \\\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL); \\\n\t\tret_result = duk__handle_return(thr, entry_act); \\\n\t\tif (ret_result == DUK__RETHAND_RESTART) { \\\n\t\t\tgoto restart_execution; \\\n\t\t} \\\n\t\tDUK_ASSERT(ret_result == DUK__RETHAND_FINISHED); \\\n\t\treturn; \\\n\t} while (0)\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_RETREG:\n\t\tcase DUK_OP_RETCONST:\n\t\tcase DUK_OP_RETCONSTN:\n\t\tcase DUK_OP_RETUNDEF: {\n\t\t\t /* BC -> return value reg/const */\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\n\t\t\tif (op == DUK_OP_RETREG) {\n\t\t\t\tduk_push_tval(thr, DUK__REGP_BC(ins));\n\t\t\t} else if (op == DUK_OP_RETUNDEF) {\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* valstack policy */\n\t\t\t\tthr->valstack_top++;\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(op == DUK_OP_RETCONST || op == DUK_OP_RETCONSTN);\n\t\t\t\tduk_push_tval(thr, DUK__CONSTP_BC(ins));\n\t\t\t}\n\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_RETREG: {\n\t\t\tduk_tval *tv;\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\ttv = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tthr->valstack_top++;\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n\t\t/* This will be unused without refcounting. */\n\t\tcase DUK_OP_RETCONST: {\n\t\t\tduk_tval *tv;\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\ttv = DUK__CONSTP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tthr->valstack_top++;\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n\t\tcase DUK_OP_RETCONSTN: {\n\t\t\tduk_tval *tv;\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\ttv = DUK__CONSTP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t/* Without refcounting only RETCONSTN is used. */\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv));  /* no INCREF for this constant */\n#endif\n\t\t\tthr->valstack_top++;\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n\t\tcase DUK_OP_RETUNDEF: {\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\tthr->valstack_top++;  /* value at valstack top is already undefined by valstack policy */\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\tcase DUK_OP_LABEL: {\n\t\t\tduk_activation *act;\n\t\t\tduk_catcher *cat;\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\t/* Allocate catcher and populate it (must be atomic). */\n\n\t\t\tcat = duk_hthread_catcher_alloc(thr);\n\t\t\tDUK_ASSERT(cat != NULL);\n\n\t\t\tcat->flags = (duk_uint32_t) (DUK_CAT_TYPE_LABEL | (bc << DUK_CAT_LABEL_SHIFT));\n\t\t\tcat->pc_base = (duk_instr_t *) curr_pc;  /* pre-incremented, points to first jump slot */\n\t\t\tcat->idx_base = 0;  /* unused for label */\n\t\t\tcat->h_varname = NULL;\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\tcat->parent = act->cat;\n\t\t\tact->cat = cat;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"LABEL catcher: flags=0x%08lx, pc_base=%ld, \"\n\t\t\t                     \"idx_base=%ld, h_varname=%!O, label_id=%ld\",\n\t\t\t                     (long) cat->flags, (long) cat->pc_base,\n\t\t\t                     (long) cat->idx_base, (duk_heaphdr *) cat->h_varname, (long) DUK_CAT_GET_LABEL(cat)));\n\n\t\t\tcurr_pc += 2;  /* skip jump slots */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDLABEL: {\n\t\t\tduk_activation *act;\n#if (defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)) || defined(DUK_USE_ASSERTIONS)\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n#endif\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"ENDLABEL %ld\", (long) bc));\n#endif\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(act->cat != NULL);\n\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_LABEL);\n\t\t\tDUK_ASSERT((duk_uint_fast_t) DUK_CAT_GET_LABEL(act->cat) == bc);\n\t\t\tduk_hthread_catcher_unwind_nolexenv_norz(thr, act);\n\n\t\t\t/* no need to unwind callstack */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_BREAK: {\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\tduk__handle_break_or_continue(thr, (duk_uint_t) bc, DUK_LJ_TYPE_BREAK);\n\t\t\tgoto restart_execution;\n\t\t}\n\n\t\tcase DUK_OP_CONTINUE: {\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\tduk__handle_break_or_continue(thr, (duk_uint_t) bc, DUK_LJ_TYPE_CONTINUE);\n\t\t\tgoto restart_execution;\n\t\t}\n\n\t\t/* XXX: move to helper, too large to be inline here */\n\t\tcase DUK_OP_TRYCATCH: {\n\t\t\tduk__handle_op_trycatch(thr, ins, curr_pc);\n\t\t\tcurr_pc += 2;  /* skip jump slots */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDTRY: {\n\t\t\tcurr_pc = duk__handle_op_endtry(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDCATCH: {\n\t\t\tduk__handle_op_endcatch(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDFIN: {\n\t\t\t/* Sync and NULL early. */\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\n\t\t\tif (duk__handle_op_endfin(thr, ins, entry_act) != 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t/* Must restart because we NULLed out curr_pc. */\n\t\t\tgoto restart_execution;\n\t\t}\n\n\t\tcase DUK_OP_THROW: {\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\t/* Note: errors are augmented when they are created, not\n\t\t\t * when they are thrown.  So, don't augment here, it would\n\t\t\t * break re-throwing for instance.\n\t\t\t */\n\n\t\t\t/* Sync so that augmentation sees up-to-date activations, NULL\n\t\t\t * thr->ptr_curr_pc so that it's not used if side effects occur\n\t\t\t * in augmentation or longjmp handling.\n\t\t\t */\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\n\t\t\tduk_dup(thr, (duk_idx_t) bc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (BYTECODE): %!dT (before throw augment)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\t\t\tduk_err_augment_error_throw(thr);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (BYTECODE): %!dT (after throw augment)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n#endif\n\n\t\t\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, DUK_GET_TVAL_NEGIDX(thr, -1));\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\t\tduk_err_check_debugger_integration(thr);\n#endif\n\n\t\t\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* always in executor */\n\t\t\tduk_err_longjmp(thr);\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_CSREG: {\n\t\t\t/*\n\t\t\t *  Assuming a register binds to a variable declared within this\n\t\t\t *  function (a declarative binding), the 'this' for the call\n\t\t\t *  setup is always 'undefined'.  E5 Section 10.2.1.1.6.\n\t\t\t */\n\n\t\t\tduk_small_uint_fast_t a = DUK_DEC_A(ins);\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\t/* A -> register containing target function (not type checked here)\n\t\t\t * BC -> target registers (BC, BC + 1) for call setup\n\t\t\t */\n\n#if defined(DUK_USE_PREFER_SIZE)\n\t\t\tduk_dup(thr, (duk_idx_t) a);\n\t\t\tduk_replace(thr, (duk_idx_t) bc);\n\t\t\tduk_to_undefined(thr, (duk_idx_t) (bc + 1));\n#else\n\t\t\tduk_tval *tv1;\n\t\t\tduk_tval *tv2;\n\t\t\tduk_tval *tv3;\n\t\t\tduk_tval tv_tmp1;\n\t\t\tduk_tval tv_tmp2;\n\n\t\t\ttv1 = DUK__REGP(bc);\n\t\t\ttv2 = tv1 + 1;\n\t\t\tDUK_TVAL_SET_TVAL(&tv_tmp1, tv1);\n\t\t\tDUK_TVAL_SET_TVAL(&tv_tmp2, tv2);\n\t\t\ttv3 = DUK__REGP(a);\n\t\t\tDUK_TVAL_SET_TVAL(tv1, tv3);\n\t\t\tDUK_TVAL_INCREF(thr, tv1);  /* no side effects */\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv2);  /* no need for incref */\n\t\t\tDUK_TVAL_DECREF(thr, &tv_tmp1);\n\t\t\tDUK_TVAL_DECREF(thr, &tv_tmp2);\n#endif\n\t\t\tbreak;\n\t\t}\n\n\n\t\t/* XXX: in some cases it's faster NOT to reuse the value\n\t\t * stack but rather copy the arguments on top of the stack\n\t\t * (mainly when the calling value stack is large and the value\n\t\t * stack resize would be large).\n\t\t */\n\n\t\tcase DUK_OP_CALL0:\n\t\tcase DUK_OP_CALL1:\n\t\tcase DUK_OP_CALL2:\n\t\tcase DUK_OP_CALL3:\n\t\tcase DUK_OP_CALL4:\n\t\tcase DUK_OP_CALL5:\n\t\tcase DUK_OP_CALL6:\n\t\tcase DUK_OP_CALL7: {\n\t\t\t/* Opcode packs 4 flag bits: 1 for indirect, 3 map\n\t\t\t * 1:1 to three lowest call handling flags.\n\t\t\t *\n\t\t\t * A -> nargs or register with nargs (indirect)\n\t\t\t * BC -> base register for call (base -> func, base+1 -> this, base+2 -> arg1 ... base+2+N-1 -> argN)\n\t\t\t */\n\n\t\t\tduk_idx_t nargs;\n\t\t\tduk_idx_t idx;\n\t\t\tduk_small_uint_t call_flags;\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tduk_hcompfunc *fun;\n#endif\n\n\t\t\tDUK_ASSERT((DUK_OP_CALL0 & 0x0fU) == 0);\n\t\t\tDUK_ASSERT((ins & DUK_BC_CALL_FLAG_INDIRECT) == 0);\n\n\t\t\tnargs = (duk_idx_t) DUK_DEC_A(ins);\n\t\t\tcall_flags = (ins & 0x07U) | DUK_CALL_FLAG_ALLOW_ECMATOECMA;\n\t\t\tidx = (duk_idx_t) DUK_DEC_BC(ins);\n\n\t\t\tif (duk__executor_handle_call(thr, idx, nargs, call_flags)) {\n\t\t\t\t/* curr_pc synced by duk_handle_call_unprotected() */\n\t\t\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n\t\t\tDUK_ASSERT(thr->ptr_curr_pc != NULL);\n\n\t\t\t/* duk_js_call.c is required to restore the stack reserve\n\t\t\t * so we only need to reset the top.\n\t\t\t */\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tfun = DUK__FUN();\n#endif\n\t\t\tduk_set_top_unsafe(thr, (duk_idx_t) fun->nregs);\n\n\t\t\t/* No need to reinit setjmp() catchpoint, as call handling\n\t\t\t * will store and restore our state.\n\t\t\t *\n\t\t\t * When debugger is enabled, we need to recheck the activation\n\t\t\t * status after returning.  This is now handled by call handling\n\t\t\t * and heap->dbg_force_restart.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_CALL8:\n\t\tcase DUK_OP_CALL9:\n\t\tcase DUK_OP_CALL10:\n\t\tcase DUK_OP_CALL11:\n\t\tcase DUK_OP_CALL12:\n\t\tcase DUK_OP_CALL13:\n\t\tcase DUK_OP_CALL14:\n\t\tcase DUK_OP_CALL15: {\n\t\t\t/* Indirect variant. */\n\t\t\tduk_uint_fast_t nargs;\n\t\t\tduk_idx_t idx;\n\t\t\tduk_small_uint_t call_flags;\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tduk_hcompfunc *fun;\n#endif\n\n\t\t\tDUK_ASSERT((DUK_OP_CALL0 & 0x0fU) == 0);\n\t\t\tDUK_ASSERT((ins & DUK_BC_CALL_FLAG_INDIRECT) != 0);\n\n\t\t\tnargs = (duk_uint_fast_t) DUK_DEC_A(ins);\n\t\t\tDUK__LOOKUP_INDIRECT(nargs);\n\t\t\tcall_flags = (ins & 0x07U) | DUK_CALL_FLAG_ALLOW_ECMATOECMA;\n\t\t\tidx = (duk_idx_t) DUK_DEC_BC(ins);\n\n\t\t\tif (duk__executor_handle_call(thr, idx, (duk_idx_t) nargs, call_flags)) {\n\t\t\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n\t\t\tDUK_ASSERT(thr->ptr_curr_pc != NULL);\n\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tfun = DUK__FUN();\n#endif\n\t\t\tduk_set_top_unsafe(thr, (duk_idx_t) fun->nregs);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_NEWOBJ: {\n\t\t\tduk_push_object(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t{\n\t\t\t\tduk_hobject *h;\n\t\t\t\th = duk_require_hobject(thr, -1);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ESIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(h) == 0);\n\t\t\t}\n#endif\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t/* XXX: could do a direct props realloc, but need hash size */\n\t\t\tduk_hobject_resize_entrypart(thr, duk_known_hobject(thr, -1), DUK_DEC_A(ins));\n#endif\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_NEWARR: {\n\t\t\tduk_push_array(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t{\n\t\t\t\tduk_hobject *h;\n\t\t\t\th = duk_require_hobject(thr, -1);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ESIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(h));\n\t\t\t}\n#endif\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\tduk_hobject_realloc_props(thr,\n\t\t\t                          duk_known_hobject(thr, -1),\n\t\t\t                          0 /*new_e_size*/,\n\t\t\t                          DUK_DEC_A(ins) /*new_a_size*/,\n\t\t\t                          0 /*new_h_size*/,\n\t\t\t                          0 /*abandon_array*/);\n#if 0\n\t\t\tduk_hobject_resize_arraypart(thr, duk_known_hobject(thr, -1), DUK_DEC_A(ins));\n#endif\n#endif\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_MPUTOBJ:\n\t\tcase DUK_OP_MPUTOBJI: {\n\t\t\tduk_idx_t obj_idx;\n\t\t\tduk_uint_fast_t idx, idx_end;\n\t\t\tduk_small_uint_fast_t count;\n\n\t\t\t/* A -> register of target object\n\t\t\t * B -> first register of key/value pair list\n\t\t\t *      or register containing first register number if indirect\n\t\t\t * C -> number of key/value pairs * 2\n\t\t\t *      (= number of value stack indices used starting from 'B')\n\t\t\t */\n\n\t\t\tobj_idx = DUK_DEC_A(ins);\n\t\t\tDUK_ASSERT(duk_is_object(thr, obj_idx));\n\n\t\t\tidx = (duk_uint_fast_t) DUK_DEC_B(ins);\n\t\t\tif (DUK_DEC_OP(ins) == DUK_OP_MPUTOBJI) {\n\t\t\t\tDUK__LOOKUP_INDIRECT(idx);\n\t\t\t}\n\n\t\t\tcount = (duk_small_uint_fast_t) DUK_DEC_C(ins);\n\t\t\tDUK_ASSERT(count > 0);  /* compiler guarantees */\n\t\t\tidx_end = idx + count;\n\n#if defined(DUK_USE_EXEC_INDIRECT_BOUND_CHECK)\n\t\t\tif (DUK_UNLIKELY(idx_end > (duk_uint_fast_t) duk_get_top(thr))) {\n\t\t\t\t/* XXX: use duk_is_valid_index() instead? */\n\t\t\t\t/* XXX: improve check; check against nregs, not against top */\n\t\t\t\tDUK__INTERNAL_ERROR(\"MPUTOBJ out of bounds\");\n\t\t\t}\n#endif\n\n\t\t\t/* Use 'force' flag to duk_def_prop() to ensure that any\n\t\t\t * inherited properties don't prevent the operation.\n\t\t\t * With ES2015 duplicate properties are allowed, so that we\n\t\t\t * must overwrite any previous data or accessor property.\n\t\t\t *\n\t\t\t * With ES2015 computed property names the literal keys\n\t\t\t * may be arbitrary values and need to be ToPropertyKey()\n\t\t\t * coerced at runtime.\n\t\t\t */\n\t\t\tdo {\n\t\t\t\t/* XXX: faster initialization (direct access or better primitives) */\n\t\t\t\tduk_dup(thr, (duk_idx_t) idx);\n\t\t\t\tduk_dup(thr, (duk_idx_t) (idx + 1));\n\t\t\t\tduk_def_prop(thr, obj_idx, DUK_DEFPROP_HAVE_VALUE |\n\t\t\t\t                           DUK_DEFPROP_FORCE |\n\t\t\t\t                           DUK_DEFPROP_SET_WRITABLE |\n\t\t\t\t                           DUK_DEFPROP_SET_ENUMERABLE |\n\t\t\t\t                           DUK_DEFPROP_SET_CONFIGURABLE);\n\t\t\t\tidx += 2;\n\t\t\t} while (idx < idx_end);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INITSET:\n\t\tcase DUK_OP_INITGET: {\n\t\t\tduk__handle_op_initset_initget(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_MPUTARR:\n\t\tcase DUK_OP_MPUTARRI: {\n\t\t\tduk_idx_t obj_idx;\n\t\t\tduk_uint_fast_t idx, idx_end;\n\t\t\tduk_small_uint_fast_t count;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_uint32_t arr_idx;\n\n\t\t\t/* A -> register of target object\n\t\t\t * B -> first register of value data (start_index, value1, value2, ..., valueN)\n\t\t\t *      or register containing first register number if indirect\n\t\t\t * C -> number of key/value pairs (N)\n\t\t\t */\n\n\t\t\tobj_idx = DUK_DEC_A(ins);\n\t\t\tDUK_ASSERT(duk_is_object(thr, obj_idx));\n\n\t\t\tidx = (duk_uint_fast_t) DUK_DEC_B(ins);\n\t\t\tif (DUK_DEC_OP(ins) == DUK_OP_MPUTARRI) {\n\t\t\t\tDUK__LOOKUP_INDIRECT(idx);\n\t\t\t}\n\n\t\t\tcount = (duk_small_uint_fast_t) DUK_DEC_C(ins);\n\t\t\tDUK_ASSERT(count > 0 + 1);  /* compiler guarantees */\n\t\t\tidx_end = idx + count;\n\n#if defined(DUK_USE_EXEC_INDIRECT_BOUND_CHECK)\n\t\t\tif (idx_end > (duk_uint_fast_t) duk_get_top(thr)) {\n\t\t\t\t/* XXX: use duk_is_valid_index() instead? */\n\t\t\t\t/* XXX: improve check; check against nregs, not against top */\n\t\t\t\tDUK__INTERNAL_ERROR(\"MPUTARR out of bounds\");\n\t\t\t}\n#endif\n\n\t\t\ttv1 = DUK__REGP(idx);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\t\tarr_idx = (duk_uint32_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\t\t\tarr_idx = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\t\tidx++;\n\n\t\t\tdo {\n\t\t\t\t/* duk_xdef_prop() will define an own property without any array\n\t\t\t\t * special behaviors.  We'll need to set the array length explicitly\n\t\t\t\t * in the end.  For arrays with elisions, the compiler will emit an\n\t\t\t\t * explicit SETALEN which will update the length.\n\t\t\t\t */\n\n\t\t\t\t/* XXX: because we're dealing with 'own' properties of a fresh array,\n\t\t\t\t * the array initializer should just ensure that the array has a large\n\t\t\t\t * enough array part and write the values directly into array part,\n\t\t\t\t * and finally set 'length' manually in the end (as already happens now).\n\t\t\t\t */\n\n\t\t\t\tduk_dup(thr, (duk_idx_t) idx);\n\t\t\t\tduk_xdef_prop_index_wec(thr, obj_idx, arr_idx);\n\n\t\t\t\tidx++;\n\t\t\t\tarr_idx++;\n\t\t\t} while (idx < idx_end);\n\n\t\t\t/* XXX: E5.1 Section 11.1.4 coerces the final length through\n\t\t\t * ToUint32() which is odd but happens now as a side effect of\n\t\t\t * 'arr_idx' type.\n\t\t\t */\n\t\t\tduk_set_length(thr, obj_idx, (duk_size_t) (duk_uarridx_t) arr_idx);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_SETALEN: {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hobject *h;\n\t\t\tduk_uint32_t len;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv1));\n\t\t\th = DUK_TVAL_GET_OBJECT(tv1);\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY(h));\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\t\tlen = (duk_uint32_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\t\t\tlen = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\t\t((duk_harray *) h)->length = len;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INITENUM: {\n\t\t\tduk__handle_op_initenum(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_NEXTENUM: {\n\t\t\tcurr_pc += duk__handle_op_nextenum(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INVLHS: {\n\t\t\tDUK_ERROR_REFERENCE(thr, DUK_STR_INVALID_LVALUE);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_DEBUGGER: {\n\t\t\t/* Opcode only emitted by compiler when debugger\n\t\t\t * support is enabled.  Ignore it silently without\n\t\t\t * debugger support, in case it has been loaded\n\t\t\t * from precompiled bytecode.\n\t\t\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\t\tif (duk_debug_is_attached(thr->heap)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement encountered, halt execution\"));\n\t\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\t\tduk_debug_halt_execution(thr, 1 /*use_prev_pc*/);\n\t\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement finished, resume execution\"));\n\t\t\t\tgoto restart_execution;\n\t\t\t} else {\n\t\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement ignored, debugger not attached\"));\n\t\t\t}\n#else\n\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement ignored, no debugger support\"));\n#endif\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_NOP: {\n\t\t\t/* Nop, ignored, but ABC fields may carry a value e.g.\n\t\t\t * for indirect opcode handling.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INVALID: {\n\t\t\tDUK_ERROR_FMT1(thr, DUK_ERR_ERROR, \"INVALID opcode (%ld)\", (long) DUK_DEC_ABC(ins));\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_ES6)\n\t\tcase DUK_OP_NEWTARGET: {\n\t\t\tduk_push_new_target(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n#endif  /* DUK_USE_ES6 */\n\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n#if !defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tcase DUK_OP_EXP_RR:\n\t\tcase DUK_OP_EXP_CR:\n\t\tcase DUK_OP_EXP_RC:\n\t\tcase DUK_OP_EXP_CC:\n#endif\n#if !defined(DUK_USE_ES6)\n\t\tcase DUK_OP_NEWTARGET:\n#endif\n#if !defined(DUK_USE_VERBOSE_ERRORS)\n\t\tcase DUK_OP_GETPROPC_RR:\n\t\tcase DUK_OP_GETPROPC_CR:\n\t\tcase DUK_OP_GETPROPC_RC:\n\t\tcase DUK_OP_GETPROPC_CC:\n#endif\n\t\tcase DUK_OP_UNUSED207:\n\t\tcase DUK_OP_UNUSED212:\n\t\tcase DUK_OP_UNUSED213:\n\t\tcase DUK_OP_UNUSED214:\n\t\tcase DUK_OP_UNUSED215:\n\t\tcase DUK_OP_UNUSED216:\n\t\tcase DUK_OP_UNUSED217:\n\t\tcase DUK_OP_UNUSED218:\n\t\tcase DUK_OP_UNUSED219:\n\t\tcase DUK_OP_UNUSED220:\n\t\tcase DUK_OP_UNUSED221:\n\t\tcase DUK_OP_UNUSED222:\n\t\tcase DUK_OP_UNUSED223:\n\t\tcase DUK_OP_UNUSED224:\n\t\tcase DUK_OP_UNUSED225:\n\t\tcase DUK_OP_UNUSED226:\n\t\tcase DUK_OP_UNUSED227:\n\t\tcase DUK_OP_UNUSED228:\n\t\tcase DUK_OP_UNUSED229:\n\t\tcase DUK_OP_UNUSED230:\n\t\tcase DUK_OP_UNUSED231:\n\t\tcase DUK_OP_UNUSED232:\n\t\tcase DUK_OP_UNUSED233:\n\t\tcase DUK_OP_UNUSED234:\n\t\tcase DUK_OP_UNUSED235:\n\t\tcase DUK_OP_UNUSED236:\n\t\tcase DUK_OP_UNUSED237:\n\t\tcase DUK_OP_UNUSED238:\n\t\tcase DUK_OP_UNUSED239:\n\t\tcase DUK_OP_UNUSED240:\n\t\tcase DUK_OP_UNUSED241:\n\t\tcase DUK_OP_UNUSED242:\n\t\tcase DUK_OP_UNUSED243:\n\t\tcase DUK_OP_UNUSED244:\n\t\tcase DUK_OP_UNUSED245:\n\t\tcase DUK_OP_UNUSED246:\n\t\tcase DUK_OP_UNUSED247:\n\t\tcase DUK_OP_UNUSED248:\n\t\tcase DUK_OP_UNUSED249:\n\t\tcase DUK_OP_UNUSED250:\n\t\tcase DUK_OP_UNUSED251:\n\t\tcase DUK_OP_UNUSED252:\n\t\tcase DUK_OP_UNUSED253:\n\t\tcase DUK_OP_UNUSED254:\n\t\tcase DUK_OP_UNUSED255:\n\t\t/* Force all case clauses to map to an actual handler\n\t\t * so that the compiler can emit a jump without a bounds\n\t\t * check: the switch argument is a duk_uint8_t so that\n\t\t * the compiler may be able to figure it out.  This is\n\t\t * a small detail and obviously compiler dependent.\n\t\t */\n\t\t/* default: clause omitted on purpose */\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tdefault:\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\t{\n\t\t\t/* Default case catches invalid/unsupported opcodes. */\n\t\t\tDUK_D(DUK_DPRINT(\"invalid opcode: %ld - %!I\", (long) op, ins));\n\t\t\tDUK__INTERNAL_ERROR(\"invalid opcode\");\n\t\t\tbreak;\n\t\t}\n\n\t\t}  /* end switch */\n\n\t\tcontinue;\n\n\t\t/* Some shared exit paths for opcode handling below.  These\n\t\t * are mostly useful to reduce code footprint when multiple\n\t\t * opcodes have a similar epilogue (like replacing stack top\n\t\t * with index 'a').\n\t\t */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t replace_top_a:\n\t\tDUK__REPLACE_TO_TVPTR(thr, DUK__REGP_A(ins));\n\t\tcontinue;\n\t replace_top_bc:\n\t\tDUK__REPLACE_TO_TVPTR(thr, DUK__REGP_BC(ins));\n\t\tcontinue;\n#endif\n\t}\n\tDUK_WO_NORETURN(return;);\n\n#if !defined(DUK_USE_VERBOSE_EXECUTOR_ERRORS)\n internal_error:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n#endif\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_js_ops.c",
    "content": "/*\n *  ECMAScript specification algorithm and conversion helpers.\n *\n *  These helpers encapsulate the primitive ECMAScript operation semantics,\n *  and are used by the bytecode executor and the API (among other places).\n *  Some primitives are only implemented as part of the API and have no\n *  \"internal\" helper.  This is the case when an internal helper would not\n *  really be useful; e.g. the operation is rare, uses value stack heavily,\n *  etc.\n *\n *  The operation arguments depend on what is required to implement\n *  the operation:\n *\n *    - If an operation is simple and stateless, and has no side\n *      effects, it won't take an duk_hthread argument and its\n *      arguments may be duk_tval pointers (which are safe as long\n *      as no side effects take place).\n *\n *    - If complex coercions are required (e.g. a \"ToNumber\" coercion)\n *      or errors may be thrown, the operation takes an duk_hthread\n *      argument.  This also implies that the operation may have\n *      arbitrary side effects, invalidating any duk_tval pointers.\n *\n *    - For operations with potential side effects, arguments can be\n *      taken in several ways:\n *\n *      a) as duk_tval pointers, which makes sense if the \"common case\"\n *         can be resolved without side effects (e.g. coercion); the\n *         arguments are pushed to the valstack for coercion if\n *         necessary\n *\n *      b) as duk_tval values\n *\n *      c) implicitly on value stack top\n *\n *      d) as indices to the value stack\n *\n *  Future work:\n *\n *     - Argument styles may not be the most sensible in every case now.\n *\n *     - In-place coercions might be useful for several operations, if\n *       in-place coercion is OK for the bytecode executor and the API.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  ToPrimitive()  (E5 Section 9.1)\n *\n *  ==> implemented in the API.\n */\n\n/*\n *  ToBoolean()  (E5 Section 9.2)\n */\n\nDUK_INTERNAL duk_bool_t duk_js_toboolean(duk_tval *tv) {\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\t\treturn 0;\n\tcase DUK_TAG_BOOLEAN:\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv) == 0 || DUK_TVAL_GET_BOOLEAN(tv) == 1);\n\t\treturn DUK_TVAL_GET_BOOLEAN(tv);\n\tcase DUK_TAG_STRING: {\n\t\t/* Symbols ToBoolean() coerce to true, regardless of their\n\t\t * description.  This happens with no explicit check because\n\t\t * of the symbol representation byte prefix.\n\t\t */\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HSTRING_GET_BYTELEN(h) > 0 ? 1 : 0);\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\treturn 1;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\t/* Mimic Uint8Array semantics: objects coerce true, regardless\n\t\t * of buffer length (zero or not) or context.\n\t\t */\n\t\treturn 1;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tvoid *p = DUK_TVAL_GET_POINTER(tv);\n\t\treturn (p != NULL ? 1 : 0);\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\treturn 1;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\tif (DUK_TVAL_GET_FASTINT(tv) != 0) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tduk_double_t d;\n#if defined(DUK_USE_PREFER_SIZE)\n\t\tint c;\n#endif\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\t\td = DUK_TVAL_GET_DOUBLE(tv);\n#if defined(DUK_USE_PREFER_SIZE)\n\t\tc = DUK_FPCLASSIFY((double) d);\n\t\tif (c == DUK_FP_ZERO || c == DUK_FP_NAN) {\n\t\t\treturn 0;\n\t\t} else {\n\t\t\treturn 1;\n\t\t}\n#else\n\t\tDUK_ASSERT(duk_double_is_nan_or_zero(d) == 0 || duk_double_is_nan_or_zero(d) == 1);\n\t\treturn duk_double_is_nan_or_zero(d) ^ 1;\n#endif\n\t}\n\t}\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  ToNumber()  (E5 Section 9.3)\n *\n *  Value to convert must be on stack top, and is popped before exit.\n *\n *  See: http://www.cs.indiana.edu/~burger/FP-Printing-PLDI96.pdf\n *       http://www.cs.indiana.edu/~burger/fp/index.html\n *\n *  Notes on the conversion:\n *\n *    - There are specific requirements on the accuracy of the conversion\n *      through a \"Mathematical Value\" (MV), so this conversion is not\n *      trivial.\n *\n *    - Quick rejects (e.g. based on first char) are difficult because\n *      the grammar allows leading and trailing white space.\n *\n *    - Quick reject based on string length is difficult even after\n *      accounting for white space; there may be arbitrarily many\n *      decimal digits.\n *\n *    - Standard grammar allows decimal values (\"123\"), hex values\n *      (\"0x123\") and infinities\n *\n *    - Unlike source code literals, ToNumber() coerces empty strings\n *      and strings with only whitespace to zero (not NaN).  However,\n *      while '' coerces to 0, '+' and '-' coerce to NaN.\n */\n\n/* E5 Section 9.3.1 */\nDUK_LOCAL duk_double_t duk__tonumber_string_raw(duk_hthread *thr) {\n\tduk_small_uint_t s2n_flags;\n\tduk_double_t d;\n\n\tDUK_ASSERT(duk_is_string(thr, -1));\n\n\t/* Quite lenient, e.g. allow empty as zero, but don't allow trailing\n\t * garbage.\n\t */\n\ts2n_flags = DUK_S2N_FLAG_TRIM_WHITE |\n\t            DUK_S2N_FLAG_ALLOW_EXP |\n\t            DUK_S2N_FLAG_ALLOW_PLUS |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |\n\t            DUK_S2N_FLAG_ALLOW_INF |\n\t            DUK_S2N_FLAG_ALLOW_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO |\n\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT;\n\n\tduk_numconv_parse(thr, 10 /*radix*/, s2n_flags);\n\n#if defined(DUK_USE_PREFER_SIZE)\n\td = duk_get_number(thr, -1);\n\tduk_pop_unsafe(thr);\n#else\n\tthr->valstack_top--;\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(thr->valstack_top));\n\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(thr->valstack_top));  /* no fastint conversion in numconv now */\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(thr->valstack_top));\n\td = DUK_TVAL_GET_DOUBLE(thr->valstack_top);  /* assumes not a fastint */\n\tDUK_TVAL_SET_UNDEFINED(thr->valstack_top);\n#endif\n\n\treturn d;\n}\n\nDUK_INTERNAL duk_double_t duk_js_tonumber(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\t/* return a specific NaN (although not strictly necessary) */\n\t\tduk_double_union du;\n\t\tDUK_DBLUNION_SET_NAN(&du);\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\t\treturn du.d;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\t/* +0.0 */\n\t\treturn 0.0;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tif (DUK_TVAL_IS_BOOLEAN_TRUE(tv)) {\n\t\t\treturn 1.0;\n\t\t}\n\t\treturn 0.0;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\t/* For Symbols ToNumber() is always a TypeError. */\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CANNOT_NUMBER_COERCE_SYMBOL);\n\t\t\tDUK_WO_NORETURN(return 0.0;);\n\t\t}\n\t\tduk_push_hstring(thr, h);\n\t\treturn duk__tonumber_string_raw(thr);\n\t}\n\tcase DUK_TAG_BUFFER:  /* plain buffer treated like object */\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_double_t d;\n\t\tduk_push_tval(thr, tv);\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);  /* 'tv' becomes invalid */\n\n\t\t/* recursive call for a primitive value (guaranteed not to cause second\n\t\t * recursion).\n\t\t */\n\t\tDUK_ASSERT(duk_get_tval(thr, -1) != NULL);\n\t\td = duk_js_tonumber(thr, duk_get_tval(thr, -1));\n\n\t\tduk_pop_unsafe(thr);\n\t\treturn d;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\t/* Coerce like boolean */\n\t\tvoid *p = DUK_TVAL_GET_POINTER(tv);\n\t\treturn (p != NULL ? 1.0 : 0.0);\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* +(function(){}) -> NaN */\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\treturn (duk_double_t) DUK_TVAL_GET_FASTINT(tv);\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\t\treturn DUK_TVAL_GET_DOUBLE(tv);\n\t}\n\t}\n\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  ToInteger()  (E5 Section 9.4)\n */\n\n/* exposed, used by e.g. duk_bi_date.c */\nDUK_INTERNAL duk_double_t duk_js_tointeger_number(duk_double_t x) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\n\tif (DUK_UNLIKELY(c == DUK_FP_NAN)) {\n\t\treturn 0.0;\n\t} else if (DUK_UNLIKELY(c == DUK_FP_INFINITE)) {\n\t\treturn x;\n\t} else {\n\t\t/* Finite, including neg/pos zero.  Neg zero sign must be\n\t\t * preserved.\n\t\t */\n\t\treturn duk_double_trunc_towards_zero(x);\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\t/* NaN and Infinity have the same exponent so it's a cheap\n\t * initial check for the rare path.\n\t */\n\tif (DUK_UNLIKELY(duk_double_is_nan_or_inf(x) != 0U)) {\n\t\tif (duk_double_is_nan(x)) {\n\t\t\treturn 0.0;\n\t\t} else {\n\t\t\treturn x;\n\t\t}\n\t} else {\n\t\treturn duk_double_trunc_towards_zero(x);\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n}\n\nDUK_INTERNAL duk_double_t duk_js_tointeger(duk_hthread *thr, duk_tval *tv) {\n\t/* XXX: fastint */\n\tduk_double_t d = duk_js_tonumber(thr, tv);  /* invalidates tv */\n\treturn duk_js_tointeger_number(d);\n}\n\n/*\n *  ToInt32(), ToUint32(), ToUint16()  (E5 Sections 9.5, 9.6, 9.7)\n */\n\n/* combined algorithm matching E5 Sections 9.5 and 9.6 */\nDUK_LOCAL duk_double_t duk__toint32_touint32_helper(duk_double_t x, duk_bool_t is_toint32) {\n#if defined (DUK_USE_PREFER_SIZE)\n\tduk_small_int_t c;\n#endif\n\n#if defined (DUK_USE_PREFER_SIZE)\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (c == DUK_FP_NAN || c == DUK_FP_ZERO || c == DUK_FP_INFINITE) {\n\t\treturn 0.0;\n\t}\n#else\n\tif (duk_double_is_nan_zero_inf(x)) {\n\t\treturn 0.0;\n\t}\n#endif\n\n\t/* x = sign(x) * floor(abs(x)), i.e. truncate towards zero, keep sign */\n\tx = duk_double_trunc_towards_zero(x);\n\n\t/* NOTE: fmod(x) result sign is same as sign of x, which\n\t * differs from what Javascript wants (see Section 9.6).\n\t */\n\n\tx = DUK_FMOD(x, DUK_DOUBLE_2TO32);    /* -> x in ]-2**32, 2**32[ */\n\n\tif (x < 0.0) {\n\t\tx += DUK_DOUBLE_2TO32;\n\t}\n\tDUK_ASSERT(x >= 0 && x < DUK_DOUBLE_2TO32);  /* -> x in [0, 2**32[ */\n\n\tif (is_toint32) {\n\t\tif (x >= DUK_DOUBLE_2TO31) {\n\t\t\t/* x in [2**31, 2**32[ */\n\n\t\t\tx -= DUK_DOUBLE_2TO32;  /* -> x in [-2**31,2**31[ */\n\t\t}\n\t}\n\n\treturn x;\n}\n\nDUK_INTERNAL duk_int32_t duk_js_toint32(duk_hthread *thr, duk_tval *tv) {\n\tduk_double_t d;\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\treturn DUK_TVAL_GET_FASTINT_I32(tv);\n\t}\n#endif\n\n\td = duk_js_tonumber(thr, tv);  /* invalidates tv */\n\td = duk__toint32_touint32_helper(d, 1);\n\tDUK_ASSERT(DUK_FPCLASSIFY(d) == DUK_FP_ZERO || DUK_FPCLASSIFY(d) == DUK_FP_NORMAL);\n\tDUK_ASSERT(d >= -2147483648.0 && d <= 2147483647.0);  /* [-0x80000000,0x7fffffff] */\n\tDUK_ASSERT(d == ((duk_double_t) ((duk_int32_t) d)));  /* whole, won't clip */\n\treturn (duk_int32_t) d;\n}\n\n\nDUK_INTERNAL duk_uint32_t duk_js_touint32(duk_hthread *thr, duk_tval *tv) {\n\tduk_double_t d;\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\treturn DUK_TVAL_GET_FASTINT_U32(tv);\n\t}\n#endif\n\n\td = duk_js_tonumber(thr, tv);  /* invalidates tv */\n\td = duk__toint32_touint32_helper(d, 0);\n\tDUK_ASSERT(DUK_FPCLASSIFY(d) == DUK_FP_ZERO || DUK_FPCLASSIFY(d) == DUK_FP_NORMAL);\n\tDUK_ASSERT(d >= 0.0 && d <= 4294967295.0);  /* [0x00000000, 0xffffffff] */\n\tDUK_ASSERT(d == ((duk_double_t) ((duk_uint32_t) d)));  /* whole, won't clip */\n\treturn (duk_uint32_t) d;\n\n}\n\nDUK_INTERNAL duk_uint16_t duk_js_touint16(duk_hthread *thr, duk_tval *tv) {\n\t/* should be a safe way to compute this */\n\treturn (duk_uint16_t) (duk_js_touint32(thr, tv) & 0x0000ffffU);\n}\n\n/*\n *  ToString()  (E5 Section 9.8)\n *  ToObject()  (E5 Section 9.9)\n *  CheckObjectCoercible()  (E5 Section 9.10)\n *  IsCallable()  (E5 Section 9.11)\n *\n *  ==> implemented in the API.\n */\n\n/*\n *  Loose equality, strict equality, and SameValue (E5 Sections 11.9.1, 11.9.4,\n *  9.12).  These have much in common so they can share some helpers.\n *\n *  Future work notes:\n *\n *    - Current implementation (and spec definition) has recursion; this should\n *      be fixed if possible.\n *\n *    - String-to-number coercion should be possible without going through the\n *      value stack (and be more compact) if a shared helper is invoked.\n */\n\n/* Note that this is the same operation for strict and loose equality:\n *  - E5 Section 11.9.3, step 1.c (loose)\n *  - E5 Section 11.9.6, step 4 (strict)\n */\n\nDUK_LOCAL duk_bool_t duk__js_equals_number(duk_double_t x, duk_double_t y) {\n#if defined(DUK_USE_PARANOID_MATH)\n\t/* Straightforward algorithm, makes fewer compiler assumptions. */\n\tduk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tduk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\tif (cx == DUK_FP_NAN || cy == DUK_FP_NAN) {\n\t\treturn 0;\n\t}\n\tif (cx == DUK_FP_ZERO && cy == DUK_FP_ZERO) {\n\t\treturn 1;\n\t}\n\tif (x == y) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else  /* DUK_USE_PARANOID_MATH */\n\t/* Better equivalent algorithm.  If the compiler is compliant, C and\n\t * ECMAScript semantics are identical for this particular comparison.\n\t * In particular, NaNs must never compare equal and zeroes must compare\n\t * equal regardless of sign.  Could also use a macro, but this inlines\n\t * already nicely (no difference on gcc, for instance).\n\t */\n\tif (x == y) {\n\t\t/* IEEE requires that NaNs compare false */\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(x) != DUK_FP_NAN);\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(y) != DUK_FP_NAN);\n\t\treturn 1;\n\t} else {\n\t\t/* IEEE requires that zeros compare the same regardless\n\t\t * of their signed, so if both x and y are zeroes, they\n\t\t * are caught above.\n\t\t */\n\t\tDUK_ASSERT(!(DUK_FPCLASSIFY(x) == DUK_FP_ZERO && DUK_FPCLASSIFY(y) == DUK_FP_ZERO));\n\t\treturn 0;\n\t}\n#endif  /* DUK_USE_PARANOID_MATH */\n}\n\nDUK_LOCAL duk_bool_t duk__js_samevalue_number(duk_double_t x, duk_double_t y) {\n#if defined(DUK_USE_PARANOID_MATH)\n\tduk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tduk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\n\tif (cx == DUK_FP_NAN && cy == DUK_FP_NAN) {\n\t\t/* SameValue(NaN, NaN) = true, regardless of NaN sign or extra bits */\n\t\treturn 1;\n\t}\n\tif (cx == DUK_FP_ZERO && cy == DUK_FP_ZERO) {\n\t\t/* Note: cannot assume that a non-zero return value of signbit() would\n\t\t * always be the same -- hence cannot (portably) use something like:\n\t\t *\n\t\t *     signbit(x) == signbit(y)\n\t\t */\n\t\tduk_small_int_t sx = DUK_SIGNBIT(x) ? 1 : 0;\n\t\tduk_small_int_t sy = DUK_SIGNBIT(y) ? 1 : 0;\n\t\treturn (sx == sy);\n\t}\n\n\t/* normal comparison; known:\n\t *   - both x and y are not NaNs (but one of them can be)\n\t *   - both x and y are not zero (but one of them can be)\n\t *   - x and y may be denormal or infinite\n\t */\n\n\treturn (x == y);\n#else  /* DUK_USE_PARANOID_MATH */\n\tduk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tduk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\n\tif (x == y) {\n\t\t/* IEEE requires that NaNs compare false */\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(x) != DUK_FP_NAN);\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(y) != DUK_FP_NAN);\n\n\t\t/* Using classification has smaller footprint than direct comparison. */\n\t\tif (DUK_UNLIKELY(cx == DUK_FP_ZERO && cy == DUK_FP_ZERO)) {\n\t\t\t/* Note: cannot assume that a non-zero return value of signbit() would\n\t\t\t * always be the same -- hence cannot (portably) use something like:\n\t\t\t *\n\t\t\t *     signbit(x) == signbit(y)\n\t\t\t */\n\t\t\treturn duk_double_same_sign(x, y);\n\t\t}\n\t\treturn 1;\n\t} else {\n\t\t/* IEEE requires that zeros compare the same regardless\n\t\t * of their sign, so if both x and y are zeroes, they\n\t\t * are caught above.\n\t\t */\n\t\tDUK_ASSERT(!(DUK_FPCLASSIFY(x) == DUK_FP_ZERO && DUK_FPCLASSIFY(y) == DUK_FP_ZERO));\n\n\t\t/* Difference to non-strict/strict comparison is that NaNs compare\n\t\t * equal and signed zero signs matter.\n\t\t */\n\t\tif (DUK_UNLIKELY(cx == DUK_FP_NAN && cy == DUK_FP_NAN)) {\n\t\t\t/* SameValue(NaN, NaN) = true, regardless of NaN sign or extra bits */\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t}\n#endif  /* DUK_USE_PARANOID_MATH */\n}\n\nDUK_INTERNAL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags) {\n\tduk_uint_t type_mask_x;\n\tduk_uint_t type_mask_y;\n\n\t/* If flags != 0 (strict or SameValue), thr can be NULL.  For loose\n\t * equals comparison it must be != NULL.\n\t */\n\tDUK_ASSERT(flags != 0 || thr != NULL);\n\n\t/*\n\t *  Same type?\n\t *\n\t *  Note: since number values have no explicit tag in the 8-byte\n\t *  representation, need the awkward if + switch.\n\t */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\tif (DUK_TVAL_GET_FASTINT(tv_x) == DUK_TVAL_GET_FASTINT(tv_y)) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}\n\telse\n#endif\n\tif (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) {\n\t\tduk_double_t d1, d2;\n\n\t\t/* Catches both doubles and cases where only one argument is\n\t\t * a fastint so can't assume a double.\n\t\t */\n\t\td1 = DUK_TVAL_GET_NUMBER(tv_x);\n\t\td2 = DUK_TVAL_GET_NUMBER(tv_y);\n\t\tif (DUK_UNLIKELY((flags & DUK_EQUALS_FLAG_SAMEVALUE) != 0)) {\n\t\t\t/* SameValue */\n\t\t\treturn duk__js_samevalue_number(d1, d2);\n\t\t} else {\n\t\t\t/* equals and strict equals */\n\t\t\treturn duk__js_equals_number(d1, d2);\n\t\t}\n\t} else if (DUK_TVAL_GET_TAG(tv_x) == DUK_TVAL_GET_TAG(tv_y)) {\n\t\tswitch (DUK_TVAL_GET_TAG(tv_x)) {\n\t\tcase DUK_TAG_UNDEFINED:\n\t\tcase DUK_TAG_NULL: {\n\t\t\treturn 1;\n\t\t}\n\t\tcase DUK_TAG_BOOLEAN: {\n\t\t\treturn DUK_TVAL_GET_BOOLEAN(tv_x) == DUK_TVAL_GET_BOOLEAN(tv_y);\n\t\t}\n\t\tcase DUK_TAG_POINTER: {\n\t\t\treturn DUK_TVAL_GET_POINTER(tv_x) == DUK_TVAL_GET_POINTER(tv_y);\n\t\t}\n\t\tcase DUK_TAG_STRING:\n\t\tcase DUK_TAG_OBJECT: {\n\t\t\t/* Heap pointer comparison suffices for strings and objects.\n\t\t\t * Symbols compare equal if they have the same internal\n\t\t\t * representation; again heap pointer comparison suffices.\n\t\t\t */\n\t\t\treturn DUK_TVAL_GET_HEAPHDR(tv_x) == DUK_TVAL_GET_HEAPHDR(tv_y);\n\t\t}\n\t\tcase DUK_TAG_BUFFER: {\n\t\t\t/* In Duktape 2.x plain buffers mimic Uint8Array objects\n\t\t\t * so always compare by heap pointer.  In Duktape 1.x\n\t\t\t * strict comparison would compare heap pointers and\n\t\t\t * non-strict would compare contents.\n\t\t\t */\n\t\t\treturn DUK_TVAL_GET_HEAPHDR(tv_x) == DUK_TVAL_GET_HEAPHDR(tv_y);\n\t\t}\n\t\tcase DUK_TAG_LIGHTFUNC: {\n\t\t\t/* At least 'magic' has a significant impact on function\n\t\t\t * identity.\n\t\t\t */\n\t\t\tduk_small_uint_t lf_flags_x;\n\t\t\tduk_small_uint_t lf_flags_y;\n\t\t\tduk_c_function func_x;\n\t\t\tduk_c_function func_y;\n\n\t\t\tDUK_TVAL_GET_LIGHTFUNC(tv_x, func_x, lf_flags_x);\n\t\t\tDUK_TVAL_GET_LIGHTFUNC(tv_y, func_y, lf_flags_y);\n\t\t\treturn ((func_x == func_y) && (lf_flags_x == lf_flags_y)) ? 1 : 0;\n\t\t}\n#if defined(DUK_USE_FASTINT)\n\t\tcase DUK_TAG_FASTINT:\n#endif\n\t\tdefault: {\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_x));\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_y));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_x));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_y));\n\t\t\tDUK_UNREACHABLE();\n\t\t\treturn 0;\n\t\t}\n\t\t}\n\t}\n\n\tif ((flags & (DUK_EQUALS_FLAG_STRICT | DUK_EQUALS_FLAG_SAMEVALUE)) != 0) {\n\t\treturn 0;\n\t}\n\n\tDUK_ASSERT(flags == 0);  /* non-strict equality from here on */\n\n\t/*\n\t *  Types are different; various cases for non-strict comparison\n\t *\n\t *  Since comparison is symmetric, we use a \"swap trick\" to reduce\n\t *  code size.\n\t */\n\n\ttype_mask_x = duk_get_type_mask_tval(tv_x);\n\ttype_mask_y = duk_get_type_mask_tval(tv_y);\n\n\t/* Undefined/null are considered equal (e.g. \"null == undefined\" -> true). */\n\tif ((type_mask_x & (DUK_TYPE_MASK_UNDEFINED | DUK_TYPE_MASK_NULL)) &&\n\t    (type_mask_y & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED))) {\n\t\treturn 1;\n\t}\n\n\t/* Number/string -> coerce string to number (e.g. \"'1.5' == 1.5\" -> true). */\n\tif ((type_mask_x & DUK_TYPE_MASK_NUMBER) && (type_mask_y & DUK_TYPE_MASK_STRING)) {\n\t\tif (!DUK_TVAL_STRING_IS_SYMBOL(tv_y)) {\n\t\t\tduk_double_t d1, d2;\n\t\t\td1 = DUK_TVAL_GET_NUMBER(tv_x);\n\t\t\td2 = duk_to_number_tval(thr, tv_y);\n\t\t\treturn duk__js_equals_number(d1, d2);\n\t\t}\n\t}\n\tif ((type_mask_x & DUK_TYPE_MASK_STRING) && (type_mask_y & DUK_TYPE_MASK_NUMBER)) {\n\t\tif (!DUK_TVAL_STRING_IS_SYMBOL(tv_x)) {\n\t\t\tduk_double_t d1, d2;\n\t\t\td1 = DUK_TVAL_GET_NUMBER(tv_y);\n\t\t\td2 = duk_to_number_tval(thr, tv_x);\n\t\t\treturn duk__js_equals_number(d1, d2);\n\t\t}\n\t}\n\n\t/* Boolean/any -> coerce boolean to number and try again.  If boolean is\n\t * compared to a pointer, the final comparison after coercion now always\n\t * yields false (as pointer vs. number compares to false), but this is\n\t * not special cased.\n\t *\n\t * ToNumber(bool) is +1.0 or 0.0.  Tagged boolean value is always 0 or 1.\n\t */\n\tif (type_mask_x & DUK_TYPE_MASK_BOOLEAN) {\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv_x) == 0 || DUK_TVAL_GET_BOOLEAN(tv_x) == 1);\n\t\tduk_push_uint(thr, DUK_TVAL_GET_BOOLEAN(tv_x));\n\t\tduk_push_tval(thr, tv_y);\n\t\tgoto recursive_call;\n\t}\n\tif (type_mask_y & DUK_TYPE_MASK_BOOLEAN) {\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv_y) == 0 || DUK_TVAL_GET_BOOLEAN(tv_y) == 1);\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_uint(thr, DUK_TVAL_GET_BOOLEAN(tv_y));\n\t\tgoto recursive_call;\n\t}\n\n\t/* String-number-symbol/object -> coerce object to primitive (apparently without hint), then try again. */\n\tif ((type_mask_x & (DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_NUMBER)) &&\n\t    (type_mask_y & DUK_TYPE_MASK_OBJECT)) {\n\t\t/* No symbol check needed because symbols and strings are accepted. */\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NONE);  /* apparently no hint? */\n\t\tgoto recursive_call;\n\t}\n\tif ((type_mask_x & DUK_TYPE_MASK_OBJECT) &&\n\t    (type_mask_y & (DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_NUMBER))) {\n\t\t/* No symbol check needed because symbols and strings are accepted. */\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\tduk_to_primitive(thr, -2, DUK_HINT_NONE);  /* apparently no hint? */\n\t\tgoto recursive_call;\n\t}\n\n\t/* Nothing worked -> not equal. */\n\treturn 0;\n\n recursive_call:\n\t/* Shared code path to call the helper again with arguments on stack top. */\n\t{\n\t\tduk_bool_t rc;\n\t\trc = duk_js_equals_helper(thr,\n\t\t                          DUK_GET_TVAL_NEGIDX(thr, -2),\n\t\t                          DUK_GET_TVAL_NEGIDX(thr, -1),\n\t\t                          0 /*flags:nonstrict*/);\n\t\tduk_pop_2_unsafe(thr);\n\t\treturn rc;\n\t}\n}\n\n/*\n *  Comparisons (x >= y, x > y, x <= y, x < y)\n *\n *  E5 Section 11.8.5: implement 'x < y' and then use negate and eval_left_first\n *  flags to get the rest.\n */\n\n/* XXX: this should probably just operate on the stack top, because it\n * needs to push stuff on the stack anyway...\n */\n\nDUK_INTERNAL duk_small_int_t duk_js_data_compare(const duk_uint8_t *buf1, const duk_uint8_t *buf2, duk_size_t len1, duk_size_t len2) {\n\tduk_size_t prefix_len;\n\tduk_small_int_t rc;\n\n\tprefix_len = (len1 <= len2 ? len1 : len2);\n\n\t/* duk_memcmp() is guaranteed to return zero (equal) for zero length\n\t * inputs.\n\t */\n\trc = duk_memcmp_unsafe((const void *) buf1,\n\t                       (const void *) buf2,\n\t                       (size_t) prefix_len);\n\n\tif (rc < 0) {\n\t\treturn -1;\n\t} else if (rc > 0) {\n\t\treturn 1;\n\t}\n\n\t/* prefix matches, lengths matter now */\n\tif (len1 < len2) {\n\t\t/* e.g. \"x\" < \"xx\" */\n\t\treturn -1;\n\t} else if (len1 > len2) {\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\nDUK_INTERNAL duk_small_int_t duk_js_string_compare(duk_hstring *h1, duk_hstring *h2) {\n\t/*\n\t *  String comparison (E5 Section 11.8.5, step 4), which\n\t *  needs to compare codepoint by codepoint.\n\t *\n\t *  However, UTF-8 allows us to use strcmp directly: the shared\n\t *  prefix will be encoded identically (UTF-8 has unique encoding)\n\t *  and the first differing character can be compared with a simple\n\t *  unsigned byte comparison (which strcmp does).\n\t *\n\t *  This will not work properly for non-xutf-8 strings, but this\n\t *  is not an issue for compliance.\n\t */\n\n\tDUK_ASSERT(h1 != NULL);\n\tDUK_ASSERT(h2 != NULL);\n\n\treturn duk_js_data_compare((const duk_uint8_t *) DUK_HSTRING_GET_DATA(h1),\n\t                           (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h2),\n\t                           (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1),\n\t                           (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2));\n}\n\n#if 0  /* unused */\nDUK_INTERNAL duk_small_int_t duk_js_buffer_compare(duk_heap *heap, duk_hbuffer *h1, duk_hbuffer *h2) {\n\t/* Similar to String comparison. */\n\n\tDUK_ASSERT(h1 != NULL);\n\tDUK_ASSERT(h2 != NULL);\n\tDUK_UNREF(heap);\n\n\treturn duk_js_data_compare((const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(heap, h1),\n\t                           (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(heap, h2),\n\t                           (duk_size_t) DUK_HBUFFER_GET_SIZE(h1),\n\t                           (duk_size_t) DUK_HBUFFER_GET_SIZE(h2));\n}\n#endif\n\n#if defined(DUK_USE_FASTINT)\nDUK_LOCAL duk_bool_t duk__compare_fastint(duk_bool_t retval, duk_int64_t v1, duk_int64_t v2) {\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\tif (v1 < v2) {\n\t\treturn retval ^ 1;\n\t} else {\n\t\treturn retval;\n\t}\n}\n#endif\n\n#if defined(DUK_USE_PARANOID_MATH)\nDUK_LOCAL duk_bool_t duk__compare_number(duk_bool_t retval, duk_double_t d1, duk_double_t d2) {\n\tduk_small_int_t c1, s1, c2, s2;\n\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\tc1 = (duk_small_int_t) DUK_FPCLASSIFY(d1);\n\ts1 = (duk_small_int_t) DUK_SIGNBIT(d1);\n\tc2 = (duk_small_int_t) DUK_FPCLASSIFY(d2);\n\ts2 = (duk_small_int_t) DUK_SIGNBIT(d2);\n\n\tif (c1 == DUK_FP_NAN || c2 == DUK_FP_NAN) {\n\t\treturn 0;  /* Always false, regardless of negation. */\n\t}\n\n\tif (c1 == DUK_FP_ZERO && c2 == DUK_FP_ZERO) {\n\t\t/* For all combinations: +0 < +0, +0 < -0, -0 < +0, -0 < -0,\n\t\t * steps e, f, and g.\n\t\t */\n\t\treturn retval;  /* false */\n\t}\n\n\tif (d1 == d2) {\n\t\treturn retval;  /* false */\n\t}\n\n\tif (c1 == DUK_FP_INFINITE && s1 == 0) {\n\t\t/* x == +Infinity */\n\t\treturn retval;  /* false */\n\t}\n\n\tif (c2 == DUK_FP_INFINITE && s2 == 0) {\n\t\t/* y == +Infinity */\n\t\treturn retval ^ 1;  /* true */\n\t}\n\n\tif (c2 == DUK_FP_INFINITE && s2 != 0) {\n\t\t/* y == -Infinity */\n\t\treturn retval;  /* false */\n\t}\n\n\tif (c1 == DUK_FP_INFINITE && s1 != 0) {\n\t\t/* x == -Infinity */\n\t\treturn retval ^ 1;  /* true */\n\t}\n\n\tif (d1 < d2) {\n\t\treturn retval ^ 1;  /* true */\n\t}\n\n\treturn retval;  /* false */\n}\n#else  /* DUK_USE_PARANOID_MATH */\nDUK_LOCAL duk_bool_t duk__compare_number(duk_bool_t retval, duk_double_t d1, duk_double_t d2) {\n\t/* This comparison tree relies doesn't match the exact steps in\n\t * E5 Section 11.8.5 but should produce the same results.  The\n\t * steps rely on exact IEEE semantics for NaNs, etc.\n\t */\n\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\tif (d1 < d2) {\n\t\t/* In no case should both (d1 < d2) and (d2 < d1) be true.\n\t\t * It's possible that neither is true though, and that's\n\t\t * handled below.\n\t\t */\n\t\tDUK_ASSERT(!(d2 < d1));\n\n\t\t/* - d1 < d2, both d1/d2 are normals (not Infinity, not NaN)\n\t\t * - d2 is +Infinity, d1 != +Infinity and NaN\n\t\t * - d1 is -Infinity, d2 != -Infinity and NaN\n\t\t */\n\t\treturn retval ^ 1;\n\t} else {\n\t\tif (d2 < d1) {\n\t\t\t/* - !(d1 < d2), both d1/d2 are normals (not Infinity, not NaN)\n\t\t\t * - d1 is +Infinity, d2 != +Infinity and NaN\n\t\t\t * - d2 is -Infinity, d1 != -Infinity and NaN\n\t\t\t */\n\t\t\treturn retval;\n\t\t} else {\n\t\t\t/* - d1 and/or d2 is NaN\n\t\t\t * - d1 and d2 are both +/- 0\n\t\t\t * - d1 == d2 (including infinities)\n\t\t\t */\n\t\t\tif (duk_double_is_nan(d1) || duk_double_is_nan(d2)) {\n\t\t\t\t/* Note: undefined from Section 11.8.5 always\n\t\t\t\t * results in false return (see e.g. Section\n\t\t\t\t * 11.8.3) - hence special treatment here.\n\t\t\t\t */\n\t\t\t\treturn 0;  /* zero regardless of negation */\n\t\t\t} else {\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\t}\n}\n#endif  /* DUK_USE_PARANOID_MATH */\n\nDUK_INTERNAL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags) {\n\tduk_double_t d1, d2;\n\tduk_small_int_t rc;\n\tduk_bool_t retval;\n\n\tDUK_ASSERT(DUK_COMPARE_FLAG_NEGATE == 1);  /* Rely on this flag being lowest. */\n\tretval = flags & DUK_COMPARE_FLAG_NEGATE;\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\n\t/* Fast path for fastints */\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_LIKELY(DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y))) {\n\t\treturn duk__compare_fastint(retval,\n\t\t                            DUK_TVAL_GET_FASTINT(tv_x),\n\t\t                            DUK_TVAL_GET_FASTINT(tv_y));\n\t}\n#endif  /* DUK_USE_FASTINT */\n\n\t/* Fast path for numbers (one of which may be a fastint) */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tif (DUK_LIKELY(DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y))) {\n\t\treturn duk__compare_number(retval,\n\t\t                           DUK_TVAL_GET_NUMBER(tv_x),\n\t\t                           DUK_TVAL_GET_NUMBER(tv_y));\n\t}\n#endif\n\n\t/* Slow path */\n\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\n\tif (flags & DUK_COMPARE_FLAG_EVAL_LEFT_FIRST) {\n\t\tduk_to_primitive(thr, -2, DUK_HINT_NUMBER);\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);\n\t} else {\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);\n\t\tduk_to_primitive(thr, -2, DUK_HINT_NUMBER);\n\t}\n\n\t/* Note: reuse variables */\n\ttv_x = DUK_GET_TVAL_NEGIDX(thr, -2);\n\ttv_y = DUK_GET_TVAL_NEGIDX(thr, -1);\n\n\tif (DUK_TVAL_IS_STRING(tv_x) && DUK_TVAL_IS_STRING(tv_y)) {\n\t\tduk_hstring *h1 = DUK_TVAL_GET_STRING(tv_x);\n\t\tduk_hstring *h2 = DUK_TVAL_GET_STRING(tv_y);\n\t\tDUK_ASSERT(h1 != NULL);\n\t\tDUK_ASSERT(h2 != NULL);\n\n\t\tif (DUK_LIKELY(!DUK_HSTRING_HAS_SYMBOL(h1) && !DUK_HSTRING_HAS_SYMBOL(h2))) {\n\t\t\trc = duk_js_string_compare(h1, h2);\n\t\t\tduk_pop_2_unsafe(thr);\n\t\t\tif (rc < 0) {\n\t\t\t\treturn retval ^ 1;\n\t\t\t} else {\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\n\t\t/* One or both are Symbols: fall through to handle in the\n\t\t * generic path.  Concretely, ToNumber() will fail.\n\t\t */\n\t}\n\n\t/* Ordering should not matter (E5 Section 11.8.5, step 3.a). */\n#if 0\n\tif (flags & DUK_COMPARE_FLAG_EVAL_LEFT_FIRST) {\n\t\td1 = duk_to_number_m2(thr);\n\t\td2 = duk_to_number_m1(thr);\n\t} else {\n\t\td2 = duk_to_number_m1(thr);\n\t\td1 = duk_to_number_m2(thr);\n\t}\n#endif\n\td1 = duk_to_number_m2(thr);\n\td2 = duk_to_number_m1(thr);\n\n\t/* We want to duk_pop_2_unsafe(thr); because the values are numbers\n\t * no decref check is needed.\n\t */\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_pop_2_nodecref_unsafe(thr);\n#else\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk_get_tval(thr, -2)));\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk_get_tval(thr, -1)));\n\tDUK_ASSERT(duk_get_top(thr) >= 2);\n\tthr->valstack_top -= 2;\n\ttv_x = thr->valstack_top;\n\ttv_y = tv_x + 1;\n\tDUK_TVAL_SET_UNDEFINED(tv_x);  /* Value stack policy */\n\tDUK_TVAL_SET_UNDEFINED(tv_y);\n#endif\n\n\treturn duk__compare_number(retval, d1, d2);\n}\n\n/*\n *  instanceof\n */\n\n/*\n *  ES2015 Section 7.3.19 describes the OrdinaryHasInstance() algorithm\n *  which covers both bound and non-bound functions; in effect the algorithm\n *  includes E5 Sections 11.8.6, 15.3.5.3, and 15.3.4.5.3.\n *\n *  ES2015 Section 12.9.4 describes the instanceof operator which first\n *  checks @@hasInstance well-known symbol and falls back to\n *  OrdinaryHasInstance().\n *\n *  Limited Proxy support: don't support 'getPrototypeOf' trap but\n *  continue lookup in Proxy target if the value is a Proxy.\n */\n\nDUK_LOCAL duk_bool_t duk__js_instanceof_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_bool_t skip_sym_check) {\n\tduk_hobject *func;\n\tduk_hobject *val;\n\tduk_hobject *proto;\n\tduk_tval *tv;\n\tduk_bool_t skip_first;\n\tduk_uint_t sanity;\n\n\t/*\n\t *  Get the values onto the stack first.  It would be possible to cover\n\t *  some normal cases without resorting to the value stack.\n\t *\n\t *  The right hand side could be a light function (as they generally\n\t *  behave like objects).  Light functions never have a 'prototype'\n\t *  property so E5.1 Section 15.3.5.3 step 3 always throws a TypeError.\n\t *  Using duk_require_hobject() is thus correct (except for error msg).\n\t */\n\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\tfunc = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(func != NULL);\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t/*\n\t *  @@hasInstance check, ES2015 Section 12.9.4, Steps 2-4.\n\t */\n\tif (!skip_sym_check) {\n\t\tif (duk_get_method_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE)) {\n\t\t\t/* [ ... lhs rhs func ] */\n\t\t\tduk_insert(thr, -3);    /* -> [ ... func lhs rhs ] */\n\t\t\tduk_swap_top(thr, -2);  /* -> [ ... func rhs(this) lhs ] */\n\t\t\tduk_call_method(thr, 1);\n\t\t\treturn duk_to_boolean_top_pop(thr);\n\t\t}\n\t}\n#else\n\tDUK_UNREF(skip_sym_check);\n#endif\n\n\t/*\n\t *  For bound objects, [[HasInstance]] just calls the target function\n\t *  [[HasInstance]].  If that is again a bound object, repeat until\n\t *  we find a non-bound Function object.\n\t *\n\t *  The bound function chain is now \"collapsed\" so there can be only\n\t *  one bound function in the chain.\n\t */\n\n\tif (!DUK_HOBJECT_IS_CALLABLE(func)) {\n\t\t/*\n\t\t *  Note: of native ECMAScript objects, only Function instances\n\t\t *  have a [[HasInstance]] internal property.  Custom objects might\n\t\t *  also have it, but not in current implementation.\n\t\t *\n\t\t *  XXX: add a separate flag, DUK_HOBJECT_FLAG_ALLOW_INSTANCEOF?\n\t\t */\n\t\tgoto error_invalid_rval;\n\t}\n\n\tif (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {\n\t\tduk_push_tval(thr, &((duk_hboundfunc *) (void *) func)->target);\n\t\tduk_replace(thr, -2);\n\t\tfunc = duk_require_hobject(thr, -1);  /* lightfunc throws */\n\n\t\t/* Rely on Function.prototype.bind() never creating bound\n\t\t * functions whose target is not proper.\n\t\t */\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(func));\n\t}\n\n\t/*\n\t *  'func' is now a non-bound object which supports [[HasInstance]]\n\t *  (which here just means DUK_HOBJECT_FLAG_CALLABLE).  Move on\n\t *  to execute E5 Section 15.3.5.3.\n\t */\n\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\tDUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(func));\n\n\t/* [ ... lval rval(func) ] */\n\n\t/* For lightfuncs, buffers, and pointers start the comparison directly\n\t * from the virtual prototype object.\n\t */\n\tskip_first = 0;\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -2);\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_LIGHTFUNC:\n\t\tval = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tcase DUK_TAG_BUFFER:\n\t\tval = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tcase DUK_TAG_POINTER:\n\t\tval = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\tskip_first = 1;  /* Ignore object itself on first round. */\n\t\tval = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tdefault:\n\t\tgoto pop2_and_false;\n\t}\n\tDUK_ASSERT(val != NULL);  /* Loop doesn't actually rely on this. */\n\n\t/* Look up .prototype of rval.  Leave it on the value stack in case it\n\t * has been virtualized (e.g. getter, Proxy trap).\n\t */\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_PROTOTYPE);  /* -> [ ... lval rval rval.prototype ] */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\tproto = duk_get_hobject(thr, -1);\n\tif (proto == NULL) {\n\t\tgoto error_invalid_rval_noproto;\n\t}\n#else\n\tproto = duk_require_hobject(thr, -1);\n#endif\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\t/*\n\t\t *  Note: prototype chain is followed BEFORE first comparison.  This\n\t\t *  means that the instanceof lval is never itself compared to the\n\t\t *  rval.prototype property.  This is apparently intentional, see E5\n\t\t *  Section 15.3.5.3, step 4.a.\n\t\t *\n\t\t *  Also note:\n\t\t *\n\t\t *      js> (function() {}) instanceof Function\n\t\t *      true\n\t\t *      js> Function instanceof Function\n\t\t *      true\n\t\t *\n\t\t *  For the latter, h_proto will be Function.prototype, which is the\n\t\t *  built-in Function prototype.  Because Function.[[Prototype]] is\n\t\t *  also the built-in Function prototype, the result is true.\n\t\t */\n\n\t\tif (!val) {\n\t\t\tgoto pop3_and_false;\n\t\t}\n\n\t\tDUK_ASSERT(val != NULL);\n#if defined(DUK_USE_ES6_PROXY)\n\t\tval = duk_hobject_resolve_proxy_target(val);\n#endif\n\n\t\tif (skip_first) {\n\t\t\tskip_first = 0;\n\t\t} else if (val == proto) {\n\t\t\tgoto pop3_and_true;\n\t\t}\n\n\t\tDUK_ASSERT(val != NULL);\n\t\tval = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, val);\n\t} while (--sanity > 0);\n\n\tif (DUK_UNLIKELY(sanity == 0)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tDUK_UNREACHABLE();\n\n pop2_and_false:\n\tduk_pop_2_unsafe(thr);\n\treturn 0;\n\n pop3_and_false:\n\tduk_pop_3_unsafe(thr);\n\treturn 0;\n\n pop3_and_true:\n\tduk_pop_3_unsafe(thr);\n\treturn 1;\n\n error_invalid_rval:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_INSTANCEOF_RVAL);\n\tDUK_WO_NORETURN(return 0;);\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n error_invalid_rval_noproto:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_INSTANCEOF_RVAL_NOPROTO);\n\tDUK_WO_NORETURN(return 0;);\n#endif\n}\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL duk_bool_t duk_js_instanceof_ordinary(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {\n\treturn duk__js_instanceof_helper(thr, tv_x, tv_y, 1 /*skip_sym_check*/);\n}\n#endif\n\nDUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {\n\treturn duk__js_instanceof_helper(thr, tv_x, tv_y, 0 /*skip_sym_check*/);\n}\n\n/*\n *  in\n */\n\n/*\n *  E5 Sections 11.8.7, 8.12.6.\n *\n *  Basically just a property existence check using [[HasProperty]].\n */\n\nDUK_INTERNAL duk_bool_t duk_js_in(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {\n\tduk_bool_t retval;\n\n\t/*\n\t *  Get the values onto the stack first.  It would be possible to cover\n\t *  some normal cases without resorting to the value stack (e.g. if\n\t *  lval is already a string).\n\t */\n\n\t/* XXX: The ES5/5.1/6 specifications require that the key in 'key in obj'\n\t * must be string coerced before the internal HasProperty() algorithm is\n\t * invoked.  A fast path skipping coercion could be safely implemented for\n\t * numbers (as number-to-string coercion has no side effects).  For ES2015\n\t * proxy behavior, the trap 'key' argument must be in a string coerced\n\t * form (which is a shame).\n\t */\n\n\t/* TypeError if rval is not an object or object like (e.g. lightfunc\n\t * or plain buffer).\n\t */\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\tduk_require_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT | DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\n\t(void) duk_to_property_key_hstring(thr, -2);\n\n\tretval = duk_hobject_hasprop(thr,\n\t                             DUK_GET_TVAL_NEGIDX(thr, -1),\n\t                             DUK_GET_TVAL_NEGIDX(thr, -2));\n\n\tduk_pop_2_unsafe(thr);\n\treturn retval;\n}\n\n/*\n *  typeof\n *\n *  E5 Section 11.4.3.\n *\n *  Very straightforward.  The only question is what to return for our\n *  non-standard tag / object types.\n *\n *  There is an unfortunate string constant define naming problem with\n *  typeof return values for e.g. \"Object\" and \"object\"; careful with\n *  the built-in string defines.  The LC_XXX defines are used for the\n *  lowercase variants now.\n */\n\nDUK_INTERNAL duk_small_uint_t duk_js_typeof_stridx(duk_tval *tv_x) {\n\tduk_small_uint_t stridx = 0;\n\n\tswitch (DUK_TVAL_GET_TAG(tv_x)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\tstridx = DUK_STRIDX_LC_UNDEFINED;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\t/* Note: not a typo, \"object\" is returned for a null value. */\n\t\tstridx = DUK_STRIDX_LC_OBJECT;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tstridx = DUK_STRIDX_LC_BOOLEAN;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\t/* Implementation specific. */\n\t\tstridx = DUK_STRIDX_LC_POINTER;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *str;\n\n\t\t/* All internal keys are identified as Symbols. */\n\t\tstr = DUK_TVAL_GET_STRING(tv_x);\n\t\tDUK_ASSERT(str != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(str))) {\n\t\t\tstridx = DUK_STRIDX_LC_SYMBOL;\n\t\t} else {\n\t\t\tstridx = DUK_STRIDX_LC_STRING;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *obj = DUK_TVAL_GET_OBJECT(tv_x);\n\t\tDUK_ASSERT(obj != NULL);\n\t\tif (DUK_HOBJECT_IS_CALLABLE(obj)) {\n\t\t\tstridx = DUK_STRIDX_LC_FUNCTION;\n\t\t} else {\n\t\t\tstridx = DUK_STRIDX_LC_OBJECT;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\t/* Implementation specific.  In Duktape 1.x this would be\n\t\t * 'buffer', in Duktape 2.x changed to 'object' because plain\n\t\t * buffers now mimic Uint8Array objects.\n\t\t */\n\t\tstridx = DUK_STRIDX_LC_OBJECT;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tstridx = DUK_STRIDX_LC_FUNCTION;\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_x));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_x));\n\t\tstridx = DUK_STRIDX_LC_NUMBER;\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\treturn stridx;\n}\n\n/*\n *  Array index and length\n *\n *  Array index: E5 Section 15.4\n *  Array length: E5 Section 15.4.5.1 steps 3.c - 3.d (array length write)\n */\n\n/* Compure array index from string context, or return a \"not array index\"\n * indicator.\n */\nDUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_string(const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uarridx_t res;\n\n\t/* Only strings with byte length 1-10 can be 32-bit array indices.\n\t * Leading zeroes (except '0' alone), plus/minus signs are not allowed.\n\t * We could do a lot of prechecks here, but since most strings won't\n\t * start with any digits, it's simpler to just parse the number and\n\t * fail quickly.\n\t */\n\n\tres = 0;\n\tif (blen == 0) {\n\t\tgoto parse_fail;\n\t}\n\tdo {\n\t\tduk_uarridx_t dig;\n\t\tdig = (duk_uarridx_t) (*str++) - DUK_ASC_0;\n\n\t\tif (dig <= 9U) {\n\t\t\t/* Careful overflow handling.  When multiplying by 10:\n\t\t\t * - 0x19999998 x 10 = 0xfffffff0: no overflow, and adding\n\t\t\t *   0...9 is safe.\n\t\t\t * - 0x19999999 x 10 = 0xfffffffa: no overflow, adding\n\t\t\t *   0...5 is safe, 6...9 overflows.\n\t\t\t * - 0x1999999a x 10 = 0x100000004: always overflow.\n\t\t\t */\n\t\t\tif (DUK_UNLIKELY(res >= 0x19999999UL)) {\n\t\t\t\tif (res >= 0x1999999aUL) {\n\t\t\t\t\t/* Always overflow. */\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(res == 0x19999999UL);\n\t\t\t\tif (dig >= 6U) {\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t\tres = 0xfffffffaUL + dig;\n\t\t\t\tDUK_ASSERT(res >= 0xfffffffaUL);\n\t\t\t\tDUK_ASSERT_DISABLE(res <= 0xffffffffUL);  /* range */\n\t\t\t} else {\n\t\t\t\tres = res * 10U + dig;\n\t\t\t\tif (DUK_UNLIKELY(res == 0)) {\n\t\t\t\t\t/* If 'res' is 0, previous 'res' must\n\t\t\t\t\t * have been 0 and we scanned in a zero.\n\t\t\t\t\t * This is only allowed if blen == 1,\n\t\t\t\t\t * i.e. the exact string '0'.\n\t\t\t\t\t */\n\t\t\t\t\tif (blen == (duk_uint32_t) 1) {\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\t}\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t/* Because 'dig' is unsigned, catches both values\n\t\t\t * above '9' and below '0'.\n\t\t\t */\n\t\t\tgoto parse_fail;\n\t\t}\n\t} while (--blen > 0);\n\n\treturn res;\n\n parse_fail:\n\treturn DUK_HSTRING_NO_ARRAY_INDEX;\n}\n\n#if !defined(DUK_USE_HSTRING_ARRIDX)\n/* Get array index for a string which is known to be an array index.  This helper\n * is needed when duk_hstring doesn't concretely store the array index, but strings\n * are flagged as array indices at intern time.\n */\nDUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_hstring_fast_known(duk_hstring *h) {\n\tconst duk_uint8_t *p;\n\tduk_uarridx_t res;\n\tduk_uint8_t t;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(h));\n\n\tp = DUK_HSTRING_GET_DATA(h);\n\tres = 0;\n\tfor (;;) {\n\t\tt = *p++;\n\t\tif (DUK_UNLIKELY(t == 0)) {\n\t\t\t/* Scanning to NUL is always safe for interned strings. */\n\t\t\tbreak;\n\t\t}\n\t\tDUK_ASSERT(t >= (duk_uint8_t) DUK_ASC_0 && t <= (duk_uint8_t) DUK_ASC_9);\n\t\tres = res * 10U + (duk_uarridx_t) t - (duk_uarridx_t) DUK_ASC_0;\n\t}\n\treturn res;\n}\n\nDUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_hstring_fast(duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n\tif (!DUK_HSTRING_HAS_ARRIDX(h)) {\n\t\treturn DUK_HSTRING_NO_ARRAY_INDEX;\n\t}\n\treturn duk_js_to_arrayindex_hstring_fast_known(h);\n}\n#endif  /* DUK_USE_HSTRING_ARRIDX */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_js_var.c",
    "content": "/*\n *  Identifier access and function closure handling.\n *\n *  Provides the primitives for slow path identifier accesses: GETVAR,\n *  PUTVAR, DELVAR, etc.  The fast path, direct register accesses, should\n *  be used for most identifier accesses.  Consequently, these slow path\n *  primitives should be optimized for maximum compactness.\n *\n *  ECMAScript environment records (declarative and object) are represented\n *  as internal objects with control keys.  Environment records have a\n *  parent record (\"outer environment reference\") which is represented by\n *  the implicit prototype for technical reasons (in other words, it is a\n *  convenient field).  The prototype chain is not followed in the ordinary\n *  sense for variable lookups.\n *\n *  See identifier-handling.rst for more details on the identifier algorithms\n *  and the internal representation.  See function-objects.rst for details on\n *  what function templates and instances are expected to look like.\n *\n *  Care must be taken to avoid duk_tval pointer invalidation caused by\n *  e.g. value stack or object resizing.\n *\n *  TODO: properties for function instances could be initialized much more\n *  efficiently by creating a property allocation for a certain size and\n *  filling in keys and values directly (and INCREFing both with \"bulk incref\"\n *  primitives.\n *\n *  XXX: duk_hobject_getprop() and duk_hobject_putprop() calls are a bit\n *  awkward (especially because they follow the prototype chain); rework\n *  if \"raw\" own property helpers are added.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Local result type for duk__get_identifier_reference() lookup.\n */\n\ntypedef struct {\n\tduk_hobject *env;\n\tduk_hobject *holder;      /* for object-bound identifiers */\n\tduk_tval *value;          /* for register-bound and declarative env identifiers */\n\tduk_uint_t attrs;         /* property attributes for identifier (relevant if value != NULL) */\n\tduk_bool_t has_this;      /* for object-bound identifiers: provide 'this' binding */\n} duk__id_lookup_result;\n\n/*\n *  Create a new function object based on a \"template function\" which contains\n *  compiled bytecode, constants, etc, but lacks a lexical environment.\n *\n *  ECMAScript requires that each created closure is a separate object, with\n *  its own set of editable properties.  However, structured property values\n *  (such as the formal arguments list and the variable map) are shared.\n *  Also the bytecode, constants, and inner functions are shared.\n *\n *  See E5 Section 13.2 for detailed requirements on the function objects;\n *  there are no similar requirements for function \"templates\" which are an\n *  implementation dependent internal feature.  Also see function-objects.rst\n *  for a discussion on the function instance properties provided by this\n *  implementation.\n *\n *  Notes:\n *\n *   * Order of internal properties should match frequency of use, since the\n *     properties will be linearly scanned on lookup (functions usually don't\n *     have enough properties to warrant a hash part).\n *\n *   * The created closure is independent of its template; they do share the\n *     same 'data' buffer object, but the template object itself can be freed\n *     even if the closure object remains reachable.\n */\n\nDUK_LOCAL void duk__inc_data_inner_refcounts(duk_hthread *thr, duk_hcompfunc *f) {\n\tduk_tval *tv, *tv_end;\n\tduk_hobject **funcs, **funcs_end;\n\n\tDUK_UNREF(thr);\n\n\t/* If function creation fails due to out-of-memory, the data buffer\n\t * pointer may be NULL in some cases.  That's actually possible for\n\t * GC code, but shouldn't be possible here because the incomplete\n\t * function will be unwound from the value stack and never instantiated.\n\t */\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, f) != NULL);\n\n\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, f);\n\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, f);\n\twhile (tv < tv_end) {\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\ttv++;\n\t}\n\n\tfuncs = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, f);\n\tfuncs_end = DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, f);\n\twhile (funcs < funcs_end) {\n\t\tDUK_HEAPHDR_INCREF(thr, (duk_heaphdr *) *funcs);\n\t\tfuncs++;\n\t}\n}\n\n/* Push a new closure on the stack.\n *\n * Note: if fun_temp has NEWENV, i.e. a new lexical and variable declaration\n * is created when the function is called, only outer_lex_env matters\n * (outer_var_env is ignored and may or may not be same as outer_lex_env).\n */\n\nDUK_LOCAL const duk_uint16_t duk__closure_copy_proplist[] = {\n\t/* order: most frequent to least frequent */\n\tDUK_STRIDX_INT_VARMAP,\n\tDUK_STRIDX_INT_FORMALS,\n#if defined(DUK_USE_PC2LINE)\n\tDUK_STRIDX_INT_PC2LINE,\n#endif\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tDUK_STRIDX_FILE_NAME,\n#endif\n#if defined(DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY)\n\tDUK_STRIDX_INT_SOURCE\n#endif\n};\n\nDUK_INTERNAL\nvoid duk_js_push_closure(duk_hthread *thr,\n                         duk_hcompfunc *fun_temp,\n                         duk_hobject *outer_var_env,\n                         duk_hobject *outer_lex_env,\n                         duk_bool_t add_auto_proto) {\n\tduk_hcompfunc *fun_clos;\n\tduk_harray *formals;\n\tduk_small_uint_t i;\n\tduk_uint_t len_value;\n\n\tDUK_ASSERT(fun_temp != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_temp) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_temp) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_temp) != NULL);\n\tDUK_ASSERT(outer_var_env != NULL);\n\tDUK_ASSERT(outer_lex_env != NULL);\n\tDUK_UNREF(len_value);\n\n\tDUK_STATS_INC(thr->heap, stats_envrec_pushclosure);\n\n\tfun_clos = duk_push_hcompfunc(thr);\n\tDUK_ASSERT(fun_clos != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) fun_clos) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\n\tduk_push_hobject(thr, &fun_temp->obj);  /* -> [ ... closure template ] */\n\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun_clos));\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_clos) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_clos) == NULL);\n\n\tDUK_HCOMPFUNC_SET_DATA(thr->heap, fun_clos, DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_temp));\n\tDUK_HCOMPFUNC_SET_FUNCS(thr->heap, fun_clos, DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_temp));\n\tDUK_HCOMPFUNC_SET_BYTECODE(thr->heap, fun_clos, DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_temp));\n\n\t/* Note: all references inside 'data' need to get their refcounts\n\t * upped too.  This is the case because refcounts are decreased\n\t * through every function referencing 'data' independently.\n\t */\n\n\tDUK_HBUFFER_INCREF(thr, DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos));\n\tduk__inc_data_inner_refcounts(thr, fun_temp);\n\n\tfun_clos->nregs = fun_temp->nregs;\n\tfun_clos->nargs = fun_temp->nargs;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tfun_clos->start_line = fun_temp->start_line;\n\tfun_clos->end_line = fun_temp->end_line;\n#endif\n\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_clos) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_clos) != NULL);\n\n\t/* XXX: Could also copy from template, but there's no way to have any\n\t * other value here now (used code has no access to the template).\n\t * Prototype is set by duk_push_hcompfunc().\n\t */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, &fun_clos->obj) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#if 0\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, &fun_clos->obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#endif\n\n\t/* Copy duk_hobject flags as is from the template using a mask.\n\t * Leave out duk_heaphdr owned flags just in case (e.g. if there's\n\t * some GC flag or similar).  Some flags can then be adjusted\n\t * separately if necessary.\n\t */\n\n\t/* DUK_HEAPHDR_SET_FLAGS() masks changes to non-duk_heaphdr flags only. */\n\tDUK_HEAPHDR_SET_FLAGS((duk_heaphdr *) fun_clos, DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) fun_temp));\n\tDUK_DD(DUK_DDPRINT(\"fun_temp heaphdr flags: 0x%08lx, fun_clos heaphdr flags: 0x%08lx\",\n\t                   (unsigned long) DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) fun_temp),\n\t                   (unsigned long) DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) fun_clos)));\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&fun_clos->obj));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(&fun_clos->obj));\n\t/* DUK_HOBJECT_FLAG_ARRAY_PART: don't care */\n\t/* DUK_HOBJECT_FLAG_NEWENV: handled below */\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(&fun_clos->obj));\n\n\tif (!DUK_HOBJECT_HAS_CONSTRUCTABLE(&fun_clos->obj)) {\n\t\t/* If the template is not constructable don't add an automatic\n\t\t * .prototype property.  This is the case for e.g. ES2015 object\n\t\t * literal getters/setters and method definitions.\n\t\t */\n\t\tadd_auto_proto = 0;\n\t}\n\n\t/*\n\t *  Setup environment record properties based on the template and\n\t *  its flags.\n\t *\n\t *  If DUK_HOBJECT_HAS_NEWENV(fun_temp) is true, the environment\n\t *  records represent identifiers \"outside\" the function; the\n\t *  \"inner\" environment records are created on demand.  Otherwise,\n\t *  the environment records are those that will be directly used\n\t *  (e.g. for declarations).\n\t *\n\t *  _Lexenv is always set; _Varenv defaults to _Lexenv if missing,\n\t *  so _Varenv is only set if _Lexenv != _Varenv.\n\t *\n\t *  This is relatively complex, see doc/identifier-handling.rst.\n\t */\n\n\tif (DUK_HOBJECT_HAS_NEWENV(&fun_clos->obj)) {\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\t\tif (DUK_HOBJECT_HAS_NAMEBINDING(&fun_clos->obj)) {\n\t\t\tduk_hobject *proto;\n\t\t\tduk_hdecenv *new_env;\n\n\t\t\t/*\n\t\t\t *  Named function expression, name needs to be bound\n\t\t\t *  in an intermediate environment record.  The \"outer\"\n\t\t\t *  lexical/variable environment will thus be:\n\t\t\t *\n\t\t\t *  a) { funcname: <func>, __prototype: outer_lex_env }\n\t\t\t *  b) { funcname: <func>, __prototype:  <globalenv> }  (if outer_lex_env missing)\n\t\t\t */\n\n\t\t\tif (outer_lex_env) {\n\t\t\t\tproto = outer_lex_env;\n\t\t\t} else {\n\t\t\t\tproto = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t\t\t}\n\n\t\t\t/* -> [ ... closure template env ] */\n\t\t\tnew_env = duk_hdecenv_alloc(thr,\n\t\t\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\t\t\tDUK_ASSERT(new_env != NULL);\n\t\t\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, proto);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, proto);\n\n\t\t\tDUK_ASSERT(new_env->thread == NULL);  /* Closed. */\n\t\t\tDUK_ASSERT(new_env->varmap == NULL);\n\n\t\t\t/* It's important that duk_xdef_prop() is a 'raw define' so that any\n\t\t\t * properties in an ancestor are never an issue (they should never be\n\t\t\t * e.g. non-writable, but just in case).\n\t\t\t *\n\t\t\t * Because template objects are not visible to user code, the case\n\t\t\t * where .name is missing shouldn't happen in practice.  It it does,\n\t\t\t * the name 'undefined' gets bound and maps to the closure (which is\n\t\t\t * a bit odd, but safe).\n\t\t\t */\n\t\t\t(void) duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME);\n\t\t\t/* -> [ ... closure template env funcname ] */\n\t\t\tduk_dup_m4(thr);                                           /* -> [ ... closure template env funcname closure ] */\n\t\t\tduk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_NONE);           /* -> [ ... closure template env ] */\n\t\t\t/* env[funcname] = closure */\n\n\t\t\t/* [ ... closure template env ] */\n\n\t\t\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, fun_clos, (duk_hobject *) new_env);\n\t\t\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, (duk_hobject *) new_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env);\n\t\t\tduk_pop_unsafe(thr);\n\n\t\t\t/* [ ... closure template ] */\n\t\t}\n\t\telse\n#endif  /* DUK_USE_FUNC_NAME_PROPERTY */\n\t\t{\n\t\t\t/*\n\t\t\t *  Other cases (function declaration, anonymous function expression,\n\t\t\t *  strict direct eval code).  The \"outer\" environment will be whatever\n\t\t\t *  the caller gave us.\n\t\t\t */\n\n\t\t\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, fun_clos, outer_lex_env);\n\t\t\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, outer_lex_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, outer_lex_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, outer_lex_env);\n\n\t\t\t/* [ ... closure template ] */\n\t\t}\n\t} else {\n\t\t/*\n\t\t *  Function gets no new environment when called.  This is the\n\t\t *  case for global code, indirect eval code, and non-strict\n\t\t *  direct eval code.  There is no direct correspondence to the\n\t\t *  E5 specification, as global/eval code is not exposed as a\n\t\t *  function.\n\t\t */\n\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NAMEBINDING(&fun_temp->obj));\n\n\t\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, fun_clos, outer_lex_env);\n\t\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, outer_var_env);\n\t\tDUK_HOBJECT_INCREF(thr, outer_lex_env);  /* NULLs not allowed; asserted on entry */\n\t\tDUK_HOBJECT_INCREF(thr, outer_var_env);\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"closure varenv -> %!ipO, lexenv -> %!ipO\",\n\t                     (duk_heaphdr *) fun_clos->var_env,\n\t                     (duk_heaphdr *) fun_clos->lex_env));\n\n\t/* Call handling assumes this for all callable closures. */\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_LEXENV(thr->heap, fun_clos) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_VARENV(thr->heap, fun_clos) != NULL);\n\n\t/*\n\t *  Copy some internal properties directly\n\t *\n\t *  The properties will be non-writable and non-enumerable, but\n\t *  configurable.\n\t *\n\t *  Function templates are bare objects, so inheritance of internal\n\t *  Symbols is not an issue here even when using ordinary property\n\t *  reads.  The function instance created is not bare, so internal\n\t *  Symbols must be defined without inheritance checks.\n\t */\n\n\t/* [ ... closure template ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"copying properties: closure=%!iT, template=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tfor (i = 0; i < (duk_small_uint_t) (sizeof(duk__closure_copy_proplist) / sizeof(duk_uint16_t)); i++) {\n\t\tduk_small_int_t stridx = (duk_small_int_t) duk__closure_copy_proplist[i];\n\t\tif (duk_xget_owndataprop_stridx_short(thr, -1, stridx)) {\n\t\t\t/* [ ... closure template val ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copying property, stridx=%ld -> found\", (long) stridx));\n\t\t\tduk_xdef_prop_stridx_short(thr, -3, stridx, DUK_PROPDESC_FLAGS_C);\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copying property, stridx=%ld -> not found\", (long) stridx));\n\t\t\tduk_pop_unsafe(thr);\n\t\t}\n\t}\n\n\t/*\n\t *  \"length\" maps to number of formals (E5 Section 13.2) for function\n\t *  declarations/expressions (non-bound functions).  Note that 'nargs'\n\t *  is NOT necessarily equal to the number of arguments.  Use length\n\t *  of _Formals; if missing, assume nargs matches .length.\n\t */\n\n\t/* [ ... closure template ] */\n\n\tformals = duk_hobject_get_formals(thr, (duk_hobject *) fun_temp);\n\tif (formals) {\n\t\tlen_value = (duk_uint_t) formals->length;\n\t\tDUK_DD(DUK_DDPRINT(\"closure length from _Formals -> %ld\", (long) len_value));\n\t} else {\n\t\tlen_value = fun_temp->nargs;\n\t\tDUK_DD(DUK_DDPRINT(\"closure length defaulted from nargs -> %ld\", (long) len_value));\n\t}\n\n\tduk_push_uint(thr, len_value);  /* [ ... closure template len_value ] */\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);\n\n\t/*\n\t *  \"prototype\" is, by default, a fresh object with the \"constructor\"\n\t *  property.\n\t *\n\t *  Note that this creates a circular reference for every function\n\t *  instance (closure) which prevents refcount-based collection of\n\t *  function instances.\n\t *\n\t *  XXX: Try to avoid creating the default prototype object, because\n\t *  many functions are not used as constructors and the default\n\t *  prototype is unnecessary.  Perhaps it could be created on-demand\n\t *  when it is first accessed?\n\t */\n\n\t/* [ ... closure template ] */\n\n\tif (add_auto_proto) {\n\t\tduk_push_object(thr);  /* -> [ ... closure template newobj ] */\n\t\tduk_dup_m3(thr);       /* -> [ ... closure template newobj closure ] */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC);  /* -> [ ... closure template newobj ] */\n\t\tduk_compact(thr, -1);  /* compact the prototype */\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W);     /* -> [ ... closure template ] */\n\t}\n\n\t/*\n\t *  \"arguments\" and \"caller\" must be mapped to throwers for strict\n\t *  mode and bound functions (E5 Section 15.3.5).\n\t *\n\t *  XXX: This is expensive to have for every strict function instance.\n\t *  Try to implement as virtual properties or on-demand created properties.\n\t */\n\n\t/* [ ... closure template ] */\n\n\tif (DUK_HOBJECT_HAS_STRICT(&fun_clos->obj)) {\n\t\tduk_xdef_prop_stridx_thrower(thr, -2, DUK_STRIDX_CALLER);\n\t\tduk_xdef_prop_stridx_thrower(thr, -2, DUK_STRIDX_LC_ARGUMENTS);\n\t} else {\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is non-strict and non-standard 'caller' property in use, add initial 'null' value\"));\n\t\tduk_push_null(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_CALLER, DUK_PROPDESC_FLAGS_NONE);\n#else\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is non-strict and non-standard 'caller' property not used\"));\n#endif\n\t}\n\n\t/*\n\t *  \"name\" used to be non-standard but is now defined by ES2015.\n\t *  In ES2015/ES2016 the .name property is configurable.\n\t */\n\n\t/* [ ... closure template ] */\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\t/* XXX: Look for own property only; doesn't matter much because\n\t * templates are bare objects.\n\t */\n\tif (duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME)) {\n\t\t/* [ ... closure template name ] */\n\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\t\tDUK_DD(DUK_DDPRINT(\"setting function instance name to %!T\", duk_get_tval(thr, -1)));\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);  /* -> [ ... closure template ] */\n\t} else {\n\t\t/* Anonymous functions don't have a .name in ES2015, so don't set\n\t\t * it on the instance either.  The instance will then inherit\n\t\t * it from Function.prototype.name.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"not setting function instance .name\"));\n\t\tduk_pop_unsafe(thr);\n\t}\n#endif\n\n\t/*\n\t *  Compact the closure, in most cases no properties will be added later.\n\t *  Also, without this the closures end up having unused property slots\n\t *  (e.g. in Duktape 0.9.0, 8 slots would be allocated and only 7 used).\n\t *  A better future solution would be to allocate the closure directly\n\t *  to correct size (and setup the properties directly without going\n\t *  through the API).\n\t */\n\n\tduk_compact(thr, -2);\n\n\t/*\n\t *  Some assertions (E5 Section 13.2).\n\t */\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(&fun_clos->obj) == DUK_HOBJECT_CLASS_FUNCTION);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, &fun_clos->obj) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(&fun_clos->obj));\n\tDUK_ASSERT(duk_has_prop_stridx(thr, -2, DUK_STRIDX_LENGTH) != 0);\n\tDUK_ASSERT(add_auto_proto == 0 || duk_has_prop_stridx(thr, -2, DUK_STRIDX_PROTOTYPE) != 0);\n\t/* May be missing .name */\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(&fun_clos->obj) ||\n\t           duk_has_prop_stridx(thr, -2, DUK_STRIDX_CALLER) != 0);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(&fun_clos->obj) ||\n\t           duk_has_prop_stridx(thr, -2, DUK_STRIDX_LC_ARGUMENTS) != 0);\n\n\t/*\n\t *  Finish\n\t */\n\n\t/* [ ... closure template ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"created function instance: template=%!iT -> closure=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (duk_tval *) duk_get_tval(thr, -2)));\n\n\tduk_pop_unsafe(thr);\n\n\t/* [ ... closure ] */\n}\n\n/*\n *  Delayed activation environment record initialization (for functions\n *  with NEWENV).\n *\n *  The non-delayed initialization is handled by duk_handle_call().\n */\n\nDUK_LOCAL void duk__preallocate_env_entries(duk_hthread *thr, duk_hobject *varmap, duk_hobject *env) {\n\tduk_uint_fast32_t i;\n\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(varmap); i++) {\n\t\tduk_hstring *key;\n\n\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, varmap, i);\n\t\tDUK_ASSERT(key != NULL);   /* assume keys are compact in _Varmap */\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, varmap, i));  /* assume plain values */\n\n\t\t/* Predefine as 'undefined' to reserve a property slot.\n\t\t * This makes the unwind process (where register values\n\t\t * are copied to the env object) safe against throwing.\n\t\t *\n\t\t * XXX: This could be made much faster by creating the\n\t\t * property table directly.\n\t\t */\n\t\tduk_push_undefined(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"preallocate env entry for key %!O\", key));\n\t\tduk_hobject_define_property_internal(thr, env, key, DUK_PROPDESC_FLAGS_WE);\n\t}\n}\n\n/* shared helper */\nDUK_INTERNAL\nduk_hobject *duk_create_activation_environment_record(duk_hthread *thr,\n                                                      duk_hobject *func,\n                                                      duk_size_t bottom_byteoff) {\n\tduk_hdecenv *env;\n\tduk_hobject *parent;\n\tduk_hcompfunc *f;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\n\tDUK_STATS_INC(thr->heap, stats_envrec_create);\n\n\tf = (duk_hcompfunc *) func;\n\tparent = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f);\n\tif (!parent) {\n\t\tparent = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t}\n\n\tenv = duk_hdecenv_alloc(thr,\n\t                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\tDUK_ASSERT(env != NULL);\n\tduk_push_hobject(thr, (duk_hobject *) env);\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) env, parent);\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, parent);  /* parent env is the prototype */\n\n\t/* open scope information, for compiled functions only */\n\n\tDUK_ASSERT(env->thread == NULL);\n\tDUK_ASSERT(env->varmap == NULL);\n\tDUK_ASSERT(env->regbase_byteoff == 0);\n\tif (DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\tduk_hobject *varmap;\n\n\t\tvarmap = duk_hobject_get_varmap(thr, func);\n\t\tif (varmap != NULL) {\n\t\t\tenv->varmap = varmap;\n\t\t\tDUK_HOBJECT_INCREF(thr, varmap);\n\t\t\tenv->thread = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tenv->regbase_byteoff = bottom_byteoff;\n\n\t\t\t/* Preallocate env property table to avoid potential\n\t\t\t * for out-of-memory on unwind when the env is closed.\n\t\t\t */\n\t\t\tduk__preallocate_env_entries(thr, varmap, (duk_hobject *) env);\n\t\t} else {\n\t\t\t/* If function has no _Varmap, leave the environment closed. */\n\t\t\tDUK_ASSERT(env->thread == NULL);\n\t\t\tDUK_ASSERT(env->varmap == NULL);\n\t\t\tDUK_ASSERT(env->regbase_byteoff == 0);\n\t\t}\n\t}\n\n\treturn (duk_hobject *) env;\n}\n\nDUK_INTERNAL\nvoid duk_js_init_activation_environment_records_delayed(duk_hthread *thr,\n                                                        duk_activation *act) {\n\tduk_hobject *func;\n\tduk_hobject *env;\n\n\tDUK_ASSERT(thr != NULL);\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));  /* bound functions are never in act 'func' */\n\n\t/*\n\t *  Delayed initialization only occurs for 'NEWENV' functions.\n\t */\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func));\n\tDUK_ASSERT(act->lex_env == NULL);\n\tDUK_ASSERT(act->var_env == NULL);\n\n\tDUK_STATS_INC(thr->heap, stats_envrec_delayedcreate);\n\n\tenv = duk_create_activation_environment_record(thr, func, act->bottom_byteoff);\n\tDUK_ASSERT(env != NULL);\n\t/* 'act' is a stable pointer, so still OK. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"created delayed fresh env: %!ipO\", (duk_heaphdr *) env));\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t{\n\t\tduk_hobject *p = env;\n\t\twhile (p) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"  -> %!ipO\", (duk_heaphdr *) p));\n\t\t\tp = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, p);\n\t\t}\n\t}\n#endif\n\n\tact->lex_env = env;\n\tact->var_env = env;\n\tDUK_HOBJECT_INCREF(thr, env);  /* XXX: incref by count (here 2 times) */\n\tDUK_HOBJECT_INCREF(thr, env);\n\n\tduk_pop_unsafe(thr);\n}\n\n/*\n *  Closing environment records.\n *\n *  The environment record MUST be closed with the thread where its activation\n *  is; i.e. if 'env' is open, 'thr' must match env->thread, and the regbase\n *  and varmap must still be valid.  On entry, 'env' must be reachable.\n */\n\nDUK_INTERNAL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject *env) {\n\tduk_uint_fast32_t i;\n\tduk_hobject *varmap;\n\tduk_hstring *key;\n\tduk_tval *tv;\n\tduk_uint_t regnum;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL);\n\n\tif (DUK_UNLIKELY(!DUK_HOBJECT_IS_DECENV(env))) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"env not a declarative record: %!iO\", (duk_heaphdr *) env));\n\t\treturn;\n\t}\n\n\tvarmap = ((duk_hdecenv *) env)->varmap;\n\tif (varmap == NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"env already closed: %!iO\", (duk_heaphdr *) env));\n\n\t\treturn;\n\t}\n\tDUK_ASSERT(((duk_hdecenv *) env)->thread != NULL);\n\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env);\n\n\tDUK_DDD(DUK_DDDPRINT(\"closing env: %!iO\", (duk_heaphdr *) env));\n\tDUK_DDD(DUK_DDDPRINT(\"varmap: %!O\", (duk_heaphdr *) varmap));\n\n\t/* Env must be closed in the same thread as where it runs. */\n\tDUK_ASSERT(((duk_hdecenv *) env)->thread == thr);\n\n\t/* XXX: additional conditions when to close variables? we don't want to do it\n\t * unless the environment may have \"escaped\" (referenced in a function closure).\n\t * With delayed environments, the existence is probably good enough of a check.\n\t */\n\n\t/* Note: we rely on the _Varmap having a bunch of nice properties, like:\n\t *  - being compacted and unmodified during this process\n\t *  - not containing an array part\n\t *  - having correct value types\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"copying bound register values, %ld bound regs\", (long) DUK_HOBJECT_GET_ENEXT(varmap)));\n\n\t/* Copy over current variable values from value stack to the\n\t * environment record.  The scope object is empty but may\n\t * inherit from another scope which has conflicting names.\n\t */\n\n\t/* XXX: Do this using a once allocated entry area, no side effects.\n\t * Hash part would need special treatment however (maybe copy, and\n\t * then realloc with hash part if large enough).\n\t */\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(varmap); i++) {\n\t\tduk_size_t regbase_byteoff;\n\n\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, varmap, i);\n\t\tDUK_ASSERT(key != NULL);   /* assume keys are compact in _Varmap */\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, varmap, i));  /* assume plain values */\n\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, varmap, i);\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tDUK_ASSERT(DUK_TVAL_GET_NUMBER(tv) <= (duk_double_t) DUK_UINT32_MAX);  /* limits */\n#if defined(DUK_USE_FASTINT)\n\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\t\tregnum = (duk_uint_t) DUK_TVAL_GET_FASTINT_U32(tv);\n#else\n\t\tregnum = (duk_uint_t) DUK_TVAL_GET_NUMBER(tv);\n#endif\n\n\t\tregbase_byteoff = ((duk_hdecenv *) env)->regbase_byteoff;\n\t\tDUK_ASSERT((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum >= (duk_uint8_t *) thr->valstack);\n\t\tDUK_ASSERT((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum < (duk_uint8_t *) thr->valstack_top);\n\n\t\t/* Write register value into env as named properties.\n\t\t * If property already exists, overwrites silently.\n\t\t * Property is writable, but not deletable (not configurable\n\t\t * in terms of property attributes).\n\t\t *\n\t\t * This property write must not throw because we're unwinding\n\t\t * and unwind code is not allowed to throw at present.  The\n\t\t * call itself has no such guarantees, but we've preallocated\n\t\t * entries for each property when the env was created, so no\n\t\t * out-of-memory error should be possible.  If this guarantee\n\t\t * is not provided, problems like GH-476 may happen.\n\t\t */\n\t\tduk_push_tval(thr, (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum));\n\t\tDUK_DDD(DUK_DDDPRINT(\"closing identifier %!O -> reg %ld, value %!T\",\n\t\t                     (duk_heaphdr *) key,\n\t\t                     (long) regnum,\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\tduk_hobject_define_property_internal(thr, env, key, DUK_PROPDESC_FLAGS_WE);\n\t}\n\n\t/* NULL atomically to avoid inconsistent state + side effects. */\n\tDUK_HOBJECT_DECREF_NORZ(thr, ((duk_hdecenv *) env)->thread);\n\tDUK_HOBJECT_DECREF_NORZ(thr, ((duk_hdecenv *) env)->varmap);\n\t((duk_hdecenv *) env)->thread = NULL;\n\t((duk_hdecenv *) env)->varmap = NULL;\n\n\tDUK_DDD(DUK_DDDPRINT(\"env after closing: %!O\", (duk_heaphdr *) env));\n}\n\n/*\n *  GETIDREF: a GetIdentifierReference-like helper.\n *\n *  Provides a parent traversing lookup and a single level lookup\n *  (for HasBinding).\n *\n *  Instead of returning the value, returns a bunch of values allowing\n *  the caller to read, write, or delete the binding.  Value pointers\n *  are duk_tval pointers which can be mutated directly as long as\n *  refcounts are properly updated.  Note that any operation which may\n *  reallocate valstacks or compact objects may invalidate the returned\n *  duk_tval (but not object) pointers, so caller must be very careful.\n *\n *  If starting environment record 'env' is given, 'act' is ignored.\n *  However, if 'env' is NULL, the caller may identify, in 'act', an\n *  activation which hasn't had its declarative environment initialized\n *  yet.  The activation registers are then looked up, and its parent\n *  traversed normally.\n *\n *  The 'out' structure values are only valid if the function returns\n *  success (non-zero).\n */\n\n/* lookup name from an open declarative record's registers */\nDUK_LOCAL\nduk_bool_t duk__getid_open_decl_env_regs(duk_hthread *thr,\n                                         duk_hstring *name,\n                                         duk_hdecenv *env,\n                                         duk__id_lookup_result *out) {\n\tduk_tval *tv;\n\tduk_size_t reg_rel;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(out != NULL);\n\n\tDUK_ASSERT(DUK_HOBJECT_IS_DECENV((duk_hobject *) env));\n\tDUK_HDECENV_ASSERT_VALID(env);\n\n\tif (env->thread == NULL) {\n\t\t/* already closed */\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(env->varmap != NULL);\n\n\ttv = duk_hobject_find_entry_tval_ptr(thr->heap, env->varmap, name);\n\tif (DUK_UNLIKELY(tv == NULL)) {\n\t\treturn 0;\n\t}\n\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\tDUK_ASSERT(DUK_TVAL_GET_NUMBER(tv) <= (duk_double_t) DUK_UINT32_MAX);  /* limits */\n#if defined(DUK_USE_FASTINT)\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\treg_rel = (duk_size_t) DUK_TVAL_GET_FASTINT_U32(tv);\n#else\n\treg_rel = (duk_size_t) DUK_TVAL_GET_NUMBER(tv);\n#endif\n\tDUK_ASSERT_DISABLE(reg_rel >= 0);  /* unsigned */\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) env->thread->valstack + env->regbase_byteoff + sizeof(duk_tval) * reg_rel);\n\tDUK_ASSERT(tv >= env->thread->valstack && tv < env->thread->valstack_end);  /* XXX: more accurate? */\n\n\tout->value = tv;\n\tout->attrs = DUK_PROPDESC_FLAGS_W;  /* registers are mutable, non-deletable */\n\tout->env = (duk_hobject *) env;\n\tout->holder = NULL;\n\tout->has_this = 0;\n\treturn 1;\n}\n\n/* lookup name from current activation record's functions' registers */\nDUK_LOCAL\nduk_bool_t duk__getid_activation_regs(duk_hthread *thr,\n                                      duk_hstring *name,\n                                      duk_activation *act,\n                                      duk__id_lookup_result *out) {\n\tduk_tval *tv;\n\tduk_hobject *func;\n\tduk_hobject *varmap;\n\tduk_size_t reg_rel;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(out != NULL);\n\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func));\n\n\tif (!DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\treturn 0;\n\t}\n\n\t/* XXX: move varmap to duk_hcompfunc struct field? */\n\tvarmap = duk_hobject_get_varmap(thr, func);\n\tif (!varmap) {\n\t\treturn 0;\n\t}\n\n\ttv = duk_hobject_find_entry_tval_ptr(thr->heap, varmap, name);\n\tif (!tv) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\treg_rel = (duk_size_t) DUK_TVAL_GET_NUMBER(tv);\n\tDUK_ASSERT_DISABLE(reg_rel >= 0);\n\tDUK_ASSERT(reg_rel < ((duk_hcompfunc *) func)->nregs);\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff);\n\ttv += reg_rel;\n\n\tout->value = tv;\n\tout->attrs = DUK_PROPDESC_FLAGS_W;  /* registers are mutable, non-deletable */\n\tout->env = NULL;\n\tout->holder = NULL;\n\tout->has_this = 0;\n\treturn 1;\n}\n\nDUK_LOCAL\nduk_bool_t duk__get_identifier_reference(duk_hthread *thr,\n                                         duk_hobject *env,\n                                         duk_hstring *name,\n                                         duk_activation *act,\n                                         duk_bool_t parents,\n                                         duk__id_lookup_result *out) {\n\tduk_tval *tv;\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL || act != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(out != NULL);\n\n\tDUK_ASSERT(!env || DUK_HOBJECT_IS_ENV(env));\n\tDUK_ASSERT(!env || !DUK_HOBJECT_HAS_ARRAY_PART(env));\n\n\t/*\n\t *  Conceptually, we look for the identifier binding by starting from\n\t *  'env' and following to chain of environment records (represented\n\t *  by the prototype chain).\n\t *\n\t *  If 'env' is NULL, the current activation does not yet have an\n\t *  allocated declarative environment record; this should be treated\n\t *  exactly as if the environment record existed but had no bindings\n\t *  other than register bindings.\n\t *\n\t *  Note: we assume that with the DUK_HOBJECT_FLAG_NEWENV cleared\n\t *  the environment will always be initialized immediately; hence\n\t *  a NULL 'env' should only happen with the flag set.  This is the\n\t *  case for: (1) function calls, and (2) strict, direct eval calls.\n\t */\n\n\tif (env == NULL && act != NULL) {\n\t\tduk_hobject *func;\n\t\tduk_hcompfunc *f;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference: env is NULL, activation is non-NULL -> \"\n\t\t                     \"delayed env case, look up activation regs first\"));\n\n\t\t/*\n\t\t *  Try registers\n\t\t */\n\n\t\tif (duk__getid_activation_regs(thr, name, act, out)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t                     \"(found from register bindings when env=NULL)\",\n\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\treturn 1;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"not found in current activation regs\"));\n\n\t\t/*\n\t\t *  Not found in registers, proceed to the parent record.\n\t\t *  Here we need to determine what the parent would be,\n\t\t *  if 'env' was not NULL (i.e. same logic as when initializing\n\t\t *  the record).\n\t\t *\n\t\t *  Note that environment initialization is only deferred when\n\t\t *  DUK_HOBJECT_HAS_NEWENV is set, and this only happens for:\n\t\t *    - Function code\n\t\t *    - Strict eval code\n\t\t *\n\t\t *  We only need to check _Lexenv here; _Varenv exists only if it\n\t\t *  differs from _Lexenv (and thus _Lexenv will also be present).\n\t\t */\n\n\t\tif (!parents) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference failed, no parent traversal \"\n\t\t\t                     \"(not found from register bindings when env=NULL)\"));\n\t\t\tgoto fail_not_found;\n\t\t}\n\n\t\tfunc = DUK_ACT_GET_FUNC(act);\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func));\n\t\tf = (duk_hcompfunc *) func;\n\n\t\tenv = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f);\n\t\tif (!env) {\n\t\t\tenv = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"continue lookup from env: %!iO\",\n\t\t                     (duk_heaphdr *) env));\n\t}\n\n\t/*\n\t *  Prototype walking starting from 'env'.\n\t *\n\t *  ('act' is not needed anywhere here.)\n\t */\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\twhile (env != NULL) {\n\t\tduk_small_uint_t cl;\n\t\tduk_uint_t attrs;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference, name=%!O, considering env=%p -> %!iO\",\n\t\t                     (duk_heaphdr *) name,\n\t\t                     (void *) env,\n\t\t                     (duk_heaphdr *) env));\n\n\t\tDUK_ASSERT(env != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_ENV(env));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(env));\n\n\t\tcl = DUK_HOBJECT_GET_CLASS_NUMBER(env);\n\t\tDUK_ASSERT(cl == DUK_HOBJECT_CLASS_OBJENV || cl == DUK_HOBJECT_CLASS_DECENV);\n\t\tif (cl == DUK_HOBJECT_CLASS_DECENV) {\n\t\t\t/*\n\t\t\t *  Declarative environment record.\n\t\t\t *\n\t\t\t *  Identifiers can never be stored in ancestors and are\n\t\t\t *  always plain values, so we can use an internal helper\n\t\t\t *  and access the value directly with an duk_tval ptr.\n\t\t\t *\n\t\t\t *  A closed environment is only indicated by it missing\n\t\t\t *  the \"book-keeping\" properties required for accessing\n\t\t\t *  register-bound variables.\n\t\t\t */\n\n\t\t\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env);\n\t\t\tif (duk__getid_open_decl_env_regs(thr, name, (duk_hdecenv *) env, out)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t\t                     \"(declarative environment record, scope open, found in regs)\",\n\t\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\ttv = duk_hobject_find_entry_tval_ptr_and_attrs(thr->heap, env, name, &attrs);\n\t\t\tif (tv) {\n\t\t\t\tout->value = tv;\n\t\t\t\tout->attrs = attrs;\n\t\t\t\tout->env = env;\n\t\t\t\tout->holder = env;\n\t\t\t\tout->has_this = 0;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t\t                     \"(declarative environment record, found in properties)\",\n\t\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Object environment record.\n\t\t\t *\n\t\t\t *  Binding (target) object is an external, uncontrolled object.\n\t\t\t *  Identifier may be bound in an ancestor property, and may be\n\t\t\t *  an accessor.  Target can also be a Proxy which we must support\n\t\t\t *  here.\n\t\t\t */\n\n\t\t\t/* XXX: we could save space by using _Target OR _This.  If _Target, assume\n\t\t\t * this binding is undefined.  If _This, assumes this binding is _This, and\n\t\t\t * target is also _This.  One property would then be enough.\n\t\t\t */\n\n\t\t\tduk_hobject *target;\n\t\t\tduk_bool_t found;\n\n\t\t\tDUK_ASSERT(cl == DUK_HOBJECT_CLASS_OBJENV);\n\t\t\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) env);\n\n\t\t\ttarget = ((duk_hobjenv *) env)->target;\n\t\t\tDUK_ASSERT(target != NULL);\n\n\t\t\t/* Target may be a Proxy or property may be an accessor, so we must\n\t\t\t * use an actual, Proxy-aware hasprop check here.\n\t\t\t *\n\t\t\t * out->holder is NOT set to the actual duk_hobject where the\n\t\t\t * property is found, but rather the object binding target object.\n\t\t\t */\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(target))) {\n\t\t\t\tduk_tval tv_name;\n\t\t\t\tduk_tval tv_target_tmp;\n\n\t\t\t\tDUK_ASSERT(name != NULL);\n\t\t\t\tDUK_TVAL_SET_STRING(&tv_name, name);\n\t\t\t\tDUK_TVAL_SET_OBJECT(&tv_target_tmp, target);\n\n\t\t\t\tfound = duk_hobject_hasprop(thr, &tv_target_tmp, &tv_name);\n\t\t\t} else\n#endif  /* DUK_USE_ES6_PROXY */\n\t\t\t{\n\t\t\t\t/* XXX: duk_hobject_hasprop() would be correct for\n\t\t\t\t * non-Proxy objects too, but it is about ~20-25%\n\t\t\t\t * slower at present so separate code paths for\n\t\t\t\t * Proxy and non-Proxy now.\n\t\t\t\t */\n\t\t\t\tfound = duk_hobject_hasprop_raw(thr, target, name);\n\t\t\t}\n\n\t\t\tif (found) {\n\t\t\t\tout->value = NULL;  /* can't get value, may be accessor */\n\t\t\t\tout->attrs = 0;     /* irrelevant when out->value == NULL */\n\t\t\t\tout->env = env;\n\t\t\t\tout->holder = target;\n\t\t\t\tout->has_this = ((duk_hobjenv *) env)->has_this;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t\t                     \"(object environment record)\",\n\t\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\tif (!parents) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference failed, no parent traversal \"\n\t\t\t                     \"(not found from first traversed env)\"));\n\t\t\tgoto fail_not_found;\n\t\t}\n\n                if (DUK_UNLIKELY(sanity-- == 0)) {\n                        DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n                }\n\t\tenv = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, env);\n\t}\n\n\t/*\n\t *  Not found (even in global object)\n\t */\n\n fail_not_found:\n\treturn 0;\n}\n\n/*\n *  HASVAR: check identifier binding from a given environment record\n *  without traversing its parents.\n *\n *  This primitive is not exposed to user code as such, but is used\n *  internally for e.g. declaration binding instantiation.\n *\n *  See E5 Sections:\n *    10.2.1.1.1 HasBinding(N)\n *    10.2.1.2.1 HasBinding(N)\n *\n *  Note: strictness has no bearing on this check.  Hence we don't take\n *  a 'strict' parameter.\n */\n\n#if 0  /*unused*/\nDUK_INTERNAL\nduk_bool_t duk_js_hasvar_envrec(duk_hthread *thr,\n                                duk_hobject *env,\n                                duk_hstring *name) {\n\tduk__id_lookup_result ref;\n\tduk_bool_t parents;\n\n\tDUK_DDD(DUK_DDDPRINT(\"hasvar: thr=%p, env=%p, name=%!O \"\n\t                     \"(env -> %!dO)\",\n\t                     (void *) thr, (void *) env, (duk_heaphdr *) name,\n\t                     (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(name != NULL);\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\n\tDUK_ASSERT(DUK_HOBJECT_IS_ENV(env));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(env));\n\n\t/* lookup results is ignored */\n\tparents = 0;\n\treturn duk__get_identifier_reference(thr, env, name, NULL, parents, &ref);\n}\n#endif\n\n/*\n *  GETVAR\n *\n *  See E5 Sections:\n *    11.1.2 Identifier Reference\n *    10.3.1 Identifier Resolution\n *    11.13.1 Simple Assignment  [example of where the Reference is GetValue'd]\n *    8.7.1 GetValue (V)\n *    8.12.1 [[GetOwnProperty]] (P)\n *    8.12.2 [[GetProperty]] (P)\n *    8.12.3 [[Get]] (P)\n *\n *  If 'throw' is true, always leaves two values on top of stack: [val this].\n *\n *  If 'throw' is false, returns 0 if identifier cannot be resolved, and the\n *  stack will be unaffected in this case.  If identifier is resolved, returns\n *  1 and leaves [val this] on top of stack.\n *\n *  Note: the 'strict' flag of a reference returned by GetIdentifierReference\n *  is ignored by GetValue.  Hence we don't take a 'strict' parameter.\n *\n *  The 'throw' flag is needed for implementing 'typeof' for an unreferenced\n *  identifier.  An unreference identifier in other contexts generates a\n *  ReferenceError.\n */\n\nDUK_LOCAL\nduk_bool_t duk__getvar_helper(duk_hthread *thr,\n                              duk_hobject *env,\n                              duk_activation *act,\n                              duk_hstring *name,\n                              duk_bool_t throw_flag) {\n\tduk__id_lookup_result ref;\n\tduk_tval tv_tmp_obj;\n\tduk_tval tv_tmp_key;\n\tduk_bool_t parents;\n\n\tDUK_DDD(DUK_DDDPRINT(\"getvar: thr=%p, env=%p, act=%p, name=%!O \"\n\t                     \"(env -> %!dO)\",\n\t                     (void *) thr, (void *) env, (void *) act,\n\t                     (duk_heaphdr *) name, (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\t/* env and act may be NULL */\n\n\tDUK_STATS_INC(thr->heap, stats_getvar_all);\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\n\tparents = 1;     /* follow parent chain */\n\tif (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) {\n\t\tif (ref.value) {\n\t\t\tduk_push_tval(thr, ref.value);\n\t\t\tduk_push_undefined(thr);\n\t\t} else {\n\t\t\tDUK_ASSERT(ref.holder != NULL);\n\n\t\t\t/* ref.holder is safe across the getprop call (even\n\t\t\t * with side effects) because 'env' is reachable and\n\t\t\t * ref.holder is a direct heap pointer.\n\t\t\t */\n\n\t\t\tDUK_TVAL_SET_OBJECT(&tv_tmp_obj, ref.holder);\n\t\t\tDUK_TVAL_SET_STRING(&tv_tmp_key, name);\n\t\t\t(void) duk_hobject_getprop(thr, &tv_tmp_obj, &tv_tmp_key);  /* [value] */\n\n\t\t\tif (ref.has_this) {\n\t\t\t\tduk_push_hobject(thr, ref.holder);\n\t\t\t} else {\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t}\n\n\t\t\t/* [value this] */\n\t\t}\n\n\t\treturn 1;\n\t} else {\n\t\tif (throw_flag) {\n\t\t\tDUK_ERROR_FMT1(thr, DUK_ERR_REFERENCE_ERROR,\n\t\t\t               \"identifier '%s' undefined\",\n\t\t\t               (const char *) DUK_HSTRING_GET_DATA(name));\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\n\t\treturn 0;\n\t}\n}\n\nDUK_INTERNAL\nduk_bool_t duk_js_getvar_envrec(duk_hthread *thr,\n                                duk_hobject *env,\n                                duk_hstring *name,\n                                duk_bool_t throw_flag) {\n\treturn duk__getvar_helper(thr, env, NULL, name, throw_flag);\n}\n\nDUK_INTERNAL\nduk_bool_t duk_js_getvar_activation(duk_hthread *thr,\n                                    duk_activation *act,\n                                    duk_hstring *name,\n                                    duk_bool_t throw_flag) {\n\tDUK_ASSERT(act != NULL);\n\treturn duk__getvar_helper(thr, act->lex_env, act, name, throw_flag);\n}\n\n/*\n *  PUTVAR\n *\n *  See E5 Sections:\n *    11.1.2 Identifier Reference\n *    10.3.1 Identifier Resolution\n *    11.13.1 Simple Assignment  [example of where the Reference is PutValue'd]\n *    8.7.2 PutValue (V,W)  [see especially step 3.b, undefined -> automatic global in non-strict mode]\n *    8.12.4 [[CanPut]] (P)\n *    8.12.5 [[Put]] (P)\n *\n *  Note: may invalidate any valstack (or object) duk_tval pointers because\n *  putting a value may reallocate any object or any valstack.  Caller beware.\n */\n\nDUK_LOCAL\nvoid duk__putvar_helper(duk_hthread *thr,\n                        duk_hobject *env,\n                        duk_activation *act,\n                        duk_hstring *name,\n                        duk_tval *val,\n                        duk_bool_t strict) {\n\tduk__id_lookup_result ref;\n\tduk_tval tv_tmp_obj;\n\tduk_tval tv_tmp_key;\n\tduk_bool_t parents;\n\n\tDUK_STATS_INC(thr->heap, stats_putvar_all);\n\n\tDUK_DDD(DUK_DDDPRINT(\"putvar: thr=%p, env=%p, act=%p, name=%!O, val=%p, strict=%ld \"\n\t                     \"(env -> %!dO, val -> %!T)\",\n\t                     (void *) thr, (void *) env, (void *) act,\n\t                     (duk_heaphdr *) name, (void *) val, (long) strict,\n\t                     (duk_heaphdr *) env, (duk_tval *) val));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(val != NULL);\n\t/* env and act may be NULL */\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\tDUK_ASSERT_REFCOUNT_NONZERO_TVAL(val);\n\n\t/*\n\t *  In strict mode E5 protects 'eval' and 'arguments' from being\n\t *  assigned to (or even declared anywhere).  Attempt to do so\n\t *  should result in a compile time SyntaxError.  See the internal\n\t *  design documentation for details.\n\t *\n\t *  Thus, we should never come here, run-time, for strict code,\n\t *  and name 'eval' or 'arguments'.\n\t */\n\n\tDUK_ASSERT(!strict ||\n\t           (name != DUK_HTHREAD_STRING_EVAL(thr) &&\n\t            name != DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)));\n\n\t/*\n\t *  Lookup variable and update in-place if found.\n\t */\n\n\tparents = 1;     /* follow parent chain */\n\n\tif (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) {\n\t\tif (ref.value && (ref.attrs & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t/* Update duk_tval in-place if pointer provided and the\n\t\t\t * property is writable.  If the property is not writable\n\t\t\t * (immutable binding), use duk_hobject_putprop() which\n\t\t\t * will respect mutability.\n\t\t\t */\n\t\t\tduk_tval *tv_val;\n\n\t\t\ttv_val = ref.value;\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv_val, val);  /* side effects */\n\n\t\t\t/* ref.value invalidated here */\n\t\t} else {\n\t\t\tDUK_ASSERT(ref.holder != NULL);\n\n\t\t\tDUK_TVAL_SET_OBJECT(&tv_tmp_obj, ref.holder);\n\t\t\tDUK_TVAL_SET_STRING(&tv_tmp_key, name);\n\t\t\t(void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, strict);\n\n\t\t\t/* ref.value invalidated here */\n\t\t}\n\n\t\treturn;\n\t}\n\n\t/*\n\t *  Not found: write to global object (non-strict) or ReferenceError\n\t *  (strict); see E5 Section 8.7.2, step 3.\n\t */\n\n\tif (strict) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"identifier binding not found, strict => reference error\"));\n\t\tDUK_ERROR_FMT1(thr, DUK_ERR_REFERENCE_ERROR,\n\t\t               \"identifier '%s' undefined\",\n\t\t               (const char *) DUK_HSTRING_GET_DATA(name));\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"identifier binding not found, not strict => set to global\"));\n\n\tDUK_TVAL_SET_OBJECT(&tv_tmp_obj, thr->builtins[DUK_BIDX_GLOBAL]);\n\tDUK_TVAL_SET_STRING(&tv_tmp_key, name);\n\t(void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, 0);  /* 0 = no throw */\n\n\t/* NB: 'val' may be invalidated here because put_value may realloc valstack,\n\t * caller beware.\n\t */\n}\n\nDUK_INTERNAL\nvoid duk_js_putvar_envrec(duk_hthread *thr,\n                          duk_hobject *env,\n                          duk_hstring *name,\n                          duk_tval *val,\n                          duk_bool_t strict) {\n\tduk__putvar_helper(thr, env, NULL, name, val, strict);\n}\n\nDUK_INTERNAL\nvoid duk_js_putvar_activation(duk_hthread *thr,\n                              duk_activation *act,\n                              duk_hstring *name,\n                              duk_tval *val,\n                              duk_bool_t strict) {\n\tDUK_ASSERT(act != NULL);\n\tduk__putvar_helper(thr, act->lex_env, act, name, val, strict);\n}\n\n/*\n *  DELVAR\n *\n *  See E5 Sections:\n *    11.4.1 The delete operator\n *    10.2.1.1.5 DeleteBinding (N)  [declarative environment record]\n *    10.2.1.2.5 DeleteBinding (N)  [object environment record]\n *\n *  Variable bindings established inside eval() are deletable (configurable),\n *  other bindings are not, including variables declared in global level.\n *  Registers are always non-deletable, and the deletion of other bindings\n *  is controlled by the configurable flag.\n *\n *  For strict mode code, the 'delete' operator should fail with a compile\n *  time SyntaxError if applied to identifiers.  Hence, no strict mode\n *  run-time deletion of identifiers should ever happen.  This function\n *  should never be called from strict mode code!\n */\n\nDUK_LOCAL\nduk_bool_t duk__delvar_helper(duk_hthread *thr,\n                              duk_hobject *env,\n                              duk_activation *act,\n                              duk_hstring *name) {\n\tduk__id_lookup_result ref;\n\tduk_bool_t parents;\n\n\tDUK_DDD(DUK_DDDPRINT(\"delvar: thr=%p, env=%p, act=%p, name=%!O \"\n\t                     \"(env -> %!dO)\",\n\t                     (void *) thr, (void *) env, (void *) act,\n\t                     (duk_heaphdr *) name, (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\t/* env and act may be NULL */\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\n\tparents = 1;     /* follow parent chain */\n\n\tif (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) {\n\t\tif (ref.value && !(ref.attrs & DUK_PROPDESC_FLAG_CONFIGURABLE)) {\n\t\t\t/* Identifier found in registers (always non-deletable)\n\t\t\t * or declarative environment record and non-configurable.\n\t\t\t */\n\t\t\treturn 0;\n\t\t}\n\t\tDUK_ASSERT(ref.holder != NULL);\n\n\t\treturn duk_hobject_delprop_raw(thr, ref.holder, name, 0);\n\t}\n\n\t/*\n\t *  Not found (even in global object).\n\t *\n\t *  In non-strict mode this is a silent SUCCESS (!), see E5 Section 11.4.1,\n\t *  step 3.b.  In strict mode this case is a compile time SyntaxError so\n\t *  we should not come here.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"identifier to be deleted not found: name=%!O \"\n\t                     \"(treated as silent success)\",\n\t                     (duk_heaphdr *) name));\n\treturn 1;\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL\nduk_bool_t duk_js_delvar_envrec(duk_hthread *thr,\n                                duk_hobject *env,\n                                duk_hstring *name) {\n\treturn duk__delvar_helper(thr, env, NULL, name);\n}\n#endif\n\nDUK_INTERNAL\nduk_bool_t duk_js_delvar_activation(duk_hthread *thr,\n                                    duk_activation *act,\n                                    duk_hstring *name) {\n\tDUK_ASSERT(act != NULL);\n\treturn duk__delvar_helper(thr, act->lex_env, act, name);\n}\n\n/*\n *  DECLVAR\n *\n *  See E5 Sections:\n *    10.4.3 Entering Function Code\n *    10.5 Declaration Binding Instantion\n *    12.2 Variable Statement\n *    11.1.2 Identifier Reference\n *    10.3.1 Identifier Resolution\n *\n *  Variable declaration behavior is mainly discussed in Section 10.5,\n *  and is not discussed in the execution semantics (Sections 11-13).\n *\n *  Conceptually declarations happen when code (global, eval, function)\n *  is entered, before any user code is executed.  In practice, register-\n *  bound identifiers are 'declared' automatically (by virtue of being\n *  allocated to registers with the initial value 'undefined').  Other\n *  identifiers are declared in the function prologue with this primitive.\n *\n *  Since non-register bindings eventually back to an internal object's\n *  properties, the 'prop_flags' argument is used to specify binding\n *  type:\n *\n *    - Immutable binding: set DUK_PROPDESC_FLAG_WRITABLE to false\n *    - Non-deletable binding: set DUK_PROPDESC_FLAG_CONFIGURABLE to false\n *    - The flag DUK_PROPDESC_FLAG_ENUMERABLE should be set, although it\n *      doesn't really matter for internal objects\n *\n *  All bindings are non-deletable mutable bindings except:\n *\n *    - Declarations in eval code (mutable, deletable)\n *    - 'arguments' binding in strict function code (immutable)\n *    - Function name binding of a function expression (immutable)\n *\n *  Declarations may go to declarative environment records (always\n *  so for functions), but may also go to object environment records\n *  (e.g. global code).  The global object environment has special\n *  behavior when re-declaring a function (but not a variable); see\n *  E5.1 specification, Section 10.5, step 5.e.\n *\n *  Declarations always go to the 'top-most' environment record, i.e.\n *  we never check the record chain.  It's not an error even if a\n *  property (even an immutable or non-deletable one) of the same name\n *  already exists.\n *\n *  If a declared variable already exists, its value needs to be updated\n *  (if possible).  Returns 1 if a PUTVAR needs to be done by the caller;\n *  otherwise returns 0.\n */\n\nDUK_LOCAL\nduk_bool_t duk__declvar_helper(duk_hthread *thr,\n                               duk_hobject *env,\n                               duk_hstring *name,\n                               duk_tval *val,\n                               duk_small_uint_t prop_flags,\n                               duk_bool_t is_func_decl) {\n\tduk_hobject *holder;\n\tduk_bool_t parents;\n\tduk__id_lookup_result ref;\n\tduk_tval *tv;\n\n\tDUK_DDD(DUK_DDDPRINT(\"declvar: thr=%p, env=%p, name=%!O, val=%!T, prop_flags=0x%08lx, is_func_decl=%ld \"\n\t                     \"(env -> %!iO)\",\n\t                     (void *) thr, (void *) env, (duk_heaphdr *) name,\n\t                     (duk_tval *) val, (unsigned long) prop_flags,\n\t                     (unsigned int) is_func_decl, (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(val != NULL);\n\n\t/* Note: in strict mode the compiler should reject explicit\n\t * declaration of 'eval' or 'arguments'.  However, internal\n\t * bytecode may declare 'arguments' in the function prologue.\n\t * We don't bother checking (or asserting) for these now.\n\t */\n\n\t/* Note: val is a stable duk_tval pointer.  The caller makes\n\t * a value copy into its stack frame, so 'tv_val' is not subject\n\t * to side effects here.\n\t */\n\n\t/*\n\t *  Check whether already declared.\n\t *\n\t *  We need to check whether the binding exists in the environment\n\t *  without walking its parents.  However, we still need to check\n\t *  register-bound identifiers and the prototype chain of an object\n\t *  environment target object.\n\t */\n\n\tparents = 0;  /* just check 'env' */\n\tif (duk__get_identifier_reference(thr, env, name, NULL, parents, &ref)) {\n\t\tduk_int_t e_idx;\n\t\tduk_int_t h_idx;\n\t\tduk_small_uint_t flags;\n\n\t\t/*\n\t\t *  Variable already declared, ignore re-declaration.\n\t\t *  The only exception is the updated behavior of E5.1 for\n\t\t *  global function declarations, E5.1 Section 10.5, step 5.e.\n\t\t *  This behavior does not apply to global variable declarations.\n\t\t */\n\n\t\tif (!(is_func_decl && env == thr->builtins[DUK_BIDX_GLOBAL_ENV])) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"re-declare a binding, ignoring\"));\n\t\t\treturn 1;  /* 1 -> needs a PUTVAR */\n\t\t}\n\n\t\t/*\n\t\t *  Special behavior in E5.1.\n\t\t *\n\t\t *  Note that even though parents == 0, the conflicting property\n\t\t *  may be an inherited property (currently our global object's\n\t\t *  prototype is Object.prototype).  Step 5.e first operates on\n\t\t *  the existing property (which is potentially in an ancestor)\n\t\t *  and then defines a new property in the global object (and\n\t\t *  never modifies the ancestor).\n\t\t *\n\t\t *  Also note that this logic would become even more complicated\n\t\t *  if the conflicting property might be a virtual one.  Object\n\t\t *  prototype has no virtual properties, though.\n\t\t *\n\t\t *  XXX: this is now very awkward, rework.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"re-declare a function binding in global object, \"\n\t\t                     \"updated E5.1 processing\"));\n\n\t\tDUK_ASSERT(ref.holder != NULL);\n\t\tholder = ref.holder;\n\n\t\t/* holder will be set to the target object, not the actual object\n\t\t * where the property was found (see duk__get_identifier_reference()).\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(holder) == DUK_HOBJECT_CLASS_GLOBAL);\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(holder));  /* global object doesn't have array part */\n\n\t\t/* XXX: use a helper for prototype traversal; no loop check here */\n\t\t/* must be found: was found earlier, and cannot be inherited */\n\t\tfor (;;) {\n\t\t\tDUK_ASSERT(holder != NULL);\n\t\t\tif (duk_hobject_find_entry(thr->heap, holder, name, &e_idx, &h_idx)) {\n\t\t\t\tDUK_ASSERT(e_idx >= 0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t/* SCANBUILD: NULL pointer dereference, doesn't actually trigger,\n\t\t\t * asserted above.\n\t\t\t */\n\t\t\tholder = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, holder);\n\t\t}\n\t\tDUK_ASSERT(holder != NULL);\n\t\tDUK_ASSERT(e_idx >= 0);\n\t\t/* SCANBUILD: scan-build produces a NULL pointer dereference warning\n\t\t * below; it never actually triggers because holder is actually never\n\t\t * NULL.\n\t\t */\n\n\t\t/* ref.holder is global object, holder is the object with the\n\t\t * conflicting property.\n\t\t */\n\n\t\tflags = DUK_HOBJECT_E_GET_FLAGS(thr->heap, holder, e_idx);\n\t\tif (!(flags & DUK_PROPDESC_FLAG_CONFIGURABLE)) {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"existing property is a non-configurable \"\n\t\t\t\t                     \"accessor -> reject\"));\n\t\t\t\tgoto fail_existing_attributes;\n\t\t\t}\n\t\t\tif (!((flags & DUK_PROPDESC_FLAG_WRITABLE) &&\n\t\t\t      (flags & DUK_PROPDESC_FLAG_ENUMERABLE))) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"existing property is a non-configurable \"\n\t\t\t\t                     \"plain property which is not writable and \"\n\t\t\t\t                     \"enumerable -> reject\"));\n\t\t\t\tgoto fail_existing_attributes;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"existing property is not configurable but \"\n\t\t\t                     \"is plain, enumerable, and writable -> \"\n\t\t\t                     \"allow redeclaration\"));\n\t\t}\n\n\t\tif (holder == ref.holder) {\n\t\t\t/* XXX: if duk_hobject_define_property_internal() was updated\n\t\t\t * to handle a pre-existing accessor property, this would be\n\t\t\t * a simple call (like for the ancestor case).\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"redefine, offending property in global object itself\"));\n\n\t\t\tif (flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t\tduk_hobject *tmp;\n\n\t\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, holder, e_idx);\n\t\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, holder, e_idx, NULL);\n\t\t\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);\n\t\t\t\tDUK_UNREF(tmp);\n\t\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, holder, e_idx);\n\t\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, holder, e_idx, NULL);\n\t\t\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);\n\t\t\t\tDUK_UNREF(tmp);\n\t\t\t} else {\n\t\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx);\n\t\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);\n\t\t\t}\n\n\t\t\t/* Here val would be potentially invalid if we didn't make\n\t\t\t * a value copy at the caller.\n\t\t\t */\n\n\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx);\n\t\t\tDUK_TVAL_SET_TVAL(tv, val);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, holder, e_idx, prop_flags);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"updated global binding, final result: \"\n\t\t\t                     \"value -> %!T, prop_flags=0x%08lx\",\n\t\t\t                     (duk_tval *) DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx),\n\t\t\t                     (unsigned long) prop_flags));\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"redefine, offending property in ancestor\"));\n\n\t\t\tDUK_ASSERT(ref.holder == thr->builtins[DUK_BIDX_GLOBAL]);\n\t\t\tduk_push_tval(thr, val);\n\t\t\tduk_hobject_define_property_internal(thr, ref.holder, name, prop_flags);\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  Not found (in registers or record objects).  Declare\n\t *  to current variable environment.\n\t */\n\n\t/*\n\t *  Get holder object\n\t */\n\n\tif (DUK_HOBJECT_IS_DECENV(env)) {\n\t\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env);\n\t\tholder = env;\n\t} else {\n\t\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) env);\n\t\tholder = ((duk_hobjenv *) env)->target;\n\t\tDUK_ASSERT(holder != NULL);\n\t}\n\n\t/*\n\t *  Define new property\n\t *\n\t *  Note: this may fail if the holder is not extensible.\n\t */\n\n\t/* XXX: this is awkward as we use an internal method which doesn't handle\n\t * extensibility etc correctly.  Basically we'd want to do a [[DefineOwnProperty]]\n\t * or Object.defineProperty() here.\n\t */\n\n\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(holder)) {\n\t\tgoto fail_not_extensible;\n\t}\n\n\tduk_push_hobject(thr, holder);\n\tduk_push_hstring(thr, name);\n\tduk_push_tval(thr, val);\n\tduk_xdef_prop(thr, -3, prop_flags);  /* [holder name val] -> [holder] */\n\tduk_pop_unsafe(thr);\n\n\treturn 0;\n\n fail_existing_attributes:\n fail_not_extensible:\n\tDUK_ERROR_TYPE(thr, \"declaration failed\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL\nduk_bool_t duk_js_declvar_activation(duk_hthread *thr,\n                                     duk_activation *act,\n                                     duk_hstring *name,\n                                     duk_tval *val,\n                                     duk_small_uint_t prop_flags,\n                                     duk_bool_t is_func_decl) {\n\tduk_hobject *env;\n\tduk_tval tv_val_copy;\n\n\tDUK_ASSERT(act != NULL);\n\n\t/*\n\t *  Make a value copy of the input val.  This ensures that\n\t *  side effects cannot invalidate the pointer.\n\t */\n\n\tDUK_TVAL_SET_TVAL(&tv_val_copy, val);\n\tval = &tv_val_copy;\n\n\t/*\n\t *  Delayed env creation check\n\t */\n\n\tif (!act->var_env) {\n\t\tDUK_ASSERT(act->lex_env == NULL);\n\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\t/* 'act' is a stable pointer, so still OK. */\n\t}\n\tDUK_ASSERT(act->lex_env != NULL);\n\tDUK_ASSERT(act->var_env != NULL);\n\n\tenv = act->var_env;\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_ENV(env));\n\n\treturn duk__declvar_helper(thr, env, name, val, prop_flags, is_func_decl);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_json.h",
    "content": "/*\n *  Defines for JSON, especially duk_bi_json.c.\n */\n\n#if !defined(DUK_JSON_H_INCLUDED)\n#define DUK_JSON_H_INCLUDED\n\n/* Encoding/decoding flags */\n#define DUK_JSON_FLAG_ASCII_ONLY              (1U << 0)  /* escape any non-ASCII characters */\n#define DUK_JSON_FLAG_AVOID_KEY_QUOTES        (1U << 1)  /* avoid key quotes when key is an ASCII Identifier */\n#define DUK_JSON_FLAG_EXT_CUSTOM              (1U << 2)  /* extended types: custom encoding */\n#define DUK_JSON_FLAG_EXT_COMPATIBLE          (1U << 3)  /* extended types: compatible encoding */\n\n/* How much stack to require on entry to object/array encode */\n#define DUK_JSON_ENC_REQSTACK                 32\n\n/* How much stack to require on entry to object/array decode */\n#define DUK_JSON_DEC_REQSTACK                 32\n\n/* How large a loop detection stack to use */\n#define DUK_JSON_ENC_LOOPARRAY                64\n\n/* Encoding state.  Heap object references are all borrowed. */\ntypedef struct {\n\tduk_hthread *thr;\n\tduk_bufwriter_ctx bw;        /* output bufwriter */\n\tduk_hobject *h_replacer;     /* replacer function */\n\tduk_hstring *h_gap;          /* gap (if empty string, NULL) */\n\tduk_idx_t idx_proplist;      /* explicit PropertyList */\n\tduk_idx_t idx_loop;          /* valstack index of loop detection object */\n\tduk_small_uint_t flags;\n\tduk_small_uint_t flag_ascii_only;\n\tduk_small_uint_t flag_avoid_key_quotes;\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tduk_small_uint_t flag_ext_custom;\n\tduk_small_uint_t flag_ext_compatible;\n\tduk_small_uint_t flag_ext_custom_or_compatible;\n#endif\n\tduk_uint_t recursion_depth;\n\tduk_uint_t recursion_limit;\n\tduk_uint_t mask_for_undefined;      /* type bit mask: types which certainly produce 'undefined' */\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tduk_small_uint_t stridx_custom_undefined;\n\tduk_small_uint_t stridx_custom_nan;\n\tduk_small_uint_t stridx_custom_neginf;\n\tduk_small_uint_t stridx_custom_posinf;\n\tduk_small_uint_t stridx_custom_function;\n#endif\n\tduk_hobject *visiting[DUK_JSON_ENC_LOOPARRAY];  /* indexed by recursion_depth */\n} duk_json_enc_ctx;\n\ntypedef struct {\n\tduk_hthread *thr;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p_end;\n\tduk_idx_t idx_reviver;\n\tduk_small_uint_t flags;\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tduk_small_uint_t flag_ext_custom;\n\tduk_small_uint_t flag_ext_compatible;\n\tduk_small_uint_t flag_ext_custom_or_compatible;\n#endif\n\tduk_int_t recursion_depth;\n\tduk_int_t recursion_limit;\n} duk_json_dec_ctx;\n\n#endif  /* DUK_JSON_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_lexer.c",
    "content": "/*\n *  Lexer for source files, ToNumber() string conversions, RegExp expressions,\n *  and JSON.\n *\n *  Provides a stream of ECMAScript tokens from an UTF-8/CESU-8 buffer.  The\n *  caller can also rewind the token stream into a certain position which is\n *  needed by the compiler part for multi-pass scanning.  Tokens are\n *  represented as duk_token structures, and contain line number information.\n *  Token types are identified with DUK_TOK_* defines.\n *\n *  Characters are decoded into a fixed size lookup window consisting of\n *  decoded Unicode code points, with window positions past the end of the\n *  input filled with an invalid codepoint (-1).  The tokenizer can thus\n *  perform multiple character lookups efficiently and with few sanity\n *  checks (such as access outside the end of the input), which keeps the\n *  tokenization code small at the cost of performance.\n *\n *  Character data in tokens, such as identifier names and string literals,\n *  is encoded into CESU-8 format on-the-fly while parsing the token in\n *  question.  The string data is made reachable to garbage collection by\n *  placing the token-related values in value stack entries allocated for\n *  this purpose by the caller.  The characters exist in Unicode code point\n *  form only in the fixed size lookup window, which keeps character data\n *  expansion (of especially ASCII data) low.\n *\n *  Token parsing supports the full range of Unicode characters as described\n *  in the E5 specification.  Parsing has been optimized for ASCII characters\n *  because ordinary ECMAScript code consists almost entirely of ASCII\n *  characters.  Matching of complex Unicode codepoint sets (such as in the\n *  IdentifierStart and IdentifierPart productions) is optimized for size,\n *  and is done using a linear scan of a bit-packed list of ranges.  This is\n *  very slow, but should never be entered unless the source code actually\n *  contains Unicode characters.\n *\n *  ECMAScript tokenization is partially context sensitive.  First,\n *  additional future reserved words are recognized in strict mode (see E5\n *  Section 7.6.1.2).  Second, a forward slash character ('/') can be\n *  recognized either as starting a RegExp literal or as a division operator,\n *  depending on context.  The caller must provide necessary context flags\n *  when requesting a new token.\n *\n *  Future work:\n *\n *    * Make line number tracking optional, as it consumes space.\n *\n *    * Add a feature flag for disabling UTF-8 decoding of input, as most\n *      source code is ASCII.  Because of Unicode escapes written in ASCII,\n *      this does not allow Unicode support to be removed from e.g.\n *      duk_unicode_is_identifier_start() nor does it allow removal of CESU-8\n *      encoding of e.g. string literals.\n *\n *    * Add a feature flag for disabling Unicode compliance of e.g. identifier\n *      names.  This allows for a build more than a kilobyte smaller, because\n *      Unicode ranges needed by duk_unicode_is_identifier_start() and\n *      duk_unicode_is_identifier_part() can be dropped.  String literals\n *      should still be allowed to contain escaped Unicode, so this still does\n *      not allow removal of CESU-8 encoding of e.g. string literals.\n *\n *    * Character lookup tables for codepoints above BMP could be stripped.\n *\n *    * Strictly speaking, E5 specification requires that source code consists\n *      of 16-bit code units, and if not, must be conceptually converted to\n *      that format first.  The current lexer processes Unicode code points\n *      and allows characters outside the BMP.  These should be converted to\n *      surrogate pairs while reading the source characters into the window,\n *      not after tokens have been formed (as is done now).  However, the fix\n *      is not trivial because two characters are decoded from one codepoint.\n *\n *    * Optimize for speed as well as size.  Large if-else ladders are (at\n *      least potentially) slow.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Various defines and file specific helper macros\n */\n\n#define DUK__MAX_RE_DECESC_DIGITS     9\n#define DUK__MAX_RE_QUANT_DIGITS      9   /* Does not allow e.g. 2**31-1, but one more would allow overflows of u32. */\n\n/* whether to use macros or helper function depends on call count */\n#define DUK__ISDIGIT(x)          ((x) >= DUK_ASC_0 && (x) <= DUK_ASC_9)\n#define DUK__ISHEXDIGIT(x)       duk__is_hex_digit((x))\n#define DUK__ISOCTDIGIT(x)       ((x) >= DUK_ASC_0 && (x) <= DUK_ASC_7)\n#define DUK__ISDIGIT03(x)        ((x) >= DUK_ASC_0 && (x) <= DUK_ASC_3)\n#define DUK__ISDIGIT47(x)        ((x) >= DUK_ASC_4 && (x) <= DUK_ASC_7)\n\n/* lexer character window helpers */\n#define DUK__LOOKUP(lex_ctx,idx)            ((lex_ctx)->window[(idx)].codepoint)\n#define DUK__ADVANCECHARS(lex_ctx,count)    duk__advance_chars((lex_ctx), (count))\n#define DUK__ADVANCEBYTES(lex_ctx,count)    duk__advance_bytes((lex_ctx), (count))\n#define DUK__INITBUFFER(lex_ctx)            duk__initbuffer((lex_ctx))\n#define DUK__APPENDBUFFER(lex_ctx,x)        duk__appendbuffer((lex_ctx), (duk_codepoint_t) (x))\n#define DUK__APPENDBUFFER_ASCII(lex_ctx,x)  duk__appendbuffer_ascii((lex_ctx), (duk_codepoint_t) (x))\n\n/* lookup shorthands (note: assume context variable is named 'lex_ctx') */\n#define DUK__L0()  DUK__LOOKUP(lex_ctx, 0)\n#define DUK__L1()  DUK__LOOKUP(lex_ctx, 1)\n#define DUK__L2()  DUK__LOOKUP(lex_ctx, 2)\n#define DUK__L3()  DUK__LOOKUP(lex_ctx, 3)\n#define DUK__L4()  DUK__LOOKUP(lex_ctx, 4)\n#define DUK__L5()  DUK__LOOKUP(lex_ctx, 5)\n\n/* packed advance/token number macro used by multiple functions */\n#define DUK__ADVTOK(advbytes,tok)  ((((advbytes) * sizeof(duk_lexer_codepoint)) << 8) + (tok))\n\n/*\n *  Advance lookup window by N characters, filling in new characters as\n *  necessary.  After returning caller is guaranteed a character window of\n *  at least DUK_LEXER_WINDOW_SIZE characters.\n *\n *  The main function duk__advance_bytes() is called at least once per every\n *  token so it has a major lexer/compiler performance impact.  There are two\n *  variants for the main duk__advance_bytes() algorithm: a sliding window\n *  approach which is slightly faster at the cost of larger code footprint,\n *  and a simple copying one.\n *\n *  Decoding directly from the source string would be another lexing option.\n *  But the lookup window based approach has the advantage of hiding the\n *  source string and its encoding effectively which gives more flexibility\n *  going forward to e.g. support chunked streaming of source from flash.\n *\n *  Decodes UTF-8/CESU-8 leniently with support for code points from U+0000 to\n *  U+10FFFF, causing an error if the input is unparseable.  Leniency means:\n *\n *    * Unicode code point validation is intentionally not performed,\n *      except to check that the codepoint does not exceed 0x10ffff.\n *\n *    * In particular, surrogate pairs are allowed and not combined, which\n *      allows source files to represent all SourceCharacters with CESU-8.\n *      Broken surrogate pairs are allowed, as ECMAScript does not mandate\n *      their validation.\n *\n *    * Allow non-shortest UTF-8 encodings.\n *\n *  Leniency here causes few security concerns because all character data is\n *  decoded into Unicode codepoints before lexer processing, and is then\n *  re-encoded into CESU-8.  The source can be parsed as strict UTF-8 with\n *  a compiler option.  However, ECMAScript source characters include -all-\n *  16-bit unsigned integer codepoints, so leniency seems to be appropriate.\n *\n *  Note that codepoints above the BMP are not strictly SourceCharacters,\n *  but the lexer still accepts them as such.  Before ending up in a string\n *  or an identifier name, codepoints above BMP are converted into surrogate\n *  pairs and then CESU-8 encoded, resulting in 16-bit Unicode data as\n *  expected by ECMAScript.\n *\n *  An alternative approach to dealing with invalid or partial sequences\n *  would be to skip them and replace them with e.g. the Unicode replacement\n *  character U+FFFD.  This has limited utility because a replacement character\n *  will most likely cause a parse error, unless it occurs inside a string.\n *  Further, ECMAScript source is typically pure ASCII.\n *\n *  See:\n *\n *     http://en.wikipedia.org/wiki/UTF-8\n *     http://en.wikipedia.org/wiki/CESU-8\n *     http://tools.ietf.org/html/rfc3629\n *     http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences\n *\n *  Future work:\n *\n *    * Reject other invalid Unicode sequences (see Wikipedia entry for examples)\n *      in strict UTF-8 mode.\n *\n *    * Size optimize.  An attempt to use a 16-byte lookup table for the first\n *      byte resulted in a code increase though.\n *\n *    * Is checking against maximum 0x10ffff really useful?  4-byte encoding\n *      imposes a certain limit anyway.\n *\n *    * Support chunked streaming of source code.  Can be implemented either\n *      by streaming chunks of bytes or chunks of codepoints.\n */\n\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\nDUK_LOCAL void duk__fill_lexer_buffer(duk_lexer_ctx *lex_ctx, duk_small_uint_t start_offset_bytes) {\n\tduk_lexer_codepoint *cp, *cp_end;\n\tduk_ucodepoint_t x;\n\tduk_small_uint_t contlen;\n\tconst duk_uint8_t *p, *p_end;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\tduk_ucodepoint_t mincp;\n#endif\n\tduk_int_t input_line;\n\n\t/* Use temporaries and update lex_ctx only when finished. */\n\tinput_line = lex_ctx->input_line;\n\tp = lex_ctx->input + lex_ctx->input_offset;\n\tp_end = lex_ctx->input + lex_ctx->input_length;\n\n\tcp = (duk_lexer_codepoint *) (void *) ((duk_uint8_t *) lex_ctx->buffer + start_offset_bytes);\n\tcp_end = lex_ctx->buffer + DUK_LEXER_BUFFER_SIZE;\n\n\tfor (; cp != cp_end; cp++) {\n\t\tcp->offset = (duk_size_t) (p - lex_ctx->input);\n\t\tcp->line = input_line;\n\n\t\t/* XXX: potential issue with signed pointers, p_end < p. */\n\t\tif (DUK_UNLIKELY(p >= p_end)) {\n\t\t\t/* If input_offset were assigned a negative value, it would\n\t\t\t * result in a large positive value.  Most likely it would be\n\t\t\t * larger than input_length and be caught here.  In any case\n\t\t\t * no memory unsafe behavior would happen.\n\t\t\t */\n\t\t\tcp->codepoint = -1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tx = (duk_ucodepoint_t) (*p++);\n\n\t\t/* Fast path. */\n\n\t\tif (DUK_LIKELY(x < 0x80UL)) {\n\t\t\tDUK_ASSERT(x != 0x2028UL && x != 0x2029UL);  /* not LS/PS */\n\t\t\tif (DUK_UNLIKELY(x <= 0x000dUL)) {\n\t\t\t\tif ((x == 0x000aUL) ||\n\t\t\t\t    ((x == 0x000dUL) && (p >= p_end || *p != 0x000aUL))) {\n\t\t\t\t\t/* lookup for 0x000a above assumes shortest encoding now */\n\n\t\t\t\t\t/* E5 Section 7.3, treat the following as newlines:\n\t\t\t\t\t *   LF\n\t\t\t\t\t *   CR [not followed by LF]\n\t\t\t\t\t *   LS\n\t\t\t\t\t *   PS\n\t\t\t\t\t *\n\t\t\t\t\t * For CR LF, CR is ignored if it is followed by LF, and the LF will bump\n\t\t\t\t\t * the line number.\n\t\t\t\t\t */\n\t\t\t\t\tinput_line++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcp->codepoint = (duk_codepoint_t) x;\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Slow path. */\n\n\t\tif (x < 0xc0UL) {\n\t\t\t/* 10xx xxxx -> invalid */\n\t\t\tgoto error_encoding;\n\t\t} else if (x < 0xe0UL) {\n\t\t\t/* 110x xxxx   10xx xxxx  */\n\t\t\tcontlen = 1;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\t\tmincp = 0x80UL;\n#endif\n\t\t\tx = x & 0x1fUL;\n\t\t} else if (x < 0xf0UL) {\n\t\t\t/* 1110 xxxx   10xx xxxx   10xx xxxx */\n\t\t\tcontlen = 2;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\t\tmincp = 0x800UL;\n#endif\n\t\t\tx = x & 0x0fUL;\n\t\t} else if (x < 0xf8UL) {\n\t\t\t/* 1111 0xxx   10xx xxxx   10xx xxxx   10xx xxxx */\n\t\t\tcontlen = 3;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\t\tmincp = 0x10000UL;\n#endif\n\t\t\tx = x & 0x07UL;\n\t\t} else {\n\t\t\t/* no point in supporting encodings of 5 or more bytes */\n\t\t\tgoto error_encoding;\n\t\t}\n\n\t\tDUK_ASSERT(p_end >= p);\n\t\tif ((duk_size_t) contlen > (duk_size_t) (p_end - p)) {\n\t\t\tgoto error_clipped;\n\t\t}\n\n\t\twhile (contlen > 0) {\n\t\t\tduk_small_uint_t y;\n\t\t\ty = *p++;\n\t\t\tif ((y & 0xc0U) != 0x80U) {\n\t\t\t\t/* check that byte has the form 10xx xxxx */\n\t\t\t\tgoto error_encoding;\n\t\t\t}\n\t\t\tx = x << 6;\n\t\t\tx += y & 0x3fUL;\n\t\t\tcontlen--;\n\t\t}\n\n\t\t/* check final character validity */\n\n\t\tif (x > 0x10ffffUL) {\n\t\t\tgoto error_encoding;\n\t\t}\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tif (x < mincp || (x >= 0xd800UL && x <= 0xdfffUL) || x == 0xfffeUL) {\n\t\t\tgoto error_encoding;\n\t\t}\n#endif\n\n\t\tDUK_ASSERT(x != 0x000aUL && x != 0x000dUL);\n\t\tif ((x == 0x2028UL) || (x == 0x2029UL)) {\n\t\t\tinput_line++;\n\t\t}\n\n\t\tcp->codepoint = (duk_codepoint_t) x;\n\t}\n\n\tlex_ctx->input_offset = (duk_size_t) (p - lex_ctx->input);\n\tlex_ctx->input_line = input_line;\n\treturn;\n\n error_clipped:   /* clipped codepoint */\n error_encoding:  /* invalid codepoint encoding or codepoint */\n\tlex_ctx->input_offset = (duk_size_t) (p - lex_ctx->input);\n\tlex_ctx->input_line = input_line;\n\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_SOURCE_DECODE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__advance_bytes(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_bytes) {\n\tduk_small_uint_t used_bytes, avail_bytes;\n\n\tDUK_ASSERT_DISABLE(count_bytes >= 0);  /* unsigned */\n\tDUK_ASSERT(count_bytes <= (duk_small_uint_t) (DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint)));\n\tDUK_ASSERT(lex_ctx->window >= lex_ctx->buffer);\n\tDUK_ASSERT(lex_ctx->window < lex_ctx->buffer + DUK_LEXER_BUFFER_SIZE);\n\tDUK_ASSERT((duk_uint8_t *) lex_ctx->window + count_bytes <= (duk_uint8_t *) lex_ctx->buffer + DUK_LEXER_BUFFER_SIZE * sizeof(duk_lexer_codepoint));\n\n\t/* Zero 'count' is also allowed to make call sites easier.\n\t * Arithmetic in bytes generates better code in GCC.\n\t */\n\n\tlex_ctx->window = (duk_lexer_codepoint *) (void *) ((duk_uint8_t *) lex_ctx->window + count_bytes);  /* avoid multiply */\n\tused_bytes = (duk_small_uint_t) ((duk_uint8_t *) lex_ctx->window - (duk_uint8_t *) lex_ctx->buffer);\n\tavail_bytes = DUK_LEXER_BUFFER_SIZE * sizeof(duk_lexer_codepoint) - used_bytes;\n\tif (avail_bytes < (duk_small_uint_t) (DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint))) {\n\t\t/* Not enough data to provide a full window, so \"scroll\" window to\n\t\t * start of buffer and fill up the rest.\n\t\t */\n\t\tduk_memmove((void *) lex_ctx->buffer,\n\t\t            (const void *) lex_ctx->window,\n\t\t            (size_t) avail_bytes);\n\t\tlex_ctx->window = lex_ctx->buffer;\n\t\tduk__fill_lexer_buffer(lex_ctx, avail_bytes);\n\t}\n}\n\nDUK_LOCAL void duk__init_lexer_window(duk_lexer_ctx *lex_ctx) {\n\tlex_ctx->window = lex_ctx->buffer;\n\tduk__fill_lexer_buffer(lex_ctx, 0);\n}\n#else  /* DUK_USE_LEXER_SLIDING_WINDOW */\nDUK_LOCAL duk_codepoint_t duk__read_char(duk_lexer_ctx *lex_ctx) {\n\tduk_ucodepoint_t x;\n\tduk_small_uint_t len;\n\tduk_small_uint_t i;\n\tconst duk_uint8_t *p;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\tduk_ucodepoint_t mincp;\n#endif\n\tduk_size_t input_offset;\n\n\tinput_offset = lex_ctx->input_offset;\n\tif (DUK_UNLIKELY(input_offset >= lex_ctx->input_length)) {\n\t\t/* If input_offset were assigned a negative value, it would\n\t\t * result in a large positive value.  Most likely it would be\n\t\t * larger than input_length and be caught here.  In any case\n\t\t * no memory unsafe behavior would happen.\n\t\t */\n\t\treturn -1;\n\t}\n\n\tp = lex_ctx->input + input_offset;\n\tx = (duk_ucodepoint_t) (*p);\n\n\tif (DUK_LIKELY(x < 0x80UL)) {\n\t\t/* 0xxx xxxx -> fast path */\n\n\t\t/* input offset tracking */\n\t\tlex_ctx->input_offset++;\n\n\t\tDUK_ASSERT(x != 0x2028UL && x != 0x2029UL);  /* not LS/PS */\n\t\tif (DUK_UNLIKELY(x <= 0x000dUL)) {\n\t\t\tif ((x == 0x000aUL) ||\n\t\t\t    ((x == 0x000dUL) && (lex_ctx->input_offset >= lex_ctx->input_length ||\n\t\t\t                         lex_ctx->input[lex_ctx->input_offset] != 0x000aUL))) {\n\t\t\t\t/* lookup for 0x000a above assumes shortest encoding now */\n\n\t\t\t\t/* E5 Section 7.3, treat the following as newlines:\n\t\t\t\t *   LF\n\t\t\t\t *   CR [not followed by LF]\n\t\t\t\t *   LS\n\t\t\t\t *   PS\n\t\t\t\t *\n\t\t\t\t * For CR LF, CR is ignored if it is followed by LF, and the LF will bump\n\t\t\t\t * the line number.\n\t\t\t\t */\n\t\t\t\tlex_ctx->input_line++;\n\t\t\t}\n\t\t}\n\n\t\treturn (duk_codepoint_t) x;\n\t}\n\n\t/* Slow path. */\n\n\tif (x < 0xc0UL) {\n\t\t/* 10xx xxxx -> invalid */\n\t\tgoto error_encoding;\n\t} else if (x < 0xe0UL) {\n\t\t/* 110x xxxx   10xx xxxx  */\n\t\tlen = 2;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tmincp = 0x80UL;\n#endif\n\t\tx = x & 0x1fUL;\n\t} else if (x < 0xf0UL) {\n\t\t/* 1110 xxxx   10xx xxxx   10xx xxxx */\n\t\tlen = 3;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tmincp = 0x800UL;\n#endif\n\t\tx = x & 0x0fUL;\n\t} else if (x < 0xf8UL) {\n\t\t/* 1111 0xxx   10xx xxxx   10xx xxxx   10xx xxxx */\n\t\tlen = 4;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tmincp = 0x10000UL;\n#endif\n\t\tx = x & 0x07UL;\n\t} else {\n\t\t/* no point in supporting encodings of 5 or more bytes */\n\t\tgoto error_encoding;\n\t}\n\n\tDUK_ASSERT(lex_ctx->input_length >= lex_ctx->input_offset);\n\tif ((duk_size_t) len > (duk_size_t) (lex_ctx->input_length - lex_ctx->input_offset)) {\n\t\tgoto error_clipped;\n\t}\n\n\tp++;\n\tfor (i = 1; i < len; i++) {\n\t\tduk_small_uint_t y;\n\t\ty = *p++;\n\t\tif ((y & 0xc0U) != 0x80U) {\n\t\t\t/* check that byte has the form 10xx xxxx */\n\t\t\tgoto error_encoding;\n\t\t}\n\t\tx = x << 6;\n\t\tx += y & 0x3fUL;\n\t}\n\n\t/* check final character validity */\n\n\tif (x > 0x10ffffUL) {\n\t\tgoto error_encoding;\n\t}\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\tif (x < mincp || (x >= 0xd800UL && x <= 0xdfffUL) || x == 0xfffeUL) {\n\t\tgoto error_encoding;\n\t}\n#endif\n\n\t/* input offset tracking */\n\tlex_ctx->input_offset += len;\n\n\t/* line tracking */\n\tDUK_ASSERT(x != 0x000aUL && x != 0x000dUL);\n\tif ((x == 0x2028UL) || (x == 0x2029UL)) {\n\t\tlex_ctx->input_line++;\n\t}\n\n\treturn (duk_codepoint_t) x;\n\n error_clipped:   /* clipped codepoint */\n error_encoding:  /* invalid codepoint encoding or codepoint */\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_SOURCE_DECODE_FAILED);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_LOCAL void duk__advance_bytes(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_bytes) {\n\tduk_small_uint_t keep_bytes;\n\tduk_lexer_codepoint *cp, *cp_end;\n\n\tDUK_ASSERT_DISABLE(count_bytes >= 0);  /* unsigned */\n\tDUK_ASSERT(count_bytes <= (duk_small_uint_t) (DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint)));\n\n\t/* Zero 'count' is also allowed to make call sites easier. */\n\n\tkeep_bytes = DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint) - count_bytes;\n\tduk_memmove((void *) lex_ctx->window,\n\t            (const void *) ((duk_uint8_t *) lex_ctx->window + count_bytes),\n\t            (size_t) keep_bytes);\n\n\tcp = (duk_lexer_codepoint *) ((duk_uint8_t *) lex_ctx->window + keep_bytes);\n\tcp_end = lex_ctx->window + DUK_LEXER_WINDOW_SIZE;\n\tfor (; cp != cp_end; cp++) {\n\t\tcp->offset = lex_ctx->input_offset;\n\t\tcp->line = lex_ctx->input_line;\n\t\tcp->codepoint = duk__read_char(lex_ctx);\n\t}\n}\n\nDUK_LOCAL void duk__init_lexer_window(duk_lexer_ctx *lex_ctx) {\n\t/* Call with count == DUK_LEXER_WINDOW_SIZE to fill buffer initially. */\n\tduk__advance_bytes(lex_ctx, DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint));  /* fill window */\n}\n#endif  /* DUK_USE_LEXER_SLIDING_WINDOW */\n\nDUK_LOCAL void duk__advance_chars(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_chars) {\n\tduk__advance_bytes(lex_ctx, count_chars * sizeof(duk_lexer_codepoint));\n}\n\n/*\n *  (Re)initialize the temporary byte buffer.  May be called extra times\n *  with little impact.\n */\n\nDUK_LOCAL void duk__initbuffer(duk_lexer_ctx *lex_ctx) {\n\t/* Reuse buffer as is unless buffer has grown large. */\n\tif (DUK_HBUFFER_DYNAMIC_GET_SIZE(lex_ctx->buf) < DUK_LEXER_TEMP_BUF_LIMIT) {\n\t\t/* Keep current size */\n\t} else {\n\t\tduk_hbuffer_resize(lex_ctx->thr, lex_ctx->buf, DUK_LEXER_TEMP_BUF_LIMIT);\n\t}\n\n\tDUK_BW_INIT_WITHBUF(lex_ctx->thr, &lex_ctx->bw, lex_ctx->buf);\n}\n\n/*\n *  Append a Unicode codepoint to the temporary byte buffer.  Performs\n *  CESU-8 surrogate pair encoding for codepoints above the BMP.\n *  Existing surrogate pairs are allowed and also encoded into CESU-8.\n */\n\nDUK_LOCAL void duk__appendbuffer(duk_lexer_ctx *lex_ctx, duk_codepoint_t x) {\n\t/*\n\t *  Since character data is only generated by decoding the source or by\n\t *  the compiler itself, we rely on the input codepoints being correct\n\t *  and avoid a check here.\n\t *\n\t *  Character data can also come here through decoding of Unicode\n\t *  escapes (\"\\udead\\ubeef\") so all 16-but unsigned values can be\n\t *  present, even when the source file itself is strict UTF-8.\n\t */\n\tDUK_ASSERT(x >= 0 && x <= 0x10ffffL);\n\n\tDUK_BW_WRITE_ENSURE_CESU8(lex_ctx->thr, &lex_ctx->bw, (duk_ucodepoint_t) x);\n}\n\nDUK_LOCAL void duk__appendbuffer_ascii(duk_lexer_ctx *lex_ctx, duk_codepoint_t x) {\n\t/* ASCII characters can be emitted as a single byte without encoding\n\t * which matters for some fast paths.\n\t */\n\tDUK_ASSERT(x >= 0 && x <= 0x7f);\n\n\tDUK_BW_WRITE_ENSURE_U8(lex_ctx->thr, &lex_ctx->bw, (duk_uint8_t) x);\n}\n\n/*\n *  Intern the temporary byte buffer into a valstack slot\n *  (in practice, slot1 or slot2).\n */\n\nDUK_LOCAL duk_hstring *duk__internbuffer(duk_lexer_ctx *lex_ctx, duk_idx_t valstack_idx) {\n\tDUK_ASSERT(valstack_idx == lex_ctx->slot1_idx || valstack_idx == lex_ctx->slot2_idx);\n\n\tDUK_BW_PUSH_AS_STRING(lex_ctx->thr, &lex_ctx->bw);\n\tduk_replace(lex_ctx->thr, valstack_idx);\n\treturn duk_known_hstring(lex_ctx->thr, valstack_idx);\n}\n\n/*\n *  Init lexer context\n */\n\nDUK_INTERNAL void duk_lexer_initctx(duk_lexer_ctx *lex_ctx) {\n\tDUK_ASSERT(lex_ctx != NULL);\n\n\tduk_memzero(lex_ctx, sizeof(*lex_ctx));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\n\tlex_ctx->window = NULL;\n#endif\n\tlex_ctx->thr = NULL;\n\tlex_ctx->input = NULL;\n\tlex_ctx->buf = NULL;\n#endif\n}\n\n/*\n *  Set lexer input position and reinitialize lookup window.\n */\n\nDUK_INTERNAL void duk_lexer_getpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt) {\n\tpt->offset = lex_ctx->window[0].offset;\n\tpt->line = lex_ctx->window[0].line;\n}\n\nDUK_INTERNAL void duk_lexer_setpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt) {\n\tDUK_ASSERT_DISABLE(pt->offset >= 0);  /* unsigned */\n\tDUK_ASSERT(pt->line >= 1);\n\tlex_ctx->input_offset = pt->offset;\n\tlex_ctx->input_line = pt->line;\n\tduk__init_lexer_window(lex_ctx);\n}\n\n/*\n *  Lexing helpers\n */\n\n/* Numeric value of a hex digit (also covers octal and decimal digits) or\n * -1 if not a valid hex digit.\n */\nDUK_LOCAL duk_codepoint_t duk__hexval_validate(duk_codepoint_t x) {\n\tduk_small_int_t t;\n\n\t/* Here 'x' is a Unicode codepoint */\n\tif (DUK_LIKELY(x >= 0 && x <= 0xff)) {\n\t\tt = duk_hex_dectab[x];\n\t\tif (DUK_LIKELY(t >= 0)) {\n\t\t\treturn t;\n\t\t}\n\t}\n\n\treturn -1;\n}\n\n/* Just a wrapper for call sites where 'x' is known to be valid so\n * we assert for it before decoding.\n */\nDUK_LOCAL duk_codepoint_t duk__hexval(duk_codepoint_t x) {\n\tduk_codepoint_t ret;\n\n\tDUK_ASSERT((x >= DUK_ASC_0 && x <= DUK_ASC_9) ||\n\t           (x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_F) ||\n\t           (x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_F));\n\tret = duk__hexval_validate(x);\n\tDUK_ASSERT(ret >= 0 && ret <= 15);\n\treturn ret;\n}\n\n/* having this as a separate function provided a size benefit */\nDUK_LOCAL duk_bool_t duk__is_hex_digit(duk_codepoint_t x) {\n\tif (DUK_LIKELY(x >= 0 && x <= 0xff)) {\n\t\treturn (duk_hex_dectab[x] >= 0);\n\t}\n\treturn 0;\n}\n\n/* Parse a Unicode escape of the form \\xHH, \\uHHHH, or \\u{H+}.  Shared by\n * source and RegExp parsing.\n */\nDUK_LOCAL duk_codepoint_t duk__lexer_parse_escape(duk_lexer_ctx *lex_ctx, duk_bool_t allow_es6) {\n\tduk_small_int_t digits;  /* Initial value 2 or 4 for fixed length escapes, 0 for ES2015 \\u{H+}. */\n\tduk_codepoint_t escval;\n\tduk_codepoint_t x;\n\tduk_small_uint_t adv;\n\n\tDUK_ASSERT(DUK__L0() == DUK_ASC_BACKSLASH);  /* caller responsibilities */\n\tDUK_ASSERT(DUK__L1() == DUK_ASC_LC_X || DUK__L1() == DUK_ASC_LC_U);\n\tDUK_UNREF(allow_es6);\n\n\tadv = 2;\n\tdigits = 2;\n\tif (DUK__L1() == DUK_ASC_LC_U) {\n\t\tdigits = 4;\n#if defined(DUK_USE_ES6_UNICODE_ESCAPE)\n\t\tif (DUK__L2() == DUK_ASC_LCURLY && allow_es6) {\n\t\t\tdigits = 0;\n\t\t\tadv = 3;\n\t\t}\n#endif\n\t}\n\tDUK__ADVANCECHARS(lex_ctx, adv);\n\n\tescval = 0;\n\tfor (;;) {\n\t\t/* One of the escape forms: \\xHH, \\uHHHH, \\u{H+}.\n\t\t * The 'digits' variable tracks parsing state and is\n\t\t * initialized to:\n\t\t *\n\t\t *   \\xHH     2\n\t\t *   \\uHH     4\n\t\t *   \\u{H+}   0 first time, updated to -1 to indicate\n\t\t *            at least one digit has been parsed\n\t\t *\n\t\t * Octal parsing is handled separately because it can be\n\t\t * done with fixed lookahead and also has validation\n\t\t * rules which depend on the escape length (which is\n\t\t * variable).\n\t\t *\n\t\t * We don't need a specific check for x < 0 (end of\n\t\t * input) or duk_unicode_is_line_terminator(x)\n\t\t * because the 'dig' decode will fail and lead to a\n\t\t * SyntaxError.\n\t\t */\n\t\tduk_codepoint_t dig;\n\n\t\tx = DUK__L0();\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\n\t\tdig = duk__hexval_validate(x);\n\t\tif (digits > 0) {\n\t\t\tdigits--;\n\t\t\tif (dig < 0) {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t\tDUK_ASSERT(dig >= 0x00 && dig <= 0x0f);\n\t\t\tescval = (escval << 4) + dig;\n\t\t\tif (digits == 0) {\n\t\t\t\tDUK_ASSERT(escval >= 0 && escval <= 0xffffL);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n#if defined(DUK_USE_ES6_UNICODE_ESCAPE)\n\t\t\tDUK_ASSERT(digits == 0 /* first time */ || digits == -1 /* others */);\n\t\t\tif (dig >= 0) {\n\t\t\t\tDUK_ASSERT(dig >= 0x00 && dig <= 0x0f);\n\t\t\t\tescval = (escval << 4) + dig;\n\t\t\t\tif (escval > 0x10ffffL) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_RCURLY) {\n\t\t\t\tif (digits == 0) {\n\t\t\t\t\t/* Empty escape, \\u{}. */\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(escval >= 0 && escval <= 0x10ffffL);\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t\tdigits = -1;  /* Indicate we have at least one digit. */\n#else  /* DUK_USE_ES6_UNICODE_ESCAPE */\n\t\t\tDUK_ASSERT(0);  /* Never happens if \\u{H+} support disabled. */\n#endif  /* DUK_USE_ES6_UNICODE_ESCAPE */\n\t\t}\n\t}\n\n\treturn escval;\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Parse legacy octal escape of the form \\N{1,3}, e.g. \\0, \\5, \\0377.  Maximum\n * allowed value is \\0377 (U+00FF), longest match is used.  Used for both string\n * RegExp octal escape parsing.  Window[0] must be the slash '\\' and the first\n * digit must already be validated to be in [0-9] by the caller.\n */\nDUK_LOCAL duk_codepoint_t duk__lexer_parse_legacy_octal(duk_lexer_ctx *lex_ctx, duk_small_uint_t *out_adv, duk_bool_t reject_annex_b) {\n\tduk_codepoint_t cp;\n\tduk_small_uint_t lookup_idx;\n\tduk_small_uint_t adv;\n\tduk_codepoint_t tmp;\n\n\tDUK_ASSERT(out_adv != NULL);\n\tDUK_ASSERT(DUK__LOOKUP(lex_ctx, 0) == DUK_ASC_BACKSLASH);\n\tDUK_ASSERT(DUK__LOOKUP(lex_ctx, 1) >= DUK_ASC_0 && DUK__LOOKUP(lex_ctx, 1) <= DUK_ASC_9);\n\n\tcp = 0;\n\ttmp = 0;\n\tfor (lookup_idx = 1; lookup_idx <= 3; lookup_idx++) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"lookup_idx=%ld, cp=%ld\", (long) lookup_idx, (long) cp));\n\t\ttmp = DUK__LOOKUP(lex_ctx, lookup_idx);\n\t\tif (tmp < DUK_ASC_0 || tmp > DUK_ASC_7) {\n\t\t\t/* No more valid digits. */\n\t\t\tbreak;\n\t\t}\n\t\ttmp = (cp << 3) + (tmp - DUK_ASC_0);\n\t\tif (tmp > 0xff) {\n\t\t\t/* Three digit octal escapes above \\377 (= 0xff)\n\t\t\t * are not allowed.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\t\tcp = tmp;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"final lookup_idx=%ld, cp=%ld\", (long) lookup_idx, (long) cp));\n\n\tadv = lookup_idx;\n\tif (lookup_idx == 1) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"\\\\8 or \\\\9 -> treat as literal, accept in strict mode too\"));\n\t\tDUK_ASSERT(tmp == DUK_ASC_8 || tmp == DUK_ASC_9);\n\t\tcp = tmp;\n\t\tadv++;  /* correction to above, eat offending character */\n\t} else if (lookup_idx == 2 && cp == 0) {\n\t\t/* Note: 'foo\\0bar' is OK in strict mode, but 'foo\\00bar' is not.\n\t\t * It won't be interpreted as 'foo\\u{0}0bar' but as a SyntaxError.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"\\\\0 -> accept in strict mode too\"));\n\t} else {\n\t\t/* This clause also handles non-shortest zero, e.g. \\00. */\n\t\tif (reject_annex_b) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-zero octal literal %ld -> reject in strict-mode\", (long) cp));\n\t\t\tcp = -1;\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-zero octal literal %ld -> accepted\", (long) cp));\n\t\t\tDUK_ASSERT(cp >= 0 && cp <= 0xff);\n\t\t}\n\t}\n\n\t*out_adv = adv;\n\n\tDUK_ASSERT((cp >= 0 && cp <= 0xff) || (cp == -1 && reject_annex_b));\n\treturn cp;\n}\n\n/* XXX: move strict mode to lex_ctx? */\nDUK_LOCAL void duk__lexer_parse_string_literal(duk_lexer_ctx *lex_ctx, duk_token *out_token, duk_small_int_t quote, duk_bool_t strict_mode) {\n\tduk_small_uint_t adv;\n\n\tfor (adv = 1 /* initial quote */ ;;) {\n\t\tduk_codepoint_t x;\n\n\t\tDUK__ADVANCECHARS(lex_ctx, adv);  /* eat opening quote on first loop */\n\t\tx = DUK__L0();\n\n\t\tadv = 1;\n\t\tif (x == quote) {\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat closing quote */\n\t\t\tbreak;\n\t\t} else if (x == '\\\\') {\n\t\t\t/* DUK__L0        -> '\\' char\n\t\t\t * DUK__L1 ... DUK__L5 -> more lookup\n\t\t\t */\n\t\t\tduk_small_int_t emitcp = -1;\n\n\t\t\tx = DUK__L1();\n\n\t\t\t/* How much to advance before next loop. */\n\t\t\tadv = 2;  /* note: long live range */\n\n\t\t\tswitch (x) {\n\t\t\tcase '\\'':\n\t\t\t\temitcp = 0x0027;\n\t\t\t\tbreak;\n\t\t\tcase '\"':\n\t\t\t\temitcp = 0x0022;\n\t\t\t\tbreak;\n\t\t\tcase '\\\\':\n\t\t\t\temitcp = 0x005c;\n\t\t\t\tbreak;\n\t\t\tcase 'b':\n\t\t\t\temitcp = 0x0008;\n\t\t\t\tbreak;\n\t\t\tcase 'f':\n\t\t\t\temitcp = 0x000c;\n\t\t\t\tbreak;\n\t\t\tcase 'n':\n\t\t\t\temitcp = 0x000a;\n\t\t\t\tbreak;\n\t\t\tcase 'r':\n\t\t\t\temitcp = 0x000d;\n\t\t\t\tbreak;\n\t\t\tcase 't':\n\t\t\t\temitcp = 0x0009;\n\t\t\t\tbreak;\n\t\t\tcase 'v':\n\t\t\t\temitcp = 0x000b;\n\t\t\t\tbreak;\n\t\t\tcase 'x':\n\t\t\tcase 'u': {\n\t\t\t\tduk_codepoint_t esc_cp;\n\t\t\t\tesc_cp = duk__lexer_parse_escape(lex_ctx, 1 /*allow_es6*/);\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, esc_cp);\n\t\t\t\tadv = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tif (duk_unicode_is_line_terminator(x)) {\n\t\t\t\t\t/* line continuation */\n\t\t\t\t\tif (x == 0x000d && DUK__L2() == 0x000a) {\n\t\t\t\t\t\t/* CR LF again a special case */\n\t\t\t\t\t\tadv = 3;  /* line terminator, CR, LF */\n\t\t\t\t\t}\n\t\t\t\t} else if (DUK__ISDIGIT(x)) {\n\t\t\t\t\t/*\n\t\t\t\t\t *  Octal escape or zero escape:\n\t\t\t\t\t *    \\0                                     (lookahead not OctalDigit)\n\t\t\t\t\t *    \\1 ... \\7                              (lookahead not OctalDigit)\n\t\t\t\t\t *    \\ZeroToThree OctalDigit                (lookahead not OctalDigit)\n\t\t\t\t\t *    \\FourToSeven OctalDigit                (no lookahead restrictions)\n\t\t\t\t\t *    \\ZeroToThree OctalDigit OctalDigit     (no lookahead restrictions)\n\t\t\t\t\t *\n\t\t\t\t\t *  Zero escape is part of the standard syntax.  Octal escapes are\n\t\t\t\t\t *  defined in E5 Section B.1.2, and are only allowed in non-strict mode.\n\t\t\t\t\t *  Any other productions starting with a decimal digit are invalid\n\t\t\t\t\t *  but are in practice treated like identity escapes.\n\t\t\t\t\t *\n\t\t\t\t\t *  Parse octal (up to 3 digits) from the lookup window.\n\t\t\t\t\t */\n\n\t\t\t\t\temitcp = duk__lexer_parse_legacy_octal(lex_ctx, &adv, strict_mode /*reject_annex_b*/);\n\t\t\t\t\tif (emitcp < 0) {\n\t\t\t\t\t\tgoto fail_escape;\n\t\t\t\t\t}\n\t\t\t\t} else if (x < 0) {\n\t\t\t\t\tgoto fail_unterminated;\n\t\t\t\t} else {\n\t\t\t\t\t/* escaped NonEscapeCharacter */\n\t\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t\t}\n\t\t\t}  /* end default clause */\n\t\t\t}  /* end switch */\n\n\t\t\t/* Shared handling for single codepoint escapes. */\n\t\t\tif (emitcp >= 0) {\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, emitcp);\n\t\t\t}\n\n\t\t\t/* Track number of escapes; count not really needed but directive\n\t\t\t * prologues need to detect whether there were any escapes or line\n\t\t\t * continuations or not.\n\t\t\t */\n\t\t\tout_token->num_escapes++;\n\t\t} else if (x >= 0x20 && x <= 0x7f) {\n\t\t\t/* Fast path for ASCII case, avoids line terminator\n\t\t\t * check and CESU-8 encoding.\n\t\t\t */\n\t\t\tDUK_ASSERT(x >= 0);\n\t\t\tDUK_ASSERT(!duk_unicode_is_line_terminator(x));\n\t\t\tDUK_ASSERT(x != quote);\n\t\t\tDUK_ASSERT(x != DUK_ASC_BACKSLASH);\n\t\t\tDUK__APPENDBUFFER_ASCII(lex_ctx, x);\n\t\t} else if (x < 0 || duk_unicode_is_line_terminator(x)) {\n\t\t\tgoto fail_unterminated;\n\t\t} else {\n\t\t\t/* Character which is part of the string but wasn't handled\n\t\t\t * by the fast path.\n\t\t\t */\n\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t}\n\t} /* string parse loop */\n\n\treturn;\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterminated:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_STRING);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Skip to end-of-line (or end-of-file), used for single line comments. */\nDUK_LOCAL void duk__lexer_skip_to_endofline(duk_lexer_ctx *lex_ctx) {\n\tfor (;;) {\n\t\tduk_codepoint_t x;\n\n\t\tx = DUK__L0();\n\t\tif (x < 0 || duk_unicode_is_line_terminator(x)) {\n\t\t\tbreak;\n\t\t}\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t}\n}\n\n/*\n *  Parse ECMAScript source InputElementDiv or InputElementRegExp\n *  (E5 Section 7), skipping whitespace, comments, and line terminators.\n *\n *  Possible results are:\n *    (1) a token\n *    (2) a line terminator (skipped)\n *    (3) a comment (skipped)\n *    (4) EOF\n *\n *  White space is automatically skipped from the current position (but\n *  not after the input element).  If input has already ended, returns\n *  DUK_TOK_EOF indefinitely.  If a parse error occurs, uses an DUK_ERROR()\n *  macro call (and hence a longjmp through current heap longjmp context).\n *  Comments and line terminator tokens are automatically skipped.\n *\n *  The input element being matched is determined by regexp_mode; if set,\n *  parses a InputElementRegExp, otherwise a InputElementDiv.  The\n *  difference between these are handling of productions starting with a\n *  forward slash.\n *\n *  If strict_mode is set, recognizes additional future reserved words\n *  specific to strict mode, and refuses to parse octal literals.\n *\n *  The matching strategy below is to (currently) use a six character\n *  lookup window to quickly determine which production is the -longest-\n *  matching one, and then parse that.  The top-level if-else clauses\n *  match the first character, and the code blocks for each clause\n *  handle -all- alternatives for that first character.  ECMAScript\n *  specification uses the \"longest match wins\" semantics, so the order\n *  of the if-clauses matters.\n *\n *  Misc notes:\n *\n *    * ECMAScript numeric literals do not accept a sign character.\n *      Consequently e.g. \"-1.0\" is parsed as two tokens: a negative\n *      sign and a positive numeric literal.  The compiler performs\n *      the negation during compilation, so this has no adverse impact.\n *\n *    * There is no token for \"undefined\": it is just a value available\n *      from the global object (or simply established by doing a reference\n *      to an undefined value).\n *\n *    * Some contexts want Identifier tokens, which are IdentifierNames\n *      excluding reserved words, while some contexts want IdentifierNames\n *      directly.  In the latter case e.g. \"while\" is interpreted as an\n *      identifier name, not a DUK_TOK_WHILE token.  The solution here is\n *      to provide both token types: DUK_TOK_WHILE goes to 't' while\n *      DUK_TOK_IDENTIFIER goes to 't_nores', and 'slot1' always contains\n *      the identifier / keyword name.\n *\n *    * Directive prologue needs to identify string literals such as\n *      \"use strict\" and 'use strict', which are sensitive to line\n *      continuations and escape sequences.  For instance, \"use\\u0020strict\"\n *      is a valid directive but is distinct from \"use strict\".  The solution\n *      here is to decode escapes while tokenizing, but to keep track of the\n *      number of escapes.  Directive detection can then check that the\n *      number of escapes is zero.\n *\n *    * Multi-line comments with one or more internal LineTerminator are\n *      treated like a line terminator to comply with automatic semicolon\n *      insertion.\n */\n\nDUK_INTERNAL\nvoid duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,\n                                      duk_token *out_token,\n                                      duk_bool_t strict_mode,\n                                      duk_bool_t regexp_mode) {\n\tduk_codepoint_t x;           /* temporary, must be signed and 32-bit to hold Unicode code points */\n\tduk_small_uint_t advtok = 0; /* (advance << 8) + token_type, updated at function end,\n\t                              * init is unnecessary but suppresses \"may be used uninitialized\" warnings.\n\t                              */\n\tduk_bool_t got_lineterm = 0;  /* got lineterm preceding non-whitespace, non-lineterm token */\n\n\tif (++lex_ctx->token_count >= lex_ctx->token_limit) {\n\t\tgoto fail_token_limit;\n\t}\n\n\tout_token->t = DUK_TOK_EOF;\n\tout_token->t_nores = DUK_TOK_INVALID;  /* marker: copy t if not changed */\n#if 0  /* not necessary to init, disabled for faster parsing */\n\tout_token->num = DUK_DOUBLE_NAN;\n\tout_token->str1 = NULL;\n\tout_token->str2 = NULL;\n#endif\n\tout_token->num_escapes = 0;\n\t/* out_token->lineterm set by caller */\n\n\t/* This would be nice, but parsing is faster without resetting the\n\t * value slots.  The only side effect is that references to temporary\n\t * string values may linger until lexing is finished; they're then\n\t * freed normally.\n\t */\n#if 0\n\tduk_to_undefined(lex_ctx->thr, lex_ctx->slot1_idx);\n\tduk_to_undefined(lex_ctx->thr, lex_ctx->slot2_idx);\n#endif\n\n\t/* 'advtok' indicates how much to advance and which token id to assign\n\t * at the end.  This shared functionality minimizes code size.  All\n\t * code paths are required to set 'advtok' to some value, so no default\n\t * init value is used.  Code paths calling DUK_ERROR() never return so\n\t * they don't need to set advtok.\n\t */\n\n\t/*\n\t *  Matching order:\n\t *\n\t *    Punctuator first chars, also covers comments, regexps\n\t *    LineTerminator\n\t *    Identifier or reserved word, also covers null/true/false literals\n\t *    NumericLiteral\n\t *    StringLiteral\n\t *    EOF\n\t *\n\t *  The order does not matter as long as the longest match is\n\t *  always correctly identified.  There are order dependencies\n\t *  in the clauses, so it's not trivial to convert to a switch.\n\t */\n\n restart_lineupdate:\n\tout_token->start_line = lex_ctx->window[0].line;\n\n restart:\n\tout_token->start_offset = lex_ctx->window[0].offset;\n\n\tx = DUK__L0();\n\n\tswitch (x) {\n\tcase DUK_ASC_SPACE:\n\tcase DUK_ASC_HT:  /* fast paths for space and tab */\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\tgoto restart;\n\tcase DUK_ASC_LF:  /* LF line terminator; CR LF and Unicode lineterms are handled in slow path */\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\tgot_lineterm = 1;\n\t\tgoto restart_lineupdate;\n#if defined(DUK_USE_SHEBANG_COMMENTS)\n\tcase DUK_ASC_HASH:  /* '#' */\n\t\tif (DUK__L1() == DUK_ASC_EXCLAMATION && lex_ctx->window[0].offset == 0 &&\n\t\t    (lex_ctx->flags & DUK_COMPILE_SHEBANG)) {\n\t\t\t/* \"Shebang\" comment ('#! ...') on first line. */\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 2) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t}\n\t\tgoto fail_token;\n#endif  /* DUK_USE_SHEBANG_COMMENTS */\n\tcase DUK_ASC_SLASH:  /* '/' */\n\t\tif (DUK__L1() == DUK_ASC_SLASH) {\n\t\t\t/*\n\t\t\t *  E5 Section 7.4, allow SourceCharacter (which is any 16-bit\n\t\t\t *  code point).\n\t\t\t */\n\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 2) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t} else if (DUK__L1() == DUK_ASC_STAR) {\n\t\t\t/*\n\t\t\t *  E5 Section 7.4.  If the multi-line comment contains a newline,\n\t\t\t *  it is treated like a single line terminator for automatic\n\t\t\t *  semicolon insertion.\n\t\t\t */\n\n\t\t\tduk_bool_t last_asterisk = 0;\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 2);\n\t\t\tfor (;;) {\n\t\t\t\tx = DUK__L0();\n\t\t\t\tif (x < 0) {\n\t\t\t\t\tgoto fail_unterm_comment;\n\t\t\t\t}\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t\tif (last_asterisk && x == DUK_ASC_SLASH) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (duk_unicode_is_line_terminator(x)) {\n\t\t\t\t\tgot_lineterm = 1;\n\t\t\t\t}\n\t\t\t\tlast_asterisk = (x == DUK_ASC_STAR);\n\t\t\t}\n\t\t\tgoto restart_lineupdate;\n\t\t} else if (regexp_mode) {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t/*\n\t\t\t *  \"/\" followed by something in regexp mode.  See E5 Section 7.8.5.\n\t\t\t *\n\t\t\t *  RegExp parsing is a bit complex.  First, the regexp body is delimited\n\t\t\t *  by forward slashes, but the body may also contain forward slashes as\n\t\t\t *  part of an escape sequence or inside a character class (delimited by\n\t\t\t *  square brackets).  A mini state machine is used to implement these.\n\t\t\t *\n\t\t\t *  Further, an early (parse time) error must be thrown if the regexp\n\t\t\t *  would cause a run-time error when used in the expression new RegExp(...).\n\t\t\t *  Parsing here simply extracts the (candidate) regexp, and also accepts\n\t\t\t *  invalid regular expressions (which are delimited properly).  The caller\n\t\t\t *  (compiler) must perform final validation and regexp compilation.\n\t\t\t *\n\t\t\t *  RegExp first char may not be '/' (single line comment) or '*' (multi-\n\t\t\t *  line comment).  These have already been checked above, so there is no\n\t\t\t *  need below for special handling of the first regexp character as in\n\t\t\t *  the E5 productions.\n\t\t\t *\n\t\t\t *  About unicode escapes within regexp literals:\n\t\t\t *\n\t\t\t *      E5 Section 7.8.5 grammar does NOT accept \\uHHHH escapes.\n\t\t\t *      However, Section 6 states that regexps accept the escapes,\n\t\t\t *      see paragraph starting with \"In string literals...\".\n\t\t\t *      The regexp grammar, which sees the decoded regexp literal\n\t\t\t *      (after lexical parsing) DOES have a \\uHHHH unicode escape.\n\t\t\t *      So, for instance:\n\t\t\t *\n\t\t\t *          /\\u1234/\n\t\t\t *\n\t\t\t *      should first be parsed by the lexical grammar as:\n\t\t\t *\n\t\t\t *          '\\' 'u'      RegularExpressionBackslashSequence\n\t\t\t *          '1'          RegularExpressionNonTerminator\n\t\t\t *          '2'          RegularExpressionNonTerminator\n\t\t\t *          '3'          RegularExpressionNonTerminator\n\t\t\t *          '4'          RegularExpressionNonTerminator\n\t\t\t *\n\t\t\t *      and the escape itself is then parsed by the regexp engine.\n\t\t\t *      This is the current implementation.\n\t\t\t *\n\t\t\t *  Minor spec inconsistency:\n\t\t\t *\n\t\t\t *      E5 Section 7.8.5 RegularExpressionBackslashSequence is:\n\t\t\t *\n\t\t\t *         \\ RegularExpressionNonTerminator\n\t\t\t *\n\t\t\t *      while Section A.1 RegularExpressionBackslashSequence is:\n\t\t\t *\n\t\t\t *         \\ NonTerminator\n\t\t\t *\n\t\t\t *      The latter is not normative and a typo.\n\t\t\t *\n\t\t\t */\n\n\t\t\t/* first, parse regexp body roughly */\n\n\t\t\tduk_small_int_t state = 0;  /* 0=base, 1=esc, 2=class, 3=class+esc */\n\n\t\t\tDUK__INITBUFFER(lex_ctx);\n\t\t\tfor (;;) {\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* skip opening slash on first loop */\n\t\t\t\tx = DUK__L0();\n\t\t\t\tif (x < 0 || duk_unicode_is_line_terminator(x)) {\n\t\t\t\t\tgoto fail_unterm_regexp;\n\t\t\t\t}\n\t\t\t\tx = DUK__L0();  /* re-read to avoid spill / fetch */\n\t\t\t\tif (state == 0) {\n\t\t\t\t\tif (x == DUK_ASC_SLASH) {\n\t\t\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat closing slash */\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\t\t\t\tstate = 1;\n\t\t\t\t\t} else if (x == DUK_ASC_LBRACKET) {\n\t\t\t\t\t\tstate = 2;\n\t\t\t\t\t}\n\t\t\t\t} else if (state == 1) {\n\t\t\t\t\tstate = 0;\n\t\t\t\t} else if (state == 2) {\n\t\t\t\t\tif (x == DUK_ASC_RBRACKET) {\n\t\t\t\t\t\tstate = 0;\n\t\t\t\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\t\t\t\tstate = 3;\n\t\t\t\t\t}\n\t\t\t\t} else { /* state == 3 */\n\t\t\t\t\tstate = 2;\n\t\t\t\t}\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t}\n\t\t\tout_token->str1 = duk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\n\t\t\t/* second, parse flags */\n\n\t\t\tDUK__INITBUFFER(lex_ctx);\n\t\t\tfor (;;) {\n\t\t\t\tx = DUK__L0();\n\t\t\t\tif (!duk_unicode_is_identifier_part(x)) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tx = DUK__L0();  /* re-read to avoid spill / fetch */\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t}\n\t\t\tout_token->str2 = duk__internbuffer(lex_ctx, lex_ctx->slot2_idx);\n\n\t\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\t\t/* validation of the regexp is caller's responsibility */\n\n\t\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_REGEXP);\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\tgoto fail_regexp_support;\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\t/* \"/=\" and not in regexp mode */\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_DIV_EQ);\n\t\t} else {\n\t\t\t/* \"/\" and not in regexp mode */\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_DIV);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_LCURLY:  /* '{' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LCURLY);\n\t\tbreak;\n\tcase DUK_ASC_RCURLY:  /* '}' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_RCURLY);\n\t\tbreak;\n\tcase DUK_ASC_LPAREN:  /* '(' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LPAREN);\n\t\tbreak;\n\tcase DUK_ASC_RPAREN:  /* ')' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_RPAREN);\n\t\tbreak;\n\tcase DUK_ASC_LBRACKET:  /* '[' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LBRACKET);\n\t\tbreak;\n\tcase DUK_ASC_RBRACKET:  /* ']' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_RBRACKET);\n\t\tbreak;\n\tcase DUK_ASC_PERIOD:  /* '.' */\n\t\tif (DUK__ISDIGIT(DUK__L1())) {\n\t\t\t/* Period followed by a digit can only start DecimalLiteral\n\t\t\t * (handled in slow path).  We could jump straight into the\n\t\t\t * DecimalLiteral handling but should avoid goto to inside\n\t\t\t * a block.\n\t\t\t */\n\t\t\tgoto slow_path;\n\t\t}\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_PERIOD);\n\t\tbreak;\n\tcase DUK_ASC_SEMICOLON:  /* ';' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_SEMICOLON);\n\t\tbreak;\n\tcase DUK_ASC_COMMA:  /* ',' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_COMMA);\n\t\tbreak;\n\tcase DUK_ASC_LANGLE:  /* '<' */\n#if defined(DUK_USE_HTML_COMMENTS)\n\t\tif (DUK__L1() == DUK_ASC_EXCLAMATION && DUK__L2() == DUK_ASC_MINUS && DUK__L3() == DUK_ASC_MINUS) {\n\t\t\t/*\n\t\t\t *  ES2015: B.1.3, handle \"<!--\" SingleLineHTMLOpenComment\n\t\t\t */\n\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 4) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t}\n\t\telse\n#endif  /* DUK_USE_HTML_COMMENTS */\n\t\tif (DUK__L1() == DUK_ASC_LANGLE && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_ALSHIFT_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_LE);\n\t\t} else if (DUK__L1() == DUK_ASC_LANGLE) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_ALSHIFT);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LT);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_RANGLE:  /* '>' */\n\t\tif (DUK__L1() == DUK_ASC_RANGLE && DUK__L2() == DUK_ASC_RANGLE && DUK__L3() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(4, DUK_TOK_RSHIFT_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_RANGLE && DUK__L2() == DUK_ASC_RANGLE) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_RSHIFT);\n\t\t} else if (DUK__L1() == DUK_ASC_RANGLE && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_ARSHIFT_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_GE);\n\t\t} else if (DUK__L1() == DUK_ASC_RANGLE) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_ARSHIFT);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_GT);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_EQUALS:  /* '=' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_SEQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_EQUALSIGN);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_EXCLAMATION:  /* '!' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_SNEQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_NEQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LNOT);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_PLUS:  /* '+' */\n\t\tif (DUK__L1() == DUK_ASC_PLUS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_INCREMENT);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_ADD_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_ADD);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_MINUS:  /* '-' */\n#if defined(DUK_USE_HTML_COMMENTS)\n\t\tif (got_lineterm && DUK__L1() == DUK_ASC_MINUS && DUK__L2() == DUK_ASC_RANGLE) {\n\t\t\t/*\n\t\t\t *  ES2015: B.1.3, handle \"-->\" SingleLineHTMLCloseComment\n\t\t\t *  Only allowed:\n\t\t\t *  - on new line\n\t\t\t *  - preceded only by whitespace\n\t\t\t *  - preceded by end of multiline comment and optional whitespace\n\t\t\t *\n\t\t\t * Since whitespace generates no tokens, and multiline comments\n\t\t\t * are treated as a line ending, consulting `got_lineterm` is\n\t\t\t * sufficient to test for these three options.\n\t\t\t */\n\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 3) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t} else\n#endif  /* DUK_USE_HTML_COMMENTS */\n\t\tif (DUK__L1() == DUK_ASC_MINUS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_DECREMENT);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_SUB_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_SUB);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_STAR:  /* '*' */\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tif (DUK__L1() == DUK_ASC_STAR && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_EXP_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_STAR) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_EXP);\n\t\t} else\n#endif\n\t\tif (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_MUL_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_MUL);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_PERCENT:  /* '%' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_MOD_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_MOD);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_AMP:  /* '&' */\n\t\tif (DUK__L1() == DUK_ASC_AMP) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_LAND);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_BAND_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BAND);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_PIPE:  /* '|' */\n\t\tif (DUK__L1() == DUK_ASC_PIPE) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_LOR);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_BOR_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BOR);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_CARET:  /* '^' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_BXOR_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BXOR);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_TILDE:  /* '~' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BNOT);\n\t\tbreak;\n\tcase DUK_ASC_QUESTION:  /* '?' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_QUESTION);\n\t\tbreak;\n\tcase DUK_ASC_COLON:  /* ':' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_COLON);\n\t\tbreak;\n\tcase DUK_ASC_DOUBLEQUOTE:    /* '\"' */\n\tcase DUK_ASC_SINGLEQUOTE: {  /* '\\'' */\n\t\tDUK__INITBUFFER(lex_ctx);\n\t\tduk__lexer_parse_string_literal(lex_ctx, out_token, x /*quote*/, strict_mode);\n\t\tduk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\t\tout_token->str1 = duk_known_hstring(lex_ctx->thr, lex_ctx->slot1_idx);\n\n\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_STRING);\n\t\tbreak;\n\t}\n\tdefault:\n\t\tgoto slow_path;\n\t}  /* switch */\n\n\tgoto skip_slow_path;\n\n slow_path:\n\tif (duk_unicode_is_line_terminator(x)) {\n\t\tif (x == 0x000d && DUK__L1() == 0x000a) {\n\t\t\t/*\n\t\t\t *  E5 Section 7.3: CR LF is detected as a single line terminator for\n\t\t\t *  line numbers.  Here we also detect it as a single line terminator\n\t\t\t *  token.\n\t\t\t */\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 2);\n\t\t} else {\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t}\n\t\tgot_lineterm = 1;\n\t\tgoto restart_lineupdate;\n\t} else if (duk_unicode_is_identifier_start(x) || x == DUK_ASC_BACKSLASH) {\n\t\t/*\n\t\t *  Parse an identifier and then check whether it is:\n\t\t *    - reserved word (keyword or other reserved word)\n\t\t *    - \"null\"  (NullLiteral)\n\t\t *    - \"true\"  (BooleanLiteral)\n\t\t *    - \"false\" (BooleanLiteral)\n\t\t *    - anything else => identifier\n\t\t *\n\t\t *  This does not follow the E5 productions cleanly, but is\n\t\t *  useful and compact.\n\t\t *\n\t\t *  Note that identifiers may contain Unicode escapes,\n\t\t *  see E5 Sections 6 and 7.6.  They must be decoded first,\n\t\t *  and the result checked against allowed characters.\n\t\t *  The above if-clause accepts an identifier start and an\n\t\t *  '\\' character -- no other token can begin with a '\\'.\n\t\t *\n\t\t *  Note that \"get\" and \"set\" are not reserved words in E5\n\t\t *  specification so they are recognized as plain identifiers\n\t\t *  (the tokens DUK_TOK_GET and DUK_TOK_SET are actually not\n\t\t *  used now).  The compiler needs to work around this.\n\t\t *\n\t\t *  Strictly speaking, following ECMAScript longest match\n\t\t *  specification, an invalid escape for the first character\n\t\t *  should cause a syntax error.  However, an invalid escape\n\t\t *  for IdentifierParts should just terminate the identifier\n\t\t *  early (longest match), and let the next tokenization\n\t\t *  fail.  For instance Rhino croaks with 'foo\\z' when\n\t\t *  parsing the identifier.  This has little practical impact.\n\t\t */\n\n\t\tduk_small_uint_t i, i_end;\n\t\tduk_bool_t first = 1;\n\t\tduk_hstring *str;\n\n\t\tDUK__INITBUFFER(lex_ctx);\n\t\tfor (;;) {\n\t\t\t/* re-lookup first char on first loop */\n\t\t\tif (DUK__L0() == DUK_ASC_BACKSLASH) {\n\t\t\t\tduk_codepoint_t esc_cp;\n\t\t\t\tif (DUK__L1() != DUK_ASC_LC_U) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t\tesc_cp = duk__lexer_parse_escape(lex_ctx, 1 /*allow_es6*/);\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, esc_cp);\n\n\t\t\t\t/* IdentifierStart is stricter than IdentifierPart, so if the first\n\t\t\t\t * character is escaped, must have a stricter check here.\n\t\t\t\t */\n\t\t\t\tif (!(first ? duk_unicode_is_identifier_start(esc_cp) : duk_unicode_is_identifier_part(esc_cp))) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\n\t\t\t\t/* Track number of escapes: necessary for proper keyword\n\t\t\t\t * detection.\n\t\t\t\t */\n\t\t\t\tout_token->num_escapes++;\n\t\t\t} else {\n\t\t\t\t/* Note: first character is checked against this.  But because\n\t\t\t\t * IdentifierPart includes all IdentifierStart characters, and\n\t\t\t\t * the first character (if unescaped) has already been checked\n\t\t\t\t * in the if condition, this is OK.\n\t\t\t\t */\n\t\t\t\tif (!duk_unicode_is_identifier_part(DUK__L0())) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, DUK__L0());\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t}\n\t\t\tfirst = 0;\n\t\t}\n\n\t\tout_token->str1 = duk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\t\tstr = out_token->str1;\n\t\tout_token->t_nores = DUK_TOK_IDENTIFIER;\n\n\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\t/*\n\t\t *  Interned identifier is compared against reserved words, which are\n\t\t *  currently interned into the heap context.  See genbuiltins.py.\n\t\t *\n\t\t *  Note that an escape in the identifier disables recognition of\n\t\t *  keywords; e.g. \"\\u0069f = 1;\" is a valid statement (assigns to\n\t\t *  identifier named \"if\").  This is not necessarily compliant,\n\t\t *  see test-dec-escaped-char-in-keyword.js.\n\t\t *\n\t\t *  Note: \"get\" and \"set\" are awkward.  They are not officially\n\t\t *  ReservedWords (and indeed e.g. \"var set = 1;\" is valid), and\n\t\t *  must come out as DUK_TOK_IDENTIFIER.  The compiler needs to\n\t\t *  work around this a bit.\n\t\t */\n\n\t\t/* XXX: optimize by adding the token numbers directly into the\n\t\t * always interned duk_hstring objects (there should be enough\n\t\t * flag bits free for that)?\n\t\t */\n\n\t\ti_end = (strict_mode ? DUK_STRIDX_END_RESERVED : DUK_STRIDX_START_STRICT_RESERVED);\n\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_IDENTIFIER);\n\t\tif (out_token->num_escapes == 0) {\n\t\t\tfor (i = DUK_STRIDX_START_RESERVED; i < i_end; i++) {\n\t\t\t\tDUK_ASSERT_DISABLE(i >= 0);  /* unsigned */\n\t\t\t\tDUK_ASSERT(i < DUK_HEAP_NUM_STRINGS);\n\t\t\t\tif (DUK_HTHREAD_GET_STRING(lex_ctx->thr, i) == str) {\n\t\t\t\t\tadvtok = DUK__ADVTOK(0, DUK_STRIDX_TO_TOK(i));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if (DUK__ISDIGIT(x) || (x == DUK_ASC_PERIOD)) {\n\t\t/* Note: decimal number may start with a period, but must be followed by a digit */\n\n\t\t/*\n\t\t *  Pre-parsing for decimal, hex, octal (both legacy and ES2015),\n\t\t *  and binary literals, followed by an actual parser step\n\t\t *  provided by numconv.\n\t\t *\n\t\t *  Note: the leading sign character ('+' or '-') is -not- part of\n\t\t *  the production in E5 grammar, and that the a DecimalLiteral\n\t\t *  starting with a '0' must be followed by a non-digit.\n\t\t *\n\t\t *  XXX: the two step parsing process is quite awkward, it would\n\t\t *  be more straightforward to allow numconv to parse the longest\n\t\t *  valid prefix (it already does that, it only needs to indicate\n\t\t *  where the input ended).  However, the lexer decodes characters\n\t\t *  using a limited lookup window, so this is not a trivial change.\n\t\t */\n\n\t\t/* XXX: because of the final check below (that the literal is not\n\t\t * followed by a digit), this could maybe be simplified, if we bail\n\t\t * out early from a leading zero (and if there are no periods etc).\n\t\t * Maybe too complex.\n\t\t */\n\n\t\tduk_double_t val;\n\t\tduk_bool_t legacy_oct = 0;\n\t\tduk_small_int_t state;  /* 0=before period/exp,\n\t\t                         * 1=after period, before exp\n\t\t                         * 2=after exp, allow '+' or '-'\n\t\t                         * 3=after exp and exp sign\n\t\t                         */\n\t\tduk_small_uint_t s2n_flags;\n\t\tduk_codepoint_t y, z;\n\t\tduk_small_int_t s2n_radix = 10;\n\t\tduk_small_uint_t pre_adv = 0;\n\n\t\tDUK__INITBUFFER(lex_ctx);\n\t\ty = DUK__L1();\n\n\t\tif (x == DUK_ASC_0) {\n\t\t\tz = DUK_LOWERCASE_CHAR_ASCII(y);\n\n\t\t\tpre_adv = 2;  /* default for 0xNNN, 0oNNN, 0bNNN. */\n\t\t\tif (z == DUK_ASC_LC_X) {\n\t\t\t\ts2n_radix = 16;\n\t\t\t} else if (z == DUK_ASC_LC_O) {\n\t\t\t\ts2n_radix = 8;\n\t\t\t} else if (z == DUK_ASC_LC_B) {\n\t\t\t\ts2n_radix = 2;\n\t\t\t} else {\n\t\t\t\tpre_adv = 0;\n\t\t\t\tif (DUK__ISDIGIT(y)) {\n\t\t\t\t\tif (strict_mode) {\n\t\t\t\t\t\t/* Reject octal like \\07 but also octal-lookalike\n\t\t\t\t\t\t * decimal like \\08 in strict mode.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tgoto fail_number_literal;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t/* Legacy OctalIntegerLiteral or octal-lookalice\n\t\t\t\t\t\t * decimal.  Deciding between the two happens below\n\t\t\t\t\t\t * in digit scanning.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t\t\t\tpre_adv = 1;\n\t\t\t\t\t\tlegacy_oct = 1;\n\t\t\t\t\t\ts2n_radix = 8;  /* tentative unless conflicting digits found */\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tDUK__ADVANCECHARS(lex_ctx, pre_adv);\n\n\t\t/* XXX: we could parse integers here directly, and fall back\n\t\t * to numconv only when encountering a fractional expression\n\t\t * or when an octal literal turned out to be decimal (0778 etc).\n\t\t */\n\t\tstate = 0;\n\t\tfor (;;) {\n\t\t\tx = DUK__L0();  /* re-lookup curr char on first round */\n\t\t\tif (DUK__ISDIGIT(x)) {\n\t\t\t\t/* Note: intentionally allow leading zeroes here, as the\n\t\t\t\t * actual parser will check for them.\n\t\t\t\t */\n\t\t\t\tif (state == 0 && legacy_oct && (x == DUK_ASC_8 || x == DUK_ASC_9)) {\n\t\t\t\t\t/* Started out as an octal-lookalike\n\t\t\t\t\t * but interpreted as decimal, e.g.\n\t\t\t\t\t * '0779' -> 779.  This also means\n\t\t\t\t\t * that fractions are allowed, e.g.\n\t\t\t\t\t * '0779.123' is allowed but '0777.123'\n\t\t\t\t\t * is not!\n\t\t\t\t\t */\n\t\t\t\t\ts2n_radix = 10;\n\t\t\t\t}\n\t\t\t\tif (state == 2) {\n\t\t\t\t\tstate = 3;\n\t\t\t\t}\n\t\t\t} else if (s2n_radix == 16 && DUK__ISHEXDIGIT(x)) {\n\t\t\t\t/* Note: 'e' and 'E' are also accepted here. */\n\t\t\t\t;\n\t\t\t} else if (x == DUK_ASC_PERIOD) {\n\t\t\t\tif (state >= 1 || s2n_radix != 10) {\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tstate = 1;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_LC_E || x == DUK_ASC_UC_E) {\n\t\t\t\tif (state >= 2 || s2n_radix != 10) {\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tstate = 2;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_MINUS || x == DUK_ASC_PLUS) {\n\t\t\t\tif (state != 2) {\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tstate = 3;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t}\n\n\t\t/* XXX: better coercion */\n\t\t(void) duk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\n\t\tif (s2n_radix != 10) {\n\t\t\t/* For bases other than 10, integer only. */\n\t\t\ts2n_flags = DUK_S2N_FLAG_ALLOW_LEADING_ZERO;\n\t\t} else {\n\t\t\ts2n_flags = DUK_S2N_FLAG_ALLOW_EXP |\n\t\t\t            DUK_S2N_FLAG_ALLOW_FRAC |\n\t\t\t            DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t\t\t            DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t\t\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO;\n\t\t}\n\n\t\tduk_dup(lex_ctx->thr, lex_ctx->slot1_idx);\n\t\tduk_numconv_parse(lex_ctx->thr, s2n_radix, s2n_flags);\n\t\tval = duk_to_number_m1(lex_ctx->thr);\n\t\tif (DUK_ISNAN(val)) {\n\t\t\tgoto fail_number_literal;\n\t\t}\n\t\tduk_replace(lex_ctx->thr, lex_ctx->slot1_idx);  /* could also just pop? */\n\n\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\t/* Section 7.8.3 (note): NumericLiteral must be followed by something other than\n\t\t * IdentifierStart or DecimalDigit.\n\t\t */\n\n\t\tif (DUK__ISDIGIT(DUK__L0()) || duk_unicode_is_identifier_start(DUK__L0())) {\n\t\t\tgoto fail_number_literal;\n\t\t}\n\n\t\tout_token->num = val;\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_NUMBER);\n\t} else if (duk_unicode_is_whitespace(DUK__LOOKUP(lex_ctx, 0))) {\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\tgoto restart;\n\t} else if (x < 0) {\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_EOF);\n\t} else {\n\t\tgoto fail_token;\n\t}\n skip_slow_path:\n\n\t/*\n\t *  Shared exit path\n\t */\n\n\tDUK__ADVANCEBYTES(lex_ctx, advtok >> 8);\n\tout_token->t = advtok & 0xff;\n\tif (out_token->t_nores == DUK_TOK_INVALID) {\n\t\tout_token->t_nores = out_token->t;\n\t}\n\tout_token->lineterm = got_lineterm;\n\n\t/* Automatic semicolon insertion is allowed if a token is preceded\n\t * by line terminator(s), or terminates a statement list (right curly\n\t * or EOF).\n\t */\n\tif (got_lineterm || out_token->t == DUK_TOK_RCURLY || out_token->t == DUK_TOK_EOF) {\n\t\tout_token->allow_auto_semi = 1;\n\t} else {\n\t\tout_token->allow_auto_semi = 0;\n\t}\n\n\treturn;\n\n fail_token_limit:\n\tDUK_ERROR_RANGE(lex_ctx->thr, DUK_STR_TOKEN_LIMIT);\n\tDUK_WO_NORETURN(return;);\n\n fail_token:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_TOKEN);\n\tDUK_WO_NORETURN(return;);\n\n fail_number_literal:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_NUMBER_LITERAL);\n\tDUK_WO_NORETURN(return;);\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterm_regexp:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_REGEXP);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterm_comment:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_COMMENT);\n\tDUK_WO_NORETURN(return;);\n\n#if !defined(DUK_USE_REGEXP_SUPPORT)\n fail_regexp_support:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_REGEXP_SUPPORT_DISABLED);\n\tDUK_WO_NORETURN(return;);\n#endif\n}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Parse a RegExp token.  The grammar is described in E5 Section 15.10.\n *  Terminal constructions (such as quantifiers) are parsed directly here.\n *\n *  0xffffffffU is used as a marker for \"infinity\" in quantifiers.  Further,\n *  DUK__MAX_RE_QUANT_DIGITS limits the maximum number of digits that\n *  will be accepted for a quantifier.\n */\n\nDUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token *out_token) {\n\tduk_small_uint_t advtok = 0;  /* init is unnecessary but suppresses \"may be used uninitialized\" warnings */\n\tduk_codepoint_t x, y;\n\n\tif (++lex_ctx->token_count >= lex_ctx->token_limit) {\n\t\tgoto fail_token_limit;\n\t}\n\n\tduk_memzero(out_token, sizeof(*out_token));\n\n\tx = DUK__L0();\n\ty = DUK__L1();\n\n\tDUK_DDD(DUK_DDDPRINT(\"parsing regexp token, L0=%ld, L1=%ld\", (long) x, (long) y));\n\n\tswitch (x) {\n\tcase DUK_ASC_PIPE: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_DISJUNCTION);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_CARET: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ASSERT_START);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_DOLLAR: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ASSERT_END);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_QUESTION: {\n\t\tout_token->qmin = 0;\n\t\tout_token->qmax = 1;\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 0;\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_STAR: {\n\t\tout_token->qmin = 0;\n\t\tout_token->qmax = DUK_RE_QUANTIFIER_INFINITE;\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 0;\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_PLUS: {\n\t\tout_token->qmin = 1;\n\t\tout_token->qmax = DUK_RE_QUANTIFIER_INFINITE;\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 0;\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LCURLY: {\n\t\t/* Production allows 'DecimalDigits', including leading zeroes */\n\t\tduk_uint32_t val1 = 0;\n\t\tduk_uint32_t val2 = DUK_RE_QUANTIFIER_INFINITE;\n\t\tduk_small_int_t digits = 0;\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\tduk_lexer_point lex_pt;\n#endif\n\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t/* Store lexer position, restoring if quantifier is invalid. */\n\t\tDUK_LEXER_GETPOINT(lex_ctx, &lex_pt);\n#endif\n\n\t\tfor (;;) {\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat '{' on entry */\n\t\t\tx = DUK__L0();\n\t\t\tif (DUK__ISDIGIT(x)) {\n\t\t\t\tdigits++;\n\t\t\t\tval1 = val1 * 10 + (duk_uint32_t) duk__hexval(x);\n\t\t\t} else if (x == DUK_ASC_COMMA) {\n\t\t\t\tif (digits > DUK__MAX_RE_QUANT_DIGITS) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (val2 != DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (DUK__L1() == DUK_ASC_RCURLY) {\n\t\t\t\t\t/* form: { DecimalDigits , }, val1 = min count */\n\t\t\t\t\tif (digits == 0) {\n\t\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t\t}\n\t\t\t\t\tout_token->qmin = val1;\n\t\t\t\t\tout_token->qmax = DUK_RE_QUANTIFIER_INFINITE;\n\t\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tval2 = val1;\n\t\t\t\tval1 = 0;\n\t\t\t\tdigits = 0;  /* not strictly necessary because of lookahead '}' above */\n\t\t\t} else if (x == DUK_ASC_RCURLY) {\n\t\t\t\tif (digits > DUK__MAX_RE_QUANT_DIGITS) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (digits == 0) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (val2 != DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\t/* val2 = min count, val1 = max count */\n\t\t\t\t\tout_token->qmin = val2;\n\t\t\t\t\tout_token->qmax = val1;\n\t\t\t\t} else {\n\t\t\t\t\t/* val1 = count */\n\t\t\t\t\tout_token->qmin = val1;\n\t\t\t\t\tout_token->qmax = val1;\n\t\t\t\t}\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tgoto invalid_quantifier;\n\t\t\t}\n\t\t}\n\t\tif (DUK__L0() == DUK_ASC_QUESTION) {\n\t\t\tout_token->greedy = 0;\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t} else {\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tadvtok = DUK__ADVTOK(0, DUK_RETOK_QUANTIFIER);\n\t\tbreak;\n invalid_quantifier:\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t/* Failed to match the quantifier, restore lexer and parse\n\t\t * opening brace as a literal.\n\t\t */\n\t\tDUK_LEXER_SETPOINT(lex_ctx, &lex_pt);\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_CHAR);\n\t\tout_token->num = DUK_ASC_LCURLY;\n#else\n\t\tgoto fail_quantifier;\n#endif\n\t\tbreak;\n\t}\n\tcase DUK_ASC_PERIOD: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_PERIOD);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_BACKSLASH: {\n\t\t/* The E5.1 specification does not seem to allow IdentifierPart characters\n\t\t * to be used as identity escapes.  Unfortunately this includes '$', which\n\t\t * cannot be escaped as '\\$'; it needs to be escaped e.g. as '\\u0024'.\n\t\t * Many other implementations (including V8 and Rhino, for instance) do\n\t\t * accept '\\$' as a valid identity escape, which is quite pragmatic, and\n\t\t * ES2015 Annex B relaxes the rules to allow these (and other) real world forms.\n\t\t */\n\n\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_CHAR);  /* default: char escape (two chars) */\n\t\tif (y == DUK_ASC_LC_B) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ASSERT_WORD_BOUNDARY);\n\t\t} else if (y == DUK_ASC_UC_B) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY);\n\t\t} else if (y == DUK_ASC_LC_F) {\n\t\t\tout_token->num = 0x000c;\n\t\t} else if (y == DUK_ASC_LC_N) {\n\t\t\tout_token->num = 0x000a;\n\t\t} else if (y == DUK_ASC_LC_T) {\n\t\t\tout_token->num = 0x0009;\n\t\t} else if (y == DUK_ASC_LC_R) {\n\t\t\tout_token->num = 0x000d;\n\t\t} else if (y == DUK_ASC_LC_V) {\n\t\t\tout_token->num = 0x000b;\n\t\t} else if (y == DUK_ASC_LC_C) {\n\t\t\tx = DUK__L2();\n\t\t\tif ((x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_Z) ||\n\t\t\t    (x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_Z)) {\n\t\t\t\tout_token->num = (duk_uint32_t) (x % 32);\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ATOM_CHAR);\n\t\t\t} else {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t} else if (y == DUK_ASC_LC_X || y == DUK_ASC_LC_U) {\n\t\t\t/* The token value is the Unicode codepoint without\n\t\t\t * it being decode into surrogate pair characters\n\t\t\t * here.  The \\u{H+} is only allowed in Unicode mode\n\t\t\t * which we don't support yet.\n\t\t\t */\n\t\t\tout_token->num = (duk_uint32_t) duk__lexer_parse_escape(lex_ctx, 0 /*allow_es6*/);\n\t\t\tadvtok = DUK__ADVTOK(0, DUK_RETOK_ATOM_CHAR);\n\t\t} else if (y == DUK_ASC_LC_D) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_DIGIT);\n\t\t} else if (y == DUK_ASC_UC_D) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_NOT_DIGIT);\n\t\t} else if (y == DUK_ASC_LC_S) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_WHITE);\n\t\t} else if (y == DUK_ASC_UC_S) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_NOT_WHITE);\n\t\t} else if (y == DUK_ASC_LC_W) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_WORD_CHAR);\n\t\t} else if (y == DUK_ASC_UC_W) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_NOT_WORD_CHAR);\n\t\t} else if (DUK__ISDIGIT(y)) {\n\t\t\t/* E5 Section 15.10.2.11 */\n\t\t\tif (y == DUK_ASC_0) {\n\t\t\t\tif (DUK__ISDIGIT(DUK__L2())) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t\tout_token->num = 0x0000;\n\t\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_CHAR);\n\t\t\t} else {\n\t\t\t\t/* XXX: shared parsing? */\n\t\t\t\tduk_uint32_t val = 0;\n\t\t\t\tduk_small_int_t i;\n\t\t\t\tfor (i = 0; ; i++) {\n\t\t\t\t\tif (i >= DUK__MAX_RE_DECESC_DIGITS) {\n\t\t\t\t\t\tgoto fail_escape;\n\t\t\t\t\t}\n\t\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat backslash on entry */\n\t\t\t\t\tx = DUK__L0();\n\t\t\t\t\tif (!DUK__ISDIGIT(x)) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tval = val * 10 + (duk_uint32_t) duk__hexval(x);\n\t\t\t\t}\n\t\t\t\t/* DUK__L0() cannot be a digit, because the loop doesn't terminate if it is */\n\t\t\t\tadvtok = DUK__ADVTOK(0, DUK_RETOK_ATOM_BACKREFERENCE);\n\t\t\t\tout_token->num = val;\n\t\t\t}\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t} else if (y >= 0) {\n\t\t\t/* For ES2015 Annex B, accept any source character as identity\n\t\t\t * escape except 'c' which is used for control characters.\n\t\t\t * http://www.ecma-international.org/ecma-262/6.0/#sec-regular-expressions-patterns\n\t\t\t * Careful not to match end-of-buffer (<0) here.\n\t\t\t * This is not yet full ES2015 Annex B because cases above\n\t\t\t * (like hex escape) won't backtrack.\n\t\t\t */\n\t\t\tDUK_ASSERT(y != DUK_ASC_LC_C);  /* covered above */\n#else  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t} else if ((y >= 0 && !duk_unicode_is_identifier_part(y)) ||\n\t\t           y == DUK_UNICODE_CP_ZWNJ ||\n\t\t           y == DUK_UNICODE_CP_ZWJ) {\n\t\t\t/* For ES5.1 identity escapes are not allowed for identifier\n\t\t\t * parts.  This conflicts with a lot of real world code as this\n\t\t\t * doesn't e.g. allow escaping a dollar sign as /\\$/, see\n\t\t\t * test-regexp-identity-escape-dollar.js.\n\t\t\t */\n#endif  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t\tout_token->num = (duk_uint32_t) y;\n\t\t} else {\n\t\t\tgoto fail_escape;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LPAREN: {\n\t\t/* XXX: naming is inconsistent: ATOM_END_GROUP ends an ASSERT_START_LOOKAHEAD */\n\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tif (DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\t\t/* (?= */\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ASSERT_START_POS_LOOKAHEAD);\n\t\t\t} else if (DUK__L2() == DUK_ASC_EXCLAMATION) {\n\t\t\t\t/* (?! */\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD);\n\t\t\t} else if (DUK__L2() == DUK_ASC_COLON) {\n\t\t\t\t/* (?: */\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ATOM_START_NONCAPTURE_GROUP);\n\t\t\t} else {\n\t\t\t\tgoto fail_group;\n\t\t\t}\n\t\t} else {\n\t\t\t/* ( */\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_START_CAPTURE_GROUP);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_RPAREN: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_END_GROUP);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LBRACKET: {\n\t\t/*\n\t\t *  To avoid creating a heavy intermediate value for the list of ranges,\n\t\t *  only the start token ('[' or '[^') is parsed here.  The regexp\n\t\t *  compiler parses the ranges itself.\n\t\t */\n\n\t\t/* XXX: with DUK_USE_ES6_REGEXP_SYNTAX we should allow left bracket\n\t\t * literal too, but it's not easy to parse without backtracking.\n\t\t */\n\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_START_CHARCLASS);\n\t\tif (y == DUK_ASC_CARET) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_START_CHARCLASS_INVERTED);\n\t\t}\n\t\tbreak;\n\t}\n#if !defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\tcase DUK_ASC_RCURLY:\n\tcase DUK_ASC_RBRACKET: {\n\t\t/* Although these could be parsed as PatternCharacters unambiguously (here),\n\t\t * E5 Section 15.10.1 grammar explicitly forbids these as PatternCharacters.\n\t\t */\n\t\tgoto fail_invalid_char;\n\t\tbreak;\n\t}\n#endif\n\tcase -1: {\n\t\t/* EOF */\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_EOF);\n\t\tbreak;\n\t}\n\tdefault: {\n\t\t/* PatternCharacter, all excluded characters are matched by cases above */\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_CHAR);\n\t\tout_token->num = (duk_uint32_t) x;\n\t\tbreak;\n\t}\n\t}\n\n\t/*\n\t *  Shared exit path\n\t */\n\n\tDUK__ADVANCEBYTES(lex_ctx, advtok >> 8);\n\tout_token->t = advtok & 0xff;\n\treturn;\n\n fail_token_limit:\n\tDUK_ERROR_RANGE(lex_ctx->thr, DUK_STR_TOKEN_LIMIT);\n\tDUK_WO_NORETURN(return;);\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_group:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_GROUP);\n\tDUK_WO_NORETURN(return;);\n\n#if !defined(DUK_USE_ES6_REGEXP_SYNTAX)\n fail_invalid_char:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_CHARACTER);\n\tDUK_WO_NORETURN(return;);\n\n fail_quantifier:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_QUANTIFIER);\n\tDUK_WO_NORETURN(return;);\n#endif\n}\n\n/*\n *  Special parser for character classes; calls callback for every\n *  range parsed and returns the number of ranges present.\n */\n\n/* XXX: this duplicates functionality in duk_regexp.c where a similar loop is\n * required anyway.  We could use that BUT we need to update the regexp compiler\n * 'nranges' too.  Work this out a bit more cleanly to save space.\n */\n\n/* XXX: the handling of character range detection is a bit convoluted.\n * Try to simplify and make smaller.\n */\n\n/* XXX: logic for handling character ranges is now incorrect, it will accept\n * e.g. [\\d-z] whereas it should croak from it?  SMJS accepts this too, though.\n *\n * Needs a read through and a lot of additional tests.\n */\n\nDUK_LOCAL\nvoid duk__emit_u16_direct_ranges(duk_lexer_ctx *lex_ctx,\n                                 duk_re_range_callback gen_range,\n                                 void *userdata,\n                                 const duk_uint16_t *ranges,\n                                 duk_small_int_t num) {\n\tconst duk_uint16_t *ranges_end;\n\n\tDUK_UNREF(lex_ctx);\n\n\tranges_end = ranges + num;\n\twhile (ranges < ranges_end) {\n\t\t/* mark range 'direct', bypass canonicalization (see Wiki) */\n\t\tgen_range(userdata, (duk_codepoint_t) ranges[0], (duk_codepoint_t) ranges[1], 1);\n\t\tranges += 2;\n\t}\n}\n\nDUK_INTERNAL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_range_callback gen_range, void *userdata) {\n\tduk_codepoint_t start = -1;\n\tduk_codepoint_t ch;\n\tduk_codepoint_t x;\n\tduk_bool_t dash = 0;\n\tduk_small_uint_t adv = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"parsing regexp ranges\"));\n\n\tfor (;;) {\n\t\tDUK__ADVANCECHARS(lex_ctx, adv);\n\t\tadv = 1;\n\n\t\tx = DUK__L0();\n\n\t\tch = -1;  /* not strictly necessary, but avoids \"uninitialized variable\" warnings */\n\t\tDUK_UNREF(ch);\n\n\t\tif (x < 0) {\n\t\t\tgoto fail_unterm_charclass;\n\t\t} else if (x == DUK_ASC_RBRACKET) {\n\t\t\tif (start >= 0) {\n\t\t\t\tgen_range(userdata, start, start, 0);\n\t\t\t}\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat ']' before finishing */\n\t\t\tbreak;\n\t\t} else if (x == DUK_ASC_MINUS) {\n\t\t\tif (start >= 0 && !dash && DUK__L1() != DUK_ASC_RBRACKET) {\n\t\t\t\t/* '-' as a range indicator */\n\t\t\t\tdash = 1;\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\t/* '-' verbatim */\n\t\t\t\tch = x;\n\t\t\t}\n\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\t/*\n\t\t\t *  The escapes are same as outside a character class, except that \\b has a\n\t\t\t *  different meaning, and \\B and backreferences are prohibited (see E5\n\t\t\t *  Section 15.10.2.19).  However, it's difficult to share code because we\n\t\t\t *  handle e.g. \"\\n\" very differently: here we generate a single character\n\t\t\t *  range for it.\n\t\t\t */\n\n\t\t\t/* XXX: ES2015 surrogate pair handling. */\n\n\t\t\tx = DUK__L1();\n\n\t\t\tadv = 2;\n\n\t\t\tif (x == DUK_ASC_LC_B) {\n\t\t\t\t/* Note: '\\b' in char class is different than outside (assertion),\n\t\t\t\t * '\\B' is not allowed and is caught by the duk_unicode_is_identifier_part()\n\t\t\t\t * check below.\n\t\t\t\t */\n\t\t\t\tch = 0x0008;\n\t\t\t} else if (x == DUK_ASC_LC_F) {\n\t\t\t\tch = 0x000c;\n\t\t\t} else if (x == DUK_ASC_LC_N) {\n\t\t\t\tch = 0x000a;\n\t\t\t} else if (x == DUK_ASC_LC_T) {\n\t\t\t\tch = 0x0009;\n\t\t\t} else if (x == DUK_ASC_LC_R) {\n\t\t\t\tch = 0x000d;\n\t\t\t} else if (x == DUK_ASC_LC_V) {\n\t\t\t\tch = 0x000b;\n\t\t\t} else if (x == DUK_ASC_LC_C) {\n\t\t\t\tx = DUK__L2();\n\t\t\t\tadv = 3;\n\t\t\t\tif ((x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_Z) ||\n\t\t\t\t    (x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_Z)) {\n\t\t\t\t\tch = (x % 32);\n\t\t\t\t} else {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_LC_X || x == DUK_ASC_LC_U) {\n\t\t\t\t/* The \\u{H+} form is only allowed in Unicode mode which\n\t\t\t\t * we don't support yet.\n\t\t\t\t */\n\t\t\t\tch = duk__lexer_parse_escape(lex_ctx, 0 /*allow_es6*/);\n\t\t\t\tadv = 0;\n\t\t\t} else if (x == DUK_ASC_LC_D) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_digit,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_digit) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_UC_D) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_not_digit,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_not_digit) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_LC_S) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_white,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_white) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_UC_S) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_not_white,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_not_white) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_LC_W) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_wordchar,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_wordchar) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_UC_W) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_not_wordchar,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_not_wordchar) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (DUK__ISDIGIT(x)) {\n\t\t\t\t/* DecimalEscape, only \\0 is allowed, no leading\n\t\t\t\t * zeroes are allowed.\n\t\t\t\t *\n\t\t\t\t * ES2015 Annex B also allows (maximal match) legacy\n\t\t\t\t * octal escapes up to \\377 and \\8 and \\9 are\n\t\t\t\t * accepted as literal '8' and '9', also in strict mode.\n\t\t\t\t */\n\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t\t\tch = duk__lexer_parse_legacy_octal(lex_ctx, &adv, 0 /*reject_annex_b*/);\n\t\t\t\tDUK_ASSERT(ch >= 0);  /* no rejections */\n#else\n\t\t\t\tif (x == DUK_ASC_0 && !DUK__ISDIGIT(DUK__L2())) {\n\t\t\t\t\tch = 0x0000;\n\t\t\t\t} else {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n#endif\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t\t} else if (x >= 0) {\n\t\t\t\t/* IdentityEscape: ES2015 Annex B allows almost all\n\t\t\t\t * source characters here.  Match anything except\n\t\t\t\t * EOF here.\n\t\t\t\t */\n\t\t\t\tch = x;\n#else  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t\t} else if (!duk_unicode_is_identifier_part(x)) {\n\t\t\t\t/* IdentityEscape: ES5.1 doesn't allow identity escape\n\t\t\t\t * for identifier part characters, which conflicts with\n\t\t\t\t * some real world code.  For example, it doesn't allow\n\t\t\t\t * /[\\$]/ which is awkward.\n\t\t\t\t */\n\t\t\t\tch = x;\n#endif  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t\t} else {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t} else {\n\t\t\t/* character represents itself */\n\t\t\tch = x;\n\t\t}\n\n\t\t/* ch is a literal character here or -1 if parsed entity was\n\t\t * an escape such as \"\\s\".\n\t\t */\n\n\t\tif (ch < 0) {\n\t\t\t/* multi-character sets not allowed as part of ranges, see\n\t\t\t * E5 Section 15.10.2.15, abstract operation CharacterRange.\n\t\t\t */\n\t\t\tif (start >= 0) {\n\t\t\t\tif (dash) {\n\t\t\t\t\tgoto fail_range;\n\t\t\t\t} else {\n\t\t\t\t\tgen_range(userdata, start, start, 0);\n\t\t\t\t\tstart = -1;\n\t\t\t\t\t/* dash is already 0 */\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (start >= 0) {\n\t\t\t\tif (dash) {\n\t\t\t\t\tif (start > ch) {\n\t\t\t\t\t\tgoto fail_range;\n\t\t\t\t\t}\n\t\t\t\t\tgen_range(userdata, start, ch, 0);\n\t\t\t\t\tstart = -1;\n\t\t\t\t\tdash = 0;\n\t\t\t\t} else {\n\t\t\t\t\tgen_range(userdata, start, start, 0);\n\t\t\t\t\tstart = ch;\n\t\t\t\t\t/* dash is already 0 */\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstart = ch;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn;\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_range:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_RANGE);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterm_charclass:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_CHARCLASS);\n\tDUK_WO_NORETURN(return;);\n}\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_lexer.h",
    "content": "/*\n *  Lexer defines.\n */\n\n#if !defined(DUK_LEXER_H_INCLUDED)\n#define DUK_LEXER_H_INCLUDED\n\ntypedef void (*duk_re_range_callback)(void *user, duk_codepoint_t r1, duk_codepoint_t r2, duk_bool_t direct);\n\n/*\n *  A token is interpreted as any possible production of InputElementDiv\n *  and InputElementRegExp, see E5 Section 7 in its entirety.  Note that\n *  the E5 \"Token\" production does not cover all actual tokens of the\n *  language (which is explicitly stated in the specification, Section 7.5).\n *  Null and boolean literals are defined as part of both ReservedWord\n *  (E5 Section 7.6.1) and Literal (E5 Section 7.8) productions.  Here,\n *  null and boolean values have literal tokens, and are not reserved\n *  words.\n *\n *  Decimal literal negative/positive sign is -not- part of DUK_TOK_NUMBER.\n *  The number tokens always have a non-negative value.  The unary minus\n *  operator in \"-1.0\" is optimized during compilation to yield a single\n *  negative constant.\n *\n *  Token numbering is free except that reserved words are required to be\n *  in a continuous range and in a particular order.  See genstrings.py.\n */\n\n#define DUK_LEXER_INITCTX(ctx)        duk_lexer_initctx((ctx))\n\n#define DUK_LEXER_SETPOINT(ctx,pt)    duk_lexer_setpoint((ctx), (pt))\n\n#define DUK_LEXER_GETPOINT(ctx,pt)    duk_lexer_getpoint((ctx), (pt))\n\n/* Currently 6 characters of lookup are actually needed (duk_lexer.c). */\n#define DUK_LEXER_WINDOW_SIZE                     6\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\n#define DUK_LEXER_BUFFER_SIZE                     64\n#endif\n\n#define DUK_TOK_MINVAL                            0\n\n/* returned after EOF (infinite amount) */\n#define DUK_TOK_EOF                               0\n\n/* identifier names (E5 Section 7.6) */\n#define DUK_TOK_IDENTIFIER                        1\n\n/* reserved words: keywords */\n#define DUK_TOK_START_RESERVED                    2\n#define DUK_TOK_BREAK                             2\n#define DUK_TOK_CASE                              3\n#define DUK_TOK_CATCH                             4\n#define DUK_TOK_CONTINUE                          5\n#define DUK_TOK_DEBUGGER                          6\n#define DUK_TOK_DEFAULT                           7\n#define DUK_TOK_DELETE                            8\n#define DUK_TOK_DO                                9\n#define DUK_TOK_ELSE                              10\n#define DUK_TOK_FINALLY                           11\n#define DUK_TOK_FOR                               12\n#define DUK_TOK_FUNCTION                          13\n#define DUK_TOK_IF                                14\n#define DUK_TOK_IN                                15\n#define DUK_TOK_INSTANCEOF                        16\n#define DUK_TOK_NEW                               17\n#define DUK_TOK_RETURN                            18\n#define DUK_TOK_SWITCH                            19\n#define DUK_TOK_THIS                              20\n#define DUK_TOK_THROW                             21\n#define DUK_TOK_TRY                               22\n#define DUK_TOK_TYPEOF                            23\n#define DUK_TOK_VAR                               24\n#define DUK_TOK_CONST                             25\n#define DUK_TOK_VOID                              26\n#define DUK_TOK_WHILE                             27\n#define DUK_TOK_WITH                              28\n\n/* reserved words: future reserved words */\n#define DUK_TOK_CLASS                             29\n#define DUK_TOK_ENUM                              30\n#define DUK_TOK_EXPORT                            31\n#define DUK_TOK_EXTENDS                           32\n#define DUK_TOK_IMPORT                            33\n#define DUK_TOK_SUPER                             34\n\n/* \"null\", \"true\", and \"false\" are always reserved words.\n * Note that \"get\" and \"set\" are not!\n */\n#define DUK_TOK_NULL                              35\n#define DUK_TOK_TRUE                              36\n#define DUK_TOK_FALSE                             37\n\n/* reserved words: additional future reserved words in strict mode */\n#define DUK_TOK_START_STRICT_RESERVED             38  /* inclusive */\n#define DUK_TOK_IMPLEMENTS                        38\n#define DUK_TOK_INTERFACE                         39\n#define DUK_TOK_LET                               40\n#define DUK_TOK_PACKAGE                           41\n#define DUK_TOK_PRIVATE                           42\n#define DUK_TOK_PROTECTED                         43\n#define DUK_TOK_PUBLIC                            44\n#define DUK_TOK_STATIC                            45\n#define DUK_TOK_YIELD                             46\n\n#define DUK_TOK_END_RESERVED                      47  /* exclusive */\n\n/* \"get\" and \"set\" are tokens but NOT ReservedWords.  They are currently\n * parsed and identifiers and these defines are actually now unused.\n */\n#define DUK_TOK_GET                               47\n#define DUK_TOK_SET                               48\n\n/* punctuators (unlike the spec, also includes \"/\" and \"/=\") */\n#define DUK_TOK_LCURLY                            49\n#define DUK_TOK_RCURLY                            50\n#define DUK_TOK_LBRACKET                          51\n#define DUK_TOK_RBRACKET                          52\n#define DUK_TOK_LPAREN                            53\n#define DUK_TOK_RPAREN                            54\n#define DUK_TOK_PERIOD                            55\n#define DUK_TOK_SEMICOLON                         56\n#define DUK_TOK_COMMA                             57\n#define DUK_TOK_LT                                58\n#define DUK_TOK_GT                                59\n#define DUK_TOK_LE                                60\n#define DUK_TOK_GE                                61\n#define DUK_TOK_EQ                                62\n#define DUK_TOK_NEQ                               63\n#define DUK_TOK_SEQ                               64\n#define DUK_TOK_SNEQ                              65\n#define DUK_TOK_ADD                               66\n#define DUK_TOK_SUB                               67\n#define DUK_TOK_MUL                               68\n#define DUK_TOK_DIV                               69\n#define DUK_TOK_MOD                               70\n#define DUK_TOK_EXP                               71\n#define DUK_TOK_INCREMENT                         72\n#define DUK_TOK_DECREMENT                         73\n#define DUK_TOK_ALSHIFT                           74   /* named \"arithmetic\" because result is signed */\n#define DUK_TOK_ARSHIFT                           75\n#define DUK_TOK_RSHIFT                            76\n#define DUK_TOK_BAND                              77\n#define DUK_TOK_BOR                               78\n#define DUK_TOK_BXOR                              79\n#define DUK_TOK_LNOT                              80\n#define DUK_TOK_BNOT                              81\n#define DUK_TOK_LAND                              82\n#define DUK_TOK_LOR                               83\n#define DUK_TOK_QUESTION                          84\n#define DUK_TOK_COLON                             85\n#define DUK_TOK_EQUALSIGN                         86\n#define DUK_TOK_ADD_EQ                            87\n#define DUK_TOK_SUB_EQ                            88\n#define DUK_TOK_MUL_EQ                            89\n#define DUK_TOK_DIV_EQ                            90\n#define DUK_TOK_MOD_EQ                            91\n#define DUK_TOK_EXP_EQ                            92\n#define DUK_TOK_ALSHIFT_EQ                        93\n#define DUK_TOK_ARSHIFT_EQ                        94\n#define DUK_TOK_RSHIFT_EQ                         95\n#define DUK_TOK_BAND_EQ                           96\n#define DUK_TOK_BOR_EQ                            97\n#define DUK_TOK_BXOR_EQ                           98\n\n/* literals (E5 Section 7.8), except null, true, false, which are treated\n * like reserved words (above).\n */\n#define DUK_TOK_NUMBER                            99\n#define DUK_TOK_STRING                            100\n#define DUK_TOK_REGEXP                            101\n\n#define DUK_TOK_MAXVAL                            101  /* inclusive */\n\n#define DUK_TOK_INVALID                           DUK_SMALL_UINT_MAX\n\n/* Convert heap string index to a token (reserved words) */\n#define DUK_STRIDX_TO_TOK(x)                        ((x) - DUK_STRIDX_START_RESERVED + DUK_TOK_START_RESERVED)\n\n/* Sanity check */\n#if (DUK_TOK_MAXVAL > 255)\n#error DUK_TOK_MAXVAL too large, code assumes it fits into 8 bits\n#endif\n\n/* Sanity checks for string and token defines */\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_BREAK) != DUK_TOK_BREAK)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CASE) != DUK_TOK_CASE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CATCH) != DUK_TOK_CATCH)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CONTINUE) != DUK_TOK_CONTINUE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DEBUGGER) != DUK_TOK_DEBUGGER)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DEFAULT) != DUK_TOK_DEFAULT)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DELETE) != DUK_TOK_DELETE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DO) != DUK_TOK_DO)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_ELSE) != DUK_TOK_ELSE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_FINALLY) != DUK_TOK_FINALLY)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_FOR) != DUK_TOK_FOR)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_LC_FUNCTION) != DUK_TOK_FUNCTION)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IF) != DUK_TOK_IF)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IN) != DUK_TOK_IN)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_INSTANCEOF) != DUK_TOK_INSTANCEOF)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_NEW) != DUK_TOK_NEW)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_RETURN) != DUK_TOK_RETURN)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_SWITCH) != DUK_TOK_SWITCH)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_THIS) != DUK_TOK_THIS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_THROW) != DUK_TOK_THROW)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_TRY) != DUK_TOK_TRY)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_TYPEOF) != DUK_TOK_TYPEOF)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_VAR) != DUK_TOK_VAR)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_VOID) != DUK_TOK_VOID)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_WHILE) != DUK_TOK_WHILE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_WITH) != DUK_TOK_WITH)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CLASS) != DUK_TOK_CLASS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CONST) != DUK_TOK_CONST)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_ENUM) != DUK_TOK_ENUM)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_EXPORT) != DUK_TOK_EXPORT)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_EXTENDS) != DUK_TOK_EXTENDS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IMPORT) != DUK_TOK_IMPORT)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_SUPER) != DUK_TOK_SUPER)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_LC_NULL) != DUK_TOK_NULL)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_TRUE) != DUK_TOK_TRUE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_FALSE) != DUK_TOK_FALSE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IMPLEMENTS) != DUK_TOK_IMPLEMENTS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_INTERFACE) != DUK_TOK_INTERFACE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_LET) != DUK_TOK_LET)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PACKAGE) != DUK_TOK_PACKAGE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PRIVATE) != DUK_TOK_PRIVATE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PROTECTED) != DUK_TOK_PROTECTED)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PUBLIC) != DUK_TOK_PUBLIC)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_STATIC) != DUK_TOK_STATIC)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_YIELD) != DUK_TOK_YIELD)\n#error mismatch in token defines\n#endif\n\n/* Regexp tokens */\n#define DUK_RETOK_EOF                              0\n#define DUK_RETOK_DISJUNCTION                      1\n#define DUK_RETOK_QUANTIFIER                       2\n#define DUK_RETOK_ASSERT_START                     3\n#define DUK_RETOK_ASSERT_END                       4\n#define DUK_RETOK_ASSERT_WORD_BOUNDARY             5\n#define DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY         6\n#define DUK_RETOK_ASSERT_START_POS_LOOKAHEAD       7\n#define DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD       8\n#define DUK_RETOK_ATOM_PERIOD                      9\n#define DUK_RETOK_ATOM_CHAR                        10\n#define DUK_RETOK_ATOM_DIGIT                       11  /* assumptions in regexp compiler */\n#define DUK_RETOK_ATOM_NOT_DIGIT                   12  /* -\"\"- */\n#define DUK_RETOK_ATOM_WHITE                       13  /* -\"\"- */\n#define DUK_RETOK_ATOM_NOT_WHITE                   14  /* -\"\"- */\n#define DUK_RETOK_ATOM_WORD_CHAR                   15  /* -\"\"- */\n#define DUK_RETOK_ATOM_NOT_WORD_CHAR               16  /* -\"\"- */\n#define DUK_RETOK_ATOM_BACKREFERENCE               17\n#define DUK_RETOK_ATOM_START_CAPTURE_GROUP         18\n#define DUK_RETOK_ATOM_START_NONCAPTURE_GROUP      19\n#define DUK_RETOK_ATOM_START_CHARCLASS             20\n#define DUK_RETOK_ATOM_START_CHARCLASS_INVERTED    21\n#define DUK_RETOK_ATOM_END_GROUP                   22\n\n/* Constants for duk_lexer_ctx.buf. */\n#define DUK_LEXER_TEMP_BUF_LIMIT                   256\n\n/* A token value.  Can be memcpy()'d, but note that slot1/slot2 values are on the valstack.\n * Some fields (like num, str1, str2) are only valid for specific token types and may have\n * stale values otherwise.\n */\nstruct duk_token {\n\tduk_small_uint_t t;           /* token type (with reserved word identification) */\n\tduk_small_uint_t t_nores;     /* token type (with reserved words as DUK_TOK_IDENTIFER) */\n\tduk_double_t num;             /* numeric value of token */\n\tduk_hstring *str1;            /* string 1 of token (borrowed, stored to ctx->slot1_idx) */\n\tduk_hstring *str2;            /* string 2 of token (borrowed, stored to ctx->slot2_idx) */\n\tduk_size_t start_offset;      /* start byte offset of token in lexer input */\n\tduk_int_t start_line;         /* start line of token (first char) */\n\tduk_int_t num_escapes;        /* number of escapes and line continuations (for directive prologue) */\n\tduk_bool_t lineterm;          /* token was preceded by a lineterm */\n\tduk_bool_t allow_auto_semi;   /* token allows automatic semicolon insertion (eof or preceded by newline) */\n};\n\n#define DUK_RE_QUANTIFIER_INFINITE         ((duk_uint32_t) 0xffffffffUL)\n\n/* A regexp token value. */\nstruct duk_re_token {\n\tduk_small_uint_t t;          /* token type */\n\tduk_small_uint_t greedy;\n\tduk_uint32_t num;            /* numeric value (character, count) */\n\tduk_uint32_t qmin;\n\tduk_uint32_t qmax;\n};\n\n/* A structure for 'snapshotting' a point for rewinding */\nstruct duk_lexer_point {\n\tduk_size_t offset;\n\tduk_int_t line;\n};\n\n/* Lexer codepoint with additional info like offset/line number */\nstruct duk_lexer_codepoint {\n\tduk_codepoint_t codepoint;\n\tduk_size_t offset;\n\tduk_int_t line;\n};\n\n/* Lexer context.  Same context is used for ECMAScript and Regexp parsing. */\nstruct duk_lexer_ctx {\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\n\tduk_lexer_codepoint *window; /* unicode code points, window[0] is always next, points to 'buffer' */\n\tduk_lexer_codepoint buffer[DUK_LEXER_BUFFER_SIZE];\n#else\n\tduk_lexer_codepoint window[DUK_LEXER_WINDOW_SIZE]; /* unicode code points, window[0] is always next */\n#endif\n\n\tduk_hthread *thr;                              /* thread; minimizes argument passing */\n\n\tconst duk_uint8_t *input;                      /* input string (may be a user pointer) */\n\tduk_size_t input_length;                       /* input byte length */\n\tduk_size_t input_offset;                       /* input offset for window leading edge (not window[0]) */\n\tduk_int_t input_line;                          /* input linenumber at input_offset (not window[0]), init to 1 */\n\n\tduk_idx_t slot1_idx;                           /* valstack slot for 1st token value */\n\tduk_idx_t slot2_idx;                           /* valstack slot for 2nd token value */\n\tduk_idx_t buf_idx;                             /* valstack slot for temp buffer */\n\tduk_hbuffer_dynamic *buf;                      /* temp accumulation buffer */\n\tduk_bufwriter_ctx bw;                          /* bufwriter for temp accumulation */\n\n\tduk_int_t token_count;                         /* number of tokens parsed */\n\tduk_int_t token_limit;                         /* maximum token count before error (sanity backstop) */\n\n\tduk_small_uint_t flags;                        /* lexer flags, use compiler flag defines for now */\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_lexer_initctx(duk_lexer_ctx *lex_ctx);\n\nDUK_INTERNAL_DECL void duk_lexer_getpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt);\nDUK_INTERNAL_DECL void duk_lexer_setpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt);\n\nDUK_INTERNAL_DECL\nvoid duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,\n                                      duk_token *out_token,\n                                      duk_bool_t strict_mode,\n                                      duk_bool_t regexp_mode);\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL_DECL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token *out_token);\nDUK_INTERNAL_DECL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_range_callback gen_range, void *userdata);\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n#endif  /* DUK_LEXER_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_numconv.c",
    "content": "/*\n *  Number-to-string and string-to-number conversions.\n *\n *  Slow path number-to-string and string-to-number conversion is based on\n *  a Dragon4 variant, with fast paths for small integers.  Big integer\n *  arithmetic is needed for guaranteeing that the conversion is correct\n *  and uses a minimum number of digits.  The big number arithmetic has a\n *  fixed maximum size and does not require dynamic allocations.\n *\n *  See: doc/number-conversion.rst.\n */\n\n#include \"duk_internal.h\"\n\n#define DUK__IEEE_DOUBLE_EXP_BIAS  1023\n#define DUK__IEEE_DOUBLE_EXP_MIN   (-1022)   /* biased exp == 0 -> denormal, exp -1022 */\n\n#define DUK__DIGITCHAR(x)  duk_lc_digits[(x)]\n\n/*\n *  Tables generated with util/gennumdigits.py.\n *\n *  duk__str2num_digits_for_radix indicates, for each radix, how many input\n *  digits should be considered significant for string-to-number conversion.\n *  The input is also padded to this many digits to give the Dragon4\n *  conversion enough (apparent) precision to work with.\n *\n *  duk__str2num_exp_limits indicates, for each radix, the radix-specific\n *  minimum/maximum exponent values (for a Dragon4 integer mantissa)\n *  below and above which the number is guaranteed to underflow to zero\n *  or overflow to Infinity.  This allows parsing to keep bigint values\n *  bounded.\n */\n\nDUK_LOCAL const duk_uint8_t duk__str2num_digits_for_radix[] = {\n\t69, 44, 35, 30, 27, 25, 23, 22, 20, 20,    /* 2 to 11 */\n\t20, 19, 19, 18, 18, 17, 17, 17, 16, 16,    /* 12 to 21 */\n\t16, 16, 16, 15, 15, 15, 15, 15, 15, 14,    /* 22 to 31 */\n\t14, 14, 14, 14, 14                         /* 31 to 36 */\n};\n\ntypedef struct {\n\tduk_int16_t upper;\n\tduk_int16_t lower;\n} duk__exp_limits;\n\nDUK_LOCAL const duk__exp_limits duk__str2num_exp_limits[] = {\n\t{ 957, -1147 }, { 605, -725 },  { 479, -575 },  { 414, -496 },\n\t{ 372, -446 },  { 342, -411 },  { 321, -384 },  { 304, -364 },\n\t{ 291, -346 },  { 279, -334 },  { 268, -323 },  { 260, -312 },\n\t{ 252, -304 },  { 247, -296 },  { 240, -289 },  { 236, -283 },\n\t{ 231, -278 },  { 227, -273 },  { 223, -267 },  { 220, -263 },\n\t{ 216, -260 },  { 213, -256 },  { 210, -253 },  { 208, -249 },\n\t{ 205, -246 },  { 203, -244 },  { 201, -241 },  { 198, -239 },\n\t{ 196, -237 },  { 195, -234 },  { 193, -232 },  { 191, -230 },\n\t{ 190, -228 },  { 188, -226 },  { 187, -225 },\n};\n\n/*\n *  Limited functionality bigint implementation.\n *\n *  Restricted to non-negative numbers with less than 32 * DUK__BI_MAX_PARTS bits,\n *  with the caller responsible for ensuring this is never exceeded.  No memory\n *  allocation (except stack) is needed for bigint computation.  Operations\n *  have been tailored for number conversion needs.\n *\n *  Argument order is \"assignment order\", i.e. target first, then arguments:\n *  x <- y * z  -->  duk__bi_mul(x, y, z);\n */\n\n/* This upper value has been experimentally determined; debug build will check\n * bigint size with assertions.\n */\n#define DUK__BI_MAX_PARTS  37  /* 37x32 = 1184 bits */\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK__BI_PRINT(name,x)  duk__bi_print((name),(x))\n#else\n#define DUK__BI_PRINT(name,x)\n#endif\n\n/* Current size is about 152 bytes. */\ntypedef struct {\n\tduk_small_int_t n;\n\tduk_uint32_t v[DUK__BI_MAX_PARTS];  /* low to high */\n} duk__bigint;\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\nDUK_LOCAL void duk__bi_print(const char *name, duk__bigint *x) {\n\t/* Overestimate required size; debug code so not critical to be tight. */\n\tchar buf[DUK__BI_MAX_PARTS * 9 + 64];\n\tchar *p = buf;\n\tduk_small_int_t i;\n\n\t/* No NUL term checks in this debug code. */\n\tp += DUK_SPRINTF(p, \"%p n=%ld\", (void *) x, (long) x->n);\n\tif (x->n == 0) {\n\t\tp += DUK_SPRINTF(p, \" 0\");\n\t}\n\tfor (i = x->n - 1; i >= 0; i--) {\n\t\tp += DUK_SPRINTF(p, \" %08lx\", (unsigned long) x->v[i]);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"%s: %s\", (const char *) name, (const char *) buf));\n}\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_LOCAL duk_small_int_t duk__bi_is_valid(duk__bigint *x) {\n\treturn (duk_small_int_t)\n\t       ( ((x->n >= 0) && (x->n <= DUK__BI_MAX_PARTS)) /* is valid size */ &&\n\t         ((x->n == 0) || (x->v[x->n - 1] != 0)) /* is normalized */ );\n}\n#endif\n\nDUK_LOCAL void duk__bi_normalize(duk__bigint *x) {\n\tduk_small_int_t i;\n\n\tfor (i = x->n - 1; i >= 0; i--) {\n\t\tif (x->v[i] != 0) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* Note: if 'x' is zero, x->n becomes 0 here */\n\tx->n = i + 1;\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* x <- y */\nDUK_LOCAL void duk__bi_copy(duk__bigint *x, duk__bigint *y) {\n\tduk_small_int_t n;\n\n\tn = y->n;\n\tx->n = n;\n\t/* No need to special case n == 0. */\n\tduk_memcpy((void *) x->v, (const void *) y->v, (size_t) (sizeof(duk_uint32_t) * (size_t) n));\n}\n\nDUK_LOCAL void duk__bi_set_small(duk__bigint *x, duk_uint32_t v) {\n\tif (v == 0U) {\n\t\tx->n = 0;\n\t} else {\n\t\tx->n = 1;\n\t\tx->v[0] = v;\n\t}\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* Return value: <0  <=>  x < y\n *                0  <=>  x == y\n *               >0  <=>  x > y\n */\nDUK_LOCAL int duk__bi_compare(duk__bigint *x, duk__bigint *y) {\n\tduk_small_int_t i, nx, ny;\n\tduk_uint32_t tx, ty;\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\tnx = x->n;\n\tny = y->n;\n\tif (nx > ny) {\n\t\tgoto ret_gt;\n\t}\n\tif (nx < ny) {\n\t\tgoto ret_lt;\n\t}\n\tfor (i = nx - 1; i >= 0; i--) {\n\t\ttx = x->v[i];\n\t\tty = y->v[i];\n\n\t\tif (tx > ty) {\n\t\t\tgoto ret_gt;\n\t\t}\n\t\tif (tx < ty) {\n\t\t\tgoto ret_lt;\n\t\t}\n\t}\n\n\treturn 0;\n\n ret_gt:\n\treturn 1;\n\n ret_lt:\n\treturn -1;\n}\n\n/* x <- y + z */\n#if defined(DUK_USE_64BIT_OPS)\nDUK_LOCAL void duk__bi_add(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_uint64_t tmp;\n\tduk_small_int_t i, ny, nz;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\n\tif (z->n > y->n) {\n\t\tduk__bigint *t;\n\t\tt = y; y = z; z = t;\n\t}\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\ttmp = 0U;\n\tfor (i = 0; i < ny; i++) {\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\ttmp += y->v[i];\n\t\tif (i < nz) {\n\t\t\ttmp += z->v[i];\n\t\t}\n\t\tx->v[i] = (duk_uint32_t) (tmp & 0xffffffffUL);\n\t\ttmp = tmp >> 32;\n\t}\n\tif (tmp != 0U) {\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\tx->v[i++] = (duk_uint32_t) tmp;\n\t}\n\tx->n = i;\n\tDUK_ASSERT(x->n <= DUK__BI_MAX_PARTS);\n\n\t/* no need to normalize */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#else  /* DUK_USE_64BIT_OPS */\nDUK_LOCAL void duk__bi_add(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_uint32_t carry, tmp1, tmp2;\n\tduk_small_int_t i, ny, nz;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\n\tif (z->n > y->n) {\n\t\tduk__bigint *t;\n\t\tt = y; y = z; z = t;\n\t}\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\tcarry = 0U;\n\tfor (i = 0; i < ny; i++) {\n\t\t/* Carry is detected based on wrapping which relies on exact 32-bit\n\t\t * types.\n\t\t */\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\ttmp1 = y->v[i];\n\t\ttmp2 = tmp1;\n\t\tif (i < nz) {\n\t\t\ttmp2 += z->v[i];\n\t\t}\n\n\t\t/* Careful with carry condition:\n\t\t *  - If carry not added: 0x12345678 + 0 + 0xffffffff = 0x12345677 (< 0x12345678)\n\t\t *  - If carry added:     0x12345678 + 1 + 0xffffffff = 0x12345678 (== 0x12345678)\n\t\t */\n\t\tif (carry) {\n\t\t\ttmp2++;\n\t\t\tcarry = (tmp2 <= tmp1 ? 1U : 0U);\n\t\t} else {\n\t\t\tcarry = (tmp2 < tmp1 ? 1U : 0U);\n\t\t}\n\n\t\tx->v[i] = tmp2;\n\t}\n\tif (carry) {\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\tDUK_ASSERT(carry == 1U);\n\t\tx->v[i++] = carry;\n\t}\n\tx->n = i;\n\tDUK_ASSERT(x->n <= DUK__BI_MAX_PARTS);\n\n\t/* no need to normalize */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#endif  /* DUK_USE_64BIT_OPS */\n\n/* x <- y + z */\nDUK_LOCAL void duk__bi_add_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) {\n\tduk__bigint tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\t/* XXX: this could be optimized; there is only one call site now though */\n\tduk__bi_set_small(&tmp, z);\n\tduk__bi_add(x, y, &tmp);\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n#if 0  /* unused */\n/* x <- x + y, use t as temp */\nDUK_LOCAL void duk__bi_add_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) {\n\tduk__bi_add(t, x, y);\n\tduk__bi_copy(x, t);\n}\n#endif\n\n/* x <- y - z, require x >= y => z >= 0, i.e. y >= z */\n#if defined(DUK_USE_64BIT_OPS)\nDUK_LOCAL void duk__bi_sub(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_small_int_t i, ny, nz;\n\tduk_uint32_t ty, tz;\n\tduk_int64_t tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\tDUK_ASSERT(duk__bi_compare(y, z) >= 0);\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\ttmp = 0;\n\tfor (i = 0; i < ny; i++) {\n\t\tty = y->v[i];\n\t\tif (i < nz) {\n\t\t\ttz = z->v[i];\n\t\t} else {\n\t\t\ttz = 0;\n\t\t}\n\t\ttmp = (duk_int64_t) ty - (duk_int64_t) tz + tmp;\n\t\tx->v[i] = (duk_uint32_t) ((duk_uint64_t) tmp & 0xffffffffUL);\n\t\ttmp = tmp >> 32;  /* 0 or -1 */\n\t}\n\tDUK_ASSERT(tmp == 0);\n\n\tx->n = i;\n\tduk__bi_normalize(x);  /* need to normalize, may even cancel to 0 */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#else\nDUK_LOCAL void duk__bi_sub(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_small_int_t i, ny, nz;\n\tduk_uint32_t tmp1, tmp2, borrow;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\tDUK_ASSERT(duk__bi_compare(y, z) >= 0);\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\tborrow = 0U;\n\tfor (i = 0; i < ny; i++) {\n\t\t/* Borrow is detected based on wrapping which relies on exact 32-bit\n\t\t * types.\n\t\t */\n\t\ttmp1 = y->v[i];\n\t\ttmp2 = tmp1;\n\t\tif (i < nz) {\n\t\t\ttmp2 -= z->v[i];\n\t\t}\n\n\t\t/* Careful with borrow condition:\n\t\t *  - If borrow not subtracted: 0x12345678 - 0 - 0xffffffff = 0x12345679 (> 0x12345678)\n\t\t *  - If borrow subtracted:     0x12345678 - 1 - 0xffffffff = 0x12345678 (== 0x12345678)\n\t\t */\n\t\tif (borrow) {\n\t\t\ttmp2--;\n\t\t\tborrow = (tmp2 >= tmp1 ? 1U : 0U);\n\t\t} else {\n\t\t\tborrow = (tmp2 > tmp1 ? 1U : 0U);\n\t\t}\n\n\t\tx->v[i] = tmp2;\n\t}\n\tDUK_ASSERT(borrow == 0U);\n\n\tx->n = i;\n\tduk__bi_normalize(x);  /* need to normalize, may even cancel to 0 */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#endif\n\n#if 0  /* unused */\n/* x <- y - z */\nDUK_LOCAL void duk__bi_sub_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) {\n\tduk__bigint tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\t/* XXX: this could be optimized */\n\tduk__bi_set_small(&tmp, z);\n\tduk__bi_sub(x, y, &tmp);\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#endif\n\n/* x <- x - y, use t as temp */\nDUK_LOCAL void duk__bi_sub_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) {\n\tduk__bi_sub(t, x, y);\n\tduk__bi_copy(x, t);\n}\n\n/* x <- y * z */\nDUK_LOCAL void duk__bi_mul(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_small_int_t i, j, nx, nz;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\n\tnx = y->n + z->n;  /* max possible */\n\tDUK_ASSERT(nx <= DUK__BI_MAX_PARTS);\n\n\tif (nx == 0) {\n\t\t/* Both inputs are zero; cases where only one is zero can go\n\t\t * through main algorithm.\n\t\t */\n\t\tx->n = 0;\n\t\treturn;\n\t}\n\n\tduk_memzero((void *) x->v, (size_t) (sizeof(duk_uint32_t) * (size_t) nx));\n\tx->n = nx;\n\n\tnz = z->n;\n\tfor (i = 0; i < y->n; i++) {\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_uint64_t tmp = 0U;\n\t\tfor (j = 0; j < nz; j++) {\n\t\t\ttmp += (duk_uint64_t) y->v[i] * (duk_uint64_t) z->v[j] + x->v[i+j];\n\t\t\tx->v[i+j] = (duk_uint32_t) (tmp & 0xffffffffUL);\n\t\t\ttmp = tmp >> 32;\n\t\t}\n\t\tif (tmp > 0) {\n\t\t\tDUK_ASSERT(i + j < nx);\n\t\t\tDUK_ASSERT(i + j < DUK__BI_MAX_PARTS);\n\t\t\tDUK_ASSERT(x->v[i+j] == 0U);\n\t\t\tx->v[i+j] = (duk_uint32_t) tmp;\n\t\t}\n#else\n\t\t/*\n\t\t *  Multiply + add + carry for 32-bit components using only 16x16->32\n\t\t *  multiplies and carry detection based on unsigned overflow.\n\t\t *\n\t\t *    1st mult, 32-bit: (A*2^16 + B)\n\t\t *    2nd mult, 32-bit: (C*2^16 + D)\n\t\t *    3rd add, 32-bit: E\n\t\t *    4th add, 32-bit: F\n\t\t *\n\t\t *      (AC*2^16 + B) * (C*2^16 + D) + E + F\n\t\t *    = AC*2^32 + AD*2^16 + BC*2^16 + BD + E + F\n\t\t *    = AC*2^32 + (AD + BC)*2^16 + (BD + E + F)\n\t\t *    = AC*2^32 + AD*2^16 + BC*2^16 + (BD + E + F)\n\t\t */\n\t\tduk_uint32_t a, b, c, d, e, f;\n\t\tduk_uint32_t r, s, t;\n\n\t\ta = y->v[i]; b = a & 0xffffUL; a = a >> 16;\n\n\t\tf = 0;\n\t\tfor (j = 0; j < nz; j++) {\n\t\t\tc = z->v[j]; d = c & 0xffffUL; c = c >> 16;\n\t\t\te = x->v[i+j];\n\n\t\t\t/* build result as: (r << 32) + s: start with (BD + E + F) */\n\t\t\tr = 0;\n\t\t\ts = b * d;\n\n\t\t\t/* add E */\n\t\t\tt = s + e;\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add F */\n\t\t\tt = s + f;\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add BC*2^16 */\n\t\t\tt = b * c;\n\t\t\tr += (t >> 16);\n\t\t\tt = s + ((t & 0xffffUL) << 16);\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add AD*2^16 */\n\t\t\tt = a * d;\n\t\t\tr += (t >> 16);\n\t\t\tt = s + ((t & 0xffffUL) << 16);\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add AC*2^32 */\n\t\t\tt = a * c;\n\t\t\tr += t;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"ab=%08lx cd=%08lx ef=%08lx -> rs=%08lx %08lx\",\n\t\t\t                     (unsigned long) y->v[i], (unsigned long) z->v[j],\n\t\t\t                     (unsigned long) x->v[i+j], (unsigned long) r,\n\t\t\t                     (unsigned long) s));\n\n\t\t\tx->v[i+j] = s;\n\t\t\tf = r;\n\t\t}\n\t\tif (f > 0U) {\n\t\t\tDUK_ASSERT(i + j < nx);\n\t\t\tDUK_ASSERT(i + j < DUK__BI_MAX_PARTS);\n\t\t\tDUK_ASSERT(x->v[i+j] == 0U);\n\t\t\tx->v[i+j] = (duk_uint32_t) f;\n\t\t}\n#endif  /* DUK_USE_64BIT_OPS */\n\t}\n\n\tduk__bi_normalize(x);\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* x <- y * z */\nDUK_LOCAL void duk__bi_mul_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) {\n\tduk__bigint tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\t/* XXX: this could be optimized */\n\tduk__bi_set_small(&tmp, z);\n\tduk__bi_mul(x, y, &tmp);\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* x <- x * y, use t as temp */\nDUK_LOCAL void duk__bi_mul_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) {\n\tduk__bi_mul(t, x, y);\n\tduk__bi_copy(x, t);\n}\n\n/* x <- x * y, use t as temp */\nDUK_LOCAL void duk__bi_mul_small_copy(duk__bigint *x, duk_uint32_t y, duk__bigint *t) {\n\tduk__bi_mul_small(t, x, y);\n\tduk__bi_copy(x, t);\n}\n\nDUK_LOCAL int duk__bi_is_even(duk__bigint *x) {\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\treturn (x->n == 0) || ((x->v[0] & 0x01) == 0);\n}\n\nDUK_LOCAL int duk__bi_is_zero(duk__bigint *x) {\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\treturn (x->n == 0);  /* this is the case for normalized numbers */\n}\n\n/* Bigint is 2^52.  Used to detect normalized IEEE double mantissa values\n * which are at the lowest edge (next floating point value downwards has\n * a different exponent).  The lowest mantissa has the form:\n *\n *     1000........000    (52 zeroes; only \"hidden bit\" is set)\n */\nDUK_LOCAL duk_small_int_t duk__bi_is_2to52(duk__bigint *x) {\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\treturn (duk_small_int_t)\n\t        (x->n == 2) && (x->v[0] == 0U) && (x->v[1] == (1U << (52-32)));\n}\n\n/* x <- (1<<y) */\nDUK_LOCAL void duk__bi_twoexp(duk__bigint *x, duk_small_int_t y) {\n\tduk_small_int_t n, r;\n\n\tn = (y / 32) + 1;\n\tDUK_ASSERT(n > 0);\n\tr = y % 32;\n\tduk_memzero((void *) x->v, sizeof(duk_uint32_t) * (size_t) n);\n\tx->n = n;\n\tx->v[n - 1] = (((duk_uint32_t) 1) << r);\n}\n\n/* x <- b^y; use t1 and t2 as temps */\nDUK_LOCAL void duk__bi_exp_small(duk__bigint *x, duk_small_int_t b, duk_small_int_t y, duk__bigint *t1, duk__bigint *t2) {\n\t/* Fast path the binary case */\n\n\tDUK_ASSERT(x != t1 && x != t2 && t1 != t2);  /* distinct bignums, easy mistake to make */\n\tDUK_ASSERT(b >= 0);\n\tDUK_ASSERT(y >= 0);\n\n\tif (b == 2) {\n\t\tduk__bi_twoexp(x, y);\n\t\treturn;\n\t}\n\n\t/* http://en.wikipedia.org/wiki/Exponentiation_by_squaring */\n\n\tDUK_DDD(DUK_DDDPRINT(\"exp_small: b=%ld, y=%ld\", (long) b, (long) y));\n\n\tduk__bi_set_small(x, 1);\n\tduk__bi_set_small(t1, (duk_uint32_t) b);\n\tfor (;;) {\n\t\t/* Loop structure ensures that we don't compute t1^2 unnecessarily\n\t\t * on the final round, as that might create a bignum exceeding the\n\t\t * current DUK__BI_MAX_PARTS limit.\n\t\t */\n\t\tif (y & 0x01) {\n\t\t\tduk__bi_mul_copy(x, t1, t2);\n\t\t}\n\t\ty = y >> 1;\n\t\tif (y == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tduk__bi_mul_copy(t1, t1, t2);\n\t}\n\n\tDUK__BI_PRINT(\"exp_small result\", x);\n}\n\n/*\n *  A Dragon4 number-to-string variant, based on:\n *\n *    Guy L. Steele Jr., Jon L. White: \"How to Print Floating-Point Numbers\n *    Accurately\"\n *\n *    Robert G. Burger, R. Kent Dybvig: \"Printing Floating-Point Numbers\n *    Quickly and Accurately\"\n *\n *  The current algorithm is based on Figure 1 of the Burger-Dybvig paper,\n *  i.e. the base implementation without logarithm estimation speedups\n *  (these would increase code footprint considerably).  Fixed-format output\n *  does not follow the suggestions in the paper; instead, we generate an\n *  extra digit and round-with-carry.\n *\n *  The same algorithm is used for number parsing (with b=10 and B=2)\n *  by generating one extra digit and doing rounding manually.\n *\n *  See doc/number-conversion.rst for limitations.\n */\n\n/* Maximum number of digits generated. */\n#define DUK__MAX_OUTPUT_DIGITS          1040  /* (Number.MAX_VALUE).toString(2).length == 1024, + slack */\n\n/* Maximum number of characters in formatted value. */\n#define DUK__MAX_FORMATTED_LENGTH       1040  /* (-Number.MAX_VALUE).toString(2).length == 1025, + slack */\n\n/* Number and (minimum) size of bigints in the nc_ctx structure. */\n#define DUK__NUMCONV_CTX_NUM_BIGINTS    7\n#define DUK__NUMCONV_CTX_BIGINTS_SIZE   (sizeof(duk__bigint) * DUK__NUMCONV_CTX_NUM_BIGINTS)\n\ntypedef struct {\n\t/* Currently about 7*152 = 1064 bytes.  The space for these\n\t * duk__bigints is used also as a temporary buffer for generating\n\t * the final string.  This is a bit awkard; a union would be\n\t * more correct.\n\t */\n\tduk__bigint f, r, s, mp, mm, t1, t2;\n\n\tduk_small_int_t is_s2n;        /* if 1, doing a string-to-number; else doing a number-to-string */\n\tduk_small_int_t is_fixed;      /* if 1, doing a fixed format output (not free format) */\n\tduk_small_int_t req_digits;    /* requested number of output digits; 0 = free-format */\n\tduk_small_int_t abs_pos;       /* digit position is absolute, not relative */\n\tduk_small_int_t e;             /* exponent for 'f' */\n\tduk_small_int_t b;             /* input radix */\n\tduk_small_int_t B;             /* output radix */\n\tduk_small_int_t k;             /* see algorithm */\n\tduk_small_int_t low_ok;        /* see algorithm */\n\tduk_small_int_t high_ok;       /* see algorithm */\n\tduk_small_int_t unequal_gaps;  /* m+ != m- (very rarely) */\n\n\t/* Buffer used for generated digits, values are in the range [0,B-1]. */\n\tduk_uint8_t digits[DUK__MAX_OUTPUT_DIGITS];\n\tduk_small_int_t count;  /* digit count */\n} duk__numconv_stringify_ctx;\n\n/* Note: computes with 'idx' in assertions, so caller beware.\n * 'idx' is preincremented, i.e. '1' on first call, because it\n * is more convenient for the caller.\n */\n#define DUK__DRAGON4_OUTPUT_PREINC(nc_ctx,preinc_idx,x)  do { \\\n\t\tDUK_ASSERT((preinc_idx) - 1 >= 0); \\\n\t\tDUK_ASSERT((preinc_idx) - 1 < DUK__MAX_OUTPUT_DIGITS); \\\n\t\t((nc_ctx)->digits[(preinc_idx) - 1]) = (duk_uint8_t) (x); \\\n\t} while (0)\n\nDUK_LOCAL duk_size_t duk__dragon4_format_uint32(duk_uint8_t *buf, duk_uint32_t x, duk_small_int_t radix) {\n\tduk_uint8_t *p;\n\tduk_size_t len;\n\tduk_small_int_t dig;\n\tduk_uint32_t t;\n\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(radix >= 2 && radix <= 36);\n\n\t/* A 32-bit unsigned integer formats to at most 32 digits (the\n\t * worst case happens with radix == 2).  Output the digits backwards,\n\t * and use a memmove() to get them in the right place.\n\t */\n\n\tp = buf + 32;\n\tfor (;;) {\n\t\tt = x / (duk_uint32_t) radix;\n\t\tdig = (duk_small_int_t) (x - t * (duk_uint32_t) radix);\n\t\tx = t;\n\n\t\tDUK_ASSERT(dig >= 0 && dig < 36);\n\t\t*(--p) = DUK__DIGITCHAR(dig);\n\n\t\tif (x == 0) {\n\t\t\tbreak;\n\t\t}\n\t}\n\tlen = (duk_size_t) ((buf + 32) - p);\n\n\tduk_memmove((void *) buf, (const void *) p, (size_t) len);\n\n\treturn len;\n}\n\nDUK_LOCAL void duk__dragon4_prepare(duk__numconv_stringify_ctx *nc_ctx) {\n\tduk_small_int_t lowest_mantissa;\n\n#if 1\n\t/* Assume IEEE round-to-even, so that shorter encoding can be used\n\t * when round-to-even would produce correct result.  By removing\n\t * this check (and having low_ok == high_ok == 0) the results would\n\t * still be accurate but in some cases longer than necessary.\n\t */\n\tif (duk__bi_is_even(&nc_ctx->f)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"f is even\"));\n\t\tnc_ctx->low_ok = 1;\n\t\tnc_ctx->high_ok = 1;\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"f is odd\"));\n\t\tnc_ctx->low_ok = 0;\n\t\tnc_ctx->high_ok = 0;\n\t}\n#else\n\t/* Note: not honoring round-to-even should work but now generates incorrect\n\t * results.  For instance, 1e23 serializes to \"a000...\", i.e. the first digit\n\t * equals the radix (10).  Scaling stops one step too early in this case.\n\t * Don't know why this is the case, but since this code path is unused, it\n\t * doesn't matter.\n\t */\n\tnc_ctx->low_ok = 0;\n\tnc_ctx->high_ok = 0;\n#endif\n\n\t/* For string-to-number, pretend we never have the lowest mantissa as there\n\t * is no natural \"precision\" for inputs.  Having lowest_mantissa == 0, we'll\n\t * fall into the base cases for both e >= 0 and e < 0.\n\t */\n\tif (nc_ctx->is_s2n) {\n\t\tlowest_mantissa = 0;\n\t} else {\n\t\tlowest_mantissa = duk__bi_is_2to52(&nc_ctx->f);\n\t}\n\n\tnc_ctx->unequal_gaps = 0;\n\tif (nc_ctx->e >= 0) {\n\t\t/* exponent non-negative (and thus not minimum exponent) */\n\n\t\tif (lowest_mantissa) {\n\t\t\t/* (>= e 0) AND (= f (expt b (- p 1)))\n\t\t\t *\n\t\t\t * be <- (expt b e) == b^e\n\t\t\t * be1 <- (* be b) == (expt b (+ e 1)) == b^(e+1)\n\t\t\t * r <- (* f be1 2) == 2 * f * b^(e+1)    [if b==2 -> f * b^(e+2)]\n\t\t\t * s <- (* b 2)                           [if b==2 -> 4]\n\t\t\t * m+ <- be1 == b^(e+1)\n\t\t\t * m- <- be == b^e\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-negative exponent (not smallest exponent); \"\n\t\t\t                     \"lowest mantissa value for this exponent -> \"\n\t\t\t                     \"unequal gaps\"));\n\n\t\t\tduk__bi_exp_small(&nc_ctx->mm, nc_ctx->b, nc_ctx->e, &nc_ctx->t1, &nc_ctx->t2);  /* mm <- b^e */\n\t\t\tduk__bi_mul_small(&nc_ctx->mp, &nc_ctx->mm, (duk_uint32_t) nc_ctx->b);           /* mp <- b^(e+1) */\n\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, 2);\n\t\t\tduk__bi_mul(&nc_ctx->r, &nc_ctx->t1, &nc_ctx->mp);              /* r <- (2 * f) * b^(e+1) */\n\t\t\tduk__bi_set_small(&nc_ctx->s, (duk_uint32_t) (nc_ctx->b * 2));  /* s <- 2 * b */\n\t\t\tnc_ctx->unequal_gaps = 1;\n\t\t} else {\n\t\t\t/* (>= e 0) AND (not (= f (expt b (- p 1))))\n\t\t\t *\n\t\t\t * be <- (expt b e) == b^e\n\t\t\t * r <- (* f be 2) == 2 * f * b^e    [if b==2 -> f * b^(e+1)]\n\t\t\t * s <- 2\n\t\t\t * m+ <- be == b^e\n\t\t\t * m- <- be == b^e\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-negative exponent (not smallest exponent); \"\n\t\t\t                     \"not lowest mantissa for this exponent -> \"\n\t\t\t                     \"equal gaps\"));\n\n\t\t\tduk__bi_exp_small(&nc_ctx->mm, nc_ctx->b, nc_ctx->e, &nc_ctx->t1, &nc_ctx->t2);  /* mm <- b^e */\n\t\t\tduk__bi_copy(&nc_ctx->mp, &nc_ctx->mm);                /* mp <- b^e */\n\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, 2);\n\t\t\tduk__bi_mul(&nc_ctx->r, &nc_ctx->t1, &nc_ctx->mp);     /* r <- (2 * f) * b^e */\n\t\t\tduk__bi_set_small(&nc_ctx->s, 2);                      /* s <- 2 */\n\t\t}\n\t} else {\n\t\t/* When doing string-to-number, lowest_mantissa is always 0 so\n\t\t * the exponent check, while incorrect, won't matter.\n\t\t */\n\t\tif (nc_ctx->e > DUK__IEEE_DOUBLE_EXP_MIN /*not minimum exponent*/ &&\n\t\t    lowest_mantissa /* lowest mantissa for this exponent*/) {\n\t\t\t/* r <- (* f b 2)                                [if b==2 -> (* f 4)]\n\t\t\t * s <- (* (expt b (- 1 e)) 2) == b^(1-e) * 2    [if b==2 -> b^(2-e)]\n\t\t\t * m+ <- b == 2\n\t\t\t * m- <- 1\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"negative exponent; not minimum exponent and \"\n\t\t\t                     \"lowest mantissa for this exponent -> \"\n\t\t\t                     \"unequal gaps\"));\n\n\t\t\tduk__bi_mul_small(&nc_ctx->r, &nc_ctx->f, (duk_uint32_t) (nc_ctx->b * 2));  /* r <- (2 * b) * f */\n\t\t\tduk__bi_exp_small(&nc_ctx->t1, nc_ctx->b, 1 - nc_ctx->e, &nc_ctx->s, &nc_ctx->t2);  /* NB: use 's' as temp on purpose */\n\t\t\tduk__bi_mul_small(&nc_ctx->s, &nc_ctx->t1, 2);             /* s <- b^(1-e) * 2 */\n\t\t\tduk__bi_set_small(&nc_ctx->mp, 2);\n\t\t\tduk__bi_set_small(&nc_ctx->mm, 1);\n\t\t\tnc_ctx->unequal_gaps = 1;\n\t\t} else {\n\t\t\t/* r <- (* f 2)\n\t\t\t * s <- (* (expt b (- e)) 2) == b^(-e) * 2    [if b==2 -> b^(1-e)]\n\t\t\t * m+ <- 1\n\t\t\t * m- <- 1\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"negative exponent; minimum exponent or not \"\n\t\t\t                     \"lowest mantissa for this exponent -> \"\n\t\t\t                     \"equal gaps\"));\n\n\t\t\tduk__bi_mul_small(&nc_ctx->r, &nc_ctx->f, 2);            /* r <- 2 * f */\n\t\t\tduk__bi_exp_small(&nc_ctx->t1, nc_ctx->b, -nc_ctx->e, &nc_ctx->s, &nc_ctx->t2);  /* NB: use 's' as temp on purpose */\n\t\t\tduk__bi_mul_small(&nc_ctx->s, &nc_ctx->t1, 2);           /* s <- b^(-e) * 2 */\n\t\t\tduk__bi_set_small(&nc_ctx->mp, 1);\n\t\t\tduk__bi_set_small(&nc_ctx->mm, 1);\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__dragon4_scale(duk__numconv_stringify_ctx *nc_ctx) {\n\tduk_small_int_t k = 0;\n\n\t/* This is essentially the 'scale' algorithm, with recursion removed.\n\t * Note that 'k' is either correct immediately, or will move in one\n\t * direction in the loop.  There's no need to do the low/high checks\n\t * on every round (like the Scheme algorithm does).\n\t *\n\t * The scheme algorithm finds 'k' and updates 's' simultaneously,\n\t * while the logical algorithm finds 'k' with 's' having its initial\n\t * value, after which 's' is updated separately (see the Burger-Dybvig\n\t * paper, Section 3.1, steps 2 and 3).\n\t *\n\t * The case where m+ == m- (almost always) is optimized for, because\n\t * it reduces the bigint operations considerably and almost always\n\t * applies.  The scale loop only needs to work with m+, so this works.\n\t */\n\n\t/* XXX: this algorithm could be optimized quite a lot by using e.g.\n\t * a logarithm based estimator for 'k' and performing B^n multiplication\n\t * using a lookup table or using some bit-representation based exp\n\t * algorithm.  Currently we just loop, with significant performance\n\t * impact for very large and very small numbers.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"scale: B=%ld, low_ok=%ld, high_ok=%ld\",\n\t                     (long) nc_ctx->B, (long) nc_ctx->low_ok, (long) nc_ctx->high_ok));\n\tDUK__BI_PRINT(\"r(init)\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s(init)\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp(init)\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm(init)\", &nc_ctx->mm);\n\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"scale loop (inc k), k=%ld\", (long) k));\n\t\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\t\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\t\tDUK__BI_PRINT(\"m+\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"m-\", &nc_ctx->mm);\n\n\t\tduk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp);  /* t1 = (+ r m+) */\n\t\tif (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) >= (nc_ctx->high_ok ? 0 : 1)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"k is too low\"));\n\t\t\t/* r <- r\n\t\t\t * s <- (* s B)\n\t\t\t * m+ <- m+\n\t\t\t * m- <- m-\n\t\t\t * k <- (+ k 1)\n\t\t\t */\n\n\t\t\tduk__bi_mul_small_copy(&nc_ctx->s, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\tk++;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* k > 0 -> k was too low, and cannot be too high */\n\tif (k > 0) {\n\t\tgoto skip_dec_k;\n\t}\n\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"scale loop (dec k), k=%ld\", (long) k));\n\t\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\t\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\t\tDUK__BI_PRINT(\"m+\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"m-\", &nc_ctx->mm);\n\n\t\tduk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp);  /* t1 = (+ r m+) */\n\t\tduk__bi_mul_small(&nc_ctx->t2, &nc_ctx->t1, (duk_uint32_t) nc_ctx->B);   /* t2 = (* (+ r m+) B) */\n\t\tif (duk__bi_compare(&nc_ctx->t2, &nc_ctx->s) <= (nc_ctx->high_ok ? -1 : 0)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"k is too high\"));\n\t\t\t/* r <- (* r B)\n\t\t\t * s <- s\n\t\t\t * m+ <- (* m+ B)\n\t\t\t * m- <- (* m- B)\n\t\t\t * k <- (- k 1)\n\t\t\t */\n\t\t\tduk__bi_mul_small_copy(&nc_ctx->r, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\tduk__bi_mul_small_copy(&nc_ctx->mp, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\tif (nc_ctx->unequal_gaps) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"m+ != m- -> need to update m- too\"));\n\t\t\t\tduk__bi_mul_small_copy(&nc_ctx->mm, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\t}\n\t\t\tk--;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n skip_dec_k:\n\n\tif (!nc_ctx->unequal_gaps) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"equal gaps, copy m- from m+\"));\n\t\tduk__bi_copy(&nc_ctx->mm, &nc_ctx->mp);  /* mm <- mp */\n\t}\n\tnc_ctx->k = k;\n\n\tDUK_DDD(DUK_DDDPRINT(\"final k: %ld\", (long) k));\n\tDUK__BI_PRINT(\"r(final)\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s(final)\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp(final)\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm(final)\", &nc_ctx->mm);\n}\n\nDUK_LOCAL void duk__dragon4_generate(duk__numconv_stringify_ctx *nc_ctx) {\n\tduk_small_int_t tc1, tc2;    /* terminating conditions */\n\tduk_small_int_t d;           /* current digit */\n\tduk_small_int_t count = 0;   /* digit count */\n\n\t/*\n\t *  Digit generation loop.\n\t *\n\t *  Different termination conditions:\n\t *\n\t *    1. Free format output.  Terminate when shortest accurate\n\t *       representation found.\n\t *\n\t *    2. Fixed format output, with specific number of digits.\n\t *       Ignore termination conditions, terminate when digits\n\t *       generated.  Caller requests an extra digit and rounds.\n\t *\n\t *    3. Fixed format output, with a specific absolute cut-off\n\t *       position (e.g. 10 digits after decimal point).  Note\n\t *       that we always generate at least one digit, even if\n\t *       the digit is below the cut-off point already.\n\t */\n\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"generate loop, count=%ld, k=%ld, B=%ld, low_ok=%ld, high_ok=%ld\",\n\t\t                     (long) count, (long) nc_ctx->k, (long) nc_ctx->B,\n\t\t                     (long) nc_ctx->low_ok, (long) nc_ctx->high_ok));\n\t\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\t\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\t\tDUK__BI_PRINT(\"m+\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"m-\", &nc_ctx->mm);\n\n\t\t/* (quotient-remainder (* r B) s) using a dummy subtraction loop */\n\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->r, (duk_uint32_t) nc_ctx->B);       /* t1 <- (* r B) */\n\t\td = 0;\n\t\tfor (;;) {\n\t\t\tif (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) < 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tduk__bi_sub_copy(&nc_ctx->t1, &nc_ctx->s, &nc_ctx->t2);  /* t1 <- t1 - s */\n\t\t\td++;\n\t\t}\n\t\tduk__bi_copy(&nc_ctx->r, &nc_ctx->t1);  /* r <- (remainder (* r B) s) */\n\t\t                                        /* d <- (quotient (* r B) s)   (in range 0...B-1) */\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> d(quot)=%ld\", (long) d));\n\t\tDUK__BI_PRINT(\"r(rem)\", &nc_ctx->r);\n\n\t\tduk__bi_mul_small_copy(&nc_ctx->mp, (duk_uint32_t) nc_ctx->B, &nc_ctx->t2); /* m+ <- (* m+ B) */\n\t\tduk__bi_mul_small_copy(&nc_ctx->mm, (duk_uint32_t) nc_ctx->B, &nc_ctx->t2); /* m- <- (* m- B) */\n\t\tDUK__BI_PRINT(\"mp(upd)\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"mm(upd)\", &nc_ctx->mm);\n\n\t\t/* Terminating conditions.  For fixed width output, we just ignore the\n\t\t * terminating conditions (and pretend that tc1 == tc2 == false).  The\n\t\t * the current shortcut for fixed-format output is to generate a few\n\t\t * extra digits and use rounding (with carry) to finish the output.\n\t\t */\n\n\t\tif (nc_ctx->is_fixed == 0) {\n\t\t\t/* free-form */\n\t\t\ttc1 = (duk__bi_compare(&nc_ctx->r, &nc_ctx->mm) <= (nc_ctx->low_ok ? 0 : -1));\n\n\t\t\tduk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp);  /* t1 <- (+ r m+) */\n\t\t\ttc2 = (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) >= (nc_ctx->high_ok ? 0 : 1));\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=%ld, tc2=%ld\", (long) tc1, (long) tc2));\n\t\t} else {\n\t\t\t/* fixed-format */\n\t\t\ttc1 = 0;\n\t\t\ttc2 = 0;\n\t\t}\n\n\t\t/* Count is incremented before DUK__DRAGON4_OUTPUT_PREINC() call\n\t\t * on purpose, which is taken into account by the macro.\n\t\t */\n\t\tcount++;\n\n\t\tif (tc1) {\n\t\t\tif (tc2) {\n\t\t\t\t/* tc1 = true, tc2 = true */\n\t\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->r, 2);\n\t\t\t\tif (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) < 0) {  /* (< (* r 2) s) */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=true, tc2=true, 2r > s: output d --> %ld (k=%ld)\",\n\t\t\t\t\t                     (long) d, (long) nc_ctx->k));\n\t\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=true, tc2=true, 2r <= s: output d+1 --> %ld (k=%ld)\",\n\t\t\t\t\t                     (long) (d + 1), (long) nc_ctx->k));\n\t\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d + 1);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t/* tc1 = true, tc2 = false */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=true, tc2=false: output d --> %ld (k=%ld)\",\n\t\t\t\t                     (long) d, (long) nc_ctx->k));\n\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (tc2) {\n\t\t\t\t/* tc1 = false, tc2 = true */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=false, tc2=true: output d+1 --> %ld (k=%ld)\",\n\t\t\t\t                     (long) (d + 1), (long) nc_ctx->k));\n\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d + 1);\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t/* tc1 = false, tc2 = false */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=false, tc2=false: output d --> %ld (k=%ld)\",\n\t\t\t\t                     (long) d, (long) nc_ctx->k));\n\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d);\n\n\t\t\t\t/* r <- r    (updated above: r <- (remainder (* r B) s)\n\t\t\t\t * s <- s\n\t\t\t\t * m+ <- m+  (updated above: m+ <- (* m+ B)\n\t\t\t\t * m- <- m-  (updated above: m- <- (* m- B)\n\t\t\t\t * B, low_ok, high_ok are fixed\n\t\t\t\t */\n\n\t\t\t\t/* fall through and continue for-loop */\n\t\t\t}\n\t\t}\n\n\t\t/* fixed-format termination conditions */\n\t\tif (nc_ctx->is_fixed) {\n\t\t\tif (nc_ctx->abs_pos) {\n\t\t\t\tint pos = nc_ctx->k - count + 1;  /* count is already incremented, take into account */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fixed format, absolute: abs pos=%ld, k=%ld, count=%ld, req=%ld\",\n\t\t\t\t                     (long) pos, (long) nc_ctx->k, (long) count, (long) nc_ctx->req_digits));\n\t\t\t\tif (pos <= nc_ctx->req_digits) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"digit position reached req_digits, end generate loop\"));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fixed format, relative: k=%ld, count=%ld, req=%ld\",\n\t\t\t\t                     (long) nc_ctx->k, (long) count, (long) nc_ctx->req_digits));\n\t\t\t\tif (count >= nc_ctx->req_digits) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"digit count reached req_digits, end generate loop\"));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}  /* for */\n\n\tnc_ctx->count = count;\n\n\tDUK_DDD(DUK_DDDPRINT(\"generate finished\"));\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t{\n\t\tduk_uint8_t buf[2048];\n\t\tduk_small_int_t i, t;\n\t\tduk_memzero(buf, sizeof(buf));\n\t\tfor (i = 0; i < nc_ctx->count; i++) {\n\t\t\tt = nc_ctx->digits[i];\n\t\t\tif (t < 0 || t > 36) {\n\t\t\t\tbuf[i] = (duk_uint8_t) '?';\n\t\t\t} else {\n\t\t\t\tbuf[i] = (duk_uint8_t) DUK__DIGITCHAR(t);\n\t\t\t}\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> generated digits; k=%ld, digits='%s'\",\n\t\t                     (long) nc_ctx->k, (const char *) buf));\n\t}\n#endif\n}\n\n/* Round up digits to a given position.  If position is out-of-bounds,\n * does nothing.  If carry propagates over the first digit, a '1' is\n * prepended to digits and 'k' will be updated.  Return value indicates\n * whether carry propagated over the first digit.\n *\n * Note that nc_ctx->count is NOT updated based on the rounding position\n * (it is updated only if carry overflows over the first digit and an\n * extra digit is prepended).\n */\nDUK_LOCAL duk_small_int_t duk__dragon4_fixed_format_round(duk__numconv_stringify_ctx *nc_ctx, duk_small_int_t round_idx) {\n\tduk_small_int_t t;\n\tduk_uint8_t *p;\n\tduk_uint8_t roundup_limit;\n\tduk_small_int_t ret = 0;\n\n\t/*\n\t *  round_idx points to the digit which is considered for rounding; the\n\t *  digit to its left is the final digit of the rounded value.  If round_idx\n\t *  is zero, rounding will be performed; the result will either be an empty\n\t *  rounded value or if carry happens a '1' digit is generated.\n\t */\n\n\tif (round_idx >= nc_ctx->count) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"round_idx out of bounds (%ld >= %ld (count)) -> no rounding\",\n\t\t                     (long) round_idx, (long) nc_ctx->count));\n\t\treturn 0;\n\t} else if (round_idx < 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"round_idx out of bounds (%ld < 0) -> no rounding\",\n\t\t                     (long) round_idx));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  Round-up limit.\n\t *\n\t *  For even values, divides evenly, e.g. 10 -> roundup_limit=5.\n\t *\n\t *  For odd values, rounds up, e.g. 3 -> roundup_limit=2.\n\t *  If radix is 3, 0/3 -> down, 1/3 -> down, 2/3 -> up.\n\t */\n\troundup_limit = (duk_uint8_t) ((nc_ctx->B + 1) / 2);\n\n\tp = &nc_ctx->digits[round_idx];\n\tif (*p >= roundup_limit) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"fixed-format rounding carry required\"));\n\t\t/* carry */\n\t\tfor (;;) {\n\t\t\t*p = 0;\n\t\t\tif (p == &nc_ctx->digits[0]) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"carry propagated to first digit -> special case handling\"));\n\t\t\t\tduk_memmove((void *) (&nc_ctx->digits[1]),\n\t\t\t\t            (const void *) (&nc_ctx->digits[0]),\n\t\t\t\t            (size_t) (sizeof(char) * (size_t) nc_ctx->count));\n\t\t\t\tnc_ctx->digits[0] = 1;  /* don't increase 'count' */\n\t\t\t\tnc_ctx->k++;  /* position of highest digit changed */\n\t\t\t\tnc_ctx->count++;  /* number of digits changed */\n\t\t\t\tret = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fixed-format rounding carry: B=%ld, roundup_limit=%ld, p=%p, digits=%p\",\n\t\t\t                     (long) nc_ctx->B, (long) roundup_limit, (void *) p, (void *) nc_ctx->digits));\n\t\t\tp--;\n\t\t\tt = *p;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"digit before carry: %ld\", (long) t));\n\t\t\tif (++t < nc_ctx->B) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rounding carry terminated\"));\n\t\t\t\t*p = (duk_uint8_t) t;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"wraps, carry to next digit\"));\n\t\t}\n\t}\n\n\treturn ret;\n}\n\n#define DUK__NO_EXP  (65536)  /* arbitrary marker, outside valid exp range */\n\nDUK_LOCAL void duk__dragon4_convert_and_push(duk__numconv_stringify_ctx *nc_ctx,\n                                             duk_hthread *thr,\n                                             duk_small_int_t radix,\n                                             duk_small_int_t digits,\n                                             duk_small_uint_t flags,\n                                             duk_small_int_t neg) {\n\tduk_small_int_t k;\n\tduk_small_int_t pos, pos_end;\n\tduk_small_int_t expt;\n\tduk_small_int_t dig;\n\tduk_uint8_t *q;\n\tduk_uint8_t *buf;\n\n\t/*\n\t *  The string conversion here incorporates all the necessary ECMAScript\n\t *  semantics without attempting to be generic.  nc_ctx->digits contains\n\t *  nc_ctx->count digits (>= 1), with the topmost digit's 'position'\n\t *  indicated by nc_ctx->k as follows:\n\t *\n\t *    digits=\"123\" count=3 k=0   -->   0.123\n\t *    digits=\"123\" count=3 k=1   -->   1.23\n\t *    digits=\"123\" count=3 k=5   -->   12300\n\t *    digits=\"123\" count=3 k=-1  -->   0.0123\n\t *\n\t *  Note that the identifier names used for format selection are different\n\t *  in Burger-Dybvig paper and ECMAScript specification (quite confusingly\n\t *  so, because e.g. 'k' has a totally different meaning in each).  See\n\t *  documentation for discussion.\n\t *\n\t *  ECMAScript doesn't specify any specific behavior for format selection\n\t *  (e.g. when to use exponent notation) for non-base-10 numbers.\n\t *\n\t *  The bigint space in the context is reused for string output, as there\n\t *  is more than enough space for that (>1kB at the moment), and we avoid\n\t *  allocating even more stack.\n\t */\n\n\tDUK_ASSERT(DUK__NUMCONV_CTX_BIGINTS_SIZE >= DUK__MAX_FORMATTED_LENGTH);\n\tDUK_ASSERT(nc_ctx->count >= 1);\n\n\tk = nc_ctx->k;\n\tbuf = (duk_uint8_t *) &nc_ctx->f;  /* XXX: union would be more correct */\n\tq = buf;\n\n\t/* Exponent handling: if exponent format is used, record exponent value and\n\t * fake k such that one leading digit is generated (e.g. digits=123 -> \"1.23\").\n\t *\n\t * toFixed() prevents exponent use; otherwise apply a set of criteria to\n\t * match the other API calls (toString(), toPrecision, etc).\n\t */\n\n\texpt = DUK__NO_EXP;\n\tif (!nc_ctx->abs_pos /* toFixed() */) {\n\t\tif ((flags & DUK_N2S_FLAG_FORCE_EXP) ||             /* exponential notation forced */\n\t\t    ((flags & DUK_N2S_FLAG_NO_ZERO_PAD) &&          /* fixed precision and zero padding would be required */\n\t             (k - digits >= 1)) ||                          /* (e.g. k=3, digits=2 -> \"12X\") */\n\t\t    ((k > 21 || k <= -6) && (radix == 10))) {       /* toString() conditions */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"use exponential notation: k=%ld -> expt=%ld\",\n\t\t\t                     (long) k, (long) (k - 1)));\n\t\t\texpt = k - 1;  /* e.g. 12.3 -> digits=\"123\" k=2 -> 1.23e1 */\n\t\t\tk = 1;  /* generate mantissa with a single leading whole number digit */\n\t\t}\n\t}\n\n\tif (neg) {\n\t\t*q++ = '-';\n\t}\n\n\t/* Start position (inclusive) and end position (exclusive) */\n\tpos = (k >= 1 ? k : 1);\n\tif (nc_ctx->is_fixed) {\n\t\tif (nc_ctx->abs_pos) {\n\t\t\t/* toFixed() */\n\t\t\tpos_end = -digits;\n\t\t} else {\n\t\t\tpos_end = k - digits;\n\t\t}\n\t} else {\n\t\tpos_end = k - nc_ctx->count;\n\t}\n\tif (pos_end > 0) {\n\t\tpos_end = 0;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"expt=%ld, k=%ld, count=%ld, pos=%ld, pos_end=%ld, is_fixed=%ld, \"\n\t                     \"digits=%ld, abs_pos=%ld\",\n\t                     (long) expt, (long) k, (long) nc_ctx->count, (long) pos, (long) pos_end,\n\t                     (long) nc_ctx->is_fixed, (long) digits, (long) nc_ctx->abs_pos));\n\n\t/* Digit generation */\n\twhile (pos > pos_end) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"digit generation: pos=%ld, pos_end=%ld\",\n\t\t                     (long) pos, (long) pos_end));\n\t\tif (pos == 0) {\n\t\t\t*q++ = (duk_uint8_t) '.';\n\t\t}\n\t\tif (pos > k) {\n\t\t\t*q++ = (duk_uint8_t) '0';\n\t\t} else if (pos <= k - nc_ctx->count) {\n\t\t\t*q++ = (duk_uint8_t) '0';\n\t\t} else {\n\t\t\tdig = nc_ctx->digits[k - pos];\n\t\t\tDUK_ASSERT(dig >= 0 && dig < nc_ctx->B);\n\t\t\t*q++ = (duk_uint8_t) DUK__DIGITCHAR(dig);\n\t\t}\n\n\t\tpos--;\n\t}\n\tDUK_ASSERT(pos <= 1);\n\n\t/* Exponent */\n\tif (expt != DUK__NO_EXP) {\n\t\t/*\n\t\t *  Exponent notation for non-base-10 numbers isn't specified in ECMAScript\n\t\t *  specification, as it never explicitly turns up: non-decimal numbers can\n\t\t *  only be formatted with Number.prototype.toString([radix]) and for that,\n\t\t *  behavior is not explicitly specified.\n\t\t *\n\t\t *  Logical choices include formatting the exponent as decimal (e.g. binary\n\t\t *  100000 as 1e+5) or in current radix (e.g. binary 100000 as 1e+101).\n\t\t *  The Dragon4 algorithm (in the original paper) prints the exponent value\n\t\t *  in the target radix B.  However, for radix values 15 and above, the\n\t\t *  exponent separator 'e' is no longer easily parseable.  Consider, for\n\t\t *  instance, the number \"1.faecee+1c\".\n\t\t */\n\n\t\tduk_size_t len;\n\t\tchar expt_sign;\n\n\t\t*q++ = 'e';\n\t\tif (expt >= 0) {\n\t\t\texpt_sign = '+';\n\t\t} else {\n\t\t\texpt_sign = '-';\n\t\t\texpt = -expt;\n\t\t}\n\t\t*q++ = (duk_uint8_t) expt_sign;\n\t\tlen = duk__dragon4_format_uint32(q, (duk_uint32_t) expt, radix);\n\t\tq += len;\n\t}\n\n\tduk_push_lstring(thr, (const char *) buf, (size_t) (q - buf));\n}\n\n/*\n *  Conversion helpers\n */\n\nDUK_LOCAL void duk__dragon4_double_to_ctx(duk__numconv_stringify_ctx *nc_ctx, duk_double_t x) {\n\tduk_double_union u;\n\tduk_uint32_t tmp;\n\tduk_small_int_t expt;\n\n\t/*\n\t *    seeeeeee eeeeffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n\t *       A        B        C        D        E        F        G        H\n\t *\n\t *    s       sign bit\n\t *    eee...  exponent field\n\t *    fff...  fraction\n\t *\n\t *    ieee value = 1.ffff... * 2^(e - 1023)  (normal)\n\t *               = 0.ffff... * 2^(-1022)     (denormal)\n\t *\n\t *    algorithm v = f * b^e\n\t */\n\n\tDUK_DBLUNION_SET_DOUBLE(&u, x);\n\n\tnc_ctx->f.n = 2;\n\n\ttmp = DUK_DBLUNION_GET_LOW32(&u);\n\tnc_ctx->f.v[0] = tmp;\n\ttmp = DUK_DBLUNION_GET_HIGH32(&u);\n\tnc_ctx->f.v[1] = tmp & 0x000fffffUL;\n\texpt = (duk_small_int_t) ((tmp >> 20) & 0x07ffUL);\n\n\tif (expt == 0) {\n\t\t/* denormal */\n\t\texpt = DUK__IEEE_DOUBLE_EXP_MIN - 52;\n\t\tduk__bi_normalize(&nc_ctx->f);\n\t} else {\n\t\t/* normal: implicit leading 1-bit */\n\t\tnc_ctx->f.v[1] |= 0x00100000UL;\n\t\texpt = expt - DUK__IEEE_DOUBLE_EXP_BIAS - 52;\n\t\tDUK_ASSERT(duk__bi_is_valid(&nc_ctx->f));  /* true, because v[1] has at least one bit set */\n\t}\n\n\tDUK_ASSERT(duk__bi_is_valid(&nc_ctx->f));\n\n\tnc_ctx->e = expt;\n}\n\nDUK_LOCAL void duk__dragon4_ctx_to_double(duk__numconv_stringify_ctx *nc_ctx, duk_double_t *x) {\n\tduk_double_union u;\n\tduk_small_int_t expt;\n\tduk_small_int_t i;\n\tduk_small_int_t bitstart;\n\tduk_small_int_t bitround;\n\tduk_small_int_t bitidx;\n\tduk_small_int_t skip_round;\n\tduk_uint32_t t, v;\n\n\tDUK_ASSERT(nc_ctx->count == 53 + 1);\n\n\t/* Sometimes this assert is not true right now; it will be true after\n\t * rounding.  See: test-bug-numconv-mantissa-assert.js.\n\t */\n\tDUK_ASSERT_DISABLE(nc_ctx->digits[0] == 1);  /* zero handled by caller */\n\n\t/* Should not be required because the code below always sets both high\n\t * and low parts, but at least gcc-4.4.5 fails to deduce this correctly\n\t * (perhaps because the low part is set (seemingly) conditionally in a\n\t * loop), so this is here to avoid the bogus warning.\n\t */\n\tduk_memzero((void *) &u, sizeof(u));\n\n\t/*\n\t *  Figure out how generated digits match up with the mantissa,\n\t *  and then perform rounding.  If mantissa overflows, need to\n\t *  recompute the exponent (it is bumped and may overflow to\n\t *  infinity).\n\t *\n\t *  For normal numbers the leading '1' is hidden and ignored,\n\t *  and the last bit is used for rounding:\n\t *\n\t *                          rounding pt\n\t *       <--------52------->|\n\t *     1 x x x x ... x x x x|y  ==>  x x x x ... x x x x\n\t *\n\t *  For denormals, the leading '1' is included in the number,\n\t *  and the rounding point is different:\n\t *\n\t *                      rounding pt\n\t *     <--52 or less--->|\n\t *     1 x x x x ... x x|x x y  ==>  0 0 ... 1 x x ... x x\n\t *\n\t *  The largest denormals will have a mantissa beginning with\n\t *  a '1' (the explicit leading bit); smaller denormals will\n\t *  have leading zero bits.\n\t *\n\t *  If the exponent would become too high, the result becomes\n\t *  Infinity.  If the exponent is so small that the entire\n\t *  mantissa becomes zero, the result becomes zero.\n\t *\n\t *  Note: the Dragon4 'k' is off-by-one with respect to the IEEE\n\t *  exponent.  For instance, k==0 indicates that the leading '1'\n\t *  digit is at the first binary fraction position (0.1xxx...);\n\t *  the corresponding IEEE exponent would be -1.\n\t */\n\n\tskip_round = 0;\n\n recheck_exp:\n\n\texpt = nc_ctx->k - 1;   /* IEEE exp without bias */\n\tif (expt > 1023) {\n\t\t/* Infinity */\n\t\tbitstart = -255;  /* needed for inf: causes mantissa to become zero,\n\t\t                   * and rounding to be skipped.\n\t\t                   */\n\t\texpt = 2047;\n\t} else if (expt >= -1022) {\n\t\t/* normal */\n\t\tbitstart = 1;  /* skip leading digit */\n\t\texpt += DUK__IEEE_DOUBLE_EXP_BIAS;\n\t\tDUK_ASSERT(expt >= 1 && expt <= 2046);\n\t} else {\n\t\t/* denormal or zero */\n\t\tbitstart = 1023 + expt;  /* expt==-1023 -> bitstart=0 (leading 1);\n\t\t                          * expt==-1024 -> bitstart=-1 (one left of leading 1), etc\n\t\t                          */\n\t\texpt = 0;\n\t}\n\tbitround = bitstart + 52;\n\n\tDUK_DDD(DUK_DDDPRINT(\"ieee expt=%ld, bitstart=%ld, bitround=%ld\",\n\t                     (long) expt, (long) bitstart, (long) bitround));\n\n\tif (!skip_round) {\n\t\tif (duk__dragon4_fixed_format_round(nc_ctx, bitround)) {\n\t\t\t/* Corner case: see test-numconv-parse-mant-carry.js.  We could\n\t\t\t * just bump the exponent and update bitstart, but it's more robust\n\t\t\t * to recompute (but avoid rounding twice).\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"rounding caused exponent to be bumped, recheck exponent\"));\n\t\t\tskip_round = 1;\n\t\t\tgoto recheck_exp;\n\t\t}\n\t}\n\n\t/*\n\t *  Create mantissa\n\t */\n\n\tt = 0;\n\tfor (i = 0; i < 52; i++) {\n\t\tbitidx = bitstart + 52 - 1 - i;\n\t\tif (bitidx >= nc_ctx->count) {\n\t\t\tv = 0;\n\t\t} else if (bitidx < 0) {\n\t\t\tv = 0;\n\t\t} else {\n\t\t\tv = nc_ctx->digits[bitidx];\n\t\t}\n\t\tDUK_ASSERT(v == 0 || v == 1);\n\t\tt += v << (i % 32);\n\t\tif (i == 31) {\n\t\t\t/* low 32 bits is complete */\n\t\t\tDUK_DBLUNION_SET_LOW32(&u, t);\n\t\t\tt = 0;\n\t\t}\n\t}\n\t/* t has high mantissa */\n\n\tDUK_DDD(DUK_DDDPRINT(\"mantissa is complete: %08lx %08lx\",\n\t                     (unsigned long) t,\n\t                     (unsigned long) DUK_DBLUNION_GET_LOW32(&u)));\n\n\tDUK_ASSERT(expt >= 0 && expt <= 0x7ffL);\n\tt += ((duk_uint32_t) expt) << 20;\n#if 0  /* caller handles sign change */\n\tif (negative) {\n\t\tt |= 0x80000000U;\n\t}\n#endif\n\tDUK_DBLUNION_SET_HIGH32(&u, t);\n\n\tDUK_DDD(DUK_DDDPRINT(\"number is complete: %08lx %08lx\",\n\t                     (unsigned long) DUK_DBLUNION_GET_HIGH32(&u),\n\t                     (unsigned long) DUK_DBLUNION_GET_LOW32(&u)));\n\n\t*x = DUK_DBLUNION_GET_DOUBLE(&u);\n}\n\n/*\n *  Exposed number-to-string API\n *\n *  Input: [ number ]\n *  Output: [ string ]\n */\n\nDUK_LOCAL DUK_NOINLINE void duk__numconv_stringify_raw(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) {\n\tduk_double_t x;\n\tduk_small_int_t c;\n\tduk_small_int_t neg;\n\tduk_uint32_t uval;\n\tduk__numconv_stringify_ctx nc_ctx_alloc;  /* large context; around 2kB now */\n\tduk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;\n\n\tx = (duk_double_t) duk_require_number(thr, -1);\n\tduk_pop(thr);\n\n\t/*\n\t *  Handle special cases (NaN, infinity, zero).\n\t */\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (DUK_SIGNBIT((double) x)) {\n\t\tx = -x;\n\t\tneg = 1;\n\t} else {\n\t\tneg = 0;\n\t}\n\n\t/* NaN sign bit is platform specific with unpacked, un-normalized NaNs */\n\tDUK_ASSERT(c == DUK_FP_NAN || DUK_SIGNBIT((double) x) == 0);\n\n\tif (c == DUK_FP_NAN) {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_NAN);\n\t\treturn;\n\t} else if (c == DUK_FP_INFINITE) {\n\t\tif (neg) {\n\t\t\t/* -Infinity */\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_MINUS_INFINITY);\n\t\t} else {\n\t\t\t/* Infinity */\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_INFINITY);\n\t\t}\n\t\treturn;\n\t} else if (c == DUK_FP_ZERO) {\n\t\t/* We can't shortcut zero here if it goes through special formatting\n\t\t * (such as forced exponential notation).\n\t\t */\n\t\t;\n\t}\n\n\t/*\n\t *  Handle integers in 32-bit range (that is, [-(2**32-1),2**32-1])\n\t *  specially, as they're very likely for embedded programs.  This\n\t *  is now done for all radix values.  We must be careful not to use\n\t *  the fast path when special formatting (e.g. forced exponential)\n\t *  is in force.\n\t *\n\t *  XXX: could save space by supporting radix 10 only and using\n\t *  sprintf \"%lu\" for the fast path and for exponent formatting.\n\t */\n\n\tuval = duk_double_to_uint32_t(x);\n\tif (((double) uval) == x &&  /* integer number in range */\n\t    flags == 0) {            /* no special formatting */\n\t\t/* use bigint area as a temp */\n\t\tduk_uint8_t *buf = (duk_uint8_t *) (&nc_ctx->f);\n\t\tduk_uint8_t *p = buf;\n\n\t\tDUK_ASSERT(DUK__NUMCONV_CTX_BIGINTS_SIZE >= 32 + 1);  /* max size: radix=2 + sign */\n\t\tif (neg && uval != 0) {\n\t\t\t/* no negative sign for zero */\n\t\t\t*p++ = (duk_uint8_t) '-';\n\t\t}\n\t\tp += duk__dragon4_format_uint32(p, uval, radix);\n\t\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) (p - buf));\n\t\treturn;\n\t}\n\n\t/*\n\t *  Dragon4 setup.\n\t *\n\t *  Convert double from IEEE representation for conversion;\n\t *  normal finite values have an implicit leading 1-bit.  The\n\t *  slow path algorithm doesn't handle zero, so zero is special\n\t *  cased here but still creates a valid nc_ctx, and goes\n\t *  through normal formatting in case special formatting has\n\t *  been requested (e.g. forced exponential format: 0 -> \"0e+0\").\n\t */\n\n\t/* Would be nice to bulk clear the allocation, but the context\n\t * is 1-2 kilobytes and nothing should rely on it being zeroed.\n\t */\n#if 0\n\tduk_memzero((void *) nc_ctx, sizeof(*nc_ctx));  /* slow init, do only for slow path cases */\n#endif\n\n\tnc_ctx->is_s2n = 0;\n\tnc_ctx->b = 2;\n\tnc_ctx->B = radix;\n\tnc_ctx->abs_pos = 0;\n\tif (flags & DUK_N2S_FLAG_FIXED_FORMAT) {\n\t\tnc_ctx->is_fixed = 1;\n\t\tif (flags & DUK_N2S_FLAG_FRACTION_DIGITS) {\n\t\t\t/* absolute req_digits; e.g. digits = 1 -> last digit is 0,\n\t\t\t * but add an extra digit for rounding.\n\t\t\t */\n\t\t\tnc_ctx->abs_pos = 1;\n\t\t\tnc_ctx->req_digits = (-digits + 1) - 1;\n\t\t} else {\n\t\t\tnc_ctx->req_digits = digits + 1;\n\t\t}\n\t} else {\n\t\tnc_ctx->is_fixed = 0;\n\t\tnc_ctx->req_digits = 0;\n\t}\n\n\tif (c == DUK_FP_ZERO) {\n\t\t/* Zero special case: fake requested number of zero digits; ensure\n\t\t * no sign bit is printed.  Relative and absolute fixed format\n\t\t * require separate handling.\n\t\t */\n\t\tduk_small_int_t count;\n\t\tif (nc_ctx->is_fixed) {\n\t\t\tif (nc_ctx->abs_pos) {\n\t\t\t\tcount = digits + 2;  /* lead zero + 'digits' fractions + 1 for rounding */\n\t\t\t} else {\n\t\t\t\tcount = digits + 1;  /* + 1 for rounding */\n\t\t\t}\n\t\t} else {\n\t\t\tcount = 1;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"count=%ld\", (long) count));\n\t\tDUK_ASSERT(count >= 1);\n\t\tduk_memzero((void *) nc_ctx->digits, (size_t) count);\n\t\tnc_ctx->count = count;\n\t\tnc_ctx->k = 1;  /* 0.000... */\n\t\tneg = 0;\n\t\tgoto zero_skip;\n\t}\n\n\tduk__dragon4_double_to_ctx(nc_ctx, x);   /* -> sets 'f' and 'e' */\n\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\tDUK_DDD(DUK_DDDPRINT(\"e=%ld\", (long) nc_ctx->e));\n\n\t/*\n\t *  Dragon4 slow path digit generation.\n\t */\n\n\tduk__dragon4_prepare(nc_ctx);  /* setup many variables in nc_ctx */\n\n\tDUK_DDD(DUK_DDDPRINT(\"after prepare:\"));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_scale(nc_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"after scale; k=%ld\", (long) nc_ctx->k));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_generate(nc_ctx);\n\n\t/*\n\t *  Convert and push final string.\n\t */\n\n zero_skip:\n\n\tif (flags & DUK_N2S_FLAG_FIXED_FORMAT) {\n\t\t/* Perform fixed-format rounding. */\n\t\tduk_small_int_t roundpos;\n\t\tif (flags & DUK_N2S_FLAG_FRACTION_DIGITS) {\n\t\t\t/* 'roundpos' is relative to nc_ctx->k and increases to the right\n\t\t\t * (opposite of how 'k' changes).\n\t\t\t */\n\t\t\troundpos = -digits;  /* absolute position for digit considered for rounding */\n\t\t\troundpos = nc_ctx->k - roundpos;\n\t\t} else {\n\t\t\troundpos = digits;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"rounding: k=%ld, count=%ld, digits=%ld, roundpos=%ld\",\n\t\t                     (long) nc_ctx->k, (long) nc_ctx->count, (long) digits, (long) roundpos));\n\t\t(void) duk__dragon4_fixed_format_round(nc_ctx, roundpos);\n\n\t\t/* Note: 'count' is currently not adjusted by rounding (i.e. the\n\t\t * digits are not \"chopped off\".  That shouldn't matter because\n\t\t * the digit position (absolute or relative) is passed on to the\n\t\t * convert-and-push function.\n\t\t */\n\t}\n\n\tduk__dragon4_convert_and_push(nc_ctx, thr, radix, digits, flags, neg);\n}\n\nDUK_INTERNAL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) {\n\tduk_native_stack_check(thr);\n\tduk__numconv_stringify_raw(thr, radix, digits, flags);\n}\n\n/*\n *  Exposed string-to-number API\n *\n *  Input: [ string ]\n *  Output: [ number ]\n *\n *  If number parsing fails, a NaN is pushed as the result.  If number parsing\n *  fails due to an internal error, an InternalError is thrown.\n */\n\nDUK_LOCAL DUK_NOINLINE void duk__numconv_parse_raw(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags) {\n\tduk__numconv_stringify_ctx nc_ctx_alloc;  /* large context; around 2kB now */\n\tduk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;\n\tduk_double_t res;\n\tduk_hstring *h_str;\n\tduk_int_t expt;\n\tduk_bool_t expt_neg;\n\tduk_small_int_t expt_adj;\n\tduk_small_int_t neg;\n\tduk_small_int_t dig;\n\tduk_small_int_t dig_whole;\n\tduk_small_int_t dig_lzero;\n\tduk_small_int_t dig_frac;\n\tduk_small_int_t dig_expt;\n\tduk_small_int_t dig_prec;\n\tconst duk__exp_limits *explim;\n\tconst duk_uint8_t *p;\n\tduk_small_int_t ch;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse number: %!T, radix=%ld, flags=0x%08lx\",\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (long) radix, (unsigned long) flags));\n\n\tDUK_ASSERT(radix >= 2 && radix <= 36);\n\tDUK_ASSERT(radix - 2 < (duk_small_int_t) sizeof(duk__str2num_digits_for_radix));\n\n\t/*\n\t *  Preliminaries: trim, sign, Infinity check\n\t *\n\t *  We rely on the interned string having a NUL terminator, which will\n\t *  cause a parse failure wherever it is encountered.  As a result, we\n\t *  don't need separate pointer checks.\n\t *\n\t *  There is no special parsing for 'NaN' in the specification although\n\t *  'Infinity' (with an optional sign) is allowed in some contexts.\n\t *  Some contexts allow plus/minus sign, while others only allow the\n\t *  minus sign (like JSON.parse()).\n\t *\n\t *  Automatic hex number detection (leading '0x' or '0X') and octal\n\t *  number detection (leading '0' followed by at least one octal digit)\n\t *  is done here too.\n\t *\n\t *  Symbols are not explicitly rejected here (that's up to the caller).\n\t *  If a symbol were passed here, it should ultimately safely fail\n\t *  parsing due to a syntax error.\n\t */\n\n\tif (flags & DUK_S2N_FLAG_TRIM_WHITE) {\n\t\t/* Leading / trailing whitespace is sometimes accepted and\n\t\t * sometimes not.  After white space trimming, all valid input\n\t\t * characters are pure ASCII.\n\t\t */\n\t\tduk_trim(thr, -1);\n\t}\n\th_str = duk_require_hstring(thr, -1);\n\tDUK_ASSERT(h_str != NULL);\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_str);\n\n\tneg = 0;\n\tch = *p;\n\tif (ch == (duk_small_int_t) '+') {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_PLUS) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: leading plus sign not allowed\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t\tp++;\n\t} else if (ch == (duk_small_int_t) '-') {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_MINUS) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: leading minus sign not allowed\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t\tp++;\n\t\tneg = 1;\n\t}\n\n\tif ((flags & DUK_S2N_FLAG_ALLOW_INF) && DUK_STRNCMP((const char *) p, \"Infinity\", 8) == 0) {\n\t\t/* Don't check for Infinity unless the context allows it.\n\t\t * 'Infinity' is a valid integer literal in e.g. base-36:\n\t\t *\n\t\t *   parseInt('Infinity', 36)\n\t\t *   1461559270678\n\t\t */\n\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_GARBAGE) == 0 && p[8] != DUK_ASC_NUL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: trailing garbage after matching 'Infinity' not allowed\"));\n\t\t\tgoto parse_fail;\n\t\t} else {\n\t\t\tres = DUK_DOUBLE_INFINITY;\n\t\t\tgoto negcheck_and_ret;\n\t\t}\n\t}\n\tch = *p;\n\tif (ch == (duk_small_int_t) '0') {\n\t\tduk_small_int_t detect_radix = 0;\n\t\tch = DUK_LOWERCASE_CHAR_ASCII(p[1]);  /* 'x' or 'X' -> 'x' */\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT) && ch == DUK_ASC_LC_X) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0x/0X hex prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 16;\n#if 0\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_LEGACY_OCT_INT) &&\n\t\t           (ch >= (duk_small_int_t) '0' && ch <= (duk_small_int_t) '9')) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0n oct prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 8;\n\n\t\t\t/* NOTE: if this legacy octal case is added back, it has\n\t\t\t * different flags and 'p' advance so this needs to be\n\t\t\t * reworked.\n\t\t\t */\n\t\t\tflags |= DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO;  /* interpret e.g. '09' as '0', not NaN */\n\t\t\tp += 1;\n#endif\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT) && ch == DUK_ASC_LC_O) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0o oct prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 8;\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT) && ch == DUK_ASC_LC_B) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0b bin prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 2;\n\t\t}\n\t\tif (detect_radix > 0) {\n\t\t\tradix = detect_radix;\n\t\t\t/* Clear empty as zero flag: interpret e.g. '0x' and '0xg' as a NaN (= parse error) */\n\t\t\tflags &= ~(DUK_S2N_FLAG_ALLOW_EXP | DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t\t\t           DUK_S2N_FLAG_ALLOW_FRAC | DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t\t\t           DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO);\n\t\t\tflags |= DUK_S2N_FLAG_ALLOW_LEADING_ZERO;  /* allow e.g. '0x0009' and '0b00010001' */\n\t\t\tp += 2;\n\t\t}\n\t}\n\n\t/*\n\t *  Scan number and setup for Dragon4.\n\t *\n\t *  The fast path case is detected during setup: an integer which\n\t *  can be converted without rounding, no net exponent.  The fast\n\t *  path could be implemented as a separate scan, but may not really\n\t *  be worth it: the multiplications for building 'f' are not\n\t *  expensive when 'f' is small.\n\t *\n\t *  The significand ('f') must contain enough bits of (apparent)\n\t *  accuracy, so that Dragon4 will generate enough binary output digits.\n\t *  For decimal numbers, this means generating a 20-digit significand,\n\t *  which should yield enough practical accuracy to parse IEEE doubles.\n\t *  In fact, the ECMAScript specification explicitly allows an\n\t *  implementation to treat digits beyond 20 as zeroes (and even\n\t *  to round the 20th digit upwards).  For non-decimal numbers, the\n\t *  appropriate number of digits has been precomputed for comparable\n\t *  accuracy.\n\t *\n\t *  Digit counts:\n\t *\n\t *    [ dig_lzero ]\n\t *      |\n\t *     .+-..---[ dig_prec ]----.\n\t *     |  ||                   |\n\t *     0000123.456789012345678901234567890e+123456\n\t *     |     | |                         |  |    |\n\t *     `--+--' `------[ dig_frac ]-------'  `-+--'\n\t *        |                                   |\n\t *    [ dig_whole ]                       [ dig_expt ]\n\t *\n\t *    dig_frac and dig_expt are -1 if not present\n\t *    dig_lzero is only computed for whole number part\n\t *\n\t *  Parsing state\n\t *\n\t *     Parsing whole part      dig_frac < 0 AND dig_expt < 0\n\t *     Parsing fraction part   dig_frac >= 0 AND dig_expt < 0\n\t *     Parsing exponent part   dig_expt >= 0   (dig_frac may be < 0 or >= 0)\n\t *\n\t *  Note: in case we hit an implementation limit (like exponent range),\n\t *  we should throw an error, NOT return NaN or Infinity.  Even with\n\t *  very large exponent (or significand) values the final result may be\n\t *  finite, so NaN/Infinity would be incorrect.\n\t */\n\n\tduk__bi_set_small(&nc_ctx->f, 0);\n\tdig_prec = 0;\n\tdig_lzero = 0;\n\tdig_whole = 0;\n\tdig_frac = -1;\n\tdig_expt = -1;\n\texpt = 0;\n\texpt_adj = 0;  /* essentially tracks digit position of lowest 'f' digit */\n\texpt_neg = 0;\n\tfor (;;) {\n\t\tch = *p++;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse digits: p=%p, ch='%c' (%ld), expt=%ld, expt_adj=%ld, \"\n\t\t                     \"dig_whole=%ld, dig_frac=%ld, dig_expt=%ld, dig_lzero=%ld, dig_prec=%ld\",\n\t\t                     (const void *) p, (int) ((ch >= 0x20 && ch <= 0x7e) ? ch : '?'), (long) ch,\n\t\t                     (long) expt, (long) expt_adj, (long) dig_whole, (long) dig_frac,\n\t\t                     (long) dig_expt, (long) dig_lzero, (long) dig_prec));\n\t\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\n\t\t/* Most common cases first. */\n\t\tif (ch >= (duk_small_int_t) '0' && ch <= (duk_small_int_t) '9') {\n\t\t\tdig = (duk_small_int_t) ch - '0' + 0;\n\t\t} else if (ch == (duk_small_int_t) '.') {\n\t\t\t/* A leading digit is not required in some cases, e.g. accept \".123\".\n\t\t\t * In other cases (JSON.parse()) a leading digit is required.  This\n\t\t\t * is checked for after the loop.\n\t\t\t */\n\t\t\tif (dig_frac >= 0 || dig_expt >= 0) {\n\t\t\t\tif (flags & DUK_S2N_FLAG_ALLOW_GARBAGE) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"garbage termination (invalid period)\"));\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: period not allowed\"));\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_FRAC) == 0) {\n\t\t\t\t/* Some contexts don't allow fractions at all; this can't be a\n\t\t\t\t * post-check because the state ('f' and expt) would be incorrect.\n\t\t\t\t */\n\t\t\t\tif (flags & DUK_S2N_FLAG_ALLOW_GARBAGE) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"garbage termination (invalid first period)\"));\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: fraction part not allowed\"));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"start fraction part\"));\n\t\t\tdig_frac = 0;\n\t\t\tcontinue;\n\t\t} else if (ch == (duk_small_int_t) 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"NUL termination\"));\n\t\t\tbreak;\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_EXP) &&\n\t\t           dig_expt < 0 && (ch == (duk_small_int_t) 'e' || ch == (duk_small_int_t) 'E')) {\n\t\t\t/* Note: we don't parse back exponent notation for anything else\n\t\t\t * than radix 10, so this is not an ambiguous check (e.g. hex\n\t\t\t * exponent values may have 'e' either as a significand digit\n\t\t\t * or as an exponent separator).\n\t\t\t *\n\t\t\t * If the exponent separator occurs twice, 'e' will be interpreted\n\t\t\t * as a digit (= 14) and will be rejected as an invalid decimal\n\t\t\t * digit.\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"start exponent part\"));\n\n\t\t\t/* Exponent without a sign or with a +/- sign is accepted\n\t\t\t * by all call sites (even JSON.parse()).\n\t\t\t */\n\t\t\tch = *p;\n\t\t\tif (ch == (duk_small_int_t) '-') {\n\t\t\t\texpt_neg = 1;\n\t\t\t\tp++;\n\t\t\t} else if (ch == (duk_small_int_t) '+') {\n\t\t\t\tp++;\n\t\t\t}\n\t\t\tdig_expt = 0;\n\t\t\tcontinue;\n\t\t} else if (ch >= (duk_small_int_t) 'a' && ch <= (duk_small_int_t) 'z') {\n\t\t\tdig = (duk_small_int_t) (ch - (duk_small_int_t) 'a' + 0x0a);\n\t\t} else if (ch >= (duk_small_int_t) 'A' && ch <= (duk_small_int_t) 'Z') {\n\t\t\tdig = (duk_small_int_t) (ch - (duk_small_int_t) 'A' + 0x0a);\n\t\t} else {\n\t\t\tdig = 255;  /* triggers garbage digit check below */\n\t\t}\n\t\tDUK_ASSERT((dig >= 0 && dig <= 35) || dig == 255);\n\n\t\tif (dig >= radix) {\n\t\t\tif (flags & DUK_S2N_FLAG_ALLOW_GARBAGE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"garbage termination\"));\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: trailing garbage or invalid digit\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t}\n\n\t\tif (dig_expt < 0) {\n\t\t\t/* whole or fraction digit */\n\n\t\t\tif (dig_prec < duk__str2num_digits_for_radix[radix - 2]) {\n\t\t\t\t/* significant from precision perspective */\n\n\t\t\t\tduk_small_int_t f_zero = duk__bi_is_zero(&nc_ctx->f);\n\t\t\t\tif (f_zero && dig == 0) {\n\t\t\t\t\t/* Leading zero is not counted towards precision digits; not\n\t\t\t\t\t * in the integer part, nor in the fraction part.\n\t\t\t\t\t */\n\t\t\t\t\tif (dig_frac < 0) {\n\t\t\t\t\t\tdig_lzero++;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t/* XXX: join these ops (multiply-accumulate), but only if\n\t\t\t\t\t * code footprint decreases.\n\t\t\t\t\t */\n\t\t\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, (duk_uint32_t) radix);\n\t\t\t\t\tduk__bi_add_small(&nc_ctx->f, &nc_ctx->t1, (duk_uint32_t) dig);\n\t\t\t\t\tdig_prec++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* Ignore digits beyond a radix-specific limit, but note them\n\t\t\t\t * in expt_adj.\n\t\t\t\t */\n\t\t\t\texpt_adj++;\n\t\t\t}\n\n\t\t\tif (dig_frac >= 0) {\n\t\t\t\tdig_frac++;\n\t\t\t\texpt_adj--;\n\t\t\t} else {\n\t\t\t\tdig_whole++;\n\t\t\t}\n\t\t} else {\n\t\t\t/* exponent digit */\n\n\t\t\tDUK_ASSERT(radix == 10);\n\t\t\texpt = expt * radix + dig;\n\t\t\tif (expt > DUK_S2N_MAX_EXPONENT) {\n\t\t\t\t/* Impose a reasonable exponent limit, so that exp\n\t\t\t\t * doesn't need to get tracked using a bigint.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: exponent too large\"));\n\t\t\t\tgoto parse_explimit_error;\n\t\t\t}\n\t\t\tdig_expt++;\n\t\t}\n\t}\n\n\t/* Leading zero. */\n\n\tif (dig_lzero > 0 && dig_whole > 1) {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_LEADING_ZERO) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: leading zeroes not allowed in integer part\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t}\n\n\t/* Validity checks for various fraction formats (\"0.1\", \".1\", \"1.\", \".\"). */\n\n\tif (dig_whole == 0) {\n\t\tif (dig_frac == 0) {\n\t\t\t/* \".\" is not accepted in any format */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: plain period without leading or trailing digits\"));\n\t\t\tgoto parse_fail;\n\t\t} else if (dig_frac > 0) {\n\t\t\t/* \".123\" */\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_NAKED_FRAC) == 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: fraction part not allowed without \"\n\t\t\t\t                     \"leading integer digit(s)\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t} else {\n\t\t\t/* Empty (\"\") is allowed in some formats (e.g. Number(''), as zero,\n\t\t\t * but it must not have a leading +/- sign (GH-2019).  Note that\n\t\t\t * for Number(), h_str is already trimmed so we can check for zero\n\t\t\t * length and still get Number('  +  ') == NaN.\n\t\t\t */\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO) == 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: empty string not allowed (as zero)\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t} else if (DUK_HSTRING_GET_BYTELEN(h_str) != 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: no digits, but not empty (had a +/- sign)\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif (dig_frac == 0) {\n\t\t\t/* \"123.\" is allowed in some formats */\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_EMPTY_FRAC) == 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: empty fractions\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t} else if (dig_frac > 0) {\n\t\t\t/* \"123.456\" */\n\t\t\t;\n\t\t} else {\n\t\t\t/* \"123\" */\n\t\t\t;\n\t\t}\n\t}\n\n\t/* Exponent without digits (e.g. \"1e\" or \"1e+\").  If trailing garbage is\n\t * allowed, ignore exponent part as garbage (= parse as \"1\", i.e. exp 0).\n\t */\n\n\tif (dig_expt == 0) {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_GARBAGE) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: empty exponent\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t\tDUK_ASSERT(expt == 0);\n\t}\n\n\tif (expt_neg) {\n\t\texpt = -expt;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"expt=%ld, expt_adj=%ld, net exponent -> %ld\",\n\t                     (long) expt, (long) expt_adj, (long) (expt + expt_adj)));\n\texpt += expt_adj;\n\n\t/* Fast path check. */\n\n\tif (nc_ctx->f.n <= 1 &&   /* 32-bit value */\n\t    expt == 0    /* no net exponent */) {\n\t\t/* Fast path is triggered for no exponent and also for balanced exponent\n\t\t * and fraction parts, e.g. for \"1.23e2\" == \"123\".  Remember to respect\n\t\t * zero sign.\n\t\t */\n\n\t\t/* XXX: could accept numbers larger than 32 bits, e.g. up to 53 bits? */\n\t\tDUK_DDD(DUK_DDDPRINT(\"fast path number parse\"));\n\t\tif (nc_ctx->f.n == 1) {\n\t\t\tres = (double) nc_ctx->f.v[0];\n\t\t} else {\n\t\t\tres = 0.0;\n\t\t}\n\t\tgoto negcheck_and_ret;\n\t}\n\n\t/* Significand ('f') padding. */\n\n\twhile (dig_prec < duk__str2num_digits_for_radix[radix - 2]) {\n\t\t/* Pad significand with \"virtual\" zero digits so that Dragon4 will\n\t\t * have enough (apparent) precision to work with.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"dig_prec=%ld, pad significand with zero\", (long) dig_prec));\n\t\tduk__bi_mul_small_copy(&nc_ctx->f, (duk_uint32_t) radix, &nc_ctx->t1);\n\t\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\t\texpt--;\n\t\tdig_prec++;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"final exponent: %ld\", (long) expt));\n\n\t/* Detect zero special case. */\n\n\tif (nc_ctx->f.n == 0) {\n\t\t/* This may happen even after the fast path check, if exponent is\n\t\t * not balanced (e.g. \"0e1\").  Remember to respect zero sign.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"significand is zero\"));\n\t\tres = 0.0;\n\t\tgoto negcheck_and_ret;\n\t}\n\n\n\t/* Quick reject of too large or too small exponents.  This check\n\t * would be incorrect for zero (e.g. \"0e1000\" is zero, not Infinity)\n\t * so zero check must be above.\n\t */\n\n\texplim = &duk__str2num_exp_limits[radix - 2];\n\tif (expt > explim->upper) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"exponent too large -> infinite\"));\n\t\tres = (duk_double_t) DUK_DOUBLE_INFINITY;\n\t\tgoto negcheck_and_ret;\n\t} else if (expt < explim->lower) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"exponent too small -> zero\"));\n\t\tres = (duk_double_t) 0.0;\n\t\tgoto negcheck_and_ret;\n\t}\n\n\tnc_ctx->is_s2n = 1;\n\tnc_ctx->e = expt;\n\tnc_ctx->b = radix;\n\tnc_ctx->B = 2;\n\tnc_ctx->is_fixed = 1;\n\tnc_ctx->abs_pos = 0;\n\tnc_ctx->req_digits = 53 + 1;\n\n\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\tDUK_DDD(DUK_DDDPRINT(\"e=%ld\", (long) nc_ctx->e));\n\n\t/*\n\t *  Dragon4 slow path (binary) digit generation.\n\t *  An extra digit is generated for rounding.\n\t */\n\n\tduk__dragon4_prepare(nc_ctx);  /* setup many variables in nc_ctx */\n\n\tDUK_DDD(DUK_DDDPRINT(\"after prepare:\"));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_scale(nc_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"after scale; k=%ld\", (long) nc_ctx->k));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_generate(nc_ctx);\n\n\tDUK_ASSERT(nc_ctx->count == 53 + 1);\n\n\t/*\n\t *  Convert binary digits into an IEEE double.  Need to handle\n\t *  denormals and rounding correctly.\n\t *\n\t *  Some call sites currently assume the result is always a\n\t *  non-fastint double.  If this is changed, check all call\n\t *  sites.\n\t */\n\n\tduk__dragon4_ctx_to_double(nc_ctx, &res);\n\tgoto negcheck_and_ret;\n\n negcheck_and_ret:\n\tif (neg) {\n\t\tres = -res;\n\t}\n\tduk_pop(thr);\n\tduk_push_number(thr, (double) res);\n\tDUK_DDD(DUK_DDDPRINT(\"result: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\treturn;\n\n parse_fail:\n\tDUK_DDD(DUK_DDDPRINT(\"parse failed\"));\n\tduk_pop(thr);\n\tduk_push_nan(thr);\n\treturn;\n\n parse_explimit_error:\n\tDUK_DDD(DUK_DDDPRINT(\"parse failed, internal error, can't return a value\"));\n\tDUK_ERROR_RANGE(thr, \"exponent too large\");\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_INTERNAL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags) {\n\tduk_native_stack_check(thr);\n\tduk__numconv_parse_raw(thr, radix, flags);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_numconv.h",
    "content": "/*\n *  Number-to-string conversion.  The semantics of these is very tightly\n *  bound with the ECMAScript semantics required for call sites.\n */\n\n#if !defined(DUK_NUMCONV_H_INCLUDED)\n#define DUK_NUMCONV_H_INCLUDED\n\n/* Output a specified number of digits instead of using the shortest\n * form.  Used for toPrecision() and toFixed().\n */\n#define DUK_N2S_FLAG_FIXED_FORMAT         (1U << 0)\n\n/* Force exponential format.  Used for toExponential(). */\n#define DUK_N2S_FLAG_FORCE_EXP            (1U << 1)\n\n/* If number would need zero padding (for whole number part), use\n * exponential format instead.  E.g. if input number is 12300, 3\n * digits are generated (\"123\"), output \"1.23e+4\" instead of \"12300\".\n * Used for toPrecision().\n */\n#define DUK_N2S_FLAG_NO_ZERO_PAD          (1U << 2)\n\n/* Digit count indicates number of fractions (i.e. an absolute\n * digit index instead of a relative one).  Used together with\n * DUK_N2S_FLAG_FIXED_FORMAT for toFixed().\n */\n#define DUK_N2S_FLAG_FRACTION_DIGITS      (1U << 3)\n\n/*\n *  String-to-number conversion\n */\n\n/* Maximum exponent value when parsing numbers.  This is not strictly\n * compliant as there should be no upper limit, but as we parse the\n * exponent without a bigint, impose some limit.  The limit should be\n * small enough that multiplying it (or limit-1 to be precise) won't\n * overflow signed 32-bit integer range.  Exponent is only parsed with\n * radix 10, but with maximum radix (36) a safe limit is:\n * (10000000*36).toString(16) -> '15752a00'\n */\n#define DUK_S2N_MAX_EXPONENT              10000000L\n\n/* Trim white space (= allow leading and trailing whitespace) */\n#define DUK_S2N_FLAG_TRIM_WHITE           (1U << 0)\n\n/* Allow exponent */\n#define DUK_S2N_FLAG_ALLOW_EXP            (1U << 1)\n\n/* Allow trailing garbage (e.g. treat \"123foo\" as \"123) */\n#define DUK_S2N_FLAG_ALLOW_GARBAGE        (1U << 2)\n\n/* Allow leading plus sign */\n#define DUK_S2N_FLAG_ALLOW_PLUS           (1U << 3)\n\n/* Allow leading minus sign */\n#define DUK_S2N_FLAG_ALLOW_MINUS          (1U << 4)\n\n/* Allow 'Infinity' */\n#define DUK_S2N_FLAG_ALLOW_INF            (1U << 5)\n\n/* Allow fraction part */\n#define DUK_S2N_FLAG_ALLOW_FRAC           (1U << 6)\n\n/* Allow naked fraction (e.g. \".123\") */\n#define DUK_S2N_FLAG_ALLOW_NAKED_FRAC     (1U << 7)\n\n/* Allow empty fraction (e.g. \"123.\") */\n#define DUK_S2N_FLAG_ALLOW_EMPTY_FRAC     (1U << 8)\n\n/* Allow empty string to be interpreted as 0 */\n#define DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO  (1U << 9)\n\n/* Allow leading zeroes (e.g. \"0123\" -> \"123\") */\n#define DUK_S2N_FLAG_ALLOW_LEADING_ZERO   (1U << 10)\n\n/* Allow automatic detection of hex base (\"0x\" or \"0X\" prefix),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT   (1U << 11)\n\n/* Allow automatic detection of legacy octal base (\"0n\"),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_LEGACY_OCT_INT   (1U << 12)\n\n/* Allow automatic detection of ES2015 octal base (\"0o123\"),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT   (1U << 13)\n\n/* Allow automatic detection of ES2015 binary base (\"0b10001\"),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT   (1U << 14)\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags);\nDUK_INTERNAL_DECL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags);\n\n#endif  /* DUK_NUMCONV_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_refcount.h",
    "content": "/*\n *  Reference counting helper macros.  The macros take a thread argument\n *  and must thus always be executed in a specific thread context.  The\n *  thread argument is not really needed anymore: DECREF can operate with\n *  a heap pointer only, and INCREF needs neither.\n */\n\n#if !defined(DUK_REFCOUNT_H_INCLUDED)\n#define DUK_REFCOUNT_H_INCLUDED\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\n#if defined(DUK_USE_ROM_OBJECTS)\n/* With ROM objects \"needs refcount update\" is true when the value is\n * heap allocated and is not a ROM object.\n */\n/* XXX: double evaluation for 'tv' argument. */\n#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv) \\\n\t(DUK_TVAL_IS_HEAP_ALLOCATED((tv)) && !DUK_HEAPHDR_HAS_READONLY(DUK_TVAL_GET_HEAPHDR((tv))))\n#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h)  (!DUK_HEAPHDR_HAS_READONLY((h)))\n#else  /* DUK_USE_ROM_OBJECTS */\n/* Without ROM objects \"needs refcount update\" == is heap allocated. */\n#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)    DUK_TVAL_IS_HEAP_ALLOCATED((tv))\n#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h)  1\n#endif  /* DUK_USE_ROM_OBJECTS */\n\n/* Fast variants, inline refcount operations except for refzero handling.\n * Can be used explicitly when speed is always more important than size.\n * For a good compiler and a single file build, these are basically the\n * same as a forced inline.\n */\n#define DUK_TVAL_INCREF_FAST(thr,tv) do { \\\n\t\tduk_tval *duk__tv = (tv); \\\n\t\tDUK_ASSERT(duk__tv != NULL); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \\\n\t\t\tduk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \\\n\t\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(duk__h); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) != 0);  /* No wrapping. */ \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_DECREF_FAST(thr,tv) do { \\\n\t\tduk_tval *duk__tv = (tv); \\\n\t\tDUK_ASSERT(duk__tv != NULL); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \\\n\t\t\tduk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \\\n\t\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \\\n\t\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \\\n\t\t\t\tduk_heaphdr_refzero((thr), duk__h); \\\n\t\t\t} \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_DECREF_NORZ_FAST(thr,tv) do { \\\n\t\tduk_tval *duk__tv = (tv); \\\n\t\tDUK_ASSERT(duk__tv != NULL); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \\\n\t\t\tduk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \\\n\t\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \\\n\t\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \\\n\t\t\t\tduk_heaphdr_refzero_norz((thr), duk__h); \\\n\t\t\t} \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_INCREF_FAST(thr,h) do { \\\n\t\tduk_heaphdr *duk__h = (duk_heaphdr *) (h); \\\n\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\tif (DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(duk__h)) { \\\n\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(duk__h); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) != 0);  /* No wrapping. */ \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_FAST_RAW(thr,h,rzcall,rzcast) do { \\\n\t\tduk_heaphdr *duk__h = (duk_heaphdr *) (h); \\\n\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \\\n\t\tif (DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(duk__h)) { \\\n\t\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \\\n\t\t\t\t(rzcall)((thr), (rzcast) duk__h); \\\n\t\t\t} \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_FAST(thr,h) \\\n\tDUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero,duk_heaphdr *)\n#define DUK_HEAPHDR_DECREF_NORZ_FAST(thr,h) \\\n\tDUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero_norz,duk_heaphdr *)\n\n/* Slow variants, call to a helper to reduce code size.\n * Can be used explicitly when size is always more important than speed.\n */\n#define DUK_TVAL_INCREF_SLOW(thr,tv)         do { duk_tval_incref((tv)); } while (0)\n#define DUK_TVAL_DECREF_SLOW(thr,tv)         do { duk_tval_decref((thr), (tv)); } while (0)\n#define DUK_TVAL_DECREF_NORZ_SLOW(thr,tv)    do { duk_tval_decref_norz((thr), (tv)); } while (0)\n#define DUK_HEAPHDR_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HEAPHDR_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HSTRING_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HSTRING_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HSTRING_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HBUFFER_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HBUFFER_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HBUFFER_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HOBJECT_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HOBJECT_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HOBJECT_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n\n/* Default variants.  Selection depends on speed/size preference.\n * Concretely: with gcc 4.8.1 -Os x64 the difference in final binary\n * is about +1kB for _FAST variants.\n */\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n/* XXX: It would be nice to specialize for specific duk_hobject subtypes\n * but current refzero queue handling prevents that.\n */\n#define DUK_TVAL_INCREF(thr,tv)                DUK_TVAL_INCREF_FAST((thr),(tv))\n#define DUK_TVAL_DECREF(thr,tv)                DUK_TVAL_DECREF_FAST((thr),(tv))\n#define DUK_TVAL_DECREF_NORZ(thr,tv)           DUK_TVAL_DECREF_NORZ_FAST((thr),(tv))\n#define DUK_HEAPHDR_INCREF(thr,h)              DUK_HEAPHDR_INCREF_FAST((thr),(h))\n#define DUK_HEAPHDR_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero,duk_heaphdr *)\n#define DUK_HEAPHDR_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero_norz,duk_heaphdr *)\n#define DUK_HSTRING_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HSTRING_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hstring_refzero,duk_hstring *)\n#define DUK_HSTRING_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hstring_refzero,duk_hstring *)  /* no 'norz' variant */\n#define DUK_HOBJECT_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HOBJECT_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HOBJECT_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HBUFFER_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HBUFFER_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hbuffer_refzero,duk_hbuffer *)\n#define DUK_HBUFFER_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hbuffer_refzero,duk_hbuffer *)  /* no 'norz' variant */\n#define DUK_HCOMPFUNC_INCREF(thr,h)            DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HCOMPFUNC_DECREF(thr,h)            DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h)       DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HNATFUNC_INCREF(thr,h)             DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HNATFUNC_DECREF(thr,h)             DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HNATFUNC_DECREF_NORZ(thr,h)        DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HBUFOBJ_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HBUFOBJ_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HBUFOBJ_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HTHREAD_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HTHREAD_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HTHREAD_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#else\n#define DUK_TVAL_INCREF(thr,tv)                DUK_TVAL_INCREF_SLOW((thr),(tv))\n#define DUK_TVAL_DECREF(thr,tv)                DUK_TVAL_DECREF_SLOW((thr),(tv))\n#define DUK_TVAL_DECREF_NORZ(thr,tv)           DUK_TVAL_DECREF_NORZ_SLOW((thr),(tv))\n#define DUK_HEAPHDR_INCREF(thr,h)              DUK_HEAPHDR_INCREF_SLOW((thr),(h))\n#define DUK_HEAPHDR_DECREF(thr,h)              DUK_HEAPHDR_DECREF_SLOW((thr),(h))\n#define DUK_HEAPHDR_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HSTRING_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HSTRING_DECREF(thr,h)              DUK_HSTRING_DECREF_SLOW((thr),(h))\n#define DUK_HSTRING_DECREF_NORZ(thr,h)         DUK_HSTRING_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HOBJECT_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HOBJECT_DECREF(thr,h)              DUK_HOBJECT_DECREF_SLOW((thr),(h))\n#define DUK_HOBJECT_DECREF_NORZ(thr,h)         DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HBUFFER_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HBUFFER_DECREF(thr,h)              DUK_HBUFFER_DECREF_SLOW((thr),(h))\n#define DUK_HBUFFER_DECREF_NORZ(thr,h)         DUK_HBUFFER_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HCOMPFUNC_INCREF(thr,h)            DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HCOMPFUNC_DECREF(thr,h)            DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h)       DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HNATFUNC_INCREF(thr,h)             DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HNATFUNC_DECREF(thr,h)             DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HNATFUNC_DECREF_NORZ(thr,h)        DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HBUFOBJ_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HBUFOBJ_DECREF(thr,h)              DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HBUFOB_DECREF_NORZ(thr,h)          DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HTHREAD_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HTHREAD_DECREF(thr,h)              DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HTHREAD_DECREF_NORZ(thr,h)         DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#endif\n\n/* Convenience for some situations; the above macros don't allow NULLs\n * for performance reasons.  Macros cover only actually needed cases.\n */\n#define DUK_HEAPHDR_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HEAPHDR_DECREF((thr), (duk_heaphdr *) (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HEAPHDR_DECREF_NORZ((thr), (duk_heaphdr *) (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HOBJECT_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HOBJECT_INCREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HOBJECT_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HOBJECT_DECREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HOBJECT_DECREF_NORZ((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HBUFFER_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HBUFFER_INCREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HBUFFER_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HBUFFER_DECREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HBUFFER_DECREF_NORZ((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HTHREAD_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HTHREAD_INCREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HTHREAD_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HTHREAD_DECREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HTHREAD_DECREF_NORZ((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n\n/* Called after one or more DECREF NORZ calls to handle pending side effects.\n * At present DECREF NORZ does freeing inline but doesn't execute finalizers,\n * so these macros check for pending finalizers and execute them.  The FAST\n * variant is performance critical.\n */\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n#define DUK_REFZERO_CHECK_FAST(thr) do { \\\n\t\tduk_refzero_check_fast((thr)); \\\n\t} while (0)\n#define DUK_REFZERO_CHECK_SLOW(thr) do { \\\n\t\tduk_refzero_check_slow((thr)); \\\n\t} while (0)\n#else  /* DUK_USE_FINALIZER_SUPPORT */\n#define DUK_REFZERO_CHECK_FAST(thr) do { } while (0)\n#define DUK_REFZERO_CHECK_SLOW(thr) do { } while (0)\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Macros to set a duk_tval and update refcount of the target (decref the\n *  old value and incref the new value if necessary).  This is both performance\n *  and footprint critical; any changes made should be measured for size/speed.\n */\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_UNDEFINED(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_UNDEFINED(tv__dst); \\\n\t\tDUK_TVAL_DECREF_NORZ((thr), &tv__tmp); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_UNUSED(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NULL_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NULL(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_BOOLEAN(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NUMBER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NUMBER(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_DOUBLE(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_NAN_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NAN(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_I48(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_I32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_I32(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_U32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_U32(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#else\n#define DUK_TVAL_SET_DOUBLE_CAST_UPDREF(thr,tvptr_dst,newval) \\\n\tDUK_TVAL_SET_DOUBLE_UPDREF((thr), (tvptr_dst), (duk_double_t) (newval))\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0(thr,tvptr_dst,lf_v,lf_fp,lf_flags) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_LIGHTFUNC(tv__dst, (lf_v), (lf_fp), (lf_flags)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_STRING_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_STRING(tv__dst, (newval)); \\\n\t\tDUK_HSTRING_INCREF((thr), (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_OBJECT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_OBJECT(tv__dst, (newval)); \\\n\t\tDUK_HOBJECT_INCREF((thr), (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BUFFER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_BUFFER(tv__dst, (newval)); \\\n\t\tDUK_HBUFFER_INCREF((thr), (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_POINTER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_POINTER(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n/* DUK_TVAL_SET_TVAL_UPDREF() is used a lot in executor, property lookups,\n * etc, so it's very important for performance.  Measure when changing.\n *\n * NOTE: the source and destination duk_tval pointers may be the same, and\n * the macros MUST deal with that correctly.\n */\n\n/* Original idiom used, minimal code size. */\n#define DUK_TVAL_SET_TVAL_UPDREF_ALT0(thr,tvptr_dst,tvptr_src) do { \\\n\t\tduk_tval *tv__dst, *tv__src; duk_tval tv__tmp; \\\n\t\ttv__dst = (tvptr_dst); tv__src = (tvptr_src); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\tDUK_TVAL_INCREF((thr), tv__src); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n/* Faster alternative: avoid making a temporary copy of tvptr_dst and use\n * fast incref/decref macros.\n */\n#define DUK_TVAL_SET_TVAL_UPDREF_ALT1(thr,tvptr_dst,tvptr_src) do { \\\n\t\tduk_tval *tv__dst, *tv__src; duk_heaphdr *h__obj; \\\n\t\ttv__dst = (tvptr_dst); tv__src = (tvptr_src); \\\n\t\tDUK_TVAL_INCREF_FAST((thr), tv__src); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv__dst)) { \\\n\t\t\th__obj = DUK_TVAL_GET_HEAPHDR(tv__dst); \\\n\t\t\tDUK_ASSERT(h__obj != NULL); \\\n\t\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\t\tDUK_HEAPHDR_DECREF_FAST((thr), h__obj);  /* side effects */ \\\n\t\t} else { \\\n\t\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\t} \\\n\t} while (0)\n\n/* XXX: no optimized variants yet */\n#define DUK_TVAL_SET_UNDEFINED_UPDREF         DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ    DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0\n#define DUK_TVAL_SET_UNUSED_UPDREF            DUK_TVAL_SET_UNUSED_UPDREF_ALT0\n#define DUK_TVAL_SET_NULL_UPDREF              DUK_TVAL_SET_NULL_UPDREF_ALT0\n#define DUK_TVAL_SET_BOOLEAN_UPDREF           DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_UPDREF            DUK_TVAL_SET_NUMBER_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF    DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0\n#define DUK_TVAL_SET_DOUBLE_UPDREF            DUK_TVAL_SET_DOUBLE_UPDREF_ALT0\n#define DUK_TVAL_SET_NAN_UPDREF               DUK_TVAL_SET_NAN_UPDREF_ALT0\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_I48_UPDREF_ALT0\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_I32_UPDREF_ALT0\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_U32_UPDREF_ALT0\n#else\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF  /* XXX: fast int-to-double */\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_FASTINT_UPDREF           DUK_TVAL_SET_I48_UPDREF  /* convenience */\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF         DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0\n#define DUK_TVAL_SET_STRING_UPDREF            DUK_TVAL_SET_STRING_UPDREF_ALT0\n#define DUK_TVAL_SET_OBJECT_UPDREF            DUK_TVAL_SET_OBJECT_UPDREF_ALT0\n#define DUK_TVAL_SET_BUFFER_UPDREF            DUK_TVAL_SET_BUFFER_UPDREF_ALT0\n#define DUK_TVAL_SET_POINTER_UPDREF           DUK_TVAL_SET_POINTER_UPDREF_ALT0\n\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n/* Optimized for speed. */\n#define DUK_TVAL_SET_TVAL_UPDREF              DUK_TVAL_SET_TVAL_UPDREF_ALT1\n#define DUK_TVAL_SET_TVAL_UPDREF_FAST         DUK_TVAL_SET_TVAL_UPDREF_ALT1\n#define DUK_TVAL_SET_TVAL_UPDREF_SLOW         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#else\n/* Optimized for size. */\n#define DUK_TVAL_SET_TVAL_UPDREF              DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_FAST         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_SLOW         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#endif\n\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\n#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)     0\n#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h)   0\n\n#define DUK_TVAL_INCREF_FAST(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_FAST(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_NORZ_FAST(thr,v)       do {} while (0) /* nop */\n#define DUK_TVAL_INCREF_SLOW(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_SLOW(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_NORZ_SLOW(thr,v)       do {} while (0) /* nop */\n#define DUK_TVAL_INCREF(thr,v)                 do {} while (0) /* nop */\n#define DUK_TVAL_DECREF(thr,v)                 do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_NORZ(thr,v)            do {} while (0) /* nop */\n#define DUK_HEAPHDR_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HEAPHDR_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HEAPHDR_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HSTRING_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HSTRING_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n\n#define DUK_HCOMPFUNC_INCREF(thr,h)            do {} while (0) /* nop */\n#define DUK_HCOMPFUNC_DECREF(thr,h)            do {} while (0) /* nop */\n#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h)       do {} while (0) /* nop */\n#define DUK_HNATFUNC_INCREF(thr,h)             do {} while (0) /* nop */\n#define DUK_HNATFUNC_DECREF(thr,h)             do {} while (0) /* nop */\n#define DUK_HNATFUNC_DECREF_NORZ(thr,h)        do {} while (0) /* nop */\n#define DUK_HBUFOBJ_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFOBJ_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFOBJ_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HTHREAD_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HTHREAD_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HTHREAD_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr,h)  do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr,h)  do {} while (0) /* nop */\n\n#define DUK_REFZERO_CHECK_FAST(thr)            do {} while (0) /* nop */\n#define DUK_REFZERO_CHECK_SLOW(thr)            do {} while (0) /* nop */\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_UNDEFINED(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_UNUSED(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NULL_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NULL(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_BOOLEAN(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NUMBER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NUMBER(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_DOUBLE(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_NAN_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NAN(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_I48(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_I32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_I32(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_U32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_U32(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#else\n#define DUK_TVAL_SET_DOUBLE_CAST_UPDREF(thr,tvptr_dst,newval) \\\n\tDUK_TVAL_SET_DOUBLE_UPDREF((thr), (tvptr_dst), (duk_double_t) (newval))\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0(thr,tvptr_dst,lf_v,lf_fp,lf_flags) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_LIGHTFUNC(tv__dst, (lf_v), (lf_fp), (lf_flags)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_STRING_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_STRING(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_OBJECT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_OBJECT(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BUFFER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_BUFFER(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_POINTER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_POINTER(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_TVAL_UPDREF_ALT0(thr,tvptr_dst,tvptr_src) do { \\\n\t\tduk_tval *tv__dst, *tv__src; \\\n\t\ttv__dst = (tvptr_dst); tv__src = (tvptr_src); \\\n\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF         DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ    DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0\n#define DUK_TVAL_SET_UNUSED_UPDREF            DUK_TVAL_SET_UNUSED_UPDREF_ALT0\n#define DUK_TVAL_SET_NULL_UPDREF              DUK_TVAL_SET_NULL_UPDREF_ALT0\n#define DUK_TVAL_SET_BOOLEAN_UPDREF           DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_UPDREF            DUK_TVAL_SET_NUMBER_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF    DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0\n#define DUK_TVAL_SET_DOUBLE_UPDREF            DUK_TVAL_SET_DOUBLE_UPDREF_ALT0\n#define DUK_TVAL_SET_NAN_UPDREF               DUK_TVAL_SET_NAN_UPDREF_ALT0\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_I48_UPDREF_ALT0\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_I32_UPDREF_ALT0\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_U32_UPDREF_ALT0\n#else\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF  /* XXX: fast-int-to-double */\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_FASTINT_UPDREF           DUK_TVAL_SET_I48_UPDREF  /* convenience */\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF         DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0\n#define DUK_TVAL_SET_STRING_UPDREF            DUK_TVAL_SET_STRING_UPDREF_ALT0\n#define DUK_TVAL_SET_OBJECT_UPDREF            DUK_TVAL_SET_OBJECT_UPDREF_ALT0\n#define DUK_TVAL_SET_BUFFER_UPDREF            DUK_TVAL_SET_BUFFER_UPDREF_ALT0\n#define DUK_TVAL_SET_POINTER_UPDREF           DUK_TVAL_SET_POINTER_UPDREF_ALT0\n\n#define DUK_TVAL_SET_TVAL_UPDREF              DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_FAST         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_SLOW         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/*\n *  Some convenience macros that don't have optimized implementations now.\n */\n\n#define DUK_TVAL_SET_TVAL_UPDREF_NORZ(thr,tv_dst,tv_src) do { \\\n\t\tduk_hthread *duk__thr = (thr); \\\n\t\tduk_tval *duk__dst = (tv_dst); \\\n\t\tduk_tval *duk__src = (tv_src); \\\n\t\tDUK_UNREF(duk__thr); \\\n\t\tDUK_TVAL_DECREF_NORZ(thr, duk__dst); \\\n\t\tDUK_TVAL_SET_TVAL(duk__dst, duk__src); \\\n\t\tDUK_TVAL_INCREF(thr, duk__dst); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_U32_UPDREF_NORZ(thr,tv_dst,val) do { \\\n\t\tduk_hthread *duk__thr = (thr); \\\n\t\tduk_tval *duk__dst = (tv_dst); \\\n\t\tduk_uint32_t duk__val = (duk_uint32_t) (val); \\\n\t\tDUK_UNREF(duk__thr); \\\n\t\tDUK_TVAL_DECREF_NORZ(thr, duk__dst); \\\n\t\tDUK_TVAL_SET_U32(duk__dst, duk__val); \\\n\t} while (0)\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL_DECL void duk_refzero_check_slow(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_refzero_check_fast(duk_hthread *thr);\n#endif\nDUK_INTERNAL_DECL void duk_heaphdr_refcount_finalize_norz(duk_heap *heap, duk_heaphdr *hdr);\nDUK_INTERNAL_DECL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject *h);\n#if 0  /* Not needed: fast path handles inline; slow path uses duk_heaphdr_decref() which is needed anyway. */\nDUK_INTERNAL_DECL void duk_hstring_decref(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_hstring_decref_norz(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_hbuffer_decref(duk_hthread *thr, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_hbuffer_decref_norz(duk_hthread *thr, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_hobject_decref(duk_hthread *thr, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_hobject_decref_norz(duk_hthread *thr, duk_hobject *h);\n#endif\nDUK_INTERNAL_DECL void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_refzero_norz(duk_hthread *thr, duk_heaphdr *h);\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\nDUK_INTERNAL_DECL void duk_hstring_refzero(duk_hthread *thr, duk_hstring *h);  /* no 'norz' variant */\nDUK_INTERNAL_DECL void duk_hbuffer_refzero(duk_hthread *thr, duk_hbuffer *h);  /* no 'norz' variant */\nDUK_INTERNAL_DECL void duk_hobject_refzero(duk_hthread *thr, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_hobject_refzero_norz(duk_hthread *thr, duk_hobject *h);\n#else\nDUK_INTERNAL_DECL void duk_tval_incref(duk_tval *tv);\nDUK_INTERNAL_DECL void duk_tval_decref(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL void duk_tval_decref_norz(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL void duk_heaphdr_incref(duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h);\n#endif\n#else  /* DUK_USE_REFERENCE_COUNTING */\n/* no refcounting */\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#endif  /* DUK_REFCOUNT_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_regexp.h",
    "content": "/*\n *  Regular expression structs, constants, and bytecode defines.\n */\n\n#if !defined(DUK_REGEXP_H_INCLUDED)\n#define DUK_REGEXP_H_INCLUDED\n\n/* maximum bytecode copies for {n,m} quantifiers */\n#define DUK_RE_MAX_ATOM_COPIES             1000\n\n/* regexp compilation limits */\n#define DUK_RE_COMPILE_TOKEN_LIMIT         100000000L   /* 1e8 */\n\n/* regexp execution limits */\n#define DUK_RE_EXECUTE_STEPS_LIMIT         1000000000L  /* 1e9 */\n\n/* regexp opcodes */\n#define DUK_REOP_MATCH                     1\n#define DUK_REOP_CHAR                      2\n#define DUK_REOP_PERIOD                    3\n#define DUK_REOP_RANGES                    4\n#define DUK_REOP_INVRANGES                 5\n#define DUK_REOP_JUMP                      6\n#define DUK_REOP_SPLIT1                    7\n#define DUK_REOP_SPLIT2                    8\n#define DUK_REOP_SQMINIMAL                 9\n#define DUK_REOP_SQGREEDY                  10\n#define DUK_REOP_SAVE                      11\n#define DUK_REOP_WIPERANGE                 12\n#define DUK_REOP_LOOKPOS                   13\n#define DUK_REOP_LOOKNEG                   14\n#define DUK_REOP_BACKREFERENCE             15\n#define DUK_REOP_ASSERT_START              16\n#define DUK_REOP_ASSERT_END                17\n#define DUK_REOP_ASSERT_WORD_BOUNDARY      18\n#define DUK_REOP_ASSERT_NOT_WORD_BOUNDARY  19\n\n/* flags */\n#define DUK_RE_FLAG_GLOBAL                 (1U << 0)\n#define DUK_RE_FLAG_IGNORE_CASE            (1U << 1)\n#define DUK_RE_FLAG_MULTILINE              (1U << 2)\n\nstruct duk_re_matcher_ctx {\n\tduk_hthread *thr;\n\n\tduk_uint32_t re_flags;\n\tconst duk_uint8_t *input;\n\tconst duk_uint8_t *input_end;\n\tconst duk_uint8_t *bytecode;\n\tconst duk_uint8_t *bytecode_end;\n\tconst duk_uint8_t **saved;  /* allocated from valstack (fixed buffer) */\n\tduk_uint32_t nsaved;\n\tduk_uint32_t recursion_depth;\n\tduk_uint32_t recursion_limit;\n\tduk_uint32_t steps_count;\n\tduk_uint32_t steps_limit;\n};\n\nstruct duk_re_compiler_ctx {\n\tduk_hthread *thr;\n\n\tduk_uint32_t re_flags;\n\tduk_lexer_ctx lex;\n\tduk_re_token curr_token;\n\tduk_bufwriter_ctx bw;\n\tduk_uint32_t captures;  /* highest capture number emitted so far (used as: ++captures) */\n\tduk_uint32_t highest_backref;\n\tduk_uint32_t recursion_depth;\n\tduk_uint32_t recursion_limit;\n\tduk_uint32_t nranges;  /* internal temporary value, used for char classes */\n};\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL_DECL void duk_regexp_compile(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_regexp_create_instance(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_regexp_match(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_regexp_match_force_global(duk_hthread *thr);  /* hacky helper for String.prototype.split() */\n#endif\n\n#endif  /* DUK_REGEXP_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_regexp_compiler.c",
    "content": "/*\n *  Regexp compilation.\n *\n *  See doc/regexp.rst for a discussion of the compilation approach and\n *  current limitations.\n *\n *  Regexp bytecode assumes jumps can be expressed with signed 32-bit\n *  integers.  Consequently the bytecode size must not exceed 0x7fffffffL.\n *  The implementation casts duk_size_t (buffer size) to duk_(u)int32_t\n *  in many places.  Although this could be changed, the bytecode format\n *  limit would still prevent regexps exceeding the signed 32-bit limit\n *  from working.\n *\n *  XXX: The implementation does not prevent bytecode from exceeding the\n *  maximum supported size.  This could be done by limiting the maximum\n *  input string size (assuming an upper bound can be computed for number\n *  of bytecode bytes emitted per input byte) or checking buffer maximum\n *  size when emitting bytecode (slower).\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Helper macros\n */\n\n#define DUK__RE_INITIAL_BUFSIZE 64\n\n#define DUK__RE_BUFLEN(re_ctx) \\\n\tDUK_BW_GET_SIZE(re_ctx->thr, &re_ctx->bw)\n\n/*\n *  Disjunction struct: result of parsing a disjunction\n */\n\ntypedef struct {\n\t/* Number of characters that the atom matches (e.g. 3 for 'abc'),\n\t * -1 if atom is complex and number of matched characters either\n\t * varies or is not known.\n\t */\n\tduk_int32_t charlen;\n\n#if 0\n\t/* These are not needed to implement quantifier capture handling,\n\t * but might be needed at some point.\n\t */\n\n\t/* re_ctx->captures at start and end of atom parsing.\n\t * Since 'captures' indicates highest capture number emitted\n\t * so far in a DUK_REOP_SAVE, the captures numbers saved by\n\t * the atom are: ]start_captures,end_captures].\n\t */\n\tduk_uint32_t start_captures;\n\tduk_uint32_t end_captures;\n#endif\n} duk__re_disjunction_info;\n\n/*\n *  Encoding helpers\n *\n *  Some of the typing is bytecode based, e.g. slice sizes are unsigned 32-bit\n *  even though the buffer operations will use duk_size_t.\n */\n\n/* XXX: the insert helpers should ensure that the bytecode result is not\n * larger than expected (or at least assert for it).  Many things in the\n * bytecode, like skip offsets, won't work correctly if the bytecode is\n * larger than say 2G.\n */\n\nDUK_LOCAL duk_uint32_t duk__encode_i32(duk_int32_t x) {\n\tif (x < 0) {\n\t\treturn ((duk_uint32_t) (-x)) * 2 + 1;\n\t} else {\n\t\treturn ((duk_uint32_t) x) * 2;\n\t}\n}\n\n/* XXX: return type should probably be duk_size_t, or explicit checks are needed for\n * maximum size.\n */\nDUK_LOCAL duk_uint32_t duk__insert_u32(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_uint32_t x) {\n\tduk_uint8_t buf[DUK_UNICODE_MAX_XUTF8_LENGTH];\n\tduk_small_int_t len;\n\n\tlen = duk_unicode_encode_xutf8((duk_ucodepoint_t) x, buf);\n\tDUK_ASSERT(len >= 0);\n\tDUK_BW_INSERT_ENSURE_BYTES(re_ctx->thr, &re_ctx->bw, offset, buf, (duk_size_t) len);\n\treturn (duk_uint32_t) len;\n}\n\nDUK_LOCAL void duk__append_u32(duk_re_compiler_ctx *re_ctx, duk_uint32_t x) {\n\tDUK_BW_WRITE_ENSURE_XUTF8(re_ctx->thr, &re_ctx->bw, x);\n}\n\nDUK_LOCAL void duk__append_7bit(duk_re_compiler_ctx *re_ctx, duk_uint32_t x) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk__append_u32(re_ctx, x);\n#else\n\tDUK_ASSERT(x <= 0x7fU);\n\tDUK_BW_WRITE_ENSURE_U8(re_ctx->thr, &re_ctx->bw, (duk_uint8_t) x);\n#endif\n}\n\n#if 0\nDUK_LOCAL void duk__append_2bytes(duk_re_compiler_ctx *re_ctx, duk_uint8_t x, duk_uint8_t y) {\n\tDUK_BW_WRITE_ENSURE_U8_2(re_ctx->thr, &re_ctx->bw, x, y);\n}\n#endif\n\nDUK_LOCAL duk_uint32_t duk__insert_i32(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_int32_t x) {\n\treturn duk__insert_u32(re_ctx, offset, duk__encode_i32(x));\n}\n\nDUK_LOCAL void duk__append_reop(duk_re_compiler_ctx *re_ctx, duk_uint32_t reop) {\n\tDUK_ASSERT(reop <= 0x7fU);\n\t(void) duk__append_7bit(re_ctx, reop);\n}\n\n#if 0  /* unused */\nDUK_LOCAL void duk__append_i32(duk_re_compiler_ctx *re_ctx, duk_int32_t x) {\n\tduk__append_u32(re_ctx, duk__encode_i32(x));\n}\n#endif\n\n/* special helper for emitting u16 lists (used for character ranges for built-in char classes) */\nDUK_LOCAL void duk__append_u16_list(duk_re_compiler_ctx *re_ctx, const duk_uint16_t *values, duk_uint32_t count) {\n\t/* Call sites don't need the result length so it's not accumulated. */\n\twhile (count-- > 0) {\n\t\tduk__append_u32(re_ctx, (duk_uint32_t) (*values++));\n\t}\n}\n\nDUK_LOCAL void duk__insert_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_uint32_t data_offset, duk_uint32_t data_length) {\n\tDUK_BW_INSERT_ENSURE_SLICE(re_ctx->thr, &re_ctx->bw, offset, data_offset, data_length);\n}\n\nDUK_LOCAL void duk__append_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t data_offset, duk_uint32_t data_length) {\n\tDUK_BW_WRITE_ENSURE_SLICE(re_ctx->thr, &re_ctx->bw, data_offset, data_length);\n}\n\nDUK_LOCAL void duk__remove_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t data_offset, duk_uint32_t data_length) {\n\tDUK_BW_REMOVE_ENSURE_SLICE(re_ctx->thr, &re_ctx->bw, data_offset, data_length);\n}\n\n/*\n *  Insert a jump offset at 'offset' to complete an instruction\n *  (the jump offset is always the last component of an instruction).\n *  The 'skip' argument must be computed relative to 'offset',\n *  -without- taking into account the skip field being inserted.\n *\n *       ... A B C ins X Y Z ...   (ins may be a JUMP, SPLIT1/SPLIT2, etc)\n *   =>  ... A B C ins SKIP X Y Z\n *\n *  Computing the final (adjusted) skip value, which is relative to the\n *  first byte of the next instruction, is a bit tricky because of the\n *  variable length UTF-8 encoding.  See doc/regexp.rst for discussion.\n */\nDUK_LOCAL duk_uint32_t duk__insert_jump_offset(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_int32_t skip) {\n#if 0\n\t/* Iterative solution. */\n\tif (skip < 0) {\n\t\tduk_small_int_t len;\n\t\t/* two encoding attempts suffices */\n\t\tlen = duk_unicode_get_xutf8_length((duk_codepoint_t) duk__encode_i32(skip));\n\t\tlen = duk_unicode_get_xutf8_length((duk_codepoint_t) duk__encode_i32(skip - (duk_int32_t) len));\n\t\tDUK_ASSERT(duk_unicode_get_xutf8_length(duk__encode_i32(skip - (duk_int32_t) len)) == len);  /* no change */\n\t\tskip -= (duk_int32_t) len;\n\t}\n#endif\n\n#if defined(DUK_USE_PREFER_SIZE)\n\t/* Closed form solution, this produces smallest code.\n\t * See re_neg_jump_offset (closed2).\n\t */\n\tif (skip < 0) {\n\t\tskip--;\n\t\tif (skip < -0x3fL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x3ffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x7fffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0xfffffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x1ffffffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x3fffffffL) {\n\t\t\tskip--;\n\t\t}\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\t/* Closed form solution, this produces fastest code.\n\t * See re_neg_jump_offset (closed1).\n\t */\n\tif (skip < 0) {\n\t\tif (skip >= -0x3eL) {\n\t\t\tskip -= 1;\n\t\t} else if (skip >= -0x3fdL) {\n\t\t\tskip -= 2;\n\t\t} else if (skip >= -0x7ffcL) {\n\t\t\tskip -= 3;\n\t\t} else if (skip >= -0xffffbL) {\n\t\t\tskip -= 4;\n\t\t} else if (skip >= -0x1fffffaL) {\n\t\t\tskip -= 5;\n\t\t} else if (skip >= -0x3ffffff9L) {\n\t\t\tskip -= 6;\n\t\t} else {\n\t\t\tskip -= 7;\n\t\t}\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n\treturn duk__insert_i32(re_ctx, offset, skip);\n}\n\nDUK_LOCAL duk_uint32_t duk__append_jump_offset(duk_re_compiler_ctx *re_ctx, duk_int32_t skip) {\n\treturn (duk_uint32_t) duk__insert_jump_offset(re_ctx, (duk_uint32_t) DUK__RE_BUFLEN(re_ctx), skip);\n}\n\n/*\n *  duk_re_range_callback for generating character class ranges.\n *\n *  When ignoreCase is false, the range is simply emitted as is.  We don't,\n *  for instance, eliminate duplicates or overlapping ranges in a character\n *  class.\n *\n *  When ignoreCase is true but the 'direct' flag is set, the caller knows\n *  that the range canonicalizes to itself for case insensitive matching,\n *  so the range is emitted as is.  This is mainly useful for built-in ranges\n *  like \\W.\n *\n *  Otherwise, when ignoreCase is true, the range needs to be normalized\n *  through canonicalization.  Unfortunately a canonicalized version of a\n *  continuous range is not necessarily continuous (e.g. [x-{] is continuous\n *  but [X-{] is not).  As a result, a single input range may expand to a lot\n *  of output ranges.  The current algorithm creates the canonicalized ranges\n *  footprint efficiently at the cost of compile time execution time; see\n *  doc/regexp.rst for discussion, and some more details below.\n *\n *  Note that the ctx->nranges is a context-wide temporary value.  This is OK\n *  because there cannot be multiple character classes being parsed\n *  simultaneously.\n *\n *  More detail on canonicalization:\n *\n *  Conceptually, a range is canonicalized by scanning the entire range,\n *  normalizing each codepoint by converting it to uppercase, and generating\n *  a set of result ranges.\n *\n *  Ideally a minimal set of output ranges would be emitted by merging all\n *  possible ranges even if they're emitted out of sequence.  Because the\n *  input string is also case normalized during matching, some codepoints\n *  never occur at runtime; these \"don't care\" codepoints can be included or\n *  excluded from ranges when merging/optimizing ranges.\n *\n *  The current algorithm does not do optimal range merging.  Rather, output\n *  codepoints are generated in sequence, and when the output codepoints are\n *  continuous (CP, CP+1, CP+2, ...), they are merged locally into as large a\n *  range as possible.  A small canonicalization bitmap is used to reduce\n *  actual codepoint canonicalizations which are quite slow at present.  The\n *  bitmap provides a \"codepoint block is continuous with respect to\n *  canonicalization\" for N-codepoint blocks.  This allows blocks to be\n *  skipped quickly.\n *\n *  There are a number of shortcomings and future work here:\n *\n *    - Individual codepoint normalizations are slow because they involve\n *      walking bit-packed rules without a lookup index.\n *\n *    - The conceptual algorithm needs to canonicalize every codepoint in the\n *      input range to figure out the output range(s).  Even with the small\n *      canonicalization bitmap the algorithm runs quite slowly for worst case\n *      inputs.  There are many data structure alternatives to improve this.\n *\n *    - While the current algorithm generates maximal output ranges when the\n *      output codepoints are emitted linearly, output ranges are not sorted or\n *      merged otherwise.  In the worst case a lot of ranges are emitted when\n *      most of the ranges could be merged.  In this process one could take\n *      advantage of \"don't care\" codepoints, which are never matched against at\n *      runtime due to canonicalization of input codepoints before comparison,\n *      to merge otherwise discontinuous output ranges.\n *\n *    - The runtime data structure is just a linear list of ranges to match\n *      against.  This can be quite slow if there are a lot of output ranges.\n *      There are various ways to make matching against the ranges faster,\n *      e.g. sorting the ranges and using a binary search; skip lists; tree\n *      based representations; full or approximate codepoint bitmaps, etc.\n *\n *    - Only BMP is supported, codepoints above BMP are assumed to canonicalize\n *      to themselves.  For now this is one place where we don't want to\n *      support chars outside the BMP, because the exhaustive search would be\n *      massively larger.  It would be possible to support non-BMP with a\n *      different algorithm, or perhaps doing case normalization only at match\n *      time.\n */\n\nDUK_LOCAL void duk__regexp_emit_range(duk_re_compiler_ctx *re_ctx, duk_codepoint_t r1, duk_codepoint_t r2) {\n\tDUK_ASSERT(r2 >= r1);\n\tduk__append_u32(re_ctx, (duk_uint32_t) r1);\n\tduk__append_u32(re_ctx, (duk_uint32_t) r2);\n\tre_ctx->nranges++;\n}\n\n#if defined(DUK_USE_REGEXP_CANON_BITMAP)\n/* Find next canonicalization discontinuity (conservative estimate) starting\n * from 'start', not exceeding 'end'.  If continuity is fine up to 'end'\n * inclusive, returns end.  Minimum possible return value is start.\n */\nDUK_LOCAL duk_codepoint_t duk__re_canon_next_discontinuity(duk_codepoint_t start, duk_codepoint_t end) {\n\tduk_uint_t start_blk;\n\tduk_uint_t end_blk;\n\tduk_uint_t blk;\n\tduk_uint_t offset;\n\tduk_uint8_t mask;\n\n\t/* Inclusive block range. */\n\tDUK_ASSERT(start >= 0);\n\tDUK_ASSERT(end >= 0);\n\tDUK_ASSERT(end >= start);\n\tstart_blk = (duk_uint_t) (start >> DUK_CANON_BITMAP_BLKSHIFT);\n\tend_blk = (duk_uint_t) (end >> DUK_CANON_BITMAP_BLKSHIFT);\n\n\tfor (blk = start_blk; blk <= end_blk; blk++) {\n\t\toffset = blk >> 3;\n\t\tmask = 1U << (blk & 0x07);\n\t\tif (offset >= sizeof(duk_unicode_re_canon_bitmap)) {\n\t\t\t/* Reached non-BMP range which is assumed continuous. */\n\t\t\treturn end;\n\t\t}\n\t\tDUK_ASSERT(offset < sizeof(duk_unicode_re_canon_bitmap));\n\t\tif ((duk_unicode_re_canon_bitmap[offset] & mask) == 0) {\n\t\t\t/* Block is discontinuous, continuity is guaranteed\n\t\t\t * only up to end of previous block (+1 for exclusive\n\t\t\t * return value => start of current block).  Start\n\t\t\t * block requires special handling.\n\t\t\t */\n\t\t\tif (blk > start_blk) {\n\t\t\t\treturn (duk_codepoint_t) (blk << DUK_CANON_BITMAP_BLKSHIFT);\n\t\t\t} else {\n\t\t\t\treturn start;\n\t\t\t}\n\t\t}\n\t}\n\tDUK_ASSERT(blk == end_blk + 1);  /* Reached end block which is continuous. */\n\treturn end;\n}\n#else  /* DUK_USE_REGEXP_CANON_BITMAP */\nDUK_LOCAL duk_codepoint_t duk__re_canon_next_discontinuity(duk_codepoint_t start, duk_codepoint_t end) {\n\tDUK_ASSERT(start >= 0);\n\tDUK_ASSERT(end >= 0);\n\tDUK_ASSERT(end >= start);\n\tif (start >= 0x10000) {\n\t\t/* Even without the bitmap, treat non-BMP as continuous. */\n\t\treturn end;\n\t}\n\treturn start;\n}\n#endif  /* DUK_USE_REGEXP_CANON_BITMAP */\n\nDUK_LOCAL void duk__regexp_generate_ranges(void *userdata, duk_codepoint_t r1, duk_codepoint_t r2, duk_bool_t direct) {\n\tduk_re_compiler_ctx *re_ctx = (duk_re_compiler_ctx *) userdata;\n\tduk_codepoint_t r_start;\n\tduk_codepoint_t r_end;\n\tduk_codepoint_t i;\n\tduk_codepoint_t t;\n\tduk_codepoint_t r_disc;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__regexp_generate_ranges(): re_ctx=%p, range=[%ld,%ld] direct=%ld\",\n\t                   (void *) re_ctx, (long) r1, (long) r2, (long) direct));\n\n\tDUK_ASSERT(r2 >= r1);  /* SyntaxError for out of order range. */\n\n\tif (direct || (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) == 0) {\n\t\tDUK_DD(DUK_DDPRINT(\"direct or not case sensitive, emit range: [%ld,%ld]\", (long) r1, (long) r2));\n\t\tduk__regexp_emit_range(re_ctx, r1, r2);\n\t\treturn;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"case sensitive, process range: [%ld,%ld]\", (long) r1, (long) r2));\n\n\tr_start = duk_unicode_re_canonicalize_char(re_ctx->thr, r1);\n\tr_end = r_start;\n\n\tfor (i = r1 + 1; i <= r2;) {\n\t\t/* Input codepoint space processed up to i-1, and\n\t\t * current range in r_{start,end} is up-to-date\n\t\t * (inclusive) and may either break or continue.\n\t\t */\n\t\tr_disc = duk__re_canon_next_discontinuity(i, r2);\n\t\tDUK_ASSERT(r_disc >= i);\n\t\tDUK_ASSERT(r_disc <= r2);\n\n\t\tr_end += r_disc - i;  /* May be zero. */\n\t\tt = duk_unicode_re_canonicalize_char(re_ctx->thr, r_disc);\n\t\tif (t == r_end + 1) {\n\t\t\t/* Not actually a discontinuity, continue range\n\t\t\t * to r_disc and recheck.\n\t\t\t */\n\t\t\tr_end = t;\n\t\t} else {\n\t\t\tduk__regexp_emit_range(re_ctx, r_start, r_end);\n\t\t\tr_start = t;\n\t\t\tr_end = t;\n\t\t}\n\t\ti = r_disc + 1;  /* Guarantees progress. */\n\t}\n\tduk__regexp_emit_range(re_ctx, r_start, r_end);\n\n#if 0  /* Exhaustive search, very slow. */\n\tr_start = duk_unicode_re_canonicalize_char(re_ctx->thr, r1);\n\tr_end = r_start;\n\tfor (i = r1 + 1; i <= r2; i++) {\n\t\tt = duk_unicode_re_canonicalize_char(re_ctx->thr, i);\n\t\tif (t == r_end + 1) {\n\t\t\tr_end = t;\n\t\t} else {\n\t\t\tDUK_DD(DUK_DDPRINT(\"canonicalized, emit range: [%ld,%ld]\", (long) r_start, (long) r_end));\n\t\t\tduk__append_u32(re_ctx, (duk_uint32_t) r_start);\n\t\t\tduk__append_u32(re_ctx, (duk_uint32_t) r_end);\n\t\t\tre_ctx->nranges++;\n\t\t\tr_start = t;\n\t\t\tr_end = t;\n\t\t}\n\t}\n\tDUK_DD(DUK_DDPRINT(\"canonicalized, emit range: [%ld,%ld]\", (long) r_start, (long) r_end));\n\tduk__append_u32(re_ctx, (duk_uint32_t) r_start);\n\tduk__append_u32(re_ctx, (duk_uint32_t) r_end);\n\tre_ctx->nranges++;\n#endif\n}\n\n/*\n *  Parse regexp Disjunction.  Most of regexp compilation happens here.\n *\n *  Handles Disjunction, Alternative, and Term productions directly without\n *  recursion.  The only constructs requiring recursion are positive/negative\n *  lookaheads, capturing parentheses, and non-capturing parentheses.\n *\n *  The function determines whether the entire disjunction is a 'simple atom'\n *  (see doc/regexp.rst discussion on 'simple quantifiers') and if so,\n *  returns the atom character length which is needed by the caller to keep\n *  track of its own atom character length.  A disjunction with more than one\n *  alternative is never considered a simple atom (although in some cases\n *  that might be the case).\n *\n *  Return value: simple atom character length or < 0 if not a simple atom.\n *  Appends the bytecode for the disjunction matcher to the end of the temp\n *  buffer.\n *\n *  Regexp top level structure is:\n *\n *    Disjunction = Term*\n *                | Term* | Disjunction\n *\n *    Term = Assertion\n *         | Atom\n *         | Atom Quantifier\n *\n *  An empty Term sequence is a valid disjunction alternative (e.g. /|||c||/).\n *\n *  Notes:\n *\n *    * Tracking of the 'simple-ness' of the current atom vs. the entire\n *      disjunction are separate matters.  For instance, the disjunction\n *      may be complex, but individual atoms may be simple.  Furthermore,\n *      simple quantifiers are used whenever possible, even if the\n *      disjunction as a whole is complex.\n *\n *    * The estimate of whether an atom is simple is conservative now,\n *      and it would be possible to expand it.  For instance, captures\n *      cause the disjunction to be marked complex, even though captures\n *      -can- be handled by simple quantifiers with some minor modifications.\n *\n *    * Disjunction 'tainting' as 'complex' is handled at the end of the\n *      main for loop collectively for atoms.  Assertions, quantifiers,\n *      and '|' tokens need to taint the result manually if necessary.\n *      Assertions cannot add to result char length, only atoms (and\n *      quantifiers) can; currently quantifiers will taint the result\n *      as complex though.\n */\n\nDUK_LOCAL const duk_uint16_t * const duk__re_range_lookup1[3] = {\n\tduk_unicode_re_ranges_digit,\n\tduk_unicode_re_ranges_white,\n\tduk_unicode_re_ranges_wordchar\n};\nDUK_LOCAL const duk_uint8_t duk__re_range_lookup2[3] = {\n\tsizeof(duk_unicode_re_ranges_digit) / (2 * sizeof(duk_uint16_t)),\n\tsizeof(duk_unicode_re_ranges_white) / (2 * sizeof(duk_uint16_t)),\n\tsizeof(duk_unicode_re_ranges_wordchar) / (2 * sizeof(duk_uint16_t))\n};\n\nDUK_LOCAL void duk__append_range_atom_matcher(duk_re_compiler_ctx *re_ctx, duk_small_uint_t re_op, const duk_uint16_t *ranges, duk_small_uint_t count) {\n#if 0\n\tDUK_ASSERT(re_op <= 0x7fUL);\n\tDUK_ASSERT(count <= 0x7fUL);\n\tduk__append_2bytes(re_ctx, (duk_uint8_t) re_op, (duk_uint8_t) count);\n#endif\n\tduk__append_reop(re_ctx, re_op);\n\tduk__append_7bit(re_ctx, count);\n\tduk__append_u16_list(re_ctx, ranges, count * 2);\n}\n\nDUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t expect_eof, duk__re_disjunction_info *out_atom_info) {\n\tduk_int32_t atom_start_offset = -1;                   /* negative -> no atom matched on previous round */\n\tduk_int32_t atom_char_length = 0;                     /* negative -> complex atom */\n\tduk_uint32_t atom_start_captures = re_ctx->captures;  /* value of re_ctx->captures at start of atom */\n\tduk_int32_t unpatched_disjunction_split = -1;\n\tduk_int32_t unpatched_disjunction_jump = -1;\n\tduk_uint32_t entry_offset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);\n\tduk_int32_t res_charlen = 0;  /* -1 if disjunction is complex, char length if simple */\n\tduk__re_disjunction_info tmp_disj;\n\n\tDUK_ASSERT(out_atom_info != NULL);\n\n\tduk_native_stack_check(re_ctx->thr);\n\tif (re_ctx->recursion_depth >= re_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_COMPILER_RECURSION_LIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tre_ctx->recursion_depth++;\n\n#if 0\n\tout_atom_info->start_captures = re_ctx->captures;\n#endif\n\n\tfor (;;) {\n\t\t/* atom_char_length, atom_start_offset, atom_start_offset reflect the\n\t\t * atom matched on the previous loop.  If a quantifier is encountered\n\t\t * on this loop, these are needed to handle the quantifier correctly.\n\t\t * new_atom_char_length etc are for the atom parsed on this round;\n\t\t * they're written to atom_char_length etc at the end of the round.\n\t\t */\n\t\tduk_int32_t new_atom_char_length;   /* char length of the atom parsed in this loop */\n\t\tduk_int32_t new_atom_start_offset;  /* bytecode start offset of the atom parsed in this loop\n\t\t                                     * (allows quantifiers to copy the atom bytecode)\n\t\t                                     */\n\t\tduk_uint32_t new_atom_start_captures;  /* re_ctx->captures at the start of the atom parsed in this loop */\n\n\t\tduk_lexer_parse_re_token(&re_ctx->lex, &re_ctx->curr_token);\n\n\t\tDUK_DD(DUK_DDPRINT(\"re token: %ld (num=%ld, char=%c)\",\n\t\t                   (long) re_ctx->curr_token.t,\n\t\t                   (long) re_ctx->curr_token.num,\n\t\t                   (re_ctx->curr_token.num >= 0x20 && re_ctx->curr_token.num <= 0x7e) ?\n\t\t                   (int) re_ctx->curr_token.num : (int) '?'));\n\n\t\t/* set by atom case clauses */\n\t\tnew_atom_start_offset = -1;\n\t\tnew_atom_char_length = -1;\n\t\tnew_atom_start_captures = re_ctx->captures;\n\n\t\tswitch (re_ctx->curr_token.t) {\n\t\tcase DUK_RETOK_DISJUNCTION: {\n\t\t\t/*\n\t\t\t *  The handling here is a bit tricky.  If a previous '|' has been processed,\n\t\t\t *  we have a pending split1 and a pending jump (for a previous match).  These\n\t\t\t *  need to be back-patched carefully.  See docs for a detailed example.\n\t\t\t */\n\n\t\t\t/* patch pending jump and split */\n\t\t\tif (unpatched_disjunction_jump >= 0) {\n\t\t\t\tduk_uint32_t offset;\n\n\t\t\t\tDUK_ASSERT(unpatched_disjunction_split >= 0);\n\t\t\t\toffset = (duk_uint32_t) unpatched_disjunction_jump;\n\t\t\t\toffset += duk__insert_jump_offset(re_ctx,\n\t\t\t\t                                  offset,\n\t\t\t\t                                  (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - offset));\n\t\t\t\t/* offset is now target of the pending split (right after jump) */\n\t\t\t\tduk__insert_jump_offset(re_ctx,\n\t\t\t\t                        (duk_uint32_t) unpatched_disjunction_split,\n\t\t\t\t                        (duk_int32_t) offset - unpatched_disjunction_split);\n\t\t\t}\n\n\t\t\t/* add a new pending split to the beginning of the entire disjunction */\n\t\t\t(void) duk__insert_u32(re_ctx,\n\t\t\t                       entry_offset,\n\t\t\t                       DUK_REOP_SPLIT1);   /* prefer direct execution */\n\t\t\tunpatched_disjunction_split = (duk_int32_t) (entry_offset + 1);   /* +1 for opcode */\n\n\t\t\t/* add a new pending match jump for latest finished alternative */\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_JUMP);\n\t\t\tunpatched_disjunction_jump = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\n\t\t\t/* 'taint' result as complex */\n\t\t\tres_charlen = -1;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_QUANTIFIER: {\n\t\t\tif (atom_start_offset < 0) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_INVALID_QUANTIFIER_NO_ATOM);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tif (re_ctx->curr_token.qmin > re_ctx->curr_token.qmax) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_INVALID_QUANTIFIER_VALUES);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tif (atom_char_length >= 0) {\n\t\t\t\t/*\n\t\t\t\t *  Simple atom\n\t\t\t\t *\n\t\t\t\t *  If atom_char_length is zero, we'll have unbounded execution time for e.g.\n\t\t\t\t *  /()*x/.exec('x').  We can't just skip the match because it might have some\n\t\t\t\t *  side effects (for instance, if we allowed captures in simple atoms, the\n\t\t\t\t *  capture needs to happen).  The simple solution below is to force the\n\t\t\t\t *  quantifier to match at most once, since the additional matches have no effect.\n\t\t\t\t *\n\t\t\t\t *  With a simple atom there can be no capture groups, so no captures need\n\t\t\t\t *  to be reset.\n\t\t\t\t */\n\t\t\t\tduk_int32_t atom_code_length;\n\t\t\t\tduk_uint32_t offset;\n\t\t\t\tduk_uint32_t qmin, qmax;\n\n\t\t\t\tqmin = re_ctx->curr_token.qmin;\n\t\t\t\tqmax = re_ctx->curr_token.qmax;\n\t\t\t\tif (atom_char_length == 0) {\n\t\t\t\t\t/* qmin and qmax will be 0 or 1 */\n\t\t\t\t\tif (qmin > 1) {\n\t\t\t\t\t\tqmin = 1;\n\t\t\t\t\t}\n\t\t\t\t\tif (qmax > 1) {\n\t\t\t\t\t\tqmax = 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_MATCH);   /* complete 'sub atom' */\n\t\t\t\tatom_code_length = (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (duk_size_t) atom_start_offset);\n\n\t\t\t\toffset = (duk_uint32_t) atom_start_offset;\n\t\t\t\tif (re_ctx->curr_token.greedy) {\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, DUK_REOP_SQGREEDY);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmin);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmax);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, (duk_uint32_t) atom_char_length);\n\t\t\t\t\toffset += duk__insert_jump_offset(re_ctx, offset, atom_code_length);\n\t\t\t\t} else {\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, DUK_REOP_SQMINIMAL);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmin);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmax);\n\t\t\t\t\toffset += duk__insert_jump_offset(re_ctx, offset, atom_code_length);\n\t\t\t\t}\n\t\t\t\tDUK_UNREF(offset);  /* silence scan-build warning */\n\t\t\t} else {\n\t\t\t\t/*\n\t\t\t\t *  Complex atom\n\t\t\t\t *\n\t\t\t\t *  The original code is used as a template, and removed at the end\n\t\t\t\t *  (this differs from the handling of simple quantifiers).\n\t\t\t\t *\n\t\t\t\t *  NOTE: there is no current solution for empty atoms in complex\n\t\t\t\t *  quantifiers.  This would need some sort of a 'progress' instruction.\n\t\t\t\t *\n\t\t\t\t *  XXX: impose limit on maximum result size, i.e. atom_code_len * atom_copies?\n\t\t\t\t */\n\t\t\t\tduk_int32_t atom_code_length;\n\t\t\t\tduk_uint32_t atom_copies;\n\t\t\t\tduk_uint32_t tmp_qmin, tmp_qmax;\n\n\t\t\t\t/* pre-check how many atom copies we're willing to make (atom_copies not needed below) */\n\t\t\t\tatom_copies = (re_ctx->curr_token.qmax == DUK_RE_QUANTIFIER_INFINITE) ?\n\t\t\t\t              re_ctx->curr_token.qmin : re_ctx->curr_token.qmax;\n\t\t\t\tif (atom_copies > DUK_RE_MAX_ATOM_COPIES) {\n\t\t\t\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_QUANTIFIER_TOO_MANY_COPIES);\n\t\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t\t}\n\n\t\t\t\t/* wipe the capture range made by the atom (if any) */\n\t\t\t\tDUK_ASSERT(atom_start_captures <= re_ctx->captures);\n\t\t\t\tif (atom_start_captures != re_ctx->captures) {\n\t\t\t\t\tDUK_ASSERT(atom_start_captures < re_ctx->captures);\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"must wipe ]atom_start_captures,re_ctx->captures]: ]%ld,%ld]\",\n\t\t\t\t\t                     (long) atom_start_captures, (long) re_ctx->captures));\n\n\t\t\t\t\t/* insert (DUK_REOP_WIPERANGE, start, count) in reverse order so the order ends up right */\n\t\t\t\t\tduk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, (re_ctx->captures - atom_start_captures) * 2U);\n\t\t\t\t\tduk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, (atom_start_captures + 1) * 2);\n\t\t\t\t\tduk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, DUK_REOP_WIPERANGE);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"no need to wipe captures: atom_start_captures == re_ctx->captures == %ld\",\n\t\t\t\t\t                     (long) atom_start_captures));\n\t\t\t\t}\n\n\t\t\t\tatom_code_length = (duk_int32_t) DUK__RE_BUFLEN(re_ctx) - atom_start_offset;\n\n\t\t\t\t/* insert the required matches (qmin) by copying the atom */\n\t\t\t\ttmp_qmin = re_ctx->curr_token.qmin;\n\t\t\t\ttmp_qmax = re_ctx->curr_token.qmax;\n\t\t\t\twhile (tmp_qmin > 0) {\n\t\t\t\t\tduk__append_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t\t\ttmp_qmin--;\n\t\t\t\t\tif (tmp_qmax != DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\t\ttmp_qmax--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(tmp_qmin == 0);\n\n\t\t\t\t/* insert code for matching the remainder - infinite or finite */\n\t\t\t\tif (tmp_qmax == DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\t/* reuse last emitted atom for remaining 'infinite' quantifier */\n\n\t\t\t\t\tif (re_ctx->curr_token.qmin == 0) {\n\t\t\t\t\t\t/* Special case: original qmin was zero so there is nothing\n\t\t\t\t\t\t * to repeat.  Emit an atom copy but jump over it here.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_JUMP);\n\t\t\t\t\t\tduk__append_jump_offset(re_ctx, atom_code_length);\n\t\t\t\t\t\tduk__append_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t\t\t}\n\t\t\t\t\tif (re_ctx->curr_token.greedy) {\n\t\t\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_SPLIT2);   /* prefer jump */\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_SPLIT1);   /* prefer direct */\n\t\t\t\t\t}\n\t\t\t\t\tduk__append_jump_offset(re_ctx, -atom_code_length - 1);  /* -1 for opcode */\n\t\t\t\t} else {\n\t\t\t\t\t/*\n\t\t\t\t\t *  The remaining matches are emitted as sequence of SPLITs and atom\n\t\t\t\t\t *  copies; the SPLITs skip the remaining copies and match the sequel.\n\t\t\t\t\t *  This sequence needs to be emitted starting from the last copy\n\t\t\t\t\t *  because the SPLITs are variable length due to the variable length\n\t\t\t\t\t *  skip offset.  This causes a lot of memory copying now.\n\t\t\t\t\t *\n\t\t\t\t\t *  Example structure (greedy, match maximum # atoms):\n\t\t\t\t\t *\n\t\t\t\t\t *      SPLIT1 LSEQ\n\t\t\t\t\t *      (atom)\n\t\t\t\t\t *      SPLIT1 LSEQ    ; <- the byte length of this instruction is needed\n\t\t\t\t\t *      (atom)         ; to encode the above SPLIT1 correctly\n\t\t\t\t\t *      ...\n\t\t\t\t\t *   LSEQ:\n\t\t\t\t\t */\n\t\t\t\t\tduk_uint32_t offset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\t\t\twhile (tmp_qmax > 0) {\n\t\t\t\t\t\tduk__insert_slice(re_ctx, offset, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t\t\t\tif (re_ctx->curr_token.greedy) {\n\t\t\t\t\t\t\tduk__insert_u32(re_ctx, offset, DUK_REOP_SPLIT1);   /* prefer direct */\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tduk__insert_u32(re_ctx, offset, DUK_REOP_SPLIT2);   /* prefer jump */\n\t\t\t\t\t\t}\n\t\t\t\t\t\tduk__insert_jump_offset(re_ctx,\n\t\t\t\t\t\t                        offset + 1,   /* +1 for opcode */\n\t\t\t\t\t\t                        (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (offset + 1)));\n\t\t\t\t\t\ttmp_qmax--;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* remove the original 'template' atom */\n\t\t\t\tduk__remove_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t}\n\n\t\t\t/* 'taint' result as complex */\n\t\t\tres_charlen = -1;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_START: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_START);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_END: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_END);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_WORD_BOUNDARY: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_WORD_BOUNDARY);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_NOT_WORD_BOUNDARY);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_START_POS_LOOKAHEAD:\n\t\tcase DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD: {\n\t\t\tduk_uint32_t offset;\n\t\t\tduk_uint32_t opcode = (re_ctx->curr_token.t == DUK_RETOK_ASSERT_START_POS_LOOKAHEAD) ?\n\t\t\t                      DUK_REOP_LOOKPOS : DUK_REOP_LOOKNEG;\n\n\t\t\toffset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__parse_disjunction(re_ctx, 0, &tmp_disj);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_MATCH);\n\n\t\t\t(void) duk__insert_u32(re_ctx, offset, opcode);\n\t\t\t(void) duk__insert_jump_offset(re_ctx,\n\t\t\t                               offset + 1,   /* +1 for opcode */\n\t\t\t                               (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (offset + 1)));\n\n\t\t\t/* 'taint' result as complex -- this is conservative,\n\t\t\t * as lookaheads do not backtrack.\n\t\t\t */\n\t\t\tres_charlen = -1;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_PERIOD: {\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_PERIOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_CHAR: {\n\t\t\t/* Note: successive characters could be joined into string matches\n\t\t\t * but this is not trivial (consider e.g. '/xyz+/); see docs for\n\t\t\t * more discussion.\n\t\t\t *\n\t\t\t * No support for \\u{H+} yet.  While only BMP Unicode escapes are\n\t\t\t * supported for RegExps at present, 'ch' may still be a non-BMP\n\t\t\t * codepoint if it is decoded straight from source text UTF-8.\n\t\t\t * There's no non-BMP support yet so this is handled simply by\n\t\t\t * matching the non-BMP character (which is custom behavior).\n\t\t\t */\n\t\t\tduk_uint32_t ch;\n\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_CHAR);\n\t\t\tch = re_ctx->curr_token.num;\n\t\t\tif (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) {\n\t\t\t\tch = (duk_uint32_t) duk_unicode_re_canonicalize_char(re_ctx->thr, (duk_codepoint_t) ch);\n\t\t\t}\n\t\t\tduk__append_u32(re_ctx, ch);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_DIGIT:\n\t\tcase DUK_RETOK_ATOM_NOT_DIGIT:\n\t\tcase DUK_RETOK_ATOM_WHITE:\n\t\tcase DUK_RETOK_ATOM_NOT_WHITE:\n\t\tcase DUK_RETOK_ATOM_WORD_CHAR:\n\t\tcase DUK_RETOK_ATOM_NOT_WORD_CHAR: {\n\t\t\tduk_small_uint_t re_op;\n\t\t\tduk_small_uint_t idx;\n\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_DIGIT & 0x01) != 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_WHITE & 0x01) != 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_WORD_CHAR & 0x01) != 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_NOT_DIGIT & 0x01) == 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_NOT_WHITE & 0x01) == 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_NOT_WORD_CHAR & 0x01) == 0);\n\t\t\tre_op = (re_ctx->curr_token.t & 0x01) ? DUK_REOP_RANGES : DUK_REOP_INVRANGES;\n\n\t\t\tDUK_ASSERT(DUK_RETOK_ATOM_WHITE == DUK_RETOK_ATOM_DIGIT + 2);\n\t\t\tDUK_ASSERT(DUK_RETOK_ATOM_WORD_CHAR == DUK_RETOK_ATOM_DIGIT + 4);\n\t\t\tidx = (duk_small_uint_t) ((re_ctx->curr_token.t - DUK_RETOK_ATOM_DIGIT) >> 1U);\n\t\t\tDUK_ASSERT(idx <= 2U);  /* Assume continuous token numbers; also checks negative underflow. */\n\n\t\t\tduk__append_range_atom_matcher(re_ctx, re_op, duk__re_range_lookup1[idx], duk__re_range_lookup2[idx]);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_BACKREFERENCE: {\n\t\t\tduk_uint32_t backref = (duk_uint32_t) re_ctx->curr_token.num;\n\t\t\tif (backref > re_ctx->highest_backref) {\n\t\t\t\tre_ctx->highest_backref = backref;\n\t\t\t}\n\t\t\tnew_atom_char_length = -1;   /* mark as complex */\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_BACKREFERENCE);\n\t\t\tduk__append_u32(re_ctx, backref);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_START_CAPTURE_GROUP: {\n\t\t\tduk_uint32_t cap;\n\n\t\t\tnew_atom_char_length = -1;   /* mark as complex (capture handling) */\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tcap = ++re_ctx->captures;\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_SAVE);\n\t\t\tduk__append_u32(re_ctx, cap * 2);\n\t\t\tduk__parse_disjunction(re_ctx, 0, &tmp_disj);  /* retval (sub-atom char length) unused, tainted as complex above */\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_SAVE);\n\t\t\tduk__append_u32(re_ctx, cap * 2 + 1);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_START_NONCAPTURE_GROUP: {\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__parse_disjunction(re_ctx, 0, &tmp_disj);\n\t\t\tnew_atom_char_length = tmp_disj.charlen;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_START_CHARCLASS:\n\t\tcase DUK_RETOK_ATOM_START_CHARCLASS_INVERTED: {\n\t\t\t/*\n\t\t\t *  Range parsing is done with a special lexer function which calls\n\t\t\t *  us for every range parsed.  This is different from how rest of\n\t\t\t *  the parsing works, but avoids a heavy, arbitrary size intermediate\n\t\t\t *  value type to hold the ranges.\n\t\t\t *\n\t\t\t *  Another complication is the handling of character ranges when\n\t\t\t *  case insensitive matching is used (see docs for discussion).\n\t\t\t *  The range handler callback given to the lexer takes care of this\n\t\t\t *  as well.\n\t\t\t *\n\t\t\t *  Note that duplicate ranges are not eliminated when parsing character\n\t\t\t *  classes, so that canonicalization of\n\t\t\t *\n\t\t\t *    [0-9a-fA-Fx-{]\n\t\t\t *\n\t\t\t *  creates the result (note the duplicate ranges):\n\t\t\t *\n\t\t\t *    [0-9A-FA-FX-Z{-{]\n\t\t\t *\n\t\t\t *  where [x-{] is split as a result of canonicalization.  The duplicate\n\t\t\t *  ranges are not a semantics issue: they work correctly.\n\t\t\t */\n\n\t\t\tduk_uint32_t offset;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"character class\"));\n\n\t\t\t/* insert ranges instruction, range count patched in later */\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx,\n\t\t\t                 (re_ctx->curr_token.t == DUK_RETOK_ATOM_START_CHARCLASS) ?\n\t\t\t                 DUK_REOP_RANGES : DUK_REOP_INVRANGES);\n\t\t\toffset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);    /* patch in range count later */\n\n\t\t\t/* parse ranges until character class ends */\n\t\t\tre_ctx->nranges = 0;    /* note: ctx-wide temporary */\n\t\t\tduk_lexer_parse_re_ranges(&re_ctx->lex, duk__regexp_generate_ranges, (void *) re_ctx);\n\n\t\t\t/* insert range count */\n\t\t\tduk__insert_u32(re_ctx, offset, re_ctx->nranges);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_END_GROUP: {\n\t\t\tif (expect_eof) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_CLOSING_PAREN);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tgoto done;\n\t\t}\n\t\tcase DUK_RETOK_EOF: {\n\t\t\tif (!expect_eof) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_END_OF_PATTERN);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tgoto done;\n\t\t}\n\t\tdefault: {\n\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_REGEXP_TOKEN);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\t}\n\n\t\t/* a complex (new) atom taints the result */\n\t\tif (new_atom_start_offset >= 0) {\n\t\t\tif (new_atom_char_length < 0) {\n\t\t\t\tres_charlen = -1;\n\t\t\t} else if (res_charlen >= 0) {\n\t\t\t\t/* only advance if not tainted */\n\t\t\t\tres_charlen += new_atom_char_length;\n\t\t\t}\n\t\t}\n\n\t\t/* record previous atom info in case next token is a quantifier */\n\t\tatom_start_offset = new_atom_start_offset;\n\t\tatom_char_length = new_atom_char_length;\n\t\tatom_start_captures = new_atom_start_captures;\n\t}\n\n done:\n\n\t/* finish up pending jump and split for last alternative */\n\tif (unpatched_disjunction_jump >= 0) {\n\t\tduk_uint32_t offset;\n\n\t\tDUK_ASSERT(unpatched_disjunction_split >= 0);\n\t\toffset = (duk_uint32_t) unpatched_disjunction_jump;\n\t\toffset += duk__insert_jump_offset(re_ctx,\n\t\t                                  offset,\n\t\t                                  (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - offset));\n\t\t/* offset is now target of the pending split (right after jump) */\n\t\tduk__insert_jump_offset(re_ctx,\n\t\t                        (duk_uint32_t) unpatched_disjunction_split,\n\t\t                        (duk_int32_t) offset - unpatched_disjunction_split);\n\t}\n\n#if 0\n\tout_atom_info->end_captures = re_ctx->captures;\n#endif\n\tout_atom_info->charlen = res_charlen;\n\tDUK_DDD(DUK_DDDPRINT(\"parse disjunction finished: charlen=%ld\",\n\t                     (long) out_atom_info->charlen));\n\n\tre_ctx->recursion_depth--;\n}\n\n/*\n *  Flags parsing (see E5 Section 15.10.4.1).\n */\n\nDUK_LOCAL duk_uint32_t duk__parse_regexp_flags(duk_hthread *thr, duk_hstring *h) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint32_t flags = 0;\n\n\tp = DUK_HSTRING_GET_DATA(h);\n\tp_end = p + DUK_HSTRING_GET_BYTELEN(h);\n\n\t/* Note: can be safely scanned as bytes (undecoded) */\n\n\twhile (p < p_end) {\n\t\tduk_uint8_t c = *p++;\n\t\tswitch (c) {\n\t\tcase (duk_uint8_t) 'g': {\n\t\t\tif (flags & DUK_RE_FLAG_GLOBAL) {\n\t\t\t\tgoto flags_error;\n\t\t\t}\n\t\t\tflags |= DUK_RE_FLAG_GLOBAL;\n\t\t\tbreak;\n\t\t}\n\t\tcase (duk_uint8_t) 'i': {\n\t\t\tif (flags & DUK_RE_FLAG_IGNORE_CASE) {\n\t\t\t\tgoto flags_error;\n\t\t\t}\n\t\t\tflags |= DUK_RE_FLAG_IGNORE_CASE;\n\t\t\tbreak;\n\t\t}\n\t\tcase (duk_uint8_t) 'm': {\n\t\t\tif (flags & DUK_RE_FLAG_MULTILINE) {\n\t\t\t\tgoto flags_error;\n\t\t\t}\n\t\t\tflags |= DUK_RE_FLAG_MULTILINE;\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tgoto flags_error;\n\t\t}\n\t\t}\n\t}\n\n\treturn flags;\n\n flags_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_REGEXP_FLAGS);\n\tDUK_WO_NORETURN(return 0U;);\n}\n\n/*\n *  Create escaped RegExp source (E5 Section 15.10.3).\n *\n *  The current approach is to special case the empty RegExp\n *  ('' -> '(?:)') and otherwise replace unescaped '/' characters\n *  with '\\/' regardless of where they occur in the regexp.\n *\n *  Note that normalization does not seem to be necessary for\n *  RegExp literals (e.g. '/foo/') because to be acceptable as\n *  a RegExp literal, the text between forward slashes must\n *  already match the escaping requirements (e.g. must not contain\n *  unescaped forward slashes or be empty).  Escaping IS needed\n *  for expressions like 'new Regexp(\"...\", \"\")' however.\n *  Currently, we re-escape in either case.\n *\n *  Also note that we process the source here in UTF-8 encoded\n *  form.  This is correct, because any non-ASCII characters are\n *  passed through without change.\n */\n\nDUK_LOCAL void duk__create_escaped_source(duk_hthread *thr, int idx_pattern) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tduk_uint8_t *q;\n\tduk_size_t i, n;\n\tduk_uint_fast8_t c_prev, c;\n\n\th = duk_known_hstring(thr, idx_pattern);\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tn = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);\n\n\tif (n == 0) {\n\t\tduk_push_literal(thr, \"(?:)\");\n\t\treturn;\n\t}\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, n);\n\tq = DUK_BW_GET_PTR(thr, bw);\n\n\tc_prev = (duk_uint_fast8_t) 0;\n\n\tfor (i = 0; i < n; i++) {\n\t\tc = p[i];\n\n\t\tq = DUK_BW_ENSURE_RAW(thr, bw, 2, q);\n\n\t\tif (c == (duk_uint_fast8_t) '/' && c_prev != (duk_uint_fast8_t) '\\\\') {\n\t\t\t/* Unescaped '/' ANYWHERE in the regexp (in disjunction,\n\t\t\t * inside a character class, ...) => same escape works.\n\t\t\t */\n\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t}\n\t\t*q++ = (duk_uint8_t) c;\n\n\t\tc_prev = c;\n\t}\n\n\tDUK_BW_SETPTR_AND_COMPACT(thr, bw, q);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if input is safe. */\n\n\t/* [ ... escaped_source ] */\n}\n\n/*\n *  Exposed regexp compilation primitive.\n *\n *  Sets up a regexp compilation context, and calls duk__parse_disjunction() to do the\n *  actual parsing.  Handles generation of the compiled regexp header and the\n *  \"boilerplate\" capture of the matching substring (save 0 and 1).  Also does some\n *  global level regexp checks after recursive compilation has finished.\n *\n *  An escaped version of the regexp source, suitable for use as a RegExp instance\n *  'source' property (see E5 Section 15.10.3), is also left on the stack.\n *\n *  Input stack:  [ pattern flags ]\n *  Output stack: [ bytecode escaped_source ]  (both as strings)\n */\n\nDUK_INTERNAL void duk_regexp_compile(duk_hthread *thr) {\n\tduk_re_compiler_ctx re_ctx;\n\tduk_lexer_point lex_point;\n\tduk_hstring *h_pattern;\n\tduk_hstring *h_flags;\n\tduk__re_disjunction_info ign_disj;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/*\n\t *  Args validation\n\t */\n\n\t/* TypeError if fails */\n\th_pattern = duk_require_hstring_notsymbol(thr, -2);\n\th_flags = duk_require_hstring_notsymbol(thr, -1);\n\n\t/*\n\t *  Create normalized 'source' property (E5 Section 15.10.3).\n\t */\n\n\t/* [ ... pattern flags ] */\n\n\tduk__create_escaped_source(thr, -2);\n\n\t/* [ ... pattern flags escaped_source ] */\n\n\t/*\n\t *  Init compilation context\n\t */\n\n\t/* [ ... pattern flags escaped_source buffer ] */\n\n\tduk_memzero(&re_ctx, sizeof(re_ctx));\n\tDUK_LEXER_INITCTX(&re_ctx.lex);  /* duplicate zeroing, expect for (possible) NULL inits */\n\tre_ctx.thr = thr;\n\tre_ctx.lex.thr = thr;\n\tre_ctx.lex.input = DUK_HSTRING_GET_DATA(h_pattern);\n\tre_ctx.lex.input_length = DUK_HSTRING_GET_BYTELEN(h_pattern);\n\tre_ctx.lex.token_limit = DUK_RE_COMPILE_TOKEN_LIMIT;\n\tre_ctx.recursion_limit = DUK_USE_REGEXP_COMPILER_RECLIMIT;\n\tre_ctx.re_flags = duk__parse_regexp_flags(thr, h_flags);\n\n\tDUK_BW_INIT_PUSHBUF(thr, &re_ctx.bw, DUK__RE_INITIAL_BUFSIZE);\n\n\tDUK_DD(DUK_DDPRINT(\"regexp compiler ctx initialized, flags=0x%08lx, recursion_limit=%ld\",\n\t                   (unsigned long) re_ctx.re_flags, (long) re_ctx.recursion_limit));\n\n\t/*\n\t *  Init lexer\n\t */\n\n\tlex_point.offset = 0;  /* expensive init, just want to fill window */\n\tlex_point.line = 1;\n\tDUK_LEXER_SETPOINT(&re_ctx.lex, &lex_point);\n\n\t/*\n\t *  Compilation\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"starting regexp compilation\"));\n\n\tduk__append_reop(&re_ctx, DUK_REOP_SAVE);\n\tduk__append_7bit(&re_ctx, 0);\n\tduk__parse_disjunction(&re_ctx, 1 /*expect_eof*/, &ign_disj);\n\tduk__append_reop(&re_ctx, DUK_REOP_SAVE);\n\tduk__append_7bit(&re_ctx, 1);\n\tduk__append_reop(&re_ctx, DUK_REOP_MATCH);\n\n\t/*\n\t *  Check for invalid backreferences; note that it is NOT an error\n\t *  to back-reference a capture group which has not yet been introduced\n\t *  in the pattern (as in /\\1(foo)/); in fact, the backreference will\n\t *  always match!  It IS an error to back-reference a capture group\n\t *  which will never be introduced in the pattern.  Thus, we can check\n\t *  for such references only after parsing is complete.\n\t */\n\n\tif (re_ctx.highest_backref > re_ctx.captures) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_BACKREFS);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/*\n\t *  Emit compiled regexp header: flags, ncaptures\n\t *  (insertion order inverted on purpose)\n\t */\n\n\tduk__insert_u32(&re_ctx, 0, (re_ctx.captures + 1) * 2);\n\tduk__insert_u32(&re_ctx, 0, re_ctx.re_flags);\n\n\t/* [ ... pattern flags escaped_source buffer ] */\n\n\tDUK_BW_COMPACT(thr, &re_ctx.bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe because flags is at most 7 bit. */\n\n\t/* [ ... pattern flags escaped_source bytecode ] */\n\n\t/*\n\t *  Finalize stack\n\t */\n\n\tduk_remove(thr, -4);     /* -> [ ... flags escaped_source bytecode ] */\n\tduk_remove(thr, -3);     /* -> [ ... escaped_source bytecode ] */\n\n\tDUK_DD(DUK_DDPRINT(\"regexp compilation successful, bytecode: %!T, escaped source: %!T\",\n\t                   (duk_tval *) duk_get_tval(thr, -1), (duk_tval *) duk_get_tval(thr, -2)));\n}\n\n/*\n *  Create a RegExp instance (E5 Section 15.10.7).\n *\n *  Note: the output stack left by duk_regexp_compile() is directly compatible\n *  with the input here.\n *\n *  Input stack:  [ escaped_source bytecode ]  (both as strings)\n *  Output stack: [ RegExp ]\n */\n\nDUK_INTERNAL void duk_regexp_create_instance(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\t/* [ ... escaped_source bytecode ] */\n\n\tduk_push_object(thr);\n\th = duk_known_hobject(thr, -1);\n\tduk_insert(thr, -3);\n\n\t/* [ ... regexp_object escaped_source bytecode ] */\n\n\tDUK_HOBJECT_SET_CLASS_NUMBER(h, DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[DUK_BIDX_REGEXP_PROTOTYPE]);\n\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_BYTECODE, DUK_PROPDESC_FLAGS_NONE);\n\n\t/* [ ... regexp_object escaped_source ] */\n\n\t/* In ES2015 .source, and the .global, .multiline, etc flags are\n\t * inherited getters.  Store the escaped source as an internal\n\t * property for the getter.\n\t */\n\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_SOURCE, DUK_PROPDESC_FLAGS_NONE);\n\n\t/* [ ... regexp_object ] */\n\n\tduk_push_int(thr, 0);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LAST_INDEX, DUK_PROPDESC_FLAGS_W);\n\n\t/* [ ... regexp_object ] */\n}\n\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\n/* regexp support disabled */\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_regexp_executor.c",
    "content": "/*\n *  Regexp executor.\n *\n *  Safety: the ECMAScript executor should prevent user from reading and\n *  replacing regexp bytecode.  Even so, the executor must validate all\n *  memory accesses etc.  When an invalid access is detected (e.g. a 'save'\n *  opcode to invalid, unallocated index) it should fail with an internal\n *  error but not cause a segmentation fault.\n *\n *  Notes:\n *\n *    - Backtrack counts are limited to unsigned 32 bits but should\n *      technically be duk_size_t for strings longer than 4G chars.\n *      This also requires a regexp bytecode change.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Helpers for UTF-8 handling\n *\n *  For bytecode readers the duk_uint32_t and duk_int32_t types are correct\n *  because they're used for more than just codepoints.\n */\n\nDUK_LOCAL duk_uint32_t duk__bc_get_u32(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **pc) {\n\treturn (duk_uint32_t) duk_unicode_decode_xutf8_checked(re_ctx->thr, pc, re_ctx->bytecode, re_ctx->bytecode_end);\n}\n\nDUK_LOCAL duk_int32_t duk__bc_get_i32(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **pc) {\n\tduk_uint32_t t;\n\n\t/* signed integer encoding needed to work with UTF-8 */\n\tt = (duk_uint32_t) duk_unicode_decode_xutf8_checked(re_ctx->thr, pc, re_ctx->bytecode, re_ctx->bytecode_end);\n\tif (t & 1) {\n\t\treturn -((duk_int32_t) (t >> 1));\n\t} else {\n\t\treturn (duk_int32_t) (t >> 1);\n\t}\n}\n\nDUK_LOCAL const duk_uint8_t *duk__utf8_backtrack(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_uint_fast32_t count) {\n\tconst duk_uint8_t *p;\n\n\t/* Note: allow backtracking from p == ptr_end */\n\tp = *ptr;\n\tif (p < ptr_start || p > ptr_end) {\n\t\tgoto fail;\n\t}\n\n\twhile (count > 0) {\n\t\tfor (;;) {\n\t\t\tp--;\n\t\t\tif (p < ptr_start) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tif ((*p & 0xc0) != 0x80) {\n\t\t\t\t/* utf-8 continuation bytes have the form 10xx xxxx */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcount--;\n\t}\n\t*ptr = p;\n\treturn p;\n\n fail:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_LOCAL const duk_uint8_t *duk__utf8_advance(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_uint_fast32_t count) {\n\tconst duk_uint8_t *p;\n\n\tp = *ptr;\n\tif (p < ptr_start || p >= ptr_end) {\n\t\tgoto fail;\n\t}\n\n\twhile (count > 0) {\n\t\tfor (;;) {\n\t\t\tp++;\n\n\t\t\t/* Note: if encoding ends by hitting end of input, we don't check that\n\t\t\t * the encoding is valid, we just assume it is.\n\t\t\t */\n\t\t\tif (p >= ptr_end || ((*p & 0xc0) != 0x80)) {\n\t\t\t\t/* utf-8 continuation bytes have the form 10xx xxxx */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcount--;\n\t}\n\n\t*ptr = p;\n\treturn p;\n\n fail:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Helpers for dealing with the input string\n */\n\n/* Get a (possibly canonicalized) input character from current sp.  The input\n * itself is never modified, and captures always record non-canonicalized\n * characters even in case-insensitive matching.  Return <0 if out of input.\n */\nDUK_LOCAL duk_codepoint_t duk__inp_get_cp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **sp) {\n\tduk_codepoint_t res;\n\n\tif (*sp >= re_ctx->input_end) {\n\t\treturn -1;\n\t}\n\tres = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(re_ctx->thr, sp, re_ctx->input, re_ctx->input_end);\n\tif (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) {\n\t\tres = duk_unicode_re_canonicalize_char(re_ctx->thr, res);\n\t}\n\treturn res;\n}\n\nDUK_LOCAL const duk_uint8_t *duk__inp_backtrack(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **sp, duk_uint_fast32_t count) {\n\treturn duk__utf8_backtrack(re_ctx->thr, sp, re_ctx->input, re_ctx->input_end, count);\n}\n\n/* Backtrack utf-8 input and return a (possibly canonicalized) input character. */\nDUK_LOCAL duk_codepoint_t duk__inp_get_prev_cp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t *sp) {\n\t/* note: caller 'sp' is intentionally not updated here */\n\t(void) duk__inp_backtrack(re_ctx, &sp, (duk_uint_fast32_t) 1);\n\treturn duk__inp_get_cp(re_ctx, &sp);\n}\n\n/*\n *  Regexp recursive matching function.\n *\n *  Returns 'sp' on successful match (points to character after last matched one),\n *  NULL otherwise.\n *\n *  The C recursion depth limit check is only performed in this function, this\n *  suffices because the function is present in all true recursion required by\n *  regexp execution.\n */\n\nDUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t *pc, const duk_uint8_t *sp) {\n\tduk_native_stack_check(re_ctx->thr);\n\tif (re_ctx->recursion_depth >= re_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_EXECUTOR_RECURSION_LIMIT);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\tre_ctx->recursion_depth++;\n\n\tfor (;;) {\n\t\tduk_small_int_t op;\n\n\t\tif (re_ctx->steps_count >= re_ctx->steps_limit) {\n\t\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_EXECUTOR_STEP_LIMIT);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t\tre_ctx->steps_count++;\n\n\t\t/* Opcodes are at most 7 bits now so they encode to one byte.  If this\n\t\t * were not the case or 'pc' is invalid here (due to a bug etc) we'll\n\t\t * still fail safely through the switch default case.\n\t\t */\n\t\tDUK_ASSERT(pc[0] <= 0x7fU);\n#if 0\n\t\top = (duk_small_int_t) duk__bc_get_u32(re_ctx, &pc);\n#endif\n\t\top = *pc++;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"match: rec=%ld, steps=%ld, pc (after op)=%ld, sp=%ld, op=%ld\",\n\t\t                     (long) re_ctx->recursion_depth,\n\t\t                     (long) re_ctx->steps_count,\n\t\t                     (long) (pc - re_ctx->bytecode),\n\t\t                     (long) (sp - re_ctx->input),\n\t\t                     (long) op));\n\n\t\tswitch (op) {\n\t\tcase DUK_REOP_MATCH: {\n\t\t\tgoto match;\n\t\t}\n\t\tcase DUK_REOP_CHAR: {\n\t\t\t/*\n\t\t\t *  Byte-based matching would be possible for case-sensitive\n\t\t\t *  matching but not for case-insensitive matching.  So, we\n\t\t\t *  match by decoding the input and bytecode character normally.\n\t\t\t *\n\t\t\t *  Bytecode characters are assumed to be already canonicalized.\n\t\t\t *  Input characters are canonicalized automatically by\n\t\t\t *  duk__inp_get_cp() if necessary.\n\t\t\t *\n\t\t\t *  There is no opcode for matching multiple characters.  The\n\t\t\t *  regexp compiler has trouble joining strings efficiently\n\t\t\t *  during compilation.  See doc/regexp.rst for more discussion.\n\t\t\t */\n\t\t\tduk_codepoint_t c1, c2;\n\n\t\t\tc1 = (duk_codepoint_t) duk__bc_get_u32(re_ctx, &pc);\n\t\t\tDUK_ASSERT(!(re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) ||\n\t\t\t           c1 == duk_unicode_re_canonicalize_char(re_ctx->thr, c1));  /* canonicalized by compiler */\n\t\t\tc2 = duk__inp_get_cp(re_ctx, &sp);\n\t\t\t/* No need to check for c2 < 0 (end of input): because c1 >= 0, it\n\t\t\t * will fail the match below automatically and cause goto fail.\n\t\t\t */\n#if 0\n\t\t\tif (c2 < 0) {\n\t\t\t\tgoto fail;\n\t\t\t}\n#endif\n\t\t\tDUK_ASSERT(c1 >= 0);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"char match, c1=%ld, c2=%ld\", (long) c1, (long) c2));\n\t\t\tif (c1 != c2) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_PERIOD: {\n\t\t\tduk_codepoint_t c;\n\n\t\t\tc = duk__inp_get_cp(re_ctx, &sp);\n\t\t\tif (c < 0 || duk_unicode_is_line_terminator(c)) {\n\t\t\t\t/* E5 Sections 15.10.2.8, 7.3 */\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_RANGES:\n\t\tcase DUK_REOP_INVRANGES: {\n\t\t\tduk_uint32_t n;\n\t\t\tduk_codepoint_t c;\n\t\t\tduk_small_int_t match;\n\n\t\t\tn = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tc = duk__inp_get_cp(re_ctx, &sp);\n\t\t\tif (c < 0) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\n\t\t\tmatch = 0;\n\t\t\twhile (n) {\n\t\t\t\tduk_codepoint_t r1, r2;\n\t\t\t\tr1 = (duk_codepoint_t) duk__bc_get_u32(re_ctx, &pc);\n\t\t\t\tr2 = (duk_codepoint_t) duk__bc_get_u32(re_ctx, &pc);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"matching ranges/invranges, n=%ld, r1=%ld, r2=%ld, c=%ld\",\n\t\t\t\t                     (long) n, (long) r1, (long) r2, (long) c));\n\t\t\t\tif (c >= r1 && c <= r2) {\n\t\t\t\t\t/* Note: don't bail out early, we must read all the ranges from\n\t\t\t\t\t * bytecode.  Another option is to skip them efficiently after\n\t\t\t\t\t * breaking out of here.  Prefer smallest code.\n\t\t\t\t\t */\n\t\t\t\t\tmatch = 1;\n\t\t\t\t}\n\t\t\t\tn--;\n\t\t\t}\n\n\t\t\tif (op == DUK_REOP_RANGES) {\n\t\t\t\tif (!match) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(op == DUK_REOP_INVRANGES);\n\t\t\t\tif (match) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_ASSERT_START: {\n\t\t\tduk_codepoint_t c;\n\n\t\t\tif (sp <= re_ctx->input) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!(re_ctx->re_flags & DUK_RE_FLAG_MULTILINE)) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tc = duk__inp_get_prev_cp(re_ctx, sp);\n\t\t\tif (duk_unicode_is_line_terminator(c)) {\n\t\t\t\t/* E5 Sections 15.10.2.8, 7.3 */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_ASSERT_END: {\n\t\t\tduk_codepoint_t c;\n\t\t\tconst duk_uint8_t *tmp_sp;\n\n\t\t\ttmp_sp = sp;\n\t\t\tc = duk__inp_get_cp(re_ctx, &tmp_sp);\n\t\t\tif (c < 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!(re_ctx->re_flags & DUK_RE_FLAG_MULTILINE)) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tif (duk_unicode_is_line_terminator(c)) {\n\t\t\t\t/* E5 Sections 15.10.2.8, 7.3 */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_ASSERT_WORD_BOUNDARY:\n\t\tcase DUK_REOP_ASSERT_NOT_WORD_BOUNDARY: {\n\t\t\t/*\n\t\t\t *  E5 Section 15.10.2.6.  The previous and current character\n\t\t\t *  should -not- be canonicalized as they are now.  However,\n\t\t\t *  canonicalization does not affect the result of IsWordChar()\n\t\t\t *  (which depends on Unicode characters never canonicalizing\n\t\t\t *  into ASCII characters) so this does not matter.\n\t\t\t */\n\t\t\tduk_small_int_t w1, w2;\n\n\t\t\tif (sp <= re_ctx->input) {\n\t\t\t\tw1 = 0;  /* not a wordchar */\n\t\t\t} else {\n\t\t\t\tduk_codepoint_t c;\n\t\t\t\tc = duk__inp_get_prev_cp(re_ctx, sp);\n\t\t\t\tw1 = duk_unicode_re_is_wordchar(c);\n\t\t\t}\n\t\t\tif (sp >= re_ctx->input_end) {\n\t\t\t\tw2 = 0;  /* not a wordchar */\n\t\t\t} else {\n\t\t\t\tconst duk_uint8_t *tmp_sp = sp;  /* dummy so sp won't get updated */\n\t\t\t\tduk_codepoint_t c;\n\t\t\t\tc = duk__inp_get_cp(re_ctx, &tmp_sp);\n\t\t\t\tw2 = duk_unicode_re_is_wordchar(c);\n\t\t\t}\n\n\t\t\tif (op == DUK_REOP_ASSERT_WORD_BOUNDARY) {\n\t\t\t\tif (w1 == w2) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(op == DUK_REOP_ASSERT_NOT_WORD_BOUNDARY);\n\t\t\t\tif (w1 != w2) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_JUMP: {\n\t\t\tduk_int32_t skip;\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tpc += skip;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_SPLIT1: {\n\t\t\t/* split1: prefer direct execution (no jump) */\n\t\t\tconst duk_uint8_t *sub_sp;\n\t\t\tduk_int32_t skip;\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\t\t\tpc += skip;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_SPLIT2: {\n\t\t\t/* split2: prefer jump execution (not direct) */\n\t\t\tconst duk_uint8_t *sub_sp;\n\t\t\tduk_int32_t skip;\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_SQMINIMAL: {\n\t\t\tduk_uint32_t q, qmin, qmax;\n\t\t\tduk_int32_t skip;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tqmin = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tqmax = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"minimal quantifier, qmin=%lu, qmax=%lu, skip=%ld\",\n\t\t\t                     (unsigned long) qmin, (unsigned long) qmax, (long) skip));\n\n\t\t\tq = 0;\n\t\t\twhile (q <= qmax) {\n\t\t\t\tif (q >= qmin) {\n\t\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\t\t\tif (sub_sp) {\n\t\t\t\t\t\tsp = sub_sp;\n\t\t\t\t\t\tgoto match;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\t\tif (!sub_sp) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tsp = sub_sp;\n\t\t\t\tq++;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_SQGREEDY: {\n\t\t\tduk_uint32_t q, qmin, qmax, atomlen;\n\t\t\tduk_int32_t skip;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tqmin = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tqmax = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tatomlen = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"greedy quantifier, qmin=%lu, qmax=%lu, atomlen=%lu, skip=%ld\",\n\t\t\t                     (unsigned long) qmin, (unsigned long) qmax, (unsigned long) atomlen, (long) skip));\n\n\t\t\tq = 0;\n\t\t\twhile (q < qmax) {\n\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\t\tif (!sub_sp) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tsp = sub_sp;\n\t\t\t\tq++;\n\t\t\t}\n\t\t\twhile (q >= qmin) {\n\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\t\tif (sub_sp) {\n\t\t\t\t\tsp = sub_sp;\n\t\t\t\t\tgoto match;\n\t\t\t\t}\n\t\t\t\tif (q == qmin) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t/* Note: if atom were to contain e.g. captures, we would need to\n\t\t\t\t * re-match the atom to get correct captures.  Simply quantifiers\n\t\t\t\t * do not allow captures in their atom now, so this is not an issue.\n\t\t\t\t */\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"greedy quantifier, backtrack %ld characters (atomlen)\",\n\t\t\t\t                     (long) atomlen));\n\t\t\t\tsp = duk__inp_backtrack(re_ctx, &sp, (duk_uint_fast32_t) atomlen);\n\t\t\t\tq--;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_SAVE: {\n\t\t\tduk_uint32_t idx;\n\t\t\tconst duk_uint8_t *old;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tidx = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tif (idx >= re_ctx->nsaved) {\n\t\t\t\t/* idx is unsigned, < 0 check is not necessary */\n\t\t\t\tDUK_D(DUK_DPRINT(\"internal error, regexp save index insane: idx=%ld\", (long) idx));\n\t\t\t\tgoto internal_error;\n\t\t\t}\n\t\t\told = re_ctx->saved[idx];\n\t\t\tre_ctx->saved[idx] = sp;\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\t\t\tre_ctx->saved[idx] = old;\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_WIPERANGE: {\n\t\t\t/* Wipe capture range and save old values for backtracking.\n\t\t\t *\n\t\t\t * XXX: this typically happens with a relatively small idx_count.\n\t\t\t * It might be useful to handle cases where the count is small\n\t\t\t * (say <= 8) by saving the values in stack instead.  This would\n\t\t\t * reduce memory churn and improve performance, at the cost of a\n\t\t\t * slightly higher code footprint.\n\t\t\t */\n\t\t\tduk_uint32_t idx_start, idx_count;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\t\tduk_uint32_t idx_end, idx;\n#endif\n\t\t\tduk_uint8_t **range_save;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tidx_start = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tidx_count = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"wipe saved range: start=%ld, count=%ld -> [%ld,%ld] (captures [%ld,%ld])\",\n\t\t\t                     (long) idx_start, (long) idx_count,\n\t\t\t                     (long) idx_start, (long) (idx_start + idx_count - 1),\n\t\t\t                     (long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2)));\n\t\t\tif (idx_start + idx_count > re_ctx->nsaved || idx_count == 0) {\n\t\t\t\t/* idx is unsigned, < 0 check is not necessary */\n\t\t\t\tDUK_D(DUK_DPRINT(\"internal error, regexp wipe indices insane: idx_start=%ld, idx_count=%ld\",\n\t\t\t\t                 (long) idx_start, (long) idx_count));\n\t\t\t\tgoto internal_error;\n\t\t\t}\n\t\t\tDUK_ASSERT(idx_count > 0);\n\n\t\t\tduk_require_stack(re_ctx->thr, 1);\n\t\t\trange_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero(re_ctx->thr,\n\t\t\t                                                           sizeof(duk_uint8_t *) * idx_count);\n\t\t\tDUK_ASSERT(range_save != NULL);\n\t\t\tduk_memcpy(range_save, re_ctx->saved + idx_start, sizeof(duk_uint8_t *) * idx_count);\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\t\tidx_end = idx_start + idx_count;\n\t\t\tfor (idx = idx_start; idx < idx_end; idx++) {\n\t\t\t\tre_ctx->saved[idx] = NULL;\n\t\t\t}\n#else\n\t\t\tduk_memzero((void *) (re_ctx->saved + idx_start), sizeof(duk_uint8_t *) * idx_count);\n#endif\n\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\t/* match: keep wiped/resaved values */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"match: keep wiped/resaved values [%ld,%ld] (captures [%ld,%ld])\",\n\t\t\t\t                     (long) idx_start, (long) (idx_start + idx_count - 1),\n\t\t\t                             (long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2)));\n\t\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\n\t\t\t/* fail: restore saves */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fail: restore wiped/resaved values [%ld,%ld] (captures [%ld,%ld])\",\n\t\t\t                     (long) idx_start, (long) (idx_start + idx_count - 1),\n\t\t\t                     (long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2)));\n\t\t\tduk_memcpy((void *) (re_ctx->saved + idx_start),\n\t\t\t           (const void *) range_save,\n\t\t\t           sizeof(duk_uint8_t *) * idx_count);\n\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_LOOKPOS:\n\t\tcase DUK_REOP_LOOKNEG: {\n\t\t\t/*\n\t\t\t *  Needs a save of multiple saved[] entries depending on what range\n\t\t\t *  may be overwritten.  Because the regexp parser does no such analysis,\n\t\t\t *  we currently save the entire saved array here.  Lookaheads are thus\n\t\t\t *  a bit expensive.  Note that the saved array is not needed for just\n\t\t\t *  the lookahead sub-match, but for the matching of the entire sequel.\n\t\t\t *\n\t\t\t *  The temporary save buffer is pushed on to the valstack to handle\n\t\t\t *  errors correctly.  Each lookahead causes a C recursion and pushes\n\t\t\t *  more stuff on the value stack.  If the C recursion limit is less\n\t\t\t *  than the value stack slack, there is no need to check the stack.\n\t\t\t *  We do so regardless, just in case.\n\t\t\t */\n\n\t\t\tduk_int32_t skip;\n\t\t\tduk_uint8_t **full_save;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tDUK_ASSERT(re_ctx->nsaved > 0);\n\n\t\t\tduk_require_stack(re_ctx->thr, 1);\n\t\t\tfull_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero(re_ctx->thr,\n\t\t\t                                                          sizeof(duk_uint8_t *) * re_ctx->nsaved);\n\t\t\tDUK_ASSERT(full_save != NULL);\n\t\t\tduk_memcpy(full_save, re_ctx->saved, sizeof(duk_uint8_t *) * re_ctx->nsaved);\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (op == DUK_REOP_LOOKPOS) {\n\t\t\t\tif (!sub_sp) {\n\t\t\t\t\tgoto lookahead_fail;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (sub_sp) {\n\t\t\t\t\tgoto lookahead_fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\t/* match: keep saves */\n\t\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\n\t\t\t/* fall through */\n\n\t\t lookahead_fail:\n\t\t\t/* fail: restore saves */\n\t\t\tduk_memcpy((void *) re_ctx->saved,\n\t\t\t           (const void *) full_save,\n\t\t\t           sizeof(duk_uint8_t *) * re_ctx->nsaved);\n\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_BACKREFERENCE: {\n\t\t\t/*\n\t\t\t *  Byte matching for back-references would be OK in case-\n\t\t\t *  sensitive matching.  In case-insensitive matching we need\n\t\t\t *  to canonicalize characters, so back-reference matching needs\n\t\t\t *  to be done with codepoints instead.  So, we just decode\n\t\t\t *  everything normally here, too.\n\t\t\t *\n\t\t\t *  Note: back-reference index which is 0 or higher than\n\t\t\t *  NCapturingParens (= number of capturing parens in the\n\t\t\t *  -entire- regexp) is a compile time error.  However, a\n\t\t\t *  backreference referring to a valid capture which has\n\t\t\t *  not matched anything always succeeds!  See E5 Section\n\t\t\t *  15.10.2.9, step 5, sub-step 3.\n\t\t\t */\n\t\t\tduk_uint32_t idx;\n\t\t\tconst duk_uint8_t *p;\n\n\t\t\tidx = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tidx = idx << 1;  /* backref n -> saved indices [n*2, n*2+1] */\n\t\t\tif (idx < 2 || idx + 1 >= re_ctx->nsaved) {\n\t\t\t\t/* regexp compiler should catch these */\n\t\t\t\tDUK_D(DUK_DPRINT(\"internal error, backreference index insane\"));\n\t\t\t\tgoto internal_error;\n\t\t\t}\n\t\t\tif (!re_ctx->saved[idx] || !re_ctx->saved[idx+1]) {\n\t\t\t\t/* capture is 'undefined', always matches! */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"backreference: saved[%ld,%ld] not complete, always match\",\n\t\t\t\t                     (long) idx, (long) (idx + 1)));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"backreference: match saved[%ld,%ld]\", (long) idx, (long) (idx + 1)));\n\n\t\t\tp = re_ctx->saved[idx];\n\t\t\twhile (p < re_ctx->saved[idx+1]) {\n\t\t\t\tduk_codepoint_t c1, c2;\n\n\t\t\t\t/* Note: not necessary to check p against re_ctx->input_end:\n\t\t\t\t * the memory access is checked by duk__inp_get_cp(), while\n\t\t\t\t * valid compiled regexps cannot write a saved[] entry\n\t\t\t\t * which points to outside the string.\n\t\t\t\t */\n\t\t\t\tc1 = duk__inp_get_cp(re_ctx, &p);\n\t\t\t\tDUK_ASSERT(c1 >= 0);\n\t\t\t\tc2 = duk__inp_get_cp(re_ctx, &sp);\n\t\t\t\t/* No need for an explicit c2 < 0 check: because c1 >= 0,\n\t\t\t\t * the comparison will always fail if c2 < 0.\n\t\t\t\t */\n#if 0\n\t\t\t\tif (c2 < 0) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n#endif\n\t\t\t\tif (c1 != c2) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tDUK_D(DUK_DPRINT(\"internal error, regexp opcode error: %ld\", (long) op));\n\t\t\tgoto internal_error;\n\t\t}\n\t\t}\n\t}\n\n match:\n\tre_ctx->recursion_depth--;\n\treturn sp;\n\n fail:\n\tre_ctx->recursion_depth--;\n\treturn NULL;\n\n internal_error:\n\tDUK_ERROR_INTERNAL(re_ctx->thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Exposed matcher function which provides the semantics of RegExp.prototype.exec().\n *\n *  RegExp.prototype.test() has the same semantics as exec() but does not return the\n *  result object (which contains the matching string and capture groups).  Currently\n *  there is no separate test() helper, so a temporary result object is created and\n *  discarded if test() is needed.  This is intentional, to save code space.\n *\n *  Input stack:  [ ... re_obj input ]\n *  Output stack: [ ... result ]\n */\n\nDUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_global) {\n\tduk_re_matcher_ctx re_ctx;\n\tduk_hobject *h_regexp;\n\tduk_hstring *h_bytecode;\n\tduk_hstring *h_input;\n\tduk_uint8_t *p_buf;\n\tconst duk_uint8_t *pc;\n\tconst duk_uint8_t *sp;\n\tduk_small_int_t match = 0;\n\tduk_small_int_t global;\n\tduk_uint_fast32_t i;\n\tdouble d;\n\tduk_uint32_t char_offset;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"regexp match: regexp=%!T, input=%!T\",\n\t                   (duk_tval *) duk_get_tval(thr, -2),\n\t                   (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/*\n\t *  Regexp instance check, bytecode check, input coercion.\n\t *\n\t *  See E5 Section 15.10.6.\n\t */\n\n\t/* TypeError if wrong; class check, see E5 Section 15.10.6 */\n\th_regexp = duk_require_hobject_with_class(thr, -2, DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_ASSERT(h_regexp != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_regexp) == DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_UNREF(h_regexp);\n\n\th_input = duk_to_hstring(thr, -1);\n\tDUK_ASSERT(h_input != NULL);\n\n\tduk_xget_owndataprop_stridx_short(thr, -2, DUK_STRIDX_INT_BYTECODE);  /* [ ... re_obj input ] -> [ ... re_obj input bc ] */\n\th_bytecode = duk_require_hstring(thr, -1);  /* no regexp instance should exist without a non-configurable bytecode property */\n\tDUK_ASSERT(h_bytecode != NULL);\n\n\t/*\n\t *  Basic context initialization.\n\t *\n\t *  Some init values are read from the bytecode header\n\t *  whose format is (UTF-8 codepoints):\n\t *\n\t *    uint   flags\n\t *    uint   nsaved (even, 2n+2 where n = num captures)\n\t */\n\n\t/* [ ... re_obj input bc ] */\n\n\tduk_memzero(&re_ctx, sizeof(re_ctx));\n\n\tre_ctx.thr = thr;\n\tre_ctx.input = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tre_ctx.input_end = re_ctx.input + DUK_HSTRING_GET_BYTELEN(h_input);\n\tre_ctx.bytecode = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_bytecode);\n\tre_ctx.bytecode_end = re_ctx.bytecode + DUK_HSTRING_GET_BYTELEN(h_bytecode);\n\tre_ctx.saved = NULL;\n\tre_ctx.recursion_limit = DUK_USE_REGEXP_EXECUTOR_RECLIMIT;\n\tre_ctx.steps_limit = DUK_RE_EXECUTE_STEPS_LIMIT;\n\n\t/* read header */\n\tpc = re_ctx.bytecode;\n\tre_ctx.re_flags = duk__bc_get_u32(&re_ctx, &pc);\n\tre_ctx.nsaved = duk__bc_get_u32(&re_ctx, &pc);\n\tre_ctx.bytecode = pc;\n\n\tDUK_ASSERT(DUK_RE_FLAG_GLOBAL < 0x10000UL);  /* must fit into duk_small_int_t */\n\tglobal = (duk_small_int_t) (force_global | (duk_small_int_t) (re_ctx.re_flags & DUK_RE_FLAG_GLOBAL));\n\n\tDUK_ASSERT(re_ctx.nsaved >= 2);\n\tDUK_ASSERT((re_ctx.nsaved % 2) == 0);\n\n\tp_buf = (duk_uint8_t *) duk_push_fixed_buffer(thr, sizeof(duk_uint8_t *) * re_ctx.nsaved);  /* rely on zeroing */\n\tDUK_UNREF(p_buf);\n\tre_ctx.saved = (const duk_uint8_t **) duk_get_buffer(thr, -1, NULL);\n\tDUK_ASSERT(re_ctx.saved != NULL);\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tfor (i = 0; i < re_ctx.nsaved; i++) {\n\t\tre_ctx.saved[i] = (duk_uint8_t *) NULL;\n\t}\n#elif defined(DUK_USE_ZERO_BUFFER_DATA)\n\t/* buffer is automatically zeroed */\n#else\n\tduk_memzero((void *) p_buf, sizeof(duk_uint8_t *) * re_ctx.nsaved);\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"regexp ctx initialized, flags=0x%08lx, nsaved=%ld, recursion_limit=%ld, steps_limit=%ld\",\n\t                     (unsigned long) re_ctx.re_flags, (long) re_ctx.nsaved, (long) re_ctx.recursion_limit,\n\t                     (long) re_ctx.steps_limit));\n\n\t/*\n\t *  Get starting character offset for match, and initialize 'sp' based on it.\n\t *\n\t *  Note: lastIndex is non-configurable so it must be present (we check the\n\t *  internal class of the object above, so we know it is).  User code can set\n\t *  its value to an arbitrary (garbage) value though; E5 requires that lastIndex\n\t *  be coerced to a number before using.  The code below works even if the\n\t *  property is missing: the value will then be coerced to zero.\n\t *\n\t *  Note: lastIndex may be outside Uint32 range even after ToInteger() coercion.\n\t *  For instance, ToInteger(+Infinity) = +Infinity.  We track the match offset\n\t *  as an integer, but pre-check it to be inside the 32-bit range before the loop.\n\t *  If not, the check in E5 Section 15.10.6.2, step 9.a applies.\n\t */\n\n\t/* XXX: lastIndex handling produces a lot of asm */\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n\tduk_get_prop_stridx_short(thr, -4, DUK_STRIDX_LAST_INDEX);  /* -> [ ... re_obj input bc saved_buf lastIndex ] */\n\t(void) duk_to_int(thr, -1);  /* ToInteger(lastIndex) */\n\td = duk_get_number(thr, -1);  /* integer, but may be +/- Infinite, +/- zero (not NaN, though) */\n\tduk_pop_nodecref_unsafe(thr);\n\n\tif (global) {\n\t\tif (d < 0.0 || d > (double) DUK_HSTRING_GET_CHARLEN(h_input)) {\n\t\t\t/* match fail */\n\t\t\tchar_offset = 0;   /* not really necessary */\n\t\t\tDUK_ASSERT(match == 0);\n\t\t\tgoto match_over;\n\t\t}\n\t\tchar_offset = (duk_uint32_t) d;\n\t} else {\n\t\t/* lastIndex must be ignored for non-global regexps, but get the\n\t\t * value for (theoretical) side effects.  No side effects can\n\t\t * really occur, because lastIndex is a normal property and is\n\t\t * always non-configurable for RegExp instances.\n\t\t */\n\t\tchar_offset = (duk_uint32_t) 0;\n\t}\n\n\tDUK_ASSERT(char_offset <= DUK_HSTRING_GET_CHARLEN(h_input));\n\tsp = re_ctx.input + duk_heap_strcache_offset_char2byte(thr, h_input, char_offset);\n\n\t/*\n\t *  Match loop.\n\t *\n\t *  Try matching at different offsets until match found or input exhausted.\n\t */\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n\tDUK_ASSERT(match == 0);\n\n\tfor (;;) {\n\t\t/* char offset in [0, h_input->clen] (both ends inclusive), checked before entry */\n\t\tDUK_ASSERT_DISABLE(char_offset >= 0);\n\t\tDUK_ASSERT(char_offset <= DUK_HSTRING_GET_CHARLEN(h_input));\n\n\t\t/* Note: re_ctx.steps is intentionally not reset, it applies to the entire unanchored match */\n\t\tDUK_ASSERT(re_ctx.recursion_depth == 0);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"attempt match at char offset %ld; %p [%p,%p]\",\n\t\t                     (long) char_offset, (const void *) sp,\n\t\t                     (const void *) re_ctx.input, (const void *) re_ctx.input_end));\n\n\t\t/*\n\t\t *  Note:\n\t\t *\n\t\t *    - duk__match_regexp() is required not to longjmp() in ordinary \"non-match\"\n\t\t *      conditions; a longjmp() will terminate the entire matching process.\n\t\t *\n\t\t *    - Clearing saved[] is not necessary because backtracking does it\n\t\t *\n\t\t *    - Backtracking also rewinds re_ctx.recursion back to zero, unless an\n\t\t *      internal/limit error occurs (which causes a longjmp())\n\t\t *\n\t\t *    - If we supported anchored matches, we would break out here\n\t\t *      unconditionally; however, ECMAScript regexps don't have anchored\n\t\t *      matches.  It might make sense to implement a fast bail-out if\n\t\t *      the regexp begins with '^' and sp is not 0: currently we'll just\n\t\t *      run through the entire input string, trivially failing the match\n\t\t *      at every non-zero offset.\n\t\t */\n\n\t\tif (duk__match_regexp(&re_ctx, re_ctx.bytecode, sp) != NULL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"match at offset %ld\", (long) char_offset));\n\t\t\tmatch = 1;\n\t\t\tbreak;\n\t\t}\n\n\t\t/* advance by one character (code point) and one char_offset */\n\t\tchar_offset++;\n\t\tif (char_offset > DUK_HSTRING_GET_CHARLEN(h_input)) {\n\t\t\t/*\n\t\t\t *  Note:\n\t\t\t *\n\t\t\t *    - Intentionally attempt (empty) match at char_offset == k_input->clen\n\t\t\t *\n\t\t\t *    - Negative char_offsets have been eliminated and char_offset is duk_uint32_t\n\t\t\t *      -> no need or use for a negative check\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"no match after trying all sp offsets\"));\n\t\t\tbreak;\n\t\t}\n\n\t\t/* avoid calling at end of input, will DUK_ERROR (above check suffices to avoid this) */\n\t\t(void) duk__utf8_advance(thr, &sp, re_ctx.input, re_ctx.input_end, (duk_uint_fast32_t) 1);\n\t}\n\n match_over:\n\n\t/*\n\t *  Matching complete, create result array or return a 'null'.  Update lastIndex\n\t *  if necessary.  See E5 Section 15.10.6.2.\n\t *\n\t *  Because lastIndex is a character (not byte) offset, we need the character\n\t *  length of the match which we conveniently get as a side effect of interning\n\t *  the matching substring (0th index of result array).\n\t *\n\t *  saved[0]         start pointer (~ byte offset) of current match\n\t *  saved[1]         end pointer (~ byte offset) of current match (exclusive)\n\t *  char_offset      start character offset of current match (-> .index of result)\n\t *  char_end_offset  end character offset (computed below)\n\t */\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n\tif (match) {\n#if defined(DUK_USE_ASSERTIONS)\n\t\tduk_hobject *h_res;\n#endif\n\t\tduk_uint32_t char_end_offset = 0;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"regexp matches at char_offset %ld\", (long) char_offset));\n\n\t\tDUK_ASSERT(re_ctx.nsaved >= 2);        /* must have start and end */\n\t\tDUK_ASSERT((re_ctx.nsaved % 2) == 0);  /* and even number */\n\n\t\t/* XXX: Array size is known before and (2 * re_ctx.nsaved) but not taken\n\t\t * advantage of now.  The array is not compacted either, as regexp match\n\t\t * objects are usually short lived.\n\t\t */\n\n\t\tduk_push_array(thr);\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\th_res = duk_require_hobject(thr, -1);\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_res));\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(h_res));\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_res) == DUK_HOBJECT_CLASS_ARRAY);\n#endif\n\n\t\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\t\tduk_push_u32(thr, char_offset);\n\t\tduk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INDEX);\n\n\t\tduk_dup_m4(thr);\n\t\tduk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INPUT);\n\n\t\tfor (i = 0; i < re_ctx.nsaved; i += 2) {\n\t\t\t/* Captures which are undefined have NULL pointers and are returned\n\t\t\t * as 'undefined'.  The same is done when saved[] pointers are insane\n\t\t\t * (this should, of course, never happen in practice).\n\t\t\t */\n\t\t\tif (re_ctx.saved[i] && re_ctx.saved[i + 1] && re_ctx.saved[i + 1] >= re_ctx.saved[i]) {\n\t\t\t\tduk_push_lstring(thr,\n\t\t\t\t                 (const char *) re_ctx.saved[i],\n\t\t\t\t                 (duk_size_t) (re_ctx.saved[i+1] - re_ctx.saved[i]));\n\t\t\t\tif (i == 0) {\n\t\t\t\t\t/* Assumes that saved[0] and saved[1] are always\n\t\t\t\t\t * set by regexp bytecode (if not, char_end_offset\n\t\t\t\t\t * will be zero).  Also assumes clen reflects the\n\t\t\t\t\t * correct char length.\n\t\t\t\t\t */\n\t\t\t\t\tchar_end_offset = char_offset + (duk_uint32_t) duk_get_length(thr, -1);  /* add charlen */\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t}\n\n\t\t\t/* [ ... re_obj input bc saved_buf res_obj val ] */\n\t\t\tduk_put_prop_index(thr, -2, (duk_uarridx_t) (i / 2));\n\t\t}\n\n\t\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\t\t/* NB: 'length' property is automatically updated by the array setup loop */\n\n\t\tif (global) {\n\t\t\t/* global regexp: lastIndex updated on match */\n\t\t\tduk_push_u32(thr, char_end_offset);\n\t\t\tduk_put_prop_stridx_short(thr, -6, DUK_STRIDX_LAST_INDEX);\n\t\t} else {\n\t\t\t/* non-global regexp: lastIndex never updated on match */\n\t\t\t;\n\t\t}\n\t} else {\n\t\t/*\n\t\t *  No match, E5 Section 15.10.6.2, step 9.a.i - 9.a.ii apply, regardless\n\t\t *  of 'global' flag of the RegExp.  In particular, if lastIndex is invalid\n\t\t *  initially, it is reset to zero.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"regexp does not match\"));\n\n\t\tduk_push_null(thr);\n\n\t\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\t\tduk_push_int(thr, 0);\n\t\tduk_put_prop_stridx_short(thr, -6, DUK_STRIDX_LAST_INDEX);\n\t}\n\n\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\tduk_insert(thr, -5);\n\n\t/* [ ... res_obj re_obj input bc saved_buf ] */\n\n\tduk_pop_n_unsafe(thr, 4);\n\n\t/* [ ... res_obj ] */\n\n\t/* XXX: these last tricks are unnecessary if the function is made\n\t * a genuine native function.\n\t */\n}\n\nDUK_INTERNAL void duk_regexp_match(duk_hthread *thr) {\n\tduk__regexp_match_helper(thr, 0 /*force_global*/);\n}\n\n/* This variant is needed by String.prototype.split(); it needs to perform\n * global-style matching on a cloned RegExp which is potentially non-global.\n */\nDUK_INTERNAL void duk_regexp_match_force_global(duk_hthread *thr) {\n\tduk__regexp_match_helper(thr, 1 /*force_global*/);\n}\n\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\n/* regexp support disabled */\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_replacements.c",
    "content": "/*\n *  Replacements for missing platform functions.\n *\n *  Unlike the originals, fpclassify() and signbit() replacements don't\n *  work on any floating point types, only doubles.  The C typing here\n *  mimics the standard prototypes.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_COMPUTED_NAN)\nDUK_INTERNAL double duk_computed_nan;\n#endif\n\n#if defined(DUK_USE_COMPUTED_INFINITY)\nDUK_INTERNAL double duk_computed_infinity;\n#endif\n\n#if defined(DUK_USE_REPL_FPCLASSIFY)\nDUK_INTERNAL int duk_repl_fpclassify(double x) {\n\tduk_double_union u;\n\tduk_uint_fast16_t expt;\n\tduk_small_int_t mzero;\n\n\tu.d = x;\n\texpt = (duk_uint_fast16_t) (u.us[DUK_DBL_IDX_US0] & 0x7ff0UL);\n\tif (expt > 0x0000UL && expt < 0x7ff0UL) {\n\t\t/* expt values [0x001,0x7fe] = normal */\n\t\treturn DUK_FP_NORMAL;\n\t}\n\n\tmzero = (u.ui[DUK_DBL_IDX_UI1] == 0 && (u.ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) == 0);\n\tif (expt == 0x0000UL) {\n\t\t/* expt 0x000 is zero/subnormal */\n\t\tif (mzero) {\n\t\t\treturn DUK_FP_ZERO;\n\t\t} else {\n\t\t\treturn DUK_FP_SUBNORMAL;\n\t\t}\n\t} else {\n\t\t/* expt 0xfff is infinite/nan */\n\t\tif (mzero) {\n\t\t\treturn DUK_FP_INFINITE;\n\t\t} else {\n\t\t\treturn DUK_FP_NAN;\n\t\t}\n\t}\n}\n#endif\n\n#if defined(DUK_USE_REPL_SIGNBIT)\nDUK_INTERNAL int duk_repl_signbit(double x) {\n\tduk_double_union u;\n\tu.d = x;\n\treturn (int) (u.uc[DUK_DBL_IDX_UC0] & 0x80UL);\n}\n#endif\n\n#if defined(DUK_USE_REPL_ISFINITE)\nDUK_INTERNAL int duk_repl_isfinite(double x) {\n\tint c = DUK_FPCLASSIFY(x);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\treturn 0;\n\t} else {\n\t\treturn 1;\n\t}\n}\n#endif\n\n#if defined(DUK_USE_REPL_ISNAN)\nDUK_INTERNAL int duk_repl_isnan(double x) {\n\tint c = DUK_FPCLASSIFY(x);\n\treturn (c == DUK_FP_NAN);\n}\n#endif\n\n#if defined(DUK_USE_REPL_ISINF)\nDUK_INTERNAL int duk_repl_isinf(double x) {\n\tint c = DUK_FPCLASSIFY(x);\n\treturn (c == DUK_FP_INFINITE);\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_replacements.h",
    "content": "#if !defined(DUK_REPLACEMENTS_H_INCLUDED)\n#define DUK_REPLACEMENTS_H_INCLUDED\n\n#if !defined(DUK_SINGLE_FILE)\n#if defined(DUK_USE_COMPUTED_INFINITY)\nDUK_INTERNAL_DECL double duk_computed_infinity;\n#endif\n#if defined(DUK_USE_COMPUTED_NAN)\nDUK_INTERNAL_DECL double duk_computed_nan;\n#endif\n#endif  /* !DUK_SINGLE_FILE */\n\n#if defined(DUK_USE_REPL_FPCLASSIFY)\nDUK_INTERNAL_DECL int duk_repl_fpclassify(double x);\n#endif\n#if defined(DUK_USE_REPL_SIGNBIT)\nDUK_INTERNAL_DECL int duk_repl_signbit(double x);\n#endif\n#if defined(DUK_USE_REPL_ISFINITE)\nDUK_INTERNAL_DECL int duk_repl_isfinite(double x);\n#endif\n#if defined(DUK_USE_REPL_ISNAN)\nDUK_INTERNAL_DECL int duk_repl_isnan(double x);\n#endif\n#if defined(DUK_USE_REPL_ISINF)\nDUK_INTERNAL_DECL int duk_repl_isinf(double x);\n#endif\n\n#endif  /* DUK_REPLACEMENTS_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_selftest.c",
    "content": "/*\n *  Self tests to ensure execution environment is sane.  Intended to catch\n *  compiler/platform problems which cannot be detected at compile time.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_SELF_TESTS)\n\n/*\n *  Unions and structs for self tests\n */\n\ntypedef union {\n\tdouble d;\n\tduk_uint8_t x[8];\n} duk__test_double_union;\n\n/* Self test failed.  Expects a local variable 'error_count' to exist. */\n#define DUK__FAILED(msg)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"self test failed: \" #msg \" at \" DUK_FILE_MACRO \":\" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO))); \\\n\t\terror_count++; \\\n\t} while (0)\n\n#define DUK__DBLUNION_CMP_TRUE(a,b)  do { \\\n\t\tif (duk_memcmp((const void *) (a), (const void *) (b), sizeof(duk__test_double_union)) != 0) { \\\n\t\t\tDUK__FAILED(\"double union compares false (expected true)\"); \\\n\t\t} \\\n\t} while (0)\n\n#define DUK__DBLUNION_CMP_FALSE(a,b)  do { \\\n\t\tif (duk_memcmp((const void *) (a), (const void *) (b), sizeof(duk__test_double_union)) == 0) { \\\n\t\t\tDUK__FAILED(\"double union compares true (expected false)\"); \\\n\t\t} \\\n\t} while (0)\n\ntypedef union {\n\tduk_uint32_t i;\n\tduk_uint8_t x[8];\n} duk__test_u32_union;\n\n#if defined(DUK_USE_INTEGER_LE)\n#define DUK__U32_INIT(u, a, b, c, d) do { \\\n\t\t(u)->x[0] = (d); (u)->x[1] = (c); (u)->x[2] = (b); (u)->x[3] = (a); \\\n\t} while (0)\n#elif defined(DUK_USE_INTEGER_ME)\n#error integer mixed endian not supported now\n#elif defined(DUK_USE_INTEGER_BE)\n#define DUK__U32_INIT(u, a, b, c, d) do { \\\n\t\t(u)->x[0] = (a); (u)->x[1] = (b); (u)->x[2] = (c); (u)->x[3] = (d); \\\n\t} while (0)\n#else\n#error unknown integer endianness\n#endif\n\n#if defined(DUK_USE_DOUBLE_LE)\n#define DUK__DOUBLE_INIT(u, a, b, c, d, e, f, g, h) do { \\\n\t\t(u)->x[0] = (h); (u)->x[1] = (g); (u)->x[2] = (f); (u)->x[3] = (e); \\\n\t\t(u)->x[4] = (d); (u)->x[5] = (c); (u)->x[6] = (b); (u)->x[7] = (a); \\\n\t} while (0)\n#define DUK__DOUBLE_COMPARE(u, a, b, c, d, e, f, g, h) \\\n\t((u)->x[0] == (h) && (u)->x[1] == (g) && (u)->x[2] == (f) && (u)->x[3] == (e) && \\\n\t (u)->x[4] == (d) && (u)->x[5] == (c) && (u)->x[6] == (b) && (u)->x[7] == (a))\n#elif defined(DUK_USE_DOUBLE_ME)\n#define DUK__DOUBLE_INIT(u, a, b, c, d, e, f, g, h) do { \\\n\t\t(u)->x[0] = (d); (u)->x[1] = (c); (u)->x[2] = (b); (u)->x[3] = (a); \\\n\t\t(u)->x[4] = (h); (u)->x[5] = (g); (u)->x[6] = (f); (u)->x[7] = (e); \\\n\t} while (0)\n#define DUK__DOUBLE_COMPARE(u, a, b, c, d, e, f, g, h) \\\n\t((u)->x[0] == (d) && (u)->x[1] == (c) && (u)->x[2] == (b) && (u)->x[3] == (a) && \\\n\t (u)->x[4] == (h) && (u)->x[5] == (g) && (u)->x[6] == (f) && (u)->x[7] == (e))\n#elif defined(DUK_USE_DOUBLE_BE)\n#define DUK__DOUBLE_INIT(u, a, b, c, d, e, f, g, h) do { \\\n\t\t(u)->x[0] = (a); (u)->x[1] = (b); (u)->x[2] = (c); (u)->x[3] = (d); \\\n\t\t(u)->x[4] = (e); (u)->x[5] = (f); (u)->x[6] = (g); (u)->x[7] = (h); \\\n\t} while (0)\n#define DUK__DOUBLE_COMPARE(u, a, b, c, d, e, f, g, h) \\\n\t((u)->x[0] == (a) && (u)->x[1] == (b) && (u)->x[2] == (c) && (u)->x[3] == (d) && \\\n\t (u)->x[4] == (e) && (u)->x[5] == (f) && (u)->x[6] == (g) && (u)->x[7] == (h))\n#else\n#error unknown double endianness\n#endif\n\n/*\n *  Various sanity checks for typing\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_types(void) {\n\tduk_uint_t error_count = 0;\n\n\tif (!(sizeof(duk_int8_t) == 1 &&\n\t      sizeof(duk_uint8_t) == 1 &&\n\t      sizeof(duk_int16_t) == 2 &&\n\t      sizeof(duk_uint16_t) == 2 &&\n\t      sizeof(duk_int32_t) == 4 &&\n\t      sizeof(duk_uint32_t) == 4)) {\n\t\tDUK__FAILED(\"duk_(u)int{8,16,32}_t size\");\n\t}\n#if defined(DUK_USE_64BIT_OPS)\n\tif (!(sizeof(duk_int64_t) == 8 &&\n\t      sizeof(duk_uint64_t) == 8)) {\n\t\tDUK__FAILED(\"duk_(u)int64_t size\");\n\t}\n#endif\n\n\tif (!(sizeof(duk_size_t) >= sizeof(duk_uint_t))) {\n\t\t/* Some internal code now assumes that all duk_uint_t values\n\t\t * can be expressed with a duk_size_t.\n\t\t */\n\t\tDUK__FAILED(\"duk_size_t is smaller than duk_uint_t\");\n\t}\n\tif (!(sizeof(duk_int_t) >= 4)) {\n\t\tDUK__FAILED(\"duk_int_t is not 32 bits\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Packed tval sanity\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_packed_tval(void) {\n\tduk_uint_t error_count = 0;\n\n#if defined(DUK_USE_PACKED_TVAL)\n\tif (sizeof(void *) > 4) {\n\t\tDUK__FAILED(\"packed duk_tval in use but sizeof(void *) > 4\");\n\t}\n#endif\n\n\treturn error_count;\n}\n\n/*\n *  Two's complement arithmetic.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_twos_complement(void) {\n\tduk_uint_t error_count = 0;\n\tvolatile int test;\n\ttest = -1;\n\n\t/* Note that byte order doesn't affect this test: all bytes in\n\t * 'test' will be 0xFF for two's complement.\n\t */\n\tif (((volatile duk_uint8_t *) &test)[0] != (duk_uint8_t) 0xff) {\n\t\tDUK__FAILED(\"two's complement arithmetic\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Byte order.  Important to self check, because on some exotic platforms\n *  there is no actual detection but rather assumption based on platform\n *  defines.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_byte_order(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_u32_union u1;\n\tduk__test_double_union u2;\n\n\t/*\n\t *  >>> struct.pack('>d', 102030405060).encode('hex')\n\t *  '4237c17c6dc40000'\n\t */\n\n\tDUK__U32_INIT(&u1, 0xde, 0xad, 0xbe, 0xef);\n\tDUK__DOUBLE_INIT(&u2, 0x42, 0x37, 0xc1, 0x7c, 0x6d, 0xc4, 0x00, 0x00);\n\n\tif (u1.i != (duk_uint32_t) 0xdeadbeefUL) {\n\t\tDUK__FAILED(\"duk_uint32_t byte order\");\n\t}\n\n\tif (u2.d != (double) 102030405060.0) {\n\t\tDUK__FAILED(\"double byte order\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  DUK_BSWAP macros\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_bswap_macros(void) {\n\tduk_uint_t error_count = 0;\n\tvolatile duk_uint32_t x32_input, x32_output;\n\tduk_uint32_t x32;\n\tvolatile duk_uint16_t x16_input, x16_output;\n\tduk_uint16_t x16;\n\tduk_double_union du;\n\tduk_double_t du_diff;\n#if defined(DUK_BSWAP64)\n\tvolatile duk_uint64_t x64_input, x64_output;\n\tduk_uint64_t x64;\n#endif\n\n\t/* Cover both compile time and runtime bswap operations, as these\n\t * may have different bugs.\n\t */\n\n\tx16_input = 0xbeefUL;\n\tx16 = x16_input;\n\tx16 = DUK_BSWAP16(x16);\n\tx16_output = x16;\n\tif (x16_output != (duk_uint16_t) 0xefbeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP16\");\n\t}\n\n\tx16 = 0xbeefUL;\n\tx16 = DUK_BSWAP16(x16);\n\tif (x16 != (duk_uint16_t) 0xefbeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP16\");\n\t}\n\n\tx32_input = 0xdeadbeefUL;\n\tx32 = x32_input;\n\tx32 = DUK_BSWAP32(x32);\n\tx32_output = x32;\n\tif (x32_output != (duk_uint32_t) 0xefbeaddeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP32\");\n\t}\n\n\tx32 = 0xdeadbeefUL;\n\tx32 = DUK_BSWAP32(x32);\n\tif (x32 != (duk_uint32_t) 0xefbeaddeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP32\");\n\t}\n\n#if defined(DUK_BSWAP64)\n\tx64_input = DUK_U64_CONSTANT(0x8899aabbccddeeff);\n\tx64 = x64_input;\n\tx64 = DUK_BSWAP64(x64);\n\tx64_output = x64;\n\tif (x64_output != (duk_uint64_t) DUK_U64_CONSTANT(0xffeeddccbbaa9988)) {\n\t\tDUK__FAILED(\"DUK_BSWAP64\");\n\t}\n\n\tx64 = DUK_U64_CONSTANT(0x8899aabbccddeeff);\n\tx64 = DUK_BSWAP64(x64);\n\tif (x64 != (duk_uint64_t) DUK_U64_CONSTANT(0xffeeddccbbaa9988)) {\n\t\tDUK__FAILED(\"DUK_BSWAP64\");\n\t}\n#endif\n\n\t/* >>> struct.unpack('>d', '4000112233445566'.decode('hex'))\n\t * (2.008366013071895,)\n\t */\n\n\tdu.uc[0] = 0x40; du.uc[1] = 0x00; du.uc[2] = 0x11; du.uc[3] = 0x22;\n\tdu.uc[4] = 0x33; du.uc[5] = 0x44; du.uc[6] = 0x55; du.uc[7] = 0x66;\n\tDUK_DBLUNION_DOUBLE_NTOH(&du);\n\tdu_diff = du.d - 2.008366013071895;\n#if 0\n\tDUK_D(DUK_DPRINT(\"du_diff: %lg\\n\", (double) du_diff));\n#endif\n\tif (du_diff > 1e-15) {\n\t\t/* Allow very small lenience because some compilers won't parse\n\t\t * exact IEEE double constants (happened in matrix testing with\n\t\t * Linux gcc-4.8 -m32 at least).\n\t\t */\n#if 0\n\t\tDUK_D(DUK_DPRINT(\"Result of DUK_DBLUNION_DOUBLE_NTOH: %02x %02x %02x %02x %02x %02x %02x %02x\\n\",\n\t\t            (unsigned int) du.uc[0], (unsigned int) du.uc[1],\n\t\t            (unsigned int) du.uc[2], (unsigned int) du.uc[3],\n\t\t            (unsigned int) du.uc[4], (unsigned int) du.uc[5],\n\t\t            (unsigned int) du.uc[6], (unsigned int) du.uc[7]));\n#endif\n\t\tDUK__FAILED(\"DUK_DBLUNION_DOUBLE_NTOH\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Basic double / byte union memory layout.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_union_size(void) {\n\tduk_uint_t error_count = 0;\n\n\tif (sizeof(duk__test_double_union) != 8) {\n\t\tDUK__FAILED(\"invalid union size\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Union aliasing, see misc/clang_aliasing.c.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_aliasing(void) {\n\t/* This testcase fails when Emscripten-generated code runs on Firefox.\n\t * It's not an issue because the failure should only affect packed\n\t * duk_tval representation, which is not used with Emscripten.\n\t */\n#if defined(DUK_USE_PACKED_TVAL)\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union a, b;\n\n\t/* Test signaling NaN and alias assignment in all endianness combinations.\n\t */\n\n\t/* little endian */\n\ta.x[0] = 0x11; a.x[1] = 0x22; a.x[2] = 0x33; a.x[3] = 0x44;\n\ta.x[4] = 0x00; a.x[5] = 0x00; a.x[6] = 0xf1; a.x[7] = 0xff;\n\tb = a;\n\tDUK__DBLUNION_CMP_TRUE(&a, &b);\n\n\t/* big endian */\n\ta.x[0] = 0xff; a.x[1] = 0xf1; a.x[2] = 0x00; a.x[3] = 0x00;\n\ta.x[4] = 0x44; a.x[5] = 0x33; a.x[6] = 0x22; a.x[7] = 0x11;\n\tb = a;\n\tDUK__DBLUNION_CMP_TRUE(&a, &b);\n\n\t/* mixed endian */\n\ta.x[0] = 0x00; a.x[1] = 0x00; a.x[2] = 0xf1; a.x[3] = 0xff;\n\ta.x[4] = 0x11; a.x[5] = 0x22; a.x[6] = 0x33; a.x[7] = 0x44;\n\tb = a;\n\tDUK__DBLUNION_CMP_TRUE(&a, &b);\n\n\treturn error_count;\n#else\n\tDUK_D(DUK_DPRINT(\"skip double aliasing self test when duk_tval is not packed\"));\n\treturn 0;\n#endif\n}\n\n/*\n *  Zero sign, see misc/tcc_zerosign2.c.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_zero_sign(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union a, b;\n\n\ta.d = 0.0;\n\tb.d = -a.d;\n\tDUK__DBLUNION_CMP_FALSE(&a, &b);\n\n\treturn error_count;\n}\n\n/*\n *  Rounding mode: Duktape assumes round-to-nearest, check that this is true.\n *  If we had C99 fenv.h we could check that fegetround() == FE_TONEAREST,\n *  but we don't want to rely on that header; and even if we did, it's good\n *  to ensure the rounding actually works.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_rounding(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union a, b, c;\n\n#if 0\n\t/* Include <fenv.h> and test manually; these trigger failures: */\n\tfesetround(FE_UPWARD);\n\tfesetround(FE_DOWNWARD);\n\tfesetround(FE_TOWARDZERO);\n\n\t/* This is the default and passes. */\n\tfesetround(FE_TONEAREST);\n#endif\n\n\t/* Rounding tests check that none of the other modes (round to\n\t * +Inf, round to -Inf, round to zero) can be active:\n\t * http://www.gnu.org/software/libc/manual/html_node/Rounding.html\n\t */\n\n\t/* 1.0 + 2^(-53): result is midway between 1.0 and 1.0 + ulp.\n\t * Round to nearest: 1.0\n\t * Round to +Inf:    1.0 + ulp\n\t * Round to -Inf:    1.0\n\t * Round to zero:    1.0\n\t * => Correct result eliminates round to +Inf.\n\t */\n\tDUK__DOUBLE_INIT(&a, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);\n\tDUK__DOUBLE_INIT(&b, 0x3c, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);\n\tduk_memset((void *) &c, 0, sizeof(c));\n\tc.d = a.d + b.d;\n\tif (!DUK__DOUBLE_COMPARE(&c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)) {\n\t\tDUK_D(DUK_DPRINT(\"broken result (native endiannesss): %02x %02x %02x %02x %02x %02x %02x %02x\",\n\t\t                 (unsigned int) c.x[0], (unsigned int) c.x[1],\n\t\t                 (unsigned int) c.x[2], (unsigned int) c.x[3],\n\t\t                 (unsigned int) c.x[4], (unsigned int) c.x[5],\n\t\t                 (unsigned int) c.x[6], (unsigned int) c.x[7]));\n\t\tDUK__FAILED(\"invalid result from 1.0 + 0.5ulp\");\n\t}\n\n\t/* (1.0 + ulp) + 2^(-53): result is midway between 1.0 + ulp and 1.0 + 2*ulp.\n\t * Round to nearest: 1.0 + 2*ulp (round to even mantissa)\n\t * Round to +Inf:    1.0 + 2*ulp\n\t * Round to -Inf:    1.0 + ulp\n\t * Round to zero:    1.0 + ulp\n\t * => Correct result eliminates round to -Inf and round to zero.\n\t */\n\tDUK__DOUBLE_INIT(&a, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01);\n\tDUK__DOUBLE_INIT(&b, 0x3c, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);\n\tduk_memset((void *) &c, 0, sizeof(c));\n\tc.d = a.d + b.d;\n\tif (!DUK__DOUBLE_COMPARE(&c, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02)) {\n\t\tDUK_D(DUK_DPRINT(\"broken result (native endiannesss): %02x %02x %02x %02x %02x %02x %02x %02x\",\n\t\t                 (unsigned int) c.x[0], (unsigned int) c.x[1],\n\t\t                 (unsigned int) c.x[2], (unsigned int) c.x[3],\n\t\t                 (unsigned int) c.x[4], (unsigned int) c.x[5],\n\t\t                 (unsigned int) c.x[6], (unsigned int) c.x[7]));\n\t\tDUK__FAILED(\"invalid result from (1.0 + ulp) + 0.5ulp\");\n\t}\n\n\t/* Could do negative number testing too, but the tests above should\n\t * differentiate between IEEE 754 rounding modes.\n\t */\n\treturn error_count;\n}\n\n/*\n *  fmod(): often a portability issue in embedded or bare platform targets.\n *  Check for at least minimally correct behavior.  Unlike some other math\n *  functions (like cos()) Duktape relies on fmod() internally too.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_fmod(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union u1, u2;\n\tvolatile duk_double_t t1, t2, t3;\n\n\t/* fmod() with integer argument and exponent 2^32 is used by e.g.\n\t * ToUint32() and some Duktape internals.\n\t */\n\tu1.d = DUK_FMOD(10.0, 4294967296.0);\n\tu2.d = 10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(4294967306.0, 4294967296.0);\n\tu2.d = 10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(73014444042.0, 4294967296.0);\n\tu2.d = 10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\t/* 52-bit integer split into two parts:\n\t * >>> 0x1fedcba9876543\n\t * 8987183256397123\n\t * >>> float(0x1fedcba9876543) / float(2**53)\n\t * 0.9977777777777778\n\t */\n\tu1.d = DUK_FMOD(8987183256397123.0, 4294967296.0);\n\tu2.d = (duk_double_t) 0xa9876543UL;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\tt1 = 8987183256397123.0;\n\tt2 = 4294967296.0;\n\tt3 = t1 / t2;\n\tu1.d = DUK_FLOOR(t3);\n\tu2.d = (duk_double_t) 0x1fedcbUL;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\t/* C99 behavior is for fmod() result sign to mathc argument sign. */\n\tu1.d = DUK_FMOD(-10.0, 4294967296.0);\n\tu2.d = -10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(-4294967306.0, 4294967296.0);\n\tu2.d = -10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(-73014444042.0, 4294967296.0);\n\tu2.d = -10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\treturn error_count;\n}\n\n/*\n *  Struct size/alignment if platform requires it\n *\n *  There are some compiler specific struct padding pragmas etc in use, this\n *  selftest ensures they're correctly detected and used.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_struct_align(void) {\n\tduk_uint_t error_count = 0;\n\n#if (DUK_USE_ALIGN_BY == 4)\n\tif ((sizeof(duk_hbuffer_fixed) % 4) != 0) {\n\t\tDUK__FAILED(\"sizeof(duk_hbuffer_fixed) not aligned to 4\");\n\t}\n#elif (DUK_USE_ALIGN_BY == 8)\n\tif ((sizeof(duk_hbuffer_fixed) % 8) != 0) {\n\t\tDUK__FAILED(\"sizeof(duk_hbuffer_fixed) not aligned to 8\");\n\t}\n#elif (DUK_USE_ALIGN_BY == 1)\n\t/* no check */\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\treturn error_count;\n}\n\n/*\n *  64-bit arithmetic\n *\n *  There are some platforms/compilers where 64-bit types are available\n *  but don't work correctly.  Test for known cases.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_64bit_arithmetic(void) {\n\tduk_uint_t error_count = 0;\n#if defined(DUK_USE_64BIT_OPS)\n\tvolatile duk_int64_t i;\n\tvolatile duk_double_t d;\n\n\t/* Catch a double-to-int64 cast issue encountered in practice. */\n\td = 2147483648.0;\n\ti = (duk_int64_t) d;\n\tif (i != DUK_I64_CONSTANT(0x80000000)) {\n\t\tDUK__FAILED(\"casting 2147483648.0 to duk_int64_t failed\");\n\t}\n#else\n\t/* nop */\n#endif\n\treturn error_count;\n}\n\n/*\n *  Casting\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_cast_double_to_small_uint(void) {\n\t/*\n\t *  https://github.com/svaarala/duktape/issues/127#issuecomment-77863473\n\t */\n\n\tduk_uint_t error_count = 0;\n\n\tduk_double_t d1, d2;\n\tduk_small_uint_t u;\n\n\tduk_double_t d1v, d2v;\n\tduk_small_uint_t uv;\n\n\t/* Test without volatiles */\n\n\td1 = 1.0;\n\tu = (duk_small_uint_t) d1;\n\td2 = (duk_double_t) u;\n\n\tif (!(d1 == 1.0 && u == 1 && d2 == 1.0 && d1 == d2)) {\n\t\tDUK__FAILED(\"double to duk_small_uint_t cast failed\");\n\t}\n\n\t/* Same test with volatiles */\n\n\td1v = 1.0;\n\tuv = (duk_small_uint_t) d1v;\n\td2v = (duk_double_t) uv;\n\n\tif (!(d1v == 1.0 && uv == 1 && d2v == 1.0 && d1v == d2v)) {\n\t\tDUK__FAILED(\"double to duk_small_uint_t cast failed\");\n\t}\n\n\treturn error_count;\n}\n\nDUK_LOCAL duk_uint_t duk__selftest_cast_double_to_uint32(void) {\n\t/*\n\t *  This test fails on an exotic ARM target; double-to-uint\n\t *  cast is incorrectly clamped to -signed- int highest value.\n\t *\n\t *  https://github.com/svaarala/duktape/issues/336\n\t */\n\n\tduk_uint_t error_count = 0;\n\tduk_double_t dv;\n\tduk_uint32_t uv;\n\n\tdv = 3735928559.0;  /* 0xdeadbeef in decimal */\n\tuv = (duk_uint32_t) dv;\n\n\tif (uv != 0xdeadbeefUL) {\n\t\tDUK__FAILED(\"double to duk_uint32_t cast failed\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Minimal test of user supplied allocation functions\n *\n *    - Basic alloc + realloc + free cycle\n *\n *    - Realloc to significantly larger size to (hopefully) trigger a\n *      relocation and check that relocation copying works\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_alloc_funcs(duk_alloc_function alloc_func,\n                                               duk_realloc_function realloc_func,\n                                               duk_free_function free_func,\n                                               void *udata) {\n\tduk_uint_t error_count = 0;\n\tvoid *ptr;\n\tvoid *new_ptr;\n\tduk_small_int_t i, j;\n\tunsigned char x;\n\n\tif (alloc_func == NULL || realloc_func == NULL || free_func == NULL) {\n\t\treturn 0;\n\t}\n\n\tfor (i = 1; i <= 256; i++) {\n\t\tptr = alloc_func(udata, (duk_size_t) i);\n\t\tif (ptr == NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"alloc failed, ignore\"));\n\t\t\tcontinue;  /* alloc failed, ignore */\n\t\t}\n\t\tfor (j = 0; j < i; j++) {\n\t\t\t((unsigned char *) ptr)[j] = (unsigned char) (0x80 + j);\n\t\t}\n\t\tnew_ptr = realloc_func(udata, ptr, 1024);\n\t\tif (new_ptr == NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"realloc failed, ignore\"));\n\t\t\tfree_func(udata, ptr);\n\t\t\tcontinue;  /* realloc failed, ignore */\n\t\t}\n\t\tptr = new_ptr;\n\t\tfor (j = 0; j < i; j++) {\n\t\t\tx = ((unsigned char *) ptr)[j];\n\t\t\tif (x != (unsigned char) (0x80 + j)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"byte at index %ld doesn't match after realloc: %02lx\",\n\t\t\t\t                 (long) j, (unsigned long) x));\n\t\t\t\tDUK__FAILED(\"byte compare after realloc\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tfree_func(udata, ptr);\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Self test main\n */\n\nDUK_INTERNAL duk_uint_t duk_selftest_run_tests(duk_alloc_function alloc_func,\n                                               duk_realloc_function realloc_func,\n                                               duk_free_function free_func,\n                                               void *udata) {\n\tduk_uint_t error_count = 0;\n\n\tDUK_D(DUK_DPRINT(\"self test starting\"));\n\n\terror_count += duk__selftest_types();\n\terror_count += duk__selftest_packed_tval();\n\terror_count += duk__selftest_twos_complement();\n\terror_count += duk__selftest_byte_order();\n\terror_count += duk__selftest_bswap_macros();\n\terror_count += duk__selftest_double_union_size();\n\terror_count += duk__selftest_double_aliasing();\n\terror_count += duk__selftest_double_zero_sign();\n\terror_count += duk__selftest_double_rounding();\n\terror_count += duk__selftest_fmod();\n\terror_count += duk__selftest_struct_align();\n\terror_count += duk__selftest_64bit_arithmetic();\n\terror_count += duk__selftest_cast_double_to_small_uint();\n\terror_count += duk__selftest_cast_double_to_uint32();\n\terror_count += duk__selftest_alloc_funcs(alloc_func, realloc_func, free_func, udata);\n\n\tDUK_D(DUK_DPRINT(\"self test complete, total error count: %ld\", (long) error_count));\n\n\treturn error_count;\n}\n\n#endif  /* DUK_USE_SELF_TESTS */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_selftest.h",
    "content": "/*\n *  Selftest code\n */\n\n#if !defined(DUK_SELFTEST_H_INCLUDED)\n#define DUK_SELFTEST_H_INCLUDED\n\n#if defined(DUK_USE_SELF_TESTS)\nDUK_INTERNAL_DECL duk_uint_t duk_selftest_run_tests(duk_alloc_function alloc_func,\n                                                    duk_realloc_function realloc_func,\n                                                    duk_free_function free_func,\n                                                    void *udata);\n#endif\n\n#endif  /* DUK_SELFTEST_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_strings.h",
    "content": "/*\n *  Shared string macros.\n *\n *  Using shared macros helps minimize strings data size because it's easy\n *  to check if an existing string could be used.  String constants don't\n *  need to be all defined here; defining a string here makes sense if there's\n *  a high chance the string could be reused.  Also, using macros allows\n *  a call site express the exact string needed, but the macro may map to an\n *  approximate string to reduce unique string count.  Macros can also be\n *  more easily tuned for low memory targets than #if defined()s throughout\n *  the code base.\n *\n *  Because format strings behave differently in the call site (they need to\n *  be followed by format arguments), they use a special prefix DUK_STR_FMT_.\n *\n *  On some compilers using explicit shared strings is preferable; on others\n *  it may be better to use straight literals because the compiler will combine\n *  them anyway, and such strings won't end up unnecessarily in a symbol table.\n */\n\n#if !defined(DUK_ERRMSG_H_INCLUDED)\n#define DUK_ERRMSG_H_INCLUDED\n\n/* Mostly API and built-in method related */\n#define DUK_STR_INTERNAL_ERROR                   \"internal error\"\n#define DUK_STR_UNSUPPORTED                      \"unsupported\"\n#define DUK_STR_INVALID_COUNT                    \"invalid count\"\n#define DUK_STR_INVALID_ARGS                     \"invalid args\"\n#define DUK_STR_INVALID_STATE                    \"invalid state\"\n#define DUK_STR_INVALID_INPUT                    \"invalid input\"\n#define DUK_STR_INVALID_LENGTH                   \"invalid length\"\n#define DUK_STR_NOT_CONSTRUCTABLE                \"not constructable\"\n#define DUK_STR_CONSTRUCT_ONLY                   \"constructor requires 'new'\"\n#define DUK_STR_NOT_CALLABLE                     \"not callable\"\n#define DUK_STR_NOT_EXTENSIBLE                   \"not extensible\"\n#define DUK_STR_NOT_WRITABLE                     \"not writable\"\n#define DUK_STR_NOT_CONFIGURABLE                 \"not configurable\"\n#define DUK_STR_INVALID_CONTEXT                  \"invalid context\"\n#define DUK_STR_INVALID_INDEX                    \"invalid args\"\n#define DUK_STR_PUSH_BEYOND_ALLOC_STACK          \"cannot push beyond allocated stack\"\n#define DUK_STR_NOT_UNDEFINED                    \"unexpected type\"\n#define DUK_STR_NOT_NULL                         \"unexpected type\"\n#define DUK_STR_NOT_BOOLEAN                      \"unexpected type\"\n#define DUK_STR_NOT_NUMBER                       \"unexpected type\"\n#define DUK_STR_NOT_STRING                       \"unexpected type\"\n#define DUK_STR_NOT_OBJECT                       \"unexpected type\"\n#define DUK_STR_NOT_POINTER                      \"unexpected type\"\n#define DUK_STR_NOT_BUFFER                       \"not buffer\"  /* still in use with verbose messages */\n#define DUK_STR_UNEXPECTED_TYPE                  \"unexpected type\"\n#define DUK_STR_NOT_THREAD                       \"unexpected type\"\n#define DUK_STR_NOT_COMPFUNC                     \"unexpected type\"\n#define DUK_STR_NOT_NATFUNC                      \"unexpected type\"\n#define DUK_STR_NOT_C_FUNCTION                   \"unexpected type\"\n#define DUK_STR_NOT_FUNCTION                     \"unexpected type\"\n#define DUK_STR_NOT_REGEXP                       \"unexpected type\"\n#define DUK_STR_TOPRIMITIVE_FAILED               \"coercion to primitive failed\"\n#define DUK_STR_NUMBER_OUTSIDE_RANGE             \"number outside range\"\n#define DUK_STR_NOT_OBJECT_COERCIBLE             \"not object coercible\"\n#define DUK_STR_CANNOT_NUMBER_COERCE_SYMBOL      \"cannot number coerce Symbol\"\n#define DUK_STR_CANNOT_STRING_COERCE_SYMBOL      \"cannot string coerce Symbol\"\n#define DUK_STR_STRING_TOO_LONG                  \"string too long\"\n#define DUK_STR_BUFFER_TOO_LONG                  \"buffer too long\"\n#define DUK_STR_ALLOC_FAILED                     \"alloc failed\"\n#define DUK_STR_WRONG_BUFFER_TYPE                \"wrong buffer type\"\n#define DUK_STR_BASE64_ENCODE_FAILED             \"base64 encode failed\"\n#define DUK_STR_SOURCE_DECODE_FAILED             \"source decode failed\"\n#define DUK_STR_UTF8_DECODE_FAILED               \"utf-8 decode failed\"\n#define DUK_STR_BASE64_DECODE_FAILED             \"base64 decode failed\"\n#define DUK_STR_HEX_DECODE_FAILED                \"hex decode failed\"\n#define DUK_STR_INVALID_BYTECODE                 \"invalid bytecode\"\n#define DUK_STR_NO_SOURCECODE                    \"no sourcecode\"\n#define DUK_STR_RESULT_TOO_LONG                  \"result too long\"\n#define DUK_STR_INVALID_CFUNC_RC                 \"invalid C function rc\"\n#define DUK_STR_INVALID_INSTANCEOF_RVAL          \"invalid instanceof rval\"\n#define DUK_STR_INVALID_INSTANCEOF_RVAL_NOPROTO  \"instanceof rval has no .prototype\"\n\n/* JSON */\n#define DUK_STR_FMT_PTR                          \"%p\"\n#define DUK_STR_FMT_INVALID_JSON                 \"invalid json (at offset %ld)\"\n#define DUK_STR_JSONDEC_RECLIMIT                 \"json decode recursion limit\"\n#define DUK_STR_JSONENC_RECLIMIT                 \"json encode recursion limit\"\n#define DUK_STR_CYCLIC_INPUT                     \"cyclic input\"\n\n/* Object property access */\n#define DUK_STR_INVALID_BASE                     \"invalid base value\"\n#define DUK_STR_STRICT_CALLER_READ               \"cannot read strict 'caller'\"\n#define DUK_STR_PROXY_REJECTED                   \"proxy rejected\"\n#define DUK_STR_INVALID_ARRAY_LENGTH             \"invalid array length\"\n#define DUK_STR_SETTER_UNDEFINED                 \"setter undefined\"\n#define DUK_STR_INVALID_DESCRIPTOR               \"invalid descriptor\"\n\n/* Proxy */\n#define DUK_STR_PROXY_REVOKED                    \"proxy revoked\"\n#define DUK_STR_INVALID_TRAP_RESULT              \"invalid trap result\"\n\n/* Variables */\n\n/* Lexer */\n#define DUK_STR_INVALID_ESCAPE                   \"invalid escape\"\n#define DUK_STR_UNTERMINATED_STRING              \"unterminated string\"\n#define DUK_STR_UNTERMINATED_COMMENT             \"unterminated comment\"\n#define DUK_STR_UNTERMINATED_REGEXP              \"unterminated regexp\"\n#define DUK_STR_TOKEN_LIMIT                      \"token limit\"\n#define DUK_STR_REGEXP_SUPPORT_DISABLED          \"regexp support disabled\"\n#define DUK_STR_INVALID_NUMBER_LITERAL           \"invalid number literal\"\n#define DUK_STR_INVALID_TOKEN                    \"invalid token\"\n\n/* Compiler */\n#define DUK_STR_PARSE_ERROR                      \"parse error\"\n#define DUK_STR_DUPLICATE_LABEL                  \"duplicate label\"\n#define DUK_STR_INVALID_LABEL                    \"invalid label\"\n#define DUK_STR_INVALID_ARRAY_LITERAL            \"invalid array literal\"\n#define DUK_STR_INVALID_OBJECT_LITERAL           \"invalid object literal\"\n#define DUK_STR_INVALID_VAR_DECLARATION          \"invalid variable declaration\"\n#define DUK_STR_CANNOT_DELETE_IDENTIFIER         \"cannot delete identifier\"\n#define DUK_STR_INVALID_EXPRESSION               \"invalid expression\"\n#define DUK_STR_INVALID_LVALUE                   \"invalid lvalue\"\n#define DUK_STR_INVALID_NEWTARGET                \"invalid new.target\"\n#define DUK_STR_EXPECTED_IDENTIFIER              \"expected identifier\"\n#define DUK_STR_EMPTY_EXPR_NOT_ALLOWED           \"empty expression not allowed\"\n#define DUK_STR_INVALID_FOR                      \"invalid for statement\"\n#define DUK_STR_INVALID_SWITCH                   \"invalid switch statement\"\n#define DUK_STR_INVALID_BREAK_CONT_LABEL         \"invalid break/continue label\"\n#define DUK_STR_INVALID_RETURN                   \"invalid return\"\n#define DUK_STR_INVALID_TRY                      \"invalid try\"\n#define DUK_STR_INVALID_THROW                    \"invalid throw\"\n#define DUK_STR_WITH_IN_STRICT_MODE              \"with in strict mode\"\n#define DUK_STR_FUNC_STMT_NOT_ALLOWED            \"function statement not allowed\"\n#define DUK_STR_UNTERMINATED_STMT                \"unterminated statement\"\n#define DUK_STR_INVALID_ARG_NAME                 \"invalid argument name\"\n#define DUK_STR_INVALID_FUNC_NAME                \"invalid function name\"\n#define DUK_STR_INVALID_GETSET_NAME              \"invalid getter/setter name\"\n#define DUK_STR_FUNC_NAME_REQUIRED               \"function name required\"\n\n/* RegExp */\n#define DUK_STR_INVALID_QUANTIFIER               \"invalid regexp quantifier\"\n#define DUK_STR_INVALID_QUANTIFIER_NO_ATOM       \"quantifier without preceding atom\"\n#define DUK_STR_INVALID_QUANTIFIER_VALUES        \"quantifier values invalid (qmin > qmax)\"\n#define DUK_STR_QUANTIFIER_TOO_MANY_COPIES       \"quantifier requires too many atom copies\"\n#define DUK_STR_UNEXPECTED_CLOSING_PAREN         \"unexpected closing parenthesis\"\n#define DUK_STR_UNEXPECTED_END_OF_PATTERN        \"unexpected end of pattern\"\n#define DUK_STR_UNEXPECTED_REGEXP_TOKEN          \"unexpected token in regexp\"\n#define DUK_STR_INVALID_REGEXP_FLAGS             \"invalid regexp flags\"\n#define DUK_STR_INVALID_REGEXP_ESCAPE            \"invalid regexp escape\"\n#define DUK_STR_INVALID_BACKREFS                 \"invalid backreference(s)\"\n#define DUK_STR_INVALID_REGEXP_CHARACTER         \"invalid regexp character\"\n#define DUK_STR_INVALID_REGEXP_GROUP             \"invalid regexp group\"\n#define DUK_STR_UNTERMINATED_CHARCLASS           \"unterminated character class\"\n#define DUK_STR_INVALID_RANGE                    \"invalid range\"\n\n/* Limits */\n#define DUK_STR_VALSTACK_LIMIT                   \"valstack limit\"\n#define DUK_STR_CALLSTACK_LIMIT                  \"callstack limit\"\n#define DUK_STR_PROTOTYPE_CHAIN_LIMIT            \"prototype chain limit\"\n#define DUK_STR_BOUND_CHAIN_LIMIT                \"function call bound chain limit\"\n#define DUK_STR_NATIVE_STACK_LIMIT               \"C stack depth limit\"\n#define DUK_STR_COMPILER_RECURSION_LIMIT         \"compiler recursion limit\"\n#define DUK_STR_BYTECODE_LIMIT                   \"bytecode limit\"\n#define DUK_STR_REG_LIMIT                        \"register limit\"\n#define DUK_STR_TEMP_LIMIT                       \"temp limit\"\n#define DUK_STR_CONST_LIMIT                      \"const limit\"\n#define DUK_STR_FUNC_LIMIT                       \"function limit\"\n#define DUK_STR_REGEXP_COMPILER_RECURSION_LIMIT  \"regexp compiler recursion limit\"\n#define DUK_STR_REGEXP_EXECUTOR_RECURSION_LIMIT  \"regexp executor recursion limit\"\n#define DUK_STR_REGEXP_EXECUTOR_STEP_LIMIT       \"regexp step limit\"\n\n#endif  /* DUK_ERRMSG_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_tval.c",
    "content": "#include \"duk_internal.h\"\n\n#if defined(DUK_USE_FASTINT)\n\n/*\n *  Manually optimized double-to-fastint downgrade check.\n *\n *  This check has a large impact on performance, especially for fastint\n *  slow paths, so must be changed carefully.  The code should probably be\n *  optimized for the case where the result does not fit into a fastint,\n *  to minimize the penalty for \"slow path code\" dealing with fractions etc.\n *\n *  At least on one tested soft float ARM platform double-to-int64 coercion\n *  is very slow (and sometimes produces incorrect results, see self tests).\n *  This algorithm combines a fastint compatibility check and extracting the\n *  integer value from an IEEE double for setting the tagged fastint.  For\n *  other platforms a more naive approach might be better.\n *\n *  See doc/fastint.rst for details.\n */\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_tval_set_number_chkfast_fast(duk_tval *tv, duk_double_t x) {\n\tduk_double_union du;\n\tduk_int64_t i;\n\tduk_small_int_t expt;\n\tduk_small_int_t shift;\n\n\t/* XXX: optimize for packed duk_tval directly? */\n\n\tdu.d = x;\n\ti = (duk_int64_t) DUK_DBLUNION_GET_INT64(&du);\n\texpt = (duk_small_int_t) ((i >> 52) & 0x07ff);\n\tshift = expt - 1023;\n\n\tif (shift >= 0 && shift <= 46) {  /* exponents 1023 to 1069 */\n\t\tduk_int64_t t;\n\n\t\tif (((DUK_I64_CONSTANT(0x000fffffffffffff) >> shift) & i) == 0) {\n\t\t\tt = i | DUK_I64_CONSTANT(0x0010000000000000);  /* implicit leading one */\n\t\t\tt = t & DUK_I64_CONSTANT(0x001fffffffffffff);\n\t\t\tt = t >> (52 - shift);\n\t\t\tif (i < 0) {\n\t\t\t\tt = -t;\n\t\t\t}\n\t\t\tDUK_TVAL_SET_FASTINT(tv, t);\n\t\t\treturn;\n\t\t}\n\t} else if (shift == -1023) {  /* exponent 0 */\n\t\tif (i >= 0 && (i & DUK_I64_CONSTANT(0x000fffffffffffff)) == 0) {\n\t\t\t/* Note: reject negative zero. */\n\t\t\tDUK_TVAL_SET_FASTINT(tv, (duk_int64_t) 0);\n\t\t\treturn;\n\t\t}\n\t} else if (shift == 47) {  /* exponent 1070 */\n\t\tif (i < 0 && (i & DUK_I64_CONSTANT(0x000fffffffffffff)) == 0) {\n\t\t\tDUK_TVAL_SET_FASTINT(tv, (duk_int64_t) DUK_FASTINT_MIN);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tDUK_TVAL_SET_DOUBLE(tv, x);\n\treturn;\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_tval_set_number_chkfast_slow(duk_tval *tv, duk_double_t x) {\n\tduk_tval_set_number_chkfast_fast(tv, x);\n}\n\n/*\n *  Manually optimized number-to-double conversion\n */\n\n#if defined(DUK_USE_FASTINT) && defined(DUK_USE_PACKED_TVAL)\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_packed(duk_tval *tv) {\n\tduk_double_union du;\n\tduk_uint64_t t;\n\n\tt = (duk_uint64_t) DUK_DBLUNION_GET_UINT64(tv);\n\tif ((t >> 48) != DUK_TAG_FASTINT) {\n\t\treturn tv->d;\n\t} else if (t & DUK_U64_CONSTANT(0x0000800000000000)) {\n\t\tt = (duk_uint64_t) (-((duk_int64_t) t));  /* avoid unary minus on unsigned */\n\t\tt = t & DUK_U64_CONSTANT(0x0000ffffffffffff);  /* negative */\n\t\tt |= DUK_U64_CONSTANT(0xc330000000000000);\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d + 4503599627370496.0;  /* 1 << 52 */\n\t} else if (t != 0) {\n\t\tt &= DUK_U64_CONSTANT(0x0000ffffffffffff);  /* positive */\n\t\tt |= DUK_U64_CONSTANT(0x4330000000000000);\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d - 4503599627370496.0;  /* 1 << 52 */\n\t} else {\n\t\treturn 0.0;  /* zero */\n\t}\n}\n#endif  /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */\n\n#if 0  /* unused */\n#if defined(DUK_USE_FASTINT) && !defined(DUK_USE_PACKED_TVAL)\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked(duk_tval *tv) {\n\tduk_double_union du;\n\tduk_uint64_t t;\n\n\tDUK_ASSERT(tv->t == DUK_TAG_NUMBER || tv->t == DUK_TAG_FASTINT);\n\n\tif (tv->t == DUK_TAG_FASTINT) {\n\t\tif (tv->v.fi >= 0) {\n\t\t\tt = DUK_U64_CONSTANT(0x4330000000000000) | (duk_uint64_t) tv->v.fi;\n\t\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\t\treturn du.d - 4503599627370496.0;  /* 1 << 52 */\n\t\t} else {\n\t\t\tt = DUK_U64_CONSTANT(0xc330000000000000) | (duk_uint64_t) (-tv->v.fi);\n\t\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\t\treturn du.d + 4503599627370496.0;  /* 1 << 52 */\n\t\t}\n\t} else {\n\t\treturn tv->v.d;\n\t}\n}\n#endif  /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */\n#endif  /* 0 */\n\n#if defined(DUK_USE_FASTINT) && !defined(DUK_USE_PACKED_TVAL)\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked_fastint(duk_tval *tv) {\n\tduk_double_union du;\n\tduk_uint64_t t;\n\n\tDUK_ASSERT(tv->t == DUK_TAG_FASTINT);\n\n\tif (tv->v.fi >= 0) {\n\t\tt = DUK_U64_CONSTANT(0x4330000000000000) | (duk_uint64_t) tv->v.fi;\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d - 4503599627370496.0;  /* 1 << 52 */\n\t} else {\n\t\tt = DUK_U64_CONSTANT(0xc330000000000000) | (duk_uint64_t) (-tv->v.fi);\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d + 4503599627370496.0;  /* 1 << 52 */\n\t}\n}\n#endif  /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */\n\n#endif  /* DUK_USE_FASTINT */\n\n/*\n *  Assertion helpers.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL void duk_tval_assert_valid(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_tval.h",
    "content": "/*\n *  Tagged type definition (duk_tval) and accessor macros.\n *\n *  Access all fields through the accessor macros, as the representation\n *  is quite tricky.\n *\n *  There are two packed type alternatives: an 8-byte representation\n *  based on an IEEE double (preferred for compactness), and a 12-byte\n *  representation (portability).  The latter is needed also in e.g.\n *  64-bit environments (it usually pads to 16 bytes per value).\n *\n *  Selecting the tagged type format involves many trade-offs (memory\n *  use, size and performance of generated code, portability, etc).\n *\n *  NB: because macro arguments are often expressions, macros should\n *  avoid evaluating their argument more than once.\n */\n\n#if !defined(DUK_TVAL_H_INCLUDED)\n#define DUK_TVAL_H_INCLUDED\n\n/* sanity */\n#if !defined(DUK_USE_DOUBLE_LE) && !defined(DUK_USE_DOUBLE_ME) && !defined(DUK_USE_DOUBLE_BE)\n#error unsupported: cannot determine byte order variant\n#endif\n\n#if defined(DUK_USE_PACKED_TVAL)\n/* ======================================================================== */\n\n/*\n *  Packed 8-byte representation\n */\n\n/* use duk_double_union as duk_tval directly */\ntypedef union duk_double_union duk_tval;\ntypedef struct {\n\tduk_uint16_t a;\n\tduk_uint16_t b;\n\tduk_uint16_t c;\n\tduk_uint16_t d;\n} duk_tval_unused;\n\n/* tags */\n#define DUK_TAG_NORMALIZED_NAN    0x7ff8UL   /* the NaN variant we use */\n/* avoid tag 0xfff0, no risk of confusion with negative infinity */\n#define DUK_TAG_MIN               0xfff1UL\n#if defined(DUK_USE_FASTINT)\n#define DUK_TAG_FASTINT           0xfff1UL   /* embed: integer value */\n#endif\n#define DUK_TAG_UNUSED            0xfff2UL   /* marker; not actual tagged value */\n#define DUK_TAG_UNDEFINED         0xfff3UL   /* embed: nothing */\n#define DUK_TAG_NULL              0xfff4UL   /* embed: nothing */\n#define DUK_TAG_BOOLEAN           0xfff5UL   /* embed: 0 or 1 (false or true) */\n/* DUK_TAG_NUMBER would logically go here, but it has multiple 'tags' */\n#define DUK_TAG_POINTER           0xfff6UL   /* embed: void ptr */\n#define DUK_TAG_LIGHTFUNC         0xfff7UL   /* embed: func ptr */\n#define DUK_TAG_STRING            0xfff8UL   /* embed: duk_hstring ptr */\n#define DUK_TAG_OBJECT            0xfff9UL   /* embed: duk_hobject ptr */\n#define DUK_TAG_BUFFER            0xfffaUL   /* embed: duk_hbuffer ptr */\n#define DUK_TAG_MAX               0xfffaUL\n\n/* for convenience */\n#define DUK_XTAG_BOOLEAN_FALSE    0xfff50000UL\n#define DUK_XTAG_BOOLEAN_TRUE     0xfff50001UL\n\n#define DUK_TVAL_IS_VALID_TAG(tv) \\\n\t(DUK_TVAL_GET_TAG((tv)) - DUK_TAG_MIN <= DUK_TAG_MAX - DUK_TAG_MIN)\n\n/* DUK_TVAL_UNUSED initializer for duk_tval_unused, works for any endianness. */\n#define DUK_TVAL_UNUSED_INITIALIZER() \\\n\t{ DUK_TAG_UNUSED, DUK_TAG_UNUSED, DUK_TAG_UNUSED, DUK_TAG_UNUSED }\n\n/* two casts to avoid gcc warning: \"warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]\" */\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) (tag)) << 16) | (((duk_uint64_t) (duk_uint32_t) (h)) << 32); \\\n\t} while (0)\n#else\n#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) (tag)) << 48) | ((duk_uint64_t) (duk_uint32_t) (h)); \\\n\t} while (0)\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) (tag)) << 16; \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (h); \\\n\t} while (0)\n#endif  /* DUK_USE_64BIT_OPS */\n\n#if defined(DUK_USE_64BIT_OPS)\n/* Double casting for pointer to avoid gcc warning (cast from pointer to integer of different size) */\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_LIGHTFUNC) << 16) | \\\n\t\t                              ((duk_uint64_t) (flags)) | \\\n\t\t                              (((duk_uint64_t) (duk_uint32_t) (fp)) << 32); \\\n\t} while (0)\n#else\n#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_LIGHTFUNC) << 48) | \\\n\t\t                              (((duk_uint64_t) (flags)) << 32) | \\\n\t\t                              ((duk_uint64_t) (duk_uint32_t) (fp)); \\\n\t} while (0)\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = (((duk_uint32_t) DUK_TAG_LIGHTFUNC) << 16) | ((duk_uint32_t) (flags)); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (fp); \\\n\t} while (0)\n#endif  /* DUK_USE_64BIT_OPS */\n\n#if defined(DUK_USE_FASTINT)\n/* Note: masking is done for 'i' to deal with negative numbers correctly */\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_SET_I48(tv,i)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) DUK_TAG_FASTINT) << 16 | (((duk_uint32_t) ((i) >> 32)) & 0x0000ffffUL); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (i); \\\n\t} while (0)\n#define DUK__TVAL_SET_U32(tv,i)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) DUK_TAG_FASTINT) << 16; \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (i); \\\n\t} while (0)\n#else\n#define DUK__TVAL_SET_I48(tv,i)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (((duk_uint64_t) (i)) & DUK_U64_CONSTANT(0x0000ffffffffffff)); \\\n\t} while (0)\n#define DUK__TVAL_SET_U32(tv,i)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (duk_uint64_t) (i); \\\n\t} while (0)\n#endif\n\n/* This needs to go through a cast because sign extension is needed. */\n#define DUK__TVAL_SET_I32(tv,i)  do { \\\n\t\tduk_int64_t duk__tmp = (duk_int64_t) (i); \\\n\t\tDUK_TVAL_SET_I48((tv), duk__tmp); \\\n\t} while (0)\n\n/* XXX: Clumsy sign extend and masking of 16 topmost bits. */\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_GET_FASTINT(tv)      (((duk_int64_t) ((((duk_uint64_t) (tv)->ui[DUK_DBL_IDX_UI0]) << 32) | ((duk_uint64_t) (tv)->ui[DUK_DBL_IDX_UI1]))) << 16 >> 16)\n#else\n#define DUK__TVAL_GET_FASTINT(tv)      ((((duk_int64_t) (tv)->ull[DUK_DBL_IDX_ULL0]) << 16) >> 16)\n#endif\n#define DUK__TVAL_GET_FASTINT_U32(tv)  ((tv)->ui[DUK_DBL_IDX_UI1])\n#define DUK__TVAL_GET_FASTINT_I32(tv)  ((duk_int32_t) (tv)->ui[DUK_DBL_IDX_UI1])\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_UNDEFINED(tv)  do { \\\n\t\t(tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNDEFINED; \\\n\t} while (0)\n#define DUK_TVAL_SET_UNUSED(tv)  do { \\\n\t\t(tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNUSED; \\\n\t} while (0)\n#define DUK_TVAL_SET_NULL(tv)  do { \\\n\t\t(tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_NULL; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN(tv,val)         DUK_DBLUNION_SET_HIGH32((tv), (((duk_uint32_t) DUK_TAG_BOOLEAN) << 16) | ((duk_uint32_t) (val)))\n\n#define DUK_TVAL_SET_NAN(tv)                 DUK_DBLUNION_SET_NAN_FULL((tv))\n\n/* Assumes that caller has normalized NaNs, otherwise trouble ahead. */\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_DOUBLE(tv,d)  do { \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (d); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); \\\n\t\tDUK_DBLUNION_SET_DOUBLE((tv), duk__dblval); \\\n\t} while (0)\n#define DUK_TVAL_SET_I48(tv,i)               DUK__TVAL_SET_I48((tv), (i))\n#define DUK_TVAL_SET_I32(tv,i)               DUK__TVAL_SET_I32((tv), (i))\n#define DUK_TVAL_SET_U32(tv,i)               DUK__TVAL_SET_U32((tv), (i))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d)  duk_tval_set_number_chkfast_fast((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d)  duk_tval_set_number_chkfast_slow((tv), (d))\n#define DUK_TVAL_SET_NUMBER(tv,d)            DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#else  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_DOUBLE(tv,d)  do { \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (d); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); \\\n\t\tDUK_DBLUNION_SET_DOUBLE((tv), duk__dblval); \\\n\t} while (0)\n#define DUK_TVAL_SET_I48(tv,i)               DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i))  /* XXX: fast int-to-double */\n#define DUK_TVAL_SET_I32(tv,i)               DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i))\n#define DUK_TVAL_SET_U32(tv,i)               DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d)    DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d)    DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_SET_NUMBER(tv,d)            DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { } while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { } while (0)\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_FASTINT(tv,i)           DUK_TVAL_SET_I48((tv), (i))  /* alias */\n\n#define DUK_TVAL_SET_LIGHTFUNC(tv,fp,flags)  DUK__TVAL_SET_LIGHTFUNC((tv), (fp), (flags))\n#define DUK_TVAL_SET_STRING(tv,h)            DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_STRING)\n#define DUK_TVAL_SET_OBJECT(tv,h)            DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_OBJECT)\n#define DUK_TVAL_SET_BUFFER(tv,h)            DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_BUFFER)\n#define DUK_TVAL_SET_POINTER(tv,p)           DUK__TVAL_SET_TAGGEDPOINTER((tv), (p), DUK_TAG_POINTER)\n\n#define DUK_TVAL_SET_TVAL(tv,x)              do { *(tv) = *(x); } while (0)\n\n/* getters */\n#define DUK_TVAL_GET_BOOLEAN(tv)             ((duk_small_uint_t) (tv)->us[DUK_DBL_IDX_US1])\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_GET_DOUBLE(tv)              ((tv)->d)\n#define DUK_TVAL_GET_FASTINT(tv)             DUK__TVAL_GET_FASTINT((tv))\n#define DUK_TVAL_GET_FASTINT_U32(tv)         DUK__TVAL_GET_FASTINT_U32((tv))\n#define DUK_TVAL_GET_FASTINT_I32(tv)         DUK__TVAL_GET_FASTINT_I32((tv))\n#define DUK_TVAL_GET_NUMBER(tv)              duk_tval_get_number_packed((tv))\n#else\n#define DUK_TVAL_GET_NUMBER(tv)              ((tv)->d)\n#define DUK_TVAL_GET_DOUBLE(tv)              ((tv)->d)\n#endif\n#define DUK_TVAL_GET_LIGHTFUNC(tv,out_fp,out_flags)  do { \\\n\t\t(out_flags) = (tv)->ui[DUK_DBL_IDX_UI0] & 0xffffUL; \\\n\t\t(out_fp) = (duk_c_function) (tv)->ui[DUK_DBL_IDX_UI1]; \\\n\t} while (0)\n#define DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv)   ((duk_c_function) ((tv)->ui[DUK_DBL_IDX_UI1]))\n#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv)     (((duk_small_uint_t) (tv)->ui[DUK_DBL_IDX_UI0]) & 0xffffUL)\n#define DUK_TVAL_GET_STRING(tv)              ((duk_hstring *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_OBJECT(tv)              ((duk_hobject *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_BUFFER(tv)              ((duk_hbuffer *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_POINTER(tv)             ((void *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_HEAPHDR(tv)             ((duk_heaphdr *) (tv)->vp[DUK_DBL_IDX_VP1])\n\n/* decoding */\n#define DUK_TVAL_GET_TAG(tv)                 ((duk_small_uint_t) (tv)->us[DUK_DBL_IDX_US0])\n\n#define DUK_TVAL_IS_UNDEFINED(tv)            (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_UNDEFINED)\n#define DUK_TVAL_IS_UNUSED(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_UNUSED)\n#define DUK_TVAL_IS_NULL(tv)                 (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_NULL)\n#define DUK_TVAL_IS_BOOLEAN(tv)              (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_BOOLEAN)\n#define DUK_TVAL_IS_BOOLEAN_TRUE(tv)         ((tv)->ui[DUK_DBL_IDX_UI0] == DUK_XTAG_BOOLEAN_TRUE)\n#define DUK_TVAL_IS_BOOLEAN_FALSE(tv)        ((tv)->ui[DUK_DBL_IDX_UI0] == DUK_XTAG_BOOLEAN_FALSE)\n#define DUK_TVAL_IS_LIGHTFUNC(tv)            (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_LIGHTFUNC)\n#define DUK_TVAL_IS_STRING(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_STRING)\n#define DUK_TVAL_IS_OBJECT(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_OBJECT)\n#define DUK_TVAL_IS_BUFFER(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_BUFFER)\n#define DUK_TVAL_IS_POINTER(tv)              (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_POINTER)\n#if defined(DUK_USE_FASTINT)\n/* 0xfff0 is -Infinity */\n#define DUK_TVAL_IS_DOUBLE(tv)               (DUK_TVAL_GET_TAG((tv)) <= 0xfff0UL)\n#define DUK_TVAL_IS_FASTINT(tv)              (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_FASTINT)\n#define DUK_TVAL_IS_NUMBER(tv)               (DUK_TVAL_GET_TAG((tv)) <= 0xfff1UL)\n#else\n#define DUK_TVAL_IS_NUMBER(tv)               (DUK_TVAL_GET_TAG((tv)) <= 0xfff0UL)\n#define DUK_TVAL_IS_DOUBLE(tv)               DUK_TVAL_IS_NUMBER((tv))\n#endif\n\n/* This is performance critical because it appears in every DECREF. */\n#define DUK_TVAL_IS_HEAP_ALLOCATED(tv)       (DUK_TVAL_GET_TAG((tv)) >= DUK_TAG_STRING)\n\n#if defined(DUK_USE_FASTINT)\nDUK_INTERNAL_DECL duk_double_t duk_tval_get_number_packed(duk_tval *tv);\n#endif\n\n#else  /* DUK_USE_PACKED_TVAL */\n/* ======================================================================== */\n\n/*\n *  Portable 12-byte representation\n */\n\n/* Note: not initializing all bytes is normally not an issue: Duktape won't\n * read or use the uninitialized bytes so valgrind won't issue warnings.\n * In some special cases a harmless valgrind warning may be issued though.\n * For example, the DumpHeap debugger command writes out a compiled function's\n * 'data' area as is, including any uninitialized bytes, which causes a\n * valgrind warning.\n */\n\ntypedef struct duk_tval_struct duk_tval;\n\nstruct duk_tval_struct {\n\tduk_small_uint_t t;\n\tduk_small_uint_t v_extra;\n\tunion {\n\t\tduk_double_t d;\n\t\tduk_small_int_t i;\n#if defined(DUK_USE_FASTINT)\n\t\tduk_int64_t fi;  /* if present, forces 16-byte duk_tval */\n#endif\n\t\tvoid *voidptr;\n\t\tduk_hstring *hstring;\n\t\tduk_hobject *hobject;\n\t\tduk_hcompfunc *hcompfunc;\n\t\tduk_hnatfunc *hnatfunc;\n\t\tduk_hthread *hthread;\n\t\tduk_hbuffer *hbuffer;\n\t\tduk_heaphdr *heaphdr;\n\t\tduk_c_function lightfunc;\n\t} v;\n};\n\ntypedef struct {\n\tduk_small_uint_t t;\n\tduk_small_uint_t v_extra;\n\t/* The rest of the fields don't matter except for debug dumps and such\n\t * for which a partial initializer may trigger out-ot-bounds memory\n\t * reads.  Include a double field which is usually as large or larger\n\t * than pointers (not always however).\n\t */\n\tduk_double_t d;\n} duk_tval_unused;\n\n#define DUK_TVAL_UNUSED_INITIALIZER() \\\n\t{ DUK_TAG_UNUSED, 0, 0.0 }\n\n#define DUK_TAG_MIN                   0\n#define DUK_TAG_NUMBER                0  /* DUK_TAG_NUMBER only defined for non-packed duk_tval */\n#if defined(DUK_USE_FASTINT)\n#define DUK_TAG_FASTINT               1\n#endif\n#define DUK_TAG_UNDEFINED             2\n#define DUK_TAG_NULL                  3\n#define DUK_TAG_BOOLEAN               4\n#define DUK_TAG_POINTER               5\n#define DUK_TAG_LIGHTFUNC             6\n#define DUK_TAG_UNUSED                7  /* marker; not actual tagged type */\n#define DUK_TAG_STRING                8  /* first heap allocated, match bit boundary */\n#define DUK_TAG_OBJECT                9\n#define DUK_TAG_BUFFER                10\n#define DUK_TAG_MAX                   10\n\n#define DUK_TVAL_IS_VALID_TAG(tv) \\\n\t(DUK_TVAL_GET_TAG((tv)) - DUK_TAG_MIN <= DUK_TAG_MAX - DUK_TAG_MIN)\n\n/* DUK_TAG_NUMBER is intentionally first, as it is the default clause in code\n * to support the 8-byte representation.  Further, it is a non-heap-allocated\n * type so it should come before DUK_TAG_STRING.  Finally, it should not break\n * the tag value ranges covered by case-clauses in a switch-case.\n */\n\n/* setters */\n#define DUK_TVAL_SET_UNDEFINED(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_UNDEFINED; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNUSED(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_UNUSED; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NULL(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NULL; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_BOOLEAN; \\\n\t\tduk__tv->v.i = (duk_small_int_t) (val); \\\n\t} while (0)\n\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_DOUBLE(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (val); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); /* nop for unpacked duk_tval */ \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NUMBER; \\\n\t\tduk__tv->v.d = duk__dblval; \\\n\t} while (0)\n#define DUK_TVAL_SET_I48(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_FASTINT; \\\n\t\tduk__tv->v.fi = (val); \\\n\t} while (0)\n#define DUK_TVAL_SET_U32(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_FASTINT; \\\n\t\tduk__tv->v.fi = (duk_int64_t) (val); \\\n\t} while (0)\n#define DUK_TVAL_SET_I32(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_FASTINT; \\\n\t\tduk__tv->v.fi = (duk_int64_t) (val); \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) \\\n\tduk_tval_set_number_chkfast_fast((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) \\\n\tduk_tval_set_number_chkfast_slow((tv), (d))\n#define DUK_TVAL_SET_NUMBER(tv,val) \\\n\tDUK_TVAL_SET_DOUBLE((tv), (val))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#else  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_DOUBLE(tv,d) \\\n\tDUK_TVAL_SET_NUMBER((tv), (d))\n#define DUK_TVAL_SET_I48(tv,val) \\\n\tDUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val))  /* XXX: fast int-to-double */\n#define DUK_TVAL_SET_U32(tv,val) \\\n\tDUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val))\n#define DUK_TVAL_SET_I32(tv,val) \\\n\tDUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val))\n#define DUK_TVAL_SET_NUMBER(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (val); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); /* nop for unpacked duk_tval */ \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NUMBER; \\\n\t\tduk__tv->v.d = duk__dblval; \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) \\\n\tDUK_TVAL_SET_NUMBER((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) \\\n\tDUK_TVAL_SET_NUMBER((tv), (d))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { } while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { } while (0)\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_FASTINT(tv,i) \\\n\tDUK_TVAL_SET_I48((tv), (i))  /* alias */\n\n#define DUK_TVAL_SET_POINTER(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_POINTER; \\\n\t\tduk__tv->v.voidptr = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_LIGHTFUNC; \\\n\t\tduk__tv->v_extra = (flags); \\\n\t\tduk__tv->v.lightfunc = (duk_c_function) (fp); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_STRING(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_STRING; \\\n\t\tduk__tv->v.hstring = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_OBJECT(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_OBJECT; \\\n\t\tduk__tv->v.hobject = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BUFFER(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_BUFFER; \\\n\t\tduk__tv->v.hbuffer = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NAN(tv)  do { \\\n\t\t/* in non-packed representation we don't care about which NaN is used */ \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NUMBER; \\\n\t\tduk__tv->v.d = DUK_DOUBLE_NAN; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_TVAL(tv,x)            do { *(tv) = *(x); } while (0)\n\n/* getters */\n#define DUK_TVAL_GET_BOOLEAN(tv)           ((duk_small_uint_t) (tv)->v.i)\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_GET_DOUBLE(tv)            ((tv)->v.d)\n#define DUK_TVAL_GET_FASTINT(tv)           ((tv)->v.fi)\n#define DUK_TVAL_GET_FASTINT_U32(tv)       ((duk_uint32_t) ((tv)->v.fi))\n#define DUK_TVAL_GET_FASTINT_I32(tv)       ((duk_int32_t) ((tv)->v.fi))\n#if 0\n#define DUK_TVAL_GET_NUMBER(tv)            (DUK_TVAL_IS_FASTINT((tv)) ? \\\n                                               (duk_double_t) DUK_TVAL_GET_FASTINT((tv)) : \\\n                                               DUK_TVAL_GET_DOUBLE((tv)))\n#define DUK_TVAL_GET_NUMBER(tv)            duk_tval_get_number_unpacked((tv))\n#else\n/* This seems reasonable overall. */\n#define DUK_TVAL_GET_NUMBER(tv)            (DUK_TVAL_IS_FASTINT((tv)) ? \\\n                                               duk_tval_get_number_unpacked_fastint((tv)) : \\\n                                               DUK_TVAL_GET_DOUBLE((tv)))\n#endif\n#else\n#define DUK_TVAL_GET_NUMBER(tv)            ((tv)->v.d)\n#define DUK_TVAL_GET_DOUBLE(tv)            ((tv)->v.d)\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_GET_POINTER(tv)           ((tv)->v.voidptr)\n#define DUK_TVAL_GET_LIGHTFUNC(tv,out_fp,out_flags)  do { \\\n\t\t(out_flags) = (duk_uint32_t) (tv)->v_extra; \\\n\t\t(out_fp) = (tv)->v.lightfunc; \\\n\t} while (0)\n#define DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv) ((tv)->v.lightfunc)\n#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv)   ((duk_small_uint_t) ((tv)->v_extra))\n#define DUK_TVAL_GET_STRING(tv)            ((tv)->v.hstring)\n#define DUK_TVAL_GET_OBJECT(tv)            ((tv)->v.hobject)\n#define DUK_TVAL_GET_BUFFER(tv)            ((tv)->v.hbuffer)\n#define DUK_TVAL_GET_HEAPHDR(tv)           ((tv)->v.heaphdr)\n\n/* decoding */\n#define DUK_TVAL_GET_TAG(tv)               ((tv)->t)\n#define DUK_TVAL_IS_UNDEFINED(tv)          ((tv)->t == DUK_TAG_UNDEFINED)\n#define DUK_TVAL_IS_UNUSED(tv)             ((tv)->t == DUK_TAG_UNUSED)\n#define DUK_TVAL_IS_NULL(tv)               ((tv)->t == DUK_TAG_NULL)\n#define DUK_TVAL_IS_BOOLEAN(tv)            ((tv)->t == DUK_TAG_BOOLEAN)\n#define DUK_TVAL_IS_BOOLEAN_TRUE(tv)       (((tv)->t == DUK_TAG_BOOLEAN) && ((tv)->v.i != 0))\n#define DUK_TVAL_IS_BOOLEAN_FALSE(tv)      (((tv)->t == DUK_TAG_BOOLEAN) && ((tv)->v.i == 0))\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_IS_DOUBLE(tv)             ((tv)->t == DUK_TAG_NUMBER)\n#define DUK_TVAL_IS_FASTINT(tv)            ((tv)->t == DUK_TAG_FASTINT)\n#define DUK_TVAL_IS_NUMBER(tv)             ((tv)->t == DUK_TAG_NUMBER || \\\n                                            (tv)->t == DUK_TAG_FASTINT)\n#else\n#define DUK_TVAL_IS_NUMBER(tv)             ((tv)->t == DUK_TAG_NUMBER)\n#define DUK_TVAL_IS_DOUBLE(tv)             DUK_TVAL_IS_NUMBER((tv))\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_IS_POINTER(tv)            ((tv)->t == DUK_TAG_POINTER)\n#define DUK_TVAL_IS_LIGHTFUNC(tv)          ((tv)->t == DUK_TAG_LIGHTFUNC)\n#define DUK_TVAL_IS_STRING(tv)             ((tv)->t == DUK_TAG_STRING)\n#define DUK_TVAL_IS_OBJECT(tv)             ((tv)->t == DUK_TAG_OBJECT)\n#define DUK_TVAL_IS_BUFFER(tv)             ((tv)->t == DUK_TAG_BUFFER)\n\n/* This is performance critical because it's needed for every DECREF.\n * Take advantage of the fact that the first heap allocated tag is 8,\n * so that bit 3 is set for all heap allocated tags (and never set for\n * non-heap-allocated tags).\n */\n#if 0\n#define DUK_TVAL_IS_HEAP_ALLOCATED(tv)     ((tv)->t >= DUK_TAG_STRING)\n#endif\n#define DUK_TVAL_IS_HEAP_ALLOCATED(tv)     ((tv)->t & 0x08)\n\n#if defined(DUK_USE_FASTINT)\n#if 0\nDUK_INTERNAL_DECL duk_double_t duk_tval_get_number_unpacked(duk_tval *tv);\n#endif\nDUK_INTERNAL_DECL duk_double_t duk_tval_get_number_unpacked_fastint(duk_tval *tv);\n#endif\n\n#endif  /* DUK_USE_PACKED_TVAL */\n\n/*\n *  Convenience (independent of representation)\n */\n\n#define DUK_TVAL_SET_BOOLEAN_TRUE(tv)        DUK_TVAL_SET_BOOLEAN((tv), 1)\n#define DUK_TVAL_SET_BOOLEAN_FALSE(tv)       DUK_TVAL_SET_BOOLEAN((tv), 0)\n\n#define DUK_TVAL_STRING_IS_SYMBOL(tv) \\\n\tDUK_HSTRING_HAS_SYMBOL(DUK_TVAL_GET_STRING((tv)))\n\n/* Lightfunc flags packing and unpacking. */\n/* Sign extend: 0x0000##00 -> 0x##000000 -> sign extend to 0xssssss##.\n * Avoid signed shifts due to portability limitations.\n */\n#define DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags) \\\n\t((duk_int32_t) (duk_int8_t) (((duk_uint16_t) (lf_flags)) >> 8))\n#define DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags) \\\n\t(((lf_flags) >> 4) & 0x0fU)\n#define DUK_LFUNC_FLAGS_GET_NARGS(lf_flags) \\\n\t((lf_flags) & 0x0fU)\n#define DUK_LFUNC_FLAGS_PACK(magic,length,nargs) \\\n\t((((duk_small_uint_t) (magic)) & 0xffU) << 8) | ((length) << 4) | (nargs)\n\n#define DUK_LFUNC_NARGS_VARARGS             0x0f   /* varargs marker */\n#define DUK_LFUNC_NARGS_MIN                 0x00\n#define DUK_LFUNC_NARGS_MAX                 0x0e   /* max, excl. varargs marker */\n#define DUK_LFUNC_LENGTH_MIN                0x00\n#define DUK_LFUNC_LENGTH_MAX                0x0f\n#define DUK_LFUNC_MAGIC_MIN                 (-0x80)\n#define DUK_LFUNC_MAGIC_MAX                 0x7f\n\n/* fastint constants etc */\n#if defined(DUK_USE_FASTINT)\n#define DUK_FASTINT_MIN           (DUK_I64_CONSTANT(-0x800000000000))\n#define DUK_FASTINT_MAX           (DUK_I64_CONSTANT(0x7fffffffffff))\n#define DUK_FASTINT_BITS          48\n\nDUK_INTERNAL_DECL void duk_tval_set_number_chkfast_fast(duk_tval *tv, duk_double_t x);\nDUK_INTERNAL_DECL void duk_tval_set_number_chkfast_slow(duk_tval *tv, duk_double_t x);\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_tval_assert_valid(duk_tval *tv);\n#define DUK_TVAL_ASSERT_VALID(tv)  do { duk_tval_assert_valid((tv)); } while (0)\n#else\n#define DUK_TVAL_ASSERT_VALID(tv)  do {} while (0)\n#endif\n\n#endif  /* DUK_TVAL_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_unicode.h",
    "content": "/*\n *  Unicode helpers\n */\n\n#if !defined(DUK_UNICODE_H_INCLUDED)\n#define DUK_UNICODE_H_INCLUDED\n\n/*\n *  UTF-8 / XUTF-8 / CESU-8 constants\n */\n\n#define DUK_UNICODE_MAX_XUTF8_LENGTH      7   /* up to 36 bit codepoints */\n#define DUK_UNICODE_MAX_XUTF8_BMP_LENGTH  3   /* all codepoints up to U+FFFF */\n#define DUK_UNICODE_MAX_CESU8_LENGTH      6   /* all codepoints up to U+10FFFF */\n#define DUK_UNICODE_MAX_CESU8_BMP_LENGTH  3   /* all codepoints up to U+FFFF */\n\n/*\n *  Useful Unicode codepoints\n *\n *  Integer constants must be signed to avoid unexpected coercions\n *  in comparisons.\n */\n\n#define DUK_UNICODE_CP_ZWNJ                   0x200cL  /* zero-width non-joiner */\n#define DUK_UNICODE_CP_ZWJ                    0x200dL  /* zero-width joiner */\n#define DUK_UNICODE_CP_REPLACEMENT_CHARACTER  0xfffdL  /* http://en.wikipedia.org/wiki/Replacement_character#Replacement_character */\n\n/*\n *  ASCII character constants\n *\n *  C character literals like 'x' have a platform specific value and do\n *  not match ASCII (UTF-8) values on e.g. EBCDIC platforms.  So, use\n *  these (admittedly awkward) constants instead.  These constants must\n *  also have signed values to avoid unexpected coercions in comparisons.\n *\n *  http://en.wikipedia.org/wiki/ASCII\n */\n\n#define DUK_ASC_NUL              0x00\n#define DUK_ASC_SOH              0x01\n#define DUK_ASC_STX              0x02\n#define DUK_ASC_ETX              0x03\n#define DUK_ASC_EOT              0x04\n#define DUK_ASC_ENQ              0x05\n#define DUK_ASC_ACK              0x06\n#define DUK_ASC_BEL              0x07\n#define DUK_ASC_BS               0x08\n#define DUK_ASC_HT               0x09\n#define DUK_ASC_LF               0x0a\n#define DUK_ASC_VT               0x0b\n#define DUK_ASC_FF               0x0c\n#define DUK_ASC_CR               0x0d\n#define DUK_ASC_SO               0x0e\n#define DUK_ASC_SI               0x0f\n#define DUK_ASC_DLE              0x10\n#define DUK_ASC_DC1              0x11\n#define DUK_ASC_DC2              0x12\n#define DUK_ASC_DC3              0x13\n#define DUK_ASC_DC4              0x14\n#define DUK_ASC_NAK              0x15\n#define DUK_ASC_SYN              0x16\n#define DUK_ASC_ETB              0x17\n#define DUK_ASC_CAN              0x18\n#define DUK_ASC_EM               0x19\n#define DUK_ASC_SUB              0x1a\n#define DUK_ASC_ESC              0x1b\n#define DUK_ASC_FS               0x1c\n#define DUK_ASC_GS               0x1d\n#define DUK_ASC_RS               0x1e\n#define DUK_ASC_US               0x1f\n#define DUK_ASC_SPACE            0x20\n#define DUK_ASC_EXCLAMATION      0x21\n#define DUK_ASC_DOUBLEQUOTE      0x22\n#define DUK_ASC_HASH             0x23\n#define DUK_ASC_DOLLAR           0x24\n#define DUK_ASC_PERCENT          0x25\n#define DUK_ASC_AMP              0x26\n#define DUK_ASC_SINGLEQUOTE      0x27\n#define DUK_ASC_LPAREN           0x28\n#define DUK_ASC_RPAREN           0x29\n#define DUK_ASC_STAR             0x2a\n#define DUK_ASC_PLUS             0x2b\n#define DUK_ASC_COMMA            0x2c\n#define DUK_ASC_MINUS            0x2d\n#define DUK_ASC_PERIOD           0x2e\n#define DUK_ASC_SLASH            0x2f\n#define DUK_ASC_0                0x30\n#define DUK_ASC_1                0x31\n#define DUK_ASC_2                0x32\n#define DUK_ASC_3                0x33\n#define DUK_ASC_4                0x34\n#define DUK_ASC_5                0x35\n#define DUK_ASC_6                0x36\n#define DUK_ASC_7                0x37\n#define DUK_ASC_8                0x38\n#define DUK_ASC_9                0x39\n#define DUK_ASC_COLON            0x3a\n#define DUK_ASC_SEMICOLON        0x3b\n#define DUK_ASC_LANGLE           0x3c\n#define DUK_ASC_EQUALS           0x3d\n#define DUK_ASC_RANGLE           0x3e\n#define DUK_ASC_QUESTION         0x3f\n#define DUK_ASC_ATSIGN           0x40\n#define DUK_ASC_UC_A             0x41\n#define DUK_ASC_UC_B             0x42\n#define DUK_ASC_UC_C             0x43\n#define DUK_ASC_UC_D             0x44\n#define DUK_ASC_UC_E             0x45\n#define DUK_ASC_UC_F             0x46\n#define DUK_ASC_UC_G             0x47\n#define DUK_ASC_UC_H             0x48\n#define DUK_ASC_UC_I             0x49\n#define DUK_ASC_UC_J             0x4a\n#define DUK_ASC_UC_K             0x4b\n#define DUK_ASC_UC_L             0x4c\n#define DUK_ASC_UC_M             0x4d\n#define DUK_ASC_UC_N             0x4e\n#define DUK_ASC_UC_O             0x4f\n#define DUK_ASC_UC_P             0x50\n#define DUK_ASC_UC_Q             0x51\n#define DUK_ASC_UC_R             0x52\n#define DUK_ASC_UC_S             0x53\n#define DUK_ASC_UC_T             0x54\n#define DUK_ASC_UC_U             0x55\n#define DUK_ASC_UC_V             0x56\n#define DUK_ASC_UC_W             0x57\n#define DUK_ASC_UC_X             0x58\n#define DUK_ASC_UC_Y             0x59\n#define DUK_ASC_UC_Z             0x5a\n#define DUK_ASC_LBRACKET         0x5b\n#define DUK_ASC_BACKSLASH        0x5c\n#define DUK_ASC_RBRACKET         0x5d\n#define DUK_ASC_CARET            0x5e\n#define DUK_ASC_UNDERSCORE       0x5f\n#define DUK_ASC_GRAVE            0x60\n#define DUK_ASC_LC_A             0x61\n#define DUK_ASC_LC_B             0x62\n#define DUK_ASC_LC_C             0x63\n#define DUK_ASC_LC_D             0x64\n#define DUK_ASC_LC_E             0x65\n#define DUK_ASC_LC_F             0x66\n#define DUK_ASC_LC_G             0x67\n#define DUK_ASC_LC_H             0x68\n#define DUK_ASC_LC_I             0x69\n#define DUK_ASC_LC_J             0x6a\n#define DUK_ASC_LC_K             0x6b\n#define DUK_ASC_LC_L             0x6c\n#define DUK_ASC_LC_M             0x6d\n#define DUK_ASC_LC_N             0x6e\n#define DUK_ASC_LC_O             0x6f\n#define DUK_ASC_LC_P             0x70\n#define DUK_ASC_LC_Q             0x71\n#define DUK_ASC_LC_R             0x72\n#define DUK_ASC_LC_S             0x73\n#define DUK_ASC_LC_T             0x74\n#define DUK_ASC_LC_U             0x75\n#define DUK_ASC_LC_V             0x76\n#define DUK_ASC_LC_W             0x77\n#define DUK_ASC_LC_X             0x78\n#define DUK_ASC_LC_Y             0x79\n#define DUK_ASC_LC_Z             0x7a\n#define DUK_ASC_LCURLY           0x7b\n#define DUK_ASC_PIPE             0x7c\n#define DUK_ASC_RCURLY           0x7d\n#define DUK_ASC_TILDE            0x7e\n#define DUK_ASC_DEL              0x7f\n\n/*\n *  Miscellaneous\n */\n\n/* Uppercase A is 0x41, lowercase a is 0x61; OR 0x20 to convert uppercase\n * to lowercase.\n */\n#define DUK_LOWERCASE_CHAR_ASCII(x)  ((x) | 0x20)\n\n/*\n *  Unicode tables\n */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n#include \"duk_unicode_ids_noa.h\"\n#else\n#include \"duk_unicode_ids_noabmp.h\"\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n#include \"duk_unicode_ids_m_let_noa.h\"\n#else\n#include \"duk_unicode_ids_m_let_noabmp.h\"\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n#include \"duk_unicode_idp_m_ids_noa.h\"\n#else\n#include \"duk_unicode_idp_m_ids_noabmp.h\"\n#endif\n\n#include \"duk_unicode_caseconv.h\"\n\n#if defined(DUK_USE_REGEXP_CANON_WORKAROUND)\n#include \"duk_unicode_re_canon_lookup.h\"\n#endif\n\n#if defined(DUK_USE_REGEXP_CANON_BITMAP)\n#include \"duk_unicode_re_canon_bitmap.h\"\n#endif\n\n/*\n *  Extern\n */\n\n/* duk_unicode_support.c */\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_unicode_xutf8_markers[7];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_digit[2];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_white[22];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_wordchar[8];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_not_digit[4];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_not_white[24];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_not_wordchar[10];\nDUK_INTERNAL_DECL const duk_int8_t duk_is_idchar_tab[128];\n#endif  /* !DUK_SINGLE_FILE */\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_get_xutf8_length(duk_ucodepoint_t cp);\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_get_cesu8_length(duk_ucodepoint_t cp);\n#endif\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_encode_xutf8(duk_ucodepoint_t cp, duk_uint8_t *out);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_encode_cesu8(duk_ucodepoint_t cp, duk_uint8_t *out);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_decode_xutf8(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_ucodepoint_t *out_cp);\nDUK_INTERNAL_DECL duk_ucodepoint_t duk_unicode_decode_xutf8_checked(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end);\nDUK_INTERNAL_DECL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_whitespace(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_line_terminator(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_identifier_start(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_identifier_part(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_letter(duk_codepoint_t cp);\nDUK_INTERNAL_DECL void duk_unicode_case_convert_string(duk_hthread *thr, duk_bool_t uppercase);\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL_DECL duk_codepoint_t duk_unicode_re_canonicalize_char(duk_hthread *thr, duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_re_is_wordchar(duk_codepoint_t cp);\n#endif\n\n#endif  /* DUK_UNICODE_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_unicode_support.c",
    "content": "/*\n *  Various Unicode help functions for character classification predicates,\n *  case conversion, decoding, etc.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Fast path tables\n */\n\n#if defined(DUK_USE_IDCHAR_FASTPATH)\nDUK_INTERNAL const duk_int8_t duk_is_idchar_tab[128] = {\n\t/* 0: not IdentifierStart or IdentifierPart\n\t * 1: IdentifierStart and IdentifierPart\n\t * -1: IdentifierPart only\n\t */\n\t0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   /* 0x00...0x0f */\n\t0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   /* 0x10...0x1f */\n\t0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   /* 0x20...0x2f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0,  0,  0,  0,  0,  0,   /* 0x30...0x3f */\n\t0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,   /* 0x40...0x4f */\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  1,   /* 0x50...0x5f */\n\t0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,   /* 0x60...0x6f */\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0    /* 0x70...0x7f */\n};\n#endif\n\n/*\n *  XUTF-8 and CESU-8 encoding/decoding\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_get_xutf8_length(duk_ucodepoint_t cp) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tif (x < 0x80UL) {\n\t\t/* 7 bits */\n\t\treturn 1;\n\t} else if (x < 0x800UL) {\n\t\t/* 11 bits */\n\t\treturn 2;\n\t} else if (x < 0x10000UL) {\n\t\t/* 16 bits */\n\t\treturn 3;\n\t} else if (x < 0x200000UL) {\n\t\t/* 21 bits */\n\t\treturn 4;\n\t} else if (x < 0x4000000UL) {\n\t\t/* 26 bits */\n\t\treturn 5;\n\t} else if (x < (duk_ucodepoint_t) 0x80000000UL) {\n\t\t/* 31 bits */\n\t\treturn 6;\n\t} else {\n\t\t/* 36 bits */\n\t\treturn 7;\n\t}\n}\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL duk_small_int_t duk_unicode_get_cesu8_length(duk_ucodepoint_t cp) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tif (x < 0x80UL) {\n\t\t/* 7 bits */\n\t\treturn 1;\n\t} else if (x < 0x800UL) {\n\t\t/* 11 bits */\n\t\treturn 2;\n\t} else if (x < 0x10000UL) {\n\t\t/* 16 bits */\n\t\treturn 3;\n\t} else {\n\t\t/* Encoded as surrogate pair, each encoding to 3 bytes for\n\t\t * 6 bytes total.  Codepoints above U+10FFFF encode as 6 bytes\n\t\t * too, see duk_unicode_encode_cesu8().\n\t\t  */\n\t\treturn 3 + 3;\n\t}\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\nDUK_INTERNAL const duk_uint8_t duk_unicode_xutf8_markers[7] = {\n\t0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe\n};\n\n/* Encode to extended UTF-8; 'out' must have space for at least\n * DUK_UNICODE_MAX_XUTF8_LENGTH bytes.  Allows encoding of any\n * 32-bit (unsigned) codepoint.\n */\nDUK_INTERNAL duk_small_int_t duk_unicode_encode_xutf8(duk_ucodepoint_t cp, duk_uint8_t *out) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tduk_small_int_t len;\n\tduk_uint8_t marker;\n\tduk_small_int_t i;\n\n\tlen = duk_unicode_get_xutf8_length(cp);\n\tDUK_ASSERT(len > 0);\n\n\tmarker = duk_unicode_xutf8_markers[len - 1];  /* 64-bit OK because always >= 0 */\n\n\ti = len;\n\tDUK_ASSERT(i > 0);\n\tdo {\n\t\ti--;\n\t\tif (i > 0) {\n\t\t\tout[i] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\t\tx >>= 6;\n\t\t} else {\n\t\t\t/* Note: masking of 'x' is not necessary because of\n\t\t\t * range check and shifting -> no bits overlapping\n\t\t\t * the marker should be set.\n\t\t\t */\n\t\t\tout[0] = (duk_uint8_t) (marker + x);\n\t\t}\n\t} while (i > 0);\n\n\treturn len;\n}\n\n/* Encode to CESU-8; 'out' must have space for at least\n * DUK_UNICODE_MAX_CESU8_LENGTH bytes; codepoints above U+10FFFF\n * will encode to garbage but won't overwrite the output buffer.\n */\nDUK_INTERNAL duk_small_int_t duk_unicode_encode_cesu8(duk_ucodepoint_t cp, duk_uint8_t *out) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tduk_small_int_t len;\n\n\tif (x < 0x80UL) {\n\t\tout[0] = (duk_uint8_t) x;\n\t\tlen = 1;\n\t} else if (x < 0x800UL) {\n\t\tout[0] = (duk_uint8_t) (0xc0 + ((x >> 6) & 0x1f));\n\t\tout[1] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\tlen = 2;\n\t} else if (x < 0x10000UL) {\n\t\t/* surrogate pairs get encoded here */\n\t\tout[0] = (duk_uint8_t) (0xe0 + ((x >> 12) & 0x0f));\n\t\tout[1] = (duk_uint8_t) (0x80 + ((x >> 6) & 0x3f));\n\t\tout[2] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\tlen = 3;\n\t} else {\n\t\t/*\n\t\t *  Unicode codepoints above U+FFFF are encoded as surrogate\n\t\t *  pairs here.  This ensures that all CESU-8 codepoints are\n\t\t *  16-bit values as expected in ECMAScript.  The surrogate\n\t\t *  pairs always get a 3-byte encoding (each) in CESU-8.\n\t\t *  See: http://en.wikipedia.org/wiki/Surrogate_pair\n\t\t *\n\t\t *  20-bit codepoint, 10 bits (A and B) per surrogate pair:\n\t\t *\n\t\t *    x = 0b00000000 0000AAAA AAAAAABB BBBBBBBB\n\t\t *  sp1 = 0b110110AA AAAAAAAA  (0xd800 + ((x >> 10) & 0x3ff))\n\t\t *  sp2 = 0b110111BB BBBBBBBB  (0xdc00 + (x & 0x3ff))\n\t\t *\n\t\t *  Encoded into CESU-8:\n\t\t *\n\t\t *  sp1 -> 0b11101101  (0xe0 + ((sp1 >> 12) & 0x0f))\n\t\t *      -> 0b1010AAAA  (0x80 + ((sp1 >> 6) & 0x3f))\n\t\t *      -> 0b10AAAAAA  (0x80 + (sp1 & 0x3f))\n\t\t *  sp2 -> 0b11101101  (0xe0 + ((sp2 >> 12) & 0x0f))\n\t\t *      -> 0b1011BBBB  (0x80 + ((sp2 >> 6) & 0x3f))\n\t\t *      -> 0b10BBBBBB  (0x80 + (sp2 & 0x3f))\n\t\t *\n\t\t *  Note that 0x10000 must be subtracted first.  The code below\n\t\t *  avoids the sp1, sp2 temporaries which saves around 20 bytes\n\t\t *  of code.\n\t\t */\n\n\t\tx -= 0x10000UL;\n\n\t\tout[0] = (duk_uint8_t) (0xed);\n\t\tout[1] = (duk_uint8_t) (0xa0 + ((x >> 16) & 0x0f));\n\t\tout[2] = (duk_uint8_t) (0x80 + ((x >> 10) & 0x3f));\n\t\tout[3] = (duk_uint8_t) (0xed);\n\t\tout[4] = (duk_uint8_t) (0xb0 + ((x >> 6) & 0x0f));\n\t\tout[5] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\tlen = 6;\n\t}\n\n\treturn len;\n}\n\n/* Decode helper.  Return zero on error. */\nDUK_INTERNAL duk_small_int_t duk_unicode_decode_xutf8(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_ucodepoint_t *out_cp) {\n\tconst duk_uint8_t *p;\n\tduk_uint32_t res;\n\tduk_uint_fast8_t ch;\n\tduk_small_int_t n;\n\n\tDUK_UNREF(thr);\n\n\tp = *ptr;\n\tif (p < ptr_start || p >= ptr_end) {\n\t\tgoto fail;\n\t}\n\n\t/*\n\t *  UTF-8 decoder which accepts longer than standard byte sequences.\n\t *  This allows full 32-bit code points to be used.\n\t */\n\n\tch = (duk_uint_fast8_t) (*p++);\n\tif (ch < 0x80) {\n\t\t/* 0xxx xxxx   [7 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x7f);\n\t\tn = 0;\n\t} else if (ch < 0xc0) {\n\t\t/* 10xx xxxx -> invalid */\n\t\tgoto fail;\n\t} else if (ch < 0xe0) {\n\t\t/* 110x xxxx   10xx xxxx   [11 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x1f);\n\t\tn = 1;\n\t} else if (ch < 0xf0) {\n\t\t/* 1110 xxxx   10xx xxxx   10xx xxxx   [16 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x0f);\n\t\tn = 2;\n\t} else if (ch < 0xf8) {\n\t\t/* 1111 0xxx   10xx xxxx   10xx xxxx   10xx xxxx   [21 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x07);\n\t\tn = 3;\n\t} else if (ch < 0xfc) {\n\t\t/* 1111 10xx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [26 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x03);\n\t\tn = 4;\n\t} else if (ch < 0xfe) {\n\t\t/* 1111 110x   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [31 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x01);\n\t\tn = 5;\n\t} else if (ch < 0xff) {\n\t\t/* 1111 1110   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [36 bits] */\n\t\tres = (duk_uint32_t) (0);\n\t\tn = 6;\n\t} else {\n\t\t/* 8-byte format could be:\n\t\t * 1111 1111   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [41 bits]\n\t\t *\n\t\t * However, this format would not have a zero bit following the\n\t\t * leading one bits and would not allow 0xFF to be used as an\n\t\t * \"invalid xutf-8\" marker for internal keys.  Further, 8-byte\n\t\t * encodings (up to 41 bit code points) are not currently needed.\n\t\t */\n\t\tgoto fail;\n\t}\n\n\tDUK_ASSERT(p >= ptr_start);  /* verified at beginning */\n\tif (p + n > ptr_end) {\n\t\t/* check pointer at end */\n\t\tgoto fail;\n\t}\n\n\twhile (n > 0) {\n\t\tDUK_ASSERT(p >= ptr_start && p < ptr_end);\n\t\tch = (duk_uint_fast8_t) (*p++);\n#if 0\n\t\tif (ch & 0xc0 != 0x80) {\n\t\t\t/* not a continuation byte */\n\t\t\tp--;\n\t\t\t*ptr = p;\n\t\t\t*out_cp = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\treturn 1;\n\t\t}\n#endif\n\t\tres = (res << 6) + (duk_uint32_t) (ch & 0x3f);\n\t\tn--;\n\t}\n\n\t*ptr = p;\n\t*out_cp = res;\n\treturn 1;\n\n fail:\n\treturn 0;\n}\n\n/* used by e.g. duk_regexp_executor.c, string built-ins */\nDUK_INTERNAL duk_ucodepoint_t duk_unicode_decode_xutf8_checked(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end) {\n\tduk_ucodepoint_t cp;\n\n\tif (duk_unicode_decode_xutf8(thr, ptr, ptr_start, ptr_end, &cp)) {\n\t\treturn cp;\n\t}\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Compute (extended) utf-8 length without codepoint encoding validation,\n * used for string interning.\n *\n * NOTE: This algorithm is performance critical, more so than string hashing\n * in some cases.  It is needed when interning a string and needs to scan\n * every byte of the string with no skipping.  Having an ASCII fast path\n * is useful if possible in the algorithm.  The current algorithms were\n * chosen from several variants, based on x64 gcc -O2 testing.  See:\n * https://github.com/svaarala/duktape/pull/422\n *\n * NOTE: must match tools/dukutil.py:duk_unicode_unvalidated_utf8_length().\n */\n\n#if defined(DUK_USE_PREFER_SIZE)\n/* Small variant; roughly 150 bytes smaller than the fast variant. */\nDUK_INTERNAL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_size_t ncont;\n\tduk_size_t clen;\n\n\tp = data;\n\tp_end = data + blen;\n\tncont = 0;\n\twhile (p != p_end) {\n\t\tduk_uint8_t x;\n\t\tx = *p++;\n\t\tif (DUK_UNLIKELY(x >= 0x80 && x <= 0xbf)) {\n\t\t\tncont++;\n\t\t}\n\t}\n\n\tDUK_ASSERT(ncont <= blen);\n\tclen = blen - ncont;\n\tDUK_ASSERT(clen <= blen);\n\treturn clen;\n}\n#else  /* DUK_USE_PREFER_SIZE */\n/* This seems like a good overall approach.  Fast path for ASCII in 4 byte\n * blocks.\n */\nDUK_INTERNAL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint32_t *p32_end;\n\tconst duk_uint32_t *p32;\n\tduk_size_t ncont;\n\tduk_size_t clen;\n\n\tncont = 0;  /* number of continuation (non-initial) bytes in [0x80,0xbf] */\n\tp = data;\n\tp_end = data + blen;\n\tif (blen < 16) {\n\t\tgoto skip_fastpath;\n\t}\n\n\t/* Align 'p' to 4; the input data may have arbitrary alignment.\n\t * End of string check not needed because blen >= 16.\n\t */\n\twhile (((duk_size_t) (const void *) p) & 0x03U) {\n\t\tduk_uint8_t x;\n\t\tx = *p++;\n\t\tif (DUK_UNLIKELY(x >= 0x80 && x <= 0xbf)) {\n\t\t\tncont++;\n\t\t}\n\t}\n\n\t/* Full, aligned 4-byte reads. */\n\tp32_end = (const duk_uint32_t *) (const void *) (p + ((duk_size_t) (p_end - p) & (duk_size_t) (~0x03)));\n\tp32 = (const duk_uint32_t *) (const void *) p;\n\twhile (p32 != (const duk_uint32_t *) p32_end) {\n\t\tduk_uint32_t x;\n\t\tx = *p32++;\n\t\tif (DUK_LIKELY((x & 0x80808080UL) == 0)) {\n\t\t\t;  /* ASCII fast path */\n\t\t} else {\n\t\t\t/* Flip highest bit of each byte which changes\n\t\t\t * the bit pattern 10xxxxxx into 00xxxxxx which\n\t\t\t * allows an easy bit mask test.\n\t\t\t */\n\t\t\tx ^= 0x80808080UL;\n\t\t\tif (DUK_UNLIKELY(!(x & 0xc0000000UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(!(x & 0x00c00000UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(!(x & 0x0000c000UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(!(x & 0x000000c0UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t}\n\t}\n\tp = (const duk_uint8_t *) p32;\n\t/* Fall through to handle the rest. */\n\n skip_fastpath:\n\twhile (p != p_end) {\n\t\tduk_uint8_t x;\n\t\tx = *p++;\n\t\tif (DUK_UNLIKELY(x >= 0x80 && x <= 0xbf)) {\n\t\t\tncont++;\n\t\t}\n\t}\n\n\tDUK_ASSERT(ncont <= blen);\n\tclen = blen - ncont;\n\tDUK_ASSERT(clen <= blen);\n\treturn clen;\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/*\n *  Unicode range matcher\n *\n *  Matches a codepoint against a packed bitstream of character ranges.\n *  Used for slow path Unicode matching.\n */\n\n/* Must match tools/extract_chars.py, generate_match_table3(). */\nDUK_LOCAL duk_uint32_t duk__uni_decode_value(duk_bitdecoder_ctx *bd_ctx) {\n\tduk_uint32_t t;\n\n\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 4);\n\tif (t <= 0x0eU) {\n\t\treturn t;\n\t}\n\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 8);\n\tif (t <= 0xfdU) {\n\t\treturn t + 0x0f;\n\t}\n\tif (t == 0xfeU) {\n\t\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 12);\n\t\treturn t + 0x0fU + 0xfeU;\n\t} else {\n\t\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 24);\n\t\treturn t + 0x0fU + 0xfeU + 0x1000UL;\n\t}\n}\n\nDUK_LOCAL duk_small_int_t duk__uni_range_match(const duk_uint8_t *unitab, duk_size_t unilen, duk_codepoint_t cp) {\n\tduk_bitdecoder_ctx bd_ctx;\n\tduk_codepoint_t prev_re;\n\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tbd_ctx.data = (const duk_uint8_t *) unitab;\n\tbd_ctx.length = (duk_size_t) unilen;\n\n\tprev_re = 0;\n\tfor (;;) {\n\t\tduk_codepoint_t r1, r2;\n\t\tr1 = (duk_codepoint_t) duk__uni_decode_value(&bd_ctx);\n\t\tif (r1 == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tr2 = (duk_codepoint_t) duk__uni_decode_value(&bd_ctx);\n\n\t\tr1 = prev_re + r1;\n\t\tr2 = r1 + r2;\n\t\tprev_re = r2;\n\n\t\t/* [r1,r2] is the range */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__uni_range_match: cp=%06lx range=[0x%06lx,0x%06lx]\",\n\t\t                     (unsigned long) cp, (unsigned long) r1, (unsigned long) r2));\n\t\tif (cp >= r1 && cp <= r2) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n/*\n *  \"WhiteSpace\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_whitespace(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.2 specifies six characters specifically as\n\t *  white space:\n\t *\n\t *    0009;<control>;Cc;0;S;;;;;N;CHARACTER TABULATION;;;;\n\t *    000B;<control>;Cc;0;S;;;;;N;LINE TABULATION;;;;\n\t *    000C;<control>;Cc;0;WS;;;;;N;FORM FEED (FF);;;;\n\t *    0020;SPACE;Zs;0;WS;;;;;N;;;;;\n\t *    00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;\n\t *    FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;;\n\t *\n\t *  It also specifies any Unicode category 'Zs' characters as white\n\t *  space.  These can be extracted with the \"tools/extract_chars.py\" script.\n\t *  Current result:\n\t *\n\t *    RAW OUTPUT:\n\t *    ===========\n\t *    0020;SPACE;Zs;0;WS;;;;;N;;;;;\n\t *    00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;\n\t *    1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;;\n\t *    180E;MONGOLIAN VOWEL SEPARATOR;Zs;0;WS;;;;;N;;;;;\n\t *    2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;;\n\t *    2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;;\n\t *    2002;EN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2003;EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2004;THREE-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2005;FOUR-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2006;SIX-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2007;FIGURE SPACE;Zs;0;WS;<noBreak> 0020;;;;N;;;;;\n\t *    2008;PUNCTUATION SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2009;THIN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    200A;HAIR SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    202F;NARROW NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;;;;;\n\t *    205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    3000;IDEOGRAPHIC SPACE;Zs;0;WS;<wide> 0020;;;;N;;;;;\n\t *\n\t *    RANGES:\n\t *    =======\n\t *    0x0020\n\t *    0x00a0\n\t *    0x1680\n\t *    0x180e\n\t *    0x2000 ... 0x200a\n\t *    0x202f\n\t *    0x205f\n\t *    0x3000\n\t *\n\t *  A manual decoder (below) is probably most compact for this.\n\t */\n\n\tduk_uint_fast8_t lo;\n\tduk_uint_fast32_t hi;\n\n\t/* cp == -1 (EOF) never matches and causes return value 0 */\n\n\tlo = (duk_uint_fast8_t) (cp & 0xff);\n\thi = (duk_uint_fast32_t) (cp >> 8);  /* does not fit into an uchar */\n\n\tif (hi == 0x0000UL) {\n\t\tif (lo == 0x09U || lo == 0x0bU || lo == 0x0cU ||\n\t\t    lo == 0x20U || lo == 0xa0U) {\n\t\t\treturn 1;\n\t\t}\n\t} else if (hi == 0x0020UL) {\n\t\tif (lo <= 0x0aU || lo == 0x2fU || lo == 0x5fU) {\n\t\t\treturn 1;\n\t\t}\n\t} else if (cp == 0x1680L || cp == 0x180eL || cp == 0x3000L ||\n\t           cp == 0xfeffL) {\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n/*\n *  \"LineTerminator\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_line_terminator(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.3\n\t *\n\t *  A LineTerminatorSequence essentially merges <CR> <LF> sequences\n\t *  into a single line terminator.  This must be handled by the caller.\n\t */\n\n\tif (cp == 0x000aL || cp == 0x000dL || cp == 0x2028L ||\n\t    cp == 0x2029L) {\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n/*\n *  \"IdentifierStart\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_identifier_start(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.6:\n\t *\n\t *    IdentifierStart:\n\t *      UnicodeLetter\n\t *      $\n\t *      _\n\t *      \\ UnicodeEscapeSequence\n\t *\n\t *  IdentifierStart production has one multi-character production:\n\t *\n\t *    \\ UnicodeEscapeSequence\n\t *\n\t *  The '\\' character is -not- matched by this function.  Rather, the caller\n\t *  should decode the escape and then call this function to check whether the\n\t *  decoded character is acceptable (see discussion in E5 Section 7.6).\n\t *\n\t *  The \"UnicodeLetter\" alternative of the production allows letters\n\t *  from various Unicode categories.  These can be extracted with the\n\t *  \"tools/extract_chars.py\" script.\n\t *\n\t *  Because the result has hundreds of Unicode codepoint ranges, matching\n\t *  for any values >= 0x80 are done using a very slow range-by-range scan\n\t *  and a packed range format.\n\t *\n\t *  The ASCII portion (codepoints 0x00 ... 0x7f) is fast-pathed below because\n\t *  it matters the most.  The ASCII related ranges of IdentifierStart are:\n\t *\n\t *    0x0041 ... 0x005a     ['A' ... 'Z']\n\t *    0x0061 ... 0x007a     ['a' ... 'z']\n\t *    0x0024                ['$']\n\t *    0x005f                ['_']\n\t */\n\n\t/* ASCII (and EOF) fast path -- quick accept and reject */\n\tif (cp <= 0x7fL) {\n#if defined(DUK_USE_IDCHAR_FASTPATH)\n\t\treturn (cp >= 0) && (duk_is_idchar_tab[cp] > 0);\n#else\n\t\tif ((cp >= 'a' && cp <= 'z') ||\n\t\t    (cp >= 'A' && cp <= 'Z') ||\n\t\t    cp == '_' || cp == '$') {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n#endif\n\t}\n\n\t/* Non-ASCII slow path (range-by-range linear comparison), very slow */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n\tif (duk__uni_range_match(duk_unicode_ids_noa,\n\t                         (duk_size_t) sizeof(duk_unicode_ids_noa),\n\t                         (duk_codepoint_t) cp)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else\n\tif (cp < 0x10000L) {\n\t\tif (duk__uni_range_match(duk_unicode_ids_noabmp,\n\t\t                         sizeof(duk_unicode_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp)) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t} else {\n\t\t/* without explicit non-BMP support, assume non-BMP characters\n\t\t * are always accepted as identifier characters.\n\t\t */\n\t\treturn 1;\n\t}\n#endif\n}\n\n/*\n *  \"IdentifierPart\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_identifier_part(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.6:\n\t *\n\t *    IdentifierPart:\n\t *      IdentifierStart\n\t *      UnicodeCombiningMark\n\t *      UnicodeDigit\n\t *      UnicodeConnectorPunctuation\n\t *      <ZWNJ>  [U+200C]\n\t *      <ZWJ>   [U+200D]\n\t *\n\t *  IdentifierPart production has one multi-character production\n\t *  as part of its IdentifierStart alternative.  The '\\' character\n\t *  of an escape sequence is not matched here, see discussion in\n\t *  duk_unicode_is_identifier_start().\n\t *\n\t *  To match non-ASCII characters (codepoints >= 0x80), a very slow\n\t *  linear range-by-range scan is used.  The codepoint is first compared\n\t *  to the IdentifierStart ranges, and if it doesn't match, then to a\n\t *  set consisting of code points in IdentifierPart but not in\n\t *  IdentifierStart.  This is done to keep the unicode range data small,\n\t *  at the expense of speed.\n\t *\n\t *  The ASCII fast path consists of:\n\t *\n\t *    0x0030 ... 0x0039     ['0' ... '9', UnicodeDigit]\n\t *    0x0041 ... 0x005a     ['A' ... 'Z', IdentifierStart]\n\t *    0x0061 ... 0x007a     ['a' ... 'z', IdentifierStart]\n\t *    0x0024                ['$', IdentifierStart]\n\t *    0x005f                ['_', IdentifierStart and\n\t *                                UnicodeConnectorPunctuation]\n\t *\n\t *  UnicodeCombiningMark has no code points <= 0x7f.\n\t *\n\t *  The matching code reuses the \"identifier start\" tables, and then\n\t *  consults a separate range set for characters in \"identifier part\"\n\t *  but not in \"identifier start\".  These can be extracted with the\n\t *  \"tools/extract_chars.py\" script.\n\t *\n\t *  UnicodeCombiningMark -> categories Mn, Mc\n\t *  UnicodeDigit -> categories Nd\n\t *  UnicodeConnectorPunctuation -> categories Pc\n\t */\n\n\t/* ASCII (and EOF) fast path -- quick accept and reject */\n\tif (cp <= 0x7fL) {\n#if defined(DUK_USE_IDCHAR_FASTPATH)\n\t\treturn (cp >= 0) && (duk_is_idchar_tab[cp] != 0);\n#else\n\t\tif ((cp >= 'a' && cp <= 'z') ||\n\t\t    (cp >= 'A' && cp <= 'Z') ||\n\t\t    (cp >= '0' && cp <= '9') ||\n\t\t    cp == '_' || cp == '$') {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n#endif\n\t}\n\n\t/* Non-ASCII slow path (range-by-range linear comparison), very slow */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n\tif (duk__uni_range_match(duk_unicode_ids_noa,\n\t                         sizeof(duk_unicode_ids_noa),\n\t                         (duk_codepoint_t) cp) ||\n\t    duk__uni_range_match(duk_unicode_idp_m_ids_noa,\n\t                         sizeof(duk_unicode_idp_m_ids_noa),\n\t                         (duk_codepoint_t) cp)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else\n\tif (cp < 0x10000L) {\n\t\tif (duk__uni_range_match(duk_unicode_ids_noabmp,\n\t\t                         sizeof(duk_unicode_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp) ||\n\t\t    duk__uni_range_match(duk_unicode_idp_m_ids_noabmp,\n\t\t                         sizeof(duk_unicode_idp_m_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp)) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t} else {\n\t\t/* without explicit non-BMP support, assume non-BMP characters\n\t\t * are always accepted as identifier characters.\n\t\t */\n\t\treturn 1;\n\t}\n#endif\n}\n\n/*\n *  Unicode letter check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_letter(duk_codepoint_t cp) {\n\t/*\n\t *  Unicode letter is now taken to be the categories:\n\t *\n\t *    Lu, Ll, Lt, Lm, Lo\n\t *\n\t *  (Not sure if this is exactly correct.)\n\t *\n\t *  The ASCII fast path consists of:\n\t *\n\t *    0x0041 ... 0x005a     ['A' ... 'Z']\n\t *    0x0061 ... 0x007a     ['a' ... 'z']\n\t */\n\n\t/* ASCII (and EOF) fast path -- quick accept and reject */\n\tif (cp <= 0x7fL) {\n\t\tif ((cp >= 'a' && cp <= 'z') ||\n\t\t    (cp >= 'A' && cp <= 'Z')) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t}\n\n\t/* Non-ASCII slow path (range-by-range linear comparison), very slow */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n\tif (duk__uni_range_match(duk_unicode_ids_noa,\n\t                         sizeof(duk_unicode_ids_noa),\n\t                         (duk_codepoint_t) cp) &&\n\t    !duk__uni_range_match(duk_unicode_ids_m_let_noa,\n\t                          sizeof(duk_unicode_ids_m_let_noa),\n\t                          (duk_codepoint_t) cp)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else\n\tif (cp < 0x10000L) {\n\t\tif (duk__uni_range_match(duk_unicode_ids_noabmp,\n\t\t                         sizeof(duk_unicode_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp) &&\n\t\t    !duk__uni_range_match(duk_unicode_ids_m_let_noabmp,\n\t\t                          sizeof(duk_unicode_ids_m_let_noabmp),\n\t\t                          (duk_codepoint_t) cp)) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t} else {\n\t\t/* without explicit non-BMP support, assume non-BMP characters\n\t\t * are always accepted as letters.\n\t\t */\n\t\treturn 1;\n\t}\n#endif\n}\n\n/*\n *  Complex case conversion helper which decodes a bit-packed conversion\n *  control stream generated by tools/extract_caseconv.py.  The conversion\n *  is very slow because it runs through the conversion data in a linear\n *  fashion to save space (which is why ASCII characters have a special\n *  fast path before arriving here).\n *\n *  The particular bit counts etc have been determined experimentally to\n *  be small but still sufficient, and must match the Python script\n *  (tools/extract_caseconv.py).\n *\n *  The return value is the case converted codepoint or -1 if the conversion\n *  results in multiple characters (this is useful for regexp Canonicalization\n *  operation).  If 'buf' is not NULL, the result codepoint(s) are also\n *  appended to the hbuffer.\n *\n *  Context and locale specific rules must be checked before consulting\n *  this function.\n */\n\nDUK_LOCAL\nduk_codepoint_t duk__slow_case_conversion(duk_hthread *thr,\n                                          duk_bufwriter_ctx *bw,\n                                          duk_codepoint_t cp,\n                                          duk_bitdecoder_ctx *bd_ctx) {\n\tduk_small_int_t skip = 0;\n\tduk_small_int_t n;\n\tduk_small_int_t t;\n\tduk_small_int_t count;\n\tduk_codepoint_t tmp_cp;\n\tduk_codepoint_t start_i;\n\tduk_codepoint_t start_o;\n\n\tDUK_ASSERT(bd_ctx != NULL);\n\tDUK_UNREF(thr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"slow case conversion for codepoint: %ld\", (long) cp));\n\n\t/* range conversion with a \"skip\" */\n\tDUK_DDD(DUK_DDDPRINT(\"checking ranges\"));\n\tfor (;;) {\n\t\tskip++;\n\t\tn = (duk_small_int_t) duk_bd_decode(bd_ctx, 6);\n\t\tif (n == 0x3f) {\n\t\t\t/* end marker */\n\t\t\tbreak;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"skip=%ld, n=%ld\", (long) skip, (long) n));\n\n\t\twhile (n--) {\n\t\t\tstart_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\t\tstart_o = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\t\tcount = (duk_small_int_t) duk_bd_decode(bd_ctx, 7);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"range: start_i=%ld, start_o=%ld, count=%ld, skip=%ld\",\n\t\t\t                     (long) start_i, (long) start_o, (long) count, (long) skip));\n\n\t\t\tif (cp >= start_i) {\n\t\t\t\ttmp_cp = cp - start_i;  /* always >= 0 */\n\t\t\t\tif (tmp_cp < (duk_codepoint_t) count * (duk_codepoint_t) skip &&\n\t\t\t\t    (tmp_cp % (duk_codepoint_t) skip) == 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"range matches input codepoint\"));\n\t\t\t\t\tcp = start_o + tmp_cp;\n\t\t\t\t\tgoto single;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/* 1:1 conversion */\n\tn = (duk_small_int_t) duk_bd_decode(bd_ctx, 7);\n\tDUK_DDD(DUK_DDDPRINT(\"checking 1:1 conversions (count %ld)\", (long) n));\n\twhile (n--) {\n\t\tstart_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\tstart_o = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\tDUK_DDD(DUK_DDDPRINT(\"1:1 conversion %ld -> %ld\", (long) start_i, (long) start_o));\n\t\tif (cp == start_i) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"1:1 matches input codepoint\"));\n\t\t\tcp = start_o;\n\t\t\tgoto single;\n\t\t}\n\t}\n\n\t/* complex, multicharacter conversion */\n\tn = (duk_small_int_t) duk_bd_decode(bd_ctx, 7);\n\tDUK_DDD(DUK_DDDPRINT(\"checking 1:n conversions (count %ld)\", (long) n));\n\twhile (n--) {\n\t\tstart_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\tt = (duk_small_int_t) duk_bd_decode(bd_ctx, 2);\n\t\tDUK_DDD(DUK_DDDPRINT(\"1:n conversion %ld -> %ld chars\", (long) start_i, (long) t));\n\t\tif (cp == start_i) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"1:n matches input codepoint\"));\n\t\t\tif (bw != NULL) {\n\t\t\t\twhile (t--) {\n\t\t\t\t\ttmp_cp = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\t\t\t\tDUK_BW_WRITE_RAW_XUTF8(thr, bw, (duk_ucodepoint_t) tmp_cp);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t} else {\n\t\t\twhile (t--) {\n\t\t\t\t(void) duk_bd_decode(bd_ctx, 16);\n\t\t\t}\n\t\t}\n\t}\n\n\t/* default: no change */\n\tDUK_DDD(DUK_DDDPRINT(\"no rule matches, output is same as input\"));\n\t/* fall through */\n\n single:\n\tif (bw != NULL) {\n\t\tDUK_BW_WRITE_RAW_XUTF8(thr, bw, (duk_ucodepoint_t) cp);\n\t}\n\treturn cp;\n}\n\n/*\n *  Case conversion helper, with context/local sensitivity.\n *  For proper case conversion, one needs to know the character\n *  and the preceding and following characters, as well as\n *  locale/language.\n */\n\n/* XXX: add 'language' argument when locale/language sensitive rule\n * support added.\n */\nDUK_LOCAL\nduk_codepoint_t duk__case_transform_helper(duk_hthread *thr,\n                                           duk_bufwriter_ctx *bw,\n                                           duk_codepoint_t cp,\n                                           duk_codepoint_t prev,\n                                           duk_codepoint_t next,\n                                           duk_bool_t uppercase) {\n\tduk_bitdecoder_ctx bd_ctx;\n\n\t/* fast path for ASCII */\n\tif (cp < 0x80L) {\n\t\t/* XXX: there are language sensitive rules for the ASCII range.\n\t\t * If/when language/locale support is implemented, they need to\n\t\t * be implemented here for the fast path.  There are no context\n\t\t * sensitive rules for ASCII range.\n\t\t */\n\n\t\tif (uppercase) {\n\t\t\tif (cp >= 'a' && cp <= 'z') {\n\t\t\t\tcp = cp - 'a' + 'A';\n\t\t\t}\n\t\t} else {\n\t\t\tif (cp >= 'A' && cp <= 'Z') {\n\t\t\t\tcp = cp - 'A' + 'a';\n\t\t\t}\n\t\t}\n\n\t\tif (bw != NULL) {\n\t\t\tDUK_BW_WRITE_RAW_U8(thr, bw, (duk_uint8_t) cp);\n\t\t}\n\t\treturn cp;\n\t}\n\n\t/* context and locale specific rules which cannot currently be represented\n\t * in the caseconv bitstream: hardcoded rules in C\n\t */\n\tif (uppercase) {\n\t\t/* XXX: turkish / azeri */\n\t} else {\n\t\t/*\n\t\t *  Final sigma context specific rule.  This is a rather tricky\n\t\t *  rule and this handling is probably not 100% correct now.\n\t\t *  The rule is not locale/language specific so it is supported.\n\t\t */\n\n\t\tif (cp == 0x03a3L &&    /* U+03A3 = GREEK CAPITAL LETTER SIGMA */\n\t\t    duk_unicode_is_letter(prev) &&        /* prev exists and is not a letter */\n\t\t    !duk_unicode_is_letter(next)) {       /* next does not exist or next is not a letter */\n\t\t\t/* Capital sigma occurred at \"end of word\", lowercase to\n\t\t\t * U+03C2 = GREEK SMALL LETTER FINAL SIGMA.  Otherwise\n\t\t\t * fall through and let the normal rules lowercase it to\n\t\t\t * U+03C3 = GREEK SMALL LETTER SIGMA.\n\t\t\t */\n\t\t\tcp = 0x03c2L;\n\t\t\tgoto singlechar;\n\t\t}\n\n\t\t/* XXX: lithuanian not implemented */\n\t\t/* XXX: lithuanian, explicit dot rules */\n\t\t/* XXX: turkish / azeri, lowercase rules */\n\t}\n\n\t/* 1:1 or special conversions, but not locale/context specific: script generated rules */\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tif (uppercase) {\n\t\tbd_ctx.data = (const duk_uint8_t *) duk_unicode_caseconv_uc;\n\t\tbd_ctx.length = (duk_size_t) sizeof(duk_unicode_caseconv_uc);\n\t} else {\n\t\tbd_ctx.data = (const duk_uint8_t *) duk_unicode_caseconv_lc;\n\t\tbd_ctx.length = (duk_size_t) sizeof(duk_unicode_caseconv_lc);\n\t}\n\treturn duk__slow_case_conversion(thr, bw, cp, &bd_ctx);\n\n singlechar:\n\tif (bw != NULL) {\n\t\tDUK_BW_WRITE_RAW_XUTF8(thr, bw, (duk_ucodepoint_t) cp);\n\t}\n\treturn cp;\n\n /* unused now, not needed until Turkish/Azeri */\n#if 0\n nochar:\n\treturn -1;\n#endif\n}\n\n/*\n *  Replace valstack top with case converted version.\n */\n\nDUK_INTERNAL void duk_unicode_case_convert_string(duk_hthread *thr, duk_bool_t uppercase) {\n\tduk_hstring *h_input;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_codepoint_t prev, curr, next;\n\n\th_input = duk_require_hstring(thr, -1);  /* Accept symbols. */\n\tDUK_ASSERT(h_input != NULL);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input));\n\n\t/* [ ... input buffer ] */\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\n\tprev = -1; DUK_UNREF(prev);\n\tcurr = -1;\n\tnext = -1;\n\tfor (;;) {\n\t\tprev = curr;\n\t\tcurr = next;\n\t\tnext = -1;\n\t\tif (p < p_end) {\n\t\t\tnext = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end);\n\t\t} else {\n\t\t\t/* end of input and last char has been processed */\n\t\t\tif (curr < 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* on first round, skip */\n\t\tif (curr >= 0) {\n\t\t\t/* XXX: could add a fast path to process chunks of input codepoints,\n\t\t\t * but relative benefit would be quite small.\n\t\t\t */\n\n\t\t\t/* Ensure space for maximum multi-character result; estimate is overkill. */\n\t\t\tDUK_BW_ENSURE(thr, bw, 8 * DUK_UNICODE_MAX_XUTF8_LENGTH);\n\n\t\t\tduk__case_transform_helper(thr,\n\t\t\t                           bw,\n\t\t\t                           (duk_codepoint_t) curr,\n\t\t\t                           prev,\n\t\t\t                           next,\n\t\t\t                           uppercase);\n\t\t}\n\t}\n\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe, output is encoded. */\n\t/* invalidates h_buf pointer */\n\tduk_remove_m2(thr);\n}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Canonicalize() abstract operation needed for canonicalization of individual\n *  codepoints during regexp compilation and execution, see E5 Section 15.10.2.8.\n *  Note that codepoints are canonicalized one character at a time, so no context\n *  specific rules can apply.  Locale specific rules can apply, though.\n */\n\nDUK_INTERNAL duk_codepoint_t duk_unicode_re_canonicalize_char(duk_hthread *thr, duk_codepoint_t cp) {\n#if defined(DUK_USE_REGEXP_CANON_WORKAROUND)\n\t/* Fast canonicalization lookup at the cost of 128kB footprint. */\n\tDUK_ASSERT(cp >= 0);\n\tDUK_UNREF(thr);\n\tif (DUK_LIKELY(cp < 0x10000L)) {\n\t\treturn (duk_codepoint_t) duk_unicode_re_canon_lookup[cp];\n\t}\n\treturn cp;\n#else  /* DUK_USE_REGEXP_CANON_WORKAROUND */\n\tduk_codepoint_t y;\n\n\ty = duk__case_transform_helper(thr,\n\t                               NULL,    /* NULL is allowed, no output */\n\t                               cp,      /* curr char */\n\t                               -1,      /* prev char */\n\t                               -1,      /* next char */\n\t                               1);      /* uppercase */\n\n\tif ((y < 0) || (cp >= 0x80 && y < 0x80)) {\n\t\t/* multiple codepoint conversion or non-ASCII mapped to ASCII\n\t\t * --> leave as is.\n\t\t */\n\t\treturn cp;\n\t}\n\n\treturn y;\n#endif  /* DUK_USE_REGEXP_CANON_WORKAROUND */\n}\n\n/*\n *  E5 Section 15.10.2.6 \"IsWordChar\" abstract operation.  Assume\n *  x < 0 for characters read outside the string.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_re_is_wordchar(duk_codepoint_t x) {\n\t/*\n\t *  Note: the description in E5 Section 15.10.2.6 has a typo, it\n\t *  contains 'A' twice and lacks 'a'; the intent is [0-9a-zA-Z_].\n\t */\n\tif ((x >= '0' && x <= '9') ||\n\t    (x >= 'a' && x <= 'z') ||\n\t    (x >= 'A' && x <= 'Z') ||\n\t    (x == '_')) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\n/*\n *  Regexp range tables\n */\n\n/* exposed because lexer needs these too */\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_digit[2] = {\n\t(duk_uint16_t) 0x0030UL, (duk_uint16_t) 0x0039UL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_white[22] = {\n\t(duk_uint16_t) 0x0009UL, (duk_uint16_t) 0x000DUL,\n\t(duk_uint16_t) 0x0020UL, (duk_uint16_t) 0x0020UL,\n\t(duk_uint16_t) 0x00A0UL, (duk_uint16_t) 0x00A0UL,\n\t(duk_uint16_t) 0x1680UL, (duk_uint16_t) 0x1680UL,\n\t(duk_uint16_t) 0x180EUL, (duk_uint16_t) 0x180EUL,\n\t(duk_uint16_t) 0x2000UL, (duk_uint16_t) 0x200AUL,\n\t(duk_uint16_t) 0x2028UL, (duk_uint16_t) 0x2029UL,\n\t(duk_uint16_t) 0x202FUL, (duk_uint16_t) 0x202FUL,\n\t(duk_uint16_t) 0x205FUL, (duk_uint16_t) 0x205FUL,\n\t(duk_uint16_t) 0x3000UL, (duk_uint16_t) 0x3000UL,\n\t(duk_uint16_t) 0xFEFFUL, (duk_uint16_t) 0xFEFFUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_wordchar[8] = {\n\t(duk_uint16_t) 0x0030UL, (duk_uint16_t) 0x0039UL,\n\t(duk_uint16_t) 0x0041UL, (duk_uint16_t) 0x005AUL,\n\t(duk_uint16_t) 0x005FUL, (duk_uint16_t) 0x005FUL,\n\t(duk_uint16_t) 0x0061UL, (duk_uint16_t) 0x007AUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_digit[4] = {\n\t(duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x002FUL,\n\t(duk_uint16_t) 0x003AUL, (duk_uint16_t) 0xFFFFUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_white[24] = {\n\t(duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x0008UL,\n\t(duk_uint16_t) 0x000EUL, (duk_uint16_t) 0x001FUL,\n\t(duk_uint16_t) 0x0021UL, (duk_uint16_t) 0x009FUL,\n\t(duk_uint16_t) 0x00A1UL, (duk_uint16_t) 0x167FUL,\n\t(duk_uint16_t) 0x1681UL, (duk_uint16_t) 0x180DUL,\n\t(duk_uint16_t) 0x180FUL, (duk_uint16_t) 0x1FFFUL,\n\t(duk_uint16_t) 0x200BUL, (duk_uint16_t) 0x2027UL,\n\t(duk_uint16_t) 0x202AUL, (duk_uint16_t) 0x202EUL,\n\t(duk_uint16_t) 0x2030UL, (duk_uint16_t) 0x205EUL,\n\t(duk_uint16_t) 0x2060UL, (duk_uint16_t) 0x2FFFUL,\n\t(duk_uint16_t) 0x3001UL, (duk_uint16_t) 0xFEFEUL,\n\t(duk_uint16_t) 0xFF00UL, (duk_uint16_t) 0xFFFFUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_wordchar[10] = {\n\t(duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x002FUL,\n\t(duk_uint16_t) 0x003AUL, (duk_uint16_t) 0x0040UL,\n\t(duk_uint16_t) 0x005BUL, (duk_uint16_t) 0x005EUL,\n\t(duk_uint16_t) 0x0060UL, (duk_uint16_t) 0x0060UL,\n\t(duk_uint16_t) 0x007BUL, (duk_uint16_t) 0xFFFFUL,\n};\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_unicode_tables.c",
    "content": "/*\n *  Unicode support tables automatically generated during build.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Unicode tables containing ranges of Unicode characters in a\n *  packed format.  These tables are used to match non-ASCII\n *  characters of complex productions by resorting to a linear\n *  range-by-range comparison.  This is very slow, but is expected\n *  to be very rare in practical ECMAScript source code, and thus\n *  compactness is most important.\n *\n *  The tables are matched using uni_range_match() and the format\n *  is described in tools/extract_chars.py.\n */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/* IdentifierStart production with ASCII excluded */\n/* duk_unicode_ids_noa[] */\n#include \"duk_unicode_ids_noa.c\"\n#else\n/* IdentifierStart production with ASCII and non-BMP excluded */\n/* duk_unicode_ids_noabmp[] */\n#include \"duk_unicode_ids_noabmp.c\"\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/* IdentifierStart production with Letter and ASCII excluded */\n/* duk_unicode_ids_m_let_noa[] */\n#include \"duk_unicode_ids_m_let_noa.c\"\n#else\n/* IdentifierStart production with Letter, ASCII, and non-BMP excluded */\n/* duk_unicode_ids_m_let_noabmp[] */\n#include \"duk_unicode_ids_m_let_noabmp.c\"\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/* IdentifierPart production with IdentifierStart and ASCII excluded */\n/* duk_unicode_idp_m_ids_noa[] */\n#include \"duk_unicode_idp_m_ids_noa.c\"\n#else\n/* IdentifierPart production with IdentifierStart, ASCII, and non-BMP excluded */\n/* duk_unicode_idp_m_ids_noabmp[] */\n#include \"duk_unicode_idp_m_ids_noabmp.c\"\n#endif\n\n/*\n *  Case conversion tables generated using tools/extract_caseconv.py.\n */\n\n/* duk_unicode_caseconv_uc[] */\n/* duk_unicode_caseconv_lc[] */\n\n#include \"duk_unicode_caseconv.c\"\n\n#if defined(DUK_USE_REGEXP_CANON_WORKAROUND)\n#include \"duk_unicode_re_canon_lookup.c\"\n#endif\n\n#if defined(DUK_USE_REGEXP_CANON_BITMAP)\n#include \"duk_unicode_re_canon_bitmap.c\"\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_util.h",
    "content": "/*\n *  Utilities\n */\n\n#if !defined(DUK_UTIL_H_INCLUDED)\n#define DUK_UTIL_H_INCLUDED\n\n#if defined(DUK_USE_GET_RANDOM_DOUBLE)\n#define DUK_UTIL_GET_RANDOM_DOUBLE(thr) DUK_USE_GET_RANDOM_DOUBLE((thr)->heap_udata)\n#else\n#define DUK_UTIL_GET_RANDOM_DOUBLE(thr) duk_util_tinyrandom_get_double(thr)\n#endif\n\n/*\n *  Some useful constants\n */\n\n#define DUK_DOUBLE_2TO32     4294967296.0\n#define DUK_DOUBLE_2TO31     2147483648.0\n#define DUK_DOUBLE_LOG2E     1.4426950408889634\n#define DUK_DOUBLE_LOG10E    0.4342944819032518\n\n/*\n *  Endian conversion\n */\n\n#if defined(DUK_USE_INTEGER_LE)\n#define DUK_HTON32(x) DUK_BSWAP32((x))\n#define DUK_NTOH32(x) DUK_BSWAP32((x))\n#define DUK_HTON16(x) DUK_BSWAP16((x))\n#define DUK_NTOH16(x) DUK_BSWAP16((x))\n#elif defined(DUK_USE_INTEGER_BE)\n#define DUK_HTON32(x) (x)\n#define DUK_NTOH32(x) (x)\n#define DUK_HTON16(x) (x)\n#define DUK_NTOH16(x) (x)\n#else\n#error internal error, endianness defines broken\n#endif\n\n/*\n *  Bitstream decoder\n */\n\nstruct duk_bitdecoder_ctx {\n\tconst duk_uint8_t *data;\n\tduk_size_t offset;\n\tduk_size_t length;\n\tduk_uint32_t currval;\n\tduk_small_int_t currbits;\n};\n\n#define DUK_BD_BITPACKED_STRING_MAXLEN 256\n\n/*\n *  Bitstream encoder\n */\n\nstruct duk_bitencoder_ctx {\n\tduk_uint8_t *data;\n\tduk_size_t offset;\n\tduk_size_t length;\n\tduk_uint32_t currval;\n\tduk_small_int_t currbits;\n\tduk_small_int_t truncated;\n};\n\n/*\n *  Raw write/read macros for big endian, unaligned basic values.\n *  Caller ensures there's enough space.  The macros update the pointer\n *  argument automatically on resizes.  The idiom seems a bit odd, but\n *  leads to compact code.\n */\n\n#define DUK_RAW_WRITE_U8(ptr,val)  do { \\\n\t\t*(ptr)++ = (duk_uint8_t) (val); \\\n\t} while (0)\n#define DUK_RAW_WRITE_U16_BE(ptr,val) duk_raw_write_u16_be(&(ptr), (duk_uint16_t) (val))\n#define DUK_RAW_WRITE_U32_BE(ptr,val) duk_raw_write_u32_be(&(ptr), (duk_uint32_t) (val))\n#define DUK_RAW_WRITE_DOUBLE_BE(ptr,val) duk_raw_write_double_be(&(ptr), (duk_double_t) (val))\n#define DUK_RAW_WRITE_XUTF8(ptr,val)  do { \\\n\t\t/* 'ptr' is evaluated both as LHS and RHS. */ \\\n\t\tduk_uint8_t *duk__ptr; \\\n\t\tduk_small_int_t duk__len; \\\n\t\tduk__ptr = (duk_uint8_t *) (ptr); \\\n\t\tduk__len = duk_unicode_encode_xutf8((duk_ucodepoint_t) (val), duk__ptr); \\\n\t\tduk__ptr += duk__len; \\\n\t\t(ptr) = duk__ptr; \\\n\t} while (0)\n#define DUK_RAW_WRITE_CESU8(ptr,val)  do { \\\n\t\t/* 'ptr' is evaluated both as LHS and RHS. */ \\\n\t\tduk_uint8_t *duk__ptr; \\\n\t\tduk_small_int_t duk__len; \\\n\t\tduk__ptr = (duk_uint8_t *) (ptr); \\\n\t\tduk__len = duk_unicode_encode_cesu8((duk_ucodepoint_t) (val), duk__ptr); \\\n\t\tduk__ptr += duk__len; \\\n\t\t(ptr) = duk__ptr; \\\n\t} while (0)\n\n#define DUK_RAW_READ_U8(ptr) ((duk_uint8_t) (*(ptr)++))\n#define DUK_RAW_READ_U16_BE(ptr) duk_raw_read_u16_be(&(ptr));\n#define DUK_RAW_READ_U32_BE(ptr) duk_raw_read_u32_be(&(ptr));\n#define DUK_RAW_READ_DOUBLE_BE(ptr) duk_raw_read_double_be(&(ptr));\n\n/*\n *  Buffer writer (dynamic buffer only)\n *\n *  Helper for writing to a dynamic buffer with a concept of a \"slack\" area\n *  to reduce resizes.  You can ensure there is enough space beforehand and\n *  then write for a while without further checks, relying on a stable data\n *  pointer.  Slack handling is automatic so call sites only indicate how\n *  much data they need right now.\n *\n *  There are several ways to write using bufwriter.  The best approach\n *  depends mainly on how much performance matters over code footprint.\n *  The key issues are (1) ensuring there is space and (2) keeping the\n *  pointers consistent.  Fast code should ensure space for multiple writes\n *  with one ensure call.  Fastest inner loop code can temporarily borrow\n *  the 'p' pointer but must write it back eventually.\n *\n *  Be careful to ensure all macro arguments (other than static pointers like\n *  'thr' and 'bw_ctx') are evaluated exactly once, using temporaries if\n *  necessary (if that's not possible, there should be a note near the macro).\n *  Buffer write arguments often contain arithmetic etc so this is\n *  particularly important here.\n */\n\n/* XXX: Migrate bufwriter and other read/write helpers to its own header? */\n\nstruct duk_bufwriter_ctx {\n\tduk_uint8_t *p;\n\tduk_uint8_t *p_base;\n\tduk_uint8_t *p_limit;\n\tduk_hbuffer_dynamic *buf;\n};\n\n#if defined(DUK_USE_PREFER_SIZE)\n#define DUK_BW_SLACK_ADD           64\n#define DUK_BW_SLACK_SHIFT         4    /* 2^4 -> 1/16 = 6.25% slack */\n#else\n#define DUK_BW_SLACK_ADD           64\n#define DUK_BW_SLACK_SHIFT         2    /* 2^2 -> 1/4 = 25% slack */\n#endif\n\n/* Initialization and finalization (compaction), converting to other types. */\n\n#define DUK_BW_INIT_PUSHBUF(thr,bw_ctx,sz) do { \\\n\t\tduk_bw_init_pushbuf((thr), (bw_ctx), (sz)); \\\n\t} while (0)\n#define DUK_BW_INIT_WITHBUF(thr,bw_ctx,buf) do { \\\n\t\tduk_bw_init((thr), (bw_ctx), (buf)); \\\n\t} while (0)\n#define DUK_BW_COMPACT(thr,bw_ctx) do { \\\n\t\t/* Make underlying buffer compact to match DUK_BW_GET_SIZE(). */ \\\n\t\tduk_bw_compact((thr), (bw_ctx)); \\\n\t} while (0)\n#define DUK_BW_PUSH_AS_STRING(thr,bw_ctx) do { \\\n\t\tduk_push_lstring((thr), \\\n\t\t                 (const char *) (bw_ctx)->p_base, \\\n\t\t                 (duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base)); \\\n\t} while (0)\n\n/* Pointers may be NULL for a while when 'buf' size is zero and before any\n * ENSURE calls have been made.  Once an ENSURE has been made, the pointers\n * are required to be non-NULL so that it's always valid to use memcpy() and\n * memmove(), even for zero size.\n */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_bw_assert_valid(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx);\n#define DUK_BW_ASSERT_VALID_EXPR(thr,bw_ctx)  (duk_bw_assert_valid((thr), (bw_ctx)))\n#define DUK_BW_ASSERT_VALID(thr,bw_ctx)  do { duk_bw_assert_valid((thr), (bw_ctx)); } while (0)\n#else\n#define DUK_BW_ASSERT_VALID_EXPR(thr,bw_ctx)  DUK_ASSERT_EXPR(1)\n#define DUK_BW_ASSERT_VALID(thr,bw_ctx)  do {} while (0)\n#endif\n\n/* Working with the pointer and current size. */\n\n#define DUK_BW_GET_PTR(thr,bw_ctx) \\\n\t((bw_ctx)->p)\n#define DUK_BW_SET_PTR(thr,bw_ctx,ptr) do { \\\n\t\t(bw_ctx)->p = (ptr); \\\n\t} while (0)\n#define DUK_BW_ADD_PTR(thr,bw_ctx,delta) do { \\\n\t\t(bw_ctx)->p += (delta); \\\n\t} while (0)\n#define DUK_BW_GET_BASEPTR(thr,bw_ctx) \\\n\t((bw_ctx)->p_base)\n#define DUK_BW_GET_LIMITPTR(thr,bw_ctx) \\\n\t((bw_ctx)->p_limit)\n#define DUK_BW_GET_SIZE(thr,bw_ctx) \\\n\t((duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base))\n#define DUK_BW_SET_SIZE(thr,bw_ctx,sz) do { \\\n\t\tDUK_ASSERT((duk_size_t) (sz) <= (duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base)); \\\n\t\t(bw_ctx)->p = (bw_ctx)->p_base + (sz); \\\n\t} while (0)\n#define DUK_BW_RESET_SIZE(thr,bw_ctx) do { \\\n\t\t/* Reset to zero size, keep current limit. */ \\\n\t\t(bw_ctx)->p = (bw_ctx)->p_base; \\\n\t} while (0)\n#define DUK_BW_GET_BUFFER(thr,bw_ctx) \\\n\t((bw_ctx)->buf)\n\n/* Ensuring (reserving) space. */\n\n#define DUK_BW_ENSURE(thr,bw_ctx,sz) do { \\\n\t\tduk_size_t duk__sz, duk__space; \\\n\t\tDUK_BW_ASSERT_VALID((thr), (bw_ctx)); \\\n\t\tduk__sz = (sz); \\\n\t\tduk__space = (duk_size_t) ((bw_ctx)->p_limit - (bw_ctx)->p); \\\n\t\tif (duk__space < duk__sz) { \\\n\t\t\t(void) duk_bw_resize((thr), (bw_ctx), duk__sz); \\\n\t\t} \\\n\t} while (0)\n/* NOTE: Multiple evaluation of 'ptr' in this macro. */\n/* XXX: Rework to use an always-inline function? */\n#define DUK_BW_ENSURE_RAW(thr,bw_ctx,sz,ptr) \\\n\t(((duk_size_t) ((bw_ctx)->p_limit - (ptr)) >= (sz)) ? \\\n\t (ptr) : \\\n\t ((bw_ctx)->p = (ptr), duk_bw_resize((thr),(bw_ctx),(sz))))\n#define DUK_BW_ENSURE_GETPTR(thr,bw_ctx,sz) \\\n\tDUK_BW_ENSURE_RAW((thr), (bw_ctx), (sz), (bw_ctx)->p)\n#define DUK_BW_ASSERT_SPACE_EXPR(thr,bw_ctx,sz) \\\n\t(DUK_BW_ASSERT_VALID_EXPR((thr), (bw_ctx)), \\\n\t DUK_ASSERT_EXPR((duk_size_t) ((bw_ctx)->p_limit - (bw_ctx)->p) >= (duk_size_t) (sz)))\n#define DUK_BW_ASSERT_SPACE(thr,bw_ctx,sz) do { \\\n\t\tDUK_BW_ASSERT_SPACE_EXPR((thr), (bw_ctx), (sz)); \\\n\t} while (0)\n\n/* Miscellaneous. */\n\n#define DUK_BW_SETPTR_AND_COMPACT(thr,bw_ctx,ptr) do { \\\n\t\t(bw_ctx)->p = (ptr); \\\n\t\tduk_bw_compact((thr), (bw_ctx)); \\\n\t} while (0)\n\n/* Fast write calls which assume you control the slack beforehand.\n * Multibyte write variants exist and use a temporary write pointer\n * because byte writes alias with anything: with a stored pointer\n * explicit pointer load/stores get generated (e.g. gcc -Os).\n */\n\n#define DUK_BW_WRITE_RAW_U8(thr,bw_ctx,val) do { \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 1); \\\n\t\t*(bw_ctx)->p++ = (duk_uint8_t) (val); \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_2(thr,bw_ctx,val1,val2) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 2); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_3(thr,bw_ctx,val1,val2,val3) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 3); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_4(thr,bw_ctx,val1,val2,val3,val4) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 4); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t*duk__p++ = (duk_uint8_t) (val4); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_5(thr,bw_ctx,val1,val2,val3,val4,val5) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 5); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t*duk__p++ = (duk_uint8_t) (val4); \\\n\t\t*duk__p++ = (duk_uint8_t) (val5); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_6(thr,bw_ctx,val1,val2,val3,val4,val5,val6) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 6); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t*duk__p++ = (duk_uint8_t) (val4); \\\n\t\t*duk__p++ = (duk_uint8_t) (val5); \\\n\t\t*duk__p++ = (duk_uint8_t) (val6); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_XUTF8(thr,bw_ctx,cp) do { \\\n\t\tduk_ucodepoint_t duk__cp; \\\n\t\tduk_small_int_t duk__enc_len; \\\n\t\tduk__cp = (duk_ucodepoint_t) (cp); \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), duk_unicode_get_xutf8_length(duk__cp)); \\\n\t\tduk__enc_len = duk_unicode_encode_xutf8(duk__cp, (bw_ctx)->p); \\\n\t\t(bw_ctx)->p += duk__enc_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_CESU8(thr,bw_ctx,cp) do { \\\n\t\tduk_ucodepoint_t duk__cp; \\\n\t\tduk_small_int_t duk__enc_len; \\\n\t\tduk__cp = (duk_ucodepoint_t) (cp); \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), duk_unicode_get_cesu8_length(duk__cp)); \\\n\t\tduk__enc_len = duk_unicode_encode_cesu8(duk__cp, (bw_ctx)->p); \\\n\t\t(bw_ctx)->p += duk__enc_len; \\\n\t} while (0)\n/* XXX: add temporary duk__p pointer here too; sharing */\n/* XXX: avoid unsafe variants */\n#define DUK_BW_WRITE_RAW_BYTES(thr,bw_ctx,valptr,valsz) do { \\\n\t\tconst void *duk__valptr; \\\n\t\tduk_size_t duk__valsz; \\\n\t\tduk__valptr = (const void *) (valptr); \\\n\t\tduk__valsz = (duk_size_t) (valsz); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), duk__valptr, duk__valsz); \\\n\t\t(bw_ctx)->p += duk__valsz; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_CSTRING(thr,bw_ctx,val) do { \\\n\t\tconst duk_uint8_t *duk__val; \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val = (const duk_uint8_t *) (val); \\\n\t\tduk__val_len = DUK_STRLEN((const char *) duk__val); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) duk__val, duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HSTRING(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HSTRING_GET_BYTELEN((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HSTRING_GET_DATA((val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HBUFFER(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_GET_SIZE((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HBUFFER_FIXED(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_FIXED_GET_SIZE((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_FIXED_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HBUFFER_DYNAMIC(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_DYNAMIC_GET_SIZE((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n\n/* Append bytes from a slice already in the buffer. */\n#define DUK_BW_WRITE_RAW_SLICE(thr,bw,dst_off,dst_len) \\\n\tduk_bw_write_raw_slice((thr), (bw), (dst_off), (dst_len))\n\n/* Insert bytes in the middle of the buffer from an external buffer. */\n#define DUK_BW_INSERT_RAW_BYTES(thr,bw,dst_off,buf,len) \\\n\tduk_bw_insert_raw_bytes((thr), (bw), (dst_off), (buf), (len))\n\n/* Insert bytes in the middle of the buffer from a slice already\n * in the buffer.  Source offset is interpreted \"before\" the operation.\n */\n#define DUK_BW_INSERT_RAW_SLICE(thr,bw,dst_off,src_off,len) \\\n\tduk_bw_insert_raw_slice((thr), (bw), (dst_off), (src_off), (len))\n\n/* Insert a reserved area somewhere in the buffer; caller fills it.\n * Evaluates to a (duk_uint_t *) pointing to the start of the reserved\n * area for convenience.\n */\n#define DUK_BW_INSERT_RAW_AREA(thr,bw,off,len) \\\n\tduk_bw_insert_raw_area((thr), (bw), (off), (len))\n\n/* Remove a slice from inside buffer. */\n#define DUK_BW_REMOVE_RAW_SLICE(thr,bw,off,len) \\\n\tduk_bw_remove_raw_slice((thr), (bw), (off), (len))\n\n/* Safe write calls which will ensure space first. */\n\n#define DUK_BW_WRITE_ENSURE_U8(thr,bw_ctx,val) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 1); \\\n\t\tDUK_BW_WRITE_RAW_U8((thr), (bw_ctx), (val)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_2(thr,bw_ctx,val1,val2) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 2); \\\n\t\tDUK_BW_WRITE_RAW_U8_2((thr), (bw_ctx), (val1), (val2)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_3(thr,bw_ctx,val1,val2,val3) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 3); \\\n\t\tDUK_BW_WRITE_RAW_U8_3((thr), (bw_ctx), (val1), (val2), (val3)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_4(thr,bw_ctx,val1,val2,val3,val4) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 4); \\\n\t\tDUK_BW_WRITE_RAW_U8_4((thr), (bw_ctx), (val1), (val2), (val3), (val4)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_5(thr,bw_ctx,val1,val2,val3,val4,val5) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 5); \\\n\t\tDUK_BW_WRITE_RAW_U8_5((thr), (bw_ctx), (val1), (val2), (val3), (val4), (val5)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_6(thr,bw_ctx,val1,val2,val3,val4,val5,val6) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 6); \\\n\t\tDUK_BW_WRITE_RAW_U8_6((thr), (bw_ctx), (val1), (val2), (val3), (val4), (val5), (val6)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_XUTF8(thr,bw_ctx,cp) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), DUK_UNICODE_MAX_XUTF8_LENGTH); \\\n\t\tDUK_BW_WRITE_RAW_XUTF8((thr), (bw_ctx), (cp)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_CESU8(thr,bw_ctx,cp) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), DUK_UNICODE_MAX_CESU8_LENGTH); \\\n\t\tDUK_BW_WRITE_RAW_CESU8((thr), (bw_ctx), (cp)); \\\n\t} while (0)\n/* XXX: add temporary duk__p pointer here too; sharing */\n/* XXX: avoid unsafe */\n#define DUK_BW_WRITE_ENSURE_BYTES(thr,bw_ctx,valptr,valsz) do { \\\n\t\tconst void *duk__valptr; \\\n\t\tduk_size_t duk__valsz; \\\n\t\tduk__valptr = (const void *) (valptr); \\\n\t\tduk__valsz = (duk_size_t) (valsz); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__valsz); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), duk__valptr, duk__valsz); \\\n\t\t(bw_ctx)->p += duk__valsz; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_CSTRING(thr,bw_ctx,val) do { \\\n\t\tconst duk_uint8_t *duk__val; \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val = (const duk_uint8_t *) (val); \\\n\t\tduk__val_len = DUK_STRLEN((const char *) duk__val); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) duk__val, duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HSTRING(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HSTRING_GET_BYTELEN((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HSTRING_GET_DATA((val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HBUFFER(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_GET_SIZE((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HBUFFER_FIXED(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_FIXED_GET_SIZE((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_FIXED_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HBUFFER_DYNAMIC(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_DYNAMIC_GET_SIZE((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n\n#define DUK_BW_WRITE_ENSURE_SLICE(thr,bw,dst_off,dst_len) \\\n\tduk_bw_write_ensure_slice((thr), (bw), (dst_off), (dst_len))\n#define DUK_BW_INSERT_ENSURE_BYTES(thr,bw,dst_off,buf,len) \\\n\tduk_bw_insert_ensure_bytes((thr), (bw), (dst_off), (buf), (len))\n#define DUK_BW_INSERT_ENSURE_SLICE(thr,bw,dst_off,src_off,len) \\\n\tduk_bw_insert_ensure_slice((thr), (bw), (dst_off), (src_off), (len))\n#define DUK_BW_INSERT_ENSURE_AREA(thr,bw,off,len) \\\n\t/* Evaluates to (duk_uint8_t *) pointing to start of area. */ \\\n\tduk_bw_insert_ensure_area((thr), (bw), (off), (len))\n#define DUK_BW_REMOVE_ENSURE_SLICE(thr,bw,off,len) \\\n\t/* No difference between raw/ensure because the buffer shrinks. */ \\\n\tDUK_BW_REMOVE_RAW_SLICE((thr), (bw), (off), (len))\n\n/*\n *  Externs and prototypes\n */\n\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_lc_digits[36];\nDUK_INTERNAL_DECL const duk_uint8_t duk_uc_nybbles[16];\nDUK_INTERNAL_DECL const duk_int8_t duk_hex_dectab[256];\n#if defined(DUK_USE_HEX_FASTPATH)\nDUK_INTERNAL_DECL const duk_int16_t duk_hex_dectab_shift4[256];\nDUK_INTERNAL_DECL const duk_uint16_t duk_hex_enctab[256];\n#endif\n#endif  /* !DUK_SINGLE_FILE */\n\n/* Note: assumes that duk_util_probe_steps size is 32 */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL duk_uint8_t duk_util_probe_steps[32];\n#endif  /* !DUK_SINGLE_FILE */\n#endif\n\n#if defined(DUK_USE_STRHASH_DENSE)\nDUK_INTERNAL_DECL duk_uint32_t duk_util_hashbytes(const duk_uint8_t *data, duk_size_t len, duk_uint32_t seed);\n#endif\n\nDUK_INTERNAL_DECL duk_uint32_t duk_bd_decode(duk_bitdecoder_ctx *ctx, duk_small_int_t bits);\nDUK_INTERNAL_DECL duk_small_uint_t duk_bd_decode_flag(duk_bitdecoder_ctx *ctx);\nDUK_INTERNAL_DECL duk_uint32_t duk_bd_decode_flagged(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_uint32_t def_value);\nDUK_INTERNAL_DECL duk_int32_t duk_bd_decode_flagged_signed(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_int32_t def_value);\nDUK_INTERNAL_DECL duk_uint32_t duk_bd_decode_varuint(duk_bitdecoder_ctx *ctx);\nDUK_INTERNAL_DECL duk_small_uint_t duk_bd_decode_bitpacked_string(duk_bitdecoder_ctx *bd, duk_uint8_t *out);\n\nDUK_INTERNAL_DECL void duk_be_encode(duk_bitencoder_ctx *ctx, duk_uint32_t data, duk_small_int_t bits);\nDUK_INTERNAL_DECL void duk_be_finish(duk_bitencoder_ctx *ctx);\n\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\nDUK_INTERNAL_DECL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL void duk_bw_init(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_hbuffer_dynamic *h_buf);\nDUK_INTERNAL_DECL void duk_bw_init_pushbuf(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t buf_size);\nDUK_INTERNAL_DECL duk_uint8_t *duk_bw_resize(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t sz);\nDUK_INTERNAL_DECL void duk_bw_compact(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx);\nDUK_INTERNAL_DECL void duk_bw_write_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_write_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_raw_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_ensure_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL duk_uint8_t *duk_bw_insert_raw_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len);\nDUK_INTERNAL_DECL duk_uint8_t *duk_bw_insert_ensure_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len);\n/* No duk_bw_remove_ensure_slice(), functionality would be identical. */\n\nDUK_INTERNAL_DECL duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p);\nDUK_INTERNAL_DECL duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p);\nDUK_INTERNAL_DECL duk_double_t duk_raw_read_double_be(duk_uint8_t **p);\nDUK_INTERNAL_DECL void duk_raw_write_u16_be(duk_uint8_t **p, duk_uint16_t val);\nDUK_INTERNAL_DECL void duk_raw_write_u32_be(duk_uint8_t **p, duk_uint32_t val);\nDUK_INTERNAL_DECL void duk_raw_write_double_be(duk_uint8_t **p, duk_double_t val);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* For now only needed by the debugger. */\nDUK_INTERNAL_DECL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len);\n#endif\n\n/* memcpy(), memmove() etc wrappers.  The plain variants like duk_memcpy()\n * assume C99+ and 'src' and 'dst' pointers must be non-NULL even when the\n * operation size is zero.  The unsafe variants like duk_memcpy_safe() deal\n * with the zero size case explicitly, and allow NULL pointers in that case\n * (which is undefined behavior in C99+).  For the majority of actual targets\n * a NULL pointer with a zero length is fine in practice.  These wrappers are\n * macros to force inlining; because there are hundreds of call sites, even a\n * few extra bytes per call site adds up to ~1kB footprint.\n */\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n#define duk_memcpy(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memcpy_unsafe(dst,src,len)  duk_memcpy((dst), (src), (len))\n#define duk_memmove(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memmove_unsafe(dst,src,len)  duk_memmove((dst), (src), (len))\n#define duk_memset(dst,val,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_small_int_t duk__val = (val); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memset_unsafe(dst,val,len)  duk_memset((dst), (val), (len))\n#define duk_memzero(dst,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memzero_unsafe(dst,len)  duk_memzero((dst), (len))\n#else  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\n#define duk_memcpy(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t(void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memcpy_unsafe(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t\t(void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#define duk_memmove(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t(void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memmove_unsafe(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t\t(void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#define duk_memset(dst,val,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_small_int_t duk__val = (val); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t(void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memset_unsafe(dst,val,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_small_int_t duk__val = (val); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\t(void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#define duk_memzero(dst,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t(void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memzero_unsafe(dst,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\t(void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#endif  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\n\nDUK_INTERNAL_DECL duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len);\nDUK_INTERNAL_DECL duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len);\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_whole_get_int32_nonegzero(duk_double_t x, duk_int32_t *ival);\nDUK_INTERNAL_DECL duk_bool_t duk_is_whole_get_int32(duk_double_t x, duk_int32_t *ival);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_anyinf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_posinf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_neginf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_or_zero(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_or_inf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_zero_inf(duk_double_t x);\nDUK_INTERNAL_DECL duk_small_uint_t duk_double_signbit(duk_double_t x);\nDUK_INTERNAL_DECL duk_double_t duk_double_trunc_towards_zero(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_same_sign(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_double_t duk_double_fmin(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_finite(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_integer(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_safe_integer(duk_double_t x);\n\nDUK_INTERNAL_DECL duk_double_t duk_double_div(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_int_t duk_double_to_int_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_uint_t duk_double_to_uint_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_int32_t duk_double_to_int32_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_uint32_t duk_double_to_uint32_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_float_t duk_double_to_float_t(duk_double_t x);\n\n/*\n *  Miscellaneous\n */\n\n/* Example: x     = 0x10 = 0b00010000\n *          x - 1 = 0x0f = 0b00001111\n *          x & (x - 1) == 0\n *\n *          x     = 0x07 = 0b00000111\n *          x - 1 = 0x06 = 0b00000110\n *          x & (x - 1) != 0\n *\n * However, incorrectly true for x == 0 so check for that explicitly.\n */\n#define DUK_IS_POWER_OF_TWO(x) \\\n\t((x) != 0U && ((x) & ((x) - 1U)) == 0U)\n\n#endif  /* DUK_UTIL_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_util_bitdecoder.c",
    "content": "/*\n *  Bitstream decoder.\n */\n\n#include \"duk_internal.h\"\n\n/* Decode 'bits' bits from the input stream (bits must be 1...24).\n * When reading past bitstream end, zeroes are shifted in.  The result\n * is signed to match duk_bd_decode_flagged.\n */\nDUK_INTERNAL duk_uint32_t duk_bd_decode(duk_bitdecoder_ctx *ctx, duk_small_int_t bits) {\n\tduk_small_int_t shift;\n\tduk_uint32_t mask;\n\tduk_uint32_t tmp;\n\n\t/* Note: cannot read more than 24 bits without possibly shifting top bits out.\n\t * Fixable, but adds complexity.\n\t */\n\tDUK_ASSERT(bits >= 1 && bits <= 24);\n\n\twhile (ctx->currbits < bits) {\n#if 0\n\t\tDUK_DDD(DUK_DDDPRINT(\"decode_bits: shift more data (bits=%ld, currbits=%ld)\",\n\t\t                     (long) bits, (long) ctx->currbits));\n#endif\n\t\tctx->currval <<= 8;\n\t\tif (ctx->offset < ctx->length) {\n\t\t\t/* If ctx->offset >= ctx->length, we \"shift zeroes in\"\n\t\t\t * instead of croaking.\n\t\t\t */\n\t\t\tctx->currval |= ctx->data[ctx->offset++];\n\t\t}\n\t\tctx->currbits += 8;\n\t}\n#if 0\n\tDUK_DDD(DUK_DDDPRINT(\"decode_bits: bits=%ld, currbits=%ld, currval=0x%08lx\",\n\t                     (long) bits, (long) ctx->currbits, (unsigned long) ctx->currval));\n#endif\n\n\t/* Extract 'top' bits of currval; note that the extracted bits do not need\n\t * to be cleared, we just ignore them on next round.\n\t */\n\tshift = ctx->currbits - bits;\n\tmask = (((duk_uint32_t) 1U) << bits) - 1U;\n\ttmp = (ctx->currval >> shift) & mask;\n\tctx->currbits = shift;  /* remaining */\n\n#if 0\n\tDUK_DDD(DUK_DDDPRINT(\"decode_bits: %ld bits -> 0x%08lx (%ld), currbits=%ld, currval=0x%08lx\",\n\t                     (long) bits, (unsigned long) tmp, (long) tmp, (long) ctx->currbits, (unsigned long) ctx->currval));\n#endif\n\n\treturn tmp;\n}\n\nDUK_INTERNAL duk_small_uint_t duk_bd_decode_flag(duk_bitdecoder_ctx *ctx) {\n\treturn (duk_small_uint_t) duk_bd_decode(ctx, 1);\n}\n\n/* Decode a one-bit flag, and if set, decode a value of 'bits', otherwise return\n * default value.\n */\nDUK_INTERNAL duk_uint32_t duk_bd_decode_flagged(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_uint32_t def_value) {\n\tif (duk_bd_decode_flag(ctx)) {\n\t\treturn duk_bd_decode(ctx, bits);\n\t} else {\n\t\treturn def_value;\n\t}\n}\n\n/* Signed variant, allows negative marker value. */\nDUK_INTERNAL duk_int32_t duk_bd_decode_flagged_signed(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_int32_t def_value) {\n\treturn (duk_int32_t) duk_bd_decode_flagged(ctx, bits, (duk_uint32_t) def_value);\n}\n\n/* Shared varint encoding.  Match dukutil.py BitEncode.varuint(). */\nDUK_INTERNAL duk_uint32_t duk_bd_decode_varuint(duk_bitdecoder_ctx *ctx) {\n\tduk_small_uint_t t;\n\n\t/* The bit encoding choices here are based on manual testing against\n\t * the actual varuints generated by genbuiltins.py.\n\t */\n\tswitch (duk_bd_decode(ctx, 2)) {\n\tcase 0:\n\t\treturn 0;  /* [0,0] */\n\tcase 1:\n\t\treturn duk_bd_decode(ctx, 2) + 1;  /* [1,4] */\n\tcase 2:\n\t\treturn duk_bd_decode(ctx, 5) + 5;  /* [5,36] */\n\tdefault:\n\t\tt = duk_bd_decode(ctx, 7);\n\t\tif (t == 0) {\n\t\t\treturn duk_bd_decode(ctx, 20);\n\t\t}\n\t\treturn (t - 1) + 37;  /* [37,163] */\n\t}\n}\n\n/* Decode a bit packed string from a custom format used by genbuiltins.py.\n * This function is here because it's used for both heap and thread inits.\n * Caller must supply the output buffer whose size is NOT checked!\n */\n\n#define DUK__BITPACK_LETTER_LIMIT  26\n#define DUK__BITPACK_LOOKUP1       26\n#define DUK__BITPACK_LOOKUP2       27\n#define DUK__BITPACK_SWITCH1       28\n#define DUK__BITPACK_SWITCH        29\n#define DUK__BITPACK_UNUSED1       30\n#define DUK__BITPACK_EIGHTBIT      31\n\nDUK_LOCAL const duk_uint8_t duk__bitpacked_lookup[16] = {\n\tDUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3,\n\tDUK_ASC_4, DUK_ASC_5, DUK_ASC_6, DUK_ASC_7,\n\tDUK_ASC_8, DUK_ASC_9, DUK_ASC_UNDERSCORE, DUK_ASC_SPACE,\n\t0x82, 0x80, DUK_ASC_DOUBLEQUOTE, DUK_ASC_LCURLY\n};\n\nDUK_INTERNAL duk_small_uint_t duk_bd_decode_bitpacked_string(duk_bitdecoder_ctx *bd, duk_uint8_t *out) {\n\tduk_small_uint_t len;\n\tduk_small_uint_t mode;\n\tduk_small_uint_t t;\n\tduk_small_uint_t i;\n\n\tlen = duk_bd_decode(bd, 5);\n\tif (len == 31) {\n\t\tlen = duk_bd_decode(bd, 8);  /* Support up to 256 bytes; rare. */\n\t}\n\n\tmode = 32;  /* 0 = uppercase, 32 = lowercase (= 'a' - 'A') */\n\tfor (i = 0; i < len; i++) {\n\t\tt = duk_bd_decode(bd, 5);\n\t\tif (t < DUK__BITPACK_LETTER_LIMIT) {\n\t\t\tt = t + DUK_ASC_UC_A + mode;\n\t\t} else if (t == DUK__BITPACK_LOOKUP1) {\n\t\t\tt = duk__bitpacked_lookup[duk_bd_decode(bd, 3)];\n\t\t} else if (t == DUK__BITPACK_LOOKUP2) {\n\t\t\tt = duk__bitpacked_lookup[8 + duk_bd_decode(bd, 3)];\n\t\t} else if (t == DUK__BITPACK_SWITCH1) {\n\t\t\tt = duk_bd_decode(bd, 5);\n\t\t\tDUK_ASSERT_DISABLE(t >= 0);  /* unsigned */\n\t\t\tDUK_ASSERT(t <= 25);\n\t\t\tt = t + DUK_ASC_UC_A + (mode ^ 32);\n\t\t} else if (t == DUK__BITPACK_SWITCH) {\n\t\t\tmode = mode ^ 32;\n\t\t\tt = duk_bd_decode(bd, 5);\n\t\t\tDUK_ASSERT_DISABLE(t >= 0);\n\t\t\tDUK_ASSERT(t <= 25);\n\t\t\tt = t + DUK_ASC_UC_A + mode;\n\t\t} else if (t == DUK__BITPACK_EIGHTBIT) {\n\t\t\tt = duk_bd_decode(bd, 8);\n\t\t}\n\t\tout[i] = (duk_uint8_t) t;\n\t}\n\n\treturn len;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_util_bitencoder.c",
    "content": "/*\n *  Bitstream encoder.\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL void duk_be_encode(duk_bitencoder_ctx *ctx, duk_uint32_t data, duk_small_int_t bits) {\n\tduk_uint8_t tmp;\n\n\tDUK_ASSERT(ctx != NULL);\n\tDUK_ASSERT(ctx->currbits < 8);\n\n\t/* This limitation would be fixable but adds unnecessary complexity. */\n\tDUK_ASSERT(bits >= 1 && bits <= 24);\n\n\tctx->currval = (ctx->currval << bits) | data;\n\tctx->currbits += bits;\n\n\twhile (ctx->currbits >= 8) {\n\t\tif (ctx->offset < ctx->length) {\n\t\t\ttmp = (duk_uint8_t) ((ctx->currval >> (ctx->currbits - 8)) & 0xff);\n\t\t\tctx->data[ctx->offset++] = tmp;\n\t\t} else {\n\t\t\t/* If buffer has been exhausted, truncate bitstream */\n\t\t\tctx->truncated = 1;\n\t\t}\n\n\t\tctx->currbits -= 8;\n\t}\n}\n\nDUK_INTERNAL void duk_be_finish(duk_bitencoder_ctx *ctx) {\n\tduk_small_int_t npad;\n\n\tDUK_ASSERT(ctx != NULL);\n\tDUK_ASSERT(ctx->currbits < 8);\n\n\tnpad = (duk_small_int_t) (8 - ctx->currbits);\n\tif (npad > 0) {\n\t\tduk_be_encode(ctx, 0, npad);\n\t}\n\tDUK_ASSERT(ctx->currbits == 0);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_util_bufwriter.c",
    "content": "/*\n *  Fast buffer writer with slack management.\n */\n\n#include \"duk_internal.h\"\n\n/* XXX: Avoid duk_{memcmp,memmove}_unsafe() by imposing a minimum length of\n * >0 for the underlying dynamic buffer.\n */\n\n/*\n *  Macro support functions (use only macros in calling code)\n */\n\nDUK_LOCAL void duk__bw_update_ptrs(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t curr_offset, duk_size_t new_length) {\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_UNREF(thr);\n\n\t/* 'p' might be NULL when the underlying buffer is zero size.  If so,\n\t * the resulting pointers are not used unsafely.\n\t */\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, bw_ctx->buf);\n\tDUK_ASSERT(p != NULL || (DUK_HBUFFER_DYNAMIC_GET_SIZE(bw_ctx->buf) == 0 && curr_offset == 0 && new_length == 0));\n\tbw_ctx->p = p + curr_offset;\n\tbw_ctx->p_base = p;\n\tbw_ctx->p_limit = p + new_length;\n}\n\nDUK_INTERNAL void duk_bw_init(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_hbuffer_dynamic *h_buf) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_ASSERT(h_buf != NULL);\n\n\tbw_ctx->buf = h_buf;\n\tduk__bw_update_ptrs(thr, bw_ctx, 0, DUK_HBUFFER_DYNAMIC_GET_SIZE(h_buf));\n}\n\nDUK_INTERNAL void duk_bw_init_pushbuf(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t buf_size) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\n\t(void) duk_push_dynamic_buffer(thr, buf_size);\n\tbw_ctx->buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, -1);\n\tDUK_ASSERT(bw_ctx->buf != NULL);\n\tduk__bw_update_ptrs(thr, bw_ctx, 0, buf_size);\n}\n\n/* Resize target buffer for requested size.  Called by the macro only when the\n * fast path test (= there is space) fails.\n */\nDUK_INTERNAL duk_uint8_t *duk_bw_resize(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t sz) {\n\tduk_size_t curr_off;\n\tduk_size_t add_sz;\n\tduk_size_t new_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\n\t/* We could do this operation without caller updating bw_ctx->ptr,\n\t * but by writing it back here we can share code better.\n\t */\n\n\tcurr_off = (duk_size_t) (bw_ctx->p - bw_ctx->p_base);\n\tadd_sz = (curr_off >> DUK_BW_SLACK_SHIFT) + DUK_BW_SLACK_ADD;\n\tnew_sz = curr_off + sz + add_sz;\n\tif (DUK_UNLIKELY(new_sz < curr_off)) {\n\t\t/* overflow */\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_BUFFER_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n#if 0  /* for manual torture testing: tight allocation, useful with valgrind */\n\tnew_sz = curr_off + sz;\n#endif\n\n\t/* This is important to ensure dynamic buffer data pointer is not\n\t * NULL (which is possible if buffer size is zero), which in turn\n\t * causes portability issues with e.g. memmove() and memcpy().\n\t */\n\tDUK_ASSERT(new_sz >= 1);\n\n\tDUK_DD(DUK_DDPRINT(\"resize bufferwriter from %ld to %ld (add_sz=%ld)\", (long) curr_off, (long) new_sz, (long) add_sz));\n\n\tduk_hbuffer_resize(thr, bw_ctx->buf, new_sz);\n\tduk__bw_update_ptrs(thr, bw_ctx, curr_off, new_sz);\n\treturn bw_ctx->p;\n}\n\n/* Make buffer compact, matching current written size. */\nDUK_INTERNAL void duk_bw_compact(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx) {\n\tduk_size_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_UNREF(thr);\n\n\tlen = (duk_size_t) (bw_ctx->p - bw_ctx->p_base);\n\tduk_hbuffer_resize(thr, bw_ctx->buf, len);\n\tduk__bw_update_ptrs(thr, bw_ctx, len, len);\n}\n\nDUK_INTERNAL void duk_bw_write_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len) {\n\tduk_uint8_t *p_base;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tduk_memcpy_unsafe((void *) bw->p,\n\t                  (const void *) (p_base + src_off),\n\t                  (size_t) len);\n\tbw->p += len;\n}\n\nDUK_INTERNAL void duk_bw_write_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\tduk_bw_write_raw_slice(thr, bw, src_off, len);\n}\n\nDUK_INTERNAL void duk_bw_insert_raw_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len) {\n\tduk_uint8_t *p_base;\n\tduk_size_t buf_sz, move_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(buf != NULL);\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tbuf_sz = (duk_size_t) (bw->p - p_base);  /* constrained by maximum buffer size */\n\tmove_sz = buf_sz - dst_off;\n\n\tDUK_ASSERT(p_base != NULL);  /* buffer size is >= 1 */\n\tduk_memmove_unsafe((void *) (p_base + dst_off + len),\n\t                   (const void *) (p_base + dst_off),\n\t                   (size_t) move_sz);\n\tduk_memcpy_unsafe((void *) (p_base + dst_off),\n\t                  (const void *) buf,\n\t                  (size_t) len);\n\tbw->p += len;\n}\n\nDUK_INTERNAL void duk_bw_insert_ensure_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(buf != NULL);\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\tduk_bw_insert_raw_bytes(thr, bw, dst_off, buf, len);\n}\n\nDUK_INTERNAL void duk_bw_insert_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len) {\n\tduk_uint8_t *p_base;\n\tduk_size_t buf_sz, move_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\n\t/* Don't support \"straddled\" source now. */\n\tDUK_ASSERT(dst_off <= src_off || dst_off >= src_off + len);\n\n\tif (dst_off <= src_off) {\n\t\t/* Target is before source.  Source offset is expressed as\n\t\t * a \"before change\" offset.  Account for the memmove.\n\t\t */\n\t\tsrc_off += len;\n\t}\n\n\tbuf_sz = (duk_size_t) (bw->p - p_base);\n\tmove_sz = buf_sz - dst_off;\n\n\tDUK_ASSERT(p_base != NULL);  /* buffer size is >= 1 */\n\tduk_memmove_unsafe((void *) (p_base + dst_off + len),\n\t                   (const void *) (p_base + dst_off),\n\t                   (size_t) move_sz);\n\tduk_memcpy_unsafe((void *) (p_base + dst_off),\n\t                  (const void *) (p_base + src_off),\n\t                  (size_t) len);\n\tbw->p += len;\n}\n\nDUK_INTERNAL void duk_bw_insert_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\n\t/* Don't support \"straddled\" source now. */\n\tDUK_ASSERT(dst_off <= src_off || dst_off >= src_off + len);\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\tduk_bw_insert_raw_slice(thr, bw, dst_off, src_off, len);\n}\n\nDUK_INTERNAL duk_uint8_t *duk_bw_insert_raw_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len) {\n\tduk_uint8_t *p_base, *p_dst, *p_src;\n\tduk_size_t buf_sz, move_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tbuf_sz = (duk_size_t) (bw->p - p_base);\n\tmove_sz = buf_sz - off;\n\tp_dst = p_base + off + len;\n\tp_src = p_base + off;\n\tduk_memmove_unsafe((void *) p_dst, (const void *) p_src, (size_t) move_sz);\n\treturn p_src;  /* point to start of 'reserved area' */\n}\n\nDUK_INTERNAL duk_uint8_t *duk_bw_insert_ensure_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw));\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\treturn duk_bw_insert_raw_area(thr, bw, off, len);\n}\n\nDUK_INTERNAL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len) {\n\tduk_size_t move_sz;\n\n\tduk_uint8_t *p_base;\n\tduk_uint8_t *p_src;\n\tduk_uint8_t *p_dst;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(off + len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tp_dst = p_base + off;\n\tp_src = p_dst + len;\n\tmove_sz = (duk_size_t) (bw->p - p_src);\n\tduk_memmove_unsafe((void *) p_dst,\n\t                   (const void *) p_src,\n\t                   (size_t) move_sz);\n\tbw->p -= len;\n}\n\n/*\n *  Macro support functions for reading/writing raw data.\n *\n *  These are done using mempcy to ensure they're valid even for unaligned\n *  reads/writes on platforms where alignment counts.  On x86 at least gcc\n *  is able to compile these into a bswap+mov.  \"Always inline\" is used to\n *  ensure these macros compile to minimal code.\n *\n *  Not really bufwriter related, but currently used together.\n */\n\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p) {\n\tunion {\n\t\tduk_uint8_t b[2];\n\t\tduk_uint16_t x;\n\t} u;\n\n\tduk_memcpy((void *) u.b, (const void *) (*p), (size_t) 2);\n\tu.x = DUK_NTOH16(u.x);\n\t*p += 2;\n\treturn u.x;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p) {\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tduk_memcpy((void *) u.b, (const void *) (*p), (size_t) 4);\n\tu.x = DUK_NTOH32(u.x);\n\t*p += 4;\n\treturn u.x;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_raw_read_double_be(duk_uint8_t **p) {\n\tduk_double_union du;\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tduk_memcpy((void *) u.b, (const void *) (*p), (size_t) 4);\n\tu.x = DUK_NTOH32(u.x);\n\tdu.ui[DUK_DBL_IDX_UI0] = u.x;\n\tduk_memcpy((void *) u.b, (const void *) (*p + 4), (size_t) 4);\n\tu.x = DUK_NTOH32(u.x);\n\tdu.ui[DUK_DBL_IDX_UI1] = u.x;\n\t*p += 8;\n\n\treturn du.d;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u16_be(duk_uint8_t **p, duk_uint16_t val) {\n\tunion {\n\t\tduk_uint8_t b[2];\n\t\tduk_uint16_t x;\n\t} u;\n\n\tu.x = DUK_HTON16(val);\n\tduk_memcpy((void *) (*p), (const void *) u.b, (size_t) 2);\n\t*p += 2;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u32_be(duk_uint8_t **p, duk_uint32_t val) {\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tu.x = DUK_HTON32(val);\n\tduk_memcpy((void *) (*p), (const void *) u.b, (size_t) 4);\n\t*p += 4;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_double_be(duk_uint8_t **p, duk_double_t val) {\n\tduk_double_union du;\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tdu.d = val;\n\tu.x = du.ui[DUK_DBL_IDX_UI0];\n\tu.x = DUK_HTON32(u.x);\n\tduk_memcpy((void *) (*p), (const void *) u.b, (size_t) 4);\n\tu.x = du.ui[DUK_DBL_IDX_UI1];\n\tu.x = DUK_HTON32(u.x);\n\tduk_memcpy((void *) (*p + 4), (const void *) u.b, (size_t) 4);\n\t*p += 8;\n}\n\n/*\n *  Assertion helpers\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL void duk_bw_assert_valid(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx) {\n\tDUK_UNREF(thr);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_ASSERT(bw_ctx->buf != NULL);\n\tDUK_ASSERT((DUK_HBUFFER_DYNAMIC_GET_SIZE(bw_ctx->buf) == 0) ||\n\t           (bw_ctx->p != NULL &&\n\t            bw_ctx->p_base != NULL &&\n\t            bw_ctx->p_limit != NULL &&\n\t            bw_ctx->p_limit >= bw_ctx->p_base &&\n\t            bw_ctx->p >= bw_ctx->p_base &&\n\t            bw_ctx->p <= bw_ctx->p_limit));\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_util_cast.c",
    "content": "/*\n *  Cast helpers.\n *\n *  C99+ coercion is challenging portability-wise because out-of-range casts\n *  may invoke implementation defined or even undefined behavior.  See e.g.\n *  http://blog.frama-c.com/index.php?post/2013/10/09/Overflow-float-integer.\n *\n *  Provide explicit cast helpers which try to avoid implementation defined\n *  or undefined behavior.  These helpers can then be simplified in the vast\n *  majority of cases where the implementation defined or undefined behavior\n *  is not problematic.\n */\n\n#include \"duk_internal.h\"\n\n/* Portable double-to-integer cast which avoids undefined behavior and avoids\n * relying on fmin(), fmax(), or other intrinsics.  Out-of-range results are\n * not assumed by caller, but here value is clamped, NaN converts to minval.\n */\n#define DUK__DOUBLE_INT_CAST1(tname,minval,maxval)  do { \\\n\t\tif (DUK_LIKELY(x >= (duk_double_t) (minval))) { \\\n\t\t\tDUK_ASSERT(!DUK_ISNAN(x)); \\\n\t\t\tif (DUK_LIKELY(x <= (duk_double_t) (maxval))) { \\\n\t\t\t\treturn (tname) x; \\\n\t\t\t} else { \\\n\t\t\t\treturn (tname) (maxval); \\\n\t\t\t} \\\n\t\t} else { \\\n\t\t\t/* NaN or below minval.  Since we don't care about the result \\\n\t\t\t * for out-of-range values, just return the minimum value for \\\n\t\t\t * both. \\\n\t\t\t */ \\\n\t\t\treturn (tname) (minval); \\\n\t\t} \\\n\t} while (0)\n\n/* Rely on specific NaN behavior for duk_double_{fmin,fmax}(): if either\n * argument is a NaN, return the second argument.  This avoids a\n * NaN-to-integer cast which is undefined behavior.\n */\n#define DUK__DOUBLE_INT_CAST2(tname,minval,maxval)  do { \\\n\t\treturn (tname) duk_double_fmin(duk_double_fmax(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \\\n\t} while (0)\n\n/* Another solution which doesn't need C99+ behavior for fmin() and fmax(). */\n#define DUK__DOUBLE_INT_CAST3(tname,minval,maxval)  do { \\\n\t\tif (DUK_ISNAN(x)) { \\\n\t\t\t/* 0 or any other value is fine. */ \\\n\t\t\treturn (tname) 0; \\\n\t\t} else \\\n\t\t\treturn (tname) DUK_FMIN(DUK_FMAX(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \\\n\t\t} \\\n\t} while (0)\n\n/* C99+ solution: relies on specific fmin() and fmax() behavior in C99: if\n * one argument is NaN but the other isn't, the non-NaN argument is returned.\n * Because the limits are non-NaN values, explicit NaN check is not needed.\n * This may not work on all legacy platforms, and also doesn't seem to inline\n * the fmin() and fmax() calls (unless one uses -ffast-math which we don't\n * support).\n */\n#define DUK__DOUBLE_INT_CAST4(tname,minval,maxval)  do { \\\n\t\treturn (tname) DUK_FMIN(DUK_FMAX(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \\\n\t} while (0)\n\nDUK_INTERNAL duk_int_t duk_double_to_int_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\t/* Real world solution: almost any practical platform will provide\n\t * an integer value without any guarantees what it is (which is fine).\n\t */\n\treturn (duk_int_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_int_t, DUK_INT_MIN, DUK_INT_MAX);\n#endif\n}\n\nDUK_INTERNAL duk_uint_t duk_double_to_uint_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_uint_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_uint_t, DUK_UINT_MIN, DUK_UINT_MAX);\n#endif\n}\n\nDUK_INTERNAL duk_int32_t duk_double_to_int32_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_int32_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_int32_t, DUK_INT32_MIN, DUK_INT32_MAX);\n#endif\n}\n\nDUK_INTERNAL duk_uint32_t duk_double_to_uint32_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_uint32_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_uint32_t, DUK_UINT32_MIN, DUK_UINT32_MAX);\n#endif\n}\n\n/* Largest IEEE double that doesn't round to infinity in the default rounding\n * mode.  The exact midpoint between (1 - 2^(-24)) * 2^128 and 2^128 rounds to\n * infinity, at least on x64.  This number is one double unit below that\n * midpoint.  See misc/float_cast.c.\n */\n#define DUK__FLOAT_ROUND_LIMIT      340282356779733623858607532500980858880.0\n\n/* Maximum IEEE float.  Double-to-float conversion above this would be out of\n * range and thus technically undefined behavior.\n */\n#define DUK__FLOAT_MAX              340282346638528859811704183484516925440.0\n\nDUK_INTERNAL duk_float_t duk_double_to_float_t(duk_double_t x) {\n\t/* Even a double-to-float cast is technically undefined behavior if\n\t * the double is out-of-range.  C99 Section 6.3.1.5:\n\t *\n\t *   If the value being converted is in the range of values that can\n\t *   be represented but cannot be represented exactly, the result is\n\t *   either the nearest higher or nearest lower representable value,\n\t *   chosen in an implementation-defined manner.  If the value being\n\t *   converted is outside the range of values that can be represented,\n\t *   the behavior is undefined.\n\t */\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_float_t) x;\n#else\n\tduk_double_t t;\n\n\tt = DUK_FABS(x);\n\tDUK_ASSERT((DUK_ISNAN(x) && DUK_ISNAN(t)) ||\n\t           (!DUK_ISNAN(x) && !DUK_ISNAN(t)));\n\n\tif (DUK_LIKELY(t <= DUK__FLOAT_MAX)) {\n\t\t/* Standard in-range case, try to get here with a minimum\n\t\t * number of checks and branches.\n\t\t */\n\t\tDUK_ASSERT(!DUK_ISNAN(x));\n\t\treturn (duk_float_t) x;\n\t} else if (t <= DUK__FLOAT_ROUND_LIMIT) {\n\t\t/* Out-of-range, but rounds to min/max float. */\n\t\tDUK_ASSERT(!DUK_ISNAN(x));\n\t\tif (x < 0.0) {\n\t\t\treturn (duk_float_t) -DUK__FLOAT_MAX;\n\t\t} else {\n\t\t\treturn (duk_float_t) DUK__FLOAT_MAX;\n\t\t}\n\t} else if (DUK_ISNAN(x)) {\n\t\t/* Assumes double NaN -> float NaN considered \"in range\". */\n\t\tDUK_ASSERT(DUK_ISNAN(x));\n\t\treturn (duk_float_t) x;\n\t} else {\n\t\t/* Out-of-range, rounds to +/- Infinity. */\n\t\tif (x < 0.0) {\n\t\t\treturn (duk_float_t) -DUK_DOUBLE_INFINITY;\n\t\t} else {\n\t\t\treturn (duk_float_t) DUK_DOUBLE_INFINITY;\n\t\t}\n\t}\n#endif\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_util_double.c",
    "content": "/*\n *  IEEE double helpers.\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL duk_bool_t duk_double_is_anyinf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn DUK_DBLUNION_IS_ANYINF(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_posinf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn DUK_DBLUNION_IS_POSINF(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_neginf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn DUK_DBLUNION_IS_NEGINF(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\t/* Assumes we're dealing with a Duktape internal NaN which is\n\t * NaN normalized if duk_tval requires it.\n\t */\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\treturn DUK_DBLUNION_IS_NAN(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan_or_zero(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\t/* Assumes we're dealing with a Duktape internal NaN which is\n\t * NaN normalized if duk_tval requires it.\n\t */\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\treturn DUK_DBLUNION_IS_NAN(&du) || DUK_DBLUNION_IS_ANYZERO(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan_or_inf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\t/* If exponent is 0x7FF the argument is either a NaN or an\n\t * infinity.  We don't need to check any other fields.\n\t */\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n\treturn (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000);\n#else\n\treturn (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000);\n#endif\n#else\n\treturn (du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL;\n#endif\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan_zero_inf(duk_double_t x) {\n\tduk_double_union du;\n#if defined(DUK_USE_64BIT_OPS)\n\tduk_uint64_t t;\n#else\n\tduk_uint32_t t;\n#endif\n\tdu.d = x;\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000);\n\tif (t == DUK_U64_CONSTANT(0x0000000000000000)) {\n\t\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x0000000080000000);\n\t\treturn t == 0;\n\t}\n\tif (t == DUK_U64_CONSTANT(0x000000007ff00000)) {\n\t\treturn 1;\n\t}\n#else\n\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000);\n\tif (t == DUK_U64_CONSTANT(0x0000000000000000)) {\n\t\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x8000000000000000);\n\t\treturn t == 0;\n\t}\n\tif (t == DUK_U64_CONSTANT(0x7ff0000000000000)) {\n\t\treturn 1;\n\t}\n#endif\n#else\n\tt = du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL;\n\tif (t == 0x00000000UL) {\n\t\treturn DUK_DBLUNION_IS_ANYZERO(&du);\n\t}\n\tif (t == 0x7ff00000UL) {\n\t\treturn 1;\n\t}\n#endif\n\treturn 0;\n}\n\nDUK_INTERNAL duk_small_uint_t duk_double_signbit(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn (duk_small_uint_t) DUK_DBLUNION_GET_SIGNBIT(&du);\n}\n\nDUK_INTERNAL duk_double_t duk_double_trunc_towards_zero(duk_double_t x) {\n\t/* XXX: optimize */\n\tduk_small_uint_t s = duk_double_signbit(x);\n\tx = DUK_FLOOR(DUK_FABS(x));  /* truncate towards zero */\n\tif (s) {\n\t\tx = -x;\n\t}\n\treturn x;\n}\n\nDUK_INTERNAL duk_bool_t duk_double_same_sign(duk_double_t x, duk_double_t y) {\n\tduk_double_union du1;\n\tduk_double_union du2;\n\tdu1.d = x;\n\tdu2.d = y;\n\n\treturn (((du1.ui[DUK_DBL_IDX_UI0] ^ du2.ui[DUK_DBL_IDX_UI0]) & 0x80000000UL) == 0);\n}\n\nDUK_INTERNAL duk_double_t duk_double_fmin(duk_double_t x, duk_double_t y) {\n\t/* Doesn't replicate fmin() behavior exactly: for fmin() if one\n\t * argument is a NaN, the other argument should be returned.\n\t * Duktape doesn't rely on this behavior so the replacement can\n\t * be simplified.\n\t */\n\treturn (x < y ? x : y);\n}\n\nDUK_INTERNAL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y) {\n\t/* Doesn't replicate fmax() behavior exactly: for fmax() if one\n\t * argument is a NaN, the other argument should be returned.\n\t * Duktape doesn't rely on this behavior so the replacement can\n\t * be simplified.\n\t */\n\treturn (x > y ? x : y);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_finite(duk_double_t x) {\n\treturn !duk_double_is_nan_or_inf(x);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_integer(duk_double_t x) {\n\tif (duk_double_is_nan_or_inf(x)) {\n\t\treturn 0;\n\t} else {\n\t\treturn duk_js_tointeger_number(x) == x;\n\t}\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_safe_integer(duk_double_t x) {\n\t/* >>> 2**53-1\n\t * 9007199254740991\n\t */\n\treturn duk_double_is_integer(x) && DUK_FABS(x) <= 9007199254740991.0;\n}\n\n/* Check whether a duk_double_t is a whole number in the 32-bit range (reject\n * negative zero), and if so, return a duk_int32_t.\n * For compiler use: don't allow negative zero as it will cause trouble with\n * LDINT+LDINTX, positive zero is OK.\n */\nDUK_INTERNAL duk_bool_t duk_is_whole_get_int32_nonegzero(duk_double_t x, duk_int32_t *ival) {\n\tduk_int32_t t;\n\n\tt = duk_double_to_int32_t(x);\n\tif (!((duk_double_t) t == x)) {\n\t\treturn 0;\n\t}\n\tif (t == 0) {\n\t\tduk_double_union du;\n\t\tdu.d = x;\n\t\tif (DUK_DBLUNION_HAS_SIGNBIT(&du)) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\t*ival = t;\n\treturn 1;\n}\n\n/* Check whether a duk_double_t is a whole number in the 32-bit range, and if\n * so, return a duk_int32_t.\n */\nDUK_INTERNAL duk_bool_t duk_is_whole_get_int32(duk_double_t x, duk_int32_t *ival) {\n\tduk_int32_t t;\n\n\tt = duk_double_to_int32_t(x);\n\tif (!((duk_double_t) t == x)) {\n\t\treturn 0;\n\t}\n\t*ival = t;\n\treturn 1;\n}\n\n/* Division: division by zero is undefined behavior (and may in fact trap)\n * so it needs special handling for portability.\n */\n\nDUK_INTERNAL DUK_INLINE duk_double_t duk_double_div(duk_double_t x, duk_double_t y) {\n#if !defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\tif (DUK_UNLIKELY(y == 0.0)) {\n\t\t/* In C99+ division by zero is undefined behavior so\n\t\t * avoid it entirely.  Hopefully the compiler is\n\t\t * smart enough to avoid emitting any actual code\n\t\t * because almost all practical platforms behave as\n\t\t * expected.\n\t\t */\n\t\tif (x > 0.0) {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn -DUK_DOUBLE_INFINITY;\n\t\t\t} else {\n\t\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t\t}\n\t\t} else if (x < 0.0) {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t\t} else {\n\t\t\t\treturn -DUK_DOUBLE_INFINITY;\n\t\t\t}\n\t\t} else {\n\t\t\t/* +/- 0, NaN */\n\t\t\treturn DUK_DOUBLE_NAN;\n\t\t}\n\t}\n#endif\n\n\treturn x / y;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_util_hashbytes.c",
    "content": "/*\n *  Hash function duk_util_hashbytes().\n *\n *  Currently, 32-bit MurmurHash2.\n *\n *  Don't rely on specific hash values; hash function may be endianness\n *  dependent, for instance.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_STRHASH_DENSE)\n/* 'magic' constants for Murmurhash2 */\n#define DUK__MAGIC_M  ((duk_uint32_t) 0x5bd1e995UL)\n#define DUK__MAGIC_R  24\n\nDUK_INTERNAL duk_uint32_t duk_util_hashbytes(const duk_uint8_t *data, duk_size_t len, duk_uint32_t seed) {\n\tduk_uint32_t h = seed ^ ((duk_uint32_t) len);\n\n\twhile (len >= 4) {\n\t\t/* Portability workaround is required for platforms without\n\t\t * unaligned access.  The replacement code emulates little\n\t\t * endian access even on big endian architectures, which is\n\t\t * OK as long as it is consistent for a build.\n\t\t */\n#if defined(DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS)\n\t\tduk_uint32_t k = *((const duk_uint32_t *) (const void *) data);\n#else\n\t\tduk_uint32_t k = ((duk_uint32_t) data[0]) |\n\t\t                 (((duk_uint32_t) data[1]) << 8) |\n\t\t                 (((duk_uint32_t) data[2]) << 16) |\n\t\t                 (((duk_uint32_t) data[3]) << 24);\n#endif\n\n\t\tk *= DUK__MAGIC_M;\n\t\tk ^= k >> DUK__MAGIC_R;\n\t\tk *= DUK__MAGIC_M;\n\t\th *= DUK__MAGIC_M;\n\t\th ^= k;\n\t\tdata += 4;\n\t\tlen -= 4;\n\t}\n\n\tswitch (len) {\n\tcase 3: h ^= data[2] << 16;\n\tcase 2: h ^= data[1] << 8;\n\tcase 1: h ^= data[0];\n\t        h *= DUK__MAGIC_M;\n        }\n\n\th ^= h >> 13;\n\th *= DUK__MAGIC_M;\n\th ^= h >> 15;\n\n\treturn h;\n}\n#endif  /* DUK_USE_STRHASH_DENSE */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_util_memory.c",
    "content": "/*\n *  Memory utils.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL || len == 0U);\n\tDUK_ASSERT(s2 != NULL || len == 0U);\n\treturn DUK_MEMCMP(s1, s2, (size_t) len);\n}\n\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL);\n\tDUK_ASSERT(s2 != NULL);\n\treturn DUK_MEMCMP(s1, s2, (size_t) len);\n}\n#else  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL || len == 0U);\n\tDUK_ASSERT(s2 != NULL || len == 0U);\n\tif (DUK_UNLIKELY(len == 0U)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(s1 != NULL);\n\tDUK_ASSERT(s2 != NULL);\n\treturn duk_memcmp(s1, s2, len);\n}\n\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL);\n\tDUK_ASSERT(s2 != NULL);\n\treturn DUK_MEMCMP(s1, s2, (size_t) len);\n}\n#endif  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_util_misc.c",
    "content": "/*\n *  Misc util stuff.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Lowercase digits for radix values 2 to 36.  Also doubles as lowercase\n *  hex nybble table.\n */\n\nDUK_INTERNAL const duk_uint8_t duk_lc_digits[36] = {\n\tDUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3,\n\tDUK_ASC_4, DUK_ASC_5, DUK_ASC_6, DUK_ASC_7,\n\tDUK_ASC_8, DUK_ASC_9, DUK_ASC_LC_A, DUK_ASC_LC_B,\n\tDUK_ASC_LC_C, DUK_ASC_LC_D, DUK_ASC_LC_E, DUK_ASC_LC_F,\n\tDUK_ASC_LC_G, DUK_ASC_LC_H, DUK_ASC_LC_I, DUK_ASC_LC_J,\n\tDUK_ASC_LC_K, DUK_ASC_LC_L, DUK_ASC_LC_M, DUK_ASC_LC_N,\n\tDUK_ASC_LC_O, DUK_ASC_LC_P, DUK_ASC_LC_Q, DUK_ASC_LC_R,\n\tDUK_ASC_LC_S, DUK_ASC_LC_T, DUK_ASC_LC_U, DUK_ASC_LC_V,\n\tDUK_ASC_LC_W, DUK_ASC_LC_X, DUK_ASC_LC_Y, DUK_ASC_LC_Z\n};\n\nDUK_INTERNAL const duk_uint8_t duk_uc_nybbles[16] = {\n\tDUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3,\n\tDUK_ASC_4, DUK_ASC_5, DUK_ASC_6, DUK_ASC_7,\n\tDUK_ASC_8, DUK_ASC_9, DUK_ASC_UC_A, DUK_ASC_UC_B,\n\tDUK_ASC_UC_C, DUK_ASC_UC_D, DUK_ASC_UC_E, DUK_ASC_UC_F\n};\n\n/*\n *  Table for hex decoding ASCII hex digits\n */\n\nDUK_INTERNAL const duk_int8_t duk_hex_dectab[256] = {\n\t/* -1 if invalid */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x00-0x0f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x10-0x1f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x20-0x2f */\n\t 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,  /* 0x30-0x3f */\n\t-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x40-0x4f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x50-0x5f */\n\t-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x60-0x6f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x70-0x7f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x80-0x8f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x90-0x9f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xa0-0xaf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xb0-0xbf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xc0-0xcf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xd0-0xdf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xe0-0xef */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1   /* 0xf0-0xff */\n};\n\n#if defined(DUK_USE_HEX_FASTPATH)\n/* Preshifted << 4.  Must use 16-bit entry to allow negative value signaling. */\nDUK_INTERNAL const duk_int16_t duk_hex_dectab_shift4[256] = {\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x00-0x0f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x10-0x1f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x20-0x2f */\n\t0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x30-0x3f */\n\t  -1, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x40-0x4f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x50-0x5f */\n\t  -1, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x60-0x6f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x70-0x7f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x80-0x8f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x90-0x9f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xa0-0xaf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xb0-0xbf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xc0-0xcf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xd0-0xdf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xe0-0xef */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1   /* 0xf0-0xff */\n};\n#endif\n\n/*\n *  Table for hex encoding bytes\n */\n\n#if defined(DUK_USE_HEX_FASTPATH)\n/* Lookup to encode one byte directly into 2 characters:\n *\n *   def genhextab(bswap):\n *       for i in xrange(256):\n *           t = chr(i).encode('hex')\n *           if bswap:\n *               t = t[1] + t[0]\n *           print('0x' + t.encode('hex') + 'U')\n *   print('big endian'); genhextab(False)\n *   print('little endian'); genhextab(True)\n*/\nDUK_INTERNAL const duk_uint16_t duk_hex_enctab[256] = {\n#if defined(DUK_USE_INTEGER_BE)\n\t0x3030U, 0x3031U, 0x3032U, 0x3033U, 0x3034U, 0x3035U, 0x3036U, 0x3037U,\n\t0x3038U, 0x3039U, 0x3061U, 0x3062U, 0x3063U, 0x3064U, 0x3065U, 0x3066U,\n\t0x3130U, 0x3131U, 0x3132U, 0x3133U, 0x3134U, 0x3135U, 0x3136U, 0x3137U,\n\t0x3138U, 0x3139U, 0x3161U, 0x3162U, 0x3163U, 0x3164U, 0x3165U, 0x3166U,\n\t0x3230U, 0x3231U, 0x3232U, 0x3233U, 0x3234U, 0x3235U, 0x3236U, 0x3237U,\n\t0x3238U, 0x3239U, 0x3261U, 0x3262U, 0x3263U, 0x3264U, 0x3265U, 0x3266U,\n\t0x3330U, 0x3331U, 0x3332U, 0x3333U, 0x3334U, 0x3335U, 0x3336U, 0x3337U,\n\t0x3338U, 0x3339U, 0x3361U, 0x3362U, 0x3363U, 0x3364U, 0x3365U, 0x3366U,\n\t0x3430U, 0x3431U, 0x3432U, 0x3433U, 0x3434U, 0x3435U, 0x3436U, 0x3437U,\n\t0x3438U, 0x3439U, 0x3461U, 0x3462U, 0x3463U, 0x3464U, 0x3465U, 0x3466U,\n\t0x3530U, 0x3531U, 0x3532U, 0x3533U, 0x3534U, 0x3535U, 0x3536U, 0x3537U,\n\t0x3538U, 0x3539U, 0x3561U, 0x3562U, 0x3563U, 0x3564U, 0x3565U, 0x3566U,\n\t0x3630U, 0x3631U, 0x3632U, 0x3633U, 0x3634U, 0x3635U, 0x3636U, 0x3637U,\n\t0x3638U, 0x3639U, 0x3661U, 0x3662U, 0x3663U, 0x3664U, 0x3665U, 0x3666U,\n\t0x3730U, 0x3731U, 0x3732U, 0x3733U, 0x3734U, 0x3735U, 0x3736U, 0x3737U,\n\t0x3738U, 0x3739U, 0x3761U, 0x3762U, 0x3763U, 0x3764U, 0x3765U, 0x3766U,\n\t0x3830U, 0x3831U, 0x3832U, 0x3833U, 0x3834U, 0x3835U, 0x3836U, 0x3837U,\n\t0x3838U, 0x3839U, 0x3861U, 0x3862U, 0x3863U, 0x3864U, 0x3865U, 0x3866U,\n\t0x3930U, 0x3931U, 0x3932U, 0x3933U, 0x3934U, 0x3935U, 0x3936U, 0x3937U,\n\t0x3938U, 0x3939U, 0x3961U, 0x3962U, 0x3963U, 0x3964U, 0x3965U, 0x3966U,\n\t0x6130U, 0x6131U, 0x6132U, 0x6133U, 0x6134U, 0x6135U, 0x6136U, 0x6137U,\n\t0x6138U, 0x6139U, 0x6161U, 0x6162U, 0x6163U, 0x6164U, 0x6165U, 0x6166U,\n\t0x6230U, 0x6231U, 0x6232U, 0x6233U, 0x6234U, 0x6235U, 0x6236U, 0x6237U,\n\t0x6238U, 0x6239U, 0x6261U, 0x6262U, 0x6263U, 0x6264U, 0x6265U, 0x6266U,\n\t0x6330U, 0x6331U, 0x6332U, 0x6333U, 0x6334U, 0x6335U, 0x6336U, 0x6337U,\n\t0x6338U, 0x6339U, 0x6361U, 0x6362U, 0x6363U, 0x6364U, 0x6365U, 0x6366U,\n\t0x6430U, 0x6431U, 0x6432U, 0x6433U, 0x6434U, 0x6435U, 0x6436U, 0x6437U,\n\t0x6438U, 0x6439U, 0x6461U, 0x6462U, 0x6463U, 0x6464U, 0x6465U, 0x6466U,\n\t0x6530U, 0x6531U, 0x6532U, 0x6533U, 0x6534U, 0x6535U, 0x6536U, 0x6537U,\n\t0x6538U, 0x6539U, 0x6561U, 0x6562U, 0x6563U, 0x6564U, 0x6565U, 0x6566U,\n\t0x6630U, 0x6631U, 0x6632U, 0x6633U, 0x6634U, 0x6635U, 0x6636U, 0x6637U,\n\t0x6638U, 0x6639U, 0x6661U, 0x6662U, 0x6663U, 0x6664U, 0x6665U, 0x6666U\n#else  /* DUK_USE_INTEGER_BE */\n\t0x3030U, 0x3130U, 0x3230U, 0x3330U, 0x3430U, 0x3530U, 0x3630U, 0x3730U,\n\t0x3830U, 0x3930U, 0x6130U, 0x6230U, 0x6330U, 0x6430U, 0x6530U, 0x6630U,\n\t0x3031U, 0x3131U, 0x3231U, 0x3331U, 0x3431U, 0x3531U, 0x3631U, 0x3731U,\n\t0x3831U, 0x3931U, 0x6131U, 0x6231U, 0x6331U, 0x6431U, 0x6531U, 0x6631U,\n\t0x3032U, 0x3132U, 0x3232U, 0x3332U, 0x3432U, 0x3532U, 0x3632U, 0x3732U,\n\t0x3832U, 0x3932U, 0x6132U, 0x6232U, 0x6332U, 0x6432U, 0x6532U, 0x6632U,\n\t0x3033U, 0x3133U, 0x3233U, 0x3333U, 0x3433U, 0x3533U, 0x3633U, 0x3733U,\n\t0x3833U, 0x3933U, 0x6133U, 0x6233U, 0x6333U, 0x6433U, 0x6533U, 0x6633U,\n\t0x3034U, 0x3134U, 0x3234U, 0x3334U, 0x3434U, 0x3534U, 0x3634U, 0x3734U,\n\t0x3834U, 0x3934U, 0x6134U, 0x6234U, 0x6334U, 0x6434U, 0x6534U, 0x6634U,\n\t0x3035U, 0x3135U, 0x3235U, 0x3335U, 0x3435U, 0x3535U, 0x3635U, 0x3735U,\n\t0x3835U, 0x3935U, 0x6135U, 0x6235U, 0x6335U, 0x6435U, 0x6535U, 0x6635U,\n\t0x3036U, 0x3136U, 0x3236U, 0x3336U, 0x3436U, 0x3536U, 0x3636U, 0x3736U,\n\t0x3836U, 0x3936U, 0x6136U, 0x6236U, 0x6336U, 0x6436U, 0x6536U, 0x6636U,\n\t0x3037U, 0x3137U, 0x3237U, 0x3337U, 0x3437U, 0x3537U, 0x3637U, 0x3737U,\n\t0x3837U, 0x3937U, 0x6137U, 0x6237U, 0x6337U, 0x6437U, 0x6537U, 0x6637U,\n\t0x3038U, 0x3138U, 0x3238U, 0x3338U, 0x3438U, 0x3538U, 0x3638U, 0x3738U,\n\t0x3838U, 0x3938U, 0x6138U, 0x6238U, 0x6338U, 0x6438U, 0x6538U, 0x6638U,\n\t0x3039U, 0x3139U, 0x3239U, 0x3339U, 0x3439U, 0x3539U, 0x3639U, 0x3739U,\n\t0x3839U, 0x3939U, 0x6139U, 0x6239U, 0x6339U, 0x6439U, 0x6539U, 0x6639U,\n\t0x3061U, 0x3161U, 0x3261U, 0x3361U, 0x3461U, 0x3561U, 0x3661U, 0x3761U,\n\t0x3861U, 0x3961U, 0x6161U, 0x6261U, 0x6361U, 0x6461U, 0x6561U, 0x6661U,\n\t0x3062U, 0x3162U, 0x3262U, 0x3362U, 0x3462U, 0x3562U, 0x3662U, 0x3762U,\n\t0x3862U, 0x3962U, 0x6162U, 0x6262U, 0x6362U, 0x6462U, 0x6562U, 0x6662U,\n\t0x3063U, 0x3163U, 0x3263U, 0x3363U, 0x3463U, 0x3563U, 0x3663U, 0x3763U,\n\t0x3863U, 0x3963U, 0x6163U, 0x6263U, 0x6363U, 0x6463U, 0x6563U, 0x6663U,\n\t0x3064U, 0x3164U, 0x3264U, 0x3364U, 0x3464U, 0x3564U, 0x3664U, 0x3764U,\n\t0x3864U, 0x3964U, 0x6164U, 0x6264U, 0x6364U, 0x6464U, 0x6564U, 0x6664U,\n\t0x3065U, 0x3165U, 0x3265U, 0x3365U, 0x3465U, 0x3565U, 0x3665U, 0x3765U,\n\t0x3865U, 0x3965U, 0x6165U, 0x6265U, 0x6365U, 0x6465U, 0x6565U, 0x6665U,\n\t0x3066U, 0x3166U, 0x3266U, 0x3366U, 0x3466U, 0x3566U, 0x3666U, 0x3766U,\n\t0x3866U, 0x3966U, 0x6166U, 0x6266U, 0x6366U, 0x6466U, 0x6566U, 0x6666U\n#endif  /* DUK_USE_INTEGER_BE */\n};\n#endif  /* DUK_USE_HEX_FASTPATH */\n\n/*\n *  Arbitrary byteswap for potentially unaligned values\n *\n *  Used to byteswap pointers e.g. in debugger code.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* For now only needed by the debugger. */\nDUK_INTERNAL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len) {\n\tduk_uint8_t tmp;\n\tduk_uint8_t *q = p + len - 1;\n\n\twhile (p - q < 0) {\n\t\ttmp = *p;\n\t\t*p = *q;\n\t\t*q = tmp;\n\t\tp++;\n\t\tq--;\n\t}\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-input/duk_util_tinyrandom.c",
    "content": "/*\n *  A tiny random number generator used for Math.random() and other internals.\n *\n *  Default algorithm is xoroshiro128+: http://xoroshiro.di.unimi.it/xoroshiro128plus.c\n *  with SplitMix64 seed preparation: http://xorshift.di.unimi.it/splitmix64.c.\n *\n *  Low memory targets and targets without 64-bit types use a slightly smaller\n *  (but slower) algorithm by Adi Shamir:\n *  http://www.woodmann.com/forum/archive/index.php/t-3100.html.\n *\n */\n\n#include \"duk_internal.h\"\n\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\n\n#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS)\n#define DUK__RANDOM_SHAMIR3OP\n#else\n#define DUK__RANDOM_XOROSHIRO128PLUS\n#endif\n\n#if defined(DUK__RANDOM_SHAMIR3OP)\n#define DUK__UPDATE_RND(rnd) do { \\\n\t\t(rnd) += ((rnd) * (rnd)) | 0x05UL; \\\n\t\t(rnd) = ((rnd) & 0xffffffffUL);       /* if duk_uint32_t is exactly 32 bits, this is a NOP */ \\\n\t} while (0)\n\n#define DUK__RND_BIT(rnd)  ((rnd) >> 31)  /* only use the highest bit */\n\nDUK_INTERNAL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr) {\n\tDUK_UNREF(thr);  /* Nothing now. */\n}\n\nDUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) {\n\tduk_double_t t;\n\tduk_small_int_t n;\n\tduk_uint32_t rnd;\n\n\trnd = thr->heap->rnd_state;\n\n\tn = 53;  /* enough to cover the whole mantissa */\n\tt = 0.0;\n\n\tdo {\n\t\tDUK__UPDATE_RND(rnd);\n\t\tt += DUK__RND_BIT(rnd);\n\t\tt /= 2.0;\n\t} while (--n);\n\n\tthr->heap->rnd_state = rnd;\n\n\tDUK_ASSERT(t >= (duk_double_t) 0.0);\n\tDUK_ASSERT(t < (duk_double_t) 1.0);\n\n\treturn t;\n}\n#endif  /* DUK__RANDOM_SHAMIR3OP */\n\n#if defined(DUK__RANDOM_XOROSHIRO128PLUS)\nDUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__rnd_splitmix64(duk_uint64_t *x) {\n\tduk_uint64_t z;\n\tz = (*x += DUK_U64_CONSTANT(0x9E3779B97F4A7C15));\n\tz = (z ^ (z >> 30U)) * DUK_U64_CONSTANT(0xBF58476D1CE4E5B9);\n\tz = (z ^ (z >> 27U)) * DUK_U64_CONSTANT(0x94D049BB133111EB);\n\treturn z ^ (z >> 31U);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__rnd_rotl(const duk_uint64_t x, duk_small_uint_t k) {\n\treturn (x << k) | (x >> (64U - k));\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__xoroshiro128plus(duk_uint64_t *s) {\n\tduk_uint64_t s0;\n\tduk_uint64_t s1;\n\tduk_uint64_t res;\n\n\ts0 = s[0];\n\ts1 = s[1];\n\tres = s0 + s1;\n\ts1 ^= s0;\n\ts[0] = duk__rnd_rotl(s0, 55) ^ s1 ^ (s1 << 14U);\n\ts[1] = duk__rnd_rotl(s1, 36);\n\n\treturn res;\n}\n\nDUK_INTERNAL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr) {\n\tduk_small_uint_t i;\n\tduk_uint64_t x;\n\n\t/* Mix both halves of the initial seed with SplitMix64.  The intent\n\t * is to ensure that very similar raw seeds (which is usually the case\n\t * because current seed is Date.now()) result in different xoroshiro128+\n\t * seeds.\n\t */\n\tx = thr->heap->rnd_state[0];  /* Only [0] is used as input here. */\n\tfor (i = 0; i < 64; i++) {\n\t\tthr->heap->rnd_state[i & 0x01] = duk__rnd_splitmix64(&x);  /* Keep last 2 values. */\n\t}\n}\n\nDUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) {\n\tduk_uint64_t v;\n\tduk_double_union du;\n\n\t/* For big and little endian the integer and IEEE double byte order\n\t * is the same so a direct assignment works.  For mixed endian the\n\t * 32-bit parts must be swapped.\n\t */\n\tv = (DUK_U64_CONSTANT(0x3ff) << 52U) | (duk__xoroshiro128plus((duk_uint64_t *) thr->heap->rnd_state) >> 12U);\n\tdu.ull[0] = v;\n#if defined(DUK_USE_DOUBLE_ME)\n\tdo {\n\t\tduk_uint32_t tmp;\n\t\ttmp = du.ui[0];\n\t\tdu.ui[0] = du.ui[1];\n\t\tdu.ui[1] = tmp;\n\t} while (0);\n#endif\n\treturn du.d - 1.0;\n}\n#endif  /* DUK__RANDOM_XOROSHIRO128PLUS */\n\n#endif  /* !DUK_USE_GET_RANDOM_DOUBLE */\n"
  },
  {
    "path": "react_juce/duktape/src-input/duktape.h.in",
    "content": "/*\n *  Duktape public API for Duktape @DUK_VERSION_FORMATTED@.\n *\n *  See the API reference for documentation on call semantics.  The exposed,\n *  supported API is between the \"BEGIN PUBLIC API\" and \"END PUBLIC API\"\n *  comments.  Other parts of the header are Duktape internal and related to\n *  e.g. platform/compiler/feature detection.\n *\n *  Git commit @GIT_COMMIT@ (@GIT_DESCRIBE@).\n *  Git branch @GIT_BRANCH@.\n *\n *  See Duktape AUTHORS.rst and LICENSE.txt for copyright and\n *  licensing information.\n */\n\n/* LICENSE.txt */\n@LICENSE_TXT@\n\n/* AUTHORS.rst */\n@AUTHORS_RST@\n\n#if !defined(DUKTAPE_H_INCLUDED)\n#define DUKTAPE_H_INCLUDED\n\n@DUK_SINGLE_FILE@\n\n/*\n *  BEGIN PUBLIC API\n */\n\n/*\n *  Version and Git commit identification\n */\n\n/* Duktape version, (major * 10000) + (minor * 100) + patch.  Allows C code\n * to #if (DUK_VERSION >= NNN) against Duktape API version.  The same value\n * is also available to ECMAScript code in Duktape.version.  Unofficial\n * development snapshots have 99 for patch level (e.g. 0.10.99 would be a\n * development version after 0.10.0 but before the next official release).\n */\n#define DUK_VERSION                       20400L\n\n/* Git commit, describe, and branch for Duktape build.  Useful for\n * non-official snapshot builds so that application code can easily log\n * which Duktape snapshot was used.  Not available in the ECMAScript\n * environment.\n */\n#define DUK_GIT_COMMIT                    @GIT_COMMIT_CSTRING@\n#define DUK_GIT_DESCRIBE                  @GIT_DESCRIBE_CSTRING@\n#define DUK_GIT_BRANCH                    @GIT_BRANCH_CSTRING@\n\n/* External duk_config.h provides platform/compiler/OS dependent\n * typedefs and macros, and DUK_USE_xxx config options so that\n * the rest of Duktape doesn't need to do any feature detection.\n * DUK_VERSION is defined before including so that configuration\n * snippets can react to it.\n */\n#include \"duk_config.h\"\n\n/*\n *  Avoid C++ name mangling\n */\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/*\n *  Some defines forwarded from feature detection\n */\n\n#undef DUK_API_VARIADIC_MACROS\n#if defined(DUK_USE_VARIADIC_MACROS)\n#define DUK_API_VARIADIC_MACROS\n#endif\n\n#define DUK_API_NORETURN(decl) DUK_NORETURN(decl)\n\n/*\n *  Public API specific typedefs\n *\n *  Many types are wrapped by Duktape for portability to rare platforms\n *  where e.g. 'int' is a 16-bit type.  See practical typing discussion\n *  in Duktape web documentation.\n */\n\nstruct duk_thread_state;\nstruct duk_memory_functions;\nstruct duk_function_list_entry;\nstruct duk_number_list_entry;\nstruct duk_time_components;\n\n/* duk_context is now defined in duk_config.h because it may also be\n * referenced there by prototypes.\n */\ntypedef struct duk_thread_state duk_thread_state;\ntypedef struct duk_memory_functions duk_memory_functions;\ntypedef struct duk_function_list_entry duk_function_list_entry;\ntypedef struct duk_number_list_entry duk_number_list_entry;\ntypedef struct duk_time_components duk_time_components;\n\ntypedef duk_ret_t (*duk_c_function)(duk_context *ctx);\ntypedef void *(*duk_alloc_function) (void *udata, duk_size_t size);\ntypedef void *(*duk_realloc_function) (void *udata, void *ptr, duk_size_t size);\ntypedef void (*duk_free_function) (void *udata, void *ptr);\ntypedef void (*duk_fatal_function) (void *udata, const char *msg);\ntypedef void (*duk_decode_char_function) (void *udata, duk_codepoint_t codepoint);\ntypedef duk_codepoint_t (*duk_map_char_function) (void *udata, duk_codepoint_t codepoint);\ntypedef duk_ret_t (*duk_safe_call_function) (duk_context *ctx, void *udata);\ntypedef duk_size_t (*duk_debug_read_function) (void *udata, char *buffer, duk_size_t length);\ntypedef duk_size_t (*duk_debug_write_function) (void *udata, const char *buffer, duk_size_t length);\ntypedef duk_size_t (*duk_debug_peek_function) (void *udata);\ntypedef void (*duk_debug_read_flush_function) (void *udata);\ntypedef void (*duk_debug_write_flush_function) (void *udata);\ntypedef duk_idx_t (*duk_debug_request_function) (duk_context *ctx, void *udata, duk_idx_t nvalues);\ntypedef void (*duk_debug_detached_function) (duk_context *ctx, void *udata);\n\nstruct duk_thread_state {\n\t/* XXX: Enough space to hold internal suspend/resume structure.\n\t * This is rather awkward and to be fixed when the internal\n\t * structure is visible for the public API header.\n\t */\n\tchar data[128];\n};\n\nstruct duk_memory_functions {\n\tduk_alloc_function alloc_func;\n\tduk_realloc_function realloc_func;\n\tduk_free_function free_func;\n\tvoid *udata;\n};\n\nstruct duk_function_list_entry {\n\tconst char *key;\n\tduk_c_function value;\n\tduk_idx_t nargs;\n};\n\nstruct duk_number_list_entry {\n\tconst char *key;\n\tduk_double_t value;\n};\n\nstruct duk_time_components {\n\tduk_double_t year;          /* year, e.g. 2016, ECMAScript year range */\n\tduk_double_t month;         /* month: 1-12 */\n\tduk_double_t day;           /* day: 1-31 */\n\tduk_double_t hours;         /* hour: 0-59 */\n\tduk_double_t minutes;       /* minute: 0-59 */\n\tduk_double_t seconds;       /* second: 0-59 (in POSIX time no leap second) */\n\tduk_double_t milliseconds;  /* may contain sub-millisecond fractions */\n\tduk_double_t weekday;       /* weekday: 0-6, 0=Sunday, 1=Monday, ..., 6=Saturday */\n};\n\n/*\n *  Constants\n */\n\n/* Duktape debug protocol version used by this build. */\n#define DUK_DEBUG_PROTOCOL_VERSION        2\n\n/* Used to represent invalid index; if caller uses this without checking,\n * this index will map to a non-existent stack entry.  Also used in some\n * API calls as a marker to denote \"no value\".\n */\n#define DUK_INVALID_INDEX                 DUK_IDX_MIN\n\n/* Indicates that a native function does not have a fixed number of args,\n * and the argument stack should not be capped/extended at all.\n */\n#define DUK_VARARGS                       ((duk_int_t) (-1))\n\n/* Number of value stack entries (in addition to actual call arguments)\n * guaranteed to be allocated on entry to a Duktape/C function.\n */\n#define DUK_API_ENTRY_STACK               64U\n\n/* Value types, used by e.g. duk_get_type() */\n#define DUK_TYPE_MIN                      0U\n#define DUK_TYPE_NONE                     0U    /* no value, e.g. invalid index */\n#define DUK_TYPE_UNDEFINED                1U    /* ECMAScript undefined */\n#define DUK_TYPE_NULL                     2U    /* ECMAScript null */\n#define DUK_TYPE_BOOLEAN                  3U    /* ECMAScript boolean: 0 or 1 */\n#define DUK_TYPE_NUMBER                   4U    /* ECMAScript number: double */\n#define DUK_TYPE_STRING                   5U    /* ECMAScript string: CESU-8 / extended UTF-8 encoded */\n#define DUK_TYPE_OBJECT                   6U    /* ECMAScript object: includes objects, arrays, functions, threads */\n#define DUK_TYPE_BUFFER                   7U    /* fixed or dynamic, garbage collected byte buffer */\n#define DUK_TYPE_POINTER                  8U    /* raw void pointer */\n#define DUK_TYPE_LIGHTFUNC                9U    /* lightweight function pointer */\n#define DUK_TYPE_MAX                      9U\n\n/* Value mask types, used by e.g. duk_get_type_mask() */\n#define DUK_TYPE_MASK_NONE                (1U << DUK_TYPE_NONE)\n#define DUK_TYPE_MASK_UNDEFINED           (1U << DUK_TYPE_UNDEFINED)\n#define DUK_TYPE_MASK_NULL                (1U << DUK_TYPE_NULL)\n#define DUK_TYPE_MASK_BOOLEAN             (1U << DUK_TYPE_BOOLEAN)\n#define DUK_TYPE_MASK_NUMBER              (1U << DUK_TYPE_NUMBER)\n#define DUK_TYPE_MASK_STRING              (1U << DUK_TYPE_STRING)\n#define DUK_TYPE_MASK_OBJECT              (1U << DUK_TYPE_OBJECT)\n#define DUK_TYPE_MASK_BUFFER              (1U << DUK_TYPE_BUFFER)\n#define DUK_TYPE_MASK_POINTER             (1U << DUK_TYPE_POINTER)\n#define DUK_TYPE_MASK_LIGHTFUNC           (1U << DUK_TYPE_LIGHTFUNC)\n#define DUK_TYPE_MASK_THROW               (1U << 10)  /* internal flag value: throw if mask doesn't match */\n#define DUK_TYPE_MASK_PROMOTE             (1U << 11)  /* internal flag value: promote to object if mask matches */\n\n/* Coercion hints */\n#define DUK_HINT_NONE                     0    /* prefer number, unless input is a Date, in which\n                                                * case prefer string (E5 Section 8.12.8)\n                                                */\n#define DUK_HINT_STRING                   1    /* prefer string */\n#define DUK_HINT_NUMBER                   2    /* prefer number */\n\n/* Enumeration flags for duk_enum() */\n#define DUK_ENUM_INCLUDE_NONENUMERABLE    (1U << 0)    /* enumerate non-numerable properties in addition to enumerable */\n#define DUK_ENUM_INCLUDE_HIDDEN           (1U << 1)    /* enumerate hidden symbols too (in Duktape 1.x called internal properties) */\n#define DUK_ENUM_INCLUDE_SYMBOLS          (1U << 2)    /* enumerate symbols */\n#define DUK_ENUM_EXCLUDE_STRINGS          (1U << 3)    /* exclude strings */\n#define DUK_ENUM_OWN_PROPERTIES_ONLY      (1U << 4)    /* don't walk prototype chain, only check own properties */\n#define DUK_ENUM_ARRAY_INDICES_ONLY       (1U << 5)    /* only enumerate array indices */\n/* XXX: misleading name */\n#define DUK_ENUM_SORT_ARRAY_INDICES       (1U << 6)    /* sort array indices (applied to full enumeration result, including inherited array indices); XXX: misleading name */\n#define DUK_ENUM_NO_PROXY_BEHAVIOR        (1U << 7)    /* enumerate a proxy object itself without invoking proxy behavior */\n\n/* Compilation flags for duk_compile() and duk_eval() */\n/* DUK_COMPILE_xxx bits 0-2 are reserved for an internal 'nargs' argument.\n */\n#define DUK_COMPILE_EVAL                  (1U << 3)    /* compile eval code (instead of global code) */\n#define DUK_COMPILE_FUNCTION              (1U << 4)    /* compile function code (instead of global code) */\n#define DUK_COMPILE_STRICT                (1U << 5)    /* use strict (outer) context for global, eval, or function code */\n#define DUK_COMPILE_SHEBANG               (1U << 6)    /* allow shebang ('#! ...') comment on first line of source */\n#define DUK_COMPILE_SAFE                  (1U << 7)    /* (internal) catch compilation errors */\n#define DUK_COMPILE_NORESULT              (1U << 8)    /* (internal) omit eval result */\n#define DUK_COMPILE_NOSOURCE              (1U << 9)    /* (internal) no source string on stack */\n#define DUK_COMPILE_STRLEN                (1U << 10)   /* (internal) take strlen() of src_buffer (avoids double evaluation in macro) */\n#define DUK_COMPILE_NOFILENAME            (1U << 11)   /* (internal) no filename on stack */\n#define DUK_COMPILE_FUNCEXPR              (1U << 12)   /* (internal) source is a function expression (used for Function constructor) */\n\n/* Flags for duk_def_prop() and its variants; base flags + a lot of convenience shorthands */\n#define DUK_DEFPROP_WRITABLE              (1U << 0)    /* set writable (effective if DUK_DEFPROP_HAVE_WRITABLE set) */\n#define DUK_DEFPROP_ENUMERABLE            (1U << 1)    /* set enumerable (effective if DUK_DEFPROP_HAVE_ENUMERABLE set) */\n#define DUK_DEFPROP_CONFIGURABLE          (1U << 2)    /* set configurable (effective if DUK_DEFPROP_HAVE_CONFIGURABLE set) */\n#define DUK_DEFPROP_HAVE_WRITABLE         (1U << 3)    /* set/clear writable */\n#define DUK_DEFPROP_HAVE_ENUMERABLE       (1U << 4)    /* set/clear enumerable */\n#define DUK_DEFPROP_HAVE_CONFIGURABLE     (1U << 5)    /* set/clear configurable */\n#define DUK_DEFPROP_HAVE_VALUE            (1U << 6)    /* set value (given on value stack) */\n#define DUK_DEFPROP_HAVE_GETTER           (1U << 7)    /* set getter (given on value stack) */\n#define DUK_DEFPROP_HAVE_SETTER           (1U << 8)    /* set setter (given on value stack) */\n#define DUK_DEFPROP_FORCE                 (1U << 9)    /* force change if possible, may still fail for e.g. virtual properties */\n#define DUK_DEFPROP_SET_WRITABLE          (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE)\n#define DUK_DEFPROP_CLEAR_WRITABLE        DUK_DEFPROP_HAVE_WRITABLE\n#define DUK_DEFPROP_SET_ENUMERABLE        (DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE)\n#define DUK_DEFPROP_CLEAR_ENUMERABLE      DUK_DEFPROP_HAVE_ENUMERABLE\n#define DUK_DEFPROP_SET_CONFIGURABLE      (DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE)\n#define DUK_DEFPROP_CLEAR_CONFIGURABLE    DUK_DEFPROP_HAVE_CONFIGURABLE\n#define DUK_DEFPROP_W                     DUK_DEFPROP_WRITABLE\n#define DUK_DEFPROP_E                     DUK_DEFPROP_ENUMERABLE\n#define DUK_DEFPROP_C                     DUK_DEFPROP_CONFIGURABLE\n#define DUK_DEFPROP_WE                    (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_ENUMERABLE)\n#define DUK_DEFPROP_WC                    (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_CONFIGURABLE)\n#define DUK_DEFPROP_WEC                   (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_CONFIGURABLE)\n#define DUK_DEFPROP_HAVE_W                DUK_DEFPROP_HAVE_WRITABLE\n#define DUK_DEFPROP_HAVE_E                DUK_DEFPROP_HAVE_ENUMERABLE\n#define DUK_DEFPROP_HAVE_C                DUK_DEFPROP_HAVE_CONFIGURABLE\n#define DUK_DEFPROP_HAVE_WE               (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE)\n#define DUK_DEFPROP_HAVE_WC               (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_CONFIGURABLE)\n#define DUK_DEFPROP_HAVE_WEC              (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE)\n#define DUK_DEFPROP_SET_W                 DUK_DEFPROP_SET_WRITABLE\n#define DUK_DEFPROP_SET_E                 DUK_DEFPROP_SET_ENUMERABLE\n#define DUK_DEFPROP_SET_C                 DUK_DEFPROP_SET_CONFIGURABLE\n#define DUK_DEFPROP_SET_WE                (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_ENUMERABLE)\n#define DUK_DEFPROP_SET_WC                (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_CONFIGURABLE)\n#define DUK_DEFPROP_SET_WEC               (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_ENUMERABLE | DUK_DEFPROP_SET_CONFIGURABLE)\n#define DUK_DEFPROP_CLEAR_W               DUK_DEFPROP_CLEAR_WRITABLE\n#define DUK_DEFPROP_CLEAR_E               DUK_DEFPROP_CLEAR_ENUMERABLE\n#define DUK_DEFPROP_CLEAR_C               DUK_DEFPROP_CLEAR_CONFIGURABLE\n#define DUK_DEFPROP_CLEAR_WE              (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_ENUMERABLE)\n#define DUK_DEFPROP_CLEAR_WC              (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_CONFIGURABLE)\n#define DUK_DEFPROP_CLEAR_WEC             (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_ENUMERABLE | DUK_DEFPROP_CLEAR_CONFIGURABLE)\n#define DUK_DEFPROP_ATTR_W                (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_W)\n#define DUK_DEFPROP_ATTR_E                (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_E)\n#define DUK_DEFPROP_ATTR_C                (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_C)\n#define DUK_DEFPROP_ATTR_WE               (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WE)\n#define DUK_DEFPROP_ATTR_WC               (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WC)\n#define DUK_DEFPROP_ATTR_WEC              (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WEC)\n\n/* Flags for duk_push_thread_raw() */\n#define DUK_THREAD_NEW_GLOBAL_ENV         (1U << 0)    /* create a new global environment */\n\n/* Flags for duk_gc() */\n#define DUK_GC_COMPACT                    (1U << 0)    /* compact heap objects */\n\n/* Error codes (must be 8 bits at most, see duk_error.h) */\n#define DUK_ERR_NONE                      0    /* no error (e.g. from duk_get_error_code()) */\n#define DUK_ERR_ERROR                     1    /* Error */\n#define DUK_ERR_EVAL_ERROR                2    /* EvalError */\n#define DUK_ERR_RANGE_ERROR               3    /* RangeError */\n#define DUK_ERR_REFERENCE_ERROR           4    /* ReferenceError */\n#define DUK_ERR_SYNTAX_ERROR              5    /* SyntaxError */\n#define DUK_ERR_TYPE_ERROR                6    /* TypeError */\n#define DUK_ERR_URI_ERROR                 7    /* URIError */\n\n/* Return codes for C functions (shortcut for throwing an error) */\n#define DUK_RET_ERROR                     (-DUK_ERR_ERROR)\n#define DUK_RET_EVAL_ERROR                (-DUK_ERR_EVAL_ERROR)\n#define DUK_RET_RANGE_ERROR               (-DUK_ERR_RANGE_ERROR)\n#define DUK_RET_REFERENCE_ERROR           (-DUK_ERR_REFERENCE_ERROR)\n#define DUK_RET_SYNTAX_ERROR              (-DUK_ERR_SYNTAX_ERROR)\n#define DUK_RET_TYPE_ERROR                (-DUK_ERR_TYPE_ERROR)\n#define DUK_RET_URI_ERROR                 (-DUK_ERR_URI_ERROR)\n\n/* Return codes for protected calls (duk_safe_call(), duk_pcall()) */\n#define DUK_EXEC_SUCCESS                  0\n#define DUK_EXEC_ERROR                    1\n\n/* Debug levels for DUK_USE_DEBUG_WRITE(). */\n#define DUK_LEVEL_DEBUG                   0\n#define DUK_LEVEL_DDEBUG                  1\n#define DUK_LEVEL_DDDEBUG                 2\n\n/*\n *  Macros to create Symbols as C statically constructed strings.\n *\n *  Call e.g. as DUK_HIDDEN_SYMBOL(\"myProperty\") <=> (\"\\xFF\" \"myProperty\").\n *\n *  Local symbols have a unique suffix, caller should take care to avoid\n *  conflicting with the Duktape internal representation by e.g. prepending\n *  a '!' character: DUK_LOCAL_SYMBOL(\"myLocal\", \"!123\").\n *\n *  Note that these can only be used for string constants, not dynamically\n *  created strings.\n *\n *  You shouldn't normally use DUK_INTERNAL_SYMBOL() at all.  It is reserved\n *  for Duktape internal symbols only.  There are no versioning guarantees\n *  for internal symbols.\n */\n\n#define DUK_HIDDEN_SYMBOL(x)     (\"\\xFF\" x)\n#define DUK_GLOBAL_SYMBOL(x)     (\"\\x80\" x)\n#define DUK_LOCAL_SYMBOL(x,uniq) (\"\\x81\" x \"\\xff\" uniq)\n#define DUK_WELLKNOWN_SYMBOL(x)  (\"\\x81\" x \"\\xff\")\n#define DUK_INTERNAL_SYMBOL(x)   (\"\\x82\" x)\n\n/*\n *  If no variadic macros, __FILE__ and __LINE__ are passed through globals\n *  which is ugly and not thread safe.\n */\n\n#if !defined(DUK_API_VARIADIC_MACROS)\nDUK_EXTERNAL_DECL const char *duk_api_global_filename;\nDUK_EXTERNAL_DECL duk_int_t duk_api_global_line;\n#endif\n\n/*\n *  Context management\n */\n\nDUK_EXTERNAL_DECL\nduk_context *duk_create_heap(duk_alloc_function alloc_func,\n                             duk_realloc_function realloc_func,\n                             duk_free_function free_func,\n                             void *heap_udata,\n                             duk_fatal_function fatal_handler);\nDUK_EXTERNAL_DECL void duk_destroy_heap(duk_context *ctx);\n\nDUK_EXTERNAL_DECL void duk_suspend(duk_context *ctx, duk_thread_state *state);\nDUK_EXTERNAL_DECL void duk_resume(duk_context *ctx, const duk_thread_state *state);\n\n#define duk_create_heap_default() \\\n\tduk_create_heap(NULL, NULL, NULL, NULL, NULL)\n\n/*\n *  Memory management\n *\n *  Raw functions have no side effects (cannot trigger GC).\n */\n\nDUK_EXTERNAL_DECL void *duk_alloc_raw(duk_context *ctx, duk_size_t size);\nDUK_EXTERNAL_DECL void duk_free_raw(duk_context *ctx, void *ptr);\nDUK_EXTERNAL_DECL void *duk_realloc_raw(duk_context *ctx, void *ptr, duk_size_t size);\nDUK_EXTERNAL_DECL void *duk_alloc(duk_context *ctx, duk_size_t size);\nDUK_EXTERNAL_DECL void duk_free(duk_context *ctx, void *ptr);\nDUK_EXTERNAL_DECL void *duk_realloc(duk_context *ctx, void *ptr, duk_size_t size);\nDUK_EXTERNAL_DECL void duk_get_memory_functions(duk_context *ctx, duk_memory_functions *out_funcs);\nDUK_EXTERNAL_DECL void duk_gc(duk_context *ctx, duk_uint_t flags);\n\n/*\n *  Error handling\n */\n\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_throw_raw(duk_context *ctx));\n#define duk_throw(ctx) \\\n\t(duk_throw_raw((ctx)), (duk_ret_t) 0)\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_fatal_raw(duk_context *ctx, const char *err_msg));\n#define duk_fatal(ctx,err_msg) \\\n\t(duk_fatal_raw((ctx), (err_msg)), (duk_ret_t) 0)\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...));\n\n#if defined(DUK_API_VARIADIC_MACROS)\n#define duk_error(ctx,err_code,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_generic_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_eval_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_EVAL_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_range_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_RANGE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_reference_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_REFERENCE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_syntax_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_SYNTAX_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_type_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_TYPE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_uri_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_URI_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#else  /* DUK_API_VARIADIC_MACROS */\n/* For legacy compilers without variadic macros a macro hack is used to allow\n * variable arguments.  While the macro allows \"return duk_error(...)\", it\n * will fail with e.g. \"(void) duk_error(...)\".  The calls are noreturn but\n * with a return value to allow the \"return duk_error(...)\" idiom.  This may\n * cause some compiler warnings, but without noreturn the generated code is\n * often worse.  The same approach as with variadic macros (using\n * \"(duk_error(...), 0)\") won't work due to the macro hack structure.\n */\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_error_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_generic_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_eval_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_range_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_reference_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_syntax_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_type_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_uri_error_stash(duk_context *ctx, const char *fmt, ...));\n#define duk_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_error_stash)  /* last value is func pointer, arguments follow in parens */\n#define duk_generic_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_generic_error_stash)\n#define duk_eval_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_eval_error_stash)\n#define duk_range_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_range_error_stash)\n#define duk_reference_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_reference_error_stash)\n#define duk_syntax_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_syntax_error_stash)\n#define duk_type_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_type_error_stash)\n#define duk_uri_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_uri_error_stash)\n#endif  /* DUK_API_VARIADIC_MACROS */\n\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_va_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap));\n\n#define duk_error_va(ctx,err_code,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_generic_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_eval_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_EVAL_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_range_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_RANGE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_reference_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_REFERENCE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_syntax_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_SYNTAX_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_type_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_TYPE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_uri_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_URI_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n\n/*\n *  Other state related functions\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_strict_call(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_constructor_call(duk_context *ctx);\n\n/*\n *  Stack management\n */\n\nDUK_EXTERNAL_DECL duk_idx_t duk_normalize_index(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_valid_index(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_require_valid_index(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL duk_idx_t duk_get_top(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_set_top(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_idx_t duk_get_top_index(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_require_top_index(duk_context *ctx);\n\n/* Although extra/top could be an unsigned type here, using a signed type\n * makes the API more robust to calling code calculation errors or corner\n * cases (where caller might occasionally come up with negative values).\n * Negative values are treated as zero, which is better than casting them\n * to a large unsigned number.  (This principle is used elsewhere in the\n * API too.)\n */\nDUK_EXTERNAL_DECL duk_bool_t duk_check_stack(duk_context *ctx, duk_idx_t extra);\nDUK_EXTERNAL_DECL void duk_require_stack(duk_context *ctx, duk_idx_t extra);\nDUK_EXTERNAL_DECL duk_bool_t duk_check_stack_top(duk_context *ctx, duk_idx_t top);\nDUK_EXTERNAL_DECL void duk_require_stack_top(duk_context *ctx, duk_idx_t top);\n\n/*\n *  Stack manipulation (other than push/pop)\n */\n\nDUK_EXTERNAL_DECL void duk_swap(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL void duk_swap_top(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_dup(duk_context *ctx, duk_idx_t from_idx);\nDUK_EXTERNAL_DECL void duk_dup_top(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_insert(duk_context *ctx, duk_idx_t to_idx);\nDUK_EXTERNAL_DECL void duk_replace(duk_context *ctx, duk_idx_t to_idx);\nDUK_EXTERNAL_DECL void duk_copy(duk_context *ctx, duk_idx_t from_idx, duk_idx_t to_idx);\nDUK_EXTERNAL_DECL void duk_remove(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_xcopymove_raw(duk_context *to_ctx, duk_context *from_ctx, duk_idx_t count, duk_bool_t is_copy);\n\n#define duk_xmove_top(to_ctx,from_ctx,count) \\\n\tduk_xcopymove_raw((to_ctx), (from_ctx), (count), 0 /*is_copy*/)\n#define duk_xcopy_top(to_ctx,from_ctx,count) \\\n\tduk_xcopymove_raw((to_ctx), (from_ctx), (count), 1 /*is_copy*/)\n\n/*\n *  Push operations\n *\n *  Push functions return the absolute (relative to bottom of frame)\n *  position of the pushed value for convenience.\n *\n *  Note: duk_dup() is technically a push.\n */\n\nDUK_EXTERNAL_DECL void duk_push_undefined(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_null(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_boolean(duk_context *ctx, duk_bool_t val);\nDUK_EXTERNAL_DECL void duk_push_true(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_false(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_number(duk_context *ctx, duk_double_t val);\nDUK_EXTERNAL_DECL void duk_push_nan(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_int(duk_context *ctx, duk_int_t val);\nDUK_EXTERNAL_DECL void duk_push_uint(duk_context *ctx, duk_uint_t val);\nDUK_EXTERNAL_DECL const char *duk_push_string(duk_context *ctx, const char *str);\nDUK_EXTERNAL_DECL const char *duk_push_lstring(duk_context *ctx, const char *str, duk_size_t len);\nDUK_EXTERNAL_DECL void duk_push_pointer(duk_context *ctx, void *p);\nDUK_EXTERNAL_DECL const char *duk_push_sprintf(duk_context *ctx, const char *fmt, ...);\nDUK_EXTERNAL_DECL const char *duk_push_vsprintf(duk_context *ctx, const char *fmt, va_list ap);\n\n/* duk_push_literal() may evaluate its argument (a C string literal) more than\n * once on purpose.  When speed is preferred, sizeof() avoids an unnecessary\n * strlen() at runtime.  Sizeof(\"foo\") == 4, so subtract 1.  The argument\n * must be non-NULL and should not contain internal NUL characters as the\n * behavior will then depend on config options.\n */\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_push_literal(ctx,cstring)  duk_push_string((ctx), (cstring))\n#else\nDUK_EXTERNAL_DECL const char *duk_push_literal_raw(duk_context *ctx, const char *str, duk_size_t len);\n#define duk_push_literal(ctx,cstring)  duk_push_literal_raw((ctx), (cstring), sizeof((cstring)) - 1U)\n#endif\n\nDUK_EXTERNAL_DECL void duk_push_this(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_new_target(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_current_function(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_current_thread(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_global_object(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_heap_stash(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_global_stash(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_thread_stash(duk_context *ctx, duk_context *target_ctx);\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_object(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_bare_object(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_array(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_bare_array(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_c_function(duk_context *ctx, duk_c_function func, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_c_lightfunc(duk_context *ctx, duk_c_function func, duk_idx_t nargs, duk_idx_t length, duk_int_t magic);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_thread_raw(duk_context *ctx, duk_uint_t flags);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_proxy(duk_context *ctx, duk_uint_t proxy_flags);\n\n#define duk_push_thread(ctx) \\\n\tduk_push_thread_raw((ctx), 0 /*flags*/)\n\n#define duk_push_thread_new_globalenv(ctx) \\\n\tduk_push_thread_raw((ctx), DUK_THREAD_NEW_GLOBAL_ENV /*flags*/)\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...);\n\n#if defined(DUK_API_VARIADIC_MACROS)\n#define duk_push_error_object(ctx,err_code,...)  \\\n\tduk_push_error_object_raw((ctx), (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__)\n#else\nDUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...);\n/* Note: parentheses are required so that the comma expression works in assignments. */\n#define duk_push_error_object  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_push_error_object_stash)  /* last value is func pointer, arguments follow in parens */\n#endif\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_va_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap);\n#define duk_push_error_object_va(ctx,err_code,fmt,ap)  \\\n\tduk_push_error_object_va_raw((ctx), (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap))\n\n#define DUK_BUF_FLAG_DYNAMIC   (1 << 0)    /* internal flag: dynamic buffer */\n#define DUK_BUF_FLAG_EXTERNAL  (1 << 1)    /* internal flag: external buffer */\n#define DUK_BUF_FLAG_NOZERO    (1 << 2)    /* internal flag: don't zero allocated buffer */\n\nDUK_EXTERNAL_DECL void *duk_push_buffer_raw(duk_context *ctx, duk_size_t size, duk_small_uint_t flags);\n\n#define duk_push_buffer(ctx,size,dynamic) \\\n\tduk_push_buffer_raw((ctx), (size), (dynamic) ? DUK_BUF_FLAG_DYNAMIC : 0)\n#define duk_push_fixed_buffer(ctx,size) \\\n\tduk_push_buffer_raw((ctx), (size), 0 /*flags*/)\n#define duk_push_dynamic_buffer(ctx,size) \\\n\tduk_push_buffer_raw((ctx), (size), DUK_BUF_FLAG_DYNAMIC /*flags*/)\n#define duk_push_external_buffer(ctx) \\\n\t((void) duk_push_buffer_raw((ctx), 0, DUK_BUF_FLAG_DYNAMIC | DUK_BUF_FLAG_EXTERNAL))\n\n#define DUK_BUFOBJ_ARRAYBUFFER         0\n#define DUK_BUFOBJ_NODEJS_BUFFER       1\n#define DUK_BUFOBJ_DATAVIEW            2\n#define DUK_BUFOBJ_INT8ARRAY           3\n#define DUK_BUFOBJ_UINT8ARRAY          4\n#define DUK_BUFOBJ_UINT8CLAMPEDARRAY   5\n#define DUK_BUFOBJ_INT16ARRAY          6\n#define DUK_BUFOBJ_UINT16ARRAY         7\n#define DUK_BUFOBJ_INT32ARRAY          8\n#define DUK_BUFOBJ_UINT32ARRAY         9\n#define DUK_BUFOBJ_FLOAT32ARRAY        10\n#define DUK_BUFOBJ_FLOAT64ARRAY        11\n\nDUK_EXTERNAL_DECL void duk_push_buffer_object(duk_context *ctx, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags);\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_heapptr(duk_context *ctx, void *ptr);\n\n/*\n *  Pop operations\n */\n\nDUK_EXTERNAL_DECL void duk_pop(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_pop_n(duk_context *ctx, duk_idx_t count);\nDUK_EXTERNAL_DECL void duk_pop_2(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_pop_3(duk_context *ctx);\n\n/*\n *  Type checks\n *\n *  duk_is_none(), which would indicate whether index it outside of stack,\n *  is not needed; duk_is_valid_index() gives the same information.\n */\n\nDUK_EXTERNAL_DECL duk_int_t duk_get_type(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_check_type(duk_context *ctx, duk_idx_t idx, duk_int_t type);\nDUK_EXTERNAL_DECL duk_uint_t duk_get_type_mask(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_check_type_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t mask);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_undefined(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_null(duk_context *ctx, duk_idx_t idx);\n#define duk_is_null_or_undefined(ctx, idx) \\\n\t((duk_get_type_mask((ctx), (idx)) & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED)) ? 1 : 0)\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_nan(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_object(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_buffer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_buffer_data(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_lightfunc(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_symbol(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_array(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_c_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_ecmascript_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_bound_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_thread(duk_context *ctx, duk_idx_t idx);\n\n#define duk_is_callable(ctx,idx) \\\n\tduk_is_function((ctx), (idx))\nDUK_EXTERNAL_DECL duk_bool_t duk_is_constructable(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_fixed_buffer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_external_buffer(duk_context *ctx, duk_idx_t idx);\n\n/* Buffers and lightfuncs are not considered primitive because they mimic\n * objects and e.g. duk_to_primitive() will coerce them instead of returning\n * them as is.  Symbols are represented as strings internally.\n */\n#define duk_is_primitive(ctx,idx) \\\n\tduk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_UNDEFINED | \\\n\t                                  DUK_TYPE_MASK_NULL | \\\n\t                                  DUK_TYPE_MASK_BOOLEAN | \\\n\t                                  DUK_TYPE_MASK_NUMBER | \\\n\t                                  DUK_TYPE_MASK_STRING | \\\n\t                                  DUK_TYPE_MASK_POINTER)\n\n/* Symbols are object coercible, covered by DUK_TYPE_MASK_STRING. */\n#define duk_is_object_coercible(ctx,idx) \\\n\tduk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_BOOLEAN | \\\n\t                                  DUK_TYPE_MASK_NUMBER | \\\n\t                                  DUK_TYPE_MASK_STRING | \\\n\t                                  DUK_TYPE_MASK_OBJECT | \\\n\t                                  DUK_TYPE_MASK_BUFFER | \\\n\t                                  DUK_TYPE_MASK_POINTER | \\\n\t                                  DUK_TYPE_MASK_LIGHTFUNC)\n\nDUK_EXTERNAL_DECL duk_errcode_t duk_get_error_code(duk_context *ctx, duk_idx_t idx);\n#define duk_is_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) != 0)\n#define duk_is_eval_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_EVAL_ERROR)\n#define duk_is_range_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_RANGE_ERROR)\n#define duk_is_reference_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_REFERENCE_ERROR)\n#define duk_is_syntax_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_SYNTAX_ERROR)\n#define duk_is_type_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_TYPE_ERROR)\n#define duk_is_uri_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_URI_ERROR)\n\n/*\n *  Get operations: no coercion, returns default value for invalid\n *  indices and invalid value types.\n *\n *  duk_get_undefined() and duk_get_null() would be pointless and\n *  are not included.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_double_t duk_get_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int_t duk_get_int(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint_t duk_get_uint(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_get_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_get_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL void *duk_get_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_get_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_get_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_c_function duk_get_c_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_context *duk_get_context(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void *duk_get_heapptr(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Get-with-explicit default operations: like get operations but with an\n *  explicit default value.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_boolean_default(duk_context *ctx, duk_idx_t idx, duk_bool_t def_value);\nDUK_EXTERNAL_DECL duk_double_t duk_get_number_default(duk_context *ctx, duk_idx_t idx, duk_double_t def_value);\nDUK_EXTERNAL_DECL duk_int_t duk_get_int_default(duk_context *ctx, duk_idx_t idx, duk_int_t def_value);\nDUK_EXTERNAL_DECL duk_uint_t duk_get_uint_default(duk_context *ctx, duk_idx_t idx, duk_uint_t def_value);\nDUK_EXTERNAL_DECL const char *duk_get_string_default(duk_context *ctx, duk_idx_t idx, const char *def_value);\nDUK_EXTERNAL_DECL const char *duk_get_lstring_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_get_buffer_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_get_buffer_data_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_get_pointer_default(duk_context *ctx, duk_idx_t idx, void *def_value);\nDUK_EXTERNAL_DECL duk_c_function duk_get_c_function_default(duk_context *ctx, duk_idx_t idx, duk_c_function def_value);\nDUK_EXTERNAL_DECL duk_context *duk_get_context_default(duk_context *ctx, duk_idx_t idx, duk_context *def_value);\nDUK_EXTERNAL_DECL void *duk_get_heapptr_default(duk_context *ctx, duk_idx_t idx, void *def_value);\n\n/*\n *  Opt operations: like require operations but with an explicit default value\n *  when value is undefined or index is invalid, null and non-matching types\n *  cause a TypeError.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_opt_boolean(duk_context *ctx, duk_idx_t idx, duk_bool_t def_value);\nDUK_EXTERNAL_DECL duk_double_t duk_opt_number(duk_context *ctx, duk_idx_t idx, duk_double_t def_value);\nDUK_EXTERNAL_DECL duk_int_t duk_opt_int(duk_context *ctx, duk_idx_t idx, duk_int_t def_value);\nDUK_EXTERNAL_DECL duk_uint_t duk_opt_uint(duk_context *ctx, duk_idx_t idx, duk_uint_t def_value);\nDUK_EXTERNAL_DECL const char *duk_opt_string(duk_context *ctx, duk_idx_t idx, const char *def_ptr);\nDUK_EXTERNAL_DECL const char *duk_opt_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_opt_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size);\nDUK_EXTERNAL_DECL void *duk_opt_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size);\nDUK_EXTERNAL_DECL void *duk_opt_pointer(duk_context *ctx, duk_idx_t idx, void *def_value);\nDUK_EXTERNAL_DECL duk_c_function duk_opt_c_function(duk_context *ctx, duk_idx_t idx, duk_c_function def_value);\nDUK_EXTERNAL_DECL duk_context *duk_opt_context(duk_context *ctx, duk_idx_t idx, duk_context *def_value);\nDUK_EXTERNAL_DECL void *duk_opt_heapptr(duk_context *ctx, duk_idx_t idx, void *def_value);\n\n/*\n *  Require operations: no coercion, throw error if index or type\n *  is incorrect.  No defaulting.\n */\n\n#define duk_require_type_mask(ctx,idx,mask) \\\n\t((void) duk_check_type_mask((ctx), (idx), (mask) | DUK_TYPE_MASK_THROW))\n\nDUK_EXTERNAL_DECL void duk_require_undefined(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_require_null(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_require_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_double_t duk_require_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int_t duk_require_int(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint_t duk_require_uint(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_require_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_require_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL void duk_require_object(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void *duk_require_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_require_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_require_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_c_function duk_require_c_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_context *duk_require_context(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_require_function(duk_context *ctx, duk_idx_t idx);\n#define duk_require_callable(ctx,idx) \\\n\tduk_require_function((ctx), (idx))\nDUK_EXTERNAL_DECL void duk_require_constructor_call(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_require_constructable(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void *duk_require_heapptr(duk_context *ctx, duk_idx_t idx);\n\n/* Symbols are object coercible and covered by DUK_TYPE_MASK_STRING. */\n#define duk_require_object_coercible(ctx,idx) \\\n\t((void) duk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_BOOLEAN | \\\n\t                                            DUK_TYPE_MASK_NUMBER | \\\n\t                                            DUK_TYPE_MASK_STRING | \\\n\t                                            DUK_TYPE_MASK_OBJECT | \\\n\t                                            DUK_TYPE_MASK_BUFFER | \\\n\t                                            DUK_TYPE_MASK_POINTER | \\\n\t                                            DUK_TYPE_MASK_LIGHTFUNC | \\\n\t                                            DUK_TYPE_MASK_THROW))\n\n/*\n *  Coercion operations: in-place coercion, return coerced value where\n *  applicable.  If index is invalid, throw error.  Some coercions may\n *  throw an expected error (e.g. from a toString() or valueOf() call)\n *  or an internal error (e.g. from out of memory).\n */\n\nDUK_EXTERNAL_DECL void duk_to_undefined(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_to_null(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_to_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_double_t duk_to_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int_t duk_to_int(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint_t duk_to_uint(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int32_t duk_to_int32(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint32_t duk_to_uint32(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint16_t duk_to_uint16(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_to_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, duk_uint_t flags);\nDUK_EXTERNAL_DECL void *duk_to_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_to_object(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_to_primitive(duk_context *ctx, duk_idx_t idx, duk_int_t hint);\n\n#define DUK_BUF_MODE_FIXED      0   /* internal: request fixed buffer result */\n#define DUK_BUF_MODE_DYNAMIC    1   /* internal: request dynamic buffer result */\n#define DUK_BUF_MODE_DONTCARE   2   /* internal: don't care about fixed/dynamic nature */\n\n#define duk_to_buffer(ctx,idx,out_size) \\\n\tduk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_DONTCARE)\n#define duk_to_fixed_buffer(ctx,idx,out_size) \\\n\tduk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_FIXED)\n#define duk_to_dynamic_buffer(ctx,idx,out_size) \\\n\tduk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_DYNAMIC)\n\n/* safe variants of a few coercion operations */\nDUK_EXTERNAL_DECL const char *duk_safe_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL const char *duk_to_stacktrace(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_safe_to_stacktrace(duk_context *ctx, duk_idx_t idx);\n#define duk_safe_to_string(ctx,idx) \\\n\tduk_safe_to_lstring((ctx), (idx), NULL)\n\n/*\n *  Value length\n */\n\nDUK_EXTERNAL_DECL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t idx, duk_size_t len);\n#if 0\n/* duk_require_length()? */\n/* duk_opt_length()? */\n#endif\n\n/*\n *  Misc conversion\n */\n\nDUK_EXTERNAL_DECL const char *duk_base64_encode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_base64_decode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_hex_encode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_hex_decode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_json_encode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_json_decode(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL const char *duk_buffer_to_string(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Buffer\n */\n\nDUK_EXTERNAL_DECL void *duk_resize_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t new_size);\nDUK_EXTERNAL_DECL void *duk_steal_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void duk_config_buffer(duk_context *ctx, duk_idx_t idx, void *ptr, duk_size_t len);\n\n/*\n *  Property access\n *\n *  The basic function assumes key is on stack.  The _(l)string variant takes\n *  a C string as a property name; the _literal variant takes a C literal.\n *  The _index variant takes an array index as a property name (e.g. 123 is\n *  equivalent to the key \"123\").  The _heapptr variant takes a raw, borrowed\n *  heap pointer.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_get_prop_literal(ctx,obj_idx,key)  duk_get_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_get_prop_literal(ctx,obj_idx,key)  duk_get_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_put_prop_literal(ctx,obj_idx,key)  duk_put_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_put_prop_literal(ctx,obj_idx,key)  duk_put_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_del_prop_literal(ctx,obj_idx,key)  duk_del_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_del_prop_literal(ctx,obj_idx,key)  duk_del_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_has_prop_literal(ctx,obj_idx,key)  duk_has_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_has_prop_literal(ctx,obj_idx,key)  duk_has_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\n\nDUK_EXTERNAL_DECL void duk_get_prop_desc(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags);\nDUK_EXTERNAL_DECL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_string(duk_context *ctx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_get_global_literal(ctx,key)  duk_get_global_string((ctx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_literal_raw(duk_context *ctx, const char *key, duk_size_t key_len);\n#define duk_get_global_literal(ctx,key)  duk_get_global_literal_raw((ctx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_heapptr(duk_context *ctx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_string(duk_context *ctx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_put_global_literal(ctx,key)  duk_put_global_string((ctx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_literal_raw(duk_context *ctx, const char *key, duk_size_t key_len);\n#define duk_put_global_literal(ctx,key)  duk_put_global_literal_raw((ctx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_heapptr(duk_context *ctx, void *ptr);\n\n/*\n *  Inspection\n */\n\nDUK_EXTERNAL_DECL void duk_inspect_value(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_inspect_callstack_entry(duk_context *ctx, duk_int_t level);\n\n/*\n *  Object prototype\n */\n\nDUK_EXTERNAL_DECL void duk_get_prototype(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_prototype(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Object finalizer\n */\n\nDUK_EXTERNAL_DECL void duk_get_finalizer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_finalizer(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Global object\n */\n\nDUK_EXTERNAL_DECL void duk_set_global_object(duk_context *ctx);\n\n/*\n *  Duktape/C function magic value\n */\n\nDUK_EXTERNAL_DECL duk_int_t duk_get_magic(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_magic(duk_context *ctx, duk_idx_t idx, duk_int_t magic);\nDUK_EXTERNAL_DECL duk_int_t duk_get_current_magic(duk_context *ctx);\n\n/*\n *  Module helpers: put multiple function or constant properties\n */\n\nDUK_EXTERNAL_DECL void duk_put_function_list(duk_context *ctx, duk_idx_t obj_idx, const duk_function_list_entry *funcs);\nDUK_EXTERNAL_DECL void duk_put_number_list(duk_context *ctx, duk_idx_t obj_idx, const duk_number_list_entry *numbers);\n\n/*\n *  Object operations\n */\n\nDUK_EXTERNAL_DECL void duk_compact(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL void duk_enum(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t enum_flags);\nDUK_EXTERNAL_DECL duk_bool_t duk_next(duk_context *ctx, duk_idx_t enum_idx, duk_bool_t get_value);\nDUK_EXTERNAL_DECL void duk_seal(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL void duk_freeze(duk_context *ctx, duk_idx_t obj_idx);\n\n/*\n *  String manipulation\n */\n\nDUK_EXTERNAL_DECL void duk_concat(duk_context *ctx, duk_idx_t count);\nDUK_EXTERNAL_DECL void duk_join(duk_context *ctx, duk_idx_t count);\nDUK_EXTERNAL_DECL void duk_decode_string(duk_context *ctx, duk_idx_t idx, duk_decode_char_function callback, void *udata);\nDUK_EXTERNAL_DECL void duk_map_string(duk_context *ctx, duk_idx_t idx, duk_map_char_function callback, void *udata);\nDUK_EXTERNAL_DECL void duk_substring(duk_context *ctx, duk_idx_t idx, duk_size_t start_char_offset, duk_size_t end_char_offset);\nDUK_EXTERNAL_DECL void duk_trim(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_codepoint_t duk_char_code_at(duk_context *ctx, duk_idx_t idx, duk_size_t char_offset);\n\n/*\n *  ECMAScript operators\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL duk_bool_t duk_strict_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL duk_bool_t duk_samevalue(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL duk_bool_t duk_instanceof(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\n\n/*\n *  Random\n */\n\nDUK_EXTERNAL_DECL duk_double_t duk_random(duk_context *ctx);\n\n/*\n *  Function (method) calls\n */\n\nDUK_EXTERNAL_DECL void duk_call(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL void duk_call_method(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL void duk_call_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pcall(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pcall_method(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pcall_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL void duk_new(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pnew(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets);\n\n/*\n *  Thread management\n */\n\n/* There are currently no native functions to yield/resume, due to the internal\n * limitations on coroutine handling.  These will be added later.\n */\n\n/*\n *  Compilation and evaluation\n */\n\nDUK_EXTERNAL_DECL duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags);\nDUK_EXTERNAL_DECL duk_int_t duk_compile_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags);\n\n/* plain */\n#define duk_eval(ctx)  \\\n\t((void) duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOFILENAME))\n\n#define duk_eval_noresult(ctx)  \\\n\t((void) duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval(ctx)  \\\n\t(duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_noresult(ctx)  \\\n\t(duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile(ctx,flags)  \\\n\t((void) duk_compile_raw((ctx), NULL, 0, 2 /*args*/ | (flags)))\n\n#define duk_pcompile(ctx,flags)  \\\n\t(duk_compile_raw((ctx), NULL, 0, 2 /*args*/ | (flags) | DUK_COMPILE_SAFE))\n\n/* string */\n#define duk_eval_string(ctx,src)  \\\n\t((void) duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_eval_string_noresult(ctx,src)  \\\n\t((void) duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_string(ctx,src)  \\\n\t(duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_string_noresult(ctx,src)  \\\n\t(duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_string(ctx,flags,src)  \\\n\t((void) duk_compile_raw((ctx), (src), 0, 0 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_string_filename(ctx,flags,src)  \\\n\t((void) duk_compile_raw((ctx), (src), 0, 1 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN))\n\n#define duk_pcompile_string(ctx,flags,src)  \\\n\t(duk_compile_raw((ctx), (src), 0, 0 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_pcompile_string_filename(ctx,flags,src)  \\\n\t(duk_compile_raw((ctx), (src), 0, 1 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN))\n\n/* lstring */\n#define duk_eval_lstring(ctx,buf,len)  \\\n\t((void) duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME))\n\n#define duk_eval_lstring_noresult(ctx,buf,len)  \\\n\t((void) duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_lstring(ctx,buf,len)  \\\n\t(duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_SAFE | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_lstring_noresult(ctx,buf,len)  \\\n\t(duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_lstring(ctx,flags,buf,len)  \\\n\t((void) duk_compile_raw((ctx), buf, len, 0 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_lstring_filename(ctx,flags,buf,len)  \\\n\t((void) duk_compile_raw((ctx), buf, len, 1 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE))\n\n#define duk_pcompile_lstring(ctx,flags,buf,len)  \\\n\t(duk_compile_raw((ctx), buf, len, 0 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME))\n\n#define duk_pcompile_lstring_filename(ctx,flags,buf,len)  \\\n\t(duk_compile_raw((ctx), buf, len, 1 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE))\n\n/*\n *  Bytecode load/dump\n */\n\nDUK_EXTERNAL_DECL void duk_dump_function(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_load_function(duk_context *ctx);\n\n/*\n *  Debugging\n */\n\nDUK_EXTERNAL_DECL void duk_push_context_dump(duk_context *ctx);\n\n/*\n *  Debugger (debug protocol)\n */\n\nDUK_EXTERNAL_DECL void duk_debugger_attach(duk_context *ctx,\n                                           duk_debug_read_function read_cb,\n                                           duk_debug_write_function write_cb,\n                                           duk_debug_peek_function peek_cb,\n                                           duk_debug_read_flush_function read_flush_cb,\n                                           duk_debug_write_flush_function write_flush_cb,\n                                           duk_debug_request_function request_cb,\n                                           duk_debug_detached_function detached_cb,\n                                           void *udata);\nDUK_EXTERNAL_DECL void duk_debugger_detach(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_debugger_cooperate(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_bool_t duk_debugger_notify(duk_context *ctx, duk_idx_t nvalues);\nDUK_EXTERNAL_DECL void duk_debugger_pause(duk_context *ctx);\n\n/*\n *  Time handling\n */\n\nDUK_EXTERNAL_DECL duk_double_t duk_get_now(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_time_to_components(duk_context *ctx, duk_double_t timeval, duk_time_components *comp);\nDUK_EXTERNAL_DECL duk_double_t duk_components_to_time(duk_context *ctx, duk_time_components *comp);\n\n/*\n *  Date provider related constants\n *\n *  NOTE: These are \"semi public\" - you should only use these if you write\n *  your own platform specific Date provider, see doc/datetime.rst.\n */\n\n/* Millisecond count constants. */\n#define DUK_DATE_MSEC_SECOND          1000L\n#define DUK_DATE_MSEC_MINUTE          (60L * 1000L)\n#define DUK_DATE_MSEC_HOUR            (60L * 60L * 1000L)\n#define DUK_DATE_MSEC_DAY             (24L * 60L * 60L * 1000L)\n\n/* ECMAScript date range is 100 million days from Epoch:\n * > 100e6 * 24 * 60 * 60 * 1000  // 100M days in millisecs\n * 8640000000000000\n * (= 8.64e15)\n */\n#define DUK_DATE_MSEC_100M_DAYS         (8.64e15)\n#define DUK_DATE_MSEC_100M_DAYS_LEEWAY  (8.64e15 + 24 * 3600e3)\n\n/* ECMAScript year range:\n * > new Date(100e6 * 24 * 3600e3).toISOString()\n * '+275760-09-13T00:00:00.000Z'\n * > new Date(-100e6 * 24 * 3600e3).toISOString()\n * '-271821-04-20T00:00:00.000Z'\n */\n#define DUK_DATE_MIN_ECMA_YEAR     (-271821L)\n#define DUK_DATE_MAX_ECMA_YEAR     275760L\n\n/* Part indices for internal breakdowns.  Part order from DUK_DATE_IDX_YEAR\n * to DUK_DATE_IDX_MILLISECOND matches argument ordering of ECMAScript API\n * calls (like Date constructor call).  Some functions in duk_bi_date.c\n * depend on the specific ordering, so change with care.  16 bits are not\n * enough for all parts (year, specifically).\n *\n * Must be in-sync with genbuiltins.py.\n */\n#define DUK_DATE_IDX_YEAR           0  /* year */\n#define DUK_DATE_IDX_MONTH          1  /* month: 0 to 11 */\n#define DUK_DATE_IDX_DAY            2  /* day within month: 0 to 30 */\n#define DUK_DATE_IDX_HOUR           3\n#define DUK_DATE_IDX_MINUTE         4\n#define DUK_DATE_IDX_SECOND         5\n#define DUK_DATE_IDX_MILLISECOND    6\n#define DUK_DATE_IDX_WEEKDAY        7  /* weekday: 0 to 6, 0=sunday, 1=monday, etc */\n#define DUK_DATE_IDX_NUM_PARTS      8\n\n/* Internal API call flags, used for various functions in duk_bi_date.c.\n * Certain flags are used by only certain functions, but since the flags\n * don't overlap, a single flags value can be passed around to multiple\n * functions.\n *\n * The unused top bits of the flags field are also used to pass values\n * to helpers (duk__get_part_helper() and duk__set_part_helper()).\n *\n * Must be in-sync with genbuiltins.py.\n */\n\n/* NOTE: when writing a Date provider you only need a few specific\n * flags from here, the rest are internal.  Avoid using anything you\n * don't need.\n */\n\n#define DUK_DATE_FLAG_NAN_TO_ZERO          (1 << 0)  /* timeval breakdown: internal time value NaN -> zero */\n#define DUK_DATE_FLAG_NAN_TO_RANGE_ERROR   (1 << 1)  /* timeval breakdown: internal time value NaN -> RangeError (toISOString) */\n#define DUK_DATE_FLAG_ONEBASED             (1 << 2)  /* timeval breakdown: convert month and day-of-month parts to one-based (default is zero-based) */\n#define DUK_DATE_FLAG_EQUIVYEAR            (1 << 3)  /* timeval breakdown: replace year with equivalent year in the [1971,2037] range for DST calculations */\n#define DUK_DATE_FLAG_LOCALTIME            (1 << 4)  /* convert time value to local time */\n#define DUK_DATE_FLAG_SUB1900              (1 << 5)  /* getter: subtract 1900 from year when getting year part */\n#define DUK_DATE_FLAG_TOSTRING_DATE        (1 << 6)  /* include date part in string conversion result */\n#define DUK_DATE_FLAG_TOSTRING_TIME        (1 << 7)  /* include time part in string conversion result */\n#define DUK_DATE_FLAG_TOSTRING_LOCALE      (1 << 8)  /* use locale specific formatting if available */\n#define DUK_DATE_FLAG_TIMESETTER           (1 << 9)  /* setter: call is a time setter (affects hour, min, sec, ms); otherwise date setter (affects year, month, day-in-month) */\n#define DUK_DATE_FLAG_YEAR_FIXUP           (1 << 10) /* setter: perform 2-digit year fixup (00...99 -> 1900...1999) */\n#define DUK_DATE_FLAG_SEP_T                (1 << 11) /* string conversion: use 'T' instead of ' ' as a separator */\n#define DUK_DATE_FLAG_VALUE_SHIFT          12        /* additional values begin at bit 12 */\n\n/*\n *  ROM pointer compression\n */\n\n/* Support array for ROM pointer compression.  Only declared when ROM\n * pointer compression is active.\n */\n#if defined(DUK_USE_ROM_OBJECTS) && defined(DUK_USE_HEAPPTR16)\nDUK_EXTERNAL_DECL const void * const duk_rom_compressed_pointers[];\n#endif\n\n/*\n *  C++ name mangling\n */\n\n#if defined(__cplusplus)\n/* end 'extern \"C\"' wrapper */\n}\n#endif\n\n/*\n *  END PUBLIC API\n */\n\n#endif  /* DUKTAPE_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-input/strings.yaml",
    "content": "#\n#  Built-in strings\n#\n#  String data is always quoted for clarity.  Codepoints U+0000...U+00FF\n#  are identified with bytes 1:1 to allow even invalid UTF-8 strings to\n#  be represented.  Internal strings are represented as Symbols with a\n#  structured markup to avoid exposing the specific internal format (which\n#  begins with a 0x82 byte since Duktape 2.2).\n#\n#  Built-in strings can be mostly scanned automatically based on what\n#  strings built-in objects need, but there are also dependencies on\n#  certain built-in strings in C code (DUK_HTHREAD_STRING_XXX()) which\n#  are scanned using an external utility src/scan_used_stridx.py.\n#  Besides knowing the plain string values, metadata on some strings\n#  matters for built-in data generation, e.g. some strings must have\n#  an 8-bit string index.\n#\n\nstrings:\n\n  # --- Standard built-in object related strings ---\n\n  # internal class values\n  - str: \"Undefined\"  # sort of\n    class_name: true\n  - str: \"Null\"       # sort of\n    class_name: true\n  - str: \"Object\"\n    class_name: true\n  - str: \"Function\"\n    class_name: true\n  - str: \"Array\"\n    class_name: true\n  - str: \"String\"\n    class_name: true\n  - str: \"Symbol\"\n    class_name: true\n    es6: true\n  - str: \"Boolean\"\n    class_name: true\n  - str: \"Number\"\n    class_name: true\n  - str: \"Date\"\n    class_name: true\n  - str: \"RegExp\"\n    class_name: true\n  - str: \"Error\"\n    class_name: true\n  - str: \"Math\"\n    class_name: true\n  - str: \"JSON\"\n    class_name: true\n  - str: \"Arguments\"\n    class_name: true\n\n  # built-in object names\n  - str: \"Object\"\n  - str: \"Function\"\n  - str: \"Array\"\n  - str: \"String\"\n  - str: \"Boolean\"\n  - str: \"Number\"\n  - str: \"Date\"\n  - str: \"RegExp\"\n  - str: \"Error\"\n  - str: \"EvalError\"\n  - str: \"RangeError\"\n  - str: \"ReferenceError\"\n  - str: \"SyntaxError\"\n  - str: \"TypeError\"\n  - str: \"URIError\"\n  - str: \"Math\"\n  - str: \"JSON\"\n\n  # Global object\n  - str: \"eval\"\n  - str: \"parseInt\"\n  - str: \"parseFloat\"\n  - str: \"isNaN\"\n  - str: \"isFinite\"\n  - str: \"decodeURI\"\n  - str: \"decodeURIComponent\"\n  - str: \"encodeURI\"\n  - str: \"encodeURIComponent\"\n  - str: \"escape\"\n  - str: \"unescape\"\n\n  # Object constructor\n  - str: \"length\"\n  - str: \"prototype\"\n  - str: \"getPrototypeOf\"\n  - str: \"getOwnPropertyDescriptor\"\n  - str: \"getOwnPropertyNames\"\n  - str: \"create\"\n  - str: \"defineProperty\"\n  - str: \"defineProperties\"\n  - str: \"seal\"\n  - str: \"freeze\"\n  - str: \"preventExtensions\"\n  - str: \"isSealed\"\n  - str: \"isFrozen\"\n  - str: \"isExtensible\"\n  - str: \"keys\"\n\n  # Property descriptors\n  - str: \"value\"\n  - str: \"writable\"\n  - str: \"configurable\"\n  - str: \"enumerable\"\n  - str: \"get\"\n  - str: \"set\"\n\n  # Object prototype\n  - str: \"constructor\"\n  - str: \"toString\"\n  - str: \"toLocaleString\"\n  - str: \"valueOf\"\n  - str: \"hasOwnProperty\"\n  - str: \"isPrototypeOf\"\n  - str: \"propertyIsEnumerable\"\n\n  # Object instances - no special properties\n\n  # Function constructor\n  - str: \"length\"\n  - str: \"prototype\"\n\n  # Function prototype\n  - str: \"constructor\"\n  - str: \"toString\"\n  - str: \"apply\"\n  - str: \"call\"\n  - str: \"bind\"\n\n  # Function instances\n  - str: \"length\"\n  - str: \"prototype\"\n  - str: \"caller\"  # bind() generated instances\n  - str: \"arguments\"  # bind() generated instances\n\n  # Array constructor\n  - str: \"length\"\n  - str: \"prototype\"\n  - str: \"isArray\"\n\n  # Array prototype\n  - str: \"constructor\"\n  - str: \"toString\"\n  - str: \"toLocaleString\"\n  - str: \"concat\"\n  - str: \"join\"\n  - str: \"pop\"\n  - str: \"push\"\n  - str: \"reverse\"\n  - str: \"shift\"\n  - str: \"slice\"\n  - str: \"sort\"\n  - str: \"splice\"\n  - str: \"unshift\"\n  - str: \"indexOf\"\n  - str: \"lastIndexOf\"\n  - str: \"every\"\n  - str: \"some\"\n  - str: \"forEach\"\n  - str: \"map\"\n  - str: \"filter\"\n  - str: \"reduce\"\n  - str: \"reduceRight\"\n\n  # Array instances\n  - str: \"length\"\n\n  # String constructor\n  - str: \"length\"\n  - str: \"prototype\"\n  - str: \"fromCharCode\"\n\n  # String prototype\n  - str: \"constructor\"\n  - str: \"toString\"\n  - str: \"valueOf\"\n  - str: \"charAt\"\n  - str: \"charCodeAt\"\n  - str: \"concat\"\n  - str: \"indexOf\"\n  - str: \"lastIndexOf\"\n  - str: \"localeCompare\"\n  - str: \"match\"\n  - str: \"replace\"\n  - str: \"search\"\n  - str: \"slice\"\n  - str: \"split\"\n  - str: \"substring\"\n  - str: \"toLowerCase\"\n  - str: \"toLocaleLowerCase\"\n  - str: \"toUpperCase\"\n  - str: \"toLocaleUpperCase\"\n  - str: \"trim\"\n  - str: \"substr\"\n    section_b: true\n\n  # String instances\n  - str: \"length\"\n\n  # Boolean constructor\n  - str: \"length\"\n  - str: \"prototype\"\n\n  # Boolean prototype\n  - str: \"constructor\"\n  - str: \"toString\"\n  - str: \"valueOf\"\n\n  # Boolean instances - no special properties\n\n  # Number constructor\n  - str: \"length\"\n  - str: \"prototype\"\n  - str: \"MAX_VALUE\"\n  - str: \"MIN_VALUE\"\n  - str: \"NaN\"\n  - str: \"NEGATIVE_INFINITY\"\n  - str: \"POSITIVE_INFINITY\"\n\n  # Number prototype\n  - str: \"constructor\"\n  - str: \"toString\"\n  - str: \"toLocaleString\"\n  - str: \"valueOf\"\n  - str: \"toFixed\"\n  - str: \"toExponential\"\n  - str: \"toPrecision\"\n\n  # Number instances - no special properties\n\n  # Date constructor\n  - str: \"length\"\n  - str: \"prototype\"\n  - str: \"parse\"\n  - str: \"UTC\"\n  - str: \"now\"\n\n  # Date prototype\n  - str: \"constructor\"\n  - str: \"toString\"\n  - str: \"toDateString\"\n  - str: \"toTimeString\"\n  - str: \"toLocaleString\"\n  - str: \"toLocaleDateString\"\n  - str: \"toLocaleTimeString\"\n  - str: \"valueOf\"\n  - str: \"getTime\"\n  - str: \"getFullYear\"\n  - str: \"getUTCFullYear\"\n  - str: \"getMonth\"\n  - str: \"getUTCMonth\"\n  - str: \"getDate\"\n  - str: \"getUTCDate\"\n  - str: \"getDay\"\n  - str: \"getUTCDay\"\n  - str: \"getHours\"\n  - str: \"getUTCHours\"\n  - str: \"getMinutes\"\n  - str: \"getUTCMinutes\"\n  - str: \"getSeconds\"\n  - str: \"getUTCSeconds\"\n  - str: \"getMilliseconds\"\n  - str: \"getUTCMilliseconds\"\n  - str: \"getTimezoneOffset\"\n  - str: \"setTime\"\n  - str: \"setMilliseconds\"\n  - str: \"setUTCMilliseconds\"\n  - str: \"setSeconds\"\n  - str: \"setUTCSeconds\"\n  - str: \"setMinutes\"\n  - str: \"setUTCMinutes\"\n  - str: \"setHours\"\n  - str: \"setUTCHours\"\n  - str: \"setDate\"\n  - str: \"setUTCDate\"\n  - str: \"setMonth\"\n  - str: \"setUTCMonth\"\n  - str: \"setFullYear\"\n  - str: \"setUTCFullYear\"\n  - str: \"toUTCString\"\n  - str: \"toISOString\"\n  - str: \"toJSON\"\n  - str: \"getYear\"\n    section_b: true\n  - str: \"setYear\"\n    section_b: true\n  - str: \"toGMTString\"\n    section_b: true\n\n  # Date instances - no special properties\n\n  # RegExp constructor\n  - str: \"length\"\n  - str: \"prototype\"\n\n  # RegExp prototype\n  - str: \"constructor\"\n  - str: \"exec\"\n  - str: \"test\"\n  - str: \"toString\"\n\n  # RegExp instances\n  - str: \"source\"\n  - str: \"global\"\n  - str: \"ignoreCase\"\n  - str: \"multiline\"\n  - str: \"lastIndex\"\n  - str: \"flags\"\n#  - str: \"unicode\"\n#  - str: \"sticky\"\n\n  # RegExp exec() results\n  - str: \"index\"\n  - str: \"input\"\n\n  # Error constructor\n  - str: \"length\"\n  - str: \"prototype\"\n\n  # Error prototype\n  - str: \"constructor\"\n  - str: \"name\"\n  - str: \"message\"\n  - str: \"toString\"\n\n  # Error instances - no special properties\n\n  # Error prototype / error fields (apply to all native errors in the spec)\n  - str: \"name\"\n  - str: \"message\"\n\n  # Math object\n  - str: \"E\"\n  - str: \"LN10\"\n  - str: \"LN2\"\n  - str: \"LOG2E\"\n  - str: \"LOG10E\"\n  - str: \"PI\"\n  - str: \"SQRT1_2\"\n  - str: \"SQRT2\"\n  - str: \"abs\"\n  - str: \"acos\"\n  - str: \"asin\"\n  - str: \"atan\"\n  - str: \"atan2\"\n  - str: \"ceil\"\n  - str: \"cos\"\n  - str: \"exp\"\n  - str: \"floor\"\n  - str: \"log\"\n  - str: \"max\"\n  - str: \"min\"\n  - str: \"pow\"\n  - str: \"random\"\n  - str: \"round\"\n  - str: \"sin\"\n  - str: \"sqrt\"\n  - str: \"tan\"\n\n  # JSON object\n  - str: \"parse\"\n  - str: \"stringify\"\n\n  # --- Other standard related strings ---\n\n  # typeof - these produce unfortunate naming conflicts like \"Object\" vs \"object\"\n  - str: \"undefined\"\n  - str: \"boolean\"\n  - str: \"number\"\n  - str: \"string\"\n  - str: \"symbol\"\n    es6: true\n  - str: \"object\"    # also returned for typeof null\n  - str: \"function\"\n\n  # type related\n  - str: \"undefined\"\n  - str: \"null\"\n  - str: \"true\"\n  - str: \"false\"\n\n  # special values\n  - str: \"length\"\n  - str: \"NaN\"\n  - str: \"Infinity\"\n  - str: \"+Infinity\"\n  - str: \"-Infinity\"\n  - str: \"0\"\n  - str: \"+0\"\n  - str: \"-0\"\n  - str: \"\"        # used as a class name for unused/invalid class\n    class_name: true\n  - str: \",\"       # for array joining\n  - str: \"\\n    \"  # for tracebacks\n  - str: \"[...]\"   # for tracebacks\n  - str: \"Invalid Date\"  # for invalid Date instances\n\n  # arguments object (E5 Section 10.6)\n  - str: \"arguments\"\n  - str: \"callee\"\n  - str: \"caller\"\n\n  # \"set\" and \"get\" are strings we need in object literals but they are not\n  # ReservedWords.\n  - str: \"get\"\n  - str: \"set\"\n\n  # --- ES2015 specific strings ---\n\n  # Proxy\n  - str: \"Proxy\"\n    es6: true\n  #- str: \"revocable\"\n  #  es6: true\n\n  # Proxy trap names (ES2015 Section 9.5)\n  #- str: \"getPrototypeOf\"\n  #  es6: true\n  #- str: \"setPrototypeOf\"\n  #  es6: true\n  #- str: \"isExtensible\"\n  #  es6: true\n  #- str: \"preventExtensions\"\n  #  es6: true\n  #- str: \"getOwnPropertyDescriptor\"\n  #  es6: true\n  - str: \"has\"\n    es6: true\n  - str: \"get\"\n    es6: true\n  - str: \"set\"\n    es6: true\n  - str: \"deleteProperty\"\n    es6: true\n  #- str: \"defineProperty\"\n  #  es6: true\n  #- str: \"enumerate\"   # obsoleted in ES2016\n  #  es6: true\n  - str: \"ownKeys\"\n    es6: true\n  - str: \"apply\"\n    es6: true\n  - str: \"construct\"\n    es6: true\n  \n  - str: \"Reflect\"\n    es6: true\n  - str: \"apply\"\n    es6: true\n  - str: \"construct\"\n    es6: true\n  - str: \"defineProperty\"\n    es6: true\n  - str: \"deleteProperty\"\n    es6: true\n  - str: \"get\"\n    es6: true\n  - str: \"getOwnPropertyDescriptor\"\n    es6: true\n  - str: \"getPrototypeOf\"\n    es6: true\n  - str: \"has\"\n    es6: true\n  - str: \"isExtensible\"\n    es6: true\n  - str: \"ownKeys\"\n    es6: true\n  - str: \"preventExtensions\"\n    es6: true\n  - str: \"set\"\n    es6: true\n  - str: \"setPrototypeOf\"\n    es6: true\n\n  # Well-known symbols\n  - str:\n      type: symbol\n      variant: wellknown\n      string: \"Symbol.toPrimitive\"\n  - str:\n      type: symbol\n      variant: wellknown\n      string: \"Symbol.hasInstance\"\n  - str:\n      type: symbol\n      variant: wellknown\n      string: \"Symbol.toStringTag\"\n  - str:\n      type: symbol\n      variant: wellknown\n      string: \"Symbol.isConcatSpreadable\"\n\n  # Misc\n  - str: \"setPrototypeOf\"\n    es6: true\n  - str: \"__proto__\"\n    es6: true\n\n  # --- Node.js Buffer / TypedArray related strings ---\n\n  # Node.js class\n  - str: \"Buffer\"\n    class_name: true\n    nodejs_buffer: true\n\n  # Node.js Buffer constructor\n  - str: \"concat\"\n    nodejs_buffer: true\n  - str: \"isEncoding\"\n    nodejs_buffer: true\n  - str: \"isBuffer\"\n    nodejs_buffer: true\n  - str: \"byteLength\"\n    nodejs_buffer: true\n  - str: \"compare\"\n    nodejs_buffer: true\n\n  # Node.js Buffer prototype\n  - str: \"toString\"\n    nodejs_buffer: true\n  - str: \"toJSON\"\n    nodejs_buffer: true\n  - str: \"write\"\n    nodejs_buffer: true\n  - str: \"fill\"\n    nodejs_buffer: true\n  - str: \"equals\"\n    nodejs_buffer: true\n  - str: \"compare\"\n    nodejs_buffer: true\n  - str: \"copy\"\n    nodejs_buffer: true\n  - str: \"slice\"\n    nodejs_buffer: true\n  - str: \"readUInt8\"\n    nodejs_buffer: true\n  - str: \"readInt8\"\n    nodejs_buffer: true\n  - str: \"readUInt16LE\"\n    nodejs_buffer: true\n  - str: \"readUInt16BE\"\n    nodejs_buffer: true\n  - str: \"readInt16LE\"\n    nodejs_buffer: true\n  - str: \"readInt16BE\"\n    nodejs_buffer: true\n  - str: \"readUInt32LE\"\n    nodejs_buffer: true\n  - str: \"readUInt32BE\"\n    nodejs_buffer: true\n  - str: \"readInt32LE\"\n    nodejs_buffer: true\n  - str: \"readInt32BE\"\n    nodejs_buffer: true\n  - str: \"readFloatLE\"\n    nodejs_buffer: true\n  - str: \"readFloatBE\"\n    nodejs_buffer: true\n  - str: \"readDoubleLE\"\n    nodejs_buffer: true\n  - str: \"readDoubleBE\"\n    nodejs_buffer: true\n  - str: \"readUIntLE\"\n    nodejs_buffer: true\n  - str: \"readUIntBE\"\n    nodejs_buffer: true\n  - str: \"readIntLE\"\n    nodejs_buffer: true\n  - str: \"readIntBE\"\n    nodejs_buffer: true\n  - str: \"writeUInt8\"\n    nodejs_buffer: true\n  - str: \"writeInt8\"\n    nodejs_buffer: true\n  - str: \"writeUInt16LE\"\n    nodejs_buffer: true\n  - str: \"writeUInt16BE\"\n    nodejs_buffer: true\n  - str: \"writeInt16LE\"\n    nodejs_buffer: true\n  - str: \"writeInt16BE\"\n    nodejs_buffer: true\n  - str: \"writeUInt32LE\"\n    nodejs_buffer: true\n  - str: \"writeUInt32BE\"\n    nodejs_buffer: true\n  - str: \"writeInt32LE\"\n    nodejs_buffer: true\n  - str: \"writeInt32BE\"\n    nodejs_buffer: true\n  - str: \"writeFloatLE\"\n    nodejs_buffer: true\n  - str: \"writeFloatBE\"\n    nodejs_buffer: true\n  - str: \"writeDoubleLE\"\n    nodejs_buffer: true\n  - str: \"writeDoubleBE\"\n    nodejs_buffer: true\n  - str: \"writeUIntLE\"\n    nodejs_buffer: true\n  - str: \"writeUIntBE\"\n    nodejs_buffer: true\n  - str: \"writeIntLE\"\n    nodejs_buffer: true\n  - str: \"writeIntBE\"\n    nodejs_buffer: true\n\n  # Node.js toJSON()\n  - str: \"type\"\n    nodejs_buffer: true\n  - str: \"data\"\n    nodejs_buffer: true\n\n  # TypedArray classes\n  - str: \"ArrayBuffer\"\n    class_name: true\n    typed_array: true\n  - str: \"DataView\"\n    class_name: true\n    typed_array: true\n  - str: \"Int8Array\"\n    class_name: true\n    typed_array: true\n  - str: \"Uint8Array\"\n    class_name: true\n    typed_array: true\n  - str: \"Uint8ClampedArray\"\n    class_name: true\n    typed_array: true\n  - str: \"Int16Array\"\n    class_name: true\n    typed_array: true\n  - str: \"Uint16Array\"\n    class_name: true\n    typed_array: true\n  - str: \"Int32Array\"\n    class_name: true\n    typed_array: true\n  - str: \"Uint32Array\"\n    class_name: true\n    typed_array: true\n  - str: \"Float32Array\"\n    class_name: true\n    typed_array: true\n  - str: \"Float64Array\"\n    class_name: true\n    typed_array: true\n\n  # TypedArray ArrayBuffer constructor\n  - str: \"isView\"\n    typed_array: true\n\n  # TypedArray ArrayBuffer instance\n  - str: \"slice\"\n    typed_array: true\n\n  # TypedArray ArrayBufferView shared\n  - str: \"buffer\"\n    typed_array: true\n  - str: \"length\"\n    typed_array: true\n  #- str: \"byteLength\"\n  #  typed_array: true\n  #- str: \"byteOffset\"\n  #  typed_array: true\n  #- str: \"BYTES_PER_ELEMENT\"\n  #  typed_array: true\n\n  # TypedArray TypedArray (e.g. Uint8Array)\n  - str: \"set\"\n    typed_array: true\n  - str: \"subarray\"\n    typed_array: true\n\n  # TypedArray DataView\n  - str: \"getInt8\"\n    typed_array: true\n  - str: \"getUint8\"\n    typed_array: true\n  - str: \"getInt16\"\n    typed_array: true\n  - str: \"getUint16\"\n    typed_array: true\n  - str: \"getInt32\"\n    typed_array: true\n  - str: \"getUint32\"\n    typed_array: true\n  - str: \"getFloat32\"\n    typed_array: true\n  - str: \"getFloat64\"\n    typed_array: true\n  - str: \"setInt8\"\n    typed_array: true\n  - str: \"setUint8\"\n    typed_array: true\n  - str: \"setInt16\"\n    typed_array: true\n  - str: \"setUint16\"\n    typed_array: true\n  - str: \"setInt32\"\n    typed_array: true\n  - str: \"setUint32\"\n    typed_array: true\n  - str: \"setFloat32\"\n    typed_array: true\n  - str: \"setFloat64\"\n    typed_array: true\n\n  # --- Duktape specific strings ---\n\n  # non-standard global properties\n  - str: \"Duktape\"\n    duktape: true\n\n  # non-standard class values\n  - str: \"global\"  # implementation specific but shared by e.g. smjs and V8\n    duktape: true\n    class_name: true\n  - str: \"ObjEnv\"\n    duktape: true\n    class_name: true\n  - str: \"DecEnv\"\n    duktape: true\n    class_name: true\n  - str: \"Buffer\"\n    duktape: true\n    class_name: true\n  - str: \"Pointer\"\n    duktape: true\n    class_name: true\n  - str: \"Thread\"\n    duktape: true\n    class_name: true\n\n  # non-standard built-in object names\n  - str: \"ThrowTypeError\"  # implementation specific, matches V8\n    duktape: true\n\n  # non-standard error object (or Error.prototype) properties\n  - str: \"stack\"\n    duktape: true\n  - str: \"pc\"\n    duktape: true\n  - str: \"fileName\"\n    duktape: true\n  - str: \"lineNumber\"\n    duktape: true\n  #- str: \"code\"\n  #  duktape: true\n  - str:\n      type: symbol\n      variant: hidden\n      string: \"Tracedata\"\n    duktape: true\n    internal: true\n\n  # non-standard function instance properties\n  - str: \"name\"  # function declaration/expression name (or empty)\n    duktape: true\n  - str: \"fileName\"  # filename associated with function (shown in tracebacks)\n    duktape: true\n\n  # typeof - these produce unfortunate naming conflicts like \"Object\" vs \"object\"\n  #- str: \"buffer\"   # no longer used in Duktape 2.x for typeof (typeof plainBuffer -> 'object' instead)\n  #  duktape: true\n  - str: \"pointer\"\n    duktape: true\n\n  # GETPROPC delayed error, can use any shared hidden Symbol that can never\n  # occur in used visible values (which may be thrown and thus trigger special\n  # handling).  At present, use _Target which is only used by enumerator\n  # objects and nothing user visible.\n  - str:\n      type: symbol\n      variant: hidden\n      string: \"Target\"\n    duktape: true\n    internal: true\n\n  # internal property for primitive value (Boolean, Number, String)\n  - str:\n      type: symbol\n      variant: hidden\n      string: \"Value\"\n    duktape: true\n    internal: true\n\n  # internal properties for enumerator objects\n  - str:\n      type: symbol\n      variant: hidden\n      string: \"Target\"\n    duktape: true\n    internal: true\n  - str:\n      type: symbol\n      variant: hidden\n      string: \"Next\"\n    duktape: true\n    internal: true\n\n  # internal properties for RegExp instances\n  - str:\n      type: symbol\n      variant: hidden\n      string: \"Bytecode\"\n    duktape: true\n    internal: true\n\n  # internal properties for function objects\n  - str:\n      type: symbol\n      variant: hidden\n      string: \"Formals\"\n    duktape: true\n    internal: true\n  - str:\n      type: symbol\n      variant: hidden\n      string: \"Varmap\"\n    duktape: true\n    internal: true\n  - str:\n      type: symbol\n      variant: hidden\n      string: \"Source\"\n    duktape: true\n    internal: true\n  - str:\n      type: symbol\n      variant: hidden\n      string: \"Pc2line\"\n    duktape: true\n    internal: true\n\n  # internal properties for thread objects\n\n  # internal properties for argument objects\n  - str:\n      type: symbol\n      variant: hidden\n      string: \"Map\"\n    duktape: true\n    internal: true\n  - str:\n      type: symbol\n      variant: hidden\n      string: \"Varenv\"\n    duktape: true\n    internal: true\n  - str:\n      type: symbol\n      variant: hidden\n      string: \"Callee\"\n    duktape: true\n    internal: true\n\n  # internal properties for general objects\n  #- str:\n  #    type: symbol\n  #    variant: hidden\n  #    string: \"Metatable\"\n  #  duktape: true\n  #  internal: true\n  - str:\n      type: symbol\n      variant: hidden\n      string: \"Finalizer\"\n    duktape: true\n    internal: true\n\n  # internal property used for GETPROPC created error objects to delay\n  # their throwing (intentionally reuse an existing property name)\n  - str:\n      type: symbol\n      variant: hidden\n      string: \"Value\"\n    duktape: true\n    internal: true\n\n  # fake filename for compiled functions\n  - str: \"compile\"    # used as a filename for functions created with Function constructor\n    duktape: true\n  - str: \"input\"      # used as a filename for eval temp function\n    duktape: true\n\n  # Duktape object\n  - str: \"errCreate\"\n    duktape: true\n  - str: \"errThrow\"\n    duktape: true\n  - str: \"env\"\n    duktape: true\n  - str: \"version\"\n    duktape: true\n  - str: \"info\"\n    duktape: true\n  - str: \"act\"\n    duktape: true\n  - str: \"gc\"\n    duktape: true\n  - str: \"fin\"\n    duktape: true\n  - str: \"enc\"\n    duktape: true\n  - str: \"dec\"\n    duktape: true\n  - str: \"compact\"\n    duktape: true\n\n  # enc/dec algorithms\n  - str: \"hex\"\n    duktape: true\n  - str: \"base64\"\n    duktape: true\n  - str: \"jx\"\n    duktape: true\n  - str: \"jc\"\n    duktape: true\n\n  # Buffer constructor\n\n  # Buffer prototype\n\n  # Pointer constructor\n\n  # Pointer prototype\n\n  # Thread constructor\n  - str: \"yield\"\n    duktape: true\n  - str: \"resume\"\n    duktape: true\n  - str: \"current\"\n    duktape: true\n\n  # Thread prototype\n\n  # special literals for custom json encodings\n  - str: \"{\\\"_undef\\\":true}\"\n    duktape: true\n  - str: \"{\\\"_nan\\\":true}\"\n    duktape: true\n  - str: \"{\\\"_inf\\\":true}\"\n    duktape: true\n  - str: \"{\\\"_ninf\\\":true}\"\n    duktape: true\n  - str: \"{\\\"_func\\\":true}\"\n    duktape: true\n  - str: \"{_func:true}\"\n    duktape: true\n\n  # --- Standard reserved words (non-strict mode + strict mode) ---\n  # Note: order must match DUK_TOK_XXX reserved defines in duk_types.h\n\n  # E5 Section 7.6.1\n\n  # Keyword\n\n  - str: \"break\"\n    reserved_word: true\n  - str: \"case\"\n    reserved_word: true\n  - str: \"catch\"\n    reserved_word: true\n  - str: \"continue\"\n    reserved_word: true\n  - str: \"debugger\"\n    reserved_word: true\n  - str: \"default\"\n    reserved_word: true\n  - str: \"delete\"\n    reserved_word: true\n  - str: \"do\"\n    reserved_word: true\n  - str: \"else\"\n    reserved_word: true\n  - str: \"finally\"\n    reserved_word: true\n  - str: \"for\"\n    reserved_word: true\n  - str: \"function\"\n    reserved_word: true\n  - str: \"if\"\n    reserved_word: true\n  - str: \"in\"\n    reserved_word: true\n  - str: \"instanceof\"\n    reserved_word: true\n  - str: \"new\"\n    reserved_word: true\n  - str: \"return\"\n    reserved_word: true\n  - str: \"switch\"\n    reserved_word: true\n  - str: \"this\"\n    reserved_word: true\n  - str: \"throw\"\n    reserved_word: true\n  - str: \"try\"\n    reserved_word: true\n  - str: \"typeof\"\n    reserved_word: true\n  - str: \"var\"\n    reserved_word: true\n  - str: \"const\"  # future reserved word in E5.1, now supported by Duktape so moved here\n    reserved_word: true\n  - str: \"void\"\n    reserved_word: true\n  - str: \"while\"\n    reserved_word: true\n  - str: \"with\"\n    reserved_word: true\n\n  # Future reserved word\n\n  - str: \"class\"\n    reserved_word: true\n    future_reserved_word: true\n  - str: \"enum\"\n    reserved_word: true\n    future_reserved_word: true\n  - str: \"export\"\n    reserved_word: true\n    future_reserved_word: true\n  - str: \"extends\"\n    reserved_word: true\n    future_reserved_word: true\n  - str: \"import\"\n    reserved_word: true\n    future_reserved_word: true\n  - str: \"super\"\n    reserved_word: true\n    future_reserved_word: true\n\n  # E5 Section 7.8.1 and 7.8.2: special literals which the lexer\n  # basically treats like keywords\n\n  - str: \"null\"\n    reserved_word: true\n    special_literal: true\n  - str: \"true\"\n    reserved_word: true\n    special_literal: true\n  - str: \"false\"\n    reserved_word: true\n    special_literal: true\n\n  # \"set\" and \"get\" are *NOT* reserved words and there is even code\n  # in the wild with statements like \"var set = 1;\".  They are thus\n  # treated as ordinary identifiers and recognized by the compiler\n  # as tokens in a special way.\n  #- str: \"get\"\n  #- str: \"set\"\n\n  # --- Standard reserved words (strict mode only) ---\n  # Note: order must match DUK_TOK_XXX reserved defines in duk_types.h\n\n  # Future reserved word (additionally in strict mode)\n\n  - str: \"implements\"\n    reserved_word: true\n    future_reserved_word: true\n    future_reserved_word_strict: true\n  - str: \"interface\"\n    reserved_word: true\n    future_reserved_word: true\n    future_reserved_word_strict: true\n  - str: \"let\"\n    reserved_word: true\n    future_reserved_word: true\n    future_reserved_word_strict: true\n  - str: \"package\"\n    reserved_word: true\n    future_reserved_word: true\n    future_reserved_word_strict: true\n  - str: \"private\"\n    reserved_word: true\n    future_reserved_word: true\n    future_reserved_word_strict: true\n  - str: \"protected\"\n    reserved_word: true\n    future_reserved_word: true\n    future_reserved_word_strict: true\n  - str: \"public\"\n    reserved_word: true\n    future_reserved_word: true\n    future_reserved_word_strict: true\n  - str: \"static\"\n    reserved_word: true\n    future_reserved_word: true\n    future_reserved_word_strict: true\n  - str: \"yield\"\n    reserved_word: true\n    future_reserved_word: true\n    future_reserved_word_strict: true\n\n# Duktape duk_lexer.h expects these strings to be in this exact order\n# starting from \"first reserved word\".\nreserved_word_token_order:\n  - \"break\"\n  - \"case\"\n  - \"catch\"\n  - \"continue\"\n  - \"debugger\"\n  - \"default\"\n  - \"delete\"\n  - \"do\"\n  - \"else\"\n  - \"finally\"\n  - \"for\"\n  - \"function\"\n  - \"if\"\n  - \"in\"\n  - \"instanceof\"\n  - \"new\"\n  - \"return\"\n  - \"switch\"\n  - \"this\"\n  - \"throw\"\n  - \"try\"\n  - \"typeof\"\n  - \"var\"\n  - \"const\"\n  - \"void\"\n  - \"while\"\n  - \"with\"\n  - \"class\"\n  - \"enum\"\n  - \"export\"\n  - \"extends\"\n  - \"import\"\n  - \"super\"\n  - \"null\"\n  - \"true\"\n  - \"false\"\n  - \"implements\"\n  - \"interface\"\n  - \"let\"\n  - \"package\"\n  - \"private\"\n  - \"protected\"\n  - \"public\"\n  - \"static\"\n  - \"yield\"\n\n# Forced define names for specific strings for which automatic name generation\n# does a bad job.\nspecial_define_names:\n  # \"typeof\" has name conflicts like \"object\" and \"Object\", broken with\n  # explicit LC/UC prefix.\n  \"undefined\": \"LC_UNDEFINED\"\n  \"Undefined\": \"UC_UNDEFINED\"\n  \"null\": \"LC_NULL\"\n  \"Null\": \"UC_NULL\"\n  \"object\": \"LC_OBJECT\"\n  \"Object\": \"UC_OBJECT\"\n  \"boolean\": \"LC_BOOLEAN\"\n  \"Boolean\": \"UC_BOOLEAN\"\n  \"number\": \"LC_NUMBER\"\n  \"Number\": \"UC_NUMBER\"\n  \"function\": \"LC_FUNCTION\"\n  \"Function\": \"UC_FUNCTION\"\n  \"string\": \"LC_STRING\"\n  \"String\": \"UC_STRING\"\n  \"symbol\": \"LC_SYMBOL\"\n  \"Symbol\": \"UC_SYMBOL\"\n  \"arguments\": \"LC_ARGUMENTS\"\n  \"Arguments\": \"UC_ARGUMENTS\"\n  \"buffer\": \"LC_BUFFER\"\n  \"Buffer\": \"UC_BUFFER\"\n  \"pointer\": \"LC_POINTER\"\n  \"Pointer\": \"UC_POINTER\"\n  #\"thread\": \"LC_THREAD\"\n  \"Thread\": \"UC_THREAD\"\n\n  \"error\": \"LC_ERROR\"\n  \"Error\": \"UC_ERROR\"\n\n  # log levels\n  \"trace\": \"LC_TRACE\"\n  #\"Trace\": \"UC_TRACE\"\n  \"debug\": \"LC_DEBUG\"\n  #\"Debug\": \"UC_DEBUG\"\n  \"info\": \"LC_INFO\"\n  #\"Info\": \"UC_INFO\"\n  \"warn\": \"LC_WARN\"\n  #\"Warn\": \"UC_WARN\"\n  #\"error\": \"LC_ERROR\"    # already above\n  #\"Error\": \"UC_ERROR\"\n  \"fatal\": \"LC_FATAL\"\n  #\"Fatal\": \"UC_FATAL\"\n\n  \"+Infinity\": \"PLUS_INFINITY\"\n  \"-Infinity\": \"MINUS_INFINITY\"\n  \"0\": \"ZERO\"\n  \"+0\": \"PLUS_ZERO\"\n  \"-0\": \"MINUS_ZERO\"\n  \"NaN\": \"NAN\"\n  \"isNaN\": \"IS_NAN\"\n  \"MIN_VALUE\": \"MIN_VALUE\"\n  \"MAX_VALUE\": \"MAX_VALUE\"\n  \"NEGATIVE_INFINITY\": \"NEGATIVE_INFINITY\"\n  \"POSITIVE_INFINITY\": \"POSITIVE_INFINITY\"\n  \"Invalid Date\": \"INVALID_DATE\"\n\n  \"decodeURIComponent\": \"DECODE_URI_COMPONENT\"\n  \"encodeURIComponent\": \"ENCODE_URI_COMPONENT\"\n  \"getUTCDate\": \"GET_UTC_DATE\"\n  \"getUTCDay\": \"GET_UTC_DAY\"\n  \"getUTCFullYear\": \"GET_UTC_FULL_YEAR\"\n  \"getUTCHours\": \"GET_UTC_HOURS\"\n  \"getUTCMilliseconds\": \"GET_UTC_MILLISECONDS\"\n  \"getUTCMinutes\": \"GET_UTC_MINUTES\"\n  \"getUTCMonth\": \"GET_UTC_MONTH\"\n  \"getUTCSeconds\": \"GET_UTC_SECONDS\"\n  \"setUTCDate\": \"SET_UTC_DATE\"\n  \"setUTCDay\": \"SET_UTC_DAY\"\n  \"setUTCFullYear\": \"SET_UTC_FULL_YEAR\"\n  \"setUTCHours\": \"SET_UTC_HOURS\"\n  \"setUTCMilliseconds\": \"SET_UTC_MILLISECONDS\"\n  \"setUTCMinutes\": \"SET_UTC_MINUTES\"\n  \"setUTCMonth\": \"SET_UTC_MONTH\"\n  \"setUTCSeconds\": \"SET_UTC_SECONDS\"\n  \"LOG10E\": \"LOG10E\"\n  \"LOG2E\": \"LOG2E\"\n  \"toISOString\": \"TO_ISO_STRING\"\n  \"toUTCString\": \"TO_UTC_STRING\"\n  \"toGMTString\": \"TO_GMT_STRING\"\n  \"URIError\": \"URI_ERROR\"\n  \"Duktape\": \"DUKTAPE\"\n  \"\": \"EMPTY_STRING\"\n  \",\": \"COMMA\"\n  \"\\n    \": \"NEWLINE_4SPACE\"\n  \"[...]\": \"BRACKETED_ELLIPSIS\"\n\n  \"{\\\"_undef\\\":true}\": \"JSON_EXT_UNDEFINED\"\n  \"{\\\"_nan\\\":true}\": \"JSON_EXT_NAN\"\n  \"{\\\"_inf\\\":true}\": \"JSON_EXT_POSINF\"\n  \"{\\\"_ninf\\\":true}\": \"JSON_EXT_NEGINF\"\n  \"{\\\"_func\\\":true}\": \"JSON_EXT_FUNCTION1\"\n  \"{_func:true}\": \"JSON_EXT_FUNCTION2\"\n\n  \"BYTES_PER_ELEMENT\": \"BYTES_PER_ELEMENT\"\n"
  },
  {
    "path": "react_juce/duktape/src-noline/duk_config.h",
    "content": "/*\n *  duk_config.h configuration header generated by genconfig.py.\n *\n *  Git commit: d4f2cff1c592d70f58bab8e1bd85705174c02a58\n *  Git describe: v2.4.0\n *  Git branch: master\n *\n *  Supported platforms:\n *      - Mac OSX, iPhone, Darwin\n *      - Orbis\n *      - OpenBSD\n *      - Generic BSD\n *      - Atari ST TOS\n *      - AmigaOS\n *      - Durango (XboxOne)\n *      - Windows\n *      - Flashplayer (Crossbridge)\n *      - QNX\n *      - TI-Nspire\n *      - Emscripten\n *      - Android\n *      - Linux\n *      - Solaris\n *      - AIX\n *      - HPUX\n *      - Generic POSIX\n *      - Cygwin\n *      - Generic UNIX\n *      - Generic fallback\n *\n *  Supported architectures:\n *      - x86\n *      - x64\n *      - x32\n *      - ARM 32-bit\n *      - ARM 64-bit\n *      - MIPS 32-bit\n *      - MIPS 64-bit\n *      - PowerPC 32-bit\n *      - PowerPC 64-bit\n *      - SPARC 32-bit\n *      - SPARC 64-bit\n *      - SuperH\n *      - Motorola 68k\n *      - Emscripten\n *      - Generic\n *\n *  Supported compilers:\n *      - Clang\n *      - GCC\n *      - MSVC\n *      - Emscripten\n *      - TinyC\n *      - VBCC\n *      - Bruce's C compiler\n *      - Generic\n *\n */\n\n#if !defined(DUK_CONFIG_H_INCLUDED)\n#define DUK_CONFIG_H_INCLUDED\n\n/*\n *  Intermediate helper defines\n */\n\n/* DLL build detection */\n/* not configured for DLL build */\n#undef DUK_F_DLL_BUILD\n\n/* Apple OSX, iOS */\n#if defined(__APPLE__)\n#define DUK_F_APPLE\n#endif\n\n/* FreeBSD */\n#if defined(__FreeBSD__) || defined(__FreeBSD)\n#define DUK_F_FREEBSD\n#endif\n\n/* Orbis (PS4) variant */\n#if defined(DUK_F_FREEBSD) && defined(__ORBIS__)\n#define DUK_F_ORBIS\n#endif\n\n/* OpenBSD */\n#if defined(__OpenBSD__) || defined(__OpenBSD)\n#define DUK_F_OPENBSD\n#endif\n\n/* NetBSD */\n#if defined(__NetBSD__) || defined(__NetBSD)\n#define DUK_F_NETBSD\n#endif\n\n/* BSD variant */\n#if defined(DUK_F_FREEBSD) || defined(DUK_F_NETBSD) || defined(DUK_F_OPENBSD) || \\\n    defined(__bsdi__) || defined(__DragonFly__)\n#define DUK_F_BSD\n#endif\n\n/* Atari ST TOS.  __TOS__ defined by PureC.  No platform define in VBCC\n * apparently, so to use with VBCC user must define __TOS__ manually.\n  */\n#if defined(__TOS__)\n#define DUK_F_TOS\n#endif\n\n/* Motorola 68K.  Not defined by VBCC, so user must define one of these\n * manually when using VBCC.\n */\n#if defined(__m68k__) || defined(M68000) || defined(__MC68K__)\n#define DUK_F_M68K\n#endif\n\n/* AmigaOS.  Neither AMIGA nor __amigaos__ is defined on VBCC, so user must\n * define 'AMIGA' manually when using VBCC.\n */\n#if defined(AMIGA) || defined(__amigaos__)\n#define DUK_F_AMIGAOS\n#endif\n\n/* PowerPC */\n#if defined(__powerpc) || defined(__powerpc__) || defined(__PPC__)\n#define DUK_F_PPC\n#if defined(__PPC64__) || defined(__LP64__) || defined(_LP64)\n#define DUK_F_PPC64\n#else\n#define DUK_F_PPC32\n#endif\n#endif\n\n/* Durango (Xbox One) */\n#if defined(_DURANGO) || defined(_XBOX_ONE)\n#define DUK_F_DURANGO\n#endif\n\n/* Windows, both 32-bit and 64-bit */\n#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64) || \\\n    defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__)\n#define DUK_F_WINDOWS\n#if defined(_WIN64) || defined(WIN64)\n#define DUK_F_WIN64\n#else\n#define DUK_F_WIN32\n#endif\n#endif\n\n/* Flash player (e.g. Crossbridge) */\n#if defined(__FLASHPLAYER__)\n#define DUK_F_FLASHPLAYER\n#endif\n\n/* QNX */\n#if defined(__QNX__)\n#define DUK_F_QNX\n#endif\n\n/* TI-Nspire (using Ndless) */\n#if defined(_TINSPIRE)\n#define DUK_F_TINSPIRE\n#endif\n\n/* Emscripten (provided explicitly by user), improve if possible */\n#if defined(EMSCRIPTEN)\n#define DUK_F_EMSCRIPTEN\n#endif\n\n/* BCC (Bruce's C compiler): this is a \"torture target\" for compilation */\n#if defined(__BCC__) || defined(__BCC_VERSION__)\n#define DUK_F_BCC\n#endif\n\n#if defined(ANDROID) || defined(__ANDROID__)\n#define DUK_F_ANDROID\n#endif\n\n/* Linux */\n#if defined(__linux) || defined(__linux__) || defined(linux)\n#define DUK_F_LINUX\n#endif\n\n/* illumos / Solaris */\n#if defined(__sun) && defined(__SVR4)\n#define DUK_F_SUN\n#if defined(__SUNPRO_C) && (__SUNPRO_C < 0x550)\n#define DUK_F_OLD_SOLARIS\n/* Defines _ILP32 / _LP64 required by DUK_F_X86/DUK_F_X64.  Platforms\n * are processed before architectures, so this happens before the\n * DUK_F_X86/DUK_F_X64 detection is emitted.\n */\n#include <sys/isa_defs.h>\n#endif\n#endif\n\n/* AIX */\n#if defined(_AIX)\n/* defined(__xlc__) || defined(__IBMC__): works but too wide */\n#define DUK_F_AIX\n#endif\n\n/* HPUX */\n#if defined(__hpux)\n#define DUK_F_HPUX\n#if defined(__ia64)\n#define DUK_F_HPUX_ITANIUM\n#endif\n#endif\n\n/* POSIX */\n#if defined(__posix)\n#define DUK_F_POSIX\n#endif\n\n/* Cygwin */\n#if defined(__CYGWIN__)\n#define DUK_F_CYGWIN\n#endif\n\n/* Generic Unix (includes Cygwin) */\n#if defined(__unix) || defined(__unix__) || defined(unix) || \\\n    defined(DUK_F_LINUX) || defined(DUK_F_BSD)\n#define DUK_F_UNIX\n#endif\n\n/* Intel x86 (32-bit), x64 (64-bit) or x32 (64-bit but 32-bit pointers),\n * define only one of DUK_F_X86, DUK_F_X64, DUK_F_X32.\n * https://sites.google.com/site/x32abi/\n *\n * With DUK_F_OLD_SOLARIS the <sys/isa_defs.h> header must be included\n * before this.\n */\n#if defined(__amd64__) || defined(__amd64) || \\\n    defined(__x86_64__) || defined(__x86_64) || \\\n    defined(_M_X64) || defined(_M_AMD64)\n#if defined(__ILP32__) || defined(_ILP32)\n#define DUK_F_X32\n#else\n#define DUK_F_X64\n#endif\n#elif defined(i386) || defined(__i386) || defined(__i386__) || \\\n      defined(__i486__) || defined(__i586__) || defined(__i686__) || \\\n      defined(__IA32__) || defined(_M_IX86) || defined(__X86__) || \\\n      defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__)\n#if defined(__LP64__) || defined(_LP64)\n/* This should not really happen, but would indicate x64. */\n#define DUK_F_X64\n#else\n#define DUK_F_X86\n#endif\n#endif\n\n/* ARM */\n#if defined(__arm__) || defined(__thumb__) || defined(_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__)\n#define DUK_F_ARM\n#if defined(__LP64__) || defined(_LP64) || defined(__arm64) || defined(__arm64__) || defined(_M_ARM64) || defined(__aarch64__)\n#define DUK_F_ARM64\n#else\n#define DUK_F_ARM32\n#endif\n#endif\n\n/* MIPS.  Related defines: __MIPSEB__, __MIPSEL__, __mips_isa_rev, __LP64__ */\n#if defined(__mips__) || defined(mips) || defined(_MIPS_ISA) || \\\n    defined(_R3000) || defined(_R4000) || defined(_R5900) || \\\n    defined(_MIPS_ISA_MIPS1) || defined(_MIPS_ISA_MIPS2) || \\\n    defined(_MIPS_ISA_MIPS3) || defined(_MIPS_ISA_MIPS4) || \\\n    defined(__mips) || defined(__MIPS__)\n#define DUK_F_MIPS\n#if defined(__LP64__) || defined(_LP64) || defined(__mips64) || \\\n    defined(__mips64__) || defined(__mips_n64)\n#define DUK_F_MIPS64\n#else\n#define DUK_F_MIPS32\n#endif\n#endif\n\n/* SPARC */\n#if defined(sparc) || defined(__sparc) || defined(__sparc__)\n#define DUK_F_SPARC\n#if defined(__LP64__) || defined(_LP64)\n#define DUK_F_SPARC64\n#else\n#define DUK_F_SPARC32\n#endif\n#endif\n\n/* SuperH */\n#if defined(__sh__) || \\\n    defined(__sh1__) || defined(__SH1__) || \\\n    defined(__sh2__) || defined(__SH2__) || \\\n    defined(__sh3__) || defined(__SH3__) || \\\n    defined(__sh4__) || defined(__SH4__) || \\\n    defined(__sh5__) || defined(__SH5__)\n#define DUK_F_SUPERH\n#endif\n\n/* Clang */\n#if defined(__clang__)\n#define DUK_F_CLANG\n#endif\n\n/* C++ */\n#undef DUK_F_CPP\n#if defined(__cplusplus)\n#define DUK_F_CPP\n#endif\n\n/* C99 or above */\n#undef DUK_F_C99\n#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)\n#define DUK_F_C99\n#endif\n\n/* C++11 or above */\n#undef DUK_F_CPP11\n#if defined(__cplusplus) && (__cplusplus >= 201103L)\n#define DUK_F_CPP11\n#endif\n\n/* GCC.  Clang also defines __GNUC__ so don't detect GCC if using Clang. */\n#if defined(__GNUC__) && !defined(__clang__) && !defined(DUK_F_CLANG)\n#define DUK_F_GCC\n#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)\n/* Convenience, e.g. gcc 4.5.1 == 40501; http://stackoverflow.com/questions/6031819/emulating-gccs-builtin-unreachable */\n#define DUK_F_GCC_VERSION  (__GNUC__ * 10000L + __GNUC_MINOR__ * 100L + __GNUC_PATCHLEVEL__)\n#else\n#error cannot figure out gcc version\n#endif\n#endif\n\n/* MinGW.  Also GCC flags (DUK_F_GCC) are enabled now. */\n#if defined(__MINGW32__) || defined(__MINGW64__)\n#define DUK_F_MINGW\n#endif\n\n/* MSVC */\n#if defined(_MSC_VER)\n/* MSVC preprocessor defines: http://msdn.microsoft.com/en-us/library/b0084kay.aspx\n * _MSC_FULL_VER includes the build number, but it has at least two formats, see e.g.\n * BOOST_MSVC_FULL_VER in http://www.boost.org/doc/libs/1_52_0/boost/config/compiler/visualc.hpp\n */\n#define DUK_F_MSVC\n#if defined(_MSC_FULL_VER)\n#if (_MSC_FULL_VER > 100000000)\n#define DUK_F_MSVC_FULL_VER _MSC_FULL_VER\n#else\n#define DUK_F_MSCV_FULL_VER (_MSC_FULL_VER * 10)\n#endif\n#endif\n#endif  /* _MSC_VER */\n\n/* TinyC */\n#if defined(__TINYC__)\n/* http://bellard.org/tcc/tcc-doc.html#SEC9 */\n#define DUK_F_TINYC\n#endif\n\n/* VBCC */\n#if defined(__VBCC__)\n#define DUK_F_VBCC\n#endif\n\n/* Atari Mint */\n#if defined(__MINT__)\n#define DUK_F_MINT\n#endif\n\n/*\n *  Platform autodetection\n */\n\n/* Workaround for older C++ compilers before including <inttypes.h>,\n * see e.g.: https://sourceware.org/bugzilla/show_bug.cgi?id=15366\n */\n#if defined(__cplusplus) && !defined(__STDC_LIMIT_MACROS)\n#define __STDC_LIMIT_MACROS\n#endif\n#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS)\n#define __STDC_CONSTANT_MACROS\n#endif\n\n#if defined(DUK_F_APPLE)\n/* --- Mac OSX, iPhone, Darwin --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <TargetConditionals.h>\n#include <architecture/byte_order.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n/* http://stackoverflow.com/questions/5919996/how-to-detect-reliably-mac-os-x-ios-linux-windows-in-c-preprocessor */\n#if TARGET_IPHONE_SIMULATOR\n#define DUK_USE_OS_STRING \"iphone-sim\"\n#elif TARGET_OS_IPHONE\n#define DUK_USE_OS_STRING \"iphone\"\n#elif TARGET_OS_MAC\n#define DUK_USE_OS_STRING \"osx\"\n#else\n#define DUK_USE_OS_STRING \"osx-unknown\"\n#endif\n\n/* Use _setjmp() on Apple by default, see GH-55. */\n#define DUK_JMPBUF_TYPE       jmp_buf\n#define DUK_SETJMP(jb)        _setjmp((jb))\n#define DUK_LONGJMP(jb)       _longjmp((jb), 1)\n#elif defined(DUK_F_ORBIS)\n/* --- Orbis --- */\n/* Orbis = PS4 */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_S\n/* no parsing (not an error) */\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <machine/endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"orbis\"\n#elif defined(DUK_F_OPENBSD)\n/* --- OpenBSD --- */\n/* http://www.monkey.org/openbsd/archive/ports/0401/msg00089.html */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"openbsd\"\n#elif defined(DUK_F_BSD)\n/* --- Generic BSD --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"bsd\"\n#elif defined(DUK_F_TOS)\n/* --- Atari ST TOS --- */\n#define DUK_USE_DATE_NOW_TIME\n#define DUK_USE_DATE_TZO_GMTIME\n/* no parsing (not an error) */\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"tos\"\n\n/* TOS on M68K is always big endian. */\n#if !defined(DUK_USE_BYTEORDER) && defined(DUK_F_M68K)\n#define DUK_USE_BYTEORDER 3\n#endif\n#elif defined(DUK_F_AMIGAOS)\n/* --- AmigaOS --- */\n#if defined(DUK_F_M68K)\n/* AmigaOS on M68k */\n#define DUK_USE_DATE_NOW_TIME\n#define DUK_USE_DATE_TZO_GMTIME\n/* no parsing (not an error) */\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n#elif defined(DUK_F_PPC)\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n#if !defined(UINTPTR_MAX)\n#define UINTPTR_MAX UINT_MAX\n#endif\n#else\n#error AmigaOS but not M68K/PPC, not supported now\n#endif\n\n#define DUK_USE_OS_STRING \"amigaos\"\n\n/* AmigaOS on M68K or PPC is always big endian. */\n#if !defined(DUK_USE_BYTEORDER) && (defined(DUK_F_M68K) || defined(DUK_F_PPC))\n#define DUK_USE_BYTEORDER 3\n#endif\n#elif defined(DUK_F_DURANGO)\n/* --- Durango (XboxOne) --- */\n/* Durango = XboxOne\n * Configuration is nearly identical to Windows, except for\n * DUK_USE_DATE_TZO_WINDOWS.\n */\n\n/* Initial fix: disable secure CRT related warnings when compiling Duktape\n * itself (must be defined before including Windows headers).  Don't define\n * for user code including duktape.h.\n */\n#if defined(DUK_COMPILING_DUKTAPE) && !defined(_CRT_SECURE_NO_WARNINGS)\n#define _CRT_SECURE_NO_WARNINGS\n#endif\n\n/* MSVC does not have sys/param.h */\n#define DUK_USE_DATE_NOW_WINDOWS\n#define DUK_USE_DATE_TZO_WINDOWS_NO_DST\n/* Note: PRS and FMT are intentionally left undefined for now.  This means\n * there is no platform specific date parsing/formatting but there is still\n * the ISO 8601 standard format.\n */\n#if defined(DUK_COMPILING_DUKTAPE)\n/* Only include when compiling Duktape to avoid polluting application build\n * with a lot of unnecessary defines.\n */\n#include <windows.h>\n#endif\n\n#define DUK_USE_OS_STRING \"durango\"\n\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#elif defined(DUK_F_WINDOWS)\n/* --- Windows --- */\n/* Windows version can't obviously be determined at compile time,\n * but _WIN32_WINNT indicates the minimum version targeted:\n * - https://msdn.microsoft.com/en-us/library/6sehtctf.aspx\n */\n\n/* Initial fix: disable secure CRT related warnings when compiling Duktape\n * itself (must be defined before including Windows headers).  Don't define\n * for user code including duktape.h.\n */\n#if defined(DUK_COMPILING_DUKTAPE) && !defined(_CRT_SECURE_NO_WARNINGS)\n#define _CRT_SECURE_NO_WARNINGS\n#endif\n\n/* Windows 32-bit and 64-bit are currently the same. */\n/* MSVC does not have sys/param.h */\n\n#if defined(DUK_COMPILING_DUKTAPE)\n/* Only include when compiling Duktape to avoid polluting application build\n * with a lot of unnecessary defines.\n */\n#include <windows.h>\n#endif\n\n/* GetSystemTimePreciseAsFileTime() available from Windows 8:\n * https://msdn.microsoft.com/en-us/library/windows/desktop/hh706895(v=vs.85).aspx\n */\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS) || defined(DUK_USE_DATE_NOW_WINDOWS)\n/* User forced provider. */\n#else\n#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)\n#define DUK_USE_DATE_NOW_WINDOWS_SUBMS\n#else\n#define DUK_USE_DATE_NOW_WINDOWS\n#endif\n#endif\n\n#define DUK_USE_DATE_TZO_WINDOWS\n\n/* Note: PRS and FMT are intentionally left undefined for now.  This means\n * there is no platform specific date parsing/formatting but there is still\n * the ISO 8601 standard format.\n */\n\n/* QueryPerformanceCounter() may go backwards in Windows XP, so enable for\n * Vista and later: https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx#qpc_support_in_windows_versions\n */\n#if !defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC) && \\\n    defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)\n#define DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC\n#endif\n\n#define DUK_USE_OS_STRING \"windows\"\n\n/* On Windows, assume we're little endian.  Even Itanium which has a\n * configurable endianness runs little endian in Windows.\n */\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#elif defined(DUK_F_FLASHPLAYER)\n/* --- Flashplayer (Crossbridge) --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"flashplayer\"\n\n#if !defined(DUK_USE_BYTEORDER) && defined(DUK_F_FLASHPLAYER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#elif defined(DUK_F_QNX)\n/* --- QNX --- */\n#if defined(DUK_F_QNX) && defined(DUK_COMPILING_DUKTAPE)\n/* See: /opt/qnx650/target/qnx6/usr/include/sys/platform.h */\n#define _XOPEN_SOURCE    600\n#define _POSIX_C_SOURCE  200112L\n#endif\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"qnx\"\n#elif defined(DUK_F_TINSPIRE)\n/* --- TI-Nspire --- */\n#if defined(DUK_COMPILING_DUKTAPE) && !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"tinspire\"\n#elif defined(DUK_F_EMSCRIPTEN)\n/* --- Emscripten --- */\n#if defined(DUK_COMPILING_DUKTAPE)\n#if !defined(_POSIX_C_SOURCE)\n#define _POSIX_C_SOURCE  200809L\n#endif\n#if !defined(_GNU_SOURCE)\n#define _GNU_SOURCE      /* e.g. getdate_r */\n#endif\n#if !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n#endif  /* DUK_COMPILING_DUKTAPE */\n\n#include <sys/types.h>\n#if defined(DUK_F_BCC)\n/* no endian.h */\n#else\n#include <endian.h>\n#endif  /* DUK_F_BCC */\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n#include <stdint.h>\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#define DUK_USE_OS_STRING \"emscripten\"\n#elif defined(DUK_F_ANDROID)\n/* --- Android --- */\n#if defined(DUK_COMPILING_DUKTAPE)\n#if !defined(_POSIX_C_SOURCE)\n#define _POSIX_C_SOURCE  200809L\n#endif\n#if !defined(_GNU_SOURCE)\n#define _GNU_SOURCE      /* e.g. getdate_r */\n#endif\n#if !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n#endif  /* DUK_COMPILING_DUKTAPE */\n\n#include <sys/types.h>\n#if defined(DUK_F_BCC)\n/* no endian.h or stdint.h */\n#else\n#include <endian.h>\n#include <stdint.h>\n#endif  /* DUK_F_BCC */\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#if 0  /* XXX: safe condition? */\n#define DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME\n#endif\n\n#define DUK_USE_OS_STRING \"android\"\n#elif defined(DUK_F_LINUX)\n/* --- Linux --- */\n#if defined(DUK_COMPILING_DUKTAPE)\n#if !defined(_POSIX_C_SOURCE)\n#define _POSIX_C_SOURCE  200809L\n#endif\n#if !defined(_GNU_SOURCE)\n#define _GNU_SOURCE      /* e.g. getdate_r */\n#endif\n#if !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n#endif  /* DUK_COMPILING_DUKTAPE */\n\n#include <sys/types.h>\n#if defined(DUK_F_BCC)\n/* no endian.h or stdint.h */\n#else\n#include <endian.h>\n#include <stdint.h>\n#endif  /* DUK_F_BCC */\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#if 0  /* XXX: safe condition? */\n#define DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME\n#endif\n\n#define DUK_USE_OS_STRING \"linux\"\n#elif defined(DUK_F_SUN)\n/* --- Solaris --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#include <sys/types.h>\n#if defined(DUK_F_OLD_SOLARIS)\n/* Old Solaris with no endian.h, stdint.h */\n#define DUK_F_NO_STDINT_H\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#else  /* DUK_F_OLD_SOLARIS */\n#include <ast/endian.h>\n#endif  /* DUK_F_OLD_SOLARIS */\n\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"solaris\"\n#elif defined(DUK_F_AIX)\n/* --- AIX --- */\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"aix\"\n#elif defined(DUK_F_HPUX)\n/* --- HPUX --- */\n#define DUK_F_NO_STDINT_H\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"hpux\"\n#elif defined(DUK_F_POSIX)\n/* --- Generic POSIX --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"posix\"\n#elif defined(DUK_F_CYGWIN)\n/* --- Cygwin --- */\n/* don't use strptime() for now */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_JMPBUF_TYPE       jmp_buf\n#define DUK_SETJMP(jb)        _setjmp((jb))\n#define DUK_LONGJMP(jb)       _longjmp((jb), 1)\n\n#define DUK_USE_OS_STRING \"windows\"\n#elif defined(DUK_F_UNIX)\n/* --- Generic UNIX --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n#include <sys/time.h>\n#define DUK_USE_OS_STRING \"unknown\"\n#else\n/* --- Generic fallback --- */\n/* The most portable current time provider is time(), but it only has a\n * one second resolution.\n */\n#define DUK_USE_DATE_NOW_TIME\n\n/* The most portable way to figure out local time offset is gmtime(),\n * but it's not thread safe so use with caution.\n */\n#define DUK_USE_DATE_TZO_GMTIME\n\n/* Avoid custom date parsing and formatting for portability. */\n#undef DUK_USE_DATE_PRS_STRPTIME\n#undef DUK_USE_DATE_FMT_STRFTIME\n\n/* Rely on C89 headers only; time.h must be here. */\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"unknown\"\n#endif  /* autodetect platform */\n\n/* Shared includes: C89 */\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdarg.h>  /* varargs */\n#include <setjmp.h>\n#include <stddef.h>  /* e.g. ptrdiff_t */\n#include <math.h>\n#include <limits.h>\n\n/* date.h is omitted, and included per platform */\n\n/* Shared includes: stdint.h is C99 */\n#if defined(DUK_F_NO_STDINT_H)\n/* stdint.h not available */\n#else\n/* Technically C99 (C++11) but found in many systems.  On some systems\n * __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS must be defined before\n * including stdint.h (see above).\n */\n#include <stdint.h>\n#endif\n\n/* <exception> is only included if needed, based on DUK_USE_xxx flags. */\n\n/*\n *  Architecture autodetection\n */\n\n#if defined(DUK_F_X86)\n/* --- x86 --- */\n#define DUK_USE_ARCH_STRING \"x86\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n\n#define DUK_USE_PACKED_TVAL\n\n/* FreeBSD, -m32, and clang prior to 5.0 has union aliasing issues which\n * break duk_tval copying.  Disable packed duk_tval automatically.\n */\n#if defined(DUK_F_FREEBSD) && defined(DUK_F_X86) && \\\n    defined(__clang__) && defined(__clang_major__) && (__clang_major__ < 5)\n#undef DUK_USE_PACKED_TVAL\n#endif\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_X64)\n/* --- x64 --- */\n#define DUK_USE_ARCH_STRING \"x64\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_X32)\n/* --- x32 --- */\n#define DUK_USE_ARCH_STRING \"x32\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_ARM32)\n/* --- ARM 32-bit --- */\n#define DUK_USE_ARCH_STRING \"arm32\"\n/* Byte order varies, so rely on autodetect. */\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_ARM64)\n/* --- ARM 64-bit --- */\n#define DUK_USE_ARCH_STRING \"arm64\"\n/* Byte order varies, so rely on autodetect. */\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_MIPS32)\n/* --- MIPS 32-bit --- */\n#define DUK_USE_ARCH_STRING \"mips32\"\n/* MIPS byte order varies so rely on autodetection. */\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_MIPS64)\n/* --- MIPS 64-bit --- */\n#define DUK_USE_ARCH_STRING \"mips64\"\n/* MIPS byte order varies so rely on autodetection. */\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_PPC32)\n/* --- PowerPC 32-bit --- */\n#define DUK_USE_ARCH_STRING \"ppc32\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_PPC64)\n/* --- PowerPC 64-bit --- */\n#define DUK_USE_ARCH_STRING \"ppc64\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_SPARC32)\n/* --- SPARC 32-bit --- */\n#define DUK_USE_ARCH_STRING \"sparc32\"\n/* SPARC byte order varies so rely on autodetection. */\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_SPARC64)\n/* --- SPARC 64-bit --- */\n#define DUK_USE_ARCH_STRING \"sparc64\"\n/* SPARC byte order varies so rely on autodetection. */\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_SUPERH)\n/* --- SuperH --- */\n#define DUK_USE_ARCH_STRING \"sh\"\n/* Byte order varies, rely on autodetection. */\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_M68K)\n/* --- Motorola 68k --- */\n#define DUK_USE_ARCH_STRING \"m68k\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_EMSCRIPTEN)\n/* --- Emscripten --- */\n#define DUK_USE_ARCH_STRING \"emscripten\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#else\n/* --- Generic --- */\n/* These are necessary wild guesses. */\n#define DUK_USE_ARCH_STRING \"generic\"\n/* Rely on autodetection for byte order, alignment, and packed tval. */\n#endif  /* autodetect architecture */\n\n/*\n *  Compiler autodetection\n */\n\n#if defined(DUK_F_CLANG)\n/* --- Clang --- */\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n/* C99 / C++11 and above: rely on va_copy() which is required. */\n#define DUK_VA_COPY(dest,src) va_copy(dest,src)\n#else\n/* Clang: assume we have __va_copy() in non-C99 mode. */\n#define DUK_VA_COPY(dest,src) __va_copy(dest,src)\n#endif\n\n#define DUK_NORETURN(decl)  decl __attribute__((noreturn))\n\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unreachable)\n#define DUK_UNREACHABLE()  do { __builtin_unreachable(); } while (0)\n#endif\n#endif\n\n#define DUK_USE_BRANCH_HINTS\n#define DUK_LIKELY(x)    __builtin_expect((x), 1)\n#define DUK_UNLIKELY(x)  __builtin_expect((x), 0)\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unpredictable)\n#define DUK_UNPREDICTABLE(x)  __builtin_unpredictable((x))\n#endif\n#endif\n\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_NOINLINE        __attribute__((noinline))\n#define DUK_INLINE          inline\n#define DUK_ALWAYS_INLINE   inline __attribute__((always_inline))\n#endif\n\n/* DUK_HOT */\n/* DUK_COLD */\n\n#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS)\n/* MSVC dllexport/dllimport: appropriate __declspec depends on whether we're\n * compiling Duktape or the application.\n */\n#if defined(DUK_COMPILING_DUKTAPE)\n#define DUK_EXTERNAL_DECL  extern __declspec(dllexport)\n#define DUK_EXTERNAL       __declspec(dllexport)\n#else\n#define DUK_EXTERNAL_DECL  extern __declspec(dllimport)\n#define DUK_EXTERNAL       should_not_happen\n#endif\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#else\n#define DUK_INTERNAL_DECL  extern\n#define DUK_INTERNAL       /*empty*/\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n#else\n#define DUK_EXTERNAL_DECL  __attribute__ ((visibility(\"default\"))) extern\n#define DUK_EXTERNAL       __attribute__ ((visibility(\"default\")))\n#if defined(DUK_SINGLE_FILE)\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n/* Minimize warnings for unused internal functions with GCC >= 3.1.1 and\n * Clang.  Based on documentation it should suffice to have the attribute\n * in the declaration only, but in practice some warnings are generated unless\n * the attribute is also applied to the definition.\n */\n#define DUK_INTERNAL_DECL  static __attribute__ ((unused))\n#define DUK_INTERNAL       static __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#endif\n#else\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused)) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\")))\n#endif\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n#endif\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"clang\"\n#else\n#define DUK_USE_COMPILER_STRING \"clang\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#define DUK_USE_UNION_INITIALIZERS\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#undef DUK_USE_GCC_PRAGMAS\n#define DUK_USE_PACK_CLANG_ATTR\n\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_bswap64)\n#define DUK_BSWAP64(x) ((duk_uint64_t) __builtin_bswap64((duk_uint64_t) (x)))\n#endif\n#if __has_builtin(__builtin_bswap32)\n#define DUK_BSWAP32(x) ((duk_uint32_t) __builtin_bswap32((duk_uint32_t) (x)))\n#endif\n#if __has_builtin(__builtin_bswap16)\n#define DUK_BSWAP16(x) ((duk_uint16_t) __builtin_bswap16((duk_uint16_t) (x)))\n#endif\n#endif\n#elif defined(DUK_F_GCC)\n/* --- GCC --- */\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n/* C99 / C++11 and above: rely on va_copy() which is required. */\n#define DUK_VA_COPY(dest,src) va_copy(dest,src)\n#else\n/* GCC: assume we have __va_copy() in non-C99 mode. */\n#define DUK_VA_COPY(dest,src) __va_copy(dest,src)\n#endif\n\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 20500L) && (DUK_F_GCC_VERSION < 50000L)\n/* Since gcc-2.5.\n *\n * Disabled temporarily in GCC 5+ because of an unresolved noreturn-related\n * issue: https://github.com/svaarala/duktape/issues/2155.\n */\n#define DUK_NORETURN(decl)  decl __attribute__((noreturn))\n#endif\n\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L)\n/* Since gcc-4.5. */\n#define DUK_UNREACHABLE()  do { __builtin_unreachable(); } while (0)\n#endif\n\n#define DUK_USE_BRANCH_HINTS\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L)\n/* GCC: test not very accurate; enable only in relatively recent builds\n * because of bugs in gcc-4.4 (http://lists.debian.org/debian-gcc/2010/04/msg00000.html)\n */\n#define DUK_LIKELY(x)    __builtin_expect((x), 1)\n#define DUK_UNLIKELY(x)  __builtin_expect((x), 0)\n#endif\n/* XXX: equivalent of clang __builtin_unpredictable? */\n\n#if (defined(DUK_F_C99) || defined(DUK_F_CPP11)) && \\\n    defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 30101)\n#define DUK_NOINLINE        __attribute__((noinline))\n#define DUK_INLINE          inline\n#define DUK_ALWAYS_INLINE   inline __attribute__((always_inline))\n#endif\n\n#if (defined(DUK_F_C99) || defined(DUK_F_CPP11)) && \\\n    defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40300)\n#define DUK_HOT             __attribute__((hot))\n#define DUK_COLD            __attribute__((cold))\n#endif\n\n#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS)\n/* MSVC dllexport/dllimport: appropriate __declspec depends on whether we're\n * compiling Duktape or the application.\n */\n#if defined(DUK_COMPILING_DUKTAPE)\n#define DUK_EXTERNAL_DECL  extern __declspec(dllexport)\n#define DUK_EXTERNAL       __declspec(dllexport)\n#else\n#define DUK_EXTERNAL_DECL  extern __declspec(dllimport)\n#define DUK_EXTERNAL       should_not_happen\n#endif\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#else\n#define DUK_INTERNAL_DECL  extern\n#define DUK_INTERNAL       /*empty*/\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n#elif defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40000)\n#define DUK_EXTERNAL_DECL  __attribute__ ((visibility(\"default\"))) extern\n#define DUK_EXTERNAL       __attribute__ ((visibility(\"default\")))\n#if defined(DUK_SINGLE_FILE)\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n/* Minimize warnings for unused internal functions with GCC >= 3.1.1 and\n * Clang.  Based on documentation it should suffice to have the attribute\n * in the declaration only, but in practice some warnings are generated unless\n * the attribute is also applied to the definition.\n */\n#define DUK_INTERNAL_DECL  static __attribute__ ((unused))\n#define DUK_INTERNAL       static __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#endif\n#else\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused)) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\")))\n#endif\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n#endif\n\n#if defined(DUK_F_MINGW)\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"mingw++\"\n#else\n#define DUK_USE_COMPILER_STRING \"mingw\"\n#endif\n#else\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"g++\"\n#else\n#define DUK_USE_COMPILER_STRING \"gcc\"\n#endif\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || (defined(DUK_F_CPP11) && defined(__GNUC__))\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#define DUK_USE_UNION_INITIALIZERS\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40600)\n#define DUK_USE_GCC_PRAGMAS\n#else\n#undef DUK_USE_GCC_PRAGMAS\n#endif\n\n#define DUK_USE_PACK_GCC_ATTR\n\n/* Availability varies based on platform (between GCC 4.4 and 4.8), and there\n * are apparently some bugs in GCC 4.x.  Check for GCC 5.0 before enabling\n * these to be safe.\n */\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 50000L)\n#define DUK_BSWAP64(x) ((duk_uint64_t) __builtin_bswap64((duk_uint64_t) (x)))\n#define DUK_BSWAP32(x) ((duk_uint32_t) __builtin_bswap32((duk_uint32_t) (x)))\n#define DUK_BSWAP16(x) ((duk_uint16_t) __builtin_bswap16((duk_uint16_t) (x)))\n#endif\n#elif defined(DUK_F_MSVC)\n/* --- MSVC --- */\n/* http://msdn.microsoft.com/en-us/library/aa235362(VS.60).aspx */\n#define DUK_NORETURN(decl)  __declspec(noreturn) decl\n\n/* XXX: DUK_UNREACHABLE for msvc? */\n\n#undef DUK_USE_BRANCH_HINTS\n\n/* XXX: DUK_LIKELY, DUK_UNLIKELY for msvc? */\n/* XXX: DUK_NOINLINE, DUK_INLINE, DUK_ALWAYS_INLINE for msvc? */\n\n#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS)\n/* MSVC dllexport/dllimport: appropriate __declspec depends on whether we're\n * compiling Duktape or the application.\n */\n#if defined(DUK_COMPILING_DUKTAPE)\n#define DUK_EXTERNAL_DECL  extern __declspec(dllexport)\n#define DUK_EXTERNAL       __declspec(dllexport)\n#else\n#define DUK_EXTERNAL_DECL  extern __declspec(dllimport)\n#define DUK_EXTERNAL       should_not_happen\n#endif\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#else\n#define DUK_INTERNAL_DECL  extern\n#define DUK_INTERNAL       /*empty*/\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n#endif\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"msvc++\"\n#else\n#define DUK_USE_COMPILER_STRING \"msvc\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99)\n#define DUK_USE_VARIADIC_MACROS\n#elif defined(_MSC_VER) && (_MSC_VER >= 1400)\n/* VS2005+ should have variadic macros even when they're not C99. */\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#undef DUK_USE_UNION_INITIALIZERS\n#if defined(_MSC_VER) && (_MSC_VER >= 1800)\n/* VS2013+ supports union initializers but there's a bug involving union-inside-struct:\n * https://connect.microsoft.com/VisualStudio/feedback/details/805981\n * The bug was fixed (at least) in VS2015 so check for VS2015 for now:\n * https://blogs.msdn.microsoft.com/vcblog/2015/07/01/c-compiler-front-end-fixes-in-vs2015/\n * Manually tested using VS2013, CL reports 18.00.31101, so enable for VS2013 too.\n */\n#define DUK_USE_UNION_INITIALIZERS\n#endif\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#undef DUK_USE_GCC_PRAGMAS\n\n#define DUK_USE_PACK_MSVC_PRAGMA\n\n/* These have been tested from VS2008 onwards; may work in older VS versions\n * too but not enabled by default.\n */\n#if defined(_MSC_VER) && (_MSC_VER >= 1500)\n#define DUK_NOINLINE        __declspec(noinline)\n#define DUK_INLINE          __inline\n#define DUK_ALWAYS_INLINE   __forceinline\n#endif\n\n#if defined(_MSC_VER) && (_MSC_VER >= 1900)\n#define DUK_SNPRINTF     snprintf\n#define DUK_VSNPRINTF    vsnprintf\n#else\n/* (v)snprintf() is missing before MSVC 2015.  Note that _(v)snprintf() does\n * NOT NUL terminate on truncation, but Duktape code never assumes that.\n * http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010\n */\n#define DUK_SNPRINTF     _snprintf\n#define DUK_VSNPRINTF    _vsnprintf\n#endif\n\n/* Avoid warning when doing DUK_UNREF(some_function). */\n#if defined(_MSC_VER) && (_MSC_VER < 1500)\n#pragma warning(disable: 4100 4101 4550 4551)\n#define DUK_UNREF(x)\n#else\n#define DUK_UNREF(x)  do { __pragma(warning(suppress:4100 4101 4550 4551)) (x); } while (0)\n#endif\n\n/* Older versions of MSVC don't support the LL/ULL suffix. */\n#define DUK_U64_CONSTANT(x) x##ui64\n#define DUK_I64_CONSTANT(x) x##i64\n#elif defined(DUK_F_EMSCRIPTEN)\n/* --- Emscripten --- */\n#define DUK_NORETURN(decl)  decl __attribute__((noreturn))\n\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unreachable)\n#define DUK_UNREACHABLE()  do { __builtin_unreachable(); } while (0)\n#endif\n#endif\n\n#define DUK_USE_BRANCH_HINTS\n#define DUK_LIKELY(x)    __builtin_expect((x), 1)\n#define DUK_UNLIKELY(x)  __builtin_expect((x), 0)\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unpredictable)\n#define DUK_UNPREDICTABLE(x)  __builtin_unpredictable((x))\n#endif\n#endif\n\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_NOINLINE        __attribute__((noinline))\n#define DUK_INLINE          inline\n#define DUK_ALWAYS_INLINE   inline __attribute__((always_inline))\n#endif\n\n#define DUK_EXTERNAL_DECL  __attribute__ ((visibility(\"default\"))) extern\n#define DUK_EXTERNAL       __attribute__ ((visibility(\"default\")))\n#if defined(DUK_SINGLE_FILE)\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n/* Minimize warnings for unused internal functions with GCC >= 3.1.1 and\n * Clang.  Based on documentation it should suffice to have the attribute\n * in the declaration only, but in practice some warnings are generated unless\n * the attribute is also applied to the definition.\n */\n#define DUK_INTERNAL_DECL  static __attribute__ ((unused))\n#define DUK_INTERNAL       static __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#endif\n#else\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused)) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\")))\n#endif\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n\n#define DUK_USE_COMPILER_STRING \"emscripten\"\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#define DUK_USE_UNION_INITIALIZERS\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#undef DUK_USE_GCC_PRAGMAS\n#define DUK_USE_PACK_CLANG_ATTR\n#elif defined(DUK_F_TINYC)\n/* --- TinyC --- */\n#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"tinyc++\"\n#else\n#define DUK_USE_COMPILER_STRING \"tinyc\"\n#endif\n\n/* http://bellard.org/tcc/tcc-doc.html#SEC7 */\n#define DUK_USE_VARIADIC_MACROS\n\n#define DUK_USE_UNION_INITIALIZERS\n\n/* Most portable, wastes space */\n#define DUK_USE_FLEX_ONESIZE\n\n/* Most portable, potentially wastes space */\n#define DUK_USE_PACK_DUMMY_MEMBER\n#elif defined(DUK_F_VBCC)\n/* --- VBCC --- */\n#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"vbcc-c++\"\n#else\n#define DUK_USE_COMPILER_STRING \"vbcc\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n/* VBCC supports C99 so check only for C99 for union initializer support.\n * Designated union initializers would possibly work even without a C99 check.\n */\n#undef DUK_USE_UNION_INITIALIZERS\n#if defined(DUK_F_C99)\n#define DUK_USE_UNION_INITIALIZERS\n#endif\n\n#define DUK_USE_FLEX_ZEROSIZE\n#define DUK_USE_PACK_DUMMY_MEMBER\n#elif defined(DUK_F_BCC)\n/* --- Bruce's C compiler --- */\n#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"bcc++\"\n#else\n#define DUK_USE_COMPILER_STRING \"bcc\"\n#endif\n\n/* Most portable */\n#undef DUK_USE_VARIADIC_MACROS\n\n/* Most portable, wastes space */\n#undef DUK_USE_UNION_INITIALIZERS\n\n/* Most portable, wastes space */\n#define DUK_USE_FLEX_ONESIZE\n\n/* Most portable, potentially wastes space */\n#define DUK_USE_PACK_DUMMY_MEMBER\n\n/* BCC, assume we're on x86. */\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#else\n/* --- Generic --- */\n#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"generic-c++\"\n#else\n#define DUK_USE_COMPILER_STRING \"generic\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n/* C++ doesn't have standard designated union initializers ({ .foo = 1 }). */\n#undef DUK_USE_UNION_INITIALIZERS\n#if defined(DUK_F_C99)\n#define DUK_USE_UNION_INITIALIZERS\n#endif\n\n/* Most portable, wastes space */\n#define DUK_USE_FLEX_ONESIZE\n\n/* Most portable, potentially wastes space */\n#define DUK_USE_PACK_DUMMY_MEMBER\n#endif  /* autodetect compiler */\n\n/* uclibc */\n#if defined(__UCLIBC__)\n#define DUK_F_UCLIBC\n#endif\n\n/*\n *  Wrapper typedefs and constants for integer types, also sanity check types.\n *\n *  C99 typedefs are quite good but not always available, and we want to avoid\n *  forcibly redefining the C99 typedefs.  So, there are Duktape wrappers for\n *  all C99 typedefs and Duktape code should only use these typedefs.  Type\n *  detection when C99 is not supported is best effort and may end up detecting\n *  some types incorrectly.\n *\n *  Pointer sizes are a portability problem: pointers to different types may\n *  have a different size and function pointers are very difficult to manage\n *  portably.\n *\n *  http://en.wikipedia.org/wiki/C_data_types#Fixed-width_integer_types\n *\n *  Note: there's an interesting corner case when trying to define minimum\n *  signed integer value constants which leads to the current workaround of\n *  defining e.g. -0x80000000 as (-0x7fffffffL - 1L).  See doc/code-issues.txt\n *  for a longer discussion.\n *\n *  Note: avoid typecasts and computations in macro integer constants as they\n *  can then no longer be used in macro relational expressions (such as\n *  #if DUK_SIZE_MAX < 0xffffffffUL).  There is internal code which relies on\n *  being able to compare DUK_SIZE_MAX against a limit.\n */\n\n/* XXX: add feature options to force basic types from outside? */\n\n#if !defined(INT_MAX)\n#error INT_MAX not defined\n#endif\n\n/* Check that architecture is two's complement, standard C allows e.g.\n * INT_MIN to be -2**31+1 (instead of -2**31).\n */\n#if defined(INT_MAX) && defined(INT_MIN)\n#if INT_MAX != -(INT_MIN + 1)\n#error platform does not seem complement of two\n#endif\n#else\n#error cannot check complement of two\n#endif\n\n/* Pointer size determination based on __WORDSIZE or architecture when\n * that's not available.\n */\n#if defined(DUK_F_X86) || defined(DUK_F_X32) || \\\n    defined(DUK_F_M68K) || defined(DUK_F_PPC32) || \\\n    defined(DUK_F_BCC) || \\\n    (defined(__WORDSIZE) && (__WORDSIZE == 32)) || \\\n    ((defined(DUK_F_OLD_SOLARIS) || defined(DUK_F_AIX) || \\\n      defined(DUK_F_HPUX)) && defined(_ILP32)) || \\\n    defined(DUK_F_ARM32)\n#define DUK_F_32BIT_PTRS\n#elif defined(DUK_F_X64) || \\\n      (defined(__WORDSIZE) && (__WORDSIZE == 64)) || \\\n   ((defined(DUK_F_OLD_SOLARIS) || defined(DUK_F_AIX) || \\\n     defined(DUK_F_HPUX)) && defined(_LP64)) || \\\n    defined(DUK_F_ARM64)\n#define DUK_F_64BIT_PTRS\n#else\n/* not sure, not needed with C99 anyway */\n#endif\n\n/* Intermediate define for 'have inttypes.h' */\n#undef DUK_F_HAVE_INTTYPES\n#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \\\n    !(defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC))\n/* vbcc + AmigaOS has C99 but no inttypes.h */\n#define DUK_F_HAVE_INTTYPES\n#elif defined(__cplusplus) && (__cplusplus >= 201103L)\n/* C++11 apparently ratified stdint.h */\n#define DUK_F_HAVE_INTTYPES\n#endif\n\n/* Basic integer typedefs and limits, preferably from inttypes.h, otherwise\n * through automatic detection.\n */\n#if defined(DUK_F_HAVE_INTTYPES)\n/* C99 or compatible */\n\n#define DUK_F_HAVE_64BIT\n#include <inttypes.h>\n\ntypedef uint8_t duk_uint8_t;\ntypedef int8_t duk_int8_t;\ntypedef uint16_t duk_uint16_t;\ntypedef int16_t duk_int16_t;\ntypedef uint32_t duk_uint32_t;\ntypedef int32_t duk_int32_t;\ntypedef uint64_t duk_uint64_t;\ntypedef int64_t duk_int64_t;\ntypedef uint_least8_t duk_uint_least8_t;\ntypedef int_least8_t duk_int_least8_t;\ntypedef uint_least16_t duk_uint_least16_t;\ntypedef int_least16_t duk_int_least16_t;\ntypedef uint_least32_t duk_uint_least32_t;\ntypedef int_least32_t duk_int_least32_t;\ntypedef uint_least64_t duk_uint_least64_t;\ntypedef int_least64_t duk_int_least64_t;\ntypedef uint_fast8_t duk_uint_fast8_t;\ntypedef int_fast8_t duk_int_fast8_t;\ntypedef uint_fast16_t duk_uint_fast16_t;\ntypedef int_fast16_t duk_int_fast16_t;\ntypedef uint_fast32_t duk_uint_fast32_t;\ntypedef int_fast32_t duk_int_fast32_t;\ntypedef uint_fast64_t duk_uint_fast64_t;\ntypedef int_fast64_t duk_int_fast64_t;\ntypedef uintptr_t duk_uintptr_t;\ntypedef intptr_t duk_intptr_t;\ntypedef uintmax_t duk_uintmax_t;\ntypedef intmax_t duk_intmax_t;\n\n#define DUK_UINT8_MIN         0\n#define DUK_UINT8_MAX         UINT8_MAX\n#define DUK_INT8_MIN          INT8_MIN\n#define DUK_INT8_MAX          INT8_MAX\n#define DUK_UINT_LEAST8_MIN   0\n#define DUK_UINT_LEAST8_MAX   UINT_LEAST8_MAX\n#define DUK_INT_LEAST8_MIN    INT_LEAST8_MIN\n#define DUK_INT_LEAST8_MAX    INT_LEAST8_MAX\n#define DUK_UINT_FAST8_MIN    0\n#define DUK_UINT_FAST8_MAX    UINT_FAST8_MAX\n#define DUK_INT_FAST8_MIN     INT_FAST8_MIN\n#define DUK_INT_FAST8_MAX     INT_FAST8_MAX\n#define DUK_UINT16_MIN        0\n#define DUK_UINT16_MAX        UINT16_MAX\n#define DUK_INT16_MIN         INT16_MIN\n#define DUK_INT16_MAX         INT16_MAX\n#define DUK_UINT_LEAST16_MIN  0\n#define DUK_UINT_LEAST16_MAX  UINT_LEAST16_MAX\n#define DUK_INT_LEAST16_MIN   INT_LEAST16_MIN\n#define DUK_INT_LEAST16_MAX   INT_LEAST16_MAX\n#define DUK_UINT_FAST16_MIN   0\n#define DUK_UINT_FAST16_MAX   UINT_FAST16_MAX\n#define DUK_INT_FAST16_MIN    INT_FAST16_MIN\n#define DUK_INT_FAST16_MAX    INT_FAST16_MAX\n#define DUK_UINT32_MIN        0\n#define DUK_UINT32_MAX        UINT32_MAX\n#define DUK_INT32_MIN         INT32_MIN\n#define DUK_INT32_MAX         INT32_MAX\n#define DUK_UINT_LEAST32_MIN  0\n#define DUK_UINT_LEAST32_MAX  UINT_LEAST32_MAX\n#define DUK_INT_LEAST32_MIN   INT_LEAST32_MIN\n#define DUK_INT_LEAST32_MAX   INT_LEAST32_MAX\n#define DUK_UINT_FAST32_MIN   0\n#define DUK_UINT_FAST32_MAX   UINT_FAST32_MAX\n#define DUK_INT_FAST32_MIN    INT_FAST32_MIN\n#define DUK_INT_FAST32_MAX    INT_FAST32_MAX\n#define DUK_UINT64_MIN        0\n#define DUK_UINT64_MAX        UINT64_MAX\n#define DUK_INT64_MIN         INT64_MIN\n#define DUK_INT64_MAX         INT64_MAX\n#define DUK_UINT_LEAST64_MIN  0\n#define DUK_UINT_LEAST64_MAX  UINT_LEAST64_MAX\n#define DUK_INT_LEAST64_MIN   INT_LEAST64_MIN\n#define DUK_INT_LEAST64_MAX   INT_LEAST64_MAX\n#define DUK_UINT_FAST64_MIN   0\n#define DUK_UINT_FAST64_MAX   UINT_FAST64_MAX\n#define DUK_INT_FAST64_MIN    INT_FAST64_MIN\n#define DUK_INT_FAST64_MAX    INT_FAST64_MAX\n\n#define DUK_UINTPTR_MIN       0\n#define DUK_UINTPTR_MAX       UINTPTR_MAX\n#define DUK_INTPTR_MIN        INTPTR_MIN\n#define DUK_INTPTR_MAX        INTPTR_MAX\n\n#define DUK_UINTMAX_MIN       0\n#define DUK_UINTMAX_MAX       UINTMAX_MAX\n#define DUK_INTMAX_MIN        INTMAX_MIN\n#define DUK_INTMAX_MAX        INTMAX_MAX\n\n#define DUK_SIZE_MIN          0\n#define DUK_SIZE_MAX          SIZE_MAX\n#undef DUK_SIZE_MAX_COMPUTED\n\n#else  /* C99 types */\n\n/* When C99 types are not available, we use heuristic detection to get\n * the basic 8, 16, 32, and (possibly) 64 bit types.  The fast/least\n * types are then assumed to be exactly the same for now: these could\n * be improved per platform but C99 types are very often now available.\n * 64-bit types are not available on all platforms; this is OK at least\n * on 32-bit platforms.\n *\n * This detection code is necessarily a bit hacky and can provide typedefs\n * and defines that won't work correctly on some exotic platform.\n */\n\n#if (defined(CHAR_BIT) && (CHAR_BIT == 8)) || \\\n    (defined(UCHAR_MAX) && (UCHAR_MAX == 255))\ntypedef unsigned char duk_uint8_t;\ntypedef signed char duk_int8_t;\n#else\n#error cannot detect 8-bit type\n#endif\n\n#if defined(USHRT_MAX) && (USHRT_MAX == 65535UL)\ntypedef unsigned short duk_uint16_t;\ntypedef signed short duk_int16_t;\n#elif defined(UINT_MAX) && (UINT_MAX == 65535UL)\n/* On some platforms int is 16-bit but long is 32-bit (e.g. PureC) */\ntypedef unsigned int duk_uint16_t;\ntypedef signed int duk_int16_t;\n#else\n#error cannot detect 16-bit type\n#endif\n\n#if defined(UINT_MAX) && (UINT_MAX == 4294967295UL)\ntypedef unsigned int duk_uint32_t;\ntypedef signed int duk_int32_t;\n#elif defined(ULONG_MAX) && (ULONG_MAX == 4294967295UL)\n/* On some platforms int is 16-bit but long is 32-bit (e.g. PureC) */\ntypedef unsigned long duk_uint32_t;\ntypedef signed long duk_int32_t;\n#else\n#error cannot detect 32-bit type\n#endif\n\n/* 64-bit type detection is a bit tricky.\n *\n * ULLONG_MAX is a standard define.  __LONG_LONG_MAX__ and __ULONG_LONG_MAX__\n * are used by at least GCC (even if system headers don't provide ULLONG_MAX).\n * Some GCC variants may provide __LONG_LONG_MAX__ but not __ULONG_LONG_MAX__.\n *\n * ULL / LL constants are rejected / warned about by some compilers, even if\n * the compiler has a 64-bit type and the compiler/system headers provide an\n * unsupported constant (ULL/LL)!  Try to avoid using ULL / LL constants.\n * As a side effect we can only check that e.g. ULONG_MAX is larger than 32\n * bits but can't be sure it is exactly 64 bits.  Self tests will catch such\n * cases.\n */\n#undef DUK_F_HAVE_64BIT\n#if !defined(DUK_F_HAVE_64BIT) && defined(ULONG_MAX)\n#if (ULONG_MAX > 4294967295UL)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long duk_uint64_t;\ntypedef signed long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(ULLONG_MAX)\n#if (ULLONG_MAX > 4294967295UL)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long long duk_uint64_t;\ntypedef signed long long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(__ULONG_LONG_MAX__)\n#if (__ULONG_LONG_MAX__ > 4294967295UL)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long long duk_uint64_t;\ntypedef signed long long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(__LONG_LONG_MAX__)\n#if (__LONG_LONG_MAX__ > 2147483647L)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long long duk_uint64_t;\ntypedef signed long long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(DUK_F_MINGW)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long duk_uint64_t;\ntypedef signed long duk_int64_t;\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(DUK_F_MSVC)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned __int64 duk_uint64_t;\ntypedef signed __int64 duk_int64_t;\n#endif\n#if !defined(DUK_F_HAVE_64BIT)\n/* cannot detect 64-bit type, not always needed so don't error */\n#endif\n\ntypedef duk_uint8_t duk_uint_least8_t;\ntypedef duk_int8_t duk_int_least8_t;\ntypedef duk_uint16_t duk_uint_least16_t;\ntypedef duk_int16_t duk_int_least16_t;\ntypedef duk_uint32_t duk_uint_least32_t;\ntypedef duk_int32_t duk_int_least32_t;\ntypedef duk_uint8_t duk_uint_fast8_t;\ntypedef duk_int8_t duk_int_fast8_t;\ntypedef duk_uint16_t duk_uint_fast16_t;\ntypedef duk_int16_t duk_int_fast16_t;\ntypedef duk_uint32_t duk_uint_fast32_t;\ntypedef duk_int32_t duk_int_fast32_t;\n#if defined(DUK_F_HAVE_64BIT)\ntypedef duk_uint64_t duk_uint_least64_t;\ntypedef duk_int64_t duk_int_least64_t;\ntypedef duk_uint64_t duk_uint_fast64_t;\ntypedef duk_int64_t duk_int_fast64_t;\n#endif\n#if defined(DUK_F_HAVE_64BIT)\ntypedef duk_uint64_t duk_uintmax_t;\ntypedef duk_int64_t duk_intmax_t;\n#else\ntypedef duk_uint32_t duk_uintmax_t;\ntypedef duk_int32_t duk_intmax_t;\n#endif\n\n/* Note: the funny looking computations for signed minimum 16-bit, 32-bit, and\n * 64-bit values are intentional as the obvious forms (e.g. -0x80000000L) are\n * -not- portable.  See code-issues.txt for a detailed discussion.\n */\n#define DUK_UINT8_MIN         0UL\n#define DUK_UINT8_MAX         0xffUL\n#define DUK_INT8_MIN          (-0x80L)\n#define DUK_INT8_MAX          0x7fL\n#define DUK_UINT_LEAST8_MIN   0UL\n#define DUK_UINT_LEAST8_MAX   0xffUL\n#define DUK_INT_LEAST8_MIN    (-0x80L)\n#define DUK_INT_LEAST8_MAX    0x7fL\n#define DUK_UINT_FAST8_MIN    0UL\n#define DUK_UINT_FAST8_MAX    0xffUL\n#define DUK_INT_FAST8_MIN     (-0x80L)\n#define DUK_INT_FAST8_MAX     0x7fL\n#define DUK_UINT16_MIN        0UL\n#define DUK_UINT16_MAX        0xffffUL\n#define DUK_INT16_MIN         (-0x7fffL - 1L)\n#define DUK_INT16_MAX         0x7fffL\n#define DUK_UINT_LEAST16_MIN  0UL\n#define DUK_UINT_LEAST16_MAX  0xffffUL\n#define DUK_INT_LEAST16_MIN   (-0x7fffL - 1L)\n#define DUK_INT_LEAST16_MAX   0x7fffL\n#define DUK_UINT_FAST16_MIN   0UL\n#define DUK_UINT_FAST16_MAX   0xffffUL\n#define DUK_INT_FAST16_MIN    (-0x7fffL - 1L)\n#define DUK_INT_FAST16_MAX    0x7fffL\n#define DUK_UINT32_MIN        0UL\n#define DUK_UINT32_MAX        0xffffffffUL\n#define DUK_INT32_MIN         (-0x7fffffffL - 1L)\n#define DUK_INT32_MAX         0x7fffffffL\n#define DUK_UINT_LEAST32_MIN  0UL\n#define DUK_UINT_LEAST32_MAX  0xffffffffUL\n#define DUK_INT_LEAST32_MIN   (-0x7fffffffL - 1L)\n#define DUK_INT_LEAST32_MAX   0x7fffffffL\n#define DUK_UINT_FAST32_MIN   0UL\n#define DUK_UINT_FAST32_MAX   0xffffffffUL\n#define DUK_INT_FAST32_MIN    (-0x7fffffffL - 1L)\n#define DUK_INT_FAST32_MAX    0x7fffffffL\n\n/* 64-bit constants.  Since LL / ULL constants are not always available,\n * use computed values.  These values can't be used in preprocessor\n * comparisons; flag them as such.\n */\n#if defined(DUK_F_HAVE_64BIT)\n#define DUK_UINT64_MIN        ((duk_uint64_t) 0)\n#define DUK_UINT64_MAX        ((duk_uint64_t) -1)\n#define DUK_INT64_MIN         ((duk_int64_t) (~(DUK_UINT64_MAX >> 1)))\n#define DUK_INT64_MAX         ((duk_int64_t) (DUK_UINT64_MAX >> 1))\n#define DUK_UINT_LEAST64_MIN  DUK_UINT64_MIN\n#define DUK_UINT_LEAST64_MAX  DUK_UINT64_MAX\n#define DUK_INT_LEAST64_MIN   DUK_INT64_MIN\n#define DUK_INT_LEAST64_MAX   DUK_INT64_MAX\n#define DUK_UINT_FAST64_MIN   DUK_UINT64_MIN\n#define DUK_UINT_FAST64_MAX   DUK_UINT64_MAX\n#define DUK_INT_FAST64_MIN    DUK_INT64_MIN\n#define DUK_INT_FAST64_MAX    DUK_INT64_MAX\n#define DUK_UINT64_MIN_COMPUTED\n#define DUK_UINT64_MAX_COMPUTED\n#define DUK_INT64_MIN_COMPUTED\n#define DUK_INT64_MAX_COMPUTED\n#define DUK_UINT_LEAST64_MIN_COMPUTED\n#define DUK_UINT_LEAST64_MAX_COMPUTED\n#define DUK_INT_LEAST64_MIN_COMPUTED\n#define DUK_INT_LEAST64_MAX_COMPUTED\n#define DUK_UINT_FAST64_MIN_COMPUTED\n#define DUK_UINT_FAST64_MAX_COMPUTED\n#define DUK_INT_FAST64_MIN_COMPUTED\n#define DUK_INT_FAST64_MAX_COMPUTED\n#endif\n\n#if defined(DUK_F_HAVE_64BIT)\n#define DUK_UINTMAX_MIN       DUK_UINT64_MIN\n#define DUK_UINTMAX_MAX       DUK_UINT64_MAX\n#define DUK_INTMAX_MIN        DUK_INT64_MIN\n#define DUK_INTMAX_MAX        DUK_INT64_MAX\n#define DUK_UINTMAX_MIN_COMPUTED\n#define DUK_UINTMAX_MAX_COMPUTED\n#define DUK_INTMAX_MIN_COMPUTED\n#define DUK_INTMAX_MAX_COMPUTED\n#else\n#define DUK_UINTMAX_MIN       0UL\n#define DUK_UINTMAX_MAX       0xffffffffUL\n#define DUK_INTMAX_MIN        (-0x7fffffffL - 1L)\n#define DUK_INTMAX_MAX        0x7fffffffL\n#endif\n\n/* This detection is not very reliable. */\n#if defined(DUK_F_32BIT_PTRS)\ntypedef duk_int32_t duk_intptr_t;\ntypedef duk_uint32_t duk_uintptr_t;\n#define DUK_UINTPTR_MIN       DUK_UINT32_MIN\n#define DUK_UINTPTR_MAX       DUK_UINT32_MAX\n#define DUK_INTPTR_MIN        DUK_INT32_MIN\n#define DUK_INTPTR_MAX        DUK_INT32_MAX\n#elif defined(DUK_F_64BIT_PTRS) && defined(DUK_F_HAVE_64BIT)\ntypedef duk_int64_t duk_intptr_t;\ntypedef duk_uint64_t duk_uintptr_t;\n#define DUK_UINTPTR_MIN       DUK_UINT64_MIN\n#define DUK_UINTPTR_MAX       DUK_UINT64_MAX\n#define DUK_INTPTR_MIN        DUK_INT64_MIN\n#define DUK_INTPTR_MAX        DUK_INT64_MAX\n#define DUK_UINTPTR_MIN_COMPUTED\n#define DUK_UINTPTR_MAX_COMPUTED\n#define DUK_INTPTR_MIN_COMPUTED\n#define DUK_INTPTR_MAX_COMPUTED\n#else\n#error cannot determine intptr type\n#endif\n\n/* SIZE_MAX may be missing so use an approximate value for it. */\n#undef DUK_SIZE_MAX_COMPUTED\n#if !defined(SIZE_MAX)\n#define DUK_SIZE_MAX_COMPUTED\n#define SIZE_MAX              ((size_t) (-1))\n#endif\n#define DUK_SIZE_MIN          0\n#define DUK_SIZE_MAX          SIZE_MAX\n\n#endif  /* C99 types */\n\n/* A few types are assumed to always exist. */\ntypedef size_t duk_size_t;\ntypedef ptrdiff_t duk_ptrdiff_t;\n\n/* The best type for an \"all around int\" in Duktape internals is \"at least\n * 32 bit signed integer\" which is most convenient.  Same for unsigned type.\n * Prefer 'int' when large enough, as it is almost always a convenient type.\n */\n#if defined(UINT_MAX) && (UINT_MAX >= 0xffffffffUL)\ntypedef int duk_int_t;\ntypedef unsigned int duk_uint_t;\n#define DUK_INT_MIN           INT_MIN\n#define DUK_INT_MAX           INT_MAX\n#define DUK_UINT_MIN          0\n#define DUK_UINT_MAX          UINT_MAX\n#else\ntypedef duk_int_fast32_t duk_int_t;\ntypedef duk_uint_fast32_t duk_uint_t;\n#define DUK_INT_MIN           DUK_INT_FAST32_MIN\n#define DUK_INT_MAX           DUK_INT_FAST32_MAX\n#define DUK_UINT_MIN          DUK_UINT_FAST32_MIN\n#define DUK_UINT_MAX          DUK_UINT_FAST32_MAX\n#endif\n\n/* Same as 'duk_int_t' but guaranteed to be a 'fast' variant if this\n * distinction matters for the CPU.  These types are used mainly in the\n * executor where it might really matter.\n */\ntypedef duk_int_fast32_t duk_int_fast_t;\ntypedef duk_uint_fast32_t duk_uint_fast_t;\n#define DUK_INT_FAST_MIN      DUK_INT_FAST32_MIN\n#define DUK_INT_FAST_MAX      DUK_INT_FAST32_MAX\n#define DUK_UINT_FAST_MIN     DUK_UINT_FAST32_MIN\n#define DUK_UINT_FAST_MAX     DUK_UINT_FAST32_MAX\n\n/* Small integers (16 bits or more) can fall back to the 'int' type, but\n * have a typedef so they are marked \"small\" explicitly.\n */\ntypedef int duk_small_int_t;\ntypedef unsigned int duk_small_uint_t;\n#define DUK_SMALL_INT_MIN     INT_MIN\n#define DUK_SMALL_INT_MAX     INT_MAX\n#define DUK_SMALL_UINT_MIN    0\n#define DUK_SMALL_UINT_MAX    UINT_MAX\n\n/* Fast variants of small integers, again for really fast paths like the\n * executor.\n */\ntypedef duk_int_fast16_t duk_small_int_fast_t;\ntypedef duk_uint_fast16_t duk_small_uint_fast_t;\n#define DUK_SMALL_INT_FAST_MIN    DUK_INT_FAST16_MIN\n#define DUK_SMALL_INT_FAST_MAX    DUK_INT_FAST16_MAX\n#define DUK_SMALL_UINT_FAST_MIN   DUK_UINT_FAST16_MIN\n#define DUK_SMALL_UINT_FAST_MAX   DUK_UINT_FAST16_MAX\n\n/* Boolean values are represented with the platform 'unsigned int'. */\ntypedef duk_small_uint_t duk_bool_t;\n#define DUK_BOOL_MIN              DUK_SMALL_UINT_MIN\n#define DUK_BOOL_MAX              DUK_SMALL_UINT_MAX\n\n/* Index values must have at least 32-bit signed range. */\ntypedef duk_int_t duk_idx_t;\n#define DUK_IDX_MIN               DUK_INT_MIN\n#define DUK_IDX_MAX               DUK_INT_MAX\n\n/* Unsigned index variant. */\ntypedef duk_uint_t duk_uidx_t;\n#define DUK_UIDX_MIN              DUK_UINT_MIN\n#define DUK_UIDX_MAX              DUK_UINT_MAX\n\n/* Array index values, could be exact 32 bits.\n * Currently no need for signed duk_arridx_t.\n */\ntypedef duk_uint_t duk_uarridx_t;\n#define DUK_UARRIDX_MIN           DUK_UINT_MIN\n#define DUK_UARRIDX_MAX           DUK_UINT_MAX\n\n/* Duktape/C function return value, platform int is enough for now to\n * represent 0, 1, or negative error code.  Must be compatible with\n * assigning truth values (e.g. duk_ret_t rc = (foo == bar);).\n */\ntypedef duk_small_int_t duk_ret_t;\n#define DUK_RET_MIN               DUK_SMALL_INT_MIN\n#define DUK_RET_MAX               DUK_SMALL_INT_MAX\n\n/* Error codes are represented with platform int.  High bits are used\n * for flags and such, so 32 bits are needed.\n */\ntypedef duk_int_t duk_errcode_t;\n#define DUK_ERRCODE_MIN           DUK_INT_MIN\n#define DUK_ERRCODE_MAX           DUK_INT_MAX\n\n/* Codepoint type.  Must be 32 bits or more because it is used also for\n * internal codepoints.  The type is signed because negative codepoints\n * are used as internal markers (e.g. to mark EOF or missing argument).\n * (X)UTF-8/CESU-8 encode/decode take and return an unsigned variant to\n * ensure duk_uint32_t casts back and forth nicely.  Almost everything\n * else uses the signed one.\n */\ntypedef duk_int_t duk_codepoint_t;\ntypedef duk_uint_t duk_ucodepoint_t;\n#define DUK_CODEPOINT_MIN         DUK_INT_MIN\n#define DUK_CODEPOINT_MAX         DUK_INT_MAX\n#define DUK_UCODEPOINT_MIN        DUK_UINT_MIN\n#define DUK_UCODEPOINT_MAX        DUK_UINT_MAX\n\n/* IEEE float/double typedef. */\ntypedef float duk_float_t;\ntypedef double duk_double_t;\n\n/* We're generally assuming that we're working on a platform with a 32-bit\n * address space.  If DUK_SIZE_MAX is a typecast value (which is necessary\n * if SIZE_MAX is missing), the check must be avoided because the\n * preprocessor can't do a comparison.\n */\n#if !defined(DUK_SIZE_MAX)\n#error DUK_SIZE_MAX is undefined, probably missing SIZE_MAX\n#elif !defined(DUK_SIZE_MAX_COMPUTED)\n#if DUK_SIZE_MAX < 0xffffffffUL\n/* On some systems SIZE_MAX can be smaller than max unsigned 32-bit value\n * which seems incorrect if size_t is (at least) an unsigned 32-bit type.\n * However, it doesn't seem useful to error out compilation if this is the\n * case.\n */\n#endif\n#endif\n\n/* Type used in public API declarations and user code.  Typedef maps to\n * 'struct duk_hthread' like the 'duk_hthread' typedef which is used\n * exclusively in internals.\n */\ntypedef struct duk_hthread duk_context;\n\n/* Check whether we should use 64-bit integers or not.\n *\n * Quite incomplete now.  Use 64-bit types if detected (C99 or other detection)\n * unless they are known to be unreliable.  For instance, 64-bit types are\n * available on VBCC but seem to misbehave.\n */\n#if defined(DUK_F_HAVE_64BIT) && !defined(DUK_F_VBCC)\n#define DUK_USE_64BIT_OPS\n#else\n#undef DUK_USE_64BIT_OPS\n#endif\n\n/*\n *  Fill-ins for platform, architecture, and compiler\n */\n\n/* An abort()-like primitive is needed by the default fatal error handler. */\n#if !defined(DUK_ABORT)\n#define DUK_ABORT             abort\n#endif\n\n#if !defined(DUK_SETJMP)\n#define DUK_JMPBUF_TYPE       jmp_buf\n#define DUK_SETJMP(jb)        setjmp((jb))\n#define DUK_LONGJMP(jb)       longjmp((jb), 1)\n#endif\n\n#if 0\n/* sigsetjmp() alternative */\n#define DUK_JMPBUF_TYPE       sigjmp_buf\n#define DUK_SETJMP(jb)        sigsetjmp((jb))\n#define DUK_LONGJMP(jb)       siglongjmp((jb), 1)\n#endif\n\n/* Special naming to avoid conflict with e.g. DUK_FREE() in duk_heap.h\n * (which is unfortunately named).  May sometimes need replacement, e.g.\n * some compilers don't handle zero length or NULL correctly in realloc().\n */\n#if !defined(DUK_ANSI_MALLOC)\n#define DUK_ANSI_MALLOC      malloc\n#endif\n#if !defined(DUK_ANSI_REALLOC)\n#define DUK_ANSI_REALLOC     realloc\n#endif\n#if !defined(DUK_ANSI_CALLOC)\n#define DUK_ANSI_CALLOC      calloc\n#endif\n#if !defined(DUK_ANSI_FREE)\n#define DUK_ANSI_FREE        free\n#endif\n\n/* ANSI C (various versions) and some implementations require that the\n * pointer arguments to memset(), memcpy(), and memmove() be valid values\n * even when byte size is 0 (even a NULL pointer is considered invalid in\n * this context).  Zero-size operations as such are allowed, as long as their\n * pointer arguments point to a valid memory area.  The DUK_MEMSET(),\n * DUK_MEMCPY(), and DUK_MEMMOVE() macros require this same behavior, i.e.:\n * (1) pointers must be valid and non-NULL, (2) zero size must otherwise be\n * allowed.  If these are not fulfilled, a macro wrapper is needed.\n *\n *   http://stackoverflow.com/questions/5243012/is-it-guaranteed-to-be-safe-to-perform-memcpy0-0-0\n *   http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-October/011065.html\n *\n * Not sure what's the required behavior when a pointer points just past the\n * end of a buffer, which often happens in practice (e.g. zero size memmoves).\n * For example, if allocation size is 3, the following pointer would not\n * technically point to a valid memory byte:\n *\n *   <-- alloc -->\n *   | 0 | 1 | 2 | .....\n *                 ^-- p=3, points after last valid byte (2)\n */\n#if !defined(DUK_MEMCPY)\n#if defined(DUK_F_UCLIBC)\n/* Old uclibcs have a broken memcpy so use memmove instead (this is overly wide\n * now on purpose): http://lists.uclibc.org/pipermail/uclibc-cvs/2008-October/025511.html\n */\n#define DUK_MEMCPY       memmove\n#else\n#define DUK_MEMCPY       memcpy\n#endif\n#endif\n#if !defined(DUK_MEMMOVE)\n#define DUK_MEMMOVE      memmove\n#endif\n#if !defined(DUK_MEMCMP)\n#define DUK_MEMCMP       memcmp\n#endif\n#if !defined(DUK_MEMSET)\n#define DUK_MEMSET       memset\n#endif\n#if !defined(DUK_STRLEN)\n#define DUK_STRLEN       strlen\n#endif\n#if !defined(DUK_STRCMP)\n#define DUK_STRCMP       strcmp\n#endif\n#if !defined(DUK_STRNCMP)\n#define DUK_STRNCMP      strncmp\n#endif\n#if !defined(DUK_SPRINTF)\n#define DUK_SPRINTF      sprintf\n#endif\n#if !defined(DUK_SNPRINTF)\n/* snprintf() is technically not part of C89 but usually available. */\n#define DUK_SNPRINTF     snprintf\n#endif\n#if !defined(DUK_VSPRINTF)\n#define DUK_VSPRINTF     vsprintf\n#endif\n#if !defined(DUK_VSNPRINTF)\n/* vsnprintf() is technically not part of C89 but usually available. */\n#define DUK_VSNPRINTF    vsnprintf\n#endif\n#if !defined(DUK_SSCANF)\n#define DUK_SSCANF       sscanf\n#endif\n#if !defined(DUK_VSSCANF)\n#define DUK_VSSCANF      vsscanf\n#endif\n#if !defined(DUK_MEMZERO)\n#define DUK_MEMZERO(p,n) DUK_MEMSET((p), 0, (n))\n#endif\n\n#if !defined(DUK_DOUBLE_INFINITY)\n#undef DUK_USE_COMPUTED_INFINITY\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION < 40600)\n/* GCC older than 4.6: avoid overflow warnings related to using INFINITY */\n#define DUK_DOUBLE_INFINITY  (__builtin_inf())\n#elif defined(INFINITY)\n#define DUK_DOUBLE_INFINITY  ((double) INFINITY)\n#elif !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) && !defined(DUK_F_BCC) && \\\n      !defined(DUK_F_OLD_SOLARIS) && !defined(DUK_F_AIX)\n#define DUK_DOUBLE_INFINITY  (1.0 / 0.0)\n#else\n/* In VBCC (1.0 / 0.0) results in a warning and 0.0 instead of infinity.\n * Use a computed infinity (initialized when a heap is created at the\n * latest).\n */\n#define DUK_USE_COMPUTED_INFINITY\n#define DUK_DOUBLE_INFINITY  duk_computed_infinity\n#endif\n#endif\n\n#if !defined(DUK_DOUBLE_NAN)\n#undef DUK_USE_COMPUTED_NAN\n#if defined(NAN)\n#define DUK_DOUBLE_NAN       NAN\n#elif !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) && !defined(DUK_F_BCC) && \\\n      !defined(DUK_F_OLD_SOLARIS) && !defined(DUK_F_AIX)\n#define DUK_DOUBLE_NAN       (0.0 / 0.0)\n#else\n/* In VBCC (0.0 / 0.0) results in a warning and 0.0 instead of NaN.\n * In MSVC (VS2010 Express) (0.0 / 0.0) results in a compile error.\n * Use a computed NaN (initialized when a heap is created at the\n * latest).\n */\n#define DUK_USE_COMPUTED_NAN\n#define DUK_DOUBLE_NAN       duk_computed_nan\n#endif\n#endif\n\n/* Many platforms are missing fpclassify() and friends, so use replacements\n * if necessary.  The replacement constants (FP_NAN etc) can be anything but\n * match Linux constants now.\n */\n#undef DUK_USE_REPL_FPCLASSIFY\n#undef DUK_USE_REPL_SIGNBIT\n#undef DUK_USE_REPL_ISFINITE\n#undef DUK_USE_REPL_ISNAN\n#undef DUK_USE_REPL_ISINF\n\n/* Complex condition broken into separate parts. */\n#undef DUK_F_USE_REPL_ALL\n#if !(defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO) && \\\n      defined(FP_SUBNORMAL) && defined(FP_NORMAL))\n/* Missing some obvious constants. */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC)\n/* VBCC is missing the built-ins even in C99 mode (perhaps a header issue). */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_AMIGAOS) && defined(DUK_F_M68K)\n/* AmigaOS + M68K seems to have math issues even when using GCC cross\n * compilation.  Use replacements for all AmigaOS versions on M68K\n * regardless of compiler.\n */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_FREEBSD) && defined(DUK_F_CLANG)\n/* Placeholder fix for (detection is wider than necessary):\n * http://llvm.org/bugs/show_bug.cgi?id=17788\n */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_UCLIBC)\n/* At least some uclibc versions have broken floating point math.  For\n * example, fpclassify() can incorrectly classify certain NaN formats.\n * To be safe, use replacements.\n */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_AIX)\n/* Older versions may be missing isnan(), etc. */\n#define DUK_F_USE_REPL_ALL\n#endif\n\n#if defined(DUK_F_USE_REPL_ALL)\n#define DUK_USE_REPL_FPCLASSIFY\n#define DUK_USE_REPL_SIGNBIT\n#define DUK_USE_REPL_ISFINITE\n#define DUK_USE_REPL_ISNAN\n#define DUK_USE_REPL_ISINF\n#define DUK_FPCLASSIFY       duk_repl_fpclassify\n#define DUK_SIGNBIT          duk_repl_signbit\n#define DUK_ISFINITE         duk_repl_isfinite\n#define DUK_ISNAN            duk_repl_isnan\n#define DUK_ISINF            duk_repl_isinf\n#define DUK_FP_NAN           0\n#define DUK_FP_INFINITE      1\n#define DUK_FP_ZERO          2\n#define DUK_FP_SUBNORMAL     3\n#define DUK_FP_NORMAL        4\n#else\n#define DUK_FPCLASSIFY       fpclassify\n#define DUK_SIGNBIT          signbit\n#define DUK_ISFINITE         isfinite\n#define DUK_ISNAN            isnan\n#define DUK_ISINF            isinf\n#define DUK_FP_NAN           FP_NAN\n#define DUK_FP_INFINITE      FP_INFINITE\n#define DUK_FP_ZERO          FP_ZERO\n#define DUK_FP_SUBNORMAL     FP_SUBNORMAL\n#define DUK_FP_NORMAL        FP_NORMAL\n#endif\n\n#if defined(DUK_F_USE_REPL_ALL)\n#undef DUK_F_USE_REPL_ALL\n#endif\n\n/* These functions don't currently need replacement but are wrapped for\n * completeness.  Because these are used as function pointers, they need\n * to be defined as concrete C functions (not macros).\n */\n#if !defined(DUK_FABS)\n#define DUK_FABS             fabs\n#endif\n#if !defined(DUK_FLOOR)\n#define DUK_FLOOR            floor\n#endif\n#if !defined(DUK_CEIL)\n#define DUK_CEIL             ceil\n#endif\n#if !defined(DUK_FMOD)\n#define DUK_FMOD             fmod\n#endif\n#if !defined(DUK_POW)\n#define DUK_POW              pow\n#endif\n#if !defined(DUK_ACOS)\n#define DUK_ACOS             acos\n#endif\n#if !defined(DUK_ASIN)\n#define DUK_ASIN             asin\n#endif\n#if !defined(DUK_ATAN)\n#define DUK_ATAN             atan\n#endif\n#if !defined(DUK_ATAN2)\n#define DUK_ATAN2            atan2\n#endif\n#if !defined(DUK_SIN)\n#define DUK_SIN              sin\n#endif\n#if !defined(DUK_COS)\n#define DUK_COS              cos\n#endif\n#if !defined(DUK_TAN)\n#define DUK_TAN              tan\n#endif\n#if !defined(DUK_EXP)\n#define DUK_EXP              exp\n#endif\n#if !defined(DUK_LOG)\n#define DUK_LOG              log\n#endif\n#if !defined(DUK_SQRT)\n#define DUK_SQRT             sqrt\n#endif\n\n/* The functions below exist only in C99/C++11 or later and need a workaround\n * for platforms that don't include them.  MSVC isn't detected as C99, but\n * these functions also exist in MSVC 2013 and later so include a clause for\n * that too.  Android doesn't have log2; disable all of these for Android.\n */\n#if (defined(DUK_F_C99) || defined(DUK_F_CPP11) || (defined(_MSC_VER) && (_MSC_VER >= 1800))) && \\\n    !defined(DUK_F_ANDROID) && !defined(DUK_F_MINT)\n#if !defined(DUK_CBRT)\n#define DUK_CBRT             cbrt\n#endif\n#if !defined(DUK_LOG2)\n#define DUK_LOG2             log2\n#endif\n#if !defined(DUK_LOG10)\n#define DUK_LOG10            log10\n#endif\n#if !defined(DUK_TRUNC)\n#define DUK_TRUNC            trunc\n#endif\n#endif  /* DUK_F_C99 etc */\n\n/* NetBSD 6.0 x86 (at least) has a few problems with pow() semantics,\n * see test-bug-netbsd-math-pow.js.  MinGW has similar (but different)\n * issues, see test-bug-mingw-math-issues.js.  Enable pow() workarounds\n * for these targets.\n */\n#undef DUK_USE_POW_WORKAROUNDS\n#if defined(DUK_F_NETBSD) || defined(DUK_F_MINGW)\n#define DUK_USE_POW_WORKAROUNDS\n#endif\n\n/* Similar workarounds for atan2() semantics issues.  MinGW issues are\n * documented in test-bug-mingw-math-issues.js.\n */\n#undef DUK_USE_ATAN2_WORKAROUNDS\n#if defined(DUK_F_MINGW)\n#define DUK_USE_ATAN2_WORKAROUNDS\n#endif\n\n/* Rely as little as possible on compiler behavior for NaN comparison,\n * signed zero handling, etc.  Currently never activated but may be needed\n * for broken compilers.\n */\n#undef DUK_USE_PARANOID_MATH\n\n/* There was a curious bug where test-bi-date-canceling.js would fail e.g.\n * on 64-bit Ubuntu, gcc-4.8.1, -m32, and no -std=c99.  Some date computations\n * using doubles would be optimized which then broke some corner case tests.\n * The problem goes away by adding 'volatile' to the datetime computations.\n * Not sure what the actual triggering conditions are, but using this on\n * non-C99 systems solves the known issues and has relatively little cost\n * on other platforms.\n */\n#undef DUK_USE_PARANOID_DATE_COMPUTATION\n#if !defined(DUK_F_C99)\n#define DUK_USE_PARANOID_DATE_COMPUTATION\n#endif\n\n/*\n *  Byte order and double memory layout detection\n *\n *  Endianness detection is a major portability hassle because the macros\n *  and headers are not standardized.  There's even variance across UNIX\n *  platforms.  Even with \"standard\" headers, details like underscore count\n *  varies between platforms, e.g. both __BYTE_ORDER and _BYTE_ORDER are used\n *  (Crossbridge has a single underscore, for instance).\n *\n *  The checks below are structured with this in mind: several approaches are\n *  used, and at the end we check if any of them worked.  This allows generic\n *  approaches to be tried first, and platform/compiler specific hacks tried\n *  last.  As a last resort, the user can force a specific endianness, as it's\n *  not likely that automatic detection will work on the most exotic platforms.\n *\n *  Duktape supports little and big endian machines.  There's also support\n *  for a hybrid used by some ARM machines where integers are little endian\n *  but IEEE double values use a mixed order (12345678 -> 43218765).  This\n *  byte order for doubles is referred to as \"mixed endian\".\n */\n\n/* GCC and Clang provide endianness defines as built-in predefines, with\n * leading and trailing double underscores (e.g. __BYTE_ORDER__).  See\n * output of \"make gccpredefs\" and \"make clangpredefs\".  Clang doesn't\n * seem to provide __FLOAT_WORD_ORDER__; assume not mixed endian for clang.\n * http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html\n */\n#if !defined(DUK_USE_BYTEORDER) && defined(__BYTE_ORDER__)\n#if defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__)\n#define DUK_USE_BYTEORDER 1\n#elif defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__)\n#define DUK_USE_BYTEORDER 2\n#elif !defined(__FLOAT_WORD_ORDER__)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 1\n#else\n/* Byte order is little endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#elif defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__)\n#define DUK_USE_BYTEORDER 3\n#elif !defined(__FLOAT_WORD_ORDER__)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 3\n#else\n/* Byte order is big endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#else\n/* Cannot determine byte order; __ORDER_PDP_ENDIAN__ is related to 32-bit\n * integer ordering and is not relevant.\n */\n#endif  /* integer byte order */\n#endif  /* !defined(DUK_USE_BYTEORDER) && defined(__BYTE_ORDER__) */\n\n/* More or less standard endianness predefines provided by header files.\n * The ARM hybrid case is detected by assuming that __FLOAT_WORD_ORDER\n * will be big endian, see: http://lists.mysql.com/internals/443.\n * On some platforms some defines may be present with an empty value which\n * causes comparisons to fail: https://github.com/svaarala/duktape/issues/453.\n */\n#if !defined(DUK_USE_BYTEORDER)\n#if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN) || \\\n    defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN) || \\\n    defined(__LITTLE_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER) && defined(__LITTLE_ENDIAN) && (__FLOAT_WORD_ORDER == __LITTLE_ENDIAN) || \\\n    defined(_FLOAT_WORD_ORDER) && defined(_LITTLE_ENDIAN) && (_FLOAT_WORD_ORDER == _LITTLE_ENDIAN)\n#define DUK_USE_BYTEORDER 1\n#elif defined(__FLOAT_WORD_ORDER) && defined(__BIG_ENDIAN) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN) || \\\n      defined(_FLOAT_WORD_ORDER) && defined(_BIG_ENDIAN) && (_FLOAT_WORD_ORDER == _BIG_ENDIAN)\n#define DUK_USE_BYTEORDER 2\n#elif !defined(__FLOAT_WORD_ORDER) && !defined(_FLOAT_WORD_ORDER)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 1\n#else\n/* Byte order is little endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN) || \\\n      defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN) || \\\n      defined(__BIG_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER) && defined(__BIG_ENDIAN) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN) || \\\n    defined(_FLOAT_WORD_ORDER) && defined(_BIG_ENDIAN) && (_FLOAT_WORD_ORDER == _BIG_ENDIAN)\n#define DUK_USE_BYTEORDER 3\n#elif !defined(__FLOAT_WORD_ORDER) && !defined(_FLOAT_WORD_ORDER)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 3\n#else\n/* Byte order is big endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#else\n/* Cannot determine byte order. */\n#endif  /* integer byte order */\n#endif  /* !defined(DUK_USE_BYTEORDER) */\n\n/* QNX gcc cross compiler seems to define e.g. __LITTLEENDIAN__ or __BIGENDIAN__:\n *  $ /opt/qnx650/host/linux/x86/usr/bin/i486-pc-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian\n *  67:#define __LITTLEENDIAN__ 1\n *  $ /opt/qnx650/host/linux/x86/usr/bin/mips-unknown-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian\n *  81:#define __BIGENDIAN__ 1\n *  $ /opt/qnx650/host/linux/x86/usr/bin/arm-unknown-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian\n *  70:#define __LITTLEENDIAN__ 1\n */\n#if !defined(DUK_USE_BYTEORDER)\n#if defined(__LITTLEENDIAN__)\n#define DUK_USE_BYTEORDER 1\n#elif defined(__BIGENDIAN__)\n#define DUK_USE_BYTEORDER 3\n#endif\n#endif\n\n/*\n *  Alignment requirement and support for unaligned accesses\n *\n *  Assume unaligned accesses are not supported unless specifically allowed\n *  in the target platform.  Some platforms may support unaligned accesses\n *  but alignment to 4 or 8 may still be desirable.  Note that unaligned\n *  accesses (and even pointers) relative to natural alignment (regardless\n *  of target alignment) are technically undefined behavior and thus\n *  compiler/architecture specific.\n */\n\n/* If not forced, use safe default for alignment. */\n#if !defined(DUK_USE_ALIGN_BY)\n#define DUK_USE_ALIGN_BY 8\n#endif\n\n/* Compiler specific hackery needed to force struct size to match alignment,\n * see e.g. duk_hbuffer.h.\n *\n * http://stackoverflow.com/questions/11130109/c-struct-size-alignment\n * http://stackoverflow.com/questions/10951039/specifying-64-bit-alignment\n */\n#if !(defined(DUK_USE_PACK_MSVC_PRAGMA) || defined(DUK_USE_PACK_GCC_ATTR) || \\\n      defined(DUK_USE_PACK_CLANG_ATTR) || defined(DUK_USE_PACK_DUMMY_MEMBER))\n#define DUK_USE_PACK_DUMMY_MEMBER\n#endif\n\n#if !defined(DUK_U64_CONSTANT)\n#define DUK_U64_CONSTANT(x) x##ULL\n#endif\n#if !defined(DUK_I64_CONSTANT)\n#define DUK_I64_CONSTANT(x) x##LL\n#endif\n\n#if !defined(DUK_VA_COPY)\n/* We need va_copy() which is defined in C99 / C++11, so an awkward\n * replacement is needed for pre-C99 / pre-C++11 environments.  This\n * will quite likely need portability hacks for some non-C99\n * environments.\n */\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n/* C99 / C++11 and above: rely on va_copy() which is required.\n * Omit parenthesis on macro right side on purpose to minimize differences\n * to direct use.\n */\n#define DUK_VA_COPY(dest,src) va_copy(dest,src)\n#else\n/* Pre-C99: va_list type is implementation dependent.  This replacement\n * assumes it is a plain value so that a simple assignment will work.\n * This is not the case on all platforms (it may be a single-array element,\n * for instance).\n */\n#define DUK_VA_COPY(dest,src) do { (dest) = (src); } while (0)\n#endif\n#endif\n\n#if !defined(DUK_MACRO_STRINGIFY)\n/* Macro hackery to convert e.g. __LINE__ to a string without formatting,\n * see: http://stackoverflow.com/questions/240353/convert-a-preprocessor-token-to-a-string\n */\n#define DUK_MACRO_STRINGIFY_HELPER(x)  #x\n#define DUK_MACRO_STRINGIFY(x)  DUK_MACRO_STRINGIFY_HELPER(x)\n#endif\n\n#if !defined(DUK_CAUSE_SEGFAULT)\n/* This can be used for testing; valgrind will then indicate the C call stack\n * leading to the call site.\n */\n#define DUK_CAUSE_SEGFAULT()  do { *((volatile duk_uint32_t *) NULL) = (duk_uint32_t) 0xdeadbeefUL; } while (0)\n#endif\n\n#if !defined(DUK_UNREF)\n/* Macro for suppressing warnings for potentially unreferenced variables.\n * The variables can be actually unreferenced or unreferenced in some\n * specific cases only; for instance, if a variable is only debug printed,\n * it is unreferenced when debug printing is disabled.  May cause warnings\n * for volatile arguments.\n */\n#define DUK_UNREF(x)  do { (void) (x); } while (0)\n#endif\n\n/* Fillin for DUK_NORETURN; DUK_WO_NORETURN() is used to insert dummy\n * dummy statements after noreturn calls to silence harmless compiler\n * warnings, e.g.:\n *\n *   DUK_ERROR_TYPE(thr, \"aiee\");\n *   DUK_WO_NORETURN(return 0;);\n *\n * Statements inside DUK_WO_NORETURN() must NEVER be actually reachable,\n * and they're only included to satisfy the compiler.\n */\n#if defined(DUK_NORETURN)\n#define DUK_WO_NORETURN(stmt) do { } while (0)\n#else\n#define DUK_NORETURN(decl)  decl\n#define DUK_WO_NORETURN(stmt) do { stmt } while (0)\n#endif\n\n#if !defined(DUK_UNREACHABLE)\n/* Don't know how to declare unreachable point, so don't do it; this\n * may cause some spurious compilation warnings (e.g. \"variable used\n * uninitialized\").\n */\n#define DUK_UNREACHABLE()  do { } while (0)\n#endif\n\n#if !defined(DUK_LOSE_CONST)\n/* Convert any input pointer into a \"void *\", losing a const qualifier.\n * This is not fully portable because casting through duk_uintptr_t may\n * not work on all architectures (e.g. those with long, segmented pointers).\n */\n#define DUK_LOSE_CONST(src) ((void *) (duk_uintptr_t) (src))\n#endif\n\n#if !defined(DUK_LIKELY)\n#define DUK_LIKELY(x)    (x)\n#endif\n#if !defined(DUK_UNLIKELY)\n#define DUK_UNLIKELY(x)  (x)\n#endif\n#if !defined(DUK_UNPREDICTABLE)\n#define DUK_UNPREDICTABLE(x)  (x)\n#endif\n\n#if !defined(DUK_NOINLINE)\n#define DUK_NOINLINE       /*nop*/\n#endif\n#if !defined(DUK_INLINE)\n#define DUK_INLINE         /*nop*/\n#endif\n#if !defined(DUK_ALWAYS_INLINE)\n#define DUK_ALWAYS_INLINE  /*nop*/\n#endif\n\n#if !defined(DUK_HOT)\n#define DUK_HOT            /*nop*/\n#endif\n#if !defined(DUK_COLD)\n#define DUK_COLD           /*nop*/\n#endif\n\n#if !defined(DUK_EXTERNAL_DECL)\n#define DUK_EXTERNAL_DECL  extern\n#endif\n#if !defined(DUK_EXTERNAL)\n#define DUK_EXTERNAL       /*empty*/\n#endif\n#if !defined(DUK_INTERNAL_DECL)\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL_DECL  static\n#else\n#define DUK_INTERNAL_DECL  extern\n#endif\n#endif\n#if !defined(DUK_INTERNAL)\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL       static\n#else\n#define DUK_INTERNAL       /*empty*/\n#endif\n#endif\n#if !defined(DUK_LOCAL_DECL)\n#define DUK_LOCAL_DECL     static\n#endif\n#if !defined(DUK_LOCAL)\n#define DUK_LOCAL          static\n#endif\n\n#if !defined(DUK_FILE_MACRO)\n#define DUK_FILE_MACRO  __FILE__\n#endif\n#if !defined(DUK_LINE_MACRO)\n#define DUK_LINE_MACRO  __LINE__\n#endif\n#if !defined(DUK_FUNC_MACRO)\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_FUNC_MACRO  __func__\n#elif defined(__FUNCTION__)\n#define DUK_FUNC_MACRO  __FUNCTION__\n#else\n#define DUK_FUNC_MACRO  \"unknown\"\n#endif\n#endif\n\n#if defined(DUK_F_HAVE_64BIT)\n#if !defined(DUK_BSWAP64)\n#define DUK_BSWAP64(x) \\\n\t((((duk_uint64_t) (x)) >> 56U) | \\\n\t ((((duk_uint64_t) (x)) >> 40U) & DUK_U64_CONSTANT(0xff00)) | \\\n\t ((((duk_uint64_t) (x)) >> 24U) & DUK_U64_CONSTANT(0xff0000)) | \\\n\t ((((duk_uint64_t) (x)) >> 8U) & DUK_U64_CONSTANT(0xff000000)) | \\\n\t ((((duk_uint64_t) (x)) << 8U) & DUK_U64_CONSTANT(0xff00000000)) | \\\n\t ((((duk_uint64_t) (x)) << 24U) & DUK_U64_CONSTANT(0xff0000000000)) | \\\n\t ((((duk_uint64_t) (x)) << 40U) & DUK_U64_CONSTANT(0xff000000000000)) | \\\n\t (((duk_uint64_t) (x)) << 56U))\n#endif\n#endif\n#if !defined(DUK_BSWAP32)\n#define DUK_BSWAP32(x) \\\n\t((((duk_uint32_t) (x)) >> 24U) | \\\n\t ((((duk_uint32_t) (x)) >> 8U) & 0xff00UL) | \\\n\t ((((duk_uint32_t) (x)) << 8U) & 0xff0000UL) | \\\n\t (((duk_uint32_t) (x)) << 24U))\n#endif\n#if !defined(DUK_BSWAP16)\n#define DUK_BSWAP16(x) \\\n\t((duk_uint16_t) (x) >> 8U) | \\\n\t((duk_uint16_t) (x) << 8U)\n#endif\n\n/* DUK_USE_VARIADIC_MACROS: required from compilers, so no fill-in. */\n/* DUK_USE_UNION_INITIALIZERS: required from compilers, so no fill-in. */\n\n#if !(defined(DUK_USE_FLEX_C99) || defined(DUK_USE_FLEX_ZEROSIZE) || defined(DUK_USE_FLEX_ONESIZE))\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE  /* Not standard but common enough */\n#endif\n#endif\n\n#if !(defined(DUK_USE_PACK_GCC_ATTR) || defined(DUK_USE_PACK_CLANG_ATTR) || \\\n      defined(DUK_USE_PACK_MSVC_PRAGMA) || defined(DUK_USE_PACK_DUMMY_MEMBER))\n#define DUK_USE_PACK_DUMMY_MEMBER\n#endif\n\n#if 0  /* not defined by default */\n#undef DUK_USE_GCC_PRAGMAS\n#endif\n\n/* Workaround for GH-323: avoid inlining control when compiling from\n * multiple sources, as it causes compiler portability trouble.\n */\n#if !defined(DUK_SINGLE_FILE)\n#undef DUK_NOINLINE\n#undef DUK_INLINE\n#undef DUK_ALWAYS_INLINE\n#define DUK_NOINLINE       /*nop*/\n#define DUK_INLINE         /*nop*/\n#define DUK_ALWAYS_INLINE  /*nop*/\n#endif\n\n/*\n *  Check whether or not a packed duk_tval representation is possible.\n *  What's basically required is that pointers are 32-bit values\n *  (sizeof(void *) == 4).  Best effort check, not always accurate.\n *  If guess goes wrong, crashes may result; self tests also verify\n *  the guess.\n */\n\n/* Explicit marker needed; may be 'defined', 'undefined, 'or 'not provided'. */\n#if !defined(DUK_F_PACKED_TVAL_PROVIDED)\n#undef DUK_F_PACKED_TVAL_POSSIBLE\n\n/* Strict C99 case: DUK_UINTPTR_MAX (= UINTPTR_MAX) should be very reliable */\n#if !defined(DUK_F_PACKED_TVAL_POSSIBLE) && defined(DUK_UINTPTR_MAX)\n#if (DUK_UINTPTR_MAX <= 0xffffffffUL)\n#define DUK_F_PACKED_TVAL_POSSIBLE\n#endif\n#endif\n\n/* Non-C99 case, still relying on DUK_UINTPTR_MAX, as long as it is not a computed value */\n#if !defined(DUK_F_PACKED_TVAL_POSSIBLE) && defined(DUK_UINTPTR_MAX) && !defined(DUK_UINTPTR_MAX_COMPUTED)\n#if (DUK_UINTPTR_MAX <= 0xffffffffUL)\n#define DUK_F_PACKED_TVAL_POSSIBLE\n#endif\n#endif\n\n/* DUK_SIZE_MAX (= SIZE_MAX) is often reliable */\n#if !defined(DUK_F_PACKED_TVAL_POSSIBLE) && defined(DUK_SIZE_MAX) && !defined(DUK_SIZE_MAX_COMPUTED)\n#if (DUK_SIZE_MAX <= 0xffffffffUL)\n#define DUK_F_PACKED_TVAL_POSSIBLE\n#endif\n#endif\n\n#undef DUK_USE_PACKED_TVAL\n#if defined(DUK_F_PACKED_TVAL_POSSIBLE)\n#define DUK_USE_PACKED_TVAL\n#endif\n#undef DUK_F_PACKED_TVAL_POSSIBLE\n\n#endif  /* DUK_F_PACKED_TVAL_PROVIDED */\n/* Object property allocation layout has implications for memory and code\n * footprint and generated code size/speed.  The best layout also depends\n * on whether the platform has alignment requirements or benefits from\n * having mostly aligned accesses.\n */\n#undef DUK_USE_HOBJECT_LAYOUT_1\n#undef DUK_USE_HOBJECT_LAYOUT_2\n#undef DUK_USE_HOBJECT_LAYOUT_3\n#if (DUK_USE_ALIGN_BY == 1)\n/* On platforms without any alignment issues, layout 1 is preferable\n * because it compiles to slightly less code and provides direct access\n * to property keys.\n */\n#define DUK_USE_HOBJECT_LAYOUT_1\n#else\n/* On other platforms use layout 2, which requires some padding but\n * is a bit more natural than layout 3 in ordering the entries.  Layout\n * 3 is currently not used.\n */\n#define DUK_USE_HOBJECT_LAYOUT_2\n#endif\n\n/* GCC/clang inaccurate math would break compliance and probably duk_tval,\n * so refuse to compile.  Relax this if -ffast-math is tested to work.\n */\n#if defined(__FAST_MATH__)\n#error __FAST_MATH__ defined, refusing to compile\n#endif\n\n/*\n *  Autogenerated defaults\n */\n\n#undef DUK_USE_ALLOW_UNDEFINED_BEHAVIOR\n#define DUK_USE_ARRAY_BUILTIN\n#define DUK_USE_ARRAY_FASTPATH\n#define DUK_USE_ARRAY_PROP_FASTPATH\n#undef DUK_USE_ASSERTIONS\n#define DUK_USE_AUGMENT_ERROR_CREATE\n#define DUK_USE_AUGMENT_ERROR_THROW\n#define DUK_USE_AVOID_PLATFORM_FUNCPTRS\n#define DUK_USE_BASE64_FASTPATH\n#define DUK_USE_BASE64_SUPPORT\n#define DUK_USE_BOOLEAN_BUILTIN\n#define DUK_USE_BUFFEROBJECT_SUPPORT\n#undef DUK_USE_BUFLEN16\n#define DUK_USE_BYTECODE_DUMP_SUPPORT\n#define DUK_USE_CACHE_ACTIVATION\n#define DUK_USE_CACHE_CATCHER\n#define DUK_USE_CALLSTACK_LIMIT 10000\n#define DUK_USE_COMPILER_RECLIMIT 2500\n#define DUK_USE_COROUTINE_SUPPORT\n#undef DUK_USE_CPP_EXCEPTIONS\n#undef DUK_USE_DATAPTR16\n#undef DUK_USE_DATAPTR_DEC16\n#undef DUK_USE_DATAPTR_ENC16\n#define DUK_USE_DATE_BUILTIN\n#undef DUK_USE_DATE_FORMAT_STRING\n#undef DUK_USE_DATE_GET_LOCAL_TZOFFSET\n#undef DUK_USE_DATE_GET_NOW\n#undef DUK_USE_DATE_PARSE_STRING\n#undef DUK_USE_DATE_PRS_GETDATE\n#undef DUK_USE_DEBUG\n#undef DUK_USE_DEBUGGER_DUMPHEAP\n#undef DUK_USE_DEBUGGER_INSPECT\n#undef DUK_USE_DEBUGGER_PAUSE_UNCAUGHT\n#undef DUK_USE_DEBUGGER_SUPPORT\n#define DUK_USE_DEBUGGER_THROW_NOTIFY\n#undef DUK_USE_DEBUGGER_TRANSPORT_TORTURE\n#define DUK_USE_DEBUG_BUFSIZE 65536L\n#define DUK_USE_DEBUG_LEVEL 0\n#undef DUK_USE_DEBUG_WRITE\n#define DUK_USE_DOUBLE_LINKED_HEAP\n#define DUK_USE_DUKTAPE_BUILTIN\n#define DUK_USE_ENCODING_BUILTINS\n#define DUK_USE_ERRCREATE\n#define DUK_USE_ERRTHROW\n#define DUK_USE_ES6\n#define DUK_USE_ES6_OBJECT_PROTO_PROPERTY\n#define DUK_USE_ES6_OBJECT_SETPROTOTYPEOF\n#define DUK_USE_ES6_PROXY\n#define DUK_USE_ES6_REGEXP_SYNTAX\n#define DUK_USE_ES6_UNICODE_ESCAPE\n#define DUK_USE_ES7\n#define DUK_USE_ES7_EXP_OPERATOR\n#define DUK_USE_ES8\n#define DUK_USE_ES9\n#define DUK_USE_ESBC_LIMITS\n#define DUK_USE_ESBC_MAX_BYTES 2147418112L\n#define DUK_USE_ESBC_MAX_LINENUMBER 2147418112L\n#undef DUK_USE_EXEC_FUN_LOCAL\n#undef DUK_USE_EXEC_INDIRECT_BOUND_CHECK\n#undef DUK_USE_EXEC_PREFER_SIZE\n#define DUK_USE_EXEC_REGCONST_OPTIMIZE\n#undef DUK_USE_EXEC_TIMEOUT_CHECK\n#undef DUK_USE_EXPLICIT_NULL_INIT\n#undef DUK_USE_EXTSTR_FREE\n#undef DUK_USE_EXTSTR_INTERN_CHECK\n#undef DUK_USE_FASTINT\n#define DUK_USE_FAST_REFCOUNT_DEFAULT\n#undef DUK_USE_FATAL_HANDLER\n#define DUK_USE_FATAL_MAXLEN 128\n#define DUK_USE_FINALIZER_SUPPORT\n#undef DUK_USE_FINALIZER_TORTURE\n#undef DUK_USE_FUNCPTR16\n#undef DUK_USE_FUNCPTR_DEC16\n#undef DUK_USE_FUNCPTR_ENC16\n#define DUK_USE_FUNCTION_BUILTIN\n#define DUK_USE_FUNC_FILENAME_PROPERTY\n#define DUK_USE_FUNC_NAME_PROPERTY\n#undef DUK_USE_GC_TORTURE\n#undef DUK_USE_GET_MONOTONIC_TIME\n#undef DUK_USE_GET_RANDOM_DOUBLE\n#undef DUK_USE_GLOBAL_BINDING\n#define DUK_USE_GLOBAL_BUILTIN\n#undef DUK_USE_HEAPPTR16\n#undef DUK_USE_HEAPPTR_DEC16\n#undef DUK_USE_HEAPPTR_ENC16\n#define DUK_USE_HEX_FASTPATH\n#define DUK_USE_HEX_SUPPORT\n#define DUK_USE_HOBJECT_ARRAY_ABANDON_LIMIT 2\n#define DUK_USE_HOBJECT_ARRAY_FAST_RESIZE_LIMIT 9\n#define DUK_USE_HOBJECT_ARRAY_MINGROW_ADD 16\n#define DUK_USE_HOBJECT_ARRAY_MINGROW_DIVISOR 8\n#define DUK_USE_HOBJECT_ENTRY_MINGROW_ADD 16\n#define DUK_USE_HOBJECT_ENTRY_MINGROW_DIVISOR 8\n#define DUK_USE_HOBJECT_HASH_PART\n#define DUK_USE_HOBJECT_HASH_PROP_LIMIT 8\n#define DUK_USE_HSTRING_ARRIDX\n#define DUK_USE_HSTRING_CLEN\n#undef DUK_USE_HSTRING_EXTDATA\n#define DUK_USE_HSTRING_LAZY_CLEN\n#define DUK_USE_HTML_COMMENTS\n#define DUK_USE_IDCHAR_FASTPATH\n#undef DUK_USE_INJECT_HEAP_ALLOC_ERROR\n#undef DUK_USE_INTERRUPT_COUNTER\n#undef DUK_USE_INTERRUPT_DEBUG_FIXUP\n#define DUK_USE_JC\n#define DUK_USE_JSON_BUILTIN\n#define DUK_USE_JSON_DECNUMBER_FASTPATH\n#define DUK_USE_JSON_DECSTRING_FASTPATH\n#define DUK_USE_JSON_DEC_RECLIMIT 1000\n#define DUK_USE_JSON_EATWHITE_FASTPATH\n#define DUK_USE_JSON_ENC_RECLIMIT 1000\n#define DUK_USE_JSON_QUOTESTRING_FASTPATH\n#undef DUK_USE_JSON_STRINGIFY_FASTPATH\n#define DUK_USE_JSON_SUPPORT\n#define DUK_USE_JX\n#define DUK_USE_LEXER_SLIDING_WINDOW\n#undef DUK_USE_LIGHTFUNC_BUILTINS\n#define DUK_USE_LITCACHE_SIZE 256\n#define DUK_USE_MARK_AND_SWEEP_RECLIMIT 256\n#define DUK_USE_MATH_BUILTIN\n#define DUK_USE_NATIVE_CALL_RECLIMIT 1000\n#undef DUK_USE_NATIVE_STACK_CHECK\n#define DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT\n#undef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY\n#undef DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY\n#define DUK_USE_NONSTD_FUNC_STMT\n#define DUK_USE_NONSTD_GETTER_KEY_ARGUMENT\n#define DUK_USE_NONSTD_JSON_ESC_U2028_U2029\n#define DUK_USE_NONSTD_SETTER_KEY_ARGUMENT\n#define DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT\n#define DUK_USE_NUMBER_BUILTIN\n#define DUK_USE_OBJECT_BUILTIN\n#undef DUK_USE_OBJSIZES16\n#undef DUK_USE_PARANOID_ERRORS\n#define DUK_USE_PC2LINE\n#define DUK_USE_PERFORMANCE_BUILTIN\n#undef DUK_USE_PREFER_SIZE\n#undef DUK_USE_PROMISE_BUILTIN\n#define DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS\n#undef DUK_USE_REFCOUNT16\n#define DUK_USE_REFCOUNT32\n#define DUK_USE_REFERENCE_COUNTING\n#define DUK_USE_REFLECT_BUILTIN\n#define DUK_USE_REGEXP_CANON_BITMAP\n#undef DUK_USE_REGEXP_CANON_WORKAROUND\n#define DUK_USE_REGEXP_COMPILER_RECLIMIT 10000\n#define DUK_USE_REGEXP_EXECUTOR_RECLIMIT 10000\n#define DUK_USE_REGEXP_SUPPORT\n#undef DUK_USE_ROM_GLOBAL_CLONE\n#undef DUK_USE_ROM_GLOBAL_INHERIT\n#undef DUK_USE_ROM_OBJECTS\n#define DUK_USE_ROM_PTRCOMP_FIRST 63488L\n#undef DUK_USE_ROM_STRINGS\n#define DUK_USE_SECTION_B\n#undef DUK_USE_SELF_TESTS\n#define DUK_USE_SHEBANG_COMMENTS\n#undef DUK_USE_SHUFFLE_TORTURE\n#define DUK_USE_SOURCE_NONBMP\n#undef DUK_USE_STRHASH16\n#undef DUK_USE_STRHASH_DENSE\n#define DUK_USE_STRHASH_SKIP_SHIFT 5\n#define DUK_USE_STRICT_DECL\n#undef DUK_USE_STRICT_UTF8_SOURCE\n#define DUK_USE_STRING_BUILTIN\n#undef DUK_USE_STRLEN16\n#define DUK_USE_STRTAB_GROW_LIMIT 17\n#define DUK_USE_STRTAB_MAXSIZE 268435456L\n#define DUK_USE_STRTAB_MINSIZE 1024\n#undef DUK_USE_STRTAB_PTRCOMP\n#define DUK_USE_STRTAB_RESIZE_CHECK_MASK 255\n#define DUK_USE_STRTAB_SHRINK_LIMIT 6\n#undef DUK_USE_STRTAB_TORTURE\n#define DUK_USE_SYMBOL_BUILTIN\n#define DUK_USE_TAILCALL\n#define DUK_USE_TARGET_INFO \"unknown\"\n#define DUK_USE_TRACEBACKS\n#define DUK_USE_TRACEBACK_DEPTH 10\n#define DUK_USE_VALSTACK_GROW_SHIFT 2\n#define DUK_USE_VALSTACK_LIMIT 1000000L\n#define DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT 2\n#define DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT 4\n#undef DUK_USE_VALSTACK_UNSAFE\n#define DUK_USE_VERBOSE_ERRORS\n#define DUK_USE_VERBOSE_EXECUTOR_ERRORS\n#define DUK_USE_VOLUNTARY_GC\n#define DUK_USE_ZERO_BUFFER_DATA\n\n/*\n *  You may add overriding #define/#undef directives below for\n *  customization.  You of course cannot un-#include or un-typedef\n *  anything; these require direct changes above.\n */\n\n/* __OVERRIDE_DEFINES__ */\n\n/*\n *  Conditional includes\n */\n\n#if defined(DUK_F_CPP) && defined(DUK_USE_CPP_EXCEPTIONS)\n#include <exception>  /* std::exception */\n#include <stdexcept>  /* std::runtime_error */\n#endif\n\n/*\n *  Date provider selection\n *\n *  User may define DUK_USE_DATE_GET_NOW() etc directly, in which case we'll\n *  rely on an external provider.  If this is not done, revert to previous\n *  behavior and use Unix/Windows built-in provider.\n */\n\n#if defined(DUK_COMPILING_DUKTAPE)\n\n#if defined(DUK_USE_DATE_GET_NOW)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_gettimeofday()\n#elif defined(DUK_USE_DATE_NOW_TIME)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_time()\n#elif defined(DUK_USE_DATE_NOW_WINDOWS)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_windows()\n#elif defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_windows_subms()\n#else\n#error no provider for DUK_USE_DATE_GET_NOW()\n#endif\n\n#if defined(DUK_USE_DATE_GET_LOCAL_TZOFFSET)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S) || defined(DUK_USE_DATE_TZO_GMTIME)\n#define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d)   duk_bi_date_get_local_tzoffset_gmtime((d))\n#elif defined(DUK_USE_DATE_TZO_WINDOWS)\n#define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d)   duk_bi_date_get_local_tzoffset_windows((d))\n#elif defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST)\n#define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d)   duk_bi_date_get_local_tzoffset_windows_no_dst((d))\n#else\n#error no provider for DUK_USE_DATE_GET_LOCAL_TZOFFSET()\n#endif\n\n#if defined(DUK_USE_DATE_PARSE_STRING)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_PRS_STRPTIME)\n#define DUK_USE_DATE_PARSE_STRING(ctx,str)   duk_bi_date_parse_string_strptime((ctx), (str))\n#elif defined(DUK_USE_DATE_PRS_GETDATE)\n#define DUK_USE_DATE_PARSE_STRING(ctx,str)   duk_bi_date_parse_string_getdate((ctx), (str))\n#else\n/* No provider for DUK_USE_DATE_PARSE_STRING(), fall back to ISO 8601 only. */\n#endif\n\n#if defined(DUK_USE_DATE_FORMAT_STRING)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_FMT_STRFTIME)\n#define DUK_USE_DATE_FORMAT_STRING(ctx,parts,tzoffset,flags) \\\n\tduk_bi_date_format_parts_strftime((ctx), (parts), (tzoffset), (flags))\n#else\n/* No provider for DUK_USE_DATE_FORMAT_STRING(), fall back to ISO 8601 only. */\n#endif\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME)\n/* External provider already defined. */\n#elif defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)\n#define DUK_USE_GET_MONOTONIC_TIME(ctx)  duk_bi_date_get_monotonic_time_clock_gettime()\n#elif defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC)\n#define DUK_USE_GET_MONOTONIC_TIME(ctx)  duk_bi_date_get_monotonic_time_windows_qpc()\n#else\n/* No provider for DUK_USE_GET_MONOTONIC_TIME(), fall back to DUK_USE_DATE_GET_NOW(). */\n#endif\n\n#endif  /* DUK_COMPILING_DUKTAPE */\n\n/*\n *  Checks for legacy feature options (DUK_OPT_xxx)\n */\n\n#if defined(DUK_OPT_ASSERTIONS)\n#error unsupported legacy feature option DUK_OPT_ASSERTIONS used\n#endif\n#if defined(DUK_OPT_BUFFEROBJECT_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_BUFFEROBJECT_SUPPORT used\n#endif\n#if defined(DUK_OPT_BUFLEN16)\n#error unsupported legacy feature option DUK_OPT_BUFLEN16 used\n#endif\n#if defined(DUK_OPT_DATAPTR16)\n#error unsupported legacy feature option DUK_OPT_DATAPTR16 used\n#endif\n#if defined(DUK_OPT_DATAPTR_DEC16)\n#error unsupported legacy feature option DUK_OPT_DATAPTR_DEC16 used\n#endif\n#if defined(DUK_OPT_DATAPTR_ENC16)\n#error unsupported legacy feature option DUK_OPT_DATAPTR_ENC16 used\n#endif\n#if defined(DUK_OPT_DDDPRINT)\n#error unsupported legacy feature option DUK_OPT_DDDPRINT used\n#endif\n#if defined(DUK_OPT_DDPRINT)\n#error unsupported legacy feature option DUK_OPT_DDPRINT used\n#endif\n#if defined(DUK_OPT_DEBUG)\n#error unsupported legacy feature option DUK_OPT_DEBUG used\n#endif\n#if defined(DUK_OPT_DEBUGGER_DUMPHEAP)\n#error unsupported legacy feature option DUK_OPT_DEBUGGER_DUMPHEAP used\n#endif\n#if defined(DUK_OPT_DEBUGGER_FWD_LOGGING)\n#error unsupported legacy feature option DUK_OPT_DEBUGGER_FWD_LOGGING used\n#endif\n#if defined(DUK_OPT_DEBUGGER_FWD_PRINTALERT)\n#error unsupported legacy feature option DUK_OPT_DEBUGGER_FWD_PRINTALERT used\n#endif\n#if defined(DUK_OPT_DEBUGGER_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_DEBUGGER_SUPPORT used\n#endif\n#if defined(DUK_OPT_DEBUGGER_TRANSPORT_TORTURE)\n#error unsupported legacy feature option DUK_OPT_DEBUGGER_TRANSPORT_TORTURE used\n#endif\n#if defined(DUK_OPT_DEBUG_BUFSIZE)\n#error unsupported legacy feature option DUK_OPT_DEBUG_BUFSIZE used\n#endif\n#if defined(DUK_OPT_DECLARE)\n#error unsupported legacy feature option DUK_OPT_DECLARE used\n#endif\n#if defined(DUK_OPT_DEEP_C_STACK)\n#error unsupported legacy feature option DUK_OPT_DEEP_C_STACK used\n#endif\n#if defined(DUK_OPT_DLL_BUILD)\n#error unsupported legacy feature option DUK_OPT_DLL_BUILD used\n#endif\n#if defined(DUK_OPT_DPRINT)\n#error unsupported legacy feature option DUK_OPT_DPRINT used\n#endif\n#if defined(DUK_OPT_DPRINT_COLORS)\n#error unsupported legacy feature option DUK_OPT_DPRINT_COLORS used\n#endif\n#if defined(DUK_OPT_DPRINT_RDTSC)\n#error unsupported legacy feature option DUK_OPT_DPRINT_RDTSC used\n#endif\n#if defined(DUK_OPT_EXEC_TIMEOUT_CHECK)\n#error unsupported legacy feature option DUK_OPT_EXEC_TIMEOUT_CHECK used\n#endif\n#if defined(DUK_OPT_EXTERNAL_STRINGS)\n#error unsupported legacy feature option DUK_OPT_EXTERNAL_STRINGS used\n#endif\n#if defined(DUK_OPT_EXTSTR_FREE)\n#error unsupported legacy feature option DUK_OPT_EXTSTR_FREE used\n#endif\n#if defined(DUK_OPT_EXTSTR_INTERN_CHECK)\n#error unsupported legacy feature option DUK_OPT_EXTSTR_INTERN_CHECK used\n#endif\n#if defined(DUK_OPT_FASTINT)\n#error unsupported legacy feature option DUK_OPT_FASTINT used\n#endif\n#if defined(DUK_OPT_FORCE_ALIGN)\n#error unsupported legacy feature option DUK_OPT_FORCE_ALIGN used\n#endif\n#if defined(DUK_OPT_FORCE_BYTEORDER)\n#error unsupported legacy feature option DUK_OPT_FORCE_BYTEORDER used\n#endif\n#if defined(DUK_OPT_FUNCPTR16)\n#error unsupported legacy feature option DUK_OPT_FUNCPTR16 used\n#endif\n#if defined(DUK_OPT_FUNCPTR_DEC16)\n#error unsupported legacy feature option DUK_OPT_FUNCPTR_DEC16 used\n#endif\n#if defined(DUK_OPT_FUNCPTR_ENC16)\n#error unsupported legacy feature option DUK_OPT_FUNCPTR_ENC16 used\n#endif\n#if defined(DUK_OPT_FUNC_NONSTD_CALLER_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_FUNC_NONSTD_CALLER_PROPERTY used\n#endif\n#if defined(DUK_OPT_FUNC_NONSTD_SOURCE_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_FUNC_NONSTD_SOURCE_PROPERTY used\n#endif\n#if defined(DUK_OPT_GC_TORTURE)\n#error unsupported legacy feature option DUK_OPT_GC_TORTURE used\n#endif\n#if defined(DUK_OPT_HAVE_CUSTOM_H)\n#error unsupported legacy feature option DUK_OPT_HAVE_CUSTOM_H used\n#endif\n#if defined(DUK_OPT_HEAPPTR16)\n#error unsupported legacy feature option DUK_OPT_HEAPPTR16 used\n#endif\n#if defined(DUK_OPT_HEAPPTR_DEC16)\n#error unsupported legacy feature option DUK_OPT_HEAPPTR_DEC16 used\n#endif\n#if defined(DUK_OPT_HEAPPTR_ENC16)\n#error unsupported legacy feature option DUK_OPT_HEAPPTR_ENC16 used\n#endif\n#if defined(DUK_OPT_INTERRUPT_COUNTER)\n#error unsupported legacy feature option DUK_OPT_INTERRUPT_COUNTER used\n#endif\n#if defined(DUK_OPT_JSON_STRINGIFY_FASTPATH)\n#error unsupported legacy feature option DUK_OPT_JSON_STRINGIFY_FASTPATH used\n#endif\n#if defined(DUK_OPT_LIGHTFUNC_BUILTINS)\n#error unsupported legacy feature option DUK_OPT_LIGHTFUNC_BUILTINS used\n#endif\n#if defined(DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY used\n#endif\n#if defined(DUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY used\n#endif\n#if defined(DUK_OPT_NO_ARRAY_SPLICE_NONSTD_DELCOUNT)\n#error unsupported legacy feature option DUK_OPT_NO_ARRAY_SPLICE_NONSTD_DELCOUNT used\n#endif\n#if defined(DUK_OPT_NO_AUGMENT_ERRORS)\n#error unsupported legacy feature option DUK_OPT_NO_AUGMENT_ERRORS used\n#endif\n#if defined(DUK_OPT_NO_BROWSER_LIKE)\n#error unsupported legacy feature option DUK_OPT_NO_BROWSER_LIKE used\n#endif\n#if defined(DUK_OPT_NO_BUFFEROBJECT_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_NO_BUFFEROBJECT_SUPPORT used\n#endif\n#if defined(DUK_OPT_NO_BYTECODE_DUMP_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_NO_BYTECODE_DUMP_SUPPORT used\n#endif\n#if defined(DUK_OPT_NO_COMMONJS_MODULES)\n#error unsupported legacy feature option DUK_OPT_NO_COMMONJS_MODULES used\n#endif\n#if defined(DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY used\n#endif\n#if defined(DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF)\n#error unsupported legacy feature option DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF used\n#endif\n#if defined(DUK_OPT_NO_ES6_PROXY)\n#error unsupported legacy feature option DUK_OPT_NO_ES6_PROXY used\n#endif\n#if defined(DUK_OPT_NO_FILE_IO)\n#error unsupported legacy feature option DUK_OPT_NO_FILE_IO used\n#endif\n#if defined(DUK_OPT_NO_FUNC_STMT)\n#error unsupported legacy feature option DUK_OPT_NO_FUNC_STMT used\n#endif\n#if defined(DUK_OPT_NO_JC)\n#error unsupported legacy feature option DUK_OPT_NO_JC used\n#endif\n#if defined(DUK_OPT_NO_JSONC)\n#error unsupported legacy feature option DUK_OPT_NO_JSONC used\n#endif\n#if defined(DUK_OPT_NO_JSONX)\n#error unsupported legacy feature option DUK_OPT_NO_JSONX used\n#endif\n#if defined(DUK_OPT_NO_JX)\n#error unsupported legacy feature option DUK_OPT_NO_JX used\n#endif\n#if defined(DUK_OPT_NO_MARK_AND_SWEEP)\n#error unsupported legacy feature option DUK_OPT_NO_MARK_AND_SWEEP used\n#endif\n#if defined(DUK_OPT_NO_MS_STRINGTABLE_RESIZE)\n#error unsupported legacy feature option DUK_OPT_NO_MS_STRINGTABLE_RESIZE used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_ACCESSOR_KEY_ARGUMENT)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_ACCESSOR_KEY_ARGUMENT used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_ARRAY_CONCAT_TRAILER)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_ARRAY_CONCAT_TRAILER used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_ARRAY_MAP_TRAILER)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_ARRAY_MAP_TRAILER used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_FUNC_STMT)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_FUNC_STMT used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_JSON_ESC_U2028_U2029)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_JSON_ESC_U2028_U2029 used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_STRING_FROMCHARCODE_32BIT)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_STRING_FROMCHARCODE_32BIT used\n#endif\n#if defined(DUK_OPT_NO_OBJECT_ES6_PROTO_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_NO_OBJECT_ES6_PROTO_PROPERTY used\n#endif\n#if defined(DUK_OPT_NO_OBJECT_ES6_SETPROTOTYPEOF)\n#error unsupported legacy feature option DUK_OPT_NO_OBJECT_ES6_SETPROTOTYPEOF used\n#endif\n#if defined(DUK_OPT_NO_OCTAL_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_NO_OCTAL_SUPPORT used\n#endif\n#if defined(DUK_OPT_NO_PACKED_TVAL)\n#error unsupported legacy feature option DUK_OPT_NO_PACKED_TVAL used\n#endif\n#if defined(DUK_OPT_NO_PC2LINE)\n#error unsupported legacy feature option DUK_OPT_NO_PC2LINE used\n#endif\n#if defined(DUK_OPT_NO_REFERENCE_COUNTING)\n#error unsupported legacy feature option DUK_OPT_NO_REFERENCE_COUNTING used\n#endif\n#if defined(DUK_OPT_NO_REGEXP_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_NO_REGEXP_SUPPORT used\n#endif\n#if defined(DUK_OPT_NO_SECTION_B)\n#error unsupported legacy feature option DUK_OPT_NO_SECTION_B used\n#endif\n#if defined(DUK_OPT_NO_SOURCE_NONBMP)\n#error unsupported legacy feature option DUK_OPT_NO_SOURCE_NONBMP used\n#endif\n#if defined(DUK_OPT_NO_STRICT_DECL)\n#error unsupported legacy feature option DUK_OPT_NO_STRICT_DECL used\n#endif\n#if defined(DUK_OPT_NO_TRACEBACKS)\n#error unsupported legacy feature option DUK_OPT_NO_TRACEBACKS used\n#endif\n#if defined(DUK_OPT_NO_VERBOSE_ERRORS)\n#error unsupported legacy feature option DUK_OPT_NO_VERBOSE_ERRORS used\n#endif\n#if defined(DUK_OPT_NO_VOLUNTARY_GC)\n#error unsupported legacy feature option DUK_OPT_NO_VOLUNTARY_GC used\n#endif\n#if defined(DUK_OPT_NO_ZERO_BUFFER_DATA)\n#error unsupported legacy feature option DUK_OPT_NO_ZERO_BUFFER_DATA used\n#endif\n#if defined(DUK_OPT_OBJSIZES16)\n#error unsupported legacy feature option DUK_OPT_OBJSIZES16 used\n#endif\n#if defined(DUK_OPT_PANIC_HANDLER)\n#error unsupported legacy feature option DUK_OPT_PANIC_HANDLER used\n#endif\n#if defined(DUK_OPT_REFCOUNT16)\n#error unsupported legacy feature option DUK_OPT_REFCOUNT16 used\n#endif\n#if defined(DUK_OPT_SEGFAULT_ON_PANIC)\n#error unsupported legacy feature option DUK_OPT_SEGFAULT_ON_PANIC used\n#endif\n#if defined(DUK_OPT_SELF_TESTS)\n#error unsupported legacy feature option DUK_OPT_SELF_TESTS used\n#endif\n#if defined(DUK_OPT_SETJMP)\n#error unsupported legacy feature option DUK_OPT_SETJMP used\n#endif\n#if defined(DUK_OPT_SHUFFLE_TORTURE)\n#error unsupported legacy feature option DUK_OPT_SHUFFLE_TORTURE used\n#endif\n#if defined(DUK_OPT_SIGSETJMP)\n#error unsupported legacy feature option DUK_OPT_SIGSETJMP used\n#endif\n#if defined(DUK_OPT_STRHASH16)\n#error unsupported legacy feature option DUK_OPT_STRHASH16 used\n#endif\n#if defined(DUK_OPT_STRICT_UTF8_SOURCE)\n#error unsupported legacy feature option DUK_OPT_STRICT_UTF8_SOURCE used\n#endif\n#if defined(DUK_OPT_STRLEN16)\n#error unsupported legacy feature option DUK_OPT_STRLEN16 used\n#endif\n#if defined(DUK_OPT_STRTAB_CHAIN)\n#error unsupported legacy feature option DUK_OPT_STRTAB_CHAIN used\n#endif\n#if defined(DUK_OPT_STRTAB_CHAIN_SIZE)\n#error unsupported legacy feature option DUK_OPT_STRTAB_CHAIN_SIZE used\n#endif\n#if defined(DUK_OPT_TARGET_INFO)\n#error unsupported legacy feature option DUK_OPT_TARGET_INFO used\n#endif\n#if defined(DUK_OPT_TRACEBACK_DEPTH)\n#error unsupported legacy feature option DUK_OPT_TRACEBACK_DEPTH used\n#endif\n#if defined(DUK_OPT_UNDERSCORE_SETJMP)\n#error unsupported legacy feature option DUK_OPT_UNDERSCORE_SETJMP used\n#endif\n#if defined(DUK_OPT_USER_INITJS)\n#error unsupported legacy feature option DUK_OPT_USER_INITJS used\n#endif\n\n/*\n *  Checks for config option consistency (DUK_USE_xxx)\n */\n\n#if defined(DUK_USE_32BIT_PTRS)\n#error unsupported config option used (option has been removed): DUK_USE_32BIT_PTRS\n#endif\n#if defined(DUK_USE_ALIGN_4)\n#error unsupported config option used (option has been removed): DUK_USE_ALIGN_4\n#endif\n#if defined(DUK_USE_ALIGN_8)\n#error unsupported config option used (option has been removed): DUK_USE_ALIGN_8\n#endif\n#if defined(DUK_USE_BROWSER_LIKE)\n#error unsupported config option used (option has been removed): DUK_USE_BROWSER_LIKE\n#endif\n#if defined(DUK_USE_BUILTIN_INITJS)\n#error unsupported config option used (option has been removed): DUK_USE_BUILTIN_INITJS\n#endif\n#if defined(DUK_USE_BYTEORDER_FORCED)\n#error unsupported config option used (option has been removed): DUK_USE_BYTEORDER_FORCED\n#endif\n#if defined(DUK_USE_COMMONJS_MODULES)\n#error unsupported config option used (option has been removed): DUK_USE_COMMONJS_MODULES\n#endif\n#if defined(DUK_USE_DATAPTR_DEC16) && !defined(DUK_USE_DATAPTR16)\n#error config option DUK_USE_DATAPTR_DEC16 requires option DUK_USE_DATAPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_DATAPTR_ENC16) && !defined(DUK_USE_DATAPTR16)\n#error config option DUK_USE_DATAPTR_ENC16 requires option DUK_USE_DATAPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_DDDPRINT)\n#error unsupported config option used (option has been removed): DUK_USE_DDDPRINT\n#endif\n#if defined(DUK_USE_DDPRINT)\n#error unsupported config option used (option has been removed): DUK_USE_DDPRINT\n#endif\n#if defined(DUK_USE_DEBUGGER_FWD_LOGGING)\n#error unsupported config option used (option has been removed): DUK_USE_DEBUGGER_FWD_LOGGING\n#endif\n#if defined(DUK_USE_DEBUGGER_FWD_PRINTALERT)\n#error unsupported config option used (option has been removed): DUK_USE_DEBUGGER_FWD_PRINTALERT\n#endif\n#if defined(DUK_USE_DEBUGGER_SUPPORT) && !defined(DUK_USE_INTERRUPT_COUNTER)\n#error config option DUK_USE_DEBUGGER_SUPPORT requires option DUK_USE_INTERRUPT_COUNTER (which is missing)\n#endif\n#if defined(DUK_USE_DEEP_C_STACK)\n#error unsupported config option used (option has been removed): DUK_USE_DEEP_C_STACK\n#endif\n#if defined(DUK_USE_DOUBLE_BE)\n#error unsupported config option used (option has been removed): DUK_USE_DOUBLE_BE\n#endif\n#if defined(DUK_USE_DOUBLE_BE) && defined(DUK_USE_DOUBLE_LE)\n#error config option DUK_USE_DOUBLE_BE conflicts with option DUK_USE_DOUBLE_LE (which is also defined)\n#endif\n#if defined(DUK_USE_DOUBLE_BE) && defined(DUK_USE_DOUBLE_ME)\n#error config option DUK_USE_DOUBLE_BE conflicts with option DUK_USE_DOUBLE_ME (which is also defined)\n#endif\n#if defined(DUK_USE_DOUBLE_LE)\n#error unsupported config option used (option has been removed): DUK_USE_DOUBLE_LE\n#endif\n#if defined(DUK_USE_DOUBLE_LE) && defined(DUK_USE_DOUBLE_BE)\n#error config option DUK_USE_DOUBLE_LE conflicts with option DUK_USE_DOUBLE_BE (which is also defined)\n#endif\n#if defined(DUK_USE_DOUBLE_LE) && defined(DUK_USE_DOUBLE_ME)\n#error config option DUK_USE_DOUBLE_LE conflicts with option DUK_USE_DOUBLE_ME (which is also defined)\n#endif\n#if defined(DUK_USE_DOUBLE_ME)\n#error unsupported config option used (option has been removed): DUK_USE_DOUBLE_ME\n#endif\n#if defined(DUK_USE_DOUBLE_ME) && defined(DUK_USE_DOUBLE_LE)\n#error config option DUK_USE_DOUBLE_ME conflicts with option DUK_USE_DOUBLE_LE (which is also defined)\n#endif\n#if defined(DUK_USE_DOUBLE_ME) && defined(DUK_USE_DOUBLE_BE)\n#error config option DUK_USE_DOUBLE_ME conflicts with option DUK_USE_DOUBLE_BE (which is also defined)\n#endif\n#if defined(DUK_USE_DPRINT)\n#error unsupported config option used (option has been removed): DUK_USE_DPRINT\n#endif\n#if defined(DUK_USE_DPRINT) && !defined(DUK_USE_DEBUG)\n#error config option DUK_USE_DPRINT requires option DUK_USE_DEBUG (which is missing)\n#endif\n#if defined(DUK_USE_DPRINT_COLORS)\n#error unsupported config option used (option has been removed): DUK_USE_DPRINT_COLORS\n#endif\n#if defined(DUK_USE_DPRINT_RDTSC)\n#error unsupported config option used (option has been removed): DUK_USE_DPRINT_RDTSC\n#endif\n#if defined(DUK_USE_ES6_REGEXP_BRACES)\n#error unsupported config option used (option has been removed): DUK_USE_ES6_REGEXP_BRACES\n#endif\n#if defined(DUK_USE_ESBC_MAX_BYTES) && !defined(DUK_USE_ESBC_LIMITS)\n#error config option DUK_USE_ESBC_MAX_BYTES requires option DUK_USE_ESBC_LIMITS (which is missing)\n#endif\n#if defined(DUK_USE_ESBC_MAX_LINENUMBER) && !defined(DUK_USE_ESBC_LIMITS)\n#error config option DUK_USE_ESBC_MAX_LINENUMBER requires option DUK_USE_ESBC_LIMITS (which is missing)\n#endif\n#if defined(DUK_USE_EXEC_TIMEOUT_CHECK) && !defined(DUK_USE_INTERRUPT_COUNTER)\n#error config option DUK_USE_EXEC_TIMEOUT_CHECK requires option DUK_USE_INTERRUPT_COUNTER (which is missing)\n#endif\n#if defined(DUK_USE_EXTSTR_FREE) && !defined(DUK_USE_HSTRING_EXTDATA)\n#error config option DUK_USE_EXTSTR_FREE requires option DUK_USE_HSTRING_EXTDATA (which is missing)\n#endif\n#if defined(DUK_USE_EXTSTR_INTERN_CHECK) && !defined(DUK_USE_HSTRING_EXTDATA)\n#error config option DUK_USE_EXTSTR_INTERN_CHECK requires option DUK_USE_HSTRING_EXTDATA (which is missing)\n#endif\n#if defined(DUK_USE_FASTINT) && !defined(DUK_USE_64BIT_OPS)\n#error config option DUK_USE_FASTINT requires option DUK_USE_64BIT_OPS (which is missing)\n#endif\n#if defined(DUK_USE_FILE_IO)\n#error unsupported config option used (option has been removed): DUK_USE_FILE_IO\n#endif\n#if defined(DUK_USE_FULL_TVAL)\n#error unsupported config option used (option has been removed): DUK_USE_FULL_TVAL\n#endif\n#if defined(DUK_USE_FUNCPTR_DEC16) && !defined(DUK_USE_FUNCPTR16)\n#error config option DUK_USE_FUNCPTR_DEC16 requires option DUK_USE_FUNCPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_FUNCPTR_ENC16) && !defined(DUK_USE_FUNCPTR16)\n#error config option DUK_USE_FUNCPTR_ENC16 requires option DUK_USE_FUNCPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS)\n#error unsupported config option used (option has been removed): DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS\n#endif\n#if defined(DUK_USE_HEAPPTR16) && defined(DUK_USE_DEBUG)\n#error config option DUK_USE_HEAPPTR16 conflicts with option DUK_USE_DEBUG (which is also defined)\n#endif\n#if defined(DUK_USE_HEAPPTR_DEC16) && !defined(DUK_USE_HEAPPTR16)\n#error config option DUK_USE_HEAPPTR_DEC16 requires option DUK_USE_HEAPPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_HEAPPTR_ENC16) && !defined(DUK_USE_HEAPPTR16)\n#error config option DUK_USE_HEAPPTR_ENC16 requires option DUK_USE_HEAPPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_INTEGER_BE)\n#error unsupported config option used (option has been removed): DUK_USE_INTEGER_BE\n#endif\n#if defined(DUK_USE_INTEGER_BE) && defined(DUK_USE_INTEGER_LE)\n#error config option DUK_USE_INTEGER_BE conflicts with option DUK_USE_INTEGER_LE (which is also defined)\n#endif\n#if defined(DUK_USE_INTEGER_BE) && defined(DUK_USE_INTEGER_ME)\n#error config option DUK_USE_INTEGER_BE conflicts with option DUK_USE_INTEGER_ME (which is also defined)\n#endif\n#if defined(DUK_USE_INTEGER_LE)\n#error unsupported config option used (option has been removed): DUK_USE_INTEGER_LE\n#endif\n#if defined(DUK_USE_INTEGER_LE) && defined(DUK_USE_INTEGER_BE)\n#error config option DUK_USE_INTEGER_LE conflicts with option DUK_USE_INTEGER_BE (which is also defined)\n#endif\n#if defined(DUK_USE_INTEGER_LE) && defined(DUK_USE_INTEGER_ME)\n#error config option DUK_USE_INTEGER_LE conflicts with option DUK_USE_INTEGER_ME (which is also defined)\n#endif\n#if defined(DUK_USE_INTEGER_ME)\n#error unsupported config option used (option has been removed): DUK_USE_INTEGER_ME\n#endif\n#if defined(DUK_USE_INTEGER_ME) && defined(DUK_USE_INTEGER_LE)\n#error config option DUK_USE_INTEGER_ME conflicts with option DUK_USE_INTEGER_LE (which is also defined)\n#endif\n#if defined(DUK_USE_INTEGER_ME) && defined(DUK_USE_INTEGER_BE)\n#error config option DUK_USE_INTEGER_ME conflicts with option DUK_USE_INTEGER_BE (which is also defined)\n#endif\n#if defined(DUK_USE_MARKANDSWEEP_FINALIZER_TORTURE)\n#error unsupported config option used (option has been removed): DUK_USE_MARKANDSWEEP_FINALIZER_TORTURE\n#endif\n#if defined(DUK_USE_MARK_AND_SWEEP)\n#error unsupported config option used (option has been removed): DUK_USE_MARK_AND_SWEEP\n#endif\n#if defined(DUK_USE_MATH_FMAX)\n#error unsupported config option used (option has been removed): DUK_USE_MATH_FMAX\n#endif\n#if defined(DUK_USE_MATH_FMIN)\n#error unsupported config option used (option has been removed): DUK_USE_MATH_FMIN\n#endif\n#if defined(DUK_USE_MATH_ROUND)\n#error unsupported config option used (option has been removed): DUK_USE_MATH_ROUND\n#endif\n#if defined(DUK_USE_MS_STRINGTABLE_RESIZE)\n#error unsupported config option used (option has been removed): DUK_USE_MS_STRINGTABLE_RESIZE\n#endif\n#if defined(DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER)\n#error unsupported config option used (option has been removed): DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER\n#endif\n#if defined(DUK_USE_NONSTD_ARRAY_MAP_TRAILER)\n#error unsupported config option used (option has been removed): DUK_USE_NONSTD_ARRAY_MAP_TRAILER\n#endif\n#if defined(DUK_USE_NONSTD_REGEXP_DOLLAR_ESCAPE)\n#error unsupported config option used (option has been removed): DUK_USE_NONSTD_REGEXP_DOLLAR_ESCAPE\n#endif\n#if defined(DUK_USE_NO_DOUBLE_ALIASING_SELFTEST)\n#error unsupported config option used (option has been removed): DUK_USE_NO_DOUBLE_ALIASING_SELFTEST\n#endif\n#if defined(DUK_USE_OCTAL_SUPPORT)\n#error unsupported config option used (option has been removed): DUK_USE_OCTAL_SUPPORT\n#endif\n#if defined(DUK_USE_PACKED_TVAL_POSSIBLE)\n#error unsupported config option used (option has been removed): DUK_USE_PACKED_TVAL_POSSIBLE\n#endif\n#if defined(DUK_USE_PANIC_ABORT)\n#error unsupported config option used (option has been removed): DUK_USE_PANIC_ABORT\n#endif\n#if defined(DUK_USE_PANIC_EXIT)\n#error unsupported config option used (option has been removed): DUK_USE_PANIC_EXIT\n#endif\n#if defined(DUK_USE_PANIC_HANDLER)\n#error unsupported config option used (option has been removed): DUK_USE_PANIC_HANDLER\n#endif\n#if defined(DUK_USE_PANIC_SEGFAULT)\n#error unsupported config option used (option has been removed): DUK_USE_PANIC_SEGFAULT\n#endif\n#if defined(DUK_USE_POW_NETBSD_WORKAROUND)\n#error unsupported config option used (option has been removed): DUK_USE_POW_NETBSD_WORKAROUND\n#endif\n#if defined(DUK_USE_RDTSC)\n#error unsupported config option used (option has been removed): DUK_USE_RDTSC\n#endif\n#if defined(DUK_USE_REFZERO_FINALIZER_TORTURE)\n#error unsupported config option used (option has been removed): DUK_USE_REFZERO_FINALIZER_TORTURE\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) && !defined(DUK_USE_ROM_STRINGS)\n#error config option DUK_USE_ROM_GLOBAL_CLONE requires option DUK_USE_ROM_STRINGS (which is missing)\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) && !defined(DUK_USE_ROM_OBJECTS)\n#error config option DUK_USE_ROM_GLOBAL_CLONE requires option DUK_USE_ROM_OBJECTS (which is missing)\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) && defined(DUK_USE_ROM_GLOBAL_INHERIT)\n#error config option DUK_USE_ROM_GLOBAL_CLONE conflicts with option DUK_USE_ROM_GLOBAL_INHERIT (which is also defined)\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_INHERIT) && !defined(DUK_USE_ROM_STRINGS)\n#error config option DUK_USE_ROM_GLOBAL_INHERIT requires option DUK_USE_ROM_STRINGS (which is missing)\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_INHERIT) && !defined(DUK_USE_ROM_OBJECTS)\n#error config option DUK_USE_ROM_GLOBAL_INHERIT requires option DUK_USE_ROM_OBJECTS (which is missing)\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_INHERIT) && defined(DUK_USE_ROM_GLOBAL_CLONE)\n#error config option DUK_USE_ROM_GLOBAL_INHERIT conflicts with option DUK_USE_ROM_GLOBAL_CLONE (which is also defined)\n#endif\n#if defined(DUK_USE_ROM_OBJECTS) && !defined(DUK_USE_ROM_STRINGS)\n#error config option DUK_USE_ROM_OBJECTS requires option DUK_USE_ROM_STRINGS (which is missing)\n#endif\n#if defined(DUK_USE_ROM_STRINGS) && !defined(DUK_USE_ROM_OBJECTS)\n#error config option DUK_USE_ROM_STRINGS requires option DUK_USE_ROM_OBJECTS (which is missing)\n#endif\n#if defined(DUK_USE_SETJMP)\n#error unsupported config option used (option has been removed): DUK_USE_SETJMP\n#endif\n#if defined(DUK_USE_SIGSETJMP)\n#error unsupported config option used (option has been removed): DUK_USE_SIGSETJMP\n#endif\n#if defined(DUK_USE_STRTAB_CHAIN)\n#error unsupported config option used (option has been removed): DUK_USE_STRTAB_CHAIN\n#endif\n#if defined(DUK_USE_STRTAB_CHAIN_SIZE)\n#error unsupported config option used (option has been removed): DUK_USE_STRTAB_CHAIN_SIZE\n#endif\n#if defined(DUK_USE_STRTAB_CHAIN_SIZE) && !defined(DUK_USE_STRTAB_CHAIN)\n#error config option DUK_USE_STRTAB_CHAIN_SIZE requires option DUK_USE_STRTAB_CHAIN (which is missing)\n#endif\n#if defined(DUK_USE_STRTAB_PROBE)\n#error unsupported config option used (option has been removed): DUK_USE_STRTAB_PROBE\n#endif\n#if defined(DUK_USE_STRTAB_PTRCOMP) && !defined(DUK_USE_HEAPPTR16)\n#error config option DUK_USE_STRTAB_PTRCOMP requires option DUK_USE_HEAPPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_TAILCALL) && defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n#error config option DUK_USE_TAILCALL conflicts with option DUK_USE_NONSTD_FUNC_CALLER_PROPERTY (which is also defined)\n#endif\n#if defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)\n#error unsupported config option used (option has been removed): DUK_USE_UNALIGNED_ACCESSES_POSSIBLE\n#endif\n#if defined(DUK_USE_UNDERSCORE_SETJMP)\n#error unsupported config option used (option has been removed): DUK_USE_UNDERSCORE_SETJMP\n#endif\n#if defined(DUK_USE_USER_DECLARE)\n#error unsupported config option used (option has been removed): DUK_USE_USER_DECLARE\n#endif\n#if defined(DUK_USE_USER_INITJS)\n#error unsupported config option used (option has been removed): DUK_USE_USER_INITJS\n#endif\n\n#if defined(DUK_USE_CPP_EXCEPTIONS) && !defined(__cplusplus)\n#error DUK_USE_CPP_EXCEPTIONS enabled but not compiling with a C++ compiler\n#endif\n\n/*\n *  Convert DUK_USE_BYTEORDER, from whatever source, into currently used\n *  internal defines.  If detection failed, #error out.\n */\n\n#if defined(DUK_USE_BYTEORDER)\n#if (DUK_USE_BYTEORDER == 1)\n#define DUK_USE_INTEGER_LE\n#define DUK_USE_DOUBLE_LE\n#elif (DUK_USE_BYTEORDER == 2)\n#define DUK_USE_INTEGER_LE  /* integer endianness is little on purpose */\n#define DUK_USE_DOUBLE_ME\n#elif (DUK_USE_BYTEORDER == 3)\n#define DUK_USE_INTEGER_BE\n#define DUK_USE_DOUBLE_BE\n#else\n#error unsupported: byte order invalid\n#endif  /* byte order */\n#else\n#error unsupported: byte order detection failed\n#endif  /* defined(DUK_USE_BYTEORDER) */\n\n\n#if JUCE_DEBUG\n//TODO: We need a better system for allowing custom/user configured duk_config headers\n//      in react-juce. This set of inline change works for now to enable debugging support.\n#define DUK_USE_INTERRUPT_COUNTER\n#define DUK_USE_DEBUGGER_SUPPORT\n#define DUK_USE_DEBUGGER_INSPECT\n#define DUK_USE_DEBUGGER_FWD_LOGGING\n\n#endif\n\n#endif  /* DUK_CONFIG_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-noline/duk_source_meta.json",
    "content": "{\n    \"comment\": \"Metadata for Duktape sources\", \n    \"duk_version_string\": \"2.4.0\", \n    \"type\": \"duk_source_meta\", \n    \"line_map\": [\n        {\n            \"original_line\": 1, \n            \"combined_line\": 154, \n            \"original_file\": \"duk_replacements.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 163, \n            \"original_file\": \"duk_internal.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 200, \n            \"original_file\": \"duk_dblunion.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 624, \n            \"original_file\": \"duk_replacements.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 654, \n            \"original_file\": \"duk_jmpbuf.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 679, \n            \"original_file\": \"duk_exception.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 710, \n            \"original_file\": \"duk_forwdecl.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 845, \n            \"original_file\": \"duk_tval.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 1485, \n            \"original_file\": \"duk_builtins.h\"\n        }, \n        {\n            \"original_line\": 44, \n            \"combined_line\": 2271, \n            \"original_file\": \"duk_internal.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 2273, \n            \"original_file\": \"duk_util.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 2980, \n            \"original_file\": \"duk_strings.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 3148, \n            \"original_file\": \"duk_js_bytecode.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 3631, \n            \"original_file\": \"duk_lexer.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 4070, \n            \"original_file\": \"duk_js_compiler.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 4298, \n            \"original_file\": \"duk_regexp.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 4383, \n            \"original_file\": \"duk_heaphdr.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 4681, \n            \"original_file\": \"duk_refcount.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 5407, \n            \"original_file\": \"duk_api_internal.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 5772, \n            \"original_file\": \"duk_hstring.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 6026, \n            \"original_file\": \"duk_hobject.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 7008, \n            \"original_file\": \"duk_hcompfunc.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 7282, \n            \"original_file\": \"duk_hnatfunc.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 7322, \n            \"original_file\": \"duk_hboundfunc.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 7360, \n            \"original_file\": \"duk_hbufobj.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 7488, \n            \"original_file\": \"duk_hthread.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 7897, \n            \"original_file\": \"duk_harray.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 7946, \n            \"original_file\": \"duk_henv.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 7992, \n            \"original_file\": \"duk_hbuffer.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 8329, \n            \"original_file\": \"duk_hproxy.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 8356, \n            \"original_file\": \"duk_heap.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 9083, \n            \"original_file\": \"duk_debugger.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 9235, \n            \"original_file\": \"duk_debug.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 9420, \n            \"original_file\": \"duk_error.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 9946, \n            \"original_file\": \"duk_unicode.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 10236, \n            \"original_file\": \"duk_json.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 10305, \n            \"original_file\": \"duk_js.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 10420, \n            \"original_file\": \"duk_numconv.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 10525, \n            \"original_file\": \"duk_bi_protos.h\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 10607, \n            \"original_file\": \"duk_selftest.h\"\n        }, \n        {\n            \"original_line\": 75, \n            \"combined_line\": 10622, \n            \"original_file\": \"duk_internal.h\"\n        }, \n        {\n            \"original_line\": 10, \n            \"combined_line\": 10624, \n            \"original_file\": \"duk_replacements.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 10697, \n            \"original_file\": \"duk_debug_macros.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 10788, \n            \"original_file\": \"duk_builtins.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 11644, \n            \"original_file\": \"duk_error_macros.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 11799, \n            \"original_file\": \"duk_unicode_support.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 12980, \n            \"original_file\": \"duk_util_misc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 13163, \n            \"original_file\": \"duk_hobject_class.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 13292, \n            \"original_file\": \"duk_alloc_default.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 13326, \n            \"original_file\": \"duk_api_buffer.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 13399, \n            \"original_file\": \"duk_api_bytecode.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 14167, \n            \"original_file\": \"duk_api_call.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 14683, \n            \"original_file\": \"duk_api_codec.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 15609, \n            \"original_file\": \"duk_api_compile.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 15781, \n            \"original_file\": \"duk_api_debug.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 16042, \n            \"original_file\": \"duk_api_heap.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 16247, \n            \"original_file\": \"duk_api_inspect.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 16492, \n            \"original_file\": \"duk_api_memory.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 16572, \n            \"original_file\": \"duk_api_object.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 17622, \n            \"original_file\": \"duk_api_random.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 17631, \n            \"original_file\": \"duk_api_stack.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 24585, \n            \"original_file\": \"duk_api_string.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 24963, \n            \"original_file\": \"duk_api_time.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 25073, \n            \"original_file\": \"duk_bi_array.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 26730, \n            \"original_file\": \"duk_bi_boolean.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 26799, \n            \"original_file\": \"duk_bi_buffer.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 29735, \n            \"original_file\": \"duk_bi_date.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 31553, \n            \"original_file\": \"duk_bi_date_unix.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 31882, \n            \"original_file\": \"duk_bi_date_windows.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 32075, \n            \"original_file\": \"duk_bi_duktape.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 32233, \n            \"original_file\": \"duk_bi_encoding.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 32771, \n            \"original_file\": \"duk_bi_error.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 33163, \n            \"original_file\": \"duk_bi_function.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 33616, \n            \"original_file\": \"duk_bi_global.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 34347, \n            \"original_file\": \"duk_bi_json.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 37616, \n            \"original_file\": \"duk_bi_math.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 38134, \n            \"original_file\": \"duk_bi_number.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 38414, \n            \"original_file\": \"duk_bi_object.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 39217, \n            \"original_file\": \"duk_bi_performance.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 39248, \n            \"original_file\": \"duk_bi_pointer.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 39323, \n            \"original_file\": \"duk_bi_promise.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 39367, \n            \"original_file\": \"duk_bi_proxy.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 39463, \n            \"original_file\": \"duk_bi_reflect.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 39562, \n            \"original_file\": \"duk_bi_regexp.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 39788, \n            \"original_file\": \"duk_bi_string.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 41368, \n            \"original_file\": \"duk_bi_symbol.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 41538, \n            \"original_file\": \"duk_bi_thread.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 41864, \n            \"original_file\": \"duk_bi_thrower.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 41873, \n            \"original_file\": \"duk_debug_fixedbuffer.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 41942, \n            \"original_file\": \"duk_debug_vsnprintf.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 43042, \n            \"original_file\": \"duk_debugger.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 45956, \n            \"original_file\": \"duk_error_augment.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 46523, \n            \"original_file\": \"duk_error_longjmp.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 46626, \n            \"original_file\": \"duk_error_misc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 46800, \n            \"original_file\": \"duk_error_throw.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 46962, \n            \"original_file\": \"duk_hbuffer_alloc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 47094, \n            \"original_file\": \"duk_hbuffer_assert.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 47107, \n            \"original_file\": \"duk_hbuffer_ops.c\"\n        }, \n        {\n            \"original_line\": 2, \n            \"combined_line\": 47186, \n            \"original_file\": \"duk_hbufobj_misc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 47205, \n            \"original_file\": \"duk_heap_alloc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 48430, \n            \"original_file\": \"duk_heap_finalize.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 48875, \n            \"original_file\": \"duk_heap_hashstring.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 48996, \n            \"original_file\": \"duk_heap_markandsweep.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 50478, \n            \"original_file\": \"duk_heap_memory.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 50843, \n            \"original_file\": \"duk_heap_misc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 51030, \n            \"original_file\": \"duk_heap_refcount.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 51876, \n            \"original_file\": \"duk_heap_stringcache.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 52185, \n            \"original_file\": \"duk_heap_stringtable.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 53234, \n            \"original_file\": \"duk_heaphdr_assert.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 53312, \n            \"original_file\": \"duk_hobject_alloc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 53583, \n            \"original_file\": \"duk_hobject_assert.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 53710, \n            \"original_file\": \"duk_hobject_enum.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 54419, \n            \"original_file\": \"duk_hobject_misc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 54472, \n            \"original_file\": \"duk_hobject_pc2line.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 54716, \n            \"original_file\": \"duk_hobject_props.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 60927, \n            \"original_file\": \"duk_hstring_assert.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 60940, \n            \"original_file\": \"duk_hstring_misc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 61136, \n            \"original_file\": \"duk_hthread_alloc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 61195, \n            \"original_file\": \"duk_hthread_builtins.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 62081, \n            \"original_file\": \"duk_hthread_misc.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 62178, \n            \"original_file\": \"duk_hthread_stacks.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 62585, \n            \"original_file\": \"duk_js_arith.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 62722, \n            \"original_file\": \"duk_js_call.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 65658, \n            \"original_file\": \"duk_js_compiler.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 73765, \n            \"original_file\": \"duk_js_executor.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 79036, \n            \"original_file\": \"duk_js_ops.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 80494, \n            \"original_file\": \"duk_js_var.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 82287, \n            \"original_file\": \"duk_lexer.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 84748, \n            \"original_file\": \"duk_numconv.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 87041, \n            \"original_file\": \"duk_regexp_compiler.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 88332, \n            \"original_file\": \"duk_regexp_executor.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 89359, \n            \"original_file\": \"duk_selftest.c\"\n        }, \n        {\n            \"original_line\": 2, \n            \"combined_line\": 90046, \n            \"original_file\": \"duk_tval.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 90197, \n            \"original_file\": \"duk_unicode_tables.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 96372, \n            \"original_file\": \"duk_util_bitdecoder.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 96538, \n            \"original_file\": \"duk_util_bitencoder.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 96581, \n            \"original_file\": \"duk_util_bufwriter.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 96959, \n            \"original_file\": \"duk_util_cast.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 97127, \n            \"original_file\": \"duk_util_double.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 97361, \n            \"original_file\": \"duk_util_hashbytes.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 97422, \n            \"original_file\": \"duk_util_memory.c\"\n        }, \n        {\n            \"original_line\": 1, \n            \"combined_line\": 97458, \n            \"original_file\": \"duk_util_tinyrandom.c\"\n        }\n    ], \n    \"duk_version\": 20400, \n    \"git_branch\": \"master\", \n    \"git_commit\": \"d4f2cff1c592d70f58bab8e1bd85705174c02a58\", \n    \"builtin_strings_info\": [\n        {\n            \"plain\": \"Undefined\", \n            \"base64\": \"VW5kZWZpbmVk\", \n            \"define\": \"DUK_STRIDX_UC_UNDEFINED\"\n        }, \n        {\n            \"plain\": \"Null\", \n            \"base64\": \"TnVsbA==\", \n            \"define\": \"DUK_STRIDX_UC_NULL\"\n        }, \n        {\n            \"plain\": \"Symbol\", \n            \"base64\": \"U3ltYm9s\", \n            \"define\": \"DUK_STRIDX_UC_SYMBOL\"\n        }, \n        {\n            \"plain\": \"Arguments\", \n            \"base64\": \"QXJndW1lbnRz\", \n            \"define\": \"DUK_STRIDX_UC_ARGUMENTS\"\n        }, \n        {\n            \"plain\": \"Object\", \n            \"base64\": \"T2JqZWN0\", \n            \"define\": \"DUK_STRIDX_UC_OBJECT\"\n        }, \n        {\n            \"plain\": \"Function\", \n            \"base64\": \"RnVuY3Rpb24=\", \n            \"define\": \"DUK_STRIDX_UC_FUNCTION\"\n        }, \n        {\n            \"plain\": \"Array\", \n            \"base64\": \"QXJyYXk=\", \n            \"define\": \"DUK_STRIDX_ARRAY\"\n        }, \n        {\n            \"plain\": \"String\", \n            \"base64\": \"U3RyaW5n\", \n            \"define\": \"DUK_STRIDX_UC_STRING\"\n        }, \n        {\n            \"plain\": \"Boolean\", \n            \"base64\": \"Qm9vbGVhbg==\", \n            \"define\": \"DUK_STRIDX_UC_BOOLEAN\"\n        }, \n        {\n            \"plain\": \"Number\", \n            \"base64\": \"TnVtYmVy\", \n            \"define\": \"DUK_STRIDX_UC_NUMBER\"\n        }, \n        {\n            \"plain\": \"Date\", \n            \"base64\": \"RGF0ZQ==\", \n            \"define\": \"DUK_STRIDX_DATE\"\n        }, \n        {\n            \"plain\": \"RegExp\", \n            \"base64\": \"UmVnRXhw\", \n            \"define\": \"DUK_STRIDX_REG_EXP\"\n        }, \n        {\n            \"plain\": \"Error\", \n            \"base64\": \"RXJyb3I=\", \n            \"define\": \"DUK_STRIDX_UC_ERROR\"\n        }, \n        {\n            \"plain\": \"Math\", \n            \"base64\": \"TWF0aA==\", \n            \"define\": \"DUK_STRIDX_MATH\"\n        }, \n        {\n            \"plain\": \"JSON\", \n            \"base64\": \"SlNPTg==\", \n            \"define\": \"DUK_STRIDX_JSON\"\n        }, \n        {\n            \"plain\": \"\", \n            \"base64\": \"\", \n            \"define\": \"DUK_STRIDX_EMPTY_STRING\"\n        }, \n        {\n            \"plain\": \"ArrayBuffer\", \n            \"base64\": \"QXJyYXlCdWZmZXI=\", \n            \"define\": \"DUK_STRIDX_ARRAY_BUFFER\"\n        }, \n        {\n            \"plain\": \"DataView\", \n            \"base64\": \"RGF0YVZpZXc=\", \n            \"define\": \"DUK_STRIDX_DATA_VIEW\"\n        }, \n        {\n            \"plain\": \"Int8Array\", \n            \"base64\": \"SW50OEFycmF5\", \n            \"define\": \"DUK_STRIDX_INT8_ARRAY\"\n        }, \n        {\n            \"plain\": \"Uint8Array\", \n            \"base64\": \"VWludDhBcnJheQ==\", \n            \"define\": \"DUK_STRIDX_UINT8_ARRAY\"\n        }, \n        {\n            \"plain\": \"Uint8ClampedArray\", \n            \"base64\": \"VWludDhDbGFtcGVkQXJyYXk=\", \n            \"define\": \"DUK_STRIDX_UINT8_CLAMPED_ARRAY\"\n        }, \n        {\n            \"plain\": \"Int16Array\", \n            \"base64\": \"SW50MTZBcnJheQ==\", \n            \"define\": \"DUK_STRIDX_INT16_ARRAY\"\n        }, \n        {\n            \"plain\": \"Uint16Array\", \n            \"base64\": \"VWludDE2QXJyYXk=\", \n            \"define\": \"DUK_STRIDX_UINT16_ARRAY\"\n        }, \n        {\n            \"plain\": \"Int32Array\", \n            \"base64\": \"SW50MzJBcnJheQ==\", \n            \"define\": \"DUK_STRIDX_INT32_ARRAY\"\n        }, \n        {\n            \"plain\": \"Uint32Array\", \n            \"base64\": \"VWludDMyQXJyYXk=\", \n            \"define\": \"DUK_STRIDX_UINT32_ARRAY\"\n        }, \n        {\n            \"plain\": \"Float32Array\", \n            \"base64\": \"RmxvYXQzMkFycmF5\", \n            \"define\": \"DUK_STRIDX_FLOAT32_ARRAY\"\n        }, \n        {\n            \"plain\": \"Float64Array\", \n            \"base64\": \"RmxvYXQ2NEFycmF5\", \n            \"define\": \"DUK_STRIDX_FLOAT64_ARRAY\"\n        }, \n        {\n            \"plain\": \"global\", \n            \"base64\": \"Z2xvYmFs\", \n            \"define\": \"DUK_STRIDX_GLOBAL\"\n        }, \n        {\n            \"plain\": \"ObjEnv\", \n            \"base64\": \"T2JqRW52\", \n            \"define\": \"DUK_STRIDX_OBJ_ENV\"\n        }, \n        {\n            \"plain\": \"DecEnv\", \n            \"base64\": \"RGVjRW52\", \n            \"define\": \"DUK_STRIDX_DEC_ENV\"\n        }, \n        {\n            \"plain\": \"Buffer\", \n            \"base64\": \"QnVmZmVy\", \n            \"define\": \"DUK_STRIDX_UC_BUFFER\"\n        }, \n        {\n            \"plain\": \"Pointer\", \n            \"base64\": \"UG9pbnRlcg==\", \n            \"define\": \"DUK_STRIDX_UC_POINTER\"\n        }, \n        {\n            \"plain\": \"Thread\", \n            \"base64\": \"VGhyZWFk\", \n            \"define\": \"DUK_STRIDX_UC_THREAD\"\n        }, \n        {\n            \"plain\": \"eval\", \n            \"base64\": \"ZXZhbA==\", \n            \"define\": \"DUK_STRIDX_EVAL\"\n        }, \n        {\n            \"plain\": \"value\", \n            \"base64\": \"dmFsdWU=\", \n            \"define\": \"DUK_STRIDX_VALUE\"\n        }, \n        {\n            \"plain\": \"writable\", \n            \"base64\": \"d3JpdGFibGU=\", \n            \"define\": \"DUK_STRIDX_WRITABLE\"\n        }, \n        {\n            \"plain\": \"configurable\", \n            \"base64\": \"Y29uZmlndXJhYmxl\", \n            \"define\": \"DUK_STRIDX_CONFIGURABLE\"\n        }, \n        {\n            \"plain\": \"enumerable\", \n            \"base64\": \"ZW51bWVyYWJsZQ==\", \n            \"define\": \"DUK_STRIDX_ENUMERABLE\"\n        }, \n        {\n            \"plain\": \"join\", \n            \"base64\": \"am9pbg==\", \n            \"define\": \"DUK_STRIDX_JOIN\"\n        }, \n        {\n            \"plain\": \"toLocaleString\", \n            \"base64\": \"dG9Mb2NhbGVTdHJpbmc=\", \n            \"define\": \"DUK_STRIDX_TO_LOCALE_STRING\"\n        }, \n        {\n            \"plain\": \"valueOf\", \n            \"base64\": \"dmFsdWVPZg==\", \n            \"define\": \"DUK_STRIDX_VALUE_OF\"\n        }, \n        {\n            \"plain\": \"toUTCString\", \n            \"base64\": \"dG9VVENTdHJpbmc=\", \n            \"define\": \"DUK_STRIDX_TO_UTC_STRING\"\n        }, \n        {\n            \"plain\": \"toISOString\", \n            \"base64\": \"dG9JU09TdHJpbmc=\", \n            \"define\": \"DUK_STRIDX_TO_ISO_STRING\"\n        }, \n        {\n            \"plain\": \"toGMTString\", \n            \"base64\": \"dG9HTVRTdHJpbmc=\", \n            \"define\": \"DUK_STRIDX_TO_GMT_STRING\"\n        }, \n        {\n            \"plain\": \"source\", \n            \"base64\": \"c291cmNl\", \n            \"define\": \"DUK_STRIDX_SOURCE\"\n        }, \n        {\n            \"plain\": \"ignoreCase\", \n            \"base64\": \"aWdub3JlQ2FzZQ==\", \n            \"define\": \"DUK_STRIDX_IGNORE_CASE\"\n        }, \n        {\n            \"plain\": \"multiline\", \n            \"base64\": \"bXVsdGlsaW5l\", \n            \"define\": \"DUK_STRIDX_MULTILINE\"\n        }, \n        {\n            \"plain\": \"lastIndex\", \n            \"base64\": \"bGFzdEluZGV4\", \n            \"define\": \"DUK_STRIDX_LAST_INDEX\"\n        }, \n        {\n            \"plain\": \"flags\", \n            \"base64\": \"ZmxhZ3M=\", \n            \"define\": \"DUK_STRIDX_FLAGS\"\n        }, \n        {\n            \"plain\": \"index\", \n            \"base64\": \"aW5kZXg=\", \n            \"define\": \"DUK_STRIDX_INDEX\"\n        }, \n        {\n            \"plain\": \"prototype\", \n            \"base64\": \"cHJvdG90eXBl\", \n            \"define\": \"DUK_STRIDX_PROTOTYPE\"\n        }, \n        {\n            \"plain\": \"constructor\", \n            \"base64\": \"Y29uc3RydWN0b3I=\", \n            \"define\": \"DUK_STRIDX_CONSTRUCTOR\"\n        }, \n        {\n            \"plain\": \"message\", \n            \"base64\": \"bWVzc2FnZQ==\", \n            \"define\": \"DUK_STRIDX_MESSAGE\"\n        }, \n        {\n            \"plain\": \"boolean\", \n            \"base64\": \"Ym9vbGVhbg==\", \n            \"define\": \"DUK_STRIDX_LC_BOOLEAN\"\n        }, \n        {\n            \"plain\": \"number\", \n            \"base64\": \"bnVtYmVy\", \n            \"define\": \"DUK_STRIDX_LC_NUMBER\"\n        }, \n        {\n            \"plain\": \"string\", \n            \"base64\": \"c3RyaW5n\", \n            \"define\": \"DUK_STRIDX_LC_STRING\"\n        }, \n        {\n            \"plain\": \"symbol\", \n            \"base64\": \"c3ltYm9s\", \n            \"define\": \"DUK_STRIDX_LC_SYMBOL\"\n        }, \n        {\n            \"plain\": \"object\", \n            \"base64\": \"b2JqZWN0\", \n            \"define\": \"DUK_STRIDX_LC_OBJECT\"\n        }, \n        {\n            \"plain\": \"undefined\", \n            \"base64\": \"dW5kZWZpbmVk\", \n            \"define\": \"DUK_STRIDX_LC_UNDEFINED\"\n        }, \n        {\n            \"plain\": \"NaN\", \n            \"base64\": \"TmFO\", \n            \"define\": \"DUK_STRIDX_NAN\"\n        }, \n        {\n            \"plain\": \"Infinity\", \n            \"base64\": \"SW5maW5pdHk=\", \n            \"define\": \"DUK_STRIDX_INFINITY\"\n        }, \n        {\n            \"plain\": \"-Infinity\", \n            \"base64\": \"LUluZmluaXR5\", \n            \"define\": \"DUK_STRIDX_MINUS_INFINITY\"\n        }, \n        {\n            \"plain\": \"-0\", \n            \"base64\": \"LTA=\", \n            \"define\": \"DUK_STRIDX_MINUS_ZERO\"\n        }, \n        {\n            \"plain\": \",\", \n            \"base64\": \"LA==\", \n            \"define\": \"DUK_STRIDX_COMMA\"\n        }, \n        {\n            \"plain\": \"\\n    \", \n            \"base64\": \"CiAgICA=\", \n            \"define\": \"DUK_STRIDX_NEWLINE_4SPACE\"\n        }, \n        {\n            \"plain\": \"[...]\", \n            \"base64\": \"Wy4uLl0=\", \n            \"define\": \"DUK_STRIDX_BRACKETED_ELLIPSIS\"\n        }, \n        {\n            \"plain\": \"Invalid Date\", \n            \"base64\": \"SW52YWxpZCBEYXRl\", \n            \"define\": \"DUK_STRIDX_INVALID_DATE\"\n        }, \n        {\n            \"plain\": \"arguments\", \n            \"base64\": \"YXJndW1lbnRz\", \n            \"define\": \"DUK_STRIDX_LC_ARGUMENTS\"\n        }, \n        {\n            \"plain\": \"callee\", \n            \"base64\": \"Y2FsbGVl\", \n            \"define\": \"DUK_STRIDX_CALLEE\"\n        }, \n        {\n            \"plain\": \"caller\", \n            \"base64\": \"Y2FsbGVy\", \n            \"define\": \"DUK_STRIDX_CALLER\"\n        }, \n        {\n            \"plain\": \"apply\", \n            \"base64\": \"YXBwbHk=\", \n            \"define\": \"DUK_STRIDX_APPLY\"\n        }, \n        {\n            \"plain\": \"construct\", \n            \"base64\": \"Y29uc3RydWN0\", \n            \"define\": \"DUK_STRIDX_CONSTRUCT\"\n        }, \n        {\n            \"plain\": \"deleteProperty\", \n            \"base64\": \"ZGVsZXRlUHJvcGVydHk=\", \n            \"define\": \"DUK_STRIDX_DELETE_PROPERTY\"\n        }, \n        {\n            \"plain\": \"get\", \n            \"base64\": \"Z2V0\", \n            \"define\": \"DUK_STRIDX_GET\"\n        }, \n        {\n            \"plain\": \"has\", \n            \"base64\": \"aGFz\", \n            \"define\": \"DUK_STRIDX_HAS\"\n        }, \n        {\n            \"plain\": \"ownKeys\", \n            \"base64\": \"b3duS2V5cw==\", \n            \"define\": \"DUK_STRIDX_OWN_KEYS\"\n        }, \n        {\n            \"plain\": \"\\u0081Symbol.toPrimitive\\u00ff\", \n            \"base64\": \"gVN5bWJvbC50b1ByaW1pdGl2Zf8=\", \n            \"define\": \"DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE\"\n        }, \n        {\n            \"plain\": \"\\u0081Symbol.hasInstance\\u00ff\", \n            \"base64\": \"gVN5bWJvbC5oYXNJbnN0YW5jZf8=\", \n            \"define\": \"DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE\"\n        }, \n        {\n            \"plain\": \"\\u0081Symbol.toStringTag\\u00ff\", \n            \"base64\": \"gVN5bWJvbC50b1N0cmluZ1RhZ/8=\", \n            \"define\": \"DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG\"\n        }, \n        {\n            \"plain\": \"\\u0081Symbol.isConcatSpreadable\\u00ff\", \n            \"base64\": \"gVN5bWJvbC5pc0NvbmNhdFNwcmVhZGFibGX/\", \n            \"define\": \"DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE\"\n        }, \n        {\n            \"plain\": \"setPrototypeOf\", \n            \"base64\": \"c2V0UHJvdG90eXBlT2Y=\", \n            \"define\": \"DUK_STRIDX_SET_PROTOTYPE_OF\"\n        }, \n        {\n            \"plain\": \"__proto__\", \n            \"base64\": \"X19wcm90b19f\", \n            \"define\": \"DUK_STRIDX___PROTO__\"\n        }, \n        {\n            \"plain\": \"toString\", \n            \"base64\": \"dG9TdHJpbmc=\", \n            \"define\": \"DUK_STRIDX_TO_STRING\"\n        }, \n        {\n            \"plain\": \"toJSON\", \n            \"base64\": \"dG9KU09O\", \n            \"define\": \"DUK_STRIDX_TO_JSON\"\n        }, \n        {\n            \"plain\": \"type\", \n            \"base64\": \"dHlwZQ==\", \n            \"define\": \"DUK_STRIDX_TYPE\"\n        }, \n        {\n            \"plain\": \"data\", \n            \"base64\": \"ZGF0YQ==\", \n            \"define\": \"DUK_STRIDX_DATA\"\n        }, \n        {\n            \"plain\": \"length\", \n            \"base64\": \"bGVuZ3Ro\", \n            \"define\": \"DUK_STRIDX_LENGTH\"\n        }, \n        {\n            \"plain\": \"set\", \n            \"base64\": \"c2V0\", \n            \"define\": \"DUK_STRIDX_SET\"\n        }, \n        {\n            \"plain\": \"stack\", \n            \"base64\": \"c3RhY2s=\", \n            \"define\": \"DUK_STRIDX_STACK\"\n        }, \n        {\n            \"plain\": \"pc\", \n            \"base64\": \"cGM=\", \n            \"define\": \"DUK_STRIDX_PC\"\n        }, \n        {\n            \"plain\": \"lineNumber\", \n            \"base64\": \"bGluZU51bWJlcg==\", \n            \"define\": \"DUK_STRIDX_LINE_NUMBER\"\n        }, \n        {\n            \"plain\": \"\\u0082Tracedata\", \n            \"base64\": \"glRyYWNlZGF0YQ==\", \n            \"define\": \"DUK_STRIDX_INT_TRACEDATA\"\n        }, \n        {\n            \"plain\": \"name\", \n            \"base64\": \"bmFtZQ==\", \n            \"define\": \"DUK_STRIDX_NAME\"\n        }, \n        {\n            \"plain\": \"fileName\", \n            \"base64\": \"ZmlsZU5hbWU=\", \n            \"define\": \"DUK_STRIDX_FILE_NAME\"\n        }, \n        {\n            \"plain\": \"pointer\", \n            \"base64\": \"cG9pbnRlcg==\", \n            \"define\": \"DUK_STRIDX_LC_POINTER\"\n        }, \n        {\n            \"plain\": \"\\u0082Target\", \n            \"base64\": \"glRhcmdldA==\", \n            \"define\": \"DUK_STRIDX_INT_TARGET\"\n        }, \n        {\n            \"plain\": \"\\u0082Next\", \n            \"base64\": \"gk5leHQ=\", \n            \"define\": \"DUK_STRIDX_INT_NEXT\"\n        }, \n        {\n            \"plain\": \"\\u0082Bytecode\", \n            \"base64\": \"gkJ5dGVjb2Rl\", \n            \"define\": \"DUK_STRIDX_INT_BYTECODE\"\n        }, \n        {\n            \"plain\": \"\\u0082Formals\", \n            \"base64\": \"gkZvcm1hbHM=\", \n            \"define\": \"DUK_STRIDX_INT_FORMALS\"\n        }, \n        {\n            \"plain\": \"\\u0082Varmap\", \n            \"base64\": \"glZhcm1hcA==\", \n            \"define\": \"DUK_STRIDX_INT_VARMAP\"\n        }, \n        {\n            \"plain\": \"\\u0082Source\", \n            \"base64\": \"glNvdXJjZQ==\", \n            \"define\": \"DUK_STRIDX_INT_SOURCE\"\n        }, \n        {\n            \"plain\": \"\\u0082Pc2line\", \n            \"base64\": \"glBjMmxpbmU=\", \n            \"define\": \"DUK_STRIDX_INT_PC2LINE\"\n        }, \n        {\n            \"plain\": \"\\u0082Map\", \n            \"base64\": \"gk1hcA==\", \n            \"define\": \"DUK_STRIDX_INT_MAP\"\n        }, \n        {\n            \"plain\": \"\\u0082Varenv\", \n            \"base64\": \"glZhcmVudg==\", \n            \"define\": \"DUK_STRIDX_INT_VARENV\"\n        }, \n        {\n            \"plain\": \"\\u0082Finalizer\", \n            \"base64\": \"gkZpbmFsaXplcg==\", \n            \"define\": \"DUK_STRIDX_INT_FINALIZER\"\n        }, \n        {\n            \"plain\": \"\\u0082Value\", \n            \"base64\": \"glZhbHVl\", \n            \"define\": \"DUK_STRIDX_INT_VALUE\"\n        }, \n        {\n            \"plain\": \"compile\", \n            \"base64\": \"Y29tcGlsZQ==\", \n            \"define\": \"DUK_STRIDX_COMPILE\"\n        }, \n        {\n            \"plain\": \"input\", \n            \"base64\": \"aW5wdXQ=\", \n            \"define\": \"DUK_STRIDX_INPUT\"\n        }, \n        {\n            \"plain\": \"errCreate\", \n            \"base64\": \"ZXJyQ3JlYXRl\", \n            \"define\": \"DUK_STRIDX_ERR_CREATE\"\n        }, \n        {\n            \"plain\": \"errThrow\", \n            \"base64\": \"ZXJyVGhyb3c=\", \n            \"define\": \"DUK_STRIDX_ERR_THROW\"\n        }, \n        {\n            \"plain\": \"env\", \n            \"base64\": \"ZW52\", \n            \"define\": \"DUK_STRIDX_ENV\"\n        }, \n        {\n            \"plain\": \"hex\", \n            \"base64\": \"aGV4\", \n            \"define\": \"DUK_STRIDX_HEX\"\n        }, \n        {\n            \"plain\": \"base64\", \n            \"base64\": \"YmFzZTY0\", \n            \"define\": \"DUK_STRIDX_BASE64\"\n        }, \n        {\n            \"plain\": \"jx\", \n            \"base64\": \"ang=\", \n            \"define\": \"DUK_STRIDX_JX\"\n        }, \n        {\n            \"plain\": \"jc\", \n            \"base64\": \"amM=\", \n            \"define\": \"DUK_STRIDX_JC\"\n        }, \n        {\n            \"plain\": \"{\\\"_undef\\\":true}\", \n            \"base64\": \"eyJfdW5kZWYiOnRydWV9\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_UNDEFINED\"\n        }, \n        {\n            \"plain\": \"{\\\"_nan\\\":true}\", \n            \"base64\": \"eyJfbmFuIjp0cnVlfQ==\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_NAN\"\n        }, \n        {\n            \"plain\": \"{\\\"_inf\\\":true}\", \n            \"base64\": \"eyJfaW5mIjp0cnVlfQ==\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_POSINF\"\n        }, \n        {\n            \"plain\": \"{\\\"_ninf\\\":true}\", \n            \"base64\": \"eyJfbmluZiI6dHJ1ZX0=\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_NEGINF\"\n        }, \n        {\n            \"plain\": \"{\\\"_func\\\":true}\", \n            \"base64\": \"eyJfZnVuYyI6dHJ1ZX0=\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_FUNCTION1\"\n        }, \n        {\n            \"plain\": \"{_func:true}\", \n            \"base64\": \"e19mdW5jOnRydWV9\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_FUNCTION2\"\n        }, \n        {\n            \"plain\": \"break\", \n            \"base64\": \"YnJlYWs=\", \n            \"define\": \"DUK_STRIDX_BREAK\"\n        }, \n        {\n            \"plain\": \"case\", \n            \"base64\": \"Y2FzZQ==\", \n            \"define\": \"DUK_STRIDX_CASE\"\n        }, \n        {\n            \"plain\": \"catch\", \n            \"base64\": \"Y2F0Y2g=\", \n            \"define\": \"DUK_STRIDX_CATCH\"\n        }, \n        {\n            \"plain\": \"continue\", \n            \"base64\": \"Y29udGludWU=\", \n            \"define\": \"DUK_STRIDX_CONTINUE\"\n        }, \n        {\n            \"plain\": \"debugger\", \n            \"base64\": \"ZGVidWdnZXI=\", \n            \"define\": \"DUK_STRIDX_DEBUGGER\"\n        }, \n        {\n            \"plain\": \"default\", \n            \"base64\": \"ZGVmYXVsdA==\", \n            \"define\": \"DUK_STRIDX_DEFAULT\"\n        }, \n        {\n            \"plain\": \"delete\", \n            \"base64\": \"ZGVsZXRl\", \n            \"define\": \"DUK_STRIDX_DELETE\"\n        }, \n        {\n            \"plain\": \"do\", \n            \"base64\": \"ZG8=\", \n            \"define\": \"DUK_STRIDX_DO\"\n        }, \n        {\n            \"plain\": \"else\", \n            \"base64\": \"ZWxzZQ==\", \n            \"define\": \"DUK_STRIDX_ELSE\"\n        }, \n        {\n            \"plain\": \"finally\", \n            \"base64\": \"ZmluYWxseQ==\", \n            \"define\": \"DUK_STRIDX_FINALLY\"\n        }, \n        {\n            \"plain\": \"for\", \n            \"base64\": \"Zm9y\", \n            \"define\": \"DUK_STRIDX_FOR\"\n        }, \n        {\n            \"plain\": \"function\", \n            \"base64\": \"ZnVuY3Rpb24=\", \n            \"define\": \"DUK_STRIDX_LC_FUNCTION\"\n        }, \n        {\n            \"plain\": \"if\", \n            \"base64\": \"aWY=\", \n            \"define\": \"DUK_STRIDX_IF\"\n        }, \n        {\n            \"plain\": \"in\", \n            \"base64\": \"aW4=\", \n            \"define\": \"DUK_STRIDX_IN\"\n        }, \n        {\n            \"plain\": \"instanceof\", \n            \"base64\": \"aW5zdGFuY2VvZg==\", \n            \"define\": \"DUK_STRIDX_INSTANCEOF\"\n        }, \n        {\n            \"plain\": \"new\", \n            \"base64\": \"bmV3\", \n            \"define\": \"DUK_STRIDX_NEW\"\n        }, \n        {\n            \"plain\": \"return\", \n            \"base64\": \"cmV0dXJu\", \n            \"define\": \"DUK_STRIDX_RETURN\"\n        }, \n        {\n            \"plain\": \"switch\", \n            \"base64\": \"c3dpdGNo\", \n            \"define\": \"DUK_STRIDX_SWITCH\"\n        }, \n        {\n            \"plain\": \"this\", \n            \"base64\": \"dGhpcw==\", \n            \"define\": \"DUK_STRIDX_THIS\"\n        }, \n        {\n            \"plain\": \"throw\", \n            \"base64\": \"dGhyb3c=\", \n            \"define\": \"DUK_STRIDX_THROW\"\n        }, \n        {\n            \"plain\": \"try\", \n            \"base64\": \"dHJ5\", \n            \"define\": \"DUK_STRIDX_TRY\"\n        }, \n        {\n            \"plain\": \"typeof\", \n            \"base64\": \"dHlwZW9m\", \n            \"define\": \"DUK_STRIDX_TYPEOF\"\n        }, \n        {\n            \"plain\": \"var\", \n            \"base64\": \"dmFy\", \n            \"define\": \"DUK_STRIDX_VAR\"\n        }, \n        {\n            \"plain\": \"const\", \n            \"base64\": \"Y29uc3Q=\", \n            \"define\": \"DUK_STRIDX_CONST\"\n        }, \n        {\n            \"plain\": \"void\", \n            \"base64\": \"dm9pZA==\", \n            \"define\": \"DUK_STRIDX_VOID\"\n        }, \n        {\n            \"plain\": \"while\", \n            \"base64\": \"d2hpbGU=\", \n            \"define\": \"DUK_STRIDX_WHILE\"\n        }, \n        {\n            \"plain\": \"with\", \n            \"base64\": \"d2l0aA==\", \n            \"define\": \"DUK_STRIDX_WITH\"\n        }, \n        {\n            \"plain\": \"class\", \n            \"base64\": \"Y2xhc3M=\", \n            \"define\": \"DUK_STRIDX_CLASS\"\n        }, \n        {\n            \"plain\": \"enum\", \n            \"base64\": \"ZW51bQ==\", \n            \"define\": \"DUK_STRIDX_ENUM\"\n        }, \n        {\n            \"plain\": \"export\", \n            \"base64\": \"ZXhwb3J0\", \n            \"define\": \"DUK_STRIDX_EXPORT\"\n        }, \n        {\n            \"plain\": \"extends\", \n            \"base64\": \"ZXh0ZW5kcw==\", \n            \"define\": \"DUK_STRIDX_EXTENDS\"\n        }, \n        {\n            \"plain\": \"import\", \n            \"base64\": \"aW1wb3J0\", \n            \"define\": \"DUK_STRIDX_IMPORT\"\n        }, \n        {\n            \"plain\": \"super\", \n            \"base64\": \"c3VwZXI=\", \n            \"define\": \"DUK_STRIDX_SUPER\"\n        }, \n        {\n            \"plain\": \"null\", \n            \"base64\": \"bnVsbA==\", \n            \"define\": \"DUK_STRIDX_LC_NULL\"\n        }, \n        {\n            \"plain\": \"true\", \n            \"base64\": \"dHJ1ZQ==\", \n            \"define\": \"DUK_STRIDX_TRUE\"\n        }, \n        {\n            \"plain\": \"false\", \n            \"base64\": \"ZmFsc2U=\", \n            \"define\": \"DUK_STRIDX_FALSE\"\n        }, \n        {\n            \"plain\": \"implements\", \n            \"base64\": \"aW1wbGVtZW50cw==\", \n            \"define\": \"DUK_STRIDX_IMPLEMENTS\"\n        }, \n        {\n            \"plain\": \"interface\", \n            \"base64\": \"aW50ZXJmYWNl\", \n            \"define\": \"DUK_STRIDX_INTERFACE\"\n        }, \n        {\n            \"plain\": \"let\", \n            \"base64\": \"bGV0\", \n            \"define\": \"DUK_STRIDX_LET\"\n        }, \n        {\n            \"plain\": \"package\", \n            \"base64\": \"cGFja2FnZQ==\", \n            \"define\": \"DUK_STRIDX_PACKAGE\"\n        }, \n        {\n            \"plain\": \"private\", \n            \"base64\": \"cHJpdmF0ZQ==\", \n            \"define\": \"DUK_STRIDX_PRIVATE\"\n        }, \n        {\n            \"plain\": \"protected\", \n            \"base64\": \"cHJvdGVjdGVk\", \n            \"define\": \"DUK_STRIDX_PROTECTED\"\n        }, \n        {\n            \"plain\": \"public\", \n            \"base64\": \"cHVibGlj\", \n            \"define\": \"DUK_STRIDX_PUBLIC\"\n        }, \n        {\n            \"plain\": \"static\", \n            \"base64\": \"c3RhdGlj\", \n            \"define\": \"DUK_STRIDX_STATIC\"\n        }, \n        {\n            \"plain\": \"yield\", \n            \"base64\": \"eWllbGQ=\", \n            \"define\": \"DUK_STRIDX_YIELD\"\n        }\n    ], \n    \"builtin_strings_base64\": [\n        \"VW5kZWZpbmVk\", \n        \"TnVsbA==\", \n        \"U3ltYm9s\", \n        \"QXJndW1lbnRz\", \n        \"T2JqZWN0\", \n        \"RnVuY3Rpb24=\", \n        \"QXJyYXk=\", \n        \"U3RyaW5n\", \n        \"Qm9vbGVhbg==\", \n        \"TnVtYmVy\", \n        \"RGF0ZQ==\", \n        \"UmVnRXhw\", \n        \"RXJyb3I=\", \n        \"TWF0aA==\", \n        \"SlNPTg==\", \n        \"\", \n        \"QXJyYXlCdWZmZXI=\", \n        \"RGF0YVZpZXc=\", \n        \"SW50OEFycmF5\", \n        \"VWludDhBcnJheQ==\", \n        \"VWludDhDbGFtcGVkQXJyYXk=\", \n        \"SW50MTZBcnJheQ==\", \n        \"VWludDE2QXJyYXk=\", \n        \"SW50MzJBcnJheQ==\", \n        \"VWludDMyQXJyYXk=\", \n        \"RmxvYXQzMkFycmF5\", \n        \"RmxvYXQ2NEFycmF5\", \n        \"Z2xvYmFs\", \n        \"T2JqRW52\", \n        \"RGVjRW52\", \n        \"QnVmZmVy\", \n        \"UG9pbnRlcg==\", \n        \"VGhyZWFk\", \n        \"ZXZhbA==\", \n        \"dmFsdWU=\", \n        \"d3JpdGFibGU=\", \n        \"Y29uZmlndXJhYmxl\", \n        \"ZW51bWVyYWJsZQ==\", \n        \"am9pbg==\", \n        \"dG9Mb2NhbGVTdHJpbmc=\", \n        \"dmFsdWVPZg==\", \n        \"dG9VVENTdHJpbmc=\", \n        \"dG9JU09TdHJpbmc=\", \n        \"dG9HTVRTdHJpbmc=\", \n        \"c291cmNl\", \n        \"aWdub3JlQ2FzZQ==\", \n        \"bXVsdGlsaW5l\", \n        \"bGFzdEluZGV4\", \n        \"ZmxhZ3M=\", \n        \"aW5kZXg=\", \n        \"cHJvdG90eXBl\", \n        \"Y29uc3RydWN0b3I=\", \n        \"bWVzc2FnZQ==\", \n        \"Ym9vbGVhbg==\", \n        \"bnVtYmVy\", \n        \"c3RyaW5n\", \n        \"c3ltYm9s\", \n        \"b2JqZWN0\", \n        \"dW5kZWZpbmVk\", \n        \"TmFO\", \n        \"SW5maW5pdHk=\", \n        \"LUluZmluaXR5\", \n        \"LTA=\", \n        \"LA==\", \n        \"CiAgICA=\", \n        \"Wy4uLl0=\", \n        \"SW52YWxpZCBEYXRl\", \n        \"YXJndW1lbnRz\", \n        \"Y2FsbGVl\", \n        \"Y2FsbGVy\", \n        \"YXBwbHk=\", \n        \"Y29uc3RydWN0\", \n        \"ZGVsZXRlUHJvcGVydHk=\", \n        \"Z2V0\", \n        \"aGFz\", \n        \"b3duS2V5cw==\", \n        \"gVN5bWJvbC50b1ByaW1pdGl2Zf8=\", \n        \"gVN5bWJvbC5oYXNJbnN0YW5jZf8=\", \n        \"gVN5bWJvbC50b1N0cmluZ1RhZ/8=\", \n        \"gVN5bWJvbC5pc0NvbmNhdFNwcmVhZGFibGX/\", \n        \"c2V0UHJvdG90eXBlT2Y=\", \n        \"X19wcm90b19f\", \n        \"dG9TdHJpbmc=\", \n        \"dG9KU09O\", \n        \"dHlwZQ==\", \n        \"ZGF0YQ==\", \n        \"bGVuZ3Ro\", \n        \"c2V0\", \n        \"c3RhY2s=\", \n        \"cGM=\", \n        \"bGluZU51bWJlcg==\", \n        \"glRyYWNlZGF0YQ==\", \n        \"bmFtZQ==\", \n        \"ZmlsZU5hbWU=\", \n        \"cG9pbnRlcg==\", \n        \"glRhcmdldA==\", \n        \"gk5leHQ=\", \n        \"gkJ5dGVjb2Rl\", \n        \"gkZvcm1hbHM=\", \n        \"glZhcm1hcA==\", \n        \"glNvdXJjZQ==\", \n        \"glBjMmxpbmU=\", \n        \"gk1hcA==\", \n        \"glZhcmVudg==\", \n        \"gkZpbmFsaXplcg==\", \n        \"glZhbHVl\", \n        \"Y29tcGlsZQ==\", \n        \"aW5wdXQ=\", \n        \"ZXJyQ3JlYXRl\", \n        \"ZXJyVGhyb3c=\", \n        \"ZW52\", \n        \"aGV4\", \n        \"YmFzZTY0\", \n        \"ang=\", \n        \"amM=\", \n        \"eyJfdW5kZWYiOnRydWV9\", \n        \"eyJfbmFuIjp0cnVlfQ==\", \n        \"eyJfaW5mIjp0cnVlfQ==\", \n        \"eyJfbmluZiI6dHJ1ZX0=\", \n        \"eyJfZnVuYyI6dHJ1ZX0=\", \n        \"e19mdW5jOnRydWV9\", \n        \"YnJlYWs=\", \n        \"Y2FzZQ==\", \n        \"Y2F0Y2g=\", \n        \"Y29udGludWU=\", \n        \"ZGVidWdnZXI=\", \n        \"ZGVmYXVsdA==\", \n        \"ZGVsZXRl\", \n        \"ZG8=\", \n        \"ZWxzZQ==\", \n        \"ZmluYWxseQ==\", \n        \"Zm9y\", \n        \"ZnVuY3Rpb24=\", \n        \"aWY=\", \n        \"aW4=\", \n        \"aW5zdGFuY2VvZg==\", \n        \"bmV3\", \n        \"cmV0dXJu\", \n        \"c3dpdGNo\", \n        \"dGhpcw==\", \n        \"dGhyb3c=\", \n        \"dHJ5\", \n        \"dHlwZW9m\", \n        \"dmFy\", \n        \"Y29uc3Q=\", \n        \"dm9pZA==\", \n        \"d2hpbGU=\", \n        \"d2l0aA==\", \n        \"Y2xhc3M=\", \n        \"ZW51bQ==\", \n        \"ZXhwb3J0\", \n        \"ZXh0ZW5kcw==\", \n        \"aW1wb3J0\", \n        \"c3VwZXI=\", \n        \"bnVsbA==\", \n        \"dHJ1ZQ==\", \n        \"ZmFsc2U=\", \n        \"aW1wbGVtZW50cw==\", \n        \"aW50ZXJmYWNl\", \n        \"bGV0\", \n        \"cGFja2FnZQ==\", \n        \"cHJpdmF0ZQ==\", \n        \"cHJvdGVjdGVk\", \n        \"cHVibGlj\", \n        \"c3RhdGlj\", \n        \"eWllbGQ=\"\n    ], \n    \"git_describe\": \"v2.4.0\", \n    \"builtin_strings\": [\n        \"Undefined\", \n        \"Null\", \n        \"Symbol\", \n        \"Arguments\", \n        \"Object\", \n        \"Function\", \n        \"Array\", \n        \"String\", \n        \"Boolean\", \n        \"Number\", \n        \"Date\", \n        \"RegExp\", \n        \"Error\", \n        \"Math\", \n        \"JSON\", \n        \"\", \n        \"ArrayBuffer\", \n        \"DataView\", \n        \"Int8Array\", \n        \"Uint8Array\", \n        \"Uint8ClampedArray\", \n        \"Int16Array\", \n        \"Uint16Array\", \n        \"Int32Array\", \n        \"Uint32Array\", \n        \"Float32Array\", \n        \"Float64Array\", \n        \"global\", \n        \"ObjEnv\", \n        \"DecEnv\", \n        \"Buffer\", \n        \"Pointer\", \n        \"Thread\", \n        \"eval\", \n        \"value\", \n        \"writable\", \n        \"configurable\", \n        \"enumerable\", \n        \"join\", \n        \"toLocaleString\", \n        \"valueOf\", \n        \"toUTCString\", \n        \"toISOString\", \n        \"toGMTString\", \n        \"source\", \n        \"ignoreCase\", \n        \"multiline\", \n        \"lastIndex\", \n        \"flags\", \n        \"index\", \n        \"prototype\", \n        \"constructor\", \n        \"message\", \n        \"boolean\", \n        \"number\", \n        \"string\", \n        \"symbol\", \n        \"object\", \n        \"undefined\", \n        \"NaN\", \n        \"Infinity\", \n        \"-Infinity\", \n        \"-0\", \n        \",\", \n        \"\\n    \", \n        \"[...]\", \n        \"Invalid Date\", \n        \"arguments\", \n        \"callee\", \n        \"caller\", \n        \"apply\", \n        \"construct\", \n        \"deleteProperty\", \n        \"get\", \n        \"has\", \n        \"ownKeys\", \n        \"\\u0081Symbol.toPrimitive\\u00ff\", \n        \"\\u0081Symbol.hasInstance\\u00ff\", \n        \"\\u0081Symbol.toStringTag\\u00ff\", \n        \"\\u0081Symbol.isConcatSpreadable\\u00ff\", \n        \"setPrototypeOf\", \n        \"__proto__\", \n        \"toString\", \n        \"toJSON\", \n        \"type\", \n        \"data\", \n        \"length\", \n        \"set\", \n        \"stack\", \n        \"pc\", \n        \"lineNumber\", \n        \"\\u0082Tracedata\", \n        \"name\", \n        \"fileName\", \n        \"pointer\", \n        \"\\u0082Target\", \n        \"\\u0082Next\", \n        \"\\u0082Bytecode\", \n        \"\\u0082Formals\", \n        \"\\u0082Varmap\", \n        \"\\u0082Source\", \n        \"\\u0082Pc2line\", \n        \"\\u0082Map\", \n        \"\\u0082Varenv\", \n        \"\\u0082Finalizer\", \n        \"\\u0082Value\", \n        \"compile\", \n        \"input\", \n        \"errCreate\", \n        \"errThrow\", \n        \"env\", \n        \"hex\", \n        \"base64\", \n        \"jx\", \n        \"jc\", \n        \"{\\\"_undef\\\":true}\", \n        \"{\\\"_nan\\\":true}\", \n        \"{\\\"_inf\\\":true}\", \n        \"{\\\"_ninf\\\":true}\", \n        \"{\\\"_func\\\":true}\", \n        \"{_func:true}\", \n        \"break\", \n        \"case\", \n        \"catch\", \n        \"continue\", \n        \"debugger\", \n        \"default\", \n        \"delete\", \n        \"do\", \n        \"else\", \n        \"finally\", \n        \"for\", \n        \"function\", \n        \"if\", \n        \"in\", \n        \"instanceof\", \n        \"new\", \n        \"return\", \n        \"switch\", \n        \"this\", \n        \"throw\", \n        \"try\", \n        \"typeof\", \n        \"var\", \n        \"const\", \n        \"void\", \n        \"while\", \n        \"with\", \n        \"class\", \n        \"enum\", \n        \"export\", \n        \"extends\", \n        \"import\", \n        \"super\", \n        \"null\", \n        \"true\", \n        \"false\", \n        \"implements\", \n        \"interface\", \n        \"let\", \n        \"package\", \n        \"private\", \n        \"protected\", \n        \"public\", \n        \"static\", \n        \"yield\"\n    ]\n}"
  },
  {
    "path": "react_juce/duktape/src-noline/duktape.c",
    "content": "/*\n *  Single source autogenerated distributable for Duktape 2.4.0.\n *\n *  Git commit d4f2cff1c592d70f58bab8e1bd85705174c02a58 (v2.4.0).\n *  Git branch master.\n *\n *  See Duktape AUTHORS.rst and LICENSE.txt for copyright and\n *  licensing information.\n */\n\n/* LICENSE.txt */\n/*\n*  ===============\n*  Duktape license\n*  ===============\n*\n*  (http://opensource.org/licenses/MIT)\n*\n*  Copyright (c) 2013-2019 by Duktape authors (see AUTHORS.rst)\n*\n*  Permission is hereby granted, free of charge, to any person obtaining a copy\n*  of this software and associated documentation files (the \"Software\"), to deal\n*  in the Software without restriction, including without limitation the rights\n*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n*  copies of the Software, and to permit persons to whom the Software is\n*  furnished to do so, subject to the following conditions:\n*\n*  The above copyright notice and this permission notice shall be included in\n*  all copies or substantial portions of the Software.\n*\n*  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n*  THE SOFTWARE.\n*/\n\n/* AUTHORS.rst */\n/*\n*  ===============\n*  Duktape authors\n*  ===============\n*\n*  Copyright\n*  =========\n*\n*  Duktape copyrights are held by its authors.  Each author has a copyright\n*  to their contribution, and agrees to irrevocably license the contribution\n*  under the Duktape ``LICENSE.txt``.\n*\n*  Authors\n*  =======\n*\n*  Please include an e-mail address, a link to your GitHub profile, or something\n*  similar to allow your contribution to be identified accurately.\n*\n*  The following people have contributed code, website contents, or Wiki contents,\n*  and agreed to irrevocably license their contributions under the Duktape\n*  ``LICENSE.txt`` (in order of appearance):\n*\n*  * Sami Vaarala <sami.vaarala@iki.fi>\n*  * Niki Dobrev\n*  * Andreas \\u00d6man <andreas@lonelycoder.com>\n*  * L\\u00e1szl\\u00f3 Lang\\u00f3 <llango.u-szeged@partner.samsung.com>\n*  * Legimet <legimet.calc@gmail.com>\n*  * Karl Skomski <karl@skomski.com>\n*  * Bruce Pascoe <fatcerberus1@gmail.com>\n*  * Ren\\u00e9 Hollander <rene@rene8888.at>\n*  * Julien Hamaide (https://github.com/crazyjul)\n*  * Sebastian G\\u00f6tte (https://github.com/jaseg)\n*  * Tomasz Magulski (https://github.com/magul)\n*  * \\D. Bohdan (https://github.com/dbohdan)\n*  * Ond\\u0159ej Jirman (https://github.com/megous)\n*  * Sa\\u00fal Ibarra Corretg\\u00e9 <saghul@gmail.com>\n*  * Jeremy HU <huxingyi@msn.com>\n*  * Ole Andr\\u00e9 Vadla Ravn\\u00e5s (https://github.com/oleavr)\n*  * Harold Brenes (https://github.com/harold-b)\n*  * Oliver Crow (https://github.com/ocrow)\n*  * Jakub Ch\\u0142api\\u0144ski (https://github.com/jchlapinski)\n*  * Brett Vickers (https://github.com/beevik)\n*  * Dominik Okwieka (https://github.com/okitec)\n*  * Remko Tron\\u00e7on (https://el-tramo.be)\n*  * Romero Malaquias (rbsm@ic.ufal.br)\n*  * Michael Drake <michael.drake@codethink.co.uk>\n*  * Steven Don (https://github.com/shdon)\n*  * Simon Stone (https://github.com/sstone1)\n*  * \\J. McC. (https://github.com/jmhmccr)\n*  * Jakub Nowakowski (https://github.com/jimvonmoon)\n*  * Tommy Nguyen (https://github.com/tn0502)\n*  * Fabrice Fontaine (https://github.com/ffontaine)\n*  * Christopher Hiller (https://github.com/boneskull)\n*  * Gonzalo Diethelm (https://github.com/gonzus)\n*  * Michal Kasperek (https://github.com/michalkas)\n*  * Andrew Janke (https://github.com/apjanke)\n*  * Steve Fan (https://github.com/stevefan1999)\n*  * Edward Betts (https://github.com/edwardbetts)\n*  * Ozhan Duz (https://github.com/webfolderio)\n*  * Akos Kiss (https://github.com/akosthekiss)\n*  * TheBrokenRail (https://github.com/TheBrokenRail)\n*  * Jesse Doyle (https://github.com/jessedoyle)\n*  * Gero Kuehn (https://github.com/dc6jgk)\n*  * James Swift (https://github.com/phraemer)\n*  * Luis de Bethencourt (https://github.com/luisbg)\n*  * Ian Whyman (https://github.com/v00d00)\n*\n*  Other contributions\n*  ===================\n*\n*  The following people have contributed something other than code (e.g. reported\n*  bugs, provided ideas, etc; roughly in order of appearance):\n*\n*  * Greg Burns\n*  * Anthony Rabine\n*  * Carlos Costa\n*  * Aur\\u00e9lien Bouilland\n*  * Preet Desai (Pris Matic)\n*  * judofyr (http://www.reddit.com/user/judofyr)\n*  * Jason Woofenden\n*  * Micha\\u0142 Przyby\\u015b\n*  * Anthony Howe\n*  * Conrad Pankoff\n*  * Jim Schimpf\n*  * Rajaran Gaunker (https://github.com/zimbabao)\n*  * Andreas \\u00d6man\n*  * Doug Sanden\n*  * Josh Engebretson (https://github.com/JoshEngebretson)\n*  * Remo Eichenberger (https://github.com/remoe)\n*  * Mamod Mehyar (https://github.com/mamod)\n*  * David Demelier (https://github.com/markand)\n*  * Tim Caswell (https://github.com/creationix)\n*  * Mitchell Blank Jr (https://github.com/mitchblank)\n*  * https://github.com/yushli\n*  * Seo Sanghyeon (https://github.com/sanxiyn)\n*  * Han ChoongWoo (https://github.com/tunz)\n*  * Joshua Peek (https://github.com/josh)\n*  * Bruce E. Pascoe (https://github.com/fatcerberus)\n*  * https://github.com/Kelledin\n*  * https://github.com/sstruchtrup\n*  * Michael Drake (https://github.com/tlsa)\n*  * https://github.com/chris-y\n*  * Laurent Zubiaur (https://github.com/lzubiaur)\n*  * Neil Kolban (https://github.com/nkolban)\n*  * Wilhelm Wanecek (https://github.com/wanecek)\n*  * Andrew Janke (https://github.com/apjanke)\n*  * Unamer (https://github.com/unamer)\n*  * Karl Dahlke (eklhad@gmail.com)\n*\n*  If you are accidentally missing from this list, send me an e-mail\n*  (``sami.vaarala@iki.fi``) and I'll fix the omission.\n*/\n\n/*\n *  Replacements for missing platform functions.\n *\n *  Unlike the originals, fpclassify() and signbit() replacements don't\n *  work on any floating point types, only doubles.  The C typing here\n *  mimics the standard prototypes.\n */\n\n/* #include duk_internal.h */\n/*\n *  Top-level include file to be used for all (internal) source files.\n *\n *  Source files should not include individual header files, as they\n *  have not been designed to be individually included.\n */\n\n#if !defined(DUK_INTERNAL_H_INCLUDED)\n#define DUK_INTERNAL_H_INCLUDED\n\n/*\n *  The 'duktape.h' header provides the public API, but also handles all\n *  compiler and platform specific feature detection, Duktape feature\n *  resolution, inclusion of system headers, etc.  These have been merged\n *  because the public API is also dependent on e.g. detecting appropriate\n *  C types which is quite platform/compiler specific especially for a non-C99\n *  build.  The public API is also dependent on the resolved feature set.\n *\n *  Some actions taken by the merged header (such as including system headers)\n *  are not appropriate for building a user application.  The define\n *  DUK_COMPILING_DUKTAPE allows the merged header to skip/include some\n *  sections depending on what is being built.\n */\n\n#define DUK_COMPILING_DUKTAPE\n#include \"duktape.h\"\n\n/*\n *  Duktape includes (other than duk_features.h)\n *\n *  The header files expect to be included in an order which satisfies header\n *  dependencies correctly (the headers themselves don't include any other\n *  includes).  Forward declarations are used to break circular struct/typedef\n *  dependencies.\n */\n\n/* #include duk_dblunion.h */\n/*\n *  Union to access IEEE double memory representation, indexes for double\n *  memory representation, and some macros for double manipulation.\n *\n *  Also used by packed duk_tval.  Use a union for bit manipulation to\n *  minimize aliasing issues in practice.  The C99 standard does not\n *  guarantee that this should work, but it's a very widely supported\n *  practice for low level manipulation.\n *\n *  IEEE double format summary:\n *\n *    seeeeeee eeeeffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n *       A        B        C        D        E        F        G        H\n *\n *    s       sign bit\n *    eee...  exponent field\n *    fff...  fraction\n *\n *  See http://en.wikipedia.org/wiki/Double_precision_floating-point_format.\n *\n *  NaNs are represented as exponent 0x7ff and mantissa != 0.  The NaN is a\n *  signaling NaN when the highest bit of the mantissa is zero, and a quiet\n *  NaN when the highest bit is set.\n *\n *  At least three memory layouts are relevant here:\n *\n *    A B C D E F G H    Big endian (e.g. 68k)           DUK_USE_DOUBLE_BE\n *    H G F E D C B A    Little endian (e.g. x86)        DUK_USE_DOUBLE_LE\n *    D C B A H G F E    Mixed/cross endian (e.g. ARM)   DUK_USE_DOUBLE_ME\n *\n *  ARM is a special case: ARM double values are in mixed/cross endian\n *  format while ARM duk_uint64_t values are in standard little endian\n *  format (H G F E D C B A).  When a double is read as a duk_uint64_t\n *  from memory, the register will contain the (logical) value\n *  E F G H A B C D.  This requires some special handling below.\n *\n *  Indexes of various types (8-bit, 16-bit, 32-bit) in memory relative to\n *  the logical (big endian) order:\n *\n *  byte order      duk_uint8_t    duk_uint16_t     duk_uint32_t\n *    BE             01234567         0123               01\n *    LE             76543210         3210               10\n *    ME (ARM)       32107654         1032               01\n *\n *  Some processors may alter NaN values in a floating point load+store.\n *  For instance, on X86 a FLD + FSTP may convert a signaling NaN to a\n *  quiet one.  This is catastrophic when NaN space is used in packed\n *  duk_tval values.  See: misc/clang_aliasing.c.\n */\n\n#if !defined(DUK_DBLUNION_H_INCLUDED)\n#define DUK_DBLUNION_H_INCLUDED\n\n/*\n *  Union for accessing double parts, also serves as packed duk_tval\n */\n\nunion duk_double_union {\n\tdouble d;\n\tfloat f[2];\n#if defined(DUK_USE_64BIT_OPS)\n\tduk_uint64_t ull[1];\n#endif\n\tduk_uint32_t ui[2];\n\tduk_uint16_t us[4];\n\tduk_uint8_t uc[8];\n#if defined(DUK_USE_PACKED_TVAL)\n\tvoid *vp[2];  /* used by packed duk_tval, assumes sizeof(void *) == 4 */\n#endif\n};\n\ntypedef union duk_double_union duk_double_union;\n\n/*\n *  Indexes of various types with respect to big endian (logical) layout\n */\n\n#if defined(DUK_USE_DOUBLE_LE)\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBL_IDX_ULL0   0\n#endif\n#define DUK_DBL_IDX_UI0    1\n#define DUK_DBL_IDX_UI1    0\n#define DUK_DBL_IDX_US0    3\n#define DUK_DBL_IDX_US1    2\n#define DUK_DBL_IDX_US2    1\n#define DUK_DBL_IDX_US3    0\n#define DUK_DBL_IDX_UC0    7\n#define DUK_DBL_IDX_UC1    6\n#define DUK_DBL_IDX_UC2    5\n#define DUK_DBL_IDX_UC3    4\n#define DUK_DBL_IDX_UC4    3\n#define DUK_DBL_IDX_UC5    2\n#define DUK_DBL_IDX_UC6    1\n#define DUK_DBL_IDX_UC7    0\n#define DUK_DBL_IDX_VP0    DUK_DBL_IDX_UI0  /* packed tval */\n#define DUK_DBL_IDX_VP1    DUK_DBL_IDX_UI1  /* packed tval */\n#elif defined(DUK_USE_DOUBLE_BE)\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBL_IDX_ULL0   0\n#endif\n#define DUK_DBL_IDX_UI0    0\n#define DUK_DBL_IDX_UI1    1\n#define DUK_DBL_IDX_US0    0\n#define DUK_DBL_IDX_US1    1\n#define DUK_DBL_IDX_US2    2\n#define DUK_DBL_IDX_US3    3\n#define DUK_DBL_IDX_UC0    0\n#define DUK_DBL_IDX_UC1    1\n#define DUK_DBL_IDX_UC2    2\n#define DUK_DBL_IDX_UC3    3\n#define DUK_DBL_IDX_UC4    4\n#define DUK_DBL_IDX_UC5    5\n#define DUK_DBL_IDX_UC6    6\n#define DUK_DBL_IDX_UC7    7\n#define DUK_DBL_IDX_VP0    DUK_DBL_IDX_UI0  /* packed tval */\n#define DUK_DBL_IDX_VP1    DUK_DBL_IDX_UI1  /* packed tval */\n#elif defined(DUK_USE_DOUBLE_ME)\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBL_IDX_ULL0   0  /* not directly applicable, byte order differs from a double */\n#endif\n#define DUK_DBL_IDX_UI0    0\n#define DUK_DBL_IDX_UI1    1\n#define DUK_DBL_IDX_US0    1\n#define DUK_DBL_IDX_US1    0\n#define DUK_DBL_IDX_US2    3\n#define DUK_DBL_IDX_US3    2\n#define DUK_DBL_IDX_UC0    3\n#define DUK_DBL_IDX_UC1    2\n#define DUK_DBL_IDX_UC2    1\n#define DUK_DBL_IDX_UC3    0\n#define DUK_DBL_IDX_UC4    7\n#define DUK_DBL_IDX_UC5    6\n#define DUK_DBL_IDX_UC6    5\n#define DUK_DBL_IDX_UC7    4\n#define DUK_DBL_IDX_VP0    DUK_DBL_IDX_UI0  /* packed tval */\n#define DUK_DBL_IDX_VP1    DUK_DBL_IDX_UI1  /* packed tval */\n#else\n#error internal error\n#endif\n\n/*\n *  Helper macros for reading/writing memory representation parts, used\n *  by duk_numconv.c and duk_tval.h.\n */\n\n#define DUK_DBLUNION_SET_DOUBLE(u,v)  do {  \\\n\t\t(u)->d = (v); \\\n\t} while (0)\n\n#define DUK_DBLUNION_SET_HIGH32(u,v)  do {  \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) (v); \\\n\t} while (0)\n\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = (duk_uint64_t) (v); \\\n\t} while (0)\n#else\n#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = ((duk_uint64_t) (v)) << 32; \\\n\t} while (0)\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v)  do { \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) (v); \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0; \\\n\t} while (0)\n#endif  /* DUK_USE_64BIT_OPS */\n\n#define DUK_DBLUNION_SET_LOW32(u,v)  do {  \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (v); \\\n\t} while (0)\n\n#define DUK_DBLUNION_GET_DOUBLE(u)  ((u)->d)\n#define DUK_DBLUNION_GET_HIGH32(u)  ((u)->ui[DUK_DBL_IDX_UI0])\n#define DUK_DBLUNION_GET_LOW32(u)   ((u)->ui[DUK_DBL_IDX_UI1])\n\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK_DBLUNION_SET_UINT64(u,v)  do { \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) ((v) >> 32); \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (v); \\\n\t} while (0)\n#define DUK_DBLUNION_GET_UINT64(u) \\\n\t((((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI0]) << 32) | \\\n\t ((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI1]))\n#else\n#define DUK_DBLUNION_SET_UINT64(u,v)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = (duk_uint64_t) (v); \\\n\t} while (0)\n#define DUK_DBLUNION_GET_UINT64(u)  ((u)->ull[DUK_DBL_IDX_ULL0])\n#endif\n#define DUK_DBLUNION_SET_INT64(u,v) DUK_DBLUNION_SET_UINT64((u), (duk_uint64_t) (v))\n#define DUK_DBLUNION_GET_INT64(u)   ((duk_int64_t) DUK_DBLUNION_GET_UINT64((u)))\n#endif  /* DUK_USE_64BIT_OPS */\n\n/*\n *  Double NaN manipulation macros related to NaN normalization needed when\n *  using the packed duk_tval representation.  NaN normalization is necessary\n *  to keep double values compatible with the duk_tval format.\n *\n *  When packed duk_tval is used, the NaN space is used to store pointers\n *  and other tagged values in addition to NaNs.  Actual NaNs are normalized\n *  to a specific quiet NaN.  The macros below are used by the implementation\n *  to check and normalize NaN values when they might be created.  The macros\n *  are essentially NOPs when the non-packed duk_tval representation is used.\n *\n *  A FULL check is exact and checks all bits.  A NOTFULL check is used by\n *  the packed duk_tval and works correctly for all NaNs except those that\n *  begin with 0x7ff0.  Since the 'normalized NaN' values used with packed\n *  duk_tval begin with 0x7ff8, the partial check is reliable when packed\n *  duk_tval is used.  The 0x7ff8 prefix means the normalized NaN will be a\n *  quiet NaN regardless of its remaining lower bits.\n *\n *  The ME variant below is specifically for ARM byte order, which has the\n *  feature that while doubles have a mixed byte order (32107654), unsigned\n *  long long values has a little endian byte order (76543210).  When writing\n *  a logical double value through a ULL pointer, the 32-bit words need to be\n *  swapped; hence the #if defined()s below for ULL writes with DUK_USE_DOUBLE_ME.\n *  This is not full ARM support but suffices for some environments.\n */\n\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n/* Macros for 64-bit ops + mixed endian doubles. */\n#define DUK__DBLUNION_SET_NAN_FULL(u)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x000000007ff80000); \\\n\t} while (0)\n#define DUK__DBLUNION_IS_NAN_FULL(u) \\\n\t((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000)) && \\\n\t ((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0xffffffff000fffff)) != 0))\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff80000))\n#define DUK__DBLUNION_IS_ANYINF(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x000000007ff00000))\n#define DUK__DBLUNION_IS_POSINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff00000))\n#define DUK__DBLUNION_IS_NEGINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x00000000fff00000))\n#define DUK__DBLUNION_IS_ANYZERO(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_POSZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_NEGZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000080000000))\n#else\n/* Macros for 64-bit ops + big/little endian doubles. */\n#define DUK__DBLUNION_SET_NAN_FULL(u)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x7ff8000000000000); \\\n\t} while (0)\n#define DUK__DBLUNION_IS_NAN_FULL(u) \\\n\t((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000)) && \\\n\t ((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0x000fffffffffffff)) != 0))\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff8000000000000))\n#define DUK__DBLUNION_IS_ANYINF(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x7ff0000000000000))\n#define DUK__DBLUNION_IS_POSINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff0000000000000))\n#define DUK__DBLUNION_IS_NEGINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0xfff0000000000000))\n#define DUK__DBLUNION_IS_ANYZERO(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_POSZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_NEGZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x8000000000000000))\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n/* Macros for no 64-bit ops, any endianness. */\n#define DUK__DBLUNION_SET_NAN_FULL(u)  do { \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) 0x7ff80000UL; \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0x00000000UL; \\\n\t} while (0)\n#define DUK__DBLUNION_IS_NAN_FULL(u) \\\n\t((((u)->ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL) && \\\n\t (((u)->ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) != 0 || \\\n          (u)->ui[DUK_DBL_IDX_UI1] != 0))\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff80000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_ANYINF(u) \\\n\t((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x7ff00000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_POSINF(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff00000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_NEGINF(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0xfff00000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_ANYZERO(u) \\\n\t((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x00000000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_POSZERO(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x00000000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_NEGZERO(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x80000000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#endif  /* DUK_USE_64BIT_OPS */\n\n#define DUK__DBLUNION_SET_NAN_NOTFULL(u)  do { \\\n\t\t(u)->us[DUK_DBL_IDX_US0] = 0x7ff8UL; \\\n\t} while (0)\n\n#define DUK__DBLUNION_IS_NAN_NOTFULL(u) \\\n\t/* E == 0x7ff, topmost four bits of F != 0 => assume NaN */ \\\n\t((((u)->us[DUK_DBL_IDX_US0] & 0x7ff0UL) == 0x7ff0UL) && \\\n\t (((u)->us[DUK_DBL_IDX_US0] & 0x000fUL) != 0x0000UL))\n\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL(u) \\\n\t/* E == 0x7ff, F == 8 => normalized NaN */ \\\n\t((u)->us[DUK_DBL_IDX_US0] == 0x7ff8UL)\n\n#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL(u)  do { \\\n\t\tif (DUK__DBLUNION_IS_NAN_FULL((u))) { \\\n\t\t\tDUK__DBLUNION_SET_NAN_FULL((u)); \\\n\t\t} \\\n\t} while (0)\n\n#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL(u)  do { \\\n\t\tif (DUK__DBLUNION_IS_NAN_NOTFULL((u))) { \\\n\t\t\tDUK__DBLUNION_SET_NAN_NOTFULL((u)); \\\n\t\t} \\\n\t} while (0)\n\n/* Concrete macros for NaN handling used by the implementation internals.\n * Chosen so that they match the duk_tval representation: with a packed\n * duk_tval, ensure NaNs are properly normalized; with a non-packed duk_tval\n * these are essentially NOPs.\n */\n\n#if defined(DUK_USE_PACKED_TVAL)\n#if defined(DUK_USE_FULL_TVAL)\n#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u)  DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL((u))\n#define DUK_DBLUNION_IS_NAN(u)               DUK__DBLUNION_IS_NAN_FULL((u))\n#define DUK_DBLUNION_IS_NORMALIZED_NAN(u)    DUK__DBLUNION_IS_NORMALIZED_NAN_FULL((u))\n#define DUK_DBLUNION_SET_NAN(d)              DUK__DBLUNION_SET_NAN_FULL((d))\n#else\n#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u)  DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL((u))\n#define DUK_DBLUNION_IS_NAN(u)               DUK__DBLUNION_IS_NAN_NOTFULL((u))\n#define DUK_DBLUNION_IS_NORMALIZED_NAN(u)    DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL((u))\n#define DUK_DBLUNION_SET_NAN(d)              DUK__DBLUNION_SET_NAN_NOTFULL((d))\n#endif\n#define DUK_DBLUNION_IS_NORMALIZED(u) \\\n\t(!DUK_DBLUNION_IS_NAN((u)) ||  /* either not a NaN */ \\\n\t DUK_DBLUNION_IS_NORMALIZED_NAN((u)))  /* or is a normalized NaN */\n#else  /* DUK_USE_PACKED_TVAL */\n#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u)  /* nop: no need to normalize */\n#define DUK_DBLUNION_IS_NAN(u)               DUK__DBLUNION_IS_NAN_FULL((u))  /* (DUK_ISNAN((u)->d)) */\n#define DUK_DBLUNION_IS_NORMALIZED_NAN(u)    DUK__DBLUNION_IS_NAN_FULL((u))  /* (DUK_ISNAN((u)->d)) */\n#define DUK_DBLUNION_IS_NORMALIZED(u)        1  /* all doubles are considered normalized */\n#define DUK_DBLUNION_SET_NAN(u)  do { \\\n\t\t/* in non-packed representation we don't care about which NaN is used */ \\\n\t\t(u)->d = DUK_DOUBLE_NAN; \\\n\t} while (0)\n#endif  /* DUK_USE_PACKED_TVAL */\n\n#define DUK_DBLUNION_IS_ANYINF(u) DUK__DBLUNION_IS_ANYINF((u))\n#define DUK_DBLUNION_IS_POSINF(u) DUK__DBLUNION_IS_POSINF((u))\n#define DUK_DBLUNION_IS_NEGINF(u) DUK__DBLUNION_IS_NEGINF((u))\n\n#define DUK_DBLUNION_IS_ANYZERO(u) DUK__DBLUNION_IS_ANYZERO((u))\n#define DUK_DBLUNION_IS_POSZERO(u) DUK__DBLUNION_IS_POSZERO((u))\n#define DUK_DBLUNION_IS_NEGZERO(u) DUK__DBLUNION_IS_NEGZERO((u))\n\n/* XXX: native 64-bit byteswaps when available */\n\n/* 64-bit byteswap, same operation independent of target endianness. */\n#define DUK_DBLUNION_BSWAP64(u) do { \\\n\t\tduk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \\\n\t\tduk__bswaptmp1 = (u)->ui[0]; \\\n\t\tduk__bswaptmp2 = (u)->ui[1]; \\\n\t\tduk__bswaptmp1 = DUK_BSWAP32(duk__bswaptmp1); \\\n\t\tduk__bswaptmp2 = DUK_BSWAP32(duk__bswaptmp2); \\\n\t\t(u)->ui[0] = duk__bswaptmp2; \\\n\t\t(u)->ui[1] = duk__bswaptmp1; \\\n\t} while (0)\n\n/* Byteswap an IEEE double in the duk_double_union from host to network\n * order.  For a big endian target this is a no-op.\n */\n#if defined(DUK_USE_DOUBLE_LE)\n#define DUK_DBLUNION_DOUBLE_HTON(u) do { \\\n\t\tduk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \\\n\t\tduk__bswaptmp1 = (u)->ui[0]; \\\n\t\tduk__bswaptmp2 = (u)->ui[1]; \\\n\t\tduk__bswaptmp1 = DUK_BSWAP32(duk__bswaptmp1); \\\n\t\tduk__bswaptmp2 = DUK_BSWAP32(duk__bswaptmp2); \\\n\t\t(u)->ui[0] = duk__bswaptmp2; \\\n\t\t(u)->ui[1] = duk__bswaptmp1; \\\n\t} while (0)\n#elif defined(DUK_USE_DOUBLE_ME)\n#define DUK_DBLUNION_DOUBLE_HTON(u) do { \\\n\t\tduk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \\\n\t\tduk__bswaptmp1 = (u)->ui[0]; \\\n\t\tduk__bswaptmp2 = (u)->ui[1]; \\\n\t\tduk__bswaptmp1 = DUK_BSWAP32(duk__bswaptmp1); \\\n\t\tduk__bswaptmp2 = DUK_BSWAP32(duk__bswaptmp2); \\\n\t\t(u)->ui[0] = duk__bswaptmp1; \\\n\t\t(u)->ui[1] = duk__bswaptmp2; \\\n\t} while (0)\n#elif defined(DUK_USE_DOUBLE_BE)\n#define DUK_DBLUNION_DOUBLE_HTON(u) do { } while (0)\n#else\n#error internal error, double endianness insane\n#endif\n\n/* Reverse operation is the same. */\n#define DUK_DBLUNION_DOUBLE_NTOH(u) DUK_DBLUNION_DOUBLE_HTON((u))\n\n/* Some sign bit helpers. */\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBLUNION_HAS_SIGNBIT(u) (((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x8000000000000000)) != 0)\n#define DUK_DBLUNION_GET_SIGNBIT(u) (((u)->ull[DUK_DBL_IDX_ULL0] >> 63U))\n#else\n#define DUK_DBLUNION_HAS_SIGNBIT(u) (((u)->ui[DUK_DBL_IDX_UI0] & 0x80000000UL) != 0)\n#define DUK_DBLUNION_GET_SIGNBIT(u) (((u)->ui[DUK_DBL_IDX_UI0] >> 31U))\n#endif\n\n#endif  /* DUK_DBLUNION_H_INCLUDED */\n/* #include duk_replacements.h */\n#if !defined(DUK_REPLACEMENTS_H_INCLUDED)\n#define DUK_REPLACEMENTS_H_INCLUDED\n\n#if !defined(DUK_SINGLE_FILE)\n#if defined(DUK_USE_COMPUTED_INFINITY)\nDUK_INTERNAL_DECL double duk_computed_infinity;\n#endif\n#if defined(DUK_USE_COMPUTED_NAN)\nDUK_INTERNAL_DECL double duk_computed_nan;\n#endif\n#endif  /* !DUK_SINGLE_FILE */\n\n#if defined(DUK_USE_REPL_FPCLASSIFY)\nDUK_INTERNAL_DECL int duk_repl_fpclassify(double x);\n#endif\n#if defined(DUK_USE_REPL_SIGNBIT)\nDUK_INTERNAL_DECL int duk_repl_signbit(double x);\n#endif\n#if defined(DUK_USE_REPL_ISFINITE)\nDUK_INTERNAL_DECL int duk_repl_isfinite(double x);\n#endif\n#if defined(DUK_USE_REPL_ISNAN)\nDUK_INTERNAL_DECL int duk_repl_isnan(double x);\n#endif\n#if defined(DUK_USE_REPL_ISINF)\nDUK_INTERNAL_DECL int duk_repl_isinf(double x);\n#endif\n\n#endif  /* DUK_REPLACEMENTS_H_INCLUDED */\n/* #include duk_jmpbuf.h */\n/*\n *  Wrapper for jmp_buf.\n *\n *  This is used because jmp_buf is an array type for backward compatibility.\n *  Wrapping jmp_buf in a struct makes pointer references, sizeof, etc,\n *  behave more intuitively.\n *\n *  http://en.wikipedia.org/wiki/Setjmp.h#Member_types\n */\n\n#if !defined(DUK_JMPBUF_H_INCLUDED)\n#define DUK_JMPBUF_H_INCLUDED\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\nstruct duk_jmpbuf {\n\tduk_small_int_t dummy;  /* unused */\n};\n#else\nstruct duk_jmpbuf {\n\tDUK_JMPBUF_TYPE jb;\n};\n#endif\n\n#endif  /* DUK_JMPBUF_H_INCLUDED */\n/* #include duk_exception.h */\n/*\n *  Exceptions for Duktape internal throws when C++ exceptions are used\n *  for long control transfers.\n */\n\n#if !defined(DUK_EXCEPTION_H_INCLUDED)\n#define DUK_EXCEPTION_H_INCLUDED\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n/* Internal exception used as a setjmp-longjmp replacement.  User code should\n * NEVER see or catch this exception, so it doesn't inherit from any base\n * class which should minimize the chance of user code accidentally catching\n * the exception.\n */\nclass duk_internal_exception {\n\t/* intentionally empty */\n};\n\n/* Fatal error, thrown as a specific C++ exception with C++ exceptions\n * enabled.  It is unsafe to continue; doing so may cause crashes or memory\n * leaks.  This is intended to be either uncaught, or caught by user code\n * aware of the \"unsafe to continue\" semantics.\n */\nclass duk_fatal_exception : public virtual std::runtime_error {\n public:\n\tduk_fatal_exception(const char *message) : std::runtime_error(message) {}\n};\n#endif\n\n#endif  /* DUK_EXCEPTION_H_INCLUDED */\n/* #include duk_forwdecl.h */\n/*\n *  Forward declarations for all Duktape structures.\n */\n\n#if !defined(DUK_FORWDECL_H_INCLUDED)\n#define DUK_FORWDECL_H_INCLUDED\n\n/*\n *  Forward declarations\n */\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\nclass duk_internal_exception;\n#else\nstruct duk_jmpbuf;\n#endif\n\n/* duk_tval intentionally skipped */\nstruct duk_heaphdr;\nstruct duk_heaphdr_string;\nstruct duk_harray;\nstruct duk_hstring;\nstruct duk_hstring_external;\nstruct duk_hobject;\nstruct duk_hcompfunc;\nstruct duk_hnatfunc;\nstruct duk_hboundfunc;\nstruct duk_hthread;\nstruct duk_hbufobj;\nstruct duk_hdecenv;\nstruct duk_hobjenv;\nstruct duk_hproxy;\nstruct duk_hbuffer;\nstruct duk_hbuffer_fixed;\nstruct duk_hbuffer_dynamic;\nstruct duk_hbuffer_external;\n\nstruct duk_propaccessor;\nunion duk_propvalue;\nstruct duk_propdesc;\n\nstruct duk_heap;\nstruct duk_breakpoint;\n\nstruct duk_activation;\nstruct duk_catcher;\nstruct duk_ljstate;\nstruct duk_strcache_entry;\nstruct duk_litcache_entry;\nstruct duk_strtab_entry;\n\n#if defined(DUK_USE_DEBUG)\nstruct duk_fixedbuffer;\n#endif\n\nstruct duk_bitdecoder_ctx;\nstruct duk_bitencoder_ctx;\nstruct duk_bufwriter_ctx;\n\nstruct duk_token;\nstruct duk_re_token;\nstruct duk_lexer_point;\nstruct duk_lexer_ctx;\nstruct duk_lexer_codepoint;\n\nstruct duk_compiler_instr;\nstruct duk_compiler_func;\nstruct duk_compiler_ctx;\n\nstruct duk_re_matcher_ctx;\nstruct duk_re_compiler_ctx;\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n/* no typedef */\n#else\ntypedef struct duk_jmpbuf duk_jmpbuf;\n#endif\n\n/* duk_tval intentionally skipped */\ntypedef struct duk_heaphdr duk_heaphdr;\ntypedef struct duk_heaphdr_string duk_heaphdr_string;\ntypedef struct duk_harray duk_harray;\ntypedef struct duk_hstring duk_hstring;\ntypedef struct duk_hstring_external duk_hstring_external;\ntypedef struct duk_hobject duk_hobject;\ntypedef struct duk_hcompfunc duk_hcompfunc;\ntypedef struct duk_hnatfunc duk_hnatfunc;\ntypedef struct duk_hboundfunc duk_hboundfunc;\ntypedef struct duk_hthread duk_hthread;\ntypedef struct duk_hbufobj duk_hbufobj;\ntypedef struct duk_hdecenv duk_hdecenv;\ntypedef struct duk_hobjenv duk_hobjenv;\ntypedef struct duk_hproxy duk_hproxy;\ntypedef struct duk_hbuffer duk_hbuffer;\ntypedef struct duk_hbuffer_fixed duk_hbuffer_fixed;\ntypedef struct duk_hbuffer_dynamic duk_hbuffer_dynamic;\ntypedef struct duk_hbuffer_external duk_hbuffer_external;\n\ntypedef struct duk_propaccessor duk_propaccessor;\ntypedef union duk_propvalue duk_propvalue;\ntypedef struct duk_propdesc duk_propdesc;\n\ntypedef struct duk_heap duk_heap;\ntypedef struct duk_breakpoint duk_breakpoint;\n\ntypedef struct duk_activation duk_activation;\ntypedef struct duk_catcher duk_catcher;\ntypedef struct duk_ljstate duk_ljstate;\ntypedef struct duk_strcache_entry duk_strcache_entry;\ntypedef struct duk_litcache_entry duk_litcache_entry;\ntypedef struct duk_strtab_entry duk_strtab_entry;\n\n#if defined(DUK_USE_DEBUG)\ntypedef struct duk_fixedbuffer duk_fixedbuffer;\n#endif\n\ntypedef struct duk_bitdecoder_ctx duk_bitdecoder_ctx;\ntypedef struct duk_bitencoder_ctx duk_bitencoder_ctx;\ntypedef struct duk_bufwriter_ctx duk_bufwriter_ctx;\n\ntypedef struct duk_token duk_token;\ntypedef struct duk_re_token duk_re_token;\ntypedef struct duk_lexer_point duk_lexer_point;\ntypedef struct duk_lexer_ctx duk_lexer_ctx;\ntypedef struct duk_lexer_codepoint duk_lexer_codepoint;\n\ntypedef struct duk_compiler_instr duk_compiler_instr;\ntypedef struct duk_compiler_func duk_compiler_func;\ntypedef struct duk_compiler_ctx duk_compiler_ctx;\n\ntypedef struct duk_re_matcher_ctx duk_re_matcher_ctx;\ntypedef struct duk_re_compiler_ctx duk_re_compiler_ctx;\n\n#endif  /* DUK_FORWDECL_H_INCLUDED */\n/* #include duk_tval.h */\n/*\n *  Tagged type definition (duk_tval) and accessor macros.\n *\n *  Access all fields through the accessor macros, as the representation\n *  is quite tricky.\n *\n *  There are two packed type alternatives: an 8-byte representation\n *  based on an IEEE double (preferred for compactness), and a 12-byte\n *  representation (portability).  The latter is needed also in e.g.\n *  64-bit environments (it usually pads to 16 bytes per value).\n *\n *  Selecting the tagged type format involves many trade-offs (memory\n *  use, size and performance of generated code, portability, etc).\n *\n *  NB: because macro arguments are often expressions, macros should\n *  avoid evaluating their argument more than once.\n */\n\n#if !defined(DUK_TVAL_H_INCLUDED)\n#define DUK_TVAL_H_INCLUDED\n\n/* sanity */\n#if !defined(DUK_USE_DOUBLE_LE) && !defined(DUK_USE_DOUBLE_ME) && !defined(DUK_USE_DOUBLE_BE)\n#error unsupported: cannot determine byte order variant\n#endif\n\n#if defined(DUK_USE_PACKED_TVAL)\n/* ======================================================================== */\n\n/*\n *  Packed 8-byte representation\n */\n\n/* use duk_double_union as duk_tval directly */\ntypedef union duk_double_union duk_tval;\ntypedef struct {\n\tduk_uint16_t a;\n\tduk_uint16_t b;\n\tduk_uint16_t c;\n\tduk_uint16_t d;\n} duk_tval_unused;\n\n/* tags */\n#define DUK_TAG_NORMALIZED_NAN    0x7ff8UL   /* the NaN variant we use */\n/* avoid tag 0xfff0, no risk of confusion with negative infinity */\n#define DUK_TAG_MIN               0xfff1UL\n#if defined(DUK_USE_FASTINT)\n#define DUK_TAG_FASTINT           0xfff1UL   /* embed: integer value */\n#endif\n#define DUK_TAG_UNUSED            0xfff2UL   /* marker; not actual tagged value */\n#define DUK_TAG_UNDEFINED         0xfff3UL   /* embed: nothing */\n#define DUK_TAG_NULL              0xfff4UL   /* embed: nothing */\n#define DUK_TAG_BOOLEAN           0xfff5UL   /* embed: 0 or 1 (false or true) */\n/* DUK_TAG_NUMBER would logically go here, but it has multiple 'tags' */\n#define DUK_TAG_POINTER           0xfff6UL   /* embed: void ptr */\n#define DUK_TAG_LIGHTFUNC         0xfff7UL   /* embed: func ptr */\n#define DUK_TAG_STRING            0xfff8UL   /* embed: duk_hstring ptr */\n#define DUK_TAG_OBJECT            0xfff9UL   /* embed: duk_hobject ptr */\n#define DUK_TAG_BUFFER            0xfffaUL   /* embed: duk_hbuffer ptr */\n#define DUK_TAG_MAX               0xfffaUL\n\n/* for convenience */\n#define DUK_XTAG_BOOLEAN_FALSE    0xfff50000UL\n#define DUK_XTAG_BOOLEAN_TRUE     0xfff50001UL\n\n#define DUK_TVAL_IS_VALID_TAG(tv) \\\n\t(DUK_TVAL_GET_TAG((tv)) - DUK_TAG_MIN <= DUK_TAG_MAX - DUK_TAG_MIN)\n\n/* DUK_TVAL_UNUSED initializer for duk_tval_unused, works for any endianness. */\n#define DUK_TVAL_UNUSED_INITIALIZER() \\\n\t{ DUK_TAG_UNUSED, DUK_TAG_UNUSED, DUK_TAG_UNUSED, DUK_TAG_UNUSED }\n\n/* two casts to avoid gcc warning: \"warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]\" */\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) (tag)) << 16) | (((duk_uint64_t) (duk_uint32_t) (h)) << 32); \\\n\t} while (0)\n#else\n#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) (tag)) << 48) | ((duk_uint64_t) (duk_uint32_t) (h)); \\\n\t} while (0)\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) (tag)) << 16; \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (h); \\\n\t} while (0)\n#endif  /* DUK_USE_64BIT_OPS */\n\n#if defined(DUK_USE_64BIT_OPS)\n/* Double casting for pointer to avoid gcc warning (cast from pointer to integer of different size) */\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_LIGHTFUNC) << 16) | \\\n\t\t                              ((duk_uint64_t) (flags)) | \\\n\t\t                              (((duk_uint64_t) (duk_uint32_t) (fp)) << 32); \\\n\t} while (0)\n#else\n#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_LIGHTFUNC) << 48) | \\\n\t\t                              (((duk_uint64_t) (flags)) << 32) | \\\n\t\t                              ((duk_uint64_t) (duk_uint32_t) (fp)); \\\n\t} while (0)\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = (((duk_uint32_t) DUK_TAG_LIGHTFUNC) << 16) | ((duk_uint32_t) (flags)); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (fp); \\\n\t} while (0)\n#endif  /* DUK_USE_64BIT_OPS */\n\n#if defined(DUK_USE_FASTINT)\n/* Note: masking is done for 'i' to deal with negative numbers correctly */\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_SET_I48(tv,i)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) DUK_TAG_FASTINT) << 16 | (((duk_uint32_t) ((i) >> 32)) & 0x0000ffffUL); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (i); \\\n\t} while (0)\n#define DUK__TVAL_SET_U32(tv,i)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) DUK_TAG_FASTINT) << 16; \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (i); \\\n\t} while (0)\n#else\n#define DUK__TVAL_SET_I48(tv,i)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (((duk_uint64_t) (i)) & DUK_U64_CONSTANT(0x0000ffffffffffff)); \\\n\t} while (0)\n#define DUK__TVAL_SET_U32(tv,i)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (duk_uint64_t) (i); \\\n\t} while (0)\n#endif\n\n/* This needs to go through a cast because sign extension is needed. */\n#define DUK__TVAL_SET_I32(tv,i)  do { \\\n\t\tduk_int64_t duk__tmp = (duk_int64_t) (i); \\\n\t\tDUK_TVAL_SET_I48((tv), duk__tmp); \\\n\t} while (0)\n\n/* XXX: Clumsy sign extend and masking of 16 topmost bits. */\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_GET_FASTINT(tv)      (((duk_int64_t) ((((duk_uint64_t) (tv)->ui[DUK_DBL_IDX_UI0]) << 32) | ((duk_uint64_t) (tv)->ui[DUK_DBL_IDX_UI1]))) << 16 >> 16)\n#else\n#define DUK__TVAL_GET_FASTINT(tv)      ((((duk_int64_t) (tv)->ull[DUK_DBL_IDX_ULL0]) << 16) >> 16)\n#endif\n#define DUK__TVAL_GET_FASTINT_U32(tv)  ((tv)->ui[DUK_DBL_IDX_UI1])\n#define DUK__TVAL_GET_FASTINT_I32(tv)  ((duk_int32_t) (tv)->ui[DUK_DBL_IDX_UI1])\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_UNDEFINED(tv)  do { \\\n\t\t(tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNDEFINED; \\\n\t} while (0)\n#define DUK_TVAL_SET_UNUSED(tv)  do { \\\n\t\t(tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNUSED; \\\n\t} while (0)\n#define DUK_TVAL_SET_NULL(tv)  do { \\\n\t\t(tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_NULL; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN(tv,val)         DUK_DBLUNION_SET_HIGH32((tv), (((duk_uint32_t) DUK_TAG_BOOLEAN) << 16) | ((duk_uint32_t) (val)))\n\n#define DUK_TVAL_SET_NAN(tv)                 DUK_DBLUNION_SET_NAN_FULL((tv))\n\n/* Assumes that caller has normalized NaNs, otherwise trouble ahead. */\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_DOUBLE(tv,d)  do { \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (d); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); \\\n\t\tDUK_DBLUNION_SET_DOUBLE((tv), duk__dblval); \\\n\t} while (0)\n#define DUK_TVAL_SET_I48(tv,i)               DUK__TVAL_SET_I48((tv), (i))\n#define DUK_TVAL_SET_I32(tv,i)               DUK__TVAL_SET_I32((tv), (i))\n#define DUK_TVAL_SET_U32(tv,i)               DUK__TVAL_SET_U32((tv), (i))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d)  duk_tval_set_number_chkfast_fast((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d)  duk_tval_set_number_chkfast_slow((tv), (d))\n#define DUK_TVAL_SET_NUMBER(tv,d)            DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#else  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_DOUBLE(tv,d)  do { \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (d); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); \\\n\t\tDUK_DBLUNION_SET_DOUBLE((tv), duk__dblval); \\\n\t} while (0)\n#define DUK_TVAL_SET_I48(tv,i)               DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i))  /* XXX: fast int-to-double */\n#define DUK_TVAL_SET_I32(tv,i)               DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i))\n#define DUK_TVAL_SET_U32(tv,i)               DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d)    DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d)    DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_SET_NUMBER(tv,d)            DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { } while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { } while (0)\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_FASTINT(tv,i)           DUK_TVAL_SET_I48((tv), (i))  /* alias */\n\n#define DUK_TVAL_SET_LIGHTFUNC(tv,fp,flags)  DUK__TVAL_SET_LIGHTFUNC((tv), (fp), (flags))\n#define DUK_TVAL_SET_STRING(tv,h)            DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_STRING)\n#define DUK_TVAL_SET_OBJECT(tv,h)            DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_OBJECT)\n#define DUK_TVAL_SET_BUFFER(tv,h)            DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_BUFFER)\n#define DUK_TVAL_SET_POINTER(tv,p)           DUK__TVAL_SET_TAGGEDPOINTER((tv), (p), DUK_TAG_POINTER)\n\n#define DUK_TVAL_SET_TVAL(tv,x)              do { *(tv) = *(x); } while (0)\n\n/* getters */\n#define DUK_TVAL_GET_BOOLEAN(tv)             ((duk_small_uint_t) (tv)->us[DUK_DBL_IDX_US1])\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_GET_DOUBLE(tv)              ((tv)->d)\n#define DUK_TVAL_GET_FASTINT(tv)             DUK__TVAL_GET_FASTINT((tv))\n#define DUK_TVAL_GET_FASTINT_U32(tv)         DUK__TVAL_GET_FASTINT_U32((tv))\n#define DUK_TVAL_GET_FASTINT_I32(tv)         DUK__TVAL_GET_FASTINT_I32((tv))\n#define DUK_TVAL_GET_NUMBER(tv)              duk_tval_get_number_packed((tv))\n#else\n#define DUK_TVAL_GET_NUMBER(tv)              ((tv)->d)\n#define DUK_TVAL_GET_DOUBLE(tv)              ((tv)->d)\n#endif\n#define DUK_TVAL_GET_LIGHTFUNC(tv,out_fp,out_flags)  do { \\\n\t\t(out_flags) = (tv)->ui[DUK_DBL_IDX_UI0] & 0xffffUL; \\\n\t\t(out_fp) = (duk_c_function) (tv)->ui[DUK_DBL_IDX_UI1]; \\\n\t} while (0)\n#define DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv)   ((duk_c_function) ((tv)->ui[DUK_DBL_IDX_UI1]))\n#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv)     (((duk_small_uint_t) (tv)->ui[DUK_DBL_IDX_UI0]) & 0xffffUL)\n#define DUK_TVAL_GET_STRING(tv)              ((duk_hstring *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_OBJECT(tv)              ((duk_hobject *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_BUFFER(tv)              ((duk_hbuffer *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_POINTER(tv)             ((void *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_HEAPHDR(tv)             ((duk_heaphdr *) (tv)->vp[DUK_DBL_IDX_VP1])\n\n/* decoding */\n#define DUK_TVAL_GET_TAG(tv)                 ((duk_small_uint_t) (tv)->us[DUK_DBL_IDX_US0])\n\n#define DUK_TVAL_IS_UNDEFINED(tv)            (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_UNDEFINED)\n#define DUK_TVAL_IS_UNUSED(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_UNUSED)\n#define DUK_TVAL_IS_NULL(tv)                 (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_NULL)\n#define DUK_TVAL_IS_BOOLEAN(tv)              (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_BOOLEAN)\n#define DUK_TVAL_IS_BOOLEAN_TRUE(tv)         ((tv)->ui[DUK_DBL_IDX_UI0] == DUK_XTAG_BOOLEAN_TRUE)\n#define DUK_TVAL_IS_BOOLEAN_FALSE(tv)        ((tv)->ui[DUK_DBL_IDX_UI0] == DUK_XTAG_BOOLEAN_FALSE)\n#define DUK_TVAL_IS_LIGHTFUNC(tv)            (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_LIGHTFUNC)\n#define DUK_TVAL_IS_STRING(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_STRING)\n#define DUK_TVAL_IS_OBJECT(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_OBJECT)\n#define DUK_TVAL_IS_BUFFER(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_BUFFER)\n#define DUK_TVAL_IS_POINTER(tv)              (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_POINTER)\n#if defined(DUK_USE_FASTINT)\n/* 0xfff0 is -Infinity */\n#define DUK_TVAL_IS_DOUBLE(tv)               (DUK_TVAL_GET_TAG((tv)) <= 0xfff0UL)\n#define DUK_TVAL_IS_FASTINT(tv)              (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_FASTINT)\n#define DUK_TVAL_IS_NUMBER(tv)               (DUK_TVAL_GET_TAG((tv)) <= 0xfff1UL)\n#else\n#define DUK_TVAL_IS_NUMBER(tv)               (DUK_TVAL_GET_TAG((tv)) <= 0xfff0UL)\n#define DUK_TVAL_IS_DOUBLE(tv)               DUK_TVAL_IS_NUMBER((tv))\n#endif\n\n/* This is performance critical because it appears in every DECREF. */\n#define DUK_TVAL_IS_HEAP_ALLOCATED(tv)       (DUK_TVAL_GET_TAG((tv)) >= DUK_TAG_STRING)\n\n#if defined(DUK_USE_FASTINT)\nDUK_INTERNAL_DECL duk_double_t duk_tval_get_number_packed(duk_tval *tv);\n#endif\n\n#else  /* DUK_USE_PACKED_TVAL */\n/* ======================================================================== */\n\n/*\n *  Portable 12-byte representation\n */\n\n/* Note: not initializing all bytes is normally not an issue: Duktape won't\n * read or use the uninitialized bytes so valgrind won't issue warnings.\n * In some special cases a harmless valgrind warning may be issued though.\n * For example, the DumpHeap debugger command writes out a compiled function's\n * 'data' area as is, including any uninitialized bytes, which causes a\n * valgrind warning.\n */\n\ntypedef struct duk_tval_struct duk_tval;\n\nstruct duk_tval_struct {\n\tduk_small_uint_t t;\n\tduk_small_uint_t v_extra;\n\tunion {\n\t\tduk_double_t d;\n\t\tduk_small_int_t i;\n#if defined(DUK_USE_FASTINT)\n\t\tduk_int64_t fi;  /* if present, forces 16-byte duk_tval */\n#endif\n\t\tvoid *voidptr;\n\t\tduk_hstring *hstring;\n\t\tduk_hobject *hobject;\n\t\tduk_hcompfunc *hcompfunc;\n\t\tduk_hnatfunc *hnatfunc;\n\t\tduk_hthread *hthread;\n\t\tduk_hbuffer *hbuffer;\n\t\tduk_heaphdr *heaphdr;\n\t\tduk_c_function lightfunc;\n\t} v;\n};\n\ntypedef struct {\n\tduk_small_uint_t t;\n\tduk_small_uint_t v_extra;\n\t/* The rest of the fields don't matter except for debug dumps and such\n\t * for which a partial initializer may trigger out-ot-bounds memory\n\t * reads.  Include a double field which is usually as large or larger\n\t * than pointers (not always however).\n\t */\n\tduk_double_t d;\n} duk_tval_unused;\n\n#define DUK_TVAL_UNUSED_INITIALIZER() \\\n\t{ DUK_TAG_UNUSED, 0, 0.0 }\n\n#define DUK_TAG_MIN                   0\n#define DUK_TAG_NUMBER                0  /* DUK_TAG_NUMBER only defined for non-packed duk_tval */\n#if defined(DUK_USE_FASTINT)\n#define DUK_TAG_FASTINT               1\n#endif\n#define DUK_TAG_UNDEFINED             2\n#define DUK_TAG_NULL                  3\n#define DUK_TAG_BOOLEAN               4\n#define DUK_TAG_POINTER               5\n#define DUK_TAG_LIGHTFUNC             6\n#define DUK_TAG_UNUSED                7  /* marker; not actual tagged type */\n#define DUK_TAG_STRING                8  /* first heap allocated, match bit boundary */\n#define DUK_TAG_OBJECT                9\n#define DUK_TAG_BUFFER                10\n#define DUK_TAG_MAX                   10\n\n#define DUK_TVAL_IS_VALID_TAG(tv) \\\n\t(DUK_TVAL_GET_TAG((tv)) - DUK_TAG_MIN <= DUK_TAG_MAX - DUK_TAG_MIN)\n\n/* DUK_TAG_NUMBER is intentionally first, as it is the default clause in code\n * to support the 8-byte representation.  Further, it is a non-heap-allocated\n * type so it should come before DUK_TAG_STRING.  Finally, it should not break\n * the tag value ranges covered by case-clauses in a switch-case.\n */\n\n/* setters */\n#define DUK_TVAL_SET_UNDEFINED(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_UNDEFINED; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNUSED(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_UNUSED; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NULL(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NULL; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_BOOLEAN; \\\n\t\tduk__tv->v.i = (duk_small_int_t) (val); \\\n\t} while (0)\n\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_DOUBLE(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (val); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); /* nop for unpacked duk_tval */ \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NUMBER; \\\n\t\tduk__tv->v.d = duk__dblval; \\\n\t} while (0)\n#define DUK_TVAL_SET_I48(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_FASTINT; \\\n\t\tduk__tv->v.fi = (val); \\\n\t} while (0)\n#define DUK_TVAL_SET_U32(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_FASTINT; \\\n\t\tduk__tv->v.fi = (duk_int64_t) (val); \\\n\t} while (0)\n#define DUK_TVAL_SET_I32(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_FASTINT; \\\n\t\tduk__tv->v.fi = (duk_int64_t) (val); \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) \\\n\tduk_tval_set_number_chkfast_fast((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) \\\n\tduk_tval_set_number_chkfast_slow((tv), (d))\n#define DUK_TVAL_SET_NUMBER(tv,val) \\\n\tDUK_TVAL_SET_DOUBLE((tv), (val))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#else  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_DOUBLE(tv,d) \\\n\tDUK_TVAL_SET_NUMBER((tv), (d))\n#define DUK_TVAL_SET_I48(tv,val) \\\n\tDUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val))  /* XXX: fast int-to-double */\n#define DUK_TVAL_SET_U32(tv,val) \\\n\tDUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val))\n#define DUK_TVAL_SET_I32(tv,val) \\\n\tDUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val))\n#define DUK_TVAL_SET_NUMBER(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (val); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); /* nop for unpacked duk_tval */ \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NUMBER; \\\n\t\tduk__tv->v.d = duk__dblval; \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) \\\n\tDUK_TVAL_SET_NUMBER((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) \\\n\tDUK_TVAL_SET_NUMBER((tv), (d))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { } while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { } while (0)\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_FASTINT(tv,i) \\\n\tDUK_TVAL_SET_I48((tv), (i))  /* alias */\n\n#define DUK_TVAL_SET_POINTER(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_POINTER; \\\n\t\tduk__tv->v.voidptr = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_LIGHTFUNC; \\\n\t\tduk__tv->v_extra = (flags); \\\n\t\tduk__tv->v.lightfunc = (duk_c_function) (fp); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_STRING(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_STRING; \\\n\t\tduk__tv->v.hstring = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_OBJECT(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_OBJECT; \\\n\t\tduk__tv->v.hobject = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BUFFER(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_BUFFER; \\\n\t\tduk__tv->v.hbuffer = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NAN(tv)  do { \\\n\t\t/* in non-packed representation we don't care about which NaN is used */ \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NUMBER; \\\n\t\tduk__tv->v.d = DUK_DOUBLE_NAN; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_TVAL(tv,x)            do { *(tv) = *(x); } while (0)\n\n/* getters */\n#define DUK_TVAL_GET_BOOLEAN(tv)           ((duk_small_uint_t) (tv)->v.i)\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_GET_DOUBLE(tv)            ((tv)->v.d)\n#define DUK_TVAL_GET_FASTINT(tv)           ((tv)->v.fi)\n#define DUK_TVAL_GET_FASTINT_U32(tv)       ((duk_uint32_t) ((tv)->v.fi))\n#define DUK_TVAL_GET_FASTINT_I32(tv)       ((duk_int32_t) ((tv)->v.fi))\n#if 0\n#define DUK_TVAL_GET_NUMBER(tv)            (DUK_TVAL_IS_FASTINT((tv)) ? \\\n                                               (duk_double_t) DUK_TVAL_GET_FASTINT((tv)) : \\\n                                               DUK_TVAL_GET_DOUBLE((tv)))\n#define DUK_TVAL_GET_NUMBER(tv)            duk_tval_get_number_unpacked((tv))\n#else\n/* This seems reasonable overall. */\n#define DUK_TVAL_GET_NUMBER(tv)            (DUK_TVAL_IS_FASTINT((tv)) ? \\\n                                               duk_tval_get_number_unpacked_fastint((tv)) : \\\n                                               DUK_TVAL_GET_DOUBLE((tv)))\n#endif\n#else\n#define DUK_TVAL_GET_NUMBER(tv)            ((tv)->v.d)\n#define DUK_TVAL_GET_DOUBLE(tv)            ((tv)->v.d)\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_GET_POINTER(tv)           ((tv)->v.voidptr)\n#define DUK_TVAL_GET_LIGHTFUNC(tv,out_fp,out_flags)  do { \\\n\t\t(out_flags) = (duk_uint32_t) (tv)->v_extra; \\\n\t\t(out_fp) = (tv)->v.lightfunc; \\\n\t} while (0)\n#define DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv) ((tv)->v.lightfunc)\n#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv)   ((duk_small_uint_t) ((tv)->v_extra))\n#define DUK_TVAL_GET_STRING(tv)            ((tv)->v.hstring)\n#define DUK_TVAL_GET_OBJECT(tv)            ((tv)->v.hobject)\n#define DUK_TVAL_GET_BUFFER(tv)            ((tv)->v.hbuffer)\n#define DUK_TVAL_GET_HEAPHDR(tv)           ((tv)->v.heaphdr)\n\n/* decoding */\n#define DUK_TVAL_GET_TAG(tv)               ((tv)->t)\n#define DUK_TVAL_IS_UNDEFINED(tv)          ((tv)->t == DUK_TAG_UNDEFINED)\n#define DUK_TVAL_IS_UNUSED(tv)             ((tv)->t == DUK_TAG_UNUSED)\n#define DUK_TVAL_IS_NULL(tv)               ((tv)->t == DUK_TAG_NULL)\n#define DUK_TVAL_IS_BOOLEAN(tv)            ((tv)->t == DUK_TAG_BOOLEAN)\n#define DUK_TVAL_IS_BOOLEAN_TRUE(tv)       (((tv)->t == DUK_TAG_BOOLEAN) && ((tv)->v.i != 0))\n#define DUK_TVAL_IS_BOOLEAN_FALSE(tv)      (((tv)->t == DUK_TAG_BOOLEAN) && ((tv)->v.i == 0))\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_IS_DOUBLE(tv)             ((tv)->t == DUK_TAG_NUMBER)\n#define DUK_TVAL_IS_FASTINT(tv)            ((tv)->t == DUK_TAG_FASTINT)\n#define DUK_TVAL_IS_NUMBER(tv)             ((tv)->t == DUK_TAG_NUMBER || \\\n                                            (tv)->t == DUK_TAG_FASTINT)\n#else\n#define DUK_TVAL_IS_NUMBER(tv)             ((tv)->t == DUK_TAG_NUMBER)\n#define DUK_TVAL_IS_DOUBLE(tv)             DUK_TVAL_IS_NUMBER((tv))\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_IS_POINTER(tv)            ((tv)->t == DUK_TAG_POINTER)\n#define DUK_TVAL_IS_LIGHTFUNC(tv)          ((tv)->t == DUK_TAG_LIGHTFUNC)\n#define DUK_TVAL_IS_STRING(tv)             ((tv)->t == DUK_TAG_STRING)\n#define DUK_TVAL_IS_OBJECT(tv)             ((tv)->t == DUK_TAG_OBJECT)\n#define DUK_TVAL_IS_BUFFER(tv)             ((tv)->t == DUK_TAG_BUFFER)\n\n/* This is performance critical because it's needed for every DECREF.\n * Take advantage of the fact that the first heap allocated tag is 8,\n * so that bit 3 is set for all heap allocated tags (and never set for\n * non-heap-allocated tags).\n */\n#if 0\n#define DUK_TVAL_IS_HEAP_ALLOCATED(tv)     ((tv)->t >= DUK_TAG_STRING)\n#endif\n#define DUK_TVAL_IS_HEAP_ALLOCATED(tv)     ((tv)->t & 0x08)\n\n#if defined(DUK_USE_FASTINT)\n#if 0\nDUK_INTERNAL_DECL duk_double_t duk_tval_get_number_unpacked(duk_tval *tv);\n#endif\nDUK_INTERNAL_DECL duk_double_t duk_tval_get_number_unpacked_fastint(duk_tval *tv);\n#endif\n\n#endif  /* DUK_USE_PACKED_TVAL */\n\n/*\n *  Convenience (independent of representation)\n */\n\n#define DUK_TVAL_SET_BOOLEAN_TRUE(tv)        DUK_TVAL_SET_BOOLEAN((tv), 1)\n#define DUK_TVAL_SET_BOOLEAN_FALSE(tv)       DUK_TVAL_SET_BOOLEAN((tv), 0)\n\n#define DUK_TVAL_STRING_IS_SYMBOL(tv) \\\n\tDUK_HSTRING_HAS_SYMBOL(DUK_TVAL_GET_STRING((tv)))\n\n/* Lightfunc flags packing and unpacking. */\n/* Sign extend: 0x0000##00 -> 0x##000000 -> sign extend to 0xssssss##.\n * Avoid signed shifts due to portability limitations.\n */\n#define DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags) \\\n\t((duk_int32_t) (duk_int8_t) (((duk_uint16_t) (lf_flags)) >> 8))\n#define DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags) \\\n\t(((lf_flags) >> 4) & 0x0fU)\n#define DUK_LFUNC_FLAGS_GET_NARGS(lf_flags) \\\n\t((lf_flags) & 0x0fU)\n#define DUK_LFUNC_FLAGS_PACK(magic,length,nargs) \\\n\t((((duk_small_uint_t) (magic)) & 0xffU) << 8) | ((length) << 4) | (nargs)\n\n#define DUK_LFUNC_NARGS_VARARGS             0x0f   /* varargs marker */\n#define DUK_LFUNC_NARGS_MIN                 0x00\n#define DUK_LFUNC_NARGS_MAX                 0x0e   /* max, excl. varargs marker */\n#define DUK_LFUNC_LENGTH_MIN                0x00\n#define DUK_LFUNC_LENGTH_MAX                0x0f\n#define DUK_LFUNC_MAGIC_MIN                 (-0x80)\n#define DUK_LFUNC_MAGIC_MAX                 0x7f\n\n/* fastint constants etc */\n#if defined(DUK_USE_FASTINT)\n#define DUK_FASTINT_MIN           (DUK_I64_CONSTANT(-0x800000000000))\n#define DUK_FASTINT_MAX           (DUK_I64_CONSTANT(0x7fffffffffff))\n#define DUK_FASTINT_BITS          48\n\nDUK_INTERNAL_DECL void duk_tval_set_number_chkfast_fast(duk_tval *tv, duk_double_t x);\nDUK_INTERNAL_DECL void duk_tval_set_number_chkfast_slow(duk_tval *tv, duk_double_t x);\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_tval_assert_valid(duk_tval *tv);\n#define DUK_TVAL_ASSERT_VALID(tv)  do { duk_tval_assert_valid((tv)); } while (0)\n#else\n#define DUK_TVAL_ASSERT_VALID(tv)  do {} while (0)\n#endif\n\n#endif  /* DUK_TVAL_H_INCLUDED */\n/* #include duk_builtins.h */\n/*\n *  Automatically generated by genbuiltins.py, do not edit!\n */\n\n#if !defined(DUK_BUILTINS_H_INCLUDED)\n#define DUK_BUILTINS_H_INCLUDED\n\n#if defined(DUK_USE_ROM_STRINGS)\n#error ROM support not enabled, rerun configure.py with --rom-support\n#else  /* DUK_USE_ROM_STRINGS */\n#define DUK_STRIDX_UC_UNDEFINED                                       0                              /* 'Undefined' */\n#define DUK_HEAP_STRING_UC_UNDEFINED(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_UNDEFINED)\n#define DUK_HTHREAD_STRING_UC_UNDEFINED(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_UNDEFINED)\n#define DUK_STRIDX_UC_NULL                                            1                              /* 'Null' */\n#define DUK_HEAP_STRING_UC_NULL(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_NULL)\n#define DUK_HTHREAD_STRING_UC_NULL(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_NULL)\n#define DUK_STRIDX_UC_SYMBOL                                          2                              /* 'Symbol' */\n#define DUK_HEAP_STRING_UC_SYMBOL(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_SYMBOL)\n#define DUK_HTHREAD_STRING_UC_SYMBOL(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_SYMBOL)\n#define DUK_STRIDX_UC_ARGUMENTS                                       3                              /* 'Arguments' */\n#define DUK_HEAP_STRING_UC_ARGUMENTS(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_ARGUMENTS)\n#define DUK_HTHREAD_STRING_UC_ARGUMENTS(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_ARGUMENTS)\n#define DUK_STRIDX_UC_OBJECT                                          4                              /* 'Object' */\n#define DUK_HEAP_STRING_UC_OBJECT(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_OBJECT)\n#define DUK_HTHREAD_STRING_UC_OBJECT(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_OBJECT)\n#define DUK_STRIDX_UC_FUNCTION                                        5                              /* 'Function' */\n#define DUK_HEAP_STRING_UC_FUNCTION(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_FUNCTION)\n#define DUK_HTHREAD_STRING_UC_FUNCTION(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_FUNCTION)\n#define DUK_STRIDX_ARRAY                                              6                              /* 'Array' */\n#define DUK_HEAP_STRING_ARRAY(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ARRAY)\n#define DUK_HTHREAD_STRING_ARRAY(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ARRAY)\n#define DUK_STRIDX_UC_STRING                                          7                              /* 'String' */\n#define DUK_HEAP_STRING_UC_STRING(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_STRING)\n#define DUK_HTHREAD_STRING_UC_STRING(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_STRING)\n#define DUK_STRIDX_UC_BOOLEAN                                         8                              /* 'Boolean' */\n#define DUK_HEAP_STRING_UC_BOOLEAN(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_BOOLEAN)\n#define DUK_HTHREAD_STRING_UC_BOOLEAN(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_BOOLEAN)\n#define DUK_STRIDX_UC_NUMBER                                          9                              /* 'Number' */\n#define DUK_HEAP_STRING_UC_NUMBER(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_NUMBER)\n#define DUK_HTHREAD_STRING_UC_NUMBER(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_NUMBER)\n#define DUK_STRIDX_DATE                                               10                             /* 'Date' */\n#define DUK_HEAP_STRING_DATE(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DATE)\n#define DUK_HTHREAD_STRING_DATE(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DATE)\n#define DUK_STRIDX_REG_EXP                                            11                             /* 'RegExp' */\n#define DUK_HEAP_STRING_REG_EXP(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_REG_EXP)\n#define DUK_HTHREAD_STRING_REG_EXP(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_REG_EXP)\n#define DUK_STRIDX_UC_ERROR                                           12                             /* 'Error' */\n#define DUK_HEAP_STRING_UC_ERROR(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_ERROR)\n#define DUK_HTHREAD_STRING_UC_ERROR(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_ERROR)\n#define DUK_STRIDX_MATH                                               13                             /* 'Math' */\n#define DUK_HEAP_STRING_MATH(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MATH)\n#define DUK_HTHREAD_STRING_MATH(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MATH)\n#define DUK_STRIDX_JSON                                               14                             /* 'JSON' */\n#define DUK_HEAP_STRING_JSON(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON)\n#define DUK_HTHREAD_STRING_JSON(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON)\n#define DUK_STRIDX_EMPTY_STRING                                       15                             /* '' */\n#define DUK_HEAP_STRING_EMPTY_STRING(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EMPTY_STRING)\n#define DUK_HTHREAD_STRING_EMPTY_STRING(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EMPTY_STRING)\n#define DUK_STRIDX_ARRAY_BUFFER                                       16                             /* 'ArrayBuffer' */\n#define DUK_HEAP_STRING_ARRAY_BUFFER(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ARRAY_BUFFER)\n#define DUK_HTHREAD_STRING_ARRAY_BUFFER(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ARRAY_BUFFER)\n#define DUK_STRIDX_DATA_VIEW                                          17                             /* 'DataView' */\n#define DUK_HEAP_STRING_DATA_VIEW(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DATA_VIEW)\n#define DUK_HTHREAD_STRING_DATA_VIEW(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DATA_VIEW)\n#define DUK_STRIDX_INT8_ARRAY                                         18                             /* 'Int8Array' */\n#define DUK_HEAP_STRING_INT8_ARRAY(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT8_ARRAY)\n#define DUK_HTHREAD_STRING_INT8_ARRAY(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT8_ARRAY)\n#define DUK_STRIDX_UINT8_ARRAY                                        19                             /* 'Uint8Array' */\n#define DUK_HEAP_STRING_UINT8_ARRAY(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT8_ARRAY)\n#define DUK_HTHREAD_STRING_UINT8_ARRAY(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT8_ARRAY)\n#define DUK_STRIDX_UINT8_CLAMPED_ARRAY                                20                             /* 'Uint8ClampedArray' */\n#define DUK_HEAP_STRING_UINT8_CLAMPED_ARRAY(heap)                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT8_CLAMPED_ARRAY)\n#define DUK_HTHREAD_STRING_UINT8_CLAMPED_ARRAY(thr)                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT8_CLAMPED_ARRAY)\n#define DUK_STRIDX_INT16_ARRAY                                        21                             /* 'Int16Array' */\n#define DUK_HEAP_STRING_INT16_ARRAY(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT16_ARRAY)\n#define DUK_HTHREAD_STRING_INT16_ARRAY(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT16_ARRAY)\n#define DUK_STRIDX_UINT16_ARRAY                                       22                             /* 'Uint16Array' */\n#define DUK_HEAP_STRING_UINT16_ARRAY(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT16_ARRAY)\n#define DUK_HTHREAD_STRING_UINT16_ARRAY(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT16_ARRAY)\n#define DUK_STRIDX_INT32_ARRAY                                        23                             /* 'Int32Array' */\n#define DUK_HEAP_STRING_INT32_ARRAY(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT32_ARRAY)\n#define DUK_HTHREAD_STRING_INT32_ARRAY(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT32_ARRAY)\n#define DUK_STRIDX_UINT32_ARRAY                                       24                             /* 'Uint32Array' */\n#define DUK_HEAP_STRING_UINT32_ARRAY(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT32_ARRAY)\n#define DUK_HTHREAD_STRING_UINT32_ARRAY(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT32_ARRAY)\n#define DUK_STRIDX_FLOAT32_ARRAY                                      25                             /* 'Float32Array' */\n#define DUK_HEAP_STRING_FLOAT32_ARRAY(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FLOAT32_ARRAY)\n#define DUK_HTHREAD_STRING_FLOAT32_ARRAY(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FLOAT32_ARRAY)\n#define DUK_STRIDX_FLOAT64_ARRAY                                      26                             /* 'Float64Array' */\n#define DUK_HEAP_STRING_FLOAT64_ARRAY(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FLOAT64_ARRAY)\n#define DUK_HTHREAD_STRING_FLOAT64_ARRAY(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FLOAT64_ARRAY)\n#define DUK_STRIDX_GLOBAL                                             27                             /* 'global' */\n#define DUK_HEAP_STRING_GLOBAL(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_GLOBAL)\n#define DUK_HTHREAD_STRING_GLOBAL(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_GLOBAL)\n#define DUK_STRIDX_OBJ_ENV                                            28                             /* 'ObjEnv' */\n#define DUK_HEAP_STRING_OBJ_ENV(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_OBJ_ENV)\n#define DUK_HTHREAD_STRING_OBJ_ENV(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_OBJ_ENV)\n#define DUK_STRIDX_DEC_ENV                                            29                             /* 'DecEnv' */\n#define DUK_HEAP_STRING_DEC_ENV(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEC_ENV)\n#define DUK_HTHREAD_STRING_DEC_ENV(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEC_ENV)\n#define DUK_STRIDX_UC_BUFFER                                          30                             /* 'Buffer' */\n#define DUK_HEAP_STRING_UC_BUFFER(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_BUFFER)\n#define DUK_HTHREAD_STRING_UC_BUFFER(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_BUFFER)\n#define DUK_STRIDX_UC_POINTER                                         31                             /* 'Pointer' */\n#define DUK_HEAP_STRING_UC_POINTER(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_POINTER)\n#define DUK_HTHREAD_STRING_UC_POINTER(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_POINTER)\n#define DUK_STRIDX_UC_THREAD                                          32                             /* 'Thread' */\n#define DUK_HEAP_STRING_UC_THREAD(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_THREAD)\n#define DUK_HTHREAD_STRING_UC_THREAD(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_THREAD)\n#define DUK_STRIDX_EVAL                                               33                             /* 'eval' */\n#define DUK_HEAP_STRING_EVAL(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EVAL)\n#define DUK_HTHREAD_STRING_EVAL(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EVAL)\n#define DUK_STRIDX_VALUE                                              34                             /* 'value' */\n#define DUK_HEAP_STRING_VALUE(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VALUE)\n#define DUK_HTHREAD_STRING_VALUE(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VALUE)\n#define DUK_STRIDX_WRITABLE                                           35                             /* 'writable' */\n#define DUK_HEAP_STRING_WRITABLE(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WRITABLE)\n#define DUK_HTHREAD_STRING_WRITABLE(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WRITABLE)\n#define DUK_STRIDX_CONFIGURABLE                                       36                             /* 'configurable' */\n#define DUK_HEAP_STRING_CONFIGURABLE(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONFIGURABLE)\n#define DUK_HTHREAD_STRING_CONFIGURABLE(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONFIGURABLE)\n#define DUK_STRIDX_ENUMERABLE                                         37                             /* 'enumerable' */\n#define DUK_HEAP_STRING_ENUMERABLE(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENUMERABLE)\n#define DUK_HTHREAD_STRING_ENUMERABLE(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENUMERABLE)\n#define DUK_STRIDX_JOIN                                               38                             /* 'join' */\n#define DUK_HEAP_STRING_JOIN(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JOIN)\n#define DUK_HTHREAD_STRING_JOIN(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JOIN)\n#define DUK_STRIDX_TO_LOCALE_STRING                                   39                             /* 'toLocaleString' */\n#define DUK_HEAP_STRING_TO_LOCALE_STRING(heap)                        DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_LOCALE_STRING)\n#define DUK_HTHREAD_STRING_TO_LOCALE_STRING(thr)                      DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_LOCALE_STRING)\n#define DUK_STRIDX_VALUE_OF                                           40                             /* 'valueOf' */\n#define DUK_HEAP_STRING_VALUE_OF(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VALUE_OF)\n#define DUK_HTHREAD_STRING_VALUE_OF(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VALUE_OF)\n#define DUK_STRIDX_TO_UTC_STRING                                      41                             /* 'toUTCString' */\n#define DUK_HEAP_STRING_TO_UTC_STRING(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_UTC_STRING)\n#define DUK_HTHREAD_STRING_TO_UTC_STRING(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_UTC_STRING)\n#define DUK_STRIDX_TO_ISO_STRING                                      42                             /* 'toISOString' */\n#define DUK_HEAP_STRING_TO_ISO_STRING(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_ISO_STRING)\n#define DUK_HTHREAD_STRING_TO_ISO_STRING(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_ISO_STRING)\n#define DUK_STRIDX_TO_GMT_STRING                                      43                             /* 'toGMTString' */\n#define DUK_HEAP_STRING_TO_GMT_STRING(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_GMT_STRING)\n#define DUK_HTHREAD_STRING_TO_GMT_STRING(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_GMT_STRING)\n#define DUK_STRIDX_SOURCE                                             44                             /* 'source' */\n#define DUK_HEAP_STRING_SOURCE(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SOURCE)\n#define DUK_HTHREAD_STRING_SOURCE(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SOURCE)\n#define DUK_STRIDX_IGNORE_CASE                                        45                             /* 'ignoreCase' */\n#define DUK_HEAP_STRING_IGNORE_CASE(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IGNORE_CASE)\n#define DUK_HTHREAD_STRING_IGNORE_CASE(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IGNORE_CASE)\n#define DUK_STRIDX_MULTILINE                                          46                             /* 'multiline' */\n#define DUK_HEAP_STRING_MULTILINE(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MULTILINE)\n#define DUK_HTHREAD_STRING_MULTILINE(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MULTILINE)\n#define DUK_STRIDX_LAST_INDEX                                         47                             /* 'lastIndex' */\n#define DUK_HEAP_STRING_LAST_INDEX(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LAST_INDEX)\n#define DUK_HTHREAD_STRING_LAST_INDEX(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LAST_INDEX)\n#define DUK_STRIDX_FLAGS                                              48                             /* 'flags' */\n#define DUK_HEAP_STRING_FLAGS(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FLAGS)\n#define DUK_HTHREAD_STRING_FLAGS(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FLAGS)\n#define DUK_STRIDX_INDEX                                              49                             /* 'index' */\n#define DUK_HEAP_STRING_INDEX(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INDEX)\n#define DUK_HTHREAD_STRING_INDEX(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INDEX)\n#define DUK_STRIDX_PROTOTYPE                                          50                             /* 'prototype' */\n#define DUK_HEAP_STRING_PROTOTYPE(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PROTOTYPE)\n#define DUK_HTHREAD_STRING_PROTOTYPE(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PROTOTYPE)\n#define DUK_STRIDX_CONSTRUCTOR                                        51                             /* 'constructor' */\n#define DUK_HEAP_STRING_CONSTRUCTOR(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONSTRUCTOR)\n#define DUK_HTHREAD_STRING_CONSTRUCTOR(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONSTRUCTOR)\n#define DUK_STRIDX_MESSAGE                                            52                             /* 'message' */\n#define DUK_HEAP_STRING_MESSAGE(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MESSAGE)\n#define DUK_HTHREAD_STRING_MESSAGE(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MESSAGE)\n#define DUK_STRIDX_LC_BOOLEAN                                         53                             /* 'boolean' */\n#define DUK_HEAP_STRING_LC_BOOLEAN(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_BOOLEAN)\n#define DUK_HTHREAD_STRING_LC_BOOLEAN(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_BOOLEAN)\n#define DUK_STRIDX_LC_NUMBER                                          54                             /* 'number' */\n#define DUK_HEAP_STRING_LC_NUMBER(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_NUMBER)\n#define DUK_HTHREAD_STRING_LC_NUMBER(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_NUMBER)\n#define DUK_STRIDX_LC_STRING                                          55                             /* 'string' */\n#define DUK_HEAP_STRING_LC_STRING(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_STRING)\n#define DUK_HTHREAD_STRING_LC_STRING(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_STRING)\n#define DUK_STRIDX_LC_SYMBOL                                          56                             /* 'symbol' */\n#define DUK_HEAP_STRING_LC_SYMBOL(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_SYMBOL)\n#define DUK_HTHREAD_STRING_LC_SYMBOL(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_SYMBOL)\n#define DUK_STRIDX_LC_OBJECT                                          57                             /* 'object' */\n#define DUK_HEAP_STRING_LC_OBJECT(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_OBJECT)\n#define DUK_HTHREAD_STRING_LC_OBJECT(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_OBJECT)\n#define DUK_STRIDX_LC_UNDEFINED                                       58                             /* 'undefined' */\n#define DUK_HEAP_STRING_LC_UNDEFINED(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_UNDEFINED)\n#define DUK_HTHREAD_STRING_LC_UNDEFINED(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_UNDEFINED)\n#define DUK_STRIDX_NAN                                                59                             /* 'NaN' */\n#define DUK_HEAP_STRING_NAN(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NAN)\n#define DUK_HTHREAD_STRING_NAN(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NAN)\n#define DUK_STRIDX_INFINITY                                           60                             /* 'Infinity' */\n#define DUK_HEAP_STRING_INFINITY(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INFINITY)\n#define DUK_HTHREAD_STRING_INFINITY(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INFINITY)\n#define DUK_STRIDX_MINUS_INFINITY                                     61                             /* '-Infinity' */\n#define DUK_HEAP_STRING_MINUS_INFINITY(heap)                          DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MINUS_INFINITY)\n#define DUK_HTHREAD_STRING_MINUS_INFINITY(thr)                        DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MINUS_INFINITY)\n#define DUK_STRIDX_MINUS_ZERO                                         62                             /* '-0' */\n#define DUK_HEAP_STRING_MINUS_ZERO(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MINUS_ZERO)\n#define DUK_HTHREAD_STRING_MINUS_ZERO(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MINUS_ZERO)\n#define DUK_STRIDX_COMMA                                              63                             /* ',' */\n#define DUK_HEAP_STRING_COMMA(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_COMMA)\n#define DUK_HTHREAD_STRING_COMMA(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_COMMA)\n#define DUK_STRIDX_NEWLINE_4SPACE                                     64                             /* '\\n    ' */\n#define DUK_HEAP_STRING_NEWLINE_4SPACE(heap)                          DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NEWLINE_4SPACE)\n#define DUK_HTHREAD_STRING_NEWLINE_4SPACE(thr)                        DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NEWLINE_4SPACE)\n#define DUK_STRIDX_BRACKETED_ELLIPSIS                                 65                             /* '[...]' */\n#define DUK_HEAP_STRING_BRACKETED_ELLIPSIS(heap)                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BRACKETED_ELLIPSIS)\n#define DUK_HTHREAD_STRING_BRACKETED_ELLIPSIS(thr)                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BRACKETED_ELLIPSIS)\n#define DUK_STRIDX_INVALID_DATE                                       66                             /* 'Invalid Date' */\n#define DUK_HEAP_STRING_INVALID_DATE(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INVALID_DATE)\n#define DUK_HTHREAD_STRING_INVALID_DATE(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INVALID_DATE)\n#define DUK_STRIDX_LC_ARGUMENTS                                       67                             /* 'arguments' */\n#define DUK_HEAP_STRING_LC_ARGUMENTS(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_ARGUMENTS)\n#define DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_ARGUMENTS)\n#define DUK_STRIDX_CALLEE                                             68                             /* 'callee' */\n#define DUK_HEAP_STRING_CALLEE(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CALLEE)\n#define DUK_HTHREAD_STRING_CALLEE(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CALLEE)\n#define DUK_STRIDX_CALLER                                             69                             /* 'caller' */\n#define DUK_HEAP_STRING_CALLER(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CALLER)\n#define DUK_HTHREAD_STRING_CALLER(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CALLER)\n#define DUK_STRIDX_APPLY                                              70                             /* 'apply' */\n#define DUK_HEAP_STRING_APPLY(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_APPLY)\n#define DUK_HTHREAD_STRING_APPLY(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_APPLY)\n#define DUK_STRIDX_CONSTRUCT                                          71                             /* 'construct' */\n#define DUK_HEAP_STRING_CONSTRUCT(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONSTRUCT)\n#define DUK_HTHREAD_STRING_CONSTRUCT(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONSTRUCT)\n#define DUK_STRIDX_DELETE_PROPERTY                                    72                             /* 'deleteProperty' */\n#define DUK_HEAP_STRING_DELETE_PROPERTY(heap)                         DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DELETE_PROPERTY)\n#define DUK_HTHREAD_STRING_DELETE_PROPERTY(thr)                       DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DELETE_PROPERTY)\n#define DUK_STRIDX_GET                                                73                             /* 'get' */\n#define DUK_HEAP_STRING_GET(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_GET)\n#define DUK_HTHREAD_STRING_GET(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_GET)\n#define DUK_STRIDX_HAS                                                74                             /* 'has' */\n#define DUK_HEAP_STRING_HAS(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_HAS)\n#define DUK_HTHREAD_STRING_HAS(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_HAS)\n#define DUK_STRIDX_OWN_KEYS                                           75                             /* 'ownKeys' */\n#define DUK_HEAP_STRING_OWN_KEYS(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_OWN_KEYS)\n#define DUK_HTHREAD_STRING_OWN_KEYS(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_OWN_KEYS)\n#define DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE                      76                             /* '\\x81Symbol.toPrimitive\\xff' */\n#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_TO_PRIMITIVE(heap)           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE)\n#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_TO_PRIMITIVE(thr)         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE)\n#define DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE                      77                             /* '\\x81Symbol.hasInstance\\xff' */\n#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_HAS_INSTANCE(heap)           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE)\n#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_HAS_INSTANCE(thr)         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE)\n#define DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG                     78                             /* '\\x81Symbol.toStringTag\\xff' */\n#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_TO_STRING_TAG(heap)          DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG)\n#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_TO_STRING_TAG(thr)        DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG)\n#define DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE              79                             /* '\\x81Symbol.isConcatSpreadable\\xff' */\n#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE(heap)   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE)\n#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE(thr)  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE)\n#define DUK_STRIDX_SET_PROTOTYPE_OF                                   80                             /* 'setPrototypeOf' */\n#define DUK_HEAP_STRING_SET_PROTOTYPE_OF(heap)                        DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SET_PROTOTYPE_OF)\n#define DUK_HTHREAD_STRING_SET_PROTOTYPE_OF(thr)                      DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SET_PROTOTYPE_OF)\n#define DUK_STRIDX___PROTO__                                          81                             /* '__proto__' */\n#define DUK_HEAP_STRING___PROTO__(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX___PROTO__)\n#define DUK_HTHREAD_STRING___PROTO__(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX___PROTO__)\n#define DUK_STRIDX_TO_STRING                                          82                             /* 'toString' */\n#define DUK_HEAP_STRING_TO_STRING(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_STRING)\n#define DUK_HTHREAD_STRING_TO_STRING(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_STRING)\n#define DUK_STRIDX_TO_JSON                                            83                             /* 'toJSON' */\n#define DUK_HEAP_STRING_TO_JSON(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_JSON)\n#define DUK_HTHREAD_STRING_TO_JSON(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_JSON)\n#define DUK_STRIDX_TYPE                                               84                             /* 'type' */\n#define DUK_HEAP_STRING_TYPE(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TYPE)\n#define DUK_HTHREAD_STRING_TYPE(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TYPE)\n#define DUK_STRIDX_DATA                                               85                             /* 'data' */\n#define DUK_HEAP_STRING_DATA(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DATA)\n#define DUK_HTHREAD_STRING_DATA(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DATA)\n#define DUK_STRIDX_LENGTH                                             86                             /* 'length' */\n#define DUK_HEAP_STRING_LENGTH(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LENGTH)\n#define DUK_HTHREAD_STRING_LENGTH(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LENGTH)\n#define DUK_STRIDX_SET                                                87                             /* 'set' */\n#define DUK_HEAP_STRING_SET(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SET)\n#define DUK_HTHREAD_STRING_SET(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SET)\n#define DUK_STRIDX_STACK                                              88                             /* 'stack' */\n#define DUK_HEAP_STRING_STACK(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_STACK)\n#define DUK_HTHREAD_STRING_STACK(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_STACK)\n#define DUK_STRIDX_PC                                                 89                             /* 'pc' */\n#define DUK_HEAP_STRING_PC(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PC)\n#define DUK_HTHREAD_STRING_PC(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PC)\n#define DUK_STRIDX_LINE_NUMBER                                        90                             /* 'lineNumber' */\n#define DUK_HEAP_STRING_LINE_NUMBER(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LINE_NUMBER)\n#define DUK_HTHREAD_STRING_LINE_NUMBER(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LINE_NUMBER)\n#define DUK_STRIDX_INT_TRACEDATA                                      91                             /* '\\x82Tracedata' */\n#define DUK_HEAP_STRING_INT_TRACEDATA(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_TRACEDATA)\n#define DUK_HTHREAD_STRING_INT_TRACEDATA(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_TRACEDATA)\n#define DUK_STRIDX_NAME                                               92                             /* 'name' */\n#define DUK_HEAP_STRING_NAME(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NAME)\n#define DUK_HTHREAD_STRING_NAME(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NAME)\n#define DUK_STRIDX_FILE_NAME                                          93                             /* 'fileName' */\n#define DUK_HEAP_STRING_FILE_NAME(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FILE_NAME)\n#define DUK_HTHREAD_STRING_FILE_NAME(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FILE_NAME)\n#define DUK_STRIDX_LC_POINTER                                         94                             /* 'pointer' */\n#define DUK_HEAP_STRING_LC_POINTER(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_POINTER)\n#define DUK_HTHREAD_STRING_LC_POINTER(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_POINTER)\n#define DUK_STRIDX_INT_TARGET                                         95                             /* '\\x82Target' */\n#define DUK_HEAP_STRING_INT_TARGET(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_TARGET)\n#define DUK_HTHREAD_STRING_INT_TARGET(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_TARGET)\n#define DUK_STRIDX_INT_NEXT                                           96                             /* '\\x82Next' */\n#define DUK_HEAP_STRING_INT_NEXT(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_NEXT)\n#define DUK_HTHREAD_STRING_INT_NEXT(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_NEXT)\n#define DUK_STRIDX_INT_BYTECODE                                       97                             /* '\\x82Bytecode' */\n#define DUK_HEAP_STRING_INT_BYTECODE(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_BYTECODE)\n#define DUK_HTHREAD_STRING_INT_BYTECODE(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_BYTECODE)\n#define DUK_STRIDX_INT_FORMALS                                        98                             /* '\\x82Formals' */\n#define DUK_HEAP_STRING_INT_FORMALS(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_FORMALS)\n#define DUK_HTHREAD_STRING_INT_FORMALS(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_FORMALS)\n#define DUK_STRIDX_INT_VARMAP                                         99                             /* '\\x82Varmap' */\n#define DUK_HEAP_STRING_INT_VARMAP(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VARMAP)\n#define DUK_HTHREAD_STRING_INT_VARMAP(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VARMAP)\n#define DUK_STRIDX_INT_SOURCE                                         100                            /* '\\x82Source' */\n#define DUK_HEAP_STRING_INT_SOURCE(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_SOURCE)\n#define DUK_HTHREAD_STRING_INT_SOURCE(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_SOURCE)\n#define DUK_STRIDX_INT_PC2LINE                                        101                            /* '\\x82Pc2line' */\n#define DUK_HEAP_STRING_INT_PC2LINE(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_PC2LINE)\n#define DUK_HTHREAD_STRING_INT_PC2LINE(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_PC2LINE)\n#define DUK_STRIDX_INT_MAP                                            102                            /* '\\x82Map' */\n#define DUK_HEAP_STRING_INT_MAP(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_MAP)\n#define DUK_HTHREAD_STRING_INT_MAP(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_MAP)\n#define DUK_STRIDX_INT_VARENV                                         103                            /* '\\x82Varenv' */\n#define DUK_HEAP_STRING_INT_VARENV(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VARENV)\n#define DUK_HTHREAD_STRING_INT_VARENV(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VARENV)\n#define DUK_STRIDX_INT_FINALIZER                                      104                            /* '\\x82Finalizer' */\n#define DUK_HEAP_STRING_INT_FINALIZER(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_FINALIZER)\n#define DUK_HTHREAD_STRING_INT_FINALIZER(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_FINALIZER)\n#define DUK_STRIDX_INT_VALUE                                          105                            /* '\\x82Value' */\n#define DUK_HEAP_STRING_INT_VALUE(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VALUE)\n#define DUK_HTHREAD_STRING_INT_VALUE(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VALUE)\n#define DUK_STRIDX_COMPILE                                            106                            /* 'compile' */\n#define DUK_HEAP_STRING_COMPILE(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_COMPILE)\n#define DUK_HTHREAD_STRING_COMPILE(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_COMPILE)\n#define DUK_STRIDX_INPUT                                              107                            /* 'input' */\n#define DUK_HEAP_STRING_INPUT(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INPUT)\n#define DUK_HTHREAD_STRING_INPUT(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INPUT)\n#define DUK_STRIDX_ERR_CREATE                                         108                            /* 'errCreate' */\n#define DUK_HEAP_STRING_ERR_CREATE(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ERR_CREATE)\n#define DUK_HTHREAD_STRING_ERR_CREATE(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ERR_CREATE)\n#define DUK_STRIDX_ERR_THROW                                          109                            /* 'errThrow' */\n#define DUK_HEAP_STRING_ERR_THROW(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ERR_THROW)\n#define DUK_HTHREAD_STRING_ERR_THROW(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ERR_THROW)\n#define DUK_STRIDX_ENV                                                110                            /* 'env' */\n#define DUK_HEAP_STRING_ENV(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENV)\n#define DUK_HTHREAD_STRING_ENV(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENV)\n#define DUK_STRIDX_HEX                                                111                            /* 'hex' */\n#define DUK_HEAP_STRING_HEX(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_HEX)\n#define DUK_HTHREAD_STRING_HEX(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_HEX)\n#define DUK_STRIDX_BASE64                                             112                            /* 'base64' */\n#define DUK_HEAP_STRING_BASE64(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BASE64)\n#define DUK_HTHREAD_STRING_BASE64(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BASE64)\n#define DUK_STRIDX_JX                                                 113                            /* 'jx' */\n#define DUK_HEAP_STRING_JX(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JX)\n#define DUK_HTHREAD_STRING_JX(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JX)\n#define DUK_STRIDX_JC                                                 114                            /* 'jc' */\n#define DUK_HEAP_STRING_JC(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JC)\n#define DUK_HTHREAD_STRING_JC(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JC)\n#define DUK_STRIDX_JSON_EXT_UNDEFINED                                 115                            /* '{\"_undef\":true}' */\n#define DUK_HEAP_STRING_JSON_EXT_UNDEFINED(heap)                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_UNDEFINED)\n#define DUK_HTHREAD_STRING_JSON_EXT_UNDEFINED(thr)                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_UNDEFINED)\n#define DUK_STRIDX_JSON_EXT_NAN                                       116                            /* '{\"_nan\":true}' */\n#define DUK_HEAP_STRING_JSON_EXT_NAN(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_NAN)\n#define DUK_HTHREAD_STRING_JSON_EXT_NAN(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_NAN)\n#define DUK_STRIDX_JSON_EXT_POSINF                                    117                            /* '{\"_inf\":true}' */\n#define DUK_HEAP_STRING_JSON_EXT_POSINF(heap)                         DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_POSINF)\n#define DUK_HTHREAD_STRING_JSON_EXT_POSINF(thr)                       DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_POSINF)\n#define DUK_STRIDX_JSON_EXT_NEGINF                                    118                            /* '{\"_ninf\":true}' */\n#define DUK_HEAP_STRING_JSON_EXT_NEGINF(heap)                         DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_NEGINF)\n#define DUK_HTHREAD_STRING_JSON_EXT_NEGINF(thr)                       DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_NEGINF)\n#define DUK_STRIDX_JSON_EXT_FUNCTION1                                 119                            /* '{\"_func\":true}' */\n#define DUK_HEAP_STRING_JSON_EXT_FUNCTION1(heap)                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_FUNCTION1)\n#define DUK_HTHREAD_STRING_JSON_EXT_FUNCTION1(thr)                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_FUNCTION1)\n#define DUK_STRIDX_JSON_EXT_FUNCTION2                                 120                            /* '{_func:true}' */\n#define DUK_HEAP_STRING_JSON_EXT_FUNCTION2(heap)                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_FUNCTION2)\n#define DUK_HTHREAD_STRING_JSON_EXT_FUNCTION2(thr)                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_FUNCTION2)\n#define DUK_STRIDX_BREAK                                              121                            /* 'break' */\n#define DUK_HEAP_STRING_BREAK(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BREAK)\n#define DUK_HTHREAD_STRING_BREAK(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BREAK)\n#define DUK_STRIDX_CASE                                               122                            /* 'case' */\n#define DUK_HEAP_STRING_CASE(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CASE)\n#define DUK_HTHREAD_STRING_CASE(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CASE)\n#define DUK_STRIDX_CATCH                                              123                            /* 'catch' */\n#define DUK_HEAP_STRING_CATCH(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CATCH)\n#define DUK_HTHREAD_STRING_CATCH(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CATCH)\n#define DUK_STRIDX_CONTINUE                                           124                            /* 'continue' */\n#define DUK_HEAP_STRING_CONTINUE(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONTINUE)\n#define DUK_HTHREAD_STRING_CONTINUE(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONTINUE)\n#define DUK_STRIDX_DEBUGGER                                           125                            /* 'debugger' */\n#define DUK_HEAP_STRING_DEBUGGER(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEBUGGER)\n#define DUK_HTHREAD_STRING_DEBUGGER(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEBUGGER)\n#define DUK_STRIDX_DEFAULT                                            126                            /* 'default' */\n#define DUK_HEAP_STRING_DEFAULT(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEFAULT)\n#define DUK_HTHREAD_STRING_DEFAULT(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEFAULT)\n#define DUK_STRIDX_DELETE                                             127                            /* 'delete' */\n#define DUK_HEAP_STRING_DELETE(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DELETE)\n#define DUK_HTHREAD_STRING_DELETE(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DELETE)\n#define DUK_STRIDX_DO                                                 128                            /* 'do' */\n#define DUK_HEAP_STRING_DO(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DO)\n#define DUK_HTHREAD_STRING_DO(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DO)\n#define DUK_STRIDX_ELSE                                               129                            /* 'else' */\n#define DUK_HEAP_STRING_ELSE(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ELSE)\n#define DUK_HTHREAD_STRING_ELSE(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ELSE)\n#define DUK_STRIDX_FINALLY                                            130                            /* 'finally' */\n#define DUK_HEAP_STRING_FINALLY(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FINALLY)\n#define DUK_HTHREAD_STRING_FINALLY(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FINALLY)\n#define DUK_STRIDX_FOR                                                131                            /* 'for' */\n#define DUK_HEAP_STRING_FOR(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FOR)\n#define DUK_HTHREAD_STRING_FOR(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FOR)\n#define DUK_STRIDX_LC_FUNCTION                                        132                            /* 'function' */\n#define DUK_HEAP_STRING_LC_FUNCTION(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_FUNCTION)\n#define DUK_HTHREAD_STRING_LC_FUNCTION(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_FUNCTION)\n#define DUK_STRIDX_IF                                                 133                            /* 'if' */\n#define DUK_HEAP_STRING_IF(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IF)\n#define DUK_HTHREAD_STRING_IF(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IF)\n#define DUK_STRIDX_IN                                                 134                            /* 'in' */\n#define DUK_HEAP_STRING_IN(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IN)\n#define DUK_HTHREAD_STRING_IN(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IN)\n#define DUK_STRIDX_INSTANCEOF                                         135                            /* 'instanceof' */\n#define DUK_HEAP_STRING_INSTANCEOF(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INSTANCEOF)\n#define DUK_HTHREAD_STRING_INSTANCEOF(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INSTANCEOF)\n#define DUK_STRIDX_NEW                                                136                            /* 'new' */\n#define DUK_HEAP_STRING_NEW(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NEW)\n#define DUK_HTHREAD_STRING_NEW(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NEW)\n#define DUK_STRIDX_RETURN                                             137                            /* 'return' */\n#define DUK_HEAP_STRING_RETURN(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_RETURN)\n#define DUK_HTHREAD_STRING_RETURN(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_RETURN)\n#define DUK_STRIDX_SWITCH                                             138                            /* 'switch' */\n#define DUK_HEAP_STRING_SWITCH(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SWITCH)\n#define DUK_HTHREAD_STRING_SWITCH(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SWITCH)\n#define DUK_STRIDX_THIS                                               139                            /* 'this' */\n#define DUK_HEAP_STRING_THIS(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_THIS)\n#define DUK_HTHREAD_STRING_THIS(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_THIS)\n#define DUK_STRIDX_THROW                                              140                            /* 'throw' */\n#define DUK_HEAP_STRING_THROW(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_THROW)\n#define DUK_HTHREAD_STRING_THROW(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_THROW)\n#define DUK_STRIDX_TRY                                                141                            /* 'try' */\n#define DUK_HEAP_STRING_TRY(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TRY)\n#define DUK_HTHREAD_STRING_TRY(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TRY)\n#define DUK_STRIDX_TYPEOF                                             142                            /* 'typeof' */\n#define DUK_HEAP_STRING_TYPEOF(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TYPEOF)\n#define DUK_HTHREAD_STRING_TYPEOF(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TYPEOF)\n#define DUK_STRIDX_VAR                                                143                            /* 'var' */\n#define DUK_HEAP_STRING_VAR(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VAR)\n#define DUK_HTHREAD_STRING_VAR(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VAR)\n#define DUK_STRIDX_CONST                                              144                            /* 'const' */\n#define DUK_HEAP_STRING_CONST(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONST)\n#define DUK_HTHREAD_STRING_CONST(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONST)\n#define DUK_STRIDX_VOID                                               145                            /* 'void' */\n#define DUK_HEAP_STRING_VOID(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VOID)\n#define DUK_HTHREAD_STRING_VOID(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VOID)\n#define DUK_STRIDX_WHILE                                              146                            /* 'while' */\n#define DUK_HEAP_STRING_WHILE(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WHILE)\n#define DUK_HTHREAD_STRING_WHILE(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WHILE)\n#define DUK_STRIDX_WITH                                               147                            /* 'with' */\n#define DUK_HEAP_STRING_WITH(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WITH)\n#define DUK_HTHREAD_STRING_WITH(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WITH)\n#define DUK_STRIDX_CLASS                                              148                            /* 'class' */\n#define DUK_HEAP_STRING_CLASS(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CLASS)\n#define DUK_HTHREAD_STRING_CLASS(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CLASS)\n#define DUK_STRIDX_ENUM                                               149                            /* 'enum' */\n#define DUK_HEAP_STRING_ENUM(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENUM)\n#define DUK_HTHREAD_STRING_ENUM(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENUM)\n#define DUK_STRIDX_EXPORT                                             150                            /* 'export' */\n#define DUK_HEAP_STRING_EXPORT(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EXPORT)\n#define DUK_HTHREAD_STRING_EXPORT(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EXPORT)\n#define DUK_STRIDX_EXTENDS                                            151                            /* 'extends' */\n#define DUK_HEAP_STRING_EXTENDS(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EXTENDS)\n#define DUK_HTHREAD_STRING_EXTENDS(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EXTENDS)\n#define DUK_STRIDX_IMPORT                                             152                            /* 'import' */\n#define DUK_HEAP_STRING_IMPORT(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IMPORT)\n#define DUK_HTHREAD_STRING_IMPORT(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IMPORT)\n#define DUK_STRIDX_SUPER                                              153                            /* 'super' */\n#define DUK_HEAP_STRING_SUPER(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SUPER)\n#define DUK_HTHREAD_STRING_SUPER(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SUPER)\n#define DUK_STRIDX_LC_NULL                                            154                            /* 'null' */\n#define DUK_HEAP_STRING_LC_NULL(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_NULL)\n#define DUK_HTHREAD_STRING_LC_NULL(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_NULL)\n#define DUK_STRIDX_TRUE                                               155                            /* 'true' */\n#define DUK_HEAP_STRING_TRUE(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TRUE)\n#define DUK_HTHREAD_STRING_TRUE(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TRUE)\n#define DUK_STRIDX_FALSE                                              156                            /* 'false' */\n#define DUK_HEAP_STRING_FALSE(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FALSE)\n#define DUK_HTHREAD_STRING_FALSE(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FALSE)\n#define DUK_STRIDX_IMPLEMENTS                                         157                            /* 'implements' */\n#define DUK_HEAP_STRING_IMPLEMENTS(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IMPLEMENTS)\n#define DUK_HTHREAD_STRING_IMPLEMENTS(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IMPLEMENTS)\n#define DUK_STRIDX_INTERFACE                                          158                            /* 'interface' */\n#define DUK_HEAP_STRING_INTERFACE(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INTERFACE)\n#define DUK_HTHREAD_STRING_INTERFACE(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INTERFACE)\n#define DUK_STRIDX_LET                                                159                            /* 'let' */\n#define DUK_HEAP_STRING_LET(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LET)\n#define DUK_HTHREAD_STRING_LET(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LET)\n#define DUK_STRIDX_PACKAGE                                            160                            /* 'package' */\n#define DUK_HEAP_STRING_PACKAGE(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PACKAGE)\n#define DUK_HTHREAD_STRING_PACKAGE(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PACKAGE)\n#define DUK_STRIDX_PRIVATE                                            161                            /* 'private' */\n#define DUK_HEAP_STRING_PRIVATE(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PRIVATE)\n#define DUK_HTHREAD_STRING_PRIVATE(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PRIVATE)\n#define DUK_STRIDX_PROTECTED                                          162                            /* 'protected' */\n#define DUK_HEAP_STRING_PROTECTED(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PROTECTED)\n#define DUK_HTHREAD_STRING_PROTECTED(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PROTECTED)\n#define DUK_STRIDX_PUBLIC                                             163                            /* 'public' */\n#define DUK_HEAP_STRING_PUBLIC(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PUBLIC)\n#define DUK_HTHREAD_STRING_PUBLIC(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PUBLIC)\n#define DUK_STRIDX_STATIC                                             164                            /* 'static' */\n#define DUK_HEAP_STRING_STATIC(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_STATIC)\n#define DUK_HTHREAD_STRING_STATIC(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_STATIC)\n#define DUK_STRIDX_YIELD                                              165                            /* 'yield' */\n#define DUK_HEAP_STRING_YIELD(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_YIELD)\n#define DUK_HTHREAD_STRING_YIELD(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_YIELD)\n\n#define DUK_HEAP_NUM_STRINGS                                          166\n#define DUK_STRIDX_START_RESERVED                                     121\n#define DUK_STRIDX_START_STRICT_RESERVED                              157\n#define DUK_STRIDX_END_RESERVED                                       166                            /* exclusive endpoint */\n\n/* To convert a heap stridx to a token number, subtract\n * DUK_STRIDX_START_RESERVED and add DUK_TOK_START_RESERVED.\n */\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_strings_data[967];\n#endif  /* !DUK_SINGLE_FILE */\n#define DUK_STRDATA_MAX_STRLEN                                        27\n#define DUK_STRDATA_DATA_LENGTH                                       967\n#endif  /* DUK_USE_ROM_STRINGS */\n\n#if defined(DUK_USE_ROM_OBJECTS)\n#error RAM support not enabled, rerun configure.py with --ram-support\n#else  /* DUK_USE_ROM_OBJECTS */\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_boolean_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_constructor_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_type_error_thrower(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_parse_int(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_parse_float(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_thread_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_pointer_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_proxy_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_constructor_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_arraybuffer_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_dataview_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_eval(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_is_nan(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_is_finite(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_decode_uri(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_decode_uri_component(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_encode_uri(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_encode_uri_component(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_escape(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_unescape(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_getprototype_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_setprototype_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_get_own_property_descriptor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_keys_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_assign(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_create(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_define_property(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_define_properties(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_seal_freeze_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_is_sealed_frozen_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_is_extensible(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_is(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_locale_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_value_of(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_has_own_property(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_property_is_enumerable(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_defineaccessor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_lookupaccessor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_apply(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_call(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_bind(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_hasinstance(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_native_function_length(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_native_function_name(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_constructor_is_array(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_join_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_concat(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_pop(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_push(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_reverse(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_shift(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_slice(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_sort(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_unshift(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_indexof_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_iter_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_reduce_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_constructor_from_char_code(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_constructor_from_code_point(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_char_at(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_char_code_at(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_concat(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_indexof_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_locale_compare(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_match(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_search(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_slice(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_split(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_substring(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_caseconv_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_trim(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_repeat(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_includes(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_substr(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_check_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_locale_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_value_of(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_fixed(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_exponential(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_precision(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor_parse(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor_utc(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor_now(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_tostring_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_to_json(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_value_of(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_get_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_get_timezone_offset(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_set_time(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_set_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_toprimitive(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_exec(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_test(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_tostring(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_flags(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_stack_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_stack_setter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_filename_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_filename_setter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_linenumber_setter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_onearg_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_twoarg_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_clz32(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_hypot(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_imul(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_max(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_min(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_random(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_sign(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_json_object_parse(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_json_object_stringify(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_info(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_act(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_gc(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_fin(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_enc(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_dec(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_compact(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_thread_yield(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_thread_resume(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_thread_current(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_apply(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_construct(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_delete_property(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_get(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_has(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_set(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_key_for(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_tostring_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_toprimitive(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_arraybuffer_isview(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_buffer_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_set(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_uint8array_allocplain(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_uint8array_plainof(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_concat(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_is_encoding(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_byte_length(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_compare_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_fill(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_copy(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_write(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_prototype_encoding_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_prototype_encode(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_performance_now(duk_context *ctx);\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[183];\n#endif  /* !DUK_SINGLE_FILE */\n#define DUK_BIDX_GLOBAL                                               0\n#define DUK_BIDX_GLOBAL_ENV                                           1\n#define DUK_BIDX_OBJECT_CONSTRUCTOR                                   2\n#define DUK_BIDX_OBJECT_PROTOTYPE                                     3\n#define DUK_BIDX_FUNCTION_CONSTRUCTOR                                 4\n#define DUK_BIDX_FUNCTION_PROTOTYPE                                   5\n#define DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE                            6\n#define DUK_BIDX_ARRAY_CONSTRUCTOR                                    7\n#define DUK_BIDX_ARRAY_PROTOTYPE                                      8\n#define DUK_BIDX_STRING_CONSTRUCTOR                                   9\n#define DUK_BIDX_STRING_PROTOTYPE                                     10\n#define DUK_BIDX_BOOLEAN_CONSTRUCTOR                                  11\n#define DUK_BIDX_BOOLEAN_PROTOTYPE                                    12\n#define DUK_BIDX_NUMBER_CONSTRUCTOR                                   13\n#define DUK_BIDX_NUMBER_PROTOTYPE                                     14\n#define DUK_BIDX_DATE_CONSTRUCTOR                                     15\n#define DUK_BIDX_DATE_PROTOTYPE                                       16\n#define DUK_BIDX_REGEXP_CONSTRUCTOR                                   17\n#define DUK_BIDX_REGEXP_PROTOTYPE                                     18\n#define DUK_BIDX_ERROR_CONSTRUCTOR                                    19\n#define DUK_BIDX_ERROR_PROTOTYPE                                      20\n#define DUK_BIDX_EVAL_ERROR_CONSTRUCTOR                               21\n#define DUK_BIDX_EVAL_ERROR_PROTOTYPE                                 22\n#define DUK_BIDX_RANGE_ERROR_CONSTRUCTOR                              23\n#define DUK_BIDX_RANGE_ERROR_PROTOTYPE                                24\n#define DUK_BIDX_REFERENCE_ERROR_CONSTRUCTOR                          25\n#define DUK_BIDX_REFERENCE_ERROR_PROTOTYPE                            26\n#define DUK_BIDX_SYNTAX_ERROR_CONSTRUCTOR                             27\n#define DUK_BIDX_SYNTAX_ERROR_PROTOTYPE                               28\n#define DUK_BIDX_TYPE_ERROR_CONSTRUCTOR                               29\n#define DUK_BIDX_TYPE_ERROR_PROTOTYPE                                 30\n#define DUK_BIDX_URI_ERROR_CONSTRUCTOR                                31\n#define DUK_BIDX_URI_ERROR_PROTOTYPE                                  32\n#define DUK_BIDX_TYPE_ERROR_THROWER                                   33\n#define DUK_BIDX_DUKTAPE                                              34\n#define DUK_BIDX_THREAD_PROTOTYPE                                     35\n#define DUK_BIDX_POINTER_PROTOTYPE                                    36\n#define DUK_BIDX_DOUBLE_ERROR                                         37\n#define DUK_BIDX_SYMBOL_PROTOTYPE                                     38\n#define DUK_BIDX_ARRAYBUFFER_PROTOTYPE                                39\n#define DUK_BIDX_DATAVIEW_PROTOTYPE                                   40\n#define DUK_BIDX_INT8ARRAY_PROTOTYPE                                  41\n#define DUK_BIDX_UINT8ARRAY_PROTOTYPE                                 42\n#define DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE                          43\n#define DUK_BIDX_INT16ARRAY_PROTOTYPE                                 44\n#define DUK_BIDX_UINT16ARRAY_PROTOTYPE                                45\n#define DUK_BIDX_INT32ARRAY_PROTOTYPE                                 46\n#define DUK_BIDX_UINT32ARRAY_PROTOTYPE                                47\n#define DUK_BIDX_FLOAT32ARRAY_PROTOTYPE                               48\n#define DUK_BIDX_FLOAT64ARRAY_PROTOTYPE                               49\n#define DUK_BIDX_NODEJS_BUFFER_PROTOTYPE                              50\n#define DUK_NUM_BUILTINS                                              51\n#define DUK_NUM_BIDX_BUILTINS                                         51\n#define DUK_NUM_ALL_BUILTINS                                          79\n#if defined(DUK_USE_DOUBLE_LE)\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4251];\n#endif  /* !DUK_SINGLE_FILE */\n#define DUK_BUILTINS_DATA_LENGTH                                      4251\n#elif defined(DUK_USE_DOUBLE_BE)\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4251];\n#endif  /* !DUK_SINGLE_FILE */\n#define DUK_BUILTINS_DATA_LENGTH                                      4251\n#elif defined(DUK_USE_DOUBLE_ME)\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4251];\n#endif  /* !DUK_SINGLE_FILE */\n#define DUK_BUILTINS_DATA_LENGTH                                      4251\n#else\n#error invalid endianness defines\n#endif\n#endif  /* DUK_USE_ROM_OBJECTS */\n#endif  /* DUK_BUILTINS_H_INCLUDED */\n\n/* #include duk_util.h */\n/*\n *  Utilities\n */\n\n#if !defined(DUK_UTIL_H_INCLUDED)\n#define DUK_UTIL_H_INCLUDED\n\n#if defined(DUK_USE_GET_RANDOM_DOUBLE)\n#define DUK_UTIL_GET_RANDOM_DOUBLE(thr) DUK_USE_GET_RANDOM_DOUBLE((thr)->heap_udata)\n#else\n#define DUK_UTIL_GET_RANDOM_DOUBLE(thr) duk_util_tinyrandom_get_double(thr)\n#endif\n\n/*\n *  Some useful constants\n */\n\n#define DUK_DOUBLE_2TO32     4294967296.0\n#define DUK_DOUBLE_2TO31     2147483648.0\n#define DUK_DOUBLE_LOG2E     1.4426950408889634\n#define DUK_DOUBLE_LOG10E    0.4342944819032518\n\n/*\n *  Endian conversion\n */\n\n#if defined(DUK_USE_INTEGER_LE)\n#define DUK_HTON32(x) DUK_BSWAP32((x))\n#define DUK_NTOH32(x) DUK_BSWAP32((x))\n#define DUK_HTON16(x) DUK_BSWAP16((x))\n#define DUK_NTOH16(x) DUK_BSWAP16((x))\n#elif defined(DUK_USE_INTEGER_BE)\n#define DUK_HTON32(x) (x)\n#define DUK_NTOH32(x) (x)\n#define DUK_HTON16(x) (x)\n#define DUK_NTOH16(x) (x)\n#else\n#error internal error, endianness defines broken\n#endif\n\n/*\n *  Bitstream decoder\n */\n\nstruct duk_bitdecoder_ctx {\n\tconst duk_uint8_t *data;\n\tduk_size_t offset;\n\tduk_size_t length;\n\tduk_uint32_t currval;\n\tduk_small_int_t currbits;\n};\n\n#define DUK_BD_BITPACKED_STRING_MAXLEN 256\n\n/*\n *  Bitstream encoder\n */\n\nstruct duk_bitencoder_ctx {\n\tduk_uint8_t *data;\n\tduk_size_t offset;\n\tduk_size_t length;\n\tduk_uint32_t currval;\n\tduk_small_int_t currbits;\n\tduk_small_int_t truncated;\n};\n\n/*\n *  Raw write/read macros for big endian, unaligned basic values.\n *  Caller ensures there's enough space.  The macros update the pointer\n *  argument automatically on resizes.  The idiom seems a bit odd, but\n *  leads to compact code.\n */\n\n#define DUK_RAW_WRITE_U8(ptr,val)  do { \\\n\t\t*(ptr)++ = (duk_uint8_t) (val); \\\n\t} while (0)\n#define DUK_RAW_WRITE_U16_BE(ptr,val) duk_raw_write_u16_be(&(ptr), (duk_uint16_t) (val))\n#define DUK_RAW_WRITE_U32_BE(ptr,val) duk_raw_write_u32_be(&(ptr), (duk_uint32_t) (val))\n#define DUK_RAW_WRITE_DOUBLE_BE(ptr,val) duk_raw_write_double_be(&(ptr), (duk_double_t) (val))\n#define DUK_RAW_WRITE_XUTF8(ptr,val)  do { \\\n\t\t/* 'ptr' is evaluated both as LHS and RHS. */ \\\n\t\tduk_uint8_t *duk__ptr; \\\n\t\tduk_small_int_t duk__len; \\\n\t\tduk__ptr = (duk_uint8_t *) (ptr); \\\n\t\tduk__len = duk_unicode_encode_xutf8((duk_ucodepoint_t) (val), duk__ptr); \\\n\t\tduk__ptr += duk__len; \\\n\t\t(ptr) = duk__ptr; \\\n\t} while (0)\n#define DUK_RAW_WRITE_CESU8(ptr,val)  do { \\\n\t\t/* 'ptr' is evaluated both as LHS and RHS. */ \\\n\t\tduk_uint8_t *duk__ptr; \\\n\t\tduk_small_int_t duk__len; \\\n\t\tduk__ptr = (duk_uint8_t *) (ptr); \\\n\t\tduk__len = duk_unicode_encode_cesu8((duk_ucodepoint_t) (val), duk__ptr); \\\n\t\tduk__ptr += duk__len; \\\n\t\t(ptr) = duk__ptr; \\\n\t} while (0)\n\n#define DUK_RAW_READ_U8(ptr) ((duk_uint8_t) (*(ptr)++))\n#define DUK_RAW_READ_U16_BE(ptr) duk_raw_read_u16_be(&(ptr));\n#define DUK_RAW_READ_U32_BE(ptr) duk_raw_read_u32_be(&(ptr));\n#define DUK_RAW_READ_DOUBLE_BE(ptr) duk_raw_read_double_be(&(ptr));\n\n/*\n *  Buffer writer (dynamic buffer only)\n *\n *  Helper for writing to a dynamic buffer with a concept of a \"slack\" area\n *  to reduce resizes.  You can ensure there is enough space beforehand and\n *  then write for a while without further checks, relying on a stable data\n *  pointer.  Slack handling is automatic so call sites only indicate how\n *  much data they need right now.\n *\n *  There are several ways to write using bufwriter.  The best approach\n *  depends mainly on how much performance matters over code footprint.\n *  The key issues are (1) ensuring there is space and (2) keeping the\n *  pointers consistent.  Fast code should ensure space for multiple writes\n *  with one ensure call.  Fastest inner loop code can temporarily borrow\n *  the 'p' pointer but must write it back eventually.\n *\n *  Be careful to ensure all macro arguments (other than static pointers like\n *  'thr' and 'bw_ctx') are evaluated exactly once, using temporaries if\n *  necessary (if that's not possible, there should be a note near the macro).\n *  Buffer write arguments often contain arithmetic etc so this is\n *  particularly important here.\n */\n\n/* XXX: Migrate bufwriter and other read/write helpers to its own header? */\n\nstruct duk_bufwriter_ctx {\n\tduk_uint8_t *p;\n\tduk_uint8_t *p_base;\n\tduk_uint8_t *p_limit;\n\tduk_hbuffer_dynamic *buf;\n};\n\n#if defined(DUK_USE_PREFER_SIZE)\n#define DUK_BW_SLACK_ADD           64\n#define DUK_BW_SLACK_SHIFT         4    /* 2^4 -> 1/16 = 6.25% slack */\n#else\n#define DUK_BW_SLACK_ADD           64\n#define DUK_BW_SLACK_SHIFT         2    /* 2^2 -> 1/4 = 25% slack */\n#endif\n\n/* Initialization and finalization (compaction), converting to other types. */\n\n#define DUK_BW_INIT_PUSHBUF(thr,bw_ctx,sz) do { \\\n\t\tduk_bw_init_pushbuf((thr), (bw_ctx), (sz)); \\\n\t} while (0)\n#define DUK_BW_INIT_WITHBUF(thr,bw_ctx,buf) do { \\\n\t\tduk_bw_init((thr), (bw_ctx), (buf)); \\\n\t} while (0)\n#define DUK_BW_COMPACT(thr,bw_ctx) do { \\\n\t\t/* Make underlying buffer compact to match DUK_BW_GET_SIZE(). */ \\\n\t\tduk_bw_compact((thr), (bw_ctx)); \\\n\t} while (0)\n#define DUK_BW_PUSH_AS_STRING(thr,bw_ctx) do { \\\n\t\tduk_push_lstring((thr), \\\n\t\t                 (const char *) (bw_ctx)->p_base, \\\n\t\t                 (duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base)); \\\n\t} while (0)\n\n/* Pointers may be NULL for a while when 'buf' size is zero and before any\n * ENSURE calls have been made.  Once an ENSURE has been made, the pointers\n * are required to be non-NULL so that it's always valid to use memcpy() and\n * memmove(), even for zero size.\n */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_bw_assert_valid(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx);\n#define DUK_BW_ASSERT_VALID_EXPR(thr,bw_ctx)  (duk_bw_assert_valid((thr), (bw_ctx)))\n#define DUK_BW_ASSERT_VALID(thr,bw_ctx)  do { duk_bw_assert_valid((thr), (bw_ctx)); } while (0)\n#else\n#define DUK_BW_ASSERT_VALID_EXPR(thr,bw_ctx)  DUK_ASSERT_EXPR(1)\n#define DUK_BW_ASSERT_VALID(thr,bw_ctx)  do {} while (0)\n#endif\n\n/* Working with the pointer and current size. */\n\n#define DUK_BW_GET_PTR(thr,bw_ctx) \\\n\t((bw_ctx)->p)\n#define DUK_BW_SET_PTR(thr,bw_ctx,ptr) do { \\\n\t\t(bw_ctx)->p = (ptr); \\\n\t} while (0)\n#define DUK_BW_ADD_PTR(thr,bw_ctx,delta) do { \\\n\t\t(bw_ctx)->p += (delta); \\\n\t} while (0)\n#define DUK_BW_GET_BASEPTR(thr,bw_ctx) \\\n\t((bw_ctx)->p_base)\n#define DUK_BW_GET_LIMITPTR(thr,bw_ctx) \\\n\t((bw_ctx)->p_limit)\n#define DUK_BW_GET_SIZE(thr,bw_ctx) \\\n\t((duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base))\n#define DUK_BW_SET_SIZE(thr,bw_ctx,sz) do { \\\n\t\tDUK_ASSERT((duk_size_t) (sz) <= (duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base)); \\\n\t\t(bw_ctx)->p = (bw_ctx)->p_base + (sz); \\\n\t} while (0)\n#define DUK_BW_RESET_SIZE(thr,bw_ctx) do { \\\n\t\t/* Reset to zero size, keep current limit. */ \\\n\t\t(bw_ctx)->p = (bw_ctx)->p_base; \\\n\t} while (0)\n#define DUK_BW_GET_BUFFER(thr,bw_ctx) \\\n\t((bw_ctx)->buf)\n\n/* Ensuring (reserving) space. */\n\n#define DUK_BW_ENSURE(thr,bw_ctx,sz) do { \\\n\t\tduk_size_t duk__sz, duk__space; \\\n\t\tDUK_BW_ASSERT_VALID((thr), (bw_ctx)); \\\n\t\tduk__sz = (sz); \\\n\t\tduk__space = (duk_size_t) ((bw_ctx)->p_limit - (bw_ctx)->p); \\\n\t\tif (duk__space < duk__sz) { \\\n\t\t\t(void) duk_bw_resize((thr), (bw_ctx), duk__sz); \\\n\t\t} \\\n\t} while (0)\n/* NOTE: Multiple evaluation of 'ptr' in this macro. */\n/* XXX: Rework to use an always-inline function? */\n#define DUK_BW_ENSURE_RAW(thr,bw_ctx,sz,ptr) \\\n\t(((duk_size_t) ((bw_ctx)->p_limit - (ptr)) >= (sz)) ? \\\n\t (ptr) : \\\n\t ((bw_ctx)->p = (ptr), duk_bw_resize((thr),(bw_ctx),(sz))))\n#define DUK_BW_ENSURE_GETPTR(thr,bw_ctx,sz) \\\n\tDUK_BW_ENSURE_RAW((thr), (bw_ctx), (sz), (bw_ctx)->p)\n#define DUK_BW_ASSERT_SPACE_EXPR(thr,bw_ctx,sz) \\\n\t(DUK_BW_ASSERT_VALID_EXPR((thr), (bw_ctx)), \\\n\t DUK_ASSERT_EXPR((duk_size_t) ((bw_ctx)->p_limit - (bw_ctx)->p) >= (duk_size_t) (sz)))\n#define DUK_BW_ASSERT_SPACE(thr,bw_ctx,sz) do { \\\n\t\tDUK_BW_ASSERT_SPACE_EXPR((thr), (bw_ctx), (sz)); \\\n\t} while (0)\n\n/* Miscellaneous. */\n\n#define DUK_BW_SETPTR_AND_COMPACT(thr,bw_ctx,ptr) do { \\\n\t\t(bw_ctx)->p = (ptr); \\\n\t\tduk_bw_compact((thr), (bw_ctx)); \\\n\t} while (0)\n\n/* Fast write calls which assume you control the slack beforehand.\n * Multibyte write variants exist and use a temporary write pointer\n * because byte writes alias with anything: with a stored pointer\n * explicit pointer load/stores get generated (e.g. gcc -Os).\n */\n\n#define DUK_BW_WRITE_RAW_U8(thr,bw_ctx,val) do { \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 1); \\\n\t\t*(bw_ctx)->p++ = (duk_uint8_t) (val); \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_2(thr,bw_ctx,val1,val2) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 2); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_3(thr,bw_ctx,val1,val2,val3) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 3); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_4(thr,bw_ctx,val1,val2,val3,val4) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 4); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t*duk__p++ = (duk_uint8_t) (val4); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_5(thr,bw_ctx,val1,val2,val3,val4,val5) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 5); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t*duk__p++ = (duk_uint8_t) (val4); \\\n\t\t*duk__p++ = (duk_uint8_t) (val5); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_6(thr,bw_ctx,val1,val2,val3,val4,val5,val6) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 6); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t*duk__p++ = (duk_uint8_t) (val4); \\\n\t\t*duk__p++ = (duk_uint8_t) (val5); \\\n\t\t*duk__p++ = (duk_uint8_t) (val6); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_XUTF8(thr,bw_ctx,cp) do { \\\n\t\tduk_ucodepoint_t duk__cp; \\\n\t\tduk_small_int_t duk__enc_len; \\\n\t\tduk__cp = (duk_ucodepoint_t) (cp); \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), duk_unicode_get_xutf8_length(duk__cp)); \\\n\t\tduk__enc_len = duk_unicode_encode_xutf8(duk__cp, (bw_ctx)->p); \\\n\t\t(bw_ctx)->p += duk__enc_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_CESU8(thr,bw_ctx,cp) do { \\\n\t\tduk_ucodepoint_t duk__cp; \\\n\t\tduk_small_int_t duk__enc_len; \\\n\t\tduk__cp = (duk_ucodepoint_t) (cp); \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), duk_unicode_get_cesu8_length(duk__cp)); \\\n\t\tduk__enc_len = duk_unicode_encode_cesu8(duk__cp, (bw_ctx)->p); \\\n\t\t(bw_ctx)->p += duk__enc_len; \\\n\t} while (0)\n/* XXX: add temporary duk__p pointer here too; sharing */\n/* XXX: avoid unsafe variants */\n#define DUK_BW_WRITE_RAW_BYTES(thr,bw_ctx,valptr,valsz) do { \\\n\t\tconst void *duk__valptr; \\\n\t\tduk_size_t duk__valsz; \\\n\t\tduk__valptr = (const void *) (valptr); \\\n\t\tduk__valsz = (duk_size_t) (valsz); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), duk__valptr, duk__valsz); \\\n\t\t(bw_ctx)->p += duk__valsz; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_CSTRING(thr,bw_ctx,val) do { \\\n\t\tconst duk_uint8_t *duk__val; \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val = (const duk_uint8_t *) (val); \\\n\t\tduk__val_len = DUK_STRLEN((const char *) duk__val); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) duk__val, duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HSTRING(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HSTRING_GET_BYTELEN((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HSTRING_GET_DATA((val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HBUFFER(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_GET_SIZE((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HBUFFER_FIXED(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_FIXED_GET_SIZE((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_FIXED_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HBUFFER_DYNAMIC(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_DYNAMIC_GET_SIZE((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n\n/* Append bytes from a slice already in the buffer. */\n#define DUK_BW_WRITE_RAW_SLICE(thr,bw,dst_off,dst_len) \\\n\tduk_bw_write_raw_slice((thr), (bw), (dst_off), (dst_len))\n\n/* Insert bytes in the middle of the buffer from an external buffer. */\n#define DUK_BW_INSERT_RAW_BYTES(thr,bw,dst_off,buf,len) \\\n\tduk_bw_insert_raw_bytes((thr), (bw), (dst_off), (buf), (len))\n\n/* Insert bytes in the middle of the buffer from a slice already\n * in the buffer.  Source offset is interpreted \"before\" the operation.\n */\n#define DUK_BW_INSERT_RAW_SLICE(thr,bw,dst_off,src_off,len) \\\n\tduk_bw_insert_raw_slice((thr), (bw), (dst_off), (src_off), (len))\n\n/* Insert a reserved area somewhere in the buffer; caller fills it.\n * Evaluates to a (duk_uint_t *) pointing to the start of the reserved\n * area for convenience.\n */\n#define DUK_BW_INSERT_RAW_AREA(thr,bw,off,len) \\\n\tduk_bw_insert_raw_area((thr), (bw), (off), (len))\n\n/* Remove a slice from inside buffer. */\n#define DUK_BW_REMOVE_RAW_SLICE(thr,bw,off,len) \\\n\tduk_bw_remove_raw_slice((thr), (bw), (off), (len))\n\n/* Safe write calls which will ensure space first. */\n\n#define DUK_BW_WRITE_ENSURE_U8(thr,bw_ctx,val) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 1); \\\n\t\tDUK_BW_WRITE_RAW_U8((thr), (bw_ctx), (val)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_2(thr,bw_ctx,val1,val2) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 2); \\\n\t\tDUK_BW_WRITE_RAW_U8_2((thr), (bw_ctx), (val1), (val2)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_3(thr,bw_ctx,val1,val2,val3) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 3); \\\n\t\tDUK_BW_WRITE_RAW_U8_3((thr), (bw_ctx), (val1), (val2), (val3)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_4(thr,bw_ctx,val1,val2,val3,val4) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 4); \\\n\t\tDUK_BW_WRITE_RAW_U8_4((thr), (bw_ctx), (val1), (val2), (val3), (val4)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_5(thr,bw_ctx,val1,val2,val3,val4,val5) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 5); \\\n\t\tDUK_BW_WRITE_RAW_U8_5((thr), (bw_ctx), (val1), (val2), (val3), (val4), (val5)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_6(thr,bw_ctx,val1,val2,val3,val4,val5,val6) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 6); \\\n\t\tDUK_BW_WRITE_RAW_U8_6((thr), (bw_ctx), (val1), (val2), (val3), (val4), (val5), (val6)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_XUTF8(thr,bw_ctx,cp) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), DUK_UNICODE_MAX_XUTF8_LENGTH); \\\n\t\tDUK_BW_WRITE_RAW_XUTF8((thr), (bw_ctx), (cp)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_CESU8(thr,bw_ctx,cp) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), DUK_UNICODE_MAX_CESU8_LENGTH); \\\n\t\tDUK_BW_WRITE_RAW_CESU8((thr), (bw_ctx), (cp)); \\\n\t} while (0)\n/* XXX: add temporary duk__p pointer here too; sharing */\n/* XXX: avoid unsafe */\n#define DUK_BW_WRITE_ENSURE_BYTES(thr,bw_ctx,valptr,valsz) do { \\\n\t\tconst void *duk__valptr; \\\n\t\tduk_size_t duk__valsz; \\\n\t\tduk__valptr = (const void *) (valptr); \\\n\t\tduk__valsz = (duk_size_t) (valsz); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__valsz); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), duk__valptr, duk__valsz); \\\n\t\t(bw_ctx)->p += duk__valsz; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_CSTRING(thr,bw_ctx,val) do { \\\n\t\tconst duk_uint8_t *duk__val; \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val = (const duk_uint8_t *) (val); \\\n\t\tduk__val_len = DUK_STRLEN((const char *) duk__val); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) duk__val, duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HSTRING(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HSTRING_GET_BYTELEN((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HSTRING_GET_DATA((val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HBUFFER(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_GET_SIZE((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HBUFFER_FIXED(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_FIXED_GET_SIZE((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_FIXED_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HBUFFER_DYNAMIC(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_DYNAMIC_GET_SIZE((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n\n#define DUK_BW_WRITE_ENSURE_SLICE(thr,bw,dst_off,dst_len) \\\n\tduk_bw_write_ensure_slice((thr), (bw), (dst_off), (dst_len))\n#define DUK_BW_INSERT_ENSURE_BYTES(thr,bw,dst_off,buf,len) \\\n\tduk_bw_insert_ensure_bytes((thr), (bw), (dst_off), (buf), (len))\n#define DUK_BW_INSERT_ENSURE_SLICE(thr,bw,dst_off,src_off,len) \\\n\tduk_bw_insert_ensure_slice((thr), (bw), (dst_off), (src_off), (len))\n#define DUK_BW_INSERT_ENSURE_AREA(thr,bw,off,len) \\\n\t/* Evaluates to (duk_uint8_t *) pointing to start of area. */ \\\n\tduk_bw_insert_ensure_area((thr), (bw), (off), (len))\n#define DUK_BW_REMOVE_ENSURE_SLICE(thr,bw,off,len) \\\n\t/* No difference between raw/ensure because the buffer shrinks. */ \\\n\tDUK_BW_REMOVE_RAW_SLICE((thr), (bw), (off), (len))\n\n/*\n *  Externs and prototypes\n */\n\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_lc_digits[36];\nDUK_INTERNAL_DECL const duk_uint8_t duk_uc_nybbles[16];\nDUK_INTERNAL_DECL const duk_int8_t duk_hex_dectab[256];\n#if defined(DUK_USE_HEX_FASTPATH)\nDUK_INTERNAL_DECL const duk_int16_t duk_hex_dectab_shift4[256];\nDUK_INTERNAL_DECL const duk_uint16_t duk_hex_enctab[256];\n#endif\n#endif  /* !DUK_SINGLE_FILE */\n\n/* Note: assumes that duk_util_probe_steps size is 32 */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL duk_uint8_t duk_util_probe_steps[32];\n#endif  /* !DUK_SINGLE_FILE */\n#endif\n\n#if defined(DUK_USE_STRHASH_DENSE)\nDUK_INTERNAL_DECL duk_uint32_t duk_util_hashbytes(const duk_uint8_t *data, duk_size_t len, duk_uint32_t seed);\n#endif\n\nDUK_INTERNAL_DECL duk_uint32_t duk_bd_decode(duk_bitdecoder_ctx *ctx, duk_small_int_t bits);\nDUK_INTERNAL_DECL duk_small_uint_t duk_bd_decode_flag(duk_bitdecoder_ctx *ctx);\nDUK_INTERNAL_DECL duk_uint32_t duk_bd_decode_flagged(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_uint32_t def_value);\nDUK_INTERNAL_DECL duk_int32_t duk_bd_decode_flagged_signed(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_int32_t def_value);\nDUK_INTERNAL_DECL duk_uint32_t duk_bd_decode_varuint(duk_bitdecoder_ctx *ctx);\nDUK_INTERNAL_DECL duk_small_uint_t duk_bd_decode_bitpacked_string(duk_bitdecoder_ctx *bd, duk_uint8_t *out);\n\nDUK_INTERNAL_DECL void duk_be_encode(duk_bitencoder_ctx *ctx, duk_uint32_t data, duk_small_int_t bits);\nDUK_INTERNAL_DECL void duk_be_finish(duk_bitencoder_ctx *ctx);\n\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\nDUK_INTERNAL_DECL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL void duk_bw_init(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_hbuffer_dynamic *h_buf);\nDUK_INTERNAL_DECL void duk_bw_init_pushbuf(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t buf_size);\nDUK_INTERNAL_DECL duk_uint8_t *duk_bw_resize(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t sz);\nDUK_INTERNAL_DECL void duk_bw_compact(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx);\nDUK_INTERNAL_DECL void duk_bw_write_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_write_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_raw_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_ensure_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL duk_uint8_t *duk_bw_insert_raw_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len);\nDUK_INTERNAL_DECL duk_uint8_t *duk_bw_insert_ensure_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len);\n/* No duk_bw_remove_ensure_slice(), functionality would be identical. */\n\nDUK_INTERNAL_DECL duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p);\nDUK_INTERNAL_DECL duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p);\nDUK_INTERNAL_DECL duk_double_t duk_raw_read_double_be(duk_uint8_t **p);\nDUK_INTERNAL_DECL void duk_raw_write_u16_be(duk_uint8_t **p, duk_uint16_t val);\nDUK_INTERNAL_DECL void duk_raw_write_u32_be(duk_uint8_t **p, duk_uint32_t val);\nDUK_INTERNAL_DECL void duk_raw_write_double_be(duk_uint8_t **p, duk_double_t val);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* For now only needed by the debugger. */\nDUK_INTERNAL_DECL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len);\n#endif\n\n/* memcpy(), memmove() etc wrappers.  The plain variants like duk_memcpy()\n * assume C99+ and 'src' and 'dst' pointers must be non-NULL even when the\n * operation size is zero.  The unsafe variants like duk_memcpy_safe() deal\n * with the zero size case explicitly, and allow NULL pointers in that case\n * (which is undefined behavior in C99+).  For the majority of actual targets\n * a NULL pointer with a zero length is fine in practice.  These wrappers are\n * macros to force inlining; because there are hundreds of call sites, even a\n * few extra bytes per call site adds up to ~1kB footprint.\n */\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n#define duk_memcpy(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memcpy_unsafe(dst,src,len)  duk_memcpy((dst), (src), (len))\n#define duk_memmove(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memmove_unsafe(dst,src,len)  duk_memmove((dst), (src), (len))\n#define duk_memset(dst,val,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_small_int_t duk__val = (val); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memset_unsafe(dst,val,len)  duk_memset((dst), (val), (len))\n#define duk_memzero(dst,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memzero_unsafe(dst,len)  duk_memzero((dst), (len))\n#else  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\n#define duk_memcpy(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t(void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memcpy_unsafe(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t\t(void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#define duk_memmove(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t(void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memmove_unsafe(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t\t(void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#define duk_memset(dst,val,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_small_int_t duk__val = (val); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t(void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memset_unsafe(dst,val,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_small_int_t duk__val = (val); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\t(void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#define duk_memzero(dst,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t(void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memzero_unsafe(dst,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\t(void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#endif  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\n\nDUK_INTERNAL_DECL duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len);\nDUK_INTERNAL_DECL duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len);\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_whole_get_int32_nonegzero(duk_double_t x, duk_int32_t *ival);\nDUK_INTERNAL_DECL duk_bool_t duk_is_whole_get_int32(duk_double_t x, duk_int32_t *ival);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_anyinf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_posinf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_neginf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_or_zero(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_or_inf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_zero_inf(duk_double_t x);\nDUK_INTERNAL_DECL duk_small_uint_t duk_double_signbit(duk_double_t x);\nDUK_INTERNAL_DECL duk_double_t duk_double_trunc_towards_zero(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_same_sign(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_double_t duk_double_fmin(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_finite(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_integer(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_safe_integer(duk_double_t x);\n\nDUK_INTERNAL_DECL duk_double_t duk_double_div(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_int_t duk_double_to_int_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_uint_t duk_double_to_uint_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_int32_t duk_double_to_int32_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_uint32_t duk_double_to_uint32_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_float_t duk_double_to_float_t(duk_double_t x);\n\n/*\n *  Miscellaneous\n */\n\n/* Example: x     = 0x10 = 0b00010000\n *          x - 1 = 0x0f = 0b00001111\n *          x & (x - 1) == 0\n *\n *          x     = 0x07 = 0b00000111\n *          x - 1 = 0x06 = 0b00000110\n *          x & (x - 1) != 0\n *\n * However, incorrectly true for x == 0 so check for that explicitly.\n */\n#define DUK_IS_POWER_OF_TWO(x) \\\n\t((x) != 0U && ((x) & ((x) - 1U)) == 0U)\n\n#endif  /* DUK_UTIL_H_INCLUDED */\n/* #include duk_strings.h */\n/*\n *  Shared string macros.\n *\n *  Using shared macros helps minimize strings data size because it's easy\n *  to check if an existing string could be used.  String constants don't\n *  need to be all defined here; defining a string here makes sense if there's\n *  a high chance the string could be reused.  Also, using macros allows\n *  a call site express the exact string needed, but the macro may map to an\n *  approximate string to reduce unique string count.  Macros can also be\n *  more easily tuned for low memory targets than #if defined()s throughout\n *  the code base.\n *\n *  Because format strings behave differently in the call site (they need to\n *  be followed by format arguments), they use a special prefix DUK_STR_FMT_.\n *\n *  On some compilers using explicit shared strings is preferable; on others\n *  it may be better to use straight literals because the compiler will combine\n *  them anyway, and such strings won't end up unnecessarily in a symbol table.\n */\n\n#if !defined(DUK_ERRMSG_H_INCLUDED)\n#define DUK_ERRMSG_H_INCLUDED\n\n/* Mostly API and built-in method related */\n#define DUK_STR_INTERNAL_ERROR                   \"internal error\"\n#define DUK_STR_UNSUPPORTED                      \"unsupported\"\n#define DUK_STR_INVALID_COUNT                    \"invalid count\"\n#define DUK_STR_INVALID_ARGS                     \"invalid args\"\n#define DUK_STR_INVALID_STATE                    \"invalid state\"\n#define DUK_STR_INVALID_INPUT                    \"invalid input\"\n#define DUK_STR_INVALID_LENGTH                   \"invalid length\"\n#define DUK_STR_NOT_CONSTRUCTABLE                \"not constructable\"\n#define DUK_STR_CONSTRUCT_ONLY                   \"constructor requires 'new'\"\n#define DUK_STR_NOT_CALLABLE                     \"not callable\"\n#define DUK_STR_NOT_EXTENSIBLE                   \"not extensible\"\n#define DUK_STR_NOT_WRITABLE                     \"not writable\"\n#define DUK_STR_NOT_CONFIGURABLE                 \"not configurable\"\n#define DUK_STR_INVALID_CONTEXT                  \"invalid context\"\n#define DUK_STR_INVALID_INDEX                    \"invalid args\"\n#define DUK_STR_PUSH_BEYOND_ALLOC_STACK          \"cannot push beyond allocated stack\"\n#define DUK_STR_NOT_UNDEFINED                    \"unexpected type\"\n#define DUK_STR_NOT_NULL                         \"unexpected type\"\n#define DUK_STR_NOT_BOOLEAN                      \"unexpected type\"\n#define DUK_STR_NOT_NUMBER                       \"unexpected type\"\n#define DUK_STR_NOT_STRING                       \"unexpected type\"\n#define DUK_STR_NOT_OBJECT                       \"unexpected type\"\n#define DUK_STR_NOT_POINTER                      \"unexpected type\"\n#define DUK_STR_NOT_BUFFER                       \"not buffer\"  /* still in use with verbose messages */\n#define DUK_STR_UNEXPECTED_TYPE                  \"unexpected type\"\n#define DUK_STR_NOT_THREAD                       \"unexpected type\"\n#define DUK_STR_NOT_COMPFUNC                     \"unexpected type\"\n#define DUK_STR_NOT_NATFUNC                      \"unexpected type\"\n#define DUK_STR_NOT_C_FUNCTION                   \"unexpected type\"\n#define DUK_STR_NOT_FUNCTION                     \"unexpected type\"\n#define DUK_STR_NOT_REGEXP                       \"unexpected type\"\n#define DUK_STR_TOPRIMITIVE_FAILED               \"coercion to primitive failed\"\n#define DUK_STR_NUMBER_OUTSIDE_RANGE             \"number outside range\"\n#define DUK_STR_NOT_OBJECT_COERCIBLE             \"not object coercible\"\n#define DUK_STR_CANNOT_NUMBER_COERCE_SYMBOL      \"cannot number coerce Symbol\"\n#define DUK_STR_CANNOT_STRING_COERCE_SYMBOL      \"cannot string coerce Symbol\"\n#define DUK_STR_STRING_TOO_LONG                  \"string too long\"\n#define DUK_STR_BUFFER_TOO_LONG                  \"buffer too long\"\n#define DUK_STR_ALLOC_FAILED                     \"alloc failed\"\n#define DUK_STR_WRONG_BUFFER_TYPE                \"wrong buffer type\"\n#define DUK_STR_BASE64_ENCODE_FAILED             \"base64 encode failed\"\n#define DUK_STR_SOURCE_DECODE_FAILED             \"source decode failed\"\n#define DUK_STR_UTF8_DECODE_FAILED               \"utf-8 decode failed\"\n#define DUK_STR_BASE64_DECODE_FAILED             \"base64 decode failed\"\n#define DUK_STR_HEX_DECODE_FAILED                \"hex decode failed\"\n#define DUK_STR_INVALID_BYTECODE                 \"invalid bytecode\"\n#define DUK_STR_NO_SOURCECODE                    \"no sourcecode\"\n#define DUK_STR_RESULT_TOO_LONG                  \"result too long\"\n#define DUK_STR_INVALID_CFUNC_RC                 \"invalid C function rc\"\n#define DUK_STR_INVALID_INSTANCEOF_RVAL          \"invalid instanceof rval\"\n#define DUK_STR_INVALID_INSTANCEOF_RVAL_NOPROTO  \"instanceof rval has no .prototype\"\n\n/* JSON */\n#define DUK_STR_FMT_PTR                          \"%p\"\n#define DUK_STR_FMT_INVALID_JSON                 \"invalid json (at offset %ld)\"\n#define DUK_STR_JSONDEC_RECLIMIT                 \"json decode recursion limit\"\n#define DUK_STR_JSONENC_RECLIMIT                 \"json encode recursion limit\"\n#define DUK_STR_CYCLIC_INPUT                     \"cyclic input\"\n\n/* Object property access */\n#define DUK_STR_INVALID_BASE                     \"invalid base value\"\n#define DUK_STR_STRICT_CALLER_READ               \"cannot read strict 'caller'\"\n#define DUK_STR_PROXY_REJECTED                   \"proxy rejected\"\n#define DUK_STR_INVALID_ARRAY_LENGTH             \"invalid array length\"\n#define DUK_STR_SETTER_UNDEFINED                 \"setter undefined\"\n#define DUK_STR_INVALID_DESCRIPTOR               \"invalid descriptor\"\n\n/* Proxy */\n#define DUK_STR_PROXY_REVOKED                    \"proxy revoked\"\n#define DUK_STR_INVALID_TRAP_RESULT              \"invalid trap result\"\n\n/* Variables */\n\n/* Lexer */\n#define DUK_STR_INVALID_ESCAPE                   \"invalid escape\"\n#define DUK_STR_UNTERMINATED_STRING              \"unterminated string\"\n#define DUK_STR_UNTERMINATED_COMMENT             \"unterminated comment\"\n#define DUK_STR_UNTERMINATED_REGEXP              \"unterminated regexp\"\n#define DUK_STR_TOKEN_LIMIT                      \"token limit\"\n#define DUK_STR_REGEXP_SUPPORT_DISABLED          \"regexp support disabled\"\n#define DUK_STR_INVALID_NUMBER_LITERAL           \"invalid number literal\"\n#define DUK_STR_INVALID_TOKEN                    \"invalid token\"\n\n/* Compiler */\n#define DUK_STR_PARSE_ERROR                      \"parse error\"\n#define DUK_STR_DUPLICATE_LABEL                  \"duplicate label\"\n#define DUK_STR_INVALID_LABEL                    \"invalid label\"\n#define DUK_STR_INVALID_ARRAY_LITERAL            \"invalid array literal\"\n#define DUK_STR_INVALID_OBJECT_LITERAL           \"invalid object literal\"\n#define DUK_STR_INVALID_VAR_DECLARATION          \"invalid variable declaration\"\n#define DUK_STR_CANNOT_DELETE_IDENTIFIER         \"cannot delete identifier\"\n#define DUK_STR_INVALID_EXPRESSION               \"invalid expression\"\n#define DUK_STR_INVALID_LVALUE                   \"invalid lvalue\"\n#define DUK_STR_INVALID_NEWTARGET                \"invalid new.target\"\n#define DUK_STR_EXPECTED_IDENTIFIER              \"expected identifier\"\n#define DUK_STR_EMPTY_EXPR_NOT_ALLOWED           \"empty expression not allowed\"\n#define DUK_STR_INVALID_FOR                      \"invalid for statement\"\n#define DUK_STR_INVALID_SWITCH                   \"invalid switch statement\"\n#define DUK_STR_INVALID_BREAK_CONT_LABEL         \"invalid break/continue label\"\n#define DUK_STR_INVALID_RETURN                   \"invalid return\"\n#define DUK_STR_INVALID_TRY                      \"invalid try\"\n#define DUK_STR_INVALID_THROW                    \"invalid throw\"\n#define DUK_STR_WITH_IN_STRICT_MODE              \"with in strict mode\"\n#define DUK_STR_FUNC_STMT_NOT_ALLOWED            \"function statement not allowed\"\n#define DUK_STR_UNTERMINATED_STMT                \"unterminated statement\"\n#define DUK_STR_INVALID_ARG_NAME                 \"invalid argument name\"\n#define DUK_STR_INVALID_FUNC_NAME                \"invalid function name\"\n#define DUK_STR_INVALID_GETSET_NAME              \"invalid getter/setter name\"\n#define DUK_STR_FUNC_NAME_REQUIRED               \"function name required\"\n\n/* RegExp */\n#define DUK_STR_INVALID_QUANTIFIER               \"invalid regexp quantifier\"\n#define DUK_STR_INVALID_QUANTIFIER_NO_ATOM       \"quantifier without preceding atom\"\n#define DUK_STR_INVALID_QUANTIFIER_VALUES        \"quantifier values invalid (qmin > qmax)\"\n#define DUK_STR_QUANTIFIER_TOO_MANY_COPIES       \"quantifier requires too many atom copies\"\n#define DUK_STR_UNEXPECTED_CLOSING_PAREN         \"unexpected closing parenthesis\"\n#define DUK_STR_UNEXPECTED_END_OF_PATTERN        \"unexpected end of pattern\"\n#define DUK_STR_UNEXPECTED_REGEXP_TOKEN          \"unexpected token in regexp\"\n#define DUK_STR_INVALID_REGEXP_FLAGS             \"invalid regexp flags\"\n#define DUK_STR_INVALID_REGEXP_ESCAPE            \"invalid regexp escape\"\n#define DUK_STR_INVALID_BACKREFS                 \"invalid backreference(s)\"\n#define DUK_STR_INVALID_REGEXP_CHARACTER         \"invalid regexp character\"\n#define DUK_STR_INVALID_REGEXP_GROUP             \"invalid regexp group\"\n#define DUK_STR_UNTERMINATED_CHARCLASS           \"unterminated character class\"\n#define DUK_STR_INVALID_RANGE                    \"invalid range\"\n\n/* Limits */\n#define DUK_STR_VALSTACK_LIMIT                   \"valstack limit\"\n#define DUK_STR_CALLSTACK_LIMIT                  \"callstack limit\"\n#define DUK_STR_PROTOTYPE_CHAIN_LIMIT            \"prototype chain limit\"\n#define DUK_STR_BOUND_CHAIN_LIMIT                \"function call bound chain limit\"\n#define DUK_STR_NATIVE_STACK_LIMIT               \"C stack depth limit\"\n#define DUK_STR_COMPILER_RECURSION_LIMIT         \"compiler recursion limit\"\n#define DUK_STR_BYTECODE_LIMIT                   \"bytecode limit\"\n#define DUK_STR_REG_LIMIT                        \"register limit\"\n#define DUK_STR_TEMP_LIMIT                       \"temp limit\"\n#define DUK_STR_CONST_LIMIT                      \"const limit\"\n#define DUK_STR_FUNC_LIMIT                       \"function limit\"\n#define DUK_STR_REGEXP_COMPILER_RECURSION_LIMIT  \"regexp compiler recursion limit\"\n#define DUK_STR_REGEXP_EXECUTOR_RECURSION_LIMIT  \"regexp executor recursion limit\"\n#define DUK_STR_REGEXP_EXECUTOR_STEP_LIMIT       \"regexp step limit\"\n\n#endif  /* DUK_ERRMSG_H_INCLUDED */\n/* #include duk_js_bytecode.h */\n/*\n *  ECMAScript bytecode\n */\n\n#if !defined(DUK_JS_BYTECODE_H_INCLUDED)\n#define DUK_JS_BYTECODE_H_INCLUDED\n\n/*\n *  Bytecode instruction layout\n *  ===========================\n *\n *  Instructions are unsigned 32-bit integers divided as follows:\n *\n *  !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! !\n *  !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!\n *  +-----------------------------------------------+---------------+\n *  !       C       !       B       !       A       !       OP      !\n *  +-----------------------------------------------+---------------+\n *\n *  OP (8 bits):  opcode (DUK_OP_*), access should be fastest\n *                consecutive opcodes allocated when opcode needs flags\n *   A (8 bits):  typically a target register number\n *   B (8 bits):  typically first source register/constant number\n *   C (8 bits):  typically second source register/constant number\n *\n *  Some instructions combine BC or ABC together for larger parameter values.\n *  Signed integers (e.g. jump offsets) are encoded as unsigned, with an\n *  opcode specific bias.\n *\n *  Some opcodes have flags which are handled by allocating consecutive\n *  opcodes to make space for 1-N flags.  Flags can also be e.g. in the 'A'\n *  field when there's room for the specific opcode.\n *\n *  For example, if three flags were needed, they could be allocated from\n *  the opcode field as follows:\n *\n *  !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! !\n *  !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!\n *  +-----------------------------------------------+---------------+\n *  !       C       !       B       !       A       !    OP   !Z!Y!X!\n *  +-----------------------------------------------+---------------+\n *\n *  Some opcodes accept a reg/const argument which is handled by allocating\n *  flags in the OP field, see DUK_BC_ISREG() and DUK_BC_ISCONST().  The\n *  following convention is shared by most opcodes, so that the compiler\n *  can handle reg/const flagging without opcode specific code paths:\n *\n *  !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! !\n *  !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!\n *  +-----------------------------------------------+---------------+\n *  !       C       !       B       !       A       !     OP    !Y!X!\n *  +-----------------------------------------------+---------------+\n *\n *    X  1=B is const, 0=B is reg\n *    Y  1=C is const, 0=C is reg\n *\n *    In effect OP, OP + 1, OP + 2, and OP + 3 are allocated from the\n *    8-bit opcode space for a single logical opcode.  The base opcode\n *    number should be divisible by 4.  If the opcode is called 'FOO'\n *    the following opcode constants would be defined:\n *\n *      DUK_OP_FOO     100       // base opcode number\n *      DUK_OP_FOO_RR  100       // FOO, B=reg, C=reg\n *      DUK_OP_FOO_CR  101       // FOO, B=const, C=reg\n *      DUK_OP_FOO_RC  102       // FOO, B=reg, C=const\n *      DUK_OP_FOO_CC  103       // FOO, B=const, C=const\n *\n *  If only B or C is a reg/const, the unused opcode combinations can be\n *  used for other opcodes (which take no reg/const argument).  However,\n *  such opcode values are initially reserved, at least while opcode space\n *  is available.  For example, if 'BAR' uses B for a register field and\n *  C is a reg/const:\n *\n *      DUK_OP_BAR            116    // base opcode number\n *      DUK_OP_BAR_RR         116    // BAR, B=reg, C=reg\n *      DUK_OP_BAR_CR_UNUSED  117    // unused, could be repurposed\n *      DUK_OP_BAR_RC         118    // BAR, B=reg, C=const\n *      DUK_OP_BAR_CC_UNUSED  119    // unused, could be repurposed\n *\n *  Macro naming is a bit misleading, e.g. \"ABC\" in macro name but the\n *  field layout is concretely \"CBA\" in the register.\n */\n\ntypedef duk_uint32_t duk_instr_t;\n\n#define DUK_BC_SHIFT_OP             0\n#define DUK_BC_SHIFT_A              8\n#define DUK_BC_SHIFT_B              16\n#define DUK_BC_SHIFT_C              24\n#define DUK_BC_SHIFT_BC             DUK_BC_SHIFT_B\n#define DUK_BC_SHIFT_ABC            DUK_BC_SHIFT_A\n\n#define DUK_BC_UNSHIFTED_MASK_OP    0xffUL\n#define DUK_BC_UNSHIFTED_MASK_A     0xffUL\n#define DUK_BC_UNSHIFTED_MASK_B     0xffUL\n#define DUK_BC_UNSHIFTED_MASK_C     0xffUL\n#define DUK_BC_UNSHIFTED_MASK_BC    0xffffUL\n#define DUK_BC_UNSHIFTED_MASK_ABC   0xffffffUL\n\n#define DUK_BC_SHIFTED_MASK_OP      (DUK_BC_UNSHIFTED_MASK_OP << DUK_BC_SHIFT_OP)\n#define DUK_BC_SHIFTED_MASK_A       (DUK_BC_UNSHIFTED_MASK_A << DUK_BC_SHIFT_A)\n#define DUK_BC_SHIFTED_MASK_B       (DUK_BC_UNSHIFTED_MASK_B << DUK_BC_SHIFT_B)\n#define DUK_BC_SHIFTED_MASK_C       (DUK_BC_UNSHIFTED_MASK_C << DUK_BC_SHIFT_C)\n#define DUK_BC_SHIFTED_MASK_BC      (DUK_BC_UNSHIFTED_MASK_BC << DUK_BC_SHIFT_BC)\n#define DUK_BC_SHIFTED_MASK_ABC     (DUK_BC_UNSHIFTED_MASK_ABC << DUK_BC_SHIFT_ABC)\n\n#define DUK_DEC_OP(x)               ((x) & 0xffUL)\n#define DUK_DEC_A(x)                (((x) >> 8) & 0xffUL)\n#define DUK_DEC_B(x)                (((x) >> 16) & 0xffUL)\n#define DUK_DEC_C(x)                (((x) >> 24) & 0xffUL)\n#define DUK_DEC_BC(x)               (((x) >> 16) & 0xffffUL)\n#define DUK_DEC_ABC(x)              (((x) >> 8) & 0xffffffUL)\n\n#define DUK_ENC_OP(op)              ((duk_instr_t) (op))\n#define DUK_ENC_OP_ABC(op,abc)      ((duk_instr_t) ( \\\n                                        (((duk_instr_t) (abc)) << 8) | \\\n                                        ((duk_instr_t) (op)) \\\n                                    ))\n#define DUK_ENC_OP_A_BC(op,a,bc)    ((duk_instr_t) ( \\\n                                        (((duk_instr_t) (bc)) << 16) | \\\n                                        (((duk_instr_t) (a)) << 8) | \\\n                                        ((duk_instr_t) (op)) \\\n                                    ))\n#define DUK_ENC_OP_A_B_C(op,a,b,c)  ((duk_instr_t) ( \\\n                                        (((duk_instr_t) (c)) << 24) | \\\n                                        (((duk_instr_t) (b)) << 16) | \\\n                                        (((duk_instr_t) (a)) << 8) | \\\n                                        ((duk_instr_t) (op)) \\\n                                    ))\n#define DUK_ENC_OP_A_B(op,a,b)      DUK_ENC_OP_A_B_C((op),(a),(b),0)\n#define DUK_ENC_OP_A(op,a)          DUK_ENC_OP_A_B_C((op),(a),0,0)\n#define DUK_ENC_OP_BC(op,bc)        DUK_ENC_OP_A_BC((op),0,(bc))\n\n/* Get opcode base value with B/C reg/const flags cleared. */\n#define DUK_BC_NOREGCONST_OP(op)    ((op) & 0xfc)\n\n/* Constants should be signed so that signed arithmetic involving them\n * won't cause values to be coerced accidentally to unsigned.\n */\n#define DUK_BC_OP_MIN               0\n#define DUK_BC_OP_MAX               0xffL\n#define DUK_BC_A_MIN                0\n#define DUK_BC_A_MAX                0xffL\n#define DUK_BC_B_MIN                0\n#define DUK_BC_B_MAX                0xffL\n#define DUK_BC_C_MIN                0\n#define DUK_BC_C_MAX                0xffL\n#define DUK_BC_BC_MIN               0\n#define DUK_BC_BC_MAX               0xffffL\n#define DUK_BC_ABC_MIN              0\n#define DUK_BC_ABC_MAX              0xffffffL\n\n/* Masks for B/C reg/const indicator in opcode field. */\n#define DUK_BC_REGCONST_B           (0x01UL)\n#define DUK_BC_REGCONST_C           (0x02UL)\n\n/* Misc. masks for opcode field. */\n#define DUK_BC_INCDECP_FLAG_DEC     (0x04UL)\n#define DUK_BC_INCDECP_FLAG_POST    (0x08UL)\n\n/* Opcodes. */\n#define DUK_OP_LDREG                0\n#define DUK_OP_STREG                1\n#define DUK_OP_JUMP                 2\n#define DUK_OP_LDCONST              3\n#define DUK_OP_LDINT                4\n#define DUK_OP_LDINTX               5\n#define DUK_OP_LDTHIS               6\n#define DUK_OP_LDUNDEF              7\n#define DUK_OP_LDNULL               8\n#define DUK_OP_LDTRUE               9\n#define DUK_OP_LDFALSE              10\n#define DUK_OP_GETVAR               11\n#define DUK_OP_BNOT                 12\n#define DUK_OP_LNOT                 13\n#define DUK_OP_UNM                  14\n#define DUK_OP_UNP                  15\n#define DUK_OP_EQ                   16\n#define DUK_OP_EQ_RR                16\n#define DUK_OP_EQ_CR                17\n#define DUK_OP_EQ_RC                18\n#define DUK_OP_EQ_CC                19\n#define DUK_OP_NEQ                  20\n#define DUK_OP_NEQ_RR               20\n#define DUK_OP_NEQ_CR               21\n#define DUK_OP_NEQ_RC               22\n#define DUK_OP_NEQ_CC               23\n#define DUK_OP_SEQ                  24\n#define DUK_OP_SEQ_RR               24\n#define DUK_OP_SEQ_CR               25\n#define DUK_OP_SEQ_RC               26\n#define DUK_OP_SEQ_CC               27\n#define DUK_OP_SNEQ                 28\n#define DUK_OP_SNEQ_RR              28\n#define DUK_OP_SNEQ_CR              29\n#define DUK_OP_SNEQ_RC              30\n#define DUK_OP_SNEQ_CC              31\n#define DUK_OP_GT                   32\n#define DUK_OP_GT_RR                32\n#define DUK_OP_GT_CR                33\n#define DUK_OP_GT_RC                34\n#define DUK_OP_GT_CC                35\n#define DUK_OP_GE                   36\n#define DUK_OP_GE_RR                36\n#define DUK_OP_GE_CR                37\n#define DUK_OP_GE_RC                38\n#define DUK_OP_GE_CC                39\n#define DUK_OP_LT                   40\n#define DUK_OP_LT_RR                40\n#define DUK_OP_LT_CR                41\n#define DUK_OP_LT_RC                42\n#define DUK_OP_LT_CC                43\n#define DUK_OP_LE                   44\n#define DUK_OP_LE_RR                44\n#define DUK_OP_LE_CR                45\n#define DUK_OP_LE_RC                46\n#define DUK_OP_LE_CC                47\n#define DUK_OP_IFTRUE               48\n#define DUK_OP_IFTRUE_R             48\n#define DUK_OP_IFTRUE_C             49\n#define DUK_OP_IFFALSE              50\n#define DUK_OP_IFFALSE_R            50\n#define DUK_OP_IFFALSE_C            51\n#define DUK_OP_ADD                  52\n#define DUK_OP_ADD_RR               52\n#define DUK_OP_ADD_CR               53\n#define DUK_OP_ADD_RC               54\n#define DUK_OP_ADD_CC               55\n#define DUK_OP_SUB                  56\n#define DUK_OP_SUB_RR               56\n#define DUK_OP_SUB_CR               57\n#define DUK_OP_SUB_RC               58\n#define DUK_OP_SUB_CC               59\n#define DUK_OP_MUL                  60\n#define DUK_OP_MUL_RR               60\n#define DUK_OP_MUL_CR               61\n#define DUK_OP_MUL_RC               62\n#define DUK_OP_MUL_CC               63\n#define DUK_OP_DIV                  64\n#define DUK_OP_DIV_RR               64\n#define DUK_OP_DIV_CR               65\n#define DUK_OP_DIV_RC               66\n#define DUK_OP_DIV_CC               67\n#define DUK_OP_MOD                  68\n#define DUK_OP_MOD_RR               68\n#define DUK_OP_MOD_CR               69\n#define DUK_OP_MOD_RC               70\n#define DUK_OP_MOD_CC               71\n#define DUK_OP_EXP                  72\n#define DUK_OP_EXP_RR               72\n#define DUK_OP_EXP_CR               73\n#define DUK_OP_EXP_RC               74\n#define DUK_OP_EXP_CC               75\n#define DUK_OP_BAND                 76\n#define DUK_OP_BAND_RR              76\n#define DUK_OP_BAND_CR              77\n#define DUK_OP_BAND_RC              78\n#define DUK_OP_BAND_CC              79\n#define DUK_OP_BOR                  80\n#define DUK_OP_BOR_RR               80\n#define DUK_OP_BOR_CR               81\n#define DUK_OP_BOR_RC               82\n#define DUK_OP_BOR_CC               83\n#define DUK_OP_BXOR                 84\n#define DUK_OP_BXOR_RR              84\n#define DUK_OP_BXOR_CR              85\n#define DUK_OP_BXOR_RC              86\n#define DUK_OP_BXOR_CC              87\n#define DUK_OP_BASL                 88\n#define DUK_OP_BASL_RR              88\n#define DUK_OP_BASL_CR              89\n#define DUK_OP_BASL_RC              90\n#define DUK_OP_BASL_CC              91\n#define DUK_OP_BLSR                 92\n#define DUK_OP_BLSR_RR              92\n#define DUK_OP_BLSR_CR              93\n#define DUK_OP_BLSR_RC              94\n#define DUK_OP_BLSR_CC              95\n#define DUK_OP_BASR                 96\n#define DUK_OP_BASR_RR              96\n#define DUK_OP_BASR_CR              97\n#define DUK_OP_BASR_RC              98\n#define DUK_OP_BASR_CC              99\n#define DUK_OP_INSTOF               100\n#define DUK_OP_INSTOF_RR            100\n#define DUK_OP_INSTOF_CR            101\n#define DUK_OP_INSTOF_RC            102\n#define DUK_OP_INSTOF_CC            103\n#define DUK_OP_IN                   104\n#define DUK_OP_IN_RR                104\n#define DUK_OP_IN_CR                105\n#define DUK_OP_IN_RC                106\n#define DUK_OP_IN_CC                107\n#define DUK_OP_GETPROP              108\n#define DUK_OP_GETPROP_RR           108\n#define DUK_OP_GETPROP_CR           109\n#define DUK_OP_GETPROP_RC           110\n#define DUK_OP_GETPROP_CC           111\n#define DUK_OP_PUTPROP              112\n#define DUK_OP_PUTPROP_RR           112\n#define DUK_OP_PUTPROP_CR           113\n#define DUK_OP_PUTPROP_RC           114\n#define DUK_OP_PUTPROP_CC           115\n#define DUK_OP_DELPROP              116\n#define DUK_OP_DELPROP_RR           116\n#define DUK_OP_DELPROP_CR_UNUSED    117  /* unused now */\n#define DUK_OP_DELPROP_RC           118\n#define DUK_OP_DELPROP_CC_UNUSED    119  /* unused now */\n#define DUK_OP_PREINCR              120  /* pre/post opcode values have constraints, */\n#define DUK_OP_PREDECR              121  /* see duk_js_executor.c and duk_js_compiler.c. */\n#define DUK_OP_POSTINCR             122\n#define DUK_OP_POSTDECR             123\n#define DUK_OP_PREINCV              124\n#define DUK_OP_PREDECV              125\n#define DUK_OP_POSTINCV             126\n#define DUK_OP_POSTDECV             127\n#define DUK_OP_PREINCP              128  /* pre/post inc/dec prop opcodes have constraints */\n#define DUK_OP_PREINCP_RR           128\n#define DUK_OP_PREINCP_CR           129\n#define DUK_OP_PREINCP_RC           130\n#define DUK_OP_PREINCP_CC           131\n#define DUK_OP_PREDECP              132\n#define DUK_OP_PREDECP_RR           132\n#define DUK_OP_PREDECP_CR           133\n#define DUK_OP_PREDECP_RC           134\n#define DUK_OP_PREDECP_CC           135\n#define DUK_OP_POSTINCP             136\n#define DUK_OP_POSTINCP_RR          136\n#define DUK_OP_POSTINCP_CR          137\n#define DUK_OP_POSTINCP_RC          138\n#define DUK_OP_POSTINCP_CC          139\n#define DUK_OP_POSTDECP             140\n#define DUK_OP_POSTDECP_RR          140\n#define DUK_OP_POSTDECP_CR          141\n#define DUK_OP_POSTDECP_RC          142\n#define DUK_OP_POSTDECP_CC          143\n#define DUK_OP_DECLVAR              144\n#define DUK_OP_DECLVAR_RR           144\n#define DUK_OP_DECLVAR_CR           145\n#define DUK_OP_DECLVAR_RC           146\n#define DUK_OP_DECLVAR_CC           147\n#define DUK_OP_REGEXP               148\n#define DUK_OP_REGEXP_RR            148\n#define DUK_OP_REGEXP_CR            149\n#define DUK_OP_REGEXP_RC            150\n#define DUK_OP_REGEXP_CC            151\n#define DUK_OP_CLOSURE              152\n#define DUK_OP_TYPEOF               153\n#define DUK_OP_TYPEOFID             154\n#define DUK_OP_PUTVAR               155\n#define DUK_OP_DELVAR               156\n#define DUK_OP_RETREG               157\n#define DUK_OP_RETUNDEF             158\n#define DUK_OP_RETCONST             159\n#define DUK_OP_RETCONSTN            160  /* return const without incref (e.g. number) */\n#define DUK_OP_LABEL                161\n#define DUK_OP_ENDLABEL             162\n#define DUK_OP_BREAK                163\n#define DUK_OP_CONTINUE             164\n#define DUK_OP_TRYCATCH             165\n#define DUK_OP_ENDTRY               166\n#define DUK_OP_ENDCATCH             167\n#define DUK_OP_ENDFIN               168\n#define DUK_OP_THROW                169\n#define DUK_OP_INVLHS               170\n#define DUK_OP_CSREG                171\n#define DUK_OP_CSVAR                172\n#define DUK_OP_CSVAR_RR             172\n#define DUK_OP_CSVAR_CR             173\n#define DUK_OP_CSVAR_RC             174\n#define DUK_OP_CSVAR_CC             175\n#define DUK_OP_CALL0                176  /* DUK_OP_CALL0 & 0x0F must be zero. */\n#define DUK_OP_CALL1                177\n#define DUK_OP_CALL2                178\n#define DUK_OP_CALL3                179\n#define DUK_OP_CALL4                180\n#define DUK_OP_CALL5                181\n#define DUK_OP_CALL6                182\n#define DUK_OP_CALL7                183\n#define DUK_OP_CALL8                184\n#define DUK_OP_CALL9                185\n#define DUK_OP_CALL10               186\n#define DUK_OP_CALL11               187\n#define DUK_OP_CALL12               188\n#define DUK_OP_CALL13               189\n#define DUK_OP_CALL14               190\n#define DUK_OP_CALL15               191\n#define DUK_OP_NEWOBJ               192\n#define DUK_OP_NEWARR               193\n#define DUK_OP_MPUTOBJ              194\n#define DUK_OP_MPUTOBJI             195\n#define DUK_OP_INITSET              196\n#define DUK_OP_INITGET              197\n#define DUK_OP_MPUTARR              198\n#define DUK_OP_MPUTARRI             199\n#define DUK_OP_SETALEN              200\n#define DUK_OP_INITENUM             201\n#define DUK_OP_NEXTENUM             202\n#define DUK_OP_NEWTARGET            203\n#define DUK_OP_DEBUGGER             204\n#define DUK_OP_NOP                  205\n#define DUK_OP_INVALID              206\n#define DUK_OP_UNUSED207            207\n#define DUK_OP_GETPROPC             208\n#define DUK_OP_GETPROPC_RR          208\n#define DUK_OP_GETPROPC_CR          209\n#define DUK_OP_GETPROPC_RC          210\n#define DUK_OP_GETPROPC_CC          211\n#define DUK_OP_UNUSED212            212\n#define DUK_OP_UNUSED213            213\n#define DUK_OP_UNUSED214            214\n#define DUK_OP_UNUSED215            215\n#define DUK_OP_UNUSED216            216\n#define DUK_OP_UNUSED217            217\n#define DUK_OP_UNUSED218            218\n#define DUK_OP_UNUSED219            219\n#define DUK_OP_UNUSED220            220\n#define DUK_OP_UNUSED221            221\n#define DUK_OP_UNUSED222            222\n#define DUK_OP_UNUSED223            223\n#define DUK_OP_UNUSED224            224\n#define DUK_OP_UNUSED225            225\n#define DUK_OP_UNUSED226            226\n#define DUK_OP_UNUSED227            227\n#define DUK_OP_UNUSED228            228\n#define DUK_OP_UNUSED229            229\n#define DUK_OP_UNUSED230            230\n#define DUK_OP_UNUSED231            231\n#define DUK_OP_UNUSED232            232\n#define DUK_OP_UNUSED233            233\n#define DUK_OP_UNUSED234            234\n#define DUK_OP_UNUSED235            235\n#define DUK_OP_UNUSED236            236\n#define DUK_OP_UNUSED237            237\n#define DUK_OP_UNUSED238            238\n#define DUK_OP_UNUSED239            239\n#define DUK_OP_UNUSED240            240\n#define DUK_OP_UNUSED241            241\n#define DUK_OP_UNUSED242            242\n#define DUK_OP_UNUSED243            243\n#define DUK_OP_UNUSED244            244\n#define DUK_OP_UNUSED245            245\n#define DUK_OP_UNUSED246            246\n#define DUK_OP_UNUSED247            247\n#define DUK_OP_UNUSED248            248\n#define DUK_OP_UNUSED249            249\n#define DUK_OP_UNUSED250            250\n#define DUK_OP_UNUSED251            251\n#define DUK_OP_UNUSED252            252\n#define DUK_OP_UNUSED253            253\n#define DUK_OP_UNUSED254            254\n#define DUK_OP_UNUSED255            255\n#define DUK_OP_NONE                 256  /* dummy value used as marker (doesn't fit in 8-bit field) */\n\n/* XXX: Allocate flags from opcode field?  Would take 16 opcode slots\n * but avoids shuffling in more cases.  Maybe not worth it.\n */\n/* DUK_OP_TRYCATCH flags in A. */\n#define DUK_BC_TRYCATCH_FLAG_HAVE_CATCH     (1U << 0)\n#define DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY   (1U << 1)\n#define DUK_BC_TRYCATCH_FLAG_CATCH_BINDING  (1U << 2)\n#define DUK_BC_TRYCATCH_FLAG_WITH_BINDING   (1U << 3)\n\n/* DUK_OP_DECLVAR flags in A; bottom bits are reserved for propdesc flags\n * (DUK_PROPDESC_FLAG_XXX).\n */\n#define DUK_BC_DECLVAR_FLAG_FUNC_DECL       (1U << 4)  /* function declaration */\n\n/* DUK_OP_CALLn flags, part of opcode field.  Three lowest bits must match\n * DUK_CALL_FLAG_xxx directly.\n */\n#define DUK_BC_CALL_FLAG_TAILCALL           (1U << 0)\n#define DUK_BC_CALL_FLAG_CONSTRUCT          (1U << 1)\n#define DUK_BC_CALL_FLAG_CALLED_AS_EVAL     (1U << 2)\n#define DUK_BC_CALL_FLAG_INDIRECT           (1U << 3)\n\n/* Misc constants and helper macros. */\n#define DUK_BC_LDINT_BIAS           (1L << 15)\n#define DUK_BC_LDINTX_SHIFT         16\n#define DUK_BC_JUMP_BIAS            (1L << 23)\n\n#endif  /* DUK_JS_BYTECODE_H_INCLUDED */\n/* #include duk_lexer.h */\n/*\n *  Lexer defines.\n */\n\n#if !defined(DUK_LEXER_H_INCLUDED)\n#define DUK_LEXER_H_INCLUDED\n\ntypedef void (*duk_re_range_callback)(void *user, duk_codepoint_t r1, duk_codepoint_t r2, duk_bool_t direct);\n\n/*\n *  A token is interpreted as any possible production of InputElementDiv\n *  and InputElementRegExp, see E5 Section 7 in its entirety.  Note that\n *  the E5 \"Token\" production does not cover all actual tokens of the\n *  language (which is explicitly stated in the specification, Section 7.5).\n *  Null and boolean literals are defined as part of both ReservedWord\n *  (E5 Section 7.6.1) and Literal (E5 Section 7.8) productions.  Here,\n *  null and boolean values have literal tokens, and are not reserved\n *  words.\n *\n *  Decimal literal negative/positive sign is -not- part of DUK_TOK_NUMBER.\n *  The number tokens always have a non-negative value.  The unary minus\n *  operator in \"-1.0\" is optimized during compilation to yield a single\n *  negative constant.\n *\n *  Token numbering is free except that reserved words are required to be\n *  in a continuous range and in a particular order.  See genstrings.py.\n */\n\n#define DUK_LEXER_INITCTX(ctx)        duk_lexer_initctx((ctx))\n\n#define DUK_LEXER_SETPOINT(ctx,pt)    duk_lexer_setpoint((ctx), (pt))\n\n#define DUK_LEXER_GETPOINT(ctx,pt)    duk_lexer_getpoint((ctx), (pt))\n\n/* Currently 6 characters of lookup are actually needed (duk_lexer.c). */\n#define DUK_LEXER_WINDOW_SIZE                     6\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\n#define DUK_LEXER_BUFFER_SIZE                     64\n#endif\n\n#define DUK_TOK_MINVAL                            0\n\n/* returned after EOF (infinite amount) */\n#define DUK_TOK_EOF                               0\n\n/* identifier names (E5 Section 7.6) */\n#define DUK_TOK_IDENTIFIER                        1\n\n/* reserved words: keywords */\n#define DUK_TOK_START_RESERVED                    2\n#define DUK_TOK_BREAK                             2\n#define DUK_TOK_CASE                              3\n#define DUK_TOK_CATCH                             4\n#define DUK_TOK_CONTINUE                          5\n#define DUK_TOK_DEBUGGER                          6\n#define DUK_TOK_DEFAULT                           7\n#define DUK_TOK_DELETE                            8\n#define DUK_TOK_DO                                9\n#define DUK_TOK_ELSE                              10\n#define DUK_TOK_FINALLY                           11\n#define DUK_TOK_FOR                               12\n#define DUK_TOK_FUNCTION                          13\n#define DUK_TOK_IF                                14\n#define DUK_TOK_IN                                15\n#define DUK_TOK_INSTANCEOF                        16\n#define DUK_TOK_NEW                               17\n#define DUK_TOK_RETURN                            18\n#define DUK_TOK_SWITCH                            19\n#define DUK_TOK_THIS                              20\n#define DUK_TOK_THROW                             21\n#define DUK_TOK_TRY                               22\n#define DUK_TOK_TYPEOF                            23\n#define DUK_TOK_VAR                               24\n#define DUK_TOK_CONST                             25\n#define DUK_TOK_VOID                              26\n#define DUK_TOK_WHILE                             27\n#define DUK_TOK_WITH                              28\n\n/* reserved words: future reserved words */\n#define DUK_TOK_CLASS                             29\n#define DUK_TOK_ENUM                              30\n#define DUK_TOK_EXPORT                            31\n#define DUK_TOK_EXTENDS                           32\n#define DUK_TOK_IMPORT                            33\n#define DUK_TOK_SUPER                             34\n\n/* \"null\", \"true\", and \"false\" are always reserved words.\n * Note that \"get\" and \"set\" are not!\n */\n#define DUK_TOK_NULL                              35\n#define DUK_TOK_TRUE                              36\n#define DUK_TOK_FALSE                             37\n\n/* reserved words: additional future reserved words in strict mode */\n#define DUK_TOK_START_STRICT_RESERVED             38  /* inclusive */\n#define DUK_TOK_IMPLEMENTS                        38\n#define DUK_TOK_INTERFACE                         39\n#define DUK_TOK_LET                               40\n#define DUK_TOK_PACKAGE                           41\n#define DUK_TOK_PRIVATE                           42\n#define DUK_TOK_PROTECTED                         43\n#define DUK_TOK_PUBLIC                            44\n#define DUK_TOK_STATIC                            45\n#define DUK_TOK_YIELD                             46\n\n#define DUK_TOK_END_RESERVED                      47  /* exclusive */\n\n/* \"get\" and \"set\" are tokens but NOT ReservedWords.  They are currently\n * parsed and identifiers and these defines are actually now unused.\n */\n#define DUK_TOK_GET                               47\n#define DUK_TOK_SET                               48\n\n/* punctuators (unlike the spec, also includes \"/\" and \"/=\") */\n#define DUK_TOK_LCURLY                            49\n#define DUK_TOK_RCURLY                            50\n#define DUK_TOK_LBRACKET                          51\n#define DUK_TOK_RBRACKET                          52\n#define DUK_TOK_LPAREN                            53\n#define DUK_TOK_RPAREN                            54\n#define DUK_TOK_PERIOD                            55\n#define DUK_TOK_SEMICOLON                         56\n#define DUK_TOK_COMMA                             57\n#define DUK_TOK_LT                                58\n#define DUK_TOK_GT                                59\n#define DUK_TOK_LE                                60\n#define DUK_TOK_GE                                61\n#define DUK_TOK_EQ                                62\n#define DUK_TOK_NEQ                               63\n#define DUK_TOK_SEQ                               64\n#define DUK_TOK_SNEQ                              65\n#define DUK_TOK_ADD                               66\n#define DUK_TOK_SUB                               67\n#define DUK_TOK_MUL                               68\n#define DUK_TOK_DIV                               69\n#define DUK_TOK_MOD                               70\n#define DUK_TOK_EXP                               71\n#define DUK_TOK_INCREMENT                         72\n#define DUK_TOK_DECREMENT                         73\n#define DUK_TOK_ALSHIFT                           74   /* named \"arithmetic\" because result is signed */\n#define DUK_TOK_ARSHIFT                           75\n#define DUK_TOK_RSHIFT                            76\n#define DUK_TOK_BAND                              77\n#define DUK_TOK_BOR                               78\n#define DUK_TOK_BXOR                              79\n#define DUK_TOK_LNOT                              80\n#define DUK_TOK_BNOT                              81\n#define DUK_TOK_LAND                              82\n#define DUK_TOK_LOR                               83\n#define DUK_TOK_QUESTION                          84\n#define DUK_TOK_COLON                             85\n#define DUK_TOK_EQUALSIGN                         86\n#define DUK_TOK_ADD_EQ                            87\n#define DUK_TOK_SUB_EQ                            88\n#define DUK_TOK_MUL_EQ                            89\n#define DUK_TOK_DIV_EQ                            90\n#define DUK_TOK_MOD_EQ                            91\n#define DUK_TOK_EXP_EQ                            92\n#define DUK_TOK_ALSHIFT_EQ                        93\n#define DUK_TOK_ARSHIFT_EQ                        94\n#define DUK_TOK_RSHIFT_EQ                         95\n#define DUK_TOK_BAND_EQ                           96\n#define DUK_TOK_BOR_EQ                            97\n#define DUK_TOK_BXOR_EQ                           98\n\n/* literals (E5 Section 7.8), except null, true, false, which are treated\n * like reserved words (above).\n */\n#define DUK_TOK_NUMBER                            99\n#define DUK_TOK_STRING                            100\n#define DUK_TOK_REGEXP                            101\n\n#define DUK_TOK_MAXVAL                            101  /* inclusive */\n\n#define DUK_TOK_INVALID                           DUK_SMALL_UINT_MAX\n\n/* Convert heap string index to a token (reserved words) */\n#define DUK_STRIDX_TO_TOK(x)                        ((x) - DUK_STRIDX_START_RESERVED + DUK_TOK_START_RESERVED)\n\n/* Sanity check */\n#if (DUK_TOK_MAXVAL > 255)\n#error DUK_TOK_MAXVAL too large, code assumes it fits into 8 bits\n#endif\n\n/* Sanity checks for string and token defines */\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_BREAK) != DUK_TOK_BREAK)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CASE) != DUK_TOK_CASE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CATCH) != DUK_TOK_CATCH)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CONTINUE) != DUK_TOK_CONTINUE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DEBUGGER) != DUK_TOK_DEBUGGER)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DEFAULT) != DUK_TOK_DEFAULT)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DELETE) != DUK_TOK_DELETE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DO) != DUK_TOK_DO)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_ELSE) != DUK_TOK_ELSE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_FINALLY) != DUK_TOK_FINALLY)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_FOR) != DUK_TOK_FOR)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_LC_FUNCTION) != DUK_TOK_FUNCTION)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IF) != DUK_TOK_IF)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IN) != DUK_TOK_IN)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_INSTANCEOF) != DUK_TOK_INSTANCEOF)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_NEW) != DUK_TOK_NEW)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_RETURN) != DUK_TOK_RETURN)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_SWITCH) != DUK_TOK_SWITCH)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_THIS) != DUK_TOK_THIS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_THROW) != DUK_TOK_THROW)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_TRY) != DUK_TOK_TRY)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_TYPEOF) != DUK_TOK_TYPEOF)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_VAR) != DUK_TOK_VAR)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_VOID) != DUK_TOK_VOID)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_WHILE) != DUK_TOK_WHILE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_WITH) != DUK_TOK_WITH)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CLASS) != DUK_TOK_CLASS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CONST) != DUK_TOK_CONST)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_ENUM) != DUK_TOK_ENUM)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_EXPORT) != DUK_TOK_EXPORT)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_EXTENDS) != DUK_TOK_EXTENDS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IMPORT) != DUK_TOK_IMPORT)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_SUPER) != DUK_TOK_SUPER)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_LC_NULL) != DUK_TOK_NULL)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_TRUE) != DUK_TOK_TRUE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_FALSE) != DUK_TOK_FALSE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IMPLEMENTS) != DUK_TOK_IMPLEMENTS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_INTERFACE) != DUK_TOK_INTERFACE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_LET) != DUK_TOK_LET)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PACKAGE) != DUK_TOK_PACKAGE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PRIVATE) != DUK_TOK_PRIVATE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PROTECTED) != DUK_TOK_PROTECTED)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PUBLIC) != DUK_TOK_PUBLIC)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_STATIC) != DUK_TOK_STATIC)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_YIELD) != DUK_TOK_YIELD)\n#error mismatch in token defines\n#endif\n\n/* Regexp tokens */\n#define DUK_RETOK_EOF                              0\n#define DUK_RETOK_DISJUNCTION                      1\n#define DUK_RETOK_QUANTIFIER                       2\n#define DUK_RETOK_ASSERT_START                     3\n#define DUK_RETOK_ASSERT_END                       4\n#define DUK_RETOK_ASSERT_WORD_BOUNDARY             5\n#define DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY         6\n#define DUK_RETOK_ASSERT_START_POS_LOOKAHEAD       7\n#define DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD       8\n#define DUK_RETOK_ATOM_PERIOD                      9\n#define DUK_RETOK_ATOM_CHAR                        10\n#define DUK_RETOK_ATOM_DIGIT                       11  /* assumptions in regexp compiler */\n#define DUK_RETOK_ATOM_NOT_DIGIT                   12  /* -\"\"- */\n#define DUK_RETOK_ATOM_WHITE                       13  /* -\"\"- */\n#define DUK_RETOK_ATOM_NOT_WHITE                   14  /* -\"\"- */\n#define DUK_RETOK_ATOM_WORD_CHAR                   15  /* -\"\"- */\n#define DUK_RETOK_ATOM_NOT_WORD_CHAR               16  /* -\"\"- */\n#define DUK_RETOK_ATOM_BACKREFERENCE               17\n#define DUK_RETOK_ATOM_START_CAPTURE_GROUP         18\n#define DUK_RETOK_ATOM_START_NONCAPTURE_GROUP      19\n#define DUK_RETOK_ATOM_START_CHARCLASS             20\n#define DUK_RETOK_ATOM_START_CHARCLASS_INVERTED    21\n#define DUK_RETOK_ATOM_END_GROUP                   22\n\n/* Constants for duk_lexer_ctx.buf. */\n#define DUK_LEXER_TEMP_BUF_LIMIT                   256\n\n/* A token value.  Can be memcpy()'d, but note that slot1/slot2 values are on the valstack.\n * Some fields (like num, str1, str2) are only valid for specific token types and may have\n * stale values otherwise.\n */\nstruct duk_token {\n\tduk_small_uint_t t;           /* token type (with reserved word identification) */\n\tduk_small_uint_t t_nores;     /* token type (with reserved words as DUK_TOK_IDENTIFER) */\n\tduk_double_t num;             /* numeric value of token */\n\tduk_hstring *str1;            /* string 1 of token (borrowed, stored to ctx->slot1_idx) */\n\tduk_hstring *str2;            /* string 2 of token (borrowed, stored to ctx->slot2_idx) */\n\tduk_size_t start_offset;      /* start byte offset of token in lexer input */\n\tduk_int_t start_line;         /* start line of token (first char) */\n\tduk_int_t num_escapes;        /* number of escapes and line continuations (for directive prologue) */\n\tduk_bool_t lineterm;          /* token was preceded by a lineterm */\n\tduk_bool_t allow_auto_semi;   /* token allows automatic semicolon insertion (eof or preceded by newline) */\n};\n\n#define DUK_RE_QUANTIFIER_INFINITE         ((duk_uint32_t) 0xffffffffUL)\n\n/* A regexp token value. */\nstruct duk_re_token {\n\tduk_small_uint_t t;          /* token type */\n\tduk_small_uint_t greedy;\n\tduk_uint32_t num;            /* numeric value (character, count) */\n\tduk_uint32_t qmin;\n\tduk_uint32_t qmax;\n};\n\n/* A structure for 'snapshotting' a point for rewinding */\nstruct duk_lexer_point {\n\tduk_size_t offset;\n\tduk_int_t line;\n};\n\n/* Lexer codepoint with additional info like offset/line number */\nstruct duk_lexer_codepoint {\n\tduk_codepoint_t codepoint;\n\tduk_size_t offset;\n\tduk_int_t line;\n};\n\n/* Lexer context.  Same context is used for ECMAScript and Regexp parsing. */\nstruct duk_lexer_ctx {\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\n\tduk_lexer_codepoint *window; /* unicode code points, window[0] is always next, points to 'buffer' */\n\tduk_lexer_codepoint buffer[DUK_LEXER_BUFFER_SIZE];\n#else\n\tduk_lexer_codepoint window[DUK_LEXER_WINDOW_SIZE]; /* unicode code points, window[0] is always next */\n#endif\n\n\tduk_hthread *thr;                              /* thread; minimizes argument passing */\n\n\tconst duk_uint8_t *input;                      /* input string (may be a user pointer) */\n\tduk_size_t input_length;                       /* input byte length */\n\tduk_size_t input_offset;                       /* input offset for window leading edge (not window[0]) */\n\tduk_int_t input_line;                          /* input linenumber at input_offset (not window[0]), init to 1 */\n\n\tduk_idx_t slot1_idx;                           /* valstack slot for 1st token value */\n\tduk_idx_t slot2_idx;                           /* valstack slot for 2nd token value */\n\tduk_idx_t buf_idx;                             /* valstack slot for temp buffer */\n\tduk_hbuffer_dynamic *buf;                      /* temp accumulation buffer */\n\tduk_bufwriter_ctx bw;                          /* bufwriter for temp accumulation */\n\n\tduk_int_t token_count;                         /* number of tokens parsed */\n\tduk_int_t token_limit;                         /* maximum token count before error (sanity backstop) */\n\n\tduk_small_uint_t flags;                        /* lexer flags, use compiler flag defines for now */\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_lexer_initctx(duk_lexer_ctx *lex_ctx);\n\nDUK_INTERNAL_DECL void duk_lexer_getpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt);\nDUK_INTERNAL_DECL void duk_lexer_setpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt);\n\nDUK_INTERNAL_DECL\nvoid duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,\n                                      duk_token *out_token,\n                                      duk_bool_t strict_mode,\n                                      duk_bool_t regexp_mode);\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL_DECL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token *out_token);\nDUK_INTERNAL_DECL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_range_callback gen_range, void *userdata);\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n#endif  /* DUK_LEXER_H_INCLUDED */\n/* #include duk_js_compiler.h */\n/*\n *  ECMAScript compiler.\n */\n\n#if !defined(DUK_JS_COMPILER_H_INCLUDED)\n#define DUK_JS_COMPILER_H_INCLUDED\n\n/* ECMAScript compiler limits */\n#define DUK_COMPILER_TOKEN_LIMIT           100000000L  /* 1e8: protects against deeply nested inner functions */\n\n/* maximum loopcount for peephole optimization */\n#define DUK_COMPILER_PEEPHOLE_MAXITER      3\n\n/* maximum bytecode length in instructions */\n#define DUK_COMPILER_MAX_BYTECODE_LENGTH   (256L * 1024L * 1024L)  /* 1 GB */\n\n/*\n *  Compiler intermediate values\n *\n *  Intermediate values describe either plain values (e.g. strings or\n *  numbers) or binary operations which have not yet been coerced into\n *  either a left-hand-side or right-hand-side role (e.g. object property).\n */\n\n#define DUK_IVAL_NONE          0   /* no value */\n#define DUK_IVAL_PLAIN         1   /* register, constant, or value */\n#define DUK_IVAL_ARITH         2   /* binary arithmetic; DUK_OP_ADD, DUK_OP_EQ, other binary ops */\n#define DUK_IVAL_PROP          3   /* property access */\n#define DUK_IVAL_VAR           4   /* variable access */\n\n#define DUK_ISPEC_NONE         0   /* no value */\n#define DUK_ISPEC_VALUE        1   /* value resides in 'valstack_idx' */\n#define DUK_ISPEC_REGCONST     2   /* value resides in a register or constant */\n\n/* Bit mask which indicates that a regconst is a constant instead of a register.\n * Chosen so that when a regconst is cast to duk_int32_t, all consts are\n * negative values.\n */\n#define DUK_REGCONST_CONST_MARKER    DUK_INT32_MIN  /* = -0x80000000 */\n\n/* Type to represent a reg/const reference during compilation, with <0\n * indicating a constant.  Some call sites also use -1 to indicate 'none'.\n */\ntypedef duk_int32_t duk_regconst_t;\n\ntypedef struct {\n\tduk_small_uint_t t;          /* DUK_ISPEC_XXX */\n\tduk_regconst_t regconst;\n\tduk_idx_t valstack_idx;      /* always set; points to a reserved valstack slot */\n} duk_ispec;\n\ntypedef struct {\n\t/*\n\t *  PLAIN: x1\n\t *  ARITH: x1 <op> x2\n\t *  PROP: x1.x2\n\t *  VAR: x1 (name)\n\t */\n\n\t/* XXX: can be optimized for smaller footprint esp. on 32-bit environments */\n\tduk_small_uint_t t;          /* DUK_IVAL_XXX */\n\tduk_small_uint_t op;         /* bytecode opcode for binary ops */\n\tduk_ispec x1;\n\tduk_ispec x2;\n} duk_ivalue;\n\n/*\n *  Bytecode instruction representation during compilation\n *\n *  Contains the actual instruction and (optionally) debug info.\n */\n\nstruct duk_compiler_instr {\n\tduk_instr_t ins;\n#if defined(DUK_USE_PC2LINE)\n\tduk_uint32_t line;\n#endif\n};\n\n/*\n *  Compiler state\n */\n\n#define DUK_LABEL_FLAG_ALLOW_BREAK       (1U << 0)\n#define DUK_LABEL_FLAG_ALLOW_CONTINUE    (1U << 1)\n\n#define DUK_DECL_TYPE_VAR                0\n#define DUK_DECL_TYPE_FUNC               1\n\n/* XXX: optimize to 16 bytes */\ntypedef struct {\n\tduk_small_uint_t flags;\n\tduk_int_t label_id;          /* numeric label_id (-1 reserved as marker) */\n\tduk_hstring *h_label;        /* borrowed label name */\n\tduk_int_t catch_depth;       /* catch depth at point of definition */\n\tduk_int_t pc_label;          /* pc of label statement:\n\t                              * pc+1: break jump site\n\t                              * pc+2: continue jump site\n\t                              */\n\n\t/* Fast jumps (which avoid longjmp) jump directly to the jump sites\n\t * which are always known even while the iteration/switch statement\n\t * is still being parsed.  A final peephole pass \"straightens out\"\n\t * the jumps.\n\t */\n} duk_labelinfo;\n\n/* Compiling state of one function, eventually converted to duk_hcompfunc */\nstruct duk_compiler_func {\n\t/* These pointers are at the start of the struct so that they pack\n\t * nicely.  Mixing pointers and integer values is bad on some\n\t * platforms (e.g. if int is 32 bits and pointers are 64 bits).\n\t */\n\n\tduk_bufwriter_ctx bw_code;          /* bufwriter for code */\n\n\tduk_hstring *h_name;                /* function name (borrowed reference), ends up in _name */\n\t/* h_code: held in bw_code */\n\tduk_hobject *h_consts;              /* array */\n\tduk_hobject *h_funcs;               /* array of function templates: [func1, offset1, line1, func2, offset2, line2]\n\t                                     * offset/line points to closing brace to allow skipping on pass 2\n\t                                     */\n\tduk_hobject *h_decls;               /* array of declarations: [ name1, val1, name2, val2, ... ]\n\t                                     * valN = (typeN) | (fnum << 8), where fnum is inner func number (0 for vars)\n\t                                     * record function and variable declarations in pass 1\n\t                                     */\n\tduk_hobject *h_labelnames;          /* array of active label names */\n\tduk_hbuffer_dynamic *h_labelinfos;  /* C array of duk_labelinfo */\n\tduk_hobject *h_argnames;            /* array of formal argument names (-> _Formals) */\n\tduk_hobject *h_varmap;              /* variable map for pass 2 (identifier -> register number or null (unmapped)) */\n\n\t/* Value stack indices for tracking objects. */\n\t/* code_idx: not needed */\n\tduk_idx_t consts_idx;\n\tduk_idx_t funcs_idx;\n\tduk_idx_t decls_idx;\n\tduk_idx_t labelnames_idx;\n\tduk_idx_t labelinfos_idx;\n\tduk_idx_t argnames_idx;\n\tduk_idx_t varmap_idx;\n\n\t/* Temp reg handling. */\n\tduk_regconst_t temp_first;           /* first register that is a temporary (below: variables) */\n\tduk_regconst_t temp_next;            /* next temporary register to allocate */\n\tduk_regconst_t temp_max;             /* highest value of temp_reg (temp_max - 1 is highest used reg) */\n\n\t/* Shuffle registers if large number of regs/consts. */\n\tduk_regconst_t shuffle1;\n\tduk_regconst_t shuffle2;\n\tduk_regconst_t shuffle3;\n\n\t/* Stats for current expression being parsed. */\n\tduk_int_t nud_count;\n\tduk_int_t led_count;\n\tduk_int_t paren_level;              /* parenthesis count, 0 = top level */\n\tduk_bool_t expr_lhs;                /* expression is left-hand-side compatible */\n\tduk_bool_t allow_in;                /* current paren level allows 'in' token */\n\n\t/* Misc. */\n\tduk_int_t stmt_next;                /* statement id allocation (running counter) */\n\tduk_int_t label_next;               /* label id allocation (running counter) */\n\tduk_int_t catch_depth;              /* catch stack depth */\n\tduk_int_t with_depth;               /* with stack depth (affects identifier lookups) */\n\tduk_int_t fnum_next;                /* inner function numbering */\n\tduk_int_t num_formals;              /* number of formal arguments */\n\tduk_regconst_t reg_stmt_value;      /* register for writing value of 'non-empty' statements (global or eval code), -1 is marker */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_int_t min_line;                 /* XXX: typing (duk_hcompfunc has duk_uint32_t) */\n\tduk_int_t max_line;\n#endif\n\n\t/* Status booleans. */\n\tduk_uint8_t is_function;             /* is an actual function (not global/eval code) */\n\tduk_uint8_t is_eval;                 /* is eval code */\n\tduk_uint8_t is_global;               /* is global code */\n\tduk_uint8_t is_namebinding;          /* needs a name binding */\n\tduk_uint8_t is_constructable;        /* result is constructable */\n\tduk_uint8_t is_setget;               /* is a setter/getter */\n\tduk_uint8_t is_strict;               /* function is strict */\n\tduk_uint8_t is_notail;               /* function must not be tail called */\n\tduk_uint8_t in_directive_prologue;   /* parsing in \"directive prologue\", recognize directives */\n\tduk_uint8_t in_scanning;             /* parsing in \"scanning\" phase (first pass) */\n\tduk_uint8_t may_direct_eval;         /* function may call direct eval */\n\tduk_uint8_t id_access_arguments;     /* function refers to 'arguments' identifier */\n\tduk_uint8_t id_access_slow;          /* function makes one or more slow path accesses that won't match own static variables */\n\tduk_uint8_t id_access_slow_own;      /* function makes one or more slow path accesses that may match own static variables */\n\tduk_uint8_t is_arguments_shadowed;   /* argument/function declaration shadows 'arguments' */\n\tduk_uint8_t needs_shuffle;           /* function needs shuffle registers */\n\tduk_uint8_t reject_regexp_in_adv;    /* reject RegExp literal on next advance() call; needed for handling IdentifierName productions */\n\tduk_uint8_t allow_regexp_in_adv;     /* allow RegExp literal on next advance() call */\n};\n\nstruct duk_compiler_ctx {\n\tduk_hthread *thr;\n\n\t/* filename being compiled (ends up in functions' '_filename' property) */\n\tduk_hstring *h_filename;            /* borrowed reference */\n\n\t/* lexing (tokenization) state (contains two valstack slot indices) */\n\tduk_lexer_ctx lex;\n\n\t/* current and previous token for parsing */\n\tduk_token prev_token;\n\tduk_token curr_token;\n\tduk_idx_t tok11_idx;                /* curr_token slot1 (matches 'lex' slot1_idx) */\n\tduk_idx_t tok12_idx;                /* curr_token slot2 (matches 'lex' slot2_idx) */\n\tduk_idx_t tok21_idx;                /* prev_token slot1 */\n\tduk_idx_t tok22_idx;                /* prev_token slot2 */\n\n\t/* recursion limit */\n\tduk_int_t recursion_depth;\n\tduk_int_t recursion_limit;\n\n\t/* code emission temporary */\n\tduk_int_t emit_jumpslot_pc;\n\n\t/* current function being compiled (embedded instead of pointer for more compact access) */\n\tduk_compiler_func curr_func;\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer, duk_size_t src_length, duk_small_uint_t flags);\n\n#endif  /* DUK_JS_COMPILER_H_INCLUDED */\n/* #include duk_regexp.h */\n/*\n *  Regular expression structs, constants, and bytecode defines.\n */\n\n#if !defined(DUK_REGEXP_H_INCLUDED)\n#define DUK_REGEXP_H_INCLUDED\n\n/* maximum bytecode copies for {n,m} quantifiers */\n#define DUK_RE_MAX_ATOM_COPIES             1000\n\n/* regexp compilation limits */\n#define DUK_RE_COMPILE_TOKEN_LIMIT         100000000L   /* 1e8 */\n\n/* regexp execution limits */\n#define DUK_RE_EXECUTE_STEPS_LIMIT         1000000000L  /* 1e9 */\n\n/* regexp opcodes */\n#define DUK_REOP_MATCH                     1\n#define DUK_REOP_CHAR                      2\n#define DUK_REOP_PERIOD                    3\n#define DUK_REOP_RANGES                    4\n#define DUK_REOP_INVRANGES                 5\n#define DUK_REOP_JUMP                      6\n#define DUK_REOP_SPLIT1                    7\n#define DUK_REOP_SPLIT2                    8\n#define DUK_REOP_SQMINIMAL                 9\n#define DUK_REOP_SQGREEDY                  10\n#define DUK_REOP_SAVE                      11\n#define DUK_REOP_WIPERANGE                 12\n#define DUK_REOP_LOOKPOS                   13\n#define DUK_REOP_LOOKNEG                   14\n#define DUK_REOP_BACKREFERENCE             15\n#define DUK_REOP_ASSERT_START              16\n#define DUK_REOP_ASSERT_END                17\n#define DUK_REOP_ASSERT_WORD_BOUNDARY      18\n#define DUK_REOP_ASSERT_NOT_WORD_BOUNDARY  19\n\n/* flags */\n#define DUK_RE_FLAG_GLOBAL                 (1U << 0)\n#define DUK_RE_FLAG_IGNORE_CASE            (1U << 1)\n#define DUK_RE_FLAG_MULTILINE              (1U << 2)\n\nstruct duk_re_matcher_ctx {\n\tduk_hthread *thr;\n\n\tduk_uint32_t re_flags;\n\tconst duk_uint8_t *input;\n\tconst duk_uint8_t *input_end;\n\tconst duk_uint8_t *bytecode;\n\tconst duk_uint8_t *bytecode_end;\n\tconst duk_uint8_t **saved;  /* allocated from valstack (fixed buffer) */\n\tduk_uint32_t nsaved;\n\tduk_uint32_t recursion_depth;\n\tduk_uint32_t recursion_limit;\n\tduk_uint32_t steps_count;\n\tduk_uint32_t steps_limit;\n};\n\nstruct duk_re_compiler_ctx {\n\tduk_hthread *thr;\n\n\tduk_uint32_t re_flags;\n\tduk_lexer_ctx lex;\n\tduk_re_token curr_token;\n\tduk_bufwriter_ctx bw;\n\tduk_uint32_t captures;  /* highest capture number emitted so far (used as: ++captures) */\n\tduk_uint32_t highest_backref;\n\tduk_uint32_t recursion_depth;\n\tduk_uint32_t recursion_limit;\n\tduk_uint32_t nranges;  /* internal temporary value, used for char classes */\n};\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL_DECL void duk_regexp_compile(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_regexp_create_instance(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_regexp_match(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_regexp_match_force_global(duk_hthread *thr);  /* hacky helper for String.prototype.split() */\n#endif\n\n#endif  /* DUK_REGEXP_H_INCLUDED */\n/* #include duk_heaphdr.h */\n/*\n *  Heap header definition and assorted macros, including ref counting.\n *  Access all fields through the accessor macros.\n */\n\n#if !defined(DUK_HEAPHDR_H_INCLUDED)\n#define DUK_HEAPHDR_H_INCLUDED\n\n/*\n *  Common heap header\n *\n *  All heap objects share the same flags and refcount fields.  Objects other\n *  than strings also need to have a single or double linked list pointers\n *  for insertion into the \"heap allocated\" list.  Strings have single linked\n *  list pointers for string table chaining.\n *\n *  Technically, 'h_refcount' must be wide enough to guarantee that it cannot\n *  wrap; otherwise objects might be freed incorrectly after wrapping.  The\n *  default refcount field is 32 bits even on 64-bit systems: while that's in\n *  theory incorrect, the Duktape heap needs to be larger than 64GB for the\n *  count to actually wrap (assuming 16-byte duk_tvals).  This is very unlikely\n *  to ever be an issue, but if it is, disabling DUK_USE_REFCOUNT32 causes\n *  Duktape to use size_t for refcounts which should always be safe.\n *\n *  Heap header size on 32-bit platforms: 8 bytes without reference counting,\n *  16 bytes with reference counting.\n *\n *  Note that 'raw' macros such as DUK_HEAPHDR_GET_REFCOUNT() are not\n *  defined without DUK_USE_REFERENCE_COUNTING, so caller must #if defined()\n *  around them.\n */\n\n/* XXX: macro for shared header fields (avoids some padding issues) */\n\nstruct duk_heaphdr {\n\tduk_uint32_t h_flags;\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#if defined(DUK_USE_ASSERTIONS)\n\t/* When assertions enabled, used by mark-and-sweep for refcount\n\t * validation.  Largest reasonable type; also detects overflows.\n\t */\n\tduk_size_t h_assert_refcount;\n#endif\n#if defined(DUK_USE_REFCOUNT16)\n\tduk_uint16_t h_refcount;\n#elif defined(DUK_USE_REFCOUNT32)\n\tduk_uint32_t h_refcount;\n#else\n\tduk_size_t h_refcount;\n#endif\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t h_next16;\n#else\n\tduk_heaphdr *h_next;\n#endif\n\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\t/* refcounting requires direct heap frees, which in turn requires a dual linked heap */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t h_prev16;\n#else\n\tduk_heaphdr *h_prev;\n#endif\n#endif\n\n\t/* When DUK_USE_HEAPPTR16 (and DUK_USE_REFCOUNT16) is in use, the\n\t * struct won't align nicely to 4 bytes.  This 16-bit extra field\n\t * is added to make the alignment clean; the field can be used by\n\t * heap objects when 16-bit packing is used.  This field is now\n\t * conditional to DUK_USE_HEAPPTR16 only, but it is intended to be\n\t * used with DUK_USE_REFCOUNT16 and DUK_USE_DOUBLE_LINKED_HEAP;\n\t * this only matter to low memory environments anyway.\n\t */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t h_extra16;\n#endif\n};\n\nstruct duk_heaphdr_string {\n\t/* 16 bits would be enough for shared heaphdr flags and duk_hstring\n\t * flags.  The initial parts of duk_heaphdr_string and duk_heaphdr\n\t * must match so changing the flags field size here would be quite\n\t * awkward.  However, to minimize struct size, we can pack at least\n\t * 16 bits of duk_hstring data into the flags field.\n\t */\n\tduk_uint32_t h_flags;\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#if defined(DUK_USE_ASSERTIONS)\n\t/* When assertions enabled, used by mark-and-sweep for refcount\n\t * validation.  Largest reasonable type; also detects overflows.\n\t */\n\tduk_size_t h_assert_refcount;\n#endif\n#if defined(DUK_USE_REFCOUNT16)\n\tduk_uint16_t h_refcount;\n\tduk_uint16_t h_strextra16;  /* round out to 8 bytes */\n#elif defined(DUK_USE_REFCOUNT32)\n\tduk_uint32_t h_refcount;\n#else\n\tduk_size_t h_refcount;\n#endif\n#else\n\tduk_uint16_t h_strextra16;\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n\tduk_hstring *h_next;\n\t/* No 'h_prev' pointer for strings. */\n};\n\n#define DUK_HEAPHDR_FLAGS_TYPE_MASK      0x00000003UL\n#define DUK_HEAPHDR_FLAGS_FLAG_MASK      (~DUK_HEAPHDR_FLAGS_TYPE_MASK)\n\n                                             /* 2 bits for heap type */\n#define DUK_HEAPHDR_FLAGS_HEAP_START     2   /* 5 heap flags */\n#define DUK_HEAPHDR_FLAGS_USER_START     7   /* 25 user flags */\n\n#define DUK_HEAPHDR_HEAP_FLAG_NUMBER(n)  (DUK_HEAPHDR_FLAGS_HEAP_START + (n))\n#define DUK_HEAPHDR_USER_FLAG_NUMBER(n)  (DUK_HEAPHDR_FLAGS_USER_START + (n))\n#define DUK_HEAPHDR_HEAP_FLAG(n)         (1UL << (DUK_HEAPHDR_FLAGS_HEAP_START + (n)))\n#define DUK_HEAPHDR_USER_FLAG(n)         (1UL << (DUK_HEAPHDR_FLAGS_USER_START + (n)))\n\n#define DUK_HEAPHDR_FLAG_REACHABLE       DUK_HEAPHDR_HEAP_FLAG(0)  /* mark-and-sweep: reachable */\n#define DUK_HEAPHDR_FLAG_TEMPROOT        DUK_HEAPHDR_HEAP_FLAG(1)  /* mark-and-sweep: children not processed */\n#define DUK_HEAPHDR_FLAG_FINALIZABLE     DUK_HEAPHDR_HEAP_FLAG(2)  /* mark-and-sweep: finalizable (on current pass) */\n#define DUK_HEAPHDR_FLAG_FINALIZED       DUK_HEAPHDR_HEAP_FLAG(3)  /* mark-and-sweep: finalized (on previous pass) */\n#define DUK_HEAPHDR_FLAG_READONLY        DUK_HEAPHDR_HEAP_FLAG(4)  /* read-only object, in code section */\n\n#define DUK_HTYPE_MIN                    0\n#define DUK_HTYPE_STRING                 0\n#define DUK_HTYPE_OBJECT                 1\n#define DUK_HTYPE_BUFFER                 2\n#define DUK_HTYPE_MAX                    2\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HEAPHDR_GET_NEXT(heap,h) \\\n\t((duk_heaphdr *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->h_next16))\n#define DUK_HEAPHDR_SET_NEXT(heap,h,val)   do { \\\n\t\t(h)->h_next16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) val); \\\n\t} while (0)\n#else\n#define DUK_HEAPHDR_GET_NEXT(heap,h)  ((h)->h_next)\n#define DUK_HEAPHDR_SET_NEXT(heap,h,val)   do { \\\n\t\t(h)->h_next = (val); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HEAPHDR_GET_PREV(heap,h) \\\n\t((duk_heaphdr *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->h_prev16))\n#define DUK_HEAPHDR_SET_PREV(heap,h,val)   do { \\\n\t\t(h)->h_prev16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (val)); \\\n\t} while (0)\n#else\n#define DUK_HEAPHDR_GET_PREV(heap,h)       ((h)->h_prev)\n#define DUK_HEAPHDR_SET_PREV(heap,h,val)   do { \\\n\t\t(h)->h_prev = (val); \\\n\t} while (0)\n#endif\n#endif\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_HEAPHDR_GET_REFCOUNT(h)   ((h)->h_refcount)\n#define DUK_HEAPHDR_SET_REFCOUNT(h,val)  do { \\\n\t\t(h)->h_refcount = (val); \\\n\t\tDUK_ASSERT((h)->h_refcount == (val));  /* No truncation. */ \\\n\t} while (0)\n#define DUK_HEAPHDR_PREINC_REFCOUNT(h)  (++(h)->h_refcount)  /* result: updated refcount */\n#define DUK_HEAPHDR_PREDEC_REFCOUNT(h)  (--(h)->h_refcount)  /* result: updated refcount */\n#else\n/* refcount macros not defined without refcounting, caller must #if defined() now */\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/*\n *  Note: type is treated as a field separate from flags, so some masking is\n *  involved in the macros below.\n */\n\n#define DUK_HEAPHDR_GET_FLAGS_RAW(h)  ((h)->h_flags)\n#define DUK_HEAPHDR_SET_FLAGS_RAW(h,val)  do { \\\n\t\t(h)->h_flags = (val); } \\\n\t}\n#define DUK_HEAPHDR_GET_FLAGS(h)      ((h)->h_flags & DUK_HEAPHDR_FLAGS_FLAG_MASK)\n#define DUK_HEAPHDR_SET_FLAGS(h,val)  do { \\\n\t\t(h)->h_flags = ((h)->h_flags & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) | (val); \\\n\t} while (0)\n#define DUK_HEAPHDR_GET_TYPE(h)       ((h)->h_flags & DUK_HEAPHDR_FLAGS_TYPE_MASK)\n#define DUK_HEAPHDR_SET_TYPE(h,val)   do { \\\n\t\t(h)->h_flags = ((h)->h_flags & ~(DUK_HEAPHDR_FLAGS_TYPE_MASK)) | (val); \\\n\t} while (0)\n\n/* Comparison for type >= DUK_HTYPE_MIN skipped; because DUK_HTYPE_MIN is zero\n * and the comparison is unsigned, it's always true and generates warnings.\n */\n#define DUK_HEAPHDR_HTYPE_VALID(h)    ( \\\n\tDUK_HEAPHDR_GET_TYPE((h)) <= DUK_HTYPE_MAX \\\n\t)\n\n#define DUK_HEAPHDR_SET_TYPE_AND_FLAGS(h,tval,fval)  do { \\\n\t\t(h)->h_flags = ((tval) & DUK_HEAPHDR_FLAGS_TYPE_MASK) | \\\n\t\t               ((fval) & DUK_HEAPHDR_FLAGS_FLAG_MASK); \\\n\t} while (0)\n\n#define DUK_HEAPHDR_SET_FLAG_BITS(h,bits)  do { \\\n\t\tDUK_ASSERT(((bits) & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) == 0); \\\n\t\t(h)->h_flags |= (bits); \\\n\t} while (0)\n\n#define DUK_HEAPHDR_CLEAR_FLAG_BITS(h,bits)  do { \\\n\t\tDUK_ASSERT(((bits) & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) == 0); \\\n\t\t(h)->h_flags &= ~((bits)); \\\n\t} while (0)\n\n#define DUK_HEAPHDR_CHECK_FLAG_BITS(h,bits)  (((h)->h_flags & (bits)) != 0)\n\n#define DUK_HEAPHDR_SET_REACHABLE(h)      DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_REACHABLE)\n#define DUK_HEAPHDR_CLEAR_REACHABLE(h)    DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_REACHABLE)\n#define DUK_HEAPHDR_HAS_REACHABLE(h)      DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_REACHABLE)\n\n#define DUK_HEAPHDR_SET_TEMPROOT(h)       DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_TEMPROOT)\n#define DUK_HEAPHDR_CLEAR_TEMPROOT(h)     DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_TEMPROOT)\n#define DUK_HEAPHDR_HAS_TEMPROOT(h)       DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_TEMPROOT)\n\n#define DUK_HEAPHDR_SET_FINALIZABLE(h)    DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZABLE)\n#define DUK_HEAPHDR_CLEAR_FINALIZABLE(h)  DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZABLE)\n#define DUK_HEAPHDR_HAS_FINALIZABLE(h)    DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZABLE)\n\n#define DUK_HEAPHDR_SET_FINALIZED(h)      DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZED)\n#define DUK_HEAPHDR_CLEAR_FINALIZED(h)    DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZED)\n#define DUK_HEAPHDR_HAS_FINALIZED(h)      DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZED)\n\n#define DUK_HEAPHDR_SET_READONLY(h)       DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_READONLY)\n#define DUK_HEAPHDR_CLEAR_READONLY(h)     DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_READONLY)\n#define DUK_HEAPHDR_HAS_READONLY(h)       DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_READONLY)\n\n/* get or set a range of flags; m=first bit number, n=number of bits */\n#define DUK_HEAPHDR_GET_FLAG_RANGE(h,m,n)  (((h)->h_flags >> (m)) & ((1UL << (n)) - 1UL))\n\n#define DUK_HEAPHDR_SET_FLAG_RANGE(h,m,n,v)  do { \\\n\t\t(h)->h_flags = \\\n\t\t\t((h)->h_flags & (~(((1UL << (n)) - 1UL) << (m)))) \\\n\t\t\t| ((v) << (m)); \\\n\t} while (0)\n\n/* init pointer fields to null */\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n#define DUK_HEAPHDR_INIT_NULLS(h)       do { \\\n\t\tDUK_HEAPHDR_SET_NEXT((h), (void *) NULL); \\\n\t\tDUK_HEAPHDR_SET_PREV((h), (void *) NULL); \\\n\t} while (0)\n#else\n#define DUK_HEAPHDR_INIT_NULLS(h)       do { \\\n\t\tDUK_HEAPHDR_SET_NEXT((h), (void *) NULL); \\\n\t} while (0)\n#endif\n\n#define DUK_HEAPHDR_STRING_INIT_NULLS(h)  do { \\\n\t\t(h)->h_next = NULL; \\\n\t} while (0)\n\n/*\n *  Type tests\n */\n\n/* Take advantage of the fact that for DUK_HTYPE_xxx numbers the lowest bit\n * is only set for DUK_HTYPE_OBJECT (= 1).\n */\n#if 0\n#define DUK_HEAPHDR_IS_OBJECT(h) (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_OBJECT)\n#endif\n#define DUK_HEAPHDR_IS_OBJECT(h) ((h)->h_flags & 0x01UL)\n#define DUK_HEAPHDR_IS_STRING(h) (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_STRING)\n#define DUK_HEAPHDR_IS_BUFFER(h) (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_BUFFER)\n\n/*\n *  Assert helpers\n */\n\n/* Check that prev/next links are consistent: if e.g. h->prev is != NULL,\n * h->prev->next should point back to h.\n */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_heaphdr_assert_valid_subclassed(duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_assert_valid(duk_heaphdr *h);\n#define DUK_HEAPHDR_ASSERT_LINKS(heap,h)  do { duk_heaphdr_assert_links((heap), (h)); } while (0)\n#define DUK_HEAPHDR_ASSERT_VALID(h)  do { duk_heaphdr_assert_valid((h)); } while (0)\n#else\n#define DUK_HEAPHDR_ASSERT_LINKS(heap,h)  do {} while (0)\n#define DUK_HEAPHDR_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n#endif  /* DUK_HEAPHDR_H_INCLUDED */\n/* #include duk_refcount.h */\n/*\n *  Reference counting helper macros.  The macros take a thread argument\n *  and must thus always be executed in a specific thread context.  The\n *  thread argument is not really needed anymore: DECREF can operate with\n *  a heap pointer only, and INCREF needs neither.\n */\n\n#if !defined(DUK_REFCOUNT_H_INCLUDED)\n#define DUK_REFCOUNT_H_INCLUDED\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\n#if defined(DUK_USE_ROM_OBJECTS)\n/* With ROM objects \"needs refcount update\" is true when the value is\n * heap allocated and is not a ROM object.\n */\n/* XXX: double evaluation for 'tv' argument. */\n#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv) \\\n\t(DUK_TVAL_IS_HEAP_ALLOCATED((tv)) && !DUK_HEAPHDR_HAS_READONLY(DUK_TVAL_GET_HEAPHDR((tv))))\n#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h)  (!DUK_HEAPHDR_HAS_READONLY((h)))\n#else  /* DUK_USE_ROM_OBJECTS */\n/* Without ROM objects \"needs refcount update\" == is heap allocated. */\n#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)    DUK_TVAL_IS_HEAP_ALLOCATED((tv))\n#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h)  1\n#endif  /* DUK_USE_ROM_OBJECTS */\n\n/* Fast variants, inline refcount operations except for refzero handling.\n * Can be used explicitly when speed is always more important than size.\n * For a good compiler and a single file build, these are basically the\n * same as a forced inline.\n */\n#define DUK_TVAL_INCREF_FAST(thr,tv) do { \\\n\t\tduk_tval *duk__tv = (tv); \\\n\t\tDUK_ASSERT(duk__tv != NULL); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \\\n\t\t\tduk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \\\n\t\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(duk__h); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) != 0);  /* No wrapping. */ \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_DECREF_FAST(thr,tv) do { \\\n\t\tduk_tval *duk__tv = (tv); \\\n\t\tDUK_ASSERT(duk__tv != NULL); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \\\n\t\t\tduk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \\\n\t\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \\\n\t\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \\\n\t\t\t\tduk_heaphdr_refzero((thr), duk__h); \\\n\t\t\t} \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_DECREF_NORZ_FAST(thr,tv) do { \\\n\t\tduk_tval *duk__tv = (tv); \\\n\t\tDUK_ASSERT(duk__tv != NULL); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \\\n\t\t\tduk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \\\n\t\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \\\n\t\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \\\n\t\t\t\tduk_heaphdr_refzero_norz((thr), duk__h); \\\n\t\t\t} \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_INCREF_FAST(thr,h) do { \\\n\t\tduk_heaphdr *duk__h = (duk_heaphdr *) (h); \\\n\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\tif (DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(duk__h)) { \\\n\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(duk__h); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) != 0);  /* No wrapping. */ \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_FAST_RAW(thr,h,rzcall,rzcast) do { \\\n\t\tduk_heaphdr *duk__h = (duk_heaphdr *) (h); \\\n\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \\\n\t\tif (DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(duk__h)) { \\\n\t\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \\\n\t\t\t\t(rzcall)((thr), (rzcast) duk__h); \\\n\t\t\t} \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_FAST(thr,h) \\\n\tDUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero,duk_heaphdr *)\n#define DUK_HEAPHDR_DECREF_NORZ_FAST(thr,h) \\\n\tDUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero_norz,duk_heaphdr *)\n\n/* Slow variants, call to a helper to reduce code size.\n * Can be used explicitly when size is always more important than speed.\n */\n#define DUK_TVAL_INCREF_SLOW(thr,tv)         do { duk_tval_incref((tv)); } while (0)\n#define DUK_TVAL_DECREF_SLOW(thr,tv)         do { duk_tval_decref((thr), (tv)); } while (0)\n#define DUK_TVAL_DECREF_NORZ_SLOW(thr,tv)    do { duk_tval_decref_norz((thr), (tv)); } while (0)\n#define DUK_HEAPHDR_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HEAPHDR_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HSTRING_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HSTRING_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HSTRING_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HBUFFER_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HBUFFER_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HBUFFER_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HOBJECT_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HOBJECT_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HOBJECT_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n\n/* Default variants.  Selection depends on speed/size preference.\n * Concretely: with gcc 4.8.1 -Os x64 the difference in final binary\n * is about +1kB for _FAST variants.\n */\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n/* XXX: It would be nice to specialize for specific duk_hobject subtypes\n * but current refzero queue handling prevents that.\n */\n#define DUK_TVAL_INCREF(thr,tv)                DUK_TVAL_INCREF_FAST((thr),(tv))\n#define DUK_TVAL_DECREF(thr,tv)                DUK_TVAL_DECREF_FAST((thr),(tv))\n#define DUK_TVAL_DECREF_NORZ(thr,tv)           DUK_TVAL_DECREF_NORZ_FAST((thr),(tv))\n#define DUK_HEAPHDR_INCREF(thr,h)              DUK_HEAPHDR_INCREF_FAST((thr),(h))\n#define DUK_HEAPHDR_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero,duk_heaphdr *)\n#define DUK_HEAPHDR_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero_norz,duk_heaphdr *)\n#define DUK_HSTRING_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HSTRING_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hstring_refzero,duk_hstring *)\n#define DUK_HSTRING_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hstring_refzero,duk_hstring *)  /* no 'norz' variant */\n#define DUK_HOBJECT_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HOBJECT_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HOBJECT_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HBUFFER_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HBUFFER_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hbuffer_refzero,duk_hbuffer *)\n#define DUK_HBUFFER_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hbuffer_refzero,duk_hbuffer *)  /* no 'norz' variant */\n#define DUK_HCOMPFUNC_INCREF(thr,h)            DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HCOMPFUNC_DECREF(thr,h)            DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h)       DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HNATFUNC_INCREF(thr,h)             DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HNATFUNC_DECREF(thr,h)             DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HNATFUNC_DECREF_NORZ(thr,h)        DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HBUFOBJ_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HBUFOBJ_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HBUFOBJ_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HTHREAD_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HTHREAD_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HTHREAD_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#else\n#define DUK_TVAL_INCREF(thr,tv)                DUK_TVAL_INCREF_SLOW((thr),(tv))\n#define DUK_TVAL_DECREF(thr,tv)                DUK_TVAL_DECREF_SLOW((thr),(tv))\n#define DUK_TVAL_DECREF_NORZ(thr,tv)           DUK_TVAL_DECREF_NORZ_SLOW((thr),(tv))\n#define DUK_HEAPHDR_INCREF(thr,h)              DUK_HEAPHDR_INCREF_SLOW((thr),(h))\n#define DUK_HEAPHDR_DECREF(thr,h)              DUK_HEAPHDR_DECREF_SLOW((thr),(h))\n#define DUK_HEAPHDR_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HSTRING_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HSTRING_DECREF(thr,h)              DUK_HSTRING_DECREF_SLOW((thr),(h))\n#define DUK_HSTRING_DECREF_NORZ(thr,h)         DUK_HSTRING_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HOBJECT_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HOBJECT_DECREF(thr,h)              DUK_HOBJECT_DECREF_SLOW((thr),(h))\n#define DUK_HOBJECT_DECREF_NORZ(thr,h)         DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HBUFFER_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HBUFFER_DECREF(thr,h)              DUK_HBUFFER_DECREF_SLOW((thr),(h))\n#define DUK_HBUFFER_DECREF_NORZ(thr,h)         DUK_HBUFFER_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HCOMPFUNC_INCREF(thr,h)            DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HCOMPFUNC_DECREF(thr,h)            DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h)       DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HNATFUNC_INCREF(thr,h)             DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HNATFUNC_DECREF(thr,h)             DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HNATFUNC_DECREF_NORZ(thr,h)        DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HBUFOBJ_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HBUFOBJ_DECREF(thr,h)              DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HBUFOB_DECREF_NORZ(thr,h)          DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HTHREAD_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HTHREAD_DECREF(thr,h)              DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HTHREAD_DECREF_NORZ(thr,h)         DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#endif\n\n/* Convenience for some situations; the above macros don't allow NULLs\n * for performance reasons.  Macros cover only actually needed cases.\n */\n#define DUK_HEAPHDR_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HEAPHDR_DECREF((thr), (duk_heaphdr *) (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HEAPHDR_DECREF_NORZ((thr), (duk_heaphdr *) (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HOBJECT_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HOBJECT_INCREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HOBJECT_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HOBJECT_DECREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HOBJECT_DECREF_NORZ((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HBUFFER_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HBUFFER_INCREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HBUFFER_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HBUFFER_DECREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HBUFFER_DECREF_NORZ((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HTHREAD_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HTHREAD_INCREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HTHREAD_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HTHREAD_DECREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HTHREAD_DECREF_NORZ((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n\n/* Called after one or more DECREF NORZ calls to handle pending side effects.\n * At present DECREF NORZ does freeing inline but doesn't execute finalizers,\n * so these macros check for pending finalizers and execute them.  The FAST\n * variant is performance critical.\n */\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n#define DUK_REFZERO_CHECK_FAST(thr) do { \\\n\t\tduk_refzero_check_fast((thr)); \\\n\t} while (0)\n#define DUK_REFZERO_CHECK_SLOW(thr) do { \\\n\t\tduk_refzero_check_slow((thr)); \\\n\t} while (0)\n#else  /* DUK_USE_FINALIZER_SUPPORT */\n#define DUK_REFZERO_CHECK_FAST(thr) do { } while (0)\n#define DUK_REFZERO_CHECK_SLOW(thr) do { } while (0)\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Macros to set a duk_tval and update refcount of the target (decref the\n *  old value and incref the new value if necessary).  This is both performance\n *  and footprint critical; any changes made should be measured for size/speed.\n */\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_UNDEFINED(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_UNDEFINED(tv__dst); \\\n\t\tDUK_TVAL_DECREF_NORZ((thr), &tv__tmp); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_UNUSED(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NULL_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NULL(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_BOOLEAN(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NUMBER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NUMBER(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_DOUBLE(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_NAN_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NAN(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_I48(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_I32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_I32(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_U32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_U32(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#else\n#define DUK_TVAL_SET_DOUBLE_CAST_UPDREF(thr,tvptr_dst,newval) \\\n\tDUK_TVAL_SET_DOUBLE_UPDREF((thr), (tvptr_dst), (duk_double_t) (newval))\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0(thr,tvptr_dst,lf_v,lf_fp,lf_flags) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_LIGHTFUNC(tv__dst, (lf_v), (lf_fp), (lf_flags)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_STRING_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_STRING(tv__dst, (newval)); \\\n\t\tDUK_HSTRING_INCREF((thr), (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_OBJECT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_OBJECT(tv__dst, (newval)); \\\n\t\tDUK_HOBJECT_INCREF((thr), (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BUFFER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_BUFFER(tv__dst, (newval)); \\\n\t\tDUK_HBUFFER_INCREF((thr), (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_POINTER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_POINTER(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n/* DUK_TVAL_SET_TVAL_UPDREF() is used a lot in executor, property lookups,\n * etc, so it's very important for performance.  Measure when changing.\n *\n * NOTE: the source and destination duk_tval pointers may be the same, and\n * the macros MUST deal with that correctly.\n */\n\n/* Original idiom used, minimal code size. */\n#define DUK_TVAL_SET_TVAL_UPDREF_ALT0(thr,tvptr_dst,tvptr_src) do { \\\n\t\tduk_tval *tv__dst, *tv__src; duk_tval tv__tmp; \\\n\t\ttv__dst = (tvptr_dst); tv__src = (tvptr_src); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\tDUK_TVAL_INCREF((thr), tv__src); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n/* Faster alternative: avoid making a temporary copy of tvptr_dst and use\n * fast incref/decref macros.\n */\n#define DUK_TVAL_SET_TVAL_UPDREF_ALT1(thr,tvptr_dst,tvptr_src) do { \\\n\t\tduk_tval *tv__dst, *tv__src; duk_heaphdr *h__obj; \\\n\t\ttv__dst = (tvptr_dst); tv__src = (tvptr_src); \\\n\t\tDUK_TVAL_INCREF_FAST((thr), tv__src); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv__dst)) { \\\n\t\t\th__obj = DUK_TVAL_GET_HEAPHDR(tv__dst); \\\n\t\t\tDUK_ASSERT(h__obj != NULL); \\\n\t\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\t\tDUK_HEAPHDR_DECREF_FAST((thr), h__obj);  /* side effects */ \\\n\t\t} else { \\\n\t\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\t} \\\n\t} while (0)\n\n/* XXX: no optimized variants yet */\n#define DUK_TVAL_SET_UNDEFINED_UPDREF         DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ    DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0\n#define DUK_TVAL_SET_UNUSED_UPDREF            DUK_TVAL_SET_UNUSED_UPDREF_ALT0\n#define DUK_TVAL_SET_NULL_UPDREF              DUK_TVAL_SET_NULL_UPDREF_ALT0\n#define DUK_TVAL_SET_BOOLEAN_UPDREF           DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_UPDREF            DUK_TVAL_SET_NUMBER_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF    DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0\n#define DUK_TVAL_SET_DOUBLE_UPDREF            DUK_TVAL_SET_DOUBLE_UPDREF_ALT0\n#define DUK_TVAL_SET_NAN_UPDREF               DUK_TVAL_SET_NAN_UPDREF_ALT0\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_I48_UPDREF_ALT0\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_I32_UPDREF_ALT0\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_U32_UPDREF_ALT0\n#else\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF  /* XXX: fast int-to-double */\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_FASTINT_UPDREF           DUK_TVAL_SET_I48_UPDREF  /* convenience */\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF         DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0\n#define DUK_TVAL_SET_STRING_UPDREF            DUK_TVAL_SET_STRING_UPDREF_ALT0\n#define DUK_TVAL_SET_OBJECT_UPDREF            DUK_TVAL_SET_OBJECT_UPDREF_ALT0\n#define DUK_TVAL_SET_BUFFER_UPDREF            DUK_TVAL_SET_BUFFER_UPDREF_ALT0\n#define DUK_TVAL_SET_POINTER_UPDREF           DUK_TVAL_SET_POINTER_UPDREF_ALT0\n\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n/* Optimized for speed. */\n#define DUK_TVAL_SET_TVAL_UPDREF              DUK_TVAL_SET_TVAL_UPDREF_ALT1\n#define DUK_TVAL_SET_TVAL_UPDREF_FAST         DUK_TVAL_SET_TVAL_UPDREF_ALT1\n#define DUK_TVAL_SET_TVAL_UPDREF_SLOW         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#else\n/* Optimized for size. */\n#define DUK_TVAL_SET_TVAL_UPDREF              DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_FAST         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_SLOW         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#endif\n\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\n#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)     0\n#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h)   0\n\n#define DUK_TVAL_INCREF_FAST(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_FAST(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_NORZ_FAST(thr,v)       do {} while (0) /* nop */\n#define DUK_TVAL_INCREF_SLOW(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_SLOW(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_NORZ_SLOW(thr,v)       do {} while (0) /* nop */\n#define DUK_TVAL_INCREF(thr,v)                 do {} while (0) /* nop */\n#define DUK_TVAL_DECREF(thr,v)                 do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_NORZ(thr,v)            do {} while (0) /* nop */\n#define DUK_HEAPHDR_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HEAPHDR_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HEAPHDR_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HSTRING_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HSTRING_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n\n#define DUK_HCOMPFUNC_INCREF(thr,h)            do {} while (0) /* nop */\n#define DUK_HCOMPFUNC_DECREF(thr,h)            do {} while (0) /* nop */\n#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h)       do {} while (0) /* nop */\n#define DUK_HNATFUNC_INCREF(thr,h)             do {} while (0) /* nop */\n#define DUK_HNATFUNC_DECREF(thr,h)             do {} while (0) /* nop */\n#define DUK_HNATFUNC_DECREF_NORZ(thr,h)        do {} while (0) /* nop */\n#define DUK_HBUFOBJ_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFOBJ_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFOBJ_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HTHREAD_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HTHREAD_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HTHREAD_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr,h)  do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr,h)  do {} while (0) /* nop */\n\n#define DUK_REFZERO_CHECK_FAST(thr)            do {} while (0) /* nop */\n#define DUK_REFZERO_CHECK_SLOW(thr)            do {} while (0) /* nop */\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_UNDEFINED(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_UNUSED(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NULL_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NULL(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_BOOLEAN(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NUMBER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NUMBER(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_DOUBLE(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_NAN_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NAN(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_I48(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_I32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_I32(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_U32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_U32(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#else\n#define DUK_TVAL_SET_DOUBLE_CAST_UPDREF(thr,tvptr_dst,newval) \\\n\tDUK_TVAL_SET_DOUBLE_UPDREF((thr), (tvptr_dst), (duk_double_t) (newval))\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0(thr,tvptr_dst,lf_v,lf_fp,lf_flags) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_LIGHTFUNC(tv__dst, (lf_v), (lf_fp), (lf_flags)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_STRING_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_STRING(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_OBJECT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_OBJECT(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BUFFER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_BUFFER(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_POINTER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_POINTER(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_TVAL_UPDREF_ALT0(thr,tvptr_dst,tvptr_src) do { \\\n\t\tduk_tval *tv__dst, *tv__src; \\\n\t\ttv__dst = (tvptr_dst); tv__src = (tvptr_src); \\\n\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF         DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ    DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0\n#define DUK_TVAL_SET_UNUSED_UPDREF            DUK_TVAL_SET_UNUSED_UPDREF_ALT0\n#define DUK_TVAL_SET_NULL_UPDREF              DUK_TVAL_SET_NULL_UPDREF_ALT0\n#define DUK_TVAL_SET_BOOLEAN_UPDREF           DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_UPDREF            DUK_TVAL_SET_NUMBER_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF    DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0\n#define DUK_TVAL_SET_DOUBLE_UPDREF            DUK_TVAL_SET_DOUBLE_UPDREF_ALT0\n#define DUK_TVAL_SET_NAN_UPDREF               DUK_TVAL_SET_NAN_UPDREF_ALT0\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_I48_UPDREF_ALT0\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_I32_UPDREF_ALT0\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_U32_UPDREF_ALT0\n#else\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF  /* XXX: fast-int-to-double */\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_FASTINT_UPDREF           DUK_TVAL_SET_I48_UPDREF  /* convenience */\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF         DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0\n#define DUK_TVAL_SET_STRING_UPDREF            DUK_TVAL_SET_STRING_UPDREF_ALT0\n#define DUK_TVAL_SET_OBJECT_UPDREF            DUK_TVAL_SET_OBJECT_UPDREF_ALT0\n#define DUK_TVAL_SET_BUFFER_UPDREF            DUK_TVAL_SET_BUFFER_UPDREF_ALT0\n#define DUK_TVAL_SET_POINTER_UPDREF           DUK_TVAL_SET_POINTER_UPDREF_ALT0\n\n#define DUK_TVAL_SET_TVAL_UPDREF              DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_FAST         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_SLOW         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/*\n *  Some convenience macros that don't have optimized implementations now.\n */\n\n#define DUK_TVAL_SET_TVAL_UPDREF_NORZ(thr,tv_dst,tv_src) do { \\\n\t\tduk_hthread *duk__thr = (thr); \\\n\t\tduk_tval *duk__dst = (tv_dst); \\\n\t\tduk_tval *duk__src = (tv_src); \\\n\t\tDUK_UNREF(duk__thr); \\\n\t\tDUK_TVAL_DECREF_NORZ(thr, duk__dst); \\\n\t\tDUK_TVAL_SET_TVAL(duk__dst, duk__src); \\\n\t\tDUK_TVAL_INCREF(thr, duk__dst); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_U32_UPDREF_NORZ(thr,tv_dst,val) do { \\\n\t\tduk_hthread *duk__thr = (thr); \\\n\t\tduk_tval *duk__dst = (tv_dst); \\\n\t\tduk_uint32_t duk__val = (duk_uint32_t) (val); \\\n\t\tDUK_UNREF(duk__thr); \\\n\t\tDUK_TVAL_DECREF_NORZ(thr, duk__dst); \\\n\t\tDUK_TVAL_SET_U32(duk__dst, duk__val); \\\n\t} while (0)\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL_DECL void duk_refzero_check_slow(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_refzero_check_fast(duk_hthread *thr);\n#endif\nDUK_INTERNAL_DECL void duk_heaphdr_refcount_finalize_norz(duk_heap *heap, duk_heaphdr *hdr);\nDUK_INTERNAL_DECL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject *h);\n#if 0  /* Not needed: fast path handles inline; slow path uses duk_heaphdr_decref() which is needed anyway. */\nDUK_INTERNAL_DECL void duk_hstring_decref(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_hstring_decref_norz(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_hbuffer_decref(duk_hthread *thr, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_hbuffer_decref_norz(duk_hthread *thr, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_hobject_decref(duk_hthread *thr, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_hobject_decref_norz(duk_hthread *thr, duk_hobject *h);\n#endif\nDUK_INTERNAL_DECL void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_refzero_norz(duk_hthread *thr, duk_heaphdr *h);\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\nDUK_INTERNAL_DECL void duk_hstring_refzero(duk_hthread *thr, duk_hstring *h);  /* no 'norz' variant */\nDUK_INTERNAL_DECL void duk_hbuffer_refzero(duk_hthread *thr, duk_hbuffer *h);  /* no 'norz' variant */\nDUK_INTERNAL_DECL void duk_hobject_refzero(duk_hthread *thr, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_hobject_refzero_norz(duk_hthread *thr, duk_hobject *h);\n#else\nDUK_INTERNAL_DECL void duk_tval_incref(duk_tval *tv);\nDUK_INTERNAL_DECL void duk_tval_decref(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL void duk_tval_decref_norz(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL void duk_heaphdr_incref(duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h);\n#endif\n#else  /* DUK_USE_REFERENCE_COUNTING */\n/* no refcounting */\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#endif  /* DUK_REFCOUNT_H_INCLUDED */\n/* #include duk_api_internal.h */\n/*\n *  Internal API calls which have (stack and other) semantics similar\n *  to the public API.\n */\n\n#if !defined(DUK_API_INTERNAL_H_INCLUDED)\n#define DUK_API_INTERNAL_H_INCLUDED\n\n/* duk_push_sprintf constants */\n#define DUK_PUSH_SPRINTF_INITIAL_SIZE  256L\n#define DUK_PUSH_SPRINTF_SANITY_LIMIT  (1L * 1024L * 1024L * 1024L)\n\n/* Flag ORed to err_code to indicate __FILE__ / __LINE__ is not\n * blamed as source of error for error fileName / lineNumber.\n */\n#define DUK_ERRCODE_FLAG_NOBLAME_FILELINE  (1L << 24)\n\n/* Current convention is to use duk_size_t for value stack sizes and global indices,\n * and duk_idx_t for local frame indices.\n */\nDUK_INTERNAL_DECL void duk_valstack_grow_check_throw(duk_hthread *thr, duk_size_t min_bytes);\nDUK_INTERNAL_DECL duk_bool_t duk_valstack_grow_check_nothrow(duk_hthread *thr, duk_size_t min_bytes);\nDUK_INTERNAL_DECL void duk_valstack_shrink_check_nothrow(duk_hthread *thr, duk_bool_t snug);\n\nDUK_INTERNAL_DECL void duk_copy_tvals_incref(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_size_t count);\n\nDUK_INTERNAL_DECL duk_tval *duk_reserve_gap(duk_hthread *thr, duk_idx_t idx_base, duk_idx_t count);\n\nDUK_INTERNAL_DECL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_set_top_and_wipe(duk_hthread *thr, duk_idx_t top, duk_idx_t idx_wipe_start);\n\nDUK_INTERNAL_DECL void duk_dup_0(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_1(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_2(duk_hthread *thr);\n/* duk_dup_m1() would be same as duk_dup_top() */\nDUK_INTERNAL_DECL void duk_dup_m2(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_m3(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_m4(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_remove_unsafe(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_remove_m2(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_remove_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count);\nDUK_INTERNAL_DECL void duk_remove_n_unsafe(duk_hthread *thr, duk_idx_t idx, duk_idx_t count);\n\nDUK_INTERNAL_DECL duk_int_t duk_get_type_tval(duk_tval *tv);\nDUK_INTERNAL_DECL duk_uint_t duk_get_type_mask_tval(duk_tval *tv);\n\n#if defined(DUK_USE_VERBOSE_ERRORS) && defined(DUK_USE_PARANOID_ERRORS)\nDUK_INTERNAL_DECL const char *duk_get_type_name(duk_hthread *thr, duk_idx_t idx);\n#endif\nDUK_INTERNAL_DECL duk_small_uint_t duk_get_class_number(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_tval *duk_get_tval(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_tval *duk_get_tval_or_unused(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_tval *duk_require_tval(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_push_tval(duk_hthread *thr, duk_tval *tv);\n\n/* Push the current 'this' binding; throw TypeError if binding is not object\n * coercible (CheckObjectCoercible).\n */\nDUK_INTERNAL_DECL void duk_push_this_check_object_coercible(duk_hthread *thr);\n\n/* duk_push_this() + CheckObjectCoercible() + duk_to_object() */\nDUK_INTERNAL_DECL duk_hobject *duk_push_this_coercible_to_object(duk_hthread *thr);\n\n/* duk_push_this() + CheckObjectCoercible() + duk_to_string() */\nDUK_INTERNAL_DECL duk_hstring *duk_push_this_coercible_to_string(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_hstring *duk_push_uint_to_hstring(duk_hthread *thr, duk_uint_t i);\n\n/* Get a borrowed duk_tval pointer to the current 'this' binding.  Caller must\n * make sure there's an active callstack entry.  Note that the returned pointer\n * is unstable with regards to side effects.\n */\nDUK_INTERNAL_DECL duk_tval *duk_get_borrowed_this_tval(duk_hthread *thr);\n\n/* XXX: add fastint support? */\n#define duk_push_u64(thr,val) \\\n\tduk_push_number((thr), (duk_double_t) (val))\n#define duk_push_i64(thr,val) \\\n\tduk_push_number((thr), (duk_double_t) (val))\n\n/* duk_push_(u)int() is guaranteed to support at least (un)signed 32-bit range */\n#define duk_push_u32(thr,val) \\\n\tduk_push_uint((thr), (duk_uint_t) (val))\n#define duk_push_i32(thr,val) \\\n\tduk_push_int((thr), (duk_int_t) (val))\n\n/* sometimes stack and array indices need to go on the stack */\n#define duk_push_idx(thr,val) \\\n\tduk_push_int((thr), (duk_int_t) (val))\n#define duk_push_uarridx(thr,val) \\\n\tduk_push_uint((thr), (duk_uint_t) (val))\n#define duk_push_size_t(thr,val) \\\n\tduk_push_uint((thr), (duk_uint_t) (val))  /* XXX: assumed to fit for now */\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_string_notsymbol(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_callable_tval(duk_hthread *thr, duk_tval *tv);\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_bare_object(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hstring *duk_get_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hstring *duk_get_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL const char *duk_get_string_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hobject *duk_get_hobject(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hbuffer *duk_get_hbuffer(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hthread *duk_get_hthread(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_get_hcompfunc(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_get_hnatfunc(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL void *duk_get_buffer_data_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len, duk_bool_t throw_flag, duk_bool_t *out_isbuffer);\n\nDUK_INTERNAL_DECL duk_hobject *duk_get_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum);\n\nDUK_INTERNAL_DECL duk_hobject *duk_get_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask);\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask);\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject_accept_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask);\n#define duk_require_hobject_promote_lfunc(thr,idx) \\\n\tduk_require_hobject_promote_mask((thr), (idx), DUK_TYPE_MASK_LIGHTFUNC)\n#define duk_get_hobject_promote_lfunc(thr,idx) \\\n\tduk_get_hobject_promote_mask((thr), (idx), DUK_TYPE_MASK_LIGHTFUNC)\n\n#if 0  /*unused*/\nDUK_INTERNAL_DECL void *duk_get_voidptr(duk_hthread *thr, duk_idx_t idx);\n#endif\n\nDUK_INTERNAL_DECL duk_hstring *duk_known_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hobject *duk_known_hobject(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hbuffer *duk_known_hbuffer(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_known_hcompfunc(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_known_hnatfunc(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_double_t duk_to_number_tval(duk_hthread *thr, duk_tval *tv);\n\nDUK_INTERNAL_DECL duk_hstring *duk_to_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hstring *duk_to_hstring_m1(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_hstring *duk_to_hstring_acceptsymbol(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hobject *duk_to_hobject(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_double_t duk_to_number_m1(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_double_t duk_to_number_m2(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_bool_t duk_to_boolean_top_pop(duk_hthread *thr);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* only needed by debugger for now */\nDUK_INTERNAL_DECL duk_hstring *duk_safe_to_hstring(duk_hthread *thr, duk_idx_t idx);\n#endif\nDUK_INTERNAL_DECL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects);\n\nDUK_INTERNAL_DECL duk_int_t duk_to_int_clamped_raw(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped);  /* out_clamped=NULL, RangeError if outside range */\nDUK_INTERNAL_DECL duk_int_t duk_to_int_clamped(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval);\nDUK_INTERNAL_DECL duk_int_t duk_to_int_check_range(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL_DECL duk_uint8_t duk_to_uint8clamped(duk_hthread *thr, duk_idx_t idx);\n#endif\nDUK_INTERNAL_DECL duk_hstring *duk_to_property_key_hstring(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hstring *duk_require_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hstring *duk_require_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL const char *duk_require_lstring_notsymbol(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len);\nDUK_INTERNAL_DECL const char *duk_require_string_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hbuffer *duk_require_hbuffer(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hthread *duk_require_hthread(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_require_hcompfunc(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_require_hnatfunc(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum);\n\nDUK_INTERNAL_DECL void duk_push_hstring(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_push_hstring_stridx(duk_hthread *thr, duk_small_uint_t stridx);\nDUK_INTERNAL_DECL void duk_push_hstring_empty(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_push_hobject(duk_hthread *thr, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_push_hbuffer(duk_hthread *thr, duk_hbuffer *h);\n#define duk_push_hthread(thr,h) \\\n\tduk_push_hobject((thr), (duk_hobject *) (h))\n#define duk_push_hnatfunc(thr,h) \\\n\tduk_push_hobject((thr), (duk_hobject *) (h))\nDUK_INTERNAL_DECL void duk_push_hobject_bidx(duk_hthread *thr, duk_small_int_t builtin_idx);\nDUK_INTERNAL_DECL duk_hobject *duk_push_object_helper(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx);\nDUK_INTERNAL_DECL duk_hobject *duk_push_object_helper_proto(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_hobject *proto);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_push_hcompfunc(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_hboundfunc *duk_push_hboundfunc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_push_c_function_builtin(duk_hthread *thr, duk_c_function func, duk_int_t nargs);\nDUK_INTERNAL_DECL void duk_push_c_function_builtin_noconstruct(duk_hthread *thr, duk_c_function func, duk_int_t nargs);\n\n/* XXX: duk_push_harray() and duk_push_hcompfunc() are inconsistent with\n * duk_push_hobject() etc which don't create a new value.\n */\nDUK_INTERNAL_DECL duk_harray *duk_push_harray(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_harray *duk_push_harray_with_size(duk_hthread *thr, duk_uint32_t size);\nDUK_INTERNAL_DECL duk_tval *duk_push_harray_with_size_outptr(duk_hthread *thr, duk_uint32_t size);\n\nDUK_INTERNAL_DECL void duk_push_string_funcptr(duk_hthread *thr, duk_uint8_t *ptr, duk_size_t sz);\nDUK_INTERNAL_DECL void duk_push_lightfunc_name_raw(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags);\nDUK_INTERNAL_DECL void duk_push_lightfunc_name(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL void duk_push_lightfunc_tostring(duk_hthread *thr, duk_tval *tv);\n#if 0  /* not used yet */\nDUK_INTERNAL_DECL void duk_push_hnatfunc_name(duk_hthread *thr, duk_hnatfunc *h);\n#endif\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL_DECL duk_hbufobj *duk_push_bufobj_raw(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx);\n#endif\n\nDUK_INTERNAL_DECL void *duk_push_fixed_buffer_nozero(duk_hthread *thr, duk_size_t len);\nDUK_INTERNAL_DECL void *duk_push_fixed_buffer_zero(duk_hthread *thr, duk_size_t len);\n\nDUK_INTERNAL_DECL const char *duk_push_string_readable(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL const char *duk_push_string_tval_readable(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL const char *duk_push_string_tval_readable_error(duk_hthread *thr, duk_tval *tv);\n\n/* The duk_xxx_prop_stridx_short() variants expect their arguments to be short\n * enough to be packed into a single 32-bit integer argument.  Argument limits\n * vary per call; typically 16 bits are assigned to the signed value stack index\n * and the stridx.  In practice these work well for footprint with constant\n * arguments and such call sites are also easiest to verify to be correct.\n */\n\nDUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [] -> [val] */\nDUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_get_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t duk_get_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\nDUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_boolean(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop);  /* [] -> [] */\n\nDUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop(duk_hthread *thr, duk_idx_t obj_idx);\nDUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);\nDUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_xget_owndataprop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t duk_xget_owndataprop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n\nDUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [val] -> [] */\nDUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_put_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t duk_put_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n\nDUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [] -> [] */\n#if 0  /* Too few call sites to be useful. */\nDUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_del_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((obj_idx) >= -0x8000L && (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((stridx) >= 0 && (stridx) <= 0xffffL), \\\n\t duk_del_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n#endif\n#define duk_del_prop_stridx_short(thr,obj_idx,stridx) \\\n\tduk_del_prop_stridx((thr), (obj_idx), (stridx))\n\nDUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [] -> [] */\n#if 0  /* Too few call sites to be useful. */\nDUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_has_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((obj_idx) >= -0x8000L && (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((stridx) >= 0 && (stridx) <= 0xffffL), \\\n\t duk_has_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n#endif\n#define duk_has_prop_stridx_short(thr,obj_idx,stridx) \\\n\tduk_has_prop_stridx((thr), (obj_idx), (stridx))\n\nDUK_INTERNAL_DECL void duk_xdef_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t desc_flags);  /* [key val] -> [] */\n\nDUK_INTERNAL_DECL void duk_xdef_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags);  /* [val] -> [] */\n\n/* XXX: Because stridx and desc_flags have a limited range, this call could\n * always pack stridx and desc_flags into a single argument.\n */\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags);  /* [val] -> [] */\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_xdef_prop_stridx_short(thr,obj_idx,stridx,desc_flags) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x80L && (duk_int_t) (obj_idx) <= 0x7fL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (desc_flags) >= 0 && (duk_int_t) (desc_flags) <= 0xffL), \\\n\t duk_xdef_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 24) + (((duk_uint_t) (stridx)) << 8) + (duk_uint_t) (desc_flags)))\n\n#define duk_xdef_prop_wec(thr,obj_idx) \\\n\tduk_xdef_prop((thr), (obj_idx), DUK_PROPDESC_FLAGS_WEC)\n#define duk_xdef_prop_index_wec(thr,obj_idx,arr_idx) \\\n\tduk_xdef_prop_index((thr), (obj_idx), (arr_idx), DUK_PROPDESC_FLAGS_WEC)\n#define duk_xdef_prop_stridx_wec(thr,obj_idx,stridx) \\\n\tduk_xdef_prop_stridx((thr), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC)\n#define duk_xdef_prop_stridx_short_wec(thr,obj_idx,stridx) \\\n\tduk_xdef_prop_stridx_short((thr), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC)\n\n#if 0  /*unused*/\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx_builtin(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags);  /* [] -> [] */\n#endif\n\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx_thrower(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);  /* [] -> [] */\n\nDUK_INTERNAL_DECL duk_bool_t duk_get_method_stridx(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t stridx);\n\nDUK_INTERNAL_DECL void duk_pack(duk_hthread *thr, duk_idx_t count);\nDUK_INTERNAL_DECL duk_idx_t duk_unpack_array_like(duk_hthread *thr, duk_idx_t idx);\n#if 0\nDUK_INTERNAL_DECL void duk_unpack(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL void duk_push_symbol_descriptive_string(duk_hthread *thr, duk_hstring *h);\n\nDUK_INTERNAL_DECL void duk_resolve_nonbound_function(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_idx_t duk_get_top_require_min(duk_hthread *thr, duk_idx_t min_top);\nDUK_INTERNAL_DECL duk_idx_t duk_get_top_index_unsafe(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count);\nDUK_INTERNAL_DECL void duk_pop_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_2_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_3_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count);\nDUK_INTERNAL_DECL void duk_pop_nodecref_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_2_nodecref_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_3_nodecref_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_undefined(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_compact_m1(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_seal_freeze_raw(duk_hthread *thr, duk_idx_t obj_idx, duk_bool_t is_freeze);\n\nDUK_INTERNAL_DECL void duk_insert_undefined(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_insert_undefined_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count);\n\nDUK_INTERNAL_DECL void duk_concat_2(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_int_t duk_pcall_method_flags(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags);\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL_DECL void duk_to_primitive_ordinary(duk_hthread *thr, duk_idx_t idx, duk_int_t hint);\n#endif\n\nDUK_INTERNAL_DECL void duk_clear_prototype(duk_hthread *thr, duk_idx_t idx);\n\n/* Raw internal valstack access macros: access is unsafe so call site\n * must have a guarantee that the index is valid.  When that is the case,\n * using these macro results in faster and smaller code than duk_get_tval().\n * Both 'ctx' and 'idx' are evaluted multiple times, but only for asserts.\n */\n#define DUK_ASSERT_VALID_NEGIDX(thr,idx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (idx) < 0), DUK_ASSERT_EXPR(duk_is_valid_index((thr), (idx))))\n#define DUK_ASSERT_VALID_POSIDX(thr,idx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (idx) >= 0), DUK_ASSERT_EXPR(duk_is_valid_index((thr), (idx))))\n#define DUK_GET_TVAL_NEGIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_NEGIDX((thr),(idx)), ((duk_hthread *) (thr))->valstack_top + (idx))\n#define DUK_GET_TVAL_POSIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_POSIDX((thr),(idx)), ((duk_hthread *) (thr))->valstack_bottom + (idx))\n#define DUK_GET_HOBJECT_NEGIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_NEGIDX((thr),(idx)), DUK_TVAL_GET_OBJECT(((duk_hthread *) (thr))->valstack_top + (idx)))\n#define DUK_GET_HOBJECT_POSIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_POSIDX((thr),(idx)), DUK_TVAL_GET_OBJECT(((duk_hthread *) (thr))->valstack_bottom + (idx)))\n\n#define DUK_GET_THIS_TVAL_PTR(thr) \\\n\t(DUK_ASSERT_EXPR((thr)->valstack_bottom > (thr)->valstack), \\\n\t (thr)->valstack_bottom - 1)\n\nDUK_INTERNAL_DECL duk_double_t duk_time_get_ecmascript_time(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_double_t duk_time_get_ecmascript_time_nofrac(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr);\n\n#endif  /* DUK_API_INTERNAL_H_INCLUDED */\n/* #include duk_hstring.h */\n/*\n *  Heap string representation.\n *\n *  Strings are byte sequences ordinarily stored in extended UTF-8 format,\n *  allowing values larger than the official UTF-8 range (used internally)\n *  and also allowing UTF-8 encoding of surrogate pairs (CESU-8 format).\n *  Strings may also be invalid UTF-8 altogether which is the case e.g. with\n *  strings used as internal property names and raw buffers converted to\n *  strings.  In such cases the 'clen' field contains an inaccurate value.\n *\n *  ECMAScript requires support for 32-bit long strings.  However, since each\n *  16-bit codepoint can take 3 bytes in CESU-8, this representation can only\n *  support about 1.4G codepoint long strings in extreme cases.  This is not\n *  really a practical issue.\n */\n\n#if !defined(DUK_HSTRING_H_INCLUDED)\n#define DUK_HSTRING_H_INCLUDED\n\n/* Impose a maximum string length for now.  Restricted artificially to\n * ensure adding a heap header length won't overflow size_t.  The limit\n * should be synchronized with DUK_HBUFFER_MAX_BYTELEN.\n *\n * E5.1 makes provisions to support strings longer than 4G characters.\n * This limit should be eliminated on 64-bit platforms (and increased\n * closer to maximum support on 32-bit platforms).\n */\n\n#if defined(DUK_USE_STRLEN16)\n#define DUK_HSTRING_MAX_BYTELEN                     (0x0000ffffUL)\n#else\n#define DUK_HSTRING_MAX_BYTELEN                     (0x7fffffffUL)\n#endif\n\n/* XXX: could add flags for \"is valid CESU-8\" (ECMAScript compatible strings),\n * \"is valid UTF-8\", \"is valid extended UTF-8\" (internal strings are not,\n * regexp bytecode is), and \"contains non-BMP characters\".  These are not\n * needed right now.\n */\n\n/* With lowmem builds the high 16 bits of duk_heaphdr are used for other\n * purposes, so this leaves 7 duk_heaphdr flags and 9 duk_hstring flags.\n */\n#define DUK_HSTRING_FLAG_ASCII                      DUK_HEAPHDR_USER_FLAG(0)  /* string is ASCII, clen == blen */\n#define DUK_HSTRING_FLAG_ARRIDX                     DUK_HEAPHDR_USER_FLAG(1)  /* string is a valid array index */\n#define DUK_HSTRING_FLAG_SYMBOL                     DUK_HEAPHDR_USER_FLAG(2)  /* string is a symbol (invalid utf-8) */\n#define DUK_HSTRING_FLAG_HIDDEN                     DUK_HEAPHDR_USER_FLAG(3)  /* string is a hidden symbol (implies symbol, Duktape 1.x internal string) */\n#define DUK_HSTRING_FLAG_RESERVED_WORD              DUK_HEAPHDR_USER_FLAG(4)  /* string is a reserved word (non-strict) */\n#define DUK_HSTRING_FLAG_STRICT_RESERVED_WORD       DUK_HEAPHDR_USER_FLAG(5)  /* string is a reserved word (strict) */\n#define DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS          DUK_HEAPHDR_USER_FLAG(6)  /* string is 'eval' or 'arguments' */\n#define DUK_HSTRING_FLAG_EXTDATA                    DUK_HEAPHDR_USER_FLAG(7)  /* string data is external (duk_hstring_external) */\n#define DUK_HSTRING_FLAG_PINNED_LITERAL             DUK_HEAPHDR_USER_FLAG(8)  /* string is a literal, and pinned */\n\n#define DUK_HSTRING_HAS_ASCII(x)                    DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII)\n#define DUK_HSTRING_HAS_ARRIDX(x)                   DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX)\n#define DUK_HSTRING_HAS_SYMBOL(x)                   DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL)\n#define DUK_HSTRING_HAS_HIDDEN(x)                   DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN)\n#define DUK_HSTRING_HAS_RESERVED_WORD(x)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD)\n#define DUK_HSTRING_HAS_STRICT_RESERVED_WORD(x)     DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD)\n#define DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(x)        DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS)\n#define DUK_HSTRING_HAS_EXTDATA(x)                  DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA)\n#define DUK_HSTRING_HAS_PINNED_LITERAL(x)           DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL)\n\n#define DUK_HSTRING_SET_ASCII(x)                    DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII)\n#define DUK_HSTRING_SET_ARRIDX(x)                   DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX)\n#define DUK_HSTRING_SET_SYMBOL(x)                   DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL)\n#define DUK_HSTRING_SET_HIDDEN(x)                   DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN)\n#define DUK_HSTRING_SET_RESERVED_WORD(x)            DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD)\n#define DUK_HSTRING_SET_STRICT_RESERVED_WORD(x)     DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD)\n#define DUK_HSTRING_SET_EVAL_OR_ARGUMENTS(x)        DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS)\n#define DUK_HSTRING_SET_EXTDATA(x)                  DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA)\n#define DUK_HSTRING_SET_PINNED_LITERAL(x)           DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL)\n\n#define DUK_HSTRING_CLEAR_ASCII(x)                  DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII)\n#define DUK_HSTRING_CLEAR_ARRIDX(x)                 DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX)\n#define DUK_HSTRING_CLEAR_SYMBOL(x)                 DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL)\n#define DUK_HSTRING_CLEAR_HIDDEN(x)                 DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN)\n#define DUK_HSTRING_CLEAR_RESERVED_WORD(x)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD)\n#define DUK_HSTRING_CLEAR_STRICT_RESERVED_WORD(x)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD)\n#define DUK_HSTRING_CLEAR_EVAL_OR_ARGUMENTS(x)      DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS)\n#define DUK_HSTRING_CLEAR_EXTDATA(x)                DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA)\n#define DUK_HSTRING_CLEAR_PINNED_LITERAL(x)         DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL)\n\n#if 0  /* Slightly smaller code without explicit flag, but explicit flag\n        * is very useful when 'clen' is dropped.\n        */\n#define DUK_HSTRING_IS_ASCII(x)                     (DUK_HSTRING_GET_BYTELEN((x)) == DUK_HSTRING_GET_CHARLEN((x)))\n#endif\n#define DUK_HSTRING_IS_ASCII(x)                     DUK_HSTRING_HAS_ASCII((x))  /* lazily set! */\n#define DUK_HSTRING_IS_EMPTY(x)                     (DUK_HSTRING_GET_BYTELEN((x)) == 0)\n\n#if defined(DUK_USE_STRHASH16)\n#define DUK_HSTRING_GET_HASH(x)                     ((x)->hdr.h_flags >> 16)\n#define DUK_HSTRING_SET_HASH(x,v) do { \\\n\t\t(x)->hdr.h_flags = ((x)->hdr.h_flags & 0x0000ffffUL) | ((v) << 16); \\\n\t} while (0)\n#else\n#define DUK_HSTRING_GET_HASH(x)                     ((x)->hash)\n#define DUK_HSTRING_SET_HASH(x,v) do { \\\n\t\t(x)->hash = (v); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_STRLEN16)\n#define DUK_HSTRING_GET_BYTELEN(x)                  ((x)->hdr.h_strextra16)\n#define DUK_HSTRING_SET_BYTELEN(x,v) do { \\\n\t\t(x)->hdr.h_strextra16 = (v); \\\n\t} while (0)\n#if defined(DUK_USE_HSTRING_CLEN)\n#define DUK_HSTRING_GET_CHARLEN(x)                  duk_hstring_get_charlen((x))\n#define DUK_HSTRING_SET_CHARLEN(x,v) do { \\\n\t\t(x)->clen16 = (v); \\\n\t} while (0)\n#else\n#define DUK_HSTRING_GET_CHARLEN(x)                  duk_hstring_get_charlen((x))\n#define DUK_HSTRING_SET_CHARLEN(x,v) do { \\\n\t\tDUK_ASSERT(0);  /* should never be called */ \\\n\t} while (0)\n#endif\n#else\n#define DUK_HSTRING_GET_BYTELEN(x)                  ((x)->blen)\n#define DUK_HSTRING_SET_BYTELEN(x,v) do { \\\n\t\t(x)->blen = (v); \\\n\t} while (0)\n#define DUK_HSTRING_GET_CHARLEN(x)                  duk_hstring_get_charlen((x))\n#define DUK_HSTRING_SET_CHARLEN(x,v) do { \\\n\t\t(x)->clen = (v); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_HSTRING_EXTDATA)\n#define DUK_HSTRING_GET_EXTDATA(x) \\\n\t((x)->extdata)\n#define DUK_HSTRING_GET_DATA(x) \\\n\t(DUK_HSTRING_HAS_EXTDATA((x)) ? \\\n\t\tDUK_HSTRING_GET_EXTDATA((const duk_hstring_external *) (x)) : ((const duk_uint8_t *) ((x) + 1)))\n#else\n#define DUK_HSTRING_GET_DATA(x) \\\n\t((const duk_uint8_t *) ((x) + 1))\n#endif\n\n#define DUK_HSTRING_GET_DATA_END(x) \\\n\t(DUK_HSTRING_GET_DATA((x)) + (x)->blen)\n\n/* Marker value; in E5 2^32-1 is not a valid array index (2^32-2 is highest\n * valid).\n */\n#define DUK_HSTRING_NO_ARRAY_INDEX  (0xffffffffUL)\n\n#if defined(DUK_USE_HSTRING_ARRIDX)\n#define DUK_HSTRING_GET_ARRIDX_FAST(h)  ((h)->arridx)\n#define DUK_HSTRING_GET_ARRIDX_SLOW(h)  ((h)->arridx)\n#else\n/* Get array index related to string (or return DUK_HSTRING_NO_ARRAY_INDEX);\n * avoids helper call if string has no array index value.\n */\n#define DUK_HSTRING_GET_ARRIDX_FAST(h)  \\\n\t(DUK_HSTRING_HAS_ARRIDX((h)) ? duk_js_to_arrayindex_hstring_fast_known((h)) : DUK_HSTRING_NO_ARRAY_INDEX)\n\n/* Slower but more compact variant. */\n#define DUK_HSTRING_GET_ARRIDX_SLOW(h)  \\\n\t(duk_js_to_arrayindex_hstring_fast((h)))\n#endif\n\n/* XXX: these actually fit into duk_hstring */\n#define DUK_SYMBOL_TYPE_HIDDEN 0\n#define DUK_SYMBOL_TYPE_GLOBAL 1\n#define DUK_SYMBOL_TYPE_LOCAL 2\n#define DUK_SYMBOL_TYPE_WELLKNOWN 3\n\n/* Assertion for duk_hstring validity. */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hstring_assert_valid(duk_hstring *h);\n#define DUK_HSTRING_ASSERT_VALID(h)  do { duk_hstring_assert_valid((h)); } while (0)\n#else\n#define DUK_HSTRING_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Misc\n */\n\nstruct duk_hstring {\n\t/* Smaller heaphdr than for other objects, because strings are held\n\t * in string intern table which requires no link pointers.  Much of\n\t * the 32-bit flags field is unused by flags, so we can stuff a 16-bit\n\t * field in there.\n\t */\n\tduk_heaphdr_string hdr;\n\n\t/* String hash. */\n#if defined(DUK_USE_STRHASH16)\n\t/* If 16-bit hash is in use, stuff it into duk_heaphdr_string flags. */\n#else\n\tduk_uint32_t hash;\n#endif\n\n\t/* Precomputed array index (or DUK_HSTRING_NO_ARRAY_INDEX). */\n#if defined(DUK_USE_HSTRING_ARRIDX)\n\tduk_uarridx_t arridx;\n#endif\n\n\t/* Length in bytes (not counting NUL term). */\n#if defined(DUK_USE_STRLEN16)\n\t/* placed in duk_heaphdr_string */\n#else\n\tduk_uint32_t blen;\n#endif\n\n\t/* Length in codepoints (must be E5 compatible). */\n#if defined(DUK_USE_STRLEN16)\n#if defined(DUK_USE_HSTRING_CLEN)\n\tduk_uint16_t clen16;\n#else\n\t/* computed live */\n#endif\n#else\n\tduk_uint32_t clen;\n#endif\n\n\t/*\n\t *  String data of 'blen+1' bytes follows (+1 for NUL termination\n\t *  convenience for C API).  No alignment needs to be guaranteed\n\t *  for strings, but fields above should guarantee alignment-by-4\n\t *  (but not alignment-by-8).\n\t */\n};\n\n/* The external string struct is defined even when the feature is inactive. */\nstruct duk_hstring_external {\n\tduk_hstring str;\n\n\t/*\n\t *  For an external string, the NUL-terminated string data is stored\n\t *  externally.  The user must guarantee that data behind this pointer\n\t *  doesn't change while it's used.\n\t */\n\n\tconst duk_uint8_t *extdata;\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, duk_uint_t pos, duk_bool_t surrogate_aware);\nDUK_INTERNAL_DECL duk_bool_t duk_hstring_equals_ascii_cstring(duk_hstring *h, const char *cstr);\nDUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);\n#if !defined(DUK_USE_HSTRING_LAZY_CLEN)\nDUK_INTERNAL_DECL void duk_hstring_init_charlen(duk_hstring *h);\n#endif\n\n#endif  /* DUK_HSTRING_H_INCLUDED */\n/* #include duk_hobject.h */\n/*\n *  Heap object representation.\n *\n *  Heap objects are used for ECMAScript objects, arrays, and functions,\n *  but also for internal control like declarative and object environment\n *  records.  Compiled functions, native functions, and threads are also\n *  objects but with an extended C struct.\n *\n *  Objects provide the required ECMAScript semantics and exotic behaviors\n *  especially for property access.\n *\n *  Properties are stored in three conceptual parts:\n *\n *    1. A linear 'entry part' contains ordered key-value-attributes triples\n *       and is the main method of string properties.\n *\n *    2. An optional linear 'array part' is used for array objects to store a\n *       (dense) range of [0,N[ array indexed entries with default attributes\n *       (writable, enumerable, configurable).  If the array part would become\n *       sparse or non-default attributes are required, the array part is\n *       abandoned and moved to the 'entry part'.\n *\n *    3. An optional 'hash part' is used to optimize lookups of the entry\n *       part; it is used only for objects with sufficiently many properties\n *       and can be abandoned without loss of information.\n *\n *  These three conceptual parts are stored in a single memory allocated area.\n *  This minimizes memory allocation overhead but also means that all three\n *  parts are resized together, and makes property access a bit complicated.\n */\n\n#if !defined(DUK_HOBJECT_H_INCLUDED)\n#define DUK_HOBJECT_H_INCLUDED\n\n/* Object flags.  Make sure this stays in sync with debugger object\n * inspection code.\n */\n\n/* XXX: some flags are object subtype specific (e.g. common to all function\n * subtypes, duk_harray, etc) and could be reused for different subtypes.\n */\n#define DUK_HOBJECT_FLAG_EXTENSIBLE            DUK_HEAPHDR_USER_FLAG(0)   /* object is extensible */\n#define DUK_HOBJECT_FLAG_CONSTRUCTABLE         DUK_HEAPHDR_USER_FLAG(1)   /* object is constructable */\n#define DUK_HOBJECT_FLAG_CALLABLE              DUK_HEAPHDR_USER_FLAG(2)   /* object is callable */\n#define DUK_HOBJECT_FLAG_BOUNDFUNC             DUK_HEAPHDR_USER_FLAG(3)   /* object established using Function.prototype.bind() */\n#define DUK_HOBJECT_FLAG_COMPFUNC              DUK_HEAPHDR_USER_FLAG(4)   /* object is a compiled function (duk_hcompfunc) */\n#define DUK_HOBJECT_FLAG_NATFUNC               DUK_HEAPHDR_USER_FLAG(5)   /* object is a native function (duk_hnatfunc) */\n#define DUK_HOBJECT_FLAG_BUFOBJ                DUK_HEAPHDR_USER_FLAG(6)   /* object is a buffer object (duk_hbufobj) (always exotic) */\n#define DUK_HOBJECT_FLAG_FASTREFS              DUK_HEAPHDR_USER_FLAG(7)   /* object has no fields needing DECREF/marking beyond base duk_hobject header */\n#define DUK_HOBJECT_FLAG_ARRAY_PART            DUK_HEAPHDR_USER_FLAG(8)   /* object has an array part (a_size may still be 0) */\n#define DUK_HOBJECT_FLAG_STRICT                DUK_HEAPHDR_USER_FLAG(9)   /* function: function object is strict */\n#define DUK_HOBJECT_FLAG_NOTAIL                DUK_HEAPHDR_USER_FLAG(10)  /* function: function must not be tail called */\n#define DUK_HOBJECT_FLAG_NEWENV                DUK_HEAPHDR_USER_FLAG(11)  /* function: create new environment when called (see duk_hcompfunc) */\n#define DUK_HOBJECT_FLAG_NAMEBINDING           DUK_HEAPHDR_USER_FLAG(12)  /* function: create binding for func name (function templates only, used for named function expressions) */\n#define DUK_HOBJECT_FLAG_CREATEARGS            DUK_HEAPHDR_USER_FLAG(13)  /* function: create an arguments object on function call */\n#define DUK_HOBJECT_FLAG_HAVE_FINALIZER        DUK_HEAPHDR_USER_FLAG(14)  /* object has a callable (own) finalizer property */\n#define DUK_HOBJECT_FLAG_EXOTIC_ARRAY          DUK_HEAPHDR_USER_FLAG(15)  /* 'Array' object, array length and index exotic behavior */\n#define DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ      DUK_HEAPHDR_USER_FLAG(16)  /* 'String' object, array index exotic behavior */\n#define DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS      DUK_HEAPHDR_USER_FLAG(17)  /* 'Arguments' object and has arguments exotic behavior (non-strict callee) */\n#define DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ       DUK_HEAPHDR_USER_FLAG(18)  /* 'Proxy' object */\n#define DUK_HOBJECT_FLAG_SPECIAL_CALL          DUK_HEAPHDR_USER_FLAG(19)  /* special casing in call behavior, for .call(), .apply(), etc. */\n\n#define DUK_HOBJECT_FLAG_CLASS_BASE            DUK_HEAPHDR_USER_FLAG_NUMBER(20)\n#define DUK_HOBJECT_FLAG_CLASS_BITS            5\n\n#define DUK_HOBJECT_GET_CLASS_NUMBER(h)        \\\n\tDUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS)\n#define DUK_HOBJECT_SET_CLASS_NUMBER(h,v)      \\\n\tDUK_HEAPHDR_SET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS, (v))\n\n#define DUK_HOBJECT_GET_CLASS_MASK(h)          \\\n\t(1UL << DUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS))\n\n/* Macro for creating flag initializer from a class number.\n * Unsigned type cast is needed to avoid warnings about coercing\n * a signed integer to an unsigned one; the largest class values\n * have the highest bit (bit 31) set which causes this.\n */\n#define DUK_HOBJECT_CLASS_AS_FLAGS(v)          (((duk_uint_t) (v)) << DUK_HOBJECT_FLAG_CLASS_BASE)\n\n/* E5 Section 8.6.2 + custom classes */\n#define DUK_HOBJECT_CLASS_NONE                 0\n#define DUK_HOBJECT_CLASS_OBJECT               1\n#define DUK_HOBJECT_CLASS_ARRAY                2\n#define DUK_HOBJECT_CLASS_FUNCTION             3\n#define DUK_HOBJECT_CLASS_ARGUMENTS            4\n#define DUK_HOBJECT_CLASS_BOOLEAN              5\n#define DUK_HOBJECT_CLASS_DATE                 6\n#define DUK_HOBJECT_CLASS_ERROR                7\n#define DUK_HOBJECT_CLASS_JSON                 8\n#define DUK_HOBJECT_CLASS_MATH                 9\n#define DUK_HOBJECT_CLASS_NUMBER               10\n#define DUK_HOBJECT_CLASS_REGEXP               11\n#define DUK_HOBJECT_CLASS_STRING               12\n#define DUK_HOBJECT_CLASS_GLOBAL               13\n#define DUK_HOBJECT_CLASS_SYMBOL               14\n#define DUK_HOBJECT_CLASS_OBJENV               15  /* custom */\n#define DUK_HOBJECT_CLASS_DECENV               16  /* custom */\n#define DUK_HOBJECT_CLASS_POINTER              17  /* custom */\n#define DUK_HOBJECT_CLASS_THREAD               18  /* custom; implies DUK_HOBJECT_IS_THREAD */\n#define DUK_HOBJECT_CLASS_BUFOBJ_MIN           19\n#define DUK_HOBJECT_CLASS_ARRAYBUFFER          19  /* implies DUK_HOBJECT_IS_BUFOBJ */\n#define DUK_HOBJECT_CLASS_DATAVIEW             20\n#define DUK_HOBJECT_CLASS_INT8ARRAY            21\n#define DUK_HOBJECT_CLASS_UINT8ARRAY           22\n#define DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY    23\n#define DUK_HOBJECT_CLASS_INT16ARRAY           24\n#define DUK_HOBJECT_CLASS_UINT16ARRAY          25\n#define DUK_HOBJECT_CLASS_INT32ARRAY           26\n#define DUK_HOBJECT_CLASS_UINT32ARRAY          27\n#define DUK_HOBJECT_CLASS_FLOAT32ARRAY         28\n#define DUK_HOBJECT_CLASS_FLOAT64ARRAY         29\n#define DUK_HOBJECT_CLASS_BUFOBJ_MAX           29\n#define DUK_HOBJECT_CLASS_MAX                  29\n\n/* Class masks. */\n#define DUK_HOBJECT_CMASK_ALL                  ((1UL << (DUK_HOBJECT_CLASS_MAX + 1)) - 1UL)\n#define DUK_HOBJECT_CMASK_NONE                 (1UL << DUK_HOBJECT_CLASS_NONE)\n#define DUK_HOBJECT_CMASK_ARGUMENTS            (1UL << DUK_HOBJECT_CLASS_ARGUMENTS)\n#define DUK_HOBJECT_CMASK_ARRAY                (1UL << DUK_HOBJECT_CLASS_ARRAY)\n#define DUK_HOBJECT_CMASK_BOOLEAN              (1UL << DUK_HOBJECT_CLASS_BOOLEAN)\n#define DUK_HOBJECT_CMASK_DATE                 (1UL << DUK_HOBJECT_CLASS_DATE)\n#define DUK_HOBJECT_CMASK_ERROR                (1UL << DUK_HOBJECT_CLASS_ERROR)\n#define DUK_HOBJECT_CMASK_FUNCTION             (1UL << DUK_HOBJECT_CLASS_FUNCTION)\n#define DUK_HOBJECT_CMASK_JSON                 (1UL << DUK_HOBJECT_CLASS_JSON)\n#define DUK_HOBJECT_CMASK_MATH                 (1UL << DUK_HOBJECT_CLASS_MATH)\n#define DUK_HOBJECT_CMASK_NUMBER               (1UL << DUK_HOBJECT_CLASS_NUMBER)\n#define DUK_HOBJECT_CMASK_OBJECT               (1UL << DUK_HOBJECT_CLASS_OBJECT)\n#define DUK_HOBJECT_CMASK_REGEXP               (1UL << DUK_HOBJECT_CLASS_REGEXP)\n#define DUK_HOBJECT_CMASK_STRING               (1UL << DUK_HOBJECT_CLASS_STRING)\n#define DUK_HOBJECT_CMASK_GLOBAL               (1UL << DUK_HOBJECT_CLASS_GLOBAL)\n#define DUK_HOBJECT_CMASK_SYMBOL               (1UL << DUK_HOBJECT_CLASS_SYMBOL)\n#define DUK_HOBJECT_CMASK_OBJENV               (1UL << DUK_HOBJECT_CLASS_OBJENV)\n#define DUK_HOBJECT_CMASK_DECENV               (1UL << DUK_HOBJECT_CLASS_DECENV)\n#define DUK_HOBJECT_CMASK_POINTER              (1UL << DUK_HOBJECT_CLASS_POINTER)\n#define DUK_HOBJECT_CMASK_ARRAYBUFFER          (1UL << DUK_HOBJECT_CLASS_ARRAYBUFFER)\n#define DUK_HOBJECT_CMASK_DATAVIEW             (1UL << DUK_HOBJECT_CLASS_DATAVIEW)\n#define DUK_HOBJECT_CMASK_INT8ARRAY            (1UL << DUK_HOBJECT_CLASS_INT8ARRAY)\n#define DUK_HOBJECT_CMASK_UINT8ARRAY           (1UL << DUK_HOBJECT_CLASS_UINT8ARRAY)\n#define DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY    (1UL << DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY)\n#define DUK_HOBJECT_CMASK_INT16ARRAY           (1UL << DUK_HOBJECT_CLASS_INT16ARRAY)\n#define DUK_HOBJECT_CMASK_UINT16ARRAY          (1UL << DUK_HOBJECT_CLASS_UINT16ARRAY)\n#define DUK_HOBJECT_CMASK_INT32ARRAY           (1UL << DUK_HOBJECT_CLASS_INT32ARRAY)\n#define DUK_HOBJECT_CMASK_UINT32ARRAY          (1UL << DUK_HOBJECT_CLASS_UINT32ARRAY)\n#define DUK_HOBJECT_CMASK_FLOAT32ARRAY         (1UL << DUK_HOBJECT_CLASS_FLOAT32ARRAY)\n#define DUK_HOBJECT_CMASK_FLOAT64ARRAY         (1UL << DUK_HOBJECT_CLASS_FLOAT64ARRAY)\n\n#define DUK_HOBJECT_CMASK_ALL_BUFOBJS \\\n\t(DUK_HOBJECT_CMASK_ARRAYBUFFER | \\\n\t DUK_HOBJECT_CMASK_DATAVIEW | \\\n\t DUK_HOBJECT_CMASK_INT8ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT8ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY | \\\n\t DUK_HOBJECT_CMASK_INT16ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT16ARRAY | \\\n\t DUK_HOBJECT_CMASK_INT32ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT32ARRAY | \\\n\t DUK_HOBJECT_CMASK_FLOAT32ARRAY | \\\n\t DUK_HOBJECT_CMASK_FLOAT64ARRAY)\n\n#define DUK_HOBJECT_IS_OBJENV(h)               (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_OBJENV)\n#define DUK_HOBJECT_IS_DECENV(h)               (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_DECENV)\n#define DUK_HOBJECT_IS_ENV(h)                  (DUK_HOBJECT_IS_OBJENV((h)) || DUK_HOBJECT_IS_DECENV((h)))\n#define DUK_HOBJECT_IS_ARRAY(h)                DUK_HOBJECT_HAS_EXOTIC_ARRAY((h))  /* Rely on class Array <=> exotic Array */\n#define DUK_HOBJECT_IS_BOUNDFUNC(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_IS_COMPFUNC(h)             DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_IS_NATFUNC(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_IS_BUFOBJ(h)               DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#else\n#define DUK_HOBJECT_IS_BUFOBJ(h)               0\n#endif\n#define DUK_HOBJECT_IS_THREAD(h)               (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_THREAD)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_IS_PROXY(h)                DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ((h))\n#else\n#define DUK_HOBJECT_IS_PROXY(h)                0\n#endif\n\n#define DUK_HOBJECT_IS_NONBOUND_FUNCTION(h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \\\n                                                        DUK_HOBJECT_FLAG_COMPFUNC | \\\n                                                        DUK_HOBJECT_FLAG_NATFUNC)\n\n#define DUK_HOBJECT_IS_FUNCTION(h)             DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \\\n                                                        DUK_HOBJECT_FLAG_BOUNDFUNC | \\\n                                                        DUK_HOBJECT_FLAG_COMPFUNC | \\\n                                                        DUK_HOBJECT_FLAG_NATFUNC)\n\n#define DUK_HOBJECT_IS_CALLABLE(h)             DUK_HOBJECT_HAS_CALLABLE((h))\n\n/* Object has any exotic behavior(s). */\n#define DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS      (DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | \\\n                                                DUK_HOBJECT_FLAG_BUFOBJ | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#define DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR(h)     DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS)\n\n/* Object has any virtual properties (not counting Proxy behavior). */\n#define DUK_HOBJECT_VIRTUAL_PROPERTY_FLAGS     (DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | \\\n                                                DUK_HOBJECT_FLAG_BUFOBJ)\n#define DUK_HOBJECT_HAS_VIRTUAL_PROPERTIES(h)  DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_VIRTUAL_PROPERTY_FLAGS)\n\n#define DUK_HOBJECT_HAS_EXTENSIBLE(h)          DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)\n#define DUK_HOBJECT_HAS_CONSTRUCTABLE(h)       DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)\n#define DUK_HOBJECT_HAS_CALLABLE(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE)\n#define DUK_HOBJECT_HAS_BOUNDFUNC(h)           DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_HAS_COMPFUNC(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_HAS_NATFUNC(h)             DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_HAS_BUFOBJ(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#else\n#define DUK_HOBJECT_HAS_BUFOBJ(h)              0\n#endif\n#define DUK_HOBJECT_HAS_FASTREFS(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)\n#define DUK_HOBJECT_HAS_ARRAY_PART(h)          DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)\n#define DUK_HOBJECT_HAS_STRICT(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)\n#define DUK_HOBJECT_HAS_NOTAIL(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)\n#define DUK_HOBJECT_HAS_NEWENV(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)\n#define DUK_HOBJECT_HAS_NAMEBINDING(h)         DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)\n#define DUK_HOBJECT_HAS_CREATEARGS(h)          DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)\n#define DUK_HOBJECT_HAS_HAVE_FINALIZER(h)      DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER)\n#define DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)        DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)\n#define DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)\n#define DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)     DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#else\n#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)     0\n#endif\n#define DUK_HOBJECT_HAS_SPECIAL_CALL(h)        DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)\n\n#define DUK_HOBJECT_SET_EXTENSIBLE(h)          DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)\n#define DUK_HOBJECT_SET_CONSTRUCTABLE(h)       DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)\n#define DUK_HOBJECT_SET_CALLABLE(h)            DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE)\n#define DUK_HOBJECT_SET_BOUNDFUNC(h)           DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_SET_COMPFUNC(h)            DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_SET_NATFUNC(h)             DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_SET_BUFOBJ(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#endif\n#define DUK_HOBJECT_SET_FASTREFS(h)            DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)\n#define DUK_HOBJECT_SET_ARRAY_PART(h)          DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)\n#define DUK_HOBJECT_SET_STRICT(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)\n#define DUK_HOBJECT_SET_NOTAIL(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)\n#define DUK_HOBJECT_SET_NEWENV(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)\n#define DUK_HOBJECT_SET_NAMEBINDING(h)         DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)\n#define DUK_HOBJECT_SET_CREATEARGS(h)          DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)\n#define DUK_HOBJECT_SET_HAVE_FINALIZER(h)      DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER)\n#define DUK_HOBJECT_SET_EXOTIC_ARRAY(h)        DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)\n#define DUK_HOBJECT_SET_EXOTIC_STRINGOBJ(h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)\n#define DUK_HOBJECT_SET_EXOTIC_ARGUMENTS(h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_SET_EXOTIC_PROXYOBJ(h)     DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#endif\n#define DUK_HOBJECT_SET_SPECIAL_CALL(h)        DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)\n\n#define DUK_HOBJECT_CLEAR_EXTENSIBLE(h)        DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)\n#define DUK_HOBJECT_CLEAR_CONSTRUCTABLE(h)     DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)\n#define DUK_HOBJECT_CLEAR_CALLABLE(h)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE)\n#define DUK_HOBJECT_CLEAR_BOUNDFUNC(h)         DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_CLEAR_COMPFUNC(h)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_CLEAR_NATFUNC(h)           DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_CLEAR_BUFOBJ(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#endif\n#define DUK_HOBJECT_CLEAR_FASTREFS(h)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)\n#define DUK_HOBJECT_CLEAR_ARRAY_PART(h)        DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)\n#define DUK_HOBJECT_CLEAR_STRICT(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)\n#define DUK_HOBJECT_CLEAR_NOTAIL(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)\n#define DUK_HOBJECT_CLEAR_NEWENV(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)\n#define DUK_HOBJECT_CLEAR_NAMEBINDING(h)       DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)\n#define DUK_HOBJECT_CLEAR_CREATEARGS(h)        DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)\n#define DUK_HOBJECT_CLEAR_HAVE_FINALIZER(h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER)\n#define DUK_HOBJECT_CLEAR_EXOTIC_ARRAY(h)      DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)\n#define DUK_HOBJECT_CLEAR_EXOTIC_STRINGOBJ(h)  DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)\n#define DUK_HOBJECT_CLEAR_EXOTIC_ARGUMENTS(h)  DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_CLEAR_EXOTIC_PROXYOBJ(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#endif\n#define DUK_HOBJECT_CLEAR_SPECIAL_CALL(h)      DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)\n\n/* Object can/cannot use FASTREFS, i.e. has no strong reference fields beyond\n * duk_hobject base header.  This is used just for asserts so doesn't need to\n * be optimized.\n */\n#define DUK_HOBJECT_PROHIBITS_FASTREFS(h) \\\n\t(DUK_HOBJECT_IS_COMPFUNC((h)) || DUK_HOBJECT_IS_DECENV((h)) || DUK_HOBJECT_IS_OBJENV((h)) || \\\n\t DUK_HOBJECT_IS_BUFOBJ((h)) || DUK_HOBJECT_IS_THREAD((h)) || DUK_HOBJECT_IS_PROXY((h)) || \\\n\t DUK_HOBJECT_IS_BOUNDFUNC((h)))\n#define DUK_HOBJECT_ALLOWS_FASTREFS(h) (!DUK_HOBJECT_PROHIBITS_FASTREFS((h)))\n\n/* Flags used for property attributes in duk_propdesc and packed flags.\n * Must fit into 8 bits.\n */\n#define DUK_PROPDESC_FLAG_WRITABLE              (1U << 0)    /* E5 Section 8.6.1 */\n#define DUK_PROPDESC_FLAG_ENUMERABLE            (1U << 1)    /* E5 Section 8.6.1 */\n#define DUK_PROPDESC_FLAG_CONFIGURABLE          (1U << 2)    /* E5 Section 8.6.1 */\n#define DUK_PROPDESC_FLAG_ACCESSOR              (1U << 3)    /* accessor */\n#define DUK_PROPDESC_FLAG_VIRTUAL               (1U << 4)    /* property is virtual: used in duk_propdesc, never stored\n                                                             * (used by e.g. buffer virtual properties)\n                                                             */\n#define DUK_PROPDESC_FLAGS_MASK                 (DUK_PROPDESC_FLAG_WRITABLE | \\\n                                                 DUK_PROPDESC_FLAG_ENUMERABLE | \\\n                                                 DUK_PROPDESC_FLAG_CONFIGURABLE | \\\n                                                 DUK_PROPDESC_FLAG_ACCESSOR)\n\n/* Additional flags which are passed in the same flags argument as property\n * flags but are not stored in object properties.\n */\n#define DUK_PROPDESC_FLAG_NO_OVERWRITE          (1U << 4)    /* internal define property: skip write silently if exists */\n\n/* Convenience defines for property attributes. */\n#define DUK_PROPDESC_FLAGS_NONE                 0\n#define DUK_PROPDESC_FLAGS_W                    (DUK_PROPDESC_FLAG_WRITABLE)\n#define DUK_PROPDESC_FLAGS_E                    (DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_PROPDESC_FLAGS_C                    (DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_PROPDESC_FLAGS_WE                   (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_PROPDESC_FLAGS_WC                   (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_PROPDESC_FLAGS_EC                   (DUK_PROPDESC_FLAG_ENUMERABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_PROPDESC_FLAGS_WEC                  (DUK_PROPDESC_FLAG_WRITABLE | \\\n                                                 DUK_PROPDESC_FLAG_ENUMERABLE | \\\n                                                 DUK_PROPDESC_FLAG_CONFIGURABLE)\n\n/* Flags for duk_hobject_get_own_propdesc() and variants. */\n#define DUK_GETDESC_FLAG_PUSH_VALUE          (1U << 0)  /* push value to stack */\n#define DUK_GETDESC_FLAG_IGNORE_PROTOLOOP    (1U << 1)  /* don't throw for prototype loop */\n\n/*\n *  Macro for object validity check\n *\n *  Assert for currently guaranteed relations between flags, for instance.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hobject_assert_valid(duk_hobject *h);\n#define DUK_HOBJECT_ASSERT_VALID(h)  do { duk_hobject_assert_valid((h)); } while (0)\n#else\n#define DUK_HOBJECT_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Macros to access the 'props' allocation.\n */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HOBJECT_GET_PROPS(heap,h) \\\n\t((duk_uint8_t *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, ((duk_heaphdr *) (h))->h_extra16))\n#define DUK_HOBJECT_SET_PROPS(heap,h,x) do { \\\n\t\t((duk_heaphdr *) (h))->h_extra16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \\\n\t} while (0)\n#else\n#define DUK_HOBJECT_GET_PROPS(heap,h) \\\n\t((h)->props)\n#define DUK_HOBJECT_SET_PROPS(heap,h,x) do { \\\n\t\t(h)->props = (duk_uint8_t *) (x); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_HOBJECT_LAYOUT_1)\n/* LAYOUT 1 */\n#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \\\n\t((duk_hstring **) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) \\\n\t))\n#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \\\n\t((duk_propvalue *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_hstring *) \\\n\t))\n#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \\\n\t((duk_uint8_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \\\n\t))\n#define DUK_HOBJECT_A_GET_BASE(heap,h) \\\n\t((duk_tval *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) \\\n\t))\n#define DUK_HOBJECT_H_GET_BASE(heap,h) \\\n\t((duk_uint32_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \\\n\t( \\\n\t\t(n_ent) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t(n_arr) * sizeof(duk_tval) + \\\n\t\t(n_hash) * sizeof(duk_uint32_t) \\\n\t)\n#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash)  do { \\\n\t\t(set_e_k) = (duk_hstring **) (void *) (p_base); \\\n\t\t(set_e_pv) = (duk_propvalue *) (void *) ((set_e_k) + (n_ent)); \\\n\t\t(set_e_f) = (duk_uint8_t *) (void *) ((set_e_pv) + (n_ent)); \\\n\t\t(set_a) = (duk_tval *) (void *) ((set_e_f) + (n_ent)); \\\n\t\t(set_h) = (duk_uint32_t *) (void *) ((set_a) + (n_arr)); \\\n\t} while (0)\n#elif defined(DUK_USE_HOBJECT_LAYOUT_2)\n/* LAYOUT 2 */\n#if (DUK_USE_ALIGN_BY == 4)\n#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) ((4 - (e_sz)) & 0x03)\n#elif (DUK_USE_ALIGN_BY == 8)\n#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) ((8 - (e_sz)) & 0x07)\n#elif (DUK_USE_ALIGN_BY == 1)\n#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) 0\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \\\n\t((duk_hstring **) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) \\\n\t))\n#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \\\n\t((duk_propvalue *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) \\\n\t))\n#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \\\n\t((duk_uint8_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \\\n\t))\n#define DUK_HOBJECT_A_GET_BASE(heap,h) \\\n\t((duk_tval *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t\tDUK_HOBJECT_E_FLAG_PADDING(DUK_HOBJECT_GET_ESIZE((h))) \\\n\t))\n#define DUK_HOBJECT_H_GET_BASE(heap,h) \\\n\t((duk_uint32_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t\tDUK_HOBJECT_E_FLAG_PADDING(DUK_HOBJECT_GET_ESIZE((h))) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \\\n\t( \\\n\t\t(n_ent) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\tDUK_HOBJECT_E_FLAG_PADDING((n_ent)) + \\\n\t\t(n_arr) * sizeof(duk_tval) + \\\n\t\t(n_hash) * sizeof(duk_uint32_t) \\\n\t)\n#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash)  do { \\\n\t\t(set_e_pv) = (duk_propvalue *) (void *) (p_base); \\\n\t\t(set_e_k) = (duk_hstring **) (void *) ((set_e_pv) + (n_ent)); \\\n\t\t(set_e_f) = (duk_uint8_t *) (void *) ((set_e_k) + (n_ent)); \\\n\t\t(set_a) = (duk_tval *) (void *) (((duk_uint8_t *) (set_e_f)) + \\\n\t\t                                 sizeof(duk_uint8_t) * (n_ent) + \\\n\t\t                                 DUK_HOBJECT_E_FLAG_PADDING((n_ent))); \\\n\t\t(set_h) = (duk_uint32_t *) (void *) ((set_a) + (n_arr)); \\\n\t} while (0)\n#elif defined(DUK_USE_HOBJECT_LAYOUT_3)\n/* LAYOUT 3 */\n#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \\\n\t((duk_hstring **) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \\\n\t((duk_propvalue *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) \\\n\t))\n#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \\\n\t((duk_uint8_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_propvalue) + sizeof(duk_hstring *)) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) + \\\n\t\t\tDUK_HOBJECT_GET_HSIZE((h)) * sizeof(duk_uint32_t) \\\n\t))\n#define DUK_HOBJECT_A_GET_BASE(heap,h) \\\n\t((duk_tval *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) \\\n\t))\n#define DUK_HOBJECT_H_GET_BASE(heap,h) \\\n\t((duk_uint32_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_propvalue) + sizeof(duk_hstring *)) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \\\n\t( \\\n\t\t(n_ent) * (sizeof(duk_propvalue) + sizeof(duk_hstring *) + sizeof(duk_uint8_t)) + \\\n\t\t(n_arr) * sizeof(duk_tval) + \\\n\t\t(n_hash) * sizeof(duk_uint32_t) \\\n\t)\n#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash)  do { \\\n\t\t(set_e_pv) = (duk_propvalue *) (void *) (p_base); \\\n\t\t(set_a) = (duk_tval *) (void *) ((set_e_pv) + (n_ent)); \\\n\t\t(set_e_k) = (duk_hstring **) (void *) ((set_a) + (n_arr)); \\\n\t\t(set_h) = (duk_uint32_t *) (void *) ((set_e_k) + (n_ent)); \\\n\t\t(set_e_f) = (duk_uint8_t *) (void *) ((set_h) + (n_hash)); \\\n\t} while (0)\n#else\n#error invalid hobject layout defines\n#endif  /* hobject property layout */\n\n#define DUK_HOBJECT_P_ALLOC_SIZE(h) \\\n\tDUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE((h)), DUK_HOBJECT_GET_ASIZE((h)), DUK_HOBJECT_GET_HSIZE((h)))\n\n#define DUK_HOBJECT_E_GET_KEY(heap,h,i)              (DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_KEY_PTR(heap,h,i)          (&DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_VALUE(heap,h,i)            (DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_VALUE_PTR(heap,h,i)        (&DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_VALUE_TVAL(heap,h,i)       (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)\n#define DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap,h,i)   (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)\n#define DUK_HOBJECT_E_GET_VALUE_GETTER(heap,h,i)     (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)\n#define DUK_HOBJECT_E_GET_VALUE_GETTER_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)\n#define DUK_HOBJECT_E_GET_VALUE_SETTER(heap,h,i)     (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)\n#define DUK_HOBJECT_E_GET_VALUE_SETTER_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)\n#define DUK_HOBJECT_E_GET_FLAGS(heap,h,i)            (DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_FLAGS_PTR(heap,h,i)        (&DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_A_GET_VALUE(heap,h,i)            (DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_A_GET_VALUE_PTR(heap,h,i)        (&DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_H_GET_INDEX(heap,h,i)            (DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_H_GET_INDEX_PTR(heap,h,i)        (&DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])\n\n#define DUK_HOBJECT_E_SET_KEY(heap,h,i,k)  do { \\\n\t\tDUK_HOBJECT_E_GET_KEY((heap), (h), (i)) = (k); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)) = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE_TVAL(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE_GETTER(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE_SETTER(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_FLAGS(heap,h,i,f)  do { \\\n\t\tDUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) = (duk_uint8_t) (f); \\\n\t} while (0)\n#define DUK_HOBJECT_A_SET_VALUE(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_A_GET_VALUE((heap), (h), (i)) = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_A_SET_VALUE_TVAL(heap,h,i,v) \\\n\tDUK_HOBJECT_A_SET_VALUE((heap), (h), (i), (v))  /* alias for above */\n#define DUK_HOBJECT_H_SET_INDEX(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_H_GET_INDEX((heap), (h), (i)) = (v); \\\n\t} while (0)\n\n#define DUK_HOBJECT_E_SET_FLAG_BITS(heap,h,i,mask)  do { \\\n\t\tDUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] |= (mask); \\\n\t} while (0)\n\n#define DUK_HOBJECT_E_CLEAR_FLAG_BITS(heap,h,i,mask)  do { \\\n\t\tDUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] &= ~(mask); \\\n\t} while (0)\n\n#define DUK_HOBJECT_E_SLOT_IS_WRITABLE(heap,h,i)     ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_WRITABLE) != 0)\n#define DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(heap,h,i)   ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)\n#define DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)\n#define DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap,h,i)     ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ACCESSOR) != 0)\n\n#define DUK_HOBJECT_E_SLOT_SET_WRITABLE(heap,h,i)        DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)\n#define DUK_HOBJECT_E_SLOT_SET_ENUMERABLE(heap,h,i)      DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_HOBJECT_E_SLOT_SET_CONFIGURABLE(heap,h,i)    DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_HOBJECT_E_SLOT_SET_ACCESSOR(heap,h,i)        DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)\n\n#define DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(heap,h,i)      DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)\n#define DUK_HOBJECT_E_SLOT_CLEAR_ENUMERABLE(heap,h,i)    DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_HOBJECT_E_SLOT_CLEAR_CONFIGURABLE(heap,h,i)  DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(heap,h,i)      DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)\n\n#define DUK_PROPDESC_IS_WRITABLE(p)             (((p)->flags & DUK_PROPDESC_FLAG_WRITABLE) != 0)\n#define DUK_PROPDESC_IS_ENUMERABLE(p)           (((p)->flags & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)\n#define DUK_PROPDESC_IS_CONFIGURABLE(p)         (((p)->flags & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)\n#define DUK_PROPDESC_IS_ACCESSOR(p)             (((p)->flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0)\n\n#define DUK_HOBJECT_HASHIDX_UNUSED              0xffffffffUL\n#define DUK_HOBJECT_HASHIDX_DELETED             0xfffffffeUL\n\n/*\n *  Macros for accessing size fields\n */\n\n#if defined(DUK_USE_OBJSIZES16)\n#define DUK_HOBJECT_GET_ESIZE(h) ((h)->e_size16)\n#define DUK_HOBJECT_SET_ESIZE(h,v) do { (h)->e_size16 = (v); } while (0)\n#define DUK_HOBJECT_GET_ENEXT(h) ((h)->e_next16)\n#define DUK_HOBJECT_SET_ENEXT(h,v) do { (h)->e_next16 = (v); } while (0)\n#define DUK_HOBJECT_POSTINC_ENEXT(h) ((h)->e_next16++)\n#define DUK_HOBJECT_GET_ASIZE(h) ((h)->a_size16)\n#define DUK_HOBJECT_SET_ASIZE(h,v) do { (h)->a_size16 = (v); } while (0)\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n#define DUK_HOBJECT_GET_HSIZE(h) ((h)->h_size16)\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { (h)->h_size16 = (v); } while (0)\n#else\n#define DUK_HOBJECT_GET_HSIZE(h) 0\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { DUK_ASSERT((v) == 0); } while (0)\n#endif\n#else\n#define DUK_HOBJECT_GET_ESIZE(h) ((h)->e_size)\n#define DUK_HOBJECT_SET_ESIZE(h,v) do { (h)->e_size = (v); } while (0)\n#define DUK_HOBJECT_GET_ENEXT(h) ((h)->e_next)\n#define DUK_HOBJECT_SET_ENEXT(h,v) do { (h)->e_next = (v); } while (0)\n#define DUK_HOBJECT_POSTINC_ENEXT(h) ((h)->e_next++)\n#define DUK_HOBJECT_GET_ASIZE(h) ((h)->a_size)\n#define DUK_HOBJECT_SET_ASIZE(h,v) do { (h)->a_size = (v); } while (0)\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n#define DUK_HOBJECT_GET_HSIZE(h) ((h)->h_size)\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { (h)->h_size = (v); } while (0)\n#else\n#define DUK_HOBJECT_GET_HSIZE(h) 0\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { DUK_ASSERT((v) == 0); } while (0)\n#endif\n#endif\n\n/*\n *  Misc\n */\n\n/* Maximum prototype traversal depth.  Sanity limit which handles e.g.\n * prototype loops (even complex ones like 1->2->3->4->2->3->4->2->3->4).\n */\n#define DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY      10000L\n\n/*\n *  ECMAScript [[Class]]\n */\n\n/* range check not necessary because all 4-bit values are mapped */\n#define DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(n)  duk_class_number_to_stridx[(n)]\n\n#define DUK_HOBJECT_GET_CLASS_STRING(heap,h)          \\\n\tDUK_HEAP_GET_STRING( \\\n\t\t(heap), \\\n\t\tDUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(DUK_HOBJECT_GET_CLASS_NUMBER((h))) \\\n\t)\n\n/*\n *  Macros for property handling\n */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HOBJECT_GET_PROTOTYPE(heap,h) \\\n\t((duk_hobject *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->prototype16))\n#define DUK_HOBJECT_SET_PROTOTYPE(heap,h,x) do { \\\n\t\t(h)->prototype16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \\\n\t} while (0)\n#else\n#define DUK_HOBJECT_GET_PROTOTYPE(heap,h) \\\n\t((h)->prototype)\n#define DUK_HOBJECT_SET_PROTOTYPE(heap,h,x) do { \\\n\t\t(h)->prototype = (x); \\\n\t} while (0)\n#endif\n\n/* Set prototype, DECREF earlier value, INCREF new value (tolerating NULLs). */\n#define DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr,h,p)       duk_hobject_set_prototype_updref((thr), (h), (p))\n\n/* Set initial prototype, assume NULL previous prototype, INCREF new value,\n * tolerate NULL.\n */\n#define DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr,h,proto) do { \\\n\t\tduk_hthread *duk__thr = (thr); \\\n\t\tduk_hobject *duk__obj = (h); \\\n\t\tduk_hobject *duk__proto = (proto); \\\n\t\tDUK_UNREF(duk__thr); \\\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(duk__thr->heap, duk__obj) == NULL); \\\n\t\tDUK_HOBJECT_SET_PROTOTYPE(duk__thr->heap, duk__obj, duk__proto); \\\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(duk__thr, duk__proto); \\\n\t} while (0)\n\n/*\n *  Finalizer check\n */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HOBJECT_HAS_FINALIZER_FAST(heap,h) duk_hobject_has_finalizer_fast_raw((heap), (h))\n#else\n#define DUK_HOBJECT_HAS_FINALIZER_FAST(heap,h) duk_hobject_has_finalizer_fast_raw((h))\n#endif\n\n/*\n *  Resizing and hash behavior\n */\n\n/* Sanity limit on max number of properties (allocated, not necessarily used).\n * This is somewhat arbitrary, but if we're close to 2**32 properties some\n * algorithms will fail (e.g. hash size selection, next prime selection).\n * Also, we use negative array/entry table indices to indicate 'not found',\n * so anything above 0x80000000 will cause trouble now.\n */\n#if defined(DUK_USE_OBJSIZES16)\n#define DUK_HOBJECT_MAX_PROPERTIES       0x0000ffffUL\n#else\n#define DUK_HOBJECT_MAX_PROPERTIES       0x3fffffffUL   /* 2**30-1 ~= 1G properties */\n#endif\n\n/* internal align target for props allocation, must be 2*n for some n */\n#if (DUK_USE_ALIGN_BY == 4)\n#define DUK_HOBJECT_ALIGN_TARGET         4\n#elif (DUK_USE_ALIGN_BY == 8)\n#define DUK_HOBJECT_ALIGN_TARGET         8\n#elif (DUK_USE_ALIGN_BY == 1)\n#define DUK_HOBJECT_ALIGN_TARGET         1\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\n/*\n *  PC-to-line constants\n */\n\n#define DUK_PC2LINE_SKIP    64\n\n/* maximum length for a SKIP-1 diffstream: 35 bits per entry, rounded up to bytes */\n#define DUK_PC2LINE_MAX_DIFF_LENGTH    (((DUK_PC2LINE_SKIP - 1) * 35 + 7) / 8)\n\n/*\n *  Struct defs\n */\n\nstruct duk_propaccessor {\n\tduk_hobject *get;\n\tduk_hobject *set;\n};\n\nunion duk_propvalue {\n\t/* The get/set pointers could be 16-bit pointer compressed but it\n\t * would make no difference on 32-bit platforms because duk_tval is\n\t * 8 bytes or more anyway.\n\t */\n\tduk_tval v;\n\tduk_propaccessor a;\n};\n\nstruct duk_propdesc {\n\t/* read-only values 'lifted' for ease of use */\n\tduk_small_uint_t flags;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\n\t/* for updating (all are set to < 0 for virtual properties) */\n\tduk_int_t e_idx;  /* prop index in 'entry part', < 0 if not there */\n\tduk_int_t h_idx;  /* prop index in 'hash part', < 0 if not there */\n\tduk_int_t a_idx;  /* prop index in 'array part', < 0 if not there */\n};\n\nstruct duk_hobject {\n\tduk_heaphdr hdr;\n\n\t/*\n\t *  'props' contains {key,value,flags} entries, optional array entries, and\n\t *  an optional hash lookup table for non-array entries in a single 'sliced'\n\t *  allocation.  There are several layout options, which differ slightly in\n\t *  generated code size/speed and alignment/padding; duk_features.h selects\n\t *  the layout used.\n\t *\n\t *  Layout 1 (DUK_USE_HOBJECT_LAYOUT_1):\n\t *\n\t *    e_size * sizeof(duk_hstring *)         bytes of   entry keys (e_next gc reachable)\n\t *    e_size * sizeof(duk_propvalue)         bytes of   entry values (e_next gc reachable)\n\t *    e_size * sizeof(duk_uint8_t)           bytes of   entry flags (e_next gc reachable)\n\t *    a_size * sizeof(duk_tval)              bytes of   (opt) array values (plain only) (all gc reachable)\n\t *    h_size * sizeof(duk_uint32_t)          bytes of   (opt) hash indexes to entries (e_size),\n\t *                                                      0xffffffffUL = unused, 0xfffffffeUL = deleted\n\t *\n\t *  Layout 2 (DUK_USE_HOBJECT_LAYOUT_2):\n\t *\n\t *    e_size * sizeof(duk_propvalue)         bytes of   entry values (e_next gc reachable)\n\t *    e_size * sizeof(duk_hstring *)         bytes of   entry keys (e_next gc reachable)\n\t *    e_size * sizeof(duk_uint8_t) + pad     bytes of   entry flags (e_next gc reachable)\n\t *    a_size * sizeof(duk_tval)              bytes of   (opt) array values (plain only) (all gc reachable)\n\t *    h_size * sizeof(duk_uint32_t)          bytes of   (opt) hash indexes to entries (e_size),\n\t *                                                      0xffffffffUL = unused, 0xfffffffeUL = deleted\n\t *\n\t *  Layout 3 (DUK_USE_HOBJECT_LAYOUT_3):\n\t *\n\t *    e_size * sizeof(duk_propvalue)         bytes of   entry values (e_next gc reachable)\n\t *    a_size * sizeof(duk_tval)              bytes of   (opt) array values (plain only) (all gc reachable)\n\t *    e_size * sizeof(duk_hstring *)         bytes of   entry keys (e_next gc reachable)\n\t *    h_size * sizeof(duk_uint32_t)          bytes of   (opt) hash indexes to entries (e_size),\n\t *                                                      0xffffffffUL = unused, 0xfffffffeUL = deleted\n\t *    e_size * sizeof(duk_uint8_t)           bytes of   entry flags (e_next gc reachable)\n\t *\n\t *  In layout 1, the 'e_next' count is rounded to 4 or 8 on platforms\n\t *  requiring 4 or 8 byte alignment.  This ensures proper alignment\n\t *  for the entries, at the cost of memory footprint.  However, it's\n\t *  probably preferable to use another layout on such platforms instead.\n\t *\n\t *  In layout 2, the key and value parts are swapped to avoid padding\n\t *  the key array on platforms requiring alignment by 8.  The flags part\n\t *  is padded to get alignment for array entries.  The 'e_next' count does\n\t *  not need to be rounded as in layout 1.\n\t *\n\t *  In layout 3, entry values and array values are always aligned properly,\n\t *  and assuming pointers are at most 8 bytes, so are the entry keys.  Hash\n\t *  indices will be properly aligned (assuming pointers are at least 4 bytes).\n\t *  Finally, flags don't need additional alignment.  This layout provides\n\t *  compact allocations without padding (even on platforms with alignment\n\t *  requirements) at the cost of a bit slower lookups.\n\t *\n\t *  Objects with few keys don't have a hash index; keys are looked up linearly,\n\t *  which is cache efficient because the keys are consecutive.  Larger objects\n\t *  have a hash index part which contains integer indexes to the entries part.\n\t *\n\t *  A single allocation reduces memory allocation overhead but requires more\n\t *  work when any part needs to be resized.  A sliced allocation for entries\n\t *  makes linear key matching faster on most platforms (more locality) and\n\t *  skimps on flags size (which would be followed by 3 bytes of padding in\n\t *  most architectures if entries were placed in a struct).\n\t *\n\t *  'props' also contains internal properties distinguished with a non-BMP\n\t *  prefix.  Often used properties should be placed early in 'props' whenever\n\t *  possible to make accessing them as fast a possible.\n\t */\n\n#if defined(DUK_USE_HEAPPTR16)\n\t/* Located in duk_heaphdr h_extra16.  Subclasses of duk_hobject (like\n\t * duk_hcompfunc) are not free to use h_extra16 for this reason.\n\t */\n#else\n\tduk_uint8_t *props;\n#endif\n\n\t/* prototype: the only internal property lifted outside 'e' as it is so central */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t prototype16;\n#else\n\tduk_hobject *prototype;\n#endif\n\n#if defined(DUK_USE_OBJSIZES16)\n\tduk_uint16_t e_size16;\n\tduk_uint16_t e_next16;\n\tduk_uint16_t a_size16;\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tduk_uint16_t h_size16;\n#endif\n#else\n\tduk_uint32_t e_size;  /* entry part size */\n\tduk_uint32_t e_next;  /* index for next new key ([0,e_next[ are gc reachable) */\n\tduk_uint32_t a_size;  /* array part size (entirely gc reachable) */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tduk_uint32_t h_size;  /* hash part size or 0 if unused */\n#endif\n#endif\n};\n\n/*\n *  Exposed data\n */\n\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL duk_uint8_t duk_class_number_to_stridx[32];\n#endif  /* !DUK_SINGLE_FILE */\n\n/*\n *  Prototypes\n */\n\n/* alloc and init */\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_harray *duk_harray_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_hcompfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_hnatfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hboundfunc *duk_hboundfunc_alloc(duk_heap *heap, duk_uint_t hobject_flags);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL_DECL duk_hbufobj *duk_hbufobj_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\n#endif\nDUK_INTERNAL_DECL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hthread *duk_hthread_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hdecenv *duk_hdecenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hobjenv *duk_hobjenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hproxy *duk_hproxy_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\n\n/* resize */\nDUK_INTERNAL_DECL void duk_hobject_realloc_props(duk_hthread *thr,\n                                                 duk_hobject *obj,\n                                                 duk_uint32_t new_e_size,\n                                                 duk_uint32_t new_a_size,\n                                                 duk_uint32_t new_h_size,\n                                                 duk_bool_t abandon_array);\nDUK_INTERNAL_DECL void duk_hobject_resize_entrypart(duk_hthread *thr,\n                                                    duk_hobject *obj,\n                                                    duk_uint32_t new_e_size);\n#if 0  /*unused*/\nDUK_INTERNAL_DECL void duk_hobject_resize_arraypart(duk_hthread *thr,\n                                                    duk_hobject *obj,\n                                                    duk_uint32_t new_a_size);\n#endif\n\n/* low-level property functions */\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_find_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_get_own_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags);\n\n/* core property functions */\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_tval *tv_val, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key);\n\n/* internal property functions */\n#define DUK_DELPROP_FLAG_THROW  (1U << 0)\n#define DUK_DELPROP_FLAG_FORCE  (1U << 1)\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key);\nDUK_INTERNAL_DECL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags);\nDUK_INTERNAL_DECL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj);\n#if defined(DUK_USE_HEAPPTR16)\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_heap *heap, duk_hobject *obj);\n#else\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_hobject *obj);\n#endif\n\n/* helpers for defineProperty() and defineProperties() */\nDUK_INTERNAL_DECL void duk_hobject_prepare_property_descriptor(duk_hthread *thr,\n                                                               duk_idx_t idx_in,\n                                                               duk_uint_t *out_defprop_flags,\n                                                               duk_idx_t *out_idx_value,\n                                                               duk_hobject **out_getter,\n                                                               duk_hobject **out_setter);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,\n                                                                duk_uint_t defprop_flags,\n                                                                duk_hobject *obj,\n                                                                duk_hstring *key,\n                                                                duk_idx_t idx_value,\n                                                                duk_hobject *get,\n                                                                duk_hobject *set,\n                                                                duk_bool_t throw_flag);\n\n/* Object built-in methods */\nDUK_INTERNAL_DECL void duk_hobject_object_get_own_property_descriptor(duk_hthread *thr, duk_idx_t obj_idx);\nDUK_INTERNAL_DECL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_object_ownprop_helper(duk_hthread *thr, duk_small_uint_t required_desc_flags);\n\n/* internal properties */\nDUK_INTERNAL_DECL duk_tval *duk_hobject_get_internal_value_tval_ptr(duk_heap *heap, duk_hobject *obj);\nDUK_INTERNAL_DECL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *heap, duk_hobject *obj);\nDUK_INTERNAL_DECL duk_harray *duk_hobject_get_formals(duk_hthread *thr, duk_hobject *obj);\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_get_varmap(duk_hthread *thr, duk_hobject *obj);\n\n/* hobject management functions */\nDUK_INTERNAL_DECL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj);\n\n/* ES2015 proxy */\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_proxy_check(duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler);\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_resolve_proxy_target(duk_hobject *obj);\n#endif\n\n/* enumeration */\nDUK_INTERNAL_DECL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint_t enum_flags);\nDUK_INTERNAL_DECL duk_ret_t duk_hobject_get_enumerated_keys(duk_hthread *thr, duk_small_uint_t enum_flags);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_enumerator_next(duk_hthread *thr, duk_bool_t get_value);\n\n/* macros */\nDUK_INTERNAL_DECL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject *h, duk_hobject *p);\n\n/* pc2line */\n#if defined(DUK_USE_PC2LINE)\nDUK_INTERNAL_DECL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr *instrs, duk_uint_fast32_t length);\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_hobject_pc2line_query(duk_hthread *thr, duk_idx_t idx_func, duk_uint_fast32_t pc);\n#endif\n\n/* misc */\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, duk_hobject *h, duk_hobject *p, duk_bool_t ignore_loop);\n\n#if !defined(DUK_USE_OBJECT_BUILTIN)\n/* These declarations are needed when related built-in is disabled and\n * genbuiltins.py won't automatically emit the declerations.\n */\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_string(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_hthread *thr);\n#endif\n\n#endif  /* DUK_HOBJECT_H_INCLUDED */\n/* #include duk_hcompfunc.h */\n/*\n *  Heap compiled function (ECMAScript function) representation.\n *\n *  There is a single data buffer containing the ECMAScript function's\n *  bytecode, constants, and inner functions.\n */\n\n#if !defined(DUK_HCOMPFUNC_H_INCLUDED)\n#define DUK_HCOMPFUNC_H_INCLUDED\n\n/*\n *  Field accessor macros\n */\n\n/* XXX: casts could be improved, especially for GET/SET DATA */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HCOMPFUNC_GET_DATA(heap,h) \\\n\t((duk_hbuffer_fixed *) (void *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->data16))\n#define DUK_HCOMPFUNC_SET_DATA(heap,h,v) do { \\\n\t\t(h)->data16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_FUNCS(heap,h)  \\\n\t((duk_hobject **) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->funcs16)))\n#define DUK_HCOMPFUNC_SET_FUNCS(heap,h,v)  do { \\\n\t\t(h)->funcs16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_BYTECODE(heap,h)  \\\n\t((duk_instr_t *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->bytecode16)))\n#define DUK_HCOMPFUNC_SET_BYTECODE(heap,h,v)  do { \\\n\t\t(h)->bytecode16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_LEXENV(heap,h)  \\\n\t((duk_hobject *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->lex_env16)))\n#define DUK_HCOMPFUNC_SET_LEXENV(heap,h,v)  do { \\\n\t\t(h)->lex_env16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_VARENV(heap,h)  \\\n\t((duk_hobject *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->var_env16)))\n#define DUK_HCOMPFUNC_SET_VARENV(heap,h,v)  do { \\\n\t\t(h)->var_env16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#else\n#define DUK_HCOMPFUNC_GET_DATA(heap,h)  ((duk_hbuffer_fixed *) (void *) (h)->data)\n#define DUK_HCOMPFUNC_SET_DATA(heap,h,v) do { \\\n\t\t(h)->data = (duk_hbuffer *) (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_FUNCS(heap,h)  ((h)->funcs)\n#define DUK_HCOMPFUNC_SET_FUNCS(heap,h,v)  do { \\\n\t\t(h)->funcs = (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_BYTECODE(heap,h)  ((h)->bytecode)\n#define DUK_HCOMPFUNC_SET_BYTECODE(heap,h,v)  do { \\\n\t\t(h)->bytecode = (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_LEXENV(heap,h)  ((h)->lex_env)\n#define DUK_HCOMPFUNC_SET_LEXENV(heap,h,v)  do { \\\n\t\t(h)->lex_env = (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_VARENV(heap,h)  ((h)->var_env)\n#define DUK_HCOMPFUNC_SET_VARENV(heap,h,v)  do { \\\n\t\t(h)->var_env = (v); \\\n\t} while (0)\n#endif\n\n/*\n *  Accessor macros for function specific data areas\n */\n\n/* Note: assumes 'data' is always a fixed buffer */\n#define DUK_HCOMPFUNC_GET_BUFFER_BASE(heap,h)  \\\n\tDUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPFUNC_GET_DATA((heap), (h)))\n\n#define DUK_HCOMPFUNC_GET_CONSTS_BASE(heap,h)  \\\n\t((duk_tval *) (void *) DUK_HCOMPFUNC_GET_BUFFER_BASE((heap), (h)))\n\n#define DUK_HCOMPFUNC_GET_FUNCS_BASE(heap,h)  \\\n\tDUK_HCOMPFUNC_GET_FUNCS((heap), (h))\n\n#define DUK_HCOMPFUNC_GET_CODE_BASE(heap,h)  \\\n\tDUK_HCOMPFUNC_GET_BYTECODE((heap), (h))\n\n#define DUK_HCOMPFUNC_GET_CONSTS_END(heap,h)  \\\n\t((duk_tval *) (void *) DUK_HCOMPFUNC_GET_FUNCS((heap), (h)))\n\n#define DUK_HCOMPFUNC_GET_FUNCS_END(heap,h)  \\\n\t((duk_hobject **) (void *) DUK_HCOMPFUNC_GET_BYTECODE((heap), (h)))\n\n/* XXX: double evaluation of DUK_HCOMPFUNC_GET_DATA() */\n#define DUK_HCOMPFUNC_GET_CODE_END(heap,h)  \\\n\t((duk_instr_t *) (void *) (DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPFUNC_GET_DATA((heap), (h))) + \\\n\t                DUK_HBUFFER_GET_SIZE((duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA((heap), h))))\n\n#define DUK_HCOMPFUNC_GET_CONSTS_SIZE(heap,h)  \\\n\t( \\\n\t (duk_size_t) \\\n\t ( \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CONSTS_END((heap), (h))) - \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CONSTS_BASE((heap), (h))) \\\n\t ) \\\n\t)\n\n#define DUK_HCOMPFUNC_GET_FUNCS_SIZE(heap,h)  \\\n\t( \\\n\t (duk_size_t) \\\n\t ( \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_FUNCS_END((heap), (h))) - \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_FUNCS_BASE((heap), (h))) \\\n\t ) \\\n\t)\n\n#define DUK_HCOMPFUNC_GET_CODE_SIZE(heap,h)  \\\n\t( \\\n\t (duk_size_t) \\\n\t ( \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CODE_END((heap),(h))) - \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CODE_BASE((heap),(h))) \\\n\t ) \\\n\t)\n\n#define DUK_HCOMPFUNC_GET_CONSTS_COUNT(heap,h)  \\\n\t((duk_size_t) (DUK_HCOMPFUNC_GET_CONSTS_SIZE((heap), (h)) / sizeof(duk_tval)))\n\n#define DUK_HCOMPFUNC_GET_FUNCS_COUNT(heap,h)  \\\n\t((duk_size_t) (DUK_HCOMPFUNC_GET_FUNCS_SIZE((heap), (h)) / sizeof(duk_hobject *)))\n\n#define DUK_HCOMPFUNC_GET_CODE_COUNT(heap,h)  \\\n\t((duk_size_t) (DUK_HCOMPFUNC_GET_CODE_SIZE((heap), (h)) / sizeof(duk_instr_t)))\n\n/*\n *  Validity assert\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hcompfunc_assert_valid(duk_hcompfunc *h);\n#define DUK_HCOMPFUNC_ASSERT_VALID(h)  do { duk_hcompfunc_assert_valid((h)); } while (0)\n#else\n#define DUK_HCOMPFUNC_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Main struct\n */\n\nstruct duk_hcompfunc {\n\t/* shared object part */\n\tduk_hobject obj;\n\n\t/*\n\t *  Pointers to function data area for faster access.  Function\n\t *  data is a buffer shared between all closures of the same\n\t *  \"template\" function.  The data buffer is always fixed (non-\n\t *  dynamic, hence stable), with a layout as follows:\n\t *\n\t *    constants (duk_tval)\n\t *    inner functions (duk_hobject *)\n\t *    bytecode (duk_instr_t)\n\t *\n\t *  Note: bytecode end address can be computed from 'data' buffer\n\t *  size.  It is not strictly necessary functionally, assuming\n\t *  bytecode never jumps outside its allocated area.  However,\n\t *  it's a safety/robustness feature for avoiding the chance of\n\t *  executing random data as bytecode due to a compiler error.\n\t *\n\t *  Note: values in the data buffer must be incref'd (they will\n\t *  be decref'd on release) for every compiledfunction referring\n\t *  to the 'data' element.\n\t */\n\n\t/* Data area, fixed allocation, stable data ptrs. */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t data16;\n#else\n\tduk_hbuffer *data;\n#endif\n\n\t/* No need for constants pointer (= same as data).\n\t *\n\t * When using 16-bit packing alignment to 4 is nice.  'funcs' will be\n\t * 4-byte aligned because 'constants' are duk_tvals.  For now the\n\t * inner function pointers are not compressed, so that 'bytecode' will\n\t * also be 4-byte aligned.\n\t */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t funcs16;\n\tduk_uint16_t bytecode16;\n#else\n\tduk_hobject **funcs;\n\tduk_instr_t *bytecode;\n#endif\n\n\t/* Lexenv: lexical environment of closure, NULL for templates.\n\t * Varenv: variable environment of closure, NULL for templates.\n\t */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t lex_env16;\n\tduk_uint16_t var_env16;\n#else\n\tduk_hobject *lex_env;\n\tduk_hobject *var_env;\n#endif\n\n\t/*\n\t *  'nregs' registers are allocated on function entry, at most 'nargs'\n\t *  are initialized to arguments, and the rest to undefined.  Arguments\n\t *  above 'nregs' are not mapped to registers.  All registers in the\n\t *  active stack range must be initialized because they are GC reachable.\n\t *  'nargs' is needed so that if the function is given more than 'nargs'\n\t *  arguments, the additional arguments do not 'clobber' registers\n\t *  beyond 'nregs' which must be consistently initialized to undefined.\n\t *\n\t *  Usually there is no need to know which registers are mapped to\n\t *  local variables.  Registers may be allocated to variable in any\n\t *  way (even including gaps).  However, a register-variable mapping\n\t *  must be the same for the duration of the function execution and\n\t *  the register cannot be used for anything else.\n\t *\n\t *  When looking up variables by name, the '_Varmap' map is used.\n\t *  When an activation closes, registers mapped to arguments are\n\t *  copied into the environment record based on the same map.  The\n\t *  reverse map (from register to variable) is not currently needed\n\t *  at run time, except for debugging, so it is not maintained.\n\t */\n\n\tduk_uint16_t nregs;                /* regs to allocate */\n\tduk_uint16_t nargs;                /* number of arguments allocated to regs */\n\n\t/*\n\t *  Additional control information is placed into the object itself\n\t *  as internal properties to avoid unnecessary fields for the\n\t *  majority of functions.  The compiler tries to omit internal\n\t *  control fields when possible.\n\t *\n\t *  Function templates:\n\t *\n\t *    {\n\t *      name: \"func\",    // declaration, named function expressions\n\t *      fileName: <debug info for creating nice errors>\n\t *      _Varmap: { \"arg1\": 0, \"arg2\": 1, \"varname\": 2 },\n\t *      _Formals: [ \"arg1\", \"arg2\" ],\n\t *      _Source: \"function func(arg1, arg2) { ... }\",\n\t *      _Pc2line: <debug info for pc-to-line mapping>,\n\t *    }\n\t *\n\t *  Function instances:\n\t *\n\t *    {\n\t *      length: 2,\n\t *      prototype: { constructor: <func> },\n\t *      caller: <thrower>,\n\t *      arguments: <thrower>,\n\t *      name: \"func\",    // declaration, named function expressions\n\t *      fileName: <debug info for creating nice errors>\n\t *      _Varmap: { \"arg1\": 0, \"arg2\": 1, \"varname\": 2 },\n\t *      _Formals: [ \"arg1\", \"arg2\" ],\n\t *      _Source: \"function func(arg1, arg2) { ... }\",\n\t *      _Pc2line: <debug info for pc-to-line mapping>,\n\t *    }\n\t *\n\t *  More detailed description of these properties can be found\n\t *  in the documentation.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* Line number range for function.  Needed during debugging to\n\t * determine active breakpoints.\n\t */\n\tduk_uint32_t start_line;\n\tduk_uint32_t end_line;\n#endif\n};\n\n#endif  /* DUK_HCOMPFUNC_H_INCLUDED */\n/* #include duk_hnatfunc.h */\n/*\n *  Heap native function representation.\n */\n\n#if !defined(DUK_HNATFUNC_H_INCLUDED)\n#define DUK_HNATFUNC_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hnatfunc_assert_valid(duk_hnatfunc *h);\n#define DUK_HNATFUNC_ASSERT_VALID(h)  do { duk_hnatfunc_assert_valid((h)); } while (0)\n#else\n#define DUK_HNATFUNC_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n#define DUK_HNATFUNC_NARGS_VARARGS  ((duk_int16_t) -1)\n#define DUK_HNATFUNC_NARGS_MAX      ((duk_int16_t) 0x7fff)\n\nstruct duk_hnatfunc {\n\t/* shared object part */\n\tduk_hobject obj;\n\n\tduk_c_function func;\n\tduk_int16_t nargs;\n\tduk_int16_t magic;\n\n\t/* The 'magic' field allows an opaque 16-bit field to be accessed by the\n\t * Duktape/C function.  This allows, for instance, the same native function\n\t * to be used for a set of very similar functions, with the 'magic' field\n\t * providing the necessary non-argument flags / values to guide the behavior\n\t * of the native function.  The value is signed on purpose: it is easier to\n\t * convert a signed value to unsigned (simply AND with 0xffff) than vice\n\t * versa.\n\t *\n\t * Note: cannot place nargs/magic into the heaphdr flags, because\n\t * duk_hobject takes almost all flags already.\n\t */\n};\n\n#endif  /* DUK_HNATFUNC_H_INCLUDED */\n/* #include duk_hboundfunc.h */\n/*\n *  Bound function representation.\n */\n\n#if !defined(DUK_HBOUNDFUNC_H_INCLUDED)\n#define DUK_HBOUNDFUNC_H_INCLUDED\n\n/* Artificial limit for args length.  Ensures arithmetic won't overflow\n * 32 bits when combining bound functions.\n */\n#define DUK_HBOUNDFUNC_MAX_ARGS 0x20000000UL\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hboundfunc_assert_valid(duk_hboundfunc *h);\n#define DUK_HBOUNDFUNC_ASSERT_VALID(h)  do { duk_hboundfunc_assert_valid((h)); } while (0)\n#else\n#define DUK_HBOUNDFUNC_ASSERT_VALID(h)  do {} while (0)\n#endif\n\nstruct duk_hboundfunc {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Final target function, stored as duk_tval so that lightfunc can be\n\t * represented too.\n\t */\n\tduk_tval target;\n\n\t/* This binding. */\n\tduk_tval this_binding;\n\n\t/* Arguments to prepend. */\n\tduk_tval *args;  /* Separate allocation. */\n\tduk_idx_t nargs;\n};\n\n#endif  /* DUK_HBOUNDFUNC_H_INCLUDED */\n/* #include duk_hbufobj.h */\n/*\n *  Heap Buffer object representation.  Used for all Buffer variants.\n */\n\n#if !defined(DUK_HBUFOBJ_H_INCLUDED)\n#define DUK_HBUFOBJ_H_INCLUDED\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\n/* All element accessors are host endian now (driven by TypedArray spec). */\n#define DUK_HBUFOBJ_ELEM_UINT8           0\n#define DUK_HBUFOBJ_ELEM_UINT8CLAMPED    1\n#define DUK_HBUFOBJ_ELEM_INT8            2\n#define DUK_HBUFOBJ_ELEM_UINT16          3\n#define DUK_HBUFOBJ_ELEM_INT16           4\n#define DUK_HBUFOBJ_ELEM_UINT32          5\n#define DUK_HBUFOBJ_ELEM_INT32           6\n#define DUK_HBUFOBJ_ELEM_FLOAT32         7\n#define DUK_HBUFOBJ_ELEM_FLOAT64         8\n#define DUK_HBUFOBJ_ELEM_MAX             8\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hbufobj_assert_valid(duk_hbufobj *h);\n#define DUK_HBUFOBJ_ASSERT_VALID(h)  do { duk_hbufobj_assert_valid((h)); } while (0)\n#else\n#define DUK_HBUFOBJ_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/* Get the current data pointer (caller must ensure buf != NULL) as a\n * duk_uint8_t ptr.  Note that the result may be NULL if the underlying\n * buffer has zero size and is not a fixed buffer.\n */\n#define DUK_HBUFOBJ_GET_SLICE_BASE(heap,h) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t(((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR((heap), (h)->buf)) + (h)->offset))\n\n/* True if slice is full, i.e. offset is zero and length covers the entire\n * buffer.  This status may change independently of the duk_hbufobj if\n * the underlying buffer is dynamic and changes without the hbufobj\n * being changed.\n */\n#define DUK_HBUFOBJ_FULL_SLICE(h) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset == 0 && (h)->length == DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n/* Validate that the whole slice [0,length[ is contained in the underlying\n * buffer.  Caller must ensure 'buf' != NULL.\n */\n#define DUK_HBUFOBJ_VALID_SLICE(h) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset + (h)->length <= DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n/* Validate byte read/write for virtual 'offset', i.e. check that the\n * offset, taking into account h->offset, is within the underlying\n * buffer size.  This is a safety check which is needed to ensure\n * that even a misconfigured duk_hbufobj never causes memory unsafe\n * behavior (e.g. if an underlying dynamic buffer changes after being\n * setup).  Caller must ensure 'buf' != NULL.\n */\n#define DUK_HBUFOBJ_VALID_BYTEOFFSET_INCL(h,off) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset + (off) < DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n#define DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h,off) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset + (off) <= DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n/* Clamp an input byte length (already assumed to be within the nominal\n * duk_hbufobj 'length') to the current dynamic buffer limits to yield\n * a byte length limit that's safe for memory accesses.  This value can\n * be invalidated by any side effect because it may trigger a user\n * callback that resizes the underlying buffer.\n */\n#define DUK_HBUFOBJ_CLAMP_BYTELENGTH(h,len) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), \\\n\tduk_hbufobj_clamp_bytelength((h), (len)))\n\n/* Typed arrays have virtual indices, ArrayBuffer and DataView do not. */\n#define DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h)  ((h)->is_typedarray)\n\nstruct duk_hbufobj {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Underlying buffer (refcounted), may be NULL. */\n\tduk_hbuffer *buf;\n\n\t/* .buffer reference to an ArrayBuffer, may be NULL. */\n\tduk_hobject *buf_prop;\n\n\t/* Slice and accessor information.\n\t *\n\t * Because the underlying buffer may be dynamic, these may be\n\t * invalidated by the buffer being modified so that both offset\n\t * and length should be validated before every access.  Behavior\n\t * when the underlying buffer has changed doesn't need to be clean:\n\t * virtual 'length' doesn't need to be affected, reads can return\n\t * zero/NaN, and writes can be ignored.\n\t *\n\t * Note that a data pointer cannot be precomputed because 'buf' may\n\t * be dynamic and its pointer unstable.\n\t */\n\n\tduk_uint_t offset;       /* byte offset to buf */\n\tduk_uint_t length;       /* byte index limit for element access, exclusive */\n\tduk_uint8_t shift;       /* element size shift:\n\t                          *   0 = u8/i8\n\t                          *   1 = u16/i16\n\t                          *   2 = u32/i32/float\n\t                          *   3 = double\n\t                          */\n\tduk_uint8_t elem_type;   /* element type */\n\tduk_uint8_t is_typedarray;\n};\n\nDUK_INTERNAL_DECL duk_uint_t duk_hbufobj_clamp_bytelength(duk_hbufobj *h_bufobj, duk_uint_t len);\nDUK_INTERNAL_DECL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_hbuffer *h_buf);\nDUK_INTERNAL_DECL void duk_hbufobj_push_validated_read(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);\nDUK_INTERNAL_DECL void duk_hbufobj_validated_write(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);\nDUK_INTERNAL_DECL void duk_hbufobj_promote_plain(duk_hthread *thr, duk_idx_t idx);\n\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* nothing */\n\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n#endif  /* DUK_HBUFOBJ_H_INCLUDED */\n/* #include duk_hthread.h */\n/*\n *  Heap thread object representation.\n *\n *  duk_hthread is also the 'context' for public API functions via a\n *  different typedef.  Most API calls operate on the topmost frame\n *  of the value stack only.\n */\n\n#if !defined(DUK_HTHREAD_H_INCLUDED)\n#define DUK_HTHREAD_H_INCLUDED\n\n/*\n *  Stack constants\n */\n\n/* Initial valstack size, roughly 0.7kiB. */\n#define DUK_VALSTACK_INITIAL_SIZE       96U\n\n/* Internal extra elements assumed on function entry, always added to\n * user-defined 'extra' for e.g. the duk_check_stack() call.\n */\n#define DUK_VALSTACK_INTERNAL_EXTRA     32U\n\n/* Number of elements guaranteed to be user accessible (in addition to call\n * arguments) on Duktape/C function entry.  This is the major public API\n * commitment.\n */\n#define DUK_VALSTACK_API_ENTRY_MINIMUM  DUK_API_ENTRY_STACK\n\n/*\n *  Activation defines\n */\n\n#define DUK_ACT_FLAG_STRICT             (1U << 0)  /* function executes in strict mode */\n#define DUK_ACT_FLAG_TAILCALLED         (1U << 1)  /* activation has tail called one or more times */\n#define DUK_ACT_FLAG_CONSTRUCT          (1U << 2)  /* function executes as a constructor (called via \"new\") */\n#define DUK_ACT_FLAG_PREVENT_YIELD      (1U << 3)  /* activation prevents yield (native call or \"new\") */\n#define DUK_ACT_FLAG_DIRECT_EVAL        (1U << 4)  /* activation is a direct eval call */\n#define DUK_ACT_FLAG_CONSTRUCT_PROXY    (1U << 5)  /* activation is for Proxy 'construct' call, special return value handling */\n#define DUK_ACT_FLAG_BREAKPOINT_ACTIVE  (1U << 6)  /* activation has active breakpoint(s) */\n\n#define DUK_ACT_GET_FUNC(act)           ((act)->func)\n\n/*\n *  Flags for __FILE__ / __LINE__ registered into tracedata\n */\n\n#define DUK_TB_FLAG_NOBLAME_FILELINE    (1U << 0)  /* don't report __FILE__ / __LINE__ as fileName/lineNumber */\n\n/*\n *  Catcher defines\n */\n\n/* XXX: remove catcher type entirely */\n\n/* flags field: LLLLLLFT, L = label (24 bits), F = flags (4 bits), T = type (4 bits) */\n#define DUK_CAT_TYPE_MASK            0x0000000fUL\n#define DUK_CAT_TYPE_BITS            4\n#define DUK_CAT_LABEL_MASK           0xffffff00UL\n#define DUK_CAT_LABEL_BITS           24\n#define DUK_CAT_LABEL_SHIFT          8\n\n#define DUK_CAT_FLAG_CATCH_ENABLED          (1U << 4)   /* catch part will catch */\n#define DUK_CAT_FLAG_FINALLY_ENABLED        (1U << 5)   /* finally part will catch */\n#define DUK_CAT_FLAG_CATCH_BINDING_ENABLED  (1U << 6)   /* request to create catch binding */\n#define DUK_CAT_FLAG_LEXENV_ACTIVE          (1U << 7)   /* catch or with binding is currently active */\n\n#define DUK_CAT_TYPE_UNKNOWN         0\n#define DUK_CAT_TYPE_TCF             1\n#define DUK_CAT_TYPE_LABEL           2\n\n#define DUK_CAT_GET_TYPE(c)          ((c)->flags & DUK_CAT_TYPE_MASK)\n#define DUK_CAT_GET_LABEL(c)         (((c)->flags & DUK_CAT_LABEL_MASK) >> DUK_CAT_LABEL_SHIFT)\n\n#define DUK_CAT_HAS_CATCH_ENABLED(c)           ((c)->flags & DUK_CAT_FLAG_CATCH_ENABLED)\n#define DUK_CAT_HAS_FINALLY_ENABLED(c)         ((c)->flags & DUK_CAT_FLAG_FINALLY_ENABLED)\n#define DUK_CAT_HAS_CATCH_BINDING_ENABLED(c)   ((c)->flags & DUK_CAT_FLAG_CATCH_BINDING_ENABLED)\n#define DUK_CAT_HAS_LEXENV_ACTIVE(c)           ((c)->flags & DUK_CAT_FLAG_LEXENV_ACTIVE)\n\n#define DUK_CAT_SET_CATCH_ENABLED(c)    do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_CATCH_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_SET_FINALLY_ENABLED(c)  do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_FINALLY_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_SET_CATCH_BINDING_ENABLED(c)    do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_CATCH_BINDING_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_SET_LEXENV_ACTIVE(c)    do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_LEXENV_ACTIVE; \\\n\t} while (0)\n\n#define DUK_CAT_CLEAR_CATCH_ENABLED(c)    do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_CATCH_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_CLEAR_FINALLY_ENABLED(c)  do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_FINALLY_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_CLEAR_CATCH_BINDING_ENABLED(c)    do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_CATCH_BINDING_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_CLEAR_LEXENV_ACTIVE(c)    do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_LEXENV_ACTIVE; \\\n\t} while (0)\n\n/*\n *  Thread defines\n */\n\n#if defined(DUK_USE_ROM_STRINGS)\n#define DUK_HTHREAD_GET_STRING(thr,idx) \\\n\t((duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_stridx[(idx)]))\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HTHREAD_GET_STRING(thr,idx) \\\n\t((duk_hstring *) DUK_USE_HEAPPTR_DEC16((thr)->heap->heap_udata, (thr)->strs16[(idx)]))\n#else\n#define DUK_HTHREAD_GET_STRING(thr,idx) \\\n\t((thr)->strs[(idx)])\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n/* values for the state field */\n#define DUK_HTHREAD_STATE_INACTIVE     1   /* thread not currently running */\n#define DUK_HTHREAD_STATE_RUNNING      2   /* thread currently running (only one at a time) */\n#define DUK_HTHREAD_STATE_RESUMED      3   /* thread resumed another thread (active but not running) */\n#define DUK_HTHREAD_STATE_YIELDED      4   /* thread has yielded */\n#define DUK_HTHREAD_STATE_TERMINATED   5   /* thread has terminated */\n\n/* Executor interrupt default interval when nothing else requires a\n * smaller value.  The default interval must be small enough to allow\n * for reasonable execution timeout checking but large enough to keep\n * impact on execution performance low.\n */\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n#define DUK_HTHREAD_INTCTR_DEFAULT     (256L * 1024L)\n#endif\n\n/*\n *  Assert context is valid: non-NULL pointer, fields look sane.\n *\n *  This is used by public API call entrypoints to catch invalid 'ctx' pointers\n *  as early as possible; invalid 'ctx' pointers cause very odd and difficult to\n *  diagnose behavior so it's worth checking even when the check is not 100%.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n/* Assertions for internals. */\nDUK_INTERNAL_DECL void duk_hthread_assert_valid(duk_hthread *thr);\n#define DUK_HTHREAD_ASSERT_VALID(thr)  do { duk_hthread_assert_valid((thr)); } while (0)\n\n/* Assertions for public API calls; a bit stronger. */\nDUK_INTERNAL_DECL void duk_ctx_assert_valid(duk_hthread *thr);\n#define DUK_CTX_ASSERT_VALID(thr)  do { duk_ctx_assert_valid((thr)); } while (0)\n#else\n#define DUK_HTHREAD_ASSERT_VALID(thr)  do {} while (0)\n#define DUK_CTX_ASSERT_VALID(thr)  do {} while (0)\n#endif\n\n/* Assertions for API call entry specifically.  Checks 'ctx' but also may\n * check internal state (e.g. not in a debugger transport callback).\n */\n#define DUK_ASSERT_API_ENTRY(thr) do { \\\n\t\tDUK_CTX_ASSERT_VALID((thr)); \\\n\t\tDUK_ASSERT((thr)->heap != NULL); \\\n\t\tDUK_ASSERT((thr)->heap->dbg_calling_transport == 0); \\\n\t} while (0)\n\n/*\n *  Assertion helpers.\n */\n\n#define DUK_ASSERT_STRIDX_VALID(val) \\\n\tDUK_ASSERT((duk_uint_t) (val) < DUK_HEAP_NUM_STRINGS)\n\n#define DUK_ASSERT_BIDX_VALID(val) \\\n\tDUK_ASSERT((duk_uint_t) (val) < DUK_NUM_BUILTINS)\n\n/*\n *  Misc\n */\n\n/* Fast access to 'this' binding.  Assumes there's a call in progress. */\n#define DUK_HTHREAD_THIS_PTR(thr) \\\n\t(DUK_ASSERT_EXPR((thr) != NULL), \\\n\t DUK_ASSERT_EXPR((thr)->valstack_bottom > (thr)->valstack), \\\n\t (thr)->valstack_bottom - 1)\n\n/*\n *  Struct defines\n */\n\n/* Fields are ordered for alignment/packing. */\nstruct duk_activation {\n\tduk_tval tv_func;       /* borrowed: full duk_tval for function being executed; for lightfuncs */\n\tduk_hobject *func;      /* borrowed: function being executed; for bound function calls, this is the final, real function, NULL for lightfuncs */\n\tduk_activation *parent; /* previous (parent) activation (or NULL if none) */\n\tduk_hobject *var_env;   /* current variable environment (may be NULL if delayed) */\n\tduk_hobject *lex_env;   /* current lexical environment (may be NULL if delayed) */\n\tduk_catcher *cat;       /* current catcher (or NULL) */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t/* Previous value of 'func' caller, restored when unwound.  Only in use\n\t * when 'func' is non-strict.\n\t */\n\tduk_hobject *prev_caller;\n#endif\n\n\tduk_instr_t *curr_pc;   /* next instruction to execute (points to 'func' bytecode, stable pointer), NULL for native calls */\n\n\t/* bottom_byteoff and retval_byteoff are only used for book-keeping\n\t * of ECMAScript-initiated calls, to allow returning to an ECMAScript\n\t * function properly.\n\t */\n\n\t/* Bottom of valstack for this activation, used to reset\n\t * valstack_bottom on return; offset is absolute.  There's\n\t * no need to track 'top' because native call handling deals\n\t * with that using locals, and for ECMAScript returns 'nregs'\n\t * indicates the necessary top.\n\t */\n\tduk_size_t bottom_byteoff;\n\n\t/* Return value when returning to this activation (points to caller\n\t * reg, not callee reg); offset is absolute (only set if activation is\n\t * not topmost).\n\t *\n\t * Note: bottom_byteoff is always set, while retval_byteoff is only\n\t * applicable for activations below the topmost one.  Currently\n\t * retval_byteoff for the topmost activation is considered garbage\n\t * (and it not initialized on entry or cleared on return; may contain\n\t * previous or garbage values).\n\t */\n\tduk_size_t retval_byteoff;\n\n\t/* Current 'this' binding is the value just below bottom.\n\t * Previously, 'this' binding was handled with an index to the\n\t * (calling) valstack.  This works for everything except tail\n\t * calls, which must not \"accumulate\" valstack temps.\n\t */\n\n\t/* Value stack reserve (valstack_end) byte offset to be restored\n\t * when returning to this activation.  Only used by the bytecode\n\t * executor.\n\t */\n\tduk_size_t reserve_byteoff;\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_uint32_t prev_line; /* needed for stepping */\n#endif\n\n\tduk_small_uint_t flags;\n};\n\nstruct duk_catcher {\n\tduk_catcher *parent;            /* previous (parent) catcher (or NULL if none) */\n\tduk_hstring *h_varname;         /* borrowed reference to catch variable name (or NULL if none) */\n\t                                /* (reference is valid as long activation exists) */\n\tduk_instr_t *pc_base;           /* resume execution from pc_base or pc_base+1 (points to 'func' bytecode, stable pointer) */\n\tduk_size_t idx_base;            /* idx_base and idx_base+1 get completion value and type */\n\tduk_uint32_t flags;             /* type and control flags, label number */\n\t/* XXX: could pack 'flags' and 'idx_base' to same value in practice,\n\t * on 32-bit targets this would make duk_catcher 16 bytes.\n\t */\n};\n\nstruct duk_hthread {\n\t/* Shared object part */\n\tduk_hobject obj;\n\n\t/* Pointer to bytecode executor's 'curr_pc' variable.  Used to copy\n\t * the current PC back into the topmost activation when activation\n\t * state is about to change (or \"syncing\" is otherwise needed).  This\n\t * is rather awkward but important for performance, see execution.rst.\n\t */\n\tduk_instr_t **ptr_curr_pc;\n\n\t/* Backpointers. */\n\tduk_heap *heap;\n\n\t/* Current strictness flag: affects API calls. */\n\tduk_uint8_t strict;\n\n\t/* Thread state. */\n\tduk_uint8_t state;\n\tduk_uint8_t unused1;\n\tduk_uint8_t unused2;\n\n\t/* XXX: Valstack and callstack are currently assumed to have non-NULL\n\t * pointers.  Relaxing this would not lead to big benefits (except\n\t * perhaps for terminated threads).\n\t */\n\n\t/* Value stack: these are expressed as pointers for faster stack\n\t * manipulation.  [valstack,valstack_top[ is GC-reachable,\n\t * [valstack_top,valstack_alloc_end[ is not GC-reachable but kept\n\t * initialized as 'undefined'.  [valstack,valstack_end[ is the\n\t * guaranteed/reserved space and the valstack cannot be resized to\n\t * a smaller size.  [valstack_end,valstack_alloc_end[ is currently\n\t * allocated slack that can be used to grow the current guaranteed\n\t * space but may be shrunk away without notice.\n\t *\n\t *\n\t * <----------------------- guaranteed --->\n\t *                                        <---- slack --->\n\t *               <--- frame --->\n\t * .-------------+=============+----------+--------------.\n\t * |xxxxxxxxxxxxx|yyyyyyyyyyyyy|uuuuuuuuuu|uuuuuuuuuuuuuu|\n\t * `-------------+=============+----------+--------------'\n\t *\n\t * ^             ^             ^          ^              ^\n\t * |             |             |          |              |\n\t * valstack      bottom        top        end            alloc_end\n\t *\n\t *     xxx = arbitrary values, below current frame\n\t *     yyy = arbitrary values, inside current frame\n\t *     uuu = outside active value stack, initialized to 'undefined'\n\t */\n\tduk_tval *valstack;                     /* start of valstack allocation */\n\tduk_tval *valstack_end;                 /* end of valstack reservation/guarantee (exclusive) */\n\tduk_tval *valstack_alloc_end;           /* end of valstack allocation */\n\tduk_tval *valstack_bottom;              /* bottom of current frame */\n\tduk_tval *valstack_top;                 /* top of current frame (exclusive) */\n\n\t/* Call stack, represented as a linked list starting from the current\n\t * activation (or NULL if nothing is active).\n\t */\n\tduk_activation *callstack_curr;         /* current activation (or NULL if none) */\n\tduk_size_t callstack_top;               /* number of activation records in callstack (0 if none) */\n\tduk_size_t callstack_preventcount;      /* number of activation records in callstack preventing a yield */\n\n\t/* Yield/resume book-keeping. */\n\tduk_hthread *resumer;                   /* who resumed us (if any) */\n\n\t/* Current compiler state (if any), used for augmenting SyntaxErrors. */\n\tduk_compiler_ctx *compile_ctx;\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\t/* Interrupt counter for triggering a slow path check for execution\n\t * timeout, debugger interaction such as breakpoints, etc.  The value\n\t * is valid for the current running thread, and both the init and\n\t * counter values are copied whenever a thread switch occurs.  It's\n\t * important for the counter to be conveniently accessible for the\n\t * bytecode executor inner loop for performance reasons.\n\t */\n\tduk_int_t interrupt_counter;    /* countdown state */\n\tduk_int_t interrupt_init;       /* start value for current countdown */\n#endif\n\n\t/* Builtin-objects; may or may not be shared with other threads,\n\t * threads existing in different \"compartments\" will have different\n\t * built-ins.  Must be stored on a per-thread basis because there\n\t * is no intermediate structure for a thread group / compartment.\n\t * This takes quite a lot of space, currently 43x4 = 172 bytes on\n\t * 32-bit platforms.\n\t *\n\t * In some cases the builtins array could be ROM based, but it's\n\t * sometimes edited (e.g. for sandboxing) so it's better to keep\n\t * this array in RAM.\n\t */\n\tduk_hobject *builtins[DUK_NUM_BUILTINS];\n\n\t/* Convenience copies from heap/vm for faster access. */\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* No field needed when strings are in ROM. */\n#else\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t *strs16;\n#else\n\tduk_hstring **strs;\n#endif\n#endif\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_hthread_copy_builtin_objects(duk_hthread *thr_from, duk_hthread *thr_to);\nDUK_INTERNAL_DECL void duk_hthread_create_builtin_objects(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_terminate(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_activation *duk_hthread_activation_alloc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_activation_free(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_hthread_activation_unwind_norz(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_activation_unwind_reuse_norz(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_activation *duk_hthread_get_activation_for_level(duk_hthread *thr, duk_int_t level);\n\nDUK_INTERNAL_DECL duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_catcher_free(duk_hthread *thr, duk_catcher *cat);\nDUK_INTERNAL_DECL void duk_hthread_catcher_unwind_norz(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_hthread_catcher_unwind_nolexenv_norz(duk_hthread *thr, duk_activation *act);\n\n#if defined(DUK_USE_FINALIZER_TORTURE)\nDUK_INTERNAL_DECL void duk_hthread_valstack_torture_realloc(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud);  /* indirect allocs */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_hthread_get_act_curr_pc(duk_hthread *thr, duk_activation *act);\n#endif\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_hthread_get_act_prev_pc(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_hthread_sync_currpc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_sync_and_null_currpc(duk_hthread *thr);\n\n#endif  /* DUK_HTHREAD_H_INCLUDED */\n/* #include duk_harray.h */\n/*\n *  Array object representation, used for actual Array instances.\n *\n *  All objects with the exotic array behavior (which must coincide with having\n *  internal class array) MUST be duk_harrays.  No other object can be a\n *  duk_harray.  However, duk_harrays may not always have an array part.\n */\n\n#if !defined(DUK_HARRAY_H_INCLUDED)\n#define DUK_HARRAY_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_harray_assert_valid(duk_harray *h);\n#define DUK_HARRAY_ASSERT_VALID(h)  do { duk_harray_assert_valid((h)); } while (0)\n#else\n#define DUK_HARRAY_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n#define DUK_HARRAY_LENGTH_WRITABLE(h)         (!(h)->length_nonwritable)\n#define DUK_HARRAY_LENGTH_NONWRITABLE(h)      ((h)->length_nonwritable)\n#define DUK_HARRAY_SET_LENGTH_WRITABLE(h)     do { (h)->length_nonwritable = 0; } while (0)\n#define DUK_HARRAY_SET_LENGTH_NONWRITABLE(h)  do { (h)->length_nonwritable = 1; } while (0)\n\nstruct duk_harray {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Array .length.\n\t *\n\t * At present Array .length may be smaller, equal, or even larger\n\t * than the allocated underlying array part.  Fast path code must\n\t * always take this into account carefully.\n\t */\n\tduk_uint32_t length;\n\n\t/* Array .length property attributes.  The property is always\n\t * non-enumerable and non-configurable.  It's initially writable\n\t * but per Object.defineProperty() rules it can be made non-writable\n\t * even if it is non-configurable.  Thus we need to track the\n\t * writability explicitly.\n\t *\n\t * XXX: this field to be eliminated and moved into duk_hobject\n\t * flags field to save space.\n\t */\n\tduk_bool_t length_nonwritable;\n};\n\n#endif  /* DUK_HARRAY_H_INCLUDED */\n/* #include duk_henv.h */\n/*\n *  Environment object representation.\n */\n\n#if !defined(DUK_HENV_H_INCLUDED)\n#define DUK_HENV_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hdecenv_assert_valid(duk_hdecenv *h);\nDUK_INTERNAL_DECL void duk_hobjenv_assert_valid(duk_hobjenv *h);\n#define DUK_HDECENV_ASSERT_VALID(h)  do { duk_hdecenv_assert_valid((h)); } while (0)\n#define DUK_HOBJENV_ASSERT_VALID(h)  do { duk_hobjenv_assert_valid((h)); } while (0)\n#else\n#define DUK_HDECENV_ASSERT_VALID(h)  do {} while (0)\n#define DUK_HOBJENV_ASSERT_VALID(h)  do {} while (0)\n#endif\n\nstruct duk_hdecenv {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* These control variables provide enough information to access live\n\t * variables for a closure that is still open.  If thread == NULL,\n\t * the record is closed and the identifiers are in the property table.\n\t */\n\tduk_hthread *thread;\n\tduk_hobject *varmap;\n\tduk_size_t regbase_byteoff;\n};\n\nstruct duk_hobjenv {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Target object and 'this' binding for object binding. */\n\tduk_hobject *target;\n\n\t/* The 'target' object is used as a this binding in only some object\n\t * environments.  For example, the global environment does not provide\n\t * a this binding, but a with statement does.\n\t */\n\tduk_bool_t has_this;\n};\n\n#endif  /* DUK_HENV_H_INCLUDED */\n/* #include duk_hbuffer.h */\n/*\n *  Heap buffer representation.\n *\n *  Heap allocated user data buffer which is either:\n *\n *    1. A fixed size buffer (data follows header statically)\n *    2. A dynamic size buffer (data pointer follows header)\n *\n *  The data pointer for a variable size buffer of zero size may be NULL.\n */\n\n#if !defined(DUK_HBUFFER_H_INCLUDED)\n#define DUK_HBUFFER_H_INCLUDED\n\n/*\n *  Flags\n *\n *  Fixed buffer:     0\n *  Dynamic buffer:   DUK_HBUFFER_FLAG_DYNAMIC\n *  External buffer:  DUK_HBUFFER_FLAG_DYNAMIC | DUK_HBUFFER_FLAG_EXTERNAL\n */\n\n#define DUK_HBUFFER_FLAG_DYNAMIC                  DUK_HEAPHDR_USER_FLAG(0)    /* buffer is behind a pointer, dynamic or external */\n#define DUK_HBUFFER_FLAG_EXTERNAL                 DUK_HEAPHDR_USER_FLAG(1)    /* buffer pointer is to an externally allocated buffer */\n\n#define DUK_HBUFFER_HAS_DYNAMIC(x)                DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)\n#define DUK_HBUFFER_HAS_EXTERNAL(x)               DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL)\n\n#define DUK_HBUFFER_SET_DYNAMIC(x)                DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)\n#define DUK_HBUFFER_SET_EXTERNAL(x)               DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL)\n\n#define DUK_HBUFFER_CLEAR_DYNAMIC(x)              DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)\n#define DUK_HBUFFER_CLEAR_EXTERNAL(x)             DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL)\n\n/*\n *  Misc defines\n */\n\n/* Impose a maximum buffer length for now.  Restricted artificially to\n * ensure resize computations or adding a heap header length won't\n * overflow size_t and that a signed duk_int_t can hold a buffer\n * length.  The limit should be synchronized with DUK_HSTRING_MAX_BYTELEN.\n */\n\n#if defined(DUK_USE_BUFLEN16)\n#define DUK_HBUFFER_MAX_BYTELEN                   (0x0000ffffUL)\n#else\n/* Intentionally not 0x7fffffffUL; at least JSON code expects that\n * 2*len + 2 fits in 32 bits.\n */\n#define DUK_HBUFFER_MAX_BYTELEN                   (0x7ffffffeUL)\n#endif\n\n/*\n *  Field access\n */\n\n#if defined(DUK_USE_BUFLEN16)\n/* size stored in duk_heaphdr unused flag bits */\n#define DUK_HBUFFER_GET_SIZE(x)     ((x)->hdr.h_flags >> 16)\n#define DUK_HBUFFER_SET_SIZE(x,v)   do { \\\n\t\tduk_size_t duk__v; \\\n\t\tduk__v = (v); \\\n\t\tDUK_ASSERT(duk__v <= 0xffffUL); \\\n\t\t(x)->hdr.h_flags = ((x)->hdr.h_flags & 0x0000ffffUL) | (((duk_uint32_t) duk__v) << 16); \\\n\t} while (0)\n#define DUK_HBUFFER_ADD_SIZE(x,dv)  do { \\\n\t\t(x)->hdr.h_flags += ((dv) << 16); \\\n\t} while (0)\n#define DUK_HBUFFER_SUB_SIZE(x,dv)  do { \\\n\t\t(x)->hdr.h_flags -= ((dv) << 16); \\\n\t} while (0)\n#else\n#define DUK_HBUFFER_GET_SIZE(x)     (((duk_hbuffer *) (x))->size)\n#define DUK_HBUFFER_SET_SIZE(x,v)   do { \\\n\t\t((duk_hbuffer *) (x))->size = (v); \\\n\t} while (0)\n#define DUK_HBUFFER_ADD_SIZE(x,dv)  do { \\\n\t\t(x)->size += (dv); \\\n\t} while (0)\n#define DUK_HBUFFER_SUB_SIZE(x,dv)  do { \\\n\t\t(x)->size -= (dv); \\\n\t} while (0)\n#endif\n\n#define DUK_HBUFFER_FIXED_GET_SIZE(x)       DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x))\n#define DUK_HBUFFER_FIXED_SET_SIZE(x,v)     DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x))\n\n#define DUK_HBUFFER_DYNAMIC_GET_SIZE(x)     DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x))\n#define DUK_HBUFFER_DYNAMIC_SET_SIZE(x,v)   DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x), (v))\n#define DUK_HBUFFER_DYNAMIC_ADD_SIZE(x,dv)  DUK_HBUFFER_ADD_SIZE((duk_hbuffer *) (x), (dv))\n#define DUK_HBUFFER_DYNAMIC_SUB_SIZE(x,dv)  DUK_HBUFFER_SUB_SIZE((duk_hbuffer *) (x), (dv))\n\n#define DUK_HBUFFER_EXTERNAL_GET_SIZE(x)    DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x))\n#define DUK_HBUFFER_EXTERNAL_SET_SIZE(x,v)  DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x), (v))\n\n#define DUK_HBUFFER_FIXED_GET_DATA_PTR(heap,x)    ((duk_uint8_t *) (((duk_hbuffer_fixed *) (void *) (x)) + 1))\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap,x) \\\n\t((void *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, ((duk_heaphdr *) (x))->h_extra16))\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t((duk_heaphdr *) (x))->h_extra16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t((duk_heaphdr *) (x))->h_extra16 = 0;  /* assume 0 <=> NULL */ \\\n\t} while (0)\n#else\n#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap,x)       ((x)->curr_alloc)\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t(x)->curr_alloc = (void *) (v); \\\n\t} while (0)\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t(x)->curr_alloc = (void *) NULL; \\\n\t} while (0)\n#endif\n\n/* No pointer compression because pointer is potentially outside of\n * Duktape heap.\n */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap,x) \\\n\t((void *) (x)->curr_alloc)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t(x)->curr_alloc = (void *) (v); \\\n\t} while (0)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t(x)->curr_alloc = (void *) NULL; \\\n\t} while (0)\n#else\n#define DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap,x) \\\n\t((void *) (x)->curr_alloc)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t(x)->curr_alloc = (void *) (v); \\\n\t} while (0)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t(x)->curr_alloc = (void *) NULL; \\\n\t} while (0)\n#endif\n\n/* Get a pointer to the current buffer contents (matching current allocation\n * size).  May be NULL for zero size dynamic/external buffer.\n */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HBUFFER_GET_DATA_PTR(heap,x)  ( \\\n\tDUK_HBUFFER_HAS_DYNAMIC((x)) ? \\\n\t\t( \\\n\t\t\tDUK_HBUFFER_HAS_EXTERNAL((x)) ? \\\n\t\t\t\tDUK_HBUFFER_EXTERNAL_GET_DATA_PTR((heap), (duk_hbuffer_external *) (x)) : \\\n\t\t\t\tDUK_HBUFFER_DYNAMIC_GET_DATA_PTR((heap), (duk_hbuffer_dynamic *) (x)) \\\n\t\t) : \\\n\t\tDUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (void *) (x)) \\\n\t)\n#else\n/* Without heap pointer compression duk_hbuffer_dynamic and duk_hbuffer_external\n * have the same layout so checking for fixed vs. dynamic (or external) is enough.\n */\n#define DUK_HBUFFER_GET_DATA_PTR(heap,x)  ( \\\n\tDUK_HBUFFER_HAS_DYNAMIC((x)) ? \\\n\t\tDUK_HBUFFER_DYNAMIC_GET_DATA_PTR((heap), (duk_hbuffer_dynamic *) (x)) : \\\n\t\tDUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (void *) (x)) \\\n\t)\n#endif\n\n/* Validity assert. */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hbuffer_assert_valid(duk_hbuffer *h);\n#define DUK_HBUFFER_ASSERT_VALID(h)  do { duk_hbuffer_assert_valid((h)); } while (0)\n#else\n#define DUK_HBUFFER_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Structs\n */\n\n/* Shared prefix for all buffer types. */\nstruct duk_hbuffer {\n\tduk_heaphdr hdr;\n\n\t/* It's not strictly necessary to track the current size, but\n\t * it is useful for writing robust native code.\n\t */\n\n\t/* Current size. */\n#if defined(DUK_USE_BUFLEN16)\n\t/* Stored in duk_heaphdr unused flags. */\n#else\n\tduk_size_t size;\n#endif\n\n\t/*\n\t *  Data following the header depends on the DUK_HBUFFER_FLAG_DYNAMIC\n\t *  flag.\n\t *\n\t *  If the flag is clear (the buffer is a fixed size one), the buffer\n\t *  data follows the header directly, consisting of 'size' bytes.\n\t *\n\t *  If the flag is set, the actual buffer is allocated separately, and\n\t *  a few control fields follow the header.  Specifically:\n\t *\n\t *    - a \"void *\" pointing to the current allocation\n\t *    - a duk_size_t indicating the full allocated size (always >= 'size')\n\t *\n\t *  If DUK_HBUFFER_FLAG_EXTERNAL is set, the buffer has been allocated\n\t *  by user code, so that Duktape won't be able to resize it and won't\n\t *  free it.  This allows buffers to point to e.g. an externally\n\t *  allocated structure such as a frame buffer.\n\t *\n\t *  Unlike strings, no terminator byte (NUL) is guaranteed after the\n\t *  data.  This would be convenient, but would pad aligned user buffers\n\t *  unnecessarily upwards in size.  For instance, if user code requested\n\t *  a 64-byte dynamic buffer, 65 bytes would actually be allocated which\n\t *  would then potentially round upwards to perhaps 68 or 72 bytes.\n\t */\n};\n\n/* Fixed buffer; data follows struct, with proper alignment guaranteed by\n * struct size.\n */\n#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)\n#pragma pack(push, 8)\n#endif\nstruct duk_hbuffer_fixed {\n\t/* A union is used here as a portable struct size / alignment trick:\n\t * by adding a 32-bit or a 64-bit (unused) union member, the size of\n\t * the struct is effectively forced to be a multiple of 4 or 8 bytes\n\t * (respectively) without increasing the size of the struct unless\n\t * necessary.\n\t */\n\tunion {\n\t\tstruct {\n\t\t\tduk_heaphdr hdr;\n#if defined(DUK_USE_BUFLEN16)\n\t\t\t/* Stored in duk_heaphdr unused flags. */\n#else\n\t\t\tduk_size_t size;\n#endif\n\t\t} s;\n#if (DUK_USE_ALIGN_BY == 4)\n\t\tduk_uint32_t dummy_for_align4;\n#elif (DUK_USE_ALIGN_BY == 8)\n\t\tduk_double_t dummy_for_align8_1;\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_uint64_t dummy_for_align8_2;\n#endif\n#elif (DUK_USE_ALIGN_BY == 1)\n\t\t/* no extra padding */\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\t} u;\n\n\t/*\n\t *  Data follows the struct header.  The struct size is padded by the\n\t *  compiler based on the struct members.  This guarantees that the\n\t *  buffer data will be aligned-by-4 but not necessarily aligned-by-8.\n\t *\n\t *  On platforms where alignment does not matter, the struct padding\n\t *  could be removed (if there is any).  On platforms where alignment\n\t *  by 8 is required, the struct size must be forced to be a multiple\n\t *  of 8 by some means.  Without it, some user code may break, and also\n\t *  Duktape itself breaks (e.g. the compiler stores duk_tvals in a\n\t *  dynamic buffer).\n\t */\n}\n#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_GCC_ATTR)\n__attribute__ ((aligned (8)))\n#elif (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_CLANG_ATTR)\n__attribute__ ((aligned (8)))\n#endif\n;\n#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)\n#pragma pack(pop)\n#endif\n\n/* Dynamic buffer with 'curr_alloc' pointing to a dynamic area allocated using\n * heap allocation primitives.  Also used for external buffers when low memory\n * options are not used.\n */\nstruct duk_hbuffer_dynamic {\n\tduk_heaphdr hdr;\n\n#if defined(DUK_USE_BUFLEN16)\n\t/* Stored in duk_heaphdr unused flags. */\n#else\n\tduk_size_t size;\n#endif\n\n#if defined(DUK_USE_HEAPPTR16)\n\t/* Stored in duk_heaphdr h_extra16. */\n#else\n\tvoid *curr_alloc;  /* may be NULL if alloc_size == 0 */\n#endif\n\n\t/*\n\t *  Allocation size for 'curr_alloc' is alloc_size.  There is no\n\t *  automatic NUL terminator for buffers (see above for rationale).\n\t *\n\t *  'curr_alloc' is explicitly allocated with heap allocation\n\t *  primitives and will thus always have alignment suitable for\n\t *  e.g. duk_tval and an IEEE double.\n\t */\n};\n\n/* External buffer with 'curr_alloc' managed by user code and pointing to an\n * arbitrary address.  When heap pointer compression is not used, this struct\n * has the same layout as duk_hbuffer_dynamic.\n */\nstruct duk_hbuffer_external {\n\tduk_heaphdr hdr;\n\n#if defined(DUK_USE_BUFLEN16)\n\t/* Stored in duk_heaphdr unused flags. */\n#else\n\tduk_size_t size;\n#endif\n\n\t/* Cannot be compressed as a heap pointer because may point to\n\t * an arbitrary address.\n\t */\n\tvoid *curr_alloc;  /* may be NULL if alloc_size == 0 */\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk_small_uint_t flags, void **out_bufdata);\nDUK_INTERNAL_DECL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud);  /* indirect allocs */\n\n/* dynamic buffer ops */\nDUK_INTERNAL_DECL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf, duk_size_t new_size);\nDUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *buf);\n\n#endif  /* DUK_HBUFFER_H_INCLUDED */\n/* #include duk_hproxy.h */\n/*\n *  Proxy object representation.\n */\n\n#if !defined(DUK_HPROXY_H_INCLUDED)\n#define DUK_HPROXY_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hproxy_assert_valid(duk_hproxy *h);\n#define DUK_HPROXY_ASSERT_VALID(h)  do { duk_hproxy_assert_valid((h)); } while (0)\n#else\n#define DUK_HPROXY_ASSERT_VALID(h)  do {} while (0)\n#endif\n\nstruct duk_hproxy {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Proxy target object. */\n\tduk_hobject *target;\n\n\t/* Proxy handlers (traps). */\n\tduk_hobject *handler;\n};\n\n#endif  /* DUK_HPROXY_H_INCLUDED */\n/* #include duk_heap.h */\n/*\n *  Heap structure.\n *\n *  Heap contains allocated heap objects, interned strings, and built-in\n *  strings for one or more threads.\n */\n\n#if !defined(DUK_HEAP_H_INCLUDED)\n#define DUK_HEAP_H_INCLUDED\n\n/* alloc function typedefs in duktape.h */\n\n/*\n *  Heap flags\n */\n\n#define DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED            (1U << 0)  /* mark-and-sweep marking reached a recursion limit and must use multi-pass marking */\n#define DUK_HEAP_FLAG_INTERRUPT_RUNNING                        (1U << 1)  /* executor interrupt running (used to avoid nested interrupts) */\n#define DUK_HEAP_FLAG_FINALIZER_NORESCUE                       (1U << 2)  /* heap destruction ongoing, finalizer rescue no longer possible */\n#define DUK_HEAP_FLAG_DEBUGGER_PAUSED                          (1U << 3)  /* debugger is paused: talk with debug client until step/resume */\n\n#define DUK__HEAP_HAS_FLAGS(heap,bits)               ((heap)->flags & (bits))\n#define DUK__HEAP_SET_FLAGS(heap,bits)  do { \\\n\t\t(heap)->flags |= (bits); \\\n\t} while (0)\n#define DUK__HEAP_CLEAR_FLAGS(heap,bits)  do { \\\n\t\t(heap)->flags &= ~(bits); \\\n\t} while (0)\n\n#define DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap)   DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)\n#define DUK_HEAP_HAS_INTERRUPT_RUNNING(heap)               DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)\n#define DUK_HEAP_HAS_FINALIZER_NORESCUE(heap)              DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE)\n#define DUK_HEAP_HAS_DEBUGGER_PAUSED(heap)                 DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED)\n\n#define DUK_HEAP_SET_MARKANDSWEEP_RECLIMIT_REACHED(heap)   DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)\n#define DUK_HEAP_SET_INTERRUPT_RUNNING(heap)               DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)\n#define DUK_HEAP_SET_FINALIZER_NORESCUE(heap)              DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE)\n#define DUK_HEAP_SET_DEBUGGER_PAUSED(heap)                 DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED)\n\n#define DUK_HEAP_CLEAR_MARKANDSWEEP_RECLIMIT_REACHED(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)\n#define DUK_HEAP_CLEAR_INTERRUPT_RUNNING(heap)             DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)\n#define DUK_HEAP_CLEAR_FINALIZER_NORESCUE(heap)            DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE)\n#define DUK_HEAP_CLEAR_DEBUGGER_PAUSED(heap)               DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED)\n\n/*\n *  Longjmp types, also double as identifying continuation type for a rethrow (in 'finally')\n */\n\n#define DUK_LJ_TYPE_UNKNOWN      0    /* unused */\n#define DUK_LJ_TYPE_THROW        1    /* value1 -> error object */\n#define DUK_LJ_TYPE_YIELD        2    /* value1 -> yield value, iserror -> error / normal */\n#define DUK_LJ_TYPE_RESUME       3    /* value1 -> resume value, value2 -> resumee thread, iserror -> error/normal */\n#define DUK_LJ_TYPE_BREAK        4    /* value1 -> label number, pseudo-type to indicate a break continuation (for ENDFIN) */\n#define DUK_LJ_TYPE_CONTINUE     5    /* value1 -> label number, pseudo-type to indicate a continue continuation (for ENDFIN) */\n#define DUK_LJ_TYPE_RETURN       6    /* value1 -> return value, pseudo-type to indicate a return continuation (for ENDFIN) */\n#define DUK_LJ_TYPE_NORMAL       7    /* no value, pseudo-type to indicate a normal continuation (for ENDFIN) */\n\n/*\n *  Mark-and-sweep flags\n *\n *  These are separate from heap level flags now but could be merged.\n *  The heap structure only contains a 'base mark-and-sweep flags'\n *  field and the GC caller can impose further flags.\n */\n\n/* Emergency mark-and-sweep: try extra hard, even at the cost of\n * performance.\n */\n#define DUK_MS_FLAG_EMERGENCY                (1U << 0)\n\n/* Voluntary mark-and-sweep: triggered periodically. */\n#define DUK_MS_FLAG_VOLUNTARY                (1U << 1)\n\n/* Postpone rescue decisions for reachable objects with FINALIZED set.\n * Used during finalize_list processing to avoid incorrect rescue\n * decisions due to finalize_list being a reachability root.\n */\n#define DUK_MS_FLAG_POSTPONE_RESCUE          (1U << 2)\n\n/* Don't compact objects; needed during object property table resize\n * to prevent a recursive resize.  It would suffice to protect only the\n * current object being resized, but this is not yet implemented.\n */\n#define DUK_MS_FLAG_NO_OBJECT_COMPACTION     (1U << 3)\n\n/*\n *  Thread switching\n *\n *  To switch heap->curr_thread, use the macro below so that interrupt counters\n *  get updated correctly.  The macro allows a NULL target thread because that\n *  happens e.g. in call handling.\n */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n#define DUK_HEAP_SWITCH_THREAD(heap,newthr)  duk_heap_switch_thread((heap), (newthr))\n#else\n#define DUK_HEAP_SWITCH_THREAD(heap,newthr)  do { \\\n\t\t(heap)->curr_thread = (newthr); \\\n\t} while (0)\n#endif\n\n/*\n *  Stats\n */\n\n#if defined(DUK_USE_DEBUG)\n#define DUK_STATS_INC(heap,fieldname) do { \\\n\t\t(heap)->fieldname += 1; \\\n\t} while (0)\n#else\n#define DUK_STATS_INC(heap,fieldname) do {} while (0)\n#endif\n\n/*\n *  Other heap related defines\n */\n\n/* Mark-and-sweep interval is relative to combined count of objects and\n * strings kept in the heap during the latest mark-and-sweep pass.\n * Fixed point .8 multiplier and .0 adder.  Trigger count (interval) is\n * decreased by each (re)allocation attempt (regardless of size), and each\n * refzero processed object.\n *\n * 'SKIP' indicates how many (re)allocations to wait until a retry if\n * GC is skipped because there is no thread do it with yet (happens\n * only during init phases).\n */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT              12800L  /* 50x heap size */\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD               1024L\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_SKIP              256L\n#else\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT              256L    /* 1x heap size */\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD               1024L\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_SKIP              256L\n#endif\n\n/* GC torture. */\n#if defined(DUK_USE_GC_TORTURE)\n#define DUK_GC_TORTURE(heap) do { duk_heap_mark_and_sweep((heap), 0); } while (0)\n#else\n#define DUK_GC_TORTURE(heap) do { } while (0)\n#endif\n\n/* Stringcache is used for speeding up char-offset-to-byte-offset\n * translations for non-ASCII strings.\n */\n#define DUK_HEAP_STRCACHE_SIZE                            4\n#define DUK_HEAP_STRINGCACHE_NOCACHE_LIMIT                16  /* strings up to the this length are not cached */\n\n/* Some list management macros. */\n#define DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap,hdr)     duk_heap_insert_into_heap_allocated((heap), (hdr))\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_HEAP_REMOVE_FROM_HEAP_ALLOCATED(heap,hdr)     duk_heap_remove_from_heap_allocated((heap), (hdr))\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n#define DUK_HEAP_INSERT_INTO_FINALIZE_LIST(heap,hdr)      duk_heap_insert_into_finalize_list((heap), (hdr))\n#define DUK_HEAP_REMOVE_FROM_FINALIZE_LIST(heap,hdr)      duk_heap_remove_from_finalize_list((heap), (hdr))\n#endif\n\n/*\n *  Built-in strings\n */\n\n/* heap string indices are autogenerated in duk_strings.h */\n#if defined(DUK_USE_ROM_STRINGS)\n#define DUK_HEAP_GET_STRING(heap,idx) \\\n\t((duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_stridx[(idx)]))\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HEAP_GET_STRING(heap,idx) \\\n\t((duk_hstring *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (heap)->strs16[(idx)]))\n#else\n#define DUK_HEAP_GET_STRING(heap,idx) \\\n\t((heap)->strs[(idx)])\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n/*\n *  Raw memory calls: relative to heap, but no GC interaction\n */\n\n#define DUK_ALLOC_RAW(heap,size) \\\n\t((heap)->alloc_func((heap)->heap_udata, (size)))\n\n#define DUK_REALLOC_RAW(heap,ptr,newsize) \\\n\t((heap)->realloc_func((heap)->heap_udata, (void *) (ptr), (newsize)))\n\n#define DUK_FREE_RAW(heap,ptr) \\\n\t((heap)->free_func((heap)->heap_udata, (void *) (ptr)))\n\n/*\n *  Memory calls: relative to heap, GC interaction, but no error throwing.\n *\n *  XXX: Currently a mark-and-sweep triggered by memory allocation will run\n *  using the heap->heap_thread.  This thread is also used for running\n *  mark-and-sweep finalization; this is not ideal because it breaks the\n *  isolation between multiple global environments.\n *\n *  Notes:\n *\n *    - DUK_FREE() is required to ignore NULL and any other possible return\n *      value of a zero-sized alloc/realloc (same as ANSI C free()).\n *\n *    - There is no DUK_REALLOC_ZEROED because we don't assume to know the\n *      old size.  Caller must zero the reallocated memory.\n *\n *    - DUK_REALLOC_INDIRECT() must be used when a mark-and-sweep triggered\n *      by an allocation failure might invalidate the original 'ptr', thus\n *      causing a realloc retry to use an invalid pointer.  Example: we're\n *      reallocating the value stack and a finalizer resizes the same value\n *      stack during mark-and-sweep.  The indirect variant requests for the\n *      current location of the pointer being reallocated using a callback\n *      right before every realloc attempt; this circuitous approach is used\n *      to avoid strict aliasing issues in a more straightforward indirect\n *      pointer (void **) approach.  Note: the pointer in the storage\n *      location is read but is NOT updated; the caller must do that.\n */\n\n/* callback for indirect reallocs, request for current pointer */\ntypedef void *(*duk_mem_getptr)(duk_heap *heap, void *ud);\n\n#define DUK_ALLOC(heap,size)                            duk_heap_mem_alloc((heap), (size))\n#define DUK_ALLOC_ZEROED(heap,size)                     duk_heap_mem_alloc_zeroed((heap), (size))\n#define DUK_REALLOC(heap,ptr,newsize)                   duk_heap_mem_realloc((heap), (ptr), (newsize))\n#define DUK_REALLOC_INDIRECT(heap,cb,ud,newsize)        duk_heap_mem_realloc_indirect((heap), (cb), (ud), (newsize))\n#define DUK_FREE(heap,ptr)                              duk_heap_mem_free((heap), (ptr))\n\n/*\n *  Checked allocation, relative to a thread\n *\n *  DUK_FREE_CHECKED() doesn't actually throw, but accepts a 'thr' argument\n *  for convenience.\n */\n\n#define DUK_ALLOC_CHECKED(thr,size)                     duk_heap_mem_alloc_checked((thr), (size))\n#define DUK_ALLOC_CHECKED_ZEROED(thr,size)              duk_heap_mem_alloc_checked_zeroed((thr), (size))\n#define DUK_FREE_CHECKED(thr,ptr)                       duk_heap_mem_free((thr)->heap, (ptr))\n\n/*\n *  Memory constants\n */\n\n#define DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT           10  /* Retry allocation after mark-and-sweep for this\n                                                              * many times.  A single mark-and-sweep round is\n                                                              * not guaranteed to free all unreferenced memory\n                                                              * because of finalization (in fact, ANY number of\n                                                              * rounds is strictly not enough).\n                                                              */\n\n#define DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT  3  /* Starting from this round, use emergency mode\n                                                              * for mark-and-sweep.\n                                                              */\n\n/*\n *  Debugger support\n */\n\n/* Maximum number of breakpoints.  Only breakpoints that are set are\n * consulted so increasing this has no performance impact.\n */\n#define DUK_HEAP_MAX_BREAKPOINTS          16\n\n/* Opcode interval for a Date-based status/peek rate limit check.  Only\n * relevant when debugger is attached.  Requesting a timestamp may be a\n * slow operation on some platforms so this shouldn't be too low.  On the\n * other hand a high value makes Duktape react to a pause request slowly.\n */\n#define DUK_HEAP_DBG_RATELIMIT_OPCODES    4000\n\n/* Milliseconds between status notify and transport peeks. */\n#define DUK_HEAP_DBG_RATELIMIT_MILLISECS  200\n\n/* Debugger pause flags. */\n#define DUK_PAUSE_FLAG_ONE_OPCODE        (1U << 0)   /* pause when a single opcode has been executed */\n#define DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE (1U << 1)   /* one opcode pause actually active; artifact of current implementation */\n#define DUK_PAUSE_FLAG_LINE_CHANGE       (1U << 2)   /* pause when current line number changes */\n#define DUK_PAUSE_FLAG_FUNC_ENTRY        (1U << 3)   /* pause when entering a function */\n#define DUK_PAUSE_FLAG_FUNC_EXIT         (1U << 4)   /* pause when exiting current function */\n#define DUK_PAUSE_FLAG_CAUGHT_ERROR      (1U << 5)   /* pause when about to throw an error that is caught */\n#define DUK_PAUSE_FLAG_UNCAUGHT_ERROR    (1U << 6)   /* pause when about to throw an error that won't be caught */\n\nstruct duk_breakpoint {\n\tduk_hstring *filename;\n\tduk_uint32_t line;\n};\n\n/*\n *  String cache should ideally be at duk_hthread level, but that would\n *  cause string finalization to slow down relative to the number of\n *  threads; string finalization must check the string cache for \"weak\"\n *  references to the string being finalized to avoid dead pointers.\n *\n *  Thus, string caches are now at the heap level now.\n */\n\nstruct duk_strcache_entry {\n\tduk_hstring *h;\n\tduk_uint32_t bidx;\n\tduk_uint32_t cidx;\n};\n\n/*\n *  Longjmp state, contains the information needed to perform a longjmp.\n *  Longjmp related values are written to value1, value2, and iserror.\n */\n\nstruct duk_ljstate {\n\tduk_jmpbuf *jmpbuf_ptr;   /* current setjmp() catchpoint */\n\tduk_small_uint_t type;    /* longjmp type */\n\tduk_bool_t iserror;       /* isError flag for yield */\n\tduk_tval value1;          /* 1st related value (type specific) */\n\tduk_tval value2;          /* 2nd related value (type specific) */\n};\n\n#define DUK_ASSERT_LJSTATE_UNSET(heap) do { \\\n\t\tDUK_ASSERT(heap != NULL); \\\n\t\tDUK_ASSERT(heap->lj.type == DUK_LJ_TYPE_UNKNOWN); \\\n\t\tDUK_ASSERT(heap->lj.iserror == 0); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&heap->lj.value1)); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&heap->lj.value2)); \\\n\t} while (0)\n#define DUK_ASSERT_LJSTATE_SET(heap) do { \\\n\t\tDUK_ASSERT(heap != NULL); \\\n\t\tDUK_ASSERT(heap->lj.type != DUK_LJ_TYPE_UNKNOWN); \\\n\t} while (0)\n\n/*\n *  Literal intern cache\n */\n\nstruct duk_litcache_entry {\n\tconst duk_uint8_t *addr;\n\tduk_hstring *h;\n};\n\n/*\n *  Main heap structure\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_heap_assert_valid(duk_heap *heap);\n#define DUK_HEAP_ASSERT_VALID(heap)  do { duk_heap_assert_valid((heap)); } while (0)\n#else\n#define DUK_HEAP_ASSERT_VALID(heap)  do {} while (0)\n#endif\n\nstruct duk_heap {\n\tduk_small_uint_t flags;\n\n\t/* Allocator functions. */\n\tduk_alloc_function alloc_func;\n\tduk_realloc_function realloc_func;\n\tduk_free_function free_func;\n\n\t/* Heap udata, used for allocator functions but also for other heap\n\t * level callbacks like fatal function, pointer compression, etc.\n\t */\n\tvoid *heap_udata;\n\n\t/* Fatal error handling, called e.g. when a longjmp() is needed but\n\t * lj.jmpbuf_ptr is NULL.  fatal_func must never return; it's not\n\t * declared as \"noreturn\" because doing that for typedefs is a bit\n\t * challenging portability-wise.\n\t */\n\tduk_fatal_function fatal_func;\n\n\t/* Main list of allocated heap objects.  Objects are either here,\n\t * in finalize_list waiting for processing, or in refzero_list\n\t * temporarily while a DECREF refzero cascade finishes.\n\t */\n\tduk_heaphdr *heap_allocated;\n\n\t/* Temporary work list for freeing a cascade of objects when a DECREF\n\t * (or DECREF_NORZ) encounters a zero refcount.  Using a work list\n\t * allows fixed C stack size when refcounts go to zero for a chain of\n\t * objects.  Outside of DECREF this is always a NULL because DECREF is\n\t * processed without side effects (only memory free calls).\n\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_heaphdr *refzero_list;\n#endif\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t/* Work list for objects to be finalized. */\n\tduk_heaphdr *finalize_list;\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Object whose finalizer is executing right now (no nesting). */\n\tduk_heaphdr *currently_finalizing;\n#endif\n#endif\n\n\t/* Freelist for duk_activations and duk_catchers. */\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\tduk_activation *activation_free;\n#endif\n#if defined(DUK_USE_CACHE_CATCHER)\n\tduk_catcher *catcher_free;\n#endif\n\n\t/* Voluntary mark-and-sweep trigger counter.  Intentionally signed\n\t * because we continue decreasing the value when voluntary GC cannot\n\t * run.\n\t */\n#if defined(DUK_USE_VOLUNTARY_GC)\n\tduk_int_t ms_trigger_counter;\n#endif\n\n\t/* Mark-and-sweep recursion control: too deep recursion causes\n\t * multi-pass processing to avoid growing C stack without bound.\n\t */\n\tduk_uint_t ms_recursion_depth;\n\n\t/* Mark-and-sweep flags automatically active (used for critical sections). */\n\tduk_small_uint_t ms_base_flags;\n\n\t/* Mark-and-sweep running flag.  Prevents re-entry, and also causes\n\t * refzero events to be ignored (= objects won't be queued to refzero_list).\n\t *\n\t * 0: mark-and-sweep not running\n\t * 1: mark-and-sweep is running\n\t * 2: heap destruction active or debugger active, prevent mark-and-sweep\n\t *    and refzero processing (but mark-and-sweep not itself running)\n\t */\n\tduk_uint_t ms_running;\n\n\t/* Mark-and-sweep prevent count, stacking.  Used to avoid M&S side\n\t * effects (besides finalizers which are controlled separately) such\n\t * as compacting the string table or object property tables.  This\n\t * is also bumped when ms_running is set to prevent recursive re-entry.\n\t * Can also be bumped when mark-and-sweep is not running.\n\t */\n\tduk_uint_t ms_prevent_count;\n\n\t/* Finalizer processing prevent count, stacking.  Bumped when finalizers\n\t * are processed to prevent recursive finalizer processing (first call site\n\t * processing finalizers handles all finalizers until the list is empty).\n\t * Can also be bumped explicitly to prevent finalizer execution.\n\t */\n\tduk_uint_t pf_prevent_count;\n\n\t/* When processing finalize_list, don't actually run finalizers but\n\t * queue finalizable objects back to heap_allocated as is.  This is\n\t * used during heap destruction to deal with finalizers that keep\n\t * on creating more finalizable garbage.\n\t */\n\tduk_uint_t pf_skip_finalizers;\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Set when we're in a critical path where an error throw would cause\n\t * e.g. sandboxing/protected call violations or state corruption.  This\n\t * is just used for asserts.\n\t */\n\tduk_bool_t error_not_allowed;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Set when heap is still being initialized, helps with writing\n\t * some assertions.\n\t */\n\tduk_bool_t heap_initializing;\n#endif\n\n\t/* Marker for detecting internal \"double faults\", errors thrown when\n\t * we're trying to create an error object, see duk_error_throw.c.\n\t */\n\tduk_bool_t creating_error;\n\n\t/* Marker for indicating we're calling a user error augmentation\n\t * (errCreate/errThrow) function.  Errors created/thrown during\n\t * such a call are not augmented.\n\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tduk_bool_t augmenting_error;\n#endif\n\n\t/* Longjmp state. */\n\tduk_ljstate lj;\n\n\t/* Heap thread, used internally and for finalization. */\n\tduk_hthread *heap_thread;\n\n\t/* Current running thread. */\n\tduk_hthread *curr_thread;\n\n\t/* Heap level \"stash\" object (e.g., various reachability roots). */\n\tduk_hobject *heap_object;\n\n\t/* duk_handle_call / duk_handle_safe_call recursion depth limiting */\n\tduk_int_t call_recursion_depth;\n\tduk_int_t call_recursion_limit;\n\n\t/* Mix-in value for computing string hashes; should be reasonably unpredictable. */\n\tduk_uint32_t hash_seed;\n\n\t/* Random number state for duk_util_tinyrandom.c. */\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\n#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS)\n\tduk_uint32_t rnd_state;  /* State for Shamir's three-op algorithm */\n#else\n\tduk_uint64_t rnd_state[2];  /* State for xoroshiro128+ */\n#endif\n#endif\n\n\t/* Counter for unique local symbol creation. */\n\t/* XXX: When 64-bit types are available, it would be more efficient to\n\t * use a duk_uint64_t at least for incrementing but maybe also for\n\t * string formatting in the Symbol constructor.\n\t */\n\tduk_uint32_t sym_counter[2];\n\n\t/* For manual debugging: instruction count based on executor and\n\t * interrupt counter book-keeping.  Inspect debug logs to see how\n\t * they match up.\n\t */\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\tduk_int_t inst_count_exec;\n\tduk_int_t inst_count_interrupt;\n#endif\n\n\t/* Debugger state. */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* Callbacks and udata; dbg_read_cb != NULL is used to indicate attached state. */\n\tduk_debug_read_function dbg_read_cb;                /* required, NULL implies detached */\n\tduk_debug_write_function dbg_write_cb;              /* required */\n\tduk_debug_peek_function dbg_peek_cb;\n\tduk_debug_read_flush_function dbg_read_flush_cb;\n\tduk_debug_write_flush_function dbg_write_flush_cb;\n\tduk_debug_request_function dbg_request_cb;\n\tduk_debug_detached_function dbg_detached_cb;\n\tvoid *dbg_udata;\n\n\t/* The following are only relevant when debugger is attached. */\n\tduk_bool_t dbg_processing;              /* currently processing messages or breakpoints: don't enter message processing recursively (e.g. no breakpoints when processing debugger eval) */\n\tduk_bool_t dbg_state_dirty;             /* resend state next time executor is about to run */\n\tduk_bool_t dbg_force_restart;           /* force executor restart to recheck breakpoints; used to handle function returns (see GH-303) */\n\tduk_bool_t dbg_detaching;               /* debugger detaching; used to avoid calling detach handler recursively */\n\tduk_small_uint_t dbg_pause_flags;       /* flags for automatic pause behavior */\n\tduk_activation *dbg_pause_act;          /* activation related to pause behavior (pause on line change, function entry/exit) */\n\tduk_uint32_t dbg_pause_startline;       /* starting line number for line change related pause behavior */\n\tduk_breakpoint dbg_breakpoints[DUK_HEAP_MAX_BREAKPOINTS];  /* breakpoints: [0,breakpoint_count[ gc reachable */\n\tduk_small_uint_t dbg_breakpoint_count;\n\tduk_breakpoint *dbg_breakpoints_active[DUK_HEAP_MAX_BREAKPOINTS + 1];  /* currently active breakpoints: NULL term, borrowed pointers */\n\t/* XXX: make active breakpoints actual copies instead of pointers? */\n\n\t/* These are for rate limiting Status notifications and transport peeking. */\n\tduk_uint_t dbg_exec_counter;            /* cumulative opcode execution count (overflows are OK) */\n\tduk_uint_t dbg_last_counter;            /* value of dbg_exec_counter when we last did a Date-based check */\n\tduk_double_t dbg_last_time;             /* time when status/peek was last done (Date-based rate limit) */\n\n\t/* Used to support single-byte stream lookahead. */\n\tduk_bool_t dbg_have_next_byte;\n\tduk_uint8_t dbg_next_byte;\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_bool_t dbg_calling_transport;       /* transport call in progress, calling into Duktape forbidden */\n#endif\n\n\t/* String intern table (weak refs). */\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable16;\n#else\n\tduk_hstring **strtable;\n#endif\n\tduk_uint32_t st_mask;    /* mask for lookup, st_size - 1 */\n\tduk_uint32_t st_size;    /* stringtable size */\n#if (DUK_USE_STRTAB_MINSIZE != DUK_USE_STRTAB_MAXSIZE)\n\tduk_uint32_t st_count;   /* string count for resize load factor checks */\n#endif\n\tduk_bool_t st_resizing;  /* string table is being resized; avoid recursive resize */\n\n\t/* String access cache (codepoint offset -> byte offset) for fast string\n\t * character looping; 'weak' reference which needs special handling in GC.\n\t */\n\tduk_strcache_entry strcache[DUK_HEAP_STRCACHE_SIZE];\n\n#if defined(DUK_USE_LITCACHE_SIZE)\n\t/* Literal intern cache.  When enabled, strings interned as literals\n\t * (e.g. duk_push_literal()) will be pinned and cached for the lifetime\n\t * of the heap.\n\t */\n\tduk_litcache_entry litcache[DUK_USE_LITCACHE_SIZE];\n#endif\n\n\t/* Built-in strings. */\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* No field needed when strings are in ROM. */\n#else\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t strs16[DUK_HEAP_NUM_STRINGS];\n#else\n\tduk_hstring *strs[DUK_HEAP_NUM_STRINGS];\n#endif\n#endif\n\n\t/* Stats. */\n#if defined(DUK_USE_DEBUG)\n\tduk_int_t stats_exec_opcodes;\n\tduk_int_t stats_exec_interrupt;\n\tduk_int_t stats_exec_throw;\n\tduk_int_t stats_call_all;\n\tduk_int_t stats_call_tailcall;\n\tduk_int_t stats_call_ecmatoecma;\n\tduk_int_t stats_safecall_all;\n\tduk_int_t stats_safecall_nothrow;\n\tduk_int_t stats_safecall_throw;\n\tduk_int_t stats_ms_try_count;\n\tduk_int_t stats_ms_skip_count;\n\tduk_int_t stats_ms_emergency_count;\n\tduk_int_t stats_strtab_intern_hit;\n\tduk_int_t stats_strtab_intern_miss;\n\tduk_int_t stats_strtab_resize_check;\n\tduk_int_t stats_strtab_resize_grow;\n\tduk_int_t stats_strtab_resize_shrink;\n\tduk_int_t stats_strtab_litcache_hit;\n\tduk_int_t stats_strtab_litcache_miss;\n\tduk_int_t stats_strtab_litcache_pin;\n\tduk_int_t stats_object_realloc_props;\n\tduk_int_t stats_object_abandon_array;\n\tduk_int_t stats_getownpropdesc_count;\n\tduk_int_t stats_getownpropdesc_hit;\n\tduk_int_t stats_getownpropdesc_miss;\n\tduk_int_t stats_getpropdesc_count;\n\tduk_int_t stats_getpropdesc_hit;\n\tduk_int_t stats_getpropdesc_miss;\n\tduk_int_t stats_getprop_all;\n\tduk_int_t stats_getprop_arrayidx;\n\tduk_int_t stats_getprop_bufobjidx;\n\tduk_int_t stats_getprop_bufferidx;\n\tduk_int_t stats_getprop_bufferlen;\n\tduk_int_t stats_getprop_stringidx;\n\tduk_int_t stats_getprop_stringlen;\n\tduk_int_t stats_getprop_proxy;\n\tduk_int_t stats_getprop_arguments;\n\tduk_int_t stats_putprop_all;\n\tduk_int_t stats_putprop_arrayidx;\n\tduk_int_t stats_putprop_bufobjidx;\n\tduk_int_t stats_putprop_bufferidx;\n\tduk_int_t stats_putprop_proxy;\n\tduk_int_t stats_getvar_all;\n\tduk_int_t stats_putvar_all;\n\tduk_int_t stats_envrec_delayedcreate;\n\tduk_int_t stats_envrec_create;\n\tduk_int_t stats_envrec_newenv;\n\tduk_int_t stats_envrec_oldenv;\n\tduk_int_t stats_envrec_pushclosure;\n#endif\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL\nduk_heap *duk_heap_alloc(duk_alloc_function alloc_func,\n                         duk_realloc_function realloc_func,\n                         duk_free_function free_func,\n                         void *heap_udata,\n                         duk_fatal_function fatal_func);\nDUK_INTERNAL_DECL void duk_heap_free(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_free_hobject(duk_heap *heap, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_free_hbuffer(duk_heap *heap, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_free_hstring(duk_heap *heap, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr);\n\nDUK_INTERNAL_DECL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphdr *hdr);\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL_DECL void duk_heap_remove_from_heap_allocated(duk_heap *heap, duk_heaphdr *hdr);\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL_DECL void duk_heap_insert_into_finalize_list(duk_heap *heap, duk_heaphdr *hdr);\nDUK_INTERNAL_DECL void duk_heap_remove_from_finalize_list(duk_heap *heap, duk_heaphdr *hdr);\n#endif\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL duk_bool_t duk_heap_in_heap_allocated(duk_heap *heap, duk_heaphdr *ptr);\n#endif\n#if defined(DUK_USE_INTERRUPT_COUNTER)\nDUK_INTERNAL_DECL void duk_heap_switch_thread(duk_heap *heap, duk_hthread *new_thr);\n#endif\n\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen);\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t len);\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_literal_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen);\n#endif\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_u32(duk_heap *heap, duk_uint32_t val);\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_u32_checked(duk_hthread *thr, duk_uint32_t val);\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL_DECL void duk_heap_strtable_unlink(duk_heap *heap, duk_hstring *h);\n#endif\nDUK_INTERNAL_DECL void duk_heap_strtable_unlink_prev(duk_heap *heap, duk_hstring *h, duk_hstring *prev);\nDUK_INTERNAL_DECL void duk_heap_strtable_force_resize(duk_heap *heap);\nDUK_INTERNAL void duk_heap_strtable_free(duk_heap *heap);\n#if defined(DUK_USE_DEBUG)\nDUK_INTERNAL void duk_heap_strtable_dump(duk_heap *heap);\n#endif\n\nDUK_INTERNAL_DECL void duk_heap_strcache_string_remove(duk_heap *heap, duk_hstring *h);\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *thr, duk_hstring *h, duk_uint_fast32_t char_offset);\n\n#if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS)\nDUK_INTERNAL_DECL void *duk_default_alloc_function(void *udata, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_default_realloc_function(void *udata, void *ptr, duk_size_t newsize);\nDUK_INTERNAL_DECL void duk_default_free_function(void *udata, void *ptr);\n#endif\n\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc(duk_heap *heap, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc_zeroed(duk_heap *heap, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc_checked(duk_hthread *thr, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc_checked_zeroed(duk_hthread *thr, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, duk_size_t newsize);\nDUK_INTERNAL_DECL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize);\nDUK_INTERNAL_DECL void duk_heap_mem_free(duk_heap *heap, void *ptr);\n\nDUK_INTERNAL_DECL void duk_heap_free_freelists(duk_heap *heap);\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL_DECL void duk_heap_run_finalizer(duk_heap *heap, duk_hobject *obj);\nDUK_INTERNAL_DECL void duk_heap_process_finalize_list(duk_heap *heap);\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_INTERNAL_DECL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags);\n\nDUK_INTERNAL_DECL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len);\n\n#endif  /* DUK_HEAP_H_INCLUDED */\n/* #include duk_debugger.h */\n#if !defined(DUK_DEBUGGER_H_INCLUDED)\n#define DUK_DEBUGGER_H_INCLUDED\n\n/* Debugger protocol version is defined in the public API header. */\n\n/* Initial bytes for markers. */\n#define DUK_DBG_IB_EOM                   0x00\n#define DUK_DBG_IB_REQUEST               0x01\n#define DUK_DBG_IB_REPLY                 0x02\n#define DUK_DBG_IB_ERROR                 0x03\n#define DUK_DBG_IB_NOTIFY                0x04\n\n/* Other initial bytes. */\n#define DUK_DBG_IB_INT4                  0x10\n#define DUK_DBG_IB_STR4                  0x11\n#define DUK_DBG_IB_STR2                  0x12\n#define DUK_DBG_IB_BUF4                  0x13\n#define DUK_DBG_IB_BUF2                  0x14\n#define DUK_DBG_IB_UNUSED                0x15\n#define DUK_DBG_IB_UNDEFINED             0x16\n#define DUK_DBG_IB_NULL                  0x17\n#define DUK_DBG_IB_TRUE                  0x18\n#define DUK_DBG_IB_FALSE                 0x19\n#define DUK_DBG_IB_NUMBER                0x1a\n#define DUK_DBG_IB_OBJECT                0x1b\n#define DUK_DBG_IB_POINTER               0x1c\n#define DUK_DBG_IB_LIGHTFUNC             0x1d\n#define DUK_DBG_IB_HEAPPTR               0x1e\n/* The short string/integer initial bytes starting from 0x60 don't have\n * defines now.\n */\n\n/* Error codes. */\n#define DUK_DBG_ERR_UNKNOWN              0x00\n#define DUK_DBG_ERR_UNSUPPORTED          0x01\n#define DUK_DBG_ERR_TOOMANY              0x02\n#define DUK_DBG_ERR_NOTFOUND             0x03\n#define DUK_DBG_ERR_APPLICATION          0x04\n\n/* Commands and notifys initiated by Duktape. */\n#define DUK_DBG_CMD_STATUS               0x01\n#define DUK_DBG_CMD_UNUSED_2             0x02  /* Duktape 1.x: print notify */\n#define DUK_DBG_CMD_UNUSED_3             0x03  /* Duktape 1.x: alert notify */\n#define DUK_DBG_CMD_UNUSED_4             0x04  /* Duktape 1.x: log notify */\n#define DUK_DBG_CMD_THROW                0x05\n#define DUK_DBG_CMD_DETACHING            0x06\n#define DUK_DBG_CMD_APPNOTIFY            0x07\n\n/* Commands initiated by debug client. */\n#define DUK_DBG_CMD_BASICINFO            0x10\n#define DUK_DBG_CMD_TRIGGERSTATUS        0x11\n#define DUK_DBG_CMD_PAUSE                0x12\n#define DUK_DBG_CMD_RESUME               0x13\n#define DUK_DBG_CMD_STEPINTO             0x14\n#define DUK_DBG_CMD_STEPOVER             0x15\n#define DUK_DBG_CMD_STEPOUT              0x16\n#define DUK_DBG_CMD_LISTBREAK            0x17\n#define DUK_DBG_CMD_ADDBREAK             0x18\n#define DUK_DBG_CMD_DELBREAK             0x19\n#define DUK_DBG_CMD_GETVAR               0x1a\n#define DUK_DBG_CMD_PUTVAR               0x1b\n#define DUK_DBG_CMD_GETCALLSTACK         0x1c\n#define DUK_DBG_CMD_GETLOCALS            0x1d\n#define DUK_DBG_CMD_EVAL                 0x1e\n#define DUK_DBG_CMD_DETACH               0x1f\n#define DUK_DBG_CMD_DUMPHEAP             0x20\n#define DUK_DBG_CMD_GETBYTECODE          0x21\n#define DUK_DBG_CMD_APPREQUEST           0x22\n#define DUK_DBG_CMD_GETHEAPOBJINFO       0x23\n#define DUK_DBG_CMD_GETOBJPROPDESC       0x24\n#define DUK_DBG_CMD_GETOBJPROPDESCRANGE  0x25\n\n/* The low 8 bits map directly to duk_hobject.h DUK_PROPDESC_FLAG_xxx.\n * The remaining flags are specific to the debugger.\n */\n#define DUK_DBG_PROPFLAG_SYMBOL          (1U << 8)\n#define DUK_DBG_PROPFLAG_HIDDEN          (1U << 9)\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL_DECL void duk_debug_do_detach(duk_heap *heap);\n\nDUK_INTERNAL_DECL duk_bool_t duk_debug_read_peek(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_write_flush(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_debug_skip_bytes(duk_hthread *thr, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_skip_byte(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_size_t length);\nDUK_INTERNAL_DECL duk_uint8_t duk_debug_read_byte(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_int32_t duk_debug_read_int(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_hstring *duk_debug_read_hstring(duk_hthread *thr);\n/* XXX: exposed duk_debug_read_pointer */\n/* XXX: exposed duk_debug_read_buffer */\n/* XXX: exposed duk_debug_read_hbuffer */\n#if 0\nDUK_INTERNAL_DECL duk_heaphdr *duk_debug_read_heapptr(duk_hthread *thr);\n#endif\n#if defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL_DECL duk_heaphdr *duk_debug_read_any_ptr(duk_hthread *thr);\n#endif\nDUK_INTERNAL_DECL duk_tval *duk_debug_read_tval(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_debug_write_bytes(duk_hthread *thr, const duk_uint8_t *data, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_write_byte(duk_hthread *thr, duk_uint8_t x);\nDUK_INTERNAL_DECL void duk_debug_write_unused(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_write_undefined(duk_hthread *thr);\n#if defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL_DECL void duk_debug_write_null(duk_hthread *thr);\n#endif\nDUK_INTERNAL_DECL void duk_debug_write_boolean(duk_hthread *thr, duk_uint_t val);\nDUK_INTERNAL_DECL void duk_debug_write_int(duk_hthread *thr, duk_int32_t x);\nDUK_INTERNAL_DECL void duk_debug_write_uint(duk_hthread *thr, duk_uint32_t x);\nDUK_INTERNAL_DECL void duk_debug_write_string(duk_hthread *thr, const char *data, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_write_cstring(duk_hthread *thr, const char *data);\nDUK_INTERNAL_DECL void duk_debug_write_hstring(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_debug_write_buffer(duk_hthread *thr, const char *data, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_write_hbuffer(duk_hthread *thr, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_debug_write_pointer(duk_hthread *thr, void *ptr);\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP) || defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL_DECL void duk_debug_write_heapptr(duk_hthread *thr, duk_heaphdr *h);\n#endif\nDUK_INTERNAL_DECL void duk_debug_write_hobject(duk_hthread *thr, duk_hobject *obj);\nDUK_INTERNAL_DECL void duk_debug_write_tval(duk_hthread *thr, duk_tval *tv);\n#if 0  /* unused */\nDUK_INTERNAL_DECL void duk_debug_write_request(duk_hthread *thr, duk_small_uint_t command);\n#endif\nDUK_INTERNAL_DECL void duk_debug_write_reply(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_write_error_eom(duk_hthread *thr, duk_small_uint_t err_code, const char *msg);\nDUK_INTERNAL_DECL void duk_debug_write_notify(duk_hthread *thr, duk_small_uint_t command);\nDUK_INTERNAL_DECL void duk_debug_write_eom(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_debug_curr_line(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_send_status(duk_hthread *thr);\n#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)\nDUK_INTERNAL_DECL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal);\n#endif\n\nDUK_INTERNAL_DECL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev_pc);\nDUK_INTERNAL_DECL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t no_block);\n\nDUK_INTERNAL_DECL duk_small_int_t duk_debug_add_breakpoint(duk_hthread *thr, duk_hstring *filename, duk_uint32_t line);\nDUK_INTERNAL_DECL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_small_uint_t breakpoint_index);\n\nDUK_INTERNAL_DECL duk_bool_t duk_debug_is_attached(duk_heap *heap);\nDUK_INTERNAL_DECL duk_bool_t duk_debug_is_paused(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_debug_set_paused(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_debug_clear_paused(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_debug_clear_pause_state(duk_heap *heap);\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n#endif  /* DUK_DEBUGGER_H_INCLUDED */\n/* #include duk_debug.h */\n/*\n *  Debugging macros, DUK_DPRINT() and its variants in particular.\n *\n *  DUK_DPRINT() allows formatted debug prints, and supports standard\n *  and Duktape specific formatters.  See duk_debug_vsnprintf.c for details.\n *\n *  DUK_D(x), DUK_DD(x), and DUK_DDD(x) are used together with log macros\n *  for technical reasons.  They are concretely used to hide 'x' from the\n *  compiler when the corresponding log level is disabled.  This allows\n *  clean builds on non-C99 compilers, at the cost of more verbose code.\n *  Examples:\n *\n *    DUK_D(DUK_DPRINT(\"foo\"));\n *    DUK_DD(DUK_DDPRINT(\"foo\"));\n *    DUK_DDD(DUK_DDDPRINT(\"foo\"));\n *\n *  This approach is preferable to the old \"double parentheses\" hack because\n *  double parentheses make the C99 solution worse: __FILE__ and __LINE__ can\n *  no longer be added transparently without going through globals, which\n *  works poorly with threading.\n */\n\n#if !defined(DUK_DEBUG_H_INCLUDED)\n#define DUK_DEBUG_H_INCLUDED\n\n#if defined(DUK_USE_DEBUG)\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0)\n#define DUK_D(x) x\n#else\n#define DUK_D(x) do { } while (0) /* omit */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n#define DUK_DD(x) x\n#else\n#define DUK_DD(x) do { } while (0) /* omit */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK_DDD(x) x\n#else\n#define DUK_DDD(x) do { } while (0) /* omit */\n#endif\n\n/*\n *  Exposed debug macros: debugging enabled\n */\n\n#if defined(DUK_USE_VARIADIC_MACROS)\n\n/* Note: combining __FILE__, __LINE__, and __func__ into fmt would be\n * possible compile time, but waste some space with shared function names.\n */\n#define DUK__DEBUG_LOG(lev,...)  duk_debug_log((duk_int_t) (lev), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, DUK_FUNC_MACRO, __VA_ARGS__);\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0)\n#define DUK_DPRINT(...)          DUK__DEBUG_LOG(DUK_LEVEL_DEBUG, __VA_ARGS__)\n#else\n#define DUK_DPRINT(...)\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n#define DUK_DDPRINT(...)         DUK__DEBUG_LOG(DUK_LEVEL_DDEBUG, __VA_ARGS__)\n#else\n#define DUK_DDPRINT(...)\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK_DDDPRINT(...)        DUK__DEBUG_LOG(DUK_LEVEL_DDDEBUG, __VA_ARGS__)\n#else\n#define DUK_DDDPRINT(...)\n#endif\n\n#else  /* DUK_USE_VARIADIC_MACROS */\n\n#define DUK__DEBUG_STASH(lev)    \\\n\t(void) DUK_SNPRINTF(duk_debug_file_stash, DUK_DEBUG_STASH_SIZE, \"%s\", (const char *) DUK_FILE_MACRO), \\\n\t(void) (duk_debug_file_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), \\\n\t(void) (duk_debug_line_stash = (duk_int_t) DUK_LINE_MACRO), \\\n\t(void) DUK_SNPRINTF(duk_debug_func_stash, DUK_DEBUG_STASH_SIZE, \"%s\", (const char *) DUK_FUNC_MACRO), \\\n\t(void) (duk_debug_func_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), \\\n\t(void) (duk_debug_level_stash = (lev))\n\n/* Without variadic macros resort to comma expression trickery to handle debug\n * prints.  This generates a lot of harmless warnings.  These hacks are not\n * needed normally because DUK_D() and friends will hide the entire debug log\n * statement from the compiler.\n */\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0)\n#define DUK_DPRINT  DUK__DEBUG_STASH(DUK_LEVEL_DEBUG), (void) duk_debug_log  /* args go here in parens */\n#else\n#define DUK_DPRINT  0 && /* args go here as a comma expression in parens */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n#define DUK_DDPRINT  DUK__DEBUG_STASH(DUK_LEVEL_DDEBUG), (void) duk_debug_log  /* args go here in parens */\n#else\n#define DUK_DDPRINT  0 && /* args */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK_DDDPRINT  DUK__DEBUG_STASH(DUK_LEVEL_DDDEBUG), (void) duk_debug_log  /* args go here in parens */\n#else\n#define DUK_DDDPRINT  0 && /* args */\n#endif\n\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n#else  /* DUK_USE_DEBUG */\n\n/*\n *  Exposed debug macros: debugging disabled\n */\n\n#define DUK_D(x) do { } while (0) /* omit */\n#define DUK_DD(x) do { } while (0) /* omit */\n#define DUK_DDD(x) do { } while (0) /* omit */\n\n#if defined(DUK_USE_VARIADIC_MACROS)\n\n#define DUK_DPRINT(...)\n#define DUK_DDPRINT(...)\n#define DUK_DDDPRINT(...)\n\n#else  /* DUK_USE_VARIADIC_MACROS */\n\n#define DUK_DPRINT    0 && /* args go here as a comma expression in parens */\n#define DUK_DDPRINT   0 && /* args */\n#define DUK_DDDPRINT  0 && /* args */\n\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n#endif  /* DUK_USE_DEBUG */\n\n/*\n *  Structs\n */\n\n#if defined(DUK_USE_DEBUG)\nstruct duk_fixedbuffer {\n\tduk_uint8_t *buffer;\n\tduk_size_t length;\n\tduk_size_t offset;\n\tduk_bool_t truncated;\n};\n#endif\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_INTERNAL_DECL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const char *format, va_list ap);\n#if 0  /*unused*/\nDUK_INTERNAL_DECL duk_int_t duk_debug_snprintf(char *str, duk_size_t size, const char *format, ...);\n#endif\nDUK_INTERNAL_DECL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_uint8_t *fptr, duk_size_t fptr_size);\n\n#if defined(DUK_USE_VARIADIC_MACROS)\nDUK_INTERNAL_DECL void duk_debug_log(duk_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...);\n#else  /* DUK_USE_VARIADIC_MACROS */\n/* parameter passing, not thread safe */\n#define DUK_DEBUG_STASH_SIZE  128\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL_DECL duk_int_t duk_debug_line_stash;\nDUK_INTERNAL_DECL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL_DECL duk_int_t duk_debug_level_stash;\n#endif\nDUK_INTERNAL_DECL void duk_debug_log(const char *fmt, ...);\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\nDUK_INTERNAL_DECL void duk_fb_put_bytes(duk_fixedbuffer *fb, const duk_uint8_t *buffer, duk_size_t length);\nDUK_INTERNAL_DECL void duk_fb_put_byte(duk_fixedbuffer *fb, duk_uint8_t x);\nDUK_INTERNAL_DECL void duk_fb_put_cstring(duk_fixedbuffer *fb, const char *x);\nDUK_INTERNAL_DECL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...);\nDUK_INTERNAL_DECL void duk_fb_put_funcptr(duk_fixedbuffer *fb, duk_uint8_t *fptr, duk_size_t fptr_size);\nDUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);\n\n#endif  /* DUK_USE_DEBUG */\n\n#endif  /* DUK_DEBUG_H_INCLUDED */\n/* #include duk_error.h */\n/*\n *  Error handling macros, assertion macro, error codes.\n *\n *  There are three types of 'errors':\n *\n *    1. Ordinary errors relative to a thread, cause a longjmp, catchable.\n *    2. Fatal errors relative to a heap, cause fatal handler to be called.\n *    3. Fatal errors without context, cause the default (not heap specific)\n *       fatal handler to be called.\n *\n *  Fatal errors without context are used by debug code such as assertions.\n *  By providing a fatal error handler for a Duktape heap, user code can\n *  avoid fatal errors without context in non-debug builds.\n */\n\n#if !defined(DUK_ERROR_H_INCLUDED)\n#define DUK_ERROR_H_INCLUDED\n\n/*\n *  Error codes: defined in duktape.h\n *\n *  Error codes are used as a shorthand to throw exceptions from inside\n *  the implementation.  The appropriate ECMAScript object is constructed\n *  based on the code.  ECMAScript code throws objects directly.  The error\n *  codes are defined in the public API header because they are also used\n *  by calling code.\n */\n\n/*\n *  Normal error\n *\n *  Normal error is thrown with a longjmp() through the current setjmp()\n *  catchpoint record in the duk_heap.  The 'curr_thread' of the duk_heap\n *  identifies the throwing thread.\n *\n *  Error formatting is usually unnecessary.  The error macros provide a\n *  zero argument version (no formatting) and separate macros for small\n *  argument counts.  Variadic macros are not used to avoid portability\n *  issues and avoid the need for stash-based workarounds when they're not\n *  available.  Vararg calls are avoided for non-formatted error calls\n *  because vararg call sites are larger than normal, and there are a lot\n *  of call sites with no formatting.\n *\n *  Note that special formatting provided by debug macros is NOT available.\n *\n *  The _RAW variants allow the caller to specify file and line.  This makes\n *  it easier to write checked calls which want to use the call site of the\n *  checked function, not the error macro call inside the checked function.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\n/* Because there are quite many call sites, pack error code (require at most\n * 8-bit) into a single argument.\n */\n#define DUK_ERROR(thr,err,msg) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (msg)); \\\n\t} while (0)\n#define DUK_ERROR_RAW(thr,file,line,err,msg) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (msg)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT1(thr,err,fmt,arg1) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT1(thr,file,line,err,fmt,arg1) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT2(thr,err,fmt,arg1,arg2) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT2(thr,file,line,err,fmt,arg1,arg2) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT3(thr,err,fmt,arg1,arg2,arg3) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT3(thr,file,line,err,fmt,arg1,arg2,arg3) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT4(thr,err,fmt,arg1,arg2,arg3,arg4) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3), (arg4)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT4(thr,file,line,err,fmt,arg1,arg2,arg3,arg4) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3), (arg4)); \\\n\t} while (0)\n\n#else  /* DUK_USE_VERBOSE_ERRORS */\n\n#define DUK_ERROR(thr,err,msg)                    duk_err_handle_error((thr), (err))\n#define DUK_ERROR_RAW(thr,file,line,err,msg)      duk_err_handle_error((thr), (err))\n\n#define DUK_ERROR_FMT1(thr,err,fmt,arg1) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT1(thr,file,line,err,fmt,arg1) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#define DUK_ERROR_FMT2(thr,err,fmt,arg1,arg2) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT2(thr,file,line,err,fmt,arg1,arg2) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#define DUK_ERROR_FMT3(thr,err,fmt,arg1,arg2,arg3) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT3(thr,file,line,err,fmt,arg1,arg2,arg3) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#define DUK_ERROR_FMT4(thr,err,fmt,arg1,arg2,arg3,arg4) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT4(thr,file,line,err,fmt,arg1,arg2,arg3,arg4) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n/*\n *  Fatal error without context\n *\n *  The macro is an expression to make it compatible with DUK_ASSERT_EXPR().\n */\n\n#define DUK_FATAL_WITHOUT_CONTEXT(msg) \\\n\tduk_default_fatal_handler(NULL, (msg))\n\n/*\n *  Error throwing helpers\n *\n *  The goal is to provide verbose and configurable error messages.  Call\n *  sites should be clean in source code and compile to a small footprint.\n *  Small footprint is also useful for performance because small cold paths\n *  reduce code cache pressure.  Adding macros here only makes sense if there\n *  are enough call sites to get concrete benefits.\n *\n *  DUK_ERROR_xxx() macros are generic and can be used anywhere.\n *\n *  DUK_DCERROR_xxx() macros can only be used in Duktape/C functions where\n *  the \"return DUK_RET_xxx;\" shorthand is available for low memory targets.\n *  The DUK_DCERROR_xxx() macros always either throw or perform a\n *  'return DUK_RET_xxx' from the calling function.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n/* Verbose errors with key/value summaries (non-paranoid) or without key/value\n * summaries (paranoid, for some security sensitive environments), the paranoid\n * vs. non-paranoid distinction affects only a few specific errors.\n */\n#if defined(DUK_USE_PARANOID_ERRORS)\n#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \\\n\t\tduk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx), (expectname)); \\\n\t} while (0)\n#else  /* DUK_USE_PARANOID_ERRORS */\n#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \\\n\t\tduk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx), (expectname)); \\\n\t} while (0)\n#endif  /* DUK_USE_PARANOID_ERRORS */\n\n#define DUK_ERROR_INTERNAL(thr) do { \\\n\t\tduk_err_error_internal((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_INTERNAL(thr) do { \\\n\t\tDUK_ERROR_INTERNAL((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_ALLOC_FAILED(thr) do { \\\n\t\tduk_err_error_alloc_failed((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_ERROR_UNSUPPORTED(thr) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_ERROR, DUK_STR_UNSUPPORTED); \\\n\t} while (0)\n#define DUK_DCERROR_UNSUPPORTED(thr) do { \\\n\t\tDUK_ERROR_UNSUPPORTED((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_ERROR(thr,msg) do { \\\n\t\tduk_err_error((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INDEX(thr,idx) do { \\\n\t\tduk_err_range_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) do { \\\n\t\tduk_err_range_push_beyond((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tDUK_ERROR_RANGE((thr), DUK_STR_INVALID_ARGS); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tDUK_ERROR_RANGE_INVALID_ARGS((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tDUK_ERROR_RANGE((thr), DUK_STR_INVALID_COUNT); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tDUK_ERROR_RANGE_INVALID_COUNT((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tDUK_ERROR_RANGE((thr), DUK_STR_INVALID_LENGTH); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tDUK_ERROR_RANGE_INVALID_LENGTH((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_RANGE(thr,msg) do { \\\n\t\tduk_err_range((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_EVAL(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_EVAL_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_REFERENCE(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_REFERENCE_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_SYNTAX(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_SYNTAX_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tduk_err_type_invalid_args((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tDUK_ERROR_TYPE_INVALID_ARGS((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tduk_err_type_invalid_state((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tDUK_ERROR_TYPE_INVALID_STATE((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tduk_err_type_invalid_trap_result((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tDUK_ERROR_TYPE((thr), DUK_STR_INVALID_TRAP_RESULT); \\\n\t} while (0)\n#define DUK_ERROR_TYPE(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_TYPE_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_URI(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_URI_ERROR, (msg)); \\\n\t} while (0)\n#else  /* DUK_USE_VERBOSE_ERRORS */\n/* Non-verbose errors for low memory targets: no file, line, or message. */\n\n#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n\n#define DUK_ERROR_INTERNAL(thr) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_INTERNAL(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_ALLOC_FAILED(thr) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_ERROR_UNSUPPORTED(thr) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_UNSUPPORTED(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_ERROR(thr,msg) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INDEX(thr,idx) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_RANGE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_RANGE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_RANGE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_RANGE(thr,msg) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_ERROR_EVAL(thr,msg) do { \\\n\t\tduk_err_eval((thr)); \\\n\t} while (0)\n#define DUK_ERROR_REFERENCE(thr,msg) do { \\\n\t\tduk_err_reference((thr)); \\\n\t} while (0)\n#define DUK_ERROR_SYNTAX(thr,msg) do { \\\n\t\tduk_err_syntax((thr)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_TYPE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_TYPE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE(thr,msg) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_ERROR_URI(thr,msg) do { \\\n\t\tduk_err_uri((thr)); \\\n\t} while (0)\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n/*\n *  Assert macro: failure causes a fatal error.\n *\n *  NOTE: since the assert macro doesn't take a heap/context argument, there's\n *  no way to look up a heap/context specific fatal error handler which may have\n *  been given by the application.  Instead, assertion failures always use the\n *  internal default fatal error handler; it can be replaced via duk_config.h\n *  and then applies to all Duktape heaps.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n\n/* The message should be a compile time constant without formatting (less risk);\n * we don't care about assertion text size because they're not used in production\n * builds.\n */\n#define DUK_ASSERT(x)  do { \\\n\tif (!(x)) { \\\n\t\tDUK_FATAL_WITHOUT_CONTEXT(\"assertion failed: \" #x \\\n\t\t\t\" (\" DUK_FILE_MACRO \":\" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) \")\"); \\\n\t} \\\n\t} while (0)\n\n/* Assertion compatible inside a comma expression, evaluates to void. */\n#define DUK_ASSERT_EXPR(x) \\\n\t((void) ((x) ? 0 : (DUK_FATAL_WITHOUT_CONTEXT(\"assertion failed: \" #x \\\n\t\t\t\t\" (\" DUK_FILE_MACRO \":\" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) \")\"), 0)))\n\n#else  /* DUK_USE_ASSERTIONS */\n\n#define DUK_ASSERT(x)  do { /* assertion omitted */ } while (0)\n\n#define DUK_ASSERT_EXPR(x)  ((void) 0)\n\n#endif  /* DUK_USE_ASSERTIONS */\n\n/* this variant is used when an assert would generate a compile warning by\n * being always true (e.g. >= 0 comparison for an unsigned value\n */\n#define DUK_ASSERT_DISABLE(x)  do { /* assertion disabled */ } while (0)\n\n/*\n *  Assertion helpers\n */\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h)  do { \\\n\t\tDUK_ASSERT((h) == NULL || DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) (h)) > 0); \\\n\t} while (0)\n#define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv)  do { \\\n\t\tif ((tv) != NULL && DUK_TVAL_IS_HEAP_ALLOCATED((tv))) { \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(DUK_TVAL_GET_HEAPHDR((tv))) > 0); \\\n\t\t} \\\n\t} while (0)\n#else\n#define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h)  /* no refcount check */\n#define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv)    /* no refcount check */\n#endif\n\n#define DUK_ASSERT_TOP(ctx,n)  DUK_ASSERT((duk_idx_t) duk_get_top((ctx)) == (duk_idx_t) (n))\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_PACKED_TVAL)\n#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval)  do { \\\n\t\tduk_double_union duk__assert_tmp_du; \\\n\t\tduk__assert_tmp_du.d = (dval); \\\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&duk__assert_tmp_du)); \\\n\t} while (0)\n#else\n#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval)  /* nop */\n#endif\n\n#define DUK_ASSERT_VS_SPACE(thr) \\\n\tDUK_ASSERT(thr->valstack_top < thr->valstack_end)\n\n/*\n *  Helper to initialize a memory area (e.g. struct) with garbage when\n *  assertions enabled.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n#define DUK_ASSERT_SET_GARBAGE(ptr,size) do { \\\n\t\tduk_memset_unsafe((void *) (ptr), 0x5a, size); \\\n\t} while (0)\n#else\n#define DUK_ASSERT_SET_GARBAGE(ptr,size) do {} while (0)\n#endif\n\n/*\n *  Helper for valstack space\n *\n *  Caller of DUK_ASSERT_VALSTACK_SPACE() estimates the number of free stack entries\n *  required for its own use, and any child calls which are not (a) Duktape API calls\n *  or (b) Duktape calls which involve extending the valstack (e.g. getter call).\n */\n\n#define DUK_VALSTACK_ASSERT_EXTRA  5  /* this is added to checks to allow for Duktape\n                                       * API calls in addition to function's own use\n                                       */\n#if defined(DUK_USE_ASSERTIONS)\n#define DUK_ASSERT_VALSTACK_SPACE(thr,n)   do { \\\n\t\tDUK_ASSERT((thr) != NULL); \\\n\t\tDUK_ASSERT((thr)->valstack_end - (thr)->valstack_top >= (n) + DUK_VALSTACK_ASSERT_EXTRA); \\\n\t} while (0)\n#else\n#define DUK_ASSERT_VALSTACK_SPACE(thr,n)   /* no valstack space check */\n#endif\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *msg));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error_fmt(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *fmt, ...));\n#else  /* DUK_USE_VERBOSE_ERRORS */\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error(duk_hthread *thr, duk_errcode_t code));\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code, const char *msg, const char *filename, duk_int_t line));\n#else\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code));\n#endif\n\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t rc));\n\n#define DUK_AUGMENT_FLAG_NOBLAME_FILELINE  (1U << 0)  /* if set, don't blame C file/line for .fileName and .lineNumber */\n#define DUK_AUGMENT_FLAG_SKIP_ONE          (1U << 1)  /* if set, skip topmost activation in traceback construction */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_INTERNAL_DECL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *filename, duk_int_t line, duk_small_uint_t flags);\n#endif\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\nDUK_INTERNAL_DECL void duk_err_augment_error_throw(duk_hthread *thr);\n#endif\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name));\n#else\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name));\n#endif\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error_alloc_failed(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range_push_beyond(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_args(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_state(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_trap_result(duk_hthread *thr, const char *filename, duk_int_t linenumber));\n#else  /* DUK_VERBOSE_ERRORS */\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_eval(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_reference(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_syntax(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_uri(duk_hthread *thr));\n#endif /* DUK_VERBOSE_ERRORS */\n\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_longjmp(duk_hthread *thr));\n\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_default_fatal_handler(void *udata, const char *msg));\n\nDUK_INTERNAL_DECL void duk_err_setup_ljstate1(duk_hthread *thr, duk_small_uint_t lj_type, duk_tval *tv_val);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL_DECL void duk_err_check_debugger_integration(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_errcode_t err_code);\n\n#endif  /* DUK_ERROR_H_INCLUDED */\n/* #include duk_unicode.h */\n/*\n *  Unicode helpers\n */\n\n#if !defined(DUK_UNICODE_H_INCLUDED)\n#define DUK_UNICODE_H_INCLUDED\n\n/*\n *  UTF-8 / XUTF-8 / CESU-8 constants\n */\n\n#define DUK_UNICODE_MAX_XUTF8_LENGTH      7   /* up to 36 bit codepoints */\n#define DUK_UNICODE_MAX_XUTF8_BMP_LENGTH  3   /* all codepoints up to U+FFFF */\n#define DUK_UNICODE_MAX_CESU8_LENGTH      6   /* all codepoints up to U+10FFFF */\n#define DUK_UNICODE_MAX_CESU8_BMP_LENGTH  3   /* all codepoints up to U+FFFF */\n\n/*\n *  Useful Unicode codepoints\n *\n *  Integer constants must be signed to avoid unexpected coercions\n *  in comparisons.\n */\n\n#define DUK_UNICODE_CP_ZWNJ                   0x200cL  /* zero-width non-joiner */\n#define DUK_UNICODE_CP_ZWJ                    0x200dL  /* zero-width joiner */\n#define DUK_UNICODE_CP_REPLACEMENT_CHARACTER  0xfffdL  /* http://en.wikipedia.org/wiki/Replacement_character#Replacement_character */\n\n/*\n *  ASCII character constants\n *\n *  C character literals like 'x' have a platform specific value and do\n *  not match ASCII (UTF-8) values on e.g. EBCDIC platforms.  So, use\n *  these (admittedly awkward) constants instead.  These constants must\n *  also have signed values to avoid unexpected coercions in comparisons.\n *\n *  http://en.wikipedia.org/wiki/ASCII\n */\n\n#define DUK_ASC_NUL              0x00\n#define DUK_ASC_SOH              0x01\n#define DUK_ASC_STX              0x02\n#define DUK_ASC_ETX              0x03\n#define DUK_ASC_EOT              0x04\n#define DUK_ASC_ENQ              0x05\n#define DUK_ASC_ACK              0x06\n#define DUK_ASC_BEL              0x07\n#define DUK_ASC_BS               0x08\n#define DUK_ASC_HT               0x09\n#define DUK_ASC_LF               0x0a\n#define DUK_ASC_VT               0x0b\n#define DUK_ASC_FF               0x0c\n#define DUK_ASC_CR               0x0d\n#define DUK_ASC_SO               0x0e\n#define DUK_ASC_SI               0x0f\n#define DUK_ASC_DLE              0x10\n#define DUK_ASC_DC1              0x11\n#define DUK_ASC_DC2              0x12\n#define DUK_ASC_DC3              0x13\n#define DUK_ASC_DC4              0x14\n#define DUK_ASC_NAK              0x15\n#define DUK_ASC_SYN              0x16\n#define DUK_ASC_ETB              0x17\n#define DUK_ASC_CAN              0x18\n#define DUK_ASC_EM               0x19\n#define DUK_ASC_SUB              0x1a\n#define DUK_ASC_ESC              0x1b\n#define DUK_ASC_FS               0x1c\n#define DUK_ASC_GS               0x1d\n#define DUK_ASC_RS               0x1e\n#define DUK_ASC_US               0x1f\n#define DUK_ASC_SPACE            0x20\n#define DUK_ASC_EXCLAMATION      0x21\n#define DUK_ASC_DOUBLEQUOTE      0x22\n#define DUK_ASC_HASH             0x23\n#define DUK_ASC_DOLLAR           0x24\n#define DUK_ASC_PERCENT          0x25\n#define DUK_ASC_AMP              0x26\n#define DUK_ASC_SINGLEQUOTE      0x27\n#define DUK_ASC_LPAREN           0x28\n#define DUK_ASC_RPAREN           0x29\n#define DUK_ASC_STAR             0x2a\n#define DUK_ASC_PLUS             0x2b\n#define DUK_ASC_COMMA            0x2c\n#define DUK_ASC_MINUS            0x2d\n#define DUK_ASC_PERIOD           0x2e\n#define DUK_ASC_SLASH            0x2f\n#define DUK_ASC_0                0x30\n#define DUK_ASC_1                0x31\n#define DUK_ASC_2                0x32\n#define DUK_ASC_3                0x33\n#define DUK_ASC_4                0x34\n#define DUK_ASC_5                0x35\n#define DUK_ASC_6                0x36\n#define DUK_ASC_7                0x37\n#define DUK_ASC_8                0x38\n#define DUK_ASC_9                0x39\n#define DUK_ASC_COLON            0x3a\n#define DUK_ASC_SEMICOLON        0x3b\n#define DUK_ASC_LANGLE           0x3c\n#define DUK_ASC_EQUALS           0x3d\n#define DUK_ASC_RANGLE           0x3e\n#define DUK_ASC_QUESTION         0x3f\n#define DUK_ASC_ATSIGN           0x40\n#define DUK_ASC_UC_A             0x41\n#define DUK_ASC_UC_B             0x42\n#define DUK_ASC_UC_C             0x43\n#define DUK_ASC_UC_D             0x44\n#define DUK_ASC_UC_E             0x45\n#define DUK_ASC_UC_F             0x46\n#define DUK_ASC_UC_G             0x47\n#define DUK_ASC_UC_H             0x48\n#define DUK_ASC_UC_I             0x49\n#define DUK_ASC_UC_J             0x4a\n#define DUK_ASC_UC_K             0x4b\n#define DUK_ASC_UC_L             0x4c\n#define DUK_ASC_UC_M             0x4d\n#define DUK_ASC_UC_N             0x4e\n#define DUK_ASC_UC_O             0x4f\n#define DUK_ASC_UC_P             0x50\n#define DUK_ASC_UC_Q             0x51\n#define DUK_ASC_UC_R             0x52\n#define DUK_ASC_UC_S             0x53\n#define DUK_ASC_UC_T             0x54\n#define DUK_ASC_UC_U             0x55\n#define DUK_ASC_UC_V             0x56\n#define DUK_ASC_UC_W             0x57\n#define DUK_ASC_UC_X             0x58\n#define DUK_ASC_UC_Y             0x59\n#define DUK_ASC_UC_Z             0x5a\n#define DUK_ASC_LBRACKET         0x5b\n#define DUK_ASC_BACKSLASH        0x5c\n#define DUK_ASC_RBRACKET         0x5d\n#define DUK_ASC_CARET            0x5e\n#define DUK_ASC_UNDERSCORE       0x5f\n#define DUK_ASC_GRAVE            0x60\n#define DUK_ASC_LC_A             0x61\n#define DUK_ASC_LC_B             0x62\n#define DUK_ASC_LC_C             0x63\n#define DUK_ASC_LC_D             0x64\n#define DUK_ASC_LC_E             0x65\n#define DUK_ASC_LC_F             0x66\n#define DUK_ASC_LC_G             0x67\n#define DUK_ASC_LC_H             0x68\n#define DUK_ASC_LC_I             0x69\n#define DUK_ASC_LC_J             0x6a\n#define DUK_ASC_LC_K             0x6b\n#define DUK_ASC_LC_L             0x6c\n#define DUK_ASC_LC_M             0x6d\n#define DUK_ASC_LC_N             0x6e\n#define DUK_ASC_LC_O             0x6f\n#define DUK_ASC_LC_P             0x70\n#define DUK_ASC_LC_Q             0x71\n#define DUK_ASC_LC_R             0x72\n#define DUK_ASC_LC_S             0x73\n#define DUK_ASC_LC_T             0x74\n#define DUK_ASC_LC_U             0x75\n#define DUK_ASC_LC_V             0x76\n#define DUK_ASC_LC_W             0x77\n#define DUK_ASC_LC_X             0x78\n#define DUK_ASC_LC_Y             0x79\n#define DUK_ASC_LC_Z             0x7a\n#define DUK_ASC_LCURLY           0x7b\n#define DUK_ASC_PIPE             0x7c\n#define DUK_ASC_RCURLY           0x7d\n#define DUK_ASC_TILDE            0x7e\n#define DUK_ASC_DEL              0x7f\n\n/*\n *  Miscellaneous\n */\n\n/* Uppercase A is 0x41, lowercase a is 0x61; OR 0x20 to convert uppercase\n * to lowercase.\n */\n#define DUK_LOWERCASE_CHAR_ASCII(x)  ((x) | 0x20)\n\n/*\n *  Unicode tables\n */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_ids_noa[1116];\n#else\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_ids_noabmp[625];\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_ids_m_let_noa[42];\n#else\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_ids_m_let_noabmp[24];\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_idp_m_ids_noa[576];\n#else\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_idp_m_ids_noabmp[358];\n#endif\n\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_caseconv_uc[1411];\nextern const duk_uint8_t duk_unicode_caseconv_lc[706];\n\n#if defined(DUK_USE_REGEXP_CANON_WORKAROUND)\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\nextern const duk_uint16_t duk_unicode_re_canon_lookup[65536];\n#endif\n\n#if defined(DUK_USE_REGEXP_CANON_BITMAP)\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\n#define DUK_CANON_BITMAP_BLKSIZE                                      32\n#define DUK_CANON_BITMAP_BLKSHIFT                                     5\n#define DUK_CANON_BITMAP_BLKMASK                                      31\nextern const duk_uint8_t duk_unicode_re_canon_bitmap[256];\n#endif\n\n/*\n *  Extern\n */\n\n/* duk_unicode_support.c */\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_unicode_xutf8_markers[7];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_digit[2];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_white[22];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_wordchar[8];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_not_digit[4];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_not_white[24];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_not_wordchar[10];\nDUK_INTERNAL_DECL const duk_int8_t duk_is_idchar_tab[128];\n#endif  /* !DUK_SINGLE_FILE */\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_get_xutf8_length(duk_ucodepoint_t cp);\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_get_cesu8_length(duk_ucodepoint_t cp);\n#endif\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_encode_xutf8(duk_ucodepoint_t cp, duk_uint8_t *out);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_encode_cesu8(duk_ucodepoint_t cp, duk_uint8_t *out);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_decode_xutf8(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_ucodepoint_t *out_cp);\nDUK_INTERNAL_DECL duk_ucodepoint_t duk_unicode_decode_xutf8_checked(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end);\nDUK_INTERNAL_DECL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_whitespace(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_line_terminator(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_identifier_start(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_identifier_part(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_letter(duk_codepoint_t cp);\nDUK_INTERNAL_DECL void duk_unicode_case_convert_string(duk_hthread *thr, duk_bool_t uppercase);\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL_DECL duk_codepoint_t duk_unicode_re_canonicalize_char(duk_hthread *thr, duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_re_is_wordchar(duk_codepoint_t cp);\n#endif\n\n#endif  /* DUK_UNICODE_H_INCLUDED */\n/* #include duk_json.h */\n/*\n *  Defines for JSON, especially duk_bi_json.c.\n */\n\n#if !defined(DUK_JSON_H_INCLUDED)\n#define DUK_JSON_H_INCLUDED\n\n/* Encoding/decoding flags */\n#define DUK_JSON_FLAG_ASCII_ONLY              (1U << 0)  /* escape any non-ASCII characters */\n#define DUK_JSON_FLAG_AVOID_KEY_QUOTES        (1U << 1)  /* avoid key quotes when key is an ASCII Identifier */\n#define DUK_JSON_FLAG_EXT_CUSTOM              (1U << 2)  /* extended types: custom encoding */\n#define DUK_JSON_FLAG_EXT_COMPATIBLE          (1U << 3)  /* extended types: compatible encoding */\n\n/* How much stack to require on entry to object/array encode */\n#define DUK_JSON_ENC_REQSTACK                 32\n\n/* How much stack to require on entry to object/array decode */\n#define DUK_JSON_DEC_REQSTACK                 32\n\n/* How large a loop detection stack to use */\n#define DUK_JSON_ENC_LOOPARRAY                64\n\n/* Encoding state.  Heap object references are all borrowed. */\ntypedef struct {\n\tduk_hthread *thr;\n\tduk_bufwriter_ctx bw;        /* output bufwriter */\n\tduk_hobject *h_replacer;     /* replacer function */\n\tduk_hstring *h_gap;          /* gap (if empty string, NULL) */\n\tduk_idx_t idx_proplist;      /* explicit PropertyList */\n\tduk_idx_t idx_loop;          /* valstack index of loop detection object */\n\tduk_small_uint_t flags;\n\tduk_small_uint_t flag_ascii_only;\n\tduk_small_uint_t flag_avoid_key_quotes;\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tduk_small_uint_t flag_ext_custom;\n\tduk_small_uint_t flag_ext_compatible;\n\tduk_small_uint_t flag_ext_custom_or_compatible;\n#endif\n\tduk_uint_t recursion_depth;\n\tduk_uint_t recursion_limit;\n\tduk_uint_t mask_for_undefined;      /* type bit mask: types which certainly produce 'undefined' */\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tduk_small_uint_t stridx_custom_undefined;\n\tduk_small_uint_t stridx_custom_nan;\n\tduk_small_uint_t stridx_custom_neginf;\n\tduk_small_uint_t stridx_custom_posinf;\n\tduk_small_uint_t stridx_custom_function;\n#endif\n\tduk_hobject *visiting[DUK_JSON_ENC_LOOPARRAY];  /* indexed by recursion_depth */\n} duk_json_enc_ctx;\n\ntypedef struct {\n\tduk_hthread *thr;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p_end;\n\tduk_idx_t idx_reviver;\n\tduk_small_uint_t flags;\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tduk_small_uint_t flag_ext_custom;\n\tduk_small_uint_t flag_ext_compatible;\n\tduk_small_uint_t flag_ext_custom_or_compatible;\n#endif\n\tduk_int_t recursion_depth;\n\tduk_int_t recursion_limit;\n} duk_json_dec_ctx;\n\n#endif  /* DUK_JSON_H_INCLUDED */\n/* #include duk_js.h */\n/*\n *  ECMAScript execution, support primitives.\n */\n\n#if !defined(DUK_JS_H_INCLUDED)\n#define DUK_JS_H_INCLUDED\n\n/* Flags for call handling.  Lowest flags must match bytecode DUK_BC_CALL_FLAG_xxx 1:1. */\n#define DUK_CALL_FLAG_TAILCALL                 (1U << 0)  /* setup for a tail call */\n#define DUK_CALL_FLAG_CONSTRUCT                (1U << 1)  /* constructor call (i.e. called as 'new Foo()') */\n#define DUK_CALL_FLAG_CALLED_AS_EVAL           (1U << 2)  /* call was made using the identifier 'eval' */\n#define DUK_CALL_FLAG_ALLOW_ECMATOECMA         (1U << 3)  /* ecma-to-ecma call with executor reuse is possible */\n#define DUK_CALL_FLAG_DIRECT_EVAL              (1U << 4)  /* call is a direct eval call */\n#define DUK_CALL_FLAG_CONSTRUCT_PROXY          (1U << 5)  /* handled via 'construct' proxy trap, check return value invariant(s) */\n#define DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED (1U << 6)  /* prototype of 'default instance' updated, temporary flag in call handling */\n\n/* Flags for duk_js_equals_helper(). */\n#define DUK_EQUALS_FLAG_SAMEVALUE            (1U << 0)  /* use SameValue instead of non-strict equality */\n#define DUK_EQUALS_FLAG_STRICT               (1U << 1)  /* use strict equality instead of non-strict equality */\n\n/* Flags for duk_js_compare_helper(). */\n#define DUK_COMPARE_FLAG_NEGATE              (1U << 0)  /* negate result */\n#define DUK_COMPARE_FLAG_EVAL_LEFT_FIRST     (1U << 1)  /* eval left argument first */\n\n/* conversions, coercions, comparison, etc */\nDUK_INTERNAL_DECL duk_bool_t duk_js_toboolean(duk_tval *tv);\nDUK_INTERNAL_DECL duk_double_t duk_js_tonumber(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_double_t duk_js_tointeger_number(duk_double_t x);\nDUK_INTERNAL_DECL duk_double_t duk_js_tointeger(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_uint32_t duk_js_touint32(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_int32_t duk_js_toint32(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_uint16_t duk_js_touint16(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_string(const duk_uint8_t *str, duk_uint32_t blen);\n#if !defined(DUK_USE_HSTRING_ARRIDX)\nDUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_hstring_fast_known(duk_hstring *h);\nDUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_hstring_fast(duk_hstring *h);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_small_int_t duk_js_data_compare(const duk_uint8_t *buf1, const duk_uint8_t *buf2, duk_size_t len1, duk_size_t len2);\nDUK_INTERNAL_DECL duk_small_int_t duk_js_string_compare(duk_hstring *h1, duk_hstring *h2);\n#if 0  /* unused */\nDUK_INTERNAL_DECL duk_small_int_t duk_js_buffer_compare(duk_heap *heap, duk_hbuffer *h1, duk_hbuffer *h2);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL_DECL duk_bool_t duk_js_instanceof_ordinary(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_in(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);\nDUK_INTERNAL_DECL duk_small_uint_t duk_js_typeof_stridx(duk_tval *tv_x);\n\n/* arithmetic */\nDUK_INTERNAL_DECL double duk_js_arith_pow(double x, double y);\nDUK_INTERNAL_DECL double duk_js_arith_mod(double x, double y);\n\n#define duk_js_equals(thr,tv_x,tv_y) \\\n\tduk_js_equals_helper((thr), (tv_x), (tv_y), 0)\n#define duk_js_strict_equals(tv_x,tv_y) \\\n\tduk_js_equals_helper(NULL, (tv_x), (tv_y), DUK_EQUALS_FLAG_STRICT)\n#define duk_js_samevalue(tv_x,tv_y) \\\n\tduk_js_equals_helper(NULL, (tv_x), (tv_y), DUK_EQUALS_FLAG_SAMEVALUE)\n\n/* E5 Sections 11.8.1, 11.8.5; x < y */\n#define duk_js_lessthan(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_x), (tv_Y), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST)\n\n/* E5 Sections 11.8.2, 11.8.5; x > y  -->  y < x */\n#define duk_js_greaterthan(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_y), (tv_x), 0)\n\n/* E5 Sections 11.8.3, 11.8.5; x <= y  -->  not (x > y)  -->  not (y < x) */\n#define duk_js_lessthanorequal(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_y), (tv_x), DUK_COMPARE_FLAG_NEGATE)\n\n/* E5 Sections 11.8.4, 11.8.5; x >= y  -->  not (x < y) */\n#define duk_js_greaterthanorequal(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_x), (tv_y), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST | DUK_COMPARE_FLAG_NEGATE)\n\n/* identifiers and environment handling */\n#if 0  /*unused*/\nDUK_INTERNAL duk_bool_t duk_js_hasvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_getvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL duk_bool_t duk_js_getvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL void duk_js_putvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name, duk_tval *val, duk_bool_t strict);\nDUK_INTERNAL_DECL void duk_js_putvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_tval *val, duk_bool_t strict);\n#if 0  /*unused*/\nDUK_INTERNAL_DECL duk_bool_t duk_js_delvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_delvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name);\nDUK_INTERNAL_DECL duk_bool_t duk_js_declvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_tval *val, duk_small_uint_t prop_flags, duk_bool_t is_func_decl);\nDUK_INTERNAL_DECL void duk_js_init_activation_environment_records_delayed(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject *env);\nDUK_INTERNAL_DECL duk_hobject *duk_create_activation_environment_record(duk_hthread *thr, duk_hobject *func, duk_size_t bottom_byteoff);\nDUK_INTERNAL_DECL void duk_js_push_closure(duk_hthread *thr,\n                                           duk_hcompfunc *fun_temp,\n                                           duk_hobject *outer_var_env,\n                                           duk_hobject *outer_lex_env,\n                                           duk_bool_t add_auto_proto);\n\n/* call handling */\nDUK_INTERNAL_DECL void duk_native_stack_check(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_int_t duk_handle_call_unprotected(duk_hthread *thr, duk_idx_t idx_func, duk_small_uint_t call_flags);\nDUK_INTERNAL_DECL duk_int_t duk_handle_call_unprotected_nargs(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags);\nDUK_INTERNAL_DECL duk_int_t duk_handle_safe_call(duk_hthread *thr, duk_safe_call_function func, void *udata, duk_idx_t num_stack_args, duk_idx_t num_stack_res);\nDUK_INTERNAL_DECL void duk_call_construct_postprocess(duk_hthread *thr, duk_small_uint_t proxy_invariant);\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_INTERNAL_DECL void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_base, duk_tval *tv_key);\n#endif\n\n/* bytecode execution */\nDUK_INTERNAL_DECL void duk_js_execute_bytecode(duk_hthread *exec_thr);\n\n#endif  /* DUK_JS_H_INCLUDED */\n/* #include duk_numconv.h */\n/*\n *  Number-to-string conversion.  The semantics of these is very tightly\n *  bound with the ECMAScript semantics required for call sites.\n */\n\n#if !defined(DUK_NUMCONV_H_INCLUDED)\n#define DUK_NUMCONV_H_INCLUDED\n\n/* Output a specified number of digits instead of using the shortest\n * form.  Used for toPrecision() and toFixed().\n */\n#define DUK_N2S_FLAG_FIXED_FORMAT         (1U << 0)\n\n/* Force exponential format.  Used for toExponential(). */\n#define DUK_N2S_FLAG_FORCE_EXP            (1U << 1)\n\n/* If number would need zero padding (for whole number part), use\n * exponential format instead.  E.g. if input number is 12300, 3\n * digits are generated (\"123\"), output \"1.23e+4\" instead of \"12300\".\n * Used for toPrecision().\n */\n#define DUK_N2S_FLAG_NO_ZERO_PAD          (1U << 2)\n\n/* Digit count indicates number of fractions (i.e. an absolute\n * digit index instead of a relative one).  Used together with\n * DUK_N2S_FLAG_FIXED_FORMAT for toFixed().\n */\n#define DUK_N2S_FLAG_FRACTION_DIGITS      (1U << 3)\n\n/*\n *  String-to-number conversion\n */\n\n/* Maximum exponent value when parsing numbers.  This is not strictly\n * compliant as there should be no upper limit, but as we parse the\n * exponent without a bigint, impose some limit.  The limit should be\n * small enough that multiplying it (or limit-1 to be precise) won't\n * overflow signed 32-bit integer range.  Exponent is only parsed with\n * radix 10, but with maximum radix (36) a safe limit is:\n * (10000000*36).toString(16) -> '15752a00'\n */\n#define DUK_S2N_MAX_EXPONENT              10000000L\n\n/* Trim white space (= allow leading and trailing whitespace) */\n#define DUK_S2N_FLAG_TRIM_WHITE           (1U << 0)\n\n/* Allow exponent */\n#define DUK_S2N_FLAG_ALLOW_EXP            (1U << 1)\n\n/* Allow trailing garbage (e.g. treat \"123foo\" as \"123) */\n#define DUK_S2N_FLAG_ALLOW_GARBAGE        (1U << 2)\n\n/* Allow leading plus sign */\n#define DUK_S2N_FLAG_ALLOW_PLUS           (1U << 3)\n\n/* Allow leading minus sign */\n#define DUK_S2N_FLAG_ALLOW_MINUS          (1U << 4)\n\n/* Allow 'Infinity' */\n#define DUK_S2N_FLAG_ALLOW_INF            (1U << 5)\n\n/* Allow fraction part */\n#define DUK_S2N_FLAG_ALLOW_FRAC           (1U << 6)\n\n/* Allow naked fraction (e.g. \".123\") */\n#define DUK_S2N_FLAG_ALLOW_NAKED_FRAC     (1U << 7)\n\n/* Allow empty fraction (e.g. \"123.\") */\n#define DUK_S2N_FLAG_ALLOW_EMPTY_FRAC     (1U << 8)\n\n/* Allow empty string to be interpreted as 0 */\n#define DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO  (1U << 9)\n\n/* Allow leading zeroes (e.g. \"0123\" -> \"123\") */\n#define DUK_S2N_FLAG_ALLOW_LEADING_ZERO   (1U << 10)\n\n/* Allow automatic detection of hex base (\"0x\" or \"0X\" prefix),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT   (1U << 11)\n\n/* Allow automatic detection of legacy octal base (\"0n\"),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_LEGACY_OCT_INT   (1U << 12)\n\n/* Allow automatic detection of ES2015 octal base (\"0o123\"),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT   (1U << 13)\n\n/* Allow automatic detection of ES2015 binary base (\"0b10001\"),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT   (1U << 14)\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags);\nDUK_INTERNAL_DECL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags);\n\n#endif  /* DUK_NUMCONV_H_INCLUDED */\n/* #include duk_bi_protos.h */\n/*\n *  Prototypes for built-in functions not automatically covered by the\n *  header declarations emitted by genbuiltins.py.\n */\n\n#if !defined(DUK_BUILTIN_PROTOS_H_INCLUDED)\n#define DUK_BUILTIN_PROTOS_H_INCLUDED\n\n/* Buffer size needed for ISO 8601 formatting.\n * Accurate value is 32 + 1 for NUL termination:\n *   >>> len('+123456-01-23T12:34:56.123+12:34')\n *   32\n * Include additional space to be safe.\n */\n#define  DUK_BI_DATE_ISO8601_BUFSIZE  40\n\n/* Helpers exposed for internal use */\nDUK_INTERNAL_DECL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts, duk_double_t *dparts, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_timeval_from_dparts(duk_double_t *dparts, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_is_leap_year(duk_int_t year);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_timeval_in_valid_range(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_year_in_valid_range(duk_double_t year);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_timeval_in_leeway_range(duk_double_t x);\n/* Built-in providers */\n#if defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_gettimeofday(void);\n#endif\n#if defined(DUK_USE_DATE_NOW_TIME)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_time(void);\n#endif\n#if defined(DUK_USE_DATE_NOW_WINDOWS)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows(void);\n#endif\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows_subms(void);\n#endif\n#if defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S) || defined(DUK_USE_DATE_TZO_GMTIME)\nDUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d);\n#endif\n#if defined(DUK_USE_DATE_TZO_WINDOWS)\nDUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d);\n#endif\n#if defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST)\nDUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_t d);\n#endif\n#if defined(DUK_USE_DATE_PRS_STRPTIME)\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_strptime(duk_hthread *thr, const char *str);\n#endif\n#if defined(DUK_USE_DATE_PRS_GETDATE)\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_getdate(duk_hthread *thr, const char *str);\n#endif\n#if defined(DUK_USE_DATE_FMT_STRFTIME)\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags);\n#endif\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_monotonic_time_clock_gettime(void);\n#endif\n#if defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_monotonic_time_windows_qpc(void);\n#endif\n\nDUK_INTERNAL_DECL\nvoid duk_bi_json_parse_helper(duk_hthread *thr,\n                              duk_idx_t idx_value,\n                              duk_idx_t idx_reviver,\n                              duk_small_uint_t flags);\nDUK_INTERNAL_DECL\nvoid duk_bi_json_stringify_helper(duk_hthread *thr,\n                                  duk_idx_t idx_value,\n                                  duk_idx_t idx_replacer,\n                                  duk_idx_t idx_space,\n                                  duk_small_uint_t flags);\n\nDUK_INTERNAL_DECL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_hthread *thr);\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL_DECL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h_proxy_target, duk_uint_t flags);\n#endif\n\n#endif  /* DUK_BUILTIN_PROTOS_H_INCLUDED */\n/* #include duk_selftest.h */\n/*\n *  Selftest code\n */\n\n#if !defined(DUK_SELFTEST_H_INCLUDED)\n#define DUK_SELFTEST_H_INCLUDED\n\n#if defined(DUK_USE_SELF_TESTS)\nDUK_INTERNAL_DECL duk_uint_t duk_selftest_run_tests(duk_alloc_function alloc_func,\n                                                    duk_realloc_function realloc_func,\n                                                    duk_free_function free_func,\n                                                    void *udata);\n#endif\n\n#endif  /* DUK_SELFTEST_H_INCLUDED */\n\n#endif  /* DUK_INTERNAL_H_INCLUDED */\n\n#if defined(DUK_USE_COMPUTED_NAN)\nDUK_INTERNAL double duk_computed_nan;\n#endif\n\n#if defined(DUK_USE_COMPUTED_INFINITY)\nDUK_INTERNAL double duk_computed_infinity;\n#endif\n\n#if defined(DUK_USE_REPL_FPCLASSIFY)\nDUK_INTERNAL int duk_repl_fpclassify(double x) {\n\tduk_double_union u;\n\tduk_uint_fast16_t expt;\n\tduk_small_int_t mzero;\n\n\tu.d = x;\n\texpt = (duk_uint_fast16_t) (u.us[DUK_DBL_IDX_US0] & 0x7ff0UL);\n\tif (expt > 0x0000UL && expt < 0x7ff0UL) {\n\t\t/* expt values [0x001,0x7fe] = normal */\n\t\treturn DUK_FP_NORMAL;\n\t}\n\n\tmzero = (u.ui[DUK_DBL_IDX_UI1] == 0 && (u.ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) == 0);\n\tif (expt == 0x0000UL) {\n\t\t/* expt 0x000 is zero/subnormal */\n\t\tif (mzero) {\n\t\t\treturn DUK_FP_ZERO;\n\t\t} else {\n\t\t\treturn DUK_FP_SUBNORMAL;\n\t\t}\n\t} else {\n\t\t/* expt 0xfff is infinite/nan */\n\t\tif (mzero) {\n\t\t\treturn DUK_FP_INFINITE;\n\t\t} else {\n\t\t\treturn DUK_FP_NAN;\n\t\t}\n\t}\n}\n#endif\n\n#if defined(DUK_USE_REPL_SIGNBIT)\nDUK_INTERNAL int duk_repl_signbit(double x) {\n\tduk_double_union u;\n\tu.d = x;\n\treturn (int) (u.uc[DUK_DBL_IDX_UC0] & 0x80UL);\n}\n#endif\n\n#if defined(DUK_USE_REPL_ISFINITE)\nDUK_INTERNAL int duk_repl_isfinite(double x) {\n\tint c = DUK_FPCLASSIFY(x);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\treturn 0;\n\t} else {\n\t\treturn 1;\n\t}\n}\n#endif\n\n#if defined(DUK_USE_REPL_ISNAN)\nDUK_INTERNAL int duk_repl_isnan(double x) {\n\tint c = DUK_FPCLASSIFY(x);\n\treturn (c == DUK_FP_NAN);\n}\n#endif\n\n#if defined(DUK_USE_REPL_ISINF)\nDUK_INTERNAL int duk_repl_isinf(double x) {\n\tint c = DUK_FPCLASSIFY(x);\n\treturn (c == DUK_FP_INFINITE);\n}\n#endif\n/*\n *  Debugging macro calls.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_DEBUG)\n\n/*\n *  Debugging enabled\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdarg.h>\n\n#if !defined(DUK_USE_DEBUG_WRITE)\n#error debugging enabled (DUK_USE_DEBUG) but DUK_USE_DEBUG_WRITE not defined\n#endif\n\n#define DUK__DEBUG_BUFSIZE  DUK_USE_DEBUG_BUFSIZE\n\n#if defined(DUK_USE_VARIADIC_MACROS)\n\nDUK_INTERNAL void duk_debug_log(duk_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...) {\n\tva_list ap;\n\tlong arg_level;\n\tconst char *arg_file;\n\tlong arg_line;\n\tconst char *arg_func;\n\tconst char *arg_msg;\n\tchar buf[DUK__DEBUG_BUFSIZE];\n\n\tva_start(ap, fmt);\n\n\tduk_memzero((void *) buf, (size_t) DUK__DEBUG_BUFSIZE);\n\tduk_debug_vsnprintf(buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap);\n\n\targ_level = (long) level;\n\targ_file = (const char *) file;\n\targ_line = (long) line;\n\targ_func = (const char *) func;\n\targ_msg = (const char *) buf;\n\tDUK_USE_DEBUG_WRITE(arg_level, arg_file, arg_line, arg_func, arg_msg);\n\n\tva_end(ap);\n}\n\n#else  /* DUK_USE_VARIADIC_MACROS */\n\nDUK_INTERNAL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL duk_int_t duk_debug_line_stash;\nDUK_INTERNAL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL duk_int_t duk_debug_level_stash;\n\nDUK_INTERNAL void duk_debug_log(const char *fmt, ...) {\n\tva_list ap;\n\tlong arg_level;\n\tconst char *arg_file;\n\tlong arg_line;\n\tconst char *arg_func;\n\tconst char *arg_msg;\n\tchar buf[DUK__DEBUG_BUFSIZE];\n\n\tva_start(ap, fmt);\n\n\tduk_memzero((void *) buf, (size_t) DUK__DEBUG_BUFSIZE);\n\tduk_debug_vsnprintf(buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap);\n\n\targ_level = (long) duk_debug_level_stash;\n\targ_file = (const char *) duk_debug_file_stash;\n\targ_line = (long) duk_debug_line_stash;\n\targ_func = (const char *) duk_debug_func_stash;\n\targ_msg = (const char *) buf;\n\tDUK_USE_DEBUG_WRITE(arg_level, arg_file, arg_line, arg_func, arg_msg);\n\n\tva_end(ap);\n}\n\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n#else  /* DUK_USE_DEBUG */\n\n/*\n *  Debugging disabled\n */\n\n#endif  /* DUK_USE_DEBUG */\n\n/* automatic undefs */\n#undef DUK__DEBUG_BUFSIZE\n/*\n *  Automatically generated by genbuiltins.py, do not edit!\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ASSERTIONS)\n#define DUK__REFCINIT(refc) 0 /*h_assert_refcount*/, (refc) /*actual*/\n#else\n#define DUK__REFCINIT(refc) (refc) /*actual*/\n#endif\n\n#if defined(DUK_USE_ROM_STRINGS)\n#error ROM support not enabled, rerun configure.py with --rom-support\n#else  /* DUK_USE_ROM_STRINGS */\nDUK_INTERNAL const duk_uint8_t duk_strings_data[967] = {\n79,40,209,144,168,105,6,78,54,139,89,185,44,48,46,90,120,8,154,140,35,103,\n35,113,193,73,5,52,112,180,104,166,135,52,188,4,98,12,27,146,156,80,211,31,\n129,115,150,64,52,220,109,24,18,68,156,24,38,67,114,36,55,9,119,151,132,\n140,93,18,113,128,153,201,212,201,205,2,248,8,196,24,224,104,82,146,40,224,\n193,48,114,168,37,147,196,54,123,28,4,98,12,43,148,67,103,177,192,70,32,\n196,121,68,54,123,28,18,192,199,144,124,4,98,12,43,136,108,244,117,184,8,\n196,24,95,40,134,207,71,91,128,140,65,133,113,13,158,158,151,1,24,131,11,\n229,16,217,233,233,112,17,136,48,206,21,110,4,244,244,184,8,196,24,103,10,\n183,2,122,218,156,4,98,12,24,203,112,64,179,113,193,79,8,218,155,131,32,\n184,70,212,220,13,10,82,68,252,123,144,217,146,38,228,207,18,0,100,37,64,\n178,212,11,161,17,104,162,96,10,200,193,57,165,65,169,16,5,100,81,27,70,18,\n32,10,200,68,185,13,116,221,197,184,64,89,57,41,197,13,49,234,5,208,156,\n113,87,55,118,147,20,187,56,161,166,92,221,212,73,210,236,226,134,153,115,\n119,76,201,203,179,138,26,99,73,212,136,136,164,25,174,137,56,32,72,137,\n101,23,52,45,13,34,86,9,79,136,104,201,114,149,96,52,138,134,140,151,75,\n226,233,186,120,121,22,39,54,83,141,5,55,68,236,36,164,3,16,225,115,150,64,\n52,205,163,2,72,154,83,138,26,99,75,12,11,150,103,5,36,20,211,70,140,133,\n67,72,49,241,160,227,81,196,52,168,106,39,132,252,183,136,105,80,212,79,2,\n249,110,128,126,88,95,133,109,237,237,237,151,235,127,46,249,119,203,190,\n186,206,33,181,2,208,61,190,12,19,34,65,19,81,132,108,228,97,1,107,33,12,\n32,45,100,137,64,247,175,9,19,155,41,198,130,155,134,69,146,100,227,226,\n231,146,51,192,204,73,140,224,145,221,102,241,68,196,169,248,30,75,12,11,\n151,242,233,187,143,138,24,137,162,164,255,253,63,3,201,97,129,114,254,92,\n112,75,136,108,166,6,136,159,255,167,224,121,44,48,46,95,203,166,238,74,\n113,67,77,201,128,223,255,223,224,121,44,48,46,95,203,145,46,9,205,16,39,\n201,62,36,0,192,21,147,255,238,145,39,199,197,211,116,240,242,113,197,78,\n214,211,226,233,187,107,105,19,119,37,56,161,166,52,221,212,201,205,36,240,\n242,16,96,152,12,178,52,211,56,228,73,150,83,0,148,39,137,75,67,73,198,209,\n129,36,85,185,201,196,2,32,193,48,17,160,97,16,84,44,156,104,24,67,189,200,\n108,201,19,238,114,96,137,137,50,238,113,164,188,211,185,192,226,100,19,\n134,68,110,112,174,139,0,185,31,115,149,4,88,7,159,115,146,117,34,34,35,\n115,143,22,146,208,210,19,115,140,3,207,185,202,130,36,109,85,185,194,161,\n160,90,50,72,155,115,149,2,232,67,137,204,122,22,66,161,175,164,210,72,199,\n130,137,1,50,32,145,143,38,120,186,195,35,106,51,146,230,8,36,77,109,65,38,\n226,72,159,191,189,181,70,140,133,222,249,212,227,66,125,245,187,251,219,\n77,3,119,190,117,56,208,159,125,110,254,246,210,26,93,239,157,78,52,39,223,\n93,191,189,180,212,52,187,223,58,156,104,79,190,187,127,123,104,180,104,\n183,190,117,56,208,159,125,102,254,209,104,209,124,234,113,161,62,250,80,\n196,128,81,4,9,16,162,4,196,116,9,205,154,27,66,32,100,13,12,98,68,227,33,\n65,69,204,195,34,201,50,8,110,33,23,34,28,168,104,22,188,12,174,138,11,70,\n138,104,115,68,130,137,13,82,27,41,129,162,35,138,54,146,198,137,39,72,180,\n210,178,38,35,146,103,68,139,51,197,214,28,227,131,79,15,35,138,58,130,37,\n19,155,41,146,174,64,203,99,161,100,37,145,51,148,75,4,164,66,54,140,49,46,\n247,70,103,37,230,70,142,70,67,30,232,204,178,163,201,18,54,139,89,39,26,\n16,165,2,228,69,33,143,89,24,70,206,73,67,102,72,148,2,32,214,73,157,224,\n18,128,98,29,241,69,65,50,37,241,116,200,41,144,102,125,2,180,8,210,152,38,\n129,23,8,34,198,\n};\n#endif  /* DUK_USE_ROM_STRINGS */\n\n#if defined(DUK_USE_ROM_OBJECTS)\n#error ROM support not enabled, rerun configure.py with --rom-support\n#else  /* DUK_USE_ROM_OBJECTS */\n/* native functions: 183 */\nDUK_INTERNAL const duk_c_function duk_bi_native_functions[183] = {\n\tNULL,\n\tduk_bi_array_constructor,\n\tduk_bi_array_constructor_is_array,\n\tduk_bi_array_prototype_concat,\n\tduk_bi_array_prototype_indexof_shared,\n\tduk_bi_array_prototype_iter_shared,\n\tduk_bi_array_prototype_join_shared,\n\tduk_bi_array_prototype_pop,\n\tduk_bi_array_prototype_push,\n\tduk_bi_array_prototype_reduce_shared,\n\tduk_bi_array_prototype_reverse,\n\tduk_bi_array_prototype_shift,\n\tduk_bi_array_prototype_slice,\n\tduk_bi_array_prototype_sort,\n\tduk_bi_array_prototype_splice,\n\tduk_bi_array_prototype_to_string,\n\tduk_bi_array_prototype_unshift,\n\tduk_bi_arraybuffer_constructor,\n\tduk_bi_arraybuffer_isview,\n\tduk_bi_boolean_constructor,\n\tduk_bi_boolean_prototype_tostring_shared,\n\tduk_bi_buffer_compare_shared,\n\tduk_bi_buffer_readfield,\n\tduk_bi_buffer_slice_shared,\n\tduk_bi_buffer_writefield,\n\tduk_bi_dataview_constructor,\n\tduk_bi_date_constructor,\n\tduk_bi_date_constructor_now,\n\tduk_bi_date_constructor_parse,\n\tduk_bi_date_constructor_utc,\n\tduk_bi_date_prototype_get_shared,\n\tduk_bi_date_prototype_get_timezone_offset,\n\tduk_bi_date_prototype_set_shared,\n\tduk_bi_date_prototype_set_time,\n\tduk_bi_date_prototype_to_json,\n\tduk_bi_date_prototype_toprimitive,\n\tduk_bi_date_prototype_tostring_shared,\n\tduk_bi_date_prototype_value_of,\n\tduk_bi_duktape_object_act,\n\tduk_bi_duktape_object_compact,\n\tduk_bi_duktape_object_dec,\n\tduk_bi_duktape_object_enc,\n\tduk_bi_duktape_object_fin,\n\tduk_bi_duktape_object_gc,\n\tduk_bi_duktape_object_info,\n\tduk_bi_error_constructor_shared,\n\tduk_bi_error_prototype_filename_getter,\n\tduk_bi_error_prototype_filename_setter,\n\tduk_bi_error_prototype_linenumber_getter,\n\tduk_bi_error_prototype_linenumber_setter,\n\tduk_bi_error_prototype_stack_getter,\n\tduk_bi_error_prototype_stack_setter,\n\tduk_bi_error_prototype_to_string,\n\tduk_bi_function_constructor,\n\tduk_bi_function_prototype,\n\tduk_bi_function_prototype_apply,\n\tduk_bi_function_prototype_bind,\n\tduk_bi_function_prototype_call,\n\tduk_bi_function_prototype_hasinstance,\n\tduk_bi_function_prototype_to_string,\n\tduk_bi_global_object_decode_uri,\n\tduk_bi_global_object_decode_uri_component,\n\tduk_bi_global_object_encode_uri,\n\tduk_bi_global_object_encode_uri_component,\n\tduk_bi_global_object_escape,\n\tduk_bi_global_object_eval,\n\tduk_bi_global_object_is_finite,\n\tduk_bi_global_object_is_nan,\n\tduk_bi_global_object_parse_float,\n\tduk_bi_global_object_parse_int,\n\tduk_bi_global_object_unescape,\n\tduk_bi_json_object_parse,\n\tduk_bi_json_object_stringify,\n\tduk_bi_math_object_clz32,\n\tduk_bi_math_object_hypot,\n\tduk_bi_math_object_imul,\n\tduk_bi_math_object_max,\n\tduk_bi_math_object_min,\n\tduk_bi_math_object_onearg_shared,\n\tduk_bi_math_object_random,\n\tduk_bi_math_object_sign,\n\tduk_bi_math_object_twoarg_shared,\n\tduk_bi_native_function_length,\n\tduk_bi_native_function_name,\n\tduk_bi_nodejs_buffer_byte_length,\n\tduk_bi_nodejs_buffer_concat,\n\tduk_bi_nodejs_buffer_constructor,\n\tduk_bi_nodejs_buffer_copy,\n\tduk_bi_nodejs_buffer_fill,\n\tduk_bi_nodejs_buffer_is_buffer,\n\tduk_bi_nodejs_buffer_is_encoding,\n\tduk_bi_nodejs_buffer_tojson,\n\tduk_bi_nodejs_buffer_tostring,\n\tduk_bi_nodejs_buffer_write,\n\tduk_bi_number_check_shared,\n\tduk_bi_number_constructor,\n\tduk_bi_number_prototype_to_exponential,\n\tduk_bi_number_prototype_to_fixed,\n\tduk_bi_number_prototype_to_locale_string,\n\tduk_bi_number_prototype_to_precision,\n\tduk_bi_number_prototype_to_string,\n\tduk_bi_number_prototype_value_of,\n\tduk_bi_object_constructor,\n\tduk_bi_object_constructor_assign,\n\tduk_bi_object_constructor_create,\n\tduk_bi_object_constructor_define_properties,\n\tduk_bi_object_constructor_define_property,\n\tduk_bi_object_constructor_get_own_property_descriptor,\n\tduk_bi_object_constructor_is,\n\tduk_bi_object_constructor_is_extensible,\n\tduk_bi_object_constructor_is_sealed_frozen_shared,\n\tduk_bi_object_constructor_keys_shared,\n\tduk_bi_object_constructor_prevent_extensions,\n\tduk_bi_object_constructor_seal_freeze_shared,\n\tduk_bi_object_getprototype_shared,\n\tduk_bi_object_prototype_defineaccessor,\n\tduk_bi_object_prototype_has_own_property,\n\tduk_bi_object_prototype_is_prototype_of,\n\tduk_bi_object_prototype_lookupaccessor,\n\tduk_bi_object_prototype_property_is_enumerable,\n\tduk_bi_object_prototype_to_locale_string,\n\tduk_bi_object_prototype_to_string,\n\tduk_bi_object_prototype_value_of,\n\tduk_bi_object_setprototype_shared,\n\tduk_bi_performance_now,\n\tduk_bi_pointer_constructor,\n\tduk_bi_pointer_prototype_tostring_shared,\n\tduk_bi_proxy_constructor,\n\tduk_bi_reflect_apply,\n\tduk_bi_reflect_construct,\n\tduk_bi_reflect_object_delete_property,\n\tduk_bi_reflect_object_get,\n\tduk_bi_reflect_object_has,\n\tduk_bi_reflect_object_set,\n\tduk_bi_regexp_constructor,\n\tduk_bi_regexp_prototype_exec,\n\tduk_bi_regexp_prototype_flags,\n\tduk_bi_regexp_prototype_shared_getter,\n\tduk_bi_regexp_prototype_test,\n\tduk_bi_regexp_prototype_tostring,\n\tduk_bi_string_constructor,\n\tduk_bi_string_constructor_from_char_code,\n\tduk_bi_string_constructor_from_code_point,\n\tduk_bi_string_prototype_caseconv_shared,\n\tduk_bi_string_prototype_char_at,\n\tduk_bi_string_prototype_char_code_at,\n\tduk_bi_string_prototype_concat,\n\tduk_bi_string_prototype_includes,\n\tduk_bi_string_prototype_indexof_shared,\n\tduk_bi_string_prototype_locale_compare,\n\tduk_bi_string_prototype_match,\n\tduk_bi_string_prototype_repeat,\n\tduk_bi_string_prototype_replace,\n\tduk_bi_string_prototype_search,\n\tduk_bi_string_prototype_slice,\n\tduk_bi_string_prototype_split,\n\tduk_bi_string_prototype_startswith_endswith,\n\tduk_bi_string_prototype_substr,\n\tduk_bi_string_prototype_substring,\n\tduk_bi_string_prototype_to_string,\n\tduk_bi_string_prototype_trim,\n\tduk_bi_symbol_constructor_shared,\n\tduk_bi_symbol_key_for,\n\tduk_bi_symbol_toprimitive,\n\tduk_bi_symbol_tostring_shared,\n\tduk_bi_textdecoder_constructor,\n\tduk_bi_textdecoder_prototype_decode,\n\tduk_bi_textdecoder_prototype_shared_getter,\n\tduk_bi_textencoder_constructor,\n\tduk_bi_textencoder_prototype_encode,\n\tduk_bi_textencoder_prototype_encoding_getter,\n\tduk_bi_thread_constructor,\n\tduk_bi_thread_current,\n\tduk_bi_thread_resume,\n\tduk_bi_thread_yield,\n\tduk_bi_type_error_thrower,\n\tduk_bi_typedarray_buffer_getter,\n\tduk_bi_typedarray_bytelength_getter,\n\tduk_bi_typedarray_byteoffset_getter,\n\tduk_bi_typedarray_constructor,\n\tduk_bi_typedarray_set,\n\tduk_bi_uint8array_allocplain,\n\tduk_bi_uint8array_plainof,\n};\n#if defined(DUK_USE_DOUBLE_LE)\nDUK_INTERNAL const duk_uint8_t duk_builtins_data[4251] = {\n144,148,105,225,32,68,52,228,126,12,104,201,37,132,52,167,194,138,105,244,\n124,57,28,211,57,18,64,52,238,254,44,138,111,171,241,164,19,87,137,30,33,\n167,18,145,159,8,211,137,9,225,42,5,240,145,139,163,163,8,211,137,10,228,\n64,211,19,132,140,93,29,56,70,156,72,119,34,66,146,36,104,137,194,70,46,\n142,172,35,78,36,47,146,195,102,11,240,145,139,163,175,8,211,137,9,228,240,\n242,112,145,139,163,179,8,211,137,8,237,34,130,118,49,116,118,225,26,48,0,\n1,94,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,\n33,8,66,26,180,41,97,167,64,150,34,33,154,112,0,1,87,247,35,79,103,237,198,\n174,216,47,31,23,95,17,13,31,217,96,211,49,50,53,212,77,141,24,0,0,179,10,\n228,240,242,15,128,140,65,128,134,188,0,0,89,167,97,181,224,0,2,205,62,53,\n224,0,2,205,66,237,120,0,0,179,81,204,107,192,0,5,154,150,67,94,0,0,44,212,\n245,90,240,0,1,102,169,162,215,128,0,11,53,93,150,188,0,0,89,171,111,53,\n108,150,163,70,0,0,42,2,249,50,94,124,35,68,225,146,49,13,24,0,0,165,161,\n124,153,47,62,12,130,112,201,24,132,56,97,115,16,0,0,0,0,0,0,62,31,243,48,\n0,0,0,0,0,0,60,31,242,241,32,26,193,55,132,112,161,156,72,135,26,41,200,\n140,114,163,156,201,7,56,79,9,80,47,132,140,93,19,160,43,145,3,76,78,18,49,\n116,78,144,238,68,133,36,72,209,19,132,140,93,19,168,47,146,195,102,11,240,\n145,139,162,117,132,242,120,121,56,72,197,209,59,2,59,72,160,157,140,93,19,\n181,36,242,50,143,36,31,131,162,166,7,144,238,133,227,226,235,224,242,161,\n249,18,21,100,20,207,44,199,151,180,122,89,135,152,154,121,153,199,156,158,\n121,218,7,158,162,121,250,71,160,166,122,26,135,162,170,122,58,199,164,16,\n240,70,68,226,27,51,199,138,120,35,34,112,171,112,38,121,1,124,153,47,62,\n17,162,112,201,19,211,11,228,201,121,240,100,19,134,72,158,160,91,201,18,\n186,44,3,68,79,122,168,151,115,165,40,21,18,227,65,198,231,200,8,68,184,84,\n53,19,38,120,128,145,144,78,25,59,72,163,48,64,144,200,39,12,157,164,80,46,\n185,143,115,72,217,230,72,9,35,68,225,147,180,138,51,68,9,17,162,112,201,\n218,69,2,235,152,247,52,141,158,108,128,98,72,64,121,51,132,4,81,164,144,\n128,242,104,136,0,16,92,38,14,49,39,199,197,211,116,240,242,113,197,231,18,\n53,189,116,65,131,18,124,117,155,199,197,207,36,103,142,12,146,20,80,249,\n186,60,116,4,204,73,241,214,111,31,23,60,145,158,56,208,48,146,229,146,3,2,\n82,65,155,195,94,3,10,36,4,201,196,64,56,100,42,26,78,62,46,121,35,60,113,\n152,16,25,10,134,147,143,139,158,72,205,4,151,21,0,73,16,11,230,144,12,88,\n144,153,39,52,144,69,241,37,72,217,240,151,153,27,36,57,178,230,16,16,137,\n114,68,2,200,62,81,1,8,151,11,23,100,141,229,18,6,34,92,37,230,70,201,1,89,\n57,36,2,40,152,151,44,129,83,18,124,117,155,199,197,207,36,103,142,75,12,\n11,151,46,89,40,18,37,200,64,12,154,236,252,238,185,23,95,213,1,132,234,0,\n194,245,128,14,56,37,199,89,188,124,92,242,70,120,232,16,26,137,113,241,\n116,221,60,60,156,113,122,36,10,62,46,121,35,60,113,18,225,27,70,18,32,10,\n201,211,32,67,107,104,100,42,26,78,24,147,153,35,181,181,207,64,67,107,104,\n100,42,26,78,72,147,153,35,181,181,207,68,16,218,218,91,156,170,63,134,36,\n230,72,237,109,116,136,16,218,218,91,156,170,63,146,36,230,72,237,109,116,\n137,16,96,128,228,2,6,191,46,3,71,147,68,4,16,22,188,169,240,16,40,104,242,\n135,198,171,44,68,65,5,217,231,215,6,231,62,188,8,49,1,3,162,92,4,98,12,41,\n7,33,148,53,242,128,97,32,130,3,9,205,16,38,199,198,14,9,0,111,115,225,0,8,\n250,72,240,207,128,241,37,73,25,18,40,0,178,58,11,56,192,2,201,104,17,35,\n160,9,39,70,114,8,6,147,214,129,18,74,240,30,141,145,208,89,203,62,3,161,\n163,37,248,226,185,244,11,88,37,62,33,163,37,248,226,185,252,0,127,255,130,\n146,164,142,32,26,1,36,230,18,1,164,7,43,163,194,0,71,128,105,64,216,7,192,\n52,192,197,66,230,72,192,52,224,209,32,232,34,68,62,129,113,32,232,34,114,\n40,49,231,16,254,0,63,255,208,99,2,140,44,92,206,8,224,143,4,225,147,210,\n124,13,44,92,206,9,195,39,30,228,54,126,163,225,200,169,198,133,42,166,191,\n246,3,11,251,0,24,71,4,120,9,251,8,10,17,193,30,9,195,39,1,63,105,1,98,112,\n201,199,185,13,159,1,63,105,32,48,156,209,2,126,227,224,58,26,50,95,142,47,\n192,208,22,176,74,124,67,70,75,241,197,248,26,64,213,184,64,89,56,39,49,\n224,137,62,36,2,176,19,17,254,68,3,196,143,88,4,79,162,0,210,32,34,35,253,\n72,5,146,208,34,125,144,5,147,214,137,253,208,9,149,3,41,197,13,55,233,0,\n185,187,139,117,137,30,8,18,39,172,1,25,187,139,112,128,178,113,110,177,35,\n193,2,68,245,128,23,55,114,143,121,35,193,2,68,245,130,8,205,220,91,132,5,\n147,148,123,201,30,8,18,39,172,16,18,113,67,63,128,3,68,143,32,39,243,32,\n42,83,4,103,46,89,19,63,224,208,16,70,142,92,178,38,127,193,164,8,67,68,\n186,12,146,247,154,1,165,64,202,113,252,160,131,32,7,35,167,26,50,235,231,\n130,48,179,192,65,148,69,19,214,2,251,85,2,232,72,31,255,255,255,255,255,\n253,239,226,122,196,55,106,160,93,9,0,4,0,0,0,0,0,0,3,49,0,0,0,0,0,0,3,225,\n252,143,94,233,34,104,169,54,144,210,161,168,158,32,0,0,0,0,0,0,120,63,145,\n235,72,96,77,21,38,210,26,84,53,19,196,0,0,0,0,0,0,15,15,240,253,35,228,\n133,185,176,0,0,0,0,0,0,44,15,8,117,128,190,212,128,82,109,33,179,33,137,\n24,31,255,255,255,255,255,231,232,100,58,196,55,106,64,41,54,144,217,144,\n196,140,15,255,255,255,255,255,243,252,49,15,4,100,78,33,179,60,120,167,\n130,50,39,10,183,2,103,144,113,8,151,10,134,162,100,221,16,18,137,113,13,\n153,12,72,238,137,1,81,46,52,28,110,232,148,53,18,228,128,82,113,13,153,12,\n72,238,137,142,73,78,52,0,0,0,0,0,0,0,0,8,58,254,1,12,38,248,134,23,130,0,\n60,221,194,162,228,30,244,128,217,187,132,187,220,210,54,104,2,247,132,5,\n205,220,124,72,36,73,14,110,252,132,25,128,193,94,8,200,149,200,3,237,38,\n43,31,192,54,186,213,128,57,45,56,210,0,0,0,0,0,0,62,31,241,90,251,224,6,\n77,220,24,38,78,74,113,67,77,124,16,50,110,228,208,194,114,83,138,26,107,\n224,172,37,240,97,41,187,139,112,128,178,112,96,153,57,41,197,13,53,240,\n113,41,187,139,112,128,178,114,104,97,57,41,197,13,53,240,128,195,95,8,44,\n61,240,132,216,93,33,133,192,128,14,98,79,147,67,9,129,0,44,196,159,11,69,\n175,152,32,35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,\n39,198,57,179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,\n240,96,153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,\n197,144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,\n150,22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,\n161,166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,\n100,39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,\n18,32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,\n72,68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,\n46,16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,\n117,11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,\n178,36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,\n173,191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,\n117,35,43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,\n131,4,201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,\n102,123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,\n162,215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,\n192,131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,181,55,136,\n200,51,128,114,108,28,100,128,0,0,0,0,0,0,0,12,110,127,32,98,115,249,73,\n117,243,249,67,21,159,202,38,47,63,148,86,8,75,144,94,50,1,38,73,79,204,67,\n95,231,1,6,128,14,79,129,185,40,249,18,149,181,207,142,199,155,172,248,172,\n89,183,207,140,198,137,175,200,0,159,72,10,5,21,220,138,120,74,129,124,36,\n98,232,228,74,81,62,160,20,10,107,185,21,114,32,105,137,194,70,46,142,68,\n165,19,235,1,64,170,187,145,119,34,66,146,36,104,137,194,70,46,142,68,165,\n19,236,1,64,174,187,145,95,37,134,204,23,225,35,23,71,34,82,137,246,128,\n160,89,93,200,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,145,\n71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,0,0,0,0,0,118,\n105,160,91,60,165,195,201,194,8,134,149,216,130,0,192,41,224,136,2,48,176,\n228,1,149,13,195,15,0,200,209,97,71,128,99,32,176,131,192,113,57,143,0,167,\n131,32,230,80,28,202,139,175,237,2,48,189,160,20,1,119,48,87,193,186,129,\n89,56,72,197,209,200,193,185,35,23,71,109,13,219,36,98,232,237,156,13,26,\n208,211,14,102,19,87,137,91,95,128,0,10,64,24,92,0,0,82,2,53,63,240,49,204,\n202,10,14,38,78,44,141,52,207,31,0,0,22,32,129,100,180,8,148,145,78,102,\n152,80,113,50,113,100,105,166,120,248,0,0,177,1,65,196,201,199,20,178,36,\n227,224,0,2,200,3,6,133,41,35,31,0,0,22,1,44,57,137,62,33,179,216,162,152,\n192,131,18,124,162,27,61,138,41,108,32,196,159,16,217,232,235,81,76,104,73,\n137,62,81,13,158,142,181,20,184,16,98,79,136,108,244,244,168,166,56,36,196,\n159,40,134,207,79,74,138,93,10,49,39,194,173,192,158,158,149,20,188,20,98,\n79,133,91,129,61,109,74,41,124,30,68,159,16,217,236,83,108,96,68,137,62,81,\n13,158,197,54,182,17,34,79,136,108,244,117,169,182,52,38,68,159,40,134,207,\n71,90,155,92,8,145,39,196,54,122,122,84,219,28,19,34,79,148,67,103,167,165,\n77,174,133,72,147,225,86,224,79,79,74,155,94,10,145,39,194,173,192,158,182,\n165,54,190,206,25,212,35,208,226,100,150,211,201,29,162,44,140,35,103,0,0,\n0,0,0,0,3,192,252,206,25,228,35,208,226,100,150,211,201,29,162,44,140,35,\n103,0,0,0,0,0,0,3,192,252,206,25,244,35,208,226,100,150,211,201,29,162,44,\n140,35,103,0,0,0,0,0,0,3,192,252,206,26,4,35,208,226,100,150,211,201,29,\n162,44,140,35,103,0,0,0,0,0,0,0,1,0,206,26,20,35,208,226,100,150,211,201,\n29,162,44,140,35,103,0,0,0,0,0,0,0,1,0,206,26,36,35,208,226,100,150,211,\n201,29,162,44,140,35,103,0,0,0,0,0,0,0,65,0,206,26,52,35,208,226,100,150,\n211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,65,0,206,26,68,35,208,226,100,\n150,211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,65,0,206,26,84,35,208,226,\n100,150,211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,129,0,195,154,99,16,38,\n36,0,251,68,117,179,216,162,128,68,72,1,241,13,158,197,20,150,25,18,0,125,\n162,58,217,232,235,117,100,162,136,25,18,0,125,162,58,217,232,235,116,36,\n162,145,2,226,64,15,136,108,244,117,186,178,81,73,129,113,32,7,196,54,122,\n58,221,9,40,165,64,200,144,3,237,17,214,207,79,75,171,37,20,80,200,144,3,\n237,17,214,207,79,75,161,37,20,138,23,18,0,124,67,103,167,165,213,146,138,\n77,11,137,0,62,33,179,211,210,232,73,69,42,133,196,128,31,10,183,2,125,89,\n40,163,5,196,128,31,10,183,2,125,9,40,164,96,200,144,3,224,221,64,172,157,\n89,40,163,134,68,128,31,6,234,5,100,232,73,69,35,133,68,128,31,104,142,182,\n125,89,40,180,0,168,144,3,237,17,214,207,161,37,22,144,19,18,0,124,67,103,\n213,146,139,80,9,137,0,62,33,179,232,73,69,172,5,90,40,153,59,68,117,179,\n216,166,192,77,162,137,147,136,108,246,41,180,176,219,69,19,39,104,142,182,\n122,58,221,89,41,178,6,218,40,153,59,68,117,179,209,214,232,73,77,162,6,90,\n40,153,56,134,207,71,91,171,37,54,152,25,104,162,100,226,27,61,29,110,132,\n148,218,160,109,162,137,147,180,71,91,61,61,46,172,148,217,67,109,20,76,\n157,162,58,217,233,233,116,36,166,209,67,45,20,76,156,67,103,167,165,213,\n146,155,77,12,180,81,50,113,13,158,158,151,66,74,109,84,50,209,68,201,194,\n173,192,159,86,74,108,193,150,138,38,78,21,110,4,250,18,83,104,193,182,138,\n38,78,13,212,10,201,213,146,155,56,109,162,137,147,131,117,2,178,116,36,\n166,209,194,237,20,76,157,162,58,217,245,100,167,16,2,237,20,76,157,162,58,\n217,244,36,167,18,2,173,20,76,156,67,103,213,146,156,80,10,180,81,50,113,\n13,159,66,74,113,97,175,220,48,216,109,192,4,42,22,189,163,0,196,133,0,185,\n80,32,28,78,99,193,18,80,36,4,19,159,141,156,0,178,90,4,74,73,0,22,209,68,\n201,185,129,4,2,8,3,132,64,60,36,6,149,113,72,176,171,240,84,0,157,91,116,\n116,32,11,42,218,221,216,181,129,32,3,234,219,165,3,188,231,235,249,8,187,\n152,252,47,86,227,105,18,7,244,17,91,42,56,175,185,248,110,173,198,209,208,\n36,0,238,82,97,87,188,189,179,240,93,122,32,12,22,162,42,125,144,132,160,7,\n236,161,25,232,237,105,64,205,59,127,102,158,160,230,63,11,217,66,51,210,\n129,154,118,254,205,61,65,236,127,171,197,34,168,48,6,90,162,1,0,39,75,84,\n72,8,9,33,186,162,80,64,76,13,213,19,2,130,96,110,150,181,0,65,6,51,213,20,\n128,65,17,11,213,19,130,137,121,211,210,210,144,6,39,75,84,80,0,201,119,\n234,138,8,41,86,231,71,84,80,129,79,135,186,122,101,224,34,25,69,233,208,3,\n91,141,170,40,96,139,113,180,181,69,36,21,110,54,142,134,168,165,1,176,23,\n212,47,0,216,134,234,87,128,111,117,181,168,128,209,3,70,230,106,192,5,139,\n168,209,234,138,32,36,144,102,235,8,3,146,27,170,40,160,146,132,103,170,40,\n192,115,3,117,69,28,22,113,163,69,170,41,103,1,66,188,17,145,52,104,4,202,\n113,67,76,130,227,72,194,13,240,108,0,0,83,96,0,2,185,0,104,146,84,97,48,0,\n1,90,192,56,169,24,145,179,192,0,5,96,8,56,16,32,128,56,18,52,125,198,86,\n147,186,140,28,50,21,13,39,31,23,60,145,158,56,204,141,47,121,6,155,190,\n188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,199,68,\n14,49,39,199,197,211,116,240,242,113,197,231,18,180,254,4,3,17,46,18,243,\n35,100,128,172,156,146,70,163,150,76,34,248,146,164,108,248,75,204,141,146,\n28,217,115,9,27,79,11,241,173,235,162,160,224,200,2,206,9,113,13,148,192,\n209,18,22,164,146,37,193,57,162,4,249,39,196,128,24,2,178,66,213,136,68,\n201,16,77,209,131,31,192,242,88,96,92,191,151,34,100,136,38,232,255,252,92,\n221,199,197,12,68,209,82,66,212,11,155,185,41,197,13,55,38,3,66,213,47,131,\n250,72,12,162,99,133,116,127,196,32,225,1,3,34,92,170,9,105,164,32,225,64,\n131,156,1,193,133,7,19,39,22,70,154,103,143,128,0,11,16,20,28,76,156,113,\n75,34,78,62,0,0,44,128,48,104,82,146,49,240,0,1,96,11,180,192,0,5,162,1,18,\n160,65,24,131,20,145,25,188,48,132,122,28,76,146,218,121,35,180,69,145,132,\n108,224,0,0,0,0,0,0,120,31,153,188,56,132,122,28,76,146,218,121,35,180,69,\n145,132,108,224,0,0,0,0,0,0,120,31,168,160,45,110,23,30,176,33,184,0,0,181,\n32,29,235,2,27,199,23,0,0,22,196,51,120,129,8,244,56,153,37,180,242,71,104,\n139,35,8,217,192,0,0,0,0,0,0,240,63,51,120,145,8,244,56,153,37,180,242,71,\n104,139,35,8,217,192,0,0,0,0,0,0,0,64,51,120,161,8,244,56,153,37,180,242,\n71,104,139,35,8,217,192,0,0,0,0,0,0,0,64,51,120,177,8,244,56,153,37,180,\n242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,120,193,8,244,56,153,37,\n180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,120,209,8,244,56,153,\n37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,120,225,8,244,56,\n153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,32,64,32,227,194,0,97,\n57,162,4,246,40,5,34,92,35,68,225,161,166,219,16,16,137,112,52,41,73,29,\n169,1,65,196,201,197,145,166,153,246,8,3,137,204,120,34,74,8,200,58,128,28,\n211,160,130,52,78,26,26,110,248,0,0,170,4,12,70,137,195,38,0,0,42,68,159,7,\n84,3,154,150,16,70,137,195,67,77,223,0,0,20,224,20,160,152,23,223,0,0,20,\n226,9,65,154,232,147,161,115,59,224,0,2,156,84,12,50,9,195,38,0,0,41,133,\n30,224,32,54,186,221,128,60,\n};\n#elif defined(DUK_USE_DOUBLE_BE)\nDUK_INTERNAL const duk_uint8_t duk_builtins_data[4251] = {\n144,148,105,225,32,68,52,228,126,12,104,201,37,132,52,167,194,138,105,244,\n124,57,28,211,57,18,64,52,238,254,44,138,111,171,241,164,19,87,137,30,33,\n167,18,145,159,8,211,137,9,225,42,5,240,145,139,163,163,8,211,137,10,228,\n64,211,19,132,140,93,29,56,70,156,72,119,34,66,146,36,104,137,194,70,46,\n142,172,35,78,36,47,146,195,102,11,240,145,139,163,175,8,211,137,9,228,240,\n242,112,145,139,163,179,8,211,137,8,237,34,130,118,49,116,118,225,26,48,0,\n1,94,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,\n33,8,66,26,180,41,97,167,64,150,34,33,154,112,0,1,87,247,35,79,103,237,198,\n174,216,47,31,23,95,17,13,31,217,96,211,49,50,53,212,77,141,24,0,0,179,10,\n228,240,242,15,128,140,65,128,134,188,0,0,89,167,97,181,224,0,2,205,62,53,\n224,0,2,205,66,237,120,0,0,179,81,204,107,192,0,5,154,150,67,94,0,0,44,212,\n245,90,240,0,1,102,169,162,215,128,0,11,53,93,150,188,0,0,89,171,111,53,\n108,150,163,70,0,0,42,2,249,50,94,124,35,68,225,146,49,13,24,0,0,165,161,\n124,153,47,62,12,130,112,201,24,132,56,97,115,16,31,254,0,0,0,0,0,0,51,48,\n31,252,0,0,0,0,0,0,50,241,32,26,193,55,132,112,161,156,72,135,26,41,200,\n140,114,163,156,201,7,56,79,9,80,47,132,140,93,19,160,43,145,3,76,78,18,49,\n116,78,144,238,68,133,36,72,209,19,132,140,93,19,168,47,146,195,102,11,240,\n145,139,162,117,132,242,120,121,56,72,197,209,59,2,59,72,160,157,140,93,19,\n181,36,242,50,143,36,31,131,162,166,7,144,238,133,227,226,235,224,242,161,\n249,18,21,100,20,207,44,199,151,180,122,89,135,152,154,121,153,199,156,158,\n121,218,7,158,162,121,250,71,160,166,122,26,135,162,170,122,58,199,164,16,\n240,70,68,226,27,51,199,138,120,35,34,112,171,112,38,121,1,124,153,47,62,\n17,162,112,201,19,211,11,228,201,121,240,100,19,134,72,158,160,91,201,18,\n186,44,3,68,79,122,168,151,115,165,40,21,18,227,65,198,231,200,8,68,184,84,\n53,19,38,120,128,145,144,78,25,59,72,163,48,64,144,200,39,12,157,164,80,46,\n185,143,115,72,217,230,72,9,35,68,225,147,180,138,51,68,9,17,162,112,201,\n218,69,2,235,152,247,52,141,158,108,128,98,72,64,121,51,132,4,81,164,144,\n128,242,104,136,0,16,92,38,14,49,39,199,197,211,116,240,242,113,197,231,18,\n53,189,116,65,131,18,124,117,155,199,197,207,36,103,142,12,146,20,80,249,\n186,60,116,4,204,73,241,214,111,31,23,60,145,158,56,208,48,146,229,146,3,2,\n82,65,155,195,94,3,10,36,4,201,196,64,56,100,42,26,78,62,46,121,35,60,113,\n152,16,25,10,134,147,143,139,158,72,205,4,151,21,0,73,16,11,230,144,12,88,\n144,153,39,52,144,69,241,37,72,217,240,151,153,27,36,57,178,230,16,16,137,\n114,68,2,200,62,81,1,8,151,11,23,100,141,229,18,6,34,92,37,230,70,201,1,89,\n57,36,2,40,152,151,44,129,83,18,124,117,155,199,197,207,36,103,142,75,12,\n11,151,46,89,40,18,37,200,64,12,154,236,252,238,185,23,95,213,1,132,234,0,\n194,245,128,14,56,37,199,89,188,124,92,242,70,120,232,16,26,137,113,241,\n116,221,60,60,156,113,122,36,10,62,46,121,35,60,113,18,225,27,70,18,32,10,\n201,211,32,67,107,104,100,42,26,78,24,147,153,35,181,181,207,64,67,107,104,\n100,42,26,78,72,147,153,35,181,181,207,68,16,218,218,91,156,170,63,134,36,\n230,72,237,109,116,136,16,218,218,91,156,170,63,146,36,230,72,237,109,116,\n137,16,96,128,228,2,6,191,46,3,71,147,68,4,16,22,188,169,240,16,40,104,242,\n135,198,171,44,68,65,5,217,231,215,6,231,62,188,8,49,1,3,162,92,4,98,12,41,\n7,33,148,53,242,128,97,32,130,3,9,205,16,38,199,198,14,9,0,111,115,225,0,8,\n250,72,240,207,128,241,37,73,25,18,40,0,178,58,11,56,192,2,201,104,17,35,\n160,9,39,70,114,8,6,147,214,129,18,74,240,30,141,145,208,89,203,62,3,161,\n163,37,248,226,185,244,11,88,37,62,33,163,37,248,226,185,252,0,127,255,130,\n146,164,142,32,26,1,36,230,18,1,164,7,43,163,194,0,71,128,105,64,216,7,192,\n52,192,197,66,230,72,192,52,224,209,32,232,34,68,62,129,113,32,232,34,114,\n40,49,231,16,254,0,63,255,208,99,2,140,44,92,206,8,224,143,4,225,147,210,\n124,13,44,92,206,9,195,39,30,228,54,126,163,225,200,169,198,133,42,166,191,\n246,3,11,251,0,24,71,4,120,9,251,8,10,17,193,30,9,195,39,1,63,105,1,98,112,\n201,199,185,13,159,1,63,105,32,48,156,209,2,126,227,224,58,26,50,95,142,47,\n192,208,22,176,74,124,67,70,75,241,197,248,26,64,213,184,64,89,56,39,49,\n224,137,62,36,2,176,19,17,254,68,3,196,143,88,4,79,162,0,210,32,34,35,253,\n72,5,146,208,34,125,144,5,147,214,137,253,208,9,149,3,41,197,13,55,233,0,\n185,187,139,117,137,30,8,18,39,172,1,25,187,139,112,128,178,113,110,177,35,\n193,2,68,245,128,23,55,114,143,121,35,193,2,68,245,130,8,205,220,91,132,5,\n147,148,123,201,30,8,18,39,172,16,18,113,67,63,128,3,68,143,32,39,243,32,\n42,83,4,103,46,89,19,63,224,208,16,70,142,92,178,38,127,193,164,8,67,68,\n186,12,146,247,154,1,165,64,202,113,252,160,131,32,7,35,167,26,50,235,231,\n130,48,179,192,65,148,69,19,214,2,251,85,2,232,72,15,253,255,255,255,255,\n255,255,226,122,196,55,106,160,93,9,0,0,0,0,0,0,0,0,7,49,1,255,224,0,0,0,0,\n0,0,143,94,233,34,104,169,54,144,210,161,168,158,32,63,248,0,0,0,0,0,0,17,\n235,72,96,77,21,38,210,26,84,53,19,196,15,255,0,0,0,0,0,0,0,253,35,228,133,\n185,176,15,44,0,0,0,0,0,0,8,117,128,190,212,128,82,109,33,179,33,137,24,8,\n103,255,255,255,255,255,255,228,58,196,55,106,64,41,54,144,217,144,196,140,\n12,51,255,255,255,255,255,255,241,15,4,100,78,33,179,60,120,167,130,50,39,\n10,183,2,103,144,113,8,151,10,134,162,100,221,16,18,137,113,13,153,12,72,\n238,137,1,81,46,52,28,110,232,148,53,18,228,128,82,113,13,153,12,72,238,\n137,142,73,78,52,0,0,0,0,0,0,0,0,8,58,254,1,12,38,248,134,23,130,0,60,221,\n194,162,228,30,244,128,217,187,132,187,220,210,54,104,2,247,132,5,205,220,\n124,72,36,73,14,110,252,132,25,128,193,94,8,200,149,200,3,237,38,43,31,192,\n54,186,213,128,57,45,56,210,31,254,0,0,0,0,0,0,49,90,251,224,6,77,220,24,\n38,78,74,113,67,77,124,16,50,110,228,208,194,114,83,138,26,107,224,172,37,\n240,97,41,187,139,112,128,178,112,96,153,57,41,197,13,53,240,113,41,187,\n139,112,128,178,114,104,97,57,41,197,13,53,240,128,195,95,8,44,61,240,132,\n216,93,33,133,192,128,14,98,79,147,67,9,129,0,44,196,159,11,69,175,152,32,\n35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,39,198,57,\n179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,240,96,\n153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,197,\n144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,150,\n22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,161,\n166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,100,\n39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,18,\n32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,72,\n68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,46,\n16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,117,\n11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,178,\n36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,173,\n191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,117,35,\n43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,131,4,\n201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,102,\n123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,162,\n215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,192,\n131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,181,55,136,200,\n51,128,114,108,28,100,128,0,0,0,0,0,0,0,12,110,127,32,98,115,249,73,117,\n243,249,67,21,159,202,38,47,63,148,86,8,75,144,94,50,1,38,73,79,204,67,95,\n231,1,6,128,14,79,129,185,40,249,18,149,181,207,142,199,155,172,248,172,89,\n183,207,140,198,137,175,200,0,159,72,10,5,21,220,138,120,74,129,124,36,98,\n232,228,74,81,62,160,20,10,107,185,21,114,32,105,137,194,70,46,142,68,165,\n19,235,1,64,170,187,145,119,34,66,146,36,104,137,194,70,46,142,68,165,19,\n236,1,64,174,187,145,95,37,134,204,23,225,35,23,71,34,82,137,246,128,160,\n89,93,200,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,145,71,\n105,20,19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,32,105,246,0,0,0,\n0,0,91,60,165,195,201,194,8,134,149,216,130,0,192,41,224,136,2,48,176,228,\n1,149,13,195,15,0,200,209,97,71,128,99,32,176,131,192,113,57,143,0,167,131,\n32,230,80,28,202,139,175,237,2,48,189,160,20,1,119,48,87,193,186,129,89,56,\n72,197,209,200,193,185,35,23,71,109,13,219,36,98,232,237,156,13,26,208,211,\n14,102,19,87,137,91,95,128,0,10,64,24,92,0,0,82,2,53,63,240,49,204,202,10,\n14,38,78,44,141,52,207,31,0,0,22,32,129,100,180,8,148,145,78,102,152,80,\n113,50,113,100,105,166,120,248,0,0,177,1,65,196,201,199,20,178,36,227,224,\n0,2,200,3,6,133,41,35,31,0,0,22,1,44,57,137,62,33,179,216,162,152,192,131,\n18,124,162,27,61,138,41,108,32,196,159,16,217,232,235,81,76,104,73,137,62,\n81,13,158,142,181,20,184,16,98,79,136,108,244,244,168,166,56,36,196,159,40,\n134,207,79,74,138,93,10,49,39,194,173,192,158,158,149,20,188,20,98,79,133,\n91,129,61,109,74,41,124,30,68,159,16,217,236,83,108,96,68,137,62,81,13,158,\n197,54,182,17,34,79,136,108,244,117,169,182,52,38,68,159,40,134,207,71,90,\n155,92,8,145,39,196,54,122,122,84,219,28,19,34,79,148,67,103,167,165,77,\n174,133,72,147,225,86,224,79,79,74,155,94,10,145,39,194,173,192,158,182,\n165,54,190,206,25,212,35,208,226,100,150,211,201,29,162,44,140,35,103,0,\n255,192,0,0,0,0,0,0,206,25,228,35,208,226,100,150,211,201,29,162,44,140,35,\n103,0,255,192,0,0,0,0,0,0,206,25,244,35,208,226,100,150,211,201,29,162,44,\n140,35,103,0,255,192,0,0,0,0,0,0,206,26,4,35,208,226,100,150,211,201,29,\n162,44,140,35,103,1,0,0,0,0,0,0,0,0,206,26,20,35,208,226,100,150,211,201,\n29,162,44,140,35,103,1,0,0,0,0,0,0,0,0,206,26,36,35,208,226,100,150,211,\n201,29,162,44,140,35,103,1,0,64,0,0,0,0,0,0,206,26,52,35,208,226,100,150,\n211,201,29,162,44,140,35,103,1,0,64,0,0,0,0,0,0,206,26,68,35,208,226,100,\n150,211,201,29,162,44,140,35,103,1,0,64,0,0,0,0,0,0,206,26,84,35,208,226,\n100,150,211,201,29,162,44,140,35,103,1,0,128,0,0,0,0,0,0,195,154,99,16,38,\n36,0,251,68,117,179,216,162,128,68,72,1,241,13,158,197,20,150,25,18,0,125,\n162,58,217,232,235,117,100,162,136,25,18,0,125,162,58,217,232,235,116,36,\n162,145,2,226,64,15,136,108,244,117,186,178,81,73,129,113,32,7,196,54,122,\n58,221,9,40,165,64,200,144,3,237,17,214,207,79,75,171,37,20,80,200,144,3,\n237,17,214,207,79,75,161,37,20,138,23,18,0,124,67,103,167,165,213,146,138,\n77,11,137,0,62,33,179,211,210,232,73,69,42,133,196,128,31,10,183,2,125,89,\n40,163,5,196,128,31,10,183,2,125,9,40,164,96,200,144,3,224,221,64,172,157,\n89,40,163,134,68,128,31,6,234,5,100,232,73,69,35,133,68,128,31,104,142,182,\n125,89,40,180,0,168,144,3,237,17,214,207,161,37,22,144,19,18,0,124,67,103,\n213,146,139,80,9,137,0,62,33,179,232,73,69,172,5,90,40,153,59,68,117,179,\n216,166,192,77,162,137,147,136,108,246,41,180,176,219,69,19,39,104,142,182,\n122,58,221,89,41,178,6,218,40,153,59,68,117,179,209,214,232,73,77,162,6,90,\n40,153,56,134,207,71,91,171,37,54,152,25,104,162,100,226,27,61,29,110,132,\n148,218,160,109,162,137,147,180,71,91,61,61,46,172,148,217,67,109,20,76,\n157,162,58,217,233,233,116,36,166,209,67,45,20,76,156,67,103,167,165,213,\n146,155,77,12,180,81,50,113,13,158,158,151,66,74,109,84,50,209,68,201,194,\n173,192,159,86,74,108,193,150,138,38,78,21,110,4,250,18,83,104,193,182,138,\n38,78,13,212,10,201,213,146,155,56,109,162,137,147,131,117,2,178,116,36,\n166,209,194,237,20,76,157,162,58,217,245,100,167,16,2,237,20,76,157,162,58,\n217,244,36,167,18,2,173,20,76,156,67,103,213,146,156,80,10,180,81,50,113,\n13,159,66,74,113,97,175,220,48,216,109,192,4,42,22,189,163,0,196,133,0,185,\n80,32,28,78,99,193,18,80,36,4,19,159,141,156,0,178,90,4,74,73,0,22,209,68,\n201,185,129,4,2,8,3,132,64,60,36,4,0,91,240,168,177,69,118,144,157,91,116,\n116,32,32,1,53,216,221,218,170,139,3,234,219,165,0,255,152,185,11,251,232,\n231,188,47,86,227,105,18,1,255,184,170,59,41,92,23,240,110,173,198,209,208,\n36,3,253,188,183,177,82,110,80,224,93,122,32,32,4,144,253,170,34,22,140,7,\n236,161,25,232,237,105,64,63,230,160,158,102,127,59,205,11,217,66,51,210,\n128,127,237,65,60,204,254,119,155,171,197,34,168,48,6,90,162,1,0,39,75,84,\n72,8,9,33,186,162,80,64,76,13,213,19,2,130,96,110,150,181,0,65,6,51,213,20,\n128,65,17,11,213,19,130,137,121,211,210,210,144,6,39,75,84,80,0,201,119,\n234,138,8,41,86,231,71,84,80,129,79,135,186,122,101,224,34,25,69,233,208,3,\n91,141,170,40,96,139,113,180,181,69,36,21,110,54,142,134,168,165,1,176,23,\n212,47,0,216,134,234,87,128,111,117,181,168,128,209,3,70,230,106,192,5,139,\n168,209,234,138,32,36,144,102,235,8,3,146,27,170,40,160,146,132,103,170,40,\n192,115,3,117,69,28,22,113,163,69,170,41,103,1,66,188,17,145,52,104,4,202,\n113,67,76,130,227,72,194,13,240,108,0,0,83,96,0,2,185,0,104,146,84,97,48,0,\n1,90,192,56,169,24,145,179,192,0,5,96,8,56,16,32,128,56,18,52,125,198,86,\n147,186,140,28,50,21,13,39,31,23,60,145,158,56,204,141,47,121,6,155,190,\n188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,199,68,\n14,49,39,199,197,211,116,240,242,113,197,231,18,180,254,4,3,17,46,18,243,\n35,100,128,172,156,146,70,163,150,76,34,248,146,164,108,248,75,204,141,146,\n28,217,115,9,27,79,11,241,173,235,162,160,224,200,2,206,9,113,13,148,192,\n209,18,22,164,146,37,193,57,162,4,249,39,196,128,24,2,178,66,213,136,68,\n201,16,77,209,131,31,192,242,88,96,92,191,151,34,100,136,38,232,255,252,92,\n221,199,197,12,68,209,82,66,212,11,155,185,41,197,13,55,38,3,66,213,47,131,\n250,72,12,162,99,133,116,127,196,32,225,1,3,34,92,170,9,105,164,32,225,64,\n131,156,1,193,133,7,19,39,22,70,154,103,143,128,0,11,16,20,28,76,156,113,\n75,34,78,62,0,0,44,128,48,104,82,146,49,240,0,1,96,11,180,192,0,5,162,1,18,\n160,65,24,131,20,145,25,188,48,132,122,28,76,146,218,121,35,180,69,145,132,\n108,224,31,248,0,0,0,0,0,0,25,188,56,132,122,28,76,146,218,121,35,180,69,\n145,132,108,224,31,248,0,0,0,0,0,0,40,160,45,110,23,30,176,33,184,0,0,181,\n32,29,235,2,27,199,23,0,0,22,196,51,120,129,8,244,56,153,37,180,242,71,104,\n139,35,8,217,192,63,240,0,0,0,0,0,0,51,120,145,8,244,56,153,37,180,242,71,\n104,139,35,8,217,192,64,0,0,0,0,0,0,0,51,120,161,8,244,56,153,37,180,242,\n71,104,139,35,8,217,192,64,0,0,0,0,0,0,0,51,120,177,8,244,56,153,37,180,\n242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,120,193,8,244,56,153,37,\n180,242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,120,209,8,244,56,153,\n37,180,242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,120,225,8,244,56,\n153,37,180,242,71,104,139,35,8,217,192,64,32,0,0,0,0,0,0,32,227,194,0,97,\n57,162,4,246,40,5,34,92,35,68,225,161,166,219,16,16,137,112,52,41,73,29,\n169,1,65,196,201,197,145,166,153,246,8,3,137,204,120,34,74,8,200,58,128,28,\n211,160,130,52,78,26,26,110,248,0,0,170,4,12,70,137,195,38,0,0,42,68,159,7,\n84,3,154,150,16,70,137,195,67,77,223,0,0,20,224,20,160,152,23,223,0,0,20,\n226,9,65,154,232,147,161,115,59,224,0,2,156,84,12,50,9,195,38,0,0,41,133,\n30,224,32,54,186,221,128,60,\n};\n#elif defined(DUK_USE_DOUBLE_ME)\nDUK_INTERNAL const duk_uint8_t duk_builtins_data[4251] = {\n144,148,105,225,32,68,52,228,126,12,104,201,37,132,52,167,194,138,105,244,\n124,57,28,211,57,18,64,52,238,254,44,138,111,171,241,164,19,87,137,30,33,\n167,18,145,159,8,211,137,9,225,42,5,240,145,139,163,163,8,211,137,10,228,\n64,211,19,132,140,93,29,56,70,156,72,119,34,66,146,36,104,137,194,70,46,\n142,172,35,78,36,47,146,195,102,11,240,145,139,163,175,8,211,137,9,228,240,\n242,112,145,139,163,179,8,211,137,8,237,34,130,118,49,116,118,225,26,48,0,\n1,94,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,\n33,8,66,26,180,41,97,167,64,150,34,33,154,112,0,1,87,247,35,79,103,237,198,\n174,216,47,31,23,95,17,13,31,217,96,211,49,50,53,212,77,141,24,0,0,179,10,\n228,240,242,15,128,140,65,128,134,188,0,0,89,167,97,181,224,0,2,205,62,53,\n224,0,2,205,66,237,120,0,0,179,81,204,107,192,0,5,154,150,67,94,0,0,44,212,\n245,90,240,0,1,102,169,162,215,128,0,11,53,93,150,188,0,0,89,171,111,53,\n108,150,163,70,0,0,42,2,249,50,94,124,35,68,225,146,49,13,24,0,0,165,161,\n124,153,47,62,12,130,112,201,24,132,56,97,115,16,0,0,62,31,192,0,0,0,51,48,\n0,0,60,31,192,0,0,0,50,241,32,26,193,55,132,112,161,156,72,135,26,41,200,\n140,114,163,156,201,7,56,79,9,80,47,132,140,93,19,160,43,145,3,76,78,18,49,\n116,78,144,238,68,133,36,72,209,19,132,140,93,19,168,47,146,195,102,11,240,\n145,139,162,117,132,242,120,121,56,72,197,209,59,2,59,72,160,157,140,93,19,\n181,36,242,50,143,36,31,131,162,166,7,144,238,133,227,226,235,224,242,161,\n249,18,21,100,20,207,44,199,151,180,122,89,135,152,154,121,153,199,156,158,\n121,218,7,158,162,121,250,71,160,166,122,26,135,162,170,122,58,199,164,16,\n240,70,68,226,27,51,199,138,120,35,34,112,171,112,38,121,1,124,153,47,62,\n17,162,112,201,19,211,11,228,201,121,240,100,19,134,72,158,160,91,201,18,\n186,44,3,68,79,122,168,151,115,165,40,21,18,227,65,198,231,200,8,68,184,84,\n53,19,38,120,128,145,144,78,25,59,72,163,48,64,144,200,39,12,157,164,80,46,\n185,143,115,72,217,230,72,9,35,68,225,147,180,138,51,68,9,17,162,112,201,\n218,69,2,235,152,247,52,141,158,108,128,98,72,64,121,51,132,4,81,164,144,\n128,242,104,136,0,16,92,38,14,49,39,199,197,211,116,240,242,113,197,231,18,\n53,189,116,65,131,18,124,117,155,199,197,207,36,103,142,12,146,20,80,249,\n186,60,116,4,204,73,241,214,111,31,23,60,145,158,56,208,48,146,229,146,3,2,\n82,65,155,195,94,3,10,36,4,201,196,64,56,100,42,26,78,62,46,121,35,60,113,\n152,16,25,10,134,147,143,139,158,72,205,4,151,21,0,73,16,11,230,144,12,88,\n144,153,39,52,144,69,241,37,72,217,240,151,153,27,36,57,178,230,16,16,137,\n114,68,2,200,62,81,1,8,151,11,23,100,141,229,18,6,34,92,37,230,70,201,1,89,\n57,36,2,40,152,151,44,129,83,18,124,117,155,199,197,207,36,103,142,75,12,\n11,151,46,89,40,18,37,200,64,12,154,236,252,238,185,23,95,213,1,132,234,0,\n194,245,128,14,56,37,199,89,188,124,92,242,70,120,232,16,26,137,113,241,\n116,221,60,60,156,113,122,36,10,62,46,121,35,60,113,18,225,27,70,18,32,10,\n201,211,32,67,107,104,100,42,26,78,24,147,153,35,181,181,207,64,67,107,104,\n100,42,26,78,72,147,153,35,181,181,207,68,16,218,218,91,156,170,63,134,36,\n230,72,237,109,116,136,16,218,218,91,156,170,63,146,36,230,72,237,109,116,\n137,16,96,128,228,2,6,191,46,3,71,147,68,4,16,22,188,169,240,16,40,104,242,\n135,198,171,44,68,65,5,217,231,215,6,231,62,188,8,49,1,3,162,92,4,98,12,41,\n7,33,148,53,242,128,97,32,130,3,9,205,16,38,199,198,14,9,0,111,115,225,0,8,\n250,72,240,207,128,241,37,73,25,18,40,0,178,58,11,56,192,2,201,104,17,35,\n160,9,39,70,114,8,6,147,214,129,18,74,240,30,141,145,208,89,203,62,3,161,\n163,37,248,226,185,244,11,88,37,62,33,163,37,248,226,185,252,0,127,255,130,\n146,164,142,32,26,1,36,230,18,1,164,7,43,163,194,0,71,128,105,64,216,7,192,\n52,192,197,66,230,72,192,52,224,209,32,232,34,68,62,129,113,32,232,34,114,\n40,49,231,16,254,0,63,255,208,99,2,140,44,92,206,8,224,143,4,225,147,210,\n124,13,44,92,206,9,195,39,30,228,54,126,163,225,200,169,198,133,42,166,191,\n246,3,11,251,0,24,71,4,120,9,251,8,10,17,193,30,9,195,39,1,63,105,1,98,112,\n201,199,185,13,159,1,63,105,32,48,156,209,2,126,227,224,58,26,50,95,142,47,\n192,208,22,176,74,124,67,70,75,241,197,248,26,64,213,184,64,89,56,39,49,\n224,137,62,36,2,176,19,17,254,68,3,196,143,88,4,79,162,0,210,32,34,35,253,\n72,5,146,208,34,125,144,5,147,214,137,253,208,9,149,3,41,197,13,55,233,0,\n185,187,139,117,137,30,8,18,39,172,1,25,187,139,112,128,178,113,110,177,35,\n193,2,68,245,128,23,55,114,143,121,35,193,2,68,245,130,8,205,220,91,132,5,\n147,148,123,201,30,8,18,39,172,16,18,113,67,63,128,3,68,143,32,39,243,32,\n42,83,4,103,46,89,19,63,224,208,16,70,142,92,178,38,127,193,164,8,67,68,\n186,12,146,247,154,1,165,64,202,113,252,160,131,32,7,35,167,26,50,235,231,\n130,48,179,192,65,148,69,19,214,2,251,85,2,232,72,31,255,253,239,255,255,\n255,255,226,122,196,55,106,160,93,9,0,0,0,0,0,4,0,0,3,49,0,0,3,225,252,0,0,\n0,0,143,94,233,34,104,169,54,144,210,161,168,158,32,0,0,120,63,128,0,0,0,\n17,235,72,96,77,21,38,210,26,84,53,19,196,0,0,15,15,240,0,0,0,0,253,35,228,\n133,185,176,0,0,44,15,0,0,0,0,8,117,128,190,212,128,82,109,33,179,33,137,\n24,31,255,231,232,127,255,255,255,228,58,196,55,106,64,41,54,144,217,144,\n196,140,15,255,243,252,63,255,255,255,241,15,4,100,78,33,179,60,120,167,\n130,50,39,10,183,2,103,144,113,8,151,10,134,162,100,221,16,18,137,113,13,\n153,12,72,238,137,1,81,46,52,28,110,232,148,53,18,228,128,82,113,13,153,12,\n72,238,137,142,73,78,52,0,0,0,0,0,0,0,0,8,58,254,1,12,38,248,134,23,130,0,\n60,221,194,162,228,30,244,128,217,187,132,187,220,210,54,104,2,247,132,5,\n205,220,124,72,36,73,14,110,252,132,25,128,193,94,8,200,149,200,3,237,38,\n43,31,192,54,186,213,128,57,45,56,210,0,0,62,31,192,0,0,0,49,90,251,224,6,\n77,220,24,38,78,74,113,67,77,124,16,50,110,228,208,194,114,83,138,26,107,\n224,172,37,240,97,41,187,139,112,128,178,112,96,153,57,41,197,13,53,240,\n113,41,187,139,112,128,178,114,104,97,57,41,197,13,53,240,128,195,95,8,44,\n61,240,132,216,93,33,133,192,128,14,98,79,147,67,9,129,0,44,196,159,11,69,\n175,152,32,35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,\n39,198,57,179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,\n240,96,153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,\n197,144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,\n150,22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,\n161,166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,\n100,39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,\n18,32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,\n72,68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,\n46,16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,\n117,11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,\n178,36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,\n173,191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,\n117,35,43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,\n131,4,201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,\n102,123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,\n162,215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,\n192,131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,181,55,136,\n200,51,128,114,108,28,100,128,0,0,0,0,0,0,0,12,110,127,32,98,115,249,73,\n117,243,249,67,21,159,202,38,47,63,148,86,8,75,144,94,50,1,38,73,79,204,67,\n95,231,1,6,128,14,79,129,185,40,249,18,149,181,207,142,199,155,172,248,172,\n89,183,207,140,198,137,175,200,0,159,72,10,5,21,220,138,120,74,129,124,36,\n98,232,228,74,81,62,160,20,10,107,185,21,114,32,105,137,194,70,46,142,68,\n165,19,235,1,64,170,187,145,119,34,66,146,36,104,137,194,70,46,142,68,165,\n19,236,1,64,174,187,145,95,37,134,204,23,225,35,23,71,34,82,137,246,128,\n160,89,93,200,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,145,\n71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,0,118,105,160,\n0,0,0,0,91,60,165,195,201,194,8,134,149,216,130,0,192,41,224,136,2,48,176,\n228,1,149,13,195,15,0,200,209,97,71,128,99,32,176,131,192,113,57,143,0,167,\n131,32,230,80,28,202,139,175,237,2,48,189,160,20,1,119,48,87,193,186,129,\n89,56,72,197,209,200,193,185,35,23,71,109,13,219,36,98,232,237,156,13,26,\n208,211,14,102,19,87,137,91,95,128,0,10,64,24,92,0,0,82,2,53,63,240,49,204,\n202,10,14,38,78,44,141,52,207,31,0,0,22,32,129,100,180,8,148,145,78,102,\n152,80,113,50,113,100,105,166,120,248,0,0,177,1,65,196,201,199,20,178,36,\n227,224,0,2,200,3,6,133,41,35,31,0,0,22,1,44,57,137,62,33,179,216,162,152,\n192,131,18,124,162,27,61,138,41,108,32,196,159,16,217,232,235,81,76,104,73,\n137,62,81,13,158,142,181,20,184,16,98,79,136,108,244,244,168,166,56,36,196,\n159,40,134,207,79,74,138,93,10,49,39,194,173,192,158,158,149,20,188,20,98,\n79,133,91,129,61,109,74,41,124,30,68,159,16,217,236,83,108,96,68,137,62,81,\n13,158,197,54,182,17,34,79,136,108,244,117,169,182,52,38,68,159,40,134,207,\n71,90,155,92,8,145,39,196,54,122,122,84,219,28,19,34,79,148,67,103,167,165,\n77,174,133,72,147,225,86,224,79,79,74,155,94,10,145,39,194,173,192,158,182,\n165,54,190,206,25,212,35,208,226,100,150,211,201,29,162,44,140,35,103,0,0,\n3,192,252,0,0,0,0,206,25,228,35,208,226,100,150,211,201,29,162,44,140,35,\n103,0,0,3,192,252,0,0,0,0,206,25,244,35,208,226,100,150,211,201,29,162,44,\n140,35,103,0,0,3,192,252,0,0,0,0,206,26,4,35,208,226,100,150,211,201,29,\n162,44,140,35,103,0,0,0,1,0,0,0,0,0,206,26,20,35,208,226,100,150,211,201,\n29,162,44,140,35,103,0,0,0,1,0,0,0,0,0,206,26,36,35,208,226,100,150,211,\n201,29,162,44,140,35,103,0,0,0,65,0,0,0,0,0,206,26,52,35,208,226,100,150,\n211,201,29,162,44,140,35,103,0,0,0,65,0,0,0,0,0,206,26,68,35,208,226,100,\n150,211,201,29,162,44,140,35,103,0,0,0,65,0,0,0,0,0,206,26,84,35,208,226,\n100,150,211,201,29,162,44,140,35,103,0,0,0,129,0,0,0,0,0,195,154,99,16,38,\n36,0,251,68,117,179,216,162,128,68,72,1,241,13,158,197,20,150,25,18,0,125,\n162,58,217,232,235,117,100,162,136,25,18,0,125,162,58,217,232,235,116,36,\n162,145,2,226,64,15,136,108,244,117,186,178,81,73,129,113,32,7,196,54,122,\n58,221,9,40,165,64,200,144,3,237,17,214,207,79,75,171,37,20,80,200,144,3,\n237,17,214,207,79,75,161,37,20,138,23,18,0,124,67,103,167,165,213,146,138,\n77,11,137,0,62,33,179,211,210,232,73,69,42,133,196,128,31,10,183,2,125,89,\n40,163,5,196,128,31,10,183,2,125,9,40,164,96,200,144,3,224,221,64,172,157,\n89,40,163,134,68,128,31,6,234,5,100,232,73,69,35,133,68,128,31,104,142,182,\n125,89,40,180,0,168,144,3,237,17,214,207,161,37,22,144,19,18,0,124,67,103,\n213,146,139,80,9,137,0,62,33,179,232,73,69,172,5,90,40,153,59,68,117,179,\n216,166,192,77,162,137,147,136,108,246,41,180,176,219,69,19,39,104,142,182,\n122,58,221,89,41,178,6,218,40,153,59,68,117,179,209,214,232,73,77,162,6,90,\n40,153,56,134,207,71,91,171,37,54,152,25,104,162,100,226,27,61,29,110,132,\n148,218,160,109,162,137,147,180,71,91,61,61,46,172,148,217,67,109,20,76,\n157,162,58,217,233,233,116,36,166,209,67,45,20,76,156,67,103,167,165,213,\n146,155,77,12,180,81,50,113,13,158,158,151,66,74,109,84,50,209,68,201,194,\n173,192,159,86,74,108,193,150,138,38,78,21,110,4,250,18,83,104,193,182,138,\n38,78,13,212,10,201,213,146,155,56,109,162,137,147,131,117,2,178,116,36,\n166,209,194,237,20,76,157,162,58,217,245,100,167,16,2,237,20,76,157,162,58,\n217,244,36,167,18,2,173,20,76,156,67,103,213,146,156,80,10,180,81,50,113,\n13,159,66,74,113,97,175,220,48,216,109,192,4,42,22,189,163,0,196,133,0,185,\n80,32,28,78,99,193,18,80,36,4,19,159,141,156,0,178,90,4,74,73,0,22,209,68,\n201,185,129,4,2,8,3,132,64,60,36,0,171,240,84,6,149,113,72,176,157,91,116,\n116,32,88,181,129,32,11,42,218,221,131,234,219,165,1,8,187,152,255,188,231,\n235,248,47,86,227,105,18,2,56,175,185,255,244,17,91,40,110,173,198,209,208,\n36,7,188,189,179,240,238,82,97,80,93,122,32,125,144,132,160,12,22,162,42,7,\n236,161,25,232,237,105,64,158,160,230,63,205,59,127,102,11,217,66,51,210,\n129,61,65,236,127,154,118,254,205,171,197,34,168,48,6,90,162,1,0,39,75,84,\n72,8,9,33,186,162,80,64,76,13,213,19,2,130,96,110,150,181,0,65,6,51,213,20,\n128,65,17,11,213,19,130,137,121,211,210,210,144,6,39,75,84,80,0,201,119,\n234,138,8,41,86,231,71,84,80,129,79,135,186,122,101,224,34,25,69,233,208,3,\n91,141,170,40,96,139,113,180,181,69,36,21,110,54,142,134,168,165,1,176,23,\n212,47,0,216,134,234,87,128,111,117,181,168,128,209,3,70,230,106,192,5,139,\n168,209,234,138,32,36,144,102,235,8,3,146,27,170,40,160,146,132,103,170,40,\n192,115,3,117,69,28,22,113,163,69,170,41,103,1,66,188,17,145,52,104,4,202,\n113,67,76,130,227,72,194,13,240,108,0,0,83,96,0,2,185,0,104,146,84,97,48,0,\n1,90,192,56,169,24,145,179,192,0,5,96,8,56,16,32,128,56,18,52,125,198,86,\n147,186,140,28,50,21,13,39,31,23,60,145,158,56,204,141,47,121,6,155,190,\n188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,199,68,\n14,49,39,199,197,211,116,240,242,113,197,231,18,180,254,4,3,17,46,18,243,\n35,100,128,172,156,146,70,163,150,76,34,248,146,164,108,248,75,204,141,146,\n28,217,115,9,27,79,11,241,173,235,162,160,224,200,2,206,9,113,13,148,192,\n209,18,22,164,146,37,193,57,162,4,249,39,196,128,24,2,178,66,213,136,68,\n201,16,77,209,131,31,192,242,88,96,92,191,151,34,100,136,38,232,255,252,92,\n221,199,197,12,68,209,82,66,212,11,155,185,41,197,13,55,38,3,66,213,47,131,\n250,72,12,162,99,133,116,127,196,32,225,1,3,34,92,170,9,105,164,32,225,64,\n131,156,1,193,133,7,19,39,22,70,154,103,143,128,0,11,16,20,28,76,156,113,\n75,34,78,62,0,0,44,128,48,104,82,146,49,240,0,1,96,11,180,192,0,5,162,1,18,\n160,65,24,131,20,145,25,188,48,132,122,28,76,146,218,121,35,180,69,145,132,\n108,224,0,0,120,31,128,0,0,0,25,188,56,132,122,28,76,146,218,121,35,180,69,\n145,132,108,224,0,0,120,31,128,0,0,0,40,160,45,110,23,30,176,33,184,0,0,\n181,32,29,235,2,27,199,23,0,0,22,196,51,120,129,8,244,56,153,37,180,242,71,\n104,139,35,8,217,192,0,0,240,63,0,0,0,0,51,120,145,8,244,56,153,37,180,242,\n71,104,139,35,8,217,192,0,0,0,64,0,0,0,0,51,120,161,8,244,56,153,37,180,\n242,71,104,139,35,8,217,192,0,0,0,64,0,0,0,0,51,120,177,8,244,56,153,37,\n180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,120,193,8,244,56,153,\n37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,120,209,8,244,56,\n153,37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,120,225,8,244,\n56,153,37,180,242,71,104,139,35,8,217,192,0,0,32,64,0,0,0,0,32,227,194,0,\n97,57,162,4,246,40,5,34,92,35,68,225,161,166,219,16,16,137,112,52,41,73,29,\n169,1,65,196,201,197,145,166,153,246,8,3,137,204,120,34,74,8,200,58,128,28,\n211,160,130,52,78,26,26,110,248,0,0,170,4,12,70,137,195,38,0,0,42,68,159,7,\n84,3,154,150,16,70,137,195,67,77,223,0,0,20,224,20,160,152,23,223,0,0,20,\n226,9,65,154,232,147,161,115,59,224,0,2,156,84,12,50,9,195,38,0,0,41,133,\n30,224,32,54,186,221,128,60,\n};\n#else\n#error invalid endianness defines\n#endif\n#endif  /* DUK_USE_ROM_OBJECTS */\n\n/* automatic undefs */\n#undef DUK__REFCINIT\n/*\n *  Error and fatal handling.\n */\n\n/* #include duk_internal.h -> already included */\n\n#define DUK__ERRFMT_BUFSIZE  256  /* size for formatting buffers */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\nDUK_INTERNAL DUK_COLD void duk_err_handle_error_fmt(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *fmt, ...) {\n\tva_list ap;\n\tchar msg[DUK__ERRFMT_BUFSIZE];\n\tva_start(ap, fmt);\n\t(void) DUK_VSNPRINTF(msg, sizeof(msg), fmt, ap);\n\tmsg[sizeof(msg) - 1] = (char) 0;\n\tduk_err_create_and_throw(thr, (duk_errcode_t) (line_and_code >> 24), msg, filename, (duk_int_t) (line_and_code & 0x00ffffffL));\n\tva_end(ap);  /* dead code, but ensures portability (see Linux man page notes) */\n}\n\nDUK_INTERNAL DUK_COLD void duk_err_handle_error(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *msg) {\n\tduk_err_create_and_throw(thr, (duk_errcode_t) (line_and_code >> 24), msg, filename, (duk_int_t) (line_and_code & 0x00ffffffL));\n}\n\n#else  /* DUK_USE_VERBOSE_ERRORS */\n\nDUK_INTERNAL DUK_COLD void duk_err_handle_error(duk_hthread *thr, duk_errcode_t code) {\n\tduk_err_create_and_throw(thr, code);\n}\n\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n/*\n *  Error throwing helpers\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\nDUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) {\n\tDUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, \"%s required, found %s (stack index %ld)\",\n\t                   expect_name, duk_get_type_name(thr, idx), (long) idx);\n}\n#else\nDUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) {\n\tDUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, \"%s required, found %s (stack index %ld)\",\n\t                   expect_name, duk_push_string_readable(thr, idx), (long) idx);\n}\n#endif\nDUK_INTERNAL DUK_COLD void duk_err_error_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, DUK_STR_INTERNAL_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_error_alloc_failed(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, DUK_STR_ALLOC_FAILED);\n}\nDUK_INTERNAL DUK_COLD void duk_err_error(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, message);\n}\nDUK_INTERNAL DUK_COLD void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, message);\n}\nDUK_INTERNAL DUK_COLD void duk_err_range_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx) {\n\tDUK_ERROR_RAW_FMT1(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, \"invalid stack index %ld\", (long) (idx));\n}\nDUK_INTERNAL DUK_COLD void duk_err_range_push_beyond(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, DUK_STR_PUSH_BEYOND_ALLOC_STACK);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type_invalid_args(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_ARGS);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type_invalid_state(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_STATE);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type_invalid_trap_result(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_TRAP_RESULT);\n}\n#else\n/* The file/line arguments are NULL and 0, they're ignored by DUK_ERROR_RAW()\n * when non-verbose errors are used.\n */\n\nDUK_NORETURN(DUK_LOCAL_DECL void duk__err_shared(duk_hthread *thr, duk_errcode_t code));\nDUK_LOCAL void duk__err_shared(duk_hthread *thr, duk_errcode_t code) {\n\tDUK_ERROR_RAW(thr, NULL, 0, code, NULL);\n}\nDUK_INTERNAL DUK_COLD void duk_err_error(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_range(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_RANGE_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_eval(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_EVAL_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_reference(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_REFERENCE_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_syntax(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_SYNTAX_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_TYPE_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_uri(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_URI_ERROR);\n}\n#endif\n\n/*\n *  Default fatal error handler\n */\n\nDUK_INTERNAL DUK_COLD void duk_default_fatal_handler(void *udata, const char *msg) {\n\tDUK_UNREF(udata);\n\tDUK_UNREF(msg);\n\n\tmsg = msg ? msg : \"NULL\";\n\n#if defined(DUK_USE_FATAL_HANDLER)\n\t/* duk_config.h provided a custom default fatal handler. */\n\tDUK_D(DUK_DPRINT(\"custom default fatal error handler called: %s\", msg));\n\tDUK_USE_FATAL_HANDLER(udata, msg);\n#elif defined(DUK_USE_CPP_EXCEPTIONS)\n\t/* With C++ use a duk_fatal_exception which user code can catch in\n\t * a natural way.\n\t */\n\tDUK_D(DUK_DPRINT(\"built-in default C++ fatal error handler called: %s\", msg));\n\tthrow duk_fatal_exception(msg);\n#else\n\t/* Default behavior is to abort() on error.  There's no printout\n\t * which makes this awkward, so it's always recommended to use an\n\t * explicit fatal error handler.\n\t *\n\t * ====================================================================\n\t * NOTE: If you are seeing this, you are most likely dealing with an\n\t * uncaught error.  You should provide a fatal error handler in Duktape\n\t * heap creation, and should consider using a protected call as your\n\t * first call into an empty Duktape context to properly handle errors.\n\t * See:\n\t *   - http://duktape.org/guide.html#error-handling\n\t *   - http://wiki.duktape.org/HowtoFatalErrors.html\n\t *   - http://duktape.org/api.html#taglist-protected\n\t * ====================================================================\n\t */\n\tDUK_D(DUK_DPRINT(\"built-in default fatal error handler called: %s\", msg));\n\tDUK_ABORT();\n#endif\n\n\tDUK_D(DUK_DPRINT(\"fatal error handler returned, enter forever loop\"));\n\tfor (;;) {\n\t\t/* Loop forever to ensure we don't return. */\n\t}\n}\n\n/* automatic undefs */\n#undef DUK__ERRFMT_BUFSIZE\n/*\n *  Various Unicode help functions for character classification predicates,\n *  case conversion, decoding, etc.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Fast path tables\n */\n\n#if defined(DUK_USE_IDCHAR_FASTPATH)\nDUK_INTERNAL const duk_int8_t duk_is_idchar_tab[128] = {\n\t/* 0: not IdentifierStart or IdentifierPart\n\t * 1: IdentifierStart and IdentifierPart\n\t * -1: IdentifierPart only\n\t */\n\t0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   /* 0x00...0x0f */\n\t0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   /* 0x10...0x1f */\n\t0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   /* 0x20...0x2f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0,  0,  0,  0,  0,  0,   /* 0x30...0x3f */\n\t0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,   /* 0x40...0x4f */\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  1,   /* 0x50...0x5f */\n\t0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,   /* 0x60...0x6f */\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0    /* 0x70...0x7f */\n};\n#endif\n\n/*\n *  XUTF-8 and CESU-8 encoding/decoding\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_get_xutf8_length(duk_ucodepoint_t cp) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tif (x < 0x80UL) {\n\t\t/* 7 bits */\n\t\treturn 1;\n\t} else if (x < 0x800UL) {\n\t\t/* 11 bits */\n\t\treturn 2;\n\t} else if (x < 0x10000UL) {\n\t\t/* 16 bits */\n\t\treturn 3;\n\t} else if (x < 0x200000UL) {\n\t\t/* 21 bits */\n\t\treturn 4;\n\t} else if (x < 0x4000000UL) {\n\t\t/* 26 bits */\n\t\treturn 5;\n\t} else if (x < (duk_ucodepoint_t) 0x80000000UL) {\n\t\t/* 31 bits */\n\t\treturn 6;\n\t} else {\n\t\t/* 36 bits */\n\t\treturn 7;\n\t}\n}\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL duk_small_int_t duk_unicode_get_cesu8_length(duk_ucodepoint_t cp) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tif (x < 0x80UL) {\n\t\t/* 7 bits */\n\t\treturn 1;\n\t} else if (x < 0x800UL) {\n\t\t/* 11 bits */\n\t\treturn 2;\n\t} else if (x < 0x10000UL) {\n\t\t/* 16 bits */\n\t\treturn 3;\n\t} else {\n\t\t/* Encoded as surrogate pair, each encoding to 3 bytes for\n\t\t * 6 bytes total.  Codepoints above U+10FFFF encode as 6 bytes\n\t\t * too, see duk_unicode_encode_cesu8().\n\t\t  */\n\t\treturn 3 + 3;\n\t}\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\nDUK_INTERNAL const duk_uint8_t duk_unicode_xutf8_markers[7] = {\n\t0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe\n};\n\n/* Encode to extended UTF-8; 'out' must have space for at least\n * DUK_UNICODE_MAX_XUTF8_LENGTH bytes.  Allows encoding of any\n * 32-bit (unsigned) codepoint.\n */\nDUK_INTERNAL duk_small_int_t duk_unicode_encode_xutf8(duk_ucodepoint_t cp, duk_uint8_t *out) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tduk_small_int_t len;\n\tduk_uint8_t marker;\n\tduk_small_int_t i;\n\n\tlen = duk_unicode_get_xutf8_length(cp);\n\tDUK_ASSERT(len > 0);\n\n\tmarker = duk_unicode_xutf8_markers[len - 1];  /* 64-bit OK because always >= 0 */\n\n\ti = len;\n\tDUK_ASSERT(i > 0);\n\tdo {\n\t\ti--;\n\t\tif (i > 0) {\n\t\t\tout[i] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\t\tx >>= 6;\n\t\t} else {\n\t\t\t/* Note: masking of 'x' is not necessary because of\n\t\t\t * range check and shifting -> no bits overlapping\n\t\t\t * the marker should be set.\n\t\t\t */\n\t\t\tout[0] = (duk_uint8_t) (marker + x);\n\t\t}\n\t} while (i > 0);\n\n\treturn len;\n}\n\n/* Encode to CESU-8; 'out' must have space for at least\n * DUK_UNICODE_MAX_CESU8_LENGTH bytes; codepoints above U+10FFFF\n * will encode to garbage but won't overwrite the output buffer.\n */\nDUK_INTERNAL duk_small_int_t duk_unicode_encode_cesu8(duk_ucodepoint_t cp, duk_uint8_t *out) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tduk_small_int_t len;\n\n\tif (x < 0x80UL) {\n\t\tout[0] = (duk_uint8_t) x;\n\t\tlen = 1;\n\t} else if (x < 0x800UL) {\n\t\tout[0] = (duk_uint8_t) (0xc0 + ((x >> 6) & 0x1f));\n\t\tout[1] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\tlen = 2;\n\t} else if (x < 0x10000UL) {\n\t\t/* surrogate pairs get encoded here */\n\t\tout[0] = (duk_uint8_t) (0xe0 + ((x >> 12) & 0x0f));\n\t\tout[1] = (duk_uint8_t) (0x80 + ((x >> 6) & 0x3f));\n\t\tout[2] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\tlen = 3;\n\t} else {\n\t\t/*\n\t\t *  Unicode codepoints above U+FFFF are encoded as surrogate\n\t\t *  pairs here.  This ensures that all CESU-8 codepoints are\n\t\t *  16-bit values as expected in ECMAScript.  The surrogate\n\t\t *  pairs always get a 3-byte encoding (each) in CESU-8.\n\t\t *  See: http://en.wikipedia.org/wiki/Surrogate_pair\n\t\t *\n\t\t *  20-bit codepoint, 10 bits (A and B) per surrogate pair:\n\t\t *\n\t\t *    x = 0b00000000 0000AAAA AAAAAABB BBBBBBBB\n\t\t *  sp1 = 0b110110AA AAAAAAAA  (0xd800 + ((x >> 10) & 0x3ff))\n\t\t *  sp2 = 0b110111BB BBBBBBBB  (0xdc00 + (x & 0x3ff))\n\t\t *\n\t\t *  Encoded into CESU-8:\n\t\t *\n\t\t *  sp1 -> 0b11101101  (0xe0 + ((sp1 >> 12) & 0x0f))\n\t\t *      -> 0b1010AAAA  (0x80 + ((sp1 >> 6) & 0x3f))\n\t\t *      -> 0b10AAAAAA  (0x80 + (sp1 & 0x3f))\n\t\t *  sp2 -> 0b11101101  (0xe0 + ((sp2 >> 12) & 0x0f))\n\t\t *      -> 0b1011BBBB  (0x80 + ((sp2 >> 6) & 0x3f))\n\t\t *      -> 0b10BBBBBB  (0x80 + (sp2 & 0x3f))\n\t\t *\n\t\t *  Note that 0x10000 must be subtracted first.  The code below\n\t\t *  avoids the sp1, sp2 temporaries which saves around 20 bytes\n\t\t *  of code.\n\t\t */\n\n\t\tx -= 0x10000UL;\n\n\t\tout[0] = (duk_uint8_t) (0xed);\n\t\tout[1] = (duk_uint8_t) (0xa0 + ((x >> 16) & 0x0f));\n\t\tout[2] = (duk_uint8_t) (0x80 + ((x >> 10) & 0x3f));\n\t\tout[3] = (duk_uint8_t) (0xed);\n\t\tout[4] = (duk_uint8_t) (0xb0 + ((x >> 6) & 0x0f));\n\t\tout[5] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\tlen = 6;\n\t}\n\n\treturn len;\n}\n\n/* Decode helper.  Return zero on error. */\nDUK_INTERNAL duk_small_int_t duk_unicode_decode_xutf8(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_ucodepoint_t *out_cp) {\n\tconst duk_uint8_t *p;\n\tduk_uint32_t res;\n\tduk_uint_fast8_t ch;\n\tduk_small_int_t n;\n\n\tDUK_UNREF(thr);\n\n\tp = *ptr;\n\tif (p < ptr_start || p >= ptr_end) {\n\t\tgoto fail;\n\t}\n\n\t/*\n\t *  UTF-8 decoder which accepts longer than standard byte sequences.\n\t *  This allows full 32-bit code points to be used.\n\t */\n\n\tch = (duk_uint_fast8_t) (*p++);\n\tif (ch < 0x80) {\n\t\t/* 0xxx xxxx   [7 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x7f);\n\t\tn = 0;\n\t} else if (ch < 0xc0) {\n\t\t/* 10xx xxxx -> invalid */\n\t\tgoto fail;\n\t} else if (ch < 0xe0) {\n\t\t/* 110x xxxx   10xx xxxx   [11 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x1f);\n\t\tn = 1;\n\t} else if (ch < 0xf0) {\n\t\t/* 1110 xxxx   10xx xxxx   10xx xxxx   [16 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x0f);\n\t\tn = 2;\n\t} else if (ch < 0xf8) {\n\t\t/* 1111 0xxx   10xx xxxx   10xx xxxx   10xx xxxx   [21 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x07);\n\t\tn = 3;\n\t} else if (ch < 0xfc) {\n\t\t/* 1111 10xx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [26 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x03);\n\t\tn = 4;\n\t} else if (ch < 0xfe) {\n\t\t/* 1111 110x   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [31 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x01);\n\t\tn = 5;\n\t} else if (ch < 0xff) {\n\t\t/* 1111 1110   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [36 bits] */\n\t\tres = (duk_uint32_t) (0);\n\t\tn = 6;\n\t} else {\n\t\t/* 8-byte format could be:\n\t\t * 1111 1111   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [41 bits]\n\t\t *\n\t\t * However, this format would not have a zero bit following the\n\t\t * leading one bits and would not allow 0xFF to be used as an\n\t\t * \"invalid xutf-8\" marker for internal keys.  Further, 8-byte\n\t\t * encodings (up to 41 bit code points) are not currently needed.\n\t\t */\n\t\tgoto fail;\n\t}\n\n\tDUK_ASSERT(p >= ptr_start);  /* verified at beginning */\n\tif (p + n > ptr_end) {\n\t\t/* check pointer at end */\n\t\tgoto fail;\n\t}\n\n\twhile (n > 0) {\n\t\tDUK_ASSERT(p >= ptr_start && p < ptr_end);\n\t\tch = (duk_uint_fast8_t) (*p++);\n#if 0\n\t\tif (ch & 0xc0 != 0x80) {\n\t\t\t/* not a continuation byte */\n\t\t\tp--;\n\t\t\t*ptr = p;\n\t\t\t*out_cp = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\treturn 1;\n\t\t}\n#endif\n\t\tres = (res << 6) + (duk_uint32_t) (ch & 0x3f);\n\t\tn--;\n\t}\n\n\t*ptr = p;\n\t*out_cp = res;\n\treturn 1;\n\n fail:\n\treturn 0;\n}\n\n/* used by e.g. duk_regexp_executor.c, string built-ins */\nDUK_INTERNAL duk_ucodepoint_t duk_unicode_decode_xutf8_checked(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end) {\n\tduk_ucodepoint_t cp;\n\n\tif (duk_unicode_decode_xutf8(thr, ptr, ptr_start, ptr_end, &cp)) {\n\t\treturn cp;\n\t}\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Compute (extended) utf-8 length without codepoint encoding validation,\n * used for string interning.\n *\n * NOTE: This algorithm is performance critical, more so than string hashing\n * in some cases.  It is needed when interning a string and needs to scan\n * every byte of the string with no skipping.  Having an ASCII fast path\n * is useful if possible in the algorithm.  The current algorithms were\n * chosen from several variants, based on x64 gcc -O2 testing.  See:\n * https://github.com/svaarala/duktape/pull/422\n *\n * NOTE: must match tools/dukutil.py:duk_unicode_unvalidated_utf8_length().\n */\n\n#if defined(DUK_USE_PREFER_SIZE)\n/* Small variant; roughly 150 bytes smaller than the fast variant. */\nDUK_INTERNAL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_size_t ncont;\n\tduk_size_t clen;\n\n\tp = data;\n\tp_end = data + blen;\n\tncont = 0;\n\twhile (p != p_end) {\n\t\tduk_uint8_t x;\n\t\tx = *p++;\n\t\tif (DUK_UNLIKELY(x >= 0x80 && x <= 0xbf)) {\n\t\t\tncont++;\n\t\t}\n\t}\n\n\tDUK_ASSERT(ncont <= blen);\n\tclen = blen - ncont;\n\tDUK_ASSERT(clen <= blen);\n\treturn clen;\n}\n#else  /* DUK_USE_PREFER_SIZE */\n/* This seems like a good overall approach.  Fast path for ASCII in 4 byte\n * blocks.\n */\nDUK_INTERNAL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint32_t *p32_end;\n\tconst duk_uint32_t *p32;\n\tduk_size_t ncont;\n\tduk_size_t clen;\n\n\tncont = 0;  /* number of continuation (non-initial) bytes in [0x80,0xbf] */\n\tp = data;\n\tp_end = data + blen;\n\tif (blen < 16) {\n\t\tgoto skip_fastpath;\n\t}\n\n\t/* Align 'p' to 4; the input data may have arbitrary alignment.\n\t * End of string check not needed because blen >= 16.\n\t */\n\twhile (((duk_size_t) (const void *) p) & 0x03U) {\n\t\tduk_uint8_t x;\n\t\tx = *p++;\n\t\tif (DUK_UNLIKELY(x >= 0x80 && x <= 0xbf)) {\n\t\t\tncont++;\n\t\t}\n\t}\n\n\t/* Full, aligned 4-byte reads. */\n\tp32_end = (const duk_uint32_t *) (const void *) (p + ((duk_size_t) (p_end - p) & (duk_size_t) (~0x03)));\n\tp32 = (const duk_uint32_t *) (const void *) p;\n\twhile (p32 != (const duk_uint32_t *) p32_end) {\n\t\tduk_uint32_t x;\n\t\tx = *p32++;\n\t\tif (DUK_LIKELY((x & 0x80808080UL) == 0)) {\n\t\t\t;  /* ASCII fast path */\n\t\t} else {\n\t\t\t/* Flip highest bit of each byte which changes\n\t\t\t * the bit pattern 10xxxxxx into 00xxxxxx which\n\t\t\t * allows an easy bit mask test.\n\t\t\t */\n\t\t\tx ^= 0x80808080UL;\n\t\t\tif (DUK_UNLIKELY(!(x & 0xc0000000UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(!(x & 0x00c00000UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(!(x & 0x0000c000UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(!(x & 0x000000c0UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t}\n\t}\n\tp = (const duk_uint8_t *) p32;\n\t/* Fall through to handle the rest. */\n\n skip_fastpath:\n\twhile (p != p_end) {\n\t\tduk_uint8_t x;\n\t\tx = *p++;\n\t\tif (DUK_UNLIKELY(x >= 0x80 && x <= 0xbf)) {\n\t\t\tncont++;\n\t\t}\n\t}\n\n\tDUK_ASSERT(ncont <= blen);\n\tclen = blen - ncont;\n\tDUK_ASSERT(clen <= blen);\n\treturn clen;\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/*\n *  Unicode range matcher\n *\n *  Matches a codepoint against a packed bitstream of character ranges.\n *  Used for slow path Unicode matching.\n */\n\n/* Must match tools/extract_chars.py, generate_match_table3(). */\nDUK_LOCAL duk_uint32_t duk__uni_decode_value(duk_bitdecoder_ctx *bd_ctx) {\n\tduk_uint32_t t;\n\n\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 4);\n\tif (t <= 0x0eU) {\n\t\treturn t;\n\t}\n\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 8);\n\tif (t <= 0xfdU) {\n\t\treturn t + 0x0f;\n\t}\n\tif (t == 0xfeU) {\n\t\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 12);\n\t\treturn t + 0x0fU + 0xfeU;\n\t} else {\n\t\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 24);\n\t\treturn t + 0x0fU + 0xfeU + 0x1000UL;\n\t}\n}\n\nDUK_LOCAL duk_small_int_t duk__uni_range_match(const duk_uint8_t *unitab, duk_size_t unilen, duk_codepoint_t cp) {\n\tduk_bitdecoder_ctx bd_ctx;\n\tduk_codepoint_t prev_re;\n\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tbd_ctx.data = (const duk_uint8_t *) unitab;\n\tbd_ctx.length = (duk_size_t) unilen;\n\n\tprev_re = 0;\n\tfor (;;) {\n\t\tduk_codepoint_t r1, r2;\n\t\tr1 = (duk_codepoint_t) duk__uni_decode_value(&bd_ctx);\n\t\tif (r1 == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tr2 = (duk_codepoint_t) duk__uni_decode_value(&bd_ctx);\n\n\t\tr1 = prev_re + r1;\n\t\tr2 = r1 + r2;\n\t\tprev_re = r2;\n\n\t\t/* [r1,r2] is the range */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__uni_range_match: cp=%06lx range=[0x%06lx,0x%06lx]\",\n\t\t                     (unsigned long) cp, (unsigned long) r1, (unsigned long) r2));\n\t\tif (cp >= r1 && cp <= r2) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n/*\n *  \"WhiteSpace\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_whitespace(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.2 specifies six characters specifically as\n\t *  white space:\n\t *\n\t *    0009;<control>;Cc;0;S;;;;;N;CHARACTER TABULATION;;;;\n\t *    000B;<control>;Cc;0;S;;;;;N;LINE TABULATION;;;;\n\t *    000C;<control>;Cc;0;WS;;;;;N;FORM FEED (FF);;;;\n\t *    0020;SPACE;Zs;0;WS;;;;;N;;;;;\n\t *    00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;\n\t *    FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;;\n\t *\n\t *  It also specifies any Unicode category 'Zs' characters as white\n\t *  space.  These can be extracted with the \"tools/extract_chars.py\" script.\n\t *  Current result:\n\t *\n\t *    RAW OUTPUT:\n\t *    ===========\n\t *    0020;SPACE;Zs;0;WS;;;;;N;;;;;\n\t *    00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;\n\t *    1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;;\n\t *    180E;MONGOLIAN VOWEL SEPARATOR;Zs;0;WS;;;;;N;;;;;\n\t *    2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;;\n\t *    2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;;\n\t *    2002;EN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2003;EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2004;THREE-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2005;FOUR-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2006;SIX-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2007;FIGURE SPACE;Zs;0;WS;<noBreak> 0020;;;;N;;;;;\n\t *    2008;PUNCTUATION SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2009;THIN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    200A;HAIR SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    202F;NARROW NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;;;;;\n\t *    205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    3000;IDEOGRAPHIC SPACE;Zs;0;WS;<wide> 0020;;;;N;;;;;\n\t *\n\t *    RANGES:\n\t *    =======\n\t *    0x0020\n\t *    0x00a0\n\t *    0x1680\n\t *    0x180e\n\t *    0x2000 ... 0x200a\n\t *    0x202f\n\t *    0x205f\n\t *    0x3000\n\t *\n\t *  A manual decoder (below) is probably most compact for this.\n\t */\n\n\tduk_uint_fast8_t lo;\n\tduk_uint_fast32_t hi;\n\n\t/* cp == -1 (EOF) never matches and causes return value 0 */\n\n\tlo = (duk_uint_fast8_t) (cp & 0xff);\n\thi = (duk_uint_fast32_t) (cp >> 8);  /* does not fit into an uchar */\n\n\tif (hi == 0x0000UL) {\n\t\tif (lo == 0x09U || lo == 0x0bU || lo == 0x0cU ||\n\t\t    lo == 0x20U || lo == 0xa0U) {\n\t\t\treturn 1;\n\t\t}\n\t} else if (hi == 0x0020UL) {\n\t\tif (lo <= 0x0aU || lo == 0x2fU || lo == 0x5fU) {\n\t\t\treturn 1;\n\t\t}\n\t} else if (cp == 0x1680L || cp == 0x180eL || cp == 0x3000L ||\n\t           cp == 0xfeffL) {\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n/*\n *  \"LineTerminator\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_line_terminator(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.3\n\t *\n\t *  A LineTerminatorSequence essentially merges <CR> <LF> sequences\n\t *  into a single line terminator.  This must be handled by the caller.\n\t */\n\n\tif (cp == 0x000aL || cp == 0x000dL || cp == 0x2028L ||\n\t    cp == 0x2029L) {\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n/*\n *  \"IdentifierStart\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_identifier_start(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.6:\n\t *\n\t *    IdentifierStart:\n\t *      UnicodeLetter\n\t *      $\n\t *      _\n\t *      \\ UnicodeEscapeSequence\n\t *\n\t *  IdentifierStart production has one multi-character production:\n\t *\n\t *    \\ UnicodeEscapeSequence\n\t *\n\t *  The '\\' character is -not- matched by this function.  Rather, the caller\n\t *  should decode the escape and then call this function to check whether the\n\t *  decoded character is acceptable (see discussion in E5 Section 7.6).\n\t *\n\t *  The \"UnicodeLetter\" alternative of the production allows letters\n\t *  from various Unicode categories.  These can be extracted with the\n\t *  \"tools/extract_chars.py\" script.\n\t *\n\t *  Because the result has hundreds of Unicode codepoint ranges, matching\n\t *  for any values >= 0x80 are done using a very slow range-by-range scan\n\t *  and a packed range format.\n\t *\n\t *  The ASCII portion (codepoints 0x00 ... 0x7f) is fast-pathed below because\n\t *  it matters the most.  The ASCII related ranges of IdentifierStart are:\n\t *\n\t *    0x0041 ... 0x005a     ['A' ... 'Z']\n\t *    0x0061 ... 0x007a     ['a' ... 'z']\n\t *    0x0024                ['$']\n\t *    0x005f                ['_']\n\t */\n\n\t/* ASCII (and EOF) fast path -- quick accept and reject */\n\tif (cp <= 0x7fL) {\n#if defined(DUK_USE_IDCHAR_FASTPATH)\n\t\treturn (cp >= 0) && (duk_is_idchar_tab[cp] > 0);\n#else\n\t\tif ((cp >= 'a' && cp <= 'z') ||\n\t\t    (cp >= 'A' && cp <= 'Z') ||\n\t\t    cp == '_' || cp == '$') {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n#endif\n\t}\n\n\t/* Non-ASCII slow path (range-by-range linear comparison), very slow */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n\tif (duk__uni_range_match(duk_unicode_ids_noa,\n\t                         (duk_size_t) sizeof(duk_unicode_ids_noa),\n\t                         (duk_codepoint_t) cp)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else\n\tif (cp < 0x10000L) {\n\t\tif (duk__uni_range_match(duk_unicode_ids_noabmp,\n\t\t                         sizeof(duk_unicode_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp)) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t} else {\n\t\t/* without explicit non-BMP support, assume non-BMP characters\n\t\t * are always accepted as identifier characters.\n\t\t */\n\t\treturn 1;\n\t}\n#endif\n}\n\n/*\n *  \"IdentifierPart\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_identifier_part(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.6:\n\t *\n\t *    IdentifierPart:\n\t *      IdentifierStart\n\t *      UnicodeCombiningMark\n\t *      UnicodeDigit\n\t *      UnicodeConnectorPunctuation\n\t *      <ZWNJ>  [U+200C]\n\t *      <ZWJ>   [U+200D]\n\t *\n\t *  IdentifierPart production has one multi-character production\n\t *  as part of its IdentifierStart alternative.  The '\\' character\n\t *  of an escape sequence is not matched here, see discussion in\n\t *  duk_unicode_is_identifier_start().\n\t *\n\t *  To match non-ASCII characters (codepoints >= 0x80), a very slow\n\t *  linear range-by-range scan is used.  The codepoint is first compared\n\t *  to the IdentifierStart ranges, and if it doesn't match, then to a\n\t *  set consisting of code points in IdentifierPart but not in\n\t *  IdentifierStart.  This is done to keep the unicode range data small,\n\t *  at the expense of speed.\n\t *\n\t *  The ASCII fast path consists of:\n\t *\n\t *    0x0030 ... 0x0039     ['0' ... '9', UnicodeDigit]\n\t *    0x0041 ... 0x005a     ['A' ... 'Z', IdentifierStart]\n\t *    0x0061 ... 0x007a     ['a' ... 'z', IdentifierStart]\n\t *    0x0024                ['$', IdentifierStart]\n\t *    0x005f                ['_', IdentifierStart and\n\t *                                UnicodeConnectorPunctuation]\n\t *\n\t *  UnicodeCombiningMark has no code points <= 0x7f.\n\t *\n\t *  The matching code reuses the \"identifier start\" tables, and then\n\t *  consults a separate range set for characters in \"identifier part\"\n\t *  but not in \"identifier start\".  These can be extracted with the\n\t *  \"tools/extract_chars.py\" script.\n\t *\n\t *  UnicodeCombiningMark -> categories Mn, Mc\n\t *  UnicodeDigit -> categories Nd\n\t *  UnicodeConnectorPunctuation -> categories Pc\n\t */\n\n\t/* ASCII (and EOF) fast path -- quick accept and reject */\n\tif (cp <= 0x7fL) {\n#if defined(DUK_USE_IDCHAR_FASTPATH)\n\t\treturn (cp >= 0) && (duk_is_idchar_tab[cp] != 0);\n#else\n\t\tif ((cp >= 'a' && cp <= 'z') ||\n\t\t    (cp >= 'A' && cp <= 'Z') ||\n\t\t    (cp >= '0' && cp <= '9') ||\n\t\t    cp == '_' || cp == '$') {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n#endif\n\t}\n\n\t/* Non-ASCII slow path (range-by-range linear comparison), very slow */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n\tif (duk__uni_range_match(duk_unicode_ids_noa,\n\t                         sizeof(duk_unicode_ids_noa),\n\t                         (duk_codepoint_t) cp) ||\n\t    duk__uni_range_match(duk_unicode_idp_m_ids_noa,\n\t                         sizeof(duk_unicode_idp_m_ids_noa),\n\t                         (duk_codepoint_t) cp)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else\n\tif (cp < 0x10000L) {\n\t\tif (duk__uni_range_match(duk_unicode_ids_noabmp,\n\t\t                         sizeof(duk_unicode_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp) ||\n\t\t    duk__uni_range_match(duk_unicode_idp_m_ids_noabmp,\n\t\t                         sizeof(duk_unicode_idp_m_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp)) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t} else {\n\t\t/* without explicit non-BMP support, assume non-BMP characters\n\t\t * are always accepted as identifier characters.\n\t\t */\n\t\treturn 1;\n\t}\n#endif\n}\n\n/*\n *  Unicode letter check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_letter(duk_codepoint_t cp) {\n\t/*\n\t *  Unicode letter is now taken to be the categories:\n\t *\n\t *    Lu, Ll, Lt, Lm, Lo\n\t *\n\t *  (Not sure if this is exactly correct.)\n\t *\n\t *  The ASCII fast path consists of:\n\t *\n\t *    0x0041 ... 0x005a     ['A' ... 'Z']\n\t *    0x0061 ... 0x007a     ['a' ... 'z']\n\t */\n\n\t/* ASCII (and EOF) fast path -- quick accept and reject */\n\tif (cp <= 0x7fL) {\n\t\tif ((cp >= 'a' && cp <= 'z') ||\n\t\t    (cp >= 'A' && cp <= 'Z')) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t}\n\n\t/* Non-ASCII slow path (range-by-range linear comparison), very slow */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n\tif (duk__uni_range_match(duk_unicode_ids_noa,\n\t                         sizeof(duk_unicode_ids_noa),\n\t                         (duk_codepoint_t) cp) &&\n\t    !duk__uni_range_match(duk_unicode_ids_m_let_noa,\n\t                          sizeof(duk_unicode_ids_m_let_noa),\n\t                          (duk_codepoint_t) cp)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else\n\tif (cp < 0x10000L) {\n\t\tif (duk__uni_range_match(duk_unicode_ids_noabmp,\n\t\t                         sizeof(duk_unicode_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp) &&\n\t\t    !duk__uni_range_match(duk_unicode_ids_m_let_noabmp,\n\t\t                          sizeof(duk_unicode_ids_m_let_noabmp),\n\t\t                          (duk_codepoint_t) cp)) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t} else {\n\t\t/* without explicit non-BMP support, assume non-BMP characters\n\t\t * are always accepted as letters.\n\t\t */\n\t\treturn 1;\n\t}\n#endif\n}\n\n/*\n *  Complex case conversion helper which decodes a bit-packed conversion\n *  control stream generated by tools/extract_caseconv.py.  The conversion\n *  is very slow because it runs through the conversion data in a linear\n *  fashion to save space (which is why ASCII characters have a special\n *  fast path before arriving here).\n *\n *  The particular bit counts etc have been determined experimentally to\n *  be small but still sufficient, and must match the Python script\n *  (tools/extract_caseconv.py).\n *\n *  The return value is the case converted codepoint or -1 if the conversion\n *  results in multiple characters (this is useful for regexp Canonicalization\n *  operation).  If 'buf' is not NULL, the result codepoint(s) are also\n *  appended to the hbuffer.\n *\n *  Context and locale specific rules must be checked before consulting\n *  this function.\n */\n\nDUK_LOCAL\nduk_codepoint_t duk__slow_case_conversion(duk_hthread *thr,\n                                          duk_bufwriter_ctx *bw,\n                                          duk_codepoint_t cp,\n                                          duk_bitdecoder_ctx *bd_ctx) {\n\tduk_small_int_t skip = 0;\n\tduk_small_int_t n;\n\tduk_small_int_t t;\n\tduk_small_int_t count;\n\tduk_codepoint_t tmp_cp;\n\tduk_codepoint_t start_i;\n\tduk_codepoint_t start_o;\n\n\tDUK_ASSERT(bd_ctx != NULL);\n\tDUK_UNREF(thr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"slow case conversion for codepoint: %ld\", (long) cp));\n\n\t/* range conversion with a \"skip\" */\n\tDUK_DDD(DUK_DDDPRINT(\"checking ranges\"));\n\tfor (;;) {\n\t\tskip++;\n\t\tn = (duk_small_int_t) duk_bd_decode(bd_ctx, 6);\n\t\tif (n == 0x3f) {\n\t\t\t/* end marker */\n\t\t\tbreak;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"skip=%ld, n=%ld\", (long) skip, (long) n));\n\n\t\twhile (n--) {\n\t\t\tstart_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\t\tstart_o = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\t\tcount = (duk_small_int_t) duk_bd_decode(bd_ctx, 7);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"range: start_i=%ld, start_o=%ld, count=%ld, skip=%ld\",\n\t\t\t                     (long) start_i, (long) start_o, (long) count, (long) skip));\n\n\t\t\tif (cp >= start_i) {\n\t\t\t\ttmp_cp = cp - start_i;  /* always >= 0 */\n\t\t\t\tif (tmp_cp < (duk_codepoint_t) count * (duk_codepoint_t) skip &&\n\t\t\t\t    (tmp_cp % (duk_codepoint_t) skip) == 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"range matches input codepoint\"));\n\t\t\t\t\tcp = start_o + tmp_cp;\n\t\t\t\t\tgoto single;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/* 1:1 conversion */\n\tn = (duk_small_int_t) duk_bd_decode(bd_ctx, 7);\n\tDUK_DDD(DUK_DDDPRINT(\"checking 1:1 conversions (count %ld)\", (long) n));\n\twhile (n--) {\n\t\tstart_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\tstart_o = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\tDUK_DDD(DUK_DDDPRINT(\"1:1 conversion %ld -> %ld\", (long) start_i, (long) start_o));\n\t\tif (cp == start_i) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"1:1 matches input codepoint\"));\n\t\t\tcp = start_o;\n\t\t\tgoto single;\n\t\t}\n\t}\n\n\t/* complex, multicharacter conversion */\n\tn = (duk_small_int_t) duk_bd_decode(bd_ctx, 7);\n\tDUK_DDD(DUK_DDDPRINT(\"checking 1:n conversions (count %ld)\", (long) n));\n\twhile (n--) {\n\t\tstart_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\tt = (duk_small_int_t) duk_bd_decode(bd_ctx, 2);\n\t\tDUK_DDD(DUK_DDDPRINT(\"1:n conversion %ld -> %ld chars\", (long) start_i, (long) t));\n\t\tif (cp == start_i) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"1:n matches input codepoint\"));\n\t\t\tif (bw != NULL) {\n\t\t\t\twhile (t--) {\n\t\t\t\t\ttmp_cp = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\t\t\t\tDUK_BW_WRITE_RAW_XUTF8(thr, bw, (duk_ucodepoint_t) tmp_cp);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t} else {\n\t\t\twhile (t--) {\n\t\t\t\t(void) duk_bd_decode(bd_ctx, 16);\n\t\t\t}\n\t\t}\n\t}\n\n\t/* default: no change */\n\tDUK_DDD(DUK_DDDPRINT(\"no rule matches, output is same as input\"));\n\t/* fall through */\n\n single:\n\tif (bw != NULL) {\n\t\tDUK_BW_WRITE_RAW_XUTF8(thr, bw, (duk_ucodepoint_t) cp);\n\t}\n\treturn cp;\n}\n\n/*\n *  Case conversion helper, with context/local sensitivity.\n *  For proper case conversion, one needs to know the character\n *  and the preceding and following characters, as well as\n *  locale/language.\n */\n\n/* XXX: add 'language' argument when locale/language sensitive rule\n * support added.\n */\nDUK_LOCAL\nduk_codepoint_t duk__case_transform_helper(duk_hthread *thr,\n                                           duk_bufwriter_ctx *bw,\n                                           duk_codepoint_t cp,\n                                           duk_codepoint_t prev,\n                                           duk_codepoint_t next,\n                                           duk_bool_t uppercase) {\n\tduk_bitdecoder_ctx bd_ctx;\n\n\t/* fast path for ASCII */\n\tif (cp < 0x80L) {\n\t\t/* XXX: there are language sensitive rules for the ASCII range.\n\t\t * If/when language/locale support is implemented, they need to\n\t\t * be implemented here for the fast path.  There are no context\n\t\t * sensitive rules for ASCII range.\n\t\t */\n\n\t\tif (uppercase) {\n\t\t\tif (cp >= 'a' && cp <= 'z') {\n\t\t\t\tcp = cp - 'a' + 'A';\n\t\t\t}\n\t\t} else {\n\t\t\tif (cp >= 'A' && cp <= 'Z') {\n\t\t\t\tcp = cp - 'A' + 'a';\n\t\t\t}\n\t\t}\n\n\t\tif (bw != NULL) {\n\t\t\tDUK_BW_WRITE_RAW_U8(thr, bw, (duk_uint8_t) cp);\n\t\t}\n\t\treturn cp;\n\t}\n\n\t/* context and locale specific rules which cannot currently be represented\n\t * in the caseconv bitstream: hardcoded rules in C\n\t */\n\tif (uppercase) {\n\t\t/* XXX: turkish / azeri */\n\t} else {\n\t\t/*\n\t\t *  Final sigma context specific rule.  This is a rather tricky\n\t\t *  rule and this handling is probably not 100% correct now.\n\t\t *  The rule is not locale/language specific so it is supported.\n\t\t */\n\n\t\tif (cp == 0x03a3L &&    /* U+03A3 = GREEK CAPITAL LETTER SIGMA */\n\t\t    duk_unicode_is_letter(prev) &&        /* prev exists and is not a letter */\n\t\t    !duk_unicode_is_letter(next)) {       /* next does not exist or next is not a letter */\n\t\t\t/* Capital sigma occurred at \"end of word\", lowercase to\n\t\t\t * U+03C2 = GREEK SMALL LETTER FINAL SIGMA.  Otherwise\n\t\t\t * fall through and let the normal rules lowercase it to\n\t\t\t * U+03C3 = GREEK SMALL LETTER SIGMA.\n\t\t\t */\n\t\t\tcp = 0x03c2L;\n\t\t\tgoto singlechar;\n\t\t}\n\n\t\t/* XXX: lithuanian not implemented */\n\t\t/* XXX: lithuanian, explicit dot rules */\n\t\t/* XXX: turkish / azeri, lowercase rules */\n\t}\n\n\t/* 1:1 or special conversions, but not locale/context specific: script generated rules */\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tif (uppercase) {\n\t\tbd_ctx.data = (const duk_uint8_t *) duk_unicode_caseconv_uc;\n\t\tbd_ctx.length = (duk_size_t) sizeof(duk_unicode_caseconv_uc);\n\t} else {\n\t\tbd_ctx.data = (const duk_uint8_t *) duk_unicode_caseconv_lc;\n\t\tbd_ctx.length = (duk_size_t) sizeof(duk_unicode_caseconv_lc);\n\t}\n\treturn duk__slow_case_conversion(thr, bw, cp, &bd_ctx);\n\n singlechar:\n\tif (bw != NULL) {\n\t\tDUK_BW_WRITE_RAW_XUTF8(thr, bw, (duk_ucodepoint_t) cp);\n\t}\n\treturn cp;\n\n /* unused now, not needed until Turkish/Azeri */\n#if 0\n nochar:\n\treturn -1;\n#endif\n}\n\n/*\n *  Replace valstack top with case converted version.\n */\n\nDUK_INTERNAL void duk_unicode_case_convert_string(duk_hthread *thr, duk_bool_t uppercase) {\n\tduk_hstring *h_input;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_codepoint_t prev, curr, next;\n\n\th_input = duk_require_hstring(thr, -1);  /* Accept symbols. */\n\tDUK_ASSERT(h_input != NULL);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input));\n\n\t/* [ ... input buffer ] */\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\n\tprev = -1; DUK_UNREF(prev);\n\tcurr = -1;\n\tnext = -1;\n\tfor (;;) {\n\t\tprev = curr;\n\t\tcurr = next;\n\t\tnext = -1;\n\t\tif (p < p_end) {\n\t\t\tnext = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end);\n\t\t} else {\n\t\t\t/* end of input and last char has been processed */\n\t\t\tif (curr < 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* on first round, skip */\n\t\tif (curr >= 0) {\n\t\t\t/* XXX: could add a fast path to process chunks of input codepoints,\n\t\t\t * but relative benefit would be quite small.\n\t\t\t */\n\n\t\t\t/* Ensure space for maximum multi-character result; estimate is overkill. */\n\t\t\tDUK_BW_ENSURE(thr, bw, 8 * DUK_UNICODE_MAX_XUTF8_LENGTH);\n\n\t\t\tduk__case_transform_helper(thr,\n\t\t\t                           bw,\n\t\t\t                           (duk_codepoint_t) curr,\n\t\t\t                           prev,\n\t\t\t                           next,\n\t\t\t                           uppercase);\n\t\t}\n\t}\n\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe, output is encoded. */\n\t/* invalidates h_buf pointer */\n\tduk_remove_m2(thr);\n}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Canonicalize() abstract operation needed for canonicalization of individual\n *  codepoints during regexp compilation and execution, see E5 Section 15.10.2.8.\n *  Note that codepoints are canonicalized one character at a time, so no context\n *  specific rules can apply.  Locale specific rules can apply, though.\n */\n\nDUK_INTERNAL duk_codepoint_t duk_unicode_re_canonicalize_char(duk_hthread *thr, duk_codepoint_t cp) {\n#if defined(DUK_USE_REGEXP_CANON_WORKAROUND)\n\t/* Fast canonicalization lookup at the cost of 128kB footprint. */\n\tDUK_ASSERT(cp >= 0);\n\tDUK_UNREF(thr);\n\tif (DUK_LIKELY(cp < 0x10000L)) {\n\t\treturn (duk_codepoint_t) duk_unicode_re_canon_lookup[cp];\n\t}\n\treturn cp;\n#else  /* DUK_USE_REGEXP_CANON_WORKAROUND */\n\tduk_codepoint_t y;\n\n\ty = duk__case_transform_helper(thr,\n\t                               NULL,    /* NULL is allowed, no output */\n\t                               cp,      /* curr char */\n\t                               -1,      /* prev char */\n\t                               -1,      /* next char */\n\t                               1);      /* uppercase */\n\n\tif ((y < 0) || (cp >= 0x80 && y < 0x80)) {\n\t\t/* multiple codepoint conversion or non-ASCII mapped to ASCII\n\t\t * --> leave as is.\n\t\t */\n\t\treturn cp;\n\t}\n\n\treturn y;\n#endif  /* DUK_USE_REGEXP_CANON_WORKAROUND */\n}\n\n/*\n *  E5 Section 15.10.2.6 \"IsWordChar\" abstract operation.  Assume\n *  x < 0 for characters read outside the string.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_re_is_wordchar(duk_codepoint_t x) {\n\t/*\n\t *  Note: the description in E5 Section 15.10.2.6 has a typo, it\n\t *  contains 'A' twice and lacks 'a'; the intent is [0-9a-zA-Z_].\n\t */\n\tif ((x >= '0' && x <= '9') ||\n\t    (x >= 'a' && x <= 'z') ||\n\t    (x >= 'A' && x <= 'Z') ||\n\t    (x == '_')) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\n/*\n *  Regexp range tables\n */\n\n/* exposed because lexer needs these too */\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_digit[2] = {\n\t(duk_uint16_t) 0x0030UL, (duk_uint16_t) 0x0039UL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_white[22] = {\n\t(duk_uint16_t) 0x0009UL, (duk_uint16_t) 0x000DUL,\n\t(duk_uint16_t) 0x0020UL, (duk_uint16_t) 0x0020UL,\n\t(duk_uint16_t) 0x00A0UL, (duk_uint16_t) 0x00A0UL,\n\t(duk_uint16_t) 0x1680UL, (duk_uint16_t) 0x1680UL,\n\t(duk_uint16_t) 0x180EUL, (duk_uint16_t) 0x180EUL,\n\t(duk_uint16_t) 0x2000UL, (duk_uint16_t) 0x200AUL,\n\t(duk_uint16_t) 0x2028UL, (duk_uint16_t) 0x2029UL,\n\t(duk_uint16_t) 0x202FUL, (duk_uint16_t) 0x202FUL,\n\t(duk_uint16_t) 0x205FUL, (duk_uint16_t) 0x205FUL,\n\t(duk_uint16_t) 0x3000UL, (duk_uint16_t) 0x3000UL,\n\t(duk_uint16_t) 0xFEFFUL, (duk_uint16_t) 0xFEFFUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_wordchar[8] = {\n\t(duk_uint16_t) 0x0030UL, (duk_uint16_t) 0x0039UL,\n\t(duk_uint16_t) 0x0041UL, (duk_uint16_t) 0x005AUL,\n\t(duk_uint16_t) 0x005FUL, (duk_uint16_t) 0x005FUL,\n\t(duk_uint16_t) 0x0061UL, (duk_uint16_t) 0x007AUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_digit[4] = {\n\t(duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x002FUL,\n\t(duk_uint16_t) 0x003AUL, (duk_uint16_t) 0xFFFFUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_white[24] = {\n\t(duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x0008UL,\n\t(duk_uint16_t) 0x000EUL, (duk_uint16_t) 0x001FUL,\n\t(duk_uint16_t) 0x0021UL, (duk_uint16_t) 0x009FUL,\n\t(duk_uint16_t) 0x00A1UL, (duk_uint16_t) 0x167FUL,\n\t(duk_uint16_t) 0x1681UL, (duk_uint16_t) 0x180DUL,\n\t(duk_uint16_t) 0x180FUL, (duk_uint16_t) 0x1FFFUL,\n\t(duk_uint16_t) 0x200BUL, (duk_uint16_t) 0x2027UL,\n\t(duk_uint16_t) 0x202AUL, (duk_uint16_t) 0x202EUL,\n\t(duk_uint16_t) 0x2030UL, (duk_uint16_t) 0x205EUL,\n\t(duk_uint16_t) 0x2060UL, (duk_uint16_t) 0x2FFFUL,\n\t(duk_uint16_t) 0x3001UL, (duk_uint16_t) 0xFEFEUL,\n\t(duk_uint16_t) 0xFF00UL, (duk_uint16_t) 0xFFFFUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_wordchar[10] = {\n\t(duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x002FUL,\n\t(duk_uint16_t) 0x003AUL, (duk_uint16_t) 0x0040UL,\n\t(duk_uint16_t) 0x005BUL, (duk_uint16_t) 0x005EUL,\n\t(duk_uint16_t) 0x0060UL, (duk_uint16_t) 0x0060UL,\n\t(duk_uint16_t) 0x007BUL, (duk_uint16_t) 0xFFFFUL,\n};\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n/*\n *  Misc util stuff.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Lowercase digits for radix values 2 to 36.  Also doubles as lowercase\n *  hex nybble table.\n */\n\nDUK_INTERNAL const duk_uint8_t duk_lc_digits[36] = {\n\tDUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3,\n\tDUK_ASC_4, DUK_ASC_5, DUK_ASC_6, DUK_ASC_7,\n\tDUK_ASC_8, DUK_ASC_9, DUK_ASC_LC_A, DUK_ASC_LC_B,\n\tDUK_ASC_LC_C, DUK_ASC_LC_D, DUK_ASC_LC_E, DUK_ASC_LC_F,\n\tDUK_ASC_LC_G, DUK_ASC_LC_H, DUK_ASC_LC_I, DUK_ASC_LC_J,\n\tDUK_ASC_LC_K, DUK_ASC_LC_L, DUK_ASC_LC_M, DUK_ASC_LC_N,\n\tDUK_ASC_LC_O, DUK_ASC_LC_P, DUK_ASC_LC_Q, DUK_ASC_LC_R,\n\tDUK_ASC_LC_S, DUK_ASC_LC_T, DUK_ASC_LC_U, DUK_ASC_LC_V,\n\tDUK_ASC_LC_W, DUK_ASC_LC_X, DUK_ASC_LC_Y, DUK_ASC_LC_Z\n};\n\nDUK_INTERNAL const duk_uint8_t duk_uc_nybbles[16] = {\n\tDUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3,\n\tDUK_ASC_4, DUK_ASC_5, DUK_ASC_6, DUK_ASC_7,\n\tDUK_ASC_8, DUK_ASC_9, DUK_ASC_UC_A, DUK_ASC_UC_B,\n\tDUK_ASC_UC_C, DUK_ASC_UC_D, DUK_ASC_UC_E, DUK_ASC_UC_F\n};\n\n/*\n *  Table for hex decoding ASCII hex digits\n */\n\nDUK_INTERNAL const duk_int8_t duk_hex_dectab[256] = {\n\t/* -1 if invalid */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x00-0x0f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x10-0x1f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x20-0x2f */\n\t 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,  /* 0x30-0x3f */\n\t-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x40-0x4f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x50-0x5f */\n\t-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x60-0x6f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x70-0x7f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x80-0x8f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x90-0x9f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xa0-0xaf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xb0-0xbf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xc0-0xcf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xd0-0xdf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xe0-0xef */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1   /* 0xf0-0xff */\n};\n\n#if defined(DUK_USE_HEX_FASTPATH)\n/* Preshifted << 4.  Must use 16-bit entry to allow negative value signaling. */\nDUK_INTERNAL const duk_int16_t duk_hex_dectab_shift4[256] = {\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x00-0x0f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x10-0x1f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x20-0x2f */\n\t0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x30-0x3f */\n\t  -1, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x40-0x4f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x50-0x5f */\n\t  -1, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x60-0x6f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x70-0x7f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x80-0x8f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x90-0x9f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xa0-0xaf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xb0-0xbf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xc0-0xcf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xd0-0xdf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xe0-0xef */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1   /* 0xf0-0xff */\n};\n#endif\n\n/*\n *  Table for hex encoding bytes\n */\n\n#if defined(DUK_USE_HEX_FASTPATH)\n/* Lookup to encode one byte directly into 2 characters:\n *\n *   def genhextab(bswap):\n *       for i in xrange(256):\n *           t = chr(i).encode('hex')\n *           if bswap:\n *               t = t[1] + t[0]\n *           print('0x' + t.encode('hex') + 'U')\n *   print('big endian'); genhextab(False)\n *   print('little endian'); genhextab(True)\n*/\nDUK_INTERNAL const duk_uint16_t duk_hex_enctab[256] = {\n#if defined(DUK_USE_INTEGER_BE)\n\t0x3030U, 0x3031U, 0x3032U, 0x3033U, 0x3034U, 0x3035U, 0x3036U, 0x3037U,\n\t0x3038U, 0x3039U, 0x3061U, 0x3062U, 0x3063U, 0x3064U, 0x3065U, 0x3066U,\n\t0x3130U, 0x3131U, 0x3132U, 0x3133U, 0x3134U, 0x3135U, 0x3136U, 0x3137U,\n\t0x3138U, 0x3139U, 0x3161U, 0x3162U, 0x3163U, 0x3164U, 0x3165U, 0x3166U,\n\t0x3230U, 0x3231U, 0x3232U, 0x3233U, 0x3234U, 0x3235U, 0x3236U, 0x3237U,\n\t0x3238U, 0x3239U, 0x3261U, 0x3262U, 0x3263U, 0x3264U, 0x3265U, 0x3266U,\n\t0x3330U, 0x3331U, 0x3332U, 0x3333U, 0x3334U, 0x3335U, 0x3336U, 0x3337U,\n\t0x3338U, 0x3339U, 0x3361U, 0x3362U, 0x3363U, 0x3364U, 0x3365U, 0x3366U,\n\t0x3430U, 0x3431U, 0x3432U, 0x3433U, 0x3434U, 0x3435U, 0x3436U, 0x3437U,\n\t0x3438U, 0x3439U, 0x3461U, 0x3462U, 0x3463U, 0x3464U, 0x3465U, 0x3466U,\n\t0x3530U, 0x3531U, 0x3532U, 0x3533U, 0x3534U, 0x3535U, 0x3536U, 0x3537U,\n\t0x3538U, 0x3539U, 0x3561U, 0x3562U, 0x3563U, 0x3564U, 0x3565U, 0x3566U,\n\t0x3630U, 0x3631U, 0x3632U, 0x3633U, 0x3634U, 0x3635U, 0x3636U, 0x3637U,\n\t0x3638U, 0x3639U, 0x3661U, 0x3662U, 0x3663U, 0x3664U, 0x3665U, 0x3666U,\n\t0x3730U, 0x3731U, 0x3732U, 0x3733U, 0x3734U, 0x3735U, 0x3736U, 0x3737U,\n\t0x3738U, 0x3739U, 0x3761U, 0x3762U, 0x3763U, 0x3764U, 0x3765U, 0x3766U,\n\t0x3830U, 0x3831U, 0x3832U, 0x3833U, 0x3834U, 0x3835U, 0x3836U, 0x3837U,\n\t0x3838U, 0x3839U, 0x3861U, 0x3862U, 0x3863U, 0x3864U, 0x3865U, 0x3866U,\n\t0x3930U, 0x3931U, 0x3932U, 0x3933U, 0x3934U, 0x3935U, 0x3936U, 0x3937U,\n\t0x3938U, 0x3939U, 0x3961U, 0x3962U, 0x3963U, 0x3964U, 0x3965U, 0x3966U,\n\t0x6130U, 0x6131U, 0x6132U, 0x6133U, 0x6134U, 0x6135U, 0x6136U, 0x6137U,\n\t0x6138U, 0x6139U, 0x6161U, 0x6162U, 0x6163U, 0x6164U, 0x6165U, 0x6166U,\n\t0x6230U, 0x6231U, 0x6232U, 0x6233U, 0x6234U, 0x6235U, 0x6236U, 0x6237U,\n\t0x6238U, 0x6239U, 0x6261U, 0x6262U, 0x6263U, 0x6264U, 0x6265U, 0x6266U,\n\t0x6330U, 0x6331U, 0x6332U, 0x6333U, 0x6334U, 0x6335U, 0x6336U, 0x6337U,\n\t0x6338U, 0x6339U, 0x6361U, 0x6362U, 0x6363U, 0x6364U, 0x6365U, 0x6366U,\n\t0x6430U, 0x6431U, 0x6432U, 0x6433U, 0x6434U, 0x6435U, 0x6436U, 0x6437U,\n\t0x6438U, 0x6439U, 0x6461U, 0x6462U, 0x6463U, 0x6464U, 0x6465U, 0x6466U,\n\t0x6530U, 0x6531U, 0x6532U, 0x6533U, 0x6534U, 0x6535U, 0x6536U, 0x6537U,\n\t0x6538U, 0x6539U, 0x6561U, 0x6562U, 0x6563U, 0x6564U, 0x6565U, 0x6566U,\n\t0x6630U, 0x6631U, 0x6632U, 0x6633U, 0x6634U, 0x6635U, 0x6636U, 0x6637U,\n\t0x6638U, 0x6639U, 0x6661U, 0x6662U, 0x6663U, 0x6664U, 0x6665U, 0x6666U\n#else  /* DUK_USE_INTEGER_BE */\n\t0x3030U, 0x3130U, 0x3230U, 0x3330U, 0x3430U, 0x3530U, 0x3630U, 0x3730U,\n\t0x3830U, 0x3930U, 0x6130U, 0x6230U, 0x6330U, 0x6430U, 0x6530U, 0x6630U,\n\t0x3031U, 0x3131U, 0x3231U, 0x3331U, 0x3431U, 0x3531U, 0x3631U, 0x3731U,\n\t0x3831U, 0x3931U, 0x6131U, 0x6231U, 0x6331U, 0x6431U, 0x6531U, 0x6631U,\n\t0x3032U, 0x3132U, 0x3232U, 0x3332U, 0x3432U, 0x3532U, 0x3632U, 0x3732U,\n\t0x3832U, 0x3932U, 0x6132U, 0x6232U, 0x6332U, 0x6432U, 0x6532U, 0x6632U,\n\t0x3033U, 0x3133U, 0x3233U, 0x3333U, 0x3433U, 0x3533U, 0x3633U, 0x3733U,\n\t0x3833U, 0x3933U, 0x6133U, 0x6233U, 0x6333U, 0x6433U, 0x6533U, 0x6633U,\n\t0x3034U, 0x3134U, 0x3234U, 0x3334U, 0x3434U, 0x3534U, 0x3634U, 0x3734U,\n\t0x3834U, 0x3934U, 0x6134U, 0x6234U, 0x6334U, 0x6434U, 0x6534U, 0x6634U,\n\t0x3035U, 0x3135U, 0x3235U, 0x3335U, 0x3435U, 0x3535U, 0x3635U, 0x3735U,\n\t0x3835U, 0x3935U, 0x6135U, 0x6235U, 0x6335U, 0x6435U, 0x6535U, 0x6635U,\n\t0x3036U, 0x3136U, 0x3236U, 0x3336U, 0x3436U, 0x3536U, 0x3636U, 0x3736U,\n\t0x3836U, 0x3936U, 0x6136U, 0x6236U, 0x6336U, 0x6436U, 0x6536U, 0x6636U,\n\t0x3037U, 0x3137U, 0x3237U, 0x3337U, 0x3437U, 0x3537U, 0x3637U, 0x3737U,\n\t0x3837U, 0x3937U, 0x6137U, 0x6237U, 0x6337U, 0x6437U, 0x6537U, 0x6637U,\n\t0x3038U, 0x3138U, 0x3238U, 0x3338U, 0x3438U, 0x3538U, 0x3638U, 0x3738U,\n\t0x3838U, 0x3938U, 0x6138U, 0x6238U, 0x6338U, 0x6438U, 0x6538U, 0x6638U,\n\t0x3039U, 0x3139U, 0x3239U, 0x3339U, 0x3439U, 0x3539U, 0x3639U, 0x3739U,\n\t0x3839U, 0x3939U, 0x6139U, 0x6239U, 0x6339U, 0x6439U, 0x6539U, 0x6639U,\n\t0x3061U, 0x3161U, 0x3261U, 0x3361U, 0x3461U, 0x3561U, 0x3661U, 0x3761U,\n\t0x3861U, 0x3961U, 0x6161U, 0x6261U, 0x6361U, 0x6461U, 0x6561U, 0x6661U,\n\t0x3062U, 0x3162U, 0x3262U, 0x3362U, 0x3462U, 0x3562U, 0x3662U, 0x3762U,\n\t0x3862U, 0x3962U, 0x6162U, 0x6262U, 0x6362U, 0x6462U, 0x6562U, 0x6662U,\n\t0x3063U, 0x3163U, 0x3263U, 0x3363U, 0x3463U, 0x3563U, 0x3663U, 0x3763U,\n\t0x3863U, 0x3963U, 0x6163U, 0x6263U, 0x6363U, 0x6463U, 0x6563U, 0x6663U,\n\t0x3064U, 0x3164U, 0x3264U, 0x3364U, 0x3464U, 0x3564U, 0x3664U, 0x3764U,\n\t0x3864U, 0x3964U, 0x6164U, 0x6264U, 0x6364U, 0x6464U, 0x6564U, 0x6664U,\n\t0x3065U, 0x3165U, 0x3265U, 0x3365U, 0x3465U, 0x3565U, 0x3665U, 0x3765U,\n\t0x3865U, 0x3965U, 0x6165U, 0x6265U, 0x6365U, 0x6465U, 0x6565U, 0x6665U,\n\t0x3066U, 0x3166U, 0x3266U, 0x3366U, 0x3466U, 0x3566U, 0x3666U, 0x3766U,\n\t0x3866U, 0x3966U, 0x6166U, 0x6266U, 0x6366U, 0x6466U, 0x6566U, 0x6666U\n#endif  /* DUK_USE_INTEGER_BE */\n};\n#endif  /* DUK_USE_HEX_FASTPATH */\n\n/*\n *  Arbitrary byteswap for potentially unaligned values\n *\n *  Used to byteswap pointers e.g. in debugger code.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* For now only needed by the debugger. */\nDUK_INTERNAL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len) {\n\tduk_uint8_t tmp;\n\tduk_uint8_t *q = p + len - 1;\n\n\twhile (p - q < 0) {\n\t\ttmp = *p;\n\t\t*p = *q;\n\t\t*q = tmp;\n\t\tp++;\n\t\tq--;\n\t}\n}\n#endif\n/*\n *  Hobject ECMAScript [[Class]].\n */\n\n/* #include duk_internal.h -> already included */\n\n#if (DUK_STRIDX_UC_ARGUMENTS > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_BOOLEAN > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_DATE > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_ERROR > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_FUNCTION > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_JSON > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_MATH > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_NUMBER > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_OBJECT > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_REG_EXP > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_STRING > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_GLOBAL > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_OBJ_ENV > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_DEC_ENV > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_POINTER > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_THREAD > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_ARRAY_BUFFER > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_DATA_VIEW > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_INT8_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT8_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT8_CLAMPED_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_INT16_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT16_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_INT32_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT32_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_FLOAT32_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_FLOAT64_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_EMPTY_STRING > 255)\n#error constant too large\n#endif\n\n/* Note: assumes that these string indexes are 8-bit, genstrings.py must ensure that */\nDUK_INTERNAL duk_uint8_t duk_class_number_to_stridx[32] = {\n\tDUK_STRIDX_EMPTY_STRING,  /* NONE, intentionally empty */\n\tDUK_STRIDX_UC_OBJECT,\n\tDUK_STRIDX_ARRAY,\n\tDUK_STRIDX_UC_FUNCTION,\n\tDUK_STRIDX_UC_ARGUMENTS,\n\tDUK_STRIDX_UC_BOOLEAN,\n\tDUK_STRIDX_DATE,\n\tDUK_STRIDX_UC_ERROR,\n\tDUK_STRIDX_JSON,\n\tDUK_STRIDX_MATH,\n\tDUK_STRIDX_UC_NUMBER,\n\tDUK_STRIDX_REG_EXP,\n\tDUK_STRIDX_UC_STRING,\n\tDUK_STRIDX_GLOBAL,\n\tDUK_STRIDX_UC_SYMBOL,\n\tDUK_STRIDX_OBJ_ENV,\n\tDUK_STRIDX_DEC_ENV,\n\tDUK_STRIDX_UC_POINTER,\n\tDUK_STRIDX_UC_THREAD,\n\tDUK_STRIDX_ARRAY_BUFFER,\n\tDUK_STRIDX_DATA_VIEW,\n\tDUK_STRIDX_INT8_ARRAY,\n\tDUK_STRIDX_UINT8_ARRAY,\n\tDUK_STRIDX_UINT8_CLAMPED_ARRAY,\n\tDUK_STRIDX_INT16_ARRAY,\n\tDUK_STRIDX_UINT16_ARRAY,\n\tDUK_STRIDX_INT32_ARRAY,\n\tDUK_STRIDX_UINT32_ARRAY,\n\tDUK_STRIDX_FLOAT32_ARRAY,\n\tDUK_STRIDX_FLOAT64_ARRAY,\n\tDUK_STRIDX_EMPTY_STRING,  /* UNUSED, intentionally empty */\n\tDUK_STRIDX_EMPTY_STRING,  /* UNUSED, intentionally empty */\n};\n/*\n *  Default allocation functions.\n *\n *  Assumes behavior such as malloc allowing zero size, yielding\n *  a NULL or a unique pointer which is a no-op for free.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS)\nDUK_INTERNAL void *duk_default_alloc_function(void *udata, duk_size_t size) {\n\tvoid *res;\n\tDUK_UNREF(udata);\n\tres = DUK_ANSI_MALLOC(size);\n\tDUK_DDD(DUK_DDDPRINT(\"default alloc function: %lu -> %p\",\n\t                     (unsigned long) size, (void *) res));\n\treturn res;\n}\n\nDUK_INTERNAL void *duk_default_realloc_function(void *udata, void *ptr, duk_size_t newsize) {\n\tvoid *res;\n\tDUK_UNREF(udata);\n\tres = DUK_ANSI_REALLOC(ptr, newsize);\n\tDUK_DDD(DUK_DDDPRINT(\"default realloc function: %p %lu -> %p\",\n\t                     (void *) ptr, (unsigned long) newsize, (void *) res));\n\treturn res;\n}\n\nDUK_INTERNAL void duk_default_free_function(void *udata, void *ptr) {\n\tDUK_DDD(DUK_DDDPRINT(\"default free function: %p\", (void *) ptr));\n\tDUK_UNREF(udata);\n\tDUK_ANSI_FREE(ptr);\n}\n#endif  /* DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS */\n/*\n *  Buffer\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_EXTERNAL void *duk_resize_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t new_size) {\n\tduk_hbuffer_dynamic *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer_dynamic *) duk_require_hbuffer(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tif (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\t/* Maximum size check is handled by callee. */\n\tduk_hbuffer_resize(thr, h, new_size);\n\n\treturn DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h);\n}\n\nDUK_EXTERNAL void *duk_steal_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tduk_hbuffer_dynamic *h;\n\tvoid *ptr;\n\tduk_size_t sz;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer_dynamic *) duk_require_hbuffer(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tif (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\t/* Forget the previous allocation, setting size to 0 and alloc to\n\t * NULL.  Caller is responsible for freeing the previous allocation.\n\t * Getting the allocation and clearing it is done in the same API\n\t * call to avoid any chance of a realloc.\n\t */\n\tptr = DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h);\n\tsz = DUK_HBUFFER_DYNAMIC_GET_SIZE(h);\n\tif (out_size) {\n\t\t*out_size = sz;\n\t}\n\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(thr->heap, h);\n\tDUK_HBUFFER_DYNAMIC_SET_SIZE(h, 0);\n\n\treturn ptr;\n}\n\nDUK_EXTERNAL void duk_config_buffer(duk_hthread *thr, duk_idx_t idx, void *ptr, duk_size_t len) {\n\tduk_hbuffer_external *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer_external *) duk_require_hbuffer(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tif (!DUK_HBUFFER_HAS_EXTERNAL(h)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h));\n\n\tDUK_HBUFFER_EXTERNAL_SET_DATA_PTR(thr->heap, h, ptr);\n\tDUK_HBUFFER_EXTERNAL_SET_SIZE(h, len);\n}\n/*\n *  Bytecode dump/load\n *\n *  The bytecode load primitive is more important performance-wise than the\n *  dump primitive.\n *\n *  Unlike most Duktape API calls, bytecode dump/load is not guaranteed to be\n *  memory safe for invalid arguments - caller beware!  There's little point\n *  in trying to achieve memory safety unless bytecode instructions are also\n *  validated which is not easy to do with indirect register references etc.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_BYTECODE_DUMP_SUPPORT)\n\n#define DUK__SER_MARKER  0xbf\n#define DUK__SER_STRING  0x00\n#define DUK__SER_NUMBER  0x01\n#define DUK__BYTECODE_INITIAL_ALLOC 256\n#define DUK__NO_FORMALS  0xffffffffUL\n\n/*\n *  Dump/load helpers, xxx_raw() helpers do no buffer checks\n */\n\nDUK_LOCAL duk_uint8_t *duk__load_string_raw(duk_hthread *thr, duk_uint8_t *p) {\n\tduk_uint32_t len;\n\n\tlen = DUK_RAW_READ_U32_BE(p);\n\tduk_push_lstring(thr, (const char *) p, len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__load_buffer_raw(duk_hthread *thr, duk_uint8_t *p) {\n\tduk_uint32_t len;\n\tduk_uint8_t *buf;\n\n\tlen = DUK_RAW_READ_U32_BE(p);\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) len);\n\tDUK_ASSERT(buf != NULL);\n\tduk_memcpy((void *) buf, (const void *) p, (size_t) len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_hstring_raw(duk_uint8_t *p, duk_hstring *h) {\n\tduk_size_t len;\n\tduk_uint32_t tmp32;\n\n\tDUK_ASSERT(h != NULL);\n\n\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\tDUK_ASSERT(len <= 0xffffffffUL);  /* string limits */\n\ttmp32 = (duk_uint32_t) len;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\tduk_memcpy((void *) p,\n\t           (const void *) DUK_HSTRING_GET_DATA(h),\n\t           len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_hbuffer_raw(duk_hthread *thr, duk_uint8_t *p, duk_hbuffer *h) {\n\tduk_size_t len;\n\tduk_uint32_t tmp32;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\tDUK_UNREF(thr);\n\n\tlen = DUK_HBUFFER_GET_SIZE(h);\n\tDUK_ASSERT(len <= 0xffffffffUL);  /* buffer limits */\n\ttmp32 = (duk_uint32_t) len;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\t/* When len == 0, buffer data pointer may be NULL. */\n\tduk_memcpy_unsafe((void *) p,\n\t                  (const void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h),\n\t                  len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_string_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx) {\n\tduk_hstring *h_str;\n\tduk_tval *tv;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_STRING(tv)) {\n\t\th_str = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h_str != NULL);\n\t} else {\n\t\th_str = DUK_HTHREAD_STRING_EMPTY_STRING(thr);\n\t\tDUK_ASSERT(h_str != NULL);\n\t}\n\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(h_str), p);\n\tp = duk__dump_hstring_raw(p, h_str);\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_buffer_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx) {\n\tduk_tval *tv;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h_buf;\n\t\th_buf = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h_buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFFER_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HBUFFER_GET_SIZE(h_buf), p);\n\t\tp = duk__dump_hbuffer_raw(thr, p, h_buf);\n\t} else {\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\t\tDUK_RAW_WRITE_U32_BE(p, 0);\n\t}\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_uint32_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx, duk_uint32_t def_value) {\n\tduk_tval *tv;\n\tduk_uint32_t val;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_NUMBER(tv)) {\n\t\tval = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv);\n\t} else {\n\t\tval = def_value;\n\t}\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\tDUK_RAW_WRITE_U32_BE(p, val);\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_varmap(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func) {\n\tduk_hobject *h;\n\n\th = duk_hobject_get_varmap(thr, (duk_hobject *) func);\n\tif (h != NULL) {\n\t\tduk_uint_fast32_t i;\n\n\t\t/* We know _Varmap only has own properties so walk property\n\t\t * table directly.  We also know _Varmap is dense and all\n\t\t * values are numbers; assert for these.  GC and finalizers\n\t\t * shouldn't affect _Varmap so side effects should be fine.\n\t\t */\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\t\tduk_hstring *key;\n\t\t\tduk_tval *tv_val;\n\t\t\tduk_uint32_t val;\n\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, h, i);\n\t\t\tDUK_ASSERT(key != NULL);  /* _Varmap is dense */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, h, i));\n\t\t\ttv_val = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, h, i);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_val));  /* known to be number; in fact an integer */\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv_val));\n\t\t\tDUK_ASSERT(DUK_TVAL_GET_FASTINT(tv_val) == (duk_int64_t) DUK_TVAL_GET_FASTINT_U32(tv_val));  /* known to be 32-bit */\n\t\t\tval = DUK_TVAL_GET_FASTINT_U32(tv_val);\n#else\n\t\t\tval = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv_val);\n#endif\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(key) + 4U, p);\n\t\t\tp = duk__dump_hstring_raw(p, key);\n\t\t\tDUK_RAW_WRITE_U32_BE(p, val);\n\t\t}\n\t}\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\tDUK_RAW_WRITE_U32_BE(p, 0);  /* end of _Varmap */\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_formals(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func) {\n\tduk_harray *h;\n\n\th = duk_hobject_get_formals(thr, (duk_hobject *) func);\n\tif (h != NULL) {\n\t\tduk_uint32_t i;\n\n\t\t/* Here we rely on _Formals being a dense array containing\n\t\t * strings.  This should be the case unless _Formals has been\n\t\t * tweaked by the application (which we don't support right\n\t\t * now).\n\t\t */\n\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\t\tDUK_ASSERT(h->length != DUK__NO_FORMALS);  /* limits */\n\t\tDUK_RAW_WRITE_U32_BE(p, h->length);\n\n\t\tfor (i = 0; i < h->length; i++) {\n\t\t\tduk_tval *tv_val;\n\t\t\tduk_hstring *varname;\n\n\t\t\ttv_val = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, (duk_hobject *) h, i);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_val));\n\n\t\t\tvarname = DUK_TVAL_GET_STRING(tv_val);\n\t\t\tDUK_ASSERT(varname != NULL);\n\t\t\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(varname) >= 1);\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(varname), p);\n\t\t\tp = duk__dump_hstring_raw(p, varname);\n\t\t}\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"dumping function without _Formals, emit marker to indicate missing _Formals\"));\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\t\tDUK_RAW_WRITE_U32_BE(p, DUK__NO_FORMALS);  /* marker: no formals */\n\t}\n\treturn p;\n}\n\nstatic duk_uint8_t *duk__dump_func(duk_hthread *thr, duk_hcompfunc *func, duk_bufwriter_ctx *bw_ctx, duk_uint8_t *p) {\n\tduk_tval *tv, *tv_end;\n\tduk_instr_t *ins, *ins_end;\n\tduk_hobject **fn, **fn_end;\n\tduk_hstring *h_str;\n\tduk_uint32_t count_instr;\n\tduk_uint32_t tmp32;\n\tduk_uint16_t tmp16;\n\tduk_double_t d;\n\n\tDUK_DD(DUK_DDPRINT(\"dumping function %p to %p: \"\n\t                   \"consts=[%p,%p[ (%ld bytes, %ld items), \"\n\t                   \"funcs=[%p,%p[ (%ld bytes, %ld items), \"\n\t                   \"code=[%p,%p[ (%ld bytes, %ld items)\",\n\t                   (void *) func,\n\t                   (void *) p,\n\t                   (void *) DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CONSTS_SIZE(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CONSTS_COUNT(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_FUNCS_SIZE(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_CODE_END(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CODE_SIZE(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CODE_COUNT(thr->heap, func)));\n\n\tDUK_ASSERT(DUK_USE_ESBC_MAX_BYTES <= 0x7fffffffUL);  /* ensures no overflow */\n\tcount_instr = (duk_uint32_t) DUK_HCOMPFUNC_GET_CODE_COUNT(thr->heap, func);\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 3U * 4U + 2U * 2U + 3U * 4U + count_instr * 4U, p);\n\n\t/* Fixed header info. */\n\ttmp32 = count_instr;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp32 = (duk_uint32_t) DUK_HCOMPFUNC_GET_CONSTS_COUNT(thr->heap, func);\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp32 = (duk_uint32_t) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, func);\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp16 = func->nregs;\n\tDUK_RAW_WRITE_U16_BE(p, tmp16);\n\ttmp16 = func->nargs;\n\tDUK_RAW_WRITE_U16_BE(p, tmp16);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\ttmp32 = func->start_line;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp32 = func->end_line;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n#else\n\tDUK_RAW_WRITE_U32_BE(p, 0);\n\tDUK_RAW_WRITE_U32_BE(p, 0);\n#endif\n\ttmp32 = DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) func);  /* masks flags, only duk_hobject flags */\n\ttmp32 &= ~(DUK_HOBJECT_FLAG_HAVE_FINALIZER);  /* finalizer flag is lost */\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\n\t/* Bytecode instructions: endian conversion needed unless\n\t * platform is big endian.\n\t */\n\tins = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, func);\n\tins_end = DUK_HCOMPFUNC_GET_CODE_END(thr->heap, func);\n\tDUK_ASSERT((duk_size_t) (ins_end - ins) == (duk_size_t) count_instr);\n#if defined(DUK_USE_INTEGER_BE)\n\tduk_memcpy_unsafe((void *) p, (const void *) ins, (size_t) (ins_end - ins));\n\tp += (size_t) (ins_end - ins);\n#else\n\twhile (ins != ins_end) {\n\t\ttmp32 = (duk_uint32_t) (*ins);\n\t\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\t\tins++;\n\t}\n#endif\n\n\t/* Constants: variable size encoding. */\n\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, func);\n\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, func);\n\twhile (tv != tv_end) {\n\t\t/* constants are strings or numbers now */\n\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv) ||\n\t\t           DUK_TVAL_IS_NUMBER(tv));\n\n\t\tif (DUK_TVAL_IS_STRING(tv)) {\n\t\t\th_str = DUK_TVAL_GET_STRING(tv);\n\t\t\tDUK_ASSERT(h_str != NULL);\n\t\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1U + 4U + DUK_HSTRING_GET_BYTELEN(h_str), p);\n\t\t\t*p++ = DUK__SER_STRING;\n\t\t\tp = duk__dump_hstring_raw(p, h_str);\n\t\t} else {\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1U + 8U, p);\n\t\t\t*p++ = DUK__SER_NUMBER;\n\t\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t\t\tDUK_RAW_WRITE_DOUBLE_BE(p, d);\n\t\t}\n\t\ttv++;\n\t}\n\n\t/* Inner functions recursively. */\n\tfn = (duk_hobject **) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, func);\n\tfn_end = (duk_hobject **) DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, func);\n\twhile (fn != fn_end) {\n\t\t/* XXX: This causes recursion up to inner function depth\n\t\t * which is normally not an issue, e.g. mark-and-sweep uses\n\t\t * a recursion limiter to avoid C stack issues.  Avoiding\n\t\t * this would mean some sort of a work list or just refusing\n\t\t * to serialize deep functions.\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(*fn));\n\t\tp = duk__dump_func(thr, (duk_hcompfunc *) *fn, bw_ctx, p);\n\t\tfn++;\n\t}\n\n\t/* Lexenv and varenv are not dumped. */\n\n\t/* Object extra properties.\n\t *\n\t * There are some difference between function templates and functions.\n\t * For example, function templates don't have .length and nargs is\n\t * normally used to instantiate the functions.\n\t */\n\n\tp = duk__dump_uint32_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_LENGTH, (duk_uint32_t) func->nargs);\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tp = duk__dump_string_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_NAME);\n#endif\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tp = duk__dump_string_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_FILE_NAME);\n#endif\n#if defined(DUK_USE_PC2LINE)\n\tp = duk__dump_buffer_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_INT_PC2LINE);\n#endif\n\tp = duk__dump_varmap(thr, p, bw_ctx, (duk_hobject *) func);\n\tp = duk__dump_formals(thr, p, bw_ctx, (duk_hobject *) func);\n\n\tDUK_DD(DUK_DDPRINT(\"serialized function %p -> final pointer %p\", (void *) func, (void *) p));\n\n\treturn p;\n}\n\n/* Load a function from bytecode.  The function object returned here must\n * match what is created by duk_js_push_closure() with respect to its flags,\n * properties, etc.\n *\n * NOTE: there are intentionally no input buffer length / bound checks.\n * Adding them would be easy but wouldn't ensure memory safety as untrusted\n * or broken bytecode is unsafe during execution unless the opcodes themselves\n * are validated (which is quite complex, especially for indirect opcodes).\n */\n\n#define DUK__ASSERT_LEFT(n) do { \\\n\t\tDUK_ASSERT((duk_size_t) (p_end - p) >= (duk_size_t) (n)); \\\n\t} while (0)\n\nstatic duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t *p_end) {\n\tduk_hcompfunc *h_fun;\n\tduk_hbuffer *h_data;\n\tduk_size_t data_size;\n\tduk_uint32_t count_instr, count_const, count_funcs;\n\tduk_uint32_t n;\n\tduk_uint32_t tmp32;\n\tduk_small_uint_t const_type;\n\tduk_uint8_t *fun_data;\n\tduk_uint8_t *q;\n\tduk_idx_t idx_base;\n\tduk_tval *tv1;\n\tduk_uarridx_t arr_idx;\n\tduk_uarridx_t arr_limit;\n\tduk_hobject *func_env;\n\tduk_bool_t need_pop;\n\n\t/* XXX: There's some overlap with duk_js_closure() here, but\n\t * seems difficult to share code.  Ensure that the final function\n\t * looks the same as created by duk_js_closure().\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"loading function, p=%p, p_end=%p\", (void *) p, (void *) p_end));\n\n\tDUK__ASSERT_LEFT(3 * 4);\n\tcount_instr = DUK_RAW_READ_U32_BE(p);\n\tcount_const = DUK_RAW_READ_U32_BE(p);\n\tcount_funcs = DUK_RAW_READ_U32_BE(p);\n\n\tdata_size = sizeof(duk_tval) * count_const +\n\t            sizeof(duk_hobject *) * count_funcs +\n\t            sizeof(duk_instr_t) * count_instr;\n\n\tDUK_DD(DUK_DDPRINT(\"instr=%ld, const=%ld, funcs=%ld, data_size=%ld\",\n\t                   (long) count_instr, (long) count_const,\n\t                   (long) count_const, (long) data_size));\n\n\t/* Value stack is used to ensure reachability of constants and\n\t * inner functions being loaded.  Require enough space to handle\n\t * large functions correctly.\n\t */\n\tduk_require_stack(thr, (duk_idx_t) (2 + count_const + count_funcs));\n\tidx_base = duk_get_top(thr);\n\n\t/* Push function object, init flags etc.  This must match\n\t * duk_js_push_closure() quite carefully.\n\t */\n\th_fun = duk_push_hcompfunc(thr);\n\tDUK_ASSERT(h_fun != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) h_fun));\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, h_fun) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, h_fun) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, h_fun) == NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_fun) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\n\th_fun->nregs = DUK_RAW_READ_U16_BE(p);\n\th_fun->nargs = DUK_RAW_READ_U16_BE(p);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\th_fun->start_line = DUK_RAW_READ_U32_BE(p);\n\th_fun->end_line = DUK_RAW_READ_U32_BE(p);\n#else\n\tp += 8;  /* skip line info */\n#endif\n\n\t/* duk_hcompfunc flags; quite version specific */\n\ttmp32 = DUK_RAW_READ_U32_BE(p);\n\tDUK_HEAPHDR_SET_FLAGS((duk_heaphdr *) h_fun, tmp32);  /* masks flags to only change duk_hobject flags */\n\n\t/* standard prototype (no need to set here, already set) */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_fun) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#if 0\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, &h_fun->obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#endif\n\n\t/* assert just a few critical flags */\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h_fun) == DUK_HTYPE_OBJECT);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&h_fun->obj));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_IS_PROXY(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(&h_fun->obj));\n\n\t/* Create function 'data' buffer but don't attach it yet. */\n\tfun_data = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, data_size);\n\tDUK_ASSERT(fun_data != NULL);\n\n\t/* Load bytecode instructions. */\n\tDUK_ASSERT(sizeof(duk_instr_t) == 4);\n\tDUK__ASSERT_LEFT(count_instr * sizeof(duk_instr_t));\n#if defined(DUK_USE_INTEGER_BE)\n\tq = fun_data + sizeof(duk_tval) * count_const + sizeof(duk_hobject *) * count_funcs;\n\tduk_memcpy((void *) q,\n\t           (const void *) p,\n\t           sizeof(duk_instr_t) * count_instr);\n\tp += sizeof(duk_instr_t) * count_instr;\n#else\n\tq = fun_data + sizeof(duk_tval) * count_const + sizeof(duk_hobject *) * count_funcs;\n\tfor (n = count_instr; n > 0; n--) {\n\t\t*((duk_instr_t *) (void *) q) = DUK_RAW_READ_U32_BE(p);\n\t\tq += sizeof(duk_instr_t);\n\t}\n#endif\n\n\t/* Load constants onto value stack but don't yet copy to buffer. */\n\tfor (n = count_const; n > 0; n--) {\n\t\tDUK__ASSERT_LEFT(1);\n\t\tconst_type = DUK_RAW_READ_U8(p);\n\t\tswitch (const_type) {\n\t\tcase DUK__SER_STRING: {\n\t\t\tp = duk__load_string_raw(thr, p);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK__SER_NUMBER: {\n\t\t\t/* Important to do a fastint check so that constants are\n\t\t\t * properly read back as fastints.\n\t\t\t */\n\t\t\tduk_tval tv_tmp;\n\t\t\tduk_double_t val;\n\t\t\tDUK__ASSERT_LEFT(8);\n\t\t\tval = DUK_RAW_READ_DOUBLE_BE(p);\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(&tv_tmp, val);\n\t\t\tduk_push_tval(thr, &tv_tmp);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tgoto format_error;\n\t\t}\n\t\t}\n\t}\n\n\t/* Load inner functions to value stack, but don't yet copy to buffer. */\n\tfor (n = count_funcs; n > 0; n--) {\n\t\tp = duk__load_func(thr, p, p_end);\n\t\tif (p == NULL) {\n\t\t\tgoto format_error;\n\t\t}\n\t}\n\n\t/* With constants and inner functions on value stack, we can now\n\t * atomically finish the function 'data' buffer, bump refcounts,\n\t * etc.\n\t *\n\t * Here we take advantage of the value stack being just a duk_tval\n\t * array: we can just memcpy() the constants as long as we incref\n\t * them afterwards.\n\t */\n\n\th_data = (duk_hbuffer *) duk_known_hbuffer(thr, idx_base + 1);\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC(h_data));\n\tDUK_HCOMPFUNC_SET_DATA(thr->heap, h_fun, h_data);\n\tDUK_HBUFFER_INCREF(thr, h_data);\n\n\ttv1 = duk_get_tval(thr, idx_base + 2);  /* may be NULL if no constants or inner funcs */\n\tDUK_ASSERT((count_const == 0 && count_funcs == 0) || tv1 != NULL);\n\n\tq = fun_data;\n\tduk_memcpy_unsafe((void *) q, (const void *) tv1, sizeof(duk_tval) * count_const);\n\tfor (n = count_const; n > 0; n--) {\n\t\tDUK_TVAL_INCREF_FAST(thr, (duk_tval *) (void *) q);  /* no side effects */\n\t\tq += sizeof(duk_tval);\n\t}\n\ttv1 += count_const;\n\n\tDUK_HCOMPFUNC_SET_FUNCS(thr->heap, h_fun, (duk_hobject **) (void *) q);\n\tfor (n = count_funcs; n > 0; n--) {\n\t\tduk_hobject *h_obj;\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv1));\n\t\th_obj = DUK_TVAL_GET_OBJECT(tv1);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\ttv1++;\n\t\tDUK_HOBJECT_INCREF(thr, h_obj);\n\n\t\t*((duk_hobject **) (void *) q) = h_obj;\n\t\tq += sizeof(duk_hobject *);\n\t}\n\n\tDUK_HCOMPFUNC_SET_BYTECODE(thr->heap, h_fun, (duk_instr_t *) (void *) q);\n\n\t/* The function object is now reachable and refcounts are fine,\n\t * so we can pop off all the temporaries.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"function is reachable, reset top; func: %!iT\", duk_get_tval(thr, idx_base)));\n\tduk_set_top(thr, idx_base + 1);\n\n\t/* Setup function properties. */\n\ttmp32 = DUK_RAW_READ_U32_BE(p);\n\tduk_push_u32(thr, tmp32);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tp = duk__load_string_raw(thr, p);  /* -> [ func funcname ] */\n\tfunc_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\tDUK_ASSERT(func_env != NULL);\n\tneed_pop = 0;\n\tif (DUK_HOBJECT_HAS_NAMEBINDING((duk_hobject *) h_fun)) {\n\t\t/* Original function instance/template had NAMEBINDING.\n\t\t * Must create a lexical environment on loading to allow\n\t\t * recursive functions like 'function foo() { foo(); }'.\n\t\t */\n\t\tduk_hdecenv *new_env;\n\n\t\tnew_env = duk_hdecenv_alloc(thr,\n\t\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\t\tDUK_ASSERT(new_env != NULL);\n\t\tDUK_ASSERT(new_env->thread == NULL);  /* Closed. */\n\t\tDUK_ASSERT(new_env->varmap == NULL);\n\t\tDUK_ASSERT(new_env->regbase_byteoff == 0);\n\t\tDUK_HDECENV_ASSERT_VALID(new_env);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, func_env);\n\t\tDUK_HOBJECT_INCREF(thr, func_env);\n\n\t\tfunc_env = (duk_hobject *) new_env;\n\n\t\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\n\t\tduk_dup_m2(thr);                                  /* -> [ func funcname env funcname ] */\n\t\tduk_dup(thr, idx_base);                           /* -> [ func funcname env funcname func ] */\n\t\tduk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_NONE);  /* -> [ func funcname env ] */\n\n\t\tneed_pop = 1;  /* Need to pop env, but -after- updating h_fun and increfs. */\n\t}\n\tDUK_ASSERT(func_env != NULL);\n\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, h_fun, func_env);\n\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, h_fun, func_env);\n\tDUK_HOBJECT_INCREF(thr, func_env);\n\tDUK_HOBJECT_INCREF(thr, func_env);\n\tif (need_pop) {\n\t\tduk_pop(thr);\n\t}\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n#endif  /* DUK_USE_FUNC_NAME_PROPERTY */\n\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tp = duk__load_string_raw(thr, p);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C);\n#endif  /* DUK_USE_FUNC_FILENAME_PROPERTY */\n\n\tif (DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) h_fun)) {\n\t\t/* Restore empty external .prototype only for constructable\n\t\t * functions.  The prototype object should inherit from\n\t\t * Object.prototype.\n\t\t */\n\t\tduk_push_object(thr);\n\t\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\t\tduk_dup_m2(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC);  /* func.prototype.constructor = func */\n\t\tduk_compact_m1(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W);\n\t}\n\n#if defined(DUK_USE_PC2LINE)\n\tp = duk__load_buffer_raw(thr, p);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_WC);\n#endif  /* DUK_USE_PC2LINE */\n\n\tduk_push_bare_object(thr);  /* _Varmap */\n\tfor (;;) {\n\t\t/* XXX: awkward */\n\t\tp = duk__load_string_raw(thr, p);\n\t\tif (duk_get_length(thr, -1) == 0) {\n\t\t\tduk_pop(thr);\n\t\t\tbreak;\n\t\t}\n\t\ttmp32 = DUK_RAW_READ_U32_BE(p);\n\t\tduk_push_u32(thr, tmp32);\n\t\tduk_put_prop(thr, -3);\n\t}\n\tduk_compact_m1(thr);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VARMAP, DUK_PROPDESC_FLAGS_NONE);\n\n\t/* _Formals may have been missing in the original function, which is\n\t * handled using a marker length.\n\t */\n\tarr_limit = DUK_RAW_READ_U32_BE(p);\n\tif (arr_limit != DUK__NO_FORMALS) {\n\t\tduk_push_bare_array(thr);  /* _Formals */\n\t\tfor (arr_idx = 0; arr_idx < arr_limit; arr_idx++) {\n\t\t\tp = duk__load_string_raw(thr, p);\n\t\t\tduk_put_prop_index(thr, -2, arr_idx);\n\t\t}\n\t\tduk_compact_m1(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_FORMALS, DUK_PROPDESC_FLAGS_NONE);\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"no _Formals in dumped function\"));\n\t}\n\n\t/* Return with final function pushed on stack top. */\n\tDUK_DD(DUK_DDPRINT(\"final loaded function: %!iT\", duk_get_tval(thr, -1)));\n\tDUK_ASSERT_TOP(thr, idx_base + 1);\n\treturn p;\n\n format_error:\n\treturn NULL;\n}\n\nDUK_EXTERNAL void duk_dump_function(duk_hthread *thr) {\n\tduk_hcompfunc *func;\n\tduk_bufwriter_ctx bw_ctx_alloc;\n\tduk_bufwriter_ctx *bw_ctx = &bw_ctx_alloc;\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Bound functions don't have all properties so we'd either need to\n\t * lookup the non-bound target function or reject bound functions.\n\t * For now, bound functions are rejected with TypeError.\n\t */\n\tfunc = duk_require_hcompfunc(thr, -1);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&func->obj));\n\n\t/* Estimating the result size beforehand would be costly, so\n\t * start with a reasonable size and extend as needed.\n\t */\n\tDUK_BW_INIT_PUSHBUF(thr, bw_ctx, DUK__BYTECODE_INITIAL_ALLOC);\n\tp = DUK_BW_GET_PTR(thr, bw_ctx);\n\t*p++ = DUK__SER_MARKER;\n\tp = duk__dump_func(thr, func, bw_ctx, p);\n\tDUK_BW_SET_PTR(thr, bw_ctx, p);\n\tDUK_BW_COMPACT(thr, bw_ctx);\n\n\tDUK_DD(DUK_DDPRINT(\"serialized result: %!T\", duk_get_tval(thr, -1)));\n\n\tduk_remove_m2(thr);  /* [ ... func buf ] -> [ ... buf ] */\n}\n\nDUK_EXTERNAL void duk_load_function(duk_hthread *thr) {\n\tduk_uint8_t *p_buf, *p, *p_end;\n\tduk_size_t sz;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tp_buf = (duk_uint8_t *) duk_require_buffer(thr, -1, &sz);\n\tDUK_ASSERT(p_buf != NULL);\n\n\t/* The caller is responsible for being sure that bytecode being loaded\n\t * is valid and trusted.  Invalid bytecode can cause memory unsafe\n\t * behavior directly during loading or later during bytecode execution\n\t * (instruction validation would be quite complex to implement).\n\t *\n\t * This signature check is the only sanity check for detecting\n\t * accidental invalid inputs.  The initial byte ensures no ordinary\n\t * string or Symbol will be accepted by accident.\n\t */\n\tp = p_buf;\n\tp_end = p_buf + sz;\n\tif (sz < 1 || p[0] != DUK__SER_MARKER) {\n\t\tgoto format_error;\n\t}\n\tp++;\n\n\tp = duk__load_func(thr, p, p_end);\n\tif (p == NULL) {\n\t\tgoto format_error;\n\t}\n\n\tduk_remove_m2(thr);  /* [ ... buf func ] -> [ ... func ] */\n\treturn;\n\n format_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BYTECODE);\n\tDUK_WO_NORETURN(return;);\n}\n\n#else  /* DUK_USE_BYTECODE_DUMP_SUPPORT */\n\nDUK_EXTERNAL void duk_dump_function(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_load_function(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n#endif  /* DUK_USE_BYTECODE_DUMP_SUPPORT */\n\n/* automatic undefs */\n#undef DUK__ASSERT_LEFT\n#undef DUK__BYTECODE_INITIAL_ALLOC\n#undef DUK__NO_FORMALS\n#undef DUK__SER_MARKER\n#undef DUK__SER_NUMBER\n#undef DUK__SER_STRING\n/*\n *  Calls.\n *\n *  Protected variants should avoid ever throwing an error.  Must be careful\n *  to catch errors related to value stack manipulation and property lookup,\n *  not just the call itself.\n *\n *  The only exception is when arguments are insane, e.g. nargs/nrets are out\n *  of bounds; in such cases an error is thrown for two reasons.  First, we\n *  can't always respect the value stack input/output guarantees in such cases\n *  so the caller would end up with the value stack in an unexpected state.\n *  Second, an attempt to create an error might itself fail (although this\n *  could be avoided by pushing a preallocated object/string or a primitive\n *  value).\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Helpers\n */\n\nstruct duk__pcall_prop_args {\n\tduk_idx_t obj_idx;\n\tduk_idx_t nargs;\n\tduk_small_uint_t call_flags;\n};\ntypedef struct duk__pcall_prop_args duk__pcall_prop_args;\n\nstruct duk__pcall_method_args {\n\tduk_idx_t nargs;\n\tduk_small_uint_t call_flags;\n};\ntypedef struct duk__pcall_method_args duk__pcall_method_args;\n\nstruct duk__pcall_args {\n\tduk_idx_t nargs;\n\tduk_small_uint_t call_flags;\n};\ntypedef struct duk__pcall_args duk__pcall_args;\n\n/* Compute and validate idx_func for a certain 'nargs' and 'other'\n * parameter count (1 or 2, depending on whether 'this' binding is\n * present).\n */\nDUK_LOCAL duk_idx_t duk__call_get_idx_func(duk_hthread *thr, duk_idx_t nargs, duk_idx_t other) {\n\tduk_idx_t idx_func;\n\n\t/* XXX: byte arithmetic? */\n\n\tDUK_ASSERT(other >= 0);\n\n\tidx_func = duk_get_top(thr) - nargs - other;\n\tif (DUK_UNLIKELY((idx_func | nargs) < 0)) {  /* idx_func < 0 || nargs < 0; OR sign bits */\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\treturn idx_func;\n}\n\n/* Compute idx_func, assume index will be valid.  This is a valid assumption\n * for protected calls: nargs < 0 is checked explicitly and duk_safe_call()\n * validates the argument count.\n */\nDUK_LOCAL duk_idx_t duk__call_get_idx_func_unvalidated(duk_hthread *thr, duk_idx_t nargs, duk_idx_t other) {\n\tduk_idx_t idx_func;\n\n\t/* XXX: byte arithmetic? */\n\n\tDUK_ASSERT(nargs >= 0);\n\tDUK_ASSERT(other >= 0);\n\n\tidx_func = duk_get_top(thr) - nargs - other;\n\tDUK_ASSERT(idx_func >= 0);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\treturn idx_func;\n}\n\n/* Prepare value stack for a method call through an object property.\n * May currently throw an error e.g. when getting the property.\n */\nDUK_LOCAL void duk__call_prop_prep_stack(duk_hthread *thr, duk_idx_t normalized_obj_idx, duk_idx_t nargs) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(nargs >= 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__call_prop_prep_stack, normalized_obj_idx=%ld, nargs=%ld, stacktop=%ld\",\n\t                     (long) normalized_obj_idx, (long) nargs, (long) duk_get_top(thr)));\n\n\t/* [... key arg1 ... argN] */\n\n\t/* duplicate key */\n\tduk_dup(thr, -nargs - 1);  /* Note: -nargs alone would fail for nargs == 0, this is OK */\n\t(void) duk_get_prop(thr, normalized_obj_idx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"func: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\tif (DUK_UNLIKELY(!duk_is_callable(thr, -1))) {\n\t\tduk_tval *tv_base;\n\t\tduk_tval *tv_key;\n\n\t\t/* tv_targ is passed on stack top (at index -1). */\n\t\ttv_base = DUK_GET_TVAL_POSIDX(thr, normalized_obj_idx);\n\t\ttv_key = DUK_GET_TVAL_NEGIDX(thr, -nargs - 2);\n\t\tDUK_ASSERT(tv_base >= thr->valstack_bottom && tv_base < thr->valstack_top);\n\t\tDUK_ASSERT(tv_key >= thr->valstack_bottom && tv_key < thr->valstack_top);\n\n\t\tduk_call_setup_propcall_error(thr, tv_base, tv_key);\n\t}\n#endif\n\n\t/* [... key arg1 ... argN func] */\n\n\tduk_replace(thr, -nargs - 2);\n\n\t/* [... func arg1 ... argN] */\n\n\tduk_dup(thr, normalized_obj_idx);\n\tduk_insert(thr, -nargs - 1);\n\n\t/* [... func this arg1 ... argN] */\n}\n\nDUK_EXTERNAL void duk_call(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_small_uint_t call_flags;\n\tduk_idx_t idx_func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx_func = duk__call_get_idx_func(thr, nargs, 1);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tduk_insert_undefined(thr, idx_func + 1);\n\n\tcall_flags = 0;  /* not protected, respect reclimit, not constructor */\n\tduk_handle_call_unprotected(thr, idx_func, call_flags);\n}\n\nDUK_EXTERNAL void duk_call_method(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_small_uint_t call_flags;\n\tduk_idx_t idx_func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx_func = duk__call_get_idx_func(thr, nargs, 2);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tcall_flags = 0;  /* not protected, respect reclimit, not constructor */\n\tduk_handle_call_unprotected(thr, idx_func, call_flags);\n}\n\nDUK_EXTERNAL void duk_call_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t nargs) {\n\t/*\n\t *  XXX: if duk_handle_call() took values through indices, this could be\n\t *  made much more sensible.  However, duk_handle_call() needs to fudge\n\t *  the 'this' and 'func' values to handle bound functions, which is now\n\t *  done \"in-place\", so this is not a trivial change.\n\t */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);  /* make absolute */\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk__call_prop_prep_stack(thr, obj_idx, nargs);\n\n\tduk_call_method(thr, nargs);\n}\n\nDUK_LOCAL duk_ret_t duk__pcall_raw(duk_hthread *thr, void *udata) {\n\tduk__pcall_args *args;\n\tduk_idx_t idx_func;\n\tduk_int_t ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\targs = (duk__pcall_args *) udata;\n\tidx_func = duk__call_get_idx_func_unvalidated(thr, args->nargs, 1);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tduk_insert_undefined(thr, idx_func + 1);\n\n\tret = duk_handle_call_unprotected(thr, idx_func, args->call_flags);\n\tDUK_ASSERT(ret == 0);\n\tDUK_UNREF(ret);\n\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_pcall(duk_hthread *thr, duk_idx_t nargs) {\n\tduk__pcall_args args;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\targs.nargs = nargs;\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\targs.call_flags = 0;\n\n\treturn duk_safe_call(thr, duk__pcall_raw, (void *) &args /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);\n}\n\nDUK_LOCAL duk_ret_t duk__pcall_method_raw(duk_hthread *thr, void *udata) {\n\tduk__pcall_method_args *args;\n\tduk_idx_t idx_func;\n\tduk_int_t ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\targs = (duk__pcall_method_args *) udata;\n\n\tidx_func = duk__call_get_idx_func_unvalidated(thr, args->nargs, 2);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tret = duk_handle_call_unprotected(thr, idx_func, args->call_flags);\n\tDUK_ASSERT(ret == 0);\n\tDUK_UNREF(ret);\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_int_t duk_pcall_method_flags(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags) {\n\tduk__pcall_method_args args;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\targs.nargs = nargs;\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\targs.call_flags = call_flags;\n\n\treturn duk_safe_call(thr, duk__pcall_method_raw, (void *) &args /*udata*/, nargs + 2 /*nargs*/, 1 /*nrets*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_pcall_method(duk_hthread *thr, duk_idx_t nargs) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_pcall_method_flags(thr, nargs, 0);\n}\n\nDUK_LOCAL duk_ret_t duk__pcall_prop_raw(duk_hthread *thr, void *udata) {\n\tduk__pcall_prop_args *args;\n\tduk_idx_t obj_idx;\n\tduk_int_t ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\targs = (duk__pcall_prop_args *) udata;\n\n\tobj_idx = duk_require_normalize_index(thr, args->obj_idx);  /* make absolute */\n\tduk__call_prop_prep_stack(thr, obj_idx, args->nargs);\n\n\tret = duk_handle_call_unprotected_nargs(thr, args->nargs, args->call_flags);\n\tDUK_ASSERT(ret == 0);\n\tDUK_UNREF(ret);\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_pcall_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t nargs) {\n\tduk__pcall_prop_args args;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\targs.obj_idx = obj_idx;\n\targs.nargs = nargs;\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\targs.call_flags = 0;\n\n\treturn duk_safe_call(thr, duk__pcall_prop_raw, (void *) &args /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_safe_call(duk_hthread *thr, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* nargs condition; fail if: top - bottom < nargs\n\t *                      <=>  top < bottom + nargs\n\t * nrets condition; fail if: end - (top - nargs) < nrets\n\t *                      <=>  end - top + nargs < nrets\n\t *                      <=>  end + nargs < top + nrets\n\t */\n\t/* XXX: check for any reserve? */\n\n\tif (DUK_UNLIKELY((nargs | nrets) < 0 ||  /* nargs < 0 || nrets < 0; OR sign bits */\n\t                 thr->valstack_top < thr->valstack_bottom + nargs ||        /* nargs too large compared to top */\n\t                 thr->valstack_end + nargs < thr->valstack_top + nrets)) {  /* nrets too large compared to reserve */\n\t\tDUK_D(DUK_DPRINT(\"not enough stack reserve for safe call or invalid arguments: \"\n\t\t                 \"nargs=%ld < 0 (?), nrets=%ld < 0 (?), top=%ld < bottom=%ld + nargs=%ld (?), \"\n\t\t                 \"end=%ld + nargs=%ld < top=%ld + nrets=%ld (?)\",\n\t\t                  (long) nargs,\n\t\t                  (long) nrets,\n\t\t                  (long) (thr->valstack_top - thr->valstack),\n\t\t                  (long) (thr->valstack_bottom - thr->valstack),\n\t\t                  (long) nargs,\n\t\t                  (long) (thr->valstack_end - thr->valstack),\n\t\t                  (long) nargs,\n\t\t                  (long) (thr->valstack_top - thr->valstack),\n\t\t                  (long) nrets));\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\n\trc = duk_handle_safe_call(thr,           /* thread */\n\t                          func,          /* func */\n\t                          udata,         /* udata */\n\t                          nargs,         /* num_stack_args */\n\t                          nrets);        /* num_stack_res */\n\n\treturn rc;\n}\n\nDUK_EXTERNAL void duk_new(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_idx_t idx_func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx_func = duk__call_get_idx_func(thr, nargs, 1);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tduk_push_object(thr);  /* default instance; internal proto updated by call handling */\n\tduk_insert(thr, idx_func + 1);\n\n\tduk_handle_call_unprotected(thr, idx_func, DUK_CALL_FLAG_CONSTRUCT);\n}\n\nDUK_LOCAL duk_ret_t duk__pnew_helper(duk_hthread *thr, void *udata) {\n\tduk_idx_t nargs;\n\n\tDUK_ASSERT(udata != NULL);\n\tnargs = *((duk_idx_t *) udata);\n\n\tduk_new(thr, nargs);\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_pnew(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* For now, just use duk_safe_call() to wrap duk_new().  We can't\n\t * simply use a protected duk_handle_call() because pushing the\n\t * default instance might throw.\n\t */\n\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\n\trc = duk_safe_call(thr, duk__pnew_helper, (void *) &nargs /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);\n\treturn rc;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_constructor_call(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\treturn ((act->flags & DUK_ACT_FLAG_CONSTRUCT) != 0 ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL void duk_require_constructor_call(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (!duk_is_constructor_call(thr)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_CONSTRUCT_ONLY);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_strict_call(duk_hthread *thr) {\n\tduk_activation *act;\n\n\t/* For user code this could just return 1 (strict) always\n\t * because all Duktape/C functions are considered strict,\n\t * and strict is also the default when nothing is running.\n\t * However, Duktape may call this function internally when\n\t * the current activation is an ECMAScript function, so\n\t * this cannot be replaced by a 'return 1' without fixing\n\t * the internal call sites.\n\t */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\treturn ((act->flags & DUK_ACT_FLAG_STRICT) != 0 ? 1 : 0);\n\t} else {\n\t\t/* Strict by default. */\n\t\treturn 1;\n\t}\n}\n\n/*\n *  Duktape/C function magic\n */\n\nDUK_EXTERNAL duk_int_t duk_get_current_magic(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_hobject *func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act) {\n\t\tfunc = DUK_ACT_GET_FUNC(act);\n\t\tif (!func) {\n\t\t\tduk_tval *tv = &act->tv_func;\n\t\t\tduk_small_uint_t lf_flags;\n\t\t\tlf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv);\n\t\t\treturn (duk_int_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags);\n\t\t}\n\t\tDUK_ASSERT(func != NULL);\n\n\t\tif (DUK_HOBJECT_IS_NATFUNC(func)) {\n\t\t\tduk_hnatfunc *nf = (duk_hnatfunc *) func;\n\t\t\treturn (duk_int_t) nf->magic;\n\t\t}\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_int_t duk_get_magic(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (!DUK_HOBJECT_HAS_NATFUNC(h)) {\n\t\t\tgoto type_error;\n\t\t}\n\t\treturn (duk_int_t) ((duk_hnatfunc *) h)->magic;\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_small_uint_t lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv);\n\t\treturn (duk_int_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags);\n\t}\n\n\t/* fall through */\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_UNEXPECTED_TYPE);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_EXTERNAL void duk_set_magic(duk_hthread *thr, duk_idx_t idx, duk_int_t magic) {\n\tduk_hnatfunc *nf;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tnf = duk_require_hnatfunc(thr, idx);\n\tDUK_ASSERT(nf != NULL);\n\tnf->magic = (duk_int16_t) magic;\n}\n\n/*\n *  Misc helpers\n */\n\n/* Resolve a bound function on value stack top to a non-bound target\n * (leave other values as is).\n */\nDUK_INTERNAL void duk_resolve_nonbound_function(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_HTHREAD_ASSERT_VALID(thr);\n\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(h)) {\n\t\t\tduk_push_tval(thr, &((duk_hboundfunc *) (void *) h)->target);\n\t\t\tduk_replace(thr, -2);\n#if 0\n\t\t\tDUK_TVAL_SET_TVAL(tv, &((duk_hboundfunc *) h)->target);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tDUK_HOBJECT_DECREF_NORZ(thr, h);\n#endif\n\t\t\t/* Rely on Function.prototype.bind() on never creating a bound\n\t\t\t * function whose target is not proper.  This is now safe\n\t\t\t * because the target is not even an internal property but a\n\t\t\t * struct member.\n\t\t\t */\n\t\t\tDUK_ASSERT(duk_is_lightfunc(thr, -1) || duk_is_callable(thr, -1));\n\t\t}\n\t}\n\n\t/* Lightfuncs cannot be bound but are always callable and\n\t * constructable.\n\t */\n}\n/*\n *  Encoding and decoding basic formats: hex, base64.\n *\n *  These are in-place operations which may allow an optimized implementation.\n *\n *  Base-64: https://tools.ietf.org/html/rfc4648#section-4\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Misc helpers\n */\n\n/* Shared handling for encode/decode argument.  Fast path handling for\n * buffer and string values because they're the most common.  In particular,\n * avoid creating a temporary string or buffer when possible.  Return value\n * is guaranteed to be non-NULL, even for zero length input.\n */\nDUK_LOCAL const duk_uint8_t *duk__prep_codec_arg(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tconst void *def_ptr = (const void *) out_len;  /* Any non-NULL pointer will do. */\n\tconst void *ptr;\n\tduk_bool_t isbuffer;\n\n\tDUK_ASSERT(out_len != NULL);\n\tDUK_ASSERT(def_ptr != NULL);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx));  /* checked by caller */\n\n\tptr = (const void *) duk_get_buffer_data_raw(thr, idx, out_len, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, &isbuffer);\n\tif (isbuffer) {\n\t\tDUK_ASSERT(ptr != NULL || *out_len == 0U);\n\t\tif (DUK_UNLIKELY(ptr == NULL)) {\n\t\t\tptr = def_ptr;\n\t\t}\n\t\tDUK_ASSERT(ptr != NULL);\n\t} else {\n\t\t/* For strings a non-NULL pointer is always guaranteed because\n\t\t * at least a NUL will be present.\n\t\t */\n\t\tptr = (const void *) duk_to_lstring(thr, idx, out_len);\n\t\tDUK_ASSERT(ptr != NULL);\n\t}\n\tDUK_ASSERT(ptr != NULL);\n\treturn (const duk_uint8_t *) ptr;\n}\n\n/*\n *  Base64\n */\n\n#if defined(DUK_USE_BASE64_SUPPORT)\n/* Bytes emitted for number of padding characters in range [0,4]. */\nDUK_LOCAL const duk_int8_t duk__base64_decode_nequal_step[5] = {\n\t3,   /* #### -> 24 bits, emit 3 bytes */\n\t2,   /* ###= -> 18 bits, emit 2 bytes */\n\t1,   /* ##== -> 12 bits, emit 1 byte */\n\t-1,  /* #=== -> 6 bits, error */\n\t0,   /* ==== -> 0 bits, emit 0 bytes */\n};\n\n#if defined(DUK_USE_BASE64_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__base64_enctab_fast[64] = {\n\t0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, 0x50U,  /* A...P */\n\t0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, 0x58U, 0x59U, 0x5aU, 0x61U, 0x62U, 0x63U, 0x64U, 0x65U, 0x66U,  /* Q...f */\n\t0x67U, 0x68U, 0x69U, 0x6aU, 0x6bU, 0x6cU, 0x6dU, 0x6eU, 0x6fU, 0x70U, 0x71U, 0x72U, 0x73U, 0x74U, 0x75U, 0x76U,  /* g...v */\n\t0x77U, 0x78U, 0x79U, 0x7aU, 0x30U, 0x31U, 0x32U, 0x33U, 0x34U, 0x35U, 0x36U, 0x37U, 0x38U, 0x39U, 0x2bU, 0x2fU   /* w.../ */\n};\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\n#if defined(DUK_USE_BASE64_FASTPATH)\n/* Decode table for one byte of input:\n *   -1 = allowed whitespace\n *   -2 = padding\n *   -3 = error\n *    0...63 decoded bytes\n */\nDUK_LOCAL const duk_int8_t duk__base64_dectab_fast[256] = {\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -1, -1, -3, -3, -1, -3, -3,  /* 0x00...0x0f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0x10...0x1f */\n\t-1, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, 62, -3, -3, -3, 63,  /* 0x20...0x2f */\n\t52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -3, -3, -3, -2, -3, -3,  /* 0x30...0x3f */\n\t-3,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,  /* 0x40...0x4f */\n\t15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -3, -3, -3, -3, -3,  /* 0x50...0x5f */\n\t-3, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,  /* 0x60...0x6f */\n\t41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -3, -3, -3, -3, -3,  /* 0x70...0x7f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0x80...0x8f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0x90...0x9f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xa0...0xaf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xb0...0xbf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xc0...0xcf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xd0...0xdf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xe0...0xef */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3   /* 0xf0...0xff */\n};\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\n#if defined(DUK_USE_BASE64_FASTPATH)\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_3(const duk_uint8_t *src, duk_uint8_t *dst) {\n\tduk_uint_t t;\n\n\tt = (duk_uint_t) src[0];\n\tt = (t << 8) + (duk_uint_t) src[1];\n\tt = (t << 8) + (duk_uint_t) src[2];\n\n\tdst[0] = duk__base64_enctab_fast[t >> 18];\n\tdst[1] = duk__base64_enctab_fast[(t >> 12) & 0x3fU];\n\tdst[2] = duk__base64_enctab_fast[(t >> 6) & 0x3fU];\n\tdst[3] = duk__base64_enctab_fast[t & 0x3fU];\n\n#if 0\n\t/* Tested: not faster on x64, most likely due to aliasing between\n\t * output and input index computation.\n\t */\n\t/* aaaaaabb bbbbcccc ccdddddd */\n\tdst[0] = duk__base64_enctab_fast[(src[0] >> 2) & 0x3fU];\n\tdst[1] = duk__base64_enctab_fast[((src[0] << 4) & 0x30U) | ((src[1] >> 4) & 0x0fU)];\n\tdst[2] = duk__base64_enctab_fast[((src[1] << 2) & 0x3fU) | ((src[2] >> 6) & 0x03U)];\n\tdst[3] = duk__base64_enctab_fast[src[2] & 0x3fU];\n#endif\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_2(const duk_uint8_t *src, duk_uint8_t *dst) {\n\tduk_uint_t t;\n\n\tt = (duk_uint_t) src[0];\n\tt = (t << 8) + (duk_uint_t) src[1];\n\tdst[0] = duk__base64_enctab_fast[t >> 10];           /* XXXXXX-- -------- */\n\tdst[1] = duk__base64_enctab_fast[(t >> 4) & 0x3fU];  /* ------XX XXXX---- */\n\tdst[2] = duk__base64_enctab_fast[(t << 2) & 0x3fU];  /* -------- ----XXXX */\n\tdst[3] = DUK_ASC_EQUALS;\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_1(const duk_uint8_t *src, duk_uint8_t *dst) {\n\tduk_uint_t t;\n\n\tt = (duk_uint_t) src[0];\n\tdst[0] = duk__base64_enctab_fast[t >> 2];            /* XXXXXX-- */\n\tdst[1] = duk__base64_enctab_fast[(t << 4) & 0x3fU];  /* ------XX */\n\tdst[2] = DUK_ASC_EQUALS;\n\tdst[3] = DUK_ASC_EQUALS;\n}\n\nDUK_LOCAL void duk__base64_encode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst) {\n\tduk_size_t n;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t *q;\n\n\tn = srclen;\n\tp = src;\n\tq = dst;\n\n\tif (n >= 16U) {\n\t\t/* Fast path, unrolled by 4, allows interleaving.  Process\n\t\t * 12-byte input chunks which encode to 16-char output chunks.\n\t\t * Only enter when at least one block is emitted (avoids div+mul\n\t\t * for short inputs too).\n\t\t */\n\t\tconst duk_uint8_t *p_end_fast;\n\n\t\tp_end_fast = p + ((n / 12U) * 12U);\n\t\tDUK_ASSERT(p_end_fast >= p + 12);\n\t\tdo {\n\t\t\tduk__base64_encode_fast_3(p, q);\n\t\t\tduk__base64_encode_fast_3(p + 3, q + 4);\n\t\t\tduk__base64_encode_fast_3(p + 6, q + 8);\n\t\t\tduk__base64_encode_fast_3(p + 9, q + 12);\n\t\t\tp += 12;\n\t\t\tq += 16;\n\t\t} while (DUK_LIKELY(p != p_end_fast));\n\n\t\tDUK_ASSERT(src + srclen >= p);\n\t\tn = (duk_size_t) (src + srclen - p);\n\t\tDUK_ASSERT(n < 12U);\n\t}\n\n\t/* Remainder. */\n\twhile (n >= 3U) {\n\t\tduk__base64_encode_fast_3(p, q);\n\t\tp += 3;\n\t\tq += 4;\n\t\tn -= 3U;\n\t}\n\tDUK_ASSERT(n == 0U || n == 1U || n == 2U);\n\tif (n == 1U) {\n\t\tduk__base64_encode_fast_1(p, q);\n#if 0  /* Unnecessary. */\n\t\tp += 1;\n\t\tq += 4;\n\t\tn -= 1U;\n#endif\n\t} else if (n == 2U) {\n\t\tduk__base64_encode_fast_2(p, q);\n#if 0  /* Unnecessary. */\n\t\tp += 2;\n\t\tq += 4;\n\t\tn -= 2U;\n#endif\n\t} else {\n\t\tDUK_ASSERT(n == 0U);  /* nothing to do */\n\t\t;\n\t}\n}\n#else  /* DUK_USE_BASE64_FASTPATH */\nDUK_LOCAL void duk__base64_encode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst) {\n\tduk_small_uint_t i, npad;\n\tduk_uint_t t, x, y;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint8_t *q;\n\n\tp = src;\n\tp_end = src + srclen;\n\tq = dst;\n\tnpad = 0U;\n\n\twhile (p < p_end) {\n\t\t/* Read 3 bytes into 't', padded by zero. */\n\t\tt = 0;\n\t\tfor (i = 0; i < 3; i++) {\n\t\t\tt = t << 8;\n\t\t\tif (p < p_end) {\n\t\t\t\tt += (duk_uint_t) (*p++);\n\t\t\t} else {\n\t\t\t\t/* This only happens on the last loop and we're\n\t\t\t\t * guaranteed to exit on the next loop.\n\t\t\t\t */\n\t\t\t\tnpad++;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(npad <= 2U);\n\n\t\t/* Emit 4 encoded characters.  If npad > 0, some of the\n\t\t * chars will be incorrect (zero bits) but we fix up the\n\t\t * padding after the loop.  A straightforward 64-byte\n\t\t * lookup would be faster and cleaner, but this is shorter.\n\t\t */\n\t\tfor (i = 0; i < 4; i++) {\n\t\t\tx = ((t >> 18) & 0x3fU);\n\t\t\tt = t << 6;\n\n\t\t\tif (x <= 51U) {\n\t\t\t\tif (x <= 25) {\n\t\t\t\t\ty = x + DUK_ASC_UC_A;\n\t\t\t\t} else {\n\t\t\t\t\ty = x - 26 + DUK_ASC_LC_A;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (x <= 61U) {\n\t\t\t\t\ty = x - 52 + DUK_ASC_0;\n\t\t\t\t} else if (x == 62) {\n\t\t\t\t\ty = DUK_ASC_PLUS;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(x == 63);\n\t\t\t\t\ty = DUK_ASC_SLASH;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t*q++ = (duk_uint8_t) y;\n\t\t}\n\t}\n\n\t/* Handle padding by rewriting 0-2 bogus characters at the end.\n\t *\n\t *  Missing bytes    npad     base64 example\n\t *    0               0         ####\n\t *    1               1         ###=\n\t *    2               2         ##==\n\t */\n\tDUK_ASSERT(npad <= 2U);\n\twhile (npad > 0U) {\n\t\t*(q - npad) = DUK_ASC_EQUALS;\n\t\tnpad--;\n\t}\n}\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\n#if defined(DUK_USE_BASE64_FASTPATH)\nDUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst, duk_uint8_t **out_dst_final) {\n\tduk_int_t x;\n\tduk_uint_t t;\n\tduk_small_uint_t n_equal;\n\tduk_int8_t step;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint8_t *p_end_safe;\n\tduk_uint8_t *q;\n\n\tDUK_ASSERT(src != NULL);  /* Required by pointer arithmetic below, which fails for NULL. */\n\n\tp = src;\n\tp_end = src + srclen;\n\tp_end_safe = p_end - 8;  /* If 'src <= src_end_safe', safe to read 8 bytes. */\n\tq = dst;\n\n\t/* Alternate between a fast path which processes clean groups with no\n\t * padding or whitespace, and a slow path which processes one arbitrary\n\t * group and then re-enters the fast path.  This handles e.g. base64\n\t * with newlines reasonably well because the majority of a line is in\n\t * the fast path.\n\t */\n\tfor (;;) {\n\t\t/* Fast path, on each loop handle two 4-char input groups.\n\t\t * If both are clean, emit 6 bytes and continue.  If first\n\t\t * is clean, emit 3 bytes and drop out; otherwise emit\n\t\t * nothing and drop out.  This approach could be extended to\n\t\t * more groups per loop, but for inputs with e.g. periodic\n\t\t * newlines (which are common) it might not be an improvement.\n\t\t */\n\t\twhile (DUK_LIKELY(p <= p_end_safe)) {\n\t\t\tduk_int_t t1, t2;\n\n\t\t\t/* The lookup byte is intentionally sign extended to\n\t\t\t * (at least) 32 bits and then ORed.  This ensures\n\t\t\t * that is at least 1 byte is negative, the highest\n\t\t\t * bit of the accumulator will be set at the end and\n\t\t\t * we don't need to check every byte.\n\t\t\t *\n\t\t\t * Read all input bytes first before writing output\n\t\t\t * bytes to minimize aliasing.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast loop: p=%p, p_end_safe=%p, p_end=%p\",\n\t\t\t                     (const void *) p, (const void *) p_end_safe, (const void *) p_end));\n\n\t\t\tt1 = (duk_int_t) duk__base64_dectab_fast[p[0]];\n\t\t\tt1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[1]];\n\t\t\tt1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[2]];\n\t\t\tt1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[3]];\n\n\t\t\tt2 = (duk_int_t) duk__base64_dectab_fast[p[4]];\n\t\t\tt2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[5]];\n\t\t\tt2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[6]];\n\t\t\tt2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[7]];\n\n\t\t\tq[0] = (duk_uint8_t) (((duk_uint_t) t1 >> 16) & 0xffU);\n\t\t\tq[1] = (duk_uint8_t) (((duk_uint_t) t1 >> 8) & 0xffU);\n\t\t\tq[2] = (duk_uint8_t) ((duk_uint_t) t1 & 0xffU);\n\n\t\t\tq[3] = (duk_uint8_t) (((duk_uint_t) t2 >> 16) & 0xffU);\n\t\t\tq[4] = (duk_uint8_t) (((duk_uint_t) t2 >> 8) & 0xffU);\n\t\t\tq[5] = (duk_uint8_t) ((duk_uint_t) t2 & 0xffU);\n\n\t\t\t/* Optimistic check using one branch. */\n\t\t\tif (DUK_LIKELY((t1 | t2) >= 0)) {\n\t\t\t\tp += 8;\n\t\t\t\tq += 6;\n\t\t\t} else if (t1 >= 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast loop first group was clean, second was not, process one slow path group\"));\n\t\t\t\tDUK_ASSERT(t2 < 0);\n\t\t\t\tp += 4;\n\t\t\t\tq += 3;\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast loop first group was not clean, second does not matter, process one slow path group\"));\n\t\t\t\tDUK_ASSERT(t1 < 0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}  /* fast path */\n\n\t\t/* Slow path step 1: try to scan a 4-character encoded group,\n\t\t * end-of-input, or start-of-padding.  We exit with:\n\t\t *   1. n_chars == 4: full group, no padding, no end-of-input.\n\t\t *   2. n_chars < 4: partial group (may also be 0), encountered\n\t\t *      padding or end of input.\n\t\t *\n\t\t * The accumulator is initialized to 1; this allows us to detect\n\t\t * a full group by comparing >= 0x1000000 without an extra\n\t\t * counter variable.\n\t\t */\n\t\tt = 1UL;\n\t\tfor (;;) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slow loop: p=%p, p_end=%p, t=%lu\",\n\t\t\t                     (const void *) p, (const void *) p_end, (unsigned long) t));\n\n\t\t\tif (DUK_LIKELY(p < p_end)) {\n\t\t\t\tx = duk__base64_dectab_fast[*p++];\n\t\t\t\tif (DUK_LIKELY(x >= 0)) {\n\t\t\t\t\tDUK_ASSERT(x >= 0 && x <= 63);\n\t\t\t\t\tt = (t << 6) + (duk_uint_t) x;\n\t\t\t\t\tif (t >= 0x1000000UL) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} else if (x == -1) {\n\t\t\t\t\tcontinue;  /* allowed ascii whitespace */\n\t\t\t\t} else if (x == -2) {\n\t\t\t\t\tp--;\n\t\t\t\t\tbreak;  /* start of padding */\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(x == -3);\n\t\t\t\t\tgoto decode_error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tbreak;  /* end of input */\n\t\t\t}\n\t\t}  /* slow path step 1 */\n\n\t\t/* Complete the padding by simulating pad characters,\n\t\t * regardless of actual input padding chars.\n\t\t */\n\t\tn_equal = 0;\n\t\twhile (t < 0x1000000UL) {\n\t\t\tt = (t << 6) + 0U;\n\t\t\tn_equal++;\n\t\t}\n\n\t\t/* Slow path step 2: deal with full/partial group, padding,\n\t\t * etc.  Note that for num chars in [0,3] we intentionally emit\n\t\t * 3 bytes but don't step forward that much, buffer space is\n\t\t * guaranteed in setup.\n\t\t *\n\t\t *  num chars:\n\t\t *   0      ####   no output (= step 0)\n\t\t *   1      #===   reject, 6 bits of data\n\t\t *   2      ##==   12 bits of data, output 1 byte (= step 1)\n\t\t *   3      ###=   18 bits of data, output 2 bytes (= step 2)\n\t\t *   4      ####   24 bits of data, output 3 bytes (= step 3)\n\t\t */\n\t\tq[0] = (duk_uint8_t) ((t >> 16) & 0xffU);\n\t\tq[1] = (duk_uint8_t) ((t >> 8) & 0xffU);\n\t\tq[2] = (duk_uint8_t) (t & 0xffU);\n\n\t\tDUK_ASSERT(n_equal <= 4);\n\t\tstep = duk__base64_decode_nequal_step[n_equal];\n\t\tif (DUK_UNLIKELY(step < 0)) {\n\t\t\tgoto decode_error;\n\t\t}\n\t\tq += step;\n\n\t\t/* Slow path step 3: read and ignore padding and whitespace\n\t\t * until (a) next non-padding and non-whitespace character\n\t\t * after which we resume the fast path, or (b) end of input.\n\t\t * This allows us to accept missing, partial, full, and extra\n\t\t * padding cases uniformly.  We also support concatenated\n\t\t * base-64 documents because we resume scanning afterwards.\n\t\t *\n\t\t * Note that to support concatenated documents well, the '='\n\t\t * padding found inside the input must also allow for 'extra'\n\t\t * padding.  For example, 'Zm===' decodes to 'f' and has one\n\t\t * extra padding char.  So, 'Zm===Zm' should decode 'ff', even\n\t\t * though the standard break-up would be 'Zm==' + '=Zm' which\n\t\t * doesn't make sense.\n\t\t *\n\t\t * We also accept prepended padding like '==Zm9', because it\n\t\t * is equivalent to an empty document with extra padding ('==')\n\t\t * followed by a valid document.\n\t\t */\n\n\t\tfor (;;) {\n\t\t\tif (DUK_UNLIKELY(p >= p_end)) {\n\t\t\t\tgoto done;\n\t\t\t}\n\t\t\tx = duk__base64_dectab_fast[*p++];\n\t\t\tif (x == -1 || x == -2) {\n\t\t\t\t;  /* padding or whitespace, keep eating */\n\t\t\t} else {\n\t\t\t\tp--;\n\t\t\t\tbreak;  /* backtrack and go back to fast path, even for -1 */\n\t\t\t}\n\t\t}  /* slow path step 3 */\n\t}  /* outer fast+slow path loop */\n\n done:\n\tDUK_DDD(DUK_DDDPRINT(\"done; p=%p, p_end=%p\",\n\t                     (const void *) p, (const void *) p_end));\n\n\tDUK_ASSERT(p == p_end);\n\n\t*out_dst_final = q;\n\treturn 1;\n\n decode_error:\n\treturn 0;\n}\n#else  /* DUK_USE_BASE64_FASTPATH */\nDUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst, duk_uint8_t **out_dst_final) {\n\tduk_uint_t t, x;\n\tduk_int_t y;\n\tduk_int8_t step;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint8_t *q;\n\t/* 0x09, 0x0a, or 0x0d */\n\tduk_uint32_t mask_white = (1U << 9) | (1U << 10) | (1U << 13);\n\n\t/* 't' tracks progress of the decoded group:\n\t *\n\t *  t == 1             no valid chars yet\n\t *  t >= 0x40          1x6 = 6 bits shifted in\n\t *  t >= 0x1000        2x6 = 12 bits shifted in\n\t *  t >= 0x40000       3x6 = 18 bits shifted in\n\t *  t >= 0x1000000     4x6 = 24 bits shifted in\n\t *\n\t * By initializing t=1 there's no need for a separate counter for\n\t * the number of characters found so far.\n\t */\n\tp = src;\n\tp_end = src + srclen;\n\tq = dst;\n\tt = 1UL;\n\n\tfor (;;) {\n\t\tduk_small_uint_t n_equal;\n\n\t\tDUK_ASSERT(t >= 1U);\n\t\tif (p >= p_end) {\n\t\t\t/* End of input: if input exists, treat like\n\t\t\t * start of padding, finish the block, then\n\t\t\t * re-enter here to see we're done.\n\t\t\t */\n\t\t\tif (t == 1U) {\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tgoto simulate_padding;\n\t\t\t}\n\t\t}\n\n\t\tx = *p++;\n\n\t\tif (x >= 0x41U) {\n\t\t\t/* Valid: a-z and A-Z. */\n\t\t\tDUK_ASSERT(x >= 0x41U && x <= 0xffU);\n\t\t\tif (x >= 0x61U && x <= 0x7aU) {\n\t\t\t\ty = (duk_int_t) x - 0x61 + 26;\n\t\t\t} else if (x <= 0x5aU) {\n\t\t\t\ty = (duk_int_t) x - 0x41;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t} else if (x >= 0x30U) {\n\t\t\t/* Valid: 0-9 and =. */\n\t\t\tDUK_ASSERT(x >= 0x30U && x <= 0x40U);\n\t\t\tif (x <= 0x39U) {\n\t\t\t\ty = (duk_int_t) x - 0x30 + 52;\n\t\t\t} else if (x == 0x3dU) {\n\t\t\t\t/* Skip padding and whitespace unless we're in the\n\t\t\t\t * middle of a block.  Otherwise complete group by\n\t\t\t\t * simulating shifting in the correct padding.\n\t\t\t\t */\n\t\t\t\tif (t == 1U) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tgoto simulate_padding;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t} else if (x >= 0x20U) {\n\t\t\t/* Valid: +, /, and 0x20 whitespace. */\n\t\t\tDUK_ASSERT(x >= 0x20U && x <= 0x2fU);\n\t\t\tif (x == 0x2bU) {\n\t\t\t\ty = 62;\n\t\t\t} else if (x == 0x2fU) {\n\t\t\t\ty = 63;\n\t\t\t} else if (x == 0x20U) {\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t} else {\n\t\t\t/* Valid: whitespace. */\n\t\t\tduk_uint32_t m;\n\t\t\tDUK_ASSERT(x < 0x20U);  /* 0x00 to 0x1f */\n\t\t\tm = (1U << x);\n\t\t\tif (mask_white & m) {\n\t\t\t\t/* Allow basic ASCII whitespace. */\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t}\n\n\t\tDUK_ASSERT(y >= 0 && y <= 63);\n\t\tt = (t << 6) + (duk_uint_t) y;\n\t\tif (t < 0x1000000UL) {\n\t\t\tcontinue;\n\t\t}\n\t\t/* fall through; no padding will be added */\n\n\t simulate_padding:\n\t\tn_equal = 0;\n\t\twhile (t < 0x1000000UL) {\n\t\t\tt = (t << 6) + 0U;\n\t\t\tn_equal++;\n\t\t}\n\n\t\t/* Output 3 bytes from 't' and advance as needed. */\n\t\tq[0] = (duk_uint8_t) ((t >> 16) & 0xffU);\n\t\tq[1] = (duk_uint8_t) ((t >> 8) & 0xffU);\n\t\tq[2] = (duk_uint8_t) (t & 0xffU);\n\n\t\tDUK_ASSERT(n_equal <= 4U);\n\t\tstep = duk__base64_decode_nequal_step[n_equal];\n\t\tif (step < 0) {\n\t\t\tgoto decode_error;\n\t\t}\n\t\tq += step;\n\n\t\t/* Re-enter loop.  The actual padding characters are skipped\n\t\t * by the main loop.  This handles cases like missing, partial,\n\t\t * full, and extra padding, and allows parsing of concatenated\n\t\t * documents (with extra padding) like: Zm===Zm.  Also extra\n\t\t * prepended padding is accepted: ===Zm9v.\n\t\t */\n\t\tt = 1U;\n\t}\n\tDUK_ASSERT(t == 1UL);\n\n\t*out_dst_final = q;\n\treturn 1;\n\n decode_error:\n\treturn 0;\n}\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\nDUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *src;\n\tduk_size_t srclen;\n\tduk_size_t dstlen;\n\tduk_uint8_t *dst;\n\tconst char *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tsrc = duk__prep_codec_arg(thr, idx, &srclen);\n\tDUK_ASSERT(src != NULL);\n\n\t/* Compute exact output length.  Computation must not wrap; this\n\t * limit works for 32-bit size_t:\n\t * >>> srclen = 3221225469\n\t * >>> '%x' % ((srclen + 2) / 3 * 4)\n\t * 'fffffffc'\n\t */\n\tif (srclen > 3221225469UL) {\n\t\tgoto type_error;\n\t}\n\tdstlen = (srclen + 2U) / 3U * 4U;\n\tdst = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, dstlen);\n\n\tduk__base64_encode_helper((const duk_uint8_t *) src, srclen, dst);\n\n\tret = duk_buffer_to_string(thr, -1);  /* Safe, result is ASCII. */\n\tduk_replace(thr, idx);\n\treturn ret;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_BASE64_ENCODE_FAILED);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *src;\n\tduk_size_t srclen;\n\tduk_size_t dstlen;\n\tduk_uint8_t *dst;\n\tduk_uint8_t *dst_final;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tsrc = duk__prep_codec_arg(thr, idx, &srclen);\n\tDUK_ASSERT(src != NULL);\n\n\t/* Round up and add safety margin.  Avoid addition before division to\n\t * avoid possibility of wrapping.  Margin includes +3 for rounding up,\n\t * and +3 for one extra group: the decoder may emit and then backtrack\n\t * a full group (3 bytes) from zero-sized input for technical reasons.\n\t * Similarly, 'xx' may ecause 1+3 = bytes to be emitted and then\n\t * backtracked.\n\t */\n\tdstlen = (srclen / 4) * 3 + 6;  /* upper limit, assuming no whitespace etc */\n\tdst = (duk_uint8_t *) duk_push_dynamic_buffer(thr, dstlen);\n\t/* Note: for dstlen=0, dst may be NULL */\n\n\tif (!duk__base64_decode_helper((const duk_uint8_t *) src, srclen, dst, &dst_final)) {\n\t\tgoto type_error;\n\t}\n\n\t/* XXX: convert to fixed buffer? */\n\t(void) duk_resize_buffer(thr, -1, (duk_size_t) (dst_final - dst));\n\tduk_replace(thr, idx);\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_BASE64_DECODE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n#else  /* DUK_USE_BASE64_SUPPORT */\nDUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_BASE64_SUPPORT */\n\n/*\n *  Hex\n */\n\n#if defined(DUK_USE_HEX_SUPPORT)\nDUK_EXTERNAL const char *duk_hex_encode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *inp;\n\tduk_size_t len;\n\tduk_size_t i;\n\tduk_uint8_t *buf;\n\tconst char *ret;\n#if defined(DUK_USE_HEX_FASTPATH)\n\tduk_size_t len_safe;\n\tduk_uint16_t *p16;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tinp = duk__prep_codec_arg(thr, idx, &len);\n\tDUK_ASSERT(inp != NULL);\n\n\t/* Fixed buffer, no zeroing because we'll fill all the data. */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len * 2);\n\tDUK_ASSERT(buf != NULL);\n\n#if defined(DUK_USE_HEX_FASTPATH)\n\tDUK_ASSERT((((duk_size_t) buf) & 0x01U) == 0);   /* pointer is aligned, guaranteed for fixed buffer */\n\tp16 = (duk_uint16_t *) (void *) buf;\n\tlen_safe = len & ~0x03U;\n\tfor (i = 0; i < len_safe; i += 4) {\n\t\tp16[0] = duk_hex_enctab[inp[i]];\n\t\tp16[1] = duk_hex_enctab[inp[i + 1]];\n\t\tp16[2] = duk_hex_enctab[inp[i + 2]];\n\t\tp16[3] = duk_hex_enctab[inp[i + 3]];\n\t\tp16 += 4;\n\t}\n\tfor (; i < len; i++) {\n\t\t*p16++ = duk_hex_enctab[inp[i]];\n\t}\n#else  /* DUK_USE_HEX_FASTPATH */\n\tfor (i = 0; i < len; i++) {\n\t\tduk_small_uint_t t;\n\t\tt = (duk_small_uint_t) inp[i];\n\t\tbuf[i*2 + 0] = duk_lc_digits[t >> 4];\n\t\tbuf[i*2 + 1] = duk_lc_digits[t & 0x0f];\n\t}\n#endif  /* DUK_USE_HEX_FASTPATH */\n\n\t/* XXX: Using a string return value forces a string intern which is\n\t * not always necessary.  As a rough performance measure, hex encode\n\t * time for tests/perf/test-hex-encode.js dropped from ~35s to ~15s\n\t * without string coercion.  Change to returning a buffer and let the\n\t * caller coerce to string if necessary?\n\t */\n\n\tret = duk_buffer_to_string(thr, -1);  /* Safe, result is ASCII. */\n\tduk_replace(thr, idx);\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *inp;\n\tduk_size_t len;\n\tduk_size_t i;\n\tduk_int_t t;\n\tduk_uint8_t *buf;\n#if defined(DUK_USE_HEX_FASTPATH)\n\tduk_int_t chk;\n\tduk_uint8_t *p;\n\tduk_size_t len_safe;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tinp = duk__prep_codec_arg(thr, idx, &len);\n\tDUK_ASSERT(inp != NULL);\n\n\tif (len & 0x01) {\n\t\tgoto type_error;\n\t}\n\n\t/* Fixed buffer, no zeroing because we'll fill all the data. */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len / 2);\n\tDUK_ASSERT(buf != NULL);\n\n#if defined(DUK_USE_HEX_FASTPATH)\n\tp = buf;\n\tlen_safe = len & ~0x07U;\n\tfor (i = 0; i < len_safe; i += 8) {\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 1]]);\n\t\tchk = t;\n\t\tp[0] = (duk_uint8_t) t;\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 2]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 3]]);\n\t\tchk |= t;\n\t\tp[1] = (duk_uint8_t) t;\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 4]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 5]]);\n\t\tchk |= t;\n\t\tp[2] = (duk_uint8_t) t;\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 6]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 7]]);\n\t\tchk |= t;\n\t\tp[3] = (duk_uint8_t) t;\n\t\tp += 4;\n\n\t\t/* Check if any lookup above had a negative result. */\n\t\tif (DUK_UNLIKELY(chk < 0)) {\n\t\t\tgoto type_error;\n\t\t}\n\t}\n\tfor (; i < len; i += 2) {\n\t\t/* First cast to duk_int_t to sign extend, second cast to\n\t\t * duk_uint_t to avoid signed left shift, and final cast to\n\t\t * duk_int_t result type.\n\t\t */\n\t\tt = (duk_int_t) ((((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i]]) << 4U) |\n\t\t                 ((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i + 1]]));\n\t\tif (DUK_UNLIKELY(t < 0)) {\n\t\t\tgoto type_error;\n\t\t}\n\t\t*p++ = (duk_uint8_t) t;\n\t}\n#else  /* DUK_USE_HEX_FASTPATH */\n\tfor (i = 0; i < len; i += 2) {\n\t\t/* For invalid characters the value -1 gets extended to\n\t\t * at least 16 bits.  If either nybble is invalid, the\n\t\t * resulting 't' will be < 0.\n\t\t */\n\t\tt = (duk_int_t) ((((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i]]) << 4U) |\n\t\t                 ((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i + 1]]));\n\t\tif (DUK_UNLIKELY(t < 0)) {\n\t\t\tgoto type_error;\n\t\t}\n\t\tbuf[i >> 1] = (duk_uint8_t) t;\n\t}\n#endif  /* DUK_USE_HEX_FASTPATH */\n\n\tduk_replace(thr, idx);\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_HEX_DECODE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n#else  /* DUK_USE_HEX_SUPPORT */\nDUK_EXTERNAL const char *duk_hex_encode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\nDUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_HEX_SUPPORT */\n\n/*\n *  JSON\n */\n\n#if defined(DUK_USE_JSON_SUPPORT)\nDUK_EXTERNAL const char *duk_json_encode(duk_hthread *thr, duk_idx_t idx) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t top_at_entry;\n#endif\n\tconst char *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\ttop_at_entry = duk_get_top(thr);\n#endif\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tduk_bi_json_stringify_helper(thr,\n\t                             idx /*idx_value*/,\n\t                             DUK_INVALID_INDEX /*idx_replacer*/,\n\t                             DUK_INVALID_INDEX /*idx_space*/,\n\t                             0 /*flags*/);\n\tDUK_ASSERT(duk_is_string(thr, -1));\n\tduk_replace(thr, idx);\n\tret = duk_get_string(thr, idx);\n\n\tDUK_ASSERT(duk_get_top(thr) == top_at_entry);\n\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_json_decode(duk_hthread *thr, duk_idx_t idx) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t top_at_entry;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\ttop_at_entry = duk_get_top(thr);\n#endif\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tduk_bi_json_parse_helper(thr,\n\t                         idx /*idx_value*/,\n\t                         DUK_INVALID_INDEX /*idx_reviver*/,\n\t                         0 /*flags*/);\n\tduk_replace(thr, idx);\n\n\tDUK_ASSERT(duk_get_top(thr) == top_at_entry);\n}\n#else  /* DUK_USE_JSON_SUPPORT */\nDUK_EXTERNAL const char *duk_json_encode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_EXTERNAL void duk_json_decode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_JSON_SUPPORT */\n/*\n *  Compilation and evaluation\n */\n\n/* #include duk_internal.h -> already included */\n\ntypedef struct duk__compile_raw_args duk__compile_raw_args;\nstruct duk__compile_raw_args {\n\tduk_size_t src_length;  /* should be first on 64-bit platforms */\n\tconst duk_uint8_t *src_buffer;\n\tduk_uint_t flags;\n};\n\n/* Eval is just a wrapper now. */\nDUK_EXTERNAL duk_int_t duk_eval_raw(duk_hthread *thr, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: strictness is *not* inherited from the current Duktape/C.\n\t * This would be confusing because the current strictness state\n\t * depends on whether we're running inside a Duktape/C activation\n\t * (= strict mode) or outside of any activation (= non-strict mode).\n\t * See tests/api/test-eval-strictness.c for more discussion.\n\t */\n\n\t/* [ ... source? filename? ] (depends on flags) */\n\n\trc = duk_compile_raw(thr, src_buffer, src_length, flags | DUK_COMPILE_EVAL);  /* may be safe, or non-safe depending on flags */\n\n\t/* [ ... closure/error ] */\n\n\tif (rc != DUK_EXEC_SUCCESS) {\n\t\trc = DUK_EXEC_ERROR;\n\t\tgoto got_rc;\n\t}\n\n\tduk_push_global_object(thr);  /* explicit 'this' binding, see GH-164 */\n\n\tif (flags & DUK_COMPILE_SAFE) {\n\t\trc = duk_pcall_method(thr, 0);\n\t} else {\n\t\tduk_call_method(thr, 0);\n\t\trc = DUK_EXEC_SUCCESS;\n\t}\n\n\t/* [ ... result/error ] */\n\n got_rc:\n\tif (flags & DUK_COMPILE_NORESULT) {\n\t\tduk_pop(thr);\n\t}\n\n\treturn rc;\n}\n\n/* Helper which can be called both directly and with duk_safe_call(). */\nDUK_LOCAL duk_ret_t duk__do_compile(duk_hthread *thr, void *udata) {\n\tduk__compile_raw_args *comp_args;\n\tduk_uint_t flags;\n\tduk_hcompfunc *h_templ;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\t/* Note: strictness is not inherited from the current Duktape/C\n\t * context.  Otherwise it would not be possible to compile\n\t * non-strict code inside a Duktape/C activation (which is\n\t * always strict now).  See tests/api/test-eval-strictness.c\n\t * for discussion.\n\t */\n\n\t/* [ ... source? filename? ] (depends on flags) */\n\n\tcomp_args = (duk__compile_raw_args *) udata;\n\tflags = comp_args->flags;\n\n\tif (flags & DUK_COMPILE_NOFILENAME) {\n\t\t/* Automatic filename: 'eval' or 'input'. */\n\t\tduk_push_hstring_stridx(thr, (flags & DUK_COMPILE_EVAL) ? DUK_STRIDX_EVAL : DUK_STRIDX_INPUT);\n\t}\n\n\t/* [ ... source? filename ] */\n\n\tif (!comp_args->src_buffer) {\n\t\tduk_hstring *h_sourcecode;\n\n\t\th_sourcecode = duk_get_hstring(thr, -2);\n\t\tif ((flags & DUK_COMPILE_NOSOURCE) ||  /* args incorrect */\n\t\t    (h_sourcecode == NULL)) {          /* e.g. duk_push_string_file_raw() pushed undefined */\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_NO_SOURCECODE);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tDUK_ASSERT(h_sourcecode != NULL);\n\t\tcomp_args->src_buffer = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_sourcecode);\n\t\tcomp_args->src_length = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sourcecode);\n\t}\n\tDUK_ASSERT(comp_args->src_buffer != NULL);\n\n\tif (flags & DUK_COMPILE_FUNCTION) {\n\t\tflags |= DUK_COMPILE_EVAL | DUK_COMPILE_FUNCEXPR;\n\t}\n\n\t/* [ ... source? filename ] */\n\n\tduk_js_compile(thr, comp_args->src_buffer, comp_args->src_length, flags);\n\n\t/* [ ... source? func_template ] */\n\n\tif (flags & DUK_COMPILE_NOSOURCE) {\n\t\t;\n\t} else {\n\t\tduk_remove_m2(thr);\n\t}\n\n\t/* [ ... func_template ] */\n\n\th_templ = (duk_hcompfunc *) duk_known_hobject(thr, -1);\n\tduk_js_push_closure(thr,\n\t                   h_templ,\n\t                   thr->builtins[DUK_BIDX_GLOBAL_ENV],\n\t                   thr->builtins[DUK_BIDX_GLOBAL_ENV],\n\t                   1 /*add_auto_proto*/);\n\tduk_remove_m2(thr);   /* -> [ ... closure ] */\n\n\t/* [ ... closure ] */\n\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_compile_raw(duk_hthread *thr, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) {\n\tduk__compile_raw_args comp_args_alloc;\n\tduk__compile_raw_args *comp_args = &comp_args_alloc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif ((flags & DUK_COMPILE_STRLEN) && (src_buffer != NULL)) {\n\t\t/* String length is computed here to avoid multiple evaluation\n\t\t * of a macro argument in the calling side.\n\t\t */\n\t\tsrc_length = DUK_STRLEN(src_buffer);\n\t}\n\n\tcomp_args->src_buffer = (const duk_uint8_t *) src_buffer;\n\tcomp_args->src_length = src_length;\n\tcomp_args->flags = flags;\n\n\t/* [ ... source? filename? ] (depends on flags) */\n\n\tif (flags & DUK_COMPILE_SAFE) {\n\t\tduk_int_t rc;\n\t\tduk_int_t nargs;\n\t\tduk_int_t nrets = 1;\n\n\t\t/* Arguments can be: [ source? filename? &comp_args] so that\n\t\t * nargs is 1 to 3.  Call site encodes the correct nargs count\n\t\t * directly into flags.\n\t\t */\n\t\tnargs = flags & 0x07;\n\t\tDUK_ASSERT(nargs == ((flags & DUK_COMPILE_NOSOURCE) ? 0 : 1) +\n\t\t                    ((flags & DUK_COMPILE_NOFILENAME) ? 0 : 1));\n\t\trc = duk_safe_call(thr, duk__do_compile, (void *) comp_args, nargs, nrets);\n\n\t\t/* [ ... closure ] */\n\t\treturn rc;\n\t}\n\n\t(void) duk__do_compile(thr, (void *) comp_args);\n\n\t/* [ ... closure ] */\n\treturn DUK_EXEC_SUCCESS;\n}\n/*\n *  Debugging related API calls\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_JSON_SUPPORT)\nDUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr) {\n\tduk_idx_t idx;\n\tduk_idx_t top;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* We don't duk_require_stack() here now, but rely on the caller having\n\t * enough space.\n\t */\n\n\ttop = duk_get_top(thr);\n\tduk_push_bare_array(thr);\n\tfor (idx = 0; idx < top; idx++) {\n\t\tduk_dup(thr, idx);\n\t\tduk_put_prop_index(thr, -2, (duk_uarridx_t) idx);\n\t}\n\n\t/* XXX: conversion errors should not propagate outwards.\n\t * Perhaps values need to be coerced individually?\n\t */\n\tduk_bi_json_stringify_helper(thr,\n\t                             duk_get_top_index(thr),  /*idx_value*/\n\t                             DUK_INVALID_INDEX,  /*idx_replacer*/\n\t                             DUK_INVALID_INDEX,  /*idx_space*/\n\t                             DUK_JSON_FLAG_EXT_CUSTOM |\n\t                             DUK_JSON_FLAG_ASCII_ONLY |\n\t                             DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/);\n\n\tduk_push_sprintf(thr, \"ctx: top=%ld, stack=%s\", (long) top, (const char *) duk_safe_to_string(thr, -1));\n\tduk_replace(thr, -3);  /* [ ... arr jsonx(arr) res ] -> [ ... res jsonx(arr) ] */\n\tduk_pop(thr);\n\tDUK_ASSERT(duk_is_string(thr, -1));\n}\n#else  /* DUK_USE_JSON_SUPPORT */\nDUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_JSON_SUPPORT */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\nDUK_EXTERNAL void duk_debugger_attach(duk_hthread *thr,\n                                      duk_debug_read_function read_cb,\n                                      duk_debug_write_function write_cb,\n                                      duk_debug_peek_function peek_cb,\n                                      duk_debug_read_flush_function read_flush_cb,\n                                      duk_debug_write_flush_function write_flush_cb,\n                                      duk_debug_request_function request_cb,\n                                      duk_debug_detached_function detached_cb,\n                                      void *udata) {\n\tduk_heap *heap;\n\tconst char *str;\n\tduk_size_t len;\n\n\t/* XXX: should there be an error or an automatic detach if\n\t * already attached?\n\t */\n\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_attach()\"));\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(read_cb != NULL);\n\tDUK_ASSERT(write_cb != NULL);\n\t/* Other callbacks are optional. */\n\n\theap = thr->heap;\n\theap->dbg_read_cb = read_cb;\n\theap->dbg_write_cb = write_cb;\n\theap->dbg_peek_cb = peek_cb;\n\theap->dbg_read_flush_cb = read_flush_cb;\n\theap->dbg_write_flush_cb = write_flush_cb;\n\theap->dbg_request_cb = request_cb;\n\theap->dbg_detached_cb = detached_cb;\n\theap->dbg_udata = udata;\n\theap->dbg_have_next_byte = 0;\n\n\t/* Start in paused state. */\n\theap->dbg_processing = 0;\n\theap->dbg_state_dirty = 0;\n\theap->dbg_force_restart = 0;\n\theap->dbg_pause_flags = 0;\n\theap->dbg_pause_act = NULL;\n\theap->dbg_pause_startline = 0;\n\theap->dbg_exec_counter = 0;\n\theap->dbg_last_counter = 0;\n\theap->dbg_last_time = 0.0;\n\tduk_debug_set_paused(heap);  /* XXX: overlap with fields above */\n\n\t/* Send version identification and flush right afterwards.  Note that\n\t * we must write raw, unframed bytes here.\n\t */\n\tduk_push_sprintf(thr, \"%ld %ld %s %s\\n\",\n\t                 (long) DUK_DEBUG_PROTOCOL_VERSION,\n\t                 (long) DUK_VERSION,\n\t                 (const char *) DUK_GIT_DESCRIBE,\n\t                 (const char *) DUK_USE_TARGET_INFO);\n\tstr = duk_get_lstring(thr, -1, &len);\n\tDUK_ASSERT(str != NULL);\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) str, len);\n\tduk_debug_write_flush(thr);\n\tduk_pop(thr);\n}\n\nDUK_EXTERNAL void duk_debugger_detach(duk_hthread *thr) {\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_detach()\"));\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\t/* Can be called multiple times with no harm. */\n\tduk_debug_do_detach(thr->heap);\n}\n\nDUK_EXTERNAL void duk_debugger_cooperate(duk_hthread *thr) {\n\tduk_bool_t processed_messages;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tif (!duk_debug_is_attached(thr->heap)) {\n\t\treturn;\n\t}\n\tif (thr->callstack_curr != NULL || thr->heap->dbg_processing) {\n\t\t/* Calling duk_debugger_cooperate() while Duktape is being\n\t\t * called into is not supported.  This is not a 100% check\n\t\t * but prevents any damage in most cases.\n\t\t */\n\t\treturn;\n\t}\n\n\tprocessed_messages = duk_debug_process_messages(thr, 1 /*no_block*/);\n\tDUK_UNREF(processed_messages);\n}\n\nDUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_hthread *thr, duk_idx_t nvalues) {\n\tduk_idx_t top;\n\tduk_idx_t idx;\n\tduk_bool_t ret = 0;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_notify() with nvalues=%ld\", (long) nvalues));\n\n\ttop = duk_get_top(thr);\n\tif (top < nvalues) {\n\t\tDUK_ERROR_RANGE(thr, \"not enough stack values for notify\");\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tduk_debug_write_notify(thr, DUK_DBG_CMD_APPNOTIFY);\n\t\tfor (idx = top - nvalues; idx < top; idx++) {\n\t\t\tduk_tval *tv = DUK_GET_TVAL_POSIDX(thr, idx);\n\t\t\tduk_debug_write_tval(thr, tv);\n\t\t}\n\t\tduk_debug_write_eom(thr);\n\n\t\t/* Return non-zero (true) if we have a good reason to believe\n\t\t * the notify was delivered; if we're still attached at least\n\t\t * a transport error was not indicated by the transport write\n\t\t * callback.  This is not a 100% guarantee of course.\n\t\t */\n\t\tif (duk_debug_is_attached(thr->heap)) {\n\t\t\tret = 1;\n\t\t}\n\t}\n\tduk_pop_n(thr, nvalues);\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_debugger_pause(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_pause()\"));\n\n\t/* Treat like a debugger statement: ignore when not attached. */\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tif (duk_debug_is_paused(thr->heap)) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_debugger_pause() called when already paused; ignoring\"));\n\t\t} else {\n\t\t\tduk_debug_set_paused(thr->heap);\n\n\t\t\t/* Pause on the next opcode executed.  This is always safe to do even\n\t\t\t * inside the debugger message loop: the interrupt counter will be reset\n\t\t\t * to its proper value when the message loop exits.\n\t\t\t */\n\t\t\tthr->interrupt_init = 1;\n\t\t\tthr->interrupt_counter = 0;\n\t\t}\n\t}\n}\n\n#else  /* DUK_USE_DEBUGGER_SUPPORT */\n\nDUK_EXTERNAL void duk_debugger_attach(duk_hthread *thr,\n                                      duk_debug_read_function read_cb,\n                                      duk_debug_write_function write_cb,\n                                      duk_debug_peek_function peek_cb,\n                                      duk_debug_read_flush_function read_flush_cb,\n                                      duk_debug_write_flush_function write_flush_cb,\n                                      duk_debug_request_function request_cb,\n                                      duk_debug_detached_function detached_cb,\n                                      void *udata) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(read_cb);\n\tDUK_UNREF(write_cb);\n\tDUK_UNREF(peek_cb);\n\tDUK_UNREF(read_flush_cb);\n\tDUK_UNREF(write_flush_cb);\n\tDUK_UNREF(request_cb);\n\tDUK_UNREF(detached_cb);\n\tDUK_UNREF(udata);\n\tDUK_ERROR_TYPE(thr, \"no debugger support\");\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_debugger_detach(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_TYPE(thr, \"no debugger support\");\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_debugger_cooperate(duk_hthread *thr) {\n\t/* nop */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n}\n\nDUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_hthread *thr, duk_idx_t nvalues) {\n\tduk_idx_t top;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttop = duk_get_top(thr);\n\tif (top < nvalues) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* No debugger support, just pop values. */\n\tduk_pop_n(thr, nvalues);\n\treturn 0;\n}\n\nDUK_EXTERNAL void duk_debugger_pause(duk_hthread *thr) {\n\t/* Treat like debugger statement: nop */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n}\n\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n/*\n *  Heap creation and destruction\n */\n\n/* #include duk_internal.h -> already included */\n\ntypedef struct duk_internal_thread_state duk_internal_thread_state;\n\nstruct duk_internal_thread_state {\n\tduk_ljstate lj;\n\tduk_bool_t creating_error;\n\tduk_hthread *curr_thread;\n\tduk_int_t call_recursion_depth;\n};\n\nDUK_EXTERNAL duk_hthread *duk_create_heap(duk_alloc_function alloc_func,\n                                          duk_realloc_function realloc_func,\n                                          duk_free_function free_func,\n                                          void *heap_udata,\n                                          duk_fatal_function fatal_handler) {\n\tduk_heap *heap = NULL;\n\tduk_hthread *thr;\n\n\t/* Assume that either all memory funcs are NULL or non-NULL, mixed\n\t * cases will now be unsafe.\n\t */\n\n\t/* XXX: just assert non-NULL values here and make caller arguments\n\t * do the defaulting to the default implementations (smaller code)?\n\t */\n\n\tif (!alloc_func) {\n\t\tDUK_ASSERT(realloc_func == NULL);\n\t\tDUK_ASSERT(free_func == NULL);\n#if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS)\n\t\talloc_func = duk_default_alloc_function;\n\t\trealloc_func = duk_default_realloc_function;\n\t\tfree_func = duk_default_free_function;\n#else\n\t\tDUK_D(DUK_DPRINT(\"no allocation functions given and no default providers\"));\n\t\treturn NULL;\n#endif\n\t} else {\n\t\tDUK_ASSERT(realloc_func != NULL);\n\t\tDUK_ASSERT(free_func != NULL);\n\t}\n\n\tif (!fatal_handler) {\n\t\tfatal_handler = duk_default_fatal_handler;\n\t}\n\n\tDUK_ASSERT(alloc_func != NULL);\n\tDUK_ASSERT(realloc_func != NULL);\n\tDUK_ASSERT(free_func != NULL);\n\tDUK_ASSERT(fatal_handler != NULL);\n\n\theap = duk_heap_alloc(alloc_func, realloc_func, free_func, heap_udata, fatal_handler);\n\tif (!heap) {\n\t\treturn NULL;\n\t}\n\tthr = heap->heap_thread;\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\treturn thr;\n}\n\nDUK_EXTERNAL void duk_destroy_heap(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tif (!thr) {\n\t\treturn;\n\t}\n\tDUK_ASSERT_API_ENTRY(thr);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tduk_heap_free(heap);\n}\n\nDUK_EXTERNAL void duk_suspend(duk_hthread *thr, duk_thread_state *state) {\n\tduk_internal_thread_state *snapshot = (duk_internal_thread_state *) (void *) state;\n\tduk_heap *heap;\n\tduk_ljstate *lj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(state != NULL);  /* unvalidated */\n\n\t/* Currently not supported when called from within a finalizer.\n\t * If that is done, the finalizer will remain running indefinitely,\n\t * preventing other finalizers from executing.  The assert is a bit\n\t * wider, checking that it would be OK to run pending finalizers.\n\t */\n\tDUK_ASSERT(thr->heap->pf_prevent_count == 0);\n\n\t/* Currently not supported to duk_suspend() from an errCreate()\n\t * call.\n\t */\n\tDUK_ASSERT(thr->heap->creating_error == 0);\n\n\theap = thr->heap;\n\tlj = &heap->lj;\n\n\tduk_push_tval(thr, &lj->value1);\n\tduk_push_tval(thr, &lj->value2);\n\n\t/* XXX: creating_error == 0 is asserted above, so no need to store. */\n\tduk_memcpy((void *) &snapshot->lj, (const void *) lj, sizeof(duk_ljstate));\n\tsnapshot->creating_error = heap->creating_error;\n\tsnapshot->curr_thread = heap->curr_thread;\n\tsnapshot->call_recursion_depth = heap->call_recursion_depth;\n\n\tlj->jmpbuf_ptr = NULL;\n\tlj->type = DUK_LJ_TYPE_UNKNOWN;\n\tDUK_TVAL_SET_UNDEFINED(&lj->value1);\n\tDUK_TVAL_SET_UNDEFINED(&lj->value2);\n\theap->creating_error = 0;\n\theap->curr_thread = NULL;\n\theap->call_recursion_depth = 0;\n}\n\nDUK_EXTERNAL void duk_resume(duk_hthread *thr, const duk_thread_state *state) {\n\tconst duk_internal_thread_state *snapshot = (const duk_internal_thread_state *) (const void *) state;\n\tduk_heap *heap;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(state != NULL);  /* unvalidated */\n\n\t/* Shouldn't be necessary if duk_suspend() is called before\n\t * duk_resume(), but assert in case API sequence is incorrect.\n\t */\n\tDUK_ASSERT(thr->heap->pf_prevent_count == 0);\n\tDUK_ASSERT(thr->heap->creating_error == 0);\n\n\theap = thr->heap;\n\n\tduk_memcpy((void *) &heap->lj, (const void *) &snapshot->lj, sizeof(duk_ljstate));\n\theap->creating_error = snapshot->creating_error;\n\theap->curr_thread = snapshot->curr_thread;\n\theap->call_recursion_depth = snapshot->call_recursion_depth;\n\n\tduk_pop_2(thr);\n}\n\n/* XXX: better place for this */\nDUK_EXTERNAL void duk_set_global_object(duk_hthread *thr) {\n\tduk_hobject *h_glob;\n\tduk_hobject *h_prev_glob;\n\tduk_hobjenv *h_env;\n\tduk_hobject *h_prev_env;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_D(DUK_DPRINT(\"replace global object with: %!T\", duk_get_tval(thr, -1)));\n\n\th_glob = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(h_glob != NULL);\n\n\t/*\n\t *  Replace global object.\n\t */\n\n\th_prev_glob = thr->builtins[DUK_BIDX_GLOBAL];\n\tDUK_UNREF(h_prev_glob);\n\tthr->builtins[DUK_BIDX_GLOBAL] = h_glob;\n\tDUK_HOBJECT_INCREF(thr, h_glob);\n\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, h_prev_glob);  /* side effects, in theory (referenced by global env) */\n\n\t/*\n\t *  Replace lexical environment for global scope\n\t *\n\t *  Create a new object environment for the global lexical scope.\n\t *  We can't just reset the _Target property of the current one,\n\t *  because the lexical scope is shared by other threads with the\n\t *  same (initial) built-ins.\n\t */\n\n\th_env = duk_hobjenv_alloc(thr,\n\t                          DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                          DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\tDUK_ASSERT(h_env != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_env) == NULL);\n\n\tDUK_ASSERT(h_env->target == NULL);\n\tDUK_ASSERT(h_glob != NULL);\n\th_env->target = h_glob;\n\tDUK_HOBJECT_INCREF(thr, h_glob);\n\tDUK_ASSERT(h_env->has_this == 0);\n\n\t/* [ ... new_glob ] */\n\n\th_prev_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\tthr->builtins[DUK_BIDX_GLOBAL_ENV] = (duk_hobject *) h_env;\n\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) h_env);\n\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, h_prev_env);  /* side effects */\n\tDUK_UNREF(h_env);  /* without refcounts */\n\tDUK_UNREF(h_prev_env);\n\n\t/* [ ... new_glob ] */\n\n\tduk_pop(thr);\n\n\t/* [ ... ] */\n}\n/*\n *  Inspection\n */\n\n/* #include duk_internal.h -> already included */\n\n/* For footprint efficient multiple value setting: arrays are much better than\n * varargs, format string with parsing is often better than string pointer arrays.\n */\nDUK_LOCAL void duk__inspect_multiple_uint(duk_hthread *thr, const char *fmt, duk_int_t *vals) {\n\tduk_int_t val;\n\tconst char *p;\n\tconst char *p_curr;\n\tduk_size_t len;\n\n\tfor (p = fmt;;) {\n\t\tlen = DUK_STRLEN(p);\n\t\tp_curr = p;\n\t\tp += len + 1;\n\t\tif (len == 0) {\n\t\t\t/* Double NUL (= empty key) terminates. */\n\t\t\tbreak;\n\t\t}\n\t\tval = *vals++;\n\t\tif (val >= 0) {\n\t\t\t/* Negative values are markers to skip key. */\n\t\t\tduk_push_string(thr, p_curr);\n\t\t\tduk_push_int(thr, val);\n\t\t\tduk_put_prop(thr, -3);\n\t\t}\n\t}\n}\n\n/* Raw helper to extract internal information / statistics about a value.\n * The return value is an object with properties that are version specific.\n * The properties must not expose anything that would lead to security\n * issues (e.g. exposing compiled function 'data' buffer might be an issue).\n * Currently only counts and sizes and such are given so there shouldn't\n * be security implications.\n */\n\n#define DUK__IDX_TYPE     0\n#define DUK__IDX_ITAG     1\n#define DUK__IDX_REFC     2\n#define DUK__IDX_HBYTES   3\n#define DUK__IDX_CLASS    4\n#define DUK__IDX_PBYTES   5\n#define DUK__IDX_ESIZE    6\n#define DUK__IDX_ENEXT    7\n#define DUK__IDX_ASIZE    8\n#define DUK__IDX_HSIZE    9\n#define DUK__IDX_BCBYTES  10\n#define DUK__IDX_DBYTES   11\n#define DUK__IDX_TSTATE   12\n#define DUK__IDX_VARIANT  13\n\nDUK_EXTERNAL void duk_inspect_value(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_heaphdr *h;\n\t/* The temporary values should be in an array rather than individual\n\t * variables which (in practice) ensures that the compiler won't map\n\t * them to registers and emit a lot of unnecessary shuffling code.\n\t */\n\tduk_int_t vals[14];\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Assume two's complement and set everything to -1. */\n\tduk_memset((void *) &vals, (int) 0xff, sizeof(vals));\n\tDUK_ASSERT(vals[DUK__IDX_TYPE] == -1);  /* spot check one */\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\th = (DUK_TVAL_IS_HEAP_ALLOCATED(tv) ? DUK_TVAL_GET_HEAPHDR(tv) : NULL);\n\n\tvals[DUK__IDX_TYPE] = duk_get_type_tval(tv);\n\tvals[DUK__IDX_ITAG] = (duk_int_t) DUK_TVAL_GET_TAG(tv);\n\n\tduk_push_bare_object(thr);  /* Invalidates 'tv'. */\n\ttv = NULL;\n\n\tif (h == NULL) {\n\t\tgoto finish;\n\t}\n\tduk_push_pointer(thr, (void *) h);\n\tduk_put_prop_literal(thr, -2, \"hptr\");\n\n#if 0\n\t/* Covers a lot of information, e.g. buffer and string variants. */\n\tduk_push_uint(thr, (duk_uint_t) DUK_HEAPHDR_GET_FLAGS(h));\n\tduk_put_prop_literal(thr, -2, \"hflags\");\n#endif\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tvals[DUK__IDX_REFC] = (duk_int_t) DUK_HEAPHDR_GET_REFCOUNT(h);\n#endif\n\tvals[DUK__IDX_VARIANT] = 0;\n\n\t/* Heaphdr size and additional allocation size, followed by\n\t * type specific stuff (with varying value count).\n\t */\n\tswitch ((duk_small_int_t) DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h_str = (duk_hstring *) h;\n\t\tvals[DUK__IDX_HBYTES] = (duk_int_t) (sizeof(duk_hstring) + DUK_HSTRING_GET_BYTELEN(h_str) + 1);\n#if defined(DUK_USE_HSTRING_EXTDATA)\n\t\tif (DUK_HSTRING_HAS_EXTDATA(h_str)) {\n\t\t\tvals[DUK__IDX_VARIANT] = 1;\n\t\t}\n#endif\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h_obj = (duk_hobject *) h;\n\n\t\t/* XXX: variants here are maybe pointless; class is enough? */\n\t\tif (DUK_HOBJECT_IS_ARRAY(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_harray);\n\t\t} else if (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hcompfunc);\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hnatfunc);\n\t\t} else if (DUK_HOBJECT_IS_THREAD(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hthread);\n\t\t\tvals[DUK__IDX_TSTATE] = ((duk_hthread *) h_obj)->state;\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hbufobj);\n\t\t\t/* XXX: some size information */\n#endif\n\t\t} else {\n\t\t\tvals[DUK__IDX_HBYTES] = (duk_small_uint_t) sizeof(duk_hobject);\n\t\t}\n\n\t\tvals[DUK__IDX_CLASS] = (duk_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h_obj);\n\t\tvals[DUK__IDX_PBYTES] = (duk_int_t) DUK_HOBJECT_P_ALLOC_SIZE(h_obj);\n\t\tvals[DUK__IDX_ESIZE] = (duk_int_t) DUK_HOBJECT_GET_ESIZE(h_obj);\n\t\tvals[DUK__IDX_ENEXT] = (duk_int_t) DUK_HOBJECT_GET_ENEXT(h_obj);\n\t\tvals[DUK__IDX_ASIZE] = (duk_int_t) DUK_HOBJECT_GET_ASIZE(h_obj);\n\t\tvals[DUK__IDX_HSIZE] = (duk_int_t) DUK_HOBJECT_GET_HSIZE(h_obj);\n\n\t\t/* Note: e_next indicates the number of gc-reachable entries\n\t\t * in the entry part, and also indicates the index where the\n\t\t * next new property would be inserted.  It does *not* indicate\n\t\t * the number of non-NULL keys present in the object.  That\n\t\t * value could be counted separately but requires a pass through\n\t\t * the key list.\n\t\t */\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tduk_hbuffer *h_data = (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(thr->heap, (duk_hcompfunc *) h_obj);\n\t\t\tvals[DUK__IDX_BCBYTES] = (duk_int_t) (h_data ? DUK_HBUFFER_GET_SIZE(h_data) : 0);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h_buf = (duk_hbuffer *) h;\n\n\t\tif (DUK_HBUFFER_HAS_DYNAMIC(h_buf)) {\n\t\t\tif (DUK_HBUFFER_HAS_EXTERNAL(h_buf)) {\n\t\t\t\tvals[DUK__IDX_VARIANT] = 2;  /* buffer variant 2: external */\n\t\t\t\tvals[DUK__IDX_HBYTES] = (duk_uint_t) (sizeof(duk_hbuffer_external));\n\t\t\t} else {\n\t\t\t\t/* When alloc_size == 0 the second allocation may not\n\t\t\t\t * actually exist.\n\t\t\t\t */\n\t\t\t\tvals[DUK__IDX_VARIANT] = 1;  /* buffer variant 1: dynamic */\n\t\t\t\tvals[DUK__IDX_HBYTES] = (duk_uint_t) (sizeof(duk_hbuffer_dynamic));\n\t\t\t}\n\t\t\tvals[DUK__IDX_DBYTES] = (duk_int_t) (DUK_HBUFFER_GET_SIZE(h_buf));\n\t\t} else {\n\t\t\tDUK_ASSERT(vals[DUK__IDX_VARIANT] == 0);  /* buffer variant 0: fixed */\n\t\t\tvals[DUK__IDX_HBYTES] = (duk_int_t) (sizeof(duk_hbuffer_fixed) + DUK_HBUFFER_GET_SIZE(h_buf));\n\t\t}\n\t\tbreak;\n\t}\n\t}\n\n finish:\n\tduk__inspect_multiple_uint(thr,\n\t    \"type\" \"\\x00\" \"itag\" \"\\x00\" \"refc\" \"\\x00\" \"hbytes\" \"\\x00\" \"class\" \"\\x00\"\n\t    \"pbytes\" \"\\x00\" \"esize\" \"\\x00\" \"enext\" \"\\x00\" \"asize\" \"\\x00\" \"hsize\" \"\\x00\"\n\t    \"bcbytes\" \"\\x00\" \"dbytes\" \"\\x00\" \"tstate\" \"\\x00\" \"variant\" \"\\x00\" \"\\x00\",\n\t    (duk_int_t *) &vals);\n}\n\nDUK_EXTERNAL void duk_inspect_callstack_entry(duk_hthread *thr, duk_int_t level) {\n\tduk_activation *act;\n\tduk_uint_fast32_t pc;\n\tduk_uint_fast32_t line;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* -1   = top callstack entry\n\t * -2   = caller of level -1\n\t * etc\n\t */\n\tact = duk_hthread_get_activation_for_level(thr, level);\n\tif (act == NULL) {\n\t\tduk_push_undefined(thr);\n\t\treturn;\n\t}\n\tduk_push_bare_object(thr);\n\n\t/* Relevant PC is just before current one because PC is\n\t * post-incremented.  This should match what error augment\n\t * code does.\n\t */\n\tpc = duk_hthread_get_act_prev_pc(thr, act);\n\n\tduk_push_tval(thr, &act->tv_func);\n\n\tduk_push_uint(thr, (duk_uint_t) pc);\n\tduk_put_prop_stridx_short(thr, -3, DUK_STRIDX_PC);\n\n#if defined(DUK_USE_PC2LINE)\n\tline = duk_hobject_pc2line_query(thr, -1, pc);\n#else\n\tline = 0;\n#endif\n\tduk_push_uint(thr, (duk_uint_t) line);\n\tduk_put_prop_stridx_short(thr, -3, DUK_STRIDX_LINE_NUMBER);\n\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_LC_FUNCTION);\n\t/* Providing access to e.g. act->lex_env would be dangerous: these\n\t * internal structures must never be accessible to the application.\n\t * Duktape relies on them having consistent data, and this consistency\n\t * is only asserted for, not checked for.\n\t */\n}\n\n/* automatic undefs */\n#undef DUK__IDX_ASIZE\n#undef DUK__IDX_BCBYTES\n#undef DUK__IDX_CLASS\n#undef DUK__IDX_DBYTES\n#undef DUK__IDX_ENEXT\n#undef DUK__IDX_ESIZE\n#undef DUK__IDX_HBYTES\n#undef DUK__IDX_HSIZE\n#undef DUK__IDX_ITAG\n#undef DUK__IDX_PBYTES\n#undef DUK__IDX_REFC\n#undef DUK__IDX_TSTATE\n#undef DUK__IDX_TYPE\n#undef DUK__IDX_VARIANT\n/*\n *  Memory calls.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_EXTERNAL void *duk_alloc_raw(duk_hthread *thr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn DUK_ALLOC_RAW(thr->heap, size);\n}\n\nDUK_EXTERNAL void duk_free_raw(duk_hthread *thr, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_FREE_RAW(thr->heap, ptr);\n}\n\nDUK_EXTERNAL void *duk_realloc_raw(duk_hthread *thr, void *ptr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn DUK_REALLOC_RAW(thr->heap, ptr, size);\n}\n\nDUK_EXTERNAL void *duk_alloc(duk_hthread *thr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn DUK_ALLOC(thr->heap, size);\n}\n\nDUK_EXTERNAL void duk_free(duk_hthread *thr, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_FREE_CHECKED(thr, ptr);\n}\n\nDUK_EXTERNAL void *duk_realloc(duk_hthread *thr, void *ptr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/*\n\t *  Note: since this is an exposed API call, there should be\n\t *  no way a mark-and-sweep could have a side effect on the\n\t *  memory allocation behind 'ptr'; the pointer should never\n\t *  be something that Duktape wants to change.\n\t *\n\t *  Thus, no need to use DUK_REALLOC_INDIRECT (and we don't\n\t *  have the storage location here anyway).\n\t */\n\n\treturn DUK_REALLOC(thr->heap, ptr, size);\n}\n\nDUK_EXTERNAL void duk_get_memory_functions(duk_hthread *thr, duk_memory_functions *out_funcs) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(out_funcs != NULL);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\theap = thr->heap;\n\tout_funcs->alloc_func = heap->alloc_func;\n\tout_funcs->realloc_func = heap->realloc_func;\n\tout_funcs->free_func = heap->free_func;\n\tout_funcs->udata = heap->heap_udata;\n}\n\nDUK_EXTERNAL void duk_gc(duk_hthread *thr, duk_uint_t flags) {\n\tduk_heap *heap;\n\tduk_small_uint_t ms_flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep requested by application\"));\n\tDUK_ASSERT(DUK_GC_COMPACT == DUK_MS_FLAG_EMERGENCY);  /* Compact flag is 1:1 with emergency flag which forces compaction. */\n\tms_flags = (duk_small_uint_t) flags;\n\tduk_heap_mark_and_sweep(heap, ms_flags);\n}\n/*\n *  Object handling: property access and other support functions.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Property handling\n *\n *  The API exposes only the most common property handling functions.\n *  The caller can invoke ECMAScript built-ins for full control (e.g.\n *  defineProperty, getOwnPropertyDescriptor).\n */\n\nDUK_EXTERNAL duk_bool_t duk_get_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property get right now.\n\t */\n\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, -1);\n\n\trc = duk_hobject_getprop(thr, tv_obj, tv_key);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\t/* a value is left on stack regardless of rc */\n\n\tduk_remove_m2(thr);  /* remove key */\n\tDUK_ASSERT(duk_is_undefined(thr, -1) || rc == 1);\n\treturn rc;  /* 1 if property found, 0 otherwise */\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk_get_prop(thr, obj_idx);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_get_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk_get_prop(thr, obj_idx);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_get_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_get_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_get_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n\nDUK_INTERNAL duk_bool_t duk_get_prop_stridx_boolean(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop) {\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\trc = duk_get_prop_stridx(thr, obj_idx, stridx);\n\tif (out_has_prop) {\n\t\t*out_has_prop = rc;\n\t}\n\treturn duk_to_boolean_top_pop(thr);\n}\n\n/* This get variant is for internal use, it differs from standard\n * duk_get_prop() in that:\n *   - Object argument must be an object (primitive values not supported).\n *   - Key argument must be a string (no coercion).\n *   - Only own properties are checked (no inheritance).  Only \"entry part\"\n *     properties are checked (not array index properties).\n *   - Property must be a plain data property, not a getter.\n *   - Proxy traps are not triggered.\n */\nDUK_INTERNAL duk_bool_t duk_xget_owndataprop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_hobject *h_obj;\n\tduk_hstring *h_key;\n\tduk_tval *tv_val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property get right now.\n\t */\n\n\th_obj = duk_get_hobject(thr, obj_idx);\n\tif (h_obj == NULL) {\n\t\treturn 0;\n\t}\n\th_key = duk_require_hstring(thr, -1);\n\n\ttv_val = duk_hobject_find_entry_tval_ptr(thr->heap, h_obj, h_key);\n\tif (tv_val == NULL) {\n\t\treturn 0;\n\t}\n\n\tduk_push_tval(thr, tv_val);\n\tduk_remove_m2(thr);  /* remove key */\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_bool_t duk_xget_owndataprop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_xget_owndataprop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_xget_owndataprop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_xget_owndataprop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                   (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n\nDUK_LOCAL duk_bool_t duk__put_prop_shared(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t idx_key) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_tval *tv_val;\n\tduk_bool_t throw_flag;\n\tduk_bool_t rc;\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property put right now (putprop protects\n\t * against it internally).\n\t */\n\n\t/* Key and value indices are either (-2, -1) or (-1, -2).  Given idx_key,\n\t * idx_val is always (idx_key ^ 0x01).\n\t */\n\tDUK_ASSERT((idx_key == -2 && (idx_key ^ 1) == -1) ||\n\t           (idx_key == -1 && (idx_key ^ 1) == -2));\n\t/* XXX: Direct access; faster validation. */\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, idx_key);\n\ttv_val = duk_require_tval(thr, idx_key ^ 1);\n\tthrow_flag = duk_is_strict_call(thr);\n\n\trc = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, throw_flag);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\n\tduk_pop_2(thr);  /* remove key and value */\n\treturn rc;  /* 1 if property found, 0 otherwise */\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__put_prop_shared(thr, obj_idx, -2);\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\t/* Careful here and with other duk_put_prop_xxx() helpers: the\n\t * target object and the property value may be in the same value\n\t * stack slot (unusual, but still conceptually clear).\n\t */\n\tobj_idx = duk_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_put_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\n\nDUK_INTERNAL duk_bool_t duk_put_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\nDUK_INTERNAL duk_bool_t duk_put_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_put_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t throw_flag;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property delete right now.\n\t */\n\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, -1);\n\tthrow_flag = duk_is_strict_call(thr);\n\n\trc = duk_hobject_delprop(thr, tv_obj, tv_key, throw_flag);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\n\tduk_pop(thr);  /* remove key */\n\treturn rc;\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk_del_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk_del_prop(thr, obj_idx);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_del_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk_del_prop(thr, obj_idx);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk_del_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk_del_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_del_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_del_prop(thr, obj_idx);\n}\n\n#if 0\nDUK_INTERNAL duk_bool_t duk_del_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_del_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_has_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property existence check right now.\n\t */\n\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, -1);\n\n\trc = duk_hobject_hasprop(thr, tv_obj, tv_key);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\n\tduk_pop(thr);  /* remove key */\n\treturn rc;  /* 1 if property found, 0 otherwise */\n}\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk_has_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk_has_prop(thr, obj_idx);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_has_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk_has_prop(thr, obj_idx);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk_has_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk_has_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_has_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_has_prop(thr, obj_idx);\n}\n\n#if 0\nDUK_INTERNAL duk_bool_t duk_has_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_has_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n#endif\n\n/* Define own property without inheritance lookups and such.  This differs from\n * [[DefineOwnProperty]] because special behaviors (like Array 'length') are\n * not invoked by this method.  The caller must be careful to invoke any such\n * behaviors if necessary.\n */\nDUK_INTERNAL void duk_xdef_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\tkey = duk_to_property_key_hstring(thr, -2);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(duk_require_tval(thr, -1) != NULL);\n\n\tduk_hobject_define_property_internal(thr, obj, key, desc_flags);\n\n\tduk_pop(thr);  /* pop key */\n}\n\nDUK_INTERNAL void duk_xdef_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\n\tduk_hobject_define_property_internal_arridx(thr, obj, arr_idx, desc_flags);\n\t/* value popped by call */\n}\n\nDUK_INTERNAL void duk_xdef_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\tkey = DUK_HTHREAD_GET_STRING(thr, stridx);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(duk_require_tval(thr, -1) != NULL);\n\n\tduk_hobject_define_property_internal(thr, obj, key, desc_flags);\n\t/* value popped by call */\n}\n\nDUK_INTERNAL void duk_xdef_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\tduk_xdef_prop_stridx(thr, (duk_idx_t) (duk_int8_t) (packed_args >> 24),\n\t                          (duk_small_uint_t) (packed_args >> 8) & 0xffffUL,\n\t                          (duk_small_uint_t) (packed_args & 0xffL));\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL void duk_xdef_prop_stridx_builtin(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\tDUK_ASSERT_BIDX_VALID(builtin_idx);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\tkey = DUK_HTHREAD_GET_STRING(thr, stridx);\n\tDUK_ASSERT(key != NULL);\n\n\tduk_push_hobject(thr, thr->builtins[builtin_idx]);\n\tduk_hobject_define_property_internal(thr, obj, key, desc_flags);\n\t/* value popped by call */\n}\n#endif\n\n/* This is a rare property helper; it sets the global thrower (E5 Section 13.2.3)\n * setter/getter into an object property.  This is needed by the 'arguments'\n * object creation code, function instance creation code, and Function.prototype.bind().\n */\n\nDUK_INTERNAL void duk_xdef_prop_stridx_thrower(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring_stridx(thr, stridx);\n\tduk_push_hobject_bidx(thr, DUK_BIDX_TYPE_ERROR_THROWER);\n\tduk_dup_top(thr);\n\tduk_def_prop(thr, obj_idx, DUK_DEFPROP_HAVE_SETTER | DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_FORCE);  /* attributes always 0 */\n}\n\n/* Object.getOwnPropertyDescriptor() equivalent C binding. */\nDUK_EXTERNAL void duk_get_prop_desc(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(flags);  /* no flags defined yet */\n\n\tduk_hobject_object_get_own_property_descriptor(thr, obj_idx);  /* [ ... key ] -> [ ... desc ] */\n}\n\n/* Object.defineProperty() equivalent C binding. */\nDUK_EXTERNAL void duk_def_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t flags) {\n\tduk_idx_t idx_base;\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_idx_t idx_value;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\tduk_uint_t is_data_desc;\n\tduk_uint_t is_acc_desc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\n\tis_data_desc = flags & (DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE);\n\tis_acc_desc = flags & (DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER);\n\tif (is_data_desc && is_acc_desc) {\n\t\t/* \"Have\" flags must not be conflicting so that they would\n\t\t * apply to both a plain property and an accessor at the same\n\t\t * time.\n\t\t */\n\t\tgoto fail_invalid_desc;\n\t}\n\n\tidx_base = duk_get_top_index(thr);\n\tif (flags & DUK_DEFPROP_HAVE_SETTER) {\n\t\tduk_require_type_mask(thr, idx_base, DUK_TYPE_MASK_UNDEFINED |\n\t\t                                     DUK_TYPE_MASK_OBJECT |\n\t\t                                     DUK_TYPE_MASK_LIGHTFUNC);\n\t\tset = duk_get_hobject_promote_lfunc(thr, idx_base);\n\t\tif (set != NULL && !DUK_HOBJECT_IS_CALLABLE(set)) {\n\t\t\tgoto fail_not_callable;\n\t\t}\n\t\tidx_base--;\n\t} else {\n\t\tset = NULL;\n\t}\n\tif (flags & DUK_DEFPROP_HAVE_GETTER) {\n\t\tduk_require_type_mask(thr, idx_base, DUK_TYPE_MASK_UNDEFINED |\n\t\t                                     DUK_TYPE_MASK_OBJECT |\n\t\t                                     DUK_TYPE_MASK_LIGHTFUNC);\n\t\tget = duk_get_hobject_promote_lfunc(thr, idx_base);\n\t\tif (get != NULL && !DUK_HOBJECT_IS_CALLABLE(get)) {\n\t\t\tgoto fail_not_callable;\n\t\t}\n\t\tidx_base--;\n\t} else {\n\t\tget = NULL;\n\t}\n\tif (flags & DUK_DEFPROP_HAVE_VALUE) {\n\t\tidx_value = idx_base;\n\t\tidx_base--;\n\t} else {\n\t\tidx_value = (duk_idx_t) -1;\n\t}\n\tkey = duk_to_property_key_hstring(thr, idx_base);\n\tDUK_ASSERT(key != NULL);\n\n\tduk_require_valid_index(thr, idx_base);\n\n\tduk_hobject_define_property_helper(thr,\n\t                                   flags /*defprop_flags*/,\n\t                                   obj,\n\t                                   key,\n\t                                   idx_value,\n\t                                   get,\n\t                                   set,\n\t                                   1 /*throw_flag*/);\n\n\t/* Clean up stack */\n\n\tduk_set_top(thr, idx_base);\n\n\t/* [ ... obj ... ] */\n\n\treturn;\n\n fail_invalid_desc:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_DESCRIPTOR);\n\tDUK_WO_NORETURN(return;);\n\n fail_not_callable:\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Object related\n */\n\nDUK_EXTERNAL void duk_compact(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, obj_idx);\n\tif (obj) {\n\t\t/* Note: this may fail, caller should protect the call if necessary */\n\t\tduk_hobject_compact_props(thr, obj);\n\t}\n}\n\nDUK_INTERNAL void duk_compact_m1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_compact(thr, -1);\n}\n\n/* XXX: the duk_hobject_enum.c stack APIs should be reworked */\n\nDUK_EXTERNAL void duk_enum(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t enum_flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_dup(thr, obj_idx);\n\tduk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tduk_hobject_enumerator_create(thr, enum_flags);   /* [target] -> [enum] */\n}\n\nDUK_EXTERNAL duk_bool_t duk_next(duk_hthread *thr, duk_idx_t enum_index, duk_bool_t get_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_require_hobject(thr, enum_index);\n\tduk_dup(thr, enum_index);\n\treturn duk_hobject_enumerator_next(thr, get_value);\n}\n\nDUK_INTERNAL void duk_seal_freeze_raw(duk_hthread *thr, duk_idx_t obj_idx, duk_bool_t is_freeze) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, obj_idx);\n\tDUK_ASSERT(tv != NULL);\n\n\t/* Seal/freeze are quite rare in practice so it'd be nice to get the\n\t * correct behavior simply via automatic promotion (at the cost of some\n\t * memory churn).  However, the promoted objects don't behave the same,\n\t * e.g. promoted lightfuncs are extensible.\n\t */\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_BUFFER:\n\t\t/* Plain buffer: already sealed, but not frozen (and can't be frozen\n\t\t * because index properties can't be made non-writable.\n\t\t */\n\t\tif (is_freeze) {\n\t\t\tgoto fail_cannot_freeze;\n\t\t}\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\t/* Lightfunc: already sealed and frozen, success. */\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (is_freeze && DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\t/* Buffer objects cannot be frozen because there's no internal\n\t\t\t * support for making virtual array indices non-writable.\n\t\t\t */\n\t\t\tDUK_DD(DUK_DDPRINT(\"cannot freeze a buffer object\"));\n\t\t\tgoto fail_cannot_freeze;\n\t\t}\n\t\tduk_hobject_object_seal_freeze_helper(thr, h, is_freeze);\n\n\t\t/* Sealed and frozen objects cannot gain any more properties,\n\t\t * so this is a good time to compact them.\n\t\t */\n\t\tduk_hobject_compact_props(thr, h);\n\t\tbreak;\n\tdefault:\n\t\t/* ES2015 Sections 19.1.2.5, 19.1.2.17 */\n\t\tbreak;\n\t}\n\treturn;\n\n fail_cannot_freeze:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);  /* XXX: proper error message */\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_seal(duk_hthread *thr, duk_idx_t obj_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_seal_freeze_raw(thr, obj_idx, 0 /*is_freeze*/);\n}\n\nDUK_EXTERNAL void duk_freeze(duk_hthread *thr, duk_idx_t obj_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_seal_freeze_raw(thr, obj_idx, 1 /*is_freeze*/);\n}\n\n/*\n *  Helpers for writing multiple properties\n */\n\nDUK_EXTERNAL void duk_put_function_list(duk_hthread *thr, duk_idx_t obj_idx, const duk_function_list_entry *funcs) {\n\tconst duk_function_list_entry *ent = funcs;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tif (ent != NULL) {\n\t\twhile (ent->key != NULL) {\n\t\t\tduk_push_c_function(thr, ent->value, ent->nargs);\n\t\t\tduk_put_prop_string(thr, obj_idx, ent->key);\n\t\t\tent++;\n\t\t}\n\t}\n}\n\nDUK_EXTERNAL void duk_put_number_list(duk_hthread *thr, duk_idx_t obj_idx, const duk_number_list_entry *numbers) {\n\tconst duk_number_list_entry *ent = numbers;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tif (ent != NULL) {\n\t\twhile (ent->key != NULL) {\n\t\t\ttv = thr->valstack_top++;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));  /* value stack init policy */\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv, ent->value);  /* no need for decref/incref */\n\t\t\tduk_put_prop_string(thr, obj_idx, ent->key);\n\t\t\tent++;\n\t\t}\n\t}\n}\n\n/*\n *  Shortcut for accessing global object properties\n */\n\nDUK_EXTERNAL duk_bool_t duk_get_global_string(duk_hthread *thr, const char *key) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_string(thr, -1, key);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_global_lstring(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_lstring(thr, -1, key, key_len);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_get_global_literal_raw(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_literal_raw(thr, -1, key, key_len);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_get_global_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_heapptr(thr, -1, ptr);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n\n\nDUK_EXTERNAL duk_bool_t duk_put_global_string(duk_hthread *thr, const char *key) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_string(thr, -2, key);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_global_lstring(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_lstring(thr, -2, key, key_len);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_put_global_literal_raw(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_literal_raw(thr, -2, key, key_len);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_put_global_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_heapptr(thr, -2, ptr);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n\n/*\n *  ES2015 GetMethod()\n */\n\nDUK_INTERNAL duk_bool_t duk_get_method_stridx(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t stridx) {\n\t(void) duk_get_prop_stridx(thr, idx, stridx);\n\tif (duk_is_null_or_undefined(thr, -1)) {\n\t\tduk_pop_nodecref_unsafe(thr);\n\t\treturn 0;\n\t}\n\tif (!duk_is_callable(thr, -1)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 1;\n}\n\n/*\n *  Object prototype\n */\n\nDUK_EXTERNAL void duk_get_prototype(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\n\t/* XXX: shared helper for duk_push_hobject_or_undefined()? */\n\tproto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, obj);\n\tif (proto) {\n\t\tduk_push_hobject(thr, proto);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n}\n\nDUK_EXTERNAL void duk_set_prototype(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\tduk_require_type_mask(thr, -1, DUK_TYPE_MASK_UNDEFINED |\n\t                               DUK_TYPE_MASK_OBJECT);\n\tproto = duk_get_hobject(thr, -1);\n\t/* proto can also be NULL here (allowed explicitly) */\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);  /* XXX: \"read only object\"? */\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, obj, proto);\n\n\tduk_pop(thr);\n}\n\nDUK_INTERNAL void duk_clear_prototype(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);  /* XXX: \"read only object\"? */\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, obj, NULL);\n}\n\nDUK_INTERNAL duk_bool_t duk_is_bare_object(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\n\tproto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, obj);\n\treturn (proto == NULL);\n}\n\n/*\n *  Object finalizer\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n/* XXX: these could be implemented as macros calling an internal function\n * directly.\n * XXX: same issue as with Duktape.fin: there's no way to delete the property\n * now (just set it to undefined).\n */\nDUK_EXTERNAL void duk_get_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* This get intentionally walks the inheritance chain at present,\n\t * which matches how the effective finalizer property is also\n\t * looked up in GC.\n\t */\n\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_INT_FINALIZER);\n}\n\nDUK_EXTERNAL void duk_set_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\tduk_bool_t callable;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hobject(thr, idx);  /* Get before 'put' so that 'idx' is correct. */\n\tcallable = duk_is_callable(thr, -1);\n\n\t/* At present finalizer is stored as a hidden Symbol, with normal\n\t * inheritance and access control.  As a result, finalizer cannot\n\t * currently be set on a non-extensible (sealed or frozen) object.\n\t * It might be useful to allow it.\n\t */\n\tduk_put_prop_stridx(thr, idx, DUK_STRIDX_INT_FINALIZER);\n\n\t/* In addition to setting the finalizer property, keep a \"have\n\t * finalizer\" flag in duk_hobject in sync so that refzero can do\n\t * a very quick finalizer check by walking the prototype chain\n\t * and checking the flag alone.  (Note that this means that just\n\t * setting _Finalizer on an object won't affect finalizer checks.)\n\t *\n\t * NOTE: if the argument is a Proxy object, this flag will be set\n\t * on the Proxy, not the target.  As a result, the target won't get\n\t * a finalizer flag and the Proxy also won't be finalized as there's\n\t * an explicit Proxy check in finalization now.\n\t */\n\tif (callable) {\n\t\tDUK_HOBJECT_SET_HAVE_FINALIZER(h);\n\t} else {\n\t\tDUK_HOBJECT_CLEAR_HAVE_FINALIZER(h);\n\t}\n}\n#else  /* DUK_USE_FINALIZER_SUPPORT */\nDUK_EXTERNAL void duk_get_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_set_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n/*\n *  Random numbers\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_EXTERNAL duk_double_t duk_random(duk_hthread *thr) {\n\treturn (duk_double_t) DUK_UTIL_GET_RANDOM_DOUBLE(thr);\n}\n/*\n *  API calls related to general value stack manipulation: resizing the value\n *  stack, pushing and popping values, type checking and reading values,\n *  coercing values, etc.\n *\n *  Also contains internal functions (such as duk_get_tval()), defined\n *  in duk_api_internal.h, with semantics similar to the public API.\n */\n\n/* XXX: repetition of stack pre-checks -> helper or macro or inline */\n/* XXX: shared api error strings, and perhaps even throw code for rare cases? */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Forward declarations\n */\n\nDUK_LOCAL_DECL duk_idx_t duk__push_c_function_raw(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_uint_t flags, duk_small_uint_t proto_bidx);\n\n/*\n *  Global state for working around missing variadic macros\n */\n\n#if !defined(DUK_USE_VARIADIC_MACROS)\nDUK_EXTERNAL const char *duk_api_global_filename = NULL;\nDUK_EXTERNAL duk_int_t duk_api_global_line = 0;\n#endif\n\n/*\n *  Misc helpers\n */\n\nDUK_LOCAL const char * const duk__symbol_type_strings[4] = {\n\t\"hidden\", \"global\", \"local\", \"wellknown\"\n};\n\n#if !defined(DUK_USE_PACKED_TVAL)\nDUK_LOCAL const duk_uint_t duk__type_from_tag[] = {\n\tDUK_TYPE_NUMBER,\n\tDUK_TYPE_NUMBER,  /* fastint */\n\tDUK_TYPE_UNDEFINED,\n\tDUK_TYPE_NULL,\n\tDUK_TYPE_BOOLEAN,\n\tDUK_TYPE_POINTER,\n\tDUK_TYPE_LIGHTFUNC,\n\tDUK_TYPE_NONE,\n\tDUK_TYPE_STRING,\n\tDUK_TYPE_OBJECT,\n\tDUK_TYPE_BUFFER,\n};\nDUK_LOCAL const duk_uint_t duk__type_mask_from_tag[] = {\n\tDUK_TYPE_MASK_NUMBER,\n\tDUK_TYPE_MASK_NUMBER,  /* fastint */\n\tDUK_TYPE_MASK_UNDEFINED,\n\tDUK_TYPE_MASK_NULL,\n\tDUK_TYPE_MASK_BOOLEAN,\n\tDUK_TYPE_MASK_POINTER,\n\tDUK_TYPE_MASK_LIGHTFUNC,\n\tDUK_TYPE_MASK_NONE,\n\tDUK_TYPE_MASK_STRING,\n\tDUK_TYPE_MASK_OBJECT,\n\tDUK_TYPE_MASK_BUFFER,\n};\n#endif  /* !DUK_USE_PACKED_TVAL */\n\n/* Assert that there's room for one value. */\n#define DUK__ASSERT_SPACE() do { \\\n\t\tDUK_ASSERT(!(thr->valstack_top >= thr->valstack_end)); \\\n\t} while (0)\n\n/* Check that there's room to push one value. */\n#if defined(DUK_USE_VALSTACK_UNSAFE)\n/* Faster but value stack overruns are memory unsafe. */\n#define DUK__CHECK_SPACE() DUK__ASSERT_SPACE()\n#else\n#define DUK__CHECK_SPACE() do { \\\n\t\tif (DUK_UNLIKELY(thr->valstack_top >= thr->valstack_end)) { \\\n\t\t\tDUK_ERROR_RANGE_PUSH_BEYOND(thr); \\\n\t\t} \\\n\t} while (0)\n#endif\n\nDUK_LOCAL duk_small_uint_t duk__get_symbol_type(duk_hstring *h) {\n\tconst duk_uint8_t *data;\n\tduk_size_t len;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HSTRING_HAS_SYMBOL(h));\n\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(h) >= 1);  /* always true, symbol prefix */\n\n\tdata = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\tDUK_ASSERT(len >= 1);\n\n\t/* XXX: differentiate between 0x82 and 0xff (hidden vs. internal?)? */\n\n\tif (data[0] == 0xffU) {\n\t\treturn DUK_SYMBOL_TYPE_HIDDEN;\n\t} else if (data[0] == 0x82U) {\n\t\treturn DUK_SYMBOL_TYPE_HIDDEN;\n\t} else if (data[0] == 0x80U) {\n\t\treturn DUK_SYMBOL_TYPE_GLOBAL;\n\t} else if (data[len - 1] != 0xffU) {\n\t\treturn DUK_SYMBOL_TYPE_LOCAL;\n\t} else {\n\t\treturn DUK_SYMBOL_TYPE_WELLKNOWN;\n\t}\n}\n\nDUK_LOCAL const char *duk__get_symbol_type_string(duk_hstring *h) {\n\tduk_small_uint_t idx;\n\tidx = duk__get_symbol_type(h);\n\tDUK_ASSERT(idx < sizeof(duk__symbol_type_strings));\n\treturn duk__symbol_type_strings[idx];\n}\n\nDUK_LOCAL_DECL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t tag);\n\nDUK_LOCAL duk_int_t duk__api_coerce_d2i(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value, duk_bool_t require) {\n\tduk_tval *tv;\n\tduk_small_int_t c;\n\tduk_double_t d;\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\t/*\n\t *  Special cases like NaN and +/- Infinity are handled explicitly\n\t *  because a plain C coercion from double to int handles these cases\n\t *  in undesirable ways.  For instance, NaN may coerce to INT_MIN\n\t *  (not zero), and INT_MAX + 1 may coerce to INT_MIN (not INT_MAX).\n\t *\n\t *  This double-to-int coercion differs from ToInteger() because it\n\t *  has a finite range (ToInteger() allows e.g. +/- Infinity).  It\n\t *  also differs from ToInt32() because the INT_MIN/INT_MAX clamping\n\t *  depends on the size of the int type on the platform.  In particular,\n\t *  on platforms with a 64-bit int type, the full range is allowed.\n\t */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tduk_int64_t t = DUK_TVAL_GET_FASTINT(tv);\n#if (DUK_INT_MAX <= 0x7fffffffL)\n\t\t/* Clamping only necessary for 32-bit ints. */\n\t\tif (t < DUK_INT_MIN) {\n\t\t\tt = DUK_INT_MIN;\n\t\t} else if (t > DUK_INT_MAX) {\n\t\t\tt = DUK_INT_MAX;\n\t\t}\n#endif\n\t\treturn (duk_int_t) t;\n\t}\n#endif\n\n\tif (DUK_TVAL_IS_NUMBER(tv)) {\n\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\t\tif (c == DUK_FP_NAN) {\n\t\t\treturn 0;\n\t\t} else if (d < (duk_double_t) DUK_INT_MIN) {\n\t\t\t/* covers -Infinity */\n\t\t\treturn DUK_INT_MIN;\n\t\t} else if (d > (duk_double_t) DUK_INT_MAX) {\n\t\t\t/* covers +Infinity */\n\t\t\treturn DUK_INT_MAX;\n\t\t} else {\n\t\t\t/* coerce towards zero */\n\t\t\treturn (duk_int_t) d;\n\t\t}\n\t}\n\n\tif (require) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"number\", DUK_STR_NOT_NUMBER);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\treturn def_value;\n}\n\nDUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value, duk_bool_t require) {\n\tduk_tval *tv;\n\tduk_small_int_t c;\n\tduk_double_t d;\n\n\t/* Same as above but for unsigned int range. */\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tduk_int64_t t = DUK_TVAL_GET_FASTINT(tv);\n\t\tif (t < 0) {\n\t\t\tt = 0;\n\t\t}\n#if (DUK_UINT_MAX <= 0xffffffffUL)\n\t\t/* Clamping only necessary for 32-bit ints. */\n\t\telse if (t > DUK_UINT_MAX) {\n\t\t\tt = DUK_UINT_MAX;\n\t\t}\n#endif\n\t\treturn (duk_uint_t) t;\n\t}\n#endif\n\n\tif (DUK_TVAL_IS_NUMBER(tv)) {\n\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\t\tif (c == DUK_FP_NAN) {\n\t\t\treturn 0;\n\t\t} else if (d < 0.0) {\n\t\t\t/* covers -Infinity */\n\t\t\treturn (duk_uint_t) 0;\n\t\t} else if (d > (duk_double_t) DUK_UINT_MAX) {\n\t\t\t/* covers +Infinity */\n\t\t\treturn (duk_uint_t) DUK_UINT_MAX;\n\t\t} else {\n\t\t\t/* coerce towards zero */\n\t\t\treturn (duk_uint_t) d;\n\t\t}\n\t}\n\n\tif (require) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"number\", DUK_STR_NOT_NUMBER);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\treturn def_value;\n}\n\n/*\n *  Stack index validation/normalization and getting a stack duk_tval ptr.\n *\n *  These are called by many API entrypoints so the implementations must be\n *  fast and \"inlined\".\n *\n *  There's some repetition because of this; keep the functions in sync.\n */\n\nDUK_EXTERNAL duk_idx_t duk_normalize_index(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\t/* Care must be taken to avoid pointer wrapping in the index\n\t * validation.  For instance, on a 32-bit platform with 8-byte\n\t * duk_tval the index 0x20000000UL would wrap the memory space\n\t * once.\n\t */\n\n\t/* Assume value stack sizes (in elements) fits into duk_idx_t. */\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\t/* since index non-negative */\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn (duk_idx_t) uidx;\n\t}\n\treturn DUK_INVALID_INDEX;\n}\n\nDUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn (duk_idx_t) uidx;\n\t}\n\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_tval *duk_get_tval(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn thr->valstack_bottom + uidx;\n\t}\n\treturn NULL;\n}\n\n/* Variant of duk_get_tval() which is guaranteed to return a valid duk_tval\n * pointer.  When duk_get_tval() would return NULL, this variant returns a\n * pointer to a duk_tval with tag DUK_TAG_UNUSED.  This allows the call site\n * to avoid an unnecessary NULL check which sometimes leads to better code.\n * The return duk_tval is read only (at least for the UNUSED value).\n */\nDUK_LOCAL const duk_tval_unused duk__const_tval_unused = DUK_TVAL_UNUSED_INITIALIZER();\n\nDUK_INTERNAL duk_tval *duk_get_tval_or_unused(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval(thr, idx);\n\tif (tv != NULL) {\n\t\treturn tv;\n\t}\n\treturn (duk_tval *) DUK_LOSE_CONST(&duk__const_tval_unused);\n}\n\nDUK_INTERNAL duk_tval *duk_require_tval(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\t/* Use unsigned arithmetic to optimize comparison. */\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn thr->valstack_bottom + uidx;\n\t}\n\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/* Non-critical. */\nDUK_EXTERNAL duk_bool_t duk_is_valid_index(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\treturn (duk_normalize_index(thr, idx) >= 0);\n}\n\n/* Non-critical. */\nDUK_EXTERNAL void duk_require_valid_index(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tif (DUK_UNLIKELY(duk_normalize_index(thr, idx) < 0)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\n/*\n *  Value stack top handling\n */\n\nDUK_EXTERNAL duk_idx_t duk_get_top(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n}\n\n/* Internal helper to get current top but to require a minimum top value\n * (TypeError if not met).\n */\nDUK_INTERNAL duk_idx_t duk_get_top_require_min(duk_hthread *thr, duk_idx_t min_top) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tif (DUK_UNLIKELY(ret < min_top)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn ret;\n}\n\n/* Set stack top within currently allocated range, but don't reallocate.\n * This is performance critical especially for call handling, so whenever\n * changing, profile and look at generated code.\n */\nDUK_EXTERNAL void duk_set_top(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t vs_limit;\n\tduk_uidx_t uidx;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tvs_limit = (duk_uidx_t) (thr->valstack_end - thr->valstack_bottom);\n\n\tif (idx < 0) {\n\t\t/* Negative indices are always within allocated stack but\n\t\t * must not go below zero index.\n\t\t */\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\t/* Positive index can be higher than valstack top but must\n\t\t * not go above allocated stack (equality is OK).\n\t\t */\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_limit);\n\n#if defined(DUK_USE_VALSTACK_UNSAFE)\n\tDUK_ASSERT(uidx <= vs_limit);\n\tDUK_UNREF(vs_limit);\n#else\n\tif (DUK_UNLIKELY(uidx > vs_limit)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\tDUK_ASSERT(uidx <= vs_limit);\n\n\t/* Handle change in value stack top.  Respect value stack\n\t * initialization policy: 'undefined' above top.  Note that\n\t * DECREF may cause a side effect that reallocates valstack,\n\t * so must relookup after DECREF.\n\t */\n\n\tif (uidx >= vs_size) {\n\t\t/* Stack size increases or stays the same. */\n#if defined(DUK_USE_ASSERTIONS)\n\t\tduk_uidx_t count;\n\n\t\tcount = uidx - vs_size;\n\t\twhile (count != 0) {\n\t\t\tcount--;\n\t\t\ttv = thr->valstack_top + count;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\t}\n#endif\n\t\tthr->valstack_top = thr->valstack_bottom + uidx;\n\t} else {\n\t\t/* Stack size decreases. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\tDUK_ASSERT(count > 0);\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);  /* Because count > 0. */\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n\t\tDUK_REFZERO_CHECK_FAST(thr);\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\t}\n}\n\n/* Internal variant with a non-negative index and no runtime size checks. */\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_set_top(thr, idx);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t uidx;\n\tduk_uidx_t vs_size;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_bottom);\n\tDUK_ASSERT(idx >= 0);\n\tDUK_ASSERT(idx <= (duk_idx_t) (thr->valstack_end - thr->valstack_bottom));\n\n\t/* XXX: byte arithmetic */\n\tuidx = (duk_uidx_t) idx;\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\n\tif (uidx >= vs_size) {\n\t\t/* Stack size increases or stays the same. */\n#if defined(DUK_USE_ASSERTIONS)\n\t\tduk_uidx_t count;\n\n\t\tcount = uidx - vs_size;\n\t\twhile (count != 0) {\n\t\t\tcount--;\n\t\t\ttv = thr->valstack_top + count;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\t}\n#endif\n\t\tthr->valstack_top = thr->valstack_bottom + uidx;\n\t} else {\n\t\t/* Stack size decreases. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\tDUK_ASSERT(count > 0);\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);  /* Because count > 0. */\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n\t\tDUK_REFZERO_CHECK_FAST(thr);\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\t}\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/* Internal helper: set top to 'top', and set [idx_wipe_start,top[ to\n * 'undefined' (doing nothing if idx_wipe_start == top).  Indices are\n * positive and within value stack reserve.  This is used by call handling.\n */\nDUK_INTERNAL void duk_set_top_and_wipe(duk_hthread *thr, duk_idx_t top, duk_idx_t idx_wipe_start) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(top >= 0);\n\tDUK_ASSERT(idx_wipe_start >= 0);\n\tDUK_ASSERT(idx_wipe_start <= top);\n\tDUK_ASSERT(thr->valstack_bottom + top <= thr->valstack_end);\n\tDUK_ASSERT(thr->valstack_bottom + idx_wipe_start <= thr->valstack_end);\n\n\tduk_set_top_unsafe(thr, idx_wipe_start);\n\tduk_set_top_unsafe(thr, top);\n}\n\nDUK_EXTERNAL duk_idx_t duk_get_top_index(duk_hthread *thr) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;\n\tif (DUK_UNLIKELY(ret < 0)) {\n\t\t/* Return invalid index; if caller uses this without checking\n\t\t * in another API call, the index won't map to a valid stack\n\t\t * entry.\n\t\t */\n\t\treturn DUK_INVALID_INDEX;\n\t}\n\treturn ret;\n}\n\n/* Internal variant: call assumes there is at least one element on the value\n * stack frame; this is only asserted for.\n */\nDUK_INTERNAL duk_idx_t duk_get_top_index_unsafe(duk_hthread *thr) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_idx_t duk_require_top_index(duk_hthread *thr) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;\n\tif (DUK_UNLIKELY(ret < 0)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, -1);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn ret;\n}\n\n/*\n *  Value stack resizing.\n *\n *  This resizing happens above the current \"top\": the value stack can be\n *  grown or shrunk, but the \"top\" is not affected.  The value stack cannot\n *  be resized to a size below the current reserve.\n *\n *  The low level reallocation primitive must carefully recompute all value\n *  stack pointers, and must also work if ALL pointers are NULL.  The resize\n *  is quite tricky because the valstack realloc may cause a mark-and-sweep,\n *  which may run finalizers.  Running finalizers may resize the valstack\n *  recursively (the same value stack we're working on).  So, after realloc\n *  returns, we know that the valstack bottom, top, and reserve should still\n *  be the same (there should not be live values above the \"top\"), but its\n *  underlying size, alloc_end, and base pointer may have changed.\n *\n *  'new_size' is known to be <= DUK_USE_VALSTACK_LIMIT, which ensures that\n *  size_t and pointer arithmetic won't wrap in duk__resize_valstack().\n */\n\n/* Low level valstack resize primitive, used for both grow and shrink.  All\n * adjustments for slack etc have already been done.  Doesn't throw but does\n * have allocation side effects.\n */\nDUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__resize_valstack(duk_hthread *thr, duk_size_t new_size) {\n\tduk_tval *pre_valstack;\n\tduk_tval *pre_bottom;\n\tduk_tval *pre_top;\n\tduk_tval *pre_end;\n\tduk_tval *pre_alloc_end;\n\tduk_ptrdiff_t ptr_diff;\n\tduk_tval *new_valstack;\n\tduk_size_t new_alloc_size;\n\tduk_tval *tv_prev_alloc_end;\n\tduk_tval *p;\n\n\tDUK_HTHREAD_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack) <= new_size);  /* can't resize below 'top' */\n\tDUK_ASSERT(new_size <= DUK_USE_VALSTACK_LIMIT);  /* valstack limit caller has check, prevents wrapping */\n\tDUK_ASSERT(new_size <= DUK_SIZE_MAX / sizeof(duk_tval));  /* specific assert for wrapping */\n\n\t/* Pre-realloc pointer copies for asserts and debug logs. */\n\tpre_valstack = thr->valstack;\n\tpre_bottom = thr->valstack_bottom;\n\tpre_top = thr->valstack_top;\n\tpre_end = thr->valstack_end;\n\tpre_alloc_end = thr->valstack_alloc_end;\n\n\tDUK_UNREF(pre_valstack);\n\tDUK_UNREF(pre_bottom);\n\tDUK_UNREF(pre_top);\n\tDUK_UNREF(pre_end);\n\tDUK_UNREF(pre_alloc_end);\n\n\t/* If finalizer torture enabled, force base pointer change every time\n\t * when it would be allowed.\n\t */\n#if defined(DUK_USE_FINALIZER_TORTURE)\n\tif (thr->heap->pf_prevent_count == 0) {\n\t\tduk_hthread_valstack_torture_realloc(thr);\n\t}\n#endif\n\n\t/* Allocate a new valstack using DUK_REALLOC_DIRECT() to deal with\n\t * a side effect changing the base pointer.\n\t */\n\tnew_alloc_size = sizeof(duk_tval) * new_size;\n\tnew_valstack = (duk_tval *) DUK_REALLOC_INDIRECT(thr->heap, duk_hthread_get_valstack_ptr, (void *) thr, new_alloc_size);\n\tif (DUK_UNLIKELY(new_valstack == NULL)) {\n\t\t/* Because new_size != 0, if condition doesn't need to be\n\t\t * (new_valstack != NULL || new_size == 0).\n\t\t */\n\t\tDUK_ASSERT(new_size != 0);\n\t\tDUK_D(DUK_DPRINT(\"failed to resize valstack to %lu entries (%lu bytes)\",\n\t\t                 (unsigned long) new_size, (unsigned long) new_alloc_size));\n\t\treturn 0;\n\t}\n\n\t/* Debug log any changes in pointer(s) by side effects.  These don't\n\t * necessarily imply any incorrect behavior, but should be rare in\n\t * practice.\n\t */\n#if defined(DUK_USE_DEBUG)\n\tif (thr->valstack != pre_valstack) {\n\t\tDUK_D(DUK_DPRINT(\"valstack base pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_valstack, (void *) thr->valstack));\n\t}\n\tif (thr->valstack_bottom != pre_bottom) {\n\t\tDUK_D(DUK_DPRINT(\"valstack bottom pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_bottom, (void *) thr->valstack_bottom));\n\t}\n\tif (thr->valstack_top != pre_top) {\n\t\tDUK_D(DUK_DPRINT(\"valstack top pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_top, (void *) thr->valstack_top));\n\t}\n\tif (thr->valstack_end != pre_end) {\n\t\tDUK_D(DUK_DPRINT(\"valstack end pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_end, (void *) thr->valstack_end));\n\t}\n\tif (thr->valstack_alloc_end != pre_alloc_end) {\n\t\tDUK_D(DUK_DPRINT(\"valstack alloc_end pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_alloc_end, (void *) thr->valstack_alloc_end));\n\t}\n#endif\n\n\t/* Assertions: offsets for bottom, top, and end (reserve) must not\n\t * have changed even with side effects because they are always\n\t * restored in unwind.  For alloc_end there's no guarantee: it may\n\t * have grown or shrunk (but remain above 'end').\n\t */\n\tDUK_ASSERT(thr->valstack_bottom - thr->valstack == pre_bottom - pre_valstack);\n\tDUK_ASSERT(thr->valstack_top - thr->valstack == pre_top - pre_valstack);\n\tDUK_ASSERT(thr->valstack_end - thr->valstack == pre_end - pre_valstack);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\n\t/* Write new pointers.  Most pointers can be handled as a pointer\n\t * difference.\n\t */\n\tptr_diff = (duk_ptrdiff_t) ((duk_uint8_t *) new_valstack - (duk_uint8_t *) thr->valstack);\n\ttv_prev_alloc_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_alloc_end + ptr_diff);\n\tthr->valstack = new_valstack;\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + ptr_diff);\n\tthr->valstack_top = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_top + ptr_diff);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_end + ptr_diff);\n\tthr->valstack_alloc_end = (duk_tval *) (void *) ((duk_uint8_t *) new_valstack + new_alloc_size);\n\n\t/* Assertions: pointer sanity after pointer updates. */\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\n\tDUK_D(DUK_DPRINT(\"resized valstack %lu -> %lu elements (%lu -> %lu bytes): \"\n\t                 \"base=%p -> %p, bottom=%p -> %p (%ld), top=%p -> %p (%ld), \"\n\t                 \"end=%p -> %p (%ld), alloc_end=%p -> %p (%ld);\"\n\t                 \" tv_prev_alloc_end=%p (-> %ld inits; <0 means shrink)\",\n\t                 (unsigned long) (pre_alloc_end - pre_valstack),\n\t                 (unsigned long) new_size,\n\t                 (unsigned long) ((duk_uint8_t *) pre_alloc_end - (duk_uint8_t *) pre_valstack),\n\t                 (unsigned long) new_alloc_size,\n\t                 (void *) pre_valstack, (void *) thr->valstack,\n\t                 (void *) pre_bottom, (void *) thr->valstack_bottom, (long) (thr->valstack_bottom - thr->valstack),\n\t                 (void *) pre_top, (void *) thr->valstack_top, (long) (thr->valstack_top - thr->valstack),\n\t                 (void *) pre_end, (void *) thr->valstack_end, (long) (thr->valstack_end - thr->valstack),\n\t                 (void *) pre_alloc_end, (void *) thr->valstack_alloc_end, (long) (thr->valstack_alloc_end - thr->valstack),\n\t                 (void *) tv_prev_alloc_end, (long) (thr->valstack_alloc_end - tv_prev_alloc_end)));\n\n\t/* If allocation grew, init any new slots to 'undefined'. */\n\tp = tv_prev_alloc_end;\n\twhile (p < thr->valstack_alloc_end) {\n\t\t/* Never executed if new size is smaller. */\n\t\tDUK_TVAL_SET_UNDEFINED(p);\n\t\tp++;\n\t}\n\n\t/* Assert for value stack initialization policy. */\n#if defined(DUK_USE_ASSERTIONS)\n\tp = thr->valstack_top;\n\twhile (p < thr->valstack_alloc_end) {\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(p));\n\t\tp++;\n\t}\n#endif\n\n\treturn 1;\n}\n\nDUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__valstack_grow(duk_hthread *thr, duk_size_t min_bytes, duk_bool_t throw_on_error) {\n\tduk_size_t min_size;\n\tduk_size_t new_size;\n\n\tDUK_ASSERT(min_bytes / sizeof(duk_tval) * sizeof(duk_tval) == min_bytes);\n\tmin_size = min_bytes / sizeof(duk_tval);  /* from bytes to slots */\n\n#if defined(DUK_USE_VALSTACK_GROW_SHIFT)\n\t/* New size is minimum size plus a proportional slack, e.g. shift of\n\t * 2 means a 25% slack.\n\t */\n\tnew_size = min_size + (min_size >> DUK_USE_VALSTACK_GROW_SHIFT);\n#else\n\t/* New size is tight with no slack.  This is sometimes preferred in\n\t * low memory environments.\n\t */\n\tnew_size = min_size;\n#endif\n\n\tif (DUK_UNLIKELY(new_size > DUK_USE_VALSTACK_LIMIT || new_size < min_size /*wrap*/)) {\n\t\t/* Note: may be triggered even if minimal new_size would not reach the limit,\n\t\t * plan limit accordingly.\n\t\t */\n\t\tif (throw_on_error) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_VALSTACK_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\treturn 0;\n\t}\n\n\tif (duk__resize_valstack(thr, new_size) == 0) {\n\t\tif (throw_on_error) {\n\t\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\treturn 0;\n\t}\n\n\tthr->valstack_end = thr->valstack + min_size;\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\n\treturn 1;\n}\n\n/* Hot, inlined value stack grow check.  Because value stack almost never\n * grows, the actual resize call is in a NOINLINE helper.\n */\nDUK_INTERNAL DUK_INLINE void duk_valstack_grow_check_throw(duk_hthread *thr, duk_size_t min_bytes) {\n\tduk_tval *tv;\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + min_bytes);\n\tif (DUK_LIKELY(thr->valstack_end >= tv)) {\n\t\treturn;\n\t}\n\tif (DUK_LIKELY(thr->valstack_alloc_end >= tv)) {\n\t\t/* Values in [valstack_top,valstack_alloc_end[ are initialized\n\t\t * to 'undefined' so we can just move the end pointer.\n\t\t */\n\t\tthr->valstack_end = tv;\n\t\treturn;\n\t}\n\t(void) duk__valstack_grow(thr, min_bytes, 1 /*throw_on_error*/);\n}\n\n/* Hot, inlined value stack grow check which doesn't throw. */\nDUK_INTERNAL DUK_INLINE duk_bool_t duk_valstack_grow_check_nothrow(duk_hthread *thr, duk_size_t min_bytes) {\n\tduk_tval *tv;\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + min_bytes);\n\tif (DUK_LIKELY(thr->valstack_end >= tv)) {\n\t\treturn 1;\n\t}\n\tif (DUK_LIKELY(thr->valstack_alloc_end >= tv)) {\n\t\tthr->valstack_end = tv;\n\t\treturn 1;\n\t}\n\treturn duk__valstack_grow(thr, min_bytes, 0 /*throw_on_error*/);\n}\n\n/* Value stack shrink check, called from mark-and-sweep. */\nDUK_INTERNAL void duk_valstack_shrink_check_nothrow(duk_hthread *thr, duk_bool_t snug) {\n\tduk_size_t alloc_bytes;\n\tduk_size_t reserve_bytes;\n\tduk_size_t shrink_bytes;\n\n\talloc_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_alloc_end - (duk_uint8_t *) thr->valstack);\n\treserve_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tDUK_ASSERT(alloc_bytes >= reserve_bytes);\n\n\t/* We're free to shrink the value stack allocation down to\n\t * reserve_bytes but not more.  If 'snug' (emergency GC)\n\t * shrink whatever we can.  Otherwise only shrink if the new\n\t * size would be considerably smaller.\n\t */\n\n#if defined(DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT)\n\tif (snug) {\n\t\tshrink_bytes = reserve_bytes;\n\t} else {\n\t\tduk_size_t proportion, slack;\n\n\t\t/* Require that value stack shrinks by at least X% of its\n\t\t * current size.  For example, shift of 2 means at least\n\t\t * 25%.  The proportion is computed as bytes and may not\n\t\t * be a multiple of sizeof(duk_tval); that's OK here.\n\t\t */\n\t\tproportion = alloc_bytes >> DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT;\n\t\tif (alloc_bytes - reserve_bytes < proportion) {\n\t\t\t/* Too little would be freed, do nothing. */\n\t\t\treturn;\n\t\t}\n\n\t\t/* Keep a slack after shrinking.  The slack is again a\n\t\t * proportion of the current size (the proportion should\n\t\t * of course be smaller than the check proportion above).\n\t\t */\n#if defined(DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT)\n\t\tDUK_ASSERT(DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT > DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT);\n\t\tslack = alloc_bytes >> DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT;\n#else\n\t\tslack = 0;\n#endif\n\t\tshrink_bytes = reserve_bytes +\n\t\t               slack / sizeof(duk_tval) * sizeof(duk_tval);  /* multiple of duk_tval */\n\t}\n#else  /* DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT */\n\t/* Always snug, useful in some low memory environments. */\n\tDUK_UNREF(snug);\n\tshrink_bytes = reserve_bytes;\n#endif  /* DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT */\n\n\tDUK_D(DUK_DPRINT(\"valstack shrink check: alloc_bytes=%ld, reserve_bytes=%ld, shrink_bytes=%ld (unvalidated)\",\n\t                 (long) alloc_bytes, (long) reserve_bytes, (long) shrink_bytes));\n\tDUK_ASSERT(shrink_bytes >= reserve_bytes);\n\tif (shrink_bytes >= alloc_bytes) {\n\t\t/* Skip if shrink target is same as current one (or higher,\n\t\t * though that shouldn't happen in practice).\n\t\t */\n\t\treturn;\n\t}\n\tDUK_ASSERT(shrink_bytes / sizeof(duk_tval) * sizeof(duk_tval) == shrink_bytes);\n\n\tDUK_D(DUK_DPRINT(\"valstack shrink check: decided to shrink, snug: %ld\", (long) snug));\n\n\tduk__resize_valstack(thr, shrink_bytes / sizeof(duk_tval));\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_stack(duk_hthread *thr, duk_idx_t extra) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\n\tif (DUK_UNLIKELY(extra < 0 || extra > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (extra < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\textra = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\textra = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) extra + DUK_VALSTACK_INTERNAL_EXTRA);\n\treturn duk_valstack_grow_check_nothrow(thr, min_new_bytes);\n}\n\nDUK_EXTERNAL void duk_require_stack(duk_hthread *thr, duk_idx_t extra) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\n\tif (DUK_UNLIKELY(extra < 0 || extra > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (extra < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\textra = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\textra = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) extra + DUK_VALSTACK_INTERNAL_EXTRA);\n\tduk_valstack_grow_check_throw(thr, min_new_bytes);\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_stack_top(duk_hthread *thr, duk_idx_t top) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (DUK_UNLIKELY(top < 0 || top > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (top < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\ttop = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\ttop = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tDUK_ASSERT(top >= 0);\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) top + DUK_VALSTACK_INTERNAL_EXTRA);\n\treturn duk_valstack_grow_check_nothrow(thr, min_new_bytes);\n}\n\nDUK_EXTERNAL void duk_require_stack_top(duk_hthread *thr, duk_idx_t top) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (DUK_UNLIKELY(top < 0 || top > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (top < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\ttop = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\ttop = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tDUK_ASSERT(top >= 0);\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) top + DUK_VALSTACK_INTERNAL_EXTRA);\n\tduk_valstack_grow_check_throw(thr, min_new_bytes);\n}\n\n/*\n *  Basic stack manipulation: swap, dup, insert, replace, etc\n */\n\nDUK_EXTERNAL void duk_swap(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n\tduk_tval tv_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_require_tval(thr, idx1);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, idx2);\n\tDUK_ASSERT(tv2 != NULL);\n\n\t/* If tv1==tv2 this is a NOP, no check is needed */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv1);\n\tDUK_TVAL_SET_TVAL(tv1, tv2);\n\tDUK_TVAL_SET_TVAL(tv2, &tv_tmp);\n}\n\nDUK_EXTERNAL void duk_swap_top(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_swap(thr, idx, -1);\n}\n\nDUK_EXTERNAL void duk_dup(duk_hthread *thr, duk_idx_t from_idx) {\n\tduk_tval *tv_from;\n\tduk_tval *tv_to;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\n\ttv_from = duk_require_tval(thr, from_idx);\n\ttv_to = thr->valstack_top++;\n\tDUK_ASSERT(tv_from != NULL);\n\tDUK_ASSERT(tv_to != NULL);\n\tDUK_TVAL_SET_TVAL(tv_to, tv_from);\n\tDUK_TVAL_INCREF(thr, tv_to);  /* no side effects */\n}\n\nDUK_EXTERNAL void duk_dup_top(duk_hthread *thr) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_dup(thr, -1);\n#else\n\tduk_tval *tv_from;\n\tduk_tval *tv_to;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\n\tif (DUK_UNLIKELY(thr->valstack_top - thr->valstack_bottom <= 0)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, -1);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\ttv_from = thr->valstack_top - 1;\n\ttv_to = thr->valstack_top++;\n\tDUK_ASSERT(tv_from != NULL);\n\tDUK_ASSERT(tv_to != NULL);\n\tDUK_TVAL_SET_TVAL(tv_to, tv_from);\n\tDUK_TVAL_INCREF(thr, tv_to);  /* no side effects */\n#endif\n}\n\nDUK_INTERNAL void duk_dup_0(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, 0);\n}\nDUK_INTERNAL void duk_dup_1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, 1);\n}\nDUK_INTERNAL void duk_dup_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, 2);\n}\nDUK_INTERNAL void duk_dup_m2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, -2);\n}\nDUK_INTERNAL void duk_dup_m3(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, -3);\n}\nDUK_INTERNAL void duk_dup_m4(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, -4);\n}\n\nDUK_EXTERNAL void duk_insert(duk_hthread *thr, duk_idx_t to_idx) {\n\tduk_tval *p;\n\tduk_tval *q;\n\tduk_tval tv_tmp;\n\tduk_size_t nbytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tp = duk_require_tval(thr, to_idx);\n\tDUK_ASSERT(p != NULL);\n\tq = duk_require_tval(thr, -1);\n\tDUK_ASSERT(q != NULL);\n\n\tDUK_ASSERT(q >= p);\n\n\t/*              nbytes\n\t *           <--------->\n\t *    [ ... | p | x | x | q ]\n\t * => [ ... | q | p | x | x ]\n\t */\n\n\tnbytes = (duk_size_t) (((duk_uint8_t *) q) - ((duk_uint8_t *) p));  /* Note: 'q' is top-1 */\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk_insert: to_idx=%ld, p=%p, q=%p, nbytes=%lu\",\n\t                     (long) to_idx, (void *) p, (void *) q, (unsigned long) nbytes));\n\n\t/* No net refcount changes.  No need to special case nbytes == 0\n\t * (p == q).\n\t */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, q);\n\tduk_memmove((void *) (p + 1), (const void *) p, (size_t) nbytes);\n\tDUK_TVAL_SET_TVAL(p, &tv_tmp);\n}\n\nDUK_INTERNAL void duk_insert_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(idx >= 0);  /* Doesn't support negative indices. */\n\n\tduk_push_undefined(thr);\n\tduk_insert(thr, idx);\n}\n\nDUK_INTERNAL void duk_insert_undefined_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) {\n\tduk_tval *tv, *tv_end;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(idx >= 0);  /* Doesn't support negative indices or count. */\n\tDUK_ASSERT(count >= 0);\n\n\ttv = duk_reserve_gap(thr, idx, count);\n\ttv_end = tv + count;\n\twhile (tv != tv_end) {\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t\ttv++;\n\t}\n}\n\nDUK_EXTERNAL void duk_replace(duk_hthread *thr, duk_idx_t to_idx) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n\tduk_tval tv_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, to_idx);\n\tDUK_ASSERT(tv2 != NULL);\n\n\t/* For tv1 == tv2, both pointing to stack top, the end result\n\t * is same as duk_pop(thr).\n\t */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv2);\n\tDUK_TVAL_SET_TVAL(tv2, tv1);\n\tDUK_TVAL_SET_UNDEFINED(tv1);\n\tthr->valstack_top--;\n\tDUK_TVAL_DECREF(thr, &tv_tmp);  /* side effects */\n}\n\nDUK_EXTERNAL void duk_copy(duk_hthread *thr, duk_idx_t from_idx, duk_idx_t to_idx) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_require_tval(thr, from_idx);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, to_idx);\n\tDUK_ASSERT(tv2 != NULL);\n\n\t/* For tv1 == tv2, this is a no-op (no explicit check needed). */\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv2, tv1);  /* side effects */\n}\n\nDUK_EXTERNAL void duk_remove(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *p;\n\tduk_tval *q;\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_tval tv_tmp;\n#endif\n\tduk_size_t nbytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tp = duk_require_tval(thr, idx);\n\tDUK_ASSERT(p != NULL);\n\tq = duk_require_tval(thr, -1);\n\tDUK_ASSERT(q != NULL);\n\n\tDUK_ASSERT(q >= p);\n\n\t/*              nbytes            zero size case\n\t *           <--------->\n\t *    [ ... | p | x | x | q ]     [ ... | p==q ]\n\t * => [ ... | x | x | q ]         [ ... ]\n\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* use a temp: decref only when valstack reachable values are correct */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, p);\n#endif\n\n\tnbytes = (duk_size_t) (((duk_uint8_t *) q) - ((duk_uint8_t *) p));  /* Note: 'q' is top-1 */\n\tduk_memmove((void *) p, (const void *) (p + 1), (size_t) nbytes);\n\n\tDUK_TVAL_SET_UNDEFINED(q);\n\tthr->valstack_top--;\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_DECREF(thr, &tv_tmp);  /* side effects */\n#endif\n}\n\nDUK_INTERNAL void duk_remove_unsafe(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_remove(thr, idx);  /* XXX: no optimization for now */\n}\n\nDUK_INTERNAL void duk_remove_m2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_remove(thr, -2);\n}\n\nDUK_INTERNAL void duk_remove_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) {\n#if defined(DUK_USE_PREFER_SIZE)\n\t/* XXX: maybe too slow even when preferring size? */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT(idx >= 0);\n\n\twhile (count-- > 0) {\n\t\tduk_remove(thr, idx);\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_tval *tv_newtop;\n\tduk_tval *tv;\n\tduk_size_t bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT(idx >= 0);\n\n\ttv_dst = thr->valstack_bottom + idx;\n\tDUK_ASSERT(tv_dst <= thr->valstack_top);\n\ttv_src = tv_dst + count;\n\tDUK_ASSERT(tv_src <= thr->valstack_top);\n\tbytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) tv_src);\n\n\tfor (tv = tv_dst; tv < tv_src; tv++) {\n\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t}\n\n\tduk_memmove((void *) tv_dst, (const void *) tv_src, bytes);\n\n\ttv_newtop = thr->valstack_top - count;\n\tfor (tv = tv_newtop; tv < thr->valstack_top; tv++) {\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t}\n\tthr->valstack_top = tv_newtop;\n\n\t/* When not preferring size, only NORZ macros are used; caller\n\t * is expected to DUK_REFZERO_CHECK().\n\t */\n#endif  /* DUK_USE_PREFER_SIZE */\n}\n\nDUK_INTERNAL void duk_remove_n_unsafe(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_remove_n(thr, idx, count);  /* XXX: no optimization for now */\n}\n\n/*\n *  Stack slice primitives\n */\n\nDUK_EXTERNAL void duk_xcopymove_raw(duk_hthread *to_thr, duk_hthread *from_thr, duk_idx_t count, duk_bool_t is_copy) {\n\tvoid *src;\n\tduk_size_t nbytes;\n\tduk_tval *p;\n\tduk_tval *q;\n\n\t/* XXX: several pointer comparison issues here */\n\n\tDUK_ASSERT_API_ENTRY(to_thr);\n\tDUK_CTX_ASSERT_VALID(to_thr);\n\tDUK_CTX_ASSERT_VALID(from_thr);\n\tDUK_ASSERT(to_thr->heap == from_thr->heap);\n\n\tif (DUK_UNLIKELY(to_thr == from_thr)) {\n\t\tDUK_ERROR_TYPE(to_thr, DUK_STR_INVALID_CONTEXT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tif (DUK_UNLIKELY((duk_uidx_t) count > (duk_uidx_t) DUK_USE_VALSTACK_LIMIT)) {\n\t\t/* Maximum value check ensures 'nbytes' won't wrap below.\n\t\t * Also handles negative count.\n\t\t */\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(to_thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(count >= 0);\n\n\tnbytes = sizeof(duk_tval) * (duk_size_t) count;\n\tif (DUK_UNLIKELY(nbytes == 0)) {\n\t\treturn;\n\t}\n\tDUK_ASSERT(to_thr->valstack_top <= to_thr->valstack_end);\n\tif (DUK_UNLIKELY((duk_size_t) ((duk_uint8_t *) to_thr->valstack_end - (duk_uint8_t *) to_thr->valstack_top) < nbytes)) {\n\t\tDUK_ERROR_RANGE_PUSH_BEYOND(to_thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tsrc = (void *) ((duk_uint8_t *) from_thr->valstack_top - nbytes);\n\tif (DUK_UNLIKELY(src < (void *) from_thr->valstack_bottom)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(to_thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* Copy values (no overlap even if to_thr == from_thr; that's not\n\t * allowed now anyway).\n\t */\n\tDUK_ASSERT(nbytes > 0);\n\tduk_memcpy((void *) to_thr->valstack_top, (const void *) src, (size_t) nbytes);\n\n\tp = to_thr->valstack_top;\n\tto_thr->valstack_top = (duk_tval *) (void *) (((duk_uint8_t *) p) + nbytes);\n\n\tif (is_copy) {\n\t\t/* Incref copies, keep originals. */\n\t\tq = to_thr->valstack_top;\n\t\twhile (p < q) {\n\t\t\tDUK_TVAL_INCREF(to_thr, p);  /* no side effects */\n\t\t\tp++;\n\t\t}\n\t} else {\n\t\t/* No net refcount change. */\n\t\tp = from_thr->valstack_top;\n\t\tq = (duk_tval *) (void *) (((duk_uint8_t *) p) - nbytes);\n\t\tfrom_thr->valstack_top = q;\n\n\t\twhile (p > q) {\n\t\t\tp--;\n\t\t\tDUK_TVAL_SET_UNDEFINED(p);\n\t\t\t/* XXX: fast primitive to set a bunch of values to UNDEFINED */\n\t\t}\n\t}\n}\n\n/* Internal helper: reserve a gap of 'count' elements at 'idx_base' and return a\n * pointer to the gap.  Values in the gap are garbage and MUST be initialized by\n * the caller before any side effects may occur.  The caller must ensure there's\n * enough stack reserve for 'count' values.\n */\nDUK_INTERNAL duk_tval *duk_reserve_gap(duk_hthread *thr, duk_idx_t idx_base, duk_idx_t count) {\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_size_t gap_bytes;\n\tduk_size_t copy_bytes;\n\n\t/* Caller is responsible for ensuring there's enough preallocated\n\t * value stack.\n\t */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_end - thr->valstack_top) >= (duk_size_t) count);\n\n\ttv_src = thr->valstack_bottom + idx_base;\n\tgap_bytes = (duk_size_t) count * sizeof(duk_tval);\n\ttv_dst = (duk_tval *) (void *) ((duk_uint8_t *) tv_src + gap_bytes);\n\tcopy_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) tv_src);\n\tthr->valstack_top = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_top + gap_bytes);\n\tduk_memmove((void *) tv_dst, (const void *) tv_src, copy_bytes);\n\n\t/* Values in the gap are left as garbage: caller must fill them in\n\t * and INCREF them before any side effects.\n\t */\n\treturn tv_src;\n}\n\n/*\n *  Get/opt/require\n */\n\nDUK_EXTERNAL void duk_require_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_UNDEFINED(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"undefined\", DUK_STR_NOT_UNDEFINED);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_EXTERNAL void duk_require_null(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_NULL(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"null\", DUK_STR_NOT_NULL);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_bool_t duk__get_boolean_raw(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) {\n\tduk_bool_t ret;\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BOOLEAN(tv)) {\n\t\tret = DUK_TVAL_GET_BOOLEAN(tv);\n\t\tDUK_ASSERT(ret == 0 || ret == 1);\n\t} else {\n\t\tret = def_value;\n\t\t/* Not guaranteed to be 0 or 1. */\n\t}\n\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_boolean_raw(thr, idx, 0);  /* default: false */\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_boolean_default(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_boolean_raw(thr, idx, def_value);\n}\n\nDUK_EXTERNAL duk_bool_t duk_require_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_LIKELY(DUK_TVAL_IS_BOOLEAN(tv))) {\n\t\tret = DUK_TVAL_GET_BOOLEAN(tv);\n\t\tDUK_ASSERT(ret == 0 || ret == 1);\n\t\treturn ret;\n\t} else {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"boolean\", DUK_STR_NOT_BOOLEAN);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n}\n\nDUK_EXTERNAL duk_bool_t duk_opt_boolean(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_boolean(thr, idx);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_double_t duk__get_number_raw(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {\n\tduk_double_union ret;\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tret.d = (duk_double_t) DUK_TVAL_GET_FASTINT(tv);  /* XXX: cast trick */\n\t}\n\telse\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv)) {\n\t\t/* When using packed duk_tval, number must be in NaN-normalized form\n\t\t * for it to be a duk_tval, so no need to normalize.  NOP for unpacked\n\t\t * duk_tval.\n\t\t */\n\t\tret.d = DUK_TVAL_GET_DOUBLE(tv);\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&ret));\n\t} else {\n\t\tret.d = def_value;\n\t\t/* Default value (including NaN) may not be normalized. */\n\t}\n\n\treturn ret.d;\n}\n\nDUK_EXTERNAL duk_double_t duk_get_number(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_number_raw(thr, idx, DUK_DOUBLE_NAN);  /* default: NaN */\n}\n\nDUK_EXTERNAL duk_double_t duk_get_number_default(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_number_raw(thr, idx, def_value);\n}\n\nDUK_EXTERNAL duk_double_t duk_require_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_double_union ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_NUMBER(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"number\", DUK_STR_NOT_NUMBER);\n\t\tDUK_WO_NORETURN(return 0.0;);\n\t}\n\n\tret.d = DUK_TVAL_GET_NUMBER(tv);\n\n\t/* When using packed duk_tval, number must be in NaN-normalized form\n\t * for it to be a duk_tval, so no need to normalize.  NOP for unpacked\n\t * duk_tval.\n\t */\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&ret));\n\treturn ret.d;\n}\n\nDUK_EXTERNAL duk_double_t duk_opt_number(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\t/* User provided default is not NaN normalized. */\n\t\treturn def_value;\n\t}\n\treturn duk_require_number(thr, idx);\n}\n\nDUK_EXTERNAL duk_int_t duk_get_int(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_get_uint(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_get_int_default(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, def_value, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_get_uint_default(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, def_value, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_require_int(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 1 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_require_uint(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 1 /*require*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_opt_int(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_int(thr, idx);\n}\n\nDUK_EXTERNAL duk_uint_t duk_opt_uint(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_uint(thr, idx);\n}\n\nDUK_EXTERNAL const char *duk_get_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tduk_hstring *h;\n\tconst char *ret;\n\tduk_size_t len;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\t\tret = (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\tlen = 0;\n\t\tret = NULL;\n\t}\n\n\tif (out_len != NULL) {\n\t\t*out_len = len;\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL const char *duk_require_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\tif (out_len) {\n\t\t*out_len = DUK_HSTRING_GET_BYTELEN(h);\n\t}\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_INTERNAL const char *duk_require_lstring_notsymbol(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hstring_notsymbol(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\tif (out_len) {\n\t\t*out_len = DUK_HSTRING_GET_BYTELEN(h);\n\t}\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_EXTERNAL const char *duk_get_string(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\treturn NULL;\n\t}\n}\n\nDUK_EXTERNAL const char *duk_opt_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\tif (out_len != NULL) {\n\t\t\t*out_len = def_len;\n\t\t}\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_lstring(thr, idx, out_len);\n}\n\nDUK_EXTERNAL const char *duk_opt_string(duk_hthread *thr, duk_idx_t idx, const char *def_ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_string(thr, idx);\n}\n\nDUK_EXTERNAL const char *duk_get_lstring_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len) {\n\tduk_hstring *h;\n\tconst char *ret;\n\tduk_size_t len;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\t\tret = (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\tlen = def_len;\n\t\tret = def_ptr;\n\t}\n\n\tif (out_len != NULL) {\n\t\t*out_len = len;\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL const char *duk_get_string_default(duk_hthread *thr, duk_idx_t idx, const char *def_value) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\treturn def_value;\n\t}\n}\n\nDUK_INTERNAL const char *duk_get_string_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring_notsymbol(thr, idx);\n\tif (h) {\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\treturn NULL;\n\t}\n}\n\nDUK_EXTERNAL const char *duk_require_string(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_require_lstring(thr, idx, NULL);\n}\n\nDUK_INTERNAL const char *duk_require_string_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hstring_notsymbol(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_EXTERNAL void duk_require_object(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_OBJECT(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"object\", DUK_STR_NOT_OBJECT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_LOCAL void *duk__get_pointer_raw(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tduk_tval *tv;\n\tvoid *p;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (!DUK_TVAL_IS_POINTER(tv)) {\n\t\treturn def_value;\n\t}\n\n\tp = DUK_TVAL_GET_POINTER(tv);  /* may be NULL */\n\treturn p;\n}\n\nDUK_EXTERNAL void *duk_get_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_pointer_raw(thr, idx, NULL /*def_value*/);\n}\n\nDUK_EXTERNAL void *duk_opt_pointer(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_pointer(thr, idx);\n}\n\nDUK_EXTERNAL void *duk_get_pointer_default(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_pointer_raw(thr, idx, def_value);\n}\n\nDUK_EXTERNAL void *duk_require_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *p;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: here we must be wary of the fact that a pointer may be\n\t * valid and be a NULL.\n\t */\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_POINTER(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"pointer\", DUK_STR_NOT_POINTER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\tp = DUK_TVAL_GET_POINTER(tv);  /* may be NULL */\n\treturn p;\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL void *duk_get_voidptr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_heaphdr *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (!DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\treturn NULL;\n\t}\n\n\th = DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(h != NULL);\n\treturn (void *) h;\n}\n#endif\n\nDUK_LOCAL void *duk__get_buffer_helper(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size, duk_bool_t throw_flag) {\n\tduk_hbuffer *h;\n\tvoid *ret;\n\tduk_size_t len;\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tif (out_size != NULL) {\n\t\t*out_size = 0;\n\t}\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_LIKELY(DUK_TVAL_IS_BUFFER(tv))) {\n\t\th = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tlen = DUK_HBUFFER_GET_SIZE(h);\n\t\tret = DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);\n\t} else {\n\t\tif (throw_flag) {\n\t\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"buffer\", DUK_STR_NOT_BUFFER);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t\tlen = def_size;\n\t\tret = def_ptr;\n\t}\n\n\tif (out_size != NULL) {\n\t\t*out_size = len;\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL void *duk_get_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_buffer_helper(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/);\n}\n\nDUK_EXTERNAL void *duk_opt_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\tif (out_size != NULL) {\n\t\t\t*out_size = def_size;\n\t\t}\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_buffer(thr, idx, out_size);\n}\n\nDUK_EXTERNAL void *duk_get_buffer_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_buffer_helper(thr, idx, out_size, def_ptr, def_len, 0 /*throw_flag*/);\n}\n\nDUK_EXTERNAL void *duk_require_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_buffer_helper(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 1 /*throw_flag*/);\n}\n\n/* Get the active buffer data area for a plain buffer or a buffer object.\n * Return NULL if the the value is not a buffer.  Note that a buffer may\n * have a NULL data pointer when its size is zero, the optional 'out_isbuffer'\n * argument allows caller to detect this reliably.\n */\nDUK_INTERNAL void *duk_get_buffer_data_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size, duk_bool_t throw_flag, duk_bool_t *out_isbuffer) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (out_isbuffer != NULL) {\n\t\t*out_isbuffer = 0;\n\t}\n\tif (out_size != NULL) {\n\t\t*out_size = def_size;\n\t}\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (out_size != NULL) {\n\t\t\t*out_size = DUK_HBUFFER_GET_SIZE(h);\n\t\t}\n\t\tif (out_isbuffer != NULL) {\n\t\t\t*out_isbuffer = 1;\n\t\t}\n\t\treturn (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);  /* may be NULL (but only if size is 0) */\n\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\telse if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\t/* XXX: this is probably a useful shared helper: for a\n\t\t\t * duk_hbufobj, get a validated buffer pointer/length.\n\t\t\t */\n\t\t\tduk_hbufobj *h_bufobj = (duk_hbufobj *) h;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t\t\tif (h_bufobj->buf != NULL &&\n\t\t\t    DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {\n\t\t\t\tduk_uint8_t *p;\n\n\t\t\t\tp = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf);\n\t\t\t\tif (out_size != NULL) {\n\t\t\t\t\t*out_size = (duk_size_t) h_bufobj->length;\n\t\t\t\t}\n\t\t\t\tif (out_isbuffer != NULL) {\n\t\t\t\t\t*out_isbuffer = 1;\n\t\t\t\t}\n\t\t\t\treturn (void *) (p + h_bufobj->offset);\n\t\t\t}\n\t\t\t/* if slice not fully valid, treat as error */\n\t\t}\n\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\tif (throw_flag) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"buffer\", DUK_STR_NOT_BUFFER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn def_ptr;\n}\n\nDUK_EXTERNAL void *duk_get_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_buffer_data_raw(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, NULL);\n}\n\nDUK_EXTERNAL void *duk_get_buffer_data_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_buffer_data_raw(thr, idx, out_size, def_ptr, def_size, 0 /*throw_flag*/, NULL);\n}\n\nDUK_EXTERNAL void *duk_opt_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\tif (out_size != NULL) {\n\t\t\t*out_size = def_size;\n\t\t}\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_buffer_data(thr, idx, out_size);\n}\n\nDUK_EXTERNAL void *duk_require_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_buffer_data_raw(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 1 /*throw_flag*/, NULL);\n}\n\n/* Raw helper for getting a value from the stack, checking its tag.\n * The tag cannot be a number because numbers don't have an internal\n * tag in the packed representation.\n */\n\nDUK_LOCAL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t tag) {\n\tduk_tval *tv;\n\tduk_heaphdr *ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_GET_TAG(tv) != tag) {\n\t\treturn (duk_heaphdr *) NULL;\n\t}\n\n\tret = DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(ret != NULL);  /* tagged null pointers should never occur */\n\treturn ret;\n\n}\n\nDUK_INTERNAL duk_hstring *duk_get_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n}\n\nDUK_INTERNAL duk_hstring *duk_get_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n\tif (DUK_UNLIKELY(h && DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\treturn NULL;\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_require_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"string\", DUK_STR_NOT_STRING);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_require_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n\tif (DUK_UNLIKELY(h == NULL || DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"string\", DUK_STR_NOT_STRING);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_get_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n}\n\nDUK_INTERNAL duk_hobject *duk_require_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"object\", DUK_STR_NOT_OBJECT);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hbuffer *duk_get_hbuffer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn (duk_hbuffer *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_BUFFER);\n}\n\nDUK_INTERNAL duk_hbuffer *duk_require_hbuffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hbuffer *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_BUFFER);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"buffer\", DUK_STR_NOT_BUFFER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hthread *duk_get_hthread(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_THREAD(h))) {\n\t\th = NULL;\n\t}\n\treturn (duk_hthread *) h;\n}\n\nDUK_INTERNAL duk_hthread *duk_require_hthread(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_THREAD(h)))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"thread\", DUK_STR_NOT_THREAD);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn (duk_hthread *) h;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_get_hcompfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_COMPFUNC(h))) {\n\t\th = NULL;\n\t}\n\treturn (duk_hcompfunc *) h;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_require_hcompfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_COMPFUNC(h)))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"compiledfunction\", DUK_STR_NOT_COMPFUNC);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn (duk_hcompfunc *) h;\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_get_hnatfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_NATFUNC(h))) {\n\t\th = NULL;\n\t}\n\treturn (duk_hnatfunc *) h;\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_require_hnatfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_NATFUNC(h)))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"nativefunction\", DUK_STR_NOT_NATFUNC);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn (duk_hnatfunc *) h;\n}\n\nDUK_EXTERNAL duk_c_function duk_get_c_function(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\tduk_hnatfunc *f;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_OBJECT(tv))) {\n\t\treturn NULL;\n\t}\n\th = DUK_TVAL_GET_OBJECT(tv);\n\tDUK_ASSERT(h != NULL);\n\n\tif (DUK_UNLIKELY(!DUK_HOBJECT_IS_NATFUNC(h))) {\n\t\treturn NULL;\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_HAS_NATFUNC(h));\n\tf = (duk_hnatfunc *) h;\n\n\treturn f->func;\n}\n\nDUK_EXTERNAL duk_c_function duk_opt_c_function(duk_hthread *thr, duk_idx_t idx, duk_c_function def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_c_function(thr, idx);\n}\n\nDUK_EXTERNAL duk_c_function duk_get_c_function_default(duk_hthread *thr, duk_idx_t idx, duk_c_function def_value) {\n\tduk_c_function ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_c_function(thr, idx);\n\tif (ret != NULL) {\n\t\treturn ret;\n\t}\n\n\treturn def_value;\n}\n\nDUK_EXTERNAL duk_c_function duk_require_c_function(duk_hthread *thr, duk_idx_t idx) {\n\tduk_c_function ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_c_function(thr, idx);\n\tif (DUK_UNLIKELY(!ret)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"nativefunction\", DUK_STR_NOT_NATFUNC);\n\t\tDUK_WO_NORETURN(return ret;);\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_require_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tif (DUK_UNLIKELY(!duk_is_function(thr, idx))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"function\", DUK_STR_NOT_FUNCTION);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_EXTERNAL void duk_require_constructable(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hobject_accept_mask(thr, idx, DUK_TYPE_MASK_LIGHTFUNC);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_HAS_CONSTRUCTABLE(h))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"constructable\", DUK_STR_NOT_CONSTRUCTABLE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\t/* Lightfuncs (h == NULL) are constructable. */\n}\n\nDUK_EXTERNAL duk_hthread *duk_get_context(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_get_hthread(thr, idx);\n}\n\nDUK_EXTERNAL duk_hthread *duk_require_context(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_require_hthread(thr, idx);\n}\n\nDUK_EXTERNAL duk_hthread *duk_opt_context(duk_hthread *thr, duk_idx_t idx, duk_hthread *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_context(thr, idx);\n}\n\nDUK_EXTERNAL duk_hthread *duk_get_context_default(duk_hthread *thr, duk_idx_t idx, duk_hthread *def_value) {\n\tduk_hthread *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_context(thr, idx);\n\tif (ret != NULL) {\n\t\treturn ret;\n\t}\n\n\treturn def_value;\n}\n\nDUK_EXTERNAL void *duk_get_heapptr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_HEAP_ALLOCATED(tv))) {\n\t\treturn (void *) NULL;\n\t}\n\n\tret = (void *) DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(ret != NULL);\n\treturn ret;\n}\n\nDUK_EXTERNAL void *duk_opt_heapptr(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_heapptr(thr, idx);\n}\n\nDUK_EXTERNAL void *duk_get_heapptr_default(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tvoid *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_heapptr(thr, idx);\n\tif (ret != NULL) {\n\t\treturn ret;\n\t}\n\n\treturn def_value;\n}\n\nDUK_EXTERNAL void *duk_require_heapptr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_HEAP_ALLOCATED(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"heapobject\", DUK_STR_UNEXPECTED_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\tret = (void *) DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(ret != NULL);\n\treturn ret;\n}\n\n/* Internal helper for getting/requiring a duk_hobject with possible promotion. */\nDUK_LOCAL duk_hobject *duk__get_hobject_promote_mask_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tduk_uint_t val_mask;\n\tduk_hobject *res;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tres = duk_get_hobject(thr, idx);  /* common case, not promoted */\n\tif (DUK_LIKELY(res != NULL)) {\n\t\tDUK_ASSERT(res != NULL);\n\t\treturn res;\n\t}\n\n\tval_mask = duk_get_type_mask(thr, idx);\n\tif (val_mask & type_mask) {\n\t\tif (type_mask & DUK_TYPE_MASK_PROMOTE) {\n\t\t\tres = duk_to_hobject(thr, idx);\n\t\t\tDUK_ASSERT(res != NULL);\n\t\t\treturn res;\n\t\t} else {\n\t\t\treturn NULL;  /* accept without promoting */\n\t\t}\n\t}\n\n\tif (type_mask & DUK_TYPE_MASK_THROW) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"object\", DUK_STR_NOT_OBJECT);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn NULL;\n}\n\n/* Get a duk_hobject * at 'idx'; if the value is not an object but matches the\n * supplied 'type_mask', promote it to an object and return the duk_hobject *.\n * This is useful for call sites which want an object but also accept a plain\n * buffer and/or a lightfunc which gets automatically promoted to an object.\n * Return value is NULL if value is neither an object nor a plain type allowed\n * by the mask.\n */\nDUK_INTERNAL duk_hobject *duk_get_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_PROMOTE);\n}\n\n/* Like duk_get_hobject_promote_mask() but throw a TypeError instead of\n * returning a NULL.\n */\nDUK_INTERNAL duk_hobject *duk_require_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_THROW | DUK_TYPE_MASK_PROMOTE);\n}\n\n/* Require a duk_hobject * at 'idx'; if the value is not an object but matches the\n * supplied 'type_mask', return a NULL instead.  Otherwise throw a TypeError.\n */\nDUK_INTERNAL duk_hobject *duk_require_hobject_accept_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_THROW);\n}\n\nDUK_INTERNAL duk_hobject *duk_get_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_DISABLE(classnum >= 0);  /* unsigned */\n\tDUK_ASSERT(classnum <= DUK_HOBJECT_CLASS_MAX);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h) != classnum)) {\n\t\th = NULL;\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_require_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_DISABLE(classnum >= 0);  /* unsigned */\n\tDUK_ASSERT(classnum <= DUK_HOBJECT_CLASS_MAX);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h) == classnum))) {\n\t\tduk_hstring *h_class;\n\t\th_class = DUK_HTHREAD_GET_STRING(thr, DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum));\n\t\tDUK_UNREF(h_class);\n\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, (const char *) DUK_HSTRING_GET_DATA(h_class), DUK_STR_UNEXPECTED_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_EXTERNAL duk_size_t duk_get_length(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\tcase DUK_TAG_BOOLEAN:\n\tcase DUK_TAG_POINTER:\n\t\treturn 0;\n#if defined(DUK_USE_PREFER_SIZE)\n\t/* String and buffer have a virtual non-configurable .length property\n\t * which is within size_t range so it can be looked up without specific\n\t * type checks.  Lightfuncs inherit from %NativeFunctionPrototype%\n\t * which provides an inherited .length accessor; it could be overwritten\n\t * to produce unexpected types or values, but just number convert and\n\t * duk_size_t cast for now.\n\t */\n\tcase DUK_TAG_STRING:\n\tcase DUK_TAG_BUFFER:\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tduk_size_t ret;\n\t\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n\t\tret = (duk_size_t) duk_to_number_m1(thr);\n\t\tduk_pop_unsafe(thr);\n\t\treturn ret;\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn (duk_size_t) DUK_HSTRING_GET_CHARLEN(h);\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (duk_size_t) DUK_HBUFFER_GET_SIZE(h);\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* We could look up the length from the lightfunc duk_tval,\n\t\t * but since Duktape 2.2 lightfunc .length comes from\n\t\t * %NativeFunctionPrototype% which can be overridden, so\n\t\t * look up the property explicitly.\n\t\t */\n\t\tduk_size_t ret;\n\t\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n\t\tret = (duk_size_t) duk_to_number_m1(thr);\n\t\tduk_pop_unsafe(thr);\n\t\treturn ret;\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (duk_size_t) duk_hobject_get_length(thr, h);\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* number or 'unused' */\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv) || DUK_TVAL_IS_UNUSED(tv));\n\t\treturn 0;\n\t}\n\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  duk_known_xxx() helpers\n *\n *  Used internally when we're 100% sure that a certain index is valid and\n *  contains an object of a certain type.  For example, if we duk_push_object()\n *  we can then safely duk_known_hobject(thr, -1).  These helpers just assert\n *  for the index and type, and if the assumptions are not valid, memory unsafe\n *  behavior happens.\n */\n\nDUK_LOCAL duk_heaphdr *duk__known_heaphdr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_heaphdr *h;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tif (idx < 0) {\n\t\ttv = thr->valstack_top + idx;\n\t} else {\n\t\ttv = thr->valstack_bottom + idx;\n\t}\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\tDUK_ASSERT(tv < thr->valstack_top);\n\th = DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(h != NULL);\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_known_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hstring(thr, idx) != NULL);\n\treturn (duk_hstring *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hobject *duk_known_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hobject(thr, idx) != NULL);\n\treturn (duk_hobject *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hbuffer *duk_known_hbuffer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hbuffer(thr, idx) != NULL);\n\treturn (duk_hbuffer *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_known_hcompfunc(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hcompfunc(thr, idx) != NULL);\n\treturn (duk_hcompfunc *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_known_hnatfunc(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hnatfunc(thr, idx) != NULL);\n\treturn (duk_hnatfunc *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_EXTERNAL void duk_set_length(duk_hthread *thr, duk_idx_t idx, duk_size_t len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_normalize_index(thr, idx);\n\tduk_push_uint(thr, (duk_uint_t) len);\n\tduk_put_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n}\n\n/*\n *  Conversions and coercions\n *\n *  The conversion/coercions are in-place operations on the value stack.\n *  Some operations are implemented here directly, while others call a\n *  helper in duk_js_ops.c after validating arguments.\n */\n\n/* E5 Section 8.12.8 */\n\nDUK_LOCAL duk_bool_t duk__defaultvalue_coerce_attempt(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t func_stridx) {\n\tif (duk_get_prop_stridx(thr, idx, func_stridx)) {\n\t\t/* [ ... func ] */\n\t\tif (duk_is_callable(thr, -1)) {\n\t\t\tduk_dup(thr, idx);         /* -> [ ... func this ] */\n\t\t\tduk_call_method(thr, 0);     /* -> [ ... retval ] */\n\t\t\tif (duk_is_primitive(thr, -1)) {\n\t\t\t\tduk_replace(thr, idx);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\t/* [ ... retval ]; popped below */\n\t\t}\n\t}\n\tduk_pop_unsafe(thr);  /* [ ... func/retval ] -> [ ... ] */\n\treturn 0;\n}\n\nDUK_EXTERNAL void duk_to_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n}\n\nDUK_EXTERNAL void duk_to_null(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tDUK_TVAL_SET_NULL_UPDREF(thr, tv);  /* side effects */\n}\n\n/* E5 Section 9.1 */\nDUK_LOCAL const char * const duk__toprim_hint_strings[3] = {\n\t\"default\", \"string\", \"number\"\n};\nDUK_LOCAL void duk__to_primitive_helper(duk_hthread *thr, duk_idx_t idx, duk_int_t hint, duk_bool_t check_symbol) {\n\t/* Inline initializer for coercers[] is not allowed by old compilers like BCC. */\n\tduk_small_uint_t coercers[2];\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(hint == DUK_HINT_NONE || hint == DUK_HINT_NUMBER || hint == DUK_HINT_STRING);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\t/* If already primitive, return as is. */\n\tif (!duk_check_type_mask(thr, idx, DUK_TYPE_MASK_OBJECT |\n\t                                   DUK_TYPE_MASK_LIGHTFUNC |\n\t                                   DUK_TYPE_MASK_BUFFER)) {\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* duk_to_string() relies on this behavior */\n\t\treturn;\n\t}\n\n\t/* @@toPrimitive lookup.  Also do for plain buffers and lightfuncs\n\t * which mimic objects.\n\t */\n\tif (check_symbol && duk_get_method_stridx(thr, idx, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE)) {\n\t\tDUK_ASSERT(hint >= 0 && (duk_size_t) hint < sizeof(duk__toprim_hint_strings) / sizeof(const char *));\n\t\tduk_dup(thr, idx);\n\t\tduk_push_string(thr, duk__toprim_hint_strings[hint]);\n\t\tduk_call_method(thr, 1);  /* [ ... method value hint ] -> [ ... res] */\n\t\tif (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT |\n\t                                         DUK_TYPE_MASK_LIGHTFUNC |\n\t\t                                 DUK_TYPE_MASK_BUFFER)) {\n\t\t\tgoto fail;\n\t\t}\n\t\tduk_replace(thr, idx);\n\t\treturn;\n\t}\n\n\t/* Objects are coerced based on E5 specification.\n\t * Lightfuncs are coerced because they behave like\n\t * objects even if they're internally a primitive\n\t * type.  Same applies to plain buffers, which behave\n\t * like ArrayBuffer objects since Duktape 2.x.\n\t */\n\n\t/* Hint magic for Date is unnecessary in ES2015 because of\n\t * Date.prototype[@@toPrimitive].  However, it is needed if\n\t * symbol support is not enabled.\n\t */\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\tif (hint == DUK_HINT_NONE) {\n\t\thint = DUK_HINT_NUMBER;\n\t}\n#else  /* DUK_USE_SYMBOL_BUILTIN */\n\tif (hint == DUK_HINT_NONE) {\n\t\tduk_small_uint_t class_number;\n\n\t\tclass_number = duk_get_class_number(thr, idx);\n\t\tif (class_number == DUK_HOBJECT_CLASS_DATE) {\n\t\t\thint = DUK_HINT_STRING;\n\t\t} else {\n\t\t\thint = DUK_HINT_NUMBER;\n\t\t}\n\t}\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n\n\tcoercers[0] = DUK_STRIDX_VALUE_OF;\n\tcoercers[1] = DUK_STRIDX_TO_STRING;\n\tif (hint == DUK_HINT_STRING) {\n\t\tcoercers[0] = DUK_STRIDX_TO_STRING;\n\t\tcoercers[1] = DUK_STRIDX_VALUE_OF;\n\t}\n\n\tif (duk__defaultvalue_coerce_attempt(thr, idx, coercers[0])) {\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* duk_to_string() relies on this behavior */\n\t\treturn;\n\t}\n\n\tif (duk__defaultvalue_coerce_attempt(thr, idx, coercers[1])) {\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* duk_to_string() relies on this behavior */\n\t\treturn;\n\t}\n\n fail:\n\tDUK_ERROR_TYPE(thr, DUK_STR_TOPRIMITIVE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_to_primitive(duk_hthread *thr, duk_idx_t idx, duk_int_t hint) {\n\tduk__to_primitive_helper(thr, idx, hint, 1 /*check_symbol*/);\n}\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL void duk_to_primitive_ordinary(duk_hthread *thr, duk_idx_t idx, duk_int_t hint) {\n\tduk__to_primitive_helper(thr, idx, hint, 0 /*check_symbol*/);\n}\n#endif\n\n/* E5 Section 9.2 */\nDUK_EXTERNAL duk_bool_t duk_to_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_bool_t val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tval = duk_js_toboolean(tv);\n\tDUK_ASSERT(val == 0 || val == 1);\n\n\t/* Note: no need to re-lookup tv, conversion is side effect free. */\n\tDUK_ASSERT(tv != NULL);\n\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv, val);  /* side effects */\n\treturn val;\n}\n\nDUK_INTERNAL duk_bool_t duk_to_boolean_top_pop(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_bool_t val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tval = duk_js_toboolean(tv);\n\tDUK_ASSERT(val == 0 || val == 1);\n\n\tduk_pop_unsafe(thr);\n\treturn val;\n}\n\nDUK_EXTERNAL duk_double_t duk_to_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_double_t d;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: No need to normalize; the whole operation could be inlined here to\n\t * avoid 'tv' re-lookup.\n\t */\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\td = duk_js_tonumber(thr, tv);  /* XXX: fastint coercion? now result will always be a non-fastint */\n\n\t/* ToNumber() may have side effects so must relookup 'tv'. */\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d);  /* side effects */\n\treturn d;\n}\n\nDUK_INTERNAL duk_double_t duk_to_number_m1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_number(thr, -1);\n}\nDUK_INTERNAL duk_double_t duk_to_number_m2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_number(thr, -2);\n}\n\nDUK_INTERNAL duk_double_t duk_to_number_tval(duk_hthread *thr, duk_tval *tv) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_double_t res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_tval(thr, tv);\n\tres = duk_to_number_m1(thr);\n\tduk_pop_unsafe(thr);\n\treturn res;\n#else\n\tduk_double_t res;\n\tduk_tval *tv_dst;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ASSERT_SPACE();\n\n\ttv_dst = thr->valstack_top++;\n\tDUK_TVAL_SET_TVAL(tv_dst, tv);\n\tDUK_TVAL_INCREF(thr, tv_dst);  /* decref not necessary */\n\tres = duk_to_number_m1(thr);  /* invalidates tv_dst */\n\n\ttv_dst = --thr->valstack_top;\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_dst));\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv_dst));  /* plain number */\n\tDUK_TVAL_SET_UNDEFINED(tv_dst);  /* valstack init policy */\n\n\treturn res;\n#endif\n}\n\n/* XXX: combine all the integer conversions: they share everything\n * but the helper function for coercion.\n */\n\ntypedef duk_double_t (*duk__toint_coercer)(duk_hthread *thr, duk_tval *tv);\n\nDUK_LOCAL duk_double_t duk__to_int_uint_helper(duk_hthread *thr, duk_idx_t idx, duk__toint_coercer coerce_func) {\n\tduk_tval *tv;\n\tduk_double_t d;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_FASTINT)\n\t/* If argument is a fastint, guarantee that it remains one.\n\t * There's no downgrade check for other cases.\n\t */\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\t/* XXX: Unnecessary conversion back and forth. */\n\t\treturn (duk_double_t) DUK_TVAL_GET_FASTINT(tv);\n\t}\n#endif\n\td = coerce_func(thr, tv);\n\n\t/* XXX: fastint? */\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d);  /* side effects */\n\treturn d;\n}\n\nDUK_EXTERNAL duk_int_t duk_to_int(duk_hthread *thr, duk_idx_t idx) {\n\t/* Value coercion (in stack): ToInteger(), E5 Section 9.4,\n\t * API return value coercion: custom.\n\t */\n\tDUK_ASSERT_API_ENTRY(thr);\n\t(void) duk__to_int_uint_helper(thr, idx, duk_js_tointeger);\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_to_uint(duk_hthread *thr, duk_idx_t idx) {\n\t/* Value coercion (in stack): ToInteger(), E5 Section 9.4,\n\t * API return value coercion: custom.\n\t */\n\tDUK_ASSERT_API_ENTRY(thr);\n\t(void) duk__to_int_uint_helper(thr, idx, duk_js_tointeger);\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_int32_t duk_to_int32(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_int32_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tret = duk_js_toint32(thr, tv);\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_I32_UPDREF(thr, tv, ret);  /* side effects */\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_uint32_t duk_to_uint32(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_uint32_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tret = duk_js_touint32(thr, tv);\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_U32_UPDREF(thr, tv, ret);  /* side effects */\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_uint16_t duk_to_uint16(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_uint16_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tret = duk_js_touint16(thr, tv);\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_U32_UPDREF(thr, tv, ret);  /* side effects */\n\treturn ret;\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Special coercion for Uint8ClampedArray. */\nDUK_INTERNAL duk_uint8_t duk_to_uint8clamped(duk_hthread *thr, duk_idx_t idx) {\n\tduk_double_t d;\n\tduk_double_t t;\n\tduk_uint8_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: Simplify this algorithm, should be possible to come up with\n\t * a shorter and faster algorithm by inspecting IEEE representation\n\t * directly.\n\t */\n\n\td = duk_to_number(thr, idx);\n\tif (d <= 0.0) {\n\t\treturn 0;\n\t} else if (d >= 255) {\n\t\treturn 255;\n\t} else if (DUK_ISNAN(d)) {\n\t\t/* Avoid NaN-to-integer coercion as it is compiler specific. */\n\t\treturn 0;\n\t}\n\n\tt = d - DUK_FLOOR(d);\n\tif (t == 0.5) {\n\t\t/* Exact halfway, round to even. */\n\t\tret = (duk_uint8_t) d;\n\t\tret = (ret + 1) & 0xfe;  /* Example: d=3.5, t=0.5 -> ret = (3 + 1) & 0xfe = 4 & 0xfe = 4\n\t\t                          * Example: d=4.5, t=0.5 -> ret = (4 + 1) & 0xfe = 5 & 0xfe = 4\n\t\t                          */\n\t} else {\n\t\t/* Not halfway, round to nearest. */\n\t\tret = (duk_uint8_t) (d + 0.5);\n\t}\n\treturn ret;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_EXTERNAL const char *duk_to_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_to_string(thr, idx);\n\tDUK_ASSERT(duk_is_string(thr, idx));\n\treturn duk_require_lstring(thr, idx, out_len);\n}\n\nDUK_LOCAL duk_ret_t duk__safe_to_string_raw(duk_hthread *thr, void *udata) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(udata);\n\n\t(void) duk_to_string(thr, -1);\n\treturn 1;\n}\n\nDUK_EXTERNAL const char *duk_safe_to_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\t/* We intentionally ignore the duk_safe_call() return value and only\n\t * check the output type.  This way we don't also need to check that\n\t * the returned value is indeed a string in the success case.\n\t */\n\n\tduk_dup(thr, idx);\n\t(void) duk_safe_call(thr, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\tif (!duk_is_string(thr, -1)) {\n\t\t/* Error: try coercing error to string once. */\n\t\t(void) duk_safe_call(thr, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\t\tif (!duk_is_string(thr, -1)) {\n\t\t\t/* Double error */\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_ERROR);\n\t\t} else {\n\t\t\t;\n\t\t}\n\t} else {\n\t\t/* String; may be a symbol, accepted. */\n\t\t;\n\t}\n\tDUK_ASSERT(duk_is_string(thr, -1));\n\n\tduk_replace(thr, idx);\n\tDUK_ASSERT(duk_get_string(thr, idx) != NULL);\n\treturn duk_get_lstring(thr, idx, out_len);\n}\n\nDUK_EXTERNAL const char *duk_to_stacktrace(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tidx = duk_require_normalize_index(thr, idx);\n\n\t/* The expected argument to the call is an Error object.  The stack\n\t * trace is extracted without an inheritance-based instanceof check\n\t * so that one can also extract the stack trace of a foreign error\n\t * created in another Realm.  Accept only a string .stack property.\n\t */\n\tif (duk_is_object(thr, idx)) {\n\t\t(void) duk_get_prop_string(thr, idx, \"stack\");\n\t\tif (duk_is_string(thr, -1)) {\n\t\t\tduk_replace(thr, idx);\n\t\t} else {\n\t\t\tduk_pop(thr);\n\t\t}\n\t}\n\n\treturn duk_to_string(thr, idx);\n}\n\nDUK_LOCAL duk_ret_t duk__safe_to_stacktrace_raw(duk_hthread *thr, void *udata) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(udata);\n\n\t(void) duk_to_stacktrace(thr, -1);\n\n\treturn 1;\n}\n\nDUK_EXTERNAL const char *duk_safe_to_stacktrace(duk_hthread *thr, duk_idx_t idx) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tidx = duk_require_normalize_index(thr, idx);\n\n\tduk_dup(thr, idx);\n\trc = duk_safe_call(thr, duk__safe_to_stacktrace_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\tif (rc != 0) {\n\t\t/* Coercion failed.  Try to coerce the coercion itself error\n\t\t * to a stack trace once.  If that also fails, return a fixed,\n\t\t * preallocated 'Error' string to avoid potential infinite loop.\n\t\t */\n\t\trc = duk_safe_call(thr, duk__safe_to_stacktrace_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\t\tif (rc != 0) {\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_ERROR);\n\t\t}\n\t}\n\tduk_replace(thr, idx);\n\n\treturn duk_get_string(thr, idx);\n}\n\nDUK_INTERNAL duk_hstring *duk_to_property_key_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_to_primitive(thr, idx, DUK_HINT_STRING);  /* needed for e.g. Symbol objects */\n\th = duk_get_hstring(thr, idx);\n\tif (h == NULL) {\n\t\t/* The \"is string?\" check may seem unnecessary, but as things\n\t\t * are duk_to_hstring() invokes ToString() which fails for\n\t\t * symbols.  But since symbols are already strings for Duktape\n\t\t * C API, we check for that before doing the coercion.\n\t\t */\n\t\th = duk_to_hstring(thr, idx);\n\t}\n\tDUK_ASSERT(h != NULL);\n\treturn h;\n}\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* only needed by debugger for now */\nDUK_INTERNAL duk_hstring *duk_safe_to_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_safe_to_string(thr, idx);\n\tDUK_ASSERT(duk_is_string(thr, idx));\n\tDUK_ASSERT(duk_get_hstring(thr, idx) != NULL);\n\treturn duk_known_hstring(thr, idx);\n}\n#endif\n\n/* Push Object.prototype.toString() output for 'tv'. */\n#if 0  /* See XXX note why this variant doesn't work. */\nDUK_INTERNAL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects) {\n\tduk_uint_t stridx_bidx = 0;  /* (prototype_bidx << 16) + default_tag_stridx */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Conceptually for any non-undefined/null value we should do a\n\t * ToObject() coercion and look up @@toStringTag (from the object\n\t * prototype) to see if a custom tag should be used.  Avoid the\n\t * actual conversion by doing a prototype lookup without the object\n\t * coercion.  However, see problem below.\n\t */\n\n\tduk_push_literal(thr, \"[object \");  /* -> [ ... \"[object\" ] */\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:  /* Treat like 'undefined', shouldn't happen. */\n\tcase DUK_TAG_UNDEFINED: {\n\t\tstridx_bidx = DUK_STRIDX_UC_UNDEFINED;\n\t\tgoto use_stridx;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tstridx_bidx = DUK_STRIDX_UC_NULL;\n\t\tgoto use_stridx;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tstridx_bidx = (DUK_BIDX_BOOLEAN_PROTOTYPE << 16) + DUK_STRIDX_UC_BOOLEAN;\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tstridx_bidx = (DUK_BIDX_POINTER_PROTOTYPE << 16) + DUK_STRIDX_UC_POINTER;\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tstridx_bidx = (DUK_BIDX_FUNCTION_PROTOTYPE << 16) + DUK_STRIDX_UC_FUNCTION;\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\t/* Even without DUK_USE_SYMBOL_BUILTIN the Symbol\n\t\t\t * prototype exists so we can lookup @@toStringTag\n\t\t\t * and provide [object Symbol] for symbol values\n\t\t\t * created from C code.\n\t\t\t */\n\t\t\tstridx_bidx = (DUK_BIDX_SYMBOL_PROTOTYPE << 16) + DUK_STRIDX_UC_SYMBOL;\n\t\t} else {\n\t\t\tstridx_bidx = (DUK_BIDX_STRING_PROTOTYPE << 16) + DUK_STRIDX_UC_STRING;\n\t\t}\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_push_tval(thr, tv);\n\t\tstridx_bidx = 0xffffffffUL;  /* Marker value. */\n\t\tgoto use_pushed_object;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\tstridx_bidx = (DUK_BIDX_UINT8ARRAY_PROTOTYPE << 16) + DUK_STRIDX_UINT8_ARRAY;\n\t\tgoto use_proto_bidx;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\t/* Fall through to generic number case. */\n#endif\n\tdefault: {\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));  /* number (maybe fastint) */\n\t\tstridx_bidx = (DUK_BIDX_NUMBER_PROTOTYPE << 16) + DUK_STRIDX_UC_NUMBER;\n\t\tgoto use_proto_bidx;\n\t}\n\t}\n\tDUK_ASSERT(0);  /* Never here. */\n\n use_proto_bidx:\n\tDUK_ASSERT_BIDX_VALID((stridx_bidx >> 16) & 0xffffUL);\n\tduk_push_hobject(thr, thr->builtins[(stridx_bidx >> 16) & 0xffffUL]);\n\t/* Fall through. */\n\n use_pushed_object:\n\t/* [ ... \"[object\" obj ] */\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t/* XXX: better handling with avoid_side_effects == 1; lookup tval\n\t * without Proxy or getter side effects, and use it in sanitized\n\t * form if it's a string.\n\t */\n\tif (!avoid_side_effects) {\n\t\t/* XXX: The problem with using the prototype object as the\n\t\t * lookup base is that if @@toStringTag is a getter, its\n\t\t * 'this' binding must be the ToObject() coerced input value,\n\t\t * not the prototype object of the type.\n\t\t */\n\t\t(void) duk_get_prop_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG);\n\t\tif (duk_is_string_notsymbol(thr, -1)) {\n\t\t\tduk_remove_m2(thr);\n\t\t\tgoto finish;\n\t\t}\n\t\tduk_pop_unsafe(thr);\n\t}\n#endif\n\n\tif (stridx_bidx == 0xffffffffUL) {\n\t\tduk_hobject *h_obj;\n\t\tduk_small_uint_t classnum;\n\n\t\th_obj = duk_known_hobject(thr, -1);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tclassnum = DUK_HOBJECT_GET_CLASS_NUMBER(h_obj);\n\t\tstridx_bidx = DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum);\n\t} else {\n\t\t/* stridx_bidx already has the desired fallback stridx. */\n\t\t;\n\t}\n\tduk_pop_unsafe(thr);\n\t/* Fall through. */\n\n use_stridx:\n\t/* [ ... \"[object\" ] */\n\tduk_push_hstring_stridx(thr, stridx_bidx & 0xffffUL);\n\n finish:\n\t/* [ ... \"[object\" tag ] */\n\tduk_push_literal(thr, \"]\");\n\tduk_concat(thr, 3);  /* [ ... \"[object\" tag \"]\" ] -> [ ... res ] */\n}\n#endif  /* 0 */\n\nDUK_INTERNAL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects) {\n\tduk_hobject *h_obj;\n\tduk_small_uint_t classnum;\n\tduk_small_uint_t stridx;\n\tduk_tval tv_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\t/* Stabilize 'tv', duk_push_literal() may trigger side effects. */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv);\n\ttv = &tv_tmp;\n\n\t/* Conceptually for any non-undefined/null value we should do a\n\t * ToObject() coercion and look up @@toStringTag (from the object\n\t * prototype) to see if a custom result should be used.  We'd like to\n\t * avoid the actual conversion, but even for primitive types the\n\t * prototype may have @@toStringTag.  What's worse, the @@toStringTag\n\t * property may be a getter that must get the object coerced value\n\t * (not the prototype) as its 'this' binding.\n\t *\n\t * For now, do an actual object coercion.  This could be avoided by\n\t * doing a side effect free lookup to see if a getter would be invoked.\n\t * If not, the value can be read directly and the object coercion could\n\t * be avoided.  This may not be worth it in practice, because\n\t * Object.prototype.toString() is usually not performance critical.\n\t */\n\n\tduk_push_literal(thr, \"[object \");  /* -> [ ... \"[object\" ] */\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:  /* Treat like 'undefined', shouldn't happen. */\n\tcase DUK_TAG_UNDEFINED: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_UNDEFINED);\n\t\tgoto finish;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_NULL);\n\t\tgoto finish;\n\t}\n\t}\n\n\tduk_push_tval(thr, tv);\n\ttv = NULL;  /* Invalidated by ToObject(). */\n\tduk_to_object(thr, -1);\n\n\t/* [ ... \"[object\" obj ] */\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t/* XXX: better handling with avoid_side_effects == 1; lookup tval\n\t * without Proxy or getter side effects, and use it in sanitized\n\t * form if it's a string.\n\t */\n\tif (!avoid_side_effects) {\n\t\t(void) duk_get_prop_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG);\n\t\tif (duk_is_string_notsymbol(thr, -1)) {\n\t\t\tduk_remove_m2(thr);\n\t\t\tgoto finish;\n\t\t}\n\t\tduk_pop_unsafe(thr);\n\t}\n#else\n\tDUK_UNREF(avoid_side_effects);\n#endif\n\n\th_obj = duk_known_hobject(thr, -1);\n\tDUK_ASSERT(h_obj != NULL);\n\tclassnum = DUK_HOBJECT_GET_CLASS_NUMBER(h_obj);\n\tstridx = DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum);\n\tduk_pop_unsafe(thr);\n\tduk_push_hstring_stridx(thr, stridx);\n\n finish:\n\t/* [ ... \"[object\" tag ] */\n\tduk_push_literal(thr, \"]\");\n\tduk_concat(thr, 3);  /* [ ... \"[object\" tag \"]\" ] -> [ ... res ] */\n}\n\n/* XXX: other variants like uint, u32 etc */\nDUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped) {\n\tduk_tval *tv;\n\tduk_tval tv_tmp;\n\tduk_double_t d, dmin, dmax;\n\tduk_int_t res;\n\tduk_bool_t clamped = 0;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\td = duk_js_tointeger(thr, tv);  /* E5 Section 9.4, ToInteger() */\n\n\tdmin = (duk_double_t) minval;\n\tdmax = (duk_double_t) maxval;\n\n\tif (d < dmin) {\n\t\tclamped = 1;\n\t\tres = minval;\n\t\td = dmin;\n\t} else if (d > dmax) {\n\t\tclamped = 1;\n\t\tres = maxval;\n\t\td = dmax;\n\t} else {\n\t\tres = (duk_int_t) d;\n\t}\n\tDUK_UNREF(d);  /* SCANBUILD: with suitable dmin/dmax limits 'd' is unused */\n\t/* 'd' and 'res' agree here */\n\n\t/* Relookup in case duk_js_tointeger() ends up e.g. coercing an object. */\n\ttv = duk_get_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);  /* not popped by side effect */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv);\n#if defined(DUK_USE_FASTINT)\n#if (DUK_INT_MAX <= 0x7fffffffL)\n\tDUK_TVAL_SET_I32(tv, res);\n#else\n\t/* Clamping needed if duk_int_t is 64 bits. */\n\tif (res >= DUK_FASTINT_MIN && res <= DUK_FASTINT_MAX) {\n\t\tDUK_TVAL_SET_FASTINT(tv, res);\n\t} else {\n\t\tDUK_TVAL_SET_NUMBER(tv, d);\n\t}\n#endif\n#else\n\tDUK_TVAL_SET_NUMBER(tv, d);  /* no need to incref */\n#endif\n\tDUK_TVAL_DECREF(thr, &tv_tmp);  /* side effects */\n\n\tif (out_clamped) {\n\t\t*out_clamped = clamped;\n\t} else {\n\t\t/* coerced value is updated to value stack even when RangeError thrown */\n\t\tif (clamped) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_NUMBER_OUTSIDE_RANGE);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t}\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_int_t duk_to_int_clamped(duk_hthread *thr, duk_idx_t idx, duk_idx_t minval, duk_idx_t maxval) {\n\tduk_bool_t dummy;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_to_int_clamped_raw(thr, idx, minval, maxval, &dummy);\n}\n\nDUK_INTERNAL duk_int_t duk_to_int_check_range(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_int_clamped_raw(thr, idx, minval, maxval, NULL);  /* out_clamped==NULL -> RangeError if outside range */\n}\n\nDUK_EXTERNAL const char *duk_to_string(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_LC_UNDEFINED);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_LC_NULL);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tif (DUK_TVAL_GET_BOOLEAN(tv)) {\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_TRUE);\n\t\t} else {\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_FALSE);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\t/* Nop for actual strings, TypeError for Symbols.\n\t\t * Because various internals rely on ToString() coercion of\n\t\t * internal strings, -allow- (NOP) string coercion for hidden\n\t\t * symbols.\n\t\t */\n#if 1\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CANNOT_STRING_COERCE_SYMBOL);\n\t\t\tDUK_WO_NORETURN(goto skip_replace;);\n\t\t} else {\n\t\t\tgoto skip_replace;\n\t\t}\n#else\n\t\tgoto skip_replace;\n#endif\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: /* Go through Uint8Array.prototype.toString() for coercion. */\n\tcase DUK_TAG_OBJECT: {\n\t\t/* Plain buffers: go through ArrayBuffer.prototype.toString()\n\t\t * for coercion.\n\t\t *\n\t\t * Symbol objects: duk_to_primitive() results in a plain symbol\n\t\t * value, and duk_to_string() then causes a TypeError.\n\t\t */\n\t\tduk_to_primitive(thr, idx, DUK_HINT_STRING);\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* ToPrimitive() must guarantee */\n\t\tDUK_ASSERT(!duk_is_object(thr, idx));\n\t\treturn duk_to_string(thr, idx);  /* Note: recursive call */\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tvoid *ptr = DUK_TVAL_GET_POINTER(tv);\n\t\tif (ptr != NULL) {\n\t\t\tduk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) ptr);\n\t\t} else {\n\t\t\t/* Represent a null pointer as 'null' to be consistent with\n\t\t\t * the JX format variant.  Native '%p' format for a NULL\n\t\t\t * pointer may be e.g. '(nil)'.\n\t\t\t */\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_LC_NULL);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Should match Function.prototype.toString() */\n\t\tduk_push_lightfunc_tostring(thr, tv);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tduk_push_tval(thr, tv);\n\t\tduk_numconv_stringify(thr,\n\t\t                      10 /*radix*/,\n\t\t                      0 /*precision:shortest*/,\n\t\t                      0 /*force_exponential*/);\n\t\tbreak;\n\t}\n\t}\n\n\tduk_replace(thr, idx);\n\n skip_replace:\n\tDUK_ASSERT(duk_is_string(thr, idx));\n\treturn duk_require_string(thr, idx);\n}\n\nDUK_INTERNAL duk_hstring *duk_to_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_to_string(thr, idx);\n\tret = duk_get_hstring(thr, idx);\n\tDUK_ASSERT(ret != NULL);\n\treturn ret;\n}\n\nDUK_INTERNAL duk_hstring *duk_to_hstring_m1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_hstring(thr, -1);\n}\n\nDUK_INTERNAL duk_hstring *duk_to_hstring_acceptsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_hstring(thr, idx);\n\tif (DUK_UNLIKELY(ret && DUK_HSTRING_HAS_SYMBOL(ret))) {\n\t\treturn ret;\n\t}\n\treturn duk_to_hstring(thr, idx);\n}\n\n/* Convert a plain buffer or any buffer object into a string, using the buffer\n * bytes 1:1 in the internal string representation.  For views the active byte\n * slice (not element slice interpreted as an initializer) is used.  This is\n * necessary in Duktape 2.x because ToString(plainBuffer) no longer creates a\n * string with the same bytes as in the buffer but rather (usually)\n * '[object ArrayBuffer]'.\n */\nDUK_EXTERNAL const char *duk_buffer_to_string(duk_hthread *thr, duk_idx_t idx) {\n\tvoid *ptr_src;\n\tduk_size_t len;\n\tconst char *res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\tptr_src = duk_require_buffer_data(thr, idx, &len);\n\tDUK_ASSERT(ptr_src != NULL || len == 0);\n\n\tres = duk_push_lstring(thr, (const char *) ptr_src, len);\n\tduk_replace(thr, idx);\n\treturn res;\n}\n\nDUK_EXTERNAL void *duk_to_buffer_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, duk_uint_t mode) {\n\tduk_hbuffer *h_buf;\n\tconst duk_uint8_t *src_data;\n\tduk_size_t src_size;\n\tduk_uint8_t *dst_data;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\th_buf = duk_get_hbuffer(thr, idx);\n\tif (h_buf != NULL) {\n\t\t/* Buffer is kept as is, with the fixed/dynamic nature of the\n\t\t * buffer only changed if requested.  An external buffer\n\t\t * is converted into a non-external dynamic buffer in a\n\t\t * duk_to_dynamic_buffer() call.\n\t\t */\n\t\tduk_uint_t tmp;\n\t\tduk_uint8_t *tmp_ptr;\n\n\t\ttmp_ptr = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_buf);\n\t\tsrc_data = (const duk_uint8_t *) tmp_ptr;\n\t\tsrc_size = DUK_HBUFFER_GET_SIZE(h_buf);\n\n\t\ttmp = (DUK_HBUFFER_HAS_DYNAMIC(h_buf) ? DUK_BUF_MODE_DYNAMIC : DUK_BUF_MODE_FIXED);\n\t\tif ((tmp == mode && !DUK_HBUFFER_HAS_EXTERNAL(h_buf)) ||\n\t\t    mode == DUK_BUF_MODE_DONTCARE) {\n\t\t\t/* Note: src_data may be NULL if input is a zero-size\n\t\t\t * dynamic buffer.\n\t\t\t */\n\t\t\tdst_data = tmp_ptr;\n\t\t\tgoto skip_copy;\n\t\t}\n\t} else {\n\t\t/* Non-buffer value is first ToString() coerced, then converted\n\t\t * to a buffer (fixed buffer is used unless a dynamic buffer is\n\t\t * explicitly requested).  Symbols are rejected with a TypeError.\n\t\t * XXX: C API could maybe allow symbol-to-buffer coercion?\n\t\t */\n\t\tsrc_data = (const duk_uint8_t *) duk_to_lstring(thr, idx, &src_size);\n\t}\n\n\tdst_data = (duk_uint8_t *) duk_push_buffer(thr, src_size, (mode == DUK_BUF_MODE_DYNAMIC) /*dynamic*/);\n\t/* dst_data may be NULL if size is zero. */\n\tduk_memcpy_unsafe((void *) dst_data, (const void *) src_data, (size_t) src_size);\n\n\tduk_replace(thr, idx);\n skip_copy:\n\n\tif (out_size) {\n\t\t*out_size = src_size;\n\t}\n\treturn dst_data;\n}\n\nDUK_EXTERNAL void *duk_to_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\tcase DUK_TAG_BOOLEAN:\n\t\tres = NULL;\n\t\tbreak;\n\tcase DUK_TAG_POINTER:\n\t\tres = DUK_TVAL_GET_POINTER(tv);\n\t\tbreak;\n\tcase DUK_TAG_STRING:\n\tcase DUK_TAG_OBJECT:\n\tcase DUK_TAG_BUFFER:\n\t\t/* Heap allocated: return heap pointer which is NOT useful\n\t\t * for the caller, except for debugging.\n\t\t */\n\t\tres = (void *) DUK_TVAL_GET_HEAPHDR(tv);\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\t/* Function pointers do not always cast correctly to void *\n\t\t * (depends on memory and segmentation model for instance),\n\t\t * so they coerce to NULL.\n\t\t */\n\t\tres = NULL;\n\t\tbreak;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tres = NULL;\n\t\tbreak;\n\t}\n\n\tduk_push_pointer(thr, res);\n\tduk_replace(thr, idx);\n\treturn res;\n}\n\nDUK_LOCAL void duk__push_func_from_lightfunc(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags) {\n\tduk_idx_t nargs;\n\tduk_uint_t flags = 0;   /* shared flags for a subset of types */\n\tduk_small_uint_t lf_len;\n\tduk_hnatfunc *nf;\n\n\tnargs = (duk_idx_t) DUK_LFUNC_FLAGS_GET_NARGS(lf_flags);\n\tif (nargs == DUK_LFUNC_NARGS_VARARGS) {\n\t\tnargs = (duk_idx_t) DUK_VARARGS;\n\t}\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\t(void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE);\n\n\tlf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags);\n\tif ((duk_idx_t) lf_len != nargs) {\n\t\t/* Explicit length is only needed if it differs from 'nargs'. */\n\t\tduk_push_int(thr, (duk_int_t) lf_len);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tduk_push_lightfunc_name_raw(thr, func, lf_flags);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n#endif\n\n\tnf = duk_known_hnatfunc(thr, -1);\n\tnf->magic = (duk_int16_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags);\n}\n\nDUK_EXTERNAL void duk_to_object(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_uint_t flags = 0;   /* shared flags for a subset of types */\n\tduk_small_int_t proto = 0;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n#if !defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tcase DUK_TAG_BUFFER:  /* With no bufferobject support, don't object coerce. */\n#endif\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL: {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_OBJECT_COERCIBLE);\n\t\tDUK_WO_NORETURN(return;);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BOOLEAN);\n\t\tproto = DUK_BIDX_BOOLEAN_PROTOTYPE;\n\t\tgoto create_object;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_SYMBOL);\n\t\t\tproto = DUK_BIDX_SYMBOL_PROTOTYPE;\n\t\t} else {\n\t\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t\t        DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ |\n\t\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_STRING);\n\t\t\tproto = DUK_BIDX_STRING_PROTOTYPE;\n\t\t}\n\t\tgoto create_object;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\t/* nop */\n\t\tbreak;\n\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tcase DUK_TAG_BUFFER: {\n\t\t/* A plain buffer object coerces to a full ArrayBuffer which\n\t\t * is not fully transparent behavior (ToObject() should be a\n\t\t * nop for an object).  This behavior matches lightfuncs which\n\t\t * also coerce to an equivalent Function object.  There are\n\t\t * also downsides to defining ToObject(plainBuffer) as a no-op;\n\t\t * for example duk_to_hobject() could result in a NULL pointer.\n\t\t */\n\t\tduk_hbuffer *h_buf;\n\n\t\th_buf = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h_buf != NULL);\n\t\tduk_hbufobj_push_uint8array_from_plain(thr, h_buf);\n\t\tgoto replace_value;\n\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\tcase DUK_TAG_POINTER: {\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER);\n\t\tproto = DUK_BIDX_POINTER_PROTOTYPE;\n\t\tgoto create_object;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Lightfunc coerces to a Function instance with concrete\n\t\t * properties.  Since 'length' is virtual for Duktape/C\n\t\t * functions, don't need to define that.  The result is made\n\t\t * extensible to mimic what happens to strings in object\n\t\t * coercion:\n\t\t *\n\t\t *   > Object.isExtensible(Object('foo'))\n\t\t *   true\n\t\t */\n\t\tduk_small_uint_t lf_flags;\n\t\tduk_c_function func;\n\n\t\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);\n\t\tduk__push_func_from_lightfunc(thr, func, lf_flags);\n\t\tgoto replace_value;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_NUMBER);\n\t\tproto = DUK_BIDX_NUMBER_PROTOTYPE;\n\t\tgoto create_object;\n\t}\n\t}\n\tDUK_ASSERT(duk_is_object(thr, idx));\n\treturn;\n\n create_object:\n\t(void) duk_push_object_helper(thr, flags, proto);\n\n\t/* Note: Boolean prototype's internal value property is not writable,\n\t * but duk_xdef_prop_stridx() disregards the write protection.  Boolean\n\t * instances are immutable.\n\t *\n\t * String and buffer special behaviors are already enabled which is not\n\t * ideal, but a write to the internal value is not affected by them.\n\t */\n\tduk_dup(thr, idx);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\n replace_value:\n\tduk_replace(thr, idx);\n\tDUK_ASSERT(duk_is_object(thr, idx));\n}\n\nDUK_INTERNAL duk_hobject *duk_to_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_to_object(thr, idx);\n\tret = duk_known_hobject(thr, idx);\n\treturn ret;\n}\n\n/*\n *  Type checking\n */\n\nDUK_LOCAL duk_bool_t duk__tag_check(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t tag) {\n\tduk_tval *tv;\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\treturn (DUK_TVAL_GET_TAG(tv) == tag);\n}\n\nDUK_LOCAL duk_bool_t duk__obj_flag_any_default_false(duk_hthread *thr, duk_idx_t idx, duk_uint_t flag_mask) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, idx);\n\tif (obj) {\n\t\treturn (DUK_HEAPHDR_CHECK_FLAG_BITS((duk_heaphdr *) obj, flag_mask) ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_INTERNAL duk_int_t duk_get_type_tval(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_PACKED_TVAL)\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:\n\t\treturn DUK_TYPE_NONE;\n\tcase DUK_TAG_UNDEFINED:\n\t\treturn DUK_TYPE_UNDEFINED;\n\tcase DUK_TAG_NULL:\n\t\treturn DUK_TYPE_NULL;\n\tcase DUK_TAG_BOOLEAN:\n\t\treturn DUK_TYPE_BOOLEAN;\n\tcase DUK_TAG_STRING:\n\t\treturn DUK_TYPE_STRING;\n\tcase DUK_TAG_OBJECT:\n\t\treturn DUK_TYPE_OBJECT;\n\tcase DUK_TAG_BUFFER:\n\t\treturn DUK_TYPE_BUFFER;\n\tcase DUK_TAG_POINTER:\n\t\treturn DUK_TYPE_POINTER;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\treturn DUK_TYPE_LIGHTFUNC;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* Note: number has no explicit tag (in 8-byte representation) */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\treturn DUK_TYPE_NUMBER;\n\t}\n#else  /* DUK_USE_PACKED_TVAL */\n\tDUK_ASSERT(DUK_TVAL_IS_VALID_TAG(tv));\n\tDUK_ASSERT(sizeof(duk__type_from_tag) / sizeof(duk_uint_t) == DUK_TAG_MAX - DUK_TAG_MIN + 1);\n\treturn (duk_int_t) duk__type_from_tag[DUK_TVAL_GET_TAG(tv) - DUK_TAG_MIN];\n#endif  /* DUK_USE_PACKED_TVAL */\n}\n\nDUK_EXTERNAL duk_int_t duk_get_type(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\treturn duk_get_type_tval(tv);\n}\n\n#if defined(DUK_USE_VERBOSE_ERRORS) && defined(DUK_USE_PARANOID_ERRORS)\nDUK_LOCAL const char * const duk__type_names[] = {\n\t\"none\",\n\t\"undefined\",\n\t\"null\",\n\t\"boolean\",\n\t\"number\",\n\t\"string\",\n\t\"object\",\n\t\"buffer\",\n\t\"pointer\",\n\t\"lightfunc\"\n};\n\nDUK_INTERNAL const char *duk_get_type_name(duk_hthread *thr, duk_idx_t idx) {\n\tduk_int_t type_tag;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttype_tag = duk_get_type(thr, idx);\n\tDUK_ASSERT(type_tag >= DUK_TYPE_MIN && type_tag <= DUK_TYPE_MAX);\n\tDUK_ASSERT(DUK_TYPE_MIN == 0 && sizeof(duk__type_names) / sizeof(const char *) == DUK_TYPE_MAX + 1);\n\n\treturn duk__type_names[type_tag];\n}\n#endif  /* DUK_USE_VERBOSE_ERRORS && DUK_USE_PARANOID_ERRORS */\n\nDUK_INTERNAL duk_small_uint_t duk_get_class_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_OBJECT:\n\t\tobj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(obj != NULL);\n\t\treturn DUK_HOBJECT_GET_CLASS_NUMBER(obj);\n\tcase DUK_TAG_BUFFER:\n\t\t/* Buffers behave like Uint8Array objects. */\n\t\treturn DUK_HOBJECT_CLASS_UINT8ARRAY;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\t/* Lightfuncs behave like Function objects. */\n\t\treturn DUK_HOBJECT_CLASS_FUNCTION;\n\tdefault:\n\t\t/* Primitive or UNUSED, no class number. */\n\t\treturn DUK_HOBJECT_CLASS_NONE;\n\t}\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_type(duk_hthread *thr, duk_idx_t idx, duk_int_t type) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_get_type(thr, idx) == type) ? 1 : 0;\n}\n\nDUK_INTERNAL duk_uint_t duk_get_type_mask_tval(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_PACKED_TVAL)\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:\n\t\treturn DUK_TYPE_MASK_NONE;\n\tcase DUK_TAG_UNDEFINED:\n\t\treturn DUK_TYPE_MASK_UNDEFINED;\n\tcase DUK_TAG_NULL:\n\t\treturn DUK_TYPE_MASK_NULL;\n\tcase DUK_TAG_BOOLEAN:\n\t\treturn DUK_TYPE_MASK_BOOLEAN;\n\tcase DUK_TAG_STRING:\n\t\treturn DUK_TYPE_MASK_STRING;\n\tcase DUK_TAG_OBJECT:\n\t\treturn DUK_TYPE_MASK_OBJECT;\n\tcase DUK_TAG_BUFFER:\n\t\treturn DUK_TYPE_MASK_BUFFER;\n\tcase DUK_TAG_POINTER:\n\t\treturn DUK_TYPE_MASK_POINTER;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\treturn DUK_TYPE_MASK_LIGHTFUNC;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* Note: number has no explicit tag (in 8-byte representation) */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\treturn DUK_TYPE_MASK_NUMBER;\n\t}\n#else  /* DUK_USE_PACKED_TVAL */\n\tDUK_ASSERT(DUK_TVAL_IS_VALID_TAG(tv));\n\tDUK_ASSERT(sizeof(duk__type_mask_from_tag) / sizeof(duk_uint_t) == DUK_TAG_MAX - DUK_TAG_MIN + 1);\n\treturn duk__type_mask_from_tag[DUK_TVAL_GET_TAG(tv) - DUK_TAG_MIN];\n#endif  /* DUK_USE_PACKED_TVAL */\n}\n\nDUK_EXTERNAL duk_uint_t duk_get_type_mask(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\treturn duk_get_type_mask_tval(tv);\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_type_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (DUK_LIKELY((duk_get_type_mask(thr, idx) & mask) != 0U)) {\n\t\treturn 1;\n\t}\n\tif (mask & DUK_TYPE_MASK_THROW) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_UNEXPECTED_TYPE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_UNDEFINED);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_null(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_NULL);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_BOOLEAN);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/*\n\t *  Number is special because it doesn't have a specific\n\t *  tag in the 8-byte representation.\n\t */\n\n\t/* XXX: shorter version for unpacked representation? */\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\treturn DUK_TVAL_IS_NUMBER(tv);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_nan(duk_hthread *thr, duk_idx_t idx) {\n\t/* XXX: This will now return false for non-numbers, even though they would\n\t * coerce to NaN (as a general rule).  In particular, duk_get_number()\n\t * returns a NaN for non-numbers, so should this function also return\n\t * true for non-numbers?\n\t */\n\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\t/* XXX: for packed duk_tval an explicit \"is number\" check is unnecessary */\n\tif (!DUK_TVAL_IS_NUMBER(tv)) {\n\t\treturn 0;\n\t}\n\treturn (duk_bool_t) DUK_ISNAN(DUK_TVAL_GET_NUMBER(tv));\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_string(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_STRING);\n}\n\nDUK_INTERNAL duk_bool_t duk_is_string_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_hstring_notsymbol(thr, idx) != NULL;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_object(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_OBJECT);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_BUFFER);\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\treturn 1;\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\nDUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_is_buffer(thr, idx);\n}\n\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_EXTERNAL duk_bool_t duk_is_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_POINTER);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_lightfunc(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_LIGHTFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_symbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\th = duk_get_hstring(thr, idx);\n\t/* Use DUK_LIKELY() here because caller may be more likely to type\n\t * check an expected symbol than not.\n\t */\n\tif (DUK_LIKELY(h != NULL && DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_array(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, idx);\n\tif (obj) {\n\t\treturn (DUK_HOBJECT_GET_CLASS_NUMBER(obj) == DUK_HOBJECT_CLASS_ARRAY ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_function(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn DUK_HOBJECT_HAS_CALLABLE(h) ? 1 : 0;\n\t}\n\tif (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_INTERNAL duk_bool_t duk_is_callable_tval(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_UNREF(thr);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn DUK_HOBJECT_HAS_CALLABLE(h) ? 1 : 0;\n\t}\n\tif (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_constructable(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn DUK_HOBJECT_HAS_CONSTRUCTABLE(h) ? 1 : 0;\n\t}\n\tif (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_c_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__obj_flag_any_default_false(thr,\n\t                                       idx,\n\t                                       DUK_HOBJECT_FLAG_NATFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_ecmascript_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__obj_flag_any_default_false(thr,\n\t                                       idx,\n\t                                       DUK_HOBJECT_FLAG_COMPFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_bound_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__obj_flag_any_default_false(thr,\n\t                                       idx,\n\t                                       DUK_HOBJECT_FLAG_BOUNDFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_thread(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, idx);\n\tif (obj) {\n\t\treturn (DUK_HOBJECT_GET_CLASS_NUMBER(obj) == DUK_HOBJECT_CLASS_THREAD ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_fixed_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HBUFFER_HAS_DYNAMIC(h) ? 0 : 1);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_dynamic_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h) ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_external_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HBUFFER_HAS_DYNAMIC(h) && DUK_HBUFFER_HAS_EXTERNAL(h) ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_errcode_t duk_get_error_code(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hobject(thr, idx);\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (!h) {\n\t\t\treturn DUK_ERR_NONE;\n\t\t}\n\n\t\t/* XXX: something more convenient? */\n\n\t\tif (h == thr->builtins[DUK_BIDX_EVAL_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_EVAL_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_RANGE_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_RANGE_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_REFERENCE_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_REFERENCE_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_SYNTAX_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_SYNTAX_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_TYPE_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_TYPE_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_URI_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_URI_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_ERROR;\n\t\t}\n\n\t\th = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t} while (--sanity > 0);\n\n\treturn DUK_ERR_NONE;\n}\n\n/*\n *  Pushers\n */\n\nDUK_INTERNAL void duk_push_tval(duk_hthread *thr, duk_tval *tv) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_TVAL(tv_slot, tv);\n\tDUK_TVAL_INCREF(thr, tv);  /* no side effects */\n}\n\nDUK_EXTERNAL void duk_push_undefined(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\t/* Because value stack init policy is 'undefined above top',\n\t * we don't need to write, just assert.\n\t */\n\tthr->valstack_top++;\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));\n}\n\nDUK_EXTERNAL void duk_push_null(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NULL(tv_slot);\n}\n\nDUK_EXTERNAL void duk_push_boolean(duk_hthread *thr, duk_bool_t val) {\n\tduk_tval *tv_slot;\n\tduk_small_int_t b;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\tb = (val ? 1 : 0);  /* ensure value is 1 or 0 (not other non-zero) */\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_BOOLEAN(tv_slot, b);\n}\n\nDUK_EXTERNAL void duk_push_true(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_BOOLEAN_TRUE(tv_slot);\n}\n\nDUK_EXTERNAL void duk_push_false(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_BOOLEAN_FALSE(tv_slot);\n}\n\n/* normalize NaN which may not match our canonical internal NaN */\nDUK_EXTERNAL void duk_push_number(duk_hthread *thr, duk_double_t val) {\n\tduk_tval *tv_slot;\n\tduk_double_union du;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\tdu.d = val;\n\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, du.d);\n}\n\nDUK_EXTERNAL void duk_push_int(duk_hthread *thr, duk_int_t val) {\n#if defined(DUK_USE_FASTINT)\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n#if DUK_INT_MAX <= 0x7fffffffL\n\tDUK_TVAL_SET_I32(tv_slot, (duk_int32_t) val);\n#else\n\tif (val >= DUK_FASTINT_MIN && val <= DUK_FASTINT_MAX) {\n\t\tDUK_TVAL_SET_FASTINT(tv_slot, (duk_int64_t) val);\n\t} else {\n\t\tduk_double_t = (duk_double_t) val;\n\t\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n\t}\n#endif\n#else  /* DUK_USE_FASTINT */\n\tduk_tval *tv_slot;\n\tduk_double_t d;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\td = (duk_double_t) val;\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n#endif  /* DUK_USE_FASTINT */\n}\n\nDUK_EXTERNAL void duk_push_uint(duk_hthread *thr, duk_uint_t val) {\n#if defined(DUK_USE_FASTINT)\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n#if DUK_UINT_MAX <= 0xffffffffUL\n\tDUK_TVAL_SET_U32(tv_slot, (duk_uint32_t) val);\n#else\n\tif (val <= DUK_FASTINT_MAX) {  /* val is unsigned so >= 0 */\n\t\t/* XXX: take advantage of val being unsigned, no need to mask */\n\t\tDUK_TVAL_SET_FASTINT(tv_slot, (duk_int64_t) val);\n\t} else {\n\t\tduk_double_t = (duk_double_t) val;\n\t\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n\t}\n#endif\n#else  /* DUK_USE_FASTINT */\n\tduk_tval *tv_slot;\n\tduk_double_t d;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\td = (duk_double_t) val;\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n#endif  /* DUK_USE_FASTINT */\n}\n\nDUK_EXTERNAL void duk_push_nan(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\tduk_double_union du;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\tDUK_DBLUNION_SET_NAN(&du);\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, du.d);\n}\n\nDUK_EXTERNAL const char *duk_push_lstring(duk_hthread *thr, const char *str, duk_size_t len) {\n\tduk_hstring *h;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Check stack before interning (avoid hanging temp). */\n\tDUK__CHECK_SPACE();\n\n\t/* NULL with zero length represents an empty string; NULL with higher\n\t * length is also now treated like an empty string although it is\n\t * a bit dubious.  This is unlike duk_push_string() which pushes a\n\t * 'null' if the input string is a NULL.\n\t */\n\tif (DUK_UNLIKELY(str == NULL)) {\n\t\tlen = 0U;\n\t}\n\n\t/* Check for maximum string length. */\n\tif (DUK_UNLIKELY(len > DUK_HSTRING_MAX_BYTELEN)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_STRING_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\th = duk_heap_strtable_intern_checked(thr, (const duk_uint8_t *) str, (duk_uint32_t) len);\n\tDUK_ASSERT(h != NULL);\n\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_STRING(tv_slot, h);\n\tDUK_HSTRING_INCREF(thr, h);  /* no side effects */\n\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_EXTERNAL const char *duk_push_string(duk_hthread *thr, const char *str) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (str) {\n\t\treturn duk_push_lstring(thr, str, DUK_STRLEN(str));\n\t} else {\n\t\tduk_push_null(thr);\n\t\treturn NULL;\n\t}\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_EXTERNAL const char *duk_push_literal_raw(duk_hthread *thr, const char *str, duk_size_t len) {\n\tduk_hstring *h;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(str != NULL);\n\tDUK_ASSERT(str[len] == (char) 0);\n\n\t/* Check for maximum string length. */\n\tif (DUK_UNLIKELY(len > DUK_HSTRING_MAX_BYTELEN)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_STRING_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\th = duk_heap_strtable_intern_literal_checked(thr, (const duk_uint8_t *) str, (duk_uint32_t) len);\n\tDUK_ASSERT(h != NULL);\n\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_STRING(tv_slot, h);\n\tDUK_HSTRING_INCREF(thr, h);  /* no side effects */\n\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n#else  /* DUK_USE_LITCACHE_SIZE */\nDUK_EXTERNAL const char *duk_push_literal_raw(duk_hthread *thr, const char *str, duk_size_t len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(str != NULL);\n\tDUK_ASSERT(str[len] == (char) 0);\n\n\treturn duk_push_lstring(thr, str, len);\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n#endif  /* !DUK_USE_PREFER_SIZE */\n\nDUK_EXTERNAL void duk_push_pointer(duk_hthread *thr, void *val) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_POINTER(tv_slot, val);\n}\n\nDUK_INTERNAL duk_hstring *duk_push_uint_to_hstring(duk_hthread *thr, duk_uint_t i) {\n\tduk_hstring *h_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: this could be a direct DUK_SPRINTF to a buffer followed by duk_push_string() */\n\tduk_push_uint(thr, (duk_uint_t) i);\n\th_tmp = duk_to_hstring_m1(thr);\n\tDUK_ASSERT(h_tmp != NULL);\n\treturn h_tmp;\n}\n\nDUK_LOCAL void duk__push_this_helper(duk_hthread *thr, duk_small_uint_t check_object_coercible) {\n\tduk_tval *tv_slot;\n\n\tDUK__CHECK_SPACE();\n\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* because of valstack init policy */\n\ttv_slot = thr->valstack_top++;\n\n\tif (DUK_UNLIKELY(thr->callstack_curr == NULL)) {\n\t\tif (check_object_coercible) {\n\t\t\tgoto type_error;\n\t\t}\n\t\t/* 'undefined' already on stack top */\n\t} else {\n\t\tduk_tval *tv;\n\n\t\t/* 'this' binding is just before current activation's bottom */\n\t\tDUK_ASSERT(thr->valstack_bottom > thr->valstack);\n\t\ttv = thr->valstack_bottom - 1;\n\t\tif (check_object_coercible &&\n\t\t    (DUK_TVAL_IS_UNDEFINED(tv) || DUK_TVAL_IS_NULL(tv))) {\n\t\t\t/* XXX: better macro for DUK_TVAL_IS_UNDEFINED_OR_NULL(tv) */\n\t\t\tgoto type_error;\n\t\t}\n\n\t\tDUK_TVAL_SET_TVAL(tv_slot, tv);\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t}\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_OBJECT_COERCIBLE);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_push_this(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 0 /*check_object_coercible*/);\n}\n\nDUK_INTERNAL void duk_push_this_check_object_coercible(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 1 /*check_object_coercible*/);\n}\n\nDUK_INTERNAL duk_hobject *duk_push_this_coercible_to_object(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 1 /*check_object_coercible*/);\n\th = duk_to_hobject(thr, -1);\n\tDUK_ASSERT(h != NULL);\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_push_this_coercible_to_string(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 1 /*check_object_coercible*/);\n\treturn duk_to_hstring_m1(thr);  /* This will reject all Symbol values; accepts Symbol objects. */\n}\n\nDUK_INTERNAL duk_tval *duk_get_borrowed_this_tval(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->callstack_top > 0);  /* caller required to know */\n\tDUK_ASSERT(thr->callstack_curr != NULL);  /* caller required to know */\n\tDUK_ASSERT(thr->valstack_bottom > thr->valstack);  /* consequence of above */\n\tDUK_ASSERT(thr->valstack_bottom - 1 >= thr->valstack);  /* 'this' binding exists */\n\n\treturn thr->valstack_bottom - 1;\n}\n\nDUK_EXTERNAL void duk_push_new_target(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* https://www.ecma-international.org/ecma-262/6.0/#sec-meta-properties-runtime-semantics-evaluation\n\t * https://www.ecma-international.org/ecma-262/6.0/#sec-getnewtarget\n\t *\n\t * No newTarget support now, so as a first approximation\n\t * use the resolved (non-bound) target function.\n\t *\n\t * Check CONSTRUCT flag from current function, or if running\n\t * direct eval, from a non-direct-eval parent (with possibly\n\t * more than one nested direct eval).  An alternative to this\n\t * would be to store [[NewTarget]] as a hidden symbol of the\n\t * lexical scope, and then just look up that variable.\n\t *\n\t * Calls from the application will either be for an empty\n\t * call stack, or a Duktape/C function as the top activation.\n\t */\n\n\tact = thr->callstack_curr;\n\tfor (;;) {\n\t\tif (act == NULL) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (act->flags & DUK_ACT_FLAG_CONSTRUCT) {\n\t\t\tduk_push_tval(thr, &act->tv_func);\n\t\t\treturn;\n\t\t} else if (act->flags & DUK_ACT_FLAG_DIRECT_EVAL) {\n\t\t\tact = act->parent;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tduk_push_undefined(thr);\n}\n\nDUK_EXTERNAL void duk_push_current_function(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\tduk_push_tval(thr, &act->tv_func);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n}\n\nDUK_EXTERNAL void duk_push_current_thread(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (thr->heap->curr_thread) {\n\t\tduk_push_hobject(thr, (duk_hobject *) thr->heap->curr_thread);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n}\n\nDUK_EXTERNAL void duk_push_global_object(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_hobject_bidx(thr, DUK_BIDX_GLOBAL);\n}\n\n/* XXX: size optimize */\nDUK_LOCAL void duk__push_stash(duk_hthread *thr) {\n\tif (!duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"creating heap/global/thread stash on first use\"));\n\t\tduk_pop_unsafe(thr);\n\t\tduk_push_bare_object(thr);\n\t\tduk_dup_top(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_C);  /* [ ... parent stash stash ] -> [ ... parent stash ] */\n\t}\n\tduk_remove_m2(thr);\n}\n\nDUK_EXTERNAL void duk_push_heap_stash(duk_hthread *thr) {\n\tduk_heap *heap;\n\tDUK_ASSERT_API_ENTRY(thr);\n\theap = thr->heap;\n\tDUK_ASSERT(heap->heap_object != NULL);\n\tduk_push_hobject(thr, heap->heap_object);\n\tduk__push_stash(thr);\n}\n\nDUK_EXTERNAL void duk_push_global_stash(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_push_global_object(thr);\n\tduk__push_stash(thr);\n}\n\nDUK_EXTERNAL void duk_push_thread_stash(duk_hthread *thr, duk_hthread *target_thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tif (DUK_UNLIKELY(target_thr == NULL)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tduk_push_hobject(thr, (duk_hobject *) target_thr);\n\tduk__push_stash(thr);\n}\n\n/* XXX: duk_ssize_t would be useful here */\nDUK_LOCAL duk_int_t duk__try_push_vsprintf(duk_hthread *thr, void *buf, duk_size_t sz, const char *fmt, va_list ap) {\n\tduk_int_t len;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(thr);\n\n\t/* NUL terminator handling doesn't matter here */\n\tlen = DUK_VSNPRINTF((char *) buf, sz, fmt, ap);\n\tif (len < (duk_int_t) sz) {\n\t\t/* Return value of 'sz' or more indicates output was (potentially)\n\t\t * truncated.\n\t\t */\n\t\treturn (duk_int_t) len;\n\t}\n\treturn -1;\n}\n\nDUK_EXTERNAL const char *duk_push_vsprintf(duk_hthread *thr, const char *fmt, va_list ap) {\n\tduk_uint8_t stack_buf[DUK_PUSH_SPRINTF_INITIAL_SIZE];\n\tduk_size_t sz = DUK_PUSH_SPRINTF_INITIAL_SIZE;\n\tduk_bool_t pushed_buf = 0;\n\tvoid *buf;\n\tduk_int_t len;  /* XXX: duk_ssize_t */\n\tconst char *res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* special handling of fmt==NULL */\n\tif (!fmt) {\n\t\tduk_hstring *h_str;\n\t\tduk_push_hstring_empty(thr);\n\t\th_str = duk_known_hstring(thr, -1);\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h_str);\n\t}\n\n\t/* initial estimate based on format string */\n\tsz = DUK_STRLEN(fmt) + 16;  /* format plus something to avoid just missing */\n\tif (sz < DUK_PUSH_SPRINTF_INITIAL_SIZE) {\n\t\tsz = DUK_PUSH_SPRINTF_INITIAL_SIZE;\n\t}\n\tDUK_ASSERT(sz > 0);\n\n\t/* Try to make do with a stack buffer to avoid allocating a temporary buffer.\n\t * This works 99% of the time which is quite nice.\n\t */\n\tfor (;;) {\n\t\tva_list ap_copy;  /* copied so that 'ap' can be reused */\n\n\t\tif (sz <= sizeof(stack_buf)) {\n\t\t\tbuf = stack_buf;\n\t\t} else if (!pushed_buf) {\n\t\t\tpushed_buf = 1;\n\t\t\tbuf = duk_push_dynamic_buffer(thr, sz);\n\t\t} else {\n\t\t\tbuf = duk_resize_buffer(thr, -1, sz);\n\t\t}\n\t\tDUK_ASSERT(buf != NULL);\n\n\t\tDUK_VA_COPY(ap_copy, ap);\n\t\tlen = duk__try_push_vsprintf(thr, buf, sz, fmt, ap_copy);\n\t\tva_end(ap_copy);\n\t\tif (len >= 0) {\n\t\t\tbreak;\n\t\t}\n\n\t\t/* failed, resize and try again */\n\t\tsz = sz * 2;\n\t\tif (DUK_UNLIKELY(sz >= DUK_PUSH_SPRINTF_SANITY_LIMIT)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t}\n\n\t/* Cannot use duk_buffer_to_string() on the buffer because it is\n\t * usually larger than 'len'; 'buf' is also usually a stack buffer.\n\t */\n\tres = duk_push_lstring(thr, (const char *) buf, (duk_size_t) len);  /* [ buf? res ] */\n\tif (pushed_buf) {\n\t\tduk_remove_m2(thr);\n\t}\n\treturn res;\n}\n\nDUK_EXTERNAL const char *duk_push_sprintf(duk_hthread *thr, const char *fmt, ...) {\n\tva_list ap;\n\tconst char *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* allow fmt==NULL */\n\tva_start(ap, fmt);\n\tret = duk_push_vsprintf(thr, fmt, ap);\n\tva_end(ap);\n\n\treturn ret;\n}\n\nDUK_INTERNAL duk_hobject *duk_push_object_helper(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx) {\n\tduk_tval *tv_slot;\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(prototype_bidx == -1 ||\n\t           (prototype_bidx >= 0 && prototype_bidx < DUK_NUM_BUILTINS));\n\n\tDUK__CHECK_SPACE();\n\n\th = duk_hobject_alloc(thr, hobject_flags_and_class);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"created object with flags: 0x%08lx\", (unsigned long) h->hdr.h_flags));\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, h);\n\tDUK_HOBJECT_INCREF(thr, h);  /* no side effects */\n\tthr->valstack_top++;\n\n\t/* object is now reachable */\n\n\tif (prototype_bidx >= 0) {\n\t\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, h, thr->builtins[prototype_bidx]);\n\t} else {\n\t\tDUK_ASSERT(prototype_bidx == -1);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h) == NULL);\n\t}\n\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_push_object_helper_proto(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_hobject *proto) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_push_object_helper(thr, hobject_flags_and_class, -1);\n\tDUK_ASSERT(h != NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, h, proto);\n\treturn h;\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_object(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              DUK_BIDX_OBJECT_PROTOTYPE);\n\treturn duk_get_top_index_unsafe(thr);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_array(duk_hthread *thr) {\n\tduk_uint_t flags;\n\tduk_harray *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_ARRAY_PART |\n\t        DUK_HOBJECT_FLAG_EXOTIC_ARRAY |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAY);\n\n\tobj = duk_harray_alloc(thr, flags);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[DUK_BIDX_ARRAY_PROTOTYPE]);\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);  /* XXX: could preallocate with refcount = 1 */\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\tDUK_ASSERT(obj->length == 0);  /* Array .length starts at zero. */\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_bare_array(duk_hthread *thr) {\n\tduk_uint_t flags;\n\tduk_harray *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_ARRAY_PART |\n\t        DUK_HOBJECT_FLAG_EXOTIC_ARRAY |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAY);\n\n\tobj = duk_harray_alloc(thr, flags);\n\tDUK_ASSERT(obj != NULL);\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);  /* XXX: could preallocate with refcount = 1 */\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\tDUK_ASSERT(obj->length == 0);  /* Array .length starts at zero. */\n\treturn ret;\n}\n\nDUK_INTERNAL duk_harray *duk_push_harray(duk_hthread *thr) {\n\t/* XXX: API call could do this directly, cast to void in API macro. */\n\tduk_harray *a;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_push_array(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(thr->valstack_top - 1));\n\ta = (duk_harray *) DUK_TVAL_GET_OBJECT(thr->valstack_top - 1);\n\tDUK_ASSERT(a != NULL);\n\treturn a;\n}\n\n/* Push a duk_harray with preallocated size (.length also set to match size).\n * Caller may then populate array part of the duk_harray directly.\n */\nDUK_INTERNAL duk_harray *duk_push_harray_with_size(duk_hthread *thr, duk_uint32_t size) {\n\tduk_harray *a;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ta = duk_push_harray(thr);\n\n\tduk_hobject_realloc_props(thr,\n\t                          (duk_hobject *) a,\n\t                          0,\n\t                          size,\n\t                          0,\n\t                          0);\n\ta->length = size;\n\treturn a;\n}\n\nDUK_INTERNAL duk_tval *duk_push_harray_with_size_outptr(duk_hthread *thr, duk_uint32_t size) {\n\tduk_harray *a;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ta = duk_push_harray_with_size(thr, size);\n\tDUK_ASSERT(a != NULL);\n\treturn DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_thread_raw(duk_hthread *thr, duk_uint_t flags) {\n\tduk_hthread *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\tobj = duk_hthread_alloc(thr,\n\t                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_THREAD));\n\tDUK_ASSERT(obj != NULL);\n\tobj->state = DUK_HTHREAD_STATE_INACTIVE;\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* Nothing to initialize, strs[] is in ROM. */\n#else\n#if defined(DUK_USE_HEAPPTR16)\n\tobj->strs16 = thr->strs16;\n#else\n\tobj->strs = thr->strs;\n#endif\n#endif\n\tDUK_DDD(DUK_DDDPRINT(\"created thread object with flags: 0x%08lx\", (unsigned long) obj->obj.hdr.h_flags));\n\n\t/* make the new thread reachable */\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HTHREAD_INCREF(thr, obj);\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\t/* important to do this *after* pushing, to make the thread reachable for gc */\n\tif (DUK_UNLIKELY(!duk_hthread_init_stacks(thr->heap, obj))) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* initialize built-ins - either by copying or creating new ones */\n\tif (flags & DUK_THREAD_NEW_GLOBAL_ENV) {\n\t\tduk_hthread_create_builtin_objects(obj);\n\t} else {\n\t\tduk_hthread_copy_builtin_objects(thr, obj);\n\t}\n\n\t/* default prototype */\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, obj->builtins[DUK_BIDX_THREAD_PROTOTYPE]);\n\n\t/* Initial stack size satisfies the stack slack constraints so there\n\t * is no need to require stack here.\n\t */\n\tDUK_ASSERT(DUK_VALSTACK_INITIAL_SIZE >=\n\t           DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\n\treturn ret;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_push_hcompfunc(duk_hthread *thr) {\n\tduk_hcompfunc *obj;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\t/* Template functions are not strictly constructable (they don't\n\t * have a \"prototype\" property for instance), so leave the\n\t * DUK_HOBJECT_FLAG_CONSRUCTABLE flag cleared here.\n\t */\n\n\tobj = duk_hcompfunc_alloc(thr,\n\t                          DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                          DUK_HOBJECT_FLAG_CALLABLE |\n\t                          DUK_HOBJECT_FLAG_COMPFUNC |\n\t                          DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION));\n\tif (DUK_UNLIKELY(obj == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"created compiled function object with flags: 0x%08lx\", (unsigned long) obj->obj.hdr.h_flags));\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\tthr->valstack_top++;\n\n\t/* default prototype */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) obj) == NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\n\treturn obj;\n}\n\nDUK_INTERNAL duk_hboundfunc *duk_push_hboundfunc(duk_hthread *thr) {\n\tduk_hboundfunc *obj;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\tobj = duk_hboundfunc_alloc(thr->heap,\n\t                           DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                           DUK_HOBJECT_FLAG_BOUNDFUNC |\n\t                           DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t                           DUK_HOBJECT_FLAG_CALLABLE |\n\t                           DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION));\n\tif (!obj) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\n\t/* Prototype is left as NULL because the caller always sets it (and\n\t * it depends on the target function).\n\t */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) obj) == NULL);\n\n\treturn obj;\n}\n\nDUK_LOCAL duk_idx_t duk__push_c_function_raw(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_uint_t flags, duk_small_uint_t proto_bidx) {\n\tduk_hnatfunc *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\tduk_int16_t func_nargs;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tDUK__CHECK_SPACE();\n\n\tif (DUK_UNLIKELY(func == NULL)) {\n\t\tgoto api_error;\n\t}\n\tif (nargs >= 0 && nargs < DUK_HNATFUNC_NARGS_MAX) {\n\t\tfunc_nargs = (duk_int16_t) nargs;\n\t} else if (nargs == DUK_VARARGS) {\n\t\tfunc_nargs = DUK_HNATFUNC_NARGS_VARARGS;\n\t} else {\n\t\tgoto api_error;\n\t}\n\n\tobj = duk_hnatfunc_alloc(thr, flags);\n\tDUK_ASSERT(obj != NULL);\n\n\tobj->func = func;\n\tobj->nargs = func_nargs;\n\n\tDUK_DDD(DUK_DDDPRINT(\"created native function object with flags: 0x%08lx, nargs=%ld\",\n\t                     (unsigned long) obj->obj.hdr.h_flags, (long) obj->nargs));\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\tDUK_ASSERT_BIDX_VALID(proto_bidx);\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[proto_bidx]);\n\treturn ret;\n\n api_error:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_c_function(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\n\t/* Default prototype is a Duktape specific %NativeFunctionPrototype%\n\t * which provides .length and .name getters.\n\t */\n\treturn duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE);\n}\n\nDUK_INTERNAL void duk_push_c_function_builtin(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\n\t/* Must use Function.prototype for standard built-in functions. */\n\t(void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_FUNCTION_PROTOTYPE);\n}\n\nDUK_INTERNAL void duk_push_c_function_builtin_noconstruct(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\n\t/* Must use Function.prototype for standard built-in functions. */\n\t(void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_FUNCTION_PROTOTYPE);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_c_lightfunc(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_idx_t length, duk_int_t magic) {\n\tduk_small_uint_t lf_flags;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\tif (nargs >= DUK_LFUNC_NARGS_MIN && nargs <= DUK_LFUNC_NARGS_MAX) {\n\t\t/* as is */\n\t} else if (nargs == DUK_VARARGS) {\n\t\tnargs = DUK_LFUNC_NARGS_VARARGS;\n\t} else {\n\t\tgoto api_error;\n\t}\n\tif (DUK_UNLIKELY(!(length >= DUK_LFUNC_LENGTH_MIN && length <= DUK_LFUNC_LENGTH_MAX))) {\n\t\tgoto api_error;\n\t}\n\tif (DUK_UNLIKELY(!(magic >= DUK_LFUNC_MAGIC_MIN && magic <= DUK_LFUNC_MAGIC_MAX))) {\n\t\tgoto api_error;\n\t}\n\n\tlf_flags = DUK_LFUNC_FLAGS_PACK((duk_small_int_t) magic, (duk_small_uint_t) length, (duk_small_uint_t) nargs);\n\ttv_slot = thr->valstack_top++;\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_slot));\n\tDUK_TVAL_SET_LIGHTFUNC(tv_slot, func, lf_flags);\n\tDUK_ASSERT(tv_slot >= thr->valstack_bottom);\n\treturn (duk_idx_t) (tv_slot - thr->valstack_bottom);\n\n api_error:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_hbufobj *duk_push_bufobj_raw(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx) {\n\tduk_hbufobj *obj;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(prototype_bidx >= 0);\n\n\tDUK__CHECK_SPACE();\n\n\tobj = duk_hbufobj_alloc(thr, hobject_flags_and_class);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[prototype_bidx]);\n\tDUK_HBUFOBJ_ASSERT_VALID(obj);\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\tthr->valstack_top++;\n\n\treturn obj;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* XXX: There's quite a bit of overlap with buffer creation handling in\n * duk_bi_buffer.c.  Look for overlap and refactor.\n */\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK__PACK_ARGS(classnum,protobidx,elemtype,elemshift,istypedarray) \\\n\t(((classnum) << 24) | ((protobidx) << 16) | ((elemtype) << 8) | ((elemshift) << 4) | (istypedarray))\n\nstatic const duk_uint32_t duk__bufobj_flags_lookup[] = {\n\t/* Node.js Buffers are Uint8Array instances which inherit from Buffer.prototype. */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_ARRAYBUFFER,       DUK_BIDX_ARRAYBUFFER_PROTOTYPE,       DUK_HBUFOBJ_ELEM_UINT8,        0, 0),  /* DUK_BUFOBJ_ARRAYBUFFER */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8ARRAY,        DUK_BIDX_NODEJS_BUFFER_PROTOTYPE,     DUK_HBUFOBJ_ELEM_UINT8,        0, 1),  /* DUK_BUFOBJ_NODEJS_BUFFER */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_DATAVIEW,          DUK_BIDX_DATAVIEW_PROTOTYPE,          DUK_HBUFOBJ_ELEM_UINT8,        0, 0),  /* DUK_BUFOBJ_DATAVIEW */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT8ARRAY,         DUK_BIDX_INT8ARRAY_PROTOTYPE,         DUK_HBUFOBJ_ELEM_INT8,         0, 1),  /* DUK_BUFOBJ_INT8ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8ARRAY,        DUK_BIDX_UINT8ARRAY_PROTOTYPE,        DUK_HBUFOBJ_ELEM_UINT8,        0, 1),  /* DUK_BUFOBJ_UINT8ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY, DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE, DUK_HBUFOBJ_ELEM_UINT8CLAMPED, 0, 1),  /* DUK_BUFOBJ_UINT8CLAMPEDARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT16ARRAY,        DUK_BIDX_INT16ARRAY_PROTOTYPE,        DUK_HBUFOBJ_ELEM_INT16,        1, 1),  /* DUK_BUFOBJ_INT16ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT16ARRAY,       DUK_BIDX_UINT16ARRAY_PROTOTYPE,       DUK_HBUFOBJ_ELEM_UINT16,       1, 1),  /* DUK_BUFOBJ_UINT16ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT32ARRAY,        DUK_BIDX_INT32ARRAY_PROTOTYPE,        DUK_HBUFOBJ_ELEM_INT32,        2, 1),  /* DUK_BUFOBJ_INT32ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT32ARRAY,       DUK_BIDX_UINT32ARRAY_PROTOTYPE,       DUK_HBUFOBJ_ELEM_UINT32,       2, 1),  /* DUK_BUFOBJ_UINT32ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_FLOAT32ARRAY,      DUK_BIDX_FLOAT32ARRAY_PROTOTYPE,      DUK_HBUFOBJ_ELEM_FLOAT32,      2, 1),  /* DUK_BUFOBJ_FLOAT32ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_FLOAT64ARRAY,      DUK_BIDX_FLOAT64ARRAY_PROTOTYPE,      DUK_HBUFOBJ_ELEM_FLOAT64,      3, 1)   /* DUK_BUFOBJ_FLOAT64ARRAY */\n};\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags) {\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_hobject *h_arraybuf;\n\tduk_uint32_t tmp;\n\tduk_uint_t classnum;\n\tduk_uint_t protobidx;\n\tduk_uint_t lookupidx;\n\tduk_uint_t uint_offset, uint_length, uint_added;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* The underlying types for offset/length in duk_hbufobj is\n\t * duk_uint_t; make sure argument values fit.\n\t */\n\tuint_offset = (duk_uint_t) byte_offset;\n\tuint_length = (duk_uint_t) byte_length;\n\tif (sizeof(duk_size_t) != sizeof(duk_uint_t)) {\n\t\tif (DUK_UNLIKELY((duk_size_t) uint_offset != byte_offset || (duk_size_t) uint_length != byte_length)) {\n\t\t\tgoto range_error;\n\t\t}\n\t}\n\n\tDUK_ASSERT_DISABLE(flags >= 0);  /* flags is unsigned */\n\tlookupidx = flags;\n\tif (DUK_UNLIKELY(lookupidx >= sizeof(duk__bufobj_flags_lookup) / sizeof(duk_uint32_t))) {\n\t\tgoto arg_error;\n\t}\n\ttmp = duk__bufobj_flags_lookup[lookupidx];\n\tclassnum = tmp >> 24;\n\tprotobidx = (tmp >> 16) & 0xff;\n\n\th_arraybuf = duk_get_hobject(thr, idx_buffer);\n\tif (h_arraybuf != NULL &&  /* argument is an object */\n\t    flags != DUK_BUFOBJ_ARRAYBUFFER &&  /* creating a view */\n\t    DUK_HOBJECT_GET_CLASS_NUMBER(h_arraybuf) == DUK_HOBJECT_CLASS_ARRAYBUFFER  /* argument is ArrayBuffer */) {\n\t\tduk_uint_t tmp_offset;\n\n\t\tDUK_HBUFOBJ_ASSERT_VALID((duk_hbufobj *) h_arraybuf);\n\t\th_val = ((duk_hbufobj *) h_arraybuf)->buf;\n\t\tif (DUK_UNLIKELY(h_val == NULL)) {\n\t\t\tgoto arg_error;\n\t\t}\n\n\t\ttmp_offset = uint_offset + ((duk_hbufobj *) h_arraybuf)->offset;\n\t\tif (DUK_UNLIKELY(tmp_offset < uint_offset)) {\n\t\t\tgoto range_error;\n\t\t}\n\t\tuint_offset = tmp_offset;\n\n\t\t/* Note intentional difference to new TypedArray(): we allow\n\t\t * caller to create an uncovered typed array (which is memory\n\t\t * safe); new TypedArray() rejects it.\n\t\t */\n\t} else {\n\t\t/* Handle unexpected object arguments here too, for nice error\n\t\t * messages.\n\t\t */\n\t\th_arraybuf = NULL;\n\t\th_val = duk_require_hbuffer(thr, idx_buffer);\n\t}\n\n\t/* Wrap check for offset+length. */\n\tuint_added = uint_offset + uint_length;\n\tif (DUK_UNLIKELY(uint_added < uint_offset)) {\n\t\tgoto range_error;\n\t}\n\tDUK_ASSERT(uint_added >= uint_offset && uint_added >= uint_length);\n\n\tDUK_ASSERT(h_val != NULL);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(classnum),\n\t                               (duk_small_int_t) protobidx);\n\tDUK_ASSERT(h_bufobj != NULL);\n\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\th_bufobj->buf_prop = h_arraybuf;\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, h_arraybuf);\n\th_bufobj->offset = uint_offset;\n\th_bufobj->length = uint_length;\n\th_bufobj->shift = (tmp >> 4) & 0x0f;\n\th_bufobj->elem_type = (tmp >> 8) & 0xff;\n\th_bufobj->is_typedarray = tmp & 0x0f;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t/* TypedArray views need an automatic ArrayBuffer which must be\n\t * provided as .buffer property of the view.  The ArrayBuffer is\n\t * referenced via duk_hbufobj->buf_prop and an inherited .buffer\n\t * accessor returns it.  The ArrayBuffer is created lazily on first\n\t * access if necessary so we don't need to do anything more here.\n\t */\n\treturn;\n\n range_error:\n\tDUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARGS);\n\tDUK_WO_NORETURN(return;);\n\n arg_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_ARGS);\n\tDUK_WO_NORETURN(return;);\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\nDUK_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx_buffer);\n\tDUK_UNREF(byte_offset);\n\tDUK_UNREF(byte_length);\n\tDUK_UNREF(flags);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_EXTERNAL duk_idx_t duk_push_error_object_va_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap) {\n\tduk_hobject *proto;\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tduk_small_uint_t augment_flags;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_UNREF(filename);\n\tDUK_UNREF(line);\n\n\t/* Error code also packs a tracedata related flag. */\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\taugment_flags = 0;\n\tif (err_code & DUK_ERRCODE_FLAG_NOBLAME_FILELINE) {\n\t\taugment_flags = DUK_AUGMENT_FLAG_NOBLAME_FILELINE;\n\t}\n#endif\n\terr_code = err_code & (~DUK_ERRCODE_FLAG_NOBLAME_FILELINE);\n\n\t/* error gets its 'name' from the prototype */\n\tproto = duk_error_prototype_from_code(thr, err_code);\n\t(void) duk_push_object_helper_proto(thr,\n\t                                    DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                    DUK_HOBJECT_FLAG_FASTREFS |\n\t                                    DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ERROR),\n\t                                    proto);\n\n\t/* ... and its 'message' from an instance property */\n\tif (fmt) {\n\t\tduk_push_vsprintf(thr, fmt, ap);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);\n\t} else {\n\t\t/* If no explicit message given, put error code into message field\n\t\t * (as a number).  This is not fully in keeping with the ECMAScript\n\t\t * error model because messages are supposed to be strings (Error\n\t\t * constructors use ToString() on their argument).  However, it's\n\t\t * probably more useful than having a separate 'code' property.\n\t\t */\n\t\tduk_push_int(thr, err_code);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);\n\t}\n\n\t/* XXX: .code = err_code disabled, not sure if useful */\n\n\t/* Creation time error augmentation */\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\t/* filename may be NULL in which case file/line is not recorded */\n\tduk_err_augment_error_create(thr, thr, filename, line, augment_flags);  /* may throw an error */\n#endif\n\n\treturn duk_get_top_index_unsafe(thr);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_error_object_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...) {\n\tva_list ap;\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tva_start(ap, fmt);\n\tret = duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\n#if !defined(DUK_USE_VARIADIC_MACROS)\nDUK_EXTERNAL duk_idx_t duk_push_error_object_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, ...) {\n\tconst char *filename = duk_api_global_filename;\n\tduk_int_t line = duk_api_global_line;\n\tva_list ap;\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_api_global_filename = NULL;\n\tduk_api_global_line = 0;\n\tva_start(ap, fmt);\n\tret = duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\nDUK_EXTERNAL void *duk_push_buffer_raw(duk_hthread *thr, duk_size_t size, duk_small_uint_t flags) {\n\tduk_tval *tv_slot;\n\tduk_hbuffer *h;\n\tvoid *buf_data;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\t/* Check for maximum buffer length. */\n\tif (DUK_UNLIKELY(size > DUK_HBUFFER_MAX_BYTELEN)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_BUFFER_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\th = duk_hbuffer_alloc(thr->heap, size, flags, &buf_data);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_BUFFER(tv_slot, h);\n\tDUK_HBUFFER_INCREF(thr, h);\n\tthr->valstack_top++;\n\n\treturn (void *) buf_data;\n}\n\nDUK_INTERNAL void *duk_push_fixed_buffer_nozero(duk_hthread *thr, duk_size_t len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_push_buffer_raw(thr, len, DUK_BUF_FLAG_NOZERO);\n}\n\nDUK_INTERNAL void *duk_push_fixed_buffer_zero(duk_hthread *thr, duk_size_t len) {\n\tvoid *ptr;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tptr = duk_push_buffer_raw(thr, len, 0);\n\tDUK_ASSERT(ptr != NULL);\n#if !defined(DUK_USE_ZERO_BUFFER_DATA)\n\t/* ES2015 requires zeroing even when DUK_USE_ZERO_BUFFER_DATA\n\t * is not set.\n\t */\n\tduk_memzero((void *) ptr, (size_t) len);\n#endif\n\treturn ptr;\n}\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_EXTERNAL duk_idx_t duk_push_proxy(duk_hthread *thr, duk_uint_t proxy_flags) {\n\tduk_hobject *h_target;\n\tduk_hobject *h_handler;\n\tduk_hproxy *h_proxy;\n\tduk_tval *tv_slot;\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(proxy_flags);\n\n\t/* DUK__CHECK_SPACE() unnecessary because the Proxy is written to\n\t * value stack in-place.\n\t */\n#if 0\n\tDUK__CHECK_SPACE();\n#endif\n\n\t/* Reject a proxy object as the target because it would need\n\t * special handling in property lookups.  (ES2015 has no such\n\t * restriction.)\n\t */\n\th_target = duk_require_hobject_promote_mask(thr, -2, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(h_target != NULL);\n\tif (DUK_HOBJECT_IS_PROXY(h_target)) {\n\t\tgoto fail_args;\n\t}\n\n\t/* Reject a proxy object as the handler because it would cause\n\t * potentially unbounded recursion.  (ES2015 has no such\n\t * restriction.)\n\t *\n\t * There's little practical reason to use a lightfunc or a plain\n\t * buffer as the handler table: one could only provide traps via\n\t * their prototype objects (Function.prototype and ArrayBuffer.prototype).\n\t * Even so, as lightfuncs and plain buffers mimic their object\n\t * counterparts, they're promoted and accepted here.\n\t */\n\th_handler = duk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(h_handler != NULL);\n\tif (DUK_HOBJECT_IS_PROXY(h_handler)) {\n\t\tgoto fail_args;\n\t}\n\n\t/* XXX: Proxy object currently has no prototype, so ToPrimitive()\n\t * coercion fails which is a bit confusing.\n\t */\n\n\t/* CALLABLE and CONSTRUCTABLE flags are copied from the (initial)\n\t * target, see ES2015 Sections 9.5.15 and 9.5.13.\n\t */\n\tflags = DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h_target) &\n\t        (DUK_HOBJECT_FLAG_CALLABLE | DUK_HOBJECT_FLAG_CONSTRUCTABLE);\n\tflags |= DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t         DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ;\n\tif (flags & DUK_HOBJECT_FLAG_CALLABLE) {\n\t\tflags |= DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION) |\n\t\t         DUK_HOBJECT_FLAG_SPECIAL_CALL;\n\t} else {\n\t\tflags |= DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT);\n\t}\n\n\th_proxy = duk_hproxy_alloc(thr, flags);\n\tDUK_ASSERT(h_proxy != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_proxy) == NULL);\n\n\t/* Initialize Proxy target and handler references; avoid INCREF\n\t * by stealing the value stack refcounts via direct value stack\n\t * manipulation.  INCREF is needed for the Proxy itself however.\n\t */\n\tDUK_ASSERT(h_target != NULL);\n\th_proxy->target = h_target;\n\tDUK_ASSERT(h_handler != NULL);\n\th_proxy->handler = h_handler;\n\tDUK_HPROXY_ASSERT_VALID(h_proxy);\n\n\tDUK_ASSERT(duk_get_hobject(thr, -2) == h_target);\n\tDUK_ASSERT(duk_get_hobject(thr, -1) == h_handler);\n\ttv_slot = thr->valstack_top - 2;\n\tDUK_ASSERT(tv_slot >= thr->valstack_bottom);\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) h_proxy);\n\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) h_proxy);\n\ttv_slot++;\n\tDUK_TVAL_SET_UNDEFINED(tv_slot);  /* [ ... target handler ] -> [ ... proxy undefined ] */\n\tthr->valstack_top = tv_slot;      /* -> [ ... proxy ] */\n\n\tDUK_DD(DUK_DDPRINT(\"created Proxy: %!iT\", duk_get_tval(thr, -1)));\n\n\treturn (duk_idx_t) (thr->valstack_top - thr->valstack_bottom - 1);\n\n fail_args:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n#else  /* DUK_USE_ES6_PROXY */\nDUK_EXTERNAL duk_idx_t duk_push_proxy(duk_hthread *thr, duk_uint_t proxy_flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(proxy_flags);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_LOCAL void duk__validate_push_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_heaphdr *h;\n\tduk_heaphdr *curr;\n\tduk_bool_t found = 0;\n\n\th = (duk_heaphdr *) ptr;\n\tif (h == NULL) {\n\t\t/* Allowed. */\n\t\treturn;\n\t}\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\n\t/* One particular problem case is where an object has been\n\t * queued for finalization but the finalizer hasn't yet been\n\t * executed.\n\t *\n\t * Corner case: we're running in a finalizer for object X, and\n\t * user code calls duk_push_heapptr() for X itself.  In this\n\t * case X will be in finalize_list, and we can detect the case\n\t * by seeing that X's FINALIZED flag is set (which is done before\n\t * the finalizer starts executing).\n\t */\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tfor (curr = thr->heap->finalize_list;\n\t     curr != NULL;\n\t     curr = DUK_HEAPHDR_GET_NEXT(thr->heap, curr)) {\n\t\t/* FINALIZABLE is set for all objects on finalize_list\n\t\t * except for an object being finalized right now.  So\n\t\t * can't assert here.\n\t\t */\n#if 0\n\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZABLE(curr));\n#endif\n\n\t\tif (curr == h) {\n\t\t\tif (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) h)) {\n\t\t\t\t/* Object is currently being finalized. */\n\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\tfound = 1;\n\t\t\t} else {\n\t\t\t\t/* Not being finalized but on finalize_list,\n\t\t\t\t * allowed since Duktape 2.1.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\tfound = 1;\n\t\t\t}\n\t\t}\n\t}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* Because refzero_list is now processed to completion inline with\n\t * no side effects, it's always empty here.\n\t */\n\tDUK_ASSERT(thr->heap->refzero_list == NULL);\n#endif\n\n\t/* If not present in finalize_list (or refzero_list), it\n\t * must be either in heap_allocated or the string table.\n\t */\n\tif (DUK_HEAPHDR_IS_STRING(h)) {\n\t\tduk_uint32_t i;\n\t\tduk_hstring *str;\n\t\tduk_heap *heap = thr->heap;\n\n\t\tDUK_ASSERT(found == 0);\n\t\tfor (i = 0; i < heap->st_size; i++) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\t\tstr = DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, heap->strtable16[i]);\n#else\n\t\t\tstr = heap->strtable[i];\n#endif\n\t\t\twhile (str != NULL) {\n\t\t\t\tif (str == (duk_hstring *) h) {\n\t\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\t\tfound = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tstr = str->hdr.h_next;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(found != 0);\n\t} else {\n\t\tfor (curr = thr->heap->heap_allocated;\n\t\t     curr != NULL;\n\t\t     curr = DUK_HEAPHDR_GET_NEXT(thr->heap, curr)) {\n\t\t\tif (curr == h) {\n\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\tfound = 1;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(found != 0);\n\t}\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\nDUK_EXTERNAL duk_idx_t duk_push_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_idx_t ret;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Reviving an object using a heap pointer is a dangerous API\n\t * operation: if the application doesn't guarantee that the\n\t * pointer target is always reachable, difficult-to-diagnose\n\t * problems may ensue.  Try to validate the 'ptr' argument to\n\t * the extent possible.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__validate_push_heapptr(thr, ptr);\n#endif\n\n\tDUK__CHECK_SPACE();\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\ttv = thr->valstack_top++;\n\n\tif (ptr == NULL) {\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\treturn ret;\n\t}\n\n\tDUK_HEAPHDR_ASSERT_VALID((duk_heaphdr *) ptr);\n\n\t/* If the argument is on finalize_list it has technically been\n\t * unreachable before duk_push_heapptr() but it's still safe to\n\t * push it.  Starting from Duktape 2.1 allow application code to\n\t * do so.  There are two main cases:\n\t *\n\t *   (1) The object is on the finalize_list and we're called by\n\t *       the finalizer for the object being finalized.  In this\n\t *       case do nothing: finalize_list handling will deal with\n\t *       the object queueing.  This is detected by the object not\n\t *       having a FINALIZABLE flag despite being on the finalize_list;\n\t *       the flag is cleared for the object being finalized only.\n\t *\n\t *   (2) The object is on the finalize_list but is not currently\n\t *       being processed.  In this case the object can be queued\n\t *       back to heap_allocated with a few flags cleared, in effect\n\t *       cancelling the finalizer.\n\t */\n\tif (DUK_UNLIKELY(DUK_HEAPHDR_HAS_FINALIZABLE((duk_heaphdr *) ptr))) {\n\t\tduk_heaphdr *curr;\n\n\t\tDUK_D(DUK_DPRINT(\"duk_push_heapptr() with a pointer on finalize_list, autorescue\"));\n\n\t\tcurr = (duk_heaphdr *) ptr;\n\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\n\t\t/* Because FINALIZED is set prior to finalizer call, it will\n\t\t * be set for the object being currently finalized, but not\n\t\t * for other objects on finalize_list.\n\t\t */\n\t\tDUK_HEAPHDR_CLEAR_FINALIZED(curr);\n\n\t\t/* Dequeue object from finalize_list and queue it back to\n\t\t * heap_allocated.\n\t\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) >= 1);  /* Preincremented on finalize_list insert. */\n\t\tDUK_HEAPHDR_PREDEC_REFCOUNT(curr);\n#endif\n\t\tDUK_HEAP_REMOVE_FROM_FINALIZE_LIST(thr->heap, curr);\n\t\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(thr->heap, curr);\n\n\t\t/* Continue with the rest. */\n\t}\n\n\tswitch (DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) ptr)) {\n\tcase DUK_HTYPE_STRING:\n\t\tDUK_TVAL_SET_STRING(tv, (duk_hstring *) ptr);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tDUK_TVAL_SET_OBJECT(tv, (duk_hobject *) ptr);\n\t\tbreak;\n\tdefault:\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) ptr) == DUK_HTYPE_BUFFER);\n\t\tDUK_TVAL_SET_BUFFER(tv, (duk_hbuffer *) ptr);\n\t\tbreak;\n\t}\n\n\tDUK_HEAPHDR_INCREF(thr, (duk_heaphdr *) ptr);\n\n\treturn ret;\n}\n\n/* Push object with no prototype, i.e. a \"bare\" object. */\nDUK_EXTERNAL duk_idx_t duk_push_bare_object(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              -1);  /* no prototype */\n\treturn duk_get_top_index_unsafe(thr);\n}\n\nDUK_INTERNAL void duk_push_hstring(duk_hthread *thr, duk_hstring *h) {\n\tduk_tval tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_TVAL_SET_STRING(&tv, h);\n\tduk_push_tval(thr, &tv);\n}\n\nDUK_INTERNAL void duk_push_hstring_stridx(duk_hthread *thr, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n}\n\nDUK_INTERNAL void duk_push_hstring_empty(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, DUK_STRIDX_EMPTY_STRING));\n}\n\nDUK_INTERNAL void duk_push_hobject(duk_hthread *thr, duk_hobject *h) {\n\tduk_tval tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_TVAL_SET_OBJECT(&tv, h);\n\tduk_push_tval(thr, &tv);\n}\n\nDUK_INTERNAL void duk_push_hbuffer(duk_hthread *thr, duk_hbuffer *h) {\n\tduk_tval tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_TVAL_SET_BUFFER(&tv, h);\n\tduk_push_tval(thr, &tv);\n}\n\nDUK_INTERNAL void duk_push_hobject_bidx(duk_hthread *thr, duk_small_int_t builtin_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(builtin_idx >= 0 && builtin_idx < DUK_NUM_BUILTINS);\n\tDUK_ASSERT(thr->builtins[builtin_idx] != NULL);\n\n\tduk_push_hobject(thr, thr->builtins[builtin_idx]);\n}\n\n/*\n *  Poppers\n */\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_n_unsafe_raw(duk_hthread *thr, duk_idx_t count) {\n\tduk_tval *tv;\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_tval *tv_end;\n#endif\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) count);\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\ttv = thr->valstack_top;\n\ttv_end = tv - count;\n\twhile (tv != tv_end) {\n\t\ttv--;\n\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t}\n\tthr->valstack_top = tv;\n\tDUK_REFZERO_CHECK_FAST(thr);\n#else\n\ttv = thr->valstack_top;\n\twhile (count > 0) {\n\t\tcount--;\n\t\ttv--;\n\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t}\n\tthr->valstack_top = tv;\n#endif\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n\nDUK_EXTERNAL void duk_pop_n(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\n\tif (DUK_UNLIKELY((duk_uidx_t) (thr->valstack_top - thr->valstack_bottom) < (duk_uidx_t) count)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(count >= 0);\n\n\tduk__pop_n_unsafe_raw(thr, count);\n}\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, count);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk__pop_n_unsafe_raw(thr, count);\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/* Pop N elements without DECREF (in effect \"stealing\" any actual refcounts). */\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) count);\n\n\ttv = thr->valstack_top;\n\twhile (count > 0) {\n\t\tcount--;\n\t\ttv--;\n\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t}\n\tthr->valstack_top = tv;\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#else  /* DUK_USE_REFERENCE_COUNTING */\nDUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, count);\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/* Popping one element is called so often that when footprint is not an issue,\n * compile a specialized function for it.\n */\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL void duk_pop(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, 1);\n}\nDUK_INTERNAL void duk_pop_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, 1);\n}\nDUK_INTERNAL void duk_pop_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_nodecref_unsafe(thr, 1);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_unsafe_raw(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);\n\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n#else\n\tDUK_TVAL_SET_UNDEFINED(tv);\n#endif\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\nDUK_EXTERNAL void duk_pop(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tif (DUK_UNLIKELY(thr->valstack_top == thr->valstack_bottom)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk__pop_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk__pop_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_nodecref_unsafe(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);\n\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\tDUK_TVAL_SET_UNDEFINED(tv);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_pop_undefined(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_nodecref_unsafe(thr);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_pop_undefined(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);\n\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));\n\tthr->valstack_top--;\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL void duk_pop_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, 2);\n}\nDUK_INTERNAL void duk_pop_2_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, 2);\n}\nDUK_INTERNAL void duk_pop_2_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_nodecref_unsafe(thr, 2);\n}\n#else\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_2_unsafe_raw(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 2);\n\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n#else\n\tDUK_TVAL_SET_UNDEFINED(tv);\n#endif\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n#else\n\tDUK_TVAL_SET_UNDEFINED(tv);\n#endif\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\nDUK_EXTERNAL void duk_pop_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tif (DUK_UNLIKELY(thr->valstack_top - 2 < thr->valstack_bottom)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk__pop_2_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_2_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk__pop_2_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_2_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 2);\n\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 2));\n\tthr->valstack_top -= 2;\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\nDUK_EXTERNAL void duk_pop_3(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, 3);\n}\n\nDUK_INTERNAL void duk_pop_3_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, 3);\n}\n\nDUK_INTERNAL void duk_pop_3_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_nodecref_unsafe(thr, 3);\n}\n\n/*\n *  Pack and unpack (pack value stack entries into an array and vice versa)\n */\n\n/* XXX: pack index range? array index offset? */\n/* XXX: need ability to pack into a bare array? */\nDUK_INTERNAL void duk_pack(duk_hthread *thr, duk_idx_t count) {\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_tval *tv_curr;\n\tduk_tval *tv_limit;\n\tduk_idx_t top;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\ttop = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT(top >= 0);\n\tif (DUK_UNLIKELY((duk_uidx_t) count > (duk_uidx_t) top)) {\n\t\t/* Also handles negative count. */\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(count >= 0);\n\n\t/* Wrapping is controlled by the check above: value stack top can be\n\t * at most DUK_USE_VALSTACK_LIMIT which is low enough so that\n\t * multiplying with sizeof(duk_tval) won't wrap.\n\t */\n\tDUK_ASSERT(count >= 0 && count <= (duk_idx_t) DUK_USE_VALSTACK_LIMIT);\n\tDUK_ASSERT((duk_size_t) count <= DUK_SIZE_MAX / sizeof(duk_tval));  /* no wrapping */\n\n\ttv_dst = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) count);  /* XXX: uninitialized would be OK */\n\tDUK_ASSERT(count == 0 || tv_dst != NULL);\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\t/* Copy value stack values directly to the array part without\n\t * any refcount updates: net refcount changes are zero.\n\t */\n\ttv_src = thr->valstack_top - count - 1;\n\tduk_memcpy_unsafe((void *) tv_dst, (const void *) tv_src, (size_t) count * sizeof(duk_tval));\n\n\t/* Overwrite result array to final value stack location and wipe\n\t * the rest; no refcount operations needed.\n\t */\n\n\ttv_dst = tv_src;  /* when count == 0, same as tv_src (OK) */\n\ttv_src = thr->valstack_top - 1;\n\tDUK_TVAL_SET_TVAL(tv_dst, tv_src);\n\n\t/* XXX: internal helper to wipe a value stack segment? */\n\ttv_curr = tv_dst + 1;\n\ttv_limit = thr->valstack_top;\n\twhile (tv_curr != tv_limit) {\n\t\t/* Wipe policy: keep as 'undefined'. */\n\t\tDUK_TVAL_SET_UNDEFINED(tv_curr);\n\t\ttv_curr++;\n\t}\n\tthr->valstack_top = tv_dst + 1;\n}\n\nDUK_INTERNAL duk_idx_t duk_unpack_array_like(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tif (DUK_LIKELY(DUK_TVAL_IS_OBJECT(tv))) {\n\t\tduk_hobject *h;\n\t\tduk_uint32_t len;\n\t\tduk_uint32_t i;\n\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_UNREF(h);\n\n#if defined(DUK_USE_ARRAY_FASTPATH)  /* close enough */\n\t\tif (DUK_LIKELY(DUK_HOBJECT_IS_ARRAY(h) &&\n\t\t               ((duk_harray *) h)->length <= DUK_HOBJECT_GET_ASIZE(h))) {\n\t\t\tduk_harray *h_arr;\n\t\t\tduk_tval *tv_src;\n\t\t\tduk_tval *tv_dst;\n\n\t\t\th_arr = (duk_harray *) h;\n\t\t\tlen = h_arr->length;\n\t\t\tif (DUK_UNLIKELY(len >= 0x80000000UL)) {\n\t\t\t\tgoto fail_over_2g;\n\t\t\t}\n\t\t\tduk_require_stack(thr, (duk_idx_t) len);\n\n\t\t\t/* The potential allocation in duk_require_stack() may\n\t\t\t * run a finalizer which modifies the argArray so that\n\t\t\t * e.g. becomes sparse.  So, we need to recheck that the\n\t\t\t * array didn't change size and that there's still a\n\t\t\t * valid backing array part.\n\t\t\t *\n\t\t\t * XXX: alternatively, could prevent finalizers for the\n\t\t\t * duration.\n\t\t\t */\n\t\t\tif (DUK_UNLIKELY(len != h_arr->length ||\n\t\t\t                 h_arr->length > DUK_HOBJECT_GET_ASIZE((duk_hobject *) h_arr))) {\n\t\t\t\tgoto skip_fast;\n\t\t\t}\n\n\t\t\t/* Main fast path: arguments array is almost always\n\t\t\t * an actual array (though it might also be an arguments\n\t\t\t * object).\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path for %ld elements\", (long) h_arr->length));\n\t\t\ttv_src = DUK_HOBJECT_A_GET_BASE(thr->heap, h);\n\t\t\ttv_dst = thr->valstack_top;\n\t\t\twhile (len-- > 0) {\n\t\t\t\tDUK_ASSERT(tv_dst < thr->valstack_end);\n\t\t\t\tif (DUK_UNLIKELY(DUK_TVAL_IS_UNUSED(tv_src))) {\n\t\t\t\t\t/* Gaps are very unlikely.  Skip over them,\n\t\t\t\t\t * without an ancestor lookup (technically\n\t\t\t\t\t * not compliant).\n\t\t\t\t\t */\n\t\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_dst));  /* valstack policy */\n\t\t\t\t} else {\n\t\t\t\t\tDUK_TVAL_SET_TVAL(tv_dst, tv_src);\n\t\t\t\t\tDUK_TVAL_INCREF(thr, tv_dst);\n\t\t\t\t}\n\t\t\t\ttv_src++;\n\t\t\t\ttv_dst++;\n\t\t\t}\n\t\t\tDUK_ASSERT(tv_dst <= thr->valstack_end);\n\t\t\tthr->valstack_top = tv_dst;\n\t\t\treturn (duk_idx_t) h_arr->length;\n\t\t}\n\t skip_fast:\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\n\t\t/* Slow path: actual lookups.  The initial 'length' lookup\n\t\t * decides the output length, regardless of side effects that\n\t\t * may resize or change the argArray while we read the\n\t\t * indices.\n\t\t */\n\t\tidx = duk_normalize_index(thr, idx);\n\t\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n\t\tlen = duk_to_uint32(thr, -1);  /* ToUint32() coercion required */\n\t\tif (DUK_UNLIKELY(len >= 0x80000000UL)) {\n\t\t\tgoto fail_over_2g;\n\t\t}\n\t\tduk_pop_unsafe(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"slow path for %ld elements\", (long) len));\n\n\t\tduk_require_stack(thr, (duk_idx_t) len);\n\t\tfor (i = 0; i < len; i++) {\n\t\t\tduk_get_prop_index(thr, idx, (duk_uarridx_t) i);\n\t\t}\n\t\treturn (duk_idx_t) len;\n\t} else if (DUK_TVAL_IS_UNDEFINED(tv) || DUK_TVAL_IS_NULL(tv)) {\n\t\treturn 0;\n\t}\n\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n\n fail_over_2g:\n\tDUK_ERROR_RANGE_INVALID_LENGTH(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/*\n *  Error throwing\n */\n\nDUK_EXTERNAL void duk_throw_raw(duk_hthread *thr) {\n\tduk_tval *tv_val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\n\tif (DUK_UNLIKELY(thr->valstack_top == thr->valstack_bottom)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* Errors are augmented when they are created, not when they are\n\t * thrown or re-thrown.  The current error handler, however, runs\n\t * just before an error is thrown.\n\t */\n\n\t/* Sync so that augmentation sees up-to-date activations, NULL\n\t * thr->ptr_curr_pc so that it's not used if side effects occur\n\t * in augmentation or longjmp handling.\n\t */\n\tduk_hthread_sync_and_null_currpc(thr);\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (API): %!dT (before throw augment)\", (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_err_augment_error_throw(thr);\n#endif\n\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (API): %!dT (after throw augment)\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\ttv_val = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, tv_val);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_err_check_debugger_integration(thr);\n#endif\n\n\t/* thr->heap->lj.jmpbuf_ptr is checked by duk_err_longjmp() so we don't\n\t * need to check that here.  If the value is NULL, a fatal error occurs\n\t * because we can't return.\n\t */\n\n\tduk_err_longjmp(thr);\n\tDUK_UNREACHABLE();\n}\n\nDUK_EXTERNAL void duk_fatal_raw(duk_hthread *thr, const char *err_msg) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->heap->fatal_func != NULL);\n\n\tDUK_D(DUK_DPRINT(\"fatal error occurred: %s\", err_msg ? err_msg : \"NULL\"));\n\n\t/* fatal_func should be noreturn, but noreturn declarations on function\n\t * pointers has a very spotty support apparently so it's not currently\n\t * done.\n\t */\n\tthr->heap->fatal_func(thr->heap->heap_udata, err_msg);\n\n\t/* If the fatal handler returns, all bets are off.  It'd be nice to\n\t * print something here but since we don't want to depend on stdio,\n\t * there's no way to do so portably.\n\t */\n\tDUK_D(DUK_DPRINT(\"fatal error handler returned, all bets are off!\"));\n\tfor (;;) {\n\t\t/* loop forever, don't return (function marked noreturn) */\n\t}\n}\n\nDUK_EXTERNAL void duk_error_va_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\t(void) duk_throw(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_error_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...) {\n\tva_list ap;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tva_start(ap, fmt);\n\tduk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\tva_end(ap);\n\t(void) duk_throw(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n#if !defined(DUK_USE_VARIADIC_MACROS)\nDUK_NORETURN(DUK_LOCAL_DECL void duk__throw_error_from_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, va_list ap));\n\nDUK_LOCAL void duk__throw_error_from_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, va_list ap) {\n\tconst char *filename;\n\tduk_int_t line;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tfilename = duk_api_global_filename;\n\tline = duk_api_global_line;\n\tduk_api_global_filename = NULL;\n\tduk_api_global_line = 0;\n\n\tduk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\t(void) duk_throw(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n#define DUK__ERROR_STASH_SHARED(code) do { \\\n\t\tva_list ap; \\\n\t\tva_start(ap, fmt); \\\n\t\tduk__throw_error_from_stash(thr, (code), fmt, ap); \\\n\t\tva_end(ap); \\\n\t\tDUK_WO_NORETURN(return 0;); \\\n\t} while (0)\n\nDUK_EXTERNAL duk_ret_t duk_error_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(err_code);\n}\nDUK_EXTERNAL duk_ret_t duk_generic_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_eval_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_EVAL_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_range_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_RANGE_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_reference_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_REFERENCE_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_syntax_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_SYNTAX_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_type_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_TYPE_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_uri_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_URI_ERROR);\n}\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n/*\n *  Comparison\n */\n\nDUK_EXTERNAL duk_bool_t duk_equals(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_get_tval(thr, idx1);\n\ttv2 = duk_get_tval(thr, idx2);\n\tif ((tv1 == NULL) || (tv2 == NULL)) {\n\t\treturn 0;\n\t}\n\n\t/* Coercion may be needed, the helper handles that by pushing the\n\t * tagged values to the stack.\n\t */\n\treturn duk_js_equals(thr, tv1, tv2);\n}\n\nDUK_EXTERNAL duk_bool_t duk_strict_equals(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_get_tval(thr, idx1);\n\ttv2 = duk_get_tval(thr, idx2);\n\tif ((tv1 == NULL) || (tv2 == NULL)) {\n\t\treturn 0;\n\t}\n\n\t/* No coercions or other side effects, so safe */\n\treturn duk_js_strict_equals(tv1, tv2);\n}\n\nDUK_EXTERNAL duk_bool_t duk_samevalue(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_get_tval(thr, idx1);\n\ttv2 = duk_get_tval(thr, idx2);\n\tif ((tv1 == NULL) || (tv2 == NULL)) {\n\t\treturn 0;\n\t}\n\n\t/* No coercions or other side effects, so safe */\n\treturn duk_js_samevalue(tv1, tv2);\n}\n\n/*\n *  instanceof\n */\n\nDUK_EXTERNAL duk_bool_t duk_instanceof(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Index validation is strict, which differs from duk_equals().\n\t * The strict behavior mimics how instanceof itself works, e.g.\n\t * it is a TypeError if rval is not a -callable- object.  It would\n\t * be somewhat inconsistent if rval would be allowed to be\n\t * non-existent without a TypeError.\n\t */\n\ttv1 = duk_require_tval(thr, idx1);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, idx2);\n\tDUK_ASSERT(tv2 != NULL);\n\n\treturn duk_js_instanceof(thr, tv1, tv2);\n}\n\n/*\n *  Lightfunc\n */\n\nDUK_INTERNAL void duk_push_lightfunc_name_raw(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags) {\n\t/* Lightfunc name, includes Duktape/C native function pointer, which\n\t * can often be used to locate the function from a symbol table.\n\t * The name also includes the 16-bit duk_tval flags field because it\n\t * includes the magic value.  Because a single native function often\n\t * provides different functionality depending on the magic value, it\n\t * seems reasonably to include it in the name.\n\t *\n\t * On the other hand, a complicated name increases string table\n\t * pressure in low memory environments (but only when function name\n\t * is accessed).\n\t */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_literal(thr, \"light_\");\n\tduk_push_string_funcptr(thr, (duk_uint8_t *) &func, sizeof(func));\n\tduk_push_sprintf(thr, \"_%04x\", (unsigned int) lf_flags);\n\tduk_concat(thr, 3);\n}\n\nDUK_INTERNAL void duk_push_lightfunc_name(duk_hthread *thr, duk_tval *tv) {\n\tduk_c_function func;\n\tduk_small_uint_t lf_flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv));\n\n\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);\n\tduk_push_lightfunc_name_raw(thr, func, lf_flags);\n}\n\nDUK_INTERNAL void duk_push_lightfunc_tostring(duk_hthread *thr, duk_tval *tv) {\n\tduk_c_function func;\n\tduk_small_uint_t lf_flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv));\n\n\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);  /* read before 'tv' potentially invalidated */\n\tduk_push_literal(thr, \"function \");\n\tduk_push_lightfunc_name_raw(thr, func, lf_flags);\n\tduk_push_literal(thr, \"() { [lightfunc code] }\");\n\tduk_concat(thr, 3);\n}\n\n/*\n *  Function pointers\n *\n *  Printing function pointers is non-portable, so we do that by hex printing\n *  bytes from memory.\n */\n\nDUK_INTERNAL void duk_push_string_funcptr(duk_hthread *thr, duk_uint8_t *ptr, duk_size_t sz) {\n\tduk_uint8_t buf[32 * 2];\n\tduk_uint8_t *p, *q;\n\tduk_small_uint_t i;\n\tduk_small_uint_t t;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(sz <= 32);  /* sanity limit for function pointer size */\n\n\tp = buf;\n#if defined(DUK_USE_INTEGER_LE)\n\tq = ptr + sz;\n#else\n\tq = ptr;\n#endif\n\tfor (i = 0; i < sz; i++) {\n#if defined(DUK_USE_INTEGER_LE)\n\t\tt = *(--q);\n#else\n\t\tt = *(q++);\n#endif\n\t\t*p++ = duk_lc_digits[t >> 4];\n\t\t*p++ = duk_lc_digits[t & 0x0f];\n\t}\n\n\tduk_push_lstring(thr, (const char *) buf, sz * 2);\n}\n\n/*\n *  Push readable string summarizing duk_tval.  The operation is side effect\n *  free and will only throw from internal errors (e.g. out of memory).\n *  This is used by e.g. property access code to summarize a key/base safely,\n *  and is not intended to be fast (but small and safe).\n */\n\n/* String limits for summary strings. */\n#define DUK__READABLE_SUMMARY_MAXCHARS 96  /* maximum supported by helper */\n#define DUK__READABLE_STRING_MAXCHARS  32  /* for strings/symbols */\n#define DUK__READABLE_ERRMSG_MAXCHARS  96  /* for error messages */\n\n/* String sanitizer which escapes ASCII control characters and a few other\n * ASCII characters, passes Unicode as is, and replaces invalid UTF-8 with\n * question marks.  No errors are thrown for any input string, except in out\n * of memory situations.\n */\nDUK_LOCAL void duk__push_hstring_readable_unicode(duk_hthread *thr, duk_hstring *h_input, duk_small_uint_t maxchars) {\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_uint8_t buf[DUK_UNICODE_MAX_XUTF8_LENGTH * DUK__READABLE_SUMMARY_MAXCHARS +\n\t                2 /*quotes*/ + 3 /*periods*/];\n\tduk_uint8_t *q;\n\tduk_ucodepoint_t cp;\n\tduk_small_uint_t nchars;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(h_input != NULL);\n\tDUK_ASSERT(maxchars <= DUK__READABLE_SUMMARY_MAXCHARS);\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\tq = buf;\n\n\tnchars = 0;\n\t*q++ = (duk_uint8_t) DUK_ASC_SINGLEQUOTE;\n\tfor (;;) {\n\t\tif (p >= p_end) {\n\t\t\tbreak;\n\t\t}\n\t\tif (nchars == maxchars) {\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_PERIOD;\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_PERIOD;\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_PERIOD;\n\t\t\tbreak;\n\t\t}\n\t\tif (duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp)) {\n\t\t\tif (cp < 0x20 || cp == 0x7f || cp == DUK_ASC_SINGLEQUOTE || cp == DUK_ASC_BACKSLASH) {\n\t\t\t\tDUK_ASSERT(DUK_UNICODE_MAX_XUTF8_LENGTH >= 4);  /* estimate is valid */\n\t\t\t\tDUK_ASSERT((cp >> 4) <= 0x0f);\n\t\t\t\t*q++ = (duk_uint8_t) DUK_ASC_BACKSLASH;\n\t\t\t\t*q++ = (duk_uint8_t) DUK_ASC_LC_X;\n\t\t\t\t*q++ = (duk_uint8_t) duk_lc_digits[cp >> 4];\n\t\t\t\t*q++ = (duk_uint8_t) duk_lc_digits[cp & 0x0f];\n\t\t\t} else {\n\t\t\t\tq += duk_unicode_encode_xutf8(cp, q);\n\t\t\t}\n\t\t} else {\n\t\t\tp++;  /* advance manually */\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_QUESTION;\n\t\t}\n\t\tnchars++;\n\t}\n\t*q++ = (duk_uint8_t) DUK_ASC_SINGLEQUOTE;\n\n\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) (q - buf));\n}\n\nDUK_LOCAL const char *duk__push_string_tval_readable(duk_hthread *thr, duk_tval *tv, duk_bool_t error_aware) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\t/* 'tv' may be NULL */\n\n\tif (tv == NULL) {\n\t\tduk_push_literal(thr, \"none\");\n\t} else {\n\t\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\t\tcase DUK_TAG_STRING: {\n\t\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\t\tif (DUK_HSTRING_HAS_SYMBOL(h)) {\n\t\t\t\t/* XXX: string summary produces question marks\n\t\t\t\t * so this is not very ideal.\n\t\t\t\t */\n\t\t\t\tduk_push_literal(thr, \"[Symbol \");\n\t\t\t\tduk_push_string(thr, duk__get_symbol_type_string(h));\n\t\t\t\tduk_push_literal(thr, \" \");\n\t\t\t\tduk__push_hstring_readable_unicode(thr, h, DUK__READABLE_STRING_MAXCHARS);\n\t\t\t\tduk_push_literal(thr, \"]\");\n\t\t\t\tduk_concat(thr, 5);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tduk__push_hstring_readable_unicode(thr, h, DUK__READABLE_STRING_MAXCHARS);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_OBJECT: {\n\t\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\t\tDUK_ASSERT(h != NULL);\n\n\t\t\tif (error_aware &&\n\t\t\t    duk_hobject_prototype_chain_contains(thr, h, thr->builtins[DUK_BIDX_ERROR_PROTOTYPE], 1 /*ignore_loop*/)) {\n\t\t\t\t/* Get error message in a side effect free way if\n\t\t\t\t * possible; if not, summarize as a generic object.\n\t\t\t\t * Error message currently gets quoted.\n\t\t\t\t */\n\t\t\t\t/* XXX: better internal getprop call; get without side effects\n\t\t\t\t * but traverse inheritance chain.\n\t\t\t\t */\n\t\t\t\tduk_tval *tv_msg;\n\t\t\t\ttv_msg = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, h, DUK_STRIDX_MESSAGE);\n\t\t\t\tif (tv_msg != NULL && DUK_TVAL_IS_STRING(tv_msg)) {\n\t\t\t\t\t/* It's critical to avoid recursion so\n\t\t\t\t\t * only summarize a string .message.\n\t\t\t\t\t */\n\t\t\t\t\tduk__push_hstring_readable_unicode(thr, DUK_TVAL_GET_STRING(tv_msg), DUK__READABLE_ERRMSG_MAXCHARS);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tduk_push_class_string_tval(thr, tv, 1 /*avoid_side_effects*/);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_BUFFER: {\n\t\t\t/* While plain buffers mimic Uint8Arrays, they summarize differently.\n\t\t\t * This is useful so that the summarized string accurately reflects the\n\t\t\t * internal type which may matter for figuring out bugs etc.\n\t\t\t */\n\t\t\t/* XXX: Hex encoded, length limited buffer summary here? */\n\t\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\t\tDUK_ASSERT(h != NULL);\n\t\t\tduk_push_sprintf(thr, \"[buffer:%ld]\", (long) DUK_HBUFFER_GET_SIZE(h));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_POINTER: {\n\t\t\t/* Surround with parentheses like in JX, ensures NULL pointer\n\t\t\t * is distinguishable from null value (\"(null)\" vs \"null\").\n\t\t\t */\n\t\t\tduk_push_tval(thr, tv);\n\t\t\tduk_push_sprintf(thr, \"(%s)\", duk_to_string(thr, -1));\n\t\t\tduk_remove_m2(thr);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tduk_push_tval(thr, tv);\n\t\t\tbreak;\n\t\t}\n\t\t}\n\t}\n\n\treturn duk_to_string(thr, -1);\n}\nDUK_INTERNAL const char *duk_push_string_tval_readable(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__push_string_tval_readable(thr, tv, 0 /*error_aware*/);\n}\n\nDUK_INTERNAL const char *duk_push_string_readable(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_push_string_tval_readable(thr, duk_get_tval(thr, idx));\n}\n\nDUK_INTERNAL const char *duk_push_string_tval_readable_error(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__push_string_tval_readable(thr, tv, 1 /*error_aware*/);\n}\n\nDUK_INTERNAL void duk_push_symbol_descriptive_string(duk_hthread *thr, duk_hstring *h) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint8_t *q;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* .toString() */\n\tduk_push_literal(thr, \"Symbol(\");\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tp_end = p + DUK_HSTRING_GET_BYTELEN(h);\n\tDUK_ASSERT(p[0] == 0xff || (p[0] & 0xc0) == 0x80);\n\tp++;\n\tfor (q = p; q < p_end; q++) {\n\t\tif (*q == 0xffU) {\n\t\t\t/* Terminate either at end-of-string (but NUL MUST\n\t\t\t * be accepted without terminating description) or\n\t\t\t * 0xFF, which is used to mark start of unique trailer\n\t\t\t * (and cannot occur in CESU-8 / extended UTF-8).\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\t}\n\tduk_push_lstring(thr, (const char *) p, (duk_size_t) (q - p));\n\tduk_push_literal(thr, \")\");\n\tduk_concat(thr, 3);\n}\n\n/*\n *  Functions\n */\n\n#if 0  /* not used yet */\nDUK_INTERNAL void duk_push_hnatfunc_name(duk_hthread *thr, duk_hnatfunc *h) {\n\tduk_c_function func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h));\n\n\tduk_push_sprintf(thr, \"native_\");\n\tfunc = h->func;\n\tduk_push_string_funcptr(thr, (duk_uint8_t *) &func, sizeof(func));\n\tduk_push_sprintf(thr, \"_%04x_%04x\",\n\t                 (unsigned int) (duk_uint16_t) h->nargs,\n\t                 (unsigned int) (duk_uint16_t) h->magic);\n\tduk_concat(thr, 3);\n}\n#endif\n\n/*\n *  duk_tval slice copy\n */\n\nDUK_INTERNAL void duk_copy_tvals_incref(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_size_t count) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n\tDUK_ASSERT(count * sizeof(duk_tval) >= count);  /* no wrap */\n\n\tduk_memcpy_unsafe((void *) tv_dst, (const void *) tv_src, count * sizeof(duk_tval));\n\n\ttv = tv_dst;\n\twhile (count-- > 0) {\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\ttv++;\n\t}\n}\n\n/* automatic undefs */\n#undef DUK__ASSERT_SPACE\n#undef DUK__CHECK_SPACE\n#undef DUK__ERROR_STASH_SHARED\n#undef DUK__PACK_ARGS\n#undef DUK__READABLE_ERRMSG_MAXCHARS\n#undef DUK__READABLE_STRING_MAXCHARS\n#undef DUK__READABLE_SUMMARY_MAXCHARS\n/*\n *  String manipulation\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_LOCAL void duk__concat_and_join_helper(duk_hthread *thr, duk_idx_t count_in, duk_bool_t is_join) {\n\tduk_uint_t count;\n\tduk_uint_t i;\n\tduk_size_t idx;\n\tduk_size_t len;\n\tduk_hstring *h;\n\tduk_uint8_t *buf;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tif (DUK_UNLIKELY(count_in <= 0)) {\n\t\tif (count_in < 0) {\n\t\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tDUK_ASSERT(count_in == 0);\n\t\tduk_push_hstring_empty(thr);\n\t\treturn;\n\t}\n\tcount = (duk_uint_t) count_in;\n\n\tif (is_join) {\n\t\tduk_size_t t1, t2, limit;\n\t\th = duk_to_hstring(thr, -((duk_idx_t) count) - 1);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* A bit tricky overflow test, see doc/code-issues.rst. */\n\t\tt1 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);\n\t\tt2 = (duk_size_t) (count - 1);\n\t\tlimit = (duk_size_t) DUK_HSTRING_MAX_BYTELEN;\n\t\tif (DUK_UNLIKELY(t2 != 0 && t1 > limit / t2)) {\n\t\t\t/* Combined size of separators already overflows. */\n\t\t\tgoto error_overflow;\n\t\t}\n\t\tlen = (duk_size_t) (t1 * t2);\n\t} else {\n\t\tlen = (duk_size_t) 0;\n\t}\n\n\tfor (i = count; i >= 1; i--) {\n\t\tduk_size_t new_len;\n\t\th = duk_to_hstring(thr, -((duk_idx_t) i));\n\t\tnew_len = len + (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);\n\n\t\t/* Impose a string maximum length, need to handle overflow\n\t\t * correctly.\n\t\t */\n\t\tif (new_len < len ||  /* wrapped */\n\t\t    new_len > (duk_size_t) DUK_HSTRING_MAX_BYTELEN) {\n\t\t\tgoto error_overflow;\n\t\t}\n\t\tlen = new_len;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"join/concat %lu strings, total length %lu bytes\",\n\t                     (unsigned long) count, (unsigned long) len));\n\n\t/* Use stack allocated buffer to ensure reachability in errors\n\t * (e.g. intern error).\n\t */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len);\n\tDUK_ASSERT(buf != NULL);\n\n\t/* [ ... (sep) str1 str2 ... strN buf ] */\n\n\tidx = 0;\n\tfor (i = count; i >= 1; i--) {\n\t\tif (is_join && i != count) {\n\t\t\th = duk_require_hstring(thr, -((duk_idx_t) count) - 2);  /* extra -1 for buffer */\n\t\t\tduk_memcpy(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\t\t\tidx += DUK_HSTRING_GET_BYTELEN(h);\n\t\t}\n\t\th = duk_require_hstring(thr, -((duk_idx_t) i) - 1);  /* extra -1 for buffer */\n\t\tduk_memcpy(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\t\tidx += DUK_HSTRING_GET_BYTELEN(h);\n\t}\n\n\tDUK_ASSERT(idx == len);\n\n\t/* [ ... (sep) str1 str2 ... strN buf ] */\n\n\t/* Get rid of the strings early to minimize memory use before intern. */\n\n\tif (is_join) {\n\t\tduk_replace(thr, -((duk_idx_t) count) - 2);  /* overwrite sep */\n\t\tduk_pop_n(thr, (duk_idx_t) count);\n\t} else {\n\t\tduk_replace(thr, -((duk_idx_t) count) - 1);  /* overwrite str1 */\n\t\tduk_pop_n(thr, (duk_idx_t) (count - 1));\n\t}\n\n\t/* [ ... buf ] */\n\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if inputs are safe. */\n\n\t/* [ ... res ] */\n\treturn;\n\n error_overflow:\n\tDUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_concat(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__concat_and_join_helper(thr, count, 0 /*is_join*/);\n}\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_concat_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_concat(thr, 2);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_concat_2(duk_hthread *thr) {\n\tduk_hstring *h1;\n\tduk_hstring *h2;\n\tduk_uint8_t *buf;\n\tduk_size_t len1;\n\tduk_size_t len2;\n\tduk_size_t len;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_top(thr) >= 2);  /* Trusted caller. */\n\n\th1 = duk_to_hstring(thr, -2);\n\th2 = duk_to_hstring(thr, -1);\n\tlen1 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1);\n\tlen2 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2);\n\tlen = len1 + len2;\n\tif (DUK_UNLIKELY(len < len1 ||  /* wrapped */\n\t                 len > (duk_size_t) DUK_HSTRING_MAX_BYTELEN)) {\n\t\tgoto error_overflow;\n\t}\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len);\n\tDUK_ASSERT(buf != NULL);\n\n\tduk_memcpy((void *) buf, (const void *) DUK_HSTRING_GET_DATA(h1), (size_t) len1);\n\tduk_memcpy((void *) (buf + len1), (const void *) DUK_HSTRING_GET_DATA(h2), (size_t) len2);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if inputs are safe. */\n\n\t/* [ ... str1 str2 buf ] */\n\n\tduk_replace(thr, -3);\n\tduk_pop_unsafe(thr);\n\treturn;\n\n error_overflow:\n\tDUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\nDUK_EXTERNAL void duk_join(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__concat_and_join_helper(thr, count, 1 /*is_join*/);\n}\n\n/* XXX: could map/decode be unified with duk_unicode_support.c code?\n * Case conversion needs also the character surroundings though.\n */\n\nDUK_EXTERNAL void duk_decode_string(duk_hthread *thr, duk_idx_t idx, duk_decode_char_function callback, void *udata) {\n\tduk_hstring *h_input;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th_input = duk_require_hstring(thr, idx);  /* Accept symbols. */\n\tDUK_ASSERT(h_input != NULL);\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\n\tfor (;;) {\n\t\tif (p >= p_end) {\n\t\t\tbreak;\n\t\t}\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end);\n\t\tcallback(udata, cp);\n\t}\n}\n\nDUK_EXTERNAL void duk_map_string(duk_hthread *thr, duk_idx_t idx, duk_map_char_function callback, void *udata) {\n\tduk_hstring *h_input;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_normalize_index(thr, idx);\n\n\th_input = duk_require_hstring(thr, idx);  /* Accept symbols. */\n\tDUK_ASSERT(h_input != NULL);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input));  /* Reasonable output estimate. */\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\n\tfor (;;) {\n\t\t/* XXX: could write output in chunks with fewer ensure calls,\n\t\t * but relative benefit would be small here.\n\t\t */\n\n\t\tif (p >= p_end) {\n\t\t\tbreak;\n\t\t}\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end);\n\t\tcp = callback(udata, cp);\n\n\t\tDUK_BW_WRITE_ENSURE_XUTF8(thr, bw, cp);\n\t}\n\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe, extended UTF-8 encoded. */\n\tduk_replace(thr, idx);\n}\n\nDUK_EXTERNAL void duk_substring(duk_hthread *thr, duk_idx_t idx, duk_size_t start_offset, duk_size_t end_offset) {\n\tduk_hstring *h;\n\tduk_hstring *res;\n\tduk_size_t start_byte_offset;\n\tduk_size_t end_byte_offset;\n\tduk_size_t charlen;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);  /* Accept symbols. */\n\th = duk_require_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tcharlen = DUK_HSTRING_GET_CHARLEN(h);\n\tif (end_offset >= charlen) {\n\t\tend_offset = charlen;\n\t}\n\tif (start_offset > end_offset) {\n\t\tstart_offset = end_offset;\n\t}\n\n\tDUK_ASSERT_DISABLE(start_offset >= 0);\n\tDUK_ASSERT(start_offset <= end_offset && start_offset <= DUK_HSTRING_GET_CHARLEN(h));\n\tDUK_ASSERT_DISABLE(end_offset >= 0);\n\tDUK_ASSERT(end_offset >= start_offset && end_offset <= DUK_HSTRING_GET_CHARLEN(h));\n\n\t/* Guaranteed by string limits. */\n\tDUK_ASSERT(start_offset <= DUK_UINT32_MAX);\n\tDUK_ASSERT(end_offset <= DUK_UINT32_MAX);\n\n\tstart_byte_offset = (duk_size_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) start_offset);\n\tend_byte_offset = (duk_size_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) end_offset);\n\n\tDUK_ASSERT(end_byte_offset >= start_byte_offset);\n\tDUK_ASSERT(end_byte_offset - start_byte_offset <= DUK_UINT32_MAX);  /* Guaranteed by string limits. */\n\n\t/* No size check is necessary. */\n\tres = duk_heap_strtable_intern_checked(thr,\n\t                                       DUK_HSTRING_GET_DATA(h) + start_byte_offset,\n\t                                       (duk_uint32_t) (end_byte_offset - start_byte_offset));\n\n\tduk_push_hstring(thr, res);\n\tduk_replace(thr, idx);\n}\n\n/* XXX: this is quite clunky.  Add Unicode helpers to scan backwards and\n * forwards with a callback to process codepoints?\n */\nDUK_EXTERNAL void duk_trim(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p, *p_start, *p_end, *p_tmp1, *p_tmp2;  /* pointers for scanning */\n\tconst duk_uint8_t *q_start, *q_end;  /* start (incl) and end (excl) of trimmed part */\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);  /* Accept symbols. */\n\th = duk_require_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tp_start = DUK_HSTRING_GET_DATA(h);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h);\n\n\tp = p_start;\n\twhile (p < p_end) {\n\t\tp_tmp1 = p;\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p_tmp1, p_start, p_end);\n\t\tif (!(duk_unicode_is_whitespace(cp) || duk_unicode_is_line_terminator(cp))) {\n\t\t\tbreak;\n\t\t}\n\t\tp = p_tmp1;\n\t}\n\tq_start = p;\n\tif (p == p_end) {\n\t\t/* Entire string is whitespace. */\n\t\tq_end = p;\n\t\tgoto scan_done;\n\t}\n\n\tp = p_end;\n\twhile (p > p_start) {\n\t\tp_tmp1 = p;\n\t\twhile (p > p_start) {\n\t\t\tp--;\n\t\t\tif (((*p) & 0xc0) != 0x80) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tp_tmp2 = p;\n\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p_tmp2, p_start, p_end);\n\t\tif (!(duk_unicode_is_whitespace(cp) || duk_unicode_is_line_terminator(cp))) {\n\t\t\tp = p_tmp1;\n\t\t\tbreak;\n\t\t}\n\t}\n\tq_end = p;\n\n scan_done:\n\t/* This may happen when forward and backward scanning disagree\n\t * (possible for non-extended-UTF-8 strings).\n\t */\n\tif (q_end < q_start) {\n\t\tq_end = q_start;\n\t}\n\n\tDUK_ASSERT(q_start >= p_start && q_start <= p_end);\n\tDUK_ASSERT(q_end >= p_start && q_end <= p_end);\n\tDUK_ASSERT(q_end >= q_start);\n\n\tDUK_DDD(DUK_DDDPRINT(\"trim: p_start=%p, p_end=%p, q_start=%p, q_end=%p\",\n\t                     (const void *) p_start, (const void *) p_end,\n\t                     (const void *) q_start, (const void *) q_end));\n\n\tif (q_start == p_start && q_end == p_end) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"nothing was trimmed: avoid interning (hashing etc)\"));\n\t\treturn;\n\t}\n\n\tduk_push_lstring(thr, (const char *) q_start, (duk_size_t) (q_end - q_start));\n\tduk_replace(thr, idx);\n}\n\nDUK_EXTERNAL duk_codepoint_t duk_char_code_at(duk_hthread *thr, duk_idx_t idx, duk_size_t char_offset) {\n\tduk_hstring *h;\n\tduk_ucodepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: Share code with String.prototype.charCodeAt?  Main difference\n\t * is handling of clamped offsets.\n\t */\n\n\th = duk_require_hstring(thr, idx);  /* Accept symbols. */\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_ASSERT_DISABLE(char_offset >= 0);  /* Always true, arg is unsigned. */\n\tif (char_offset >= DUK_HSTRING_GET_CHARLEN(h)) {\n\t\treturn 0;\n\t}\n\n\tDUK_ASSERT(char_offset <= DUK_UINT_MAX);  /* Guaranteed by string limits. */\n\tcp = duk_hstring_char_code_at_raw(thr, h, (duk_uint_t) char_offset, 0 /*surrogate_aware*/);\n\treturn (duk_codepoint_t) cp;\n}\n/*\n *  Date/time.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL duk_double_t duk_time_get_ecmascript_time(duk_hthread *thr) {\n\t/* ECMAScript time, with millisecond fractions.  Exposed via\n\t * duk_get_now() for example.\n\t */\n\tDUK_UNREF(thr);\n\treturn (duk_double_t) DUK_USE_DATE_GET_NOW(thr);\n}\n\nDUK_INTERNAL duk_double_t duk_time_get_ecmascript_time_nofrac(duk_hthread *thr) {\n\t/* ECMAScript time without millisecond fractions.  Exposed via\n\t * the Date built-in which doesn't allow fractions.\n\t */\n\tDUK_UNREF(thr);\n\treturn (duk_double_t) DUK_FLOOR(DUK_USE_DATE_GET_NOW(thr));\n}\n\nDUK_INTERNAL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr) {\n\tDUK_UNREF(thr);\n#if defined(DUK_USE_GET_MONOTONIC_TIME)\n\treturn (duk_double_t) DUK_USE_GET_MONOTONIC_TIME(thr);\n#else\n\treturn (duk_double_t) DUK_USE_DATE_GET_NOW(thr);\n#endif\n}\n\nDUK_EXTERNAL duk_double_t duk_get_now(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n\n\t/* This API intentionally allows millisecond fractions. */\n\treturn duk_time_get_ecmascript_time(thr);\n}\n\n#if 0  /* XXX: worth exposing? */\nDUK_EXTERNAL duk_double_t duk_get_monotonic_time(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n\n\treturn duk_time_get_monotonic_time(thr);\n}\n#endif\n\nDUK_EXTERNAL void duk_time_to_components(duk_hthread *thr, duk_double_t timeval, duk_time_components *comp) {\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(comp != NULL);  /* XXX: or check? */\n\tDUK_UNREF(thr);\n\n\t/* Convert as one-based, but change month to zero-based to match the\n\t * ECMAScript Date built-in behavior 1:1.\n\t */\n\tflags = DUK_DATE_FLAG_ONEBASED | DUK_DATE_FLAG_NAN_TO_ZERO;\n\n\tduk_bi_date_timeval_to_parts(timeval, parts, dparts, flags);\n\n\t/* XXX: sub-millisecond accuracy for the API */\n\n\tDUK_ASSERT(dparts[DUK_DATE_IDX_MONTH] >= 1.0 && dparts[DUK_DATE_IDX_MONTH] <= 12.0);\n\tcomp->year = dparts[DUK_DATE_IDX_YEAR];\n\tcomp->month = dparts[DUK_DATE_IDX_MONTH] - 1.0;\n\tcomp->day = dparts[DUK_DATE_IDX_DAY];\n\tcomp->hours = dparts[DUK_DATE_IDX_HOUR];\n\tcomp->minutes = dparts[DUK_DATE_IDX_MINUTE];\n\tcomp->seconds = dparts[DUK_DATE_IDX_SECOND];\n\tcomp->milliseconds = dparts[DUK_DATE_IDX_MILLISECOND];\n\tcomp->weekday = dparts[DUK_DATE_IDX_WEEKDAY];\n}\n\nDUK_EXTERNAL duk_double_t duk_components_to_time(duk_hthread *thr, duk_time_components *comp) {\n\tduk_double_t d;\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(comp != NULL);  /* XXX: or check? */\n\tDUK_UNREF(thr);\n\n\t/* Match Date constructor behavior (with UTC time).  Month is given\n\t * as zero-based.  Day-of-month is given as one-based so normalize\n\t * it to zero-based as the internal conversion helpers expects all\n\t * components to be zero-based.\n\t */\n\tflags = 0;\n\n\t/* XXX: expensive conversion; use array format in API instead, or unify\n\t * time provider and time API to use same struct?\n\t */\n\n\tdparts[DUK_DATE_IDX_YEAR] = comp->year;\n\tdparts[DUK_DATE_IDX_MONTH] = comp->month;\n\tdparts[DUK_DATE_IDX_DAY] = comp->day - 1.0;\n\tdparts[DUK_DATE_IDX_HOUR] = comp->hours;\n\tdparts[DUK_DATE_IDX_MINUTE] = comp->minutes;\n\tdparts[DUK_DATE_IDX_SECOND] = comp->seconds;\n\tdparts[DUK_DATE_IDX_MILLISECOND] = comp->milliseconds;\n\tdparts[DUK_DATE_IDX_WEEKDAY] = 0;  /* ignored */\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, flags);\n\n\treturn d;\n}\n/*\n *  Array built-ins\n *\n *  Most Array built-ins are intentionally generic in ECMAScript, and are\n *  intended to work even when the 'this' binding is not an Array instance.\n *  This ECMAScript feature is also used by much real world code.  For this\n *  reason the implementations here don't assume exotic Array behavior or\n *  e.g. presence of a .length property.  However, some algorithms have a\n *  fast path for duk_harray backed actual Array instances, enabled when\n *  footprint is not a concern.\n *\n *  XXX: the \"Throw\" flag should be set for (almost?) all [[Put]] and\n *  [[Delete]] operations, but it's currently false throughout.  Go through\n *  all put/delete cases and check throw flag use.  Need a new API primitive\n *  which allows throws flag to be specified.\n *\n *  XXX: array lengths above 2G won't work reliably.  There are many places\n *  where one needs a full signed 32-bit range ([-0xffffffff, 0xffffffff],\n *  i.e. -33- bits).  Although array 'length' cannot be written to be outside\n *  the unsigned 32-bit range (E5.1 Section 15.4.5.1 throws a RangeError if so)\n *  some intermediate values may be above 0xffffffff and this may not be always\n *  correctly handled now (duk_uint32_t is not enough for all algorithms).\n *  For instance, push() can legitimately write entries beyond length 0xffffffff\n *  and cause a RangeError only at the end.  To do this properly, the current\n *  push() implementation tracks the array index using a 'double' instead of a\n *  duk_uint32_t (which is somewhat awkward).  See test-bi-array-push-maxlen.js.\n *\n *  On using \"put\" vs. \"def\" prop\n *  =============================\n *\n *  Code below must be careful to use the appropriate primitive as it matters\n *  for compliance.  When using \"put\" there may be inherited properties in\n *  Array.prototype which cause side effects when values are written.  When\n *  using \"define\" there are no such side effects, and many test262 test cases\n *  check for this (for real world code, such side effects are very rare).\n *  Both \"put\" and \"define\" are used in the E5.1 specification; as a rule,\n *  \"put\" is used when modifying an existing array (or a non-array 'this'\n *  binding) and \"define\" for setting values into a fresh result array.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Perform an intermediate join when this many elements have been pushed\n * on the value stack.\n */\n#define  DUK__ARRAY_MID_JOIN_LIMIT  4096\n\n#if defined(DUK_USE_ARRAY_BUILTIN)\n\n/*\n *  Shared helpers.\n */\n\n/* Shared entry code for many Array built-ins: the 'this' binding is pushed\n * on the value stack and object coerced, and the current .length is returned.\n * Note that length is left on stack (it could be popped, but that's not\n * usually necessary because call handling will clean it up automatically).\n */\nDUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32(duk_hthread *thr) {\n\tduk_uint32_t len;\n\n\t/* XXX: push more directly? */\n\t(void) duk_push_this_coercible_to_object(thr);\n\tDUK_HOBJECT_ASSERT_VALID(duk_get_hobject(thr, -1));\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_LENGTH);\n\tlen = duk_to_uint32(thr, -1);\n\n\t/* -> [ ... ToObject(this) ToUint32(length) ] */\n\treturn len;\n}\n\nDUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32_limited(duk_hthread *thr) {\n\t/* Range limited to [0, 0x7fffffff] range, i.e. range that can be\n\t * represented with duk_int32_t.  Use this when the method doesn't\n\t * handle the full 32-bit unsigned range correctly.\n\t */\n\tduk_uint32_t ret = duk__push_this_obj_len_u32(thr);\n\tif (DUK_UNLIKELY(ret >= 0x80000000UL)) {\n\t\tDUK_ERROR_RANGE_INVALID_LENGTH(thr);\n\t\tDUK_WO_NORETURN(return 0U;);\n\t}\n\treturn ret;\n}\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\n/* Check if 'this' binding is an Array instance (duk_harray) which satisfies\n * a few other guarantees for fast path operation.  The fast path doesn't\n * need to handle all operations, even for duk_harrays, but must handle a\n * significant fraction to improve performance.  Return a non-NULL duk_harray\n * pointer when all fast path criteria are met, NULL otherwise.\n */\nDUK_LOCAL duk_harray *duk__arraypart_fastpath_this(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\tduk_uint_t flags_mask, flags_bits, flags_value;\n\n\tDUK_ASSERT(thr->valstack_bottom > thr->valstack);  /* because call in progress */\n\ttv = DUK_GET_THIS_TVAL_PTR(thr);\n\n\t/* Fast path requires that 'this' is a duk_harray.  Read only arrays\n\t * (ROM backed) are also rejected for simplicity.\n\t */\n\tif (!DUK_TVAL_IS_OBJECT(tv)) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject array fast path: not an object\"));\n\t\treturn NULL;\n\t}\n\th = DUK_TVAL_GET_OBJECT(tv);\n\tDUK_ASSERT(h != NULL);\n\tflags_mask = DUK_HOBJECT_FLAG_ARRAY_PART | \\\n\t             DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \\\n\t             DUK_HEAPHDR_FLAG_READONLY;\n\tflags_bits = DUK_HOBJECT_FLAG_ARRAY_PART | \\\n\t             DUK_HOBJECT_FLAG_EXOTIC_ARRAY;\n\tflags_value = DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) h);\n\tif ((flags_value & flags_mask) != flags_bits) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject array fast path: object flag check failed\"));\n\t\treturn NULL;\n\t}\n\n\t/* In some cases a duk_harray's 'length' may be larger than the\n\t * current array part allocation.  Avoid the fast path in these\n\t * cases, so that all fast path code can safely assume that all\n\t * items in the range [0,length[ are backed by the current array\n\t * part allocation.\n\t */\n\tif (((duk_harray *) h)->length > DUK_HOBJECT_GET_ASIZE(h)) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject array fast path: length > array part size\"));\n\t\treturn NULL;\n\t}\n\n\t/* Guarantees for fast path. */\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0 || DUK_HOBJECT_A_GET_BASE(thr->heap, h) != NULL);\n\tDUK_ASSERT(((duk_harray *) h)->length <= DUK_HOBJECT_GET_ASIZE(h));\n\n\tDUK_DD(DUK_DDPRINT(\"array fast path allowed for: %!O\", (duk_heaphdr *) h));\n\treturn (duk_harray *) h;\n}\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_constructor(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_harray *a;\n\tduk_double_t d;\n\tduk_uint32_t len;\n\tduk_uint32_t len_prealloc;\n\n\tnargs = duk_get_top(thr);\n\n\tif (nargs == 1 && duk_is_number(thr, 0)) {\n\t\t/* XXX: expensive check (also shared elsewhere - so add a shared internal API call?) */\n\t\td = duk_get_number(thr, 0);\n\t\tlen = duk_to_uint32(thr, 0);\n\t\tif (((duk_double_t) len) != d) {\n\t\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t\t}\n\n\t\t/* For small lengths create a dense preallocated array.\n\t\t * For large arrays preallocate an initial part.\n\t\t */\n\t\tlen_prealloc = len < 64 ? len : 64;\n\t\ta = duk_push_harray_with_size(thr, len_prealloc);\n\t\tDUK_ASSERT(a != NULL);\n\t\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\t\ta->length = len;\n\t\treturn 1;\n\t}\n\n\tduk_pack(thr, nargs);\n\treturn 1;\n}\n\n/*\n *  isArray()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_constructor_is_array(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\th = duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_ARRAY);\n\tduk_push_boolean(thr, (h != NULL));\n\treturn 1;\n}\n\n/*\n *  toString()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_to_string(duk_hthread *thr) {\n\t(void) duk_push_this_coercible_to_object(thr);\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_JOIN);\n\n\t/* [ ... this func ] */\n\tif (!duk_is_callable(thr, -1)) {\n\t\t/* Fall back to the initial (original) Object.toString().  We don't\n\t\t * currently have pointers to the built-in functions, only the top\n\t\t * level global objects (like \"Array\") so this is now done in a bit\n\t\t * of a hacky manner.  It would be cleaner to push the (original)\n\t\t * function and use duk_call_method().\n\t\t */\n\n\t\t/* XXX: 'this' will be ToObject() coerced twice, which is incorrect\n\t\t * but should have no visible side effects.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"this.join is not callable, fall back to (original) Object.toString\"));\n\t\tduk_set_top(thr, 0);\n\t\treturn duk_bi_object_prototype_to_string(thr);  /* has access to 'this' binding */\n\t}\n\n\t/* [ ... this func ] */\n\n\tduk_insert(thr, -2);\n\n\t/* [ ... func this ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"calling: func=%!iT, this=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_call_method(thr, 0);\n\n\treturn 1;\n}\n\n/*\n *  concat()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_concat(duk_hthread *thr) {\n\tduk_idx_t i, n;\n\tduk_uint32_t j, idx, len;\n\tduk_hobject *h;\n\tduk_size_t tmp_len;\n\n\t/* XXX: In ES2015 Array .length can be up to 2^53-1.  The current\n\t * implementation is limited to 2^32-1.\n\t */\n\n\t/* XXX: Fast path for array 'this' and array element. */\n\n\t/* XXX: The insert here is a bit expensive if there are a lot of items.\n\t * It could also be special cased in the outermost for loop quite easily\n\t * (as the element is dup()'d anyway).\n\t */\n\n\t(void) duk_push_this_coercible_to_object(thr);\n\tduk_insert(thr, 0);\n\tn = duk_get_top(thr);\n\tduk_push_array(thr);  /* -> [ ToObject(this) item1 ... itemN arr ] */\n\n\t/* NOTE: The Array special behaviors are NOT invoked by duk_xdef_prop_index()\n\t * (which differs from the official algorithm).  If no error is thrown, this\n\t * doesn't matter as the length is updated at the end.  However, if an error\n\t * is thrown, the length will be unset.  That shouldn't matter because the\n\t * caller won't get a reference to the intermediate value.\n\t */\n\n\tidx = 0;\n\tfor (i = 0; i < n; i++) {\n\t\tduk_bool_t spreadable;\n\t\tduk_bool_t need_has_check;\n\n\t\tDUK_ASSERT_TOP(thr, n + 1);\n\n\t\t/* [ ToObject(this) item1 ... itemN arr ] */\n\n\t\th = duk_get_hobject(thr, i);\n\n\t\tif (h == NULL) {\n\t\t\tspreadable = 0;\n\t\t} else {\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t\t\tduk_get_prop_stridx(thr, i, DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE);\n\t\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\t\tspreadable = (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY);\n\t\t\t} else {\n\t\t\t\tspreadable = duk_to_boolean(thr, -1);\n\t\t\t}\n\t\t\tduk_pop_nodecref_unsafe(thr);\n#else\n\t\t\tspreadable = (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY);\n#endif\n\t\t}\n\n\t\tif (!spreadable) {\n\t\t\tduk_dup(thr, i);\n\t\t\tduk_xdef_prop_index_wec(thr, -2, idx);\n\t\t\tidx++;\n\t\t\tif (DUK_UNLIKELY(idx == 0U)) {\n\t\t\t\t/* Index after update is 0, and index written\n\t\t\t\t * was 0xffffffffUL which is no longer a valid\n\t\t\t\t * array index.\n\t\t\t\t */\n\t\t\t\tgoto fail_wrap;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_ASSERT(duk_is_object(thr, i));\n\t\tneed_has_check = (DUK_HOBJECT_IS_PROXY(h) != 0);  /* Always 0 w/o Proxy support. */\n\n\t\t/* [ ToObject(this) item1 ... itemN arr ] */\n\n\t\ttmp_len = duk_get_length(thr, i);\n\t\tlen = (duk_uint32_t) tmp_len;\n\t\tif (DUK_UNLIKELY(tmp_len != (duk_size_t) len)) {\n\t\t\tgoto fail_wrap;\n\t\t}\n\t\tif (DUK_UNLIKELY(idx + len < idx)) {\n\t\t\t/* Result length must be at most 0xffffffffUL to be\n\t\t\t * a valid 32-bit array index.\n\t\t\t */\n\t\t\tgoto fail_wrap;\n\t\t}\n\t\tfor (j = 0; j < len; j++) {\n\t\t\t/* For a Proxy element, an explicit 'has' check is\n\t\t\t * needed to allow the Proxy to present gaps.\n\t\t\t */\n\t\t\tif (need_has_check) {\n\t\t\t\tif (duk_has_prop_index(thr, i, j)) {\n\t\t\t\t\tduk_get_prop_index(thr, i, j);\n\t\t\t\t\tduk_xdef_prop_index_wec(thr, -2, idx);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (duk_get_prop_index(thr, i, j)) {\n\t\t\t\t\tduk_xdef_prop_index_wec(thr, -2, idx);\n\t\t\t\t} else {\n\t\t\t\t\tduk_pop_undefined(thr);\n\t\t\t\t}\n\t\t\t}\n\t\t\tidx++;\n\t\t\tDUK_ASSERT(idx != 0U);  /* Wrap check above. */\n\t\t}\n\t}\n\n\t/* ES5.1 has a specification \"bug\" in that nonexistent trailing\n\t * elements don't affect the result .length.  Test262 and other\n\t * engines disagree, and the specification bug was fixed in ES2015\n\t * (see NOTE 1 in https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.concat).\n\t */\n\tduk_push_uarridx(thr, idx);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\n\tDUK_ASSERT_TOP(thr, n + 1);\n\treturn 1;\n\n fail_wrap:\n\tDUK_ERROR_RANGE_INVALID_LENGTH(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/*\n *  join(), toLocaleString()\n *\n *  Note: checking valstack is necessary, but only in the per-element loop.\n *\n *  Note: the trivial approach of pushing all the elements on the value stack\n *  and then calling duk_join() fails when the array contains a large number\n *  of elements.  This problem can't be offloaded to duk_join() because the\n *  elements to join must be handled here and have special handling.  Current\n *  approach is to do intermediate joins with very large number of elements.\n *  There is no fancy handling; the prefix gets re-joined multiple times.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_join_shared(duk_hthread *thr) {\n\tduk_uint32_t len, count;\n\tduk_uint32_t idx;\n\tduk_small_int_t to_locale_string = duk_get_current_magic(thr);\n\tduk_idx_t valstack_required;\n\n\t/* For join(), nargs is 1.  For toLocaleString(), nargs is 0 and\n\t * setting the top essentially pushes an undefined to the stack,\n\t * thus defaulting to a comma separator.\n\t */\n\tduk_set_top(thr, 1);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tduk_pop_undefined(thr);\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_COMMA);\n\t} else {\n\t\tduk_to_string(thr, 0);\n\t}\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\n\t/* [ sep ToObject(this) len ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"sep=%!T, this=%!T, len=%lu\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1),\n\t                     (unsigned long) len));\n\n\t/* The extra (+4) is tight. */\n\tvalstack_required = (duk_idx_t) ((len >= DUK__ARRAY_MID_JOIN_LIMIT ?\n\t                                  DUK__ARRAY_MID_JOIN_LIMIT : len) + 4);\n\tduk_require_stack(thr, valstack_required);\n\n\tduk_dup_0(thr);\n\n\t/* [ sep ToObject(this) len sep ] */\n\n\tcount = 0;\n\tidx = 0;\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"join idx=%ld\", (long) idx));\n\t\tif (count >= DUK__ARRAY_MID_JOIN_LIMIT ||   /* intermediate join to avoid valstack overflow */\n\t\t    idx >= len) { /* end of loop (careful with len==0) */\n\t\t\t/* [ sep ToObject(this) len sep str0 ... str(count-1) ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"mid/final join, count=%ld, idx=%ld, len=%ld\",\n\t\t\t                     (long) count, (long) idx, (long) len));\n\t\t\tduk_join(thr, (duk_idx_t) count);  /* -> [ sep ToObject(this) len str ] */\n\t\t\tduk_dup_0(thr);                    /* -> [ sep ToObject(this) len str sep ] */\n\t\t\tduk_insert(thr, -2);               /* -> [ sep ToObject(this) len sep str ] */\n\t\t\tcount = 1;\n\t\t}\n\t\tif (idx >= len) {\n\t\t\t/* if true, the stack already contains the final result */\n\t\t\tbreak;\n\t\t}\n\n\t\tduk_get_prop_index(thr, 1, (duk_uarridx_t) idx);\n\t\tif (duk_is_null_or_undefined(thr, -1)) {\n\t\t\tduk_pop_nodecref_unsafe(thr);\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tif (to_locale_string) {\n\t\t\t\tduk_to_object(thr, -1);\n\t\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_LOCALE_STRING);\n\t\t\t\tduk_insert(thr, -2);  /* -> [ ... toLocaleString ToObject(val) ] */\n\t\t\t\tduk_call_method(thr, 0);\n\t\t\t}\n\t\t\tduk_to_string(thr, -1);\n\t\t}\n\n\t\tcount++;\n\t\tidx++;\n\t}\n\n\t/* [ sep ToObject(this) len sep result ] */\n\n\treturn 1;\n}\n\n/*\n *  pop(), push()\n */\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\nDUK_LOCAL duk_ret_t duk__array_pop_fastpath(duk_hthread *thr, duk_harray *h_arr) {\n\tduk_tval *tv_arraypart;\n\tduk_tval *tv_val;\n\tduk_uint32_t len;\n\n\ttv_arraypart = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) h_arr);\n\tlen = h_arr->length;\n\tif (len <= 0) {\n\t\t/* nop, return undefined */\n\t\treturn 0;\n\t}\n\n\tlen--;\n\th_arr->length = len;\n\n\t/* Fast path doesn't check for an index property inherited from\n\t * Array.prototype.  This is quite often acceptable; if not,\n\t * disable fast path.\n\t */\n\tDUK_ASSERT_VS_SPACE(thr);\n\ttv_val = tv_arraypart + len;\n\tif (DUK_TVAL_IS_UNUSED(tv_val)) {\n\t\t/* No net refcount change.  Value stack already has\n\t\t * 'undefined' based on value stack init policy.\n\t\t */\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv_val));\n\t} else {\n\t\t/* No net refcount change. */\n\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv_val);\n\t\tDUK_TVAL_SET_UNUSED(tv_val);\n\t}\n\tthr->valstack_top++;\n\n\t/* XXX: there's no shrink check in the fast path now */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_pop(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t idx;\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\tduk_harray *h_arr;\n#endif\n\n\tDUK_ASSERT_TOP(thr, 0);\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\th_arr = duk__arraypart_fastpath_this(thr);\n\tif (h_arr) {\n\t\treturn duk__array_pop_fastpath(thr, h_arr);\n\t}\n#endif\n\n\t/* XXX: Merge fastpath check into a related call (push this, coerce length, etc)? */\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tif (len == 0) {\n\t\tduk_push_int(thr, 0);\n\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\t\treturn 0;\n\t}\n\tidx = len - 1;\n\n\tduk_get_prop_index(thr, 0, (duk_uarridx_t) idx);\n\tduk_del_prop_index(thr, 0, (duk_uarridx_t) idx);\n\tduk_push_u32(thr, idx);\n\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\treturn 1;\n}\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\nDUK_LOCAL duk_ret_t duk__array_push_fastpath(duk_hthread *thr, duk_harray *h_arr) {\n\tduk_tval *tv_arraypart;\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_uint32_t len;\n\tduk_idx_t i, n;\n\n\tlen = h_arr->length;\n\ttv_arraypart = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) h_arr);\n\n\tn = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT(n >= 0);\n\tDUK_ASSERT((duk_uint32_t) n <= DUK_UINT32_MAX);\n\tif (DUK_UNLIKELY(len + (duk_uint32_t) n < len)) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.push() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);  /* != 0 return value returned as is by caller */\n\t}\n\tif (len + (duk_uint32_t) n > DUK_HOBJECT_GET_ASIZE((duk_hobject *) h_arr)) {\n\t\t/* Array part would need to be extended.  Rely on slow path\n\t\t * for now.\n\t\t *\n\t\t * XXX: Rework hobject code a bit and add extend support.\n\t\t */\n\t\treturn 0;\n\t}\n\n\ttv_src = thr->valstack_bottom;\n\ttv_dst = tv_arraypart + len;\n\tfor (i = 0; i < n; i++) {\n\t\t/* No net refcount change; reset value stack values to\n\t\t * undefined to satisfy value stack init policy.\n\t\t */\n\t\tDUK_TVAL_SET_TVAL(tv_dst, tv_src);\n\t\tDUK_TVAL_SET_UNDEFINED(tv_src);\n\t\ttv_src++;\n\t\ttv_dst++;\n\t}\n\tthr->valstack_top = thr->valstack_bottom;\n\tlen += (duk_uint32_t) n;\n\th_arr->length = len;\n\n\tDUK_ASSERT((duk_uint_t) len == len);\n\tduk_push_uint(thr, (duk_uint_t) len);\n\treturn 1;\n}\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_push(duk_hthread *thr) {\n\t/* Note: 'this' is not necessarily an Array object.  The push()\n\t * algorithm is supposed to work for other kinds of objects too,\n\t * so the algorithm has e.g. an explicit update for the 'length'\n\t * property which is normally \"magical\" in arrays.\n\t */\n\n\tduk_uint32_t len;\n\tduk_idx_t i, n;\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\tduk_harray *h_arr;\n#endif\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\th_arr = duk__arraypart_fastpath_this(thr);\n\tif (h_arr) {\n\t\tduk_ret_t rc;\n\t\trc = duk__array_push_fastpath(thr, h_arr);\n\t\tif (rc != 0) {\n\t\t\treturn rc;\n\t\t}\n\t\tDUK_DD(DUK_DDPRINT(\"array push() fast path exited, resize case\"));\n\t}\n#endif\n\n\tn = duk_get_top(thr);\n\tlen = duk__push_this_obj_len_u32(thr);\n\n\t/* [ arg1 ... argN obj length ] */\n\n\t/* Technically Array.prototype.push() can create an Array with length\n\t * longer than 2^32-1, i.e. outside the 32-bit range.  The final length\n\t * is *not* wrapped to 32 bits in the specification.\n\t *\n\t * This implementation tracks length with a uint32 because it's much\n\t * more practical.\n\t *\n\t * See: test-bi-array-push-maxlen.js.\n\t */\n\n\tif (len + (duk_uint32_t) n < len) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.push() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t}\n\n\tfor (i = 0; i < n; i++) {\n\t\tduk_dup(thr, i);\n\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) (len + (duk_uint32_t) i));\n\t}\n\tlen += (duk_uint32_t) n;\n\n\tduk_push_u32(thr, len);\n\tduk_dup_top(thr);\n\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH);\n\n\t/* [ arg1 ... argN obj length new_length ] */\n\treturn 1;\n}\n\n/*\n *  sort()\n *\n *  Currently qsort with random pivot.  This is now really, really slow,\n *  because there is no fast path for array parts.\n *\n *  Signed indices are used because qsort() leaves and degenerate cases\n *  may use a negative offset.\n */\n\nDUK_LOCAL duk_small_int_t duk__array_sort_compare(duk_hthread *thr, duk_int_t idx1, duk_int_t idx2) {\n\tduk_bool_t have1, have2;\n\tduk_bool_t undef1, undef2;\n\tduk_small_int_t ret;\n\tduk_idx_t idx_obj = 1;  /* fixed offsets in valstack */\n\tduk_idx_t idx_fn = 0;\n\tduk_hstring *h1, *h2;\n\n\t/* Fast exit if indices are identical.  This is valid for a non-existent property,\n\t * for an undefined value, and almost always for ToString() coerced comparison of\n\t * arbitrary values (corner cases where this is not the case include e.g. a an\n\t * object with varying ToString() coercion).\n\t *\n\t * The specification does not prohibit \"caching\" of values read from the array, so\n\t * assuming equality for comparing an index with itself falls into the category of\n\t * \"caching\".\n\t *\n\t * Also, compareFn may be inconsistent, so skipping a call to compareFn here may\n\t * have an effect on the final result.  The specification does not require any\n\t * specific behavior for inconsistent compare functions, so again, this fast path\n\t * is OK.\n\t */\n\n\tif (idx1 == idx2) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__array_sort_compare: idx1=%ld, idx2=%ld -> indices identical, quick exit\",\n\t\t                     (long) idx1, (long) idx2));\n\t\treturn 0;\n\t}\n\n\thave1 = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) idx1);\n\thave2 = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) idx2);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__array_sort_compare: idx1=%ld, idx2=%ld, have1=%ld, have2=%ld, val1=%!T, val2=%!T\",\n\t                     (long) idx1, (long) idx2, (long) have1, (long) have2,\n\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (have1) {\n\t\tif (have2) {\n\t\t\t;\n\t\t} else {\n\t\t\tret = -1;\n\t\t\tgoto pop_ret;\n\t\t}\n\t} else {\n\t\tif (have2) {\n\t\t\tret = 1;\n\t\t\tgoto pop_ret;\n\t\t} else {\n\t\t\tret = 0;\n\t\t\tgoto pop_ret;\n\t\t}\n\t}\n\n\tundef1 = duk_is_undefined(thr, -2);\n\tundef2 = duk_is_undefined(thr, -1);\n\tif (undef1) {\n\t\tif (undef2) {\n\t\t\tret = 0;\n\t\t\tgoto pop_ret;\n\t\t} else {\n\t\t\tret = 1;\n\t\t\tgoto pop_ret;\n\t\t}\n\t} else {\n\t\tif (undef2) {\n\t\t\tret = -1;\n\t\t\tgoto pop_ret;\n\t\t} else {\n\t\t\t;\n\t\t}\n\t}\n\n\tif (!duk_is_undefined(thr, idx_fn)) {\n\t\tduk_double_t d;\n\n\t\t/* No need to check callable; duk_call() will do that. */\n\t\tduk_dup(thr, idx_fn);    /* -> [ ... x y fn ] */\n\t\tduk_insert(thr, -3);     /* -> [ ... fn x y ] */\n\t\tduk_call(thr, 2);        /* -> [ ... res ] */\n\n\t\t/* ES5 is a bit vague about what to do if the return value is\n\t\t * not a number.  ES2015 provides a concrete description:\n\t\t * http://www.ecma-international.org/ecma-262/6.0/#sec-sortcompare.\n\t\t */\n\n\t\td = duk_to_number_m1(thr);\n\t\tif (d < 0.0) {\n\t\t\tret = -1;\n\t\t} else if (d > 0.0) {\n\t\t\tret = 1;\n\t\t} else {\n\t\t\t/* Because NaN compares to false, NaN is handled here\n\t\t\t * without an explicit check above.\n\t\t\t */\n\t\t\tret = 0;\n\t\t}\n\n\t\tduk_pop_nodecref_unsafe(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> result %ld (from comparefn, after coercion)\", (long) ret));\n\t\treturn ret;\n\t}\n\n\t/* string compare is the default (a bit oddly) */\n\n\t/* XXX: any special handling for plain array; causes repeated coercion now? */\n\th1 = duk_to_hstring(thr, -2);\n\th2 = duk_to_hstring_m1(thr);\n\tDUK_ASSERT(h1 != NULL);\n\tDUK_ASSERT(h2 != NULL);\n\n\tret = duk_js_string_compare(h1, h2);  /* retval is directly usable */\n\tgoto pop_ret;\n\n pop_ret:\n\tduk_pop_2_unsafe(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"-> result %ld\", (long) ret));\n\treturn ret;\n}\n\nDUK_LOCAL void duk__array_sort_swap(duk_hthread *thr, duk_int_t l, duk_int_t r) {\n\tduk_bool_t have_l, have_r;\n\tduk_idx_t idx_obj = 1;  /* fixed offset in valstack */\n\n\tif (l == r) {\n\t\treturn;\n\t}\n\n\t/* swap elements; deal with non-existent elements correctly */\n\thave_l = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) l);\n\thave_r = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) r);\n\n\tif (have_r) {\n\t\t/* right exists, [[Put]] regardless whether or not left exists */\n\t\tduk_put_prop_index(thr, idx_obj, (duk_uarridx_t) l);\n\t} else {\n\t\tduk_del_prop_index(thr, idx_obj, (duk_uarridx_t) l);\n\t\tduk_pop_undefined(thr);\n\t}\n\n\tif (have_l) {\n\t\tduk_put_prop_index(thr, idx_obj, (duk_uarridx_t) r);\n\t} else {\n\t\tduk_del_prop_index(thr, idx_obj, (duk_uarridx_t) r);\n\t\tduk_pop_undefined(thr);\n\t}\n}\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n/* Debug print which visualizes the qsort partitioning process. */\nDUK_LOCAL void duk__debuglog_qsort_state(duk_hthread *thr, duk_int_t lo, duk_int_t hi, duk_int_t pivot) {\n\tchar buf[4096];\n\tchar *ptr = buf;\n\tduk_int_t i, n;\n\tn = (duk_int_t) duk_get_length(thr, 1);\n\tif (n > 4000) {\n\t\tn = 4000;\n\t}\n\t*ptr++ = '[';\n\tfor (i = 0; i < n; i++) {\n\t\tif (i == pivot) {\n\t\t\t*ptr++ = '|';\n\t\t} else if (i == lo) {\n\t\t\t*ptr++ = '<';\n\t\t} else if (i == hi) {\n\t\t\t*ptr++ = '>';\n\t\t} else if (i >= lo && i <= hi) {\n\t\t\t*ptr++ = '-';\n\t\t} else {\n\t\t\t*ptr++ = ' ';\n\t\t}\n\t}\n\t*ptr++ = ']';\n\t*ptr++ = '\\0';\n\n\tDUK_DDD(DUK_DDDPRINT(\"%s   (lo=%ld, hi=%ld, pivot=%ld)\",\n\t                     (const char *) buf, (long) lo, (long) hi, (long) pivot));\n}\n#endif\n\nDUK_LOCAL void duk__array_qsort(duk_hthread *thr, duk_int_t lo, duk_int_t hi) {\n\tduk_int_t p, l, r;\n\n\t/* The lo/hi indices may be crossed and hi < 0 is possible at entry. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__array_qsort: lo=%ld, hi=%ld, obj=%!T\",\n\t                     (long) lo, (long) hi, (duk_tval *) duk_get_tval(thr, 1)));\n\n\tDUK_ASSERT_TOP(thr, 3);\n\n\t/* In some cases it may be that lo > hi, or hi < 0; these\n\t * degenerate cases happen e.g. for empty arrays, and in\n\t * recursion leaves.\n\t */\n\n\t/* trivial cases */\n\tif (hi - lo < 1) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"degenerate case, return immediately\"));\n\t\treturn;\n\t}\n\tDUK_ASSERT(hi > lo);\n\tDUK_ASSERT(hi - lo + 1 >= 2);\n\n\t/* randomized pivot selection */\n\tp = lo + (duk_int_t) (DUK_UTIL_GET_RANDOM_DOUBLE(thr) * (duk_double_t) (hi - lo + 1));\n\tDUK_ASSERT(p >= lo && p <= hi);\n\tDUK_DDD(DUK_DDDPRINT(\"lo=%ld, hi=%ld, chose pivot p=%ld\", (long) lo, (long) hi, (long) p));\n\n\t/* move pivot out of the way */\n\tduk__array_sort_swap(thr, p, lo);\n\tp = lo;\n\tDUK_DDD(DUK_DDDPRINT(\"pivot moved out of the way: %!T\", (duk_tval *) duk_get_tval(thr, 1)));\n\n\tl = lo + 1;\n\tr = hi;\n\tfor (;;) {\n\t\t/* find elements to swap */\n\t\tfor (;;) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"left scan: l=%ld, r=%ld, p=%ld\",\n\t\t\t                     (long) l, (long) r, (long) p));\n\t\t\tif (l >= hi) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (duk__array_sort_compare(thr, l, p) >= 0) {  /* !(l < p) */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tl++;\n\t\t}\n\t\tfor (;;) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"right scan: l=%ld, r=%ld, p=%ld\",\n\t\t\t                     (long) l, (long) r, (long) p));\n\t\t\tif (r <= lo) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (duk__array_sort_compare(thr, p, r) >= 0) {  /* !(p < r) */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tr--;\n\t\t}\n\t\tif (l >= r) {\n\t\t\tgoto done;\n\t\t}\n\t\tDUK_ASSERT(l < r);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"swap %ld and %ld\", (long) l, (long) r));\n\n\t\tduk__array_sort_swap(thr, l, r);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"after swap: %!T\", (duk_tval *) duk_get_tval(thr, 1)));\n\t\tl++;\n\t\tr--;\n\t}\n done:\n\t/* Note that 'l' and 'r' may cross, i.e. r < l */\n\tDUK_ASSERT(l >= lo && l <= hi);\n\tDUK_ASSERT(r >= lo && r <= hi);\n\n\t/* XXX: there's no explicit recursion bound here now.  For the average\n\t * qsort recursion depth O(log n) that's not really necessary: e.g. for\n\t * 2**32 recursion depth would be about 32 which is OK.  However, qsort\n\t * worst case recursion depth is O(n) which may be a problem.\n\t */\n\n\t/* move pivot to its final place */\n\tDUK_DDD(DUK_DDDPRINT(\"before final pivot swap: %!T\", (duk_tval *) duk_get_tval(thr, 1)));\n\tduk__array_sort_swap(thr, lo, r);\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\tduk__debuglog_qsort_state(thr, lo, hi, r);\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"recurse: pivot=%ld, obj=%!T\", (long) r, (duk_tval *) duk_get_tval(thr, 1)));\n\tduk__array_qsort(thr, lo, r - 1);\n\tduk__array_qsort(thr, r + 1, hi);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_sort(duk_hthread *thr) {\n\tduk_uint32_t len;\n\n\t/* XXX: len >= 0x80000000 won't work below because a signed type\n\t * is needed by qsort.\n\t */\n\tlen = duk__push_this_obj_len_u32_limited(thr);\n\n\t/* stack[0] = compareFn\n\t * stack[1] = ToObject(this)\n\t * stack[2] = ToUint32(length)\n\t */\n\n\tif (len > 0) {\n\t\t/* avoid degenerate cases, so that (len - 1) won't underflow */\n\t\tduk__array_qsort(thr, (duk_int_t) 0, (duk_int_t) (len - 1));\n\t}\n\n\tDUK_ASSERT_TOP(thr, 3);\n\tduk_pop_nodecref_unsafe(thr);\n\treturn 1;  /* return ToObject(this) */\n}\n\n/*\n *  splice()\n */\n\n/* XXX: this compiles to over 500 bytes now, even without special handling\n * for an array part.  Uses signed ints so does not handle full array range correctly.\n */\n\n/* XXX: can shift() / unshift() use the same helper?\n *   shift() is (close to?) <--> splice(0, 1)\n *   unshift is (close to?) <--> splice(0, 0, [items])?\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_uint32_t len_u32;\n\tduk_int_t len;\n\tduk_bool_t have_delcount;\n\tduk_int_t item_count;\n\tduk_int_t act_start;\n\tduk_int_t del_count;\n\tduk_int_t i, n;\n\n\tDUK_UNREF(have_delcount);\n\n\tnargs = duk_get_top(thr);\n\tif (nargs < 2) {\n\t\tduk_set_top(thr, 2);\n\t\tnargs = 2;\n\t\thave_delcount = 0;\n\t} else {\n\t\thave_delcount = 1;\n\t}\n\n\t/* XXX: len >= 0x80000000 won't work below because we need to be\n\t * able to represent -len.\n\t */\n\tlen_u32 = duk__push_this_obj_len_u32_limited(thr);\n\tlen = (duk_int_t) len_u32;\n\tDUK_ASSERT(len >= 0);\n\n\tact_start = duk_to_int_clamped(thr, 0, -len, len);\n\tif (act_start < 0) {\n\t\tact_start = len + act_start;\n\t}\n\tDUK_ASSERT(act_start >= 0 && act_start <= len);\n\n#if defined(DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT)\n\tif (have_delcount) {\n#endif\n\t\tdel_count = duk_to_int_clamped(thr, 1, 0, len - act_start);\n#if defined(DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT)\n\t} else {\n\t\t/* E5.1 standard behavior when deleteCount is not given would be\n\t\t * to treat it just like if 'undefined' was given, which coerces\n\t\t * ultimately to 0.  Real world behavior is to splice to the end\n\t\t * of array, see test-bi-array-proto-splice-no-delcount.js.\n\t\t */\n\t\tdel_count = len - act_start;\n\t}\n#endif\n\n\tDUK_ASSERT(nargs >= 2);\n\titem_count = (duk_int_t) (nargs - 2);\n\n\tDUK_ASSERT(del_count >= 0 && del_count <= len - act_start);\n\tDUK_ASSERT(del_count + act_start <= len);\n\n\t/* For now, restrict result array into 32-bit length range. */\n\tif (((duk_double_t) len) - ((duk_double_t) del_count) + ((duk_double_t) item_count) > (duk_double_t) DUK_UINT32_MAX) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.splice() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t}\n\n\tduk_push_array(thr);\n\n\t/* stack[0] = start\n\t * stack[1] = deleteCount\n\t * stack[2...nargs-1] = items\n\t * stack[nargs] = ToObject(this)               -3\n\t * stack[nargs+1] = ToUint32(length)           -2\n\t * stack[nargs+2] = result array               -1\n\t */\n\n\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t/* Step 9: copy elements-to-be-deleted into the result array */\n\n\tfor (i = 0; i < del_count; i++) {\n\t\tif (duk_get_prop_index(thr, -3, (duk_uarridx_t) (act_start + i))) {\n\t\t\tduk_xdef_prop_index_wec(thr, -2, (duk_uarridx_t) i);  /* throw flag irrelevant (false in std alg) */\n\t\t} else {\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\t}\n\tduk_push_u32(thr, (duk_uint32_t) del_count);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\n\t/* Steps 12 and 13: reorganize elements to make room for itemCount elements */\n\n\tif (item_count < del_count) {\n\t\t/*    [ A B C D E F G H ]    rel_index = 2, del_count 3, item count 1\n\t\t * -> [ A B F G H ]          (conceptual intermediate step)\n\t\t * -> [ A B . F G H ]        (placeholder marked)\n\t\t *    [ A B C F G H ]        (actual result at this point, C will be replaced)\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t\tn = len - del_count;\n\t\tfor (i = act_start; i < n; i++) {\n\t\t\tif (duk_get_prop_index(thr, -3, (duk_uarridx_t) (i + del_count))) {\n\t\t\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) (i + item_count));\n\t\t\t} else {\n\t\t\t\tduk_pop_undefined(thr);\n\t\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) (i + item_count));\n\t\t\t}\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t\t/* loop iterator init and limit changed from standard algorithm */\n\t\tn = len - del_count + item_count;\n\t\tfor (i = len - 1; i >= n; i--) {\n\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) i);\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\t} else if (item_count > del_count) {\n\t\t/*    [ A B C D E F G H ]    rel_index = 2, del_count 3, item count 4\n\t\t * -> [ A B F G H ]          (conceptual intermediate step)\n\t\t * -> [ A B . . . . F G H ]  (placeholder marked)\n\t\t *    [ A B C D E F F G H ]  (actual result at this point)\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t\t/* loop iterator init and limit changed from standard algorithm */\n\t\tfor (i = len - del_count - 1; i >= act_start; i--) {\n\t\t\tif (duk_get_prop_index(thr, -3, (duk_uarridx_t) (i + del_count))) {\n\t\t\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) (i + item_count));\n\t\t\t} else {\n\t\t\t\tduk_pop_undefined(thr);\n\t\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) (i + item_count));\n\t\t\t}\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\t} else {\n\t\t/*    [ A B C D E F G H ]    rel_index = 2, del_count 3, item count 3\n\t\t * -> [ A B F G H ]          (conceptual intermediate step)\n\t\t * -> [ A B . . . F G H ]    (placeholder marked)\n\t\t *    [ A B C D E F G H ]    (actual result at this point)\n\t\t */\n\t}\n\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t/* Step 15: insert itemCount elements into the hole made above */\n\n\tfor (i = 0; i < item_count; i++) {\n\t\tduk_dup(thr, i + 2);  /* args start at index 2 */\n\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) (act_start + i));\n\t}\n\n\t/* Step 16: update length; note that the final length may be above 32 bit range\n\t * (but we checked above that this isn't the case here)\n\t */\n\n\tduk_push_u32(thr, (duk_uint32_t) (len - del_count + item_count));\n\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH);\n\n\t/* result array is already at the top of stack */\n\tDUK_ASSERT_TOP(thr, nargs + 3);\n\treturn 1;\n}\n\n/*\n *  reverse()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_reverse(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t middle;\n\tduk_uint32_t lower, upper;\n\tduk_bool_t have_lower, have_upper;\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tmiddle = len / 2;\n\n\t/* If len <= 1, middle will be 0 and for-loop bails out\n\t * immediately (0 < 0 -> false).\n\t */\n\n\tfor (lower = 0; lower < middle; lower++) {\n\t\tDUK_ASSERT(len >= 2);\n\t\tDUK_ASSERT_TOP(thr, 2);\n\n\t\tDUK_ASSERT(len >= lower + 1);\n\t\tupper = len - lower - 1;\n\n\t\thave_lower = duk_get_prop_index(thr, -2, (duk_uarridx_t) lower);\n\t\thave_upper = duk_get_prop_index(thr, -3, (duk_uarridx_t) upper);\n\n\t\t/* [ ToObject(this) ToUint32(length) lowerValue upperValue ] */\n\n\t\tif (have_upper) {\n\t\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) lower);\n\t\t} else {\n\t\t\tduk_del_prop_index(thr, -4, (duk_uarridx_t) lower);\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\n\t\tif (have_lower) {\n\t\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) upper);\n\t\t} else {\n\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) upper);\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t}\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_pop_unsafe(thr);  /* -> [ ToObject(this) ] */\n\treturn 1;\n}\n\n/*\n *  slice()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_slice(duk_hthread *thr) {\n\tduk_uint32_t len_u32;\n\tduk_int_t len;\n\tduk_int_t start, end;\n\tduk_int_t i;\n\tduk_uarridx_t idx;\n\tduk_uint32_t res_length = 0;\n\n\t/* XXX: len >= 0x80000000 won't work below because we need to be\n\t * able to represent -len.\n\t */\n\tlen_u32 = duk__push_this_obj_len_u32_limited(thr);\n\tlen = (duk_int_t) len_u32;\n\tDUK_ASSERT(len >= 0);\n\n\tduk_push_array(thr);\n\n\t/* stack[0] = start\n\t * stack[1] = end\n\t * stack[2] = ToObject(this)\n\t * stack[3] = ToUint32(length)\n\t * stack[4] = result array\n\t */\n\n\tstart = duk_to_int_clamped(thr, 0, -len, len);\n\tif (start < 0) {\n\t\tstart = len + start;\n\t}\n\t/* XXX: could duk_is_undefined() provide defaulting undefined to 'len'\n\t * (the upper limit)?\n\t */\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend = len;\n\t} else {\n\t\tend = duk_to_int_clamped(thr, 1, -len, len);\n\t\tif (end < 0) {\n\t\t\tend = len + end;\n\t\t}\n\t}\n\tDUK_ASSERT(start >= 0 && start <= len);\n\tDUK_ASSERT(end >= 0 && end <= len);\n\n\tidx = 0;\n\tfor (i = start; i < end; i++) {\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t\tif (duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\tduk_xdef_prop_index_wec(thr, 4, idx);\n\t\t\tres_length = idx + 1;\n\t\t} else {\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\t\tidx++;\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t}\n\n\tduk_push_u32(thr, res_length);\n\tduk_xdef_prop_stridx_short(thr, 4, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\n\tDUK_ASSERT_TOP(thr, 5);\n\treturn 1;\n}\n\n/*\n *  shift()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_shift(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t i;\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tif (len == 0) {\n\t\tduk_push_int(thr, 0);\n\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\t\treturn 0;\n\t}\n\n\tduk_get_prop_index(thr, 0, 0);\n\n\t/* stack[0] = object (this)\n\t * stack[1] = ToUint32(length)\n\t * stack[2] = elem at index 0 (retval)\n\t */\n\n\tfor (i = 1; i < len; i++) {\n\t\tDUK_ASSERT_TOP(thr, 3);\n\t\tif (duk_get_prop_index(thr, 0, (duk_uarridx_t) i)) {\n\t\t\t/* fromPresent = true */\n\t\t\tduk_put_prop_index(thr, 0, (duk_uarridx_t) (i - 1));\n\t\t} else {\n\t\t\t/* fromPresent = false */\n\t\t\tduk_del_prop_index(thr, 0, (duk_uarridx_t) (i - 1));\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\t}\n\tduk_del_prop_index(thr, 0, (duk_uarridx_t) (len - 1));\n\n\tduk_push_u32(thr, (duk_uint32_t) (len - 1));\n\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\n\tDUK_ASSERT_TOP(thr, 3);\n\treturn 1;\n}\n\n/*\n *  unshift()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_unshift(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_uint32_t len;\n\tduk_uint32_t i;\n\n\tnargs = duk_get_top(thr);\n\tlen = duk__push_this_obj_len_u32(thr);\n\n\t/* stack[0...nargs-1] = unshift args (vararg)\n\t * stack[nargs] = ToObject(this)\n\t * stack[nargs+1] = ToUint32(length)\n\t */\n\n\tDUK_ASSERT_TOP(thr, nargs + 2);\n\n\t/* Note: unshift() may operate on indices above unsigned 32-bit range\n\t * and the final length may be >= 2**32.  However, we restrict the\n\t * final result to 32-bit range for practicality.\n\t */\n\n\tif (len + (duk_uint32_t) nargs < len) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.unshift() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t}\n\n\ti = len;\n\twhile (i > 0) {\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t\ti--;\n\t\t/* k+argCount-1; note that may be above 32-bit range */\n\n\t\tif (duk_get_prop_index(thr, -2, (duk_uarridx_t) i)) {\n\t\t\t/* fromPresent = true */\n\t\t\t/* [ ... ToObject(this) ToUint32(length) val ] */\n\t\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) (i + (duk_uint32_t) nargs));  /* -> [ ... ToObject(this) ToUint32(length) ] */\n\t\t} else {\n\t\t\t/* fromPresent = false */\n\t\t\t/* [ ... ToObject(this) ToUint32(length) val ] */\n\t\t\tduk_pop_undefined(thr);\n\t\t\tduk_del_prop_index(thr, -2, (duk_uarridx_t) (i + (duk_uint32_t) nargs));  /* -> [ ... ToObject(this) ToUint32(length) ] */\n\t\t}\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t}\n\n\tfor (i = 0; i < (duk_uint32_t) nargs; i++) {\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t\tduk_dup(thr, (duk_idx_t) i);  /* -> [ ... ToObject(this) ToUint32(length) arg[i] ] */\n\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) i);\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t}\n\n\tDUK_ASSERT_TOP(thr, nargs + 2);\n\tduk_push_u32(thr, len + (duk_uint32_t) nargs);\n\tduk_dup_top(thr);  /* -> [ ... ToObject(this) ToUint32(length) final_len final_len ] */\n\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH);\n\treturn 1;\n}\n\n/*\n *  indexOf(), lastIndexOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_indexof_shared(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_int_t i, len;\n\tduk_int_t from_idx;\n\tduk_small_int_t idx_step = duk_get_current_magic(thr);  /* idx_step is +1 for indexOf, -1 for lastIndexOf */\n\n\t/* lastIndexOf() needs to be a vararg function because we must distinguish\n\t * between an undefined fromIndex and a \"not given\" fromIndex; indexOf() is\n\t * made vararg for symmetry although it doesn't strictly need to be.\n\t */\n\n\tnargs = duk_get_top(thr);\n\tduk_set_top(thr, 2);\n\n\t/* XXX: must be able to represent -len */\n\tlen = (duk_int_t) duk__push_this_obj_len_u32_limited(thr);\n\tif (len == 0) {\n\t\tgoto not_found;\n\t}\n\n\t/* Index clamping is a bit tricky, we must ensure that we'll only iterate\n\t * through elements that exist and that the specific requirements from E5.1\n\t * Sections 15.4.4.14 and 15.4.4.15 are fulfilled; especially:\n\t *\n\t *   - indexOf: clamp to [-len,len], negative handling -> [0,len],\n\t *     if clamped result is len, for-loop bails out immediately\n\t *\n\t *   - lastIndexOf: clamp to [-len-1, len-1], negative handling -> [-1, len-1],\n\t *     if clamped result is -1, for-loop bails out immediately\n\t *\n\t * If fromIndex is not given, ToInteger(undefined) = 0, which is correct\n\t * for indexOf() but incorrect for lastIndexOf().  Hence special handling,\n\t * and why lastIndexOf() needs to be a vararg function.\n\t */\n\n\tif (nargs >= 2) {\n\t\t/* indexOf: clamp fromIndex to [-len, len]\n\t\t * (if fromIndex == len, for-loop terminates directly)\n\t\t *\n\t\t * lastIndexOf: clamp fromIndex to [-len - 1, len - 1]\n\t\t * (if clamped to -len-1 -> fromIndex becomes -1, terminates for-loop directly)\n\t\t */\n\t\tfrom_idx = duk_to_int_clamped(thr,\n\t\t                              1,\n\t\t                              (idx_step > 0 ? -len : -len - 1),\n\t\t                              (idx_step > 0 ? len : len - 1));\n\t\tif (from_idx < 0) {\n\t\t\t/* for lastIndexOf, result may be -1 (mark immediate termination) */\n\t\t\tfrom_idx = len + from_idx;\n\t\t}\n\t} else {\n\t\t/* for indexOf, ToInteger(undefined) would be 0, i.e. correct, but\n\t\t * handle both indexOf and lastIndexOf specially here.\n\t\t */\n\t\tif (idx_step > 0) {\n\t\t\tfrom_idx = 0;\n\t\t} else {\n\t\t\tfrom_idx = len - 1;\n\t\t}\n\t}\n\n\t/* stack[0] = searchElement\n\t * stack[1] = fromIndex\n\t * stack[2] = object\n\t * stack[3] = length (not needed, but not popped above)\n\t */\n\n\tfor (i = from_idx; i >= 0 && i < len; i += idx_step) {\n\t\tDUK_ASSERT_TOP(thr, 4);\n\n\t\tif (duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t\tif (duk_strict_equals(thr, 0, 4)) {\n\t\t\t\tduk_push_int(thr, i);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\tduk_pop_unsafe(thr);\n\t}\n\n not_found:\n\tduk_push_int(thr, -1);\n\treturn 1;\n}\n\n/*\n *  every(), some(), forEach(), map(), filter()\n */\n\n#define DUK__ITER_EVERY    0\n#define DUK__ITER_SOME     1\n#define DUK__ITER_FOREACH  2\n#define DUK__ITER_MAP      3\n#define DUK__ITER_FILTER   4\n\n/* XXX: This helper is a bit awkward because the handling for the different iteration\n * callers is quite different.  This now compiles to a bit less than 500 bytes, so with\n * 5 callers the net result is about 100 bytes / caller.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_iter_shared(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t i;\n\tduk_uarridx_t k;\n\tduk_bool_t bval;\n\tduk_small_int_t iter_type = duk_get_current_magic(thr);\n\tduk_uint32_t res_length = 0;\n\n\t/* each call this helper serves has nargs==2 */\n\tDUK_ASSERT_TOP(thr, 2);\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tduk_require_callable(thr, 0);\n\t/* if thisArg not supplied, behave as if undefined was supplied */\n\n\tif (iter_type == DUK__ITER_MAP || iter_type == DUK__ITER_FILTER) {\n\t\tduk_push_array(thr);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n\n\t/* stack[0] = callback\n\t * stack[1] = thisArg\n\t * stack[2] = object\n\t * stack[3] = ToUint32(length)  (unused, but avoid unnecessary pop)\n\t * stack[4] = result array (or undefined)\n\t */\n\n\tk = 0;  /* result index for filter() */\n\tfor (i = 0; i < len; i++) {\n\t\tDUK_ASSERT_TOP(thr, 5);\n\n\t\tif (!duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\t/* For 'map' trailing missing elements don't invoke the\n\t\t\t * callback but count towards the result length.\n\t\t\t */\n\t\t\tif (iter_type == DUK__ITER_MAP) {\n\t\t\t\tres_length = i + 1;\n\t\t\t}\n\t\t\tduk_pop_undefined(thr);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* The original value needs to be preserved for filter(), hence\n\t\t * this funny order.  We can't re-get the value because of side\n\t\t * effects.\n\t\t */\n\n\t\tduk_dup_0(thr);\n\t\tduk_dup_1(thr);\n\t\tduk_dup_m3(thr);\n\t\tduk_push_u32(thr, i);\n\t\tduk_dup_2(thr);  /* [ ... val callback thisArg val i obj ] */\n\t\tduk_call_method(thr, 3); /* -> [ ... val retval ] */\n\n\t\tswitch (iter_type) {\n\t\tcase DUK__ITER_EVERY:\n\t\t\tbval = duk_to_boolean(thr, -1);\n\t\t\tif (!bval) {\n\t\t\t\t/* stack top contains 'false' */\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase DUK__ITER_SOME:\n\t\t\tbval = duk_to_boolean(thr, -1);\n\t\t\tif (bval) {\n\t\t\t\t/* stack top contains 'true' */\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase DUK__ITER_FOREACH:\n\t\t\t/* nop */\n\t\t\tbreak;\n\t\tcase DUK__ITER_MAP:\n\t\t\tduk_dup_top(thr);\n\t\t\tduk_xdef_prop_index_wec(thr, 4, (duk_uarridx_t) i);  /* retval to result[i] */\n\t\t\tres_length = i + 1;\n\t\t\tbreak;\n\t\tcase DUK__ITER_FILTER:\n\t\t\tbval = duk_to_boolean(thr, -1);\n\t\t\tif (bval) {\n\t\t\t\tduk_dup_m2(thr);  /* orig value */\n\t\t\t\tduk_xdef_prop_index_wec(thr, 4, (duk_uarridx_t) k);\n\t\t\t\tk++;\n\t\t\t\tres_length = k;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tduk_pop_2_unsafe(thr);\n\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t}\n\n\tswitch (iter_type) {\n\tcase DUK__ITER_EVERY:\n\t\tduk_push_true(thr);\n\t\tbreak;\n\tcase DUK__ITER_SOME:\n\t\tduk_push_false(thr);\n\t\tbreak;\n\tcase DUK__ITER_FOREACH:\n\t\tduk_push_undefined(thr);\n\t\tbreak;\n\tcase DUK__ITER_MAP:\n\tcase DUK__ITER_FILTER:\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t\tDUK_ASSERT(duk_is_array(thr, -1));  /* topmost element is the result array already */\n\t\tduk_push_u32(thr, res_length);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\t\tbreak;\n\tdefault:\n\t\tDUK_UNREACHABLE();\n\t\tbreak;\n\t}\n\n\treturn 1;\n}\n\n/*\n *  reduce(), reduceRight()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_reduce_shared(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_bool_t have_acc;\n\tduk_uint32_t i, len;\n\tduk_small_int_t idx_step = duk_get_current_magic(thr);  /* idx_step is +1 for reduce, -1 for reduceRight */\n\n\t/* We're a varargs function because we need to detect whether\n\t * initialValue was given or not.\n\t */\n\tnargs = duk_get_top(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"nargs=%ld\", (long) nargs));\n\n\tduk_set_top(thr, 2);\n\tlen = duk__push_this_obj_len_u32(thr);\n\tduk_require_callable(thr, 0);\n\n\t/* stack[0] = callback fn\n\t * stack[1] = initialValue\n\t * stack[2] = object (coerced this)\n\t * stack[3] = length (not needed, but not popped above)\n\t * stack[4] = accumulator\n\t */\n\n\thave_acc = 0;\n\tif (nargs >= 2) {\n\t\tduk_dup_1(thr);\n\t\thave_acc = 1;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"have_acc=%ld, acc=%!T\",\n\t                     (long) have_acc, (duk_tval *) duk_get_tval(thr, 3)));\n\n\t/* For len == 0, i is initialized to len - 1 which underflows.\n\t * The condition (i < len) will then exit the for-loop on the\n\t * first round which is correct.  Similarly, loop termination\n\t * happens by i underflowing.\n\t */\n\n\tfor (i = (idx_step >= 0 ? 0 : len - 1);\n\t     i < len;  /* i >= 0 would always be true */\n\t     i += (duk_uint32_t) idx_step) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"i=%ld, len=%ld, have_acc=%ld, top=%ld, acc=%!T\",\n\t\t                     (long) i, (long) len, (long) have_acc,\n\t\t                     (long) duk_get_top(thr),\n\t\t                     (duk_tval *) duk_get_tval(thr, 4)));\n\n\t\tDUK_ASSERT((have_acc && duk_get_top(thr) == 5) ||\n\t\t           (!have_acc && duk_get_top(thr) == 4));\n\n\t\tif (!duk_has_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!have_acc) {\n\t\t\tDUK_ASSERT_TOP(thr, 4);\n\t\t\tduk_get_prop_index(thr, 2, (duk_uarridx_t) i);\n\t\t\thave_acc = 1;\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t} else {\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_dup(thr, 4);\n\t\t\tduk_get_prop_index(thr, 2, (duk_uarridx_t) i);\n\t\t\tduk_push_u32(thr, i);\n\t\t\tduk_dup_2(thr);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"calling reduce function: func=%!T, prev=%!T, curr=%!T, idx=%!T, obj=%!T\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -5), (duk_tval *) duk_get_tval(thr, -4),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -3), (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tduk_call(thr, 4);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> result: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tduk_replace(thr, 4);\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t}\n\t}\n\n\tif (!have_acc) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tDUK_ASSERT_TOP(thr, 5);\n\treturn 1;\n}\n\n#endif  /* DUK_USE_ARRAY_BUILTIN */\n\n/* automatic undefs */\n#undef DUK__ARRAY_MID_JOIN_LIMIT\n#undef DUK__ITER_EVERY\n#undef DUK__ITER_FILTER\n#undef DUK__ITER_FOREACH\n#undef DUK__ITER_MAP\n#undef DUK__ITER_SOME\n/*\n *  Boolean built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_BOOLEAN_BUILTIN)\n\n/* Shared helper to provide toString() and valueOf().  Checks 'this', gets\n * the primitive value to stack top, and optionally coerces with ToString().\n */\nDUK_INTERNAL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\tduk_small_int_t coerce_tostring = duk_get_current_magic(thr);\n\n\t/* XXX: there is room to use a shared helper here, many built-ins\n\t * check the 'this' type, and if it's an object, check its class,\n\t * then get its internal value, etc.\n\t */\n\n\tduk_push_this(thr);\n\ttv = duk_get_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_BOOLEAN(tv)) {\n\t\tgoto type_ok;\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_BOOLEAN) {\n\t\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t\t\tDUK_ASSERT(duk_is_boolean(thr, -1));\n\t\t\tgoto type_ok;\n\t\t}\n\t}\n\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t/* never here */\n\n type_ok:\n\tif (coerce_tostring) {\n\t\tduk_to_string(thr, -1);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_boolean_constructor(duk_hthread *thr) {\n\tduk_hobject *h_this;\n\n\tduk_to_boolean(thr, 0);\n\n\tif (duk_is_constructor_call(thr)) {\n\t\t/* XXX: helper; rely on Boolean.prototype as being non-writable, non-configurable */\n\t\tduk_push_this(thr);\n\t\th_this = duk_known_hobject(thr, -1);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE]);\n\n\t\tDUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_BOOLEAN);\n\n\t\tduk_dup_0(thr);  /* -> [ val obj val ] */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);  /* XXX: proper flags? */\n\t}  /* unbalanced stack */\n\n\treturn 1;\n}\n\n#endif  /* DUK_USE_BOOLEAN_BUILTIN */\n/*\n *  ES2015 TypedArray and Node.js Buffer built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Helpers for buffer handling, enabled with DUK_USE_BUFFEROBJECT_SUPPORT.\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Map class number (minus DUK_HOBJECT_CLASS_BUFOBJ_MIN) to a bidx for the\n * default internal prototype.\n */\nstatic const duk_uint8_t duk__buffer_proto_from_classnum[] = {\n\tDUK_BIDX_ARRAYBUFFER_PROTOTYPE,\n\tDUK_BIDX_DATAVIEW_PROTOTYPE,\n\tDUK_BIDX_INT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE,\n\tDUK_BIDX_INT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_INT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT64ARRAY_PROTOTYPE\n};\n\n/* Map DUK_HBUFOBJ_ELEM_xxx to duk_hobject class number.\n * Sync with duk_hbufobj.h and duk_hobject.h.\n */\nstatic const duk_uint8_t duk__buffer_class_from_elemtype[9] = {\n\tDUK_HOBJECT_CLASS_UINT8ARRAY,\n\tDUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY,\n\tDUK_HOBJECT_CLASS_INT8ARRAY,\n\tDUK_HOBJECT_CLASS_UINT16ARRAY,\n\tDUK_HOBJECT_CLASS_INT16ARRAY,\n\tDUK_HOBJECT_CLASS_UINT32ARRAY,\n\tDUK_HOBJECT_CLASS_INT32ARRAY,\n\tDUK_HOBJECT_CLASS_FLOAT32ARRAY,\n\tDUK_HOBJECT_CLASS_FLOAT64ARRAY\n};\n\n/* Map DUK_HBUFOBJ_ELEM_xxx to prototype object built-in index.\n * Sync with duk_hbufobj.h.\n */\nstatic const duk_uint8_t duk__buffer_proto_from_elemtype[9] = {\n\tDUK_BIDX_UINT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE,\n\tDUK_BIDX_INT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_INT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_INT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT64ARRAY_PROTOTYPE\n};\n\n/* Map DUK__FLD_xxx to byte size. */\nstatic const duk_uint8_t duk__buffer_nbytes_from_fldtype[6] = {\n\t1,  /* DUK__FLD_8BIT */\n\t2,  /* DUK__FLD_16BIT */\n\t4,  /* DUK__FLD_32BIT */\n\t4,  /* DUK__FLD_FLOAT */\n\t8,  /* DUK__FLD_DOUBLE */\n\t0   /* DUK__FLD_VARINT; not relevant here */\n};\n\n/* Bitfield for each DUK_HBUFOBJ_ELEM_xxx indicating which element types\n * are compatible with a blind byte copy for the TypedArray set() method (also\n * used for TypedArray constructor).  Array index is target buffer elem type,\n * bitfield indicates compatible source types.  The types must have same byte\n * size and they must be coercion compatible.\n */\n#if !defined(DUK_USE_PREFER_SIZE)\nstatic duk_uint16_t duk__buffer_elemtype_copy_compatible[9] = {\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT8 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT8) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_UINT8CLAMPED) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT8),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT8CLAMPED\n\t * Note: INT8 is -not- copy compatible, e.g. -1 would coerce to 0x00.\n\t */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT8) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_UINT8CLAMPED),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_INT8 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT8) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_UINT8CLAMPED) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT8),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT16 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT16) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT16),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_INT16 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT16) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT16),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT32 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT32) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT32),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_INT32 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT32) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT32),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_FLOAT32 */\n\t(1U << DUK_HBUFOBJ_ELEM_FLOAT32),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_FLOAT64 */\n\t(1U << DUK_HBUFOBJ_ELEM_FLOAT64)\n};\n#endif  /* !DUK_USE_PREFER_SIZE */\n\nDUK_LOCAL duk_hbufobj *duk__hbufobj_promote_this(duk_hthread *thr) {\n\tduk_tval *tv_dst;\n\tduk_hbufobj *res;\n\n\tduk_push_this(thr);\n\tDUK_ASSERT(duk_is_buffer(thr, -1));\n\tres = (duk_hbufobj *) duk_to_hobject(thr, -1);\n\tDUK_HBUFOBJ_ASSERT_VALID(res);\n\tDUK_DD(DUK_DDPRINT(\"promoted 'this' automatically to an ArrayBuffer: %!iT\", duk_get_tval(thr, -1)));\n\n\ttv_dst = duk_get_borrowed_this_tval(thr);\n\tDUK_TVAL_SET_OBJECT_UPDREF(thr, tv_dst, (duk_hobject *) res);\n\tduk_pop(thr);\n\n\treturn res;\n}\n\n#define DUK__BUFOBJ_FLAG_THROW    (1 << 0)\n#define DUK__BUFOBJ_FLAG_PROMOTE  (1 << 1)\n\n/* Shared helper.  When DUK__BUFOBJ_FLAG_PROMOTE is given, the return value is\n * always a duk_hbufobj *.  Without the flag the return value can also be a\n * plain buffer, and the caller must check for it using DUK_HEAPHDR_IS_BUFFER().\n */\nDUK_LOCAL duk_heaphdr *duk__getrequire_bufobj_this(duk_hthread *thr, duk_small_uint_t flags) {\n\tduk_tval *tv;\n\tduk_hbufobj *h_this;\n\n\tDUK_ASSERT(thr != NULL);\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_this = (duk_hbufobj *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_this != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h_this)) {\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\t\t\treturn (duk_heaphdr *) h_this;\n\t\t}\n\t} else if (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tif (flags & DUK__BUFOBJ_FLAG_PROMOTE) {\n\t\t\t/* Promote a plain buffer to a Uint8Array.  This is very\n\t\t\t * inefficient but allows plain buffer to be used wherever an\n\t\t\t * Uint8Array is used with very small cost; hot path functions\n\t\t\t * like index read/write calls should provide direct buffer\n\t\t\t * support to avoid promotion.\n\t\t\t */\n\t\t\t/* XXX: make this conditional to a flag if call sites need it? */\n\t\t\th_this = duk__hbufobj_promote_this(thr);\n\t\t\tDUK_ASSERT(h_this != NULL);\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\t\t\treturn (duk_heaphdr *) h_this;\n\t\t} else {\n\t\t\t/* XXX: ugly, share return pointer for duk_hbuffer. */\n\t\t\treturn (duk_heaphdr *) DUK_TVAL_GET_BUFFER(tv);\n\t\t}\n\t}\n\n\tif (flags & DUK__BUFOBJ_FLAG_THROW) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_BUFFER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn NULL;\n}\n\n/* Check that 'this' is a duk_hbufobj and return a pointer to it. */\nDUK_LOCAL duk_hbufobj *duk__get_bufobj_this(duk_hthread *thr) {\n\treturn (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_PROMOTE);\n}\n\n/* Check that 'this' is a duk_hbufobj and return a pointer to it\n * (NULL if not).\n */\nDUK_LOCAL duk_hbufobj *duk__require_bufobj_this(duk_hthread *thr) {\n\treturn (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW | DUK__BUFOBJ_FLAG_PROMOTE);\n}\n\n/* Check that value is a duk_hbufobj and return a pointer to it. */\nDUK_LOCAL duk_hbufobj *duk__require_bufobj_value(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hbufobj *h_obj;\n\n\t/* Don't accept relative indices now. */\n\tDUK_ASSERT(idx >= 0);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_obj = (duk_hbufobj *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h_obj)) {\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_obj);\n\t\t\treturn h_obj;\n\t\t}\n\t} else if (DUK_TVAL_IS_BUFFER(tv)) {\n\t\th_obj = (duk_hbufobj *) duk_to_hobject(thr, idx);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tDUK_HBUFOBJ_ASSERT_VALID(h_obj);\n\t\treturn h_obj;\n\t}\n\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_BUFFER);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_LOCAL void duk__set_bufobj_buffer(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_hbuffer *h_val) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tDUK_ASSERT(h_bufobj->buf == NULL);  /* no need to decref */\n\tDUK_ASSERT(h_val != NULL);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\tDUK_UNREF(thr);\n\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\th_bufobj->length = (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_val);\n\tDUK_ASSERT(h_bufobj->shift == 0);\n\tDUK_ASSERT(h_bufobj->elem_type == DUK_HBUFOBJ_ELEM_UINT8);\n\tDUK_ASSERT(h_bufobj->is_typedarray == 0);\n\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n}\n\n/* Shared offset/length coercion helper. */\nDUK_LOCAL void duk__resolve_offset_opt_length(duk_hthread *thr,\n                                              duk_hbufobj *h_bufarg,\n                                              duk_idx_t idx_offset,\n                                              duk_idx_t idx_length,\n                                              duk_uint_t *out_offset,\n                                              duk_uint_t *out_length,\n                                              duk_bool_t throw_flag) {\n\tduk_int_t offset_signed;\n\tduk_int_t length_signed;\n\tduk_uint_t offset;\n\tduk_uint_t length;\n\n\toffset_signed = duk_to_int(thr, idx_offset);\n\tif (offset_signed < 0) {\n\t\tgoto fail_range;\n\t}\n\toffset = (duk_uint_t) offset_signed;\n\tif (offset > h_bufarg->length) {\n\t\tgoto fail_range;\n\t}\n\tDUK_ASSERT_DISABLE(offset >= 0);  /* unsigned */\n\tDUK_ASSERT(offset <= h_bufarg->length);\n\n\tif (duk_is_undefined(thr, idx_length)) {\n\t\tDUK_ASSERT(h_bufarg->length >= offset);\n\t\tlength = h_bufarg->length - offset;  /* >= 0 */\n\t} else {\n\t\tlength_signed = duk_to_int(thr, idx_length);\n\t\tif (length_signed < 0) {\n\t\t\tgoto fail_range;\n\t\t}\n\t\tlength = (duk_uint_t) length_signed;\n\t\tDUK_ASSERT(h_bufarg->length >= offset);\n\t\tif (length > h_bufarg->length - offset) {\n\t\t\t/* Unlike for negative arguments, some call sites\n\t\t\t * want length to be clamped if it's positive.\n\t\t\t */\n\t\t\tif (throw_flag) {\n\t\t\t\tgoto fail_range;\n\t\t\t} else {\n\t\t\t\tlength = h_bufarg->length - offset;\n\t\t\t}\n\t\t}\n\t}\n\tDUK_ASSERT_DISABLE(length >= 0);  /* unsigned */\n\tDUK_ASSERT(offset + length <= h_bufarg->length);\n\n\t*out_offset = offset;\n\t*out_length = length;\n\treturn;\n\n fail_range:\n\tDUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARGS);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Shared lenient buffer length clamping helper.  No negative indices, no\n * element/byte shifting.\n */\nDUK_LOCAL void duk__clamp_startend_nonegidx_noshift(duk_hthread *thr,\n                                                    duk_int_t buffer_length,\n                                                    duk_idx_t idx_start,\n                                                    duk_idx_t idx_end,\n                                                    duk_int_t *out_start_offset,\n                                                    duk_int_t *out_end_offset) {\n\tduk_int_t start_offset;\n\tduk_int_t end_offset;\n\n\tDUK_ASSERT(out_start_offset != NULL);\n\tDUK_ASSERT(out_end_offset != NULL);\n\n\t/* undefined coerces to zero which is correct */\n\tstart_offset = duk_to_int_clamped(thr, idx_start, 0, buffer_length);\n\tif (duk_is_undefined(thr, idx_end)) {\n\t\tend_offset = buffer_length;\n\t} else {\n\t\tend_offset = duk_to_int_clamped(thr, idx_end, start_offset, buffer_length);\n\t}\n\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(start_offset <= buffer_length);\n\tDUK_ASSERT(end_offset >= 0);\n\tDUK_ASSERT(end_offset <= buffer_length);\n\tDUK_ASSERT(start_offset <= end_offset);\n\n\t*out_start_offset = start_offset;\n\t*out_end_offset = end_offset;\n}\n\n/* Shared lenient buffer length clamping helper.  Indices are treated as\n * element indices (though output values are byte offsets) which only\n * really matters for TypedArray views as other buffer object have a zero\n * shift.  Negative indices are counted from end of input slice; crossed\n * indices are clamped to zero length; and final indices are clamped\n * against input slice.  Used for e.g. ArrayBuffer slice().\n */\nDUK_LOCAL void duk__clamp_startend_negidx_shifted(duk_hthread *thr,\n                                                  duk_int_t buffer_length,\n                                                  duk_uint8_t buffer_shift,\n                                                  duk_idx_t idx_start,\n                                                  duk_idx_t idx_end,\n                                                  duk_int_t *out_start_offset,\n                                                  duk_int_t *out_end_offset) {\n\tduk_int_t start_offset;\n\tduk_int_t end_offset;\n\n\tDUK_ASSERT(out_start_offset != NULL);\n\tDUK_ASSERT(out_end_offset != NULL);\n\n\tbuffer_length >>= buffer_shift;  /* as (full) elements */\n\n\t/* Resolve start/end offset as element indices first; arguments\n\t * at idx_start/idx_end are element offsets.  Working with element\n\t * indices first also avoids potential for wrapping.\n\t */\n\n\tstart_offset = duk_to_int(thr, idx_start);\n\tif (start_offset < 0) {\n\t\tstart_offset = buffer_length + start_offset;\n\t}\n\tif (duk_is_undefined(thr, idx_end)) {\n\t\tend_offset = buffer_length;\n\t} else {\n\t\tend_offset = duk_to_int(thr, idx_end);\n\t\tif (end_offset < 0) {\n\t\t\tend_offset = buffer_length + end_offset;\n\t\t}\n\t}\n\t/* Note: start_offset/end_offset can still be < 0 here. */\n\n\tif (start_offset < 0) {\n\t\tstart_offset = 0;\n\t} else if (start_offset > buffer_length) {\n\t\tstart_offset = buffer_length;\n\t}\n\tif (end_offset < start_offset) {\n\t\tend_offset = start_offset;\n\t} else if (end_offset > buffer_length) {\n\t\tend_offset = buffer_length;\n\t}\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(start_offset <= buffer_length);\n\tDUK_ASSERT(end_offset >= 0);\n\tDUK_ASSERT(end_offset <= buffer_length);\n\tDUK_ASSERT(start_offset <= end_offset);\n\n\t/* Convert indices to byte offsets. */\n\tstart_offset <<= buffer_shift;\n\tend_offset <<= buffer_shift;\n\n\t*out_start_offset = start_offset;\n\t*out_end_offset = end_offset;\n}\n\nDUK_INTERNAL void duk_hbufobj_promote_plain(duk_hthread *thr, duk_idx_t idx) {\n\tif (duk_is_buffer(thr, idx)) {\n\t\tduk_to_object(thr, idx);\n\t}\n}\n\nDUK_INTERNAL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_hbuffer *h_buf) {\n\t/* Push Uint8Array which will share the same underlying buffer as\n\t * the plain buffer argument.  Also create an ArrayBuffer with the\n\t * same backing for the result .buffer property.\n\t */\n\n\tduk_push_hbuffer(thr, h_buf);\n\tduk_push_buffer_object(thr, -1, 0, (duk_size_t) DUK_HBUFFER_GET_SIZE(h_buf), DUK_BUFOBJ_UINT8ARRAY);\n\tduk_remove_m2(thr);\n\n#if 0\n\t/* More verbose equivalent; maybe useful if e.g. .buffer is omitted. */\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_UINT8ARRAY),\n\t                               DUK_BIDX_UINT8ARRAY_PROTOTYPE);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tduk__set_bufobj_buffer(thr, h_bufobj, h_buf);\n\th_bufobj->is_typedarray = 1;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\th_arrbuf = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),\n\t                               DUK_BIDX_ARRAYBUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_arrbuf != NULL);\n\tduk__set_bufobj_buffer(thr, h_arrbuf, h_buf);\n\tDUK_ASSERT(h_arrbuf->is_typedarray == 0);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_arrbuf);\n\n\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\th_bufobj->buf_prop = (duk_hobject *) h_arrbuf;\n\tDUK_ASSERT(h_arrbuf != NULL);\n\tDUK_HBUFOBJ_INCREF(thr, h_arrbuf);\n\tduk_pop(thr);\n#endif\n}\n\n/* Indexed read helper for buffer objects, also called from outside this file. */\nDUK_INTERNAL void duk_hbufobj_push_validated_read(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size) {\n\tduk_double_union du;\n\n\tDUK_ASSERT(elem_size > 0);\n\tduk_memcpy((void *) du.uc, (const void *) p, (size_t) elem_size);\n\n\tswitch (h_bufobj->elem_type) {\n\tcase DUK_HBUFOBJ_ELEM_UINT8:\n\tcase DUK_HBUFOBJ_ELEM_UINT8CLAMPED:\n\t\tduk_push_uint(thr, (duk_uint_t) du.uc[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT8:\n\t\tduk_push_int(thr, (duk_int_t) (duk_int8_t) du.uc[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT16:\n\t\tduk_push_uint(thr, (duk_uint_t) du.us[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT16:\n\t\tduk_push_int(thr, (duk_int_t) (duk_int16_t) du.us[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT32:\n\t\tduk_push_uint(thr, (duk_uint_t) du.ui[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT32:\n\t\tduk_push_int(thr, (duk_int_t) (duk_int32_t) du.ui[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT32:\n\t\tduk_push_number(thr, (duk_double_t) du.f[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT64:\n\t\tduk_push_number(thr, (duk_double_t) du.d);\n\t\tbreak;\n\tdefault:\n\t\tDUK_UNREACHABLE();\n\t}\n}\n\n/* Indexed write helper for buffer objects, also called from outside this file. */\nDUK_INTERNAL void duk_hbufobj_validated_write(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size) {\n\tduk_double_union du;\n\n\t/* NOTE! Caller must ensure that any side effects from the\n\t * coercions below are safe.  If that cannot be guaranteed\n\t * (which is normally the case), caller must coerce the\n\t * argument using duk_to_number() before any pointer\n\t * validations; the result of duk_to_number() always coerces\n\t * without side effects here.\n\t */\n\n\tswitch (h_bufobj->elem_type) {\n\tcase DUK_HBUFOBJ_ELEM_UINT8:\n\t\tdu.uc[0] = (duk_uint8_t) duk_to_uint32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT8CLAMPED:\n\t\tdu.uc[0] = (duk_uint8_t) duk_to_uint8clamped(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT8:\n\t\tdu.uc[0] = (duk_uint8_t) duk_to_int32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT16:\n\t\tdu.us[0] = (duk_uint16_t) duk_to_uint32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT16:\n\t\tdu.us[0] = (duk_uint16_t) duk_to_int32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT32:\n\t\tdu.ui[0] = (duk_uint32_t) duk_to_uint32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT32:\n\t\tdu.ui[0] = (duk_uint32_t) duk_to_int32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT32:\n\t\t/* A double-to-float cast is undefined behavior in C99 if\n\t\t * the cast is out-of-range, so use a helper.  Example:\n\t\t * runtime error: value -1e+100 is outside the range of representable values of type 'float'\n\t\t */\n\t\tdu.f[0] = duk_double_to_float_t(duk_to_number_m1(thr));\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT64:\n\t\tdu.d = (duk_double_t) duk_to_number_m1(thr);\n\t\tbreak;\n\tdefault:\n\t\tDUK_UNREACHABLE();\n\t}\n\n\tDUK_ASSERT(elem_size > 0);\n\tduk_memcpy((void *) p, (const void *) du.uc, (size_t) elem_size);\n}\n\n/* Helper to create a fixed buffer from argument value at index 0.\n * Node.js and allocPlain() compatible.\n */\nDUK_LOCAL duk_hbuffer *duk__hbufobj_fixed_from_argvalue(duk_hthread *thr) {\n\tduk_int_t len;\n\tduk_int_t i;\n\tduk_size_t buf_size;\n\tduk_uint8_t *buf;\n\n\tswitch (duk_get_type(thr, 0)) {\n\tcase DUK_TYPE_NUMBER: {\n\t\tlen = duk_to_int_clamped(thr, 0, 0, DUK_INT_MAX);\n\t\t(void) duk_push_fixed_buffer_zero(thr, (duk_size_t) len);\n\t\tbreak;\n\t}\n\tcase DUK_TYPE_BUFFER: { /* Treat like Uint8Array. */\n\t\tgoto slow_copy;\n\t}\n\tcase DUK_TYPE_OBJECT: {\n\t\tduk_hobject *h;\n\t\tduk_hbufobj *h_bufobj;\n\n\t\t/* For Node.js Buffers \"Passing an ArrayBuffer returns a Buffer\n\t\t * that shares allocated memory with the given ArrayBuffer.\"\n\t\t * https://nodejs.org/api/buffer.html#buffer_buffer_from_buffer_alloc_and_buffer_allocunsafe\n\t\t */\n\n\t\th = duk_known_hobject(thr, 0);\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ(h));\n\t\t\th_bufobj = (duk_hbufobj *) h;\n\t\t\tif (DUK_UNLIKELY(h_bufobj->buf == NULL)) {\n\t\t\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(h_bufobj->offset != 0 || h_bufobj->length != DUK_HBUFFER_GET_SIZE(h_bufobj->buf))) {\n\t\t\t\t/* No support for ArrayBuffers with slice\n\t\t\t\t * offset/length.\n\t\t\t\t */\n\t\t\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t\t}\n\t\t\tduk_push_hbuffer(thr, h_bufobj->buf);\n\t\t\treturn h_bufobj->buf;\n\t\t}\n\t\tgoto slow_copy;\n\t}\n\tcase DUK_TYPE_STRING: {\n\t\t/* ignore encoding for now */\n\t\tduk_require_hstring_notsymbol(thr, 0);\n\t\tduk_dup_0(thr);\n\t\t(void) duk_to_buffer(thr, -1, &buf_size);\n\t\tbreak;\n\t}\n\tdefault:\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n done:\n\tDUK_ASSERT(duk_is_buffer(thr, -1));\n\treturn duk_known_hbuffer(thr, -1);\n\n slow_copy:\n\t/* XXX: fast path for typed arrays and other buffer objects? */\n\n\t(void) duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\tlen = duk_to_int_clamped(thr, -1, 0, DUK_INT_MAX);\n\tduk_pop(thr);\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) len);  /* no zeroing, all indices get initialized */\n\tfor (i = 0; i < len; i++) {\n\t\t/* XXX: fast path for array or buffer arguments? */\n\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);\n\t\tbuf[i] = (duk_uint8_t) (duk_to_uint32(thr, -1) & 0xffU);\n\t\tduk_pop(thr);\n\t}\n\tgoto done;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer constructor\n *\n *  Node.js Buffers are just Uint8Arrays with internal prototype set to\n *  Buffer.prototype so they're handled otherwise the same as Uint8Array.\n *  However, the constructor arguments are very different so a separate\n *  constructor entry point is used.\n */\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_hthread *thr) {\n\tduk_hbuffer *h_buf;\n\n\th_buf = duk__hbufobj_fixed_from_argvalue(thr);\n\tDUK_ASSERT(h_buf != NULL);\n\n\tduk_push_buffer_object(thr,\n\t                       -1,\n\t                       0,\n\t                       DUK_HBUFFER_FIXED_GET_SIZE((duk_hbuffer_fixed *) (void *) h_buf),\n\t                       DUK_BUFOBJ_UINT8ARRAY);\n\tduk_push_hobject_bidx(thr, DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);\n\tduk_set_prototype(thr, -2);\n\n\t/* XXX: a more direct implementation */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  ArrayBuffer, DataView, and TypedArray constructors\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_arraybuffer_constructor(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_int_t len;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tduk_require_constructor_call(thr);\n\n\tlen = duk_to_int(thr, 0);\n\tif (len < 0) {\n\t\tgoto fail_length;\n\t}\n\t(void) duk_push_fixed_buffer_zero(thr, (duk_size_t) len);\n\th_val = (duk_hbuffer *) duk_known_hbuffer(thr, -1);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),\n\t                               DUK_BIDX_ARRAYBUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_bufobj != NULL);\n\n\tduk__set_bufobj_buffer(thr, h_bufobj, h_val);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\treturn 1;\n\n fail_length:\n\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\n/* Format of magic, bits:\n *   0...1: elem size shift (0-3)\n *   2...5: elem type (DUK_HBUFOBJ_ELEM_xxx)\n *\n * XXX: add prototype bidx explicitly to magic instead of using a mapping?\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hobject *h_obj;\n\tduk_hbufobj *h_bufobj = NULL;\n\tduk_hbufobj *h_bufarg = NULL;\n\tduk_hbuffer *h_val;\n\tduk_small_uint_t magic;\n\tduk_small_uint_t shift;\n\tduk_small_uint_t elem_type;\n\tduk_small_uint_t elem_size;\n\tduk_small_uint_t class_num;\n\tduk_small_uint_t proto_bidx;\n\tduk_uint_t align_mask;\n\tduk_uint_t elem_length;\n\tduk_int_t elem_length_signed;\n\tduk_uint_t byte_length;\n\tduk_small_uint_t copy_mode;\n\n\t/* XXX: The same copy helpers could be shared with at least some\n\t * buffer functions.\n\t */\n\n\tduk_require_constructor_call(thr);\n\n\t/* We could fit built-in index into magic but that'd make the magic\n\t * number dependent on built-in numbering (genbuiltins.py doesn't\n\t * handle that yet).  So map both class and prototype from the\n\t * element type.\n\t */\n\tmagic = (duk_small_uint_t) duk_get_current_magic(thr);\n\tshift = magic & 0x03U;               /* bits 0...1: shift */\n\telem_type = (magic >> 2) & 0x0fU;    /* bits 2...5: type */\n\telem_size = 1U << shift;\n\talign_mask = elem_size - 1;\n\tDUK_ASSERT(elem_type < sizeof(duk__buffer_proto_from_elemtype) / sizeof(duk_uint8_t));\n\tproto_bidx = duk__buffer_proto_from_elemtype[elem_type];\n\tDUK_ASSERT(proto_bidx < DUK_NUM_BUILTINS);\n\tDUK_ASSERT(elem_type < sizeof(duk__buffer_class_from_elemtype) / sizeof(duk_uint8_t));\n\tclass_num = duk__buffer_class_from_elemtype[elem_type];\n\n\tDUK_DD(DUK_DDPRINT(\"typedarray constructor, magic=%d, shift=%d, elem_type=%d, \"\n\t                   \"elem_size=%d, proto_bidx=%d, class_num=%d\",\n\t                   (int) magic, (int) shift, (int) elem_type, (int) elem_size,\n\t                   (int) proto_bidx, (int) class_num));\n\n\t/* Argument variants.  When the argument is an ArrayBuffer a view to\n\t * the same buffer is created; otherwise a new ArrayBuffer is always\n\t * created.\n\t */\n\n\t/* XXX: initial iteration to treat a plain buffer like an ArrayBuffer:\n\t * coerce to an ArrayBuffer object and use that as .buffer.  The underlying\n\t * buffer will be the same but result .buffer !== inputPlainBuffer.\n\t */\n\tduk_hbufobj_promote_plain(thr, 0);\n\n\ttv = duk_get_tval(thr, 0);\n\tDUK_ASSERT(tv != NULL);  /* arg count */\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_obj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_obj != NULL);\n\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\t\t/* ArrayBuffer: unlike any other argument variant, create\n\t\t\t * a view into the existing buffer.\n\t\t\t */\n\n\t\t\tduk_int_t byte_offset_signed;\n\t\t\tduk_uint_t byte_offset;\n\n\t\t\th_bufarg = (duk_hbufobj *) h_obj;\n\n\t\t\tbyte_offset_signed = duk_to_int(thr, 1);\n\t\t\tif (byte_offset_signed < 0) {\n\t\t\t\tgoto fail_arguments;\n\t\t\t}\n\t\t\tbyte_offset = (duk_uint_t) byte_offset_signed;\n\t\t\tif (byte_offset > h_bufarg->length ||\n\t\t\t    (byte_offset & align_mask) != 0) {\n\t\t\t\t/* Must be >= 0 and multiple of element size. */\n\t\t\t\tgoto fail_arguments;\n\t\t\t}\n\t\t\tif (duk_is_undefined(thr, 2)) {\n\t\t\t\tDUK_ASSERT(h_bufarg->length >= byte_offset);\n\t\t\t\tbyte_length = h_bufarg->length - byte_offset;\n\t\t\t\tif ((byte_length & align_mask) != 0) {\n\t\t\t\t\t/* Must be element size multiple from\n\t\t\t\t\t * start offset to end of buffer.\n\t\t\t\t\t */\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t\telem_length = (byte_length >> shift);\n\t\t\t} else {\n\t\t\t\telem_length_signed = duk_to_int(thr, 2);\n\t\t\t\tif (elem_length_signed < 0) {\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t\telem_length = (duk_uint_t) elem_length_signed;\n\t\t\t\tbyte_length = elem_length << shift;\n\t\t\t\tif ((byte_length >> shift) != elem_length) {\n\t\t\t\t\t/* Byte length would overflow. */\n\t\t\t\t\t/* XXX: easier check with less code? */\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(h_bufarg->length >= byte_offset);\n\t\t\t\tif (byte_length > h_bufarg->length - byte_offset) {\n\t\t\t\t\t/* Not enough data. */\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t}\n\t\t\tDUK_UNREF(elem_length);\n\t\t\tDUK_ASSERT_DISABLE(byte_offset >= 0);\n\t\t\tDUK_ASSERT(byte_offset <= h_bufarg->length);\n\t\t\tDUK_ASSERT_DISABLE(byte_length >= 0);\n\t\t\tDUK_ASSERT(byte_offset + byte_length <= h_bufarg->length);\n\t\t\tDUK_ASSERT((elem_length << shift) == byte_length);\n\n\t\t\th_bufobj = duk_push_bufobj_raw(thr,\n\t\t\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t\t\t                               DUK_HOBJECT_CLASS_AS_FLAGS(class_num),\n\t\t\t                               (duk_small_int_t) proto_bidx);\n\t\t\th_val = h_bufarg->buf;\n\t\t\tif (h_val == NULL) {\n\t\t\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t}\n\t\t\th_bufobj->buf = h_val;\n\t\t\tDUK_HBUFFER_INCREF(thr, h_val);\n\t\t\th_bufobj->offset = h_bufarg->offset + byte_offset;\n\t\t\th_bufobj->length = byte_length;\n\t\t\th_bufobj->shift = (duk_uint8_t) shift;\n\t\t\th_bufobj->elem_type = (duk_uint8_t) elem_type;\n\t\t\th_bufobj->is_typedarray = 1;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t\t\t/* Set .buffer to the argument ArrayBuffer. */\n\t\t\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\t\t\th_bufobj->buf_prop = (duk_hobject *) h_bufarg;\n\t\t\tDUK_ASSERT(h_bufarg != NULL);\n\t\t\tDUK_HBUFOBJ_INCREF(thr, h_bufarg);\n\t\t\treturn 1;\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\t/* TypedArray (or other non-ArrayBuffer duk_hbufobj).\n\t\t\t * Conceptually same behavior as for an Array-like argument,\n\t\t\t * with a few fast paths.\n\t\t\t */\n\n\t\t\th_bufarg = (duk_hbufobj *) h_obj;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufarg);\n\t\t\telem_length_signed = (duk_int_t) (h_bufarg->length >> h_bufarg->shift);\n\t\t\tif (h_bufarg->buf == NULL) {\n\t\t\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t}\n\n\t\t\t/* Select copy mode.  Must take into account element\n\t\t\t * compatibility and validity of the underlying source\n\t\t\t * buffer.\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"selecting copy mode for bufobj arg, \"\n\t\t\t                     \"src byte_length=%ld, src shift=%d, \"\n\t\t\t                     \"src/dst elem_length=%ld; \"\n\t\t\t                     \"dst shift=%d -> dst byte_length=%ld\",\n\t\t\t                     (long) h_bufarg->length, (int) h_bufarg->shift,\n\t\t\t                     (long) elem_length_signed, (int) shift,\n\t\t\t                     (long) (elem_length_signed << shift)));\n\n\t\t\tcopy_mode = 2;  /* default is explicit index read/write copy */\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t/* With a size optimized build copy_mode 2 is enough.\n\t\t\t * Modes 0 and 1 are faster but conceptually the same.\n\t\t\t */\n\t\t\tDUK_ASSERT(elem_type < sizeof(duk__buffer_elemtype_copy_compatible) / sizeof(duk_uint16_t));\n\t\t\tif (DUK_HBUFOBJ_VALID_SLICE(h_bufarg)) {\n\t\t\t\tif ((duk__buffer_elemtype_copy_compatible[elem_type] & (1 << h_bufarg->elem_type)) != 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"source/target are copy compatible, memcpy\"));\n\t\t\t\t\tDUK_ASSERT(shift == h_bufarg->shift);  /* byte sizes will match */\n\t\t\t\t\tcopy_mode = 0;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"source/target not copy compatible but valid, fast copy\"));\n\t\t\t\t\tcopy_mode = 1;\n\t\t\t\t}\n\t\t\t}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\t\t} else {\n\t\t\t/* Array or Array-like */\n\t\t\telem_length_signed = (duk_int_t) duk_get_length(thr, 0);\n\t\t\tcopy_mode = 2;\n\t\t}\n\t} else {\n\t\t/* Non-object argument is simply int coerced, matches\n\t\t * V8 behavior (except for \"null\", which we coerce to\n\t\t * 0 but V8 TypeErrors).\n\t\t */\n\t\telem_length_signed = duk_to_int(thr, 0);\n\t\tcopy_mode = 3;\n\t}\n\tif (elem_length_signed < 0) {\n\t\tgoto fail_arguments;\n\t}\n\telem_length = (duk_uint_t) elem_length_signed;\n\tbyte_length = (duk_uint_t) (elem_length << shift);\n\tif ((byte_length >> shift) != elem_length) {\n\t\t/* Byte length would overflow. */\n\t\t/* XXX: easier check with less code? */\n\t\tgoto fail_arguments;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"elem_length=%ld, byte_length=%ld\",\n\t                     (long) elem_length, (long) byte_length));\n\n\t/* ArrayBuffer argument is handled specially above; the rest of the\n\t * argument variants are handled by shared code below.\n\t *\n\t * ArrayBuffer in h_bufobj->buf_prop is intentionally left unset.\n\t * It will be automatically created by the .buffer accessor on\n\t * first access.\n\t */\n\n\t/* Push the resulting view object on top of a plain fixed buffer. */\n\t(void) duk_push_fixed_buffer(thr, byte_length);\n\th_val = duk_known_hbuffer(thr, -1);\n\tDUK_ASSERT(h_val != NULL);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(class_num),\n\t                               (duk_small_int_t) proto_bidx);\n\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\tDUK_ASSERT(h_bufobj->offset == 0);\n\th_bufobj->length = byte_length;\n\th_bufobj->shift = (duk_uint8_t) shift;\n\th_bufobj->elem_type = (duk_uint8_t) elem_type;\n\th_bufobj->is_typedarray = 1;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t/* Copy values, the copy method depends on the arguments.\n\t *\n\t * Copy mode decision may depend on the validity of the underlying\n\t * buffer of the source argument; there must be no harmful side effects\n\t * from there to here for copy_mode to still be valid.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"copy mode: %d\", (int) copy_mode));\n\tswitch (copy_mode) {\n\t\t/* Copy modes 0 and 1 can be omitted in size optimized build,\n\t\t * copy mode 2 handles them (but more slowly).\n\t\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tcase 0: {\n\t\t/* Use byte copy. */\n\n\t\tduk_uint8_t *p_src;\n\t\tduk_uint8_t *p_dst;\n\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\t\tDUK_ASSERT(h_bufobj->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufobj));\n\t\tDUK_ASSERT(h_bufarg != NULL);\n\t\tDUK_ASSERT(h_bufarg->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufarg));\n\n\t\tp_dst = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj);\n\t\tp_src = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using memcpy: p_src=%p, p_dst=%p, byte_length=%ld\",\n\t\t                     (void *) p_src, (void *) p_dst, (long) byte_length));\n\n\t\tduk_memcpy_unsafe((void *) p_dst, (const void *) p_src, (size_t) byte_length);\n\t\tbreak;\n\t}\n\tcase 1: {\n\t\t/* Copy values through direct validated reads and writes. */\n\n\t\tduk_small_uint_t src_elem_size;\n\t\tduk_small_uint_t dst_elem_size;\n\t\tduk_uint8_t *p_src;\n\t\tduk_uint8_t *p_src_end;\n\t\tduk_uint8_t *p_dst;\n\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\t\tDUK_ASSERT(h_bufobj->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufobj));\n\t\tDUK_ASSERT(h_bufarg != NULL);\n\t\tDUK_ASSERT(h_bufarg->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufarg));\n\n\t\tsrc_elem_size = (duk_small_uint_t) (1U << h_bufarg->shift);\n\t\tdst_elem_size = elem_size;\n\n\t\tp_src = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg);\n\t\tp_dst = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj);\n\t\tp_src_end = p_src + h_bufarg->length;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using fast copy: p_src=%p, p_src_end=%p, p_dst=%p, \"\n\t\t                     \"src_elem_size=%d, dst_elem_size=%d\",\n\t\t                     (void *) p_src, (void *) p_src_end, (void *) p_dst,\n\t\t                     (int) src_elem_size, (int) dst_elem_size));\n\n\t\twhile (p_src != p_src_end) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path per element copy loop: \"\n\t\t\t                     \"p_src=%p, p_src_end=%p, p_dst=%p\",\n\t\t\t                     (void *) p_src, (void *) p_src_end, (void *) p_dst));\n\t\t\t/* A validated read() is always a number, so it's write coercion\n\t\t\t * is always side effect free an won't invalidate pointers etc.\n\t\t\t */\n\t\t\tduk_hbufobj_push_validated_read(thr, h_bufarg, p_src, src_elem_size);\n\t\t\tduk_hbufobj_validated_write(thr, h_bufobj, p_dst, dst_elem_size);\n\t\t\tduk_pop(thr);\n\t\t\tp_src += src_elem_size;\n\t\t\tp_dst += dst_elem_size;\n\t\t}\n\t\tbreak;\n\t}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\tcase 2: {\n\t\t/* Copy values by index reads and writes.  Let virtual\n\t\t * property handling take care of coercion.\n\t\t */\n\t\tduk_uint_t i;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using slow copy\"));\n\n\t\tfor (i = 0; i < elem_length; i++) {\n\t\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);\n\t\t\tduk_put_prop_index(thr, -2, (duk_uarridx_t) i);\n\t\t}\n\t\tbreak;\n\t}\n\tdefault:\n\tcase 3: {\n\t\t/* No copy, leave zero bytes in the buffer.  There's no\n\t\t * ambiguity with Float32/Float64 because zero bytes also\n\t\t * represent 0.0.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using no copy\"));\n\t\tbreak;\n\t}\n\t}\n\n\treturn 1;\n\n fail_arguments:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n/* When bufferobject support is disabled, new Uint8Array() could still be\n * supported to create a plain fixed buffer.  Disabled for now.\n */\n#if 0\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) {\n\tduk_int_t elem_length_signed;\n\tduk_uint_t byte_length;\n\n\t/* XXX: The same copy helpers could be shared with at least some\n\t * buffer functions.\n\t */\n\n\tduk_require_constructor_call(thr);\n\n\telem_length_signed = duk_require_int(thr, 0);\n\tif (elem_length_signed < 0) {\n\t\tgoto fail_arguments;\n\t}\n\tbyte_length = (duk_uint_t) elem_length_signed;\n\n\t(void) duk_push_fixed_buffer_zero(thr, (duk_size_t) byte_length);\n\treturn 1;\n\n fail_arguments:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* 0 */\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_dataview_constructor(duk_hthread *thr) {\n\tduk_hbufobj *h_bufarg;\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_uint_t offset;\n\tduk_uint_t length;\n\n\tduk_require_constructor_call(thr);\n\n\th_bufarg = duk__require_bufobj_value(thr, 0);\n\tDUK_ASSERT(h_bufarg != NULL);\n\tif (DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *) h_bufarg) != DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tduk__resolve_offset_opt_length(thr, h_bufarg, 1, 2, &offset, &length, 1 /*throw_flag*/);\n\tDUK_ASSERT(offset <= h_bufarg->length);\n\tDUK_ASSERT(offset + length <= h_bufarg->length);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATAVIEW),\n\t                               DUK_BIDX_DATAVIEW_PROTOTYPE);\n\n\th_val = h_bufarg->buf;\n\tif (h_val == NULL) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\th_bufobj->offset = h_bufarg->offset + offset;\n\th_bufobj->length = length;\n\tDUK_ASSERT(h_bufobj->shift == 0);\n\tDUK_ASSERT(h_bufobj->elem_type == DUK_HBUFOBJ_ELEM_UINT8);\n\tDUK_ASSERT(h_bufobj->is_typedarray == 0);\n\n\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\th_bufobj->buf_prop = (duk_hobject *) h_bufarg;\n\tDUK_ASSERT(h_bufarg != NULL);\n\tDUK_HBUFOBJ_INCREF(thr, h_bufarg);\n\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  ArrayBuffer.isView()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_arraybuffer_isview(duk_hthread *thr) {\n\tduk_hobject *h_obj;\n\tduk_bool_t ret = 0;\n\n\tif (duk_is_buffer(thr, 0)) {\n\t\tret = 1;\n\t} else {\n\t\th_obj = duk_get_hobject(thr, 0);\n\t\tif (h_obj != NULL && DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\t/* DataView needs special casing: ArrayBuffer.isView() is\n\t\t\t * true, but ->is_typedarray is 0.\n\t\t\t */\n\t\t\tret = ((duk_hbufobj *) h_obj)->is_typedarray ||\n\t\t\t      (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_DATAVIEW);\n\t\t}\n\t}\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Uint8Array.allocPlain()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_uint8array_allocplain(duk_hthread *thr) {\n\tduk__hbufobj_fixed_from_argvalue(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Uint8Array.plainOf()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_uint8array_plainof(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\t/* Avoid churn if argument is already a plain buffer. */\n\tif (duk_is_buffer(thr, 0)) {\n\t\treturn 1;\n\t}\n#endif\n\n\t/* Promotes plain buffers to ArrayBuffers, so for a plain buffer\n\t * argument we'll create a pointless temporary (but still work\n\t * correctly).\n\t */\n\th_bufobj = duk__require_bufobj_value(thr, 0);\n\tif (h_bufobj->buf == NULL) {\n\t\tduk_push_undefined(thr);\n\t} else {\n\t\tduk_push_hbuffer(thr, h_bufobj->buf);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer: toString([encoding], [start], [end])\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_int_t start_offset, end_offset;\n\tduk_uint8_t *buf_slice;\n\tduk_size_t slice_length;\n\n\th_this = duk__get_bufobj_this(thr);\n\tif (h_this == NULL) {\n\t\t/* XXX: happens e.g. when evaluating: String(Buffer.prototype). */\n\t\tduk_push_literal(thr, \"[object Object]\");\n\t\treturn 1;\n\t}\n\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\n\t/* Ignore encoding for now. */\n\n\tduk__clamp_startend_nonegidx_noshift(thr,\n\t                                     (duk_int_t) h_this->length,\n\t                                     1 /*idx_start*/,\n\t                                     2 /*idx_end*/,\n\t                                     &start_offset,\n\t                                     &end_offset);\n\n\tslice_length = (duk_size_t) (end_offset - start_offset);\n\tbuf_slice = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, slice_length);  /* all bytes initialized below */\n\tDUK_ASSERT(buf_slice != NULL);\n\n\t/* Neutered or uncovered, TypeError. */\n\tif (h_this->buf == NULL ||\n\t    !DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, (duk_size_t) start_offset + slice_length)) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* XXX: ideally we wouldn't make a copy but a view into the buffer for the\n\t * decoding process.  Or the decoding helper could be changed to accept\n\t * the slice info (a buffer pointer is NOT a good approach because guaranteeing\n\t * its stability is difficult).\n\t */\n\n\tDUK_ASSERT(DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, (duk_size_t) start_offset + slice_length));\n\tduk_memcpy_unsafe((void *) buf_slice,\n\t                  (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + start_offset),\n\t                  (size_t) slice_length);\n\n\t/* Use the equivalent of: new TextEncoder().encode(this) to convert the\n\t * string.  Result will be valid UTF-8; non-CESU-8 inputs are currently\n\t * interpreted loosely.  Value stack convention is a bit odd for now.\n\t */\n\tduk_replace(thr, 0);\n\tduk_set_top(thr, 1);\n\treturn duk_textdecoder_decode_utf8_nodejs(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype: toJSON()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_uint8_t *buf;\n\tduk_uint_t i, n;\n\tduk_tval *tv;\n\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\n\tif (h_this->buf == NULL || !DUK_HBUFOBJ_VALID_SLICE(h_this)) {\n\t\t/* Serialize uncovered backing buffer as a null; doesn't\n\t\t * really matter as long we're memory safe.\n\t\t */\n\t\tduk_push_null(thr);\n\t\treturn 1;\n\t}\n\n\tduk_push_object(thr);\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_BUFFER);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_TYPE);\n\n\t/* XXX: uninitialized would be OK */\n\tDUK_ASSERT_DISABLE((duk_size_t) h_this->length <= (duk_size_t) DUK_UINT32_MAX);\n\ttv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) h_this->length);  /* XXX: needs revision with >4G buffers */\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\tDUK_ASSERT(h_this->buf != NULL);\n\tbuf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this);\n\tfor (i = 0, n = h_this->length; i < n; i++) {\n\t\tDUK_TVAL_SET_U32(tv + i, (duk_uint32_t) buf[i]);  /* no need for decref or incref */\n\t}\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_DATA);\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.equals()\n *  Node.js Buffer.prototype.compare()\n *  Node.js Buffer.compare()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_buffer_compare_shared(duk_hthread *thr) {\n\tduk_small_uint_t magic;\n\tduk_hbufobj *h_bufarg1;\n\tduk_hbufobj *h_bufarg2;\n\tduk_small_int_t comp_res;\n\n\t/* XXX: keep support for plain buffers and non-Node.js buffers? */\n\n\tmagic = (duk_small_uint_t) duk_get_current_magic(thr);\n\tif (magic & 0x02U) {\n\t\t/* Static call style. */\n\t\th_bufarg1 = duk__require_bufobj_value(thr, 0);\n\t\th_bufarg2 = duk__require_bufobj_value(thr, 1);\n\t} else {\n\t\th_bufarg1 = duk__require_bufobj_this(thr);\n\t\th_bufarg2 = duk__require_bufobj_value(thr, 0);\n\t}\n\tDUK_ASSERT(h_bufarg1 != NULL);\n\tDUK_ASSERT(h_bufarg2 != NULL);\n\n\t/* We want to compare the slice/view areas of the arguments.\n\t * If either slice/view is invalid (underlying buffer is shorter)\n\t * ensure equals() is false, but otherwise the only thing that\n\t * matters is to be memory safe.\n\t */\n\n\tif (DUK_HBUFOBJ_VALID_SLICE(h_bufarg1) &&\n\t    DUK_HBUFOBJ_VALID_SLICE(h_bufarg2)) {\n\t\tcomp_res = duk_js_data_compare((const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufarg1->buf) + h_bufarg1->offset,\n\t\t                               (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufarg2->buf) + h_bufarg2->offset,\n\t\t                               (duk_size_t) h_bufarg1->length,\n\t\t                               (duk_size_t) h_bufarg2->length);\n\t} else {\n\t\tcomp_res = -1;  /* either nonzero value is ok */\n\t}\n\n\tif (magic & 0x01U) {\n\t\t/* compare: similar to string comparison but for buffer data. */\n\t\tduk_push_int(thr, comp_res);\n\t} else {\n\t\t/* equals */\n\t\tduk_push_boolean(thr, (comp_res == 0));\n\t}\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.fill()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tconst duk_uint8_t *fill_str_ptr;\n\tduk_size_t fill_str_len;\n\tduk_uint8_t fill_value;\n\tduk_int_t fill_offset;\n\tduk_int_t fill_end;\n\tduk_size_t fill_length;\n\tduk_uint8_t *p;\n\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\tif (h_this->buf == NULL) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* [ value offset end ] */\n\n\tif (duk_is_string_notsymbol(thr, 0)) {\n\t\tfill_str_ptr = (const duk_uint8_t *) duk_get_lstring(thr, 0, &fill_str_len);\n\t\tDUK_ASSERT(fill_str_ptr != NULL);\n\t} else {\n\t\t/* Symbols get ToNumber() coerced and cause TypeError. */\n\t\tfill_value = (duk_uint8_t) duk_to_uint32(thr, 0);\n\t\tfill_str_ptr = (const duk_uint8_t *) &fill_value;\n\t\tfill_str_len = 1;\n\t}\n\n\t/* Fill offset handling is more lenient than in Node.js. */\n\n\tduk__clamp_startend_nonegidx_noshift(thr,\n\t                                     (duk_int_t) h_this->length,\n\t                                     1 /*idx_start*/,\n\t                                     2 /*idx_end*/,\n\t                                     &fill_offset,\n\t                                     &fill_end);\n\n\tDUK_DDD(DUK_DDDPRINT(\"fill: fill_value=%02x, fill_offset=%ld, fill_end=%ld, view length=%ld\",\n\t                     (unsigned int) fill_value, (long) fill_offset, (long) fill_end, (long) h_this->length));\n\n\tDUK_ASSERT(fill_end - fill_offset >= 0);\n\tDUK_ASSERT(h_this->buf != NULL);\n\n\tp = (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + fill_offset);\n\tfill_length = (duk_size_t) (fill_end - fill_offset);\n\tif (fill_str_len == 1) {\n\t\t/* Handle single character fills as memset() even when\n\t\t * the fill data comes from a one-char argument.\n\t\t */\n\t\tduk_memset_unsafe((void *) p, (int) fill_str_ptr[0], (size_t) fill_length);\n\t} else if (fill_str_len > 1) {\n\t\tduk_size_t i, n, t;\n\n\t\tfor (i = 0, n = (duk_size_t) (fill_end - fill_offset), t = 0; i < n; i++) {\n\t\t\tp[i] = fill_str_ptr[t++];\n\t\t\tif (t >= fill_str_len) {\n\t\t\t\tt = 0;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"zero size fill pattern, ignore silently\"));\n\t}\n\n\t/* Return the Buffer to allow chaining: b.fill(0x11).fill(0x22, 3, 5).toString() */\n\tduk_push_this(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.write(string, [offset], [length], [encoding])\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_write(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_uint_t offset;\n\tduk_uint_t length;\n\tconst duk_uint8_t *str_data;\n\tduk_size_t str_len;\n\n\t/* XXX: very inefficient support for plain buffers */\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\n\t/* Argument must be a string, e.g. a buffer is not allowed. */\n\tstr_data = (const duk_uint8_t *) duk_require_lstring_notsymbol(thr, 0, &str_len);\n\n\tduk__resolve_offset_opt_length(thr, h_this, 1, 2, &offset, &length, 0 /*throw_flag*/);\n\tDUK_ASSERT(offset <= h_this->length);\n\tDUK_ASSERT(offset + length <= h_this->length);\n\n\t/* XXX: encoding is ignored now. */\n\n\tif (length > str_len) {\n\t\tlength = (duk_uint_t) str_len;\n\t}\n\n\tif (DUK_HBUFOBJ_VALID_SLICE(h_this)) {\n\t\t/* Cannot overlap. */\n\t\tduk_memcpy_unsafe((void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + offset),\n\t\t                  (const void *) str_data,\n\t\t                  (size_t) length);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"write() target buffer is not covered, silent ignore\"));\n\t}\n\n\tduk_push_uint(thr, length);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.copy()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_hbufobj *h_bufarg;\n\tduk_int_t source_length;\n\tduk_int_t target_length;\n\tduk_int_t target_start, source_start, source_end;\n\tduk_uint_t target_ustart, source_ustart, source_uend;\n\tduk_uint_t copy_size = 0;\n\n\t/* [ targetBuffer targetStart sourceStart sourceEnd ] */\n\n\th_this = duk__require_bufobj_this(thr);\n\th_bufarg = duk__require_bufobj_value(thr, 0);\n\tDUK_ASSERT(h_this != NULL);\n\tDUK_ASSERT(h_bufarg != NULL);\n\tsource_length = (duk_int_t) h_this->length;\n\ttarget_length = (duk_int_t) h_bufarg->length;\n\n\ttarget_start = duk_to_int(thr, 1);\n\tsource_start = duk_to_int(thr, 2);\n\tif (duk_is_undefined(thr, 3)) {\n\t\tsource_end = source_length;\n\t} else {\n\t\tsource_end = duk_to_int(thr, 3);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"checking copy args: target_start=%ld, target_length=%ld, \"\n\t                     \"source_start=%ld, source_end=%ld, source_length=%ld\",\n\t                     (long) target_start, (long) h_bufarg->length,\n\t                     (long) source_start, (long) source_end, (long) source_length));\n\n\t/* This behavior mostly mimics Node.js now. */\n\n\tif (source_start < 0 || source_end < 0 || target_start < 0) {\n\t\t/* Negative offsets cause a RangeError. */\n\t\tgoto fail_bounds;\n\t}\n\tsource_ustart = (duk_uint_t) source_start;\n\tsource_uend = (duk_uint_t) source_end;\n\ttarget_ustart = (duk_uint_t) target_start;\n\tif (source_ustart >= source_uend ||  /* crossed offsets or zero size */\n\t    source_ustart >= (duk_uint_t) source_length ||  /* source out-of-bounds (but positive) */\n\t    target_ustart >= (duk_uint_t) target_length) {  /* target out-of-bounds (but positive) */\n\t\tgoto silent_ignore;\n\t}\n\tif (source_uend >= (duk_uint_t) source_length) {\n\t\t/* Source end clamped silently to available length. */\n\t\tsource_uend = (duk_uint_t) source_length;\n\t}\n\tcopy_size = source_uend - source_ustart;\n\tif (target_ustart + copy_size > (duk_uint_t) target_length) {\n\t\t/* Clamp to target's end if too long.\n\t\t *\n\t\t * NOTE: there's no overflow possibility in the comparison;\n\t\t * both target_ustart and copy_size are >= 0 and based on\n\t\t * values in duk_int_t range.  Adding them as duk_uint_t\n\t\t * values is then guaranteed not to overflow.\n\t\t */\n\t\tDUK_ASSERT(target_ustart + copy_size >= target_ustart);  /* no overflow */\n\t\tDUK_ASSERT(target_ustart + copy_size >= copy_size);  /* no overflow */\n\t\tcopy_size = (duk_uint_t) target_length - target_ustart;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"making copy: target_ustart=%lu source_ustart=%lu copy_size=%lu\",\n\t                     (unsigned long) target_ustart, (unsigned long) source_ustart,\n\t                     (unsigned long) copy_size));\n\n\tDUK_ASSERT(copy_size >= 1);\n\tDUK_ASSERT(source_ustart <= (duk_uint_t) source_length);\n\tDUK_ASSERT(source_ustart + copy_size <= (duk_uint_t) source_length);\n\tDUK_ASSERT(target_ustart <= (duk_uint_t) target_length);\n\tDUK_ASSERT(target_ustart + copy_size <= (duk_uint_t) target_length);\n\n\t/* Ensure copy is covered by underlying buffers. */\n\tDUK_ASSERT(h_bufarg->buf != NULL);  /* length check */\n\tDUK_ASSERT(h_this->buf != NULL);    /* length check */\n\tif (DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufarg, target_ustart + copy_size) &&\n\t    DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, source_ustart + copy_size)) {\n\t\t/* Must use memmove() because copy area may overlap (source and target\n\t\t * buffer may be the same, or from different slices.\n\t\t */\n\t\tduk_memmove_unsafe((void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg) + target_ustart),\n\t\t                   (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + source_ustart),\n\t\t                   (size_t) copy_size);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"buffer copy not covered by underlying buffer(s), ignoring\"));\n\t}\n\n silent_ignore:\n\t/* Return value is like write(), number of bytes written.\n\t * The return value matters because of code like:\n\t * \"off += buf.copy(...)\".\n         */\n\tduk_push_uint(thr, copy_size);\n\treturn 1;\n\n fail_bounds:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  TypedArray.prototype.set()\n *\n *  TypedArray set() is pretty interesting to implement because:\n *\n *    - The source argument may be a plain array or a typedarray.  If the\n *      source is a TypedArray, values are decoded and re-encoded into the\n *      target (not as a plain byte copy).  This may happen even when the\n *      element byte size is the same, e.g. integer values may be re-encoded\n *      into floats.\n *\n *    - Source and target may refer to the same underlying buffer, so that\n *      the set() operation may overlap.  The specification requires that this\n *      must work as if a copy was made before the operation.  Note that this\n *      is NOT a simple memmove() situation because the source and target\n *      byte sizes may be different -- e.g. a 4-byte source (Int8Array) may\n *      expand to a 16-byte target (Uint32Array) so that the target overlaps\n *      the source both from beginning and the end (unlike in typical memmove).\n *\n *    - Even if 'buf' pointers of the source and target differ, there's no\n *      guarantee that their memory areas don't overlap.  This may be the\n *      case with external buffers.\n *\n *  Even so, it is nice to optimize for the common case:\n *\n *    - Source and target separate buffers or non-overlapping.\n *\n *    - Source and target have a compatible type so that a plain byte copy\n *      is possible.  Note that while e.g. uint8 and int8 are compatible\n *      (coercion one way or another doesn't change the byte representation),\n *      e.g. int8 and uint8clamped are NOT compatible when writing int8\n *      values into uint8clamped typedarray (-1 would clamp to 0 for instance).\n *\n *  See test-bi-typedarray-proto-set.js.\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_hobject *h_obj;\n\tduk_uarridx_t i, n;\n\tduk_int_t offset_signed;\n\tduk_uint_t offset_elems;\n\tduk_uint_t offset_bytes;\n\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\n\tif (h_this->buf == NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"source neutered, skip copy\"));\n\t\treturn 0;\n\t}\n\n\tduk_hbufobj_promote_plain(thr, 0);\n\th_obj = duk_require_hobject(thr, 0);\n\n\t/* XXX: V8 throws a TypeError for negative values.  Would it\n\t * be more useful to interpret negative offsets here from the\n\t * end of the buffer too?\n\t */\n\toffset_signed = duk_to_int(thr, 1);\n\tif (offset_signed < 0) {\n\t\t/* For some reason this is a TypeError (at least in V8). */\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\toffset_elems = (duk_uint_t) offset_signed;\n\toffset_bytes = offset_elems << h_this->shift;\n\tif ((offset_bytes >> h_this->shift) != offset_elems) {\n\t\t/* Byte length would overflow. */\n\t\t/* XXX: easier check with less code? */\n\t\tgoto fail_args;\n\t}\n\tif (offset_bytes > h_this->length) {\n\t\t/* Equality may be OK but >length not.  Checking\n\t\t * this explicitly avoids some overflow cases\n\t\t * below.\n\t\t */\n\t\tgoto fail_args;\n\t}\n\tDUK_ASSERT(offset_bytes <= h_this->length);\n\n\t/* Fast path: source is a TypedArray (or any bufobj). */\n\n\tif (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\tduk_hbufobj *h_bufarg;\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\tduk_uint16_t comp_mask;\n#endif\n\t\tduk_small_int_t no_overlap = 0;\n\t\tduk_uint_t src_length;\n\t\tduk_uint_t dst_length;\n\t\tduk_uint_t dst_length_elems;\n\t\tduk_uint8_t *p_src_base;\n\t\tduk_uint8_t *p_src_end;\n\t\tduk_uint8_t *p_src;\n\t\tduk_uint8_t *p_dst_base;\n\t\tduk_uint8_t *p_dst;\n\t\tduk_small_uint_t src_elem_size;\n\t\tduk_small_uint_t dst_elem_size;\n\n\t\th_bufarg = (duk_hbufobj *) h_obj;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufarg);\n\n\t\tif (h_bufarg->buf == NULL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"target neutered, skip copy\"));\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* Nominal size check. */\n\t\tsrc_length = h_bufarg->length;  /* bytes in source */\n\t\tdst_length_elems = (src_length >> h_bufarg->shift);  /* elems in source and dest */\n\t\tdst_length = dst_length_elems << h_this->shift;  /* bytes in dest */\n\t\tif ((dst_length >> h_this->shift) != dst_length_elems) {\n\t\t\t/* Byte length would overflow. */\n\t\t\t/* XXX: easier check with less code? */\n\t\t\tgoto fail_args;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"nominal size check: src_length=%ld, dst_length=%ld\",\n\t\t                     (long) src_length, (long) dst_length));\n\t\tDUK_ASSERT(offset_bytes <= h_this->length);\n\t\tif (dst_length > h_this->length - offset_bytes) {\n\t\t\t/* Overflow not an issue because subtraction is used on the right\n\t\t\t * side and guaranteed to be >= 0.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copy exceeds target buffer nominal length\"));\n\t\t\tgoto fail_args;\n\t\t}\n\t\tif (!DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, offset_bytes + dst_length)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copy not covered by underlying target buffer, ignore\"));\n\t\t\treturn 0;\n\t\t}\n\n\t\tp_src_base = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg);\n\t\tp_dst_base = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + offset_bytes;\n\n\t\t/* Check actual underlying buffers for validity and that they\n\t\t * cover the copy.  No side effects are allowed after the check\n\t\t * so that the validity status doesn't change.\n\t\t */\n\t\tif (!DUK_HBUFOBJ_VALID_SLICE(h_this) ||\n\t\t    !DUK_HBUFOBJ_VALID_SLICE(h_bufarg)) {\n\t\t\t/* The condition could be more narrow and check for the\n\t\t\t * copy area only, but there's no need for fine grained\n\t\t\t * behavior when the underlying buffer is misconfigured.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"source and/or target not covered by underlying buffer, skip copy\"));\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* We want to do a straight memory copy if possible: this is\n\t\t * an important operation because .set() is the TypedArray\n\t\t * way to copy chunks of memory.  However, because set()\n\t\t * conceptually works in terms of elements, not all views are\n\t\t * compatible with direct byte copying.\n\t\t *\n\t\t * If we do manage a direct copy, the \"overlap issue\" handled\n\t\t * below can just be solved using memmove() because the source\n\t\t * and destination element sizes are necessarily equal.\n\t\t */\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\tDUK_ASSERT(h_this->elem_type < sizeof(duk__buffer_elemtype_copy_compatible) / sizeof(duk_uint16_t));\n\t\tcomp_mask = duk__buffer_elemtype_copy_compatible[h_this->elem_type];\n\t\tif (comp_mask & (1 << h_bufarg->elem_type)) {\n\t\t\tDUK_ASSERT(src_length == dst_length);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path: able to use memmove() because views are compatible\"));\n\t\t\tduk_memmove_unsafe((void *) p_dst_base, (const void *) p_src_base, (size_t) dst_length);\n\t\t\treturn 0;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"fast path: views are not compatible with a byte copy, copy by item\"));\n#endif  /* !DUK_USE_PREFER_SIZE */\n\n\t\t/* We want to avoid making a copy to process set() but that's\n\t\t * not always possible: the source and the target may overlap\n\t\t * and because element sizes are different, the overlap cannot\n\t\t * always be handled with a memmove() or choosing the copy\n\t\t * direction in a certain way.  For example, if source type is\n\t\t * uint8 and target type is uint32, the target area may exceed\n\t\t * the source area from both ends!\n\t\t *\n\t\t * Note that because external buffers may point to the same\n\t\t * memory areas, we must ultimately make this check using\n\t\t * pointers.\n\t\t *\n\t\t * NOTE: careful with side effects: any side effect may cause\n\t\t * a buffer resize (or external buffer pointer/length update)!\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"overlap check: p_src_base=%p, src_length=%ld, \"\n\t\t                     \"p_dst_base=%p, dst_length=%ld\",\n\t\t                     (void *) p_src_base, (long) src_length,\n\t\t                     (void *) p_dst_base, (long) dst_length));\n\n\t\tif (p_src_base >= p_dst_base + dst_length ||  /* source starts after dest ends */\n\t\t    p_src_base + src_length <= p_dst_base) {   /* source ends before dest starts */\n\t\t\tno_overlap = 1;\n\t\t}\n\n\t\tif (!no_overlap) {\n\t\t\t/* There's overlap: the desired end result is that\n\t\t\t * conceptually a copy is made to avoid \"trampling\"\n\t\t\t * of source data by destination writes.  We make\n\t\t\t * an actual temporary copy to handle this case.\n\t\t\t */\n\t\t\tduk_uint8_t *p_src_copy;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"there is overlap, make a copy of the source\"));\n\t\t\tp_src_copy = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, src_length);\n\t\t\tDUK_ASSERT(p_src_copy != NULL);\n\t\t\tduk_memcpy_unsafe((void *) p_src_copy, (const void *) p_src_base, (size_t) src_length);\n\n\t\t\tp_src_base = p_src_copy;  /* use p_src_base from now on */\n\t\t}\n\t\t/* Value stack intentionally mixed size here. */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"after overlap check: p_src_base=%p, src_length=%ld, \"\n\t\t                     \"p_dst_base=%p, dst_length=%ld, valstack top=%ld\",\n\t\t                     (void *) p_src_base, (long) src_length,\n\t\t                     (void *) p_dst_base, (long) dst_length,\n\t\t                     (long) duk_get_top(thr)));\n\n\t\t/* Ready to make the copy.  We must proceed element by element\n\t\t * and must avoid any side effects that might cause the buffer\n\t\t * validity check above to become invalid.\n\t\t *\n\t\t * Although we work through the value stack here, only plain\n\t\t * numbers are handled which should be side effect safe.\n\t\t */\n\n\t\tsrc_elem_size = (duk_small_uint_t) (1U << h_bufarg->shift);\n\t\tdst_elem_size = (duk_small_uint_t) (1U << h_this->shift);\n\t\tp_src = p_src_base;\n\t\tp_dst = p_dst_base;\n\t\tp_src_end = p_src_base + src_length;\n\n\t\twhile (p_src != p_src_end) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path per element copy loop: \"\n\t\t\t                     \"p_src=%p, p_src_end=%p, p_dst=%p\",\n\t\t\t                     (void *) p_src, (void *) p_src_end, (void *) p_dst));\n\t\t\t/* A validated read() is always a number, so it's write coercion\n\t\t\t * is always side effect free an won't invalidate pointers etc.\n\t\t\t */\n\t\t\tduk_hbufobj_push_validated_read(thr, h_bufarg, p_src, src_elem_size);\n\t\t\tduk_hbufobj_validated_write(thr, h_this, p_dst, dst_elem_size);\n\t\t\tduk_pop(thr);\n\t\t\tp_src += src_elem_size;\n\t\t\tp_dst += dst_elem_size;\n\t\t}\n\n\t\treturn 0;\n\t} else {\n\t\t/* Slow path: quite slow, but we save space by using the property code\n\t\t * to write coerce target values.  We don't need to worry about overlap\n\t\t * here because the source is not a TypedArray.\n\t\t *\n\t\t * We could use the bufobj write coercion helper but since the\n\t\t * property read may have arbitrary side effects, full validity checks\n\t\t * would be needed for every element anyway.\n\t\t */\n\n\t\tn = (duk_uarridx_t) duk_get_length(thr, 0);\n\t\tDUK_ASSERT(offset_bytes <= h_this->length);\n\t\tif ((n << h_this->shift) > h_this->length - offset_bytes) {\n\t\t\t/* Overflow not an issue because subtraction is used on the right\n\t\t\t * side and guaranteed to be >= 0.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copy exceeds target buffer nominal length\"));\n\t\t\tgoto fail_args;\n\t\t}\n\n\t\t/* There's no need to check for buffer validity status for the\n\t\t * target here: the property access code will do that for each\n\t\t * element.  Moreover, if we did check the validity here, side\n\t\t * effects from reading the source argument might invalidate\n\t\t * the results anyway.\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t\tduk_push_this(thr);\n\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk_get_prop_index(thr, 0, i);\n\t\t\tduk_put_prop_index(thr, 2, offset_elems + i);\n\t\t}\n\t}\n\n\treturn 0;\n\n fail_args:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.slice([start], [end])\n *  ArrayBuffer.prototype.slice(begin, [end])\n *  TypedArray.prototype.subarray(begin, [end])\n *\n *  The API calls are almost identical; negative indices are counted from end\n *  of buffer, and final indices are clamped (allowing crossed indices).  Main\n *  differences:\n *\n *    - Copy/view behavior; Node.js .slice() and TypedArray .subarray() create\n *      views, ArrayBuffer .slice() creates a copy\n *\n *    - Resulting object has a different class and prototype depending on the\n *      call (or 'this' argument)\n *\n *    - TypedArray .subarray() arguments are element indices, not byte offsets\n *\n *    - Plain buffer argument creates a plain buffer slice\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL void duk__arraybuffer_plain_slice(duk_hthread *thr, duk_hbuffer *h_val) {\n\tduk_int_t start_offset, end_offset;\n\tduk_uint_t slice_length;\n\tduk_uint8_t *p_copy;\n\tduk_size_t copy_length;\n\n\tduk__clamp_startend_negidx_shifted(thr,\n\t                                   (duk_int_t) DUK_HBUFFER_GET_SIZE(h_val),\n\t                                   0 /*buffer_shift*/,\n\t                                   0 /*idx_start*/,\n\t                                   1 /*idx_end*/,\n\t                                   &start_offset,\n\t                                   &end_offset);\n\tDUK_ASSERT(end_offset <= (duk_int_t) DUK_HBUFFER_GET_SIZE(h_val));\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(end_offset >= start_offset);\n\tslice_length = (duk_uint_t) (end_offset - start_offset);\n\n\tp_copy = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) slice_length);\n\tDUK_ASSERT(p_copy != NULL);\n\tcopy_length = slice_length;\n\n\tduk_memcpy_unsafe((void *) p_copy,\n\t                  (const void *) ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_val) + start_offset),\n\t                  copy_length);\n}\n#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Shared helper for slice/subarray operation.\n * Magic: 0x01=isView, 0x02=copy, 0x04=Node.js Buffer special handling.\n */\nDUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_hthread *thr) {\n\tduk_small_int_t magic;\n\tduk_small_uint_t res_class_num;\n\tduk_small_int_t res_proto_bidx;\n\tduk_hbufobj *h_this;\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_int_t start_offset, end_offset;\n\tduk_uint_t slice_length;\n\tduk_tval *tv;\n\n\t/* [ start end ] */\n\n\tmagic = duk_get_current_magic(thr);\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\t/* For plain buffers return a plain buffer slice. */\n\t\th_val = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h_val != NULL);\n\n\t\tif (magic & 0x02) {\n\t\t\t/* Make copy: ArrayBuffer.prototype.slice() uses this. */\n\t\t\tduk__arraybuffer_plain_slice(thr, h_val);\n\t\t\treturn 1;\n\t\t} else {\n\t\t\t/* View into existing buffer: cannot be done if the\n\t\t\t * result is a plain buffer because there's no slice\n\t\t\t * info.  So return an ArrayBuffer instance; coerce\n\t\t\t * the 'this' binding into an object and behave as if\n\t\t\t * the original call was for an Object-coerced plain\n\t\t\t * buffer (handled automatically by duk__require_bufobj_this()).\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slice() doesn't handle view into plain buffer, coerce 'this' to ArrayBuffer object\"));\n\t\t\t/* fall through */\n\t\t}\n\t}\n\ttv = NULL;  /* No longer valid nor needed. */\n\n\th_this = duk__require_bufobj_this(thr);\n\n\t/* Slice offsets are element (not byte) offsets, which only matters\n\t * for TypedArray views, Node.js Buffer and ArrayBuffer have shift\n\t * zero so byte and element offsets are the same.  Negative indices\n\t * are counted from end of slice, crossed indices are allowed (and\n\t * result in zero length result), and final values are clamped\n\t * against the current slice.  There's intentionally no check\n\t * against the underlying buffer here.\n\t */\n\n\tduk__clamp_startend_negidx_shifted(thr,\n\t                                   (duk_int_t) h_this->length,\n\t                                   (duk_uint8_t) h_this->shift,\n\t                                   0 /*idx_start*/,\n\t                                   1 /*idx_end*/,\n\t                                   &start_offset,\n\t                                   &end_offset);\n\tDUK_ASSERT(end_offset >= start_offset);\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(end_offset >= 0);\n\tslice_length = (duk_uint_t) (end_offset - start_offset);\n\n\t/* The resulting buffer object gets the same class and prototype as\n\t * the buffer in 'this', e.g. if the input is a Uint8Array the\n\t * result is a Uint8Array; if the input is a Float32Array, the\n\t * result is a Float32Array.  The result internal prototype should\n\t * be the default prototype for the class (e.g. initial value of\n\t * Uint8Array.prototype), not copied from the argument (Duktape 1.x\n\t * did that).\n\t *\n\t * Node.js Buffers have special handling: they're Uint8Arrays as far\n\t * as the internal class is concerned, so the new Buffer should also\n\t * be an Uint8Array but inherit from Buffer.prototype.\n\t */\n\tres_class_num = DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *) h_this);\n\tDUK_ASSERT(res_class_num >= DUK_HOBJECT_CLASS_BUFOBJ_MIN);  /* type check guarantees */\n\tDUK_ASSERT(res_class_num <= DUK_HOBJECT_CLASS_BUFOBJ_MAX);\n\tres_proto_bidx = duk__buffer_proto_from_classnum[res_class_num - DUK_HOBJECT_CLASS_BUFOBJ_MIN];\n\tif (magic & 0x04) {\n\t\tres_proto_bidx = DUK_BIDX_NODEJS_BUFFER_PROTOTYPE;\n\t}\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(res_class_num),\n\t                               res_proto_bidx);\n\tDUK_ASSERT(h_bufobj != NULL);\n\n\tDUK_ASSERT(h_bufobj->length == 0);\n\th_bufobj->shift = h_this->shift;  /* inherit */\n\th_bufobj->elem_type = h_this->elem_type;  /* inherit */\n\th_bufobj->is_typedarray = magic & 0x01;\n\tDUK_ASSERT(h_bufobj->is_typedarray == 0 || h_bufobj->is_typedarray == 1);\n\n\th_val = h_this->buf;\n\tif (h_val == NULL) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tif (magic & 0x02) {\n\t\t/* non-zero: make copy */\n\t\tduk_uint8_t *p_copy;\n\t\tduk_size_t copy_length;\n\n\t\tp_copy = (duk_uint8_t *) duk_push_fixed_buffer_zero(thr, (duk_size_t) slice_length);  /* must be zeroed, not all bytes always copied */\n\t\tDUK_ASSERT(p_copy != NULL);\n\n\t\t/* Copy slice, respecting underlying buffer limits; remainder\n\t\t * is left as zero.\n\t\t */\n\t\tcopy_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, slice_length);\n\t\tduk_memcpy_unsafe((void *) p_copy,\n\t\t                  (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + start_offset),\n\t\t                  copy_length);\n\n\t\th_val = duk_known_hbuffer(thr, -1);\n\n\t\th_bufobj->buf = h_val;\n\t\tDUK_HBUFFER_INCREF(thr, h_val);\n\t\th_bufobj->length = slice_length;\n\t\tDUK_ASSERT(h_bufobj->offset == 0);\n\n\t\tduk_pop(thr);  /* reachable so pop OK */\n\t} else {\n\t\th_bufobj->buf = h_val;\n\t\tDUK_HBUFFER_INCREF(thr, h_val);\n\t\th_bufobj->length = slice_length;\n\t\th_bufobj->offset = h_this->offset + (duk_uint_t) start_offset;\n\n\t\t/* Copy the .buffer property, needed for TypedArray.prototype.subarray().\n\t\t *\n\t\t * XXX: limit copy only for TypedArray classes specifically?\n\t\t */\n\n\t\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\t\th_bufobj->buf_prop = h_this->buf_prop;  /* may be NULL */\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, (duk_hobject *) h_bufobj->buf_prop);\n\t}\n\t/* unbalanced stack on purpose */\n\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.isEncoding()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_encoding(duk_hthread *thr) {\n\tconst char *encoding;\n\n\t/* only accept lowercase 'utf8' now. */\n\n\tencoding = duk_to_string(thr, 0);\n\tDUK_ASSERT(duk_is_string(thr, 0));  /* guaranteed by duk_to_string() */\n\tduk_push_boolean(thr, DUK_STRCMP(encoding, \"utf8\") == 0);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.isBuffer()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_hthread *thr) {\n\tduk_hobject *h;\n\tduk_hobject *h_proto;\n\tduk_bool_t ret = 0;\n\n\tDUK_ASSERT(duk_get_top(thr) >= 1);  /* nargs */\n\th = duk_get_hobject(thr, 0);\n\tif (h != NULL) {\n\t\th_proto = thr->builtins[DUK_BIDX_NODEJS_BUFFER_PROTOTYPE];\n\t\tDUK_ASSERT(h_proto != NULL);\n\n\t\th = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t\tif (h != NULL) {\n\t\t\tret = duk_hobject_prototype_chain_contains(thr, h, h_proto, 0 /*ignore_loop*/);\n\t\t}\n\t}\n\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.byteLength()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_byte_length(duk_hthread *thr) {\n\tconst char *str;\n\tduk_size_t len;\n\n\t/* At the moment Buffer(<str>) will just use the string bytes as\n\t * is (ignoring encoding), so we return the string length here\n\t * unconditionally.\n\t */\n\n\t/* XXX: to be revised; Old Node.js behavior just coerces any buffer\n\t * values to string:\n\t * $ node\n\t * > Buffer.byteLength(new Uint32Array(10))\n\t * 20\n\t * > Buffer.byteLength(new Uint32Array(100))\n\t * 20\n\t * (The 20 comes from '[object Uint32Array]'.length\n\t */\n\n\tstr = duk_to_lstring(thr, 0, &len);\n\tDUK_UNREF(str);\n\tduk_push_size_t(thr, len);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.concat()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_hthread *thr) {\n\tduk_hobject *h_arg;\n\tduk_uint_t total_length;\n\tduk_hbufobj *h_bufobj;\n\tduk_hbufobj *h_bufres;\n\tduk_hbuffer *h_val;\n\tduk_uint_t i, n;\n\tduk_uint8_t *p;\n\tduk_size_t space_left;\n\tduk_size_t copy_size;\n\n\t/* Node.js accepts only actual Arrays. */\n\th_arg = duk_require_hobject(thr, 0);\n\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h_arg) != DUK_HOBJECT_CLASS_ARRAY) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* Compute result length and validate argument buffers. */\n\tn = (duk_uint_t) duk_get_length(thr, 0);\n\ttotal_length = 0;\n\tfor (i = 0; i < n; i++) {\n\t\t/* Neutered checks not necessary here: neutered buffers have\n\t\t * zero 'length' so we'll effectively skip them.\n\t\t */\n\t\tDUK_ASSERT_TOP(thr, 2);  /* [ array totalLength ] */\n\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);  /* -> [ array totalLength buf ] */\n\t\th_bufobj = duk__require_bufobj_value(thr, 2);\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\t\ttotal_length += h_bufobj->length;\n\t\tif (DUK_UNLIKELY(total_length < h_bufobj->length)) {\n\t\t\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);  /* Wrapped. */\n\t\t}\n\t\tduk_pop(thr);\n\t}\n\t/* In Node.js v0.12.1 a 1-element array is special and won't create a\n\t * copy, this was fixed later so an explicit check no longer needed.\n\t */\n\n\t/* User totalLength overrides a computed length, but we'll check\n\t * every copy in the copy loop.  Note that duk_to_int() can\n\t * technically have arbitrary side effects so we need to recheck\n\t * the buffers in the copy loop.\n\t */\n\tif (!duk_is_undefined(thr, 1) && n > 0) {\n\t\t/* For n == 0, Node.js ignores totalLength argument and\n\t\t * returns a zero length buffer.\n\t\t */\n\t\tduk_int_t total_length_signed;\n\t\ttotal_length_signed = duk_to_int(thr, 1);\n\t\tif (total_length_signed < 0) {\n\t\t\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n\t\t}\n\t\ttotal_length = (duk_uint_t) total_length_signed;\n\t}\n\n\th_bufres = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_UINT8ARRAY),\n\t                               DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_bufres != NULL);\n\n\tp = (duk_uint8_t *) duk_push_fixed_buffer_zero(thr, total_length);  /* must be zeroed, all bytes not necessarily written over */\n\tDUK_ASSERT(p != NULL);\n\tspace_left = (duk_size_t) total_length;\n\n\tfor (i = 0; i < n; i++) {\n\t\tDUK_ASSERT_TOP(thr, 4);  /* [ array totalLength bufres buf ] */\n\n\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);\n\t\th_bufobj = duk__require_bufobj_value(thr, 4);\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\n\t\tcopy_size = h_bufobj->length;\n\t\tif (copy_size > space_left) {\n\t\t\tcopy_size = space_left;\n\t\t}\n\n\t\tif (h_bufobj->buf != NULL &&\n\t\t    DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {\n\t\t\tduk_memcpy_unsafe((void *) p,\n\t\t\t                  (const void *) DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj),\n\t\t\t                  copy_size);\n\t\t} else {\n\t\t\t/* Just skip, leaving zeroes in the result. */\n\t\t\t;\n\t\t}\n\t\tp += copy_size;\n\t\tspace_left -= copy_size;\n\n\t\tduk_pop(thr);\n\t}\n\n\th_val = duk_known_hbuffer(thr, -1);\n\n\tduk__set_bufobj_buffer(thr, h_bufres, h_val);\n\th_bufres->is_typedarray = 1;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufres);\n\n\tduk_pop(thr);  /* pop plain buffer, now reachable through h_bufres */\n\n\treturn 1;  /* return h_bufres */\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Shared readfield and writefield methods\n *\n *  The readfield/writefield methods need support for endianness and field\n *  types.  All offsets are byte based so no offset shifting is needed.\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Format of magic, bits:\n *   0...1: field type; 0=uint8, 1=uint16, 2=uint32, 3=float, 4=double, 5=unused, 6=unused, 7=unused\n *       3: endianness: 0=little, 1=big\n *       4: signed: 1=yes, 0=no\n *       5: typedarray: 1=yes, 0=no\n */\n#define  DUK__FLD_8BIT         0\n#define  DUK__FLD_16BIT        1\n#define  DUK__FLD_32BIT        2\n#define  DUK__FLD_FLOAT        3\n#define  DUK__FLD_DOUBLE       4\n#define  DUK__FLD_VARINT       5\n#define  DUK__FLD_BIGENDIAN    (1 << 3)\n#define  DUK__FLD_SIGNED       (1 << 4)\n#define  DUK__FLD_TYPEDARRAY   (1 << 5)\n\n/* XXX: split into separate functions for each field type? */\nDUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_hthread *thr) {\n\tduk_small_int_t magic = (duk_small_int_t) duk_get_current_magic(thr);\n\tduk_small_int_t magic_ftype;\n\tduk_small_int_t magic_bigendian;\n\tduk_small_int_t magic_signed;\n\tduk_small_int_t magic_typedarray;\n\tduk_small_int_t endswap;\n\tduk_hbufobj *h_this;\n\tduk_bool_t no_assert;\n\tduk_int_t offset_signed;\n\tduk_uint_t offset;\n\tduk_uint_t buffer_length;\n\tduk_uint_t check_length;\n\tduk_uint8_t *buf;\n\tduk_double_union du;\n\n\tmagic_ftype = magic & 0x0007;\n\tmagic_bigendian = magic & 0x0008;\n\tmagic_signed = magic & 0x0010;\n\tmagic_typedarray = magic & 0x0020;\n\n\th_this = duk__require_bufobj_this(thr);  /* XXX: very inefficient for plain buffers */\n\tDUK_ASSERT(h_this != NULL);\n\tbuffer_length = h_this->length;\n\n\t/* [ offset noAssert                 ], when ftype != DUK__FLD_VARINT */\n\t/* [ offset fieldByteLength noAssert ], when ftype == DUK__FLD_VARINT */\n\t/* [ offset littleEndian             ], when DUK__FLD_TYPEDARRAY (regardless of ftype) */\n\n\t/* Handle TypedArray vs. Node.js Buffer arg differences */\n\tif (magic_typedarray) {\n\t\tno_assert = 0;\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = !duk_to_boolean(thr, 1);  /* 1=little endian */\n#else\n\t\tendswap = duk_to_boolean(thr, 1);  /* 1=little endian */\n#endif\n\t} else {\n\t\tno_assert = duk_to_boolean(thr, (magic_ftype == DUK__FLD_VARINT) ? 2 : 1);\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = magic_bigendian;\n#else\n\t\tendswap = !magic_bigendian;\n#endif\n\t}\n\n\t/* Offset is coerced first to signed integer range and then to unsigned.\n\t * This ensures we can add a small byte length (1-8) to the offset in\n\t * bound checks and not wrap.\n\t */\n\toffset_signed = duk_to_int(thr, 0);\n\toffset = (duk_uint_t) offset_signed;\n\tif (offset_signed < 0) {\n\t\tgoto fail_bounds;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"readfield, buffer_length=%ld, offset=%ld, no_assert=%d, \"\n\t                     \"magic=%04x, magic_fieldtype=%d, magic_bigendian=%d, magic_signed=%d, \"\n\t                     \"endswap=%d\",\n\t                     (long) buffer_length, (long) offset, (int) no_assert,\n\t                     (unsigned int) magic, (int) magic_ftype, (int) (magic_bigendian >> 3),\n\t                     (int) (magic_signed >> 4), (int) endswap));\n\n\t/* Update 'buffer_length' to be the effective, safe limit which\n\t * takes into account the underlying buffer.  This value will be\n\t * potentially invalidated by any side effect.\n\t */\n\tcheck_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, buffer_length);\n\tDUK_DDD(DUK_DDDPRINT(\"buffer_length=%ld, check_length=%ld\",\n\t                     (long) buffer_length, (long) check_length));\n\n\tif (h_this->buf) {\n\t\tbuf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this);\n\t} else {\n\t\t/* Neutered.  We could go into the switch-case safely with\n\t\t * buf == NULL because check_length == 0.  To avoid scanbuild\n\t\t * warnings, fail directly instead.\n\t\t */\n\t\tDUK_ASSERT(check_length == 0);\n\t\tgoto fail_neutered;\n\t}\n\tDUK_ASSERT(buf != NULL);\n\n\tswitch (magic_ftype) {\n\tcase DUK__FLD_8BIT: {\n\t\tduk_uint8_t tmp;\n\t\tif (offset + 1U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\ttmp = buf[offset];\n\t\tif (magic_signed) {\n\t\t\tduk_push_int(thr, (duk_int_t) ((duk_int8_t) tmp));\n\t\t} else {\n\t\t\tduk_push_uint(thr, (duk_uint_t) tmp);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK__FLD_16BIT: {\n\t\tduk_uint16_t tmp;\n\t\tif (offset + 2U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 2);\n\t\ttmp = du.us[0];\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP16(tmp);\n\t\t}\n\t\tif (magic_signed) {\n\t\t\tduk_push_int(thr, (duk_int_t) ((duk_int16_t) tmp));\n\t\t} else {\n\t\t\tduk_push_uint(thr, (duk_uint_t) tmp);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK__FLD_32BIT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 4);\n\t\ttmp = du.ui[0];\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t}\n\t\tif (magic_signed) {\n\t\t\tduk_push_int(thr, (duk_int_t) ((duk_int32_t) tmp));\n\t\t} else {\n\t\t\tduk_push_uint(thr, (duk_uint_t) tmp);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK__FLD_FLOAT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 4);\n\t\tif (endswap) {\n\t\t\ttmp = du.ui[0];\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t\tdu.ui[0] = tmp;\n\t\t}\n\t\tduk_push_number(thr, (duk_double_t) du.f[0]);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_DOUBLE: {\n\t\tif (offset + 8U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 8);\n\t\tif (endswap) {\n\t\t\tDUK_DBLUNION_BSWAP64(&du);\n\t\t}\n\t\tduk_push_number(thr, (duk_double_t) du.d);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_VARINT: {\n\t\t/* Node.js Buffer variable width integer field.  We don't really\n\t\t * care about speed here, so aim for shortest algorithm.\n\t\t */\n\t\tduk_int_t field_bytelen;\n\t\tduk_int_t i, i_step, i_end;\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_int64_t tmp;\n\t\tduk_small_uint_t shift_tmp;\n#else\n\t\tduk_double_t tmp;\n\t\tduk_small_int_t highbyte;\n#endif\n\t\tconst duk_uint8_t *p;\n\n\t\tfield_bytelen = duk_get_int(thr, 1);  /* avoid side effects! */\n\t\tif (field_bytelen < 1 || field_bytelen > 6) {\n\t\t\tgoto fail_field_length;\n\t\t}\n\t\tif (offset + (duk_uint_t) field_bytelen > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tp = (const duk_uint8_t *) (buf + offset);\n\n\t\t/* Slow gathering of value using either 64-bit arithmetic\n\t\t * or IEEE doubles if 64-bit types not available.  Handling\n\t\t * of negative numbers is a bit non-obvious in both cases.\n\t\t */\n\n\t\tif (magic_bigendian) {\n\t\t\t/* Gather in big endian */\n\t\t\ti = 0;\n\t\t\ti_step = 1;\n\t\t\ti_end = field_bytelen;  /* one i_step over */\n\t\t} else {\n\t\t\t/* Gather in little endian */\n\t\t\ti = field_bytelen - 1;\n\t\t\ti_step = -1;\n\t\t\ti_end = -1;  /* one i_step over */\n\t\t}\n\n#if defined(DUK_USE_64BIT_OPS)\n\t\ttmp = 0;\n\t\tdo {\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\ttmp = (tmp << 8) + (duk_int64_t) p[i];\n\t\t\ti += i_step;\n\t\t} while (i != i_end);\n\n\t\tif (magic_signed) {\n\t\t\t/* Shift to sign extend.  Left shift must be unsigned\n\t\t\t * to avoid undefined behavior; right shift must be\n\t\t\t * signed to sign extend properly.\n\t\t\t */\n\t\t\tshift_tmp = (duk_small_uint_t) (64U - (duk_small_uint_t) field_bytelen * 8U);\n\t\t\ttmp = (duk_int64_t) ((duk_uint64_t) tmp << shift_tmp) >> shift_tmp;\n\t\t}\n\n\t\tduk_push_i64(thr, tmp);\n#else\n\t\thighbyte = p[i];\n\t\tif (magic_signed && (highbyte & 0x80) != 0) {\n\t\t\t/* 0xff => 255 - 256 = -1; 0x80 => 128 - 256 = -128 */\n\t\t\ttmp = (duk_double_t) (highbyte - 256);\n\t\t} else {\n\t\t\ttmp = (duk_double_t) highbyte;\n\t\t}\n\t\tfor (;;) {\n\t\t\ti += i_step;\n\t\t\tif (i == i_end) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\ttmp = (tmp * 256.0) + (duk_double_t) p[i];\n\t\t}\n\n\t\tduk_push_number(thr, tmp);\n#endif\n\t\tbreak;\n\t}\n\tdefault: {  /* should never happen but default here */\n\t\tgoto fail_bounds;\n\t}\n\t}\n\n\treturn 1;\n\n fail_neutered:\n fail_field_length:\n fail_bounds:\n\tif (no_assert) {\n\t\t/* Node.js return value for noAssert out-of-bounds reads is\n\t\t * usually (but not always) NaN.  Return NaN consistently.\n\t\t */\n\t\tduk_push_nan(thr);\n\t\treturn 1;\n\t}\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* XXX: split into separate functions for each field type? */\nDUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_hthread *thr) {\n\tduk_small_int_t magic = (duk_small_int_t) duk_get_current_magic(thr);\n\tduk_small_int_t magic_ftype;\n\tduk_small_int_t magic_bigendian;\n\tduk_small_int_t magic_signed;\n\tduk_small_int_t magic_typedarray;\n\tduk_small_int_t endswap;\n\tduk_hbufobj *h_this;\n\tduk_bool_t no_assert;\n\tduk_int_t offset_signed;\n\tduk_uint_t offset;\n\tduk_uint_t buffer_length;\n\tduk_uint_t check_length;\n\tduk_uint8_t *buf;\n\tduk_double_union du;\n\tduk_int_t nbytes = 0;\n\n\tmagic_ftype = magic & 0x0007;\n\tmagic_bigendian = magic & 0x0008;\n\tmagic_signed = magic & 0x0010;\n\tmagic_typedarray = magic & 0x0020;\n\tDUK_UNREF(magic_signed);\n\n\th_this = duk__require_bufobj_this(thr);  /* XXX: very inefficient for plain buffers */\n\tDUK_ASSERT(h_this != NULL);\n\tbuffer_length = h_this->length;\n\n\t/* [ value  offset noAssert                 ], when ftype != DUK__FLD_VARINT */\n\t/* [ value  offset fieldByteLength noAssert ], when ftype == DUK__FLD_VARINT */\n\t/* [ offset value  littleEndian             ], when DUK__FLD_TYPEDARRAY (regardless of ftype) */\n\n\t/* Handle TypedArray vs. Node.js Buffer arg differences */\n\tif (magic_typedarray) {\n\t\tno_assert = 0;\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = !duk_to_boolean(thr, 2);  /* 1=little endian */\n#else\n\t\tendswap = duk_to_boolean(thr, 2);  /* 1=little endian */\n#endif\n\t\tduk_swap(thr, 0, 1);  /* offset/value order different from Node.js */\n\t} else {\n\t\tno_assert = duk_to_boolean(thr, (magic_ftype == DUK__FLD_VARINT) ? 3 : 2);\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = magic_bigendian;\n#else\n\t\tendswap = !magic_bigendian;\n#endif\n\t}\n\n\t/* Offset is coerced first to signed integer range and then to unsigned.\n\t * This ensures we can add a small byte length (1-8) to the offset in\n\t * bound checks and not wrap.\n\t */\n\toffset_signed = duk_to_int(thr, 1);\n\toffset = (duk_uint_t) offset_signed;\n\n\t/* We need 'nbytes' even for a failed offset; return value must be\n\t * (offset + nbytes) even when write fails due to invalid offset.\n\t */\n\tif (magic_ftype != DUK__FLD_VARINT) {\n\t\tDUK_ASSERT(magic_ftype >= 0 && magic_ftype < (duk_small_int_t) (sizeof(duk__buffer_nbytes_from_fldtype) / sizeof(duk_uint8_t)));\n\t\tnbytes = duk__buffer_nbytes_from_fldtype[magic_ftype];\n\t} else {\n\t\tnbytes = duk_get_int(thr, 2);\n\t\tif (nbytes < 1 || nbytes > 6) {\n\t\t\tgoto fail_field_length;\n\t\t}\n\t}\n\tDUK_ASSERT(nbytes >= 1 && nbytes <= 8);\n\n\t/* Now we can check offset validity. */\n\tif (offset_signed < 0) {\n\t\tgoto fail_bounds;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"writefield, value=%!T, buffer_length=%ld, offset=%ld, no_assert=%d, \"\n\t                     \"magic=%04x, magic_fieldtype=%d, magic_bigendian=%d, magic_signed=%d, \"\n\t                     \"endswap=%d\",\n\t                     duk_get_tval(thr, 0), (long) buffer_length, (long) offset, (int) no_assert,\n\t                     (unsigned int) magic, (int) magic_ftype, (int) (magic_bigendian >> 3),\n\t                     (int) (magic_signed >> 4), (int) endswap));\n\n\t/* Coerce value to a number before computing check_length, so that\n\t * the field type specific coercion below can't have side effects\n\t * that would invalidate check_length.\n\t */\n\tduk_to_number(thr, 0);\n\n\t/* Update 'buffer_length' to be the effective, safe limit which\n\t * takes into account the underlying buffer.  This value will be\n\t * potentially invalidated by any side effect.\n\t */\n\tcheck_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, buffer_length);\n\tDUK_DDD(DUK_DDDPRINT(\"buffer_length=%ld, check_length=%ld\",\n\t                     (long) buffer_length, (long) check_length));\n\n\tif (h_this->buf) {\n\t\tbuf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this);\n\t} else {\n\t\t/* Neutered.  We could go into the switch-case safely with\n\t\t * buf == NULL because check_length == 0.  To avoid scanbuild\n\t\t * warnings, fail directly instead.\n\t\t */\n\t\tDUK_ASSERT(check_length == 0);\n\t\tgoto fail_neutered;\n\t}\n\tDUK_ASSERT(buf != NULL);\n\n\tswitch (magic_ftype) {\n\tcase DUK__FLD_8BIT: {\n\t\tif (offset + 1U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\t/* sign doesn't matter when writing */\n\t\tbuf[offset] = (duk_uint8_t) duk_to_uint32(thr, 0);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_16BIT: {\n\t\tduk_uint16_t tmp;\n\t\tif (offset + 2U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\ttmp = (duk_uint16_t) duk_to_uint32(thr, 0);\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP16(tmp);\n\t\t}\n\t\tdu.us[0] = tmp;\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 2);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_32BIT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\ttmp = (duk_uint32_t) duk_to_uint32(thr, 0);\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t}\n\t\tdu.ui[0] = tmp;\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 4);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_FLOAT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tdu.f[0] = (duk_float_t) duk_to_number(thr, 0);\n\t\tif (endswap) {\n\t\t\ttmp = du.ui[0];\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t\tdu.ui[0] = tmp;\n\t\t}\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 4);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_DOUBLE: {\n\t\tif (offset + 8U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tdu.d = (duk_double_t) duk_to_number(thr, 0);\n\t\tif (endswap) {\n\t\t\tDUK_DBLUNION_BSWAP64(&du);\n\t\t}\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 8);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_VARINT: {\n\t\t/* Node.js Buffer variable width integer field.  We don't really\n\t\t * care about speed here, so aim for shortest algorithm.\n\t\t */\n\t\tduk_int_t field_bytelen;\n\t\tduk_int_t i, i_step, i_end;\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_int64_t tmp;\n#else\n\t\tduk_double_t tmp;\n#endif\n\t\tduk_uint8_t *p;\n\n\t\tfield_bytelen = (duk_int_t) nbytes;\n\t\tif (offset + (duk_uint_t) field_bytelen > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\n\t\t/* Slow writing of value using either 64-bit arithmetic\n\t\t * or IEEE doubles if 64-bit types not available.  There's\n\t\t * no special sign handling when writing varints.\n\t\t */\n\n\t\tif (magic_bigendian) {\n\t\t\t/* Write in big endian */\n\t\t\ti = field_bytelen;  /* one i_step added at top of loop */\n\t\t\ti_step = -1;\n\t\t\ti_end = 0;\n\t\t} else {\n\t\t\t/* Write in little endian */\n\t\t\ti = -1;  /* one i_step added at top of loop */\n\t\t\ti_step = 1;\n\t\t\ti_end = field_bytelen - 1;\n\t\t}\n\n\t\t/* XXX: The duk_to_number() cast followed by integer coercion\n\t\t * is platform specific so NaN, +/- Infinity, and out-of-bounds\n\t\t * values result in platform specific output now.\n\t\t * See: test-bi-nodejs-buffer-proto-varint-special.js\n\t\t */\n\n#if defined(DUK_USE_64BIT_OPS)\n\t\ttmp = (duk_int64_t) duk_to_number(thr, 0);\n\t\tp = (duk_uint8_t *) (buf + offset);\n\t\tdo {\n\t\t\ti += i_step;\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\tp[i] = (duk_uint8_t) (tmp & 0xff);\n\t\t\ttmp = tmp >> 8;  /* unnecessary shift for last byte */\n\t\t} while (i != i_end);\n#else\n\t\ttmp = duk_to_number(thr, 0);\n\t\tp = (duk_uint8_t *) (buf + offset);\n\t\tdo {\n\t\t\ti += i_step;\n\t\t\ttmp = DUK_FLOOR(tmp);\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\tp[i] = (duk_uint8_t) (DUK_FMOD(tmp, 256.0));\n\t\t\ttmp = tmp / 256.0;  /* unnecessary div for last byte */\n\t\t} while (i != i_end);\n#endif\n\t\tbreak;\n\t}\n\tdefault: {  /* should never happen but default here */\n\t\tgoto fail_bounds;\n\t}\n\t}\n\n\t/* Node.js Buffer: return offset + #bytes written (i.e. next\n\t * write offset).\n\t */\n\tif (magic_typedarray) {\n\t\t/* For TypedArrays 'undefined' return value is specified\n\t\t * by ES2015 (matches V8).\n\t\t */\n\t\treturn 0;\n\t}\n\tduk_push_uint(thr, offset + (duk_uint_t) nbytes);\n\treturn 1;\n\n fail_neutered:\n fail_field_length:\n fail_bounds:\n\tif (no_assert) {\n\t\t/* Node.js return value for failed writes is offset + #bytes\n\t\t * that would have been written.\n\t\t */\n\t\t/* XXX: for negative input offsets, 'offset' will be a large\n\t\t * positive value so the result here is confusing.\n\t\t */\n\t\tif (magic_typedarray) {\n\t\t\treturn 0;\n\t\t}\n\t\tduk_push_uint(thr, offset + (duk_uint_t) nbytes);\n\t\treturn 1;\n\t}\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Accessors for .buffer, .byteLength, .byteOffset\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL duk_hbufobj *duk__autospawn_arraybuffer(duk_hthread *thr, duk_hbuffer *h_buf) {\n\tduk_hbufobj *h_res;\n\n\th_res = duk_push_bufobj_raw(thr,\n\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                            DUK_HOBJECT_FLAG_BUFOBJ |\n\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),\n\t                            DUK_BIDX_ARRAYBUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_res != NULL);\n\tDUK_UNREF(h_res);\n\n\tduk__set_bufobj_buffer(thr, h_res, h_buf);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_res);\n\tDUK_ASSERT(h_res->buf_prop == NULL);\n\treturn h_res;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n\th_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW /*flags*/);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tif (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *) h_bufobj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"autospawn ArrayBuffer for plain buffer\"));\n\t\t(void) duk__autospawn_arraybuffer(thr, (duk_hbuffer *) h_bufobj);\n\t\treturn 1;\n\t} else {\n\t\tif (h_bufobj->buf_prop == NULL &&\n\t\t    DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *) h_bufobj) != DUK_HOBJECT_CLASS_ARRAYBUFFER &&\n\t\t    h_bufobj->buf != NULL) {\n\t\t\tduk_hbufobj *h_arrbuf;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"autospawn ArrayBuffer for typed array or DataView\"));\n\t\t\th_arrbuf = duk__autospawn_arraybuffer(thr, h_bufobj->buf);\n\n\t\t\tif (h_bufobj->buf_prop == NULL) {\n\t\t\t\t/* Must recheck buf_prop, in case ArrayBuffer\n\t\t\t\t * alloc had a side effect which already filled\n\t\t\t\t * it!\n\t\t\t\t */\n\n\t\t\t\t/* Set ArrayBuffer's .byteOffset and .byteLength based\n\t\t\t\t * on the view so that Arraybuffer[view.byteOffset]\n\t\t\t\t * matches view[0].\n\t\t\t\t */\n\t\t\t\th_arrbuf->offset = 0;\n\t\t\t\tDUK_ASSERT(h_bufobj->offset + h_bufobj->length >= h_bufobj->offset);  /* Wrap check on creation. */\n\t\t\t\th_arrbuf->length = h_bufobj->offset + h_bufobj->length;\n\t\t\t\tDUK_ASSERT(h_arrbuf->buf_prop == NULL);\n\n\t\t\t\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\t\t\t\th_bufobj->buf_prop = (duk_hobject *) h_arrbuf;\n\t\t\t\tDUK_HBUFOBJ_INCREF(thr, h_arrbuf);  /* Now reachable and accounted for. */\n\t\t\t}\n\n\t\t\t/* Left on stack; pushed for the second time below (OK). */\n\t\t}\n\t\tif (h_bufobj->buf_prop) {\n\t\t\tduk_push_hobject(thr, h_bufobj->buf_prop);\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n\th_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW /*flags*/);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tif (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *) h_bufobj)) {\n\t\tduk_push_uint(thr, 0);\n\t} else {\n\t\t/* If neutered must return 0; offset is zeroed during\n\t\t * neutering.\n\t\t */\n\t\tduk_push_uint(thr, h_bufobj->offset);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n\th_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW /*flags*/);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tif (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *) h_bufobj)) {\n\t\tduk_hbuffer *h_buf;\n\n\t\th_buf = (duk_hbuffer *) h_bufobj;\n\t\tDUK_ASSERT(DUK_HBUFFER_GET_SIZE(h_buf) <= DUK_UINT_MAX);  /* Buffer limits. */\n\t\tduk_push_uint(thr, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_buf));\n\t} else {\n\t\t/* If neutered must return 0; length is zeroed during\n\t\t * neutering.\n\t\t */\n\t\tduk_push_uint(thr, h_bufobj->length);\n\t}\n\treturn 1;\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n/* No .buffer getter without ArrayBuffer support. */\n#if 0\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_hthread *thr) {\n\treturn 0;\n}\n#endif\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_hthread *thr) {\n\tduk_push_uint(thr, 0);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_hthread *thr) {\n\tduk_hbuffer *h_buf;\n\n\t/* XXX: helper? */\n\tduk_push_this(thr);\n\th_buf = duk_require_hbuffer(thr, -1);\n\tduk_push_uint(thr, DUK_HBUFFER_GET_SIZE(h_buf));\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* automatic undefs */\n#undef DUK__BUFOBJ_FLAG_PROMOTE\n#undef DUK__BUFOBJ_FLAG_THROW\n#undef DUK__FLD_16BIT\n#undef DUK__FLD_32BIT\n#undef DUK__FLD_8BIT\n#undef DUK__FLD_BIGENDIAN\n#undef DUK__FLD_DOUBLE\n#undef DUK__FLD_FLOAT\n#undef DUK__FLD_SIGNED\n#undef DUK__FLD_TYPEDARRAY\n#undef DUK__FLD_VARINT\n/*\n *  Date built-ins\n *\n *  Unlike most built-ins, Date has some platform dependencies for getting\n *  UTC time, converting between UTC and local time, and parsing and\n *  formatting time values.  These are all abstracted behind DUK_USE_xxx\n *  config options.  There are built-in platform specific providers for\n *  POSIX and Windows, but external providers can also be used.\n *\n *  See doc/datetime.rst.\n *\n */\n\n/* #include duk_internal.h -> already included */\n\n/* XXX: currently defines unnecessary symbols when DUK_USE_DATE_BUILTIN is disabled. */\n\n/*\n *  Forward declarations\n */\n\nDUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval_tzoffset(duk_hthread *thr, duk_small_uint_t flags, duk_int_t *out_tzoffset);\nDUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval(duk_hthread *thr, duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__twodigit_year_fixup(duk_hthread *thr, duk_idx_t idx_val);\nDUK_LOCAL_DECL duk_ret_t duk__set_this_timeval_from_dparts(duk_hthread *thr, duk_double_t *dparts, duk_small_uint_t flags);\n\n/*\n *  Other file level defines\n */\n\n/* Debug macro to print all parts and dparts (used manually because of debug level). */\n#define  DUK__DPRINT_PARTS_AND_DPARTS(parts,dparts)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"parts: %ld %ld %ld %ld %ld %ld %ld %ld, dparts: %lf %lf %lf %lf %lf %lf %lf %lf\", \\\n\t\t                 (long) (parts)[0], (long) (parts)[1], \\\n\t\t                 (long) (parts)[2], (long) (parts)[3], \\\n\t\t                 (long) (parts)[4], (long) (parts)[5], \\\n\t\t                 (long) (parts)[6], (long) (parts)[7], \\\n\t\t                 (double) (dparts)[0], (double) (dparts)[1], \\\n\t\t                 (double) (dparts)[2], (double) (dparts)[3], \\\n\t\t                 (double) (dparts)[4], (double) (dparts)[5], \\\n\t\t                 (double) (dparts)[6], (double) (dparts)[7])); \\\n\t} while (0)\n#define  DUK__DPRINT_PARTS(parts)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"parts: %ld %ld %ld %ld %ld %ld %ld %ld\", \\\n\t\t                 (long) (parts)[0], (long) (parts)[1], \\\n\t\t                 (long) (parts)[2], (long) (parts)[3], \\\n\t\t                 (long) (parts)[4], (long) (parts)[5], \\\n\t\t                 (long) (parts)[6], (long) (parts)[7])); \\\n\t} while (0)\n#define  DUK__DPRINT_DPARTS(dparts)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"dparts: %lf %lf %lf %lf %lf %lf %lf %lf\", \\\n\t\t                 (double) (dparts)[0], (double) (dparts)[1], \\\n\t\t                 (double) (dparts)[2], (double) (dparts)[3], \\\n\t\t                 (double) (dparts)[4], (double) (dparts)[5], \\\n\t\t                 (double) (dparts)[6], (double) (dparts)[7])); \\\n\t} while (0)\n\n/* Equivalent year for DST calculations outside [1970,2038[ range, see\n * E5 Section 15.9.1.8.  Equivalent year has the same leap-year-ness and\n * starts with the same weekday on Jan 1.\n * https://bugzilla.mozilla.org/show_bug.cgi?id=351066\n */\n#define DUK__YEAR(x) ((duk_uint8_t) ((x) - 1970))\nDUK_LOCAL duk_uint8_t duk__date_equivyear[14] = {\n#if 1\n\t/* This is based on V8 EquivalentYear() algorithm (see util/genequivyear.py):\n\t * http://code.google.com/p/v8/source/browse/trunk/src/date.h#146\n\t */\n\n\t/* non-leap year: sunday, monday, ... */\n\tDUK__YEAR(2023), DUK__YEAR(2035), DUK__YEAR(2019), DUK__YEAR(2031),\n\tDUK__YEAR(2015), DUK__YEAR(2027), DUK__YEAR(2011),\n\n\t/* leap year: sunday, monday, ... */\n\tDUK__YEAR(2012), DUK__YEAR(2024), DUK__YEAR(2008), DUK__YEAR(2020),\n\tDUK__YEAR(2032), DUK__YEAR(2016), DUK__YEAR(2028)\n#endif\n\n#if 0\n\t/* This is based on Rhino EquivalentYear() algorithm:\n\t * https://github.com/mozilla/rhino/blob/f99cc11d616f0cdda2c42bde72b3484df6182947/src/org/mozilla/javascript/NativeDate.java\n\t */\n\n\t/* non-leap year: sunday, monday, ... */\n\tDUK__YEAR(1978), DUK__YEAR(1973), DUK__YEAR(1985), DUK__YEAR(1986),\n\tDUK__YEAR(1981), DUK__YEAR(1971), DUK__YEAR(1977),\n\n\t/* leap year: sunday, monday, ... */\n\tDUK__YEAR(1984), DUK__YEAR(1996), DUK__YEAR(1980), DUK__YEAR(1992),\n\tDUK__YEAR(1976), DUK__YEAR(1988), DUK__YEAR(1972)\n#endif\n};\n\n/*\n *  ISO 8601 subset parser.\n */\n\n/* Parser part count. */\n#define DUK__NUM_ISO8601_PARSER_PARTS  9\n\n/* Parser part indices. */\n#define DUK__PI_YEAR         0\n#define DUK__PI_MONTH        1\n#define DUK__PI_DAY          2\n#define DUK__PI_HOUR         3\n#define DUK__PI_MINUTE       4\n#define DUK__PI_SECOND       5\n#define DUK__PI_MILLISECOND  6\n#define DUK__PI_TZHOUR       7\n#define DUK__PI_TZMINUTE     8\n\n/* Parser part masks. */\n#define DUK__PM_YEAR         (1 << DUK__PI_YEAR)\n#define DUK__PM_MONTH        (1 << DUK__PI_MONTH)\n#define DUK__PM_DAY          (1 << DUK__PI_DAY)\n#define DUK__PM_HOUR         (1 << DUK__PI_HOUR)\n#define DUK__PM_MINUTE       (1 << DUK__PI_MINUTE)\n#define DUK__PM_SECOND       (1 << DUK__PI_SECOND)\n#define DUK__PM_MILLISECOND  (1 << DUK__PI_MILLISECOND)\n#define DUK__PM_TZHOUR       (1 << DUK__PI_TZHOUR)\n#define DUK__PM_TZMINUTE     (1 << DUK__PI_TZMINUTE)\n\n/* Parser separator indices. */\n#define DUK__SI_PLUS         0\n#define DUK__SI_MINUS        1\n#define DUK__SI_T            2\n#define DUK__SI_SPACE        3\n#define DUK__SI_COLON        4\n#define DUK__SI_PERIOD       5\n#define DUK__SI_Z            6\n#define DUK__SI_NUL          7\n\n/* Parser separator masks. */\n#define DUK__SM_PLUS         (1 << DUK__SI_PLUS)\n#define DUK__SM_MINUS        (1 << DUK__SI_MINUS)\n#define DUK__SM_T            (1 << DUK__SI_T)\n#define DUK__SM_SPACE        (1 << DUK__SI_SPACE)\n#define DUK__SM_COLON        (1 << DUK__SI_COLON)\n#define DUK__SM_PERIOD       (1 << DUK__SI_PERIOD)\n#define DUK__SM_Z            (1 << DUK__SI_Z)\n#define DUK__SM_NUL          (1 << DUK__SI_NUL)\n\n/* Rule control flags. */\n#define DUK__CF_NEG          (1 << 0)  /* continue matching, set neg_tzoffset flag */\n#define DUK__CF_ACCEPT       (1 << 1)  /* accept string */\n#define DUK__CF_ACCEPT_NUL   (1 << 2)  /* accept string if next char is NUL (otherwise reject) */\n\n#define DUK__PACK_RULE(partmask,sepmask,nextpart,flags)  \\\n\t((duk_uint32_t) (partmask) + \\\n\t (((duk_uint32_t) (sepmask)) << 9) + \\\n\t (((duk_uint32_t) (nextpart)) << 17) + \\\n\t (((duk_uint32_t) (flags)) << 21))\n\n#define DUK__UNPACK_RULE(rule,var_nextidx,var_flags)  do { \\\n\t\t(var_nextidx) = (duk_small_uint_t) (((rule) >> 17) & 0x0f); \\\n\t\t(var_flags) = (duk_small_uint_t) ((rule) >> 21); \\\n\t} while (0)\n\n#define DUK__RULE_MASK_PART_SEP  0x1ffffUL\n\n/* Matching separator index is used in the control table */\nDUK_LOCAL const duk_uint8_t duk__parse_iso8601_seps[] = {\n\tDUK_ASC_PLUS /*0*/, DUK_ASC_MINUS /*1*/, DUK_ASC_UC_T /*2*/, DUK_ASC_SPACE /*3*/,\n\tDUK_ASC_COLON /*4*/, DUK_ASC_PERIOD /*5*/, DUK_ASC_UC_Z /*6*/, DUK_ASC_NUL /*7*/\n};\n\n/* Rule table: first matching rule is used to determine what to do next. */\nDUK_LOCAL const duk_uint32_t duk__parse_iso8601_control[] = {\n\tDUK__PACK_RULE(DUK__PM_YEAR, DUK__SM_MINUS, DUK__PI_MONTH, 0),\n\tDUK__PACK_RULE(DUK__PM_MONTH, DUK__SM_MINUS, DUK__PI_DAY, 0),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY, DUK__SM_T | DUK__SM_SPACE, DUK__PI_HOUR, 0),\n\tDUK__PACK_RULE(DUK__PM_HOUR, DUK__SM_COLON, DUK__PI_MINUTE, 0),\n\tDUK__PACK_RULE(DUK__PM_MINUTE, DUK__SM_COLON, DUK__PI_SECOND, 0),\n\tDUK__PACK_RULE(DUK__PM_SECOND, DUK__SM_PERIOD, DUK__PI_MILLISECOND, 0),\n\tDUK__PACK_RULE(DUK__PM_TZHOUR, DUK__SM_COLON, DUK__PI_TZMINUTE, 0),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_PLUS, DUK__PI_TZHOUR, 0),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_MINUS, DUK__PI_TZHOUR, DUK__CF_NEG),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_Z, 0, DUK__CF_ACCEPT_NUL),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND | DUK__PM_TZHOUR /*Note2*/ | DUK__PM_TZMINUTE, DUK__SM_NUL, 0, DUK__CF_ACCEPT)\n\n\t/* Note1: the specification doesn't require matching a time form with\n\t *        just hours (\"HH\"), but we accept it here, e.g. \"2012-01-02T12Z\".\n\t *\n\t * Note2: the specification doesn't require matching a timezone offset\n\t *        with just hours (\"HH\"), but accept it here, e.g. \"2012-01-02T03:04:05+02\"\n\t */\n};\n\nDUK_LOCAL duk_bool_t duk__parse_string_iso8601_subset(duk_hthread *thr, const char *str) {\n\tduk_int_t parts[DUK__NUM_ISO8601_PARSER_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t d;\n\tconst duk_uint8_t *p;\n\tduk_small_uint_t part_idx = 0;\n\tduk_int_t accum = 0;\n\tduk_small_uint_t ndigits = 0;\n\tduk_bool_t neg_year = 0;\n\tduk_bool_t neg_tzoffset = 0;\n\tduk_uint_fast8_t ch;\n\tduk_small_uint_t i;\n\n\t/* During parsing, month and day are one-based; set defaults here. */\n\tduk_memzero(parts, sizeof(parts));\n\tDUK_ASSERT(parts[DUK_DATE_IDX_YEAR] == 0);  /* don't care value, year is mandatory */\n\tparts[DUK_DATE_IDX_MONTH] = 1;\n\tparts[DUK_DATE_IDX_DAY] = 1;\n\n\t/* Special handling for year sign. */\n\tp = (const duk_uint8_t *) str;\n\tch = p[0];\n\tif (ch == DUK_ASC_PLUS) {\n\t\tp++;\n\t} else if (ch == DUK_ASC_MINUS) {\n\t\tneg_year = 1;\n\t\tp++;\n\t}\n\n\tfor (;;) {\n\t\tch = *p++;\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsing, part_idx=%ld, char=%ld ('%c')\",\n\t\t                     (long) part_idx, (long) ch,\n\t\t                     (int) ((ch >= 0x20 && ch <= 0x7e) ? ch : DUK_ASC_QUESTION)));\n\n\t\tif (ch >= DUK_ASC_0 && ch <= DUK_ASC_9) {\n\t\t\tif (ndigits >= 9) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"too many digits -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tif (part_idx == DUK__PI_MILLISECOND && ndigits >= 3) {\n\t\t\t\t/* ignore millisecond fractions after 3 */\n\t\t\t} else {\n\t\t\t\taccum = accum * 10 + ((duk_int_t) ch) - ((duk_int_t) DUK_ASC_0) + 0x00;\n\t\t\t\tndigits++;\n\t\t\t}\n\t\t} else {\n\t\t\tduk_uint_fast32_t match_val;\n\t\t\tduk_small_uint_t sep_idx;\n\n\t\t\tif (ndigits <= 0) {\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tif (part_idx == DUK__PI_MILLISECOND) {\n\t\t\t\t/* complete the millisecond field */\n\t\t\t\twhile (ndigits < 3) {\n\t\t\t\t\taccum *= 10;\n\t\t\t\t\tndigits++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tparts[part_idx] = accum;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"wrote part %ld -> value %ld\", (long) part_idx, (long) accum));\n\n\t\t\taccum = 0;\n\t\t\tndigits = 0;\n\n\t\t\tfor (i = 0; i < (duk_small_uint_t) (sizeof(duk__parse_iso8601_seps) / sizeof(duk_uint8_t)); i++) {\n\t\t\t\tif (duk__parse_iso8601_seps[i] == ch) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (i == (duk_small_uint_t) (sizeof(duk__parse_iso8601_seps) / sizeof(duk_uint8_t))) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"separator character doesn't match -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\n\t\t\tsep_idx = i;\n\t\t\tmatch_val = (1UL << part_idx) + (1UL << (sep_idx + 9));  /* match against rule part/sep bits */\n\n\t\t\tfor (i = 0; i < (duk_small_uint_t) (sizeof(duk__parse_iso8601_control) / sizeof(duk_uint32_t)); i++) {\n\t\t\t\tduk_uint_fast32_t rule = duk__parse_iso8601_control[i];\n\t\t\t\tduk_small_uint_t nextpart;\n\t\t\t\tduk_small_uint_t cflags;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"part_idx=%ld, sep_idx=%ld, match_val=0x%08lx, considering rule=0x%08lx\",\n\t\t\t\t                     (long) part_idx, (long) sep_idx,\n\t\t\t\t                     (unsigned long) match_val, (unsigned long) rule));\n\n\t\t\t\tif ((rule & match_val) != match_val) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tDUK__UNPACK_RULE(rule, nextpart, cflags);\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rule match -> part_idx=%ld, sep_idx=%ld, match_val=0x%08lx, \"\n\t\t\t\t                     \"rule=0x%08lx -> nextpart=%ld, cflags=0x%02lx\",\n\t\t\t\t                     (long) part_idx, (long) sep_idx,\n\t\t\t\t                     (unsigned long) match_val, (unsigned long) rule,\n\t\t\t\t                     (long) nextpart, (unsigned long) cflags));\n\n\t\t\t\tif (cflags & DUK__CF_NEG) {\n\t\t\t\t\tneg_tzoffset = 1;\n\t\t\t\t}\n\n\t\t\t\tif (cflags & DUK__CF_ACCEPT) {\n\t\t\t\t\tgoto accept;\n\t\t\t\t}\n\n\t\t\t\tif (cflags & DUK__CF_ACCEPT_NUL) {\n\t\t\t\t\tDUK_ASSERT(*(p - 1) != (char) 0);\n\t\t\t\t\tif (*p == DUK_ASC_NUL) {\n\t\t\t\t\t\tgoto accept;\n\t\t\t\t\t}\n\t\t\t\t\tgoto reject;\n\t\t\t\t}\n\n\t\t\t\tpart_idx = nextpart;\n\t\t\t\tbreak;\n\t\t\t}  /* rule match */\n\n\t\t\tif (i == (duk_small_uint_t) (sizeof(duk__parse_iso8601_control) / sizeof(duk_uint32_t))) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"no rule matches -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\n\t\t\tif (ch == 0) {\n\t\t\t\t/* This shouldn't be necessary, but check just in case\n\t\t\t\t * to avoid any chance of overruns.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"NUL after rule matching (should not happen) -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t}  /* if-digit-else-ctrl */\n\t}  /* char loop */\n\n\t/* We should never exit the loop above. */\n\tDUK_UNREACHABLE();\n\n reject:\n\tDUK_DDD(DUK_DDDPRINT(\"reject\"));\n\treturn 0;\n\n accept:\n\tDUK_DDD(DUK_DDDPRINT(\"accept\"));\n\n\t/* Apply timezone offset to get the main parts in UTC */\n\tif (neg_year) {\n\t\tparts[DUK__PI_YEAR] = -parts[DUK__PI_YEAR];\n\t}\n\tif (neg_tzoffset) {\n\t\tparts[DUK__PI_HOUR] += parts[DUK__PI_TZHOUR];\n\t\tparts[DUK__PI_MINUTE] += parts[DUK__PI_TZMINUTE];\n\t} else {\n\t\tparts[DUK__PI_HOUR] -= parts[DUK__PI_TZHOUR];\n\t\tparts[DUK__PI_MINUTE] -= parts[DUK__PI_TZMINUTE];\n\t}\n\tparts[DUK__PI_MONTH] -= 1;  /* zero-based month */\n\tparts[DUK__PI_DAY] -= 1;  /* zero-based day */\n\n\t/* Use double parts, they tolerate unnormalized time.\n\t *\n\t * Note: DUK_DATE_IDX_WEEKDAY is initialized with a bogus value (DUK__PI_TZHOUR)\n\t * on purpose.  It won't be actually used by duk_bi_date_get_timeval_from_dparts(),\n\t * but will make the value initialized just in case, and avoid any\n\t * potential for Valgrind issues.\n\t */\n\tfor (i = 0; i < DUK_DATE_IDX_NUM_PARTS; i++) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"part[%ld] = %ld\", (long) i, (long) parts[i]));\n\t\tdparts[i] = parts[i];\n\t}\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);\n\tduk_push_number(thr, d);\n\treturn 1;\n}\n\n/*\n *  Date/time parsing helper.\n *\n *  Parse a datetime string into a time value.  We must first try to parse\n *  the input according to the standard format in E5.1 Section 15.9.1.15.\n *  If that fails, we can try to parse using custom parsing, which can\n *  either be platform neutral (custom code) or platform specific (using\n *  existing platform API calls).\n *\n *  Note in particular that we must parse whatever toString(), toUTCString(),\n *  and toISOString() can produce; see E5.1 Section 15.9.4.2.\n *\n *  Returns 1 to allow tail calling.\n *\n *  There is much room for improvement here with respect to supporting\n *  alternative datetime formats.  For instance, V8 parses '2012-01-01' as\n *  UTC and '2012/01/01' as local time.\n */\n\nDUK_LOCAL duk_ret_t duk__parse_string(duk_hthread *thr, const char *str) {\n\t/* XXX: there is a small risk here: because the ISO 8601 parser is\n\t * very loose, it may end up parsing some datetime values which\n\t * would be better parsed with a platform specific parser.\n\t */\n\n\tDUK_ASSERT(str != NULL);\n\tDUK_DDD(DUK_DDDPRINT(\"parse datetime from string '%s'\", (const char *) str));\n\n\tif (duk__parse_string_iso8601_subset(thr, str) != 0) {\n\t\treturn 1;\n\t}\n\n#if defined(DUK_USE_DATE_PARSE_STRING)\n\t/* Contract, either:\n\t * - Push value on stack and return 1\n\t * - Don't push anything on stack and return 0\n\t */\n\n\tif (DUK_USE_DATE_PARSE_STRING(thr, str) != 0) {\n\t\treturn 1;\n\t}\n#else\n\t/* No platform-specific parsing, this is not an error. */\n#endif\n\n\tduk_push_nan(thr);\n\treturn 1;\n}\n\n/*\n *  Calendar helpers\n *\n *  Some helpers are used for getters and can operate on normalized values\n *  which can be represented with 32-bit signed integers.  Other helpers are\n *  needed by setters and operate on un-normalized double values, must watch\n *  out for non-finite numbers etc.\n */\n\nDUK_LOCAL duk_uint8_t duk__days_in_month[12] = {\n\t(duk_uint8_t) 31, (duk_uint8_t) 28, (duk_uint8_t) 31, (duk_uint8_t) 30,\n\t(duk_uint8_t) 31, (duk_uint8_t) 30, (duk_uint8_t) 31, (duk_uint8_t) 31,\n\t(duk_uint8_t) 30, (duk_uint8_t) 31, (duk_uint8_t) 30, (duk_uint8_t) 31\n};\n\n/* Maximum iteration count for computing UTC-to-local time offset when\n * creating an ECMAScript time value from local parts.\n */\n#define DUK__LOCAL_TZOFFSET_MAXITER   4\n\n/* Because 'day since epoch' can be negative and is used to compute weekday\n * using a modulo operation, add this multiple of 7 to avoid negative values\n * when year is below 1970 epoch.  ECMAScript time values are restricted to\n * +/- 100 million days from epoch, so this adder fits nicely into 32 bits.\n * Round to a multiple of 7 (= floor(100000000 / 7) * 7) and add margin.\n */\n#define DUK__WEEKDAY_MOD_ADDER  (20000000 * 7)  /* 0x08583b00 */\n\nDUK_INTERNAL duk_bool_t duk_bi_date_is_leap_year(duk_int_t year) {\n\tif ((year % 4) != 0) {\n\t\treturn 0;\n\t}\n\tif ((year % 100) != 0) {\n\t\treturn 1;\n\t}\n\tif ((year % 400) != 0) {\n\t\treturn 0;\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_bool_t duk_bi_date_timeval_in_valid_range(duk_double_t x) {\n\treturn (x >= -DUK_DATE_MSEC_100M_DAYS && x <= DUK_DATE_MSEC_100M_DAYS);\n}\n\nDUK_INTERNAL duk_bool_t duk_bi_date_timeval_in_leeway_range(duk_double_t x) {\n\treturn (x >= -DUK_DATE_MSEC_100M_DAYS_LEEWAY && x <= DUK_DATE_MSEC_100M_DAYS_LEEWAY);\n}\n\nDUK_INTERNAL duk_bool_t duk_bi_date_year_in_valid_range(duk_double_t x) {\n\treturn (x >= DUK_DATE_MIN_ECMA_YEAR && x <= DUK_DATE_MAX_ECMA_YEAR);\n}\n\nDUK_LOCAL duk_double_t duk__timeclip(duk_double_t x) {\n\tif (!DUK_ISFINITE(x)) {\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\n\tif (!duk_bi_date_timeval_in_valid_range(x)) {\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\n\tx = duk_js_tointeger_number(x);\n\n\t/* Here we'd have the option to normalize -0 to +0. */\n\treturn x;\n}\n\n/* Integer division which floors also negative values correctly. */\nDUK_LOCAL duk_int_t duk__div_floor(duk_int_t a, duk_int_t b) {\n\tDUK_ASSERT(b > 0);\n\tif (a >= 0) {\n\t\treturn a / b;\n\t} else {\n\t\t/* e.g. a = -4, b = 5  -->  -4 - 5 + 1 / 5  -->  -8 / 5  -->  -1\n\t\t *      a = -5, b = 5  -->  -5 - 5 + 1 / 5  -->  -9 / 5  -->  -1\n\t\t *      a = -6, b = 5  -->  -6 - 5 + 1 / 5  -->  -10 / 5  -->  -2\n\t\t */\n\t\treturn (a - b + 1) / b;\n\t}\n}\n\n/* Compute day number of the first day of a given year. */\nDUK_LOCAL duk_int_t duk__day_from_year(duk_int_t year) {\n\t/* Note: in integer arithmetic, (x / 4) is same as floor(x / 4) for non-negative\n\t * values, but is incorrect for negative ones.\n\t */\n\treturn 365 * (year - 1970)\n\t       + duk__div_floor(year - 1969, 4)\n\t       - duk__div_floor(year - 1901, 100)\n\t       + duk__div_floor(year - 1601, 400);\n}\n\n/* Given a day number, determine year and day-within-year. */\nDUK_LOCAL duk_int_t duk__year_from_day(duk_int_t day, duk_small_int_t *out_day_within_year) {\n\tduk_int_t year;\n\tduk_int_t diff_days;\n\n\t/* estimate year upwards (towards positive infinity), then back down;\n\t * two iterations should be enough\n\t */\n\n\tif (day >= 0) {\n\t\tyear = 1970 + day / 365;\n\t} else {\n\t\tyear = 1970 + day / 366;\n\t}\n\n\tfor (;;) {\n\t\tdiff_days = duk__day_from_year(year) - day;\n\t\tDUK_DDD(DUK_DDDPRINT(\"year=%ld day=%ld, diff_days=%ld\", (long) year, (long) day, (long) diff_days));\n\t\tif (diff_days <= 0) {\n\t\t\tDUK_ASSERT(-diff_days < 366);  /* fits into duk_small_int_t */\n\t\t\t*out_day_within_year = -diff_days;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"--> year=%ld, day-within-year=%ld\",\n\t\t\t                     (long) year, (long) *out_day_within_year));\n\t\t\tDUK_ASSERT(*out_day_within_year >= 0);\n\t\t\tDUK_ASSERT(*out_day_within_year < (duk_bi_date_is_leap_year(year) ? 366 : 365));\n\t\t\treturn year;\n\t\t}\n\n\t\t/* Note: this is very tricky; we must never 'overshoot' the\n\t\t * correction downwards.\n\t\t */\n\t\tyear -= 1 + (diff_days - 1) / 366;  /* conservative */\n\t}\n}\n\n/* Given a (year, month, day-within-month) triple, compute day number.\n * The input triple is un-normalized and may contain non-finite values.\n */\nDUK_LOCAL duk_double_t duk__make_day(duk_double_t year, duk_double_t month, duk_double_t day) {\n\tduk_int_t day_num;\n\tduk_bool_t is_leap;\n\tduk_small_int_t i, n;\n\n\t/* Assume that year, month, day are all coerced to whole numbers.\n\t * They may also be NaN or infinity, in which case this function\n\t * must return NaN or infinity to ensure time value becomes NaN.\n\t * If 'day' is NaN, the final return will end up returning a NaN,\n\t * so it doesn't need to be checked here.\n\t */\n\n\tif (!DUK_ISFINITE(year) || !DUK_ISFINITE(month)) {\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\n\tyear += DUK_FLOOR(month / 12.0);\n\n\tmonth = DUK_FMOD(month, 12.0);\n\tif (month < 0.0) {\n\t\t/* handle negative values */\n\t\tmonth += 12.0;\n\t}\n\n\t/* The algorithm in E5.1 Section 15.9.1.12 normalizes month, but\n\t * does not normalize the day-of-month (nor check whether or not\n\t * it is finite) because it's not necessary for finding the day\n\t * number which matches the (year,month) pair.\n\t *\n\t * We assume that duk__day_from_year() is exact here.\n\t *\n\t * Without an explicit infinity / NaN check in the beginning,\n\t * day_num would be a bogus integer here.\n\t *\n\t * It's possible for 'year' to be out of integer range here.\n\t * If so, we need to return NaN without integer overflow.\n\t * This fixes test-bug-setyear-overflow.js.\n\t */\n\n\tif (!duk_bi_date_year_in_valid_range(year)) {\n\t\tDUK_DD(DUK_DDPRINT(\"year not in ecmascript valid range, avoid integer overflow: %lf\", (double) year));\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\tday_num = duk__day_from_year((duk_int_t) year);\n\tis_leap = duk_bi_date_is_leap_year((duk_int_t) year);\n\n\tn = (duk_small_int_t) month;\n\tfor (i = 0; i < n; i++) {\n\t\tday_num += duk__days_in_month[i];\n\t\tif (i == 1 && is_leap) {\n\t\t\tday_num++;\n\t\t}\n\t}\n\n\t/* If 'day' is NaN, returns NaN. */\n\treturn (duk_double_t) day_num + day;\n}\n\n/* Split time value into parts.  The time value may contain fractions (it may\n * come from duk_time_to_components() API call) which are truncated.  Possible\n * local time adjustment has already been applied when reading the time value.\n */\nDUK_INTERNAL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts, duk_double_t *dparts, duk_small_uint_t flags) {\n\tduk_double_t d1, d2;\n\tduk_int_t t1, t2;\n\tduk_int_t day_since_epoch;\n\tduk_int_t year;  /* does not fit into 16 bits */\n\tduk_small_int_t day_in_year;\n\tduk_small_int_t month;\n\tduk_small_int_t day;\n\tduk_small_int_t dim;\n\tduk_int_t jan1_since_epoch;\n\tduk_small_int_t jan1_weekday;\n\tduk_int_t equiv_year;\n\tduk_small_uint_t i;\n\tduk_bool_t is_leap;\n\tduk_small_int_t arridx;\n\n\tDUK_ASSERT(DUK_ISFINITE(d));    /* caller checks */\n\td = DUK_FLOOR(d);  /* remove fractions if present */\n\tDUK_ASSERT(DUK_FLOOR(d) == d);\n\n\t/* The timevalue must be in valid ECMAScript range, but since a local\n\t * time offset can be applied, we need to allow a +/- 24h leeway to\n\t * the value.  In other words, although the UTC time is within the\n\t * ECMAScript range, the local part values can be just outside of it.\n\t */\n\tDUK_UNREF(duk_bi_date_timeval_in_leeway_range);\n\tDUK_ASSERT(duk_bi_date_timeval_in_leeway_range(d));\n\n\t/* These computations are guaranteed to be exact for the valid\n\t * E5 time value range, assuming milliseconds without fractions.\n\t */\n\td1 = (duk_double_t) DUK_FMOD(d, (double) DUK_DATE_MSEC_DAY);\n\tif (d1 < 0.0) {\n\t\t/* deal with negative values */\n\t\td1 += (duk_double_t) DUK_DATE_MSEC_DAY;\n\t}\n\td2 = DUK_FLOOR((double) (d / (duk_double_t) DUK_DATE_MSEC_DAY));\n\tDUK_ASSERT(d2 * ((duk_double_t) DUK_DATE_MSEC_DAY) + d1 == d);\n\t/* now expected to fit into a 32-bit integer */\n\tt1 = (duk_int_t) d1;\n\tt2 = (duk_int_t) d2;\n\tday_since_epoch = t2;\n\tDUK_ASSERT((duk_double_t) t1 == d1);\n\tDUK_ASSERT((duk_double_t) t2 == d2);\n\n\t/* t1 = milliseconds within day (fits 32 bit)\n\t * t2 = day number from epoch (fits 32 bit, may be negative)\n\t */\n\n\tparts[DUK_DATE_IDX_MILLISECOND] = t1 % 1000; t1 /= 1000;\n\tparts[DUK_DATE_IDX_SECOND] = t1 % 60; t1 /= 60;\n\tparts[DUK_DATE_IDX_MINUTE] = t1 % 60; t1 /= 60;\n\tparts[DUK_DATE_IDX_HOUR] = t1;\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MILLISECOND] >= 0 && parts[DUK_DATE_IDX_MILLISECOND] <= 999);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_SECOND] >= 0 && parts[DUK_DATE_IDX_SECOND] <= 59);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MINUTE] >= 0 && parts[DUK_DATE_IDX_MINUTE] <= 59);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_HOUR] >= 0 && parts[DUK_DATE_IDX_HOUR] <= 23);\n\n\tDUK_DDD(DUK_DDDPRINT(\"d=%lf, d1=%lf, d2=%lf, t1=%ld, t2=%ld, parts: hour=%ld min=%ld sec=%ld msec=%ld\",\n\t                     (double) d, (double) d1, (double) d2, (long) t1, (long) t2,\n\t                     (long) parts[DUK_DATE_IDX_HOUR],\n\t                     (long) parts[DUK_DATE_IDX_MINUTE],\n\t                     (long) parts[DUK_DATE_IDX_SECOND],\n\t                     (long) parts[DUK_DATE_IDX_MILLISECOND]));\n\n\t/* This assert depends on the input parts representing time inside\n\t * the ECMAScript range.\n\t */\n\tDUK_ASSERT(t2 + DUK__WEEKDAY_MOD_ADDER >= 0);\n\tparts[DUK_DATE_IDX_WEEKDAY] = (t2 + 4 + DUK__WEEKDAY_MOD_ADDER) % 7;  /* E5.1 Section 15.9.1.6 */\n\tDUK_ASSERT(parts[DUK_DATE_IDX_WEEKDAY] >= 0 && parts[DUK_DATE_IDX_WEEKDAY] <= 6);\n\n\tyear = duk__year_from_day(t2, &day_in_year);\n\tday = day_in_year;\n\tis_leap = duk_bi_date_is_leap_year(year);\n\tfor (month = 0; month < 12; month++) {\n\t\tdim = duk__days_in_month[month];\n\t\tif (month == 1 && is_leap) {\n\t\t\tdim++;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"month=%ld, dim=%ld, day=%ld\",\n\t\t                     (long) month, (long) dim, (long) day));\n\t\tif (day < dim) {\n\t\t\tbreak;\n\t\t}\n\t\tday -= dim;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"final month=%ld\", (long) month));\n\tDUK_ASSERT(month >= 0 && month <= 11);\n\tDUK_ASSERT(day >= 0 && day <= 31);\n\n\t/* Equivalent year mapping, used to avoid DST trouble when platform\n\t * may fail to provide reasonable DST answers for dates outside the\n\t * ordinary range (e.g. 1970-2038).  An equivalent year has the same\n\t * leap-year-ness as the original year and begins on the same weekday\n\t * (Jan 1).\n\t *\n\t * The year 2038 is avoided because there seem to be problems with it\n\t * on some platforms.  The year 1970 is also avoided as there were\n\t * practical problems with it; an equivalent year is used for it too,\n\t * which breaks some DST computations for 1970 right now, see e.g.\n\t * test-bi-date-tzoffset-brute-fi.js.\n\t */\n\tif ((flags & DUK_DATE_FLAG_EQUIVYEAR) && (year < 1971 || year > 2037)) {\n\t\tDUK_ASSERT(is_leap == 0 || is_leap == 1);\n\n\t\tjan1_since_epoch = day_since_epoch - day_in_year;  /* day number for Jan 1 since epoch */\n\t\tDUK_ASSERT(jan1_since_epoch + DUK__WEEKDAY_MOD_ADDER >= 0);\n\t\tjan1_weekday = (jan1_since_epoch + 4 + DUK__WEEKDAY_MOD_ADDER) % 7;  /* E5.1 Section 15.9.1.6 */\n\t\tDUK_ASSERT(jan1_weekday >= 0 && jan1_weekday <= 6);\n\t\tarridx = jan1_weekday;\n\t\tif (is_leap) {\n\t\t\tarridx += 7;\n\t\t}\n\t\tDUK_ASSERT(arridx >= 0 && arridx < (duk_small_int_t) (sizeof(duk__date_equivyear) / sizeof(duk_uint8_t)));\n\n\t\tequiv_year = (duk_int_t) duk__date_equivyear[arridx] + 1970;\n\t\tyear = equiv_year;\n\t\tDUK_DDD(DUK_DDDPRINT(\"equiv year mapping, year=%ld, day_in_year=%ld, day_since_epoch=%ld, \"\n\t\t                     \"jan1_since_epoch=%ld, jan1_weekday=%ld -> equiv year %ld\",\n\t\t                     (long) year, (long) day_in_year, (long) day_since_epoch,\n\t\t                     (long) jan1_since_epoch, (long) jan1_weekday, (long) equiv_year));\n\t}\n\n\tparts[DUK_DATE_IDX_YEAR] = year;\n\tparts[DUK_DATE_IDX_MONTH] = month;\n\tparts[DUK_DATE_IDX_DAY] = day;\n\n\tif (flags & DUK_DATE_FLAG_ONEBASED) {\n\t\tparts[DUK_DATE_IDX_MONTH]++;  /* zero-based -> one-based */\n\t\tparts[DUK_DATE_IDX_DAY]++;    /* -\"\"- */\n\t}\n\n\tif (dparts != NULL) {\n\t\tfor (i = 0; i < DUK_DATE_IDX_NUM_PARTS; i++) {\n\t\t\tdparts[i] = (duk_double_t) parts[i];\n\t\t}\n\t}\n}\n\n/* Compute time value from (double) parts.  The parts can be either UTC\n * or local time; if local, they need to be (conceptually) converted into\n * UTC time.  The parts may represent valid or invalid time, and may be\n * wildly out of range (but may cancel each other and still come out in\n * the valid Date range).\n */\nDUK_INTERNAL duk_double_t duk_bi_date_get_timeval_from_dparts(duk_double_t *dparts, duk_small_uint_t flags) {\n#if defined(DUK_USE_PARANOID_DATE_COMPUTATION)\n\t/* See comments below on MakeTime why these are volatile. */\n\tvolatile duk_double_t tmp_time;\n\tvolatile duk_double_t tmp_day;\n\tvolatile duk_double_t d;\n#else\n\tduk_double_t tmp_time;\n\tduk_double_t tmp_day;\n\tduk_double_t d;\n#endif\n\tduk_small_uint_t i;\n\tduk_int_t tzoff, tzoffprev1, tzoffprev2;\n\n\t/* Expects 'this' at top of stack on entry. */\n\n\t/* Coerce all finite parts with ToInteger().  ToInteger() must not\n\t * be called for NaN/Infinity because it will convert e.g. NaN to\n\t * zero.  If ToInteger() has already been called, this has no side\n\t * effects and is idempotent.\n\t *\n\t * Don't read dparts[DUK_DATE_IDX_WEEKDAY]; it will cause Valgrind\n\t * issues if the value is uninitialized.\n\t */\n\tfor (i = 0; i <= DUK_DATE_IDX_MILLISECOND; i++) {\n\t\t/* SCANBUILD: scan-build complains here about assigned value\n\t\t * being garbage or undefined.  This is correct but operating\n\t\t * on undefined values has no ill effect and is ignored by the\n\t\t * caller in the case where this happens.\n\t\t */\n\t\td = dparts[i];\n\t\tif (DUK_ISFINITE(d)) {\n\t\t\tdparts[i] = duk_js_tointeger_number(d);\n\t\t}\n\t}\n\n\t/* Use explicit steps in computation to try to ensure that\n\t * computation happens with intermediate results coerced to\n\t * double values (instead of using something more accurate).\n\t * E.g. E5.1 Section 15.9.1.11 requires use of IEEE 754\n\t * rules (= ECMAScript '+' and '*' operators).\n\t *\n\t * Without 'volatile' even this approach fails on some platform\n\t * and compiler combinations.  For instance, gcc 4.8.1 on Ubuntu\n\t * 64-bit, with -m32 and without -std=c99, test-bi-date-canceling.js\n\t * would fail because of some optimizations when computing tmp_time\n\t * (MakeTime below).  Adding 'volatile' to tmp_time solved this\n\t * particular problem (annoyingly, also adding debug prints or\n\t * running the executable under valgrind hides it).\n\t */\n\n\t/* MakeTime */\n\ttmp_time = 0.0;\n\ttmp_time += dparts[DUK_DATE_IDX_HOUR] * ((duk_double_t) DUK_DATE_MSEC_HOUR);\n\ttmp_time += dparts[DUK_DATE_IDX_MINUTE] * ((duk_double_t) DUK_DATE_MSEC_MINUTE);\n\ttmp_time += dparts[DUK_DATE_IDX_SECOND] * ((duk_double_t) DUK_DATE_MSEC_SECOND);\n\ttmp_time += dparts[DUK_DATE_IDX_MILLISECOND];\n\n\t/* MakeDay */\n\ttmp_day = duk__make_day(dparts[DUK_DATE_IDX_YEAR], dparts[DUK_DATE_IDX_MONTH], dparts[DUK_DATE_IDX_DAY]);\n\n\t/* MakeDate */\n\td = tmp_day * ((duk_double_t) DUK_DATE_MSEC_DAY) + tmp_time;\n\n\tDUK_DDD(DUK_DDDPRINT(\"time=%lf day=%lf --> timeval=%lf\",\n\t                     (double) tmp_time, (double) tmp_day, (double) d));\n\n\t/* Optional UTC conversion. */\n\tif (flags & DUK_DATE_FLAG_LOCALTIME) {\n\t\t/* DUK_USE_DATE_GET_LOCAL_TZOFFSET() needs to be called with a\n\t\t * time value computed from UTC parts.  At this point we only\n\t\t * have 'd' which is a time value computed from local parts, so\n\t\t * it is off by the UTC-to-local time offset which we don't know\n\t\t * yet.  The current solution for computing the UTC-to-local\n\t\t * time offset is to iterate a few times and detect a fixed\n\t\t * point or a two-cycle loop (or a sanity iteration limit),\n\t\t * see test-bi-date-local-parts.js and test-bi-date-tzoffset-basic-fi.js.\n\t\t *\n\t\t * E5.1 Section 15.9.1.9:\n\t\t * UTC(t) = t - LocalTZA - DaylightSavingTA(t - LocalTZA)\n\t\t *\n\t\t * For NaN/inf, DUK_USE_DATE_GET_LOCAL_TZOFFSET() returns 0.\n\t\t */\n\n#if 0\n\t\t/* Old solution: don't iterate, incorrect */\n\t\ttzoff = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);\n\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset w/o iteration, tzoff=%ld\", (long) tzoff));\n\t\td -= tzoff * 1000L;\n\t\tDUK_UNREF(tzoffprev1);\n\t\tDUK_UNREF(tzoffprev2);\n#endif\n\n\t\t/* Iteration solution */\n\t\ttzoff = 0;\n\t\ttzoffprev1 = 999999999L;  /* invalid value which never matches */\n\t\tfor (i = 0; i < DUK__LOCAL_TZOFFSET_MAXITER; i++) {\n\t\t\ttzoffprev2 = tzoffprev1;\n\t\t\ttzoffprev1 = tzoff;\n\t\t\ttzoff = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d - tzoff * 1000L);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration, i=%d, tzoff=%ld, tzoffprev1=%ld tzoffprev2=%ld\",\n\t\t\t                     (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2));\n\t\t\tif (tzoff == tzoffprev1) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration finished, i=%d, tzoff=%ld, tzoffprev1=%ld, tzoffprev2=%ld\",\n\t\t\t\t                     (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2));\n\t\t\t\tbreak;\n\t\t\t} else if (tzoff == tzoffprev2) {\n\t\t\t\t/* Two value cycle, see e.g. test-bi-date-tzoffset-basic-fi.js.\n\t\t\t\t * In these cases, favor a higher tzoffset to get a consistent\n\t\t\t\t * result which is independent of iteration count.  Not sure if\n\t\t\t\t * this is a generically correct solution.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration two-value cycle, i=%d, tzoff=%ld, tzoffprev1=%ld, tzoffprev2=%ld\",\n\t\t\t\t                     (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2));\n\t\t\t\tif (tzoffprev1 > tzoff) {\n\t\t\t\t\ttzoff = tzoffprev1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration, tzoff=%ld\", (long) tzoff));\n\t\td -= tzoff * 1000L;\n\t}\n\n\t/* TimeClip(), which also handles Infinity -> NaN conversion */\n\td = duk__timeclip(d);\n\n\treturn d;\n}\n\n/*\n *  API oriented helpers\n */\n\n/* Push 'this' binding, check that it is a Date object; then push the\n * internal time value.  At the end, stack is: [ ... this timeval ].\n * Returns the time value.  Local time adjustment is done if requested.\n */\nDUK_LOCAL duk_double_t duk__push_this_get_timeval_tzoffset(duk_hthread *thr, duk_small_uint_t flags, duk_int_t *out_tzoffset) {\n\tduk_hobject *h;\n\tduk_double_t d;\n\tduk_int_t tzoffset = 0;\n\n\tduk_push_this(thr);\n\th = duk_get_hobject(thr, -1);  /* XXX: getter with class check, useful in built-ins */\n\tif (h == NULL || DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_DATE) {\n\t\tDUK_ERROR_TYPE(thr, \"expected Date\");\n\t\tDUK_WO_NORETURN(return 0.0;);\n\t}\n\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\td = duk_to_number_m1(thr);\n\tduk_pop(thr);\n\n\tif (DUK_ISNAN(d)) {\n\t\tif (flags & DUK_DATE_FLAG_NAN_TO_ZERO) {\n\t\t\td = 0.0;\n\t\t}\n\t\tif (flags & DUK_DATE_FLAG_NAN_TO_RANGE_ERROR) {\n\t\t\tDUK_ERROR_RANGE(thr, \"Invalid Date\");\n\t\t\tDUK_WO_NORETURN(return 0.0;);\n\t\t}\n\t}\n\t/* if no NaN handling flag, may still be NaN here, but not Inf */\n\tDUK_ASSERT(!DUK_ISINF(d));\n\n\tif (flags & DUK_DATE_FLAG_LOCALTIME) {\n\t\t/* Note: DST adjustment is determined using UTC time.\n\t\t * If 'd' is NaN, tzoffset will be 0.\n\t\t */\n\t\ttzoffset = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);  /* seconds */\n\t\td += tzoffset * 1000L;\n\t}\n\tif (out_tzoffset) {\n\t\t*out_tzoffset = tzoffset;\n\t}\n\n\t/* [ ... this ] */\n\treturn d;\n}\n\nDUK_LOCAL duk_double_t duk__push_this_get_timeval(duk_hthread *thr, duk_small_uint_t flags) {\n\treturn duk__push_this_get_timeval_tzoffset(thr, flags, NULL);\n}\n\n/* Set timeval to 'this' from dparts, push the new time value onto the\n * value stack and return 1 (caller can then tail call us).  Expects\n * the value stack to contain 'this' on the stack top.\n */\nDUK_LOCAL duk_ret_t duk__set_this_timeval_from_dparts(duk_hthread *thr, duk_double_t *dparts, duk_small_uint_t flags) {\n\tduk_double_t d;\n\n\t/* [ ... this ] */\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, flags);\n\tduk_push_number(thr, d);  /* -> [ ... this timeval_new ] */\n\tduk_dup_top(thr);         /* -> [ ... this timeval_new timeval_new ] */\n\n\t/* Must force write because e.g. .setYear() must work even when\n\t * the Date instance is frozen.\n\t */\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\n\t/* Stack top: new time value, return 1 to allow tail calls. */\n\treturn 1;\n}\n\n/* 'out_buf' must be at least DUK_BI_DATE_ISO8601_BUFSIZE long. */\nDUK_LOCAL void duk__format_parts_iso8601(duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags, duk_uint8_t *out_buf) {\n\tchar yearstr[8];   /* \"-123456\\0\" */\n\tchar tzstr[8];     /* \"+11:22\\0\" */\n\tchar sep = (flags & DUK_DATE_FLAG_SEP_T) ? DUK_ASC_UC_T : DUK_ASC_SPACE;\n\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MONTH] >= 1 && parts[DUK_DATE_IDX_MONTH] <= 12);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_DAY] >= 1 && parts[DUK_DATE_IDX_DAY] <= 31);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_YEAR] >= -999999 && parts[DUK_DATE_IDX_YEAR] <= 999999);\n\n\t/* Note: %06d for positive value, %07d for negative value to include\n\t * sign and 6 digits.\n\t */\n\tDUK_SNPRINTF(yearstr,\n\t             sizeof(yearstr),\n\t             (parts[DUK_DATE_IDX_YEAR] >= 0 && parts[DUK_DATE_IDX_YEAR] <= 9999) ? \"%04ld\" :\n\t                    ((parts[DUK_DATE_IDX_YEAR] >= 0) ? \"+%06ld\" : \"%07ld\"),\n\t             (long) parts[DUK_DATE_IDX_YEAR]);\n\tyearstr[sizeof(yearstr) - 1] = (char) 0;\n\n\tif (flags & DUK_DATE_FLAG_LOCALTIME) {\n\t\t/* tzoffset seconds are dropped; 16 bits suffice for\n\t\t * time offset in minutes\n\t\t */\n\t\tconst char *fmt;\n\t\tduk_small_int_t tmp, arg_hours, arg_minutes;\n\n\t\tif (tzoffset >= 0) {\n\t\t\ttmp = tzoffset;\n\t\t\tfmt = \"+%02d:%02d\";\n\t\t} else {\n\t\t\ttmp = -tzoffset;\n\t\t\tfmt = \"-%02d:%02d\";\n\t\t}\n\t\ttmp = tmp / 60;\n\t\targ_hours = tmp / 60;\n\t\targ_minutes = tmp % 60;\n\t\tDUK_ASSERT(arg_hours <= 24);  /* Even less is actually guaranteed for a valid tzoffset. */\n\t\targ_hours = arg_hours & 0x3f;  /* For [0,24] this is a no-op, but fixes GCC 7 warning, see https://github.com/svaarala/duktape/issues/1602. */\n\n\t\tDUK_SNPRINTF(tzstr, sizeof(tzstr), fmt, (int) arg_hours, (int) arg_minutes);\n\t\ttzstr[sizeof(tzstr) - 1] = (char) 0;\n\t} else {\n\t\ttzstr[0] = DUK_ASC_UC_Z;\n\t\ttzstr[1] = (char) 0;\n\t}\n\n\t/* Unlike year, the other parts fit into 16 bits so %d format\n\t * is portable.\n\t */\n\tif ((flags & DUK_DATE_FLAG_TOSTRING_DATE) && (flags & DUK_DATE_FLAG_TOSTRING_TIME)) {\n\t\tDUK_SPRINTF((char *) out_buf, \"%s-%02d-%02d%c%02d:%02d:%02d.%03d%s\",\n\t\t            (const char *) yearstr, (int) parts[DUK_DATE_IDX_MONTH], (int) parts[DUK_DATE_IDX_DAY], (int) sep,\n\t\t            (int) parts[DUK_DATE_IDX_HOUR], (int) parts[DUK_DATE_IDX_MINUTE],\n\t\t            (int) parts[DUK_DATE_IDX_SECOND], (int) parts[DUK_DATE_IDX_MILLISECOND], (const char *) tzstr);\n\t} else if (flags & DUK_DATE_FLAG_TOSTRING_DATE) {\n\t\tDUK_SPRINTF((char *) out_buf, \"%s-%02d-%02d\",\n\t\t            (const char *) yearstr, (int) parts[DUK_DATE_IDX_MONTH], (int) parts[DUK_DATE_IDX_DAY]);\n\t} else {\n\t\tDUK_ASSERT(flags & DUK_DATE_FLAG_TOSTRING_TIME);\n\t\tDUK_SPRINTF((char *) out_buf, \"%02d:%02d:%02d.%03d%s\",\n\t\t            (int) parts[DUK_DATE_IDX_HOUR], (int) parts[DUK_DATE_IDX_MINUTE],\n\t\t            (int) parts[DUK_DATE_IDX_SECOND], (int) parts[DUK_DATE_IDX_MILLISECOND],\n\t\t            (const char *) tzstr);\n\t}\n}\n\n/* Helper for string conversion calls: check 'this' binding, get the\n * internal time value, and format date and/or time in a few formats.\n * Return value allows tail calls.\n */\nDUK_LOCAL duk_ret_t duk__to_string_helper(duk_hthread *thr, duk_small_uint_t flags) {\n\tduk_double_t d;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_int_t tzoffset;  /* seconds, doesn't fit into 16 bits */\n\tduk_bool_t rc;\n\tduk_uint8_t buf[DUK_BI_DATE_ISO8601_BUFSIZE];\n\n\tDUK_UNREF(rc);  /* unreferenced with some options */\n\n\td = duk__push_this_get_timeval_tzoffset(thr, flags, &tzoffset);\n\tif (DUK_ISNAN(d)) {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_INVALID_DATE);\n\t\treturn 1;\n\t}\n\tDUK_ASSERT(DUK_ISFINITE(d));\n\n\t/* formatters always get one-based month/day-of-month */\n\tduk_bi_date_timeval_to_parts(d, parts, NULL, DUK_DATE_FLAG_ONEBASED);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MONTH] >= 1 && parts[DUK_DATE_IDX_MONTH] <= 12);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_DAY] >= 1 && parts[DUK_DATE_IDX_DAY] <= 31);\n\n\tif (flags & DUK_DATE_FLAG_TOSTRING_LOCALE) {\n\t\t/* try locale specific formatter; if it refuses to format the\n\t\t * string, fall back to an ISO 8601 formatted value in local\n\t\t * time.\n\t\t */\n#if defined(DUK_USE_DATE_FORMAT_STRING)\n\t\t/* Contract, either:\n\t\t * - Push string to value stack and return 1\n\t\t * - Don't push anything and return 0\n\t\t */\n\n\t\trc = DUK_USE_DATE_FORMAT_STRING(thr, parts, tzoffset, flags);\n\t\tif (rc != 0) {\n\t\t\treturn 1;\n\t\t}\n#else\n\t\t/* No locale specific formatter; this is OK, we fall back\n\t\t * to ISO 8601.\n\t\t */\n#endif\n\t}\n\n\t/* Different calling convention than above used because the helper\n\t * is shared.\n\t */\n\tduk__format_parts_iso8601(parts, tzoffset, flags, buf);\n\tduk_push_string(thr, (const char *) buf);\n\treturn 1;\n}\n\n/* Helper for component getter calls: check 'this' binding, get the\n * internal time value, split it into parts (either as UTC time or\n * local time), push a specified component as a return value to the\n * value stack and return 1 (caller can then tail call us).\n */\nDUK_LOCAL duk_ret_t duk__get_part_helper(duk_hthread *thr, duk_small_uint_t flags_and_idx) {\n\tduk_double_t d;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_small_uint_t idx_part = (duk_small_uint_t) (flags_and_idx >> DUK_DATE_FLAG_VALUE_SHIFT);  /* unpack args */\n\n\tDUK_ASSERT_DISABLE(idx_part >= 0);  /* unsigned */\n\tDUK_ASSERT(idx_part < DUK_DATE_IDX_NUM_PARTS);\n\n\td = duk__push_this_get_timeval(thr, flags_and_idx);\n\tif (DUK_ISNAN(d)) {\n\t\tduk_push_nan(thr);\n\t\treturn 1;\n\t}\n\tDUK_ASSERT(DUK_ISFINITE(d));\n\n\tduk_bi_date_timeval_to_parts(d, parts, NULL, flags_and_idx);  /* no need to mask idx portion */\n\n\t/* Setter APIs detect special year numbers (0...99) and apply a +1900\n\t * only in certain cases.  The legacy getYear() getter applies -1900\n\t * unconditionally.\n\t */\n\tduk_push_int(thr, (flags_and_idx & DUK_DATE_FLAG_SUB1900) ? parts[idx_part] - 1900 : parts[idx_part]);\n\treturn 1;\n}\n\n/* Helper for component setter calls: check 'this' binding, get the\n * internal time value, split it into parts (either as UTC time or\n * local time), modify one or more components as specified, recompute\n * the time value, set it as the internal value.  Finally, push the\n * new time value as a return value to the value stack and return 1\n * (caller can then tail call us).\n */\nDUK_LOCAL duk_ret_t duk__set_part_helper(duk_hthread *thr, duk_small_uint_t flags_and_maxnargs) {\n\tduk_double_t d;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_idx_t nargs;\n\tduk_small_uint_t maxnargs = (duk_small_uint_t) (flags_and_maxnargs >> DUK_DATE_FLAG_VALUE_SHIFT);  /* unpack args */\n\tduk_small_uint_t idx_first, idx;\n\tduk_small_uint_t i;\n\n\tnargs = duk_get_top(thr);\n\td = duk__push_this_get_timeval(thr, flags_and_maxnargs);\n\tDUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));\n\n\tif (DUK_ISFINITE(d)) {\n\t\tduk_bi_date_timeval_to_parts(d, parts, dparts, flags_and_maxnargs);\n\t} else {\n\t\t/* NaN timevalue: we need to coerce the arguments, but\n\t\t * the resulting internal timestamp needs to remain NaN.\n\t\t * This works but is not pretty: parts and dparts will\n\t\t * be partially uninitialized, but we only write to them.\n\t\t */\n\t}\n\n\t/*\n\t *  Determining which datetime components to overwrite based on\n\t *  stack arguments is a bit complicated, but important to factor\n\t *  out from setters themselves for compactness.\n\t *\n\t *  If DUK_DATE_FLAG_TIMESETTER, maxnargs indicates setter type:\n\t *\n\t *   1 -> millisecond\n\t *   2 -> second, [millisecond]\n\t *   3 -> minute, [second], [millisecond]\n\t *   4 -> hour, [minute], [second], [millisecond]\n\t *\n\t *  Else:\n\t *\n\t *   1 -> date\n\t *   2 -> month, [date]\n\t *   3 -> year, [month], [date]\n\t *\n\t *  By comparing nargs and maxnargs (and flags) we know which\n\t *  components to override.  We rely on part index ordering.\n\t */\n\n\tif (flags_and_maxnargs & DUK_DATE_FLAG_TIMESETTER) {\n\t\tDUK_ASSERT(maxnargs >= 1 && maxnargs <= 4);\n\t\tidx_first = DUK_DATE_IDX_MILLISECOND - (maxnargs - 1);\n\t} else {\n\t\tDUK_ASSERT(maxnargs >= 1 && maxnargs <= 3);\n\t\tidx_first = DUK_DATE_IDX_DAY - (maxnargs - 1);\n\t}\n\tDUK_ASSERT_DISABLE(idx_first >= 0);  /* unsigned */\n\tDUK_ASSERT(idx_first < DUK_DATE_IDX_NUM_PARTS);\n\n\tfor (i = 0; i < maxnargs; i++) {\n\t\tif ((duk_idx_t) i >= nargs) {\n\t\t\t/* no argument given -> leave components untouched */\n\t\t\tbreak;\n\t\t}\n\t\tidx = idx_first + i;\n\t\tDUK_ASSERT_DISABLE(idx >= 0);  /* unsigned */\n\t\tDUK_ASSERT(idx < DUK_DATE_IDX_NUM_PARTS);\n\n\t\tif (idx == DUK_DATE_IDX_YEAR && (flags_and_maxnargs & DUK_DATE_FLAG_YEAR_FIXUP)) {\n\t\t\tduk__twodigit_year_fixup(thr, (duk_idx_t) i);\n\t\t}\n\n\t\tdparts[idx] = duk_to_number(thr, (duk_idx_t) i);\n\n\t\tif (idx == DUK_DATE_IDX_DAY) {\n\t\t\t/* Day-of-month is one-based in the API, but zero-based\n\t\t\t * internally, so fix here.  Note that month is zero-based\n\t\t\t * both in the API and internally.\n\t\t\t */\n\t\t\t/* SCANBUILD: complains about use of uninitialized values.\n\t\t\t * The complaint is correct, but operating in undefined\n\t\t\t * values here is intentional in some cases and the caller\n\t\t\t * ignores the results.\n\t\t\t */\n\t\t\tdparts[idx] -= 1.0;\n\t\t}\n\t}\n\n\t/* Leaves new timevalue on stack top and returns 1, which is correct\n\t * for part setters.\n\t */\n\tif (DUK_ISFINITE(d)) {\n\t\treturn duk__set_this_timeval_from_dparts(thr, dparts, flags_and_maxnargs);\n\t} else {\n\t\t/* Internal timevalue is already NaN, so don't touch it. */\n\t\tduk_push_nan(thr);\n\t\treturn 1;\n\t}\n}\n\n/* Apply ToNumber() to specified index; if ToInteger(val) in [0,99], add\n * 1900 and replace value at idx_val.\n */\nDUK_LOCAL void duk__twodigit_year_fixup(duk_hthread *thr, duk_idx_t idx_val) {\n\tduk_double_t d;\n\n\t/* XXX: idx_val would fit into 16 bits, but using duk_small_uint_t\n\t * might not generate better code due to casting.\n\t */\n\n\t/* E5 Sections 15.9.3.1, B.2.4, B.2.5 */\n\tduk_to_number(thr, idx_val);\n\tif (duk_is_nan(thr, idx_val)) {\n\t\treturn;\n\t}\n\tduk_dup(thr, idx_val);\n\tduk_to_int(thr, -1);\n\td = duk_get_number(thr, -1);  /* get as double to handle huge numbers correctly */\n\tif (d >= 0.0 && d <= 99.0) {\n\t\td += 1900.0;\n\t\tduk_push_number(thr, d);\n\t\tduk_replace(thr, idx_val);\n\t}\n\tduk_pop(thr);\n}\n\n/* Set datetime parts from stack arguments, defaulting any missing values.\n * Day-of-week is not set; it is not required when setting the time value.\n */\nDUK_LOCAL void duk__set_parts_from_args(duk_hthread *thr, duk_double_t *dparts, duk_idx_t nargs) {\n\tduk_double_t d;\n\tduk_small_uint_t i;\n\tduk_small_uint_t idx;\n\n\t/* Causes a ToNumber() coercion, but doesn't break coercion order since\n\t * year is coerced first anyway.\n\t */\n\tduk__twodigit_year_fixup(thr, 0);\n\n\t/* There are at most 7 args, but we use 8 here so that also\n\t * DUK_DATE_IDX_WEEKDAY gets initialized (to zero) to avoid the potential\n\t * for any Valgrind gripes later.\n\t */\n\tfor (i = 0; i < 8; i++) {\n\t\t/* Note: rely on index ordering */\n\t\tidx = DUK_DATE_IDX_YEAR + i;\n\t\tif ((duk_idx_t) i < nargs) {\n\t\t\td = duk_to_number(thr, (duk_idx_t) i);\n\t\t\tif (idx == DUK_DATE_IDX_DAY) {\n\t\t\t\t/* Convert day from one-based to zero-based (internal).  This may\n\t\t\t\t * cause the day part to be negative, which is OK.\n\t\t\t\t */\n\t\t\t\td -= 1.0;\n\t\t\t}\n\t\t} else {\n\t\t\t/* All components default to 0 except day-of-month which defaults\n\t\t\t * to 1.  However, because our internal day-of-month is zero-based,\n\t\t\t * it also defaults to zero here.\n\t\t\t */\n\t\t\td = 0.0;\n\t\t}\n\t\tdparts[idx] = d;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"parts from args -> %lf %lf %lf %lf %lf %lf %lf %lf\",\n\t                     (double) dparts[0], (double) dparts[1],\n\t                     (double) dparts[2], (double) dparts[3],\n\t                     (double) dparts[4], (double) dparts[5],\n\t                     (double) dparts[6], (double) dparts[7]));\n}\n\n/*\n *  Indirect magic value lookup for Date methods.\n *\n *  Date methods don't put their control flags into the function magic value\n *  because they wouldn't fit into a LIGHTFUNC's magic field.  Instead, the\n *  magic value is set to an index pointing to the array of control flags\n *  below.\n *\n *  This must be kept in strict sync with genbuiltins.py!\n */\n\nstatic duk_uint16_t duk__date_magics[] = {\n\t/* 0: toString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 1: toDateString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 2: toTimeString */\n\tDUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 3: toLocaleString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 4: toLocaleDateString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 5: toLocaleTimeString */\n\tDUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 6: toUTCString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME,\n\n\t/* 7: toISOString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_NAN_TO_RANGE_ERROR + DUK_DATE_FLAG_SEP_T,\n\n\t/* 8: getFullYear */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 9: getUTCFullYear */\n\t0 + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 10: getMonth */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MONTH << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 11: getUTCMonth */\n\t0 + (DUK_DATE_IDX_MONTH << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 12: getDate */\n\tDUK_DATE_FLAG_ONEBASED + DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_DAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 13: getUTCDate */\n\tDUK_DATE_FLAG_ONEBASED + (DUK_DATE_IDX_DAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 14: getDay */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_WEEKDAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 15: getUTCDay */\n\t0 + (DUK_DATE_IDX_WEEKDAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 16: getHours */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_HOUR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 17: getUTCHours */\n\t0 + (DUK_DATE_IDX_HOUR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 18: getMinutes */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MINUTE << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 19: getUTCMinutes */\n\t0 + (DUK_DATE_IDX_MINUTE << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 20: getSeconds */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_SECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 21: getUTCSeconds */\n\t0 + (DUK_DATE_IDX_SECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 22: getMilliseconds */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MILLISECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 23: getUTCMilliseconds */\n\t0 + (DUK_DATE_IDX_MILLISECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 24: setMilliseconds */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 25: setUTCMilliseconds */\n\tDUK_DATE_FLAG_TIMESETTER + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 26: setSeconds */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 27: setUTCSeconds */\n\tDUK_DATE_FLAG_TIMESETTER + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 28: setMinutes */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 29: setUTCMinutes */\n\tDUK_DATE_FLAG_TIMESETTER + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 30: setHours */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (4 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 31: setUTCHours */\n\tDUK_DATE_FLAG_TIMESETTER + (4 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 32: setDate */\n\tDUK_DATE_FLAG_LOCALTIME + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 33: setUTCDate */\n\t0 + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 34: setMonth */\n\tDUK_DATE_FLAG_LOCALTIME + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 35: setUTCMonth */\n\t0 + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 36: setFullYear */\n\tDUK_DATE_FLAG_NAN_TO_ZERO + DUK_DATE_FLAG_LOCALTIME + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 37: setUTCFullYear */\n\tDUK_DATE_FLAG_NAN_TO_ZERO + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 38: getYear */\n\tDUK_DATE_FLAG_LOCALTIME + DUK_DATE_FLAG_SUB1900 + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 39: setYear */\n\tDUK_DATE_FLAG_NAN_TO_ZERO + DUK_DATE_FLAG_YEAR_FIXUP + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n};\n\nDUK_LOCAL duk_small_uint_t duk__date_get_indirect_magic(duk_hthread *thr) {\n\tduk_small_uint_t magicidx = (duk_small_uint_t) duk_get_current_magic(thr);\n\tDUK_ASSERT(magicidx < (duk_small_int_t) (sizeof(duk__date_magics) / sizeof(duk_uint16_t)));\n\treturn (duk_small_uint_t) duk__date_magics[magicidx];\n}\n\n#if defined(DUK_USE_DATE_BUILTIN)\n/*\n *  Constructor calls\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor(duk_hthread *thr) {\n\tduk_idx_t nargs = duk_get_top(thr);\n\tduk_bool_t is_cons = duk_is_constructor_call(thr);\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t d;\n\n\tDUK_DDD(DUK_DDDPRINT(\"Date constructor, nargs=%ld, is_cons=%ld\", (long) nargs, (long) is_cons));\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATE),\n\t                              DUK_BIDX_DATE_PROTOTYPE);\n\n\t/* Unlike most built-ins, the internal [[PrimitiveValue]] of a Date\n\t * is mutable.\n\t */\n\n\tif (nargs == 0 || !is_cons) {\n\t\td = duk__timeclip(duk_time_get_ecmascript_time_nofrac(thr));\n\t\tduk_push_number(thr, d);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\t\tif (!is_cons) {\n\t\t\t/* called as a normal function: return new Date().toString() */\n\t\t\tduk_to_string(thr, -1);\n\t\t}\n\t\treturn 1;\n\t} else if (nargs == 1) {\n\t\tconst char *str;\n\t\tduk_to_primitive(thr, 0, DUK_HINT_NONE);\n\t\tstr = duk_get_string_notsymbol(thr, 0);\n\t\tif (str) {\n\t\t\tduk__parse_string(thr, str);\n\t\t\tduk_replace(thr, 0);  /* may be NaN */\n\t\t}\n\t\td = duk__timeclip(duk_to_number(thr, 0));  /* symbols fail here */\n\t\tduk_push_number(thr, d);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\t\treturn 1;\n\t}\n\n\tduk__set_parts_from_args(thr, dparts, nargs);\n\n\t/* Parts are in local time, convert when setting. */\n\n\t(void) duk__set_this_timeval_from_dparts(thr, dparts, DUK_DATE_FLAG_LOCALTIME /*flags*/);  /* -> [ ... this timeval ] */\n\tduk_pop(thr);  /* -> [ ... this ] */\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor_parse(duk_hthread *thr) {\n\treturn duk__parse_string(thr, duk_to_string(thr, 0));\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor_utc(duk_hthread *thr) {\n\tduk_idx_t nargs = duk_get_top(thr);\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t d;\n\n\t/* Behavior for nargs < 2 is implementation dependent: currently we'll\n\t * set a NaN time value (matching V8 behavior) in this case.\n\t */\n\n\tif (nargs < 2) {\n\t\tduk_push_nan(thr);\n\t} else {\n\t\tduk__set_parts_from_args(thr, dparts, nargs);\n\t\td = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);\n\t\tduk_push_number(thr, d);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor_now(duk_hthread *thr) {\n\tduk_double_t d;\n\n\td = duk_time_get_ecmascript_time_nofrac(thr);\n\tDUK_ASSERT(duk__timeclip(d) == d);  /* TimeClip() should never be necessary */\n\tduk_push_number(thr, d);\n\treturn 1;\n}\n\n/*\n *  String/JSON conversions\n *\n *  Human readable conversions are now basically ISO 8601 with a space\n *  (instead of 'T') as the date/time separator.  This is a good baseline\n *  and is platform independent.\n *\n *  A shared native helper to provide many conversions.  Magic value contains\n *  a set of flags.  The helper provides:\n *\n *    toString()\n *    toDateString()\n *    toTimeString()\n *    toLocaleString()\n *    toLocaleDateString()\n *    toLocaleTimeString()\n *    toUTCString()\n *    toISOString()\n *\n *  Notes:\n *\n *    - Date.prototype.toGMTString() and Date.prototype.toUTCString() are\n *      required to be the same ECMAScript function object (!), so it is\n *      omitted from here.\n *\n *    - Date.prototype.toUTCString(): E5.1 specification does not require a\n *      specific format, but result should be human readable.  The\n *      specification suggests using ISO 8601 format with a space (instead\n *      of 'T') separator if a more human readable format is not available.\n *\n *    - Date.prototype.toISOString(): unlike other conversion functions,\n *      toISOString() requires a RangeError for invalid date values.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_tostring_shared(duk_hthread *thr) {\n\tduk_small_uint_t flags = duk__date_get_indirect_magic(thr);\n\treturn duk__to_string_helper(thr, flags);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_value_of(duk_hthread *thr) {\n\t/* This native function is also used for Date.prototype.getTime()\n\t * as their behavior is identical.\n\t */\n\n\tduk_double_t d = duk__push_this_get_timeval(thr, 0 /*flags*/);  /* -> [ this ] */\n\tDUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));\n\tduk_push_number(thr, d);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_to_json(duk_hthread *thr) {\n\t/* Note: toJSON() is a generic function which works even if 'this'\n\t * is not a Date.  The sole argument is ignored.\n\t */\n\n\tduk_push_this(thr);\n\tduk_to_object(thr, -1);\n\n\tduk_dup_top(thr);\n\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);\n\tif (duk_is_number(thr, -1)) {\n\t\tduk_double_t d = duk_get_number(thr, -1);\n\t\tif (!DUK_ISFINITE(d)) {\n\t\t\tduk_push_null(thr);\n\t\t\treturn 1;\n\t\t}\n\t}\n\tduk_pop(thr);\n\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_ISO_STRING);\n\tduk_dup_m2(thr);  /* -> [ O toIsoString O ] */\n\tduk_call_method(thr, 0);\n\treturn 1;\n}\n\n/*\n *  Getters.\n *\n *  Implementing getters is quite easy.  The internal time value is either\n *  NaN, or represents milliseconds (without fractions) from Jan 1, 1970.\n *  The internal time value can be converted to integer parts, and each\n *  part will be normalized and will fit into a 32-bit signed integer.\n *\n *  A shared native helper to provide all getters.  Magic value contains\n *  a set of flags and also packs the date component index argument.  The\n *  helper provides:\n *\n *    getFullYear()\n *    getUTCFullYear()\n *    getMonth()\n *    getUTCMonth()\n *    getDate()\n *    getUTCDate()\n *    getDay()\n *    getUTCDay()\n *    getHours()\n *    getUTCHours()\n *    getMinutes()\n *    getUTCMinutes()\n *    getSeconds()\n *    getUTCSeconds()\n *    getMilliseconds()\n *    getUTCMilliseconds()\n *    getYear()\n *\n *  Notes:\n *\n *    - Date.prototype.getDate(): 'date' means day-of-month, and is\n *      zero-based in internal calculations but public API expects it to\n *      be one-based.\n *\n *    - Date.prototype.getTime() and Date.prototype.valueOf() have identical\n *      behavior.  They have separate function objects, but share the same C\n *      function (duk_bi_date_prototype_value_of).\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_shared(duk_hthread *thr) {\n\tduk_small_uint_t flags_and_idx = duk__date_get_indirect_magic(thr);\n\treturn duk__get_part_helper(thr, flags_and_idx);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_timezone_offset(duk_hthread *thr) {\n\t/*\n\t *  Return (t - LocalTime(t)) in minutes:\n\t *\n\t *    t - LocalTime(t) = t - (t + LocalTZA + DaylightSavingTA(t))\n\t *                     = -(LocalTZA + DaylightSavingTA(t))\n\t *\n\t *  where DaylightSavingTA() is checked for time 't'.\n\t *\n\t *  Note that the sign of the result is opposite to common usage,\n\t *  e.g. for EE(S)T which normally is +2h or +3h from UTC, this\n\t *  function returns -120 or -180.\n\t *\n\t */\n\n\tduk_double_t d;\n\tduk_int_t tzoffset;\n\n\t/* Note: DST adjustment is determined using UTC time. */\n\td = duk__push_this_get_timeval(thr, 0 /*flags*/);\n\tDUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));\n\tif (DUK_ISNAN(d)) {\n\t\tduk_push_nan(thr);\n\t} else {\n\t\tDUK_ASSERT(DUK_ISFINITE(d));\n\t\ttzoffset = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);\n\t\tduk_push_int(thr, -tzoffset / 60);\n\t}\n\treturn 1;\n}\n\n/*\n *  Setters.\n *\n *  Setters are a bit more complicated than getters.  Component setters\n *  break down the current time value into its (normalized) component\n *  parts, replace one or more components with -unnormalized- new values,\n *  and the components are then converted back into a time value.  As an\n *  example of using unnormalized values:\n *\n *    var d = new Date(1234567890);\n *\n *  is equivalent to:\n *\n *    var d = new Date(0);\n *    d.setUTCMilliseconds(1234567890);\n *\n *  A shared native helper to provide almost all setters.  Magic value\n *  contains a set of flags and also packs the \"maxnargs\" argument.  The\n *  helper provides:\n *\n *    setMilliseconds()\n *    setUTCMilliseconds()\n *    setSeconds()\n *    setUTCSeconds()\n *    setMinutes()\n *    setUTCMinutes()\n *    setHours()\n *    setUTCHours()\n *    setDate()\n *    setUTCDate()\n *    setMonth()\n *    setUTCMonth()\n *    setFullYear()\n *    setUTCFullYear()\n *    setYear()\n *\n *  Notes:\n *\n *    - Date.prototype.setYear() (Section B addition): special year check\n *      is omitted.  NaN / Infinity will just flow through and ultimately\n *      result in a NaN internal time value.\n *\n *    - Date.prototype.setYear() does not have optional arguments for\n *      setting month and day-in-month (like setFullYear()), but we indicate\n *      'maxnargs' to be 3 to get the year written to the correct component\n *      index in duk__set_part_helper().  The function has nargs == 1, so only\n *      the year will be set regardless of actual argument count.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_shared(duk_hthread *thr) {\n\tduk_small_uint_t flags_and_maxnargs = duk__date_get_indirect_magic(thr);\n\treturn duk__set_part_helper(thr, flags_and_maxnargs);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_time(duk_hthread *thr) {\n\tduk_double_t d;\n\n\t(void) duk__push_this_get_timeval(thr, 0 /*flags*/); /* -> [ timeval this ] */\n\td = duk__timeclip(duk_to_number(thr, 0));\n\tduk_push_number(thr, d);\n\tduk_dup_top(thr);\n\t/* Must force write because .setTime() must work even when\n\t * the Date instance is frozen.\n\t */\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\t/* -> [ timeval this timeval ] */\n\n\treturn 1;\n}\n\n/*\n *  Misc.\n */\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_toprimitive(duk_hthread *thr) {\n\tduk_size_t hintlen;\n\tconst char *hintstr;\n\tduk_int_t hint;\n\n\t/* Invokes OrdinaryToPrimitive() with suitable hint.  Note that the\n\t * method is generic, and works on non-Date arguments too.\n\t *\n\t * https://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype-@@toprimitive\n\t */\n\n\tduk_push_this(thr);\n\tduk_require_object(thr, -1);\n\tDUK_ASSERT_TOP(thr, 2);\n\n\thintstr = duk_require_lstring(thr, 0, &hintlen);\n\tif ((hintlen == 6 && DUK_STRCMP(hintstr, \"string\") == 0) ||\n\t    (hintlen == 7 && DUK_STRCMP(hintstr, \"default\") == 0)) {\n\t\thint = DUK_HINT_STRING;\n\t} else if (hintlen == 6 && DUK_STRCMP(hintstr, \"number\") == 0) {\n\t\thint = DUK_HINT_NUMBER;\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tduk_to_primitive_ordinary(thr, -1, hint);\n\treturn 1;\n}\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n\n#endif  /* DUK_USE_DATE_BUILTIN */\n\n/* automatic undefs */\n#undef DUK__CF_ACCEPT\n#undef DUK__CF_ACCEPT_NUL\n#undef DUK__CF_NEG\n#undef DUK__DPRINT_DPARTS\n#undef DUK__DPRINT_PARTS\n#undef DUK__DPRINT_PARTS_AND_DPARTS\n#undef DUK__LOCAL_TZOFFSET_MAXITER\n#undef DUK__NUM_ISO8601_PARSER_PARTS\n#undef DUK__PACK_RULE\n#undef DUK__PI_DAY\n#undef DUK__PI_HOUR\n#undef DUK__PI_MILLISECOND\n#undef DUK__PI_MINUTE\n#undef DUK__PI_MONTH\n#undef DUK__PI_SECOND\n#undef DUK__PI_TZHOUR\n#undef DUK__PI_TZMINUTE\n#undef DUK__PI_YEAR\n#undef DUK__PM_DAY\n#undef DUK__PM_HOUR\n#undef DUK__PM_MILLISECOND\n#undef DUK__PM_MINUTE\n#undef DUK__PM_MONTH\n#undef DUK__PM_SECOND\n#undef DUK__PM_TZHOUR\n#undef DUK__PM_TZMINUTE\n#undef DUK__PM_YEAR\n#undef DUK__RULE_MASK_PART_SEP\n#undef DUK__SI_COLON\n#undef DUK__SI_MINUS\n#undef DUK__SI_NUL\n#undef DUK__SI_PERIOD\n#undef DUK__SI_PLUS\n#undef DUK__SI_SPACE\n#undef DUK__SI_T\n#undef DUK__SI_Z\n#undef DUK__SM_COLON\n#undef DUK__SM_MINUS\n#undef DUK__SM_NUL\n#undef DUK__SM_PERIOD\n#undef DUK__SM_PLUS\n#undef DUK__SM_SPACE\n#undef DUK__SM_T\n#undef DUK__SM_Z\n#undef DUK__UNPACK_RULE\n#undef DUK__WEEKDAY_MOD_ADDER\n#undef DUK__YEAR\n/*\n *  Unix-like Date providers\n *\n *  Generally useful Unix / POSIX / ANSI Date providers.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* The necessary #includes are in place in duk_config.h. */\n\n/* Buffer sizes for some UNIX calls.  Larger than strictly necessary\n * to avoid Valgrind errors.\n */\n#define DUK__STRPTIME_BUF_SIZE  64\n#define DUK__STRFTIME_BUF_SIZE  64\n\n#if defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)\n/* Get current ECMAScript time (= UNIX/Posix time, but in milliseconds). */\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_gettimeofday(void) {\n\tstruct timeval tv;\n\tduk_double_t d;\n\n\tif (gettimeofday(&tv, NULL) != 0) {\n\t\tDUK_D(DUK_DPRINT(\"gettimeofday() failed\"));\n\t\treturn 0.0;\n\t}\n\n\t/* As of Duktape 2.2.0 allow fractions. */\n\td = ((duk_double_t) tv.tv_sec) * 1000.0 +\n\t    ((duk_double_t) tv.tv_usec) / 1000.0;\n\n\treturn d;\n}\n#endif  /* DUK_USE_DATE_NOW_GETTIMEOFDAY */\n\n#if defined(DUK_USE_DATE_NOW_TIME)\n/* Not a very good provider: only full seconds are available. */\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_time(void) {\n\ttime_t t;\n\n\tt = time(NULL);\n\tif (t == (time_t) -1) {\n\t\tDUK_D(DUK_DPRINT(\"time() failed\"));\n\t\treturn 0.0;\n\t}\n\treturn ((duk_double_t) t) * 1000.0;\n}\n#endif  /* DUK_USE_DATE_NOW_TIME */\n\n#if defined(DUK_USE_DATE_TZO_GMTIME) || defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S)\n/* Get local time offset (in seconds) for a certain (UTC) instant 'd'. */\nDUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d) {\n\ttime_t t, t1, t2;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tstruct tm tms[2];\n#if defined(DUK_USE_DATE_TZO_GMTIME)\n\tstruct tm *tm_ptr;\n#endif\n\n\t/* For NaN/inf, the return value doesn't matter. */\n\tif (!DUK_ISFINITE(d)) {\n\t\treturn 0;\n\t}\n\n\t/* If not within ECMAScript range, some integer time calculations\n\t * won't work correctly (and some asserts will fail), so bail out\n\t * if so.  This fixes test-bug-date-insane-setyear.js.  There is\n\t * a +/- 24h leeway in this range check to avoid a test262 corner\n\t * case documented in test-bug-date-timeval-edges.js.\n\t */\n\tif (!duk_bi_date_timeval_in_leeway_range(d)) {\n\t\tDUK_DD(DUK_DDPRINT(\"timeval not within valid range, skip tzoffset computation to avoid integer overflows\"));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  This is a bit tricky to implement portably.  The result depends\n\t *  on the timestamp (specifically, DST depends on the timestamp).\n\t *  If e.g. UNIX APIs are used, they'll have portability issues with\n\t *  very small and very large years.\n\t *\n\t *  Current approach:\n\t *\n\t *  - Stay within portable UNIX limits by using equivalent year mapping.\n\t *    Avoid year 1970 and 2038 as some conversions start to fail, at\n\t *    least on some platforms.  Avoiding 1970 means that there are\n\t *    currently DST discrepancies for 1970.\n\t *\n\t *  - Create a UTC and local time breakdowns from 't'.  Then create\n\t *    a time_t using gmtime() and localtime() and compute the time\n\t *    difference between the two.\n\t *\n\t *  Equivalent year mapping (E5 Section 15.9.1.8):\n\t *\n\t *    If the host environment provides functionality for determining\n\t *    daylight saving time, the implementation of ECMAScript is free\n\t *    to map the year in question to an equivalent year (same\n\t *    leap-year-ness and same starting week day for the year) for which\n\t *    the host environment provides daylight saving time information.\n\t *    The only restriction is that all equivalent years should produce\n\t *    the same result.\n\t *\n\t *  This approach is quite reasonable but not entirely correct, e.g.\n\t *  the specification also states (E5 Section 15.9.1.8):\n\t *\n\t *    The implementation of ECMAScript should not try to determine\n\t *    whether the exact time was subject to daylight saving time, but\n\t *    just whether daylight saving time would have been in effect if\n\t *    the _current daylight saving time algorithm_ had been used at the\n\t *    time.  This avoids complications such as taking into account the\n\t *    years that the locale observed daylight saving time year round.\n\t *\n\t *  Since we rely on the platform APIs for conversions between local\n\t *  time and UTC, we can't guarantee the above.  Rather, if the platform\n\t *  has historical DST rules they will be applied.  This seems to be the\n\t *  general preferred direction in ECMAScript standardization (or at least\n\t *  implementations) anyway, and even the equivalent year mapping should\n\t *  be disabled if the platform is known to handle DST properly for the\n\t *  full ECMAScript range.\n\t *\n\t *  The following has useful discussion and links:\n\t *\n\t *    https://bugzilla.mozilla.org/show_bug.cgi?id=351066\n\t */\n\n\tduk_bi_date_timeval_to_parts(d, parts, dparts, DUK_DATE_FLAG_EQUIVYEAR /*flags*/);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_YEAR] >= 1970 && parts[DUK_DATE_IDX_YEAR] <= 2038);\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);\n\tDUK_ASSERT(d >= 0 && d < 2147483648.0 * 1000.0);  /* unsigned 31-bit range */\n\tt = (time_t) (d / 1000.0);\n\tDUK_DDD(DUK_DDDPRINT(\"timeval: %lf -> time_t %ld\", (double) d, (long) t));\n\n\tduk_memzero((void *) tms, sizeof(struct tm) * 2);\n\n#if defined(DUK_USE_DATE_TZO_GMTIME_R)\n\t(void) gmtime_r(&t, &tms[0]);\n\t(void) localtime_r(&t, &tms[1]);\n#elif defined(DUK_USE_DATE_TZO_GMTIME_S)\n\t(void) gmtime_s(&t, &tms[0]);\n\t(void) localtime_s(&t, &tms[1]);\n#elif defined(DUK_USE_DATE_TZO_GMTIME)\n\ttm_ptr = gmtime(&t);\n\tduk_memcpy((void *) &tms[0], tm_ptr, sizeof(struct tm));\n\ttm_ptr = localtime(&t);\n\tduk_memcpy((void *) &tms[1], tm_ptr, sizeof(struct tm));\n#else\n#error internal error\n#endif\n\tDUK_DDD(DUK_DDDPRINT(\"gmtime result: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,\"\n\t                     \"wday:%ld,yday:%ld,isdst:%ld}\",\n\t                     (long) tms[0].tm_sec, (long) tms[0].tm_min, (long) tms[0].tm_hour,\n\t                     (long) tms[0].tm_mday, (long) tms[0].tm_mon, (long) tms[0].tm_year,\n\t                     (long) tms[0].tm_wday, (long) tms[0].tm_yday, (long) tms[0].tm_isdst));\n\tDUK_DDD(DUK_DDDPRINT(\"localtime result: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,\"\n\t                     \"wday:%ld,yday:%ld,isdst:%ld}\",\n\t                     (long) tms[1].tm_sec, (long) tms[1].tm_min, (long) tms[1].tm_hour,\n\t                     (long) tms[1].tm_mday, (long) tms[1].tm_mon, (long) tms[1].tm_year,\n\t                     (long) tms[1].tm_wday, (long) tms[1].tm_yday, (long) tms[1].tm_isdst));\n\n\t/* tm_isdst is both an input and an output to mktime(), use 0 to\n\t * avoid DST handling in mktime():\n\t * - https://github.com/svaarala/duktape/issues/406\n\t * - http://stackoverflow.com/questions/8558919/mktime-and-tm-isdst\n\t */\n\ttms[0].tm_isdst = 0;\n\ttms[1].tm_isdst = 0;\n\tt1 = mktime(&tms[0]);  /* UTC */\n\tt2 = mktime(&tms[1]);  /* local */\n\tif (t1 == (time_t) -1 || t2 == (time_t) -1) {\n\t\t/* This check used to be for (t < 0) but on some platforms\n\t\t * time_t is unsigned and apparently the proper way to detect\n\t\t * an mktime() error return is the cast above.  See e.g.:\n\t\t * http://pubs.opengroup.org/onlinepubs/009695299/functions/mktime.html\n\t\t */\n\t\tgoto mktime_error;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"t1=%ld (utc), t2=%ld (local)\", (long) t1, (long) t2));\n\n\t/* Compute final offset in seconds, positive if local time ahead of\n\t * UTC (returned value is UTC-to-local offset).\n\t *\n\t * difftime() returns a double, so coercion to int generates quite\n\t * a lot of code.  Direct subtraction is not portable, however.\n\t * XXX: allow direct subtraction on known platforms.\n\t */\n#if 0\n\treturn (duk_int_t) (t2 - t1);\n#endif\n\treturn (duk_int_t) difftime(t2, t1);\n\n mktime_error:\n\t/* XXX: return something more useful, so that caller can throw? */\n\tDUK_D(DUK_DPRINT(\"mktime() failed, d=%lf\", (double) d));\n\treturn 0;\n}\n#endif  /* DUK_USE_DATE_TZO_GMTIME */\n\n#if defined(DUK_USE_DATE_PRS_STRPTIME)\nDUK_INTERNAL duk_bool_t duk_bi_date_parse_string_strptime(duk_hthread *thr, const char *str) {\n\tstruct tm tm;\n\ttime_t t;\n\tchar buf[DUK__STRPTIME_BUF_SIZE];\n\n\t/* Copy to buffer with slack to avoid Valgrind gripes from strptime. */\n\tDUK_ASSERT(str != NULL);\n\tduk_memzero(buf, sizeof(buf));  /* valgrind whine without this */\n\tDUK_SNPRINTF(buf, sizeof(buf), \"%s\", (const char *) str);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parsing: '%s'\", (const char *) buf));\n\n\tduk_memzero(&tm, sizeof(tm));\n\tif (strptime((const char *) buf, \"%c\", &tm) != NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"before mktime: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,\"\n\t\t                     \"wday:%ld,yday:%ld,isdst:%ld}\",\n\t\t                     (long) tm.tm_sec, (long) tm.tm_min, (long) tm.tm_hour,\n\t\t                     (long) tm.tm_mday, (long) tm.tm_mon, (long) tm.tm_year,\n\t\t                     (long) tm.tm_wday, (long) tm.tm_yday, (long) tm.tm_isdst));\n\t\ttm.tm_isdst = -1;  /* negative: dst info not available */\n\n\t\tt = mktime(&tm);\n\t\tDUK_DDD(DUK_DDDPRINT(\"mktime() -> %ld\", (long) t));\n\t\tif (t >= 0) {\n\t\t\tduk_push_number(thr, ((duk_double_t) t) * 1000.0);\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n#endif  /* DUK_USE_DATE_PRS_STRPTIME */\n\n#if defined(DUK_USE_DATE_PRS_GETDATE)\nDUK_INTERNAL duk_bool_t duk_bi_date_parse_string_getdate(duk_hthread *thr, const char *str) {\n\tstruct tm tm;\n\tduk_small_int_t rc;\n\ttime_t t;\n\n\t/* For this to work, DATEMSK must be set, so this is not very\n\t * convenient for an embeddable interpreter.\n\t */\n\n\tduk_memzero(&tm, sizeof(struct tm));\n\trc = (duk_small_int_t) getdate_r(str, &tm);\n\tDUK_DDD(DUK_DDDPRINT(\"getdate_r() -> %ld\", (long) rc));\n\n\tif (rc == 0) {\n\t\tt = mktime(&tm);\n\t\tDUK_DDD(DUK_DDDPRINT(\"mktime() -> %ld\", (long) t));\n\t\tif (t >= 0) {\n\t\t\tduk_push_number(thr, (duk_double_t) t);\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n#endif  /* DUK_USE_DATE_PRS_GETDATE */\n\n#if defined(DUK_USE_DATE_FMT_STRFTIME)\nDUK_INTERNAL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags) {\n\tchar buf[DUK__STRFTIME_BUF_SIZE];\n\tstruct tm tm;\n\tconst char *fmt;\n\n\tDUK_UNREF(tzoffset);\n\n\t/* If the platform doesn't support the entire ECMAScript range, we need\n\t * to return 0 so that the caller can fall back to the default formatter.\n\t *\n\t * For now, assume that if time_t is 8 bytes or more, the whole ECMAScript\n\t * range is supported.  For smaller time_t values (4 bytes in practice),\n\t * assumes that the signed 32-bit range is supported.\n\t *\n\t * XXX: detect this more correctly per platform.  The size of time_t is\n\t * probably not an accurate guarantee of strftime() supporting or not\n\t * supporting a large time range (the full ECMAScript range).\n\t */\n\tif (sizeof(time_t) < 8 &&\n\t    (parts[DUK_DATE_IDX_YEAR] < 1970 || parts[DUK_DATE_IDX_YEAR] > 2037)) {\n\t\t/* be paranoid for 32-bit time values (even avoiding negative ones) */\n\t\treturn 0;\n\t}\n\n\tduk_memzero(&tm, sizeof(tm));\n\ttm.tm_sec = parts[DUK_DATE_IDX_SECOND];\n\ttm.tm_min = parts[DUK_DATE_IDX_MINUTE];\n\ttm.tm_hour = parts[DUK_DATE_IDX_HOUR];\n\ttm.tm_mday = parts[DUK_DATE_IDX_DAY];       /* already one-based */\n\ttm.tm_mon = parts[DUK_DATE_IDX_MONTH] - 1;  /* one-based -> zero-based */\n\ttm.tm_year = parts[DUK_DATE_IDX_YEAR] - 1900;\n\ttm.tm_wday = parts[DUK_DATE_IDX_WEEKDAY];\n\ttm.tm_isdst = 0;\n\n\tduk_memzero(buf, sizeof(buf));\n\tif ((flags & DUK_DATE_FLAG_TOSTRING_DATE) && (flags & DUK_DATE_FLAG_TOSTRING_TIME)) {\n\t\tfmt = \"%c\";\n\t} else if (flags & DUK_DATE_FLAG_TOSTRING_DATE) {\n\t\tfmt = \"%x\";\n\t} else {\n\t\tDUK_ASSERT(flags & DUK_DATE_FLAG_TOSTRING_TIME);\n\t\tfmt = \"%X\";\n\t}\n\t(void) strftime(buf, sizeof(buf) - 1, fmt, &tm);\n\tDUK_ASSERT(buf[sizeof(buf) - 1] == 0);\n\n\tduk_push_string(thr, buf);\n\treturn 1;\n}\n#endif  /* DUK_USE_DATE_FMT_STRFTIME */\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)\nDUK_INTERNAL duk_double_t duk_bi_date_get_monotonic_time_clock_gettime(void) {\n\tstruct timespec ts;\n\n\tif (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {\n\t\treturn (duk_double_t) ts.tv_sec * 1000.0 + (duk_double_t) ts.tv_nsec / 1000000.0;\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"clock_gettime(CLOCK_MONOTONIC) failed\"));\n\t\treturn 0.0;\n\t}\n}\n#endif\n\n/* automatic undefs */\n#undef DUK__STRFTIME_BUF_SIZE\n#undef DUK__STRPTIME_BUF_SIZE\n/*\n *  Windows Date providers\n *\n *  Platform specific links:\n *\n *    - http://msdn.microsoft.com/en-us/library/windows/desktop/ms725473(v=vs.85).aspx\n */\n\n/* #include duk_internal.h -> already included */\n\n/* The necessary #includes are in place in duk_config.h. */\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS) || defined(DUK_USE_DATE_TZO_WINDOWS)\n/* Shared Windows helpers. */\nDUK_LOCAL void duk__convert_systime_to_ularge(const SYSTEMTIME *st, ULARGE_INTEGER *res) {\n\tFILETIME ft;\n\tif (SystemTimeToFileTime(st, &ft) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"SystemTimeToFileTime() failed, returning 0\"));\n\t\tres->QuadPart = 0;\n\t} else {\n\t\tres->LowPart = ft.dwLowDateTime;\n\t\tres->HighPart = ft.dwHighDateTime;\n\t}\n}\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\nDUK_LOCAL void duk__convert_filetime_to_ularge(const FILETIME *ft, ULARGE_INTEGER *res) {\n\tres->LowPart = ft->dwLowDateTime;\n\tres->HighPart = ft->dwHighDateTime;\n}\n#endif  /* DUK_USE_DATE_NOW_WINDOWS_SUBMS */\n\nDUK_LOCAL void duk__set_systime_jan1970(SYSTEMTIME *st) {\n\tduk_memzero((void *) st, sizeof(*st));\n\tst->wYear = 1970;\n\tst->wMonth = 1;\n\tst->wDayOfWeek = 4;  /* not sure whether or not needed; Thursday */\n\tst->wDay = 1;\n\tDUK_ASSERT(st->wHour == 0);\n\tDUK_ASSERT(st->wMinute == 0);\n\tDUK_ASSERT(st->wSecond == 0);\n\tDUK_ASSERT(st->wMilliseconds == 0);\n}\n#endif  /* defined(DUK_USE_DATE_NOW_WINDOWS) || defined(DUK_USE_DATE_TZO_WINDOWS) */\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS)\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_windows(void) {\n\t/* Suggested step-by-step method from documentation of RtlTimeToSecondsSince1970:\n\t * http://msdn.microsoft.com/en-us/library/windows/desktop/ms724928(v=vs.85).aspx\n\t */\n\tSYSTEMTIME st1, st2;\n\tULARGE_INTEGER tmp1, tmp2;\n\n\tGetSystemTime(&st1);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1);\n\n\tduk__set_systime_jan1970(&st2);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);\n\n\t/* Difference is in 100ns units, convert to milliseconds, keeping\n\t * fractions since Duktape 2.2.0.  This is only theoretical because\n\t * SYSTEMTIME is limited to milliseconds.\n\t */\n\treturn (duk_double_t) ((LONGLONG) tmp1.QuadPart - (LONGLONG) tmp2.QuadPart) / 10000.0;\n}\n#endif  /* DUK_USE_DATE_NOW_WINDOWS */\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_windows_subms(void) {\n\t/* Variant of the basic algorithm using GetSystemTimePreciseAsFileTime()\n\t * for more accuracy.\n\t */\n\tFILETIME ft1;\n\tSYSTEMTIME st2;\n\tULARGE_INTEGER tmp1, tmp2;\n\n\tGetSystemTimePreciseAsFileTime(&ft1);\n\tduk__convert_filetime_to_ularge((const FILETIME *) &ft1, &tmp1);\n\n\tduk__set_systime_jan1970(&st2);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);\n\n\t/* Difference is in 100ns units, convert to milliseconds, keeping\n\t * fractions since Duktape 2.2.0.\n\t */\n\treturn (duk_double_t) ((LONGLONG) tmp1.QuadPart - (LONGLONG) tmp2.QuadPart) / 10000.0;\n}\n#endif  /* DUK_USE_DATE_NOW_WINDOWS */\n\n#if defined(DUK_USE_DATE_TZO_WINDOWS)\nDUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d) {\n\tSYSTEMTIME st1;\n\tSYSTEMTIME st2;\n\tSYSTEMTIME st3;\n\tULARGE_INTEGER tmp1;\n\tULARGE_INTEGER tmp2;\n\tULARGE_INTEGER tmp3;\n\tFILETIME ft1;\n\n\t/* XXX: handling of timestamps outside Windows supported range.\n\t * How does Windows deal with dates before 1600?  Does windows\n\t * support all ECMAScript years (like -200000 and +200000)?\n\t * Should equivalent year mapping be used here too?  If so, use\n\t * a shared helper (currently integrated into timeval-to-parts).\n\t */\n\n\t/* Use the approach described in \"Remarks\" of FileTimeToLocalFileTime:\n\t * http://msdn.microsoft.com/en-us/library/windows/desktop/ms724277(v=vs.85).aspx\n\t */\n\n\tduk__set_systime_jan1970(&st1);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1);\n\ttmp2.QuadPart = (ULONGLONG) (d * 10000.0);  /* millisec -> 100ns units since jan 1, 1970 */\n\ttmp2.QuadPart += tmp1.QuadPart;             /* input 'd' in Windows UTC, 100ns units */\n\n\tft1.dwLowDateTime = tmp2.LowPart;\n\tft1.dwHighDateTime = tmp2.HighPart;\n\tif (FileTimeToSystemTime((const FILETIME *) &ft1, &st2) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"FileTimeToSystemTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tif (SystemTimeToTzSpecificLocalTime((LPTIME_ZONE_INFORMATION) NULL, &st2, &st3) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"SystemTimeToTzSpecificLocalTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st3, &tmp3);\n\n\t/* Positive if local time ahead of UTC. */\n\treturn (duk_int_t) (((LONGLONG) tmp3.QuadPart - (LONGLONG) tmp2.QuadPart) / DUK_I64_CONSTANT(10000000));  /* seconds */\n}\n#endif  /* DUK_USE_DATE_TZO_WINDOWS */\n\n#if defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST)\nDUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_t d) {\n\tSYSTEMTIME st1;\n\tSYSTEMTIME st2;\n\tFILETIME ft1;\n\tFILETIME ft2;\n\tULARGE_INTEGER tmp1;\n\tULARGE_INTEGER tmp2;\n\n\t/* Do a similar computation to duk_bi_date_get_local_tzoffset_windows\n\t * but without accounting for daylight savings time.  Use this on\n\t * Windows platforms (like Durango) that don't support the\n\t * SystemTimeToTzSpecificLocalTime() call.\n\t */\n\n\t/* current time not needed for this computation */\n\tDUK_UNREF(d);\n\n\tduk__set_systime_jan1970(&st1);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1);\n\n\tft1.dwLowDateTime = tmp1.LowPart;\n\tft1.dwHighDateTime = tmp1.HighPart;\n\tif (FileTimeToLocalFileTime((const FILETIME *) &ft1, &ft2) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"FileTimeToLocalFileTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tif (FileTimeToSystemTime((const FILETIME *) &ft2, &st2) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"FileTimeToSystemTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);\n\n\treturn (duk_int_t) (((LONGLONG) tmp2.QuadPart - (LONGLONG) tmp1.QuadPart) / DUK_I64_CONSTANT(10000000));  /* seconds */\n}\n#endif  /* DUK_USE_DATE_TZO_WINDOWS_NO_DST */\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC)\nDUK_INTERNAL duk_double_t duk_bi_date_get_monotonic_time_windows_qpc(void) {\n\tLARGE_INTEGER count, freq;\n\n\t/* There are legacy issues with QueryPerformanceCounter():\n\t * - Potential jumps: https://support.microsoft.com/en-us/help/274323/performance-counter-value-may-unexpectedly-leap-forward\n\t * - Differences between cores (XP): https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx#qpc_support_in_windows_versions\n\t *\n\t * We avoid these by enabling QPC by default only for Vista or later.\n\t */\n\n\tif (QueryPerformanceCounter(&count) && QueryPerformanceFrequency(&freq)) {\n\t\t/* XXX: QueryPerformanceFrequency() can be cached */\n\t\treturn (duk_double_t) count.QuadPart / (duk_double_t) freq.QuadPart * 1000.0;\n\t} else {\n\t\t/* MSDN: \"On systems that run Windows XP or later, the function\n\t\t * will always succeed and will thus never return zero.\"\n\t\t * Provide minimal error path just in case user enables this\n\t\t * feature in pre-XP Windows.\n\t\t */\n\t\treturn 0.0;\n\t}\n}\n#endif  /* DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC */\n/*\n *  Duktape built-ins\n *\n *  Size optimization note: it might seem that vararg multipurpose functions\n *  like fin(), enc(), and dec() are not very size optimal, but using a single\n *  user-visible ECMAScript function saves a lot of run-time footprint; each\n *  Function instance takes >100 bytes.  Using a shared native helper and a\n *  'magic' value won't save much if there are multiple Function instances\n *  anyway.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_DUKTAPE_BUILTIN)\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_info(duk_hthread *thr) {\n\tduk_inspect_value(thr, -1);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_act(duk_hthread *thr) {\n\tduk_int_t level;\n\n\tlevel = duk_to_int(thr, 0);\n\tduk_inspect_callstack_entry(thr, level);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_gc(duk_hthread *thr) {\n\tduk_small_uint_t flags;\n\n\tflags = (duk_small_uint_t) duk_get_uint(thr, 0);\n\tduk_heap_mark_and_sweep(thr->heap, flags);\n\n\t/* XXX: Not sure what the best return value would be in the API.\n\t * Return true for now.\n\t */\n\tduk_push_true(thr);\n\treturn 1;\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_fin(duk_hthread *thr) {\n\t(void) duk_require_hobject(thr, 0);\n\tif (duk_get_top(thr) >= 2) {\n\t\t/* Set: currently a finalizer is disabled by setting it to\n\t\t * undefined; this does not remove the property at the moment.\n\t\t * The value could be type checked to be either a function\n\t\t * or something else; if something else, the property could\n\t\t * be deleted.  Must use duk_set_finalizer() to keep\n\t\t * DUK_HOBJECT_FLAG_HAVE_FINALIZER in sync.\n\t\t */\n\t\tduk_set_top(thr, 2);\n\t\tduk_set_finalizer(thr, 0);\n\t\treturn 0;\n\t} else {\n\t\t/* Get. */\n\t\tDUK_ASSERT(duk_get_top(thr) == 1);\n\t\tduk_get_finalizer(thr, 0);\n\t\treturn 1;\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_enc(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\t/* Vararg function: must be careful to check/require arguments.\n\t * The JSON helpers accept invalid indices and treat them like\n\t * non-existent optional parameters.\n\t */\n\n\th_str = duk_require_hstring(thr, 0);  /* Could reject symbols, but no point: won't match comparisons. */\n\tduk_require_valid_index(thr, 1);\n\n\tif (h_str == DUK_HTHREAD_STRING_HEX(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_hex_encode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t} else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_base64_encode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX)\n\t} else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {\n\t\tduk_bi_json_stringify_helper(thr,\n\t\t                             1 /*idx_value*/,\n\t\t                             2 /*idx_replacer*/,\n\t\t                             3 /*idx_space*/,\n\t\t                             DUK_JSON_FLAG_EXT_CUSTOM |\n\t\t                             DUK_JSON_FLAG_ASCII_ONLY |\n\t\t                             DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/);\n#endif\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC)\n\t} else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {\n\t\tduk_bi_json_stringify_helper(thr,\n\t\t                             1 /*idx_value*/,\n\t\t                             2 /*idx_replacer*/,\n\t\t                             3 /*idx_space*/,\n\t\t                             DUK_JSON_FLAG_EXT_COMPATIBLE |\n\t\t                             DUK_JSON_FLAG_ASCII_ONLY /*flags*/);\n#endif\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_dec(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\t/* Vararg function: must be careful to check/require arguments.\n\t * The JSON helpers accept invalid indices and treat them like\n\t * non-existent optional parameters.\n\t */\n\n\th_str = duk_require_hstring(thr, 0);  /* Could reject symbols, but no point: won't match comparisons */\n\tduk_require_valid_index(thr, 1);\n\n\tif (h_str == DUK_HTHREAD_STRING_HEX(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_hex_decode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t} else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_base64_decode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX)\n\t} else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {\n\t\tduk_bi_json_parse_helper(thr,\n\t\t                         1 /*idx_value*/,\n\t\t                         2 /*idx_replacer*/,\n\t\t                         DUK_JSON_FLAG_EXT_CUSTOM /*flags*/);\n#endif\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC)\n\t} else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {\n\t\tduk_bi_json_parse_helper(thr,\n\t\t                         1 /*idx_value*/,\n\t\t                         2 /*idx_replacer*/,\n\t\t                         DUK_JSON_FLAG_EXT_COMPATIBLE /*flags*/);\n#endif\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\treturn 1;\n}\n\n/*\n *  Compact an object\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_compact(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 1);\n\tduk_compact(thr, 0);\n\treturn 1;  /* return the argument object */\n}\n\n#endif  /* DUK_USE_DUKTAPE_BUILTIN */\n/*\n *  WHATWG Encoding API built-ins\n *\n *  API specification: https://encoding.spec.whatwg.org/#api\n *  Web IDL: https://www.w3.org/TR/WebIDL/\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Data structures for encoding/decoding\n */\n\ntypedef struct {\n\tduk_uint8_t *out;      /* where to write next byte(s) */\n\tduk_codepoint_t lead;  /* lead surrogate */\n} duk__encode_context;\n\ntypedef struct {\n\t/* UTF-8 decoding state */\n\tduk_codepoint_t codepoint;  /* built up incrementally */\n\tduk_uint8_t upper;          /* max value of next byte (decode error otherwise) */\n\tduk_uint8_t lower;          /* min value of next byte (ditto) */\n\tduk_uint8_t needed;         /* how many more bytes we need */\n\tduk_uint8_t bom_handled;    /* BOM seen or no longer expected */\n\n\t/* Decoder configuration */\n\tduk_uint8_t fatal;\n\tduk_uint8_t ignore_bom;\n} duk__decode_context;\n\n/* The signed duk_codepoint_t type is used to signal a decoded codepoint\n * (>= 0) or various other states using negative values.\n */\n#define DUK__CP_CONTINUE   (-1)  /* continue to next byte, no completed codepoint */\n#define DUK__CP_ERROR      (-2)  /* decoding error */\n#define DUK__CP_RETRY      (-3)  /* decoding error; retry last byte */\n\n/*\n *  Raw helpers for encoding/decoding\n */\n\n/* Emit UTF-8 (= CESU-8) encoded U+FFFD (replacement char), i.e. ef bf bd. */\nDUK_LOCAL duk_uint8_t *duk__utf8_emit_repl(duk_uint8_t *ptr) {\n\t*ptr++ = 0xef;\n\t*ptr++ = 0xbf;\n\t*ptr++ = 0xbd;\n\treturn ptr;\n}\n\nDUK_LOCAL void duk__utf8_decode_init(duk__decode_context *dec_ctx) {\n\t/* (Re)init the decoding state of 'dec_ctx' but leave decoder\n\t * configuration fields untouched.\n\t */\n\tdec_ctx->codepoint = 0x0000L;\n\tdec_ctx->upper = 0xbf;\n\tdec_ctx->lower = 0x80;\n\tdec_ctx->needed = 0;\n\tdec_ctx->bom_handled = 0;\n}\n\nDUK_LOCAL duk_codepoint_t duk__utf8_decode_next(duk__decode_context *dec_ctx, duk_uint8_t x) {\n\t/*\n\t *  UTF-8 algorithm based on the Encoding specification:\n\t *  https://encoding.spec.whatwg.org/#utf-8-decoder\n\t *\n\t *  Two main states: decoding initial byte vs. decoding continuation\n\t *  bytes.  Shortest length encoding is validated by restricting the\n\t *  allowed range of first continuation byte using 'lower' and 'upper'.\n\t */\n\n\tif (dec_ctx->needed == 0) {\n\t\t/* process initial byte */\n\t\tif (x <= 0x7f) {\n\t\t\t/* U+0000-U+007F, 1 byte (ASCII) */\n\t\t\treturn (duk_codepoint_t) x;\n\t\t} else if (x >= 0xc2 && x <= 0xdf) {\n\t\t\t/* U+0080-U+07FF, 2 bytes */\n\t\t\tdec_ctx->needed = 1;\n\t\t\tdec_ctx->codepoint = x & 0x1f;\n\t\t\tDUK_ASSERT(dec_ctx->lower == 0x80);\n\t\t\tDUK_ASSERT(dec_ctx->upper == 0xbf);\n\t\t\treturn DUK__CP_CONTINUE;\n\t\t} else if (x >= 0xe0 && x <= 0xef) {\n\t\t\t/* U+0800-U+FFFF, 3 bytes */\n\t\t\tif (x == 0xe0) {\n\t\t\t\tdec_ctx->lower = 0xa0;\n\t\t\t\tDUK_ASSERT(dec_ctx->upper == 0xbf);\n\t\t\t} else if (x == 0xed) {\n\t\t\t\tDUK_ASSERT(dec_ctx->lower == 0x80);\n\t\t\t\tdec_ctx->upper = 0x9f;\n\t\t\t}\n\t\t\tdec_ctx->needed = 2;\n\t\t\tdec_ctx->codepoint = x & 0x0f;\n\t\t\treturn DUK__CP_CONTINUE;\n\t\t} else if (x >= 0xf0 && x <= 0xf4) {\n\t\t\t/* U+010000-U+10FFFF, 4 bytes */\n\t\t\tif (x == 0xf0) {\n\t\t\t\tdec_ctx->lower = 0x90;\n\t\t\t\tDUK_ASSERT(dec_ctx->upper == 0xbf);\n\t\t\t} else if (x == 0xf4) {\n\t\t\t\tDUK_ASSERT(dec_ctx->lower == 0x80);\n\t\t\t\tdec_ctx->upper = 0x8f;\n\t\t\t}\n\t\t\tdec_ctx->needed = 3;\n\t\t\tdec_ctx->codepoint = x & 0x07;\n\t\t\treturn DUK__CP_CONTINUE;\n\t\t} else {\n\t\t\t/* not a legal initial byte */\n\t\t\treturn DUK__CP_ERROR;\n\t\t}\n\t} else {\n\t\t/* process continuation byte */\n\t\tif (x >= dec_ctx->lower && x <= dec_ctx->upper) {\n\t\t\tdec_ctx->lower = 0x80;\n\t\t\tdec_ctx->upper = 0xbf;\n\t\t\tdec_ctx->codepoint = (dec_ctx->codepoint << 6) | (x & 0x3f);\n\t\t\tif (--dec_ctx->needed > 0) {\n\t\t\t\t/* need more bytes */\n\t\t\t\treturn DUK__CP_CONTINUE;\n\t\t\t} else {\n\t\t\t\t/* got a codepoint */\n\t\t\t\tduk_codepoint_t ret;\n\t\t\t\tDUK_ASSERT(dec_ctx->codepoint <= 0x10ffffL);  /* Decoding rules guarantee. */\n\t\t\t\tret = dec_ctx->codepoint;\n\t\t\t\tdec_ctx->codepoint = 0x0000L;\n\t\t\t\tdec_ctx->needed = 0;\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} else {\n\t\t\t/* We just encountered an illegal UTF-8 continuation byte.  This might\n\t\t\t * be the initial byte of the next character; if we return a plain\n\t\t\t * error status and the decoder is in replacement mode, the character\n\t\t\t * will be masked.  We still need to alert the caller to the error\n\t\t\t * though.\n\t\t\t */\n\t\t\tdec_ctx->codepoint = 0x0000L;\n\t\t\tdec_ctx->needed = 0;\n\t\t\tdec_ctx->lower = 0x80;\n\t\t\tdec_ctx->upper = 0xbf;\n\t\t\treturn DUK__CP_RETRY;\n\t\t}\n\t}\n}\n\n#if defined(DUK_USE_ENCODING_BUILTINS)\nDUK_LOCAL void duk__utf8_encode_char(void *udata, duk_codepoint_t codepoint) {\n\tduk__encode_context *enc_ctx;\n\n\tDUK_ASSERT(codepoint >= 0);\n\tenc_ctx = (duk__encode_context *) udata;\n\tDUK_ASSERT(enc_ctx != NULL);\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\tif (codepoint <= 0x7f && enc_ctx->lead == 0x0000L) {\n\t\t/* Fast path for ASCII. */\n\t\t*enc_ctx->out++ = (duk_uint8_t) codepoint;\n\t\treturn;\n\t}\n#endif\n\n\tif (DUK_UNLIKELY(codepoint > 0x10ffffL)) {\n\t\t/* cannot legally encode in UTF-8 */\n\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t} else if (codepoint >= 0xd800L && codepoint <= 0xdfffL) {\n\t\tif (codepoint <= 0xdbffL) {\n\t\t\t/* high surrogate */\n\t\t\tduk_codepoint_t prev_lead = enc_ctx->lead;\n\t\t\tenc_ctx->lead = codepoint;\n\t\t\tif (prev_lead == 0x0000L) {\n\t\t\t\t/* high surrogate, no output */\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\t/* consecutive high surrogates, consider first one unpaired */\n\t\t\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\t}\n\t\t} else {\n\t\t\t/* low surrogate */\n\t\t\tif (enc_ctx->lead != 0x0000L) {\n\t\t\t\tcodepoint = (duk_codepoint_t) (0x010000L + ((enc_ctx->lead - 0xd800L) << 10) + (codepoint - 0xdc00L));\n\t\t\t\tenc_ctx->lead = 0x0000L;\n\t\t\t} else {\n\t\t\t\t/* unpaired low surrogate */\n\t\t\t\tDUK_ASSERT(enc_ctx->lead == 0x0000L);\n\t\t\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif (enc_ctx->lead != 0x0000L) {\n\t\t\t/* unpaired high surrogate: emit replacement character and the input codepoint */\n\t\t\tenc_ctx->lead = 0x0000L;\n\t\t\tenc_ctx->out = duk__utf8_emit_repl(enc_ctx->out);\n\t\t}\n\t}\n\n\t/* Codepoint may be original input, a decoded surrogate pair, or may\n\t * have been replaced with U+FFFD.\n\t */\n\tenc_ctx->out += duk_unicode_encode_xutf8((duk_ucodepoint_t) codepoint, enc_ctx->out);\n}\n#endif  /* DUK_USE_ENCODING_BUILTINS */\n\n/* Shared helper for buffer-to-string using a TextDecoder() compatible UTF-8\n * decoder.\n */\nDUK_LOCAL duk_ret_t duk__decode_helper(duk_hthread *thr, duk__decode_context *dec_ctx) {\n\tconst duk_uint8_t *input;\n\tduk_size_t len = 0;\n\tduk_size_t len_tmp;\n\tduk_bool_t stream = 0;\n\tduk_codepoint_t codepoint;\n\tduk_uint8_t *output;\n\tconst duk_uint8_t *in;\n\tduk_uint8_t *out;\n\n\tDUK_ASSERT(dec_ctx != NULL);\n\n\t/* Careful with input buffer pointer: any side effects involving\n\t * code execution (e.g. getters, coercion calls, and finalizers)\n\t * may cause a resize and invalidate a pointer we've read.  This\n\t * is why the pointer is actually looked up at the last minute.\n\t * Argument validation must still happen first to match WHATWG\n\t * required side effect order.\n\t */\n\n\tif (duk_is_undefined(thr, 0)) {\n\t\tduk_push_fixed_buffer_nozero(thr, 0);\n\t\tduk_replace(thr, 0);\n\t}\n\t(void) duk_require_buffer_data(thr, 0, &len);  /* Need 'len', avoid pointer. */\n\n\tif (duk_check_type_mask(thr, 1, DUK_TYPE_MASK_UNDEFINED |\n\t                                DUK_TYPE_MASK_NULL |\n\t                                DUK_TYPE_MASK_NONE)) {\n\t\t/* Use defaults, treat missing value like undefined. */\n\t} else {\n\t\tduk_require_type_mask(thr, 1, DUK_TYPE_MASK_UNDEFINED |\n\t                                      DUK_TYPE_MASK_NULL |\n\t                                      DUK_TYPE_MASK_LIGHTFUNC |\n\t                                      DUK_TYPE_MASK_BUFFER |\n\t\t                              DUK_TYPE_MASK_OBJECT);\n\t\tif (duk_get_prop_literal(thr, 1, \"stream\")) {\n\t\t\tstream = duk_to_boolean(thr, -1);\n\t\t}\n\t}\n\n\t/* Allowance is 3*len in the general case because all bytes may potentially\n\t * become U+FFFD.  If the first byte completes a non-BMP codepoint it will\n\t * decode to a CESU-8 surrogate pair (6 bytes) so we allow 3 extra bytes to\n\t * compensate: (1*3)+3 = 6.  Non-BMP codepoints are safe otherwise because\n\t * the 4->6 expansion is well under the 3x allowance.\n\t *\n\t * XXX: As with TextEncoder, need a better buffer allocation strategy here.\n\t */\n\tif (len >= (DUK_HBUFFER_MAX_BYTELEN / 3) - 3) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_RESULT_TOO_LONG);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\toutput = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, 3 + (3 * len));  /* used parts will be always manually written over */\n\n\tinput = (const duk_uint8_t *) duk_get_buffer_data(thr, 0, &len_tmp);\n\tDUK_ASSERT(input != NULL || len == 0);\n\tif (DUK_UNLIKELY(len != len_tmp)) {\n\t\t/* Very unlikely but possible: source buffer was resized by\n\t\t * a side effect when fixed buffer was pushed.  Output buffer\n\t\t * may not be large enough to hold output, so just fail if\n\t\t * length has changed.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"input buffer resized by side effect, fail\"));\n\t\tgoto fail_type;\n\t}\n\n\t/* From this point onwards it's critical that no side effect occur\n\t * which may disturb 'input': finalizer execution, property accesses,\n\t * active coercions, etc.  Even an allocation related mark-and-sweep\n\t * may affect the pointer because it may trigger a pending finalizer.\n\t */\n\n\tin = input;\n\tout = output;\n\twhile (in < input + len) {\n\t\tcodepoint = duk__utf8_decode_next(dec_ctx, *in++);\n\t\tif (codepoint < 0) {\n\t\t\tif (codepoint == DUK__CP_CONTINUE) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* Decoding error with or without retry. */\n\t\t\tDUK_ASSERT(codepoint == DUK__CP_ERROR || codepoint == DUK__CP_RETRY);\n\t\t\tif (codepoint == DUK__CP_RETRY) {\n\t\t\t\t--in;  /* retry last byte */\n\t\t\t}\n\t\t\t/* replacement mode: replace with U+FFFD */\n\t\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\tif (dec_ctx->fatal) {\n\t\t\t\t/* fatal mode: throw a TypeError */\n\t\t\t\tgoto fail_type;\n\t\t\t}\n\t\t\t/* Continue with 'codepoint', Unicode replacement. */\n\t\t}\n\t\tDUK_ASSERT(codepoint >= 0x0000L && codepoint <= 0x10ffffL);\n\n\t\tif (!dec_ctx->bom_handled) {\n\t\t\tdec_ctx->bom_handled = 1;\n\t\t\tif (codepoint == 0xfeffL && !dec_ctx->ignore_bom) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tout += duk_unicode_encode_cesu8((duk_ucodepoint_t) codepoint, out);\n\t\tDUK_ASSERT(out <= output + (3 + (3 * len)));\n\t}\n\n\tif (!stream) {\n\t\tif (dec_ctx->needed != 0) {\n\t\t\t/* truncated sequence at end of buffer */\n\t\t\tif (dec_ctx->fatal) {\n\t\t\t\tgoto fail_type;\n\t\t\t} else {\n\t\t\t\tout += duk_unicode_encode_cesu8(DUK_UNICODE_CP_REPLACEMENT_CHARACTER, out);\n\t\t\t\tDUK_ASSERT(out <= output + (3 + (3 * len)));\n\t\t\t}\n\t\t}\n\t\tduk__utf8_decode_init(dec_ctx);  /* Initialize decoding state for potential reuse. */\n\t}\n\n\t/* Output buffer is fixed and thus stable even if there had been\n\t * side effects (which there shouldn't be).\n\t */\n\tduk_push_lstring(thr, (const char *) output, (duk_size_t) (out - output));\n\treturn 1;\n\n fail_type:\n\tDUK_ERROR_TYPE(thr, DUK_STR_UTF8_DECODE_FAILED);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/*\n *  Built-in bindings\n */\n\n#if defined(DUK_USE_ENCODING_BUILTINS)\nDUK_INTERNAL duk_ret_t duk_bi_textencoder_constructor(duk_hthread *thr) {\n\t/* TextEncoder currently requires no persistent state, so the constructor\n\t * does nothing on purpose.\n\t */\n\n\tduk_require_constructor_call(thr);\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encoding_getter(duk_hthread *thr) {\n\tduk_push_literal(thr, \"utf-8\");\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encode(duk_hthread *thr) {\n\tduk__encode_context enc_ctx;\n\tduk_size_t len;\n\tduk_size_t final_len;\n\tduk_uint8_t *output;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tlen = 0;\n\t} else {\n\t\tduk_hstring *h_input;\n\n\t\th_input = duk_to_hstring(thr, 0);\n\t\tDUK_ASSERT(h_input != NULL);\n\n\t\tlen = (duk_size_t) DUK_HSTRING_GET_CHARLEN(h_input);\n\t\tif (len >= DUK_HBUFFER_MAX_BYTELEN / 3) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_RESULT_TOO_LONG);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t}\n\n\t/* Allowance is 3*len because all bytes can potentially be replaced with\n\t * U+FFFD -- which rather inconveniently encodes to 3 bytes in UTF-8.\n\t * Rely on dynamic buffer data pointer stability: no other code has\n\t * access to the data pointer.\n\t *\n\t * XXX: The buffer allocation strategy used here is rather inefficient.\n\t * Maybe switch to a chunk-based strategy, or preprocess the string to\n\t * figure out the space needed ahead of time?\n\t */\n\tDUK_ASSERT(3 * len >= len);\n\toutput = (duk_uint8_t *) duk_push_dynamic_buffer(thr, 3 * len);\n\n\tif (len > 0) {\n\t\tDUK_ASSERT(duk_is_string(thr, 0));  /* True if len > 0. */\n\n\t\t/* XXX: duk_decode_string() is used to process the input\n\t\t * string.  For standard ECMAScript strings, represented\n\t\t * internally as CESU-8, this is fine.  However, behavior\n\t\t * beyond CESU-8 is not very strict: codepoints using an\n\t\t * extended form of UTF-8 are also accepted, and invalid\n\t\t * codepoint sequences (which are allowed in Duktape strings)\n\t\t * are not handled as well as they could (e.g. invalid\n\t\t * continuation bytes may mask following codepoints).\n\t\t * This is how ECMAScript code would also see such strings.\n\t\t * Maybe replace duk_decode_string() with an explicit strict\n\t\t * CESU-8 decoder here?\n\t\t */\n\t\tenc_ctx.lead = 0x0000L;\n\t\tenc_ctx.out = output;\n\t\tduk_decode_string(thr, 0, duk__utf8_encode_char, (void *) &enc_ctx);\n\t\tif (enc_ctx.lead != 0x0000L) {\n\t\t\t/* unpaired high surrogate at end of string */\n\t\t\tenc_ctx.out = duk__utf8_emit_repl(enc_ctx.out);\n\t\t\tDUK_ASSERT(enc_ctx.out <= output + (3 * len));\n\t\t}\n\n\t\t/* The output buffer is usually very much oversized, so shrink it to\n\t\t * actually needed size.  Pointer stability assumed up to this point.\n\t\t */\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t\tDUK_ASSERT(output == (duk_uint8_t *) duk_get_buffer_data(thr, -1, NULL));\n\n\t\tfinal_len = (duk_size_t) (enc_ctx.out - output);\n\t\tduk_resize_buffer(thr, -1, final_len);\n\t\t/* 'output' and 'enc_ctx.out' are potentially invalidated by the resize. */\n\t} else {\n\t\tfinal_len = 0;\n\t}\n\n\t/* Standard WHATWG output is a Uint8Array.  Here the Uint8Array will\n\t * be backed by a dynamic buffer which differs from e.g. Uint8Arrays\n\t * created as 'new Uint8Array(N)'.  ECMAScript code won't see the\n\t * difference but C code will.  When bufferobjects are not supported,\n\t * returns a plain dynamic buffer.\n\t */\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tduk_push_buffer_object(thr, -1, 0, final_len, DUK_BUFOBJ_UINT8ARRAY);\n#endif\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textdecoder_constructor(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\tduk_bool_t fatal = 0;\n\tduk_bool_t ignore_bom = 0;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_require_constructor_call(thr);\n\tif (!duk_is_undefined(thr, 0)) {\n\t\t/* XXX: For now ignore 'label' (encoding identifier). */\n\t\tduk_to_string(thr, 0);\n\t}\n\tif (!duk_is_null_or_undefined(thr, 1)) {\n\t\tif (duk_get_prop_literal(thr, 1, \"fatal\")) {\n\t\t\tfatal = duk_to_boolean(thr, -1);\n\t\t}\n\t\tif (duk_get_prop_literal(thr, 1, \"ignoreBOM\")) {\n\t\t\tignore_bom = duk_to_boolean(thr, -1);\n\t\t}\n\t}\n\n\tduk_push_this(thr);\n\n\t/* The decode context is not assumed to be zeroed; all fields are\n\t * initialized explicitly.\n\t */\n\tdec_ctx = (duk__decode_context *) duk_push_fixed_buffer(thr, sizeof(duk__decode_context));\n\tdec_ctx->fatal = (duk_uint8_t) fatal;\n\tdec_ctx->ignore_bom = (duk_uint8_t) ignore_bom;\n\tduk__utf8_decode_init(dec_ctx);  /* Initializes remaining fields. */\n\n\tduk_put_prop_literal(thr, -2, DUK_INTERNAL_SYMBOL(\"Context\"));\n\treturn 0;\n}\n\n/* Get TextDecoder context from 'this'; leaves garbage on stack. */\nDUK_LOCAL duk__decode_context *duk__get_textdecoder_context(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\tduk_push_this(thr);\n\tduk_get_prop_literal(thr, -1, DUK_INTERNAL_SYMBOL(\"Context\"));\n\tdec_ctx = (duk__decode_context *) duk_require_buffer(thr, -1, NULL);\n\tDUK_ASSERT(dec_ctx != NULL);\n\treturn dec_ctx;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\tduk_int_t magic;\n\n\tdec_ctx = duk__get_textdecoder_context(thr);\n\tmagic = duk_get_current_magic(thr);\n\tswitch (magic) {\n\tcase 0:\n\t\t/* Encoding is now fixed, so _Context lookup is only needed to\n\t\t * validate the 'this' binding (TypeError if not TextDecoder-like).\n\t\t */\n\t\tduk_push_literal(thr, \"utf-8\");\n\t\tbreak;\n\tcase 1:\n\t\tduk_push_boolean(thr, dec_ctx->fatal);\n\t\tbreak;\n\tdefault:\n\t\tduk_push_boolean(thr, dec_ctx->ignore_bom);\n\t\tbreak;\n\t}\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\n\tdec_ctx = duk__get_textdecoder_context(thr);\n\treturn duk__decode_helper(thr, dec_ctx);\n}\n#endif  /* DUK_USE_ENCODING_BUILTINS */\n\n/*\n *  Internal helper for Node.js Buffer\n */\n\n/* Internal helper used for Node.js Buffer .toString().  Value stack convention\n * is currently odd: it mimics TextDecoder .decode() so that argument must be at\n * index 0, and decode options (not present for Buffer) at index 1.  Return value\n * is a Duktape/C function return value.\n */\nDUK_INTERNAL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_hthread *thr) {\n\tduk__decode_context dec_ctx;\n\n\tdec_ctx.fatal = 0;  /* use replacement chars */\n\tdec_ctx.ignore_bom = 1;  /* ignore BOMs (matches Node.js Buffer .toString()) */\n\tduk__utf8_decode_init(&dec_ctx);\n\n\treturn duk__decode_helper(thr, &dec_ctx);\n}\n\n/* automatic undefs */\n#undef DUK__CP_CONTINUE\n#undef DUK__CP_ERROR\n#undef DUK__CP_RETRY\n/*\n *  Error built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL duk_ret_t duk_bi_error_constructor_shared(duk_hthread *thr) {\n\t/* Behavior for constructor and non-constructor call is\n\t * the same except for augmenting the created error.  When\n\t * called as a constructor, the caller (duk_new()) will handle\n\t * augmentation; when called as normal function, we need to do\n\t * it here.\n\t */\n\n\tduk_small_int_t bidx_prototype = duk_get_current_magic(thr);\n\n\t/* same for both error and each subclass like TypeError */\n\tduk_uint_t flags_and_class = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                             DUK_HOBJECT_FLAG_FASTREFS |\n\t                             DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ERROR);\n\n\t(void) duk_push_object_helper(thr, flags_and_class, bidx_prototype);\n\n\t/* If message is undefined, the own property 'message' is not set at\n\t * all to save property space.  An empty message is inherited anyway.\n\t */\n\tif (!duk_is_undefined(thr, 0)) {\n\t\tduk_to_string(thr, 0);\n\t\tduk_dup_0(thr);  /* [ message error message ] */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);\n\t}\n\n\t/* Augment the error if called as a normal function.  __FILE__ and __LINE__\n\t * are not desirable in this case.\n\t */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tif (!duk_is_constructor_call(thr)) {\n\t\tduk_err_augment_error_create(thr, thr, NULL, 0, DUK_AUGMENT_FLAG_NOBLAME_FILELINE);\n\t}\n#endif\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_to_string(duk_hthread *thr) {\n\t/* XXX: optimize with more direct internal access */\n\n\tduk_push_this(thr);\n\t(void) duk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\n\t/* [ ... this ] */\n\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME);\n\tif (duk_is_undefined(thr, -1)) {\n\t\tduk_pop(thr);\n\t\tduk_push_literal(thr, \"Error\");\n\t} else {\n\t\tduk_to_string(thr, -1);\n\t}\n\n\t/* [ ... this name ] */\n\n\t/* XXX: Are steps 6 and 7 in E5 Section 15.11.4.4 duplicated by\n\t * accident or are they actually needed?  The first ToString()\n\t * could conceivably return 'undefined'.\n\t */\n\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE);\n\tif (duk_is_undefined(thr, -1)) {\n\t\tduk_pop(thr);\n\t\tduk_push_hstring_empty(thr);\n\t} else {\n\t\tduk_to_string(thr, -1);\n\t}\n\n\t/* [ ... this name message ] */\n\n\tif (duk_get_length(thr, -2) == 0) {\n\t\t/* name is empty -> return message */\n\t\treturn 1;\n\t}\n\tif (duk_get_length(thr, -1) == 0) {\n\t\t/* message is empty -> return name */\n\t\tduk_pop(thr);\n\t\treturn 1;\n\t}\n\tduk_push_literal(thr, \": \");\n\tduk_insert(thr, -2);  /* ... name ': ' message */\n\tduk_concat(thr, 3);\n\n\treturn 1;\n}\n\n#if defined(DUK_USE_TRACEBACKS)\n\n/*\n *  Traceback handling\n *\n *  The unified helper decodes the traceback and produces various requested\n *  outputs.  It should be optimized for size, and may leave garbage on stack,\n *  only the topmost return value matters.  For instance, traceback separator\n *  and decoded strings are pushed even when looking for filename only.\n *\n *  NOTE: although _Tracedata is an internal property, user code can currently\n *  write to the array (or replace it with something other than an array).\n *  The code below must tolerate arbitrary _Tracedata.  It can throw errors\n *  etc, but cannot cause a segfault or memory unsafe behavior.\n */\n\n/* constants arbitrary, chosen for small loads */\n#define DUK__OUTPUT_TYPE_TRACEBACK   (-1)\n#define DUK__OUTPUT_TYPE_FILENAME    0\n#define DUK__OUTPUT_TYPE_LINENUMBER  1\n\nDUK_LOCAL duk_ret_t duk__error_getter_helper(duk_hthread *thr, duk_small_int_t output_type) {\n\tduk_idx_t idx_td;\n\tduk_small_int_t i;  /* traceback depth fits into 16 bits */\n\tduk_small_int_t t;  /* stack type fits into 16 bits */\n\tduk_small_int_t count_func = 0;  /* traceback depth ensures fits into 16 bits */\n\tconst char *str_tailcall = \" tailcall\";\n\tconst char *str_strict = \" strict\";\n\tconst char *str_construct = \" construct\";\n\tconst char *str_prevyield = \" preventsyield\";\n\tconst char *str_directeval = \" directeval\";\n\tconst char *str_empty = \"\";\n\n\tDUK_ASSERT_TOP(thr, 0);  /* fixed arg count */\n\n\tduk_push_this(thr);\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_TRACEDATA);\n\tidx_td = duk_get_top_index(thr);\n\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_NEWLINE_4SPACE);\n\tduk_push_this(thr);\n\n\t/* [ ... this tracedata sep this ] */\n\n\t/* XXX: skip null filename? */\n\n\tif (duk_check_type(thr, idx_td, DUK_TYPE_OBJECT)) {\n\t\t/* Current tracedata contains 2 entries per callstack entry. */\n\t\tfor (i = 0; ; i += 2) {\n\t\t\tduk_int_t pc;\n\t\t\tduk_uint_t line;\n\t\t\tduk_uint_t flags;\n\t\t\tduk_double_t d;\n\t\t\tconst char *funcname;\n\t\t\tconst char *filename;\n\t\t\tduk_hobject *h_func;\n\t\t\tduk_hstring *h_name;\n\n\t\t\tduk_require_stack(thr, 5);\n\t\t\tduk_get_prop_index(thr, idx_td, (duk_uarridx_t) i);\n\t\t\tduk_get_prop_index(thr, idx_td, (duk_uarridx_t) (i + 1));\n\t\t\td = duk_to_number_m1(thr);\n\t\t\tpc = duk_double_to_int_t(DUK_FMOD(d, DUK_DOUBLE_2TO32));\n\t\t\tflags = duk_double_to_uint_t(DUK_FLOOR(d / DUK_DOUBLE_2TO32));\n\t\t\tt = (duk_small_int_t) duk_get_type(thr, -2);\n\n\t\t\tif (t == DUK_TYPE_OBJECT || t == DUK_TYPE_LIGHTFUNC) {\n\t\t\t\t/*\n\t\t\t\t *  ECMAScript/native function call or lightfunc call\n\t\t\t\t */\n\n\t\t\t\tcount_func++;\n\n\t\t\t\t/* [ ... v1(func) v2(pc+flags) ] */\n\n\t\t\t\t/* These may be systematically omitted by Duktape\n\t\t\t\t * with certain config options, but allow user to\n\t\t\t\t * set them on a case-by-case basis.\n\t\t\t\t */\n\t\t\t\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME);\n\t\t\t\tduk_get_prop_stridx_short(thr, -3, DUK_STRIDX_FILE_NAME);\n\n#if defined(DUK_USE_PC2LINE)\n\t\t\t\tline = (duk_uint_t) duk_hobject_pc2line_query(thr, -4, (duk_uint_fast32_t) pc);\n#else\n\t\t\t\tline = 0;\n#endif\n\n\t\t\t\t/* [ ... v1 v2 name filename ] */\n\n\t\t\t\t/* When looking for .fileName/.lineNumber, blame first\n\t\t\t\t * function which has a .fileName.\n\t\t\t\t */\n\t\t\t\tif (duk_is_string_notsymbol(thr, -1)) {\n\t\t\t\t\tif (output_type == DUK__OUTPUT_TYPE_FILENAME) {\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t} else if (output_type == DUK__OUTPUT_TYPE_LINENUMBER) {\n\t\t\t\t\t\tduk_push_uint(thr, line);\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* XXX: Change 'anon' handling here too, to use empty string for anonymous functions? */\n\t\t\t\t/* XXX: Could be improved by coercing to a readable duk_tval (especially string escaping) */\n\t\t\t\th_name = duk_get_hstring_notsymbol(thr, -2);  /* may be NULL */\n\t\t\t\tfuncname = (h_name == NULL || h_name == DUK_HTHREAD_STRING_EMPTY_STRING(thr)) ?\n\t\t\t\t           \"[anon]\" : (const char *) DUK_HSTRING_GET_DATA(h_name);\n\t\t\t\tfilename = duk_get_string_notsymbol(thr, -1);\n\t\t\t\tfilename = filename ? filename : \"\";\n\t\t\t\tDUK_ASSERT(funcname != NULL);\n\t\t\t\tDUK_ASSERT(filename != NULL);\n\n\t\t\t\th_func = duk_get_hobject(thr, -4);  /* NULL for lightfunc */\n\n\t\t\t\tif (h_func == NULL) {\n\t\t\t\t\tduk_push_sprintf(thr, \"at %s light%s%s%s%s%s\",\n\t\t\t\t\t                 (const char *) funcname,\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));\n\t\t\t\t} else if (DUK_HOBJECT_HAS_NATFUNC(h_func)) {\n\t\t\t\t\tduk_push_sprintf(thr, \"at %s (%s) native%s%s%s%s%s\",\n\t\t\t\t\t                 (const char *) funcname,\n\t\t\t\t\t                 (const char *) filename,\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));\n\t\t\t\t} else {\n\t\t\t\t\tduk_push_sprintf(thr, \"at %s (%s:%lu)%s%s%s%s%s\",\n\t\t\t\t\t                 (const char *) funcname,\n\t\t\t\t\t                 (const char *) filename,\n\t\t\t\t\t                 (unsigned long) line,\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));\n\t\t\t\t}\n\t\t\t\tduk_replace(thr, -5);   /* [ ... v1 v2 name filename str ] -> [ ... str v2 name filename ] */\n\t\t\t\tduk_pop_3(thr);         /* -> [ ... str ] */\n\t\t\t} else if (t == DUK_TYPE_STRING) {\n\t\t\t\tconst char *str_file;\n\n\t\t\t\t/*\n\t\t\t\t *  __FILE__ / __LINE__ entry, here 'pc' is line number directly.\n\t\t\t\t *  Sometimes __FILE__ / __LINE__ is reported as the source for\n\t\t\t\t *  the error (fileName, lineNumber), sometimes not.\n\t\t\t\t */\n\n\t\t\t\t/* [ ... v1(filename) v2(line+flags) ] */\n\n\t\t\t\t/* When looking for .fileName/.lineNumber, blame compilation\n\t\t\t\t * or C call site unless flagged not to do so.\n\t\t\t\t */\n\t\t\t\tif (!(flags & DUK_TB_FLAG_NOBLAME_FILELINE)) {\n\t\t\t\t\tif (output_type == DUK__OUTPUT_TYPE_FILENAME) {\n\t\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t} else if (output_type == DUK__OUTPUT_TYPE_LINENUMBER) {\n\t\t\t\t\t\tduk_push_int(thr, pc);\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* Tracedata is trusted but avoid any risk of using a NULL\n\t\t\t\t * for %s format because it has undefined behavior.  Symbols\n\t\t\t\t * don't need to be explicitly rejected as they pose no memory\n\t\t\t\t * safety issues.\n\t\t\t\t */\n\t\t\t\tstr_file = (const char *) duk_get_string(thr, -2);\n\t\t\t\tduk_push_sprintf(thr, \"at [anon] (%s:%ld) internal\",\n\t\t\t\t                 (const char *) (str_file ? str_file : \"null\"), (long) pc);\n\t\t\t\tduk_replace(thr, -3);  /* [ ... v1 v2 str ] -> [ ... str v2 ] */\n\t\t\t\tduk_pop(thr);          /* -> [ ... str ] */\n\t\t\t} else {\n\t\t\t\t/* unknown, ignore */\n\t\t\t\tduk_pop_2(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (count_func >= DUK_USE_TRACEBACK_DEPTH) {\n\t\t\t/* Possibly truncated; there is no explicit truncation\n\t\t\t * marker so this is the best we can do.\n\t\t\t */\n\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_BRACKETED_ELLIPSIS);\n\t\t}\n\t}\n\n\t/* [ ... this tracedata sep this str1 ... strN ] */\n\n\tif (output_type != DUK__OUTPUT_TYPE_TRACEBACK) {\n\t\treturn 0;\n\t} else {\n\t\t/* The 'this' after 'sep' will get ToString() coerced by\n\t\t * duk_join() automatically.  We don't want to do that\n\t\t * coercion when providing .fileName or .lineNumber (GH-254).\n\t\t */\n\t\tduk_join(thr, duk_get_top(thr) - (idx_td + 2) /*count, not including sep*/);\n\t\treturn 1;\n\t}\n}\n\n/* XXX: Output type could be encoded into native function 'magic' value to\n * save space.  For setters the stridx could be encoded into 'magic'.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter(duk_hthread *thr) {\n\treturn duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_TRACEBACK);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter(duk_hthread *thr) {\n\treturn duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_FILENAME);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_hthread *thr) {\n\treturn duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_LINENUMBER);\n}\n\n#else  /* DUK_USE_TRACEBACKS */\n\n/*\n *  Traceback handling when tracebacks disabled.\n *\n *  The fileName / lineNumber stubs are now necessary because built-in\n *  data will include the accessor properties in Error.prototype.  If those\n *  are removed for builds without tracebacks, these can also be removed.\n *  'stack' should still be present and produce a ToString() equivalent:\n *  this is useful for user code which prints a stacktrace and expects to\n *  see something useful.  A normal stacktrace also begins with a ToString()\n *  of the error so this makes sense.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter(duk_hthread *thr) {\n\t/* XXX: remove this native function and map 'stack' accessor\n\t * to the toString() implementation directly.\n\t */\n\treturn duk_bi_error_prototype_to_string(thr);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter(duk_hthread *thr) {\n\tDUK_UNREF(thr);\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_hthread *thr) {\n\tDUK_UNREF(thr);\n\treturn 0;\n}\n\n#endif  /* DUK_USE_TRACEBACKS */\n\nDUK_LOCAL duk_ret_t duk__error_setter_helper(duk_hthread *thr, duk_small_uint_t stridx_key) {\n\t/* Attempt to write 'stack', 'fileName', 'lineNumber' works as if\n\t * user code called Object.defineProperty() to create an overriding\n\t * own property.  This allows user code to overwrite .fileName etc\n\t * intuitively as e.g. \"err.fileName = 'dummy'\" as one might expect.\n\t * See https://github.com/svaarala/duktape/issues/387.\n\t */\n\n\tDUK_ASSERT_TOP(thr, 1);  /* fixed arg count: value */\n\n\tduk_push_this(thr);\n\tduk_push_hstring_stridx(thr, stridx_key);\n\tduk_dup_0(thr);\n\n\t/* [ ... obj key value ] */\n\n\tDUK_DD(DUK_DDPRINT(\"error setter: %!T %!T %!T\",\n\t                   duk_get_tval(thr, -3), duk_get_tval(thr, -2), duk_get_tval(thr, -1)));\n\n\tduk_def_prop(thr, -3, DUK_DEFPROP_HAVE_VALUE |\n\t                      DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE |\n\t                      DUK_DEFPROP_HAVE_ENUMERABLE | /*not enumerable*/\n\t                      DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE);\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_setter(duk_hthread *thr) {\n\treturn duk__error_setter_helper(thr, DUK_STRIDX_STACK);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_setter(duk_hthread *thr) {\n\treturn duk__error_setter_helper(thr, DUK_STRIDX_FILE_NAME);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_setter(duk_hthread *thr) {\n\treturn duk__error_setter_helper(thr, DUK_STRIDX_LINE_NUMBER);\n}\n\n/* automatic undefs */\n#undef DUK__OUTPUT_TYPE_FILENAME\n#undef DUK__OUTPUT_TYPE_LINENUMBER\n#undef DUK__OUTPUT_TYPE_TRACEBACK\n/*\n *  Function built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Needed even when Function built-in is disabled. */\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype(duk_hthread *thr) {\n\t/* ignore arguments, return undefined (E5 Section 15.3.4) */\n\tDUK_UNREF(thr);\n\treturn 0;\n}\n\n#if defined(DUK_USE_FUNCTION_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_function_constructor(duk_hthread *thr) {\n\tduk_hstring *h_sourcecode;\n\tduk_idx_t nargs;\n\tduk_idx_t i;\n\tduk_small_uint_t comp_flags;\n\tduk_hcompfunc *func;\n\tduk_hobject *outer_lex_env;\n\tduk_hobject *outer_var_env;\n\n\t/* normal and constructor calls have identical semantics */\n\n\tnargs = duk_get_top(thr);\n\tfor (i = 0; i < nargs; i++) {\n\t\tduk_to_string(thr, i);  /* Rejects Symbols during coercion. */\n\t}\n\n\tif (nargs == 0) {\n\t\tduk_push_hstring_empty(thr);\n\t\tduk_push_hstring_empty(thr);\n\t} else if (nargs == 1) {\n\t\t/* XXX: cover this with the generic >1 case? */\n\t\tduk_push_hstring_empty(thr);\n\t} else {\n\t\tduk_insert(thr, 0);   /* [ arg1 ... argN-1 body] -> [body arg1 ... argN-1] */\n\t\tduk_push_literal(thr, \",\");\n\t\tduk_insert(thr, 1);\n\t\tduk_join(thr, nargs - 1);\n\t}\n\n\t/* [ body formals ], formals is comma separated list that needs to be parsed */\n\n\tDUK_ASSERT_TOP(thr, 2);\n\n\t/* XXX: this placeholder is not always correct, but use for now.\n\t * It will fail in corner cases; see test-dev-func-cons-args.js.\n\t */\n\tduk_push_literal(thr, \"function(\");\n\tduk_dup_1(thr);\n\tduk_push_literal(thr, \"){\");\n\tduk_dup_0(thr);\n\tduk_push_literal(thr, \"\\n}\");  /* Newline is important to handle trailing // comment. */\n\tduk_concat(thr, 5);\n\n\t/* [ body formals source ] */\n\n\tDUK_ASSERT_TOP(thr, 3);\n\n\t/* strictness is not inherited, intentional */\n\tcomp_flags = DUK_COMPILE_FUNCEXPR;\n\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_COMPILE);  /* XXX: copy from caller? */  /* XXX: ignored now */\n\th_sourcecode = duk_require_hstring(thr, -2);  /* no symbol check needed; -2 is concat'd code */\n\tduk_js_compile(thr,\n\t               (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_sourcecode),\n\t               (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sourcecode),\n\t               comp_flags);\n\n\t/* Force .name to 'anonymous' (ES2015). */\n\tduk_push_literal(thr, \"anonymous\");\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n\n\tfunc = (duk_hcompfunc *) duk_known_hobject(thr, -1);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) func));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) func));\n\n\t/* [ body formals source template ] */\n\n\t/* only outer_lex_env matters, as functions always get a new\n\t * variable declaration environment.\n\t */\n\n\touter_lex_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\touter_var_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\n\tduk_js_push_closure(thr, func, outer_var_env, outer_lex_env, 1 /*add_auto_proto*/);\n\n\t/* [ body formals source template closure ] */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_FUNCTION_BUILTIN */\n\n#if defined(DUK_USE_FUNCTION_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_to_string(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\t/*\n\t *  E5 Section 15.3.4.2 places few requirements on the output of\n\t *  this function: the result is implementation dependent, must\n\t *  follow FunctionDeclaration syntax (in particular, must have a\n\t *  name even for anonymous functions or functions with empty name).\n\t *  The output does NOT need to compile into anything useful.\n\t *\n\t *  E6 Section 19.2.3.5 changes the requirements completely: the\n\t *  result must either eval() to a functionally equivalent object\n\t *  OR eval() to a SyntaxError.\n\t *\n\t *  We opt for the SyntaxError approach for now, with a syntax that\n\t *  mimics V8's native function syntax:\n\t *\n\t *      'function cos() { [native code] }'\n\t *\n\t *  but extended with [ecmascript code], [bound code], and\n\t *  [lightfunc code].\n\t */\n\n\tduk_push_this(thr);\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *obj = DUK_TVAL_GET_OBJECT(tv);\n\t\tconst char *func_name;\n\n\t\t/* Function name: missing/undefined is mapped to empty string,\n\t\t * otherwise coerce to string.  No handling for invalid identifier\n\t\t * characters or e.g. '{' in the function name.  This doesn't\n\t\t * really matter as long as a SyntaxError results.  Technically\n\t\t * if the name contained a suitable prefix followed by '//' it\n\t\t * might cause the result to parse without error.\n\t\t */\n\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME);\n\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\tfunc_name = \"\";\n\t\t} else {\n\t\t\tfunc_name = duk_to_string(thr, -1);\n\t\t\tDUK_ASSERT(func_name != NULL);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(obj)) {\n\t\t\tduk_push_sprintf(thr, \"function %s() { [ecmascript code] }\", (const char *) func_name);\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(obj)) {\n\t\t\tduk_push_sprintf(thr, \"function %s() { [native code] }\", (const char *) func_name);\n\t\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(obj)) {\n\t\t\tduk_push_sprintf(thr, \"function %s() { [bound code] }\", (const char *) func_name);\n\t\t} else {\n\t\t\tgoto type_error;\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_push_lightfunc_tostring(thr, tv);\n\t} else {\n\t\tgoto type_error;\n\t}\n\n\treturn 1;\n\n type_error:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n#endif\n\n/* Always present because the native function pointer is needed in call\n * handling.\n */\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_call(duk_hthread *thr) {\n\t/* .call() is dealt with in call handling by simulating its\n\t * effects so this function is actually never called.\n\t */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_apply(duk_hthread *thr) {\n\t/* Like .call(), never actually called. */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_apply(duk_hthread *thr) {\n\t/* Like .call(), never actually called. */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_construct(duk_hthread *thr) {\n\t/* Like .call(), never actually called. */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\n#if defined(DUK_USE_FUNCTION_BUILTIN)\n/* Create a bound function which points to a target function which may\n * be bound or non-bound.  If the target is bound, the argument lists\n * and 'this' binding of the functions are merged and the resulting\n * function points directly to the non-bound target.\n */\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_bind(duk_hthread *thr) {\n\tduk_hboundfunc *h_bound;\n\tduk_idx_t nargs;  /* bound args, not counting 'this' binding */\n\tduk_idx_t bound_nargs;\n\tduk_int_t bound_len;\n\tduk_tval *tv_prevbound;\n\tduk_idx_t n_prevbound;\n\tduk_tval *tv_res;\n\tduk_tval *tv_tmp;\n\n\t/* XXX: C API call, e.g. duk_push_bound_function(thr, target_idx, nargs); */\n\n\t/* Vararg function, careful arg handling, e.g. thisArg may not\n\t * be present.\n\t */\n\tnargs = duk_get_top(thr) - 1;  /* actual args, not counting 'this' binding */\n\tif (nargs < 0) {\n\t\tnargs++;\n\t\tduk_push_undefined(thr);\n\t}\n\tDUK_ASSERT(nargs >= 0);\n\n\t/* Limit 'nargs' for bound functions to guarantee arithmetic\n\t * below will never wrap.\n\t */\n\tif (nargs > (duk_idx_t) DUK_HBOUNDFUNC_MAX_ARGS) {\n\t\tDUK_DCERROR_RANGE_INVALID_COUNT(thr);\n\t}\n\n\tduk_push_this(thr);\n\tduk_require_callable(thr, -1);\n\n\t/* [ thisArg arg1 ... argN func ]  (thisArg+args == nargs+1 total) */\n\tDUK_ASSERT_TOP(thr, nargs + 2);\n\n\t/* Create bound function object. */\n\th_bound = duk_push_hboundfunc(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&h_bound->target));\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&h_bound->this_binding));\n\tDUK_ASSERT(h_bound->args == NULL);\n\tDUK_ASSERT(h_bound->nargs == 0);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_bound) == NULL);\n\n\t/* [ thisArg arg1 ... argN func boundFunc ] */\n\n\t/* If the target is a bound function, argument lists must be\n\t * merged.  The 'this' binding closest to the target function\n\t * wins because in call handling the 'this' gets replaced over\n\t * and over again until we call the non-bound function.\n\t */\n\ttv_prevbound = NULL;\n\tn_prevbound = 0;\n\ttv_tmp = DUK_GET_TVAL_POSIDX(thr, 0);\n\tDUK_TVAL_SET_TVAL(&h_bound->this_binding, tv_tmp);\n\ttv_tmp = DUK_GET_TVAL_NEGIDX(thr, -2);\n\tDUK_TVAL_SET_TVAL(&h_bound->target, tv_tmp);\n\n\tif (DUK_TVAL_IS_OBJECT(tv_tmp)) {\n\t\tduk_hobject *h_target;\n\t\tduk_hobject *bound_proto;\n\n\t\th_target = DUK_TVAL_GET_OBJECT(tv_tmp);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(h_target));\n\n\t\t/* Internal prototype must be copied from the target.\n\t\t * For lightfuncs Function.prototype is used and is already\n\t\t * in place.\n\t\t */\n\t\tbound_proto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_target);\n\t\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) h_bound, bound_proto);\n\n\t\t/* The 'strict' flag is copied to get the special [[Get]] of E5.1\n\t\t * Section 15.3.5.4 to apply when a 'caller' value is a strict bound\n\t\t * function.  Not sure if this is correct, because the specification\n\t\t * is a bit ambiguous on this point but it would make sense.\n\t\t */\n\t\t/* Strictness is inherited from target. */\n\t\tif (DUK_HOBJECT_HAS_STRICT(h_target)) {\n\t\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_bound);\n\t\t}\n\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(h_target)) {\n\t\t\tduk_hboundfunc *h_boundtarget;\n\n\t\t\th_boundtarget = (duk_hboundfunc *) (void *) h_target;\n\n\t\t\t/* The final function should always be non-bound, unless\n\t\t\t * there's a bug in the internals.  Assert for it.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(&h_boundtarget->target) ||\n\t\t\t           (DUK_TVAL_IS_OBJECT(&h_boundtarget->target) &&\n\t\t\t            DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(&h_boundtarget->target)) &&\n\t\t\t            !DUK_HOBJECT_IS_BOUNDFUNC(DUK_TVAL_GET_OBJECT(&h_boundtarget->target))));\n\n\t\t\tDUK_TVAL_SET_TVAL(&h_bound->target, &h_boundtarget->target);\n\t\t\tDUK_TVAL_SET_TVAL(&h_bound->this_binding, &h_boundtarget->this_binding);\n\n\t\t\ttv_prevbound = h_boundtarget->args;\n\t\t\tn_prevbound = h_boundtarget->nargs;\n\t\t}\n\t} else {\n\t\t/* Lightfuncs are always strict. */\n\t\tduk_hobject *bound_proto;\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_tmp));\n\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_bound);\n\t\tbound_proto = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];\n\t\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) h_bound, bound_proto);\n\t}\n\n\tDUK_TVAL_INCREF(thr, &h_bound->target);  /* old values undefined, no decref needed */\n\tDUK_TVAL_INCREF(thr, &h_bound->this_binding);\n\n\tbound_nargs = n_prevbound + nargs;\n\tif (bound_nargs > (duk_idx_t) DUK_HBOUNDFUNC_MAX_ARGS) {\n\t\tDUK_DCERROR_RANGE_INVALID_COUNT(thr);\n\t}\n\ttv_res = (duk_tval *) DUK_ALLOC_CHECKED(thr, ((duk_size_t) bound_nargs) * sizeof(duk_tval));\n\tDUK_ASSERT(tv_res != NULL || bound_nargs == 0);\n\tDUK_ASSERT(h_bound->args == NULL);\n\tDUK_ASSERT(h_bound->nargs == 0);\n\th_bound->args = tv_res;\n\th_bound->nargs = bound_nargs;\n\n\tDUK_ASSERT(n_prevbound >= 0);\n\tduk_copy_tvals_incref(thr, tv_res, tv_prevbound, (duk_size_t) n_prevbound);\n\tDUK_ASSERT(nargs >= 0);\n\tduk_copy_tvals_incref(thr, tv_res + n_prevbound, DUK_GET_TVAL_POSIDX(thr, 1), (duk_size_t) nargs);\n\n\t/* [ thisArg arg1 ... argN func boundFunc ] */\n\n\t/* Bound function 'length' property is interesting.\n\t * For lightfuncs, simply read the virtual property.\n\t */\n\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH);\n\tbound_len = duk_get_int(thr, -1);  /* ES2015: no coercion */\n\tif (bound_len < nargs) {\n\t\tbound_len = 0;\n\t} else {\n\t\tbound_len -= nargs;\n\t}\n\tif (sizeof(duk_int_t) > 4 && bound_len > (duk_int_t) DUK_UINT32_MAX) {\n\t\tbound_len = (duk_int_t) DUK_UINT32_MAX;\n\t}\n\tduk_pop(thr);\n\tDUK_ASSERT(bound_len >= 0);\n\ttv_tmp = thr->valstack_top++;\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_tmp));\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv_tmp));\n\tDUK_TVAL_SET_U32(tv_tmp, (duk_uint32_t) bound_len);  /* in-place update, fastint */\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);  /* attrs in E6 Section 9.2.4 */\n\n\t/* XXX: could these be virtual? */\n\t/* Caller and arguments must use the same thrower, [[ThrowTypeError]]. */\n\tduk_xdef_prop_stridx_thrower(thr, -1, DUK_STRIDX_CALLER);\n\tduk_xdef_prop_stridx_thrower(thr, -1, DUK_STRIDX_LC_ARGUMENTS);\n\n\t/* Function name and fileName (non-standard). */\n\tduk_push_literal(thr, \"bound \");  /* ES2015 19.2.3.2. */\n\tduk_get_prop_stridx(thr, -3, DUK_STRIDX_NAME);\n\tif (!duk_is_string_notsymbol(thr, -1)) {\n\t\t/* ES2015 has requirement to check that .name of target is a string\n\t\t * (also must check for Symbol); if not, targetName should be the\n\t\t * empty string.  ES2015 19.2.3.2.\n\t\t */\n\t\tduk_pop(thr);\n\t\tduk_push_hstring_empty(thr);\n\t}\n\tduk_concat(thr, 2);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C);\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"created bound function: %!iT\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\treturn 1;\n}\n#endif  /* DUK_USE_FUNCTION_BUILTIN */\n\n/* %NativeFunctionPrototype% .length getter. */\nDUK_INTERNAL duk_ret_t duk_bi_native_function_length(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hnatfunc *h;\n\tduk_int16_t func_nargs;\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = (duk_hnatfunc *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (!DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h)) {\n\t\t\tgoto fail_type;\n\t\t}\n\t\tfunc_nargs = h->nargs;\n\t\tduk_push_int(thr, func_nargs == DUK_HNATFUNC_NARGS_VARARGS ? 0 : func_nargs);\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_small_uint_t lf_flags;\n\t\tduk_small_uint_t lf_len;\n\n\t\tlf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv);\n\t\tlf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags);\n\t\tduk_push_uint(thr, lf_len);\n\t} else {\n\t\tgoto fail_type;\n\t}\n\treturn 1;\n\n fail_type:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n\n/* %NativeFunctionPrototype% .name getter. */\nDUK_INTERNAL duk_ret_t duk_bi_native_function_name(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hnatfunc *h;\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = (duk_hnatfunc *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (!DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h)) {\n\t\t\tgoto fail_type;\n\t\t}\n#if 0\n\t\tduk_push_hnatfunc_name(thr, h);\n#endif\n\t\tduk_push_hstring_empty(thr);\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_push_lightfunc_name(thr, tv);\n\t} else {\n\t\tgoto fail_type;\n\t}\n\treturn 1;\n\n fail_type:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_hasinstance(duk_hthread *thr) {\n\t/* This binding: RHS, stack index 0: LHS. */\n\tduk_bool_t ret;\n\n\tret = duk_js_instanceof_ordinary(thr, DUK_GET_TVAL_POSIDX(thr, 0), DUK_GET_THIS_TVAL_PTR(thr));\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n/*\n *  Global object built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Encoding/decoding helpers\n */\n\n/* XXX: Could add fast path (for each transform callback) with direct byte\n * lookups (no shifting) and no explicit check for x < 0x80 before table\n * lookup.\n */\n\n/* Macros for creating and checking bitmasks for character encoding.\n * Bit number is a bit counterintuitive, but minimizes code size.\n */\n#define DUK__MKBITS(a,b,c,d,e,f,g,h)  ((duk_uint8_t) ( \\\n\t((a) << 0) | ((b) << 1) | ((c) << 2) | ((d) << 3) | \\\n\t((e) << 4) | ((f) << 5) | ((g) << 6) | ((h) << 7) \\\n\t))\n#define DUK__CHECK_BITMASK(table,cp)  ((table)[(cp) >> 3] & (1 << ((cp) & 0x07)))\n\n/* E5.1 Section 15.1.3.3: uriReserved + uriUnescaped + '#' */\nDUK_LOCAL const duk_uint8_t duk__encode_uriunescaped_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 1, 0, 1, 1, 0, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x20-0x2f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 0, 1, 0, 1),  /* 0x30-0x3f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x40-0x4f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x60-0x6f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 1, 0),  /* 0x70-0x7f */\n};\n\n/* E5.1 Section 15.1.3.4: uriUnescaped */\nDUK_LOCAL const duk_uint8_t duk__encode_uricomponent_unescaped_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 1, 0, 0, 0, 0, 0, 1), DUK__MKBITS(1, 1, 1, 0, 0, 1, 1, 0),  /* 0x20-0x2f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 0, 0, 0, 0, 0, 0),  /* 0x30-0x3f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x40-0x4f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x60-0x6f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 1, 0),  /* 0x70-0x7f */\n};\n\n/* E5.1 Section 15.1.3.1: uriReserved + '#' */\nDUK_LOCAL const duk_uint8_t duk__decode_uri_reserved_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 0, 0, 1, 1, 0, 1, 0), DUK__MKBITS(0, 0, 0, 1, 1, 0, 0, 1),  /* 0x20-0x2f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 1, 1, 0, 1, 0, 1),  /* 0x30-0x3f */\n\tDUK__MKBITS(1, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x40-0x4f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x60-0x6f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x70-0x7f */\n};\n\n/* E5.1 Section 15.1.3.2: empty */\nDUK_LOCAL const duk_uint8_t duk__decode_uri_component_reserved_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x20-0x2f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x30-0x3f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x40-0x4f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x60-0x6f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x70-0x7f */\n};\n\n#if defined(DUK_USE_SECTION_B)\n/* E5.1 Section B.2.2, step 7. */\nDUK_LOCAL const duk_uint8_t duk__escape_unescaped_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 1, 1, 0, 1, 1, 1),  /* 0x20-0x2f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 0, 0, 0, 0, 0, 0),  /* 0x30-0x3f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x40-0x4f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x60-0x6f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 0)   /* 0x70-0x7f */\n};\n#endif  /* DUK_USE_SECTION_B */\n\ntypedef struct {\n\tduk_hthread *thr;\n\tduk_hstring *h_str;\n\tduk_bufwriter_ctx bw;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p_end;\n} duk__transform_context;\n\ntypedef void (*duk__transform_callback)(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp);\n\n/* XXX: refactor and share with other code */\nDUK_LOCAL duk_small_int_t duk__decode_hex_escape(const duk_uint8_t *p, duk_small_int_t n) {\n\tduk_small_int_t ch;\n\tduk_small_int_t t = 0;\n\n\twhile (n > 0) {\n\t\tt = t * 16;\n\t\tch = (duk_small_int_t) duk_hex_dectab[*p++];\n\t\tif (DUK_LIKELY(ch >= 0)) {\n\t\t\tt += ch;\n\t\t} else {\n\t\t\treturn -1;\n\t\t}\n\t\tn--;\n\t}\n\treturn t;\n}\n\nDUK_LOCAL int duk__transform_helper(duk_hthread *thr, duk__transform_callback callback, const void *udata) {\n\tduk__transform_context tfm_ctx_alloc;\n\tduk__transform_context *tfm_ctx = &tfm_ctx_alloc;\n\tduk_codepoint_t cp;\n\n\ttfm_ctx->thr = thr;\n\n\ttfm_ctx->h_str = duk_to_hstring(thr, 0);\n\tDUK_ASSERT(tfm_ctx->h_str != NULL);\n\n\tDUK_BW_INIT_PUSHBUF(thr, &tfm_ctx->bw, DUK_HSTRING_GET_BYTELEN(tfm_ctx->h_str));  /* initial size guess */\n\n\ttfm_ctx->p_start = DUK_HSTRING_GET_DATA(tfm_ctx->h_str);\n\ttfm_ctx->p_end = tfm_ctx->p_start + DUK_HSTRING_GET_BYTELEN(tfm_ctx->h_str);\n\ttfm_ctx->p = tfm_ctx->p_start;\n\n\twhile (tfm_ctx->p < tfm_ctx->p_end) {\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &tfm_ctx->p, tfm_ctx->p_start, tfm_ctx->p_end);\n\t\tcallback(tfm_ctx, udata, cp);\n\t}\n\n\tDUK_BW_COMPACT(thr, &tfm_ctx->bw);\n\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if transform is safe. */\n\treturn 1;\n}\n\nDUK_LOCAL void duk__transform_callback_encode_uri(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tduk_uint8_t xutf8_buf[DUK_UNICODE_MAX_XUTF8_LENGTH];\n\tduk_small_int_t len;\n\tduk_codepoint_t cp1, cp2;\n\tduk_small_int_t i, t;\n\tconst duk_uint8_t *unescaped_table = (const duk_uint8_t *) udata;\n\n\t/* UTF-8 encoded bytes escaped as %xx%xx%xx... -> 3 * nbytes.\n\t * Codepoint range is restricted so this is a slightly too large\n\t * but doesn't matter.\n\t */\n\tDUK_BW_ENSURE(tfm_ctx->thr, &tfm_ctx->bw, 3 * DUK_UNICODE_MAX_XUTF8_LENGTH);\n\n\tif (cp < 0) {\n\t\tgoto uri_error;\n\t} else if ((cp < 0x80L) && DUK__CHECK_BITMASK(unescaped_table, cp)) {\n\t\tDUK_BW_WRITE_RAW_U8(tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t) cp);\n\t\treturn;\n\t} else if (cp >= 0xdc00L && cp <= 0xdfffL) {\n\t\tgoto uri_error;\n\t} else if (cp >= 0xd800L && cp <= 0xdbffL) {\n\t\t/* Needs lookahead */\n\t\tif (duk_unicode_decode_xutf8(tfm_ctx->thr, &tfm_ctx->p, tfm_ctx->p_start, tfm_ctx->p_end, (duk_ucodepoint_t *) &cp2) == 0) {\n\t\t\tgoto uri_error;\n\t\t}\n\t\tif (!(cp2 >= 0xdc00L && cp2 <= 0xdfffL)) {\n\t\t\tgoto uri_error;\n\t\t}\n\t\tcp1 = cp;\n\t\tcp = (duk_codepoint_t) (((cp1 - 0xd800L) << 10) + (cp2 - 0xdc00L) + 0x10000L);\n\t} else if (cp > 0x10ffffL) {\n\t\t/* Although we can allow non-BMP characters (they'll decode\n\t\t * back into surrogate pairs), we don't allow extended UTF-8\n\t\t * characters; they would encode to URIs which won't decode\n\t\t * back because of strict UTF-8 checks in URI decoding.\n\t\t * (However, we could just as well allow them here.)\n\t\t */\n\t\tgoto uri_error;\n\t} else {\n\t\t/* Non-BMP characters within valid UTF-8 range: encode as is.\n\t\t * They'll decode back into surrogate pairs if the escaped\n\t\t * output is decoded.\n\t\t */\n\t\t;\n\t}\n\n\tlen = duk_unicode_encode_xutf8((duk_ucodepoint_t) cp, xutf8_buf);\n\tfor (i = 0; i < len; i++) {\n\t\tt = (duk_small_int_t) xutf8_buf[i];\n\t\tDUK_BW_WRITE_RAW_U8_3(tfm_ctx->thr,\n\t\t                      &tfm_ctx->bw,\n\t\t                      DUK_ASC_PERCENT,\n\t\t                      (duk_uint8_t) duk_uc_nybbles[t >> 4],\n                                      (duk_uint8_t) duk_uc_nybbles[t & 0x0f]);\n\t}\n\n\treturn;\n\n uri_error:\n\tDUK_ERROR_URI(tfm_ctx->thr, DUK_STR_INVALID_INPUT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__transform_callback_decode_uri(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tconst duk_uint8_t *reserved_table = (const duk_uint8_t *) udata;\n\tduk_small_uint_t utf8_blen;\n\tduk_codepoint_t min_cp;\n\tduk_small_int_t t;  /* must be signed */\n\tduk_small_uint_t i;\n\n\t/* Maximum write size: XUTF8 path writes max DUK_UNICODE_MAX_XUTF8_LENGTH,\n\t * percent escape path writes max two times CESU-8 encoded BMP length.\n\t */\n\tDUK_BW_ENSURE(tfm_ctx->thr,\n\t              &tfm_ctx->bw,\n\t              (DUK_UNICODE_MAX_XUTF8_LENGTH >= 2 * DUK_UNICODE_MAX_CESU8_BMP_LENGTH ?\n\t              DUK_UNICODE_MAX_XUTF8_LENGTH : DUK_UNICODE_MAX_CESU8_BMP_LENGTH));\n\n\tif (cp == (duk_codepoint_t) '%') {\n\t\tconst duk_uint8_t *p = tfm_ctx->p;\n\t\tduk_size_t left = (duk_size_t) (tfm_ctx->p_end - p);  /* bytes left */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"percent encoding, left=%ld\", (long) left));\n\n\t\tif (left < 2) {\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tt = duk__decode_hex_escape(p, 2);\n\t\tDUK_DDD(DUK_DDDPRINT(\"first byte: %ld\", (long) t));\n\t\tif (t < 0) {\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tif (t < 0x80) {\n\t\t\tif (DUK__CHECK_BITMASK(reserved_table, t)) {\n\t\t\t\t/* decode '%xx' to '%xx' if decoded char in reserved set */\n\t\t\t\tDUK_ASSERT(tfm_ctx->p - 1 >= tfm_ctx->p_start);\n\t\t\t\tDUK_BW_WRITE_RAW_U8_3(tfm_ctx->thr,\n\t\t\t\t                      &tfm_ctx->bw,\n\t\t\t\t                      DUK_ASC_PERCENT,\n\t\t\t\t                      p[0],\n\t\t\t\t                      p[1]);\n\t\t\t} else {\n\t\t\t\tDUK_BW_WRITE_RAW_U8(tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t) t);\n\t\t\t}\n\t\t\ttfm_ctx->p += 2;\n\t\t\treturn;\n\t\t}\n\n\t\t/* Decode UTF-8 codepoint from a sequence of hex escapes.  The\n\t\t * first byte of the sequence has been decoded to 't'.\n\t\t *\n\t\t * Note that UTF-8 validation must be strict according to the\n\t\t * specification: E5.1 Section 15.1.3, decode algorithm step\n\t\t * 4.d.vii.8.  URIError from non-shortest encodings is also\n\t\t * specifically noted in the spec.\n\t\t */\n\n\t\tDUK_ASSERT(t >= 0x80);\n\t\tif (t < 0xc0) {\n\t\t\t/* continuation byte */\n\t\t\tgoto uri_error;\n\t\t} else if (t < 0xe0) {\n\t\t\t/* 110x xxxx; 2 bytes */\n\t\t\tutf8_blen = 2;\n\t\t\tmin_cp = 0x80L;\n\t\t\tcp = t & 0x1f;\n\t\t} else if (t < 0xf0) {\n\t\t\t/* 1110 xxxx; 3 bytes */\n\t\t\tutf8_blen = 3;\n\t\t\tmin_cp = 0x800L;\n\t\t\tcp = t & 0x0f;\n\t\t} else if (t < 0xf8) {\n\t\t\t/* 1111 0xxx; 4 bytes */\n\t\t\tutf8_blen = 4;\n\t\t\tmin_cp = 0x10000L;\n\t\t\tcp = t & 0x07;\n\t\t} else {\n\t\t\t/* extended utf-8 not allowed for URIs */\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tif (left < utf8_blen * 3 - 1) {\n\t\t\t/* '%xx%xx...%xx', p points to char after first '%' */\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tp += 3;\n\t\tfor (i = 1; i < utf8_blen; i++) {\n\t\t\t/* p points to digit part ('%xy', p points to 'x') */\n\t\t\tt = duk__decode_hex_escape(p, 2);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"i=%ld utf8_blen=%ld cp=%ld t=0x%02lx\",\n\t\t\t                     (long) i, (long) utf8_blen, (long) cp, (unsigned long) t));\n\t\t\tif (t < 0) {\n\t\t\t\tgoto uri_error;\n\t\t\t}\n\t\t\tif ((t & 0xc0) != 0x80) {\n\t\t\t\tgoto uri_error;\n\t\t\t}\n\t\t\tcp = (cp << 6) + (t & 0x3f);\n\t\t\tp += 3;\n\t\t}\n\t\tp--;  /* p overshoots */\n\t\ttfm_ctx->p = p;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"final cp=%ld, min_cp=%ld\", (long) cp, (long) min_cp));\n\n\t\tif (cp < min_cp || cp > 0x10ffffL || (cp >= 0xd800L && cp <= 0xdfffL)) {\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\t/* The E5.1 algorithm checks whether or not a decoded codepoint\n\t\t * is below 0x80 and perhaps may be in the \"reserved\" set.\n\t\t * This seems pointless because the single byte UTF-8 case is\n\t\t * handled separately, and non-shortest encodings are rejected.\n\t\t * So, 'cp' cannot be below 0x80 here, and thus cannot be in\n\t\t * the reserved set.\n\t\t */\n\n\t\t/* utf-8 validation ensures these */\n\t\tDUK_ASSERT(cp >= 0x80L && cp <= 0x10ffffL);\n\n\t\tif (cp >= 0x10000L) {\n\t\t\tcp -= 0x10000L;\n\t\t\tDUK_ASSERT(cp < 0x100000L);\n\n\t\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, ((cp >> 10) + 0xd800L));\n\t\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, ((cp & 0x03ffL) + 0xdc00L));\n\t\t} else {\n\t\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp);\n\t\t}\n\t} else {\n\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp);\n\t}\n\treturn;\n\n uri_error:\n\tDUK_ERROR_URI(tfm_ctx->thr, DUK_STR_INVALID_INPUT);\n\tDUK_WO_NORETURN(return;);\n}\n\n#if defined(DUK_USE_SECTION_B)\nDUK_LOCAL void duk__transform_callback_escape(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tDUK_UNREF(udata);\n\n\tDUK_BW_ENSURE(tfm_ctx->thr, &tfm_ctx->bw, 6);\n\n\tif (cp < 0) {\n\t\tgoto esc_error;\n\t} else if ((cp < 0x80L) && DUK__CHECK_BITMASK(duk__escape_unescaped_table, cp)) {\n\t\tDUK_BW_WRITE_RAW_U8(tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t) cp);\n\t} else if (cp < 0x100L) {\n\t\tDUK_BW_WRITE_RAW_U8_3(tfm_ctx->thr,\n\t\t                      &tfm_ctx->bw,\n\t\t                      (duk_uint8_t) DUK_ASC_PERCENT,\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp >> 4],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp & 0x0f]);\n\t} else if (cp < 0x10000L) {\n\t\tDUK_BW_WRITE_RAW_U8_6(tfm_ctx->thr,\n\t\t                      &tfm_ctx->bw,\n\t\t                      (duk_uint8_t) DUK_ASC_PERCENT,\n\t\t                      (duk_uint8_t) DUK_ASC_LC_U,\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp >> 12],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[(cp >> 8) & 0x0f],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[(cp >> 4) & 0x0f],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp & 0x0f]);\n\t} else {\n\t\t/* Characters outside BMP cannot be escape()'d.  We could\n\t\t * encode them as surrogate pairs (for codepoints inside\n\t\t * valid UTF-8 range, but not extended UTF-8).  Because\n\t\t * escape() and unescape() are legacy functions, we don't.\n\t\t */\n\t\tgoto esc_error;\n\t}\n\n\treturn;\n\n esc_error:\n\tDUK_ERROR_TYPE(tfm_ctx->thr, DUK_STR_INVALID_INPUT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__transform_callback_unescape(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tduk_small_int_t t;\n\n\tDUK_UNREF(udata);\n\n\tif (cp == (duk_codepoint_t) '%') {\n\t\tconst duk_uint8_t *p = tfm_ctx->p;\n\t\tduk_size_t left = (duk_size_t) (tfm_ctx->p_end - p);  /* bytes left */\n\n\t\tif (left >= 5 && p[0] == 'u' &&\n\t\t    ((t = duk__decode_hex_escape(p + 1, 4)) >= 0)) {\n\t\t\tcp = (duk_codepoint_t) t;\n\t\t\ttfm_ctx->p += 5;\n\t\t} else if (left >= 2 &&\n\t\t           ((t = duk__decode_hex_escape(p, 2)) >= 0)) {\n\t\t\tcp = (duk_codepoint_t) t;\n\t\t\ttfm_ctx->p += 2;\n\t\t}\n\t}\n\n\tDUK_BW_WRITE_ENSURE_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp);\n}\n#endif  /* DUK_USE_SECTION_B */\n\n/*\n *  Eval\n *\n *  Eval needs to handle both a \"direct eval\" and an \"indirect eval\".\n *  Direct eval handling needs access to the caller's activation so that its\n *  lexical environment can be accessed.  A direct eval is only possible from\n *  ECMAScript code; an indirect eval call is possible also from C code.\n *  When an indirect eval call is made from C code, there may not be a\n *  calling activation at all which needs careful handling.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_activation *act_caller;\n\tduk_activation *act_eval;\n\tduk_hcompfunc *func;\n\tduk_hobject *outer_lex_env;\n\tduk_hobject *outer_var_env;\n\tduk_bool_t this_to_global = 1;\n\tduk_small_uint_t comp_flags;\n\tduk_int_t level = -2;\n\tduk_small_uint_t call_flags;\n\n\tDUK_ASSERT(duk_get_top(thr) == 1 || duk_get_top(thr) == 2);  /* 2 when called by debugger */\n\tDUK_ASSERT(thr->callstack_top >= 1);  /* at least this function exists */\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT((thr->callstack_curr->flags & DUK_ACT_FLAG_DIRECT_EVAL) == 0 || /* indirect eval */\n\t           (thr->callstack_top >= 2));  /* if direct eval, calling activation must exist */\n\n\t/*\n\t *  callstack_top - 1 --> this function\n\t *  callstack_top - 2 --> caller (may not exist)\n\t *\n\t *  If called directly from C, callstack_top might be 1.  If calling\n\t *  activation doesn't exist, call must be indirect.\n\t */\n\n\th = duk_get_hstring_notsymbol(thr, 0);\n\tif (!h) {\n\t\t/* Symbol must be returned as is, like any non-string values. */\n\t\treturn 1;  /* return arg as-is */\n\t}\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* NOTE: level is used only by the debugger and should never be present\n\t * for an ECMAScript eval().\n\t */\n\tDUK_ASSERT(level == -2);  /* by default, use caller's environment */\n\tif (duk_get_top(thr) >= 2 && duk_is_number(thr, 1)) {\n\t\tlevel = duk_get_int(thr, 1);\n\t}\n\tDUK_ASSERT(level <= -2);  /* This is guaranteed by debugger code. */\n#endif\n\n\t/* [ source ] */\n\n\tcomp_flags = DUK_COMPILE_EVAL;\n\tact_eval = thr->callstack_curr;  /* this function */\n\tDUK_ASSERT(act_eval != NULL);\n\tact_caller = duk_hthread_get_activation_for_level(thr, level);\n\tif (act_caller != NULL) {\n\t\t/* Have a calling activation, check for direct eval (otherwise\n\t\t * assume indirect eval.\n\t\t */\n\t\tif ((act_caller->flags & DUK_ACT_FLAG_STRICT) &&\n\t\t    (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL)) {\n\t\t\t/* Only direct eval inherits strictness from calling code\n\t\t\t * (E5.1 Section 10.1.1).\n\t\t\t */\n\t\t\tcomp_flags |= DUK_COMPILE_STRICT;\n\t\t}\n\t} else {\n\t\tDUK_ASSERT((act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) == 0);\n\t}\n\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_INPUT);  /* XXX: copy from caller? */\n\tduk_js_compile(thr,\n\t               (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h),\n\t               (duk_size_t) DUK_HSTRING_GET_BYTELEN(h),\n\t               comp_flags);\n\tfunc = (duk_hcompfunc *) duk_known_hobject(thr, -1);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) func));\n\n\t/* [ source template ] */\n\n\t/* E5 Section 10.4.2 */\n\n\tif (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) {\n\t\tDUK_ASSERT(thr->callstack_top >= 2);\n\t\tDUK_ASSERT(act_caller != NULL);\n\t\tif (act_caller->lex_env == NULL) {\n\t\t\tDUK_ASSERT(act_caller->var_env == NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"delayed environment initialization\"));\n\n\t\t\t/* this may have side effects, so re-lookup act */\n\t\t\tduk_js_init_activation_environment_records_delayed(thr, act_caller);\n\t\t}\n\t\tDUK_ASSERT(act_caller->lex_env != NULL);\n\t\tDUK_ASSERT(act_caller->var_env != NULL);\n\n\t\tthis_to_global = 0;\n\n\t\tif (DUK_HOBJECT_HAS_STRICT((duk_hobject *) func)) {\n\t\t\tduk_hdecenv *new_env;\n\t\t\tduk_hobject *act_lex_env;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"direct eval call to a strict function -> \"\n\t\t\t                     \"var_env and lex_env to a fresh env, \"\n\t\t\t                     \"this_binding to caller's this_binding\"));\n\n\t\t\tact_lex_env = act_caller->lex_env;\n\n\t\t\tnew_env = duk_hdecenv_alloc(thr,\n\t\t\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\t\t\tDUK_ASSERT(new_env != NULL);\n\t\t\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, act_lex_env);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, act_lex_env);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new_env allocated: %!iO\", (duk_heaphdr *) new_env));\n\n\t\t\touter_lex_env = (duk_hobject *) new_env;\n\t\t\touter_var_env = (duk_hobject *) new_env;\n\n\t\t\tduk_insert(thr, 0);  /* stash to bottom of value stack to keep new_env reachable for duration of eval */\n\n\t\t\t/* compiler's responsibility */\n\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV((duk_hobject *) func));\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"direct eval call to a non-strict function -> \"\n\t\t\t                     \"var_env and lex_env to caller's envs, \"\n\t\t\t                     \"this_binding to caller's this_binding\"));\n\n\t\t\touter_lex_env = act_caller->lex_env;\n\t\t\touter_var_env = act_caller->var_env;\n\n\t\t\t/* compiler's responsibility */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV((duk_hobject *) func));\n\t\t}\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"indirect eval call -> var_env and lex_env to \"\n\t\t                     \"global object, this_binding to global object\"));\n\n\t\tthis_to_global = 1;\n\t\touter_lex_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t\touter_var_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t}\n\n\t/* Eval code doesn't need an automatic .prototype object. */\n\tduk_js_push_closure(thr, func, outer_var_env, outer_lex_env, 0 /*add_auto_proto*/);\n\n\t/* [ env? source template closure ] */\n\n\tif (this_to_global) {\n\t\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\t\tduk_push_hobject_bidx(thr, DUK_BIDX_GLOBAL);\n\t} else {\n\t\tduk_tval *tv;\n\t\tDUK_ASSERT(thr->callstack_top >= 2);\n\t\tDUK_ASSERT(act_caller != NULL);\n\t\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act_caller->bottom_byteoff - sizeof(duk_tval));  /* this is just beneath bottom */\n\t\tDUK_ASSERT(tv >= thr->valstack);\n\t\tduk_push_tval(thr, tv);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"eval -> lex_env=%!iO, var_env=%!iO, this_binding=%!T\",\n\t                     (duk_heaphdr *) outer_lex_env,\n\t                     (duk_heaphdr *) outer_var_env,\n\t                     duk_get_tval(thr, -1)));\n\n\t/* [ env? source template closure this ] */\n\n\tcall_flags = 0;\n\tif (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) {\n\t\t/* Set DIRECT_EVAL flag for the call; it's not strictly\n\t\t * needed for the 'inner' eval call (the eval body) but\n\t\t * current new.target implementation expects to find it\n\t\t * so it can traverse direct eval chains up to the real\n\t\t * calling function.\n\t\t */\n\t\tcall_flags |= DUK_CALL_FLAG_DIRECT_EVAL;\n\t}\n\tduk_handle_call_unprotected_nargs(thr, 0, call_flags);\n\n\t/* [ env? source template result ] */\n\n\treturn 1;\n}\n\n/*\n *  Parsing of ints and floats\n */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_parse_int(duk_hthread *thr) {\n\tduk_int32_t radix;\n\tduk_small_uint_t s2n_flags;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, 0);  /* Reject symbols. */\n\n\tradix = duk_to_int32(thr, 1);\n\n\t/* While parseInt() recognizes 0xdeadbeef, it doesn't recognize\n\t * ES2015 0o123 or 0b10001.\n\t */\n\ts2n_flags = DUK_S2N_FLAG_TRIM_WHITE |\n\t            DUK_S2N_FLAG_ALLOW_GARBAGE |\n\t            DUK_S2N_FLAG_ALLOW_PLUS |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |\n\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT;\n\n\t/* Specification stripPrefix maps to DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT.\n\t *\n\t * Don't autodetect octals (from leading zeroes), require user code to\n\t * provide an explicit radix 8 for parsing octal.  See write-up from Mozilla:\n\t * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt#ECMAScript_5_Removes_Octal_Interpretation\n\t */\n\n\tif (radix != 0) {\n\t\tif (radix < 2 || radix > 36) {\n\t\t\tgoto ret_nan;\n\t\t}\n\t\tif (radix != 16) {\n\t\t\ts2n_flags &= ~DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT;\n\t\t}\n\t} else {\n\t\tradix = 10;\n\t}\n\n\tduk_dup_0(thr);\n\tduk_numconv_parse(thr, (duk_small_int_t) radix, s2n_flags);\n\treturn 1;\n\n ret_nan:\n\tduk_push_nan(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_parse_float(duk_hthread *thr) {\n\tduk_small_uint_t s2n_flags;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\tduk_to_string(thr, 0);  /* Reject symbols. */\n\n\t/* XXX: check flags */\n\ts2n_flags = DUK_S2N_FLAG_TRIM_WHITE |\n\t            DUK_S2N_FLAG_ALLOW_EXP |\n\t            DUK_S2N_FLAG_ALLOW_GARBAGE |\n\t            DUK_S2N_FLAG_ALLOW_PLUS |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |\n\t            DUK_S2N_FLAG_ALLOW_INF |\n\t            DUK_S2N_FLAG_ALLOW_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO;\n\n\tduk_numconv_parse(thr, 10 /*radix*/, s2n_flags);\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n/*\n *  Number checkers\n */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_is_nan(duk_hthread *thr) {\n\tduk_double_t d = duk_to_number(thr, 0);\n\tduk_push_boolean(thr, (duk_bool_t) DUK_ISNAN(d));\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_is_finite(duk_hthread *thr) {\n\tduk_double_t d = duk_to_number(thr, 0);\n\tduk_push_boolean(thr, (duk_bool_t) DUK_ISFINITE(d));\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n/*\n *  URI handling\n */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_decode_uri(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_decode_uri, (const void *) duk__decode_uri_reserved_table);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_decode_uri_component(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_decode_uri, (const void *) duk__decode_uri_component_reserved_table);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_encode_uri(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_encode_uri, (const void *) duk__encode_uriunescaped_table);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_encode_uri_component(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_encode_uri, (const void *) duk__encode_uricomponent_unescaped_table);\n}\n\n#if defined(DUK_USE_SECTION_B)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_escape(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_escape, (const void *) NULL);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_unescape(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_unescape, (const void *) NULL);\n}\n#endif  /* DUK_USE_SECTION_B */\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n/* automatic undefs */\n#undef DUK__CHECK_BITMASK\n#undef DUK__MKBITS\n/*\n *  JSON built-ins.\n *\n *  See doc/json.rst.\n *\n *  Codepoints are handled as duk_uint_fast32_t to ensure that the full\n *  unsigned 32-bit range is supported.  This matters to e.g. JX.\n *\n *  Input parsing doesn't do an explicit end-of-input check at all.  This is\n *  safe: input string data is always NUL-terminated (0x00) and valid JSON\n *  inputs never contain plain NUL characters, so that as long as syntax checks\n *  are correct, we'll never read past the NUL.  This approach reduces code size\n *  and improves parsing performance, but it's critical that syntax checks are\n *  indeed correct!\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_JSON_SUPPORT)\n\n/*\n *  Local defines and forward declarations.\n */\n\n#define DUK__JSON_DECSTR_BUFSIZE 128\n#define DUK__JSON_DECSTR_CHUNKSIZE 64\n#define DUK__JSON_ENCSTR_CHUNKSIZE 64\n#define DUK__JSON_STRINGIFY_BUFSIZE 128\n#define DUK__JSON_MAX_ESC_LEN 10  /* '\\Udeadbeef' */\n\nDUK_LOCAL_DECL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx);\n#if defined(DUK_USE_JX)\nDUK_LOCAL_DECL duk_uint8_t duk__dec_peek(duk_json_dec_ctx *js_ctx);\n#endif\nDUK_LOCAL_DECL duk_uint8_t duk__dec_get(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL duk_uint8_t duk__dec_get_nonwhite(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n);\nDUK_LOCAL_DECL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx);\nDUK_LOCAL_DECL void duk__dec_string(duk_json_dec_ctx *js_ctx);\n#if defined(DUK_USE_JX)\nDUK_LOCAL_DECL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_pointer(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_buffer(duk_json_dec_ctx *js_ctx);\n#endif\nDUK_LOCAL_DECL void duk__dec_number(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_object(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_array(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_value(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx);\n\nDUK_LOCAL_DECL void duk__emit_1(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch);\nDUK_LOCAL_DECL void duk__emit_2(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch1, duk_uint_fast8_t ch2);\nDUK_LOCAL_DECL void duk__unemit_1(duk_json_enc_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__emit_hstring(duk_json_enc_ctx *js_ctx, duk_hstring *h);\n#if defined(DUK_USE_FASTINT)\nDUK_LOCAL_DECL void duk__emit_cstring(duk_json_enc_ctx *js_ctx, const char *p);\n#endif\nDUK_LOCAL_DECL void duk__emit_stridx(duk_json_enc_ctx *js_ctx, duk_small_uint_t stridx);\nDUK_LOCAL_DECL duk_uint8_t *duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uint_fast32_t cp, duk_uint8_t *q);\nDUK_LOCAL_DECL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k);\nDUK_LOCAL_DECL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str);\nDUK_LOCAL_DECL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top);\nDUK_LOCAL_DECL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top);\nDUK_LOCAL_DECL void duk__enc_object(duk_json_enc_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__enc_array(duk_json_enc_ctx *js_ctx);\nDUK_LOCAL_DECL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder);\nDUK_LOCAL_DECL duk_bool_t duk__enc_allow_into_proplist(duk_tval *tv);\nDUK_LOCAL_DECL void duk__enc_double(duk_json_enc_ctx *js_ctx);\n#if defined(DUK_USE_FASTINT)\nDUK_LOCAL_DECL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv);\n#endif\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL_DECL void duk__enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h);\nDUK_LOCAL_DECL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL_DECL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj);\n#endif\n#endif\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\nDUK_LOCAL_DECL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h);\n#endif\nDUK_LOCAL_DECL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth);\n\n/*\n *  Helper tables\n */\n\n#if defined(DUK_USE_JSON_QUOTESTRING_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_quotestr_lookup[256] = {\n\t/* 0x00 ... 0x7f: as is\n\t * 0x80: escape generically\n\t * 0x81: slow path\n\t * 0xa0 ... 0xff: backslash + one char\n\t */\n\n\t0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xe2, 0xf4, 0xee, 0x80, 0xe6, 0xf2, 0x80, 0x80,\n\t0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,\n\t0x20, 0x21, 0xa2, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,\n\t0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,\n\t0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,\n\t0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0xdc, 0x5d, 0x5e, 0x5f,\n\t0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81\n};\n#else  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\nDUK_LOCAL const duk_uint8_t duk__json_quotestr_esc[14] = {\n\tDUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL,\n\tDUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL,\n\tDUK_ASC_LC_B, DUK_ASC_LC_T, DUK_ASC_LC_N, DUK_ASC_NUL,\n\tDUK_ASC_LC_F, DUK_ASC_LC_R\n};\n#endif  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\n\n#if defined(DUK_USE_JSON_DECSTRING_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_decstr_lookup[256] = {\n\t/* 0x00: slow path\n\t * other: as is\n\t */\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x20, 0x21, 0x00, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,\n\t0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,\n\t0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,\n\t0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x00, 0x5d, 0x5e, 0x5f,\n\t0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,\n\t0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,\n\t0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,\n\t0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,\n\t0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,\n\t0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,\n\t0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,\n\t0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,\n\t0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff\n};\n#endif  /* DUK_USE_JSON_DECSTRING_FASTPATH */\n\n#if defined(DUK_USE_JSON_EATWHITE_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_eatwhite_lookup[256] = {\n\t/* 0x00: finish (non-white)\n\t * 0x01: continue\n\t */\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\n#endif  /* DUK_USE_JSON_EATWHITE_FASTPATH */\n\n#if defined(DUK_USE_JSON_DECNUMBER_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_decnumber_lookup[256] = {\n\t/* 0x00: finish (not part of number)\n\t * 0x01: continue\n\t */\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00,\n\t0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\n#endif  /* DUK_USE_JSON_DECNUMBER_FASTPATH */\n\n/*\n *  Parsing implementation.\n *\n *  JSON lexer is now separate from duk_lexer.c because there are numerous\n *  small differences making it difficult to share the lexer.\n *\n *  The parser here works with raw bytes directly; this works because all\n *  JSON delimiters are ASCII characters.  Invalid xUTF-8 encoded values\n *  inside strings will be passed on without normalization; this is not a\n *  compliance concern because compliant inputs will always be valid\n *  CESU-8 encodings.\n */\n\nDUK_LOCAL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx) {\n\t/* Shared handler to minimize parser size.  Cause will be\n\t * hidden, unfortunately, but we'll have an offset which\n\t * is often quite enough.\n\t */\n\tDUK_ERROR_FMT1(js_ctx->thr, DUK_ERR_SYNTAX_ERROR, DUK_STR_FMT_INVALID_JSON,\n\t               (long) (js_ctx->p - js_ctx->p_start));\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx) {\n\tconst duk_uint8_t *p;\n\tduk_uint8_t t;\n\n\tp = js_ctx->p;\n\tfor (;;) {\n\t\tDUK_ASSERT(p <= js_ctx->p_end);\n\t\tt = *p;\n\n#if defined(DUK_USE_JSON_EATWHITE_FASTPATH)\n\t\t/* This fast path is pretty marginal in practice.\n\t\t * XXX: candidate for removal.\n\t\t */\n\t\tDUK_ASSERT(duk__json_eatwhite_lookup[0x00] == 0x00);  /* end-of-input breaks */\n\t\tif (duk__json_eatwhite_lookup[t] == 0) {\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_JSON_EATWHITE_FASTPATH */\n\t\tif (!(t == 0x20 || t == 0x0a || t == 0x0d || t == 0x09)) {\n\t\t\t/* NUL also comes here.  Comparison order matters, 0x20\n\t\t\t * is most common whitespace.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_JSON_EATWHITE_FASTPATH */\n\t\tp++;\n\t}\n\tjs_ctx->p = p;\n}\n\n#if defined(DUK_USE_JX)\nDUK_LOCAL duk_uint8_t duk__dec_peek(duk_json_dec_ctx *js_ctx) {\n\tDUK_ASSERT(js_ctx->p <= js_ctx->p_end);\n\treturn *js_ctx->p;\n}\n#endif\n\nDUK_LOCAL duk_uint8_t duk__dec_get(duk_json_dec_ctx *js_ctx) {\n\tDUK_ASSERT(js_ctx->p <= js_ctx->p_end);\n\treturn *js_ctx->p++;\n}\n\nDUK_LOCAL duk_uint8_t duk__dec_get_nonwhite(duk_json_dec_ctx *js_ctx) {\n\tduk__dec_eat_white(js_ctx);\n\treturn duk__dec_get(js_ctx);\n}\n\n/* For JX, expressing the whole unsigned 32-bit range matters. */\nDUK_LOCAL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n) {\n\tduk_small_uint_t i;\n\tduk_uint_fast32_t res = 0;\n\tduk_uint8_t x;\n\tduk_small_int_t t;\n\n\tfor (i = 0; i < n; i++) {\n\t\t/* XXX: share helper from lexer; duk_lexer.c / hexval(). */\n\n\t\tx = duk__dec_get(js_ctx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"decode_hex_escape: i=%ld, n=%ld, res=%ld, x=%ld\",\n\t\t                     (long) i, (long) n, (long) res, (long) x));\n\n\t\t/* x == 0x00 (EOF) causes syntax_error */\n\t\tDUK_ASSERT(duk_hex_dectab[0] == -1);\n\t\tt = duk_hex_dectab[x & 0xff];\n\t\tif (DUK_LIKELY(t >= 0)) {\n\t\t\tres = (res * 16) + (duk_uint_fast32_t) t;\n\t\t} else {\n\t\t\t/* catches EOF and invalid digits */\n\t\t\tgoto syntax_error;\n\t\t}\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"final hex decoded value: %ld\", (long) res));\n\treturn res;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n\treturn 0;\n}\n\nDUK_LOCAL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t x, y;\n\n\t/* First character has already been eaten and checked by the caller.\n\t * We can scan until a NUL in stridx string because no built-in strings\n\t * have internal NULs.\n\t */\n\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\th = DUK_HTHREAD_GET_STRING(js_ctx->thr, stridx);\n\tDUK_ASSERT(h != NULL);\n\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h) + 1;\n\tDUK_ASSERT(*(js_ctx->p - 1) == *(p - 1));  /* first character has been matched */\n\n\tfor (;;) {\n\t\tx = *p;\n\t\tif (x == 0) {\n\t\t\tbreak;\n\t\t}\n\t\ty = duk__dec_get(js_ctx);\n\t\tif (x != y) {\n\t\t\t/* Catches EOF of JSON input. */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\tp++;\n\t}\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\nDUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_uint8_t **ext_p) {\n\tduk_uint_fast32_t cp;\n\n\t/* EOF (-1) will be cast to an unsigned value first\n\t * and then re-cast for the switch.  In any case, it\n\t * will match the default case (syntax error).\n\t */\n\tcp = (duk_uint_fast32_t) duk__dec_get(js_ctx);\n\tswitch (cp) {\n\tcase DUK_ASC_BACKSLASH: break;\n\tcase DUK_ASC_DOUBLEQUOTE: break;\n\tcase DUK_ASC_SLASH: break;\n\tcase DUK_ASC_LC_T: cp = 0x09; break;\n\tcase DUK_ASC_LC_N: cp = 0x0a; break;\n\tcase DUK_ASC_LC_R: cp = 0x0d; break;\n\tcase DUK_ASC_LC_F: cp = 0x0c; break;\n\tcase DUK_ASC_LC_B: cp = 0x08; break;\n\tcase DUK_ASC_LC_U: {\n\t\tcp = duk__dec_decode_hex_escape(js_ctx, 4);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_JX)\n\tcase DUK_ASC_UC_U: {\n\t\tif (js_ctx->flag_ext_custom) {\n\t\t\tcp = duk__dec_decode_hex_escape(js_ctx, 8);\n\t\t} else {\n\t\t\treturn 1;  /* syntax error */\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LC_X: {\n\t\tif (js_ctx->flag_ext_custom) {\n\t\t\tcp = duk__dec_decode_hex_escape(js_ctx, 2);\n\t\t} else {\n\t\t\treturn 1;  /* syntax error */\n\t\t}\n\t\tbreak;\n\t}\n#endif  /* DUK_USE_JX */\n\tdefault:\n\t\t/* catches EOF (0x00) */\n\t\treturn 1;  /* syntax error */\n\t}\n\n\tDUK_RAW_WRITE_XUTF8(*ext_p, cp);\n\n\treturn 0;\n}\n\nDUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tduk_uint8_t *q;\n\n\t/* '\"' was eaten by caller */\n\n\t/* Note that we currently parse -bytes-, not codepoints.\n\t * All non-ASCII extended UTF-8 will encode to bytes >= 0x80,\n\t * so they'll simply pass through (valid UTF-8 or not).\n\t */\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(js_ctx->thr, bw, DUK__JSON_DECSTR_BUFSIZE);\n\tq = DUK_BW_GET_PTR(js_ctx->thr, bw);\n\n#if defined(DUK_USE_JSON_DECSTRING_FASTPATH)\n\tfor (;;) {\n\t\tduk_small_uint_t safe;\n\t\tduk_uint8_t b, x;\n\t\tconst duk_uint8_t *p;\n\n\t\t/* Select a safe loop count where no output checks are\n\t\t * needed assuming we won't encounter escapes.  Input\n\t\t * bound checks are not necessary as a NUL (guaranteed)\n\t\t * will cause a SyntaxError before we read out of bounds.\n\t\t */\n\n\t\tsafe = DUK__JSON_DECSTR_CHUNKSIZE;\n\n\t\t/* Ensure space for 1:1 output plus one escape. */\n\t\tq = DUK_BW_ENSURE_RAW(js_ctx->thr, bw, safe + DUK_UNICODE_MAX_XUTF8_LENGTH, q);\n\n\t\tp = js_ctx->p;  /* temp copy, write back for next loop */\n\t\tfor (;;) {\n\t\t\tif (safe == 0) {\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tsafe--;\n\n\t\t\t/* End of input (NUL) goes through slow path and causes SyntaxError. */\n\t\t\tDUK_ASSERT(duk__json_decstr_lookup[0] == 0x00);\n\n\t\t\tb = *p++;\n\t\t\tx = (duk_small_int_t) duk__json_decstr_lookup[b];\n\t\t\tif (DUK_LIKELY(x != 0)) {\n\t\t\t\t/* Fast path, decode as is. */\n\t\t\t\t*q++ = b;\n\t\t\t} else if (b == DUK_ASC_DOUBLEQUOTE) {\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tgoto found_quote;\n\t\t\t} else if (b == DUK_ASC_BACKSLASH) {\n\t\t\t\t/* We've ensured space for one escaped input; then\n\t\t\t\t * bail out and recheck (this makes escape handling\n\t\t\t\t * quite slow but it's uncommon).\n\t\t\t\t */\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tif (duk__dec_string_escape(js_ctx, &q) != 0) {\n\t\t\t\t\tgoto syntax_error;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t}\n\t}\n found_quote:\n#else  /* DUK_USE_JSON_DECSTRING_FASTPATH */\n\tfor (;;) {\n\t\tduk_uint8_t x;\n\n\t\tq = DUK_BW_ENSURE_RAW(js_ctx->thr, bw, DUK_UNICODE_MAX_XUTF8_LENGTH, q);\n\n\t\tx = duk__dec_get(js_ctx);\n\n\t\tif (x == DUK_ASC_DOUBLEQUOTE) {\n\t\t\tbreak;\n\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\tif (duk__dec_string_escape(js_ctx, &q) != 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t} else if (x < 0x20) {\n\t\t\t/* catches EOF (NUL) */\n\t\t\tgoto syntax_error;\n\t\t} else {\n\t\t\t*q++ = (duk_uint8_t) x;\n\t\t}\n\t}\n#endif  /* DUK_USE_JSON_DECSTRING_FASTPATH */\n\n\tDUK_BW_SETPTR_AND_COMPACT(js_ctx->thr, bw, q);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if input string is safe. */\n\n\t/* [ ... str ] */\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\n#if defined(DUK_USE_JX)\n/* Decode a plain string consisting entirely of identifier characters.\n * Used to parse plain keys (e.g. \"foo: 123\").\n */\nDUK_LOCAL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p;\n\tduk_small_int_t x;\n\n\t/* Caller has already eaten the first char so backtrack one byte. */\n\n\tjs_ctx->p--;  /* safe */\n\tp = js_ctx->p;\n\n\t/* Here again we parse bytes, and non-ASCII UTF-8 will cause end of\n\t * parsing (which is correct except if there are non-shortest encodings).\n\t * There is also no need to check explicitly for end of input buffer as\n\t * the input is NUL padded and NUL will exit the parsing loop.\n\t *\n\t * Because no unescaping takes place, we can just scan to the end of the\n\t * plain string and intern from the input buffer.\n\t */\n\n\tfor (;;) {\n\t\tx = *p;\n\n\t\t/* There is no need to check the first character specially here\n\t\t * (i.e. reject digits): the caller only accepts valid initial\n\t\t * characters and won't call us if the first character is a digit.\n\t\t * This also ensures that the plain string won't be empty.\n\t\t */\n\n\t\tif (!duk_unicode_is_identifier_part((duk_codepoint_t) x)) {\n\t\t\tbreak;\n\t\t}\n\t\tp++;\n\t}\n\n\tduk_push_lstring(thr, (const char *) js_ctx->p, (duk_size_t) (p - js_ctx->p));\n\tjs_ctx->p = p;\n\n\t/* [ ... str ] */\n}\n#endif  /* DUK_USE_JX */\n\n#if defined(DUK_USE_JX)\nDUK_LOCAL void duk__dec_pointer(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p;\n\tduk_small_int_t x;\n\tvoid *voidptr;\n\n\t/* Caller has already eaten the first character ('(') which we don't need. */\n\n\tp = js_ctx->p;\n\n\tfor (;;) {\n\t\tx = *p;\n\n\t\t/* Assume that the native representation never contains a closing\n\t\t * parenthesis.\n\t\t */\n\n\t\tif (x == DUK_ASC_RPAREN) {\n\t\t\tbreak;\n\t\t} else if (x <= 0) {\n\t\t\t/* NUL term or -1 (EOF), NUL check would suffice */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\tp++;\n\t}\n\n\t/* There is no need to NUL delimit the sscanf() call: trailing garbage is\n\t * ignored and there is always a NUL terminator which will force an error\n\t * if no error is encountered before it.  It's possible that the scan\n\t * would scan further than between [js_ctx->p,p[ though and we'd advance\n\t * by less than the scanned value.\n\t *\n\t * Because pointers are platform specific, a failure to scan a pointer\n\t * results in a null pointer which is a better placeholder than a missing\n\t * value or an error.\n\t */\n\n\tvoidptr = NULL;\n\t(void) DUK_SSCANF((const char *) js_ctx->p, DUK_STR_FMT_PTR, &voidptr);\n\tduk_push_pointer(thr, voidptr);\n\tjs_ctx->p = p + 1;  /* skip ')' */\n\n\t/* [ ... ptr ] */\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n#endif  /* DUK_USE_JX */\n\n#if defined(DUK_USE_JX)\nDUK_LOCAL void duk__dec_buffer(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t *buf;\n\tduk_size_t src_len;\n\tduk_small_int_t x;\n\n\t/* Caller has already eaten the first character ('|') which we don't need. */\n\n\tp = js_ctx->p;\n\n\t/* XXX: Would be nice to share the fast path loop from duk_hex_decode()\n\t * and avoid creating a temporary buffer.  However, there are some\n\t * differences which prevent trivial sharing:\n\t *\n\t *   - Pipe char detection\n\t *   - EOF detection\n\t *   - Unknown length of input and output\n\t *\n\t * The best approach here would be a bufwriter and a reasonaly sized\n\t * safe inner loop (e.g. 64 output bytes at a time).\n\t */\n\n\tfor (;;) {\n\t\tx = *p;\n\n\t\t/* This loop intentionally does not ensure characters are valid\n\t\t * ([0-9a-fA-F]) because the hex decode call below will do that.\n\t\t */\n\t\tif (x == DUK_ASC_PIPE) {\n\t\t\tbreak;\n\t\t} else if (x <= 0) {\n\t\t\t/* NUL term or -1 (EOF), NUL check would suffice */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\tp++;\n\t}\n\n\t/* XXX: this is not very nice; unnecessary copy is made. */\n\tsrc_len = (duk_size_t) (p - js_ctx->p);\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, src_len);\n\tDUK_ASSERT(buf != NULL);\n\tduk_memcpy((void *) buf, (const void *) js_ctx->p, src_len);\n\tduk_hex_decode(thr, -1);\n\n\tjs_ctx->p = p + 1;  /* skip '|' */\n\n\t/* [ ... buf ] */\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n#endif  /* DUK_USE_JX */\n\n/* Parse a number, other than NaN or +/- Infinity */\nDUK_LOCAL void duk__dec_number(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t x;\n\tduk_small_uint_t s2n_flags;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_number\"));\n\n\tp_start = js_ctx->p;\n\n\t/* First pass parse is very lenient (e.g. allows '1.2.3') and extracts a\n\t * string for strict number parsing.\n\t */\n\n\tp = js_ctx->p;\n\tfor (;;) {\n\t\tx = *p;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse_number: p_start=%p, p=%p, p_end=%p, x=%ld\",\n\t\t                     (const void *) p_start, (const void *) p,\n\t\t                     (const void *) js_ctx->p_end, (long) x));\n\n#if defined(DUK_USE_JSON_DECNUMBER_FASTPATH)\n\t\t/* This fast path is pretty marginal in practice.\n\t\t * XXX: candidate for removal.\n\t\t */\n\t\tDUK_ASSERT(duk__json_decnumber_lookup[0x00] == 0x00);  /* end-of-input breaks */\n\t\tif (duk__json_decnumber_lookup[x] == 0) {\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_JSON_DECNUMBER_FASTPATH */\n\t\tif (!((x >= DUK_ASC_0 && x <= DUK_ASC_9) ||\n\t\t      (x == DUK_ASC_PERIOD || x == DUK_ASC_LC_E ||\n\t\t       x == DUK_ASC_UC_E || x == DUK_ASC_MINUS || x == DUK_ASC_PLUS))) {\n\t\t\t/* Plus sign must be accepted for positive exponents\n\t\t\t * (e.g. '1.5e+2').  This clause catches NULs.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_JSON_DECNUMBER_FASTPATH */\n\t\tp++;  /* safe, because matched (NUL causes a break) */\n\t}\n\tjs_ctx->p = p;\n\n\tDUK_ASSERT(js_ctx->p > p_start);\n\tduk_push_lstring(thr, (const char *) p_start, (duk_size_t) (p - p_start));\n\n\ts2n_flags = DUK_S2N_FLAG_ALLOW_EXP |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |  /* but don't allow leading plus */\n\t            DUK_S2N_FLAG_ALLOW_FRAC;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_number: string before parsing: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_numconv_parse(thr, 10 /*radix*/, s2n_flags);\n\tif (duk_is_nan(thr, -1)) {\n\t\tduk__dec_syntax_error(js_ctx);\n\t}\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\tDUK_DDD(DUK_DDDPRINT(\"parse_number: final number: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* [ ... num ] */\n}\n\nDUK_LOCAL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_require_stack(thr, DUK_JSON_DEC_REQSTACK);\n\n\t/* c recursion check */\n\n\tDUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0);  /* unsigned */\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tif (js_ctx->recursion_depth >= js_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_JSONDEC_RECLIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tjs_ctx->recursion_depth++;\n}\n\nDUK_LOCAL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx) {\n\t/* c recursion check */\n\n\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tjs_ctx->recursion_depth--;\n}\n\nDUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_int_t key_count;  /* XXX: a \"first\" flag would suffice */\n\tduk_uint8_t x;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_object\"));\n\n\tduk__dec_objarr_entry(js_ctx);\n\n\tduk_push_object(thr);\n\n\t/* Initial '{' has been checked and eaten by caller. */\n\n\tkey_count = 0;\n\tfor (;;) {\n\t\tx = duk__dec_get_nonwhite(js_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse_object: obj=%!T, x=%ld, key_count=%ld\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t\t                     (long) x, (long) key_count));\n\n\t\t/* handle comma and closing brace */\n\n\t\tif (x == DUK_ASC_COMMA && key_count > 0) {\n\t\t\t/* accept comma, expect new value */\n\t\t\tx = duk__dec_get_nonwhite(js_ctx);\n\t\t} else if (x == DUK_ASC_RCURLY) {\n\t\t\t/* eat closing brace */\n\t\t\tbreak;\n\t\t} else if (key_count == 0) {\n\t\t\t/* accept anything, expect first value (EOF will be\n\t\t\t * caught by key parsing below.\n\t\t\t */\n\t\t\t;\n\t\t} else {\n\t\t\t/* catches EOF (NUL) and initial comma */\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/* parse key and value */\n\n\t\tif (x == DUK_ASC_DOUBLEQUOTE) {\n\t\t\tduk__dec_string(js_ctx);\n#if defined(DUK_USE_JX)\n\t\t} else if (js_ctx->flag_ext_custom &&\n\t\t           duk_unicode_is_identifier_start((duk_codepoint_t) x)) {\n\t\t\tduk__dec_plain_string(js_ctx);\n#endif\n\t\t} else {\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/* [ ... obj key ] */\n\n\t\tx = duk__dec_get_nonwhite(js_ctx);\n\t\tif (x != DUK_ASC_COLON) {\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\tduk__dec_value(js_ctx);\n\n\t\t/* [ ... obj key val ] */\n\n\t\tduk_xdef_prop_wec(thr, -3);\n\n\t\t/* [ ... obj ] */\n\n\t\tkey_count++;\n\t}\n\n\t/* [ ... obj ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_object: final object is %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__dec_objarr_exit(js_ctx);\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\nDUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_uarridx_t arr_idx;\n\tduk_uint8_t x;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_array\"));\n\n\tduk__dec_objarr_entry(js_ctx);\n\n\tduk_push_array(thr);\n\n\t/* Initial '[' has been checked and eaten by caller. */\n\n\tarr_idx = 0;\n\tfor (;;) {\n\t\tx = duk__dec_get_nonwhite(js_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse_array: arr=%!T, x=%ld, arr_idx=%ld\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t\t                     (long) x, (long) arr_idx));\n\n\t\t/* handle comma and closing bracket */\n\n\t\tif ((x == DUK_ASC_COMMA) && (arr_idx != 0)) {\n\t\t\t/* accept comma, expect new value */\n\t\t\t;\n\t\t} else if (x == DUK_ASC_RBRACKET) {\n\t\t\t/* eat closing bracket */\n\t\t\tbreak;\n\t\t} else if (arr_idx == 0) {\n\t\t\t/* accept anything, expect first value (EOF will be\n\t\t\t * caught by duk__dec_value() below.\n\t\t\t */\n\t\t\tjs_ctx->p--;  /* backtrack (safe) */\n\t\t} else {\n\t\t\t/* catches EOF (NUL) and initial comma */\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/* parse value */\n\n\t\tduk__dec_value(js_ctx);\n\n\t\t/* [ ... arr val ] */\n\n\t\tduk_xdef_prop_index_wec(thr, -2, arr_idx);\n\t\tarr_idx++;\n\t}\n\n\t/* Must set 'length' explicitly when using duk_xdef_prop_xxx() to\n\t * set the values.\n\t */\n\n\tduk_set_length(thr, -1, arr_idx);\n\n\t/* [ ... arr ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_array: final array is %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__dec_objarr_exit(js_ctx);\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\nDUK_LOCAL void duk__dec_value(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_uint8_t x;\n\n\tx = duk__dec_get_nonwhite(js_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_value: initial x=%ld\", (long) x));\n\n\t/* Note: duk__dec_req_stridx() backtracks one char */\n\n\tif (x == DUK_ASC_DOUBLEQUOTE) {\n\t\tduk__dec_string(js_ctx);\n\t} else if ((x >= DUK_ASC_0 && x <= DUK_ASC_9) || (x == DUK_ASC_MINUS)) {\n#if defined(DUK_USE_JX)\n\t\tif (js_ctx->flag_ext_custom && x == DUK_ASC_MINUS && duk__dec_peek(js_ctx) == DUK_ASC_UC_I) {\n\t\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_MINUS_INFINITY);  /* \"-Infinity\", '-' has been eaten */\n\t\t\tduk_push_number(thr, -DUK_DOUBLE_INFINITY);\n\t\t} else {\n#else\n\t\t{  /* unconditional block */\n#endif\n\t\t\t/* We already ate 'x', so backup one byte. */\n\t\t\tjs_ctx->p--;  /* safe */\n\t\t\tduk__dec_number(js_ctx);\n\t\t}\n\t} else if (x == DUK_ASC_LC_T) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_TRUE);\n\t\tduk_push_true(thr);\n\t} else if (x == DUK_ASC_LC_F) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_FALSE);\n\t\tduk_push_false(thr);\n\t} else if (x == DUK_ASC_LC_N) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_NULL);\n\t\tduk_push_null(thr);\n#if defined(DUK_USE_JX)\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_LC_U) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_UNDEFINED);\n\t\tduk_push_undefined(thr);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_N) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_NAN);\n\t\tduk_push_nan(thr);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_I) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_INFINITY);\n\t\tduk_push_number(thr, DUK_DOUBLE_INFINITY);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_LPAREN) {\n\t\tduk__dec_pointer(js_ctx);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_PIPE) {\n\t\tduk__dec_buffer(js_ctx);\n#endif\n\t} else if (x == DUK_ASC_LCURLY) {\n\t\tduk__dec_object(js_ctx);\n\t} else if (x == DUK_ASC_LBRACKET) {\n\t\tduk__dec_array(js_ctx);\n\t} else {\n\t\t/* catches EOF (NUL) */\n\t\tgoto syntax_error;\n\t}\n\n\tduk__dec_eat_white(js_ctx);\n\n\t/* [ ... val ] */\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\n/* Recursive value reviver, implements the Walk() algorithm.  No C recursion\n * check is done here because the initial parsing step will already ensure\n * there is a reasonable limit on C recursion depth and hence object depth.\n */\nDUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hobject *h;\n\tduk_uarridx_t i, arr_len;\n\n\tDUK_DDD(DUK_DDDPRINT(\"walk: top=%ld, holder=%!T, name=%!T\",\n\t                     (long) duk_get_top(thr),\n\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk_dup_top(thr);\n\tduk_get_prop(thr, -3);  /* -> [ ... holder name val ] */\n\n\th = duk_get_hobject(thr, -1);\n\tif (h != NULL) {\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tarr_len = (duk_uarridx_t) duk_get_length(thr, -1);\n\t\t\tfor (i = 0; i < arr_len; i++) {\n\t\t\t\t/* [ ... holder name val ] */\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"walk: array, top=%ld, i=%ld, arr_len=%ld, holder=%!T, name=%!T, val=%!T\",\n\t\t\t\t                     (long) duk_get_top(thr), (long) i, (long) arr_len,\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -3), (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t\tduk_dup_top(thr);\n\t\t\t\t(void) duk_push_uint_to_hstring(thr, (duk_uint_t) i);  /* -> [ ... holder name val val ToString(i) ] */\n\t\t\t\tduk__dec_reviver_walk(js_ctx);  /* -> [ ... holder name val new_elem ] */\n\n\t\t\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\tduk_del_prop_index(thr, -1, i);\n\t\t\t\t} else {\n\t\t\t\t\t/* XXX: duk_xdef_prop_index_wec() would be more appropriate\n\t\t\t\t\t * here but it currently makes some assumptions that might\n\t\t\t\t\t * not hold (e.g. that previous property is not an accessor).\n\t\t\t\t\t */\n\t\t\t\t\tduk_put_prop_index(thr, -2, i);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t/* [ ... holder name val ] */\n\t\t\tduk_enum(thr, -1, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/);\n\t\t\twhile (duk_next(thr, -1 /*enum_index*/, 0 /*get_value*/)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"walk: object, top=%ld, holder=%!T, name=%!T, val=%!T, enum=%!iT, obj_key=%!T\",\n\t\t\t\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, -5),\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -4), (duk_tval *) duk_get_tval(thr, -3),\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t\t/* [ ... holder name val enum obj_key ] */\n\t\t\t\tduk_dup_m3(thr);\n\t\t\t\tduk_dup_m2(thr);\n\n\t\t\t\t/* [ ... holder name val enum obj_key val obj_key ] */\n\t\t\t\tduk__dec_reviver_walk(js_ctx);\n\n\t\t\t\t/* [ ... holder name val enum obj_key new_elem ] */\n\t\t\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\tduk_del_prop(thr, -3);\n\t\t\t\t} else {\n\t\t\t\t\t/* XXX: duk_xdef_prop_index_wec() would be more appropriate\n\t\t\t\t\t * here but it currently makes some assumptions that might\n\t\t\t\t\t * not hold (e.g. that previous property is not an accessor).\n\t\t\t\t\t *\n\t\t\t\t\t * Using duk_put_prop() works incorrectly with '__proto__'\n\t\t\t\t\t * if the own property with that name has been deleted.  This\n\t\t\t\t\t * does not happen normally, but a clever reviver can trigger\n\t\t\t\t\t * that, see complex reviver case in: test-bug-json-parse-__proto__.js.\n\t\t\t\t\t */\n\t\t\t\t\tduk_put_prop(thr, -4);\n\t\t\t\t}\n\t\t\t}\n\t\t\tduk_pop(thr);  /* pop enum */\n\t\t}\n\t}\n\n\t/* [ ... holder name val ] */\n\n\tduk_dup(thr, js_ctx->idx_reviver);\n\tduk_insert(thr, -4);  /* -> [ ... reviver holder name val ] */\n\tduk_call_method(thr, 2);  /* -> [ ... res ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"walk: top=%ld, result=%!T\",\n\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, -1)));\n}\n\n/*\n *  Stringify implementation.\n */\n\n#define DUK__EMIT_1(js_ctx,ch)          duk__emit_1((js_ctx), (duk_uint_fast8_t) (ch))\n#define DUK__EMIT_2(js_ctx,ch1,ch2)     duk__emit_2((js_ctx), (duk_uint_fast8_t) (ch1), (duk_uint_fast8_t) (ch2))\n#define DUK__EMIT_HSTR(js_ctx,h)        duk__emit_hstring((js_ctx), (h))\n#if defined(DUK_USE_FASTINT) || defined(DUK_USE_JX) || defined(DUK_USE_JC)\n#define DUK__EMIT_CSTR(js_ctx,p)        duk__emit_cstring((js_ctx), (p))\n#endif\n#define DUK__EMIT_STRIDX(js_ctx,i)      duk__emit_stridx((js_ctx), (i))\n#define DUK__UNEMIT_1(js_ctx)           duk__unemit_1((js_ctx))\n\nDUK_LOCAL void duk__emit_1(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch) {\n\tDUK_BW_WRITE_ENSURE_U8(js_ctx->thr, &js_ctx->bw, ch);\n}\n\nDUK_LOCAL void duk__emit_2(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch1, duk_uint_fast8_t ch2) {\n\tDUK_BW_WRITE_ENSURE_U8_2(js_ctx->thr, &js_ctx->bw, ch1, ch2);\n}\n\nDUK_LOCAL void duk__emit_hstring(duk_json_enc_ctx *js_ctx, duk_hstring *h) {\n\tDUK_BW_WRITE_ENSURE_HSTRING(js_ctx->thr, &js_ctx->bw, h);\n}\n\n#if defined(DUK_USE_FASTINT) || defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL void duk__emit_cstring(duk_json_enc_ctx *js_ctx, const char *str) {\n\tDUK_BW_WRITE_ENSURE_CSTRING(js_ctx->thr, &js_ctx->bw, str);\n}\n#endif\n\nDUK_LOCAL void duk__emit_stridx(duk_json_enc_ctx *js_ctx, duk_small_uint_t stridx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\th = DUK_HTHREAD_GET_STRING(js_ctx->thr, stridx);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_BW_WRITE_ENSURE_HSTRING(js_ctx->thr, &js_ctx->bw, h);\n}\n\nDUK_LOCAL void duk__unemit_1(duk_json_enc_ctx *js_ctx) {\n\tDUK_ASSERT(DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw) >= 1);\n\tDUK_BW_ADD_PTR(js_ctx->thr, &js_ctx->bw, -1);\n}\n\n#define DUK__MKESC(nybbles,esc1,esc2)  \\\n\t(((duk_uint_fast32_t) (nybbles)) << 16) | \\\n\t(((duk_uint_fast32_t) (esc1)) << 8) | \\\n\t((duk_uint_fast32_t) (esc2))\n\nDUK_LOCAL duk_uint8_t *duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uint_fast32_t cp, duk_uint8_t *q) {\n\tduk_uint_fast32_t tmp;\n\tduk_small_uint_t dig;\n\n\tDUK_UNREF(js_ctx);\n\n\t/* Caller ensures space for at least DUK__JSON_MAX_ESC_LEN. */\n\n\t/* Select appropriate escape format automatically, and set 'tmp' to a\n\t * value encoding both the escape format character and the nybble count:\n\t *\n\t *   (nybble_count << 16) | (escape_char1) | (escape_char2)\n\t */\n\n#if defined(DUK_USE_JX)\n\tif (DUK_LIKELY(cp < 0x100UL)) {\n\t\tif (DUK_UNLIKELY(js_ctx->flag_ext_custom != 0U)) {\n\t\t\ttmp = DUK__MKESC(2, DUK_ASC_BACKSLASH, DUK_ASC_LC_X);\n\t\t} else {\n\t\t\ttmp = DUK__MKESC(4, DUK_ASC_BACKSLASH, DUK_ASC_LC_U);\n\t\t}\n\t} else\n#endif\n\tif (DUK_LIKELY(cp < 0x10000UL)) {\n\t\ttmp = DUK__MKESC(4, DUK_ASC_BACKSLASH, DUK_ASC_LC_U);\n\t} else {\n#if defined(DUK_USE_JX)\n\t\tif (DUK_LIKELY(js_ctx->flag_ext_custom != 0U)) {\n\t\t\ttmp = DUK__MKESC(8, DUK_ASC_BACKSLASH, DUK_ASC_UC_U);\n\t\t} else\n#endif\n\t\t{\n\t\t\t/* In compatible mode and standard JSON mode, output\n\t\t\t * something useful for non-BMP characters.  This won't\n\t\t\t * roundtrip but will still be more or less readable and\n\t\t\t * more useful than an error.\n\t\t\t */\n\t\t\ttmp = DUK__MKESC(8, DUK_ASC_UC_U, DUK_ASC_PLUS);\n\t\t}\n\t}\n\n\t*q++ = (duk_uint8_t) ((tmp >> 8) & 0xff);\n\t*q++ = (duk_uint8_t) (tmp & 0xff);\n\n\ttmp = tmp >> 16;\n\twhile (tmp > 0) {\n\t\ttmp--;\n\t\tdig = (duk_small_uint_t) ((cp >> (4 * tmp)) & 0x0f);\n\t\t*q++ = duk_lc_digits[dig];\n\t}\n\n\treturn q;\n}\n\nDUK_LOCAL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k) {\n\tconst duk_int8_t *p, *p_start, *p_end;  /* Note: intentionally signed. */\n\tduk_size_t k_len;\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT(k != NULL);\n\n\t/* Accept ASCII strings which conform to identifier requirements\n\t * as being emitted without key quotes.  Since we only accept ASCII\n\t * there's no need for actual decoding: 'p' is intentionally signed\n\t * so that bytes >= 0x80 extend to negative values and are rejected\n\t * as invalid identifier codepoints.\n\t */\n\n\tif (js_ctx->flag_avoid_key_quotes) {\n\t\tk_len = DUK_HSTRING_GET_BYTELEN(k);\n\t\tp_start = (const duk_int8_t *) DUK_HSTRING_GET_DATA(k);\n\t\tp_end = p_start + k_len;\n\t\tp = p_start;\n\n\t\tif (p == p_end) {\n\t\t\t/* Zero length string is not accepted without quotes */\n\t\t\tgoto quote_normally;\n\t\t}\n\t\tcp = (duk_codepoint_t) (*p++);\n\t\tif (DUK_UNLIKELY(!duk_unicode_is_identifier_start(cp))) {\n\t\t\tgoto quote_normally;\n\t\t}\n\t\twhile (p < p_end) {\n\t\t\tcp = (duk_codepoint_t) (*p++);\n\t\t\tif (DUK_UNLIKELY(!duk_unicode_is_identifier_part(cp))) {\n\t\t\t\tgoto quote_normally;\n\t\t\t}\n\t\t}\n\n\t\t/* This seems faster than emitting bytes one at a time and\n\t\t * then potentially rewinding.\n\t\t */\n\t\tDUK__EMIT_HSTR(js_ctx, k);\n\t\treturn;\n\t}\n\n quote_normally:\n\tduk__enc_quote_string(js_ctx, k);\n}\n\n/* The Quote(value) operation: quote a string.\n *\n * Stack policy: [ ] -> [ ].\n */\n\nDUK_LOCAL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p, *p_start, *p_end, *p_now, *p_tmp;\n\tduk_uint8_t *q;\n\tduk_ucodepoint_t cp;  /* typed for duk_unicode_decode_xutf8() */\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_quote_string: h_str=%!O\", (duk_heaphdr *) h_str));\n\n\tDUK_ASSERT(h_str != NULL);\n\tp_start = DUK_HSTRING_GET_DATA(h_str);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_str);\n\tp = p_start;\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_DOUBLEQUOTE);\n\n\t/* Encode string in small chunks, estimating the maximum expansion so that\n\t * there's no need to ensure space while processing the chunk.\n\t */\n\n\twhile (p < p_end) {\n\t\tduk_size_t left, now, space;\n\n\t\tleft = (duk_size_t) (p_end - p);\n\t\tnow = (left > DUK__JSON_ENCSTR_CHUNKSIZE ?\n\t\t       DUK__JSON_ENCSTR_CHUNKSIZE : left);\n\n\t\t/* Maximum expansion per input byte is 6:\n\t\t *   - invalid UTF-8 byte causes \"\\uXXXX\" to be emitted (6/1 = 6).\n\t\t *   - 2-byte UTF-8 encodes as \"\\uXXXX\" (6/2 = 3).\n\t\t *   - 4-byte UTF-8 encodes as \"\\Uxxxxxxxx\" (10/4 = 2.5).\n\t\t */\n\t\tspace = now * 6;\n\t\tq = DUK_BW_ENSURE_GETPTR(thr, &js_ctx->bw, space);\n\n\t\tp_now = p + now;\n\n\t\twhile (p < p_now) {\n#if defined(DUK_USE_JSON_QUOTESTRING_FASTPATH)\n\t\t\tduk_uint8_t b;\n\n\t\t\tb = duk__json_quotestr_lookup[*p++];\n\t\t\tif (DUK_LIKELY(b < 0x80)) {\n\t\t\t\t/* Most input bytes go through here. */\n\t\t\t\t*q++ = b;\n\t\t\t} else if (b >= 0xa0) {\n\t\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t\t\t*q++ = (duk_uint8_t) (b - 0x80);\n\t\t\t} else if (b == 0x80) {\n\t\t\t\tcp = (duk_ucodepoint_t) (*(p - 1));\n\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t} else if (b == 0x7f && js_ctx->flag_ascii_only) {\n\t\t\t\t/* 0x7F is special */\n\t\t\t\tDUK_ASSERT(b == 0x81);\n\t\t\t\tcp = (duk_ucodepoint_t) 0x7f;\n\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(b == 0x81);\n\t\t\t\tp--;\n\n\t\t\t\t/* slow path is shared */\n#else  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\n\t\t\tcp = *p;\n\n\t\t\tif (DUK_LIKELY(cp <= 0x7f)) {\n\t\t\t\t/* ascii fast path: avoid decoding utf-8 */\n\t\t\t\tp++;\n\t\t\t\tif (cp == 0x22 || cp == 0x5c) {\n\t\t\t\t\t/* double quote or backslash */\n\t\t\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t\t\t\t*q++ = (duk_uint8_t) cp;\n\t\t\t\t} else if (cp < 0x20) {\n\t\t\t\t\tduk_uint_fast8_t esc_char;\n\n\t\t\t\t\t/* This approach is a bit shorter than a straight\n\t\t\t\t\t * if-else-ladder and also a bit faster.\n\t\t\t\t\t */\n\t\t\t\t\tif (cp < (sizeof(duk__json_quotestr_esc) / sizeof(duk_uint8_t)) &&\n\t\t\t\t\t    (esc_char = duk__json_quotestr_esc[cp]) != 0) {\n\t\t\t\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t\t\t\t\t*q++ = (duk_uint8_t) esc_char;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t\t\t}\n\t\t\t\t} else if (cp == 0x7f && js_ctx->flag_ascii_only) {\n\t\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t\t} else {\n\t\t\t\t\t/* any other printable -> as is */\n\t\t\t\t\t*q++ = (duk_uint8_t) cp;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* slow path is shared */\n#endif  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\n\n\t\t\t\t/* slow path decode */\n\n\t\t\t\t/* If XUTF-8 decoding fails, treat the offending byte as a codepoint directly\n\t\t\t\t * and go forward one byte.  This is of course very lossy, but allows some kind\n\t\t\t\t * of output to be produced even for internal strings which don't conform to\n\t\t\t\t * XUTF-8.  All standard ECMAScript strings are always CESU-8, so this behavior\n\t\t\t\t * does not violate the ECMAScript specification.  The behavior is applied to\n\t\t\t\t * all modes, including ECMAScript standard JSON.  Because the current XUTF-8\n\t\t\t\t * decoding is not very strict, this behavior only really affects initial bytes\n\t\t\t\t * and truncated codepoints.\n\t\t\t\t *\n\t\t\t\t * Another alternative would be to scan forwards to start of next codepoint\n\t\t\t\t * (or end of input) and emit just one replacement codepoint.\n\t\t\t\t */\n\n\t\t\t\tp_tmp = p;\n\t\t\t\tif (!duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp)) {\n\t\t\t\t\t/* Decode failed. */\n\t\t\t\t\tcp = *p_tmp;\n\t\t\t\t\tp = p_tmp + 1;\n\t\t\t\t}\n\n#if defined(DUK_USE_NONSTD_JSON_ESC_U2028_U2029)\n\t\t\t\tif (js_ctx->flag_ascii_only || cp == 0x2028 || cp == 0x2029) {\n#else\n\t\t\t\tif (js_ctx->flag_ascii_only) {\n#endif\n\t\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t\t} else {\n\t\t\t\t\t/* as is */\n\t\t\t\t\tDUK_RAW_WRITE_XUTF8(q, cp);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tDUK_BW_SET_PTR(thr, &js_ctx->bw, q);\n\t}\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_DOUBLEQUOTE);\n}\n\n/* Encode a double (checked by caller) from stack top.  Stack top may be\n * replaced by serialized string but is not popped (caller does that).\n */\nDUK_LOCAL void duk__enc_double(duk_json_enc_ctx *js_ctx) {\n\tduk_hthread *thr;\n\tduk_tval *tv;\n\tduk_double_t d;\n\tduk_small_int_t c;\n\tduk_small_int_t s;\n\tduk_small_uint_t stridx;\n\tduk_small_uint_t n2s_flags;\n\tduk_hstring *h_str;\n\n\tDUK_ASSERT(js_ctx != NULL);\n\tthr = js_ctx->thr;\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Caller must ensure 'tv' is indeed a double and not a fastint! */\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\td = DUK_TVAL_GET_DOUBLE(tv);\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\ts = (duk_small_int_t) DUK_SIGNBIT(d);\n\tDUK_UNREF(s);\n\n\tif (DUK_LIKELY(!(c == DUK_FP_INFINITE || c == DUK_FP_NAN))) {\n\t\tDUK_ASSERT(DUK_ISFINITE(d));\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t/* Negative zero needs special handling in JX/JC because\n\t\t * it would otherwise serialize to '0', not '-0'.\n\t\t */\n\t\tif (DUK_UNLIKELY(c == DUK_FP_ZERO && s != 0 &&\n\t\t                 (js_ctx->flag_ext_custom_or_compatible))) {\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_MINUS_ZERO);  /* '-0' */\n\t\t} else\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\t\t{\n\t\t\tn2s_flags = 0;\n\t\t\t/* [ ... number ] -> [ ... string ] */\n\t\t\tduk_numconv_stringify(thr, 10 /*radix*/, 0 /*digits*/, n2s_flags);\n\t\t}\n\t\th_str = duk_known_hstring(thr, -1);\n\t\tDUK__EMIT_HSTR(js_ctx, h_str);\n\t\treturn;\n\t}\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tif (!(js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM |\n\t                       DUK_JSON_FLAG_EXT_COMPATIBLE))) {\n\t\tstridx = DUK_STRIDX_LC_NULL;\n\t} else if (c == DUK_FP_NAN) {\n\t\tstridx = js_ctx->stridx_custom_nan;\n\t} else if (s == 0) {\n\t\tstridx = js_ctx->stridx_custom_posinf;\n\t} else {\n\t\tstridx = js_ctx->stridx_custom_neginf;\n\t}\n#else\n\tstridx = DUK_STRIDX_LC_NULL;\n#endif\n\tDUK__EMIT_STRIDX(js_ctx, stridx);\n}\n\n#if defined(DUK_USE_FASTINT)\n/* Encode a fastint from duk_tval ptr, no value stack effects. */\nDUK_LOCAL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv) {\n\tduk_int64_t v;\n\n\t/* Fastint range is signed 48-bit so longest value is -2^47 = -140737488355328\n\t * (16 chars long), longest signed 64-bit value is -2^63 = -9223372036854775808\n\t * (20 chars long).  Alloc space for 64-bit range to be safe.\n\t */\n\tduk_uint8_t buf[20 + 1];\n\n\t/* Caller must ensure 'tv' is indeed a fastint! */\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\tv = DUK_TVAL_GET_FASTINT(tv);\n\n\t/* XXX: There are no format strings in duk_config.h yet, could add\n\t * one for formatting duk_int64_t.  For now, assumes \"%lld\" and that\n\t * \"long long\" type exists.  Could also rely on C99 directly but that\n\t * won't work for older MSVC.\n\t */\n\tDUK_SPRINTF((char *) buf, \"%lld\", (long long) v);\n\tDUK__EMIT_CSTR(js_ctx, (const char *) buf);\n}\n#endif\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n#if defined(DUK_USE_HEX_FASTPATH)\nDUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) {\n\tduk_uint8_t *q;\n\tduk_uint16_t *q16;\n\tduk_small_uint_t x;\n\tduk_size_t i, len_safe;\n#if !defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)\n\tduk_bool_t shift_dst;\n#endif\n\n\t/* Unlike in duk_hex_encode() 'dst' is not necessarily aligned by 2.\n\t * For platforms where unaligned accesses are not allowed, shift 'dst'\n\t * ahead by 1 byte to get alignment and then duk_memmove() the result\n\t * in place.  The faster encoding loop makes up the difference.\n\t * There's always space for one extra byte because a terminator always\n\t * follows the hex data and that's been accounted for by the caller.\n\t */\n\n#if defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)\n\tq16 = (duk_uint16_t *) (void *) dst;\n#else\n\tshift_dst = (duk_bool_t) (((duk_size_t) dst) & 0x01U);\n\tif (shift_dst) {\n\t\tDUK_DD(DUK_DDPRINT(\"unaligned accesses not possible, dst not aligned -> step to dst + 1\"));\n\t\tq16 = (duk_uint16_t *) (void *) (dst + 1);\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"unaligned accesses not possible, dst is aligned\"));\n\t\tq16 = (duk_uint16_t *) (void *) dst;\n\t}\n\tDUK_ASSERT((((duk_size_t) q16) & 0x01U) == 0);\n#endif\n\n\tlen_safe = src_len & ~0x03U;\n\tfor (i = 0; i < len_safe; i += 4) {\n\t\tq16[0] = duk_hex_enctab[src[i]];\n\t\tq16[1] = duk_hex_enctab[src[i + 1]];\n\t\tq16[2] = duk_hex_enctab[src[i + 2]];\n\t\tq16[3] = duk_hex_enctab[src[i + 3]];\n\t\tq16 += 4;\n\t}\n\tq = (duk_uint8_t *) q16;\n\n#if !defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)\n\tif (shift_dst) {\n\t\tq--;\n\t\tduk_memmove((void *) dst, (const void *) (dst + 1), 2 * len_safe);\n\t\tDUK_ASSERT(dst + 2 * len_safe == q);\n\t}\n#endif\n\n\tfor (; i < src_len; i++) {\n\t\tx = src[i];\n\t\t*q++ = duk_lc_digits[x >> 4];\n\t\t*q++ = duk_lc_digits[x & 0x0f];\n\t}\n\n\treturn q;\n}\n#else  /* DUK_USE_HEX_FASTPATH */\nDUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint8_t *q;\n\tduk_small_uint_t x;\n\n\tp = src;\n\tp_end = src + src_len;\n\tq = dst;\n\twhile (p != p_end) {\n\t\tx = *p++;\n\t\t*q++ = duk_lc_digits[x >> 4];\n\t\t*q++ = duk_lc_digits[x & 0x0f];\n\t}\n\n\treturn q;\n}\n#endif  /* DUK_USE_HEX_FASTPATH */\n\nDUK_LOCAL void duk__enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_data, duk_size_t buf_len) {\n\tduk_hthread *thr;\n\tduk_uint8_t *q;\n\tduk_size_t space;\n\n\tthr = js_ctx->thr;\n\n\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);  /* caller checks */\n\tDUK_ASSERT(js_ctx->flag_ext_custom_or_compatible);\n\n\t/* Buffer values are encoded in (lowercase) hex to make the\n\t * binary data readable.  Base64 or similar would be more\n\t * compact but less readable, and the point of JX/JC\n\t * variants is to be as useful to a programmer as possible.\n\t */\n\n\t/* The #if defined() clutter here needs to handle the three\n\t * cases: (1) JX+JC, (2) JX only, (3) JC only.\n\t */\n\n\t/* Note: space must cater for both JX and JC. */\n\tspace = 9 + buf_len * 2 + 2;\n\tDUK_ASSERT(DUK_HBUFFER_MAX_BYTELEN <= 0x7ffffffeUL);\n\tDUK_ASSERT((space - 2) / 2 >= buf_len);  /* overflow not possible, buffer limits */\n\tq = DUK_BW_ENSURE_GETPTR(thr, &js_ctx->bw, space);\n\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\tif (js_ctx->flag_ext_custom)\n#endif\n#if defined(DUK_USE_JX)\n\t{\n\t\t*q++ = DUK_ASC_PIPE;\n\t\tq = duk__enc_buffer_data_hex(buf_data, buf_len, q);\n\t\t*q++ = DUK_ASC_PIPE;\n\n\t}\n#endif\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\telse\n#endif\n#if defined(DUK_USE_JC)\n\t{\n\t\tDUK_ASSERT(js_ctx->flag_ext_compatible);\n\t\tduk_memcpy((void *) q, (const void *) \"{\\\"_buf\\\":\\\"\", 9);  /* len: 9 */\n\t\tq += 9;\n\t\tq = duk__enc_buffer_data_hex(buf_data, buf_len, q);\n\t\t*q++ = DUK_ASC_DOUBLEQUOTE;\n\t\t*q++ = DUK_ASC_RCURLY;\n\t}\n#endif\n\n\tDUK_BW_SET_PTR(thr, &js_ctx->bw, q);\n}\n\nDUK_LOCAL void duk__enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) {\n\tduk__enc_buffer_data(js_ctx,\n\t                     (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(js_ctx->thr->heap, h),\n\t                     (duk_size_t) DUK_HBUFFER_GET_SIZE(h));\n}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\nDUK_LOCAL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) {\n\tduk_size_t i, n;\n\tconst duk_uint8_t *buf;\n\tduk_uint8_t *q;\n\n\tn = DUK_HBUFFER_GET_SIZE(h);\n\tif (n == 0) {\n\t\tDUK__EMIT_2(js_ctx, DUK_ASC_LCURLY, DUK_ASC_RCURLY);\n\t\treturn;\n\t}\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);\n\n\t/* Maximum encoded length with 32-bit index: 1 + 10 + 2 + 3 + 1 + 1 = 18,\n\t * with 64-bit index: 1 + 20 + 2 + 3 + 1 + 1 = 28.  32 has some slack.\n\t *\n\t * Note that because the output buffer is reallocated from time to time,\n\t * side effects (such as finalizers) affecting the buffer 'h' must be\n\t * disabled.  This is the case in the JSON.stringify() fast path.\n\t */\n\n\tbuf = (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(js_ctx->thr->heap, h);\n\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth + 1);\n\t\t\tq = DUK_BW_ENSURE_GETPTR(js_ctx->thr, &js_ctx->bw, 32);\n\t\t\tq += DUK_SPRINTF((char *) q, \"\\\"%lu\\\": %u,\", (unsigned long) i, (unsigned int) buf[i]);\n\t\t\tDUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, q);\n\t\t}\n\t} else {\n\t\tq = DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw);\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tq = DUK_BW_ENSURE_RAW(js_ctx->thr, &js_ctx->bw, 32, q);\n\t\t\tq += DUK_SPRINTF((char *) q, \"\\\"%lu\\\":%u,\", (unsigned long) i, (unsigned int) buf[i]);\n\t\t}\n\t\tDUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, q);\n\t}\n\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\n\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t}\n\tDUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);\n}\n#endif  /* DUK_USE_JSON_STRINGIFY_FASTPATH */\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr) {\n\tchar buf[64];  /* XXX: how to figure correct size? */\n\tconst char *fmt;\n\n\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);  /* caller checks */\n\tDUK_ASSERT(js_ctx->flag_ext_custom_or_compatible);\n\n\tduk_memzero(buf, sizeof(buf));\n\n\t/* The #if defined() clutter here needs to handle the three\n\t * cases: (1) JX+JC, (2) JX only, (3) JC only.\n\t */\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\tif (js_ctx->flag_ext_custom)\n#endif\n#if defined(DUK_USE_JX)\n\t{\n\t\tfmt = ptr ? \"(%p)\" : \"(null)\";\n\t}\n#endif\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\telse\n#endif\n#if defined(DUK_USE_JC)\n\t{\n\t\tDUK_ASSERT(js_ctx->flag_ext_compatible);\n\t\tfmt = ptr ? \"{\\\"_ptr\\\":\\\"%p\\\"}\" : \"{\\\"_ptr\\\":\\\"null\\\"}\";\n\t}\n#endif\n\n\t/* When ptr == NULL, the format argument is unused. */\n\tDUK_SNPRINTF(buf, sizeof(buf) - 1, fmt, ptr);  /* must not truncate */\n\tDUK__EMIT_CSTR(js_ctx, buf);\n}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj) {\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\tif (h_bufobj->buf == NULL || !DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t} else {\n\t\t/* Handle both full and partial slice (as long as covered). */\n\t\tduk__enc_buffer_data(js_ctx,\n\t\t                     (duk_uint8_t *) DUK_HBUFOBJ_GET_SLICE_BASE(js_ctx->thr->heap, h_bufobj),\n\t\t                     (duk_size_t) h_bufobj->length);\n\t}\n}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* Indent helper.  Calling code relies on js_ctx->recursion_depth also being\n * directly related to indent depth.\n */\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) {\n\tDUK_ASSERT(js_ctx->h_gap != NULL);\n\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) > 0);  /* caller guarantees */\n\n\tDUK__EMIT_1(js_ctx, 0x0a);\n\twhile (depth-- > 0) {\n\t\tDUK__EMIT_HSTR(js_ctx, js_ctx->h_gap);\n\t}\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) {\n\tconst duk_uint8_t *gap_data;\n\tduk_size_t gap_len;\n\tduk_size_t avail_bytes;   /* bytes of indent available for copying */\n\tduk_size_t need_bytes;    /* bytes of indent still needed */\n\tduk_uint8_t *p_start;\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT(js_ctx->h_gap != NULL);\n\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) > 0);  /* caller guarantees */\n\n\tDUK__EMIT_1(js_ctx, 0x0a);\n\tif (DUK_UNLIKELY(depth == 0)) {\n\t\treturn;\n\t}\n\n\t/* To handle deeper indents efficiently, make use of copies we've\n\t * already emitted.  In effect we can emit a sequence of 1, 2, 4,\n\t * 8, etc copies, and then finish the last run.  Byte counters\n\t * avoid multiply with gap_len on every loop.\n\t */\n\n\tgap_data = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(js_ctx->h_gap);\n\tgap_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap);\n\tDUK_ASSERT(gap_len > 0);\n\n\tneed_bytes = gap_len * depth;\n\tp = DUK_BW_ENSURE_GETPTR(js_ctx->thr, &js_ctx->bw, need_bytes);\n\tp_start = p;\n\n\tduk_memcpy((void *) p, (const void *) gap_data, (size_t) gap_len);\n\tp += gap_len;\n\tavail_bytes = gap_len;\n\tDUK_ASSERT(need_bytes >= gap_len);\n\tneed_bytes -= gap_len;\n\n\twhile (need_bytes >= avail_bytes) {\n\t\tduk_memcpy((void *) p, (const void *) p_start, (size_t) avail_bytes);\n\t\tp += avail_bytes;\n\t\tneed_bytes -= avail_bytes;\n\t\tavail_bytes <<= 1;\n\t}\n\n\tDUK_ASSERT(need_bytes < avail_bytes);  /* need_bytes may be zero */\n\tduk_memcpy((void *) p, (const void *) p_start, (size_t) need_bytes);\n\tp += need_bytes;\n\t/*avail_bytes += need_bytes*/\n\n\tDUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, p);\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/* Shared entry handling for object/array serialization. */\nDUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hobject *h_target;\n\tduk_uint_fast32_t i, n;\n\n\t*entry_top = duk_get_top(thr);\n\n\tduk_require_stack(thr, DUK_JSON_ENC_REQSTACK);\n\n\t/* Loop check using a hybrid approach: a fixed-size visited[] array\n\t * with overflow in a loop check object.\n\t */\n\n\th_target = duk_known_hobject(thr, -1);  /* object or array */\n\n\tn = js_ctx->recursion_depth;\n\tif (DUK_UNLIKELY(n > DUK_JSON_ENC_LOOPARRAY)) {\n\t\tn = DUK_JSON_ENC_LOOPARRAY;\n\t}\n\tfor (i = 0; i < n; i++) {\n\t\tif (DUK_UNLIKELY(js_ctx->visiting[i] == h_target)) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"slow path loop detect\"));\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CYCLIC_INPUT);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t}\n\tif (js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY) {\n\t\tjs_ctx->visiting[js_ctx->recursion_depth] = h_target;\n\t} else {\n\t\tduk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) h_target);\n\t\tduk_dup_top(thr);  /* -> [ ... voidp voidp ] */\n\t\tif (duk_has_prop(thr, js_ctx->idx_loop)) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CYCLIC_INPUT);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tduk_push_true(thr);  /* -> [ ... voidp true ] */\n\t\tduk_put_prop(thr, js_ctx->idx_loop);  /* -> [ ... ] */\n\t}\n\n\t/* C recursion check. */\n\n\tDUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0);  /* unsigned */\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tif (js_ctx->recursion_depth >= js_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_JSONENC_RECLIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tjs_ctx->recursion_depth++;\n\n\tDUK_DDD(DUK_DDDPRINT(\"shared entry finished: top=%ld, loop=%!T\",\n\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop)));\n}\n\n/* Shared exit handling for object/array serialization. */\nDUK_LOCAL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hobject *h_target;\n\n\t/* C recursion check. */\n\n\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tjs_ctx->recursion_depth--;\n\n\t/* Loop check. */\n\n\th_target = duk_known_hobject(thr, *entry_top - 1);  /* original target at entry_top - 1 */\n\n\tif (js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY) {\n\t\t/* Previous entry was inside visited[], nothing to do. */\n\t} else {\n\t\tduk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) h_target);\n\t\tduk_del_prop(thr, js_ctx->idx_loop);  /* -> [ ... ] */\n\t}\n\n\t/* Restore stack top after unbalanced code paths. */\n\tduk_set_top(thr, *entry_top);\n\n\tDUK_DDD(DUK_DDDPRINT(\"shared entry finished: top=%ld, loop=%!T\",\n\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop)));\n}\n\n/* The JO(value) operation: encode object.\n *\n * Stack policy: [ object ] -> [ object ].\n */\nDUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hstring *h_key;\n\tduk_idx_t entry_top;\n\tduk_idx_t idx_obj;\n\tduk_idx_t idx_keys;\n\tduk_bool_t emitted;\n\tduk_uarridx_t arr_len, i;\n\tduk_size_t prev_size;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_object: obj=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__enc_objarr_entry(js_ctx, &entry_top);\n\n\tidx_obj = entry_top - 1;\n\n\tif (js_ctx->idx_proplist >= 0) {\n\t\tidx_keys = js_ctx->idx_proplist;\n\t} else {\n\t\t/* XXX: would be nice to enumerate an object at specified index */\n\t\tduk_dup(thr, idx_obj);\n\t\t(void) duk_hobject_get_enumerated_keys(thr, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/);  /* [ ... target ] -> [ ... target keys ] */\n\t\tidx_keys = duk_require_normalize_index(thr, -1);\n\t\t/* leave stack unbalanced on purpose */\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"idx_keys=%ld, h_keys=%!T\",\n\t                     (long) idx_keys, (duk_tval *) duk_get_tval(thr, idx_keys)));\n\n\t/* Steps 8-10 have been merged to avoid a \"partial\" variable. */\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);\n\n\t/* XXX: keys is an internal object with all keys to be processed\n\t * in its (gapless) array part.  Because nobody can touch the keys\n\t * object, we could iterate its array part directly (keeping in mind\n\t * that it can be reallocated).\n\t */\n\n\tarr_len = (duk_uarridx_t) duk_get_length(thr, idx_keys);\n\temitted = 0;\n\tfor (i = 0; i < arr_len; i++) {\n\t\tduk_get_prop_index(thr, idx_keys, i);  /* -> [ ... key ] */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"object property loop: holder=%!T, key=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_obj),\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\th_key = duk_known_hstring(thr, -1);\n\t\tDUK_ASSERT(h_key != NULL);\n\t\tDUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(h_key));  /* proplist filtering; enum options */\n\n\t\tprev_size = DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw);\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t\tduk__enc_key_autoquote(js_ctx, h_key);\n\t\t\tDUK__EMIT_2(js_ctx, DUK_ASC_COLON, DUK_ASC_SPACE);\n\t\t} else {\n\t\t\tduk__enc_key_autoquote(js_ctx, h_key);\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COLON);\n\t\t}\n\n\t\t/* [ ... key ] */\n\n\t\tif (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_obj) == 0)) {\n\t\t\t/* Value would yield 'undefined', so skip key altogether.\n\t\t\t * Side effects have already happened.\n\t\t\t */\n\t\t\tDUK_BW_SET_SIZE(js_ctx->thr, &js_ctx->bw, prev_size);\n\t\t} else {\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\t\temitted = 1;\n\t\t}\n\n\t\t/* [ ... ] */\n\t}\n\n\tif (emitted) {\n\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t}\n\t}\n\tDUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);\n\n\tduk__enc_objarr_exit(js_ctx, &entry_top);\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n}\n\n/* The JA(value) operation: encode array.\n *\n * Stack policy: [ array ] -> [ array ].\n */\nDUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_idx_t entry_top;\n\tduk_idx_t idx_arr;\n\tduk_bool_t emitted;\n\tduk_uarridx_t i, arr_len;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_array: array=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__enc_objarr_entry(js_ctx, &entry_top);\n\n\tidx_arr = entry_top - 1;\n\n\t/* Steps 8-10 have been merged to avoid a \"partial\" variable. */\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_LBRACKET);\n\n\tarr_len = (duk_uarridx_t) duk_get_length(thr, idx_arr);\n\temitted = 0;\n\tfor (i = 0; i < arr_len; i++) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"array entry loop: array=%!T, index=%ld, arr_len=%ld\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_arr),\n\t\t                     (long) i, (long) arr_len));\n\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t}\n\n\t\t(void) duk_push_uint_to_hstring(thr, (duk_uint_t) i);  /* -> [ ... key ] */\n\n\t\t/* [ ... key ] */\n\n\t\tif (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_arr) == 0)) {\n\t\t\t/* Value would normally be omitted, replace with 'null'. */\n\t\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\t} else {\n\t\t\t;\n\t\t}\n\n\t\t/* [ ... ] */\n\n\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\temitted = 1;\n\t}\n\n\tif (emitted) {\n\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t}\n\t}\n\tDUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET);\n\n\tduk__enc_objarr_exit(js_ctx, &entry_top);\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n}\n\n/* The Str(key, holder) operation.\n *\n * Stack policy: [ ... key ] -> [ ... ]\n */\nDUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_tval *tv;\n\tduk_tval *tv_holder;\n\tduk_tval *tv_key;\n\tduk_small_int_t c;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_value: idx_holder=%ld, holder=%!T, key=%!T\",\n\t                     (long) idx_holder, (duk_tval *) duk_get_tval(thr, idx_holder),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\ttv_holder = DUK_GET_TVAL_POSIDX(thr, idx_holder);\n\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_holder));\n\ttv_key = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_key));\n\tDUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(DUK_TVAL_GET_STRING(tv_key)));  /* Caller responsible. */\n\t(void) duk_hobject_getprop(thr, tv_holder, tv_key);\n\n\t/* -> [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* Standard JSON checks for .toJSON() only for actual objects; for\n\t * example, setting Number.prototype.toJSON and then serializing a\n\t * number won't invoke the .toJSON() method.  However, lightfuncs and\n\t * plain buffers mimic objects so we check for their .toJSON() method.\n\t */\n\tif (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT |\n\t                                 DUK_TYPE_MASK_LIGHTFUNC |\n\t                                 DUK_TYPE_MASK_BUFFER)) {\n\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_JSON);\n\t\tif (duk_is_callable(thr, -1)) {  /* toJSON() can also be a lightfunc */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is object, has callable toJSON() -> call it\"));\n\t\t\t/* XXX: duk_dup_unvalidated(thr, -2) etc. */\n\t\t\tduk_dup_m2(thr);          /* -> [ ... key val toJSON val ] */\n\t\t\tduk_dup_m4(thr);          /* -> [ ... key val toJSON val key ] */\n\t\t\tduk_call_method(thr, 1);  /* -> [ ... key val val' ] */\n\t\t\tduk_remove_m2(thr);       /* -> [ ... key val' ] */\n\t\t} else {\n\t\t\tduk_pop(thr);             /* -> [ ... key val ] */\n\t\t}\n\t}\n\n\t/* [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (js_ctx->h_replacer) {\n\t\t/* XXX: Here a \"slice copy\" would be useful. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"replacer is set, call replacer\"));\n\t\tduk_push_hobject(thr, js_ctx->h_replacer);  /* -> [ ... key val replacer ] */\n\t\tduk_dup(thr, idx_holder);                   /* -> [ ... key val replacer holder ] */\n\t\tduk_dup_m4(thr);                            /* -> [ ... key val replacer holder key ] */\n\t\tduk_dup_m4(thr);                            /* -> [ ... key val replacer holder key val ] */\n\t\tduk_call_method(thr, 2);                    /* -> [ ... key val val' ] */\n\t\tduk_remove_m2(thr);                         /* -> [ ... key val' ] */\n\t}\n\n\t/* [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h) &&\n\t\t    js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE)) {\n\t\t\t/* With JX/JC a bufferobject gets serialized specially. */\n\t\t\tduk_hbufobj *h_bufobj;\n\t\t\th_bufobj = (duk_hbufobj *) h;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\t\t\tduk__enc_bufobj(js_ctx, h_bufobj);\n\t\t\tgoto pop2_emitted;\n\t\t}\n\t\t/* Otherwise bufferobjects get serialized as normal objects. */\n#endif  /* JX || JC */\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t\tc = (duk_small_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h);\n\t\tswitch (c) {\n\t\tcase DUK_HOBJECT_CLASS_NUMBER: {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is a Number object -> coerce with ToNumber()\"));\n\t\t\tduk_to_number_m1(thr);\n\t\t\t/* The coercion potentially invokes user .valueOf() and .toString()\n\t\t\t * but can't result in a function value because ToPrimitive() would\n\t\t\t * reject such a result: test-dev-json-stringify-coercion-1.js.\n\t\t\t */\n\t\t\tDUK_ASSERT(!duk_is_callable(thr, -1));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_HOBJECT_CLASS_STRING: {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is a String object -> coerce with ToString()\"));\n\t\t\tduk_to_string(thr, -1);\n\t\t\t/* Same coercion behavior as for Number. */\n\t\t\tDUK_ASSERT(!duk_is_callable(thr, -1));\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tcase DUK_HOBJECT_CLASS_POINTER:\n#endif\n\t\tcase DUK_HOBJECT_CLASS_BOOLEAN: {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is a Boolean/Buffer/Pointer object -> get internal value\"));\n\t\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t\t\tduk_remove_m2(thr);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\t/* Normal object which doesn't get automatically coerced to a\n\t\t\t * primitive value.  Functions are checked for specially.  The\n\t\t\t * primitive value coercions for Number, String, Pointer, and\n\t\t\t * Boolean can't result in functions so suffices to check here.\n\t\t\t * Symbol objects are handled like plain objects (their primitive\n\t\t\t * value is NOT looked up like for e.g. String objects).\n\t\t\t */\n\t\t\tDUK_ASSERT(h != NULL);\n\t\t\tif (DUK_HOBJECT_IS_CALLABLE(h)) {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t\t\tif (js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM |\n\t\t\t\t                     DUK_JSON_FLAG_EXT_COMPATIBLE)) {\n\t\t\t\t\t/* We only get here when doing non-standard JSON encoding */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> function allowed, serialize to custom format\"));\n\t\t\t\t\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);\n\t\t\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function);\n\t\t\t\t\tgoto pop2_emitted;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> will result in undefined (function)\"));\n\t\t\t\t\tgoto pop2_undef;\n\t\t\t\t}\n#else  /* DUK_USE_JX || DUK_USE_JC */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> will result in undefined (function)\"));\n\t\t\t\tgoto pop2_undef;\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\t\t\t}\n\t\t}\n\t\t}  /* end switch */\n\t}\n\n\t/* [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (duk_check_type_mask(thr, -1, js_ctx->mask_for_undefined)) {\n\t\t/* will result in undefined */\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> will result in undefined (type mask check)\"));\n\t\tgoto pop2_undef;\n\t}\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t/* When JX/JC not in use, the type mask above will avoid this case if needed. */\n\tcase DUK_TAG_UNDEFINED: {\n\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined);\n\t\tbreak;\n\t}\n#endif\n\tcase DUK_TAG_NULL: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_TVAL_GET_BOOLEAN(tv) ?\n\t\t                 DUK_STRIDX_TRUE : DUK_STRIDX_FALSE);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t/* When JX/JC not in use, the type mask above will avoid this case if needed. */\n\tcase DUK_TAG_POINTER: {\n\t\tduk__enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv));\n\t\tbreak;\n\t}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tgoto pop2_undef;\n\t\t}\n\t\tduk__enc_quote_string(js_ctx, h);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* Function values are handled completely above (including\n\t\t * coercion results):\n\t\t */\n\t\tDUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE(h));\n\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tduk__enc_array(js_ctx);\n\t\t} else {\n\t\t\tduk__enc_object(js_ctx);\n\t\t}\n\t\tbreak;\n\t}\n\t/* Because plain buffers mimics Uint8Array, they have enumerable\n\t * index properties [0,byteLength[.  Because JSON only serializes\n\t * enumerable own properties, no properties can be serialized for\n\t * plain buffers (all virtual properties are non-enumerable).  However,\n\t * there may be a .toJSON() method which was already handled above.\n\t */\n\tcase DUK_TAG_BUFFER: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tduk__enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv));\n\t\t\tbreak;\n\t\t}\n#endif\n\n\t\t/* Could implement a fastpath, but the fast path would need\n\t\t * to handle realloc side effects correctly.\n\t\t */\n\t\tduk_to_object(thr, -1);\n\t\tduk__enc_object(js_ctx);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t/* We only get here when doing non-standard JSON encoding */\n\t\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);\n\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function);\n#else\n\t\t/* Standard JSON omits functions */\n\t\tDUK_UNREACHABLE();\n#endif\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\t/* Number serialization has a significant impact relative to\n\t\t * other fast path code, so careful fast path for fastints.\n\t\t */\n\t\tduk__enc_fastint_tval(js_ctx, tv);\n\t\tbreak;\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\t/* XXX: A fast path for usual integers would be useful when\n\t\t * fastint support is not enabled.\n\t\t */\n\t\tduk__enc_double(js_ctx);\n\t\tbreak;\n\t}\n\t}\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n pop2_emitted:\n#endif\n\tduk_pop_2(thr); /* [ ... key val ] -> [ ... ] */\n\treturn 1;  /* emitted */\n\n pop2_undef:\n\tduk_pop_2(thr);  /* [ ... key val ] -> [ ... ] */\n\treturn 0;  /* not emitted */\n}\n\n/* E5 Section 15.12.3, main algorithm, step 4.b.ii steps 1-4. */\nDUK_LOCAL duk_bool_t duk__enc_allow_into_proplist(duk_tval *tv) {\n\tduk_small_int_t c;\n\n\t/* XXX: some kind of external internal type checker?\n\t * - type mask; symbol flag; class mask\n\t */\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_STRING(tv)) {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn 1;\n\t} else if (DUK_TVAL_IS_NUMBER(tv)) {\n\t\treturn 1;\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tc = (duk_small_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h);\n\t\tif (c == DUK_HOBJECT_CLASS_STRING || c == DUK_HOBJECT_CLASS_NUMBER) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n/*\n *  JSON.stringify() fast path\n *\n *  Otherwise supports full JSON, JX, and JC features, but bails out on any\n *  possible side effect which might change the value being serialized.  The\n *  fast path can take advantage of the fact that the value being serialized\n *  is unchanged so that we can walk directly through property tables etc.\n */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\nDUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, duk_tval *tv) {\n\tduk_uint_fast32_t i, n;\n\n\tDUK_DDD(DUK_DDDPRINT(\"stringify fast: %!T\", tv));\n\n\tDUK_ASSERT(js_ctx != NULL);\n\tDUK_ASSERT(js_ctx->thr != NULL);\n\n#if 0 /* disabled for now */\n restart_match:\n#endif\n\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible) {\n\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined);\n\t\t\tbreak;\n\t\t} else {\n\t\t\tgoto emit_undefined;\n\t\t}\n#else\n\t\tgoto emit_undefined;\n#endif\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_TVAL_GET_BOOLEAN(tv) ?\n\t\t                 DUK_STRIDX_TRUE : DUK_STRIDX_FALSE);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tgoto emit_undefined;\n\t\t}\n\t\tduk__enc_quote_string(js_ctx, h);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *obj;\n\t\tduk_tval *tv_val;\n\t\tduk_bool_t emitted = 0;\n\t\tduk_uint32_t c_bit, c_all, c_array, c_unbox, c_undef,\n\t\t             c_func, c_bufobj, c_object, c_abort;\n\n\t\t/* For objects JSON.stringify() only looks for own, enumerable\n\t\t * properties which is nice for the fast path here.\n\t\t *\n\t\t * For arrays JSON.stringify() uses [[Get]] so it will actually\n\t\t * inherit properties during serialization!  This fast path\n\t\t * supports gappy arrays as long as there's no actual inherited\n\t\t * property (which might be a getter etc).\n\t\t *\n\t\t * Since recursion only happens for objects, we can have both\n\t\t * recursion and loop checks here.  We use a simple, depth-limited\n\t\t * loop check in the fast path because the object-based tracking\n\t\t * is very slow (when tested, it accounted for 50% of fast path\n\t\t * execution time for input data with a lot of small objects!).\n\t\t */\n\n\t\t/* XXX: for real world code, could just ignore array inheritance\n\t\t * and only look at array own properties.\n\t\t */\n\n\t\t/* We rely on a few object flag / class number relationships here,\n\t\t * assert for them.\n\t\t */\n\n\t\tobj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(obj != NULL);\n\t\tDUK_HOBJECT_ASSERT_VALID(obj);\n\n\t\t/* Once recursion depth is increased, exit path must decrease\n\t\t * it (though it's OK to abort the fast path).\n\t\t */\n\n\t\tDUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0);  /* unsigned */\n\t\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\t\tif (js_ctx->recursion_depth >= js_ctx->recursion_limit) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"fast path recursion limit\"));\n\t\t\tDUK_ERROR_RANGE(js_ctx->thr, DUK_STR_JSONDEC_RECLIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\n\t\tfor (i = 0, n = (duk_uint_fast32_t) js_ctx->recursion_depth; i < n; i++) {\n\t\t\tif (DUK_UNLIKELY(js_ctx->visiting[i] == obj)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"fast path loop detect\"));\n\t\t\t\tDUK_ERROR_TYPE(js_ctx->thr, DUK_STR_CYCLIC_INPUT);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\n\t\t/* Guaranteed by recursion_limit setup so we don't have to\n\t\t * check twice.\n\t\t */\n\t\tDUK_ASSERT(js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY);\n\t\tjs_ctx->visiting[js_ctx->recursion_depth] = obj;\n\t\tjs_ctx->recursion_depth++;\n\n\t\t/* If object has a .toJSON() property, we can't be certain\n\t\t * that it wouldn't mutate any value arbitrarily, so bail\n\t\t * out of the fast path.\n\t\t *\n\t\t * If an object is a Proxy we also can't avoid side effects\n\t\t * so abandon.\n\t\t */\n\t\t/* XXX: non-callable .toJSON() doesn't need to cause an abort\n\t\t * but does at the moment, probably not worth fixing.\n\t\t */\n\t\tif (duk_hobject_hasprop_raw(js_ctx->thr, obj, DUK_HTHREAD_STRING_TO_JSON(js_ctx->thr)) ||\n\t\t    DUK_HOBJECT_IS_PROXY(obj)) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"object has a .toJSON property or object is a Proxy, abort fast path\"));\n\t\t\tgoto abort_fastpath;\n\t\t}\n\n\t\t/* We could use a switch-case for the class number but it turns out\n\t\t * a small if-else ladder on class masks is better.  The if-ladder\n\t\t * should be in order of relevancy.\n\t\t */\n\n\t\t/* XXX: move masks to js_ctx? they don't change during one\n\t\t * fast path invocation.\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_CLASS_MAX <= 31);\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tc_all = DUK_HOBJECT_CMASK_ALL;\n\t\t\tc_array = DUK_HOBJECT_CMASK_ARRAY;\n\t\t\tc_unbox = DUK_HOBJECT_CMASK_NUMBER |\n\t\t\t          DUK_HOBJECT_CMASK_STRING |\n\t\t\t          DUK_HOBJECT_CMASK_BOOLEAN |\n\t\t\t          DUK_HOBJECT_CMASK_POINTER;  /* Symbols are not unboxed. */\n\t\t\tc_func = DUK_HOBJECT_CMASK_FUNCTION;\n\t\t\tc_bufobj = DUK_HOBJECT_CMASK_ALL_BUFOBJS;\n\t\t\tc_undef = 0;\n\t\t\tc_abort = 0;\n\t\t\tc_object = c_all & ~(c_array | c_unbox | c_func | c_bufobj | c_undef | c_abort);\n\t\t}\n\t\telse\n#endif\n\t\t{\n\t\t\tc_all = DUK_HOBJECT_CMASK_ALL;\n\t\t\tc_array = DUK_HOBJECT_CMASK_ARRAY;\n\t\t\tc_unbox = DUK_HOBJECT_CMASK_NUMBER |\n\t\t\t          DUK_HOBJECT_CMASK_STRING |\n\t\t\t          DUK_HOBJECT_CMASK_BOOLEAN;  /* Symbols are not unboxed. */\n\t\t\tc_func = 0;\n\t\t\tc_bufobj = 0;\n\t\t\tc_undef = DUK_HOBJECT_CMASK_FUNCTION |\n\t\t\t          DUK_HOBJECT_CMASK_POINTER;\n\t\t\t/* As the fast path doesn't currently properly support\n\t\t\t * duk_hbufobj virtual properties, abort fast path if\n\t\t\t * we encounter them in plain JSON mode.\n\t\t\t */\n\t\t\tc_abort = DUK_HOBJECT_CMASK_ALL_BUFOBJS;\n\t\t\tc_object = c_all & ~(c_array | c_unbox | c_func | c_bufobj | c_undef | c_abort);\n\t\t}\n\n\t\tc_bit = (duk_uint32_t) DUK_HOBJECT_GET_CLASS_MASK(obj);\n\t\tif (c_bit & c_object) {\n\t\t\t/* All other object types. */\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);\n\n\t\t\t/* A non-Array object should not have an array part in practice.\n\t\t\t * But since it is supported internally (and perhaps used at some\n\t\t\t * point), check and abandon if that's the case.\n\t\t\t */\n\t\t\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"non-Array object has array part, abort fast path\"));\n\t\t\t\tgoto abort_fastpath;\n\t\t\t}\n\n\t\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\t\tduk_hstring *k;\n\t\t\t\tduk_size_t prev_size;\n\n\t\t\t\tk = DUK_HOBJECT_E_GET_KEY(js_ctx->thr->heap, obj, i);\n\t\t\t\tif (!k) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (DUK_HSTRING_HAS_ARRIDX(k)) {\n\t\t\t\t\t/* If an object has array index keys we would need\n\t\t\t\t\t * to sort them into the ES2015 enumeration order to\n\t\t\t\t\t * be consistent with the slow path.  Abort the fast\n\t\t\t\t\t * path and handle in the slow path for now.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"property key is an array index, abort fast path\"));\n\t\t\t\t\tgoto abort_fastpath;\n\t\t\t\t}\n\t\t\t\tif (!DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(js_ctx->thr->heap, obj, i)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(js_ctx->thr->heap, obj, i)) {\n\t\t\t\t\t/* Getter might have arbitrary side effects,\n\t\t\t\t\t * so bail out.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"property is an accessor, abort fast path\"));\n\t\t\t\t\tgoto abort_fastpath;\n\t\t\t\t}\n\t\t\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(k))) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\ttv_val = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(js_ctx->thr->heap, obj, i);\n\n\t\t\t\tprev_size = DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw);\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t\t\t\tduk__enc_key_autoquote(js_ctx, k);\n\t\t\t\t\tDUK__EMIT_2(js_ctx, DUK_ASC_COLON, DUK_ASC_SPACE);\n\t\t\t\t} else {\n\t\t\t\t\tduk__enc_key_autoquote(js_ctx, k);\n\t\t\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COLON);\n\t\t\t\t}\n\n\t\t\t\tif (duk__json_stringify_fast_value(js_ctx, tv_val) == 0) {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"prop value not supported, rewind key and colon\"));\n\t\t\t\t\tDUK_BW_SET_SIZE(js_ctx->thr, &js_ctx->bw, prev_size);\n\t\t\t\t} else {\n\t\t\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\t\t\t\temitted = 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* If any non-Array value had enumerable virtual own\n\t\t\t * properties, they should be serialized here (actually,\n\t\t\t * before the explicit properties).  Standard types don't.\n\t\t\t */\n\n\t\t\tif (emitted) {\n\t\t\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\t\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t\t\t}\n\t\t\t}\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);\n\t\t} else if (c_bit & c_array) {\n\t\t\tduk_uint_fast32_t arr_len;\n\t\t\tduk_uint_fast32_t asize;\n\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_LBRACKET);\n\n\t\t\t/* Assume arrays are dense in the fast path. */\n\t\t\tif (!DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"Array object is sparse, abort fast path\"));\n\t\t\t\tgoto abort_fastpath;\n\t\t\t}\n\n\t\t\tarr_len = (duk_uint_fast32_t) ((duk_harray *) obj)->length;\n\t\t\tasize = (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(obj);\n\t\t\t/* Array part may be larger than 'length'; if so, iterate\n\t\t\t * only up to array 'length'.  Array part may also be smaller\n\t\t\t * than 'length' in some cases.\n\t\t\t */\n\t\t\tfor (i = 0; i < arr_len; i++) {\n\t\t\t\tduk_tval *tv_arrval;\n\t\t\t\tduk_hstring *h_tmp;\n\t\t\t\tduk_bool_t has_inherited;\n\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t\t\t}\n\n\t\t\t\tif (DUK_LIKELY(i < asize)) {\n\t\t\t\t\ttv_arrval = DUK_HOBJECT_A_GET_VALUE_PTR(js_ctx->thr->heap, obj, i);\n\t\t\t\t\tif (DUK_LIKELY(!DUK_TVAL_IS_UNUSED(tv_arrval))) {\n\t\t\t\t\t\t/* Expected case: element is present. */\n\t\t\t\t\t\tif (duk__json_stringify_fast_value(js_ctx, tv_arrval) == 0) {\n\t\t\t\t\t\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tgoto elem_done;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* Gap in array; check for inherited property,\n\t\t\t\t * bail out if one exists.  This should be enough\n\t\t\t\t * to support gappy arrays for all practical code.\n\t\t\t\t */\n\n\t\t\t\th_tmp = duk_push_uint_to_hstring(js_ctx->thr, (duk_uint_t) i);\n\t\t\t\thas_inherited = duk_hobject_hasprop_raw(js_ctx->thr, obj, h_tmp);\n\t\t\t\tduk_pop(js_ctx->thr);\n\t\t\t\tif (has_inherited) {\n\t\t\t\t\tDUK_D(DUK_DPRINT(\"gap in array, conflicting inherited property, abort fast path\"));\n\t\t\t\t\tgoto abort_fastpath;\n\t\t\t\t}\n\n\t\t\t\t/* Ordinary gap, undefined encodes to 'null' in\n\t\t\t\t * standard JSON, but JX/JC use their form for\n\t\t\t\t * undefined to better preserve the typing.\n\t\t\t\t */\n\t\t\t\tDUK_D(DUK_DPRINT(\"gap in array, no conflicting inherited property, remain on fast path\"));\n#if defined(DUK_USE_JX)\n\t\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined);\n#else\n\t\t\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n#endif\n\t\t\t\t/* fall through */\n\n\t\t\t elem_done:\n\t\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\t\t\temitted = 1;\n\t\t\t}\n\n\t\t\tif (emitted) {\n\t\t\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\t\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t\t\t}\n\t\t\t}\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET);\n\t\t} else if (c_bit & c_unbox) {\n\t\t\t/* Certain boxed types are required to go through\n\t\t\t * automatic unboxing.  Rely on internal value being\n\t\t\t * sane (to avoid infinite recursion).\n\t\t\t */\n\t\t\tDUK_ASSERT((c_bit & DUK_HOBJECT_CMASK_SYMBOL) == 0);  /* Symbols are not unboxed. */\n\n#if 1\n\t\t\t/* The code below is incorrect if .toString() or .valueOf() have\n\t\t\t * have been overridden.  The correct approach would be to look up\n\t\t\t * the method(s) and if they resolve to the built-in function we\n\t\t\t * can safely bypass it and look up the internal value directly.\n\t\t\t * Unimplemented for now, abort fast path for boxed values.\n\t\t\t */\n\t\t\tgoto abort_fastpath;\n#else  /* disabled */\n\t\t\t/* Disabled until fixed, see above. */\n\t\t\tduk_tval *tv_internal;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"auto unboxing in fast path\"));\n\n\t\t\ttv_internal = duk_hobject_get_internal_value_tval_ptr(js_ctx->thr->heap, obj);\n\t\t\tDUK_ASSERT(tv_internal != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_internal) ||\n\t\t\t           DUK_TVAL_IS_NUMBER(tv_internal) ||\n\t\t\t           DUK_TVAL_IS_BOOLEAN(tv_internal) ||\n\t\t\t           DUK_TVAL_IS_POINTER(tv_internal));\n\n\t\t\ttv = tv_internal;\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\t\t\tjs_ctx->recursion_depth--;  /* required to keep recursion depth correct */\n\t\t\tgoto restart_match;\n#endif  /* disabled */\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t} else if (c_bit & c_func) {\n\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t} else if (c_bit & c_bufobj) {\n\t\t\tduk__enc_bufobj(js_ctx, (duk_hbufobj *) obj);\n#endif\n#endif\n\t\t} else if (c_bit & c_abort) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"abort fast path for unsupported type\"));\n\t\t\tgoto abort_fastpath;\n\t\t} else {\n\t\t\tDUK_ASSERT((c_bit & c_undef) != 0);\n\n\t\t\t/* Must decrease recursion depth before returning. */\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\t\t\tjs_ctx->recursion_depth--;\n\t\t\tgoto emit_undefined;\n\t\t}\n\n\t\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\t\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\t\tjs_ctx->recursion_depth--;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\t/* Plain buffers are treated like Uint8Arrays: they have\n\t\t * enumerable indices.  Other virtual properties are not\n\t\t * enumerable, and inherited properties are not serialized.\n\t\t * However, there can be a replacer (not relevant here) or\n\t\t * a .toJSON() method (which we need to check for explicitly).\n\t\t */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (duk_hobject_hasprop_raw(js_ctx->thr,\n\t\t                            js_ctx->thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE],\n\t\t                            DUK_HTHREAD_STRING_TO_JSON(js_ctx->thr))) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"value is a plain buffer and there's an inherited .toJSON, abort fast path\"));\n\t\t\tgoto abort_fastpath;\n\t\t}\n#endif\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tduk__enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv));\n\t\t\tbreak;\n\t\t}\n#endif\n\n\t\t/* Plain buffers mimic Uint8Arrays, and have enumerable index\n\t\t * properties.\n\t\t */\n\t\tduk__enc_buffer_json_fastpath(js_ctx, DUK_TVAL_GET_BUFFER(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_POINTER: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tduk__enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv));\n\t\t\tbreak;\n\t\t} else {\n\t\t\tgoto emit_undefined;\n\t\t}\n#else\n\t\tgoto emit_undefined;\n#endif\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* A lightfunc might also inherit a .toJSON() so just bail out. */\n\t\t/* XXX: Could just lookup .toJSON() and continue in fast path,\n\t\t * as it would almost never be defined.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"value is a lightfunc, abort fast path\"));\n\t\tgoto abort_fastpath;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT: {\n\t\t/* Number serialization has a significant impact relative to\n\t\t * other fast path code, so careful fast path for fastints.\n\t\t */\n\t\tduk__enc_fastint_tval(js_ctx, tv);\n\t\tbreak;\n\t}\n#endif\n\tdefault: {\n\t\t/* XXX: A fast path for usual integers would be useful when\n\t\t * fastint support is not enabled.\n\t\t */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\n\t\t/* XXX: Stack discipline is annoying, could be changed in numconv. */\n\t\tduk_push_tval(js_ctx->thr, tv);\n\t\tduk__enc_double(js_ctx);\n\t\tduk_pop(js_ctx->thr);\n\n#if 0\n\t\t/* Could also rely on native sprintf(), but it will handle\n\t\t * values like NaN, Infinity, -0, exponent notation etc in\n\t\t * a JSON-incompatible way.\n\t\t */\n\t\tduk_double_t d;\n\t\tchar buf[64];\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\t\td = DUK_TVAL_GET_DOUBLE(tv);\n\t\tDUK_SPRINTF(buf, \"%lg\", d);\n\t\tDUK__EMIT_CSTR(js_ctx, buf);\n#endif\n\t}\n\t}\n\treturn 1;  /* not undefined */\n\n emit_undefined:\n\treturn 0;  /* value was undefined/unsupported */\n\n abort_fastpath:\n\t/* Error message doesn't matter: the error is ignored anyway. */\n\tDUK_DD(DUK_DDPRINT(\"aborting fast path\"));\n\tDUK_ERROR_INTERNAL(js_ctx->thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_LOCAL duk_ret_t duk__json_stringify_fast(duk_hthread *thr, void *udata) {\n\tduk_json_enc_ctx *js_ctx;\n\tduk_tval *tv;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(udata != NULL);\n\n\tjs_ctx = (duk_json_enc_ctx *) udata;\n\tDUK_ASSERT(js_ctx != NULL);\n\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tif (duk__json_stringify_fast_value(js_ctx, tv) == 0) {\n\t\tDUK_DD(DUK_DDPRINT(\"top level value not supported, fail fast path\"));\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);  /* Error message is ignored, so doesn't matter. */\n\t}\n\n\treturn 0;\n}\n#endif  /* DUK_USE_JSON_STRINGIFY_FASTPATH */\n\n/*\n *  Top level wrappers\n */\n\nDUK_INTERNAL\nvoid duk_bi_json_parse_helper(duk_hthread *thr,\n                              duk_idx_t idx_value,\n                              duk_idx_t idx_reviver,\n                              duk_small_uint_t flags) {\n\tduk_json_dec_ctx js_ctx_alloc;\n\tduk_json_dec_ctx *js_ctx = &js_ctx_alloc;\n\tduk_hstring *h_text;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top = duk_get_top(thr);\n#endif\n\n\t/* negative top-relative indices not allowed now */\n\tDUK_ASSERT(idx_value == DUK_INVALID_INDEX || idx_value >= 0);\n\tDUK_ASSERT(idx_reviver == DUK_INVALID_INDEX || idx_reviver >= 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON parse start: text=%!T, reviver=%!T, flags=0x%08lx, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_reviver),\n\t                     (unsigned long) flags,\n\t                     (long) duk_get_top(thr)));\n\n\tduk_memzero(&js_ctx_alloc, sizeof(js_ctx_alloc));\n\tjs_ctx->thr = thr;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t/* nothing now */\n#endif\n\tjs_ctx->recursion_limit = DUK_USE_JSON_DEC_RECLIMIT;\n\tDUK_ASSERT(js_ctx->recursion_depth == 0);\n\n\t/* Flag handling currently assumes that flags are consistent.  This is OK\n\t * because the call sites are now strictly controlled.\n\t */\n\n\tjs_ctx->flags = flags;\n#if defined(DUK_USE_JX)\n\tjs_ctx->flag_ext_custom = flags & DUK_JSON_FLAG_EXT_CUSTOM;\n#endif\n#if defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_compatible = flags & DUK_JSON_FLAG_EXT_COMPATIBLE;\n#endif\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_custom_or_compatible = flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE);\n#endif\n\n\th_text = duk_to_hstring(thr, idx_value);  /* coerce in-place; rejects Symbols */\n\tDUK_ASSERT(h_text != NULL);\n\n\t/* JSON parsing code is allowed to read [p_start,p_end]: p_end is\n\t * valid and points to the string NUL terminator (which is always\n\t * guaranteed for duk_hstrings.\n\t */\n\tjs_ctx->p_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_text);\n\tjs_ctx->p = js_ctx->p_start;\n\tjs_ctx->p_end = ((const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_text)) +\n\t                DUK_HSTRING_GET_BYTELEN(h_text);\n\tDUK_ASSERT(*(js_ctx->p_end) == 0x00);\n\n\tduk__dec_value(js_ctx);  /* -> [ ... value ] */\n\n\t/* Trailing whitespace has been eaten by duk__dec_value(), so if\n\t * we're not at end of input here, it's a SyntaxError.\n\t */\n\n\tif (js_ctx->p != js_ctx->p_end) {\n\t\tduk__dec_syntax_error(js_ctx);\n\t}\n\n\tif (duk_is_callable(thr, idx_reviver)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"applying reviver: %!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_reviver)));\n\n\t\tjs_ctx->idx_reviver = idx_reviver;\n\n\t\tduk_push_object(thr);\n\t\tduk_dup_m2(thr);  /* -> [ ... val root val ] */\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_EMPTY_STRING);  /* default attrs ok */\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_EMPTY_STRING);  /* -> [ ... val root \"\" ] */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"start reviver walk, root=%!T, name=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\tduk__dec_reviver_walk(js_ctx);  /* [ ... val root \"\" ] -> [ ... val val' ] */\n\t\tduk_remove_m2(thr);             /* -> [ ... val' ] */\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"reviver does not exist or is not callable: %!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_reviver)));\n\t}\n\n\t/* Final result is at stack top. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON parse end: text=%!T, reviver=%!T, flags=0x%08lx, result=%!T, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_reviver),\n\t                     (unsigned long) flags,\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (long) duk_get_top(thr)));\n\n\tDUK_ASSERT(duk_get_top(thr) == entry_top + 1);\n}\n\nDUK_INTERNAL\nvoid duk_bi_json_stringify_helper(duk_hthread *thr,\n                                  duk_idx_t idx_value,\n                                  duk_idx_t idx_replacer,\n                                  duk_idx_t idx_space,\n                                  duk_small_uint_t flags) {\n\tduk_json_enc_ctx js_ctx_alloc;\n\tduk_json_enc_ctx *js_ctx = &js_ctx_alloc;\n\tduk_hobject *h;\n\tduk_idx_t idx_holder;\n\tduk_idx_t entry_top;\n\n\t/* negative top-relative indices not allowed now */\n\tDUK_ASSERT(idx_value == DUK_INVALID_INDEX || idx_value >= 0);\n\tDUK_ASSERT(idx_replacer == DUK_INVALID_INDEX || idx_replacer >= 0);\n\tDUK_ASSERT(idx_space == DUK_INVALID_INDEX || idx_space >= 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON stringify start: value=%!T, replacer=%!T, space=%!T, flags=0x%08lx, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_replacer),\n\t                     (duk_tval *) duk_get_tval(thr, idx_space),\n\t                     (unsigned long) flags,\n\t                     (long) duk_get_top(thr)));\n\n\tentry_top = duk_get_top(thr);\n\n\t/*\n\t *  Context init\n\t */\n\n\tduk_memzero(&js_ctx_alloc, sizeof(js_ctx_alloc));\n\tjs_ctx->thr = thr;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tjs_ctx->h_replacer = NULL;\n\tjs_ctx->h_gap = NULL;\n#endif\n\tjs_ctx->idx_proplist = -1;\n\n\t/* Flag handling currently assumes that flags are consistent.  This is OK\n\t * because the call sites are now strictly controlled.\n\t */\n\n\tjs_ctx->flags = flags;\n\tjs_ctx->flag_ascii_only = flags & DUK_JSON_FLAG_ASCII_ONLY;\n\tjs_ctx->flag_avoid_key_quotes = flags & DUK_JSON_FLAG_AVOID_KEY_QUOTES;\n#if defined(DUK_USE_JX)\n\tjs_ctx->flag_ext_custom = flags & DUK_JSON_FLAG_EXT_CUSTOM;\n#endif\n#if defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_compatible = flags & DUK_JSON_FLAG_EXT_COMPATIBLE;\n#endif\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_custom_or_compatible = flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE);\n#endif\n\n\t/* The #if defined() clutter here handles the JX/JC enable/disable\n\t * combinations properly.\n\t */\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tjs_ctx->stridx_custom_undefined = DUK_STRIDX_LC_NULL;  /* standard JSON; array gaps */\n#if defined(DUK_USE_JX)\n\tif (flags & DUK_JSON_FLAG_EXT_CUSTOM) {\n\t\tjs_ctx->stridx_custom_undefined = DUK_STRIDX_LC_UNDEFINED;\n\t\tjs_ctx->stridx_custom_nan = DUK_STRIDX_NAN;\n\t\tjs_ctx->stridx_custom_neginf = DUK_STRIDX_MINUS_INFINITY;\n\t\tjs_ctx->stridx_custom_posinf = DUK_STRIDX_INFINITY;\n\t\tjs_ctx->stridx_custom_function =\n\t\t        (flags & DUK_JSON_FLAG_AVOID_KEY_QUOTES) ?\n\t\t                DUK_STRIDX_JSON_EXT_FUNCTION2 :\n\t\t                DUK_STRIDX_JSON_EXT_FUNCTION1;\n\t}\n#endif  /* DUK_USE_JX */\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\telse\n#endif  /* DUK_USE_JX && DUK_USE_JC */\n#if defined(DUK_USE_JC)\n\tif (js_ctx->flags & DUK_JSON_FLAG_EXT_COMPATIBLE) {\n\t\tjs_ctx->stridx_custom_undefined = DUK_STRIDX_JSON_EXT_UNDEFINED;\n\t\tjs_ctx->stridx_custom_nan = DUK_STRIDX_JSON_EXT_NAN;\n\t\tjs_ctx->stridx_custom_neginf = DUK_STRIDX_JSON_EXT_NEGINF;\n\t\tjs_ctx->stridx_custom_posinf = DUK_STRIDX_JSON_EXT_POSINF;\n\t\tjs_ctx->stridx_custom_function = DUK_STRIDX_JSON_EXT_FUNCTION1;\n\t}\n#endif  /* DUK_USE_JC */\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tif (js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM |\n\t                     DUK_JSON_FLAG_EXT_COMPATIBLE)) {\n\t\tDUK_ASSERT(js_ctx->mask_for_undefined == 0);  /* already zero */\n\t}\n\telse\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\t{\n\t\t/* Plain buffer is treated like ArrayBuffer and serialized.\n\t\t * Lightfuncs are treated like objects, but JSON explicitly\n\t\t * skips serializing Function objects so we can just reject\n\t\t * lightfuncs here.\n\t\t */\n\t\tjs_ctx->mask_for_undefined = DUK_TYPE_MASK_UNDEFINED |\n\t\t                             DUK_TYPE_MASK_POINTER |\n\t\t                             DUK_TYPE_MASK_LIGHTFUNC;\n\t}\n\n\tDUK_BW_INIT_PUSHBUF(thr, &js_ctx->bw, DUK__JSON_STRINGIFY_BUFSIZE);\n\n\tjs_ctx->idx_loop = duk_push_bare_object(thr);\n\tDUK_ASSERT(js_ctx->idx_loop >= 0);\n\n\t/* [ ... buf loop ] */\n\n\t/*\n\t *  Process replacer/proplist (2nd argument to JSON.stringify)\n\t */\n\n\th = duk_get_hobject(thr, idx_replacer);\n\tif (h != NULL) {\n\t\tif (DUK_HOBJECT_IS_CALLABLE(h)) {\n\t\t\tjs_ctx->h_replacer = h;\n\t\t} else if (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\t/* Here the specification requires correct array index enumeration\n\t\t\t * which is a bit tricky for sparse arrays (it is handled by the\n\t\t\t * enum setup code).  We now enumerate ancestors too, although the\n\t\t\t * specification is not very clear on whether that is required.\n\t\t\t */\n\n\t\t\tduk_uarridx_t plist_idx = 0;\n\t\t\tduk_small_uint_t enum_flags;\n\n\t\t\tjs_ctx->idx_proplist = duk_push_array(thr);  /* XXX: array internal? */\n\n\t\t\tenum_flags = DUK_ENUM_ARRAY_INDICES_ONLY |\n\t\t\t             DUK_ENUM_SORT_ARRAY_INDICES;  /* expensive flag */\n\t\t\tduk_enum(thr, idx_replacer, enum_flags);\n\t\t\twhile (duk_next(thr, -1 /*enum_index*/, 1 /*get_value*/)) {\n\t\t\t\t/* [ ... proplist enum_obj key val ] */\n\t\t\t\tif (duk__enc_allow_into_proplist(duk_get_tval(thr, -1))) {\n\t\t\t\t\t/* XXX: duplicates should be eliminated here */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proplist enum: key=%!T, val=%!T --> accept\",\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\t\t\tduk_to_string(thr, -1);  /* extra coercion of strings is OK */\n\t\t\t\t\tduk_put_prop_index(thr, -4, plist_idx);  /* -> [ ... proplist enum_obj key ] */\n\t\t\t\t\tplist_idx++;\n\t\t\t\t\tduk_pop(thr);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proplist enum: key=%!T, val=%!T --> reject\",\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\t\t\tduk_pop_2(thr);\n\t\t\t\t}\n                        }\n                        duk_pop(thr);  /* pop enum */\n\n\t\t\t/* [ ... proplist ] */\n\t\t}\n\t}\n\n\t/* [ ... buf loop (proplist) ] */\n\n\t/*\n\t *  Process space (3rd argument to JSON.stringify)\n\t */\n\n\th = duk_get_hobject(thr, idx_space);\n\tif (h != NULL) {\n\t\tduk_small_uint_t c = DUK_HOBJECT_GET_CLASS_NUMBER(h);\n\t\tif (c == DUK_HOBJECT_CLASS_NUMBER) {\n\t\t\tduk_to_number(thr, idx_space);\n\t\t} else if (c == DUK_HOBJECT_CLASS_STRING) {\n\t\t\tduk_to_string(thr, idx_space);\n\t\t}\n\t}\n\n\tif (duk_is_number(thr, idx_space)) {\n\t\tduk_small_int_t nspace;\n\t\t/* spaces[] must be static to allow initializer with old compilers like BCC */\n\t\tstatic const char spaces[10] = {\n\t\t\tDUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE,\n\t\t\tDUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE,\n\t\t\tDUK_ASC_SPACE, DUK_ASC_SPACE\n\t\t};  /* XXX: helper */\n\n\t\t/* ToInteger() coercion; NaN -> 0, infinities are clamped to 0 and 10 */\n\t\tnspace = (duk_small_int_t) duk_to_int_clamped(thr, idx_space, 0 /*minval*/, 10 /*maxval*/);\n\t\tDUK_ASSERT(nspace >= 0 && nspace <= 10);\n\n\t\tduk_push_lstring(thr, spaces, (duk_size_t) nspace);\n\t\tjs_ctx->h_gap = duk_known_hstring(thr, -1);\n\t\tDUK_ASSERT(js_ctx->h_gap != NULL);\n\t} else if (duk_is_string_notsymbol(thr, idx_space)) {\n\t\tduk_dup(thr, idx_space);\n\t\tduk_substring(thr, -1, 0, 10);  /* clamp to 10 chars */\n\t\tjs_ctx->h_gap = duk_known_hstring(thr, -1);\n\t} else {\n\t\t/* nop */\n\t}\n\n\tif (js_ctx->h_gap != NULL) {\n\t\t/* If gap is empty, behave as if not given at all.  Check\n\t\t * against byte length because character length is more\n\t\t * expensive.\n\t\t */\n\t\tif (DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) == 0) {\n\t\t\tjs_ctx->h_gap = NULL;\n\t\t}\n\t}\n\n\t/* [ ... buf loop (proplist) (gap) ] */\n\n\t/*\n\t *  Fast path: assume no mutation, iterate object property tables\n\t *  directly; bail out if that assumption doesn't hold.\n\t */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\n\tif (js_ctx->h_replacer == NULL &&  /* replacer is a mutation risk */\n\t    js_ctx->idx_proplist == -1) {  /* proplist is very rare */\n\t\tduk_int_t pcall_rc;\n\t\tduk_small_uint_t prev_ms_base_flags;\n\n\t\tDUK_DD(DUK_DDPRINT(\"try JSON.stringify() fast path\"));\n\n\t\t/* Use recursion_limit to ensure we don't overwrite js_ctx->visiting[]\n\t\t * array so we don't need two counter checks in the fast path.  The\n\t\t * slow path has a much larger recursion limit which we'll use if\n\t\t * necessary.\n\t\t */\n\t\tDUK_ASSERT(DUK_USE_JSON_ENC_RECLIMIT >= DUK_JSON_ENC_LOOPARRAY);\n\t\tjs_ctx->recursion_limit = DUK_JSON_ENC_LOOPARRAY;\n\t\tDUK_ASSERT(js_ctx->recursion_depth == 0);\n\n\t\t/* Execute the fast path in a protected call.  If any error is thrown,\n\t\t * fall back to the slow path.  This includes e.g. recursion limit\n\t\t * because the fast path has a smaller recursion limit (and simpler,\n\t\t * limited loop detection).\n\t\t */\n\n\t\tduk_dup(thr, idx_value);\n\n\t\t/* Must prevent finalizers which may have arbitrary side effects. */\n\t\tprev_ms_base_flags = thr->heap->ms_base_flags;\n\t\tthr->heap->ms_base_flags |=\n\t\t        DUK_MS_FLAG_NO_OBJECT_COMPACTION;      /* Avoid attempt to compact any objects. */\n\t\tthr->heap->pf_prevent_count++;                 /* Prevent finalizers. */\n\t\tDUK_ASSERT(thr->heap->pf_prevent_count != 0);  /* Wrap. */\n\n\t\tpcall_rc = duk_safe_call(thr, duk__json_stringify_fast, (void *) js_ctx /*udata*/, 1 /*nargs*/, 0 /*nret*/);\n\n\t\tDUK_ASSERT(thr->heap->pf_prevent_count > 0);\n\t\tthr->heap->pf_prevent_count--;\n\t\tthr->heap->ms_base_flags = prev_ms_base_flags;\n\n\t\tif (pcall_rc == DUK_EXEC_SUCCESS) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"fast path successful\"));\n\t\t\tDUK_BW_PUSH_AS_STRING(thr, &js_ctx->bw);\n\t\t\tgoto replace_finished;\n\t\t}\n\n\t\t/* We come here for actual aborts (like encountering .toJSON())\n\t\t * but also for recursion/loop errors.  Bufwriter size can be\n\t\t * kept because we'll probably need at least as much as we've\n\t\t * allocated so far.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"fast path failed, serialize using slow path instead\"));\n\t\tDUK_BW_RESET_SIZE(thr, &js_ctx->bw);\n\t\tjs_ctx->recursion_depth = 0;\n\t}\n#endif\n\n\t/*\n\t *  Create wrapper object and serialize\n\t */\n\n\tidx_holder = duk_push_object(thr);\n\tduk_dup(thr, idx_value);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_EMPTY_STRING);\n\n\tDUK_DDD(DUK_DDDPRINT(\"before: flags=0x%08lx, loop=%!T, replacer=%!O, \"\n\t                     \"proplist=%!T, gap=%!O, holder=%!T\",\n\t                     (unsigned long) js_ctx->flags,\n\t                     (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop),\n\t                     (duk_heaphdr *) js_ctx->h_replacer,\n\t                     (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(thr, js_ctx->idx_proplist) : NULL),\n\t                     (duk_heaphdr *) js_ctx->h_gap,\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* serialize the wrapper with empty string key */\n\n\tduk_push_hstring_empty(thr);\n\n\t/* [ ... buf loop (proplist) (gap) holder \"\" ] */\n\n\tjs_ctx->recursion_limit = DUK_USE_JSON_ENC_RECLIMIT;\n\tDUK_ASSERT(js_ctx->recursion_depth == 0);\n\n\tif (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_holder) == 0)) {  /* [ ... holder key ] -> [ ... holder ] */\n\t\t/* Result is undefined. */\n\t\tduk_push_undefined(thr);\n\t} else {\n\t\t/* Convert buffer to result string. */\n\t\tDUK_BW_PUSH_AS_STRING(thr, &js_ctx->bw);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"after: flags=0x%08lx, loop=%!T, replacer=%!O, \"\n\t                     \"proplist=%!T, gap=%!O, holder=%!T\",\n\t                     (unsigned long) js_ctx->flags,\n\t                     (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop),\n\t                     (duk_heaphdr *) js_ctx->h_replacer,\n\t                     (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(thr, js_ctx->idx_proplist) : NULL),\n\t                     (duk_heaphdr *) js_ctx->h_gap,\n\t                     (duk_tval *) duk_get_tval(thr, idx_holder)));\n\n\t/* The stack has a variable shape here, so force it to the\n\t * desired one explicitly.\n\t */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\n replace_finished:\n#endif\n\tduk_replace(thr, entry_top);\n\tduk_set_top(thr, entry_top + 1);\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON stringify end: value=%!T, replacer=%!T, space=%!T, \"\n\t                     \"flags=0x%08lx, result=%!T, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_replacer),\n\t                     (duk_tval *) duk_get_tval(thr, idx_space),\n\t                     (unsigned long) flags,\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (long) duk_get_top(thr)));\n\n\tDUK_ASSERT(duk_get_top(thr) == entry_top + 1);\n}\n\n#if defined(DUK_USE_JSON_BUILTIN)\n\n/*\n *  Entry points\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_json_object_parse(duk_hthread *thr) {\n\tduk_bi_json_parse_helper(thr,\n\t                         0 /*idx_value*/,\n\t                         1 /*idx_replacer*/,\n\t                         0 /*flags*/);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_json_object_stringify(duk_hthread *thr) {\n\tduk_bi_json_stringify_helper(thr,\n\t                             0 /*idx_value*/,\n\t                             1 /*idx_replacer*/,\n\t                             2 /*idx_space*/,\n\t                             0 /*flags*/);\n\treturn 1;\n}\n\n#endif  /* DUK_USE_JSON_BUILTIN */\n\n#endif  /* DUK_USE_JSON_SUPPORT */\n\n/* automatic undefs */\n#undef DUK__EMIT_1\n#undef DUK__EMIT_2\n#undef DUK__EMIT_CSTR\n#undef DUK__EMIT_HSTR\n#undef DUK__EMIT_STRIDX\n#undef DUK__JSON_DECSTR_BUFSIZE\n#undef DUK__JSON_DECSTR_CHUNKSIZE\n#undef DUK__JSON_ENCSTR_CHUNKSIZE\n#undef DUK__JSON_MAX_ESC_LEN\n#undef DUK__JSON_STRINGIFY_BUFSIZE\n#undef DUK__MKESC\n#undef DUK__UNEMIT_1\n/*\n *  Math built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_MATH_BUILTIN)\n\n/*\n *  Use static helpers which can work with math.h functions matching\n *  the following signatures. This is not portable if any of these math\n *  functions is actually a macro.\n *\n *  Typing here is intentionally 'double' wherever values interact with\n *  the standard library APIs.\n */\n\ntypedef double (*duk__one_arg_func)(double);\ntypedef double (*duk__two_arg_func)(double, double);\n\nDUK_LOCAL duk_ret_t duk__math_minmax(duk_hthread *thr, duk_double_t initial, duk__two_arg_func min_max) {\n\tduk_idx_t n = duk_get_top(thr);\n\tduk_idx_t i;\n\tduk_double_t res = initial;\n\tduk_double_t t;\n\n\t/*\n\t *  Note: fmax() does not match the E5 semantics.  E5 requires\n\t *  that if -any- input to Math.max() is a NaN, the result is a\n\t *  NaN.  fmax() will return a NaN only if -both- inputs are NaN.\n\t *  Same applies to fmin().\n\t *\n\t *  Note: every input value must be coerced with ToNumber(), even\n\t *  if we know the result will be a NaN anyway: ToNumber() may have\n\t *  side effects for which even order of evaluation matters.\n\t */\n\n\tfor (i = 0; i < n; i++) {\n\t\tt = duk_to_number(thr, i);\n\t\tif (DUK_FPCLASSIFY(t) == DUK_FP_NAN || DUK_FPCLASSIFY(res) == DUK_FP_NAN) {\n\t\t\t/* Note: not normalized, but duk_push_number() will normalize */\n\t\t\tres = (duk_double_t) DUK_DOUBLE_NAN;\n\t\t} else {\n\t\t\tres = (duk_double_t) min_max(res, (double) t);\n\t\t}\n\t}\n\n\tduk_push_number(thr, res);\n\treturn 1;\n}\n\nDUK_LOCAL double duk__fmin_fixed(double x, double y) {\n\t/* fmin() with args -0 and +0 is not guaranteed to return\n\t * -0 as ECMAScript requires.\n\t */\n\tif (x == 0 && y == 0) {\n\t\tduk_double_union du1, du2;\n\t\tdu1.d = x;\n\t\tdu2.d = y;\n\n\t\t/* Already checked to be zero so these must hold, and allow us\n\t\t * to check for \"x is -0 or y is -0\" by ORing the high parts\n\t\t * for comparison.\n\t\t */\n\t\tDUK_ASSERT(du1.ui[DUK_DBL_IDX_UI0] == 0 || du1.ui[DUK_DBL_IDX_UI0] == 0x80000000UL);\n\t\tDUK_ASSERT(du2.ui[DUK_DBL_IDX_UI0] == 0 || du2.ui[DUK_DBL_IDX_UI0] == 0x80000000UL);\n\n\t\t/* XXX: what's the safest way of creating a negative zero? */\n\t\tif ((du1.ui[DUK_DBL_IDX_UI0] | du2.ui[DUK_DBL_IDX_UI0]) != 0) {\n\t\t\t/* Enter here if either x or y (or both) is -0. */\n\t\t\treturn -0.0;\n\t\t} else {\n\t\t\treturn +0.0;\n\t\t}\n\t}\n\treturn duk_double_fmin(x, y);\n}\n\nDUK_LOCAL double duk__fmax_fixed(double x, double y) {\n\t/* fmax() with args -0 and +0 is not guaranteed to return\n\t * +0 as ECMAScript requires.\n\t */\n\tif (x == 0 && y == 0) {\n\t\tif (DUK_SIGNBIT(x) == 0 || DUK_SIGNBIT(y) == 0) {\n\t\t\treturn +0.0;\n\t\t} else {\n\t\t\treturn -0.0;\n\t\t}\n\t}\n\treturn duk_double_fmax(x, y);\n}\n\n#if defined(DUK_USE_ES6)\nDUK_LOCAL double duk__cbrt(double x) {\n\t/* cbrt() is C99.  To avoid hassling embedders with the need to provide a\n\t * cube root function, we can get by with pow().  The result is not\n\t * identical, but that's OK: ES2015 says it's implementation-dependent.\n\t */\n\n#if defined(DUK_CBRT)\n\t/* cbrt() matches ES2015 requirements. */\n\treturn DUK_CBRT(x);\n#else\n\tduk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\n\t/* pow() does not, however. */\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE || c == DUK_FP_ZERO) {\n\t\treturn x;\n\t}\n\tif (DUK_SIGNBIT(x)) {\n\t\treturn -DUK_POW(-x, 1.0 / 3.0);\n\t} else {\n\t\treturn DUK_POW(x, 1.0 / 3.0);\n\t}\n#endif\n}\n\nDUK_LOCAL double duk__log2(double x) {\n#if defined(DUK_LOG2)\n\treturn DUK_LOG2(x);\n#else\n\treturn DUK_LOG(x) * DUK_DOUBLE_LOG2E;\n#endif\n}\n\nDUK_LOCAL double duk__log10(double x) {\n#if defined(DUK_LOG10)\n\treturn DUK_LOG10(x);\n#else\n\treturn DUK_LOG(x) * DUK_DOUBLE_LOG10E;\n#endif\n}\n\nDUK_LOCAL double duk__trunc(double x) {\n#if defined(DUK_TRUNC)\n\treturn DUK_TRUNC(x);\n#else\n\t/* Handles -0 correctly: -0.0 matches 'x >= 0.0' but floor()\n\t * is required to return -0 when the argument is -0.\n\t */\n\treturn x >= 0.0 ? DUK_FLOOR(x) : DUK_CEIL(x);\n#endif\n}\n#endif  /* DUK_USE_ES6 */\n\nDUK_LOCAL double duk__round_fixed(double x) {\n\t/* Numbers half-way between integers must be rounded towards +Infinity,\n\t * e.g. -3.5 must be rounded to -3 (not -4).  When rounded to zero, zero\n\t * sign must be set appropriately.  E5.1 Section 15.8.2.15.\n\t *\n\t * Note that ANSI C round() is \"round to nearest integer, away from zero\",\n\t * which is incorrect for negative values.  Here we make do with floor().\n\t */\n\n\tduk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE || c == DUK_FP_ZERO) {\n\t\treturn x;\n\t}\n\n\t/*\n\t *  x is finite and non-zero\n\t *\n\t *  -1.6 -> floor(-1.1) -> -2\n\t *  -1.5 -> floor(-1.0) -> -1  (towards +Inf)\n\t *  -1.4 -> floor(-0.9) -> -1\n\t *  -0.5 -> -0.0               (special case)\n\t *  -0.1 -> -0.0               (special case)\n\t *  +0.1 -> +0.0               (special case)\n\t *  +0.5 -> floor(+1.0) -> 1   (towards +Inf)\n\t *  +1.4 -> floor(+1.9) -> 1\n\t *  +1.5 -> floor(+2.0) -> 2   (towards +Inf)\n\t *  +1.6 -> floor(+2.1) -> 2\n\t */\n\n\tif (x >= -0.5 && x < 0.5) {\n\t\t/* +0.5 is handled by floor, this is on purpose */\n\t\tif (x < 0.0) {\n\t\t\treturn -0.0;\n\t\t} else {\n\t\t\treturn +0.0;\n\t\t}\n\t}\n\n\treturn DUK_FLOOR(x + 0.5);\n}\n\n/* Wrappers for calling standard math library methods.  These may be required\n * on platforms where one or more of the math built-ins are defined as macros\n * or inline functions and are thus not suitable to be used as function pointers.\n */\n#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)\nDUK_LOCAL double duk__fabs(double x) {\n\treturn DUK_FABS(x);\n}\nDUK_LOCAL double duk__acos(double x) {\n\treturn DUK_ACOS(x);\n}\nDUK_LOCAL double duk__asin(double x) {\n\treturn DUK_ASIN(x);\n}\nDUK_LOCAL double duk__atan(double x) {\n\treturn DUK_ATAN(x);\n}\nDUK_LOCAL double duk__ceil(double x) {\n\treturn DUK_CEIL(x);\n}\nDUK_LOCAL double duk__cos(double x) {\n\treturn DUK_COS(x);\n}\nDUK_LOCAL double duk__exp(double x) {\n\treturn DUK_EXP(x);\n}\nDUK_LOCAL double duk__floor(double x) {\n\treturn DUK_FLOOR(x);\n}\nDUK_LOCAL double duk__log(double x) {\n\treturn DUK_LOG(x);\n}\nDUK_LOCAL double duk__sin(double x) {\n\treturn DUK_SIN(x);\n}\nDUK_LOCAL double duk__sqrt(double x) {\n\treturn DUK_SQRT(x);\n}\nDUK_LOCAL double duk__tan(double x) {\n\treturn DUK_TAN(x);\n}\nDUK_LOCAL double duk__atan2_fixed(double x, double y) {\n#if defined(DUK_USE_ATAN2_WORKAROUNDS)\n\t/* Specific fixes to common atan2() implementation issues:\n\t * - test-bug-mingw-math-issues.js\n\t */\n\tif (DUK_ISINF(x) && DUK_ISINF(y)) {\n\t\tif (DUK_SIGNBIT(x)) {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn -2.356194490192345;\n\t\t\t} else {\n\t\t\t\treturn -0.7853981633974483;\n\t\t\t}\n\t\t} else {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn 2.356194490192345;\n\t\t\t} else {\n\t\t\t\treturn 0.7853981633974483;\n\t\t\t}\n\t\t}\n\t}\n#else\n\t/* Some ISO C assumptions. */\n\tDUK_ASSERT(DUK_ATAN2(DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY) == 0.7853981633974483);\n\tDUK_ASSERT(DUK_ATAN2(-DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY) == -0.7853981633974483);\n\tDUK_ASSERT(DUK_ATAN2(DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY) == 2.356194490192345);\n\tDUK_ASSERT(DUK_ATAN2(-DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY) == -2.356194490192345);\n#endif\n\n\treturn DUK_ATAN2(x, y);\n}\n#endif  /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */\n\n/* order must match constants in genbuiltins.py */\nDUK_LOCAL const duk__one_arg_func duk__one_arg_funcs[] = {\n#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)\n\tduk__fabs,\n\tduk__acos,\n\tduk__asin,\n\tduk__atan,\n\tduk__ceil,\n\tduk__cos,\n\tduk__exp,\n\tduk__floor,\n\tduk__log,\n\tduk__round_fixed,\n\tduk__sin,\n\tduk__sqrt,\n\tduk__tan,\n#if defined(DUK_USE_ES6)\n\tduk__cbrt,\n\tduk__log2,\n\tduk__log10,\n\tduk__trunc\n#endif\n#else  /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */\n\tDUK_FABS,\n\tDUK_ACOS,\n\tDUK_ASIN,\n\tDUK_ATAN,\n\tDUK_CEIL,\n\tDUK_COS,\n\tDUK_EXP,\n\tDUK_FLOOR,\n\tDUK_LOG,\n\tduk__round_fixed,\n\tDUK_SIN,\n\tDUK_SQRT,\n\tDUK_TAN,\n#if defined(DUK_USE_ES6)\n\tduk__cbrt,\n\tduk__log2,\n\tduk__log10,\n\tduk__trunc\n#endif\n#endif  /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */\n};\n\n/* order must match constants in genbuiltins.py */\nDUK_LOCAL const duk__two_arg_func duk__two_arg_funcs[] = {\n#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)\n\tduk__atan2_fixed,\n\tduk_js_arith_pow\n#else\n\tduk__atan2_fixed,\n\tduk_js_arith_pow\n#endif\n};\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_onearg_shared(duk_hthread *thr) {\n\tduk_small_int_t fun_idx = duk_get_current_magic(thr);\n\tduk__one_arg_func fun;\n\tduk_double_t arg1;\n\n\tDUK_ASSERT(fun_idx >= 0);\n\tDUK_ASSERT(fun_idx < (duk_small_int_t) (sizeof(duk__one_arg_funcs) / sizeof(duk__one_arg_func)));\n\targ1 = duk_to_number(thr, 0);\n\tfun = duk__one_arg_funcs[fun_idx];\n\tduk_push_number(thr, (duk_double_t) fun((double) arg1));\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_twoarg_shared(duk_hthread *thr) {\n\tduk_small_int_t fun_idx = duk_get_current_magic(thr);\n\tduk__two_arg_func fun;\n\tduk_double_t arg1;\n\tduk_double_t arg2;\n\n\tDUK_ASSERT(fun_idx >= 0);\n\tDUK_ASSERT(fun_idx < (duk_small_int_t) (sizeof(duk__two_arg_funcs) / sizeof(duk__two_arg_func)));\n\targ1 = duk_to_number(thr, 0);  /* explicit ordered evaluation to match coercion semantics */\n\targ2 = duk_to_number(thr, 1);\n\tfun = duk__two_arg_funcs[fun_idx];\n\tduk_push_number(thr, (duk_double_t) fun((double) arg1, (double) arg2));\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_max(duk_hthread *thr) {\n\treturn duk__math_minmax(thr, -DUK_DOUBLE_INFINITY, duk__fmax_fixed);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_min(duk_hthread *thr) {\n\treturn duk__math_minmax(thr, DUK_DOUBLE_INFINITY, duk__fmin_fixed);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_random(duk_hthread *thr) {\n\tduk_push_number(thr, (duk_double_t) DUK_UTIL_GET_RANDOM_DOUBLE(thr));\n\treturn 1;\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_hypot(duk_hthread *thr) {\n\t/*\n\t *  E6 Section 20.2.2.18: Math.hypot\n\t *\n\t *  - If no arguments are passed, the result is +0.\n\t *  - If any argument is +inf, the result is +inf.\n\t *  - If any argument is -inf, the result is +inf.\n\t *  - If no argument is +inf or -inf, and any argument is NaN, the result is\n\t *    NaN.\n\t *  - If all arguments are either +0 or -0, the result is +0.\n\t */\n\n\tduk_idx_t nargs;\n\tduk_idx_t i;\n\tduk_bool_t found_nan;\n\tduk_double_t max;\n\tduk_double_t sum, summand;\n\tduk_double_t comp, prelim;\n\tduk_double_t t;\n\n\tnargs = duk_get_top(thr);\n\n\t/* Find the highest value.  Also ToNumber() coerces. */\n\tmax = 0.0;\n\tfound_nan = 0;\n\tfor (i = 0; i < nargs; i++) {\n\t\tt = DUK_FABS(duk_to_number(thr, i));\n\t\tif (DUK_FPCLASSIFY(t) == DUK_FP_NAN) {\n\t\t\tfound_nan = 1;\n\t\t} else {\n\t\t\tmax = duk_double_fmax(max, t);\n\t\t}\n\t}\n\n\t/* Early return cases. */\n\tif (max == DUK_DOUBLE_INFINITY) {\n\t\tduk_push_number(thr, DUK_DOUBLE_INFINITY);\n\t\treturn 1;\n\t} else if (found_nan) {\n\t\tduk_push_number(thr, DUK_DOUBLE_NAN);\n\t\treturn 1;\n\t} else if (max == 0.0) {\n\t\tduk_push_number(thr, 0.0);\n\t\t/* Otherwise we'd divide by zero. */\n\t\treturn 1;\n\t}\n\n\t/* Use Kahan summation and normalize to the highest value to minimize\n\t * floating point rounding error and avoid overflow.\n\t *\n\t * https://en.wikipedia.org/wiki/Kahan_summation_algorithm\n\t */\n\tsum = 0.0;\n\tcomp = 0.0;\n\tfor (i = 0; i < nargs; i++) {\n\t\tt = DUK_FABS(duk_get_number(thr, i)) / max;\n\t\tsummand = (t * t) - comp;\n\t\tprelim = sum + summand;\n\t\tcomp = (prelim - sum) - summand;\n\t\tsum = prelim;\n\t}\n\n\tduk_push_number(thr, (duk_double_t) DUK_SQRT(sum) * max);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_sign(duk_hthread *thr) {\n\tduk_double_t d;\n\n\td = duk_to_number(thr, 0);\n\tif (duk_double_is_nan(d)) {\n\t\tDUK_ASSERT(duk_is_nan(thr, -1));\n\t\treturn 1;  /* NaN input -> return NaN */\n\t}\n\tif (d == 0.0) {\n\t\t/* Zero sign kept, i.e. -0 -> -0, +0 -> +0. */\n\t\treturn 1;\n\t}\n\tduk_push_int(thr, (d > 0.0 ? 1 : -1));\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_clz32(duk_hthread *thr) {\n\tduk_uint32_t x;\n\tduk_small_uint_t i;\n\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_uint32_t mask;\n\n\tx = duk_to_uint32(thr, 0);\n\tfor (i = 0, mask = 0x80000000UL; mask != 0; mask >>= 1) {\n\t\tif (x & mask) {\n\t\t\tbreak;\n\t\t}\n\t\ti++;\n\t}\n\tDUK_ASSERT(i <= 32);\n\tduk_push_uint(thr, i);\n\treturn 1;\n#else  /* DUK_USE_PREFER_SIZE */\n\ti = 0;\n\tx = duk_to_uint32(thr, 0);\n\tif (x & 0xffff0000UL) {\n\t\tx >>= 16;\n\t} else {\n\t\ti += 16;\n\t}\n\tif (x & 0x0000ff00UL) {\n\t\tx >>= 8;\n\t} else {\n\t\ti += 8;\n\t}\n\tif (x & 0x000000f0UL) {\n\t\tx >>= 4;\n\t} else {\n\t\ti += 4;\n\t}\n\tif (x & 0x0000000cUL) {\n\t\tx >>= 2;\n\t} else {\n\t\ti += 2;\n\t}\n\tif (x & 0x00000002UL) {\n\t\tx >>= 1;\n\t} else {\n\t\ti += 1;\n\t}\n\tif (x & 0x00000001UL) {\n\t\t;\n\t} else {\n\t\ti += 1;\n\t}\n\tDUK_ASSERT(i <= 32);\n\tduk_push_uint(thr, i);\n\treturn 1;\n#endif  /* DUK_USE_PREFER_SIZE */\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_imul(duk_hthread *thr) {\n\tduk_uint32_t x, y, z;\n\n\tx = duk_to_uint32(thr, 0);\n\ty = duk_to_uint32(thr, 1);\n\tz = x * y;\n\n\t/* While arguments are ToUint32() coerced and the multiplication\n\t * is unsigned as such, the final result is curiously interpreted\n\t * as a signed 32-bit value.\n\t */\n\tduk_push_i32(thr, (duk_int32_t) z);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#endif  /* DUK_USE_MATH_BUILTIN */\n/*\n *  Number built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_NUMBER_BUILTIN)\n\nDUK_LOCAL duk_double_t duk__push_this_number_plain(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\t/* Number built-in accepts a plain number or a Number object (whose\n\t * internal value is operated on).  Other types cause TypeError.\n\t */\n\n\tduk_push_this(thr);\n\tif (duk_is_number(thr, -1)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"plain number value: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\t\tgoto done;\n\t}\n\th = duk_get_hobject(thr, -1);\n\tif (!h ||\n\t    (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_NUMBER)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"unacceptable this value: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\t\tDUK_ERROR_TYPE(thr, \"number expected\");\n\t\tDUK_WO_NORETURN(return 0.0;);\n\t}\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\tDUK_DDD(DUK_DDDPRINT(\"number object: %!T, internal value: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_remove_m2(thr);\n\n done:\n\treturn duk_get_number(thr, -1);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_constructor(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_hobject *h_this;\n\n\t/*\n\t *  The Number constructor uses ToNumber(arg) for number coercion\n\t *  (coercing an undefined argument to NaN).  However, if the\n\t *  argument is not given at all, +0 must be used instead.  To do\n\t *  this, a vararg function is used.\n\t */\n\n\tnargs = duk_get_top(thr);\n\tif (nargs == 0) {\n\t\tduk_push_int(thr, 0);\n\t}\n\tduk_to_number(thr, 0);\n\tduk_set_top(thr, 1);\n\tDUK_ASSERT_TOP(thr, 1);\n\n\tif (!duk_is_constructor_call(thr)) {\n\t\treturn 1;\n\t}\n\n\t/*\n\t *  E5 Section 15.7.2.1 requires that the constructed object\n\t *  must have the original Number.prototype as its internal\n\t *  prototype.  However, since Number.prototype is non-writable\n\t *  and non-configurable, this doesn't have to be enforced here:\n\t *  The default object (bound to 'this') is OK, though we have\n\t *  to change its class.\n\t *\n\t *  Internal value set to ToNumber(arg) or +0; if no arg given,\n\t *  ToNumber(undefined) = NaN, so special treatment is needed\n\t *  (above).  String internal value is immutable.\n\t */\n\n\t/* XXX: helper */\n\tduk_push_this(thr);\n\th_this = duk_known_hobject(thr, -1);\n\tDUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_NUMBER);\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE]);\n\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_this) == DUK_HOBJECT_CLASS_NUMBER);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_this));\n\n\tduk_dup_0(thr);  /* -> [ val obj val ] */\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\treturn 0;  /* no return value -> don't replace created value */\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_value_of(duk_hthread *thr) {\n\t(void) duk__push_this_number_plain(thr);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_string(duk_hthread *thr) {\n\tduk_small_int_t radix;\n\tduk_small_uint_t n2s_flags;\n\n\t(void) duk__push_this_number_plain(thr);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tradix = 10;\n\t} else {\n\t\tradix = (duk_small_int_t) duk_to_int_check_range(thr, 0, 2, 36);\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"radix=%ld\", (long) radix));\n\n\tn2s_flags = 0;\n\n\tduk_numconv_stringify(thr,\n\t                      radix /*radix*/,\n\t                      0 /*digits*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_locale_string(duk_hthread *thr) {\n\t/* XXX: just use toString() for now; permitted although not recommended.\n\t * nargs==1, so radix is passed to toString().\n\t */\n\treturn duk_bi_number_prototype_to_string(thr);\n}\n\n/*\n *  toFixed(), toExponential(), toPrecision()\n */\n\n/* XXX: shared helper for toFixed(), toExponential(), toPrecision()? */\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_fixed(duk_hthread *thr) {\n\tduk_small_int_t frac_digits;\n\tduk_double_t d;\n\tduk_small_int_t c;\n\tduk_small_uint_t n2s_flags;\n\n\t/* In ES5.1 frac_digits is coerced first; in ES2015 the 'this number\n\t * value' check is done first.\n\t */\n\td = duk__push_this_number_plain(thr);\n\tfrac_digits = (duk_small_int_t) duk_to_int_check_range(thr, 0, 0, 20);\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\tgoto use_to_string;\n\t}\n\n\tif (d >= 1.0e21 || d <= -1.0e21) {\n\t\tgoto use_to_string;\n\t}\n\n\tn2s_flags = DUK_N2S_FLAG_FIXED_FORMAT |\n\t            DUK_N2S_FLAG_FRACTION_DIGITS;\n\n\tduk_numconv_stringify(thr,\n\t                      10 /*radix*/,\n\t                      frac_digits /*digits*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n\n use_to_string:\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, -1);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_exponential(duk_hthread *thr) {\n\tduk_bool_t frac_undefined;\n\tduk_small_int_t frac_digits;\n\tduk_double_t d;\n\tduk_small_int_t c;\n\tduk_small_uint_t n2s_flags;\n\n\td = duk__push_this_number_plain(thr);\n\n\tfrac_undefined = duk_is_undefined(thr, 0);\n\tduk_to_int(thr, 0);  /* for side effects */\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\tgoto use_to_string;\n\t}\n\n\tfrac_digits = (duk_small_int_t) duk_to_int_check_range(thr, 0, 0, 20);\n\n\tn2s_flags = DUK_N2S_FLAG_FORCE_EXP |\n\t           (frac_undefined ? 0 : DUK_N2S_FLAG_FIXED_FORMAT);\n\n\tduk_numconv_stringify(thr,\n\t                      10 /*radix*/,\n\t                      frac_digits + 1 /*leading digit + fractions*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n\n use_to_string:\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, -1);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_precision(duk_hthread *thr) {\n\t/* The specification has quite awkward order of coercion and\n\t * checks for toPrecision().  The operations below are a bit\n\t * reordered, within constraints of observable side effects.\n\t */\n\n\tduk_double_t d;\n\tduk_small_int_t prec;\n\tduk_small_int_t c;\n\tduk_small_uint_t n2s_flags;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\n\td = duk__push_this_number_plain(thr);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tgoto use_to_string;\n\t}\n\tDUK_ASSERT_TOP(thr, 2);\n\n\tduk_to_int(thr, 0);  /* for side effects */\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\tgoto use_to_string;\n\t}\n\n\tprec = (duk_small_int_t) duk_to_int_check_range(thr, 0, 1, 21);\n\n\tn2s_flags = DUK_N2S_FLAG_FIXED_FORMAT |\n\t            DUK_N2S_FLAG_NO_ZERO_PAD;\n\n\tduk_numconv_stringify(thr,\n\t                      10 /*radix*/,\n\t                      prec /*digits*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n\n use_to_string:\n\t/* Used when precision is undefined; also used for NaN (-> \"NaN\"),\n\t * and +/- infinity (-> \"Infinity\", \"-Infinity\").\n\t */\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, -1);\n\treturn 1;\n}\n\n/*\n *  ES2015 isFinite() etc\n */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_number_check_shared(duk_hthread *thr) {\n\tduk_int_t magic;\n\tduk_bool_t ret = 0;\n\n\tif (duk_is_number(thr, 0)) {\n\t\tduk_double_t d;\n\n\t\tmagic = duk_get_current_magic(thr);\n\t\td = duk_get_number(thr, 0);\n\n\t\tswitch (magic) {\n\t\tcase 0:  /* isFinite() */\n\t\t\tret = duk_double_is_finite(d);\n\t\t\tbreak;\n\t\tcase 1:  /* isInteger() */\n\t\t\tret = duk_double_is_integer(d);\n\t\t\tbreak;\n\t\tcase 2:  /* isNaN() */\n\t\t\tret = duk_double_is_nan(d);\n\t\t\tbreak;\n\t\tdefault:  /* isSafeInteger() */\n\t\t\tDUK_ASSERT(magic == 3);\n\t\t\tret = duk_double_is_safe_integer(d);\n\t\t}\n\t}\n\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#endif  /* DUK_USE_NUMBER_BUILTIN */\n/*\n *  Object built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Needed even when Object built-in disabled. */\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_string(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\ttv = DUK_HTHREAD_THIS_PTR(thr);\n\tduk_push_class_string_tval(thr, tv, 0 /*avoid_side_effects*/);\n\treturn 1;\n}\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor(duk_hthread *thr) {\n\tduk_uint_t arg_mask;\n\n\targ_mask = duk_get_type_mask(thr, 0);\n\n\tif (!duk_is_constructor_call(thr) &&  /* not a constructor call */\n\t    ((arg_mask & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED)) == 0)) {  /* and argument not null or undefined */\n\t\tduk_to_object(thr, 0);\n\t\treturn 1;\n\t}\n\n\t/* Pointer and buffer primitive values are treated like other\n\t * primitives values which have a fully fledged object counterpart:\n\t * promote to an object value.  Lightfuncs and plain buffers are\n\t * coerced with ToObject() even they could also be returned as is.\n\t */\n\tif (arg_mask & (DUK_TYPE_MASK_OBJECT |\n\t                DUK_TYPE_MASK_STRING |\n\t                DUK_TYPE_MASK_BOOLEAN |\n\t                DUK_TYPE_MASK_NUMBER |\n\t                DUK_TYPE_MASK_POINTER |\n\t                DUK_TYPE_MASK_BUFFER |\n\t                DUK_TYPE_MASK_LIGHTFUNC)) {\n\t\t/* For DUK_TYPE_OBJECT the coercion is a no-op and could\n\t\t * be checked for explicitly, but Object(obj) calls are\n\t\t * not very common so opt for minimal footprint.\n\t\t */\n\t\tduk_to_object(thr, 0);\n\t\treturn 1;\n\t}\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              DUK_BIDX_OBJECT_PROTOTYPE);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) && defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_assign(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_int_t idx;\n\n\tnargs = duk_get_top_require_min(thr, 1 /*min_top*/);\n\n\tduk_to_object(thr, 0);\n\tfor (idx = 1; idx < nargs; idx++) {\n\t\t/* E7 19.1.2.1 (step 4a) */\n\t\tif (duk_is_null_or_undefined(thr, idx)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* duk_enum() respects ES2015+ [[OwnPropertyKeys]] ordering, which is\n\t\t * convenient here.\n\t\t */\n\t\tduk_to_object(thr, idx);\n\t\tduk_enum(thr, idx, DUK_ENUM_OWN_PROPERTIES_ONLY);\n\t\twhile (duk_next(thr, -1, 1 /*get_value*/)) {\n\t\t\t/* [ target ... enum key value ] */\n\t\t\tduk_put_prop(thr, 0);\n\t\t\t/* [ target ... enum ] */\n\t\t}\n\t\t/* Could pop enumerator, but unnecessary because of duk_set_top()\n\t\t * below.\n\t\t */\n\t}\n\n\tduk_set_top(thr, 1);\n\treturn 1;\n}\n#endif\n\n#if defined(DUK_USE_OBJECT_BUILTIN) && defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_is(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_push_boolean(thr, duk_samevalue(thr, 0, 1));\n\treturn 1;\n}\n#endif\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_create(duk_hthread *thr) {\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tduk_hbufobj_promote_plain(thr, 0);\n#endif\n\tproto = duk_require_hobject_accept_mask(thr, 0, DUK_TYPE_MASK_NULL);\n\tDUK_ASSERT(proto != NULL || duk_is_null(thr, 0));\n\n\t(void) duk_push_object_helper_proto(thr,\n\t                                    DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                    DUK_HOBJECT_FLAG_FASTREFS |\n\t                                    DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                                    proto);\n\n\tif (!duk_is_undefined(thr, 1)) {\n\t\t/* [ O Properties obj ] */\n\n\t\tduk_replace(thr, 0);\n\n\t\t/* [ obj Properties ] */\n\n\t\t/* Just call the \"original\" Object.defineProperties() to\n\t\t * finish up.\n\t\t */\n\n\t\treturn duk_bi_object_constructor_define_properties(thr);\n\t}\n\n\t/* [ O Properties obj ] */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_hthread *thr) {\n\tduk_small_uint_t pass;\n\tduk_uint_t defprop_flags;\n\tduk_hobject *obj;\n\tduk_idx_t idx_value;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\n\t/* Lightfunc and plain buffer handling by ToObject() coercion. */\n\tobj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(obj != NULL);\n\n\tduk_to_object(thr, 1);        /* properties object */\n\n\tDUK_DDD(DUK_DDDPRINT(\"target=%!iT, properties=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\n\t/*\n\t *  Two pass approach to processing the property descriptors.\n\t *  On first pass validate and normalize all descriptors before\n\t *  any changes are made to the target object.  On second pass\n\t *  make the actual modifications to the target object.\n\t *\n\t *  Right now we'll just use the same normalize/validate helper\n\t *  on both passes, ignoring its outputs on the first pass.\n\t */\n\n\tfor (pass = 0; pass < 2; pass++) {\n\t\tduk_set_top(thr, 2);  /* -> [ hobject props ] */\n\t\tduk_enum(thr, 1, DUK_ENUM_OWN_PROPERTIES_ONLY | DUK_ENUM_INCLUDE_SYMBOLS /*enum_flags*/);\n\n\t\tfor (;;) {\n\t\t\tduk_hstring *key;\n\n\t\t\t/* [ hobject props enum(props) ] */\n\n\t\t\tduk_set_top(thr, 3);\n\n\t\t\tif (!duk_next(thr, 2, 1 /*get_value*/)) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> key=%!iT, desc=%!iT\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t/* [ hobject props enum(props) key desc ] */\n\n\t\t\tduk_hobject_prepare_property_descriptor(thr,\n\t\t\t                                        4 /*idx_desc*/,\n\t\t\t                                        &defprop_flags,\n\t\t\t                                        &idx_value,\n\t\t\t                                        &get,\n\t\t\t                                        &set);\n\n\t\t\t/* [ hobject props enum(props) key desc [multiple values] ] */\n\n\t\t\tif (pass == 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* This allows symbols on purpose. */\n\t\t\tkey = duk_known_hstring(thr, 3);\n\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\tduk_hobject_define_property_helper(thr,\n\t\t\t                                   defprop_flags,\n\t\t\t                                   obj,\n\t\t\t                                   key,\n\t\t\t                                   idx_value,\n\t\t\t                                   get,\n\t\t\t                                   set,\n\t\t\t                                   1 /*throw_flag*/);\n\t\t}\n\t}\n\n\t/*\n\t *  Return target object\n\t */\n\n\tduk_dup_0(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_seal_freeze_shared(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 1);\n\n\tduk_seal_freeze_raw(thr, 0, (duk_bool_t) duk_get_current_magic(thr) /*is_freeze*/);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_sealed_frozen_shared(duk_hthread *thr) {\n\tduk_hobject *h;\n\tduk_bool_t is_frozen;\n\tduk_uint_t mask;\n\n\tis_frozen = (duk_bool_t) duk_get_current_magic(thr);\n\tmask = duk_get_type_mask(thr, 0);\n\tif (mask & (DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER)) {\n\t\tDUK_ASSERT(is_frozen == 0 || is_frozen == 1);\n\t\tduk_push_boolean(thr, (mask & DUK_TYPE_MASK_LIGHTFUNC) ?\n\t\t                          1 :               /* lightfunc always frozen and sealed */\n\t\t                          (is_frozen ^ 1)); /* buffer sealed but not frozen (index props writable) */\n\t} else {\n\t\t/* ES2015 Sections 19.1.2.12, 19.1.2.13: anything other than an object\n\t\t * is considered to be already sealed and frozen.\n\t\t */\n\t\th = duk_get_hobject(thr, 0);\n\t\tduk_push_boolean(thr, (h == NULL) ||\n\t\t                      duk_hobject_object_is_sealed_frozen_helper(thr, h, is_frozen /*is_frozen*/));\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_locale_string(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 0);\n\t(void) duk_push_this_coercible_to_object(thr);\n\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_TO_STRING);\n#if 0  /* This is mentioned explicitly in the E5.1 spec, but duk_call_method() checks for it in practice. */\n\tduk_require_callable(thr, 1);\n#endif\n\tduk_dup_0(thr);  /* -> [ O toString O ] */\n\tduk_call_method(thr, 0);  /* XXX: call method tail call? */\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_value_of(duk_hthread *thr) {\n\t/* For lightfuncs and plain buffers, returns Object() coerced. */\n\t(void) duk_push_this_coercible_to_object(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_hthread *thr) {\n\tduk_hobject *h_v;\n\tduk_hobject *h_obj;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\n\th_v = duk_get_hobject(thr, 0);\n\tif (!h_v) {\n\t\tduk_push_false(thr);  /* XXX: tail call: return duk_push_false(thr) */\n\t\treturn 1;\n\t}\n\n\th_obj = duk_push_this_coercible_to_object(thr);\n\tDUK_ASSERT(h_obj != NULL);\n\n\t/* E5.1 Section 15.2.4.6, step 3.a, lookup proto once before compare.\n\t * Prototype loops should cause an error to be thrown.\n\t */\n\tduk_push_boolean(thr, duk_hobject_prototype_chain_contains(thr, DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_v), h_obj, 0 /*ignore_loop*/));\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_has_own_property(duk_hthread *thr) {\n\treturn (duk_ret_t) duk_hobject_object_ownprop_helper(thr, 0 /*required_desc_flags*/);\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_property_is_enumerable(duk_hthread *thr) {\n\treturn (duk_ret_t) duk_hobject_object_ownprop_helper(thr, DUK_PROPDESC_FLAG_ENUMERABLE /*required_desc_flags*/);\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\n/* Shared helper to implement Object.getPrototypeOf,\n * Object.prototype.__proto__ getter, and Reflect.getPrototypeOf.\n *\n * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-get-object.prototype.__proto__\n */\nDUK_INTERNAL duk_ret_t duk_bi_object_getprototype_shared(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: __proto__ getter\n\t *  magic = 1: Object.getPrototypeOf()\n\t *  magic = 2: Reflect.getPrototypeOf()\n\t */\n\n\tduk_hobject *h;\n\tduk_hobject *proto;\n\tduk_tval *tv;\n\tduk_int_t magic;\n\n\tmagic = duk_get_current_magic(thr);\n\n\tif (magic == 0) {\n\t\tDUK_ASSERT_TOP(thr, 0);\n\t\tduk_push_this_coercible_to_object(thr);\n\t}\n\tDUK_ASSERT(duk_get_top(thr) >= 1);\n\tif (magic < 2) {\n\t\t/* ES2015 Section 19.1.2.9, step 1 */\n\t\tduk_to_object(thr, 0);\n\t}\n\ttv = DUK_GET_TVAL_POSIDX(thr, 0);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_BUFFER:\n\t\tproto = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\tproto = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tproto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t\tbreak;\n\tdefault:\n\t\t/* This implicitly handles CheckObjectCoercible() caused\n\t\t * TypeError.\n\t\t */\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\tif (proto != NULL) {\n\t\tduk_push_hobject(thr, proto);\n\t} else {\n\t\tduk_push_null(thr);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\n/* Shared helper to implement ES2015 Object.setPrototypeOf,\n * Object.prototype.__proto__ setter, and Reflect.setPrototypeOf.\n *\n * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-get-object.prototype.__proto__\n * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.setprototypeof\n */\nDUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: __proto__ setter\n\t *  magic = 1: Object.setPrototypeOf()\n\t *  magic = 2: Reflect.setPrototypeOf()\n\t */\n\n\tduk_hobject *h_obj;\n\tduk_hobject *h_new_proto;\n\tduk_hobject *h_curr;\n\tduk_ret_t ret_success = 1;  /* retval for success path */\n\tduk_uint_t mask;\n\tduk_int_t magic;\n\n\t/* Preliminaries for __proto__ and setPrototypeOf (E6 19.1.2.18 steps 1-4). */\n\tmagic = duk_get_current_magic(thr);\n\tif (magic == 0) {\n\t\tduk_push_this_check_object_coercible(thr);\n\t\tduk_insert(thr, 0);\n\t\tif (!duk_check_type_mask(thr, 1, DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_OBJECT)) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* __proto__ setter returns 'undefined' on success unlike the\n\t\t * setPrototypeOf() call which returns the target object.\n\t\t */\n\t\tret_success = 0;\n\t} else {\n\t\tif (magic == 1) {\n\t\t\tduk_require_object_coercible(thr, 0);\n\t\t} else {\n\t\t\tduk_require_hobject_accept_mask(thr, 0,\n\t\t\t                                DUK_TYPE_MASK_LIGHTFUNC |\n\t\t\t                                DUK_TYPE_MASK_BUFFER);\n\t\t}\n\t\tduk_require_type_mask(thr, 1, DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_OBJECT);\n\t}\n\n\th_new_proto = duk_get_hobject(thr, 1);\n\t/* h_new_proto may be NULL */\n\n\tmask = duk_get_type_mask(thr, 0);\n\tif (mask & (DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER)) {\n\t\tduk_hobject *curr_proto;\n\t\tcurr_proto = thr->builtins[(mask & DUK_TYPE_MASK_LIGHTFUNC) ?\n\t\t                               DUK_BIDX_FUNCTION_PROTOTYPE :\n\t\t                               DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tif (h_new_proto == curr_proto) {\n\t\t\tgoto skip;\n\t\t}\n\t\tgoto fail_nonextensible;\n\t}\n\th_obj = duk_get_hobject(thr, 0);\n\tif (h_obj == NULL) {\n\t\tgoto skip;\n\t}\n\tDUK_ASSERT(h_obj != NULL);\n\n\t/* [[SetPrototypeOf]] standard behavior, E6 9.1.2. */\n\t/* TODO: implement Proxy object support here */\n\n\tif (h_new_proto == DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_obj)) {\n\t\tgoto skip;\n\t}\n\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(h_obj)) {\n\t\tgoto fail_nonextensible;\n\t}\n\tfor (h_curr = h_new_proto; h_curr != NULL; h_curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_curr)) {\n\t\t/* Loop prevention. */\n\t\tif (h_curr == h_obj) {\n\t\t\tgoto fail_loop;\n\t\t}\n\t}\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h_obj, h_new_proto);\n\t/* fall thru */\n\n skip:\n\tduk_set_top(thr, 1);\n\tif (magic == 2) {\n\t\tduk_push_true(thr);\n\t}\n\treturn ret_success;\n\n fail_nonextensible:\n fail_loop:\n\tif (magic != 2) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t} else {\n\t\tduk_push_false(thr);\n\t\treturn 1;\n\t}\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: Object.defineProperty()\n\t *  magic = 1: Reflect.defineProperty()\n\t */\n\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\tduk_idx_t idx_value;\n\tduk_uint_t defprop_flags;\n\tduk_small_uint_t magic;\n\tduk_bool_t throw_flag;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"Object.defineProperty(): ctx=%p obj=%!T key=%!T desc=%!T\",\n\t                     (void *) thr,\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1),\n\t                     (duk_tval *) duk_get_tval(thr, 2)));\n\n\t/* [ obj key desc ] */\n\n\tmagic = (duk_small_uint_t) duk_get_current_magic(thr);\n\n\t/* Lightfuncs are currently supported by coercing to a temporary\n\t * Function object; changes will be allowed (the coerced value is\n\t * extensible) but will be lost.  Same for plain buffers.\n\t */\n\tobj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(obj != NULL);\n\tkey = duk_to_property_key_hstring(thr, 1);\n\t(void) duk_require_hobject(thr, 2);\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(duk_get_hobject(thr, 2) != NULL);\n\n\t/*\n\t *  Validate and convert argument property descriptor (an ECMAScript\n\t *  object) into a set of defprop_flags and possibly property value,\n\t *  getter, and/or setter values on the value stack.\n\t *\n\t *  Lightfunc set/get values are coerced to full Functions.\n\t */\n\n\tduk_hobject_prepare_property_descriptor(thr,\n\t                                        2 /*idx_desc*/,\n\t                                        &defprop_flags,\n\t                                        &idx_value,\n\t                                        &get,\n\t                                        &set);\n\n\t/*\n\t *  Use Object.defineProperty() helper for the actual operation.\n\t */\n\n\tDUK_ASSERT(magic == 0U || magic == 1U);\n\tthrow_flag = magic ^ 1U;\n\tret = duk_hobject_define_property_helper(thr,\n\t                                         defprop_flags,\n\t                                         obj,\n\t                                         key,\n\t                                         idx_value,\n\t                                         get,\n\t                                         set,\n\t                                         throw_flag);\n\n\t/* Ignore the normalize/validate helper outputs on the value stack,\n\t * they're popped automatically.\n\t */\n\n\tif (magic == 0U) {\n\t\t/* Object.defineProperty(): return target object. */\n\t\tduk_push_hobject(thr, obj);\n\t} else {\n\t\t/* Reflect.defineProperty(): return success/fail. */\n\t\tduk_push_boolean(thr, ret);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_get_own_property_descriptor(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 2);\n\n\t/* ES2015 Section 19.1.2.6, step 1 */\n\tif (duk_get_current_magic(thr) == 0) {\n\t\tduk_to_object(thr, 0);\n\t}\n\n\t/* [ obj key ] */\n\n\tduk_hobject_object_get_own_property_descriptor(thr, -2);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_extensible(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: Object.isExtensible()\n\t *  magic = 1: Reflect.isExtensible()\n\t */\n\n\tduk_hobject *h;\n\n\tif (duk_get_current_magic(thr) == 0) {\n\t\th = duk_get_hobject(thr, 0);\n\t} else {\n\t\t/* Reflect.isExtensible(): throw if non-object, but we accept lightfuncs\n\t\t * and plain buffers here because they pretend to be objects.\n\t\t */\n\t\th = duk_require_hobject_accept_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\t}\n\n\tduk_push_boolean(thr, (h != NULL) && DUK_HOBJECT_HAS_EXTENSIBLE(h));\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\n/* Shared helper for various key/symbol listings, magic:\n * 0=Object.keys()\n * 1=Object.getOwnPropertyNames(),\n * 2=Object.getOwnPropertySymbols(),\n * 3=Reflect.ownKeys()\n */\nDUK_LOCAL const duk_small_uint_t duk__object_keys_enum_flags[4] = {\n\t/* Object.keys() */\n\tDUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR,\n\n\t/* Object.getOwnPropertyNames() */\n\tDUK_ENUM_INCLUDE_NONENUMERABLE |\n\t    DUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR,\n\n\t/* Object.getOwnPropertySymbols() */\n\tDUK_ENUM_INCLUDE_SYMBOLS |\n\t    DUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_EXCLUDE_STRINGS |\n\t    DUK_ENUM_INCLUDE_NONENUMERABLE |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR,\n\n\t/* Reflect.ownKeys() */\n\tDUK_ENUM_INCLUDE_SYMBOLS |\n\t    DUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_INCLUDE_NONENUMERABLE |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR\n};\n\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_keys_shared(duk_hthread *thr) {\n\tduk_hobject *obj;\n#if defined(DUK_USE_ES6_PROXY)\n\tduk_hobject *h_proxy_target;\n\tduk_hobject *h_proxy_handler;\n\tduk_hobject *h_trap_result;\n#endif\n\tduk_small_uint_t enum_flags;\n\tduk_int_t magic;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\n\tmagic = duk_get_current_magic(thr);\n\tif (magic == 3) {\n\t\t/* ES2015 Section 26.1.11 requires a TypeError for non-objects.  Lightfuncs\n\t\t * and plain buffers pretend to be objects, so accept those too.\n\t\t */\n\t\tobj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\t} else {\n\t\t/* ES2015: ToObject coerce. */\n\t\tobj = duk_to_hobject(thr, 0);\n\t}\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(obj);\n\n\t/* XXX: proxy chains */\n\n#if defined(DUK_USE_ES6_PROXY)\n\t/* XXX: better sharing of code between proxy target call sites */\n\tif (DUK_LIKELY(!duk_hobject_proxy_check(obj,\n\t                                        &h_proxy_target,\n\t                                        &h_proxy_handler))) {\n\t\tgoto skip_proxy;\n\t}\n\n\tduk_push_hobject(thr, h_proxy_handler);\n\tif (!duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_OWN_KEYS)) {\n\t\t/* Careful with reachability here: don't pop 'obj' before pushing\n\t\t * proxy target.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"no ownKeys trap, get keys of target instead\"));\n\t\tduk_pop_2(thr);\n\t\tduk_push_hobject(thr, h_proxy_target);\n\t\tduk_replace(thr, 0);\n\t\tDUK_ASSERT_TOP(thr, 1);\n\t\tgoto skip_proxy;\n\t}\n\n\t/* [ obj handler trap ] */\n\tduk_insert(thr, -2);\n\tduk_push_hobject(thr, h_proxy_target);  /* -> [ obj trap handler target ] */\n\tduk_call_method(thr, 1 /*nargs*/);      /* -> [ obj trap_result ] */\n\th_trap_result = duk_require_hobject(thr, -1);\n\tDUK_UNREF(h_trap_result);\n\n\tmagic = duk_get_current_magic(thr);\n\tDUK_ASSERT(magic >= 0 && magic < (duk_int_t) (sizeof(duk__object_keys_enum_flags) / sizeof(duk_small_uint_t)));\n\tenum_flags = duk__object_keys_enum_flags[magic];\n\n\tduk_proxy_ownkeys_postprocess(thr, h_proxy_target, enum_flags);\n\treturn 1;\n\n skip_proxy:\n#endif  /* DUK_USE_ES6_PROXY */\n\n\tDUK_ASSERT_TOP(thr, 1);\n\tmagic = duk_get_current_magic(thr);\n\tDUK_ASSERT(magic >= 0 && magic < (duk_int_t) (sizeof(duk__object_keys_enum_flags) / sizeof(duk_small_uint_t)));\n\tenum_flags = duk__object_keys_enum_flags[magic];\n\treturn duk_hobject_get_enumerated_keys(thr, enum_flags);\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: Object.preventExtensions()\n\t *  magic = 1: Reflect.preventExtensions()\n\t */\n\n\tduk_hobject *h;\n\tduk_uint_t mask;\n\tduk_int_t magic;\n\n\tmagic = duk_get_current_magic(thr);\n\n\t/* Silent success for lightfuncs and plain buffers always. */\n\tmask = DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER;\n\n\t/* Object.preventExtensions() silent success for non-object. */\n\tif (magic == 0) {\n\t\tmask |= DUK_TYPE_MASK_UNDEFINED |\n\t\t        DUK_TYPE_MASK_NULL |\n\t\t        DUK_TYPE_MASK_BOOLEAN |\n\t\t        DUK_TYPE_MASK_NUMBER |\n\t\t        DUK_TYPE_MASK_STRING |\n\t\t        DUK_TYPE_MASK_POINTER;\n\t}\n\n\tif (duk_check_type_mask(thr, 0, mask)) {\n\t\t/* Not an object, already non-extensible so always success. */\n\t\tgoto done;\n\t}\n\th = duk_require_hobject(thr, 0);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_HOBJECT_CLEAR_EXTENSIBLE(h);\n\n\t/* A non-extensible object cannot gain any more properties,\n\t * so this is a good time to compact.\n\t */\n\tduk_hobject_compact_props(thr, h);\n\n done:\n\tif (magic == 1) {\n\t\tduk_push_true(thr);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n/*\n *  __defineGetter__, __defineSetter__, __lookupGetter__, __lookupSetter__\n */\n\n#if defined(DUK_USE_ES8)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_defineaccessor(duk_hthread *thr) {\n\tduk_push_this(thr);\n\tduk_insert(thr, 0);\n\tduk_to_object(thr, 0);\n\tduk_require_callable(thr, 2);\n\n\t/* [ ToObject(this) key getter/setter ] */\n\n\t/* ToPropertyKey() coercion is not needed, duk_def_prop() does it. */\n\tduk_def_prop(thr, 0, DUK_DEFPROP_SET_ENUMERABLE |\n\t                     DUK_DEFPROP_SET_CONFIGURABLE |\n\t                     (duk_get_current_magic(thr) ? DUK_DEFPROP_HAVE_SETTER : DUK_DEFPROP_HAVE_GETTER));\n\treturn 0;\n}\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_lookupaccessor(duk_hthread *thr) {\n\tduk_uint_t sanity;\n\n\tduk_push_this(thr);\n\tduk_to_object(thr, -1);\n\n\t/* XXX: Prototype walk (with sanity) should be a core property\n\t * operation, could add a flag to e.g. duk_get_prop_desc().\n\t */\n\n\t/* ToPropertyKey() coercion is not needed, duk_get_prop_desc() does it. */\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\twhile (!duk_is_undefined(thr, -1)) {\n\t\t/* [ key obj ] */\n\t\tduk_dup(thr, 0);\n\t\tduk_get_prop_desc(thr, 1, 0 /*flags*/);\n\t\tif (!duk_is_undefined(thr, -1)) {\n\t\t\tduk_get_prop_stridx(thr, -1, (duk_get_current_magic(thr) != 0 ? DUK_STRIDX_SET : DUK_STRIDX_GET));\n\t\t\treturn 1;\n\t\t}\n\t\tduk_pop(thr);\n\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\n\t\tduk_get_prototype(thr, -1);\n\t\tduk_remove(thr, -2);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_ES8 */\n/*\n *  High resolution time API (performance.now() et al)\n *\n *  API specification: https://encoding.spec.whatwg.org/#ap://www.w3.org/TR/hr-time/\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_PERFORMANCE_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_performance_now(duk_hthread *thr) {\n\t/* From API spec:\n\t * The DOMHighResTimeStamp type is used to store a time value in\n\t * milliseconds, measured relative from the time origin, global\n\t * monotonic clock, or a time value that represents a duration\n\t * between two DOMHighResTimeStamp's.\n\t */\n\tduk_push_number(thr, duk_time_get_monotonic_time(thr));\n\treturn 1;\n}\n\n#if 0  /* Missing until semantics decided. */\nDUK_INTERNAL duk_ret_t duk_bi_performance_timeorigin_getter(duk_hthread *thr) {\n\t/* No decision yet how to handle timeOrigins, e.g. should one be\n\t * initialized per heap, or per global object set.  See\n\t * https://www.w3.org/TR/hr-time/#time-origin.\n\t */\n\tduk_push_uint(thr, 0);\n\treturn 1;\n}\n#endif  /* 0 */\n#endif  /* DUK_USE_PERFORMANCE_BUILTIN */\n/*\n *  Pointer built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_pointer_constructor(duk_hthread *thr) {\n\t/* XXX: this behavior is quite useless now; it would be nice to be able\n\t * to create pointer values from e.g. numbers or strings.  Numbers are\n\t * problematic on 64-bit platforms though.  Hex encoded strings?\n\t */\n\tif (duk_get_top(thr) == 0) {\n\t\tduk_push_pointer(thr, NULL);\n\t} else {\n\t\tduk_to_pointer(thr, 0);\n\t}\n\tDUK_ASSERT(duk_is_pointer(thr, 0));\n\tduk_set_top(thr, 1);\n\n\tif (duk_is_constructor_call(thr)) {\n\t\t(void) duk_push_object_helper(thr,\n\t\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER),\n\t\t                              DUK_BIDX_POINTER_PROTOTYPE);\n\n\t\t/* Pointer object internal value is immutable. */\n\t\tduk_dup_0(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\t/* Note: unbalanced stack on purpose */\n\n\treturn 1;\n}\n\n/*\n *  toString(), valueOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_small_int_t to_string = duk_get_current_magic(thr);\n\n\tduk_push_this(thr);\n\ttv = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_POINTER(tv)) {\n\t\t/* nop */\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* Must be a \"pointer object\", i.e. class \"Pointer\" */\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_POINTER) {\n\t\t\tgoto type_error;\n\t\t}\n\n\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t} else {\n\t\tgoto type_error;\n\t}\n\n\tif (to_string) {\n\t\tduk_to_string(thr, -1);\n\t}\n\treturn 1;\n\n type_error:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n/*\n *  Promise built-in\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_PROMISE_BUILTIN)\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_constructor(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_all(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_race(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_reject(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_resolve(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_catch(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_then(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\n#endif  /* DUK_USE_PROMISE_BUILTIN */\n/*\n *  Proxy built-in (ES2015)\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ES6_PROXY)\n/* Post-process a Proxy ownKeys() result at stack top.  Push a cleaned up\n * array of valid result keys (strings or symbols).  TypeError for invalid\n * values.  Flags are shared with duk_enum().\n */\nDUK_INTERNAL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h_proxy_target, duk_uint_t flags) {\n\tduk_uarridx_t i, len, idx;\n\tduk_propdesc desc;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(h_proxy_target != NULL);\n\n\tlen = (duk_uarridx_t) duk_get_length(thr, -1);\n\tidx = 0;\n\tduk_push_array(thr);\n\t/* XXX: preallocated dense array, fill in directly */\n\tfor (i = 0; i < len; i++) {\n\t\tduk_hstring *h;\n\n\t\t/* [ obj trap_result res_arr ] */\n\t\t(void) duk_get_prop_index(thr, -2, i);\n\t\th = duk_get_hstring(thr, -1);\n\t\tif (h == NULL) {\n\t\t\tDUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\n\t\tif (!(flags & DUK_ENUM_INCLUDE_NONENUMERABLE)) {\n\t\t\t/* No support for 'getOwnPropertyDescriptor' trap yet,\n\t\t\t * so check enumerability always from target object\n\t\t\t * descriptor.\n\t\t\t */\n\t\t\tif (duk_hobject_get_own_propdesc(thr, h_proxy_target, duk_known_hstring(thr, -1), &desc, 0 /*flags*/)) {\n\t\t\t\tif ((desc.flags & DUK_PROPDESC_FLAG_ENUMERABLE) == 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore non-enumerable property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\t\tgoto skip_key;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore non-existent property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t}\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tif (!(flags & DUK_ENUM_INCLUDE_SYMBOLS)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore symbol property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t\tif (DUK_HSTRING_HAS_HIDDEN(h) && !(flags & DUK_ENUM_INCLUDE_HIDDEN)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore hidden symbol property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t} else {\n\t\t\tif (flags & DUK_ENUM_EXCLUDE_STRINGS) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore string property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t}\n\n\t\t/* [ obj trap_result res_arr propname ] */\n\t\tduk_put_prop_index(thr, -2, idx++);\n\t\tcontinue;\n\n\t skip_key:\n\t\tduk_pop(thr);\n\t\tcontinue;\n\t}\n\n\t/* XXX: Missing trap result validation for non-configurable target keys\n\t * (must be present), for non-extensible target all target keys must be\n\t * present and no extra keys can be present.\n\t * http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys\n\t */\n\n\t/* XXX: The key enumerability check should trigger the \"getOwnPropertyDescriptor\"\n\t * trap which has not yet been implemented.  In the absence of such a trap,\n\t * the enumerability should be checked from the target object; this is\n\t * handled above.\n\t */\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL duk_ret_t duk_bi_proxy_constructor(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 2);  /* [ target handler ] */\n\n\tduk_require_constructor_call(thr);\n\tduk_push_proxy(thr, 0 /*flags*/);  /* [ target handler ] -> [ proxy ] */\n\treturn 1;  /* replacement */\n}\n#endif  /* DUK_USE_ES6_PROXY */\n/*\n *  'Reflect' built-in (ES2016 Section 26.1)\n *  http://www.ecma-international.org/ecma-262/7.0/#sec-reflect-object\n *\n *  Many Reflect built-in functions are provided by shared helpers in\n *  duk_bi_object.c or duk_bi_function.c.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_delete_property(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\n\t/* [ target key ] */\n\n\tDUK_ASSERT(thr != NULL);\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\tret = duk_hobject_delprop(thr, tv_obj, tv_key, 0 /*throw_flag*/);\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_get(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_idx_t nargs;\n\n\tDUK_ASSERT(thr != NULL);\n\tnargs = duk_get_top_require_min(thr, 2 /*min_top*/);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\tif (nargs >= 3 && !duk_strict_equals(thr, 0, 2)) {\n\t\t/* XXX: [[Get]] receiver currently unsupported */\n\t\tDUK_ERROR_UNSUPPORTED(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* [ target key receiver? ...? ] */\n\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\t(void) duk_hobject_getprop(thr, tv_obj, tv_key);  /* This could also be a duk_get_prop(). */\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_has(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT_TOP(thr, 2);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\n\t/* [ target key ] */\n\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\tret = duk_hobject_hasprop(thr, tv_obj, tv_key);\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_set(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_tval *tv_val;\n\tduk_idx_t nargs;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\tnargs = duk_get_top_require_min(thr, 3 /*min_top*/);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\tif (nargs >= 4 && !duk_strict_equals(thr, 0, 3)) {\n\t\t/* XXX: [[Set]] receiver currently unsupported */\n\t\tDUK_ERROR_UNSUPPORTED(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* [ target key value receiver? ...? ] */\n\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\ttv_val = DUK_GET_TVAL_POSIDX(thr, 2);\n\tret = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, 0 /*throw_flag*/);\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_REFLECT_BUILTIN */\n/*\n *  RegExp built-ins\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\nDUK_LOCAL void duk__get_this_regexp(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\tduk_push_this(thr);\n\th = duk_require_hobject_with_class(thr, -1, DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_ASSERT(h != NULL);\n\tDUK_UNREF(h);\n\tduk_insert(thr, 0);  /* prepend regexp to valstack 0 index */\n}\n\n/* XXX: much to improve (code size) */\nDUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_hthread *thr) {\n\tduk_hobject *h_pattern;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\th_pattern = duk_get_hobject(thr, 0);\n\n\tif (!duk_is_constructor_call(thr) &&\n\t    h_pattern != NULL &&\n\t    DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP &&\n\t    duk_is_undefined(thr, 1)) {\n\t\t/* Called as a function, pattern has [[Class]] \"RegExp\" and\n\t\t * flags is undefined -> return object as is.\n\t\t */\n\t\t/* XXX: ES2015 has a NewTarget SameValue() check which is not\n\t\t * yet implemented.\n\t\t */\n\t\tduk_dup_0(thr);\n\t\treturn 1;\n\t}\n\n\t/* Else functionality is identical for function call and constructor\n\t * call.\n\t */\n\n\tif (h_pattern != NULL &&\n\t    DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP) {\n\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_SOURCE);\n\t\tif (duk_is_undefined(thr, 1)) {\n\t\t\t/* In ES5 one would need to read the flags individually;\n\t\t\t * in ES2015 just read .flags.\n\t\t\t */\n\t\t\tduk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS);\n\t\t} else {\n\t\t\t/* In ES2015 allowed; overrides argument RegExp flags. */\n\t\t\tduk_dup_1(thr);\n\t\t}\n\t} else {\n\t\tif (duk_is_undefined(thr, 0)) {\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_to_string(thr, -1);  /* Rejects Symbols. */\n\t\t}\n\t\tif (duk_is_undefined(thr, 1)) {\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tduk_dup_1(thr);\n\t\t\tduk_to_string(thr, -1);  /* Rejects Symbols. */\n\t\t}\n\n\t\t/* [ ... pattern flags ] */\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"RegExp constructor/function call, pattern=%!T, flags=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* [ ... pattern flags ] (both uncoerced) */\n\n\tduk_to_string(thr, -2);\n\tduk_to_string(thr, -1);\n\tduk_regexp_compile(thr);\n\n\t/* [ ... bytecode escaped_source ] */\n\n\tduk_regexp_create_instance(thr);\n\n\t/* [ ... RegExp ] */\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_exec(duk_hthread *thr) {\n\tduk__get_this_regexp(thr);\n\n\t/* [ regexp input ] */\n\n\tduk_regexp_match(thr);\n\n\t/* [ result ] */\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_test(duk_hthread *thr) {\n\tduk__get_this_regexp(thr);\n\n\t/* [ regexp input ] */\n\n\t/* result object is created and discarded; wasteful but saves code space */\n\tduk_regexp_match(thr);\n\n\t/* [ result ] */\n\n\tduk_push_boolean(thr, (duk_is_null(thr, -1) ? 0 : 1));\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_tostring(duk_hthread *thr) {\n\t/* This must be generic in ES2015 and later. */\n\tDUK_ASSERT_TOP(thr, 0);\n\tduk_push_this(thr);\n\tduk_push_literal(thr, \"/\");\n\tduk_get_prop_stridx(thr, 0, DUK_STRIDX_SOURCE);\n\tduk_dup_m2(thr);  /* another \"/\" */\n\tduk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS);\n\tduk_concat(thr, 4);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_flags(duk_hthread *thr) {\n\t/* .flags is ES2015 but present even when ES2015 bindings are\n\t * disabled because the constructor relies on it.\n\t */\n\tduk_uint8_t buf[8];  /* enough for all flags + NUL */\n\tduk_uint8_t *p = buf;\n\n\t/* .flags is generic and works on any object. */\n\tduk_push_this(thr);\n\t(void) duk_require_hobject(thr, -1);\n\tif (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL)) {\n\t\t*p++ = DUK_ASC_LC_G;\n\t}\n\tif (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_IGNORE_CASE, NULL)) {\n\t\t*p++ = DUK_ASC_LC_I;\n\t}\n\tif (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_MULTILINE, NULL)) {\n\t\t*p++ = DUK_ASC_LC_M;\n\t}\n\t/* .unicode: to be added */\n\t/* .sticky: to be added */\n\t*p++ = DUK_ASC_NUL;\n\tDUK_ASSERT((duk_size_t) (p - buf) <= sizeof(buf));\n\n\tduk_push_string(thr, (const char *) buf);\n\treturn 1;\n}\n\n/* Shared helper for providing .source, .global, .multiline, etc getters. */\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_hthread *thr) {\n\tduk_hstring *h_bc;\n\tduk_small_uint_t re_flags;\n\tduk_hobject *h;\n\tduk_int_t magic;\n\n\tDUK_ASSERT_TOP(thr, 0);\n\n\tduk_push_this(thr);\n\th = duk_require_hobject(thr, -1);\n\tmagic = duk_get_current_magic(thr);\n\n\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_REGEXP) {\n\t\tduk_xget_owndataprop_stridx_short(thr, 0, DUK_STRIDX_INT_SOURCE);\n\t\tduk_xget_owndataprop_stridx_short(thr, 0, DUK_STRIDX_INT_BYTECODE);\n\t\th_bc = duk_require_hstring(thr, -1);\n\t\tre_flags = (duk_small_uint_t) DUK_HSTRING_GET_DATA(h_bc)[0];  /* Safe even if h_bc length is 0 (= NUL) */\n\t\tduk_pop(thr);\n\t} else if (h == thr->builtins[DUK_BIDX_REGEXP_PROTOTYPE]) {\n\t\t/* In ES2015 and ES2016 a TypeError would be thrown here.\n\t\t * However, this had real world issues so ES2017 draft\n\t\t * allows RegExp.prototype specifically, returning '(?:)'\n\t\t * for .source and undefined for all flags.\n\t\t */\n\t\tif (magic != 16 /* .source */) {\n\t\t\treturn 0;\n\t\t}\n\t\tduk_push_literal(thr, \"(?:)\");  /* .source handled by switch-case */\n\t\tre_flags = 0;\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* [ regexp source ] */\n\n\tswitch (magic) {\n\tcase 0: {  /* global */\n\t\tduk_push_boolean(thr, (re_flags & DUK_RE_FLAG_GLOBAL));\n\t\tbreak;\n\t}\n\tcase 1: {  /* ignoreCase */\n\t\tduk_push_boolean(thr, (re_flags & DUK_RE_FLAG_IGNORE_CASE));\n\t\tbreak;\n\t}\n\tcase 2: {  /* multiline */\n\t\tduk_push_boolean(thr, (re_flags & DUK_RE_FLAG_MULTILINE));\n\t\tbreak;\n\t}\n#if 0\n\t/* Don't provide until implemented to avoid interfering with feature\n\t * detection in user code.\n\t */\n\tcase 3:    /* sticky */\n\tcase 4: {  /* unicode */\n\t\tduk_push_false(thr);\n\t\tbreak;\n\t}\n#endif\n\tdefault: {  /* source */\n\t\t/* leave 'source' on top */\n\t\tbreak;\n\t}\n\t}\n\n\treturn 1;\n}\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n/*\n *  String built-ins\n *\n *  Most String built-ins must only accept strings (or String objects).\n *  Symbols, represented internally as strings, must be generally rejected.\n *  The duk_push_this_coercible_to_string() helper does this automatically.\n */\n\n/* XXX: There are several limitations in the current implementation for\n * strings with >= 0x80000000UL characters.  In some cases one would need\n * to be able to represent the range [-0xffffffff,0xffffffff] and so on.\n * Generally character and byte length are assumed to fit into signed 32\n * bits (< 0x80000000UL).  Places with issues are not marked explicitly\n * below in all cases, look for signed type usage (duk_int_t etc) for\n * offsets/lengths.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_STRING_BUILTIN)\n\n/*\n *  Helpers\n */\n\nDUK_LOCAL duk_hstring *duk__str_tostring_notregexp(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tif (duk_get_class_number(thr, idx) == DUK_HOBJECT_CLASS_REGEXP) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\th = duk_to_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\treturn h;\n}\n\nDUK_LOCAL duk_int_t duk__str_search_shared(duk_hthread *thr, duk_hstring *h_this, duk_hstring *h_search, duk_int_t start_cpos, duk_bool_t backwards) {\n\tduk_int_t cpos;\n\tduk_int_t bpos;\n\tconst duk_uint8_t *p_start, *p_end, *p;\n\tconst duk_uint8_t *q_start;\n\tduk_int_t q_blen;\n\tduk_uint8_t firstbyte;\n\tduk_uint8_t t;\n\n\tcpos = start_cpos;\n\n\t/* Empty searchstring always matches; cpos must be clamped here.\n\t * (If q_blen were < 0 due to clamped coercion, it would also be\n\t * caught here.)\n\t */\n\tq_start = DUK_HSTRING_GET_DATA(h_search);\n\tq_blen = (duk_int_t) DUK_HSTRING_GET_BYTELEN(h_search);\n\tif (q_blen <= 0) {\n\t\treturn cpos;\n\t}\n\tDUK_ASSERT(q_blen > 0);\n\n\tbpos = (duk_int_t) duk_heap_strcache_offset_char2byte(thr, h_this, (duk_uint32_t) cpos);\n\n\tp_start = DUK_HSTRING_GET_DATA(h_this);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_this);\n\tp = p_start + bpos;\n\n\t/* This loop is optimized for size.  For speed, there should be\n\t * two separate loops, and we should ensure that memcmp() can be\n\t * used without an extra \"will searchstring fit\" check.  Doing\n\t * the preconditioning for 'p' and 'p_end' is easy but cpos\n\t * must be updated if 'p' is wound back (backward scanning).\n\t */\n\n\tfirstbyte = q_start[0];  /* leading byte of match string */\n\twhile (p <= p_end && p >= p_start) {\n\t\tt = *p;\n\n\t\t/* For ECMAScript strings, this check can only match for\n\t\t * initial UTF-8 bytes (not continuation bytes).  For other\n\t\t * strings all bets are off.\n\t\t */\n\n\t\tif ((t == firstbyte) && ((duk_size_t) (p_end - p) >= (duk_size_t) q_blen)) {\n\t\t\tDUK_ASSERT(q_blen > 0);\n\t\t\tif (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {\n\t\t\t\treturn cpos;\n\t\t\t}\n\t\t}\n\n\t\t/* track cpos while scanning */\n\t\tif (backwards) {\n\t\t\t/* when going backwards, we decrement cpos 'early';\n\t\t\t * 'p' may point to a continuation byte of the char\n\t\t\t * at offset 'cpos', but that's OK because we'll\n\t\t\t * backtrack all the way to the initial byte.\n\t\t\t */\n\t\t\tif ((t & 0xc0) != 0x80) {\n\t\t\t\tcpos--;\n\t\t\t}\n\t\t\tp--;\n\t\t} else {\n\t\t\tif ((t & 0xc0) != 0x80) {\n\t\t\t\tcpos++;\n\t\t\t}\n\t\t\tp++;\n\t\t}\n\t}\n\n\t/* Not found.  Empty string case is handled specially above. */\n\treturn -1;\n}\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_constructor(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_uint_t flags;\n\n\t/* String constructor needs to distinguish between an argument not given at all\n\t * vs. given as 'undefined'.  We're a vararg function to handle this properly.\n\t */\n\n\t/* XXX: copy current activation flags to thr, including current magic,\n\t * is_constructor_call etc.  This takes a few bytes in duk_hthread but\n\t * makes call sites smaller (there are >30 is_constructor_call and get\n\t * current magic call sites.\n\t */\n\n\tif (duk_get_top(thr) == 0) {\n\t\tduk_push_hstring_empty(thr);\n\t} else {\n\t\th = duk_to_hstring_acceptsymbol(thr, 0);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h) && !duk_is_constructor_call(thr))) {\n\t\t\tduk_push_symbol_descriptive_string(thr, h);\n\t\t\tduk_replace(thr, 0);\n\t\t}\n\t}\n\tduk_to_string(thr, 0);  /* catches symbol argument for constructor call */\n\tDUK_ASSERT(duk_is_string(thr, 0));\n\tduk_set_top(thr, 1);  /* Top may be 1 or larger. */\n\n\tif (duk_is_constructor_call(thr)) {\n\t\t/* String object internal value is immutable */\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_STRING);\n\t\tduk_push_object_helper(thr, flags, DUK_BIDX_STRING_PROTOTYPE);\n\t\tduk_dup_0(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\t/* Note: unbalanced stack on purpose */\n\n\treturn 1;\n}\n\nDUK_LOCAL duk_ret_t duk__construct_from_codepoints(duk_hthread *thr, duk_bool_t nonbmp) {\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tduk_idx_t i, n;\n\tduk_ucodepoint_t cp;\n\n\t/* XXX: It would be nice to build the string directly but ToUint16()\n\t * coercion is needed so a generic helper would not be very\n\t * helpful (perhaps coerce the value stack first here and then\n\t * build a string from a duk_tval number sequence in one go?).\n\t */\n\n\tn = duk_get_top(thr);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, (duk_size_t) n);  /* initial estimate for ASCII only codepoints */\n\n\tfor (i = 0; i < n; i++) {\n\t\t/* XXX: could improve bufwriter handling to write multiple codepoints\n\t\t * with one ensure call but the relative benefit would be quite small.\n\t\t */\n\n\t\tif (nonbmp) {\n\t\t\t/* ES2015 requires that (1) SameValue(cp, ToInteger(cp)) and\n\t\t\t * (2) cp >= 0 and cp <= 0x10ffff.  This check does not\n\t\t\t * implement the steps exactly but the outcome should be\n\t\t\t * the same.\n\t\t\t */\n\t\t\tduk_int32_t i32 = 0;\n\t\t\tif (!duk_is_whole_get_int32(duk_to_number(thr, i), &i32) ||\n\t\t\t    i32 < 0 || i32 > 0x10ffffL) {\n\t\t\t\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n\t\t\t}\n\t\t\tDUK_ASSERT(i32 >= 0 && i32 <= 0x10ffffL);\n\t\t\tcp = (duk_ucodepoint_t) i32;\n\t\t\tDUK_BW_WRITE_ENSURE_CESU8(thr, bw, cp);\n\t\t} else {\n#if defined(DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT)\n\t\t\t/* ToUint16() coercion is mandatory in the E5.1 specification, but\n\t\t\t * this non-compliant behavior makes more sense because we support\n\t\t\t * non-BMP codepoints.  Don't use CESU-8 because that'd create\n\t\t\t * surrogate pairs.\n\t\t\t */\n\t\t\tcp = (duk_ucodepoint_t) duk_to_uint32(thr, i);\n\t\t\tDUK_BW_WRITE_ENSURE_XUTF8(thr, bw, cp);\n#else\n\t\t\tcp = (duk_ucodepoint_t) duk_to_uint16(thr, i);\n\t\t\tDUK_ASSERT(cp >= 0 && cp <= 0x10ffffL);\n\t\t\tDUK_BW_WRITE_ENSURE_CESU8(thr, bw, cp);\n#endif\n\t\t}\n\t}\n\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe, extended UTF-8 or CESU-8 encoded. */\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_string_constructor_from_char_code(duk_hthread *thr) {\n\treturn duk__construct_from_codepoints(thr, 0 /*nonbmp*/);\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_constructor_from_code_point(duk_hthread *thr) {\n\treturn duk__construct_from_codepoints(thr, 1 /*nonbmp*/);\n}\n#endif\n\n/*\n *  toString(), valueOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_to_string(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tduk_push_this(thr);\n\ttv = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_STRING(tv)) {\n\t\t/* return as is */\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* Must be a \"string object\", i.e. class \"String\" */\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_STRING) {\n\t\t\tgoto type_error;\n\t\t}\n\n\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\t} else {\n\t\tgoto type_error;\n\t}\n\n\t(void) duk_require_hstring_notsymbol(thr, -1);  /* Reject symbols (and wrapped symbols). */\n\treturn 1;\n\n type_error:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n\n/*\n *  Character and charcode access\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_at(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t pos;\n\n\t/* XXX: faster implementation */\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tpos = duk_to_int(thr, 0);\n\n\tif (sizeof(duk_size_t) >= sizeof(duk_uint_t)) {\n\t\t/* Cast to duk_size_t works in this case:\n\t\t * - If pos < 0, (duk_size_t) pos will always be\n\t\t *   >= max_charlen, and result will be the empty string\n\t\t *   (see duk_substring()).\n\t\t * - If pos >= 0, pos + 1 cannot wrap.\n\t\t */\n\t\tDUK_ASSERT((duk_size_t) DUK_INT_MIN >= DUK_HSTRING_MAX_BYTELEN);\n\t\tDUK_ASSERT((duk_size_t) DUK_INT_MAX + 1U > (duk_size_t) DUK_INT_MAX);\n\t\tduk_substring(thr, -1, (duk_size_t) pos, (duk_size_t) pos + 1U);\n\t} else {\n\t\t/* If size_t is smaller than int, explicit bounds checks\n\t\t * are needed because an int may wrap multiple times.\n\t\t */\n\t\tif (DUK_UNLIKELY(pos < 0 || (duk_uint_t) pos >= (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h))) {\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tduk_substring(thr, -1, (duk_size_t) pos, (duk_size_t) pos + 1U);\n\t\t}\n\t}\n\n\treturn 1;\n}\n\n/* Magic: 0=charCodeAt, 1=codePointAt */\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_code_at(duk_hthread *thr) {\n\tduk_int_t pos;\n\tduk_hstring *h;\n\tduk_bool_t clamped;\n\tduk_uint32_t cp;\n\tduk_int_t magic;\n\n\t/* XXX: faster implementation */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arg=%!T\", (duk_tval *) duk_get_tval(thr, 0)));\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tpos = duk_to_int_clamped_raw(thr,\n\t                             0 /*index*/,\n\t                             0 /*min(incl)*/,\n\t                             (duk_int_t) DUK_HSTRING_GET_CHARLEN(h) - 1 /*max(incl)*/,\n\t                             &clamped /*out_clamped*/);\n#if defined(DUK_USE_ES6)\n\tmagic = duk_get_current_magic(thr);\n#else\n\tDUK_ASSERT(duk_get_current_magic(thr) == 0);\n\tmagic = 0;\n#endif\n\tif (clamped) {\n\t\t/* For out-of-bounds indices .charCodeAt() returns NaN and\n\t\t * .codePointAt() returns undefined.\n\t\t */\n\t\tif (magic != 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tduk_push_nan(thr);\n\t} else {\n\t\tDUK_ASSERT(pos >= 0);\n\t\tcp = (duk_uint32_t) duk_hstring_char_code_at_raw(thr, h, (duk_uint_t) pos, (duk_bool_t) magic /*surrogate_aware*/);\n\t\tduk_push_u32(thr, cp);\n\t}\n\treturn 1;\n}\n\n/*\n *  substring(), substr(), slice()\n */\n\n/* XXX: any chance of merging these three similar but still slightly\n * different algorithms so that footprint would be reduced?\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_substring(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t start_pos, end_pos;\n\tduk_int_t len;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\n\t/* [ start end str ] */\n\n\tstart_pos = duk_to_int_clamped(thr, 0, 0, len);\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend_pos = len;\n\t} else {\n\t\tend_pos = duk_to_int_clamped(thr, 1, 0, len);\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\tDUK_ASSERT(end_pos >= 0 && end_pos <= len);\n\n\tif (start_pos > end_pos) {\n\t\tduk_int_t tmp = start_pos;\n\t\tstart_pos = end_pos;\n\t\tend_pos = tmp;\n\t}\n\n\tDUK_ASSERT(end_pos >= start_pos);\n\n\tduk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);\n\treturn 1;\n}\n\n#if defined(DUK_USE_SECTION_B)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_substr(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t start_pos, end_pos;\n\tduk_int_t len;\n\n\t/* Unlike non-obsolete String calls, substr() algorithm in E5.1\n\t * specification will happily coerce undefined and null to strings\n\t * (\"undefined\" and \"null\").\n\t */\n\tduk_push_this(thr);\n\th = duk_to_hstring_m1(thr);  /* Reject Symbols. */\n\tDUK_ASSERT(h != NULL);\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\n\t/* [ start length str ] */\n\n\t/* The implementation for computing of start_pos and end_pos differs\n\t * from the standard algorithm, but is intended to result in the exactly\n\t * same behavior.  This is not always obvious.\n\t */\n\n\t/* combines steps 2 and 5; -len ensures max() not needed for step 5 */\n\tstart_pos = duk_to_int_clamped(thr, 0, -len, len);\n\tif (start_pos < 0) {\n\t\tstart_pos = len + start_pos;\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\n\t/* combines steps 3, 6; step 7 is not needed */\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend_pos = len;\n\t} else {\n\t\tDUK_ASSERT(start_pos <= len);\n\t\tend_pos = start_pos + duk_to_int_clamped(thr, 1, 0, len - start_pos);\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\tDUK_ASSERT(end_pos >= 0 && end_pos <= len);\n\tDUK_ASSERT(end_pos >= start_pos);\n\n\tduk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);\n\treturn 1;\n}\n#endif  /* DUK_USE_SECTION_B */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_slice(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t start_pos, end_pos;\n\tduk_int_t len;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\n\t/* [ start end str ] */\n\n\tstart_pos = duk_to_int_clamped(thr, 0, -len, len);\n\tif (start_pos < 0) {\n\t\tstart_pos = len + start_pos;\n\t}\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend_pos = len;\n\t} else {\n\t\tend_pos = duk_to_int_clamped(thr, 1, -len, len);\n\t\tif (end_pos < 0) {\n\t\t\tend_pos = len + end_pos;\n\t\t}\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\tDUK_ASSERT(end_pos >= 0 && end_pos <= len);\n\n\tif (end_pos < start_pos) {\n\t\tend_pos = start_pos;\n\t}\n\n\tDUK_ASSERT(end_pos >= start_pos);\n\n\tduk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);\n\treturn 1;\n}\n\n/*\n *  Case conversion\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_caseconv_shared(duk_hthread *thr) {\n\tduk_small_int_t uppercase = duk_get_current_magic(thr);\n\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk_unicode_case_convert_string(thr, (duk_bool_t) uppercase);\n\treturn 1;\n}\n\n/*\n *  indexOf() and lastIndexOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_indexof_shared(duk_hthread *thr) {\n\tduk_hstring *h_this;\n\tduk_hstring *h_search;\n\tduk_int_t clen_this;\n\tduk_int_t cpos;\n\tduk_small_uint_t is_lastindexof = (duk_small_uint_t) duk_get_current_magic(thr);  /* 0=indexOf, 1=lastIndexOf */\n\n\th_this = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_this != NULL);\n\tclen_this = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h_this);\n\n\th_search = duk_to_hstring(thr, 0);\n\tDUK_ASSERT(h_search != NULL);\n\n\tduk_to_number(thr, 1);\n\tif (duk_is_nan(thr, 1) && is_lastindexof) {\n\t\t/* indexOf: NaN should cause pos to be zero.\n\t\t * lastIndexOf: NaN should cause pos to be +Infinity\n\t\t * (and later be clamped to len).\n\t\t */\n\t\tcpos = clen_this;\n\t} else {\n\t\tcpos = duk_to_int_clamped(thr, 1, 0, clen_this);\n\t}\n\n\tcpos = duk__str_search_shared(thr, h_this, h_search, cpos, is_lastindexof /*backwards*/);\n\tduk_push_int(thr, cpos);\n\treturn 1;\n}\n\n/*\n *  replace()\n */\n\n/* XXX: the current implementation works but is quite clunky; it compiles\n * to almost 1,4kB of x86 code so it needs to be simplified (better approach,\n * shared helpers, etc).  Some ideas for refactoring:\n *\n * - a primitive to convert a string into a regexp matcher (reduces matching\n *   code at the cost of making matching much slower)\n * - use replace() as a basic helper for match() and split(), which are both\n *   much simpler\n * - API call to get_prop and to_boolean\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {\n\tduk_hstring *h_input;\n\tduk_hstring *h_match;\n\tduk_hstring *h_search;\n\tduk_hobject *h_re;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tduk_bool_t is_regexp;\n\tduk_bool_t is_global;\n#endif\n\tduk_bool_t is_repl_func;\n\tduk_uint32_t match_start_coff, match_start_boff;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tduk_int_t match_caps;\n#endif\n\tduk_uint32_t prev_match_end_boff;\n\tconst duk_uint8_t *r_start, *r_end, *r;   /* repl string scan */\n\tduk_size_t tmp_sz;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\th_input = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_input != NULL);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input));  /* input size is good output starting point */\n\n\tDUK_ASSERT_TOP(thr, 4);\n\n\t/* stack[0] = search value\n\t * stack[1] = replace value\n\t * stack[2] = input string\n\t * stack[3] = result buffer\n\t */\n\n\th_re = duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_REGEXP);\n\tif (h_re) {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tis_regexp = 1;\n\t\tis_global = duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL);\n\n\t\tif (is_global) {\n\t\t\t/* start match from beginning */\n\t\t\tduk_push_int(thr, 0);\n\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t}\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\tDUK_DCERROR_UNSUPPORTED(thr);\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t} else {\n\t\tduk_to_string(thr, 0);  /* rejects symbols */\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tis_regexp = 0;\n\t\tis_global = 0;\n#endif\n\t}\n\n\tif (duk_is_function(thr, 1)) {\n\t\tis_repl_func = 1;\n\t\tr_start = NULL;\n\t\tr_end = NULL;\n\t} else {\n\t\tduk_hstring *h_repl;\n\n\t\tis_repl_func = 0;\n\t\th_repl = duk_to_hstring(thr, 1);  /* reject symbols */\n\t\tDUK_ASSERT(h_repl != NULL);\n\t\tr_start = DUK_HSTRING_GET_DATA(h_repl);\n\t\tr_end = r_start + DUK_HSTRING_GET_BYTELEN(h_repl);\n\t}\n\n\tprev_match_end_boff = 0;\n\n\tfor (;;) {\n\t\t/*\n\t\t *  If matching with a regexp:\n\t\t *    - non-global RegExp: lastIndex not touched on a match, zeroed\n\t\t *      on a non-match\n\t\t *    - global RegExp: on match, lastIndex will be updated by regexp\n\t\t *      executor to point to next char after the matching part (so that\n\t\t *      characters in the matching part are not matched again)\n\t\t *\n\t\t *  If matching with a string:\n\t\t *    - always non-global match, find first occurrence\n\t\t *\n\t\t *  We need:\n\t\t *    - The character offset of start-of-match for the replacer function\n\t\t *    - The byte offsets for start-of-match and end-of-match to implement\n\t\t *      the replacement values $&, $`, and $', and to copy non-matching\n\t\t *      input string portions (including header and trailer) verbatim.\n\t\t *\n\t\t *  NOTE: the E5.1 specification is a bit vague how the RegExp should\n\t\t *  behave in the replacement process; e.g. is matching done first for\n\t\t *  all matches (in the global RegExp case) before any replacer calls\n\t\t *  are made?  See: test-bi-string-proto-replace.js for discussion.\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, 4);\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (is_regexp) {\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_dup_2(thr);\n\t\t\tduk_regexp_match(thr);  /* [ ... regexp input ] -> [ res_obj ] */\n\t\t\tif (!duk_is_object(thr, -1)) {\n\t\t\t\tduk_pop(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX);\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tmatch_start_coff = duk_get_uint(thr, -1);\n\t\t\tduk_pop(thr);\n\n\t\t\tduk_get_prop_index(thr, -1, 0);\n\t\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\t\t\th_match = duk_known_hstring(thr, -1);\n\t\t\tduk_pop(thr);  /* h_match is borrowed, remains reachable through match_obj */\n\n\t\t\tif (DUK_HSTRING_GET_BYTELEN(h_match) == 0) {\n\t\t\t\t/* This should be equivalent to match() algorithm step 8.f.iii.2:\n\t\t\t\t * detect an empty match and allow it, but don't allow it twice.\n\t\t\t\t */\n\t\t\t\tduk_uint32_t last_index;\n\n\t\t\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\t\tlast_index = (duk_uint32_t) duk_get_uint(thr, -1);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"empty match, bump lastIndex: %ld -> %ld\",\n\t\t\t\t                     (long) last_index, (long) (last_index + 1)));\n\t\t\t\tduk_pop(thr);\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) (last_index + 1));\n\t\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\t}\n\n\t\t\tDUK_ASSERT(duk_get_length(thr, -1) <= DUK_INT_MAX);  /* string limits */\n\t\t\tmatch_caps = (duk_int_t) duk_get_length(thr, -1);\n\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\tconst duk_uint8_t *p_start, *p_end, *p;   /* input string scan */\n\t\t\tconst duk_uint8_t *q_start;               /* match string */\n\t\t\tduk_size_t q_blen;\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\tDUK_ASSERT(!is_global);  /* single match always */\n#endif\n\n\t\t\tp_start = DUK_HSTRING_GET_DATA(h_input);\n\t\t\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\t\t\tp = p_start;\n\n\t\t\th_search = duk_known_hstring(thr, 0);\n\t\t\tq_start = DUK_HSTRING_GET_DATA(h_search);\n\t\t\tq_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_search);\n\n\t\t\tp_end -= q_blen;  /* ensure full memcmp() fits in while */\n\n\t\t\tmatch_start_coff = 0;\n\n\t\t\twhile (p <= p_end) {\n\t\t\t\tDUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + DUK_HSTRING_GET_BYTELEN(h_input));\n\t\t\t\tif (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {\n\t\t\t\t\tduk_dup_0(thr);\n\t\t\t\t\th_match = duk_known_hstring(thr, -1);\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t\t\tmatch_caps = 0;\n#endif\n\t\t\t\t\tgoto found;\n\t\t\t\t}\n\n\t\t\t\t/* track utf-8 non-continuation bytes */\n\t\t\t\tif ((p[0] & 0xc0) != 0x80) {\n\t\t\t\t\tmatch_start_coff++;\n\t\t\t\t}\n\t\t\t\tp++;\n\t\t\t}\n\n\t\t\t/* not found */\n\t\t\tbreak;\n\t\t}\n\t found:\n\n\t\t/* stack[0] = search value\n\t\t * stack[1] = replace value\n\t\t * stack[2] = input string\n\t\t * stack[3] = result buffer\n\t\t * stack[4] = regexp match OR match string\n\t\t */\n\n\t\tmatch_start_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h_input, match_start_coff);\n\n\t\ttmp_sz = (duk_size_t) (match_start_boff - prev_match_end_boff);\n\t\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff, tmp_sz);\n\n\t\tprev_match_end_boff = match_start_boff + DUK_HSTRING_GET_BYTELEN(h_match);\n\n\t\tif (is_repl_func) {\n\t\t\tduk_idx_t idx_args;\n\t\t\tduk_hstring *h_repl;\n\n\t\t\t/* regexp res_obj is at index 4 */\n\n\t\t\tduk_dup_1(thr);\n\t\t\tidx_args = duk_get_top(thr);\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\tif (is_regexp) {\n\t\t\t\tduk_int_t idx;\n\t\t\t\tduk_require_stack(thr, match_caps + 2);\n\t\t\t\tfor (idx = 0; idx < match_caps; idx++) {\n\t\t\t\t\t/* match followed by capture(s) */\n\t\t\t\t\tduk_get_prop_index(thr, 4, (duk_uarridx_t) idx);\n\t\t\t\t}\n\t\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t\t/* match == search string, by definition */\n\t\t\t\tduk_dup_0(thr);\n\t\t\t}\n\t\t\tduk_push_uint(thr, (duk_uint_t) match_start_coff);\n\t\t\tduk_dup_2(thr);\n\n\t\t\t/* [ ... replacer match [captures] match_char_offset input ] */\n\n\t\t\tduk_call(thr, duk_get_top(thr) - idx_args);\n\t\t\th_repl = duk_to_hstring_m1(thr);  /* -> [ ... repl_value ] */\n\t\t\tDUK_ASSERT(h_repl != NULL);\n\n\t\t\tDUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_repl);\n\n\t\t\tduk_pop(thr);  /* repl_value */\n\t\t} else {\n\t\t\tr = r_start;\n\n\t\t\twhile (r < r_end) {\n\t\t\t\tduk_int_t ch1;\n\t\t\t\tduk_int_t ch2;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t\tduk_int_t ch3;\n#endif\n\t\t\t\tduk_size_t left;\n\n\t\t\t\tch1 = *r++;\n\t\t\t\tif (ch1 != DUK_ASC_DOLLAR) {\n\t\t\t\t\tgoto repl_write;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(r <= r_end);\n\t\t\t\tleft = (duk_size_t) (r_end - r);\n\n\t\t\t\tif (left <= 0) {\n\t\t\t\t\tgoto repl_write;\n\t\t\t\t}\n\n\t\t\t\tch2 = r[0];\n\t\t\t\tswitch (ch2) {\n\t\t\t\tcase DUK_ASC_DOLLAR: {\n\t\t\t\t\tch1 = (1 << 8) + DUK_ASC_DOLLAR;\n\t\t\t\t\tgoto repl_write;\n\t\t\t\t}\n\t\t\t\tcase DUK_ASC_AMP: {\n\t\t\t\t\tDUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_match);\n\t\t\t\t\tr++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcase DUK_ASC_GRAVE: {\n\t\t\t\t\ttmp_sz = (duk_size_t) match_start_boff;\n\t\t\t\t\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input), tmp_sz);\n\t\t\t\t\tr++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcase DUK_ASC_SINGLEQUOTE: {\n\t\t\t\t\tduk_uint32_t match_end_boff;\n\n\t\t\t\t\t/* Use match charlen instead of bytelen, just in case the input and\n\t\t\t\t\t * match codepoint encodings would have different lengths.\n\t\t\t\t\t */\n\t\t\t\t\t/* XXX: charlen computed here, and also in char2byte helper. */\n\t\t\t\t\tmatch_end_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr,\n\t\t\t\t\t                                                                   h_input,\n\t\t\t\t\t                                                                   match_start_coff + (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h_match));\n\n\t\t\t\t\ttmp_sz = (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - match_end_boff);\n\t\t\t\t\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + match_end_boff, tmp_sz);\n\t\t\t\t\tr++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tdefault: {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t\t\tduk_int_t capnum, captmp, capadv;\n\t\t\t\t\t/* XXX: optional check, match_caps is zero if no regexp,\n\t\t\t\t\t * so dollar will be interpreted literally anyway.\n\t\t\t\t\t */\n\n\t\t\t\t\tif (!is_regexp) {\n\t\t\t\t\t\tgoto repl_write;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!(ch2 >= DUK_ASC_0 && ch2 <= DUK_ASC_9)) {\n\t\t\t\t\t\tgoto repl_write;\n\t\t\t\t\t}\n\t\t\t\t\tcapnum = ch2 - DUK_ASC_0;\n\t\t\t\t\tcapadv = 1;\n\n\t\t\t\t\tif (left >= 2) {\n\t\t\t\t\t\tch3 = r[1];\n\t\t\t\t\t\tif (ch3 >= DUK_ASC_0 && ch3 <= DUK_ASC_9) {\n\t\t\t\t\t\t\tcaptmp = capnum * 10 + (ch3 - DUK_ASC_0);\n\t\t\t\t\t\t\tif (captmp < match_caps) {\n\t\t\t\t\t\t\t\tcapnum = captmp;\n\t\t\t\t\t\t\t\tcapadv = 2;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (capnum > 0 && capnum < match_caps) {\n\t\t\t\t\t\tDUK_ASSERT(is_regexp != 0);  /* match_caps == 0 without regexps */\n\n\t\t\t\t\t\t/* regexp res_obj is at offset 4 */\n\t\t\t\t\t\tduk_get_prop_index(thr, 4, (duk_uarridx_t) capnum);\n\t\t\t\t\t\tif (duk_is_string(thr, -1)) {\n\t\t\t\t\t\t\tduk_hstring *h_tmp_str;\n\n\t\t\t\t\t\t\th_tmp_str = duk_known_hstring(thr, -1);\n\n\t\t\t\t\t\t\tDUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_tmp_str);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t/* undefined -> skip (replaced with empty) */\n\t\t\t\t\t\t}\n\t\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\t\tr += capadv;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgoto repl_write;\n\t\t\t\t\t}\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t\t\tgoto repl_write;  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t\t}  /* default case */\n\t\t\t\t}  /* switch (ch2) */\n\n\t\t\t repl_write:\n\t\t\t\t/* ch1 = (r_increment << 8) + byte */\n\n\t\t\t\tDUK_BW_WRITE_ENSURE_U8(thr, bw, (duk_uint8_t) (ch1 & 0xff));\n\t\t\t\tr += ch1 >> 8;\n\t\t\t}  /* while repl */\n\t\t}  /* if (is_repl_func) */\n\n\t\tduk_pop(thr);  /* pop regexp res_obj or match string */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (!is_global) {\n#else\n\t\t{  /* unconditionally; is_global==0 */\n#endif\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* trailer */\n\ttmp_sz = (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - prev_match_end_boff);\n\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff, tmp_sz);\n\n\tDUK_ASSERT_TOP(thr, 4);\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if inputs are safe. */\n\treturn 1;\n}\n\n/*\n *  split()\n */\n\n/* XXX: very messy now, but works; clean up, remove unused variables (nomimally\n * used so compiler doesn't complain).\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {\n\tduk_hstring *h_input;\n\tduk_hstring *h_sep;\n\tduk_uint32_t limit;\n\tduk_uint32_t arr_idx;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tduk_bool_t is_regexp;\n#endif\n\tduk_bool_t matched;  /* set to 1 if any match exists (needed for empty input special case) */\n\tduk_uint32_t prev_match_end_coff, prev_match_end_boff;\n\tduk_uint32_t match_start_boff, match_start_coff;\n\tduk_uint32_t match_end_boff, match_end_coff;\n\n\th_input = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_input != NULL);\n\n\tduk_push_array(thr);\n\n\tif (duk_is_undefined(thr, 1)) {\n\t\tlimit = 0xffffffffUL;\n\t} else {\n\t\tlimit = duk_to_uint32(thr, 1);\n\t}\n\n\tif (limit == 0) {\n\t\treturn 1;\n\t}\n\n\t/* If the separator is a RegExp, make a \"clone\" of it.  The specification\n\t * algorithm calls [[Match]] directly for specific indices; we emulate this\n\t * by tweaking lastIndex and using a \"force global\" variant of duk_regexp_match()\n\t * which will use global-style matching even when the RegExp itself is non-global.\n\t */\n\n\tif (duk_is_undefined(thr, 0)) {\n\t\t/* The spec algorithm first does \"R = ToString(separator)\" before checking\n\t\t * whether separator is undefined.  Since this is side effect free, we can\n\t\t * skip the ToString() here.\n\t\t */\n\t\tduk_dup_2(thr);\n\t\tduk_put_prop_index(thr, 3, 0);\n\t\treturn 1;\n\t} else if (duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_REGEXP) != NULL) {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tduk_push_hobject_bidx(thr, DUK_BIDX_REGEXP_CONSTRUCTOR);\n\t\tduk_dup_0(thr);\n\t\tduk_new(thr, 1);  /* [ ... RegExp val ] -> [ ... res ] */\n\t\tduk_replace(thr, 0);\n\t\t/* lastIndex is initialized to zero by new RegExp() */\n\t\tis_regexp = 1;\n#else\n\t\tDUK_DCERROR_UNSUPPORTED(thr);\n#endif\n\t} else {\n\t\tduk_to_string(thr, 0);\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tis_regexp = 0;\n#endif\n\t}\n\n\t/* stack[0] = separator (string or regexp)\n\t * stack[1] = limit\n\t * stack[2] = input string\n\t * stack[3] = result array\n\t */\n\n\tprev_match_end_boff = 0;\n\tprev_match_end_coff = 0;\n\tarr_idx = 0;\n\tmatched = 0;\n\n\tfor (;;) {\n\t\t/*\n\t\t *  The specification uses RegExp [[Match]] to attempt match at specific\n\t\t *  offsets.  We don't have such a primitive, so we use an actual RegExp\n\t\t *  and tweak lastIndex.  Since the RegExp may be non-global, we use a\n\t\t *  special variant which forces global-like behavior for matching.\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, 4);\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (is_regexp) {\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_dup_2(thr);\n\t\t\tduk_regexp_match_force_global(thr);  /* [ ... regexp input ] -> [ res_obj ] */\n\t\t\tif (!duk_is_object(thr, -1)) {\n\t\t\t\tduk_pop(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched = 1;\n\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX);\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tmatch_start_coff = duk_get_uint(thr, -1);\n\t\t\tmatch_start_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h_input, match_start_coff);\n\t\t\tduk_pop(thr);\n\n\t\t\tif (match_start_coff == DUK_HSTRING_GET_CHARLEN(h_input)) {\n\t\t\t\t/* don't allow an empty match at the end of the string */\n\t\t\t\tduk_pop(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tmatch_end_coff = duk_get_uint(thr, -1);\n\t\t\tmatch_end_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h_input, match_end_coff);\n\t\t\tduk_pop(thr);\n\n\t\t\t/* empty match -> bump and continue */\n\t\t\tif (prev_match_end_boff == match_end_boff) {\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) (match_end_coff + 1));\n\t\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\t\tduk_pop(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\tconst duk_uint8_t *p_start, *p_end, *p;   /* input string scan */\n\t\t\tconst duk_uint8_t *q_start;               /* match string */\n\t\t\tduk_size_t q_blen, q_clen;\n\n\t\t\tp_start = DUK_HSTRING_GET_DATA(h_input);\n\t\t\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\t\t\tp = p_start + prev_match_end_boff;\n\n\t\t\th_sep = duk_known_hstring(thr, 0);  /* symbol already rejected above */\n\t\t\tq_start = DUK_HSTRING_GET_DATA(h_sep);\n\t\t\tq_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sep);\n\t\t\tq_clen = (duk_size_t) DUK_HSTRING_GET_CHARLEN(h_sep);\n\n\t\t\tp_end -= q_blen;  /* ensure full memcmp() fits in while */\n\n\t\t\tmatch_start_coff = prev_match_end_coff;\n\n\t\t\tif (q_blen == 0) {\n\t\t\t\t/* Handle empty separator case: it will always match, and always\n\t\t\t\t * triggers the check in step 13.c.iii initially.  Note that we\n\t\t\t\t * must skip to either end of string or start of first codepoint,\n\t\t\t\t * skipping over any continuation bytes!\n\t\t\t\t *\n\t\t\t\t * Don't allow an empty string to match at the end of the input.\n\t\t\t\t */\n\n\t\t\t\tmatched = 1;  /* empty separator can always match */\n\n\t\t\t\tmatch_start_coff++;\n\t\t\t\tp++;\n\t\t\t\twhile (p < p_end) {\n\t\t\t\t\tif ((p[0] & 0xc0) != 0x80) {\n\t\t\t\t\t\tgoto found;\n\t\t\t\t\t}\n\t\t\t\t\tp++;\n\t\t\t\t}\n\t\t\t\tgoto not_found;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(q_blen > 0 && q_clen > 0);\n\t\t\twhile (p <= p_end) {\n\t\t\t\tDUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + DUK_HSTRING_GET_BYTELEN(h_input));\n\t\t\t\tDUK_ASSERT(q_blen > 0);  /* no issues with empty memcmp() */\n\t\t\t\tif (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {\n\t\t\t\t\t/* never an empty match, so step 13.c.iii can't be triggered */\n\t\t\t\t\tgoto found;\n\t\t\t\t}\n\n\t\t\t\t/* track utf-8 non-continuation bytes */\n\t\t\t\tif ((p[0] & 0xc0) != 0x80) {\n\t\t\t\t\tmatch_start_coff++;\n\t\t\t\t}\n\t\t\t\tp++;\n\t\t\t}\n\n\t\t not_found:\n\t\t\t/* not found */\n\t\t\tbreak;\n\n\t\t found:\n\t\t\tmatched = 1;\n\t\t\tmatch_start_boff = (duk_uint32_t) (p - p_start);\n\t\t\tmatch_end_coff = (duk_uint32_t) (match_start_coff + q_clen);  /* constrained by string length */\n\t\t\tmatch_end_boff = (duk_uint32_t) (match_start_boff + q_blen);  /* ditto */\n\n\t\t\t/* empty match (may happen with empty separator) -> bump and continue */\n\t\t\tif (prev_match_end_boff == match_end_boff) {\n\t\t\t\tprev_match_end_boff++;\n\t\t\t\tprev_match_end_coff++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}  /* if (is_regexp) */\n\n\t\t/* stack[0] = separator (string or regexp)\n\t\t * stack[1] = limit\n\t\t * stack[2] = input string\n\t\t * stack[3] = result array\n\t\t * stack[4] = regexp res_obj (if is_regexp)\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"split; match_start b=%ld,c=%ld, match_end b=%ld,c=%ld, prev_end b=%ld,c=%ld\",\n\t\t                     (long) match_start_boff, (long) match_start_coff,\n\t\t                     (long) match_end_boff, (long) match_end_coff,\n\t\t                     (long) prev_match_end_boff, (long) prev_match_end_coff));\n\n\t\tduk_push_lstring(thr,\n\t\t                 (const char *) (DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff),\n\t\t                 (duk_size_t) (match_start_boff - prev_match_end_boff));\n\t\tduk_put_prop_index(thr, 3, arr_idx);\n\t\tarr_idx++;\n\t\tif (arr_idx >= limit) {\n\t\t\tgoto hit_limit;\n\t\t}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (is_regexp) {\n\t\t\tduk_size_t i, len;\n\n\t\t\tlen = duk_get_length(thr, 4);\n\t\t\tfor (i = 1; i < len; i++) {\n\t\t\t\tDUK_ASSERT(i <= DUK_UARRIDX_MAX);  /* cannot have >4G captures */\n\t\t\t\tduk_get_prop_index(thr, 4, (duk_uarridx_t) i);\n\t\t\t\tduk_put_prop_index(thr, 3, arr_idx);\n\t\t\t\tarr_idx++;\n\t\t\t\tif (arr_idx >= limit) {\n\t\t\t\t\tgoto hit_limit;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_pop(thr);\n\t\t\t/* lastIndex already set up for next match */\n\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t/* no action */\n\t\t}\n\n\t\tprev_match_end_boff = match_end_boff;\n\t\tprev_match_end_coff = match_end_coff;\n\t\tcontinue;\n\t}  /* for */\n\n\t/* Combined step 11 (empty string special case) and 14-15. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"split trailer; prev_end b=%ld,c=%ld\",\n\t                     (long) prev_match_end_boff, (long) prev_match_end_coff));\n\n\tif (DUK_HSTRING_GET_BYTELEN(h_input) > 0 || !matched) {\n\t\t/* Add trailer if:\n\t\t *   a) non-empty input\n\t\t *   b) empty input and no (zero size) match found (step 11)\n\t\t */\n\n\t\tduk_push_lstring(thr,\n\t\t                 (const char *) DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff,\n\t\t                 (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - prev_match_end_boff));\n\t\tduk_put_prop_index(thr, 3, arr_idx);\n\t\t/* No arr_idx update or limit check */\n\t}\n\n\treturn 1;\n\n hit_limit:\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tif (is_regexp) {\n\t\tduk_pop(thr);\n\t}\n#endif\n\n\treturn 1;\n}\n\n/*\n *  Various\n */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_LOCAL void duk__to_regexp_helper(duk_hthread *thr, duk_idx_t idx, duk_bool_t force_new) {\n\tduk_hobject *h;\n\n\t/* Shared helper for match() steps 3-4, search() steps 3-4. */\n\n\tDUK_ASSERT(idx >= 0);\n\n\tif (force_new) {\n\t\tgoto do_new;\n\t}\n\n\th = duk_get_hobject_with_class(thr, idx, DUK_HOBJECT_CLASS_REGEXP);\n\tif (!h) {\n\t\tgoto do_new;\n\t}\n\treturn;\n\n do_new:\n\tduk_push_hobject_bidx(thr, DUK_BIDX_REGEXP_CONSTRUCTOR);\n\tduk_dup(thr, idx);\n\tduk_new(thr, 1);  /* [ ... RegExp val ] -> [ ... res ] */\n\tduk_replace(thr, idx);\n}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_search(duk_hthread *thr) {\n\t/* Easiest way to implement the search required by the specification\n\t * is to do a RegExp test() with lastIndex forced to zero.  To avoid\n\t * side effects on the argument, \"clone\" the RegExp if a RegExp was\n\t * given as input.\n\t *\n\t * The global flag of the RegExp should be ignored; setting lastIndex\n\t * to zero (which happens when \"cloning\" the RegExp) should have an\n\t * equivalent effect.\n\t */\n\n\tDUK_ASSERT_TOP(thr, 1);\n\t(void) duk_push_this_coercible_to_string(thr);  /* at index 1 */\n\tduk__to_regexp_helper(thr, 0 /*index*/, 1 /*force_new*/);\n\n\t/* stack[0] = regexp\n\t * stack[1] = string\n\t */\n\n\t/* Avoid using RegExp.prototype methods, as they're writable and\n\t * configurable and may have been changed.\n\t */\n\n\tduk_dup_0(thr);\n\tduk_dup_1(thr);  /* [ ... re_obj input ] */\n\tduk_regexp_match(thr);  /* -> [ ... res_obj ] */\n\n\tif (!duk_is_object(thr, -1)) {\n\t\tduk_push_int(thr, -1);\n\t\treturn 1;\n\t}\n\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX);\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\treturn 1;\n}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_match(duk_hthread *thr) {\n\tduk_bool_t global;\n\tduk_int_t prev_last_index;\n\tduk_int_t this_index;\n\tduk_int_t arr_idx;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk__to_regexp_helper(thr, 0 /*index*/, 0 /*force_new*/);\n\tglobal = duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL);\n\tDUK_ASSERT_TOP(thr, 2);\n\n\t/* stack[0] = regexp\n\t * stack[1] = string\n\t */\n\n\tif (!global) {\n\t\tduk_regexp_match(thr);  /* -> [ res_obj ] */\n\t\treturn 1;  /* return 'res_obj' */\n\t}\n\n\t/* Global case is more complex. */\n\n\t/* [ regexp string ] */\n\n\tduk_push_int(thr, 0);\n\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\tduk_push_array(thr);\n\n\t/* [ regexp string res_arr ] */\n\n\tprev_last_index = 0;\n\tarr_idx = 0;\n\n\tfor (;;) {\n\t\tDUK_ASSERT_TOP(thr, 3);\n\n\t\tduk_dup_0(thr);\n\t\tduk_dup_1(thr);\n\t\tduk_regexp_match(thr);  /* -> [ ... regexp string ] -> [ ... res_obj ] */\n\n\t\tif (!duk_is_object(thr, -1)) {\n\t\t\tduk_pop(thr);\n\t\t\tbreak;\n\t\t}\n\n\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\tthis_index = duk_get_int(thr, -1);\n\t\tduk_pop(thr);\n\n\t\tif (this_index == prev_last_index) {\n\t\t\tthis_index++;\n\t\t\tduk_push_int(thr, this_index);\n\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t}\n\t\tprev_last_index = this_index;\n\n\t\tduk_get_prop_index(thr, -1, 0);  /* match string */\n\t\tduk_put_prop_index(thr, 2, (duk_uarridx_t) arr_idx);\n\t\tarr_idx++;\n\t\tduk_pop(thr);  /* res_obj */\n\t}\n\n\tif (arr_idx == 0) {\n\t\tduk_push_null(thr);\n\t}\n\n\treturn 1;  /* return 'res_arr' or 'null' */\n}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_concat(duk_hthread *thr) {\n\t/* duk_concat() coerces arguments with ToString() in correct order */\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk_insert(thr, 0);  /* this is relatively expensive */\n\tduk_concat(thr, duk_get_top(thr));\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_trim(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 0);\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk_trim(thr, 0);\n\tDUK_ASSERT_TOP(thr, 1);\n\treturn 1;\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_hthread *thr) {\n\tduk_hstring *h_input;\n\tduk_size_t input_blen;\n\tduk_size_t result_len;\n\tduk_int_t count_signed;\n\tduk_uint_t count;\n\tconst duk_uint8_t *src;\n\tduk_uint8_t *buf;\n\tduk_uint8_t *p;\n\tduk_double_t d;\n#if !defined(DUK_USE_PREFER_SIZE)\n\tduk_size_t copy_size;\n\tduk_uint8_t *p_end;\n#endif\n\n\tDUK_ASSERT_TOP(thr, 1);\n\th_input = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_input != NULL);\n\tinput_blen = DUK_HSTRING_GET_BYTELEN(h_input);\n\n\t/* Count is ToNumber() coerced; +Infinity must be always rejected\n\t * (even if input string is zero length), as well as negative values\n\t * and -Infinity.  -Infinity doesn't require an explicit check\n\t * because duk_get_int() clamps it to DUK_INT_MIN which gets rejected\n\t * as a negative value (regardless of input string length).\n\t */\n\td = duk_to_number(thr, 0);\n\tif (duk_double_is_posinf(d)) {\n\t\tgoto fail_range;\n\t}\n\tcount_signed = duk_get_int(thr, 0);\n\tif (count_signed < 0) {\n\t\tgoto fail_range;\n\t}\n\tcount = (duk_uint_t) count_signed;\n\n\t/* Overflow check for result length. */\n\tresult_len = count * input_blen;\n\tif (count != 0 && result_len / count != input_blen) {\n\t\tgoto fail_range;\n\t}\n\n\t/* Temporary fixed buffer, later converted to string. */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, result_len);\n\tDUK_ASSERT(buf != NULL);\n\tsrc = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tDUK_ASSERT(src != NULL);\n\n#if defined(DUK_USE_PREFER_SIZE)\n\tp = buf;\n\twhile (count-- > 0) {\n\t\tduk_memcpy((void *) p, (const void *) src, input_blen);  /* copy size may be zero, but pointers are valid */\n\t\tp += input_blen;\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\t/* Take advantage of already copied pieces to speed up the process\n\t * especially for small repeated strings.\n\t */\n\tp = buf;\n\tp_end = p + result_len;\n\tcopy_size = input_blen;\n\tfor (;;) {\n\t\tduk_size_t remain = (duk_size_t) (p_end - p);\n\t\tDUK_DDD(DUK_DDDPRINT(\"remain=%ld, copy_size=%ld, input_blen=%ld, result_len=%ld\",\n\t\t                     (long) remain, (long) copy_size, (long) input_blen,\n\t\t                     (long) result_len));\n\t\tif (remain <= copy_size) {\n\t\t\t/* If result_len is zero, this case is taken and does\n\t\t\t * a zero size copy (with valid pointers).\n\t\t\t */\n\t\t\tduk_memcpy((void *) p, (const void *) src, remain);\n\t\t\tbreak;\n\t\t} else {\n\t\t\tduk_memcpy((void *) p, (const void *) src, copy_size);\n\t\t\tp += copy_size;\n\t\t}\n\n\t\tsrc = (const duk_uint8_t *) buf;  /* Use buf as source for larger copies. */\n\t\tcopy_size = (duk_size_t) (p - buf);\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n\t/* XXX: It would be useful to be able to create a duk_hstring with\n\t * a certain byte size whose data area wasn't initialized and which\n\t * wasn't in the string table yet.  This would allow a string to be\n\t * constructed directly without a buffer temporary and when it was\n\t * finished, it could be injected into the string table.  Currently\n\t * this isn't possible because duk_hstrings are only tracked by the\n\t * intern table (they are not in heap_allocated).\n\t */\n\n\tduk_buffer_to_string(thr, -1);  /* Safe if input is safe. */\n\treturn 1;\n\n fail_range:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_ES6 */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_locale_compare(duk_hthread *thr) {\n\tduk_hstring *h1;\n\tduk_hstring *h2;\n\tduk_size_t h1_len, h2_len, prefix_len;\n\tduk_small_int_t ret = 0;\n\tduk_small_int_t rc;\n\n\t/* The current implementation of localeCompare() is simply a codepoint\n\t * by codepoint comparison, implemented with a simple string compare\n\t * because UTF-8 should preserve codepoint ordering (assuming valid\n\t * shortest UTF-8 encoding).\n\t *\n\t * The specification requires that the return value must be related\n\t * to the sort order: e.g. negative means that 'this' comes before\n\t * 'that' in sort order.  We assume an ascending sort order.\n\t */\n\n\t/* XXX: could share code with duk_js_ops.c, duk_js_compare_helper */\n\n\th1 = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h1 != NULL);\n\n\th2 = duk_to_hstring(thr, 0);\n\tDUK_ASSERT(h2 != NULL);\n\n\th1_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1);\n\th2_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2);\n\tprefix_len = (h1_len <= h2_len ? h1_len : h2_len);\n\n\trc = (duk_small_int_t) duk_memcmp((const void *) DUK_HSTRING_GET_DATA(h1),\n\t                                  (const void *) DUK_HSTRING_GET_DATA(h2),\n\t                                  (size_t) prefix_len);\n\n\tif (rc < 0) {\n\t\tret = -1;\n\t\tgoto done;\n\t} else if (rc > 0) {\n\t\tret = 1;\n\t\tgoto done;\n\t}\n\n\t/* prefix matches, lengths matter now */\n\tif (h1_len > h2_len) {\n\t\tret = 1;\n\t\tgoto done;\n\t} else if (h1_len == h2_len) {\n\t\tDUK_ASSERT(ret == 0);\n\t\tgoto done;\n\t}\n\tret = -1;\n\tgoto done;\n\n done:\n\tduk_push_int(thr, (duk_int_t) ret);\n\treturn 1;\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_hthread *thr) {\n\tduk_int_t magic;\n\tduk_hstring *h;\n\tduk_hstring *h_search;\n\tduk_size_t blen_search;\n\tconst duk_uint8_t *p_cmp_start;\n\tduk_bool_t result;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\th_search = duk__str_tostring_notregexp(thr, 0);\n\tDUK_ASSERT(h_search != NULL);\n\n\tmagic = duk_get_current_magic(thr);\n\n\tp_cmp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tblen_search = DUK_HSTRING_GET_BYTELEN(h_search);\n\n\tif (duk_is_undefined(thr, 1)) {\n\t\tif (magic) {\n\t\t\tp_cmp_start = p_cmp_start + DUK_HSTRING_GET_BYTELEN(h) - blen_search;\n\t\t} else {\n\t\t\t/* p_cmp_start already OK */\n\t\t}\n\t} else {\n\t\tduk_int_t len;\n\t\tduk_int_t pos;\n\n\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= DUK_INT_MAX);\n\t\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\t\tpos = duk_to_int_clamped(thr, 1, 0, len);\n\t\tDUK_ASSERT(pos >= 0 && pos <= len);\n\n\t\tif (magic) {\n\t\t\tp_cmp_start -= blen_search;  /* Conceptually subtracted last, but do already here. */\n\t\t}\n\t\tDUK_ASSERT(pos >= 0 && pos <= len);\n\n\t\tp_cmp_start += duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) pos);\n\t}\n\n\t/* The main comparison can be done using a memcmp() rather than\n\t * doing codepoint comparisons: for CESU-8 strings there is a\n\t * canonical representation for every codepoint.  But we do need\n\t * to deal with the char/byte offset translation to find the\n\t * comparison range.\n\t */\n\n\tresult = 0;\n\tif (p_cmp_start >= DUK_HSTRING_GET_DATA(h) &&\n\t    (duk_size_t) (p_cmp_start - (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h)) + blen_search <= DUK_HSTRING_GET_BYTELEN(h)) {\n\t\tif (duk_memcmp((const void *) p_cmp_start,\n\t\t               (const void *) DUK_HSTRING_GET_DATA(h_search),\n\t\t               (size_t) blen_search) == 0) {\n\t\t\tresult = 1;\n\t\t}\n\t}\n\n\tduk_push_boolean(thr, result);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_includes(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_hstring *h_search;\n\tduk_int_t len;\n\tduk_int_t pos;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\th_search = duk__str_tostring_notregexp(thr, 0);\n\tDUK_ASSERT(h_search != NULL);\n\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\tpos = duk_to_int_clamped(thr, 1, 0, len);\n\tDUK_ASSERT(pos >= 0 && pos <= len);\n\n\tpos = duk__str_search_shared(thr, h, h_search, pos, 0 /*backwards*/);\n\tduk_push_boolean(thr, pos >= 0);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n#endif  /* DUK_USE_STRING_BUILTIN */\n/*\n *  Symbol built-in\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_constructor_shared(duk_hthread *thr) {\n\tconst duk_uint8_t *desc;\n\tduk_size_t len;\n\tduk_uint8_t *buf;\n\tduk_uint8_t *p;\n\tduk_int_t magic;\n\n\tmagic = duk_get_current_magic(thr);\n\tif (duk_is_undefined(thr, 0) && (magic == 0)) {\n\t\t/* Symbol() accepts undefined and empty string, but they are\n\t\t * treated differently.\n\t\t */\n\t\tdesc = NULL;\n\t\tlen = 0;\n\t} else {\n\t\t/* Symbol.for() coerces undefined to 'undefined' */\n\t\tdesc = (const duk_uint8_t *) duk_to_lstring(thr, 0, &len);\n\t}\n\n\t/* Maximum symbol data length:\n\t *   +1    initial byte (0x80 or 0x81)\n\t *   +len  description\n\t *   +1    0xff after description, before unique suffix\n\t *   +17   autogenerated unique suffix: 'ffffffff-ffffffff' is longest\n\t *   +1    0xff after unique suffix for symbols with undefined description\n\t */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer(thr, 1 + len + 1 + 17 + 1);\n\tDUK_ASSERT(buf != NULL);\n\tp = buf + 1;\n\tDUK_ASSERT(desc != NULL || len == 0);  /* may be NULL if len is 0 */\n\tduk_memcpy_unsafe((void *) p, (const void *) desc, len);\n\tp += len;\n\tif (magic == 0) {\n\t\t/* Symbol(): create unique symbol.  Use two 32-bit values\n\t\t * to avoid dependency on 64-bit types and 64-bit integer\n\t\t * formatting (at least for now).\n\t\t */\n\t\tif (++thr->heap->sym_counter[0] == 0) {\n\t\t\tthr->heap->sym_counter[1]++;\n\t\t}\n\t\tp += DUK_SPRINTF((char *) p, \"\\xFF\" \"%lx-%lx\",\n\t\t                 (unsigned long) thr->heap->sym_counter[1],\n\t\t                 (unsigned long) thr->heap->sym_counter[0]);\n\t\tif (desc == NULL) {\n\t\t\t/* Special case for 'undefined' description, trailing\n\t\t\t * 0xff distinguishes from empty string description,\n\t\t\t * but needs minimal special case handling elsewhere.\n\t\t\t */\n\t\t\t*p++ = 0xff;\n\t\t}\n\t\tbuf[0] = 0x81;\n\t} else {\n\t\t/* Symbol.for(): create a global symbol */\n\t\tbuf[0] = 0x80;\n\t}\n\n\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) (p - buf));\n\tDUK_DDD(DUK_DDDPRINT(\"created symbol: %!T\", duk_get_tval(thr, -1)));\n\treturn 1;\n}\n\nDUK_LOCAL duk_hstring *duk__auto_unbox_symbol(duk_hthread *thr, duk_tval *tv_arg) {\n\tduk_tval *tv;\n\tduk_hobject *h_obj;\n\tduk_hstring *h_str;\n\n\tDUK_ASSERT(tv_arg != NULL);\n\n\t/* XXX: add internal helper: duk_auto_unbox_tval(thr, tv, mask); */\n\t/* XXX: add internal helper: duk_auto_unbox(thr, tv, idx); */\n\n\ttv = tv_arg;\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_obj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_SYMBOL) {\n\t\t\ttv = duk_hobject_get_internal_value_tval_ptr(thr->heap, h_obj);\n\t\t\tif (tv == NULL) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t} else {\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\tif (!DUK_TVAL_IS_STRING(tv)) {\n\t\treturn NULL;\n\t}\n\th_str = DUK_TVAL_GET_STRING(tv);\n\tDUK_ASSERT(h_str != NULL);\n\n\t/* Here symbol is more expected than not. */\n\tif (DUK_UNLIKELY(!DUK_HSTRING_HAS_SYMBOL(h_str))) {\n\t\treturn NULL;\n\t}\n\n\treturn h_str;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_tostring_shared(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\th_str = duk__auto_unbox_symbol(thr, DUK_HTHREAD_THIS_PTR(thr));\n\tif (h_str == NULL) {\n\t\treturn DUK_RET_TYPE_ERROR;\n\t}\n\n\tif (duk_get_current_magic(thr) == 0) {\n\t\t/* .toString() */\n\t\tduk_push_symbol_descriptive_string(thr, h_str);\n\t} else {\n\t\t/* .valueOf() */\n\t\tduk_push_hstring(thr, h_str);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_key_for(duk_hthread *thr) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p;\n\n\t/* Argument must be a symbol but not checked here.  The initial byte\n\t * check will catch non-symbol strings.\n\t */\n\th = duk_require_hstring(thr, 0);\n\tDUK_ASSERT(h != NULL);\n\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tDUK_ASSERT(p != NULL);\n\n\t/* Even for zero length strings there's at least one NUL byte so\n\t * we can safely check the initial byte.\n\t */\n\tif (p[0] == 0x80) {\n\t\t/* Global symbol, return its key (bytes just after the initial byte). */\n\t\tduk_push_lstring(thr, (const char *) (p + 1), (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h) - 1));\n\t\treturn 1;\n\t} else if (p[0] == 0x81 || p[0] == 0x82 || p[0] == 0xff) {\n\t\t/* Local symbol or hidden symbol, return undefined. */\n\t\treturn 0;\n\t}\n\n\t/* Covers normal strings and unknown initial bytes. */\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_toprimitive(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\th_str = duk__auto_unbox_symbol(thr, DUK_HTHREAD_THIS_PTR(thr));\n\tif (h_str == NULL) {\n\t\treturn DUK_RET_TYPE_ERROR;\n\t}\n\tduk_push_hstring(thr, h_str);\n\treturn 1;\n}\n\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n/*\n *  Thread builtins\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Constructor\n */\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_constructor(duk_hthread *thr) {\n\tduk_hthread *new_thr;\n\tduk_hobject *func;\n\n\t/* Check that the argument is callable; this is not 100% because we\n\t * don't allow native functions to be a thread's initial function.\n\t * Resume will reject such functions in any case.\n\t */\n\t/* XXX: need a duk_require_func_promote_lfunc() */\n\tfunc = duk_require_hobject_promote_lfunc(thr, 0);\n\tDUK_ASSERT(func != NULL);\n\tduk_require_callable(thr, 0);\n\n\tduk_push_thread(thr);\n\tnew_thr = (duk_hthread *) duk_known_hobject(thr, -1);\n\tnew_thr->state = DUK_HTHREAD_STATE_INACTIVE;\n\n\t/* push initial function call to new thread stack; this is\n\t * picked up by resume().\n\t */\n\tduk_push_hobject(new_thr, func);\n\n\treturn 1;  /* return thread */\n}\n#endif\n\n/*\n *  Resume a thread.\n *\n *  The thread must be in resumable state, either (a) new thread which hasn't\n *  yet started, or (b) a thread which has previously yielded.  This method\n *  must be called from an ECMAScript function.\n *\n *  Args:\n *    - thread\n *    - value\n *    - isError (defaults to false)\n *\n *  Note: yield and resume handling is currently asymmetric.\n */\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) {\n\tduk_hthread *thr = (duk_hthread *) ctx;\n\tduk_hthread *thr_resume;\n\tduk_hobject *caller_func;\n\tduk_small_uint_t is_error;\n\n\tDUK_DDD(DUK_DDDPRINT(\"Duktape.Thread.resume(): thread=%!T, value=%!T, is_error=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1),\n\t                     (duk_tval *) duk_get_tval(thr, 2)));\n\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\tDUK_ASSERT(thr->heap->curr_thread == thr);\n\n\tthr_resume = duk_require_hthread(thr, 0);\n\tDUK_ASSERT(duk_get_top(thr) == 3);\n\tis_error = (duk_small_uint_t) duk_to_boolean_top_pop(thr);\n\tDUK_ASSERT(duk_get_top(thr) == 2);\n\n\t/* [ thread value ] */\n\n\t/*\n\t *  Thread state and calling context checks\n\t */\n\n\tif (thr->callstack_top < 2) {\n\t\tDUK_DD(DUK_DDPRINT(\"resume state invalid: callstack should contain at least 2 entries (caller and Duktape.Thread.resume)\"));\n\t\tgoto state_error;\n\t}\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);  /* us */\n\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL);  /* caller */\n\n\tcaller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent);\n\tif (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) {\n\t\tDUK_DD(DUK_DDPRINT(\"resume state invalid: caller must be ECMAScript code\"));\n\t\tgoto state_error;\n\t}\n\n\t/* Note: there is no requirement that: 'thr->callstack_preventcount == 1'\n\t * like for yield.\n\t */\n\n\tif (thr_resume->state != DUK_HTHREAD_STATE_INACTIVE &&\n\t    thr_resume->state != DUK_HTHREAD_STATE_YIELDED) {\n\t\tDUK_DD(DUK_DDPRINT(\"resume state invalid: target thread must be INACTIVE or YIELDED\"));\n\t\tgoto state_error;\n\t}\n\n\tDUK_ASSERT(thr_resume->state == DUK_HTHREAD_STATE_INACTIVE ||\n\t           thr_resume->state == DUK_HTHREAD_STATE_YIELDED);\n\n\t/* Further state-dependent pre-checks */\n\n\tif (thr_resume->state == DUK_HTHREAD_STATE_YIELDED) {\n\t\t/* no pre-checks now, assume a previous yield() has left things in\n\t\t * tip-top shape (longjmp handler will assert for these).\n\t\t */\n\t} else {\n\t\tduk_hobject *h_fun;\n\n\t\tDUK_ASSERT(thr_resume->state == DUK_HTHREAD_STATE_INACTIVE);\n\n\t\t/* The initial function must be an ECMAScript function (but\n\t\t * can be bound).  We must make sure of that before we longjmp\n\t\t * because an error in the RESUME handler call processing will\n\t\t * not be handled very cleanly.\n\t\t */\n\t\tif ((thr_resume->callstack_top != 0) ||\n\t\t    (thr_resume->valstack_top - thr_resume->valstack != 1)) {\n\t\t\tgoto state_error;\n\t\t}\n\n\t\tduk_push_tval(thr, DUK_GET_TVAL_NEGIDX(thr_resume, -1));\n\t\tduk_resolve_nonbound_function(thr);\n\t\th_fun = duk_require_hobject(thr, -1);  /* reject lightfuncs on purpose */\n\t\tif (!DUK_HOBJECT_IS_CALLABLE(h_fun) || !DUK_HOBJECT_IS_COMPFUNC(h_fun)) {\n\t\t\tgoto state_error;\n\t\t}\n\t\tduk_pop(thr);\n\t}\n\n#if 0\n\t/* This check would prevent a heap destruction time finalizer from\n\t * launching a coroutine, which would ensure that during finalization\n\t * 'thr' would always equal heap_thread.  Normal runtime finalizers\n\t * run with ms_running == 0, i.e. outside mark-and-sweep.  See GH-2030.\n\t */\n\tif (thr->heap->ms_running) {\n\t\tDUK_D(DUK_DPRINT(\"refuse Duktape.Thread.resume() when ms_running != 0\"));\n\t\tgoto state_error;\n\t}\n#endif\n\n\t/*\n\t *  The error object has been augmented with a traceback and other\n\t *  info from its creation point -- usually another thread.  The\n\t *  error handler is called here right before throwing, but it also\n\t *  runs in the resumer's thread.  It might be nice to get a traceback\n\t *  from the resumee but this is not the case now.\n\t */\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\tif (is_error) {\n\t\tDUK_ASSERT_TOP(thr, 2);  /* value (error) is at stack top */\n\t\tduk_err_augment_error_throw(thr);  /* in resumer's context */\n\t}\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\tif (is_error) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"RESUME ERROR: thread=%!T, value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\t} else if (thr_resume->state == DUK_HTHREAD_STATE_YIELDED) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"RESUME NORMAL: thread=%!T, value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"RESUME INITIAL: thread=%!T, value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\t}\n#endif\n\n\tthr->heap->lj.type = DUK_LJ_TYPE_RESUME;\n\n\t/* lj value2: thread */\n\tDUK_ASSERT(thr->valstack_bottom < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value2, &thr->valstack_bottom[0]);  /* side effects */\n\n\t/* lj value1: value */\n\tDUK_ASSERT(thr->valstack_bottom + 1 < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, &thr->valstack_bottom[1]);  /* side effects */\n\tDUK_TVAL_CHKFAST_INPLACE_SLOW(&thr->heap->lj.value1);\n\n\tthr->heap->lj.iserror = is_error;\n\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* call is from executor, so we know we have a jmpbuf */\n\tduk_err_longjmp(thr);  /* execution resumes in bytecode executor */\n\tDUK_UNREACHABLE();\n\t/* Never here, fall through to error (from compiler point of view). */\n\n state_error:\n\tDUK_DCERROR_TYPE_INVALID_STATE(thr);\n}\n#endif\n\n/*\n *  Yield the current thread.\n *\n *  The thread must be in yieldable state: it must have a resumer, and there\n *  must not be any yield-preventing calls (native calls and constructor calls,\n *  currently) in the thread's call stack (otherwise a resume would not be\n *  possible later).  This method must be called from an ECMAScript function.\n *\n *  Args:\n *    - value\n *    - isError (defaults to false)\n *\n *  Note: yield and resume handling is currently asymmetric.\n */\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_hthread *thr) {\n\tduk_hobject *caller_func;\n\tduk_small_uint_t is_error;\n\n\tDUK_DDD(DUK_DDDPRINT(\"Duktape.Thread.yield(): value=%!T, is_error=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\tDUK_ASSERT(thr->heap->curr_thread == thr);\n\n\tDUK_ASSERT(duk_get_top(thr) == 2);\n\tis_error = (duk_small_uint_t) duk_to_boolean_top_pop(thr);\n\tDUK_ASSERT(duk_get_top(thr) == 1);\n\n\t/* [ value ] */\n\n\t/*\n\t *  Thread state and calling context checks\n\t */\n\n\tif (!thr->resumer) {\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: current thread must have a resumer\"));\n\t\tgoto state_error;\n\t}\n\tDUK_ASSERT(thr->resumer->state == DUK_HTHREAD_STATE_RESUMED);\n\n\tif (thr->callstack_top < 2) {\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: callstack should contain at least 2 entries (caller and Duktape.Thread.yield)\"));\n\t\tgoto state_error;\n\t}\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);  /* us */\n\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL);  /* caller */\n\n\tcaller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent);\n\tif (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) {\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: caller must be ECMAScript code\"));\n\t\tgoto state_error;\n\t}\n\n\tDUK_ASSERT(thr->callstack_preventcount >= 1);  /* should never be zero, because we (Duktape.Thread.yield) are on the stack */\n\tif (thr->callstack_preventcount != 1) {\n\t\t/* Note: the only yield-preventing call is Duktape.Thread.yield(), hence check for 1, not 0 */\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: there must be no yield-preventing calls in current thread callstack (preventcount is %ld)\",\n\t\t                   (long) thr->callstack_preventcount));\n\t\tgoto state_error;\n\t}\n\n\t/*\n\t *  The error object has been augmented with a traceback and other\n\t *  info from its creation point -- usually the current thread.\n\t *  The error handler, however, is called right before throwing\n\t *  and runs in the yielder's thread.\n\t */\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\tif (is_error) {\n\t\tDUK_ASSERT_TOP(thr, 1);  /* value (error) is at stack top */\n\t\tduk_err_augment_error_throw(thr);  /* in yielder's context */\n\t}\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\tif (is_error) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"YIELD ERROR: value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0)));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"YIELD NORMAL: value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0)));\n\t}\n#endif\n\n\t/*\n\t *  Process yield\n\t *\n\t *  After longjmp(), processing continues in bytecode executor longjmp\n\t *  handler, which will e.g. update thr->resumer to NULL.\n\t */\n\n\tthr->heap->lj.type = DUK_LJ_TYPE_YIELD;\n\n\t/* lj value1: value */\n\tDUK_ASSERT(thr->valstack_bottom < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, &thr->valstack_bottom[0]);  /* side effects */\n\tDUK_TVAL_CHKFAST_INPLACE_SLOW(&thr->heap->lj.value1);\n\n\tthr->heap->lj.iserror = is_error;\n\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* call is from executor, so we know we have a jmpbuf */\n\tduk_err_longjmp(thr);  /* execution resumes in bytecode executor */\n\tDUK_UNREACHABLE();\n\t/* Never here, fall through to error (from compiler point of view). */\n\n state_error:\n\tDUK_DCERROR_TYPE_INVALID_STATE(thr);\n}\n#endif\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_current(duk_hthread *thr) {\n\tduk_push_current_thread(thr);\n\treturn 1;\n}\n#endif\n/*\n *  Type error thrower, E5 Section 13.2.3.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL duk_ret_t duk_bi_type_error_thrower(duk_hthread *thr) {\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n/*\n *  Fixed buffer helper useful for debugging, requires no allocation\n *  which is critical for debugging.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_DEBUG)\n\nDUK_INTERNAL void duk_fb_put_bytes(duk_fixedbuffer *fb, const duk_uint8_t *buffer, duk_size_t length) {\n\tduk_size_t avail;\n\tduk_size_t copylen;\n\n\tavail = (fb->offset >= fb->length ? (duk_size_t) 0 : (duk_size_t) (fb->length - fb->offset));\n\tif (length > avail) {\n\t\tcopylen = avail;\n\t\tfb->truncated = 1;\n\t} else {\n\t\tcopylen = length;\n\t}\n\tduk_memcpy_unsafe(fb->buffer + fb->offset, buffer, copylen);\n\tfb->offset += copylen;\n}\n\nDUK_INTERNAL void duk_fb_put_byte(duk_fixedbuffer *fb, duk_uint8_t x) {\n\tduk_fb_put_bytes(fb, (const duk_uint8_t *) &x, 1);\n}\n\nDUK_INTERNAL void duk_fb_put_cstring(duk_fixedbuffer *fb, const char *x) {\n\tduk_fb_put_bytes(fb, (const duk_uint8_t *) x, (duk_size_t) DUK_STRLEN(x));\n}\n\nDUK_INTERNAL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...) {\n\tduk_size_t avail;\n\tva_list ap;\n\n\tva_start(ap, fmt);\n\tavail = (fb->offset >= fb->length ? (duk_size_t) 0 : (duk_size_t) (fb->length - fb->offset));\n\tif (avail > 0) {\n\t\tduk_int_t res = (duk_int_t) DUK_VSNPRINTF((char *) (fb->buffer + fb->offset), avail, fmt, ap);\n\t\tif (res < 0) {\n\t\t\t/* error */\n\t\t} else if ((duk_size_t) res >= avail) {\n\t\t\t/* (maybe) truncated */\n\t\t\tfb->offset += avail;\n\t\t\tif ((duk_size_t) res > avail) {\n\t\t\t\t/* actual chars dropped (not just NUL term) */\n\t\t\t\tfb->truncated = 1;\n\t\t\t}\n\t\t} else {\n\t\t\t/* normal */\n\t\t\tfb->offset += (duk_size_t) res;\n\t\t}\n\t}\n\tva_end(ap);\n}\n\nDUK_INTERNAL void duk_fb_put_funcptr(duk_fixedbuffer *fb, duk_uint8_t *fptr, duk_size_t fptr_size) {\n\tchar buf[64+1];\n\tduk_debug_format_funcptr(buf, sizeof(buf), fptr, fptr_size);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\tduk_fb_put_cstring(fb, buf);\n}\n\nDUK_INTERNAL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb) {\n\treturn (fb->offset >= fb->length);\n}\n\n#endif  /* DUK_USE_DEBUG */\n/*\n *  Custom formatter for debug printing, allowing Duktape specific data\n *  structures (such as tagged values and heap objects) to be printed with\n *  a nice format string.  Because debug printing should not affect execution\n *  state, formatting here must be independent of execution (see implications\n *  below) and must not allocate memory.\n *\n *  Custom format tags begin with a '%!' to safely distinguish them from\n *  standard format tags.  The following conversions are supported:\n *\n *     %!T    tagged value (duk_tval *)\n *     %!O    heap object (duk_heaphdr *)\n *     %!I    decoded bytecode instruction\n *     %!X    bytecode instruction opcode name (arg is long)\n *     %!C    catcher (duk_catcher *)\n *     %!A    activation (duk_activation *)\n *\n *  Everything is serialized in a JSON-like manner.  The default depth is one\n *  level, internal prototype is not followed, and internal properties are not\n *  serialized.  The following modifiers change this behavior:\n *\n *     @      print pointers\n *     #      print binary representations (where applicable)\n *     d      deep traversal of own properties (not prototype)\n *     p      follow prototype chain (useless without 'd')\n *     i      include internal properties (other than prototype)\n *     x      hexdump buffers\n *     h      heavy formatting\n *\n *  For instance, the following serializes objects recursively, but does not\n *  follow the prototype chain nor print internal properties: \"%!dO\".\n *\n *  Notes:\n *\n *    * Standard snprintf return value semantics seem to vary.  This\n *      implementation returns the number of bytes it actually wrote\n *      (excluding the null terminator).  If retval == buffer size,\n *      output was truncated (except for corner cases).\n *\n *    * Output format is intentionally different from ECMAScript\n *      formatting requirements, as formatting here serves debugging\n *      of internals.\n *\n *    * Depth checking (and updating) is done in each type printer\n *      separately, to allow them to call each other freely.\n *\n *    * Some pathological structures might take ages to print (e.g.\n *      self recursion with 100 properties pointing to the object\n *      itself).  To guard against these, each printer also checks\n *      whether the output buffer is full; if so, early exit.\n *\n *    * Reference loops are detected using a loop stack.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_DEBUG)\n\n/* #include stdio.h -> already included */\n/* #include stdarg.h -> already included */\n#include <string.h>\n\n/* list of conversion specifiers that terminate a format tag;\n * this is unfortunately guesswork.\n */\n#define DUK__ALLOWED_STANDARD_SPECIFIERS  \"diouxXeEfFgGaAcsCSpnm\"\n\n/* maximum length of standard format tag that we support */\n#define DUK__MAX_FORMAT_TAG_LENGTH  32\n\n/* heapobj recursion depth when deep printing is selected */\n#define DUK__DEEP_DEPTH_LIMIT  8\n\n/* maximum recursion depth for loop detection stacks */\n#define DUK__LOOP_STACK_DEPTH  256\n\n/* must match bytecode defines now; build autogenerate? */\nDUK_LOCAL const char * const duk__bc_optab[256] = {\n\t\"LDREG\", \"STREG\", \"JUMP\", \"LDCONST\", \"LDINT\", \"LDINTX\", \"LDTHIS\", \"LDUNDEF\",\n\t\"LDNULL\", \"LDTRUE\", \"LDFALSE\", \"GETVAR\", \"BNOT\", \"LNOT\", \"UNM\", \"UNP\",\n\t\"EQ_RR\", \"EQ_CR\", \"EQ_RC\", \"EQ_CC\", \"NEQ_RR\", \"NEQ_CR\", \"NEQ_RC\", \"NEQ_CC\",\n\t\"SEQ_RR\", \"SEQ_CR\", \"SEQ_RC\", \"SEQ_CC\", \"SNEQ_RR\", \"SNEQ_CR\", \"SNEQ_RC\", \"SNEQ_CC\",\n\n\t\"GT_RR\", \"GT_CR\", \"GT_RC\", \"GT_CC\", \"GE_RR\", \"GE_CR\", \"GE_RC\", \"GE_CC\",\n\t\"LT_RR\", \"LT_CR\", \"LT_RC\", \"LT_CC\", \"LE_RR\", \"LE_CR\", \"LE_RC\", \"LE_CC\",\n\t\"IFTRUE_R\", \"IFTRUE_C\", \"IFFALSE_R\", \"IFFALSE_C\", \"ADD_RR\", \"ADD_CR\", \"ADD_RC\", \"ADD_CC\",\n\t\"SUB_RR\", \"SUB_CR\", \"SUB_RC\", \"SUB_CC\", \"MUL_RR\", \"MUL_CR\", \"MUL_RC\", \"MUL_CC\",\n\n\t\"DIV_RR\", \"DIV_CR\", \"DIV_RC\", \"DIV_CC\", \"MOD_RR\", \"MOD_CR\", \"MOD_RC\", \"MOD_CC\",\n\t\"EXP_RR\", \"EXP_CR\", \"EXP_RC\", \"EXP_CC\", \"BAND_RR\", \"BAND_CR\", \"BAND_RC\", \"BAND_CC\",\n\t\"BOR_RR\", \"BOR_CR\", \"BOR_RC\", \"BOR_CC\", \"BXOR_RR\", \"BXOR_CR\", \"BXOR_RC\", \"BXOR_CC\",\n\t\"BASL_RR\", \"BASL_CR\", \"BASL_RC\", \"BASL_CC\", \"BLSR_RR\", \"BLSR_CR\", \"BLSR_RC\", \"BLSR_CC\",\n\n\t\"BASR_RR\", \"BASR_CR\", \"BASR_RC\", \"BASR_CC\", \"INSTOF_RR\", \"INSTOF_CR\", \"INSTOF_RC\", \"INSTOF_CC\",\n\t\"IN_RR\", \"IN_CR\", \"IN_RC\", \"IN_CC\", \"GETPROP_RR\", \"GETPROP_CR\", \"GETPROP_RC\", \"GETPROP_CC\",\n\t\"PUTPROP_RR\", \"PUTPROP_CR\", \"PUTPROP_RC\", \"PUTPROP_CC\", \"DELPROP_RR\", \"DELPROP_CR\", \"DELPROP_RC\", \"DELPROP_CC\",\n\t\"PREINCR\", \"PREDECR\", \"POSTINCR\", \"POSTDECR\", \"PREINCV\", \"PREDECV\", \"POSTINCV\", \"POSTDECV\",\n\n\t\"PREINCP_RR\", \"PREINCP_CR\", \"PREINCP_RC\", \"PREINCP_CC\", \"PREDECP_RR\", \"PREDECP_CR\", \"PREDECP_RC\", \"PREDECP_CC\",\n\t\"POSTINCP_RR\", \"POSTINCP_CR\", \"POSTINCP_RC\", \"POSTINCP_CC\", \"POSTDECP_RR\", \"POSTDECP_CR\", \"POSTDECP_RC\", \"POSTDECP_CC\",\n\t\"DECLVAR_RR\", \"DECLVAR_CR\", \"DECLVAR_RC\", \"DECLVAR_CC\", \"REGEXP_RR\", \"REGEXP_RC\", \"REGEXP_CR\", \"REGEXP_CC\",\n\t\"CLOSURE\", \"TYPEOF\", \"TYPEOFID\", \"PUTVAR\", \"DELVAR\", \"RETREG\", \"RETUNDEF\", \"RETCONST\",\n\n\t\"RETCONSTN\", \"LABEL\", \"ENDLABEL\", \"BREAK\", \"CONTINUE\", \"TRYCATCH\", \"ENDTRY\", \"ENDCATCH\",\n\t\"ENDFIN\", \"THROW\", \"INVLHS\", \"CSREG\", \"CSVAR_RR\", \"CSVAR_CR\", \"CSVAR_RC\", \"CSVAR_CC\",\n\t\"CALL0\", \"CALL1\", \"CALL2\", \"CALL3\", \"CALL4\", \"CALL5\", \"CALL6\", \"CALL7\",\n\t\"CALL8\", \"CALL9\", \"CALL10\", \"CALL11\", \"CALL12\", \"CALL13\", \"CALL14\", \"CALL15\",\n\n\t\"NEWOBJ\", \"NEWARR\", \"MPUTOBJ\", \"MPUTOBJI\", \"INITSET\", \"INITGET\", \"MPUTARR\", \"MPUTARRI\",\n\t\"SETALEN\", \"INITENUM\", \"NEXTENUM\", \"NEWTARGET\", \"DEBUGGER\", \"NOP\", \"INVALID\", \"UNUSED207\",\n\t\"GETPROPC_RR\", \"GETPROPC_CR\", \"GETPROPC_RC\", \"GETPROPC_CC\", \"UNUSED212\", \"UNUSED213\", \"UNUSED214\", \"UNUSED215\",\n\t\"UNUSED216\", \"UNUSED217\", \"UNUSED218\", \"UNUSED219\", \"UNUSED220\", \"UNUSED221\", \"UNUSED222\", \"UNUSED223\",\n\n\t\"UNUSED224\", \"UNUSED225\", \"UNUSED226\", \"UNUSED227\", \"UNUSED228\", \"UNUSED229\", \"UNUSED230\", \"UNUSED231\",\n\t\"UNUSED232\", \"UNUSED233\", \"UNUSED234\", \"UNUSED235\", \"UNUSED236\", \"UNUSED237\", \"UNUSED238\", \"UNUSED239\",\n\t\"UNUSED240\", \"UNUSED241\", \"UNUSED242\", \"UNUSED243\", \"UNUSED244\", \"UNUSED245\", \"UNUSED246\", \"UNUSED247\",\n\t\"UNUSED248\", \"UNUSED249\", \"UNUSED250\", \"UNUSED251\", \"UNUSED252\", \"UNUSED253\", \"UNUSED254\", \"UNUSED255\"\n};\n\ntypedef struct duk__dprint_state duk__dprint_state;\nstruct duk__dprint_state {\n\tduk_fixedbuffer *fb;\n\n\t/* loop_stack_index could be perhaps be replaced by 'depth', but it's nice\n\t * to not couple these two mechanisms unnecessarily.\n\t */\n\tduk_hobject *loop_stack[DUK__LOOP_STACK_DEPTH];\n\tduk_int_t loop_stack_index;\n\tduk_int_t loop_stack_limit;\n\n\tduk_int_t depth;\n\tduk_int_t depth_limit;\n\n\tduk_bool_t pointer;\n\tduk_bool_t heavy;\n\tduk_bool_t binary;\n\tduk_bool_t follow_proto;\n\tduk_bool_t internal;\n\tduk_bool_t hexdump;\n};\n\n/* helpers */\nDUK_LOCAL_DECL void duk__print_hstring(duk__dprint_state *st, duk_hstring *k, duk_bool_t quotes);\nDUK_LOCAL_DECL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h);\nDUK_LOCAL_DECL void duk__print_hbuffer(duk__dprint_state *st, duk_hbuffer *h);\nDUK_LOCAL_DECL void duk__print_tval(duk__dprint_state *st, duk_tval *tv);\nDUK_LOCAL_DECL void duk__print_instr(duk__dprint_state *st, duk_instr_t ins);\nDUK_LOCAL_DECL void duk__print_heaphdr(duk__dprint_state *st, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__print_shared_heaphdr(duk__dprint_state *st, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__print_shared_heaphdr_string(duk__dprint_state *st, duk_heaphdr_string *h);\n\nDUK_LOCAL void duk__print_shared_heaphdr(duk__dprint_state *st, duk_heaphdr *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"(%p)\", (void *) h);\n\t}\n\n\tif (!h) {\n\t\treturn;\n\t}\n\n\tif (st->binary) {\n\t\tduk_size_t i;\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET);\n\t\tfor (i = 0; i < (duk_size_t) sizeof(*h); i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) ((duk_uint8_t *)h)[i]);\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET);\n\t}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)  /* currently implicitly also DUK_USE_DOUBLE_LINKED_HEAP */\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_next=%p,h_prev=%p,h_refcount=%lu,h_flags=%08lx,type=%ld,\"\n\t\t               \"reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (void *) DUK_HEAPHDR_GET_NEXT(NULL, h),\n\t\t               (void *) DUK_HEAPHDR_GET_PREV(NULL, h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS(h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE(h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED(h) ? 1 : 0));\n\t}\n#else\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_next=%p,h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (void *) DUK_HEAPHDR_GET_NEXT(NULL, h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS(h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE(h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED(h) ? 1 : 0));\n\t}\n#endif\n}\n\nDUK_LOCAL void duk__print_shared_heaphdr_string(duk__dprint_state *st, duk_heaphdr_string *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"(%p)\", (void *) h);\n\t}\n\n\tif (!h) {\n\t\treturn;\n\t}\n\n\tif (st->binary) {\n\t\tduk_size_t i;\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET);\n\t\tfor (i = 0; i < (duk_size_t) sizeof(*h); i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) ((duk_uint8_t *)h)[i]);\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET);\n\t}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_refcount=%lu,h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (unsigned long) DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) h) ? 1 : 0));\n\t}\n#else\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) h) ? 1 : 0));\n\t}\n#endif\n}\n\nDUK_LOCAL void duk__print_hstring(duk__dprint_state *st, duk_hstring *h, duk_bool_t quotes) {\n\tduk_fixedbuffer *fb = st->fb;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\n\t/* terminal type: no depth check */\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tduk__print_shared_heaphdr_string(st, &h->hdr);\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tp = DUK_HSTRING_GET_DATA(h);\n\tp_end = p + DUK_HSTRING_GET_BYTELEN(h);\n\n\tif (p_end > p && p[0] == DUK_ASC_UNDERSCORE) {\n\t\t/* If property key begins with underscore, encode it with\n\t\t * forced quotes (e.g. \"_Foo\") to distinguish it from encoded\n\t\t * internal properties (e.g. \\x82Bar -> _Bar).\n\t\t */\n\t\tquotes = 1;\n\t}\n\n\tif (quotes) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_DOUBLEQUOTE);\n\t}\n\twhile (p < p_end) {\n\t\tduk_uint8_t ch = *p++;\n\n\t\t/* two special escapes: '\\' and '\"', other printables as is */\n\t\tif (ch == '\\\\') {\n\t\t\tduk_fb_sprintf(fb, \"\\\\\\\\\");\n\t\t} else if (ch == '\"') {\n\t\t\tduk_fb_sprintf(fb, \"\\\\\\\"\");\n\t\t} else if (ch >= 0x20 && ch <= 0x7e) {\n\t\t\tduk_fb_put_byte(fb, ch);\n\t\t} else if (ch == 0x82 && !quotes) {\n\t\t\t/* encode \\x82Bar as _Bar if no quotes are\n\t\t\t * applied, this is for readable internal keys.\n\t\t\t */\n\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_UNDERSCORE);\n\t\t} else {\n\t\t\tduk_fb_sprintf(fb, \"\\\\x%02lx\", (unsigned long) ch);\n\t\t}\n\t}\n\tif (quotes) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_DOUBLEQUOTE);\n\t}\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* XXX: limit to quoted strings only, to save keys from being cluttered? */\n\tduk_fb_sprintf(fb, \"/%lu\", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(&h->hdr));\n#endif\n}\n\n#define DUK__COMMA()  do { \\\n\t\tif (first) { \\\n\t\t\tfirst = 0; \\\n\t\t} else { \\\n\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COMMA); \\\n\t\t} \\\n\t} while (0)\n\nDUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\tduk_uint_fast32_t i;\n\tduk_tval *tv;\n\tduk_hstring *key;\n\tduk_bool_t first = 1;\n\tconst char *brace1 = \"{\";\n\tconst char *brace2 = \"}\";\n\tduk_bool_t pushed_loopstack = 0;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tduk__print_shared_heaphdr(st, &h->hdr);\n\n\tif (h && DUK_HOBJECT_HAS_ARRAY_PART(h)) {\n\t\tbrace1 = \"[\";\n\t\tbrace2 = \"]\";\n\t}\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\tgoto finished;\n\t}\n\n\tif (st->depth >= st->depth_limit) {\n\t\tconst char *subtype = \"generic\";\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\t\tsubtype = \"compfunc\";\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\t\tsubtype = \"natfunc\";\n\t\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\t\tsubtype = \"thread\";\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\tsubtype = \"bufobj\";\n\t\t} else if (DUK_HOBJECT_IS_ARRAY(h)) {\n\t\t\tsubtype = \"array\";\n\t\t}\n\t\tduk_fb_sprintf(fb, \"%sobject/%s %p%s\", (const char *) brace1, subtype, (void *) h, (const char *) brace2);\n\t\treturn;\n\t}\n\n\tfor (i = 0; i < (duk_uint_fast32_t) st->loop_stack_index; i++) {\n\t\tif (st->loop_stack[i] == h) {\n\t\t\tduk_fb_sprintf(fb, \"%sLOOP:%p%s\", (const char *) brace1, (void *) h, (const char *) brace2);\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/* after this, return paths should 'goto finished' for decrement */\n\tst->depth++;\n\n\tif (st->loop_stack_index >= st->loop_stack_limit) {\n\t\tduk_fb_sprintf(fb, \"%sOUT-OF-LOOP-STACK%s\", (const char *) brace1, (const char *) brace2);\n\t\tgoto finished;\n\t}\n\tst->loop_stack[st->loop_stack_index++] = h;\n\tpushed_loopstack = 1;\n\n\t/*\n\t *  Notation: double underscore used for internal properties which are not\n\t *  stored in the property allocation (e.g. '__valstack').\n\t */\n\n\tduk_fb_put_cstring(fb, brace1);\n\n\tif (DUK_HOBJECT_GET_PROPS(NULL, h)) {\n\t\tduk_uint32_t a_limit;\n\n\t\ta_limit = DUK_HOBJECT_GET_ASIZE(h);\n\t\tif (st->internal) {\n\t\t\t/* dump all allocated entries, unused entries print as 'unused',\n\t\t\t * note that these may extend beyond current 'length' and look\n\t\t\t * a bit funny.\n\t\t\t */\n\t\t} else {\n\t\t\t/* leave out trailing 'unused' elements */\n\t\t\twhile (a_limit > 0) {\n\t\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(NULL, h, a_limit - 1);\n\t\t\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ta_limit--;\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < a_limit; i++) {\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(NULL, h, i);\n\t\t\tDUK__COMMA();\n\t\t\tduk__print_tval(st, tv);\n\t\t}\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(NULL, h, i);\n\t\t\tif (!key) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!st->internal && DUK_HSTRING_HAS_HIDDEN(key)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tDUK__COMMA();\n\t\t\tduk__print_hstring(st, key, 0);\n\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COLON);\n\t\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(NULL, h, i)) {\n\t\t\t\tduk_fb_sprintf(fb, \"[get:%p,set:%p]\",\n\t\t\t\t               (void *) DUK_HOBJECT_E_GET_VALUE(NULL, h, i).a.get,\n\t\t\t\t               (void *) DUK_HOBJECT_E_GET_VALUE(NULL, h, i).a.set);\n\t\t\t} else {\n\t\t\t\ttv = &DUK_HOBJECT_E_GET_VALUE(NULL, h, i).v;\n\t\t\t\tduk__print_tval(st, tv);\n\t\t\t}\n\t\t\tif (st->heavy) {\n\t\t\t\tduk_fb_sprintf(fb, \"<%02lx>\", (unsigned long) DUK_HOBJECT_E_GET_FLAGS(NULL, h, i));\n\t\t\t}\n\t\t}\n\t}\n\tif (st->internal) {\n\t\tif (DUK_HOBJECT_IS_ARRAY(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__array:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXTENSIBLE(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__extensible:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_CONSTRUCTABLE(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__constructable:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__boundfunc:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_COMPFUNC(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__compfunc:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NATFUNC(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__natfunc:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_BUFOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__bufobj:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_IS_THREAD(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__thread:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_ARRAY_PART(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__array_part:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_STRICT(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__strict:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NOTAIL(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__notail:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NEWENV(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__newenv:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NAMEBINDING(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__namebinding:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_CREATEARGS(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__createargs:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_array:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_stringobj:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_arguments:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_bufobj:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_proxyobj:true\");\n\t\t}\n\t}\n\n\tif (st->internal && DUK_HOBJECT_IS_ARRAY(h)) {\n\t\tduk_harray *a = (duk_harray *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__length:%ld\", (long) a->length);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__length_nonwritable:%ld\", (long) a->length_nonwritable);\n\t} else if (st->internal && DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__data:\");\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(NULL, f));\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__lexenv:\"); duk__print_hobject(st, DUK_HCOMPFUNC_GET_LEXENV(NULL, f));\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__varenv:\"); duk__print_hobject(st, DUK_HCOMPFUNC_GET_VARENV(NULL, f));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__nregs:%ld\", (long) f->nregs);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__nargs:%ld\", (long) f->nargs);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__start_line:%ld\", (long) f->start_line);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__end_line:%ld\", (long) f->end_line);\n#endif\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__data:\");\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(NULL, f));\n\t} else if (st->internal && DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\tduk_hnatfunc *f = (duk_hnatfunc *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__func:\");\n\t\tduk_fb_put_funcptr(fb, (duk_uint8_t *) &f->func, sizeof(f->func));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__nargs:%ld\", (long) f->nargs);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__magic:%ld\", (long) f->magic);\n\t} else if (st->internal && DUK_HOBJECT_IS_DECENV(h)) {\n\t\tduk_hdecenv *e = (duk_hdecenv *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__thread:\"); duk__print_hobject(st, (duk_hobject *) e->thread);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__varmap:\"); duk__print_hobject(st, (duk_hobject *) e->varmap);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__regbase_byteoff:%ld\", (long) e->regbase_byteoff);\n\t} else if (st->internal && DUK_HOBJECT_IS_OBJENV(h)) {\n\t\tduk_hobjenv *e = (duk_hobjenv *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__target:\"); duk__print_hobject(st, (duk_hobject *) e->target);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__has_this:%ld\", (long) e->has_this);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t} else if (st->internal && DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\tduk_hbufobj *b = (duk_hbufobj *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__buf:\");\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) b->buf);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__buf_prop:\");\n\t\tduk__print_hobject(st, (duk_hobject *) b->buf_prop);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__offset:%ld\", (long) b->offset);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__length:%ld\", (long) b->length);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__shift:%ld\", (long) b->shift);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__elemtype:%ld\", (long) b->elem_type);\n#endif\n\t} else if (st->internal && DUK_HOBJECT_IS_PROXY(h)) {\n\t\tduk_hproxy *p = (duk_hproxy *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__target:\");\n\t\tduk__print_hobject(st, p->target);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__handler:\");\n\t\tduk__print_hobject(st, p->handler);\n\t} else if (st->internal && DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__ptr_curr_pc:%p\", (void *) t->ptr_curr_pc);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__heap:%p\", (void *) t->heap);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__strict:%ld\", (long) t->strict);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__state:%ld\", (long) t->state);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__unused1:%ld\", (long) t->unused1);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__unused2:%ld\", (long) t->unused2);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack:%p\", (void *) t->valstack);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_end:%p/%ld\", (void *) t->valstack_end, (long) (t->valstack_end - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_alloc_end:%p/%ld\", (void *) t->valstack_alloc_end, (long) (t->valstack_alloc_end - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_bottom:%p/%ld\", (void *) t->valstack_bottom, (long) (t->valstack_bottom - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_top:%p/%ld\", (void *) t->valstack_top, (long) (t->valstack_top - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__callstack_curr:%p\", (void *) t->callstack_curr);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__callstack_top:%ld\", (long) t->callstack_top);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__callstack_preventcount:%ld\", (long) t->callstack_preventcount);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__resumer:\"); duk__print_hobject(st, (duk_hobject *) t->resumer);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__compile_ctx:%p\", (void *) t->compile_ctx);\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__interrupt_counter:%ld\", (long) t->interrupt_counter);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__interrupt_init:%ld\", (long) t->interrupt_init);\n#endif\n\n\t\t/* XXX: print built-ins array? */\n\n\t}\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tif (st->internal) {\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__refcount:%lu\", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h));\n\t}\n#endif\n\tif (st->internal) {\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__class:%ld\", (long) DUK_HOBJECT_GET_CLASS_NUMBER(h));\n\t}\n\n\tDUK__COMMA(); duk_fb_sprintf(fb, \"__heapptr:%p\", (void *) h);  /* own pointer */\n\n\t/* prototype should be last, for readability */\n\tif (DUK_HOBJECT_GET_PROTOTYPE(NULL, h)) {\n\t\tif (st->follow_proto) {\n\t\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__prototype:\"); duk__print_hobject(st, DUK_HOBJECT_GET_PROTOTYPE(NULL, h));\n\t\t} else {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__prototype:%p\", (void *) DUK_HOBJECT_GET_PROTOTYPE(NULL, h));\n\t\t}\n\t}\n\n\tduk_fb_put_cstring(fb, brace2);\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (st->heavy && DUK_HOBJECT_GET_HSIZE(h) > 0) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LANGLE);\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_HSIZE(h); i++) {\n\t\t\tduk_uint_t h_idx = DUK_HOBJECT_H_GET_INDEX(NULL, h, i);\n\t\t\tif (i > 0) {\n\t\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COMMA);\n\t\t\t}\n\t\t\tif (h_idx == DUK_HOBJECT_HASHIDX_UNUSED) {\n\t\t\t\tduk_fb_sprintf(fb, \"u\");\n\t\t\t} else if (h_idx == DUK_HOBJECT_HASHIDX_DELETED) {\n\t\t\t\tduk_fb_sprintf(fb, \"d\");\n\t\t\t} else {\n\t\t\t\tduk_fb_sprintf(fb, \"%ld\", (long) h_idx);\n\t\t\t}\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RANGLE);\n\t}\n#endif\n\n finished:\n\tst->depth--;\n\tif (pushed_loopstack) {\n\t\tst->loop_stack_index--;\n\t\tst->loop_stack[st->loop_stack_index] = NULL;\n\t}\n}\n\nDUK_LOCAL void duk__print_hbuffer(duk__dprint_state *st, duk_hbuffer *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\tduk_size_t i, n;\n\tduk_uint8_t *p;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\t/* terminal type: no depth check */\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tif (DUK_HBUFFER_HAS_DYNAMIC(h)) {\n\t\tif (DUK_HBUFFER_HAS_EXTERNAL(h)) {\n\t\t\tduk_hbuffer_external *g = (duk_hbuffer_external *) h;\n\t\t\tduk_fb_sprintf(fb, \"buffer:external:%p:%ld\",\n\t\t\t               (void *) DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(NULL, g),\n\t\t\t               (long) DUK_HBUFFER_EXTERNAL_GET_SIZE(g));\n\t\t} else {\n\t\t\tduk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h;\n\t\t\tduk_fb_sprintf(fb, \"buffer:dynamic:%p:%ld\",\n\t\t\t               (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(NULL, g),\n\t\t\t               (long) DUK_HBUFFER_DYNAMIC_GET_SIZE(g));\n\t\t}\n\t} else {\n\t\tduk_fb_sprintf(fb, \"buffer:fixed:%ld\", (long) DUK_HBUFFER_GET_SIZE(h));\n\t}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_fb_sprintf(fb, \"/%lu\", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(&h->hdr));\n#endif\n\n\tif (st->hexdump) {\n\t\tduk_fb_sprintf(fb, \"=[\");\n\t\tn = DUK_HBUFFER_GET_SIZE(h);\n\t\tp = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(NULL, h);\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) p[i]);\n\t\t}\n\t\tduk_fb_sprintf(fb, \"]\");\n\t}\n}\n\nDUK_LOCAL void duk__print_heaphdr(duk__dprint_state *st, duk_heaphdr *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING:\n\t\tduk__print_hstring(st, (duk_hstring *) h, 1);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tduk__print_hobject(st, (duk_hobject *) h);\n\t\tbreak;\n\tcase DUK_HTYPE_BUFFER:\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) h);\n\t\tbreak;\n\tdefault:\n\t\tduk_fb_sprintf(fb, \"[unknown htype %ld]\", (long) DUK_HEAPHDR_GET_TYPE(h));\n\t\tbreak;\n\t}\n}\n\nDUK_LOCAL void duk__print_tval(duk__dprint_state *st, duk_tval *tv) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\t/* depth check is done when printing an actual type */\n\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"(%p)\", (void *) tv);\n\t}\n\n\tif (!tv) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tif (st->binary) {\n\t\tduk_size_t i;\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET);\n\t\tfor (i = 0; i < (duk_size_t) sizeof(*tv); i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) ((duk_uint8_t *)tv)[i]);\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET);\n\t}\n\n\tif (st->heavy) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LANGLE);\n\t}\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\tduk_fb_put_cstring(fb, \"undefined\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_UNUSED: {\n\t\tduk_fb_put_cstring(fb, \"unused\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tduk_fb_put_cstring(fb, \"null\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tduk_fb_put_cstring(fb, DUK_TVAL_GET_BOOLEAN(tv) ? \"true\" : \"false\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\t/* Note: string is a terminal heap object, so no depth check here */\n\t\tduk__print_hstring(st, DUK_TVAL_GET_STRING(tv), 1);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk__print_hobject(st, DUK_TVAL_GET_OBJECT(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\tduk__print_hbuffer(st, DUK_TVAL_GET_BUFFER(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tduk_fb_sprintf(fb, \"pointer:%p\", (void *) DUK_TVAL_GET_POINTER(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tduk_c_function func;\n\t\tduk_small_uint_t lf_flags;\n\n\t\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);\n\t\tduk_fb_sprintf(fb, \"lightfunc:\");\n\t\tduk_fb_put_funcptr(fb, (duk_uint8_t *) &func, sizeof(func));\n\t\tduk_fb_sprintf(fb, \":%04lx\", (long) lf_flags);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tduk_fb_sprintf(fb, \"%.18g_F\", (double) DUK_TVAL_GET_NUMBER(tv));\n\t\tbreak;\n#endif\n\tdefault: {\n\t\t/* IEEE double is approximately 16 decimal digits; print a couple extra */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tduk_fb_sprintf(fb, \"%.18g\", (double) DUK_TVAL_GET_NUMBER(tv));\n\t\tbreak;\n\t}\n\t}\n\tif (st->heavy) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RANGLE);\n\t}\n}\n\nDUK_LOCAL void duk__print_instr(duk__dprint_state *st, duk_instr_t ins) {\n\tduk_fixedbuffer *fb = st->fb;\n\tduk_small_int_t op;\n\tconst char *op_name;\n\n\top = (duk_small_int_t) DUK_DEC_OP(ins);\n\top_name = duk__bc_optab[op];\n\n\t/* XXX: option to fix opcode length so it lines up nicely */\n\n\tif (op == DUK_OP_JUMP) {\n\t\tduk_int_t diff1 = (duk_int_t) (DUK_DEC_ABC(ins) - DUK_BC_JUMP_BIAS);  /* from next pc */\n\t\tduk_int_t diff2 = diff1 + 1;                                          /* from curr pc */\n\n\t\tduk_fb_sprintf(fb, \"%s %ld (to pc%c%ld)\",\n\t\t               (const char *) op_name, (long) diff1,\n\t\t               (int) (diff2 >= 0 ? '+' : '-'),  /* char format: use int */\n\t\t               (long) (diff2 >= 0 ? diff2 : -diff2));\n\t} else {\n\t\tduk_fb_sprintf(fb, \"%s %ld, %ld, %ld\",\n\t\t               (const char *) op_name, (long) DUK_DEC_A(ins),\n\t\t               (long) DUK_DEC_B(ins), (long) DUK_DEC_C(ins));\n\t}\n}\n\nDUK_LOCAL void duk__print_opcode(duk__dprint_state *st, duk_small_int_t opcode) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (opcode < DUK_BC_OP_MIN || opcode > DUK_BC_OP_MAX) {\n\t\tduk_fb_sprintf(fb, \"?(%ld)\", (long) opcode);\n\t} else {\n\t\tduk_fb_sprintf(fb, \"%s\", (const char *) duk__bc_optab[opcode]);\n\t}\n}\n\nDUK_LOCAL void duk__print_catcher(duk__dprint_state *st, duk_catcher *cat) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tif (!cat) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tduk_fb_sprintf(fb, \"[catcher ptr=%p parent=%p varname=%p pc_base=%p, idx_base=%ld, flags=0x%08lx]\",\n\t               (void *) cat,\n\t               (void *) cat->parent, (void *) cat->h_varname, (void *) cat->pc_base,\n\t\t       (long) cat->idx_base, (unsigned long) cat->flags);\n}\n\n\nDUK_LOCAL void duk__print_activation(duk__dprint_state *st, duk_activation *act) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tif (!act) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\t/* prev_caller: conditional, omitted on purpose, it's rarely used. */\n\t/* prev_line: conditional, omitted on purpose (but would be nice). */\n\tduk_fb_sprintf(fb, \"[activation ptr=%p tv_func=<omit> func=%p parent=%p var_env=%p lex_env=%p cat=%p curr_pc=%p bottom_byteoff=%ld retval_byteoff=%ld reserve_byteoff=%ld flags=%ld]\",\n\t               (void *) act,\n\t               (void *) act->func, (void *) act->parent, (void *) act->var_env,\n\t\t       (void *) act->lex_env, (void *) act->cat, (void *) act->curr_pc,\n\t\t       (long) act->bottom_byteoff, (long) act->retval_byteoff, (long) act->reserve_byteoff,\n\t\t       (long) act->flags);\n}\n\nDUK_INTERNAL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const char *format, va_list ap) {\n\tduk_fixedbuffer fb;\n\tconst char *p = format;\n\tconst char *p_end = p + DUK_STRLEN(format);\n\tduk_int_t retval;\n\n\tduk_memzero(&fb, sizeof(fb));\n\tfb.buffer = (duk_uint8_t *) str;\n\tfb.length = size;\n\tfb.offset = 0;\n\tfb.truncated = 0;\n\n\twhile (p < p_end) {\n\t\tchar ch = *p++;\n\t\tconst char *p_begfmt = NULL;\n\t\tduk_bool_t got_exclamation = 0;\n\t\tduk_bool_t got_long = 0;  /* %lf, %ld etc */\n\t\tduk__dprint_state st;\n\n\t\tif (ch != DUK_ASC_PERCENT) {\n\t\t\tduk_fb_put_byte(&fb, (duk_uint8_t) ch);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/*\n\t\t *  Format tag parsing.  Since we don't understand all the\n\t\t *  possible format tags allowed, we just scan for a terminating\n\t\t *  specifier and keep track of relevant modifiers that we do\n\t\t *  understand.  See man 3 printf.\n\t\t */\n\n\t\tduk_memzero(&st, sizeof(st));\n\t\tst.fb = &fb;\n\t\tst.depth = 0;\n\t\tst.depth_limit = 1;\n\t\tst.loop_stack_index = 0;\n\t\tst.loop_stack_limit = DUK__LOOP_STACK_DEPTH;\n\n\t\tp_begfmt = p - 1;\n\t\twhile (p < p_end) {\n\t\t\tch = *p++;\n\n\t\t\tif (ch == DUK_ASC_STAR) {\n\t\t\t\t/* unsupported: would consume multiple args */\n\t\t\t\tgoto format_error;\n\t\t\t} else if (ch == DUK_ASC_PERCENT) {\n\t\t\t\tduk_fb_put_byte(&fb, (duk_uint8_t) DUK_ASC_PERCENT);\n\t\t\t\tbreak;\n\t\t\t} else if (ch == DUK_ASC_EXCLAMATION) {\n\t\t\t\tgot_exclamation = 1;\n\t\t\t} else if (!got_exclamation && ch == DUK_ASC_LC_L) {\n\t\t\t\tgot_long = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_D) {\n\t\t\t\tst.depth_limit = DUK__DEEP_DEPTH_LIMIT;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_P) {\n\t\t\t\tst.follow_proto = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_I) {\n\t\t\t\tst.internal = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_X) {\n\t\t\t\tst.hexdump = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_H) {\n\t\t\t\tst.heavy = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_ATSIGN) {\n\t\t\t\tst.pointer = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_HASH) {\n\t\t\t\tst.binary = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_T) {\n\t\t\t\tduk_tval *t = va_arg(ap, duk_tval *);\n\t\t\t\tif (st.pointer && !st.heavy) {\n\t\t\t\t\tduk_fb_sprintf(&fb, \"(%p)\", (void *) t);\n\t\t\t\t}\n\t\t\t\tduk__print_tval(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_O) {\n\t\t\t\tduk_heaphdr *t = va_arg(ap, duk_heaphdr *);\n\t\t\t\tif (st.pointer && !st.heavy) {\n\t\t\t\t\tduk_fb_sprintf(&fb, \"(%p)\", (void *) t);\n\t\t\t\t}\n\t\t\t\tduk__print_heaphdr(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_I) {\n\t\t\t\tduk_instr_t t = va_arg(ap, duk_instr_t);\n\t\t\t\tduk__print_instr(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_X) {\n\t\t\t\tlong t = va_arg(ap, long);\n\t\t\t\tduk__print_opcode(&st, (duk_small_int_t) t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_C) {\n\t\t\t\tduk_catcher *t = va_arg(ap, duk_catcher *);\n\t\t\t\tduk__print_catcher(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_A) {\n\t\t\t\tduk_activation *t = va_arg(ap, duk_activation *);\n\t\t\t\tduk__print_activation(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (!got_exclamation && strchr(DUK__ALLOWED_STANDARD_SPECIFIERS, (int) ch)) {\n\t\t\t\tchar fmtbuf[DUK__MAX_FORMAT_TAG_LENGTH];\n\t\t\t\tduk_size_t fmtlen;\n\n\t\t\t\tDUK_ASSERT(p >= p_begfmt);\n\t\t\t\tfmtlen = (duk_size_t) (p - p_begfmt);\n\t\t\t\tif (fmtlen >= sizeof(fmtbuf)) {\n\t\t\t\t\t/* format is too large, abort */\n\t\t\t\t\tgoto format_error;\n\t\t\t\t}\n\t\t\t\tduk_memzero(fmtbuf, sizeof(fmtbuf));\n\t\t\t\tduk_memcpy(fmtbuf, p_begfmt, fmtlen);\n\n\t\t\t\t/* assume exactly 1 arg, which is why '*' is forbidden; arg size still\n\t\t\t\t * depends on type though.\n\t\t\t\t */\n\n\t\t\t\tif (ch == DUK_ASC_LC_F || ch == DUK_ASC_LC_G || ch == DUK_ASC_LC_E) {\n\t\t\t\t\t/* %f and %lf both consume a 'long' */\n\t\t\t\t\tdouble arg = va_arg(ap, double);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_D && got_long) {\n\t\t\t\t\t/* %ld */\n\t\t\t\t\tlong arg = va_arg(ap, long);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_D) {\n\t\t\t\t\t/* %d; only 16 bits are guaranteed */\n\t\t\t\t\tint arg = va_arg(ap, int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_U && got_long) {\n\t\t\t\t\t/* %lu */\n\t\t\t\t\tunsigned long arg = va_arg(ap, unsigned long);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_U) {\n\t\t\t\t\t/* %u; only 16 bits are guaranteed */\n\t\t\t\t\tunsigned int arg = va_arg(ap, unsigned int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_X && got_long) {\n\t\t\t\t\t/* %lx */\n\t\t\t\t\tunsigned long arg = va_arg(ap, unsigned long);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_X) {\n\t\t\t\t\t/* %x; only 16 bits are guaranteed */\n\t\t\t\t\tunsigned int arg = va_arg(ap, unsigned int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_S) {\n\t\t\t\t\t/* %s */\n\t\t\t\t\tconst char *arg = va_arg(ap, const char *);\n\t\t\t\t\tif (arg == NULL) {\n\t\t\t\t\t\t/* '%s' and NULL is not portable, so special case\n\t\t\t\t\t\t * it for debug printing.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk_fb_sprintf(&fb, \"NULL\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t\t}\n\t\t\t\t} else if (ch == DUK_ASC_LC_P) {\n\t\t\t\t\t/* %p */\n\t\t\t\t\tvoid *arg = va_arg(ap, void *);\n\t\t\t\t\tif (arg == NULL) {\n\t\t\t\t\t\t/* '%p' and NULL is portable, but special case it\n\t\t\t\t\t\t * anyway to get a standard NULL marker in logs.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk_fb_sprintf(&fb, \"NULL\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t\t}\n\t\t\t\t} else if (ch == DUK_ASC_LC_C) {\n\t\t\t\t\t/* '%c', passed concretely as int */\n\t\t\t\t\tint arg = va_arg(ap, int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else {\n\t\t\t\t\t/* Should not happen. */\n\t\t\t\t\tduk_fb_sprintf(&fb, \"INVALID-FORMAT(%s)\", (const char *) fmtbuf);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t/* ignore */\n\t\t\t}\n\t\t}\n\t}\n\tgoto done;\n\n format_error:\n\tduk_fb_put_cstring(&fb, \"FMTERR\");\n\t/* fall through */\n\n done:\n\tretval = (duk_int_t) fb.offset;\n\tduk_fb_put_byte(&fb, (duk_uint8_t) 0);\n\n\t/* return total chars written excluding terminator */\n\treturn retval;\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL duk_int_t duk_debug_snprintf(char *str, duk_size_t size, const char *format, ...) {\n\tduk_int_t retval;\n\tva_list ap;\n\tva_start(ap, format);\n\tretval = duk_debug_vsnprintf(str, size, format, ap);\n\tva_end(ap);\n\treturn retval;\n}\n#endif\n\n/* Formatting function pointers is tricky: there is no standard pointer for\n * function pointers and the size of a function pointer may depend on the\n * specific pointer type.  This helper formats a function pointer based on\n * its memory layout to get something useful on most platforms.\n */\nDUK_INTERNAL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_uint8_t *fptr, duk_size_t fptr_size) {\n\tduk_size_t i;\n\tduk_uint8_t *p = (duk_uint8_t *) buf;\n\tduk_uint8_t *p_end = (duk_uint8_t *) (buf + buf_size - 1);\n\n\tDUK_ASSERT(buf != NULL);\n\tduk_memzero(buf, buf_size);\n\n\tfor (i = 0; i < fptr_size; i++) {\n\t\tduk_int_t left = (duk_int_t) (p_end - p);\n\t\tduk_uint8_t ch;\n\t\tif (left <= 0) {\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Quite approximate but should be useful for little and big endian. */\n#if defined(DUK_USE_INTEGER_BE)\n\t\tch = fptr[i];\n#else\n\t\tch = fptr[fptr_size - 1 - i];\n#endif\n\t\tp += DUK_SNPRINTF((char *) p, (duk_size_t) left, \"%02lx\", (unsigned long) ch);\n\t}\n}\n\n#endif  /* DUK_USE_DEBUG */\n\n/* automatic undefs */\n#undef DUK__ALLOWED_STANDARD_SPECIFIERS\n#undef DUK__COMMA\n#undef DUK__DEEP_DEPTH_LIMIT\n#undef DUK__LOOP_STACK_DEPTH\n#undef DUK__MAX_FORMAT_TAG_LENGTH\n/*\n *  Duktape debugger\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\n/*\n *  Assert helpers\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n#define DUK__DBG_TPORT_ENTER() do { \\\n\t\tDUK_ASSERT(heap->dbg_calling_transport == 0); \\\n\t\theap->dbg_calling_transport = 1; \\\n\t} while (0)\n#define DUK__DBG_TPORT_EXIT() do { \\\n\t\tDUK_ASSERT(heap->dbg_calling_transport == 1); \\\n\t\theap->dbg_calling_transport = 0; \\\n\t} while (0)\n#else\n#define DUK__DBG_TPORT_ENTER() do {} while (0)\n#define DUK__DBG_TPORT_EXIT() do {} while (0)\n#endif\n\n/*\n *  Helper structs\n */\n\ntypedef union {\n\tvoid *p;\n\tduk_uint_t b[1];\n\t/* Use b[] to access the size of the union, which is strictly not\n\t * correct.  Can't use fixed size unless there's feature detection\n\t * for pointer byte size.\n\t */\n} duk__ptr_union;\n\n/*\n *  Detach handling\n */\n\n#define DUK__SET_CONN_BROKEN(thr,reason) do { \\\n\t\t/* For now shared handler is fine. */ \\\n\t\tduk__debug_do_detach1((thr)->heap, (reason)); \\\n\t} while (0)\n\nDUK_LOCAL void duk__debug_do_detach1(duk_heap *heap, duk_int_t reason) {\n\t/* Can be called multiple times with no harm.  Mark the transport\n\t * bad (dbg_read_cb == NULL) and clear state except for the detached\n\t * callback and the udata field.  The detached callback is delayed\n\t * to the message loop so that it can be called between messages;\n\t * this avoids corner cases related to immediate debugger reattach\n\t * inside the detached callback.\n\t */\n\n\tif (heap->dbg_detaching) {\n\t\tDUK_D(DUK_DPRINT(\"debugger already detaching, ignore detach1\"));\n\t\treturn;\n\t}\n\n\tDUK_D(DUK_DPRINT(\"debugger transport detaching, marking transport broken\"));\n\n\theap->dbg_detaching = 1;  /* prevent multiple in-progress detaches */\n\n\tif (heap->dbg_write_cb != NULL) {\n\t\tduk_hthread *thr;\n\n\t\tthr = heap->heap_thread;\n\t\tDUK_ASSERT(thr != NULL);\n\n\t\tduk_debug_write_notify(thr, DUK_DBG_CMD_DETACHING);\n\t\tduk_debug_write_int(thr, reason);\n\t\tduk_debug_write_eom(thr);\n\t}\n\n\theap->dbg_read_cb = NULL;\n\theap->dbg_write_cb = NULL;\n\theap->dbg_peek_cb = NULL;\n\theap->dbg_read_flush_cb = NULL;\n\theap->dbg_write_flush_cb = NULL;\n\theap->dbg_request_cb = NULL;\n\t/* heap->dbg_detached_cb: keep */\n\t/* heap->dbg_udata: keep */\n\t/* heap->dbg_processing: keep on purpose to avoid debugger re-entry in detaching state */\n\theap->dbg_state_dirty = 0;\n\theap->dbg_force_restart = 0;\n\theap->dbg_pause_flags = 0;\n\theap->dbg_pause_act = NULL;\n\theap->dbg_pause_startline = 0;\n\theap->dbg_have_next_byte = 0;\n\tduk_debug_clear_paused(heap);  /* XXX: some overlap with field inits above */\n\theap->dbg_state_dirty = 0;     /* XXX: clear_paused sets dirty; rework? */\n\n\t/* Ensure there are no stale active breakpoint pointers.\n\t * Breakpoint list is currently kept - we could empty it\n\t * here but we'd need to handle refcounts correctly, and\n\t * we'd need a 'thr' reference for that.\n\t *\n\t * XXX: clear breakpoint on either attach or detach?\n\t */\n\theap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;\n}\n\nDUK_LOCAL void duk__debug_do_detach2(duk_heap *heap) {\n\tduk_debug_detached_function detached_cb;\n\tvoid *detached_udata;\n\tduk_hthread *thr;\n\n\tthr = heap->heap_thread;\n\tif (thr == NULL) {\n\t\tDUK_ASSERT(heap->dbg_detached_cb == NULL);\n\t\treturn;\n\t}\n\n\t/* Safe to call multiple times. */\n\n\tdetached_cb = heap->dbg_detached_cb;\n\tdetached_udata = heap->dbg_udata;\n\theap->dbg_detached_cb = NULL;\n\theap->dbg_udata = NULL;\n\n\tif (detached_cb) {\n\t\t/* Careful here: state must be wiped before the call\n\t\t * so that we can cleanly handle a re-attach from\n\t\t * inside the callback.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"detached during message loop, delayed call to detached_cb\"));\n\t\tdetached_cb(thr, detached_udata);\n\t}\n\n\theap->dbg_detaching = 0;\n}\n\nDUK_INTERNAL void duk_debug_do_detach(duk_heap *heap) {\n\tduk__debug_do_detach1(heap, 0);\n\tduk__debug_do_detach2(heap);\n}\n\n/* Called on a read/write error: NULL all callbacks except the detached\n * callback so that we never accidentally call them after a read/write\n * error has been indicated.  This is especially important for the transport\n * I/O callbacks to fulfill guaranteed callback semantics.\n */\nDUK_LOCAL void duk__debug_null_most_callbacks(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\n\theap = thr->heap;\n\tDUK_D(DUK_DPRINT(\"transport read/write error, NULL all callbacks expected detached\"));\n\theap->dbg_read_cb = NULL;\n\theap->dbg_write_cb = NULL;  /* this is especially critical to avoid another write call in detach1() */\n\theap->dbg_peek_cb = NULL;\n\theap->dbg_read_flush_cb = NULL;\n\theap->dbg_write_flush_cb = NULL;\n\theap->dbg_request_cb = NULL;\n\t/* keep heap->dbg_detached_cb */\n}\n\n/*\n *  Pause handling\n */\n\nDUK_LOCAL void duk__debug_set_pause_state(duk_hthread *thr, duk_heap *heap, duk_small_uint_t pause_flags) {\n\tduk_uint_fast32_t line;\n\n\tline = duk_debug_curr_line(thr);\n\tif (line == 0) {\n\t\t/* No line info for current function. */\n\t\tduk_small_uint_t updated_flags;\n\n\t\tupdated_flags = pause_flags & ~(DUK_PAUSE_FLAG_LINE_CHANGE);\n\t\tDUK_D(DUK_DPRINT(\"no line info for current activation, disable line-based pause flags: 0x%08lx -> 0x%08lx\",\n\t\t                 (long) pause_flags, (long) updated_flags));\n\t\tpause_flags = updated_flags;\n\t}\n\n\theap->dbg_pause_flags = pause_flags;\n\theap->dbg_pause_act = thr->callstack_curr;\n\theap->dbg_pause_startline = (duk_uint32_t) line;\n\theap->dbg_state_dirty = 1;\n\n\tDUK_D(DUK_DPRINT(\"set state for automatic pause triggers, flags=0x%08lx, act=%p, startline=%ld\",\n\t                 (long) heap->dbg_pause_flags, (void *) heap->dbg_pause_act,\n\t                 (long) heap->dbg_pause_startline));\n}\n\n/*\n *  Debug connection peek and flush primitives\n */\n\nDUK_INTERNAL duk_bool_t duk_debug_read_peek(duk_hthread *thr) {\n\tduk_heap *heap;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to peek in detached state, return zero (= no data)\"));\n\t\treturn 0;\n\t}\n\tif (heap->dbg_peek_cb == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"no peek callback, return zero (= no data)\"));\n\t\treturn 0;\n\t}\n\n\tDUK__DBG_TPORT_ENTER();\n\tret = (duk_bool_t) (heap->dbg_peek_cb(heap->dbg_udata) > 0);\n\tDUK__DBG_TPORT_EXIT();\n\treturn ret;\n}\n\nDUK_INTERNAL void duk_debug_read_flush(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to read flush in detached state, ignore\"));\n\t\treturn;\n\t}\n\tif (heap->dbg_read_flush_cb == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"no read flush callback, ignore\"));\n\t\treturn;\n\t}\n\n\tDUK__DBG_TPORT_ENTER();\n\theap->dbg_read_flush_cb(heap->dbg_udata);\n\tDUK__DBG_TPORT_EXIT();\n}\n\nDUK_INTERNAL void duk_debug_write_flush(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to write flush in detached state, ignore\"));\n\t\treturn;\n\t}\n\tif (heap->dbg_write_flush_cb == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"no write flush callback, ignore\"));\n\t\treturn;\n\t}\n\n\tDUK__DBG_TPORT_ENTER();\n\theap->dbg_write_flush_cb(heap->dbg_udata);\n\tDUK__DBG_TPORT_EXIT();\n}\n\n/*\n *  Debug connection skip primitives\n */\n\n/* Skip fully. */\nDUK_INTERNAL void duk_debug_skip_bytes(duk_hthread *thr, duk_size_t length) {\n\tduk_uint8_t dummy[64];\n\tduk_size_t now;\n\n\tDUK_ASSERT(thr != NULL);\n\n\twhile (length > 0) {\n\t\tnow = (length > sizeof(dummy) ? sizeof(dummy) : length);\n\t\tduk_debug_read_bytes(thr, dummy, now);\n\t\tlength -= now;\n\t}\n}\n\nDUK_INTERNAL void duk_debug_skip_byte(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\t(void) duk_debug_read_byte(thr);\n}\n\n/*\n *  Debug connection read primitives\n */\n\n/* Peek ahead in the stream one byte. */\nDUK_INTERNAL uint8_t duk_debug_peek_byte(duk_hthread *thr) {\n\t/* It is important not to call this if the last byte read was an EOM.\n\t * Reading ahead in this scenario would cause unnecessary blocking if\n\t * another message is not available.\n\t */\n\n\tduk_uint8_t x;\n\n\tx = duk_debug_read_byte(thr);\n\tthr->heap->dbg_have_next_byte = 1;\n\tthr->heap->dbg_next_byte = x;\n\treturn x;\n}\n\n/* Read fully. */\nDUK_INTERNAL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_size_t length) {\n\tduk_heap *heap;\n\tduk_uint8_t *p;\n\tduk_size_t left;\n\tduk_size_t got;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(data != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to read %ld bytes in detached state, return zero data\", (long) length));\n\t\tgoto fail;\n\t}\n\n\t/* NOTE: length may be zero */\n\tp = data;\n\tif (length >= 1 && heap->dbg_have_next_byte) {\n\t\theap->dbg_have_next_byte = 0;\n\t\t*p++ = heap->dbg_next_byte;\n\t}\n\tfor (;;) {\n\t\tleft = (duk_size_t) ((data + length) - p);\n\t\tif (left == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tDUK_ASSERT(heap->dbg_read_cb != NULL);\n\t\tDUK_ASSERT(left >= 1);\n#if defined(DUK_USE_DEBUGGER_TRANSPORT_TORTURE)\n\t\tleft = 1;\n#endif\n\t\tDUK__DBG_TPORT_ENTER();\n\t\tgot = heap->dbg_read_cb(heap->dbg_udata, (char *) p, left);\n\t\tDUK__DBG_TPORT_EXIT();\n\n\t\tif (got == 0 || got > left) {\n\t\t\tDUK_D(DUK_DPRINT(\"connection error during read, return zero data\"));\n\t\t\tduk__debug_null_most_callbacks(thr);  /* avoid calling write callback in detach1() */\n\t\t\tDUK__SET_CONN_BROKEN(thr, 1);\n\t\t\tgoto fail;\n\t\t}\n\t\tp += got;\n\t}\n\treturn;\n\n fail:\n\tduk_memzero((void *) data, (size_t) length);\n}\n\nDUK_INTERNAL duk_uint8_t duk_debug_read_byte(duk_hthread *thr) {\n\tduk_uint8_t x;\n\n\tx = 0;  /* just in case callback is broken and won't write 'x' */\n\tduk_debug_read_bytes(thr, &x, 1);\n\treturn x;\n}\n\nDUK_LOCAL duk_uint32_t duk__debug_read_uint32_raw(duk_hthread *thr) {\n\tduk_uint8_t buf[4];\n\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_read_bytes(thr, buf, 4);\n\treturn ((duk_uint32_t) buf[0] << 24) |\n\t       ((duk_uint32_t) buf[1] << 16) |\n\t       ((duk_uint32_t) buf[2] << 8) |\n\t       (duk_uint32_t) buf[3];\n}\n\nDUK_LOCAL duk_int32_t duk__debug_read_int32_raw(duk_hthread *thr) {\n\treturn (duk_int32_t) duk__debug_read_uint32_raw(thr);\n}\n\nDUK_LOCAL duk_uint16_t duk__debug_read_uint16_raw(duk_hthread *thr) {\n\tduk_uint8_t buf[2];\n\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_read_bytes(thr, buf, 2);\n\treturn ((duk_uint16_t) buf[0] << 8) |\n\t       (duk_uint16_t) buf[1];\n}\n\nDUK_INTERNAL duk_int32_t duk_debug_read_int(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\tduk_small_uint_t t;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x >= 0xc0) {\n\t\tt = duk_debug_read_byte(thr);\n\t\treturn (duk_int32_t) (((x - 0xc0) << 8) + t);\n\t} else if (x >= 0x80) {\n\t\treturn (duk_int32_t) (x - 0x80);\n\t} else if (x == DUK_DBG_IB_INT4) {\n\t\treturn (duk_int32_t) duk__debug_read_uint32_raw(thr);\n\t}\n\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode int\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn 0;\n}\n\nDUK_LOCAL duk_hstring *duk__debug_read_hstring_raw(duk_hthread *thr, duk_uint32_t len) {\n\tduk_uint8_t buf[31];\n\tduk_uint8_t *p;\n\n\tif (len <= sizeof(buf)) {\n\t\tduk_debug_read_bytes(thr, buf, (duk_size_t) len);\n\t\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) len);\n\t} else {\n\t\tp = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len);  /* zero for paranoia */\n\t\tDUK_ASSERT(p != NULL);\n\t\tduk_debug_read_bytes(thr, p, (duk_size_t) len);\n\t\t(void) duk_buffer_to_string(thr, -1);  /* Safety relies on debug client, which is OK. */\n\t}\n\n\treturn duk_require_hstring(thr, -1);\n}\n\nDUK_INTERNAL duk_hstring *duk_debug_read_hstring(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\tduk_uint32_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x >= 0x60 && x <= 0x7f) {\n\t\t/* For short strings, use a fixed temp buffer. */\n\t\tlen = (duk_uint32_t) (x - 0x60);\n\t} else if (x == DUK_DBG_IB_STR2) {\n\t\tlen = (duk_uint32_t) duk__debug_read_uint16_raw(thr);\n\t} else if (x == DUK_DBG_IB_STR4) {\n\t\tlen = (duk_uint32_t) duk__debug_read_uint32_raw(thr);\n\t} else {\n\t\tgoto fail;\n\t}\n\n\treturn duk__debug_read_hstring_raw(thr, len);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode int\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\tduk_push_hstring_empty(thr);  /* always push some string */\n\treturn duk_require_hstring(thr, -1);\n}\n\nDUK_LOCAL duk_hbuffer *duk__debug_read_hbuffer_raw(duk_hthread *thr, duk_uint32_t len) {\n\tduk_uint8_t *p;\n\n\tp = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len);  /* zero for paranoia */\n\tDUK_ASSERT(p != NULL);\n\tduk_debug_read_bytes(thr, p, (duk_size_t) len);\n\n\treturn duk_require_hbuffer(thr, -1);\n}\n\nDUK_LOCAL void *duk__debug_read_pointer_raw(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\tduk__ptr_union pu;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x != sizeof(pu)) {\n\t\tgoto fail;\n\t}\n\tduk_debug_read_bytes(thr, (duk_uint8_t *) &pu.p, sizeof(pu));\n#if defined(DUK_USE_INTEGER_LE)\n\tduk_byteswap_bytes((duk_uint8_t *) pu.b, sizeof(pu));\n#endif\n\treturn (void *) pu.p;\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode pointer\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn (void *) NULL;\n}\n\nDUK_LOCAL duk_double_t duk__debug_read_double_raw(duk_hthread *thr) {\n\tduk_double_union du;\n\n\tDUK_ASSERT(sizeof(du.uc) == 8);\n\tduk_debug_read_bytes(thr, (duk_uint8_t *) du.uc, sizeof(du.uc));\n\tDUK_DBLUNION_DOUBLE_NTOH(&du);\n\treturn du.d;\n}\n\n#if 0\nDUK_INTERNAL duk_heaphdr *duk_debug_read_heapptr(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x != DUK_DBG_IB_HEAPPTR) {\n\t\tgoto fail;\n\t}\n\n\treturn (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode heapptr\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn NULL;\n}\n#endif\n\nDUK_INTERNAL duk_heaphdr *duk_debug_read_any_ptr(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tswitch (x) {\n\tcase DUK_DBG_IB_OBJECT:\n\tcase DUK_DBG_IB_POINTER:\n\tcase DUK_DBG_IB_HEAPPTR:\n\t\t/* Accept any pointer-like value; for 'object' dvalue, read\n\t\t * and ignore the class number.\n\t\t */\n\t\tif (x == DUK_DBG_IB_OBJECT) {\n\t\t\tduk_debug_skip_byte(thr);\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tgoto fail;\n\t}\n\n\treturn (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode any pointer (object, pointer, heapptr)\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_tval *duk_debug_read_tval(duk_hthread *thr) {\n\tduk_uint8_t x;\n\tduk_uint_t t;\n\tduk_uint32_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\n\tif (x >= 0xc0) {\n\t\tt = (duk_uint_t) (x - 0xc0);\n\t\tt = (t << 8) + duk_debug_read_byte(thr);\n\t\tduk_push_uint(thr, (duk_uint_t) t);\n\t\tgoto return_ptr;\n\t}\n\tif (x >= 0x80) {\n\t\tduk_push_uint(thr, (duk_uint_t) (x - 0x80));\n\t\tgoto return_ptr;\n\t}\n\tif (x >= 0x60) {\n\t\tlen = (duk_uint32_t) (x - 0x60);\n\t\tduk__debug_read_hstring_raw(thr, len);\n\t\tgoto return_ptr;\n\t}\n\n\tswitch (x) {\n\tcase DUK_DBG_IB_INT4: {\n\t\tduk_int32_t i = duk__debug_read_int32_raw(thr);\n\t\tduk_push_i32(thr, i);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_STR4: {\n\t\tlen = duk__debug_read_uint32_raw(thr);\n\t\tduk__debug_read_hstring_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_STR2: {\n\t\tlen = duk__debug_read_uint16_raw(thr);\n\t\tduk__debug_read_hstring_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_BUF4: {\n\t\tlen = duk__debug_read_uint32_raw(thr);\n\t\tduk__debug_read_hbuffer_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_BUF2: {\n\t\tlen = duk__debug_read_uint16_raw(thr);\n\t\tduk__debug_read_hbuffer_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_UNDEFINED: {\n\t\tduk_push_undefined(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_NULL: {\n\t\tduk_push_null(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_TRUE: {\n\t\tduk_push_true(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_FALSE: {\n\t\tduk_push_false(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_NUMBER: {\n\t\tduk_double_t d;\n\t\td = duk__debug_read_double_raw(thr);\n\t\tduk_push_number(thr, d);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_OBJECT: {\n\t\tduk_heaphdr *h;\n\t\tduk_debug_skip_byte(thr);\n\t\th = (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\t\tduk_push_heapptr(thr, (void *) h);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_POINTER: {\n\t\tvoid *ptr;\n\t\tptr = duk__debug_read_pointer_raw(thr);\n\t\tduk_push_pointer(thr, ptr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_LIGHTFUNC: {\n\t\t/* XXX: Not needed for now, so not implemented.  Note that\n\t\t * function pointers may have different size/layout than\n\t\t * a void pointer.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"reading lightfunc values unimplemented\"));\n\t\tgoto fail;\n\t}\n\tcase DUK_DBG_IB_HEAPPTR: {\n\t\tduk_heaphdr *h;\n\t\th = (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\t\tduk_push_heapptr(thr, (void *) h);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_UNUSED:  /* unused: not accepted in inbound messages */\n\tdefault:\n\t\tgoto fail;\n\t}\n\n return_ptr:\n\treturn DUK_GET_TVAL_NEGIDX(thr, -1);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode tval\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn NULL;\n}\n\n/*\n *  Debug connection write primitives\n */\n\n/* Write fully. */\nDUK_INTERNAL void duk_debug_write_bytes(duk_hthread *thr, const duk_uint8_t *data, duk_size_t length) {\n\tduk_heap *heap;\n\tconst duk_uint8_t *p;\n\tduk_size_t left;\n\tduk_size_t got;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(length == 0 || data != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_write_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to write %ld bytes in detached state, ignore\", (long) length));\n\t\treturn;\n\t}\n\tif (length == 0) {\n\t\t/* Avoid doing an actual write callback with length == 0,\n\t\t * because that's reserved for a write flush.\n\t\t */\n\t\treturn;\n\t}\n\tDUK_ASSERT(data != NULL);\n\n\tp = data;\n\tfor (;;) {\n\t\tleft = (duk_size_t) ((data + length) - p);\n\t\tif (left == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tDUK_ASSERT(heap->dbg_write_cb != NULL);\n\t\tDUK_ASSERT(left >= 1);\n#if defined(DUK_USE_DEBUGGER_TRANSPORT_TORTURE)\n\t\tleft = 1;\n#endif\n\t\tDUK__DBG_TPORT_ENTER();\n\t\tgot = heap->dbg_write_cb(heap->dbg_udata, (const char *) p, left);\n\t\tDUK__DBG_TPORT_EXIT();\n\n\t\tif (got == 0 || got > left) {\n\t\t\tduk__debug_null_most_callbacks(thr);  /* avoid calling write callback in detach1() */\n\t\t\tDUK_D(DUK_DPRINT(\"connection error during write\"));\n\t\t\tDUK__SET_CONN_BROKEN(thr, 1);\n\t\t\treturn;\n\t\t}\n\t\tp += got;\n\t}\n}\n\nDUK_INTERNAL void duk_debug_write_byte(duk_hthread *thr, duk_uint8_t x) {\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &x, 1);\n}\n\nDUK_INTERNAL void duk_debug_write_unused(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_UNUSED);\n}\n\nDUK_INTERNAL void duk_debug_write_undefined(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_UNDEFINED);\n}\n\n#if defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL void duk_debug_write_null(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_NULL);\n}\n#endif\n\nDUK_INTERNAL void duk_debug_write_boolean(duk_hthread *thr, duk_uint_t val) {\n\tduk_debug_write_byte(thr, val ? DUK_DBG_IB_TRUE : DUK_DBG_IB_FALSE);\n}\n\n/* Write signed 32-bit integer. */\nDUK_INTERNAL void duk_debug_write_int(duk_hthread *thr, duk_int32_t x) {\n\tduk_uint8_t buf[5];\n\tduk_size_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tif (x >= 0 && x <= 0x3fL) {\n\t\tbuf[0] = (duk_uint8_t) (0x80 + x);\n\t\tlen = 1;\n\t} else if (x >= 0 && x <= 0x3fffL) {\n\t\tbuf[0] = (duk_uint8_t) (0xc0 + (x >> 8));\n\t\tbuf[1] = (duk_uint8_t) (x & 0xff);\n\t\tlen = 2;\n\t} else {\n\t\t/* Signed integers always map to 4 bytes now. */\n\t\tbuf[0] = (duk_uint8_t) DUK_DBG_IB_INT4;\n\t\tbuf[1] = (duk_uint8_t) ((x >> 24) & 0xff);\n\t\tbuf[2] = (duk_uint8_t) ((x >> 16) & 0xff);\n\t\tbuf[3] = (duk_uint8_t) ((x >> 8) & 0xff);\n\t\tbuf[4] = (duk_uint8_t) (x & 0xff);\n\t\tlen = 5;\n\t}\n\tduk_debug_write_bytes(thr, buf, len);\n}\n\n/* Write unsigned 32-bit integer. */\nDUK_INTERNAL void duk_debug_write_uint(duk_hthread *thr, duk_uint32_t x) {\n\t/* The debugger protocol doesn't support a plain integer encoding for\n\t * the full 32-bit unsigned range (only 32-bit signed).  For now,\n\t * unsigned 32-bit values simply written as signed ones.  This is not\n\t * a concrete issue except for 32-bit heaphdr fields.  Proper solutions\n\t * would be to (a) write such integers as IEEE doubles or (b) add an\n\t * unsigned 32-bit dvalue.\n\t */\n\tif (x >= 0x80000000UL) {\n\t\tDUK_D(DUK_DPRINT(\"writing unsigned integer 0x%08lx as signed integer\",\n\t\t                 (long) x));\n\t}\n\tduk_debug_write_int(thr, (duk_int32_t) x);\n}\n\nDUK_INTERNAL void duk_debug_write_strbuf(duk_hthread *thr, const char *data, duk_size_t length, duk_uint8_t marker_base) {\n\tduk_uint8_t buf[5];\n\tduk_size_t buflen;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(length == 0 || data != NULL);\n\n\tif (length <= 0x1fUL && marker_base == DUK_DBG_IB_STR4) {\n\t\t/* For strings, special form for short lengths. */\n\t\tbuf[0] = (duk_uint8_t) (0x60 + length);\n\t\tbuflen = 1;\n\t} else if (length <= 0xffffUL) {\n\t\tbuf[0] = (duk_uint8_t) (marker_base + 1);\n\t\tbuf[1] = (duk_uint8_t) (length >> 8);\n\t\tbuf[2] = (duk_uint8_t) (length & 0xff);\n\t\tbuflen = 3;\n\t} else {\n\t\tbuf[0] = (duk_uint8_t) marker_base;\n\t\tbuf[1] = (duk_uint8_t) (length >> 24);\n\t\tbuf[2] = (duk_uint8_t) ((length >> 16) & 0xff);\n\t\tbuf[3] = (duk_uint8_t) ((length >> 8) & 0xff);\n\t\tbuf[4] = (duk_uint8_t) (length & 0xff);\n\t\tbuflen = 5;\n\t}\n\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) buf, buflen);\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) data, length);\n}\n\nDUK_INTERNAL void duk_debug_write_string(duk_hthread *thr, const char *data, duk_size_t length) {\n\tduk_debug_write_strbuf(thr, data, length, DUK_DBG_IB_STR4);\n}\n\nDUK_INTERNAL void duk_debug_write_cstring(duk_hthread *thr, const char *data) {\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_write_string(thr,\n\t                       data,\n\t                       data ? DUK_STRLEN(data) : 0);\n}\n\nDUK_INTERNAL void duk_debug_write_hstring(duk_hthread *thr, duk_hstring *h) {\n\tDUK_ASSERT(thr != NULL);\n\n\t/* XXX: differentiate null pointer from empty string? */\n\tduk_debug_write_string(thr,\n\t                       (h != NULL ? (const char *) DUK_HSTRING_GET_DATA(h) : NULL),\n\t                       (h != NULL ? (duk_size_t) DUK_HSTRING_GET_BYTELEN(h) : 0));\n}\n\nDUK_LOCAL void duk__debug_write_hstring_safe_top(duk_hthread *thr) {\n\tduk_debug_write_hstring(thr, duk_safe_to_hstring(thr, -1));\n}\n\nDUK_INTERNAL void duk_debug_write_buffer(duk_hthread *thr, const char *data, duk_size_t length) {\n\tduk_debug_write_strbuf(thr, data, length, DUK_DBG_IB_BUF4);\n}\n\nDUK_INTERNAL void duk_debug_write_hbuffer(duk_hthread *thr, duk_hbuffer *h) {\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_write_buffer(thr,\n\t                       (h != NULL ? (const char *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h) : NULL),\n\t                       (h != NULL ? (duk_size_t) DUK_HBUFFER_GET_SIZE(h) : 0));\n}\n\nDUK_LOCAL void duk__debug_write_pointer_raw(duk_hthread *thr, void *ptr, duk_uint8_t ibyte) {\n\tduk_uint8_t buf[2];\n\tduk__ptr_union pu;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(sizeof(ptr) >= 1 && sizeof(ptr) <= 16);\n\t/* ptr may be NULL */\n\n\tbuf[0] = ibyte;\n\tbuf[1] = sizeof(pu);\n\tduk_debug_write_bytes(thr, buf, 2);\n\tpu.p = (void *) ptr;\n#if defined(DUK_USE_INTEGER_LE)\n\tduk_byteswap_bytes((duk_uint8_t *) pu.b, sizeof(pu));\n#endif\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &pu.p, (duk_size_t) sizeof(pu));\n}\n\nDUK_INTERNAL void duk_debug_write_pointer(duk_hthread *thr, void *ptr) {\n\tduk__debug_write_pointer_raw(thr, ptr, DUK_DBG_IB_POINTER);\n}\n\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP) || defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL void duk_debug_write_heapptr(duk_hthread *thr, duk_heaphdr *h) {\n\tduk__debug_write_pointer_raw(thr, (void *) h, DUK_DBG_IB_HEAPPTR);\n}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP || DUK_USE_DEBUGGER_INSPECT */\n\nDUK_INTERNAL void duk_debug_write_hobject(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint8_t buf[3];\n\tduk__ptr_union pu;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(sizeof(obj) >= 1 && sizeof(obj) <= 16);\n\tDUK_ASSERT(obj != NULL);\n\n\tbuf[0] = DUK_DBG_IB_OBJECT;\n\tbuf[1] = (duk_uint8_t) DUK_HOBJECT_GET_CLASS_NUMBER(obj);\n\tbuf[2] = sizeof(pu);\n\tduk_debug_write_bytes(thr, buf, 3);\n\tpu.p = (void *) obj;\n#if defined(DUK_USE_INTEGER_LE)\n\tduk_byteswap_bytes((duk_uint8_t *) pu.b, sizeof(pu));\n#endif\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &pu.p, (duk_size_t) sizeof(pu));\n}\n\nDUK_INTERNAL void duk_debug_write_tval(duk_hthread *thr, duk_tval *tv) {\n\tduk_c_function lf_func;\n\tduk_small_uint_t lf_flags;\n\tduk_uint8_t buf[4];\n\tduk_double_union du1;\n\tduk_double_union du2;\n\tduk_int32_t i32;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\t\tduk_debug_write_byte(thr, DUK_DBG_IB_UNDEFINED);\n\t\tbreak;\n\tcase DUK_TAG_UNUSED:\n\t\tduk_debug_write_byte(thr, DUK_DBG_IB_UNUSED);\n\t\tbreak;\n\tcase DUK_TAG_NULL:\n\t\tduk_debug_write_byte(thr, DUK_DBG_IB_NULL);\n\t\tbreak;\n\tcase DUK_TAG_BOOLEAN:\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv) == 0 ||\n\t\t           DUK_TVAL_GET_BOOLEAN(tv) == 1);\n\t\tduk_debug_write_boolean(thr, DUK_TVAL_GET_BOOLEAN(tv));\n\t\tbreak;\n\tcase DUK_TAG_POINTER:\n\t\tduk_debug_write_pointer(thr, (void *) DUK_TVAL_GET_POINTER(tv));\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\tDUK_TVAL_GET_LIGHTFUNC(tv, lf_func, lf_flags);\n\t\tbuf[0] = DUK_DBG_IB_LIGHTFUNC;\n\t\tbuf[1] = (duk_uint8_t) (lf_flags >> 8);\n\t\tbuf[2] = (duk_uint8_t) (lf_flags & 0xff);\n\t\tbuf[3] = sizeof(lf_func);\n\t\tduk_debug_write_bytes(thr, buf, 4);\n\t\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &lf_func, sizeof(lf_func));\n\t\tbreak;\n\tcase DUK_TAG_STRING:\n\t\tduk_debug_write_hstring(thr, DUK_TVAL_GET_STRING(tv));\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\tduk_debug_write_hobject(thr, DUK_TVAL_GET_OBJECT(tv));\n\t\tbreak;\n\tcase DUK_TAG_BUFFER:\n\t\tduk_debug_write_hbuffer(thr, DUK_TVAL_GET_BUFFER(tv));\n\t\tbreak;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* Numbers are normalized to big (network) endian.  We can\n\t\t * (but are not required) to use integer dvalues when there's\n\t\t * no loss of precision.\n\t\t *\n\t\t * XXX: share check with other code; this check is slow but\n\t\t * reliable and doesn't require careful exponent/mantissa\n\t\t * mask tricks as in the fastint downgrade code.\n\t\t */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tdu1.d = DUK_TVAL_GET_NUMBER(tv);\n\t\ti32 = (duk_int32_t) du1.d;\n\t\tdu2.d = (duk_double_t) i32;\n\n\t\tDUK_DD(DUK_DDPRINT(\"i32=%ld du1=%02x%02x%02x%02x%02x%02x%02x%02x \"\n\t\t                   \"du2=%02x%02x%02x%02x%02x%02x%02x%02x\",\n\t\t                   (long) i32,\n\t\t                   (unsigned int) du1.uc[0], (unsigned int) du1.uc[1],\n\t\t                   (unsigned int) du1.uc[2], (unsigned int) du1.uc[3],\n\t\t                   (unsigned int) du1.uc[4], (unsigned int) du1.uc[5],\n\t\t                   (unsigned int) du1.uc[6], (unsigned int) du1.uc[7],\n\t\t                   (unsigned int) du2.uc[0], (unsigned int) du2.uc[1],\n\t\t                   (unsigned int) du2.uc[2], (unsigned int) du2.uc[3],\n\t\t                   (unsigned int) du2.uc[4], (unsigned int) du2.uc[5],\n\t\t                   (unsigned int) du2.uc[6], (unsigned int) du2.uc[7]));\n\n\t\tif (duk_memcmp((const void *) du1.uc, (const void *) du2.uc, sizeof(du1.uc)) == 0) {\n\t\t\tduk_debug_write_int(thr, i32);\n\t\t} else {\n\t\t\tDUK_DBLUNION_DOUBLE_HTON(&du1);\n\t\t\tduk_debug_write_byte(thr, DUK_DBG_IB_NUMBER);\n\t\t\tduk_debug_write_bytes(thr, (const duk_uint8_t *) du1.uc, sizeof(du1.uc));\n\t\t}\n\t}\n}\n\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP)\n/* Variant for writing duk_tvals so that any heap allocated values are\n * written out as tagged heap pointers.\n */\nDUK_LOCAL void duk__debug_write_tval_heapptr(duk_hthread *thr, duk_tval *tv) {\n\tif (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tduk_debug_write_heapptr(thr, h);\n\t} else {\n\t\tduk_debug_write_tval(thr, tv);\n\t}\n}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP */\n\n/*\n *  Debug connection message write helpers\n */\n\n#if 0  /* unused */\nDUK_INTERNAL void duk_debug_write_request(duk_hthread *thr, duk_small_uint_t command) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_REQUEST);\n\tduk_debug_write_int(thr, command);\n}\n#endif\n\nDUK_INTERNAL void duk_debug_write_reply(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_REPLY);\n}\n\nDUK_INTERNAL void duk_debug_write_error_eom(duk_hthread *thr, duk_small_uint_t err_code, const char *msg) {\n\t/* Allow NULL 'msg' */\n\tduk_debug_write_byte(thr, DUK_DBG_IB_ERROR);\n\tduk_debug_write_int(thr, (duk_int32_t) err_code);\n\tduk_debug_write_cstring(thr, msg);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_INTERNAL void duk_debug_write_notify(duk_hthread *thr, duk_small_uint_t command) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_NOTIFY);\n\tduk_debug_write_int(thr, (duk_int32_t) command);\n}\n\nDUK_INTERNAL void duk_debug_write_eom(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_EOM);\n\n\t/* As an initial implementation, write flush after every EOM (and the\n\t * version identifier).  A better implementation would flush only when\n\t * Duktape is finished processing messages so that a flush only happens\n\t * after all outbound messages are finished on that occasion.\n\t */\n\tduk_debug_write_flush(thr);\n}\n\n/*\n *  Status message and helpers\n */\n\nDUK_INTERNAL duk_uint_fast32_t duk_debug_curr_line(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_uint_fast32_t line;\n\tduk_uint_fast32_t pc;\n\n\tact = thr->callstack_curr;\n\tif (act == NULL) {\n\t\treturn 0;\n\t}\n\n\t/* We're conceptually between two opcodes; act->pc indicates the next\n\t * instruction to be executed.  This is usually the correct pc/line to\n\t * indicate in Status.  (For the 'debugger' statement this now reports\n\t * the pc/line after the debugger statement because the debugger opcode\n\t * has already been executed.)\n\t */\n\n\tpc = duk_hthread_get_act_curr_pc(thr, act);\n\n\t/* XXX: this should be optimized to be a raw query and avoid valstack\n\t * operations if possible.\n\t */\n\tduk_push_tval(thr, &act->tv_func);\n\tline = duk_hobject_pc2line_query(thr, -1, pc);\n\tduk_pop(thr);\n\treturn line;\n}\n\nDUK_INTERNAL void duk_debug_send_status(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tduk_debug_write_notify(thr, DUK_DBG_CMD_STATUS);\n\tduk_debug_write_int(thr, (DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) ? 1 : 0));\n\n\tact = thr->callstack_curr;\n\tif (act == NULL) {\n\t\tduk_debug_write_undefined(thr);\n\t\tduk_debug_write_undefined(thr);\n\t\tduk_debug_write_int(thr, 0);\n\t\tduk_debug_write_int(thr, 0);\n\t} else {\n\t\tduk_push_tval(thr, &act->tv_func);\n\t\tduk_get_prop_literal(thr, -1, \"fileName\");\n\t\tduk__debug_write_hstring_safe_top(thr);\n\t\tduk_get_prop_literal(thr, -2, \"name\");\n\t\tduk__debug_write_hstring_safe_top(thr);\n\t\tduk_pop_3(thr);\n\t\t/* Report next pc/line to be executed. */\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) duk_debug_curr_line(thr));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) duk_hthread_get_act_curr_pc(thr, act));\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n\n#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)\nDUK_INTERNAL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal) {\n\t/*\n\t *  NFY <int: 5> <int: fatal> <str: msg> <str: filename> <int: linenumber> EOM\n\t */\n\n\tduk_activation *act;\n\tduk_uint32_t pc;\n\n\tDUK_ASSERT(thr->valstack_top > thr->valstack);  /* At least: ... [err] */\n\n\tduk_debug_write_notify(thr, DUK_DBG_CMD_THROW);\n\tduk_debug_write_int(thr, (duk_int32_t) fatal);\n\n\t/* Report thrown value to client coerced to string */\n\tduk_dup_top(thr);\n\tduk__debug_write_hstring_safe_top(thr);\n\tduk_pop(thr);\n\n\tif (duk_is_error(thr, -1)) {\n\t\t/* Error instance, use augmented error data directly */\n\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME);\n\t\tduk__debug_write_hstring_safe_top(thr);\n\t\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_LINE_NUMBER);\n\t\tduk_debug_write_uint(thr, duk_get_uint(thr, -1));\n\t\tduk_pop_2(thr);\n\t} else {\n\t\t/* For anything other than an Error instance, we calculate the\n\t\t * error location directly from the current activation if one\n\t\t * exists.\n\t\t */\n\t\tact = thr->callstack_curr;\n\t\tif (act != NULL) {\n\t\t\tduk_push_tval(thr, &act->tv_func);\n\t\t\tduk_get_prop_literal(thr, -1, \"fileName\");\n\t\t\tduk__debug_write_hstring_safe_top(thr);\n\t\t\tpc = (duk_uint32_t) duk_hthread_get_act_prev_pc(thr, act);\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) duk_hobject_pc2line_query(thr, -2, pc));\n\t\t\tduk_pop_2(thr);\n\t\t} else {\n\t\t\t/* Can happen if duk_throw() is called on an empty\n\t\t\t * callstack.\n\t\t\t */\n\t\t\tduk_debug_write_cstring(thr, \"\");\n\t\t\tduk_debug_write_uint(thr, 0);\n\t\t}\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n#endif  /* DUK_USE_DEBUGGER_THROW_NOTIFY */\n\n/*\n *  Debug message processing\n */\n\n/* Skip dvalue. */\nDUK_LOCAL duk_bool_t duk__debug_skip_dvalue(duk_hthread *thr) {\n\tduk_uint8_t x;\n\tduk_uint32_t len;\n\n\tx = duk_debug_read_byte(thr);\n\n\tif (x >= 0xc0) {\n\t\tduk_debug_skip_byte(thr);\n\t\treturn 0;\n\t}\n\tif (x >= 0x80) {\n\t\treturn 0;\n\t}\n\tif (x >= 0x60) {\n\t\tduk_debug_skip_bytes(thr, (duk_size_t) (x - 0x60));\n\t\treturn 0;\n\t}\n\tswitch(x) {\n\tcase DUK_DBG_IB_EOM:\n\t\treturn 1;  /* Return 1: got EOM */\n\tcase DUK_DBG_IB_REQUEST:\n\tcase DUK_DBG_IB_REPLY:\n\tcase DUK_DBG_IB_ERROR:\n\tcase DUK_DBG_IB_NOTIFY:\n\t\tbreak;\n\tcase DUK_DBG_IB_INT4:\n\t\t(void) duk__debug_read_uint32_raw(thr);\n\t\tbreak;\n\tcase DUK_DBG_IB_STR4:\n\tcase DUK_DBG_IB_BUF4:\n\t\tlen = duk__debug_read_uint32_raw(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_STR2:\n\tcase DUK_DBG_IB_BUF2:\n\t\tlen = duk__debug_read_uint16_raw(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_UNUSED:\n\tcase DUK_DBG_IB_UNDEFINED:\n\tcase DUK_DBG_IB_NULL:\n\tcase DUK_DBG_IB_TRUE:\n\tcase DUK_DBG_IB_FALSE:\n\t\tbreak;\n\tcase DUK_DBG_IB_NUMBER:\n\t\tduk_debug_skip_bytes(thr, 8);\n\t\tbreak;\n\tcase DUK_DBG_IB_OBJECT:\n\t\tduk_debug_skip_byte(thr);\n\t\tlen = duk_debug_read_byte(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_POINTER:\n\tcase DUK_DBG_IB_HEAPPTR:\n\t\tlen = duk_debug_read_byte(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_LIGHTFUNC:\n\t\tduk_debug_skip_bytes(thr, 2);\n\t\tlen = duk_debug_read_byte(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tdefault:\n\t\tgoto fail;\n\t}\n\n\treturn 0;\n\n fail:\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn 1;  /* Pretend like we got EOM */\n}\n\n/* Skip dvalues to EOM. */\nDUK_LOCAL void duk__debug_skip_to_eom(duk_hthread *thr) {\n\tfor (;;) {\n\t\tif (duk__debug_skip_dvalue(thr)) {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/* Read and validate a call stack index.  If index is invalid, write out an\n * error message and return zero.\n */\nDUK_LOCAL duk_int32_t duk__debug_read_validate_csindex(duk_hthread *thr) {\n\tduk_int32_t level;\n\tlevel = duk_debug_read_int(thr);\n\tif (level >= 0 || -level > (duk_int32_t) thr->callstack_top) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid callstack index\");\n\t\treturn 0;  /* zero indicates failure */\n\t}\n\treturn level;\n}\n\n/* Read a call stack index and lookup the corresponding duk_activation.\n * If index is invalid, write out an error message and return NULL.\n */\nDUK_LOCAL duk_activation *duk__debug_read_level_get_activation(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_int32_t level;\n\n\tlevel = duk_debug_read_int(thr);\n\tact = duk_hthread_get_activation_for_level(thr, level);\n\tif (act == NULL) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid callstack index\");\n\t}\n\treturn act;\n}\n\n/*\n *  Simple commands\n */\n\nDUK_LOCAL void duk__debug_handle_basic_info(duk_hthread *thr, duk_heap *heap) {\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command Version\"));\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_int(thr, DUK_VERSION);\n\tduk_debug_write_cstring(thr, DUK_GIT_DESCRIBE);\n\tduk_debug_write_cstring(thr, DUK_USE_TARGET_INFO);\n#if defined(DUK_USE_DOUBLE_LE)\n\tduk_debug_write_int(thr, 1);\n#elif defined(DUK_USE_DOUBLE_ME)\n\tduk_debug_write_int(thr, 2);\n#elif defined(DUK_USE_DOUBLE_BE)\n\tduk_debug_write_int(thr, 3);\n#else\n\tduk_debug_write_int(thr, 0);\n#endif\n\tduk_debug_write_int(thr, (duk_int_t) sizeof(void *));\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_trigger_status(duk_hthread *thr, duk_heap *heap) {\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command TriggerStatus\"));\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n\theap->dbg_state_dirty = 1;\n}\n\nDUK_LOCAL void duk__debug_handle_pause(duk_hthread *thr, duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"debug command Pause\"));\n\tduk_debug_set_paused(heap);\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_resume(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_uint_t pause_flags;\n\n\tDUK_D(DUK_DPRINT(\"debug command Resume\"));\n\n\tduk_debug_clear_paused(heap);\n\n\tpause_flags = 0;\n#if 0  /* manual testing */\n\tpause_flags |= DUK_PAUSE_FLAG_ONE_OPCODE;\n\tpause_flags |= DUK_PAUSE_FLAG_CAUGHT_ERROR;\n\tpause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;\n#endif\n#if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)\n\tpause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;\n#endif\n\n\tduk__debug_set_pause_state(thr, heap, pause_flags);\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_step(duk_hthread *thr, duk_heap *heap, duk_int32_t cmd) {\n\tduk_small_uint_t pause_flags;\n\n\tDUK_D(DUK_DPRINT(\"debug command StepInto/StepOver/StepOut: %d\", (int) cmd));\n\n\tif (cmd == DUK_DBG_CMD_STEPINTO) {\n\t\tpause_flags = DUK_PAUSE_FLAG_LINE_CHANGE |\n\t\t              DUK_PAUSE_FLAG_FUNC_ENTRY |\n\t\t              DUK_PAUSE_FLAG_FUNC_EXIT;\n\t} else if (cmd == DUK_DBG_CMD_STEPOVER) {\n\t\tpause_flags = DUK_PAUSE_FLAG_LINE_CHANGE |\n\t\t              DUK_PAUSE_FLAG_FUNC_EXIT;\n\t} else {\n\t\tDUK_ASSERT(cmd == DUK_DBG_CMD_STEPOUT);\n\t\tpause_flags = DUK_PAUSE_FLAG_FUNC_EXIT;\n\t}\n#if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)\n\tpause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;\n#endif\n\n\t/* If current activation doesn't have line information, line-based\n\t * pause flags are automatically disabled.  As a result, e.g.\n\t * StepInto will then pause on (native) function entry or exit.\n\t */\n\tduk_debug_clear_paused(heap);\n\tduk__debug_set_pause_state(thr, heap, pause_flags);\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_list_break(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_int_t i;\n\n\tDUK_D(DUK_DPRINT(\"debug command ListBreak\"));\n\tduk_debug_write_reply(thr);\n\tfor (i = 0; i < (duk_small_int_t) heap->dbg_breakpoint_count; i++) {\n\t\tduk_debug_write_hstring(thr, heap->dbg_breakpoints[i].filename);\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) heap->dbg_breakpoints[i].line);\n\t}\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_add_break(duk_hthread *thr, duk_heap *heap) {\n\tduk_hstring *filename;\n\tduk_uint32_t linenumber;\n\tduk_small_int_t idx;\n\n\tDUK_UNREF(heap);\n\n\tfilename = duk_debug_read_hstring(thr);\n\tlinenumber = (duk_uint32_t) duk_debug_read_int(thr);\n\tDUK_D(DUK_DPRINT(\"debug command AddBreak: %!O:%ld\", (duk_hobject *) filename, (long) linenumber));\n\tidx = duk_debug_add_breakpoint(thr, filename, linenumber);\n\tif (idx >= 0) {\n\t\tduk_debug_write_reply(thr);\n\t\tduk_debug_write_int(thr, (duk_int32_t) idx);\n\t\tduk_debug_write_eom(thr);\n\t} else {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_TOOMANY, \"no space for breakpoint\");\n\t}\n}\n\nDUK_LOCAL void duk__debug_handle_del_break(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_uint_t idx;\n\n\tDUK_UNREF(heap);\n\n\tDUK_D(DUK_DPRINT(\"debug command DelBreak\"));\n\tidx = (duk_small_uint_t) duk_debug_read_int(thr);\n\tif (duk_debug_remove_breakpoint(thr, idx)) {\n\t\tduk_debug_write_reply(thr);\n\t\tduk_debug_write_eom(thr);\n\t} else {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid breakpoint index\");\n\t}\n}\n\nDUK_LOCAL void duk__debug_handle_get_var(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hstring *str;\n\tduk_bool_t rc;\n\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command GetVar\"));\n\n\tact = duk__debug_read_level_get_activation(thr);\n\tif (act == NULL) {\n\t\treturn;\n\t}\n\tstr = duk_debug_read_hstring(thr);  /* push to stack */\n\tDUK_ASSERT(str != NULL);\n\n\trc = duk_js_getvar_activation(thr, act, str, 0);\n\n\tduk_debug_write_reply(thr);\n\tif (rc) {\n\t\tduk_debug_write_int(thr, 1);\n\t\tDUK_ASSERT(duk_get_tval(thr, -2) != NULL);\n\t\tduk_debug_write_tval(thr, duk_get_tval(thr, -2));\n\t} else {\n\t\tduk_debug_write_int(thr, 0);\n\t\tduk_debug_write_unused(thr);\n\t}\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_put_var(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hstring *str;\n\tduk_tval *tv;\n\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command PutVar\"));\n\n\tact = duk__debug_read_level_get_activation(thr);\n\tif (act == NULL) {\n\t\treturn;\n\t}\n\tstr = duk_debug_read_hstring(thr);  /* push to stack */\n\tDUK_ASSERT(str != NULL);\n\ttv = duk_debug_read_tval(thr);\n\tif (tv == NULL) {\n\t\t/* detached */\n\t\treturn;\n\t}\n\n\tduk_js_putvar_activation(thr, act, str, tv, 0);\n\n\t/* XXX: Current putvar implementation doesn't have a success flag,\n\t * add one and send to debug client?\n\t */\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_get_call_stack(duk_hthread *thr, duk_heap *heap) {\n\tduk_hthread *curr_thr = thr;\n\tduk_activation *curr_act;\n\tduk_uint_fast32_t pc;\n\tduk_uint_fast32_t line;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_UNREF(heap);\n\n\tduk_debug_write_reply(thr);\n\twhile (curr_thr != NULL) {\n\t\tfor (curr_act = curr_thr->callstack_curr; curr_act != NULL; curr_act = curr_act->parent) {\n\t\t\t/* PC/line semantics here are:\n\t\t\t *   - For callstack top we're conceptually between two\n\t\t\t *     opcodes and current PC indicates next line to\n\t\t\t *     execute, so report that (matches Status).\n\t\t\t *   - For other activations we're conceptually still\n\t\t\t *     executing the instruction at PC-1, so report that\n\t\t\t *     (matches error stacktrace behavior).\n\t\t\t *   - See: https://github.com/svaarala/duktape/issues/281\n\t\t\t */\n\n\t\t\t/* XXX: optimize to use direct reads, i.e. avoid\n\t\t\t * value stack operations.\n\t\t\t */\n\t\t\tduk_push_tval(thr, &curr_act->tv_func);\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME);\n\t\t\tduk__debug_write_hstring_safe_top(thr);\n\t\t\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME);\n\t\t\tduk__debug_write_hstring_safe_top(thr);\n\t\t\tpc = duk_hthread_get_act_curr_pc(thr, curr_act);\n\t\t\tif (curr_act != curr_thr->callstack_curr && pc > 0) {\n\t\t\t\tpc--;\n\t\t\t}\n\t\t\tline = duk_hobject_pc2line_query(thr, -3, pc);\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) line);\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) pc);\n\t\t\tduk_pop_3(thr);\n\t\t}\n\t\tcurr_thr = curr_thr->resumer;\n\t}\n\t/* SCANBUILD: warning about 'thr' potentially being NULL here,\n\t * warning is incorrect because thr != NULL always here.\n\t */\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_get_locals(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hstring *varname;\n\n\tDUK_UNREF(heap);\n\n\tact = duk__debug_read_level_get_activation(thr);\n\tif (act == NULL) {\n\t\treturn;\n\t}\n\n\tduk_debug_write_reply(thr);\n\n\t/* XXX: several nice-to-have improvements here:\n\t *   - Use direct reads avoiding value stack operations\n\t *   - Avoid triggering getters, indicate getter values to debug client\n\t *   - If side effects are possible, add error catching\n\t */\n\n\tif (DUK_TVAL_IS_OBJECT(&act->tv_func)) {\n\t\tduk_hobject *h_func = DUK_TVAL_GET_OBJECT(&act->tv_func);\n\t\tduk_hobject *h_varmap;\n\n\t\th_varmap = duk_hobject_get_varmap(thr, h_func);\n\t\tif (h_varmap != NULL) {\n\t\t\tduk_push_hobject(thr, h_varmap);\n\t\t\tduk_enum(thr, -1, 0 /*enum_flags*/);\n\t\t\twhile (duk_next(thr, -1 /*enum_index*/, 0 /*get_value*/)) {\n\t\t\t\tvarname = duk_known_hstring(thr, -1);\n\n\t\t\t\tduk_js_getvar_activation(thr, act, varname, 0 /*throw_flag*/);\n\t\t\t\t/* [ ... func varmap enum key value this ] */\n\t\t\t\tduk_debug_write_hstring(thr, duk_get_hstring(thr, -3));\n\t\t\t\tduk_debug_write_tval(thr, duk_get_tval(thr, -2));\n\t\t\t\tduk_pop_3(thr);  /* -> [ ... func varmap enum ] */\n\t\t\t}\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"varmap missing in GetLocals, ignore\"));\n\t\t}\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"varmap is not an object in GetLocals, ignore\"));\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_uint_t call_flags;\n\tduk_int_t call_ret;\n\tduk_small_int_t eval_err;\n\tduk_bool_t direct_eval;\n\tduk_int32_t level;\n\tduk_idx_t idx_func;\n\n\tDUK_UNREF(heap);\n\n\tDUK_D(DUK_DPRINT(\"debug command Eval\"));\n\n\t/* The eval code is executed within the lexical environment of a specified\n\t * activation.  For now, use global object eval() function, with the eval\n\t * considered a 'direct call to eval'.\n\t *\n\t * Callstack index for debug commands only affects scope -- the callstack\n\t * as seen by, e.g. Duktape.act() will be the same regardless.\n\t */\n\n\t/* nargs == 2 so we can pass a callstack index to eval(). */\n\tidx_func = duk_get_top(thr);\n\tduk_push_c_function(thr, duk_bi_global_object_eval, 2 /*nargs*/);\n\tduk_push_undefined(thr);  /* 'this' binding shouldn't matter here */\n\n\t/* Read callstack index, if non-null. */\n\tif (duk_debug_peek_byte(thr) == DUK_DBG_IB_NULL) {\n\t\tdirect_eval = 0;\n\t\tlevel = -1;  /* Not needed, but silences warning. */\n\t\t(void) duk_debug_read_byte(thr);\n\t} else {\n\t\tdirect_eval = 1;\n\t\tlevel = duk__debug_read_validate_csindex(thr);\n\t\tif (level == 0) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\tDUK_ASSERT(!direct_eval ||\n\t           (level < 0 && -level <= (duk_int32_t) thr->callstack_top));\n\n\t(void) duk_debug_read_hstring(thr);\n\tif (direct_eval) {\n\t\tduk_push_int(thr, level - 1);  /* compensate for eval() call */\n\t}\n\n\t/* [ ... eval \"eval\" eval_input level? ] */\n\n\tcall_flags = 0;\n\tif (direct_eval) {\n\t\tduk_activation *act;\n\t\tduk_hobject *fun;\n\n\t\tact = duk_hthread_get_activation_for_level(thr, level);\n\t\tif (act != NULL) {\n\t\t\tfun = DUK_ACT_GET_FUNC(act);\n\t\t\tif (fun != NULL && DUK_HOBJECT_IS_COMPFUNC(fun)) {\n\t\t\t\t/* Direct eval requires that there's a current\n\t\t\t\t * activation and it is an ECMAScript function.\n\t\t\t\t * When Eval is executed from e.g. cooperate API\n\t\t\t\t * call we'll need to do an indirect eval instead.\n\t\t\t\t */\n\t\t\t\tcall_flags |= DUK_CALL_FLAG_DIRECT_EVAL;\n\t\t\t}\n\t\t}\n\t}\n\n\tcall_ret = duk_pcall_method_flags(thr, duk_get_top(thr) - (idx_func + 2), call_flags);\n\n\tif (call_ret == DUK_EXEC_SUCCESS) {\n\t\teval_err = 0;\n\t\t/* Use result value as is. */\n\t} else {\n\t\t/* For errors a string coerced result is most informative\n\t\t * right now, as the debug client doesn't have the capability\n\t\t * to traverse the error object.\n\t\t */\n\t\teval_err = 1;\n\t\tduk_safe_to_string(thr, -1);\n\t}\n\n\t/* [ ... result ] */\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_int(thr, (duk_int32_t) eval_err);\n\tDUK_ASSERT(duk_get_tval(thr, -1) != NULL);\n\tduk_debug_write_tval(thr, duk_get_tval(thr, -1));\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_detach(duk_hthread *thr, duk_heap *heap) {\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command Detach\"));\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n\n\tDUK_D(DUK_DPRINT(\"debug connection detached, mark broken\"));\n\tDUK__SET_CONN_BROKEN(thr, 0);  /* not an error */\n}\n\nDUK_LOCAL void duk__debug_handle_apprequest(duk_hthread *thr, duk_heap *heap) {\n\tduk_idx_t old_top;\n\n\tDUK_D(DUK_DPRINT(\"debug command AppRequest\"));\n\n\told_top = duk_get_top(thr);  /* save stack top */\n\n\tif (heap->dbg_request_cb != NULL) {\n\t\tduk_idx_t nrets;\n\t\tduk_idx_t nvalues = 0;\n\t\tduk_idx_t top, idx;\n\n\t\t/* Read tvals from the message and push them onto the valstack,\n\t\t * then call the request callback to process the request.\n\t\t */\n\t\twhile (duk_debug_peek_byte(thr) != DUK_DBG_IB_EOM) {\n\t\t\tduk_tval *tv;\n\t\t\tif (!duk_check_stack(thr, 1)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"failed to allocate space for request dvalue(s)\"));\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\ttv = duk_debug_read_tval(thr);  /* push to stack */\n\t\t\tif (tv == NULL) {\n\t\t\t\t/* detached */\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnvalues++;\n\t\t}\n\t\tDUK_ASSERT(duk_get_top(thr) == old_top + nvalues);\n\n\t\t/* Request callback should push values for reply to client onto valstack */\n\t\tDUK_D(DUK_DPRINT(\"calling into AppRequest request_cb with nvalues=%ld, old_top=%ld, top=%ld\",\n\t\t                 (long) nvalues, (long) old_top, (long) duk_get_top(thr)));\n\t\tnrets = heap->dbg_request_cb(thr, heap->dbg_udata, nvalues);\n\t\tDUK_D(DUK_DPRINT(\"returned from AppRequest request_cb; nvalues=%ld -> nrets=%ld, old_top=%ld, top=%ld\",\n\t\t                 (long) nvalues, (long) nrets, (long) old_top, (long) duk_get_top(thr)));\n\t\tif (nrets >= 0) {\n\t\t\tDUK_ASSERT(duk_get_top(thr) >= old_top + nrets);\n\t\t\tif (duk_get_top(thr) < old_top + nrets) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"AppRequest callback doesn't match value stack configuration, \"\n\t\t\t\t                 \"top=%ld < old_top=%ld + nrets=%ld; \"\n\t\t\t\t                 \"this might mean it's unsafe to continue!\",\n\t\t\t\t                 (long) duk_get_top(thr), (long) old_top, (long) nrets));\n\t\t\t\tgoto fail;\n\t\t\t}\n\n\t\t\t/* Reply with tvals pushed by request callback */\n\t\t\tduk_debug_write_byte(thr, DUK_DBG_IB_REPLY);\n\t\t\ttop = duk_get_top(thr);\n\t\t\tfor (idx = top - nrets; idx < top; idx++) {\n\t\t\t\tduk_debug_write_tval(thr, DUK_GET_TVAL_POSIDX(thr, idx));\n\t\t\t}\n\t\t\tduk_debug_write_eom(thr);\n\t\t} else {\n\t\t\tDUK_ASSERT(duk_get_top(thr) >= old_top + 1);\n\t\t\tif (duk_get_top(thr) < old_top + 1) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"request callback return value doesn't match value stack configuration\"));\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_APPLICATION, duk_get_string(thr, -1));\n\t\t}\n\n\t\tduk_set_top(thr, old_top);  /* restore stack top */\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"no request callback, treat AppRequest as unsupported\"));\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNSUPPORTED, \"AppRequest unsupported by target\");\n\t}\n\n\treturn;\n\n fail:\n\tduk_set_top(thr, old_top);  /* restore stack top */\n\tDUK__SET_CONN_BROKEN(thr, 1);\n}\n\n/*\n *  DumpHeap command\n */\n\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP)\n/* XXX: this has some overlap with object inspection; remove this and make\n * DumpHeap return lists of heapptrs instead?\n */\nDUK_LOCAL void duk__debug_dump_heaphdr(duk_hthread *thr, duk_heap *heap, duk_heaphdr *hdr) {\n\tDUK_UNREF(heap);\n\n\tduk_debug_write_heapptr(thr, hdr);\n\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HEAPHDR_GET_TYPE(hdr));\n\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HEAPHDR_GET_FLAGS_RAW(hdr));\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HEAPHDR_GET_REFCOUNT(hdr));\n#else\n\tduk_debug_write_int(thr, (duk_int32_t) -1);\n#endif\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(hdr)) {\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h = (duk_hstring *) hdr;\n\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_BYTELEN(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_CHARLEN(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_HASH(h));\n\t\tduk_debug_write_hstring(thr, h);\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h = (duk_hobject *) hdr;\n\t\tduk_hstring *k;\n\t\tduk_uint_fast32_t i;\n\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_CLASS_NUMBER(h));\n\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(heap, h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_ESIZE(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_ENEXT(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_ASIZE(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_HSIZE(h));\n\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_E_GET_FLAGS(heap, h, i));\n\t\t\tk = DUK_HOBJECT_E_GET_KEY(heap, h, i);\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) k);\n\t\t\tif (k == NULL) {\n\t\t\t\tduk_debug_write_int(thr, 0);  /* isAccessor */\n\t\t\t\tduk_debug_write_unused(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)) {\n\t\t\t\tduk_debug_write_int(thr, 1);  /* isAccessor */\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.get);\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.set);\n\t\t\t} else {\n\t\t\t\tduk_debug_write_int(thr, 0);  /* isAccessor */\n\n\t\t\t\tduk__debug_write_tval_heapptr(thr, &DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->v);\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(h); i++) {\n\t\t\t/* Note: array dump will include elements beyond\n\t\t\t * 'length'.\n\t\t\t */\n\t\t\tduk__debug_write_tval_heapptr(thr, DUK_HOBJECT_A_GET_VALUE_PTR(heap, h, i));\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h = (duk_hbuffer *) hdr;\n\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HBUFFER_GET_SIZE(h));\n\t\tduk_debug_write_buffer(thr, (const char *) DUK_HBUFFER_GET_DATA_PTR(heap, h), (duk_size_t) DUK_HBUFFER_GET_SIZE(h));\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tDUK_D(DUK_DPRINT(\"invalid htype: %d\", (int) DUK_HEAPHDR_GET_TYPE(hdr)));\n\t}\n\t}\n}\n\nDUK_LOCAL void duk__debug_dump_heap_allocated(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\n\thdr = heap->heap_allocated;\n\twhile (hdr != NULL) {\n\t\tduk__debug_dump_heaphdr(thr, heap, hdr);\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n}\n\nDUK_LOCAL void duk__debug_dump_strtab(duk_hthread *thr, duk_heap *heap) {\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\n\tfor (i = 0; i < heap->st_size; i++) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\th = DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, heap->strtable16[i]);\n#else\n\t\th = heap->strtable[i];\n#endif\n\t\twhile (h != NULL) {\n\t\t\tduk__debug_dump_heaphdr(thr, heap, (duk_heaphdr *) h);\n\t\t\th = h->hdr.h_next;\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__debug_handle_dump_heap(duk_hthread *thr, duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"debug command DumpHeap\"));\n\n\tduk_debug_write_reply(thr);\n\tduk__debug_dump_heap_allocated(thr, heap);\n\tduk__debug_dump_strtab(thr, heap);\n\tduk_debug_write_eom(thr);\n}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP */\n\nDUK_LOCAL void duk__debug_handle_get_bytecode(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hcompfunc *fun = NULL;\n\tduk_size_t i, n;\n\tduk_tval *tv;\n\tduk_hobject **fn;\n\tduk_int32_t level = -1;\n\tduk_uint8_t ibyte;\n\n\tDUK_UNREF(heap);\n\n\tDUK_D(DUK_DPRINT(\"debug command GetBytecode\"));\n\n\tibyte = duk_debug_peek_byte(thr);\n\tif (ibyte != DUK_DBG_IB_EOM) {\n\t\ttv = duk_debug_read_tval(thr);\n\t\tif (tv == NULL) {\n\t\t\t/* detached */\n\t\t\treturn;\n\t\t}\n\t\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\t\t/* tentative, checked later */\n\t\t\tfun = (duk_hcompfunc *) DUK_TVAL_GET_OBJECT(tv);\n\t\t\tDUK_ASSERT(fun != NULL);\n\t\t} else if (DUK_TVAL_IS_NUMBER(tv)) {\n\t\t\tlevel = (duk_int32_t) DUK_TVAL_GET_NUMBER(tv);\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"invalid argument to GetBytecode: %!T\", tv));\n\t\t\tgoto fail_args;\n\t\t}\n\t}\n\n\tif (fun == NULL) {\n\t\tact = duk_hthread_get_activation_for_level(thr, level);\n\t\tif (act == NULL) {\n\t\t\tgoto fail_index;\n\t\t}\n\t\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\t}\n\n\tif (fun == NULL || !DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun)) {\n\t\tDUK_D(DUK_DPRINT(\"invalid argument to GetBytecode: %!O\", fun));\n\t\tgoto fail_args;\n\t}\n\tDUK_ASSERT(fun != NULL && DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun));\n\n\tduk_debug_write_reply(thr);\n\tn = DUK_HCOMPFUNC_GET_CONSTS_COUNT(heap, fun);\n\tduk_debug_write_int(thr, (duk_int32_t) n);\n\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, fun);\n\tfor (i = 0; i < n; i++) {\n\t\tduk_debug_write_tval(thr, tv);\n\t\ttv++;\n\t}\n\tn = DUK_HCOMPFUNC_GET_FUNCS_COUNT(heap, fun);\n\tduk_debug_write_int(thr, (duk_int32_t) n);\n\tfn = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, fun);\n\tfor (i = 0; i < n; i++) {\n\t\tduk_debug_write_hobject(thr, *fn);\n\t\tfn++;\n\t}\n\tduk_debug_write_string(thr,\n\t                       (const char *) DUK_HCOMPFUNC_GET_CODE_BASE(heap, fun),\n\t                       (duk_size_t) DUK_HCOMPFUNC_GET_CODE_SIZE(heap, fun));\n\tduk_debug_write_eom(thr);\n\treturn;\n\n fail_args:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid argument\");\n\treturn;\n\n fail_index:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid callstack index\");\n\treturn;\n}\n\n/*\n *  Object inspection commands: GetHeapObjInfo, GetObjPropDesc,\n *  GetObjPropDescRange\n */\n\n#if defined(DUK_USE_DEBUGGER_INSPECT)\n\n#if 0 /* pruned */\nDUK_LOCAL const char * const duk__debug_getinfo_heaphdr_keys[] = {\n\t\"reachable\",\n\t\"temproot\",\n\t\"finalizable\",\n\t\"finalized\",\n\t\"readonly\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_heaphdr_masks[] = {\n\tDUK_HEAPHDR_FLAG_REACHABLE,\n\tDUK_HEAPHDR_FLAG_TEMPROOT,\n\tDUK_HEAPHDR_FLAG_FINALIZABLE,\n\tDUK_HEAPHDR_FLAG_FINALIZED,\n\tDUK_HEAPHDR_FLAG_READONLY,\n\t0  /* terminator */\n};\n#endif\nDUK_LOCAL const char * const duk__debug_getinfo_hstring_keys[] = {\n#if 0\n\t\"arridx\",\n\t\"symbol\",\n\t\"hidden\",\n\t\"reserved_word\",\n\t\"strict_reserved_word\",\n\t\"eval_or_arguments\",\n#endif\n\t\"extdata\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_hstring_masks[] = {\n#if 0\n\tDUK_HSTRING_FLAG_ARRIDX,\n\tDUK_HSTRING_FLAG_SYMBOL,\n\tDUK_HSTRING_FLAG_HIDDEN,\n\tDUK_HSTRING_FLAG_RESERVED_WORD,\n\tDUK_HSTRING_FLAG_STRICT_RESERVED_WORD,\n\tDUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS,\n#endif\n\tDUK_HSTRING_FLAG_EXTDATA,\n\t0  /* terminator */\n};\nDUK_LOCAL const char * const duk__debug_getinfo_hobject_keys[] = {\n\t\"extensible\",\n\t\"constructable\",\n\t\"callable\",\n\t\"boundfunc\",\n\t\"compfunc\",\n\t\"natfunc\",\n\t\"bufobj\",\n\t\"fastrefs\",\n\t\"array_part\",\n\t\"strict\",\n\t\"notail\",\n\t\"newenv\",\n\t\"namebinding\",\n\t\"createargs\",\n\t\"have_finalizer\",\n\t\"exotic_array\",\n\t\"exotic_stringobj\",\n\t\"exotic_arguments\",\n\t\"exotic_proxyobj\",\n\t\"special_call\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_hobject_masks[] = {\n\tDUK_HOBJECT_FLAG_EXTENSIBLE,\n\tDUK_HOBJECT_FLAG_CONSTRUCTABLE,\n\tDUK_HOBJECT_FLAG_CALLABLE,\n\tDUK_HOBJECT_FLAG_BOUNDFUNC,\n\tDUK_HOBJECT_FLAG_COMPFUNC,\n\tDUK_HOBJECT_FLAG_NATFUNC,\n\tDUK_HOBJECT_FLAG_BUFOBJ,\n\tDUK_HOBJECT_FLAG_FASTREFS,\n\tDUK_HOBJECT_FLAG_ARRAY_PART,\n\tDUK_HOBJECT_FLAG_STRICT,\n\tDUK_HOBJECT_FLAG_NOTAIL,\n\tDUK_HOBJECT_FLAG_NEWENV,\n\tDUK_HOBJECT_FLAG_NAMEBINDING,\n\tDUK_HOBJECT_FLAG_CREATEARGS,\n\tDUK_HOBJECT_FLAG_HAVE_FINALIZER,\n\tDUK_HOBJECT_FLAG_EXOTIC_ARRAY,\n\tDUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ,\n\tDUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS,\n\tDUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ,\n\tDUK_HOBJECT_FLAG_SPECIAL_CALL,\n\t0  /* terminator */\n};\nDUK_LOCAL const char * const duk__debug_getinfo_hbuffer_keys[] = {\n\t\"dynamic\",\n\t\"external\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_hbuffer_masks[] = {\n\tDUK_HBUFFER_FLAG_DYNAMIC,\n\tDUK_HBUFFER_FLAG_EXTERNAL,\n\t0  /* terminator */\n};\n\nDUK_LOCAL void duk__debug_getinfo_flags_key(duk_hthread *thr, const char *key) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n}\n\nDUK_LOCAL void duk__debug_getinfo_prop_uint(duk_hthread *thr, const char *key, duk_uint_t val) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n\tduk_debug_write_uint(thr, val);\n}\n\nDUK_LOCAL void duk__debug_getinfo_prop_int(duk_hthread *thr, const char *key, duk_int_t val) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n\tduk_debug_write_int(thr, val);\n}\n\nDUK_LOCAL void duk__debug_getinfo_prop_bool(duk_hthread *thr, const char *key, duk_bool_t val) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n\tduk_debug_write_boolean(thr, val);\n}\n\nDUK_LOCAL void duk__debug_getinfo_bitmask(duk_hthread *thr, const char * const * keys, duk_uint_t *masks, duk_uint_t flags) {\n\tconst char *key;\n\tduk_uint_t mask;\n\n\tfor (;;) {\n\t\tmask = *masks++;\n\t\tif (mask == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tkey = *keys++;\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tDUK_DD(DUK_DDPRINT(\"inspect bitmask: key=%s, mask=0x%08lx, flags=0x%08lx\", key, (unsigned long) mask, (unsigned long) flags));\n\t\tduk__debug_getinfo_prop_bool(thr, key, flags & mask);\n\t}\n}\n\n/* Inspect a property using a virtual index into a conceptual property list\n * consisting of (1) all array part items from [0,a_size[ (even when above\n * .length) and (2) all entry part items from [0,e_next[.  Unused slots are\n * indicated using dvalue 'unused'.\n */\nDUK_LOCAL duk_bool_t duk__debug_getprop_index(duk_hthread *thr, duk_heap *heap, duk_hobject *h_obj, duk_uint_t idx) {\n\tduk_uint_t a_size;\n\tduk_tval *tv;\n\tduk_hstring *h_key;\n\tduk_hobject *h_getset;\n\tduk_uint_t flags;\n\n\tDUK_UNREF(heap);\n\n\ta_size = DUK_HOBJECT_GET_ASIZE(h_obj);\n\tif (idx < a_size) {\n\t\tduk_debug_write_uint(thr, DUK_PROPDESC_FLAGS_WEC);\n\t\tduk_debug_write_uint(thr, idx);\n\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(heap, h_obj, idx);\n\t\tduk_debug_write_tval(thr, tv);\n\t\treturn 1;\n\t}\n\n\tidx -= a_size;\n\tif (idx >= DUK_HOBJECT_GET_ENEXT(h_obj)) {\n\t\treturn 0;\n\t}\n\n\th_key = DUK_HOBJECT_E_GET_KEY(heap, h_obj, idx);\n\tif (h_key == NULL) {\n\t\tduk_debug_write_uint(thr, 0);\n\t\tduk_debug_write_null(thr);\n\t\tduk_debug_write_unused(thr);\n\t\treturn 1;\n\t}\n\n\tflags = DUK_HOBJECT_E_GET_FLAGS(heap, h_obj, idx);\n\tif (DUK_HSTRING_HAS_SYMBOL(h_key)) {\n\t\tflags |= DUK_DBG_PROPFLAG_SYMBOL;\n\t}\n\tif (DUK_HSTRING_HAS_HIDDEN(h_key)) {\n\t\tflags |= DUK_DBG_PROPFLAG_HIDDEN;\n\t}\n\tduk_debug_write_uint(thr, flags);\n\tduk_debug_write_hstring(thr, h_key);\n\tif (flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\th_getset = DUK_HOBJECT_E_GET_VALUE_GETTER(heap, h_obj, idx);\n\t\tif (h_getset) {\n\t\t\tduk_debug_write_hobject(thr, h_getset);\n\t\t} else {\n\t\t\tduk_debug_write_null(thr);\n\t\t}\n\t\th_getset = DUK_HOBJECT_E_GET_VALUE_SETTER(heap, h_obj, idx);\n\t\tif (h_getset) {\n\t\t\tduk_debug_write_hobject(thr, h_getset);\n\t\t} else {\n\t\t\tduk_debug_write_null(thr);\n\t\t}\n\t} else {\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, h_obj, idx);\n\t\tduk_debug_write_tval(thr, tv);\n\t}\n\treturn 1;\n}\n\nDUK_LOCAL void duk__debug_handle_get_heap_obj_info(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *h;\n\n\tDUK_D(DUK_DPRINT(\"debug command GetHeapObjInfo\"));\n\tDUK_UNREF(heap);\n\n\tDUK_ASSERT(sizeof(duk__debug_getinfo_hstring_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hstring_masks) / sizeof(duk_uint_t) - 1);\n\tDUK_ASSERT(sizeof(duk__debug_getinfo_hobject_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hobject_masks) / sizeof(duk_uint_t) - 1);\n\tDUK_ASSERT(sizeof(duk__debug_getinfo_hbuffer_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hbuffer_masks) / sizeof(duk_uint_t) - 1);\n\n\th = duk_debug_read_any_ptr(thr);\n\tif (!h) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid target\");\n\t\treturn;\n\t}\n\n\tduk_debug_write_reply(thr);\n\n\t/* As with all inspection code, we rely on the debug client providing\n\t * a valid, non-stale pointer: there's no portable way to safely\n\t * validate the pointer here.\n\t */\n\n\tduk__debug_getinfo_flags_key(thr, \"heapptr\");\n\tduk_debug_write_heapptr(thr, h);\n\n\t/* XXX: comes out as signed now */\n\tduk__debug_getinfo_prop_uint(thr, \"heaphdr_flags\", (duk_uint_t) DUK_HEAPHDR_GET_FLAGS(h));\n\tduk__debug_getinfo_prop_uint(thr, \"heaphdr_type\", (duk_uint_t) DUK_HEAPHDR_GET_TYPE(h));\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__debug_getinfo_prop_uint(thr, \"refcount\", (duk_uint_t) DUK_HEAPHDR_GET_REFCOUNT(h));\n#endif\n#if 0 /* pruned */\n\tduk__debug_getinfo_bitmask(thr,\n\t                           duk__debug_getinfo_heaphdr_keys,\n\t                           duk__debug_getinfo_heaphdr_masks,\n\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n#endif\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h_str;\n\n\t\th_str = (duk_hstring *) h;\n\t\tduk__debug_getinfo_bitmask(thr,\n\t\t                           duk__debug_getinfo_hstring_keys,\n\t\t                           duk__debug_getinfo_hstring_masks,\n\t\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n\t\tduk__debug_getinfo_prop_uint(thr, \"bytelen\", (duk_uint_t) DUK_HSTRING_GET_BYTELEN(h_str));\n\t\tduk__debug_getinfo_prop_uint(thr, \"charlen\", (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h_str));\n\t\tduk__debug_getinfo_prop_uint(thr, \"hash\", (duk_uint_t) DUK_HSTRING_GET_HASH(h_str));\n\t\tduk__debug_getinfo_flags_key(thr, \"data\");\n\t\tduk_debug_write_hstring(thr, h_str);\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h_obj;\n\t\tduk_hobject *h_proto;\n\n\t\th_obj = (duk_hobject *) h;\n\t\th_proto = DUK_HOBJECT_GET_PROTOTYPE(heap, h_obj);\n\n\t\t/* duk_hobject specific fields. */\n\t\tduk__debug_getinfo_bitmask(thr,\n\t\t                           duk__debug_getinfo_hobject_keys,\n\t\t                           duk__debug_getinfo_hobject_masks,\n\t\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n\t\tduk__debug_getinfo_prop_uint(thr, \"class_number\", DUK_HOBJECT_GET_CLASS_NUMBER(h_obj));\n\t\tduk__debug_getinfo_flags_key(thr, \"class_name\");\n\t\tduk_debug_write_hstring(thr, DUK_HOBJECT_GET_CLASS_STRING(heap, h_obj));\n\t\tduk__debug_getinfo_flags_key(thr, \"prototype\");\n\t\tif (h_proto != NULL) {\n\t\t\tduk_debug_write_hobject(thr, h_proto);\n\t\t} else {\n\t\t\tduk_debug_write_null(thr);\n\t\t}\n\t\tduk__debug_getinfo_flags_key(thr, \"props\");\n\t\tduk_debug_write_pointer(thr, (void *) DUK_HOBJECT_GET_PROPS(heap, h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"e_size\", (duk_uint_t) DUK_HOBJECT_GET_ESIZE(h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"e_next\", (duk_uint_t) DUK_HOBJECT_GET_ENEXT(h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"a_size\", (duk_uint_t) DUK_HOBJECT_GET_ASIZE(h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"h_size\", (duk_uint_t) DUK_HOBJECT_GET_HSIZE(h_obj));\n\n\t\tif (DUK_HOBJECT_IS_ARRAY(h_obj)) {\n\t\t\tduk_harray *h_arr;\n\t\t\th_arr = (duk_harray *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"length\", (duk_uint_t) h_arr->length);\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"length_nonwritable\", h_arr->length_nonwritable);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_NATFUNC(h_obj)) {\n\t\t\tduk_hnatfunc *h_fun;\n\t\t\th_fun = (duk_hnatfunc *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_int(thr, \"nargs\", h_fun->nargs);\n\t\t\tduk__debug_getinfo_prop_int(thr, \"magic\", h_fun->magic);\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"varargs\", h_fun->magic == DUK_HNATFUNC_NARGS_VARARGS);\n\t\t\t/* Native function pointer may be different from a void pointer,\n\t\t\t * and we serialize it from memory directly now (no byte swapping etc).\n\t\t\t */\n\t\t\tduk__debug_getinfo_flags_key(thr, \"funcptr\");\n\t\t\tduk_debug_write_buffer(thr, (const char *) &h_fun->func, sizeof(h_fun->func));\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tduk_hcompfunc *h_fun;\n\t\t\tduk_hbuffer *h_buf;\n\t\t\tduk_hobject *h_lexenv;\n\t\t\tduk_hobject *h_varenv;\n\t\t\th_fun = (duk_hcompfunc *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_int(thr, \"nregs\", h_fun->nregs);\n\t\t\tduk__debug_getinfo_prop_int(thr, \"nargs\", h_fun->nargs);\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"lex_env\");\n\t\t\th_lexenv = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, h_fun);\n\t\t\tif (h_lexenv != NULL) {\n\t\t\t\tduk_debug_write_hobject(thr, h_lexenv);\n\t\t\t} else {\n\t\t\t\tduk_debug_write_null(thr);\n\t\t\t}\n\t\t\tduk__debug_getinfo_flags_key(thr, \"var_env\");\n\t\t\th_varenv = DUK_HCOMPFUNC_GET_VARENV(thr->heap, h_fun);\n\t\t\tif (h_varenv != NULL) {\n\t\t\t\tduk_debug_write_hobject(thr, h_varenv);\n\t\t\t} else {\n\t\t\t\tduk_debug_write_null(thr);\n\t\t\t}\n\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"start_line\", h_fun->start_line);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"end_line\", h_fun->end_line);\n\t\t\th_buf = (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(thr->heap, h_fun);\n\t\t\tif (h_buf != NULL) {\n\t\t\t\tduk__debug_getinfo_flags_key(thr, \"data\");\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) h_buf);\n\t\t\t}\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_BOUNDFUNC(h_obj)) {\n\t\t\tduk_hboundfunc *h_bfun;\n\t\t\th_bfun = (duk_hboundfunc *) (void *) h_obj;\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"target\");\n\t\t\tduk_debug_write_tval(thr, &h_bfun->target);\n\t\t\tduk__debug_getinfo_flags_key(thr, \"this_binding\");\n\t\t\tduk_debug_write_tval(thr, &h_bfun->this_binding);\n\t\t\tduk__debug_getinfo_flags_key(thr, \"nargs\");\n\t\t\tduk_debug_write_int(thr, h_bfun->nargs);\n\t\t\t/* h_bfun->args not exposed now */\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_THREAD(h_obj)) {\n\t\t\t/* XXX: Currently no inspection of threads, e.g. value stack, call\n\t\t\t * stack, catch stack, etc.\n\t\t\t */\n\t\t\tduk_hthread *h_thr;\n\t\t\th_thr = (duk_hthread *) h_obj;\n\t\t\tDUK_UNREF(h_thr);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_DECENV(h_obj)) {\n\t\t\tduk_hdecenv *h_env;\n\t\t\th_env = (duk_hdecenv *) h_obj;\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"thread\");\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->thread));\n\t\t\tduk__debug_getinfo_flags_key(thr, \"varmap\");\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->varmap));\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"regbase\", (duk_uint_t) h_env->regbase_byteoff);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_OBJENV(h_obj)) {\n\t\t\tduk_hobjenv *h_env;\n\t\t\th_env = (duk_hobjenv *) h_obj;\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"target\");\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->target));\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"has_this\", h_env->has_this);\n\t\t}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\tduk_hbufobj *h_bufobj;\n\t\t\th_bufobj = (duk_hbufobj *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"slice_offset\", h_bufobj->offset);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"slice_length\", h_bufobj->length);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"elem_shift\", (duk_uint_t) h_bufobj->shift);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"elem_type\", (duk_uint_t) h_bufobj->elem_type);\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"is_typedarray\", (duk_uint_t) h_bufobj->is_typedarray);\n\t\t\tif (h_bufobj->buf != NULL) {\n\t\t\t\tduk__debug_getinfo_flags_key(thr, \"buffer\");\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) h_bufobj->buf);\n\t\t\t}\n\t\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h_buf;\n\n\t\th_buf = (duk_hbuffer *) h;\n\t\tduk__debug_getinfo_bitmask(thr,\n\t\t                           duk__debug_getinfo_hbuffer_keys,\n\t\t                           duk__debug_getinfo_hbuffer_masks,\n\t\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n\t\tduk__debug_getinfo_prop_uint(thr, \"size\", (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_buf));\n\t\tduk__debug_getinfo_flags_key(thr, \"dataptr\");\n\t\tduk_debug_write_pointer(thr, (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_buf));\n\t\tduk__debug_getinfo_flags_key(thr, \"data\");\n\t\tduk_debug_write_hbuffer(thr, h_buf);  /* tolerates NULL h_buf */\n\t\tbreak;\n\t}\n\tdefault: {\n\t\t/* Since we already started writing the reply, just emit nothing. */\n\t\tDUK_D(DUK_DPRINT(\"inspect target pointer has invalid heaphdr type\"));\n\t}\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_get_obj_prop_desc(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *h;\n\tduk_hobject *h_obj;\n\tduk_hstring *h_key;\n\tduk_propdesc desc;\n\n\tDUK_D(DUK_DPRINT(\"debug command GetObjPropDesc\"));\n\tDUK_UNREF(heap);\n\n\th = duk_debug_read_any_ptr(thr);\n\tif (!h) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid target\");\n\t\treturn;\n\t}\n\th_key = duk_debug_read_hstring(thr);\n\tif (h == NULL || DUK_HEAPHDR_GET_TYPE(h) != DUK_HTYPE_OBJECT || h_key == NULL) {\n\t\tgoto fail_args;\n\t}\n\th_obj = (duk_hobject *) h;\n\n\tif (duk_hobject_get_own_propdesc(thr, h_obj, h_key, &desc, 0 /*flags*/)) {\n\t\tduk_int_t virtual_idx;\n\t\tduk_bool_t rc;\n\n\t\t/* To use the shared helper need the virtual index. */\n\t\tDUK_ASSERT(desc.e_idx >= 0 || desc.a_idx >= 0);\n\t\tvirtual_idx = (desc.a_idx >= 0 ? desc.a_idx :\n\t\t               (duk_int_t) DUK_HOBJECT_GET_ASIZE(h_obj) + desc.e_idx);\n\n\t\tduk_debug_write_reply(thr);\n\t\trc = duk__debug_getprop_index(thr, heap, h_obj, (duk_uint_t) virtual_idx);\n\t\tDUK_ASSERT(rc == 1);\n\t\tDUK_UNREF(rc);\n\t\tduk_debug_write_eom(thr);\n\t} else {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"not found\");\n\t}\n\treturn;\n\n fail_args:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid args\");\n}\n\nDUK_LOCAL void duk__debug_handle_get_obj_prop_desc_range(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *h;\n\tduk_hobject *h_obj;\n\tduk_uint_t idx, idx_start, idx_end;\n\n\tDUK_D(DUK_DPRINT(\"debug command GetObjPropDescRange\"));\n\tDUK_UNREF(heap);\n\n\th = duk_debug_read_any_ptr(thr);\n\tidx_start = (duk_uint_t) duk_debug_read_int(thr);\n\tidx_end = (duk_uint_t) duk_debug_read_int(thr);\n\tif (h == NULL || DUK_HEAPHDR_GET_TYPE(h) != DUK_HTYPE_OBJECT) {\n\t\tgoto fail_args;\n\t}\n\th_obj = (duk_hobject *) h;\n\n\t/* The index range space is conceptually the array part followed by the\n\t * entry part.  Unlike normal enumeration all slots are exposed here as\n\t * is and return 'unused' if the slots are not in active use.  In particular\n\t * the array part is included for the full a_size regardless of what the\n\t * array .length is.\n\t */\n\n\tduk_debug_write_reply(thr);\n\tfor (idx = idx_start; idx < idx_end; idx++) {\n\t\tif (!duk__debug_getprop_index(thr, heap, h_obj, idx)) {\n\t\t\tbreak;\n\t\t}\n\t}\n\tduk_debug_write_eom(thr);\n\treturn;\n\n fail_args:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid args\");\n}\n\n#endif  /* DUK_USE_DEBUGGER_INSPECT */\n\n/*\n *  Process incoming debug requests\n *\n *  Individual request handlers can push temporaries on the value stack and\n *  rely on duk__debug_process_message() to restore the value stack top\n *  automatically.\n */\n\n/* Process one debug message.  Automatically restore value stack top to its\n * entry value, so that individual message handlers don't need exact value\n * stack handling which is convenient.\n */\nDUK_LOCAL void duk__debug_process_message(duk_hthread *thr) {\n\tduk_heap *heap;\n\tduk_uint8_t x;\n\tduk_int32_t cmd;\n\tduk_idx_t entry_top;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tentry_top = duk_get_top(thr);\n\n\tx = duk_debug_read_byte(thr);\n\tswitch (x) {\n\tcase DUK_DBG_IB_REQUEST: {\n\t\tcmd = duk_debug_read_int(thr);\n\t\tswitch (cmd) {\n\t\tcase DUK_DBG_CMD_BASICINFO: {\n\t\t\tduk__debug_handle_basic_info(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_TRIGGERSTATUS: {\n\t\t\tduk__debug_handle_trigger_status(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_PAUSE: {\n\t\t\tduk__debug_handle_pause(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_RESUME: {\n\t\t\tduk__debug_handle_resume(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_STEPINTO:\n\t\tcase DUK_DBG_CMD_STEPOVER:\n\t\tcase DUK_DBG_CMD_STEPOUT: {\n\t\t\tduk__debug_handle_step(thr, heap, cmd);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_LISTBREAK: {\n\t\t\tduk__debug_handle_list_break(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_ADDBREAK: {\n\t\t\tduk__debug_handle_add_break(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_DELBREAK: {\n\t\t\tduk__debug_handle_del_break(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETVAR: {\n\t\t\tduk__debug_handle_get_var(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_PUTVAR: {\n\t\t\tduk__debug_handle_put_var(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETCALLSTACK: {\n\t\t\tduk__debug_handle_get_call_stack(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETLOCALS: {\n\t\t\tduk__debug_handle_get_locals(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_EVAL: {\n\t\t\tduk__debug_handle_eval(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_DETACH: {\n\t\t\t/* The actual detached_cb call is postponed to message loop so\n\t\t\t * we don't need any special precautions here (just skip to EOM\n\t\t\t * on the already closed connection).\n\t\t\t */\n\t\t\tduk__debug_handle_detach(thr, heap);\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP)\n\t\tcase DUK_DBG_CMD_DUMPHEAP: {\n\t\t\tduk__debug_handle_dump_heap(thr, heap);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP */\n\t\tcase DUK_DBG_CMD_GETBYTECODE: {\n\t\t\tduk__debug_handle_get_bytecode(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_APPREQUEST: {\n\t\t\tduk__debug_handle_apprequest(thr, heap);\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_DEBUGGER_INSPECT)\n\t\tcase DUK_DBG_CMD_GETHEAPOBJINFO: {\n\t\t\tduk__debug_handle_get_heap_obj_info(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETOBJPROPDESC: {\n\t\t\tduk__debug_handle_get_obj_prop_desc(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETOBJPROPDESCRANGE: {\n\t\t\tduk__debug_handle_get_obj_prop_desc_range(thr, heap);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_DEBUGGER_INSPECT */\n\t\tdefault: {\n\t\t\tDUK_D(DUK_DPRINT(\"debug command unsupported: %d\", (int) cmd));\n\t\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNSUPPORTED, \"unsupported command\");\n\t\t}\n\t\t}  /* switch cmd */\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_REPLY: {\n\t\tDUK_D(DUK_DPRINT(\"debug reply, skipping\"));\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_ERROR: {\n\t\tDUK_D(DUK_DPRINT(\"debug error, skipping\"));\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_NOTIFY: {\n\t\tDUK_D(DUK_DPRINT(\"debug notify, skipping\"));\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tDUK_D(DUK_DPRINT(\"invalid initial byte, drop connection: %d\", (int) x));\n\t\tgoto fail;\n\t}\n\t}  /* switch initial byte */\n\n\tDUK_ASSERT(duk_get_top(thr) >= entry_top);\n\tduk_set_top(thr, entry_top);\n\tduk__debug_skip_to_eom(thr);\n\treturn;\n\n fail:\n\tDUK_ASSERT(duk_get_top(thr) >= entry_top);\n\tduk_set_top(thr, entry_top);\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn;\n}\n\nDUK_LOCAL void duk__check_resend_status(duk_hthread *thr) {\n\tif (thr->heap->dbg_read_cb != NULL && thr->heap->dbg_state_dirty) {\n\t\tduk_debug_send_status(thr);\n\t\tthr->heap->dbg_state_dirty = 0;\n\t}\n}\n\nDUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t no_block) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top;\n#endif\n\tduk_bool_t retval = 0;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\n\tDUK_D(DUK_DPRINT(\"process debug messages: read_cb=%s, no_block=%ld, detaching=%ld, processing=%ld\",\n\t                 thr->heap->dbg_read_cb ? \"not NULL\" : \"NULL\", (long) no_block,\n\t                 (long) thr->heap->dbg_detaching, (long) thr->heap->dbg_processing));\n\tDUK_DD(DUK_DDPRINT(\"top at entry: %ld\", (long) duk_get_top(thr)));\n\n\t/* thr->heap->dbg_detaching may be != 0 if a debugger write outside\n\t * the message loop caused a transport error and detach1() to run.\n\t */\n\tDUK_ASSERT(thr->heap->dbg_detaching == 0 || thr->heap->dbg_detaching == 1);\n\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\tthr->heap->dbg_processing = 1;\n\n\t/* Ensure dirty state causes a Status even if never process any\n\t * messages.  This is expected by the bytecode executor when in\n\t * the running state.\n\t */\n\tduk__check_resend_status(thr);\n\n\tfor (;;) {\n\t\t/* Process messages until we're no longer paused or we peek\n\t\t * and see there's nothing to read right now.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"top at loop top: %ld\", (long) duk_get_top(thr)));\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 1);\n\n\t\twhile (thr->heap->dbg_read_cb == NULL && thr->heap->dbg_detaching) {\n\t\t\t/* Detach is pending; can be triggered from outside the\n\t\t\t * debugger loop (e.g. Status notify write error) or by\n\t\t\t * previous message handling.  Call detached callback\n\t\t\t * here, in a controlled state, to ensure a possible\n\t\t\t * reattach inside the detached_cb is handled correctly.\n\t\t\t *\n\t\t\t * Recheck for detach in a while loop: an immediate\n\t\t\t * reattach involves a call to duk_debugger_attach()\n\t\t\t * which writes a debugger handshake line immediately\n\t\t\t * inside the API call.  If the transport write fails\n\t\t\t * for that handshake, we can immediately end up in a\n\t\t\t * \"transport broken, detaching\" case several times here.\n\t\t\t * Loop back until we're either cleanly attached or\n\t\t\t * fully detached.\n\t\t\t *\n\t\t\t * NOTE: Reset dbg_processing = 1 forcibly, in case we\n\t\t\t * re-attached; duk_debugger_attach() sets dbg_processing\n\t\t\t * to 0 at the moment.\n\t\t\t */\n\n\t\t\tDUK_D(DUK_DPRINT(\"detach pending (dbg_read_cb == NULL, dbg_detaching != 0), call detach2\"));\n\n\t\t\tduk__debug_do_detach2(thr->heap);\n\t\t\tthr->heap->dbg_processing = 1;  /* may be set to 0 by duk_debugger_attach() inside callback */\n\n\t\t\tDUK_D(DUK_DPRINT(\"after detach2 (and possible reattach): dbg_read_cb=%s, dbg_detaching=%ld\",\n\t\t\t                 thr->heap->dbg_read_cb ? \"not NULL\" : \"NULL\", (long) thr->heap->dbg_detaching));\n\t\t}\n\t\tDUK_ASSERT(thr->heap->dbg_detaching == 0);  /* true even with reattach */\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 1);  /* even after a detach and possible reattach */\n\n\t\tif (thr->heap->dbg_read_cb == NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"debug connection broken (and not detaching), stop processing messages\"));\n\t\t\tbreak;\n\t\t}\n\n\t\tif (!DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || no_block) {\n\t\t\tif (!duk_debug_read_peek(thr)) {\n\t\t\t\t/* Note: peek cannot currently trigger a detach\n\t\t\t\t * so the dbg_detaching == 0 assert outside the\n\t\t\t\t * loop is correct.\n\t\t\t\t */\n\t\t\t\tDUK_D(DUK_DPRINT(\"processing debug message, peek indicated no data, stop processing messages\"));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_D(DUK_DPRINT(\"processing debug message, peek indicated there is data, handle it\"));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"paused, process debug message, blocking if necessary\"));\n\t\t}\n\n\t\tduk__check_resend_status(thr);\n\t\tduk__debug_process_message(thr);\n\t\tduk__check_resend_status(thr);\n\n\t\tretval = 1;  /* processed one or more messages */\n\t}\n\n\tDUK_ASSERT(thr->heap->dbg_detaching == 0);\n\tDUK_ASSERT(thr->heap->dbg_processing == 1);\n\tthr->heap->dbg_processing = 0;\n\n\t/* As an initial implementation, read flush after exiting the message\n\t * loop.  If transport is broken, this is a no-op (with debug logs).\n\t */\n\tduk_debug_read_flush(thr);  /* this cannot initiate a detach */\n\tDUK_ASSERT(thr->heap->dbg_detaching == 0);\n\n\tDUK_DD(DUK_DDPRINT(\"top at exit: %ld\", (long) duk_get_top(thr)));\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Easy to get wrong, so assert for it. */\n\tDUK_ASSERT(entry_top == duk_get_top(thr));\n#endif\n\n\treturn retval;\n}\n\n/*\n *  Halt execution helper\n */\n\n/* Halt execution and enter a debugger message loop until execution is resumed\n * by the client.  PC for the current activation may be temporarily decremented\n * so that the \"current\" instruction will be shown by the client.  This helper\n * is callable from anywhere, also outside bytecode executor.\n */\n\nDUK_INTERNAL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev_pc) {\n\tduk_activation *act;\n\tduk_hcompfunc *fun;\n\tduk_instr_t *old_pc = NULL;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(duk_debug_is_attached(thr->heap));\n\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\tDUK_ASSERT(!duk_debug_is_paused(thr->heap));\n\n\tduk_debug_set_paused(thr->heap);\n\n\tact = thr->callstack_curr;\n\n\t/* NOTE: act may be NULL if an error is thrown outside of any activation,\n\t * which may happen in the case of, e.g. syntax errors.\n\t */\n\n\t/* Decrement PC if that was requested, this requires a PC sync. */\n\tif (act != NULL) {\n\t\tduk_hthread_sync_currpc(thr);\n\t\told_pc = act->curr_pc;\n\t\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\n\t\t/* Short circuit if is safe: if act->curr_pc != NULL, 'fun' is\n\t\t * guaranteed to be a non-NULL ECMAScript function.\n\t\t */\n\t\tDUK_ASSERT(act->curr_pc == NULL ||\n\t\t           (fun != NULL && DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun)));\n\t\tif (use_prev_pc &&\n\t\t    act->curr_pc != NULL &&\n\t\t    act->curr_pc > DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, fun)) {\n\t\t\tact->curr_pc--;\n\t\t}\n\t}\n\n\t/* Process debug messages until we are no longer paused. */\n\n\t/* NOTE: This is a bit fragile.  It's important to ensure that\n\t * duk_debug_process_messages() never throws an error or\n\t * act->curr_pc will never be reset.\n\t */\n\n\tthr->heap->dbg_state_dirty = 1;\n\twhile (DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap)) {\n\t\tDUK_ASSERT(duk_debug_is_attached(thr->heap));\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\t\tduk_debug_process_messages(thr, 0 /*no_block*/);\n\t}\n\n\t/* XXX: Decrementing and restoring act->curr_pc works now, but if the\n\t * debugger message loop gains the ability to adjust the current PC\n\t * (e.g. a forced jump) restoring the PC here will break.  Another\n\t * approach would be to use a state flag for the \"decrement 1 from\n\t * topmost activation's PC\" and take it into account whenever dealing\n\t * with PC values.\n\t */\n\tif (act != NULL) {\n\t\tact->curr_pc = old_pc;  /* restore PC */\n\t}\n}\n\n/*\n *  Breakpoint management\n */\n\nDUK_INTERNAL duk_small_int_t duk_debug_add_breakpoint(duk_hthread *thr, duk_hstring *filename, duk_uint32_t line) {\n\tduk_heap *heap;\n\tduk_breakpoint *b;\n\n\t/* Caller must trigger recomputation of active breakpoint list.  To\n\t * ensure stale values are not used if that doesn't happen, clear the\n\t * active breakpoint list here.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(filename != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_breakpoint_count >= DUK_HEAP_MAX_BREAKPOINTS) {\n\t\tDUK_D(DUK_DPRINT(\"failed to add breakpoint for %O:%ld, all breakpoint slots used\",\n\t\t                 (duk_heaphdr *) filename, (long) line));\n\t\treturn -1;\n\t}\n\theap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;\n\tb = heap->dbg_breakpoints + (heap->dbg_breakpoint_count++);\n\tb->filename = filename;\n\tb->line = line;\n\tDUK_HSTRING_INCREF(thr, filename);\n\n\treturn (duk_small_int_t) (heap->dbg_breakpoint_count - 1);  /* index */\n}\n\nDUK_INTERNAL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_small_uint_t breakpoint_index) {\n\tduk_heap *heap;\n\tduk_hstring *h;\n\tduk_breakpoint *b;\n\tduk_size_t move_size;\n\n\t/* Caller must trigger recomputation of active breakpoint list.  To\n\t * ensure stale values are not used if that doesn't happen, clear the\n\t * active breakpoint list here.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(duk_debug_is_attached(thr->heap));\n\tDUK_ASSERT_DISABLE(breakpoint_index >= 0);  /* unsigned */\n\n\tif (breakpoint_index >= heap->dbg_breakpoint_count) {\n\t\tDUK_D(DUK_DPRINT(\"invalid breakpoint index: %ld\", (long) breakpoint_index));\n\t\treturn 0;\n\t}\n\tb = heap->dbg_breakpoints + breakpoint_index;\n\n\th = b->filename;\n\tDUK_ASSERT(h != NULL);\n\n\tmove_size = sizeof(duk_breakpoint) * (heap->dbg_breakpoint_count - breakpoint_index - 1);\n\tduk_memmove((void *) b,\n\t            (const void *) (b + 1),\n\t            (size_t) move_size);\n\n\theap->dbg_breakpoint_count--;\n\theap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;\n\n\tDUK_HSTRING_DECREF(thr, h);  /* side effects */\n\tDUK_UNREF(h);  /* w/o refcounting */\n\n\t/* Breakpoint entries above the used area are left as garbage. */\n\n\treturn 1;\n}\n\n/*\n *  Misc state management\n */\n\nDUK_INTERNAL duk_bool_t duk_debug_is_attached(duk_heap *heap) {\n\treturn (heap->dbg_read_cb != NULL);\n}\n\nDUK_INTERNAL duk_bool_t duk_debug_is_paused(duk_heap *heap) {\n\treturn (DUK_HEAP_HAS_DEBUGGER_PAUSED(heap) != 0);\n}\n\nDUK_INTERNAL void duk_debug_set_paused(duk_heap *heap) {\n\tif (duk_debug_is_paused(heap)) {\n\t\tDUK_D(DUK_DPRINT(\"trying to set paused state when already paused, ignoring\"));\n\t} else {\n\t\tDUK_HEAP_SET_DEBUGGER_PAUSED(heap);\n\t\theap->dbg_state_dirty = 1;\n\t\tduk_debug_clear_pause_state(heap);\n\t\tDUK_ASSERT(heap->ms_running == 0);  /* debugger can't be triggered within mark-and-sweep */\n\t\theap->ms_running = 2;  /* prevent mark-and-sweep, prevent refzero queueing */\n\t\theap->ms_prevent_count++;\n\t\tDUK_ASSERT(heap->ms_prevent_count != 0);  /* Wrap. */\n\t\tDUK_ASSERT(heap->heap_thread != NULL);\n\t}\n}\n\nDUK_INTERNAL void duk_debug_clear_paused(duk_heap *heap) {\n\tif (duk_debug_is_paused(heap)) {\n\t\tDUK_HEAP_CLEAR_DEBUGGER_PAUSED(heap);\n\t\theap->dbg_state_dirty = 1;\n\t\tduk_debug_clear_pause_state(heap);\n\t\tDUK_ASSERT(heap->ms_running == 2);\n\t\tDUK_ASSERT(heap->ms_prevent_count > 0);\n\t\theap->ms_prevent_count--;\n\t\theap->ms_running = 0;\n\t\tDUK_ASSERT(heap->heap_thread != NULL);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"trying to clear paused state when not paused, ignoring\"));\n\t}\n}\n\nDUK_INTERNAL void duk_debug_clear_pause_state(duk_heap *heap) {\n\theap->dbg_pause_flags = 0;\n\theap->dbg_pause_act = NULL;\n\theap->dbg_pause_startline = 0;\n}\n\n#else  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/* No debugger support. */\n\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/* automatic undefs */\n#undef DUK__DBG_TPORT_ENTER\n#undef DUK__DBG_TPORT_EXIT\n#undef DUK__SET_CONN_BROKEN\n/*\n *  Augmenting errors at their creation site and their throw site.\n *\n *  When errors are created, traceback data is added by built-in code\n *  and a user error handler (if defined) can process or replace the\n *  error.  Similarly, when errors are thrown, a user error handler\n *  (if defined) can process or replace the error.\n *\n *  Augmentation and other processing at error creation time is nice\n *  because an error is only created once, but it may be thrown and\n *  rethrown multiple times.  User error handler registered for processing\n *  an error at its throw site must be careful to handle rethrowing in\n *  a useful manner.\n *\n *  Error augmentation may throw an internal error (e.g. alloc error).\n *\n *  ECMAScript allows throwing any values, so all values cannot be\n *  augmented.  Currently, the built-in augmentation at error creation\n *  only augments error values which are Error instances (= have the\n *  built-in Error.prototype in their prototype chain) and are also\n *  extensible.  User error handlers have no limitations in this respect.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Helper for calling a user error handler.\n *\n *  'thr' must be the currently active thread; the error handler is called\n *  in its context.  The valstack of 'thr' must have the error value on\n *  top, and will be replaced by another error value based on the return\n *  value of the error handler.\n *\n *  The helper calls duk_handle_call() recursively in protected mode.\n *  Before that call happens, no longjmps should happen; as a consequence,\n *  we must assume that the valstack contains enough temporary space for\n *  arguments and such.\n *\n *  While the error handler runs, any errors thrown will not trigger a\n *  recursive error handler call (this is implemented using a heap level\n *  flag which will \"follow\" through any coroutines resumed inside the\n *  error handler).  If the error handler is not callable or throws an\n *  error, the resulting error replaces the original error (for Duktape\n *  internal errors, duk_error_throw.c further substitutes this error with\n *  a DoubleError which is not ideal).  This would be easy to change and\n *  even signal to the caller.\n *\n *  The user error handler is stored in 'Duktape.errCreate' or\n *  'Duktape.errThrow' depending on whether we're augmenting the error at\n *  creation or throw time.  There are several alternatives to this approach,\n *  see doc/error-objects.rst for discussion.\n *\n *  Note: since further longjmp()s may occur while calling the error handler\n *  (for many reasons, e.g. a labeled 'break' inside the handler), the\n *  caller can make no assumptions on the thr->heap->lj state after the\n *  call (this affects especially duk_error_throw.c).  This is not an issue\n *  as long as the caller writes to the lj state only after the error handler\n *  finishes.\n */\n\n#if defined(DUK_USE_ERRTHROW) || defined(DUK_USE_ERRCREATE)\nDUK_LOCAL void duk__err_augment_user(duk_hthread *thr, duk_small_uint_t stridx_cb) {\n\tduk_tval *tv_hnd;\n\tduk_int_t rc;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT_STRIDX_VALID(stridx_cb);\n\n\tif (thr->heap->augmenting_error) {\n\t\tDUK_D(DUK_DPRINT(\"recursive call to error augmentation, ignore\"));\n\t\treturn;\n\t}\n\n\t/*\n\t *  Check whether or not we have an error handler.\n\t *\n\t *  We must be careful of not triggering an error when looking up the\n\t *  property.  For instance, if the property is a getter, we don't want\n\t *  to call it, only plain values are allowed.  The value, if it exists,\n\t *  is not checked.  If the value is not a function, a TypeError happens\n\t *  when it is called and that error replaces the original one.\n\t */\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, 4);  /* 3 entries actually needed below */\n\n\t/* [ ... errval ] */\n\n\tif (thr->builtins[DUK_BIDX_DUKTAPE] == NULL) {\n\t\t/* When creating built-ins, some of the built-ins may not be set\n\t\t * and we want to tolerate that when throwing errors.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"error occurred when DUK_BIDX_DUKTAPE is NULL, ignoring\"));\n\t\treturn;\n\t}\n\ttv_hnd = duk_hobject_find_entry_tval_ptr_stridx(thr->heap,\n\t                                                thr->builtins[DUK_BIDX_DUKTAPE],\n\t                                                stridx_cb);\n\tif (tv_hnd == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"error handler does not exist or is not a plain value: %!T\",\n\t\t                   (duk_tval *) tv_hnd));\n\t\treturn;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"error handler dump (callability not checked): %!T\",\n\t                     (duk_tval *) tv_hnd));\n\tduk_push_tval(thr, tv_hnd);\n\n\t/* [ ... errval errhandler ] */\n\n\tduk_insert(thr, -2);  /* -> [ ... errhandler errval ] */\n\tduk_push_undefined(thr);\n\tduk_insert(thr, -2);  /* -> [ ... errhandler undefined(= this) errval ] */\n\n\t/* [ ... errhandler undefined errval ] */\n\n\t/*\n\t *  heap->augmenting_error prevents recursive re-entry and also causes\n\t *  call handling to use a larger (but not unbounded) call stack limit\n\t *  for the duration of error augmentation.\n\t *\n\t *  We ignore errors now: a success return and an error value both\n\t *  replace the original error value.  (This would be easy to change.)\n\t */\n\n\tDUK_ASSERT(thr->heap->augmenting_error == 0);\n\tthr->heap->augmenting_error = 1;\n\n\trc = duk_pcall_method(thr, 1);\n\tDUK_UNREF(rc);  /* no need to check now: both success and error are OK */\n\n\tDUK_ASSERT(thr->heap->augmenting_error == 1);\n\tthr->heap->augmenting_error = 0;\n\n\t/* [ ... errval ] */\n}\n#endif  /* DUK_USE_ERRTHROW || DUK_USE_ERRCREATE */\n\n/*\n *  Add ._Tracedata to an error on the stack top.\n */\n\n#if defined(DUK_USE_TRACEBACKS)\nDUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {\n\tduk_activation *act;\n\tduk_int_t depth;\n\tduk_int_t arr_size;\n\tduk_tval *tv;\n\tduk_hstring *s;\n\tduk_uint32_t u32;\n\tduk_double_t d;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr_callstack != NULL);\n\n\t/* [ ... error ] */\n\n\t/*\n\t *  The traceback format is pretty arcane in an attempt to keep it compact\n\t *  and cheap to create.  It may change arbitrarily from version to version.\n\t *  It should be decoded/accessed through version specific accessors only.\n\t *\n\t *  See doc/error-objects.rst.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"adding traceback to object: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* Preallocate array to correct size, so that we can just write out\n\t * the _Tracedata values into the array part.\n\t */\n\tact = thr->callstack_curr;\n\tdepth = DUK_USE_TRACEBACK_DEPTH;\n\tDUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX);  /* callstack limits */\n\tif (depth > (duk_int_t) thr_callstack->callstack_top) {\n\t\tdepth = (duk_int_t) thr_callstack->callstack_top;\n\t}\n\tif (depth > 0) {\n\t\tif (flags & DUK_AUGMENT_FLAG_SKIP_ONE) {\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\tact = act->parent;\n\t\t\tdepth--;\n\t\t}\n\t}\n\tarr_size = depth * 2;\n\tif (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) {\n\t\tarr_size += 2;\n\t}\n\tif (c_filename) {\n\t\t/* We need the C filename to be interned before getting the\n\t\t * array part pointer to avoid any GC interference while the\n\t\t * array part is populated.\n\t\t */\n\t\tduk_push_string(thr, c_filename);\n\t\tarr_size += 2;\n\t}\n\n\t/* XXX: Uninitialized would be OK.  Maybe add internal primitive to\n\t * push bare duk_harray with size?\n\t */\n\tDUK_D(DUK_DPRINT(\"preallocated _Tracedata to %ld items\", (long) arr_size));\n\ttv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) arr_size);\n\tduk_clear_prototype(thr, -1);\n\tDUK_ASSERT(duk_is_bare_object(thr, -1));\n\tDUK_ASSERT(arr_size == 0 || tv != NULL);\n\n\t/* Compiler SyntaxErrors (and other errors) come first, and are\n\t * blamed by default (not flagged \"noblame\").\n\t */\n\tif (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) {\n\t\ts = thr->compile_ctx->h_filename;\n\t\tDUK_TVAL_SET_STRING(tv, s);\n\t\tDUK_HSTRING_INCREF(thr, s);\n\t\ttv++;\n\n\t\tu32 = (duk_uint32_t) thr->compile_ctx->curr_token.start_line;  /* (flags<<32) + (line), flags = 0 */\n\t\tDUK_TVAL_SET_U32(tv, u32);\n\t\ttv++;\n\t}\n\n\t/* Filename/line from C macros (__FILE__, __LINE__) are added as an\n\t * entry with a special format: (string, number).  The number contains\n\t * the line and flags.\n\t */\n\n\t/* [ ... error c_filename? arr ] */\n\n\tif (c_filename) {\n\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(thr->valstack_top - 2));\n\t\ts = DUK_TVAL_GET_STRING(thr->valstack_top - 2);  /* interned c_filename */\n\t\tDUK_ASSERT(s != NULL);\n\t\tDUK_TVAL_SET_STRING(tv, s);\n\t\tDUK_HSTRING_INCREF(thr, s);\n\t\ttv++;\n\n\t\td = ((flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE) ? ((duk_double_t) DUK_TB_FLAG_NOBLAME_FILELINE) * DUK_DOUBLE_2TO32 : 0.0) +\n\t\t    (duk_double_t) c_line;\n\t\tDUK_TVAL_SET_DOUBLE(tv, d);\n\t\ttv++;\n\t}\n\n\t/* Traceback depth doesn't take into account the filename/line\n\t * special handling above (intentional).\n\t */\n\tfor (; depth-- > 0; act = act->parent) {\n\t\tduk_uint32_t pc;\n\t\tduk_tval *tv_src;\n\n\t\t/* [... arr] */\n\n\t\tDUK_ASSERT(act != NULL);  /* depth check above, assumes book-keeping is correct */\n\t\tDUK_ASSERT_DISABLE(act->pc >= 0);  /* unsigned */\n\n\t\t/* Add function object. */\n\t\ttv_src = &act->tv_func;  /* object (function) or lightfunc */\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_src) || DUK_TVAL_IS_LIGHTFUNC(tv_src));\n\t\tDUK_TVAL_SET_TVAL(tv, tv_src);\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\ttv++;\n\n\t\t/* Add a number containing: pc, activation flags.\n\t\t *\n\t\t * PC points to next instruction, find offending PC.  Note that\n\t\t * PC == 0 for native code.\n\t\t */\n\t\tpc = (duk_uint32_t) duk_hthread_get_act_prev_pc(thr_callstack, act);\n\t\tDUK_ASSERT_DISABLE(pc >= 0);  /* unsigned */\n\t\tDUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32);  /* assume PC is at most 32 bits and non-negative */\n\t\td = ((duk_double_t) act->flags) * DUK_DOUBLE_2TO32 + (duk_double_t) pc;\n\t\tDUK_TVAL_SET_DOUBLE(tv, d);\n\t\ttv++;\n\t}\n\n#if defined(DUK_USE_ASSERTIONS)\n\t{\n\t\tduk_harray *a;\n\t\ta = (duk_harray *) duk_known_hobject(thr, -1);\n\t\tDUK_ASSERT(a != NULL);\n\t\tDUK_ASSERT((duk_uint32_t) (tv - DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a)) == a->length);\n\t\tDUK_ASSERT(a->length == (duk_uint32_t) arr_size);\n\t\tDUK_ASSERT(duk_is_bare_object(thr, -1));\n\t}\n#endif\n\n\t/* [ ... error c_filename? arr ] */\n\n\tif (c_filename) {\n\t\tduk_remove_m2(thr);\n\t}\n\n\t/* [ ... error arr ] */\n\n\tduk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INT_TRACEDATA);  /* -> [ ... error ] */\n}\n#endif  /* DUK_USE_TRACEBACKS */\n\n/*\n *  Add .fileName and .lineNumber to an error on the stack top.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE) && !defined(DUK_USE_TRACEBACKS)\nDUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_int_t entry_top;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\n\t/*\n\t *  If tracebacks are disabled, 'fileName' and 'lineNumber' are added\n\t *  as plain own properties.  Since Error.prototype has accessors of\n\t *  the same name, we need to define own properties directly (cannot\n\t *  just use e.g. duk_put_prop_stridx).  Existing properties are not\n\t *  overwritten in case they already exist.\n\t */\n\n\tif (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) {\n\t\t/* Compiler SyntaxError (or other error) gets the primary blame.\n\t\t * Currently no flag to prevent blaming.\n\t\t */\n\t\tduk_push_uint(thr, (duk_uint_t) thr->compile_ctx->curr_token.start_line);\n\t\tduk_push_hstring(thr, thr->compile_ctx->h_filename);\n\t} else if (c_filename && (flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE) == 0) {\n\t\t/* C call site gets blamed next, unless flagged not to do so.\n\t\t * XXX: file/line is disabled in minimal builds, so disable this\n\t\t * too when appropriate.\n\t\t */\n\t\tduk_push_int(thr, c_line);\n\t\tduk_push_string(thr, c_filename);\n\t} else {\n\t\t/* Finally, blame the innermost callstack entry which has a\n\t\t * .fileName property.\n\t\t */\n\t\tduk_small_uint_t depth;\n\t\tduk_uint32_t ecma_line;\n\t\tduk_activation *act;\n\n\t\tDUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX);  /* callstack limits */\n\t\tdepth = DUK_USE_TRACEBACK_DEPTH;\n\t\tif (depth > thr_callstack->callstack_top) {\n\t\t\tdepth = thr_callstack->callstack_top;\n\t\t}\n\t\tfor (act = thr_callstack->callstack_curr; depth-- > 0; act = act->parent) {\n\t\t\tduk_hobject *func;\n\t\t\tduk_uint32_t pc;\n\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\tfunc = DUK_ACT_GET_FUNC(act);\n\t\t\tif (func == NULL) {\n\t\t\t\t/* Lightfunc, not blamed now. */\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* PC points to next instruction, find offending PC,\n\t\t\t * PC == 0 for native code.\n\t\t\t */\n\t\t\tpc = duk_hthread_get_act_prev_pc(thr, act);  /* thr argument only used for thr->heap, so specific thread doesn't matter */\n\t\t\tDUK_UNREF(pc);\n\t\t\tDUK_ASSERT_DISABLE(pc >= 0);  /* unsigned */\n\t\t\tDUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32);  /* assume PC is at most 32 bits and non-negative */\n\n\t\t\tduk_push_hobject(thr, func);\n\n\t\t\t/* [ ... error func ] */\n\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME);\n\t\t\tif (!duk_is_string_notsymbol(thr, -1)) {\n\t\t\t\tduk_pop_2(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* [ ... error func fileName ] */\n\n\t\t\tecma_line = 0;\n#if defined(DUK_USE_PC2LINE)\n\t\t\tif (DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\t\t\tecma_line = duk_hobject_pc2line_query(thr, -2, (duk_uint_fast32_t) pc);\n\t\t\t} else {\n\t\t\t\t/* Native function, no relevant lineNumber. */\n\t\t\t}\n#endif  /* DUK_USE_PC2LINE */\n\t\t\tduk_push_u32(thr, ecma_line);\n\n\t\t\t/* [ ... error func fileName lineNumber ] */\n\n\t\t\tduk_replace(thr, -3);\n\n\t\t\t/* [ ... error lineNumber fileName ] */\n\t\t\tgoto define_props;\n\t\t}\n\n\t\t/* No activation matches, use undefined for both .fileName and\n\t\t * .lineNumber (matches what we do with a _Tracedata based\n\t\t * no-match lookup.\n\t\t */\n\t\tduk_push_undefined(thr);\n\t\tduk_push_undefined(thr);\n\t}\n\n define_props:\n\t/* [ ... error lineNumber fileName ] */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(duk_get_top(thr) == entry_top + 2);\n#endif\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LINE_NUMBER, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE);\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE && !DUK_USE_TRACEBACKS */\n\n/*\n *  Add line number to a compiler error.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_LOCAL void duk__add_compiler_error_line(duk_hthread *thr) {\n\n\t/* Append a \"(line NNN)\" to the \"message\" property of any error\n\t * thrown during compilation.  Usually compilation errors are\n\t * SyntaxErrors but they can also be out-of-memory errors and\n\t * the like.\n\t */\n\n\t/* [ ... error ] */\n\n\tDUK_ASSERT(duk_is_object(thr, -1));\n\n\tif (!(thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL)) {\n\t\treturn;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"compile error, before adding line info: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_MESSAGE)) {\n\t\tduk_push_sprintf(thr, \" (line %ld)\", (long) thr->compile_ctx->curr_token.start_line);\n\t\tduk_concat(thr, 2);\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE);\n\t} else {\n\t\tduk_pop(thr);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"compile error, after adding line info: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE */\n\n/*\n *  Augment an error being created using Duktape specific properties\n *  like _Tracedata or .fileName/.lineNumber.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_LOCAL void duk__err_augment_builtin_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_hobject *obj, duk_small_uint_t flags) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_int_t entry_top;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_UNREF(obj);  /* unreferenced w/o tracebacks */\n\n\tduk__add_compiler_error_line(thr);\n\n#if defined(DUK_USE_TRACEBACKS)\n\t/* If tracebacks are enabled, the '_Tracedata' property is the only\n\t * thing we need: 'fileName' and 'lineNumber' are virtual properties\n\t * which use '_Tracedata'.  (Check _Tracedata only as own property.)\n\t */\n\tif (duk_hobject_find_entry_tval_ptr_stridx(thr->heap, obj, DUK_STRIDX_INT_TRACEDATA) != NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"error value already has a '_Tracedata' property, not modifying it\"));\n\t} else {\n\t\tduk__add_traceback(thr, thr_callstack, c_filename, c_line, flags);\n\t}\n#else\n\t/* Without tracebacks the concrete .fileName and .lineNumber need\n\t * to be added directly.\n\t */\n\tduk__add_fileline(thr, thr_callstack, c_filename, c_line, flags);\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(duk_get_top(thr) == entry_top);\n#endif\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE */\n\n/*\n *  Augment an error at creation time with _Tracedata/fileName/lineNumber\n *  and allow a user error handler (if defined) to process/replace the error.\n *  The error to be augmented is at the stack top.\n *\n *  thr: thread containing the error value\n *  thr_callstack: thread which should be used for generating callstack etc.\n *  c_filename: C __FILE__ related to the error\n *  c_line: C __LINE__ related to the error\n *  flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE:\n *      if true, don't fileName/line as error source, otherwise use traceback\n *      (needed because user code filename/line are reported but internal ones\n *      are not)\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_INTERNAL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr_callstack != NULL);\n\n\t/* [ ... error ] */\n\n\t/*\n\t *  Criteria for augmenting:\n\t *\n\t *   - augmentation enabled in build (naturally)\n\t *   - error value internal prototype chain contains the built-in\n\t *     Error prototype object (i.e. 'val instanceof Error')\n\t *\n\t *  Additional criteria for built-in augmenting:\n\t *\n\t *   - error value is an extensible object\n\t */\n\n\tobj = duk_get_hobject(thr, -1);\n\tif (!obj) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"value is not an object, skip both built-in and user augment\"));\n\t\treturn;\n\t}\n\tif (!duk_hobject_prototype_chain_contains(thr, obj, thr->builtins[DUK_BIDX_ERROR_PROTOTYPE], 1 /*ignore_loop*/)) {\n\t\t/* If the value has a prototype loop, it's critical not to\n\t\t * throw here.  Instead, assume the value is not to be\n\t\t * augmented.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"value is not an error instance, skip both built-in and user augment\"));\n\t\treturn;\n\t}\n\tif (DUK_HOBJECT_HAS_EXTENSIBLE(obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"error meets criteria, built-in augment\"));\n\t\tduk__err_augment_builtin_create(thr, thr_callstack, c_filename, c_line, obj, flags);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"error does not meet criteria, no built-in augment\"));\n\t}\n\n\t/* [ ... error ] */\n\n#if defined(DUK_USE_ERRCREATE)\n\tduk__err_augment_user(thr, DUK_STRIDX_ERR_CREATE);\n#endif\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE */\n\n/*\n *  Augment an error at throw time; allow a user error handler (if defined)\n *  to process/replace the error.  The error to be augmented is at the\n *  stack top.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\nDUK_INTERNAL void duk_err_augment_error_throw(duk_hthread *thr) {\n#if defined(DUK_USE_ERRTHROW)\n\tduk__err_augment_user(thr, DUK_STRIDX_ERR_THROW);\n#endif  /* DUK_USE_ERRTHROW */\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_THROW */\n/*\n *  Do a longjmp call, calling the fatal error handler if no\n *  catchpoint exists.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_minimal(duk_hthread *thr));\nDUK_LOCAL void duk__uncaught_minimal(duk_hthread *thr) {\n\t(void) duk_fatal(thr, \"uncaught error\");\n\tDUK_WO_NORETURN(return;);\n}\n#endif\n\n#if 0\nDUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_readable(duk_hthread *thr));\nDUK_LOCAL void duk__uncaught_readable(duk_hthread *thr) {\n\tconst char *summary;\n\tchar buf[DUK_USE_FATAL_MAXLEN];\n\n\tsummary = duk_push_string_tval_readable(thr, &thr->heap->lj.value1);\n\tDUK_SNPRINTF(buf, sizeof(buf), \"uncaught: %s\", summary);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\t(void) duk_fatal(thr, (const char *) buf);\n\tDUK_WO_NORETURN(return;);\n}\n#endif\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_error_aware(duk_hthread *thr));\nDUK_LOCAL void duk__uncaught_error_aware(duk_hthread *thr) {\n\tconst char *summary;\n\tchar buf[DUK_USE_FATAL_MAXLEN];\n\n\tsummary = duk_push_string_tval_readable_error(thr, &thr->heap->lj.value1);\n\tDUK_ASSERT(summary != NULL);\n\tDUK_SNPRINTF(buf, sizeof(buf), \"uncaught: %s\", summary);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\t(void) duk_fatal(thr, (const char *) buf);\n\tDUK_WO_NORETURN(return;);\n}\n#endif\n\nDUK_INTERNAL void duk_err_longjmp(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"longjmp error: type=%d iserror=%d value1=%!T value2=%!T\",\n\t                   (int) thr->heap->lj.type, (int) thr->heap->lj.iserror,\n\t                   &thr->heap->lj.value1, &thr->heap->lj.value2));\n\n\t/* Prevent finalizer execution during error handling.  All error\n\t * handling sites will process pending finalizers once error handling\n\t * is complete and we're ready for the side effects.  Does not prevent\n\t * refzero freeing or mark-and-sweep during error handling.\n\t *\n\t * NOTE: when we come here some calling code may have used DECREF\n\t * NORZ macros without an explicit DUK_REFZERO_CHECK_xxx() call.\n\t * We don't want to do it here because it would just check for\n\t * pending finalizers and we prevent that explicitly.  Instead,\n\t * the error catcher will run the finalizers once error handling\n\t * is complete.\n\t */\n\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\n\tthr->heap->pf_prevent_count++;\n\tDUK_ASSERT(thr->heap->pf_prevent_count != 0);  /* Wrap. */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* XXX: set this immediately when longjmp state is set */\n\tDUK_ASSERT(thr->heap->error_not_allowed == 0);  /* Detect error within critical section. */\n\tthr->heap->error_not_allowed = 1;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"about to longjmp, pf_prevent_count=%ld\", (long) thr->heap->pf_prevent_count));\n\n\t/* If we don't have a jmpbuf_ptr, there is little we can do except\n\t * cause a fatal error.  The caller's expectation is that we never\n\t * return.\n\t */\n\tif (!thr->heap->lj.jmpbuf_ptr) {\n\t\tDUK_D(DUK_DPRINT(\"uncaught error: type=%d iserror=%d value1=%!T value2=%!T\",\n\t\t                 (int) thr->heap->lj.type, (int) thr->heap->lj.iserror,\n\t\t                 &thr->heap->lj.value1, &thr->heap->lj.value2));\n\n#if defined(DUK_USE_PREFER_SIZE)\n\t\tduk__uncaught_minimal(thr);\n#else\n\t\tduk__uncaught_error_aware(thr);\n#endif\n\t\tDUK_UNREACHABLE();\n\t}\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\tthrow duk_internal_exception();  /* dummy */\n#else\n\tDUK_LONGJMP(thr->heap->lj.jmpbuf_ptr->jb);\n#endif\n\n\tDUK_UNREACHABLE();\n}\n/*\n *  Error helpers\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Helper to walk the thread chain and see if there is an active error\n *  catcher.  Protected calls or finally blocks aren't considered catching.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_LOCAL duk_bool_t duk__have_active_catcher(duk_hthread *thr) {\n\t/* As noted above, a protected API call won't be counted as a\n\t * catcher.  This is usually convenient, e.g. in the case of a top-\n\t * level duk_pcall(), but may not always be desirable.  Perhaps add\n\t * an argument to treat them as catchers?\n\t */\n\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tfor (; thr != NULL; thr = thr->resumer) {\n\t\tfor (act = thr->callstack_curr; act != NULL; act = act->parent) {\n\t\t\tfor (cat = act->cat; cat != NULL; cat = cat->parent) {\n\t\t\t\tif (DUK_CAT_HAS_CATCH_ENABLED(cat)) {\n\t\t\t\t\treturn 1;  /* all we need to know */\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn 0;\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/*\n *  Get prototype object for an integer error code.\n */\n\nDUK_INTERNAL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_errcode_t code) {\n\tswitch (code) {\n\tcase DUK_ERR_EVAL_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_EVAL_ERROR_PROTOTYPE];\n\tcase DUK_ERR_RANGE_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_RANGE_ERROR_PROTOTYPE];\n\tcase DUK_ERR_REFERENCE_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_REFERENCE_ERROR_PROTOTYPE];\n\tcase DUK_ERR_SYNTAX_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_SYNTAX_ERROR_PROTOTYPE];\n\tcase DUK_ERR_TYPE_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_TYPE_ERROR_PROTOTYPE];\n\tcase DUK_ERR_URI_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_URI_ERROR_PROTOTYPE];\n\tcase DUK_ERR_ERROR:\n\tdefault:\n\t\treturn thr->builtins[DUK_BIDX_ERROR_PROTOTYPE];\n\t}\n}\n\n/*\n *  Helper for debugger throw notify and pause-on-uncaught integration.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL void duk_err_check_debugger_integration(duk_hthread *thr) {\n\tduk_bool_t uncaught;\n\tduk_tval *tv_obj;\n\n\t/* If something is thrown with the debugger attached and nobody will\n\t * catch it, execution is paused before the longjmp, turning over\n\t * control to the debug client.  This allows local state to be examined\n\t * before the stack is unwound.  Errors are not intercepted when debug\n\t * message loop is active (e.g. for Eval).\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\t/* XXX: Allow customizing the pause and notify behavior at runtime\n\t * using debugger runtime flags.  For now the behavior is fixed using\n\t * config options.\n\t */\n\n\tif (!duk_debug_is_attached(thr->heap) ||\n\t    thr->heap->dbg_processing ||\n\t    thr->heap->lj.type != DUK_LJ_TYPE_THROW ||\n\t    thr->heap->creating_error) {\n\t\tDUK_D(DUK_DPRINT(\"skip debugger error integration; not attached, debugger processing, not THROW, or error thrown while creating error\"));\n\t\treturn;\n\t}\n\n\t/* Don't intercept a DoubleError, we may have caused the initial double\n\t * fault and attempting to intercept it will cause us to be called\n\t * recursively and exhaust the C stack.  (This should no longer happen\n\t * for the initial throw because DoubleError path doesn't do a debugger\n\t * integration check, but it might happen for rethrows.)\n\t */\n\ttv_obj = &thr->heap->lj.value1;\n\tif (DUK_TVAL_IS_OBJECT(tv_obj) && DUK_TVAL_GET_OBJECT(tv_obj) == thr->builtins[DUK_BIDX_DOUBLE_ERROR]) {\n\t\tDUK_D(DUK_DPRINT(\"built-in DoubleError instance (re)thrown, not intercepting\"));\n\t\treturn;\n\t}\n\n\tuncaught = !duk__have_active_catcher(thr);\n\n\t/* Debugger code expects the value at stack top.  This also serves\n\t * as a backup: we need to store/restore the longjmp state because\n\t * when the debugger is paused Eval commands may be executed and\n\t * they can arbitrarily clobber the longjmp state.\n\t */\n\tduk_push_tval(thr, tv_obj);\n\n\t/* Store and reset longjmp state. */\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\tDUK_TVAL_DECREF_NORZ(thr, tv_obj);\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value2));  /* Always for THROW type. */\n\tDUK_TVAL_SET_UNDEFINED(tv_obj);\n\tthr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)\n\t/* Report it to the debug client */\n\tDUK_D(DUK_DPRINT(\"throw with debugger attached, report to client\"));\n\tduk_debug_send_throw(thr, uncaught);\n#endif\n\n\tif (uncaught) {\n\t\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_UNCAUGHT_ERROR) {\n\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by uncaught error\"));\n\t\t\tduk_debug_halt_execution(thr, 1 /*use_prev_pc*/);\n\t\t}\n\t} else {\n\t\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_CAUGHT_ERROR) {\n\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by caught error\"));\n\t\t\tduk_debug_halt_execution(thr, 1 /*use_prev_pc*/);\n\t\t}\n\t}\n\n\t/* Restore longjmp state. */\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\tthr->heap->lj.type = DUK_LJ_TYPE_THROW;\n\ttv_obj = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value1));\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value2));\n\tDUK_TVAL_SET_TVAL(&thr->heap->lj.value1, tv_obj);\n\tDUK_TVAL_INCREF(thr, tv_obj);\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\n\tduk_pop(thr);\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/*\n *  Helpers for setting up heap longjmp state.\n */\n\nDUK_INTERNAL void duk_err_setup_ljstate1(duk_hthread *thr, duk_small_uint_t lj_type, duk_tval *tv_val) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(tv_val != NULL);\n\n\tDUK_ASSERT_LJSTATE_UNSET(heap);\n\n\theap->lj.type = lj_type;\n\tDUK_TVAL_SET_TVAL(&heap->lj.value1, tv_val);\n\tDUK_TVAL_INCREF(thr, tv_val);\n\n\tDUK_ASSERT_LJSTATE_SET(heap);\n}\n/*\n *  Create and throw an ECMAScript error object based on a code and a message.\n *\n *  Used when we throw errors internally.  ECMAScript generated error objects\n *  are created by ECMAScript code, and the throwing is handled by the bytecode\n *  executor.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Create and throw an error (originating from Duktape internally)\n *\n *  Push an error object on top of the stack, possibly throw augmenting\n *  the error, and finally longjmp.\n *\n *  If an error occurs while we're dealing with the current error, we might\n *  enter an infinite recursion loop.  This is prevented by detecting a\n *  \"double fault\" through the heap->creating_error flag; the recursion\n *  then stops at the second level.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code, const char *msg, const char *filename, duk_int_t line) {\n#else\nDUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code) {\n#endif\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\tDUK_DD(DUK_DDPRINT(\"duk_err_create_and_throw(): code=%ld, msg=%s, filename=%s, line=%ld\",\n\t                   (long) code, (const char *) msg,\n\t                   (const char *) filename, (long) line));\n#else\n\tDUK_DD(DUK_DDPRINT(\"duk_err_create_and_throw(): code=%ld\", (long) code));\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Even though nested call is possible because we throw an error when\n\t * trying to create an error, the potential errors must happen before\n\t * the longjmp state is configured.\n\t */\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\t/* Sync so that augmentation sees up-to-date activations, NULL\n\t * thr->ptr_curr_pc so that it's not used if side effects occur\n\t * in augmentation or longjmp handling.\n\t */\n\tduk_hthread_sync_and_null_currpc(thr);\n\n\t/*\n\t *  Create and push an error object onto the top of stack.\n\t *  The error is potentially augmented before throwing.\n\t *\n\t *  If a \"double error\" occurs, use a fixed error instance\n\t *  to avoid further trouble.\n\t */\n\n\tif (thr->heap->creating_error) {\n\t\tduk_tval tv_val;\n\t\tduk_hobject *h_err;\n\n\t\tthr->heap->creating_error = 0;\n\n\t\th_err = thr->builtins[DUK_BIDX_DOUBLE_ERROR];\n\t\tif (h_err != NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"double fault detected -> use built-in fixed 'double error' instance\"));\n\t\t\tDUK_TVAL_SET_OBJECT(&tv_val, h_err);\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"double fault detected; there is no built-in fixed 'double error' instance \"\n\t\t\t                 \"-> use the error code as a number\"));\n\t\t\tDUK_TVAL_SET_I32(&tv_val, (duk_int32_t) code);\n\t\t}\n\n\t\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, &tv_val);\n\n\t\t/* No augmentation to avoid any allocations or side effects. */\n\t} else {\n\t\t/* Prevent infinite recursion.  Extra call stack and C\n\t\t * recursion headroom (see GH-191) is added for augmentation.\n\t\t * That is now signalled by heap->augmenting error and taken\n\t\t * into account in call handling without an explicit limit bump.\n\t\t */\n\t\tthr->heap->creating_error = 1;\n\n\t\tduk_require_stack(thr, 1);\n\n\t\t/* XXX: usually unnecessary '%s' formatting here, but cannot\n\t\t * use 'msg' as a format string directly.\n\t\t */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\tduk_push_error_object_raw(thr,\n\t\t                          code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t\t                          filename,\n\t\t                          line,\n\t\t                          \"%s\",\n\t\t                          (const char *) msg);\n#else\n\t\tduk_push_error_object_raw(thr,\n\t\t                          code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t\t                          NULL,\n\t\t                          0,\n\t\t                          NULL);\n#endif\n\n\t\t/* Note that an alloc error may happen during error augmentation.\n\t\t * This may happen both when the original error is an alloc error\n\t\t * and when it's something else.  Because any error in augmentation\n\t\t * must be handled correctly anyway, there's no special check for\n\t\t * avoiding it for alloc errors (this differs from Duktape 1.x).\n\t\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\t\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (INTERNAL): %!iT (before throw augment)\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\tduk_err_augment_error_throw(thr);\n#endif\n\n\t\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, DUK_GET_TVAL_NEGIDX(thr, -1));\n\t\tthr->heap->creating_error = 0;\n\n\t\t/* Error is now created and we assume no errors can occur any\n\t\t * more.  Check for debugger Throw integration only when the\n\t\t * error is complete.  If we enter debugger message loop,\n\t\t * creating_error must be 0 so that errors can be thrown in\n\t\t * the paused state, e.g. in Eval commands.\n\t\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tduk_err_check_debugger_integration(thr);\n#endif\n\t}\n\n\t/*\n\t *  Finally, longjmp\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (INTERNAL): %!iT, %!iT (after throw augment)\",\n\t                     (duk_tval *) &thr->heap->lj.value1, (duk_tval *) &thr->heap->lj.value2));\n\n\tduk_err_longjmp(thr);\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  Helper for C function call negative return values.\n */\n\nDUK_INTERNAL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t rc) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(rc < 0);\n\n\t/*\n\t *  The __FILE__ and __LINE__ information is intentionally not used in the\n\t *  creation of the error object, as it isn't useful in the tracedata.  The\n\t *  tracedata still contains the function which returned the negative return\n\t *  code, and having the file/line of this function isn't very useful.\n\t *\n\t *  The error messages for DUK_RET_xxx shorthand are intentionally very\n\t *  minimal: they're only really useful for low memory targets.\n\t */\n\n\tduk_error_raw(thr, -rc, NULL, 0, \"error (rc %ld)\", (long) rc);\n\tDUK_WO_NORETURN(return;);\n}\n/*\n *  duk_hbuffer allocation and freeing.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Allocate a new duk_hbuffer of a certain type and return a pointer to it\n * (NULL on error).  Write buffer data pointer to 'out_bufdata' (only if\n * allocation successful).\n */\nDUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk_small_uint_t flags, void **out_bufdata) {\n\tduk_hbuffer *res = NULL;\n\tduk_size_t header_size;\n\tduk_size_t alloc_size;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(out_bufdata != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"allocate hbuffer\"));\n\n\t/* Size sanity check.  Should not be necessary because caller is\n\t * required to check this, but we don't want to cause a segfault\n\t * if the size wraps either in duk_size_t computation or when\n\t * storing the size in a 16-bit field.\n\t */\n\tif (size > DUK_HBUFFER_MAX_BYTELEN) {\n\t\tDUK_D(DUK_DPRINT(\"hbuffer alloc failed: size too large: %ld\", (long) size));\n\t\treturn NULL;  /* no need to write 'out_bufdata' */\n\t}\n\n\tif (flags & DUK_BUF_FLAG_EXTERNAL) {\n\t\theader_size = sizeof(duk_hbuffer_external);\n\t\talloc_size = sizeof(duk_hbuffer_external);\n\t} else if (flags & DUK_BUF_FLAG_DYNAMIC) {\n\t\theader_size = sizeof(duk_hbuffer_dynamic);\n\t\talloc_size = sizeof(duk_hbuffer_dynamic);\n\t} else {\n\t\theader_size = sizeof(duk_hbuffer_fixed);\n\t\talloc_size = sizeof(duk_hbuffer_fixed) + size;\n\t\tDUK_ASSERT(alloc_size >= sizeof(duk_hbuffer_fixed));  /* no wrapping */\n\t}\n\n\tres = (duk_hbuffer *) DUK_ALLOC(heap, alloc_size);\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\tgoto alloc_error;\n\t}\n\n\t/* zero everything unless requested not to do so */\n#if defined(DUK_USE_ZERO_BUFFER_DATA)\n\tduk_memzero((void *) res,\n\t            (flags & DUK_BUF_FLAG_NOZERO) ? header_size : alloc_size);\n#else\n\tduk_memzero((void *) res, header_size);\n#endif\n\n\tif (flags & DUK_BUF_FLAG_EXTERNAL) {\n\t\tduk_hbuffer_external *h;\n\t\th = (duk_hbuffer_external *) res;\n\t\tDUK_UNREF(h);\n\t\t*out_bufdata = NULL;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_HEAPPTR16)\n/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */\n#else\n\t\tDUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap, h, NULL);\n#endif\n#endif\n\t\tDUK_ASSERT(DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap, h) == NULL);\n\t} else if (flags & DUK_BUF_FLAG_DYNAMIC) {\n\t\tduk_hbuffer_dynamic *h = (duk_hbuffer_dynamic *) res;\n\t\tvoid *ptr;\n\n\t\tif (size > 0) {\n\t\t\tDUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL));  /* alloc external with size zero */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"dynamic buffer with nonzero size, alloc actual buffer\"));\n#if defined(DUK_USE_ZERO_BUFFER_DATA)\n\t\t\tptr = DUK_ALLOC_ZEROED(heap, size);\n#else\n\t\t\tptr = DUK_ALLOC(heap, size);\n#endif\n\t\t\tif (DUK_UNLIKELY(ptr == NULL)) {\n\t\t\t\t/* Because size > 0, NULL check is correct */\n\t\t\t\tgoto alloc_error;\n\t\t\t}\n\t\t\t*out_bufdata = ptr;\n\n\t\t\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, ptr);\n\t\t} else {\n\t\t\t*out_bufdata = NULL;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_HEAPPTR16)\n/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */\n#else\n\t\t\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, NULL);\n#endif\n#endif\n\t\t\tDUK_ASSERT(DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, h) == NULL);\n\t\t}\n\t} else {\n\t\t*out_bufdata = (void *) ((duk_hbuffer_fixed *) (void *) res + 1);\n\t}\n\n\tDUK_HBUFFER_SET_SIZE(res, size);\n\n\tDUK_HEAPHDR_SET_TYPE(&res->hdr, DUK_HTYPE_BUFFER);\n\tif (flags & DUK_BUF_FLAG_DYNAMIC) {\n\t\tDUK_HBUFFER_SET_DYNAMIC(res);\n\t\tif (flags & DUK_BUF_FLAG_EXTERNAL) {\n\t\t\tDUK_HBUFFER_SET_EXTERNAL(res);\n\t\t}\n\t} else {\n\t\tDUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL));\n\t}\n        DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &res->hdr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"allocated hbuffer: %p\", (void *) res));\n\treturn res;\n\n alloc_error:\n\tDUK_DD(DUK_DDPRINT(\"hbuffer allocation failed\"));\n\n\tDUK_FREE(heap, res);\n\treturn NULL;  /* no need to write 'out_bufdata' */\n}\n\n/* For indirect allocs. */\n\nDUK_INTERNAL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud) {\n\tduk_hbuffer_dynamic *buf = (duk_hbuffer_dynamic *) ud;\n\tDUK_UNREF(heap);\n\treturn (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, buf);\n}\n/*\n *  duk_hbuffer assertion helpers\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ASSERTIONS)\n\nDUK_INTERNAL void duk_hbuffer_assert_valid(duk_hbuffer *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n/*\n *  duk_hbuffer operations such as resizing and inserting/appending data to\n *  a dynamic buffer.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Resizing\n */\n\nDUK_INTERNAL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf, duk_size_t new_size) {\n\tvoid *res;\n\tduk_size_t prev_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf));\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf));\n\n\t/*\n\t *  Maximum size check\n\t */\n\n\tif (new_size > DUK_HBUFFER_MAX_BYTELEN) {\n\t\tDUK_ERROR_RANGE(thr, \"buffer too long\");\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/*\n\t *  Note: use indirect realloc variant just in case mark-and-sweep\n\t *  (finalizers) might resize this same buffer during garbage\n\t *  collection.\n\t */\n\n\tres = DUK_REALLOC_INDIRECT(thr->heap, duk_hbuffer_get_dynalloc_ptr, (void *) buf, new_size);\n\tif (DUK_LIKELY(res != NULL || new_size == 0)) {\n\t\t/* 'res' may be NULL if new allocation size is 0. */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"resized dynamic buffer %p:%ld -> %p:%ld\",\n\t\t                     (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, buf),\n\t\t                     (long) DUK_HBUFFER_DYNAMIC_GET_SIZE(buf),\n\t\t                     (void *) res,\n\t\t                     (long) new_size));\n\n\t\t/*\n\t\t *  The entire allocated buffer area, regardless of actual used\n\t\t *  size, is kept zeroed in resizes for simplicity.  If the buffer\n\t\t *  is grown, zero the new part.\n\t\t */\n\n\t\tprev_size = DUK_HBUFFER_DYNAMIC_GET_SIZE(buf);\n\t\tif (new_size > prev_size) {\n\t\t\tDUK_ASSERT(new_size - prev_size > 0);\n#if defined(DUK_USE_ZERO_BUFFER_DATA)\n\t\t\tduk_memzero((void *) ((char *) res + prev_size),\n\t\t\t            (duk_size_t) (new_size - prev_size));\n#endif\n\t\t}\n\n\t\tDUK_HBUFFER_DYNAMIC_SET_SIZE(buf, new_size);\n\t\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR(thr->heap, buf, res);\n\t} else {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_ASSERT(res != NULL || new_size == 0);\n}\n\nDUK_INTERNAL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *buf) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf));\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf));\n\n\tduk_hbuffer_resize(thr, buf, 0);\n}\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_uint_t duk_hbufobj_clamp_bytelength(duk_hbufobj *h_bufobj, duk_uint_t len) {\n\tduk_uint_t buf_size;\n\tduk_uint_t buf_avail;\n\n\tDUK_ASSERT(h_bufobj != NULL);\n\tDUK_ASSERT(h_bufobj->buf != NULL);\n\n\tbuf_size = (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_bufobj->buf);\n\tif (h_bufobj->offset > buf_size) {\n\t\t/* Slice starting point is beyond current length. */\n\t\treturn 0;\n\t}\n\tbuf_avail = buf_size - h_bufobj->offset;\n\n\treturn buf_avail >= len ? len : buf_avail;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n/*\n *  duk_heap allocation and freeing.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ROM_STRINGS)\n/* Fixed seed value used with ROM strings. */\n#define DUK__FIXED_HASH_SEED       0xabcd1234\n#endif\n\n/*\n *  Free a heap object.\n *\n *  Free heap object and its internal (non-heap) pointers.  Assumes that\n *  caller has removed the object from heap allocated list or the string\n *  intern table, and any weak references (which strings may have) have\n *  been already dealt with.\n */\n\nDUK_INTERNAL void duk_free_hobject(duk_heap *heap, duk_hobject *h) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_FREE(heap, DUK_HOBJECT_GET_PROPS(heap, h));\n\n\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tDUK_UNREF(f);\n\t\t/* Currently nothing to free; 'data' is a heap object */\n\t} else if (DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\tduk_hnatfunc *f = (duk_hnatfunc *) h;\n\t\tDUK_UNREF(f);\n\t\t/* Currently nothing to free */\n\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tduk_activation *act;\n\n\t\tDUK_FREE(heap, t->valstack);\n\n\t\t/* Don't free h->resumer because it exists in the heap.\n\t\t * Callstack entries also contain function pointers which\n\t\t * are not freed for the same reason.  They are decref\n\t\t * finalized and the targets are freed if necessary based\n\t\t * on their refcount (or reachability).\n\t\t */\n\t\tfor (act = t->callstack_curr; act != NULL;) {\n\t\t\tduk_activation *act_next;\n\t\t\tduk_catcher *cat;\n\n\t\t\tfor (cat = act->cat; cat != NULL;) {\n\t\t\t\tduk_catcher *cat_next;\n\n\t\t\t\tcat_next = cat->parent;\n\t\t\t\tDUK_FREE(heap, (void *) cat);\n\t\t\t\tcat = cat_next;\n\t\t\t}\n\n\t\t\tact_next = act->parent;\n\t\t\tDUK_FREE(heap, (void *) act);\n\t\t\tact = act_next;\n\t\t}\n\n\t\t/* XXX: with 'caller' property the callstack would need\n\t\t * to be unwound to update the 'caller' properties of\n\t\t * functions in the callstack.\n\t\t */\n\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {\n\t\tduk_hboundfunc *f = (duk_hboundfunc *) (void *) h;\n\n\t\tDUK_FREE(heap, f->args);\n\t}\n\n\tDUK_FREE(heap, (void *) h);\n}\n\nDUK_INTERNAL void duk_free_hbuffer(duk_heap *heap, duk_hbuffer *h) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n\tif (DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h)) {\n\t\tduk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h;\n\t\tDUK_DDD(DUK_DDDPRINT(\"free dynamic buffer %p\", (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, g)));\n\t\tDUK_FREE(heap, DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, g));\n\t}\n\tDUK_FREE(heap, (void *) h);\n}\n\nDUK_INTERNAL void duk_free_hstring(duk_heap *heap, duk_hstring *h) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_UNREF(heap);\n\tDUK_UNREF(h);\n\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_FREE)\n\tif (DUK_HSTRING_HAS_EXTDATA(h)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"free extstr: hstring %!O, extdata: %p\",\n\t\t                     h, DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) h)));\n\t\tDUK_USE_EXTSTR_FREE(heap->heap_udata, (const void *) DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) h));\n\t}\n#endif\n\tDUK_FREE(heap, (void *) h);\n}\n\nDUK_INTERNAL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr) {\n\tDUK_ASSERT(heap);\n\tDUK_ASSERT(hdr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"free heaphdr %p, htype %ld\", (void *) hdr, (long) DUK_HEAPHDR_GET_TYPE(hdr)));\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(hdr)) {\n\tcase DUK_HTYPE_STRING:\n\t\tduk_free_hstring(heap, (duk_hstring *) hdr);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tduk_free_hobject(heap, (duk_hobject *) hdr);\n\t\tbreak;\n\tdefault:\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) == DUK_HTYPE_BUFFER);\n\t\tduk_free_hbuffer(heap, (duk_hbuffer *) hdr);\n\t}\n\n}\n\n/*\n *  Free the heap.\n *\n *  Frees heap-related non-heap-tracked allocations such as the\n *  string intern table; then frees the heap allocated objects;\n *  and finally frees the heap structure itself.  Reference counts\n *  and GC markers are ignored (and not updated) in this process,\n *  and finalizers won't be called.\n *\n *  The heap pointer and heap object pointers must not be used\n *  after this call.\n */\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\nDUK_LOCAL duk_size_t duk__heap_free_activation_freelist(duk_heap *heap) {\n\tduk_activation *act;\n\tduk_activation *act_next;\n\tduk_size_t count_act = 0;\n\n\tfor (act = heap->activation_free; act != NULL;) {\n\t\tact_next = act->parent;\n\t\tDUK_FREE(heap, (void *) act);\n\t\tact = act_next;\n#if defined(DUK_USE_DEBUG)\n\t\tcount_act++;\n#endif\n\t}\n\theap->activation_free = NULL;  /* needed when called from mark-and-sweep */\n\treturn count_act;\n}\n#endif  /* DUK_USE_CACHE_ACTIVATION */\n\n#if defined(DUK_USE_CACHE_CATCHER)\nDUK_LOCAL duk_size_t duk__heap_free_catcher_freelist(duk_heap *heap) {\n\tduk_catcher *cat;\n\tduk_catcher *cat_next;\n\tduk_size_t count_cat = 0;\n\n\tfor (cat = heap->catcher_free; cat != NULL;) {\n\t\tcat_next = cat->parent;\n\t\tDUK_FREE(heap, (void *) cat);\n\t\tcat = cat_next;\n#if defined(DUK_USE_DEBUG)\n\t\tcount_cat++;\n#endif\n\t}\n\theap->catcher_free = NULL;  /* needed when called from mark-and-sweep */\n\n\treturn count_cat;\n}\n#endif  /* DUK_USE_CACHE_CATCHER */\n\nDUK_INTERNAL void duk_heap_free_freelists(duk_heap *heap) {\n\tduk_size_t count_act = 0;\n\tduk_size_t count_cat = 0;\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\tcount_act = duk__heap_free_activation_freelist(heap);\n#endif\n#if defined(DUK_USE_CACHE_CATCHER)\n\tcount_cat = duk__heap_free_catcher_freelist(heap);\n#endif\n\tDUK_UNREF(heap);\n\tDUK_UNREF(count_act);\n\tDUK_UNREF(count_cat);\n\n\tDUK_D(DUK_DPRINT(\"freed %ld activation freelist entries, %ld catcher freelist entries\",\n\t                 (long) count_act, (long) count_cat));\n}\n\nDUK_LOCAL void duk__free_allocated(duk_heap *heap) {\n\tduk_heaphdr *curr;\n\tduk_heaphdr *next;\n\n\tcurr = heap->heap_allocated;\n\twhile (curr) {\n\t\t/* We don't log or warn about freeing zero refcount objects\n\t\t * because they may happen with finalizer processing.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"FINALFREE (allocated): %!iO\",\n\t\t                     (duk_heaphdr *) curr));\n\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\tduk_heap_free_heaphdr_raw(heap, curr);\n\t\tcurr = next;\n\t}\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__free_finalize_list(duk_heap *heap) {\n\tduk_heaphdr *curr;\n\tduk_heaphdr *next;\n\n\tcurr = heap->finalize_list;\n\twhile (curr) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"FINALFREE (finalize_list): %!iO\",\n\t\t                     (duk_heaphdr *) curr));\n\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\tduk_heap_free_heaphdr_raw(heap, curr);\n\t\tcurr = next;\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_LOCAL void duk__free_stringtable(duk_heap *heap) {\n\t/* strings are only tracked by stringtable */\n\tduk_heap_strtable_free(heap);\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__free_run_finalizers(duk_heap *heap) {\n\tduk_heaphdr *curr;\n\tduk_uint_t round_no;\n\tduk_size_t count_all;\n\tduk_size_t count_finalized;\n\tduk_size_t curr_limit;\n\n\tDUK_ASSERT(heap != NULL);\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* refzero not running -> must be empty */\n#endif\n\tDUK_ASSERT(heap->finalize_list == NULL);  /* mark-and-sweep last pass */\n\n\tif (heap->heap_thread == NULL) {\n\t\t/* May happen when heap allocation fails right off.  There\n\t\t * cannot be any finalizable objects in this case.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"no heap_thread in heap destruct, assume no finalizable objects\"));\n\t\treturn;\n\t}\n\n\t/* Prevent finalize_list processing and mark-and-sweep entirely.\n\t * Setting ms_running != 0 also prevents refzero handling from moving\n\t * objects away from the heap_allocated list.  The flag name is a bit\n\t * misleading here.\n\t *\n\t * Use a distinct value for ms_running here (== 2) so that assertions\n\t * can detect this situation separate from the normal runtime\n\t * mark-and-sweep case.  This allows better assertions (GH-2030).\n\t */\n\tDUK_ASSERT(heap->pf_prevent_count == 0);\n\tDUK_ASSERT(heap->ms_running == 0);\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\theap->pf_prevent_count = 1;\n\theap->ms_running = 2;  /* Use distinguishable value. */\n\theap->ms_prevent_count = 1;  /* Bump, because mark-and-sweep assumes it's bumped when ms_running is set. */\n\n\tcurr_limit = 0;  /* suppress warning, not used */\n\tfor (round_no = 0; ; round_no++) {\n\t\tcurr = heap->heap_allocated;\n\t\tcount_all = 0;\n\t\tcount_finalized = 0;\n\t\twhile (curr) {\n\t\t\tcount_all++;\n\t\t\tif (DUK_HEAPHDR_IS_OBJECT(curr)) {\n\t\t\t\t/* Only objects in heap_allocated may have finalizers.  Check that\n\t\t\t\t * the object itself has a _Finalizer property (own or inherited)\n\t\t\t\t * so that we don't execute finalizers for e.g. Proxy objects.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(curr != NULL);\n\n\t\t\t\tif (DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) curr)) {\n\t\t\t\t\tif (!DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) curr)) {\n\t\t\t\t\t\tDUK_ASSERT(DUK_HEAP_HAS_FINALIZER_NORESCUE(heap));  /* maps to finalizer 2nd argument */\n\t\t\t\t\t\tduk_heap_run_finalizer(heap, (duk_hobject *) curr);\n\t\t\t\t\t\tcount_finalized++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurr = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\t}\n\n\t\t/* Each round of finalizer execution may spawn new finalizable objects\n\t\t * which is normal behavior for some applications.  Allow multiple\n\t\t * rounds of finalization, but use a shrinking limit based on the\n\t\t * first round to detect the case where a runaway finalizer creates\n\t\t * an unbounded amount of new finalizable objects.  Finalizer rescue\n\t\t * is not supported: the semantics are unclear because most of the\n\t\t * objects being finalized here are already reachable.  The finalizer\n\t\t * is given a boolean to indicate that rescue is not possible.\n\t\t *\n\t\t * See discussion in: https://github.com/svaarala/duktape/pull/473\n\t\t */\n\n\t\tif (round_no == 0) {\n\t\t\t/* Cannot wrap: each object is at least 8 bytes so count is\n\t\t\t * at most 1/8 of that.\n\t\t\t */\n\t\t\tcurr_limit = count_all * 2;\n\t\t} else {\n\t\t\tcurr_limit = (curr_limit * 3) / 4;   /* Decrease by 25% every round */\n\t\t}\n\t\tDUK_D(DUK_DPRINT(\"finalizer round %ld complete, %ld objects, tried to execute %ld finalizers, current limit is %ld\",\n\t\t                 (long) round_no, (long) count_all, (long) count_finalized, (long) curr_limit));\n\n\t\tif (count_finalized == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"no more finalizable objects, forced finalization finished\"));\n\t\t\tbreak;\n\t\t}\n\t\tif (count_finalized >= curr_limit) {\n\t\t\tDUK_D(DUK_DPRINT(\"finalizer count above limit, potentially runaway finalizer; skip remaining finalizers\"));\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tDUK_ASSERT(heap->ms_running == 2);\n\tDUK_ASSERT(heap->pf_prevent_count == 1);\n\theap->ms_running = 0;\n\theap->pf_prevent_count = 0;\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_INTERNAL void duk_heap_free(duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"free heap: %p\", (void *) heap));\n\n#if defined(DUK_USE_DEBUG)\n\tduk_heap_strtable_dump(heap);\n#endif\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* Detach a debugger if attached (can be called multiple times)\n\t * safely.\n\t */\n\t/* XXX: Add a flag to reject an attempt to re-attach?  Otherwise\n\t * the detached callback may immediately reattach.\n\t */\n\tduk_debug_do_detach(heap);\n#endif\n\n\t/* Execute finalizers before freeing the heap, even for reachable\n\t * objects.  This gives finalizers the chance to free any native\n\t * resources like file handles, allocations made outside Duktape,\n\t * etc.  This is quite tricky to get right, so that all finalizer\n\t * guarantees are honored.\n\t *\n\t * Run mark-and-sweep a few times just in case (unreachable object\n\t * finalizers run already here).  The last round must rescue objects\n\t * from the previous round without running any more finalizers.  This\n\t * ensures rescued objects get their FINALIZED flag cleared so that\n\t * their finalizer is called once more in forced finalization to\n\t * satisfy finalizer guarantees.  However, we don't want to run any\n\t * more finalizers because that'd required one more loop, and so on.\n\t *\n\t * XXX: this perhaps requires an execution time limit.\n\t */\n\tDUK_D(DUK_DPRINT(\"execute finalizers before freeing heap\"));\n\tDUK_ASSERT(heap->pf_skip_finalizers == 0);\n\tDUK_D(DUK_DPRINT(\"forced gc #1 in heap destruction\"));\n\tduk_heap_mark_and_sweep(heap, 0);\n\tDUK_D(DUK_DPRINT(\"forced gc #2 in heap destruction\"));\n\tduk_heap_mark_and_sweep(heap, 0);\n\tDUK_D(DUK_DPRINT(\"forced gc #3 in heap destruction (don't run finalizers)\"));\n\theap->pf_skip_finalizers = 1;\n\tduk_heap_mark_and_sweep(heap, 0);  /* Skip finalizers; queue finalizable objects to heap_allocated. */\n\n\t/* There are never objects in refzero_list at this point, or at any\n\t * point beyond a DECREF (even a DECREF_NORZ).  Since Duktape 2.1\n\t * refzero_list processing is side effect free, so it is always\n\t * processed to completion by a DECREF initially triggering a zero\n\t * refcount.\n\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always processed to completion inline. */\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tDUK_ASSERT(heap->finalize_list == NULL);  /* Last mark-and-sweep with skip_finalizers. */\n#endif\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tDUK_D(DUK_DPRINT(\"run finalizers for remaining finalizable objects\"));\n\tDUK_HEAP_SET_FINALIZER_NORESCUE(heap);  /* Rescue no longer supported. */\n\tduk__free_run_finalizers(heap);\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n\t/* Note: heap->heap_thread, heap->curr_thread, and heap->heap_object\n\t * are on the heap allocated list.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"freeing temporary freelists\"));\n\tduk_heap_free_freelists(heap);\n\n\tDUK_D(DUK_DPRINT(\"freeing heap_allocated of heap: %p\", (void *) heap));\n\tduk__free_allocated(heap);\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always processed to completion inline. */\n#endif\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tDUK_D(DUK_DPRINT(\"freeing finalize_list of heap: %p\", (void *) heap));\n\tduk__free_finalize_list(heap);\n#endif\n\n\tDUK_D(DUK_DPRINT(\"freeing string table of heap: %p\", (void *) heap));\n\tduk__free_stringtable(heap);\n\n\tDUK_D(DUK_DPRINT(\"freeing heap structure: %p\", (void *) heap));\n\theap->free_func(heap->heap_udata, heap);\n}\n\n/*\n *  Allocate a heap.\n *\n *  String table is initialized with built-in strings from genbuiltins.py,\n *  either by dynamically creating the strings or by referring to ROM strings.\n */\n\n#if defined(DUK_USE_ROM_STRINGS)\nDUK_LOCAL duk_bool_t duk__init_heap_strings(duk_heap *heap) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_small_uint_t i;\n#endif\n\n\tDUK_UNREF(heap);\n\n\t/* With ROM-based strings, heap->strs[] and thr->strs[] are omitted\n\t * so nothing to initialize for strs[].\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tfor (i = 0; i < sizeof(duk_rom_strings_lookup) / sizeof(const duk_hstring *); i++) {\n\t\tconst duk_hstring *h;\n\t\tduk_uint32_t hash;\n\n\t\th = duk_rom_strings_lookup[i];\n\t\twhile (h != NULL) {\n\t\t\thash = duk_heap_hashstring(heap, (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\t\t\tDUK_DD(DUK_DDPRINT(\"duk_rom_strings_lookup[%d] -> hash 0x%08lx, computed 0x%08lx\",\n\t\t\t                   (int) i, (unsigned long) DUK_HSTRING_GET_HASH(h), (unsigned long) hash));\n\t\t\tDUK_ASSERT(hash == (duk_uint32_t) DUK_HSTRING_GET_HASH(h));\n\n\t\t\th = (const duk_hstring *) h->hdr.h_next;\n\t\t}\n\t}\n#endif\n\treturn 1;\n}\n#else  /* DUK_USE_ROM_STRINGS */\n\nDUK_LOCAL duk_bool_t duk__init_heap_strings(duk_heap *heap) {\n\tduk_bitdecoder_ctx bd_ctx;\n\tduk_bitdecoder_ctx *bd = &bd_ctx;  /* convenience */\n\tduk_small_uint_t i;\n\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tbd->data = (const duk_uint8_t *) duk_strings_data;\n\tbd->length = (duk_size_t) DUK_STRDATA_DATA_LENGTH;\n\n\tfor (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) {\n\t\tduk_uint8_t tmp[DUK_STRDATA_MAX_STRLEN];\n\t\tduk_small_uint_t len;\n\t\tduk_hstring *h;\n\n\t\tlen = duk_bd_decode_bitpacked_string(bd, tmp);\n\n\t\t/* No need to length check string: it will never exceed even\n\t\t * the 16-bit length maximum.\n\t\t */\n\t\tDUK_ASSERT(len <= 0xffffUL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"intern built-in string %ld\", (long) i));\n\t\th = duk_heap_strtable_intern(heap, tmp, len);\n\t\tif (!h) {\n\t\t\tgoto failed;\n\t\t}\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h));\n\n\t\t/* Special flags checks.  Since these strings are always\n\t\t * reachable and a string cannot appear twice in the string\n\t\t * table, there's no need to check/set these flags elsewhere.\n\t\t * The 'internal' flag is set by string intern code.\n\t\t */\n\t\tif (i == DUK_STRIDX_EVAL || i == DUK_STRIDX_LC_ARGUMENTS) {\n\t\t\tDUK_HSTRING_SET_EVAL_OR_ARGUMENTS(h);\n\t\t}\n\t\tif (i >= DUK_STRIDX_START_RESERVED && i < DUK_STRIDX_END_RESERVED) {\n\t\t\tDUK_HSTRING_SET_RESERVED_WORD(h);\n\t\t\tif (i >= DUK_STRIDX_START_STRICT_RESERVED) {\n\t\t\t\tDUK_HSTRING_SET_STRICT_RESERVED_WORD(h);\n\t\t\t}\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"interned: %!O\", (duk_heaphdr *) h));\n\n\t\t/* XXX: The incref macro takes a thread pointer but doesn't\n\t\t * use it right now.\n\t\t */\n\t\tDUK_HSTRING_INCREF(_never_referenced_, h);\n\n#if defined(DUK_USE_HEAPPTR16)\n\t\theap->strs16[i] = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) h);\n#else\n\t\theap->strs[i] = h;\n#endif\n\t}\n\n\treturn 1;\n\n failed:\n\treturn 0;\n}\n#endif  /* DUK_USE_ROM_STRINGS */\n\nDUK_LOCAL duk_bool_t duk__init_heap_thread(duk_heap *heap) {\n\tduk_hthread *thr;\n\n\tDUK_D(DUK_DPRINT(\"heap init: alloc heap thread\"));\n\tthr = duk_hthread_alloc_unchecked(heap,\n\t                                  DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                  DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_THREAD));\n\tif (thr == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"failed to alloc heap_thread\"));\n\t\treturn 0;\n\t}\n\tthr->state = DUK_HTHREAD_STATE_INACTIVE;\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* No strs[] pointer. */\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n\tthr->strs16 = heap->strs16;\n#else\n\tthr->strs = heap->strs;\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n\theap->heap_thread = thr;\n\tDUK_HTHREAD_INCREF(thr, thr);  /* Note: first argument not really used */\n\n\t/* 'thr' is now reachable */\n\n\tDUK_D(DUK_DPRINT(\"heap init: init heap thread stacks\"));\n\tif (!duk_hthread_init_stacks(heap, thr)) {\n\t\treturn 0;\n\t}\n\n\t/* XXX: this may now fail, and is not handled correctly */\n\tduk_hthread_create_builtin_objects(thr);\n\n\t/* default prototype */\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) thr, thr->builtins[DUK_BIDX_THREAD_PROTOTYPE]);\n\n\treturn 1;\n}\n\n#if defined(DUK_USE_DEBUG)\n#define DUK__DUMPSZ(t)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"\" #t \"=%ld\", (long) sizeof(t))); \\\n\t} while (0)\n\n/* These is not 100% because format would need to be non-portable \"long long\".\n * Also print out as doubles to catch cases where the \"long\" type is not wide\n * enough; the limits will then not be printed accurately but the magnitude\n * will be correct.\n */\n#define DUK__DUMPLM_SIGNED_RAW(t,a,b)  do { \\\n\t\tDUK_D(DUK_DPRINT(t \"=[%ld,%ld]=[%lf,%lf]\", \\\n\t\t                 (long) (a), (long) (b), \\\n\t\t                 (double) (a), (double) (b))); \\\n\t} while (0)\n#define DUK__DUMPLM_UNSIGNED_RAW(t,a,b)  do { \\\n\t\tDUK_D(DUK_DPRINT(t \"=[%lu,%lu]=[%lf,%lf]\", \\\n\t\t                 (unsigned long) (a), (unsigned long) (b), \\\n\t\t                 (double) (a), (double) (b))); \\\n\t} while (0)\n#define DUK__DUMPLM_SIGNED(t)  do { \\\n\t\tDUK__DUMPLM_SIGNED_RAW(\"DUK_\" #t \"_{MIN,MAX}\", DUK_##t##_MIN, DUK_##t##_MAX); \\\n\t} while (0)\n#define DUK__DUMPLM_UNSIGNED(t)  do { \\\n\t\tDUK__DUMPLM_UNSIGNED_RAW(\"DUK_\" #t \"_{MIN,MAX}\", DUK_##t##_MIN, DUK_##t##_MAX); \\\n\t} while (0)\n\nDUK_LOCAL void duk__dump_type_sizes(void) {\n\tDUK_D(DUK_DPRINT(\"sizeof()\"));\n\n\t/* basic platform types */\n\tDUK__DUMPSZ(char);\n\tDUK__DUMPSZ(short);\n\tDUK__DUMPSZ(int);\n\tDUK__DUMPSZ(long);\n\tDUK__DUMPSZ(double);\n\tDUK__DUMPSZ(void *);\n\tDUK__DUMPSZ(size_t);\n\n\t/* basic types from duk_features.h */\n\tDUK__DUMPSZ(duk_uint8_t);\n\tDUK__DUMPSZ(duk_int8_t);\n\tDUK__DUMPSZ(duk_uint16_t);\n\tDUK__DUMPSZ(duk_int16_t);\n\tDUK__DUMPSZ(duk_uint32_t);\n\tDUK__DUMPSZ(duk_int32_t);\n\tDUK__DUMPSZ(duk_uint64_t);\n\tDUK__DUMPSZ(duk_int64_t);\n\tDUK__DUMPSZ(duk_uint_least8_t);\n\tDUK__DUMPSZ(duk_int_least8_t);\n\tDUK__DUMPSZ(duk_uint_least16_t);\n\tDUK__DUMPSZ(duk_int_least16_t);\n\tDUK__DUMPSZ(duk_uint_least32_t);\n\tDUK__DUMPSZ(duk_int_least32_t);\n#if defined(DUK_USE_64BIT_OPS)\n\tDUK__DUMPSZ(duk_uint_least64_t);\n\tDUK__DUMPSZ(duk_int_least64_t);\n#endif\n\tDUK__DUMPSZ(duk_uint_fast8_t);\n\tDUK__DUMPSZ(duk_int_fast8_t);\n\tDUK__DUMPSZ(duk_uint_fast16_t);\n\tDUK__DUMPSZ(duk_int_fast16_t);\n\tDUK__DUMPSZ(duk_uint_fast32_t);\n\tDUK__DUMPSZ(duk_int_fast32_t);\n#if defined(DUK_USE_64BIT_OPS)\n\tDUK__DUMPSZ(duk_uint_fast64_t);\n\tDUK__DUMPSZ(duk_int_fast64_t);\n#endif\n\tDUK__DUMPSZ(duk_uintptr_t);\n\tDUK__DUMPSZ(duk_intptr_t);\n\tDUK__DUMPSZ(duk_uintmax_t);\n\tDUK__DUMPSZ(duk_intmax_t);\n\tDUK__DUMPSZ(duk_double_t);\n\n\t/* important chosen base types */\n\tDUK__DUMPSZ(duk_int_t);\n\tDUK__DUMPSZ(duk_uint_t);\n\tDUK__DUMPSZ(duk_int_fast_t);\n\tDUK__DUMPSZ(duk_uint_fast_t);\n\tDUK__DUMPSZ(duk_small_int_t);\n\tDUK__DUMPSZ(duk_small_uint_t);\n\tDUK__DUMPSZ(duk_small_int_fast_t);\n\tDUK__DUMPSZ(duk_small_uint_fast_t);\n\n\t/* some derived types */\n\tDUK__DUMPSZ(duk_codepoint_t);\n\tDUK__DUMPSZ(duk_ucodepoint_t);\n\tDUK__DUMPSZ(duk_idx_t);\n\tDUK__DUMPSZ(duk_errcode_t);\n\tDUK__DUMPSZ(duk_uarridx_t);\n\n\t/* tval */\n\tDUK__DUMPSZ(duk_double_union);\n\tDUK__DUMPSZ(duk_tval);\n\n\t/* structs from duk_forwdecl.h */\n\tDUK__DUMPSZ(duk_jmpbuf);  /* just one 'int' for C++ exceptions */\n\tDUK__DUMPSZ(duk_heaphdr);\n\tDUK__DUMPSZ(duk_heaphdr_string);\n\tDUK__DUMPSZ(duk_hstring);\n\tDUK__DUMPSZ(duk_hstring_external);\n\tDUK__DUMPSZ(duk_hobject);\n\tDUK__DUMPSZ(duk_harray);\n\tDUK__DUMPSZ(duk_hcompfunc);\n\tDUK__DUMPSZ(duk_hnatfunc);\n\tDUK__DUMPSZ(duk_hdecenv);\n\tDUK__DUMPSZ(duk_hobjenv);\n\tDUK__DUMPSZ(duk_hthread);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tDUK__DUMPSZ(duk_hbufobj);\n#endif\n\tDUK__DUMPSZ(duk_hproxy);\n\tDUK__DUMPSZ(duk_hbuffer);\n\tDUK__DUMPSZ(duk_hbuffer_fixed);\n\tDUK__DUMPSZ(duk_hbuffer_dynamic);\n\tDUK__DUMPSZ(duk_hbuffer_external);\n\tDUK__DUMPSZ(duk_propaccessor);\n\tDUK__DUMPSZ(duk_propvalue);\n\tDUK__DUMPSZ(duk_propdesc);\n\tDUK__DUMPSZ(duk_heap);\n\tDUK__DUMPSZ(duk_activation);\n\tDUK__DUMPSZ(duk_catcher);\n\tDUK__DUMPSZ(duk_strcache_entry);\n\tDUK__DUMPSZ(duk_litcache_entry);\n\tDUK__DUMPSZ(duk_ljstate);\n\tDUK__DUMPSZ(duk_fixedbuffer);\n\tDUK__DUMPSZ(duk_bitdecoder_ctx);\n\tDUK__DUMPSZ(duk_bitencoder_ctx);\n\tDUK__DUMPSZ(duk_token);\n\tDUK__DUMPSZ(duk_re_token);\n\tDUK__DUMPSZ(duk_lexer_point);\n\tDUK__DUMPSZ(duk_lexer_ctx);\n\tDUK__DUMPSZ(duk_compiler_instr);\n\tDUK__DUMPSZ(duk_compiler_func);\n\tDUK__DUMPSZ(duk_compiler_ctx);\n\tDUK__DUMPSZ(duk_re_matcher_ctx);\n\tDUK__DUMPSZ(duk_re_compiler_ctx);\n}\nDUK_LOCAL void duk__dump_type_limits(void) {\n\tDUK_D(DUK_DPRINT(\"limits\"));\n\n\t/* basic types */\n\tDUK__DUMPLM_SIGNED(INT8);\n\tDUK__DUMPLM_UNSIGNED(UINT8);\n\tDUK__DUMPLM_SIGNED(INT_FAST8);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST8);\n\tDUK__DUMPLM_SIGNED(INT_LEAST8);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST8);\n\tDUK__DUMPLM_SIGNED(INT16);\n\tDUK__DUMPLM_UNSIGNED(UINT16);\n\tDUK__DUMPLM_SIGNED(INT_FAST16);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST16);\n\tDUK__DUMPLM_SIGNED(INT_LEAST16);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST16);\n\tDUK__DUMPLM_SIGNED(INT32);\n\tDUK__DUMPLM_UNSIGNED(UINT32);\n\tDUK__DUMPLM_SIGNED(INT_FAST32);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST32);\n\tDUK__DUMPLM_SIGNED(INT_LEAST32);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST32);\n#if defined(DUK_USE_64BIT_OPS)\n\tDUK__DUMPLM_SIGNED(INT64);\n\tDUK__DUMPLM_UNSIGNED(UINT64);\n\tDUK__DUMPLM_SIGNED(INT_FAST64);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST64);\n\tDUK__DUMPLM_SIGNED(INT_LEAST64);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST64);\n#endif\n\tDUK__DUMPLM_SIGNED(INTPTR);\n\tDUK__DUMPLM_UNSIGNED(UINTPTR);\n\tDUK__DUMPLM_SIGNED(INTMAX);\n\tDUK__DUMPLM_UNSIGNED(UINTMAX);\n\n\t/* derived types */\n\tDUK__DUMPLM_SIGNED(INT);\n\tDUK__DUMPLM_UNSIGNED(UINT);\n\tDUK__DUMPLM_SIGNED(INT_FAST);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST);\n\tDUK__DUMPLM_SIGNED(SMALL_INT);\n\tDUK__DUMPLM_UNSIGNED(SMALL_UINT);\n\tDUK__DUMPLM_SIGNED(SMALL_INT_FAST);\n\tDUK__DUMPLM_UNSIGNED(SMALL_UINT_FAST);\n}\n\nDUK_LOCAL void duk__dump_misc_options(void) {\n\tDUK_D(DUK_DPRINT(\"DUK_VERSION: %ld\", (long) DUK_VERSION));\n\tDUK_D(DUK_DPRINT(\"DUK_GIT_DESCRIBE: %s\", DUK_GIT_DESCRIBE));\n\tDUK_D(DUK_DPRINT(\"OS string: %s\", DUK_USE_OS_STRING));\n\tDUK_D(DUK_DPRINT(\"architecture string: %s\", DUK_USE_ARCH_STRING));\n\tDUK_D(DUK_DPRINT(\"compiler string: %s\", DUK_USE_COMPILER_STRING));\n\tDUK_D(DUK_DPRINT(\"debug level: %ld\", (long) DUK_USE_DEBUG_LEVEL));\n#if defined(DUK_USE_PACKED_TVAL)\n\tDUK_D(DUK_DPRINT(\"DUK_USE_PACKED_TVAL: yes\"));\n#else\n\tDUK_D(DUK_DPRINT(\"DUK_USE_PACKED_TVAL: no\"));\n#endif\n#if defined(DUK_USE_VARIADIC_MACROS)\n\tDUK_D(DUK_DPRINT(\"DUK_USE_VARIADIC_MACROS: yes\"));\n#else\n\tDUK_D(DUK_DPRINT(\"DUK_USE_VARIADIC_MACROS: no\"));\n#endif\n#if defined(DUK_USE_INTEGER_LE)\n\tDUK_D(DUK_DPRINT(\"integer endianness: little\"));\n#elif defined(DUK_USE_INTEGER_ME)\n\tDUK_D(DUK_DPRINT(\"integer endianness: mixed\"));\n#elif defined(DUK_USE_INTEGER_BE)\n\tDUK_D(DUK_DPRINT(\"integer endianness: big\"));\n#else\n\tDUK_D(DUK_DPRINT(\"integer endianness: ???\"));\n#endif\n#if defined(DUK_USE_DOUBLE_LE)\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: little\"));\n#elif defined(DUK_USE_DOUBLE_ME)\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: mixed\"));\n#elif defined(DUK_USE_DOUBLE_BE)\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: big\"));\n#else\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: ???\"));\n#endif\n}\n#endif  /* DUK_USE_DEBUG */\n\nDUK_INTERNAL\nduk_heap *duk_heap_alloc(duk_alloc_function alloc_func,\n                         duk_realloc_function realloc_func,\n                         duk_free_function free_func,\n                         void *heap_udata,\n                         duk_fatal_function fatal_func) {\n\tduk_heap *res = NULL;\n\tduk_uint32_t st_initsize;\n\n\tDUK_D(DUK_DPRINT(\"allocate heap\"));\n\n\t/*\n\t *  Random config sanity asserts\n\t */\n\n\tDUK_ASSERT(DUK_USE_STRTAB_MINSIZE >= 64);\n\n\tDUK_ASSERT((DUK_HTYPE_STRING & 0x01U) == 0);\n\tDUK_ASSERT((DUK_HTYPE_BUFFER & 0x01U) == 0);\n\tDUK_ASSERT((DUK_HTYPE_OBJECT & 0x01U) == 1);  /* DUK_HEAPHDR_IS_OBJECT() relies ont his. */\n\n\t/*\n\t *  Debug dump type sizes\n\t */\n\n#if defined(DUK_USE_DEBUG)\n\tduk__dump_misc_options();\n\tduk__dump_type_sizes();\n\tduk__dump_type_limits();\n#endif\n\n\t/*\n\t *  If selftests enabled, run them as early as possible.\n\t */\n\n#if defined(DUK_USE_SELF_TESTS)\n\tDUK_D(DUK_DPRINT(\"run self tests\"));\n\tif (duk_selftest_run_tests(alloc_func, realloc_func, free_func, heap_udata) > 0) {\n\t\tfatal_func(heap_udata, \"self test(s) failed\");\n\t}\n\tDUK_D(DUK_DPRINT(\"self tests passed\"));\n#endif\n\n\t/*\n\t *  Important assert-like checks that should be enabled even\n\t *  when assertions are otherwise not enabled.\n\t */\n\n#if defined(DUK_USE_EXEC_REGCONST_OPTIMIZE)\n\t/* Can't check sizeof() using preprocessor so explicit check.\n\t * This will be optimized away in practice; unfortunately a\n\t * warning is generated on some compilers as a result.\n\t */\n#if defined(DUK_USE_PACKED_TVAL)\n\tif (sizeof(duk_tval) != 8) {\n#else\n\tif (sizeof(duk_tval) != 16) {\n#endif\n\t\tfatal_func(heap_udata, \"sizeof(duk_tval) not 8 or 16, cannot use DUK_USE_EXEC_REGCONST_OPTIMIZE option\");\n\t}\n#endif  /* DUK_USE_EXEC_REGCONST_OPTIMIZE */\n\n\t/*\n\t *  Computed values (e.g. INFINITY)\n\t */\n\n#if defined(DUK_USE_COMPUTED_NAN)\n\tdo {\n\t\t/* Workaround for some exotic platforms where NAN is missing\n\t\t * and the expression (0.0 / 0.0) does NOT result in a NaN.\n\t\t * Such platforms use the global 'duk_computed_nan' which must\n\t\t * be initialized at runtime.  Use 'volatile' to ensure that\n\t\t * the compiler will actually do the computation and not try\n\t\t * to do constant folding which might result in the original\n\t\t * problem.\n\t\t */\n\t\tvolatile double dbl1 = 0.0;\n\t\tvolatile double dbl2 = 0.0;\n\t\tduk_computed_nan = dbl1 / dbl2;\n\t} while (0);\n#endif\n\n#if defined(DUK_USE_COMPUTED_INFINITY)\n\tdo {\n\t\t/* Similar workaround for INFINITY. */\n\t\tvolatile double dbl1 = 1.0;\n\t\tvolatile double dbl2 = 0.0;\n\t\tduk_computed_infinity = dbl1 / dbl2;\n\t} while (0);\n#endif\n\n\t/*\n\t *  Allocate heap struct\n\t *\n\t *  Use a raw call, all macros expect the heap to be initialized\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 1)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"alloc duk_heap object\"));\n\tres = (duk_heap *) alloc_func(heap_udata, sizeof(duk_heap));\n\tif (!res) {\n\t\tgoto failed;\n\t}\n\n\t/*\n\t *  Zero the struct, and start initializing roughly in order\n\t */\n\n\tduk_memzero(res, sizeof(*res));\n#if defined(DUK_USE_ASSERTIONS)\n\tres->heap_initializing = 1;\n#endif\n\n\t/* explicit NULL inits */\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->heap_udata = NULL;\n\tres->heap_allocated = NULL;\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tres->refzero_list = NULL;\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tres->finalize_list = NULL;\n#if defined(DUK_USE_ASSERTIONS)\n\tres->currently_finalizing = NULL;\n#endif\n#endif\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\tres->activation_free = NULL;\n#endif\n#if defined(DUK_USE_CACHE_CATCHER)\n\tres->catcher_free = NULL;\n#endif\n\tres->heap_thread = NULL;\n\tres->curr_thread = NULL;\n\tres->heap_object = NULL;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tres->strtable16 = NULL;\n#else\n\tres->strtable = NULL;\n#endif\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* no res->strs[] */\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n\t/* res->strs16[] is zeroed and zero decodes to NULL, so no NULL inits. */\n#else\n\t{\n\t\tduk_small_uint_t i;\n\t        for (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) {\n\t\t\tres->strs[i] = NULL;\n\t        }\n\t}\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tres->dbg_read_cb = NULL;\n\tres->dbg_write_cb = NULL;\n\tres->dbg_peek_cb = NULL;\n\tres->dbg_read_flush_cb = NULL;\n\tres->dbg_write_flush_cb = NULL;\n\tres->dbg_request_cb = NULL;\n\tres->dbg_udata = NULL;\n\tres->dbg_pause_act = NULL;\n#endif\n#endif  /* DUK_USE_EXPLICIT_NULL_INIT */\n\n\tres->alloc_func = alloc_func;\n\tres->realloc_func = realloc_func;\n\tres->free_func = free_func;\n\tres->heap_udata = heap_udata;\n\tres->fatal_func = fatal_func;\n\n\t/* XXX: for now there's a pointer packing zero assumption, i.e.\n\t * NULL <=> compressed pointer 0.  If this is removed, may need\n\t * to precompute e.g. null16 here.\n\t */\n\n\t/* res->ms_trigger_counter == 0 -> now causes immediate GC; which is OK */\n\n\t/* Prevent mark-and-sweep and finalizer execution until heap is completely\n\t * initialized.\n\t */\n\tDUK_ASSERT(res->ms_prevent_count == 0);\n\tDUK_ASSERT(res->pf_prevent_count == 0);\n\tres->ms_prevent_count = 1;\n\tres->pf_prevent_count = 1;\n\tDUK_ASSERT(res->ms_running == 0);\n\n\tres->call_recursion_depth = 0;\n\tres->call_recursion_limit = DUK_USE_NATIVE_CALL_RECLIMIT;\n\n\t/* XXX: use the pointer as a seed for now: mix in time at least */\n\n\t/* The casts through duk_uintptr_t is to avoid the following GCC warning:\n\t *\n\t *   warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]\n\t *\n\t * This still generates a /Wp64 warning on VS2010 when compiling for x86.\n\t */\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* XXX: make a common DUK_USE_ option, and allow custom fixed seed? */\n\tDUK_D(DUK_DPRINT(\"using rom strings, force heap hash_seed to fixed value 0x%08lx\", (long) DUK__FIXED_HASH_SEED));\n\tres->hash_seed = (duk_uint32_t) DUK__FIXED_HASH_SEED;\n#else  /* DUK_USE_ROM_STRINGS */\n\tres->hash_seed = (duk_uint32_t) (duk_uintptr_t) res;\n#if !defined(DUK_USE_STRHASH_DENSE)\n\tres->hash_seed ^= 5381;  /* Bernstein hash init value is normally 5381; XOR it in in case pointer low bits are 0 */\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->lj.jmpbuf_ptr = NULL;\n#endif\n\tDUK_ASSERT(res->lj.type == DUK_LJ_TYPE_UNKNOWN);  /* zero */\n\tDUK_ASSERT(res->lj.iserror == 0);\n\tDUK_TVAL_SET_UNDEFINED(&res->lj.value1);\n\tDUK_TVAL_SET_UNDEFINED(&res->lj.value2);\n\n\tDUK_ASSERT_LJSTATE_UNSET(res);\n\n\t/*\n\t *  Init stringtable: fixed variant\n\t */\n\n\tst_initsize = DUK_USE_STRTAB_MINSIZE;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tres->strtable16 = (duk_uint16_t *) alloc_func(heap_udata, sizeof(duk_uint16_t) * st_initsize);\n\tif (res->strtable16 == NULL) {\n\t\tgoto failed;\n\t}\n#else\n\tres->strtable = (duk_hstring **) alloc_func(heap_udata, sizeof(duk_hstring *) * st_initsize);\n\tif (res->strtable == NULL) {\n\t\tgoto failed;\n\t}\n#endif\n\tres->st_size = st_initsize;\n\tres->st_mask = st_initsize - 1;\n#if (DUK_USE_STRTAB_MINSIZE != DUK_USE_STRTAB_MAXSIZE)\n\tDUK_ASSERT(res->st_count == 0);\n#endif\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t/* zero assumption */\n\tduk_memzero(res->strtable16, sizeof(duk_uint16_t) * st_initsize);\n#else\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t{\n\t\tduk_uint32_t i;\n\t        for (i = 0; i < st_initsize; i++) {\n\t\t\tres->strtable[i] = NULL;\n\t        }\n\t}\n#else\n\tduk_memzero(res->strtable, sizeof(duk_hstring *) * st_initsize);\n#endif  /* DUK_USE_EXPLICIT_NULL_INIT */\n#endif  /* DUK_USE_STRTAB_PTRCOMP */\n\n\t/*\n\t *  Init stringcache\n\t */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t{\n\t\tduk_uint_t i;\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tres->strcache[i].h = NULL;\n\t\t}\n\t}\n#endif\n\n\t/*\n\t *  Init litcache\n\t */\n#if defined(DUK_USE_LITCACHE_SIZE)\n\tDUK_ASSERT(DUK_USE_LITCACHE_SIZE > 0);\n\tDUK_ASSERT(DUK_IS_POWER_OF_TWO((duk_uint_t) DUK_USE_LITCACHE_SIZE));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t{\n\t\tduk_uint_t i;\n\t\tfor (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) {\n\t\t\tres->litcache[i].addr = NULL;\n\t\t\tres->litcache[i].h = NULL;\n\t\t}\n\t}\n#endif\n#endif  /* DUK_USE_LITCACHE_SIZE */\n\n\t/* XXX: error handling is incomplete.  It would be cleanest if\n\t * there was a setjmp catchpoint, so that all init code could\n\t * freely throw errors.  If that were the case, the return code\n\t * passing here could be removed.\n\t */\n\n\t/*\n\t *  Init built-in strings\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 2)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"heap init: initialize heap strings\"));\n\tif (!duk__init_heap_strings(res)) {\n\t\tgoto failed;\n\t}\n\n\t/*\n\t *  Init the heap thread\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 3)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"heap init: initialize heap thread\"));\n\tif (!duk__init_heap_thread(res)) {\n\t\tgoto failed;\n\t}\n\n\t/*\n\t *  Init the heap object\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 4)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"heap init: initialize heap object\"));\n\tDUK_ASSERT(res->heap_thread != NULL);\n\tres->heap_object = duk_hobject_alloc_unchecked(res, DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                                    DUK_HOBJECT_FLAG_FASTREFS |\n\t                                                    DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT));\n\tif (res->heap_object == NULL) {\n\t\tgoto failed;\n\t}\n\tDUK_HOBJECT_INCREF(res->heap_thread, res->heap_object);\n\n\t/*\n\t *  Odds and ends depending on the heap thread\n\t */\n\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\n#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS)\n\tres->rnd_state = (duk_uint32_t) duk_time_get_ecmascript_time(res->heap_thread);\n\tduk_util_tinyrandom_prepare_seed(res->heap_thread);\n#else\n\tres->rnd_state[0] = (duk_uint64_t) duk_time_get_ecmascript_time(res->heap_thread);\n\tDUK_ASSERT(res->rnd_state[1] == 0);  /* Not filled here, filled in by seed preparation. */\n#if 0  /* Manual test values matching misc/xoroshiro128plus_test.c. */\n\tres->rnd_state[0] = DUK_U64_CONSTANT(0xdeadbeef12345678);\n\tres->rnd_state[1] = DUK_U64_CONSTANT(0xcafed00d12345678);\n#endif\n\tduk_util_tinyrandom_prepare_seed(res->heap_thread);\n\t/* Mix in heap pointer: this ensures that if two Duktape heaps are\n\t * created on the same millisecond, they get a different PRNG\n\t * sequence (unless e.g. virtual memory addresses cause also the\n\t * heap object pointer to be the same).\n\t */\n\t{\n\t\tduk_uint64_t tmp_u64;\n\t\ttmp_u64 = 0;\n\t\tduk_memcpy((void *) &tmp_u64,\n\t\t           (const void *) &res,\n\t\t           (size_t) (sizeof(void *) >= sizeof(duk_uint64_t) ? sizeof(duk_uint64_t) : sizeof(void *)));\n\t\tres->rnd_state[1] ^= tmp_u64;\n\t}\n\tdo {\n\t\tduk_small_uint_t i;\n\t\tfor (i = 0; i < 10; i++) {\n\t\t\t/* Throw away a few initial random numbers just in\n\t\t\t * case.  Probably unnecessary due to SplitMix64\n\t\t\t * preparation.\n\t\t\t */\n\t\t\t(void) duk_util_tinyrandom_get_double(res->heap_thread);\n\t\t}\n\t} while (0);\n#endif\n#endif\n\n\t/*\n\t *  Allow finalizer and mark-and-sweep processing.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"heap init: allow finalizer/mark-and-sweep processing\"));\n\tDUK_ASSERT(res->ms_prevent_count == 1);\n\tDUK_ASSERT(res->pf_prevent_count == 1);\n\tres->ms_prevent_count = 0;\n\tres->pf_prevent_count = 0;\n\tDUK_ASSERT(res->ms_running == 0);\n#if defined(DUK_USE_ASSERTIONS)\n\tres->heap_initializing = 0;\n#endif\n\n\t/*\n\t *  All done.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"allocated heap: %p\", (void *) res));\n\treturn res;\n\n failed:\n\tDUK_D(DUK_DPRINT(\"heap allocation failed\"));\n\n\tif (res != NULL) {\n\t\t/* Assumes that allocated pointers and alloc funcs are valid\n\t\t * if res exists.\n\t\t */\n\t\tDUK_ASSERT(res->ms_prevent_count == 1);\n\t\tDUK_ASSERT(res->pf_prevent_count == 1);\n\t\tDUK_ASSERT(res->ms_running == 0);\n\t\tif (res->heap_thread != NULL) {\n\t\t\tres->ms_prevent_count = 0;\n\t\t\tres->pf_prevent_count = 0;\n\t\t}\n#if defined(DUK_USE_ASSERTIONS)\n\t\tres->heap_initializing = 0;\n#endif\n\n\t\tDUK_ASSERT(res->alloc_func != NULL);\n\t\tDUK_ASSERT(res->realloc_func != NULL);\n\t\tDUK_ASSERT(res->free_func != NULL);\n\t\tduk_heap_free(res);\n\t}\n\n\treturn NULL;\n}\n\n/* automatic undefs */\n#undef DUK__DUMPLM_SIGNED\n#undef DUK__DUMPLM_SIGNED_RAW\n#undef DUK__DUMPLM_UNSIGNED\n#undef DUK__DUMPLM_UNSIGNED_RAW\n#undef DUK__DUMPSZ\n#undef DUK__FIXED_HASH_SEED\n/*\n *  Finalizer handling.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\n/*\n *  Fake torture finalizer.\n */\n\n#if defined(DUK_USE_FINALIZER_TORTURE)\nDUK_LOCAL duk_ret_t duk__fake_global_finalizer(duk_hthread *thr) {\n\tDUK_DD(DUK_DDPRINT(\"fake global torture finalizer executed\"));\n\n\t/* Require a lot of stack to force a value stack grow/shrink. */\n\tduk_require_stack(thr, 100000);\n\n\t/* Force a reallocation with pointer change for value stack\n\t * to maximize side effects.\n\t */\n\tduk_hthread_valstack_torture_realloc(thr);\n\n\t/* Inner function call, error throw. */\n\tduk_eval_string_noresult(thr,\n\t\t\"(function dummy() {\\n\"\n\t\t\"    dummy.prototype = null;  /* break reference loop */\\n\"\n\t\t\"    try {\\n\"\n\t\t\"        throw 'fake-finalizer-dummy-error';\\n\"\n\t\t\"    } catch (e) {\\n\"\n\t\t\"        void e;\\n\"\n\t\t\"    }\\n\"\n\t\t\"})()\");\n\n\t/* The above creates garbage (e.g. a function instance).  Because\n\t * the function/prototype reference loop is broken, it gets collected\n\t * immediately by DECREF.  If Function.prototype has a _Finalizer\n\t * property (happens in some test cases), the garbage gets queued to\n\t * finalize_list.  This still won't cause an infinite loop because\n\t * the torture finalizer is called once per finalize_list run and\n\t * the garbage gets handled in the same run.  (If the garbage needs\n\t * mark-and-sweep collection, an infinite loop might ensue.)\n\t */\n\treturn 0;\n}\n\nDUK_LOCAL void duk__run_global_torture_finalizer(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Avoid fake finalization when callstack limit is near.  Otherwise\n\t * a callstack limit error will be created, then refzero'ed.  The\n\t * +5 headroom is conservative.\n\t */\n\tif (thr->heap->call_recursion_depth + 5 >= thr->heap->call_recursion_limit ||\n\t    thr->callstack_top + 5 >= DUK_USE_CALLSTACK_LIMIT) {\n\t\tDUK_D(DUK_DPRINT(\"skip global torture finalizer, too little headroom for call recursion or call stack size\"));\n\t\treturn;\n\t}\n\n\t/* Run fake finalizer.  Avoid creating unnecessary garbage. */\n\tduk_push_c_function(thr, duk__fake_global_finalizer, 0 /*nargs*/);\n\t(void) duk_pcall(thr, 0 /*nargs*/);\n\tduk_pop(thr);\n}\n#endif  /* DUK_USE_FINALIZER_TORTURE */\n\n/*\n *  Process the finalize_list to completion.\n *\n *  An object may be placed on finalize_list by either refcounting or\n *  mark-and-sweep.  The refcount of objects placed by refcounting will be\n *  zero; the refcount of objects placed by mark-and-sweep is > 0.  In both\n *  cases the refcount is bumped by 1 artificially so that a REFZERO event\n *  can never happen while an object is waiting for finalization.  Without\n *  this bump a REFZERO could now happen because user code may call\n *  duk_push_heapptr() and then pop a value even when it's on finalize_list.\n *\n *  List processing assumes refcounts are kept up-to-date at all times, so\n *  that once the finalizer returns, a zero refcount is a reliable reason to\n *  free the object immediately rather than place it back to the heap.  This\n *  is the case because we run outside of refzero_list processing so that\n *  DECREF cascades are handled fully inline.\n *\n *  For mark-and-sweep queued objects (had_zero_refcount false) the object\n *  may be freed immediately if its refcount is zero after the finalizer call\n *  (i.e. finalizer removed the reference loop for the object).  If not, the\n *  next mark-and-sweep will collect the object unless it has become reachable\n *  (i.e. rescued) by that time and its refcount hasn't fallen to zero before\n *  that.  Mark-and-sweep detects these objects because their FINALIZED flag\n *  is set.\n *\n *  There's an inherent limitation for mark-and-sweep finalizer rescuing: an\n *  object won't get refinalized if (1) it's rescued, but (2) becomes\n *  unreachable before mark-and-sweep has had time to notice it.  The next\n *  mark-and-sweep round simply doesn't have any information of whether the\n *  object has been unreachable the whole time or not (the only way to get\n *  that information would be a mark-and-sweep pass for *every finalized\n *  object*).  This is awkward for the application because the mark-and-sweep\n *  round is not generally visible or under full application control.\n *\n *  For refcount queued objects (had_zero_refcount true) the object is either\n *  immediately freed or rescued, and waiting for a mark-and-sweep round is not\n *  necessary (or desirable); FINALIZED is cleared when a rescued object is\n *  queued back to heap_allocated.  The object is eligible for finalization\n *  again (either via refcounting or mark-and-sweep) immediately after being\n *  rescued.  If a refcount finalized object is placed into an unreachable\n *  reference loop by its finalizer, it will get collected by mark-and-sweep\n *  and currently the finalizer will execute again.\n *\n *  There's a special case where:\n *\n *    - Mark-and-sweep queues an object to finalize_list for finalization.\n *    - The finalizer is executed, FINALIZED is set, and object is queued\n *      back to heap_allocated, waiting for a new mark-and-sweep round.\n *    - The object's refcount drops to zero before mark-and-sweep has a\n *      chance to run another round and make a rescue/free decision.\n *\n *  This is now handled by refzero code: if an object has a finalizer but\n *  FINALIZED is already set, the object is freed without finalizer processing.\n *  The outcome is the same as if mark-and-sweep was executed at that point;\n *  mark-and-sweep would also free the object without another finalizer run.\n *  This could also be changed so that the refzero-triggered finalizer *IS*\n *  executed: being refzero collected implies someone has operated on the\n *  object so it hasn't been totally unreachable the whole time.  This would\n *  risk a finalizer loop however.\n */\n\nDUK_INTERNAL void duk_heap_process_finalize_list(duk_heap *heap) {\n\tduk_heaphdr *curr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count = 0;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk_heap_process_finalize_list: %p\", (void *) heap));\n\n\tif (heap->pf_prevent_count != 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"skip finalize_list processing: pf_prevent_count != 0\"));\n\t\treturn;\n\t}\n\n\t/* Heap alloc prevents mark-and-sweep before heap_thread is ready. */\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(heap->heap_thread->valstack != NULL);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);\n#endif\n\n\tDUK_ASSERT(heap->pf_prevent_count == 0);\n\theap->pf_prevent_count = 1;\n\n\t/* Mark-and-sweep no longer needs to be prevented when running\n\t * finalizers: mark-and-sweep skips any rescue decisions if there\n\t * are any objects in finalize_list when mark-and-sweep is entered.\n\t * This protects finalized objects from incorrect rescue decisions\n\t * caused by finalize_list being a reachability root and only\n\t * partially processed.  Freeing decisions are not postponed.\n\t */\n\n\t/* When finalizer torture is enabled, make a fake finalizer call with\n\t * maximum side effects regardless of whether finalize_list is empty.\n\t */\n#if defined(DUK_USE_FINALIZER_TORTURE)\n\tduk__run_global_torture_finalizer(heap->heap_thread);\n#endif\n\n\t/* Process finalize_list until it becomes empty.  There's currently no\n\t * protection against a finalizer always creating more garbage.\n\t */\n\twhile ((curr = heap->finalize_list) != NULL) {\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tduk_bool_t queue_back;\n#endif\n\n\t\tDUK_DD(DUK_DDPRINT(\"processing finalize_list entry: %p -> %!iO\", (void *) curr, curr));\n\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);  /* Only objects have finalizers. */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(curr));\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(curr));\n\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZABLE(curr));  /* All objects on finalize_list will have this flag (except object being finalized right now). */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));   /* Queueing code ensures. */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(curr));  /* ROM objects never get freed (or finalized). */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\tDUK_ASSERT(heap->currently_finalizing == NULL);\n\t\theap->currently_finalizing = curr;\n#endif\n\n\t\t/* Clear FINALIZABLE for object being finalized, so that\n\t\t * duk_push_heapptr() can properly ignore the object.\n\t\t */\n\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\n\t\tif (DUK_LIKELY(!heap->pf_skip_finalizers)) {\n\t\t\t/* Run the finalizer, duk_heap_run_finalizer() sets\n\t\t\t * and checks for FINALIZED to prevent the finalizer\n\t\t\t * from executing multiple times per finalization cycle.\n\t\t\t * (This safeguard shouldn't be actually needed anymore).\n\t\t\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tduk_bool_t had_zero_refcount;\n#endif\n\n\t\t\t/* The object's refcount is >0 throughout so it won't be\n\t\t\t * refzero processed prematurely.\n\t\t\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) >= 1);\n\t\t\thad_zero_refcount = (DUK_HEAPHDR_GET_REFCOUNT(curr) == 1);  /* Preincremented on finalize_list insert. */\n#endif\n\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));\n\t\t\tduk_heap_run_finalizer(heap, (duk_hobject *) curr);  /* must never longjmp */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZED(curr));\n\t\t\t/* XXX: assert that object is still in finalize_list\n\t\t\t * when duk_push_heapptr() allows automatic rescue.\n\t\t\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tDUK_DD(DUK_DDPRINT(\"refcount after finalizer (includes bump): %ld\", (long) DUK_HEAPHDR_GET_REFCOUNT(curr)));\n\t\t\tif (DUK_HEAPHDR_GET_REFCOUNT(curr) == 1) {  /* Only artificial bump in refcount? */\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tif (had_zero_refcount) {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"finalized object's refcount is zero -> free immediately (refcount queued)\"));\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"finalized object's refcount is zero -> free immediately (mark-and-sweep queued)\"));\n\t\t\t\t}\n#endif\n\t\t\t\tqueue_back = 0;\n\t\t\t} else\n#endif\n\t\t\t{\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t\tqueue_back = 1;\n\t\t\t\tif (had_zero_refcount) {\n\t\t\t\t\t/* When finalization is triggered\n\t\t\t\t\t * by refzero and we queue the object\n\t\t\t\t\t * back, clear FINALIZED right away\n\t\t\t\t\t * so that the object can be refinalized\n\t\t\t\t\t * immediately if necessary.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_HEAPHDR_CLEAR_FINALIZED(curr);\n\t\t\t\t}\n#endif\n\t\t\t}\n\t\t} else {\n\t\t\t/* Used during heap destruction: don't actually run finalizers\n\t\t\t * because we're heading into forced finalization.  Instead,\n\t\t\t * queue finalizable objects back to the heap_allocated list.\n\t\t\t */\n\t\t\tDUK_D(DUK_DPRINT(\"skip finalizers flag set, queue object to heap_allocated without finalizing\"));\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tqueue_back = 1;\n#endif\n\t\t}\n\n\t\t/* Dequeue object from finalize_list.  Note that 'curr' may no\n\t\t * longer be finalize_list head because new objects may have\n\t\t * been queued to the list.  As a result we can't optimize for\n\t\t * the single-linked heap case and must scan the list for\n\t\t * removal, typically the scan is very short however.\n\t\t */\n\t\tDUK_HEAP_REMOVE_FROM_FINALIZE_LIST(heap, curr);\n\n\t\t/* Queue back to heap_allocated or free immediately. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tif (queue_back) {\n\t\t\t/* FINALIZED is only cleared if object originally\n\t\t\t * queued for finalization by refcounting.  For\n\t\t\t * mark-and-sweep FINALIZED is left set, so that\n\t\t\t * next mark-and-sweep round can make a rescue/free\n\t\t\t * decision.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) >= 1);\n\t\t\tDUK_HEAPHDR_PREDEC_REFCOUNT(curr);  /* Remove artificial refcount bump. */\n\t\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\t\t\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, curr);\n\t\t} else {\n\t\t\t/* No need to remove the refcount bump here. */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);  /* currently, always the case */\n\t\t\tDUK_DD(DUK_DDPRINT(\"refcount finalize after finalizer call: %!O\", curr));\n\t\t\tduk_hobject_refcount_finalize_norz(heap, (duk_hobject *) curr);\n\t\t\tduk_free_hobject(heap, (duk_hobject *) curr);\n\t\t\tDUK_DD(DUK_DDPRINT(\"freed hobject after finalization: %p\", (void *) curr));\n\t\t}\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\t\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, curr);\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_DEBUG)\n\t\tcount++;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\tDUK_ASSERT(heap->currently_finalizing != NULL);\n\t\theap->currently_finalizing = NULL;\n#endif\n\t}\n\n\t/* finalize_list will always be processed completely. */\n\tDUK_ASSERT(heap->finalize_list == NULL);\n\n#if 0\n\t/* While NORZ macros are used above, this is unnecessary because the\n\t * only pending side effects are now finalizers, and finalize_list is\n\t * empty.\n\t */\n\tDUK_REFZERO_CHECK_SLOW(heap->heap_thread);\n#endif\n\n\t/* Prevent count may be bumped while finalizers run, but should always\n\t * be reliably unbumped by the time we get here.\n\t */\n\tDUK_ASSERT(heap->pf_prevent_count == 1);\n\theap->pf_prevent_count = 0;\n\n#if defined(DUK_USE_DEBUG)\n\tDUK_DD(DUK_DDPRINT(\"duk_heap_process_finalize_list: %ld finalizers called\", (long) count));\n#endif\n}\n\n/*\n *  Run an duk_hobject finalizer.  Must never throw an uncaught error\n *  (but may throw caught errors).\n *\n *  There is no return value.  Any return value or error thrown by\n *  the finalizer is ignored (although errors are debug logged).\n *\n *  Notes:\n *\n *    - The finalizer thread 'top' assertions are there because it is\n *      critical that strict stack policy is observed (i.e. no cruft\n *      left on the finalizer stack).\n */\n\nDUK_LOCAL duk_ret_t duk__finalize_helper(duk_hthread *thr, void *udata) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_UNREF(udata);\n\n\tDUK_DDD(DUK_DDDPRINT(\"protected finalization helper running\"));\n\n\t/* [... obj] */\n\n\t/* _Finalizer property is read without checking if the value is\n\t * callable or even exists.  This is intentional, and handled\n\t * by throwing an error which is caught by the safe call wrapper.\n\t *\n\t * XXX: Finalizer lookup should traverse the prototype chain (to allow\n\t * inherited finalizers) but should not invoke accessors or proxy object\n\t * behavior.  At the moment this lookup will invoke proxy behavior, so\n\t * caller must ensure that this function is not called if the target is\n\t * a Proxy.\n\t */\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_FINALIZER);  /* -> [... obj finalizer] */\n\tduk_dup_m2(thr);\n\tduk_push_boolean(thr, DUK_HEAP_HAS_FINALIZER_NORESCUE(thr->heap));\n\tDUK_DDD(DUK_DDDPRINT(\"calling finalizer\"));\n\tduk_call(thr, 2);  /* [ ... obj finalizer obj heapDestruct ]  -> [ ... obj retval ] */\n\tDUK_DDD(DUK_DDDPRINT(\"finalizer returned successfully\"));\n\treturn 0;\n\n\t/* Note: we rely on duk_safe_call() to fix up the stack for the caller,\n\t * so we don't need to pop stuff here.  There is no return value;\n\t * caller determines rescued status based on object refcount.\n\t */\n}\n\nDUK_INTERNAL void duk_heap_run_finalizer(duk_heap *heap, duk_hobject *obj) {\n\tduk_hthread *thr;\n\tduk_ret_t rc;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"running duk_hobject finalizer for object: %p\", (void *) obj));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tthr = heap->heap_thread;\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(heap->heap_thread, 1);\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\t/*\n\t *  Get and call the finalizer.  All of this must be wrapped\n\t *  in a protected call, because even getting the finalizer\n\t *  may trigger an error (getter may throw one, for instance).\n\t */\n\n\t/* ROM objects could inherit a finalizer, but they are never deemed\n\t * unreachable by mark-and-sweep, and their refcount never falls to 0.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\n\t/* Duktape 2.1: finalize_list never contains objects with FINALIZED\n\t * set, so no need to check here.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) obj));\n#if 0\n\tif (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) obj)) {\n\t\tDUK_D(DUK_DPRINT(\"object already finalized, avoid running finalizer twice: %!O\", obj));\n\t\treturn;\n\t}\n#endif\n\tDUK_HEAPHDR_SET_FINALIZED((duk_heaphdr *) obj);  /* ensure never re-entered until rescue cycle complete */\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (DUK_HOBJECT_IS_PROXY(obj)) {\n\t\t/* This may happen if duk_set_finalizer() or Duktape.fin() is\n\t\t * called for a Proxy object.  In such cases the fast finalizer\n\t\t * flag will be set on the Proxy, not the target, and neither\n\t\t * will be finalized.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"object is a Proxy, skip finalizer call\"));\n\t\treturn;\n\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\tduk_push_hobject(thr, obj);  /* this also increases refcount by one */\n\trc = duk_safe_call(thr, duk__finalize_helper, NULL /*udata*/, 0 /*nargs*/, 1 /*nrets*/);  /* -> [... obj retval/error] */\n\tDUK_ASSERT_TOP(thr, entry_top + 2);  /* duk_safe_call discipline */\n\n\tif (rc != DUK_EXEC_SUCCESS) {\n\t\t/* Note: we ask for one return value from duk_safe_call to get this\n\t\t * error debugging here.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"wrapped finalizer call failed for object %p (ignored); error: %!T\",\n\t\t                 (void *) obj, (duk_tval *) duk_get_tval(thr, -1)));\n\t}\n\tduk_pop_2(thr);  /* -> [...] */\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n}\n\n#else  /* DUK_USE_FINALIZER_SUPPORT */\n\n/* nothing */\n\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n/*\n *  String hash computation (interning).\n *\n *  String hashing is performance critical because a string hash is computed\n *  for all new strings which are candidates to be added to the string table.\n *  However, strings actually added to the string table go through a codepoint\n *  length calculation which dominates performance because it goes through\n *  every byte of the input string (but only for strings added).\n *\n *  The string hash algorithm should be fast, but on the other hand provide\n *  good enough hashes to ensure both string table and object property table\n *  hash tables work reasonably well (i.e., there aren't too many collisions\n *  with real world inputs).  Unless the hash is cryptographic, it's always\n *  possible to craft inputs with maximal hash collisions.\n *\n *  NOTE: The hash algorithms must match tools/dukutil.py:duk_heap_hashstring()\n *  for ROM string support!\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_STRHASH_DENSE)\n/* Constants for duk_hashstring(). */\n#define DUK__STRHASH_SHORTSTRING   4096L\n#define DUK__STRHASH_MEDIUMSTRING  (256L * 1024L)\n#define DUK__STRHASH_BLOCKSIZE     256L\n\nDUK_INTERNAL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len) {\n\tduk_uint32_t hash;\n\n\t/* Use Murmurhash2 directly for short strings, and use \"block skipping\"\n\t * for long strings: hash an initial part and then sample the rest of\n\t * the string with reasonably sized chunks.  An initial offset for the\n\t * sampling is computed based on a hash of the initial part of the string;\n\t * this is done to (usually) avoid the case where all long strings have\n\t * certain offset ranges which are never sampled.\n\t *\n\t * Skip should depend on length and bound the total time to roughly\n\t * logarithmic.  With current values:\n\t *\n\t *   1M string => 256 * 241 = 61696 bytes (0.06M) of hashing\n\t *   1G string => 256 * 16321 = 4178176 bytes (3.98M) of hashing\n\t *\n\t * XXX: It would be better to compute the skip offset more \"smoothly\"\n\t * instead of having a few boundary values.\n\t */\n\n\t/* note: mixing len into seed improves hashing when skipping */\n\tduk_uint32_t str_seed = heap->hash_seed ^ ((duk_uint32_t) len);\n\n\tif (len <= DUK__STRHASH_SHORTSTRING) {\n\t\thash = duk_util_hashbytes(str, len, str_seed);\n\t} else {\n\t\tduk_size_t off;\n\t\tduk_size_t skip;\n\n\t\tif (len <= DUK__STRHASH_MEDIUMSTRING) {\n\t\t\tskip = (duk_size_t) (16 * DUK__STRHASH_BLOCKSIZE + DUK__STRHASH_BLOCKSIZE);\n\t\t} else {\n\t\t\tskip = (duk_size_t) (256 * DUK__STRHASH_BLOCKSIZE + DUK__STRHASH_BLOCKSIZE);\n\t\t}\n\n\t\thash = duk_util_hashbytes(str, (duk_size_t) DUK__STRHASH_SHORTSTRING, str_seed);\n\t\toff = DUK__STRHASH_SHORTSTRING + (skip * (hash % 256)) / 256;\n\n\t\t/* XXX: inefficient loop */\n\t\twhile (off < len) {\n\t\t\tduk_size_t left = len - off;\n\t\t\tduk_size_t now = (duk_size_t) (left > DUK__STRHASH_BLOCKSIZE ? DUK__STRHASH_BLOCKSIZE : left);\n\t\t\thash ^= duk_util_hashbytes(str + off, now, str_seed);\n\t\t\toff += skip;\n\t\t}\n\t}\n\n#if defined(DUK_USE_STRHASH16)\n\t/* Truncate to 16 bits here, so that a computed hash can be compared\n\t * against a hash stored in a 16-bit field.\n\t */\n\thash &= 0x0000ffffUL;\n#endif\n\treturn hash;\n}\n#else  /* DUK_USE_STRHASH_DENSE */\nDUK_INTERNAL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len) {\n\tduk_uint32_t hash;\n\tduk_size_t step;\n\tduk_size_t off;\n\n\t/* Slightly modified \"Bernstein hash\" from:\n\t *\n\t *     http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx\n\t *\n\t * Modifications: string skipping and reverse direction similar to\n\t * Lua 5.1.5, and different hash initializer.\n\t *\n\t * The reverse direction ensures last byte it always included in the\n\t * hash which is a good default as changing parts of the string are\n\t * more often in the suffix than in the prefix.\n\t */\n\n\thash = heap->hash_seed ^ ((duk_uint32_t) len);  /* Bernstein hash init value is normally 5381 */\n\tstep = (len >> DUK_USE_STRHASH_SKIP_SHIFT) + 1;\n\tfor (off = len; off >= step; off -= step) {\n\t\tDUK_ASSERT(off >= 1);  /* off >= step, and step >= 1 */\n\t\thash = (hash * 33) + str[off - 1];\n\t}\n\n#if defined(DUK_USE_STRHASH16)\n\t/* Truncate to 16 bits here, so that a computed hash can be compared\n\t * against a hash stored in a 16-bit field.\n\t */\n\thash &= 0x0000ffffUL;\n#endif\n\treturn hash;\n}\n#endif  /* DUK_USE_STRHASH_DENSE */\n\n/* automatic undefs */\n#undef DUK__STRHASH_BLOCKSIZE\n#undef DUK__STRHASH_MEDIUMSTRING\n#undef DUK__STRHASH_SHORTSTRING\n/*\n *  Mark-and-sweep garbage collection.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_LOCAL_DECL void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__mark_heaphdr_nonnull(duk_heap *heap, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__mark_tval(duk_heap *heap, duk_tval *tv);\nDUK_LOCAL_DECL void duk__mark_tvals(duk_heap *heap, duk_tval *tv, duk_idx_t count);\n\n/*\n *  Marking functions for heap types: mark children recursively.\n */\n\nDUK_LOCAL void duk__mark_hstring(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\tDUK_UNREF(h);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_hstring: %p\", (void *) h));\n\tDUK_ASSERT(h);\n\tDUK_HSTRING_ASSERT_VALID(h);\n\n\t/* nothing to process */\n}\n\nDUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {\n\tduk_uint_fast32_t i;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_hobject: %p\", (void *) h));\n\n\tDUK_ASSERT(h);\n\tDUK_HOBJECT_ASSERT_VALID(h);\n\n\t/* XXX: use advancing pointers instead of index macros -> faster and smaller? */\n\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\tduk_hstring *key = DUK_HOBJECT_E_GET_KEY(heap, h, i);\n\t\tif (key == NULL) {\n\t\t\tcontinue;\n\t\t}\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) key);\n\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)) {\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.get);\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.set);\n\t\t} else {\n\t\t\tduk__mark_tval(heap, &DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->v);\n\t\t}\n\t}\n\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(h); i++) {\n\t\tduk__mark_tval(heap, DUK_HOBJECT_A_GET_VALUE_PTR(heap, h, i));\n\t}\n\n\t/* Hash part is a 'weak reference' and does not contribute. */\n\n\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(heap, h));\n\n\t/* Fast path for objects which don't have a subclass struct, or have a\n\t * subclass struct but nothing that needs marking in the subclass struct.\n\t */\n\tif (DUK_HOBJECT_HAS_FASTREFS(h)) {\n\t\tDUK_ASSERT(DUK_HOBJECT_ALLOWS_FASTREFS(h));\n\t\treturn;\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_PROHIBITS_FASTREFS(h));\n\n\t/* XXX: reorg, more common first */\n\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tduk_tval *tv, *tv_end;\n\t\tduk_hobject **fn, **fn_end;\n\n\t\tDUK_HCOMPFUNC_ASSERT_VALID(f);\n\n\t\t/* 'data' is reachable through every compiled function which\n\t\t * contains a reference.\n\t\t */\n\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_DATA(heap, f));\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_LEXENV(heap, f));\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_VARENV(heap, f));\n\n\t\tif (DUK_HCOMPFUNC_GET_DATA(heap, f) != NULL) {\n\t\t\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, f);\n\t\t\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(heap, f);\n\t\t\twhile (tv < tv_end) {\n\t\t\t\tduk__mark_tval(heap, tv);\n\t\t\t\ttv++;\n\t\t\t}\n\n\t\t\tfn = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, f);\n\t\t\tfn_end = DUK_HCOMPFUNC_GET_FUNCS_END(heap, f);\n\t\t\twhile (fn < fn_end) {\n\t\t\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) *fn);\n\t\t\t\tfn++;\n\t\t\t}\n\t\t} else {\n\t\t\t/* May happen in some out-of-memory corner cases. */\n\t\t\tDUK_D(DUK_DPRINT(\"duk_hcompfunc 'data' is NULL, skipping marking\"));\n\t\t}\n\t} else if (DUK_HOBJECT_IS_DECENV(h)) {\n\t\tduk_hdecenv *e = (duk_hdecenv *) h;\n\t\tDUK_HDECENV_ASSERT_VALID(e);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) e->thread);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) e->varmap);\n\t} else if (DUK_HOBJECT_IS_OBJENV(h)) {\n\t\tduk_hobjenv *e = (duk_hobjenv *) h;\n\t\tDUK_HOBJENV_ASSERT_VALID(e);\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) e->target);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\tduk_hbufobj *b = (duk_hbufobj *) h;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(b);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) b->buf);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) b->buf_prop);\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {\n\t\tduk_hboundfunc *f = (duk_hboundfunc *) (void *) h;\n\t\tDUK_HBOUNDFUNC_ASSERT_VALID(f);\n\t\tduk__mark_tval(heap, &f->target);\n\t\tduk__mark_tval(heap, &f->this_binding);\n\t\tduk__mark_tvals(heap, f->args, f->nargs);\n#if defined(DUK_USE_ES6_PROXY)\n\t} else if (DUK_HOBJECT_IS_PROXY(h)) {\n\t\tduk_hproxy *p = (duk_hproxy *) h;\n\t\tDUK_HPROXY_ASSERT_VALID(p);\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) p->target);\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) p->handler);\n#endif  /* DUK_USE_ES6_PROXY */\n\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tduk_activation *act;\n\t\tduk_tval *tv;\n\n\t\tDUK_HTHREAD_ASSERT_VALID(t);\n\n\t\ttv = t->valstack;\n\t\twhile (tv < t->valstack_top) {\n\t\t\tduk__mark_tval(heap, tv);\n\t\t\ttv++;\n\t\t}\n\n\t\tfor (act = t->callstack_curr; act != NULL; act = act->parent) {\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_ACT_GET_FUNC(act));\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) act->var_env);\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) act->lex_env);\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) act->prev_caller);\n#endif\n#if 0  /* nothing now */\n\t\t\tfor (cat = act->cat; cat != NULL; cat = cat->parent) {\n\t\t\t}\n#endif\n\t\t}\n\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) t->resumer);\n\n\t\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) t->builtins[i]);\n\t\t}\n\t} else {\n\t\t/* We may come here if the object should have a FASTREFS flag\n\t\t * but it's missing for some reason.  Assert for never getting\n\t\t * here; however, other than performance, this is harmless.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"missing FASTREFS flag for: %!iO\", h));\n\t\tDUK_ASSERT(0);\n\t}\n}\n\n/* Mark any duk_heaphdr type.  Recursion tracking happens only here. */\nDUK_LOCAL void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_heaphdr %p, type %ld\",\n\t                     (void *) h,\n\t                     (h != NULL ? (long) DUK_HEAPHDR_GET_TYPE(h) : (long) -1)));\n\n\t/* XXX: add non-null variant? */\n\tif (h == NULL) {\n\t\treturn;\n\t}\n\n\tDUK_HEAPHDR_ASSERT_VALID(h);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(h) || DUK_HEAPHDR_HAS_REACHABLE(h));\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\tif (!DUK_HEAPHDR_HAS_READONLY(h)) {\n\t\th->h_assert_refcount++;  /* Comparison refcount: bump even if already reachable. */\n\t}\n#endif\n\tif (DUK_HEAPHDR_HAS_REACHABLE(h)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"already marked reachable, skip\"));\n\t\treturn;\n\t}\n#if defined(DUK_USE_ROM_OBJECTS)\n\t/* READONLY objects always have REACHABLE set, so the check above\n\t * will prevent READONLY objects from being marked here.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(h));\n#endif\n\n\tDUK_HEAPHDR_SET_REACHABLE(h);\n\n\tif (heap->ms_recursion_depth >= DUK_USE_MARK_AND_SWEEP_RECLIMIT) {\n\t\tDUK_D(DUK_DPRINT(\"mark-and-sweep recursion limit reached, marking as temproot: %p\", (void *) h));\n\t\tDUK_HEAP_SET_MARKANDSWEEP_RECLIMIT_REACHED(heap);\n\t\tDUK_HEAPHDR_SET_TEMPROOT(h);\n\t\treturn;\n\t}\n\n\theap->ms_recursion_depth++;\n\tDUK_ASSERT(heap->ms_recursion_depth != 0);  /* Wrap. */\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING:\n\t\tduk__mark_hstring(heap, (duk_hstring *) h);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tduk__mark_hobject(heap, (duk_hobject *) h);\n\t\tbreak;\n\tcase DUK_HTYPE_BUFFER:\n\t\t/* nothing to mark */\n\t\tbreak;\n\tdefault:\n\t\tDUK_D(DUK_DPRINT(\"attempt to mark heaphdr %p with invalid htype %ld\", (void *) h, (long) DUK_HEAPHDR_GET_TYPE(h)));\n\t\tDUK_UNREACHABLE();\n\t}\n\n\tDUK_ASSERT(heap->ms_recursion_depth > 0);\n\theap->ms_recursion_depth--;\n}\n\nDUK_LOCAL void duk__mark_tval(duk_heap *heap, duk_tval *tv) {\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_tval %p\", (void *) tv));\n\tif (tv == NULL) {\n\t\treturn;\n\t}\n\tDUK_TVAL_ASSERT_VALID(tv);\n\tif (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\tduk_heaphdr *h;\n\t\th = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tduk__mark_heaphdr_nonnull(heap, h);\n\t}\n}\n\nDUK_LOCAL void duk__mark_tvals(duk_heap *heap, duk_tval *tv, duk_idx_t count) {\n\tDUK_ASSERT(count == 0 || tv != NULL);\n\n\twhile (count-- > 0) {\n\t\tDUK_TVAL_ASSERT_VALID(tv);\n\t\tif (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\t\tduk_heaphdr *h;\n\t\t\th = DUK_TVAL_GET_HEAPHDR(tv);\n\t\t\tDUK_ASSERT(h != NULL);\n\t\t\tduk__mark_heaphdr_nonnull(heap, h);\n\t\t}\n\t\ttv++;\n\t}\n}\n\n/* Mark any duk_heaphdr type, caller guarantees a non-NULL pointer. */\nDUK_LOCAL void duk__mark_heaphdr_nonnull(duk_heap *heap, duk_heaphdr *h) {\n\t/* For now, just call the generic handler.  Change when call sites\n\t * are changed too.\n\t */\n\tduk__mark_heaphdr(heap, h);\n}\n\n/*\n *  Mark the heap.\n */\n\nDUK_LOCAL void duk__mark_roots_heap(duk_heap *heap) {\n\tduk_small_uint_t i;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_roots_heap: %p\", (void *) heap));\n\n\tduk__mark_heaphdr(heap, (duk_heaphdr *) heap->heap_thread);\n\tduk__mark_heaphdr(heap, (duk_heaphdr *) heap->heap_object);\n\n\tfor (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) {\n\t\tduk_hstring *h = DUK_HEAP_GET_STRING(heap, i);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) h);\n\t}\n\n\tduk__mark_tval(heap, &heap->lj.value1);\n\tduk__mark_tval(heap, &heap->lj.value2);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tfor (i = 0; i < heap->dbg_breakpoint_count; i++) {\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) heap->dbg_breakpoints[i].filename);\n\t}\n#endif\n}\n\n/*\n *  Mark unreachable, finalizable objects.\n *\n *  Such objects will be moved aside and their finalizers run later.  They\n *  have to be treated as reachability roots for their properties etc to\n *  remain allocated.  This marking is only done for unreachable values which\n *  would be swept later.\n *\n *  Objects are first marked FINALIZABLE and only then marked as reachability\n *  roots; otherwise circular references might be handled inconsistently.\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__mark_finalizable(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\tduk_size_t count_finalizable = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_finalizable: %p\", (void *) heap));\n\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\n\thdr = heap->heap_allocated;\n\twhile (hdr != NULL) {\n\t\t/* A finalizer is looked up from the object and up its\n\t\t * prototype chain (which allows inherited finalizers).\n\t\t * The finalizer is checked for using a duk_hobject flag\n\t\t * which is kept in sync with the presence and callability\n\t\t * of a _Finalizer hidden symbol.\n\t\t */\n\n\t\tif (!DUK_HEAPHDR_HAS_REACHABLE(hdr) &&\n\t\t    DUK_HEAPHDR_IS_OBJECT(hdr) &&\n\t\t    !DUK_HEAPHDR_HAS_FINALIZED(hdr) &&\n\t\t    DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) hdr)) {\n\t\t\t/* heaphdr:\n\t\t\t *  - is not reachable\n\t\t\t *  - is an object\n\t\t\t *  - is not a finalized object waiting for rescue/keep decision\n\t\t\t *  - has a finalizer\n\t\t\t */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"unreachable heap object will be \"\n\t\t\t                   \"finalized -> mark as finalizable \"\n\t\t\t                   \"and treat as a reachability root: %p\",\n\t\t\t                   (void *) hdr));\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(hdr));\n\t\t\tDUK_HEAPHDR_SET_FINALIZABLE(hdr);\n\t\t\tcount_finalizable++;\n\t\t}\n\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n\n\tif (count_finalizable == 0) {\n\t\treturn;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"marked %ld heap objects as finalizable, now mark them reachable\",\n\t                   (long) count_finalizable));\n\n\thdr = heap->heap_allocated;\n\twhile (hdr != NULL) {\n\t\tif (DUK_HEAPHDR_HAS_FINALIZABLE(hdr)) {\n\t\t\tduk__mark_heaphdr_nonnull(heap, hdr);\n\t\t}\n\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n\n\t/* Caller will finish the marking process if we hit a recursion limit. */\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Mark objects on finalize_list.\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__mark_finalize_list(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_finalize_list = 0;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_finalize_list: %p\", (void *) heap));\n\n\thdr = heap->finalize_list;\n\twhile (hdr != NULL) {\n\t\tduk__mark_heaphdr_nonnull(heap, hdr);\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n#if defined(DUK_USE_DEBUG)\n\t\tcount_finalize_list++;\n#endif\n\t}\n\n#if defined(DUK_USE_DEBUG)\n\tif (count_finalize_list > 0) {\n\t\tDUK_D(DUK_DPRINT(\"marked %ld objects on the finalize_list as reachable (previous finalizer run skipped)\",\n\t\t                 (long) count_finalize_list));\n\t}\n#endif\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Fallback marking handler if recursion limit is reached.\n *\n *  Iterates 'temproots' until recursion limit is no longer hit.  Temproots\n *  can be in heap_allocated or finalize_list; refzero_list is now always\n *  empty for mark-and-sweep.  A temproot may occur in finalize_list now if\n *  there are objects on the finalize_list and user code creates a reference\n *  from an object in heap_allocated to the object in finalize_list (which is\n *  now allowed), and it happened to coincide with the recursion depth limit.\n *\n *  This is a slow scan, but guarantees that we finish with a bounded C stack.\n *\n *  Note that nodes may have been marked as temproots before this scan begun,\n *  OR they may have been marked during the scan (as we process nodes\n *  recursively also during the scan).  This is intended behavior.\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__handle_temproot(duk_heap *heap, duk_heaphdr *hdr, duk_size_t *count) {\n#else\nDUK_LOCAL void duk__handle_temproot(duk_heap *heap, duk_heaphdr *hdr) {\n#endif\n\tDUK_ASSERT(hdr != NULL);\n\n\tif (!DUK_HEAPHDR_HAS_TEMPROOT(hdr)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"not a temp root: %p\", (void *) hdr));\n\t\treturn;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"found a temp root: %p\", (void *) hdr));\n\tDUK_HEAPHDR_CLEAR_TEMPROOT(hdr);\n\tDUK_HEAPHDR_CLEAR_REACHABLE(hdr);  /* Done so that duk__mark_heaphdr() works correctly. */\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\thdr->h_assert_refcount--;  /* Same node visited twice. */\n#endif\n\tduk__mark_heaphdr_nonnull(heap, hdr);\n\n#if defined(DUK_USE_DEBUG)\n\t(*count)++;\n#endif\n}\n\nDUK_LOCAL void duk__mark_temproots_by_heap_scan(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_temproots_by_heap_scan: %p\", (void *) heap));\n\n\twhile (DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap)) {\n\t\tDUK_DD(DUK_DDPRINT(\"recursion limit reached, doing heap scan to continue from temproots\"));\n\n#if defined(DUK_USE_DEBUG)\n\t\tcount = 0;\n#endif\n\t\tDUK_HEAP_CLEAR_MARKANDSWEEP_RECLIMIT_REACHED(heap);\n\n\t\thdr = heap->heap_allocated;\n\t\twhile (hdr) {\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk__handle_temproot(heap, hdr, &count);\n#else\n\t\t\tduk__handle_temproot(heap, hdr);\n#endif\n\t\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t\t}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\thdr = heap->finalize_list;\n\t\twhile (hdr) {\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk__handle_temproot(heap, hdr, &count);\n#else\n\t\t\tduk__handle_temproot(heap, hdr);\n#endif\n\t\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t\t}\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\t\tDUK_DD(DUK_DDPRINT(\"temproot mark heap scan processed %ld temp roots\", (long) count));\n#endif\n\t}\n}\n\n/*\n *  Finalize refcounts for heap elements just about to be freed.\n *  This must be done for all objects before freeing to avoid any\n *  stale pointer dereferences.\n *\n *  Note that this must deduce the set of objects to be freed\n *  identically to duk__sweep_heap().\n */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_LOCAL void duk__finalize_refcounts(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"duk__finalize_refcounts: heap=%p\", (void *) heap));\n\n\thdr = heap->heap_allocated;\n\twhile (hdr) {\n\t\tif (!DUK_HEAPHDR_HAS_REACHABLE(hdr)) {\n\t\t\t/*\n\t\t\t *  Unreachable object about to be swept.  Finalize target refcounts\n\t\t\t *  (objects which the unreachable object points to) without doing\n\t\t\t *  refzero processing.  Recursive decrefs are also prevented when\n\t\t\t *  refzero processing is disabled.\n\t\t\t *\n\t\t\t *  Value cannot be a finalizable object, as they have been made\n\t\t\t *  temporarily reachable for this round.\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"unreachable object, refcount finalize before sweeping: %p\", (void *) hdr));\n\n\t\t\t/* Finalize using heap->heap_thread; DECREF has a\n\t\t\t * suppress check for mark-and-sweep which is based\n\t\t\t * on heap->ms_running.\n\t\t\t */\n\t\t\tduk_heaphdr_refcount_finalize_norz(heap, hdr);\n\t\t}\n\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/*\n *  Clear (reachable) flags of finalize_list.\n *\n *  We could mostly do in the sweep phase when we move objects from the\n *  heap into the finalize_list.  However, if a finalizer run is skipped\n *  during a mark-and-sweep, the objects on the finalize_list will be marked\n *  reachable during the next mark-and-sweep.  Since they're already on the\n *  finalize_list, no-one will be clearing their REACHABLE flag so we do it\n *  here.  (This now overlaps with the sweep handling in a harmless way.)\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__clear_finalize_list_flags(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__clear_finalize_list_flags: %p\", (void *) heap));\n\n\thdr = heap->finalize_list;\n\twhile (hdr) {\n\t\tDUK_HEAPHDR_CLEAR_REACHABLE(hdr);\n#if defined(DUK_USE_ASSERTIONS)\n\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZABLE(hdr) || \\\n\t\t           (heap->currently_finalizing == hdr));\n#endif\n\t\t/* DUK_HEAPHDR_FLAG_FINALIZED may be set. */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(hdr));\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Sweep stringtable.\n */\n\nDUK_LOCAL void duk__sweep_stringtable(duk_heap *heap, duk_size_t *out_count_keep) {\n\tduk_hstring *h;\n\tduk_hstring *prev;\n\tduk_uint32_t i;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_free = 0;\n#endif\n\tduk_size_t count_keep = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__sweep_stringtable: %p\", (void *) heap));\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tif (heap->strtable16 == NULL) {\n#else\n\tif (heap->strtable == NULL) {\n#endif\n\t\tgoto done;\n\t}\n\n\tfor (i = 0; i < heap->st_size; i++) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\th = DUK_USE_HEAPPTR_DEC16(heap->heap_udata, heap->strtable16[i]);\n#else\n\t\th = heap->strtable[i];\n#endif\n\t\tprev = NULL;\n\t\twhile (h != NULL) {\n\t\t\tduk_hstring *next;\n\t\t\tnext = h->hdr.h_next;\n\n\t\t\tif (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h))\n\t\t\t{\n\t\t\t\tDUK_HEAPHDR_CLEAR_REACHABLE((duk_heaphdr *) h);\n\t\t\t\tcount_keep++;\n\t\t\t\tprev = h;\n\t\t\t} else {\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tcount_free++;\n#endif\n\n\t\t\t\t/* For pinned strings the refcount has been\n\t\t\t\t * bumped.  We could unbump it here before\n\t\t\t\t * freeing, but that's actually not necessary\n\t\t\t\t * except for assertions.\n\t\t\t\t */\n#if 0\n\t\t\t\tif (DUK_HSTRING_HAS_PINNED_LITERAL(h)) {\n\t\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) > 0U);\n\t\t\t\t\tDUK_HSTRING_DECREF_NORZ(heap->heap_thread, h);\n\t\t\t\t\tDUK_HSTRING_CLEAR_PINNED_LITERAL(h);\n\t\t\t\t}\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t\t/* Non-zero refcounts should not happen for unreachable strings,\n\t\t\t\t * because we refcount finalize all unreachable objects which\n\t\t\t\t * should have decreased unreachable string refcounts to zero\n\t\t\t\t * (even for cycles).  However, pinned strings have a +1 bump.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) ==\n\t\t\t\t           DUK_HSTRING_HAS_PINNED_LITERAL(h) ? 1U : 0U);\n#endif\n\n\t\t\t\t/* Deal with weak references first. */\n\t\t\t\tduk_heap_strcache_string_remove(heap, (duk_hstring *) h);\n\n\t\t\t\t/* Remove the string from the string table. */\n\t\t\t\tduk_heap_strtable_unlink_prev(heap, (duk_hstring *) h, (duk_hstring *) prev);\n\n\t\t\t\t/* Free inner references (these exist e.g. when external\n\t\t\t\t * strings are enabled) and the struct itself.\n\t\t\t\t */\n\t\t\t\tduk_free_hstring(heap, (duk_hstring *) h);\n\n\t\t\t\t/* Don't update 'prev'; it should be last string kept. */\n\t\t\t}\n\n\t\t\th = next;\n\t\t}\n\t}\n\n done:\n#if defined(DUK_USE_DEBUG)\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep sweep stringtable: %ld freed, %ld kept\",\n\t                 (long) count_free, (long) count_keep));\n#endif\n\t*out_count_keep = count_keep;\n}\n\n/*\n *  Sweep heap.\n */\n\nDUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_small_uint_t flags, duk_size_t *out_count_keep) {\n\tduk_heaphdr *prev;  /* last element that was left in the heap */\n\tduk_heaphdr *curr;\n\tduk_heaphdr *next;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_free = 0;\n\tduk_size_t count_finalize = 0;\n\tduk_size_t count_rescue = 0;\n#endif\n\tduk_size_t count_keep = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__sweep_heap: %p\", (void *) heap));\n\n\tprev = NULL;\n\tcurr = heap->heap_allocated;\n\theap->heap_allocated = NULL;\n\twhile (curr) {\n\t\t/* Strings and ROM objects are never placed on the heap allocated list. */\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) != DUK_HTYPE_STRING);\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(curr));\n\n\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\n\t\tif (DUK_HEAPHDR_HAS_REACHABLE(curr)) {\n\t\t\t/*\n\t\t\t *  Reachable object:\n\t\t\t *    - If FINALIZABLE -> actually unreachable (but marked\n\t\t\t *      artificially reachable), queue to finalize_list.\n\t\t\t *    - If !FINALIZABLE but FINALIZED -> rescued after\n\t\t\t *      finalizer execution.\n\t\t\t *    - Otherwise just a normal, reachable object.\n\t\t\t *\n\t\t\t *  Objects which are kept are queued to heap_allocated\n\t\t\t *  tail (we're essentially filtering heap_allocated in\n\t\t\t *  practice).\n\t\t\t */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\t\tif (DUK_UNLIKELY(DUK_HEAPHDR_HAS_FINALIZABLE(curr))) {\n\t\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));\n\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable, finalizable --> move to finalize_list: %p\", (void *) curr));\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(curr);  /* Bump refcount so that refzero never occurs when pending a finalizer call. */\n#endif\n\t\t\t\tDUK_HEAP_INSERT_INTO_FINALIZE_LIST(heap, curr);\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tcount_finalize++;\n#endif\n\t\t\t}\n\t\t\telse\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\t\t\t{\n\t\t\t\tif (DUK_UNLIKELY(DUK_HEAPHDR_HAS_FINALIZED(curr))) {\n\t\t\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(curr));\n\t\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);\n\n\t\t\t\t\tif (flags & DUK_MS_FLAG_POSTPONE_RESCUE) {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable, finalized, but postponing rescue decisions --> keep object (with FINALIZED set): %!iO\", curr));\n\t\t\t\t\t\tcount_keep++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable, finalized --> rescued after finalization: %p\", (void *) curr));\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\t\t\t\t\tDUK_HEAPHDR_CLEAR_FINALIZED(curr);\n#endif\n#if defined(DUK_USE_DEBUG)\n\t\t\t\t\t\tcount_rescue++;\n#endif\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable --> keep: %!iO\", curr));\n\t\t\t\t\tcount_keep++;\n\t\t\t\t}\n\n\t\t\t\tif (prev != NULL) {\n\t\t\t\t\tDUK_ASSERT(heap->heap_allocated != NULL);\n\t\t\t\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, curr);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(heap->heap_allocated == NULL);\n\t\t\t\t\theap->heap_allocated = curr;\n\t\t\t\t}\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\t\t\t\tDUK_HEAPHDR_SET_PREV(heap, curr, prev);\n#endif\n\t\t\t\tDUK_HEAPHDR_ASSERT_LINKS(heap, prev);\n\t\t\t\tDUK_HEAPHDR_ASSERT_LINKS(heap, curr);\n\t\t\t\tprev = curr;\n\t\t\t}\n\n\t\t\t/*\n\t\t\t *  Shrink check for value stacks here.  We're inside\n\t\t\t *  ms_prevent_count protection which prevents recursive\n\t\t\t *  mark-and-sweep and refzero finalizers, so there are\n\t\t\t *  no side effects that would affect the heap lists.\n\t\t\t */\n\t\t\tif (DUK_HEAPHDR_IS_OBJECT(curr) && DUK_HOBJECT_IS_THREAD((duk_hobject *) curr)) {\n\t\t\t\tduk_hthread *thr_curr = (duk_hthread *) curr;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"value stack shrink check for thread: %!O\", curr));\n\t\t\t\tduk_valstack_shrink_check_nothrow(thr_curr, flags & DUK_MS_FLAG_EMERGENCY /*snug*/);\n\t\t\t}\n\n\t\t\tDUK_HEAPHDR_CLEAR_REACHABLE(curr);\n\t\t\t/* Keep FINALIZED if set, used if rescue decisions are postponed. */\n\t\t\t/* Keep FINALIZABLE for objects on finalize_list. */\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(curr));\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Unreachable object:\n\t\t\t *    - If FINALIZED, object was finalized but not\n\t\t\t *      rescued.  This doesn't affect freeing.\n\t\t\t *    - Otherwise normal unreachable object.\n\t\t\t *\n\t\t\t *  There's no guard preventing a FINALIZED object\n\t\t\t *  from being freed while finalizers execute: the\n\t\t\t *  artificial finalize_list reachability roots can't\n\t\t\t *  cause an incorrect free decision (but can cause\n\t\t\t *  an incorrect rescue decision).\n\t\t\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t/* Non-zero refcounts should not happen because we refcount\n\t\t\t * finalize all unreachable objects which should cancel out\n\t\t\t * refcounts (even for cycles).\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) == 0);\n#endif\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(curr));\n\n#if defined(DUK_USE_DEBUG)\n\t\t\tif (DUK_HEAPHDR_HAS_FINALIZED(curr)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; unreachable, finalized --> finalized object not rescued: %p\", (void *) curr));\n\t\t\t} else {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; not reachable --> free: %p\", (void *) curr));\n\t\t\t}\n\n#endif\n\n\t\t\t/* Note: object cannot be a finalizable unreachable object, as\n\t\t\t * they have been marked temporarily reachable for this round,\n\t\t\t * and are handled above.\n\t\t\t */\n\n#if defined(DUK_USE_DEBUG)\n\t\t\tcount_free++;\n#endif\n\n\t\t\t/* Weak refs should be handled here, but no weak refs for\n\t\t\t * any non-string objects exist right now.\n\t\t\t */\n\n\t\t\t/* Free object and all auxiliary (non-heap) allocs. */\n\t\t\tduk_heap_free_heaphdr_raw(heap, curr);\n\t\t}\n\n\t\tcurr = next;\n\t}\n\n\tif (prev != NULL) {\n\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, NULL);\n\t}\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, prev);\n\n#if defined(DUK_USE_DEBUG)\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep sweep objects (non-string): %ld freed, %ld kept, %ld rescued, %ld queued for finalization\",\n\t                 (long) count_free, (long) count_keep, (long) count_rescue, (long) count_finalize));\n#endif\n\t*out_count_keep = count_keep;\n}\n\n/*\n *  Litcache helpers.\n */\n\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_LOCAL void duk__wipe_litcache(duk_heap *heap) {\n\tduk_uint_t i;\n\tduk_litcache_entry *e;\n\n\te = heap->litcache;\n\tfor (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) {\n\t\te->addr = NULL;\n\t\t/* e->h does not need to be invalidated: when e->addr is\n\t\t * NULL, e->h is considered garbage.\n\t\t */\n\t\te++;\n\t}\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n\n/*\n *  Object compaction.\n *\n *  Compaction is assumed to never throw an error.\n */\n\nDUK_LOCAL int duk__protected_compact_object(duk_hthread *thr, void *udata) {\n\tduk_hobject *obj;\n\t/* XXX: for threads, compact stacks? */\n\n\tDUK_UNREF(udata);\n\tobj = duk_known_hobject(thr, -1);\n\tduk_hobject_compact_props(thr, obj);\n\treturn 0;\n}\n\n#if defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__compact_object_list(duk_heap *heap, duk_hthread *thr, duk_heaphdr *start, duk_size_t *p_count_check, duk_size_t *p_count_compact, duk_size_t *p_count_bytes_saved) {\n#else\nDUK_LOCAL void duk__compact_object_list(duk_heap *heap, duk_hthread *thr, duk_heaphdr *start) {\n#endif\n\tduk_heaphdr *curr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t old_size, new_size;\n#endif\n\tduk_hobject *obj;\n\n\tDUK_UNREF(heap);\n\n\tcurr = start;\n\twhile (curr) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"mark-and-sweep compact: %p\", (void *) curr));\n\n\t\tif (DUK_HEAPHDR_GET_TYPE(curr) != DUK_HTYPE_OBJECT) {\n\t\t\tgoto next;\n\t\t}\n\t\tobj = (duk_hobject *) curr;\n\n#if defined(DUK_USE_DEBUG)\n\t\told_size = DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_ASIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_HSIZE(obj));\n#endif\n\n\t\tDUK_DD(DUK_DDPRINT(\"compact object: %p\", (void *) obj));\n\t\tduk_push_hobject(thr, obj);\n\t\t/* XXX: disable error handlers for duration of compaction? */\n\t\tduk_safe_call(thr, duk__protected_compact_object, NULL, 1, 0);\n\n#if defined(DUK_USE_DEBUG)\n\t\tnew_size = DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_ASIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_HSIZE(obj));\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\t\t(*p_count_compact)++;\n\t\t(*p_count_bytes_saved) += (duk_size_t) (old_size - new_size);\n#endif\n\n\t next:\n\t\tcurr = DUK_HEAPHDR_GET_NEXT(heap, curr);\n#if defined(DUK_USE_DEBUG)\n\t\t(*p_count_check)++;\n#endif\n\t}\n}\n\nDUK_LOCAL void duk__compact_objects(duk_heap *heap) {\n\t/* XXX: which lists should participate?  to be finalized? */\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_check = 0;\n\tduk_size_t count_compact = 0;\n\tduk_size_t count_bytes_saved = 0;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"duk__compact_objects: %p\", (void *) heap));\n\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\n#if defined(DUK_USE_DEBUG)\n\tduk__compact_object_list(heap, heap->heap_thread, heap->heap_allocated, &count_check, &count_compact, &count_bytes_saved);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__compact_object_list(heap, heap->heap_thread, heap->finalize_list, &count_check, &count_compact, &count_bytes_saved);\n#endif\n#else\n\tduk__compact_object_list(heap, heap->heap_thread, heap->heap_allocated);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__compact_object_list(heap, heap->heap_thread, heap->finalize_list);\n#endif\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always handled to completion inline in DECREF. */\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep compact objects: %ld checked, %ld compaction attempts, %ld bytes saved by compaction\",\n\t                 (long) count_check, (long) count_compact, (long) count_bytes_saved));\n#endif\n}\n\n/*\n *  Assertion helpers.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\ntypedef void (*duk__gc_heaphdr_assert)(duk_heap *heap, duk_heaphdr *h);\ntypedef void (*duk__gc_hstring_assert)(duk_heap *heap, duk_hstring *h);\n\nDUK_LOCAL void duk__assert_walk_list(duk_heap *heap, duk_heaphdr *start, duk__gc_heaphdr_assert func) {\n\tduk_heaphdr *curr;\n\tfor (curr = start; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) {\n\t\tfunc(heap, curr);\n\t}\n}\n\nDUK_LOCAL void duk__assert_walk_strtable(duk_heap *heap, duk__gc_hstring_assert func) {\n\tduk_uint32_t i;\n\n\tfor (i = 0; i < heap->st_size; i++) {\n\t\tduk_hstring *h;\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\th = DUK_USE_HEAPPTR_DEC16(heap->heap_udata, heap->strtable16[i]);\n#else\n\t\th = heap->strtable[i];\n#endif\n\t\twhile (h != NULL) {\n\t\t\tfunc(heap, h);\n\t\t\th = h->hdr.h_next;\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__assert_heaphdr_flags_cb(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(h));\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(h));\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(h));\n\t/* may have FINALIZED */\n}\nDUK_LOCAL void duk__assert_heaphdr_flags(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__assert_heaphdr_flags_cb);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always handled to completion inline in DECREF. */\n#endif\n\t/* XXX: Assertions for finalize_list? */\n}\n\nDUK_LOCAL void duk__assert_validity_cb1(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tDUK_ASSERT(DUK_HEAPHDR_IS_OBJECT(h) || DUK_HEAPHDR_IS_BUFFER(h));\n\tduk_heaphdr_assert_valid_subclassed(h);\n}\nDUK_LOCAL void duk__assert_validity_cb2(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\tDUK_ASSERT(DUK_HEAPHDR_IS_STRING((duk_heaphdr *) h));\n\tduk_heaphdr_assert_valid_subclassed((duk_heaphdr *) h);\n}\nDUK_LOCAL void duk__assert_validity(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__assert_validity_cb1);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__assert_walk_list(heap, heap->finalize_list, duk__assert_validity_cb1);\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__assert_walk_list(heap, heap->refzero_list, duk__assert_validity_cb1);\n#endif\n\tduk__assert_walk_strtable(heap, duk__assert_validity_cb2);\n}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_LOCAL void duk__assert_valid_refcounts_cb(duk_heap *heap, duk_heaphdr *h) {\n\t/* Cannot really assert much w.r.t. refcounts now. */\n\n\tDUK_UNREF(heap);\n\tif (DUK_HEAPHDR_GET_REFCOUNT(h) == 0 &&\n\t    DUK_HEAPHDR_HAS_FINALIZED(h)) {\n\t\t/* An object may be in heap_allocated list with a zero\n\t\t * refcount if it has just been finalized and is waiting\n\t\t * to be collected by the next cycle.\n\t\t * (This doesn't currently happen however.)\n\t\t */\n\t} else if (DUK_HEAPHDR_GET_REFCOUNT(h) == 0) {\n\t\t/* An object may be in heap_allocated list with a zero\n\t\t * refcount also if it is a temporary object created\n\t\t * during debugger paused state.  It will get collected\n\t\t * by mark-and-sweep based on its reachability status\n\t\t * (presumably not reachable because refcount is 0).\n\t\t */\n\t}\n\tDUK_ASSERT_DISABLE(DUK_HEAPHDR_GET_REFCOUNT(h) >= 0);  /* Unsigned. */\n}\nDUK_LOCAL void duk__assert_valid_refcounts(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__assert_valid_refcounts_cb);\n}\n\nDUK_LOCAL void duk__clear_assert_refcounts_cb1(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\th->h_assert_refcount = 0;\n}\nDUK_LOCAL void duk__clear_assert_refcounts_cb2(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\t((duk_heaphdr *) h)->h_assert_refcount = 0;\n}\nDUK_LOCAL void duk__clear_assert_refcounts(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__clear_assert_refcounts_cb1);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__assert_walk_list(heap, heap->finalize_list, duk__clear_assert_refcounts_cb1);\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__assert_walk_list(heap, heap->refzero_list, duk__clear_assert_refcounts_cb1);\n#endif\n\tduk__assert_walk_strtable(heap, duk__clear_assert_refcounts_cb2);\n}\n\nDUK_LOCAL void duk__check_refcount_heaphdr(duk_heaphdr *hdr) {\n\tduk_bool_t count_ok;\n\tduk_size_t expect_refc;\n\n\t/* The refcount check only makes sense for reachable objects on\n\t * heap_allocated or string table, after the sweep phase.  Prior to\n\t * sweep phase refcounts will include references that are not visible\n\t * via reachability roots.\n\t *\n\t * Because we're called after the sweep phase, all heap objects on\n\t * heap_allocated are reachable.  REACHABLE flags have already been\n\t * cleared so we can't check them.\n\t */\n\n\t/* ROM objects have intentionally incorrect refcount (1), but we won't\n\t * check them.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(hdr));\n\n\texpect_refc = hdr->h_assert_refcount;\n\tif (DUK_HEAPHDR_IS_STRING(hdr) && DUK_HSTRING_HAS_PINNED_LITERAL((duk_hstring *) hdr)) {\n\t\texpect_refc++;\n\t}\n\tcount_ok = ((duk_size_t) DUK_HEAPHDR_GET_REFCOUNT(hdr) == expect_refc);\n\tif (!count_ok) {\n\t\tDUK_D(DUK_DPRINT(\"refcount mismatch for: %p: header=%ld counted=%ld --> %!iO\",\n\t\t                 (void *) hdr, (long) DUK_HEAPHDR_GET_REFCOUNT(hdr),\n\t\t                 (long) hdr->h_assert_refcount, hdr));\n\t\tDUK_ASSERT(0);\n\t}\n}\n\nDUK_LOCAL void duk__check_assert_refcounts_cb1(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tduk__check_refcount_heaphdr(h);\n}\nDUK_LOCAL void duk__check_assert_refcounts_cb2(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\tduk__check_refcount_heaphdr((duk_heaphdr *) h);\n}\nDUK_LOCAL void duk__check_assert_refcounts(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__check_assert_refcounts_cb1);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__assert_walk_list(heap, heap->finalize_list, duk__check_assert_refcounts_cb1);\n#endif\n\t/* XXX: Assert anything for refzero_list? */\n\tduk__assert_walk_strtable(heap, duk__check_assert_refcounts_cb2);\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_LOCAL void duk__assert_litcache_nulls(duk_heap *heap) {\n\tduk_uint_t i;\n\tduk_litcache_entry *e;\n\n\te = heap->litcache;\n\tfor (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) {\n\t\t/* Entry addresses were NULLed before mark-and-sweep, check\n\t\t * that they're still NULL afterwards to ensure no pointers\n\t\t * were recorded through any side effects.\n\t\t */\n\t\tDUK_ASSERT(e->addr == NULL);\n\t}\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n#endif  /* DUK_USE_ASSERTIONS */\n\n/*\n *  Stats dump.\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__dump_stats(duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"stats executor: opcodes=%ld, interrupt=%ld, throw=%ld\",\n\t                 (long) heap->stats_exec_opcodes, (long) heap->stats_exec_interrupt,\n\t                 (long) heap->stats_exec_throw));\n\tDUK_D(DUK_DPRINT(\"stats call: all=%ld, tailcall=%ld, ecmatoecma=%ld\",\n\t                 (long) heap->stats_call_all, (long) heap->stats_call_tailcall,\n\t                 (long) heap->stats_call_ecmatoecma));\n\tDUK_D(DUK_DPRINT(\"stats safecall: all=%ld, nothrow=%ld, throw=%ld\",\n\t                 (long) heap->stats_safecall_all, (long) heap->stats_safecall_nothrow,\n\t                 (long) heap->stats_safecall_throw));\n\tDUK_D(DUK_DPRINT(\"stats mark-and-sweep: try_count=%ld, skip_count=%ld, emergency_count=%ld\",\n\t                 (long) heap->stats_ms_try_count, (long) heap->stats_ms_skip_count,\n\t                 (long) heap->stats_ms_emergency_count));\n\tDUK_D(DUK_DPRINT(\"stats stringtable: intern_hit=%ld, intern_miss=%ld, \"\n\t                 \"resize_check=%ld, resize_grow=%ld, resize_shrink=%ld, \"\n\t                 \"litcache_hit=%ld, litcache_miss=%ld, litcache_pin=%ld\",\n\t                 (long) heap->stats_strtab_intern_hit, (long) heap->stats_strtab_intern_miss,\n\t                 (long) heap->stats_strtab_resize_check, (long) heap->stats_strtab_resize_grow,\n\t                 (long) heap->stats_strtab_resize_shrink, (long) heap->stats_strtab_litcache_hit,\n\t                 (long) heap->stats_strtab_litcache_miss, (long) heap->stats_strtab_litcache_pin));\n\tDUK_D(DUK_DPRINT(\"stats object: realloc_props=%ld, abandon_array=%ld\",\n\t                 (long) heap->stats_object_realloc_props, (long) heap->stats_object_abandon_array));\n\tDUK_D(DUK_DPRINT(\"stats getownpropdesc: count=%ld, hit=%ld, miss=%ld\",\n\t                 (long) heap->stats_getownpropdesc_count, (long) heap->stats_getownpropdesc_hit,\n\t                 (long) heap->stats_getownpropdesc_miss));\n\tDUK_D(DUK_DPRINT(\"stats getpropdesc: count=%ld, hit=%ld, miss=%ld\",\n\t                 (long) heap->stats_getpropdesc_count, (long) heap->stats_getpropdesc_hit,\n\t                 (long) heap->stats_getpropdesc_miss));\n\tDUK_D(DUK_DPRINT(\"stats getprop: all=%ld, arrayidx=%ld, bufobjidx=%ld, \"\n\t                 \"bufferidx=%ld, bufferlen=%ld, stringidx=%ld, stringlen=%ld, \"\n\t                 \"proxy=%ld, arguments=%ld\",\n\t                 (long) heap->stats_getprop_all, (long) heap->stats_getprop_arrayidx,\n\t                 (long) heap->stats_getprop_bufobjidx, (long) heap->stats_getprop_bufferidx,\n\t                 (long) heap->stats_getprop_bufferlen, (long) heap->stats_getprop_stringidx,\n\t                 (long) heap->stats_getprop_stringlen, (long) heap->stats_getprop_proxy,\n\t                 (long) heap->stats_getprop_arguments));\n\tDUK_D(DUK_DPRINT(\"stats putprop: all=%ld, arrayidx=%ld, bufobjidx=%ld, \"\n\t                 \"bufferidx=%ld, proxy=%ld\",\n\t                 (long) heap->stats_putprop_all, (long) heap->stats_putprop_arrayidx,\n\t                 (long) heap->stats_putprop_bufobjidx, (long) heap->stats_putprop_bufferidx,\n\t                 (long) heap->stats_putprop_proxy));\n\tDUK_D(DUK_DPRINT(\"stats getvar: all=%ld\",\n\t                 (long) heap->stats_getvar_all));\n\tDUK_D(DUK_DPRINT(\"stats putvar: all=%ld\",\n\t                 (long) heap->stats_putvar_all));\n\tDUK_D(DUK_DPRINT(\"stats envrec: delayedcreate=%ld, create=%ld, newenv=%ld, oldenv=%ld, pushclosure=%ld\",\n\t                 (long) heap->stats_envrec_delayedcreate,\n\t                 (long) heap->stats_envrec_create,\n\t                 (long) heap->stats_envrec_newenv,\n\t                 (long) heap->stats_envrec_oldenv,\n\t                 (long) heap->stats_envrec_pushclosure));\n}\n#endif  /* DUK_USE_DEBUG */\n\n/*\n *  Main mark-and-sweep function.\n *\n *  'flags' represents the features requested by the caller.  The current\n *  heap->ms_base_flags is ORed automatically into the flags; the base flags\n *  mask typically prevents certain mark-and-sweep operation to avoid trouble.\n */\n\nDUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags) {\n\tduk_size_t count_keep_obj;\n\tduk_size_t count_keep_str;\n#if defined(DUK_USE_VOLUNTARY_GC)\n\tduk_size_t tmp;\n#endif\n\n\tDUK_STATS_INC(heap, stats_ms_try_count);\n#if defined(DUK_USE_DEBUG)\n\tif (flags & DUK_MS_FLAG_EMERGENCY) {\n\t\tDUK_STATS_INC(heap, stats_ms_emergency_count);\n\t}\n#endif\n\n\t/* If debugger is paused, garbage collection is disabled by default.\n\t * This is achieved by bumping ms_prevent_count when becoming paused.\n\t */\n\tDUK_ASSERT(!DUK_HEAP_HAS_DEBUGGER_PAUSED(heap) || heap->ms_prevent_count > 0);\n\n\t/* Prevention/recursion check as soon as possible because we may\n\t * be called a number of times when voluntary mark-and-sweep is\n\t * pending.\n\t */\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject recursive mark-and-sweep\"));\n\t\tDUK_STATS_INC(heap, stats_ms_skip_count);\n\t\treturn;\n\t}\n\tDUK_ASSERT(heap->ms_running == 0);  /* ms_prevent_count is bumped when ms_running is set */\n\n\t/* Heap_thread is used during mark-and-sweep for refcount finalization\n\t * (it's also used for finalizer execution once mark-and-sweep is\n\t * complete).  Heap allocation code ensures heap_thread is set and\n\t * properly initialized before setting ms_prevent_count to 0.\n\t */\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(heap->heap_thread->valstack != NULL);\n\n\tDUK_D(DUK_DPRINT(\"garbage collect (mark-and-sweep) starting, requested flags: 0x%08lx, effective flags: 0x%08lx\",\n\t                 (unsigned long) flags, (unsigned long) (flags | heap->ms_base_flags)));\n\n\tflags |= heap->ms_base_flags;\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tif (heap->finalize_list != NULL) {\n\t\tflags |= DUK_MS_FLAG_POSTPONE_RESCUE;\n\t}\n#endif\n\n\t/*\n\t *  Assertions before\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\tDUK_ASSERT(heap->ms_running == 0);\n\tDUK_ASSERT(!DUK_HEAP_HAS_DEBUGGER_PAUSED(heap));\n\tDUK_ASSERT(!DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap));\n\tDUK_ASSERT(heap->ms_recursion_depth == 0);\n\tduk__assert_heaphdr_flags(heap);\n\tduk__assert_validity(heap);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* Note: heap->refzero_free_running may be true; a refcount\n\t * finalizer may trigger a mark-and-sweep.\n\t */\n\tduk__assert_valid_refcounts(heap);\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n#endif  /* DUK_USE_ASSERTIONS */\n\n\t/*\n\t *  Begin\n\t */\n\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\tDUK_ASSERT(heap->ms_running == 0);\n\theap->ms_prevent_count = 1;\n\theap->ms_running = 1;\n\n\t/*\n\t *  Free activation/catcher freelists on every mark-and-sweep for now.\n\t *  This is an initial rough draft; ideally we'd keep count of the\n\t *  freelist size and free only excess entries.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"freeing temporary freelists\"));\n\tduk_heap_free_freelists(heap);\n\n\t/*\n\t *  Mark roots, hoping that recursion limit is not normally hit.\n\t *  If recursion limit is hit, run additional reachability rounds\n\t *  starting from \"temproots\" until marking is complete.\n\t *\n\t *  Marking happens in two phases: first we mark actual reachability\n\t *  roots (and run \"temproots\" to complete the process).  Then we\n\t *  check which objects are unreachable and are finalizable; such\n\t *  objects are marked as FINALIZABLE and marked as reachability\n\t *  (and \"temproots\" is run again to complete the process).\n\t *\n\t *  The heap finalize_list must also be marked as a reachability root.\n\t *  There may be objects on the list from a previous round if the\n\t *  previous run had finalizer skip flag.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__clear_assert_refcounts(heap);\n#endif\n#if defined(DUK_USE_LITCACHE_SIZE)\n\tduk__wipe_litcache(heap);\n#endif\n\tduk__mark_roots_heap(heap);               /* Mark main reachability roots. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);   /* Always handled to completion inline in DECREF. */\n#endif\n\tduk__mark_temproots_by_heap_scan(heap);   /* Temproots. */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__mark_finalizable(heap);              /* Mark finalizable as reachability roots. */\n\tduk__mark_finalize_list(heap);            /* Mark finalizer work list as reachability roots. */\n#endif\n\tduk__mark_temproots_by_heap_scan(heap);   /* Temproots. */\n\n\t/*\n\t *  Sweep garbage and remove marking flags, and move objects with\n\t *  finalizers to the finalizer work list.\n\t *\n\t *  Objects to be swept need to get their refcounts finalized before\n\t *  they are swept.  In other words, their target object refcounts\n\t *  need to be decreased.  This has to be done before freeing any\n\t *  objects to avoid decref'ing dangling pointers (which may happen\n\t *  even without bugs, e.g. with reference loops)\n\t *\n\t *  Because strings don't point to other heap objects, similar\n\t *  finalization is not necessary for strings.\n\t */\n\n\t/* XXX: more emergency behavior, e.g. find smaller hash sizes etc */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__finalize_refcounts(heap);\n#endif\n\tduk__sweep_heap(heap, flags, &count_keep_obj);\n\tduk__sweep_stringtable(heap, &count_keep_str);\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__check_assert_refcounts(heap);\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);   /* Always handled to completion inline in DECREF. */\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__clear_finalize_list_flags(heap);\n#endif\n\n\t/*\n\t *  Object compaction (emergency only).\n\t *\n\t *  Object compaction is a separate step after sweeping, as there is\n\t *  more free memory for it to work with.  Also, currently compaction\n\t *  may insert new objects into the heap allocated list and the string\n\t *  table which we don't want to do during a sweep (the reachability\n\t *  flags of such objects would be incorrect).  The objects inserted\n\t *  are currently:\n\t *\n\t *    - a temporary duk_hbuffer for a new properties allocation\n\t *    - if array part is abandoned, string keys are interned\n\t *\n\t *  The object insertions go to the front of the list, so they do not\n\t *  cause an infinite loop (they are not compacted).\n\t *\n\t *  At present compaction is not allowed when mark-and-sweep runs\n\t *  during error handling because it involves a duk_safe_call()\n\t *  interfering with error state.\n\t */\n\n\tif ((flags & DUK_MS_FLAG_EMERGENCY) &&\n\t    !(flags & DUK_MS_FLAG_NO_OBJECT_COMPACTION)) {\n\t\tif (heap->lj.type != DUK_LJ_TYPE_UNKNOWN) {\n\t\t\tDUK_D(DUK_DPRINT(\"lj.type (%ld) not DUK_LJ_TYPE_UNKNOWN, skip object compaction\", (long) heap->lj.type));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"object compaction\"));\n\t\t\tduk__compact_objects(heap);\n\t\t}\n\t}\n\n\t/*\n\t *  String table resize check.\n\t *\n\t *  This is mainly useful in emergency GC: if the string table load\n\t *  factor is really low for some reason, we can shrink the string\n\t *  table to a smaller size and free some memory in the process.\n\t *  Only execute in emergency GC.  String table has internal flags\n\t *  to protect against recursive resizing if this mark-and-sweep pass\n\t *  was triggered by a string table resize.\n\t */\n\n\tif (flags & DUK_MS_FLAG_EMERGENCY) {\n\t\tDUK_D(DUK_DPRINT(\"stringtable resize check in emergency gc\"));\n\t\tduk_heap_strtable_force_resize(heap);\n\t}\n\n\t/*\n\t *  Finish\n\t */\n\n\tDUK_ASSERT(heap->ms_prevent_count == 1);\n\tDUK_ASSERT(heap->ms_running == 1);\n\theap->ms_prevent_count = 0;\n\theap->ms_running = 0;\n\n\t/*\n\t *  Assertions after\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\tDUK_ASSERT(!DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap));\n\tDUK_ASSERT(heap->ms_recursion_depth == 0);\n\tduk__assert_heaphdr_flags(heap);\n\tduk__assert_validity(heap);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* Note: heap->refzero_free_running may be true; a refcount\n\t * finalizer may trigger a mark-and-sweep.\n\t */\n\tduk__assert_valid_refcounts(heap);\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n#if defined(DUK_USE_LITCACHE_SIZE)\n\tduk__assert_litcache_nulls(heap);\n#endif  /* DUK_USE_LITCACHE_SIZE */\n#endif  /* DUK_USE_ASSERTIONS */\n\n\t/*\n\t *  Reset trigger counter\n\t */\n\n#if defined(DUK_USE_VOLUNTARY_GC)\n\ttmp = (count_keep_obj + count_keep_str) / 256;\n\theap->ms_trigger_counter = (duk_int_t) (\n\t    (tmp * DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT) +\n\t    DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD);\n\tDUK_D(DUK_DPRINT(\"garbage collect (mark-and-sweep) finished: %ld objects kept, %ld strings kept, trigger reset to %ld\",\n\t                 (long) count_keep_obj, (long) count_keep_str, (long) heap->ms_trigger_counter));\n#else\n\tDUK_D(DUK_DPRINT(\"garbage collect (mark-and-sweep) finished: %ld objects kept, %ld strings kept, no voluntary trigger\",\n\t                 (long) count_keep_obj, (long) count_keep_str));\n#endif\n\n\t/*\n\t *  Stats dump\n\t */\n\n#if defined(DUK_USE_DEBUG)\n\tduk__dump_stats(heap);\n#endif\n\n\t/*\n\t *  Finalize objects in the finalization work list.  Finalized\n\t *  objects are queued back to heap_allocated with FINALIZED set.\n\t *\n\t *  Since finalizers may cause arbitrary side effects, they are\n\t *  prevented e.g. during string table and object property allocation\n\t *  resizing using heap->pf_prevent_count.  In this case the objects\n\t *  remain in the finalization work list after mark-and-sweep exits\n\t *  and they may be finalized on the next pass or any DECREF checking\n\t *  for finalize_list.\n\t *\n\t *  As of Duktape 2.1 finalization happens outside mark-and-sweep\n\t *  protection.  Mark-and-sweep is allowed while the finalize_list\n\t *  is being processed, but no rescue decisions are done while the\n\t *  process is on-going.  This avoids incorrect rescue decisions\n\t *  if an object is considered reachable (and thus rescued) because\n\t *  of a reference via finalize_list (which is considered a reachability\n\t *  root).  When finalize_list is being processed, reachable objects\n\t *  with FINALIZED set will just keep their FINALIZED flag for later\n\t *  mark-and-sweep processing.\n\t *\n\t *  This could also be handled (a bit better) by having a more refined\n\t *  notion of reachability for rescue/free decisions.\n\t *\n\t *  XXX: avoid finalizer execution when doing emergency GC?\n\t */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t/* Attempt to process finalize_list, pf_prevent_count check\n\t * is inside the target.\n\t */\n\tduk_heap_process_finalize_list(heap);\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n}\n/*\n *  Memory allocation handling.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Voluntary GC check\n */\n\n#if defined(DUK_USE_VOLUNTARY_GC)\nDUK_LOCAL DUK_INLINE void duk__check_voluntary_gc(duk_heap *heap) {\n\tif (DUK_UNLIKELY(--(heap)->ms_trigger_counter < 0)) {\n#if defined(DUK_USE_DEBUG)\n\t\tif (heap->ms_prevent_count == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"triggering voluntary mark-and-sweep\"));\n\t\t} else {\n\t\t\tDUK_DD(DUK_DDPRINT(\"gc blocked -> skip voluntary mark-and-sweep now\"));\n\t\t}\n#endif\n\n\t\t/* Prevention checks in the call target handle cases where\n\t\t * voluntary GC is not allowed.  The voluntary GC trigger\n\t\t * counter is only rewritten if mark-and-sweep actually runs.\n\t\t */\n\t\tduk_heap_mark_and_sweep(heap, DUK_MS_FLAG_VOLUNTARY /*flags*/);\n\t}\n}\n#define DUK__VOLUNTARY_PERIODIC_GC(heap)  do { duk__check_voluntary_gc((heap)); } while (0)\n#else\n#define DUK__VOLUNTARY_PERIODIC_GC(heap)  /* no voluntary gc */\n#endif  /* DUK_USE_VOLUNTARY_GC */\n\n/*\n *  Allocate memory with garbage collection\n */\n\nDUK_INTERNAL void *duk_heap_mem_alloc(duk_heap *heap, duk_size_t size) {\n\tvoid *res;\n\tduk_small_int_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT_DISABLE(size >= 0);\n\n\t/*\n\t *  Voluntary periodic GC (if enabled)\n\t */\n\n\tDUK__VOLUNTARY_PERIODIC_GC(heap);\n\n\t/*\n\t *  First attempt\n\t */\n\n#if defined(DUK_USE_GC_TORTURE)\n\t/* Simulate alloc failure on every alloc, except when mark-and-sweep\n\t * is running.\n\t */\n\tif (heap->ms_prevent_count == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"gc torture enabled, pretend that first alloc attempt fails\"));\n\t\tres = NULL;\n\t\tDUK_UNREF(res);\n\t\tgoto skip_attempt;\n\t}\n#endif\n\tres = heap->alloc_func(heap->heap_udata, size);\n\tif (DUK_LIKELY(res || size == 0)) {\n\t\t/* For zero size allocations NULL is allowed. */\n\t\treturn res;\n\t}\n#if defined(DUK_USE_GC_TORTURE)\n skip_attempt:\n#endif\n\n\tDUK_D(DUK_DPRINT(\"first alloc attempt failed, attempt to gc and retry\"));\n\n#if 0\n\t/*\n\t *  Avoid a GC if GC is already running.  This can happen at a late\n\t *  stage in a GC when we try to e.g. resize the stringtable\n\t *  or compact objects.\n\t *\n\t *  NOTE: explicit handling isn't actually be needed: if the GC is\n\t *  not allowed, duk_heap_mark_and_sweep() will reject it for every\n\t *  attempt in the loop below, resulting in a NULL same as here.\n\t */\n\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_alloc() failed, gc in progress (gc skipped), alloc size %ld\", (long) size));\n\t\treturn NULL;\n\t}\n#endif\n\n\t/*\n\t *  Retry with several GC attempts.  Initial attempts are made without\n\t *  emergency mode; later attempts use emergency mode which minimizes\n\t *  memory allocations forcibly.\n\t */\n\n\tfor (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) {\n\t\tduk_small_uint_t flags;\n\n\t\tflags = 0;\n\t\tif (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) {\n\t\t\tflags |= DUK_MS_FLAG_EMERGENCY;\n\t\t}\n\n\t\tduk_heap_mark_and_sweep(heap, flags);\n\n\t\tres = heap->alloc_func(heap->heap_udata, size);\n\t\tif (res) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_alloc() succeeded after gc (pass %ld), alloc size %ld\",\n\t\t\t                 (long) (i + 1), (long) size));\n\t\t\treturn res;\n\t\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"duk_heap_mem_alloc() failed even after gc, alloc size %ld\", (long) size));\n\treturn NULL;\n}\n\nDUK_INTERNAL void *duk_heap_mem_alloc_zeroed(duk_heap *heap, duk_size_t size) {\n\tvoid *res;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT_DISABLE(size >= 0);\n\n\tres = DUK_ALLOC(heap, size);\n\tif (DUK_LIKELY(res != NULL)) {\n\t\tduk_memzero(res, size);\n\t}\n\treturn res;\n}\n\nDUK_INTERNAL void *duk_heap_mem_alloc_checked(duk_hthread *thr, duk_size_t size) {\n\tvoid *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tres = duk_heap_mem_alloc(thr->heap, size);\n\tif (DUK_LIKELY(res != NULL || size == 0)) {\n\t\treturn res;\n\t}\n\tDUK_ERROR_ALLOC_FAILED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_INTERNAL void *duk_heap_mem_alloc_checked_zeroed(duk_hthread *thr, duk_size_t size) {\n\tvoid *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tres = duk_heap_mem_alloc_zeroed(thr->heap, size);\n\tif (DUK_LIKELY(res != NULL || size == 0)) {\n\t\treturn res;\n\t}\n\tDUK_ERROR_ALLOC_FAILED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Reallocate memory with garbage collection\n */\n\nDUK_INTERNAL void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, duk_size_t newsize) {\n\tvoid *res;\n\tduk_small_int_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\t/* ptr may be NULL */\n\tDUK_ASSERT_DISABLE(newsize >= 0);\n\n\t/*\n\t *  Voluntary periodic GC (if enabled)\n\t */\n\n\tDUK__VOLUNTARY_PERIODIC_GC(heap);\n\n\t/*\n\t *  First attempt\n\t */\n\n#if defined(DUK_USE_GC_TORTURE)\n\t/* Simulate alloc failure on every realloc, except when mark-and-sweep\n\t * is running.\n\t */\n\tif (heap->ms_prevent_count == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"gc torture enabled, pretend that first realloc attempt fails\"));\n\t\tres = NULL;\n\t\tDUK_UNREF(res);\n\t\tgoto skip_attempt;\n\t}\n#endif\n\tres = heap->realloc_func(heap->heap_udata, ptr, newsize);\n\tif (DUK_LIKELY(res || newsize == 0)) {\n\t\t/* For zero size allocations NULL is allowed. */\n\t\treturn res;\n\t}\n#if defined(DUK_USE_GC_TORTURE)\n skip_attempt:\n#endif\n\n\tDUK_D(DUK_DPRINT(\"first realloc attempt failed, attempt to gc and retry\"));\n\n#if 0\n\t/*\n\t *  Avoid a GC if GC is already running.  See duk_heap_mem_alloc().\n\t */\n\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc() failed, gc in progress (gc skipped), alloc size %ld\", (long) newsize));\n\t\treturn NULL;\n\t}\n#endif\n\n\t/*\n\t *  Retry with several GC attempts.  Initial attempts are made without\n\t *  emergency mode; later attempts use emergency mode which minimizes\n\t *  memory allocations forcibly.\n\t */\n\n\tfor (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) {\n\t\tduk_small_uint_t flags;\n\n\t\tflags = 0;\n\t\tif (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) {\n\t\t\tflags |= DUK_MS_FLAG_EMERGENCY;\n\t\t}\n\n\t\tduk_heap_mark_and_sweep(heap, flags);\n\n\t\tres = heap->realloc_func(heap->heap_udata, ptr, newsize);\n\t\tif (res || newsize == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc() succeeded after gc (pass %ld), alloc size %ld\",\n\t\t\t                 (long) (i + 1), (long) newsize));\n\t\t\treturn res;\n\t\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc() failed even after gc, alloc size %ld\", (long) newsize));\n\treturn NULL;\n}\n\n/*\n *  Reallocate memory with garbage collection, using a callback to provide\n *  the current allocated pointer.  This variant is used when a mark-and-sweep\n *  (e.g. finalizers) might change the original pointer.\n */\n\nDUK_INTERNAL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize) {\n\tvoid *res;\n\tduk_small_int_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT_DISABLE(newsize >= 0);\n\n\t/*\n\t *  Voluntary periodic GC (if enabled)\n\t */\n\n\tDUK__VOLUNTARY_PERIODIC_GC(heap);\n\n\t/*\n\t *  First attempt\n\t */\n\n#if defined(DUK_USE_GC_TORTURE)\n\t/* Simulate alloc failure on every realloc, except when mark-and-sweep\n\t * is running.\n\t */\n\tif (heap->ms_prevent_count == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"gc torture enabled, pretend that first indirect realloc attempt fails\"));\n\t\tres = NULL;\n\t\tDUK_UNREF(res);\n\t\tgoto skip_attempt;\n\t}\n#endif\n\tres = heap->realloc_func(heap->heap_udata, cb(heap, ud), newsize);\n\tif (DUK_LIKELY(res || newsize == 0)) {\n\t\t/* For zero size allocations NULL is allowed. */\n\t\treturn res;\n\t}\n#if defined(DUK_USE_GC_TORTURE)\n skip_attempt:\n#endif\n\n\tDUK_D(DUK_DPRINT(\"first indirect realloc attempt failed, attempt to gc and retry\"));\n\n#if 0\n\t/*\n\t *  Avoid a GC if GC is already running.  See duk_heap_mem_alloc().\n\t */\n\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc_indirect() failed, gc in progress (gc skipped), alloc size %ld\", (long) newsize));\n\t\treturn NULL;\n\t}\n#endif\n\n\t/*\n\t *  Retry with several GC attempts.  Initial attempts are made without\n\t *  emergency mode; later attempts use emergency mode which minimizes\n\t *  memory allocations forcibly.\n\t */\n\n\tfor (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) {\n\t\tduk_small_uint_t flags;\n\n#if defined(DUK_USE_DEBUG)\n\t\tvoid *ptr_pre;\n\t\tvoid *ptr_post;\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\t\tptr_pre = cb(heap, ud);\n#endif\n\t\tflags = 0;\n\t\tif (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) {\n\t\t\tflags |= DUK_MS_FLAG_EMERGENCY;\n\t\t}\n\n\t\tduk_heap_mark_and_sweep(heap, flags);\n#if defined(DUK_USE_DEBUG)\n\t\tptr_post = cb(heap, ud);\n\t\tif (ptr_pre != ptr_post) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"realloc base pointer changed by mark-and-sweep: %p -> %p\",\n\t\t\t                   (void *) ptr_pre, (void *) ptr_post));\n\t\t}\n#endif\n\n\t\t/* Note: key issue here is to re-lookup the base pointer on every attempt.\n\t\t * The pointer being reallocated may change after every mark-and-sweep.\n\t\t */\n\n\t\tres = heap->realloc_func(heap->heap_udata, cb(heap, ud), newsize);\n\t\tif (res || newsize == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc_indirect() succeeded after gc (pass %ld), alloc size %ld\",\n\t\t\t                 (long) (i + 1), (long) newsize));\n\t\t\treturn res;\n\t\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc_indirect() failed even after gc, alloc size %ld\", (long) newsize));\n\treturn NULL;\n}\n\n/*\n *  Free memory\n */\n\nDUK_INTERNAL void duk_heap_mem_free(duk_heap *heap, void *ptr) {\n\tDUK_ASSERT(heap != NULL);\n\t/* ptr may be NULL */\n\n\t/* Must behave like a no-op with NULL and any pointer returned from\n\t * malloc/realloc with zero size.\n\t */\n\theap->free_func(heap->heap_udata, ptr);\n\n\t/* Never perform a GC (even voluntary) in a memory free, otherwise\n\t * all call sites doing frees would need to deal with the side effects.\n\t * No need to update voluntary GC counter either.\n\t */\n}\n\n/* automatic undefs */\n#undef DUK__VOLUNTARY_PERIODIC_GC\n/*\n *  Support functions for duk_heap.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphdr *hdr) {\n\tduk_heaphdr *root;\n\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) != DUK_HTYPE_STRING);\n\n\troot = heap->heap_allocated;\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tif (root != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, root) == NULL);\n\t\tDUK_HEAPHDR_SET_PREV(heap, root, hdr);\n\t}\n\tDUK_HEAPHDR_SET_PREV(heap, hdr, NULL);\n#endif\n\tDUK_HEAPHDR_SET_NEXT(heap, hdr, root);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, hdr);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, root);\n\theap->heap_allocated = hdr;\n}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL void duk_heap_remove_from_heap_allocated(duk_heap *heap, duk_heaphdr *hdr) {\n\tduk_heaphdr *prev;\n\tduk_heaphdr *next;\n\n\t/* Strings are in string table. */\n\tDUK_ASSERT(hdr != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) != DUK_HTYPE_STRING);\n\n\t/* Target 'hdr' must be in heap_allocated (not e.g. finalize_list).\n\t * If not, heap lists will become corrupted so assert early for it.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\t{\n\t\tduk_heaphdr *tmp;\n\t\tfor (tmp = heap->heap_allocated; tmp != NULL; tmp = DUK_HEAPHDR_GET_NEXT(heap, tmp)) {\n\t\t\tif (tmp == hdr) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(tmp == hdr);\n\t}\n#endif\n\n\t/* Read/write only once to minimize pointer compression calls. */\n\tprev = DUK_HEAPHDR_GET_PREV(heap, hdr);\n\tnext = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\n\tif (prev != NULL) {\n\t\tDUK_ASSERT(heap->heap_allocated != hdr);\n\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, next);\n\t} else {\n\t\tDUK_ASSERT(heap->heap_allocated == hdr);\n\t\theap->heap_allocated = next;\n\t}\n\tif (next != NULL) {\n\t\tDUK_HEAPHDR_SET_PREV(heap, next, prev);\n\t} else {\n\t\t;\n\t}\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL void duk_heap_insert_into_finalize_list(duk_heap *heap, duk_heaphdr *hdr) {\n\tduk_heaphdr *root;\n\n\troot = heap->finalize_list;\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tDUK_HEAPHDR_SET_PREV(heap, hdr, NULL);\n\tif (root != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, root) == NULL);\n\t\tDUK_HEAPHDR_SET_PREV(heap, root, hdr);\n\t}\n#endif\n\tDUK_HEAPHDR_SET_NEXT(heap, hdr, root);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, hdr);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, root);\n\theap->finalize_list = hdr;\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL void duk_heap_remove_from_finalize_list(duk_heap *heap, duk_heaphdr *hdr) {\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tduk_heaphdr *next;\n\tduk_heaphdr *prev;\n\n\tnext = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\tprev = DUK_HEAPHDR_GET_PREV(heap, hdr);\n\tif (next != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, next) == hdr);\n\t\tDUK_HEAPHDR_SET_PREV(heap, next, prev);\n\t}\n\tif (prev == NULL) {\n\t\tDUK_ASSERT(hdr == heap->finalize_list);\n\t\theap->finalize_list = next;\n\t} else {\n\t\tDUK_ASSERT(hdr != heap->finalize_list);\n\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, next);\n\t}\n#else\n\tduk_heaphdr *next;\n\tduk_heaphdr *curr;\n\n\t/* Random removal is expensive: we need to locate the previous element\n\t * because we don't have a 'prev' pointer.\n\t */\n\tcurr = heap->finalize_list;\n\tif (curr == hdr) {\n\t\theap->finalize_list = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t} else {\n\t\tDUK_ASSERT(hdr != heap->finalize_list);\n\t\tfor (;;) {\n\t\t\tDUK_ASSERT(curr != NULL);  /* Caller responsibility. */\n\n\t\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\t\tif (next == hdr) {\n\t\t\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t\t\t\tDUK_HEAPHDR_SET_NEXT(heap, curr, next);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n#endif\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL duk_bool_t duk_heap_in_heap_allocated(duk_heap *heap, duk_heaphdr *ptr) {\n\tduk_heaphdr *curr;\n\tDUK_ASSERT(heap != NULL);\n\n\tfor (curr = heap->heap_allocated; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) {\n\t\tif (curr == ptr) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\nDUK_INTERNAL void duk_heap_switch_thread(duk_heap *heap, duk_hthread *new_thr) {\n\tduk_hthread *curr_thr;\n\n\tDUK_ASSERT(heap != NULL);\n\n\tif (new_thr != NULL) {\n\t\tcurr_thr = heap->curr_thread;\n\t\tif (curr_thr == NULL) {\n\t\t\t/* For initial entry use default value; zero forces an\n\t\t\t * interrupt before executing the first insturction.\n\t\t\t */\n\t\t\tDUK_DD(DUK_DDPRINT(\"switch thread, initial entry, init default interrupt counter\"));\n\t\t\tnew_thr->interrupt_counter = 0;\n\t\t\tnew_thr->interrupt_init = 0;\n\t\t} else {\n\t\t\t/* Copy interrupt counter/init value state to new thread (if any).\n\t\t\t * It's OK for new_thr to be the same as curr_thr.\n\t\t\t */\n#if defined(DUK_USE_DEBUG)\n\t\t\tif (new_thr != curr_thr) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"switch thread, not initial entry, copy interrupt counter\"));\n\t\t\t}\n#endif\n\t\t\tnew_thr->interrupt_counter = curr_thr->interrupt_counter;\n\t\t\tnew_thr->interrupt_init = curr_thr->interrupt_init;\n\t\t}\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"switch thread, new thread is NULL, no interrupt counter changes\"));\n\t}\n\n\theap->curr_thread = new_thr;  /* may be NULL */\n}\n#endif  /* DUK_USE_INTERRUPT_COUNTER */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL void duk_heap_assert_valid(duk_heap *heap) {\n\tDUK_ASSERT(heap != NULL);\n}\n#endif\n/*\n *  Reference counting implementation.\n *\n *  INCREF/DECREF, finalization and freeing of objects whose refcount reaches\n *  zero (refzero).  These operations are very performance sensitive, so\n *  various small tricks are used in an attempt to maximize speed.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\n#if !defined(DUK_USE_DOUBLE_LINKED_HEAP)\n#error internal error, reference counting requires a double linked heap\n#endif\n\n/*\n *  Heap object refcount finalization.\n *\n *  When an object is about to be freed, all other objects it refers to must\n *  be decref'd.  Refcount finalization does NOT free the object or its inner\n *  allocations (mark-and-sweep shares these helpers), it just manipulates\n *  the refcounts.\n *\n *  Note that any of the DECREFs may cause a refcount to drop to zero.  If so,\n *  the object won't be refzero processed inline, but will just be queued to\n *  refzero_list and processed by an earlier caller working on refzero_list,\n *  eliminating C recursion from even long refzero cascades.  If refzero\n *  finalization is triggered by mark-and-sweep, refzero conditions are ignored\n *  (objects are not even queued to refzero_list) because mark-and-sweep deals\n *  with them; refcounts are still updated so that they remain in sync with\n *  actual references.\n */\n\nDUK_LOCAL void duk__decref_tvals_norz(duk_hthread *thr, duk_tval *tv, duk_idx_t count) {\n\tDUK_ASSERT(count == 0 || tv != NULL);\n\n\twhile (count-- > 0) {\n\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t\ttv++;\n\t}\n}\n\nDUK_INTERNAL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject *h) {\n\tduk_hthread *thr;\n\tduk_uint_fast32_t i;\n\tduk_uint_fast32_t n;\n\tduk_propvalue *p_val;\n\tduk_tval *p_tv;\n\tduk_hstring **p_key;\n\tduk_uint8_t *p_flag;\n\tduk_hobject *h_proto;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(h);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h) == DUK_HTYPE_OBJECT);\n\n\tthr = heap->heap_thread;\n\tDUK_ASSERT(thr != NULL);\n\n\tp_key = DUK_HOBJECT_E_GET_KEY_BASE(heap, h);\n\tp_val = DUK_HOBJECT_E_GET_VALUE_BASE(heap, h);\n\tp_flag = DUK_HOBJECT_E_GET_FLAGS_BASE(heap, h);\n\tn = DUK_HOBJECT_GET_ENEXT(h);\n\twhile (n-- > 0) {\n\t\tduk_hstring *key;\n\n\t\tkey = p_key[n];\n\t\tif (DUK_UNLIKELY(key == NULL)) {\n\t\t\tcontinue;\n\t\t}\n\t\tDUK_HSTRING_DECREF_NORZ(thr, key);\n\t\tif (DUK_UNLIKELY(p_flag[n] & DUK_PROPDESC_FLAG_ACCESSOR)) {\n\t\t\tduk_hobject *h_getset;\n\t\t\th_getset = p_val[n].a.get;\n\t\t\tDUK_ASSERT(h_getset == NULL || DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_getset));\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h_getset);\n\t\t\th_getset = p_val[n].a.set;\n\t\t\tDUK_ASSERT(h_getset == NULL || DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_getset));\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h_getset);\n\t\t} else {\n\t\t\tduk_tval *tv_val;\n\t\t\ttv_val = &p_val[n].v;\n\t\t\tDUK_TVAL_DECREF_NORZ(thr, tv_val);\n\t\t}\n\t}\n\n\tp_tv = DUK_HOBJECT_A_GET_BASE(heap, h);\n\tn = DUK_HOBJECT_GET_ASIZE(h);\n\twhile (n-- > 0) {\n\t\tduk_tval *tv_val;\n\t\ttv_val = p_tv + n;\n\t\tDUK_TVAL_DECREF_NORZ(thr, tv_val);\n\t}\n\n\t/* Hash part is a 'weak reference' and doesn't contribute to refcounts. */\n\n\th_proto = (duk_hobject *) DUK_HOBJECT_GET_PROTOTYPE(heap, h);\n\tDUK_ASSERT(h_proto == NULL || DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_proto));\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h_proto);\n\n\t/* XXX: Object subclass tests are quite awkward at present, ideally\n\t * we should be able to switch-case here with a dense index (subtype\n\t * number or something).  For now, fast path plain objects and arrays\n\t * and bit test the rest individually.\n\t */\n\n\tif (DUK_HOBJECT_HAS_FASTREFS(h)) {\n\t\t/* Plain object or array, nothing more to do.  While a\n\t\t * duk_harray has additional fields, none of them need\n\t\t * DECREF updates.\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_ALLOWS_FASTREFS(h));\n\t\treturn;\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_PROHIBITS_FASTREFS(h));\n\n\t/* Slow path: special object, start bit checks from most likely. */\n\n\t/* XXX: reorg, more common first */\n\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tduk_tval *tv, *tv_end;\n\t\tduk_hobject **funcs, **funcs_end;\n\n\t\tDUK_HCOMPFUNC_ASSERT_VALID(f);\n\n\t\tif (DUK_LIKELY(DUK_HCOMPFUNC_GET_DATA(heap, f) != NULL)) {\n\t\t\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, f);\n\t\t\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(heap, f);\n\t\t\twhile (tv < tv_end) {\n\t\t\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t\t\t\ttv++;\n\t\t\t}\n\n\t\t\tfuncs = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, f);\n\t\t\tfuncs_end = DUK_HCOMPFUNC_GET_FUNCS_END(heap, f);\n\t\t\twhile (funcs < funcs_end) {\n\t\t\t\tduk_hobject *h_func;\n\t\t\t\th_func = *funcs;\n\t\t\t\tDUK_ASSERT(h_func != NULL);\n\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_func));\n\t\t\t\tDUK_HCOMPFUNC_DECREF_NORZ(thr, (duk_hcompfunc *) h_func);\n\t\t\t\tfuncs++;\n\t\t\t}\n\t\t} else {\n\t\t\t/* May happen in some out-of-memory corner cases. */\n\t\t\tDUK_D(DUK_DPRINT(\"duk_hcompfunc 'data' is NULL, skipping decref\"));\n\t\t}\n\n\t\tDUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_heaphdr *) DUK_HCOMPFUNC_GET_LEXENV(heap, f));\n\t\tDUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_heaphdr *) DUK_HCOMPFUNC_GET_VARENV(heap, f));\n\t\tDUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(heap, f));\n\t} else if (DUK_HOBJECT_IS_DECENV(h)) {\n\t\tduk_hdecenv *e = (duk_hdecenv *) h;\n\t\tDUK_HDECENV_ASSERT_VALID(e);\n\t\tDUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr, e->thread);\n\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, e->varmap);\n\t} else if (DUK_HOBJECT_IS_OBJENV(h)) {\n\t\tduk_hobjenv *e = (duk_hobjenv *) h;\n\t\tDUK_HOBJENV_ASSERT_VALID(e);\n\t\tDUK_ASSERT(e->target != NULL);  /* Required for object environments. */\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, e->target);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\tduk_hbufobj *b = (duk_hbufobj *) h;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(b);\n\t\tDUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr, (duk_hbuffer *) b->buf);\n\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) b->buf_prop);\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {\n\t\tduk_hboundfunc *f = (duk_hboundfunc *) (void *) h;\n\t\tDUK_HBOUNDFUNC_ASSERT_VALID(f);\n\t\tDUK_TVAL_DECREF_NORZ(thr, &f->target);\n\t\tDUK_TVAL_DECREF_NORZ(thr, &f->this_binding);\n\t\tduk__decref_tvals_norz(thr, f->args, f->nargs);\n#if defined(DUK_USE_ES6_PROXY)\n\t} else if (DUK_HOBJECT_IS_PROXY(h)) {\n\t\tduk_hproxy *p = (duk_hproxy *) h;\n\t\tDUK_HPROXY_ASSERT_VALID(p);\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, p->target);\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, p->handler);\n#endif  /* DUK_USE_ES6_PROXY */\n\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tduk_activation *act;\n\t\tduk_tval *tv;\n\n\t\tDUK_HTHREAD_ASSERT_VALID(t);\n\n\t\ttv = t->valstack;\n\t\twhile (tv < t->valstack_top) {\n\t\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t\t\ttv++;\n\t\t}\n\n\t\tfor (act = t->callstack_curr; act != NULL; act = act->parent) {\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) DUK_ACT_GET_FUNC(act));\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->var_env);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->lex_env);\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->prev_caller);\n#endif\n#if 0  /* nothing now */\n\t\t\tfor (cat = act->cat; cat != NULL; cat = cat->parent) {\n\t\t\t}\n#endif\n\t\t}\n\n\n\t\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) t->builtins[i]);\n\t\t}\n\n\t\tDUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr, (duk_hthread *) t->resumer);\n\t} else {\n\t\t/* We may come here if the object should have a FASTREFS flag\n\t\t * but it's missing for some reason.  Assert for never getting\n\t\t * here; however, other than performance, this is harmless.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"missing FASTREFS flag for: %!iO\", h));\n\t\tDUK_ASSERT(0);\n\t}\n}\n\nDUK_INTERNAL void duk_heaphdr_refcount_finalize_norz(duk_heap *heap, duk_heaphdr *hdr) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(hdr != NULL);\n\n\tif (DUK_HEAPHDR_IS_OBJECT(hdr)) {\n\t\tduk_hobject_refcount_finalize_norz(heap, (duk_hobject *) hdr);\n\t}\n\t/* DUK_HTYPE_BUFFER: nothing to finalize */\n\t/* DUK_HTYPE_STRING: nothing to finalize */\n}\n\n/*\n *  Refzero processing for duk_hobject: queue a refzero'ed object to either\n *  finalize_list or refzero_list and process the relevent list(s) if\n *  necessary.\n *\n *  Refzero_list is single linked, with only 'prev' pointers set and valid.\n *  All 'next' pointers are intentionally left as garbage.  This doesn't\n *  matter because refzero_list is processed to completion before any other\n *  code (like mark-and-sweep) might walk the list.\n *\n *  In more detail:\n *\n *  - On first insert refzero_list is NULL and the new object becomes the\n *    first and only element on the list; duk__refcount_free_pending() is\n *    called and it starts processing the list from the initial element,\n *    i.e. the list tail.\n *\n *  - As each object is refcount finalized, new objects may be queued to\n *    refzero_list head.  Their 'next' pointers are left as garbage, but\n *    'prev' points are set correctly, with the element at refzero_list\n *    having a NULL 'prev' pointer.  The fact that refzero_list is non-NULL\n *    is used to reject (1) recursive duk__refcount_free_pending() and\n *    (2) finalize_list processing calls.\n *\n *  - When we're done with the current object, read its 'prev' pointer and\n *    free the object.  If 'prev' is NULL, we've reached head of list and are\n *    done: set refzero_list to NULL and process pending finalizers.  Otherwise\n *    continue processing the list.\n *\n *  A refzero cascade is free of side effects because it only involves\n *  queueing more objects and freeing memory; finalizer execution is blocked\n *  in the code path queueing objects to finalize_list.  As a result the\n *  initial refzero call (which triggers duk__refcount_free_pending()) must\n *  check finalize_list so that finalizers are executed snappily.\n *\n *  If finalize_list processing starts first, refzero may occur while we're\n *  processing finalizers.  That's fine: that particular refzero cascade is\n *  handled to completion without side effects.  Once the cascade is complete,\n *  we'll run pending finalizers but notice that we're already doing that and\n *  return.\n *\n *  This could be expanded to allow incremental freeing: just bail out\n *  early and resume at a future alloc/decref/refzero.  However, if that\n *  were done, the list structure would need to be kept consistent at all\n *  times, mark-and-sweep would need to handle refzero_list, etc.\n */\n\nDUK_LOCAL void duk__refcount_free_pending(duk_heap *heap) {\n\tduk_heaphdr *curr;\n#if defined(DUK_USE_DEBUG)\n\tduk_int_t count = 0;\n#endif\n\n\tDUK_ASSERT(heap != NULL);\n\n\tcurr = heap->refzero_list;\n\tDUK_ASSERT(curr != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, curr) == NULL);  /* We're called on initial insert only. */\n\t/* curr->next is GARBAGE. */\n\n\tdo {\n\t\tduk_heaphdr *prev;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"refzero processing %p: %!O\", (void *) curr, (duk_heaphdr *) curr));\n\n#if defined(DUK_USE_DEBUG)\n\t\tcount++;\n#endif\n\n\t\tDUK_ASSERT(curr != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);  /* currently, always the case */\n\t\t/* FINALIZED may be set; don't care about flags here. */\n\n\t\t/* Refcount finalize 'curr'.  Refzero_list must be non-NULL\n\t\t * here to prevent recursive entry to duk__refcount_free_pending().\n\t\t */\n\t\tDUK_ASSERT(heap->refzero_list != NULL);\n\t\tduk_hobject_refcount_finalize_norz(heap, (duk_hobject *) curr);\n\n\t\tprev = DUK_HEAPHDR_GET_PREV(heap, curr);\n\t\tDUK_ASSERT((prev == NULL && heap->refzero_list == curr) || \\\n\t\t           (prev != NULL && heap->refzero_list != curr));\n\t\t/* prev->next is intentionally not updated and is garbage. */\n\n\t\tduk_free_hobject(heap, (duk_hobject *) curr);  /* Invalidates 'curr'. */\n\n\t\tcurr = prev;\n\t} while (curr != NULL);\n\n\theap->refzero_list = NULL;\n\n\tDUK_DD(DUK_DDPRINT(\"refzero processed %ld objects\", (long) count));\n}\n\nDUK_LOCAL DUK_INLINE void duk__refcount_refzero_hobject(duk_heap *heap, duk_hobject *obj, duk_bool_t skip_free_pending) {\n\tduk_heaphdr *hdr;\n\tduk_heaphdr *root;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) obj) == DUK_HTYPE_OBJECT);\n\n\thdr = (duk_heaphdr *) obj;\n\n\t/* Refzero'd objects must be in heap_allocated.  They can't be in\n\t * finalize_list because all objects on finalize_list have an\n\t * artificial +1 refcount bump.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(duk_heap_in_heap_allocated(heap, (duk_heaphdr *) obj));\n#endif\n\n\tDUK_HEAP_REMOVE_FROM_HEAP_ALLOCATED(heap, hdr);\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t/* This finalizer check MUST BE side effect free.  It should also be\n\t * as fast as possible because it's applied to every object freed.\n\t */\n\tif (DUK_UNLIKELY(DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) hdr) != 0U)) {\n\t\t/* Special case: FINALIZED may be set if mark-and-sweep queued\n\t\t * object for finalization, the finalizer was executed (and\n\t\t * FINALIZED set), mark-and-sweep hasn't yet processed the\n\t\t * object again, but its refcount drops to zero.  Free without\n\t\t * running the finalizer again.\n\t\t */\n\t\tif (DUK_HEAPHDR_HAS_FINALIZED(hdr)) {\n\t\t\tDUK_D(DUK_DPRINT(\"refzero'd object has finalizer and FINALIZED is set -> free\"));\n\t\t} else {\n\t\t\t/* Set FINALIZABLE flag so that all objects on finalize_list\n\t\t\t * will have it set and are thus detectable based on the\n\t\t\t * flag alone.\n\t\t\t */\n\t\t\tDUK_HEAPHDR_SET_FINALIZABLE(hdr);\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(hdr));\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t/* Bump refcount on finalize_list insert so that a\n\t\t\t * refzero can never occur when an object is waiting\n\t\t\t * for its finalizer call.  Refzero might otherwise\n\t\t\t * now happen because we allow duk_push_heapptr() for\n\t\t\t * objects pending finalization.\n\t\t\t */\n\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(hdr);\n#endif\n\t\t\tDUK_HEAP_INSERT_INTO_FINALIZE_LIST(heap, hdr);\n\n\t\t\t/* Process finalizers unless skipping is explicitly\n\t\t\t * requested (NORZ) or refzero_list is being processed\n\t\t\t * (avoids side effects during a refzero cascade).\n\t\t\t * If refzero_list is processed, the initial refzero\n\t\t\t * call will run pending finalizers when refzero_list\n\t\t\t * is done.\n\t\t\t */\n\t\t\tif (!skip_free_pending && heap->refzero_list == NULL) {\n\t\t\t\tduk_heap_process_finalize_list(heap);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n\t/* No need to finalize, free object via refzero_list. */\n\n\troot = heap->refzero_list;\n\n\tDUK_HEAPHDR_SET_PREV(heap, hdr, NULL);\n\t/* 'next' is left as GARBAGE. */\n\theap->refzero_list = hdr;\n\n\tif (root == NULL) {\n\t\t/* Object is now queued.  Refzero_list was NULL so\n\t\t * no-one is currently processing it; do it here.\n\t\t * With refzero processing just doing a cascade of\n\t\t * free calls, we can process it directly even when\n\t\t * NORZ macros are used: there are no side effects.\n\t\t */\n\t\tduk__refcount_free_pending(heap);\n\t\tDUK_ASSERT(heap->refzero_list == NULL);\n\n\t\t/* Process finalizers only after the entire cascade\n\t\t * is finished.  In most cases there's nothing to\n\t\t * finalize, so fast path check to avoid a call.\n\t\t */\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\tif (!skip_free_pending && DUK_UNLIKELY(heap->finalize_list != NULL)) {\n\t\t\tduk_heap_process_finalize_list(heap);\n\t\t}\n#endif\n\t} else {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, root) == NULL);\n\t\tDUK_HEAPHDR_SET_PREV(heap, root, hdr);\n\n\t\t/* Object is now queued.  Because refzero_list was\n\t\t * non-NULL, it's already being processed by someone\n\t\t * in the C call stack, so we're done.\n\t\t */\n\t}\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_refzero_check_fast(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->heap->refzero_list == NULL);  /* Processed to completion inline. */\n\n\tif (DUK_UNLIKELY(thr->heap->finalize_list != NULL)) {\n\t\tduk_heap_process_finalize_list(thr->heap);\n\t}\n}\n\nDUK_INTERNAL void duk_refzero_check_slow(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->heap->refzero_list == NULL);  /* Processed to completion inline. */\n\n\tif (DUK_UNLIKELY(thr->heap->finalize_list != NULL)) {\n\t\tduk_heap_process_finalize_list(thr->heap);\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Refzero processing for duk_hstring.\n */\n\nDUK_LOCAL DUK_INLINE void duk__refcount_refzero_hstring(duk_heap *heap, duk_hstring *str) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(str != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) str) == DUK_HTYPE_STRING);\n\n\tduk_heap_strcache_string_remove(heap, str);\n\tduk_heap_strtable_unlink(heap, str);\n\tduk_free_hstring(heap, str);\n}\n\n/*\n *  Refzero processing for duk_hbuffer.\n */\n\nDUK_LOCAL DUK_INLINE void duk__refcount_refzero_hbuffer(duk_heap *heap, duk_hbuffer *buf) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) buf) == DUK_HTYPE_BUFFER);\n\n\tDUK_HEAP_REMOVE_FROM_HEAP_ALLOCATED(heap, (duk_heaphdr *) buf);\n\tduk_free_hbuffer(heap, buf);\n}\n\n/*\n *  Incref and decref functions.\n *\n *  Decref may trigger immediate refzero handling, which may free and finalize\n *  an arbitrary number of objects (a \"DECREF cascade\").\n *\n *  Refzero handling is skipped entirely if (1) mark-and-sweep is running or\n *  (2) execution is paused in the debugger.  The objects are left in the heap,\n *  and will be freed by mark-and-sweep or eventual heap destruction.\n *\n *  This is necessary during mark-and-sweep because refcounts are also updated\n *  during the sweep phase (otherwise objects referenced by a swept object\n *  would have incorrect refcounts) which then calls here.  This could be\n *  avoided by using separate decref macros in mark-and-sweep; however,\n *  mark-and-sweep also calls finalizers which would use the ordinary decref\n *  macros anyway.\n *\n *  We can't process refzeros (= free objects) when the debugger is running\n *  as the debugger might make an object unreachable but still continue\n *  inspecting it (or even cause it to be pushed back).  So we must rely on\n *  mark-and-sweep to collect them.\n *\n *  The DUK__RZ_SUPPRESS_CHECK() condition is also used in heap destruction\n *  when running finalizers for remaining objects: the flag prevents objects\n *  from being moved around in heap linked lists while that's being done.\n *\n *  The suppress condition is important to performance.\n */\n\n#define DUK__RZ_SUPPRESS_ASSERT1() do { \\\n\t\tDUK_ASSERT(thr != NULL); \\\n\t\tDUK_ASSERT(thr->heap != NULL); \\\n\t\t/* When mark-and-sweep runs, heap_thread must exist. */ \\\n\t\tDUK_ASSERT(thr->heap->ms_running == 0 || thr->heap->heap_thread != NULL); \\\n\t\t/* In normal operation finalizers are executed with ms_running == 0 \\\n\t\t * so we should never see ms_running == 1 and thr != heap_thread. \\\n\t\t * In heap destruction finalizers are executed with ms_running != 0 \\\n\t\t * to e.g. prevent refzero; a special value ms_running == 2 is used \\\n\t\t * in that case so it can be distinguished from the normal runtime \\\n\t\t * case, and allows a stronger assertion here (GH-2030). \\\n\t\t */ \\\n\t\tDUK_ASSERT(!(thr->heap->ms_running == 1 && thr != thr->heap->heap_thread)); \\\n\t\t/* We may be called when the heap is initializing and we process \\\n\t\t * refzeros normally, but mark-and-sweep and finalizers are prevented \\\n\t\t * if that's the case. \\\n\t\t */ \\\n\t\tDUK_ASSERT(thr->heap->heap_initializing == 0 || thr->heap->ms_prevent_count > 0); \\\n\t\tDUK_ASSERT(thr->heap->heap_initializing == 0 || thr->heap->pf_prevent_count > 0); \\\n\t} while (0)\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n#define DUK__RZ_SUPPRESS_ASSERT2() do { \\\n\t\t/* When debugger is paused, ms_running is set. */ \\\n\t\tDUK_ASSERT(!DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || thr->heap->ms_running != 0); \\\n\t} while (0)\n#define DUK__RZ_SUPPRESS_COND()  (heap->ms_running != 0)\n#else\n#define DUK__RZ_SUPPRESS_ASSERT2() do { } while (0)\n#define DUK__RZ_SUPPRESS_COND()  (heap->ms_running != 0)\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n#define DUK__RZ_SUPPRESS_CHECK() do { \\\n\t\tDUK__RZ_SUPPRESS_ASSERT1(); \\\n\t\tDUK__RZ_SUPPRESS_ASSERT2(); \\\n\t\tif (DUK_UNLIKELY(DUK__RZ_SUPPRESS_COND())) { \\\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"refzero handling suppressed (not even queued) when mark-and-sweep running, object: %p\", (void *) h)); \\\n\t\t\treturn; \\\n\t\t} \\\n\t} while (0)\n\n#define DUK__RZ_STRING() do { \\\n\t\tduk__refcount_refzero_hstring(heap, (duk_hstring *) h); \\\n\t} while (0)\n#define DUK__RZ_BUFFER() do { \\\n\t\tduk__refcount_refzero_hbuffer(heap, (duk_hbuffer *) h); \\\n\t} while (0)\n#define DUK__RZ_OBJECT() do { \\\n\t\tduk__refcount_refzero_hobject(heap, (duk_hobject *) h, skip_free_pending); \\\n\t} while (0)\n\n/* XXX: test the effect of inlining here vs. NOINLINE in refzero helpers */\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n#define DUK__RZ_INLINE DUK_ALWAYS_INLINE\n#else\n#define DUK__RZ_INLINE /*nop*/\n#endif\n\nDUK_LOCAL DUK__RZ_INLINE void duk__hstring_refzero_helper(duk_hthread *thr, duk_hstring *h) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\tDUK__RZ_SUPPRESS_CHECK();\n\tDUK__RZ_STRING();\n}\n\nDUK_LOCAL DUK__RZ_INLINE void duk__hbuffer_refzero_helper(duk_hthread *thr, duk_hbuffer *h) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\tDUK__RZ_SUPPRESS_CHECK();\n\tDUK__RZ_BUFFER();\n}\n\nDUK_LOCAL DUK__RZ_INLINE void duk__hobject_refzero_helper(duk_hthread *thr, duk_hobject *h, duk_bool_t skip_free_pending) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\tDUK__RZ_SUPPRESS_CHECK();\n\tDUK__RZ_OBJECT();\n}\n\nDUK_LOCAL DUK__RZ_INLINE void duk__heaphdr_refzero_helper(duk_hthread *thr, duk_heaphdr *h, duk_bool_t skip_free_pending) {\n\tduk_heap *heap;\n\tduk_small_uint_t htype;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\thtype = (duk_small_uint_t) DUK_HEAPHDR_GET_TYPE(h);\n\tDUK_DDD(DUK_DDDPRINT(\"ms_running=%ld, heap_thread=%p\", (long) thr->heap->ms_running, thr->heap->heap_thread));\n\tDUK__RZ_SUPPRESS_CHECK();\n\n\tswitch (htype) {\n\tcase DUK_HTYPE_STRING:\n\t\t/* Strings have no internal references but do have \"weak\"\n\t\t * references in the string cache.  Also note that strings\n\t\t * are not on the heap_allocated list like other heap\n\t\t * elements.\n\t\t */\n\n\t\tDUK__RZ_STRING();\n\t\tbreak;\n\n\tcase DUK_HTYPE_OBJECT:\n\t\t/* Objects have internal references.  Must finalize through\n\t\t * the \"refzero\" work list.\n\t\t */\n\n\t\tDUK__RZ_OBJECT();\n\t\tbreak;\n\n\tdefault:\n\t\t/* Buffers have no internal references.  However, a dynamic\n\t\t * buffer has a separate allocation for the buffer.  This is\n\t\t * freed by duk_heap_free_heaphdr_raw().\n\t\t */\n\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(h) == DUK_HTYPE_BUFFER);\n\t\tDUK__RZ_BUFFER();\n\t\tbreak;\n\t}\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h) {\n\tduk__heaphdr_refzero_helper(thr, h, 0 /*skip_free_pending*/);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_heaphdr_refzero_norz(duk_hthread *thr, duk_heaphdr *h) {\n\tduk__heaphdr_refzero_helper(thr, h, 1 /*skip_free_pending*/);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hstring_refzero(duk_hthread *thr, duk_hstring *h) {\n\tduk__hstring_refzero_helper(thr, h);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hbuffer_refzero(duk_hthread *thr, duk_hbuffer *h) {\n\tduk__hbuffer_refzero_helper(thr, h);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hobject_refzero(duk_hthread *thr, duk_hobject *h) {\n\tduk__hobject_refzero_helper(thr, h, 0 /*skip_free_pending*/);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hobject_refzero_norz(duk_hthread *thr, duk_hobject *h) {\n\tduk__hobject_refzero_helper(thr, h, 1 /*skip_free_pending*/);\n}\n\n#if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\nDUK_INTERNAL void duk_tval_incref(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\t\tDUK_ASSERT_DISABLE(h->h_refcount >= 0);\n\t\tDUK_HEAPHDR_PREINC_REFCOUNT(h);\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) != 0);  /* No wrapping. */\n\t}\n}\n\nDUK_INTERNAL void duk_tval_decref(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) >= 1);\n#if 0\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(h) != 0) {\n\t\t\treturn;\n\t\t}\n\t\tduk_heaphdr_refzero(thr, h);\n#else\n\t\tduk_heaphdr_decref(thr, h);\n#endif\n\t}\n}\n\nDUK_INTERNAL void duk_tval_decref_norz(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) >= 1);\n#if 0\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(h) != 0) {\n\t\t\treturn;\n\t\t}\n\t\tduk_heaphdr_refzero_norz(thr, h);\n#else\n\t\tduk_heaphdr_decref_norz(thr, h);\n#endif\n\t}\n}\n#endif  /* !DUK_USE_FAST_REFCOUNT_DEFAULT */\n\n#define DUK__DECREF_ASSERTS() do { \\\n\t\tDUK_ASSERT(thr != NULL); \\\n\t\tDUK_ASSERT(thr->heap != NULL); \\\n\t\tDUK_ASSERT(h != NULL); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID((duk_heaphdr *) h)); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) >= 1); \\\n\t} while (0)\n#if defined(DUK_USE_ROM_OBJECTS)\n#define DUK__INCREF_SHARED() do { \\\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t\tDUK_HEAPHDR_PREINC_REFCOUNT((duk_heaphdr *) h); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) != 0);  /* No wrapping. */ \\\n\t} while (0)\n#define DUK__DECREF_SHARED() do { \\\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT((duk_heaphdr *) h) != 0) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t} while (0)\n#else\n#define DUK__INCREF_SHARED() do { \\\n\t\tDUK_HEAPHDR_PREINC_REFCOUNT((duk_heaphdr *) h); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) != 0);  /* No wrapping. */ \\\n\t} while (0)\n#define DUK__DECREF_SHARED() do { \\\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT((duk_heaphdr *) h) != 0) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t} while (0)\n#endif\n\n#if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n/* This will in practice be inlined because it's just an INC instructions\n * and a bit test + INC when ROM objects are enabled.\n */\nDUK_INTERNAL void duk_heaphdr_incref(duk_heaphdr *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\tDUK_ASSERT_DISABLE(DUK_HEAPHDR_GET_REFCOUNT(h) >= 0);\n\n\tDUK__INCREF_SHARED();\n}\n\nDUK_INTERNAL void duk_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_heaphdr_refzero(thr, h);\n\n\t/* Forced mark-and-sweep when GC torture enabled; this could happen\n\t * on any DECREF (but not DECREF_NORZ).\n\t */\n\tDUK_GC_TORTURE(thr->heap);\n}\nDUK_INTERNAL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_heaphdr_refzero_norz(thr, h);\n}\n#endif  /* !DUK_USE_FAST_REFCOUNT_DEFAULT */\n\n#if 0  /* Not needed. */\nDUK_INTERNAL void duk_hstring_decref(duk_hthread *thr, duk_hstring *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hstring_refzero(thr, h);\n}\nDUK_INTERNAL void duk_hstring_decref_norz(duk_hthread *thr, duk_hstring *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hstring_refzero_norz(thr, h);\n}\nDUK_INTERNAL void duk_hbuffer_decref(duk_hthread *thr, duk_hbuffer *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hbuffer_refzero(thr, h);\n}\nDUK_INTERNAL void duk_hbuffer_decref_norz(duk_hthread *thr, duk_hbuffer *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hbuffer_refzero_norz(thr, h);\n}\nDUK_INTERNAL void duk_hobject_decref(duk_hthread *thr, duk_hobject *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hobject_refzero(thr, h);\n}\nDUK_INTERNAL void duk_hobject_decref_norz(duk_hthread *thr, duk_hobject *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hobject_refzero_norz(thr, h);\n}\n#endif\n\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\n/* no refcounting */\n\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/* automatic undefs */\n#undef DUK__DECREF_ASSERTS\n#undef DUK__DECREF_SHARED\n#undef DUK__INCREF_SHARED\n#undef DUK__RZ_BUFFER\n#undef DUK__RZ_INLINE\n#undef DUK__RZ_OBJECT\n#undef DUK__RZ_STRING\n#undef DUK__RZ_SUPPRESS_ASSERT1\n#undef DUK__RZ_SUPPRESS_ASSERT2\n#undef DUK__RZ_SUPPRESS_CHECK\n#undef DUK__RZ_SUPPRESS_COND\n/*\n *  String cache.\n *\n *  Provides a cache to optimize indexed string lookups.  The cache keeps\n *  track of (byte offset, char offset) states for a fixed number of strings.\n *  Otherwise we'd need to scan from either end of the string, as we store\n *  strings in (extended) UTF-8.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Delete references to given hstring from the heap string cache.\n *\n *  String cache references are 'weak': they are not counted towards\n *  reference counts, nor serve as roots for mark-and-sweep.  When an\n *  object is about to be freed, such references need to be removed.\n */\n\nDUK_INTERNAL void duk_heap_strcache_string_remove(duk_heap *heap, duk_hstring *h) {\n\tduk_uint_t i;\n\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\tduk_strcache_entry *c = heap->strcache + i;\n\t\tif (c->h == h) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"deleting weak strcache reference to hstring %p from heap %p\",\n\t\t\t                   (void *) h, (void *) heap));\n\t\t\tc->h = NULL;\n\n\t\t\t/* XXX: the string shouldn't appear twice, but we now loop to the\n\t\t\t * end anyway; if fixed, add a looping assertion to ensure there\n\t\t\t * is no duplicate.\n\t\t\t */\n\t\t}\n\t}\n}\n\n/*\n *  String scanning helpers\n *\n *  All bytes other than UTF-8 continuation bytes ([0x80,0xbf]) are\n *  considered to contribute a character.  This must match how string\n *  character length is computed.\n */\n\nDUK_LOCAL const duk_uint8_t *duk__scan_forwards(const duk_uint8_t *p, const duk_uint8_t *q, duk_uint_fast32_t n) {\n\twhile (n > 0) {\n\t\tfor (;;) {\n\t\t\tp++;\n\t\t\tif (p >= q) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\tif ((*p & 0xc0) != 0x80) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tn--;\n\t}\n\treturn p;\n}\n\nDUK_LOCAL const duk_uint8_t *duk__scan_backwards(const duk_uint8_t *p, const duk_uint8_t *q, duk_uint_fast32_t n) {\n\twhile (n > 0) {\n\t\tfor (;;) {\n\t\t\tp--;\n\t\t\tif (p < q) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\tif ((*p & 0xc0) != 0x80) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tn--;\n\t}\n\treturn p;\n}\n\n/*\n *  Convert char offset to byte offset\n *\n *  Avoid using the string cache if possible: for ASCII strings byte and\n *  char offsets are equal and for short strings direct scanning may be\n *  better than using the string cache (which may evict a more important\n *  entry).\n *\n *  Typing now assumes 32-bit string byte/char offsets (duk_uint_fast32_t).\n *  Better typing might be to use duk_size_t.\n *\n *  Caller should ensure 'char_offset' is within the string bounds [0,charlen]\n *  (endpoint is inclusive).  If this is not the case, no memory unsafe\n *  behavior will happen but an error will be thrown.\n */\n\nDUK_INTERNAL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *thr, duk_hstring *h, duk_uint_fast32_t char_offset) {\n\tduk_heap *heap;\n\tduk_strcache_entry *sce;\n\tduk_uint_fast32_t byte_offset;\n\tduk_uint_t i;\n\tduk_bool_t use_cache;\n\tduk_uint_fast32_t dist_start, dist_end, dist_sce;\n\tduk_uint_fast32_t char_length;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint8_t *p_found;\n\n\t/*\n\t *  For ASCII strings, the answer is simple.\n\t */\n\n\tif (DUK_LIKELY(DUK_HSTRING_IS_ASCII(h))) {\n\t\treturn char_offset;\n\t}\n\n\tchar_length = (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h);\n\tDUK_ASSERT(char_offset <= char_length);\n\n\tif (DUK_LIKELY(DUK_HSTRING_IS_ASCII(h))) {\n\t\t/* Must recheck because the 'is ascii' flag may be set\n\t\t * lazily.  Alternatively, we could just compare charlen\n\t\t * to bytelen.\n\t\t */\n\t\treturn char_offset;\n\t}\n\n\t/*\n\t *  For non-ASCII strings, we need to scan forwards or backwards\n\t *  from some starting point.  The starting point may be the start\n\t *  or end of the string, or some cached midpoint in the string\n\t *  cache.\n\t *\n\t *  For \"short\" strings we simply scan without checking or updating\n\t *  the cache.  For longer strings we check and update the cache as\n\t *  necessary, inserting a new cache entry if none exists.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string %p, char_offset=%ld, clen=%ld, blen=%ld\",\n\t                     (void *) h, (long) char_offset,\n\t                     (long) DUK_HSTRING_GET_CHARLEN(h),\n\t                     (long) DUK_HSTRING_GET_BYTELEN(h)));\n\n\theap = thr->heap;\n\tsce = NULL;\n\tuse_cache = (char_length > DUK_HEAP_STRINGCACHE_NOCACHE_LIMIT);\n\n\tif (use_cache) {\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t\tDUK_DDD(DUK_DDDPRINT(\"stringcache before char2byte (using cache):\"));\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tduk_strcache_entry *c = heap->strcache + i;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"  [%ld] -> h=%p, cidx=%ld, bidx=%ld\",\n\t\t\t                     (long) i, (void *) c->h, (long) c->cidx, (long) c->bidx));\n\t\t}\n#endif\n\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tduk_strcache_entry *c = heap->strcache + i;\n\n\t\t\tif (c->h == h) {\n\t\t\t\tsce = c;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t/*\n\t *  Scan from shortest distance:\n\t *    - start of string\n\t *    - end of string\n\t *    - cache entry (if exists)\n\t */\n\n\tDUK_ASSERT(DUK_HSTRING_GET_CHARLEN(h) >= char_offset);\n\tdist_start = char_offset;\n\tdist_end = char_length - char_offset;\n\tdist_sce = 0; DUK_UNREF(dist_sce);  /* initialize for debug prints, needed if sce==NULL */\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tp_end = (const duk_uint8_t *) (p_start + DUK_HSTRING_GET_BYTELEN(h));\n\tp_found = NULL;\n\n\tif (sce) {\n\t\tif (char_offset >= sce->cidx) {\n\t\t\tdist_sce = char_offset - sce->cidx;\n\t\t\tif ((dist_sce <= dist_start) && (dist_sce <= dist_end)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t\t\t                     \"scan forwards from sce\",\n\t\t\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\t\t\tp_found = duk__scan_forwards(p_start + sce->bidx,\n\t\t\t\t                             p_end,\n\t\t\t\t                             dist_sce);\n\t\t\t\tgoto scan_done;\n\t\t\t}\n\t\t} else {\n\t\t\tdist_sce = sce->cidx - char_offset;\n\t\t\tif ((dist_sce <= dist_start) && (dist_sce <= dist_end)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t\t\t                     \"scan backwards from sce\",\n\t\t\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\t\t\tp_found = duk__scan_backwards(p_start + sce->bidx,\n\t\t\t\t                              p_start,\n\t\t\t\t                              dist_sce);\n\t\t\t\tgoto scan_done;\n\t\t\t}\n\t\t}\n\t}\n\n\t/* no sce, or sce scan not best */\n\n\tif (dist_start <= dist_end) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t                     \"scan forwards from string start\",\n\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\tp_found = duk__scan_forwards(p_start,\n\t\t                             p_end,\n\t\t                             dist_start);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t                     \"scan backwards from string end\",\n\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\tp_found = duk__scan_backwards(p_end,\n\t\t                              p_start,\n\t\t                              dist_end);\n\t}\n\n scan_done:\n\n\tif (DUK_UNLIKELY(p_found == NULL)) {\n\t\t/* Scan error: this shouldn't normally happen; it could happen if\n\t\t * string is not valid UTF-8 data, and clen/blen are not consistent\n\t\t * with the scanning algorithm.\n\t\t */\n\t\tgoto scan_error;\n\t}\n\n\tDUK_ASSERT(p_found >= p_start);\n\tDUK_ASSERT(p_found <= p_end);  /* may be equal */\n\tbyte_offset = (duk_uint32_t) (p_found - p_start);\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> string %p, cidx %ld -> bidx %ld\",\n\t                     (void *) h, (long) char_offset, (long) byte_offset));\n\n\t/*\n\t *  Update cache entry (allocating if necessary), and move the\n\t *  cache entry to the first place (in an \"LRU\" policy).\n\t */\n\n\tif (use_cache) {\n\t\t/* update entry, allocating if necessary */\n\t\tif (!sce) {\n\t\t\tsce = heap->strcache + DUK_HEAP_STRCACHE_SIZE - 1;  /* take last entry */\n\t\t\tsce->h = h;\n\t\t}\n\t\tDUK_ASSERT(sce != NULL);\n\t\tsce->bidx = (duk_uint32_t) (p_found - p_start);\n\t\tsce->cidx = (duk_uint32_t) char_offset;\n\n\t\t/* LRU: move our entry to first */\n\t\tif (sce > &heap->strcache[0]) {\n\t\t\t/*\n\t\t\t *   A                  C\n\t\t\t *   B                  A\n\t\t\t *   C <- sce    ==>    B\n\t\t\t *   D                  D\n\t\t\t */\n\t\t\tduk_strcache_entry tmp;\n\n\t\t\ttmp = *sce;\n\t\t\tduk_memmove((void *) (&heap->strcache[1]),\n\t\t\t            (const void *) (&heap->strcache[0]),\n\t\t\t            (size_t) (((char *) sce) - ((char *) &heap->strcache[0])));\n\t\t\theap->strcache[0] = tmp;\n\n\t\t\t/* 'sce' points to the wrong entry here, but is no longer used */\n\t\t}\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t\tDUK_DDD(DUK_DDDPRINT(\"stringcache after char2byte (using cache):\"));\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tduk_strcache_entry *c = heap->strcache + i;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"  [%ld] -> h=%p, cidx=%ld, bidx=%ld\",\n\t\t\t                     (long) i, (void *) c->h, (long) c->cidx, (long) c->bidx));\n\t\t}\n#endif\n\t}\n\n\treturn byte_offset;\n\n scan_error:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n/*\n *  Heap string table handling, string interning.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Resize checks not needed if minsize == maxsize, typical for low memory\n * targets.\n */\n#define DUK__STRTAB_RESIZE_CHECK\n#if (DUK_USE_STRTAB_MINSIZE == DUK_USE_STRTAB_MAXSIZE)\n#undef DUK__STRTAB_RESIZE_CHECK\n#endif\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n#define DUK__HEAPPTR_ENC16(heap,ptr)    DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (ptr))\n#define DUK__HEAPPTR_DEC16(heap,val)    DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (val))\n#define DUK__GET_STRTABLE(heap)         ((heap)->strtable16)\n#else\n#define DUK__HEAPPTR_ENC16(heap,ptr)    (ptr)\n#define DUK__HEAPPTR_DEC16(heap,val)    (val)\n#define DUK__GET_STRTABLE(heap)         ((heap)->strtable)\n#endif\n\n#define DUK__STRTAB_U32_MAX_STRLEN      10               /* 4'294'967'295 */\n\n/*\n *  Debug dump stringtable.\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_INTERNAL void duk_heap_strtable_dump(duk_heap *heap) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable;\n#else\n\tduk_hstring **strtable;\n#endif\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_size_t count_total = 0;\n\tduk_size_t count_chain;\n\tduk_size_t count_chain_min = DUK_SIZE_MAX;\n\tduk_size_t count_chain_max = 0;\n\tduk_size_t count_len[8];  /* chain lengths from 0 to 7 */\n\n\tif (heap == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"string table, heap=NULL\"));\n\t\treturn;\n\t}\n\n\tstrtable = DUK__GET_STRTABLE(heap);\n\tif (strtable == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"string table, strtab=NULL\"));\n\t\treturn;\n\t}\n\n\tduk_memzero((void *) count_len, sizeof(count_len));\n\tfor (i = 0; i < heap->st_size; i++) {\n\t\th = DUK__HEAPPTR_DEC16(heap, strtable[i]);\n\t\tcount_chain = 0;\n\t\twhile (h != NULL) {\n\t\t\tcount_chain++;\n\t\t\th = h->hdr.h_next;\n\t\t}\n\t\tif (count_chain < sizeof(count_len) / sizeof(duk_size_t)) {\n\t\t\tcount_len[count_chain]++;\n\t\t}\n\t\tcount_chain_max = (count_chain > count_chain_max ? count_chain : count_chain_max);\n\t\tcount_chain_min = (count_chain < count_chain_min ? count_chain : count_chain_min);\n\t\tcount_total += count_chain;\n\t}\n\n\tDUK_D(DUK_DPRINT(\"string table, strtab=%p, count=%lu, chain min=%lu max=%lu avg=%lf: \"\n\t                 \"counts: %lu %lu %lu %lu %lu %lu %lu %lu ...\",\n\t                 (void *) heap->strtable, (unsigned long) count_total,\n\t                 (unsigned long) count_chain_min, (unsigned long) count_chain_max,\n\t                 (double) count_total / (double) heap->st_size,\n\t                 (unsigned long) count_len[0], (unsigned long) count_len[1],\n\t                 (unsigned long) count_len[2], (unsigned long) count_len[3],\n\t                 (unsigned long) count_len[4], (unsigned long) count_len[5],\n\t                 (unsigned long) count_len[6], (unsigned long) count_len[7]));\n}\n#endif  /* DUK_USE_DEBUG */\n\n/*\n *  Assertion helper to ensure strtable is populated correctly.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_LOCAL void duk__strtable_assert_checks(duk_heap *heap) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable;\n#else\n\tduk_hstring **strtable;\n#endif\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_size_t count = 0;\n\n\tDUK_ASSERT(heap != NULL);\n\n\tstrtable = DUK__GET_STRTABLE(heap);\n\tif (strtable != NULL) {\n\t\tDUK_ASSERT(heap->st_size != 0);\n\t\tDUK_ASSERT(heap->st_mask == heap->st_size - 1);\n\n\t\tfor (i = 0; i < heap->st_size; i++) {\n\t\t\th = DUK__HEAPPTR_DEC16(heap, strtable[i]);\n\t\t\twhile (h != NULL) {\n\t\t\t\tDUK_ASSERT((DUK_HSTRING_GET_HASH(h) & heap->st_mask) == i);\n\t\t\t\tcount++;\n\t\t\t\th = h->hdr.h_next;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_ASSERT(heap->st_size == 0);\n\t\tDUK_ASSERT(heap->st_mask == 0);\n\t}\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tDUK_ASSERT(count == (duk_size_t) heap->st_count);\n#endif\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\n/*\n *  Allocate and initialize a duk_hstring.\n *\n *  Returns a NULL if allocation or initialization fails for some reason.\n *\n *  The string won't be inserted into the string table and isn't tracked in\n *  any way (link pointers will be NULL).  The caller must place the string\n *  into the string table without any risk of a longjmp, otherwise the string\n *  is leaked.\n */\n\nDUK_LOCAL duk_hstring *duk__strtable_alloc_hstring(duk_heap *heap,\n                                                   const duk_uint8_t *str,\n                                                   duk_uint32_t blen,\n                                                   duk_uint32_t strhash,\n                                                   const duk_uint8_t *extdata) {\n\tduk_hstring *res;\n\tconst duk_uint8_t *data;\n#if !defined(DUK_USE_HSTRING_ARRIDX)\n\tduk_uarridx_t dummy;\n#endif\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_UNREF(extdata);\n\n#if defined(DUK_USE_STRLEN16)\n\t/* If blen <= 0xffffUL, clen is also guaranteed to be <= 0xffffUL. */\n\tif (blen > 0xffffUL) {\n\t\tDUK_D(DUK_DPRINT(\"16-bit string blen/clen active and blen over 16 bits, reject intern\"));\n\t\tgoto alloc_error;\n\t}\n#endif\n\n\t/* XXX: Memzeroing the allocated structure is not really necessary\n\t * because we could just initialize all fields explicitly (almost\n\t * all fields are initialized explicitly anyway).\n\t */\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK)\n\tif (extdata) {\n\t\tres = (duk_hstring *) DUK_ALLOC(heap, sizeof(duk_hstring_external));\n\t\tif (DUK_UNLIKELY(res == NULL)) {\n\t\t\tgoto alloc_error;\n\t\t}\n\t\tduk_memzero(res, sizeof(duk_hstring_external));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\tDUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr);\n#endif\n\t\tDUK_HEAPHDR_SET_TYPE_AND_FLAGS(&res->hdr, DUK_HTYPE_STRING, DUK_HSTRING_FLAG_EXTDATA);\n\n\t\tDUK_ASSERT(extdata[blen] == 0);  /* Application responsibility. */\n\t\tdata = extdata;\n\t\t((duk_hstring_external *) res)->extdata = extdata;\n\t} else\n#endif  /* DUK_USE_HSTRING_EXTDATA && DUK_USE_EXTSTR_INTERN_CHECK */\n\t{\n\t\tduk_uint8_t *data_tmp;\n\n\t\t/* NUL terminate for convenient C access */\n\t\tDUK_ASSERT(sizeof(duk_hstring) + blen + 1 > blen);  /* No wrap, limits ensure. */\n\t\tres = (duk_hstring *) DUK_ALLOC(heap, sizeof(duk_hstring) + blen + 1);\n\t\tif (DUK_UNLIKELY(res == NULL)) {\n\t\t\tgoto alloc_error;\n\t\t}\n\t\tduk_memzero(res, sizeof(duk_hstring));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\tDUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr);\n#endif\n\t\tDUK_HEAPHDR_SET_TYPE_AND_FLAGS(&res->hdr, DUK_HTYPE_STRING, 0);\n\n\t\tdata_tmp = (duk_uint8_t *) (res + 1);\n\t\tduk_memcpy(data_tmp, str, blen);\n\t\tdata_tmp[blen] = (duk_uint8_t) 0;\n\t\tdata = (const duk_uint8_t *) data_tmp;\n\t}\n\n\tDUK_HSTRING_SET_BYTELEN(res, blen);\n\tDUK_HSTRING_SET_HASH(res, strhash);\n\n\tDUK_ASSERT(!DUK_HSTRING_HAS_ARRIDX(res));\n#if defined(DUK_USE_HSTRING_ARRIDX)\n\tres->arridx = duk_js_to_arrayindex_string(data, blen);\n\tif (res->arridx != DUK_HSTRING_NO_ARRAY_INDEX) {\n#else\n\tdummy = duk_js_to_arrayindex_string(data, blen);\n\tif (dummy != DUK_HSTRING_NO_ARRAY_INDEX) {\n#endif\n\t\t/* Array index strings cannot be symbol strings,\n\t\t * and they're always pure ASCII so blen == clen.\n\t\t */\n\t\tDUK_HSTRING_SET_ARRIDX(res);\n\t\tDUK_HSTRING_SET_ASCII(res);\n\t\tDUK_ASSERT(duk_unicode_unvalidated_utf8_length(data, (duk_size_t) blen) == blen);\n\t} else {\n\t\t/* Because 'data' is NUL-terminated, we don't need a\n\t\t * blen > 0 check here.  For NUL (0x00) the symbol\n\t\t * checks will be false.\n\t\t */\n\t\tif (DUK_UNLIKELY(data[0] >= 0x80U)) {\n\t\t\tif (data[0] <= 0x81) {\n\t\t\t\tDUK_HSTRING_SET_SYMBOL(res);\n\t\t\t} else if (data[0] == 0x82U || data[0] == 0xffU) {\n\t\t\t\tDUK_HSTRING_SET_HIDDEN(res);\n\t\t\t\tDUK_HSTRING_SET_SYMBOL(res);\n\t\t\t}\n\t\t}\n\n\t\t/* Using an explicit 'ASCII' flag has larger footprint (one call site\n\t\t * only) but is quite useful for the case when there's no explicit\n\t\t * 'clen' in duk_hstring.\n\t\t *\n\t\t * The flag is set lazily for RAM strings.\n\t\t */\n\t\tDUK_ASSERT(!DUK_HSTRING_HAS_ASCII(res));\n\n#if defined(DUK_USE_HSTRING_LAZY_CLEN)\n\t\t/* Charlen initialized to 0, updated on-the-fly. */\n#else\n\t\tduk_hstring_init_charlen(res);  /* Also sets ASCII flag. */\n#endif\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"interned string, hash=0x%08lx, blen=%ld, has_arridx=%ld, has_extdata=%ld\",\n\t                     (unsigned long) DUK_HSTRING_GET_HASH(res),\n\t                     (long) DUK_HSTRING_GET_BYTELEN(res),\n\t                     (long) (DUK_HSTRING_HAS_ARRIDX(res) ? 1 : 0),\n\t                     (long) (DUK_HSTRING_HAS_EXTDATA(res) ? 1 : 0)));\n\n\tDUK_ASSERT(res != NULL);\n\treturn res;\n\n alloc_error:\n\treturn NULL;\n}\n\n/*\n *  Grow strtable allocation in-place.\n */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL void duk__strtable_grow_inplace(duk_heap *heap) {\n\tduk_uint32_t new_st_size;\n\tduk_uint32_t old_st_size;\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_hstring *next;\n\tduk_hstring *prev;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *new_ptr;\n\tduk_uint16_t *new_ptr_high;\n#else\n\tduk_hstring **new_ptr;\n\tduk_hstring **new_ptr_high;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"grow in-place: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size * 2));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->st_resizing == 1);\n\tDUK_ASSERT(heap->st_size >= 2);\n\tDUK_ASSERT((heap->st_size & (heap->st_size - 1)) == 0);  /* 2^N */\n\tDUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL);\n\n\tDUK_STATS_INC(heap, stats_strtab_resize_grow);\n\n\tnew_st_size = heap->st_size << 1U;\n\tDUK_ASSERT(new_st_size > heap->st_size);  /* No overflow. */\n\n\t/* Reallocate the strtable first and then work in-place to rehash\n\t * strings.  We don't need an indirect allocation here: even if GC\n\t * is triggered to satisfy the allocation, recursive strtable resize\n\t * is prevented by flags.  This is also why we don't need to use\n\t * DUK_REALLOC_INDIRECT().\n\t */\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tnew_ptr = (duk_uint16_t *) DUK_REALLOC(heap, heap->strtable16, sizeof(duk_uint16_t) * new_st_size);\n#else\n\tnew_ptr = (duk_hstring **) DUK_REALLOC(heap, heap->strtable, sizeof(duk_hstring *) * new_st_size);\n#endif\n\tif (DUK_UNLIKELY(new_ptr == NULL)) {\n\t\t/* If realloc fails we can continue normally: the string table\n\t\t * won't \"fill up\" although chains will gradually get longer.\n\t\t * When string insertions continue, we'll quite soon try again\n\t\t * with no special handling.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"string table grow failed, ignoring\"));\n\t\treturn;\n\t}\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\theap->strtable16 = new_ptr;\n#else\n\theap->strtable = new_ptr;\n#endif\n\n\t/* Rehash a single bucket into two separate ones.  When we grow\n\t * by x2 the highest 'new' bit determines whether a string remains\n\t * in its old position (bit is 0) or goes to a new one (bit is 1).\n\t */\n\n\told_st_size = heap->st_size;\n\tnew_ptr_high = new_ptr + old_st_size;\n\tfor (i = 0; i < old_st_size; i++) {\n\t\tduk_hstring *new_root;\n\t\tduk_hstring *new_root_high;\n\n\t\th = DUK__HEAPPTR_DEC16(heap, new_ptr[i]);\n\t\tnew_root = h;\n\t\tnew_root_high = NULL;\n\n\t\tprev = NULL;\n\t\twhile (h != NULL) {\n\t\t\tduk_uint32_t mask;\n\n\t\t\tDUK_ASSERT((DUK_HSTRING_GET_HASH(h) & heap->st_mask) == i);\n\t\t\tnext = h->hdr.h_next;\n\n\t\t\t/* Example: if previous size was 256, previous mask is 0xFF\n\t\t\t * and size is 0x100 which corresponds to the new bit that\n\t\t\t * comes into play.\n\t\t\t */\n\t\t\tDUK_ASSERT(heap->st_mask == old_st_size - 1);\n\t\t\tmask = old_st_size;\n\t\t\tif (DUK_HSTRING_GET_HASH(h) & mask) {\n\t\t\t\tif (prev != NULL) {\n\t\t\t\t\tprev->hdr.h_next = h->hdr.h_next;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(h == new_root);\n\t\t\t\t\tnew_root = h->hdr.h_next;\n\t\t\t\t}\n\n\t\t\t\th->hdr.h_next = new_root_high;\n\t\t\t\tnew_root_high = h;\n\t\t\t} else {\n\t\t\t\tprev = h;\n\t\t\t}\n\t\t\th = next;\n\t\t}\n\n\t\tnew_ptr[i] = DUK__HEAPPTR_ENC16(heap, new_root);\n\t\tnew_ptr_high[i] = DUK__HEAPPTR_ENC16(heap, new_root_high);\n\t}\n\n\theap->st_size = new_st_size;\n\theap->st_mask = new_st_size - 1;\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__strtable_assert_checks(heap);\n#endif\n}\n#endif  /* DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Shrink strtable allocation in-place.\n */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL void duk__strtable_shrink_inplace(duk_heap *heap) {\n\tduk_uint32_t new_st_size;\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_hstring *other;\n\tduk_hstring *root;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *old_ptr;\n\tduk_uint16_t *old_ptr_high;\n\tduk_uint16_t *new_ptr;\n#else\n\tduk_hstring **old_ptr;\n\tduk_hstring **old_ptr_high;\n\tduk_hstring **new_ptr;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"shrink in-place: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size / 2));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->st_resizing == 1);\n\tDUK_ASSERT(heap->st_size >= 2);\n\tDUK_ASSERT((heap->st_size & (heap->st_size - 1)) == 0);  /* 2^N */\n\tDUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL);\n\n\tDUK_STATS_INC(heap, stats_strtab_resize_shrink);\n\n\tnew_st_size = heap->st_size >> 1U;\n\n\t/* Combine two buckets into a single one.  When we shrink, one hash\n\t * bit (highest) disappears.\n\t */\n\told_ptr = DUK__GET_STRTABLE(heap);\n\told_ptr_high = old_ptr + new_st_size;\n\tfor (i = 0; i < new_st_size; i++) {\n\t\th = DUK__HEAPPTR_DEC16(heap, old_ptr[i]);\n\t\tother = DUK__HEAPPTR_DEC16(heap, old_ptr_high[i]);\n\n\t\tif (h == NULL) {\n\t\t\t/* First chain is empty, so use second one as is. */\n\t\t\troot = other;\n\t\t} else {\n\t\t\t/* Find end of first chain, and link in the second. */\n\t\t\troot = h;\n\t\t\twhile (h->hdr.h_next != NULL) {\n\t\t\t\th = h->hdr.h_next;\n\t\t\t}\n\t\t\th->hdr.h_next = other;\n\t\t}\n\n\t\told_ptr[i] = DUK__HEAPPTR_ENC16(heap, root);\n\t}\n\n\theap->st_size = new_st_size;\n\theap->st_mask = new_st_size - 1;\n\n\t/* The strtable is now consistent and we can realloc safely.  Even\n\t * if side effects cause string interning or removal the strtable\n\t * updates are safe.  Recursive resize has been prevented by caller.\n\t * This is also why we don't need to use DUK_REALLOC_INDIRECT().\n\t *\n\t * We assume a realloc() to a smaller size is guaranteed to succeed.\n\t * It would be relatively straightforward to handle the error by\n\t * essentially performing a \"grow\" step to recover.\n\t */\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tnew_ptr = (duk_uint16_t *) DUK_REALLOC(heap, heap->strtable16, sizeof(duk_uint16_t) * new_st_size);\n\tDUK_ASSERT(new_ptr != NULL);\n\theap->strtable16 = new_ptr;\n#else\n\tnew_ptr = (duk_hstring **) DUK_REALLOC(heap, heap->strtable, sizeof(duk_hstring *) * new_st_size);\n\tDUK_ASSERT(new_ptr != NULL);\n\theap->strtable = new_ptr;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__strtable_assert_checks(heap);\n#endif\n}\n#endif  /* DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Grow/shrink check.\n */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL DUK_COLD DUK_NOINLINE void duk__strtable_resize_check(duk_heap *heap) {\n\tduk_uint32_t load_factor;  /* fixed point */\n\n\tDUK_ASSERT(heap != NULL);\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tDUK_ASSERT(heap->strtable16 != NULL);\n#else\n\tDUK_ASSERT(heap->strtable != NULL);\n#endif\n\n\tDUK_STATS_INC(heap, stats_strtab_resize_check);\n\n\t/* Prevent recursive resizing. */\n\tif (DUK_UNLIKELY(heap->st_resizing != 0U)) {\n\t\tDUK_D(DUK_DPRINT(\"prevent recursive strtable resize\"));\n\t\treturn;\n\t}\n\n\theap->st_resizing = 1;\n\n\tDUK_ASSERT(heap->st_size >= 16U);\n\tDUK_ASSERT((heap->st_size >> 4U) >= 1);\n\tload_factor = heap->st_count / (heap->st_size >> 4U);\n\n\tDUK_DD(DUK_DDPRINT(\"resize check string table: size=%lu, count=%lu, load_factor=%lu (fixed point .4; float %lf)\",\n\t                   (unsigned long) heap->st_size, (unsigned long) heap->st_count,\n\t                   (unsigned long) load_factor,\n\t                   (double) heap->st_count / (double) heap->st_size));\n\n\tif (load_factor >= DUK_USE_STRTAB_GROW_LIMIT) {\n\t\tif (heap->st_size >= DUK_USE_STRTAB_MAXSIZE) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"want to grow strtable (based on load factor) but already maximum size\"));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"grow string table: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size * 2));\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk_heap_strtable_dump(heap);\n#endif\n\t\t\tduk__strtable_grow_inplace(heap);\n\t\t}\n\t} else if (load_factor <= DUK_USE_STRTAB_SHRINK_LIMIT) {\n\t\tif (heap->st_size <= DUK_USE_STRTAB_MINSIZE) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"want to shrink strtable (based on load factor) but already minimum size\"));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"shrink string table: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size / 2));\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk_heap_strtable_dump(heap);\n#endif\n\t\t\tduk__strtable_shrink_inplace(heap);\n\t\t}\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"no need for strtable resize\"));\n\t}\n\n\theap->st_resizing = 0;\n}\n#endif  /* DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Torture grow/shrink: unconditionally grow and shrink back.\n */\n\n#if defined(DUK_USE_STRTAB_TORTURE) && defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL void duk__strtable_resize_torture(duk_heap *heap) {\n\tduk_uint32_t old_st_size;\n\n\tDUK_ASSERT(heap != NULL);\n\n\told_st_size = heap->st_size;\n\tif (old_st_size >= DUK_USE_STRTAB_MAXSIZE) {\n\t\treturn;\n\t}\n\n\theap->st_resizing = 1;\n\tduk__strtable_grow_inplace(heap);\n\tif (heap->st_size > old_st_size) {\n\t\tduk__strtable_shrink_inplace(heap);\n\t}\n\theap->st_resizing = 0;\n}\n#endif  /* DUK_USE_STRTAB_TORTURE && DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Raw intern; string already checked not to be present.\n */\n\nDUK_LOCAL duk_hstring *duk__strtable_do_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen, duk_uint32_t strhash) {\n\tduk_hstring *res;\n\tconst duk_uint8_t *extdata;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *slot;\n#else\n\tduk_hstring **slot;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"do_intern: heap=%p, str=%p, blen=%lu, strhash=%lx, st_size=%lu, st_count=%lu, load=%lf\",\n\t                     (void *) heap, (const void *) str, (unsigned long) blen, (unsigned long) strhash,\n\t                     (unsigned long) heap->st_size, (unsigned long) heap->st_count,\n\t                     (double) heap->st_count / (double) heap->st_size));\n\n\tDUK_ASSERT(heap != NULL);\n\n\t/* Prevent any side effects on the string table and the caller provided\n\t * str/blen arguments while interning is in progress.  For example, if\n\t * the caller provided str/blen from a dynamic buffer, a finalizer\n\t * might resize or modify that dynamic buffer, invalidating the call\n\t * arguments.\n\t *\n\t * While finalizers must be prevented, mark-and-sweep itself is fine.\n\t * Recursive string table resize is prevented explicitly here.\n\t */\n\n\theap->pf_prevent_count++;\n\tDUK_ASSERT(heap->pf_prevent_count != 0);  /* Wrap. */\n\n#if defined(DUK_USE_STRTAB_TORTURE) && defined(DUK__STRTAB_RESIZE_CHECK)\n\tduk__strtable_resize_torture(heap);\n#endif\n\n\t/* String table grow/shrink check.  Because of chaining (and no\n\t * accumulation issues as with hash probe chains and DELETED\n\t * markers) there's never a mandatory need to resize right now.\n\t * Check for the resize only periodically, based on st_count\n\t * bit pattern.  Because string table removal doesn't do a shrink\n\t * check, we do that also here.\n\t *\n\t * Do the resize and possible grow/shrink before the new duk_hstring\n\t * has been allocated.  Otherwise we may trigger a GC when the result\n\t * duk_hstring is not yet strongly referenced.\n\t */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tif (DUK_UNLIKELY((heap->st_count & DUK_USE_STRTAB_RESIZE_CHECK_MASK) == 0)) {\n\t\tduk__strtable_resize_check(heap);\n\t}\n#endif\n\n\t/* External string check (low memory optimization). */\n\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK)\n\textdata = (const duk_uint8_t *) DUK_USE_EXTSTR_INTERN_CHECK(heap->heap_udata, (void *) DUK_LOSE_CONST(str), (duk_size_t) blen);\n#else\n\textdata = (const duk_uint8_t *) NULL;\n#endif\n\n\t/* Allocate and initialize string, not yet linked.  This may cause a\n\t * GC which may cause other strings to be interned and inserted into\n\t * the string table before we insert our string.  Finalizer execution\n\t * is disabled intentionally to avoid a finalizer from e.g. resizing\n\t * a buffer used as a data area for 'str'.\n\t */\n\n\tres = duk__strtable_alloc_hstring(heap, str, blen, strhash, extdata);\n\n\t/* Allow side effects again: GC must be avoided until duk_hstring\n\t * result (if successful) has been INCREF'd.\n\t */\n\tDUK_ASSERT(heap->pf_prevent_count > 0);\n\theap->pf_prevent_count--;\n\n\t/* Alloc error handling. */\n\n\tif (DUK_UNLIKELY(res == NULL)) {\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK)\n\t\tif (extdata != NULL) {\n\t\t\tDUK_USE_EXTSTR_FREE(heap->heap_udata, (const void *) extdata);\n\t\t}\n#endif\n\t\treturn NULL;\n\t}\n\n\t/* Insert into string table. */\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tslot = heap->strtable16 + (strhash & heap->st_mask);\n#else\n\tslot = heap->strtable + (strhash & heap->st_mask);\n#endif\n\tDUK_ASSERT(res->hdr.h_next == NULL);  /* This is the case now, but unnecessary zeroing/NULLing. */\n\tres->hdr.h_next = DUK__HEAPPTR_DEC16(heap, *slot);\n\t*slot = DUK__HEAPPTR_ENC16(heap, res);\n\n\t/* Update string count only for successful inserts. */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\theap->st_count++;\n#endif\n\n\t/* The duk_hstring is in the string table but is not yet strongly\n\t * reachable.  Calling code MUST NOT make any allocations or other\n\t * side effects before the duk_hstring has been INCREF'd and made\n\t * reachable.\n\t */\n\n\treturn res;\n}\n\n/*\n *  Intern a string from str/blen, returning either an existing duk_hstring\n *  or adding a new one into the string table.  The input string does -not-\n *  need to be NUL terminated.\n *\n *  The input 'str' argument may point to a Duktape managed data area such as\n *  the data area of a dynamic buffer.  It's crucial to avoid any side effects\n *  that might affect the data area (e.g. resize the dynamic buffer, or write\n *  to the buffer) before the string is fully interned.\n */\n\n#if defined(DUK_USE_ROM_STRINGS)\nDUK_LOCAL duk_hstring *duk__strtab_romstring_lookup(duk_heap *heap, const duk_uint8_t *str, duk_size_t blen, duk_uint32_t strhash) {\n\tduk_size_t lookup_hash;\n\tduk_hstring *curr;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_UNREF(heap);\n\n\tlookup_hash = (blen << 4);\n\tif (blen > 0) {\n\t\tlookup_hash += str[0];\n\t}\n\tlookup_hash &= 0xff;\n\n\tcurr = (duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_lookup[lookup_hash]);\n\twhile (curr != NULL) {\n\t\t/* Unsafe memcmp() because for zero blen, str may be NULL. */\n\t\tif (strhash == DUK_HSTRING_GET_HASH(curr) &&\n\t\t    blen == DUK_HSTRING_GET_BYTELEN(curr) &&\n\t\t    duk_memcmp_unsafe((const void *) str, (const void *) DUK_HSTRING_GET_DATA(curr), blen) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"intern check: rom string: %!O, computed hash 0x%08lx, rom hash 0x%08lx\",\n\t\t\t                     curr, (unsigned long) strhash, (unsigned long) DUK_HSTRING_GET_HASH(curr)));\n\t\t\treturn curr;\n\t\t}\n\t\tcurr = curr->hdr.h_next;\n\t}\n\n\treturn NULL;\n}\n#endif  /* DUK_USE_ROM_STRINGS */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uint32_t strhash;\n\tduk_hstring *h;\n\n\tDUK_DDD(DUK_DDDPRINT(\"intern check: heap=%p, str=%p, blen=%lu\", (void *) heap, (const void *) str, (unsigned long) blen));\n\n\t/* Preliminaries. */\n\n\t/* XXX: maybe just require 'str != NULL' even for zero size? */\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(blen == 0 || str != NULL);\n\tDUK_ASSERT(blen <= DUK_HSTRING_MAX_BYTELEN);  /* Caller is responsible for ensuring this. */\n\tstrhash = duk_heap_hashstring(heap, str, (duk_size_t) blen);\n\n\t/* String table lookup. */\n\n\tDUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL);\n\tDUK_ASSERT(heap->st_size > 0);\n\tDUK_ASSERT(heap->st_size == heap->st_mask + 1);\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\th = DUK__HEAPPTR_DEC16(heap, heap->strtable16[strhash & heap->st_mask]);\n#else\n\th = heap->strtable[strhash & heap->st_mask];\n#endif\n\twhile (h != NULL) {\n\t\tif (DUK_HSTRING_GET_HASH(h) == strhash &&\n\t\t    DUK_HSTRING_GET_BYTELEN(h) == blen &&\n\t\t    duk_memcmp_unsafe((const void *) str, (const void *) DUK_HSTRING_GET_DATA(h), (size_t) blen) == 0) {\n\t\t\t/* Found existing entry. */\n\t\t\tDUK_STATS_INC(heap, stats_strtab_intern_hit);\n\t\t\treturn h;\n\t\t}\n\t\th = h->hdr.h_next;\n\t}\n\n\t/* ROM table lookup.  Because this lookup is slower, do it only after\n\t * RAM lookup.  This works because no ROM string is ever interned into\n\t * the RAM string table.\n\t */\n\n#if defined(DUK_USE_ROM_STRINGS)\n\th = duk__strtab_romstring_lookup(heap, str, blen, strhash);\n\tif (h != NULL) {\n\t\tDUK_STATS_INC(heap, stats_strtab_intern_hit);\n\t\treturn h;\n\t}\n#endif\n\n\t/* Not found in string table; insert. */\n\n\tDUK_STATS_INC(heap, stats_strtab_intern_miss);\n\th = duk__strtable_do_intern(heap, str, blen, strhash);\n\treturn h;  /* may be NULL */\n}\n\n/*\n *  Intern a string from u32.\n */\n\n/* XXX: Could arrange some special handling because we know that the result\n * will have an arridx flag and an ASCII flag, won't need a clen check, etc.\n */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_u32(duk_heap *heap, duk_uint32_t val) {\n\tduk_uint8_t buf[DUK__STRTAB_U32_MAX_STRLEN];\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT(heap != NULL);\n\n\t/* This is smaller and faster than a %lu sprintf. */\n\tp = buf + sizeof(buf);\n\tdo {\n\t\tp--;\n\t\t*p = duk_lc_digits[val % 10];\n\t\tval = val / 10;\n\t} while (val != 0);  /* For val == 0, emit exactly one '0'. */\n\tDUK_ASSERT(p >= buf);\n\n\treturn duk_heap_strtable_intern(heap, (const duk_uint8_t *) p, (duk_uint32_t) ((buf + sizeof(buf)) - p));\n}\n\n/*\n *  Checked convenience variants.\n *\n *  XXX: Because the main use case is for the checked variants, make them the\n *  main functionality and provide a safe variant separately (it is only needed\n *  during heap init).  The problem with that is that longjmp state and error\n *  creation must already be possible to throw.\n */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_hstring *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(blen == 0 || str != NULL);\n\n\tres = duk_heap_strtable_intern(thr->heap, str, blen);\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn res;\n}\n\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_LOCAL duk_uint_t duk__strtable_litcache_key(const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uintptr_t key;\n\n\tDUK_ASSERT(DUK_USE_LITCACHE_SIZE > 0);\n\tDUK_ASSERT(DUK_IS_POWER_OF_TWO((duk_uint_t) DUK_USE_LITCACHE_SIZE));\n\n\tkey = (duk_uintptr_t) blen ^ (duk_uintptr_t) str;\n\tkey &= (duk_uintptr_t) (DUK_USE_LITCACHE_SIZE - 1);  /* Assumes size is power of 2. */\n\t/* Due to masking, cast is in 32-bit range. */\n\tDUK_ASSERT(key <= DUK_UINT_MAX);\n\treturn (duk_uint_t) key;\n}\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_literal_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uint_t key;\n\tduk_litcache_entry *ent;\n\tduk_hstring *h;\n\n\t/* Fast path check: literal exists in literal cache. */\n\tkey = duk__strtable_litcache_key(str, blen);\n\tent = thr->heap->litcache + key;\n\tif (ent->addr == str) {\n\t\tDUK_DD(DUK_DDPRINT(\"intern check for cached, pinned literal: str=%p, blen=%ld -> duk_hstring %!O\",\n\t\t                   (const void *) str, (long) blen, (duk_heaphdr *) ent->h));\n\t\tDUK_ASSERT(ent->h != NULL);\n\t\tDUK_ASSERT(DUK_HSTRING_HAS_PINNED_LITERAL(ent->h));\n\t\tDUK_STATS_INC(thr->heap, stats_strtab_litcache_hit);\n\t\treturn ent->h;\n\t}\n\n\t/* Intern and update (overwrite) cache entry. */\n\th = duk_heap_strtable_intern_checked(thr, str, blen);\n\tent->addr = str;\n\tent->h = h;\n\tDUK_STATS_INC(thr->heap, stats_strtab_litcache_miss);\n\n\t/* Pin the duk_hstring until the next mark-and-sweep.  This means\n\t * litcache entries don't need to be invalidated until the next\n\t * mark-and-sweep as their target duk_hstring is not freed before\n\t * the mark-and-sweep happens.  The pin remains even if the literal\n\t * cache entry is overwritten, and is still useful to avoid string\n\t * table traffic.\n\t */\n\tif (!DUK_HSTRING_HAS_PINNED_LITERAL(h)) {\n\t\tDUK_DD(DUK_DDPRINT(\"pin duk_hstring because it is a literal: %!O\", (duk_heaphdr *) h));\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h));\n\t\tDUK_HSTRING_INCREF(thr, h);\n\t\tDUK_HSTRING_SET_PINNED_LITERAL(h);\n\t\tDUK_STATS_INC(thr->heap, stats_strtab_litcache_pin);\n\t}\n\n\treturn h;\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_u32_checked(duk_hthread *thr, duk_uint32_t val) {\n\tduk_hstring *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tres = duk_heap_strtable_intern_u32(thr->heap, val);\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn res;\n}\n\n/*\n *  Remove (unlink) a string from the string table.\n *\n *  Just unlinks the duk_hstring, leaving link pointers as garbage.\n *  Caller must free the string itself.\n */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n/* Unlink without a 'prev' pointer. */\nDUK_INTERNAL void duk_heap_strtable_unlink(duk_heap *heap, duk_hstring *h) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *slot;\n#else\n\tduk_hstring **slot;\n#endif\n\tduk_hstring *other;\n\tduk_hstring *prev;\n\n\tDUK_DDD(DUK_DDDPRINT(\"remove: heap=%p, h=%p, blen=%lu, strhash=%lx\",\n\t                     (void *) heap, (void *) h,\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_BYTELEN(h) : 0),\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_HASH(h) : 0)));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tDUK_ASSERT(heap->st_count > 0);\n\theap->st_count--;\n#endif\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tslot = heap->strtable16 + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#else\n\tslot = heap->strtable + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#endif\n\tother = DUK__HEAPPTR_DEC16(heap, *slot);\n\tDUK_ASSERT(other != NULL);  /* At least argument string is in the chain. */\n\n\tprev = NULL;\n\twhile (other != h) {\n\t\tprev = other;\n\t\tother = other->hdr.h_next;\n\t\tDUK_ASSERT(other != NULL);  /* We'll eventually find 'h'. */\n\t}\n\tif (prev != NULL) {\n\t\t/* Middle of list. */\n\t\tprev->hdr.h_next = h->hdr.h_next;\n\t} else {\n\t\t/* Head of list. */\n\t\t*slot = DUK__HEAPPTR_ENC16(heap, h->hdr.h_next);\n\t}\n\n\t/* There's no resize check on a string free.  The next string\n\t * intern will do one.\n\t */\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/* Unlink with a 'prev' pointer. */\nDUK_INTERNAL void duk_heap_strtable_unlink_prev(duk_heap *heap, duk_hstring *h, duk_hstring *prev) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *slot;\n#else\n\tduk_hstring **slot;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"remove: heap=%p, prev=%p, h=%p, blen=%lu, strhash=%lx\",\n\t                     (void *) heap, (void *) prev, (void *) h,\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_BYTELEN(h) : 0),\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_HASH(h) : 0)));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(prev == NULL || prev->hdr.h_next == h);\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tDUK_ASSERT(heap->st_count > 0);\n\theap->st_count--;\n#endif\n\n\tif (prev != NULL) {\n\t\t/* Middle of list. */\n\t\tprev->hdr.h_next = h->hdr.h_next;\n\t} else {\n\t\t/* Head of list. */\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\tslot = heap->strtable16 + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#else\n\t\tslot = heap->strtable + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#endif\n\t\tDUK_ASSERT(DUK__HEAPPTR_DEC16(heap, *slot) == h);\n\t\t*slot = DUK__HEAPPTR_ENC16(heap, h->hdr.h_next);\n\t}\n}\n\n/*\n *  Force string table resize check in mark-and-sweep.\n */\n\nDUK_INTERNAL void duk_heap_strtable_force_resize(duk_heap *heap) {\n\t/* Does only one grow/shrink step if needed.  The heap->st_resizing\n\t * flag protects against recursive resizing.\n\t */\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_UNREF(heap);\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tif (heap->strtable16 != NULL) {\n#else\n\tif (heap->strtable != NULL) {\n#endif\n\t\tduk__strtable_resize_check(heap);\n\t}\n#endif\n}\n\n/*\n *  Free strings in the string table and the string table itself.\n */\n\nDUK_INTERNAL void duk_heap_strtable_free(duk_heap *heap) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable;\n\tduk_uint16_t *st;\n#else\n\tduk_hstring **strtable;\n\tduk_hstring **st;\n#endif\n\tduk_hstring *h;\n\n\tDUK_ASSERT(heap != NULL);\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__strtable_assert_checks(heap);\n#endif\n\n\t/* Strtable can be NULL if heap init fails.  However, in that case\n\t * heap->st_size is 0, so strtable == strtable_end and we skip the\n\t * loop without a special check.\n\t */\n\tstrtable = DUK__GET_STRTABLE(heap);\n\tst = strtable + heap->st_size;\n\tDUK_ASSERT(strtable != NULL || heap->st_size == 0);\n\n\twhile (strtable != st) {\n\t\t--st;\n\t\th = DUK__HEAPPTR_DEC16(heap, *st);\n\t\twhile (h) {\n\t\t\tduk_hstring *h_next;\n\t\t\th_next = h->hdr.h_next;\n\n\t\t\t/* Strings may have inner refs (extdata) in some cases. */\n\t\t\tduk_free_hstring(heap, h);\n\n\t\t\th = h_next;\n\t\t}\n\t}\n\n\tDUK_FREE(heap, strtable);\n}\n\n/* automatic undefs */\n#undef DUK__GET_STRTABLE\n#undef DUK__HEAPPTR_DEC16\n#undef DUK__HEAPPTR_ENC16\n#undef DUK__STRTAB_U32_MAX_STRLEN\n/*\n *  duk_heaphdr assertion helpers\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ASSERTIONS)\n\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\nDUK_INTERNAL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tif (h != NULL) {\n\t\tduk_heaphdr *h_prev, *h_next;\n\t\th_prev = DUK_HEAPHDR_GET_PREV(heap, h);\n\t\th_next = DUK_HEAPHDR_GET_NEXT(heap, h);\n\t\tDUK_ASSERT(h_prev == NULL || (DUK_HEAPHDR_GET_NEXT(heap, h_prev) == h));\n\t\tDUK_ASSERT(h_next == NULL || (DUK_HEAPHDR_GET_PREV(heap, h_next) == h));\n\t}\n}\n#else\nDUK_INTERNAL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tDUK_UNREF(h);\n}\n#endif\n\nDUK_INTERNAL void duk_heaphdr_assert_valid(duk_heaphdr *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n}\n\n/* Assert validity of a heaphdr, including all subclasses. */\nDUK_INTERNAL void duk_heaphdr_assert_valid_subclassed(duk_heaphdr *h) {\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h_obj = (duk_hobject *) h;\n\t\tDUK_HOBJECT_ASSERT_VALID(h_obj);\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tDUK_HCOMPFUNC_ASSERT_VALID((duk_hcompfunc *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h_obj)) {\n\t\t\tDUK_HNATFUNC_ASSERT_VALID((duk_hnatfunc *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_DECENV(h_obj)) {\n\t\t\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_OBJENV(h_obj)) {\n\t\t\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID((duk_hbufobj *) h_obj);\n#endif\n\t\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h_obj)) {\n\t\t\tDUK_HBOUNDFUNC_ASSERT_VALID((duk_hboundfunc *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_PROXY(h_obj)) {\n\t\t\tDUK_HPROXY_ASSERT_VALID((duk_hproxy *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_THREAD(h_obj)) {\n\t\t\tDUK_HTHREAD_ASSERT_VALID((duk_hthread *) h_obj);\n\t\t} else {\n\t\t\t/* Just a plain object. */\n\t\t\t;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h_str = (duk_hstring *) h;\n\t\tDUK_HSTRING_ASSERT_VALID(h_str);\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h_buf = (duk_hbuffer *) h;\n\t\tDUK_HBUFFER_ASSERT_VALID(h_buf);\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tDUK_ASSERT(0);\n\t}\n\t}\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n/*\n *  Hobject allocation.\n *\n *  Provides primitive allocation functions for all object types (plain object,\n *  compiled function, native function, thread).  The object return is not yet\n *  in \"heap allocated\" list and has a refcount of zero, so caller must careful.\n */\n\n/* XXX: In most cases there's no need for plain allocation without pushing\n * to the value stack.  Maybe rework contract?\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Helpers.\n */\n\nDUK_LOCAL void duk__init_object_parts(duk_heap *heap, duk_uint_t hobject_flags, duk_hobject *obj) {\n\tDUK_ASSERT(obj != NULL);\n\t/* Zeroed by caller. */\n\n\tobj->hdr.h_flags = hobject_flags | DUK_HTYPE_OBJECT;\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(&obj->hdr) == DUK_HTYPE_OBJECT);  /* Assume zero shift. */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tDUK_HOBJECT_SET_PROTOTYPE(heap, obj, NULL);\n\tDUK_HOBJECT_SET_PROPS(heap, obj, NULL);\n#endif\n#if defined(DUK_USE_HEAPPTR16)\n\t/* Zero encoded pointer is required to match NULL. */\n\tDUK_HEAPHDR_SET_NEXT(heap, &obj->hdr, NULL);\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tDUK_HEAPHDR_SET_PREV(heap, &obj->hdr, NULL);\n#endif\n#endif\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, &obj->hdr);\n\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &obj->hdr);\n\n\t/* obj->props is intentionally left as NULL, and duk_hobject_props.c must deal\n\t * with this properly.  This is intentional: empty objects consume a minimum\n\t * amount of memory.  Further, an initial allocation might fail and cause\n\t * 'obj' to \"leak\" (require a mark-and-sweep) since it is not reachable yet.\n\t */\n}\n\nDUK_LOCAL void *duk__hobject_alloc_init(duk_hthread *thr, duk_uint_t hobject_flags, duk_size_t size) {\n\tvoid *res;\n\n\tres = (void *) DUK_ALLOC_CHECKED_ZEROED(thr, size);\n\tDUK_ASSERT(res != NULL);\n\tduk__init_object_parts(thr->heap, hobject_flags, (duk_hobject *) res);\n\treturn res;\n}\n\n/*\n *  Allocate an duk_hobject.\n *\n *  The allocated object has no allocation for properties; the caller may\n *  want to force a resize if a desired size is known.\n *\n *  The allocated object has zero reference count and is not reachable.\n *  The caller MUST make the object reachable and increase its reference\n *  count before invoking any operation that might require memory allocation.\n */\n\nDUK_INTERNAL duk_hobject *duk_hobject_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags) {\n\tduk_hobject *res;\n\n\tDUK_ASSERT(heap != NULL);\n\n\t/* different memory layout, alloc size, and init */\n\tDUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_COMPFUNC) == 0);\n\tDUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_NATFUNC) == 0);\n\tDUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_BOUNDFUNC) == 0);\n\n\tres = (duk_hobject *) DUK_ALLOC_ZEROED(heap, sizeof(duk_hobject));\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\treturn NULL;\n\t}\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(res));\n\n\tduk__init_object_parts(heap, hobject_flags, res);\n\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(res));\n\treturn res;\n}\n\nDUK_INTERNAL duk_hobject *duk_hobject_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hobject *res;\n\n\tres = (duk_hobject *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hobject));\n\treturn res;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_hcompfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hcompfunc *res;\n\n\tres = (duk_hcompfunc *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hcompfunc));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_HEAPPTR16)\n\t/* NULL pointer is required to encode to zero, so memset is enough. */\n#else\n\tres->data = NULL;\n\tres->funcs = NULL;\n\tres->bytecode = NULL;\n#endif\n\tres->lex_env = NULL;\n\tres->var_env = NULL;\n#endif\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_hnatfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hnatfunc *res;\n\n\tres = (duk_hnatfunc *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hnatfunc));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->func = NULL;\n#endif\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hboundfunc *duk_hboundfunc_alloc(duk_heap *heap, duk_uint_t hobject_flags) {\n\tduk_hboundfunc *res;\n\n\tres = (duk_hboundfunc *) DUK_ALLOC(heap, sizeof(duk_hboundfunc));\n\tif (!res) {\n\t\treturn NULL;\n\t}\n\tduk_memzero(res, sizeof(duk_hboundfunc));\n\n\tduk__init_object_parts(heap, hobject_flags, &res->obj);\n\n\tDUK_TVAL_SET_UNDEFINED(&res->target);\n\tDUK_TVAL_SET_UNDEFINED(&res->this_binding);\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->args = NULL;\n#endif\n\n\treturn res;\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_hbufobj *duk_hbufobj_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hbufobj *res;\n\n\tres = (duk_hbufobj *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hbufobj));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->buf = NULL;\n\tres->buf_prop = NULL;\n#endif\n\n\tDUK_HBUFOBJ_ASSERT_VALID(res);\n\treturn res;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* Allocate a new thread.\n *\n * Leaves the built-ins array uninitialized.  The caller must either\n * initialize a new global context or share existing built-ins from\n * another thread.\n */\nDUK_INTERNAL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags) {\n\tduk_hthread *res;\n\n\tres = (duk_hthread *) DUK_ALLOC(heap, sizeof(duk_hthread));\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\treturn NULL;\n\t}\n\tduk_memzero(res, sizeof(duk_hthread));\n\n\tduk__init_object_parts(heap, hobject_flags, &res->obj);\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->ptr_curr_pc = NULL;\n\tres->heap = NULL;\n\tres->valstack = NULL;\n\tres->valstack_end = NULL;\n\tres->valstack_alloc_end = NULL;\n\tres->valstack_bottom = NULL;\n\tres->valstack_top = NULL;\n\tres->callstack_curr = NULL;\n\tres->resumer = NULL;\n\tres->compile_ctx = NULL,\n#if defined(DUK_USE_HEAPPTR16)\n\tres->strs16 = NULL;\n#else\n\tres->strs = NULL;\n#endif\n\t{\n\t\tduk_small_uint_t i;\n\t\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\t\tres->builtins[i] = NULL;\n\t\t}\n\t}\n#endif\n\t/* When nothing is running, API calls are in non-strict mode. */\n\tDUK_ASSERT(res->strict == 0);\n\n\tres->heap = heap;\n\n\t/* XXX: Any reason not to merge duk_hthread_alloc.c here? */\n\treturn res;\n}\n\nDUK_INTERNAL duk_hthread *duk_hthread_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hthread *res;\n\n\tres = duk_hthread_alloc_unchecked(thr->heap, hobject_flags);\n\tif (res == NULL) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn res;\n}\n\nDUK_INTERNAL duk_harray *duk_harray_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_harray *res;\n\n\tres = (duk_harray *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_harray));\n\n\tDUK_ASSERT(res->length == 0);\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hdecenv *duk_hdecenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hdecenv *res;\n\n\tres = (duk_hdecenv *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hdecenv));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->thread = NULL;\n\tres->varmap = NULL;\n#endif\n\n\tDUK_ASSERT(res->thread == NULL);\n\tDUK_ASSERT(res->varmap == NULL);\n\tDUK_ASSERT(res->regbase_byteoff == 0);\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hobjenv *duk_hobjenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hobjenv *res;\n\n\tres = (duk_hobjenv *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hobjenv));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->target = NULL;\n#endif\n\n\tDUK_ASSERT(res->target == NULL);\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hproxy *duk_hproxy_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hproxy *res;\n\n\tres = (duk_hproxy *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hproxy));\n\n\t/* Leave ->target and ->handler uninitialized, as caller will always\n\t * explicitly initialize them before any side effects are possible.\n\t */\n\n\treturn res;\n}\n/*\n *  duk_hobject and subclass assertion helpers\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ASSERTIONS)\n\nDUK_INTERNAL void duk_hobject_assert_valid(duk_hobject *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE(h) ||\n\t           DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FUNCTION);\n\tDUK_ASSERT(!DUK_HOBJECT_IS_BUFOBJ(h) ||\n\t           (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAYBUFFER ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_DATAVIEW ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT8ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT8ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT16ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT16ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT32ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT32ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FLOAT32ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FLOAT64ARRAY));\n\t/* Object is an Array <=> object has exotic array behavior */\n\tDUK_ASSERT((DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY && DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)) ||\n\t           (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_ARRAY && !DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)));\n}\n\nDUK_INTERNAL void duk_harray_assert_valid(duk_harray *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) h));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY((duk_hobject *) h));\n}\n\nDUK_INTERNAL void duk_hboundfunc_assert_valid(duk_hboundfunc *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_BOUNDFUNC((duk_hobject *) h));\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(&h->target) ||\n\t           (DUK_TVAL_IS_OBJECT(&h->target) &&\n\t            DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(&h->target))));\n\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(&h->this_binding));\n\tDUK_ASSERT(h->nargs == 0 || h->args != NULL);\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL void duk_hbufobj_assert_valid(duk_hbufobj *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(h->shift <= 3);\n\tDUK_ASSERT(h->elem_type <= DUK_HBUFOBJ_ELEM_MAX);\n\tDUK_ASSERT((h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT8) ||\n\t           (h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT8CLAMPED) ||\n\t           (h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_INT8) ||\n\t           (h->shift == 1 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT16) ||\n\t           (h->shift == 1 && h->elem_type == DUK_HBUFOBJ_ELEM_INT16) ||\n\t           (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT32) ||\n\t           (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_INT32) ||\n\t           (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_FLOAT32) ||\n\t           (h->shift == 3 && h->elem_type == DUK_HBUFOBJ_ELEM_FLOAT64));\n\tDUK_ASSERT(h->is_typedarray == 0 || h->is_typedarray == 1);\n\tDUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h));\n\tif (h->buf == NULL) {\n\t\tDUK_ASSERT(h->offset == 0);\n\t\tDUK_ASSERT(h->length == 0);\n\t} else {\n\t\t/* No assertions for offset or length; in particular,\n\t\t * it's OK for length to be longer than underlying\n\t\t * buffer.  Just ensure they don't wrap when added.\n\t\t */\n\t\tDUK_ASSERT(h->offset + h->length >= h->offset);\n\t}\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_INTERNAL void duk_hcompfunc_assert_valid(duk_hcompfunc *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\nDUK_INTERNAL void duk_hnatfunc_assert_valid(duk_hnatfunc *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\nDUK_INTERNAL void duk_hdecenv_assert_valid(duk_hdecenv *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_DECENV((duk_hobject *) h));\n\tDUK_ASSERT(h->thread == NULL || h->varmap != NULL);\n}\n\nDUK_INTERNAL void duk_hobjenv_assert_valid(duk_hobjenv *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_OBJENV((duk_hobject *) h));\n\tDUK_ASSERT(h->target != NULL);\n\tDUK_ASSERT(h->has_this == 0 || h->has_this == 1);\n}\n\nDUK_INTERNAL void duk_hproxy_assert_valid(duk_hproxy *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(h->target != NULL);\n\tDUK_ASSERT(h->handler != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ((duk_hobject *) h));\n}\n\nDUK_INTERNAL void duk_hthread_assert_valid(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) thr) == DUK_HTYPE_OBJECT);\n\tDUK_ASSERT(DUK_HOBJECT_IS_THREAD((duk_hobject *) thr));\n\tDUK_ASSERT(thr->unused1 == 0);\n\tDUK_ASSERT(thr->unused2 == 0);\n}\n\nDUK_INTERNAL void duk_ctx_assert_valid(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_HTHREAD_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack != NULL);\n\tDUK_ASSERT(thr->valstack_bottom != NULL);\n\tDUK_ASSERT(thr->valstack_top != NULL);\n\tDUK_ASSERT(thr->valstack_end != NULL);\n\tDUK_ASSERT(thr->valstack_alloc_end != NULL);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n/*\n *  Object enumeration support.\n *\n *  Creates an internal enumeration state object to be used e.g. with for-in\n *  enumeration.  The state object contains a snapshot of target object keys\n *  and internal control state for enumeration.  Enumerator flags allow caller\n *  to e.g. request internal/non-enumerable properties, and to enumerate only\n *  \"own\" properties.\n *\n *  Also creates the result value for e.g. Object.keys() based on the same\n *  internal structure.\n *\n *  This snapshot-based enumeration approach is used to simplify enumeration:\n *  non-snapshot-based approaches are difficult to reconcile with mutating\n *  the enumeration target, running multiple long-lived enumerators at the\n *  same time, garbage collection details, etc.  The downside is that the\n *  enumerator object is memory inefficient especially for iterating arrays.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* XXX: identify enumeration target with an object index (not top of stack) */\n\n/* First enumerated key index in enumerator object, must match exactly the\n * number of control properties inserted to the enumerator.\n */\n#define DUK__ENUM_START_INDEX  2\n\n/* Current implementation suffices for ES2015 for now because there's no symbol\n * sorting, so commented out for now.\n */\n\n/*\n *  Helper to sort enumeration keys using a callback for pairwise duk_hstring\n *  comparisons.  The keys are in the enumeration object entry part, starting\n *  from DUK__ENUM_START_INDEX, and the entry part is dense.  Entry part values\n *  are all \"true\", e.g. \"1\" -> true, \"3\" -> true, \"foo\" -> true, \"2\" -> true,\n *  so it suffices to just switch keys without switching values.\n *\n *  ES2015 [[OwnPropertyKeys]] enumeration order for ordinary objects:\n *  (1) array indices in ascending order,\n *  (2) non-array-index keys in insertion order, and\n *  (3) symbols in insertion order.\n *  http://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys.\n *\n *  This rule is applied to \"own properties\" at each inheritance level;\n *  non-duplicate parent keys always follow child keys.  For example,\n *  an inherited array index will enumerate -after- a symbol in the\n *  child.\n *\n *  Insertion sort is used because (1) it's simple and compact, (2) works\n *  in-place, (3) minimizes operations if data is already nearly sorted,\n *  (4) doesn't reorder elements considered equal.\n *  http://en.wikipedia.org/wiki/Insertion_sort\n */\n\n/* Sort key, must hold array indices, \"not array index\" marker, and one more\n * higher value for symbols.\n */\n#if !defined(DUK_USE_SYMBOL_BUILTIN)\ntypedef duk_uint32_t duk__sort_key_t;\n#elif defined(DUK_USE_64BIT_OPS)\ntypedef duk_uint64_t duk__sort_key_t;\n#else\ntypedef duk_double_t duk__sort_key_t;\n#endif\n\n/* Get sort key for a duk_hstring. */\nDUK_LOCAL duk__sort_key_t duk__hstring_sort_key(duk_hstring *x) {\n\tduk__sort_key_t val;\n\n\t/* For array indices [0,0xfffffffe] use the array index as is.\n\t * For strings, use 0xffffffff, the marker 'arridx' already in\n\t * duk_hstring.  For symbols, any value above 0xffffffff works,\n\t * as long as it is the same for all symbols; currently just add\n\t * the masked flag field into the arridx temporary.\n\t */\n\tDUK_ASSERT(x != NULL);\n\tDUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(x) || DUK_HSTRING_GET_ARRIDX_FAST(x) == DUK_HSTRING_NO_ARRAY_INDEX);\n\n\tval = (duk__sort_key_t) DUK_HSTRING_GET_ARRIDX_FAST(x);\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\tval = val + (duk__sort_key_t) (DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) x) & DUK_HSTRING_FLAG_SYMBOL);\n#endif\n\n\treturn (duk__sort_key_t) val;\n}\n\n/* Insert element 'b' after element 'a'? */\nDUK_LOCAL duk_bool_t duk__sort_compare_es6(duk_hstring *a, duk_hstring *b, duk__sort_key_t val_b) {\n\tduk__sort_key_t val_a;\n\n\tDUK_ASSERT(a != NULL);\n\tDUK_ASSERT(b != NULL);\n\tDUK_UNREF(b);  /* Not actually needed now, val_b suffices. */\n\n\tval_a = duk__hstring_sort_key(a);\n\n\tif (val_a > val_b) {\n\t\treturn 0;\n\t} else {\n\t\treturn 1;\n\t}\n}\n\nDUK_LOCAL void duk__sort_enum_keys_es6(duk_hthread *thr, duk_hobject *h_obj, duk_int_fast32_t idx_start, duk_int_fast32_t idx_end) {\n\tduk_hstring **keys;\n\tduk_int_fast32_t idx;\n\n\tDUK_ASSERT(h_obj != NULL);\n\tDUK_ASSERT(idx_start >= DUK__ENUM_START_INDEX);\n\tDUK_ASSERT(idx_end >= idx_start);\n\tDUK_UNREF(thr);\n\n\tif (idx_end <= idx_start + 1) {\n\t\treturn;  /* Zero or one element(s). */\n\t}\n\n\tkeys = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, h_obj);\n\n\tfor (idx = idx_start + 1; idx < idx_end; idx++) {\n\t\tduk_hstring *h_curr;\n\t\tduk_int_fast32_t idx_insert;\n\t\tduk__sort_key_t val_curr;\n\n\t\th_curr = keys[idx];\n\t\tDUK_ASSERT(h_curr != NULL);\n\n\t\t/* Scan backwards for insertion place.  This works very well\n\t\t * when the elements are nearly in order which is the common\n\t\t * (and optimized for) case.\n\t\t */\n\n\t\tval_curr = duk__hstring_sort_key(h_curr);  /* Remains same during scanning. */\n\t\tfor (idx_insert = idx - 1; idx_insert >= idx_start; idx_insert--) {\n\t\t\tduk_hstring *h_insert;\n\t\t\th_insert = keys[idx_insert];\n\t\t\tDUK_ASSERT(h_insert != NULL);\n\n\t\t\tif (duk__sort_compare_es6(h_insert, h_curr, val_curr)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t/* If we're out of indices, idx_insert == idx_start - 1 and idx_insert++\n\t\t * brings us back to idx_start.\n\t\t */\n\t\tidx_insert++;\n\t\tDUK_ASSERT(idx_insert >= 0 && idx_insert <= idx);\n\n\t\t/*        .-- p_insert   .-- p_curr\n\t\t *        v              v\n\t\t *  | ... | insert | ... | curr\n\t\t */\n\n\t\t/* This could also done when the keys are in order, i.e.\n\t\t * idx_insert == idx.  The result would be an unnecessary\n\t\t * memmove() but we use an explicit check because the keys\n\t\t * are very often in order already.\n\t\t */\n\t\tif (idx != idx_insert) {\n\t\t\tduk_memmove((void *) (keys + idx_insert + 1),\n\t\t\t            (const void *) (keys + idx_insert),\n\t\t\t            ((size_t) (idx - idx_insert) * sizeof(duk_hstring *)));\n\t\t\tkeys[idx_insert] = h_curr;\n\t\t}\n\t}\n}\n\n/*\n *  Create an internal enumerator object E, which has its keys ordered\n *  to match desired enumeration ordering.  Also initialize internal control\n *  properties for enumeration.\n *\n *  Note: if an array was used to hold enumeration keys instead, an array\n *  scan would be needed to eliminate duplicates found in the prototype chain.\n */\n\nDUK_LOCAL void duk__add_enum_key(duk_hthread *thr, duk_hstring *k) {\n\t/* 'k' may be unreachable on entry so must push without any\n\t * potential for GC.\n\t */\n\tduk_push_hstring(thr, k);\n\tduk_push_true(thr);\n\tduk_put_prop(thr, -3);\n}\n\nDUK_LOCAL void duk__add_enum_key_stridx(duk_hthread *thr, duk_small_uint_t stridx) {\n\tduk__add_enum_key(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n}\n\nDUK_INTERNAL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint_t enum_flags) {\n\tduk_hobject *enum_target;\n\tduk_hobject *curr;\n\tduk_hobject *res;\n#if defined(DUK_USE_ES6_PROXY)\n\tduk_hobject *h_proxy_target;\n\tduk_hobject *h_proxy_handler;\n\tduk_hobject *h_trap_result;\n#endif\n\tduk_uint_fast32_t i, len;  /* used for array, stack, and entry indices */\n\tduk_uint_fast32_t sort_start_index;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tenum_target = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(enum_target != NULL);\n\n\tduk_push_bare_object(thr);\n\tres = duk_known_hobject(thr, -1);\n\n\t/* [enum_target res] */\n\n\t/* Target must be stored so that we can recheck whether or not\n\t * keys still exist when we enumerate.  This is not done if the\n\t * enumeration result comes from a proxy trap as there is no\n\t * real object to check against.\n\t */\n\tduk_push_hobject(thr, enum_target);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_TARGET);  /* Target is bare, plain put OK. */\n\n\t/* Initialize index so that we skip internal control keys. */\n\tduk_push_int(thr, DUK__ENUM_START_INDEX);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_NEXT);  /* Target is bare, plain put OK. */\n\n\t/*\n\t *  Proxy object handling\n\t */\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (DUK_LIKELY((enum_flags & DUK_ENUM_NO_PROXY_BEHAVIOR) != 0)) {\n\t\tgoto skip_proxy;\n\t}\n\tif (DUK_LIKELY(!duk_hobject_proxy_check(enum_target,\n\t                                        &h_proxy_target,\n\t                                        &h_proxy_handler))) {\n\t\tgoto skip_proxy;\n\t}\n\n\t/* XXX: share code with Object.keys() Proxy handling */\n\n\t/* In ES2015 for-in invoked the \"enumerate\" trap; in ES2016 \"enumerate\"\n\t * has been obsoleted and \"ownKeys\" is used instead.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"proxy enumeration\"));\n\tduk_push_hobject(thr, h_proxy_handler);\n\tif (!duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_OWN_KEYS)) {\n\t\t/* No need to replace the 'enum_target' value in stack, only the\n\t\t * enum_target reference.  This also ensures that the original\n\t\t * enum target is reachable, which keeps the proxy and the proxy\n\t\t * target reachable.  We do need to replace the internal _Target.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"no ownKeys trap, enumerate proxy target instead\"));\n\t\tDUK_DDD(DUK_DDDPRINT(\"h_proxy_target=%!O\", (duk_heaphdr *) h_proxy_target));\n\t\tenum_target = h_proxy_target;\n\n\t\tduk_push_hobject(thr, enum_target);  /* -> [ ... enum_target res handler undefined target ] */\n\t\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_INT_TARGET);  /* Target is bare, plain put OK. */\n\n\t\tduk_pop_2(thr);  /* -> [ ... enum_target res ] */\n\t\tgoto skip_proxy;\n\t}\n\n\t/* [ ... enum_target res handler trap ] */\n\tduk_insert(thr, -2);\n\tduk_push_hobject(thr, h_proxy_target);    /* -> [ ... enum_target res trap handler target ] */\n\tduk_call_method(thr, 1 /*nargs*/);        /* -> [ ... enum_target res trap_result ] */\n\th_trap_result = duk_require_hobject(thr, -1);\n\tDUK_UNREF(h_trap_result);\n\n\tduk_proxy_ownkeys_postprocess(thr, h_proxy_target, enum_flags);\n\t/* -> [ ... enum_target res trap_result keys_array ] */\n\n\t/* Copy cleaned up trap result keys into the enumerator object. */\n\t/* XXX: result is a dense array; could make use of that. */\n\tDUK_ASSERT(duk_is_array(thr, -1));\n\tlen = (duk_uint_fast32_t) duk_get_length(thr, -1);\n\tfor (i = 0; i < len; i++) {\n\t\t(void) duk_get_prop_index(thr, -1, (duk_uarridx_t) i);\n\t\tDUK_ASSERT(duk_is_string(thr, -1));  /* postprocess cleaned up */\n\t\t/* [ ... enum_target res trap_result keys_array val ] */\n\t\tduk_push_true(thr);\n\t\t/* [ ... enum_target res trap_result keys_array val true ] */\n\t\tduk_put_prop(thr, -5);\n\t}\n\t/* [ ... enum_target res trap_result keys_array ] */\n\tduk_pop_2(thr);\n\tduk_remove_m2(thr);\n\n\t/* [ ... res ] */\n\n\t/* The internal _Target property is kept pointing to the original\n\t * enumeration target (the proxy object), so that the enumerator\n\t * 'next' operation can read property values if so requested.  The\n\t * fact that the _Target is a proxy disables key existence check\n\t * during enumeration.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"proxy enumeration, final res: %!O\", (duk_heaphdr *) res));\n\tgoto compact_and_return;\n\n skip_proxy:\n#endif  /* DUK_USE_ES6_PROXY */\n\n\tcurr = enum_target;\n\tsort_start_index = DUK__ENUM_START_INDEX;\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(res) == DUK__ENUM_START_INDEX);\n\twhile (curr) {\n\t\tduk_uint_fast32_t sort_end_index;\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\tduk_bool_t need_sort = 0;\n#endif\n\t\tduk_bool_t cond;\n\n\t\t/* Enumeration proceeds by inheritance level.  Virtual\n\t\t * properties need to be handled specially, followed by\n\t\t * array part, and finally entry part.\n\t\t *\n\t\t * If there are array index keys in the entry part or any\n\t\t * other risk of the ES2015 [[OwnPropertyKeys]] order being\n\t\t * violated, need_sort is set and an explicit ES2015 sort is\n\t\t * done for the inheritance level.\n\t\t */\n\n\t\t/* XXX: inheriting from proxy */\n\n\t\t/*\n\t\t *  Virtual properties.\n\t\t *\n\t\t *  String and buffer indices are virtual and always enumerable,\n\t\t *  'length' is virtual and non-enumerable.  Array and arguments\n\t\t *  object props have special behavior but are concrete.\n\t\t *\n\t\t *  String and buffer objects don't have an array part so as long\n\t\t *  as virtual array index keys are enumerated first, we don't\n\t\t *  need to set need_sort.\n\t\t */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tcond = DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr) || DUK_HOBJECT_IS_BUFOBJ(curr);\n#else\n\t\tcond = DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr);\n#endif\n\t\tcond = cond && !(enum_flags & DUK_ENUM_EXCLUDE_STRINGS);\n\t\tif (cond) {\n\t\t\tduk_bool_t have_length = 1;\n\n\t\t\t/* String and buffer enumeration behavior is identical now,\n\t\t\t * so use shared handler.\n\t\t\t */\n\t\t\tif (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr)) {\n\t\t\t\tduk_hstring *h_val;\n\t\t\t\th_val = duk_hobject_get_internal_value_string(thr->heap, curr);\n\t\t\t\tDUK_ASSERT(h_val != NULL);  /* string objects must not created without internal value */\n\t\t\t\tlen = (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h_val);\n\t\t\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t\telse {\n\t\t\t\tduk_hbufobj *h_bufobj;\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ(curr));\n\t\t\t\th_bufobj = (duk_hbufobj *) curr;\n\n\t\t\t\tif (h_bufobj == NULL || !h_bufobj->is_typedarray) {\n\t\t\t\t\t/* Zero length seems like a good behavior for neutered buffers.\n\t\t\t\t\t * ArrayBuffer (non-view) and DataView don't have index properties\n\t\t\t\t\t * or .length property.\n\t\t\t\t\t */\n\t\t\t\t\tlen = 0;\n\t\t\t\t\thave_length = 0;\n\t\t\t\t} else {\n\t\t\t\t\t/* There's intentionally no check for\n\t\t\t\t\t * current underlying buffer length.\n\t\t\t\t\t */\n\t\t\t\t\tlen = (duk_uint_fast32_t) (h_bufobj->length >> h_bufobj->shift);\n\t\t\t\t}\n\t\t\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\tduk_hstring *k;\n\n\t\t\t\t/* This is a bit fragile: the string is not\n\t\t\t\t * reachable until it is pushed by the helper.\n\t\t\t\t */\n\t\t\t\tk = duk_heap_strtable_intern_u32_checked(thr, (duk_uint32_t) i);\n\t\t\t\tDUK_ASSERT(k);\n\n\t\t\t\tduk__add_enum_key(thr, k);\n\n\t\t\t\t/* [enum_target res] */\n\t\t\t}\n\n\t\t\t/* 'length' and other virtual properties are not\n\t\t\t * enumerable, but are included if non-enumerable\n\t\t\t * properties are requested.\n\t\t\t */\n\n\t\t\tif (have_length && (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE)) {\n\t\t\t\tduk__add_enum_key_stridx(thr, DUK_STRIDX_LENGTH);\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t *  Array part\n\t\t */\n\n\t\tcond = !(enum_flags & DUK_ENUM_EXCLUDE_STRINGS);\n\t\tif (cond) {\n\t\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(curr); i++) {\n\t\t\t\tduk_hstring *k;\n\t\t\t\tduk_tval *tv;\n\n\t\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, curr, i);\n\t\t\t\tif (DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tk = duk_heap_strtable_intern_u32_checked(thr, (duk_uint32_t) i);  /* Fragile reachability. */\n\t\t\t\tDUK_ASSERT(k);\n\n\t\t\t\tduk__add_enum_key(thr, k);\n\n\t\t\t\t/* [enum_target res] */\n\t\t\t}\n\n\t\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(curr)) {\n\t\t\t\t/* Array .length comes after numeric indices. */\n\t\t\t\tif (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) {\n\t\t\t\t\tduk__add_enum_key_stridx(thr, DUK_STRIDX_LENGTH);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t *  Entries part\n\t\t */\n\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(curr); i++) {\n\t\t\tduk_hstring *k;\n\n\t\t\tk = DUK_HOBJECT_E_GET_KEY(thr->heap, curr, i);\n\t\t\tif (!k) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!(enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) &&\n\t\t\t    !DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(thr->heap, curr, i)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(k))) {\n\t\t\t\tif (!(enum_flags & DUK_ENUM_INCLUDE_HIDDEN) &&\n\t\t\t\t    DUK_HSTRING_HAS_HIDDEN(k)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!(enum_flags & DUK_ENUM_INCLUDE_SYMBOLS)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t\tneed_sort = 1;\n#endif\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(!DUK_HSTRING_HAS_HIDDEN(k));  /* would also have symbol flag */\n\t\t\t\tif (enum_flags & DUK_ENUM_EXCLUDE_STRINGS) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (DUK_HSTRING_HAS_ARRIDX(k)) {\n\t\t\t\t/* This in currently only possible if the\n\t\t\t\t * object has no array part: the array part\n\t\t\t\t * is exhaustive when it is present.\n\t\t\t\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t\tneed_sort = 1;\n#endif\n\t\t\t} else {\n\t\t\t\tif (enum_flags & DUK_ENUM_ARRAY_INDICES_ONLY) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, curr, i) ||\n\t\t\t           !DUK_TVAL_IS_UNUSED(&DUK_HOBJECT_E_GET_VALUE_PTR(thr->heap, curr, i)->v));\n\n\t\t\tduk__add_enum_key(thr, k);\n\n\t\t\t/* [enum_target res] */\n\t\t}\n\n\t\t/* Sort enumerated keys according to ES2015 requirements for\n\t\t * the \"inheritance level\" just processed.  This is far from\n\t\t * optimal, ES2015 semantics could be achieved more efficiently\n\t\t * by handling array index string keys (and symbol keys)\n\t\t * specially above in effect doing the sort inline.\n\t\t *\n\t\t * Skip the sort if array index sorting is requested because\n\t\t * we must consider all keys, also inherited, so an explicit\n\t\t * sort is done for the whole result after we're done with the\n\t\t * prototype chain.\n\t\t *\n\t\t * Also skip the sort if need_sort == 0, i.e. we know for\n\t\t * certain that the enumerated order is already correct.\n\t\t */\n\t\tsort_end_index = DUK_HOBJECT_GET_ENEXT(res);\n\n\t\tif (!(enum_flags & DUK_ENUM_SORT_ARRAY_INDICES)) {\n#if defined(DUK_USE_PREFER_SIZE)\n\t\t\tduk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) sort_start_index, (duk_int_fast32_t) sort_end_index);\n#else\n\t\t\tif (need_sort) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"need to sort\"));\n\t\t\t\tduk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) sort_start_index, (duk_int_fast32_t) sort_end_index);\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"no need to sort\"));\n\t\t\t}\n#endif\n\t\t}\n\n\t\tsort_start_index = sort_end_index;\n\n\t\tif (enum_flags & DUK_ENUM_OWN_PROPERTIES_ONLY) {\n\t\t\tbreak;\n\t\t}\n\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t}\n\n\t/* [enum_target res] */\n\n\tduk_remove_m2(thr);\n\n\t/* [res] */\n\n\tif (enum_flags & DUK_ENUM_SORT_ARRAY_INDICES) {\n\t\t/* Some E5/E5.1 algorithms require that array indices are iterated\n\t\t * in a strictly ascending order.  This is the case for e.g.\n\t\t * Array.prototype.forEach() and JSON.stringify() PropertyList\n\t\t * handling.  The caller can request an explicit sort in these\n\t\t * cases.\n\t\t */\n\n\t\t/* Sort to ES2015 order which works for pure array incides but\n\t\t * also for mixed keys.\n\t\t */\n\t\tduk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) DUK__ENUM_START_INDEX, (duk_int_fast32_t) DUK_HOBJECT_GET_ENEXT(res));\n\t}\n\n#if defined(DUK_USE_ES6_PROXY)\n compact_and_return:\n#endif\n\t/* compact; no need to seal because object is internal */\n\tduk_hobject_compact_props(thr, res);\n\n\tDUK_DDD(DUK_DDDPRINT(\"created enumerator object: %!iT\", (duk_tval *) duk_get_tval(thr, -1)));\n}\n\n/*\n *  Returns non-zero if a key and/or value was enumerated, and:\n *\n *   [enum] -> [key]        (get_value == 0)\n *   [enum] -> [key value]  (get_value == 1)\n *\n *  Returns zero without pushing anything on the stack otherwise.\n */\nDUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_hthread *thr, duk_bool_t get_value) {\n\tduk_hobject *e;\n\tduk_hobject *enum_target;\n\tduk_hstring *res = NULL;\n\tduk_uint_fast32_t idx;\n\tduk_bool_t check_existence;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* [... enum] */\n\n\te = duk_require_hobject(thr, -1);\n\n\t/* XXX use get tval ptr, more efficient */\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_NEXT);\n\tidx = (duk_uint_fast32_t) duk_require_uint(thr, -1);\n\tduk_pop(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"enumeration: index is: %ld\", (long) idx));\n\n\t/* Enumeration keys are checked against the enumeration target (to see\n\t * that they still exist).  In the proxy enumeration case _Target will\n\t * be the proxy, and checking key existence against the proxy is not\n\t * required (or sensible, as the keys may be fully virtual).\n\t */\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_TARGET);\n\tenum_target = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(enum_target != NULL);\n#if defined(DUK_USE_ES6_PROXY)\n\tcheck_existence = (!DUK_HOBJECT_IS_PROXY(enum_target));\n#else\n\tcheck_existence = 1;\n#endif\n\tduk_pop(thr);  /* still reachable */\n\n\tDUK_DDD(DUK_DDDPRINT(\"getting next enum value, enum_target=%!iO, enumerator=%!iT\",\n\t                     (duk_heaphdr *) enum_target, (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* no array part */\n\tfor (;;) {\n\t\tduk_hstring *k;\n\n\t\tif (idx >= DUK_HOBJECT_GET_ENEXT(e)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"enumeration: ran out of elements\"));\n\t\t\tbreak;\n\t\t}\n\n\t\t/* we know these because enum objects are internally created */\n\t\tk = DUK_HOBJECT_E_GET_KEY(thr->heap, e, idx);\n\t\tDUK_ASSERT(k != NULL);\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, e, idx));\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(&DUK_HOBJECT_E_GET_VALUE(thr->heap, e, idx).v));\n\n\t\tidx++;\n\n\t\t/* recheck that the property still exists */\n\t\tif (check_existence && !duk_hobject_hasprop_raw(thr, enum_target, k)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property deleted during enumeration, skip\"));\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"enumeration: found element, key: %!O\", (duk_heaphdr *) k));\n\t\tres = k;\n\t\tbreak;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"enumeration: updating next index to %ld\", (long) idx));\n\n\tduk_push_u32(thr, (duk_uint32_t) idx);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_NEXT);\n\n\t/* [... enum] */\n\n\tif (res) {\n\t\tduk_push_hstring(thr, res);\n\t\tif (get_value) {\n\t\t\tduk_push_hobject(thr, enum_target);\n\t\t\tduk_dup_m2(thr);       /* -> [... enum key enum_target key] */\n\t\t\tduk_get_prop(thr, -2); /* -> [... enum key enum_target val] */\n\t\t\tduk_remove_m2(thr);    /* -> [... enum key val] */\n\t\t\tduk_remove(thr, -3);   /* -> [... key val] */\n\t\t} else {\n\t\t\tduk_remove_m2(thr);    /* -> [... key] */\n\t\t}\n\t\treturn 1;\n\t} else {\n\t\tduk_pop(thr);  /* -> [...] */\n\t\treturn 0;\n\t}\n}\n\n/*\n *  Get enumerated keys in an ECMAScript array.  Matches Object.keys() behavior\n *  described in E5 Section 15.2.3.14.\n */\n\nDUK_INTERNAL duk_ret_t duk_hobject_get_enumerated_keys(duk_hthread *thr, duk_small_uint_t enum_flags) {\n\tduk_hobject *e;\n\tduk_hstring **keys;\n\tduk_tval *tv;\n\tduk_uint_fast32_t count;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(duk_get_hobject(thr, -1) != NULL);\n\n\t/* Create a temporary enumerator to get the (non-duplicated) key list;\n\t * the enumerator state is initialized without being needed, but that\n\t * has little impact.\n\t */\n\n\tduk_hobject_enumerator_create(thr, enum_flags);\n\te = duk_known_hobject(thr, -1);\n\n\t/* [enum_target enum res] */\n\n\t/* Create dense result array to exact size. */\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(e) >= DUK__ENUM_START_INDEX);\n\tcount = (duk_uint32_t) (DUK_HOBJECT_GET_ENEXT(e) - DUK__ENUM_START_INDEX);\n\n\t/* XXX: uninit would be OK */\n\ttv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) count);\n\tDUK_ASSERT(count == 0 || tv != NULL);\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\t/* Fill result array, no side effects. */\n\n\tkeys = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, e);\n\tkeys += DUK__ENUM_START_INDEX;\n\n\twhile (count-- > 0) {\n\t\tduk_hstring *k;\n\n\t\tk = *keys++;\n\t\tDUK_ASSERT(k != NULL);  /* enumerator must have no keys deleted */\n\n\t\tDUK_TVAL_SET_STRING(tv, k);\n\t\ttv++;\n\t\tDUK_HSTRING_INCREF(thr, k);\n\t}\n\n\t/* [enum_target enum res] */\n\tduk_remove_m2(thr);\n\n\t/* [enum_target res] */\n\n\treturn 1;  /* return 1 to allow callers to tail call */\n}\n\n/* automatic undefs */\n#undef DUK__ENUM_START_INDEX\n/*\n *  Misc support functions\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, duk_hobject *h, duk_hobject *p, duk_bool_t ignore_loop) {\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* False if the object is NULL or the prototype 'p' is NULL.\n\t * In particular, false if both are NULL (don't compare equal).\n\t */\n\tif (h == NULL || p == NULL) {\n\t\treturn 0;\n\t}\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (h == p) {\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (sanity-- == 0) {\n\t\t\tif (ignore_loop) {\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\t\th = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t} while (h);\n\n\treturn 0;\n}\n\nDUK_INTERNAL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject *h, duk_hobject *p) {\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_hobject *tmp;\n\n\tDUK_ASSERT(h);\n\ttmp = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, h, p);\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, p);  /* avoid problems if p == h->prototype */\n\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);\n#else\n\tDUK_ASSERT(h);\n\tDUK_UNREF(thr);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, h, p);\n#endif\n}\n/*\n *  Helpers for creating and querying pc2line debug data, which\n *  converts a bytecode program counter to a source line number.\n *\n *  The run-time pc2line data is bit-packed, and documented in:\n *\n *    doc/function-objects.rst\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_PC2LINE)\n\n/* Generate pc2line data for an instruction sequence, leaving a buffer on stack top. */\nDUK_INTERNAL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr *instrs, duk_uint_fast32_t length) {\n\tduk_hbuffer_dynamic *h_buf;\n\tduk_bitencoder_ctx be_ctx_alloc;\n\tduk_bitencoder_ctx *be_ctx = &be_ctx_alloc;\n\tduk_uint32_t *hdr;\n\tduk_size_t new_size;\n\tduk_uint_fast32_t num_header_entries;\n\tduk_uint_fast32_t curr_offset;\n\tduk_int_fast32_t curr_line, next_line, diff_line;\n\tduk_uint_fast32_t curr_pc;\n\tduk_uint_fast32_t hdr_index;\n\n\tDUK_ASSERT(length <= DUK_COMPILER_MAX_BYTECODE_LENGTH);\n\n\tnum_header_entries = (length + DUK_PC2LINE_SKIP - 1) / DUK_PC2LINE_SKIP;\n\tcurr_offset = (duk_uint_fast32_t) (sizeof(duk_uint32_t) + num_header_entries * sizeof(duk_uint32_t) * 2);\n\n\tduk_push_dynamic_buffer(thr, (duk_size_t) curr_offset);\n\th_buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, -1);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h_buf) && !DUK_HBUFFER_HAS_EXTERNAL(h_buf));\n\n\thdr = (duk_uint32_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h_buf);\n\tDUK_ASSERT(hdr != NULL);\n\thdr[0] = (duk_uint32_t) length;  /* valid pc range is [0, length[ */\n\n\tcurr_pc = 0U;\n\twhile (curr_pc < length) {\n\t\tnew_size = (duk_size_t) (curr_offset + DUK_PC2LINE_MAX_DIFF_LENGTH);\n\t\tduk_hbuffer_resize(thr, h_buf, new_size);\n\n\t\thdr = (duk_uint32_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h_buf);\n\t\tDUK_ASSERT(hdr != NULL);\n\t\tDUK_ASSERT(curr_pc < length);\n\t\thdr_index = 1 + (curr_pc / DUK_PC2LINE_SKIP) * 2;\n\t\tcurr_line = (duk_int_fast32_t) instrs[curr_pc].line;\n\t\thdr[hdr_index + 0] = (duk_uint32_t) curr_line;\n\t\thdr[hdr_index + 1] = (duk_uint32_t) curr_offset;\n\n#if 0\n\t\tDUK_DDD(DUK_DDDPRINT(\"hdr[%ld]: pc=%ld line=%ld offset=%ld\",\n\t\t                     (long) (curr_pc / DUK_PC2LINE_SKIP),\n\t\t                     (long) curr_pc,\n\t\t                     (long) hdr[hdr_index + 0],\n\t\t                     (long) hdr[hdr_index + 1]));\n#endif\n\n\t\tduk_memzero(be_ctx, sizeof(*be_ctx));\n\t\tbe_ctx->data = ((duk_uint8_t *) hdr) + curr_offset;\n\t\tbe_ctx->length = (duk_size_t) DUK_PC2LINE_MAX_DIFF_LENGTH;\n\n\t\tfor (;;) {\n\t\t\tcurr_pc++;\n\t\t\tif ( ((curr_pc % DUK_PC2LINE_SKIP) == 0) ||  /* end of diff run */\n\t\t\t     (curr_pc >= length) ) {                 /* end of bytecode */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_ASSERT(curr_pc < length);\n\t\t\tnext_line = (duk_int32_t) instrs[curr_pc].line;\n\t\t\tdiff_line = next_line - curr_line;\n\n#if 0\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"curr_line=%ld, next_line=%ld -> diff_line=%ld\",\n\t\t\t                     (long) curr_line, (long) next_line, (long) diff_line));\n#endif\n\n\t\t\tif (diff_line == 0) {\n\t\t\t\t/* 0 */\n\t\t\t\tduk_be_encode(be_ctx, 0, 1);\n\t\t\t} else if (diff_line >= 1 && diff_line <= 4) {\n\t\t\t\t/* 1 0 <2 bits> */\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) ((0x02 << 2) + (diff_line - 1)), 4);\n\t\t\t} else if (diff_line >= -0x80 && diff_line <= 0x7f) {\n\t\t\t\t/* 1 1 0 <8 bits> */\n\t\t\t\tDUK_ASSERT(diff_line + 0x80 >= 0 && diff_line + 0x80 <= 0xff);\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) ((0x06 << 8) + (diff_line + 0x80)), 11);\n\t\t\t} else {\n\t\t\t\t/* 1 1 1 <32 bits>\n\t\t\t\t * Encode in two parts to avoid bitencode 24-bit limitation\n\t\t\t\t */\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) ((0x07 << 16) + ((next_line >> 16) & 0xffff)), 19);\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) (next_line & 0xffff), 16);\n\t\t\t}\n\n\t\t\tcurr_line = next_line;\n\t\t}\n\n\t\tduk_be_finish(be_ctx);\n\t\tDUK_ASSERT(!be_ctx->truncated);\n\n\t\t/* be_ctx->offset == length of encoded bitstream */\n\t\tcurr_offset += (duk_uint_fast32_t) be_ctx->offset;\n\t}\n\n\t/* compact */\n\tnew_size = (duk_size_t) curr_offset;\n\tduk_hbuffer_resize(thr, h_buf, new_size);\n\n\t(void) duk_to_fixed_buffer(thr, -1, NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"final pc2line data: pc_limit=%ld, length=%ld, %lf bits/opcode --> %!ixT\",\n\t                     (long) length, (long) new_size, (double) new_size * 8.0 / (double) length,\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n}\n\n/* PC is unsigned.  If caller does PC arithmetic and gets a negative result,\n * it will map to a large PC which is out of bounds and causes a zero to be\n * returned.\n */\nDUK_LOCAL duk_uint_fast32_t duk__hobject_pc2line_query_raw(duk_hthread *thr, duk_hbuffer_fixed *buf, duk_uint_fast32_t pc) {\n\tduk_bitdecoder_ctx bd_ctx_alloc;\n\tduk_bitdecoder_ctx *bd_ctx = &bd_ctx_alloc;\n\tduk_uint32_t *hdr;\n\tduk_uint_fast32_t start_offset;\n\tduk_uint_fast32_t pc_limit;\n\tduk_uint_fast32_t hdr_index;\n\tduk_uint_fast32_t pc_base;\n\tduk_uint_fast32_t n;\n\tduk_uint_fast32_t curr_line;\n\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) buf) && !DUK_HBUFFER_HAS_EXTERNAL((duk_hbuffer *) buf));\n\tDUK_UNREF(thr);\n\n\t/*\n\t *  Use the index in the header to find the right starting point\n\t */\n\n\thdr_index = pc / DUK_PC2LINE_SKIP;\n\tpc_base = hdr_index * DUK_PC2LINE_SKIP;\n\tn = pc - pc_base;\n\n\tif (DUK_HBUFFER_FIXED_GET_SIZE(buf) <= sizeof(duk_uint32_t)) {\n\t\tDUK_DD(DUK_DDPRINT(\"pc2line lookup failed: buffer is smaller than minimal header\"));\n\t\tgoto pc2line_error;\n\t}\n\n\thdr = (duk_uint32_t *) (void *) DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, buf);\n\tpc_limit = hdr[0];\n\tif (pc >= pc_limit) {\n\t\t/* Note: pc is unsigned and cannot be negative */\n\t\tDUK_DD(DUK_DDPRINT(\"pc2line lookup failed: pc out of bounds (pc=%ld, limit=%ld)\",\n\t\t                   (long) pc, (long) pc_limit));\n\t\tgoto pc2line_error;\n\t}\n\n\tcurr_line = hdr[1 + hdr_index * 2];\n\tstart_offset = hdr[1 + hdr_index * 2 + 1];\n\tif ((duk_size_t) start_offset > DUK_HBUFFER_FIXED_GET_SIZE(buf)) {\n\t\tDUK_DD(DUK_DDPRINT(\"pc2line lookup failed: start_offset out of bounds (start_offset=%ld, buffer_size=%ld)\",\n\t\t                   (long) start_offset, (long) DUK_HBUFFER_GET_SIZE((duk_hbuffer *) buf)));\n\t\tgoto pc2line_error;\n\t}\n\n\t/*\n\t *  Iterate the bitstream (line diffs) until PC is reached\n\t */\n\n\tduk_memzero(bd_ctx, sizeof(*bd_ctx));\n\tbd_ctx->data = ((duk_uint8_t *) hdr) + start_offset;\n\tbd_ctx->length = (duk_size_t) (DUK_HBUFFER_FIXED_GET_SIZE(buf) - start_offset);\n\n#if 0\n\tDUK_DDD(DUK_DDDPRINT(\"pc2line lookup: pc=%ld -> hdr_index=%ld, pc_base=%ld, n=%ld, start_offset=%ld\",\n\t                     (long) pc, (long) hdr_index, (long) pc_base, (long) n, (long) start_offset));\n#endif\n\n\twhile (n > 0) {\n#if 0\n\t\tDUK_DDD(DUK_DDDPRINT(\"lookup: n=%ld, curr_line=%ld\", (long) n, (long) curr_line));\n#endif\n\n\t\tif (duk_bd_decode_flag(bd_ctx)) {\n\t\t\tif (duk_bd_decode_flag(bd_ctx)) {\n\t\t\t\tif (duk_bd_decode_flag(bd_ctx)) {\n\t\t\t\t\t/* 1 1 1 <32 bits> */\n\t\t\t\t\tduk_uint_fast32_t t;\n\t\t\t\t\tt = duk_bd_decode(bd_ctx, 16);  /* workaround: max nbits = 24 now */\n\t\t\t\t\tt = (t << 16) + duk_bd_decode(bd_ctx, 16);\n\t\t\t\t\tcurr_line = t;\n\t\t\t\t} else {\n\t\t\t\t\t/* 1 1 0 <8 bits> */\n\t\t\t\t\tduk_uint_fast32_t t;\n\t\t\t\t\tt = duk_bd_decode(bd_ctx, 8);\n\t\t\t\t\tcurr_line = curr_line + t - 0x80;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* 1 0 <2 bits> */\n\t\t\t\tduk_uint_fast32_t t;\n\t\t\t\tt = duk_bd_decode(bd_ctx, 2);\n\t\t\t\tcurr_line = curr_line + t + 1;\n\t\t\t}\n\t\t} else {\n\t\t\t/* 0: no change */\n\t\t}\n\n\t\tn--;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"pc2line lookup result: pc %ld -> line %ld\", (long) pc, (long) curr_line));\n\treturn curr_line;\n\n pc2line_error:\n\tDUK_D(DUK_DPRINT(\"pc2line conversion failed for pc=%ld\", (long) pc));\n\treturn 0;\n}\n\nDUK_INTERNAL duk_uint_fast32_t duk_hobject_pc2line_query(duk_hthread *thr, duk_idx_t idx_func, duk_uint_fast32_t pc) {\n\tduk_hbuffer_fixed *pc2line;\n\tduk_uint_fast32_t line;\n\n\t/* XXX: now that pc2line is used by the debugger quite heavily in\n\t * checked execution, this should be optimized to avoid value stack\n\t * and perhaps also implement some form of pc2line caching (see\n\t * future work in debugger.rst).\n\t */\n\n\tduk_xget_owndataprop_stridx_short(thr, idx_func, DUK_STRIDX_INT_PC2LINE);\n\tpc2line = (duk_hbuffer_fixed *) (void *) duk_get_hbuffer(thr, -1);\n\tif (pc2line != NULL) {\n\t\tDUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) pc2line) && !DUK_HBUFFER_HAS_EXTERNAL((duk_hbuffer *) pc2line));\n\t\tline = duk__hobject_pc2line_query_raw(thr, pc2line, (duk_uint_fast32_t) pc);\n\t} else {\n\t\tline = 0;\n\t}\n\tduk_pop(thr);\n\n\treturn line;\n}\n\n#endif  /* DUK_USE_PC2LINE */\n/*\n *  duk_hobject property access functionality.\n *\n *  This is very central functionality for size, performance, and compliance.\n *  It is also rather intricate; see hobject-algorithms.rst for discussion on\n *  the algorithms and memory-management.rst for discussion on refcounts and\n *  side effect issues.\n *\n *  Notes:\n *\n *    - It might be tempting to assert \"refcount nonzero\" for objects\n *      being operated on, but that's not always correct: objects with\n *      a zero refcount may be operated on by the refcount implementation\n *      (finalization) for instance.  Hence, no refcount assertions are made.\n *\n *    - Many operations (memory allocation, identifier operations, etc)\n *      may cause arbitrary side effects (e.g. through GC and finalization).\n *      These side effects may invalidate duk_tval pointers which point to\n *      areas subject to reallocation (like value stack).  Heap objects\n *      themselves have stable pointers.  Holding heap object pointers or\n *      duk_tval copies is not problematic with respect to side effects;\n *      care must be taken when holding and using argument duk_tval pointers.\n *\n *    - If a finalizer is executed, it may operate on the the same object\n *      we're currently dealing with.  For instance, the finalizer might\n *      delete a certain property which has already been looked up and\n *      confirmed to exist.  Ideally finalizers would be disabled if GC\n *      happens during property access.  At the moment property table realloc\n *      disables finalizers, and all DECREFs may cause arbitrary changes so\n *      handle DECREF carefully.\n *\n *    - The order of operations for a DECREF matters.  When DECREF is executed,\n *      the entire object graph must be consistent; note that a refzero may\n *      lead to a mark-and-sweep through a refcount finalizer.  Use NORZ macros\n *      and an explicit DUK_REFZERO_CHECK_xxx() if achieving correct order is hard.\n */\n\n/*\n *  XXX: array indices are mostly typed as duk_uint32_t here; duk_uarridx_t\n *  might be more appropriate.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Local defines\n */\n\n#define DUK__NO_ARRAY_INDEX             DUK_HSTRING_NO_ARRAY_INDEX\n\n/* Marker values for hash part. */\n#define DUK__HASH_UNUSED                DUK_HOBJECT_HASHIDX_UNUSED\n#define DUK__HASH_DELETED               DUK_HOBJECT_HASHIDX_DELETED\n\n/* Valstack space that suffices for all local calls, excluding any recursion\n * into ECMAScript or Duktape/C calls (Proxy, getters, etc).\n */\n#define DUK__VALSTACK_SPACE             10\n\n/* Valstack space allocated especially for proxy lookup which does a\n * recursive property lookup.\n */\n#define DUK__VALSTACK_PROXY_LOOKUP      20\n\n/*\n *  Local prototypes\n */\n\nDUK_LOCAL_DECL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc);\nDUK_LOCAL_DECL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc, duk_bool_t throw_flag);\nDUK_LOCAL_DECL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc);\n\nDUK_LOCAL_DECL duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr, duk_hobject *obj, duk_uint32_t old_len, duk_uint32_t new_len, duk_bool_t force_flag, duk_uint32_t *out_result_len);\nDUK_LOCAL_DECL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject *obj);\n\nDUK_LOCAL_DECL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags);\nDUK_LOCAL_DECL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_uint32_t arr_idx, duk_propdesc *out_desc, duk_small_uint_t flags);\n\nDUK_LOCAL_DECL void duk__abandon_array_part(duk_hthread *thr, duk_hobject *obj);\nDUK_LOCAL_DECL void duk__grow_props_for_array_item(duk_hthread *thr, duk_hobject *obj, duk_uint32_t highest_arr_idx);\n\n/*\n *  Misc helpers\n */\n\n/* Convert a duk_tval number (caller checks) to a 32-bit index.  Returns\n * DUK__NO_ARRAY_INDEX if the number is not whole or not a valid array\n * index.\n */\n/* XXX: for fastints, could use a variant which assumes a double duk_tval\n * (and doesn't need to check for fastint again).\n */\nDUK_LOCAL duk_uint32_t duk__tval_number_to_arr_idx(duk_tval *tv) {\n\tduk_double_t dbl;\n\tduk_uint32_t idx;\n\n\tDUK_ASSERT(tv != NULL);\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\n\t/* -0 is accepted here as index 0 because ToString(-0) == \"0\" which is\n\t * in canonical form and thus an array index.\n\t */\n\tdbl = DUK_TVAL_GET_NUMBER(tv);\n\tidx = (duk_uint32_t) dbl;\n\tif ((duk_double_t) idx == dbl) {\n\t        /* Is whole and within 32 bit range.  If the value happens to be 0xFFFFFFFF,\n\t\t * it's not a valid array index but will then match DUK__NO_ARRAY_INDEX.\n\t\t */\n\t\treturn idx;\n\t}\n\treturn DUK__NO_ARRAY_INDEX;\n}\n\n#if defined(DUK_USE_FASTINT)\n/* Convert a duk_tval fastint (caller checks) to a 32-bit index. */\nDUK_LOCAL duk_uint32_t duk__tval_fastint_to_arr_idx(duk_tval *tv) {\n\tduk_int64_t t;\n\n\tDUK_ASSERT(tv != NULL);\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\n\tt = DUK_TVAL_GET_FASTINT(tv);\n\tif (((duk_uint64_t) t & ~DUK_U64_CONSTANT(0xffffffff)) != 0) {\n\t\t/* Catches >0x100000000 and negative values. */\n\t\treturn DUK__NO_ARRAY_INDEX;\n\t}\n\n\t/* If the value happens to be 0xFFFFFFFF, it's not a valid array index\n\t * but will then match DUK__NO_ARRAY_INDEX.\n\t */\n\treturn (duk_uint32_t) t;\n}\n#endif  /* DUK_USE_FASTINT */\n\n/* Convert a duk_tval on the value stack (in a trusted index we don't validate)\n * to a string or symbol using ES2015 ToPropertyKey():\n * http://www.ecma-international.org/ecma-262/6.0/#sec-topropertykey.\n *\n * Also check if it's a valid array index and return that (or DUK__NO_ARRAY_INDEX\n * if not).\n */\nDUK_LOCAL duk_uint32_t duk__to_property_key(duk_hthread *thr, duk_idx_t idx, duk_hstring **out_h) {\n\tduk_uint32_t arr_idx;\n\tduk_hstring *h;\n\tduk_tval *tv_dst;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(out_h != NULL);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx));\n\tDUK_ASSERT(idx < 0);\n\n\t/* XXX: The revised ES2015 ToPropertyKey() handling (ES5.1 was just\n\t * ToString()) involves a ToPrimitive(), a symbol check, and finally\n\t * a ToString().  Figure out the best way to have a good fast path\n\t * but still be compliant and share code.\n\t */\n\n\ttv_dst = DUK_GET_TVAL_NEGIDX(thr, idx);  /* intentionally unvalidated */\n\tif (DUK_TVAL_IS_STRING(tv_dst)) {\n\t\t/* Most important path: strings and plain symbols are used as\n\t\t * is.  For symbols the array index check below is unnecessary\n\t\t * (they're never valid array indices) but checking that the\n\t\t * string is a symbol would make the plain string path slower\n\t\t * unnecessarily.\n\t\t */\n\t\th = DUK_TVAL_GET_STRING(tv_dst);\n\t} else {\n\t\th = duk_to_property_key_hstring(thr, idx);\n\t}\n\tDUK_ASSERT(h != NULL);\n\t*out_h = h;\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_FAST(h);\n\treturn arr_idx;\n}\n\nDUK_LOCAL duk_uint32_t duk__push_tval_to_property_key(duk_hthread *thr, duk_tval *tv_key, duk_hstring **out_h) {\n\tduk_push_tval(thr, tv_key);  /* XXX: could use an unsafe push here */\n\treturn duk__to_property_key(thr, -1, out_h);\n}\n\n/* String is an own (virtual) property of a plain buffer. */\nDUK_LOCAL duk_bool_t duk__key_is_plain_buf_ownprop(duk_hthread *thr, duk_hbuffer *buf, duk_hstring *key, duk_uint32_t arr_idx) {\n\tDUK_UNREF(thr);\n\n\t/* Virtual index properties.  Checking explicitly for\n\t * 'arr_idx != DUK__NO_ARRAY_INDEX' is not necessary\n\t * because DUK__NO_ARRAY_INDEXi is always larger than\n\t * maximum allowed buffer size.\n\t */\n\tDUK_ASSERT(DUK__NO_ARRAY_INDEX >= DUK_HBUFFER_GET_SIZE(buf));\n\tif (arr_idx < DUK_HBUFFER_GET_SIZE(buf)) {\n\t\treturn 1;\n\t}\n\n\t/* Other virtual properties. */\n\treturn (key == DUK_HTHREAD_STRING_LENGTH(thr));\n}\n\n/*\n *  Helpers for managing property storage size\n */\n\n/* Get default hash part size for a certain entry part size. */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\nDUK_LOCAL duk_uint32_t duk__get_default_h_size(duk_uint32_t e_size) {\n\tDUK_ASSERT(e_size <= DUK_HOBJECT_MAX_PROPERTIES);\n\n\tif (e_size >= DUK_USE_HOBJECT_HASH_PROP_LIMIT) {\n\t\tduk_uint32_t res;\n\t\tduk_uint32_t tmp;\n\n\t\t/* Hash size should be 2^N where N is chosen so that 2^N is\n\t\t * larger than e_size.  Extra shifting is used to ensure hash\n\t\t * is relatively sparse.\n\t\t */\n\t\ttmp = e_size;\n\t\tres = 2;  /* Result will be 2 ** (N + 1). */\n\t\twhile (tmp >= 0x40) {\n\t\t\ttmp >>= 6;\n\t\t\tres <<= 6;\n\t\t}\n\t\twhile (tmp != 0) {\n\t\t\ttmp >>= 1;\n\t\t\tres <<= 1;\n\t\t}\n\t\tDUK_ASSERT((DUK_HOBJECT_MAX_PROPERTIES << 2U) > DUK_HOBJECT_MAX_PROPERTIES);  /* Won't wrap, even shifted by 2. */\n\t\tDUK_ASSERT(res > e_size);\n\t\treturn res;\n\t} else {\n\t\treturn 0;\n\t}\n}\n#endif  /* USE_PROP_HASH_PART */\n\n/* Get minimum entry part growth for a certain size. */\nDUK_LOCAL duk_uint32_t duk__get_min_grow_e(duk_uint32_t e_size) {\n\tduk_uint32_t res;\n\n\tres = (e_size + DUK_USE_HOBJECT_ENTRY_MINGROW_ADD) / DUK_USE_HOBJECT_ENTRY_MINGROW_DIVISOR;\n\tDUK_ASSERT(res >= 1);  /* important for callers */\n\treturn res;\n}\n\n/* Get minimum array part growth for a certain size. */\nDUK_LOCAL duk_uint32_t duk__get_min_grow_a(duk_uint32_t a_size) {\n\tduk_uint32_t res;\n\n\tres = (a_size + DUK_USE_HOBJECT_ARRAY_MINGROW_ADD) / DUK_USE_HOBJECT_ARRAY_MINGROW_DIVISOR;\n\tDUK_ASSERT(res >= 1);  /* important for callers */\n\treturn res;\n}\n\n/* Count actually used entry part entries (non-NULL keys). */\nDUK_LOCAL duk_uint32_t duk__count_used_e_keys(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint_fast32_t i;\n\tduk_uint_fast32_t n = 0;\n\tduk_hstring **e;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(thr);\n\n\te = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, obj);\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tif (*e++) {\n\t\t\tn++;\n\t\t}\n\t}\n\treturn (duk_uint32_t) n;\n}\n\n/* Count actually used array part entries and array minimum size.\n * NOTE: 'out_min_size' can be computed much faster by starting from the\n * end and breaking out early when finding first used entry, but this is\n * not needed now.\n */\nDUK_LOCAL void duk__compute_a_stats(duk_hthread *thr, duk_hobject *obj, duk_uint32_t *out_used, duk_uint32_t *out_min_size) {\n\tduk_uint_fast32_t i;\n\tduk_uint_fast32_t used = 0;\n\tduk_uint_fast32_t highest_idx = (duk_uint_fast32_t) -1;  /* see below */\n\tduk_tval *a;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(out_used != NULL);\n\tDUK_ASSERT(out_min_size != NULL);\n\tDUK_UNREF(thr);\n\n\ta = DUK_HOBJECT_A_GET_BASE(thr->heap, obj);\n\tfor (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\tduk_tval *tv = a++;\n\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\tused++;\n\t\t\thighest_idx = i;\n\t\t}\n\t}\n\n\t/* Initial value for highest_idx is -1 coerced to unsigned.  This\n\t * is a bit odd, but (highest_idx + 1) will then wrap to 0 below\n\t * for out_min_size as intended.\n\t */\n\n\t*out_used = (duk_uint32_t) used;\n\t*out_min_size = (duk_uint32_t) (highest_idx + 1);  /* 0 if no used entries */\n}\n\n/* Check array density and indicate whether or not the array part should be abandoned. */\nDUK_LOCAL duk_bool_t duk__abandon_array_density_check(duk_uint32_t a_used, duk_uint32_t a_size) {\n\t/*\n\t *  Array abandon check; abandon if:\n\t *\n\t *    new_used / new_size < limit\n\t *    new_used < limit * new_size        || limit is 3 bits fixed point\n\t *    new_used < limit' / 8 * new_size   || *8\n\t *    8*new_used < limit' * new_size     || :8\n\t *    new_used < limit' * (new_size / 8)\n\t *\n\t *  Here, new_used = a_used, new_size = a_size.\n\t *\n\t *  Note: some callers use approximate values for a_used and/or a_size\n\t *  (e.g. dropping a '+1' term).  This doesn't affect the usefulness\n\t *  of the check, but may confuse debugging.\n\t */\n\n\treturn (a_used < DUK_USE_HOBJECT_ARRAY_ABANDON_LIMIT * (a_size >> 3));\n}\n\n/* Fast check for extending array: check whether or not a slow density check is required. */\nDUK_LOCAL duk_bool_t duk__abandon_array_slow_check_required(duk_uint32_t arr_idx, duk_uint32_t old_size) {\n\t/*\n\t *  In a fast check we assume old_size equals old_used (i.e., existing\n\t *  array is fully dense).\n\t *\n\t *  Slow check if:\n\t *\n\t *    (new_size - old_size) / old_size > limit\n\t *    new_size - old_size > limit * old_size\n\t *    new_size > (1 + limit) * old_size        || limit' is 3 bits fixed point\n\t *    new_size > (1 + (limit' / 8)) * old_size || * 8\n\t *    8 * new_size > (8 + limit') * old_size   || : 8\n\t *    new_size > (8 + limit') * (old_size / 8)\n\t *    new_size > limit'' * (old_size / 8)      || limit'' = 9 -> max 25% increase\n\t *    arr_idx + 1 > limit'' * (old_size / 8)\n\t *\n\t *  This check doesn't work well for small values, so old_size is rounded\n\t *  up for the check (and the '+ 1' of arr_idx can be ignored in practice):\n\t *\n\t *    arr_idx > limit'' * ((old_size + 7) / 8)\n\t */\n\n\treturn (arr_idx > DUK_USE_HOBJECT_ARRAY_FAST_RESIZE_LIMIT * ((old_size + 7) >> 3));\n}\n\nDUK_LOCAL duk_bool_t duk__abandon_array_check(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) {\n\tduk_uint32_t min_size;\n\tduk_uint32_t old_used;\n\tduk_uint32_t old_size;\n\n\tif (!duk__abandon_array_slow_check_required(arr_idx, DUK_HOBJECT_GET_ASIZE(obj))) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"=> fast resize is OK\"));\n\t\treturn 0;\n\t}\n\n\tduk__compute_a_stats(thr, obj, &old_used, &old_size);\n\n\tDUK_DDD(DUK_DDDPRINT(\"abandon check, array stats: old_used=%ld, old_size=%ld, arr_idx=%ld\",\n\t                     (long) old_used, (long) old_size, (long) arr_idx));\n\n\tmin_size = arr_idx + 1;\n#if defined(DUK_USE_OBJSIZES16)\n\tif (min_size > DUK_UINT16_MAX) {\n\t\tgoto do_abandon;\n\t}\n#endif\n\tDUK_UNREF(min_size);\n\n\t/* Note: intentionally use approximations to shave a few instructions:\n\t *   a_used = old_used  (accurate: old_used + 1)\n\t *   a_size = arr_idx   (accurate: arr_idx + 1)\n\t */\n\tif (duk__abandon_array_density_check(old_used, arr_idx)) {\n\t\tDUK_DD(DUK_DDPRINT(\"write to new array entry beyond current length, \"\n\t\t                   \"decided to abandon array part (would become too sparse)\"));\n\n\t\t/* Abandoning requires a props allocation resize and\n\t\t * 'rechecks' the valstack, invalidating any existing\n\t\t * valstack value pointers.\n\t\t */\n\t\tgoto do_abandon;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"=> decided to keep array part\"));\n\treturn 0;\n\n do_abandon:\n\tduk__abandon_array_part(thr, obj);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\treturn 1;\n}\n\nDUK_LOCAL duk_tval *duk__obtain_arridx_slot_slowpath(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) {\n\t/*\n\t *  Array needs to grow, but we don't want it becoming too sparse.\n\t *  If it were to become sparse, abandon array part, moving all\n\t *  array entries into the entries part (for good).\n\t *\n\t *  Since we don't keep track of actual density (used vs. size) of\n\t *  the array part, we need to estimate somehow.  The check is made\n\t *  in two parts:\n\t *\n\t *    - Check whether the resize need is small compared to the\n\t *      current size (relatively); if so, resize without further\n\t *      checking (essentially we assume that the original part is\n\t *      \"dense\" so that the result would be dense enough).\n\t *\n\t *    - Otherwise, compute the resize using an actual density\n\t *      measurement based on counting the used array entries.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"write to new array requires array resize, decide whether to do a \"\n\t                     \"fast resize without abandon check (arr_idx=%ld, old_size=%ld)\",\n\t                     (long) arr_idx, (long) DUK_HOBJECT_GET_ASIZE(obj)));\n\n\tif (DUK_UNLIKELY(duk__abandon_array_check(thr, arr_idx, obj) != 0)) {\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\treturn NULL;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"write to new array entry beyond current length, \"\n\t                   \"decided to extend current allocation\"));\n\n\t/* In principle it's possible to run out of memory extending the\n\t * array but with the allocation going through if we were to abandon\n\t * the array part and try again.  In practice this should be rare\n\t * because abandoned arrays have a higher per-entry footprint.\n\t */\n\n\tduk__grow_props_for_array_item(thr, obj, arr_idx);\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\tDUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(obj));\n\treturn DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n}\n\nDUK_LOCAL DUK_INLINE duk_tval *duk__obtain_arridx_slot(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) {\n\tif (DUK_LIKELY(arr_idx < DUK_HOBJECT_GET_ASIZE(obj))) {\n\t\treturn DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n\t} else {\n\t\treturn duk__obtain_arridx_slot_slowpath(thr, arr_idx, obj);\n\t}\n}\n\n/*\n *  Proxy helpers\n */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL duk_bool_t duk_hobject_proxy_check(duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler) {\n\tduk_hproxy *h_proxy;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(out_target != NULL);\n\tDUK_ASSERT(out_handler != NULL);\n\n\t/* Caller doesn't need to check exotic proxy behavior (but does so for\n\t * some fast paths).\n\t */\n\tif (DUK_LIKELY(!DUK_HOBJECT_IS_PROXY(obj))) {\n\t\treturn 0;\n\t}\n\th_proxy = (duk_hproxy *) obj;\n\tDUK_HPROXY_ASSERT_VALID(h_proxy);\n\n\tDUK_ASSERT(h_proxy->handler != NULL);\n\tDUK_ASSERT(h_proxy->target != NULL);\n\t*out_handler = h_proxy->handler;\n\t*out_target = h_proxy->target;\n\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n/* Get Proxy target object.  If the argument is not a Proxy, return it as is.\n * If a Proxy is revoked, an error is thrown.\n */\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL duk_hobject *duk_hobject_resolve_proxy_target(duk_hobject *obj) {\n\tDUK_ASSERT(obj != NULL);\n\n\t/* Resolve Proxy targets until Proxy chain ends.  No explicit check for\n\t * a Proxy loop: user code cannot create such a loop (it would only be\n\t * possible by editing duk_hproxy references directly).\n\t */\n\n\twhile (DUK_HOBJECT_IS_PROXY(obj)) {\n\t\tduk_hproxy *h_proxy;\n\n\t\th_proxy = (duk_hproxy *) obj;\n\t\tDUK_HPROXY_ASSERT_VALID(h_proxy);\n\t\tobj = h_proxy->target;\n\t\tDUK_ASSERT(obj != NULL);\n\t}\n\n\tDUK_ASSERT(obj != NULL);\n\treturn obj;\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_LOCAL duk_bool_t duk__proxy_check_prop(duk_hthread *thr, duk_hobject *obj, duk_small_uint_t stridx_trap, duk_tval *tv_key, duk_hobject **out_target) {\n\tduk_hobject *h_handler;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\tDUK_ASSERT(out_target != NULL);\n\n\tif (!duk_hobject_proxy_check(obj, out_target, &h_handler)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(*out_target != NULL);\n\tDUK_ASSERT(h_handler != NULL);\n\n\t/* XXX: At the moment Duktape accesses internal keys like _Finalizer using a\n\t * normal property set/get which would allow a proxy handler to interfere with\n\t * such behavior and to get access to internal key strings.  This is not a problem\n\t * as such because internal key strings can be created in other ways too (e.g.\n\t * through buffers).  The best fix is to change Duktape internal lookups to\n\t * skip proxy behavior.  Until that, internal property accesses bypass the\n\t * proxy and are applied to the target (as if the handler did not exist).\n\t * This has some side effects, see test-bi-proxy-internal-keys.js.\n\t */\n\n\tif (DUK_TVAL_IS_STRING(tv_key)) {\n\t\tduk_hstring *h_key = (duk_hstring *) DUK_TVAL_GET_STRING(tv_key);\n\t\tDUK_ASSERT(h_key != NULL);\n\t\tif (DUK_HSTRING_HAS_HIDDEN(h_key)) {\n\t\t\t/* Symbol accesses must go through proxy lookup in ES2015.\n\t\t\t * Hidden symbols behave like Duktape 1.x internal keys\n\t\t\t * and currently won't.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"hidden key, skip proxy handler and apply to target\"));\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* The handler is looked up with a normal property lookup; it may be an\n\t * accessor or the handler object itself may be a proxy object.  If the\n\t * handler is a proxy, we need to extend the valstack as we make a\n\t * recursive proxy check without a function call in between (in fact\n\t * there is no limit to the potential recursion here).\n\t *\n\t * (For sanity, proxy creation rejects another proxy object as either\n\t * the handler or the target at the moment so recursive proxy cases\n\t * are not realized now.)\n\t */\n\n\t/* XXX: C recursion limit if proxies are allowed as handler/target values */\n\n\tduk_require_stack(thr, DUK__VALSTACK_PROXY_LOOKUP);\n\tduk_push_hobject(thr, h_handler);\n\tif (duk_get_prop_stridx_short(thr, -1, stridx_trap)) {\n\t\t/* -> [ ... handler trap ] */\n\t\tduk_insert(thr, -2);  /* -> [ ... trap handler ] */\n\n\t\t/* stack prepped for func call: [ ... trap handler ] */\n\t\treturn 1;\n\t} else {\n\t\tduk_pop_2_unsafe(thr);\n\t\treturn 0;\n\t}\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n/*\n *  Reallocate property allocation, moving properties to the new allocation.\n *\n *  Includes key compaction, rehashing, and can also optionally abandon\n *  the array part, 'migrating' array entries into the beginning of the\n *  new entry part.\n *\n *  There is no support for in-place reallocation or just compacting keys\n *  without resizing the property allocation.  This is intentional to keep\n *  code size minimal, but would be useful future work.\n *\n *  The implementation is relatively straightforward, except for the array\n *  abandonment process.  Array abandonment requires that new string keys\n *  are interned, which may trigger GC.  All keys interned so far must be\n *  reachable for GC at all times and correctly refcounted for; valstack is\n *  used for that now.\n *\n *  Also, a GC triggered during this reallocation process must not interfere\n *  with the object being resized.  This is currently controlled by preventing\n *  finalizers (as they may affect ANY object) and object compaction in\n *  mark-and-sweep.  It would suffice to protect only this particular object\n *  from compaction, however.  DECREF refzero cascades are side effect free\n *  and OK.\n *\n *  Note: because we need to potentially resize the valstack (as part\n *  of abandoning the array part), any tval pointers to the valstack\n *  will become invalid after this call.\n */\n\nDUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,\n                                            duk_hobject *obj,\n                                            duk_uint32_t new_e_size,\n                                            duk_uint32_t new_a_size,\n                                            duk_uint32_t new_h_size,\n                                            duk_bool_t abandon_array) {\n\tduk_small_uint_t prev_ms_base_flags;\n\tduk_uint32_t new_alloc_size;\n\tduk_uint32_t new_e_size_adjusted;\n\tduk_uint8_t *new_p;\n\tduk_hstring **new_e_k;\n\tduk_propvalue *new_e_pv;\n\tduk_uint8_t *new_e_f;\n\tduk_tval *new_a;\n\tduk_uint32_t *new_h;\n\tduk_uint32_t new_e_next;\n\tduk_uint_fast32_t i;\n\tduk_size_t array_copy_size;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_bool_t prev_error_not_allowed;\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(!abandon_array || new_a_size == 0);  /* if abandon_array, new_a_size must be 0 */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL || (DUK_HOBJECT_GET_ESIZE(obj) == 0 && DUK_HOBJECT_GET_ASIZE(obj) == 0));\n\tDUK_ASSERT(new_h_size == 0 || new_h_size >= new_e_size);  /* required to guarantee success of rehashing,\n\t                                                           * intentionally use unadjusted new_e_size\n\t                                                           */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_object_realloc_props);\n\n\t/*\n\t *  Pre resize assertions.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* XXX: pre-checks (such as no duplicate keys) */\n#endif\n\n\t/*\n\t *  For property layout 1, tweak e_size to ensure that the whole entry\n\t *  part (key + val + flags) is a suitable multiple for alignment\n\t *  (platform specific).\n\t *\n\t *  Property layout 2 does not require this tweaking and is preferred\n\t *  on low RAM platforms requiring alignment.\n\t */\n\n#if defined(DUK_USE_HOBJECT_LAYOUT_2) || defined(DUK_USE_HOBJECT_LAYOUT_3)\n\tDUK_DDD(DUK_DDDPRINT(\"using layout 2 or 3, no need to pad e_size: %ld\", (long) new_e_size));\n\tnew_e_size_adjusted = new_e_size;\n#elif defined(DUK_USE_HOBJECT_LAYOUT_1) && (DUK_HOBJECT_ALIGN_TARGET == 1)\n\tDUK_DDD(DUK_DDDPRINT(\"using layout 1, but no need to pad e_size: %ld\", (long) new_e_size));\n\tnew_e_size_adjusted = new_e_size;\n#elif defined(DUK_USE_HOBJECT_LAYOUT_1) && ((DUK_HOBJECT_ALIGN_TARGET == 4) || (DUK_HOBJECT_ALIGN_TARGET == 8))\n\tnew_e_size_adjusted = (new_e_size + (duk_uint32_t) DUK_HOBJECT_ALIGN_TARGET - 1U) &\n\t                      (~((duk_uint32_t) DUK_HOBJECT_ALIGN_TARGET - 1U));\n\tDUK_DDD(DUK_DDDPRINT(\"using layout 1, and alignment target is %ld, adjusted e_size: %ld -> %ld\",\n\t                     (long) DUK_HOBJECT_ALIGN_TARGET, (long) new_e_size, (long) new_e_size_adjusted));\n\tDUK_ASSERT(new_e_size_adjusted >= new_e_size);\n#else\n#error invalid hobject layout defines\n#endif\n\n\t/*\n\t *  Debug logging after adjustment.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"attempt to resize hobject %p props (%ld -> %ld bytes), from {p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld} to \"\n\t                     \"{e_size=%ld,a_size=%ld,h_size=%ld}, abandon_array=%ld, unadjusted new_e_size=%ld\",\n\t                     (void *) obj,\n\t                     (long) DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t                                                       DUK_HOBJECT_GET_ASIZE(obj),\n\t                                                       DUK_HOBJECT_GET_HSIZE(obj)),\n\t                     (long) DUK_HOBJECT_P_COMPUTE_SIZE(new_e_size_adjusted, new_a_size, new_h_size),\n\t                     (void *) DUK_HOBJECT_GET_PROPS(thr->heap, obj),\n\t                     (long) DUK_HOBJECT_GET_ESIZE(obj),\n\t                     (long) DUK_HOBJECT_GET_ENEXT(obj),\n\t                     (long) DUK_HOBJECT_GET_ASIZE(obj),\n\t                     (long) DUK_HOBJECT_GET_HSIZE(obj),\n\t                     (long) new_e_size_adjusted,\n\t                     (long) new_a_size,\n\t                     (long) new_h_size,\n\t                     (long) abandon_array,\n\t                     (long) new_e_size));\n\n\t/*\n\t *  Property count check.  This is the only point where we ensure that\n\t *  we don't get more (allocated) property space that we can handle.\n\t *  There aren't hard limits as such, but some algorithms may fail\n\t *  if we get too close to the 4G property limit.\n\t *\n\t *  Since this works based on allocation size (not actually used size),\n\t *  the limit is a bit approximate but good enough in practice.\n\t */\n\n\tif (new_e_size_adjusted + new_a_size > DUK_HOBJECT_MAX_PROPERTIES) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size_adjusted > DUK_UINT16_MAX || new_a_size > DUK_UINT16_MAX) {\n\t\t/* If caller gave us sizes larger than what we can store,\n\t\t * fail memory safely with an internal error rather than\n\t\t * truncating the sizes.\n\t\t */\n\t\tDUK_ERROR_INTERNAL(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\t/*\n\t *  Compute new alloc size and alloc new area.\n\t *\n\t *  The new area is not tracked in the heap at all, so it's critical\n\t *  we get to free/keep it in a controlled manner.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Whole path must be error throw free, but we may be called from\n\t * within error handling so can't assert for error_not_allowed == 0.\n\t */\n\tprev_error_not_allowed = thr->heap->error_not_allowed;\n\tthr->heap->error_not_allowed = 1;\n#endif\n\tprev_ms_base_flags = thr->heap->ms_base_flags;\n\tthr->heap->ms_base_flags |=\n\t        DUK_MS_FLAG_NO_OBJECT_COMPACTION;      /* Avoid attempt to compact the current object (all objects really). */\n\tthr->heap->pf_prevent_count++;                 /* Avoid finalizers. */\n\tDUK_ASSERT(thr->heap->pf_prevent_count != 0);  /* Wrap. */\n\n\tnew_alloc_size = DUK_HOBJECT_P_COMPUTE_SIZE(new_e_size_adjusted, new_a_size, new_h_size);\n\tDUK_DDD(DUK_DDDPRINT(\"new hobject allocation size is %ld\", (long) new_alloc_size));\n\tif (new_alloc_size == 0) {\n\t\tDUK_ASSERT(new_e_size_adjusted == 0);\n\t\tDUK_ASSERT(new_a_size == 0);\n\t\tDUK_ASSERT(new_h_size == 0);\n\t\tnew_p = NULL;\n\t} else {\n\t\t/* Alloc may trigger mark-and-sweep but no compaction, and\n\t\t * cannot throw.\n\t\t */\n#if 0  /* XXX: inject test */\n\t\tif (1) {\n\t\t\tnew_p = NULL;\n\t\t\tgoto alloc_failed;\n\t\t}\n#endif\n\t\tnew_p = (duk_uint8_t *) DUK_ALLOC(thr->heap, new_alloc_size);\n\t\tif (new_p == NULL) {\n\t\t\t/* NULL always indicates alloc failure because\n\t\t\t * new_alloc_size > 0.\n\t\t\t */\n\t\t\tgoto alloc_failed;\n\t\t}\n\t}\n\n\t/* Set up pointers to the new property area: this is hidden behind a macro\n\t * because it is memory layout specific.\n\t */\n\tDUK_HOBJECT_P_SET_REALLOC_PTRS(new_p, new_e_k, new_e_pv, new_e_f, new_a, new_h,\n\t                               new_e_size_adjusted, new_a_size, new_h_size);\n\tDUK_UNREF(new_h);  /* happens when hash part dropped */\n\tnew_e_next = 0;\n\n\t/* if new_p == NULL, all of these pointers are NULL */\n\tDUK_ASSERT((new_p != NULL) ||\n\t           (new_e_k == NULL && new_e_pv == NULL && new_e_f == NULL &&\n\t            new_a == NULL && new_h == NULL));\n\n\tDUK_DDD(DUK_DDDPRINT(\"new alloc size %ld, new_e_k=%p, new_e_pv=%p, new_e_f=%p, new_a=%p, new_h=%p\",\n\t                     (long) new_alloc_size, (void *) new_e_k, (void *) new_e_pv, (void *) new_e_f,\n\t                     (void *) new_a, (void *) new_h));\n\n\t/*\n\t *  Migrate array part to start of entries if requested.\n\t *\n\t *  Note: from an enumeration perspective the order of entry keys matters.\n\t *  Array keys should appear wherever they appeared before the array abandon\n\t *  operation.  (This no longer matters much because keys are ES2015 sorted.)\n\t */\n\n\tif (abandon_array) {\n\t\t/* Assuming new_a_size == 0, and that entry part contains\n\t\t * no conflicting keys, refcounts do not need to be adjusted for\n\t\t * the values, as they remain exactly the same.\n\t\t *\n\t\t * The keys, however, need to be interned, incref'd, and be\n\t\t * reachable for GC.  Any intern attempt may trigger a GC and\n\t\t * claim any non-reachable strings, so every key must be reachable\n\t\t * at all times.  Refcounts must be correct to satisfy refcount\n\t\t * assertions.\n\t\t *\n\t\t * A longjmp must not occur here, as the new_p allocation would\n\t\t * leak.  Refcounts would come out correctly as the interned\n\t\t * strings are valstack tracked.\n\t\t */\n\t\tDUK_ASSERT(new_a_size == 0);\n\n\t\tDUK_STATS_INC(thr->heap, stats_object_abandon_array);\n\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_tval *tv2;\n\t\t\tduk_hstring *key;\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);\n\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\t\tif (DUK_TVAL_IS_UNUSED(tv1)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(new_p != NULL && new_e_k != NULL &&\n\t\t\t           new_e_pv != NULL && new_e_f != NULL);\n\n\t\t\t/*\n\t\t\t *  Intern key via the valstack to ensure reachability behaves\n\t\t\t *  properly.  We must avoid longjmp's here so use non-checked\n\t\t\t *  primitives.\n\t\t\t *\n\t\t\t *  Note: duk_check_stack() potentially reallocs the valstack,\n\t\t\t *  invalidating any duk_tval pointers to valstack.  Callers\n\t\t\t *  must be careful.\n\t\t\t */\n\n#if 0  /* XXX: inject test */\n\t\t\tif (1) {\n\t\t\t\tgoto abandon_error;\n\t\t\t}\n#endif\n\t\t\t/* Never shrinks; auto-adds DUK_VALSTACK_INTERNAL_EXTRA, which\n\t\t\t * is generous.\n\t\t\t */\n\t\t\tif (!duk_check_stack(thr, 1)) {\n\t\t\t\tgoto abandon_error;\n\t\t\t}\n\t\t\tDUK_ASSERT_VALSTACK_SPACE(thr, 1);\n\t\t\tkey = duk_heap_strtable_intern_u32(thr->heap, (duk_uint32_t) i);\n\t\t\tif (key == NULL) {\n\t\t\t\tgoto abandon_error;\n\t\t\t}\n\t\t\tduk_push_hstring(thr, key);  /* keep key reachable for GC etc; guaranteed not to fail */\n\n\t\t\t/* Key is now reachable in the valstack, don't INCREF\n\t\t\t * the new allocation yet (we'll steal the refcounts\n\t\t\t * from the value stack once all keys are done).\n\t\t\t */\n\n\t\t\tnew_e_k[new_e_next] = key;\n\t\t\ttv2 = &new_e_pv[new_e_next].v;  /* array entries are all plain values */\n\t\t\tDUK_TVAL_SET_TVAL(tv2, tv1);\n\t\t\tnew_e_f[new_e_next] = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t                      DUK_PROPDESC_FLAG_ENUMERABLE |\n\t\t\t                      DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\tnew_e_next++;\n\n\t\t\t/* Note: new_e_next matches pushed temp key count, and nothing can\n\t\t\t * fail above between the push and this point.\n\t\t\t */\n\t\t}\n\n\t\t/* Steal refcounts from value stack. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"abandon array: pop %ld key temps from valstack\", (long) new_e_next));\n\t\tduk_pop_n_nodecref_unsafe(thr, (duk_idx_t) new_e_next);\n\t}\n\n\t/*\n\t *  Copy keys and values in the entry part (compacting them at the same time).\n\t */\n\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tduk_hstring *key;\n\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);\n\n\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);\n\t\tif (key == NULL) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_ASSERT(new_p != NULL && new_e_k != NULL &&\n\t\t           new_e_pv != NULL && new_e_f != NULL);\n\n\t\tnew_e_k[new_e_next] = key;\n\t\tnew_e_pv[new_e_next] = DUK_HOBJECT_E_GET_VALUE(thr->heap, obj, i);\n\t\tnew_e_f[new_e_next] = DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, i);\n\t\tnew_e_next++;\n\t}\n\t/* the entries [new_e_next, new_e_size_adjusted[ are left uninitialized on purpose (ok, not gc reachable) */\n\n\t/*\n\t *  Copy array elements to new array part.  If the new array part is\n\t *  larger, initialize the unused entries as UNUSED because they are\n\t *  GC reachable.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Caller must have decref'd values above new_a_size (if that is necessary). */\n\tif (!abandon_array) {\n\t\tfor (i = new_a_size; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\t\tduk_tval *tv;\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv));\n\t\t}\n\t}\n#endif\n\tif (new_a_size > DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\tarray_copy_size = sizeof(duk_tval) * DUK_HOBJECT_GET_ASIZE(obj);\n\t} else {\n\t\tarray_copy_size = sizeof(duk_tval) * new_a_size;\n\t}\n\n\tDUK_ASSERT(new_a != NULL || array_copy_size == 0U);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL || array_copy_size == 0U);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) > 0 || array_copy_size == 0U);\n\tduk_memcpy_unsafe((void *) new_a,\n\t                  (const void *) DUK_HOBJECT_A_GET_BASE(thr->heap, obj),\n\t                  array_copy_size);\n\n\tfor (i = DUK_HOBJECT_GET_ASIZE(obj); i < new_a_size; i++) {\n\t\tduk_tval *tv = &new_a[i];\n\t\tDUK_TVAL_SET_UNUSED(tv);\n\t}\n\n\t/*\n\t *  Rebuild the hash part always from scratch (guaranteed to finish\n\t *  as long as caller gave consistent parameters).\n\t *\n\t *  Any resize of hash part requires rehashing.  In addition, by rehashing\n\t *  get rid of any elements marked deleted (DUK__HASH_DELETED) which is critical\n\t *  to ensuring the hash part never fills up.\n\t */\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (new_h_size == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"no hash part, no rehash\"));\n\t} else {\n\t\tduk_uint32_t mask;\n\n\t\tDUK_ASSERT(new_h != NULL);\n\n\t\t/* fill new_h with u32 0xff = UNUSED */\n\t\tDUK_ASSERT(new_h_size > 0);\n\t\tduk_memset(new_h, 0xff, sizeof(duk_uint32_t) * new_h_size);\n\n\t\tDUK_ASSERT(new_e_next <= new_h_size);  /* equality not actually possible */\n\n\t\tmask = new_h_size - 1;\n\t\tfor (i = 0; i < new_e_next; i++) {\n\t\t\tduk_hstring *key = new_e_k[i];\n\t\t\tduk_uint32_t j, step;\n\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tj = DUK_HSTRING_GET_HASH(key) & mask;\n\t\t\tstep = 1;  /* Cache friendly but clustering prone. */\n\n\t\t\tfor (;;) {\n\t\t\t\tDUK_ASSERT(new_h[j] != DUK__HASH_DELETED);  /* should never happen */\n\t\t\t\tif (new_h[j] == DUK__HASH_UNUSED) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rebuild hit %ld -> %ld\", (long) j, (long) i));\n\t\t\t\t\tnew_h[j] = (duk_uint32_t) i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rebuild miss %ld, step %ld\", (long) j, (long) step));\n\t\t\t\tj = (j + step) & mask;\n\n\t\t\t\t/* Guaranteed to finish (hash is larger than #props). */\n\t\t\t}\n\t\t}\n\t}\n#endif  /* DUK_USE_HOBJECT_HASH_PART */\n\n\t/*\n\t *  Nice debug log.\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"resized hobject %p props (%ld -> %ld bytes), from {p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld} to \"\n\t                   \"{p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld}, abandon_array=%ld, unadjusted new_e_size=%ld\",\n\t                   (void *) obj,\n\t                   (long) DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t                                                     DUK_HOBJECT_GET_ASIZE(obj),\n\t                                                     DUK_HOBJECT_GET_HSIZE(obj)),\n\t                   (long) new_alloc_size,\n\t                   (void *) DUK_HOBJECT_GET_PROPS(thr->heap, obj),\n\t                   (long) DUK_HOBJECT_GET_ESIZE(obj),\n\t                   (long) DUK_HOBJECT_GET_ENEXT(obj),\n\t                   (long) DUK_HOBJECT_GET_ASIZE(obj),\n\t                   (long) DUK_HOBJECT_GET_HSIZE(obj),\n\t                   (void *) new_p,\n\t                   (long) new_e_size_adjusted,\n\t                   (long) new_e_next,\n\t                   (long) new_a_size,\n\t                   (long) new_h_size,\n\t                   (long) abandon_array,\n\t                   (long) new_e_size));\n\n\t/*\n\t *  All done, switch properties ('p') allocation to new one.\n\t */\n\n\tDUK_FREE_CHECKED(thr, DUK_HOBJECT_GET_PROPS(thr->heap, obj));  /* NULL obj->p is OK */\n\tDUK_HOBJECT_SET_PROPS(thr->heap, obj, new_p);\n\tDUK_HOBJECT_SET_ESIZE(obj, new_e_size_adjusted);\n\tDUK_HOBJECT_SET_ENEXT(obj, new_e_next);\n\tDUK_HOBJECT_SET_ASIZE(obj, new_a_size);\n\tDUK_HOBJECT_SET_HSIZE(obj, new_h_size);\n\n\t/* Clear array part flag only after switching. */\n\tif (abandon_array) {\n\t\tDUK_HOBJECT_CLEAR_ARRAY_PART(obj);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"resize result: %!O\", (duk_heaphdr *) obj));\n\n\tDUK_ASSERT(thr->heap->pf_prevent_count > 0);\n\tthr->heap->pf_prevent_count--;\n\tthr->heap->ms_base_flags = prev_ms_base_flags;\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->heap->error_not_allowed == 1);\n\tthr->heap->error_not_allowed = prev_error_not_allowed;\n#endif\n\n\t/*\n\t *  Post resize assertions.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* XXX: post-checks (such as no duplicate keys) */\n#endif\n\treturn;\n\n\t/*\n\t *  Abandon array failed.  We don't need to DECREF anything\n\t *  because the references in the new allocation are not\n\t *  INCREF'd until abandon is complete.  The string interned\n\t *  keys are on the value stack and are handled normally by\n\t *  unwind.\n\t */\n\n abandon_error:\n alloc_failed:\n\tDUK_D(DUK_DPRINT(\"object property table resize failed\"));\n\n\tDUK_FREE_CHECKED(thr, new_p);  /* OK for NULL. */\n\n\tthr->heap->pf_prevent_count--;\n\tthr->heap->ms_base_flags = prev_ms_base_flags;\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->heap->error_not_allowed == 1);\n\tthr->heap->error_not_allowed = prev_error_not_allowed;\n#endif\n\n\tDUK_ERROR_ALLOC_FAILED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Helpers to resize properties allocation on specific needs.\n */\n\nDUK_INTERNAL void duk_hobject_resize_entrypart(duk_hthread *thr,\n                                               duk_hobject *obj,\n                                               duk_uint32_t new_e_size) {\n\tduk_uint32_t old_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_h_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\told_e_size = DUK_HOBJECT_GET_ESIZE(obj);\n\tif (old_e_size > new_e_size) {\n\t\tnew_e_size = old_e_size;\n\t}\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tnew_h_size = duk__get_default_h_size(new_e_size);\n#else\n\tnew_h_size = 0;\n#endif\n\tnew_a_size = DUK_HOBJECT_GET_ASIZE(obj);\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);\n}\n\n/* Grow entry part allocation for one additional entry. */\nDUK_LOCAL void duk__grow_props_for_new_entry_item(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint32_t old_e_used;  /* actually used, non-NULL entries */\n\tduk_uint32_t new_e_size_minimum;\n\tduk_uint32_t new_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_h_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\t/* Duktape 0.11.0 and prior tried to optimize the resize by not\n\t * counting the number of actually used keys prior to the resize.\n\t * This worked mostly well but also caused weird leak-like behavior\n\t * as in: test-bug-object-prop-alloc-unbounded.js.  So, now we count\n\t * the keys explicitly to compute the new entry part size.\n\t */\n\n\told_e_used = duk__count_used_e_keys(thr, obj);\n\tnew_e_size_minimum = old_e_used + 1;\n\tnew_e_size = old_e_used + duk__get_min_grow_e(old_e_used);\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tnew_h_size = duk__get_default_h_size(new_e_size);\n#else\n\tnew_h_size = 0;\n#endif\n\tnew_a_size = DUK_HOBJECT_GET_ASIZE(obj);\n\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size > DUK_UINT16_MAX) {\n\t\tnew_e_size = DUK_UINT16_MAX;\n\t}\n\tif (new_h_size > DUK_UINT16_MAX) {\n\t\tnew_h_size = DUK_UINT16_MAX;\n\t}\n\tif (new_a_size > DUK_UINT16_MAX) {\n\t\tnew_a_size = DUK_UINT16_MAX;\n\t}\n#endif\n\tDUK_ASSERT(new_h_size == 0 || new_h_size >= new_e_size);\n\n\tif (!(new_e_size >= new_e_size_minimum)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);\n}\n\n/* Grow array part for a new highest array index. */\nDUK_LOCAL void duk__grow_props_for_array_item(duk_hthread *thr, duk_hobject *obj, duk_uint32_t highest_arr_idx) {\n\tduk_uint32_t new_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_a_size_minimum;\n\tduk_uint32_t new_h_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(highest_arr_idx >= DUK_HOBJECT_GET_ASIZE(obj));\n\n\tnew_e_size = DUK_HOBJECT_GET_ESIZE(obj);\n\tnew_h_size = DUK_HOBJECT_GET_HSIZE(obj);\n\tnew_a_size_minimum = highest_arr_idx + 1;\n\tnew_a_size = highest_arr_idx + duk__get_min_grow_a(highest_arr_idx);\n\tDUK_ASSERT(new_a_size >= highest_arr_idx + 1);  /* duk__get_min_grow_a() is always >= 1 */\n\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size > DUK_UINT16_MAX) {\n\t\tnew_e_size = DUK_UINT16_MAX;\n\t}\n\tif (new_h_size > DUK_UINT16_MAX) {\n\t\tnew_h_size = DUK_UINT16_MAX;\n\t}\n\tif (new_a_size > DUK_UINT16_MAX) {\n\t\tnew_a_size = DUK_UINT16_MAX;\n\t}\n#endif\n\n\tif (!(new_a_size >= new_a_size_minimum)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);\n}\n\n/* Abandon array part, moving array entries into entries part.\n * This requires a props resize, which is a heavy operation.\n * We also compact the entries part while we're at it, although\n * this is not strictly required.\n */\nDUK_LOCAL void duk__abandon_array_part(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint32_t new_e_size_minimum;\n\tduk_uint32_t new_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_h_size;\n\tduk_uint32_t e_used;  /* actually used, non-NULL keys */\n\tduk_uint32_t a_used;\n\tduk_uint32_t a_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\te_used = duk__count_used_e_keys(thr, obj);\n\tduk__compute_a_stats(thr, obj, &a_used, &a_size);\n\n\t/*\n\t *  Must guarantee all actually used array entries will fit into\n\t *  new entry part.  Add one growth step to ensure we don't run out\n\t *  of space right away.\n\t */\n\n\tnew_e_size_minimum = e_used + a_used;\n\tnew_e_size = new_e_size_minimum + duk__get_min_grow_e(new_e_size_minimum);\n\tnew_a_size = 0;\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tnew_h_size = duk__get_default_h_size(new_e_size);\n#else\n\tnew_h_size = 0;\n#endif\n\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size > DUK_UINT16_MAX) {\n\t\tnew_e_size = DUK_UINT16_MAX;\n\t}\n\tif (new_h_size > DUK_UINT16_MAX) {\n\t\tnew_h_size = DUK_UINT16_MAX;\n\t}\n\tif (new_a_size > DUK_UINT16_MAX) {\n\t\tnew_a_size = DUK_UINT16_MAX;\n\t}\n#endif\n\n\tif (!(new_e_size >= new_e_size_minimum)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"abandon array part for hobject %p, \"\n\t                   \"array stats before: e_used=%ld, a_used=%ld, a_size=%ld; \"\n\t                   \"resize to e_size=%ld, a_size=%ld, h_size=%ld\",\n\t                   (void *) obj, (long) e_used, (long) a_used, (long) a_size,\n\t                   (long) new_e_size, (long) new_a_size, (long) new_h_size));\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 1);\n}\n\n/*\n *  Compact an object.  Minimizes allocation size for objects which are\n *  not likely to be extended.  This is useful for internal and non-\n *  extensible objects, but can also be called for non-extensible objects.\n *  May abandon the array part if it is computed to be too sparse.\n *\n *  This call is relatively expensive, as it needs to scan both the\n *  entries and the array part.\n *\n *  The call may fail due to allocation error.\n */\n\nDUK_INTERNAL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint32_t e_size;       /* currently used -> new size */\n\tduk_uint32_t a_size;       /* currently required */\n\tduk_uint32_t a_used;       /* actually used */\n\tduk_uint32_t h_size;\n\tduk_bool_t abandon_array;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"ignore attempt to compact a rom object\"));\n\t\treturn;\n\t}\n#endif\n\n\te_size = duk__count_used_e_keys(thr, obj);\n\tduk__compute_a_stats(thr, obj, &a_used, &a_size);\n\n\tDUK_DD(DUK_DDPRINT(\"compacting hobject, used e keys %ld, used a keys %ld, min a size %ld, \"\n\t                   \"resized array density would be: %ld/%ld = %lf\",\n\t                   (long) e_size, (long) a_used, (long) a_size,\n\t                   (long) a_used, (long) a_size,\n\t                   (double) a_used / (double) a_size));\n\n\tif (duk__abandon_array_density_check(a_used, a_size)) {\n\t\tDUK_DD(DUK_DDPRINT(\"decided to abandon array during compaction, a_used=%ld, a_size=%ld\",\n\t\t                   (long) a_used, (long) a_size));\n\t\tabandon_array = 1;\n\t\te_size += a_used;\n\t\ta_size = 0;\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"decided to keep array during compaction\"));\n\t\tabandon_array = 0;\n\t}\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (e_size >= DUK_USE_HOBJECT_HASH_PROP_LIMIT) {\n\t\th_size = duk__get_default_h_size(e_size);\n\t} else {\n\t\th_size = 0;\n\t}\n#else\n\th_size = 0;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"compacting hobject -> new e_size %ld, new a_size=%ld, new h_size=%ld, abandon_array=%ld\",\n\t                   (long) e_size, (long) a_size, (long) h_size, (long) abandon_array));\n\n\tduk_hobject_realloc_props(thr, obj, e_size, a_size, h_size, abandon_array);\n}\n\n/*\n *  Find an existing key from entry part either by linear scan or by\n *  using the hash index (if it exists).\n *\n *  Sets entry index (and possibly the hash index) to output variables,\n *  which allows the caller to update the entry and hash entries in-place.\n *  If entry is not found, both values are set to -1.  If entry is found\n *  but there is no hash part, h_idx is set to -1.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_find_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx) {\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(e_idx != NULL);\n\tDUK_ASSERT(h_idx != NULL);\n\tDUK_UNREF(heap);\n\n\tif (DUK_LIKELY(DUK_HOBJECT_GET_HSIZE(obj) == 0))\n\t{\n\t\t/* Linear scan: more likely because most objects are small.\n\t\t * This is an important fast path.\n\t\t *\n\t\t * XXX: this might be worth inlining for property lookups.\n\t\t */\n\t\tduk_uint_fast32_t i;\n\t\tduk_uint_fast32_t n;\n\t\tduk_hstring **h_keys_base;\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk_hobject_find_entry() using linear scan for lookup\"));\n\n\t\th_keys_base = DUK_HOBJECT_E_GET_KEY_BASE(heap, obj);\n\t\tn = DUK_HOBJECT_GET_ENEXT(obj);\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tif (h_keys_base[i] == key) {\n\t\t\t\t*e_idx = (duk_int_t) i;\n\t\t\t\t*h_idx = -1;\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t}\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\telse\n\t{\n\t\t/* hash lookup */\n\t\tduk_uint32_t n;\n\t\tduk_uint32_t i, step;\n\t\tduk_uint32_t *h_base;\n\t\tduk_uint32_t mask;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk_hobject_find_entry() using hash part for lookup\"));\n\n\t\th_base = DUK_HOBJECT_H_GET_BASE(heap, obj);\n\t\tn = DUK_HOBJECT_GET_HSIZE(obj);\n\t\tmask = n - 1;\n\t\ti = DUK_HSTRING_GET_HASH(key) & mask;\n\t\tstep = 1;  /* Cache friendly but clustering prone. */\n\n\t\tfor (;;) {\n\t\t\tduk_uint32_t t;\n\n\t\t\tDUK_ASSERT_DISABLE(i >= 0);  /* unsigned */\n\t\t\tDUK_ASSERT(i < DUK_HOBJECT_GET_HSIZE(obj));\n\t\t\tt = h_base[i];\n\t\t\tDUK_ASSERT(t == DUK__HASH_UNUSED || t == DUK__HASH_DELETED ||\n\t\t\t           (t < DUK_HOBJECT_GET_ESIZE(obj)));  /* t >= 0 always true, unsigned */\n\n\t\t\tif (t == DUK__HASH_UNUSED) {\n\t\t\t\tbreak;\n\t\t\t} else if (t == DUK__HASH_DELETED) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"lookup miss (deleted) i=%ld, t=%ld\",\n\t\t\t\t                     (long) i, (long) t));\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(t < DUK_HOBJECT_GET_ESIZE(obj));\n\t\t\t\tif (DUK_HOBJECT_E_GET_KEY(heap, obj, t) == key) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"lookup hit i=%ld, t=%ld -> key %p\",\n\t\t\t\t\t                     (long) i, (long) t, (void *) key));\n\t\t\t\t\t*e_idx = (duk_int_t) t;\n\t\t\t\t\t*h_idx = (duk_int_t) i;\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"lookup miss i=%ld, t=%ld\",\n\t\t\t\t                     (long) i, (long) t));\n\t\t\t}\n\t\t\ti = (i + step) & mask;\n\n\t\t\t/* Guaranteed to finish (hash is larger than #props). */\n\t\t}\n\t}\n#endif  /* DUK_USE_HOBJECT_HASH_PART */\n\n\t/* Not found, leave e_idx and h_idx unset. */\n\treturn 0;\n}\n\n/* For internal use: get non-accessor entry value */\nDUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key) {\n\tduk_int_t e_idx;\n\tduk_int_t h_idx;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_UNREF(heap);\n\n\tif (duk_hobject_find_entry(heap, obj, key, &e_idx, &h_idx)) {\n\t\tDUK_ASSERT(e_idx >= 0);\n\t\tif (!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {\n\t\t\treturn DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);\n\t\t}\n\t}\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx) {\n\treturn duk_hobject_find_entry_tval_ptr(heap, obj, DUK_HEAP_GET_STRING(heap, stridx));\n}\n\n/* For internal use: get non-accessor entry value and attributes */\nDUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs) {\n\tduk_int_t e_idx;\n\tduk_int_t h_idx;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_attrs != NULL);\n\tDUK_UNREF(heap);\n\n\tif (duk_hobject_find_entry(heap, obj, key, &e_idx, &h_idx)) {\n\t\tDUK_ASSERT(e_idx >= 0);\n\t\tif (!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {\n\t\t\t*out_attrs = DUK_HOBJECT_E_GET_FLAGS(heap, obj, e_idx);\n\t\t\treturn DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);\n\t\t}\n\t}\n\t/* If not found, out_attrs is left unset. */\n\treturn NULL;\n}\n\n/* For internal use: get array part value */\nDUK_INTERNAL duk_tval *duk_hobject_find_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(heap);\n\n\tif (!DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\treturn NULL;\n\t}\n\tif (i >= DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\treturn NULL;\n\t}\n\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(heap, obj, i);\n\treturn tv;\n}\n\n/*\n *  Allocate and initialize a new entry, resizing the properties allocation\n *  if necessary.  Returns entry index (e_idx) or throws an error if alloc fails.\n *\n *  Sets the key of the entry (increasing the key's refcount), and updates\n *  the hash part if it exists.  Caller must set value and flags, and update\n *  the entry value refcount.  A decref for the previous value is not necessary.\n */\n\nDUK_LOCAL duk_int_t duk__hobject_alloc_entry_checked(duk_hthread *thr, duk_hobject *obj, duk_hstring *key) {\n\tduk_uint32_t idx;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(obj) <= DUK_HOBJECT_GET_ESIZE(obj));\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* key must not already exist in entry part */\n\t{\n\t\tduk_uint_fast32_t i;\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != key);\n\t\t}\n\t}\n#endif\n\n\tif (DUK_HOBJECT_GET_ENEXT(obj) >= DUK_HOBJECT_GET_ESIZE(obj)) {\n\t\t/* only need to guarantee 1 more slot, but allocation growth is in chunks */\n\t\tDUK_DDD(DUK_DDDPRINT(\"entry part full, allocate space for one more entry\"));\n\t\tduk__grow_props_for_new_entry_item(thr, obj);\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(obj) < DUK_HOBJECT_GET_ESIZE(obj));\n\tidx = DUK_HOBJECT_POSTINC_ENEXT(obj);\n\n\t/* previous value is assumed to be garbage, so don't touch it */\n\tDUK_HOBJECT_E_SET_KEY(thr->heap, obj, idx, key);\n\tDUK_HSTRING_INCREF(thr, key);\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (DUK_UNLIKELY(DUK_HOBJECT_GET_HSIZE(obj) > 0)) {\n\t\tduk_uint32_t n, mask;\n\t\tduk_uint32_t i, step;\n\t\tduk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(thr->heap, obj);\n\n\t\tn = DUK_HOBJECT_GET_HSIZE(obj);\n\t\tmask = n - 1;\n\t\ti = DUK_HSTRING_GET_HASH(key) & mask;\n\t\tstep = 1;  /* Cache friendly but clustering prone. */\n\n\t\tfor (;;) {\n\t\t\tduk_uint32_t t = h_base[i];\n\t\t\tif (t == DUK__HASH_UNUSED || t == DUK__HASH_DELETED) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__hobject_alloc_entry_checked() inserted key into hash part, %ld -> %ld\",\n\t\t\t\t                     (long) i, (long) idx));\n\t\t\t\tDUK_ASSERT_DISABLE(i >= 0);  /* unsigned */\n\t\t\t\tDUK_ASSERT(i < DUK_HOBJECT_GET_HSIZE(obj));\n\t\t\t\tDUK_ASSERT_DISABLE(idx >= 0);\n\t\t\t\tDUK_ASSERT(idx < DUK_HOBJECT_GET_ESIZE(obj));\n\t\t\t\th_base[i] = idx;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__hobject_alloc_entry_checked() miss %ld\", (long) i));\n\t\t\ti = (i + step) & mask;\n\n\t\t\t/* Guaranteed to finish (hash is larger than #props). */\n\t\t}\n\t}\n#endif  /* DUK_USE_HOBJECT_HASH_PART */\n\n\t/* Note: we could return the hash index here too, but it's not\n\t * needed right now.\n\t */\n\n\tDUK_ASSERT_DISABLE(idx >= 0);\n\tDUK_ASSERT(idx < DUK_HOBJECT_GET_ESIZE(obj));\n\tDUK_ASSERT(idx < DUK_HOBJECT_GET_ENEXT(obj));\n\treturn (duk_int_t) idx;\n}\n\n/*\n *  Object internal value\n *\n *  Returned value is guaranteed to be reachable / incref'd, caller does not need\n *  to incref OR decref.  No proxies or accessors are invoked, no prototype walk.\n */\n\nDUK_INTERNAL duk_tval *duk_hobject_get_internal_value_tval_ptr(duk_heap *heap, duk_hobject *obj) {\n\treturn duk_hobject_find_entry_tval_ptr_stridx(heap, obj, DUK_STRIDX_INT_VALUE);\n}\n\nDUK_LOCAL duk_heaphdr *duk_hobject_get_internal_value_heaphdr(duk_heap *heap, duk_hobject *obj) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\ttv = duk_hobject_get_internal_value_tval_ptr(heap, obj);\n\tif (tv != NULL) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn h;\n\t}\n\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *heap, duk_hobject *obj) {\n\tduk_hstring *h;\n\n\th = (duk_hstring *) duk_hobject_get_internal_value_heaphdr(heap, obj);\n\tif (h != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_IS_STRING((duk_heaphdr *) h));\n\t}\n\treturn h;\n}\n\nDUK_LOCAL duk_hobject *duk__hobject_get_entry_object_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(heap, obj, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn h;\n\t}\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_harray *duk_hobject_get_formals(duk_hthread *thr, duk_hobject *obj) {\n\tduk_harray *h;\n\n\th = (duk_harray *) duk__hobject_get_entry_object_stridx(thr->heap, obj, DUK_STRIDX_INT_FORMALS);\n\tif (h != NULL) {\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) h));\n\t\tDUK_ASSERT(h->length <= DUK_HOBJECT_GET_ASIZE((duk_hobject *) h));\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_hobject_get_varmap(duk_hthread *thr, duk_hobject *obj) {\n\tduk_hobject *h;\n\n\th = duk__hobject_get_entry_object_stridx(thr->heap, obj, DUK_STRIDX_INT_VARMAP);\n\treturn h;\n}\n\n/*\n *  Arguments handling helpers (argument map mainly).\n *\n *  An arguments object has exotic behavior for some numeric indices.\n *  Accesses may translate to identifier operations which may have\n *  arbitrary side effects (potentially invalidating any duk_tval\n *  pointers).\n */\n\n/* Lookup 'key' from arguments internal 'map', perform a variable lookup\n * if mapped, and leave the result on top of stack (and return non-zero).\n * Used in E5 Section 10.6 algorithms [[Get]] and [[GetOwnProperty]].\n */\nDUK_LOCAL\nduk_bool_t duk__lookup_arguments_map(duk_hthread *thr,\n                                     duk_hobject *obj,\n                                     duk_hstring *key,\n                                     duk_propdesc *temp_desc,\n                                     duk_hobject **out_map,\n                                     duk_hobject **out_varenv) {\n\tduk_hobject *map;\n\tduk_hobject *varenv;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments map lookup: thr=%p, obj=%p, key=%p, temp_desc=%p \"\n\t                     \"(obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (void *) temp_desc,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tif (!duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_MAP(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> no 'map'\"));\n\t\treturn 0;\n\t}\n\n\tmap = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(map != NULL);\n\tduk_pop_unsafe(thr);  /* map is reachable through obj */\n\n\tif (!duk_hobject_get_own_propdesc(thr, map, key, temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> 'map' exists, but key not in map\"));\n\t\treturn 0;\n\t}\n\n\t/* [... varname] */\n\tDUK_DDD(DUK_DDDPRINT(\"-> 'map' exists, and contains key, key is mapped to argument/variable binding %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\tDUK_ASSERT(duk_is_string(thr, -1));  /* guaranteed when building arguments */\n\n\t/* get varenv for varname (callee's declarative lexical environment) */\n\trc = duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_VARENV(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE);\n\tDUK_UNREF(rc);\n\tDUK_ASSERT(rc != 0);  /* arguments MUST have an initialized lexical environment reference */\n\tvarenv = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(varenv != NULL);\n\tduk_pop_unsafe(thr);  /* varenv remains reachable through 'obj' */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments varenv is: %!dO\", (duk_heaphdr *) varenv));\n\n\t/* success: leave varname in stack */\n\t*out_map = map;\n\t*out_varenv = varenv;\n\treturn 1;  /* [... varname] */\n}\n\n/* Lookup 'key' from arguments internal 'map', and leave replacement value\n * on stack top if mapped (and return non-zero).\n * Used in E5 Section 10.6 algorithm for [[GetOwnProperty]] (used by [[Get]]).\n */\nDUK_LOCAL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc) {\n\tduk_hobject *map;\n\tduk_hobject *varenv;\n\tduk_hstring *varname;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk__lookup_arguments_map(thr, obj, key, temp_desc, &map, &varenv)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arguments: key not mapped, no exotic get behavior\"));\n\t\treturn 0;\n\t}\n\n\t/* [... varname] */\n\n\tvarname = duk_require_hstring(thr, -1);\n\tDUK_ASSERT(varname != NULL);\n\tduk_pop_unsafe(thr);  /* varname is still reachable */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments object automatic getvar for a bound variable; \"\n\t                     \"key=%!O, varname=%!O\",\n\t                     (duk_heaphdr *) key,\n\t                     (duk_heaphdr *) varname));\n\n\t(void) duk_js_getvar_envrec(thr, varenv, varname, 1 /*throw*/);\n\n\t/* [... value this_binding] */\n\n\tduk_pop_unsafe(thr);\n\n\t/* leave result on stack top */\n\treturn 1;\n}\n\n/* Lookup 'key' from arguments internal 'map', perform a variable write if mapped.\n * Used in E5 Section 10.6 algorithm for [[DefineOwnProperty]] (used by [[Put]]).\n * Assumes stack top contains 'put' value (which is NOT popped).\n */\nDUK_LOCAL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc, duk_bool_t throw_flag) {\n\tduk_hobject *map;\n\tduk_hobject *varenv;\n\tduk_hstring *varname;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk__lookup_arguments_map(thr, obj, key, temp_desc, &map, &varenv)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arguments: key not mapped, no exotic put behavior\"));\n\t\treturn;\n\t}\n\n\t/* [... put_value varname] */\n\n\tvarname = duk_require_hstring(thr, -1);\n\tDUK_ASSERT(varname != NULL);\n\tduk_pop_unsafe(thr);  /* varname is still reachable */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments object automatic putvar for a bound variable; \"\n\t                     \"key=%!O, varname=%!O, value=%!T\",\n\t                     (duk_heaphdr *) key,\n\t                     (duk_heaphdr *) varname,\n\t                     (duk_tval *) duk_require_tval(thr, -1)));\n\n\t/* [... put_value] */\n\n\t/*\n\t *  Note: although arguments object variable mappings are only established\n\t *  for non-strict functions (and a call to a non-strict function created\n\t *  the arguments object in question), an inner strict function may be doing\n\t *  the actual property write.  Hence the throw_flag applied here comes from\n\t *  the property write call.\n\t */\n\n\tduk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(thr, -1), throw_flag);\n\n\t/* [... put_value] */\n}\n\n/* Lookup 'key' from arguments internal 'map', delete mapping if found.\n * Used in E5 Section 10.6 algorithm for [[Delete]].  Note that the\n * variable/argument itself (where the map points) is not deleted.\n */\nDUK_LOCAL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc) {\n\tduk_hobject *map;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_MAP(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arguments: key not mapped, no exotic delete behavior\"));\n\t\treturn;\n\t}\n\n\tmap = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(map != NULL);\n\tduk_pop_unsafe(thr);  /* map is reachable through obj */\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> have 'map', delete key %!O from map (if exists)); ignore result\",\n\t                     (duk_heaphdr *) key));\n\n\t/* Note: no recursion issue, we can trust 'map' to behave */\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR(map));\n\tDUK_DDD(DUK_DDDPRINT(\"map before deletion: %!O\", (duk_heaphdr *) map));\n\t(void) duk_hobject_delprop_raw(thr, map, key, 0);  /* ignore result */\n\tDUK_DDD(DUK_DDDPRINT(\"map after deletion: %!O\", (duk_heaphdr *) map));\n}\n\n/*\n *  ECMAScript compliant [[GetOwnProperty]](P), for internal use only.\n *\n *  If property is found:\n *    - Fills descriptor fields to 'out_desc'\n *    - If DUK_GETDESC_FLAG_PUSH_VALUE is set, pushes a value related to the\n *      property onto the stack ('undefined' for accessor properties).\n *    - Returns non-zero\n *\n *  If property is not found:\n *    - 'out_desc' is left in untouched state (possibly garbage)\n *    - Nothing is pushed onto the stack (not even with DUK_GETDESC_FLAG_PUSH_VALUE\n *      set)\n *    - Returns zero\n *\n *  Notes:\n *\n *    - Getting a property descriptor may cause an allocation (and hence\n *      GC) to take place, hence reachability and refcount of all related\n *      values matter.  Reallocation of value stack, properties, etc may\n *      invalidate many duk_tval pointers (concretely, those which reside\n *      in memory areas subject to reallocation).  However, heap object\n *      pointers are never affected (heap objects have stable pointers).\n *\n *    - The value of a plain property is always reachable and has a non-zero\n *      reference count.\n *\n *    - The value of a virtual property is not necessarily reachable from\n *      elsewhere and may have a refcount of zero.  Hence we push it onto\n *      the valstack for the caller, which ensures it remains reachable\n *      while it is needed.\n *\n *    - There are no virtual accessor properties.  Hence, all getters and\n *      setters are always related to concretely stored properties, which\n *      ensures that the get/set functions in the resulting descriptor are\n *      reachable and have non-zero refcounts.  Should there be virtual\n *      accessor properties later, this would need to change.\n */\n\nDUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_uint32_t arr_idx, duk_propdesc *out_desc, duk_small_uint_t flags) {\n\tduk_tval *tv;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk_hobject_get_own_propdesc: thr=%p, obj=%p, key=%p, out_desc=%p, flags=%lx, \"\n\t                     \"arr_idx=%ld (obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (void *) out_desc,\n\t                     (long) flags, (long) arr_idx,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_desc != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_getownpropdesc_count);\n\n\t/* Each code path returning 1 (= found) must fill in all the output\n\t * descriptor fields.  We don't do it beforehand because it'd be\n\t * unnecessary work if the property isn't found and would happen\n\t * multiple times for an inheritance chain.\n\t */\n\tDUK_ASSERT_SET_GARBAGE(out_desc, sizeof(*out_desc));\n#if 0\n\tout_desc->flags = 0;\n\tout_desc->get = NULL;\n\tout_desc->set = NULL;\n\tout_desc->e_idx = -1;\n\tout_desc->h_idx = -1;\n\tout_desc->a_idx = -1;\n#endif\n\n\t/*\n\t *  Try entries part first because it's the common case.\n\t *\n\t *  Array part lookups are usually handled by the array fast path, and\n\t *  are not usually inherited.  Array and entry parts never contain the\n\t *  same keys so the entry part vs. array part order doesn't matter.\n\t */\n\n\tif (duk_hobject_find_entry(thr->heap, obj, key, &out_desc->e_idx, &out_desc->h_idx)) {\n\t\tduk_int_t e_idx = out_desc->e_idx;\n\t\tDUK_ASSERT(out_desc->e_idx >= 0);\n\t\tout_desc->a_idx = -1;\n\t\tout_desc->flags = DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, e_idx);\n\t\tout_desc->get = NULL;\n\t\tout_desc->set = NULL;\n\t\tif (DUK_UNLIKELY(out_desc->flags & DUK_PROPDESC_FLAG_ACCESSOR)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found accessor property in entry part\"));\n\t\t\tout_desc->get = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, e_idx);\n\t\t\tout_desc->set = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, e_idx);\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t/* a dummy undefined value is pushed to make valstack\n\t\t\t\t * behavior uniform for caller\n\t\t\t\t */\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t}\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found plain property in entry part\"));\n\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\tduk_push_tval(thr, tv);\n\t\t\t}\n\t\t}\n\t\tgoto prop_found;\n\t}\n\n\t/*\n\t *  Try array part.\n\t */\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj) && arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\tif (arr_idx < DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n\t\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found in array part\"));\n\t\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t\tduk_push_tval(thr, tv);\n\t\t\t\t}\n\t\t\t\t/* implicit attributes */\n\t\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t\t                  DUK_PROPDESC_FLAG_CONFIGURABLE |\n\t\t\t\t                  DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t\tout_desc->get = NULL;\n\t\t\t\tout_desc->set = NULL;\n\t\t\t\tout_desc->e_idx = -1;\n\t\t\t\tout_desc->h_idx = -1;\n\t\t\t\tout_desc->a_idx = (duk_int_t) arr_idx;  /* XXX: limit 2G due to being signed */\n\t\t\t\tgoto prop_found;\n\t\t\t}\n\t\t}\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> not found as a concrete property\"));\n\n\t/*\n\t *  Not found as a concrete property, check for virtual properties.\n\t */\n\n\tif (!DUK_HOBJECT_HAS_VIRTUAL_PROPERTIES(obj)) {\n\t\t/* Quick skip. */\n\t\tgoto prop_not_found;\n\t}\n\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\tduk_harray *a;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array object exotic property get for key: %!O, arr_idx: %ld\",\n\t\t                     (duk_heaphdr *) key, (long) arr_idx));\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, key is 'length', length exotic behavior\"));\n\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) a->length);\n\t\t\t}\n\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\tif (DUK_HARRAY_LENGTH_WRITABLE(a)) {\n\t\t\t\tout_desc->flags |= DUK_PROPDESC_FLAG_WRITABLE;\n\t\t\t}\n\t\t\tout_desc->get = NULL;\n\t\t\tout_desc->set = NULL;\n\t\t\tout_desc->e_idx = -1;\n\t\t\tout_desc->h_idx = -1;\n\t\t\tout_desc->a_idx = -1;\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t}\n\t} else if (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"string object exotic property get for key: %!O, arr_idx: %ld\",\n\t\t                     (duk_heaphdr *) key, (long) arr_idx));\n\n\t\t/* XXX: charlen; avoid multiple lookups? */\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t\tduk_hstring *h_val;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index exists\"));\n\n\t\t\th_val = duk_hobject_get_internal_value_string(thr->heap, obj);\n\t\t\tDUK_ASSERT(h_val);\n\t\t\tif (arr_idx < DUK_HSTRING_GET_CHARLEN(h_val)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, array index inside string\"));\n\t\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t\tduk_push_hstring(thr, h_val);\n\t\t\t\t\tduk_substring(thr, -1, arr_idx, arr_idx + 1);  /* [str] -> [substr] */\n\t\t\t\t}\n\t\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_ENUMERABLE |  /* E5 Section 15.5.5.2 */\n\t\t\t\t                  DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\t\tout_desc->get = NULL;\n\t\t\t\tout_desc->set = NULL;\n\t\t\t\tout_desc->e_idx = -1;\n\t\t\t\tout_desc->h_idx = -1;\n\t\t\t\tout_desc->a_idx = -1;\n\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t\t} else {\n\t\t\t\t/* index is above internal string length -> property is fully normal */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index outside string -> normal property\"));\n\t\t\t}\n\t\t} else if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tduk_hstring *h_val;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, key is 'length', length exotic behavior\"));\n\n\t\t\th_val = duk_hobject_get_internal_value_string(thr->heap, obj);\n\t\t\tDUK_ASSERT(h_val != NULL);\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h_val));\n\t\t\t}\n\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;  /* E5 Section 15.5.5.1 */\n\t\t\tout_desc->get = NULL;\n\t\t\tout_desc->set = NULL;\n\t\t\tout_desc->e_idx = -1;\n\t\t\tout_desc->h_idx = -1;\n\t\t\tout_desc->a_idx = -1;\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t}\n\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\telse if (DUK_HOBJECT_IS_BUFOBJ(obj)) {\n\t\tduk_hbufobj *h_bufobj;\n\t\tduk_uint_t byte_off;\n\t\tduk_small_uint_t elem_size;\n\n\t\th_bufobj = (duk_hbufobj *) obj;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\t\tDUK_DDD(DUK_DDDPRINT(\"bufobj property get for key: %!O, arr_idx: %ld\",\n\t\t                     (duk_heaphdr *) key, (long) arr_idx));\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index exists\"));\n\n\t\t\t/* Careful with wrapping: arr_idx upshift may easily wrap, whereas\n\t\t\t * length downshift won't.\n\t\t\t */\n\t\t\tif (arr_idx < (h_bufobj->length >> h_bufobj->shift)) {\n\t\t\t\tbyte_off = arr_idx << h_bufobj->shift;  /* no wrap assuming h_bufobj->length is valid */\n\t\t\t\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\t\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t\tduk_uint8_t *data;\n\n\t\t\t\t\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\t\t\t\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\t\t\t\t\tduk_hbufobj_push_validated_read(thr, h_bufobj, data, elem_size);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (read zero)\"));\n\t\t\t\t\t\tduk_push_uint(thr, 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t\t                  DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(obj) != DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\t\t\t\t/* ArrayBuffer indices are non-standard and are\n\t\t\t\t\t * non-enumerable to avoid their serialization.\n\t\t\t\t\t */\n\t\t\t\t\tout_desc->flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t\t}\n\t\t\t\tout_desc->get = NULL;\n\t\t\t\tout_desc->set = NULL;\n\t\t\t\tout_desc->e_idx = -1;\n\t\t\t\tout_desc->h_idx = -1;\n\t\t\t\tout_desc->a_idx = -1;\n\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\t\tgoto prop_found_noexotic;  /* cannot be e.g. arguments exotic, since exotic 'traits' are mutually exclusive */\n\t\t\t} else {\n\t\t\t\t/* index is above internal buffer length -> property is fully normal */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index outside buffer -> normal property\"));\n\t\t\t}\n\t\t} else if (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, key is 'length', length exotic behavior\"));\n\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t/* Length in elements: take into account shift, but\n\t\t\t\t * intentionally don't check the underlying buffer here.\n\t\t\t\t */\n\t\t\t\tduk_push_uint(thr, h_bufobj->length >> h_bufobj->shift);\n\t\t\t}\n\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\tout_desc->get = NULL;\n\t\t\tout_desc->set = NULL;\n\t\t\tout_desc->e_idx = -1;\n\t\t\tout_desc->h_idx = -1;\n\t\t\tout_desc->a_idx = -1;\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t}\n\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\t/* Array properties have exotic behavior but they are concrete,\n\t * so no special handling here.\n\t *\n\t * Arguments exotic behavior (E5 Section 10.6, [[GetOwnProperty]]\n\t * is only relevant as a post-check implemented below; hence no\n\t * check here.\n\t */\n\n\t/*\n\t *  Not found as concrete or virtual.\n\t */\n\n prop_not_found:\n\tDUK_DDD(DUK_DDDPRINT(\"-> not found (virtual, entry part, or array part)\"));\n\tDUK_STATS_INC(thr->heap, stats_getownpropdesc_miss);\n\treturn 0;\n\n\t/*\n\t *  Found.\n\t *\n\t *  Arguments object has exotic post-processing, see E5 Section 10.6,\n\t *  description of [[GetOwnProperty]] variant for arguments.\n\t */\n\n prop_found:\n\tDUK_DDD(DUK_DDDPRINT(\"-> property found, checking for arguments exotic post-behavior\"));\n\n\t/* Notes:\n\t *  - Only numbered indices are relevant, so arr_idx fast reject is good\n\t *    (this is valid unless there are more than 4**32-1 arguments).\n\t *  - Since variable lookup has no side effects, this can be skipped if\n\t *    DUK_GETDESC_FLAG_PUSH_VALUE is not set.\n\t */\n\n\tif (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) &&\n\t                 arr_idx != DUK__NO_ARRAY_INDEX &&\n\t                 (flags & DUK_GETDESC_FLAG_PUSH_VALUE))) {\n\t\tduk_propdesc temp_desc;\n\n\t\t/* Magically bound variable cannot be an accessor.  However,\n\t\t * there may be an accessor property (or a plain property) in\n\t\t * place with magic behavior removed.  This happens e.g. when\n\t\t * a magic property is redefined with defineProperty().\n\t\t * Cannot assert for \"not accessor\" here.\n\t\t */\n\n\t\t/* replaces top of stack with new value if necessary */\n\t\tDUK_ASSERT((flags & DUK_GETDESC_FLAG_PUSH_VALUE) != 0);\n\n\t\t/* This can perform a variable lookup but only into a declarative\n\t\t * environment which has no side effects.\n\t\t */\n\t\tif (duk__check_arguments_map_for_get(thr, obj, key, &temp_desc)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> arguments exotic behavior overrides result: %!T -> %!T\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\t/* [... old_result result] -> [... result] */\n\t\t\tduk_remove_m2(thr);\n\t\t}\n\t}\n\n prop_found_noexotic:\n\tDUK_STATS_INC(thr->heap, stats_getownpropdesc_hit);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_bool_t duk_hobject_get_own_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_desc != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\treturn duk__get_own_propdesc_raw(thr, obj, key, DUK_HSTRING_GET_ARRIDX_SLOW(key), out_desc, flags);\n}\n\n/*\n *  ECMAScript compliant [[GetProperty]](P), for internal use only.\n *\n *  If property is found:\n *    - Fills descriptor fields to 'out_desc'\n *    - If DUK_GETDESC_FLAG_PUSH_VALUE is set, pushes a value related to the\n *      property onto the stack ('undefined' for accessor properties).\n *    - Returns non-zero\n *\n *  If property is not found:\n *    - 'out_desc' is left in untouched state (possibly garbage)\n *    - Nothing is pushed onto the stack (not even with DUK_GETDESC_FLAG_PUSH_VALUE\n *      set)\n *    - Returns zero\n *\n *  May cause arbitrary side effects and invalidate (most) duk_tval\n *  pointers.\n */\n\nDUK_LOCAL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags) {\n\tduk_hobject *curr;\n\tduk_uint32_t arr_idx;\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_desc != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_getpropdesc_count);\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__get_propdesc: thr=%p, obj=%p, key=%p, out_desc=%p, flags=%lx, \"\n\t                     \"arr_idx=%ld (obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (void *) out_desc,\n\t                     (long) flags, (long) arr_idx,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tcurr = obj;\n\tDUK_ASSERT(curr != NULL);\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (duk__get_own_propdesc_raw(thr, curr, key, arr_idx, out_desc, flags)) {\n\t\t\t/* stack contains value (if requested), 'out_desc' is set */\n\t\t\tDUK_STATS_INC(thr->heap, stats_getpropdesc_hit);\n\t\t\treturn 1;\n\t\t}\n\n\t\t/* not found in 'curr', next in prototype chain; impose max depth */\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tif (flags & DUK_GETDESC_FLAG_IGNORE_PROTOLOOP) {\n\t\t\t\t/* treat like property not found */\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t} while (curr != NULL);\n\n\t/* out_desc is left untouched (possibly garbage), caller must use return\n\t * value to determine whether out_desc can be looked up\n\t */\n\n\tDUK_STATS_INC(thr->heap, stats_getpropdesc_miss);\n\treturn 0;\n}\n\n/*\n *  Shallow fast path checks for accessing array elements with numeric\n *  indices.  The goal is to try to avoid coercing an array index to an\n *  (interned) string for the most common lookups, in particular, for\n *  standard Array objects.\n *\n *  Interning is avoided but only for a very narrow set of cases:\n *    - Object has array part, index is within array allocation, and\n *      value is not unused (= key exists)\n *    - Object has no interfering exotic behavior (e.g. arguments or\n *      string object exotic behaviors interfere, array exotic\n *      behavior does not).\n *\n *  Current shortcoming: if key does not exist (even if it is within\n *  the array allocation range) a slow path lookup with interning is\n *  always required.  This can probably be fixed so that there is a\n *  quick fast path for non-existent elements as well, at least for\n *  standard Array objects.\n */\n\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\nDUK_LOCAL duk_tval *duk__getprop_shallow_fastpath_array_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key) {\n\tduk_tval *tv;\n\tduk_uint32_t idx;\n\n\tDUK_UNREF(thr);\n\n\tif (!(DUK_HOBJECT_HAS_ARRAY_PART(obj) &&\n\t     !DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) &&\n\t     !DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj) &&\n\t     !DUK_HOBJECT_IS_BUFOBJ(obj) &&\n\t     !DUK_HOBJECT_IS_PROXY(obj))) {\n\t\t/* Must have array part and no conflicting exotic behaviors.\n\t\t * Doesn't need to have array special behavior, e.g. Arguments\n\t\t * object has array part.\n\t\t */\n\t\treturn NULL;\n\t}\n\n\t/* Arrays never have other exotic behaviors. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"fast path attempt (no exotic string/arguments/buffer \"\n\t                     \"behavior, object has array part)\"));\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"key is not a number\"));\n\t\treturn NULL;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside object 'a_size'.\n\t */\n\n\tif (idx >= DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"key is not an array index or outside array part\"));\n\t\treturn NULL;\n\t}\n\tDUK_ASSERT(idx != 0xffffffffUL);\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\t/* XXX: for array instances we could take a shortcut here and assume\n\t * Array.prototype doesn't contain an array index property.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"key is a valid array index and inside array part\"));\n\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, idx);\n\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> fast path successful\"));\n\t\treturn tv;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"fast path attempt failed, fall back to slow path\"));\n\treturn NULL;\n}\n\nDUK_LOCAL duk_bool_t duk__putprop_shallow_fastpath_array_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val) {\n\tduk_tval *tv;\n\tduk_harray *a;\n\tduk_uint32_t idx;\n\tduk_uint32_t old_len, new_len;\n\n\tif (!(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj) &&\n\t      DUK_HOBJECT_HAS_ARRAY_PART(obj) &&\n\t      DUK_HOBJECT_HAS_EXTENSIBLE(obj))) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));  /* caller ensures */\n\n\ta = (duk_harray *) obj;\n\tDUK_HARRAY_ASSERT_VALID(a);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"key is not a number\"));\n\t\treturn 0;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside object 'a_size'.\n\t */\n\n\tif (idx >= DUK_HOBJECT_GET_ASIZE(obj)) {  /* for resizing of array part, use slow path */\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(idx != 0xffffffffUL);\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\told_len = a->length;\n\n\tif (idx >= old_len) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"write new array entry requires length update \"\n\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t                     (long) idx, (long) old_len));\n\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a)) {\n\t\t\t/* The correct behavior here is either a silent error\n\t\t\t * or a TypeError, depending on strictness.  Fall back\n\t\t\t * to the slow path to handle the situation.\n\t\t\t */\n\t\t\treturn 0;\n\t\t}\n\t\tnew_len = idx + 1;\n\n\t\t((duk_harray *) obj)->length = new_len;\n\t}\n\n\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, idx);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val);  /* side effects */\n\n\tDUK_DDD(DUK_DDDPRINT(\"array fast path success for index %ld\", (long) idx));\n\treturn 1;\n}\n#endif  /* DUK_USE_ARRAY_PROP_FASTPATH */\n\n/*\n *  Fast path for bufobj getprop/putprop\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL duk_bool_t duk__getprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key) {\n\tduk_uint32_t idx;\n\tduk_hbufobj *h_bufobj;\n\tduk_uint_t byte_off;\n\tduk_small_uint_t elem_size;\n\tduk_uint8_t *data;\n\n\tif (!DUK_HOBJECT_IS_BUFOBJ(obj)) {\n\t\treturn 0;\n\t}\n\th_bufobj = (duk_hbufobj *) obj;\n\tif (!DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\treturn 0;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\treturn 0;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside bufobj length.\n\t */\n\n\t/* Careful with wrapping (left shifting idx would be unsafe). */\n\tif (idx >= (h_bufobj->length >> h_bufobj->shift)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\tbyte_off = idx << h_bufobj->shift;  /* no wrap assuming h_bufobj->length is valid */\n\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\n\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\tduk_hbufobj_push_validated_read(thr, h_bufobj, data, elem_size);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (read zero)\"));\n\t\tduk_push_uint(thr, 0);\n\t}\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL duk_bool_t duk__putprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val) {\n\tduk_uint32_t idx;\n\tduk_hbufobj *h_bufobj;\n\tduk_uint_t byte_off;\n\tduk_small_uint_t elem_size;\n\tduk_uint8_t *data;\n\n\tif (!(DUK_HOBJECT_IS_BUFOBJ(obj) &&\n\t      DUK_TVAL_IS_NUMBER(tv_val))) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));  /* caller ensures; rom objects are never bufobjs now */\n\n\th_bufobj = (duk_hbufobj *) obj;\n\tif (!DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\treturn 0;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\treturn 0;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside bufobj length.\n\t */\n\n\t/* Careful with wrapping (left shifting idx would be unsafe). */\n\tif (idx >= (h_bufobj->length >> h_bufobj->shift)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\tbyte_off = idx << h_bufobj->shift;  /* no wrap assuming h_bufobj->length is valid */\n\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\n\t/* Value is required to be a number in the fast path so there\n\t * are no side effects in write coercion.\n\t */\n\tduk_push_tval(thr, tv_val);\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\n\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\tduk_hbufobj_validated_write(thr, h_bufobj, data, elem_size);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (write skipped)\"));\n\t}\n\n\tduk_pop_unsafe(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  GETPROP: ECMAScript property read.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) {\n\tduk_tval tv_obj_copy;\n\tduk_tval tv_key_copy;\n\tduk_hobject *curr = NULL;\n\tduk_hstring *key = NULL;\n\tduk_uint32_t arr_idx = DUK__NO_ARRAY_INDEX;\n\tduk_propdesc desc;\n\tduk_uint_t sanity;\n\n\tDUK_DDD(DUK_DDDPRINT(\"getprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key,\n\t                     (duk_tval *) tv_obj, (duk_tval *) tv_key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_getprop_all);\n\n\t/*\n\t *  Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of\n\t *  them being invalidated by a valstack resize.\n\t *\n\t *  XXX: this is now an overkill for many fast paths.  Rework this\n\t *  to be faster (although switching to a valstack discipline might\n\t *  be a better solution overall).\n\t */\n\n\tDUK_TVAL_SET_TVAL(&tv_obj_copy, tv_obj);\n\tDUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);\n\ttv_obj = &tv_obj_copy;\n\ttv_key = &tv_key_copy;\n\n\t/*\n\t *  Coercion and fast path processing\n\t */\n\n\tswitch (DUK_TVAL_GET_TAG(tv_obj)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL: {\n\t\t/* Note: unconditional throw */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is undefined or null -> reject\"));\n#if defined(DUK_USE_PARANOID_ERRORS)\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\t\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot read property %s of %s\",\n\t\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\t\tDUK_WO_NORETURN(return 0;);\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a boolean, start lookup from boolean prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);\n\t\tduk_int_t pop_count;\n\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\t/* Symbols (ES2015 or hidden) don't have virtual properties. */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a symbol, start lookup from symbol prototype\"));\n\t\t\tcurr = thr->builtins[DUK_BIDX_SYMBOL_PROTOTYPE];\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_FASTINT)\n\t\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\t\tarr_idx = duk__tval_fastint_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a fast-path fastint; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else\n#endif\n\t\tif (DUK_TVAL_IS_NUMBER(tv_key)) {\n\t\t\tarr_idx = duk__tval_number_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a fast-path number; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t\tpop_count = 1;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {\n\t\t\tduk_pop_n_unsafe(thr, pop_count);\n\t\t\tduk_push_hstring(thr, h);\n\t\t\tduk_substring(thr, -1, arr_idx, arr_idx + 1);  /* [str] -> [substr] */\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_stringidx);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is string, key is an index inside string length \"\n\t\t\t                     \"after coercion -> return char)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (pop_count == 0) {\n\t\t\t/* This is a pretty awkward control flow, but we need to recheck the\n\t\t\t * key coercion here.\n\t\t\t */\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tduk_pop_unsafe(thr);  /* [key] -> [] */\n\t\t\tduk_push_uint(thr, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h));  /* [] -> [res] */\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_stringlen);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is string, key is 'length' after coercion -> \"\n\t\t\t                     \"return string length)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a string, start lookup from string prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_STRING_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_OBJECT: {\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\n\t\tduk_tval *tmp;\n#endif\n\n\t\tcurr = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(curr != NULL);\n\n\t\t/* XXX: array .length fast path (important in e.g. loops)? */\n\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\n\t\ttmp = duk__getprop_shallow_fastpath_array_tval(thr, curr, tv_key);\n\t\tif (tmp) {\n\t\t\tduk_push_tval(thr, tmp);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is object, key is a number, array part \"\n\t\t\t                     \"fast path)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_arrayidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (duk__getprop_fastpath_bufobj_tval(thr, curr, tv_key) != 0) {\n\t\t\t/* Read value pushed on stack. */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is bufobj, key is a number, bufobj \"\n\t\t\t                     \"fast path)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_bufobjidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(curr))) {\n\t\t\tduk_hobject *h_target;\n\n\t\t\tif (duk__proxy_check_prop(thr, curr, DUK_STRIDX_GET, tv_key, &h_target)) {\n\t\t\t\t/* -> [ ... trap handler ] */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'get' for key %!T\", (duk_tval *) tv_key));\n\t\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_proxy);\n\t\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\t\tduk_push_tval(thr, tv_key);       /* P */\n\t\t\t\tduk_push_tval(thr, tv_obj);       /* Receiver: Proxy object */\n\t\t\t\tduk_call_method(thr, 3 /*nargs*/);\n\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\t\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\t\t\t\tduk_tval *tv_hook = duk_require_tval(thr, -3);  /* value from hook */\n\t\t\t\t\tduk_tval *tv_targ = duk_require_tval(thr, -1);  /* value from target */\n\t\t\t\t\tduk_bool_t datadesc_reject;\n\t\t\t\t\tduk_bool_t accdesc_reject;\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'get': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; tv_hook=%!T, tv_targ=%!T, desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (duk_tval *) tv_hook, (duk_tval *) tv_targ,\n\t\t\t\t\t                     (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\n\t\t\t\t\tdatadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) &&\n\t\t\t\t\t                  !duk_js_samevalue(tv_hook, tv_targ);\n\t\t\t\t\taccdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                 !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                 (desc.get == NULL) &&\n\t\t\t\t\t                 !DUK_TVAL_IS_UNDEFINED(tv_hook);\n\t\t\t\t\tif (datadesc_reject || accdesc_reject) {\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\n\t\t\t\t\tduk_pop_2_unsafe(thr);\n\t\t\t\t} else {\n\t\t\t\t\tduk_pop_unsafe(thr);\n\t\t\t\t}\n\t\t\t\treturn 1;  /* return value */\n\t\t\t}\n\n\t\t\tcurr = h_target;  /* resume lookup from target */\n\t\t\tDUK_TVAL_SET_OBJECT(tv_obj, curr);\n\t\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(curr)) {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_arguments);\n\t\t\tif (duk__check_arguments_map_for_get(thr, curr, key, &desc)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is object with arguments exotic behavior, \"\n\t\t\t\t                     \"key matches magically bound property -> skip standard \"\n\t\t\t\t                     \"Get with replacement value)\",\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t\t/* no need for 'caller' post-check, because 'key' must be an array index */\n\n\t\t\t\tduk_remove_m2(thr);  /* [key result] -> [result] */\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tgoto lookup;  /* avoid double coercion */\n\t\t}\n\t\tbreak;\n\t}\n\n\t/* Buffer has virtual properties similar to string, but indexed values\n\t * are numbers, not 1-byte buffers/strings which would perform badly.\n\t */\n\tcase DUK_TAG_BUFFER: {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);\n\t\tduk_int_t pop_count;\n\n\t\t/*\n\t\t *  Because buffer values are often looped over, a number fast path\n\t\t *  is important.\n\t\t */\n\n#if defined(DUK_USE_FASTINT)\n\t\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\t\tarr_idx = duk__tval_fastint_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path fastint; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t}\n\t\telse\n#endif\n\t\tif (DUK_TVAL_IS_NUMBER(tv_key)) {\n\t\t\tarr_idx = duk__tval_number_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path number; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t\tpop_count = 1;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HBUFFER_GET_SIZE(h)) {\n\t\t\tduk_pop_n_unsafe(thr, pop_count);\n\t\t\tduk_push_uint(thr, ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h))[arr_idx]);\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_bufferidx);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is buffer, key is an index inside buffer length \"\n\t\t\t                     \"after coercion -> return byte as number)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (pop_count == 0) {\n\t\t\t/* This is a pretty awkward control flow, but we need to recheck the\n\t\t\t * key coercion here.\n\t\t\t */\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tduk_pop_unsafe(thr);  /* [key] -> [] */\n\t\t\tduk_push_uint(thr, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h));  /* [] -> [res] */\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_bufferlen);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is buffer, key is 'length' \"\n\t\t\t                     \"after coercion -> return buffer length)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a buffer, start lookup from Uint8Array prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_POINTER: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a pointer, start lookup from pointer prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Lightfuncs inherit getter .name and .length from %NativeFunctionPrototype%. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a lightfunc, start lookup from function prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE];\n\t\tbreak;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a number, start lookup from number prototype\"));\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_obj));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_obj));\n\t\tcurr = thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE];\n\t\tbreak;\n\t}\n\t}\n\n\t/* key coercion (unless already coerced above) */\n\tDUK_ASSERT(key == NULL);\n\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\tDUK_ASSERT(key != NULL);\n\t/*\n\t *  Property lookup\n\t */\n\n lookup:\n\t/* [key] (coerced) */\n\tDUK_ASSERT(curr != NULL);\n\tDUK_ASSERT(key != NULL);\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (!duk__get_own_propdesc_raw(thr, curr, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\t\tgoto next_in_chain;\n\t\t}\n\n\t\tif (desc.get != NULL) {\n\t\t\t/* accessor with defined getter */\n\t\t\tDUK_ASSERT((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0);\n\n\t\t\tduk_pop_unsafe(thr);              /* [key undefined] -> [key] */\n\t\t\tduk_push_hobject(thr, desc.get);\n\t\t\tduk_push_tval(thr, tv_obj);       /* note: original, uncoerced base */\n#if defined(DUK_USE_NONSTD_GETTER_KEY_ARGUMENT)\n\t\t\tduk_dup_m3(thr);\n\t\t\tduk_call_method(thr, 1);          /* [key getter this key] -> [key retval] */\n#else\n\t\t\tduk_call_method(thr, 0);          /* [key getter this] -> [key retval] */\n#endif\n\t\t} else {\n\t\t\t/* [key value] or [key undefined] */\n\n\t\t\t/* data property or accessor without getter */\n\t\t\tDUK_ASSERT(((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) == 0) ||\n\t\t\t           (desc.get == NULL));\n\n\t\t\t/* if accessor without getter, return value is undefined */\n\t\t\tDUK_ASSERT(((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) == 0) ||\n\t\t\t           duk_is_undefined(thr, -1));\n\n\t\t\t/* Note: for an accessor without getter, falling through to\n\t\t\t * check for \"caller\" exotic behavior is unnecessary as\n\t\t\t * \"undefined\" will never activate the behavior.  But it does\n\t\t\t * no harm, so we'll do it anyway.\n\t\t\t */\n\t\t}\n\n\t\tgoto found;  /* [key result] */\n\n\t next_in_chain:\n\t\t/* XXX: option to pretend property doesn't exist if sanity limit is\n\t\t * hit might be useful.\n\t\t */\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t} while (curr != NULL);\n\n\t/*\n\t *  Not found\n\t */\n\n\tduk_to_undefined(thr, -1);  /* [key] -> [undefined] (default value) */\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (not found)\", (duk_tval *) duk_get_tval(thr, -1)));\n\treturn 0;\n\n\t/*\n\t *  Found; post-processing (Function and arguments objects)\n\t */\n\n found:\n\t/* [key result] */\n\n#if !defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t/* Special behavior for 'caller' property of (non-bound) function objects\n\t * and non-strict Arguments objects: if 'caller' -value- (!) is a strict\n\t * mode function, throw a TypeError (E5 Sections 15.3.5.4, 10.6).\n\t * Quite interestingly, a non-strict function with no formal arguments\n\t * will get an arguments object -without- special 'caller' behavior!\n\t *\n\t * The E5.1 spec is a bit ambiguous if this special behavior applies when\n\t * a bound function is the base value (not the 'caller' value): Section\n\t * 15.3.4.5 (describing bind()) states that [[Get]] for bound functions\n\t * matches that of Section 15.3.5.4 ([[Get]] for Function instances).\n\t * However, Section 13.3.5.4 has \"NOTE: Function objects created using\n\t * Function.prototype.bind use the default [[Get]] internal method.\"\n\t * The current implementation assumes this means that bound functions\n\t * should not have the special [[Get]] behavior.\n\t *\n\t * The E5.1 spec is also a bit unclear if the TypeError throwing is\n\t * applied if the 'caller' value is a strict bound function.  The\n\t * current implementation will throw even for both strict non-bound\n\t * and strict bound functions.\n\t *\n\t * See test-dev-strict-func-as-caller-prop-value.js for quite extensive\n\t * tests.\n\t *\n\t * This exotic behavior is disabled when the non-standard 'caller' property\n\t * is enabled, as it conflicts with the free use of 'caller'.\n\t */\n\tif (key == DUK_HTHREAD_STRING_CALLER(thr) &&\n\t    DUK_TVAL_IS_OBJECT(tv_obj)) {\n\t\tduk_hobject *orig = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(orig != NULL);\n\n\t\tif (DUK_HOBJECT_IS_NONBOUND_FUNCTION(orig) ||\n\t\t    DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(orig)) {\n\t\t\tduk_hobject *h;\n\n\t\t\t/* XXX: The TypeError is currently not applied to bound\n\t\t\t * functions because the 'strict' flag is not copied by\n\t\t\t * bind().  This may or may not be correct, the specification\n\t\t\t * only refers to the value being a \"strict mode Function\n\t\t\t * object\" which is ambiguous.\n\t\t\t */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(orig));\n\n\t\t\th = duk_get_hobject(thr, -1);  /* NULL if not an object */\n\t\t\tif (h &&\n\t\t\t    DUK_HOBJECT_IS_FUNCTION(h) &&\n\t\t\t    DUK_HOBJECT_HAS_STRICT(h)) {\n\t\t\t\t/* XXX: sufficient to check 'strict', assert for 'is function' */\n\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_STRICT_CALLER_READ);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\t}\n#endif   /* !DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */\n\n\tduk_remove_m2(thr);  /* [key result] -> [result] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (found)\", (duk_tval *) duk_get_tval(thr, -1)));\n\treturn 1;\n}\n\n/*\n *  HASPROP: ECMAScript property existence check (\"in\" operator).\n *\n *  Interestingly, the 'in' operator does not do any coercion of\n *  the target object.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) {\n\tduk_tval tv_key_copy;\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_uint32_t arr_idx;\n\tduk_bool_t rc;\n\tduk_propdesc desc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"hasprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key,\n\t                     (duk_tval *) tv_obj, (duk_tval *) tv_key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);\n\ttv_key = &tv_key_copy;\n\n\t/*\n\t *  The 'in' operator requires an object as its right hand side,\n\t *  throwing a TypeError unconditionally if this is not the case.\n\t *\n\t *  However, lightfuncs need to behave like fully fledged objects\n\t *  here to be maximally transparent, so we need to handle them\n\t *  here.  Same goes for plain buffers which behave like ArrayBuffers.\n\t */\n\n\t/* XXX: Refactor key coercion so that it's only called once.  It can't\n\t * be trivially lifted here because the object must be type checked\n\t * first.\n\t */\n\n\tif (DUK_TVAL_IS_OBJECT(tv_obj)) {\n\t\tobj = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(obj != NULL);\n\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t} else if (DUK_TVAL_IS_BUFFER(tv_obj)) {\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\tif (duk__key_is_plain_buf_ownprop(thr, DUK_TVAL_GET_BUFFER(tv_obj), key, arr_idx)) {\n\t\t\trc = 1;\n\t\t\tgoto pop_and_return;\n\t\t}\n\t\tobj = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) {\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\n\t\t/* If not found, resume existence check from %NativeFunctionPrototype%.\n\t\t * We can just substitute the value in this case; nothing will\n\t\t * need the original base value (as would be the case with e.g.\n\t\t * setters/getters.\n\t\t */\n\t\tobj = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE];\n\t} else {\n\t\t/* Note: unconditional throw */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is not an object -> reject\"));\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* XXX: fast path for arrays? */\n\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(arr_idx);\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(obj))) {\n\t\tduk_hobject *h_target;\n\t\tduk_bool_t tmp_bool;\n\n\t\t/* XXX: the key in 'key in obj' is string coerced before we're called\n\t\t * (which is the required behavior in E5/E5.1/E6) so the key is a string\n\t\t * here already.\n\t\t */\n\n\t\tif (duk__proxy_check_prop(thr, obj, DUK_STRIDX_HAS, tv_key, &h_target)) {\n\t\t\t/* [ ... key trap handler ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'has' for key %!T\", (duk_tval *) tv_key));\n\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\tduk_push_tval(thr, tv_key);       /* P */\n\t\t\tduk_call_method(thr, 2 /*nargs*/);\n\t\t\ttmp_bool = duk_to_boolean_top_pop(thr);\n\t\t\tif (!tmp_bool) {\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'has': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\t\t\t\t\t/* XXX: Extensibility check for target uses IsExtensible().  If we\n\t\t\t\t\t * implemented the isExtensible trap and didn't reject proxies as\n\t\t\t\t\t * proxy targets, it should be respected here.\n\t\t\t\t\t */\n\t\t\t\t\tif (!((desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&  /* property is configurable and */\n\t\t\t\t\t      DUK_HOBJECT_HAS_EXTENSIBLE(h_target))) {          /* ... target is extensible */\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_pop_unsafe(thr);  /* [ key ] -> [] */\n\t\t\treturn tmp_bool;\n\t\t}\n\n\t\tobj = h_target;  /* resume check from proxy target */\n\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t/* XXX: inline into a prototype walking loop? */\n\n\trc = duk__get_propdesc(thr, obj, key, &desc, 0 /*flags*/);  /* don't push value */\n\t/* fall through */\n\n pop_and_return:\n\tduk_pop_unsafe(thr);  /* [ key ] -> [] */\n\treturn rc;\n}\n\n/*\n *  HASPROP variant used internally.\n *\n *  This primitive must never throw an error, callers rely on this.\n *  In particular, don't throw an error for prototype loops; instead,\n *  pretend like the property doesn't exist if a prototype sanity limit\n *  is reached.\n *\n *  Does not implement proxy behavior: if applied to a proxy object,\n *  returns key existence on the proxy object itself.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key) {\n\tduk_propdesc dummy;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\treturn duk__get_propdesc(thr, obj, key, &dummy, DUK_GETDESC_FLAG_IGNORE_PROTOLOOP);  /* don't push value */\n}\n\n/*\n *  Helper: handle Array object 'length' write which automatically\n *  deletes properties, see E5 Section 15.4.5.1, step 3.  This is\n *  quite tricky to get right.\n *\n *  Used by duk_hobject_putprop().\n */\n\n/* Coerce a new .length candidate to a number and check that it's a valid\n * .length.\n */\nDUK_LOCAL duk_uint32_t duk__to_new_array_length_checked(duk_hthread *thr, duk_tval *tv) {\n\tduk_uint32_t res;\n\tduk_double_t d;\n\n#if !defined(DUK_USE_PREFER_SIZE)\n#if defined(DUK_USE_FASTINT)\n\t/* When fastints are enabled, the most interesting case is assigning\n\t * a fastint to .length (e.g. arr.length = 0).\n\t */\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\t/* Very common case. */\n\t\tduk_int64_t fi;\n\t\tfi = DUK_TVAL_GET_FASTINT(tv);\n\t\tif (fi < 0 || fi > DUK_I64_CONSTANT(0xffffffff)) {\n\t\t\tgoto fail_range;\n\t\t}\n\t\treturn (duk_uint32_t) fi;\n\t}\n#else  /* DUK_USE_FASTINT */\n\t/* When fastints are not enabled, the most interesting case is any\n\t * number.\n\t */\n\tif (DUK_TVAL_IS_DOUBLE(tv)) {\n\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t}\n#endif  /* DUK_USE_FASTINT */\n\telse\n#endif  /* !DUK_USE_PREFER_SIZE */\n\t{\n\t\t/* In all other cases, and when doing a size optimized build,\n\t\t * fall back to the comprehensive handler.\n\t\t */\n\t\td = duk_js_tonumber(thr, tv);\n\t}\n\n\t/* Refuse to update an Array's 'length' to a value outside the\n\t * 32-bit range.  Negative zero is accepted as zero.\n\t */\n\tres = duk_double_to_uint32_t(d);\n\tif ((duk_double_t) res != d) {\n\t\tgoto fail_range;\n\t}\n\n\treturn res;\n\n fail_range:\n\tDUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARRAY_LENGTH);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Delete elements required by a smaller length, taking into account\n * potentially non-configurable elements.  Returns non-zero if all\n * elements could be deleted, and zero if all or some elements could\n * not be deleted.  Also writes final \"target length\" to 'out_result_len'.\n * This is the length value that should go into the 'length' property\n * (must be set by the caller).  Never throws an error.\n */\nDUK_LOCAL\nduk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr,\n                                                duk_hobject *obj,\n                                                duk_uint32_t old_len,\n                                                duk_uint32_t new_len,\n                                                duk_bool_t force_flag,\n                                                duk_uint32_t *out_result_len) {\n\tduk_uint32_t target_len;\n\tduk_uint_fast32_t i;\n\tduk_uint32_t arr_idx;\n\tduk_hstring *key;\n\tduk_tval *tv;\n\tduk_bool_t rc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"new array length smaller than old (%ld -> %ld), \"\n\t                     \"probably need to remove elements\",\n\t                     (long) old_len, (long) new_len));\n\n\t/*\n\t *  New length is smaller than old length, need to delete properties above\n\t *  the new length.\n\t *\n\t *  If array part exists, this is straightforward: array entries cannot\n\t *  be non-configurable so this is guaranteed to work.\n\t *\n\t *  If array part does not exist, array-indexed values are scattered\n\t *  in the entry part, and some may not be configurable (preventing length\n\t *  from becoming lower than their index + 1).  To handle the algorithm\n\t *  in E5 Section 15.4.5.1, step l correctly, we scan the entire property\n\t *  set twice.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(new_len < old_len);\n\tDUK_ASSERT(out_result_len != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj));\n\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY(obj));\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t/*\n\t\t *  All defined array-indexed properties are in the array part\n\t\t *  (we assume the array part is comprehensive), and all array\n\t\t *  entries are writable, configurable, and enumerable.  Thus,\n\t\t *  nothing can prevent array entries from being deleted.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"have array part, easy case\"));\n\n\t\tif (old_len < DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\t\t/* XXX: assertion that entries >= old_len are already unused */\n\t\t\ti = old_len;\n\t\t} else {\n\t\t\ti = DUK_HOBJECT_GET_ASIZE(obj);\n\t\t}\n\t\tDUK_ASSERT(i <= DUK_HOBJECT_GET_ASIZE(obj));\n\n\t\twhile (i > new_len) {\n\t\t\ti--;\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\t\tDUK_TVAL_SET_UNUSED_UPDREF(thr, tv);  /* side effects */\n\t\t}\n\n\t\t*out_result_len = new_len;\n\t\treturn 1;\n\t} else {\n\t\t/*\n\t\t *  Entries part is a bit more complex.\n\t\t */\n\n\t\t/* Stage 1: find highest preventing non-configurable entry (if any).\n\t\t * When forcing, ignore non-configurability.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"no array part, slow case\"));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part, stage 1: find target_len \"\n\t\t                     \"(highest preventing non-configurable entry (if any))\"));\n\n\t\ttarget_len = new_len;\n\t\tif (force_flag) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part; force flag -> skip stage 1\"));\n\t\t\tgoto skip_stage1;\n\t\t}\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);\n\t\t\tif (!key) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: null key\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!DUK_HSTRING_HAS_ARRIDX(key)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key not an array index\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(key));  /* XXX: macro checks for array index flag, which is unnecessary here */\n\t\t\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\t\t\tDUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX);\n\t\t\tDUK_ASSERT(arr_idx < old_len);  /* consistency requires this */\n\n\t\t\tif (arr_idx < new_len) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key is array index %ld, below new_len\",\n\t\t\t\t                     (long) i, (long) arr_idx));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(thr->heap, obj, i)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key is a relevant array index %ld, but configurable\",\n\t\t\t\t                     (long) i, (long) arr_idx));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* relevant array index is non-configurable, blocks write */\n\t\t\tif (arr_idx >= target_len) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"entry at index %ld has arr_idx %ld, is not configurable, \"\n\t\t\t\t                     \"update target_len %ld -> %ld\",\n\t\t\t\t                     (long) i, (long) arr_idx, (long) target_len,\n\t\t\t\t                     (long) (arr_idx + 1)));\n\t\t\t\ttarget_len = arr_idx + 1;\n\t\t\t}\n\t\t}\n\t skip_stage1:\n\n\t\t/* stage 2: delete configurable entries above target length */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"old_len=%ld, new_len=%ld, target_len=%ld\",\n\t\t                     (long) old_len, (long) new_len, (long) target_len));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part, stage 2: remove \"\n\t\t                     \"entries >= target_len\"));\n\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);\n\t\t\tif (!key) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: null key\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!DUK_HSTRING_HAS_ARRIDX(key)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key not an array index\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(key));  /* XXX: macro checks for array index flag, which is unnecessary here */\n\t\t\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\t\t\tDUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX);\n\t\t\tDUK_ASSERT(arr_idx < old_len);  /* consistency requires this */\n\n\t\t\tif (arr_idx < target_len) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key is array index %ld, below target_len\",\n\t\t\t\t                     (long) i, (long) arr_idx));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tDUK_ASSERT(force_flag || DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(thr->heap, obj, i));  /* stage 1 guarantees */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"delete entry index %ld: key is array index %ld\",\n\t\t\t                     (long) i, (long) arr_idx));\n\n\t\t\t/*\n\t\t\t *  Slow delete, but we don't care as we're already in a very slow path.\n\t\t\t *  The delete always succeeds: key has no exotic behavior, property\n\t\t\t *  is configurable, and no resize occurs.\n\t\t\t */\n\t\t\trc = duk_hobject_delprop_raw(thr, obj, key, force_flag ? DUK_DELPROP_FLAG_FORCE : 0);\n\t\t\tDUK_UNREF(rc);\n\t\t\tDUK_ASSERT(rc != 0);\n\t\t}\n\n\t\t/* stage 3: update length (done by caller), decide return code */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part, stage 3: update length (done by caller)\"));\n\n\t\t*out_result_len = target_len;\n\n\t\tif (target_len == new_len) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"target_len matches new_len, return success\"));\n\t\t\treturn 1;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"target_len does not match new_len (some entry prevented \"\n\t\t                     \"full length adjustment), return error\"));\n\t\treturn 0;\n\t}\n\n\tDUK_UNREACHABLE();\n}\n\n/* XXX: is valstack top best place for argument? */\nDUK_LOCAL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject *obj) {\n\tduk_harray *a;\n\tduk_uint32_t old_len;\n\tduk_uint32_t new_len;\n\tduk_uint32_t result_len;\n\tduk_bool_t rc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"handling a put operation to array 'length' exotic property, \"\n\t                     \"new val: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj));\n\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY(obj));\n\ta = (duk_harray *) obj;\n\tDUK_HARRAY_ASSERT_VALID(a);\n\n\tDUK_ASSERT(duk_is_valid_index(thr, -1));\n\n\t/*\n\t *  Get old and new length\n\t */\n\n\told_len = a->length;\n\tnew_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_NEGIDX(thr, -1));\n\tDUK_DDD(DUK_DDDPRINT(\"old_len=%ld, new_len=%ld\", (long) old_len, (long) new_len));\n\n\t/*\n\t *  Writability check\n\t */\n\n\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"length is not writable, fail\"));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  New length not lower than old length => no changes needed\n\t *  (not even array allocation).\n\t */\n\n\tif (new_len >= old_len) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"new length is same or higher than old length, just update length, no deletions\"));\n\t\ta->length = new_len;\n\t\treturn 1;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"new length is lower than old length, probably must delete entries\"));\n\n\t/*\n\t *  New length lower than old length => delete elements, then\n\t *  update length.\n\t *\n\t *  Note: even though a bunch of elements have been deleted, the 'desc' is\n\t *  still valid as properties haven't been resized (and entries compacted).\n\t */\n\n\trc = duk__handle_put_array_length_smaller(thr, obj, old_len, new_len, 0 /*force_flag*/, &result_len);\n\tDUK_ASSERT(result_len >= new_len && result_len <= old_len);\n\n\ta->length = result_len;\n\n\t/* XXX: shrink array allocation or entries compaction here? */\n\n\treturn rc;\n}\n\n/*\n *  PUTPROP: ECMAScript property write.\n *\n *  Unlike ECMAScript primitive which returns nothing, returns 1 to indicate\n *  success and 0 to indicate failure (assuming throw is not set).\n *\n *  This is an extremely tricky function.  Some examples:\n *\n *    * Currently a decref may trigger a GC, which may compact an object's\n *      property allocation.  Consequently, any entry indices (e_idx) will\n *      be potentially invalidated by a decref.\n *\n *    * Exotic behaviors (strings, arrays, arguments object) require,\n *      among other things:\n *\n *      - Preprocessing before and postprocessing after an actual property\n *        write.  For example, array index write requires pre-checking the\n *        array 'length' property for access control, and may require an\n *        array 'length' update after the actual write has succeeded (but\n *        not if it fails).\n *\n *      - Deletion of multiple entries, as a result of array 'length' write.\n *\n *    * Input values are taken as pointers which may point to the valstack.\n *      If valstack is resized because of the put (this may happen at least\n *      when the array part is abandoned), the pointers can be invalidated.\n *      (We currently make a copy of all of the input values to avoid issues.)\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_tval *tv_val, duk_bool_t throw_flag) {\n\tduk_tval tv_obj_copy;\n\tduk_tval tv_key_copy;\n\tduk_tval tv_val_copy;\n\tduk_hobject *orig = NULL;  /* NULL if tv_obj is primitive */\n\tduk_hobject *curr;\n\tduk_hstring *key = NULL;\n\tduk_propdesc desc;\n\tduk_tval *tv;\n\tduk_uint32_t arr_idx;\n\tduk_bool_t rc;\n\tduk_int_t e_idx;\n\tduk_uint_t sanity;\n\tduk_uint32_t new_array_length = 0;  /* 0 = no update */\n\n\tDUK_DDD(DUK_DDDPRINT(\"putprop: thr=%p, obj=%p, key=%p, val=%p, throw=%ld \"\n\t                     \"(obj -> %!T, key -> %!T, val -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key, (void *) tv_val,\n\t                     (long) throw_flag, (duk_tval *) tv_obj, (duk_tval *) tv_key, (duk_tval *) tv_val));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\tDUK_ASSERT(tv_val != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_putprop_all);\n\n\t/*\n\t *  Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of\n\t *  them being invalidated by a valstack resize.\n\t *\n\t *  XXX: this is an overkill for some paths, so optimize this later\n\t *  (or maybe switch to a stack arguments model entirely).\n\t */\n\n\tDUK_TVAL_SET_TVAL(&tv_obj_copy, tv_obj);\n\tDUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);\n\tDUK_TVAL_SET_TVAL(&tv_val_copy, tv_val);\n\ttv_obj = &tv_obj_copy;\n\ttv_key = &tv_key_copy;\n\ttv_val = &tv_val_copy;\n\n\t/*\n\t *  Coercion and fast path processing.\n\t */\n\n\tswitch (DUK_TVAL_GET_TAG(tv_obj)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL: {\n\t\t/* Note: unconditional throw */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is undefined or null -> reject (object=%!iT)\",\n\t\t                     (duk_tval *) tv_obj));\n#if defined(DUK_USE_PARANOID_ERRORS)\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\t\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot write property %s of %s\",\n\t\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\t\tDUK_WO_NORETURN(return 0;);\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a boolean, start lookup from boolean prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);\n\n\t\t/*\n\t\t *  Note: currently no fast path for array index writes.\n\t\t *  They won't be possible anyway as strings are immutable.\n\t\t */\n\n\t\tDUK_ASSERT(key == NULL);\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\t/* Symbols (ES2015 or hidden) don't have virtual properties. */\n\t\t\tcurr = thr->builtins[DUK_BIDX_SYMBOL_PROTOTYPE];\n\t\t\tgoto lookup;\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_writable;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {\n\t\t\tgoto fail_not_writable;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a string, start lookup from string prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_STRING_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_OBJECT: {\n\t\torig = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(orig != NULL);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\t\t/* With this check in place fast paths won't need read-only\n\t\t * object checks.  This is technically incorrect if there are\n\t\t * setters that cause no writes to ROM objects, but current\n\t\t * built-ins don't have such setters.\n\t\t */\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"attempt to putprop on read-only target object\"));\n\t\t\tgoto fail_not_writable_no_pop;  /* Must avoid duk_pop() in exit path */\n\t\t}\n#endif\n\n\t\t/* The fast path for array property put is not fully compliant:\n\t\t * If one places conflicting number-indexed properties into\n\t\t * Array.prototype (for example, a non-writable Array.prototype[7])\n\t\t * the fast path will incorrectly ignore them.\n\t\t *\n\t\t * This fast path could be made compliant by falling through\n\t\t * to the slow path if the previous value was UNUSED.  This would\n\t\t * also remove the need to check for extensibility.  Right now a\n\t\t * non-extensible array is slower than an extensible one as far\n\t\t * as writes are concerned.\n\t\t *\n\t\t * The fast path behavior is documented in more detail here:\n\t\t * tests/ecmascript/test-misc-array-fast-write.js\n\t\t */\n\n\t\t/* XXX: array .length? */\n\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\n\t\tif (duk__putprop_shallow_fastpath_array_tval(thr, orig, tv_key, tv_val) != 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array fast path success\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_arrayidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (duk__putprop_fastpath_bufobj_tval(thr, orig, tv_key, tv_val) != 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base is bufobj, key is a number, bufobj fast path\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_bufobjidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(orig))) {\n\t\t\tduk_hobject *h_target;\n\t\t\tduk_bool_t tmp_bool;\n\n\t\t\tif (duk__proxy_check_prop(thr, orig, DUK_STRIDX_SET, tv_key, &h_target)) {\n\t\t\t\t/* -> [ ... trap handler ] */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'set' for key %!T\", (duk_tval *) tv_key));\n\t\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_proxy);\n\t\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\t\tduk_push_tval(thr, tv_key);       /* P */\n\t\t\t\tduk_push_tval(thr, tv_val);       /* V */\n\t\t\t\tduk_push_tval(thr, tv_obj);       /* Receiver: Proxy object */\n\t\t\t\tduk_call_method(thr, 4 /*nargs*/);\n\t\t\t\ttmp_bool = duk_to_boolean_top_pop(thr);\n\t\t\t\tif (!tmp_bool) {\n\t\t\t\t\tgoto fail_proxy_rejected;\n\t\t\t\t}\n\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\t\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\t\t\t\tduk_tval *tv_targ = duk_require_tval(thr, -1);\n\t\t\t\t\tduk_bool_t datadesc_reject;\n\t\t\t\t\tduk_bool_t accdesc_reject;\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'set': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; tv_val=%!T, tv_targ=%!T, desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (duk_tval *) tv_val, (duk_tval *) tv_targ,\n\t\t\t\t\t                     (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\n\t\t\t\t\tdatadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) &&\n\t\t\t\t\t                  !duk_js_samevalue(tv_val, tv_targ);\n\t\t\t\t\taccdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                 !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                 (desc.set == NULL);\n\t\t\t\t\tif (datadesc_reject || accdesc_reject) {\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\n\t\t\t\t\tduk_pop_2_unsafe(thr);\n\t\t\t\t} else {\n\t\t\t\t\tduk_pop_unsafe(thr);\n\t\t\t\t}\n\t\t\t\treturn 1;  /* success */\n\t\t\t}\n\n\t\t\torig = h_target;  /* resume write to target */\n\t\t\tDUK_TVAL_SET_OBJECT(tv_obj, orig);\n\t\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t\tcurr = orig;\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_BUFFER: {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);\n\t\tduk_int_t pop_count = 0;\n\n\t\t/*\n\t\t *  Because buffer values may be looped over and read/written\n\t\t *  from, an array index fast path is important.\n\t\t */\n\n#if defined(DUK_USE_FASTINT)\n\t\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\t\tarr_idx = duk__tval_fastint_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path fastint; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else\n#endif\n\t\tif (DUK_TVAL_IS_NUMBER(tv_key)) {\n\t\t\tarr_idx = duk__tval_number_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path number; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t\tpop_count = 1;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HBUFFER_GET_SIZE(h)) {\n\t\t\tduk_uint8_t *data;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"writing to buffer data at index %ld\", (long) arr_idx));\n\t\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);\n\n\t\t\t/* XXX: duk_to_int() ensures we'll get 8 lowest bits as\n\t\t\t * as input is within duk_int_t range (capped outside it).\n\t\t\t */\n#if defined(DUK_USE_FASTINT)\n\t\t\t/* Buffer writes are often integers. */\n\t\t\tif (DUK_TVAL_IS_FASTINT(tv_val)) {\n\t\t\t\tdata[arr_idx] = (duk_uint8_t) DUK_TVAL_GET_FASTINT_U32(tv_val);\n\t\t\t}\n\t\t\telse\n#endif\n\t\t\t{\n\t\t\t\tduk_push_tval(thr, tv_val);\n\t\t\t\tdata[arr_idx] = (duk_uint8_t) duk_to_uint32(thr, -1);\n\t\t\t\tpop_count++;\n\t\t\t}\n\n\t\t\tduk_pop_n_unsafe(thr, pop_count);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"result: success (buffer data write)\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_bufferidx);\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (pop_count == 0) {\n\t\t\t/* This is a pretty awkward control flow, but we need to recheck the\n\t\t\t * key coercion here.\n\t\t\t */\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_writable;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a buffer, start lookup from Uint8Array prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_POINTER: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a pointer, start lookup from pointer prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Lightfuncs have no own properties and are considered non-extensible.\n\t\t * However, the write may be captured by an inherited setter which\n\t\t * means we can't stop the lookup here.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a lightfunc, start lookup from function prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE];\n\t\tbreak;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a number, start lookup from number prototype\"));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_obj));\n\t\tcurr = thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE];\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_ASSERT(key == NULL);\n\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\tDUK_ASSERT(key != NULL);\n\n lookup:\n\n\t/*\n\t *  Check whether the property already exists in the prototype chain.\n\t *  Note that the actual write goes into the original base object\n\t *  (except if an accessor property captures the write).\n\t */\n\n\t/* [key] */\n\n\tDUK_ASSERT(curr != NULL);\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (!duk__get_own_propdesc_raw(thr, curr, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\t\tgoto next_in_chain;\n\t\t}\n\n\t\tif (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t/*\n\t\t\t *  Found existing accessor property (own or inherited).\n\t\t\t *  Call setter with 'this' set to orig, and value as the only argument.\n\t\t\t *  Setter calls are OK even for ROM objects.\n\t\t\t *\n\t\t\t *  Note: no exotic arguments object behavior, because [[Put]] never\n\t\t\t *  calls [[DefineOwnProperty]] (E5 Section 8.12.5, step 5.b).\n\t\t\t */\n\n\t\t\tduk_hobject *setter;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"put to an own or inherited accessor, calling setter\"));\n\n\t\t\tsetter = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, curr, desc.e_idx);\n\t\t\tif (!setter) {\n\t\t\t\tgoto fail_no_setter;\n\t\t\t}\n\t\t\tduk_push_hobject(thr, setter);\n\t\t\tduk_push_tval(thr, tv_obj);  /* note: original, uncoerced base */\n\t\t\tduk_push_tval(thr, tv_val);  /* [key setter this val] */\n#if defined(DUK_USE_NONSTD_SETTER_KEY_ARGUMENT)\n\t\t\tduk_dup_m4(thr);\n\t\t\tduk_call_method(thr, 2);     /* [key setter this val key] -> [key retval] */\n#else\n\t\t\tduk_call_method(thr, 1);     /* [key setter this val] -> [key retval] */\n#endif\n\t\t\tduk_pop_unsafe(thr);         /* ignore retval -> [key] */\n\t\t\tgoto success_no_arguments_exotic;\n\t\t}\n\n\t\tif (orig == NULL) {\n\t\t\t/*\n\t\t\t *  Found existing own or inherited plain property, but original\n\t\t\t *  base is a primitive value.\n\t\t\t */\n\t\t\tDUK_DD(DUK_DDPRINT(\"attempt to create a new property in a primitive base object\"));\n\t\t\tgoto fail_base_primitive;\n\t\t}\n\n\t\tif (curr != orig) {\n\t\t\t/*\n\t\t\t *  Found existing inherited plain property.\n\t\t\t *  Do an access control check, and if OK, write\n\t\t\t *  new property to 'orig'.\n\t\t\t */\n\t\t\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(orig)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing inherited plain property, but original object is not extensible\"));\n\t\t\t\tgoto fail_not_extensible;\n\t\t\t}\n\t\t\tif (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing inherited plain property, original object is extensible, but inherited property is not writable\"));\n\t\t\t\tgoto fail_not_writable;\n\t\t\t}\n\t\t\tDUK_DD(DUK_DDPRINT(\"put to new property, object extensible, inherited property found and is writable\"));\n\t\t\tgoto create_new;\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Found existing own (non-inherited) plain property.\n\t\t\t *  Do an access control check and update in place.\n\t\t\t */\n\n\t\t\tif (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing own (non-inherited) plain property, but property is not writable\"));\n\t\t\t\tgoto fail_not_writable;\n\t\t\t}\n\t\t\tif (desc.flags & DUK_PROPDESC_FLAG_VIRTUAL) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing own (non-inherited) virtual property, property is writable\"));\n\n\t\t\t\tif (DUK_HOBJECT_IS_ARRAY(curr)) {\n\t\t\t\t\t/*\n\t\t\t\t\t *  Write to 'length' of an array is a very complex case\n\t\t\t\t\t *  handled in a helper which updates both the array elements\n\t\t\t\t\t *  and writes the new 'length'.  The write may result in an\n\t\t\t\t\t *  unconditional RangeError or a partial write (indicated\n\t\t\t\t\t *  by a return code).\n\t\t\t\t\t *\n\t\t\t\t\t *  Note: the helper has an unnecessary writability check\n\t\t\t\t\t *  for 'length', we already know it is writable.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_ASSERT(key == DUK_HTHREAD_STRING_LENGTH(thr));  /* only virtual array property */\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"writing existing 'length' property to array exotic, invoke complex helper\"));\n\n\t\t\t\t\t/* XXX: the helper currently assumes stack top contains new\n\t\t\t\t\t * 'length' value and the whole calling convention is not very\n\t\t\t\t\t * compatible with what we need.\n\t\t\t\t\t */\n\n\t\t\t\t\tduk_push_tval(thr, tv_val);  /* [key val] */\n\t\t\t\t\trc = duk__handle_put_array_length(thr, orig);\n\t\t\t\t\tduk_pop_unsafe(thr);  /* [key val] -> [key] */\n\t\t\t\t\tif (!rc) {\n\t\t\t\t\t\tgoto fail_array_length_partial;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* key is 'length', cannot match argument exotic behavior */\n\t\t\t\t\tgoto success_no_arguments_exotic;\n\t\t\t\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t\t\telse if (DUK_HOBJECT_IS_BUFOBJ(curr)) {\n\t\t\t\t\tduk_hbufobj *h_bufobj;\n\t\t\t\t\tduk_uint_t byte_off;\n\t\t\t\t\tduk_small_uint_t elem_size;\n\n\t\t\t\t\th_bufobj = (duk_hbufobj *) curr;\n\t\t\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"writable virtual property is in buffer object\"));\n\n\t\t\t\t\t/* Careful with wrapping: arr_idx upshift may easily wrap, whereas\n\t\t\t\t\t * length downshift won't.\n\t\t\t\t\t */\n\t\t\t\t\tif (arr_idx < (h_bufobj->length >> h_bufobj->shift) && DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\t\t\t\t\tduk_uint8_t *data;\n\t\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"writing to buffer data at index %ld\", (long) arr_idx));\n\n\t\t\t\t\t\tDUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX);  /* index/length check guarantees */\n\t\t\t\t\t\tbyte_off = arr_idx << h_bufobj->shift;       /* no wrap assuming h_bufobj->length is valid */\n\t\t\t\t\t\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\n\t\t\t\t\t\t/* Coerce to number before validating pointers etc so that the\n\t\t\t\t\t\t * number coercions in duk_hbufobj_validated_write() are\n\t\t\t\t\t\t * guaranteed to be side effect free and not invalidate the\n\t\t\t\t\t\t * pointer checks we do here.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk_push_tval(thr, tv_val);\n\t\t\t\t\t\t(void) duk_to_number_m1(thr);\n\n\t\t\t\t\t\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\t\t\t\t\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\t\t\t\t\t\tduk_hbufobj_validated_write(thr, h_bufobj, data, elem_size);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (write skipped)\"));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tduk_pop_unsafe(thr);\n\t\t\t\t\t\tgoto success_no_arguments_exotic;\n\t\t\t\t\t}\n\t\t\t\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\t\t\t\tDUK_D(DUK_DPRINT(\"should not happen, key %!O\", key));\n\t\t\t\tgoto fail_internal;  /* should not happen */\n\t\t\t}\n\t\t\tDUK_DD(DUK_DDPRINT(\"put to existing own plain property, property is writable\"));\n\t\t\tgoto update_old;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\n\t next_in_chain:\n\t\t/* XXX: option to pretend property doesn't exist if sanity limit is\n\t\t * hit might be useful.\n\t\t */\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t} while (curr != NULL);\n\n\t/*\n\t *  Property not found in prototype chain.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"property not found in prototype chain\"));\n\n\tif (orig == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to create a new property in a primitive base object\"));\n\t\tgoto fail_base_primitive;\n\t}\n\n\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(orig)) {\n\t\tDUK_DD(DUK_DDPRINT(\"put to a new property (not found in prototype chain), but original object not extensible\"));\n\t\tgoto fail_not_extensible;\n\t}\n\n\tgoto create_new;\n\n update_old:\n\n\t/*\n\t *  Update an existing property of the base object.\n\t */\n\n\t/* [key] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"update an existing property of the original object\"));\n\n\tDUK_ASSERT(orig != NULL);\n#if defined(DUK_USE_ROM_OBJECTS)\n\t/* This should not happen because DUK_TAG_OBJECT case checks\n\t * for this already, but check just in case.\n\t */\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {\n\t\tgoto fail_not_writable;\n\t}\n#endif\n\n\t/* Although there are writable virtual properties (e.g. plain buffer\n\t * and buffer object number indices), they are handled before we come\n\t * here.\n\t */\n\tDUK_ASSERT((desc.flags & DUK_PROPDESC_FLAG_VIRTUAL) == 0);\n\tDUK_ASSERT(desc.a_idx >= 0 || desc.e_idx >= 0);\n\n\t/* Array own property .length is handled above. */\n\tDUK_ASSERT(!(DUK_HOBJECT_IS_ARRAY(orig) && key == DUK_HTHREAD_STRING_LENGTH(thr)));\n\n\tif (desc.e_idx >= 0) {\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, desc.e_idx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"previous entry value: %!iT\", (duk_tval *) tv));\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val);  /* side effects; e_idx may be invalidated */\n\t\t/* don't touch property attributes or hash part */\n\t\tDUK_DD(DUK_DDPRINT(\"put to an existing entry at index %ld -> new value %!iT\",\n\t\t                   (long) desc.e_idx, (duk_tval *) tv));\n\t} else {\n\t\t/* Note: array entries are always writable, so the writability check\n\t\t * above is pointless for them.  The check could be avoided with some\n\t\t * refactoring but is probably not worth it.\n\t\t */\n\n\t\tDUK_ASSERT(desc.a_idx >= 0);\n\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, orig, desc.a_idx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"previous array value: %!iT\", (duk_tval *) tv));\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val);  /* side effects; a_idx may be invalidated */\n\t\tDUK_DD(DUK_DDPRINT(\"put to an existing array entry at index %ld -> new value %!iT\",\n\t\t                   (long) desc.a_idx, (duk_tval *) tv));\n\t}\n\n\t/* Regardless of whether property is found in entry or array part,\n\t * it may have arguments exotic behavior (array indices may reside\n\t * in entry part for abandoned / non-existent array parts).\n\t */\n\tgoto success_with_arguments_exotic;\n\n create_new:\n\n\t/*\n\t *  Create a new property in the original object.\n\t *\n\t *  Exotic properties need to be reconsidered here from a write\n\t *  perspective (not just property attributes perspective).\n\t *  However, the property does not exist in the object already,\n\t *  so this limits the kind of exotic properties that apply.\n\t */\n\n\t/* [key] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"create new property to original object\"));\n\n\tDUK_ASSERT(orig != NULL);\n\n\t/* Array own property .length is handled above. */\n\tDUK_ASSERT(!(DUK_HOBJECT_IS_ARRAY(orig) && key == DUK_HTHREAD_STRING_LENGTH(thr)));\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\t/* This should not happen because DUK_TAG_OBJECT case checks\n\t * for this already, but check just in case.\n\t */\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {\n\t\tgoto fail_not_writable;\n\t}\n#endif\n\n\t/* Not possible because array object 'length' is present\n\t * from its creation and cannot be deleted, and is thus\n\t * caught as an existing property above.\n\t */\n\tDUK_ASSERT(!(DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig) &&\n\t             key == DUK_HTHREAD_STRING_LENGTH(thr)));\n\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig) &&\n\t    arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t/* automatic length update */\n\t\tduk_uint32_t old_len;\n\t\tduk_harray *a;\n\n\t\ta = (duk_harray *) orig;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\told_len = a->length;\n\n\t\tif (arr_idx >= old_len) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"write new array entry requires length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\n\t\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"attempt to extend array, but array 'length' is not writable\"));\n\t\t\t\tgoto fail_not_writable;\n\t\t\t}\n\n\t\t\t/* Note: actual update happens once write has been completed\n\t\t\t * without error below.  The write should always succeed\n\t\t\t * from a specification viewpoint, but we may e.g. run out\n\t\t\t * of memory.  It's safer in this order.\n\t\t\t */\n\n\t\t\tDUK_ASSERT(arr_idx != 0xffffffffUL);\n\t\t\tnew_array_length = arr_idx + 1;  /* flag for later write */\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"write new array entry does not require length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\t\t}\n\t}\n\n /* write_to_array_part: */\n\n\t/*\n\t *  Write to array part?\n\t *\n\t *  Note: array abandonding requires a property resize which uses\n\t *  'rechecks' valstack for temporaries and may cause any existing\n\t *  valstack pointers to be invalidated.  To protect against this,\n\t *  tv_obj, tv_key, and tv_val are copies of the original inputs.\n\t */\n\n\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(orig)) {\n\t\ttv = duk__obtain_arridx_slot(thr, arr_idx, orig);\n\t\tif (tv == NULL) {\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(orig));\n\t\t\tgoto write_to_entry_part;\n\t\t}\n\n\t\t/* prev value must be unused, no decref */\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_TVAL_SET_TVAL(tv, tv_val);\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\tDUK_DD(DUK_DDPRINT(\"put to new array entry: %ld -> %!T\",\n\t\t                   (long) arr_idx, (duk_tval *) tv));\n\n\t\t/* Note: array part values are [[Writable]], [[Enumerable]],\n\t\t * and [[Configurable]] which matches the required attributes\n\t\t * here.\n\t\t */\n\t\tgoto entry_updated;\n\t}\n\n write_to_entry_part:\n\n\t/*\n\t *  Write to entry part\n\t */\n\n\t/* entry allocation updates hash part and increases the key\n\t * refcount; may need a props allocation resize but doesn't\n\t * 'recheck' the valstack.\n\t */\n\te_idx = duk__hobject_alloc_entry_checked(thr, orig, key);\n\tDUK_ASSERT(e_idx >= 0);\n\n\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, e_idx);\n\t/* prev value can be garbage, no decref */\n\tDUK_TVAL_SET_TVAL(tv, tv_val);\n\tDUK_TVAL_INCREF(thr, tv);\n\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, orig, e_idx, DUK_PROPDESC_FLAGS_WEC);\n\tgoto entry_updated;\n\n entry_updated:\n\n\t/*\n\t *  Possible pending array length update, which must only be done\n\t *  if the actual entry write succeeded.\n\t */\n\n\tif (new_array_length > 0) {\n\t\t/* Note: zero works as a \"no update\" marker because the new length\n\t\t * can never be zero after a new property is written.\n\t\t */\n\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"write successful, pending array length update to: %ld\",\n\t\t                     (long) new_array_length));\n\n\t\t((duk_harray *) orig)->length = new_array_length;\n\t}\n\n\t/*\n\t *  Arguments exotic behavior not possible for new properties: all\n\t *  magically bound properties are initially present in the arguments\n\t *  object, and if they are deleted, the binding is also removed from\n\t *  parameter map.\n\t */\n\n\tgoto success_no_arguments_exotic;\n\n success_with_arguments_exotic:\n\n\t/*\n\t *  Arguments objects have exotic [[DefineOwnProperty]] which updates\n\t *  the internal 'map' of arguments for writes to currently mapped\n\t *  arguments.  More conretely, writes to mapped arguments generate\n\t *  a write to a bound variable.\n\t *\n\t *  The [[Put]] algorithm invokes [[DefineOwnProperty]] for existing\n\t *  data properties and new properties, but not for existing accessors.\n\t *  Hence, in E5 Section 10.6 ([[DefinedOwnProperty]] algorithm), we\n\t *  have a Desc with 'Value' (and possibly other properties too), and\n\t *  we end up in step 5.b.i.\n\t */\n\n\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t    DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(orig)) {\n\t\t/* Note: only numbered indices are relevant, so arr_idx fast reject\n\t\t * is good (this is valid unless there are more than 4**32-1 arguments).\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"putprop successful, arguments exotic behavior needed\"));\n\n\t\t/* Note: we can reuse 'desc' here */\n\n\t\t/* XXX: top of stack must contain value, which helper doesn't touch,\n\t\t * rework to use tv_val directly?\n\t\t */\n\n\t\tduk_push_tval(thr, tv_val);\n\t\t(void) duk__check_arguments_map_for_put(thr, orig, key, &desc, throw_flag);\n\t\tduk_pop_unsafe(thr);\n\t}\n\t/* fall thru */\n\n success_no_arguments_exotic:\n\t/* shared exit path now */\n\tDUK_DDD(DUK_DDDPRINT(\"result: success\"));\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 1;\n\n#if defined(DUK_USE_ES6_PROXY)\n fail_proxy_rejected:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, proxy rejects\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\t/* Note: no key on stack */\n\treturn 0;\n#endif\n\n fail_base_primitive:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, base primitive\"));\n\tif (throw_flag) {\n#if defined(DUK_USE_PARANOID_ERRORS)\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\t\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot write property %s of %s\",\n\t\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_not_extensible:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, not extensible\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_not_writable:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, not writable\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n#if defined(DUK_USE_ROM_OBJECTS)\n fail_not_writable_no_pop:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, not writable\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n#endif\n\n fail_array_length_partial:\n\tDUK_DD(DUK_DDPRINT(\"result: error, array length write only partially successful\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_no_setter:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, accessor property without setter\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_SETTER_UNDEFINED);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_internal:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, internal\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_INTERNAL(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n}\n\n/*\n *  ECMAScript compliant [[Delete]](P, Throw).\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags) {\n\tduk_propdesc desc;\n\tduk_tval *tv;\n\tduk_uint32_t arr_idx;\n\tduk_bool_t throw_flag;\n\tduk_bool_t force_flag;\n\n\tthrow_flag = (flags & DUK_DELPROP_FLAG_THROW);\n\tforce_flag = (flags & DUK_DELPROP_FLAG_FORCE);\n\n\tDUK_DDD(DUK_DDDPRINT(\"delprop_raw: thr=%p, obj=%p, key=%p, throw=%ld, force=%ld (obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (long) throw_flag, (long) force_flag,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);\n\n\t/* 0 = don't push current value */\n\tif (!duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\tDUK_DDD(DUK_DDDPRINT(\"property not found, succeed always\"));\n\t\tgoto success;\n\t}\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to delprop on read-only target object\"));\n\t\tgoto fail_not_configurable;\n\t}\n#endif\n\n\tif ((desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) == 0 && !force_flag) {\n\t\tgoto fail_not_configurable;\n\t}\n\tif (desc.a_idx < 0 && desc.e_idx < 0) {\n\t\t/* Currently there are no deletable virtual properties, but\n\t\t * with force_flag we might attempt to delete one.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"delete failed: property found, force flag, but virtual (and implicitly non-configurable)\"));\n\t\tgoto fail_virtual;\n\t}\n\n\tif (desc.a_idx >= 0) {\n\t\tDUK_ASSERT(desc.e_idx < 0);\n\n\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx);\n\t\tDUK_TVAL_SET_UNUSED_UPDREF(thr, tv);  /* side effects */\n\t\tgoto success;\n\t} else {\n\t\tDUK_ASSERT(desc.a_idx < 0);\n\n\t\t/* remove hash entry (no decref) */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\t\tif (desc.h_idx >= 0) {\n\t\t\tduk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(thr->heap, obj);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"removing hash entry at h_idx %ld\", (long) desc.h_idx));\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) > 0);\n\t\t\tDUK_ASSERT((duk_uint32_t) desc.h_idx < DUK_HOBJECT_GET_HSIZE(obj));\n\t\t\th_base[desc.h_idx] = DUK__HASH_DELETED;\n\t\t} else {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) == 0);\n\t\t}\n#else\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) == 0);\n#endif\n\n\t\t/* Remove value.  This requires multiple writes so avoid side\n\t\t * effects via no-refzero macros so that e_idx is not\n\t\t * invalidated.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"before removing value, e_idx %ld, key %p, key at slot %p\",\n\t\t                     (long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)));\n\t\tDUK_DDD(DUK_DDDPRINT(\"removing value at e_idx %ld\", (long) desc.e_idx));\n\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx)) {\n\t\t\tduk_hobject *tmp;\n\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, desc.e_idx);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, desc.e_idx, NULL);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, desc.e_idx);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, desc.e_idx, NULL);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\t\t} else {\n\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t\t}\n#if 0\n\t\t/* Not strictly necessary because if key == NULL, flag MUST be ignored. */\n\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, 0);\n#endif\n\n\t\t/* Remove key. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"before removing key, e_idx %ld, key %p, key at slot %p\",\n\t\t                     (long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)));\n\t\tDUK_DDD(DUK_DDDPRINT(\"removing key at e_idx %ld\", (long) desc.e_idx));\n\t\tDUK_ASSERT(key == DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx));\n\t\tDUK_HOBJECT_E_SET_KEY(thr->heap, obj, desc.e_idx, NULL);\n\t\tDUK_HSTRING_DECREF_NORZ(thr, key);\n\n\t\t/* Trigger refzero side effects only when we're done as a\n\t\t * finalizer might operate on the object and affect the\n\t\t * e_idx we're supposed to use.\n\t\t */\n\t\tDUK_REFZERO_CHECK_SLOW(thr);\n\t\tgoto success;\n\t}\n\n\tDUK_UNREACHABLE();\n\n success:\n\t/*\n\t *  Argument exotic [[Delete]] behavior (E5 Section 10.6) is\n\t *  a post-check, keeping arguments internal 'map' in sync with\n\t *  any successful deletes (note that property does not need to\n\t *  exist for delete to 'succeed').\n\t *\n\t *  Delete key from 'map'.  Since 'map' only contains array index\n\t *  keys, we can use arr_idx for a fast skip.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"delete successful, check for arguments exotic behavior\"));\n\n\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)) {\n\t\t/* Note: only numbered indices are relevant, so arr_idx fast reject\n\t\t * is good (this is valid unless there are more than 4**32-1 arguments).\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"delete successful, arguments exotic behavior needed\"));\n\n\t\t/* Note: we can reuse 'desc' here */\n\t\t(void) duk__check_arguments_map_for_delete(thr, obj, key, &desc);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"delete successful\"));\n\treturn 1;\n\n fail_virtual:  /* just use the same \"not configurable\" error message */\n fail_not_configurable:\n\tDUK_DDD(DUK_DDDPRINT(\"delete failed: property found, not configurable\"));\n\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n}\n\n/*\n *  DELPROP: ECMAScript property deletion.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_bool_t throw_flag) {\n\tduk_hstring *key = NULL;\n#if defined(DUK_USE_ES6_PROXY)\n\tduk_propdesc desc;\n#endif\n\tduk_int_t entry_top;\n\tduk_uint32_t arr_idx = DUK__NO_ARRAY_INDEX;\n\tduk_bool_t rc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"delprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key,\n\t                     (duk_tval *) tv_obj, (duk_tval *) tv_key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\t/* Storing the entry top is cheaper here to ensure stack is correct at exit,\n\t * as there are several paths out.\n\t */\n\tentry_top = duk_get_top(thr);\n\n\tif (DUK_TVAL_IS_UNDEFINED(tv_obj) ||\n\t    DUK_TVAL_IS_NULL(tv_obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is undefined or null -> reject\"));\n\t\tgoto fail_invalid_base_uncond;\n\t}\n\n\tduk_push_tval(thr, tv_obj);\n\tduk_push_tval(thr, tv_key);\n\n\ttv_obj = DUK_GET_TVAL_NEGIDX(thr, -2);\n\tif (DUK_TVAL_IS_OBJECT(tv_obj)) {\n\t\tduk_hobject *obj = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(obj != NULL);\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(obj))) {\n\t\t\tduk_hobject *h_target;\n\t\t\tduk_bool_t tmp_bool;\n\n\t\t\t/* Note: proxy handling must happen before key is string coerced. */\n\n\t\t\tif (duk__proxy_check_prop(thr, obj, DUK_STRIDX_DELETE_PROPERTY, tv_key, &h_target)) {\n\t\t\t\t/* -> [ ... obj key trap handler ] */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'deleteProperty' for key %!T\", (duk_tval *) tv_key));\n\t\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\t\tduk_dup_m4(thr);  /* P */\n\t\t\t\tduk_call_method(thr, 2 /*nargs*/);\n\t\t\t\ttmp_bool = duk_to_boolean_top_pop(thr);\n\t\t\t\tif (!tmp_bool) {\n\t\t\t\t\tgoto fail_proxy_rejected;  /* retval indicates delete failed */\n\t\t\t\t}\n\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\t\t\t\ttv_key = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\t\t\t\tduk_small_int_t desc_reject;\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'deleteProperty': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\n\t\t\t\t\tdesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE);\n\t\t\t\t\tif (desc_reject) {\n\t\t\t\t\t\t/* unconditional */\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\trc = 1;  /* success */\n\t\t\t\tgoto done_rc;\n\t\t\t}\n\n\t\t\tobj = h_target;  /* resume delete to target */\n\t\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\trc = duk_hobject_delprop_raw(thr, obj, key, throw_flag ? DUK_DELPROP_FLAG_THROW : 0);\n\t\tgoto done_rc;\n\t} else if (DUK_TVAL_IS_STRING(tv_obj)) {\n\t\t/* String has .length and array index virtual properties\n\t\t * which can't be deleted.  No need for a symbol check;\n\t\t * no offending virtual symbols exist.\n\t\t */\n\t\t/* XXX: unnecessary string coercion for array indices,\n\t\t * intentional to keep small.\n\t\t */\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\t} else if (DUK_TVAL_IS_BUFFER(tv_obj)) {\n\t\t/* XXX: unnecessary string coercion for array indices,\n\t\t * intentional to keep small; some overlap with string\n\t\t * handling.\n\t\t */\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HBUFFER_GET_SIZE(h)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) {\n\t\t/* Lightfunc has no virtual properties since Duktape 2.2\n\t\t * so success.  Still must coerce key for side effects.\n\t\t */\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\t\tDUK_UNREF(key);\n\t}\n\n\t/* non-object base, no offending virtual property */\n\trc = 1;\n\tgoto done_rc;\n\n done_rc:\n\tduk_set_top_unsafe(thr, entry_top);\n\treturn rc;\n\n fail_invalid_base_uncond:\n\t/* Note: unconditional throw */\n\tDUK_ASSERT(duk_get_top(thr) == entry_top);\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot delete property %s of %s\",\n\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\tDUK_WO_NORETURN(return 0;);\n\n#if defined(DUK_USE_ES6_PROXY)\n fail_proxy_rejected:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_set_top_unsafe(thr, entry_top);\n\treturn 0;\n#endif\n\n fail_not_configurable:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_set_top_unsafe(thr, entry_top);\n\treturn 0;\n}\n\n/*\n *  Internal helper to define a property with specific flags, ignoring\n *  normal semantics such as extensibility, write protection etc.\n *  Overwrites any existing value and attributes unless caller requests\n *  that value only be updated if it doesn't already exists.\n *\n *  Does not support:\n *    - virtual properties (error if write attempted)\n *    - getter/setter properties (error if write attempted)\n *    - non-default (!= WEC) attributes for array entries (error if attempted)\n *    - array abandoning: if array part exists, it is always extended\n *    - array 'length' updating\n *\n *  Stack: [... in_val] -> []\n *\n *  Used for e.g. built-in initialization and environment record\n *  operations.\n */\n\nDUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags) {\n\tduk_propdesc desc;\n\tduk_uint32_t arr_idx;\n\tduk_int_t e_idx;\n\tduk_tval *tv1 = NULL;\n\tduk_tval *tv2 = NULL;\n\tduk_small_uint_t propflags = flags & DUK_PROPDESC_FLAGS_MASK;  /* mask out flags not actually stored */\n\n\tDUK_DDD(DUK_DDDPRINT(\"define new property (internal): thr=%p, obj=%!O, key=%!O, flags=0x%02lx, val=%!T\",\n\t                     (void *) thr, (duk_heaphdr *) obj, (duk_heaphdr *) key,\n\t                     (unsigned long) flags, (duk_tval *) duk_get_tval(thr, -1)));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\tDUK_ASSERT(duk_is_valid_index(thr, -1));  /* contains value */\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\n\tif (duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\tif (desc.e_idx >= 0) {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the entry part -> skip as requested\"));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the entry part -> update value and attributes\"));\n\t\t\tif (DUK_UNLIKELY(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx))) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"existing property is an accessor, not supported\"));\n\t\t\t\tgoto error_internal;\n\t\t\t}\n\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, propflags);\n\t\t\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);\n\t\t} else if (desc.a_idx >= 0) {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the array part -> skip as requested\"));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the array part -> update value (assert attributes)\"));\n\t\t\tif (propflags != DUK_PROPDESC_FLAGS_WEC) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"existing property in array part, but propflags not WEC (0x%02lx)\",\n\t\t\t\t                 (unsigned long) propflags));\n\t\t\t\tgoto error_internal;\n\t\t\t}\n\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx);\n\t\t} else {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists but is virtual -> skip as requested\"));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\t\t\tduk_uint32_t new_len;\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tduk_uint32_t prev_len;\n\t\t\t\tprev_len = ((duk_harray *) obj)->length;\n#endif\n\t\t\t\tnew_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_NEGIDX(thr, -1));\n\t\t\t\t((duk_harray *) obj)->length = new_len;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"internal define property for array .length: %ld -> %ld\",\n\t\t\t\t                   (long) prev_len, (long) ((duk_harray *) obj)->length));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tDUK_DD(DUK_DDPRINT(\"property already exists but is virtual -> failure\"));\n\t\t\tgoto error_virtual;\n\t\t}\n\n\t\tgoto write_value;\n\t}\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property does not exist, object has array part -> possibly extend array part and write value (assert attributes)\"));\n\t\t\tDUK_ASSERT(propflags == DUK_PROPDESC_FLAGS_WEC);\n\n\t\t\ttv1 = duk__obtain_arridx_slot(thr, arr_idx, obj);\n\t\t\tif (tv1 == NULL) {\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\t\t\tgoto write_to_entry_part;\n\t\t\t}\n\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n\t\t\tgoto write_value;\n\t\t}\n\t}\n\n write_to_entry_part:\n\tDUK_DDD(DUK_DDDPRINT(\"property does not exist, object belongs in entry part -> allocate new entry and write value and attributes\"));\n\te_idx = duk__hobject_alloc_entry_checked(thr, obj, key);  /* increases key refcount */\n\tDUK_ASSERT(e_idx >= 0);\n\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, propflags);\n\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);\n\t/* new entry: previous value is garbage; set to undefined to share write_value */\n\tDUK_TVAL_SET_UNDEFINED(tv1);\n\tgoto write_value;\n\n write_value:\n\t/* tv1 points to value storage */\n\n\ttv2 = duk_require_tval(thr, -1);  /* late lookup, avoid side effects */\n\tDUK_DDD(DUK_DDDPRINT(\"writing/updating value: %!T -> %!T\",\n\t                     (duk_tval *) tv1, (duk_tval *) tv2));\n\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\tgoto pop_exit;\n\n pop_exit:\n\tduk_pop_unsafe(thr);  /* remove in_val */\n\treturn;\n\n error_virtual:  /* share error message */\n error_internal:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Fast path for defining array indexed values without interning the key.\n *  This is used by e.g. code for Array prototype and traceback creation so\n *  must avoid interning.\n */\n\nDUK_INTERNAL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags) {\n\tduk_hstring *key;\n\tduk_tval *tv1, *tv2;\n\n\tDUK_DDD(DUK_DDDPRINT(\"define new property (internal) arr_idx fast path: thr=%p, obj=%!O, \"\n\t                     \"arr_idx=%ld, flags=0x%02lx, val=%!T\",\n\t                     (void *) thr, obj, (long) arr_idx, (unsigned long) flags,\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj) &&\n\t    arr_idx != DUK__NO_ARRAY_INDEX &&\n\t    flags == DUK_PROPDESC_FLAGS_WEC) {\n\t\tDUK_ASSERT((flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) == 0);  /* covered by comparison */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"define property to array part (property may or may not exist yet)\"));\n\n\t\ttv1 = duk__obtain_arridx_slot(thr, arr_idx, obj);\n\t\tif (tv1 == NULL) {\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\t\tgoto write_slow;\n\t\t}\n\t\ttv2 = duk_require_tval(thr, -1);\n\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\n\t\tduk_pop_unsafe(thr);  /* [ ...val ] -> [ ... ] */\n\t\treturn;\n\t}\n\n write_slow:\n\tDUK_DDD(DUK_DDDPRINT(\"define property fast path didn't work, use slow path\"));\n\n\tkey = duk_push_uint_to_hstring(thr, (duk_uint_t) arr_idx);\n\tDUK_ASSERT(key != NULL);\n\tduk_insert(thr, -2);  /* [ ... val key ] -> [ ... key val ] */\n\n\tduk_hobject_define_property_internal(thr, obj, key, flags);\n\n\tduk_pop_unsafe(thr);  /* [ ... key ] -> [ ... ] */\n}\n\n/*\n *  Internal helpers for managing object 'length'\n */\n\nDUK_INTERNAL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj) {\n\tduk_double_t val;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(obj != NULL);\n\n\t/* Fast path for Arrays. */\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\treturn ((duk_harray *) obj)->length;\n\t}\n\n\t/* Slow path, .length can be e.g. accessor, obj can be a Proxy, etc. */\n\tduk_push_hobject(thr, obj);\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_LENGTH);\n\t(void) duk_hobject_getprop(thr,\n\t                           DUK_GET_TVAL_NEGIDX(thr, -2),\n\t                           DUK_GET_TVAL_NEGIDX(thr, -1));\n\tval = duk_to_number_m1(thr);\n\tduk_pop_3_unsafe(thr);\n\n\t/* This isn't part of ECMAScript semantics; return a value within\n\t * duk_size_t range, or 0 otherwise.\n\t */\n\tif (val >= 0.0 && val <= (duk_double_t) DUK_SIZE_MAX) {\n\t\treturn (duk_size_t) val;\n\t}\n\treturn 0;\n}\n\n/*\n *  Fast finalizer check for an object.  Walks the prototype chain, checking\n *  for finalizer presence using DUK_HOBJECT_FLAG_HAVE_FINALIZER which is kept\n *  in sync with the actual property when setting/removing the finalizer.\n */\n\n#if defined(DUK_USE_HEAPPTR16)\nDUK_INTERNAL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_heap *heap, duk_hobject *obj) {\n#else\nDUK_INTERNAL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_hobject *obj) {\n#endif\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(obj != NULL);\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_HAS_HAVE_FINALIZER(obj))) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_D(DUK_DPRINT(\"prototype loop when checking for finalizer existence; returning false\"));\n\t\t\treturn 0;\n\t\t}\n#if defined(DUK_USE_HEAPPTR16)\n\t\tDUK_ASSERT(heap != NULL);\n\t\tobj = DUK_HOBJECT_GET_PROTOTYPE(heap, obj);\n#else\n\t\tobj = DUK_HOBJECT_GET_PROTOTYPE(NULL, obj);  /* 'heap' arg ignored */\n#endif\n\t} while (obj != NULL);\n\n\treturn 0;\n}\n\n/*\n *  Object.getOwnPropertyDescriptor()  (E5 Sections 15.2.3.3, 8.10.4)\n *\n *  [ ... key ] -> [ ... desc/undefined ]\n */\n\nDUK_INTERNAL void duk_hobject_object_get_own_property_descriptor(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_propdesc pd;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tobj = duk_require_hobject_promote_mask(thr, obj_idx, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tkey = duk_to_property_key_hstring(thr, -1);\n\tDUK_ASSERT(key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk_hobject_get_own_propdesc(thr, obj, key, &pd, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tduk_push_undefined(thr);\n\t\tduk_remove_m2(thr);\n\t\treturn;\n\t}\n\n\tduk_push_object(thr);\n\n\t/* [ ... key value desc ] */\n\n\tif (DUK_PROPDESC_IS_ACCESSOR(&pd)) {\n\t\t/* If a setter/getter is missing (undefined), the descriptor must\n\t\t * still have the property present with the value 'undefined'.\n\t\t */\n\t\tif (pd.get) {\n\t\t\tduk_push_hobject(thr, pd.get);\n\t\t} else {\n\t\t\tduk_push_undefined(thr);\n\t\t}\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_GET);\n\t\tif (pd.set) {\n\t\t\tduk_push_hobject(thr, pd.set);\n\t\t} else {\n\t\t\tduk_push_undefined(thr);\n\t\t}\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_SET);\n\t} else {\n\t\tduk_dup_m2(thr);\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_VALUE);\n\t\tduk_push_boolean(thr, DUK_PROPDESC_IS_WRITABLE(&pd));\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_WRITABLE);\n\t}\n\tduk_push_boolean(thr, DUK_PROPDESC_IS_ENUMERABLE(&pd));\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_ENUMERABLE);\n\tduk_push_boolean(thr, DUK_PROPDESC_IS_CONFIGURABLE(&pd));\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_CONFIGURABLE);\n\n\t/* [ ... key value desc ] */\n\n\tduk_replace(thr, -3);\n\tduk_pop_unsafe(thr);  /* -> [ ... desc ] */\n}\n\n/*\n *  NormalizePropertyDescriptor() related helper.\n *\n *  Internal helper which validates and normalizes a property descriptor\n *  represented as an ECMAScript object (e.g. argument to defineProperty()).\n *  The output of this conversion is a set of defprop_flags and possibly\n *  some values pushed on the value stack to (1) ensure borrowed pointers\n *  remain valid, and (2) avoid unnecessary pops for footprint reasons.\n *  Caller must manage stack top carefully because the number of values\n *  pushed depends on the input property descriptor.\n *\n *  The original descriptor object must not be altered in the process.\n */\n\n/* XXX: very basic optimization -> duk_get_prop_stridx_top */\n\nDUK_INTERNAL\nvoid duk_hobject_prepare_property_descriptor(duk_hthread *thr,\n                                             duk_idx_t idx_in,\n                                             duk_uint_t *out_defprop_flags,\n                                             duk_idx_t *out_idx_value,\n                                             duk_hobject **out_getter,\n                                             duk_hobject **out_setter) {\n\tduk_idx_t idx_value = -1;\n\tduk_hobject *getter = NULL;\n\tduk_hobject *setter = NULL;\n\tduk_bool_t is_data_desc = 0;\n\tduk_bool_t is_acc_desc = 0;\n\tduk_uint_t defprop_flags = 0;\n\n\tDUK_ASSERT(out_defprop_flags != NULL);\n\tDUK_ASSERT(out_idx_value != NULL);\n\tDUK_ASSERT(out_getter != NULL);\n\tDUK_ASSERT(out_setter != NULL);\n\tDUK_ASSERT(idx_in <= 0x7fffL);  /* short variants would be OK, but not used to avoid shifts */\n\n\t/* Must be an object, otherwise TypeError (E5.1 Section 8.10.5, step 1). */\n\tidx_in = duk_require_normalize_index(thr, idx_in);\n\t(void) duk_require_hobject(thr, idx_in);\n\n\t/* The coercion order must match the ToPropertyDescriptor() algorithm\n\t * so that side effects in coercion happen in the correct order.\n\t * (This order also happens to be compatible with duk_def_prop(),\n\t * although it doesn't matter in practice.)\n\t */\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_VALUE)) {\n\t\tis_data_desc = 1;\n\t\tdefprop_flags |= DUK_DEFPROP_HAVE_VALUE;\n\t\tidx_value = duk_get_top_index(thr);\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_WRITABLE)) {\n\t\tis_data_desc = 1;\n\t\tif (duk_to_boolean_top_pop(thr)) {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE;\n\t\t} else {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_WRITABLE;\n\t\t}\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_GET)) {\n\t\tduk_tval *tv = duk_require_tval(thr, -1);\n\t\tduk_hobject *h_get;\n\n\t\tif (DUK_TVAL_IS_UNDEFINED(tv)) {\n\t\t\t/* undefined is accepted */\n\t\t\tDUK_ASSERT(getter == NULL);\n\t\t} else {\n\t\t\t/* NOTE: lightfuncs are coerced to full functions because\n\t\t\t * lightfuncs don't fit into a property value slot.  This\n\t\t\t * has some side effects, see test-dev-lightfunc-accessor.js.\n\t\t\t */\n\t\t\th_get = duk_get_hobject_promote_lfunc(thr, -1);\n\t\t\tif (h_get == NULL || !DUK_HOBJECT_IS_CALLABLE(h_get)) {\n\t\t\t\tgoto type_error;\n\t\t\t}\n\t\t\tgetter = h_get;\n\t\t}\n\t\tis_acc_desc = 1;\n\t\tdefprop_flags |= DUK_DEFPROP_HAVE_GETTER;\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_SET)) {\n\t\tduk_tval *tv = duk_require_tval(thr, -1);\n\t\tduk_hobject *h_set;\n\n\t\tif (DUK_TVAL_IS_UNDEFINED(tv)) {\n\t\t\t/* undefined is accepted */\n\t\t\tDUK_ASSERT(setter == NULL);\n\t\t}  else {\n\t\t\t/* NOTE: lightfuncs are coerced to full functions because\n\t\t\t * lightfuncs don't fit into a property value slot.  This\n\t\t\t * has some side effects, see test-dev-lightfunc-accessor.js.\n\t\t\t */\n\t\t\th_set = duk_get_hobject_promote_lfunc(thr, -1);\n\t\t\tif (h_set == NULL || !DUK_HOBJECT_IS_CALLABLE(h_set)) {\n\t\t\t\tgoto type_error;\n\t\t\t}\n\t\t\tsetter = h_set;\n\t\t}\n\t\tis_acc_desc = 1;\n\t\tdefprop_flags |= DUK_DEFPROP_HAVE_SETTER;\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_ENUMERABLE)) {\n\t\tif (duk_to_boolean_top_pop(thr)) {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE;\n\t\t} else {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE;\n\t\t}\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_CONFIGURABLE)) {\n\t\tif (duk_to_boolean_top_pop(thr)) {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE;\n\t\t} else {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE;\n\t\t}\n\t}\n\n\tif (is_data_desc && is_acc_desc) {\n\t\tgoto type_error;\n\t}\n\n\t*out_defprop_flags = defprop_flags;\n\t*out_idx_value = idx_value;\n\t*out_getter = getter;\n\t*out_setter = setter;\n\n\t/* [ ... [multiple values] ] */\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_DESCRIPTOR);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Object.defineProperty() related helper (E5 Section 15.2.3.6).\n *  Also handles ES2015 Reflect.defineProperty().\n *\n *  Inlines all [[DefineOwnProperty]] exotic behaviors.\n *\n *  Note: ECMAScript compliant [[DefineOwnProperty]](P, Desc, Throw) is not\n *  implemented directly, but Object.defineProperty() serves its purpose.\n *  We don't need the [[DefineOwnProperty]] internally and we don't have a\n *  property descriptor with 'missing values' so it's easier to avoid it\n *  entirely.\n *\n *  Note: this is only called for actual objects, not primitive values.\n *  This must support virtual properties for full objects (e.g. Strings)\n *  but not for plain values (e.g. strings).  Lightfuncs, even though\n *  primitive in a sense, are treated like objects and accepted as target\n *  values.\n */\n\n/* XXX: this is a major target for size optimization */\nDUK_INTERNAL\nduk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,\n                                              duk_uint_t defprop_flags,\n                                              duk_hobject *obj,\n                                              duk_hstring *key,\n                                              duk_idx_t idx_value,\n                                              duk_hobject *get,\n                                              duk_hobject *set,\n                                              duk_bool_t throw_flag) {\n\tduk_uint32_t arr_idx;\n\tduk_tval tv;\n\tduk_bool_t has_enumerable;\n\tduk_bool_t has_configurable;\n\tduk_bool_t has_writable;\n\tduk_bool_t has_value;\n\tduk_bool_t has_get;\n\tduk_bool_t has_set;\n\tduk_bool_t is_enumerable;\n\tduk_bool_t is_configurable;\n\tduk_bool_t is_writable;\n\tduk_bool_t force_flag;\n\tduk_small_uint_t new_flags;\n\tduk_propdesc curr;\n\tduk_uint32_t arridx_new_array_length;  /* != 0 => post-update for array 'length' (used when key is an array index) */\n\tduk_uint32_t arrlen_old_len;\n\tduk_uint32_t arrlen_new_len;\n\tduk_bool_t pending_write_protect;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\t/* idx_value may be < 0 (no value), set and get may be NULL */\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\t/* All the flags fit in 16 bits, so will fit into duk_bool_t. */\n\n\thas_writable = (defprop_flags & DUK_DEFPROP_HAVE_WRITABLE);\n\thas_enumerable = (defprop_flags & DUK_DEFPROP_HAVE_ENUMERABLE);\n\thas_configurable = (defprop_flags & DUK_DEFPROP_HAVE_CONFIGURABLE);\n\thas_value = (defprop_flags & DUK_DEFPROP_HAVE_VALUE);\n\thas_get = (defprop_flags & DUK_DEFPROP_HAVE_GETTER);\n\thas_set = (defprop_flags & DUK_DEFPROP_HAVE_SETTER);\n\tis_writable = (defprop_flags & DUK_DEFPROP_WRITABLE);\n\tis_enumerable = (defprop_flags & DUK_DEFPROP_ENUMERABLE);\n\tis_configurable = (defprop_flags & DUK_DEFPROP_CONFIGURABLE);\n\tforce_flag = (defprop_flags & DUK_DEFPROP_FORCE);\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\n\tarridx_new_array_length = 0;\n\tpending_write_protect = 0;\n\tarrlen_old_len = 0;\n\tarrlen_new_len = 0;\n\n\tDUK_DDD(DUK_DDDPRINT(\"has_enumerable=%ld is_enumerable=%ld \"\n\t                     \"has_configurable=%ld is_configurable=%ld \"\n\t                     \"has_writable=%ld is_writable=%ld \"\n\t                     \"has_value=%ld value=%!T \"\n\t                     \"has_get=%ld get=%p=%!O \"\n\t                     \"has_set=%ld set=%p=%!O \"\n\t                     \"arr_idx=%ld throw_flag=!%ld\",\n\t                     (long) has_enumerable, (long) is_enumerable,\n\t                     (long) has_configurable, (long) is_configurable,\n\t                     (long) has_writable, (long) is_writable,\n\t                     (long) has_value, (duk_tval *) (idx_value >= 0 ? duk_get_tval(thr, idx_value) : NULL),\n\t                     (long) has_get, (void *) get, (duk_heaphdr *) get,\n\t                     (long) has_set, (void *) set, (duk_heaphdr *) set,\n\t                     (long) arr_idx, (long) throw_flag));\n\n\t/*\n\t *  Array exotic behaviors can be implemented at this point.  The local variables\n\t *  are essentially a 'value copy' of the input descriptor (Desc), which is modified\n\t *  by the Array [[DefineOwnProperty]] (E5 Section 15.4.5.1).\n\t */\n\n\tif (!DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\tgoto skip_array_exotic;\n\t}\n\n\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\tduk_harray *a;\n\n\t\t/* E5 Section 15.4.5.1, step 3, steps a - i are implemented here, j - n at the end */\n\t\tif (!has_value) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"exotic array behavior for 'length', but no value in descriptor -> normal behavior\"));\n\t\t\tgoto skip_array_exotic;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"exotic array behavior for 'length', value present in descriptor -> exotic behavior\"));\n\n\t\t/*\n\t\t *  Get old and new length\n\t\t */\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\t\tarrlen_old_len = a->length;\n\n\t\tDUK_ASSERT(idx_value >= 0);\n\t\tarrlen_new_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_POSIDX(thr, idx_value));\n\t\tduk_push_u32(thr, arrlen_new_len);\n\t\tduk_replace(thr, idx_value);  /* step 3.e: replace 'Desc.[[Value]]' */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"old_len=%ld, new_len=%ld\", (long) arrlen_old_len, (long) arrlen_new_len));\n\n\t\tif (arrlen_new_len >= arrlen_old_len) {\n\t\t\t/* standard behavior, step 3.f.i */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new length is same or higher as previous => standard behavior\"));\n\t\t\tgoto skip_array_exotic;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"new length is smaller than previous => exotic post behavior\"));\n\n\t\t/* XXX: consolidated algorithm step 15.f -> redundant? */\n\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a) && !force_flag) {\n\t\t\t/* Array .length is always non-configurable; if it's also\n\t\t\t * non-writable, don't allow it to be written.\n\t\t\t */\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\n\t\t/* steps 3.h and 3.i */\n\t\tif (has_writable && !is_writable) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"desc writable is false, force it back to true, and flag pending write protect\"));\n\t\t\tis_writable = 1;\n\t\t\tpending_write_protect = 1;\n\t\t}\n\n\t\t/* remaining actual steps are carried out if standard DefineOwnProperty succeeds */\n\t} else if (arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t/* XXX: any chance of unifying this with the 'length' key handling? */\n\n\t\t/* E5 Section 15.4.5.1, step 4 */\n\t\tduk_uint32_t old_len;\n\t\tduk_harray *a;\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\told_len = a->length;\n\n\t\tif (arr_idx >= old_len) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty requires array length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\n\t\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a) && !force_flag) {\n\t\t\t\t/* Array .length is always non-configurable, so\n\t\t\t\t * if it's also non-writable, don't allow a value\n\t\t\t\t * write.  With force flag allow writing.\n\t\t\t\t */\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\n\t\t\t/* actual update happens once write has been completed without\n\t\t\t * error below.\n\t\t\t */\n\t\t\tDUK_ASSERT(arr_idx != 0xffffffffUL);\n\t\t\tarridx_new_array_length = arr_idx + 1;\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty does not require length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld) -> standard behavior\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\t\t}\n\t}\n skip_array_exotic:\n\n\t/* XXX: There is currently no support for writing buffer object\n\t * indexed elements here.  Attempt to do so will succeed and\n\t * write a concrete property into the buffer object.  This should\n\t * be fixed at some point but because buffers are a custom feature\n\t * anyway, this is relatively unimportant.\n\t */\n\n\t/*\n\t *  Actual Object.defineProperty() default algorithm.\n\t */\n\n\t/*\n\t *  First check whether property exists; if not, simple case.  This covers\n\t *  steps 1-4.\n\t */\n\n\tif (!duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"property does not exist\"));\n\n\t\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(obj) && !force_flag) {\n\t\t\tgoto fail_not_extensible;\n\t\t}\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\t\t/* ROM objects are never extensible but force flag may\n\t\t * allow us to come here anyway.\n\t\t */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj) || !DUK_HOBJECT_HAS_EXTENSIBLE(obj));\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\t\tDUK_D(DUK_DPRINT(\"attempt to define property on a read-only target object\"));\n\t\t\tgoto fail_not_configurable;\n\t\t}\n#endif\n\n\t\t/* XXX: share final setting code for value and flags?  difficult because\n\t\t * refcount code is different.  Share entry allocation?  But can't allocate\n\t\t * until array index checked.\n\t\t */\n\n\t\t/* steps 4.a and 4.b are tricky */\n\t\tif (has_set || has_get) {\n\t\t\tduk_int_t e_idx;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"create new accessor property\"));\n\n\t\t\tDUK_ASSERT(has_set || set == NULL);\n\t\t\tDUK_ASSERT(has_get || get == NULL);\n\t\t\tDUK_ASSERT(!has_value);\n\t\t\tDUK_ASSERT(!has_writable);\n\n\t\t\tnew_flags = DUK_PROPDESC_FLAG_ACCESSOR;  /* defaults, E5 Section 8.6.1, Table 7 */\n\t\t\tif (has_enumerable && is_enumerable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t}\n\t\t\tif (has_configurable && is_configurable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t}\n\n\t\t\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"accessor cannot go to array part, abandon array\"));\n\t\t\t\tduk__abandon_array_part(thr, obj);\n\t\t\t}\n\n\t\t\t/* write to entry part */\n\t\t\te_idx = duk__hobject_alloc_entry_checked(thr, obj, key);\n\t\t\tDUK_ASSERT(e_idx >= 0);\n\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, e_idx, get);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, e_idx, set);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, get);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, set);\n\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags);\n\t\t\tgoto success_exotics;\n\t\t} else {\n\t\t\tduk_int_t e_idx;\n\t\t\tduk_tval *tv2;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"create new data property\"));\n\n\t\t\tDUK_ASSERT(!has_set);\n\t\t\tDUK_ASSERT(!has_get);\n\n\t\t\tnew_flags = 0;  /* defaults, E5 Section 8.6.1, Table 7 */\n\t\t\tif (has_writable && is_writable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_WRITABLE;\n\t\t\t}\n\t\t\tif (has_enumerable && is_enumerable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t}\n\t\t\tif (has_configurable && is_configurable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t}\n\t\t\tif (has_value) {\n\t\t\t\tduk_tval *tv_tmp = duk_require_tval(thr, idx_value);\n\t\t\t\tDUK_TVAL_SET_TVAL(&tv, tv_tmp);\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_UNDEFINED(&tv);  /* default value */\n\t\t\t}\n\n\t\t\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tif (new_flags == DUK_PROPDESC_FLAGS_WEC) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"new data property attributes match array defaults, attempt to write to array part\"));\n\t\t\t\t\ttv2 = duk__obtain_arridx_slot(thr, arr_idx, obj);\n\t\t\t\t\tif (tv2 == NULL) {\n\t\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"failed writing to array part, abandoned array\"));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"success in writing to array part\"));\n\t\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\t\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv2));\n\t\t\t\t\t\tDUK_TVAL_SET_TVAL(tv2, &tv);\n\t\t\t\t\t\tDUK_TVAL_INCREF(thr, tv2);\n\t\t\t\t\t\tgoto success_exotics;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"new data property cannot go to array part, abandon array\"));\n\t\t\t\t\tduk__abandon_array_part(thr, obj);\n\t\t\t\t}\n\t\t\t\t/* fall through */\n\t\t\t}\n\n\t\t\t/* write to entry part */\n\t\t\te_idx = duk__hobject_alloc_entry_checked(thr, obj, key);\n\t\t\tDUK_ASSERT(e_idx >= 0);\n\t\t\ttv2 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);\n\t\t\tDUK_TVAL_SET_TVAL(tv2, &tv);\n\t\t\tDUK_TVAL_INCREF(thr, tv2);\n\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags);\n\t\t\tgoto success_exotics;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\t}\n\n\t/* we currently assume virtual properties are not configurable (as none of them are) */\n\tDUK_ASSERT((curr.e_idx >= 0 || curr.a_idx >= 0) || !(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE));\n\n\t/* [obj key desc value get set curr_value] */\n\n\t/*\n\t *  Property already exists.  Steps 5-6 detect whether any changes need\n\t *  to be made.\n\t */\n\n\tif (has_enumerable) {\n\t\tif (is_enumerable) {\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE)) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t}\n\t}\n\tif (has_configurable) {\n\t\tif (is_configurable) {\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE)) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t}\n\t}\n\tif (has_value) {\n\t\tduk_tval *tmp1;\n\t\tduk_tval *tmp2;\n\n\t\t/* attempt to change from accessor to data property */\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tgoto need_check;\n\t\t}\n\n\t\ttmp1 = duk_require_tval(thr, -1);         /* curr value */\n\t\ttmp2 = duk_require_tval(thr, idx_value);  /* new value */\n\t\tif (!duk_js_samevalue(tmp1, tmp2)) {\n\t\t\tgoto need_check;\n\t\t}\n\t}\n\tif (has_writable) {\n\t\t/* attempt to change from accessor to data property */\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tgoto need_check;\n\t\t}\n\n\t\tif (is_writable) {\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_WRITABLE) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t}\n\t}\n\tif (has_set) {\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tif (set != curr.set) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tgoto need_check;\n\t\t}\n\t}\n\tif (has_get) {\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tif (get != curr.get) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tgoto need_check;\n\t\t}\n\t}\n\n\t/* property exists, either 'desc' is empty, or all values\n\t * match (SameValue)\n\t */\n\tgoto success_no_exotics;\n\n need_check:\n\n\t/*\n\t *  Some change(s) need to be made.  Steps 7-11.\n\t */\n\n\t/* shared checks for all descriptor types */\n\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\tif (has_configurable && is_configurable) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\t\tif (has_enumerable) {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE) {\n\t\t\t\tif (!is_enumerable) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (is_enumerable) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Virtual properties don't have backing so they can't mostly be\n\t * edited.  Some virtual properties are, however, writable: for\n\t * example, virtual index properties of buffer objects and Array\n\t * instance .length.  These are not configurable so the checks\n\t * above mostly cover attempts to change them, except when the\n\t * duk_def_prop() call is used with DUK_DEFPROP_FORCE; even in\n\t * that case we can't forcibly change the property attributes\n\t * because they don't have concrete backing.\n\t */\n\n\t/* XXX: for ROM objects too it'd be best if value modify was\n\t * allowed if the value matches SameValue.\n\t */\n\t/* Reject attempt to change a read-only object. */\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to define property on read-only target object\"));\n\t\tgoto fail_not_configurable;\n\t}\n#endif\n\n\t/* descriptor type specific checks */\n\tif (has_set || has_get) {\n\t\t/* IsAccessorDescriptor(desc) == true */\n\t\tDUK_ASSERT(!has_writable);\n\t\tDUK_ASSERT(!has_value);\n\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t/* curr and desc are accessors */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tif (has_set && set != curr.set) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t\tif (has_get && get != curr.get) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tduk_bool_t rc;\n\t\t\tduk_tval *tv1;\n\n\t\t\t/* curr is data, desc is accessor */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"convert property to accessor property\"));\n\t\t\tif (curr.a_idx >= 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property to convert is stored in an array entry, abandon array and re-lookup\"));\n\t\t\t\tduk__abandon_array_part(thr, obj);\n\t\t\t\tduk_pop_unsafe(thr);  /* remove old value */\n\t\t\t\trc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);\n\t\t\t\tDUK_UNREF(rc);\n\t\t\t\tDUK_ASSERT(rc != 0);\n\t\t\t\tDUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);\n\t\t\t}\n\t\t\tif (curr.e_idx < 0) {\n\t\t\t\tDUK_ASSERT(curr.a_idx < 0 && curr.e_idx < 0);\n\t\t\t\tgoto fail_virtual;  /* safeguard for virtual property */\n\t\t\t}\n\n\t\t\tDUK_ASSERT(curr.e_idx >= 0);\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\n\t\t\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv1);  /* XXX: just decref */\n\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_HOBJECT_E_SLOT_SET_ACCESSOR(thr->heap, obj, curr.e_idx);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"flags after data->accessor conversion: 0x%02lx\",\n\t\t\t                     (unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));\n\t\t\t/* Update curr.flags; faster than a re-lookup. */\n\t\t\tcurr.flags &= ~DUK_PROPDESC_FLAG_WRITABLE;\n\t\t\tcurr.flags |= DUK_PROPDESC_FLAG_ACCESSOR;\n\t\t}\n\t} else if (has_value || has_writable) {\n\t\t/* IsDataDescriptor(desc) == true */\n\t\tDUK_ASSERT(!has_set);\n\t\tDUK_ASSERT(!has_get);\n\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tduk_hobject *tmp;\n\n\t\t\t/* curr is accessor, desc is data */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\n\t\t\t/* curr is accessor -> cannot be in array part. */\n\t\t\tDUK_ASSERT(curr.a_idx < 0);\n\t\t\tif (curr.e_idx < 0) {\n\t\t\t\tgoto fail_virtual;  /* safeguard; no virtual accessors now */\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"convert property to data property\"));\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\n\t\t\tDUK_TVAL_SET_UNDEFINED(DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx));\n\t\t\tDUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(thr->heap, obj, curr.e_idx);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"flags after accessor->data conversion: 0x%02lx\",\n\t\t\t                     (unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));\n\n\t\t\t/* Update curr.flags; faster than a re-lookup. */\n\t\t\tcurr.flags &= ~(DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ACCESSOR);\n\t\t} else {\n\t\t\t/* curr and desc are data */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && has_writable && is_writable) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t\t/* Note: changing from writable to non-writable is OK */\n\t\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && has_value) {\n\t\t\t\t\tduk_tval *tmp1 = duk_require_tval(thr, -1);         /* curr value */\n\t\t\t\t\tduk_tval *tmp2 = duk_require_tval(thr, idx_value);  /* new value */\n\t\t\t\t\tif (!duk_js_samevalue(tmp1, tmp2)) {\n\t\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\t/* IsGenericDescriptor(desc) == true; this means in practice that 'desc'\n\t\t * only has [[Enumerable]] or [[Configurable]] flag updates, which are\n\t\t * allowed at this point.\n\t\t */\n\n\t\tDUK_ASSERT(!has_value && !has_writable && !has_get && !has_set);\n\t}\n\n\t/*\n\t *  Start doing property attributes updates.  Steps 12-13.\n\t *\n\t *  Start by computing new attribute flags without writing yet.\n\t *  Property type conversion is done above if necessary.\n\t */\n\n\tnew_flags = curr.flags;\n\n\tif (has_enumerable) {\n\t\tif (is_enumerable) {\n\t\t\tnew_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t} else {\n\t\t\tnew_flags &= ~DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t}\n\t}\n\tif (has_configurable) {\n\t\tif (is_configurable) {\n\t\t\tnew_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t} else {\n\t\t\tnew_flags &= ~DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t}\n\t}\n\tif (has_writable) {\n\t\tif (is_writable) {\n\t\t\tnew_flags |= DUK_PROPDESC_FLAG_WRITABLE;\n\t\t} else {\n\t\t\tnew_flags &= ~DUK_PROPDESC_FLAG_WRITABLE;\n\t\t}\n\t}\n\n\t/* XXX: write protect after flag? -> any chance of handling it here? */\n\n\tDUK_DDD(DUK_DDDPRINT(\"new flags that we want to write: 0x%02lx\",\n\t                     (unsigned long) new_flags));\n\n\t/*\n\t *  Check whether we need to abandon an array part (if it exists)\n\t */\n\n\tif (curr.a_idx >= 0) {\n\t\tduk_bool_t rc;\n\n\t\tDUK_ASSERT(curr.e_idx < 0);\n\n\t\tif (new_flags == DUK_PROPDESC_FLAGS_WEC) {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index, new property attributes match array defaults, update in-place\"));\n\n\t\t\tDUK_ASSERT(curr.flags == DUK_PROPDESC_FLAGS_WEC);  /* must have been, since in array part */\n\t\t\tDUK_ASSERT(!has_set);\n\t\t\tDUK_ASSERT(!has_get);\n\t\t\tDUK_ASSERT(idx_value >= 0);  /* must be: if attributes match and we get here the value must differ (otherwise no change) */\n\n\t\t\ttv2 = duk_require_tval(thr, idx_value);\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, curr.a_idx);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects; may invalidate a_idx */\n\t\t\tgoto success_exotics;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array index, new property attributes do not match array defaults, abandon array and re-lookup\"));\n\t\tduk__abandon_array_part(thr, obj);\n\t\tduk_pop_unsafe(thr);  /* remove old value */\n\t\trc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);\n\t\tDUK_UNREF(rc);\n\t\tDUK_ASSERT(rc != 0);\n\t\tDUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"updating existing property in entry part\"));\n\n\t/* Array case is handled comprehensively above: either in entry\n\t * part or a virtual property.\n\t */\n\tDUK_ASSERT(curr.a_idx < 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"update existing property attributes\"));\n\tif (curr.e_idx >= 0) {\n\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, curr.e_idx, new_flags);\n\t} else {\n\t\t/* For Array .length the only allowed transition is for .length\n\t\t * to become non-writable.\n\t\t */\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\t\tduk_harray *a;\n\t\t\ta = (duk_harray *) obj;\n\t\t\tDUK_DD(DUK_DDPRINT(\"Object.defineProperty() attribute update for duk_harray .length -> %02lx\", (unsigned long) new_flags));\n\t\t\tDUK_HARRAY_ASSERT_VALID(a);\n\t\t\tif ((new_flags & DUK_PROPDESC_FLAGS_EC) != (curr.flags & DUK_PROPDESC_FLAGS_EC)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"Object.defineProperty() attempt to change virtual array .length enumerable or configurable attribute, fail\"));\n\t\t\t\tgoto fail_virtual;\n\t\t\t}\n\t\t\tif (new_flags & DUK_PROPDESC_FLAG_WRITABLE) {\n\t\t\t\tDUK_HARRAY_SET_LENGTH_WRITABLE(a);\n\t\t\t} else {\n\t\t\t\tDUK_HARRAY_SET_LENGTH_NONWRITABLE(a);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (has_set) {\n\t\tduk_hobject *tmp;\n\n\t\t/* Virtual properties are non-configurable but with a 'force'\n\t\t * flag we might come here so check explicitly for virtual.\n\t\t */\n\t\tif (curr.e_idx < 0) {\n\t\t\tgoto fail_virtual;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"update existing property setter\"));\n\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\n\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);\n\t\tDUK_UNREF(tmp);\n\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, set);\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, set);\n\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);  /* side effects; may invalidate e_idx */\n\t}\n\tif (has_get) {\n\t\tduk_hobject *tmp;\n\n\t\tif (curr.e_idx < 0) {\n\t\t\tgoto fail_virtual;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"update existing property getter\"));\n\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\n\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);\n\t\tDUK_UNREF(tmp);\n\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, get);\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, get);\n\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);  /* side effects; may invalidate e_idx */\n\t}\n\tif (has_value) {\n\t\tduk_tval *tv1, *tv2;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"update existing property value\"));\n\n\t\tif (curr.e_idx >= 0) {\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\t\t\ttv2 = duk_require_tval(thr, idx_value);\n\t\t\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects; may invalidate e_idx */\n\t\t} else {\n\t\t\tDUK_ASSERT(curr.a_idx < 0);  /* array part case handled comprehensively previously */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"Object.defineProperty(), value update for virtual property\"));\n\t\t\t/* XXX: Uint8Array and other typed array virtual writes not currently\n\t\t\t * handled.\n\t\t\t */\n\t\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\t\t\tduk_harray *a;\n\t\t\t\ta = (duk_harray *) obj;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"Object.defineProperty() value update for duk_harray .length -> %ld\", (long) arrlen_new_len));\n\t\t\t\tDUK_HARRAY_ASSERT_VALID(a);\n\t\t\t\ta->length = arrlen_new_len;\n\t\t\t} else {\n\t\t\t\tgoto fail_virtual;  /* should not happen */\n\t\t\t}\n\t\t}\n\t}\n\n\t/*\n\t *  Standard algorithm succeeded without errors, check for exotic post-behaviors.\n\t *\n\t *  Arguments exotic behavior in E5 Section 10.6 occurs after the standard\n\t *  [[DefineOwnProperty]] has completed successfully.\n\t *\n\t *  Array exotic behavior in E5 Section 15.4.5.1 is implemented partly\n\t *  prior to the default [[DefineOwnProperty]], but:\n\t *    - for an array index key (e.g. \"10\") the final 'length' update occurs here\n\t *    - for 'length' key the element deletion and 'length' update occurs here\n\t */\n\n success_exotics:\n\n\t/* curr.a_idx or curr.e_idx may have been invalidated by side effects\n\t * above.\n\t */\n\n\t/* [obj key desc value get set curr_value] */\n\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\tduk_harray *a;\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\tif (arridx_new_array_length > 0) {\n\t\t\t/*\n\t\t\t *  Note: zero works as a \"no update\" marker because the new length\n\t\t\t *  can never be zero after a new property is written.\n\t\t\t */\n\n\t\t\t/* E5 Section 15.4.5.1, steps 4.e.i - 4.e.ii */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, pending array length update to: %ld\",\n\t\t\t                     (long) arridx_new_array_length));\n\n\t\t\ta->length = arridx_new_array_length;\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && arrlen_new_len < arrlen_old_len) {\n\t\t\t/*\n\t\t\t *  E5 Section 15.4.5.1, steps 3.k - 3.n.  The order at the end combines\n\t\t\t *  the error case 3.l.iii and the success case 3.m-3.n.\n\t\t\t */\n\n\t\t\t/* XXX: investigate whether write protect can be handled above, if we\n\t\t\t * just update length here while ignoring its protected status\n\t\t\t */\n\n\t\t\tduk_uint32_t result_len;\n\t\t\tduk_bool_t rc;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key is 'length', exotic array behavior, \"\n\t\t\t                     \"doing array element deletion and length update\"));\n\n\t\t\trc = duk__handle_put_array_length_smaller(thr, obj, arrlen_old_len, arrlen_new_len, force_flag, &result_len);\n\n\t\t\t/* update length (curr points to length, and we assume it's still valid) */\n\t\t\tDUK_ASSERT(result_len >= arrlen_new_len && result_len <= arrlen_old_len);\n\n\t\t\ta->length = result_len;\n\n\t\t\tif (pending_write_protect) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"setting array length non-writable (pending writability update)\"));\n\t\t\t\tDUK_HARRAY_SET_LENGTH_NONWRITABLE(a);\n\t\t\t}\n\n\t\t\t/* XXX: shrink array allocation or entries compaction here? */\n\t\t\tif (!rc) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"array length write only partially successful\"));\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\t\t}\n\t} else if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)) {\n\t\tduk_hobject *map;\n\t\tduk_hobject *varenv;\n\n\t\tDUK_ASSERT(arridx_new_array_length == 0);\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj));  /* traits are separate; in particular, arguments not an array */\n\n\t\tmap = NULL;\n\t\tvarenv = NULL;\n\t\tif (!duk__lookup_arguments_map(thr, obj, key, &curr, &map, &varenv)) {\n\t\t\tgoto success_no_exotics;\n\t\t}\n\t\tDUK_ASSERT(map != NULL);\n\t\tDUK_ASSERT(varenv != NULL);\n\n\t\t/* [obj key desc value get set curr_value varname] */\n\n\t\tif (has_set || has_get) {\n\t\t\t/* = IsAccessorDescriptor(Desc) */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map' \"\n\t\t\t                     \"changed to an accessor, delete arguments binding\"));\n\n\t\t\t(void) duk_hobject_delprop_raw(thr, map, key, 0);  /* ignore result */\n\t\t} else {\n\t\t\t/* Note: this order matters (final value before deleting map entry must be done) */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map', \"\n\t\t\t                     \"check for value update / binding deletion\"));\n\n\t\t\tif (has_value) {\n\t\t\t\tduk_hstring *varname;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map', \"\n\t\t\t\t                     \"update bound value (variable/argument)\"));\n\n\t\t\t\tvarname = duk_require_hstring(thr, -1);\n\t\t\t\tDUK_ASSERT(varname != NULL);\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"arguments object automatic putvar for a bound variable; \"\n\t\t\t\t                     \"key=%!O, varname=%!O, value=%!T\",\n\t\t\t\t                     (duk_heaphdr *) key,\n\t\t\t\t                     (duk_heaphdr *) varname,\n\t\t\t\t                     (duk_tval *) duk_require_tval(thr, idx_value)));\n\n\t\t\t\t/* strict flag for putvar comes from our caller (currently: fixed) */\n\t\t\t\tduk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(thr, idx_value), 1 /*throw_flag*/);\n\t\t\t}\n\t\t\tif (has_writable && !is_writable) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map', \"\n\t\t\t\t                     \"changed to non-writable, delete arguments binding\"));\n\n\t\t\t\t(void) duk_hobject_delprop_raw(thr, map, key, 0);  /* ignore result */\n\t\t\t}\n\t\t}\n\n\t\t/* 'varname' is in stack in this else branch, leaving an unbalanced stack below,\n\t\t * but this doesn't matter now.\n\t\t */\n\t}\n\n success_no_exotics:\n\t/* Some code paths use NORZ macros for simplicity, ensure refzero\n\t * handling is completed.\n\t */\n\tDUK_REFZERO_CHECK_SLOW(thr);\n\treturn 1;\n\n fail_not_extensible:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n\n fail_virtual:  /* just use the same \"not configurable\" error message\" */\n fail_not_configurable:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n}\n\n/*\n *  Object.prototype.hasOwnProperty() and Object.prototype.propertyIsEnumerable().\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_object_ownprop_helper(duk_hthread *thr, duk_small_uint_t required_desc_flags) {\n\tduk_hstring *h_v;\n\tduk_hobject *h_obj;\n\tduk_propdesc desc;\n\tduk_bool_t ret;\n\n\t/* coercion order matters */\n\th_v = duk_to_hstring_acceptsymbol(thr, 0);\n\tDUK_ASSERT(h_v != NULL);\n\n\th_obj = duk_push_this_coercible_to_object(thr);\n\tDUK_ASSERT(h_obj != NULL);\n\n\tret = duk_hobject_get_own_propdesc(thr, h_obj, h_v, &desc, 0 /*flags*/);  /* don't push value */\n\n\tduk_push_boolean(thr, ret && ((desc.flags & required_desc_flags) == required_desc_flags));\n\treturn 1;\n}\n\n/*\n *  Object.seal() and Object.freeze()  (E5 Sections 15.2.3.8 and 15.2.3.9)\n *\n *  Since the algorithms are similar, a helper provides both functions.\n *  Freezing is essentially sealing + making plain properties non-writable.\n *\n *  Note: virtual (non-concrete) properties which are non-configurable but\n *  writable would pose some problems, but such properties do not currently\n *  exist (all virtual properties are non-configurable and non-writable).\n *  If they did exist, the non-configurability does NOT prevent them from\n *  becoming non-writable.  However, this change should be recorded somehow\n *  so that it would turn up (e.g. when getting the property descriptor),\n *  requiring some additional flags in the object.\n */\n\nDUK_INTERNAL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze) {\n\tduk_uint_fast32_t i;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to seal/freeze a readonly object, reject\"));\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\t/*\n\t *  Abandon array part because all properties must become non-configurable.\n\t *  Note that this is now done regardless of whether this is always the case\n\t *  (skips check, but performance problem if caller would do this many times\n\t *  for the same object; not likely).\n\t */\n\n\tduk__abandon_array_part(thr, obj);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) == 0);\n\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tduk_uint8_t *fp;\n\n\t\t/* since duk__abandon_array_part() causes a resize, there should be no gaps in keys */\n\t\tDUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != NULL);\n\n\t\t/* avoid multiple computations of flags address; bypasses macros */\n\t\tfp = DUK_HOBJECT_E_GET_FLAGS_PTR(thr->heap, obj, i);\n\t\tif (is_freeze && !((*fp) & DUK_PROPDESC_FLAG_ACCESSOR)) {\n\t\t\t*fp &= ~(DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE);\n\t\t} else {\n\t\t\t*fp &= ~DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t}\n\t}\n\n\tDUK_HOBJECT_CLEAR_EXTENSIBLE(obj);\n\n\t/* no need to compact since we already did that in duk__abandon_array_part()\n\t * (regardless of whether an array part existed or not.\n\t */\n\n\treturn;\n}\n\n/*\n *  Object.isSealed() and Object.isFrozen()  (E5 Sections 15.2.3.11, 15.2.3.13)\n *\n *  Since the algorithms are similar, a helper provides both functions.\n *  Freezing is essentially sealing + making plain properties non-writable.\n *\n *  Note: all virtual (non-concrete) properties are currently non-configurable\n *  and non-writable (and there are no accessor virtual properties), so they don't\n *  need to be considered here now.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen) {\n\tduk_uint_fast32_t i;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(thr);\n\n\t/* Note: no allocation pressure, no need to check refcounts etc */\n\n\t/* must not be extensible */\n\tif (DUK_HOBJECT_HAS_EXTENSIBLE(obj)) {\n\t\treturn 0;\n\t}\n\n\t/* all virtual properties are non-configurable and non-writable */\n\n\t/* entry part must not contain any configurable properties, or\n\t * writable properties (if is_frozen).\n\t */\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tduk_small_uint_t flags;\n\n\t\tif (!DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* avoid multiple computations of flags address; bypasses macros */\n\t\tflags = (duk_small_uint_t) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, i);\n\n\t\tif (flags & DUK_PROPDESC_FLAG_CONFIGURABLE) {\n\t\t\treturn 0;\n\t\t}\n\t\tif (is_frozen &&\n\t\t    !(flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t    (flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* array part must not contain any non-unused properties, as they would\n\t * be configurable and writable.\n\t */\n\tfor (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\tduk_tval *tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\treturn 1;\n}\n\n/*\n *  Object.preventExtensions() and Object.isExtensible()  (E5 Sections 15.2.3.10, 15.2.3.13)\n *\n *  Not needed, implemented by macros DUK_HOBJECT_{HAS,CLEAR,SET}_EXTENSIBLE\n *  and the Object built-in bindings.\n */\n\n/* automatic undefs */\n#undef DUK__HASH_DELETED\n#undef DUK__HASH_UNUSED\n#undef DUK__NO_ARRAY_INDEX\n#undef DUK__VALSTACK_PROXY_LOOKUP\n#undef DUK__VALSTACK_SPACE\n/*\n *  duk_hstring assertion helpers.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ASSERTIONS)\n\nDUK_INTERNAL void duk_hstring_assert_valid(duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n/*\n *  Misc support functions\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  duk_hstring charCodeAt, with and without surrogate awareness\n */\n\nDUK_INTERNAL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, duk_uint_t pos, duk_bool_t surrogate_aware) {\n\tduk_uint32_t boff;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_ucodepoint_t cp1;\n\tduk_ucodepoint_t cp2;\n\n\t/* Caller must check character offset to be inside the string. */\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT_DISABLE(pos >= 0);  /* unsigned */\n\tDUK_ASSERT(pos < (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h));\n\n\tboff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint32_t) pos);\n\tDUK_DDD(DUK_DDDPRINT(\"charCodeAt: pos=%ld -> boff=%ld, str=%!O\",\n\t                     (long) pos, (long) boff, (duk_heaphdr *) h));\n\tDUK_ASSERT_DISABLE(boff >= 0);\n\tDUK_ASSERT(boff < DUK_HSTRING_GET_BYTELEN(h));\n\n\tp_start = DUK_HSTRING_GET_DATA(h);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h);\n\tp = p_start + boff;\n\tDUK_DDD(DUK_DDDPRINT(\"p_start=%p, p_end=%p, p=%p\",\n\t                     (const void *) p_start, (const void *) p_end,\n\t                     (const void *) p));\n\n\t/* For invalid UTF-8 (never happens for standard ECMAScript strings)\n\t * return U+FFFD replacement character.\n\t */\n\tif (duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp1)) {\n\t\tif (surrogate_aware && cp1 >= 0xd800UL && cp1 <= 0xdbffUL) {\n\t\t\t/* The decode helper is memory safe even if 'cp1' was\n\t\t\t * decoded at the end of the string and 'p' is no longer\n\t\t\t * within string memory range.\n\t\t\t */\n\t\t\tcp2 = 0;  /* If call fails, this is left untouched and won't match cp2 check. */\n\t\t\t(void) duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp2);\n\t\t\tif (cp2 >= 0xdc00UL && cp2 <= 0xdfffUL) {\n\t\t\t\tcp1 = (duk_ucodepoint_t) (((cp1 - 0xd800UL) << 10) + (cp2 - 0xdc00UL) + 0x10000UL);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tcp1 = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t}\n\n\treturn cp1;\n}\n\n/*\n *  duk_hstring charlen, when lazy charlen disabled\n */\n\n#if !defined(DUK_USE_HSTRING_LAZY_CLEN)\n#if !defined(DUK_USE_HSTRING_CLEN)\n#error non-lazy duk_hstring charlen but DUK_USE_HSTRING_CLEN not set\n#endif\nDUK_INTERNAL void duk_hstring_init_charlen(duk_hstring *h) {\n\tduk_uint32_t clen;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(!DUK_HSTRING_HAS_ASCII(h));\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h));\n\n\tclen = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n#if defined(DUK_USE_STRLEN16)\n\tDUK_ASSERT(clen <= 0xffffUL);  /* Bytelength checked during interning. */\n\th->clen16 = (duk_uint16_t) clen;\n#else\n\th->clen = (duk_uint32_t) clen;\n#endif\n\tif (DUK_LIKELY(clen == DUK_HSTRING_GET_BYTELEN(h))) {\n\t\tDUK_HSTRING_SET_ASCII(h);\n\t}\n}\n\nDUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {\n#if defined(DUK_USE_STRLEN16)\n\treturn h->clen16;\n#else\n\treturn h->clen;\n#endif\n}\n#endif  /* !DUK_USE_HSTRING_LAZY_CLEN */\n\n/*\n *  duk_hstring charlen, when lazy charlen enabled\n */\n\n#if defined(DUK_USE_HSTRING_LAZY_CLEN)\n#if defined(DUK_USE_HSTRING_CLEN)\nDUK_LOCAL DUK_COLD duk_size_t duk__hstring_get_charlen_slowpath(duk_hstring *h) {\n\tduk_size_t res;\n\n\tDUK_ASSERT(h->clen == 0);  /* Checked by caller. */\n\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* ROM strings have precomputed clen, but if the computed clen is zero\n\t * we can still come here and can't write anything.\n\t */\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) {\n\t\treturn 0;\n\t}\n#endif\n\n\tres = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n#if defined(DUK_USE_STRLEN16)\n\tDUK_ASSERT(res <= 0xffffUL);  /* Bytelength checked during interning. */\n\th->clen16 = (duk_uint16_t) res;\n#else\n\th->clen = (duk_uint32_t) res;\n#endif\n\tif (DUK_LIKELY(res == DUK_HSTRING_GET_BYTELEN(h))) {\n\t\tDUK_HSTRING_SET_ASCII(h);\n\t}\n\treturn res;\n}\n#else  /* DUK_USE_HSTRING_CLEN */\nDUK_LOCAL duk_size_t duk__hstring_get_charlen_slowpath(duk_hstring *h) {\n\tif (DUK_LIKELY(DUK_HSTRING_HAS_ASCII(h))) {\n\t\t/* Most practical strings will go here. */\n\t\treturn DUK_HSTRING_GET_BYTELEN(h);\n\t} else {\n\t\t/* ASCII flag is lazy, so set it here. */\n\t\tduk_size_t res;\n\n\t\t/* XXX: here we could use the strcache to speed up the\n\t\t * computation (matters for 'i < str.length' loops).\n\t\t */\n\n\t\tres = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\n#if defined(DUK_USE_ROM_STRINGS)\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) {\n\t\t\t/* For ROM strings, can't write anything; ASCII flag\n\t\t\t * is preset so we don't need to update it.\n\t\t\t */\n\t\t\treturn res;\n\t\t}\n#endif\n\t\tif (DUK_LIKELY(res == DUK_HSTRING_GET_BYTELEN(h))) {\n\t\t\tDUK_HSTRING_SET_ASCII(h);\n\t\t}\n\t\treturn res;\n\t}\n}\n#endif  /* DUK_USE_HSTRING_CLEN */\n\n#if defined(DUK_USE_HSTRING_CLEN)\nDUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {\n#if defined(DUK_USE_STRLEN16)\n\tif (DUK_LIKELY(h->clen16 != 0)) {\n\t\treturn h->clen16;\n\t}\n#else\n\tif (DUK_LIKELY(h->clen != 0)) {\n\t\treturn h->clen;\n\t}\n#endif\n\treturn duk__hstring_get_charlen_slowpath(h);\n}\n#else  /* DUK_USE_HSTRING_CLEN */\nDUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {\n\t/* Always use slow path. */\n\treturn duk__hstring_get_charlen_slowpath(h);\n}\n#endif  /* DUK_USE_HSTRING_CLEN */\n#endif  /* DUK_USE_HSTRING_LAZY_CLEN */\n\n/*\n *  Compare duk_hstring to an ASCII cstring.\n */\n\nDUK_INTERNAL duk_bool_t duk_hstring_equals_ascii_cstring(duk_hstring *h, const char *cstr) {\n\tduk_size_t len;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(cstr != NULL);\n\n\tlen = DUK_STRLEN(cstr);\n\tif (len != DUK_HSTRING_GET_BYTELEN(h)) {\n\t\treturn 0;\n\t}\n\tif (duk_memcmp((const void *) cstr, (const void *) DUK_HSTRING_GET_DATA(h), len) == 0) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n/*\n *  duk_hthread allocation and freeing.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Allocate initial stacks for a thread.  Note that 'thr' must be reachable\n *  as a garbage collection may be triggered by the allocation attempts.\n *  Returns zero (without leaking memory) if init fails.\n */\n\nDUK_INTERNAL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr) {\n\tduk_size_t alloc_size;\n\tduk_size_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->valstack == NULL);\n\tDUK_ASSERT(thr->valstack_end == NULL);\n\tDUK_ASSERT(thr->valstack_alloc_end == NULL);\n\tDUK_ASSERT(thr->valstack_bottom == NULL);\n\tDUK_ASSERT(thr->valstack_top == NULL);\n\tDUK_ASSERT(thr->callstack_curr == NULL);\n\n\t/* valstack */\n\tDUK_ASSERT(DUK_VALSTACK_API_ENTRY_MINIMUM <= DUK_VALSTACK_INITIAL_SIZE);\n\talloc_size = sizeof(duk_tval) * DUK_VALSTACK_INITIAL_SIZE;\n\tthr->valstack = (duk_tval *) DUK_ALLOC(heap, alloc_size);\n\tif (!thr->valstack) {\n\t\tgoto fail;\n\t}\n\tduk_memzero(thr->valstack, alloc_size);\n\tthr->valstack_end = thr->valstack + DUK_VALSTACK_API_ENTRY_MINIMUM;\n\tthr->valstack_alloc_end = thr->valstack + DUK_VALSTACK_INITIAL_SIZE;\n\tthr->valstack_bottom = thr->valstack;\n\tthr->valstack_top = thr->valstack;\n\n\tfor (i = 0; i < DUK_VALSTACK_INITIAL_SIZE; i++) {\n\t\tDUK_TVAL_SET_UNDEFINED(&thr->valstack[i]);\n\t}\n\n\treturn 1;\n\n fail:\n\tDUK_FREE(heap, thr->valstack);\n\tDUK_ASSERT(thr->callstack_curr == NULL);\n\n\tthr->valstack = NULL;\n\treturn 0;\n}\n\n/* For indirect allocs. */\n\nDUK_INTERNAL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud) {\n\tduk_hthread *thr = (duk_hthread *) ud;\n\tDUK_UNREF(heap);\n\treturn (void *) thr->valstack;\n}\n/*\n *  Initialize built-in objects.  Current thread must have a valstack\n *  and initialization errors may longjmp, so a setjmp() catch point\n *  must exist.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Encoding constants, must match genbuiltins.py\n */\n\n#define DUK__PROP_FLAGS_BITS             3\n#define DUK__LENGTH_PROP_BITS            3\n#define DUK__NARGS_BITS                  3\n#define DUK__PROP_TYPE_BITS              3\n\n#define DUK__NARGS_VARARGS_MARKER        0x07\n\n#define DUK__PROP_TYPE_DOUBLE            0\n#define DUK__PROP_TYPE_STRING            1\n#define DUK__PROP_TYPE_STRIDX            2\n#define DUK__PROP_TYPE_BUILTIN           3\n#define DUK__PROP_TYPE_UNDEFINED         4\n#define DUK__PROP_TYPE_BOOLEAN_TRUE      5\n#define DUK__PROP_TYPE_BOOLEAN_FALSE     6\n#define DUK__PROP_TYPE_ACCESSOR          7\n\n/*\n *  Create built-in objects by parsing an init bitstream generated\n *  by genbuiltins.py.\n */\n\n#if defined(DUK_USE_ROM_OBJECTS)\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) || defined(DUK_USE_ROM_GLOBAL_INHERIT)\nDUK_LOCAL void duk__duplicate_ram_global_object(duk_hthread *thr) {\n\tduk_hobject *h_global;\n#if defined(DUK_USE_ROM_GLOBAL_CLONE)\n\tduk_hobject *h_oldglobal;\n\tduk_uint8_t *props;\n\tduk_size_t alloc_size;\n#endif\n\tduk_hobject *h_objenv;\n\n\t/* XXX: refactor into internal helper, duk_clone_hobject() */\n\n#if defined(DUK_USE_ROM_GLOBAL_INHERIT)\n\t/* Inherit from ROM-based global object: less RAM usage, less transparent. */\n\th_global = duk_push_object_helper(thr,\n\t                                  DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                  DUK_HOBJECT_FLAG_FASTREFS |\n\t                                  DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL),\n\t                                  DUK_BIDX_GLOBAL);\n\tDUK_ASSERT(h_global != NULL);\n#elif defined(DUK_USE_ROM_GLOBAL_CLONE)\n\t/* Clone the properties of the ROM-based global object to create a\n\t * fully RAM-based global object.  Uses more memory than the inherit\n\t * model but more compliant.\n\t */\n\th_global = duk_push_object_helper(thr,\n\t                                  DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                  DUK_HOBJECT_FLAG_FASTREFS |\n\t                                  DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL),\n\t                                  DUK_BIDX_OBJECT_PROTOTYPE);\n\tDUK_ASSERT(h_global != NULL);\n\th_oldglobal = thr->builtins[DUK_BIDX_GLOBAL];\n\tDUK_ASSERT(h_oldglobal != NULL);\n\n\t/* Copy the property table verbatim; this handles attributes etc.\n\t * For ROM objects it's not necessary (or possible) to update\n\t * refcounts so leave them as is.\n\t */\n\talloc_size = DUK_HOBJECT_P_ALLOC_SIZE(h_oldglobal);\n\tDUK_ASSERT(alloc_size > 0);\n\tprops = DUK_ALLOC_CHECKED(thr, alloc_size);\n\tDUK_ASSERT(props != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, h_oldglobal) != NULL);\n\tduk_memcpy((void *) props, (const void *) DUK_HOBJECT_GET_PROPS(thr->heap, h_oldglobal), alloc_size);\n\n\t/* XXX: keep property attributes or tweak them here?\n\t * Properties will now be non-configurable even when they're\n\t * normally configurable for the global object.\n\t */\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, h_global) == NULL);\n\tDUK_HOBJECT_SET_PROPS(thr->heap, h_global, props);\n\tDUK_HOBJECT_SET_ESIZE(h_global, DUK_HOBJECT_GET_ESIZE(h_oldglobal));\n\tDUK_HOBJECT_SET_ENEXT(h_global, DUK_HOBJECT_GET_ENEXT(h_oldglobal));\n\tDUK_HOBJECT_SET_ASIZE(h_global, DUK_HOBJECT_GET_ASIZE(h_oldglobal));\n\tDUK_HOBJECT_SET_HSIZE(h_global, DUK_HOBJECT_GET_HSIZE(h_oldglobal));\n#else\n#error internal error in config defines\n#endif\n\n\tduk_hobject_compact_props(thr, h_global);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE((duk_heaphdr *) thr->builtins[DUK_BIDX_GLOBAL]));  /* no need to decref: ROM object */\n\tthr->builtins[DUK_BIDX_GLOBAL] = h_global;\n\tDUK_HOBJECT_INCREF(thr, h_global);\n\tDUK_D(DUK_DPRINT(\"duplicated global object: %!O\", h_global));\n\n\t/* Create a fresh object environment for the global scope.  This is\n\t * needed so that the global scope points to the newly created RAM-based\n\t * global object.\n\t */\n\th_objenv = (duk_hobject *) duk_hobjenv_alloc(thr,\n\t                                             DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                             DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\tDUK_ASSERT(h_objenv != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_objenv) == NULL);\n\tduk_push_hobject(thr, h_objenv);\n\n\tDUK_ASSERT(h_global != NULL);\n\t((duk_hobjenv *) h_objenv)->target = h_global;\n\tDUK_HOBJECT_INCREF(thr, h_global);\n\tDUK_ASSERT(((duk_hobjenv *) h_objenv)->has_this == 0);\n\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL_ENV] != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE((duk_heaphdr *) thr->builtins[DUK_BIDX_GLOBAL_ENV]));  /* no need to decref: ROM object */\n\tthr->builtins[DUK_BIDX_GLOBAL_ENV] = h_objenv;\n\tDUK_HOBJECT_INCREF(thr, h_objenv);\n\tDUK_D(DUK_DPRINT(\"duplicated global env: %!O\", h_objenv));\n\n\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) h_objenv);\n\n\tduk_pop_2(thr);  /* Pop global object and global env. */\n}\n#endif  /* DUK_USE_ROM_GLOBAL_CLONE || DUK_USE_ROM_GLOBAL_INHERIT */\n\nDUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {\n\t/* Setup builtins from ROM objects.  All heaps/threads will share\n\t * the same readonly objects.\n\t */\n\tduk_small_uint_t i;\n\n\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\tduk_hobject *h;\n\t\th = (duk_hobject *) DUK_LOSE_CONST(duk_rom_builtins_bidx[i]);\n\t\tDUK_ASSERT(h != NULL);\n\t\tthr->builtins[i] = h;\n\t}\n\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) || defined(DUK_USE_ROM_GLOBAL_INHERIT)\n\t/* By default the global object is read-only which is often much\n\t * more of an issue than having read-only built-in objects (like\n\t * RegExp, Date, etc).  Use a RAM-based copy of the global object\n\t * and the global environment object for convenience.\n\t */\n\tduk__duplicate_ram_global_object(thr);\n#endif\n}\n#else  /* DUK_USE_ROM_OBJECTS */\nDUK_LOCAL void duk__push_stridx(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\tduk_small_uint_t n;\n\n\tn = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\tDUK_ASSERT_DISABLE(n >= 0);  /* unsigned */\n\tDUK_ASSERT(n < DUK_HEAP_NUM_STRINGS);\n\tduk_push_hstring_stridx(thr, n);\n}\nDUK_LOCAL void duk__push_string(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\t/* XXX: built-ins data could provide a maximum length that is\n\t * actually needed; bitpacked max length is now 256 bytes.\n\t */\n\tduk_uint8_t tmp[DUK_BD_BITPACKED_STRING_MAXLEN];\n\tduk_small_uint_t len;\n\n\tlen = duk_bd_decode_bitpacked_string(bd, tmp);\n\tduk_push_lstring(thr, (const char *) tmp, (duk_size_t) len);\n}\nDUK_LOCAL void duk__push_stridx_or_string(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\tduk_small_uint_t n;\n\n\tn = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\tif (n == 0) {\n\t\tduk__push_string(thr, bd);\n\t} else {\n\t\tn--;\n\t\tDUK_ASSERT(n < DUK_HEAP_NUM_STRINGS);\n\t\tduk_push_hstring_stridx(thr, n);\n\t}\n}\nDUK_LOCAL void duk__push_double(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\tduk_double_union du;\n\tduk_small_uint_t i;\n\n\tfor (i = 0; i < 8; i++) {\n\t\t/* Encoding endianness must match target memory layout,\n\t\t * build scripts and genbuiltins.py must ensure this.\n\t\t */\n\t\tdu.uc[i] = (duk_uint8_t) duk_bd_decode(bd, 8);\n\t}\n\n\tduk_push_number(thr, du.d);  /* push operation normalizes NaNs */\n}\n\nDUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {\n\tduk_bitdecoder_ctx bd_ctx;\n\tduk_bitdecoder_ctx *bd = &bd_ctx;  /* convenience */\n\tduk_hobject *h;\n\tduk_small_uint_t i, j;\n\n\tDUK_D(DUK_DPRINT(\"INITBUILTINS BEGIN: DUK_NUM_BUILTINS=%d, DUK_NUM_BUILTINS_ALL=%d\", (int) DUK_NUM_BUILTINS, (int) DUK_NUM_ALL_BUILTINS));\n\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tbd->data = (const duk_uint8_t *) duk_builtins_data;\n\tbd->length = (duk_size_t) DUK_BUILTINS_DATA_LENGTH;\n\n\t/*\n\t *  First create all built-in bare objects on the empty valstack.\n\t *\n\t *  Built-ins in the index range [0,DUK_NUM_BUILTINS-1] have value\n\t *  stack indices matching their eventual thr->builtins[] index.\n\t *\n\t *  Built-ins in the index range [DUK_NUM_BUILTINS,DUK_NUM_ALL_BUILTINS]\n\t *  will exist on the value stack during init but won't be placed\n\t *  into thr->builtins[].  These are objects referenced in some way\n\t *  from thr->builtins[] roots but which don't need to be indexed by\n\t *  Duktape through thr->builtins[] (e.g. user custom objects).\n\t *\n\t *  Internal prototypes will be incorrect (NULL) at this stage.\n\t */\n\n\tduk_require_stack(thr, DUK_NUM_ALL_BUILTINS);\n\n\tDUK_DD(DUK_DDPRINT(\"create empty built-ins\"));\n\tDUK_ASSERT_TOP(thr, 0);\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tduk_small_uint_t class_num;\n\t\tduk_small_int_t len = -1;  /* must be signed */\n\n\t\tclass_num = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tlen = (duk_small_int_t) duk_bd_decode_flagged_signed(bd, DUK__LENGTH_PROP_BITS, (duk_int32_t) -1 /*def_value*/);\n\n\t\tif (class_num == DUK_HOBJECT_CLASS_FUNCTION) {\n\t\t\tduk_small_uint_t natidx;\n\t\t\tduk_small_int_t c_nargs;  /* must hold DUK_VARARGS */\n\t\t\tduk_c_function c_func;\n\t\t\tduk_int16_t magic;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"len=%ld\", (long) len));\n\t\t\tDUK_ASSERT(len >= 0);\n\n\t\t\tnatidx = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\tDUK_ASSERT(natidx != 0);\n\t\t\tc_func = duk_bi_native_functions[natidx];\n\t\t\tDUK_ASSERT(c_func != NULL);\n\n\t\t\tc_nargs = (duk_small_int_t) duk_bd_decode_flagged_signed(bd, DUK__NARGS_BITS, len /*def_value*/);\n\t\t\tif (c_nargs == DUK__NARGS_VARARGS_MARKER) {\n\t\t\t\tc_nargs = DUK_VARARGS;\n\t\t\t}\n\n\t\t\t/* XXX: set magic directly here? (it could share the c_nargs arg) */\n\t\t\t(void) duk_push_c_function_builtin(thr, c_func, c_nargs);\n\t\t\th = duk_known_hobject(thr, -1);\n\n\t\t\t/* Currently all built-in native functions are strict.\n\t\t\t * duk_push_c_function() now sets strict flag, so\n\t\t\t * assert for it.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_STRICT(h));\n\n\t\t\t/* XXX: function properties */\n\n\t\t\tduk__push_stridx_or_string(thr, bd);\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\t\t\tduk_xdef_prop_stridx_short(thr,\n\t\t\t                           -2,\n\t\t\t                           DUK_STRIDX_NAME,\n\t\t\t                           DUK_PROPDESC_FLAGS_C);\n#else\n\t\t\tduk_pop(thr);  /* Not very ideal but good enough for now. */\n#endif\n\n\t\t\t/* Almost all global level Function objects are constructable\n\t\t\t * but not all: Function.prototype is a non-constructable,\n\t\t\t * callable Function.\n\t\t\t */\n\t\t\tif (duk_bd_decode_flag(bd)) {\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_CONSTRUCTABLE(h));\n\t\t\t} else {\n\t\t\t\tDUK_HOBJECT_CLEAR_CONSTRUCTABLE(h);\n\t\t\t}\n\n\t\t\t/* Cast converts magic to 16-bit signed value */\n\t\t\tmagic = (duk_int16_t) duk_bd_decode_varuint(bd);\n\t\t\t((duk_hnatfunc *) h)->magic = magic;\n\t\t} else if (class_num == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tduk_push_array(thr);\n\t\t} else if (class_num == DUK_HOBJECT_CLASS_OBJENV) {\n\t\t\tduk_hobjenv *env;\n\t\t\tduk_hobject *global;\n\n\t\t\tDUK_ASSERT(i == DUK_BIDX_GLOBAL_ENV);\n\t\t\tDUK_ASSERT(DUK_BIDX_GLOBAL_ENV > DUK_BIDX_GLOBAL);\n\n\t\t\tenv = duk_hobjenv_alloc(thr,\n\t                                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\t\t\tDUK_ASSERT(env->target == NULL);\n\t\t\tduk_push_hobject(thr, (duk_hobject *) env);\n\n\t\t\tglobal = duk_known_hobject(thr, DUK_BIDX_GLOBAL);\n\t\t\tDUK_ASSERT(global != NULL);\n\t\t\tenv->target = global;\n\t\t\tDUK_HOBJECT_INCREF(thr, global);\n\t\t\tDUK_ASSERT(env->has_this == 0);\n\n\t\t\tDUK_HOBJENV_ASSERT_VALID(env);\n\t\t} else {\n\t\t\tDUK_ASSERT(class_num != DUK_HOBJECT_CLASS_DECENV);\n\n\t\t\t(void) duk_push_object_helper(thr,\n\t\t\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t\t\t                              DUK_HOBJECT_FLAG_EXTENSIBLE,\n\t\t\t                              -1);  /* no prototype or class yet */\n\n\t\t}\n\n\t\th = duk_known_hobject(thr, -1);\n\t\tDUK_HOBJECT_SET_CLASS_NUMBER(h, class_num);\n\n\t\tif (i < DUK_NUM_BUILTINS) {\n\t\t\tthr->builtins[i] = h;\n\t\t\tDUK_HOBJECT_INCREF(thr, &h->hdr);\n\t\t}\n\n\t\tif (len >= 0) {\n\t\t\t/* In ES2015+ built-in function object .length property\n\t\t\t * has property attributes C (configurable only):\n\t\t\t * http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-standard-built-in-objects\n\t\t\t *\n\t\t\t * Array.prototype remains an Array instance in ES2015+\n\t\t\t * and its length has attributes W (writable only).\n\t\t\t * Because .length is now virtual for duk_harray, it is\n\t\t\t * not encoded explicitly in init data.\n\t\t\t */\n\n\t\t\tDUK_ASSERT(class_num != DUK_HOBJECT_CLASS_ARRAY);  /* .length is virtual */\n\t\t\tduk_push_int(thr, len);\n\t\t\tduk_xdef_prop_stridx_short(thr,\n\t\t\t                           -2,\n\t\t\t                           DUK_STRIDX_LENGTH,\n\t\t\t                           DUK_PROPDESC_FLAGS_C);\n\t\t}\n\n\t\t/* enable exotic behaviors last */\n\n\t\tif (class_num == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(h));  /* set by duk_push_array() */\n\t\t}\n\t\tif (class_num == DUK_HOBJECT_CLASS_STRING) {\n\t\t\tDUK_HOBJECT_SET_EXOTIC_STRINGOBJ(h);\n\t\t}\n\n\t\t/* some assertions */\n\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h));\n\t\t/* DUK_HOBJECT_FLAG_CONSTRUCTABLE varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_COMPFUNC(h));\n\t\t/* DUK_HOBJECT_FLAG_NATFUNC varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_IS_PROXY(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(h) || class_num == DUK_HOBJECT_CLASS_ARRAY);\n\t\t/* DUK_HOBJECT_FLAG_STRICT varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(h) ||  /* all native functions have NEWENV */\n\t\t           DUK_HOBJECT_HAS_NEWENV(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NAMEBINDING(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(h));\n\t\t/* DUK_HOBJECT_FLAG_EXOTIC_ARRAY varies */\n\t\t/* DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"created built-in %ld, class=%ld, length=%ld\", (long) i, (long) class_num, (long) len));\n\t}\n\n\t/*\n\t *  Then decode the builtins init data (see genbuiltins.py) to\n\t *  init objects.  Internal prototypes are set at this stage,\n\t *  with thr->builtins[] populated.\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"initialize built-in object properties\"));\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tduk_small_uint_t t;\n\t\tduk_small_uint_t num;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"initializing built-in object at index %ld\", (long) i));\n\t\th = duk_known_hobject(thr, (duk_idx_t) i);\n\n\t\tt = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tif (t > 0) {\n\t\t\tt--;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"set internal prototype: built-in %ld\", (long) t));\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, duk_known_hobject(thr, (duk_idx_t) t));\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\t\t/* Standard native built-ins cannot inherit from\n\t\t\t * %NativeFunctionPrototype%, they are required to\n\t\t\t * inherit from Function.prototype directly.\n\t\t\t */\n\t\t\tDUK_ASSERT(thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE] != NULL);\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\t\t}\n\n\t\tt = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tif (t > 0) {\n\t\t\t/* 'prototype' property for all built-in objects (which have it) has attributes:\n\t\t\t *  [[Writable]] = false,\n\t\t\t *  [[Enumerable]] = false,\n\t\t\t *  [[Configurable]] = false\n\t\t\t */\n\t\t\tt--;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"set external prototype: built-in %ld\", (long) t));\n\t\t\tduk_dup(thr, (duk_idx_t) t);\n\t\t\tduk_xdef_prop_stridx(thr, (duk_idx_t) i, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_NONE);\n\t\t}\n\n\t\tt = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tif (t > 0) {\n\t\t\t/* 'constructor' property for all built-in objects (which have it) has attributes:\n\t\t\t *  [[Writable]] = true,\n\t\t\t *  [[Enumerable]] = false,\n\t\t\t *  [[Configurable]] = true\n\t\t\t */\n\t\t\tt--;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"set external constructor: built-in %ld\", (long) t));\n\t\t\tduk_dup(thr, (duk_idx_t) t);\n\t\t\tduk_xdef_prop_stridx(thr, (duk_idx_t) i, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC);\n\t\t}\n\n\t\t/* normal valued properties */\n\t\tnum = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tDUK_DDD(DUK_DDDPRINT(\"built-in object %ld, %ld normal valued properties\", (long) i, (long) num));\n\t\tfor (j = 0; j < num; j++) {\n\t\t\tduk_small_uint_t defprop_flags;\n\n\t\t\tduk__push_stridx_or_string(thr, bd);\n\n\t\t\t/*\n\t\t\t *  Property attribute defaults are defined in E5 Section 15 (first\n\t\t\t *  few pages); there is a default for all properties and a special\n\t\t\t *  default for 'length' properties.  Variation from the defaults is\n\t\t\t *  signaled using a single flag bit in the bitstream.\n\t\t\t */\n\n\t\t\tdefprop_flags = (duk_small_uint_t) duk_bd_decode_flagged(bd,\n\t\t\t                                                         DUK__PROP_FLAGS_BITS,\n\t\t\t                                                         (duk_uint32_t) DUK_PROPDESC_FLAGS_WC);\n\t\t\tdefprop_flags |= DUK_DEFPROP_FORCE |\n\t\t\t                 DUK_DEFPROP_HAVE_VALUE |\n\t\t\t                 DUK_DEFPROP_HAVE_WRITABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_ENUMERABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_CONFIGURABLE;  /* Defaults for data properties. */\n\n\t\t\t/* The writable, enumerable, configurable flags in prop_flags\n\t\t\t * match both duk_def_prop() and internal property flags.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_WRITABLE == DUK_DEFPROP_WRITABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_ENUMERABLE == DUK_DEFPROP_ENUMERABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_CONFIGURABLE == DUK_DEFPROP_CONFIGURABLE);\n\n\t\t\tt = (duk_small_uint_t) duk_bd_decode(bd, DUK__PROP_TYPE_BITS);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"built-in %ld, normal-valued property %ld, key %!T, flags 0x%02lx, type %ld\",\n\t\t\t                     (long) i, (long) j, duk_get_tval(thr, -1), (unsigned long) defprop_flags, (long) t));\n\n\t\t\tswitch (t) {\n\t\t\tcase DUK__PROP_TYPE_DOUBLE: {\n\t\t\t\tduk__push_double(thr, bd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_STRING: {\n\t\t\t\tduk__push_string(thr, bd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_STRIDX: {\n\t\t\t\tduk__push_stridx(thr, bd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_BUILTIN: {\n\t\t\t\tduk_small_uint_t bidx;\n\n\t\t\t\tbidx = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_dup(thr, (duk_idx_t) bidx);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_UNDEFINED: {\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_BOOLEAN_TRUE: {\n\t\t\t\tduk_push_true(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_BOOLEAN_FALSE: {\n\t\t\t\tduk_push_false(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_ACCESSOR: {\n\t\t\t\tduk_small_uint_t natidx_getter = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_small_uint_t natidx_setter = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_small_uint_t accessor_magic = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_c_function c_func_getter;\n\t\t\t\tduk_c_function c_func_setter;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"built-in accessor property: objidx=%ld, key=%!T, getteridx=%ld, setteridx=%ld, flags=0x%04lx\",\n\t\t\t\t                     (long) i, duk_get_tval(thr, -1), (long) natidx_getter, (long) natidx_setter, (unsigned long) defprop_flags));\n\n\t\t\t\tc_func_getter = duk_bi_native_functions[natidx_getter];\n\t\t\t\tif (c_func_getter != NULL) {\n\t\t\t\t\tduk_push_c_function_builtin_noconstruct(thr, c_func_getter, 0);  /* always 0 args */\n\t\t\t\t\tduk_set_magic(thr, -1, (duk_int_t) accessor_magic);\n\t\t\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_GETTER;\n\t\t\t\t}\n\t\t\t\tc_func_setter = duk_bi_native_functions[natidx_setter];\n\t\t\t\tif (c_func_setter != NULL) {\n\t\t\t\t\tduk_push_c_function_builtin_noconstruct(thr, c_func_setter, 1);  /* always 1 arg */\n\t\t\t\t\tduk_set_magic(thr, -1, (duk_int_t) accessor_magic);\n\t\t\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_SETTER;\n\t\t\t\t}\n\n\t\t\t\t/* Writable flag doesn't make sense for an accessor. */\n\t\t\t\tDUK_ASSERT((defprop_flags & DUK_PROPDESC_FLAG_WRITABLE) == 0);  /* genbuiltins.py ensures */\n\n\t\t\t\tdefprop_flags &= ~(DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE);\n\t\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t/* exhaustive */\n\t\t\t\tDUK_UNREACHABLE();\n\t\t\t}\n\t\t\t}\n\n\t\t\tduk_def_prop(thr, (duk_idx_t) i, defprop_flags);\n\t\t\tDUK_ASSERT_TOP(thr, DUK_NUM_ALL_BUILTINS);\n\t\t}\n\n\t\t/* native function properties */\n\t\tnum = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tDUK_DDD(DUK_DDDPRINT(\"built-in object %ld, %ld function valued properties\", (long) i, (long) num));\n\t\tfor (j = 0; j < num; j++) {\n\t\t\tduk_hstring *h_key;\n\t\t\tduk_small_uint_t natidx;\n\t\t\tduk_int_t c_nargs;  /* must hold DUK_VARARGS */\n\t\t\tduk_small_uint_t c_length;\n\t\t\tduk_int16_t magic;\n\t\t\tduk_c_function c_func;\n\t\t\tduk_hnatfunc *h_func;\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t\tduk_small_int_t lightfunc_eligible;\n#endif\n\t\t\tduk_small_uint_t defprop_flags;\n\n\t\t\tduk__push_stridx_or_string(thr, bd);\n\t\t\th_key = duk_known_hstring(thr, -1);\n\t\t\tDUK_UNREF(h_key);\n\t\t\tnatidx = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\n\t\t\tc_length = (duk_small_uint_t) duk_bd_decode(bd, DUK__LENGTH_PROP_BITS);\n\t\t\tc_nargs = (duk_int_t) duk_bd_decode_flagged(bd, DUK__NARGS_BITS, (duk_uint32_t) c_length /*def_value*/);\n\t\t\tif (c_nargs == DUK__NARGS_VARARGS_MARKER) {\n\t\t\t\tc_nargs = DUK_VARARGS;\n\t\t\t}\n\n\t\t\tc_func = duk_bi_native_functions[natidx];\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"built-in %ld, function-valued property %ld, key %!O, natidx %ld, length %ld, nargs %ld\",\n\t\t\t                     (long) i, (long) j, (duk_heaphdr *) h_key, (long) natidx, (long) c_length,\n\t\t\t                     (c_nargs == DUK_VARARGS ? (long) -1 : (long) c_nargs)));\n\n\t\t\t/* Cast converts magic to 16-bit signed value */\n\t\t\tmagic = (duk_int16_t) duk_bd_decode_varuint(bd);\n\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t\tlightfunc_eligible =\n\t\t\t\t((c_nargs >= DUK_LFUNC_NARGS_MIN && c_nargs <= DUK_LFUNC_NARGS_MAX) || (c_nargs == DUK_VARARGS)) &&\n\t\t\t\t(c_length <= DUK_LFUNC_LENGTH_MAX) &&\n\t\t\t\t(magic >= DUK_LFUNC_MAGIC_MIN && magic <= DUK_LFUNC_MAGIC_MAX);\n\n\t\t\t/* These functions have trouble working as lightfuncs.\n\t\t\t * Some of them have specific asserts and some may have\n\t\t         * additional properties (e.g. 'require.id' may be written).\n\t\t\t */\n\t\t\tif (c_func == duk_bi_global_object_eval) {\n\t\t\t\tlightfunc_eligible = 0;\n\t\t\t}\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\t\t\tif (c_func == duk_bi_thread_yield ||\n\t\t\t    c_func == duk_bi_thread_resume) {\n\t\t\t\tlightfunc_eligible = 0;\n\t\t\t}\n#endif\n\t\t\tif (c_func == duk_bi_function_prototype_call ||\n\t\t\t    c_func == duk_bi_function_prototype_apply ||\n\t\t\t    c_func == duk_bi_reflect_apply ||\n\t\t\t    c_func == duk_bi_reflect_construct) {\n\t\t\t\tlightfunc_eligible = 0;\n\t\t\t}\n\n\t\t\tif (lightfunc_eligible) {\n\t\t\t\tduk_tval tv_lfunc;\n\t\t\t\tduk_small_uint_t lf_nargs = (duk_small_uint_t) (c_nargs == DUK_VARARGS ? DUK_LFUNC_NARGS_VARARGS : c_nargs);\n\t\t\t\tduk_small_uint_t lf_flags = DUK_LFUNC_FLAGS_PACK(magic, c_length, lf_nargs);\n\t\t\t\tDUK_TVAL_SET_LIGHTFUNC(&tv_lfunc, c_func, lf_flags);\n\t\t\t\tduk_push_tval(thr, &tv_lfunc);\n\t\t\t\tDUK_D(DUK_DPRINT(\"built-in function eligible as light function: i=%d, j=%d c_length=%ld, c_nargs=%ld, magic=%ld -> %!iT\", (int) i, (int) j, (long) c_length, (long) c_nargs, (long) magic, duk_get_tval(thr, -1)));\n\t\t\t\tgoto lightfunc_skip;\n\t\t\t}\n\n\t\t\tDUK_D(DUK_DPRINT(\"built-in function NOT ELIGIBLE as light function: i=%d, j=%d c_length=%ld, c_nargs=%ld, magic=%ld\", (int) i, (int) j, (long) c_length, (long) c_nargs, (long) magic));\n#endif  /* DUK_USE_LIGHTFUNC_BUILTINS */\n\n\t\t\t/* [ (builtin objects) name ] */\n\n\t\t\tduk_push_c_function_builtin_noconstruct(thr, c_func, c_nargs);\n\t\t\th_func = duk_known_hnatfunc(thr, -1);\n\t\t\tDUK_UNREF(h_func);\n\n\t\t\t/* XXX: add into init data? */\n\n\t\t\t/* Special call handling, not described in init data. */\n\t\t\tif (c_func == duk_bi_global_object_eval ||\n\t\t\t    c_func == duk_bi_function_prototype_call ||\n\t\t\t    c_func == duk_bi_function_prototype_apply ||\n\t\t\t    c_func == duk_bi_reflect_apply ||\n\t\t\t    c_func == duk_bi_reflect_construct) {\n\t\t\t\tDUK_HOBJECT_SET_SPECIAL_CALL((duk_hobject *) h_func);\n\t\t\t}\n\n\t\t\t/* Currently all built-in native functions are strict.\n\t\t\t * This doesn't matter for many functions, but e.g.\n\t\t\t * String.prototype.charAt (and other string functions)\n\t\t\t * rely on being strict so that their 'this' binding is\n\t\t\t * not automatically coerced.\n\t\t\t */\n\t\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_func);\n\n\t\t\t/* No built-in functions are constructable except the top\n\t\t\t * level ones (Number, etc).\n\t\t\t */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) h_func));\n\n\t\t\t/* XXX: any way to avoid decoding magic bit; there are quite\n\t\t\t * many function properties and relatively few with magic values.\n\t\t\t */\n\t\t\th_func->magic = magic;\n\n\t\t\t/* [ (builtin objects) name func ] */\n\n\t\t\tduk_push_uint(thr, c_length);\n\t\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);\n\n\t\t\tduk_dup_m2(thr);\n\t\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n\n\t\t\t/* XXX: other properties of function instances; 'arguments', 'caller'. */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"built-in object %ld, function property %ld -> %!T\",\n\t\t\t                   (long) i, (long) j, (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t/* [ (builtin objects) name func ] */\n\n\t\t\t/*\n\t\t\t *  The default property attributes are correct for all\n\t\t\t *  function valued properties of built-in objects now.\n\t\t\t */\n\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t lightfunc_skip:\n#endif\n\n\t\t\tdefprop_flags = (duk_small_uint_t) duk_bd_decode_flagged(bd,\n\t\t\t                                                         DUK__PROP_FLAGS_BITS,\n\t\t\t                                                         (duk_uint32_t) DUK_PROPDESC_FLAGS_WC);\n\t\t\tdefprop_flags |= DUK_DEFPROP_FORCE |\n\t\t\t                 DUK_DEFPROP_HAVE_VALUE |\n\t\t\t                 DUK_DEFPROP_HAVE_WRITABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_ENUMERABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_CONFIGURABLE;\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_WRITABLE == DUK_DEFPROP_WRITABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_ENUMERABLE == DUK_DEFPROP_ENUMERABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_CONFIGURABLE == DUK_DEFPROP_CONFIGURABLE);\n\n\t\t\tduk_def_prop(thr, (duk_idx_t) i, defprop_flags);\n\n\t\t\t/* [ (builtin objects) ] */\n\t\t}\n\t}\n\n\t/*\n\t *  Special post-tweaks, for cases not covered by the init data format.\n\t *\n\t *  - Set Date.prototype.toGMTString to Date.prototype.toUTCString.\n\t *    toGMTString is required to have the same Function object as\n\t *    toUTCString in E5 Section B.2.6.  Note that while Smjs respects\n\t *    this, V8 does not (the Function objects are distinct).\n\t *\n\t *  - Make DoubleError non-extensible.\n\t *\n\t *  - Add info about most important effective compile options to Duktape.\n\t *\n\t *  - Possibly remove some properties (values or methods) which are not\n\t *    desirable with current feature options but are not currently\n\t *    conditional in init data.\n\t */\n\n#if defined(DUK_USE_DATE_BUILTIN)\n\tduk_get_prop_stridx_short(thr, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_UTC_STRING);\n\tduk_xdef_prop_stridx_short(thr, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_GMT_STRING, DUK_PROPDESC_FLAGS_WC);\n#endif\n\n\th = duk_known_hobject(thr, DUK_BIDX_DOUBLE_ERROR);\n\tDUK_HOBJECT_CLEAR_EXTENSIBLE(h);\n\n#if !defined(DUK_USE_ES6_OBJECT_PROTO_PROPERTY)\n\tDUK_DD(DUK_DDPRINT(\"delete Object.prototype.__proto__ built-in which is not enabled in features\"));\n\t(void) duk_hobject_delprop_raw(thr, thr->builtins[DUK_BIDX_OBJECT_PROTOTYPE], DUK_HTHREAD_STRING___PROTO__(thr), DUK_DELPROP_FLAG_THROW);\n#endif\n\n#if !defined(DUK_USE_ES6_OBJECT_SETPROTOTYPEOF)\n\tDUK_DD(DUK_DDPRINT(\"delete Object.setPrototypeOf built-in which is not enabled in features\"));\n\t(void) duk_hobject_delprop_raw(thr, thr->builtins[DUK_BIDX_OBJECT_CONSTRUCTOR], DUK_HTHREAD_STRING_SET_PROTOTYPE_OF(thr), DUK_DELPROP_FLAG_THROW);\n#endif\n\n\t/* XXX: relocate */\n\tduk_push_string(thr,\n\t\t\t/* Endianness indicator */\n#if defined(DUK_USE_INTEGER_LE)\n\t                \"l\"\n#elif defined(DUK_USE_INTEGER_BE)\n\t                \"b\"\n#elif defined(DUK_USE_INTEGER_ME)  /* integer mixed endian not really used now */\n\t                \"m\"\n#else\n\t                \"?\"\n#endif\n#if defined(DUK_USE_DOUBLE_LE)\n\t                \"l\"\n#elif defined(DUK_USE_DOUBLE_BE)\n\t                \"b\"\n#elif defined(DUK_USE_DOUBLE_ME)\n\t                \"m\"\n#else\n\t                \"?\"\n#endif\n\t                \" \"\n\t\t\t/* Packed or unpacked tval */\n#if defined(DUK_USE_PACKED_TVAL)\n\t                \"p\"\n#else\n\t                \"u\"\n#endif\n#if defined(DUK_USE_FASTINT)\n\t\t\t\"f\"\n#endif\n\t\t\t\" \"\n\t\t\t/* Low memory/performance options */\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\t\t\"s\"\n#endif\n#if !defined(DUK_USE_HEAPPTR16) && !defined(DUK_DATAPTR16) && !defined(DUK_FUNCPTR16)\n\t\t\t\"n\"\n#endif\n#if defined(DUK_USE_HEAPPTR16)\n\t\t\t\"h\"\n#endif\n#if defined(DUK_USE_DATAPTR16)\n\t\t\t\"d\"\n#endif\n#if defined(DUK_USE_FUNCPTR16)\n\t\t\t\"f\"\n#endif\n#if defined(DUK_USE_REFCOUNT16)\n\t\t\t\"R\"\n#endif\n#if defined(DUK_USE_STRHASH16)\n\t\t\t\"H\"\n#endif\n#if defined(DUK_USE_STRLEN16)\n\t\t\t\"S\"\n#endif\n#if defined(DUK_USE_BUFLEN16)\n\t\t\t\"B\"\n#endif\n#if defined(DUK_USE_OBJSIZES16)\n\t\t\t\"O\"\n#endif\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t\t\"L\"\n#endif\n#if defined(DUK_USE_ROM_STRINGS) || defined(DUK_USE_ROM_OBJECTS)\n\t\t\t/* XXX: This won't be shown in practice now\n\t\t\t * because this code is not run when builtins\n\t\t\t * are in ROM.\n\t\t\t */\n\t\t\t\"Z\"\n#endif\n#if defined(DUK_USE_LITCACHE_SIZE)\n\t\t\t\"l\"\n#endif\n\t                \" \"\n\t\t\t/* Object property allocation layout */\n#if defined(DUK_USE_HOBJECT_LAYOUT_1)\n\t\t\t\"p1\"\n#elif defined(DUK_USE_HOBJECT_LAYOUT_2)\n\t\t\t\"p2\"\n#elif defined(DUK_USE_HOBJECT_LAYOUT_3)\n\t\t\t\"p3\"\n#else\n\t\t\t\"p?\"\n#endif\n\t\t\t\" \"\n\t\t\t/* Alignment guarantee */\n#if (DUK_USE_ALIGN_BY == 4)\n\t\t\t\"a4\"\n#elif (DUK_USE_ALIGN_BY == 8)\n\t\t\t\"a8\"\n#elif (DUK_USE_ALIGN_BY == 1)\n\t\t\t\"a1\"\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\t\t\t\" \"\n\t\t\t/* Architecture, OS, and compiler strings */\n\t                DUK_USE_ARCH_STRING\n\t\t\t\" \"\n\t                DUK_USE_OS_STRING\n\t\t\t\" \"\n\t                DUK_USE_COMPILER_STRING);\n\tduk_xdef_prop_stridx_short(thr, DUK_BIDX_DUKTAPE, DUK_STRIDX_ENV, DUK_PROPDESC_FLAGS_WC);\n\n\t/*\n\t *  Since built-ins are not often extended, compact them.\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"compact built-ins\"));\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tduk_hobject_compact_props(thr, duk_known_hobject(thr, (duk_idx_t) i));\n\t}\n\n\tDUK_D(DUK_DPRINT(\"INITBUILTINS END\"));\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tDUK_DD(DUK_DDPRINT(\"built-in object %ld after initialization and compacting: %!@iO\",\n\t\t                   (long) i, (duk_heaphdr *) duk_require_hobject(thr, (duk_idx_t) i)));\n\t}\n#endif\n\n\t/*\n\t *  Pop built-ins from stack: they are now INCREF'd and\n\t *  reachable from the builtins[] array or indirectly\n\t *  through builtins[].\n\t */\n\n\tduk_set_top(thr, 0);\n\tDUK_ASSERT_TOP(thr, 0);\n}\n#endif  /* DUK_USE_ROM_OBJECTS */\n\nDUK_INTERNAL void duk_hthread_copy_builtin_objects(duk_hthread *thr_from, duk_hthread *thr_to) {\n\tduk_small_uint_t i;\n\n\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\tthr_to->builtins[i] = thr_from->builtins[i];\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr_to, thr_to->builtins[i]);  /* side effect free */\n\t}\n}\n\n/* automatic undefs */\n#undef DUK__LENGTH_PROP_BITS\n#undef DUK__NARGS_BITS\n#undef DUK__NARGS_VARARGS_MARKER\n#undef DUK__PROP_FLAGS_BITS\n#undef DUK__PROP_TYPE_ACCESSOR\n#undef DUK__PROP_TYPE_BITS\n#undef DUK__PROP_TYPE_BOOLEAN_FALSE\n#undef DUK__PROP_TYPE_BOOLEAN_TRUE\n#undef DUK__PROP_TYPE_BUILTIN\n#undef DUK__PROP_TYPE_DOUBLE\n#undef DUK__PROP_TYPE_STRIDX\n#undef DUK__PROP_TYPE_STRING\n#undef DUK__PROP_TYPE_UNDEFINED\n/*\n *  Thread support.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL void duk_hthread_terminate(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\twhile (thr->callstack_curr != NULL) {\n\t\tduk_hthread_activation_unwind_norz(thr);\n\t}\n\n\tthr->valstack_bottom = thr->valstack;\n\tduk_set_top(thr, 0);  /* unwinds valstack, updating refcounts */\n\n\tthr->state = DUK_HTHREAD_STATE_TERMINATED;\n\n\t/* Here we could remove references to built-ins, but it may not be\n\t * worth the effort because built-ins are quite likely to be shared\n\t * with another (unterminated) thread, and terminated threads are also\n\t * usually garbage collected quite quickly.\n\t *\n\t * We could also shrink the value stack here, but that also may not\n\t * be worth the effort for the same reason.\n\t */\n\n\tDUK_REFZERO_CHECK_SLOW(thr);\n}\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_curr_pc(duk_hthread *thr, duk_activation *act) {\n\tduk_instr_t *bcode;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_UNREF(thr);\n\n\t/* XXX: store 'bcode' pointer to activation for faster lookup? */\n\tif (act->func && DUK_HOBJECT_IS_COMPFUNC(act->func)) {\n\t\tbcode = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) (act->func));\n\t\treturn (duk_uint_fast32_t) (act->curr_pc - bcode);\n\t}\n\treturn 0;\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\nDUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_prev_pc(duk_hthread *thr, duk_activation *act) {\n\tduk_instr_t *bcode;\n\tduk_uint_fast32_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_UNREF(thr);\n\n\tif (act->func && DUK_HOBJECT_IS_COMPFUNC(act->func)) {\n\t\tbcode = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) (act->func));\n\t\tret = (duk_uint_fast32_t) (act->curr_pc - bcode);\n\t\tif (ret > 0) {\n\t\t\tret--;\n\t\t}\n\t\treturn ret;\n\t}\n\treturn 0;\n}\n\n/* Write bytecode executor's curr_pc back to topmost activation (if any). */\nDUK_INTERNAL void duk_hthread_sync_currpc(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tif (thr->ptr_curr_pc != NULL) {\n\t\t/* ptr_curr_pc != NULL only when bytecode executor is active. */\n\t\tDUK_ASSERT(thr->callstack_top > 0);\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tact = thr->callstack_curr;\n\t\tDUK_ASSERT(act != NULL);\n\t\tact->curr_pc = *thr->ptr_curr_pc;\n\t}\n}\n\nDUK_INTERNAL void duk_hthread_sync_and_null_currpc(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tif (thr->ptr_curr_pc != NULL) {\n\t\t/* ptr_curr_pc != NULL only when bytecode executor is active. */\n\t\tDUK_ASSERT(thr->callstack_top > 0);\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tact = thr->callstack_curr;\n\t\tDUK_ASSERT(act != NULL);\n\t\tact->curr_pc = *thr->ptr_curr_pc;\n\t\tthr->ptr_curr_pc = NULL;\n\t}\n}\n/*\n *  Thread stack (mainly call stack) primitives: allocation of activations,\n *  unwinding catchers and activations, etc.\n *\n *  Value stack handling is a part of the API implementation.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Unwind the topmost catcher of the current activation (caller must check that\n * both exist) without side effects.\n */\nDUK_INTERNAL void duk_hthread_catcher_unwind_norz(duk_hthread *thr, duk_activation *act) {\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(act->cat != NULL);  /* caller must check */\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"unwinding catch stack entry %p (lexenv check is done)\", (void *) cat));\n\n\tif (DUK_CAT_HAS_LEXENV_ACTIVE(cat)) {\n\t\tduk_hobject *env;\n\n\t\tenv = act->lex_env;             /* current lex_env of the activation (created for catcher) */\n\t\tDUK_ASSERT(env != NULL);        /* must be, since env was created when catcher was created */\n\t\tact->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, env);  /* prototype is lex_env before catcher created */\n\t\tDUK_HOBJECT_INCREF(thr, act->lex_env);\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, env);\n\n\t\t/* There is no need to decref anything else than 'env': if 'env'\n\t\t * becomes unreachable, refzero will handle decref'ing its prototype.\n\t\t */\n\t}\n\n\tact->cat = cat->parent;\n\tduk_hthread_catcher_free(thr, cat);\n}\n\n/* Same as above, but caller is certain no catcher-related lexenv may exist. */\nDUK_INTERNAL void duk_hthread_catcher_unwind_nolexenv_norz(duk_hthread *thr, duk_activation *act) {\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(act->cat != NULL);  /* caller must check */\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"unwinding catch stack entry %p (lexenv check is not done)\", (void *) cat));\n\n\tDUK_ASSERT(!DUK_CAT_HAS_LEXENV_ACTIVE(cat));\n\n\tact->cat = cat->parent;\n\tduk_hthread_catcher_free(thr, cat);\n}\n\nDUK_LOCAL\n#if defined(DUK_USE_CACHE_CATCHER)\nDUK_NOINLINE\n#endif\nduk_catcher *duk__hthread_catcher_alloc_slow(duk_hthread *thr) {\n\tduk_catcher *cat;\n\n\tcat = (duk_catcher *) DUK_ALLOC_CHECKED(thr, sizeof(duk_catcher));\n\tDUK_ASSERT(cat != NULL);\n\treturn cat;\n}\n\n#if defined(DUK_USE_CACHE_CATCHER)\nDUK_INTERNAL DUK_INLINE duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr) {\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tcat = thr->heap->catcher_free;\n\tif (DUK_LIKELY(cat != NULL)) {\n\t\tthr->heap->catcher_free = cat->parent;\n\t\treturn cat;\n\t}\n\n\treturn duk__hthread_catcher_alloc_slow(thr);\n}\n#else  /* DUK_USE_CACHE_CATCHER */\nDUK_INTERNAL duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr) {\n\treturn duk__hthread_catcher_alloc_slow(thr);\n}\n#endif  /* DUK_USE_CACHE_CATCHER */\n\nDUK_INTERNAL void duk_hthread_catcher_free(duk_hthread *thr, duk_catcher *cat) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(cat != NULL);\n\n#if defined(DUK_USE_CACHE_CATCHER)\n\t/* Unconditional caching for now; freed in mark-and-sweep. */\n\tcat->parent = thr->heap->catcher_free;\n\tthr->heap->catcher_free = cat;\n#else\n\tDUK_FREE_CHECKED(thr, (void *) cat);\n#endif\n}\n\nDUK_LOCAL\n#if defined(DUK_USE_CACHE_ACTIVATION)\nDUK_NOINLINE\n#endif\nduk_activation *duk__hthread_activation_alloc_slow(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tact = (duk_activation *) DUK_ALLOC_CHECKED(thr, sizeof(duk_activation));\n\tDUK_ASSERT(act != NULL);\n\treturn act;\n}\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\nDUK_INTERNAL DUK_INLINE duk_activation *duk_hthread_activation_alloc(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tact = thr->heap->activation_free;\n\tif (DUK_LIKELY(act != NULL)) {\n\t\tthr->heap->activation_free = act->parent;\n\t\treturn act;\n\t}\n\n\treturn duk__hthread_activation_alloc_slow(thr);\n}\n#else  /* DUK_USE_CACHE_ACTIVATION */\nDUK_INTERNAL duk_activation *duk_hthread_activation_alloc(duk_hthread *thr) {\n\treturn duk__hthread_activation_alloc_slow(thr);\n}\n#endif  /* DUK_USE_CACHE_ACTIVATION */\n\n\nDUK_INTERNAL void duk_hthread_activation_free(duk_hthread *thr, duk_activation *act) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\t/* Unconditional caching for now; freed in mark-and-sweep. */\n\tact->parent = thr->heap->activation_free;\n\tthr->heap->activation_free = act;\n#else\n\tDUK_FREE_CHECKED(thr, (void *) act);\n#endif\n}\n\n/* Internal helper: process the unwind for the topmost activation of a thread,\n * but leave the duk_activation in place for possible tailcall reuse.\n */\nDUK_LOCAL void duk__activation_unwind_nofree_norz(duk_hthread *thr) {\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_heap *heap;\n#endif\n\tduk_activation *act;\n\tduk_hobject *func;\n\tduk_hobject *tmp;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->callstack_curr != NULL);  /* caller must check */\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\t/* With lightfuncs, act 'func' may be NULL. */\n\n\t/* With duk_activation records allocated separately, 'act' is a stable\n\t * pointer and not affected by side effects.\n\t */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t/*\n\t *  Restore 'caller' property for non-strict callee functions.\n\t */\n\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tif (func != NULL && !DUK_HOBJECT_HAS_STRICT(func)) {\n\t\tduk_tval *tv_caller;\n\t\tduk_tval tv_tmp;\n\t\tduk_hobject *h_tmp;\n\n\t\ttv_caller = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, func, DUK_STRIDX_CALLER);\n\n\t\t/* The act->prev_caller should only be set if the entry for 'caller'\n\t\t * exists (as it is only set in that case, and the property is not\n\t\t * configurable), but handle all the cases anyway.\n\t\t */\n\n\t\tif (tv_caller) {\n\t\t\tDUK_TVAL_SET_TVAL(&tv_tmp, tv_caller);\n\t\t\tif (act->prev_caller) {\n\t\t\t\t/* Just transfer the refcount from act->prev_caller to tv_caller,\n\t\t\t\t * so no need for a refcount update.  This is the expected case.\n\t\t\t\t */\n\t\t\t\tDUK_TVAL_SET_OBJECT(tv_caller, act->prev_caller);\n\t\t\t\tact->prev_caller = NULL;\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_NULL(tv_caller);   /* no incref needed */\n\t\t\t\tDUK_ASSERT(act->prev_caller == NULL);\n\t\t\t}\n\t\t\tDUK_TVAL_DECREF_NORZ(thr, &tv_tmp);\n\t\t} else {\n\t\t\th_tmp = act->prev_caller;\n\t\t\tif (h_tmp) {\n\t\t\t\tact->prev_caller = NULL;\n\t\t\t\tDUK_HOBJECT_DECREF_NORZ(thr, h_tmp);\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(act->prev_caller == NULL);\n\t}\n#endif\n\n\t/*\n\t *  Unwind debugger state.  If we unwind while stepping\n\t *  (for any step type), pause execution.  This is the\n\t *  only place explicitly handling a step out.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\theap = thr->heap;\n\tif (heap->dbg_pause_act == thr->callstack_curr) {\n\t\tif (heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_EXIT) {\n\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by function exit\"));\n\t\t\tduk_debug_set_paused(heap);\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"unwound past dbg_pause_act, set to NULL\"));\n\t\t\theap->dbg_pause_act = NULL;  /* avoid stale pointers */\n\t\t}\n\t\tDUK_ASSERT(heap->dbg_pause_act == NULL);\n\t}\n#endif\n\n\t/*\n\t *  Unwind catchers.\n\t *\n\t *  Since there are no references in the catcher structure,\n\t *  unwinding is quite simple.  The only thing we need to\n\t *  look out for is popping a possible lexical environment\n\t *  established for an active catch clause.\n\t */\n\n\twhile (act->cat != NULL) {\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t}\n\n\t/*\n\t *  Close environment record(s) if they exist.\n\t *\n\t *  Only variable environments are closed.  If lex_env != var_env, it\n\t *  cannot currently contain any register bound declarations.\n\t *\n\t *  Only environments created for a NEWENV function are closed.  If an\n\t *  environment is created for e.g. an eval call, it must not be closed.\n\t */\n\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tif (func != NULL && !DUK_HOBJECT_HAS_NEWENV(func)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"skip closing environments, envs not owned by this activation\"));\n\t\tgoto skip_env_close;\n\t}\n\t/* func is NULL for lightfunc */\n\n\t/* Catch sites are required to clean up their environments\n\t * in FINALLY part before propagating, so this should\n\t * always hold here.\n\t */\n\tDUK_ASSERT(act->lex_env == act->var_env);\n\n\t/* XXX: Closing the environment record copies values from registers\n\t * into the scope object.  It's side effect free as such, but may\n\t * currently run out of memory which causes an error throw.  This is\n\t * an actual sandboxing problem for error unwinds, and needs to be\n\t * fixed e.g. by preallocating the scope property slots.\n\t */\n\tif (act->var_env != NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"closing var_env record %p -> %!O\",\n\t\t                     (void *) act->var_env, (duk_heaphdr *) act->var_env));\n\t\tduk_js_close_environment_record(thr, act->var_env);\n\t}\n\n skip_env_close:\n\n\t/*\n\t *  Update preventcount\n\t */\n\n\tif (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) {\n\t\tDUK_ASSERT(thr->callstack_preventcount >= 1);\n\t\tthr->callstack_preventcount--;\n\t}\n\n\t/*\n\t *  Reference count updates, using NORZ macros so we don't\n\t *  need to handle side effects.\n\t *\n\t *  duk_activation pointers like act->var_env are intentionally\n\t *  left as garbage and not NULLed.  Without side effects they\n\t *  can't be used when the values are dangling/garbage.\n\t */\n\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, act->var_env);\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, act->lex_env);\n\ttmp = DUK_ACT_GET_FUNC(act);\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\tDUK_UNREF(tmp);\n}\n\n/* Unwind topmost duk_activation of a thread, caller must ensure that an\n * activation exists.  The call is side effect free, except that scope\n * closure may currently throw an out-of-memory error.\n */\nDUK_INTERNAL void duk_hthread_activation_unwind_norz(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tduk__activation_unwind_nofree_norz(thr);\n\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tact = thr->callstack_curr;\n\tthr->callstack_curr = act->parent;\n\tthr->callstack_top--;\n\n\t/* Ideally we'd restore value stack reserve here to caller's value.\n\t * This doesn't work for current unwind call sites however, because\n\t * the current (unwound) value stack top may be above the reserve.\n\t * Thus value stack reserve is restored by the call sites.\n\t */\n\n\t/* XXX: inline for performance builds? */\n\tduk_hthread_activation_free(thr, act);\n\n\t/* We could clear the book-keeping variables like retval_byteoff for\n\t * the topmost activation, but don't do so now as it's not necessary.\n\t */\n}\n\nDUK_INTERNAL void duk_hthread_activation_unwind_reuse_norz(duk_hthread *thr) {\n\tduk__activation_unwind_nofree_norz(thr);\n}\n\n/* Get duk_activation for given callstack level or NULL if level is invalid\n * or deeper than the call stack.  Level -1 refers to current activation, -2\n * to its caller, etc.  Starting from Duktape 2.2 finding the activation is\n * a linked list scan which gets more expensive the deeper the lookup is.\n */\nDUK_INTERNAL duk_activation *duk_hthread_get_activation_for_level(duk_hthread *thr, duk_int_t level) {\n\tduk_activation *act;\n\n\tif (level >= 0) {\n\t\treturn NULL;\n\t}\n\tact = thr->callstack_curr;\n\tfor (;;) {\n\t\tif (act == NULL) {\n\t\t\treturn act;\n\t\t}\n\t\tif (level == -1) {\n\t\t\treturn act;\n\t\t}\n\t\tlevel++;\n\t\tact = act->parent;\n\t}\n\t/* never here */\n}\n\n#if defined(DUK_USE_FINALIZER_TORTURE)\nDUK_INTERNAL void duk_hthread_valstack_torture_realloc(duk_hthread *thr) {\n\tduk_size_t alloc_size;\n\tduk_tval *new_ptr;\n\tduk_ptrdiff_t alloc_end_off;\n\tduk_ptrdiff_t end_off;\n\tduk_ptrdiff_t bottom_off;\n\tduk_ptrdiff_t top_off;\n\n\tif (thr->valstack == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"skip valstack torture realloc, valstack is NULL\"));\n\t\treturn;\n\t}\n\n\talloc_end_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_alloc_end - (duk_uint8_t *) thr->valstack);\n\tend_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tbottom_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);\n\ttop_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack);\n\talloc_size = (duk_size_t) alloc_end_off;\n\tif (alloc_size == 0) {\n\t\tDUK_D(DUK_DPRINT(\"skip valstack torture realloc, alloc_size is zero\"));\n\t\treturn;\n\t}\n\n\t/* Use DUK_ALLOC_RAW() to avoid side effects. */\n\tnew_ptr = (duk_tval *) DUK_ALLOC_RAW(thr->heap, alloc_size);\n\tif (new_ptr != NULL) {\n\t\tduk_memcpy((void *) new_ptr, (const void *) thr->valstack, alloc_size);\n\t\tduk_memset((void *) thr->valstack, 0x55, alloc_size);\n\t\tDUK_FREE_CHECKED(thr, (void *) thr->valstack);\n\t\tthr->valstack = new_ptr;\n\t\tthr->valstack_alloc_end = (duk_tval *) ((duk_uint8_t *) new_ptr + alloc_end_off);\n\t\tthr->valstack_end = (duk_tval *) ((duk_uint8_t *) new_ptr + end_off);\n\t\tthr->valstack_bottom = (duk_tval *) ((duk_uint8_t *) new_ptr + bottom_off);\n\t\tthr->valstack_top = (duk_tval *) ((duk_uint8_t *) new_ptr + top_off);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"failed to realloc valstack for torture, ignore\"));\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_TORTURE */\n/*\n *  Shared helpers for arithmetic operations\n */\n\n/* #include duk_internal.h -> already included */\n\n/* ECMAScript modulus ('%') does not match IEEE 754 \"remainder\" operation\n * (implemented by remainder() in C99) but does seem to match ANSI C fmod().\n * Compare E5 Section 11.5.3 and \"man fmod\".\n */\nDUK_INTERNAL double duk_js_arith_mod(double d1, double d2) {\n#if defined(DUK_USE_POW_WORKAROUNDS)\n\t/* Specific fixes to common fmod() implementation issues:\n\t * - test-bug-mingw-math-issues.js\n\t */\n\tif (DUK_ISINF(d2)) {\n\t\tif (DUK_ISINF(d1)) {\n\t\t\treturn DUK_DOUBLE_NAN;\n\t\t} else {\n\t\t\treturn d1;\n\t\t}\n\t} else if (d1 == 0.0) {\n\t\t/* d1 +/-0 is returned as is (preserving sign) except when\n\t\t * d2 is zero or NaN.\n\t\t */\n\t\tif (d2 == 0.0 || DUK_ISNAN(d2)) {\n\t\t\treturn DUK_DOUBLE_NAN;\n\t\t} else {\n\t\t\treturn d1;\n\t\t}\n\t}\n#else\n\t/* Some ISO C assumptions. */\n\tDUK_ASSERT(DUK_FMOD(1.0, DUK_DOUBLE_INFINITY) == 1.0);\n\tDUK_ASSERT(DUK_FMOD(-1.0, DUK_DOUBLE_INFINITY) == -1.0);\n\tDUK_ASSERT(DUK_FMOD(1.0, -DUK_DOUBLE_INFINITY) == 1.0);\n\tDUK_ASSERT(DUK_FMOD(-1.0, -DUK_DOUBLE_INFINITY) == -1.0);\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_FMOD(0.0, 1.0) == 0.0 && DUK_SIGNBIT(DUK_FMOD(0.0, 1.0)) == 0);\n\tDUK_ASSERT(DUK_FMOD(-0.0, 1.0) == 0.0 && DUK_SIGNBIT(DUK_FMOD(-0.0, 1.0)) != 0);\n\tDUK_ASSERT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY)) == 0);\n\tDUK_ASSERT(DUK_FMOD(-0.0, DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(-0.0, DUK_DOUBLE_INFINITY)) != 0);\n\tDUK_ASSERT(DUK_FMOD(0.0, -DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY)) == 0);\n\tDUK_ASSERT(DUK_FMOD(-0.0, -DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(-0.0, -DUK_DOUBLE_INFINITY)) != 0);\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, 0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, 0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, -0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, -0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, DUK_DOUBLE_NAN)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, DUK_DOUBLE_NAN)));\n#endif\n\n\treturn (duk_double_t) DUK_FMOD((double) d1, (double) d2);\n}\n\n/* Shared helper for Math.pow() and exponentiation operator. */\nDUK_INTERNAL double duk_js_arith_pow(double x, double y) {\n\t/* The ANSI C pow() semantics differ from ECMAScript.\n\t *\n\t * E.g. when x==1 and y is +/- infinite, the ECMAScript required\n\t * result is NaN, while at least Linux pow() returns 1.\n\t */\n\n\tduk_small_int_t cx, cy, sx;\n\n\tDUK_UNREF(cx);\n\tDUK_UNREF(sx);\n\tcy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\n\tif (cy == DUK_FP_NAN) {\n\t\tgoto ret_nan;\n\t}\n\tif (DUK_FABS(x) == 1.0 && cy == DUK_FP_INFINITE) {\n\t\tgoto ret_nan;\n\t}\n\n#if defined(DUK_USE_POW_WORKAROUNDS)\n\t/* Specific fixes to common pow() implementation issues:\n\t *   - test-bug-netbsd-math-pow.js: NetBSD 6.0 on x86 (at least)\n\t *   - test-bug-mingw-math-issues.js\n\t */\n\tcx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (cx == DUK_FP_ZERO && y < 0.0) {\n\t\tsx = (duk_small_int_t) DUK_SIGNBIT(x);\n\t\tif (sx == 0) {\n\t\t\t/* Math.pow(+0,y) should be Infinity when y<0.  NetBSD pow()\n\t\t\t * returns -Infinity instead when y is <0 and finite.  The\n\t\t\t * if-clause also catches y == -Infinity (which works even\n\t\t\t * without the fix).\n\t\t\t */\n\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t} else {\n\t\t\t/* Math.pow(-0,y) where y<0 should be:\n\t\t\t *   - -Infinity if y<0 and an odd integer\n\t\t\t *   - Infinity if y<0 but not an odd integer\n\t\t\t * NetBSD pow() returns -Infinity for all finite y<0.  The\n\t\t\t * if-clause also catches y == -Infinity (which works even\n\t\t\t * without the fix).\n\t\t\t */\n\n\t\t\t/* fmod() return value has same sign as input (negative) so\n\t\t\t * the result here will be in the range ]-2,0], -1 indicates\n\t\t\t * odd.  If x is -Infinity, NaN is returned and the odd check\n\t\t\t * always concludes \"not odd\" which results in desired outcome.\n\t\t\t */\n\t\t\tdouble tmp = DUK_FMOD(y, 2);\n\t\t\tif (tmp == -1.0) {\n\t\t\t\treturn -DUK_DOUBLE_INFINITY;\n\t\t\t} else {\n\t\t\t\t/* Not odd, or y == -Infinity */\n\t\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t\t}\n\t\t}\n\t} else if (cx == DUK_FP_NAN) {\n\t\tif (y == 0.0) {\n\t\t\t/* NaN ** +/- 0 should always be 1, but is NaN on\n\t\t\t * at least some Cygwin/MinGW versions.\n\t\t\t */\n\t\t\treturn 1.0;\n\t\t}\n\t}\n#else\n\t/* Some ISO C assumptions. */\n\tDUK_ASSERT(DUK_POW(DUK_DOUBLE_NAN, 0.0) == 1.0);\n\tDUK_ASSERT(DUK_ISINF(DUK_POW(0.0, -1.0)) && DUK_SIGNBIT(DUK_POW(0.0, -1.0)) == 0);\n\tDUK_ASSERT(DUK_ISINF(DUK_POW(-0.0, -2.0)) && DUK_SIGNBIT(DUK_POW(-0.0, -2.0)) == 0);\n\tDUK_ASSERT(DUK_ISINF(DUK_POW(-0.0, -3.0)) && DUK_SIGNBIT(DUK_POW(-0.0, -3.0)) != 0);\n#endif\n\n\treturn DUK_POW(x, y);\n\n ret_nan:\n\treturn DUK_DOUBLE_NAN;\n}\n/*\n *  Call handling.\n *\n *  duk_handle_call_unprotected():\n *\n *    - Unprotected call to ECMAScript or Duktape/C function, from native\n *      code or bytecode executor.\n *\n *    - Also handles Ecma-to-Ecma calls which reuses a currently running\n *      executor instance to avoid native recursion.  Call setup is done\n *      normally, but just before calling the bytecode executor a special\n *      return code is used to indicate that a calling executor is reused.\n *\n *    - Also handles tailcalls, i.e. reuse of current duk_activation.\n *\n *    - Also handles setup for initial Duktape.Thread.resume().\n *\n *  duk_handle_safe_call():\n *\n *    - Protected C call within current activation.\n *\n *  setjmp() and local variables have a nasty interaction, see execution.rst;\n *  non-volatile locals modified after setjmp() call are not guaranteed to\n *  keep their value and can cause compiler or compiler version specific\n *  difficult to replicate issues.\n *\n *  See 'execution.rst'.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* XXX: heap->error_not_allowed for success path too? */\n\n/*\n *  Limit check helpers.\n */\n\n/* Check native stack space if DUK_USE_NATIVE_STACK_CHECK() defined. */\nDUK_INTERNAL void duk_native_stack_check(duk_hthread *thr) {\n#if defined(DUK_USE_NATIVE_STACK_CHECK)\n\tif (DUK_USE_NATIVE_STACK_CHECK() != 0) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_NATIVE_STACK_LIMIT);\n\t}\n#else\n\tDUK_UNREF(thr);\n#endif\n}\n\n/* Allow headroom for calls during error augmentation (see GH-191).\n * We allow space for 10 additional recursions, with one extra\n * for, e.g. a print() call at the deepest level, and an extra\n * +1 for protected call wrapping.\n */\n#define DUK__AUGMENT_CALL_RELAX_COUNT  (10 + 2)\n\n/* Stack space required by call handling entry. */\n#define DUK__CALL_HANDLING_REQUIRE_STACK  8\n\nDUK_LOCAL DUK_NOINLINE void duk__call_c_recursion_limit_check_slowpath(duk_hthread *thr) {\n\t/* When augmenting an error, the effective limit is a bit higher.\n\t * Check for it only if the fast path check fails.\n\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tif (thr->heap->augmenting_error) {\n\t\tif (thr->heap->call_recursion_depth < thr->heap->call_recursion_limit + DUK__AUGMENT_CALL_RELAX_COUNT) {\n\t\t\tDUK_D(DUK_DPRINT(\"C recursion limit reached but augmenting error and within relaxed limit\"));\n\t\t\treturn;\n\t\t}\n\t}\n#endif\n\n\tDUK_D(DUK_DPRINT(\"call prevented because C recursion limit reached\"));\n\tDUK_ERROR_RANGE(thr, DUK_STR_NATIVE_STACK_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__call_c_recursion_limit_check(duk_hthread *thr) {\n\tDUK_ASSERT(thr->heap->call_recursion_depth >= 0);\n\tDUK_ASSERT(thr->heap->call_recursion_depth <= thr->heap->call_recursion_limit);\n\n\tduk_native_stack_check(thr);\n\n\t/* This check is forcibly inlined because it's very cheap and almost\n\t * always passes.  The slow path is forcibly noinline.\n\t */\n\tif (DUK_LIKELY(thr->heap->call_recursion_depth < thr->heap->call_recursion_limit)) {\n\t\treturn;\n\t}\n\n\tduk__call_c_recursion_limit_check_slowpath(thr);\n}\n\nDUK_LOCAL DUK_NOINLINE void duk__call_callstack_limit_check_slowpath(duk_hthread *thr) {\n\t/* When augmenting an error, the effective limit is a bit higher.\n\t * Check for it only if the fast path check fails.\n\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tif (thr->heap->augmenting_error) {\n\t\tif (thr->callstack_top < DUK_USE_CALLSTACK_LIMIT + DUK__AUGMENT_CALL_RELAX_COUNT) {\n\t\t\tDUK_D(DUK_DPRINT(\"call stack limit reached but augmenting error and within relaxed limit\"));\n\t\t\treturn;\n\t\t}\n\t}\n#endif\n\n\t/* XXX: error message is a bit misleading: we reached a recursion\n\t * limit which is also essentially the same as a C callstack limit\n\t * (except perhaps with some relaxed threading assumptions).\n\t */\n\tDUK_D(DUK_DPRINT(\"call prevented because call stack limit reached\"));\n\tDUK_ERROR_RANGE(thr, DUK_STR_CALLSTACK_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__call_callstack_limit_check(duk_hthread *thr) {\n\t/* This check is forcibly inlined because it's very cheap and almost\n\t * always passes.  The slow path is forcibly noinline.\n\t */\n\tif (DUK_LIKELY(thr->callstack_top < DUK_USE_CALLSTACK_LIMIT)) {\n\t\treturn;\n\t}\n\n\tduk__call_callstack_limit_check_slowpath(thr);\n}\n\n/*\n *  Interrupt counter fixup (for development only).\n */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__interrupt_fixup(duk_hthread *thr, duk_hthread *entry_curr_thread) {\n\t/* Currently the bytecode executor and executor interrupt\n\t * instruction counts are off because we don't execute the\n\t * interrupt handler when we're about to exit from the initial\n\t * user call into Duktape.\n\t *\n\t * If we were to execute the interrupt handler here, the counts\n\t * would match.  You can enable this block manually to check\n\t * that this is the case.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n#if defined(DUK_USE_INTERRUPT_DEBUG_FIXUP)\n\tif (entry_curr_thread == NULL) {\n\t\tthr->interrupt_init = thr->interrupt_init - thr->interrupt_counter;\n\t\tthr->heap->inst_count_interrupt += thr->interrupt_init;\n\t\tDUK_DD(DUK_DDPRINT(\"debug test: updated interrupt count on exit to \"\n\t\t                   \"user code, instruction counts: executor=%ld, interrupt=%ld\",\n\t\t                   (long) thr->heap->inst_count_exec, (long) thr->heap->inst_count_interrupt));\n\t\tDUK_ASSERT(thr->heap->inst_count_exec == thr->heap->inst_count_interrupt);\n\t}\n#else\n\tDUK_UNREF(thr);\n\tDUK_UNREF(entry_curr_thread);\n#endif\n}\n#endif\n\n/*\n *  Arguments object creation.\n *\n *  Creating arguments objects involves many small details, see E5 Section\n *  10.6 for the specific requirements.  Much of the arguments object exotic\n *  behavior is implemented in duk_hobject_props.c, and is enabled by the\n *  object flag DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS.\n */\n\nDUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,\n                                            duk_hobject *func,\n                                            duk_hobject *varenv,\n                                            duk_idx_t idx_args) {\n\tduk_hobject *arg;          /* 'arguments' */\n\tduk_hobject *formals;      /* formals for 'func' (may be NULL if func is a C function) */\n\tduk_idx_t i_arg;\n\tduk_idx_t i_map;\n\tduk_idx_t i_mappednames;\n\tduk_idx_t i_formals;\n\tduk_idx_t i_argbase;\n\tduk_idx_t n_formals;\n\tduk_idx_t idx;\n\tduk_idx_t num_stack_args;\n\tduk_bool_t need_map;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_NONBOUND_FUNCTION(func));\n\tDUK_ASSERT(varenv != NULL);\n\n\t/* [ ... func this arg1(@idx_args) ... argN envobj ]\n\t * [ arg1(@idx_args) ... argN envobj ] (for tailcalls)\n\t */\n\n\tneed_map = 0;\n\n\ti_argbase = idx_args;\n\tnum_stack_args = duk_get_top(thr) - i_argbase - 1;\n\tDUK_ASSERT(i_argbase >= 0);\n\tDUK_ASSERT(num_stack_args >= 0);\n\n\tformals = (duk_hobject *) duk_hobject_get_formals(thr, (duk_hobject *) func);\n\tif (formals) {\n\t\tn_formals = (duk_idx_t) ((duk_harray *) formals)->length;\n\t\tduk_push_hobject(thr, formals);\n\t} else {\n\t\t/* This shouldn't happen without tampering of internal\n\t\t * properties: if a function accesses 'arguments', _Formals\n\t\t * is kept.  Check for the case anyway in case internal\n\t\t * properties have been modified manually.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"_Formals is undefined when creating arguments, use n_formals == 0\"));\n\t\tn_formals = 0;\n\t\tduk_push_undefined(thr);\n\t}\n\ti_formals = duk_require_top_index(thr);\n\n\tDUK_ASSERT(n_formals >= 0);\n\tDUK_ASSERT(formals != NULL || n_formals == 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"func=%!O, formals=%!O, n_formals=%ld\",\n\t                     (duk_heaphdr *) func, (duk_heaphdr *) formals,\n\t                     (long) n_formals));\n\n\t/* [ ... formals ] */\n\n\t/*\n\t *  Create required objects:\n\t *    - 'arguments' object: array-like, but not an array\n\t *    - 'map' object: internal object, tied to 'arguments' (bare)\n\t *    - 'mappedNames' object: temporary value used during construction (bare)\n\t */\n\n\targ = duk_push_object_helper(thr,\n\t                             DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                             DUK_HOBJECT_FLAG_FASTREFS |\n\t                             DUK_HOBJECT_FLAG_ARRAY_PART |\n\t                             DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARGUMENTS),\n\t                             DUK_BIDX_OBJECT_PROTOTYPE);\n\tDUK_ASSERT(arg != NULL);\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              -1);  /* no prototype */\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              -1);  /* no prototype */\n\ti_arg = duk_get_top(thr) - 3;\n\ti_map = i_arg + 1;\n\ti_mappednames = i_arg + 2;\n\tDUK_ASSERT(!duk_is_bare_object(thr, -3));  /* arguments */\n\tDUK_ASSERT(duk_is_bare_object(thr, -2));  /* map */\n\tDUK_ASSERT(duk_is_bare_object(thr, -1));  /* mappedNames */\n\n\t/* [ ... formals arguments map mappedNames ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"created arguments related objects: \"\n\t                     \"arguments at index %ld -> %!O \"\n\t                     \"map at index %ld -> %!O \"\n\t                     \"mappednames at index %ld -> %!O\",\n\t                     (long) i_arg, (duk_heaphdr *) duk_get_hobject(thr, i_arg),\n\t                     (long) i_map, (duk_heaphdr *) duk_get_hobject(thr, i_map),\n\t                     (long) i_mappednames, (duk_heaphdr *) duk_get_hobject(thr, i_mappednames)));\n\n\t/*\n\t *  Init arguments properties, map, etc.\n\t */\n\n\tduk_push_int(thr, num_stack_args);\n\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_WC);\n\n\t/*\n\t *  Init argument related properties.\n\t */\n\n\t/* step 11 */\n\tidx = num_stack_args - 1;\n\twhile (idx >= 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arg idx %ld, argbase=%ld, argidx=%ld\",\n\t\t                     (long) idx, (long) i_argbase, (long) (i_argbase + idx)));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"define arguments[%ld]=arg\", (long) idx));\n\t\tduk_dup(thr, i_argbase + idx);\n\t\tduk_xdef_prop_index_wec(thr, i_arg, (duk_uarridx_t) idx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"defined arguments[%ld]=arg\", (long) idx));\n\n\t\t/* step 11.c is relevant only if non-strict (checked in 11.c.ii) */\n\t\tif (!DUK_HOBJECT_HAS_STRICT(func) && idx < n_formals) {\n\t\t\tDUK_ASSERT(formals != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"strict function, index within formals (%ld < %ld)\",\n\t\t\t                     (long) idx, (long) n_formals));\n\n\t\t\tduk_get_prop_index(thr, i_formals, (duk_uarridx_t) idx);\n\t\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\n\t\t\tduk_dup_top(thr);  /* [ ... name name ] */\n\n\t\t\tif (!duk_has_prop(thr, i_mappednames)) {\n\t\t\t\t/* steps 11.c.ii.1 - 11.c.ii.4, but our internal book-keeping\n\t\t\t\t * differs from the reference model\n\t\t\t\t */\n\n\t\t\t\t/* [ ... name ] */\n\n\t\t\t\tneed_map = 1;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"set mappednames[%s]=%ld\",\n\t\t\t\t                     (const char *) duk_get_string(thr, -1),\n\t\t\t\t                     (long) idx));\n\t\t\t\tduk_dup_top(thr);                      /* name */\n\t\t\t\t(void) duk_push_uint_to_hstring(thr, (duk_uint_t) idx);  /* index */\n\t\t\t\tduk_xdef_prop_wec(thr, i_mappednames);  /* out of spec, must be configurable */\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"set map[%ld]=%s\",\n\t\t\t\t                     (long) idx,\n\t\t\t\t                     duk_get_string(thr, -1)));\n\t\t\t\tduk_dup_top(thr);         /* name */\n\t\t\t\tduk_xdef_prop_index_wec(thr, i_map, (duk_uarridx_t) idx);  /* out of spec, must be configurable */\n\t\t\t} else {\n\t\t\t\t/* duk_has_prop() popped the second 'name' */\n\t\t\t}\n\n\t\t\t/* [ ... name ] */\n\t\t\tduk_pop(thr);  /* pop 'name' */\n\t\t}\n\n\t\tidx--;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"actual arguments processed\"));\n\n\t/* step 12 */\n\tif (need_map) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"adding 'map' and 'varenv' to arguments object\"));\n\n\t\t/* should never happen for a strict callee */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(func));\n\n\t\tduk_dup(thr, i_map);\n\t\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_INT_MAP, DUK_PROPDESC_FLAGS_NONE);  /* out of spec, don't care */\n\n\t\t/* The variable environment for magic variable bindings needs to be\n\t\t * given by the caller and recorded in the arguments object.\n\t\t *\n\t\t * See E5 Section 10.6, the creation of setters/getters.\n\t\t *\n\t\t * The variable environment also provides access to the callee, so\n\t\t * an explicit (internal) callee property is not needed.\n\t\t */\n\n\t\tduk_push_hobject(thr, varenv);\n\t\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_INT_VARENV, DUK_PROPDESC_FLAGS_NONE);  /* out of spec, don't care */\n\t}\n\n\t/* steps 13-14 */\n\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t/* Callee/caller are throwers and are not deletable etc.  They\n\t\t * could be implemented as virtual properties, but currently\n\t\t * there is no support for virtual properties which are accessors\n\t\t * (only plain virtual properties).  This would not be difficult\n\t\t * to change in duk_hobject_props, but we can make the throwers\n\t\t * normal, concrete properties just as easily.\n\t\t *\n\t\t * Note that the specification requires that the *same* thrower\n\t\t * built-in object is used here!  See E5 Section 10.6 main\n\t\t * algoritm, step 14, and Section 13.2.3 which describes the\n\t\t * thrower.  See test case test-arguments-throwers.js.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"strict function, setting caller/callee to throwers\"));\n\n\t\t/* In ES2017 .caller is no longer set at all. */\n\t\tduk_xdef_prop_stridx_thrower(thr, i_arg, DUK_STRIDX_CALLEE);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-strict function, setting callee to actual value\"));\n\t\tduk_push_hobject(thr, func);\n\t\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_CALLEE, DUK_PROPDESC_FLAGS_WC);\n\t}\n\n\t/* set exotic behavior only after we're done */\n\tif (need_map) {\n\t\t/* Exotic behaviors are only enabled for arguments objects\n\t\t * which have a parameter map (see E5 Section 10.6 main\n\t\t * algorithm, step 12).\n\t\t *\n\t\t * In particular, a non-strict arguments object with no\n\t\t * mapped formals does *NOT* get exotic behavior, even\n\t\t * for e.g. \"caller\" property.  This seems counterintuitive\n\t\t * but seems to be the case.\n\t\t */\n\n\t\t/* cannot be strict (never mapped variables) */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(func));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"enabling exotic behavior for arguments object\"));\n\t\tDUK_HOBJECT_SET_EXOTIC_ARGUMENTS(arg);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"not enabling exotic behavior for arguments object\"));\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"final arguments related objects: \"\n\t                     \"arguments at index %ld -> %!O \"\n\t                     \"map at index %ld -> %!O \"\n\t                     \"mappednames at index %ld -> %!O\",\n\t                     (long) i_arg, (duk_heaphdr *) duk_get_hobject(thr, i_arg),\n\t                     (long) i_map, (duk_heaphdr *) duk_get_hobject(thr, i_map),\n\t                     (long) i_mappednames, (duk_heaphdr *) duk_get_hobject(thr, i_mappednames)));\n\n\t/* [ args(n) envobj formals arguments map mappednames ] */\n\n\tduk_pop_2(thr);\n\tduk_remove_m2(thr);\n\n\t/* [ args(n) envobj arguments ] */\n}\n\n/* Helper for creating the arguments object and adding it to the env record\n * on top of the value stack.\n */\nDUK_LOCAL void duk__handle_createargs_for_call(duk_hthread *thr,\n                                               duk_hobject *func,\n                                               duk_hobject *env,\n                                               duk_idx_t idx_args) {\n\tDUK_DDD(DUK_DDDPRINT(\"creating arguments object for function call\"));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_CREATEARGS(func));\n\n\t/* [ ... arg1 ... argN envobj ] */\n\n\tduk__create_arguments_object(thr,\n\t                             func,\n\t                             env,\n\t                             idx_args);\n\n\t/* [ ... arg1 ... argN envobj argobj ] */\n\n\tduk_xdef_prop_stridx_short(thr,\n\t                           -2,\n\t                           DUK_STRIDX_LC_ARGUMENTS,\n\t                           DUK_HOBJECT_HAS_STRICT(func) ? DUK_PROPDESC_FLAGS_E :   /* strict: non-deletable, non-writable */\n\t                                                          DUK_PROPDESC_FLAGS_WE);  /* non-strict: non-deletable, writable */\n\t/* [ ... arg1 ... argN envobj ] */\n}\n\n/*\n *  Helpers for constructor call handling.\n *\n *  There are two [[Construct]] operations in the specification:\n *\n *    - E5 Section 13.2.2: for Function objects\n *    - E5 Section 15.3.4.5.2: for \"bound\" Function objects\n *\n *  The chain of bound functions is resolved in Section 15.3.4.5.2,\n *  with arguments \"piling up\" until the [[Construct]] internal\n *  method is called on the final, actual Function object.  Note\n *  that the \"prototype\" property is looked up *only* from the\n *  final object, *before* calling the constructor.\n *\n *  Since Duktape 2.2 bound functions are represented with the\n *  duk_hboundfunc internal type, and bound function chains are\n *  collapsed when a bound function is created.  As a result, the\n *  direct target of a duk_hboundfunc is always non-bound and the\n *  this/argument lists have been resolved.\n *\n *  When constructing new Array instances, an unnecessary object is\n *  created and discarded now: the standard [[Construct]] creates an\n *  object, and calls the Array constructor.  The Array constructor\n *  returns an Array instance, which is used as the result value for\n *  the \"new\" operation; the object created before the Array constructor\n *  call is discarded.\n *\n *  This would be easy to fix, e.g. by knowing that the Array constructor\n *  will always create a replacement object and skip creating the fallback\n *  object in that case.\n */\n\n/* Update default instance prototype for constructor call. */\nDUK_LOCAL void duk__update_default_instance_proto(duk_hthread *thr, duk_idx_t idx_func) {\n\tduk_hobject *proto;\n\tduk_hobject *fallback;\n\n\tDUK_ASSERT(duk_is_constructable(thr, idx_func));\n\n\tduk_get_prop_stridx_short(thr, idx_func, DUK_STRIDX_PROTOTYPE);\n\tproto = duk_get_hobject(thr, -1);\n\tif (proto == NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"constructor has no 'prototype' property, or value not an object \"\n\t\t                     \"-> leave standard Object prototype as fallback prototype\"));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"constructor has 'prototype' property with object value \"\n\t\t                     \"-> set fallback prototype to that value: %!iO\", (duk_heaphdr *) proto));\n\t\t/* Original fallback (default instance) is untouched when\n\t\t * resolving bound functions etc.\n\t\t */\n\t\tfallback = duk_known_hobject(thr, idx_func + 1);\n\t\tDUK_ASSERT(fallback != NULL);\n\t\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, fallback, proto);\n\t}\n\tduk_pop(thr);\n}\n\n/* Postprocess: return value special handling, error augmentation. */\nDUK_INTERNAL void duk_call_construct_postprocess(duk_hthread *thr, duk_small_uint_t proxy_invariant) {\n\t/* Use either fallback (default instance) or retval depending\n\t * on retval type.  Needs to be called before unwind because\n\t * the default instance is read from the current (immutable)\n\t * 'this' binding.\n\t *\n\t * For Proxy 'construct' calls the return value must be an\n\t * Object (we accept object-like values like buffers and\n\t * lightfuncs too).  If not, TypeError.\n\t */\n\tif (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT |\n\t                                 DUK_TYPE_MASK_BUFFER |\n\t                                 DUK_TYPE_MASK_LIGHTFUNC)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"replacement value\"));\n\t} else {\n\t\tif (DUK_UNLIKELY(proxy_invariant != 0U)) {\n\t\t\t/* Proxy 'construct' return value invariant violated. */\n\t\t\tDUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\t/* XXX: direct value stack access */\n\t\tduk_pop(thr);\n\t\tduk_push_this(thr);\n\t}\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\t/* Augment created errors upon creation, not when they are thrown or\n\t * rethrown.  __FILE__ and __LINE__ are not desirable here; the call\n\t * stack reflects the caller which is correct.  Skip topmost, unwound\n\t * activation when creating a traceback.  If thr->ptr_curr_pc was !=\n\t * NULL we'd need to sync the current PC so that the traceback comes\n\t * out right; however it is always synced here so just assert for it.\n\t */\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\tduk_err_augment_error_create(thr, thr, NULL, 0, DUK_AUGMENT_FLAG_NOBLAME_FILELINE |\n\t                                                DUK_AUGMENT_FLAG_SKIP_ONE);\n#endif\n}\n\n/*\n *  Helper for handling a bound function when a call is being made.\n *\n *  Assumes that bound function chains have been \"collapsed\" so that either\n *  the target is non-bound or there is one bound function that points to a\n *  nonbound target.\n *\n *  Prepends the bound arguments to the value stack (at idx_func + 2).\n *  The 'this' binding is also updated if necessary (at idx_func + 1).\n *  Note that for constructor calls the 'this' binding is never updated by\n *  [[BoundThis]].\n */\n\nDUK_LOCAL void duk__handle_bound_chain_for_call(duk_hthread *thr,\n                                                duk_idx_t idx_func,\n                                                duk_bool_t is_constructor_call) {\n\tduk_tval *tv_func;\n\tduk_hobject *func;\n\tduk_idx_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* On entry, item at idx_func is a bound, non-lightweight function,\n\t * but we don't rely on that below.\n\t */\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\ttv_func = duk_require_tval(thr, idx_func);\n\tDUK_ASSERT(tv_func != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\n\t\t/* XXX: separate helper function, out of fast path? */\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {\n\t\t\tduk_hboundfunc *h_bound;\n\t\t\tduk_tval *tv_args;\n\t\t\tduk_tval *tv_gap;\n\n\t\t\th_bound = (duk_hboundfunc *) (void *) func;\n\t\t\ttv_args = h_bound->args;\n\t\t\tlen = h_bound->nargs;\n\t\t\tDUK_ASSERT(len == 0 || tv_args != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"bound function encountered, ptr=%p: %!T\",\n\t\t\t                     (void *) DUK_TVAL_GET_OBJECT(tv_func), tv_func));\n\n\t\t\t/* [ ... func this arg1 ... argN ] */\n\n\t\t\tif (is_constructor_call) {\n\t\t\t\t/* See: tests/ecmascript/test-spec-bound-constructor.js */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"constructor call: don't update this binding\"));\n\t\t\t} else {\n\t\t\t\t/* XXX: duk_replace_tval */\n\t\t\t\tduk_push_tval(thr, &h_bound->this_binding);\n\t\t\t\tduk_replace(thr, idx_func + 1);  /* idx_this = idx_func + 1 */\n\t\t\t}\n\n\t\t\t/* [ ... func this arg1 ... argN ] */\n\n\t\t\tduk_require_stack(thr, len);\n\n\t\t\ttv_gap = duk_reserve_gap(thr, idx_func + 2, len);\n\t\t\tduk_copy_tvals_incref(thr, tv_gap, tv_args, (duk_size_t) len);\n\n\t\t\t/* [ ... func this <bound args> arg1 ... argN ] */\n\n\t\t\tduk_push_tval(thr, &h_bound->target);\n\t\t\tduk_replace(thr, idx_func);  /* replace in stack */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"bound function handled, idx_func=%ld, curr func=%!T\",\n\t\t\t                     (long) idx_func, duk_get_tval(thr, idx_func)));\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {\n\t\t/* Lightweight function: never bound, so terminate. */\n\t\t;\n\t} else {\n\t\t/* Shouldn't happen, so ugly error is enough. */\n\t\tDUK_ERROR_INTERNAL(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\tDUK_DDD(DUK_DDDPRINT(\"final non-bound function is: %!T\", duk_get_tval(thr, idx_func)));\n\n#if defined(DUK_USE_ASSERTIONS)\n\ttv_func = duk_require_tval(thr, idx_func);\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func) || DUK_TVAL_IS_OBJECT(tv_func));\n\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func) ||\n\t\t           DUK_HOBJECT_HAS_NATFUNC(func) ||\n\t\t           DUK_HOBJECT_IS_PROXY(func));\n\t}\n#endif\n}\n\n/*\n *  Helper for inline handling of .call(), .apply(), and .construct().\n */\n\nDUK_LOCAL duk_bool_t duk__handle_specialfuncs_for_call(duk_hthread *thr, duk_idx_t idx_func, duk_hobject *func, duk_small_uint_t *call_flags, duk_bool_t first) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_c_function natfunc;\n#endif\n\tduk_tval *tv_args;\n\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT((*call_flags & DUK_CALL_FLAG_CONSTRUCT) == 0);  /* Caller. */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tnatfunc = ((duk_hnatfunc *) func)->func;\n\tDUK_ASSERT(natfunc != NULL);\n#endif\n\n\t/* On every round of function resolution at least target function and\n\t * 'this' binding are set.  We can assume that here, and must guarantee\n\t * it on exit.  Value stack reserve is extended for bound function and\n\t * .apply() unpacking so we don't need to extend it here when we need a\n\t * few slots.\n\t */\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\t/* Handle native 'eval' specially.  A direct eval check is only made\n\t * for the first resolution attempt; e.g. a bound eval call is -not-\n\t * a direct eval call.\n\t */\n\tif (DUK_UNLIKELY(((duk_hnatfunc *) func)->magic == 15)) {\n\t\t/* For now no special handling except for direct eval\n\t\t * detection.\n\t\t */\n\t\tDUK_ASSERT(((duk_hnatfunc *) func)->func == duk_bi_global_object_eval);\n\t\tif (first && (*call_flags & DUK_CALL_FLAG_CALLED_AS_EVAL)) {\n\t\t\t*call_flags = (*call_flags & ~DUK_CALL_FLAG_CALLED_AS_EVAL) | DUK_CALL_FLAG_DIRECT_EVAL;\n\t\t}\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\t\treturn 1;  /* stop resolving */\n\t}\n\n\t/* Handle special functions based on the DUK_HOBJECT_FLAG_SPECIAL_CALL\n\t * flag; their magic value is used for switch-case.\n\t *\n\t * NOTE: duk_unpack_array_like() reserves value stack space\n\t * for the result values (unlike most other value stack calls).\n\t */\n\tswitch (((duk_hnatfunc *) func)->magic) {\n\tcase 0: {  /* 0=Function.prototype.call() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Function.prototype.call()  [removed]\n\t\t * idx_func + 1: this binding for .call (target function)\n\t\t * idx_func + 2: 1st argument to .call, desired 'this' binding\n\t\t * idx_func + 3: 2nd argument to .call, desired 1st argument for ultimate target\n\t\t * ...\n\t\t *\n\t\t * Remove idx_func + 0 to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding\n\t\t * idx_func + 2: call arguments\n\t\t * ...\n\t\t */\n\t\tDUK_ASSERT(natfunc == duk_bi_function_prototype_call);\n\t\tduk_remove_unsafe(thr, idx_func);\n\t\ttv_args = thr->valstack_bottom + idx_func + 2;\n\t\tif (thr->valstack_top < tv_args) {\n\t\t\tDUK_ASSERT(tv_args <= thr->valstack_end);\n\t\t\tthr->valstack_top = tv_args;  /* at least target function and 'this' binding present */\n\t\t}\n\t\tbreak;\n\t}\n\tcase 1: {  /* 1=Function.prototype.apply() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Function.prototype.apply()  [removed]\n\t\t * idx_func + 1: this binding for .apply (target function)\n\t\t * idx_func + 2: 1st argument to .apply, desired 'this' binding\n\t\t * idx_func + 3: 2nd argument to .apply, argArray\n\t\t * [anything after this MUST be ignored]\n\t\t *\n\t\t * Remove idx_func + 0 and unpack the argArray to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding\n\t\t * idx_func + 2: call arguments\n\t\t * ...\n\t\t */\n\t\tDUK_ASSERT(natfunc == duk_bi_function_prototype_apply);\n\t\tduk_remove_unsafe(thr, idx_func);\n\t\tgoto apply_shared;\n\t}\n#if defined(DUK_USE_REFLECT_BUILTIN)\n\tcase 2: {  /* 2=Reflect.apply() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Reflect.apply()  [removed]\n\t\t * idx_func + 1: this binding for .apply (ignored, usually Reflect)  [removed]\n\t\t * idx_func + 2: 1st argument to .apply, target function\n\t\t * idx_func + 3: 2nd argument to .apply, desired 'this' binding\n\t\t * idx_func + 4: 3rd argument to .apply, argArray\n\t\t * [anything after this MUST be ignored]\n\t\t *\n\t\t * Remove idx_func + 0 and idx_func + 1, and unpack the argArray to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding\n\t\t * idx_func + 2: call arguments\n\t\t * ...\n\t\t */\n\t\tDUK_ASSERT(natfunc == duk_bi_reflect_apply);\n\t\tduk_remove_n_unsafe(thr, idx_func, 2);\n\t\tgoto apply_shared;\n\t}\n\tcase 3: {  /* 3=Reflect.construct() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Reflect.construct()  [removed]\n\t\t * idx_func + 1: this binding for .construct (ignored, usually Reflect)  [removed]\n\t\t * idx_func + 2: 1st argument to .construct, target function\n\t\t * idx_func + 3: 2nd argument to .construct, argArray\n\t\t * idx_func + 4: 3rd argument to .construct, newTarget\n\t\t * [anything after this MUST be ignored]\n\t\t *\n\t\t * Remove idx_func + 0 and idx_func + 1, unpack the argArray,\n\t\t * and insert default instance (prototype not yet updated), to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding (default instance)\n\t\t * idx_func + 2: constructor call arguments\n\t\t * ...\n\t\t *\n\t\t * Call flags must be updated to reflect the fact that we're\n\t\t * now dealing with a constructor call, and e.g. the 'this'\n\t\t * binding cannot be overwritten if the target is bound.\n\t\t *\n\t\t * newTarget is checked but not yet passed onwards.\n\t\t */\n\n\t\tduk_idx_t top;\n\n\t\tDUK_ASSERT(natfunc == duk_bi_reflect_construct);\n\t\t*call_flags |= DUK_CALL_FLAG_CONSTRUCT;\n\t\tduk_remove_n_unsafe(thr, idx_func, 2);\n\t\ttop = duk_get_top(thr);\n\t\tif (!duk_is_constructable(thr, idx_func)) {\n\t\t\t/* Target constructability must be checked before\n\t\t\t * unpacking argArray (which may cause side effects).\n\t\t\t * Just return; caller will throw the error.\n\t\t\t */\n\t\t\tduk_set_top_unsafe(thr, idx_func + 2);  /* satisfy asserts */\n\t\t\tbreak;\n\t\t}\n\t\tduk_push_object(thr);\n\t\tduk_insert(thr, idx_func + 1);  /* default instance */\n\n\t\t/* [ ... func default_instance argArray newTarget? ] */\n\n\t\ttop = duk_get_top(thr);\n\t\tif (top < idx_func + 3) {\n\t\t\t/* argArray is a mandatory argument for Reflect.construct(). */\n\t\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tif (top > idx_func + 3) {\n\t\t\tif (!duk_strict_equals(thr, idx_func, idx_func + 3)) {\n\t\t\t\t/* XXX: [[Construct]] newTarget currently unsupported */\n\t\t\t\tDUK_ERROR_UNSUPPORTED(thr);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t\tduk_set_top_unsafe(thr, idx_func + 3);  /* remove any args beyond argArray */\n\t\t}\n\t\tDUK_ASSERT(duk_get_top(thr) == idx_func + 3);\n\t\tDUK_ASSERT(duk_is_valid_index(thr, idx_func + 2));\n\t\t(void) duk_unpack_array_like(thr, idx_func + 2);  /* XXX: should also remove target to be symmetric with duk_pack()? */\n\t\tduk_remove(thr, idx_func + 2);\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\t\tbreak;\n\t}\n#endif  /* DUK_USE_REFLECT_BUILTIN */\n\tdefault: {\n\t\tDUK_ASSERT(0);\n\t\tDUK_UNREACHABLE();\n\t}\n\t}\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\treturn 0;  /* keep resolving */\n\n apply_shared:\n\ttv_args = thr->valstack_bottom + idx_func + 2;\n\tif (thr->valstack_top <= tv_args) {\n\t\tDUK_ASSERT(tv_args <= thr->valstack_end);\n\t\tthr->valstack_top = tv_args;  /* at least target func and 'this' binding present */\n\t\t/* No need to check for argArray. */\n\t} else {\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 3);  /* idx_func + 2 covered above */\n\t\tif (thr->valstack_top > tv_args + 1) {\n\t\t\tduk_set_top_unsafe(thr, idx_func + 3);  /* remove any args beyond argArray */\n\t\t}\n\t\tDUK_ASSERT(duk_is_valid_index(thr, idx_func + 2));\n\t\tif (!duk_is_callable(thr, idx_func)) {\n\t\t\t/* Avoid unpack side effects if the target isn't callable.\n\t\t\t * Calling code will throw the actual error.\n\t\t\t */\n\t\t} else {\n\t\t\t(void) duk_unpack_array_like(thr, idx_func + 2);\n\t\t\tduk_remove(thr, idx_func + 2);\n\t\t}\n\t}\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\treturn 0;  /* keep resolving */\n}\n\n/*\n *  Helper for Proxy handling.\n */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_LOCAL void duk__handle_proxy_for_call(duk_hthread *thr, duk_idx_t idx_func, duk_hproxy *h_proxy, duk_small_uint_t *call_flags) {\n\tduk_bool_t rc;\n\n\t/* Value stack:\n\t * idx_func + 0: Proxy object\n\t * idx_func + 1: this binding for call\n\t * idx_func + 2: 1st argument for call\n\t * idx_func + 3: 2nd argument for call\n\t * ...\n\t *\n\t * If Proxy doesn't have a trap for the call ('apply' or 'construct'),\n\t * replace Proxy object with target object.\n\t *\n\t * If we're dealing with a normal call and the Proxy has an 'apply'\n\t * trap, manipulate value stack to:\n\t *\n\t * idx_func + 0: trap\n\t * idx_func + 1: Proxy's handler\n\t * idx_func + 2: Proxy's target\n\t * idx_func + 3: this binding for call (from idx_func + 1)\n\t * idx_func + 4: call arguments packed to an array\n\t *\n\t * If we're dealing with a constructor call and the Proxy has a\n\t * 'construct' trap, manipulate value stack to:\n\t *\n\t * idx_func + 0: trap\n\t * idx_func + 1: Proxy's handler\n\t * idx_func + 2: Proxy's target\n\t * idx_func + 3: call arguments packed to an array\n\t * idx_func + 4: newTarget == Proxy object here\n\t *\n\t * As we don't yet have proper newTarget support, the newTarget at\n\t * idx_func + 3 is just the original constructor being called, i.e.\n\t * the Proxy object (not the target).  Note that the default instance\n\t * (original 'this' binding) is dropped and ignored.\n\t */\n\n\tduk_push_hobject(thr, h_proxy->handler);\n\trc = duk_get_prop_stridx_short(thr, -1, (*call_flags & DUK_CALL_FLAG_CONSTRUCT) ? DUK_STRIDX_CONSTRUCT : DUK_STRIDX_APPLY);\n\tif (rc == 0) {\n\t\t/* Not found, continue to target.  If this is a construct\n\t\t * call, update default instance prototype using the Proxy,\n\t\t * not the target.\n\t\t */\n\t\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\t\tif (!(*call_flags & DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED)) {\n\t\t\t\t*call_flags |= DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED;\n\t\t\t\tduk__update_default_instance_proto(thr, idx_func);\n\t\t\t}\n\t\t}\n\t\tduk_pop_2(thr);\n\t\tduk_push_hobject(thr, h_proxy->target);\n\t\tduk_replace(thr, idx_func);\n\t\treturn;\n\t}\n\n\t/* Here we must be careful not to replace idx_func while\n\t * h_proxy is still needed, otherwise h_proxy may become\n\t * dangling.  This could be improved e.g. using a\n\t * duk_pack_slice() with a freeform slice.\n\t */\n\n\t/* Here:\n\t * idx_func + 0: Proxy object\n\t * idx_func + 1: this binding for call\n\t * idx_func + 2: 1st argument for call\n\t * idx_func + 3: 2nd argument for call\n\t * ...\n\t * idx_func + N: handler\n\t * idx_func + N + 1: trap\n\t */\n\n\tduk_insert(thr, idx_func + 1);\n\tduk_insert(thr, idx_func + 2);\n\tduk_push_hobject(thr, h_proxy->target);\n\tduk_insert(thr, idx_func + 3);\n\tduk_pack(thr, duk_get_top(thr) - (idx_func + 5));\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\t/* Here:\n\t * idx_func + 0: Proxy object\n\t * idx_func + 1: trap\n\t * idx_func + 2: Proxy's handler\n\t * idx_func + 3: Proxy's target\n\t * idx_func + 4: this binding for call\n\t * idx_func + 5: arguments array\n\t */\n\tDUK_ASSERT(duk_get_top(thr) == idx_func + 6);\n\n\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\t*call_flags |= DUK_CALL_FLAG_CONSTRUCT_PROXY;  /* Enable 'construct' trap return invariant check. */\n\t\t*call_flags &= ~(DUK_CALL_FLAG_CONSTRUCT);     /* Resume as non-constructor call to the trap. */\n\n\t\t/* 'apply' args: target, thisArg, argArray\n\t\t * 'construct' args: target, argArray, newTarget\n\t\t */\n\t\tduk_remove(thr, idx_func + 4);\n\t\tduk_push_hobject(thr, (duk_hobject *) h_proxy);\n\t}\n\n\t/* Finalize value stack layout by removing Proxy reference. */\n\tduk_remove(thr, idx_func);\n\th_proxy = NULL;  /* invalidated */\n\tDUK_ASSERT(duk_get_top(thr) == idx_func + 5);\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n/*\n *  Helper for setting up var_env and lex_env of an activation,\n *  assuming it does NOT have the DUK_HOBJECT_FLAG_NEWENV flag.\n */\n\nDUK_LOCAL void duk__handle_oldenv_for_call(duk_hthread *thr,\n                                           duk_hobject *func,\n                                           duk_activation *act) {\n\tduk_hcompfunc *f;\n\tduk_hobject *h_lex;\n\tduk_hobject *h_var;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV(func));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(func));\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(func));\n\tDUK_UNREF(thr);\n\n\tf = (duk_hcompfunc *) func;\n\th_lex = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f);\n\th_var = DUK_HCOMPFUNC_GET_VARENV(thr->heap, f);\n\tDUK_ASSERT(h_lex != NULL);  /* Always true for closures (not for templates) */\n\tDUK_ASSERT(h_var != NULL);\n\tact->lex_env = h_lex;\n\tact->var_env = h_var;\n\tDUK_HOBJECT_INCREF(thr, h_lex);\n\tDUK_HOBJECT_INCREF(thr, h_var);\n}\n\n/*\n *  Helper for updating callee 'caller' property.\n */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\nDUK_LOCAL void duk__update_func_caller_prop(duk_hthread *thr, duk_hobject *func) {\n\tduk_tval *tv_caller;\n\tduk_hobject *h_tmp;\n\tduk_activation *act_callee;\n\tduk_activation *act_caller;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));  /* bound chain resolved */\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\n\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t/* Strict functions don't get their 'caller' updated. */\n\t\treturn;\n\t}\n\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tact_callee = thr->callstack_curr;\n\tDUK_ASSERT(act_callee != NULL);\n\tact_caller = (thr->callstack_top >= 2 ? act_callee->parent : NULL);\n\n\t/* XXX: check .caller writability? */\n\n\t/* Backup 'caller' property and update its value. */\n\ttv_caller = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, func, DUK_STRIDX_CALLER);\n\tif (tv_caller) {\n\t\t/* If caller is global/eval code, 'caller' should be set to\n\t\t * 'null'.\n\t\t *\n\t\t * XXX: there is no exotic flag to infer this correctly now.\n\t\t * The NEWENV flag is used now which works as intended for\n\t\t * everything (global code, non-strict eval code, and functions)\n\t\t * except strict eval code.  Bound functions are never an issue\n\t\t * because 'func' has been resolved to a non-bound function.\n\t\t */\n\n\t\tif (act_caller != NULL) {\n\t\t\t/* act_caller->func may be NULL in some finalization cases,\n\t\t\t * just treat like we don't know the caller.\n\t\t\t */\n\t\t\tif (act_caller->func && !DUK_HOBJECT_HAS_NEWENV(act_caller->func)) {\n\t\t\t\t/* Setting to NULL causes 'caller' to be set to\n\t\t\t\t * 'null' as desired.\n\t\t\t\t */\n\t\t\t\tact_caller = NULL;\n\t\t\t}\n\t\t}\n\n\t\tif (DUK_TVAL_IS_OBJECT(tv_caller)) {\n\t\t\th_tmp = DUK_TVAL_GET_OBJECT(tv_caller);\n\t\t\tDUK_ASSERT(h_tmp != NULL);\n\t\t\tact_callee->prev_caller = h_tmp;\n\n\t\t\t/* Previous value doesn't need refcount changes because its ownership\n\t\t\t * is transferred to prev_caller.\n\t\t\t */\n\n\t\t\tif (act_caller != NULL) {\n\t\t\t\tDUK_ASSERT(act_caller->func != NULL);\n\t\t\t\tDUK_TVAL_SET_OBJECT(tv_caller, act_caller->func);\n\t\t\t\tDUK_TVAL_INCREF(thr, tv_caller);\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_NULL(tv_caller);  /* no incref */\n\t\t\t}\n\t\t} else {\n\t\t\t/* 'caller' must only take on 'null' or function value */\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_caller));\n\t\t\tDUK_ASSERT(act_callee->prev_caller == NULL);\n\t\t\tif (act_caller != NULL && act_caller->func) {\n\t\t\t\t/* Tolerate act_caller->func == NULL which happens in\n\t\t\t\t * some finalization cases; treat like unknown caller.\n\t\t\t\t */\n\t\t\t\tDUK_TVAL_SET_OBJECT(tv_caller, act_caller->func);\n\t\t\t\tDUK_TVAL_INCREF(thr, tv_caller);\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_NULL(tv_caller);  /* no incref */\n\t\t\t}\n\t\t}\n\t}\n}\n#endif  /* DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */\n\n/*\n *  Shared helpers for resolving the final, non-bound target function of the\n *  call and the effective 'this' binding.  Resolves bound functions and\n *  applies .call(), .apply(), and .construct() inline.\n *\n *  Proxy traps are also handled inline so that if the target is a Proxy with\n *  a 'call' or 'construct' trap, the trap handler is called with a modified\n *  argument list.\n *\n *  Once the bound function / .call() / .apply() / .construct() sequence has\n *  been resolved, the value at idx_func + 1 may need coercion described in\n *  E5 Section 10.4.3.\n *\n *  A call that begins as a non-constructor call may be converted into a\n *  constructor call during the resolution process if Reflect.construct()\n *  is invoked.  This is handled by updating the caller's call_flags.\n *\n *  For global and eval code (E5 Sections 10.4.1 and 10.4.2), we assume\n *  that the caller has provided the correct 'this' binding explicitly\n *  when calling, i.e.:\n *\n *    - global code: this=global object\n *    - direct eval: this=copy from eval() caller's this binding\n *    - other eval:  this=global object\n *\n *  The 'this' coercion may cause a recursive function call with arbitrary\n *  side effects, because ToObject() may be called.\n */\n\nDUK_LOCAL DUK_INLINE void duk__coerce_nonstrict_this_binding(duk_hthread *thr, duk_idx_t idx_this) {\n\tduk_tval *tv_this;\n\tduk_hobject *obj_global;\n\n\ttv_this = thr->valstack_bottom + idx_this;\n\tswitch (DUK_TVAL_GET_TAG(tv_this)) {\n\tcase DUK_TAG_OBJECT:\n\t\tDUK_DDD(DUK_DDDPRINT(\"this binding: non-strict, object -> use directly\"));\n\t\tbreak;\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\t\tDUK_DDD(DUK_DDDPRINT(\"this binding: non-strict, undefined/null -> use global object\"));\n\t\tobj_global = thr->builtins[DUK_BIDX_GLOBAL];\n\t\t/* XXX: avoid this check somehow */\n\t\tif (DUK_LIKELY(obj_global != NULL)) {\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_this));  /* no need to decref previous value */\n\t\t\tDUK_TVAL_SET_OBJECT(tv_this, obj_global);\n\t\t\tDUK_HOBJECT_INCREF(thr, obj_global);\n\t\t} else {\n\t\t\t/* This may only happen if built-ins are being \"torn down\".\n\t\t\t * This behavior is out of specification scope.\n\t\t\t */\n\t\t\tDUK_D(DUK_DPRINT(\"this binding: wanted to use global object, but it is NULL -> using undefined instead\"));\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_this));  /* no need to decref previous value */\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv_this);  /* nothing to incref */\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\t/* Plain buffers and lightfuncs are object coerced.  Lightfuncs\n\t\t * very rarely come here however, because the call target would\n\t\t * need to be a non-strict non-lightfunc (lightfuncs are considered\n\t\t * strict) with an explicit lightfunc 'this' binding.\n\t\t */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_this));\n\t\tDUK_DDD(DUK_DDDPRINT(\"this binding: non-strict, not object/undefined/null -> use ToObject(value)\"));\n\t\tduk_to_object(thr, idx_this);  /* may have side effects */\n\t\tbreak;\n\t}\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_bool_t duk__resolve_target_fastpath_check(duk_hthread *thr, duk_idx_t idx_func, duk_hobject **out_func, duk_small_uint_t call_flags) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tDUK_UNREF(thr);\n\tDUK_UNREF(idx_func);\n\tDUK_UNREF(out_func);\n\tDUK_UNREF(call_flags);\n#else  /* DUK_USE_PREFER_SIZE */\n\tduk_tval *tv_func;\n\tduk_hobject *func;\n\n\tif (DUK_UNLIKELY(call_flags & DUK_CALL_FLAG_CONSTRUCT)) {\n\t\treturn 0;\n\t}\n\n\ttv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);\n\tDUK_ASSERT(tv_func != NULL);\n\n\tif (DUK_LIKELY(DUK_TVAL_IS_OBJECT(tv_func))) {\n\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\t\tif (DUK_HOBJECT_IS_CALLABLE(func) &&\n\t\t    !DUK_HOBJECT_HAS_BOUNDFUNC(func) &&\n\t\t    !DUK_HOBJECT_HAS_SPECIAL_CALL(func)) {\n\t\t\t*out_func = func;\n\n\t\t\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t\t\t/* Strict function: no 'this' coercion. */\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tduk__coerce_nonstrict_this_binding(thr, idx_func + 1);\n\t\t\treturn 1;\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {\n\t\t*out_func = NULL;\n\n\t\t/* Lightfuncs are considered strict, so 'this' binding is\n\t\t * used as is.  They're never bound, always constructable,\n\t\t * and never special functions.\n\t\t */\n\t\treturn 1;\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\treturn 0;  /* let slow path deal with it */\n}\n\nDUK_LOCAL duk_hobject *duk__resolve_target_func_and_this_binding(duk_hthread *thr,\n                                                                 duk_idx_t idx_func,\n                                                                 duk_small_uint_t *call_flags) {\n\tduk_tval *tv_func;\n\tduk_hobject *func;\n\tduk_bool_t first;\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\tfor (first = 1;; first = 0) {\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\t\ttv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);\n\t\tDUK_ASSERT(tv_func != NULL);\n\n\t\tDUK_DD(DUK_DDPRINT(\"target func: %!iT\", tv_func));\n\n\t\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\n\t\t\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\t\t\tif (DUK_UNLIKELY(!DUK_HOBJECT_HAS_CONSTRUCTABLE(func))) {\n\t\t\t\t\tgoto not_constructable;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (DUK_UNLIKELY(!DUK_HOBJECT_IS_CALLABLE(func))) {\n\t\t\t\t\tgoto not_callable;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (DUK_LIKELY(!DUK_HOBJECT_HAS_BOUNDFUNC(func) &&\n\t\t\t               !DUK_HOBJECT_HAS_SPECIAL_CALL(func) &&\n\t\t\t               !DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(func))) {\n\t\t\t\t/* Common case, so test for using a single bitfield test.\n\t\t\t\t * Break out to handle this coercion etc.\n\t\t\t\t */\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/* XXX: could set specialcall for boundfuncs too, simplify check above */\n\n\t\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_SPECIAL_CALL(func));\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_IS_NATFUNC(func));\n\n\t\t\t\t/* Callable/constructable flags are the same\n\t\t\t\t * for the bound function and its target, so\n\t\t\t\t * we don't need to check them here, we can\n\t\t\t\t * check them from the target only.\n\t\t\t\t */\n\t\t\t\tduk__handle_bound_chain_for_call(thr, idx_func, *call_flags & DUK_CALL_FLAG_CONSTRUCT);\n\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(duk_require_tval(thr, idx_func)) ||\n\t\t\t\t           DUK_TVAL_IS_LIGHTFUNC(duk_require_tval(thr, idx_func)));\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_SPECIAL_CALL(func));\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\t\t\tif (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(func)) {\n\t\t\t\t\t/* If no trap, resume processing from Proxy trap.\n\t\t\t\t\t * If trap exists, helper converts call into a trap\n\t\t\t\t\t * call; this may change a constructor call into a\n\t\t\t\t\t * normal (non-constructor) trap call.  We must\n\t\t\t\t\t * continue processing even when a trap is found as\n\t\t\t\t\t * the trap may be bound.\n\t\t\t\t\t */\n\t\t\t\t\tduk__handle_proxy_for_call(thr, idx_func, (duk_hproxy *) func, call_flags);\n\t\t\t\t}\n\t\t\t\telse\n#endif\n\t\t\t\t{\n\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(func));\n\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_CALLABLE(func));\n\t\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CONSTRUCTABLE(func));\n\t\t\t\t\t/* Constructable check already done above. */\n\n\t\t\t\t\tif (duk__handle_specialfuncs_for_call(thr, idx_func, func, call_flags, first) != 0) {\n\t\t\t\t\t\t/* Encountered native eval call, normal call\n\t\t\t\t\t\t * context.  Break out, handle this coercion etc.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* Retry loop. */\n\t\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {\n\t\t\t/* Lightfuncs are:\n\t\t\t *   - Always strict, so no 'this' coercion.\n\t\t\t *   - Always callable.\n\t\t\t *   - Always constructable.\n\t\t\t *   - Never specialfuncs.\n\t\t\t */\n\t\t\tfunc = NULL;\n\t\t\tgoto finished;\n\t\t} else {\n\t\t\tgoto not_callable;\n\t\t}\n\t}\n\n\tDUK_ASSERT(func != NULL);\n\n\tif (!DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t/* Non-strict target needs 'this' coercion.\n\t\t * This has potential side effects invalidating\n\t\t * 'tv_func'.\n\t\t */\n\t\tduk__coerce_nonstrict_this_binding(thr, idx_func + 1);\n\t}\n\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tif (!(*call_flags & DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED)) {\n\t\t\t*call_flags |= DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED;\n\t\t\tduk__update_default_instance_proto(thr, idx_func);\n\t\t}\n\t}\n\n finished:\n\n#if defined(DUK_USE_ASSERTIONS)\n\t{\n\t\tduk_tval *tv_tmp;\n\n\t\ttv_tmp = duk_get_tval(thr, idx_func);\n\t\tDUK_ASSERT(tv_tmp != NULL);\n\n\t\tDUK_ASSERT((DUK_TVAL_IS_OBJECT(tv_tmp) && DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(tv_tmp))) ||\n\t\t           DUK_TVAL_IS_LIGHTFUNC(tv_tmp));\n\t\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\t\tDUK_ASSERT(func == NULL || (DUK_HOBJECT_IS_COMPFUNC(func) ||\n\t\t                            DUK_HOBJECT_IS_NATFUNC(func)));\n\t\tDUK_ASSERT(func == NULL || (DUK_HOBJECT_HAS_CONSTRUCTABLE(func) ||\n\t\t                            (*call_flags & DUK_CALL_FLAG_CONSTRUCT) == 0));\n\t}\n#endif\n\n\treturn func;\n\n not_callable:\n\tDUK_ASSERT(tv_func != NULL);\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t/* GETPROPC delayed error handling: when target is not callable,\n\t * GETPROPC replaces idx_func+0 with a non-callable wrapper object\n\t * with a hidden Symbol to signify it's to be handled here.  If\n\t * found, unwrap the original Error and throw it as is here.  The\n\t * hidden Symbol is only checked as an own property, not inherited\n\t * (which would be dangerous).\n\t */\n\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\tduk_tval *tv_wrap = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, DUK_TVAL_GET_OBJECT(tv_func), DUK_STRIDX_INT_TARGET);\n\t\tif (tv_wrap != NULL) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"delayed error from GETPROPC: %!T\", tv_wrap));\n\t\t\tduk_push_tval(thr, tv_wrap);\n\t\t\t(void) duk_throw(thr);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t}\n#endif\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not callable\", duk_get_type_name(thr, idx_func));\n#else\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not callable\", duk_push_string_tval_readable(thr, tv_func));\n#endif\n#else\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);\n#endif\n\tDUK_WO_NORETURN(return NULL;);\n\n not_constructable:\n\t/* For now GETPROPC delayed error not needed for constructor calls. */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not constructable\", duk_get_type_name(thr, idx_func));\n#else\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not constructable\", duk_push_string_tval_readable(thr, tv_func));\n#endif\n#else\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONSTRUCTABLE);\n#endif\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Manipulate value stack so that exactly 'num_stack_rets' return\n *  values are at 'idx_retbase' in every case, assuming there are\n *  'rc' return values on top of stack.\n *\n *  This is a bit tricky, because the called C function operates in\n *  the same activation record and may have e.g. popped the stack\n *  empty (below idx_retbase).\n */\n\nDUK_LOCAL void duk__safe_call_adjust_valstack(duk_hthread *thr, duk_idx_t idx_retbase, duk_idx_t num_stack_rets, duk_idx_t num_actual_rets) {\n\tduk_idx_t idx_rcbase;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(idx_retbase >= 0);\n\tDUK_ASSERT(num_stack_rets >= 0);\n\tDUK_ASSERT(num_actual_rets >= 0);\n\n\tidx_rcbase = duk_get_top(thr) - num_actual_rets;  /* base of known return values */\n\tif (DUK_UNLIKELY(idx_rcbase < 0)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_CFUNC_RC);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"adjust valstack after func call: \"\n\t                     \"num_stack_rets=%ld, num_actual_rets=%ld, stack_top=%ld, idx_retbase=%ld, idx_rcbase=%ld\",\n\t                     (long) num_stack_rets, (long) num_actual_rets, (long) duk_get_top(thr),\n\t                     (long) idx_retbase, (long) idx_rcbase));\n\n\tDUK_ASSERT(idx_rcbase >= 0);  /* caller must check */\n\n\t/* Space for num_stack_rets was reserved before the safe call.\n\t * Because value stack reserve cannot shrink except in call returns,\n\t * the reserve is still in place.  Adjust valstack, carefully\n\t * ensuring we don't overstep the reserve.\n\t */\n\n\t/* Match idx_rcbase with idx_retbase so that the return values\n\t * start at the correct index.\n\t */\n\tif (idx_rcbase > idx_retbase) {\n\t\tduk_idx_t count = idx_rcbase - idx_retbase;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"elements at/after idx_retbase have enough to cover func retvals \"\n\t\t                     \"(idx_retbase=%ld, idx_rcbase=%ld)\", (long) idx_retbase, (long) idx_rcbase));\n\n\t\t/* Remove values between irc_rcbase (start of intended return\n\t\t * values) and idx_retbase to lower return values to idx_retbase.\n\t\t */\n\t\tDUK_ASSERT(count > 0);\n\t\tduk_remove_n(thr, idx_retbase, count);  /* may be NORZ */\n\t} else {\n\t\tduk_idx_t count = idx_retbase - idx_rcbase;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"not enough elements at/after idx_retbase to cover func retvals \"\n\t\t                     \"(idx_retbase=%ld, idx_rcbase=%ld)\", (long) idx_retbase, (long) idx_rcbase));\n\n\t\t/* Insert 'undefined' at idx_rcbase (start of intended return\n\t\t * values) to lift return values to idx_retbase.\n\t\t */\n\t\tDUK_ASSERT(count >= 0);\n\t\tDUK_ASSERT(thr->valstack_end - thr->valstack_top >= count);  /* reserve cannot shrink */\n\t\tduk_insert_undefined_n(thr, idx_rcbase, count);\n\t}\n\n\t/* Chop extra retvals away / extend with undefined. */\n\tduk_set_top_unsafe(thr, idx_retbase + num_stack_rets);\n}\n\n/*\n *  Activation setup for tailcalls and non-tailcalls.\n */\n\n#if defined(DUK_USE_TAILCALL)\nDUK_LOCAL duk_small_uint_t duk__call_setup_act_attempt_tailcall(duk_hthread *thr,\n                                                                duk_small_uint_t call_flags,\n                                                                duk_idx_t idx_func,\n                                                                duk_hobject *func,\n                                                                duk_size_t entry_valstack_bottom_byteoff,\n                                                                duk_size_t entry_valstack_end_byteoff,\n                                                                duk_idx_t *out_nargs,\n                                                                duk_idx_t *out_nregs,\n                                                                duk_size_t *out_vs_min_bytes,\n                                                                duk_activation **out_act) {\n\tduk_activation *act;\n\tduk_tval *tv1, *tv2;\n\tduk_idx_t idx_args;\n\tduk_small_uint_t flags1, flags2;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_activation *prev_pause_act;\n#endif\n\n\tDUK_UNREF(entry_valstack_end_byteoff);\n\n\t/* Tailcall cannot be flagged to resume calls, and a\n\t * previous frame must exist.\n\t */\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\t*out_act = act;\n\n\tif (func == NULL || !DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by target not being ecma function\"));\n\t\treturn 0;\n\t}\n\tif (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by current activation having DUK_ACT_FLAG_PREVENT_YIELD\"));\n\t\treturn 0;\n\t}\n\t/* Tailcall is only allowed if current and candidate\n\t * function have identical return value handling.  There\n\t * are three possible return value handling cases:\n\t *   1. Normal function call, no special return value handling.\n\t *   2. Constructor call, return value replacement object check.\n\t *   3. Proxy 'construct' trap call, return value invariant check.\n\t */\n\tflags1 = (duk_small_uint_t) ((act->flags & DUK_ACT_FLAG_CONSTRUCT) ? 1 : 0)\n#if defined(DUK_USE_ES6_PROXY)\n\t         | (duk_small_uint_t) ((act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) ? 2 : 0)\n#endif\n\t         ;\n\tflags2 = (duk_small_uint_t) ((call_flags & DUK_CALL_FLAG_CONSTRUCT) ? 1 : 0)\n#if defined(DUK_USE_ES6_PROXY)\n\t         | (duk_small_uint_t) ((call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) ? 2 : 0);\n#endif\n\t         ;\n\tif (flags1 != flags2) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by incompatible return value handling\"));\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(((act->flags & DUK_ACT_FLAG_CONSTRUCT) && (call_flags & DUK_CALL_FLAG_CONSTRUCT)) ||\n\t           (!(act->flags & DUK_ACT_FLAG_CONSTRUCT) && !(call_flags & DUK_CALL_FLAG_CONSTRUCT)));\n\tDUK_ASSERT(((act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) && (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY)) ||\n\t           (!(act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) && !(call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY)));\n\tif (DUK_HOBJECT_HAS_NOTAIL(func)) {\n\t\t/* See: test-bug-tailcall-preventyield-assert.c. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by function having a notail flag\"));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  Tailcall handling\n\t *\n\t *  Although the callstack entry is reused, we need to explicitly unwind\n\t *  the current activation (or simulate an unwind).  In particular, the\n\t *  current activation must be closed, otherwise something like\n\t *  test-bug-reduce-judofyr.js results.  Also catchers need to be unwound\n\t *  because there may be non-error-catching label entries in valid tail calls.\n\t *\n\t *  Special attention is needed for debugger and pause behavior when\n\t *  reusing an activation.\n\t *    - Disable StepOut processing for the activation unwind because\n\t *      we reuse the activation, see:\n\t *      https://github.com/svaarala/duktape/issues/1684.\n\t *    - Disable line change pause flag permanently if act == dbg_pause_act\n\t *      (if set) because it would no longer be relevant, see:\n\t *      https://github.com/svaarala/duktape/issues/1726,\n\t *      https://github.com/svaarala/duktape/issues/1786.\n\t *    - Check for function entry (e.g. StepInto) pause flag here, because\n\t *      the executor pause check won't trigger due to shared activation, see:\n\t *      https://github.com/svaarala/duktape/issues/1726.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"is tail call, reusing activation at callstack top, at index %ld\",\n                             (long) (thr->callstack_top - 1)));\n\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(func));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));\n\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\tDUK_ASSERT(call_flags & DUK_CALL_FLAG_ALLOW_ECMATOECMA);\n\n\t/* Unwind the topmost callstack entry before reusing it.  This\n\t * also unwinds the catchers related to the topmost entry.\n\t */\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (act == thr->heap->dbg_pause_act) {\n\t\tthr->heap->dbg_pause_flags &= ~DUK_PAUSE_FLAG_LINE_CHANGE;\n\t}\n\n\tprev_pause_act = thr->heap->dbg_pause_act;\n\tthr->heap->dbg_pause_act = NULL;\n\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_ENTRY) {\n\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by function entry (tailcall)\"));\n\t\tduk_debug_set_paused(thr->heap);\n\t}\n#endif\n\tduk_hthread_activation_unwind_reuse_norz(thr);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tthr->heap->dbg_pause_act = prev_pause_act;\n#endif\n\tDUK_ASSERT(act == thr->callstack_curr);\n\n\t/* XXX: We could restore the caller's value stack reserve\n\t * here, as if we did an actual unwind-and-call.  Without\n\t * the restoration, value stack reserve may remain higher\n\t * than would otherwise be possible until we return to a\n\t * non-tailcall.\n\t */\n\n\t/* Then reuse the unwound activation. */\n\tact->cat = NULL;\n\tact->var_env = NULL;\n\tact->lex_env = NULL;\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));\n\tact->func = func;  /* don't want an intermediate exposed state with func == NULL */\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\tact->prev_caller = NULL;\n#endif\n\t/* don't want an intermediate exposed state with invalid pc */\n\tact->curr_pc = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) func);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tact->prev_line = 0;\n#endif\n\tDUK_TVAL_SET_OBJECT(&act->tv_func, func);  /* borrowed, no refcount */\n\tDUK_HOBJECT_INCREF(thr, func);\n\n\tact->flags = DUK_ACT_FLAG_TAILCALLED;\n\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\tact->flags |= DUK_ACT_FLAG_STRICT;\n\t}\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT;\n\t}\n#if defined(DUK_USE_ES6_PROXY)\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT_PROXY;\n\t}\n#endif\n\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) == func);      /* already updated */\n\tDUK_ASSERT(act->var_env == NULL);\n\tDUK_ASSERT(act->lex_env == NULL);\n\tact->bottom_byteoff = entry_valstack_bottom_byteoff;  /* tail call -> reuse current \"frame\" */\n#if 0\n\t/* Topmost activation retval_byteoff is considered garbage, no need to init. */\n\tact->retval_byteoff = 0;\n#endif\n\t/* Filled in when final reserve is known, dummy value doesn't matter\n\t * even in error unwind because reserve_byteoff is only used when\n\t * returning to -this- activation.\n\t */\n\tact->reserve_byteoff = 0;\n\n\t/*\n\t *  Manipulate valstack so that args are on the current bottom and the\n\t *  previous caller's 'this' binding (which is the value preceding the\n\t *  current bottom) is replaced with the new 'this' binding:\n\t *\n\t *       [ ... this_old | (crud) func this_new arg1 ... argN ]\n\t *  -->  [ ... this_new | arg1 ... argN ]\n\t *\n\t *  For tail calling to work properly, the valstack bottom must not grow\n\t *  here; otherwise crud would accumulate on the valstack.\n\t */\n\n\ttv1 = thr->valstack_bottom - 1;\n\ttv2 = thr->valstack_bottom + idx_func + 1;\n\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);  /* tv1 is -below- valstack_bottom */\n\tDUK_ASSERT(tv2 >= thr->valstack_bottom && tv2 < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\n\tidx_args = idx_func + 2;\n\tduk_remove_n(thr, 0, idx_args);  /* may be NORZ */\n\n\tidx_func = 0; DUK_UNREF(idx_func);  /* really 'not applicable' anymore, should not be referenced after this */\n\tidx_args = 0;\n\n\t*out_nargs = ((duk_hcompfunc *) func)->nargs;\n\t*out_nregs = ((duk_hcompfunc *) func)->nregs;\n\tDUK_ASSERT(*out_nregs >= 0);\n\tDUK_ASSERT(*out_nregs >= *out_nargs);\n\t*out_vs_min_bytes = entry_valstack_bottom_byteoff + sizeof(duk_tval) * ((duk_size_t) *out_nregs + DUK_VALSTACK_INTERNAL_EXTRA);\n\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n#if defined(DUK_USE_TAILCALL)\n#error incorrect options: tail calls enabled with function caller property\n#endif\n\t/* XXX: This doesn't actually work properly for tail calls, so\n\t * tail calls are disabled when DUK_USE_NONSTD_FUNC_CALLER_PROPERTY\n\t * is in use.\n\t */\n\tduk__update_func_caller_prop(thr, func);\n#endif\n\n\t/* [ ... this_new | arg1 ... argN ] */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_TAILCALL */\n\nDUK_LOCAL void duk__call_setup_act_not_tailcall(duk_hthread *thr,\n                                                duk_small_uint_t call_flags,\n                                                duk_idx_t idx_func,\n                                                duk_hobject *func,\n                                                duk_size_t entry_valstack_bottom_byteoff,\n                                                duk_size_t entry_valstack_end_byteoff,\n                                                duk_idx_t *out_nargs,\n                                                duk_idx_t *out_nregs,\n                                                duk_size_t *out_vs_min_bytes,\n                                                duk_activation **out_act) {\n\tduk_activation *act;\n\tduk_activation *new_act;\n\n\tDUK_UNREF(entry_valstack_end_byteoff);\n\n\tDUK_DDD(DUK_DDDPRINT(\"not a tail call, pushing a new activation to callstack, to index %ld\",\n\t                     (long) (thr->callstack_top)));\n\n\tduk__call_callstack_limit_check(thr);\n\tnew_act = duk_hthread_activation_alloc(thr);\n\tDUK_ASSERT(new_act != NULL);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\t/*\n\t\t *  Update return value stack index of current activation (if any).\n\t\t *\n\t\t *  Although it might seem this is not necessary (bytecode executor\n\t\t *  does this for ECMAScript-to-ECMAScript calls; other calls are\n\t\t *  handled here), this turns out to be necessary for handling yield\n\t\t *  and resume.  For them, an ECMAScript-to-native call happens, and\n\t\t *  the ECMAScript call's retval_byteoff must be set for things to work.\n\t\t */\n\n\t\tact->retval_byteoff = entry_valstack_bottom_byteoff + (duk_size_t) idx_func * sizeof(duk_tval);\n\t}\n\n\tnew_act->parent = act;\n\tthr->callstack_curr = new_act;\n\tthr->callstack_top++;\n\tact = new_act;\n\t*out_act = act;\n\n\tDUK_ASSERT(thr->valstack_top > thr->valstack_bottom);  /* at least effective 'this' */\n\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\n\tact->cat = NULL;\n\n\tact->flags = 0;\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT;\n\t}\n#if defined(DUK_USE_ES6_PROXY)\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT_PROXY;\n\t}\n#endif\n\tif (call_flags & DUK_CALL_FLAG_DIRECT_EVAL) {\n\t\tact->flags |= DUK_ACT_FLAG_DIRECT_EVAL;\n\t}\n\n\t/* start of arguments: idx_func + 2. */\n\tact->func = func;  /* NULL for lightfunc */\n\tif (DUK_LIKELY(func != NULL)) {\n\t\tDUK_TVAL_SET_OBJECT(&act->tv_func, func);  /* borrowed, no refcount */\n\t\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t\tact->flags |= DUK_ACT_FLAG_STRICT;\n\t\t}\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\t\t*out_nargs = ((duk_hcompfunc *) func)->nargs;\n\t\t\t*out_nregs = ((duk_hcompfunc *) func)->nregs;\n\t\t\tDUK_ASSERT(*out_nregs >= 0);\n\t\t\tDUK_ASSERT(*out_nregs >= *out_nargs);\n\t\t\t*out_vs_min_bytes = entry_valstack_bottom_byteoff +\n\t\t\t\tsizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nregs + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t} else {\n\t\t\t/* True because of call target lookup checks. */\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(func));\n\n\t\t\t*out_nargs = ((duk_hnatfunc *) func)->nargs;\n\t\t\t*out_nregs = *out_nargs;\n\t\t\tif (*out_nargs >= 0) {\n\t\t\t\t*out_vs_min_bytes = entry_valstack_bottom_byteoff +\n\t\t\t\t\tsizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nregs + DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t\t} else {\n\t\t\t\t/* Vararg function. */\n\t\t\t\tduk_size_t valstack_top_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - ((duk_uint8_t *) thr->valstack));\n\t\t\t\t*out_vs_min_bytes = valstack_top_byteoff +\n\t\t\t\t\tsizeof(duk_tval) * (DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tduk_small_uint_t lf_flags;\n\t\tduk_tval *tv_func;\n\n\t\tact->flags |= DUK_ACT_FLAG_STRICT;\n\n\t\ttv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);\n\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func));\n\t\tDUK_TVAL_SET_TVAL(&act->tv_func, tv_func);  /* borrowed, no refcount */\n\n\t\tlf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv_func);\n\t\t*out_nargs = DUK_LFUNC_FLAGS_GET_NARGS(lf_flags);\n\t\tif (*out_nargs != DUK_LFUNC_NARGS_VARARGS) {\n\t\t\t*out_vs_min_bytes = entry_valstack_bottom_byteoff +\n\t\t\t\tsizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nargs + DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t} else {\n\t\t\tduk_size_t valstack_top_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - ((duk_uint8_t *) thr->valstack));\n\t\t\t*out_vs_min_bytes = valstack_top_byteoff +\n\t\t\t\tsizeof(duk_tval) * (DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t\t*out_nargs = -1;  /* vararg */\n\t\t}\n\t\t*out_nregs = *out_nargs;\n\t}\n\n\tact->var_env = NULL;\n\tact->lex_env = NULL;\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\tact->prev_caller = NULL;\n#endif\n\tact->curr_pc = NULL;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tact->prev_line = 0;\n#endif\n\tact->bottom_byteoff = entry_valstack_bottom_byteoff + sizeof(duk_tval) * ((duk_size_t) idx_func + 2U);\n#if 0\n\tact->retval_byteoff = 0;   /* topmost activation retval_byteoff is considered garbage, no need to init */\n#endif\n\t/* Filled in when final reserve is known, dummy value doesn't matter\n\t * even in error unwind because reserve_byteoff is only used when\n\t * returning to -this- activation.\n\t */\n\tact->reserve_byteoff = 0;  /* filled in by caller */\n\n\t/* XXX: Is this INCREF necessary? 'func' is always a borrowed\n\t * reference reachable through the value stack?  If changed, stack\n\t * unwind code also needs to be fixed to match.\n\t */\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, func);  /* act->func */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\tif (func) {\n\t\tduk__update_func_caller_prop(thr, func);\n\t}\n#endif\n}\n\n/*\n *  Environment setup.\n */\n\nDUK_LOCAL void duk__call_env_setup(duk_hthread *thr, duk_hobject *func, duk_activation *act, duk_idx_t idx_args) {\n\tduk_hobject *env;\n\n\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));  /* bound function has already been resolved */\n\n\tif (DUK_LIKELY(func != NULL)) {\n\t\tif (DUK_LIKELY(DUK_HOBJECT_HAS_NEWENV(func))) {\n\t\t\tDUK_STATS_INC(thr->heap, stats_envrec_newenv);\n\t\t\tif (DUK_LIKELY(!DUK_HOBJECT_HAS_CREATEARGS(func))) {\n\t\t\t\t/* Use a new environment but there's no 'arguments' object;\n\t\t\t\t * delayed environment initialization.  This is the most\n\t\t\t\t * common case.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(act->lex_env == NULL);\n\t\t\t\tDUK_ASSERT(act->var_env == NULL);\n\t\t\t} else {\n\t\t\t\t/* Use a new environment and there's an 'arguments' object.\n\t\t\t\t * We need to initialize it right now.\n\t\t\t\t */\n\n\t\t\t\t/* third arg: absolute index (to entire valstack) of bottom_byteoff of new activation */\n\t\t\t\tenv = duk_create_activation_environment_record(thr, func, act->bottom_byteoff);\n\t\t\t\tDUK_ASSERT(env != NULL);\n\n\t\t\t\t/* [ ... func this arg1 ... argN envobj ] */\n\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_CREATEARGS(func));\n\t\t\t\tduk__handle_createargs_for_call(thr, func, env, idx_args);\n\n\t\t\t\t/* [ ... func this arg1 ... argN envobj ] */\n\n\t\t\t\tact->lex_env = env;\n\t\t\t\tact->var_env = env;\n\t\t\t\tDUK_HOBJECT_INCREF(thr, env);\n\t\t\t\tDUK_HOBJECT_INCREF(thr, env);  /* XXX: incref by count (2) directly */\n\t\t\t\tduk_pop(thr);\n\t\t\t}\n\t\t} else {\n\t\t\t/* Use existing env (e.g. for non-strict eval); cannot have\n\t\t\t * an own 'arguments' object (but can refer to an existing one).\n\t\t\t */\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(func));\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_envrec_oldenv);\n\t\t\tduk__handle_oldenv_for_call(thr, func, act);\n\n\t\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\t\tDUK_ASSERT(act->var_env != NULL);\n\t\t}\n\t} else {\n\t\t/* Lightfuncs are always native functions and have \"newenv\". */\n\t\tDUK_ASSERT(act->lex_env == NULL);\n\t\tDUK_ASSERT(act->var_env == NULL);\n\t\tDUK_STATS_INC(thr->heap, stats_envrec_newenv);\n\t}\n}\n\n/*\n *  Misc shared helpers.\n */\n\n/* Check thread state, update current thread. */\nDUK_LOCAL void duk__call_thread_state_update(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\tif (DUK_LIKELY(thr == thr->heap->curr_thread)) {\n\t\tif (DUK_UNLIKELY(thr->state != DUK_HTHREAD_STATE_RUNNING)) {\n\t\t\t/* Should actually never happen, but check anyway. */\n\t\t\tgoto thread_state_error;\n\t\t}\n\t} else {\n\t\tDUK_ASSERT(thr->heap->curr_thread == NULL ||\n\t\t           thr->heap->curr_thread->state == DUK_HTHREAD_STATE_RUNNING);\n\t\tif (DUK_UNLIKELY(thr->state != DUK_HTHREAD_STATE_INACTIVE)) {\n\t\t\tgoto thread_state_error;\n\t\t}\n\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, thr);\n\t\tthr->state = DUK_HTHREAD_STATE_RUNNING;\n\n\t\t/* Multiple threads may be simultaneously in the RUNNING\n\t\t * state, but not in the same \"resume chain\".\n\t\t */\n\t}\n\tDUK_ASSERT(thr->heap->curr_thread == thr);\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\treturn;\n\n thread_state_error:\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"invalid thread state (%ld)\", (long) thr->state);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Main unprotected call handler, handles:\n *\n *    - All combinations of native/ECMAScript caller and native/ECMAScript\n *      target.\n *\n *    - Optimized ECMAScript-to-ECMAScript call where call handling only\n *      sets up a new duk_activation but reuses an existing bytecode executor\n *      (the caller) without native recursion.\n *\n *    - Tailcalls, where an activation is reused without increasing call\n *      stack (duk_activation) depth.\n *\n *    - Setup for an initial Duktape.Thread.resume().\n *\n *  The call handler doesn't provide any protection guarantees, protected calls\n *  must be implemented e.g. by wrapping the call in a duk_safe_call().\n *  Call setup may fail at any stage, even when the new activation is in\n *  place; the only guarantee is that the state is consistent for unwinding.\n */\n\nDUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,\n                                         duk_idx_t idx_func,\n                                         duk_small_uint_t call_flags) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_activation *entry_act;\n\tduk_size_t entry_callstack_top;\n#endif\n\tduk_size_t entry_valstack_bottom_byteoff;\n\tduk_size_t entry_valstack_end_byteoff;\n\tduk_int_t entry_call_recursion_depth;\n\tduk_hthread *entry_curr_thread;\n\tduk_uint_fast8_t entry_thread_state;\n\tduk_instr_t **entry_ptr_curr_pc;\n\tduk_idx_t idx_args;\n\tduk_idx_t nargs;            /* # argument registers target function wants (< 0 => \"as is\") */\n\tduk_idx_t nregs;            /* # total registers target function wants on entry (< 0 => \"as is\") */\n\tduk_size_t vs_min_bytes;    /* minimum value stack size (bytes) for handling call */\n\tduk_hobject *func;          /* 'func' on stack (borrowed reference) */\n\tduk_activation *act;\n\tduk_ret_t rc;\n\tduk_small_uint_t use_tailcall;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\t/* Asserts for heap->curr_thread omitted: it may be NULL, 'thr', or\n\t * any other thread (e.g. when heap thread is used to run finalizers).\n\t */\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\tDUK_ASSERT(idx_func >= 0);\n\n\tDUK_STATS_INC(thr->heap, stats_call_all);\n\n\t/* If a tail call:\n\t *   - an ECMAScript activation must be on top of the callstack\n\t *   - there cannot be any catch stack entries that would catch\n\t *     a return\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tif (call_flags & DUK_CALL_FLAG_TAILCALL) {\n\t\tduk_activation *tmp_act;\n\t\tduk_catcher *tmp_cat;\n\n\t\tDUK_ASSERT(thr->callstack_top >= 1);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\t\t/* No entry in the catch stack which would actually catch a\n\t\t * throw can refer to the callstack entry being reused.\n\t\t * There *can* be catch stack entries referring to the current\n\t\t * callstack entry as long as they don't catch (e.g. label sites).\n\t\t */\n\n\t\ttmp_act = thr->callstack_curr;\n\t\tfor (tmp_cat = tmp_act->cat; tmp_cat != NULL; tmp_cat = tmp_cat->parent) {\n\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(tmp_cat) == DUK_CAT_TYPE_LABEL); /* a non-catching entry */\n\t\t}\n\t}\n#endif  /* DUK_USE_ASSERTIONS */\n\n\t/*\n\t *  Store entry state.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_act = thr->callstack_curr;\n\tentry_callstack_top = thr->callstack_top;\n#endif\n\tentry_valstack_bottom_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);\n\tentry_valstack_end_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tentry_call_recursion_depth = thr->heap->call_recursion_depth;\n\tentry_curr_thread = thr->heap->curr_thread;  /* may be NULL if first call */\n\tentry_thread_state = thr->state;\n\tentry_ptr_curr_pc = thr->ptr_curr_pc;  /* may be NULL */\n\n\t/* If thr->ptr_curr_pc is set, sync curr_pc to act->pc.  Then NULL\n\t * thr->ptr_curr_pc so that it's not accidentally used with an incorrect\n\t * activation when side effects occur.\n\t */\n\tduk_hthread_sync_and_null_currpc(thr);\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"duk__handle_call_raw: thr=%p, idx_func=%ld, \"\n\t                   \"call_flags=0x%08lx (constructor=%ld), \"\n\t                   \"valstack_top=%ld, idx_func=%ld, idx_args=%ld, rec_depth=%ld/%ld, \"\n\t                   \"entry_valstack_bottom_byteoff=%ld, entry_valstack_end_byteoff=%ld, \"\n\t                   \"entry_call_recursion_depth=%ld, \"\n\t                   \"entry_curr_thread=%p, entry_thread_state=%ld\",\n\t                   (void *) thr,\n\t                   (long) idx_func,\n\t                   (unsigned long) call_flags,\n\t                   (long) ((call_flags & DUK_CALL_FLAG_CONSTRUCT) != 0 ? 1 : 0),\n\t                   (long) duk_get_top(thr),\n\t                   (long) idx_func,\n\t                   (long) (idx_func + 2),\n\t                   (long) thr->heap->call_recursion_depth,\n\t                   (long) thr->heap->call_recursion_limit,\n\t                   (long) entry_valstack_bottom_byteoff,\n\t                   (long) entry_valstack_end_byteoff,\n\t                   (long) entry_call_recursion_depth,\n\t                   (void *) entry_curr_thread,\n\t                   (long) entry_thread_state));\n\n\t/*\n\t *  Thread state check and book-keeping.\n\t */\n\n\tduk__call_thread_state_update(thr);\n\n\t/*\n\t *  Increase call recursion depth as early as possible so that if we\n\t *  enter a recursive call for any reason there's a backstop to native\n\t *  recursion.  This can happen e.g. for almost any property read\n\t *  because it may cause a getter call or a Proxy trap (GC and finalizers\n\t *  are not an issue because they are not recursive).  If we end up\n\t *  doing an Ecma-to-Ecma call, revert the increase.  (See GH-2032.)\n\t *\n\t *  For similar reasons, ensure there is a known value stack spare\n\t *  even before we actually prepare the value stack for the target\n\t *  function.  If this isn't done, early recursion may consume the\n\t *  value stack space.\n\t *\n\t *  XXX: Should bump yield preventcount early, for the same reason.\n\t */\n\n\tduk__call_c_recursion_limit_check(thr);\n\tthr->heap->call_recursion_depth++;\n\tduk_require_stack(thr, DUK__CALL_HANDLING_REQUIRE_STACK);\n\n\t/*\n\t *  Resolve final target function; handle bound functions and special\n\t *  functions like .call() and .apply().  Also figure out the effective\n\t *  'this' binding, which replaces the current value at idx_func + 1.\n\t */\n\n\tif (DUK_LIKELY(duk__resolve_target_fastpath_check(thr, idx_func, &func, call_flags) != 0U)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"fast path target resolve\"));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"slow path target resolve\"));\n\t\tfunc = duk__resolve_target_func_and_this_binding(thr, idx_func, &call_flags);\n\t}\n\tDUK_ASSERT(duk_get_top(thr) - idx_func >= 2);  /* at least func and this present */\n\n\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\tDUK_ASSERT(func == NULL || (DUK_HOBJECT_IS_COMPFUNC(func) ||\n\t                            DUK_HOBJECT_IS_NATFUNC(func)));\n\n\t/* [ ... func this arg1 ... argN ] */\n\n\t/*\n\t *  Setup a preliminary activation and figure out nargs/nregs and\n\t *  value stack minimum size.\n\t *\n\t *  Don't touch valstack_bottom or valstack_top yet so that Duktape API\n\t *  calls work normally.\n\t *\n\t *  Because 'act' is not zeroed, all fields must be filled in.\n\t */\n\n\t/* Should not be necessary, but initialize to silence warnings. */\n\tact = NULL;\n\tnargs = 0;\n\tnregs = 0;\n\tvs_min_bytes = 0;\n\n#if defined(DUK_USE_TAILCALL)\n\tuse_tailcall = (call_flags & DUK_CALL_FLAG_TAILCALL);\n\tif (use_tailcall) {\n\t\tuse_tailcall = duk__call_setup_act_attempt_tailcall(thr,\n\t\t                                                    call_flags,\n\t\t                                                    idx_func,\n\t\t                                                    func,\n\t\t                                                    entry_valstack_bottom_byteoff,\n\t\t                                                    entry_valstack_end_byteoff,\n\t\t                                                    &nargs,\n\t\t                                                    &nregs,\n\t\t                                                    &vs_min_bytes,\n\t\t                                                    &act);\n\t}\n#else\n\tDUK_ASSERT((call_flags & DUK_CALL_FLAG_TAILCALL) == 0);  /* compiler ensures this */\n\tuse_tailcall = 0;\n#endif\n\n\tif (use_tailcall) {\n\t\tidx_args = 0;\n\t\tDUK_STATS_INC(thr->heap, stats_call_tailcall);\n\t} else {\n\t\tduk__call_setup_act_not_tailcall(thr,\n\t\t                                 call_flags,\n\t\t                                 idx_func,\n\t\t                                 func,\n\t\t                                 entry_valstack_bottom_byteoff,\n\t\t                                 entry_valstack_end_byteoff,\n\t\t                                 &nargs,\n\t\t                                 &nregs,\n\t\t                                 &vs_min_bytes,\n\t\t                                 &act);\n\t\tidx_args = idx_func + 2;\n\t}\n\t/* After this point idx_func is no longer valid for tailcalls. */\n\n\tDUK_ASSERT(act != NULL);\n\n\t/* [ ... func this arg1 ... argN ] */\n\n\t/*\n\t *  Environment record creation and 'arguments' object creation.\n\t *  Named function expression name binding is handled by the\n\t *  compiler; the compiled function's parent env will contain\n\t *  the (immutable) binding already.\n\t *\n\t *  This handling is now identical for C and ECMAScript functions.\n\t *  C functions always have the 'NEWENV' flag set, so their\n\t *  environment record initialization is delayed (which is good).\n\t *\n\t *  Delayed creation (on demand) is handled in duk_js_var.c.\n\t */\n\n\tduk__call_env_setup(thr, func, act, idx_args);\n\n\t/* [ ... func this arg1 ... argN ] */\n\n\t/*\n\t *  Setup value stack: clamp to 'nargs', fill up to 'nregs',\n\t *  ensure value stack size matches target requirements, and\n\t *  switch value stack bottom.  Valstack top is kept.\n\t *\n\t *  Value stack can only grow here.\n\t */\n\n\tduk_valstack_grow_check_throw(thr, vs_min_bytes);\n\tact->reserve_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\n\tif (use_tailcall) {\n\t\tDUK_ASSERT(nregs >= 0);\n\t\tDUK_ASSERT(nregs >= nargs);\n\t\tduk_set_top_and_wipe(thr, nregs, nargs);\n\t} else {\n\t\tif (nregs >= 0) {\n\t\t\tDUK_ASSERT(nregs >= nargs);\n\t\t\tduk_set_top_and_wipe(thr, idx_func + 2 + nregs, idx_func + 2 + nargs);\n\t\t} else {\n\t\t\t;\n\t\t}\n\t\tthr->valstack_bottom = thr->valstack_bottom + idx_func + 2;\n\t}\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\n\t/*\n\t *  Make the actual call.  For Ecma-to-Ecma calls detect that\n\t *  setup is complete, then return with a status code that allows\n\t *  the caller to reuse the running executor.\n\t */\n\n\tif (func != NULL && DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\t/*\n\t\t *  ECMAScript call.\n\t\t */\n\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));\n\t\tact->curr_pc = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) func);\n\n\t\tif (call_flags & DUK_CALL_FLAG_ALLOW_ECMATOECMA) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"avoid native call, use existing executor\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_call_ecmatoecma);\n\t\t\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\t\t\tDUK_REFZERO_CHECK_FAST(thr);\n\t\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\t\tthr->heap->call_recursion_depth--;  /* No recursion increase for this case. */\n\t\t\treturn 1;  /* 1=reuse executor */\n\t\t}\n\t\tDUK_ASSERT(use_tailcall == 0);\n\n\t\t/* duk_hthread_activation_unwind_norz() will decrease this on unwind */\n\t\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\t\tact->flags |= DUK_ACT_FLAG_PREVENT_YIELD;\n\t\tthr->callstack_preventcount++;\n\n\t\t/* [ ... func this | arg1 ... argN ] ('this' must precede new bottom) */\n\n\t\t/*\n\t\t *  Bytecode executor call.\n\t\t *\n\t\t *  Execute bytecode, handling any recursive function calls and\n\t\t *  thread resumptions.  Returns when execution would return from\n\t\t *  the entry level activation.  When the executor returns, a\n\t\t *  single return value is left on the stack top.\n\t\t *\n\t\t *  The only possible longjmp() is an error (DUK_LJ_TYPE_THROW),\n\t\t *  other types are handled internally by the executor.\n\t\t */\n\n\t\t/* thr->ptr_curr_pc is set by bytecode executor early on entry */\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"entering bytecode execution\"));\n\t\tduk_js_execute_bytecode(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"returned from bytecode execution\"));\n\t} else {\n\t\t/*\n\t\t *  Native call.\n\t\t */\n\n\t\tDUK_ASSERT(func == NULL || ((duk_hnatfunc *) func)->func != NULL);\n\t\tDUK_ASSERT(use_tailcall == 0);\n\n\t\t/* [ ... func this | arg1 ... argN ] ('this' must precede new bottom) */\n\n\t\t/* duk_hthread_activation_unwind_norz() will decrease this on unwind */\n\t\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\t\tact->flags |= DUK_ACT_FLAG_PREVENT_YIELD;\n\t\tthr->callstack_preventcount++;\n\n\t\t/* For native calls must be NULL so we don't sync back */\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\n\t\t/* XXX: native funcptr could come out of call setup. */\n\t\tif (func) {\n\t\t\trc = ((duk_hnatfunc *) func)->func(thr);\n\t\t} else {\n\t\t\tduk_tval *tv_func;\n\t\t\tduk_c_function funcptr;\n\n\t\t\ttv_func = &act->tv_func;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func));\n\t\t\tfuncptr = DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv_func);\n\t\t\trc = funcptr(thr);\n\t\t}\n\n\t\t/* Automatic error throwing, retval check. */\n\n\t\tif (rc == 0) {\n\t\t\tDUK_ASSERT(thr->valstack < thr->valstack_end);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));\n\t\t\tthr->valstack_top++;\n\t\t} else if (rc == 1) {\n\t\t\t;\n\t\t} else if (rc < 0) {\n\t\t\tduk_error_throw_from_negative_rc(thr, rc);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t} else {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_CFUNC_RC);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t}\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\tDUK_ASSERT(use_tailcall == 0);\n\n\t/*\n\t *  Constructor call post processing.\n\t */\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (call_flags & (DUK_CALL_FLAG_CONSTRUCT | DUK_CALL_FLAG_CONSTRUCT_PROXY)) {\n\t\tduk_call_construct_postprocess(thr, call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY);\n\t}\n#else\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tduk_call_construct_postprocess(thr, 0);\n\t}\n#endif\n\n\t/*\n\t *  Unwind, restore valstack bottom and other book-keeping.\n\t */\n\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_curr->parent == entry_act);\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top + 1);\n\tduk_hthread_activation_unwind_norz(thr);\n\tDUK_ASSERT(thr->callstack_curr == entry_act);\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_bottom_byteoff);\n\t/* keep current valstack_top */\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_top - thr->valstack_bottom >= idx_func + 1);\n\n\t/* Return value handling. */\n\n\t/* [ ... func this (crud) retval ] */\n\n\t{\n\t\tduk_tval *tv_ret;\n\t\tduk_tval *tv_funret;\n\n\t\ttv_ret = thr->valstack_bottom + idx_func;\n\t\ttv_funret = thr->valstack_top - 1;\n#if defined(DUK_USE_FASTINT)\n\t\t/* Explicit check for fastint downgrade. */\n\t\tDUK_TVAL_CHKFAST_INPLACE_FAST(tv_funret);\n#endif\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv_ret, tv_funret);  /* side effects */\n\t}\n\n\tduk_set_top_unsafe(thr, idx_func + 1);\n\n\t/* [ ... retval ] */\n\n\t/* Restore caller's value stack reserve (cannot fail). */\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff >= (duk_uint8_t *) thr->valstack_top);\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff <= (duk_uint8_t *) thr->valstack_alloc_end);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff);\n\n\t/* XXX: Trial value stack shrink would be OK here, but we'd need\n\t * to prevent side effects of the potential realloc.\n\t */\n\n\t/* Restore entry thread executor curr_pc stack frame pointer. */\n\tthr->ptr_curr_pc = entry_ptr_curr_pc;\n\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread);  /* may be NULL */\n\tthr->state = (duk_uint8_t) entry_thread_state;\n\n\t/* Disabled assert: triggered with some torture tests. */\n#if 0\n\tDUK_ASSERT((thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread == NULL) ||  /* first call */\n\t           (thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread != NULL) ||  /* other call */\n\t           (thr->state == DUK_HTHREAD_STATE_RUNNING && thr->heap->curr_thread == thr));     /* current thread */\n#endif\n\n\tthr->heap->call_recursion_depth = entry_call_recursion_depth;\n\n\t/* If the debugger is active we need to force an interrupt so that\n\t * debugger breakpoints are rechecked.  This is important for function\n\t * calls caused by side effects (e.g. when doing a DUK_OP_GETPROP), see\n\t * GH-303.  Only needed for success path, error path always causes a\n\t * breakpoint recheck in the executor.  It would be enough to set this\n\t * only when returning to an ECMAScript activation, but setting the flag\n\t * on every return should have no ill effect.\n\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tDUK_DD(DUK_DDPRINT(\"returning with debugger enabled, force interrupt\"));\n\t\tDUK_ASSERT(thr->interrupt_counter <= thr->interrupt_init);\n\t\tthr->interrupt_init -= thr->interrupt_counter;\n\t\tthr->interrupt_counter = 0;\n\t\tthr->heap->dbg_force_restart = 1;\n\t}\n#endif\n\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\tduk__interrupt_fixup(thr, entry_curr_thread);\n#endif\n\n\t/* Restored by success path. */\n\tDUK_ASSERT(thr->heap->call_recursion_depth == entry_call_recursion_depth);\n\tDUK_ASSERT(thr->ptr_curr_pc == entry_ptr_curr_pc);\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\tDUK_REFZERO_CHECK_FAST(thr);\n\n\treturn 0;  /* 0=call handled inline */\n}\n\nDUK_INTERNAL duk_int_t duk_handle_call_unprotected_nargs(duk_hthread *thr,\n                                                         duk_idx_t nargs,\n                                                         duk_small_uint_t call_flags) {\n\tduk_idx_t idx_func;\n\tDUK_ASSERT(duk_get_top(thr) >= nargs + 2);\n\tidx_func = duk_get_top(thr) - (nargs + 2);\n\tDUK_ASSERT(idx_func >= 0);\n\treturn duk_handle_call_unprotected(thr, idx_func, call_flags);\n}\n\nDUK_INTERNAL duk_int_t duk_handle_call_unprotected(duk_hthread *thr,\n                                                   duk_idx_t idx_func,\n                                                   duk_small_uint_t call_flags) {\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\tDUK_ASSERT(idx_func >= 0);\n\treturn duk__handle_call_raw(thr, idx_func, call_flags);\n}\n\n/*\n *  duk_handle_safe_call(): make a \"C protected call\" within the\n *  current activation.\n *\n *  The allowed thread states for making a call are the same as for\n *  duk_handle_call_protected().\n *\n *  Even though this call is protected, errors are thrown for insane arguments\n *  and may result in a fatal error unless there's another protected call which\n *  catches such errors.\n *\n *  The error handling path should be error free, even for out-of-memory\n *  errors, to ensure safe sandboxing.  (As of Duktape 2.2.0 this is not\n *  yet the case for environment closing which may run out of memory, see\n *  XXX notes below.)\n */\n\nDUK_LOCAL void duk__handle_safe_call_inner(duk_hthread *thr,\n                                           duk_safe_call_function func,\n                                           void *udata,\n#if defined(DUK_USE_ASSERTIONS)\n                                           duk_size_t entry_valstack_bottom_byteoff,\n                                           duk_size_t entry_callstack_top,\n#endif\n                                           duk_hthread *entry_curr_thread,\n                                           duk_uint_fast8_t entry_thread_state,\n                                           duk_idx_t idx_retbase,\n                                           duk_idx_t num_stack_rets) {\n\tduk_ret_t rc;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\t/*\n\t *  Thread state check and book-keeping.\n\t */\n\n\tduk__call_thread_state_update(thr);\n\n\t/*\n\t *  Recursion limit check.\n\t */\n\n\tduk__call_c_recursion_limit_check(thr);\n\tthr->heap->call_recursion_depth++;\n\n\t/*\n\t *  Make the C call.\n\t */\n\n\trc = func(thr, udata);\n\n\tDUK_DDD(DUK_DDDPRINT(\"safe_call, func rc=%ld\", (long) rc));\n\n\t/*\n\t *  Valstack manipulation for results.\n\t */\n\n\t/* we're running inside the caller's activation, so no change in call/catch stack or valstack bottom */\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) == entry_valstack_bottom_byteoff);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\n\tif (DUK_UNLIKELY(rc < 0)) {\n\t\tduk_error_throw_from_negative_rc(thr, rc);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(rc >= 0);\n\n\tduk__safe_call_adjust_valstack(thr, idx_retbase, num_stack_rets, rc);  /* throws for insane rc */\n\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread);  /* may be NULL */\n\tthr->state = (duk_uint8_t) entry_thread_state;\n}\n\nDUK_LOCAL void duk__handle_safe_call_error(duk_hthread *thr,\n                                           duk_activation *entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n                                           duk_size_t entry_callstack_top,\n#endif\n                                           duk_hthread *entry_curr_thread,\n                                           duk_uint_fast8_t entry_thread_state,\n                                           duk_idx_t idx_retbase,\n                                           duk_idx_t num_stack_rets,\n                                           duk_size_t entry_valstack_bottom_byteoff,\n                                           duk_jmpbuf *old_jmpbuf_ptr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\t/*\n\t *  Error during call.  The error value is at heap->lj.value1.\n\t *\n\t *  The very first thing we do is restore the previous setjmp catcher.\n\t *  This means that any error in error handling will propagate outwards\n\t *  instead of causing a setjmp() re-entry above.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"error caught during protected duk_handle_safe_call()\"));\n\n\t/* Other longjmp types are handled by executor before propagating\n\t * the error here.\n\t */\n\tDUK_ASSERT(thr->heap->lj.type == DUK_LJ_TYPE_THROW);\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\n\t/* Either pointer may be NULL (at entry), so don't assert. */\n\tthr->heap->lj.jmpbuf_ptr = old_jmpbuf_ptr;\n\n\t/* XXX: callstack unwind may now throw an error when closing\n\t * scopes; this is a sandboxing issue, described in:\n\t * https://github.com/svaarala/duktape/issues/476\n\t */\n\t/* XXX: \"unwind to\" primitive? */\n\n\tDUK_ASSERT(thr->callstack_top >= entry_callstack_top);\n\twhile (thr->callstack_curr != entry_act) {\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tduk_hthread_activation_unwind_norz(thr);\n\t}\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\n\t/* Switch active thread before any side effects to avoid a\n\t * dangling curr_thread pointer.\n\t */\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread);  /* may be NULL */\n\tthr->state = (duk_uint8_t) entry_thread_state;\n\n\tDUK_ASSERT(thr->heap->curr_thread == entry_curr_thread);\n\tDUK_ASSERT(thr->state == entry_thread_state);\n\n\t/* Restore valstack bottom. */\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_bottom_byteoff);\n\n\t/* [ ... | (crud) ] */\n\n\t/* XXX: ensure space in valstack (now relies on internal reserve)? */\n\tduk_push_tval(thr, &thr->heap->lj.value1);\n\n\t/* [ ... | (crud) errobj ] */\n\n\tDUK_ASSERT(duk_get_top(thr) >= 1);  /* at least errobj must be on stack */\n\n\tduk__safe_call_adjust_valstack(thr, idx_retbase, num_stack_rets, 1);  /* 1 = num actual 'return values' */\n\n\t/* [ ... | ] or [ ... | errobj (M * undefined)] where M = num_stack_rets - 1 */\n\n\t/* Reset longjmp state. */\n\tthr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;\n\tthr->heap->lj.iserror = 0;\n\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, &thr->heap->lj.value1);\n\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, &thr->heap->lj.value2);\n\n\t/* Error handling complete, remove side effect protections.  Caller\n\t * will process pending finalizers.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->heap->error_not_allowed == 1);\n\tthr->heap->error_not_allowed = 0;\n#endif\n\tDUK_ASSERT(thr->heap->pf_prevent_count > 0);\n\tthr->heap->pf_prevent_count--;\n\tDUK_DD(DUK_DDPRINT(\"safe call error handled, pf_prevent_count updated to %ld\", (long) thr->heap->pf_prevent_count));\n\n\t/* thr->ptr_curr_pc is restored by\n\t * duk__handle_safe_call_shared_unwind() which is also used for\n\t * success path.\n\t */\n}\n\nDUK_LOCAL void duk__handle_safe_call_shared_unwind(duk_hthread *thr,\n                                                   duk_idx_t idx_retbase,\n                                                   duk_idx_t num_stack_rets,\n#if defined(DUK_USE_ASSERTIONS)\n                                                   duk_size_t entry_callstack_top,\n#endif\n                                                   duk_int_t entry_call_recursion_depth,\n                                                   duk_hthread *entry_curr_thread,\n                                                   duk_instr_t **entry_ptr_curr_pc) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(idx_retbase);\n\tDUK_UNREF(num_stack_rets);\n\tDUK_UNREF(entry_curr_thread);\n\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\n\t/* Restore entry thread executor curr_pc stack frame pointer.\n\t * XXX: would be enough to do in error path only, should nest\n\t * cleanly in success path.\n\t */\n\tthr->ptr_curr_pc = entry_ptr_curr_pc;\n\n\tthr->heap->call_recursion_depth = entry_call_recursion_depth;\n\n\t/* stack discipline consistency check */\n\tDUK_ASSERT(duk_get_top(thr) == idx_retbase + num_stack_rets);\n\n\t/* A debugger forced interrupt check is not needed here, as\n\t * problematic safe calls are not caused by side effects.\n\t */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\tduk__interrupt_fixup(thr, entry_curr_thread);\n#endif\n}\n\nDUK_INTERNAL duk_int_t duk_handle_safe_call(duk_hthread *thr,\n                                            duk_safe_call_function func,\n                                            void *udata,\n                                            duk_idx_t num_stack_args,\n                                            duk_idx_t num_stack_rets) {\n\tduk_activation *entry_act;\n\tduk_size_t entry_valstack_bottom_byteoff;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_size_t entry_valstack_end_byteoff;\n\tduk_size_t entry_callstack_top;\n\tduk_size_t entry_callstack_preventcount;\n#endif\n\tduk_int_t entry_call_recursion_depth;\n\tduk_hthread *entry_curr_thread;\n\tduk_uint_fast8_t entry_thread_state;\n\tduk_instr_t **entry_ptr_curr_pc;\n\tduk_jmpbuf *old_jmpbuf_ptr = NULL;\n\tduk_jmpbuf our_jmpbuf;\n\tduk_idx_t idx_retbase;\n\tduk_int_t retval;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(duk_get_top(thr) >= num_stack_args);  /* Caller ensures. */\n\n\tDUK_STATS_INC(thr->heap, stats_safecall_all);\n\n\t/* Value stack reserve handling: safe call assumes caller has reserved\n\t * space for nrets (assuming optimal unwind processing).  Value stack\n\t * reserve is not stored/restored as for normal calls because a safe\n\t * call conceptually happens in the same activation.\n\t */\n\n\t/* Careful with indices like '-x'; if 'x' is zero, it refers to bottom */\n\tentry_act = thr->callstack_curr;\n\tentry_valstack_bottom_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_valstack_end_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tentry_callstack_top = thr->callstack_top;\n\tentry_callstack_preventcount = thr->callstack_preventcount;\n#endif\n\tentry_call_recursion_depth = thr->heap->call_recursion_depth;\n\tentry_curr_thread = thr->heap->curr_thread;  /* may be NULL if first call */\n\tentry_thread_state = thr->state;\n\tentry_ptr_curr_pc = thr->ptr_curr_pc;  /* may be NULL */\n\tidx_retbase = duk_get_top(thr) - num_stack_args;  /* not a valid stack index if num_stack_args == 0 */\n\tDUK_ASSERT(idx_retbase >= 0);\n\n\tDUK_ASSERT((duk_idx_t) (thr->valstack_top - thr->valstack_bottom) >= num_stack_args);  /* Caller ensures. */\n\tDUK_ASSERT((duk_idx_t) (thr->valstack_end - (thr->valstack_bottom + idx_retbase)) >= num_stack_rets);  /* Caller ensures. */\n\n\t/* Cannot portably debug print a function pointer, hence 'func' not printed! */\n\tDUK_DD(DUK_DDPRINT(\"duk_handle_safe_call: thr=%p, num_stack_args=%ld, num_stack_rets=%ld, \"\n\t                   \"valstack_top=%ld, idx_retbase=%ld, rec_depth=%ld/%ld, \"\n\t                   \"entry_act=%p, entry_valstack_bottom_byteoff=%ld, entry_call_recursion_depth=%ld, \"\n\t                   \"entry_curr_thread=%p, entry_thread_state=%ld\",\n\t                   (void *) thr,\n\t                   (long) num_stack_args,\n\t                   (long) num_stack_rets,\n\t                   (long) duk_get_top(thr),\n\t                   (long) idx_retbase,\n\t                   (long) thr->heap->call_recursion_depth,\n\t                   (long) thr->heap->call_recursion_limit,\n\t                   (void *) entry_act,\n\t                   (long) entry_valstack_bottom_byteoff,\n\t                   (long) entry_call_recursion_depth,\n\t                   (void *) entry_curr_thread,\n\t                   (long) entry_thread_state));\n\n\t/* Setjmp catchpoint setup. */\n\told_jmpbuf_ptr = thr->heap->lj.jmpbuf_ptr;\n\tthr->heap->lj.jmpbuf_ptr = &our_jmpbuf;\n\n\t/* Prevent yields for the duration of the safe call.  This only\n\t * matters if the executor makes safe calls to functions that\n\t * yield, this doesn't currently happen.\n\t */\n\tthr->callstack_preventcount++;\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\ttry {\n#else\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr == &our_jmpbuf);\n\tif (DUK_SETJMP(our_jmpbuf.jb) == 0) {\n\t\t/* Success path. */\n#endif\n\t\tDUK_DDD(DUK_DDDPRINT(\"safe_call setjmp catchpoint setup complete\"));\n\n\t\tduk__handle_safe_call_inner(thr,\n\t\t                            func,\n\t\t                            udata,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t                            entry_valstack_bottom_byteoff,\n\t\t                            entry_callstack_top,\n#endif\n\t\t                            entry_curr_thread,\n\t\t                            entry_thread_state,\n\t\t                            idx_retbase,\n\t\t                            num_stack_rets);\n\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_nothrow);\n\n\t\t/* Either pointer may be NULL (at entry), so don't assert */\n\t\tthr->heap->lj.jmpbuf_ptr = old_jmpbuf_ptr;\n\n\t\t/* If calls happen inside the safe call, these are restored by\n\t\t * whatever calls are made.  Reserve cannot decrease.\n\t\t */\n\t\tDUK_ASSERT(thr->callstack_curr == entry_act);\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\n\t\tretval = DUK_EXEC_SUCCESS;\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t} catch (duk_internal_exception &exc) {\n\t\tDUK_UNREF(exc);\n#else\n\t} else {\n\t\t/* Error path. */\n#endif\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_throw);\n\n\t\tduk__handle_safe_call_error(thr,\n\t\t                            entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t                            entry_callstack_top,\n#endif\n\t\t                            entry_curr_thread,\n\t\t                            entry_thread_state,\n\t\t                            idx_retbase,\n\t\t                            num_stack_rets,\n\t\t                            entry_valstack_bottom_byteoff,\n\t\t                            old_jmpbuf_ptr);\n\n\t\tretval = DUK_EXEC_ERROR;\n\t}\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\tcatch (duk_fatal_exception &exc) {\n\t\tDUK_D(DUK_DPRINT(\"rethrow duk_fatal_exception\"));\n\t\tthrow;\n\t} catch (std::exception &exc) {\n\t\tconst char *what = exc.what();\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_throw);\n\t\tif (!what) {\n\t\t\twhat = \"unknown\";\n\t\t}\n\t\tDUK_D(DUK_DPRINT(\"unexpected c++ std::exception (perhaps thrown by user code)\"));\n\t\ttry {\n\t\t\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"caught invalid c++ std::exception '%s' (perhaps thrown by user code)\", what);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t} catch (duk_internal_exception exc) {\n\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ std::exception\"));\n\t\t\tDUK_UNREF(exc);\n\t\t\tduk__handle_safe_call_error(thr,\n\t\t\t                            entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t                            entry_callstack_top,\n#endif\n\t\t\t                            entry_curr_thread,\n\t\t\t                            entry_thread_state,\n\t\t\t                            idx_retbase,\n\t\t\t                            num_stack_rets,\n\t\t\t                            entry_valstack_bottom_byteoff,\n\t\t\t                            old_jmpbuf_ptr);\n\t\t\tretval = DUK_EXEC_ERROR;\n\t\t}\n\t} catch (...) {\n\t\tDUK_D(DUK_DPRINT(\"unexpected c++ exception (perhaps thrown by user code)\"));\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_throw);\n\t\ttry {\n\t\t\tDUK_ERROR_TYPE(thr, \"caught invalid c++ exception (perhaps thrown by user code)\");\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t} catch (duk_internal_exception exc) {\n\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ exception\"));\n\t\t\tDUK_UNREF(exc);\n\t\t\tduk__handle_safe_call_error(thr,\n\t\t\t                            entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t                            entry_callstack_top,\n#endif\n\t\t\t                            entry_curr_thread,\n\t\t\t                            entry_thread_state,\n\t\t\t                            idx_retbase,\n\t\t\t                            num_stack_rets,\n\t\t\t                            entry_valstack_bottom_byteoff,\n\t\t\t                            old_jmpbuf_ptr);\n\t\t\tretval = DUK_EXEC_ERROR;\n\t\t}\n\t}\n#endif\n\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr == old_jmpbuf_ptr);  /* success/error path both do this */\n\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\tduk__handle_safe_call_shared_unwind(thr,\n\t                                    idx_retbase,\n\t                                    num_stack_rets,\n#if defined(DUK_USE_ASSERTIONS)\n\t                                    entry_callstack_top,\n#endif\n\t                                    entry_call_recursion_depth,\n\t                                    entry_curr_thread,\n\t                                    entry_ptr_curr_pc);\n\n\t/* Restore preventcount. */\n\tthr->callstack_preventcount--;\n\tDUK_ASSERT(thr->callstack_preventcount == entry_callstack_preventcount);\n\n\t/* Final asserts. */\n\tDUK_ASSERT(thr->callstack_curr == entry_act);\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) == entry_valstack_bottom_byteoff);\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\tDUK_ASSERT(thr->heap->call_recursion_depth == entry_call_recursion_depth);\n\tDUK_ASSERT(thr->heap->curr_thread == entry_curr_thread);\n\tDUK_ASSERT(thr->state == entry_thread_state);\n\tDUK_ASSERT(thr->ptr_curr_pc == entry_ptr_curr_pc);\n\tDUK_ASSERT(duk_get_top(thr) == idx_retbase + num_stack_rets);\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\t/* Pending side effects. */\n\tDUK_REFZERO_CHECK_FAST(thr);\n\n\treturn retval;\n}\n\n/*\n *  Property-based call (foo.noSuch()) error setup: replace target function\n *  on stack top with a hidden Symbol tagged non-callable wrapper object\n *  holding the error.  The error gets thrown in call handling at the\n *  proper spot to follow ECMAScript semantics.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_INTERNAL DUK_NOINLINE DUK_COLD void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_base, duk_tval *tv_key) {\n\tconst char *str_targ, *str_key, *str_base;\n\tduk_idx_t entry_top;\n\n\tentry_top = duk_get_top(thr);\n\n\t/* [ <nargs> target ] */\n\n\t/* Must stabilize pointers first.  tv_targ is already on stack top. */\n\tduk_push_tval(thr, tv_base);\n\tduk_push_tval(thr, tv_key);\n\n\tDUK_GC_TORTURE(thr->heap);\n\n\tduk_push_bare_object(thr);\n\n\t/* [ <nargs> target base key {} ] */\n\n\t/* We only push a wrapped error, replacing the call target (at\n\t * idx_func) with the error to ensure side effects come out\n\t * correctly:\n\t * - Property read\n\t * - Call argument evaluation\n\t * - Callability check and error thrown\n\t *\n\t * A hidden Symbol on the wrapper object pushed above is used by\n\t * call handling to figure out the error is to be thrown as is.\n\t * It is CRITICAL that the hidden Symbol can never occur on a\n\t * user visible object that may get thrown.\n\t */\n\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tstr_targ = duk_get_type_name(thr, -4);\n\tstr_key = duk_get_type_name(thr, -2);\n\tstr_base = duk_get_type_name(thr, -3);\n\tduk_push_error_object(thr,\n\t                      DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t                      \"%s not callable (property %s of %s)\", str_targ, str_key, str_base);\n\tduk_xdef_prop_stridx(thr, -2, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE);  /* Marker property, reuse _Target. */\n\t/* [ <nargs> target base key { _Target: error } ] */\n\tduk_replace(thr, entry_top - 1);\n#else\n\tstr_targ = duk_push_string_readable(thr, -4);\n\tstr_key = duk_push_string_readable(thr, -3);\n\tstr_base = duk_push_string_readable(thr, -5);\n\tduk_push_error_object(thr,\n\t                      DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t                      \"%s not callable (property %s of %s)\", str_targ, str_key, str_base);\n\t/* [ <nargs> target base key {} str_targ str_key str_base error ] */\n\tduk_xdef_prop_stridx(thr, -5, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE);  /* Marker property, reuse _Target. */\n\t/* [ <nargs> target base key { _Target: error } str_targ str_key str_base ] */\n\tduk_swap(thr, -4, entry_top - 1);\n\t/* [ <nargs> { _Target: error } base key target str_targ str_key str_base ] */\n#endif\n\n\t/* [ <nregs> { _Target: error } <variable> */\n\tduk_set_top(thr, entry_top);\n\n\t/* [ <nregs> { _Target: error } */\n\tDUK_ASSERT(!duk_is_callable(thr, -1));  /* Critical so that call handling will throw the error. */\n}\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n/* automatic undefs */\n#undef DUK__AUGMENT_CALL_RELAX_COUNT\n#undef DUK__CALL_HANDLING_REQUIRE_STACK\n/*\n *  ECMAScript compiler.\n *\n *  Parses an input string and generates a function template result.\n *  Compilation may happen in multiple contexts (global code, eval\n *  code, function code).\n *\n *  The parser uses a traditional top-down recursive parsing for the\n *  statement level, and an operator precedence based top-down approach\n *  for the expression level.  The attempt is to minimize the C stack\n *  depth.  Bytecode is generated directly without an intermediate\n *  representation (tree), at the cost of needing two (and sometimes\n *  three) passes over each function.\n *\n *  The top-down recursive parser functions are named \"duk__parse_XXX\".\n *\n *  Recursion limits are in key functions to prevent arbitrary C recursion:\n *  function body parsing, statement parsing, and expression parsing.\n *\n *  See doc/compiler.rst for discussion on the design.\n *\n *  A few typing notes:\n *\n *    - duk_regconst_t: signed, highest bit set (< 0) means constant,\n *      some call sites use -1 for \"none\" (equivalent to constant 0x7fffffff)\n *    - PC values: duk_int_t, negative values used as markers\n */\n\n/* #include duk_internal.h -> already included */\n\n/* If highest bit of a register number is set, it refers to a constant instead.\n * When interpreted as a signed value, this means const values are always\n * negative (when interpreted as two's complement).  For example DUK__ISREG_TEMP()\n * uses this approach to avoid an explicit DUK__ISREG() check (the condition is\n * logically \"'x' is a register AND 'x' >= temp_first\").\n */\n#define DUK__CONST_MARKER                   DUK_REGCONST_CONST_MARKER\n#define DUK__REMOVECONST(x)                 ((x) & ~DUK__CONST_MARKER)\n#define DUK__ISREG(x)                       ((x) >= 0)\n#define DUK__ISCONST(x)                     ((x) < 0)\n#define DUK__ISREG_TEMP(comp_ctx,x)         ((duk_int32_t) (x) >= (duk_int32_t) ((comp_ctx)->curr_func.temp_first))   /* Check for x >= temp_first && x >= 0 by comparing as signed. */\n#define DUK__ISREG_NOTTEMP(comp_ctx,x)      ((duk_uint32_t) (x) < (duk_uint32_t) ((comp_ctx)->curr_func.temp_first))  /* Check for x >= 0 && x < temp_first by interpreting as unsigned. */\n#define DUK__GETTEMP(comp_ctx)              ((comp_ctx)->curr_func.temp_next)\n#define DUK__SETTEMP(comp_ctx,x)            ((comp_ctx)->curr_func.temp_next = (x))  /* dangerous: must only lower (temp_max not updated) */\n#define DUK__SETTEMP_CHECKMAX(comp_ctx,x)   duk__settemp_checkmax((comp_ctx),(x))\n#define DUK__ALLOCTEMP(comp_ctx)            duk__alloctemp((comp_ctx))\n#define DUK__ALLOCTEMPS(comp_ctx,count)     duk__alloctemps((comp_ctx),(count))\n\n/* Init value set size for array and object literals. */\n#define DUK__MAX_ARRAY_INIT_VALUES        20\n#define DUK__MAX_OBJECT_INIT_PAIRS        10\n\n/* XXX: hack, remove when const lookup is not O(n) */\n#define DUK__GETCONST_MAX_CONSTS_CHECK    256\n\n/* These limits are based on bytecode limits.  Max temps is limited\n * by duk_hcompfunc nargs/nregs fields being 16 bits.\n */\n#define DUK__MAX_CONSTS                   DUK_BC_BC_MAX\n#define DUK__MAX_FUNCS                    DUK_BC_BC_MAX\n#define DUK__MAX_TEMPS                    0xffffL\n\n/* Initial bytecode size allocation. */\n#if defined(DUK_USE_PREFER_SIZE)\n#define DUK__BC_INITIAL_INSTS             16\n#else\n#define DUK__BC_INITIAL_INSTS             256\n#endif\n\n#define DUK__RECURSION_INCREASE(comp_ctx,thr)  do { \\\n\t\tDUK_DDD(DUK_DDDPRINT(\"RECURSION INCREASE: %s:%ld\", (const char *) DUK_FILE_MACRO, (long) DUK_LINE_MACRO)); \\\n\t\tduk__comp_recursion_increase((comp_ctx)); \\\n\t} while (0)\n\n#define DUK__RECURSION_DECREASE(comp_ctx,thr)  do { \\\n\t\tDUK_DDD(DUK_DDDPRINT(\"RECURSION DECREASE: %s:%ld\", (const char *) DUK_FILE_MACRO, (long) DUK_LINE_MACRO)); \\\n\t\tduk__comp_recursion_decrease((comp_ctx)); \\\n\t} while (0)\n\n/* Value stack slot limits: these are quite approximate right now, and\n * because they overlap in control flow, some could be eliminated.\n */\n#define DUK__COMPILE_ENTRY_SLOTS          8\n#define DUK__FUNCTION_INIT_REQUIRE_SLOTS  16\n#define DUK__FUNCTION_BODY_REQUIRE_SLOTS  16\n#define DUK__PARSE_STATEMENTS_SLOTS       16\n#define DUK__PARSE_EXPR_SLOTS             16\n\n/* Temporary structure used to pass a stack allocated region through\n * duk_safe_call().\n */\ntypedef struct {\n\tduk_small_uint_t flags;\n\tduk_compiler_ctx comp_ctx_alloc;\n\tduk_lexer_point lex_pt_alloc;\n} duk__compiler_stkstate;\n\n/*\n *  Prototypes\n */\n\n/* lexing */\nDUK_LOCAL_DECL void duk__advance_helper(duk_compiler_ctx *comp_ctx, duk_small_int_t expect);\nDUK_LOCAL_DECL void duk__advance_expect(duk_compiler_ctx *comp_ctx, duk_small_int_t expect);\nDUK_LOCAL_DECL void duk__advance(duk_compiler_ctx *ctx);\n\n/* function helpers */\nDUK_LOCAL_DECL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ctx, duk_regconst_t *out_stmt_value_reg);\nDUK_LOCAL_DECL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx);\n\n/* code emission */\nDUK_LOCAL_DECL duk_int_t duk__get_current_pc(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_compiler_instr *duk__get_instr_ptr(duk_compiler_ctx *comp_ctx, duk_int_t pc);\nDUK_LOCAL_DECL void duk__emit(duk_compiler_ctx *comp_ctx, duk_instr_t ins);\nDUK_LOCAL_DECL void duk__emit_op_only(duk_compiler_ctx *comp_ctx, duk_small_uint_t op);\nDUK_LOCAL_DECL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b, duk_regconst_t c);\nDUK_LOCAL_DECL void duk__emit_a_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b);\nDUK_LOCAL_DECL void duk__emit_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b, duk_regconst_t c);\n#if 0  /* unused */\nDUK_LOCAL_DECL void duk__emit_a(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a);\nDUK_LOCAL_DECL void duk__emit_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b);\n#endif\nDUK_LOCAL_DECL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t bc);\nDUK_LOCAL_DECL void duk__emit_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t bc);\nDUK_LOCAL_DECL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t abc);\nDUK_LOCAL_DECL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val);\nDUK_LOCAL_DECL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val);\nDUK_LOCAL_DECL void duk__emit_jump(duk_compiler_ctx *comp_ctx, duk_int_t target_pc);\nDUK_LOCAL_DECL duk_int_t duk__emit_jump_empty(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc);\nDUK_LOCAL_DECL void duk__patch_jump(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc, duk_int_t target_pc);\nDUK_LOCAL_DECL void duk__patch_jump_here(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc);\nDUK_LOCAL_DECL void duk__patch_trycatch(duk_compiler_ctx *comp_ctx, duk_int_t ldconst_pc, duk_int_t trycatch_pc, duk_regconst_t reg_catch, duk_regconst_t const_varname, duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__emit_if_false_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst);\nDUK_LOCAL_DECL void duk__emit_if_true_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst);\nDUK_LOCAL_DECL void duk__emit_invalid(duk_compiler_ctx *comp_ctx);\n\n/* ivalue/ispec helpers */\nDUK_LOCAL_DECL void duk__ivalue_regconst(duk_ivalue *x, duk_regconst_t regconst);\nDUK_LOCAL_DECL void duk__ivalue_plain_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL void duk__ivalue_var_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL void duk__ivalue_var_hstring(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_hstring *h);\nDUK_LOCAL_DECL void duk__copy_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *src, duk_ispec *dst);\nDUK_LOCAL_DECL void duk__copy_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *src, duk_ivalue *dst);\nDUK_LOCAL_DECL duk_regconst_t duk__alloctemps(duk_compiler_ctx *comp_ctx, duk_small_int_t num);\nDUK_LOCAL_DECL duk_regconst_t duk__alloctemp(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, duk_regconst_t temp_next);\nDUK_LOCAL_DECL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL\nduk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                         duk_ispec *x,\n                                         duk_regconst_t forced_reg,\n                                         duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ispec *x, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL void duk__ivalue_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL void duk__ivalue_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL\nduk_regconst_t duk__ivalue_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                          duk_ivalue *x,\n                                          duk_regconst_t forced_reg,\n                                          duk_small_uint_t flags);\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\n#endif\nDUK_LOCAL_DECL void duk__ivalue_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_int_t forced_reg);\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\n\n/* identifier handling */\nDUK_LOCAL_DECL duk_regconst_t duk__lookup_active_register_binding(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *ctx, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname);\n\n/* label handling */\nDUK_LOCAL_DECL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_int_t pc_label, duk_int_t label_id);\nDUK_LOCAL_DECL void duk__update_label_flags(duk_compiler_ctx *comp_ctx, duk_int_t label_id, duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_bool_t is_break, duk_int_t *out_label_id, duk_int_t *out_label_catch_depth, duk_int_t *out_label_pc, duk_bool_t *out_is_closest);\nDUK_LOCAL_DECL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, duk_size_t len);\n\n/* top-down expression parser */\nDUK_LOCAL_DECL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_ivalue *res);\nDUK_LOCAL_DECL duk_small_uint_t duk__expr_lbp(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_bool_t duk__expr_is_empty(duk_compiler_ctx *comp_ctx);\n\n/* exprtop is the top level variant which resets nud/led counts */\nDUK_LOCAL_DECL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\nDUK_LOCAL_DECL void duk__exprtop(duk_compiler_ctx *ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n\n/* convenience helpers */\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__expr_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__expr_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\nDUK_LOCAL_DECL void duk__expr_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL duk_regconst_t duk__expr_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__expr_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\nDUK_LOCAL_DECL void duk__expr_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\nDUK_LOCAL_DECL void duk__expr_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\nDUK_LOCAL_DECL duk_regconst_t duk__exprtop_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__exprtop_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\nDUK_LOCAL_DECL void duk__exprtop_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL duk_regconst_t duk__exprtop_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#if 0  /* unused */\nDUK_LOCAL_DECL void duk__exprtop_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\n\n/* expression parsing helpers */\nDUK_LOCAL_DECL duk_int_t duk__parse_arguments(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\n\n/* statement parsing */\nDUK_LOCAL_DECL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname);\nDUK_LOCAL_DECL void duk__parse_var_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags);\nDUK_LOCAL_DECL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_if_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_do_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_while_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_break_or_continue_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_throw_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_bool_t allow_source_elem);\nDUK_LOCAL_DECL duk_int_t duk__stmt_label_site(duk_compiler_ctx *comp_ctx, duk_int_t label_id);\nDUK_LOCAL_DECL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_source_elem, duk_bool_t expect_eof, duk_bool_t regexp_after);\n\nDUK_LOCAL_DECL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expect_eof, duk_bool_t implicit_return_value, duk_bool_t regexp_after, duk_small_int_t expect_token);\nDUK_LOCAL_DECL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags);\nDUK_LOCAL_DECL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags);\n\n#define DUK__FUNC_FLAG_DECL            (1 << 0)   /* Parsing a function declaration. */\n#define DUK__FUNC_FLAG_GETSET          (1 << 1)   /* Parsing an object literal getter/setter. */\n#define DUK__FUNC_FLAG_METDEF          (1 << 2)   /* Parsing an object literal method definition shorthand. */\n#define DUK__FUNC_FLAG_PUSHNAME_PASS1  (1 << 3)   /* Push function name when creating template (first pass only). */\n#define DUK__FUNC_FLAG_USE_PREVTOKEN   (1 << 4)   /* Use prev_token to start function parsing (workaround for object literal). */\n\n/*\n *  Parser control values for tokens.  The token table is ordered by the\n *  DUK_TOK_XXX defines.\n *\n *  The binding powers are for lbp() use (i.e. for use in led() context).\n *  Binding powers are positive for typing convenience, and bits at the\n *  top should be reserved for flags.  Binding power step must be higher\n *  than 1 so that binding power \"lbp - 1\" can be used for right associative\n *  operators.  Currently a step of 2 is used (which frees one more bit for\n *  flags).\n */\n\n/* XXX: actually single step levels would work just fine, clean up */\n\n/* binding power \"levels\" (see doc/compiler.rst) */\n#define DUK__BP_INVALID                0             /* always terminates led() */\n#define DUK__BP_EOF                    2\n#define DUK__BP_CLOSING                4             /* token closes expression, e.g. ')', ']' */\n#define DUK__BP_FOR_EXPR               DUK__BP_CLOSING    /* bp to use when parsing a top level Expression */\n#define DUK__BP_COMMA                  6\n#define DUK__BP_ASSIGNMENT             8\n#define DUK__BP_CONDITIONAL            10\n#define DUK__BP_LOR                    12\n#define DUK__BP_LAND                   14\n#define DUK__BP_BOR                    16\n#define DUK__BP_BXOR                   18\n#define DUK__BP_BAND                   20\n#define DUK__BP_EQUALITY               22\n#define DUK__BP_RELATIONAL             24\n#define DUK__BP_SHIFT                  26\n#define DUK__BP_ADDITIVE               28\n#define DUK__BP_MULTIPLICATIVE         30\n#define DUK__BP_EXPONENTIATION         32\n#define DUK__BP_POSTFIX                34\n#define DUK__BP_CALL                   36\n#define DUK__BP_MEMBER                 38\n\n#define DUK__TOKEN_LBP_BP_MASK         0x1f\n#define DUK__TOKEN_LBP_FLAG_NO_REGEXP  (1 << 5)   /* regexp literal must not follow this token */\n#define DUK__TOKEN_LBP_FLAG_TERMINATES (1 << 6)   /* terminates expression; e.g. post-increment/-decrement */\n#define DUK__TOKEN_LBP_FLAG_UNUSED     (1 << 7)   /* unused */\n\n#define DUK__TOKEN_LBP_GET_BP(x)       ((duk_small_uint_t) (((x) & DUK__TOKEN_LBP_BP_MASK) * 2))\n\n#define DUK__MK_LBP(bp)                ((bp) >> 1)    /* bp is assumed to be even */\n#define DUK__MK_LBP_FLAGS(bp,flags)    (((bp) >> 1) | (flags))\n\nDUK_LOCAL const duk_uint8_t duk__token_lbp[] = {\n\tDUK__MK_LBP(DUK__BP_EOF),                                 /* DUK_TOK_EOF */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_IDENTIFIER */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_BREAK */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CASE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CATCH */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CONTINUE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DEBUGGER */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DEFAULT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DELETE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DO */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_ELSE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_FINALLY */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_FOR */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_FUNCTION */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_IF */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_IN */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_INSTANCEOF */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_NEW */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_RETURN */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SWITCH */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_THIS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_THROW */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_TRY */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_TYPEOF */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_VAR */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CONST */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_VOID */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_WHILE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_WITH */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CLASS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_ENUM */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_EXPORT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_EXTENDS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_IMPORT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SUPER */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_NULL */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_TRUE */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_FALSE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_GET */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SET */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_IMPLEMENTS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_INTERFACE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_LET */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PACKAGE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PRIVATE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PROTECTED */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PUBLIC */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_STATIC */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_YIELD */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_LCURLY */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_RCURLY */\n\tDUK__MK_LBP(DUK__BP_MEMBER),                              /* DUK_TOK_LBRACKET */\n\tDUK__MK_LBP_FLAGS(DUK__BP_CLOSING, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_RBRACKET */\n\tDUK__MK_LBP(DUK__BP_CALL),                                /* DUK_TOK_LPAREN */\n\tDUK__MK_LBP_FLAGS(DUK__BP_CLOSING, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_RPAREN */\n\tDUK__MK_LBP(DUK__BP_MEMBER),                              /* DUK_TOK_PERIOD */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SEMICOLON */\n\tDUK__MK_LBP(DUK__BP_COMMA),                               /* DUK_TOK_COMMA */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_LT */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_GT */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_LE */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_GE */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_EQ */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_NEQ */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_SEQ */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_SNEQ */\n\tDUK__MK_LBP(DUK__BP_ADDITIVE),                            /* DUK_TOK_ADD */\n\tDUK__MK_LBP(DUK__BP_ADDITIVE),                            /* DUK_TOK_SUB */\n\tDUK__MK_LBP(DUK__BP_MULTIPLICATIVE),                      /* DUK_TOK_MUL */\n\tDUK__MK_LBP(DUK__BP_MULTIPLICATIVE),                      /* DUK_TOK_DIV */\n\tDUK__MK_LBP(DUK__BP_MULTIPLICATIVE),                      /* DUK_TOK_MOD */\n\tDUK__MK_LBP(DUK__BP_EXPONENTIATION),                      /* DUK_TOK_EXP */\n\tDUK__MK_LBP_FLAGS(DUK__BP_POSTFIX, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_INCREMENT */\n\tDUK__MK_LBP_FLAGS(DUK__BP_POSTFIX, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_DECREMENT */\n\tDUK__MK_LBP(DUK__BP_SHIFT),                               /* DUK_TOK_ALSHIFT */\n\tDUK__MK_LBP(DUK__BP_SHIFT),                               /* DUK_TOK_ARSHIFT */\n\tDUK__MK_LBP(DUK__BP_SHIFT),                               /* DUK_TOK_RSHIFT */\n\tDUK__MK_LBP(DUK__BP_BAND),                                /* DUK_TOK_BAND */\n\tDUK__MK_LBP(DUK__BP_BOR),                                 /* DUK_TOK_BOR */\n\tDUK__MK_LBP(DUK__BP_BXOR),                                /* DUK_TOK_BXOR */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_LNOT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_BNOT */\n\tDUK__MK_LBP(DUK__BP_LAND),                                /* DUK_TOK_LAND */\n\tDUK__MK_LBP(DUK__BP_LOR),                                 /* DUK_TOK_LOR */\n\tDUK__MK_LBP(DUK__BP_CONDITIONAL),                         /* DUK_TOK_QUESTION */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_COLON */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_EQUALSIGN */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_ADD_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_SUB_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_MUL_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_DIV_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_MOD_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_EXP_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_ALSHIFT_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_ARSHIFT_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_RSHIFT_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_BAND_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_BOR_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_BXOR_EQ */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_NUMBER */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_STRING */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_REGEXP */\n};\n\n/*\n *  Misc helpers\n */\n\nDUK_LOCAL void duk__comp_recursion_increase(duk_compiler_ctx *comp_ctx) {\n\tDUK_ASSERT(comp_ctx != NULL);\n\tDUK_ASSERT(comp_ctx->recursion_depth >= 0);\n\tif (comp_ctx->recursion_depth >= comp_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_COMPILER_RECURSION_LIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tcomp_ctx->recursion_depth++;\n}\n\nDUK_LOCAL void duk__comp_recursion_decrease(duk_compiler_ctx *comp_ctx) {\n\tDUK_ASSERT(comp_ctx != NULL);\n\tDUK_ASSERT(comp_ctx->recursion_depth > 0);\n\tcomp_ctx->recursion_depth--;\n}\n\nDUK_LOCAL duk_bool_t duk__hstring_is_eval_or_arguments(duk_compiler_ctx *comp_ctx, duk_hstring *h) {\n\tDUK_UNREF(comp_ctx);\n\tDUK_ASSERT(h != NULL);\n\treturn DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(h);\n}\n\nDUK_LOCAL duk_bool_t duk__hstring_is_eval_or_arguments_in_strict_mode(duk_compiler_ctx *comp_ctx, duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n\treturn (comp_ctx->curr_func.is_strict &&\n\t        DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(h));\n}\n\n/*\n *  Parser duk__advance() token eating functions\n */\n\n/* XXX: valstack handling is awkward.  Add a valstack helper which\n * avoids dup():ing; valstack_copy(src, dst)?\n */\n\nDUK_LOCAL void duk__advance_helper(duk_compiler_ctx *comp_ctx, duk_small_int_t expect) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t regexp;\n\n\tDUK_ASSERT_DISABLE(comp_ctx->curr_token.t >= 0);  /* unsigned */\n\tDUK_ASSERT(comp_ctx->curr_token.t <= DUK_TOK_MAXVAL);  /* MAXVAL is inclusive */\n\n\t/*\n\t *  Use current token to decide whether a RegExp can follow.\n\t *\n\t *  We can use either 't' or 't_nores'; the latter would not\n\t *  recognize keywords.  Some keywords can be followed by a\n\t *  RegExp (e.g. \"return\"), so using 't' is better.  This is\n\t *  not trivial, see doc/compiler.rst.\n\t */\n\n\tregexp = 1;\n\tif (duk__token_lbp[comp_ctx->curr_token.t] & DUK__TOKEN_LBP_FLAG_NO_REGEXP) {\n\t\tregexp = 0;\n\t}\n\tif (comp_ctx->curr_func.reject_regexp_in_adv) {\n\t\tcomp_ctx->curr_func.reject_regexp_in_adv = 0;\n\t\tregexp = 0;\n\t}\n\tif (comp_ctx->curr_func.allow_regexp_in_adv) {\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 0;\n\t\tregexp = 1;\n\t}\n\n\tif (expect >= 0 && comp_ctx->curr_token.t != (duk_small_uint_t) expect) {\n\t\tDUK_D(DUK_DPRINT(\"parse error: expect=%ld, got=%ld\",\n\t\t                 (long) expect, (long) comp_ctx->curr_token.t));\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* make current token the previous; need to fiddle with valstack \"backing store\" */\n\tduk_memcpy(&comp_ctx->prev_token, &comp_ctx->curr_token, sizeof(duk_token));\n\tduk_copy(thr, comp_ctx->tok11_idx, comp_ctx->tok21_idx);\n\tduk_copy(thr, comp_ctx->tok12_idx, comp_ctx->tok22_idx);\n\n\t/* parse new token */\n\tduk_lexer_parse_js_input_element(&comp_ctx->lex,\n\t                                 &comp_ctx->curr_token,\n\t                                 comp_ctx->curr_func.is_strict,\n\t                                 regexp);\n\n\tDUK_DDD(DUK_DDDPRINT(\"advance: curr: tok=%ld/%ld,%ld,term=%ld,%!T,%!T \"\n\t                     \"prev: tok=%ld/%ld,%ld,term=%ld,%!T,%!T\",\n\t                     (long) comp_ctx->curr_token.t,\n\t                     (long) comp_ctx->curr_token.t_nores,\n\t                     (long) comp_ctx->curr_token.start_line,\n\t                     (long) comp_ctx->curr_token.lineterm,\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok11_idx),\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok12_idx),\n\t                     (long) comp_ctx->prev_token.t,\n\t                     (long) comp_ctx->prev_token.t_nores,\n\t                     (long) comp_ctx->prev_token.start_line,\n\t                     (long) comp_ctx->prev_token.lineterm,\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok21_idx),\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok22_idx)));\n}\n\n/* advance, expecting current token to be a specific token; parse next token in regexp context */\nDUK_LOCAL void duk__advance_expect(duk_compiler_ctx *comp_ctx, duk_small_int_t expect) {\n\tduk__advance_helper(comp_ctx, expect);\n}\n\n/* advance, whatever the current token is; parse next token in regexp context */\nDUK_LOCAL void duk__advance(duk_compiler_ctx *comp_ctx) {\n\tduk__advance_helper(comp_ctx, -1);\n}\n\n/*\n *  Helpers for duk_compiler_func.\n */\n\n/* init function state: inits valstack allocations */\nDUK_LOCAL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func = &comp_ctx->curr_func;\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_idx_t entry_top;\n\n\tentry_top = duk_get_top(thr);\n\n\tduk_memzero(func, sizeof(*func));  /* intentional overlap with earlier memzero */\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tfunc->h_name = NULL;\n\tfunc->h_consts = NULL;\n\tfunc->h_funcs = NULL;\n\tfunc->h_decls = NULL;\n\tfunc->h_labelnames = NULL;\n\tfunc->h_labelinfos = NULL;\n\tfunc->h_argnames = NULL;\n\tfunc->h_varmap = NULL;\n#endif\n\n\tduk_require_stack(thr, DUK__FUNCTION_INIT_REQUIRE_SLOTS);\n\n\tDUK_BW_INIT_PUSHBUF(thr, &func->bw_code, DUK__BC_INITIAL_INSTS * sizeof(duk_compiler_instr));\n\t/* code_idx = entry_top + 0 */\n\n\tduk_push_bare_array(thr);\n\tfunc->consts_idx = entry_top + 1;\n\tfunc->h_consts = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 1);\n\tDUK_ASSERT(func->h_consts != NULL);\n\n\tduk_push_bare_array(thr);\n\tfunc->funcs_idx = entry_top + 2;\n\tfunc->h_funcs = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 2);\n\tDUK_ASSERT(func->h_funcs != NULL);\n\tDUK_ASSERT(func->fnum_next == 0);\n\n\tduk_push_bare_array(thr);\n\tfunc->decls_idx = entry_top + 3;\n\tfunc->h_decls = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 3);\n\tDUK_ASSERT(func->h_decls != NULL);\n\n\tduk_push_bare_array(thr);\n\tfunc->labelnames_idx = entry_top + 4;\n\tfunc->h_labelnames = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 4);\n\tDUK_ASSERT(func->h_labelnames != NULL);\n\n\tduk_push_dynamic_buffer(thr, 0);\n\tfunc->labelinfos_idx = entry_top + 5;\n\tfunc->h_labelinfos = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, entry_top + 5);\n\tDUK_ASSERT(func->h_labelinfos != NULL);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(func->h_labelinfos) && !DUK_HBUFFER_HAS_EXTERNAL(func->h_labelinfos));\n\n\tduk_push_bare_array(thr);\n\tfunc->argnames_idx = entry_top + 6;\n\tfunc->h_argnames = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 6);\n\tDUK_ASSERT(func->h_argnames != NULL);\n\n\tduk_push_bare_object(thr);\n\tfunc->varmap_idx = entry_top + 7;\n\tfunc->h_varmap = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 7);\n\tDUK_ASSERT(func->h_varmap != NULL);\n}\n\n/* reset function state (prepare for pass 2) */\nDUK_LOCAL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func = &comp_ctx->curr_func;\n\tduk_hthread *thr = comp_ctx->thr;\n\n\t/* reset bytecode buffer but keep current size; pass 2 will\n\t * require same amount or more.\n\t */\n\tDUK_BW_RESET_SIZE(thr, &func->bw_code);\n\n\tduk_set_length(thr, func->consts_idx, 0);\n\t/* keep func->h_funcs; inner functions are not reparsed to avoid O(depth^2) parsing */\n\tfunc->fnum_next = 0;\n\t/* duk_set_length(thr, func->funcs_idx, 0); */\n\tduk_set_length(thr, func->labelnames_idx, 0);\n\tduk_hbuffer_reset(thr, func->h_labelinfos);\n\t/* keep func->h_argnames; it is fixed for all passes */\n\n\t/* truncated in case pass 3 needed */\n\tduk_push_bare_object(thr);\n\tduk_replace(thr, func->varmap_idx);\n\tfunc->h_varmap = DUK_GET_HOBJECT_POSIDX(thr, func->varmap_idx);\n\tDUK_ASSERT(func->h_varmap != NULL);\n}\n\n/* cleanup varmap from any null entries, compact it, etc; returns number\n * of final entries after cleanup.\n */\nDUK_LOCAL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hobject *h_varmap;\n\tduk_hstring *h_key;\n\tduk_tval *tv;\n\tduk_uint32_t i, e_next;\n\tduk_int_t ret;\n\n\t/* [ ... varmap ] */\n\n\th_varmap = DUK_GET_HOBJECT_NEGIDX(thr, -1);\n\tDUK_ASSERT(h_varmap != NULL);\n\n\tret = 0;\n\te_next = DUK_HOBJECT_GET_ENEXT(h_varmap);\n\tfor (i = 0; i < e_next; i++) {\n\t\th_key = DUK_HOBJECT_E_GET_KEY(thr->heap, h_varmap, i);\n\t\tif (!h_key) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, h_varmap, i));\n\n\t\t/* The entries can either be register numbers or 'null' values.\n\t\t * Thus, no need to DECREF them and get side effects.  DECREF'ing\n\t\t * the keys (strings) can cause memory to be freed but no side\n\t\t * effects as strings don't have finalizers.  This is why we can\n\t\t * rely on the object properties not changing from underneath us.\n\t\t */\n\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, h_varmap, i);\n\t\tif (!DUK_TVAL_IS_NUMBER(tv)) {\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv));\n\t\t\tDUK_HOBJECT_E_SET_KEY(thr->heap, h_varmap, i, NULL);\n\t\t\tDUK_HSTRING_DECREF(thr, h_key);\n\t\t\t/* when key is NULL, value is garbage so no need to set */\n\t\t} else {\n\t\t\tret++;\n\t\t}\n\t}\n\n\tduk_compact_m1(thr);\n\n\treturn ret;\n}\n\n/* Convert duk_compiler_func into a function template, leaving the result\n * on top of stack.\n */\n/* XXX: awkward and bloated asm -- use faster internal accesses */\nDUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func = &comp_ctx->curr_func;\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hcompfunc *h_res;\n\tduk_hbuffer_fixed *h_data;\n\tduk_size_t consts_count;\n\tduk_size_t funcs_count;\n\tduk_size_t code_count;\n\tduk_size_t code_size;\n\tduk_size_t data_size;\n\tduk_size_t i;\n\tduk_tval *p_const;\n\tduk_hobject **p_func;\n\tduk_instr_t *p_instr;\n\tduk_compiler_instr *q_instr;\n\tduk_tval *tv;\n\tduk_bool_t keep_varmap;\n\tduk_bool_t keep_formals;\n#if !defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_size_t formals_length;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"converting duk_compiler_func to function/template\"));\n\n\t/*\n\t *  Push result object and init its flags\n\t */\n\n\t/* Valstack should suffice here, required on function valstack init */\n\n\th_res = duk_push_hcompfunc(thr);\n\tDUK_ASSERT(h_res != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_res) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, (duk_hobject *) h_res, NULL);  /* Function templates are \"bare objects\". */\n\n\tif (func->is_function) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function -> set NEWENV\"));\n\t\tDUK_HOBJECT_SET_NEWENV((duk_hobject *) h_res);\n\n\t\tif (!func->is_arguments_shadowed) {\n\t\t\t/* arguments object would be accessible; note that shadowing\n\t\t\t * bindings are arguments or function declarations, neither\n\t\t\t * of which are deletable, so this is safe.\n\t\t\t */\n\n\t\t\tif (func->id_access_arguments || func->may_direct_eval) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"function may access 'arguments' object directly or \"\n\t\t\t\t                     \"indirectly -> set CREATEARGS\"));\n\t\t\t\tDUK_HOBJECT_SET_CREATEARGS((duk_hobject *) h_res);\n\t\t\t}\n\t\t}\n\t} else if (func->is_eval && func->is_strict) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"strict eval code -> set NEWENV\"));\n\t\tDUK_HOBJECT_SET_NEWENV((duk_hobject *) h_res);\n\t} else {\n\t\t/* non-strict eval: env is caller's env or global env (direct vs. indirect call)\n\t\t * global code: env is is global env\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-strict eval code or global code -> no NEWENV\"));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV((duk_hobject *) h_res));\n\t}\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tif (func->is_function && func->is_namebinding && func->h_name != NULL) {\n\t\t/* Object literal set/get functions have a name (property\n\t\t * name) but must not have a lexical name binding, see\n\t\t * test-bug-getset-func-name.js.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"function expression with a name -> set NAMEBINDING\"));\n\t\tDUK_HOBJECT_SET_NAMEBINDING((duk_hobject *) h_res);\n\t}\n#endif\n\n\tif (func->is_strict) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is strict -> set STRICT\"));\n\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_res);\n\t}\n\n\tif (func->is_notail) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is notail -> set NOTAIL\"));\n\t\tDUK_HOBJECT_SET_NOTAIL((duk_hobject *) h_res);\n\t}\n\n\tif (func->is_constructable) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is constructable -> set CONSTRUCTABLE\"));\n\t\tDUK_HOBJECT_SET_CONSTRUCTABLE((duk_hobject *) h_res);\n\t}\n\n\t/*\n\t *  Build function fixed size 'data' buffer, which contains bytecode,\n\t *  constants, and inner function references.\n\t *\n\t *  During the building phase 'data' is reachable but incomplete.\n\t *  Only incref's occur during building (no refzero or GC happens),\n\t *  so the building process is atomic.\n\t */\n\n\tconsts_count = duk_hobject_get_length(thr, func->h_consts);\n\tfuncs_count = duk_hobject_get_length(thr, func->h_funcs) / 3;\n\tcode_count = DUK_BW_GET_SIZE(thr, &func->bw_code) / sizeof(duk_compiler_instr);\n\tcode_size = code_count * sizeof(duk_instr_t);\n\n\tdata_size = consts_count * sizeof(duk_tval) +\n\t            funcs_count * sizeof(duk_hobject *) +\n\t            code_size;\n\n\tDUK_DDD(DUK_DDDPRINT(\"consts_count=%ld, funcs_count=%ld, code_size=%ld -> \"\n\t                     \"data_size=%ld*%ld + %ld*%ld + %ld = %ld\",\n\t                     (long) consts_count, (long) funcs_count, (long) code_size,\n\t                     (long) consts_count, (long) sizeof(duk_tval),\n\t                     (long) funcs_count, (long) sizeof(duk_hobject *),\n\t                     (long) code_size, (long) data_size));\n\n\tduk_push_fixed_buffer_nozero(thr, data_size);\n\th_data = (duk_hbuffer_fixed *) (void *) duk_known_hbuffer(thr, -1);\n\n\tDUK_HCOMPFUNC_SET_DATA(thr->heap, h_res, (duk_hbuffer *) h_data);\n\tDUK_HEAPHDR_INCREF(thr, h_data);\n\n\tp_const = (duk_tval *) (void *) DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, h_data);\n\tfor (i = 0; i < consts_count; i++) {\n\t\tDUK_ASSERT(i <= DUK_UARRIDX_MAX);  /* const limits */\n\t\ttv = duk_hobject_find_array_entry_tval_ptr(thr->heap, func->h_consts, (duk_uarridx_t) i);\n\t\tDUK_ASSERT(tv != NULL);\n\t\tDUK_TVAL_SET_TVAL(p_const, tv);\n\t\tp_const++;\n\t\tDUK_TVAL_INCREF(thr, tv);  /* may be a string constant */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"constant: %!T\", (duk_tval *) tv));\n\t}\n\n\tp_func = (duk_hobject **) p_const;\n\tDUK_HCOMPFUNC_SET_FUNCS(thr->heap, h_res, p_func);\n\tfor (i = 0; i < funcs_count; i++) {\n\t\tduk_hobject *h;\n\t\tDUK_ASSERT(i * 3 <= DUK_UARRIDX_MAX);  /* func limits */\n\t\ttv = duk_hobject_find_array_entry_tval_ptr(thr->heap, func->h_funcs, (duk_uarridx_t) (i * 3));\n\t\tDUK_ASSERT(tv != NULL);\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(h));\n\t\t*p_func++ = h;\n\t\tDUK_HOBJECT_INCREF(thr, h);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"inner function: %p -> %!iO\",\n\t\t                     (void *) h, (duk_heaphdr *) h));\n\t}\n\n\tp_instr = (duk_instr_t *) p_func;\n\tDUK_HCOMPFUNC_SET_BYTECODE(thr->heap, h_res, p_instr);\n\n\t/* copy bytecode instructions one at a time */\n\tq_instr = (duk_compiler_instr *) (void *) DUK_BW_GET_BASEPTR(thr, &func->bw_code);\n\tfor (i = 0; i < code_count; i++) {\n\t\tp_instr[i] = q_instr[i].ins;\n\t}\n\t/* Note: 'q_instr' is still used below */\n\n\tDUK_ASSERT((duk_uint8_t *) (p_instr + code_count) == DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, h_data) + data_size);\n\n\tduk_pop(thr);  /* 'data' (and everything in it) is reachable through h_res now */\n\n\t/*\n\t *  Init non-property result fields\n\t *\n\t *  'nregs' controls how large a register frame is allocated.\n\t *\n\t *  'nargs' controls how many formal arguments are written to registers:\n\t *  r0, ... r(nargs-1).  The remaining registers are initialized to\n\t *  undefined.\n\t */\n\n\tDUK_ASSERT(func->temp_max >= 0);\n\th_res->nregs = (duk_uint16_t) func->temp_max;\n\th_res->nargs = (duk_uint16_t) duk_hobject_get_length(thr, func->h_argnames);\n\tDUK_ASSERT(h_res->nregs >= h_res->nargs);  /* pass2 allocation handles this */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\th_res->start_line = (duk_uint32_t) func->min_line;\n\th_res->end_line = (duk_uint32_t) func->max_line;\n#endif\n\n\t/*\n\t *  Init object properties\n\t *\n\t *  Properties should be added in decreasing order of access frequency.\n\t *  (Not very critical for function templates.)\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"init function properties\"));\n\n\t/* [ ... res ] */\n\n\t/* _Varmap: omitted if function is guaranteed not to do a slow path\n\t * identifier access that might be caught by locally declared variables.\n\t * The varmap can also be omitted if it turns out empty of actual\n\t * register mappings after a cleanup.  When debugging is enabled, we\n\t * always need the varmap to be able to lookup variables at any point.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tDUK_DD(DUK_DDPRINT(\"keeping _Varmap because debugger support is enabled\"));\n\tkeep_varmap = 1;\n#else\n\tif (func->id_access_slow_own ||   /* directly uses slow accesses that may match own variables */\n\t    func->id_access_arguments ||  /* accesses 'arguments' directly */\n\t    func->may_direct_eval ||      /* may indirectly slow access through a direct eval */\n\t    funcs_count > 0) {            /* has inner functions which may slow access (XXX: this can be optimized by looking at the inner functions) */\n\t\tDUK_DD(DUK_DDPRINT(\"keeping _Varmap because of direct eval, slow path access that may match local variables, or presence of inner functions\"));\n\t\tkeep_varmap = 1;\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"dropping _Varmap\"));\n\t\tkeep_varmap = 0;\n\t}\n#endif\n\n\tif (keep_varmap) {\n\t\tduk_int_t num_used;\n\t\tduk_dup(thr, func->varmap_idx);\n\t\tnum_used = duk__cleanup_varmap(comp_ctx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"cleaned up varmap: %!T (num_used=%ld)\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) num_used));\n\n\t\tif (num_used > 0) {\n\t\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VARMAP, DUK_PROPDESC_FLAGS_NONE);\n\t\t} else {\n\t\t\tDUK_DD(DUK_DDPRINT(\"varmap is empty after cleanup -> no need to add\"));\n\t\t\tduk_pop(thr);\n\t\t}\n\t}\n\n\t/* _Formals: omitted if function is guaranteed not to need a (non-strict)\n\t * arguments object, and _Formals.length matches nargs exactly.\n\t *\n\t * Non-arrow functions can't see an outer function's 'argument' binding\n\t * (because they have their own), but arrow functions can.  When arrow\n\t * functions are added, this condition would need to be added:\n\t *     inner_arrow_funcs_count > 0   inner arrow functions may access 'arguments'\n\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tDUK_DD(DUK_DDPRINT(\"keeping _Formals because debugger support is enabled\"));\n\tkeep_formals = 1;\n#else\n\tformals_length = duk_get_length(thr, func->argnames_idx);\n\tif (formals_length != (duk_size_t) h_res->nargs) {\n\t\t/* Nargs not enough for closure .length: keep _Formals regardless\n\t\t * of its length.  Shouldn't happen in practice at the moment.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"keeping _Formals because _Formals.length != nargs\"));\n\t\tkeep_formals = 1;\n\t} else if ((func->id_access_arguments || func->may_direct_eval) &&\n\t           (formals_length > 0)) {\n\t\t/* Direct eval (may access 'arguments') or accesses 'arguments'\n\t\t * explicitly: keep _Formals unless it is zero length.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"keeping _Formals because of direct eval or explicit access to 'arguments', and _Formals.length != 0\"));\n\t\tkeep_formals = 1;\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"omitting _Formals, nargs matches _Formals.length, so no properties added\"));\n\t\tkeep_formals = 0;\n\t}\n#endif\n\n\tif (keep_formals) {\n\t\tduk_dup(thr, func->argnames_idx);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_FORMALS, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\n\t/* name */\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tif (func->h_name) {\n\t\tduk_push_hstring(thr, func->h_name);\n\t\tDUK_DD(DUK_DDPRINT(\"setting function template .name to %!T\", duk_get_tval(thr, -1)));\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_NONE);\n\t}\n#endif  /* DUK_USE_FUNC_NAME_PROPERTY */\n\n\t/* _Source */\n#if defined(DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY)\n\tif (0) {\n\t\t/* XXX: Currently function source code is not stored, as it is not\n\t\t * required by the standard.  Source code should not be stored by\n\t\t * default (user should enable it explicitly), and the source should\n\t\t * probably be compressed with a trivial text compressor; average\n\t\t * compression of 20-30% is quite easy to achieve even with a trivial\n\t\t * compressor (RLE + backwards lookup).\n\t\t *\n\t\t * Debugging needs source code to be useful: sometimes input code is\n\t\t * not found in files as it may be generated and then eval()'d, given\n\t\t * by dynamic C code, etc.\n\t\t *\n\t\t * Other issues:\n\t\t *\n\t\t *   - Need tokenizer indices for start and end to substring\n\t\t *   - Always normalize function declaration part?\n\t\t *   - If we keep _Formals, only need to store body\n\t\t */\n\n\t\t/*\n\t\t *  For global or eval code this is straightforward.  For functions\n\t\t *  created with the Function constructor we only get the source for\n\t\t *  the body and must manufacture the \"function ...\" part.\n\t\t *\n\t\t *  For instance, for constructed functions (v8):\n\t\t *\n\t\t *    > a = new Function(\"foo\", \"bar\", \"print(foo)\");\n\t\t *    [Function]\n\t\t *    > a.toString()\n\t\t *    'function anonymous(foo,bar) {\\nprint(foo)\\n}'\n\t\t *\n\t\t *  Similarly for e.g. getters (v8):\n\t\t *\n\t\t *    > x = { get a(foo,bar) { print(foo); } }\n\t\t *    { a: [Getter] }\n\t\t *    > Object.getOwnPropertyDescriptor(x, 'a').get.toString()\n\t\t *    'function a(foo,bar) { print(foo); }'\n\t\t */\n\n#if 0\n\t\tduk_push_literal(thr, \"XXX\");\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_SOURCE, DUK_PROPDESC_FLAGS_NONE);\n#endif\n\t}\n#endif  /* DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY */\n\n\t/* _Pc2line */\n#if defined(DUK_USE_PC2LINE)\n\tif (1) {\n\t\t/*\n\t\t *  Size-optimized pc->line mapping.\n\t\t */\n\n\t\tDUK_ASSERT(code_count <= DUK_COMPILER_MAX_BYTECODE_LENGTH);\n\t\tduk_hobject_pc2line_pack(thr, q_instr, (duk_uint_fast32_t) code_count);  /* -> pushes fixed buffer */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_NONE);\n\n\t\t/* XXX: if assertions enabled, walk through all valid PCs\n\t\t * and check line mapping.\n\t\t */\n\t}\n#endif  /* DUK_USE_PC2LINE */\n\n\t/* fileName */\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tif (comp_ctx->h_filename) {\n\t\t/*\n\t\t *  Source filename (or equivalent), for identifying thrown errors.\n\t\t */\n\n\t\tduk_push_hstring(thr, comp_ctx->h_filename);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_NONE);\n\t}\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"converted function: %!ixT\",\n\t                   (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/*\n\t *  Compact the function template.\n\t */\n\n\tduk_compact_m1(thr);\n\n\t/*\n\t *  Debug dumping\n\t */\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t{\n\t\tduk_hcompfunc *h;\n\t\tduk_instr_t *p, *p_start, *p_end;\n\n\t\th = (duk_hcompfunc *) duk_get_hobject(thr, -1);\n\t\tp_start = (duk_instr_t *) DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, h);\n\t\tp_end = (duk_instr_t *) DUK_HCOMPFUNC_GET_CODE_END(thr->heap, h);\n\n\t\tp = p_start;\n\t\twhile (p < p_end) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"BC %04ld: %!I        ; 0x%08lx op=%ld (%!X) a=%ld b=%ld c=%ld\",\n\t\t\t                     (long) (p - p_start),\n\t\t\t                     (duk_instr_t) (*p),\n\t\t\t                     (unsigned long) (*p),\n\t\t\t                     (long) DUK_DEC_OP(*p),\n\t\t\t                     (long) DUK_DEC_OP(*p),\n\t\t\t                     (long) DUK_DEC_A(*p),\n\t\t\t                     (long) DUK_DEC_B(*p),\n\t\t\t                     (long) DUK_DEC_C(*p)));\n\t\t\tp++;\n\t\t}\n\t}\n#endif\n}\n\n/*\n *  Code emission helpers\n *\n *  Some emission helpers understand the range of target and source reg/const\n *  values and automatically emit shuffling code if necessary.  This is the\n *  case when the slot in question (A, B, C) is used in the standard way and\n *  for opcodes the emission helpers explicitly understand (like DUK_OP_MPUTOBJ).\n *\n *  The standard way is that:\n *    - slot A is a target register\n *    - slot B is a source register/constant\n *    - slot C is a source register/constant\n *\n *  If a slot is used in a non-standard way the caller must indicate this\n *  somehow.  If a slot is used as a target instead of a source (or vice\n *  versa), this can be indicated with a flag to trigger proper shuffling\n *  (e.g. DUK__EMIT_FLAG_B_IS_TARGET).  If the value in the slot is not\n *  register/const related at all, the caller must ensure that the raw value\n *  fits into the corresponding slot so as to not trigger shuffling.  The\n *  caller must set a \"no shuffle\" flag to ensure compilation fails if\n *  shuffling were to be triggered because of an internal error.\n *\n *  For slots B and C the raw slot size is 9 bits but one bit is reserved for\n *  the reg/const indicator.  To use the full 9-bit range for a raw value,\n *  shuffling must be disabled with the DUK__EMIT_FLAG_NO_SHUFFLE_{B,C} flag.\n *  Shuffling is only done for A, B, and C slots, not the larger BC or ABC slots.\n *\n *  There is call handling specific understanding in the A-B-C emitter to\n *  convert call setup and call instructions into indirect ones if necessary.\n */\n\n/* Code emission flags, passed in the 'opcode' field.  Opcode + flags\n * fit into 16 bits for now, so use duk_small_uint_t.\n */\n#define DUK__EMIT_FLAG_NO_SHUFFLE_A      (1 << 8)\n#define DUK__EMIT_FLAG_NO_SHUFFLE_B      (1 << 9)\n#define DUK__EMIT_FLAG_NO_SHUFFLE_C      (1 << 10)\n#define DUK__EMIT_FLAG_A_IS_SOURCE       (1 << 11)  /* slot A is a source (default: target) */\n#define DUK__EMIT_FLAG_B_IS_TARGET       (1 << 12)  /* slot B is a target (default: source) */\n#define DUK__EMIT_FLAG_C_IS_TARGET       (1 << 13)  /* slot C is a target (default: source) */\n#define DUK__EMIT_FLAG_BC_REGCONST       (1 << 14)  /* slots B and C are reg/const */\n#define DUK__EMIT_FLAG_RESERVE_JUMPSLOT  (1 << 15)  /* reserve a jumpslot after instr before target spilling, used for NEXTENUM */\n\n/* XXX: macro smaller than call? */\nDUK_LOCAL duk_int_t duk__get_current_pc(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func;\n\tfunc = &comp_ctx->curr_func;\n\treturn (duk_int_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &func->bw_code) / sizeof(duk_compiler_instr));\n}\n\nDUK_LOCAL duk_compiler_instr *duk__get_instr_ptr(duk_compiler_ctx *comp_ctx, duk_int_t pc) {\n\tDUK_ASSERT(pc >= 0);\n\tDUK_ASSERT((duk_size_t) pc < (duk_size_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr)));\n\treturn ((duk_compiler_instr *) (void *) DUK_BW_GET_BASEPTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code)) + pc;\n}\n\n/* emit instruction; could return PC but that's not needed in the majority\n * of cases.\n */\nDUK_LOCAL void duk__emit(duk_compiler_ctx *comp_ctx, duk_instr_t ins) {\n#if defined(DUK_USE_PC2LINE)\n\tduk_int_t line;\n#endif\n\tduk_compiler_instr *instr;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__emit: 0x%08lx curr_token.start_line=%ld prev_token.start_line=%ld pc=%ld --> %!I\",\n\t                     (unsigned long) ins,\n\t                     (long) comp_ctx->curr_token.start_line,\n\t                     (long) comp_ctx->prev_token.start_line,\n\t                     (long) duk__get_current_pc(comp_ctx),\n\t                     (duk_instr_t) ins));\n\n\tinstr = (duk_compiler_instr *) (void *) DUK_BW_ENSURE_GETPTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, sizeof(duk_compiler_instr));\n\tDUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, sizeof(duk_compiler_instr));\n\n#if defined(DUK_USE_PC2LINE)\n\t/* The line number tracking is a bit inconsistent right now, which\n\t * affects debugger accuracy.  Mostly call sites emit opcodes when\n\t * they have parsed a token (say a terminating semicolon) and called\n\t * duk__advance().  In this case the line number of the previous\n\t * token is the most accurate one (except in prologue where\n\t * prev_token.start_line is 0).  This is probably not 100% correct\n\t * right now.\n\t */\n\t/* approximation, close enough */\n\tline = comp_ctx->prev_token.start_line;\n\tif (line == 0) {\n\t\tline = comp_ctx->curr_token.start_line;\n\t}\n#endif\n\n\tinstr->ins = ins;\n#if defined(DUK_USE_PC2LINE)\n\tinstr->line = (duk_uint32_t) line;\n#endif\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (line < comp_ctx->curr_func.min_line) {\n\t\tcomp_ctx->curr_func.min_line = line;\n\t}\n\tif (line > comp_ctx->curr_func.max_line) {\n\t\tcomp_ctx->curr_func.max_line = line;\n\t}\n#endif\n\n\t/* Limit checks for bytecode byte size and line number. */\n\tif (DUK_UNLIKELY(DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) > DUK_USE_ESBC_MAX_BYTES)) {\n\t\tgoto fail_bc_limit;\n\t}\n#if defined(DUK_USE_PC2LINE) && defined(DUK_USE_ESBC_LIMITS)\n#if defined(DUK_USE_BUFLEN16)\n\t/* Buffer length is bounded to 0xffff automatically, avoid compile warning. */\n\tif (DUK_UNLIKELY(line > DUK_USE_ESBC_MAX_LINENUMBER)) {\n\t\tgoto fail_bc_limit;\n\t}\n#else\n\tif (DUK_UNLIKELY(line > DUK_USE_ESBC_MAX_LINENUMBER)) {\n\t\tgoto fail_bc_limit;\n\t}\n#endif\n#endif\n\n\treturn;\n\n  fail_bc_limit:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_BYTECODE_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Update function min/max line from current token.  Needed to improve\n * function line range information for debugging, so that e.g. opening\n * curly brace is covered by line range even when no opcodes are emitted\n * for the line containing the brace.\n */\nDUK_LOCAL void duk__update_lineinfo_currtoken(duk_compiler_ctx *comp_ctx) {\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_int_t line;\n\n\tline = comp_ctx->curr_token.start_line;\n\tif (line == 0) {\n\t\treturn;\n\t}\n\tif (line < comp_ctx->curr_func.min_line) {\n\t\tcomp_ctx->curr_func.min_line = line;\n\t}\n\tif (line > comp_ctx->curr_func.max_line) {\n\t\tcomp_ctx->curr_func.max_line = line;\n\t}\n#else\n\tDUK_UNREF(comp_ctx);\n#endif\n}\n\nDUK_LOCAL void duk__emit_op_only(duk_compiler_ctx *comp_ctx, duk_small_uint_t op) {\n\tduk__emit(comp_ctx, DUK_ENC_OP_ABC(op, 0));\n}\n\n/* Important main primitive. */\nDUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b, duk_regconst_t c) {\n\tduk_instr_t ins = 0;\n\tduk_int_t a_out = -1;\n\tduk_int_t b_out = -1;\n\tduk_int_t c_out = -1;\n\tduk_int_t tmp;\n\tduk_small_uint_t op = op_flags & 0xffU;\n\n\tDUK_DDD(DUK_DDDPRINT(\"emit: op_flags=%04lx, a=%ld, b=%ld, c=%ld\",\n\t                     (unsigned long) op_flags, (long) a, (long) b, (long) c));\n\n\t/* We could rely on max temp/const checks: if they don't exceed BC\n\t * limit, nothing here can either (just asserts would be enough).\n\t * Currently we check for the limits, which provides additional\n\t * protection against creating invalid bytecode due to compiler\n\t * bugs.\n\t */\n\n\tDUK_ASSERT_DISABLE((op_flags & 0xff) >= DUK_BC_OP_MIN);  /* unsigned */\n\tDUK_ASSERT((op_flags & 0xff) <= DUK_BC_OP_MAX);\n\tDUK_ASSERT(DUK__ISREG(a));\n\tDUK_ASSERT(b != -1);  /* Not 'none'. */\n\tDUK_ASSERT(c != -1);  /* Not 'none'. */\n\n\t/* Input shuffling happens before the actual operation, while output\n\t * shuffling happens afterwards.  Output shuffling decisions are still\n\t * made at the same time to reduce branch clutter; output shuffle decisions\n\t * are recorded into X_out variables.\n\t */\n\n\t/* Slot A: currently no support for reg/const. */\n\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\tif (a <= DUK_BC_A_MAX && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A)) {\n#else\n\tif (a <= DUK_BC_A_MAX) {\n#endif\n\t\t;\n\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A) {\n\t\tDUK_D(DUK_DPRINT(\"out of regs: 'a' (reg) needs shuffling but shuffle prohibited, a: %ld\", (long) a));\n\t\tgoto error_outofregs;\n\t} else if (a <= DUK_BC_BC_MAX) {\n\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\ttmp = comp_ctx->curr_func.shuffle1;\n\t\tif (op_flags & DUK__EMIT_FLAG_A_IS_SOURCE) {\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, a));\n\t\t} else {\n\t\t\t/* Output shuffle needed after main operation */\n\t\t\ta_out = a;\n\n\t\t\t/* The DUK_OP_CSVAR output shuffle assumes shuffle registers are\n\t\t\t * consecutive.\n\t\t\t */\n\t\t\tDUK_ASSERT((comp_ctx->curr_func.shuffle1 == 0 && comp_ctx->curr_func.shuffle2 == 0) ||\n\t\t\t           (comp_ctx->curr_func.shuffle2 == comp_ctx->curr_func.shuffle1 + 1));\n\t\t\tif (op == DUK_OP_CSVAR) {\n\t\t\t\t/* For CSVAR the limit is one smaller because output shuffle\n\t\t\t\t * must be able to express 'a + 1' in BC.\n\t\t\t\t */\n\t\t\t\tif (a + 1 > DUK_BC_BC_MAX) {\n\t\t\t\t\tgoto error_outofregs;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ta = tmp;\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"out of regs: 'a' (reg) needs shuffling but does not fit into BC, a: %ld\", (long) a));\n\t\tgoto error_outofregs;\n\t}\n\n\t/* Slot B: reg/const support, mapped to bit 0 of opcode. */\n\n\tif ((b & DUK__CONST_MARKER) != 0) {\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B) == 0);\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_B_IS_TARGET) == 0);\n\t\tb = b & ~DUK__CONST_MARKER;\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (0) {\n#else\n\t\tif (b <= 0xff) {\n#endif\n\t\t\tif (op_flags & DUK__EMIT_FLAG_BC_REGCONST) {\n\t\t\t\t/* Opcode follows B/C reg/const convention. */\n\t\t\t\tDUK_ASSERT((op & 0x01) == 0);\n\t\t\t\tins |= DUK_ENC_OP_A_B_C(0x01, 0, 0, 0);  /* const flag for B */\n\t\t\t} else {\n\t\t\t\tDUK_D(DUK_DPRINT(\"B is const, opcode is not B/C reg/const: %x\", op_flags));\n\t\t\t}\n\t\t} else if (b <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle2;\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDCONST, tmp, b));\n\t\t\tb = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'b' (const) needs shuffling but does not fit into BC, b: %ld\", (long) b));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t} else {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (b <= 0xff && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B)) {\n#else\n\t\tif (b <= 0xff) {\n#endif\n\t\t\t;\n\t\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B) {\n\t\t\tif (b > DUK_BC_B_MAX) {\n\t\t\t\t/* Note: 0xff != DUK_BC_B_MAX */\n\t\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'b' (reg) needs shuffling but shuffle prohibited, b: %ld\", (long) b));\n\t\t\t\tgoto error_outofregs;\n\t\t\t}\n\t\t} else if (b <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle2;\n\t\t\tif (op_flags & DUK__EMIT_FLAG_B_IS_TARGET) {\n\t\t\t\t/* Output shuffle needed after main operation */\n\t\t\t\tb_out = b;\n\t\t\t}\n\t\t\tif (!(op_flags & DUK__EMIT_FLAG_B_IS_TARGET)) {\n\t\t\t\tif (op == DUK_OP_MPUTOBJ || op == DUK_OP_MPUTARR) {\n\t\t\t\t\t/* Special handling for MPUTOBJ/MPUTARR shuffling.\n\t\t\t\t\t * For each, slot B identifies the first register of a range\n\t\t\t\t\t * of registers, so normal shuffling won't work.  Instead,\n\t\t\t\t\t * an indirect version of the opcode is used.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_B_IS_TARGET) == 0);\n\t\t\t\t\tduk__emit_load_int32_noshuffle(comp_ctx, tmp, b);\n\t\t\t\t\tDUK_ASSERT(DUK_OP_MPUTOBJI == DUK_OP_MPUTOBJ + 1);\n\t\t\t\t\tDUK_ASSERT(DUK_OP_MPUTARRI == DUK_OP_MPUTARR + 1);\n\t\t\t\t\top_flags++;  /* indirect opcode follows direct */\n\t\t\t\t} else {\n\t\t\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, b));\n\t\t\t\t}\n\t\t\t}\n\t\t\tb = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'b' (reg) needs shuffling but does not fit into BC, b: %ld\", (long) b));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t}\n\n\t/* Slot C: reg/const support, mapped to bit 1 of opcode. */\n\n\tif ((c & DUK__CONST_MARKER) != 0) {\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C) == 0);\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_C_IS_TARGET) == 0);\n\t\tc = c & ~DUK__CONST_MARKER;\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (0) {\n#else\n\t\tif (c <= 0xff) {\n#endif\n\t\t\tif (op_flags & DUK__EMIT_FLAG_BC_REGCONST) {\n\t\t\t\t/* Opcode follows B/C reg/const convention. */\n\t\t\t\tDUK_ASSERT((op & 0x02) == 0);\n\t\t\t\tins |= DUK_ENC_OP_A_B_C(0x02, 0, 0, 0);  /* const flag for C */\n\t\t\t} else {\n\t\t\t\tDUK_D(DUK_DPRINT(\"C is const, opcode is not B/C reg/const: %x\", op_flags));\n\t\t\t}\n\t\t} else if (c <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle3;\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDCONST, tmp, c));\n\t\t\tc = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'c' (const) needs shuffling but does not fit into BC, c: %ld\", (long) c));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t} else {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (c <= 0xff && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C)) {\n#else\n\t\tif (c <= 0xff) {\n#endif\n\t\t\t;\n\t\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C) {\n\t\t\tif (c > DUK_BC_C_MAX) {\n\t\t\t\t/* Note: 0xff != DUK_BC_C_MAX */\n\t\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'c' (reg) needs shuffling but shuffle prohibited, c: %ld\", (long) c));\n\t\t\t\tgoto error_outofregs;\n\t\t\t}\n\t\t} else if (c <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle3;\n\t\t\tif (op_flags & DUK__EMIT_FLAG_C_IS_TARGET) {\n\t\t\t\t/* Output shuffle needed after main operation */\n\t\t\t\tc_out = c;\n\t\t\t} else {\n\t\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, c));\n\t\t\t}\n\t\t\tc = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'c' (reg) needs shuffling but does not fit into BC, c: %ld\", (long) c));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t}\n\n\t/* Main operation */\n\n\tDUK_ASSERT(a >= DUK_BC_A_MIN);\n\tDUK_ASSERT(a <= DUK_BC_A_MAX);\n\tDUK_ASSERT(b >= DUK_BC_B_MIN);\n\tDUK_ASSERT(b <= DUK_BC_B_MAX);\n\tDUK_ASSERT(c >= DUK_BC_C_MIN);\n\tDUK_ASSERT(c <= DUK_BC_C_MAX);\n\n\tins |= DUK_ENC_OP_A_B_C(op_flags & 0xff, a, b, c);\n\tduk__emit(comp_ctx, ins);\n\n\t/* NEXTENUM needs a jump slot right after the main instruction.\n\t * When the JUMP is taken, output spilling is not needed so this\n\t * workaround is possible.  The jump slot PC is exceptionally\n\t * plumbed through comp_ctx to minimize call sites.\n\t */\n\tif (op_flags & DUK__EMIT_FLAG_RESERVE_JUMPSLOT) {\n\t\tcomp_ctx->emit_jumpslot_pc = duk__get_current_pc(comp_ctx);\n\t\tduk__emit_abc(comp_ctx, DUK_OP_JUMP, 0);\n\t}\n\n\t/* Output shuffling: only one output register is realistically possible.\n\t *\n\t * (Zero would normally be an OK marker value: if the target register\n\t * was zero, it would never be shuffled.  But with DUK_USE_SHUFFLE_TORTURE\n\t * this is no longer true, so use -1 as a marker instead.)\n\t */\n\n\tif (a_out >= 0) {\n\t\tDUK_ASSERT(b_out < 0);\n\t\tDUK_ASSERT(c_out < 0);\n\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, a, a_out));\n\n\t\tif (op == DUK_OP_CSVAR) {\n\t\t\t/* Special handling for CSVAR shuffling.  The variable lookup\n\t\t\t * results in a <value, this binding> pair in successive\n\t\t\t * registers so use two shuffle registers and two output\n\t\t\t * loads.  (In practice this is dead code because temp/const\n\t\t\t * limit is reached first.)\n\t\t\t */\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, a + 1, a_out + 1));\n\t\t}\n\t} else if (b_out >= 0) {\n\t\tDUK_ASSERT(a_out < 0);\n\t\tDUK_ASSERT(c_out < 0);\n\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, b, b_out));\n\t} else if (c_out >= 0) {\n\t\tDUK_ASSERT(b_out < 0);\n\t\tDUK_ASSERT(c_out < 0);\n\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, c, c_out));\n\t}\n\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* For many of the helpers below it'd be technically correct to add\n * \"no shuffle\" flags for parameters passed in as zero.  For example,\n * duk__emit_a_b() should call duk__emit_a_b_c() with C set to 0, and\n * DUK__EMIT_FLAG_NO_SHUFFLE_C added to op_flags.  However, since the\n * C value is 0, it'll never get shuffled so adding the flag is just\n * unnecessary additional code.  This is unfortunately not true for\n * \"shuffle torture\" mode which needs special handling.\n */\n\nDUK_LOCAL void duk__emit_a_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_C;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, a, b, 0);\n}\n\nDUK_LOCAL void duk__emit_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b, duk_regconst_t c) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_A;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, 0, b, c);\n}\n\n#if 0  /* unused */\nDUK_LOCAL void duk__emit_a(duk_compiler_ctx *comp_ctx, int op_flags, int a) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_B | DUK__EMIT_FLAG_NO_SHUFFLE_C;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, a, 0, 0);\n}\n#endif\n\n#if 0  /* unused */\nDUK_LOCAL void duk__emit_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_NO_SHUFFLE_C;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, 0, b, 0);\n}\n#endif\n\nDUK_LOCAL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t bc) {\n\tduk_instr_t ins;\n\tduk_int_t tmp;\n\n\t/* allow caller to give a const number with the DUK__CONST_MARKER */\n\tDUK_ASSERT(bc != -1);  /* Not 'none'. */\n\tbc = bc & (~DUK__CONST_MARKER);\n\n\tDUK_ASSERT_DISABLE((op_flags & 0xff) >= DUK_BC_OP_MIN);  /* unsigned */\n\tDUK_ASSERT((op_flags & 0xff) <= DUK_BC_OP_MAX);\n\tDUK_ASSERT(bc >= DUK_BC_BC_MIN);\n\tDUK_ASSERT(bc <= DUK_BC_BC_MAX);\n\tDUK_ASSERT((bc & DUK__CONST_MARKER) == 0);\n\n\tif (bc <= DUK_BC_BC_MAX) {\n\t\t;\n\t} else {\n\t\t/* No BC shuffling now. */\n\t\tgoto error_outofregs;\n\t}\n\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\tif (a <= DUK_BC_A_MAX && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A)) {\n#else\n\tif (a <= DUK_BC_A_MAX) {\n#endif\n\t\tins = DUK_ENC_OP_A_BC(op_flags & 0xff, a, bc);\n\t\tduk__emit(comp_ctx, ins);\n\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A) {\n\t\tgoto error_outofregs;\n\t} else if ((op_flags & 0xf0U) == DUK_OP_CALL0) {\n\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\ttmp = comp_ctx->curr_func.shuffle1;\n\t\tduk__emit_load_int32_noshuffle(comp_ctx, tmp, a);\n\t\top_flags |= DUK_BC_CALL_FLAG_INDIRECT;\n\t\tins = DUK_ENC_OP_A_BC(op_flags & 0xff, tmp, bc);\n\t\tduk__emit(comp_ctx, ins);\n\t} else if (a <= DUK_BC_BC_MAX) {\n\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\ttmp = comp_ctx->curr_func.shuffle1;\n\t\tins = DUK_ENC_OP_A_BC(op_flags & 0xff, tmp, bc);\n\t\tif (op_flags & DUK__EMIT_FLAG_A_IS_SOURCE) {\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, a));\n\t\t\tduk__emit(comp_ctx, ins);\n\t\t} else {\n\t\t\tduk__emit(comp_ctx, ins);\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, tmp, a));\n\t\t}\n\t} else {\n\t\tgoto error_outofregs;\n\t}\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__emit_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t bc) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top |= DUK__EMIT_FLAG_NO_SHUFFLE_A;\n#endif\n\tduk__emit_a_bc(comp_ctx, op, 0, bc);\n}\n\nDUK_LOCAL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t abc) {\n\tduk_instr_t ins;\n\n\tDUK_ASSERT_DISABLE(op >= DUK_BC_OP_MIN);  /* unsigned */\n\tDUK_ASSERT(op <= DUK_BC_OP_MAX);\n\tDUK_ASSERT_DISABLE(abc >= DUK_BC_ABC_MIN);  /* unsigned */\n\tDUK_ASSERT(abc <= DUK_BC_ABC_MAX);\n\tDUK_ASSERT((abc & DUK__CONST_MARKER) == 0);\n\tDUK_ASSERT(abc != -1);  /* Not 'none'. */\n\n\tif (abc <= DUK_BC_ABC_MAX) {\n\t\t;\n\t} else {\n\t\tgoto error_outofregs;\n\t}\n\tins = DUK_ENC_OP_ABC(op, abc);\n\tDUK_DDD(DUK_DDDPRINT(\"duk__emit_abc: 0x%08lx line=%ld pc=%ld op=%ld (%!X) abc=%ld (%!I)\",\n\t                     (unsigned long) ins, (long) comp_ctx->curr_token.start_line,\n\t                     (long) duk__get_current_pc(comp_ctx), (long) op, (long) op,\n\t                     (long) abc, (duk_instr_t) ins));\n\tduk__emit(comp_ctx, ins);\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__emit_load_int32_raw(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val, duk_small_uint_t op_flags) {\n\t/* XXX: Shuffling support could be implemented here so that LDINT+LDINTX\n\t * would only shuffle once (instead of twice).  The current code works\n\t * though, and has a smaller compiler footprint.\n\t */\n\n\tif ((val >= (duk_int32_t) DUK_BC_BC_MIN - (duk_int32_t) DUK_BC_LDINT_BIAS) &&\n\t    (val <= (duk_int32_t) DUK_BC_BC_MAX - (duk_int32_t) DUK_BC_LDINT_BIAS)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"emit LDINT to reg %ld for %ld\", (long) reg, (long) val));\n\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDINT | op_flags, reg, (duk_regconst_t) (val + (duk_int32_t) DUK_BC_LDINT_BIAS));\n\t} else {\n\t\tduk_int32_t hi = val >> DUK_BC_LDINTX_SHIFT;\n\t\tduk_int32_t lo = val & ((((duk_int32_t) 1) << DUK_BC_LDINTX_SHIFT) - 1);\n\t\tDUK_ASSERT(lo >= 0);\n\t\tDUK_DDD(DUK_DDDPRINT(\"emit LDINT+LDINTX to reg %ld for %ld -> hi %ld, lo %ld\",\n\t\t                     (long) reg, (long) val, (long) hi, (long) lo));\n\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDINT | op_flags, reg, (duk_regconst_t) (hi + (duk_int32_t) DUK_BC_LDINT_BIAS));\n\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDINTX | op_flags, reg, (duk_regconst_t) lo);\n\t}\n}\n\nDUK_LOCAL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val) {\n\tduk__emit_load_int32_raw(comp_ctx, reg, val, 0 /*op_flags*/);\n}\n\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n/* Used by duk__emit*() calls so that we don't shuffle the loadints that\n * are needed to handle indirect opcodes.\n */\nDUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val) {\n\tduk__emit_load_int32_raw(comp_ctx, reg, val, DUK__EMIT_FLAG_NO_SHUFFLE_A /*op_flags*/);\n}\n#else\nDUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val) {\n\t/* When torture not enabled, can just use the same helper because\n\t * 'reg' won't get spilled.\n\t */\n\tDUK_ASSERT(reg <= DUK_BC_A_MAX);\n\tduk__emit_load_int32(comp_ctx, reg, val);\n}\n#endif\n\nDUK_LOCAL void duk__emit_jump(duk_compiler_ctx *comp_ctx, duk_int_t target_pc) {\n\tduk_int_t curr_pc;\n\tduk_int_t offset;\n\n\tcurr_pc = (duk_int_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr));\n\toffset = (duk_int_t) target_pc - (duk_int_t) curr_pc - 1;\n\tDUK_ASSERT(offset + DUK_BC_JUMP_BIAS >= DUK_BC_ABC_MIN);\n\tDUK_ASSERT(offset + DUK_BC_JUMP_BIAS <= DUK_BC_ABC_MAX);\n\tduk__emit_abc(comp_ctx, DUK_OP_JUMP, (duk_regconst_t) (offset + DUK_BC_JUMP_BIAS));\n}\n\nDUK_LOCAL duk_int_t duk__emit_jump_empty(duk_compiler_ctx *comp_ctx) {\n\tduk_int_t ret;\n\n\tret = duk__get_current_pc(comp_ctx);  /* useful for patching jumps later */\n\tduk__emit_op_only(comp_ctx, DUK_OP_JUMP);\n\treturn ret;\n}\n\n/* Insert an empty jump in the middle of code emitted earlier.  This is\n * currently needed for compiling for-in.\n */\nDUK_LOCAL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc) {\n#if defined(DUK_USE_PC2LINE)\n\tduk_int_t line;\n#endif\n\tduk_compiler_instr *instr;\n\tduk_size_t offset;\n\n\tDUK_ASSERT(jump_pc >= 0);\n\toffset = (duk_size_t) jump_pc * sizeof(duk_compiler_instr);\n\tinstr = (duk_compiler_instr *) (void *)\n\t        DUK_BW_INSERT_ENSURE_AREA(comp_ctx->thr,\n\t                                  &comp_ctx->curr_func.bw_code,\n\t                                  offset,\n\t                                  sizeof(duk_compiler_instr));\n\n#if defined(DUK_USE_PC2LINE)\n\tline = comp_ctx->curr_token.start_line;  /* approximation, close enough */\n#endif\n\tinstr->ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, 0);\n#if defined(DUK_USE_PC2LINE)\n\tinstr->line = (duk_uint32_t) line;\n#endif\n\n\tDUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, sizeof(duk_compiler_instr));\n\tif (DUK_UNLIKELY(DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) > DUK_USE_ESBC_MAX_BYTES)) {\n\t\tgoto fail_bc_limit;\n\t}\n\treturn;\n\n  fail_bc_limit:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_BYTECODE_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Does not assume that jump_pc contains a DUK_OP_JUMP previously; this is intentional\n * to allow e.g. an INVALID opcode be overwritten with a JUMP (label management uses this).\n */\nDUK_LOCAL void duk__patch_jump(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc, duk_int_t target_pc) {\n\tduk_compiler_instr *instr;\n\tduk_int_t offset;\n\n\t/* allow negative PCs, behave as a no-op */\n\tif (jump_pc < 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__patch_jump(): nop call, jump_pc=%ld (<0), target_pc=%ld\",\n\t\t                     (long) jump_pc, (long) target_pc));\n\t\treturn;\n\t}\n\tDUK_ASSERT(jump_pc >= 0);\n\n\t/* XXX: range assert */\n\tinstr = duk__get_instr_ptr(comp_ctx, jump_pc);\n\tDUK_ASSERT(instr != NULL);\n\n\t/* XXX: range assert */\n\toffset = target_pc - jump_pc - 1;\n\n\tinstr->ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, offset + DUK_BC_JUMP_BIAS);\n\tDUK_DDD(DUK_DDDPRINT(\"duk__patch_jump(): jump_pc=%ld, target_pc=%ld, offset=%ld\",\n\t                     (long) jump_pc, (long) target_pc, (long) offset));\n}\n\nDUK_LOCAL void duk__patch_jump_here(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc) {\n\tduk__patch_jump(comp_ctx, jump_pc, duk__get_current_pc(comp_ctx));\n}\n\nDUK_LOCAL void duk__patch_trycatch(duk_compiler_ctx *comp_ctx, duk_int_t ldconst_pc, duk_int_t trycatch_pc, duk_regconst_t reg_catch, duk_regconst_t const_varname, duk_small_uint_t flags) {\n\tduk_compiler_instr *instr;\n\n\tDUK_ASSERT(DUK__ISREG(reg_catch));\n\n\tinstr = duk__get_instr_ptr(comp_ctx, ldconst_pc);\n\tDUK_ASSERT(DUK_DEC_OP(instr->ins) == DUK_OP_LDCONST);\n\tDUK_ASSERT(instr != NULL);\n\tif (const_varname & DUK__CONST_MARKER) {\n\t\t/* Have a catch variable. */\n\t\tconst_varname = const_varname & (~DUK__CONST_MARKER);\n\t\tif (reg_catch > DUK_BC_BC_MAX || const_varname > DUK_BC_BC_MAX) {\n\t\t\t/* Catch attempts to use out-of-range reg/const.  Without this\n\t\t\t * check Duktape 0.12.0 could generate invalid code which caused\n\t\t\t * an assert failure on execution.  This error is triggered e.g.\n\t\t\t * for functions with a lot of constants and a try-catch statement.\n\t\t\t * Shuffling or opcode semantics change is needed to fix the issue.\n\t\t\t * See: test-bug-trycatch-many-constants.js.\n\t\t\t */\n\t\t\tDUK_D(DUK_DPRINT(\"failed to patch trycatch: flags=%ld, reg_catch=%ld, const_varname=%ld (0x%08lx)\",\n\t\t\t                 (long) flags, (long) reg_catch, (long) const_varname, (long) const_varname));\n\t\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tinstr->ins |= DUK_ENC_OP_A_BC(0, 0, const_varname);\n\t} else {\n\t\t/* No catch variable, e.g. a try-finally; replace LDCONST with\n\t\t * NOP to avoid a bogus LDCONST.\n\t\t */\n\t\tinstr->ins = DUK_ENC_OP(DUK_OP_NOP);\n\t}\n\n\tinstr = duk__get_instr_ptr(comp_ctx, trycatch_pc);\n\tDUK_ASSERT(instr != NULL);\n\tDUK_ASSERT_DISABLE(flags >= DUK_BC_A_MIN);\n\tDUK_ASSERT(flags <= DUK_BC_A_MAX);\n\tinstr->ins = DUK_ENC_OP_A_BC(DUK_OP_TRYCATCH, flags, reg_catch);\n}\n\nDUK_LOCAL void duk__emit_if_false_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst) {\n\tduk_small_uint_t op;\n\n\top = DUK__ISREG(regconst) ? DUK_OP_IFFALSE_R : DUK_OP_IFFALSE_C;\n\tduk__emit_bc(comp_ctx, op, regconst);  /* helper will remove const flag */\n}\n\nDUK_LOCAL void duk__emit_if_true_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst) {\n\tduk_small_uint_t op;\n\n\top = DUK__ISREG(regconst) ? DUK_OP_IFTRUE_R : DUK_OP_IFTRUE_C;\n\tduk__emit_bc(comp_ctx, op, regconst);  /* helper will remove const flag */\n}\n\nDUK_LOCAL void duk__emit_invalid(duk_compiler_ctx *comp_ctx) {\n\tduk__emit_op_only(comp_ctx, DUK_OP_INVALID);\n}\n\n/*\n *  Peephole optimizer for finished bytecode.\n *\n *  Does not remove opcodes; currently only straightens out unconditional\n *  jump chains which are generated by several control structures.\n */\n\nDUK_LOCAL void duk__peephole_optimize_bytecode(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_instr *bc;\n\tduk_small_uint_t iter;\n\tduk_int_t i, n;\n\tduk_int_t count_opt;\n\n\tbc = (duk_compiler_instr *) (void *) DUK_BW_GET_BASEPTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code);\n#if defined(DUK_USE_BUFLEN16)\n\t/* No need to assert, buffer size maximum is 0xffff. */\n#else\n\tDUK_ASSERT((duk_size_t) DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr) <= (duk_size_t) DUK_INT_MAX);  /* bytecode limits */\n#endif\n\tn = (duk_int_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr));\n\n\tfor (iter = 0; iter < DUK_COMPILER_PEEPHOLE_MAXITER; iter++) {\n\t\tcount_opt = 0;\n\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk_instr_t ins;\n\t\t\tduk_int_t target_pc1;\n\t\t\tduk_int_t target_pc2;\n\n\t\t\tins = bc[i].ins;\n\t\t\tif (DUK_DEC_OP(ins) != DUK_OP_JUMP) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttarget_pc1 = i + 1 + (duk_int_t) DUK_DEC_ABC(ins) - (duk_int_t) DUK_BC_JUMP_BIAS;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"consider jump at pc %ld; target_pc=%ld\", (long) i, (long) target_pc1));\n\t\t\tDUK_ASSERT(target_pc1 >= 0);\n\t\t\tDUK_ASSERT(target_pc1 < n);\n\n\t\t\t/* Note: if target_pc1 == i, we'll optimize a jump to itself.\n\t\t\t * This does not need to be checked for explicitly; the case\n\t\t\t * is rare and max iter breaks us out.\n\t\t\t */\n\n\t\t\tins = bc[target_pc1].ins;\n\t\t\tif (DUK_DEC_OP(ins) != DUK_OP_JUMP) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttarget_pc2 = target_pc1 + 1 + (duk_int_t) DUK_DEC_ABC(ins) - (duk_int_t) DUK_BC_JUMP_BIAS;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"optimizing jump at pc %ld; old target is %ld -> new target is %ld\",\n\t\t\t                     (long) i, (long) target_pc1, (long) target_pc2));\n\n\t\t\tbc[i].ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, target_pc2 - (i + 1) + DUK_BC_JUMP_BIAS);\n\n\t\t\tcount_opt++;\n\t\t}\n\n\t\tDUK_DD(DUK_DDPRINT(\"optimized %ld jumps on peephole round %ld\", (long) count_opt, (long) (iter + 1)));\n\n\t\tif (count_opt == 0) {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/*\n *  Intermediate value helpers\n */\n\n/* Flags for intermediate value coercions.  A flag for using a forced reg\n * is not needed, the forced_reg argument suffices and generates better\n * code (it is checked as it is used).\n */\n/* XXX: DUK__IVAL_FLAG_REQUIRE_SHORT is passed but not currently implemented\n * by ispec/ivalue operations.\n */\n#define DUK__IVAL_FLAG_ALLOW_CONST          (1 << 0)  /* allow a constant to be returned */\n#define DUK__IVAL_FLAG_REQUIRE_TEMP         (1 << 1)  /* require a (mutable) temporary as a result (or a const if allowed) */\n#define DUK__IVAL_FLAG_REQUIRE_SHORT        (1 << 2)  /* require a short (8-bit) reg/const which fits into bytecode B/C slot */\n\n/* XXX: some code might benefit from DUK__SETTEMP_IFTEMP(thr,x) */\n\n#if 0  /* enable manually for dumping */\n#define DUK__DUMP_ISPEC(compctx,ispec) do { duk__dump_ispec((compctx), (ispec)); } while (0)\n#define DUK__DUMP_IVALUE(compctx,ivalue) do { duk__dump_ivalue((compctx), (ivalue)); } while (0)\n\nDUK_LOCAL void duk__dump_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *x) {\n\tDUK_D(DUK_DPRINT(\"ispec dump: t=%ld regconst=0x%08lx, valstack_idx=%ld, value=%!T\",\n\t                 (long) x->t, (unsigned long) x->regconst, (long) x->valstack_idx,\n\t                 duk_get_tval(comp_ctx->thr, x->valstack_idx)));\n}\nDUK_LOCAL void duk__dump_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tDUK_D(DUK_DPRINT(\"ivalue dump: t=%ld op=%ld \"\n\t                 \"x1={t=%ld regconst=0x%08lx valstack_idx=%ld value=%!T} \"\n\t                 \"x2={t=%ld regconst=0x%08lx valstack_idx=%ld value=%!T}\",\n\t\t         (long) x->t, (long) x->op,\n\t                 (long) x->x1.t, (unsigned long) x->x1.regconst, (long) x->x1.valstack_idx,\n\t                 duk_get_tval(comp_ctx->thr, x->x1.valstack_idx),\n\t                 (long) x->x2.t, (unsigned long) x->x2.regconst, (long) x->x2.valstack_idx,\n\t                 duk_get_tval(comp_ctx->thr, x->x2.valstack_idx)));\n}\n#else\n#define DUK__DUMP_ISPEC(comp_ctx,x) do {} while (0)\n#define DUK__DUMP_IVALUE(comp_ctx,x) do {} while (0)\n#endif\n\nDUK_LOCAL void duk__ivalue_regconst(duk_ivalue *x, duk_regconst_t regconst) {\n\tx->t = DUK_IVAL_PLAIN;\n\tx->x1.t = DUK_ISPEC_REGCONST;\n\tx->x1.regconst = regconst;\n}\n\nDUK_LOCAL void duk__ivalue_plain_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tx->t = DUK_IVAL_PLAIN;\n\tx->x1.t = DUK_ISPEC_VALUE;\n\tduk_replace(comp_ctx->thr, x->x1.valstack_idx);\n}\n\nDUK_LOCAL void duk__ivalue_var_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tx->t = DUK_IVAL_VAR;\n\tx->x1.t = DUK_ISPEC_VALUE;\n\tduk_replace(comp_ctx->thr, x->x1.valstack_idx);\n}\n\nDUK_LOCAL_DECL void duk__ivalue_var_hstring(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n\tduk_push_hstring(comp_ctx->thr, h);\n\tduk__ivalue_var_fromstack(comp_ctx, x);\n}\n\nDUK_LOCAL void duk__copy_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *src, duk_ispec *dst) {\n\tdst->t = src->t;\n\tdst->regconst = src->regconst;\n\tduk_copy(comp_ctx->thr, src->valstack_idx, dst->valstack_idx);\n}\n\nDUK_LOCAL void duk__copy_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *src, duk_ivalue *dst) {\n\tdst->t = src->t;\n\tdst->op = src->op;\n\tdst->x1.t = src->x1.t;\n\tdst->x1.regconst = src->x1.regconst;\n\tdst->x2.t = src->x2.t;\n\tdst->x2.regconst = src->x2.regconst;\n\tduk_copy(comp_ctx->thr, src->x1.valstack_idx, dst->x1.valstack_idx);\n\tduk_copy(comp_ctx->thr, src->x2.valstack_idx, dst->x2.valstack_idx);\n}\n\nDUK_LOCAL duk_regconst_t duk__alloctemps(duk_compiler_ctx *comp_ctx, duk_small_int_t num) {\n\tduk_regconst_t res;\n\n\tres = comp_ctx->curr_func.temp_next;\n\tcomp_ctx->curr_func.temp_next += num;\n\n\tif (comp_ctx->curr_func.temp_next > DUK__MAX_TEMPS) {  /* == DUK__MAX_TEMPS is OK */\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_TEMP_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* maintain highest 'used' temporary, needed to figure out nregs of function */\n\tif (comp_ctx->curr_func.temp_next > comp_ctx->curr_func.temp_max) {\n\t\tcomp_ctx->curr_func.temp_max = comp_ctx->curr_func.temp_next;\n\t}\n\n\treturn res;\n}\n\nDUK_LOCAL duk_regconst_t duk__alloctemp(duk_compiler_ctx *comp_ctx) {\n\treturn duk__alloctemps(comp_ctx, 1);\n}\n\nDUK_LOCAL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, duk_regconst_t temp_next) {\n\tcomp_ctx->curr_func.temp_next = temp_next;\n\tif (temp_next > comp_ctx->curr_func.temp_max) {\n\t\tcomp_ctx->curr_func.temp_max = temp_next;\n\t}\n}\n\n/* get const for value at valstack top */\nDUK_LOCAL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_compiler_func *f = &comp_ctx->curr_func;\n\tduk_tval *tv1;\n\tduk_int_t i, n, n_check;\n\n\tn = (duk_int_t) duk_get_length(thr, f->consts_idx);\n\n\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(tv1 != NULL);\n\n#if defined(DUK_USE_FASTINT)\n\t/* Explicit check for fastint downgrade. */\n\tDUK_TVAL_CHKFAST_INPLACE_SLOW(tv1);\n#endif\n\n\t/* Sanity workaround for handling functions with a large number of\n\t * constants at least somewhat reasonably.  Otherwise checking whether\n\t * we already have the constant would grow very slow (as it is O(N^2)).\n\t */\n\tn_check = (n > DUK__GETCONST_MAX_CONSTS_CHECK ? DUK__GETCONST_MAX_CONSTS_CHECK : n);\n\tfor (i = 0; i < n_check; i++) {\n\t\tduk_tval *tv2 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, f->h_consts, i);\n\n\t\t/* Strict equality is NOT enough, because we cannot use the same\n\t\t * constant for e.g. +0 and -0.\n\t\t */\n\t\tif (duk_js_samevalue(tv1, tv2)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"reused existing constant for %!T -> const index %ld\",\n\t\t\t                     (duk_tval *) tv1, (long) i));\n\t\t\tduk_pop(thr);\n\t\t\treturn (duk_regconst_t) i | (duk_regconst_t) DUK__CONST_MARKER;\n\t\t}\n\t}\n\n\tif (n > DUK__MAX_CONSTS) {\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_CONST_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"allocating new constant for %!T -> const index %ld\",\n\t                     (duk_tval *) tv1, (long) n));\n\t(void) duk_put_prop_index(thr, f->consts_idx, (duk_uarridx_t) n);  /* invalidates tv1, tv2 */\n\treturn (duk_regconst_t) n | (duk_regconst_t) DUK__CONST_MARKER;\n}\n\nDUK_LOCAL duk_bool_t duk__const_needs_refcount(duk_compiler_ctx *comp_ctx, duk_regconst_t rc) {\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_compiler_func *f = &comp_ctx->curr_func;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT((rc & DUK__CONST_MARKER) == 0);  /* caller removes const marker */\n\t(void) duk_get_prop_index(comp_ctx->thr, f->consts_idx, (duk_uarridx_t) rc);\n\tret = !duk_is_number(comp_ctx->thr, -1);  /* now only number/string, so conservative check */\n\tduk_pop(comp_ctx->thr);\n\treturn ret;\n#else\n\tDUK_UNREF(comp_ctx);\n\tDUK_UNREF(rc);\n\tDUK_ASSERT((rc & DUK__CONST_MARKER) == 0);  /* caller removes const marker */\n\treturn 0;\n#endif\n}\n\n/* Get the value represented by an duk_ispec to a register or constant.\n * The caller can control the result by indicating whether or not:\n *\n *   (1) a constant is allowed (sometimes the caller needs the result to\n *       be in a register)\n *\n *   (2) a temporary register is required (usually when caller requires\n *       the register to be safely mutable; normally either a bound\n *       register or a temporary register are both OK)\n *\n *   (3) a forced register target needs to be used\n *\n * Bytecode may be emitted to generate the necessary value.  The return\n * value is either a register or a constant.\n */\n\nDUK_LOCAL\nduk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                         duk_ispec *x,\n                                         duk_regconst_t forced_reg,\n                                         duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__ispec_toregconst_raw(): x={%ld:%ld:%!T}, \"\n\t                     \"forced_reg=%ld, flags 0x%08lx: allow_const=%ld require_temp=%ld require_short=%ld\",\n\t                     (long) x->t,\n\t                     (long) x->regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->valstack_idx),\n\t                     (long) forced_reg,\n\t                     (unsigned long) flags,\n\t                     (long) ((flags & DUK__IVAL_FLAG_ALLOW_CONST) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_SHORT) ? 1 : 0)));\n\n\tswitch (x->t) {\n\tcase DUK_ISPEC_VALUE: {\n\t\tduk_tval *tv;\n\n\t\ttv = DUK_GET_TVAL_POSIDX(thr, x->valstack_idx);\n\t\tDUK_ASSERT(tv != NULL);\n\n\t\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\t\tcase DUK_TAG_UNDEFINED: {\n\t\t\t/* Note: although there is no 'undefined' literal, undefined\n\t\t\t * values can occur during compilation as a result of e.g.\n\t\t\t * the 'void' operator.\n\t\t\t */\n\t\t\tduk_regconst_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_LDUNDEF, dest);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_NULL: {\n\t\t\tduk_regconst_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_LDNULL, dest);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_BOOLEAN: {\n\t\t\tduk_regconst_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             (DUK_TVAL_GET_BOOLEAN(tv) ? DUK_OP_LDTRUE : DUK_OP_LDFALSE),\n\t\t\t             dest);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_POINTER: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_STRING: {\n\t\t\tduk_hstring *h;\n\t\t\tduk_regconst_t dest;\n\t\t\tduk_regconst_t constidx;\n\n\t\t\th = DUK_TVAL_GET_STRING(tv);\n\t\t\tDUK_UNREF(h);\n\t\t\tDUK_ASSERT(h != NULL);\n\n#if 0  /* XXX: to be implemented? */\n\t\t\t/* Use special opcodes to load short strings */\n\t\t\tif (DUK_HSTRING_GET_BYTELEN(h) <= 2) {\n\t\t\t\t/* Encode into a single opcode (18 bits can encode 1-2 bytes + length indicator) */\n\t\t\t} else if (DUK_HSTRING_GET_BYTELEN(h) <= 6) {\n\t\t\t\t/* Encode into a double constant (53 bits can encode 6*8 = 48 bits + 3-bit length */\n\t\t\t}\n#endif\n\t\t\tduk_dup(thr, x->valstack_idx);\n\t\t\tconstidx = duk__getconst(comp_ctx);\n\n\t\t\tif (flags & DUK__IVAL_FLAG_ALLOW_CONST) {\n\t\t\t\treturn constidx;\n\t\t\t}\n\n\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, constidx);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_OBJECT: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_BUFFER: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_LIGHTFUNC: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_FASTINT)\n\t\tcase DUK_TAG_FASTINT:\n#endif\n\t\tdefault: {\n\t\t\t/* number */\n\t\t\tduk_regconst_t dest;\n\t\t\tduk_regconst_t constidx;\n\t\t\tduk_double_t dval;\n\t\t\tduk_int32_t ival;\n\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\t\tdval = DUK_TVAL_GET_NUMBER(tv);\n\n\t\t\tif (!(flags & DUK__IVAL_FLAG_ALLOW_CONST)) {\n\t\t\t\t/* A number can be loaded either through a constant, using\n\t\t\t\t * LDINT, or using LDINT+LDINTX.  LDINT is always a size win,\n\t\t\t\t * LDINT+LDINTX is not if the constant is used multiple times.\n\t\t\t\t * Currently always prefer LDINT+LDINTX over a double constant.\n\t\t\t\t */\n\n\t\t\t\tif (duk_is_whole_get_int32_nonegzero(dval, &ival)) {\n\t\t\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\t\t\tduk__emit_load_int32(comp_ctx, dest, ival);\n\t\t\t\t\treturn dest;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_dup(thr, x->valstack_idx);\n\t\t\tconstidx = duk__getconst(comp_ctx);\n\n\t\t\tif (flags & DUK__IVAL_FLAG_ALLOW_CONST) {\n\t\t\t\treturn constidx;\n\t\t\t} else {\n\t\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, constidx);\n\t\t\t\treturn dest;\n\t\t\t}\n\t\t}\n\t\t}  /* end switch */\n\t\tgoto fail_internal;  /* never here */\n\t}\n\tcase DUK_ISPEC_REGCONST: {\n\t\tif (forced_reg >= 0) {\n\t\t\tif (DUK__ISCONST(x->regconst)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, forced_reg, x->regconst);\n\t\t\t} else if (x->regconst != forced_reg) {\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDREG, forced_reg, x->regconst);\n\t\t\t} else {\n\t\t\t\t; /* already in correct reg */\n\t\t\t}\n\t\t\treturn forced_reg;\n\t\t}\n\n\t\tDUK_ASSERT(forced_reg < 0);\n\t\tif (DUK__ISCONST(x->regconst)) {\n\t\t\tif (!(flags & DUK__IVAL_FLAG_ALLOW_CONST)) {\n\t\t\t\tduk_regconst_t dest = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, x->regconst);\n\t\t\t\treturn dest;\n\t\t\t}\n\t\t\treturn x->regconst;\n\t\t}\n\n\t\tDUK_ASSERT(forced_reg < 0 && !DUK__ISCONST(x->regconst));\n\t\tif ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) && !DUK__ISREG_TEMP(comp_ctx, x->regconst)) {\n\t\t\tduk_regconst_t dest = DUK__ALLOCTEMP(comp_ctx);\n\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDREG, dest, x->regconst);\n\t\t\treturn dest;\n\t\t}\n\t\treturn x->regconst;\n\t}\n\tdefault: {\n\t\tbreak;  /* never here */\n\t}\n\t}\n\n fail_internal:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_LOCAL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ispec *x, duk_regconst_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\t(void) duk__ispec_toregconst_raw(comp_ctx, x, forced_reg, 0 /*flags*/);\n}\n\n/* Coerce an duk_ivalue to a 'plain' value by generating the necessary\n * arithmetic operations, property access, or variable access bytecode.\n * The duk_ivalue argument ('x') is converted into a plain value as a\n * side effect.\n */\nDUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_regconst_t forced_reg) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__ivalue_toplain_raw(): x={t=%ld,op=%ld,x1={%ld:%ld:%!T},x2={%ld:%ld:%!T}}, \"\n\t                     \"forced_reg=%ld\",\n\t                     (long) x->t, (long) x->op,\n\t                     (long) x->x1.t, (long) x->x1.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x1.valstack_idx),\n\t                     (long) x->x2.t, (long) x->x2.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x2.valstack_idx),\n\t                     (long) forced_reg));\n\n\tswitch (x->t) {\n\tcase DUK_IVAL_PLAIN: {\n\t\treturn;\n\t}\n\t/* XXX: support unary arithmetic ivalues (useful?) */\n\tcase DUK_IVAL_ARITH: {\n\t\tduk_regconst_t arg1;\n\t\tduk_regconst_t arg2;\n\t\tduk_regconst_t dest;\n\t\tduk_tval *tv1;\n\t\tduk_tval *tv2;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"arith to plain conversion\"));\n\n\t\t/* inline arithmetic check for constant values */\n\t\t/* XXX: use the exactly same arithmetic function here as in executor */\n\t\tif (x->x1.t == DUK_ISPEC_VALUE && x->x2.t == DUK_ISPEC_VALUE && x->t == DUK_IVAL_ARITH) {\n\t\t\ttv1 = DUK_GET_TVAL_POSIDX(thr, x->x1.valstack_idx);\n\t\t\ttv2 = DUK_GET_TVAL_POSIDX(thr, x->x2.valstack_idx);\n\t\t\tDUK_ASSERT(tv1 != NULL);\n\t\t\tDUK_ASSERT(tv2 != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"arith: tv1=%!T, tv2=%!T\",\n\t\t\t                     (duk_tval *) tv1,\n\t\t\t                     (duk_tval *) tv2));\n\n\t\t\tif (DUK_TVAL_IS_NUMBER(tv1) && DUK_TVAL_IS_NUMBER(tv2)) {\n\t\t\t\tduk_double_t d1 = DUK_TVAL_GET_NUMBER(tv1);\n\t\t\t\tduk_double_t d2 = DUK_TVAL_GET_NUMBER(tv2);\n\t\t\t\tduk_double_t d3;\n\t\t\t\tduk_bool_t accept_fold = 1;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"arith inline check: d1=%lf, d2=%lf, op=%ld\",\n\t\t\t\t                     (double) d1, (double) d2, (long) x->op));\n\t\t\t\tswitch (x->op) {\n\t\t\t\tcase DUK_OP_ADD: {\n\t\t\t\t\td3 = d1 + d2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_SUB: {\n\t\t\t\t\td3 = d1 - d2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_MUL: {\n\t\t\t\t\td3 = d1 * d2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_DIV: {\n\t\t\t\t\t/* Division-by-zero is undefined\n\t\t\t\t\t * behavior, so rely on a helper.\n\t\t\t\t\t */\n\t\t\t\t\td3 = duk_double_div(d1, d2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_EXP: {\n\t\t\t\t\td3 = (duk_double_t) duk_js_arith_pow((double) d1, (double) d2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\td3 = 0.0;  /* Won't be used, but silence MSVC /W4 warning. */\n\t\t\t\t\taccept_fold = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (accept_fold) {\n\t\t\t\t\tduk_double_union du;\n\t\t\t\t\tdu.d = d3;\n\t\t\t\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\t\t\t\t\td3 = du.d;\n\n\t\t\t\t\tx->t = DUK_IVAL_PLAIN;\n\t\t\t\t\tDUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE);\n\t\t\t\t\tDUK_TVAL_SET_NUMBER(tv1, d3);  /* old value is number: no refcount */\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else if (x->op == DUK_OP_ADD && DUK_TVAL_IS_STRING(tv1) && DUK_TVAL_IS_STRING(tv2)) {\n\t\t\t\t/* Inline string concatenation.  No need to check for\n\t\t\t\t * symbols, as all inputs are valid ECMAScript strings.\n\t\t\t\t */\n\t\t\t\tduk_dup(thr, x->x1.valstack_idx);\n\t\t\t\tduk_dup(thr, x->x2.valstack_idx);\n\t\t\t\tduk_concat(thr, 2);\n\t\t\t\tduk_replace(thr, x->x1.valstack_idx);\n\t\t\t\tx->t = DUK_IVAL_PLAIN;\n\t\t\t\tDUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\targ1 = duk__ispec_toregconst_raw(comp_ctx, &x->x1, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\t\targ2 = duk__ispec_toregconst_raw(comp_ctx, &x->x2, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\n\t\t/* If forced reg, use it as destination.  Otherwise try to\n\t\t * use either coerced ispec if it is a temporary.\n\t\t */\n\t\tif (forced_reg >= 0) {\n\t\t\tdest = forced_reg;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg1)) {\n\t\t\tdest = arg1;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg2)) {\n\t\t\tdest = arg2;\n\t\t} else {\n\t\t\tdest = DUK__ALLOCTEMP(comp_ctx);\n\t\t}\n\n\t\tDUK_ASSERT(DUK__ISREG(dest));\n\t\tduk__emit_a_b_c(comp_ctx, x->op | DUK__EMIT_FLAG_BC_REGCONST, dest, arg1, arg2);\n\n\t\tduk__ivalue_regconst(x, dest);\n\t\treturn;\n\t}\n\tcase DUK_IVAL_PROP: {\n\t\t/* XXX: very similar to DUK_IVAL_ARITH - merge? */\n\t\tduk_regconst_t arg1;\n\t\tduk_regconst_t arg2;\n\t\tduk_regconst_t dest;\n\n\t\t/* Need a short reg/const, does not have to be a mutable temp. */\n\t\targ1 = duk__ispec_toregconst_raw(comp_ctx, &x->x1, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\t\targ2 = duk__ispec_toregconst_raw(comp_ctx, &x->x2, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\n\t\t/* Pick a destination register.  If either base value or key\n\t\t * happens to be a temp value, reuse it as the destination.\n\t\t *\n\t\t * XXX: The temp must be a \"mutable\" one, i.e. such that no\n\t\t * other expression is using it anymore.  Here this should be\n\t\t * the case because the value of a property access expression\n\t\t * is neither the base nor the key, but the lookup result.\n\t\t */\n\n\t\tif (forced_reg >= 0) {\n\t\t\tdest = forced_reg;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg1)) {\n\t\t\tdest = arg1;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg2)) {\n\t\t\tdest = arg2;\n\t\t} else {\n\t\t\tdest = DUK__ALLOCTEMP(comp_ctx);\n\t\t}\n\n\t\tduk__emit_a_b_c(comp_ctx,\n\t\t                DUK_OP_GETPROP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t                dest,\n\t\t                arg1,\n\t\t                arg2);\n\n\t\tduk__ivalue_regconst(x, dest);\n\t\treturn;\n\t}\n\tcase DUK_IVAL_VAR: {\n\t\t/* x1 must be a string */\n\t\tduk_regconst_t dest;\n\t\tduk_regconst_t reg_varbind;\n\t\tduk_regconst_t rc_varname;\n\n\t\tDUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE);\n\n\t\tduk_dup(thr, x->x1.valstack_idx);\n\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\tduk__ivalue_regconst(x, reg_varbind);\n\t\t} else {\n\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_GETVAR, dest, rc_varname);\n\t\t\tduk__ivalue_regconst(x, dest);\n\t\t}\n\t\treturn;\n\t}\n\tcase DUK_IVAL_NONE:\n\tdefault: {\n\t\tDUK_D(DUK_DPRINT(\"invalid ivalue type: %ld\", (long) x->t));\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* evaluate to plain value, no forced register (temp/bound reg both ok) */\nDUK_LOCAL void duk__ivalue_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tduk__ivalue_toplain_raw(comp_ctx, x, -1 /*forced_reg*/);\n}\n\n/* evaluate to final form (e.g. coerce GETPROP to code), throw away temp */\nDUK_LOCAL void duk__ivalue_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tduk_regconst_t temp;\n\n\t/* If duk__ivalue_toplain_raw() allocates a temp, forget it and\n\t * restore next temp state.\n\t */\n\ttemp = DUK__GETTEMP(comp_ctx);\n\tduk__ivalue_toplain_raw(comp_ctx, x, -1 /*forced_reg*/);\n\tDUK__SETTEMP(comp_ctx, temp);\n}\n\n/* Coerce an duk_ivalue to a register or constant; result register may\n * be a temp or a bound register.\n *\n * The duk_ivalue argument ('x') is converted into a regconst as a\n * side effect.\n */\nDUK_LOCAL\nduk_regconst_t duk__ivalue_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                          duk_ivalue *x,\n                                          duk_regconst_t forced_reg,\n                                          duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg;\n\tDUK_UNREF(thr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__ivalue_toregconst_raw(): x={t=%ld,op=%ld,x1={%ld:%ld:%!T},x2={%ld:%ld:%!T}}, \"\n\t                     \"forced_reg=%ld, flags 0x%08lx: allow_const=%ld require_temp=%ld require_short=%ld\",\n\t                     (long) x->t, (long) x->op,\n\t                     (long) x->x1.t, (long) x->x1.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x1.valstack_idx),\n\t                     (long) x->x2.t, (long) x->x2.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x2.valstack_idx),\n\t                     (long) forced_reg,\n\t                     (unsigned long) flags,\n\t                     (long) ((flags & DUK__IVAL_FLAG_ALLOW_CONST) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_SHORT) ? 1 : 0)));\n\n\t/* first coerce to a plain value */\n\tduk__ivalue_toplain_raw(comp_ctx, x, forced_reg);\n\tDUK_ASSERT(x->t == DUK_IVAL_PLAIN);\n\n\t/* then to a register */\n\treg = duk__ispec_toregconst_raw(comp_ctx, &x->x1, forced_reg, flags);\n\tduk__ivalue_regconst(x, reg);\n\n\treturn reg;\n}\n\nDUK_LOCAL duk_regconst_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, 0 /*flags*/);\n}\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__ivalue_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/);\n}\n#endif\n\nDUK_LOCAL void duk__ivalue_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_int_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\t(void) duk__ivalue_toregconst_raw(comp_ctx, x, forced_reg, 0 /*flags*/);\n}\n\nDUK_LOCAL duk_regconst_t duk__ivalue_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n}\n\nDUK_LOCAL duk_regconst_t duk__ivalue_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/);\n}\n\n/* The issues below can be solved with better flags */\n\n/* XXX: many operations actually want toforcedtemp() -- brand new temp? */\n/* XXX: need a toplain_ignore() which will only coerce a value to a temp\n * register if it might have a side effect.  Side-effect free values do not\n * need to be coerced.\n */\n\n/*\n *  Identifier handling\n */\n\nDUK_LOCAL duk_regconst_t duk__lookup_active_register_binding(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hstring *h_varname;\n\tduk_regconst_t ret;\n\n\tDUK_DDD(DUK_DDDPRINT(\"resolving identifier reference to '%!T'\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/*\n\t *  Special name handling\n\t */\n\n\th_varname = duk_known_hstring(thr, -1);\n\n\tif (h_varname == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"flagging function as accessing 'arguments'\"));\n\t\tcomp_ctx->curr_func.id_access_arguments = 1;\n\t}\n\n\t/*\n\t *  Inside one or more 'with' statements fall back to slow path always.\n\t *  (See e.g. test-stmt-with.js.)\n\t */\n\n\tif (comp_ctx->curr_func.with_depth > 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup inside a 'with' -> fall back to slow path\"));\n\t\tgoto slow_path_own;\n\t}\n\n\t/*\n\t *  Any catch bindings (\"catch (e)\") also affect identifier binding.\n\t *\n\t *  Currently, the varmap is modified for the duration of the catch\n\t *  clause to ensure any identifier accesses with the catch variable\n\t *  name will use slow path.\n\t */\n\n\tduk_get_prop(thr, comp_ctx->curr_func.varmap_idx);\n\tif (duk_is_number(thr, -1)) {\n\t\tret = duk_to_int(thr, -1);\n\t\tduk_pop(thr);\n\t} else {\n\t\tduk_pop(thr);\n\t\tif (comp_ctx->curr_func.catch_depth > 0 || comp_ctx->curr_func.with_depth > 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slow path access from inside a try-catch or with needs _Varmap\"));\n\t\t\tgoto slow_path_own;\n\t\t} else {\n\t\t\t/* In this case we're doing a variable lookup that doesn't\n\t\t\t * match our own variables, so _Varmap won't be needed at\n\t\t\t * run time.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slow path access outside of try-catch and with, no need for _Varmap\"));\n\t\t\tgoto slow_path_notown;\n\t\t}\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup -> reg %ld\", (long) ret));\n\treturn ret;\n\n slow_path_notown:\n\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup -> slow path, not own variable\"));\n\n\tcomp_ctx->curr_func.id_access_slow = 1;\n\treturn (duk_regconst_t) -1;\n\n slow_path_own:\n\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup -> slow path, may be own variable\"));\n\n\tcomp_ctx->curr_func.id_access_slow = 1;\n\tcomp_ctx->curr_func.id_access_slow_own = 1;\n\treturn (duk_regconst_t) -1;\n}\n\n/* Lookup an identifier name in the current varmap, indicating whether the\n * identifier is register-bound and if not, allocating a constant for the\n * identifier name.  Returns 1 if register-bound, 0 otherwise.  Caller can\n * also check (out_reg_varbind >= 0) to check whether or not identifier is\n * register bound.  The caller must NOT use out_rc_varname at all unless\n * return code is 0 or out_reg_varbind is < 0; this is becuase out_rc_varname\n * is unsigned and doesn't have a \"unused\" / none value.\n */\nDUK_LOCAL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *comp_ctx, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg_varbind;\n\tduk_regconst_t rc_varname;\n\n\t/* [ ... varname ] */\n\n\tduk_dup_top(thr);\n\treg_varbind = duk__lookup_active_register_binding(comp_ctx);\n\n\tif (reg_varbind >= 0) {\n\t\t*out_reg_varbind = reg_varbind;\n\t\t*out_rc_varname = 0;  /* duk_regconst_t is unsigned, so use 0 as dummy value (ignored by caller) */\n\t\tduk_pop(thr);\n\t\treturn 1;\n\t} else {\n\t\trc_varname = duk__getconst(comp_ctx);\n\t\t*out_reg_varbind = -1;\n\t\t*out_rc_varname = rc_varname;\n\t\treturn 0;\n\t}\n}\n\n/*\n *  Label handling\n *\n *  Labels are initially added with flags prohibiting both break and continue.\n *  When the statement type is finally uncovered (after potentially multiple\n *  labels), all the labels are updated to allow/prohibit break and continue.\n */\n\nDUK_LOCAL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_int_t pc_label, duk_int_t label_id) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_size_t n;\n\tduk_size_t new_size;\n\tduk_uint8_t *p;\n\tduk_labelinfo *li_start, *li;\n\n\t/* Duplicate (shadowing) labels are not allowed, except for the empty\n\t * labels (which are used as default labels for switch and iteration\n\t * statements).\n\t *\n\t * We could also allow shadowing of non-empty pending labels without any\n\t * other issues than breaking the required label shadowing requirements\n\t * of the E5 specification, see Section 12.12.\n\t */\n\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tli = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\tn = (duk_size_t) (li - li_start);\n\n\twhile (li > li_start) {\n\t\tli--;\n\n\t\tif (li->h_label == h_label && h_label != DUK_HTHREAD_STRING_EMPTY_STRING(thr)) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_DUPLICATE_LABEL);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t}\n\n\tduk_push_hstring(thr, h_label);\n\tDUK_ASSERT(n <= DUK_UARRIDX_MAX);  /* label limits */\n\t(void) duk_put_prop_index(thr, comp_ctx->curr_func.labelnames_idx, (duk_uarridx_t) n);\n\n\tnew_size = (n + 1) * sizeof(duk_labelinfo);\n\tduk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, new_size);\n\t/* XXX: slack handling, slow now */\n\n\t/* relookup after possible realloc */\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tDUK_UNREF(li_start);  /* silence scan-build warning */\n\tli = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\tli--;\n\n\t/* Labels can be used for iteration statements but also for other statements,\n\t * in particular a label can be used for a block statement.  All cases of a\n\t * named label accept a 'break' so that flag is set here.  Iteration statements\n\t * also allow 'continue', so that flag is updated when we figure out the\n\t * statement type.\n\t */\n\n\tli->flags = DUK_LABEL_FLAG_ALLOW_BREAK;\n\tli->label_id = label_id;\n\tli->h_label = h_label;\n\tli->catch_depth = comp_ctx->curr_func.catch_depth;   /* catch depth from current func */\n\tli->pc_label = pc_label;\n\n\tDUK_DDD(DUK_DDDPRINT(\"registered label: flags=0x%08lx, id=%ld, name=%!O, catch_depth=%ld, pc_label=%ld\",\n\t                     (unsigned long) li->flags, (long) li->label_id, (duk_heaphdr *) li->h_label,\n\t                     (long) li->catch_depth, (long) li->pc_label));\n}\n\n/* Update all labels with matching label_id. */\nDUK_LOCAL void duk__update_label_flags(duk_compiler_ctx *comp_ctx, duk_int_t label_id, duk_small_uint_t flags) {\n\tduk_uint8_t *p;\n\tduk_labelinfo *li_start, *li;\n\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(comp_ctx->thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tli = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\n\t/* Match labels starting from latest; once label_id no longer matches, we can\n\t * safely exit without checking the rest of the labels (only the topmost labels\n\t * are ever updated).\n\t */\n\twhile (li > li_start) {\n\t\tli--;\n\n\t\tif (li->label_id != label_id) {\n\t\t\tbreak;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"updating (overwriting) label flags for li=%p, label_id=%ld, flags=%ld\",\n\t\t                     (void *) li, (long) label_id, (long) flags));\n\n\t\tli->flags = flags;\n\t}\n}\n\n/* Lookup active label information.  Break/continue distinction is necessary to handle switch\n * statement related labels correctly: a switch will only catch a 'break', not a 'continue'.\n *\n * An explicit label cannot appear multiple times in the active set, but empty labels (unlabelled\n * iteration and switch statements) can.  A break will match the closest unlabelled or labelled\n * statement.  A continue will match the closest unlabelled or labelled iteration statement.  It is\n * a syntax error if a continue matches a labelled switch statement; because an explicit label cannot\n * be duplicated, the continue cannot match any valid label outside the switch.\n *\n * A side effect of these rules is that a LABEL statement related to a switch should never actually\n * catch a continue abrupt completion at run-time.  Hence an INVALID opcode can be placed in the\n * continue slot of the switch's LABEL statement.\n */\n\n/* XXX: awkward, especially the bunch of separate output values -> output struct? */\nDUK_LOCAL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_bool_t is_break, duk_int_t *out_label_id, duk_int_t *out_label_catch_depth, duk_int_t *out_label_pc, duk_bool_t *out_is_closest) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_uint8_t *p;\n\tduk_labelinfo *li_start, *li_end, *li;\n\tduk_bool_t match = 0;\n\n\tDUK_DDD(DUK_DDDPRINT(\"looking up active label: label='%!O', is_break=%ld\",\n\t                     (duk_heaphdr *) h_label, (long) is_break));\n\n\tDUK_UNREF(thr);\n\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tli_end = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\tli = li_end;\n\n\t/* Match labels starting from latest label because there can be duplicate empty\n\t * labels in the label set.\n\t */\n\twhile (li > li_start) {\n\t\tli--;\n\n\t\tif (li->h_label != h_label) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"labelinfo[%ld] ->'%!O' != %!O\",\n\t\t\t                     (long) (li - li_start),\n\t\t\t                     (duk_heaphdr *) li->h_label,\n\t\t\t                     (duk_heaphdr *) h_label));\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"labelinfo[%ld] -> '%!O' label name matches (still need to check type)\",\n\t\t                     (long) (li - li_start), (duk_heaphdr *) h_label));\n\n\t\t/* currently all labels accept a break, so no explicit check for it now */\n\t\tDUK_ASSERT(li->flags & DUK_LABEL_FLAG_ALLOW_BREAK);\n\n\t\tif (is_break) {\n\t\t\t/* break matches always */\n\t\t\tmatch = 1;\n\t\t\tbreak;\n\t\t} else if (li->flags & DUK_LABEL_FLAG_ALLOW_CONTINUE) {\n\t\t\t/* iteration statements allow continue */\n\t\t\tmatch = 1;\n\t\t\tbreak;\n\t\t} else {\n\t\t\t/* continue matched this label -- we can only continue if this is the empty\n\t\t\t * label, for which duplication is allowed, and thus there is hope of\n\t\t\t * finding a match deeper in the label stack.\n\t\t\t */\n\t\t\tif (h_label != DUK_HTHREAD_STRING_EMPTY_STRING(thr)) {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LABEL);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"continue matched an empty label which does not \"\n\t\t\t\t                     \"allow a continue -> continue lookup deeper in label stack\"));\n\t\t\t}\n\t\t}\n\t}\n\t/* XXX: match flag is awkward, rework */\n\tif (!match) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LABEL);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"label match: %!O -> label_id %ld, catch_depth=%ld, pc_label=%ld\",\n\t                     (duk_heaphdr *) h_label, (long) li->label_id,\n\t                     (long) li->catch_depth, (long) li->pc_label));\n\n\t*out_label_id = li->label_id;\n\t*out_label_catch_depth = li->catch_depth;\n\t*out_label_pc = li->pc_label;\n\t*out_is_closest = (li == li_end - 1);\n}\n\nDUK_LOCAL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, duk_size_t len) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\tduk_set_length(thr, comp_ctx->curr_func.labelnames_idx, len);\n\tduk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, sizeof(duk_labelinfo) * len);\n}\n\n/*\n *  Expression parsing: duk__expr_nud(), duk__expr_led(), duk__expr_lbp(), and helpers.\n *\n *  - duk__expr_nud(): (\"null denotation\"): process prev_token as a \"start\" of an expression (e.g. literal)\n *  - duk__expr_led(): (\"left denotation\"): process prev_token in the \"middle\" of an expression (e.g. operator)\n *  - duk__expr_lbp(): (\"left-binding power\"): return left-binding power of curr_token\n */\n\n/* object literal key tracking flags */\n#define DUK__OBJ_LIT_KEY_PLAIN  (1 << 0)  /* key encountered as a plain property */\n#define DUK__OBJ_LIT_KEY_GET    (1 << 1)  /* key encountered as a getter */\n#define DUK__OBJ_LIT_KEY_SET    (1 << 2)  /* key encountered as a setter */\n\nDUK_LOCAL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg_obj;                 /* result reg */\n\tduk_regconst_t reg_temp;                /* temp reg */\n\tduk_regconst_t temp_start;              /* temp reg value for start of loop */\n\tduk_small_uint_t max_init_values;  /* max # of values initialized in one MPUTARR set */\n\tduk_small_uint_t num_values;       /* number of values in current MPUTARR set */\n\tduk_uarridx_t curr_idx;            /* current (next) array index */\n\tduk_uarridx_t start_idx;           /* start array index of current MPUTARR set */\n\tduk_uarridx_t init_idx;            /* last array index explicitly initialized, +1 */\n\tduk_bool_t require_comma;          /* next loop requires a comma */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tduk_int_t pc_newarr;\n\tduk_compiler_instr *instr;\n#endif\n\n\t/* DUK_TOK_LBRACKET already eaten, current token is right after that */\n\tDUK_ASSERT(comp_ctx->prev_token.t == DUK_TOK_LBRACKET);\n\n\tmax_init_values = DUK__MAX_ARRAY_INIT_VALUES;  /* XXX: depend on available temps? */\n\n\treg_obj = DUK__ALLOCTEMP(comp_ctx);\n#if !defined(DUK_USE_PREFER_SIZE)\n\tpc_newarr = duk__get_current_pc(comp_ctx);\n#endif\n\tduk__emit_bc(comp_ctx, DUK_OP_NEWARR, reg_obj);  /* XXX: patch initial size hint afterwards? */\n\ttemp_start = DUK__GETTEMP(comp_ctx);\n\n\t/*\n\t *  Emit initializers in sets of maximum max_init_values.\n\t *  Corner cases such as single value initializers do not have\n\t *  special handling now.\n\t *\n\t *  Elided elements must not be emitted as 'undefined' values,\n\t *  because such values would be enumerable (which is incorrect).\n\t *  Also note that trailing elisions must be reflected in the\n\t *  length of the final array but cause no elements to be actually\n\t *  inserted.\n\t */\n\n\tcurr_idx = 0;\n\tinit_idx = 0;         /* tracks maximum initialized index + 1 */\n\tstart_idx = 0;\n\trequire_comma = 0;\n\n\tfor (;;) {\n\t\tnum_values = 0;\n\t\tDUK__SETTEMP(comp_ctx, temp_start);\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RBRACKET) {\n\t\t\tbreak;\n\t\t}\n\n\t\tfor (;;) {\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_RBRACKET) {\n\t\t\t\t/* the outer loop will recheck and exit */\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/* comma check */\n\t\t\tif (require_comma) {\n\t\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_COMMA) {\n\t\t\t\t\t/* comma after a value, expected */\n\t\t\t\t\tduk__advance(comp_ctx);\n\t\t\t\t\trequire_comma = 0;\n\t\t\t\t\tcontinue;\n\t\t\t\t} else {\n\t\t\t\t\tgoto syntax_error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_COMMA) {\n\t\t\t\t\t/* elision - flush */\n\t\t\t\t\tcurr_idx++;\n\t\t\t\t\tduk__advance(comp_ctx);\n\t\t\t\t\t/* if num_values > 0, MPUTARR emitted by outer loop after break */\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* else an array initializer element */\n\n\t\t\t/* initial index */\n\t\t\tif (num_values == 0) {\n\t\t\t\tstart_idx = curr_idx;\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_load_int32(comp_ctx, reg_temp, (duk_int32_t) start_idx);\n\t\t\t}\n\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);   /* alloc temp just in case, to update max temp */\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp);\n\t\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp /*forced_reg*/);\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\n\t\t\tnum_values++;\n\t\t\tcurr_idx++;\n\t\t\trequire_comma = 1;\n\n\t\t\tif (num_values >= max_init_values) {\n\t\t\t\t/* MPUTARR emitted by outer loop */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (num_values > 0) {\n\t\t\t/* - A is a source register (it's not a write target, but used\n\t\t\t *   to identify the target object) but can be shuffled.\n\t\t\t * - B cannot be shuffled normally because it identifies a range\n\t\t\t *   of registers, the emitter has special handling for this\n\t\t\t *   (the \"no shuffle\" flag must not be set).\n\t\t\t * - C is a non-register number and cannot be shuffled, but\n\t\t\t *   never needs to be.\n\t\t\t */\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_MPUTARR |\n\t\t\t                    DUK__EMIT_FLAG_NO_SHUFFLE_C |\n\t\t\t                    DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t                reg_obj,\n\t\t\t                temp_start,\n\t\t\t                (duk_regconst_t) (num_values + 1));\n\t\t\tinit_idx = start_idx + num_values;\n\n\t\t\t/* num_values and temp_start reset at top of outer loop */\n\t\t}\n\t}\n\n\t/* Update initil size for NEWARR, doesn't need to be exact and is\n\t * capped at A field limit.\n\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tinstr = duk__get_instr_ptr(comp_ctx, pc_newarr);\n\tinstr->ins |= DUK_ENC_OP_A(0, curr_idx > DUK_BC_A_MAX ? DUK_BC_A_MAX : curr_idx);\n#endif\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RBRACKET);\n\tduk__advance(comp_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"array literal done, curridx=%ld, initidx=%ld\",\n\t                     (long) curr_idx, (long) init_idx));\n\n\t/* trailing elisions? */\n\tif (curr_idx > init_idx) {\n\t\t/* yes, must set array length explicitly */\n\t\tDUK_DDD(DUK_DDDPRINT(\"array literal has trailing elisions which affect its length\"));\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk__emit_load_int32(comp_ctx, reg_temp, (duk_int_t) curr_idx);\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               DUK_OP_SETALEN | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t               reg_obj,\n\t\t               reg_temp);\n\t}\n\n\tDUK__SETTEMP(comp_ctx, temp_start);\n\n\tduk__ivalue_regconst(res, reg_obj);\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_ARRAY_LITERAL);\n\tDUK_WO_NORETURN(return;);\n}\n\ntypedef struct {\n\tduk_regconst_t reg_obj;\n\tduk_regconst_t temp_start;\n\tduk_small_uint_t num_pairs;\n\tduk_small_uint_t num_total_pairs;\n} duk__objlit_state;\n\nDUK_LOCAL void duk__objlit_flush_keys(duk_compiler_ctx *comp_ctx, duk__objlit_state *st) {\n\tif (st->num_pairs > 0) {\n\t\t/* - A is a source register (it's not a write target, but used\n\t\t *   to identify the target object) but can be shuffled.\n\t\t * - B cannot be shuffled normally because it identifies a range\n\t\t *   of registers, the emitter has special handling for this\n\t\t *   (the \"no shuffle\" flag must not be set).\n\t\t * - C is a non-register number and cannot be shuffled, but\n\t\t *   never needs to be.\n\t\t */\n\t\tDUK_ASSERT(st->num_pairs > 0);\n\t\tduk__emit_a_b_c(comp_ctx,\n\t\t                DUK_OP_MPUTOBJ |\n\t\t                    DUK__EMIT_FLAG_NO_SHUFFLE_C |\n\t\t                    DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t                st->reg_obj,\n\t\t                st->temp_start,\n\t\t                (duk_regconst_t) (st->num_pairs * 2));\n\t\tst->num_total_pairs += st->num_pairs;\n\t\tst->num_pairs = 0;\n\t}\n\tDUK__SETTEMP(comp_ctx, st->temp_start);\n}\n\nDUK_LOCAL duk_bool_t duk__objlit_load_key(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_token *tok, duk_regconst_t reg_temp) {\n\tif (tok->t_nores == DUK_TOK_IDENTIFIER || tok->t_nores == DUK_TOK_STRING) {\n\t\t/* same handling for identifiers and strings */\n\t\tDUK_ASSERT(tok->str1 != NULL);\n\t\tduk_push_hstring(comp_ctx->thr, tok->str1);\n\t} else if (tok->t == DUK_TOK_NUMBER) {\n\t\t/* numbers can be loaded as numbers and coerced on the fly */\n\t\tduk_push_number(comp_ctx->thr, tok->num);\n\t} else {\n\t\treturn 1;  /* error */\n\t}\n\n\tduk__ivalue_plain_fromstack(comp_ctx, res);\n\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\tduk__ivalue_toforcedreg(comp_ctx, res, reg_temp);\n\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\treturn 0;\n}\n\nDUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk__objlit_state st;\n\tduk_regconst_t reg_temp;          /* temp reg */\n\tduk_small_uint_t max_init_pairs;  /* max # of key-value pairs initialized in one MPUTOBJ set */\n\tduk_bool_t first;                 /* first value: comma must not precede the value */\n\tduk_bool_t is_set, is_get;        /* temps */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tduk_int_t pc_newobj;\n\tduk_compiler_instr *instr;\n#endif\n\n\tDUK_ASSERT(comp_ctx->prev_token.t == DUK_TOK_LCURLY);\n\n\tmax_init_pairs = DUK__MAX_OBJECT_INIT_PAIRS;  /* XXX: depend on available temps? */\n\n\tst.reg_obj = DUK__ALLOCTEMP(comp_ctx);    /* target object */\n\tst.temp_start = DUK__GETTEMP(comp_ctx);   /* start of MPUTOBJ argument list */\n\tst.num_pairs = 0;                         /* number of key/value pairs emitted for current MPUTOBJ set */\n\tst.num_total_pairs = 0;                   /* number of key/value pairs emitted overall */\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\tpc_newobj = duk__get_current_pc(comp_ctx);\n#endif\n\tduk__emit_bc(comp_ctx, DUK_OP_NEWOBJ, st.reg_obj);\n\n\t/*\n\t *  Emit initializers in sets of maximum max_init_pairs keys.\n\t *  Setter/getter is handled separately and terminates the\n\t *  current set of initializer values.  Corner cases such as\n\t *  single value initializers do not have special handling now.\n\t */\n\n\tfirst = 1;\n\tfor (;;) {\n\t\t/*\n\t\t *  ES5 and ES2015+ provide a lot of different PropertyDefinition\n\t\t *  formats, see http://www.ecma-international.org/ecma-262/6.0/#sec-object-initializer.\n\t\t *\n\t\t *  PropertyName can be IdentifierName (includes reserved words), a string\n\t\t *  literal, or a number literal.  Note that IdentifierName allows 'get' and\n\t\t *  'set' too, so we need to look ahead to the next token to distinguish:\n\t\t *\n\t\t *     { get : 1 }\n\t\t *\n\t\t *  and\n\t\t *\n\t\t *     { get foo() { return 1 } }\n\t\t *     { get get() { return 1 } }    // 'get' as getter propertyname\n\t\t *\n\t\t *  Finally, a trailing comma is allowed.\n\t\t *\n\t\t *  Key name is coerced to string at compile time (and ends up as a\n\t\t *  a string constant) even for numeric keys (e.g. \"{1:'foo'}\").\n\t\t *  These could be emitted using e.g. LDINT, but that seems hardly\n\t\t *  worth the effort and would increase code size.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"object literal loop, curr_token->t = %ld\",\n\t\t                     (long) comp_ctx->curr_token.t));\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (first) {\n\t\t\tfirst = 0;\n\t\t} else {\n\t\t\tif (comp_ctx->curr_token.t != DUK_TOK_COMMA) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t\tduk__advance(comp_ctx);\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\t\t/* trailing comma followed by rcurly */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* Advance to get one step of lookup. */\n\t\tduk__advance(comp_ctx);\n\n\t\t/* Flush current MPUTOBJ if enough many pairs gathered. */\n\t\tif (st.num_pairs >= max_init_pairs) {\n\t\t\tduk__objlit_flush_keys(comp_ctx, &st);\n\t\t\tDUK_ASSERT(st.num_pairs == 0);\n\t\t}\n\n\t\t/* Reset temp register state and reserve reg_temp and\n\t\t * reg_temp + 1 for handling the current property.\n\t\t */\n\t\tDUK__SETTEMP(comp_ctx, st.temp_start + 2 * (duk_regconst_t) st.num_pairs);\n\t\treg_temp = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\t\t/* NOTE: \"get\" and \"set\" are not officially ReservedWords and the lexer\n\t\t * currently treats them always like ordinary identifiers (DUK_TOK_GET\n\t\t * and DUK_TOK_SET are unused).  They need to be detected based on the\n\t\t * identifier string content.\n\t\t */\n\n\t\tis_get = (comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t          comp_ctx->prev_token.str1 == DUK_HTHREAD_STRING_GET(thr));\n\t\tis_set = (comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t          comp_ctx->prev_token.str1 == DUK_HTHREAD_STRING_SET(thr));\n\t\tif ((is_get || is_set) && comp_ctx->curr_token.t != DUK_TOK_COLON) {\n\t\t\t/* getter/setter */\n\t\t\tduk_int_t fnum;\n\n\t\t\tduk__objlit_flush_keys(comp_ctx, &st);\n\t\t\tDUK_ASSERT(DUK__GETTEMP(comp_ctx) == st.temp_start);  /* 2 regs are guaranteed to be allocated w.r.t. temp_max */\n\t\t\treg_temp = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\t\t\tif (duk__objlit_load_key(comp_ctx, res, &comp_ctx->curr_token, reg_temp) != 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\t/* curr_token = get/set name */\n\t\t\tfnum = duk__parse_func_like_fnum(comp_ctx, DUK__FUNC_FLAG_GETSET);\n\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CLOSURE,\n\t\t\t               st.temp_start + 1,\n\t\t\t               (duk_regconst_t) fnum);\n\n\t\t\t/* Slot C is used in a non-standard fashion (range of regs),\n\t\t\t * emitter code has special handling for it (must not set the\n\t\t\t * \"no shuffle\" flag).\n\t\t\t */\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t              (is_get ? DUK_OP_INITGET : DUK_OP_INITSET) | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t              st.reg_obj,\n\t\t\t              st.temp_start);   /* temp_start+0 = key, temp_start+1 = closure */\n\n\t\t\tDUK_ASSERT(st.num_pairs == 0);  /* temp state is reset on next loop */\n#if defined(DUK_USE_ES6)\n\t\t} else if (comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t           (comp_ctx->curr_token.t == DUK_TOK_COMMA || comp_ctx->curr_token.t == DUK_TOK_RCURLY)) {\n\t\t\tduk_bool_t load_rc;\n\n\t\t\tload_rc = duk__objlit_load_key(comp_ctx, res, &comp_ctx->prev_token, reg_temp);\n\t\t\tDUK_UNREF(load_rc);\n\t\t\tDUK_ASSERT(load_rc == 0);  /* always succeeds because token is identifier */\n\n\t\t\tduk__ivalue_var_hstring(comp_ctx, res, comp_ctx->prev_token.str1);\n\t\t\tDUK_ASSERT(DUK__GETTEMP(comp_ctx) == reg_temp + 1);\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_temp + 1);\n\n\t\t\tst.num_pairs++;\n\t\t} else if ((comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER ||\n\t\t            comp_ctx->prev_token.t == DUK_TOK_STRING ||\n\t\t            comp_ctx->prev_token.t == DUK_TOK_NUMBER) &&\n\t\t           comp_ctx->curr_token.t == DUK_TOK_LPAREN) {\n\t\t\tduk_int_t fnum;\n\n\t\t\t/* Parsing-wise there's a small hickup here: the token parsing\n\t\t\t * state is one step too advanced for the function parse helper\n\t\t\t * compared to other cases.  The current solution is an extra\n\t\t\t * flag to indicate whether function parsing should use the\n\t\t\t * current or the previous token to starting parsing from.\n\t\t\t */\n\n\t\t\tif (duk__objlit_load_key(comp_ctx, res, &comp_ctx->prev_token, reg_temp) != 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\tfnum = duk__parse_func_like_fnum(comp_ctx, DUK__FUNC_FLAG_USE_PREVTOKEN | DUK__FUNC_FLAG_METDEF);\n\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CLOSURE,\n\t\t\t               reg_temp + 1,\n\t\t\t               (duk_regconst_t) fnum);\n\n\t\t\tst.num_pairs++;\n#endif  /* DUK_USE_ES6 */\n\t\t} else {\n#if defined(DUK_USE_ES6)\n\t\t\tif (comp_ctx->prev_token.t == DUK_TOK_LBRACKET) {\n\t\t\t\t/* ES2015 computed property name.  Executor ToPropertyKey()\n\t\t\t\t * coerces the key at runtime.\n\t\t\t\t */\n\t\t\t\tDUK__SETTEMP(comp_ctx, reg_temp);\n\t\t\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_FOR_EXPR, reg_temp);\n\t\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_RBRACKET);\n\n\t\t\t\t/* XXX: If next token is '(' we're dealing with\n\t\t\t\t * the method shorthand with a computed name,\n\t\t\t\t * e.g. { [Symbol.for('foo')](a,b) {} }.  This\n\t\t\t\t * form is not yet supported and causes a\n\t\t\t\t * SyntaxError on the DUK_TOK_COLON check below.\n\t\t\t\t */\n\t\t\t}\n\t\t\telse\n#endif  /* DUK_USE_ES6 */\n\t\t\t{\n\t\t\t\tif (duk__objlit_load_key(comp_ctx, res, &comp_ctx->prev_token, reg_temp) != 0) {\n\t\t\t\t\tgoto syntax_error;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\t\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp + 1 /*forced_reg*/);\n\n\t\t\tst.num_pairs++;\n\t\t}\n\t}  /* property loop */\n\n\t/* Flush remaining properties. */\n\tduk__objlit_flush_keys(comp_ctx, &st);\n\tDUK_ASSERT(st.num_pairs == 0);\n\tDUK_ASSERT(DUK__GETTEMP(comp_ctx) == st.temp_start);\n\n\t/* Update initial size for NEWOBJ.  The init size doesn't need to be\n\t * exact as the purpose is just to avoid object resizes in common\n\t * cases.  The size is capped to field A limit, and will be too high\n\t * if the object literal contains duplicate keys (this is harmless but\n\t * increases memory traffic if the object is compacted later on).\n\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tinstr = duk__get_instr_ptr(comp_ctx, pc_newobj);\n\tinstr->ins |= DUK_ENC_OP_A(0, st.num_total_pairs > DUK_BC_A_MAX ? DUK_BC_A_MAX : st.num_total_pairs);\n#endif\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RCURLY);\n\tduk__advance(comp_ctx);  /* No RegExp after object literal. */\n\n\tduk__ivalue_regconst(res, st.reg_obj);\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_OBJECT_LITERAL);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Parse argument list.  Arguments are written to temps starting from\n * \"next temp\".  Returns number of arguments parsed.  Expects left paren\n * to be already eaten, and eats the right paren before returning.\n */\nDUK_LOCAL duk_int_t duk__parse_arguments(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_int_t nargs = 0;\n\tduk_regconst_t reg_temp;\n\n\t/* Note: expect that caller has already eaten the left paren */\n\n\tDUK_DDD(DUK_DDDPRINT(\"start parsing arguments, prev_token.t=%ld, curr_token.t=%ld\",\n\t                     (long) comp_ctx->prev_token.t, (long) comp_ctx->curr_token.t));\n\n\tfor (;;) {\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RPAREN) {\n\t\t\tbreak;\n\t\t}\n\t\tif (nargs > 0) {\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COMMA);\n\t\t}\n\n\t\t/* We want the argument expression value to go to \"next temp\"\n\t\t * without additional moves.  That should almost always be the\n\t\t * case, but we double check after expression parsing.\n\t\t *\n\t\t * This is not the cleanest possible approach.\n\t\t */\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);  /* bump up \"allocated\" reg count, just in case */\n\t\tDUK__SETTEMP(comp_ctx, reg_temp);\n\n\t\t/* binding power must be high enough to NOT allow comma expressions directly */\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp);  /* always allow 'in', coerce to 'tr' just in case */\n\n\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\t\tnargs++;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"argument #%ld written into reg %ld\", (long) nargs, (long) reg_temp));\n\t}\n\n\t/* eat the right paren */\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* RegExp mode does not matter. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing arguments\"));\n\n\treturn nargs;\n}\n\nDUK_LOCAL duk_bool_t duk__expr_is_empty(duk_compiler_ctx *comp_ctx) {\n\t/* empty expressions can be detected conveniently with nud/led counts */\n\treturn (comp_ctx->curr_func.nud_count == 0) &&\n\t       (comp_ctx->curr_func.led_count == 0);\n}\n\nDUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_token *tk;\n\tduk_regconst_t temp_at_entry;\n\tduk_small_uint_t tok;\n\tduk_uint32_t args;  /* temp variable to pass constants and flags to shared code */\n\n\t/*\n\t *  ctx->prev_token     token to process with duk__expr_nud()\n\t *  ctx->curr_token     updated by caller\n\t *\n\t *  Note: the token in the switch below has already been eaten.\n\t */\n\n\ttemp_at_entry = DUK__GETTEMP(comp_ctx);\n\n\tcomp_ctx->curr_func.nud_count++;\n\n\ttk = &comp_ctx->prev_token;\n\ttok = tk->t;\n\tres->t = DUK_IVAL_NONE;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__expr_nud(), prev_token.t=%ld, allow_in=%ld, paren_level=%ld\",\n\t                     (long) tk->t, (long) comp_ctx->curr_func.allow_in, (long) comp_ctx->curr_func.paren_level));\n\n\tswitch (tok) {\n\n\t/* PRIMARY EXPRESSIONS */\n\n\tcase DUK_TOK_THIS: {\n\t\tduk_regconst_t reg_temp;\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk__emit_bc(comp_ctx,\n\t\t             DUK_OP_LDTHIS,\n\t\t             reg_temp);\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\tcase DUK_TOK_IDENTIFIER: {\n\t\tduk__ivalue_var_hstring(comp_ctx, res, tk->str1);\n\t\treturn;\n\t}\n\tcase DUK_TOK_NULL: {\n\t\tduk_push_null(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_TRUE: {\n\t\tduk_push_true(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_FALSE: {\n\t\tduk_push_false(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_NUMBER: {\n\t\tduk_push_number(thr, tk->num);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_STRING: {\n\t\tDUK_ASSERT(tk->str1 != NULL);\n\t\tduk_push_hstring(thr, tk->str1);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_REGEXP: {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tduk_regconst_t reg_temp;\n\t\tduk_regconst_t rc_re_bytecode;  /* const */\n\t\tduk_regconst_t rc_re_source;    /* const */\n\n\t\tDUK_ASSERT(tk->str1 != NULL);\n\t\tDUK_ASSERT(tk->str2 != NULL);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"emitting regexp op, str1=%!O, str2=%!O\",\n\t\t                     (duk_heaphdr *) tk->str1,\n\t\t                     (duk_heaphdr *) tk->str2));\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk_push_hstring(thr, tk->str1);\n\t\tduk_push_hstring(thr, tk->str2);\n\n\t\t/* [ ... pattern flags ] */\n\n\t\tduk_regexp_compile(thr);\n\n\t\t/* [ ... escaped_source bytecode ] */\n\n\t\trc_re_bytecode = duk__getconst(comp_ctx);\n\t\trc_re_source = duk__getconst(comp_ctx);\n\n\t\tduk__emit_a_b_c(comp_ctx,\n\t\t                DUK_OP_REGEXP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t                reg_temp /*a*/,\n\t\t                rc_re_bytecode /*b*/,\n\t\t                rc_re_source /*c*/);\n\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\tgoto syntax_error;\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t}\n\tcase DUK_TOK_LBRACKET: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsing array literal\"));\n\t\tduk__nud_array_literal(comp_ctx, res);\n\t\treturn;\n\t}\n\tcase DUK_TOK_LCURLY: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsing object literal\"));\n\t\tduk__nud_object_literal(comp_ctx, res);\n\t\treturn;\n\t}\n\tcase DUK_TOK_LPAREN: {\n\t\tduk_bool_t prev_allow_in;\n\n\t\tcomp_ctx->curr_func.paren_level++;\n\t\tprev_allow_in = comp_ctx->curr_func.allow_in;\n\t\tcomp_ctx->curr_func.allow_in = 1; /* reset 'allow_in' for parenthesized expression */\n\n\t\tduk__expr(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);  /* Expression, terminates at a ')' */\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* No RegExp after parenthesized expression. */\n\t\tcomp_ctx->curr_func.allow_in = prev_allow_in;\n\t\tcomp_ctx->curr_func.paren_level--;\n\t\treturn;\n\t}\n\n\t/* MEMBER/NEW/CALL EXPRESSIONS */\n\n\tcase DUK_TOK_NEW: {\n\t\t/*\n\t\t *  Parsing an expression starting with 'new' is tricky because\n\t\t *  there are multiple possible productions deriving from\n\t\t *  LeftHandSideExpression which begin with 'new'.\n\t\t *\n\t\t *  We currently resort to one-token lookahead to distinguish the\n\t\t *  cases.  Hopefully this is correct.  The binding power must be\n\t\t *  such that parsing ends at an LPAREN (CallExpression) but not at\n\t\t *  a PERIOD or LBRACKET (MemberExpression).\n\t\t *\n\t\t *  See doc/compiler.rst for discussion on the parsing approach,\n\t\t *  and testcases/test-dev-new.js for a bunch of documented tests.\n\t\t */\n\n\t\tduk_regconst_t reg_target;\n\t\tduk_int_t nargs;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"begin parsing new expression\"));\n\n\t\treg_target = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n#if defined(DUK_USE_ES6)\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_PERIOD) {\n\t\t\t/* new.target */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new.target\"));\n\t\t\tduk__advance(comp_ctx);\n\t\t\tif (comp_ctx->curr_token.t_nores != DUK_TOK_IDENTIFIER ||\n\t\t\t    !duk_hstring_equals_ascii_cstring(comp_ctx->curr_token.str1, \"target\")) {\n\t\t\t\tgoto syntax_error_newtarget;\n\t\t\t}\n\t\t\tif (comp_ctx->curr_func.is_global) {\n\t\t\t\tgoto syntax_error_newtarget;\n\t\t\t}\n\t\t\tduk__advance(comp_ctx);\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_NEWTARGET,\n\t\t\t             reg_target);\n\t\t\tduk__ivalue_regconst(res, reg_target);\n\t\t\treturn;\n\t\t}\n#endif  /* DUK_USE_ES6 */\n\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_CALL /*rbp_flags*/, reg_target /*forced_reg*/);\n\t\tduk__emit_bc(comp_ctx, DUK_OP_NEWOBJ, reg_target + 1);  /* default instance */\n\t\tDUK__SETTEMP(comp_ctx, reg_target + 2);\n\n\t\t/* XXX: 'new obj.noSuch()' doesn't use GETPROPC now which\n\t\t * makes the error message worse than for obj.noSuch().\n\t\t */\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_LPAREN) {\n\t\t\t/* 'new' MemberExpression Arguments */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new expression has argument list\"));\n\t\t\tduk__advance(comp_ctx);\n\t\t\tnargs = duk__parse_arguments(comp_ctx, res);  /* parse args starting from \"next temp\", reg_target + 1 */\n\t\t\t/* right paren eaten */\n\t\t} else {\n\t\t\t/* 'new' MemberExpression */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new expression has no argument list\"));\n\t\t\tnargs = 0;\n\t\t}\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t              DUK_OP_CALL0 | DUK_BC_CALL_FLAG_CONSTRUCT,\n\t\t              nargs /*num_args*/,\n\t\t              reg_target /*target*/);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"end parsing new expression\"));\n\n\t\tduk__ivalue_regconst(res, reg_target);\n\t\treturn;\n\t}\n\n\t/* FUNCTION EXPRESSIONS */\n\n\tcase DUK_TOK_FUNCTION: {\n\t\t/* Function expression.  Note that any statement beginning with 'function'\n\t\t * is handled by the statement parser as a function declaration, or a\n\t\t * non-standard function expression/statement (or a SyntaxError).  We only\n\t\t * handle actual function expressions (occurring inside an expression) here.\n\t\t *\n\t\t * O(depth^2) parse count for inner functions is handled by recording a\n\t\t * lexer offset on the first compilation pass, so that the function can\n\t\t * be efficiently skipped on the second pass.  This is encapsulated into\n\t\t * duk__parse_func_like_fnum().\n\t\t */\n\n\t\tduk_regconst_t reg_temp;\n\t\tduk_int_t fnum;\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t/* curr_token follows 'function' */\n\t\tfnum = duk__parse_func_like_fnum(comp_ctx, 0 /*flags*/);\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsed inner function -> fnum %ld\", (long) fnum));\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               DUK_OP_CLOSURE,\n\t\t               reg_temp /*a*/,\n\t\t               (duk_regconst_t) fnum /*bc*/);\n\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\n\t/* UNARY EXPRESSIONS */\n\n\tcase DUK_TOK_DELETE: {\n\t\t/* Delete semantics are a bit tricky.  The description in E5 specification\n\t\t * is kind of confusing, because it distinguishes between resolvability of\n\t\t * a reference (which is only known at runtime) seemingly at compile time\n\t\t * (= SyntaxError throwing).\n\t\t */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\t/* not allowed in strict mode, regardless of whether resolves;\n\t\t\t * in non-strict mode DELVAR handles both non-resolving and\n\t\t\t * resolving cases (the specification description is a bit confusing).\n\t\t\t */\n\n\t\t\tduk_regconst_t reg_temp;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\tif (comp_ctx->curr_func.is_strict) {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_CANNOT_DELETE_IDENTIFIER);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\n\t\t\tDUK__SETTEMP(comp_ctx, temp_at_entry);\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\t/* register bound variables are non-configurable -> always false */\n\t\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t\t             DUK_OP_LDFALSE,\n\t\t\t\t             reg_temp);\n\t\t\t} else {\n\t\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\t\trc_varname = duk__getconst(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_DELVAR,\n\t\t\t\t               reg_temp,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\t\t\tduk__ivalue_regconst(res, reg_temp);\n\t\t} else if (res->t == DUK_IVAL_PROP) {\n\t\t\tduk_regconst_t reg_temp;\n\t\t\tduk_regconst_t reg_obj;\n\t\t\tduk_regconst_t rc_key;\n\n\t\t\tDUK__SETTEMP(comp_ctx, temp_at_entry);\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_DELPROP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_temp,\n\t\t\t                reg_obj,\n\t\t\t                rc_key);\n\n\t\t\tduk__ivalue_regconst(res, reg_temp);\n\t\t} else {\n\t\t\t/* non-Reference deletion is always 'true', even in strict mode */\n\t\t\tduk_push_true(thr);\n\t\t\tgoto plain_value;\n\t\t}\n\t\treturn;\n\t}\n\tcase DUK_TOK_VOID: {\n\t\tduk__expr_toplain_ignore(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tduk_push_undefined(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_TYPEOF: {\n\t\t/* 'typeof' must handle unresolvable references without throwing\n\t\t * a ReferenceError (E5 Section 11.4.3).  Register mapped values\n\t\t * will never be unresolvable so special handling is only required\n\t\t * when an identifier is a \"slow path\" one.\n\t\t */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\n\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\t\t\tduk_regconst_t reg_temp;\n\n\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\tif (!duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"typeof for an identifier name which could not be resolved \"\n\t\t\t\t                     \"at compile time, need to use special run-time handling\"));\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_TYPEOFID,\n\t\t\t\t               reg_temp,\n\t\t\t\t               rc_varname);\n\t\t\t\tduk__ivalue_regconst(res, reg_temp);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\targs = DUK_OP_TYPEOF;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_INCREMENT: {\n\t\targs = (DUK_OP_PREINCP << 8) + DUK_OP_PREINCR;\n\t\tgoto preincdec;\n\t}\n\tcase DUK_TOK_DECREMENT: {\n\t\targs = (DUK_OP_PREDECP << 8) + DUK_OP_PREDECR;\n\t\tgoto preincdec;\n\t}\n\tcase DUK_TOK_ADD: {\n\t\t/* unary plus */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE &&\n\t\t    duk_is_number(thr, res->x1.valstack_idx)) {\n\t\t\t/* unary plus of a number is identity */\n\t\t\treturn;\n\t\t}\n\t\targs = DUK_OP_UNP;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_SUB: {\n\t\t/* unary minus */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE &&\n\t\t    duk_is_number(thr, res->x1.valstack_idx)) {\n\t\t\t/* this optimization is important to handle negative literals\n\t\t\t * (which are not directly provided by the lexical grammar)\n\t\t\t */\n\t\t\tduk_tval *tv_num;\n\t\t\tduk_double_union du;\n\n\t\t\ttv_num = DUK_GET_TVAL_POSIDX(thr, res->x1.valstack_idx);\n\t\t\tDUK_ASSERT(tv_num != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_num));\n\t\t\tdu.d = DUK_TVAL_GET_NUMBER(tv_num);\n\t\t\tdu.d = -du.d;\n\t\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\t\t\tDUK_TVAL_SET_NUMBER(tv_num, du.d);\n\t\t\treturn;\n\t\t}\n\t\targs = DUK_OP_UNM;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_BNOT: {\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\targs = DUK_OP_BNOT;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_LNOT: {\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE) {\n\t\t\t/* Very minimal inlining to handle common idioms '!0' and '!1',\n\t\t\t * and also boolean arguments like '!false' and '!true'.\n\t\t\t */\n\t\t\tduk_tval *tv_val;\n\n\t\t\ttv_val = DUK_GET_TVAL_POSIDX(thr, res->x1.valstack_idx);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tif (DUK_TVAL_IS_NUMBER(tv_val)) {\n\t\t\t\tduk_double_t d;\n\t\t\t\td = DUK_TVAL_GET_NUMBER(tv_val);\n\t\t\t\tif (d == 0.0) {\n\t\t\t\t\t/* Matches both +0 and -0 on purpose. */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"inlined lnot: !0 -> true\"));\n\t\t\t\t\tDUK_TVAL_SET_BOOLEAN_TRUE(tv_val);\n\t\t\t\t\treturn;\n\t\t\t\t} else if (d == 1.0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"inlined lnot: !1 -> false\"));\n\t\t\t\t\tDUK_TVAL_SET_BOOLEAN_FALSE(tv_val);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else if (DUK_TVAL_IS_BOOLEAN(tv_val)) {\n\t\t\t\tduk_small_uint_t v;\n\t\t\t\tv = DUK_TVAL_GET_BOOLEAN(tv_val);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"inlined lnot boolean: %ld\", (long) v));\n\t\t\t\tDUK_ASSERT(v == 0 || v == 1);\n\t\t\t\tDUK_TVAL_SET_BOOLEAN(tv_val, v ^ 0x01);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\targs = DUK_OP_LNOT;\n\t\tgoto unary;\n\t}\n\n\t}  /* end switch */\n\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);\n\tDUK_WO_NORETURN(return;);\n\n unary:\n\t{\n\t\t/* Unary opcodes use just the 'BC' register source because it\n\t\t * matches current shuffle limits, and maps cleanly to 16 high\n\t\t * bits of the opcode.\n\t\t */\n\n\t\tduk_regconst_t reg_src, reg_res;\n\n\t\treg_src = duk__ivalue_toregconst_raw(comp_ctx, res, -1 /*forced_reg*/, 0 /*flags*/);\n\t\tif (DUK__ISREG_TEMP(comp_ctx, reg_src)) {\n\t\t\treg_res = reg_src;\n\t\t} else {\n\t\t\treg_res = DUK__ALLOCTEMP(comp_ctx);\n\t\t}\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t             args,\n\t\t             reg_res,\n\t\t             reg_src);\n\t\tduk__ivalue_regconst(res, reg_res);\n\t\treturn;\n\t}\n\n preincdec:\n\t{\n\t\t/* preincrement and predecrement */\n\t\tduk_regconst_t reg_res;\n\t\tduk_small_uint_t args_op1 = args & 0xff;  /* DUK_OP_PREINCR/DUK_OP_PREDECR */\n\t\tduk_small_uint_t args_op2 = args >> 8;    /* DUK_OP_PREINCP_RR/DUK_OP_PREDECP_RR */\n\n\t\t/* Specific assumptions for opcode numbering. */\n\t\tDUK_ASSERT(DUK_OP_PREINCR + 4 == DUK_OP_PREINCV);\n\t\tDUK_ASSERT(DUK_OP_PREDECR + 4 == DUK_OP_PREDECV);\n\n\t\treg_res = DUK__ALLOCTEMP(comp_ctx);\n\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\th_varname = duk_known_hstring(thr, res->x1.valstack_idx);\n\n\t\t\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               args_op1,  /* e.g. DUK_OP_PREINCR */\n\t\t\t\t               reg_res,\n\t\t\t\t               reg_varbind);\n\t\t\t} else {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t                args_op1 + 4,  /* e.g. DUK_OP_PREINCV */\n\t\t\t\t                reg_res,\n\t\t\t\t                rc_varname);\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"preincdec to '%!O' -> reg_varbind=%ld, rc_varname=%ld\",\n\t\t\t                     (duk_heaphdr *) h_varname, (long) reg_varbind, (long) rc_varname));\n\t\t} else if (res->t == DUK_IVAL_PROP) {\n\t\t\tduk_regconst_t reg_obj;  /* allocate to reg only (not const) */\n\t\t\tduk_regconst_t rc_key;\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                args_op2 | DUK__EMIT_FLAG_BC_REGCONST,  /* e.g. DUK_OP_PREINCP */\n\t\t\t                reg_res,\n\t\t\t                reg_obj,\n\t\t\t                rc_key);\n\t\t} else {\n\t\t\t/* Technically return value is not needed because INVLHS will\n\t\t\t * unconditially throw a ReferenceError.  Coercion is necessary\n\t\t\t * for proper semantics (consider ToNumber() called for an object).\n\t\t\t * Use DUK_OP_UNP with a dummy register to get ToNumber().\n\t\t\t */\n\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_res);\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_UNP,\n\t\t\t             reg_res);  /* for side effects, result ignored */\n\t\t\tduk__emit_op_only(comp_ctx,\n\t\t\t                  DUK_OP_INVLHS);\n\t\t}\n\t\tDUK__SETTEMP(comp_ctx, reg_res + 1);\n\t\tduk__ivalue_regconst(res, reg_res);\n\t\treturn;\n\t}\n\n plain_value:\n\t{\n\t\t/* Stack top contains plain value */\n\t\tduk__ivalue_plain_fromstack(comp_ctx, res);\n\t\treturn;\n\t}\n\n#if defined(DUK_USE_ES6)\n syntax_error_newtarget:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_NEWTARGET);\n\tDUK_WO_NORETURN(return;);\n#endif\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_EXPRESSION);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* XXX: add flag to indicate whether caller cares about return value; this\n * affects e.g. handling of assignment expressions.  This change needs API\n * changes elsewhere too.\n */\nDUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_token *tk;\n\tduk_small_uint_t tok;\n\tduk_uint32_t args;  /* temp variable to pass constants and flags to shared code */\n\n\t/*\n\t *  ctx->prev_token     token to process with duk__expr_led()\n\t *  ctx->curr_token     updated by caller\n\t */\n\n\tcomp_ctx->curr_func.led_count++;\n\n\t/* The token in the switch has already been eaten here */\n\ttk = &comp_ctx->prev_token;\n\ttok = tk->t;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__expr_led(), prev_token.t=%ld, allow_in=%ld, paren_level=%ld\",\n\t                     (long) tk->t, (long) comp_ctx->curr_func.allow_in, (long) comp_ctx->curr_func.paren_level));\n\n\t/* XXX: default priority for infix operators is duk__expr_lbp(tok) -> get it here? */\n\n\tswitch (tok) {\n\n\t/* PRIMARY EXPRESSIONS */\n\n\tcase DUK_TOK_PERIOD: {\n\t\t/* Property access expressions are critical for correct LHS ordering,\n\t\t * see comments in duk__expr()!\n\t\t *\n\t\t * A conservative approach would be to use duk__ivalue_totempconst()\n\t\t * for 'left'.  However, allowing a reg-bound variable seems safe here\n\t\t * and is nice because \"foo.bar\" is a common expression.  If the ivalue\n\t\t * is used in an expression a GETPROP will occur before any changes to\n\t\t * the base value can occur.  If the ivalue is used as an assignment\n\t\t * LHS, the assignment code will ensure the base value is safe from\n\t\t * RHS mutation.\n\t\t */\n\n\t\t/* XXX: This now coerces an identifier into a GETVAR to a temp, which\n\t\t * causes an extra LDREG in call setup.  It's sufficient to coerce to a\n\t\t * unary ivalue?\n\t\t */\n\t\tduk__ivalue_toplain(comp_ctx, left);\n\n\t\t/* NB: must accept reserved words as property name */\n\t\tif (comp_ctx->curr_token.t_nores != DUK_TOK_IDENTIFIER) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EXPECTED_IDENTIFIER);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\n\t\tres->t = DUK_IVAL_PROP;\n\t\tduk__copy_ispec(comp_ctx, &left->x1, &res->x1);  /* left.x1 -> res.x1 */\n\t\tDUK_ASSERT(comp_ctx->curr_token.str1 != NULL);\n\t\tduk_push_hstring(thr, comp_ctx->curr_token.str1);\n\t\tduk_replace(thr, res->x2.valstack_idx);\n\t\tres->x2.t = DUK_ISPEC_VALUE;\n\n\t\t/* special RegExp literal handling after IdentifierName */\n\t\tcomp_ctx->curr_func.reject_regexp_in_adv = 1;\n\n\t\tduk__advance(comp_ctx);\n\t\treturn;\n\t}\n\tcase DUK_TOK_LBRACKET: {\n\t\t/* Property access expressions are critical for correct LHS ordering,\n\t\t * see comments in duk__expr()!\n\t\t */\n\n\t\t/* XXX: optimize temp reg use */\n\t\t/* XXX: similar coercion issue as in DUK_TOK_PERIOD */\n\t\t/* XXX: coerce to regs? it might be better for enumeration use, where the\n\t\t * same PROP ivalue is used multiple times.  Or perhaps coerce PROP further\n\t\t * there?\n\t\t */\n\t\t/* XXX: for simple cases like x['y'] an unnecessary LDREG is\n\t\t * emitted for the base value; could avoid it if we knew that\n\t\t * the key expression is safe (e.g. just a single literal).\n\t\t */\n\n\t\t/* The 'left' value must not be a register bound variable\n\t\t * because it may be mutated during the rest of the expression\n\t\t * and E5.1 Section 11.2.1 specifies the order of evaluation\n\t\t * so that the base value is evaluated first.\n\t\t * See: test-bug-nested-prop-mutate.js.\n\t\t */\n\t\tduk__ivalue_totempconst(comp_ctx, left);\n\t\tduk__expr_toplain(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);  /* Expression, ']' terminates */\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RBRACKET);\n\n\t\tres->t = DUK_IVAL_PROP;\n\t\tduk__copy_ispec(comp_ctx, &res->x1, &res->x2);   /* res.x1 -> res.x2 */\n\t\tduk__copy_ispec(comp_ctx, &left->x1, &res->x1);  /* left.x1 -> res.x1 */\n\t\treturn;\n\t}\n\tcase DUK_TOK_LPAREN: {\n\t\t/* function call */\n\t\tduk_regconst_t reg_cs = DUK__ALLOCTEMPS(comp_ctx, 2);\n\t\tduk_int_t nargs;\n\t\tduk_small_uint_t call_op = DUK_OP_CALL0;\n\n\t\t/* XXX: attempt to get the call result to \"next temp\" whenever\n\t\t * possible to avoid unnecessary register shuffles.\n\t\t */\n\n\t\t/*\n\t\t *  Setup call: target and 'this' binding.  Three cases:\n\t\t *\n\t\t *    1. Identifier base (e.g. \"foo()\")\n\t\t *    2. Property base (e.g. \"foo.bar()\")\n\t\t *    3. Register base (e.g. \"foo()()\"; i.e. when a return value is a function)\n\t\t */\n\n\t\tif (left->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with identifier base\"));\n\n\t\t\th_varname = duk_known_hstring(thr, left->x1.valstack_idx);\n\t\t\tif (h_varname == DUK_HTHREAD_STRING_EVAL(thr)) {\n\t\t\t\t/* Potential direct eval call detected, flag the CALL\n\t\t\t\t * so that a run-time \"direct eval\" check is made and\n\t\t\t\t * special behavior may be triggered.  Note that this\n\t\t\t\t * does not prevent 'eval' from being register bound.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with identifier 'eval' \"\n\t\t\t\t                     \"-> using EVALCALL, marking function \"\n\t\t\t\t                     \"as may_direct_eval\"));\n\t\t\t\tcall_op |= DUK_BC_CALL_FLAG_CALLED_AS_EVAL;\n\t\t\t\tcomp_ctx->curr_func.may_direct_eval = 1;\n\t\t\t}\n\n\t\t\tduk_dup(thr, left->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t              DUK_OP_CSREG | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t              reg_varbind,\n\t\t\t\t              reg_cs + 0);\n\t\t\t} else {\n\t\t\t\t/* XXX: expand target register or constant field to\n\t\t\t\t * reduce shuffling.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(DUK__ISCONST(rc_varname));\n\t\t\t\tduk__emit_a_b(comp_ctx,\n\t\t\t\t              DUK_OP_CSVAR | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t              reg_cs + 0,\n\t\t\t\t              rc_varname);\n\t\t\t}\n\t\t} else if (left->t == DUK_IVAL_PROP) {\n\t\t\t/* Call through a property lookup, E5 Section 11.2.3, step 6.a.i,\n\t\t\t * E5 Section 10.4.3.  There used to be a separate CSPROP opcode\n\t\t\t * but a typical call setup took 3 opcodes (e.g. LDREG, LDCONST,\n\t\t\t * CSPROP) and the same can be achieved with ordinary loads.\n\t\t\t */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\t\tduk_regconst_t reg_key;\n#endif\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with property base\"));\n\n\t\t\t/* XXX: For Math.sin() this generates: LDCONST + LDREG +\n\t\t\t * GETPROPC + call.  The LDREG is unnecessary because LDCONST\n\t\t\t * could be loaded directly into reg_cs + 1.  This doesn't\n\t\t\t * happen now because a variable cannot be in left->x1 of a\n\t\t\t * DUK_IVAL_PROP.  We could notice that left->x1 is a temp\n\t\t\t * and reuse, but it would still be in the wrong position\n\t\t\t * (reg_cs + 0 rather than reg_cs + 1).\n\t\t\t */\n\t\t\tduk__ispec_toforcedreg(comp_ctx, &left->x1, reg_cs + 1);  /* base */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\t\treg_key = duk__ispec_toregconst_raw(comp_ctx, &left->x2, -1, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_GETPROPC | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_cs + 0,\n\t\t\t                reg_cs + 1,\n\t\t\t                reg_key);\n#else\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_cs + 0);  /* base[key] */\n#endif\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with register base\"));\n\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_cs + 0);\n#if 0\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CSREG | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t               reg_cs + 0,\n\t\t\t               reg_cs + 0);  /* in-place setup */\n#endif\n\t\t\t/* Because of in-place setup, REGCS is equivalent to\n\t\t\t * just this LDUNDEF.\n\t\t\t */\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_LDUNDEF, reg_cs + 1);\n\t\t}\n\n\t\tDUK__SETTEMP(comp_ctx, reg_cs + 2);\n\t\tnargs = duk__parse_arguments(comp_ctx, res);  /* parse args starting from \"next temp\" */\n\n\t\t/* Tailcalls are handled by back-patching the already emitted opcode\n\t\t * later in return statement parser.\n\t\t */\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               call_op,\n\t\t               (duk_regconst_t) nargs /*numargs*/,\n\t\t               reg_cs /*basereg*/);\n\t\tDUK__SETTEMP(comp_ctx, reg_cs + 1);    /* result in csreg */\n\n\t\tduk__ivalue_regconst(res, reg_cs);\n\t\treturn;\n\t}\n\n\t/* POSTFIX EXPRESSION */\n\n\tcase DUK_TOK_INCREMENT: {\n\t\targs = (DUK_OP_POSTINCP_RR << 16) + (DUK_OP_POSTINCR << 8) + 0;\n\t\tgoto postincdec;\n\t}\n\tcase DUK_TOK_DECREMENT: {\n\t\targs = (DUK_OP_POSTDECP_RR << 16) + (DUK_OP_POSTDECR << 8) + 0;\n\t\tgoto postincdec;\n\t}\n\n\t/* EXPONENTIATION EXPRESSION */\n\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\tcase DUK_TOK_EXP: {\n\t\targs = (DUK_OP_EXP << 8) + DUK__BP_EXPONENTIATION - 1;  /* UnaryExpression */\n\t\tgoto binary;\n\t}\n#endif\n\n\t/* MULTIPLICATIVE EXPRESSION */\n\n\tcase DUK_TOK_MUL: {\n\t\targs = (DUK_OP_MUL << 8) + DUK__BP_MULTIPLICATIVE;  /* ExponentiationExpression */\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_DIV: {\n\t\targs = (DUK_OP_DIV << 8) + DUK__BP_MULTIPLICATIVE;  /* ExponentiationExpression */\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_MOD: {\n\t\targs = (DUK_OP_MOD << 8) + DUK__BP_MULTIPLICATIVE;  /* ExponentiationExpression */\n\t\tgoto binary;\n\t}\n\n\t/* ADDITIVE EXPRESSION */\n\n\tcase DUK_TOK_ADD: {\n\t\targs = (DUK_OP_ADD << 8) + DUK__BP_ADDITIVE;  /* MultiplicativeExpression */\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_SUB: {\n\t\targs = (DUK_OP_SUB << 8) + DUK__BP_ADDITIVE;  /* MultiplicativeExpression */\n\t\tgoto binary;\n\t}\n\n\t/* SHIFT EXPRESSION */\n\n\tcase DUK_TOK_ALSHIFT: {\n\t\t/* << */\n\t\targs = (DUK_OP_BASL << 8) + DUK__BP_SHIFT;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_ARSHIFT: {\n\t\t/* >> */\n\t\targs = (DUK_OP_BASR << 8) + DUK__BP_SHIFT;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_RSHIFT: {\n\t\t/* >>> */\n\t\targs = (DUK_OP_BLSR << 8) + DUK__BP_SHIFT;\n\t\tgoto binary;\n\t}\n\n\t/* RELATIONAL EXPRESSION */\n\n\tcase DUK_TOK_LT: {\n\t\t/* < */\n\t\targs = (DUK_OP_LT << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_GT: {\n\t\targs = (DUK_OP_GT << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_LE: {\n\t\targs = (DUK_OP_LE << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_GE: {\n\t\targs = (DUK_OP_GE << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_INSTANCEOF: {\n\t\targs = (DUK_OP_INSTOF << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_IN: {\n\t\targs = (DUK_OP_IN << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\n\t/* EQUALITY EXPRESSION */\n\n\tcase DUK_TOK_EQ: {\n\t\targs = (DUK_OP_EQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_NEQ: {\n\t\targs = (DUK_OP_NEQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_SEQ: {\n\t\targs = (DUK_OP_SEQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_SNEQ: {\n\t\targs = (DUK_OP_SNEQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\n\t/* BITWISE EXPRESSIONS */\n\n\tcase DUK_TOK_BAND: {\n\t\targs = (DUK_OP_BAND << 8) + DUK__BP_BAND;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_BXOR: {\n\t\targs = (DUK_OP_BXOR << 8) + DUK__BP_BXOR;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_BOR: {\n\t\targs = (DUK_OP_BOR << 8) + DUK__BP_BOR;\n\t\tgoto binary;\n\t}\n\n\t/* LOGICAL EXPRESSIONS */\n\n\tcase DUK_TOK_LAND: {\n\t\t/* syntactically left-associative but parsed as right-associative */\n\t\targs = (1 << 8) + DUK__BP_LAND - 1;\n\t\tgoto binary_logical;\n\t}\n\tcase DUK_TOK_LOR: {\n\t\t/* syntactically left-associative but parsed as right-associative */\n\t\targs = (0 << 8) + DUK__BP_LOR - 1;\n\t\tgoto binary_logical;\n\t}\n\n\t/* CONDITIONAL EXPRESSION */\n\n\tcase DUK_TOK_QUESTION: {\n\t\t/* XXX: common reg allocation need is to reuse a sub-expression's temp reg,\n\t\t * but only if it really is a temp.  Nothing fancy here now.\n\t\t */\n\t\tduk_regconst_t reg_temp;\n\t\tduk_int_t pc_jump1;\n\t\tduk_int_t pc_jump2;\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_temp);\n\t\tduk__emit_if_true_skip(comp_ctx, reg_temp);\n\t\tpc_jump1 = duk__emit_jump_empty(comp_ctx);  /* jump to false */\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp /*forced_reg*/);  /* AssignmentExpression */\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\t\tpc_jump2 = duk__emit_jump_empty(comp_ctx);  /* jump to end */\n\t\tduk__patch_jump_here(comp_ctx, pc_jump1);\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp /*forced_reg*/);  /* AssignmentExpression */\n\t\tduk__patch_jump_here(comp_ctx, pc_jump2);\n\n\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\n\t/* ASSIGNMENT EXPRESSION */\n\n\tcase DUK_TOK_EQUALSIGN: {\n\t\t/*\n\t\t *  Assignments are right associative, allows e.g.\n\t\t *    a = 5;\n\t\t *    a += b = 9;   // same as a += (b = 9)\n\t\t *  -> expression value 14, a = 14, b = 9\n\t\t *\n\t\t *  Right associativiness is reflected in the BP for recursion,\n\t\t *  \"-1\" ensures assignment operations are allowed.\n\t\t *\n\t\t *  XXX: just use DUK__BP_COMMA (i.e. no need for 2-step bp levels)?\n\t\t */\n\t\targs = (DUK_OP_NONE << 8) + DUK__BP_ASSIGNMENT - 1;   /* DUK_OP_NONE marks a 'plain' assignment */\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_ADD_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_ADD << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_SUB_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_SUB << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_MUL_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_MUL << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_DIV_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_DIV << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_MOD_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_MOD << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\tcase DUK_TOK_EXP_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_EXP << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n#endif\n\tcase DUK_TOK_ALSHIFT_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BASL << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_ARSHIFT_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BASR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_RSHIFT_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BLSR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_BAND_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BAND << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_BOR_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BOR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_BXOR_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BXOR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\n\t/* COMMA */\n\n\tcase DUK_TOK_COMMA: {\n\t\t/* right associative */\n\n\t\tduk__ivalue_toplain_ignore(comp_ctx, left);  /* need side effects, not value */\n\t\tduk__expr_toplain(comp_ctx, res, DUK__BP_COMMA - 1 /*rbp_flags*/);\n\n\t\t/* return 'res' (of right part) as our result */\n\t\treturn;\n\t}\n\n\tdefault: {\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"parse error: unexpected token: %ld\", (long) tok));\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);\n\tDUK_WO_NORETURN(return;);\n\n#if 0\n\t/* XXX: shared handling for 'duk__expr_lhs'? */\n\tif (comp_ctx->curr_func.paren_level == 0 && XXX) {\n\t\tcomp_ctx->curr_func.duk__expr_lhs = 0;\n\t}\n#endif\n\n binary:\n\t/*\n\t *  Shared handling of binary operations\n\t *\n\t *  args = (opcode << 8) + rbp\n\t */\n\t{\n\t\tduk__ivalue_toplain(comp_ctx, left);\n\t\tduk__expr_toplain(comp_ctx, res, args & 0xff /*rbp_flags*/);\n\n\t\t/* combine left->x1 and res->x1 (right->x1, really) -> (left->x1 OP res->x1) */\n\t\tDUK_ASSERT(left->t == DUK_IVAL_PLAIN);\n\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN);\n\n\t\tres->t = DUK_IVAL_ARITH;\n\t\tres->op = (args >> 8) & 0xff;\n\n\t\tres->x2.t = res->x1.t;\n\t\tres->x2.regconst = res->x1.regconst;\n\t\tduk_copy(thr, res->x1.valstack_idx, res->x2.valstack_idx);\n\n\t\tres->x1.t = left->x1.t;\n\t\tres->x1.regconst = left->x1.regconst;\n\t\tduk_copy(thr, left->x1.valstack_idx, res->x1.valstack_idx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"binary op, res: t=%ld, x1.t=%ld, x1.regconst=0x%08lx, x2.t=%ld, x2.regconst=0x%08lx\",\n\t\t                     (long) res->t, (long) res->x1.t, (unsigned long) res->x1.regconst, (long) res->x2.t, (unsigned long) res->x2.regconst));\n\t\treturn;\n\t}\n\n binary_logical:\n\t/*\n\t *  Shared handling for logical AND and logical OR.\n\t *\n\t *  args = (truthval << 8) + rbp\n\t *\n\t *  Truthval determines when to skip right-hand-side.\n\t *  For logical AND truthval=1, for logical OR truthval=0.\n\t *\n\t *  See doc/compiler.rst for discussion on compiling logical\n\t *  AND and OR expressions.  The approach here is very simplistic,\n\t *  generating extra jumps and multiple evaluations of truth values,\n\t *  but generates code on-the-fly with only local back-patching.\n\t *\n\t *  Both logical AND and OR are syntactically left-associated.\n\t *  However, logical ANDs are compiled as right associative\n\t *  expressions, i.e. \"A && B && C\" as \"A && (B && C)\", to allow\n\t *  skip jumps to skip over the entire tail.  Similarly for logical OR.\n\t */\n\n\t{\n\t\tduk_regconst_t reg_temp;\n\t\tduk_int_t pc_jump;\n\t\tduk_small_uint_t args_truthval = args >> 8;\n\t\tduk_small_uint_t args_rbp = args & 0xff;\n\n\t\t/* XXX: unoptimal use of temps, resetting */\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_temp);\n\t\tDUK_ASSERT(DUK__ISREG(reg_temp));\n\t\tduk__emit_bc(comp_ctx,\n\t\t            (args_truthval ? DUK_OP_IFTRUE_R : DUK_OP_IFFALSE_R),\n\t\t            reg_temp);  /* skip jump conditionally */\n\t\tpc_jump = duk__emit_jump_empty(comp_ctx);\n\t\tduk__expr_toforcedreg(comp_ctx, res, args_rbp /*rbp_flags*/, reg_temp /*forced_reg*/);\n\t\tduk__patch_jump_here(comp_ctx, pc_jump);\n\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\n assign:\n\t/*\n\t *  Shared assignment expression handling\n\t *\n\t *  args = (opcode << 8) + rbp\n\t *\n\t *  If 'opcode' is DUK_OP_NONE, plain assignment without arithmetic.\n\t *  Syntactically valid left-hand-side forms which are not accepted as\n\t *  left-hand-side values (e.g. as in \"f() = 1\") must NOT cause a\n\t *  SyntaxError, but rather a run-time ReferenceError.\n\t *\n\t *  When evaluating X <op>= Y, the LHS (X) is conceptually evaluated\n\t *  to a temporary first.  The RHS is then evaluated.  Finally, the\n\t *  <op> is applied to the initial value of RHS (not the value after\n\t *  RHS evaluation), and written to X.  Doing so concretely generates\n\t *  inefficient code so we'd like to avoid the temporary when possible.\n\t *  See: https://github.com/svaarala/duktape/pull/992.\n\t *\n\t *  The expression value (final LHS value, written to RHS) is\n\t *  conceptually copied into a fresh temporary so that it won't\n\t *  change even if the LHS/RHS values change in outer expressions.\n\t *  For example, it'd be generally incorrect for the expression value\n\t *  to be the RHS register binding, unless there's a guarantee that it\n\t *  won't change during further expression evaluation.  Using the\n\t *  temporary concretely produces inefficient bytecode, so we try to\n\t *  avoid the extra temporary for some known-to-be-safe cases.\n\t *  Currently the only safe case we detect is a \"top level assignment\",\n\t *  for example \"x = y + z;\", where the assignment expression value is\n\t *  ignored.\n\t *  See: test-dev-assign-expr.js and test-bug-assign-mutate-gh381.js.\n\t */\n\n\t{\n\t\tduk_small_uint_t args_op = args >> 8;\n\t\tduk_small_uint_t args_rbp = args & 0xff;\n\t\tduk_bool_t toplevel_assign;\n\n\t\t/* XXX: here we need to know if 'left' is left-hand-side compatible.\n\t\t * That information is no longer available from current expr parsing\n\t\t * state; it would need to be carried into the 'left' ivalue or by\n\t\t * some other means.\n\t\t */\n\n\t\t/* A top-level assignment is e.g. \"x = y;\".  For these it's safe\n\t\t * to use the RHS as-is as the expression value, even if the RHS\n\t\t * is a reg-bound identifier.  The RHS ('res') is right associative\n\t\t * so it has consumed all other assignment level operations; the\n\t\t * only relevant lower binding power construct is comma operator\n\t\t * which will ignore the expression value provided here.  Usually\n\t\t * the top level assignment expression value is ignored, but it\n\t\t * is relevant for e.g. eval code.\n\t\t */\n\t\ttoplevel_assign = (comp_ctx->curr_func.nud_count == 1 && /* one token before */\n\t\t                   comp_ctx->curr_func.led_count == 1);  /* one operator (= assign) */\n\t\tDUK_DDD(DUK_DDDPRINT(\"assignment: nud_count=%ld, led_count=%ld, toplevel_assign=%ld\",\n\t\t                     (long) comp_ctx->curr_func.nud_count,\n\t\t                     (long) comp_ctx->curr_func.led_count,\n\t\t                     (long) toplevel_assign));\n\n\t\tif (left->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\tDUK_ASSERT(left->x1.t == DUK_ISPEC_VALUE);  /* LHS is already side effect free */\n\n\t\t\th_varname = duk_known_hstring(thr, left->x1.valstack_idx);\n\t\t\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\t\t\t/* E5 Section 11.13.1 (and others for other assignments), step 4. */\n\t\t\t\tgoto syntax_error_lvalue;\n\t\t\t}\n\t\t\tduk_dup(thr, left->x1.valstack_idx);\n\t\t\t(void) duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname);\n\n\t\t\tif (args_op == DUK_OP_NONE) {\n\t\t\t\tduk__expr(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\tif (toplevel_assign) {\n\t\t\t\t\t/* Any 'res' will do. */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"plain assignment, toplevel assign, use as is\"));\n\t\t\t\t} else {\n\t\t\t\t\t/* 'res' must be a plain ivalue, and not register-bound variable. */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"plain assignment, not toplevel assign, ensure not a reg-bound identifier\"));\n\t\t\t\t\tif (res->t != DUK_IVAL_PLAIN || (res->x1.t == DUK_ISPEC_REGCONST &&\n\t\t\t\t\t                                 DUK__ISREG_NOTTEMP(comp_ctx, res->x1.regconst))) {\n\t\t\t\t\t\tduk__ivalue_totempconst(comp_ctx, res);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* For X <op>= Y we need to evaluate the pre-op\n\t\t\t\t * value of X before evaluating the RHS: the RHS\n\t\t\t\t * can change X, but when we do <op> we must use\n\t\t\t\t * the pre-op value.\n\t\t\t\t */\n\t\t\t\tduk_regconst_t reg_temp;\n\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t\t\tif (reg_varbind >= 0) {\n\t\t\t\t\tduk_regconst_t reg_res;\n\t\t\t\t\tduk_regconst_t reg_src;\n\t\t\t\t\tduk_int_t pc_temp_load;\n\t\t\t\t\tduk_int_t pc_before_rhs;\n\t\t\t\t\tduk_int_t pc_after_rhs;\n\n\t\t\t\t\tif (toplevel_assign) {\n\t\t\t\t\t\t/* 'reg_varbind' is the operation result and can also\n\t\t\t\t\t\t * become the expression value for top level assignments\n\t\t\t\t\t\t * such as: \"var x; x += y;\".\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"<op>= expression is top level, write directly to reg_varbind\"));\n\t\t\t\t\t\treg_res = reg_varbind;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t/* Not safe to use 'reg_varbind' as assignment expression\n\t\t\t\t\t\t * value, so go through a temp.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"<op>= expression is not top level, write to reg_temp\"));\n\t\t\t\t\t\treg_res = reg_temp;  /* reg_res should be smallest possible */\n\t\t\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\t\t}\n\n\t\t\t\t\t/* Try to optimize X <op>= Y for reg-bound\n\t\t\t\t\t * variables.  Detect side-effect free RHS\n\t\t\t\t\t * narrowly by seeing whether it emits code.\n\t\t\t\t\t * If not, rewind the code emitter and overwrite\n\t\t\t\t\t * the unnecessary temp reg load.\n\t\t\t\t\t */\n\n\t\t\t\t\tpc_temp_load = duk__get_current_pc(comp_ctx);\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_LDREG,\n\t\t\t\t\t               reg_temp,\n\t\t\t\t\t               reg_varbind);\n\n\t\t\t\t\tpc_before_rhs = duk__get_current_pc(comp_ctx);\n\t\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\t\t\t\t\tpc_after_rhs = duk__get_current_pc(comp_ctx);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"pc_temp_load=%ld, pc_before_rhs=%ld, pc_after_rhs=%ld\",\n\t\t\t\t\t                   (long) pc_temp_load, (long) pc_before_rhs,\n\t\t\t\t\t                   (long) pc_after_rhs));\n\n\t\t\t\t\tif (pc_after_rhs == pc_before_rhs) {\n\t\t\t\t\t\t/* Note: if the reg_temp load generated shuffling\n\t\t\t\t\t\t * instructions, we may need to rewind more than\n\t\t\t\t\t\t * one instruction, so use explicit PC computation.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"rhs is side effect free, rewind and avoid unnecessary temp for reg-based <op>=\"));\n\t\t\t\t\t\tDUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, (pc_temp_load - pc_before_rhs) * (duk_int_t) sizeof(duk_compiler_instr));\n\t\t\t\t\t\treg_src = reg_varbind;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"rhs evaluation emitted code, not sure if rhs is side effect free; use temp reg for LHS\"));\n\t\t\t\t\t\treg_src = reg_temp;\n\t\t\t\t\t}\n\n\t\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t\t                args_op | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t\t                reg_res,\n\t\t\t\t\t                reg_src,\n\t\t\t\t\t                res->x1.regconst);\n\n\t\t\t\t\tres->x1.regconst = reg_res;\n\n\t\t\t\t\t/* Ensure compact use of temps. */\n\t\t\t\t\tif (DUK__ISREG_TEMP(comp_ctx, reg_res)) {\n\t\t\t\t\t\tDUK__SETTEMP(comp_ctx, reg_res + 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t/* When LHS is not register bound, always go through a\n\t\t\t\t\t * temporary.  No optimization for top level assignment.\n\t\t\t\t\t */\n\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_GETVAR,\n\t\t\t\t\t               reg_temp,\n\t\t\t\t\t               rc_varname);\n\n\t\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\n\t\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t\t                args_op | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t\t                reg_temp,\n\t\t\t\t\t                reg_temp,\n\t\t\t\t\t                res->x1.regconst);\n\t\t\t\t\tres->x1.regconst = reg_temp;\n\t\t\t\t}\n\n\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\t\t\t}\n\n\t\t\t/* At this point 'res' holds the potential expression value.\n\t\t\t * It can be basically any ivalue here, including a reg-bound\n\t\t\t * identifier (if code above deems it safe) or a unary/binary\n\t\t\t * operation.  Operations must be resolved to a side effect free\n\t\t\t * plain value, and the side effects must happen exactly once.\n\t\t\t */\n\n\t\t\tif (reg_varbind >= 0) {\n\t\t\t\tif (res->t != DUK_IVAL_PLAIN) {\n\t\t\t\t\t/* Resolve 'res' directly into the LHS binding, and use\n\t\t\t\t\t * that as the expression value if safe.  If not safe,\n\t\t\t\t\t * resolve to a temp/const and copy to LHS.\n\t\t\t\t\t */\n\t\t\t\t\tif (toplevel_assign) {\n\t\t\t\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, (duk_int_t) reg_varbind);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk__ivalue_totempconst(comp_ctx, res);\n\t\t\t\t\t\tduk__copy_ivalue(comp_ctx, res, left);  /* use 'left' as a temp */\n\t\t\t\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, (duk_int_t) reg_varbind);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t/* Use 'res' as the expression value (it's side effect\n\t\t\t\t\t * free and may be a plain value, a register, or a\n\t\t\t\t\t * constant) and write it to the LHS binding too.\n\t\t\t\t\t */\n\t\t\t\t\tduk__copy_ivalue(comp_ctx, res, left);  /* use 'left' as a temp */\n\t\t\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, (duk_int_t) reg_varbind);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* Only a reg fits into 'A' so coerce 'res' into a register\n\t\t\t\t * for PUTVAR.\n\t\t\t\t *\n\t\t\t\t * XXX: here the current A/B/C split is suboptimal: we could\n\t\t\t\t * just use 9 bits for reg_res (and support constants) and 17\n\t\t\t\t * instead of 18 bits for the varname const index.\n\t\t\t\t */\n\n\t\t\t\tduk__ivalue_toreg(comp_ctx, res);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t               res->x1.regconst,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\n\t\t\t/* 'res' contains expression value */\n\t\t} else if (left->t == DUK_IVAL_PROP) {\n\t\t\t/* E5 Section 11.13.1 (and others) step 4 never matches for prop writes -> no check */\n\t\t\tduk_regconst_t reg_obj;\n\t\t\tduk_regconst_t rc_key;\n\t\t\tduk_regconst_t rc_res;\n\t\t\tduk_regconst_t reg_temp;\n\n\t\t\t/* Property access expressions ('a[b]') are critical to correct\n\t\t\t * LHS evaluation ordering, see test-dev-assign-eval-order*.js.\n\t\t\t * We must make sure that the LHS target slot (base object and\n\t\t\t * key) don't change during RHS evaluation.  The only concrete\n\t\t\t * problem is a register reference to a variable-bound register\n\t\t\t * (i.e., non-temp).  Require temp regs for both key and base.\n\t\t\t *\n\t\t\t * Don't allow a constant for the object (even for a number\n\t\t\t * etc), as it goes into the 'A' field of the opcode.\n\t\t\t */\n\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx,\n\t\t\t                                    &left->x1,\n\t\t\t                                    -1 /*forced_reg*/,\n\t\t\t                                    DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/);\n\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx,\n\t\t\t                                   &left->x2,\n\t\t\t                                   -1 /*forced_reg*/,\n\t\t\t                                   DUK__IVAL_FLAG_REQUIRE_TEMP | DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\n\t\t\t/* Evaluate RHS only when LHS is safe. */\n\n\t\t\tif (args_op == DUK_OP_NONE) {\n\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\t\t\t\trc_res = res->x1.regconst;\n\t\t\t} else {\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                DUK_OP_GETPROP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                reg_temp,\n\t\t\t\t                reg_obj,\n\t\t\t\t                rc_key);\n\n\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                args_op | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                reg_temp,\n\t\t\t\t                reg_temp,\n\t\t\t\t                res->x1.regconst);\n\t\t\t\trc_res = reg_temp;\n\t\t\t}\n\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_obj,\n\t\t\t                rc_key,\n\t\t\t                rc_res);\n\n\t\t\tduk__ivalue_regconst(res, rc_res);\n\t\t} else {\n\t\t\t/* No support for lvalues returned from new or function call expressions.\n\t\t\t * However, these must NOT cause compile-time SyntaxErrors, but run-time\n\t\t\t * ReferenceErrors.  Both left and right sides of the assignment must be\n\t\t\t * evaluated before throwing a ReferenceError.  For instance:\n\t\t\t *\n\t\t\t *     f() = g();\n\t\t\t *\n\t\t\t * must result in f() being evaluated, then g() being evaluated, and\n\t\t\t * finally, a ReferenceError being thrown.  See E5 Section 11.13.1.\n\t\t\t */\n\n\t\t\tduk_regconst_t rc_res;\n\n\t\t\t/* First evaluate LHS fully to ensure all side effects are out. */\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, left);\n\n\t\t\t/* Then evaluate RHS fully (its value becomes the expression value too).\n\t\t\t * Technically we'd need the side effect safety check here too, but because\n\t\t\t * we always throw using INVLHS the result doesn't matter.\n\t\t\t */\n\t\t\trc_res = duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\n\t\t\tduk__emit_op_only(comp_ctx, DUK_OP_INVLHS);\n\n\t\t\tduk__ivalue_regconst(res, rc_res);\n\t\t}\n\n\t\treturn;\n\t}\n\n postincdec:\n\t{\n\t\t/*\n\t\t *  Post-increment/decrement will return the original value as its\n\t\t *  result value.  However, even that value will be coerced using\n\t\t *  ToNumber() which is quite awkward.  Specific bytecode opcodes\n\t\t *  are used to handle these semantics.\n\t\t *\n\t\t *  Note that post increment/decrement has a \"no LineTerminator here\"\n\t\t *  restriction.  This is handled by duk__expr_lbp(), which forcibly terminates\n\t\t *  the previous expression if a LineTerminator occurs before '++'/'--'.\n\t\t */\n\n\t\tduk_regconst_t reg_res;\n\t\tduk_small_uint_t args_op1 = (args >> 8) & 0xff;  /* DUK_OP_POSTINCR/DUK_OP_POSTDECR */\n\t\tduk_small_uint_t args_op2 = args >> 16;          /* DUK_OP_POSTINCP_RR/DUK_OP_POSTDECP_RR */\n\n\t\t/* Specific assumptions for opcode numbering. */\n\t\tDUK_ASSERT(DUK_OP_POSTINCR + 4 == DUK_OP_POSTINCV);\n\t\tDUK_ASSERT(DUK_OP_POSTDECR + 4 == DUK_OP_POSTDECV);\n\n\t\treg_res = DUK__ALLOCTEMP(comp_ctx);\n\n\t\tif (left->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\th_varname = duk_known_hstring(thr, left->x1.valstack_idx);\n\n\t\t\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\tduk_dup(thr, left->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               args_op1,  /* e.g. DUK_OP_POSTINCR */\n\t\t\t\t               reg_res,\n\t\t\t\t               reg_varbind);\n\t\t\t} else {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               args_op1 + 4,  /* e.g. DUK_OP_POSTINCV */\n\t\t\t\t               reg_res,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"postincdec to '%!O' -> reg_varbind=%ld, rc_varname=%ld\",\n\t\t\t                     (duk_heaphdr *) h_varname, (long) reg_varbind, (long) rc_varname));\n\t\t} else if (left->t == DUK_IVAL_PROP) {\n\t\t\tduk_regconst_t reg_obj;  /* allocate to reg only (not const) */\n\t\t\tduk_regconst_t rc_key;\n\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &left->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &left->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                args_op2 | DUK__EMIT_FLAG_BC_REGCONST,  /* e.g. DUK_OP_POSTINCP */\n\t\t\t                reg_res,\n\t\t\t                reg_obj,\n\t\t\t                rc_key);\n\t\t} else {\n\t\t\t/* Technically return value is not needed because INVLHS will\n\t\t\t * unconditially throw a ReferenceError.  Coercion is necessary\n\t\t\t * for proper semantics (consider ToNumber() called for an object).\n\t\t\t * Use DUK_OP_UNP with a dummy register to get ToNumber().\n\t\t\t */\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_res);\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_UNP,\n\t\t\t             reg_res);  /* for side effects, result ignored */\n\t\t\tduk__emit_op_only(comp_ctx,\n\t\t\t                  DUK_OP_INVLHS);\n\t\t}\n\n\t\tDUK__SETTEMP(comp_ctx, reg_res + 1);\n\t\tduk__ivalue_regconst(res, reg_res);\n\t\treturn;\n\t}\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_EXPRESSION);\n\tDUK_WO_NORETURN(return;);\n\n syntax_error_lvalue:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LVALUE);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL duk_small_uint_t duk__expr_lbp(duk_compiler_ctx *comp_ctx) {\n\tduk_small_uint_t tok = comp_ctx->curr_token.t;\n\n\tDUK_ASSERT_DISABLE(tok >= DUK_TOK_MINVAL);  /* unsigned */\n\tDUK_ASSERT(tok <= DUK_TOK_MAXVAL);\n\tDUK_ASSERT(sizeof(duk__token_lbp) == DUK_TOK_MAXVAL + 1);\n\n\t/* XXX: integrate support for this into led() instead?\n\t * Similar issue as post-increment/post-decrement.\n\t */\n\n\t/* prevent duk__expr_led() by using a binding power less than anything valid */\n\tif (tok == DUK_TOK_IN && !comp_ctx->curr_func.allow_in) {\n\t\treturn 0;\n\t}\n\n\tif ((tok == DUK_TOK_DECREMENT || tok == DUK_TOK_INCREMENT) &&\n\t    (comp_ctx->curr_token.lineterm)) {\n\t\t/* '++' or '--' in a post-increment/decrement position,\n\t\t * and a LineTerminator occurs between the operator and\n\t\t * the preceding expression.  Force the previous expr\n\t\t * to terminate, in effect treating e.g. \"a,b\\n++\" as\n\t\t * \"a,b;++\" (= SyntaxError).\n\t\t */\n\t\treturn 0;\n\t}\n\n\treturn DUK__TOKEN_LBP_GET_BP(duk__token_lbp[tok]);  /* format is bit packed */\n}\n\n/*\n *  Expression parsing.\n *\n *  Upon entry to 'expr' and its variants, 'curr_tok' is assumed to be the\n *  first token of the expression.  Upon exit, 'curr_tok' will be the first\n *  token not part of the expression (e.g. semicolon terminating an expression\n *  statement).\n */\n\n#define DUK__EXPR_RBP_MASK           0xff\n#define DUK__EXPR_FLAG_REJECT_IN     (1 << 8)   /* reject 'in' token (used for for-in) */\n#define DUK__EXPR_FLAG_ALLOW_EMPTY   (1 << 9)   /* allow empty expression */\n#define DUK__EXPR_FLAG_REQUIRE_INIT  (1 << 10)  /* require initializer for var/const */\n\n/* main expression parser function */\nDUK_LOCAL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_ivalue tmp_alloc;   /* 'res' is used for \"left\", and 'tmp' for \"right\" */\n\tduk_ivalue *tmp = &tmp_alloc;\n\tduk_small_uint_t rbp;\n\n\tDUK__RECURSION_INCREASE(comp_ctx, thr);\n\n\tduk_require_stack(thr, DUK__PARSE_EXPR_SLOTS);\n\n\t/* filter out flags from exprtop rbp_flags here to save space */\n\trbp = rbp_flags & DUK__EXPR_RBP_MASK;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__expr(), rbp_flags=%ld, rbp=%ld, allow_in=%ld, paren_level=%ld\",\n\t                     (long) rbp_flags, (long) rbp, (long) comp_ctx->curr_func.allow_in,\n\t                     (long) comp_ctx->curr_func.paren_level));\n\n\tduk_memzero(&tmp_alloc, sizeof(tmp_alloc));\n\ttmp->x1.valstack_idx = duk_get_top(thr);\n\ttmp->x2.valstack_idx = tmp->x1.valstack_idx + 1;\n\tduk_push_undefined(thr);\n\tduk_push_undefined(thr);\n\n\t/* XXX: where to release temp regs in intermediate expressions?\n\t * e.g. 1+2+3 -> don't inflate temp register count when parsing this.\n\t * that particular expression temp regs can be forced here.\n\t */\n\n\t/* XXX: increase ctx->expr_tokens here for every consumed token\n\t * (this would be a nice statistic)?\n\t */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON || comp_ctx->curr_token.t == DUK_TOK_RPAREN) {\n\t\t/* XXX: possibly incorrect handling of empty expression */\n\t\tDUK_DDD(DUK_DDDPRINT(\"empty expression\"));\n\t\tif (!(rbp_flags & DUK__EXPR_FLAG_ALLOW_EMPTY)) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EMPTY_EXPR_NOT_ALLOWED);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tduk_push_undefined(thr);\n\t\tduk__ivalue_plain_fromstack(comp_ctx, res);\n\t\tgoto cleanup;\n\t}\n\n\tduk__advance(comp_ctx);\n\tduk__expr_nud(comp_ctx, res);  /* reuse 'res' as 'left' */\n\twhile (rbp < duk__expr_lbp(comp_ctx)) {\n\t\tduk__advance(comp_ctx);\n\t\tduk__expr_led(comp_ctx, res, tmp);\n\t\tduk__copy_ivalue(comp_ctx, tmp, res);  /* tmp -> res */\n\t}\n\n cleanup:\n\t/* final result is already in 'res' */\n\n\tduk_pop_2(thr);\n\n\tDUK__RECURSION_DECREASE(comp_ctx, thr);\n}\n\nDUK_LOCAL void duk__exprtop(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\t/* Note: these variables must reside in 'curr_func' instead of the global\n\t * context: when parsing function expressions, expression parsing is nested.\n\t */\n\tcomp_ctx->curr_func.nud_count = 0;\n\tcomp_ctx->curr_func.led_count = 0;\n\tcomp_ctx->curr_func.paren_level = 0;\n\tcomp_ctx->curr_func.expr_lhs = 1;\n\tcomp_ctx->curr_func.allow_in = (rbp_flags & DUK__EXPR_FLAG_REJECT_IN ? 0 : 1);\n\n\tduk__expr(comp_ctx, res, rbp_flags);\n\n\tif (!(rbp_flags & DUK__EXPR_FLAG_ALLOW_EMPTY) && duk__expr_is_empty(comp_ctx)) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EMPTY_EXPR_NOT_ALLOWED);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\n/* A bunch of helpers (for size optimization) that combine duk__expr()/duk__exprtop()\n * and result conversions.\n *\n * Each helper needs at least 2-3 calls to make it worth while to wrap.\n */\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__expr_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toreg(comp_ctx, res);\n}\n#endif\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__expr_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_totemp(comp_ctx, res);\n}\n#endif\n\nDUK_LOCAL void duk__expr_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\tduk__expr(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toforcedreg(comp_ctx, res, forced_reg);\n}\n\nDUK_LOCAL duk_regconst_t duk__expr_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toregconst(comp_ctx, res);\n}\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__expr_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_totempconst(comp_ctx, res);\n}\n#endif\n\nDUK_LOCAL void duk__expr_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toplain(comp_ctx, res);\n}\n\nDUK_LOCAL void duk__expr_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toplain_ignore(comp_ctx, res);\n}\n\nDUK_LOCAL duk_regconst_t duk__exprtop_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toreg(comp_ctx, res);\n}\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__exprtop_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_totemp(comp_ctx, res);\n}\n#endif\n\nDUK_LOCAL void duk__exprtop_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toforcedreg(comp_ctx, res, forced_reg);\n}\n\nDUK_LOCAL duk_regconst_t duk__exprtop_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toregconst(comp_ctx, res);\n}\n\n#if 0  /* unused */\nDUK_LOCAL void duk__exprtop_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, int rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toplain_ignore(comp_ctx, res);\n}\n#endif\n\n/*\n *  Parse an individual source element (top level statement) or a statement.\n *\n *  Handles labeled statements automatically (peeling away labels before\n *  parsing an expression that follows the label(s)).\n *\n *  Upon entry, 'curr_tok' contains the first token of the statement (parsed\n *  in \"allow regexp literal\" mode).  Upon exit, 'curr_tok' contains the first\n *  token following the statement (if the statement has a terminator, this is\n *  the token after the terminator).\n */\n\n#define DUK__HAS_VAL                  (1 << 0)  /* stmt has non-empty value */\n#define DUK__HAS_TERM                 (1 << 1)  /* stmt has explicit/implicit semicolon terminator */\n#define DUK__ALLOW_AUTO_SEMI_ALWAYS   (1 << 2)  /* allow automatic semicolon even without lineterm (compatibility) */\n#define DUK__STILL_PROLOGUE           (1 << 3)  /* statement does not terminate directive prologue */\n#define DUK__IS_TERMINAL              (1 << 4)  /* statement is guaranteed to be terminal (control doesn't flow to next statement) */\n\n/* Parse a single variable declaration (e.g. \"i\" or \"i=10\").  A leading 'var'\n * has already been eaten.  These is no return value in 'res', it is used only\n * as a temporary.\n *\n * When called from 'for-in' statement parser, the initializer expression must\n * not allow the 'in' token.  The caller supply additional expression parsing\n * flags (like DUK__EXPR_FLAG_REJECT_IN) in 'expr_flags'.\n *\n * Finally, out_rc_varname and out_reg_varbind are updated to reflect where\n * the identifier is bound:\n *\n *    If register bound:      out_reg_varbind >= 0, out_rc_varname == 0 (ignore)\n *    If not register bound:  out_reg_varbind < 0, out_rc_varname >= 0\n *\n * These allow the caller to use the variable for further assignment, e.g.\n * as is done in 'for-in' parsing.\n */\n\nDUK_LOCAL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hstring *h_varname;\n\tduk_regconst_t reg_varbind;\n\tduk_regconst_t rc_varname;\n\n\t/* assume 'var' has been eaten */\n\n\t/* Note: Identifier rejects reserved words */\n\tif (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) {\n\t\tgoto syntax_error;\n\t}\n\th_varname = comp_ctx->curr_token.str1;\n\n\tDUK_ASSERT(h_varname != NULL);\n\n\t/* strict mode restrictions (E5 Section 12.2.1) */\n\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\tgoto syntax_error;\n\t}\n\n\t/* register declarations in first pass */\n\tif (comp_ctx->curr_func.in_scanning) {\n\t\tduk_uarridx_t n;\n\t\tDUK_DDD(DUK_DDDPRINT(\"register variable declaration %!O in pass 1\",\n\t\t                     (duk_heaphdr *) h_varname));\n\t\tn = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.decls_idx);\n\t\tduk_push_hstring(thr, h_varname);\n\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n);\n\t\tduk_push_int(thr, DUK_DECL_TYPE_VAR + (0 << 8));\n\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n + 1);\n\t}\n\n\tduk_push_hstring(thr, h_varname);  /* push before advancing to keep reachable */\n\n\t/* register binding lookup is based on varmap (even in first pass) */\n\tduk_dup_top(thr);\n\t(void) duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname);\n\n\tduk__advance(comp_ctx);  /* eat identifier */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_EQUALSIGN) {\n\t\tduk__advance(comp_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"vardecl, assign to '%!O' -> reg_varbind=%ld, rc_varname=%ld\",\n\t\t                     (duk_heaphdr *) h_varname, (long) reg_varbind, (long) rc_varname));\n\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_COMMA | expr_flags /*rbp_flags*/);  /* AssignmentExpression */\n\n\t\tif (reg_varbind >= 0) {\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_varbind);\n\t\t} else {\n\t\t\tduk_regconst_t reg_val;\n\t\t\treg_val = duk__ivalue_toreg(comp_ctx, res);\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t               reg_val,\n\t\t\t               rc_varname);\n\t\t}\n\t} else {\n\t\tif (expr_flags & DUK__EXPR_FLAG_REQUIRE_INIT) {\n\t\t\t/* Used for minimal 'const': initializer required. */\n\t\t\tgoto syntax_error;\n\t\t}\n\t}\n\n\tduk_pop(thr);  /* pop varname */\n\n\t*out_rc_varname = rc_varname;\n\t*out_reg_varbind = reg_varbind;\n\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_VAR_DECLARATION);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_var_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags) {\n\tduk_regconst_t reg_varbind;\n\tduk_regconst_t rc_varname;\n\n\tduk__advance(comp_ctx);  /* eat 'var' */\n\n\tfor (;;) {\n\t\t/* rc_varname and reg_varbind are ignored here */\n\t\tduk__parse_var_decl(comp_ctx, res, 0 | expr_flags, &reg_varbind, &rc_varname);\n\n\t\tif (comp_ctx->curr_token.t != DUK_TOK_COMMA) {\n\t\t\tbreak;\n\t\t}\n\t\tduk__advance(comp_ctx);\n\t}\n}\n\nDUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_int_t pc_v34_lhs;         /* start variant 3/4 left-hand-side code (L1 in doc/compiler.rst example) */\n\tduk_regconst_t temp_reset;    /* knock back \"next temp\" to this whenever possible */\n\tduk_regconst_t reg_temps;     /* preallocated temporaries (2) for variants 3 and 4 */\n\n\tDUK_DDD(DUK_DDDPRINT(\"start parsing a for/for-in statement\"));\n\n\t/* Two temporaries are preallocated here for variants 3 and 4 which need\n\t * registers which are never clobbered by expressions in the loop\n\t * (concretely: for the enumerator object and the next enumerated value).\n\t * Variants 1 and 2 \"release\" these temps.\n\t */\n\n\treg_temps = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\ttemp_reset = DUK__GETTEMP(comp_ctx);\n\n\t/*\n\t *  For/for-in main variants are:\n\t *\n\t *    1. for (ExpressionNoIn_opt; Expression_opt; Expression_opt) Statement\n\t *    2. for (var VariableDeclarationNoIn; Expression_opt; Expression_opt) Statement\n\t *    3. for (LeftHandSideExpression in Expression) Statement\n\t *    4. for (var VariableDeclarationNoIn in Expression) Statement\n\t *\n\t *  Parsing these without arbitrary lookahead or backtracking is relatively\n\t *  tricky but we manage to do so for now.\n\t *\n\t *  See doc/compiler.rst for a detailed discussion of control flow\n\t *  issues, evaluation order issues, etc.\n\t */\n\n\tduk__advance(comp_ctx);  /* eat 'for' */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\tDUK_DDD(DUK_DDDPRINT(\"detecting for/for-in loop variant, pc=%ld\", (long) duk__get_current_pc(comp_ctx)));\n\n\t/* a label site has been emitted by duk__parse_stmt() automatically\n\t * (it will also emit the ENDLABEL).\n\t */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_VAR) {\n\t\t/*\n\t\t *  Variant 2 or 4\n\t\t */\n\n\t\tduk_regconst_t reg_varbind;  /* variable binding register if register-bound (otherwise < 0) */\n\t\tduk_regconst_t rc_varname;   /* variable name reg/const, if variable not register-bound */\n\n\t\tduk__advance(comp_ctx);  /* eat 'var' */\n\t\tduk__parse_var_decl(comp_ctx, res, DUK__EXPR_FLAG_REJECT_IN, &reg_varbind, &rc_varname);\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_IN) {\n\t\t\t/*\n\t\t\t *  Variant 4\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 4: for (var VariableDeclarationNoIn in Expression) Statement\"));\n\t\t\tpc_v34_lhs = duk__get_current_pc(comp_ctx);  /* jump is inserted here */\n\t\t\tif (reg_varbind >= 0) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_LDREG,\n\t\t\t\t               reg_varbind,\n\t\t\t\t               reg_temps + 0);\n\t\t\t} else {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t               reg_temps + 0,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\t\t\tgoto parse_3_or_4;\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Variant 2\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 2: for (var VariableDeclarationNoIn; Expression_opt; Expression_opt) Statement\"));\n\t\t\tfor (;;) {\n\t\t\t\t/* more initializers */\n\t\t\t\tif (comp_ctx->curr_token.t != DUK_TOK_COMMA) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"variant 2 has another variable initializer\"));\n\n\t\t\t\tduk__advance(comp_ctx);  /* eat comma */\n\t\t\t\tduk__parse_var_decl(comp_ctx, res, DUK__EXPR_FLAG_REJECT_IN, &reg_varbind, &rc_varname);\n\t\t\t}\n\t\t\tgoto parse_1_or_2;\n\t\t}\n\t} else {\n\t\t/*\n\t\t *  Variant 1 or 3\n\t\t */\n\n\t\tpc_v34_lhs = duk__get_current_pc(comp_ctx);  /* jump is inserted here (variant 3) */\n\n\t\t/* Note that duk__exprtop() here can clobber any reg above current temp_next,\n\t\t * so any loop variables (e.g. enumerator) must be \"preallocated\".\n\t\t */\n\n\t\t/* don't coerce yet to a plain value (variant 3 needs special handling) */\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR | DUK__EXPR_FLAG_REJECT_IN | DUK__EXPR_FLAG_ALLOW_EMPTY /*rbp_flags*/);  /* Expression */\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_IN) {\n\t\t\t/*\n\t\t\t *  Variant 3\n\t\t\t */\n\n\t\t\t/* XXX: need to determine LHS type, and check that it is LHS compatible */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 3: for (LeftHandSideExpression in Expression) Statement\"));\n\t\t\tif (duk__expr_is_empty(comp_ctx)) {\n\t\t\t\tgoto syntax_error;  /* LeftHandSideExpression does not allow empty expression */\n\t\t\t}\n\n\t\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\t\tduk_regconst_t reg_varbind;\n\t\t\t\tduk_regconst_t rc_varname;\n\n\t\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_LDREG,\n\t\t\t\t\t               reg_varbind,\n\t\t\t\t\t               reg_temps + 0);\n\t\t\t\t} else {\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t\t               reg_temps + 0,\n\t\t\t\t\t               rc_varname);\n\t\t\t\t}\n\t\t\t} else if (res->t == DUK_IVAL_PROP) {\n\t\t\t\t/* Don't allow a constant for the object (even for a number etc), as\n\t\t\t\t * it goes into the 'A' field of the opcode.\n\t\t\t\t */\n\t\t\t\tduk_regconst_t reg_obj;\n\t\t\t\tduk_regconst_t rc_key;\n\t\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                reg_obj,\n\t\t\t\t                rc_key,\n\t\t\t\t                reg_temps + 0);\n\t\t\t} else {\n\t\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);  /* just in case */\n\t\t\t\tduk__emit_op_only(comp_ctx,\n\t\t\t\t                  DUK_OP_INVLHS);\n\t\t\t}\n\t\t\tgoto parse_3_or_4;\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Variant 1\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 1: for (ExpressionNoIn_opt; Expression_opt; Expression_opt) Statement\"));\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);\n\t\t\tgoto parse_1_or_2;\n\t\t}\n\t}\n\n parse_1_or_2:\n\t/*\n\t *  Parse variant 1 or 2.  The first part expression (which differs\n\t *  in the variants) has already been parsed and its code emitted.\n\t *\n\t *  reg_temps + 0: unused\n\t *  reg_temps + 1: unused\n\t */\n\t{\n\t\tduk_regconst_t rc_cond;\n\t\tduk_int_t pc_l1, pc_l2, pc_l3, pc_l4;\n\t\tduk_int_t pc_jumpto_l3, pc_jumpto_l4;\n\t\tduk_bool_t expr_c_empty;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"shared code for parsing variants 1 and 2\"));\n\n\t\t/* \"release\" preallocated temps since we won't need them */\n\t\ttemp_reset = reg_temps + 0;\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_SEMICOLON);\n\n\t\tpc_l1 = duk__get_current_pc(comp_ctx);\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR | DUK__EXPR_FLAG_ALLOW_EMPTY /*rbp_flags*/);  /* Expression_opt */\n\t\tif (duk__expr_is_empty(comp_ctx)) {\n\t\t\t/* no need to coerce */\n\t\t\tpc_jumpto_l3 = duk__emit_jump_empty(comp_ctx);  /* to body */\n\t\t\tpc_jumpto_l4 = -1;  /* omitted */\n\t\t} else {\n\t\t\trc_cond = duk__ivalue_toregconst(comp_ctx, res);\n\t\t\tduk__emit_if_false_skip(comp_ctx, rc_cond);\n\t\t\tpc_jumpto_l3 = duk__emit_jump_empty(comp_ctx);  /* to body */\n\t\t\tpc_jumpto_l4 = duk__emit_jump_empty(comp_ctx);  /* to exit */\n\t\t}\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_SEMICOLON);\n\n\t\tpc_l2 = duk__get_current_pc(comp_ctx);\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR | DUK__EXPR_FLAG_ALLOW_EMPTY /*rbp_flags*/);  /* Expression_opt */\n\t\tif (duk__expr_is_empty(comp_ctx)) {\n\t\t\t/* no need to coerce */\n\t\t\texpr_c_empty = 1;\n\t\t\t/* JUMP L1 omitted */\n\t\t} else {\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);\n\t\t\texpr_c_empty = 0;\n\t\t\tduk__emit_jump(comp_ctx, pc_l1);\n\t\t}\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\t\tpc_l3 = duk__get_current_pc(comp_ctx);\n\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\t\tif (expr_c_empty) {\n\t\t\tduk__emit_jump(comp_ctx, pc_l1);\n\t\t} else {\n\t\t\tduk__emit_jump(comp_ctx, pc_l2);\n\t\t}\n\t\t/* temp reset is not necessary after duk__parse_stmt(), which already does it */\n\n\t\tpc_l4 = duk__get_current_pc(comp_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"patching jumps: jumpto_l3: %ld->%ld, jumpto_l4: %ld->%ld, \"\n\t\t                     \"break: %ld->%ld, continue: %ld->%ld\",\n\t\t\t             (long) pc_jumpto_l3, (long) pc_l3, (long) pc_jumpto_l4, (long) pc_l4,\n\t\t                     (long) (pc_label_site + 1), (long) pc_l4, (long) (pc_label_site + 2), (long) pc_l2));\n\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l3, pc_l3);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l4, pc_l4);\n\t\tduk__patch_jump(comp_ctx,\n\t\t                pc_label_site + 1,\n\t\t                pc_l4);                         /* break jump */\n\t\tduk__patch_jump(comp_ctx,\n\t\t                pc_label_site + 2,\n\t\t                expr_c_empty ? pc_l1 : pc_l2);  /* continue jump */\n\t}\n\tgoto finished;\n\n parse_3_or_4:\n\t/*\n\t *  Parse variant 3 or 4.\n\t *\n\t *  For variant 3 (e.g. \"for (A in C) D;\") the code for A (except the\n\t *  final property/variable write) has already been emitted.  The first\n\t *  instruction of that code is at pc_v34_lhs; a JUMP needs to be inserted\n\t *  there to satisfy control flow needs.\n\t *\n\t *  For variant 4, if the variable declaration had an initializer\n\t *  (e.g. \"for (var A = B in C) D;\") the code for the assignment\n\t *  (B) has already been emitted.\n\t *\n\t *  Variables set before entering here:\n\t *\n\t *    pc_v34_lhs:    insert a \"JUMP L2\" here (see doc/compiler.rst example).\n\t *    reg_temps + 0: iteration target value (written to LHS)\n\t *    reg_temps + 1: enumerator object\n\t */\n\t{\n\t\tduk_int_t pc_l1, pc_l2, pc_l3, pc_l4, pc_l5;\n\t\tduk_int_t pc_jumpto_l2, pc_jumpto_l3, pc_jumpto_l4, pc_jumpto_l5;\n\t\tduk_regconst_t reg_target;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"shared code for parsing variants 3 and 4, pc_v34_lhs=%ld\", (long) pc_v34_lhs));\n\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\t/* First we need to insert a jump in the middle of previously\n\t\t * emitted code to get the control flow right.  No jumps can\n\t\t * cross the position where the jump is inserted.  See doc/compiler.rst\n\t\t * for discussion on the intricacies of control flow and side effects\n\t\t * for variants 3 and 4.\n\t\t */\n\n\t\tduk__insert_jump_entry(comp_ctx, pc_v34_lhs);\n\t\tpc_jumpto_l2 = pc_v34_lhs;  /* inserted jump */\n\t\tpc_l1 = pc_v34_lhs + 1;     /* +1, right after inserted jump */\n\n\t\t/* The code for writing reg_temps + 0 to the left hand side has already\n\t\t * been emitted.\n\t\t */\n\n\t\tpc_jumpto_l3 = duk__emit_jump_empty(comp_ctx);  /* -> loop body */\n\n\t\tduk__advance(comp_ctx);  /* eat 'in' */\n\n\t\t/* Parse enumeration target and initialize enumerator.  For 'null' and 'undefined',\n\t\t * INITENUM will creates a 'null' enumerator which works like an empty enumerator\n\t\t * (E5 Section 12.6.4, step 3).  Note that INITENUM requires the value to be in a\n\t\t * register (constant not allowed).\n\t\t */\n\n\t\tpc_l2 = duk__get_current_pc(comp_ctx);\n\t\treg_target = duk__exprtop_toreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);  /* Expression */\n\t\tduk__emit_b_c(comp_ctx,\n\t\t              DUK_OP_INITENUM | DUK__EMIT_FLAG_B_IS_TARGET,\n\t\t              reg_temps + 1,\n\t\t              reg_target);\n\t\tpc_jumpto_l4 = duk__emit_jump_empty(comp_ctx);\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\t\tpc_l3 = duk__get_current_pc(comp_ctx);\n\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\t\t/* temp reset is not necessary after duk__parse_stmt(), which already does it */\n\n\t\t/* NEXTENUM needs a jump slot right after the main opcode.\n\t\t * We need the code emitter to reserve the slot: if there's\n\t\t * target shuffling, the target shuffle opcodes must happen\n\t\t * after the jump slot (for NEXTENUM the shuffle opcodes are\n\t\t * not needed if the enum is finished).\n\t\t */\n\t\tpc_l4 = duk__get_current_pc(comp_ctx);\n\t\tduk__emit_b_c(comp_ctx,\n\t\t              DUK_OP_NEXTENUM | DUK__EMIT_FLAG_B_IS_TARGET | DUK__EMIT_FLAG_RESERVE_JUMPSLOT,\n\t\t              reg_temps + 0,\n\t\t              reg_temps + 1);\n\t\tpc_jumpto_l5 = comp_ctx->emit_jumpslot_pc;  /* NEXTENUM jump slot: executed when enum finished */\n\t\tduk__emit_jump(comp_ctx, pc_l1);  /* jump to next loop, using reg_v34_iter as iterated value */\n\n\t\tpc_l5 = duk__get_current_pc(comp_ctx);\n\n\t\t/* XXX: since the enumerator may be a memory expensive object,\n\t\t * perhaps clear it explicitly here?  If so, break jump must\n\t\t * go through this clearing operation.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"patching jumps: jumpto_l2: %ld->%ld, jumpto_l3: %ld->%ld, \"\n\t\t                     \"jumpto_l4: %ld->%ld, jumpto_l5: %ld->%ld, \"\n\t\t                     \"break: %ld->%ld, continue: %ld->%ld\",\n\t\t\t             (long) pc_jumpto_l2, (long) pc_l2, (long) pc_jumpto_l3, (long) pc_l3,\n\t\t\t             (long) pc_jumpto_l4, (long) pc_l4, (long) pc_jumpto_l5, (long) pc_l5,\n\t\t                     (long) (pc_label_site + 1), (long) pc_l5, (long) (pc_label_site + 2), (long) pc_l4));\n\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l2, pc_l2);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l3, pc_l3);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l4, pc_l4);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l5, pc_l5);\n\t\tduk__patch_jump(comp_ctx, pc_label_site + 1, pc_l5);  /* break jump */\n\t\tduk__patch_jump(comp_ctx, pc_label_site + 2, pc_l4);  /* continue jump */\n\t}\n\tgoto finished;\n\n finished:\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing a for/for-in statement\"));\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_FOR);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t temp_at_loop;\n\tduk_regconst_t rc_switch;    /* reg/const for switch value */\n\tduk_regconst_t rc_case;      /* reg/const for case value */\n\tduk_regconst_t reg_temp;     /* general temp register */\n\tduk_int_t pc_prevcase = -1;\n\tduk_int_t pc_prevstmt = -1;\n\tduk_int_t pc_default = -1;   /* -1 == not set, -2 == pending (next statement list) */\n\n\t/* Note: negative pc values are ignored when patching jumps, so no explicit checks needed */\n\n\t/*\n\t *  Switch is pretty complicated because of several conflicting concerns:\n\t *\n\t *    - Want to generate code without an intermediate representation,\n\t *      i.e., in one go\n\t *\n\t *    - Case selectors are expressions, not values, and may thus e.g. throw\n\t *      exceptions (which causes evaluation order concerns)\n\t *\n\t *    - Evaluation semantics of case selectors and default clause need to be\n\t *      carefully implemented to provide correct behavior even with case value\n\t *      side effects\n\t *\n\t *    - Fall through case and default clauses; avoiding dead JUMPs if case\n\t *      ends with an unconditional jump (a break or a continue)\n\t *\n\t *    - The same case value may occur multiple times, but evaluation rules\n\t *      only process the first match before switching to a \"propagation\" mode\n\t *      where case values are no longer evaluated\n\t *\n\t *  See E5 Section 12.11.  Also see doc/compiler.rst for compilation\n\t *  discussion.\n\t */\n\n\tduk__advance(comp_ctx);\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\trc_switch = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* RegExp mode does not matter. */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\n\tDUK_DDD(DUK_DDDPRINT(\"switch value in register %ld\", (long) rc_switch));\n\n\ttemp_at_loop = DUK__GETTEMP(comp_ctx);\n\n\tfor (;;) {\n\t\tduk_int_t num_stmts;\n\t\tduk_small_uint_t tok;\n\n\t\t/* sufficient for keeping temp reg numbers in check */\n\t\tDUK__SETTEMP(comp_ctx, temp_at_loop);\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\tbreak;\n\t\t}\n\n\t\t/*\n\t\t *  Parse a case or default clause.\n\t\t */\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_CASE) {\n\t\t\t/*\n\t\t\t *  Case clause.\n\t\t\t *\n\t\t\t *  Note: cannot use reg_case as a temp register (for SEQ target)\n\t\t\t *  because it may be a constant.\n\t\t\t */\n\n\t\t\tduk__patch_jump_here(comp_ctx, pc_prevcase);  /* chain jumps for case\n\t\t\t                                               * evaluation and checking\n\t\t\t                                               */\n\n\t\t\tduk__advance(comp_ctx);\n\t\t\trc_case = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_SEQ | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_temp,\n\t\t\t                rc_switch,\n\t\t\t                rc_case);\n\t\t\tduk__emit_if_true_skip(comp_ctx, reg_temp);\n\n\t\t\t/* jump to next case clause */\n\t\t\tpc_prevcase = duk__emit_jump_empty(comp_ctx);  /* no match, next case */\n\n\t\t\t/* statements go here (if any) on next loop */\n\t\t} else if (comp_ctx->curr_token.t == DUK_TOK_DEFAULT) {\n\t\t\t/*\n\t\t\t *  Default clause.\n\t\t\t */\n\n\t\t\tif (pc_default >= 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t\tduk__advance(comp_ctx);\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\n\t\t\t/* Fix for https://github.com/svaarala/duktape/issues/155:\n\t\t\t * If 'default' is first clause (detected by pc_prevcase < 0)\n\t\t\t * we need to ensure we stay in the matching chain.\n\t\t\t */\n\t\t\tif (pc_prevcase < 0) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"default clause is first, emit prevcase jump\"));\n\t\t\t\tpc_prevcase = duk__emit_jump_empty(comp_ctx);\n\t\t\t}\n\n\t\t\t/* default clause matches next statement list (if any) */\n\t\t\tpc_default = -2;\n\t\t} else {\n\t\t\t/* Code is not accepted before the first case/default clause */\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/*\n\t\t *  Parse code after the clause.  Possible terminators are\n\t\t *  'case', 'default', and '}'.\n\t\t *\n\t\t *  Note that there may be no code at all, not even an empty statement,\n\t\t *  between case clauses.  This must be handled just like an empty statement\n\t\t *  (omitting seemingly pointless JUMPs), to avoid situations like\n\t\t *  test-bug-case-fallthrough.js.\n\t\t */\n\n\t\tnum_stmts = 0;\n\t\tif (pc_default == -2) {\n\t\t\tpc_default = duk__get_current_pc(comp_ctx);\n\t\t}\n\n\t\t/* Note: this is correct even for default clause statements:\n\t\t * they participate in 'fall-through' behavior even if the\n\t\t * default clause is in the middle.\n\t\t */\n\t\tduk__patch_jump_here(comp_ctx, pc_prevstmt);  /* chain jumps for 'fall-through'\n\t\t                                               * after a case matches.\n\t\t                                               */\n\n\t\tfor (;;) {\n\t\t\ttok = comp_ctx->curr_token.t;\n\t\t\tif (tok == DUK_TOK_CASE || tok == DUK_TOK_DEFAULT ||\n\t\t\t    tok == DUK_TOK_RCURLY) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tnum_stmts++;\n\t\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\t\t}\n\n\t\t/* fall-through jump to next code of next case (backpatched) */\n\t\tpc_prevstmt = duk__emit_jump_empty(comp_ctx);\n\n\t\t/* XXX: would be nice to omit this jump when the jump is not\n\t\t * reachable, at least in the obvious cases (such as the case\n\t\t * ending with a 'break'.\n\t\t *\n\t\t * Perhaps duk__parse_stmt() could provide some info on whether\n\t\t * the statement is a \"dead end\"?\n\t\t *\n\t\t * If implemented, just set pc_prevstmt to -1 when not needed.\n\t\t */\n\t}\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RCURLY);\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance(comp_ctx);  /* Allow RegExp as part of next stmt. */\n\n\t/* default case control flow patchup; note that if pc_prevcase < 0\n\t * (i.e. no case clauses), control enters default case automatically.\n\t */\n\tif (pc_default >= 0) {\n\t\t/* default case exists: go there if no case matches */\n\t\tduk__patch_jump(comp_ctx, pc_prevcase, pc_default);\n\t} else {\n\t\t/* default case does not exist, or no statements present\n\t\t * after default case: finish case evaluation\n\t\t */\n\t\tduk__patch_jump_here(comp_ctx, pc_prevcase);\n\t}\n\n\t/* fall-through control flow patchup; note that pc_prevstmt may be\n\t * < 0 (i.e. no case clauses), in which case this is a no-op.\n\t */\n\tduk__patch_jump_here(comp_ctx, pc_prevstmt);\n\n\t/* continue jump not patched, an INVALID opcode remains there */\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 1);  /* break jump */\n\n\t/* Note: 'fast' breaks will jump to pc_label_site + 1, which will\n\t * then jump here.  The double jump will be eliminated by a\n\t * peephole pass, resulting in an optimal jump here.  The label\n\t * site jumps will remain in bytecode and will waste code size.\n\t */\n\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_SWITCH);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_if_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_regconst_t temp_reset;\n\tduk_regconst_t rc_cond;\n\tduk_int_t pc_jump_false;\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin parsing if statement\"));\n\n\ttemp_reset = DUK__GETTEMP(comp_ctx);\n\n\tduk__advance(comp_ctx);  /* eat 'if' */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\trc_cond = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_if_true_skip(comp_ctx, rc_cond);\n\tpc_jump_false = duk__emit_jump_empty(comp_ctx);  /* jump to end or else part */\n\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\n\t/* The 'else' ambiguity is resolved by 'else' binding to the innermost\n\t * construct, so greedy matching is correct here.\n\t */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_ELSE) {\n\t\tduk_int_t pc_jump_end;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"if has else part\"));\n\n\t\tduk__advance(comp_ctx);\n\n\t\tpc_jump_end = duk__emit_jump_empty(comp_ctx);  /* jump from true part to end */\n\t\tduk__patch_jump_here(comp_ctx, pc_jump_false);\n\n\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\n\t\tduk__patch_jump_here(comp_ctx, pc_jump_end);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"if does not have else part\"));\n\n\t\tduk__patch_jump_here(comp_ctx, pc_jump_false);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing if statement\"));\n}\n\nDUK_LOCAL void duk__parse_do_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_regconst_t rc_cond;\n\tduk_int_t pc_start;\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin parsing do statement\"));\n\n\tduk__advance(comp_ctx);  /* Eat 'do'; allow RegExp as part of next stmt. */\n\n\tpc_start = duk__get_current_pc(comp_ctx);\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 2);  /* continue jump */\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_WHILE);\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\trc_cond = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_if_false_skip(comp_ctx, rc_cond);\n\tduk__emit_jump(comp_ctx, pc_start);\n\t/* no need to reset temps, as we're finished emitting code */\n\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;  /* Allow RegExp as part of next stmt. */\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);\n\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 1);  /* break jump */\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing do statement\"));\n}\n\nDUK_LOCAL void duk__parse_while_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_regconst_t temp_reset;\n\tduk_regconst_t rc_cond;\n\tduk_int_t pc_start;\n\tduk_int_t pc_jump_false;\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin parsing while statement\"));\n\n\ttemp_reset = DUK__GETTEMP(comp_ctx);\n\n\tduk__advance(comp_ctx);  /* eat 'while' */\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\tpc_start = duk__get_current_pc(comp_ctx);\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 2);  /* continue jump */\n\n\trc_cond = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_if_true_skip(comp_ctx, rc_cond);\n\tpc_jump_false = duk__emit_jump_empty(comp_ctx);\n\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\tduk__emit_jump(comp_ctx, pc_start);\n\n\tduk__patch_jump_here(comp_ctx, pc_jump_false);\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 1);  /* break jump */\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing while statement\"));\n}\n\nDUK_LOCAL void duk__parse_break_or_continue_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t is_break = (comp_ctx->curr_token.t == DUK_TOK_BREAK);\n\tduk_int_t label_id;\n\tduk_int_t label_catch_depth;\n\tduk_int_t label_pc;  /* points to LABEL; pc+1 = jump site for break; pc+2 = jump site for continue */\n\tduk_bool_t label_is_closest;\n\n\tDUK_UNREF(res);\n\n\tduk__advance(comp_ctx);  /* eat 'break' or 'continue' */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON ||  /* explicit semi follows */\n\t    comp_ctx->curr_token.lineterm ||                /* automatic semi will be inserted */\n\t    comp_ctx->curr_token.allow_auto_semi) {         /* automatic semi will be inserted */\n\t\t/* break/continue without label */\n\n\t\tduk__lookup_active_label(comp_ctx, DUK_HTHREAD_STRING_EMPTY_STRING(thr), is_break, &label_id, &label_catch_depth, &label_pc, &label_is_closest);\n\t} else if (comp_ctx->curr_token.t == DUK_TOK_IDENTIFIER) {\n\t\t/* break/continue with label (label cannot be a reserved word, production is 'Identifier' */\n\t\tDUK_ASSERT(comp_ctx->curr_token.str1 != NULL);\n\t\tduk__lookup_active_label(comp_ctx, comp_ctx->curr_token.str1, is_break, &label_id, &label_catch_depth, &label_pc, &label_is_closest);\n\t\tduk__advance(comp_ctx);\n\t} else {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_BREAK_CONT_LABEL);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* Use a fast break/continue when possible.  A fast break/continue is\n\t * just a jump to the LABEL break/continue jump slot, which then jumps\n\t * to an appropriate place (for break, going through ENDLABEL correctly).\n\t * The peephole optimizer will optimize the jump to a direct one.\n\t */\n\n\tif (label_catch_depth == comp_ctx->curr_func.catch_depth &&\n\t    label_is_closest) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"break/continue: is_break=%ld, label_id=%ld, label_is_closest=%ld, \"\n\t\t                     \"label_catch_depth=%ld, catch_depth=%ld \"\n\t\t                     \"-> use fast variant (direct jump)\",\n\t\t                     (long) is_break, (long) label_id, (long) label_is_closest,\n\t\t                     (long) label_catch_depth, (long) comp_ctx->curr_func.catch_depth));\n\n\t\tduk__emit_jump(comp_ctx, label_pc + (is_break ? 1 : 2));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"break/continue: is_break=%ld, label_id=%ld, label_is_closest=%ld, \"\n\t\t                     \"label_catch_depth=%ld, catch_depth=%ld \"\n\t\t                     \"-> use slow variant (longjmp)\",\n\t\t                     (long) is_break, (long) label_id, (long) label_is_closest,\n\t\t                     (long) label_catch_depth, (long) comp_ctx->curr_func.catch_depth));\n\n\t\tduk__emit_bc(comp_ctx,\n\t\t             is_break ? DUK_OP_BREAK : DUK_OP_CONTINUE,\n\t\t             (duk_regconst_t) label_id);\n\t}\n}\n\nDUK_LOCAL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t rc_val;\n\n\tduk__advance(comp_ctx);  /* eat 'return' */\n\n\t/* A 'return' statement is only allowed inside an actual function body,\n\t * not as part of eval or global code.\n\t */\n\tif (!comp_ctx->curr_func.is_function) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_RETURN);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON ||  /* explicit semi follows */\n\t    comp_ctx->curr_token.lineterm ||                /* automatic semi will be inserted */\n\t    comp_ctx->curr_token.allow_auto_semi) {         /* automatic semi will be inserted */\n\t\tDUK_DDD(DUK_DDDPRINT(\"empty return value -> undefined\"));\n\t\tduk__emit_op_only(comp_ctx, DUK_OP_RETUNDEF);\n\t} else {\n\t\tduk_int_t pc_before_expr;\n\t\tduk_int_t pc_after_expr;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"return with a value\"));\n\n\t\tDUK_UNREF(pc_before_expr);\n\t\tDUK_UNREF(pc_after_expr);\n\n\t\tpc_before_expr = duk__get_current_pc(comp_ctx);\n\t\trc_val = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\t\tpc_after_expr = duk__get_current_pc(comp_ctx);\n\n\t\t/* Tail call check: if last opcode emitted was CALL, and\n\t\t * the context allows it, add a tailcall flag to the CALL.\n\t\t * This doesn't guarantee that a tail call will be allowed at\n\t\t * runtime, so the RETURN must still be emitted.  (Duktape\n\t\t * 0.10.0 avoided this and simulated a RETURN if a tail call\n\t\t * couldn't be used at runtime; but this didn't work\n\t\t * correctly with a thread yield/resume, see\n\t\t * test-bug-tailcall-thread-yield-resume.js for discussion.)\n\t\t *\n\t\t * In addition to the last opcode being CALL, we also need to\n\t\t * be sure that 'rc_val' is the result register of the CALL.\n\t\t * For instance, for the expression 'return 0, (function ()\n\t\t * { return 1; }), 2' the last opcode emitted is CALL (no\n\t\t * bytecode is emitted for '2') but 'rc_val' indicates\n\t\t * constant '2'.  Similarly if '2' is replaced by a register\n\t\t * bound variable, no opcodes are emitted but tail call would\n\t\t * be incorrect.\n\t\t *\n\t\t * This is tricky and easy to get wrong.  It would be best to\n\t\t * track enough expression metadata to check that 'rc_val' came\n\t\t * from that last CALL instruction.  We don't have that metadata\n\t\t * now, so we check that 'rc_val' is a temporary register result\n\t\t * (not a constant or a register bound variable).  There should\n\t\t * be no way currently for 'rc_val' to be a temporary for an\n\t\t * expression following the CALL instruction without emitting\n\t\t * some opcodes following the CALL.  This proxy check is used\n\t\t * below.\n\t\t *\n\t\t * See: test-bug-comma-expr-gh131.js.\n\t\t *\n\t\t * The non-standard 'caller' property disables tail calls\n\t\t * because they pose some special cases which haven't been\n\t\t * fixed yet.\n\t\t */\n\n#if defined(DUK_USE_TAILCALL)\n\t\tif (comp_ctx->curr_func.catch_depth == 0 &&   /* no catchers */\n\t\t    pc_after_expr > pc_before_expr) {         /* at least one opcode emitted */\n\t\t\tduk_compiler_instr *instr;\n\t\t\tduk_instr_t ins;\n\t\t\tduk_small_uint_t op;\n\n\t\t\tinstr = duk__get_instr_ptr(comp_ctx, pc_after_expr - 1);\n\t\t\tDUK_ASSERT(instr != NULL);\n\n\t\t\tins = instr->ins;\n\t\t\top = (duk_small_uint_t) DUK_DEC_OP(ins);\n\t\t\tif ((op & ~0x0fU) == DUK_OP_CALL0 &&\n\t\t\t    DUK__ISREG_TEMP(comp_ctx, rc_val) /* see above */) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"return statement detected a tail call opportunity: \"\n\t\t\t\t                     \"catch depth is 0, duk__exprtop() emitted >= 1 instructions, \"\n\t\t\t\t                     \"and last instruction is a CALL \"\n\t\t\t\t                     \"-> change to TAILCALL\"));\n\t\t\t\tins |= DUK_ENC_OP(DUK_BC_CALL_FLAG_TAILCALL);\n\t\t\t\tinstr->ins = ins;\n\t\t\t}\n\t\t}\n#endif  /* DUK_USE_TAILCALL */\n\n\t\tif (DUK__ISREG(rc_val)) {\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_RETREG, rc_val);\n\t\t} else {\n\t\t\trc_val = DUK__REMOVECONST(rc_val);\n\t\t\tif (duk__const_needs_refcount(comp_ctx, rc_val)) {\n\t\t\t\tduk__emit_bc(comp_ctx, DUK_OP_RETCONST, rc_val);\n\t\t\t} else {\n\t\t\t\tduk__emit_bc(comp_ctx, DUK_OP_RETCONSTN, rc_val);\n\t\t\t}\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__parse_throw_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_regconst_t reg_val;\n\n\tduk__advance(comp_ctx);  /* eat 'throw' */\n\n\t/* Unlike break/continue, throw statement does not allow an empty value. */\n\n\tif (comp_ctx->curr_token.lineterm) {\n\t\tDUK_ERROR_SYNTAX(comp_ctx->thr, DUK_STR_INVALID_THROW);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\treg_val = duk__exprtop_toreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_bc(comp_ctx,\n\t             DUK_OP_THROW,\n\t             reg_val);\n}\n\nDUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg_catch;      /* reg_catch+0 and reg_catch+1 are reserved for TRYCATCH */\n\tduk_regconst_t rc_varname = 0;\n\tduk_small_uint_t trycatch_flags = 0;\n\tduk_int_t pc_ldconst = -1;\n\tduk_int_t pc_trycatch = -1;\n\tduk_int_t pc_catch = -1;\n\tduk_int_t pc_finally = -1;\n\n\tDUK_UNREF(res);\n\n\t/*\n\t *  See the following documentation for discussion:\n\t *\n\t *    doc/execution.rst: control flow details\n\t *\n\t *  Try, catch, and finally \"parts\" are Blocks, not Statements, so\n\t *  they must always be delimited by curly braces.  This is unlike e.g.\n\t *  the if statement, which accepts any Statement.  This eliminates any\n\t *  questions of matching parts of nested try statements.  The Block\n\t *  parsing is implemented inline here (instead of calling out).\n\t *\n\t *  Finally part has a 'let scoped' variable, which requires a few kinks\n\t *  here.\n\t */\n\n\tcomp_ctx->curr_func.catch_depth++;\n\n\tduk__advance(comp_ctx);  /* eat 'try' */\n\n\treg_catch = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\t/* The target for this LDCONST may need output shuffling, but we assume\n\t * that 'pc_ldconst' will be the LDCONST that we can patch later.  This\n\t * should be the case because there's no input shuffling.  (If there's\n\t * no catch clause, this LDCONST will be replaced with a NOP.)\n\t */\n\tpc_ldconst = duk__get_current_pc(comp_ctx);\n\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, reg_catch, 0 /*patched later*/);\n\n\tpc_trycatch = duk__get_current_pc(comp_ctx);\n\tduk__emit_invalid(comp_ctx);  /* TRYCATCH, cannot emit now (not enough info) */\n\tduk__emit_invalid(comp_ctx);  /* jump for 'catch' case */\n\tduk__emit_invalid(comp_ctx);  /* jump for 'finally' case or end (if no finally) */\n\n\t/* try part */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\tduk__emit_op_only(comp_ctx, DUK_OP_ENDTRY);\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_CATCH) {\n\t\t/*\n\t\t *  The catch variable must be updated to reflect the new allocated\n\t\t *  register for the duration of the catch clause.  We need to store\n\t\t *  and restore the original value for the varmap entry (if any).\n\t\t */\n\n\t\t/*\n\t\t *  Note: currently register bindings must be fixed for the entire\n\t\t *  function.  So, even though the catch variable is in a register\n\t\t *  we know, we must use an explicit environment record and slow path\n\t\t *  accesses to read/write the catch binding to make closures created\n\t\t *  within the catch clause work correctly.  This restriction should\n\t\t *  be fixable (at least in common cases) later.\n\t\t *\n\t\t *  See: test-bug-catch-binding-2.js.\n\t\t *\n\t\t *  XXX: improve to get fast path access to most catch clauses.\n\t\t */\n\n\t\tduk_hstring *h_var;\n\t\tduk_int_t varmap_value;  /* for storing/restoring the varmap binding for catch variable */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"stack top at start of catch clause: %ld\", (long) duk_get_top(thr)));\n\n\t\ttrycatch_flags |= DUK_BC_TRYCATCH_FLAG_HAVE_CATCH;\n\n\t\tpc_catch = duk__get_current_pc(comp_ctx);\n\n\t\tduk__advance(comp_ctx);\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\t\tif (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) {\n\t\t\t/* Identifier, i.e. don't allow reserved words */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\th_var = comp_ctx->curr_token.str1;\n\t\tDUK_ASSERT(h_var != NULL);\n\n\t\tduk_push_hstring(thr, h_var);  /* keep in on valstack, use borrowed ref below */\n\n\t\tif (comp_ctx->curr_func.is_strict &&\n\t\t    ((h_var == DUK_HTHREAD_STRING_EVAL(thr)) ||\n\t\t     (h_var == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)))) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"catch identifier 'eval' or 'arguments' in strict mode -> SyntaxError\"));\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\tduk_dup_top(thr);\n\t\trc_varname = duk__getconst(comp_ctx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"catch clause, rc_varname=0x%08lx (%ld)\",\n\t\t                     (unsigned long) rc_varname, (long) rc_varname));\n\n\t\tduk__advance(comp_ctx);\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"varmap before modifying for catch clause: %!iT\",\n\t\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));\n\n\t\tduk_dup_top(thr);\n\t\tduk_get_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\tvarmap_value = -2;\n\t\t} else if (duk_is_null(thr, -1)) {\n\t\t\tvarmap_value = -1;\n\t\t} else {\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tvarmap_value = duk_get_int(thr, -1);\n\t\t\tDUK_ASSERT(varmap_value >= 0);\n\t\t}\n\t\tduk_pop(thr);\n\n#if 0\n\t\t/* It'd be nice to do something like this - but it doesn't\n\t\t * work for closures created inside the catch clause.\n\t\t */\n\t\tduk_dup_top(thr);\n\t\tduk_push_int(thr, (duk_int_t) (reg_catch + 0));\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);\n#endif\n\t\tduk_dup_top(thr);\n\t\tduk_push_null(thr);\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t               reg_catch + 0 /*value*/,\n\t\t               rc_varname /*varname*/);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"varmap before parsing catch clause: %!iT\",\n\t\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));\n\n\t\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\n\t\tif (varmap_value == -2) {\n\t\t\t/* not present */\n\t\t\tduk_del_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\t} else {\n\t\t\tif (varmap_value == -1) {\n\t\t\t\tduk_push_null(thr);\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(varmap_value >= 0);\n\t\t\t\tduk_push_int(thr, varmap_value);\n\t\t\t}\n\t\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\t}\n\t\t/* varname is popped by above code */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"varmap after restore catch clause: %!iT\",\n\t\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));\n\n\t\tduk__emit_op_only(comp_ctx,\n\t\t                  DUK_OP_ENDCATCH);\n\n\t\t/*\n\t\t *  XXX: for now, indicate that an expensive catch binding\n\t\t *  declarative environment is always needed.  If we don't\n\t\t *  need it, we don't need the const_varname either.\n\t\t */\n\n\t\ttrycatch_flags |= DUK_BC_TRYCATCH_FLAG_CATCH_BINDING;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"stack top at end of catch clause: %ld\", (long) duk_get_top(thr)));\n\t}\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_FINALLY) {\n\t\ttrycatch_flags |= DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY;\n\n\t\tpc_finally = duk__get_current_pc(comp_ctx);\n\n\t\tduk__advance(comp_ctx);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\t\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\t\tduk__emit_abc(comp_ctx,\n\t\t              DUK_OP_ENDFIN,\n\t\t              reg_catch);  /* rethrow */\n\t}\n\n\tif (!(trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) &&\n\t    !(trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY)) {\n\t\t/* must have catch and/or finally */\n\t\tgoto syntax_error;\n\t}\n\n\t/* If there's no catch block, rc_varname will be 0 and duk__patch_trycatch()\n\t * will replace the LDCONST with a NOP.  For any actual constant (including\n\t * constant 0) the DUK__CONST_MARKER flag will be set in rc_varname.\n\t */\n\n\tduk__patch_trycatch(comp_ctx,\n\t                    pc_ldconst,\n\t                    pc_trycatch,\n\t                    reg_catch,\n\t                    rc_varname,\n\t                    trycatch_flags);\n\n\tif (trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) {\n\t\tDUK_ASSERT(pc_catch >= 0);\n\t\tduk__patch_jump(comp_ctx, pc_trycatch + 1, pc_catch);\n\t}\n\n\tif (trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY) {\n\t\tDUK_ASSERT(pc_finally >= 0);\n\t\tduk__patch_jump(comp_ctx, pc_trycatch + 2, pc_finally);\n\t} else {\n\t\t/* without finally, the second jump slot is used to jump to end of stmt */\n\t\tduk__patch_jump_here(comp_ctx, pc_trycatch + 2);\n\t}\n\n\tcomp_ctx->curr_func.catch_depth--;\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_TRY);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_int_t pc_trycatch;\n\tduk_int_t pc_finished;\n\tduk_regconst_t reg_catch;\n\tduk_small_uint_t trycatch_flags;\n\n\tif (comp_ctx->curr_func.is_strict) {\n\t\tDUK_ERROR_SYNTAX(comp_ctx->thr, DUK_STR_WITH_IN_STRICT_MODE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tcomp_ctx->curr_func.catch_depth++;\n\n\tduk__advance(comp_ctx);  /* eat 'with' */\n\n\treg_catch = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\tduk__exprtop_toforcedreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/, reg_catch);\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\tpc_trycatch = duk__get_current_pc(comp_ctx);\n\ttrycatch_flags = DUK_BC_TRYCATCH_FLAG_WITH_BINDING;\n\tduk__emit_a_bc(comp_ctx,\n\t                DUK_OP_TRYCATCH | DUK__EMIT_FLAG_NO_SHUFFLE_A,\n\t                (duk_regconst_t) trycatch_flags /*a*/,\n\t                reg_catch /*bc*/);\n\tduk__emit_invalid(comp_ctx);  /* catch jump */\n\tduk__emit_invalid(comp_ctx);  /* finished jump */\n\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\tduk__emit_op_only(comp_ctx, DUK_OP_ENDTRY);\n\n\tpc_finished = duk__get_current_pc(comp_ctx);\n\n\tduk__patch_jump(comp_ctx, pc_trycatch + 2, pc_finished);\n\n\tcomp_ctx->curr_func.catch_depth--;\n}\n\nDUK_LOCAL duk_int_t duk__stmt_label_site(duk_compiler_ctx *comp_ctx, duk_int_t label_id) {\n\t/* if a site already exists, nop: max one label site per statement */\n\tif (label_id >= 0) {\n\t\treturn label_id;\n\t}\n\n\tlabel_id = comp_ctx->curr_func.label_next++;\n\tDUK_DDD(DUK_DDDPRINT(\"allocated new label id for label site: %ld\", (long) label_id));\n\n\tduk__emit_bc(comp_ctx,\n\t             DUK_OP_LABEL,\n\t             (duk_regconst_t) label_id);\n\tduk__emit_invalid(comp_ctx);\n\tduk__emit_invalid(comp_ctx);\n\n\treturn label_id;\n}\n\n/* Parse a single statement.\n *\n * Creates a label site (with an empty label) automatically for iteration\n * statements.  Also \"peels off\" any label statements for explicit labels.\n */\nDUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_bool_t allow_source_elem) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t dir_prol_at_entry;    /* directive prologue status at entry */\n\tduk_regconst_t temp_at_entry;\n\tduk_size_t labels_len_at_entry;\n\tduk_int_t pc_at_entry;           /* assumed to also be PC of \"LABEL\" */\n\tduk_int_t stmt_id;\n\tduk_small_uint_t stmt_flags = 0;\n\tduk_int_t label_id = -1;\n\tduk_small_uint_t tok;\n\tduk_bool_t test_func_decl;\n\n\tDUK__RECURSION_INCREASE(comp_ctx, thr);\n\n\ttemp_at_entry = DUK__GETTEMP(comp_ctx);\n\tpc_at_entry = duk__get_current_pc(comp_ctx);\n\tlabels_len_at_entry = duk_get_length(thr, comp_ctx->curr_func.labelnames_idx);\n\tstmt_id = comp_ctx->curr_func.stmt_next++;\n\tdir_prol_at_entry = comp_ctx->curr_func.in_directive_prologue;\n\n\tDUK_UNREF(stmt_id);\n\n\tDUK_DDD(DUK_DDDPRINT(\"parsing a statement, stmt_id=%ld, temp_at_entry=%ld, labels_len_at_entry=%ld, \"\n\t                     \"is_strict=%ld, in_directive_prologue=%ld, catch_depth=%ld\",\n\t                     (long) stmt_id, (long) temp_at_entry, (long) labels_len_at_entry,\n\t                     (long) comp_ctx->curr_func.is_strict, (long) comp_ctx->curr_func.in_directive_prologue,\n\t                     (long) comp_ctx->curr_func.catch_depth));\n\n\t/* The directive prologue flag is cleared by default so that it is\n\t * unset for any recursive statement parsing.  It is only \"revived\"\n\t * if a directive is detected.  (We could also make directives only\n\t * allowed if 'allow_source_elem' was true.)\n\t */\n\tcomp_ctx->curr_func.in_directive_prologue = 0;\n\n retry_parse:\n\n\tDUK_DDD(DUK_DDDPRINT(\"try stmt parse, stmt_id=%ld, label_id=%ld, allow_source_elem=%ld, catch_depth=%ld\",\n\t                     (long) stmt_id, (long) label_id, (long) allow_source_elem,\n\t                     (long) comp_ctx->curr_func.catch_depth));\n\n\t/*\n\t *  Detect iteration statements; if encountered, establish an\n\t *  empty label.\n\t */\n\n\ttok = comp_ctx->curr_token.t;\n\tif (tok == DUK_TOK_FOR || tok == DUK_TOK_DO || tok == DUK_TOK_WHILE ||\n\t    tok == DUK_TOK_SWITCH) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"iteration/switch statement -> add empty label\"));\n\n\t\tlabel_id = duk__stmt_label_site(comp_ctx, label_id);\n\t\tduk__add_label(comp_ctx,\n\t\t               DUK_HTHREAD_STRING_EMPTY_STRING(thr),\n\t\t               pc_at_entry /*pc_label*/,\n\t\t               label_id);\n\t}\n\n\t/*\n\t *  Main switch for statement / source element type.\n\t */\n\n\tswitch (comp_ctx->curr_token.t) {\n\tcase DUK_TOK_FUNCTION: {\n\t\t/*\n\t\t *  Function declaration, function expression, or (non-standard)\n\t\t *  function statement.\n\t\t *\n\t\t *  The E5 specification only allows function declarations at\n\t\t *  the top level (in \"source elements\").  An ExpressionStatement\n\t\t *  is explicitly not allowed to begin with a \"function\" keyword\n\t\t *  (E5 Section 12.4).  Hence any non-error semantics for such\n\t\t *  non-top-level statements are non-standard.  Duktape semantics\n\t\t *  for function statements are modelled after V8, see\n\t\t *  test-dev-func-decl-outside-top.js.\n\t\t */\n\t\ttest_func_decl = allow_source_elem;\n#if defined(DUK_USE_NONSTD_FUNC_STMT)\n\t\t/* Lenient: allow function declarations outside top level in\n\t\t * non-strict mode but reject them in strict mode.\n\t\t */\n\t\ttest_func_decl = test_func_decl || !comp_ctx->curr_func.is_strict;\n#endif  /* DUK_USE_NONSTD_FUNC_STMT */\n\t\t/* Strict: never allow function declarations outside top level. */\n\t\tif (test_func_decl) {\n\t\t\t/* FunctionDeclaration: not strictly a statement but handled as such.\n\t\t\t *\n\t\t\t * O(depth^2) parse count for inner functions is handled by recording a\n\t\t\t * lexer offset on the first compilation pass, so that the function can\n\t\t\t * be efficiently skipped on the second pass.  This is encapsulated into\n\t\t\t * duk__parse_func_like_fnum().\n\t\t\t */\n\n\t\t\tduk_int_t fnum;\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\tduk_idx_t top_before;\n#endif\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function declaration statement\"));\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\ttop_before = duk_get_top(thr);\n#endif\n\n\t\t\tduk__advance(comp_ctx);  /* eat 'function' */\n\t\t\tfnum = duk__parse_func_like_fnum(comp_ctx, DUK__FUNC_FLAG_DECL | DUK__FUNC_FLAG_PUSHNAME_PASS1);\n\n\t\t\t/* The value stack convention here is a bit odd: the function\n\t\t\t * name is only pushed on pass 1 (in_scanning), and is needed\n\t\t\t * to process function declarations.\n\t\t\t */\n\t\t\tif (comp_ctx->curr_func.in_scanning) {\n\t\t\t\tduk_uarridx_t n;\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t\tDUK_ASSERT(duk_get_top(thr) == top_before + 1);\n#endif\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"register function declaration %!T in pass 1, fnum %ld\",\n\t\t\t\t                     duk_get_tval(thr, -1), (long) fnum));\n\t\t\t\tn = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.decls_idx);\n\t\t\t\t/* funcname is at index -1 */\n\t\t\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n);\n\t\t\t\tduk_push_int(thr, (duk_int_t) (DUK_DECL_TYPE_FUNC + (fnum << 8)));\n\t\t\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n + 1);\n\t\t\t} else {\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t\tDUK_ASSERT(duk_get_top(thr) == top_before);\n#endif\n\t\t\t}\n\n\t\t\t/* no statement value (unlike function expression) */\n\t\t\tstmt_flags = 0;\n\t\t\tbreak;\n\t\t} else {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_FUNC_STMT_NOT_ALLOWED);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TOK_LCURLY: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"block statement\"));\n\t\tduk__advance(comp_ctx);\n\t\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\t\tif (label_id >= 0) {\n\t\t\tduk__patch_jump_here(comp_ctx, pc_at_entry + 1);  /* break jump */\n\t\t}\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_CONST: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"constant declaration statement\"));\n\t\tduk__parse_var_stmt(comp_ctx, res, DUK__EXPR_FLAG_REQUIRE_INIT /*expr_flags*/);\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_VAR: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"variable declaration statement\"));\n\t\tduk__parse_var_stmt(comp_ctx, res, 0 /*expr_flags*/);\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_SEMICOLON: {\n\t\t/* empty statement with an explicit semicolon */\n\t\tDUK_DDD(DUK_DDDPRINT(\"empty statement\"));\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_IF: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"if statement\"));\n\t\tduk__parse_if_stmt(comp_ctx, res);\n\t\tif (label_id >= 0) {\n\t\t\tduk__patch_jump_here(comp_ctx, pc_at_entry + 1);  /* break jump */\n\t\t}\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_DO: {\n\t\t/*\n\t\t *  Do-while statement is mostly trivial, but there is special\n\t\t *  handling for automatic semicolon handling (triggered by the\n\t\t *  DUK__ALLOW_AUTO_SEMI_ALWAYS) flag related to a bug filed at:\n\t\t *\n\t\t *    https://bugs.ecmascript.org/show_bug.cgi?id=8\n\t\t *\n\t\t *  See doc/compiler.rst for details.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"do statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK | DUK_LABEL_FLAG_ALLOW_CONTINUE);\n\t\tduk__parse_do_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__ALLOW_AUTO_SEMI_ALWAYS;  /* DUK__ALLOW_AUTO_SEMI_ALWAYS workaround */\n\t\tbreak;\n\t}\n\tcase DUK_TOK_WHILE: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"while statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK | DUK_LABEL_FLAG_ALLOW_CONTINUE);\n\t\tduk__parse_while_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_FOR: {\n\t\t/*\n\t\t *  For/for-in statement is complicated to parse because\n\t\t *  determining the statement type (three-part for vs. a\n\t\t *  for-in) requires potential backtracking.\n\t\t *\n\t\t *  See the helper for the messy stuff.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"for/for-in statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK | DUK_LABEL_FLAG_ALLOW_CONTINUE);\n\t\tduk__parse_for_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_CONTINUE:\n\tcase DUK_TOK_BREAK: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"break/continue statement\"));\n\t\tduk__parse_break_or_continue_stmt(comp_ctx, res);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__IS_TERMINAL;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_RETURN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"return statement\"));\n\t\tduk__parse_return_stmt(comp_ctx, res);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__IS_TERMINAL;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_WITH: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"with statement\"));\n\t\tcomp_ctx->curr_func.with_depth++;\n\t\tduk__parse_with_stmt(comp_ctx, res);\n\t\tif (label_id >= 0) {\n\t\t\tduk__patch_jump_here(comp_ctx, pc_at_entry + 1);  /* break jump */\n\t\t}\n\t\tcomp_ctx->curr_func.with_depth--;\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_SWITCH: {\n\t\t/*\n\t\t *  The switch statement is pretty messy to compile.\n\t\t *  See the helper for details.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"switch statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK);  /* don't allow continue */\n\t\tduk__parse_switch_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_THROW: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"throw statement\"));\n\t\tduk__parse_throw_stmt(comp_ctx, res);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__IS_TERMINAL;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_TRY: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"try statement\"));\n\t\tduk__parse_try_stmt(comp_ctx, res);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_DEBUGGER: {\n\t\tduk__advance(comp_ctx);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tDUK_DDD(DUK_DDDPRINT(\"debugger statement: debugging enabled, emit debugger opcode\"));\n\t\tduk__emit_op_only(comp_ctx, DUK_OP_DEBUGGER);\n#else\n\t\tDUK_DDD(DUK_DDDPRINT(\"debugger statement: ignored\"));\n#endif\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tdefault: {\n\t\t/*\n\t\t *  Else, must be one of:\n\t\t *    - ExpressionStatement, possibly a directive (String)\n\t\t *    - LabelledStatement (Identifier followed by ':')\n\t\t *\n\t\t *  Expressions beginning with 'function' keyword are covered by a case\n\t\t *  above (such expressions are not allowed in standard E5 anyway).\n\t\t *  Also expressions starting with '{' are interpreted as block\n\t\t *  statements.  See E5 Section 12.4.\n\t\t *\n\t\t *  Directive detection is tricky; see E5 Section 14.1 on directive\n\t\t *  prologue.  A directive is an expression statement with a single\n\t\t *  string literal and an explicit or automatic semicolon.  Escape\n\t\t *  characters are significant and no parens etc are allowed:\n\t\t *\n\t\t *    'use strict';          // valid 'use strict' directive\n\t\t *    'use\\u0020strict';     // valid directive, not a 'use strict' directive\n\t\t *    ('use strict');        // not a valid directive\n\t\t *\n\t\t *  The expression is determined to consist of a single string literal\n\t\t *  based on duk__expr_nud() and duk__expr_led() call counts.  The string literal\n\t\t *  of a 'use strict' directive is determined to lack any escapes based\n\t\t *  num_escapes count from the lexer.  Note that other directives may be\n\t\t *  allowed to contain escapes, so a directive with escapes does not\n\t\t *  terminate a directive prologue.\n\t\t *\n\t\t *  We rely on the fact that the expression parser will not emit any\n\t\t *  code for a single token expression.  However, it will generate an\n\t\t *  intermediate value which we will then successfully ignore.\n\t\t *\n\t\t *  A similar approach is used for labels.\n\t\t */\n\n\t\tduk_bool_t single_token;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"expression statement\"));\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\n\t\tsingle_token = (comp_ctx->curr_func.nud_count == 1 &&  /* one token */\n\t\t                comp_ctx->curr_func.led_count == 0);   /* no operators */\n\n\t\tif (single_token &&\n\t\t    comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t    comp_ctx->curr_token.t == DUK_TOK_COLON) {\n\t\t\t/*\n\t\t\t *  Detected label\n\t\t\t */\n\n\t\t\tduk_hstring *h_lab;\n\n\t\t\t/* expected ival */\n\t\t\tDUK_ASSERT(res->t == DUK_IVAL_VAR);\n\t\t\tDUK_ASSERT(res->x1.t == DUK_ISPEC_VALUE);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(duk_get_tval(thr, res->x1.valstack_idx)));\n\t\t\th_lab = comp_ctx->prev_token.str1;\n\t\t\tDUK_ASSERT(h_lab != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"explicit label site for label '%!O'\",\n\t\t\t                     (duk_heaphdr *) h_lab));\n\n\t\t\tduk__advance(comp_ctx);  /* eat colon */\n\n\t\t\tlabel_id = duk__stmt_label_site(comp_ctx, label_id);\n\n\t\t\tduk__add_label(comp_ctx,\n\t\t\t               h_lab,\n\t\t\t               pc_at_entry /*pc_label*/,\n\t\t\t               label_id);\n\n\t\t\t/* a statement following a label cannot be a source element\n\t\t\t * (a function declaration).\n\t\t\t */\n\t\t\tallow_source_elem = 0;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"label handled, retry statement parsing\"));\n\t\t\tgoto retry_parse;\n\t\t}\n\n\t\tstmt_flags = 0;\n\n\t\tif (dir_prol_at_entry &&                           /* still in prologue */\n\t\t    single_token &&                                /* single string token */\n\t\t    comp_ctx->prev_token.t == DUK_TOK_STRING) {\n\t\t\t/*\n\t\t\t *  Detected a directive\n\t\t\t */\n\t\t\tduk_hstring *h_dir;\n\n\t\t\t/* expected ival */\n\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN);\n\t\t\tDUK_ASSERT(res->x1.t == DUK_ISPEC_VALUE);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(duk_get_tval(thr, res->x1.valstack_idx)));\n\t\t\th_dir = comp_ctx->prev_token.str1;\n\t\t\tDUK_ASSERT(h_dir != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"potential directive: %!O\", h_dir));\n\n\t\t\tstmt_flags |= DUK__STILL_PROLOGUE;\n\n\t\t\t/* Note: escaped characters differentiate directives */\n\n\t\t\tif (comp_ctx->prev_token.num_escapes > 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"directive contains escapes: valid directive \"\n\t\t\t\t                     \"but we ignore such directives\"));\n\t\t\t} else {\n\t\t\t\t/*\n\t\t\t\t * The length comparisons are present to handle\n\t\t\t\t * strings like \"use strict\\u0000foo\" as required.\n\t\t\t\t */\n\n\t\t\t\tif (DUK_HSTRING_GET_BYTELEN(h_dir) == 10 &&\n\t\t\t\t    DUK_STRCMP((const char *) DUK_HSTRING_GET_DATA(h_dir), \"use strict\") == 0) {\n#if defined(DUK_USE_STRICT_DECL)\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"use strict directive detected: strict flag %ld -> %ld\",\n\t\t\t\t\t                     (long) comp_ctx->curr_func.is_strict, (long) 1));\n\t\t\t\t\tcomp_ctx->curr_func.is_strict = 1;\n#else\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"use strict detected but strict declarations disabled, ignoring\"));\n#endif\n\t\t\t\t} else if (DUK_HSTRING_GET_BYTELEN(h_dir) == 14 &&\n\t\t\t\t           DUK_STRCMP((const char *) DUK_HSTRING_GET_DATA(h_dir), \"use duk notail\") == 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"use duk notail directive detected: notail flag %ld -> %ld\",\n\t\t\t\t\t                     (long) comp_ctx->curr_func.is_notail, (long) 1));\n\t\t\t\t\tcomp_ctx->curr_func.is_notail = 1;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"unknown directive: '%!O', ignoring but not terminating \"\n\t\t\t\t\t                   \"directive prologue\", (duk_hobject *) h_dir));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-directive expression statement or no longer in prologue; \"\n\t\t\t                     \"prologue terminated if still active\"));\n                }\n\n\t\tstmt_flags |= DUK__HAS_VAL | DUK__HAS_TERM;\n\t}\n\t}  /* end switch (tok) */\n\n\t/*\n\t *  Statement value handling.\n\t *\n\t *  Global code and eval code has an implicit return value\n\t *  which comes from the last statement with a value\n\t *  (technically a non-\"empty\" continuation, which is\n\t *  different from an empty statement).\n\t *\n\t *  Since we don't know whether a later statement will\n\t *  override the value of the current statement, we need\n\t *  to coerce the statement value to a register allocated\n\t *  for implicit return values.  In other cases we need\n\t *  to coerce the statement value to a plain value to get\n\t *  any side effects out (consider e.g. \"foo.bar;\").\n\t */\n\n\t/* XXX: what about statements which leave a half-cooked value in 'res'\n\t * but have no stmt value?  Any such statements?\n\t */\n\n\tif (stmt_flags & DUK__HAS_VAL) {\n\t\tduk_regconst_t reg_stmt_value = comp_ctx->curr_func.reg_stmt_value;\n\t\tif (reg_stmt_value >= 0) {\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_stmt_value);\n\t\t} else {\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);\n\t\t}\n\t} else {\n\t\t;\n\t}\n\n\t/*\n\t *  Statement terminator check, including automatic semicolon\n\t *  handling.  After this step, 'curr_tok' should be the first\n\t *  token after a possible statement terminator.\n\t */\n\n\tif (stmt_flags & DUK__HAS_TERM) {\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"explicit semicolon terminates statement\"));\n\t\t\tduk__advance(comp_ctx);\n\t\t} else {\n\t\t\tif (comp_ctx->curr_token.allow_auto_semi) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"automatic semicolon terminates statement\"));\n\t\t\t} else if (stmt_flags & DUK__ALLOW_AUTO_SEMI_ALWAYS) {\n\t\t\t\t/* XXX: make this lenience dependent on flags or strictness? */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"automatic semicolon terminates statement (allowed for compatibility \"\n\t\t\t\t                     \"even though no lineterm present before next token)\"));\n\t\t\t} else {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_UNTERMINATED_STMT);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"statement has no terminator\"));\n\t}\n\n\t/*\n\t *  Directive prologue tracking.\n\t */\n\n\tif (stmt_flags & DUK__STILL_PROLOGUE) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"setting in_directive_prologue\"));\n\t\tcomp_ctx->curr_func.in_directive_prologue = 1;\n\t}\n\n\t/*\n\t *  Cleanups (all statement parsing flows through here).\n\t *\n\t *  Pop label site and reset labels.  Reset 'next temp' to value at\n\t *  entry to reuse temps.\n\t */\n\n\tif (label_id >= 0) {\n\t\tduk__emit_bc(comp_ctx,\n\t\t             DUK_OP_ENDLABEL,\n\t\t             (duk_regconst_t) label_id);\n\t}\n\n\tDUK__SETTEMP(comp_ctx, temp_at_entry);\n\n\tduk__reset_labels_to_length(comp_ctx, labels_len_at_entry);\n\n\t/* XXX: return indication of \"terminalness\" (e.g. a 'throw' is terminal) */\n\n\tDUK__RECURSION_DECREASE(comp_ctx, thr);\n}\n\n/*\n *  Parse a statement list.\n *\n *  Handles automatic semicolon insertion and implicit return value.\n *\n *  Upon entry, 'curr_tok' should contain the first token of the first\n *  statement (parsed in the \"allow regexp literal\" mode).  Upon exit,\n *  'curr_tok' contains the token following the statement list terminator\n *  (EOF or closing brace).\n */\n\nDUK_LOCAL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_source_elem, duk_bool_t expect_eof, duk_bool_t regexp_after) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_ivalue res_alloc;\n\tduk_ivalue *res = &res_alloc;\n\n\t/* Setup state.  Initial ivalue is 'undefined'. */\n\n\tduk_require_stack(thr, DUK__PARSE_STATEMENTS_SLOTS);\n\n\t/* XXX: 'res' setup can be moved to function body level; in fact, two 'res'\n\t * intermediate values suffice for parsing of each function.  Nesting is needed\n\t * for nested functions (which may occur inside expressions).\n\t */\n\n\tduk_memzero(&res_alloc, sizeof(res_alloc));\n\tres->t = DUK_IVAL_PLAIN;\n\tres->x1.t = DUK_ISPEC_VALUE;\n\tres->x1.valstack_idx = duk_get_top(thr);\n\tres->x2.valstack_idx = res->x1.valstack_idx + 1;\n\tduk_push_undefined(thr);\n\tduk_push_undefined(thr);\n\n\t/* Parse statements until a closing token (EOF or '}') is found. */\n\n\tfor (;;) {\n\t\t/* Check whether statement list ends. */\n\n\t\tif (expect_eof) {\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_EOF) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* Check statement type based on the first token type.\n\t\t *\n\t\t * Note: expression parsing helpers expect 'curr_tok' to\n\t\t * contain the first token of the expression upon entry.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"TOKEN %ld (non-whitespace, non-comment)\", (long) comp_ctx->curr_token.t));\n\n\t\tduk__parse_stmt(comp_ctx, res, allow_source_elem);\n\t}\n\n\t/* RegExp is allowed / not allowed depending on context.  For function\n\t * declarations RegExp is allowed because it follows a function\n\t * declaration statement and may appear as part of the next statement.\n\t * For function expressions RegExp is not allowed, and it's possible\n\t * to do something like '(function () {} / 123)'.\n\t */\n\tif (regexp_after) {\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t}\n\tduk__advance(comp_ctx);\n\n\t/* Tear down state. */\n\n\tduk_pop_2(thr);\n}\n\n/*\n *  Declaration binding instantiation conceptually happens when calling a\n *  function; for us it essentially means that function prologue.  The\n *  conceptual process is described in E5 Section 10.5.\n *\n *  We need to keep track of all encountered identifiers to (1) create an\n *  identifier-to-register map (\"varmap\"); and (2) detect duplicate\n *  declarations.  Identifiers which are not bound to registers still need\n *  to be tracked for detecting duplicates.  Currently such identifiers\n *  are put into the varmap with a 'null' value, which is later cleaned up.\n *\n *  To support functions with a large number of variable and function\n *  declarations, registers are not allocated beyond a certain limit;\n *  after that limit, variables and functions need slow path access.\n *  Arguments are currently always register bound, which imposes a hard\n *  (and relatively small) argument count limit.\n *\n *  Some bindings in E5 are not configurable (= deletable) and almost all\n *  are mutable (writable).  Exceptions are:\n *\n *    - The 'arguments' binding, established only if no shadowing argument\n *      or function declaration exists.  We handle 'arguments' creation\n *      and binding through an explicit slow path environment record.\n *\n *    - The \"name\" binding for a named function expression.  This is also\n *      handled through an explicit slow path environment record.\n */\n\n/* XXX: add support for variables to not be register bound always, to\n * handle cases with a very large number of variables?\n */\n\nDUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ctx, duk_regconst_t *out_stmt_value_reg) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hstring *h_name;\n\tduk_bool_t configurable_bindings;\n\tduk_uarridx_t num_args;\n\tduk_uarridx_t num_decls;\n\tduk_regconst_t rc_name;\n\tduk_small_uint_t declvar_flags;\n\tduk_uarridx_t i;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\n\t/*\n\t *  Preliminaries\n\t */\n\n\tconfigurable_bindings = comp_ctx->curr_func.is_eval;\n\tDUK_DDD(DUK_DDDPRINT(\"configurable_bindings=%ld\", (long) configurable_bindings));\n\n\t/* varmap is already in comp_ctx->curr_func.varmap_idx */\n\n\t/*\n\t *  Function formal arguments, always bound to registers\n\t *  (there's no support for shuffling them now).\n\t */\n\n\tnum_args = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.argnames_idx);\n\tDUK_DDD(DUK_DDDPRINT(\"num_args=%ld\", (long) num_args));\n\t/* XXX: check num_args */\n\n\tfor (i = 0; i < num_args; i++) {\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.argnames_idx, i);\n\t\th_name = duk_known_hstring(thr, -1);\n\n\t\tif (comp_ctx->curr_func.is_strict) {\n\t\t\tif (duk__hstring_is_eval_or_arguments(comp_ctx, h_name)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"arg named 'eval' or 'arguments' in strict mode -> SyntaxError\"));\n\t\t\t\tgoto error_argname;\n\t\t\t}\n\t\t\tduk_dup_top(thr);\n\t\t\tif (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duplicate arg name in strict mode -> SyntaxError\"));\n\t\t\t\tgoto error_argname;\n\t\t\t}\n\n\t\t\t/* Ensure argument name is not a reserved word in current\n\t\t\t * (final) strictness.  Formal argument parsing may not\n\t\t\t * catch reserved names if strictness changes during\n\t\t\t * parsing.\n\t\t\t *\n\t\t\t * We only need to do this in strict mode because non-strict\n\t\t\t * keyword are always detected in formal argument parsing.\n\t\t\t */\n\n\t\t\tif (DUK_HSTRING_HAS_STRICT_RESERVED_WORD(h_name)) {\n\t\t\t\tgoto error_argname;\n\t\t\t}\n\t\t}\n\n\t\t/* overwrite any previous binding of the same name; the effect is\n\t\t * that last argument of a certain name wins.\n\t\t */\n\n\t\t/* only functions can have arguments */\n\t\tDUK_ASSERT(comp_ctx->curr_func.is_function);\n\t\tduk_push_uarridx(thr, i);  /* -> [ ... name index ] */\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx); /* -> [ ... ] */\n\n\t\t/* no code needs to be emitted, the regs already have values */\n\t}\n\n\t/* use temp_next for tracking register allocations */\n\tDUK__SETTEMP_CHECKMAX(comp_ctx, (duk_regconst_t) num_args);\n\n\t/*\n\t *  After arguments, allocate special registers (like shuffling temps)\n\t */\n\n\tif (out_stmt_value_reg) {\n\t\t*out_stmt_value_reg = DUK__ALLOCTEMP(comp_ctx);\n\t}\n\tif (comp_ctx->curr_func.needs_shuffle) {\n\t\tduk_regconst_t shuffle_base = DUK__ALLOCTEMPS(comp_ctx, 3);\n\t\tcomp_ctx->curr_func.shuffle1 = shuffle_base;\n\t\tcomp_ctx->curr_func.shuffle2 = shuffle_base + 1;\n\t\tcomp_ctx->curr_func.shuffle3 = shuffle_base + 2;\n\t\tDUK_D(DUK_DPRINT(\"shuffle registers needed by function, allocated: %ld %ld %ld\",\n\t\t                 (long) comp_ctx->curr_func.shuffle1,\n\t\t                 (long) comp_ctx->curr_func.shuffle2,\n\t\t                 (long) comp_ctx->curr_func.shuffle3));\n\t}\n\tif (comp_ctx->curr_func.temp_next > 0x100) {\n\t\tDUK_D(DUK_DPRINT(\"not enough 8-bit regs: temp_next=%ld\", (long) comp_ctx->curr_func.temp_next));\n\t\tgoto error_outofregs;\n\t}\n\n\t/*\n\t *  Function declarations\n\t */\n\n\tnum_decls = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.decls_idx);\n\tDUK_DDD(DUK_DDDPRINT(\"num_decls=%ld -> %!T\",\n\t                     (long) num_decls,\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.decls_idx)));\n\tfor (i = 0; i < num_decls; i += 2) {\n\t\tduk_int_t decl_type;\n\t\tduk_int_t fnum;\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i + 1);  /* decl type */\n\t\tdecl_type = duk_to_int(thr, -1);\n\t\tfnum = decl_type >> 8;  /* XXX: macros */\n\t\tdecl_type = decl_type & 0xff;\n\t\tduk_pop(thr);\n\n\t\tif (decl_type != DUK_DECL_TYPE_FUNC) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i);  /* decl name */\n\n\t\t/* XXX: spilling */\n\t\tif (comp_ctx->curr_func.is_function) {\n\t\t\tduk_regconst_t reg_bind;\n\t\t\tduk_dup_top(thr);\n\t\t\tif (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) {\n\t\t\t\t/* shadowed; update value */\n\t\t\t\tduk_dup_top(thr);\n\t\t\t\tduk_get_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\t\t\treg_bind = duk_to_int(thr, -1);  /* [ ... name reg_bind ] */\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_CLOSURE,\n\t\t\t\t               reg_bind,\n\t\t\t\t               (duk_regconst_t) fnum);\n\t\t\t} else {\n\t\t\t\t/* function: always register bound */\n\t\t\t\treg_bind = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_CLOSURE,\n\t\t\t\t               reg_bind,\n\t\t\t\t               (duk_regconst_t) fnum);\n\t\t\t\tduk_push_int(thr, (duk_int_t) reg_bind);\n\t\t\t}\n\t\t} else {\n\t\t\t/* Function declaration for global/eval code is emitted even\n\t\t\t * for duplicates, because of E5 Section 10.5, step 5.e of\n\t\t\t * E5.1 (special behavior for variable bound to global object).\n\t\t\t *\n\t\t\t * DECLVAR will not re-declare a variable as such, but will\n\t\t\t * update the binding value.\n\t\t\t */\n\n\t\t\tduk_regconst_t reg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\tduk_dup_top(thr);\n\t\t\trc_name = duk__getconst(comp_ctx);\n\t\t\tduk_push_null(thr);\n\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CLOSURE,\n\t\t\t               reg_temp,\n\t\t\t               (duk_regconst_t) fnum);\n\n\t\t\tdeclvar_flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t                DUK_PROPDESC_FLAG_ENUMERABLE |\n\t\t\t                DUK_BC_DECLVAR_FLAG_FUNC_DECL;\n\n\t\t\tif (configurable_bindings) {\n\t\t\t\tdeclvar_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t}\n\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_DECLVAR | DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                (duk_regconst_t) declvar_flags /*flags*/,\n\t\t\t                rc_name /*name*/,\n\t\t\t                reg_temp /*value*/);\n\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp);  /* forget temp */\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"function declaration to varmap: %!T -> %!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n#if defined(DUK_USE_FASTINT)\n\t\tDUK_ASSERT(DUK_TVAL_IS_NULL(duk_get_tval(thr, -1)) || DUK_TVAL_IS_FASTINT(duk_get_tval(thr, -1)));\n#endif\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);  /* [ ... name reg/null ] -> [ ... ] */\n\t}\n\n\t/*\n\t *  'arguments' binding is special; if a shadowing argument or\n\t *  function declaration exists, an arguments object will\n\t *  definitely not be needed, regardless of whether the identifier\n\t *  'arguments' is referenced inside the function body.\n\t */\n\n\tif (duk_has_prop_stridx(thr, comp_ctx->curr_func.varmap_idx, DUK_STRIDX_LC_ARGUMENTS)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"'arguments' is shadowed by argument or function declaration \"\n\t\t                     \"-> arguments object creation can be skipped\"));\n\t\tcomp_ctx->curr_func.is_arguments_shadowed = 1;\n\t}\n\n\t/*\n\t *  Variable declarations.\n\t *\n\t *  Unlike function declarations, variable declaration values don't get\n\t *  assigned on entry.  If a binding of the same name already exists, just\n\t *  ignore it silently.\n\t */\n\n\tfor (i = 0; i < num_decls; i += 2) {\n\t\tduk_int_t decl_type;\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i + 1);  /* decl type */\n\t\tdecl_type = duk_to_int(thr, -1);\n\t\tdecl_type = decl_type & 0xff;\n\t\tduk_pop(thr);\n\n\t\tif (decl_type != DUK_DECL_TYPE_VAR) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i);  /* decl name */\n\n\t\tif (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) {\n\t\t\t/* shadowed, ignore */\n\t\t} else {\n\t\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i);  /* decl name */\n\t\t\th_name = duk_known_hstring(thr, -1);\n\n\t\t\tif (h_name == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr) &&\n\t\t\t    !comp_ctx->curr_func.is_arguments_shadowed) {\n\t\t\t\t/* E5 Section steps 7-8 */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"'arguments' not shadowed by a function declaration, \"\n\t\t\t\t                     \"but appears as a variable declaration -> treat as \"\n\t\t\t\t                     \"a no-op for variable declaration purposes\"));\n\t\t\t\tduk_pop(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* XXX: spilling */\n\t\t\tif (comp_ctx->curr_func.is_function) {\n\t\t\t\tduk_regconst_t reg_bind = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\t/* no need to init reg, it will be undefined on entry */\n\t\t\t\tduk_push_int(thr, (duk_int_t) reg_bind);\n\t\t\t} else {\n\t\t\t\tduk_dup_top(thr);\n\t\t\t\trc_name = duk__getconst(comp_ctx);\n\t\t\t\tduk_push_null(thr);\n\n\t\t\t\tdeclvar_flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t                        DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t\tif (configurable_bindings) {\n\t\t\t\t\tdeclvar_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t\t}\n\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                DUK_OP_DECLVAR | DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                (duk_regconst_t) declvar_flags /*flags*/,\n\t\t\t\t                rc_name /*name*/,\n\t\t\t\t                0 /*value*/);\n\t\t\t}\n\n\t\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);  /* [ ... name reg/null ] -> [ ... ] */\n\t\t}\n\t}\n\n\t/*\n\t *  Wrap up\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"varmap: %!T, is_arguments_shadowed=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx),\n\t                     (long) comp_ctx->curr_func.is_arguments_shadowed));\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n\n error_argname:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_ARG_NAME);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Parse a function-body-like expression (FunctionBody or Program\n *  in E5 grammar) using a two-pass parse.  The productions appear\n *  in the following contexts:\n *\n *    - function expression\n *    - function statement\n *    - function declaration\n *    - getter in object literal\n *    - setter in object literal\n *    - global code\n *    - eval code\n *    - Function constructor body\n *\n *  This function only parses the statement list of the body; the argument\n *  list and possible function name must be initialized by the caller.\n *  For instance, for Function constructor, the argument names are originally\n *  on the value stack.  The parsing of statements ends either at an EOF or\n *  a closing brace; this is controlled by an input flag.\n *\n *  Note that there are many differences affecting parsing and even code\n *  generation:\n *\n *    - Global and eval code have an implicit return value generated\n *      by the last statement; function code does not\n *\n *    - Global code, eval code, and Function constructor body end in\n *      an EOF, other bodies in a closing brace ('}')\n *\n *  Upon entry, 'curr_tok' is ignored and the function will pull in the\n *  first token on its own.  Upon exit, 'curr_tok' is the terminating\n *  token (EOF or closing brace).\n */\n\nDUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expect_eof, duk_bool_t implicit_return_value, duk_bool_t regexp_after, duk_small_int_t expect_token) {\n\tduk_compiler_func *func;\n\tduk_hthread *thr;\n\tduk_regconst_t reg_stmt_value = -1;\n\tduk_lexer_point lex_pt;\n\tduk_regconst_t temp_first;\n\tduk_small_int_t compile_round = 1;\n\n\tDUK_ASSERT(comp_ctx != NULL);\n\n\tthr = comp_ctx->thr;\n\tDUK_ASSERT(thr != NULL);\n\n\tfunc = &comp_ctx->curr_func;\n\tDUK_ASSERT(func != NULL);\n\n\tDUK__RECURSION_INCREASE(comp_ctx, thr);\n\n\tduk_require_stack(thr, DUK__FUNCTION_BODY_REQUIRE_SLOTS);\n\n\t/*\n\t *  Store lexer position for a later rewind\n\t */\n\n\tDUK_LEXER_GETPOINT(&comp_ctx->lex, &lex_pt);\n\n\t/*\n\t *  Program code (global and eval code) has an implicit return value\n\t *  from the last statement value (e.g. eval(\"1; 2+3;\") returns 3).\n\t *  This is not the case with functions.  If implicit statement return\n\t *  value is requested, all statements are coerced to a register\n\t *  allocated here, and used in the implicit return statement below.\n\t */\n\n\t/* XXX: this is pointless here because pass 1 is throw-away */\n\tif (implicit_return_value) {\n\t\treg_stmt_value = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t/* If an implicit return value is needed by caller, it must be\n\t\t * initialized to 'undefined' because we don't know whether any\n\t\t * non-empty (where \"empty\" is a continuation type, and different\n\t\t * from an empty statement) statements will be executed.\n\t\t *\n\t\t * However, since 1st pass is a throwaway one, no need to emit\n\t\t * it here.\n\t\t */\n#if 0\n\t\tduk__emit_bc(comp_ctx,\n\t\t             DUK_OP_LDUNDEF,\n\t\t             0);\n#endif\n\t}\n\n\t/*\n\t *  First pass.\n\t *\n\t *  Gather variable/function declarations needed for second pass.\n\t *  Code generated is dummy and discarded.\n\t */\n\n\tfunc->in_directive_prologue = 1;\n\tfunc->in_scanning = 1;\n\tfunc->may_direct_eval = 0;\n\tfunc->id_access_arguments = 0;\n\tfunc->id_access_slow = 0;\n\tfunc->id_access_slow_own = 0;\n\tfunc->reg_stmt_value = reg_stmt_value;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tfunc->min_line = DUK_INT_MAX;\n\tfunc->max_line = 0;\n#endif\n\n\t/* duk__parse_stmts() expects curr_tok to be set; parse in \"allow\n\t * regexp literal\" mode with current strictness.\n\t */\n\tif (expect_token >= 0) {\n\t\t/* Eating a left curly; regexp mode is allowed by left curly\n\t\t * based on duk__token_lbp[] automatically.\n\t\t */\n\t\tDUK_ASSERT(expect_token == DUK_TOK_LCURLY);\n\t\tduk__update_lineinfo_currtoken(comp_ctx);\n\t\tduk__advance_expect(comp_ctx, expect_token);\n\t} else {\n\t\t/* Need to set curr_token.t because lexing regexp mode depends on current\n\t\t * token type.  Zero value causes \"allow regexp\" mode.\n\t\t */\n\t\tcomp_ctx->curr_token.t = 0;\n\t\tduk__advance(comp_ctx);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin 1st pass\"));\n\tduk__parse_stmts(comp_ctx,\n\t                 1,             /* allow source elements */\n\t                 expect_eof,    /* expect EOF instead of } */\n\t                 regexp_after); /* regexp after */\n\tDUK_DDD(DUK_DDDPRINT(\"end 1st pass\"));\n\n\t/*\n\t *  Second (and possibly third) pass.\n\t *\n\t *  Generate actual code.  In most cases the need for shuffle\n\t *  registers is detected during pass 1, but in some corner cases\n\t *  we'll only detect it during pass 2 and a third pass is then\n\t *  needed (see GH-115).\n\t */\n\n\tfor (;;) {\n\t\tduk_bool_t needs_shuffle_before = comp_ctx->curr_func.needs_shuffle;\n\t\tcompile_round++;\n\n\t\t/*\n\t\t *  Rewind lexer.\n\t\t *\n\t\t *  duk__parse_stmts() expects curr_tok to be set; parse in \"allow regexp\n\t\t *  literal\" mode with current strictness.\n\t\t *\n\t\t *  curr_token line number info should be initialized for pass 2 before\n\t\t *  generating prologue, to ensure prologue bytecode gets nice line numbers.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"rewind lexer\"));\n\t\tDUK_LEXER_SETPOINT(&comp_ctx->lex, &lex_pt);\n\t\tcomp_ctx->curr_token.t = 0;  /* this is needed for regexp mode */\n\t\tcomp_ctx->curr_token.start_line = 0;  /* needed for line number tracking (becomes prev_token.start_line) */\n\t\tduk__advance(comp_ctx);\n\n\t\t/*\n\t\t *  Reset function state and perform register allocation, which creates\n\t\t *  'varmap' for second pass.  Function prologue for variable declarations,\n\t\t *  binding value initializations etc is emitted as a by-product.\n\t\t *\n\t\t *  Strict mode restrictions for duplicate and invalid argument\n\t\t *  names are checked here now that we know whether the function\n\t\t *  is actually strict.  See: test-dev-strict-mode-boundary.js.\n\t\t *\n\t\t *  Inner functions are compiled during pass 1 and are not reset.\n\t\t */\n\n\t\tduk__reset_func_for_pass2(comp_ctx);\n\t\tfunc->in_directive_prologue = 1;\n\t\tfunc->in_scanning = 0;\n\n\t\t/* must be able to emit code, alloc consts, etc. */\n\n\t\tduk__init_varmap_and_prologue_for_pass2(comp_ctx,\n\t\t                                        (implicit_return_value ? &reg_stmt_value : NULL));\n\t\tfunc->reg_stmt_value = reg_stmt_value;\n\n\t\ttemp_first = DUK__GETTEMP(comp_ctx);\n\n\t\tfunc->temp_first = temp_first;\n\t\tfunc->temp_next = temp_first;\n\t\tfunc->stmt_next = 0;\n\t\tfunc->label_next = 0;\n\n\t\t/* XXX: init or assert catch depth etc -- all values */\n\t\tfunc->id_access_arguments = 0;\n\t\tfunc->id_access_slow = 0;\n\t\tfunc->id_access_slow_own = 0;\n\n\t\t/*\n\t\t *  Check function name validity now that we know strictness.\n\t\t *  This only applies to function declarations and expressions,\n\t\t *  not setter/getter name.\n\t\t *\n\t\t *  See: test-dev-strict-mode-boundary.js\n\t\t */\n\n\t\tif (func->is_function && !func->is_setget && func->h_name != NULL) {\n\t\t\tif (func->is_strict) {\n\t\t\t\tif (duk__hstring_is_eval_or_arguments(comp_ctx, func->h_name)) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"func name is 'eval' or 'arguments' in strict mode\"));\n\t\t\t\t\tgoto error_funcname;\n\t\t\t\t}\n\t\t\t\tif (DUK_HSTRING_HAS_STRICT_RESERVED_WORD(func->h_name)) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"func name is a reserved word in strict mode\"));\n\t\t\t\t\tgoto error_funcname;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (DUK_HSTRING_HAS_RESERVED_WORD(func->h_name) &&\n\t\t\t\t    !DUK_HSTRING_HAS_STRICT_RESERVED_WORD(func->h_name)) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"func name is a reserved word in non-strict mode\"));\n\t\t\t\t\tgoto error_funcname;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t *  Second pass parsing.\n\t\t */\n\n\t\tif (implicit_return_value) {\n\t\t\t/* Default implicit return value. */\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_LDUNDEF,\n\t\t\t             0);\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"begin 2nd pass\"));\n\t\tduk__parse_stmts(comp_ctx,\n\t\t                 1,             /* allow source elements */\n\t\t                 expect_eof,    /* expect EOF instead of } */\n\t\t                 regexp_after); /* regexp after */\n\t\tDUK_DDD(DUK_DDDPRINT(\"end 2nd pass\"));\n\n\t\tduk__update_lineinfo_currtoken(comp_ctx);\n\n\t\tif (needs_shuffle_before == comp_ctx->curr_func.needs_shuffle) {\n\t\t\t/* Shuffle decision not changed. */\n\t\t\tbreak;\n\t\t}\n\t\tif (compile_round >= 3) {\n\t\t\t/* Should never happen but avoid infinite loop just in case. */\n\t\t\tDUK_D(DUK_DPRINT(\"more than 3 compile passes needed, should never happen\"));\n\t\t\tDUK_ERROR_INTERNAL(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tDUK_D(DUK_DPRINT(\"need additional round to compile function, round now %d\", (int) compile_round));\n\t}\n\n\t/*\n\t *  Emit a final RETURN.\n\t *\n\t *  It would be nice to avoid emitting an unnecessary \"return\" opcode\n\t *  if the current PC is not reachable.  However, this cannot be reliably\n\t *  detected; even if the previous instruction is an unconditional jump,\n\t *  there may be a previous jump which jumps to current PC (which is the\n\t *  case for iteration and conditional statements, for instance).\n\t */\n\n\t/* XXX: request a \"last statement is terminal\" from duk__parse_stmt() and duk__parse_stmts();\n\t * we could avoid the last RETURN if we could ensure there is no way to get here\n\t * (directly or via a jump)\n\t */\n\n\tDUK_ASSERT(comp_ctx->curr_func.catch_depth == 0);\n\tif (reg_stmt_value >= 0) {\n\t\tDUK_ASSERT(DUK__ISREG(reg_stmt_value));\n\t\tduk__emit_bc(comp_ctx, DUK_OP_RETREG, reg_stmt_value /*reg*/);\n\t} else {\n\t\tduk__emit_op_only(comp_ctx, DUK_OP_RETUNDEF);\n\t}\n\n\t/*\n\t *  Peephole optimize JUMP chains.\n\t */\n\n\tduk__peephole_optimize_bytecode(comp_ctx);\n\n\t/*\n\t *  comp_ctx->curr_func is now ready to be converted into an actual\n\t *  function template.\n\t */\n\n\tDUK__RECURSION_DECREASE(comp_ctx, thr);\n\treturn;\n\n error_funcname:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_FUNC_NAME);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Parse a function-like expression:\n *\n *    - function expression\n *    - function declaration\n *    - function statement (non-standard)\n *    - setter/getter\n *\n *  Adds the function to comp_ctx->curr_func function table and returns the\n *  function number.\n *\n *  On entry, curr_token points to:\n *\n *    - the token after 'function' for function expression/declaration/statement\n *    - the token after 'set' or 'get' for setter/getter\n */\n\n/* Parse formals. */\nDUK_LOCAL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t first = 1;\n\tduk_uarridx_t n;\n\n\tfor (;;) {\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RPAREN) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (first) {\n\t\t\t/* no comma */\n\t\t\tfirst = 0;\n\t\t} else {\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COMMA);\n\t\t}\n\n\t\t/* Note: when parsing a formal list in non-strict context, e.g.\n\t\t * \"implements\" is parsed as an identifier.  When the function is\n\t\t * later detected to be strict, the argument list must be rechecked\n\t\t * against a larger set of reserved words (that of strict mode).\n\t\t * This is handled by duk__parse_func_body().  Here we recognize\n\t\t * whatever tokens are considered reserved in current strictness\n\t\t * (which is not always enough).\n\t\t */\n\n\t\tif (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EXPECTED_IDENTIFIER);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_IDENTIFIER);\n\t\tDUK_ASSERT(comp_ctx->curr_token.str1 != NULL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"formal argument: %!O\",\n\t\t                     (duk_heaphdr *) comp_ctx->curr_token.str1));\n\n\t\t/* XXX: append primitive */\n\t\tduk_push_hstring(thr, comp_ctx->curr_token.str1);\n\t\tn = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.argnames_idx);\n\t\tduk_put_prop_index(thr, comp_ctx->curr_func.argnames_idx, n);\n\n\t\tduk__advance(comp_ctx);  /* eat identifier */\n\t}\n}\n\n/* Parse a function-like expression, assuming that 'comp_ctx->curr_func' is\n * correctly set up.  Assumes that curr_token is just after 'function' (or\n * 'set'/'get' etc).\n */\nDUK_LOCAL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_token *tok;\n\tduk_bool_t no_advance;\n\n\tDUK_ASSERT(comp_ctx->curr_func.num_formals == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_function == 1);\n\tDUK_ASSERT(comp_ctx->curr_func.is_eval == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_global == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_setget == ((flags & DUK__FUNC_FLAG_GETSET) != 0));\n\n\tduk__update_lineinfo_currtoken(comp_ctx);\n\n\t/*\n\t *  Function name (if any)\n\t *\n\t *  We don't check for prohibited names here, because we don't\n\t *  yet know whether the function will be strict.  Function body\n\t *  parsing handles this retroactively.\n\t *\n\t *  For function expressions and declarations function name must\n\t *  be an Identifer (excludes reserved words).  For setter/getter\n\t *  it is a PropertyName which allows reserved words and also\n\t *  strings and numbers (e.g. \"{ get 1() { ... } }\").\n\t *\n\t *  Function parsing may start either from prev_token or curr_token\n\t *  (object literal method definition uses prev_token for example).\n\t *  This is dealt with for the initial token.\n\t */\n\n\tno_advance = (flags & DUK__FUNC_FLAG_USE_PREVTOKEN);\n\tif (no_advance) {\n\t\ttok = &comp_ctx->prev_token;\n\t} else {\n\t\ttok = &comp_ctx->curr_token;\n\t}\n\n\tif (flags & DUK__FUNC_FLAG_GETSET) {\n\t\t/* PropertyName -> IdentifierName | StringLiteral | NumericLiteral */\n\t\tif (tok->t_nores == DUK_TOK_IDENTIFIER || tok->t == DUK_TOK_STRING) {\n\t\t\tduk_push_hstring(thr, tok->str1);       /* keep in valstack */\n\t\t} else if (tok->t == DUK_TOK_NUMBER) {\n\t\t\tduk_push_number(thr, tok->num);\n\t\t\tduk_to_string(thr, -1);\n\t\t} else {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_GETSET_NAME);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tcomp_ctx->curr_func.h_name = duk_known_hstring(thr, -1);  /* borrowed reference */\n\t} else {\n\t\t/* Function name is an Identifier (not IdentifierName), but we get\n\t\t * the raw name (not recognizing keywords) here and perform the name\n\t\t * checks only after pass 1.\n\t\t */\n\t\tif (tok->t_nores == DUK_TOK_IDENTIFIER) {\n\t\t\tduk_push_hstring(thr, tok->str1);       /* keep in valstack */\n\t\t\tcomp_ctx->curr_func.h_name = duk_known_hstring(thr, -1);  /* borrowed reference */\n\t\t} else {\n\t\t\t/* valstack will be unbalanced, which is OK */\n\t\t\tDUK_ASSERT((flags & DUK__FUNC_FLAG_GETSET) == 0);\n\t\t\tDUK_ASSERT(comp_ctx->curr_func.h_name == NULL);\n\t\t\tno_advance = 1;\n\t\t\tif (flags & DUK__FUNC_FLAG_DECL) {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_FUNC_NAME_REQUIRED);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t}\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"function name: %!O\",\n\t                   (duk_heaphdr *) comp_ctx->curr_func.h_name));\n\n\tif (!no_advance) {\n\t\tduk__advance(comp_ctx);\n\t}\n\n\t/*\n\t *  Formal argument list\n\t *\n\t *  We don't check for prohibited names or for duplicate argument\n\t *  names here, becase we don't yet know whether the function will\n\t *  be strict.  Function body parsing handles this retroactively.\n\t */\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\tduk__parse_func_formals(comp_ctx);\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RPAREN);\n\tduk__advance(comp_ctx);\n\n\t/*\n\t *  Parse function body\n\t */\n\n\tduk__parse_func_body(comp_ctx,\n\t                     0,   /* expect_eof */\n\t                     0,   /* implicit_return_value */\n\t                     flags & DUK__FUNC_FLAG_DECL, /* regexp_after */\n\t                     DUK_TOK_LCURLY);  /* expect_token */\n\n\t/*\n\t *  Convert duk_compiler_func to a function template and add it\n\t *  to the parent function table.\n\t */\n\n\tduk__convert_to_func_template(comp_ctx);  /* -> [ ... func ] */\n}\n\n/* Parse an inner function, adding the function template to the current function's\n * function table.  Return a function number to be used by the outer function.\n *\n * Avoiding O(depth^2) inner function parsing is handled here.  On the first pass,\n * compile and register the function normally into the 'funcs' array, also recording\n * a lexer point (offset/line) to the closing brace of the function.  On the second\n * pass, skip the function and return the same 'fnum' as on the first pass by using\n * a running counter.\n *\n * An unfortunate side effect of this is that when parsing the inner function, almost\n * nothing is known of the outer function, i.e. the inner function's scope.  We don't\n * need that information at the moment, but it would allow some optimizations if it\n * were used.\n */\nDUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_compiler_func old_func;\n\tduk_idx_t entry_top;\n\tduk_int_t fnum;\n\n\t/*\n\t *  On second pass, skip the function.\n\t */\n\n\tif (!comp_ctx->curr_func.in_scanning) {\n\t\tduk_lexer_point lex_pt;\n\n\t\tfnum = comp_ctx->curr_func.fnum_next++;\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 1));\n\t\tlex_pt.offset = (duk_size_t) duk_to_uint(thr, -1);\n\t\tduk_pop(thr);\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 2));\n\t\tlex_pt.line = duk_to_int(thr, -1);\n\t\tduk_pop(thr);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"second pass of an inner func, skip the function, reparse closing brace; lex offset=%ld, line=%ld\",\n\t\t                     (long) lex_pt.offset, (long) lex_pt.line));\n\n\t\tDUK_LEXER_SETPOINT(&comp_ctx->lex, &lex_pt);\n\t\tcomp_ctx->curr_token.t = 0;  /* this is needed for regexp mode */\n\t\tcomp_ctx->curr_token.start_line = 0;  /* needed for line number tracking (becomes prev_token.start_line) */\n\t\tduk__advance(comp_ctx);\n\n\t\t/* RegExp is not allowed after a function expression, e.g. in\n\t\t * (function () {} / 123).  A RegExp *is* allowed after a\n\t\t * function declaration!\n\t\t */\n\t\tif (flags & DUK__FUNC_FLAG_DECL) {\n\t\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t\t}\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RCURLY);\n\n\t\treturn fnum;\n\t}\n\n\t/*\n\t *  On first pass, perform actual parsing.  Remember valstack top on entry\n\t *  to restore it later, and switch to using a new function in comp_ctx.\n\t */\n\n\tentry_top = duk_get_top(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"before func: entry_top=%ld, curr_tok.start_offset=%ld\",\n\t                     (long) entry_top, (long) comp_ctx->curr_token.start_offset));\n\n\tduk_memcpy(&old_func, &comp_ctx->curr_func, sizeof(duk_compiler_func));\n\n\tduk_memzero(&comp_ctx->curr_func, sizeof(duk_compiler_func));\n\tduk__init_func_valstack_slots(comp_ctx);\n\tDUK_ASSERT(comp_ctx->curr_func.num_formals == 0);\n\n\t/* inherit initial strictness from parent */\n\tcomp_ctx->curr_func.is_strict = old_func.is_strict;\n\n\t/* XXX: It might be better to just store the flags into the curr_func\n\t * struct and use them as is without this flag interpretation step\n\t * here.\n\t */\n\tDUK_ASSERT(comp_ctx->curr_func.is_notail == 0);\n\tcomp_ctx->curr_func.is_function = 1;\n\tDUK_ASSERT(comp_ctx->curr_func.is_eval == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_global == 0);\n\tcomp_ctx->curr_func.is_setget = ((flags & DUK__FUNC_FLAG_GETSET) != 0);\n\tcomp_ctx->curr_func.is_namebinding = !(flags & (DUK__FUNC_FLAG_GETSET |\n\t                                                DUK__FUNC_FLAG_METDEF |\n\t                                                DUK__FUNC_FLAG_DECL));  /* no name binding for: declarations, objlit getset, objlit method def */\n\tcomp_ctx->curr_func.is_constructable = !(flags & (DUK__FUNC_FLAG_GETSET |\n\t                                                  DUK__FUNC_FLAG_METDEF));  /* not constructable: objlit getset, objlit method def */\n\n\t/*\n\t *  Parse inner function\n\t */\n\n\tduk__parse_func_like_raw(comp_ctx, flags);  /* pushes function template */\n\n\t/* prev_token.start_offset points to the closing brace here; when skipping\n\t * we're going to reparse the closing brace to ensure semicolon insertion\n\t * etc work as expected.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"after func: prev_tok.start_offset=%ld, curr_tok.start_offset=%ld\",\n\t                     (long) comp_ctx->prev_token.start_offset, (long) comp_ctx->curr_token.start_offset));\n\tDUK_ASSERT(comp_ctx->lex.input[comp_ctx->prev_token.start_offset] == (duk_uint8_t) DUK_ASC_RCURLY);\n\n\t/* XXX: append primitive */\n\tDUK_ASSERT(duk_get_length(thr, old_func.funcs_idx) == (duk_size_t) (old_func.fnum_next * 3));\n\tfnum = old_func.fnum_next++;\n\n\tif (fnum > DUK__MAX_FUNCS) {\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_FUNC_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* array writes autoincrement length */\n\t(void) duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3));\n\tduk_push_size_t(thr, comp_ctx->prev_token.start_offset);\n\t(void) duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 1));\n\tduk_push_int(thr, comp_ctx->prev_token.start_line);\n\t(void) duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 2));\n\n\t/*\n\t *  Cleanup: restore original function, restore valstack state.\n\t *\n\t *  Function declaration handling needs the function name to be pushed\n\t *  on the value stack.\n\t */\n\n\tif (flags & DUK__FUNC_FLAG_PUSHNAME_PASS1) {\n\t\tDUK_ASSERT(comp_ctx->curr_func.h_name != NULL);\n\t\tduk_push_hstring(thr, comp_ctx->curr_func.h_name);\n\t\tduk_replace(thr, entry_top);\n\t\tduk_set_top(thr, entry_top + 1);\n\t} else {\n\t\tduk_set_top(thr, entry_top);\n\t}\n\tduk_memcpy((void *) &comp_ctx->curr_func, (void *) &old_func, sizeof(duk_compiler_func));\n\n\treturn fnum;\n}\n\n/*\n *  Compile input string into an executable function template without\n *  arguments.\n *\n *  The string is parsed as the \"Program\" production of ECMAScript E5.\n *  Compilation context can be either global code or eval code (see E5\n *  Sections 14 and 15.1.2.1).\n *\n *  Input stack:  [ ... filename ]\n *  Output stack: [ ... func_template ]\n */\n\n/* XXX: source code property */\n\nDUK_LOCAL duk_ret_t duk__js_compile_raw(duk_hthread *thr, void *udata) {\n\tduk_hstring *h_filename;\n\tduk__compiler_stkstate *comp_stk;\n\tduk_compiler_ctx *comp_ctx;\n\tduk_lexer_point *lex_pt;\n\tduk_compiler_func *func;\n\tduk_idx_t entry_top;\n\tduk_bool_t is_strict;\n\tduk_bool_t is_eval;\n\tduk_bool_t is_funcexpr;\n\tduk_small_uint_t flags;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(udata != NULL);\n\n\t/*\n\t *  Arguments check\n\t */\n\n\tentry_top = duk_get_top(thr);\n\tDUK_ASSERT(entry_top >= 1);\n\n\tcomp_stk = (duk__compiler_stkstate *) udata;\n\tcomp_ctx = &comp_stk->comp_ctx_alloc;\n\tlex_pt = &comp_stk->lex_pt_alloc;\n\tDUK_ASSERT(comp_ctx != NULL);\n\tDUK_ASSERT(lex_pt != NULL);\n\n\tflags = comp_stk->flags;\n\tis_eval = (flags & DUK_COMPILE_EVAL ? 1 : 0);\n\tis_strict = (flags & DUK_COMPILE_STRICT ? 1 : 0);\n\tis_funcexpr = (flags & DUK_COMPILE_FUNCEXPR ? 1 : 0);\n\n\th_filename = duk_get_hstring(thr, -1);  /* may be undefined */\n\n\t/*\n\t *  Init compiler and lexer contexts\n\t */\n\n\tfunc = &comp_ctx->curr_func;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tcomp_ctx->thr = NULL;\n\tcomp_ctx->h_filename = NULL;\n\tcomp_ctx->prev_token.str1 = NULL;\n\tcomp_ctx->prev_token.str2 = NULL;\n\tcomp_ctx->curr_token.str1 = NULL;\n\tcomp_ctx->curr_token.str2 = NULL;\n#endif\n\n\tduk_require_stack(thr, DUK__COMPILE_ENTRY_SLOTS);\n\n\tduk_push_dynamic_buffer(thr, 0);       /* entry_top + 0 */\n\tduk_push_undefined(thr);               /* entry_top + 1 */\n\tduk_push_undefined(thr);               /* entry_top + 2 */\n\tduk_push_undefined(thr);               /* entry_top + 3 */\n\tduk_push_undefined(thr);               /* entry_top + 4 */\n\n\tcomp_ctx->thr = thr;\n\tcomp_ctx->h_filename = h_filename;\n\tcomp_ctx->tok11_idx = entry_top + 1;\n\tcomp_ctx->tok12_idx = entry_top + 2;\n\tcomp_ctx->tok21_idx = entry_top + 3;\n\tcomp_ctx->tok22_idx = entry_top + 4;\n\tcomp_ctx->recursion_limit = DUK_USE_COMPILER_RECLIMIT;\n\n\t/* comp_ctx->lex has been pre-initialized by caller: it has been\n\t * zeroed and input/input_length has been set.\n\t */\n\tcomp_ctx->lex.thr = thr;\n\t/* comp_ctx->lex.input and comp_ctx->lex.input_length filled by caller */\n\tcomp_ctx->lex.slot1_idx = comp_ctx->tok11_idx;\n\tcomp_ctx->lex.slot2_idx = comp_ctx->tok12_idx;\n\tcomp_ctx->lex.buf_idx = entry_top + 0;\n\tcomp_ctx->lex.buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, entry_top + 0);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(comp_ctx->lex.buf) && !DUK_HBUFFER_HAS_EXTERNAL(comp_ctx->lex.buf));\n\tcomp_ctx->lex.token_limit = DUK_COMPILER_TOKEN_LIMIT;\n\n\tlex_pt->offset = 0;\n\tlex_pt->line = 1;\n\tDUK_LEXER_SETPOINT(&comp_ctx->lex, lex_pt);    /* fills window */\n\tcomp_ctx->curr_token.start_line = 0;  /* needed for line number tracking (becomes prev_token.start_line) */\n\n\t/*\n\t *  Initialize function state for a zero-argument function\n\t */\n\n\tduk__init_func_valstack_slots(comp_ctx);\n\tDUK_ASSERT(func->num_formals == 0);\n\n\tif (is_funcexpr) {\n\t\t/* Name will be filled from function expression, not by caller.\n\t\t * This case is used by Function constructor and duk_compile()\n\t\t * API with the DUK_COMPILE_FUNCTION option.\n\t\t */\n\t\tDUK_ASSERT(func->h_name == NULL);\n\t} else {\n\t\tduk_push_hstring_stridx(thr, (is_eval ? DUK_STRIDX_EVAL :\n\t\t                                        DUK_STRIDX_GLOBAL));\n\t\tfunc->h_name = duk_get_hstring(thr, -1);\n\t}\n\n\t/*\n\t *  Parse a function body or a function-like expression, depending\n\t *  on flags.\n\t */\n\n\tDUK_ASSERT(func->is_setget == 0);\n\tfunc->is_strict = (duk_uint8_t) is_strict;\n\tDUK_ASSERT(func->is_notail == 0);\n\n\tif (is_funcexpr) {\n\t\tfunc->is_function = 1;\n\t\tDUK_ASSERT(func->is_eval == 0);\n\t\tDUK_ASSERT(func->is_global == 0);\n\t\tfunc->is_namebinding = 1;\n\t\tfunc->is_constructable = 1;\n\n\t\tduk__advance(comp_ctx);  /* init 'curr_token' */\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_FUNCTION);\n\t\t(void) duk__parse_func_like_raw(comp_ctx, 0 /*flags*/);\n\t} else {\n\t\tDUK_ASSERT(func->is_function == 0);\n\t\tDUK_ASSERT(is_eval == 0 || is_eval == 1);\n\t\tfunc->is_eval = (duk_uint8_t) is_eval;\n\t\tfunc->is_global = (duk_uint8_t) !is_eval;\n\t\tDUK_ASSERT(func->is_namebinding == 0);\n\t\tDUK_ASSERT(func->is_constructable == 0);\n\n\t\tduk__parse_func_body(comp_ctx,\n\t\t                     1,             /* expect_eof */\n\t\t                     1,             /* implicit_return_value */\n\t\t                     1,             /* regexp_after (does not matter) */\n\t\t                     -1);           /* expect_token */\n\t}\n\n\t/*\n\t *  Convert duk_compiler_func to a function template\n\t */\n\n\tduk__convert_to_func_template(comp_ctx);\n\n\t/*\n\t *  Wrapping duk_safe_call() will mangle the stack, just return stack top\n\t */\n\n\t/* [ ... filename (temps) func ] */\n\n\treturn 1;\n}\n\nDUK_INTERNAL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer, duk_size_t src_length, duk_small_uint_t flags) {\n\tduk__compiler_stkstate comp_stk;\n\tduk_compiler_ctx *prev_ctx;\n\tduk_ret_t safe_rc;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(src_buffer != NULL);\n\n\t/* preinitialize lexer state partially */\n\tduk_memzero(&comp_stk, sizeof(comp_stk));\n\tcomp_stk.flags = flags;\n\tDUK_LEXER_INITCTX(&comp_stk.comp_ctx_alloc.lex);\n\tcomp_stk.comp_ctx_alloc.lex.input = src_buffer;\n\tcomp_stk.comp_ctx_alloc.lex.input_length = src_length;\n\tcomp_stk.comp_ctx_alloc.lex.flags = flags;  /* Forward flags directly for now. */\n\n\t/* [ ... filename ] */\n\n\tprev_ctx = thr->compile_ctx;\n\tthr->compile_ctx = &comp_stk.comp_ctx_alloc;  /* for duk_error_augment.c */\n\tsafe_rc = duk_safe_call(thr, duk__js_compile_raw, (void *) &comp_stk /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\tthr->compile_ctx = prev_ctx;  /* must restore reliably before returning */\n\n\tif (safe_rc != DUK_EXEC_SUCCESS) {\n\t\tDUK_D(DUK_DPRINT(\"compilation failed: %!T\", duk_get_tval(thr, -1)));\n\t\t(void) duk_throw(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* [ ... template ] */\n}\n\n/* automatic undefs */\n#undef DUK__ALLOCTEMP\n#undef DUK__ALLOCTEMPS\n#undef DUK__ALLOW_AUTO_SEMI_ALWAYS\n#undef DUK__BC_INITIAL_INSTS\n#undef DUK__BP_ADDITIVE\n#undef DUK__BP_ASSIGNMENT\n#undef DUK__BP_BAND\n#undef DUK__BP_BOR\n#undef DUK__BP_BXOR\n#undef DUK__BP_CALL\n#undef DUK__BP_CLOSING\n#undef DUK__BP_COMMA\n#undef DUK__BP_CONDITIONAL\n#undef DUK__BP_EOF\n#undef DUK__BP_EQUALITY\n#undef DUK__BP_EXPONENTIATION\n#undef DUK__BP_FOR_EXPR\n#undef DUK__BP_INVALID\n#undef DUK__BP_LAND\n#undef DUK__BP_LOR\n#undef DUK__BP_MEMBER\n#undef DUK__BP_MULTIPLICATIVE\n#undef DUK__BP_POSTFIX\n#undef DUK__BP_RELATIONAL\n#undef DUK__BP_SHIFT\n#undef DUK__COMPILE_ENTRY_SLOTS\n#undef DUK__CONST_MARKER\n#undef DUK__DUMP_ISPEC\n#undef DUK__DUMP_IVALUE\n#undef DUK__EMIT_FLAG_A_IS_SOURCE\n#undef DUK__EMIT_FLAG_BC_REGCONST\n#undef DUK__EMIT_FLAG_B_IS_TARGET\n#undef DUK__EMIT_FLAG_C_IS_TARGET\n#undef DUK__EMIT_FLAG_NO_SHUFFLE_A\n#undef DUK__EMIT_FLAG_NO_SHUFFLE_B\n#undef DUK__EMIT_FLAG_NO_SHUFFLE_C\n#undef DUK__EMIT_FLAG_RESERVE_JUMPSLOT\n#undef DUK__EXPR_FLAG_ALLOW_EMPTY\n#undef DUK__EXPR_FLAG_REJECT_IN\n#undef DUK__EXPR_FLAG_REQUIRE_INIT\n#undef DUK__EXPR_RBP_MASK\n#undef DUK__FUNCTION_BODY_REQUIRE_SLOTS\n#undef DUK__FUNCTION_INIT_REQUIRE_SLOTS\n#undef DUK__FUNC_FLAG_DECL\n#undef DUK__FUNC_FLAG_GETSET\n#undef DUK__FUNC_FLAG_METDEF\n#undef DUK__FUNC_FLAG_PUSHNAME_PASS1\n#undef DUK__FUNC_FLAG_USE_PREVTOKEN\n#undef DUK__GETCONST_MAX_CONSTS_CHECK\n#undef DUK__GETTEMP\n#undef DUK__HAS_TERM\n#undef DUK__HAS_VAL\n#undef DUK__ISCONST\n#undef DUK__ISREG\n#undef DUK__ISREG_NOTTEMP\n#undef DUK__ISREG_TEMP\n#undef DUK__IS_TERMINAL\n#undef DUK__IVAL_FLAG_ALLOW_CONST\n#undef DUK__IVAL_FLAG_REQUIRE_SHORT\n#undef DUK__IVAL_FLAG_REQUIRE_TEMP\n#undef DUK__MAX_ARRAY_INIT_VALUES\n#undef DUK__MAX_CONSTS\n#undef DUK__MAX_FUNCS\n#undef DUK__MAX_OBJECT_INIT_PAIRS\n#undef DUK__MAX_TEMPS\n#undef DUK__MK_LBP\n#undef DUK__MK_LBP_FLAGS\n#undef DUK__OBJ_LIT_KEY_GET\n#undef DUK__OBJ_LIT_KEY_PLAIN\n#undef DUK__OBJ_LIT_KEY_SET\n#undef DUK__PARSE_EXPR_SLOTS\n#undef DUK__PARSE_STATEMENTS_SLOTS\n#undef DUK__RECURSION_DECREASE\n#undef DUK__RECURSION_INCREASE\n#undef DUK__REMOVECONST\n#undef DUK__SETTEMP\n#undef DUK__SETTEMP_CHECKMAX\n#undef DUK__STILL_PROLOGUE\n#undef DUK__TOKEN_LBP_BP_MASK\n#undef DUK__TOKEN_LBP_FLAG_NO_REGEXP\n#undef DUK__TOKEN_LBP_FLAG_TERMINATES\n#undef DUK__TOKEN_LBP_FLAG_UNUSED\n#undef DUK__TOKEN_LBP_GET_BP\n/*\n *  ECMAScript bytecode executor.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Local declarations.\n */\n\nDUK_LOCAL_DECL void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, duk_activation *entry_act);\n\n/*\n *  Misc helpers.\n */\n\n/* Forced inline declaration, only applied for performance oriented build. */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n#define DUK__INLINE_PERF\n#define DUK__NOINLINE_PERF\n#else\n#define DUK__INLINE_PERF DUK_ALWAYS_INLINE\n#define DUK__NOINLINE_PERF DUK_NOINLINE\n#endif\n\n/* Replace value stack top to value at 'tv_ptr'.  Optimize for\n * performance by only applying the net refcount change.\n */\n#define DUK__REPLACE_TO_TVPTR(thr,tv_ptr) do { \\\n\t\tduk_hthread *duk__thr; \\\n\t\tduk_tval *duk__tvsrc; \\\n\t\tduk_tval *duk__tvdst; \\\n\t\tduk_tval duk__tvtmp; \\\n\t\tduk__thr = (thr); \\\n\t\tduk__tvsrc = DUK_GET_TVAL_NEGIDX(duk__thr, -1); \\\n\t\tduk__tvdst = (tv_ptr); \\\n\t\tDUK_TVAL_SET_TVAL(&duk__tvtmp, duk__tvdst); \\\n\t\tDUK_TVAL_SET_TVAL(duk__tvdst, duk__tvsrc); \\\n\t\tDUK_TVAL_SET_UNDEFINED(duk__tvsrc);  /* value stack init policy */ \\\n\t\tduk__thr->valstack_top = duk__tvsrc; \\\n\t\tDUK_TVAL_DECREF(duk__thr, &duk__tvtmp); \\\n\t} while (0)\n\n/* XXX: candidate of being an internal shared API call */\n#if 0  /* unused */\nDUK_LOCAL void duk__push_tvals_incref_only(duk_hthread *thr, duk_tval *tv_src, duk_small_uint_fast_t count) {\n\tduk_tval *tv_dst;\n\tduk_size_t copy_size;\n\tduk_size_t i;\n\n\ttv_dst = thr->valstack_top;\n\tcopy_size = sizeof(duk_tval) * count;\n\tduk_memcpy((void *) tv_dst, (const void *) tv_src, copy_size);\n\tfor (i = 0; i < count; i++) {\n\t\tDUK_TVAL_INCREF(thr, tv_dst);\n\t\ttv_dst++;\n\t}\n\tthr->valstack_top = tv_dst;\n}\n#endif\n\n/*\n *  Arithmetic, binary, and logical helpers.\n *\n *  Note: there is no opcode for logical AND or logical OR; this is on\n *  purpose, because the evalution order semantics for them make such\n *  opcodes pretty pointless: short circuiting means they are most\n *  comfortably implemented as jumps.  However, a logical NOT opcode\n *  is useful.\n *\n *  Note: careful with duk_tval pointers here: they are potentially\n *  invalidated by any DECREF and almost any API call.  It's still\n *  preferable to work without making a copy but that's not always\n *  possible.\n */\n\nDUK_LOCAL DUK__INLINE_PERF duk_double_t duk__compute_mod(duk_double_t d1, duk_double_t d2) {\n\treturn (duk_double_t) duk_js_arith_mod((double) d1, (double) d2);\n}\n\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\nDUK_LOCAL DUK__INLINE_PERF duk_double_t duk__compute_exp(duk_double_t d1, duk_double_t d2) {\n\treturn (duk_double_t) duk_js_arith_pow((double) d1, (double) d2);\n}\n#endif\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_add(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_fast_t idx_z) {\n\t/*\n\t *  Addition operator is different from other arithmetic\n\t *  operations in that it also provides string concatenation.\n\t *  Hence it is implemented separately.\n\t *\n\t *  There is a fast path for number addition.  Other cases go\n\t *  through potentially multiple coercions as described in the\n\t *  E5 specification.  It may be possible to reduce the number\n\t *  of coercions, but this must be done carefully to preserve\n\t *  the exact semantics.\n\t *\n\t *  E5 Section 11.6.1.\n\t *\n\t *  Custom types also have special behavior implemented here.\n\t */\n\n\tduk_double_union du;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_x != NULL);  /* may be reg or const */\n\tDUK_ASSERT(tv_y != NULL);  /* may be reg or const */\n\tDUK_ASSERT_DISABLE(idx_z >= 0);  /* unsigned */\n\tDUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr));\n\n\t/*\n\t *  Fast paths\n\t */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\tduk_int64_t v1, v2, v3;\n\t\tduk_int32_t v3_hi;\n\t\tduk_tval *tv_z;\n\n\t\t/* Input values are signed 48-bit so we can detect overflow\n\t\t * reliably from high bits or just a comparison.\n\t\t */\n\n\t\tv1 = DUK_TVAL_GET_FASTINT(tv_x);\n\t\tv2 = DUK_TVAL_GET_FASTINT(tv_y);\n\t\tv3 = v1 + v2;\n\t\tv3_hi = (duk_int32_t) (v3 >> 32);\n\t\tif (DUK_LIKELY(v3_hi >= DUK_I64_CONSTANT(-0x8000) && v3_hi <= DUK_I64_CONSTANT(0x7fff))) {\n\t\t\ttv_z = thr->valstack_bottom + idx_z;\n\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, v3);  /* side effects */\n\t\t\treturn;\n\t\t} else {\n\t\t\t/* overflow, fall through */\n\t\t\t;\n\t\t}\n\t}\n#endif  /* DUK_USE_FASTINT */\n\n\tif (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) {\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tduk_tval *tv_z;\n#endif\n\n\t\tdu.d = DUK_TVAL_GET_NUMBER(tv_x) + DUK_TVAL_GET_NUMBER(tv_y);\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tduk_push_number(thr, du.d);  /* will NaN normalize result */\n\t\tduk_replace(thr, (duk_idx_t) idx_z);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\t\ttv_z = thr->valstack_bottom + idx_z;\n\t\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, du.d);  /* side effects */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\treturn;\n\t}\n\n\t/*\n\t *  Slow path: potentially requires function calls for coercion\n\t */\n\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\tduk_to_primitive(thr, -2, DUK_HINT_NONE);  /* side effects -> don't use tv_x, tv_y after */\n\tduk_to_primitive(thr, -1, DUK_HINT_NONE);\n\n\t/* Since Duktape 2.x plain buffers are treated like ArrayBuffer. */\n\tif (duk_is_string(thr, -2) || duk_is_string(thr, -1)) {\n\t\t/* Symbols shouldn't technically be handled here, but should\n\t\t * go into the default ToNumber() coercion path instead and\n\t\t * fail there with a TypeError.  However, there's a ToString()\n\t\t * in duk_concat_2() which also fails with TypeError so no\n\t\t * explicit check is needed.\n\t\t */\n\t\tduk_concat_2(thr);  /* [... s1 s2] -> [... s1+s2] */\n\t} else {\n\t\tduk_double_t d1, d2;\n\n\t\td1 = duk_to_number_m2(thr);\n\t\td2 = duk_to_number_m1(thr);\n\t\tDUK_ASSERT(duk_is_number(thr, -2));\n\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d1);\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d2);\n\n\t\tdu.d = d1 + d2;\n\t\tduk_pop_2_unsafe(thr);\n\t\tduk_push_number(thr, du.d);  /* will NaN normalize result */\n\t}\n\tduk_replace(thr, (duk_idx_t) idx_z);  /* side effects */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_binary_op(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_uint_fast_t idx_z, duk_small_uint_fast_t opcode) {\n\t/*\n\t *  Arithmetic operations other than '+' have number-only semantics\n\t *  and are implemented here.  The separate switch-case here means a\n\t *  \"double dispatch\" of the arithmetic opcode, but saves code space.\n\t *\n\t *  E5 Sections 11.5, 11.5.1, 11.5.2, 11.5.3, 11.6, 11.6.1, 11.6.2, 11.6.3.\n\t */\n\n\tduk_double_t d1, d2;\n\tduk_double_union du;\n\tduk_small_uint_fast_t opcode_shifted;\n#if defined(DUK_USE_FASTINT) || !defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_tval *tv_z;\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_x != NULL);  /* may be reg or const */\n\tDUK_ASSERT(tv_y != NULL);  /* may be reg or const */\n\tDUK_ASSERT_DISABLE(idx_z >= 0);  /* unsigned */\n\tDUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr));\n\n\topcode_shifted = opcode >> 2;  /* Get base opcode without reg/const modifiers. */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\tduk_int64_t v1, v2, v3;\n\t\tduk_int32_t v3_hi;\n\n\t\tv1 = DUK_TVAL_GET_FASTINT(tv_x);\n\t\tv2 = DUK_TVAL_GET_FASTINT(tv_y);\n\n\t\tswitch (opcode_shifted) {\n\t\tcase DUK_OP_SUB >> 2: {\n\t\t\tv3 = v1 - v2;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL >> 2: {\n\t\t\t/* Must ensure result is 64-bit (no overflow); a\n\t\t\t * simple and sufficient fast path is to allow only\n\t\t\t * 32-bit inputs.  Avoid zero inputs to avoid\n\t\t\t * negative zero issues (-1 * 0 = -0, for instance).\n\t\t\t */\n\t\t\tif (v1 >= DUK_I64_CONSTANT(-0x80000000) && v1 <= DUK_I64_CONSTANT(0x7fffffff) && v1 != 0 &&\n\t\t\t    v2 >= DUK_I64_CONSTANT(-0x80000000) && v2 <= DUK_I64_CONSTANT(0x7fffffff) && v2 != 0) {\n\t\t\t\tv3 = v1 * v2;\n\t\t\t} else {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV >> 2: {\n\t\t\t/* Don't allow a zero divisor.  Fast path check by\n\t\t\t * \"verifying\" with multiplication.  Also avoid zero\n\t\t\t * dividend to avoid negative zero issues (0 / -1 = -0\n\t\t\t * for instance).\n\t\t\t */\n\t\t\tif (v1 == 0 || v2 == 0) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tv3 = v1 / v2;\n\t\t\tif (v3 * v2 != v1) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD >> 2: {\n\t\t\t/* Don't allow a zero divisor.  Restrict both v1 and\n\t\t\t * v2 to positive values to avoid compiler specific\n\t\t\t * behavior.\n\t\t\t */\n\t\t\tif (v1 < 1 || v2 < 1) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tv3 = v1 % v2;\n\t\t\tDUK_ASSERT(v3 >= 0);\n\t\t\tDUK_ASSERT(v3 < v2);\n\t\t\tDUK_ASSERT(v1 - (v1 / v2) * v2 == v3);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\t/* Possible with DUK_OP_EXP. */\n\t\t\tgoto skip_fastint;\n\t\t}\n\t\t}\n\n\t\tv3_hi = (duk_int32_t) (v3 >> 32);\n\t\tif (DUK_LIKELY(v3_hi >= DUK_I64_CONSTANT(-0x8000) && v3_hi <= DUK_I64_CONSTANT(0x7fff))) {\n\t\t\ttv_z = thr->valstack_bottom + idx_z;\n\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, v3);  /* side effects */\n\t\t\treturn;\n\t\t}\n\t\t/* fall through if overflow etc */\n\t}\n skip_fastint:\n#endif  /* DUK_USE_FASTINT */\n\n\tif (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) {\n\t\t/* fast path */\n\t\td1 = DUK_TVAL_GET_NUMBER(tv_x);\n\t\td2 = DUK_TVAL_GET_NUMBER(tv_y);\n\t} else {\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\td1 = duk_to_number_m2(thr);  /* side effects */\n\t\td2 = duk_to_number_m1(thr);\n\t\tDUK_ASSERT(duk_is_number(thr, -2));\n\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d1);\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d2);\n\t\tduk_pop_2_unsafe(thr);\n\t}\n\n\tswitch (opcode_shifted) {\n\tcase DUK_OP_SUB >> 2: {\n\t\tdu.d = d1 - d2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_MUL >> 2: {\n\t\tdu.d = d1 * d2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_DIV >> 2: {\n\t\t/* Division-by-zero is undefined behavior, so\n\t\t * rely on a helper.\n\t\t */\n\t\tdu.d = duk_double_div(d1, d2);\n\t\tbreak;\n\t}\n\tcase DUK_OP_MOD >> 2: {\n\t\tdu.d = duk__compute_mod(d1, d2);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\tcase DUK_OP_EXP >> 2: {\n\t\tdu.d = duk__compute_exp(d1, d2);\n\t\tbreak;\n\t}\n#endif\n\tdefault: {\n\t\tDUK_UNREACHABLE();\n\t\tdu.d = DUK_DOUBLE_NAN;  /* should not happen */\n\t\tbreak;\n\t}\n\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_push_number(thr, du.d);  /* will NaN normalize result */\n\tduk_replace(thr, (duk_idx_t) idx_z);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t/* important to use normalized NaN with 8-byte tagged types */\n\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\ttv_z = thr->valstack_bottom + idx_z;\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, du.d);  /* side effects */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_bitwise_binary_op(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_fast_t idx_z, duk_small_uint_fast_t opcode) {\n\t/*\n\t *  Binary bitwise operations use different coercions (ToInt32, ToUint32)\n\t *  depending on the operation.  We coerce the arguments first using\n\t *  ToInt32(), and then cast to an 32-bit value if necessary.  Note that\n\t *  such casts must be correct even if there is no native 32-bit type\n\t *  (e.g., duk_int32_t and duk_uint32_t are 64-bit).\n\t *\n\t *  E5 Sections 11.10, 11.7.1, 11.7.2, 11.7.3\n\t */\n\n\tduk_int32_t i1, i2, i3;\n\tduk_uint32_t u1, u2, u3;\n#if defined(DUK_USE_FASTINT)\n\tduk_int64_t fi3;\n#else\n\tduk_double_t d3;\n#endif\n\tduk_small_uint_fast_t opcode_shifted;\n#if defined(DUK_USE_FASTINT) || !defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_tval *tv_z;\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_x != NULL);  /* may be reg or const */\n\tDUK_ASSERT(tv_y != NULL);  /* may be reg or const */\n\tDUK_ASSERT_DISABLE(idx_z >= 0);  /* unsigned */\n\tDUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr));\n\n\topcode_shifted = opcode >> 2;  /* Get base opcode without reg/const modifiers. */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\ti1 = (duk_int32_t) DUK_TVAL_GET_FASTINT_I32(tv_x);\n\t\ti2 = (duk_int32_t) DUK_TVAL_GET_FASTINT_I32(tv_y);\n\t}\n\telse\n#endif  /* DUK_USE_FASTINT */\n\t{\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\ti1 = duk_to_int32(thr, -2);\n\t\ti2 = duk_to_int32(thr, -1);\n\t\tduk_pop_2_unsafe(thr);\n\t}\n\n\tswitch (opcode_shifted) {\n\tcase DUK_OP_BAND >> 2: {\n\t\ti3 = i1 & i2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_BOR >> 2: {\n\t\ti3 = i1 | i2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_BXOR >> 2: {\n\t\ti3 = i1 ^ i2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_BASL >> 2: {\n\t\t/* Signed shift, named \"arithmetic\" (asl) because the result\n\t\t * is signed, e.g. 4294967295 << 1 -> -2.  Note that result\n\t\t * must be masked.\n\t\t */\n\n\t\tu2 = ((duk_uint32_t) i2) & 0xffffffffUL;\n\t\ti3 = (duk_int32_t) (((duk_uint32_t) i1) << (u2 & 0x1fUL));  /* E5 Section 11.7.1, steps 7 and 8 */\n\t\ti3 = i3 & ((duk_int32_t) 0xffffffffUL);                     /* Note: left shift, should mask */\n\t\tbreak;\n\t}\n\tcase DUK_OP_BASR >> 2: {\n\t\t/* signed shift */\n\n\t\tu2 = ((duk_uint32_t) i2) & 0xffffffffUL;\n\t\ti3 = i1 >> (u2 & 0x1fUL);                      /* E5 Section 11.7.2, steps 7 and 8 */\n\t\tbreak;\n\t}\n\tcase DUK_OP_BLSR >> 2: {\n\t\t/* unsigned shift */\n\n\t\tu1 = ((duk_uint32_t) i1) & 0xffffffffUL;\n\t\tu2 = ((duk_uint32_t) i2) & 0xffffffffUL;\n\n\t\t/* special result value handling */\n\t\tu3 = u1 >> (u2 & 0x1fUL);     /* E5 Section 11.7.2, steps 7 and 8 */\n#if defined(DUK_USE_FASTINT)\n\t\tfi3 = (duk_int64_t) u3;\n\t\tgoto fastint_result_set;\n#else\n\t\td3 = (duk_double_t) u3;\n\t\tgoto result_set;\n#endif\n\t}\n\tdefault: {\n\t\tDUK_UNREACHABLE();\n\t\ti3 = 0;  /* should not happen */\n\t\tbreak;\n\t}\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\t/* Result is always fastint compatible. */\n\t/* XXX: Set 32-bit result (but must then handle signed and\n\t * unsigned results separately).\n\t */\n\tfi3 = (duk_int64_t) i3;\n\n fastint_result_set:\n\ttv_z = thr->valstack_bottom + idx_z;\n\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, fi3);  /* side effects */\n#else  /* DUK_USE_FASTINT */\n\td3 = (duk_double_t) i3;\n\n result_set:\n\tDUK_ASSERT(!DUK_ISNAN(d3));            /* 'd3' is never NaN, so no need to normalize */\n\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d3);   /* always normalized */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_push_number(thr, d3);  /* would NaN normalize result, but unnecessary */\n\tduk_replace(thr, (duk_idx_t) idx_z);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\ttv_z = thr->valstack_bottom + idx_z;\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, d3);  /* side effects */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n#endif  /* DUK_USE_FASTINT */\n}\n\n/* In-place unary operation. */\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_unary_op(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst, duk_small_uint_fast_t opcode) {\n\t/*\n\t *  Arithmetic operations other than '+' have number-only semantics\n\t *  and are implemented here.  The separate switch-case here means a\n\t *  \"double dispatch\" of the arithmetic opcode, but saves code space.\n\t *\n\t *  E5 Sections 11.5, 11.5.1, 11.5.2, 11.5.3, 11.6, 11.6.1, 11.6.2, 11.6.3.\n\t */\n\n\tduk_tval *tv;\n\tduk_double_t d1;\n\tduk_double_union du;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(opcode == DUK_OP_UNM || opcode == DUK_OP_UNP);\n\tDUK_ASSERT_DISABLE(idx_src >= 0);\n\tDUK_ASSERT_DISABLE(idx_dst >= 0);\n\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tduk_int64_t v1, v2;\n\n\t\tv1 = DUK_TVAL_GET_FASTINT(tv);\n\t\tif (opcode == DUK_OP_UNM) {\n\t\t\t/* The smallest fastint is no longer 48-bit when\n\t\t\t * negated.  Positive zero becames negative zero\n\t\t\t * (cannot be represented) when negated.\n\t\t\t */\n\t\t\tif (DUK_LIKELY(v1 != DUK_FASTINT_MIN && v1 != 0)) {\n\t\t\t\tv2 = -v1;\n\t\t\t\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv, v2);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\t/* ToNumber() for a fastint is a no-op. */\n\t\t\tDUK_ASSERT(opcode == DUK_OP_UNP);\n\t\t\tv2 = v1;\n\t\t\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv, v2);\n\t\t\treturn;\n\t\t}\n\t\t/* fall through if overflow etc */\n\t}\n#endif  /* DUK_USE_FASTINT */\n\n\tif (DUK_TVAL_IS_NUMBER(tv)) {\n\t\td1 = DUK_TVAL_GET_NUMBER(tv);\n\t} else {\n\t\td1 = duk_to_number_tval(thr, tv);  /* side effects */\n\t}\n\n\tif (opcode == DUK_OP_UNP) {\n\t\t/* ToNumber() for a double is a no-op, but unary plus is\n\t\t * used to force a fastint check so do that here.\n\t\t */\n\t\tdu.d = d1;\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n#if defined(DUK_USE_FASTINT)\n\t\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t\tDUK_TVAL_SET_NUMBER_CHKFAST_UPDREF(thr, tv, du.d);  /* always 'fast', i.e. inlined */\n\t\treturn;\n#endif\n\t} else {\n\t\tDUK_ASSERT(opcode == DUK_OP_UNM);\n\t\tdu.d = -d1;\n\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);  /* mandatory if du.d is a NaN */\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\t}\n\n\t/* XXX: size optimize: push+replace? */\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv, du.d);\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_bitwise_not(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst) {\n\t/*\n\t *  E5 Section 11.4.8\n\t */\n\n\tduk_tval *tv;\n\tduk_int32_t i1, i2;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT_DISABLE(idx_src >= 0);\n\tDUK_ASSERT_DISABLE(idx_dst >= 0);\n\tDUK_ASSERT((duk_uint_t) idx_src < (duk_uint_t) duk_get_top(thr));\n\tDUK_ASSERT((duk_uint_t) idx_dst < (duk_uint_t) duk_get_top(thr));\n\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\ti1 = (duk_int32_t) DUK_TVAL_GET_FASTINT_I32(tv);\n\t}\n\telse\n#endif  /* DUK_USE_FASTINT */\n\t{\n\t\tduk_push_tval(thr, tv);\n\t\ti1 = duk_to_int32(thr, -1);  /* side effects */\n\t\tduk_pop_unsafe(thr);\n\t}\n\n\t/* Result is always fastint compatible. */\n\ti2 = ~i1;\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\tDUK_TVAL_SET_I32_UPDREF(thr, tv, i2);  /* side effects */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_logical_not(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst) {\n\t/*\n\t *  E5 Section 11.4.9\n\t */\n\n\tduk_tval *tv;\n\tduk_bool_t res;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT_DISABLE(idx_src >= 0);\n\tDUK_ASSERT_DISABLE(idx_dst >= 0);\n\tDUK_ASSERT((duk_uint_t) idx_src < (duk_uint_t) duk_get_top(thr));\n\tDUK_ASSERT((duk_uint_t) idx_dst < (duk_uint_t) duk_get_top(thr));\n\n\t/* ToBoolean() does not require any operations with side effects so\n\t * we can do it efficiently.  For footprint it would be better to use\n\t * duk_js_toboolean() and then push+replace to the result slot.\n\t */\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src);\n\tres = duk_js_toboolean(tv);  /* does not modify 'tv' */\n\tDUK_ASSERT(res == 0 || res == 1);\n\tres ^= 1;\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t/* XXX: size optimize: push+replace? */\n\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv, res);  /* side effects */\n}\n\n/* XXX: size optimized variant */\nDUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_reg_helper(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_small_uint_t op) {\n\tduk_double_t x, y, z;\n\n\t/* Two lowest bits of opcode are used to distinguish\n\t * variants.  Bit 0 = inc(0)/dec(1), bit 1 = pre(0)/post(1).\n\t */\n\tDUK_ASSERT((DUK_OP_PREINCR & 0x03) == 0x00);\n\tDUK_ASSERT((DUK_OP_PREDECR & 0x03) == 0x01);\n\tDUK_ASSERT((DUK_OP_POSTINCR & 0x03) == 0x02);\n\tDUK_ASSERT((DUK_OP_POSTDECR & 0x03) == 0x03);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_src)) {\n\t\tduk_int64_t x_fi, y_fi, z_fi;\n\t\tx_fi = DUK_TVAL_GET_FASTINT(tv_src);\n\t\tif (op & 0x01) {\n\t\t\tif (DUK_UNLIKELY(x_fi == DUK_FASTINT_MIN)) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\ty_fi = x_fi - 1;\n\t\t} else {\n\t\t\tif (DUK_UNLIKELY(x_fi == DUK_FASTINT_MAX)) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\ty_fi = x_fi + 1;\n\t\t}\n\n\t\tDUK_TVAL_SET_FASTINT(tv_src, y_fi);  /* no need for refcount update */\n\n\t\tz_fi = (op & 0x02) ? x_fi : y_fi;\n\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_dst, z_fi);  /* side effects */\n\t\treturn;\n\t}\n skip_fastint:\n#endif\n\tif (DUK_TVAL_IS_NUMBER(tv_src)) {\n\t\t/* Fast path for the case where the register\n\t\t * is a number (e.g. loop counter).\n\t\t */\n\n\t\tx = DUK_TVAL_GET_NUMBER(tv_src);\n\t\tif (op & 0x01) {\n\t\t\ty = x - 1.0;\n\t\t} else {\n\t\t\ty = x + 1.0;\n\t\t}\n\n\t\tDUK_TVAL_SET_NUMBER(tv_src, y);  /* no need for refcount update */\n\t} else {\n\t\t/* Preserve duk_tval pointer(s) across a potential valstack\n\t\t * resize by converting them into offsets temporarily.\n\t\t */\n\t\tduk_idx_t bc;\n\t\tduk_size_t off_dst;\n\n\t\toff_dst = (duk_size_t) ((duk_uint8_t *) tv_dst - (duk_uint8_t *) thr->valstack_bottom);\n\t\tbc = (duk_idx_t) (tv_src - thr->valstack_bottom);  /* XXX: pass index explicitly? */\n\t\ttv_src = NULL;  /* no longer referenced */\n\n\t\tx = duk_to_number(thr, bc);\n\t\tif (op & 0x01) {\n\t\t\ty = x - 1.0;\n\t\t} else {\n\t\t\ty = x + 1.0;\n\t\t}\n\n\t\tduk_push_number(thr, y);\n\t\tduk_replace(thr, bc);\n\n\t\ttv_dst = (duk_tval *) (void *) (((duk_uint8_t *) thr->valstack_bottom) + off_dst);\n\t}\n\n\tz = (op & 0x02) ? x : y;\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_dst, z);  /* side effects */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_var_helper(duk_hthread *thr, duk_small_uint_t idx_dst, duk_tval *tv_id, duk_small_uint_t op, duk_small_uint_t is_strict) {\n\tduk_activation *act;\n\tduk_double_t x, y;\n\tduk_hstring *name;\n\n\t/* XXX: The pre/post inc/dec for an identifier lookup is\n\t * missing the important fast path where the identifier\n\t * has a storage location e.g. in a scope object so that\n\t * it can be updated in-place.  In particular, the case\n\t * where the identifier has a storage location AND the\n\t * previous value is a number should be optimized because\n\t * it's side effect free.\n\t */\n\n\t/* Two lowest bits of opcode are used to distinguish\n\t * variants.  Bit 0 = inc(0)/dec(1), bit 1 = pre(0)/post(1).\n\t */\n\tDUK_ASSERT((DUK_OP_PREINCV & 0x03) == 0x00);\n\tDUK_ASSERT((DUK_OP_PREDECV & 0x03) == 0x01);\n\tDUK_ASSERT((DUK_OP_POSTINCV & 0x03) == 0x02);\n\tDUK_ASSERT((DUK_OP_POSTDECV & 0x03) == 0x03);\n\n\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_id));\n\tname = DUK_TVAL_GET_STRING(tv_id);\n\tDUK_ASSERT(name != NULL);\n\tact = thr->callstack_curr;\n\t(void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/);  /* -> [ ... val this ] */\n\n\t/* XXX: Fastint fast path would be useful here.  Also fastints\n\t * now lose their fastint status in current handling which is\n\t * not intuitive.\n\t */\n\n\tx = duk_to_number_m2(thr);\n\tif (op & 0x01) {\n\t\ty = x - 1.0;\n\t} else {\n\t\ty = x + 1.0;\n\t}\n\n\t/* [... x this] */\n\n\tif (op & 0x02) {\n\t\tduk_push_number(thr, y);  /* -> [ ... x this y ] */\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tduk_js_putvar_activation(thr, act, name, DUK_GET_TVAL_NEGIDX(thr, -1), is_strict);\n\t\tduk_pop_2_unsafe(thr);  /* -> [ ... x ] */\n\t} else {\n\t\tduk_pop_2_unsafe(thr);  /* -> [ ... ] */\n\t\tduk_push_number(thr, y);  /* -> [ ... y ] */\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tduk_js_putvar_activation(thr, act, name, DUK_GET_TVAL_NEGIDX(thr, -1), is_strict);\n\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_replace(thr, (duk_idx_t) idx_dst);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\tDUK__REPLACE_TO_TVPTR(thr, DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n}\n\n/*\n *  Longjmp and other control flow transfer for the bytecode executor.\n *\n *  The longjmp handler can handle all longjmp types: error, yield, and\n *  resume (pseudotypes are never actually thrown).\n *\n *  Error policy for longjmp: should not ordinarily throw errors; if errors\n *  occur (e.g. due to out-of-memory) they bubble outwards rather than being\n *  handled recursively.\n */\n\n#define DUK__LONGJMP_RESTART   0  /* state updated, restart bytecode execution */\n#define DUK__LONGJMP_RETHROW   1  /* exit bytecode executor by rethrowing an error to caller */\n\n#define DUK__RETHAND_RESTART   0  /* state updated, restart bytecode execution */\n#define DUK__RETHAND_FINISHED  1  /* exit bytecode execution with return value */\n\n/* XXX: optimize reconfig valstack operations so that resize, clamp, and setting\n * top are combined into one pass.\n */\n\n/* Reconfigure value stack for return to an ECMAScript function at\n * callstack top (caller unwinds).\n */\nDUK_LOCAL void duk__reconfig_valstack_ecma_return(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_hcompfunc *h_func;\n\tduk_idx_t clamp_top;\n\n\tDUK_ASSERT(thr != NULL);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act)));\n\n\t/* Clamp so that values at 'clamp_top' and above are wiped and won't\n\t * retain reachable garbage.  Then extend to 'nregs' because we're\n\t * returning to an ECMAScript function.\n\t */\n\n\th_func = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff);\n\tDUK_ASSERT(act->retval_byteoff >= act->bottom_byteoff);\n\tclamp_top = (duk_idx_t) ((act->retval_byteoff - act->bottom_byteoff + sizeof(duk_tval)) / sizeof(duk_tval));  /* +1 = one retval */\n\tduk_set_top_and_wipe(thr, h_func->nregs, clamp_top);\n\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack_end >= (duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\n\t/* XXX: a best effort shrink check would be OK here */\n}\n\n/* Reconfigure value stack for an ECMAScript catcher.  Use topmost catcher\n * in 'act'.\n */\nDUK_LOCAL void duk__reconfig_valstack_ecma_catcher(duk_hthread *thr, duk_activation *act) {\n\tduk_catcher *cat;\n\tduk_hcompfunc *h_func;\n\tduk_size_t idx_bottom;\n\tduk_idx_t clamp_top;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act)));\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\th_func = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff);\n\tidx_bottom = (duk_size_t) (thr->valstack_bottom - thr->valstack);\n\tDUK_ASSERT(cat->idx_base >= idx_bottom);\n\tclamp_top = (duk_idx_t) (cat->idx_base - idx_bottom + 2);  /* +2 = catcher value, catcher lj_type */\n\tduk_set_top_and_wipe(thr, h_func->nregs, clamp_top);\n\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack_end >= (duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\n\t/* XXX: a best effort shrink check would be OK here */\n}\n\n/* Set catcher regs: idx_base+0 = value, idx_base+1 = lj_type.\n * No side effects.\n */\nDUK_LOCAL void duk__set_catcher_regs_norz(duk_hthread *thr, duk_catcher *cat, duk_tval *tv_val_unstable, duk_small_uint_t lj_type) {\n\tduk_tval *tv1;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\n\ttv1 = thr->valstack + cat->idx_base;\n\tDUK_ASSERT(tv1 < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF_NORZ(thr, tv1, tv_val_unstable);\n\n\ttv1++;\n\tDUK_ASSERT(tv1 == thr->valstack + cat->idx_base + 1);\n\tDUK_ASSERT(tv1 < thr->valstack_top);\n\tDUK_TVAL_SET_U32_UPDREF_NORZ(thr, tv1, (duk_uint32_t) lj_type);\n}\n\nDUK_LOCAL void duk__handle_catch_part1(duk_hthread *thr, duk_tval *tv_val_unstable, duk_small_uint_t lj_type, volatile duk_bool_t *out_delayed_catch_setup) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_DD(DUK_DDPRINT(\"handle catch, part 1; act=%!A, cat=%!C\", act, act->cat));\n\n\tDUK_ASSERT(act->cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);\n\n\t/* The part1/part2 split could also be made here at the very top\n\t * of catch handling.  Value stack would be reconfigured inside\n\t * part2's protection.  Value stack reconfiguration should be free\n\t * of allocs, however.\n\t */\n\n\tduk__set_catcher_regs_norz(thr, act->cat, tv_val_unstable, lj_type);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tduk__reconfig_valstack_ecma_catcher(thr, act);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tact->curr_pc = cat->pc_base + 0;  /* +0 = catch */\n\n\t/*\n\t *  If the catch block has an automatic catch variable binding,\n\t *  we need to create a lexical environment for it which requires\n\t *  allocations.  Move out of \"error handling state\" before the\n\t *  allocations to avoid e.g. out-of-memory errors (leading to\n\t *  GH-2022 or similar).\n\t */\n\n\tif (DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"catcher has an automatic catch binding, handle in part 2\"));\n\t\t*out_delayed_catch_setup = 1;\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"catcher has no catch binding\"));\n\t}\n\n\tDUK_CAT_CLEAR_CATCH_ENABLED(cat);\n}\n\nDUK_LOCAL void duk__handle_catch_part2(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_hdecenv *new_env;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_DD(DUK_DDPRINT(\"handle catch, part 2; act=%!A, cat=%!C\", act, act->cat));\n\n\tDUK_ASSERT(act->cat != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);\n\tDUK_ASSERT(DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat));\n\tDUK_ASSERT(thr->valstack + cat->idx_base < thr->valstack_top);\n\n\t/*\n\t *  Create lexical environment for the catch clause, containing\n\t *  a binding for the caught value.\n\t *\n\t *  The binding is mutable (= writable) but not deletable.\n\t *  Step 4 for the catch production in E5 Section 12.14;\n\t *  no value is given for CreateMutableBinding 'D' argument,\n\t *  which implies the binding is not deletable.\n\t */\n\n\tif (act->lex_env == NULL) {\n\t\tDUK_ASSERT(act->var_env == NULL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"delayed environment initialization\"));\n\n\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t}\n\tDUK_ASSERT(act->lex_env != NULL);\n\tDUK_ASSERT(act->var_env != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\n\tnew_env = duk_hdecenv_alloc(thr,\n\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\tDUK_ASSERT(new_env != NULL);\n\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\tDUK_DDD(DUK_DDDPRINT(\"new_env allocated: %!iO\", (duk_heaphdr *) new_env));\n\n\t/* Note: currently the catch binding is handled without a register\n\t * binding because we don't support dynamic register bindings (they\n\t * must be fixed for an entire function).  So, there is no need to\n\t * record regbases etc.\n\t */\n\n\t/* [ ...env ] */\n\n\tDUK_ASSERT(cat->h_varname != NULL);\n\tduk_push_hstring(thr, cat->h_varname);\n\tDUK_ASSERT(thr->valstack + cat->idx_base < thr->valstack_top);\n\tduk_push_tval(thr, thr->valstack + cat->idx_base);\n\tduk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_W);  /* writable, not configurable */\n\n\t/* [ ... env ] */\n\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, act->lex_env);\n\tact->lex_env = (duk_hobject *) new_env;\n\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env);  /* reachable through activation */\n\t/* Net refcount change to act->lex_env is 0: incref for new_env's\n\t * prototype, decref for act->lex_env overwrite.\n\t */\n\n\tDUK_CAT_SET_LEXENV_ACTIVE(cat);\n\n\tduk_pop_unsafe(thr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"new_env finished: %!iO\", (duk_heaphdr *) new_env));\n}\n\nDUK_LOCAL void duk__handle_finally(duk_hthread *thr, duk_tval *tv_val_unstable, duk_small_uint_t lj_type) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(act->cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);\n\n\tduk__set_catcher_regs_norz(thr, act->cat, tv_val_unstable, lj_type);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tduk__reconfig_valstack_ecma_catcher(thr, act);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tact->curr_pc = cat->pc_base + 1;  /* +1 = finally */\n\n\tDUK_CAT_CLEAR_FINALLY_ENABLED(cat);\n}\n\nDUK_LOCAL void duk__handle_label(duk_hthread *thr, duk_small_uint_t lj_type) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(DUK_ACT_GET_FUNC(act)));\n\n\t/* +0 = break, +1 = continue */\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_LABEL);\n\n\tact->curr_pc = cat->pc_base + (lj_type == DUK_LJ_TYPE_CONTINUE ? 1 : 0);\n\n\t/* valstack should not need changes */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) ==\n\t           (duk_size_t) ((duk_hcompfunc *) DUK_ACT_GET_FUNC(act))->nregs);\n#endif\n}\n\n/* Called for handling both a longjmp() with type DUK_LJ_TYPE_YIELD and\n * when a RETURN opcode terminates a thread and yields to the resumer.\n * Caller unwinds so that top of callstack is the activation we return to.\n */\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_LOCAL void duk__handle_yield(duk_hthread *thr, duk_hthread *resumer, duk_tval *tv_val_unstable) {\n\tduk_activation *act_resumer;\n\tduk_tval *tv1;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(resumer != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\tact_resumer = resumer->callstack_curr;\n\tDUK_ASSERT(act_resumer != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act_resumer) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act_resumer)));  /* resume caller must be an ECMAScript func */\n\n\ttv1 = (duk_tval *) (void *) ((duk_uint8_t *) resumer->valstack + act_resumer->retval_byteoff);  /* return value from Duktape.Thread.resume() */\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv_val_unstable);  /* side effects */  /* XXX: avoid side effects */\n\n\tduk__reconfig_valstack_ecma_return(resumer);\n\n\t/* caller must change active thread, and set thr->resumer to NULL */\n}\n#endif  /* DUK_USE_COROUTINE_SUPPORT */\n\nDUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation *entry_act, volatile duk_bool_t *out_delayed_catch_setup) {\n\tduk_small_uint_t retval = DUK__LONGJMP_RESTART;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(entry_act != NULL);\n\n\t/* 'thr' is the current thread, as no-one resumes except us and we\n\t * switch 'thr' in that case.\n\t */\n\tDUK_ASSERT(thr == thr->heap->curr_thread);\n\n\t/*\n\t *  (Re)try handling the longjmp.\n\t *\n\t *  A longjmp handler may convert the longjmp to a different type and\n\t *  \"virtually\" rethrow by goto'ing to 'check_longjmp'.  Before the goto,\n\t *  the following must be updated:\n\t *    - the heap 'lj' state\n\t *    - 'thr' must reflect the \"throwing\" thread\n\t */\n\n check_longjmp:\n\n\tDUK_DD(DUK_DDPRINT(\"handling longjmp: type=%ld, value1=%!T, value2=%!T, iserror=%ld, top=%ld\",\n\t                   (long) thr->heap->lj.type,\n\t                   (duk_tval *) &thr->heap->lj.value1,\n\t                   (duk_tval *) &thr->heap->lj.value2,\n\t                   (long) thr->heap->lj.iserror,\n\t\t\t   (long) duk_get_top(thr)));\n\n\tswitch (thr->heap->lj.type) {\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\tcase DUK_LJ_TYPE_RESUME: {\n\t\t/*\n\t\t *  Note: lj.value1 is 'value', lj.value2 is 'resumee'.\n\t\t *  This differs from YIELD.\n\t\t */\n\n\t\tduk_tval *tv;\n\t\tduk_tval *tv2;\n\t\tduk_hthread *resumee;\n\n\t\t/* duk_bi_duk_object_yield() and duk_bi_duk_object_resume() ensure all of these are met */\n\n\t\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);                                                         /* unchanged by Duktape.Thread.resume() */\n\t\tDUK_ASSERT(thr->callstack_top >= 2);                                                                         /* ECMAScript activation + Duktape.Thread.resume() activation */\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL &&\n\t\t           DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)) &&\n\t\t           ((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->callstack_curr))->func == duk_bi_thread_resume);\n\n\t\ttv = &thr->heap->lj.value2;  /* resumee */\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));\n\t\tDUK_ASSERT(DUK_TVAL_GET_OBJECT(tv) != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_THREAD(DUK_TVAL_GET_OBJECT(tv)));\n\t\tresumee = (duk_hthread *) DUK_TVAL_GET_OBJECT(tv);\n\n\t\tDUK_ASSERT(resumee != NULL);\n\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\tDUK_ASSERT(resumee->state == DUK_HTHREAD_STATE_INACTIVE ||\n\t\t           resumee->state == DUK_HTHREAD_STATE_YIELDED);                                                     /* checked by Duktape.Thread.resume() */\n\t\tDUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_YIELDED ||\n\t\t           resumee->callstack_top >= 2);                                                                     /* YIELDED: ECMAScript activation + Duktape.Thread.yield() activation */\n\t\tDUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_YIELDED ||\n\t\t           (DUK_ACT_GET_FUNC(resumee->callstack_curr) != NULL &&\n\t\t            DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(resumee->callstack_curr)) &&\n\t\t            ((duk_hnatfunc *) DUK_ACT_GET_FUNC(resumee->callstack_curr))->func == duk_bi_thread_yield));\n\t\tDUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_INACTIVE ||\n\t\t           resumee->callstack_top == 0);                                                                     /* INACTIVE: no activation, single function value on valstack */\n\n\t\tif (thr->heap->lj.iserror) {\n\t\t\t/*\n\t\t\t *  Throw the error in the resumed thread's context; the\n\t\t\t *  error value is pushed onto the resumee valstack.\n\t\t\t *\n\t\t\t *  Note: the callstack of the target may empty in this case\n\t\t\t *  too (i.e. the target thread has never been resumed).  The\n\t\t\t *  value stack will contain the initial function in that case,\n\t\t\t *  which we simply ignore.\n\t\t\t */\n\n\t\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\t\tresumee->resumer = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tresumee->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tthr->state = DUK_HTHREAD_STATE_RESUMED;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumee);\n\t\t\tthr = resumee;\n\n\t\t\tthr->heap->lj.type = DUK_LJ_TYPE_THROW;\n\n\t\t\t/* thr->heap->lj.value1 is already the value to throw */\n\t\t\t/* thr->heap->lj.value2 is 'thread', will be wiped out at the end */\n\n\t\t\tDUK_ASSERT(thr->heap->lj.iserror);  /* already set */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> resume with an error, converted to a throw in the resumee, propagate\"));\n\t\t\tgoto check_longjmp;\n\t\t} else if (resumee->state == DUK_HTHREAD_STATE_YIELDED) {\n\t\t\t/* Unwind previous Duktape.Thread.yield() call.  The\n\t\t\t * activation remaining must always be an ECMAScript\n\t\t\t * call now (yield() accepts calls from ECMAScript\n\t\t\t * only).\n\t\t\t */\n\t\t\tduk_activation *act_resumee;\n\n\t\t\tDUK_ASSERT(resumee->callstack_top >= 2);\n\t\t\tact_resumee = resumee->callstack_curr;  /* Duktape.Thread.yield() */\n\t\t\tDUK_ASSERT(act_resumee != NULL);\n\t\t\tact_resumee = act_resumee->parent;      /* ECMAScript call site for yield() */\n\t\t\tDUK_ASSERT(act_resumee != NULL);\n\n\t\t\ttv = (duk_tval *) (void *) ((duk_uint8_t *) resumee->valstack + act_resumee->retval_byteoff);  /* return value from Duktape.Thread.yield() */\n\t\t\tDUK_ASSERT(tv >= resumee->valstack && tv < resumee->valstack_top);\n\t\t\ttv2 = &thr->heap->lj.value1;\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv2);  /* side effects */  /* XXX: avoid side effects */\n\n\t\t\tduk_hthread_activation_unwind_norz(resumee);  /* unwind to 'yield' caller */\n\t\t\t/* no need to unwind catch stack */\n\n\t\t\tduk__reconfig_valstack_ecma_return(resumee);\n\n\t\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\t\tresumee->resumer = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tresumee->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tthr->state = DUK_HTHREAD_STATE_RESUMED;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumee);\n#if 0\n\t\t\tthr = resumee;  /* not needed, as we exit right away */\n#endif\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> resume with a value, restart execution in resumee\"));\n\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\tgoto wipe_and_return;\n\t\t} else {\n\t\t\t/* Initial resume call. */\n\t\t\tduk_small_uint_t call_flags;\n\t\t\tduk_int_t setup_rc;\n\n\t\t\t/* resumee: [... initial_func]  (currently actually: [initial_func]) */\n\n\t\t\tduk_push_undefined(resumee);\n\t\t\ttv = &thr->heap->lj.value1;\n\t\t\tduk_push_tval(resumee, tv);\n\n\t\t\t/* resumee: [... initial_func undefined(= this) resume_value ] */\n\n\t\t\tcall_flags = DUK_CALL_FLAG_ALLOW_ECMATOECMA;  /* not tailcall, ecma-to-ecma (assumed to succeed) */\n\n\t\t\tsetup_rc = duk_handle_call_unprotected_nargs(resumee, 1 /*nargs*/, call_flags);\n\t\t\tif (setup_rc == 0) {\n\t\t\t\t/* This shouldn't happen; Duktape.Thread.resume()\n\t\t\t\t * should make sure of that.  If it does happen\n\t\t\t\t * this internal error will propagate out of the\n\t\t\t\t * executor which can be quite misleading.\n\t\t\t\t */\n\t\t\t\tDUK_ERROR_INTERNAL(thr);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\n\t\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\t\tresumee->resumer = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tresumee->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tthr->state = DUK_HTHREAD_STATE_RESUMED;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumee);\n#if 0\n\t\t\tthr = resumee;  /* not needed, as we exit right away */\n#endif\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> resume with a value, restart execution in resumee\"));\n\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\tgoto wipe_and_return;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\t\tbreak;  /* never here */\n\t}\n\n\tcase DUK_LJ_TYPE_YIELD: {\n\t\t/*\n\t\t *  Currently only allowed only if yielding thread has only\n\t\t *  ECMAScript activations (except for the Duktape.Thread.yield()\n\t\t *  call at the callstack top) and none of them constructor\n\t\t *  calls.\n\t\t *\n\t\t *  This excludes the 'entry' thread which will always have\n\t\t *  a preventcount > 0.\n\t\t */\n\n\t\tduk_hthread *resumer;\n\n\t\t/* duk_bi_duk_object_yield() and duk_bi_duk_object_resume() ensure all of these are met */\n\n#if 0  /* entry_thread not available for assert */\n\t\tDUK_ASSERT(thr != entry_thread);                                                                             /* Duktape.Thread.yield() should prevent */\n#endif\n\t\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);                                                         /* unchanged from Duktape.Thread.yield() */\n\t\tDUK_ASSERT(thr->callstack_top >= 2);                                                                         /* ECMAScript activation + Duktape.Thread.yield() activation */\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL &&\n\t\t           DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)) &&\n\t\t           ((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->callstack_curr))->func == duk_bi_thread_yield);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL &&\n\t\t           DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent)));                              /* an ECMAScript function */\n\n\t\tresumer = thr->resumer;\n\n\t\tDUK_ASSERT(resumer != NULL);\n\t\tDUK_ASSERT(resumer->state == DUK_HTHREAD_STATE_RESUMED);                                                     /* written by a previous RESUME handling */\n\t\tDUK_ASSERT(resumer->callstack_top >= 2);                                                                     /* ECMAScript activation + Duktape.Thread.resume() activation */\n\t\tDUK_ASSERT(resumer->callstack_curr != NULL);\n\t\tDUK_ASSERT(resumer->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack_curr) != NULL &&\n\t\t           DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr)) &&\n\t\t           ((duk_hnatfunc *) DUK_ACT_GET_FUNC(resumer->callstack_curr))->func == duk_bi_thread_resume);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack_curr->parent) != NULL &&\n\t\t           DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr->parent)));                            /* an ECMAScript function */\n\n\t\tif (thr->heap->lj.iserror) {\n\t\t\tthr->state = DUK_HTHREAD_STATE_YIELDED;\n\t\t\tthr->resumer = NULL;\n\t\t\tDUK_HTHREAD_DECREF_NORZ(thr, resumer);\n\t\t\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n\t\t\tthr = resumer;\n\n\t\t\tthr->heap->lj.type = DUK_LJ_TYPE_THROW;\n\t\t\t/* lj.value1 is already set */\n\t\t\tDUK_ASSERT(thr->heap->lj.iserror);  /* already set */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> yield an error, converted to a throw in the resumer, propagate\"));\n\t\t\tgoto check_longjmp;\n\t\t} else {\n\t\t\tduk_hthread_activation_unwind_norz(resumer);\n\t\t\tduk__handle_yield(thr, resumer, &thr->heap->lj.value1);\n\n\t\t\tthr->state = DUK_HTHREAD_STATE_YIELDED;\n\t\t\tthr->resumer = NULL;\n\t\t\tDUK_HTHREAD_DECREF_NORZ(thr, resumer);\n\t\t\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n#if 0\n\t\t\tthr = resumer;  /* not needed, as we exit right away */\n#endif\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> yield a value, restart execution in resumer\"));\n\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\tgoto wipe_and_return;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\t\tbreak;  /* never here */\n\t}\n#endif  /* DUK_USE_COROUTINE_SUPPORT */\n\n\tcase DUK_LJ_TYPE_THROW: {\n\t\t/*\n\t\t *  Three possible outcomes:\n\t\t *    * A try or finally catcher is found => resume there.\n\t\t *      (or)\n\t\t *    * The error propagates to the bytecode executor entry\n\t\t *      level (and we're in the entry thread) => rethrow\n\t\t *      with a new longjmp(), after restoring the previous\n\t\t *      catchpoint.\n\t\t *    * The error is not caught in the current thread, so\n\t\t *      the thread finishes with an error.  This works like\n\t\t *      a yielded error, except that the thread is finished\n\t\t *      and can no longer be resumed.  (There is always a\n\t\t *      resumer in this case.)\n\t\t *\n\t\t *  Note: until we hit the entry level, there can only be\n\t\t *  ECMAScript activations.\n\t\t */\n\n\t\tduk_activation *act;\n\t\tduk_catcher *cat;\n\t\tduk_hthread *resumer;\n\n\t\tfor (;;) {\n\t\t\tact = thr->callstack_curr;\n\t\t\tif (act == NULL) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tfor (;;) {\n\t\t\t\tcat = act->cat;\n\t\t\t\tif (cat == NULL) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (DUK_CAT_HAS_CATCH_ENABLED(cat)) {\n\t\t\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"before catch part 1: thr=%p, act=%p, cat=%p\",\n\t\t\t\t\t                     (void *) thr, (void *) act, (void *) act->cat));\n\t\t\t\t\tduk__handle_catch_part1(thr,\n\t\t\t\t\t                        &thr->heap->lj.value1,\n\t\t\t\t\t                        DUK_LJ_TYPE_THROW,\n\t\t\t\t\t\t\t        out_delayed_catch_setup);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"-> throw caught by a 'catch' clause, restart execution\"));\n\t\t\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\t\t\tgoto wipe_and_return;\n\t\t\t\t}\n\n\t\t\t\tif (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\t\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);\n\t\t\t\t\tDUK_ASSERT(!DUK_CAT_HAS_CATCH_ENABLED(cat));\n\n\t\t\t\t\tduk__handle_finally(thr,\n\t\t\t\t\t                    &thr->heap->lj.value1,\n\t\t\t\t\t                    DUK_LJ_TYPE_THROW);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"-> throw caught by a 'finally' clause, restart execution\"));\n\t\t\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\t\t\tgoto wipe_and_return;\n\t\t\t\t}\n\n\t\t\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t\t\t}\n\n\t\t\tif (act == entry_act) {\n\t\t\t\t/* Not caught by anything before entry level; rethrow and let the\n\t\t\t\t * final catcher finish unwinding (esp. value stack).\n\t\t\t\t */\n\t\t\t\tDUK_D(DUK_DPRINT(\"-> throw propagated up to entry level, rethrow and exit bytecode executor\"));\n\t\t\t\tretval = DUK__LONGJMP_RETHROW;\n\t\t\t\tgoto just_return;\n\t\t\t}\n\n\t\t\tduk_hthread_activation_unwind_norz(thr);\n\t\t}\n\n\t\tDUK_DD(DUK_DDPRINT(\"-> throw not caught by current thread, yield error to resumer and recheck longjmp\"));\n\n\t\t/* Not caught by current thread, thread terminates (yield error to resumer);\n\t\t * note that this may cause a cascade if the resumer terminates with an uncaught\n\t\t * exception etc (this is OK, but needs careful testing).\n\t\t */\n\n\t\tDUK_ASSERT(thr->resumer != NULL);\n\t\tDUK_ASSERT(thr->resumer->callstack_top >= 2);  /* ECMAScript activation + Duktape.Thread.resume() activation */\n\t\tDUK_ASSERT(thr->resumer->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->resumer->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent) != NULL &&\n\t\t           DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent)));  /* an ECMAScript function */\n\n\t\tresumer = thr->resumer;\n\n\t\t/* reset longjmp */\n\n\t\tDUK_ASSERT(thr->heap->lj.type == DUK_LJ_TYPE_THROW);  /* already set */\n\t\t/* lj.value1 already set */\n\n\t\tduk_hthread_terminate(thr);  /* updates thread state, minimizes its allocations */\n\t\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_TERMINATED);\n\n\t\tthr->resumer = NULL;\n\t\tDUK_HTHREAD_DECREF_NORZ(thr, resumer);\n\t\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n\t\tthr = resumer;\n\t\tgoto check_longjmp;\n\t}\n\n\tcase DUK_LJ_TYPE_BREAK:  /* pseudotypes, not used in actual longjmps */\n\tcase DUK_LJ_TYPE_CONTINUE:\n\tcase DUK_LJ_TYPE_RETURN:\n\tcase DUK_LJ_TYPE_NORMAL:\n\tdefault: {\n\t\t/* should never happen, but be robust */\n\t\tDUK_D(DUK_DPRINT(\"caught unknown longjmp type %ld, treat as internal error\", (long) thr->heap->lj.type));\n\t\tgoto convert_to_internal_error;\n\t}\n\n\t}  /* end switch */\n\n\tDUK_UNREACHABLE();\n\n wipe_and_return:\n\tDUK_DD(DUK_DDPRINT(\"handling longjmp done, wipe-and-return, top=%ld\",\n\t                   (long) duk_get_top(thr)));\n\tthr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;\n\tthr->heap->lj.iserror = 0;\n\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value1);  /* side effects */\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value2);  /* side effects */\n\n\tDUK_GC_TORTURE(thr->heap);\n\n just_return:\n\treturn retval;\n\n convert_to_internal_error:\n\t/* This could also be thrown internally (set the error, goto check_longjmp),\n\t * but it's better for internal errors to bubble outwards so that we won't\n\t * infinite loop in this catchpoint.\n\t */\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Handle a BREAK/CONTINUE opcode.  Avoid using longjmp() for BREAK/CONTINUE\n * handling because it has a measurable performance impact in ordinary\n * environments and an extreme impact in Emscripten (GH-342).\n */\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_break_or_continue(duk_hthread *thr,\n                                                                duk_uint_t label_id,\n                                                                duk_small_uint_t lj_type) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Find a matching label catcher or 'finally' catcher in\n\t * the same function, unwinding catchers as we go.\n\t *\n\t * A label catcher must always exist and will match unless\n\t * a 'finally' captures the break/continue first.  It is the\n\t * compiler's responsibility to ensure that labels are used\n\t * correctly.\n\t */\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\tfor (;;) {\n\t\tcat = act->cat;\n\t\tif (cat == NULL) {\n\t\t\tbreak;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"considering catcher %p: type=%ld label=%ld\",\n\t\t                     (void *) cat,\n\t\t                     (long) DUK_CAT_GET_TYPE(cat),\n\t\t                     (long) DUK_CAT_GET_LABEL(cat)));\n\n\t\t/* XXX: bit mask test; FINALLY <-> TCF, single bit mask would suffice? */\n\n\t\tif (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF &&\n\t\t    DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\t\tduk_tval tv_tmp;\n\n\t\t\tDUK_TVAL_SET_U32(&tv_tmp, (duk_uint32_t) label_id);\n\t\t\tduk__handle_finally(thr, &tv_tmp, lj_type);\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> break/continue caught by 'finally', restart execution\"));\n\t\t\treturn;\n\t\t}\n\t\tif (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_LABEL &&\n\t\t    (duk_uint_t) DUK_CAT_GET_LABEL(cat) == label_id) {\n\t\t\tduk__handle_label(thr, lj_type);\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> break/continue caught by a label catcher (in the same function), restart execution\"));\n\t\t\treturn;\n\t\t}\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t}\n\n\t/* Should never happen, but be robust. */\n\tDUK_D(DUK_DPRINT(\"-> break/continue not caught by anything in the current function (should never happen), throw internal error\"));\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Handle a RETURN opcode.  Avoid using longjmp() for return handling because\n * it has a measurable performance impact in ordinary environments and an extreme\n * impact in Emscripten (GH-342).  Return value is on value stack top.\n */\nDUK_LOCAL duk_small_uint_t duk__handle_return(duk_hthread *thr, duk_activation *entry_act) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\tduk_hthread *resumer;\n#endif\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\t/* We can directly access value stack here. */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(entry_act != NULL);\n\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\ttv1 = thr->valstack_top - 1;\n\tDUK_TVAL_CHKFAST_INPLACE_FAST(tv1);  /* fastint downgrade check for return values */\n\n\t/*\n\t *  Four possible outcomes:\n\t *\n\t *    1. A 'finally' in the same function catches the 'return'.\n\t *       It may continue to propagate when 'finally' is finished,\n\t *       or it may be neutralized by 'finally' (both handled by\n\t *       ENDFIN).\n\t *\n\t *    2. The return happens at the entry level of the bytecode\n\t *       executor, so return from the executor (in C stack).\n\t *\n\t *    3. There is a calling (ECMAScript) activation in the call\n\t *       stack => return to it, in the same executor instance.\n\t *\n\t *    4. There is no calling activation, and the thread is\n\t *       terminated.  There is always a resumer in this case,\n\t *       which gets the return value similarly to a 'yield'\n\t *       (except that the current thread can no longer be\n\t *       resumed).\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\tfor (;;) {\n\t\tcat = act->cat;\n\t\tif (cat == NULL) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF &&\n\t\t    DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\t\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\t\t\tduk__handle_finally(thr, thr->valstack_top - 1, DUK_LJ_TYPE_RETURN);\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> return caught by 'finally', restart execution\"));\n\t\t\treturn DUK__RETHAND_RESTART;\n\t\t}\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t}\n\n\tif (act == entry_act) {\n\t\t/* Return to the bytecode executor caller who will unwind stacks\n\t\t * and handle constructor post-processing.\n\t\t * Return value is already on the stack top: [ ... retval ].\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> return propagated up to entry level, exit bytecode executor\"));\n\t\treturn DUK__RETHAND_FINISHED;\n\t}\n\n\tif (thr->callstack_top >= 2) {\n\t\t/* There is a caller; it MUST be an ECMAScript caller (otherwise it would\n\t\t * match entry_act check).\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"return to ECMAScript caller, retval_byteoff=%ld, lj_value1=%!T\",\n\t\t                     (long) (thr->callstack_curr->parent->retval_byteoff),\n\t\t                     (duk_tval *) &thr->heap->lj.value1));\n\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent)));   /* must be ECMAScript */\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (thr->callstack_curr->flags & (DUK_ACT_FLAG_CONSTRUCT | DUK_ACT_FLAG_CONSTRUCT_PROXY)) {\n\t\t\tduk_call_construct_postprocess(thr, thr->callstack_curr->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY);  /* side effects */\n\t\t}\n#else\n\t\tif (thr->callstack_curr->flags & DUK_ACT_FLAG_CONSTRUCT) {\n\t\t\tduk_call_construct_postprocess(thr, 0);  /* side effects */\n\t\t}\n#endif\n\n\t\ttv1 = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + thr->callstack_curr->parent->retval_byteoff);\n\t\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\t\ttv2 = thr->valstack_top - 1;\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\n\t\t/* Catch stack unwind happens inline in callstack unwind. */\n\t\tduk_hthread_activation_unwind_norz(thr);\n\n\t\tduk__reconfig_valstack_ecma_return(thr);\n\n\t\tDUK_DD(DUK_DDPRINT(\"-> return not intercepted, restart execution in caller\"));\n\t\treturn DUK__RETHAND_RESTART;\n\t}\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\tDUK_DD(DUK_DDPRINT(\"no calling activation, thread finishes (similar to yield)\"));\n\n\tDUK_ASSERT(thr->resumer != NULL);\n\tDUK_ASSERT(thr->resumer->callstack_top >= 2);  /* ECMAScript activation + Duktape.Thread.resume() activation */\n\tDUK_ASSERT(thr->resumer->callstack_curr != NULL);\n\tDUK_ASSERT(thr->resumer->callstack_curr->parent != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr) != NULL &&\n\t\t\tDUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr)) &&\n\t\t\t((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->resumer->callstack_curr))->func == duk_bi_thread_resume);  /* Duktape.Thread.resume() */\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent) != NULL &&\n\t\t\tDUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent)));  /* an ECMAScript function */\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\tDUK_ASSERT(thr->resumer->state == DUK_HTHREAD_STATE_RESUMED);\n\n\tresumer = thr->resumer;\n\n\t/* Share yield longjmp handler.\n\t *\n\t * This sequence of steps is a bit fragile (see GH-1845):\n\t * - We need the return value from 'thr' (resumed thread) value stack.\n\t *   The termination unwinds its value stack, losing the value.\n\t * - We need a refcounted reference for 'thr', which may only exist\n\t *   in the caller value stack.  We can't unwind or reconfigure the\n\t *   caller's value stack without potentially freeing 'thr'.\n\t *\n\t * Current approach is to capture the 'thr' return value and store\n\t * a reference to 'thr' in the caller value stack temporarily.  This\n\t * keeps 'thr' reachable until final yield/return handling which\n\t * removes the references atomatically.\n\t */\n\n\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\tduk_hthread_activation_unwind_norz(resumer);  /* May remove last reference to 'thr', but is NORZ. */\n\tduk_push_tval(resumer, thr->valstack_top - 1);  /* Capture return value, side effect free. */\n\tduk_push_hthread(resumer, thr);  /* Make 'thr' reachable again, before side effects. */\n\n\tduk_hthread_terminate(thr);  /* Updates thread state, minimizes its allocations. */\n\tthr->resumer = NULL;\n\tDUK_HTHREAD_DECREF(thr, resumer);\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_TERMINATED);\n\n\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n\n\tDUK_ASSERT(resumer->valstack_top - 2 >= resumer->valstack_bottom);\n\tduk__handle_yield(thr, resumer, resumer->valstack_top - 2);\n\tthr = NULL;  /* 'thr' invalidated by call */\n\n#if 0\n\tthr = resumer;  /* not needed */\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"-> return not caught, thread terminated; handle like yield, restart execution in resumer\"));\n\treturn DUK__RETHAND_RESTART;\n#else\n\t/* Without coroutine support this case should never happen. */\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n#endif\n}\n\n/*\n *  Executor interrupt handling\n *\n *  The handler is called whenever the interrupt countdown reaches zero\n *  (or below).  The handler must perform whatever checks are activated,\n *  e.g. check for cumulative step count to impose an execution step\n *  limit or check for breakpoints or other debugger interaction.\n *\n *  When the actions are done, the handler must reinit the interrupt\n *  init and counter values.  The 'init' value must indicate how many\n *  bytecode instructions are executed before the next interrupt.  The\n *  counter must interface with the bytecode executor loop.  Concretely,\n *  the new init value is normally one higher than the new counter value.\n *  For instance, to execute exactly one bytecode instruction the init\n *  value is set to 1 and the counter to 0.  If an error is thrown by the\n *  interrupt handler, the counters are set to the same value (e.g. both\n *  to 0 to cause an interrupt when the next bytecode instruction is about\n *  to be executed after error handling).\n *\n *  Maintaining the init/counter value properly is important for accurate\n *  behavior.  For instance, executor step limit needs a cumulative step\n *  count which is simply computed as a sum of 'init' values.  This must\n *  work accurately even when single stepping.\n */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\n#define DUK__INT_NOACTION    0    /* no specific action, resume normal execution */\n#define DUK__INT_RESTART     1    /* must \"goto restart_execution\", e.g. breakpoints changed */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_immediate, duk_small_uint_t *out_interrupt_retval) {\n\tduk_activation *act;\n\tduk_breakpoint *bp;\n\tduk_breakpoint **bp_active;\n\tduk_uint_fast32_t line = 0;\n\tduk_bool_t process_messages;\n\tduk_bool_t processed_messages = 0;\n\n\tDUK_ASSERT(thr->heap->dbg_processing == 0);  /* don't re-enter e.g. during Eval */\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\t/* It might seem that replacing 'thr->heap' with just 'heap' below\n\t * might be a good idea, but it increases code size slightly\n\t * (probably due to unnecessary spilling) at least on x64.\n\t */\n\n\t/*\n\t *  Single opcode step check\n\t */\n\n\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE) {\n\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by one opcode step\"));\n\t\tduk_debug_set_paused(thr->heap);\n\t}\n\n\t/*\n\t *  Breakpoint and step state checks\n\t */\n\n\tif (act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE ||\n\t    (thr->heap->dbg_pause_act == thr->callstack_curr)) {\n\t\tline = duk_debug_curr_line(thr);\n\n\t\tif (act->prev_line != line) {\n\t\t\t/* Stepped?  Step out is handled by callstack unwind. */\n\t\t\tif ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) &&\n\t\t\t    (thr->heap->dbg_pause_act == thr->callstack_curr) &&\n\t\t\t    (line != thr->heap->dbg_pause_startline)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by line change, at line %ld\",\n\t\t\t\t                 (long) line));\n\t\t\t\tduk_debug_set_paused(thr->heap);\n\t\t\t}\n\n\t\t\t/* Check for breakpoints only on line transition.\n\t\t\t * Breakpoint is triggered when we enter the target\n\t\t\t * line from a different line, and the previous line\n\t\t\t * was within the same function.\n\t\t\t *\n\t\t\t * This condition is tricky: the condition used to be\n\t\t\t * that transition to -or across- the breakpoint line\n\t\t\t * triggered the breakpoint.  This seems intuitively\n\t\t\t * better because it handles breakpoints on lines with\n\t\t\t * no emitted opcodes; but this leads to the issue\n\t\t\t * described in: https://github.com/svaarala/duktape/issues/263.\n\t\t\t */\n\t\t\tbp_active = thr->heap->dbg_breakpoints_active;\n\t\t\tfor (;;) {\n\t\t\t\tbp = *bp_active++;\n\t\t\t\tif (bp == NULL) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tDUK_ASSERT(bp->filename != NULL);\n\t\t\t\tif (act->prev_line != bp->line && line == bp->line) {\n\t\t\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by breakpoint at %!O:%ld\",\n\t\t\t\t\t                 (duk_heaphdr *) bp->filename, (long) bp->line));\n\t\t\t\t\tduk_debug_set_paused(thr->heap);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t;\n\t\t}\n\n\t\tact->prev_line = (duk_uint32_t) line;\n\t}\n\n\t/*\n\t *  Rate limit check for sending status update or peeking into\n\t *  the debug transport.  Both can be expensive operations that\n\t *  we don't want to do on every opcode.\n\t *\n\t *  Making sure the interval remains reasonable on a wide variety\n\t *  of targets and bytecode is difficult without a timestamp, so\n\t *  we use a Date-provided timestamp for the rate limit check.\n\t *  But since it's also expensive to get a timestamp, a bytecode\n\t *  counter is used to rate limit getting timestamps.\n\t */\n\n\tprocess_messages = 0;\n\tif (thr->heap->dbg_state_dirty || DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || thr->heap->dbg_detaching) {\n\t\t/* Enter message processing loop for sending Status notifys and\n\t\t * to finish a pending detach.\n\t\t */\n\t\tprocess_messages = 1;\n\t}\n\n\t/* XXX: remove heap->dbg_exec_counter, use heap->inst_count_interrupt instead? */\n\tDUK_ASSERT(thr->interrupt_init >= 0);\n\tthr->heap->dbg_exec_counter += (duk_uint_t) thr->interrupt_init;\n\tif (thr->heap->dbg_exec_counter - thr->heap->dbg_last_counter >= DUK_HEAP_DBG_RATELIMIT_OPCODES) {\n\t\t/* Overflow of the execution counter is fine and doesn't break\n\t\t * anything here.\n\t\t */\n\n\t\tduk_double_t now, diff_last;\n\n\t\tthr->heap->dbg_last_counter = thr->heap->dbg_exec_counter;\n\t\tnow = duk_time_get_monotonic_time(thr);\n\n\t\tdiff_last = now - thr->heap->dbg_last_time;\n\t\tif (diff_last < 0.0 || diff_last >= (duk_double_t) DUK_HEAP_DBG_RATELIMIT_MILLISECS) {\n\t\t\t/* Monotonic time should not experience time jumps,\n\t\t\t * but the provider may be missing and we're actually\n\t\t\t * using ECMAScript time.  So, tolerate negative values\n\t\t\t * so that a time jump works reasonably.\n\t\t\t *\n\t\t\t * Same interval is now used for status sending and\n\t\t\t * peeking.\n\t\t\t */\n\n\t\t\tthr->heap->dbg_last_time = now;\n\t\t\tthr->heap->dbg_state_dirty = 1;\n\t\t\tprocess_messages = 1;\n\t\t}\n\t}\n\n\t/*\n\t *  Process messages and send status if necessary.\n\t *\n\t *  If we're paused, we'll block for new messages.  If we're not\n\t *  paused, we'll process anything we can peek but won't block\n\t *  for more.  Detach (and re-attach) handling is all localized\n\t *  to duk_debug_process_messages() too.\n\t *\n\t *  Debugger writes outside the message loop may cause debugger\n\t *  detach1 phase to run, after which dbg_read_cb == NULL and\n\t *  dbg_detaching != 0.  The message loop will finish the detach\n\t *  by running detach2 phase, so enter the message loop also when\n\t *  detaching.\n\t */\n\n\tif (process_messages) {\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\t\tprocessed_messages = duk_debug_process_messages(thr, 0 /*no_block*/);\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\t}\n\n\t/* Continue checked execution if there are breakpoints or we're stepping.\n\t * Also use checked execution if paused flag is active - it shouldn't be\n\t * because the debug message loop shouldn't terminate if it was.  Step out\n\t * is handled by callstack unwind and doesn't need checked execution.\n\t * Note that debugger may have detached due to error or explicit request\n\t * above, so we must recheck attach status.\n\t */\n\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t\tif (act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE ||\n\t\t    (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE) ||\n\t\t    ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) &&\n\t\t     thr->heap->dbg_pause_act == thr->callstack_curr) ||\n\t\t     DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap)) {\n\t\t\t*out_immediate = 1;\n\t\t}\n\n\t\t/* If we processed any debug messages breakpoints may have\n\t\t * changed; restart execution to re-check active breakpoints.\n\t\t */\n\t\tif (processed_messages) {\n\t\t\tDUK_D(DUK_DPRINT(\"processed debug messages, restart execution to recheck possibly changed breakpoints\"));\n\t\t\t*out_interrupt_retval = DUK__INT_RESTART;\n\t\t} else {\n\t\t\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE) {\n\t\t\t\t/* Set 'pause after one opcode' active only when we're\n\t\t\t\t * actually just about to execute code.\n\t\t\t\t */\n\t\t\t\tthr->heap->dbg_pause_flags |= DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"debugger became detached, resume normal execution\"));\n\t}\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\nDUK_LOCAL DUK__NOINLINE_PERF DUK_COLD duk_small_uint_t duk__executor_interrupt(duk_hthread *thr) {\n\tduk_int_t ctr;\n\tduk_activation *act;\n\tduk_hcompfunc *fun;\n\tduk_bool_t immediate = 0;\n\tduk_small_uint_t retval;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->callstack_top > 0);\n\n#if defined(DUK_USE_DEBUG)\n\tthr->heap->inst_count_interrupt += thr->interrupt_init;\n\tDUK_DD(DUK_DDPRINT(\"execution interrupt, counter=%ld, init=%ld, \"\n\t                   \"instruction counts: executor=%ld, interrupt=%ld\",\n\t                   (long) thr->interrupt_counter, (long) thr->interrupt_init,\n\t                   (long) thr->heap->inst_count_exec, (long) thr->heap->inst_count_interrupt));\n#endif\n\n\tretval = DUK__INT_NOACTION;\n\tctr = DUK_HTHREAD_INTCTR_DEFAULT;\n\n\t/*\n\t *  Avoid nested calls.  Concretely this happens during debugging, e.g.\n\t *  when we eval() an expression.\n\t *\n\t *  Also don't interrupt if we're currently doing debug processing\n\t *  (which can be initiated outside the bytecode executor) as this\n\t *  may cause the debugger to be called recursively.  Check required\n\t *  for correct operation of throw intercept and other \"exotic\" halting\n\t * scenarios.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (DUK_HEAP_HAS_INTERRUPT_RUNNING(thr->heap) || thr->heap->dbg_processing) {\n#else\n\tif (DUK_HEAP_HAS_INTERRUPT_RUNNING(thr->heap)) {\n#endif\n\t\tDUK_DD(DUK_DDPRINT(\"nested executor interrupt, ignoring\"));\n\n\t\t/* Set a high interrupt counter; the original executor\n\t\t * interrupt invocation will rewrite before exiting.\n\t\t */\n\t\tthr->interrupt_init = ctr;\n\t\tthr->interrupt_counter = ctr - 1;\n\t\treturn DUK__INT_NOACTION;\n\t}\n\tDUK_HEAP_SET_INTERRUPT_RUNNING(thr->heap);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC((duk_hobject *) fun));\n\n\tDUK_UNREF(fun);\n\n#if defined(DUK_USE_EXEC_TIMEOUT_CHECK)\n\t/*\n\t *  Execution timeout check\n\t */\n\n\tif (DUK_USE_EXEC_TIMEOUT_CHECK(thr->heap->heap_udata)) {\n\t\t/* Keep throwing an error whenever we get here.  The unusual values\n\t\t * are set this way because no instruction is ever executed, we just\n\t\t * throw an error until all try/catch/finally and other catchpoints\n\t\t * have been exhausted.  Duktape/C code gets control at each protected\n\t\t * call but whenever it enters back into Duktape the RangeError gets\n\t\t * raised.  User exec timeout check must consistently indicate a timeout\n\t\t * until we've fully bubbled out of Duktape.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"execution timeout, throwing a RangeError\"));\n\t\tthr->interrupt_init = 0;\n\t\tthr->interrupt_counter = 0;\n\t\tDUK_HEAP_CLEAR_INTERRUPT_RUNNING(thr->heap);\n\t\tDUK_ERROR_RANGE(thr, \"execution timeout\");\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n#endif  /* DUK_USE_EXEC_TIMEOUT_CHECK */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (!thr->heap->dbg_processing &&\n\t    (thr->heap->dbg_read_cb != NULL || thr->heap->dbg_detaching)) {\n\t\t/* Avoid recursive re-entry; enter when we're attached or\n\t\t * detaching (to finish off the pending detach).\n\t\t */\n\t\tduk__interrupt_handle_debugger(thr, &immediate, &retval);\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n\t/*\n\t *  Update the interrupt counter\n\t */\n\n\tif (immediate) {\n\t\t/* Cause an interrupt after executing one instruction. */\n\t\tctr = 1;\n\t}\n\n\t/* The counter value is one less than the init value: init value should\n\t * indicate how many instructions are executed before interrupt.  To\n\t * execute 1 instruction (after interrupt handler return), counter must\n\t * be 0.\n\t */\n\tDUK_ASSERT(ctr >= 1);\n\tthr->interrupt_init = ctr;\n\tthr->interrupt_counter = ctr - 1;\n\tDUK_HEAP_CLEAR_INTERRUPT_RUNNING(thr->heap);\n\n\treturn retval;\n}\n#endif  /* DUK_USE_INTERRUPT_COUNTER */\n\n/*\n *  Debugger handling for executor restart\n *\n *  Check for breakpoints, stepping, etc, and figure out if we should execute\n *  in checked or normal mode.  Note that we can't do this when an activation\n *  is created, because breakpoint status (and stepping status) may change\n *  later, so we must recheck every time we're executing an activation.\n *  This primitive should be side effect free to avoid changes during check.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_LOCAL void duk__executor_recheck_debugger(duk_hthread *thr, duk_activation *act, duk_hcompfunc *fun) {\n\tduk_heap *heap;\n\tduk_tval *tv_tmp;\n\tduk_hstring *filename;\n\tduk_small_uint_t bp_idx;\n\tduk_breakpoint **bp_active;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(fun != NULL);\n\n\theap = thr->heap;\n\tbp_active = heap->dbg_breakpoints_active;\n\tact->flags &= ~DUK_ACT_FLAG_BREAKPOINT_ACTIVE;\n\n\ttv_tmp = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) fun, DUK_STRIDX_FILE_NAME);\n\tif (tv_tmp && DUK_TVAL_IS_STRING(tv_tmp)) {\n\t\tfilename = DUK_TVAL_GET_STRING(tv_tmp);\n\n\t\t/* Figure out all active breakpoints.  A breakpoint is\n\t\t * considered active if the current function's fileName\n\t\t * matches the breakpoint's fileName, AND there is no\n\t\t * inner function that has matching line numbers\n\t\t * (otherwise a breakpoint would be triggered both\n\t\t * inside and outside of the inner function which would\n\t\t * be confusing).  Example:\n\t\t *\n\t\t *     function foo() {\n\t\t *         print('foo');\n\t\t *         function bar() {    <-.  breakpoints in these\n\t\t *             print('bar');     |  lines should not affect\n\t\t *         }                   <-'  foo() execution\n\t\t *         bar();\n\t\t *     }\n\t\t *\n\t\t * We need a few things that are only available when\n\t\t * debugger support is enabled: (1) a line range for\n\t\t * each function, and (2) access to the function\n\t\t * template to access the inner functions (and their\n\t\t * line ranges).\n\t\t *\n\t\t * It's important to have a narrow match for active\n\t\t * breakpoints so that we don't enter checked execution\n\t\t * when that's not necessary.  For instance, if we're\n\t\t * running inside a certain function and there's\n\t\t * breakpoint outside in (after the call site), we\n\t\t * don't want to slow down execution of the function.\n\t\t */\n\n\t\tfor (bp_idx = 0; bp_idx < heap->dbg_breakpoint_count; bp_idx++) {\n\t\t\tduk_breakpoint *bp = heap->dbg_breakpoints + bp_idx;\n\t\t\tduk_hobject **funcs, **funcs_end;\n\t\t\tduk_hcompfunc *inner_fun;\n\t\t\tduk_bool_t bp_match;\n\n\t\t\tif (bp->filename == filename &&\n\t\t\t    bp->line >= fun->start_line && bp->line <= fun->end_line) {\n\t\t\t\tbp_match = 1;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"breakpoint filename and line match: \"\n\t\t\t\t                   \"%s:%ld vs. %s (line %ld vs. %ld-%ld)\",\n\t\t\t\t                   DUK_HSTRING_GET_DATA(bp->filename),\n\t\t\t\t                   (long) bp->line,\n\t\t\t\t                   DUK_HSTRING_GET_DATA(filename),\n\t\t\t\t                   (long) bp->line,\n\t\t\t\t                   (long) fun->start_line,\n\t\t\t\t                   (long) fun->end_line));\n\n\t\t\t\tfuncs = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, fun);\n\t\t\t\tfuncs_end = DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, fun);\n\t\t\t\twhile (funcs != funcs_end) {\n\t\t\t\t\tinner_fun = (duk_hcompfunc *) *funcs;\n\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) inner_fun));\n\t\t\t\t\tif (bp->line >= inner_fun->start_line && bp->line <= inner_fun->end_line) {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"inner function masks ('captures') breakpoint\"));\n\t\t\t\t\t\tbp_match = 0;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tfuncs++;\n\t\t\t\t}\n\n\t\t\t\tif (bp_match) {\n\t\t\t\t\t/* No need to check for size of bp_active list,\n\t\t\t\t\t * it's always larger than maximum number of\n\t\t\t\t\t * breakpoints.\n\t\t\t\t\t */\n\t\t\t\t\tact->flags |= DUK_ACT_FLAG_BREAKPOINT_ACTIVE;\n\t\t\t\t\t*bp_active = heap->dbg_breakpoints + bp_idx;\n\t\t\t\t\tbp_active++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t*bp_active = NULL;  /* terminate */\n\n\tDUK_DD(DUK_DDPRINT(\"ACTIVE BREAKPOINTS: %ld\", (long) (bp_active - thr->heap->dbg_breakpoints_active)));\n\n\t/* Force pause if we were doing \"step into\" in another activation. */\n\tif ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_ENTRY) &&\n\t    thr->heap->dbg_pause_act != thr->callstack_curr) {\n\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by function entry\"));\n\t\tduk_debug_set_paused(thr->heap);\n\t}\n\n\t/* Force interrupt right away if we're paused or in \"checked mode\".\n\t * Step out is handled by callstack unwind.\n\t */\n\tif ((act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE) ||\n\t    DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) ||\n\t    ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) &&\n\t     thr->heap->dbg_pause_act == thr->callstack_curr)) {\n\t\t/* We'll need to interrupt early so recompute the init\n\t\t * counter to reflect the number of bytecode instructions\n\t\t * executed so that step counts for e.g. debugger rate\n\t\t * limiting are accurate.\n\t\t */\n\t\tDUK_ASSERT(thr->interrupt_counter <= thr->interrupt_init);\n\t\tthr->interrupt_init = thr->interrupt_init - thr->interrupt_counter;\n\t\tthr->interrupt_counter = 0;\n\t}\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/*\n *  Opcode handlers for opcodes with a lot of code and which are relatively\n *  rare; NOINLINE to reduce amount of code in main bytecode dispatcher.\n */\n\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_initset_initget(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_bool_t is_set = (DUK_DEC_OP(ins) == DUK_OP_INITSET);\n\tduk_uint_fast_t idx;\n\tduk_uint_t defprop_flags;\n\n\t/* A -> object register (acts as a source)\n\t * BC -> BC+0 contains key, BC+1 closure (value)\n\t */\n\n\t/* INITSET/INITGET are only used to initialize object literal keys.\n\t * There may be a previous propery in ES2015 because duplicate property\n\t * names are allowed.\n\t */\n\n\t/* This could be made more optimal by accessing internals directly. */\n\n\tidx = (duk_uint_fast_t) DUK_DEC_BC(ins);\n\tduk_dup(thr, (duk_idx_t) (idx + 0));  /* key */\n\tduk_dup(thr, (duk_idx_t) (idx + 1));  /* getter/setter */\n\tif (is_set) {\n\t        defprop_flags = DUK_DEFPROP_HAVE_SETTER |\n\t                        DUK_DEFPROP_FORCE |\n\t                        DUK_DEFPROP_SET_ENUMERABLE |\n\t                        DUK_DEFPROP_SET_CONFIGURABLE;\n\t} else {\n\t        defprop_flags = DUK_DEFPROP_HAVE_GETTER |\n\t                        DUK_DEFPROP_FORCE |\n\t                        DUK_DEFPROP_SET_ENUMERABLE |\n\t                        DUK_DEFPROP_SET_CONFIGURABLE;\n\t}\n\tduk_def_prop(thr, (duk_idx_t) DUK_DEC_A(ins), defprop_flags);\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_trycatch(duk_hthread *thr, duk_uint_fast32_t ins, duk_instr_t *curr_pc) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_tval *tv1;\n\tduk_small_uint_fast_t a;\n\tduk_small_uint_fast_t bc;\n\n\t/* A -> flags\n\t * BC -> reg_catch; base register for two registers used both during\n\t *       trycatch setup and when catch is triggered\n\t *\n\t *      If DUK_BC_TRYCATCH_FLAG_CATCH_BINDING set:\n\t *          reg_catch + 0: catch binding variable name (string).\n\t *          Automatic declarative environment is established for\n\t *          the duration of the 'catch' clause.\n\t *\n\t *      If DUK_BC_TRYCATCH_FLAG_WITH_BINDING set:\n\t *          reg_catch + 0: with 'target value', which is coerced to\n\t *          an object and then used as a bindind object for an\n\t *          environment record.  The binding is initialized here, for\n\t *          the 'try' clause.\n\t *\n\t * Note that a TRYCATCH generated for a 'with' statement has no\n\t * catch or finally parts.\n\t */\n\n\t/* XXX: TRYCATCH handling should be reworked to avoid creating\n\t * an explicit scope unless it is actually needed (e.g. function\n\t * instances or eval is executed inside the catch block).  This\n\t * rework is not trivial because the compiler doesn't have an\n\t * intermediate representation.  When the rework is done, the\n\t * opcode format can also be made more straightforward.\n\t */\n\n\t/* XXX: side effect handling is quite awkward here */\n\n\tDUK_DDD(DUK_DDDPRINT(\"TRYCATCH: reg_catch=%ld, have_catch=%ld, \"\n\t                     \"have_finally=%ld, catch_binding=%ld, with_binding=%ld (flags=0x%02lx)\",\n\t                     (long) DUK_DEC_BC(ins),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH ? 1 : 0),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY ? 1 : 0),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_CATCH_BINDING ? 1 : 0),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_WITH_BINDING ? 1 : 0),\n\t                     (unsigned long) DUK_DEC_A(ins)));\n\n\ta = DUK_DEC_A(ins);\n\tbc = DUK_DEC_BC(ins);\n\n\t/* Registers 'bc' and 'bc + 1' are written in longjmp handling\n\t * and if their previous values (which are temporaries) become\n\t * unreachable -and- have a finalizer, there'll be a function\n\t * call during error handling which is not supported now (GH-287).\n\t * Ensure that both 'bc' and 'bc + 1' have primitive values to\n\t * guarantee no finalizer calls in error handling.  Scrubbing also\n\t * ensures finalizers for the previous values run here rather than\n\t * later.  Error handling related values are also written to 'bc'\n\t * and 'bc + 1' but those values never become unreachable during\n\t * error handling, so there's no side effect problem even if the\n\t * error value has a finalizer.\n\t */\n\tduk_dup(thr, (duk_idx_t) bc);  /* Stabilize value. */\n\tduk_to_undefined(thr, (duk_idx_t) bc);\n\tduk_to_undefined(thr, (duk_idx_t) (bc + 1));\n\n\t/* Allocate catcher and populate it.  Doesn't have to\n\t * be fully atomic, but the catcher must be in a\n\t * consistent state if side effects (such as finalizer\n\t * calls) occur.\n\t */\n\n\tcat = duk_hthread_catcher_alloc(thr);\n\tDUK_ASSERT(cat != NULL);\n\n\tcat->flags = DUK_CAT_TYPE_TCF;\n\tcat->h_varname = NULL;\n\tcat->pc_base = (duk_instr_t *) curr_pc;  /* pre-incremented, points to first jump slot */\n\tcat->idx_base = (duk_size_t) (thr->valstack_bottom - thr->valstack) + bc;\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tcat->parent = act->cat;\n\tact->cat = cat;\n\n\tif (a & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) {\n\t\tcat->flags |= DUK_CAT_FLAG_CATCH_ENABLED;\n\t}\n\tif (a & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY) {\n\t\tcat->flags |= DUK_CAT_FLAG_FINALLY_ENABLED;\n\t}\n\tif (a & DUK_BC_TRYCATCH_FLAG_CATCH_BINDING) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"catch binding flag set to catcher\"));\n\t\tcat->flags |= DUK_CAT_FLAG_CATCH_BINDING_ENABLED;\n\t\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\n\t\t/* borrowed reference; although 'tv1' comes from a register,\n\t\t * its value was loaded using LDCONST so the constant will\n\t\t * also exist and be reachable.\n\t\t */\n\t\tcat->h_varname = DUK_TVAL_GET_STRING(tv1);\n\t} else if (a & DUK_BC_TRYCATCH_FLAG_WITH_BINDING) {\n\t\tduk_hobjenv *env;\n\t\tduk_hobject *target;\n\n\t\t/* Delayed env initialization for activation (if needed). */\n\t\tDUK_ASSERT(thr->callstack_top >= 1);\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t\tif (act->lex_env == NULL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"delayed environment initialization\"));\n\t\t\tDUK_ASSERT(act->var_env == NULL);\n\n\t\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\t\tDUK_UNREF(act);  /* 'act' is no longer accessed, scanbuild fix */\n\t\t}\n\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\tDUK_ASSERT(act->var_env != NULL);\n\n\t\t/* Coerce 'with' target. */\n\t\ttarget = duk_to_hobject(thr, -1);\n\t\tDUK_ASSERT(target != NULL);\n\n\t\t/* Create an object environment; it is not pushed\n\t\t * so avoid side effects very carefully until it is\n\t\t * referenced.\n\t\t */\n\t\tenv = duk_hobjenv_alloc(thr,\n\t\t                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\t\tDUK_ASSERT(env != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);\n\t\tenv->target = target;  /* always provideThis=true */\n\t\tDUK_HOBJECT_INCREF(thr, target);\n\t\tenv->has_this = 1;\n\t\tDUK_HOBJENV_ASSERT_VALID(env);\n\t\tDUK_DDD(DUK_DDDPRINT(\"environment for with binding: %!iO\", env));\n\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);\n\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) env, act->lex_env);\n\t\tact->lex_env = (duk_hobject *) env;  /* Now reachable. */\n\t\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) env);\n\t\t/* Net refcount change to act->lex_env is 0: incref for env's\n\t\t * prototype, decref for act->lex_env overwrite.\n\t\t */\n\n\t\t/* Set catcher lex_env active (affects unwind)\n\t\t * only when the whole setup is complete.\n\t\t */\n\t\tcat = act->cat;  /* XXX: better to relookup? not mandatory because 'cat' is stable */\n\t\tcat->flags |= DUK_CAT_FLAG_LEXENV_ACTIVE;\n\t} else {\n\t\t;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"TRYCATCH catcher: flags=0x%08lx, pc_base=%ld, \"\n\t                     \"idx_base=%ld, h_varname=%!O\",\n\t                     (unsigned long) cat->flags,\n\t                     (long) cat->pc_base, (long) cat->idx_base, (duk_heaphdr *) cat->h_varname));\n\n\tduk_pop_unsafe(thr);\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_instr_t *duk__handle_op_endtry(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_tval *tv1;\n\tduk_instr_t *pc_base;\n\n\tDUK_UNREF(ins);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);\n\n\tDUK_DDD(DUK_DDDPRINT(\"ENDTRY: clearing catch active flag (regardless of whether it was set or not)\"));\n\tDUK_CAT_CLEAR_CATCH_ENABLED(cat);\n\n\tpc_base = cat->pc_base;\n\n\tif (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDTRY: finally part is active, jump through 2nd jump slot with 'normal continuation'\"));\n\n\t\ttv1 = thr->valstack + cat->idx_base;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\ttv1 = thr->valstack + cat->idx_base + 1;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_U32_UPDREF(thr, tv1, (duk_uint32_t) DUK_LJ_TYPE_NORMAL);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\tDUK_CAT_CLEAR_FINALLY_ENABLED(cat);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDTRY: no finally part, dismantle catcher, jump through 2nd jump slot (to end of statement)\"));\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);  /* lexenv may be set for 'with' binding */\n\t\t/* no need to unwind callstack */\n\t}\n\n\treturn pc_base + 1;  /* new curr_pc value */\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_instr_t *duk__handle_op_endcatch(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_tval *tv1;\n\tduk_instr_t *pc_base;\n\n\tDUK_UNREF(ins);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(!DUK_CAT_HAS_CATCH_ENABLED(cat));  /* cleared before entering catch part */\n\n\tif (DUK_CAT_HAS_LEXENV_ACTIVE(cat)) {\n\t\tduk_hobject *prev_env;\n\n\t\t/* 'with' binding has no catch clause, so can't be here unless a normal try-catch */\n\t\tDUK_ASSERT(DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat));\n\t\tDUK_ASSERT(act->lex_env != NULL);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDCATCH: popping catcher part lexical environment\"));\n\n\t\tprev_env = act->lex_env;\n\t\tDUK_ASSERT(prev_env != NULL);\n\t\tact->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, prev_env);\n\t\tDUK_CAT_CLEAR_LEXENV_ACTIVE(cat);\n\t\tDUK_HOBJECT_INCREF(thr, act->lex_env);\n\t\tDUK_HOBJECT_DECREF(thr, prev_env);  /* side effects */\n\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t}\n\n\tpc_base = cat->pc_base;\n\n\tif (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDCATCH: finally part is active, jump through 2nd jump slot with 'normal continuation'\"));\n\n\t\ttv1 = thr->valstack + cat->idx_base;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\ttv1 = thr->valstack + cat->idx_base + 1;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_U32_UPDREF(thr, tv1, (duk_uint32_t) DUK_LJ_TYPE_NORMAL);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\tDUK_CAT_CLEAR_FINALLY_ENABLED(cat);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDCATCH: no finally part, dismantle catcher, jump through 2nd jump slot (to end of statement)\"));\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t\t/* no need to unwind callstack */\n\t}\n\n\treturn pc_base + 1;  /* new curr_pc value */\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_small_uint_t duk__handle_op_endfin(duk_hthread *thr, duk_uint_fast32_t ins, duk_activation *entry_act) {\n\tduk_activation *act;\n\tduk_tval *tv1;\n\tduk_uint_t reg_catch;\n\tduk_small_uint_t cont_type;\n\tduk_small_uint_t ret_result;\n\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\treg_catch = DUK_DEC_ABC(ins);\n\n\t/* CATCH flag may be enabled or disabled here; it may be enabled if\n\t * the statement has a catch block but the try block does not throw\n\t * an error.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: completion value=%!T, type=%!T\",\n\t                     (duk_tval *) (thr->valstack_bottom + reg_catch + 0),\n\t                     (duk_tval *) (thr->valstack_bottom + reg_catch + 1)));\n\n\ttv1 = thr->valstack_bottom + reg_catch + 1;  /* type */\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\tcont_type = (duk_small_uint_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\tcont_type = (duk_small_uint_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\n\ttv1--;  /* value */\n\n\tswitch (cont_type) {\n\tcase DUK_LJ_TYPE_NORMAL: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: finally part finishing with 'normal' (non-abrupt) completion -> \"\n\t\t                     \"dismantle catcher, resume execution after ENDFIN\"));\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t\t/* no need to unwind callstack */\n\t\treturn 0;  /* restart execution */\n\t}\n\tcase DUK_LJ_TYPE_RETURN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: finally part finishing with 'return' complation -> dismantle \"\n\t\t                     \"catcher, handle return, lj.value1=%!T\", tv1));\n\n\t\t/* Not necessary to unwind catch stack: return handling will\n\t\t * do it.  The finally flag of 'cat' is no longer set.  The\n\t\t * catch flag may be set, but it's not checked by return handling.\n\t\t */\n\n\t\tduk_push_tval(thr, tv1);\n\t\tret_result = duk__handle_return(thr, entry_act);\n\t\tif (ret_result == DUK__RETHAND_RESTART) {\n\t\t\treturn 0;  /* restart execution */\n\t\t}\n\t\tDUK_ASSERT(ret_result == DUK__RETHAND_FINISHED);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"exiting executor after ENDFIN and RETURN (pseudo) longjmp type\"));\n\t\treturn 1;  /* exit executor */\n\t}\n\tcase DUK_LJ_TYPE_BREAK:\n\tcase DUK_LJ_TYPE_CONTINUE: {\n\t\tduk_uint_t label_id;\n\t\tduk_small_uint_t lj_type;\n\n\t\t/* Not necessary to unwind catch stack: break/continue\n\t\t * handling will do it.  The finally flag of 'cat' is\n\t\t * no longer set.  The catch flag may be set, but it's\n\t\t * not checked by break/continue handling.\n\t\t */\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\tlabel_id = (duk_small_uint_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\t\tlabel_id = (duk_small_uint_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\tlj_type = cont_type;\n\t\tduk__handle_break_or_continue(thr, label_id, lj_type);\n\t\treturn 0;  /* restart execution */\n\t}\n\tdefault: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: finally part finishing with abrupt completion, lj_type=%ld -> \"\n\t\t                     \"dismantle catcher, re-throw error\",\n\t\t                     (long) cont_type));\n\n\t\tduk_err_setup_ljstate1(thr, (duk_small_uint_t) cont_type, tv1);\n\t\t/* No debugger Throw notify check on purpose (rethrow). */\n\n\t\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* always in executor */\n\t\tduk_err_longjmp(thr);\n\t\tDUK_UNREACHABLE();\n\t}\n\t}\n\n\tDUK_UNREACHABLE();\n\treturn 0;\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_initenum(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_small_uint_t b;\n\tduk_small_uint_t c;\n\n\t/*\n\t *  Enumeration semantics come from for-in statement, E5 Section 12.6.4.\n\t *  If called with 'null' or 'undefined', this opcode returns 'null' as\n\t *  the enumerator, which is special cased in NEXTENUM.  This simplifies\n\t *  the compiler part\n\t */\n\n\t/* B -> register for writing enumerator object\n\t * C -> value to be enumerated (register)\n\t */\n\tb = DUK_DEC_B(ins);\n\tc = DUK_DEC_C(ins);\n\n\tif (duk_is_null_or_undefined(thr, (duk_idx_t) c)) {\n\t\tduk_push_null(thr);\n\t\tduk_replace(thr, (duk_idx_t) b);\n\t} else {\n\t\tduk_dup(thr, (duk_idx_t) c);\n\t\tduk_to_object(thr, -1);\n\t\tduk_hobject_enumerator_create(thr, 0 /*enum_flags*/);  /* [ ... val ] --> [ ... enum ] */\n\t\tduk_replace(thr, (duk_idx_t) b);\n\t}\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_small_uint_t duk__handle_op_nextenum(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_small_uint_t b;\n\tduk_small_uint_t c;\n\tduk_small_uint_t pc_skip = 0;\n\n\t/*\n\t *  NEXTENUM checks whether the enumerator still has unenumerated\n\t *  keys.  If so, the next key is loaded to the target register\n\t *  and the next instruction is skipped.  Otherwise the next instruction\n\t *  will be executed, jumping out of the enumeration loop.\n\t */\n\n\t/* B -> target register for next key\n\t * C -> enum register\n\t */\n\tb = DUK_DEC_B(ins);\n\tc = DUK_DEC_C(ins);\n\n\tDUK_DDD(DUK_DDDPRINT(\"NEXTENUM: b->%!T, c->%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, (duk_idx_t) b),\n\t                     (duk_tval *) duk_get_tval(thr, (duk_idx_t) c)));\n\n\tif (duk_is_object(thr, (duk_idx_t) c)) {\n\t\t/* XXX: assert 'c' is an enumerator */\n\t\tduk_dup(thr, (duk_idx_t) c);\n\t\tif (duk_hobject_enumerator_next(thr, 0 /*get_value*/)) {\n\t\t\t/* [ ... enum ] -> [ ... next_key ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"enum active, next key is %!T, skip jump slot \",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tpc_skip = 1;\n\t\t} else {\n\t\t\t/* [ ... enum ] -> [ ... ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"enum finished, execute jump slot\"));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* valstack policy */\n\t\t\tthr->valstack_top++;\n\t\t}\n\t\tduk_replace(thr, (duk_idx_t) b);\n\t} else {\n\t\t/* 'null' enumerator case -> behave as with an empty enumerator */\n\t\tDUK_ASSERT(duk_is_null(thr, (duk_idx_t) c));\n\t\tDUK_DDD(DUK_DDDPRINT(\"enum is null, execute jump slot\"));\n\t}\n\n\treturn pc_skip;\n}\n\n/*\n *  Call handling helpers.\n */\n\nDUK_LOCAL duk_bool_t duk__executor_handle_call(duk_hthread *thr, duk_idx_t idx, duk_idx_t nargs, duk_small_uint_t call_flags) {\n\tduk_bool_t rc;\n\n\tduk_set_top_unsafe(thr, (duk_idx_t) (idx + nargs + 2));   /* [ ... func this arg1 ... argN ] */\n\n\t/* Attempt an Ecma-to-Ecma call setup.  If the call\n\t * target is (directly or indirectly) Reflect.construct(),\n\t * the call may change into a constructor call on the fly.\n\t */\n\trc = (duk_bool_t) duk_handle_call_unprotected(thr, idx, call_flags);\n\tif (rc != 0) {\n\t\t/* Ecma-to-ecma call possible, may or may not\n\t\t * be a tail call.  Avoid C recursion by\n\t\t * reusing current executor instance.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"ecma-to-ecma call setup possible, restart execution\"));\n\t\t/* curr_pc synced by duk_handle_call_unprotected() */\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\treturn rc;\n\t} else {\n\t\t/* Call was handled inline. */\n\t}\n\tDUK_ASSERT(thr->ptr_curr_pc != NULL);\n\treturn rc;\n}\n\n/*\n *  ECMAScript bytecode executor.\n *\n *  Resume execution for the current thread from its current activation.\n *  Returns when execution would return from the entry level activation,\n *  leaving a single return value on top of the stack.  Function calls\n *  and thread resumptions are handled internally.  If an error occurs,\n *  a longjmp() with type DUK_LJ_TYPE_THROW is called on the entry level\n *  setjmp() jmpbuf.\n *\n *  ECMAScript function calls and coroutine resumptions are handled\n *  internally (by the outer executor function) without recursive C calls.\n *  Other function calls are handled using duk_handle_call(), increasing\n *  C recursion depth.\n *\n *  Abrupt completions (= long control tranfers) are handled either\n *  directly by reconfiguring relevant stacks and restarting execution,\n *  or via a longjmp.  Longjmp-free handling is preferable for performance\n *  (especially Emscripten performance), and is used for: break, continue,\n *  and return.\n *\n *  For more detailed notes, see doc/execution.rst.\n *\n *  Also see doc/code-issues.rst for discussion of setjmp(), longjmp(),\n *  and volatile.\n */\n\n/* Presence of 'fun' is config based, there's a marginal performance\n * difference and the best option is architecture dependent.\n */\n#if defined(DUK_USE_EXEC_FUN_LOCAL)\n#define DUK__FUN()          fun\n#else\n#define DUK__FUN()          ((duk_hcompfunc *) DUK_ACT_GET_FUNC((thr)->callstack_curr))\n#endif\n\n/* Strict flag. */\n#define DUK__STRICT()       ((duk_small_uint_t) DUK_HOBJECT_HAS_STRICT((duk_hobject *) DUK__FUN()))\n\n/* Reg/const access macros: these are very footprint and performance sensitive\n * so modify with care.  Arguments are sometimes evaluated multiple times which\n * is not ideal.\n */\n#define DUK__REG(x)         (*(thr->valstack_bottom + (x)))\n#define DUK__REGP(x)        (thr->valstack_bottom + (x))\n#define DUK__CONST(x)       (*(consts + (x)))\n#define DUK__CONSTP(x)      (consts + (x))\n\n/* Reg/const access macros which take the 32-bit instruction and avoid an\n * explicit field decoding step by using shifts and masks.  These must be\n * kept in sync with duk_js_bytecode.h.  The shift/mask values are chosen\n * so that 'ins' can be shifted and masked and used as a -byte- offset\n * instead of a duk_tval offset which needs further shifting (which is an\n * issue on some, but not all, CPUs).\n */\n#define DUK__RCBIT_B           DUK_BC_REGCONST_B\n#define DUK__RCBIT_C           DUK_BC_REGCONST_C\n#if defined(DUK_USE_EXEC_REGCONST_OPTIMIZE)\n#if defined(DUK_USE_PACKED_TVAL)\n#define DUK__TVAL_SHIFT        3  /* sizeof(duk_tval) == 8 */\n#else\n#define DUK__TVAL_SHIFT        4  /* sizeof(duk_tval) == 16; not always the case so also asserted for */\n#endif\n#define DUK__SHIFT_A           (DUK_BC_SHIFT_A - DUK__TVAL_SHIFT)\n#define DUK__SHIFT_B           (DUK_BC_SHIFT_B - DUK__TVAL_SHIFT)\n#define DUK__SHIFT_C           (DUK_BC_SHIFT_C - DUK__TVAL_SHIFT)\n#define DUK__SHIFT_BC          (DUK_BC_SHIFT_BC - DUK__TVAL_SHIFT)\n#define DUK__MASK_A            (DUK_BC_UNSHIFTED_MASK_A << DUK__TVAL_SHIFT)\n#define DUK__MASK_B            (DUK_BC_UNSHIFTED_MASK_B << DUK__TVAL_SHIFT)\n#define DUK__MASK_C            (DUK_BC_UNSHIFTED_MASK_C << DUK__TVAL_SHIFT)\n#define DUK__MASK_BC           (DUK_BC_UNSHIFTED_MASK_BC << DUK__TVAL_SHIFT)\n#define DUK__BYTEOFF_A(ins)    (((ins) >> DUK__SHIFT_A) & DUK__MASK_A)\n#define DUK__BYTEOFF_B(ins)    (((ins) >> DUK__SHIFT_B) & DUK__MASK_B)\n#define DUK__BYTEOFF_C(ins)    (((ins) >> DUK__SHIFT_C) & DUK__MASK_C)\n#define DUK__BYTEOFF_BC(ins)   (((ins) >> DUK__SHIFT_BC) & DUK__MASK_BC)\n\n#define DUK__REGP_A(ins)       ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_A((ins))))\n#define DUK__REGP_B(ins)       ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_B((ins))))\n#define DUK__REGP_C(ins)       ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_C((ins))))\n#define DUK__REGP_BC(ins)      ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_BC((ins))))\n#define DUK__CONSTP_A(ins)     ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_A((ins))))\n#define DUK__CONSTP_B(ins)     ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_B((ins))))\n#define DUK__CONSTP_C(ins)     ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_C((ins))))\n#define DUK__CONSTP_BC(ins)    ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_BC((ins))))\n#define DUK__REGCONSTP_B(ins)  ((duk_tval *) (void *) ((duk_uint8_t *) (((ins) & DUK__RCBIT_B) ? consts : thr->valstack_bottom) + DUK__BYTEOFF_B((ins))))\n#define DUK__REGCONSTP_C(ins)  ((duk_tval *) (void *) ((duk_uint8_t *) (((ins) & DUK__RCBIT_C) ? consts : thr->valstack_bottom) + DUK__BYTEOFF_C((ins))))\n#else  /* DUK_USE_EXEC_REGCONST_OPTIMIZE */\n/* Safe alternatives, no assumption about duk_tval size. */\n#define DUK__REGP_A(ins)       DUK__REGP(DUK_DEC_A((ins)))\n#define DUK__REGP_B(ins)       DUK__REGP(DUK_DEC_B((ins)))\n#define DUK__REGP_C(ins)       DUK__REGP(DUK_DEC_C((ins)))\n#define DUK__REGP_BC(ins)      DUK__REGP(DUK_DEC_BC((ins)))\n#define DUK__CONSTP_A(ins)     DUK__CONSTP(DUK_DEC_A((ins)))\n#define DUK__CONSTP_B(ins)     DUK__CONSTP(DUK_DEC_B((ins)))\n#define DUK__CONSTP_C(ins)     DUK__CONSTP(DUK_DEC_C((ins)))\n#define DUK__CONSTP_BC(ins)    DUK__CONSTP(DUK_DEC_BC((ins)))\n#define DUK__REGCONSTP_B(ins)  ((((ins) & DUK__RCBIT_B) ? consts : thr->valstack_bottom) + DUK_DEC_B((ins)))\n#define DUK__REGCONSTP_C(ins)  ((((ins) & DUK__RCBIT_C) ? consts : thr->valstack_bottom) + DUK_DEC_C((ins)))\n#endif  /* DUK_USE_EXEC_REGCONST_OPTIMIZE */\n\n#if defined(DUK_USE_VERBOSE_EXECUTOR_ERRORS)\n#define DUK__INTERNAL_ERROR(msg)  do { \\\n\t\tDUK_ERROR_ERROR(thr, (msg)); \\\n\t\tDUK_WO_NORETURN(return;); \\\n\t} while (0)\n#else\n#define DUK__INTERNAL_ERROR(msg)  do { \\\n\t\tgoto internal_error; \\\n\t} while (0)\n#endif\n\n#define DUK__SYNC_CURR_PC()  do { \\\n\t\tduk_activation *duk__act; \\\n\t\tduk__act = thr->callstack_curr; \\\n\t\tduk__act->curr_pc = curr_pc; \\\n\t} while (0)\n#define DUK__SYNC_AND_NULL_CURR_PC()  do { \\\n\t\tduk_activation *duk__act; \\\n\t\tduk__act = thr->callstack_curr; \\\n\t\tduk__act->curr_pc = curr_pc; \\\n\t\tthr->ptr_curr_pc = NULL; \\\n\t} while (0)\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n#define DUK__LOOKUP_INDIRECT(idx) do { \\\n\t\t(idx) = (duk_uint_fast_t) duk_get_uint(thr, (duk_idx_t) (idx)); \\\n\t} while (0)\n#elif defined(DUK_USE_FASTINT)\n#define DUK__LOOKUP_INDIRECT(idx) do { \\\n\t\tduk_tval *tv_ind; \\\n\t\ttv_ind = DUK__REGP((idx)); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_ind)); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv_ind));  /* compiler guarantees */ \\\n\t\t(idx) = (duk_uint_fast_t) DUK_TVAL_GET_FASTINT_U32(tv_ind); \\\n\t} while (0)\n#else\n#define DUK__LOOKUP_INDIRECT(idx) do { \\\n\t\tduk_tval *tv_ind; \\\n\t\ttv_ind = DUK__REGP(idx); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_ind)); \\\n\t\tidx = (duk_uint_fast_t) DUK_TVAL_GET_NUMBER(tv_ind); \\\n\t} while (0)\n#endif\n\nDUK_LOCAL void duk__handle_executor_error(duk_heap *heap,\n                                          duk_activation *entry_act,\n                                          duk_int_t entry_call_recursion_depth,\n                                          duk_jmpbuf *entry_jmpbuf_ptr,\n                                          volatile duk_bool_t *out_delayed_catch_setup) {\n\tduk_small_uint_t lj_ret;\n\n\t/* Longjmp callers are required to sync-and-null thr->ptr_curr_pc\n\t * before longjmp.\n\t */\n\tDUK_ASSERT(heap->curr_thread != NULL);\n\tDUK_ASSERT(heap->curr_thread->ptr_curr_pc == NULL);\n\n\t/* XXX: signalling the need to shrink check (only if unwound) */\n\n\t/* Must be restored here to handle e.g. yields properly. */\n\theap->call_recursion_depth = entry_call_recursion_depth;\n\n\t/* Switch to caller's setjmp() catcher so that if an error occurs\n\t * during error handling, it is always propagated outwards instead\n\t * of causing an infinite loop in our own handler.\n\t */\n\theap->lj.jmpbuf_ptr = (duk_jmpbuf *) entry_jmpbuf_ptr;\n\n\tlj_ret = duk__handle_longjmp(heap->curr_thread, entry_act, out_delayed_catch_setup);\n\n\t/* Error handling complete, remove side effect protections.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(heap->error_not_allowed == 1);\n\theap->error_not_allowed = 0;\n#endif\n\tDUK_ASSERT(heap->pf_prevent_count > 0);\n\theap->pf_prevent_count--;\n\tDUK_DD(DUK_DDPRINT(\"executor error handled, pf_prevent_count updated to %ld\", (long) heap->pf_prevent_count));\n\n\tif (lj_ret == DUK__LONGJMP_RESTART) {\n\t\t/* Restart bytecode execution, possibly with a changed thread. */\n\t\tDUK_REFZERO_CHECK_SLOW(heap->curr_thread);\n\t} else {\n\t\t/* If an error is propagated, don't run refzero checks here.\n\t\t * The next catcher will deal with that.  Pf_prevent_count\n\t\t * will be re-bumped by the longjmp.\n\t\t */\n\n\t\tDUK_ASSERT(lj_ret == DUK__LONGJMP_RETHROW);  /* Rethrow error to calling state. */\n\t\tDUK_ASSERT(heap->lj.jmpbuf_ptr == entry_jmpbuf_ptr);  /* Longjmp handling has restored jmpbuf_ptr. */\n\n\t\t/* Thread may have changed, e.g. YIELD converted to THROW. */\n\t\tduk_err_longjmp(heap->curr_thread);\n\t\tDUK_UNREACHABLE();\n\t}\n}\n\n/* Outer executor with setjmp/longjmp handling. */\nDUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {\n\t/* Entry level info. */\n\tduk_hthread *entry_thread;\n\tduk_activation *entry_act;\n\tduk_int_t entry_call_recursion_depth;\n\tduk_jmpbuf *entry_jmpbuf_ptr;\n\tduk_jmpbuf our_jmpbuf;\n\tduk_heap *heap;\n\tvolatile duk_bool_t delayed_catch_setup = 0;\n\n\tDUK_ASSERT(exec_thr != NULL);\n\tDUK_ASSERT(exec_thr->heap != NULL);\n\tDUK_ASSERT(exec_thr->heap->curr_thread != NULL);\n\tDUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR((duk_heaphdr *) exec_thr);\n\tDUK_ASSERT(exec_thr->callstack_top >= 1);  /* at least one activation, ours */\n\tDUK_ASSERT(exec_thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(exec_thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(exec_thr->callstack_curr)));\n\n\tDUK_GC_TORTURE(exec_thr->heap);\n\n\tentry_thread = exec_thr;\n\theap = entry_thread->heap;\n\tentry_act = entry_thread->callstack_curr;\n\tDUK_ASSERT(entry_act != NULL);\n\tentry_call_recursion_depth = entry_thread->heap->call_recursion_depth;\n\tentry_jmpbuf_ptr = entry_thread->heap->lj.jmpbuf_ptr;\n\n\t/*\n\t *  Note: we currently assume that the setjmp() catchpoint is\n\t *  not re-entrant (longjmp() cannot be called more than once\n\t *  for a single setjmp()).\n\t *\n\t *  See doc/code-issues.rst for notes on variable assignment\n\t *  before and after setjmp().\n\t */\n\n\tfor (;;) {\n\t\theap->lj.jmpbuf_ptr = &our_jmpbuf;\n\t\tDUK_ASSERT(heap->lj.jmpbuf_ptr != NULL);\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\ttry {\n#else\n\t\tDUK_ASSERT(heap->lj.jmpbuf_ptr == &our_jmpbuf);\n\t\tif (DUK_SETJMP(our_jmpbuf.jb) == 0) {\n#endif\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"after setjmp, delayed catch setup: %ld\\n\", (long) delayed_catch_setup));\n\n\t\t\tif (DUK_UNLIKELY(delayed_catch_setup != 0)) {\n\t\t\t\tduk_hthread *thr = entry_thread->heap->curr_thread;\n\n\t\t\t\tdelayed_catch_setup = 0;\n\t\t\t\tduk__handle_catch_part2(thr);\n\t\t\t\tDUK_ASSERT(delayed_catch_setup == 0);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"top after delayed catch setup: %ld\", (long) duk_get_top(entry_thread)));\n\t\t\t}\n\n\t\t\t/* Execute bytecode until returned or longjmp(). */\n\t\t\tduk__js_execute_bytecode_inner(entry_thread, entry_act);\n\n\t\t\t/* Successful return: restore jmpbuf and return to caller. */\n\t\t\theap->lj.jmpbuf_ptr = entry_jmpbuf_ptr;\n\n\t\t\treturn;\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\t} catch (duk_internal_exception &exc) {\n#else\n\t\t} else {\n#endif\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\t\tDUK_UNREF(exc);\n#endif\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"longjmp caught by bytecode executor\"));\n\t\t\tDUK_STATS_INC(exec_thr->heap, stats_exec_throw);\n\n\t\t\tduk__handle_executor_error(heap,\n\t\t\t                           entry_act,\n\t\t\t                           entry_call_recursion_depth,\n\t\t\t                           entry_jmpbuf_ptr,\n\t\t\t\t\t\t   &delayed_catch_setup);\n\t\t}\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\tcatch (duk_fatal_exception &exc) {\n\t\t\tDUK_D(DUK_DPRINT(\"rethrow duk_fatal_exception\"));\n\t\t\tthrow;\n\t\t} catch (std::exception &exc) {\n\t\t\tconst char *what = exc.what();\n\t\t\tif (!what) {\n\t\t\t\twhat = \"unknown\";\n\t\t\t}\n\t\t\tDUK_D(DUK_DPRINT(\"unexpected c++ std::exception (perhaps thrown by user code)\"));\n\t\t\tDUK_STATS_INC(exec_thr->heap, stats_exec_throw);\n\t\t\ttry {\n\t\t\t\tDUK_ASSERT(heap->curr_thread != NULL);\n\t\t\t\tDUK_ERROR_FMT1(heap->curr_thread, DUK_ERR_TYPE_ERROR, \"caught invalid c++ std::exception '%s' (perhaps thrown by user code)\", what);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t} catch (duk_internal_exception exc) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ std::exception\"));\n\t\t\t\tDUK_UNREF(exc);\n\t\t\t\tduk__handle_executor_error(heap,\n\t\t\t\t                           entry_act,\n\t\t\t\t                           entry_call_recursion_depth,\n\t\t\t\t                           entry_jmpbuf_ptr,\n\t\t\t\t\t\t\t   &delayed_catch_setup);\n\t\t\t}\n\t\t} catch (...) {\n\t\t\tDUK_D(DUK_DPRINT(\"unexpected c++ exception (perhaps thrown by user code)\"));\n\t\t\tDUK_STATS_INC(exec_thr->heap, stats_exec_throw);\n\t\t\ttry {\n\t\t\t\tDUK_ASSERT(heap->curr_thread != NULL);\n\t\t\t\tDUK_ERROR_TYPE(heap->curr_thread, \"caught invalid c++ exception (perhaps thrown by user code)\");\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t} catch (duk_internal_exception exc) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ exception\"));\n\t\t\t\tDUK_UNREF(exc);\n\t\t\t\tduk__handle_executor_error(heap,\n\t\t\t\t                           entry_act,\n\t\t\t\t                           entry_call_recursion_depth,\n\t\t\t\t                           entry_jmpbuf_ptr,\n\t\t\t\t\t\t\t   &delayed_catch_setup);\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Inner executor, performance critical. */\nDUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, duk_activation *entry_act) {\n\t/* Current PC, accessed by other functions through thr->ptr_to_curr_pc.\n\t * Critical for performance.  It would be safest to make this volatile,\n\t * but that eliminates performance benefits; aliasing guarantees\n\t * should be enough though.\n\t */\n\tduk_instr_t *curr_pc;         /* bytecode has a stable pointer */\n\n\t/* Hot variables for interpretation.  Critical for performance,\n\t * but must add sparingly to minimize register shuffling.\n\t */\n\tduk_hthread *thr;             /* stable */\n\tduk_tval *consts;             /* stable */\n\tduk_uint_fast32_t ins;\n\t/* 'funcs' is quite rarely used, so no local for it */\n#if defined(DUK_USE_EXEC_FUN_LOCAL)\n\tduk_hcompfunc *fun;\n#else\n\t/* 'fun' is quite rarely used, so no local for it */\n#endif\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\tduk_int_t int_ctr;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_size_t valstack_top_base;    /* valstack top, should match before interpreting each op (no leftovers) */\n#endif\n\n\t/* Optimized reg/const access macros assume sizeof(duk_tval) to be\n\t * either 8 or 16.  Heap allocation checks this even without asserts\n\t * enabled now because it can't be autodetected in duk_config.h.\n\t */\n#if 1\n#if defined(DUK_USE_PACKED_TVAL)\n\tDUK_ASSERT(sizeof(duk_tval) == 8);\n#else\n\tDUK_ASSERT(sizeof(duk_tval) == 16);\n#endif\n#endif\n\n\tDUK_GC_TORTURE(entry_thread->heap);\n\n\t/*\n\t *  Restart execution by reloading thread state.\n\t *\n\t *  Note that 'thr' and any thread configuration may have changed,\n\t *  so all local variables are suspect and we need to reinitialize.\n\t *\n\t *  The number of local variables should be kept to a minimum: if\n\t *  the variables are spilled, they will need to be loaded from\n\t *  memory anyway.\n\t *\n\t *  Any 'goto restart_execution;' code path in opcode dispatch must\n\t *  ensure 'curr_pc' is synced back to act->curr_pc before the goto\n\t *  takes place.\n\t *\n\t *  The interpreter must be very careful with memory pointers, as\n\t *  many pointers are not guaranteed to be 'stable' and may be\n\t *  reallocated and relocated on-the-fly quite easily (e.g. by a\n\t *  memory allocation or a property access).\n\t *\n\t *  The following are assumed to have stable pointers:\n\t *    - the current thread\n\t *    - the current function\n\t *    - the bytecode, constant table, inner function table of the\n\t *      current function (as they are a part of the function allocation)\n\t *\n\t *  The following are assumed to have semi-stable pointers:\n\t *    - the current activation entry: stable as long as callstack\n\t *      is not changed (reallocated by growing or shrinking), or\n\t *      by any garbage collection invocation (through finalizers)\n\t *    - Note in particular that ANY DECREF can invalidate the\n\t *      activation pointer, so for the most part a fresh lookup\n\t *      is required\n\t *\n\t *  The following are not assumed to have stable pointers at all:\n\t *    - the value stack (registers) of the current thread\n\t *\n\t *  See execution.rst for discussion.\n\t */\n\n restart_execution:\n\n\t/* Lookup current thread; use the stable 'entry_thread' for this to\n\t * avoid clobber warnings.  Any valid, reachable 'thr' value would be\n\t * fine for this, so using 'entry_thread' is just to silence warnings.\n\t */\n\tthr = entry_thread->heap->curr_thread;\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\tDUK_GC_TORTURE(thr->heap);\n\n\tthr->ptr_curr_pc = &curr_pc;\n\n\t/* Relookup and initialize dispatch loop variables.  Debugger check. */\n\t{\n\t\tduk_activation *act;\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\tduk_hcompfunc *fun;\n#endif\n\n\t\t/* Assume interrupt init/counter are properly initialized here. */\n\t\t/* Assume that thr->valstack_bottom has been set-up before getting here. */\n\n\t\tact = thr->callstack_curr;\n\t\tDUK_ASSERT(act != NULL);\n\t\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\t\tDUK_ASSERT(fun != NULL);\n\t\tDUK_ASSERT(thr->valstack_top - thr->valstack_bottom == fun->nregs);\n\t\tconsts = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, fun);\n\t\tDUK_ASSERT(consts != NULL);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tif (DUK_UNLIKELY(duk_debug_is_attached(thr->heap) && !thr->heap->dbg_processing)) {\n\t\t\tduk__executor_recheck_debugger(thr, act, fun);\n\t\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\tvalstack_top_base = (duk_size_t) (thr->valstack_top - thr->valstack);\n#endif\n\n\t\t/* Set up curr_pc for opcode dispatch. */\n\t\tcurr_pc = act->curr_pc;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"restarting execution, thr %p, act idx %ld, fun %p,\"\n\t                   \"consts %p, funcs %p, lev %ld, regbot %ld, regtop %ld, \"\n\t                   \"preventcount=%ld\",\n\t                   (void *) thr,\n\t                   (long) (thr->callstack_top - 1),\n\t                   (void *) DUK__FUN(),\n\t                   (void *) DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, DUK__FUN()),\n\t                   (void *) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, DUK__FUN()),\n\t                   (long) (thr->callstack_top - 1),\n\t                   (long) (thr->valstack_bottom - thr->valstack),\n\t                   (long) (thr->valstack_top - thr->valstack),\n\t                   (long) thr->callstack_preventcount));\n\n\t/* Dispatch loop. */\n\n\tfor (;;) {\n\t\tduk_uint8_t op;\n\n\t\tDUK_ASSERT(thr->callstack_top >= 1);\n\t\tDUK_ASSERT(thr->valstack_top - thr->valstack_bottom == DUK__FUN()->nregs);\n\t\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack) == valstack_top_base);\n\n\t\t/* Executor interrupt counter check, used to implement breakpoints,\n\t\t * debugging interface, execution timeouts, etc.  The counter is heap\n\t\t * specific but is maintained in the current thread to make the check\n\t\t * as fast as possible.  The counter is copied back to the heap struct\n\t\t * whenever a thread switch occurs by the DUK_HEAP_SWITCH_THREAD() macro.\n\t\t */\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\t\tint_ctr = thr->interrupt_counter;\n\t\tif (DUK_LIKELY(int_ctr > 0)) {\n\t\t\tthr->interrupt_counter = int_ctr - 1;\n\t\t} else {\n\t\t\t/* Trigger at zero or below */\n\t\t\tduk_small_uint_t exec_int_ret;\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_exec_interrupt);\n\n\t\t\t/* Write curr_pc back for the debugger. */\n\t\t\t{\n\t\t\t\tduk_activation *act;\n\t\t\t\tDUK_ASSERT(thr->callstack_top > 0);\n\t\t\t\tact = thr->callstack_curr;\n\t\t\t\tDUK_ASSERT(act != NULL);\n\t\t\t\tact->curr_pc = (duk_instr_t *) curr_pc;\n\t\t\t}\n\n\t\t\t/* Forced restart caused by a function return; must recheck\n\t\t\t * debugger breakpoints before checking line transitions,\n\t\t\t * see GH-303.  Restart and then handle interrupt_counter\n\t\t\t * zero again.\n\t\t\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\t\tif (thr->heap->dbg_force_restart) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"dbg_force_restart flag forced restart execution\"));  /* GH-303 */\n\t\t\t\tthr->heap->dbg_force_restart = 0;\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n#endif\n\n\t\t\texec_int_ret = duk__executor_interrupt(thr);\n\t\t\tif (exec_int_ret == DUK__INT_RESTART) {\n\t\t\t\t/* curr_pc synced back above */\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n\t\t}\n#endif  /* DUK_USE_INTERRUPT_COUNTER */\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\t\t/* For cross-checking during development: ensure dispatch count\n\t\t * matches cumulative interrupt counter init value sums.\n\t\t */\n\t\tthr->heap->inst_count_exec++;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS) || defined(DUK_USE_DEBUG)\n\t\t{\n\t\t\tduk_activation *act;\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(curr_pc >= DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, DUK__FUN()));\n\t\t\tDUK_ASSERT(curr_pc < DUK_HCOMPFUNC_GET_CODE_END(thr->heap, DUK__FUN()));\n\t\t\tDUK_UNREF(act);  /* if debugging disabled */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"executing bytecode: pc=%ld, ins=0x%08lx, op=%ld, valstack_top=%ld/%ld, nregs=%ld  -->  %!I\",\n\t\t\t                     (long) (curr_pc - DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, DUK__FUN())),\n\t\t\t                     (unsigned long) *curr_pc,\n\t\t\t                     (long) DUK_DEC_OP(*curr_pc),\n\t\t\t                     (long) (thr->valstack_top - thr->valstack),\n\t\t\t                     (long) (thr->valstack_end - thr->valstack),\n\t\t\t                     (long) (DUK__FUN() ? DUK__FUN()->nregs : -1),\n\t\t\t                     (duk_instr_t) *curr_pc));\n\t\t}\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\t/* Quite heavy assert: check valstack policy.  Improper\n\t\t * shuffle instructions can write beyond valstack_top/end\n\t\t * so this check catches them in the act.\n\t\t */\n\t\t{\n\t\t\tduk_tval *tv;\n\t\t\ttv = thr->valstack_top;\n\t\t\twhile (tv != thr->valstack_end) {\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\t\t\ttv++;\n\t\t\t}\n\t\t}\n#endif\n\n\t\tins = *curr_pc++;\n\t\tDUK_STATS_INC(thr->heap, stats_exec_opcodes);\n\n\t\t/* Typing: use duk_small_(u)int_fast_t when decoding small\n\t\t * opcode fields (op, A, B, C, BC) which fit into 16 bits\n\t\t * and duk_(u)int_fast_t when decoding larger fields (e.g.\n\t\t * ABC).  Use unsigned variant by default, signed when the\n\t\t * value is used in signed arithmetic.  Using variable names\n\t\t * such as 'a', 'b', 'c', 'bc', etc makes it easier to spot\n\t\t * typing mismatches.\n\t\t */\n\n\t\t/* Switch based on opcode.  Cast to 8-bit unsigned value and\n\t\t * use a fully populated case clauses so that the compiler\n\t\t * will (at least usually) omit a bounds check.\n\t\t */\n\t\top = (duk_uint8_t) DUK_DEC_OP(ins);\n\t\tswitch (op) {\n\n\t\t/* Some useful macros.  These access inner executor variables\n\t\t * directly so they only apply within the executor.\n\t\t */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n#define DUK__REPLACE_TOP_A_BREAK() { goto replace_top_a; }\n#define DUK__REPLACE_TOP_BC_BREAK() { goto replace_top_bc; }\n#define DUK__REPLACE_BOOL_A_BREAK(bval) { \\\n\t\tduk_bool_t duk__bval; \\\n\t\tduk__bval = (bval); \\\n\t\tDUK_ASSERT(duk__bval == 0 || duk__bval == 1); \\\n\t\tduk_push_boolean(thr, duk__bval); \\\n\t\tDUK__REPLACE_TOP_A_BREAK(); \\\n\t}\n#else\n#define DUK__REPLACE_TOP_A_BREAK() { DUK__REPLACE_TO_TVPTR(thr, DUK__REGP_A(ins)); break; }\n#define DUK__REPLACE_TOP_BC_BREAK() { DUK__REPLACE_TO_TVPTR(thr, DUK__REGP_BC(ins)); break; }\n#define DUK__REPLACE_BOOL_A_BREAK(bval) { \\\n\t\tduk_bool_t duk__bval; \\\n\t\tduk_tval *duk__tvdst; \\\n\t\tduk__bval = (bval); \\\n\t\tDUK_ASSERT(duk__bval == 0 || duk__bval == 1); \\\n\t\tduk__tvdst = DUK__REGP_A(ins); \\\n\t\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, duk__tvdst, duk__bval); \\\n\t\tbreak; \\\n\t}\n#endif\n\n\t\t/* XXX: 12 + 12 bit variant might make sense too, for both reg and\n\t\t * const loads.\n\t\t */\n\n\t\t/* For LDREG, STREG, LDCONST footprint optimized variants would just\n\t\t * duk_dup() + duk_replace(), but because they're used quite a lot\n\t\t * they're currently intentionally not size optimized.\n\t\t */\n\t\tcase DUK_OP_LDREG: {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\ttv2 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv1, tv2);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_STREG: {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\ttv2 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv2, tv1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_LDCONST: {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\ttv2 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv1, tv2);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\n\t\t/* LDINT and LDINTX are intended to load an arbitrary signed\n\t\t * 32-bit value.  Only an LDINT+LDINTX sequence is supported.\n\t\t * This also guarantees all values remain fastints.\n\t\t */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_LDINT: {\n\t\t\tduk_int32_t val;\n\n\t\t\tval = (duk_int32_t) DUK_DEC_BC(ins) - (duk_int32_t) DUK_BC_LDINT_BIAS;\n\t\t\tduk_push_int(thr, val);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n\t\tcase DUK_OP_LDINTX: {\n\t\t\tduk_int32_t val;\n\n\t\t\tval = (duk_int32_t) duk_get_int(thr, DUK_DEC_A(ins));\n\t\t\tval = (val << DUK_BC_LDINTX_SHIFT) + (duk_int32_t) DUK_DEC_BC(ins);  /* no bias */\n\t\t\tduk_push_int(thr, val);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_LDINT: {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_int32_t val;\n\n\t\t\tval = (duk_int32_t) DUK_DEC_BC(ins) - (duk_int32_t) DUK_BC_LDINT_BIAS;\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_I32_UPDREF(thr, tv1, val);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDINTX: {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_int32_t val;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\t\tval = DUK_TVAL_GET_FASTINT_I32(tv1);\n#else\n\t\t\t/* XXX: fast double-to-int conversion, we know number is integer in [-0x80000000,0xffffffff]. */\n\t\t\tval = (duk_int32_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\t\tval = (duk_int32_t) ((duk_uint32_t) val << DUK_BC_LDINTX_SHIFT) + (duk_int32_t) DUK_DEC_BC(ins);  /* no bias */\n\t\t\tDUK_TVAL_SET_I32_UPDREF(thr, tv1, val);  /* side effects */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_LDTHIS: {\n\t\t\tduk_push_this(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\t\tcase DUK_OP_LDUNDEF: {\n\t\t\tduk_to_undefined(thr, (duk_idx_t) DUK_DEC_BC(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDNULL: {\n\t\t\tduk_to_null(thr, (duk_idx_t) DUK_DEC_BC(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDTRUE: {\n\t\t\tduk_push_true(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\t\tcase DUK_OP_LDFALSE: {\n\t\t\tduk_push_false(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_LDTHIS: {\n\t\t\t/* Note: 'this' may be bound to any value, not just an object */\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\ttv2 = thr->valstack_bottom - 1;  /* 'this binding' is just under bottom */\n\t\t\tDUK_ASSERT(tv2 >= thr->valstack);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv1, tv2);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDUNDEF: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDNULL: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_NULL_UPDREF(thr, tv1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDTRUE: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv1, 1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDFALSE: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv1, 0);  /* side effects */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\tcase DUK_OP_BNOT: {\n\t\t\tduk__vm_bitwise_not(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_LNOT: {\n\t\t\tduk__vm_logical_not(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_UNM:\n\t\tcase DUK_OP_UNP: {\n\t\t\tduk__vm_arith_unary_op(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins), op);\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_UNM: {\n\t\t\tduk__vm_arith_unary_op(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins), DUK_OP_UNM);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_UNP: {\n\t\t\tduk__vm_arith_unary_op(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins), DUK_OP_UNP);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_TYPEOF: {\n\t\t\tduk_small_uint_t stridx;\n\n\t\t\tstridx = duk_js_typeof_stridx(DUK__REGP_BC(ins));\n\t\t\tDUK_ASSERT_STRIDX_VALID(stridx);\n\t\t\tduk_push_hstring_stridx(thr, stridx);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_TYPEOF: {\n\t\t\tduk_tval *tv;\n\t\t\tduk_small_uint_t stridx;\n\t\t\tduk_hstring *h_str;\n\n\t\t\ttv = DUK__REGP_BC(ins);\n\t\t\tstridx = duk_js_typeof_stridx(tv);\n\t\t\tDUK_ASSERT_STRIDX_VALID(stridx);\n\t\t\th_str = DUK_HTHREAD_GET_STRING(thr, stridx);\n\t\t\ttv = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_STRING_UPDREF(thr, tv, h_str);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\tcase DUK_OP_TYPEOFID: {\n\t\t\tduk_small_uint_t stridx;\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_hstring *h_str;\n#endif\n\t\t\tduk_activation *act;\n\t\t\tduk_hstring *name;\n\t\t\tduk_tval *tv;\n\n\t\t\t/* A -> target register\n\t\t\t * BC -> constant index of identifier name\n\t\t\t */\n\n\t\t\ttv = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv));\n\t\t\tname = DUK_TVAL_GET_STRING(tv);\n\t\t\ttv = NULL;  /* lookup has side effects */\n\t\t\tact = thr->callstack_curr;\n\t\t\tif (duk_js_getvar_activation(thr, act, name, 0 /*throw*/)) {\n\t\t\t\t/* -> [... val this] */\n\t\t\t\ttv = DUK_GET_TVAL_NEGIDX(thr, -2);\n\t\t\t\tstridx = duk_js_typeof_stridx(tv);\n\t\t\t\ttv = NULL;  /* no longer needed */\n\t\t\t\tduk_pop_2_unsafe(thr);\n\t\t\t} else {\n\t\t\t\t/* unresolvable, no stack changes */\n\t\t\t\tstridx = DUK_STRIDX_LC_UNDEFINED;\n\t\t\t}\n\t\t\tDUK_ASSERT_STRIDX_VALID(stridx);\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_push_hstring_stridx(thr, stridx);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\t\th_str = DUK_HTHREAD_GET_STRING(thr, stridx);\n\t\t\ttv = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_STRING_UPDREF(thr, tv, h_str);\n\t\t\tbreak;\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\t}\n\n\t\t/* Equality: E5 Sections 11.9.1, 11.9.3 */\n\n#define DUK__EQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_equals(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__NEQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_equals(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\ttmp ^= 1; \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__SEQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_strict_equals((barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__SNEQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_strict_equals((barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\ttmp ^= 1; \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_EQ_RR:\n\t\tcase DUK_OP_EQ_CR:\n\t\tcase DUK_OP_EQ_RC:\n\t\tcase DUK_OP_EQ_CC:\n\t\t\tDUK__EQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_NEQ_RR:\n\t\tcase DUK_OP_NEQ_CR:\n\t\tcase DUK_OP_NEQ_RC:\n\t\tcase DUK_OP_NEQ_CC:\n\t\t\tDUK__NEQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_SEQ_RR:\n\t\tcase DUK_OP_SEQ_CR:\n\t\tcase DUK_OP_SEQ_RC:\n\t\tcase DUK_OP_SEQ_CC:\n\t\t\tDUK__SEQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_SNEQ_RR:\n\t\tcase DUK_OP_SNEQ_CR:\n\t\tcase DUK_OP_SNEQ_RC:\n\t\tcase DUK_OP_SNEQ_CC:\n\t\t\tDUK__SNEQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_EQ_RR:\n\t\t\tDUK__EQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_EQ_CR:\n\t\t\tDUK__EQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_EQ_RC:\n\t\t\tDUK__EQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_EQ_CC:\n\t\t\tDUK__EQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_NEQ_RR:\n\t\t\tDUK__NEQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_NEQ_CR:\n\t\t\tDUK__NEQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_NEQ_RC:\n\t\t\tDUK__NEQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_NEQ_CC:\n\t\t\tDUK__NEQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SEQ_RR:\n\t\t\tDUK__SEQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SEQ_CR:\n\t\t\tDUK__SEQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SEQ_RC:\n\t\t\tDUK__SEQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SEQ_CC:\n\t\t\tDUK__SEQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SNEQ_RR:\n\t\t\tDUK__SNEQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SNEQ_CR:\n\t\t\tDUK__SNEQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SNEQ_RC:\n\t\t\tDUK__SNEQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SNEQ_CC:\n\t\t\tDUK__SNEQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#define DUK__COMPARE_BODY(arg1,arg2,flags) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_compare_helper(thr, (arg1), (arg2), (flags)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__GT_BODY(barg,carg) DUK__COMPARE_BODY((carg), (barg), 0)\n#define DUK__GE_BODY(barg,carg) DUK__COMPARE_BODY((barg), (carg), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST | DUK_COMPARE_FLAG_NEGATE)\n#define DUK__LT_BODY(barg,carg) DUK__COMPARE_BODY((barg), (carg), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST)\n#define DUK__LE_BODY(barg,carg) DUK__COMPARE_BODY((carg), (barg), DUK_COMPARE_FLAG_NEGATE)\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_GT_RR:\n\t\tcase DUK_OP_GT_CR:\n\t\tcase DUK_OP_GT_RC:\n\t\tcase DUK_OP_GT_CC:\n\t\t\tDUK__GT_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_GE_RR:\n\t\tcase DUK_OP_GE_CR:\n\t\tcase DUK_OP_GE_RC:\n\t\tcase DUK_OP_GE_CC:\n\t\t\tDUK__GE_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_LT_RR:\n\t\tcase DUK_OP_LT_CR:\n\t\tcase DUK_OP_LT_RC:\n\t\tcase DUK_OP_LT_CC:\n\t\t\tDUK__LT_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_LE_RR:\n\t\tcase DUK_OP_LE_CR:\n\t\tcase DUK_OP_LE_RC:\n\t\tcase DUK_OP_LE_CC:\n\t\t\tDUK__LE_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_GT_RR:\n\t\t\tDUK__GT_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GT_CR:\n\t\t\tDUK__GT_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GT_RC:\n\t\t\tDUK__GT_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GT_CC:\n\t\t\tDUK__GT_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GE_RR:\n\t\t\tDUK__GE_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GE_CR:\n\t\t\tDUK__GE_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GE_RC:\n\t\t\tDUK__GE_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GE_CC:\n\t\t\tDUK__GE_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LT_RR:\n\t\t\tDUK__LT_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LT_CR:\n\t\t\tDUK__LT_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LT_RC:\n\t\t\tDUK__LT_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LT_CC:\n\t\t\tDUK__LT_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LE_RR:\n\t\t\tDUK__LE_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LE_CR:\n\t\t\tDUK__LE_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LE_RC:\n\t\t\tDUK__LE_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LE_CC:\n\t\t\tDUK__LE_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* No size optimized variant at present for IF. */\n\t\tcase DUK_OP_IFTRUE_R: {\n\t\t\tif (duk_js_toboolean(DUK__REGP_BC(ins)) != 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_IFTRUE_C: {\n\t\t\tif (duk_js_toboolean(DUK__CONSTP_BC(ins)) != 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_IFFALSE_R: {\n\t\t\tif (duk_js_toboolean(DUK__REGP_BC(ins)) == 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_IFFALSE_C: {\n\t\t\tif (duk_js_toboolean(DUK__CONSTP_BC(ins)) == 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_ADD_RR:\n\t\tcase DUK_OP_ADD_CR:\n\t\tcase DUK_OP_ADD_RC:\n\t\tcase DUK_OP_ADD_CC: {\n\t\t\t/* XXX: could leave value on stack top and goto replace_top_a; */\n\t\t\tduk__vm_arith_add(thr, DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_ADD_RR: {\n\t\t\tduk__vm_arith_add(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_ADD_CR: {\n\t\t\tduk__vm_arith_add(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_ADD_RC: {\n\t\t\tduk__vm_arith_add(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_ADD_CC: {\n\t\t\tduk__vm_arith_add(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_SUB_RR:\n\t\tcase DUK_OP_SUB_CR:\n\t\tcase DUK_OP_SUB_RC:\n\t\tcase DUK_OP_SUB_CC:\n\t\tcase DUK_OP_MUL_RR:\n\t\tcase DUK_OP_MUL_CR:\n\t\tcase DUK_OP_MUL_RC:\n\t\tcase DUK_OP_MUL_CC:\n\t\tcase DUK_OP_DIV_RR:\n\t\tcase DUK_OP_DIV_CR:\n\t\tcase DUK_OP_DIV_RC:\n\t\tcase DUK_OP_DIV_CC:\n\t\tcase DUK_OP_MOD_RR:\n\t\tcase DUK_OP_MOD_CR:\n\t\tcase DUK_OP_MOD_RC:\n\t\tcase DUK_OP_MOD_CC:\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tcase DUK_OP_EXP_RR:\n\t\tcase DUK_OP_EXP_CR:\n\t\tcase DUK_OP_EXP_RC:\n\t\tcase DUK_OP_EXP_CC:\n#endif  /* DUK_USE_ES7_EXP_OPERATOR */\n\t\t{\n\t\t\t/* XXX: could leave value on stack top and goto replace_top_a; */\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins), DUK_DEC_A(ins), op);\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_SUB_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_SUB_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_SUB_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_SUB_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tcase DUK_OP_EXP_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_EXP_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_EXP_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_EXP_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_ES7_EXP_OPERATOR */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_BAND_RR:\n\t\tcase DUK_OP_BAND_CR:\n\t\tcase DUK_OP_BAND_RC:\n\t\tcase DUK_OP_BAND_CC:\n\t\tcase DUK_OP_BOR_RR:\n\t\tcase DUK_OP_BOR_CR:\n\t\tcase DUK_OP_BOR_RC:\n\t\tcase DUK_OP_BOR_CC:\n\t\tcase DUK_OP_BXOR_RR:\n\t\tcase DUK_OP_BXOR_CR:\n\t\tcase DUK_OP_BXOR_RC:\n\t\tcase DUK_OP_BXOR_CC:\n\t\tcase DUK_OP_BASL_RR:\n\t\tcase DUK_OP_BASL_CR:\n\t\tcase DUK_OP_BASL_RC:\n\t\tcase DUK_OP_BASL_CC:\n\t\tcase DUK_OP_BLSR_RR:\n\t\tcase DUK_OP_BLSR_CR:\n\t\tcase DUK_OP_BLSR_RC:\n\t\tcase DUK_OP_BLSR_CC:\n\t\tcase DUK_OP_BASR_RR:\n\t\tcase DUK_OP_BASR_CR:\n\t\tcase DUK_OP_BASR_RC:\n\t\tcase DUK_OP_BASR_CC: {\n\t\t\t/* XXX: could leave value on stack top and goto replace_top_a; */\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins), DUK_DEC_A(ins), op);\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_BAND_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BAND_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BAND_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BAND_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* For INSTOF and IN, B is always a register. */\n#define DUK__INSTOF_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_instanceof(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__IN_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_in(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_INSTOF_RR:\n\t\tcase DUK_OP_INSTOF_CR:\n\t\tcase DUK_OP_INSTOF_RC:\n\t\tcase DUK_OP_INSTOF_CC:\n\t\t\tDUK__INSTOF_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_IN_RR:\n\t\tcase DUK_OP_IN_CR:\n\t\tcase DUK_OP_IN_RC:\n\t\tcase DUK_OP_IN_CC:\n\t\t\tDUK__IN_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_INSTOF_RR:\n\t\t\tDUK__INSTOF_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_INSTOF_CR:\n\t\t\tDUK__INSTOF_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_INSTOF_RC:\n\t\t\tDUK__INSTOF_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_INSTOF_CC:\n\t\t\tDUK__INSTOF_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_IN_RR:\n\t\t\tDUK__IN_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_IN_CR:\n\t\t\tDUK__IN_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_IN_RC:\n\t\t\tDUK__IN_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_IN_CC:\n\t\t\tDUK__IN_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* Pre/post inc/dec for register variables, important for loops. */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_PREINCR:\n\t\tcase DUK_OP_PREDECR:\n\t\tcase DUK_OP_POSTINCR:\n\t\tcase DUK_OP_POSTDECR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), op);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREINCV:\n\t\tcase DUK_OP_PREDECV:\n\t\tcase DUK_OP_POSTINCV:\n\t\tcase DUK_OP_POSTDECV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), op, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_PREINCR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_PREINCR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREDECR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_PREDECR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTINCR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_POSTINCR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTDECR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_POSTDECR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREINCV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_PREINCV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREDECV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_PREDECV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTINCV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_POSTINCV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTDECV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_POSTDECV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* XXX: Move to separate helper, optimize for perf/size separately. */\n\t\t/* Preinc/predec for object properties. */\n\t\tcase DUK_OP_PREINCP_RR:\n\t\tcase DUK_OP_PREINCP_CR:\n\t\tcase DUK_OP_PREINCP_RC:\n\t\tcase DUK_OP_PREINCP_CC:\n\t\tcase DUK_OP_PREDECP_RR:\n\t\tcase DUK_OP_PREDECP_CR:\n\t\tcase DUK_OP_PREDECP_RC:\n\t\tcase DUK_OP_PREDECP_CC:\n\t\tcase DUK_OP_POSTINCP_RR:\n\t\tcase DUK_OP_POSTINCP_CR:\n\t\tcase DUK_OP_POSTINCP_RC:\n\t\tcase DUK_OP_POSTINCP_CC:\n\t\tcase DUK_OP_POSTDECP_RR:\n\t\tcase DUK_OP_POSTDECP_CR:\n\t\tcase DUK_OP_POSTDECP_RC:\n\t\tcase DUK_OP_POSTDECP_CC: {\n\t\t\tduk_tval *tv_obj;\n\t\t\tduk_tval *tv_key;\n\t\t\tduk_tval *tv_val;\n\t\t\tduk_bool_t rc;\n\t\t\tduk_double_t x, y, z;\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_tval *tv_dst;\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t\t/* A -> target reg\n\t\t\t * B -> object reg/const (may be const e.g. in \"'foo'[1]\")\n\t\t\t * C -> key reg/const\n\t\t\t */\n\n\t\t\t/* Opcode bits 0-1 are used to distinguish reg/const variants.\n\t\t\t * Opcode bits 2-3 are used to distinguish inc/dec variants:\n\t\t\t * Bit 2 = inc(0)/dec(1), bit 3 = pre(0)/post(1).\n\t\t\t */\n\t\t\tDUK_ASSERT((DUK_OP_PREINCP_RR & 0x0c) == 0x00);\n\t\t\tDUK_ASSERT((DUK_OP_PREDECP_RR & 0x0c) == 0x04);\n\t\t\tDUK_ASSERT((DUK_OP_POSTINCP_RR & 0x0c) == 0x08);\n\t\t\tDUK_ASSERT((DUK_OP_POSTDECP_RR & 0x0c) == 0x0c);\n\n\t\t\ttv_obj = DUK__REGCONSTP_B(ins);\n\t\t\ttv_key = DUK__REGCONSTP_C(ins);\n\t\t\trc = duk_hobject_getprop(thr, tv_obj, tv_key);  /* -> [val] */\n\t\t\tDUK_UNREF(rc);  /* ignore */\n\t\t\ttv_obj = NULL;  /* invalidated */\n\t\t\ttv_key = NULL;  /* invalidated */\n\n\t\t\t/* XXX: Fastint fast path would be useful here.  Also fastints\n\t\t\t * now lose their fastint status in current handling which is\n\t\t\t * not intuitive.\n\t\t\t */\n\n\t\t\tx = duk_to_number_m1(thr);\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tif (ins & DUK_BC_INCDECP_FLAG_DEC) {\n\t\t\t\ty = x - 1.0;\n\t\t\t} else {\n\t\t\t\ty = x + 1.0;\n\t\t\t}\n\n\t\t\tduk_push_number(thr, y);\n\t\t\ttv_val = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\ttv_obj = DUK__REGCONSTP_B(ins);\n\t\t\ttv_key = DUK__REGCONSTP_C(ins);\n\t\t\trc = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, DUK__STRICT());\n\t\t\tDUK_UNREF(rc);  /* ignore */\n\t\t\ttv_obj = NULL;  /* invalidated */\n\t\t\ttv_key = NULL;  /* invalidated */\n\t\t\tduk_pop_unsafe(thr);\n\n\t\t\tz = (ins & DUK_BC_INCDECP_FLAG_POST) ? x : y;\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_push_number(thr, z);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n#else\n\t\t\ttv_dst = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_dst, z);\n\t\t\tbreak;\n#endif\n\t\t}\n\n\t\t/* XXX: GETPROP where object is 'this', GETPROPT?\n\t\t * Occurs relatively often in object oriented code.\n\t\t */\n\n#define DUK__GETPROP_BODY(barg,carg) { \\\n\t\t/* A -> target reg \\\n\t\t * B -> object reg/const (may be const e.g. in \"'foo'[1]\") \\\n\t\t * C -> key reg/const \\\n\t\t */ \\\n\t\t(void) duk_hobject_getprop(thr, (barg), (carg)); \\\n\t\tDUK__REPLACE_TOP_A_BREAK(); \\\n\t}\n#define DUK__GETPROPC_BODY(barg,carg) { \\\n\t\t/* Same as GETPROP but callability check for property-based calls. */ \\\n\t\tduk_tval *tv__targ; \\\n\t\t(void) duk_hobject_getprop(thr, (barg), (carg)); \\\n\t\tDUK_GC_TORTURE(thr->heap); \\\n\t\ttv__targ = DUK_GET_TVAL_NEGIDX(thr, -1); \\\n\t\tif (DUK_UNLIKELY(!duk_is_callable_tval(thr, tv__targ))) { \\\n\t\t\t/* Here we intentionally re-evaluate the macro \\\n\t\t\t * arguments to deal with potentially changed \\\n\t\t\t * valstack base pointer! \\\n\t\t\t */ \\\n\t\t\tduk_call_setup_propcall_error(thr, (barg), (carg)); \\\n\t\t} \\\n\t\tDUK__REPLACE_TOP_A_BREAK(); \\\n\t}\n#define DUK__PUTPROP_BODY(aarg,barg,carg) { \\\n\t\t/* A -> object reg \\\n\t\t * B -> key reg/const \\\n\t\t * C -> value reg/const \\\n\t\t * \\\n\t\t * Note: intentional difference to register arrangement \\\n\t\t * of e.g. GETPROP; 'A' must contain a register-only value. \\\n\t\t */ \\\n\t\t(void) duk_hobject_putprop(thr, (aarg), (barg), (carg), DUK__STRICT()); \\\n\t\tbreak; \\\n\t}\n#define DUK__DELPROP_BODY(barg,carg) { \\\n\t\t/* A -> result reg \\\n\t\t * B -> object reg \\\n\t\t * C -> key reg/const \\\n\t\t */ \\\n\t\tduk_bool_t rc; \\\n\t\trc = duk_hobject_delprop(thr, (barg), (carg), DUK__STRICT()); \\\n\t\tDUK_ASSERT(rc == 0 || rc == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(rc); \\\n\t}\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_GETPROP_RR:\n\t\tcase DUK_OP_GETPROP_CR:\n\t\tcase DUK_OP_GETPROP_RC:\n\t\tcase DUK_OP_GETPROP_CC:\n\t\t\tDUK__GETPROP_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\tcase DUK_OP_GETPROPC_RR:\n\t\tcase DUK_OP_GETPROPC_CR:\n\t\tcase DUK_OP_GETPROPC_RC:\n\t\tcase DUK_OP_GETPROPC_CC:\n\t\t\tDUK__GETPROPC_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#endif\n\t\tcase DUK_OP_PUTPROP_RR:\n\t\tcase DUK_OP_PUTPROP_CR:\n\t\tcase DUK_OP_PUTPROP_RC:\n\t\tcase DUK_OP_PUTPROP_CC:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_DELPROP_RR:\n\t\tcase DUK_OP_DELPROP_RC:  /* B is always reg */\n\t\t\tDUK__DELPROP_BODY(DUK__REGP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_GETPROP_RR:\n\t\t\tDUK__GETPROP_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROP_CR:\n\t\t\tDUK__GETPROP_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROP_RC:\n\t\t\tDUK__GETPROP_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GETPROP_CC:\n\t\t\tDUK__GETPROP_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\tcase DUK_OP_GETPROPC_RR:\n\t\t\tDUK__GETPROPC_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROPC_CR:\n\t\t\tDUK__GETPROPC_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROPC_RC:\n\t\t\tDUK__GETPROPC_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GETPROPC_CC:\n\t\t\tDUK__GETPROPC_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif\n\t\tcase DUK_OP_PUTPROP_RR:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_PUTPROP_CR:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_PUTPROP_RC:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_PUTPROP_CC:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_DELPROP_RR:  /* B is always reg */\n\t\t\tDUK__DELPROP_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_DELPROP_RC:\n\t\t\tDUK__DELPROP_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* No fast path for DECLVAR now, it's quite a rare instruction. */\n\t\tcase DUK_OP_DECLVAR_RR:\n\t\tcase DUK_OP_DECLVAR_CR:\n\t\tcase DUK_OP_DECLVAR_RC:\n\t\tcase DUK_OP_DECLVAR_CC: {\n\t\t\tduk_activation *act;\n\t\t\tduk_small_uint_fast_t a = DUK_DEC_A(ins);\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\t\t\tduk_small_uint_t prop_flags;\n\t\t\tduk_bool_t is_func_decl;\n\n\t\t\ttv1 = DUK__REGCONSTP_B(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\n\t\t\tis_func_decl = ((a & DUK_BC_DECLVAR_FLAG_FUNC_DECL) != 0);\n\n\t\t\t/* XXX: declvar takes an duk_tval pointer, which is awkward and\n\t\t\t * should be reworked.\n\t\t\t */\n\n\t\t\t/* Compiler is responsible for selecting property flags (configurability,\n\t\t\t * writability, etc).\n\t\t\t */\n\t\t\tprop_flags = a & DUK_PROPDESC_FLAGS_MASK;\n\n\t\t\tif (is_func_decl) {\n\t\t\t\tduk_push_tval(thr, DUK__REGCONSTP_C(ins));\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* valstack policy */\n\t\t\t\tthr->valstack_top++;\n\t\t\t}\n\t\t\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tif (duk_js_declvar_activation(thr, act, name, tv1, prop_flags, is_func_decl)) {\n\t\t\t\tif (is_func_decl) {\n\t\t\t\t\t/* Already declared, update value. */\n\t\t\t\t\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\t\t\t\tduk_js_putvar_activation(thr, act, name, tv1, DUK__STRICT());\n\t\t\t\t} else {\n\t\t\t\t\t/* Already declared but no initializer value\n\t\t\t\t\t * (e.g. 'var xyz;'), no-op.\n\t\t\t\t\t */\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t/* The compiler should never emit DUK_OP_REGEXP if there is no\n\t\t * regexp support.\n\t\t */\n\t\tcase DUK_OP_REGEXP_RR:\n\t\tcase DUK_OP_REGEXP_CR:\n\t\tcase DUK_OP_REGEXP_RC:\n\t\tcase DUK_OP_REGEXP_CC: {\n\t\t\t/* A -> target register\n\t\t\t * B -> bytecode (also contains flags)\n\t\t\t * C -> escaped source\n\t\t\t */\n\n\t\t\tduk_push_tval(thr, DUK__REGCONSTP_C(ins));\n\t\t\tduk_push_tval(thr, DUK__REGCONSTP_B(ins));  /* -> [ ... escaped_source bytecode ] */\n\t\t\tduk_regexp_create_instance(thr);   /* -> [ ... regexp_instance ] */\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n\t\t/* XXX: 'c' is unused, use whole BC, etc. */\n\t\tcase DUK_OP_CSVAR_RR:\n\t\tcase DUK_OP_CSVAR_CR:\n\t\tcase DUK_OP_CSVAR_RC:\n\t\tcase DUK_OP_CSVAR_CC: {\n\t\t\t/* The speciality of calling through a variable binding is that the\n\t\t\t * 'this' value may be provided by the variable lookup: E5 Section 6.b.i.\n\t\t\t *\n\t\t\t * The only (standard) case where the 'this' binding is non-null is when\n\t\t\t *   (1) the variable is found in an object environment record, and\n\t\t\t *   (2) that object environment record is a 'with' block.\n\t\t\t */\n\n\t\t\tduk_activation *act;\n\t\t\tduk_uint_fast_t idx;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\n\t\t\t/* A -> target registers (A, A + 1) for call setup\n\t\t\t * B -> identifier name, usually constant but can be a register due to shuffling\n\t\t\t */\n\n\t\t\ttv1 = DUK__REGCONSTP_B(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\t\t\tact = thr->callstack_curr;\n\t\t\t(void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/);  /* -> [... val this] */\n\n\t\t\tidx = (duk_uint_fast_t) DUK_DEC_A(ins);\n\n\t\t\t/* Could add direct value stack handling. */\n\t\t\tduk_replace(thr, (duk_idx_t) (idx + 1));  /* 'this' binding */\n\t\t\tduk_replace(thr, (duk_idx_t) idx);        /* variable value (function, we hope, not checked here) */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_CLOSURE: {\n\t\t\tduk_activation *act;\n\t\t\tduk_hcompfunc *fun_act;\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\t\t\tduk_hobject *fun_temp;\n\n\t\t\t/* A -> target reg\n\t\t\t * BC -> inner function index\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"CLOSURE to target register %ld, fnum %ld (count %ld)\",\n\t\t\t                     (long) DUK_DEC_A(ins), (long) DUK_DEC_BC(ins), (long) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, DUK__FUN())));\n\n\t\t\tDUK_ASSERT_DISABLE(bc >= 0); /* unsigned */\n\t\t\tDUK_ASSERT((duk_uint_t) bc < (duk_uint_t) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, DUK__FUN()));\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tfun_act = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\t\t\tfun_temp = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, fun_act)[bc];\n\t\t\tDUK_ASSERT(fun_temp != NULL);\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(fun_temp));\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"CLOSURE: function template is: %p -> %!O\",\n\t\t\t                     (void *) fun_temp, (duk_heaphdr *) fun_temp));\n\n\t\t\tif (act->lex_env == NULL) {\n\t\t\t\tDUK_ASSERT(act->var_env == NULL);\n\t\t\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\t\t\tact = thr->callstack_curr;\n\t\t\t}\n\t\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\t\tDUK_ASSERT(act->var_env != NULL);\n\n\t\t\t/* functions always have a NEWENV flag, i.e. they get a\n\t\t\t * new variable declaration environment, so only lex_env\n\t\t\t * matters here.\n\t\t\t */\n\t\t\tduk_js_push_closure(thr,\n\t\t\t                    (duk_hcompfunc *) fun_temp,\n\t\t\t                    act->var_env,\n\t\t\t                    act->lex_env,\n\t\t\t                    1 /*add_auto_proto*/);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_GETVAR: {\n\t\t\tduk_activation *act;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\n\t\t\ttv1 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\t(void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/);  /* -> [... val this] */\n\t\t\tduk_pop_unsafe(thr);  /* 'this' binding is not needed here */\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_PUTVAR: {\n\t\t\tduk_activation *act;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\n\t\t\ttv1 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\n\t\t\t/* XXX: putvar takes a duk_tval pointer, which is awkward and\n\t\t\t * should be reworked.\n\t\t\t */\n\n\t\t\ttv1 = DUK__REGP_A(ins);  /* val */\n\t\t\tact = thr->callstack_curr;\n\t\t\tduk_js_putvar_activation(thr, act, name, tv1, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_DELVAR: {\n\t\t\tduk_activation *act;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\t\t\tduk_bool_t rc;\n\n\t\t\ttv1 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\t\t\tact = thr->callstack_curr;\n\t\t\trc = duk_js_delvar_activation(thr, act, name);\n\t\t\tDUK__REPLACE_BOOL_A_BREAK(rc);\n\t\t}\n\n\t\tcase DUK_OP_JUMP: {\n\t\t\t/* Note: without explicit cast to signed, MSVC will\n\t\t\t * apparently generate a large positive jump when the\n\t\t\t * bias-corrected value would normally be negative.\n\t\t\t */\n\t\t\tcurr_pc += (duk_int_fast_t) DUK_DEC_ABC(ins) - (duk_int_fast_t) DUK_BC_JUMP_BIAS;\n\t\t\tbreak;\n\t\t}\n\n#define DUK__RETURN_SHARED() do { \\\n\t\tduk_small_uint_t ret_result; \\\n\t\t/* duk__handle_return() is guaranteed never to throw, except \\\n\t\t * for potential out-of-memory situations which will then \\\n\t\t * propagate out of the executor longjmp handler. \\\n\t\t */ \\\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL); \\\n\t\tret_result = duk__handle_return(thr, entry_act); \\\n\t\tif (ret_result == DUK__RETHAND_RESTART) { \\\n\t\t\tgoto restart_execution; \\\n\t\t} \\\n\t\tDUK_ASSERT(ret_result == DUK__RETHAND_FINISHED); \\\n\t\treturn; \\\n\t} while (0)\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_RETREG:\n\t\tcase DUK_OP_RETCONST:\n\t\tcase DUK_OP_RETCONSTN:\n\t\tcase DUK_OP_RETUNDEF: {\n\t\t\t /* BC -> return value reg/const */\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\n\t\t\tif (op == DUK_OP_RETREG) {\n\t\t\t\tduk_push_tval(thr, DUK__REGP_BC(ins));\n\t\t\t} else if (op == DUK_OP_RETUNDEF) {\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* valstack policy */\n\t\t\t\tthr->valstack_top++;\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(op == DUK_OP_RETCONST || op == DUK_OP_RETCONSTN);\n\t\t\t\tduk_push_tval(thr, DUK__CONSTP_BC(ins));\n\t\t\t}\n\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_RETREG: {\n\t\t\tduk_tval *tv;\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\ttv = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tthr->valstack_top++;\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n\t\t/* This will be unused without refcounting. */\n\t\tcase DUK_OP_RETCONST: {\n\t\t\tduk_tval *tv;\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\ttv = DUK__CONSTP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tthr->valstack_top++;\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n\t\tcase DUK_OP_RETCONSTN: {\n\t\t\tduk_tval *tv;\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\ttv = DUK__CONSTP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t/* Without refcounting only RETCONSTN is used. */\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv));  /* no INCREF for this constant */\n#endif\n\t\t\tthr->valstack_top++;\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n\t\tcase DUK_OP_RETUNDEF: {\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\tthr->valstack_top++;  /* value at valstack top is already undefined by valstack policy */\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\tcase DUK_OP_LABEL: {\n\t\t\tduk_activation *act;\n\t\t\tduk_catcher *cat;\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\t/* Allocate catcher and populate it (must be atomic). */\n\n\t\t\tcat = duk_hthread_catcher_alloc(thr);\n\t\t\tDUK_ASSERT(cat != NULL);\n\n\t\t\tcat->flags = (duk_uint32_t) (DUK_CAT_TYPE_LABEL | (bc << DUK_CAT_LABEL_SHIFT));\n\t\t\tcat->pc_base = (duk_instr_t *) curr_pc;  /* pre-incremented, points to first jump slot */\n\t\t\tcat->idx_base = 0;  /* unused for label */\n\t\t\tcat->h_varname = NULL;\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\tcat->parent = act->cat;\n\t\t\tact->cat = cat;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"LABEL catcher: flags=0x%08lx, pc_base=%ld, \"\n\t\t\t                     \"idx_base=%ld, h_varname=%!O, label_id=%ld\",\n\t\t\t                     (long) cat->flags, (long) cat->pc_base,\n\t\t\t                     (long) cat->idx_base, (duk_heaphdr *) cat->h_varname, (long) DUK_CAT_GET_LABEL(cat)));\n\n\t\t\tcurr_pc += 2;  /* skip jump slots */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDLABEL: {\n\t\t\tduk_activation *act;\n#if (defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)) || defined(DUK_USE_ASSERTIONS)\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n#endif\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"ENDLABEL %ld\", (long) bc));\n#endif\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(act->cat != NULL);\n\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_LABEL);\n\t\t\tDUK_ASSERT((duk_uint_fast_t) DUK_CAT_GET_LABEL(act->cat) == bc);\n\t\t\tduk_hthread_catcher_unwind_nolexenv_norz(thr, act);\n\n\t\t\t/* no need to unwind callstack */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_BREAK: {\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\tduk__handle_break_or_continue(thr, (duk_uint_t) bc, DUK_LJ_TYPE_BREAK);\n\t\t\tgoto restart_execution;\n\t\t}\n\n\t\tcase DUK_OP_CONTINUE: {\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\tduk__handle_break_or_continue(thr, (duk_uint_t) bc, DUK_LJ_TYPE_CONTINUE);\n\t\t\tgoto restart_execution;\n\t\t}\n\n\t\t/* XXX: move to helper, too large to be inline here */\n\t\tcase DUK_OP_TRYCATCH: {\n\t\t\tduk__handle_op_trycatch(thr, ins, curr_pc);\n\t\t\tcurr_pc += 2;  /* skip jump slots */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDTRY: {\n\t\t\tcurr_pc = duk__handle_op_endtry(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDCATCH: {\n\t\t\tduk__handle_op_endcatch(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDFIN: {\n\t\t\t/* Sync and NULL early. */\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\n\t\t\tif (duk__handle_op_endfin(thr, ins, entry_act) != 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t/* Must restart because we NULLed out curr_pc. */\n\t\t\tgoto restart_execution;\n\t\t}\n\n\t\tcase DUK_OP_THROW: {\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\t/* Note: errors are augmented when they are created, not\n\t\t\t * when they are thrown.  So, don't augment here, it would\n\t\t\t * break re-throwing for instance.\n\t\t\t */\n\n\t\t\t/* Sync so that augmentation sees up-to-date activations, NULL\n\t\t\t * thr->ptr_curr_pc so that it's not used if side effects occur\n\t\t\t * in augmentation or longjmp handling.\n\t\t\t */\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\n\t\t\tduk_dup(thr, (duk_idx_t) bc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (BYTECODE): %!dT (before throw augment)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\t\t\tduk_err_augment_error_throw(thr);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (BYTECODE): %!dT (after throw augment)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n#endif\n\n\t\t\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, DUK_GET_TVAL_NEGIDX(thr, -1));\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\t\tduk_err_check_debugger_integration(thr);\n#endif\n\n\t\t\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* always in executor */\n\t\t\tduk_err_longjmp(thr);\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_CSREG: {\n\t\t\t/*\n\t\t\t *  Assuming a register binds to a variable declared within this\n\t\t\t *  function (a declarative binding), the 'this' for the call\n\t\t\t *  setup is always 'undefined'.  E5 Section 10.2.1.1.6.\n\t\t\t */\n\n\t\t\tduk_small_uint_fast_t a = DUK_DEC_A(ins);\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\t/* A -> register containing target function (not type checked here)\n\t\t\t * BC -> target registers (BC, BC + 1) for call setup\n\t\t\t */\n\n#if defined(DUK_USE_PREFER_SIZE)\n\t\t\tduk_dup(thr, (duk_idx_t) a);\n\t\t\tduk_replace(thr, (duk_idx_t) bc);\n\t\t\tduk_to_undefined(thr, (duk_idx_t) (bc + 1));\n#else\n\t\t\tduk_tval *tv1;\n\t\t\tduk_tval *tv2;\n\t\t\tduk_tval *tv3;\n\t\t\tduk_tval tv_tmp1;\n\t\t\tduk_tval tv_tmp2;\n\n\t\t\ttv1 = DUK__REGP(bc);\n\t\t\ttv2 = tv1 + 1;\n\t\t\tDUK_TVAL_SET_TVAL(&tv_tmp1, tv1);\n\t\t\tDUK_TVAL_SET_TVAL(&tv_tmp2, tv2);\n\t\t\ttv3 = DUK__REGP(a);\n\t\t\tDUK_TVAL_SET_TVAL(tv1, tv3);\n\t\t\tDUK_TVAL_INCREF(thr, tv1);  /* no side effects */\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv2);  /* no need for incref */\n\t\t\tDUK_TVAL_DECREF(thr, &tv_tmp1);\n\t\t\tDUK_TVAL_DECREF(thr, &tv_tmp2);\n#endif\n\t\t\tbreak;\n\t\t}\n\n\n\t\t/* XXX: in some cases it's faster NOT to reuse the value\n\t\t * stack but rather copy the arguments on top of the stack\n\t\t * (mainly when the calling value stack is large and the value\n\t\t * stack resize would be large).\n\t\t */\n\n\t\tcase DUK_OP_CALL0:\n\t\tcase DUK_OP_CALL1:\n\t\tcase DUK_OP_CALL2:\n\t\tcase DUK_OP_CALL3:\n\t\tcase DUK_OP_CALL4:\n\t\tcase DUK_OP_CALL5:\n\t\tcase DUK_OP_CALL6:\n\t\tcase DUK_OP_CALL7: {\n\t\t\t/* Opcode packs 4 flag bits: 1 for indirect, 3 map\n\t\t\t * 1:1 to three lowest call handling flags.\n\t\t\t *\n\t\t\t * A -> nargs or register with nargs (indirect)\n\t\t\t * BC -> base register for call (base -> func, base+1 -> this, base+2 -> arg1 ... base+2+N-1 -> argN)\n\t\t\t */\n\n\t\t\tduk_idx_t nargs;\n\t\t\tduk_idx_t idx;\n\t\t\tduk_small_uint_t call_flags;\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tduk_hcompfunc *fun;\n#endif\n\n\t\t\tDUK_ASSERT((DUK_OP_CALL0 & 0x0fU) == 0);\n\t\t\tDUK_ASSERT((ins & DUK_BC_CALL_FLAG_INDIRECT) == 0);\n\n\t\t\tnargs = (duk_idx_t) DUK_DEC_A(ins);\n\t\t\tcall_flags = (ins & 0x07U) | DUK_CALL_FLAG_ALLOW_ECMATOECMA;\n\t\t\tidx = (duk_idx_t) DUK_DEC_BC(ins);\n\n\t\t\tif (duk__executor_handle_call(thr, idx, nargs, call_flags)) {\n\t\t\t\t/* curr_pc synced by duk_handle_call_unprotected() */\n\t\t\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n\t\t\tDUK_ASSERT(thr->ptr_curr_pc != NULL);\n\n\t\t\t/* duk_js_call.c is required to restore the stack reserve\n\t\t\t * so we only need to reset the top.\n\t\t\t */\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tfun = DUK__FUN();\n#endif\n\t\t\tduk_set_top_unsafe(thr, (duk_idx_t) fun->nregs);\n\n\t\t\t/* No need to reinit setjmp() catchpoint, as call handling\n\t\t\t * will store and restore our state.\n\t\t\t *\n\t\t\t * When debugger is enabled, we need to recheck the activation\n\t\t\t * status after returning.  This is now handled by call handling\n\t\t\t * and heap->dbg_force_restart.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_CALL8:\n\t\tcase DUK_OP_CALL9:\n\t\tcase DUK_OP_CALL10:\n\t\tcase DUK_OP_CALL11:\n\t\tcase DUK_OP_CALL12:\n\t\tcase DUK_OP_CALL13:\n\t\tcase DUK_OP_CALL14:\n\t\tcase DUK_OP_CALL15: {\n\t\t\t/* Indirect variant. */\n\t\t\tduk_uint_fast_t nargs;\n\t\t\tduk_idx_t idx;\n\t\t\tduk_small_uint_t call_flags;\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tduk_hcompfunc *fun;\n#endif\n\n\t\t\tDUK_ASSERT((DUK_OP_CALL0 & 0x0fU) == 0);\n\t\t\tDUK_ASSERT((ins & DUK_BC_CALL_FLAG_INDIRECT) != 0);\n\n\t\t\tnargs = (duk_uint_fast_t) DUK_DEC_A(ins);\n\t\t\tDUK__LOOKUP_INDIRECT(nargs);\n\t\t\tcall_flags = (ins & 0x07U) | DUK_CALL_FLAG_ALLOW_ECMATOECMA;\n\t\t\tidx = (duk_idx_t) DUK_DEC_BC(ins);\n\n\t\t\tif (duk__executor_handle_call(thr, idx, (duk_idx_t) nargs, call_flags)) {\n\t\t\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n\t\t\tDUK_ASSERT(thr->ptr_curr_pc != NULL);\n\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tfun = DUK__FUN();\n#endif\n\t\t\tduk_set_top_unsafe(thr, (duk_idx_t) fun->nregs);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_NEWOBJ: {\n\t\t\tduk_push_object(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t{\n\t\t\t\tduk_hobject *h;\n\t\t\t\th = duk_require_hobject(thr, -1);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ESIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(h) == 0);\n\t\t\t}\n#endif\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t/* XXX: could do a direct props realloc, but need hash size */\n\t\t\tduk_hobject_resize_entrypart(thr, duk_known_hobject(thr, -1), DUK_DEC_A(ins));\n#endif\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_NEWARR: {\n\t\t\tduk_push_array(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t{\n\t\t\t\tduk_hobject *h;\n\t\t\t\th = duk_require_hobject(thr, -1);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ESIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(h));\n\t\t\t}\n#endif\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\tduk_hobject_realloc_props(thr,\n\t\t\t                          duk_known_hobject(thr, -1),\n\t\t\t                          0 /*new_e_size*/,\n\t\t\t                          DUK_DEC_A(ins) /*new_a_size*/,\n\t\t\t                          0 /*new_h_size*/,\n\t\t\t                          0 /*abandon_array*/);\n#if 0\n\t\t\tduk_hobject_resize_arraypart(thr, duk_known_hobject(thr, -1), DUK_DEC_A(ins));\n#endif\n#endif\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_MPUTOBJ:\n\t\tcase DUK_OP_MPUTOBJI: {\n\t\t\tduk_idx_t obj_idx;\n\t\t\tduk_uint_fast_t idx, idx_end;\n\t\t\tduk_small_uint_fast_t count;\n\n\t\t\t/* A -> register of target object\n\t\t\t * B -> first register of key/value pair list\n\t\t\t *      or register containing first register number if indirect\n\t\t\t * C -> number of key/value pairs * 2\n\t\t\t *      (= number of value stack indices used starting from 'B')\n\t\t\t */\n\n\t\t\tobj_idx = DUK_DEC_A(ins);\n\t\t\tDUK_ASSERT(duk_is_object(thr, obj_idx));\n\n\t\t\tidx = (duk_uint_fast_t) DUK_DEC_B(ins);\n\t\t\tif (DUK_DEC_OP(ins) == DUK_OP_MPUTOBJI) {\n\t\t\t\tDUK__LOOKUP_INDIRECT(idx);\n\t\t\t}\n\n\t\t\tcount = (duk_small_uint_fast_t) DUK_DEC_C(ins);\n\t\t\tDUK_ASSERT(count > 0);  /* compiler guarantees */\n\t\t\tidx_end = idx + count;\n\n#if defined(DUK_USE_EXEC_INDIRECT_BOUND_CHECK)\n\t\t\tif (DUK_UNLIKELY(idx_end > (duk_uint_fast_t) duk_get_top(thr))) {\n\t\t\t\t/* XXX: use duk_is_valid_index() instead? */\n\t\t\t\t/* XXX: improve check; check against nregs, not against top */\n\t\t\t\tDUK__INTERNAL_ERROR(\"MPUTOBJ out of bounds\");\n\t\t\t}\n#endif\n\n\t\t\t/* Use 'force' flag to duk_def_prop() to ensure that any\n\t\t\t * inherited properties don't prevent the operation.\n\t\t\t * With ES2015 duplicate properties are allowed, so that we\n\t\t\t * must overwrite any previous data or accessor property.\n\t\t\t *\n\t\t\t * With ES2015 computed property names the literal keys\n\t\t\t * may be arbitrary values and need to be ToPropertyKey()\n\t\t\t * coerced at runtime.\n\t\t\t */\n\t\t\tdo {\n\t\t\t\t/* XXX: faster initialization (direct access or better primitives) */\n\t\t\t\tduk_dup(thr, (duk_idx_t) idx);\n\t\t\t\tduk_dup(thr, (duk_idx_t) (idx + 1));\n\t\t\t\tduk_def_prop(thr, obj_idx, DUK_DEFPROP_HAVE_VALUE |\n\t\t\t\t                           DUK_DEFPROP_FORCE |\n\t\t\t\t                           DUK_DEFPROP_SET_WRITABLE |\n\t\t\t\t                           DUK_DEFPROP_SET_ENUMERABLE |\n\t\t\t\t                           DUK_DEFPROP_SET_CONFIGURABLE);\n\t\t\t\tidx += 2;\n\t\t\t} while (idx < idx_end);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INITSET:\n\t\tcase DUK_OP_INITGET: {\n\t\t\tduk__handle_op_initset_initget(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_MPUTARR:\n\t\tcase DUK_OP_MPUTARRI: {\n\t\t\tduk_idx_t obj_idx;\n\t\t\tduk_uint_fast_t idx, idx_end;\n\t\t\tduk_small_uint_fast_t count;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_uint32_t arr_idx;\n\n\t\t\t/* A -> register of target object\n\t\t\t * B -> first register of value data (start_index, value1, value2, ..., valueN)\n\t\t\t *      or register containing first register number if indirect\n\t\t\t * C -> number of key/value pairs (N)\n\t\t\t */\n\n\t\t\tobj_idx = DUK_DEC_A(ins);\n\t\t\tDUK_ASSERT(duk_is_object(thr, obj_idx));\n\n\t\t\tidx = (duk_uint_fast_t) DUK_DEC_B(ins);\n\t\t\tif (DUK_DEC_OP(ins) == DUK_OP_MPUTARRI) {\n\t\t\t\tDUK__LOOKUP_INDIRECT(idx);\n\t\t\t}\n\n\t\t\tcount = (duk_small_uint_fast_t) DUK_DEC_C(ins);\n\t\t\tDUK_ASSERT(count > 0 + 1);  /* compiler guarantees */\n\t\t\tidx_end = idx + count;\n\n#if defined(DUK_USE_EXEC_INDIRECT_BOUND_CHECK)\n\t\t\tif (idx_end > (duk_uint_fast_t) duk_get_top(thr)) {\n\t\t\t\t/* XXX: use duk_is_valid_index() instead? */\n\t\t\t\t/* XXX: improve check; check against nregs, not against top */\n\t\t\t\tDUK__INTERNAL_ERROR(\"MPUTARR out of bounds\");\n\t\t\t}\n#endif\n\n\t\t\ttv1 = DUK__REGP(idx);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\t\tarr_idx = (duk_uint32_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\t\t\tarr_idx = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\t\tidx++;\n\n\t\t\tdo {\n\t\t\t\t/* duk_xdef_prop() will define an own property without any array\n\t\t\t\t * special behaviors.  We'll need to set the array length explicitly\n\t\t\t\t * in the end.  For arrays with elisions, the compiler will emit an\n\t\t\t\t * explicit SETALEN which will update the length.\n\t\t\t\t */\n\n\t\t\t\t/* XXX: because we're dealing with 'own' properties of a fresh array,\n\t\t\t\t * the array initializer should just ensure that the array has a large\n\t\t\t\t * enough array part and write the values directly into array part,\n\t\t\t\t * and finally set 'length' manually in the end (as already happens now).\n\t\t\t\t */\n\n\t\t\t\tduk_dup(thr, (duk_idx_t) idx);\n\t\t\t\tduk_xdef_prop_index_wec(thr, obj_idx, arr_idx);\n\n\t\t\t\tidx++;\n\t\t\t\tarr_idx++;\n\t\t\t} while (idx < idx_end);\n\n\t\t\t/* XXX: E5.1 Section 11.1.4 coerces the final length through\n\t\t\t * ToUint32() which is odd but happens now as a side effect of\n\t\t\t * 'arr_idx' type.\n\t\t\t */\n\t\t\tduk_set_length(thr, obj_idx, (duk_size_t) (duk_uarridx_t) arr_idx);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_SETALEN: {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hobject *h;\n\t\t\tduk_uint32_t len;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv1));\n\t\t\th = DUK_TVAL_GET_OBJECT(tv1);\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY(h));\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\t\tlen = (duk_uint32_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\t\t\tlen = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\t\t((duk_harray *) h)->length = len;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INITENUM: {\n\t\t\tduk__handle_op_initenum(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_NEXTENUM: {\n\t\t\tcurr_pc += duk__handle_op_nextenum(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INVLHS: {\n\t\t\tDUK_ERROR_REFERENCE(thr, DUK_STR_INVALID_LVALUE);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_DEBUGGER: {\n\t\t\t/* Opcode only emitted by compiler when debugger\n\t\t\t * support is enabled.  Ignore it silently without\n\t\t\t * debugger support, in case it has been loaded\n\t\t\t * from precompiled bytecode.\n\t\t\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\t\tif (duk_debug_is_attached(thr->heap)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement encountered, halt execution\"));\n\t\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\t\tduk_debug_halt_execution(thr, 1 /*use_prev_pc*/);\n\t\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement finished, resume execution\"));\n\t\t\t\tgoto restart_execution;\n\t\t\t} else {\n\t\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement ignored, debugger not attached\"));\n\t\t\t}\n#else\n\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement ignored, no debugger support\"));\n#endif\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_NOP: {\n\t\t\t/* Nop, ignored, but ABC fields may carry a value e.g.\n\t\t\t * for indirect opcode handling.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INVALID: {\n\t\t\tDUK_ERROR_FMT1(thr, DUK_ERR_ERROR, \"INVALID opcode (%ld)\", (long) DUK_DEC_ABC(ins));\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_ES6)\n\t\tcase DUK_OP_NEWTARGET: {\n\t\t\tduk_push_new_target(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n#endif  /* DUK_USE_ES6 */\n\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n#if !defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tcase DUK_OP_EXP_RR:\n\t\tcase DUK_OP_EXP_CR:\n\t\tcase DUK_OP_EXP_RC:\n\t\tcase DUK_OP_EXP_CC:\n#endif\n#if !defined(DUK_USE_ES6)\n\t\tcase DUK_OP_NEWTARGET:\n#endif\n#if !defined(DUK_USE_VERBOSE_ERRORS)\n\t\tcase DUK_OP_GETPROPC_RR:\n\t\tcase DUK_OP_GETPROPC_CR:\n\t\tcase DUK_OP_GETPROPC_RC:\n\t\tcase DUK_OP_GETPROPC_CC:\n#endif\n\t\tcase DUK_OP_UNUSED207:\n\t\tcase DUK_OP_UNUSED212:\n\t\tcase DUK_OP_UNUSED213:\n\t\tcase DUK_OP_UNUSED214:\n\t\tcase DUK_OP_UNUSED215:\n\t\tcase DUK_OP_UNUSED216:\n\t\tcase DUK_OP_UNUSED217:\n\t\tcase DUK_OP_UNUSED218:\n\t\tcase DUK_OP_UNUSED219:\n\t\tcase DUK_OP_UNUSED220:\n\t\tcase DUK_OP_UNUSED221:\n\t\tcase DUK_OP_UNUSED222:\n\t\tcase DUK_OP_UNUSED223:\n\t\tcase DUK_OP_UNUSED224:\n\t\tcase DUK_OP_UNUSED225:\n\t\tcase DUK_OP_UNUSED226:\n\t\tcase DUK_OP_UNUSED227:\n\t\tcase DUK_OP_UNUSED228:\n\t\tcase DUK_OP_UNUSED229:\n\t\tcase DUK_OP_UNUSED230:\n\t\tcase DUK_OP_UNUSED231:\n\t\tcase DUK_OP_UNUSED232:\n\t\tcase DUK_OP_UNUSED233:\n\t\tcase DUK_OP_UNUSED234:\n\t\tcase DUK_OP_UNUSED235:\n\t\tcase DUK_OP_UNUSED236:\n\t\tcase DUK_OP_UNUSED237:\n\t\tcase DUK_OP_UNUSED238:\n\t\tcase DUK_OP_UNUSED239:\n\t\tcase DUK_OP_UNUSED240:\n\t\tcase DUK_OP_UNUSED241:\n\t\tcase DUK_OP_UNUSED242:\n\t\tcase DUK_OP_UNUSED243:\n\t\tcase DUK_OP_UNUSED244:\n\t\tcase DUK_OP_UNUSED245:\n\t\tcase DUK_OP_UNUSED246:\n\t\tcase DUK_OP_UNUSED247:\n\t\tcase DUK_OP_UNUSED248:\n\t\tcase DUK_OP_UNUSED249:\n\t\tcase DUK_OP_UNUSED250:\n\t\tcase DUK_OP_UNUSED251:\n\t\tcase DUK_OP_UNUSED252:\n\t\tcase DUK_OP_UNUSED253:\n\t\tcase DUK_OP_UNUSED254:\n\t\tcase DUK_OP_UNUSED255:\n\t\t/* Force all case clauses to map to an actual handler\n\t\t * so that the compiler can emit a jump without a bounds\n\t\t * check: the switch argument is a duk_uint8_t so that\n\t\t * the compiler may be able to figure it out.  This is\n\t\t * a small detail and obviously compiler dependent.\n\t\t */\n\t\t/* default: clause omitted on purpose */\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tdefault:\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\t{\n\t\t\t/* Default case catches invalid/unsupported opcodes. */\n\t\t\tDUK_D(DUK_DPRINT(\"invalid opcode: %ld - %!I\", (long) op, ins));\n\t\t\tDUK__INTERNAL_ERROR(\"invalid opcode\");\n\t\t\tbreak;\n\t\t}\n\n\t\t}  /* end switch */\n\n\t\tcontinue;\n\n\t\t/* Some shared exit paths for opcode handling below.  These\n\t\t * are mostly useful to reduce code footprint when multiple\n\t\t * opcodes have a similar epilogue (like replacing stack top\n\t\t * with index 'a').\n\t\t */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t replace_top_a:\n\t\tDUK__REPLACE_TO_TVPTR(thr, DUK__REGP_A(ins));\n\t\tcontinue;\n\t replace_top_bc:\n\t\tDUK__REPLACE_TO_TVPTR(thr, DUK__REGP_BC(ins));\n\t\tcontinue;\n#endif\n\t}\n\tDUK_WO_NORETURN(return;);\n\n#if !defined(DUK_USE_VERBOSE_EXECUTOR_ERRORS)\n internal_error:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n#endif\n}\n\n/* automatic undefs */\n#undef DUK__BYTEOFF_A\n#undef DUK__BYTEOFF_B\n#undef DUK__BYTEOFF_BC\n#undef DUK__BYTEOFF_C\n#undef DUK__COMPARE_BODY\n#undef DUK__CONST\n#undef DUK__CONSTP\n#undef DUK__CONSTP_A\n#undef DUK__CONSTP_B\n#undef DUK__CONSTP_BC\n#undef DUK__CONSTP_C\n#undef DUK__DELPROP_BODY\n#undef DUK__EQ_BODY\n#undef DUK__FUN\n#undef DUK__GETPROPC_BODY\n#undef DUK__GETPROP_BODY\n#undef DUK__GE_BODY\n#undef DUK__GT_BODY\n#undef DUK__INLINE_PERF\n#undef DUK__INSTOF_BODY\n#undef DUK__INTERNAL_ERROR\n#undef DUK__INT_NOACTION\n#undef DUK__INT_RESTART\n#undef DUK__IN_BODY\n#undef DUK__LE_BODY\n#undef DUK__LONGJMP_RESTART\n#undef DUK__LONGJMP_RETHROW\n#undef DUK__LOOKUP_INDIRECT\n#undef DUK__LT_BODY\n#undef DUK__MASK_A\n#undef DUK__MASK_B\n#undef DUK__MASK_BC\n#undef DUK__MASK_C\n#undef DUK__NEQ_BODY\n#undef DUK__NOINLINE_PERF\n#undef DUK__PUTPROP_BODY\n#undef DUK__RCBIT_B\n#undef DUK__RCBIT_C\n#undef DUK__REG\n#undef DUK__REGCONSTP_B\n#undef DUK__REGCONSTP_C\n#undef DUK__REGP\n#undef DUK__REGP_A\n#undef DUK__REGP_B\n#undef DUK__REGP_BC\n#undef DUK__REGP_C\n#undef DUK__REPLACE_BOOL_A_BREAK\n#undef DUK__REPLACE_TOP_A_BREAK\n#undef DUK__REPLACE_TOP_BC_BREAK\n#undef DUK__REPLACE_TO_TVPTR\n#undef DUK__RETHAND_FINISHED\n#undef DUK__RETHAND_RESTART\n#undef DUK__RETURN_SHARED\n#undef DUK__SEQ_BODY\n#undef DUK__SHIFT_A\n#undef DUK__SHIFT_B\n#undef DUK__SHIFT_BC\n#undef DUK__SHIFT_C\n#undef DUK__SNEQ_BODY\n#undef DUK__STRICT\n#undef DUK__SYNC_AND_NULL_CURR_PC\n#undef DUK__SYNC_CURR_PC\n#undef DUK__TVAL_SHIFT\n/*\n *  ECMAScript specification algorithm and conversion helpers.\n *\n *  These helpers encapsulate the primitive ECMAScript operation semantics,\n *  and are used by the bytecode executor and the API (among other places).\n *  Some primitives are only implemented as part of the API and have no\n *  \"internal\" helper.  This is the case when an internal helper would not\n *  really be useful; e.g. the operation is rare, uses value stack heavily,\n *  etc.\n *\n *  The operation arguments depend on what is required to implement\n *  the operation:\n *\n *    - If an operation is simple and stateless, and has no side\n *      effects, it won't take an duk_hthread argument and its\n *      arguments may be duk_tval pointers (which are safe as long\n *      as no side effects take place).\n *\n *    - If complex coercions are required (e.g. a \"ToNumber\" coercion)\n *      or errors may be thrown, the operation takes an duk_hthread\n *      argument.  This also implies that the operation may have\n *      arbitrary side effects, invalidating any duk_tval pointers.\n *\n *    - For operations with potential side effects, arguments can be\n *      taken in several ways:\n *\n *      a) as duk_tval pointers, which makes sense if the \"common case\"\n *         can be resolved without side effects (e.g. coercion); the\n *         arguments are pushed to the valstack for coercion if\n *         necessary\n *\n *      b) as duk_tval values\n *\n *      c) implicitly on value stack top\n *\n *      d) as indices to the value stack\n *\n *  Future work:\n *\n *     - Argument styles may not be the most sensible in every case now.\n *\n *     - In-place coercions might be useful for several operations, if\n *       in-place coercion is OK for the bytecode executor and the API.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  ToPrimitive()  (E5 Section 9.1)\n *\n *  ==> implemented in the API.\n */\n\n/*\n *  ToBoolean()  (E5 Section 9.2)\n */\n\nDUK_INTERNAL duk_bool_t duk_js_toboolean(duk_tval *tv) {\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\t\treturn 0;\n\tcase DUK_TAG_BOOLEAN:\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv) == 0 || DUK_TVAL_GET_BOOLEAN(tv) == 1);\n\t\treturn DUK_TVAL_GET_BOOLEAN(tv);\n\tcase DUK_TAG_STRING: {\n\t\t/* Symbols ToBoolean() coerce to true, regardless of their\n\t\t * description.  This happens with no explicit check because\n\t\t * of the symbol representation byte prefix.\n\t\t */\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HSTRING_GET_BYTELEN(h) > 0 ? 1 : 0);\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\treturn 1;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\t/* Mimic Uint8Array semantics: objects coerce true, regardless\n\t\t * of buffer length (zero or not) or context.\n\t\t */\n\t\treturn 1;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tvoid *p = DUK_TVAL_GET_POINTER(tv);\n\t\treturn (p != NULL ? 1 : 0);\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\treturn 1;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\tif (DUK_TVAL_GET_FASTINT(tv) != 0) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tduk_double_t d;\n#if defined(DUK_USE_PREFER_SIZE)\n\t\tint c;\n#endif\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\t\td = DUK_TVAL_GET_DOUBLE(tv);\n#if defined(DUK_USE_PREFER_SIZE)\n\t\tc = DUK_FPCLASSIFY((double) d);\n\t\tif (c == DUK_FP_ZERO || c == DUK_FP_NAN) {\n\t\t\treturn 0;\n\t\t} else {\n\t\t\treturn 1;\n\t\t}\n#else\n\t\tDUK_ASSERT(duk_double_is_nan_or_zero(d) == 0 || duk_double_is_nan_or_zero(d) == 1);\n\t\treturn duk_double_is_nan_or_zero(d) ^ 1;\n#endif\n\t}\n\t}\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  ToNumber()  (E5 Section 9.3)\n *\n *  Value to convert must be on stack top, and is popped before exit.\n *\n *  See: http://www.cs.indiana.edu/~burger/FP-Printing-PLDI96.pdf\n *       http://www.cs.indiana.edu/~burger/fp/index.html\n *\n *  Notes on the conversion:\n *\n *    - There are specific requirements on the accuracy of the conversion\n *      through a \"Mathematical Value\" (MV), so this conversion is not\n *      trivial.\n *\n *    - Quick rejects (e.g. based on first char) are difficult because\n *      the grammar allows leading and trailing white space.\n *\n *    - Quick reject based on string length is difficult even after\n *      accounting for white space; there may be arbitrarily many\n *      decimal digits.\n *\n *    - Standard grammar allows decimal values (\"123\"), hex values\n *      (\"0x123\") and infinities\n *\n *    - Unlike source code literals, ToNumber() coerces empty strings\n *      and strings with only whitespace to zero (not NaN).  However,\n *      while '' coerces to 0, '+' and '-' coerce to NaN.\n */\n\n/* E5 Section 9.3.1 */\nDUK_LOCAL duk_double_t duk__tonumber_string_raw(duk_hthread *thr) {\n\tduk_small_uint_t s2n_flags;\n\tduk_double_t d;\n\n\tDUK_ASSERT(duk_is_string(thr, -1));\n\n\t/* Quite lenient, e.g. allow empty as zero, but don't allow trailing\n\t * garbage.\n\t */\n\ts2n_flags = DUK_S2N_FLAG_TRIM_WHITE |\n\t            DUK_S2N_FLAG_ALLOW_EXP |\n\t            DUK_S2N_FLAG_ALLOW_PLUS |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |\n\t            DUK_S2N_FLAG_ALLOW_INF |\n\t            DUK_S2N_FLAG_ALLOW_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO |\n\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT;\n\n\tduk_numconv_parse(thr, 10 /*radix*/, s2n_flags);\n\n#if defined(DUK_USE_PREFER_SIZE)\n\td = duk_get_number(thr, -1);\n\tduk_pop_unsafe(thr);\n#else\n\tthr->valstack_top--;\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(thr->valstack_top));\n\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(thr->valstack_top));  /* no fastint conversion in numconv now */\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(thr->valstack_top));\n\td = DUK_TVAL_GET_DOUBLE(thr->valstack_top);  /* assumes not a fastint */\n\tDUK_TVAL_SET_UNDEFINED(thr->valstack_top);\n#endif\n\n\treturn d;\n}\n\nDUK_INTERNAL duk_double_t duk_js_tonumber(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\t/* return a specific NaN (although not strictly necessary) */\n\t\tduk_double_union du;\n\t\tDUK_DBLUNION_SET_NAN(&du);\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\t\treturn du.d;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\t/* +0.0 */\n\t\treturn 0.0;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tif (DUK_TVAL_IS_BOOLEAN_TRUE(tv)) {\n\t\t\treturn 1.0;\n\t\t}\n\t\treturn 0.0;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\t/* For Symbols ToNumber() is always a TypeError. */\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CANNOT_NUMBER_COERCE_SYMBOL);\n\t\t\tDUK_WO_NORETURN(return 0.0;);\n\t\t}\n\t\tduk_push_hstring(thr, h);\n\t\treturn duk__tonumber_string_raw(thr);\n\t}\n\tcase DUK_TAG_BUFFER:  /* plain buffer treated like object */\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_double_t d;\n\t\tduk_push_tval(thr, tv);\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);  /* 'tv' becomes invalid */\n\n\t\t/* recursive call for a primitive value (guaranteed not to cause second\n\t\t * recursion).\n\t\t */\n\t\tDUK_ASSERT(duk_get_tval(thr, -1) != NULL);\n\t\td = duk_js_tonumber(thr, duk_get_tval(thr, -1));\n\n\t\tduk_pop_unsafe(thr);\n\t\treturn d;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\t/* Coerce like boolean */\n\t\tvoid *p = DUK_TVAL_GET_POINTER(tv);\n\t\treturn (p != NULL ? 1.0 : 0.0);\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* +(function(){}) -> NaN */\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\treturn (duk_double_t) DUK_TVAL_GET_FASTINT(tv);\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\t\treturn DUK_TVAL_GET_DOUBLE(tv);\n\t}\n\t}\n\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  ToInteger()  (E5 Section 9.4)\n */\n\n/* exposed, used by e.g. duk_bi_date.c */\nDUK_INTERNAL duk_double_t duk_js_tointeger_number(duk_double_t x) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\n\tif (DUK_UNLIKELY(c == DUK_FP_NAN)) {\n\t\treturn 0.0;\n\t} else if (DUK_UNLIKELY(c == DUK_FP_INFINITE)) {\n\t\treturn x;\n\t} else {\n\t\t/* Finite, including neg/pos zero.  Neg zero sign must be\n\t\t * preserved.\n\t\t */\n\t\treturn duk_double_trunc_towards_zero(x);\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\t/* NaN and Infinity have the same exponent so it's a cheap\n\t * initial check for the rare path.\n\t */\n\tif (DUK_UNLIKELY(duk_double_is_nan_or_inf(x) != 0U)) {\n\t\tif (duk_double_is_nan(x)) {\n\t\t\treturn 0.0;\n\t\t} else {\n\t\t\treturn x;\n\t\t}\n\t} else {\n\t\treturn duk_double_trunc_towards_zero(x);\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n}\n\nDUK_INTERNAL duk_double_t duk_js_tointeger(duk_hthread *thr, duk_tval *tv) {\n\t/* XXX: fastint */\n\tduk_double_t d = duk_js_tonumber(thr, tv);  /* invalidates tv */\n\treturn duk_js_tointeger_number(d);\n}\n\n/*\n *  ToInt32(), ToUint32(), ToUint16()  (E5 Sections 9.5, 9.6, 9.7)\n */\n\n/* combined algorithm matching E5 Sections 9.5 and 9.6 */\nDUK_LOCAL duk_double_t duk__toint32_touint32_helper(duk_double_t x, duk_bool_t is_toint32) {\n#if defined (DUK_USE_PREFER_SIZE)\n\tduk_small_int_t c;\n#endif\n\n#if defined (DUK_USE_PREFER_SIZE)\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (c == DUK_FP_NAN || c == DUK_FP_ZERO || c == DUK_FP_INFINITE) {\n\t\treturn 0.0;\n\t}\n#else\n\tif (duk_double_is_nan_zero_inf(x)) {\n\t\treturn 0.0;\n\t}\n#endif\n\n\t/* x = sign(x) * floor(abs(x)), i.e. truncate towards zero, keep sign */\n\tx = duk_double_trunc_towards_zero(x);\n\n\t/* NOTE: fmod(x) result sign is same as sign of x, which\n\t * differs from what Javascript wants (see Section 9.6).\n\t */\n\n\tx = DUK_FMOD(x, DUK_DOUBLE_2TO32);    /* -> x in ]-2**32, 2**32[ */\n\n\tif (x < 0.0) {\n\t\tx += DUK_DOUBLE_2TO32;\n\t}\n\tDUK_ASSERT(x >= 0 && x < DUK_DOUBLE_2TO32);  /* -> x in [0, 2**32[ */\n\n\tif (is_toint32) {\n\t\tif (x >= DUK_DOUBLE_2TO31) {\n\t\t\t/* x in [2**31, 2**32[ */\n\n\t\t\tx -= DUK_DOUBLE_2TO32;  /* -> x in [-2**31,2**31[ */\n\t\t}\n\t}\n\n\treturn x;\n}\n\nDUK_INTERNAL duk_int32_t duk_js_toint32(duk_hthread *thr, duk_tval *tv) {\n\tduk_double_t d;\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\treturn DUK_TVAL_GET_FASTINT_I32(tv);\n\t}\n#endif\n\n\td = duk_js_tonumber(thr, tv);  /* invalidates tv */\n\td = duk__toint32_touint32_helper(d, 1);\n\tDUK_ASSERT(DUK_FPCLASSIFY(d) == DUK_FP_ZERO || DUK_FPCLASSIFY(d) == DUK_FP_NORMAL);\n\tDUK_ASSERT(d >= -2147483648.0 && d <= 2147483647.0);  /* [-0x80000000,0x7fffffff] */\n\tDUK_ASSERT(d == ((duk_double_t) ((duk_int32_t) d)));  /* whole, won't clip */\n\treturn (duk_int32_t) d;\n}\n\n\nDUK_INTERNAL duk_uint32_t duk_js_touint32(duk_hthread *thr, duk_tval *tv) {\n\tduk_double_t d;\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\treturn DUK_TVAL_GET_FASTINT_U32(tv);\n\t}\n#endif\n\n\td = duk_js_tonumber(thr, tv);  /* invalidates tv */\n\td = duk__toint32_touint32_helper(d, 0);\n\tDUK_ASSERT(DUK_FPCLASSIFY(d) == DUK_FP_ZERO || DUK_FPCLASSIFY(d) == DUK_FP_NORMAL);\n\tDUK_ASSERT(d >= 0.0 && d <= 4294967295.0);  /* [0x00000000, 0xffffffff] */\n\tDUK_ASSERT(d == ((duk_double_t) ((duk_uint32_t) d)));  /* whole, won't clip */\n\treturn (duk_uint32_t) d;\n\n}\n\nDUK_INTERNAL duk_uint16_t duk_js_touint16(duk_hthread *thr, duk_tval *tv) {\n\t/* should be a safe way to compute this */\n\treturn (duk_uint16_t) (duk_js_touint32(thr, tv) & 0x0000ffffU);\n}\n\n/*\n *  ToString()  (E5 Section 9.8)\n *  ToObject()  (E5 Section 9.9)\n *  CheckObjectCoercible()  (E5 Section 9.10)\n *  IsCallable()  (E5 Section 9.11)\n *\n *  ==> implemented in the API.\n */\n\n/*\n *  Loose equality, strict equality, and SameValue (E5 Sections 11.9.1, 11.9.4,\n *  9.12).  These have much in common so they can share some helpers.\n *\n *  Future work notes:\n *\n *    - Current implementation (and spec definition) has recursion; this should\n *      be fixed if possible.\n *\n *    - String-to-number coercion should be possible without going through the\n *      value stack (and be more compact) if a shared helper is invoked.\n */\n\n/* Note that this is the same operation for strict and loose equality:\n *  - E5 Section 11.9.3, step 1.c (loose)\n *  - E5 Section 11.9.6, step 4 (strict)\n */\n\nDUK_LOCAL duk_bool_t duk__js_equals_number(duk_double_t x, duk_double_t y) {\n#if defined(DUK_USE_PARANOID_MATH)\n\t/* Straightforward algorithm, makes fewer compiler assumptions. */\n\tduk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tduk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\tif (cx == DUK_FP_NAN || cy == DUK_FP_NAN) {\n\t\treturn 0;\n\t}\n\tif (cx == DUK_FP_ZERO && cy == DUK_FP_ZERO) {\n\t\treturn 1;\n\t}\n\tif (x == y) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else  /* DUK_USE_PARANOID_MATH */\n\t/* Better equivalent algorithm.  If the compiler is compliant, C and\n\t * ECMAScript semantics are identical for this particular comparison.\n\t * In particular, NaNs must never compare equal and zeroes must compare\n\t * equal regardless of sign.  Could also use a macro, but this inlines\n\t * already nicely (no difference on gcc, for instance).\n\t */\n\tif (x == y) {\n\t\t/* IEEE requires that NaNs compare false */\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(x) != DUK_FP_NAN);\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(y) != DUK_FP_NAN);\n\t\treturn 1;\n\t} else {\n\t\t/* IEEE requires that zeros compare the same regardless\n\t\t * of their signed, so if both x and y are zeroes, they\n\t\t * are caught above.\n\t\t */\n\t\tDUK_ASSERT(!(DUK_FPCLASSIFY(x) == DUK_FP_ZERO && DUK_FPCLASSIFY(y) == DUK_FP_ZERO));\n\t\treturn 0;\n\t}\n#endif  /* DUK_USE_PARANOID_MATH */\n}\n\nDUK_LOCAL duk_bool_t duk__js_samevalue_number(duk_double_t x, duk_double_t y) {\n#if defined(DUK_USE_PARANOID_MATH)\n\tduk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tduk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\n\tif (cx == DUK_FP_NAN && cy == DUK_FP_NAN) {\n\t\t/* SameValue(NaN, NaN) = true, regardless of NaN sign or extra bits */\n\t\treturn 1;\n\t}\n\tif (cx == DUK_FP_ZERO && cy == DUK_FP_ZERO) {\n\t\t/* Note: cannot assume that a non-zero return value of signbit() would\n\t\t * always be the same -- hence cannot (portably) use something like:\n\t\t *\n\t\t *     signbit(x) == signbit(y)\n\t\t */\n\t\tduk_small_int_t sx = DUK_SIGNBIT(x) ? 1 : 0;\n\t\tduk_small_int_t sy = DUK_SIGNBIT(y) ? 1 : 0;\n\t\treturn (sx == sy);\n\t}\n\n\t/* normal comparison; known:\n\t *   - both x and y are not NaNs (but one of them can be)\n\t *   - both x and y are not zero (but one of them can be)\n\t *   - x and y may be denormal or infinite\n\t */\n\n\treturn (x == y);\n#else  /* DUK_USE_PARANOID_MATH */\n\tduk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tduk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\n\tif (x == y) {\n\t\t/* IEEE requires that NaNs compare false */\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(x) != DUK_FP_NAN);\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(y) != DUK_FP_NAN);\n\n\t\t/* Using classification has smaller footprint than direct comparison. */\n\t\tif (DUK_UNLIKELY(cx == DUK_FP_ZERO && cy == DUK_FP_ZERO)) {\n\t\t\t/* Note: cannot assume that a non-zero return value of signbit() would\n\t\t\t * always be the same -- hence cannot (portably) use something like:\n\t\t\t *\n\t\t\t *     signbit(x) == signbit(y)\n\t\t\t */\n\t\t\treturn duk_double_same_sign(x, y);\n\t\t}\n\t\treturn 1;\n\t} else {\n\t\t/* IEEE requires that zeros compare the same regardless\n\t\t * of their sign, so if both x and y are zeroes, they\n\t\t * are caught above.\n\t\t */\n\t\tDUK_ASSERT(!(DUK_FPCLASSIFY(x) == DUK_FP_ZERO && DUK_FPCLASSIFY(y) == DUK_FP_ZERO));\n\n\t\t/* Difference to non-strict/strict comparison is that NaNs compare\n\t\t * equal and signed zero signs matter.\n\t\t */\n\t\tif (DUK_UNLIKELY(cx == DUK_FP_NAN && cy == DUK_FP_NAN)) {\n\t\t\t/* SameValue(NaN, NaN) = true, regardless of NaN sign or extra bits */\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t}\n#endif  /* DUK_USE_PARANOID_MATH */\n}\n\nDUK_INTERNAL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags) {\n\tduk_uint_t type_mask_x;\n\tduk_uint_t type_mask_y;\n\n\t/* If flags != 0 (strict or SameValue), thr can be NULL.  For loose\n\t * equals comparison it must be != NULL.\n\t */\n\tDUK_ASSERT(flags != 0 || thr != NULL);\n\n\t/*\n\t *  Same type?\n\t *\n\t *  Note: since number values have no explicit tag in the 8-byte\n\t *  representation, need the awkward if + switch.\n\t */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\tif (DUK_TVAL_GET_FASTINT(tv_x) == DUK_TVAL_GET_FASTINT(tv_y)) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}\n\telse\n#endif\n\tif (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) {\n\t\tduk_double_t d1, d2;\n\n\t\t/* Catches both doubles and cases where only one argument is\n\t\t * a fastint so can't assume a double.\n\t\t */\n\t\td1 = DUK_TVAL_GET_NUMBER(tv_x);\n\t\td2 = DUK_TVAL_GET_NUMBER(tv_y);\n\t\tif (DUK_UNLIKELY((flags & DUK_EQUALS_FLAG_SAMEVALUE) != 0)) {\n\t\t\t/* SameValue */\n\t\t\treturn duk__js_samevalue_number(d1, d2);\n\t\t} else {\n\t\t\t/* equals and strict equals */\n\t\t\treturn duk__js_equals_number(d1, d2);\n\t\t}\n\t} else if (DUK_TVAL_GET_TAG(tv_x) == DUK_TVAL_GET_TAG(tv_y)) {\n\t\tswitch (DUK_TVAL_GET_TAG(tv_x)) {\n\t\tcase DUK_TAG_UNDEFINED:\n\t\tcase DUK_TAG_NULL: {\n\t\t\treturn 1;\n\t\t}\n\t\tcase DUK_TAG_BOOLEAN: {\n\t\t\treturn DUK_TVAL_GET_BOOLEAN(tv_x) == DUK_TVAL_GET_BOOLEAN(tv_y);\n\t\t}\n\t\tcase DUK_TAG_POINTER: {\n\t\t\treturn DUK_TVAL_GET_POINTER(tv_x) == DUK_TVAL_GET_POINTER(tv_y);\n\t\t}\n\t\tcase DUK_TAG_STRING:\n\t\tcase DUK_TAG_OBJECT: {\n\t\t\t/* Heap pointer comparison suffices for strings and objects.\n\t\t\t * Symbols compare equal if they have the same internal\n\t\t\t * representation; again heap pointer comparison suffices.\n\t\t\t */\n\t\t\treturn DUK_TVAL_GET_HEAPHDR(tv_x) == DUK_TVAL_GET_HEAPHDR(tv_y);\n\t\t}\n\t\tcase DUK_TAG_BUFFER: {\n\t\t\t/* In Duktape 2.x plain buffers mimic Uint8Array objects\n\t\t\t * so always compare by heap pointer.  In Duktape 1.x\n\t\t\t * strict comparison would compare heap pointers and\n\t\t\t * non-strict would compare contents.\n\t\t\t */\n\t\t\treturn DUK_TVAL_GET_HEAPHDR(tv_x) == DUK_TVAL_GET_HEAPHDR(tv_y);\n\t\t}\n\t\tcase DUK_TAG_LIGHTFUNC: {\n\t\t\t/* At least 'magic' has a significant impact on function\n\t\t\t * identity.\n\t\t\t */\n\t\t\tduk_small_uint_t lf_flags_x;\n\t\t\tduk_small_uint_t lf_flags_y;\n\t\t\tduk_c_function func_x;\n\t\t\tduk_c_function func_y;\n\n\t\t\tDUK_TVAL_GET_LIGHTFUNC(tv_x, func_x, lf_flags_x);\n\t\t\tDUK_TVAL_GET_LIGHTFUNC(tv_y, func_y, lf_flags_y);\n\t\t\treturn ((func_x == func_y) && (lf_flags_x == lf_flags_y)) ? 1 : 0;\n\t\t}\n#if defined(DUK_USE_FASTINT)\n\t\tcase DUK_TAG_FASTINT:\n#endif\n\t\tdefault: {\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_x));\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_y));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_x));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_y));\n\t\t\tDUK_UNREACHABLE();\n\t\t\treturn 0;\n\t\t}\n\t\t}\n\t}\n\n\tif ((flags & (DUK_EQUALS_FLAG_STRICT | DUK_EQUALS_FLAG_SAMEVALUE)) != 0) {\n\t\treturn 0;\n\t}\n\n\tDUK_ASSERT(flags == 0);  /* non-strict equality from here on */\n\n\t/*\n\t *  Types are different; various cases for non-strict comparison\n\t *\n\t *  Since comparison is symmetric, we use a \"swap trick\" to reduce\n\t *  code size.\n\t */\n\n\ttype_mask_x = duk_get_type_mask_tval(tv_x);\n\ttype_mask_y = duk_get_type_mask_tval(tv_y);\n\n\t/* Undefined/null are considered equal (e.g. \"null == undefined\" -> true). */\n\tif ((type_mask_x & (DUK_TYPE_MASK_UNDEFINED | DUK_TYPE_MASK_NULL)) &&\n\t    (type_mask_y & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED))) {\n\t\treturn 1;\n\t}\n\n\t/* Number/string -> coerce string to number (e.g. \"'1.5' == 1.5\" -> true). */\n\tif ((type_mask_x & DUK_TYPE_MASK_NUMBER) && (type_mask_y & DUK_TYPE_MASK_STRING)) {\n\t\tif (!DUK_TVAL_STRING_IS_SYMBOL(tv_y)) {\n\t\t\tduk_double_t d1, d2;\n\t\t\td1 = DUK_TVAL_GET_NUMBER(tv_x);\n\t\t\td2 = duk_to_number_tval(thr, tv_y);\n\t\t\treturn duk__js_equals_number(d1, d2);\n\t\t}\n\t}\n\tif ((type_mask_x & DUK_TYPE_MASK_STRING) && (type_mask_y & DUK_TYPE_MASK_NUMBER)) {\n\t\tif (!DUK_TVAL_STRING_IS_SYMBOL(tv_x)) {\n\t\t\tduk_double_t d1, d2;\n\t\t\td1 = DUK_TVAL_GET_NUMBER(tv_y);\n\t\t\td2 = duk_to_number_tval(thr, tv_x);\n\t\t\treturn duk__js_equals_number(d1, d2);\n\t\t}\n\t}\n\n\t/* Boolean/any -> coerce boolean to number and try again.  If boolean is\n\t * compared to a pointer, the final comparison after coercion now always\n\t * yields false (as pointer vs. number compares to false), but this is\n\t * not special cased.\n\t *\n\t * ToNumber(bool) is +1.0 or 0.0.  Tagged boolean value is always 0 or 1.\n\t */\n\tif (type_mask_x & DUK_TYPE_MASK_BOOLEAN) {\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv_x) == 0 || DUK_TVAL_GET_BOOLEAN(tv_x) == 1);\n\t\tduk_push_uint(thr, DUK_TVAL_GET_BOOLEAN(tv_x));\n\t\tduk_push_tval(thr, tv_y);\n\t\tgoto recursive_call;\n\t}\n\tif (type_mask_y & DUK_TYPE_MASK_BOOLEAN) {\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv_y) == 0 || DUK_TVAL_GET_BOOLEAN(tv_y) == 1);\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_uint(thr, DUK_TVAL_GET_BOOLEAN(tv_y));\n\t\tgoto recursive_call;\n\t}\n\n\t/* String-number-symbol/object -> coerce object to primitive (apparently without hint), then try again. */\n\tif ((type_mask_x & (DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_NUMBER)) &&\n\t    (type_mask_y & DUK_TYPE_MASK_OBJECT)) {\n\t\t/* No symbol check needed because symbols and strings are accepted. */\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NONE);  /* apparently no hint? */\n\t\tgoto recursive_call;\n\t}\n\tif ((type_mask_x & DUK_TYPE_MASK_OBJECT) &&\n\t    (type_mask_y & (DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_NUMBER))) {\n\t\t/* No symbol check needed because symbols and strings are accepted. */\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\tduk_to_primitive(thr, -2, DUK_HINT_NONE);  /* apparently no hint? */\n\t\tgoto recursive_call;\n\t}\n\n\t/* Nothing worked -> not equal. */\n\treturn 0;\n\n recursive_call:\n\t/* Shared code path to call the helper again with arguments on stack top. */\n\t{\n\t\tduk_bool_t rc;\n\t\trc = duk_js_equals_helper(thr,\n\t\t                          DUK_GET_TVAL_NEGIDX(thr, -2),\n\t\t                          DUK_GET_TVAL_NEGIDX(thr, -1),\n\t\t                          0 /*flags:nonstrict*/);\n\t\tduk_pop_2_unsafe(thr);\n\t\treturn rc;\n\t}\n}\n\n/*\n *  Comparisons (x >= y, x > y, x <= y, x < y)\n *\n *  E5 Section 11.8.5: implement 'x < y' and then use negate and eval_left_first\n *  flags to get the rest.\n */\n\n/* XXX: this should probably just operate on the stack top, because it\n * needs to push stuff on the stack anyway...\n */\n\nDUK_INTERNAL duk_small_int_t duk_js_data_compare(const duk_uint8_t *buf1, const duk_uint8_t *buf2, duk_size_t len1, duk_size_t len2) {\n\tduk_size_t prefix_len;\n\tduk_small_int_t rc;\n\n\tprefix_len = (len1 <= len2 ? len1 : len2);\n\n\t/* duk_memcmp() is guaranteed to return zero (equal) for zero length\n\t * inputs.\n\t */\n\trc = duk_memcmp_unsafe((const void *) buf1,\n\t                       (const void *) buf2,\n\t                       (size_t) prefix_len);\n\n\tif (rc < 0) {\n\t\treturn -1;\n\t} else if (rc > 0) {\n\t\treturn 1;\n\t}\n\n\t/* prefix matches, lengths matter now */\n\tif (len1 < len2) {\n\t\t/* e.g. \"x\" < \"xx\" */\n\t\treturn -1;\n\t} else if (len1 > len2) {\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\nDUK_INTERNAL duk_small_int_t duk_js_string_compare(duk_hstring *h1, duk_hstring *h2) {\n\t/*\n\t *  String comparison (E5 Section 11.8.5, step 4), which\n\t *  needs to compare codepoint by codepoint.\n\t *\n\t *  However, UTF-8 allows us to use strcmp directly: the shared\n\t *  prefix will be encoded identically (UTF-8 has unique encoding)\n\t *  and the first differing character can be compared with a simple\n\t *  unsigned byte comparison (which strcmp does).\n\t *\n\t *  This will not work properly for non-xutf-8 strings, but this\n\t *  is not an issue for compliance.\n\t */\n\n\tDUK_ASSERT(h1 != NULL);\n\tDUK_ASSERT(h2 != NULL);\n\n\treturn duk_js_data_compare((const duk_uint8_t *) DUK_HSTRING_GET_DATA(h1),\n\t                           (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h2),\n\t                           (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1),\n\t                           (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2));\n}\n\n#if 0  /* unused */\nDUK_INTERNAL duk_small_int_t duk_js_buffer_compare(duk_heap *heap, duk_hbuffer *h1, duk_hbuffer *h2) {\n\t/* Similar to String comparison. */\n\n\tDUK_ASSERT(h1 != NULL);\n\tDUK_ASSERT(h2 != NULL);\n\tDUK_UNREF(heap);\n\n\treturn duk_js_data_compare((const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(heap, h1),\n\t                           (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(heap, h2),\n\t                           (duk_size_t) DUK_HBUFFER_GET_SIZE(h1),\n\t                           (duk_size_t) DUK_HBUFFER_GET_SIZE(h2));\n}\n#endif\n\n#if defined(DUK_USE_FASTINT)\nDUK_LOCAL duk_bool_t duk__compare_fastint(duk_bool_t retval, duk_int64_t v1, duk_int64_t v2) {\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\tif (v1 < v2) {\n\t\treturn retval ^ 1;\n\t} else {\n\t\treturn retval;\n\t}\n}\n#endif\n\n#if defined(DUK_USE_PARANOID_MATH)\nDUK_LOCAL duk_bool_t duk__compare_number(duk_bool_t retval, duk_double_t d1, duk_double_t d2) {\n\tduk_small_int_t c1, s1, c2, s2;\n\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\tc1 = (duk_small_int_t) DUK_FPCLASSIFY(d1);\n\ts1 = (duk_small_int_t) DUK_SIGNBIT(d1);\n\tc2 = (duk_small_int_t) DUK_FPCLASSIFY(d2);\n\ts2 = (duk_small_int_t) DUK_SIGNBIT(d2);\n\n\tif (c1 == DUK_FP_NAN || c2 == DUK_FP_NAN) {\n\t\treturn 0;  /* Always false, regardless of negation. */\n\t}\n\n\tif (c1 == DUK_FP_ZERO && c2 == DUK_FP_ZERO) {\n\t\t/* For all combinations: +0 < +0, +0 < -0, -0 < +0, -0 < -0,\n\t\t * steps e, f, and g.\n\t\t */\n\t\treturn retval;  /* false */\n\t}\n\n\tif (d1 == d2) {\n\t\treturn retval;  /* false */\n\t}\n\n\tif (c1 == DUK_FP_INFINITE && s1 == 0) {\n\t\t/* x == +Infinity */\n\t\treturn retval;  /* false */\n\t}\n\n\tif (c2 == DUK_FP_INFINITE && s2 == 0) {\n\t\t/* y == +Infinity */\n\t\treturn retval ^ 1;  /* true */\n\t}\n\n\tif (c2 == DUK_FP_INFINITE && s2 != 0) {\n\t\t/* y == -Infinity */\n\t\treturn retval;  /* false */\n\t}\n\n\tif (c1 == DUK_FP_INFINITE && s1 != 0) {\n\t\t/* x == -Infinity */\n\t\treturn retval ^ 1;  /* true */\n\t}\n\n\tif (d1 < d2) {\n\t\treturn retval ^ 1;  /* true */\n\t}\n\n\treturn retval;  /* false */\n}\n#else  /* DUK_USE_PARANOID_MATH */\nDUK_LOCAL duk_bool_t duk__compare_number(duk_bool_t retval, duk_double_t d1, duk_double_t d2) {\n\t/* This comparison tree relies doesn't match the exact steps in\n\t * E5 Section 11.8.5 but should produce the same results.  The\n\t * steps rely on exact IEEE semantics for NaNs, etc.\n\t */\n\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\tif (d1 < d2) {\n\t\t/* In no case should both (d1 < d2) and (d2 < d1) be true.\n\t\t * It's possible that neither is true though, and that's\n\t\t * handled below.\n\t\t */\n\t\tDUK_ASSERT(!(d2 < d1));\n\n\t\t/* - d1 < d2, both d1/d2 are normals (not Infinity, not NaN)\n\t\t * - d2 is +Infinity, d1 != +Infinity and NaN\n\t\t * - d1 is -Infinity, d2 != -Infinity and NaN\n\t\t */\n\t\treturn retval ^ 1;\n\t} else {\n\t\tif (d2 < d1) {\n\t\t\t/* - !(d1 < d2), both d1/d2 are normals (not Infinity, not NaN)\n\t\t\t * - d1 is +Infinity, d2 != +Infinity and NaN\n\t\t\t * - d2 is -Infinity, d1 != -Infinity and NaN\n\t\t\t */\n\t\t\treturn retval;\n\t\t} else {\n\t\t\t/* - d1 and/or d2 is NaN\n\t\t\t * - d1 and d2 are both +/- 0\n\t\t\t * - d1 == d2 (including infinities)\n\t\t\t */\n\t\t\tif (duk_double_is_nan(d1) || duk_double_is_nan(d2)) {\n\t\t\t\t/* Note: undefined from Section 11.8.5 always\n\t\t\t\t * results in false return (see e.g. Section\n\t\t\t\t * 11.8.3) - hence special treatment here.\n\t\t\t\t */\n\t\t\t\treturn 0;  /* zero regardless of negation */\n\t\t\t} else {\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\t}\n}\n#endif  /* DUK_USE_PARANOID_MATH */\n\nDUK_INTERNAL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags) {\n\tduk_double_t d1, d2;\n\tduk_small_int_t rc;\n\tduk_bool_t retval;\n\n\tDUK_ASSERT(DUK_COMPARE_FLAG_NEGATE == 1);  /* Rely on this flag being lowest. */\n\tretval = flags & DUK_COMPARE_FLAG_NEGATE;\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\n\t/* Fast path for fastints */\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_LIKELY(DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y))) {\n\t\treturn duk__compare_fastint(retval,\n\t\t                            DUK_TVAL_GET_FASTINT(tv_x),\n\t\t                            DUK_TVAL_GET_FASTINT(tv_y));\n\t}\n#endif  /* DUK_USE_FASTINT */\n\n\t/* Fast path for numbers (one of which may be a fastint) */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tif (DUK_LIKELY(DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y))) {\n\t\treturn duk__compare_number(retval,\n\t\t                           DUK_TVAL_GET_NUMBER(tv_x),\n\t\t                           DUK_TVAL_GET_NUMBER(tv_y));\n\t}\n#endif\n\n\t/* Slow path */\n\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\n\tif (flags & DUK_COMPARE_FLAG_EVAL_LEFT_FIRST) {\n\t\tduk_to_primitive(thr, -2, DUK_HINT_NUMBER);\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);\n\t} else {\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);\n\t\tduk_to_primitive(thr, -2, DUK_HINT_NUMBER);\n\t}\n\n\t/* Note: reuse variables */\n\ttv_x = DUK_GET_TVAL_NEGIDX(thr, -2);\n\ttv_y = DUK_GET_TVAL_NEGIDX(thr, -1);\n\n\tif (DUK_TVAL_IS_STRING(tv_x) && DUK_TVAL_IS_STRING(tv_y)) {\n\t\tduk_hstring *h1 = DUK_TVAL_GET_STRING(tv_x);\n\t\tduk_hstring *h2 = DUK_TVAL_GET_STRING(tv_y);\n\t\tDUK_ASSERT(h1 != NULL);\n\t\tDUK_ASSERT(h2 != NULL);\n\n\t\tif (DUK_LIKELY(!DUK_HSTRING_HAS_SYMBOL(h1) && !DUK_HSTRING_HAS_SYMBOL(h2))) {\n\t\t\trc = duk_js_string_compare(h1, h2);\n\t\t\tduk_pop_2_unsafe(thr);\n\t\t\tif (rc < 0) {\n\t\t\t\treturn retval ^ 1;\n\t\t\t} else {\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\n\t\t/* One or both are Symbols: fall through to handle in the\n\t\t * generic path.  Concretely, ToNumber() will fail.\n\t\t */\n\t}\n\n\t/* Ordering should not matter (E5 Section 11.8.5, step 3.a). */\n#if 0\n\tif (flags & DUK_COMPARE_FLAG_EVAL_LEFT_FIRST) {\n\t\td1 = duk_to_number_m2(thr);\n\t\td2 = duk_to_number_m1(thr);\n\t} else {\n\t\td2 = duk_to_number_m1(thr);\n\t\td1 = duk_to_number_m2(thr);\n\t}\n#endif\n\td1 = duk_to_number_m2(thr);\n\td2 = duk_to_number_m1(thr);\n\n\t/* We want to duk_pop_2_unsafe(thr); because the values are numbers\n\t * no decref check is needed.\n\t */\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_pop_2_nodecref_unsafe(thr);\n#else\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk_get_tval(thr, -2)));\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk_get_tval(thr, -1)));\n\tDUK_ASSERT(duk_get_top(thr) >= 2);\n\tthr->valstack_top -= 2;\n\ttv_x = thr->valstack_top;\n\ttv_y = tv_x + 1;\n\tDUK_TVAL_SET_UNDEFINED(tv_x);  /* Value stack policy */\n\tDUK_TVAL_SET_UNDEFINED(tv_y);\n#endif\n\n\treturn duk__compare_number(retval, d1, d2);\n}\n\n/*\n *  instanceof\n */\n\n/*\n *  ES2015 Section 7.3.19 describes the OrdinaryHasInstance() algorithm\n *  which covers both bound and non-bound functions; in effect the algorithm\n *  includes E5 Sections 11.8.6, 15.3.5.3, and 15.3.4.5.3.\n *\n *  ES2015 Section 12.9.4 describes the instanceof operator which first\n *  checks @@hasInstance well-known symbol and falls back to\n *  OrdinaryHasInstance().\n *\n *  Limited Proxy support: don't support 'getPrototypeOf' trap but\n *  continue lookup in Proxy target if the value is a Proxy.\n */\n\nDUK_LOCAL duk_bool_t duk__js_instanceof_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_bool_t skip_sym_check) {\n\tduk_hobject *func;\n\tduk_hobject *val;\n\tduk_hobject *proto;\n\tduk_tval *tv;\n\tduk_bool_t skip_first;\n\tduk_uint_t sanity;\n\n\t/*\n\t *  Get the values onto the stack first.  It would be possible to cover\n\t *  some normal cases without resorting to the value stack.\n\t *\n\t *  The right hand side could be a light function (as they generally\n\t *  behave like objects).  Light functions never have a 'prototype'\n\t *  property so E5.1 Section 15.3.5.3 step 3 always throws a TypeError.\n\t *  Using duk_require_hobject() is thus correct (except for error msg).\n\t */\n\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\tfunc = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(func != NULL);\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t/*\n\t *  @@hasInstance check, ES2015 Section 12.9.4, Steps 2-4.\n\t */\n\tif (!skip_sym_check) {\n\t\tif (duk_get_method_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE)) {\n\t\t\t/* [ ... lhs rhs func ] */\n\t\t\tduk_insert(thr, -3);    /* -> [ ... func lhs rhs ] */\n\t\t\tduk_swap_top(thr, -2);  /* -> [ ... func rhs(this) lhs ] */\n\t\t\tduk_call_method(thr, 1);\n\t\t\treturn duk_to_boolean_top_pop(thr);\n\t\t}\n\t}\n#else\n\tDUK_UNREF(skip_sym_check);\n#endif\n\n\t/*\n\t *  For bound objects, [[HasInstance]] just calls the target function\n\t *  [[HasInstance]].  If that is again a bound object, repeat until\n\t *  we find a non-bound Function object.\n\t *\n\t *  The bound function chain is now \"collapsed\" so there can be only\n\t *  one bound function in the chain.\n\t */\n\n\tif (!DUK_HOBJECT_IS_CALLABLE(func)) {\n\t\t/*\n\t\t *  Note: of native ECMAScript objects, only Function instances\n\t\t *  have a [[HasInstance]] internal property.  Custom objects might\n\t\t *  also have it, but not in current implementation.\n\t\t *\n\t\t *  XXX: add a separate flag, DUK_HOBJECT_FLAG_ALLOW_INSTANCEOF?\n\t\t */\n\t\tgoto error_invalid_rval;\n\t}\n\n\tif (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {\n\t\tduk_push_tval(thr, &((duk_hboundfunc *) (void *) func)->target);\n\t\tduk_replace(thr, -2);\n\t\tfunc = duk_require_hobject(thr, -1);  /* lightfunc throws */\n\n\t\t/* Rely on Function.prototype.bind() never creating bound\n\t\t * functions whose target is not proper.\n\t\t */\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(func));\n\t}\n\n\t/*\n\t *  'func' is now a non-bound object which supports [[HasInstance]]\n\t *  (which here just means DUK_HOBJECT_FLAG_CALLABLE).  Move on\n\t *  to execute E5 Section 15.3.5.3.\n\t */\n\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\tDUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(func));\n\n\t/* [ ... lval rval(func) ] */\n\n\t/* For lightfuncs, buffers, and pointers start the comparison directly\n\t * from the virtual prototype object.\n\t */\n\tskip_first = 0;\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -2);\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_LIGHTFUNC:\n\t\tval = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tcase DUK_TAG_BUFFER:\n\t\tval = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tcase DUK_TAG_POINTER:\n\t\tval = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\tskip_first = 1;  /* Ignore object itself on first round. */\n\t\tval = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tdefault:\n\t\tgoto pop2_and_false;\n\t}\n\tDUK_ASSERT(val != NULL);  /* Loop doesn't actually rely on this. */\n\n\t/* Look up .prototype of rval.  Leave it on the value stack in case it\n\t * has been virtualized (e.g. getter, Proxy trap).\n\t */\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_PROTOTYPE);  /* -> [ ... lval rval rval.prototype ] */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\tproto = duk_get_hobject(thr, -1);\n\tif (proto == NULL) {\n\t\tgoto error_invalid_rval_noproto;\n\t}\n#else\n\tproto = duk_require_hobject(thr, -1);\n#endif\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\t/*\n\t\t *  Note: prototype chain is followed BEFORE first comparison.  This\n\t\t *  means that the instanceof lval is never itself compared to the\n\t\t *  rval.prototype property.  This is apparently intentional, see E5\n\t\t *  Section 15.3.5.3, step 4.a.\n\t\t *\n\t\t *  Also note:\n\t\t *\n\t\t *      js> (function() {}) instanceof Function\n\t\t *      true\n\t\t *      js> Function instanceof Function\n\t\t *      true\n\t\t *\n\t\t *  For the latter, h_proto will be Function.prototype, which is the\n\t\t *  built-in Function prototype.  Because Function.[[Prototype]] is\n\t\t *  also the built-in Function prototype, the result is true.\n\t\t */\n\n\t\tif (!val) {\n\t\t\tgoto pop3_and_false;\n\t\t}\n\n\t\tDUK_ASSERT(val != NULL);\n#if defined(DUK_USE_ES6_PROXY)\n\t\tval = duk_hobject_resolve_proxy_target(val);\n#endif\n\n\t\tif (skip_first) {\n\t\t\tskip_first = 0;\n\t\t} else if (val == proto) {\n\t\t\tgoto pop3_and_true;\n\t\t}\n\n\t\tDUK_ASSERT(val != NULL);\n\t\tval = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, val);\n\t} while (--sanity > 0);\n\n\tif (DUK_UNLIKELY(sanity == 0)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tDUK_UNREACHABLE();\n\n pop2_and_false:\n\tduk_pop_2_unsafe(thr);\n\treturn 0;\n\n pop3_and_false:\n\tduk_pop_3_unsafe(thr);\n\treturn 0;\n\n pop3_and_true:\n\tduk_pop_3_unsafe(thr);\n\treturn 1;\n\n error_invalid_rval:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_INSTANCEOF_RVAL);\n\tDUK_WO_NORETURN(return 0;);\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n error_invalid_rval_noproto:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_INSTANCEOF_RVAL_NOPROTO);\n\tDUK_WO_NORETURN(return 0;);\n#endif\n}\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL duk_bool_t duk_js_instanceof_ordinary(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {\n\treturn duk__js_instanceof_helper(thr, tv_x, tv_y, 1 /*skip_sym_check*/);\n}\n#endif\n\nDUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {\n\treturn duk__js_instanceof_helper(thr, tv_x, tv_y, 0 /*skip_sym_check*/);\n}\n\n/*\n *  in\n */\n\n/*\n *  E5 Sections 11.8.7, 8.12.6.\n *\n *  Basically just a property existence check using [[HasProperty]].\n */\n\nDUK_INTERNAL duk_bool_t duk_js_in(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {\n\tduk_bool_t retval;\n\n\t/*\n\t *  Get the values onto the stack first.  It would be possible to cover\n\t *  some normal cases without resorting to the value stack (e.g. if\n\t *  lval is already a string).\n\t */\n\n\t/* XXX: The ES5/5.1/6 specifications require that the key in 'key in obj'\n\t * must be string coerced before the internal HasProperty() algorithm is\n\t * invoked.  A fast path skipping coercion could be safely implemented for\n\t * numbers (as number-to-string coercion has no side effects).  For ES2015\n\t * proxy behavior, the trap 'key' argument must be in a string coerced\n\t * form (which is a shame).\n\t */\n\n\t/* TypeError if rval is not an object or object like (e.g. lightfunc\n\t * or plain buffer).\n\t */\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\tduk_require_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT | DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\n\t(void) duk_to_property_key_hstring(thr, -2);\n\n\tretval = duk_hobject_hasprop(thr,\n\t                             DUK_GET_TVAL_NEGIDX(thr, -1),\n\t                             DUK_GET_TVAL_NEGIDX(thr, -2));\n\n\tduk_pop_2_unsafe(thr);\n\treturn retval;\n}\n\n/*\n *  typeof\n *\n *  E5 Section 11.4.3.\n *\n *  Very straightforward.  The only question is what to return for our\n *  non-standard tag / object types.\n *\n *  There is an unfortunate string constant define naming problem with\n *  typeof return values for e.g. \"Object\" and \"object\"; careful with\n *  the built-in string defines.  The LC_XXX defines are used for the\n *  lowercase variants now.\n */\n\nDUK_INTERNAL duk_small_uint_t duk_js_typeof_stridx(duk_tval *tv_x) {\n\tduk_small_uint_t stridx = 0;\n\n\tswitch (DUK_TVAL_GET_TAG(tv_x)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\tstridx = DUK_STRIDX_LC_UNDEFINED;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\t/* Note: not a typo, \"object\" is returned for a null value. */\n\t\tstridx = DUK_STRIDX_LC_OBJECT;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tstridx = DUK_STRIDX_LC_BOOLEAN;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\t/* Implementation specific. */\n\t\tstridx = DUK_STRIDX_LC_POINTER;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *str;\n\n\t\t/* All internal keys are identified as Symbols. */\n\t\tstr = DUK_TVAL_GET_STRING(tv_x);\n\t\tDUK_ASSERT(str != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(str))) {\n\t\t\tstridx = DUK_STRIDX_LC_SYMBOL;\n\t\t} else {\n\t\t\tstridx = DUK_STRIDX_LC_STRING;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *obj = DUK_TVAL_GET_OBJECT(tv_x);\n\t\tDUK_ASSERT(obj != NULL);\n\t\tif (DUK_HOBJECT_IS_CALLABLE(obj)) {\n\t\t\tstridx = DUK_STRIDX_LC_FUNCTION;\n\t\t} else {\n\t\t\tstridx = DUK_STRIDX_LC_OBJECT;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\t/* Implementation specific.  In Duktape 1.x this would be\n\t\t * 'buffer', in Duktape 2.x changed to 'object' because plain\n\t\t * buffers now mimic Uint8Array objects.\n\t\t */\n\t\tstridx = DUK_STRIDX_LC_OBJECT;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tstridx = DUK_STRIDX_LC_FUNCTION;\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_x));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_x));\n\t\tstridx = DUK_STRIDX_LC_NUMBER;\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\treturn stridx;\n}\n\n/*\n *  Array index and length\n *\n *  Array index: E5 Section 15.4\n *  Array length: E5 Section 15.4.5.1 steps 3.c - 3.d (array length write)\n */\n\n/* Compure array index from string context, or return a \"not array index\"\n * indicator.\n */\nDUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_string(const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uarridx_t res;\n\n\t/* Only strings with byte length 1-10 can be 32-bit array indices.\n\t * Leading zeroes (except '0' alone), plus/minus signs are not allowed.\n\t * We could do a lot of prechecks here, but since most strings won't\n\t * start with any digits, it's simpler to just parse the number and\n\t * fail quickly.\n\t */\n\n\tres = 0;\n\tif (blen == 0) {\n\t\tgoto parse_fail;\n\t}\n\tdo {\n\t\tduk_uarridx_t dig;\n\t\tdig = (duk_uarridx_t) (*str++) - DUK_ASC_0;\n\n\t\tif (dig <= 9U) {\n\t\t\t/* Careful overflow handling.  When multiplying by 10:\n\t\t\t * - 0x19999998 x 10 = 0xfffffff0: no overflow, and adding\n\t\t\t *   0...9 is safe.\n\t\t\t * - 0x19999999 x 10 = 0xfffffffa: no overflow, adding\n\t\t\t *   0...5 is safe, 6...9 overflows.\n\t\t\t * - 0x1999999a x 10 = 0x100000004: always overflow.\n\t\t\t */\n\t\t\tif (DUK_UNLIKELY(res >= 0x19999999UL)) {\n\t\t\t\tif (res >= 0x1999999aUL) {\n\t\t\t\t\t/* Always overflow. */\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(res == 0x19999999UL);\n\t\t\t\tif (dig >= 6U) {\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t\tres = 0xfffffffaUL + dig;\n\t\t\t\tDUK_ASSERT(res >= 0xfffffffaUL);\n\t\t\t\tDUK_ASSERT_DISABLE(res <= 0xffffffffUL);  /* range */\n\t\t\t} else {\n\t\t\t\tres = res * 10U + dig;\n\t\t\t\tif (DUK_UNLIKELY(res == 0)) {\n\t\t\t\t\t/* If 'res' is 0, previous 'res' must\n\t\t\t\t\t * have been 0 and we scanned in a zero.\n\t\t\t\t\t * This is only allowed if blen == 1,\n\t\t\t\t\t * i.e. the exact string '0'.\n\t\t\t\t\t */\n\t\t\t\t\tif (blen == (duk_uint32_t) 1) {\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\t}\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t/* Because 'dig' is unsigned, catches both values\n\t\t\t * above '9' and below '0'.\n\t\t\t */\n\t\t\tgoto parse_fail;\n\t\t}\n\t} while (--blen > 0);\n\n\treturn res;\n\n parse_fail:\n\treturn DUK_HSTRING_NO_ARRAY_INDEX;\n}\n\n#if !defined(DUK_USE_HSTRING_ARRIDX)\n/* Get array index for a string which is known to be an array index.  This helper\n * is needed when duk_hstring doesn't concretely store the array index, but strings\n * are flagged as array indices at intern time.\n */\nDUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_hstring_fast_known(duk_hstring *h) {\n\tconst duk_uint8_t *p;\n\tduk_uarridx_t res;\n\tduk_uint8_t t;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(h));\n\n\tp = DUK_HSTRING_GET_DATA(h);\n\tres = 0;\n\tfor (;;) {\n\t\tt = *p++;\n\t\tif (DUK_UNLIKELY(t == 0)) {\n\t\t\t/* Scanning to NUL is always safe for interned strings. */\n\t\t\tbreak;\n\t\t}\n\t\tDUK_ASSERT(t >= (duk_uint8_t) DUK_ASC_0 && t <= (duk_uint8_t) DUK_ASC_9);\n\t\tres = res * 10U + (duk_uarridx_t) t - (duk_uarridx_t) DUK_ASC_0;\n\t}\n\treturn res;\n}\n\nDUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_hstring_fast(duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n\tif (!DUK_HSTRING_HAS_ARRIDX(h)) {\n\t\treturn DUK_HSTRING_NO_ARRAY_INDEX;\n\t}\n\treturn duk_js_to_arrayindex_hstring_fast_known(h);\n}\n#endif  /* DUK_USE_HSTRING_ARRIDX */\n/*\n *  Identifier access and function closure handling.\n *\n *  Provides the primitives for slow path identifier accesses: GETVAR,\n *  PUTVAR, DELVAR, etc.  The fast path, direct register accesses, should\n *  be used for most identifier accesses.  Consequently, these slow path\n *  primitives should be optimized for maximum compactness.\n *\n *  ECMAScript environment records (declarative and object) are represented\n *  as internal objects with control keys.  Environment records have a\n *  parent record (\"outer environment reference\") which is represented by\n *  the implicit prototype for technical reasons (in other words, it is a\n *  convenient field).  The prototype chain is not followed in the ordinary\n *  sense for variable lookups.\n *\n *  See identifier-handling.rst for more details on the identifier algorithms\n *  and the internal representation.  See function-objects.rst for details on\n *  what function templates and instances are expected to look like.\n *\n *  Care must be taken to avoid duk_tval pointer invalidation caused by\n *  e.g. value stack or object resizing.\n *\n *  TODO: properties for function instances could be initialized much more\n *  efficiently by creating a property allocation for a certain size and\n *  filling in keys and values directly (and INCREFing both with \"bulk incref\"\n *  primitives.\n *\n *  XXX: duk_hobject_getprop() and duk_hobject_putprop() calls are a bit\n *  awkward (especially because they follow the prototype chain); rework\n *  if \"raw\" own property helpers are added.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Local result type for duk__get_identifier_reference() lookup.\n */\n\ntypedef struct {\n\tduk_hobject *env;\n\tduk_hobject *holder;      /* for object-bound identifiers */\n\tduk_tval *value;          /* for register-bound and declarative env identifiers */\n\tduk_uint_t attrs;         /* property attributes for identifier (relevant if value != NULL) */\n\tduk_bool_t has_this;      /* for object-bound identifiers: provide 'this' binding */\n} duk__id_lookup_result;\n\n/*\n *  Create a new function object based on a \"template function\" which contains\n *  compiled bytecode, constants, etc, but lacks a lexical environment.\n *\n *  ECMAScript requires that each created closure is a separate object, with\n *  its own set of editable properties.  However, structured property values\n *  (such as the formal arguments list and the variable map) are shared.\n *  Also the bytecode, constants, and inner functions are shared.\n *\n *  See E5 Section 13.2 for detailed requirements on the function objects;\n *  there are no similar requirements for function \"templates\" which are an\n *  implementation dependent internal feature.  Also see function-objects.rst\n *  for a discussion on the function instance properties provided by this\n *  implementation.\n *\n *  Notes:\n *\n *   * Order of internal properties should match frequency of use, since the\n *     properties will be linearly scanned on lookup (functions usually don't\n *     have enough properties to warrant a hash part).\n *\n *   * The created closure is independent of its template; they do share the\n *     same 'data' buffer object, but the template object itself can be freed\n *     even if the closure object remains reachable.\n */\n\nDUK_LOCAL void duk__inc_data_inner_refcounts(duk_hthread *thr, duk_hcompfunc *f) {\n\tduk_tval *tv, *tv_end;\n\tduk_hobject **funcs, **funcs_end;\n\n\tDUK_UNREF(thr);\n\n\t/* If function creation fails due to out-of-memory, the data buffer\n\t * pointer may be NULL in some cases.  That's actually possible for\n\t * GC code, but shouldn't be possible here because the incomplete\n\t * function will be unwound from the value stack and never instantiated.\n\t */\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, f) != NULL);\n\n\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, f);\n\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, f);\n\twhile (tv < tv_end) {\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\ttv++;\n\t}\n\n\tfuncs = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, f);\n\tfuncs_end = DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, f);\n\twhile (funcs < funcs_end) {\n\t\tDUK_HEAPHDR_INCREF(thr, (duk_heaphdr *) *funcs);\n\t\tfuncs++;\n\t}\n}\n\n/* Push a new closure on the stack.\n *\n * Note: if fun_temp has NEWENV, i.e. a new lexical and variable declaration\n * is created when the function is called, only outer_lex_env matters\n * (outer_var_env is ignored and may or may not be same as outer_lex_env).\n */\n\nDUK_LOCAL const duk_uint16_t duk__closure_copy_proplist[] = {\n\t/* order: most frequent to least frequent */\n\tDUK_STRIDX_INT_VARMAP,\n\tDUK_STRIDX_INT_FORMALS,\n#if defined(DUK_USE_PC2LINE)\n\tDUK_STRIDX_INT_PC2LINE,\n#endif\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tDUK_STRIDX_FILE_NAME,\n#endif\n#if defined(DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY)\n\tDUK_STRIDX_INT_SOURCE\n#endif\n};\n\nDUK_INTERNAL\nvoid duk_js_push_closure(duk_hthread *thr,\n                         duk_hcompfunc *fun_temp,\n                         duk_hobject *outer_var_env,\n                         duk_hobject *outer_lex_env,\n                         duk_bool_t add_auto_proto) {\n\tduk_hcompfunc *fun_clos;\n\tduk_harray *formals;\n\tduk_small_uint_t i;\n\tduk_uint_t len_value;\n\n\tDUK_ASSERT(fun_temp != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_temp) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_temp) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_temp) != NULL);\n\tDUK_ASSERT(outer_var_env != NULL);\n\tDUK_ASSERT(outer_lex_env != NULL);\n\tDUK_UNREF(len_value);\n\n\tDUK_STATS_INC(thr->heap, stats_envrec_pushclosure);\n\n\tfun_clos = duk_push_hcompfunc(thr);\n\tDUK_ASSERT(fun_clos != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) fun_clos) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\n\tduk_push_hobject(thr, &fun_temp->obj);  /* -> [ ... closure template ] */\n\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun_clos));\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_clos) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_clos) == NULL);\n\n\tDUK_HCOMPFUNC_SET_DATA(thr->heap, fun_clos, DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_temp));\n\tDUK_HCOMPFUNC_SET_FUNCS(thr->heap, fun_clos, DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_temp));\n\tDUK_HCOMPFUNC_SET_BYTECODE(thr->heap, fun_clos, DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_temp));\n\n\t/* Note: all references inside 'data' need to get their refcounts\n\t * upped too.  This is the case because refcounts are decreased\n\t * through every function referencing 'data' independently.\n\t */\n\n\tDUK_HBUFFER_INCREF(thr, DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos));\n\tduk__inc_data_inner_refcounts(thr, fun_temp);\n\n\tfun_clos->nregs = fun_temp->nregs;\n\tfun_clos->nargs = fun_temp->nargs;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tfun_clos->start_line = fun_temp->start_line;\n\tfun_clos->end_line = fun_temp->end_line;\n#endif\n\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_clos) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_clos) != NULL);\n\n\t/* XXX: Could also copy from template, but there's no way to have any\n\t * other value here now (used code has no access to the template).\n\t * Prototype is set by duk_push_hcompfunc().\n\t */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, &fun_clos->obj) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#if 0\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, &fun_clos->obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#endif\n\n\t/* Copy duk_hobject flags as is from the template using a mask.\n\t * Leave out duk_heaphdr owned flags just in case (e.g. if there's\n\t * some GC flag or similar).  Some flags can then be adjusted\n\t * separately if necessary.\n\t */\n\n\t/* DUK_HEAPHDR_SET_FLAGS() masks changes to non-duk_heaphdr flags only. */\n\tDUK_HEAPHDR_SET_FLAGS((duk_heaphdr *) fun_clos, DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) fun_temp));\n\tDUK_DD(DUK_DDPRINT(\"fun_temp heaphdr flags: 0x%08lx, fun_clos heaphdr flags: 0x%08lx\",\n\t                   (unsigned long) DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) fun_temp),\n\t                   (unsigned long) DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) fun_clos)));\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&fun_clos->obj));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(&fun_clos->obj));\n\t/* DUK_HOBJECT_FLAG_ARRAY_PART: don't care */\n\t/* DUK_HOBJECT_FLAG_NEWENV: handled below */\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(&fun_clos->obj));\n\n\tif (!DUK_HOBJECT_HAS_CONSTRUCTABLE(&fun_clos->obj)) {\n\t\t/* If the template is not constructable don't add an automatic\n\t\t * .prototype property.  This is the case for e.g. ES2015 object\n\t\t * literal getters/setters and method definitions.\n\t\t */\n\t\tadd_auto_proto = 0;\n\t}\n\n\t/*\n\t *  Setup environment record properties based on the template and\n\t *  its flags.\n\t *\n\t *  If DUK_HOBJECT_HAS_NEWENV(fun_temp) is true, the environment\n\t *  records represent identifiers \"outside\" the function; the\n\t *  \"inner\" environment records are created on demand.  Otherwise,\n\t *  the environment records are those that will be directly used\n\t *  (e.g. for declarations).\n\t *\n\t *  _Lexenv is always set; _Varenv defaults to _Lexenv if missing,\n\t *  so _Varenv is only set if _Lexenv != _Varenv.\n\t *\n\t *  This is relatively complex, see doc/identifier-handling.rst.\n\t */\n\n\tif (DUK_HOBJECT_HAS_NEWENV(&fun_clos->obj)) {\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\t\tif (DUK_HOBJECT_HAS_NAMEBINDING(&fun_clos->obj)) {\n\t\t\tduk_hobject *proto;\n\t\t\tduk_hdecenv *new_env;\n\n\t\t\t/*\n\t\t\t *  Named function expression, name needs to be bound\n\t\t\t *  in an intermediate environment record.  The \"outer\"\n\t\t\t *  lexical/variable environment will thus be:\n\t\t\t *\n\t\t\t *  a) { funcname: <func>, __prototype: outer_lex_env }\n\t\t\t *  b) { funcname: <func>, __prototype:  <globalenv> }  (if outer_lex_env missing)\n\t\t\t */\n\n\t\t\tif (outer_lex_env) {\n\t\t\t\tproto = outer_lex_env;\n\t\t\t} else {\n\t\t\t\tproto = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t\t\t}\n\n\t\t\t/* -> [ ... closure template env ] */\n\t\t\tnew_env = duk_hdecenv_alloc(thr,\n\t\t\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\t\t\tDUK_ASSERT(new_env != NULL);\n\t\t\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, proto);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, proto);\n\n\t\t\tDUK_ASSERT(new_env->thread == NULL);  /* Closed. */\n\t\t\tDUK_ASSERT(new_env->varmap == NULL);\n\n\t\t\t/* It's important that duk_xdef_prop() is a 'raw define' so that any\n\t\t\t * properties in an ancestor are never an issue (they should never be\n\t\t\t * e.g. non-writable, but just in case).\n\t\t\t *\n\t\t\t * Because template objects are not visible to user code, the case\n\t\t\t * where .name is missing shouldn't happen in practice.  It it does,\n\t\t\t * the name 'undefined' gets bound and maps to the closure (which is\n\t\t\t * a bit odd, but safe).\n\t\t\t */\n\t\t\t(void) duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME);\n\t\t\t/* -> [ ... closure template env funcname ] */\n\t\t\tduk_dup_m4(thr);                                           /* -> [ ... closure template env funcname closure ] */\n\t\t\tduk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_NONE);           /* -> [ ... closure template env ] */\n\t\t\t/* env[funcname] = closure */\n\n\t\t\t/* [ ... closure template env ] */\n\n\t\t\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, fun_clos, (duk_hobject *) new_env);\n\t\t\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, (duk_hobject *) new_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env);\n\t\t\tduk_pop_unsafe(thr);\n\n\t\t\t/* [ ... closure template ] */\n\t\t}\n\t\telse\n#endif  /* DUK_USE_FUNC_NAME_PROPERTY */\n\t\t{\n\t\t\t/*\n\t\t\t *  Other cases (function declaration, anonymous function expression,\n\t\t\t *  strict direct eval code).  The \"outer\" environment will be whatever\n\t\t\t *  the caller gave us.\n\t\t\t */\n\n\t\t\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, fun_clos, outer_lex_env);\n\t\t\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, outer_lex_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, outer_lex_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, outer_lex_env);\n\n\t\t\t/* [ ... closure template ] */\n\t\t}\n\t} else {\n\t\t/*\n\t\t *  Function gets no new environment when called.  This is the\n\t\t *  case for global code, indirect eval code, and non-strict\n\t\t *  direct eval code.  There is no direct correspondence to the\n\t\t *  E5 specification, as global/eval code is not exposed as a\n\t\t *  function.\n\t\t */\n\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NAMEBINDING(&fun_temp->obj));\n\n\t\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, fun_clos, outer_lex_env);\n\t\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, outer_var_env);\n\t\tDUK_HOBJECT_INCREF(thr, outer_lex_env);  /* NULLs not allowed; asserted on entry */\n\t\tDUK_HOBJECT_INCREF(thr, outer_var_env);\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"closure varenv -> %!ipO, lexenv -> %!ipO\",\n\t                     (duk_heaphdr *) fun_clos->var_env,\n\t                     (duk_heaphdr *) fun_clos->lex_env));\n\n\t/* Call handling assumes this for all callable closures. */\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_LEXENV(thr->heap, fun_clos) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_VARENV(thr->heap, fun_clos) != NULL);\n\n\t/*\n\t *  Copy some internal properties directly\n\t *\n\t *  The properties will be non-writable and non-enumerable, but\n\t *  configurable.\n\t *\n\t *  Function templates are bare objects, so inheritance of internal\n\t *  Symbols is not an issue here even when using ordinary property\n\t *  reads.  The function instance created is not bare, so internal\n\t *  Symbols must be defined without inheritance checks.\n\t */\n\n\t/* [ ... closure template ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"copying properties: closure=%!iT, template=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tfor (i = 0; i < (duk_small_uint_t) (sizeof(duk__closure_copy_proplist) / sizeof(duk_uint16_t)); i++) {\n\t\tduk_small_int_t stridx = (duk_small_int_t) duk__closure_copy_proplist[i];\n\t\tif (duk_xget_owndataprop_stridx_short(thr, -1, stridx)) {\n\t\t\t/* [ ... closure template val ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copying property, stridx=%ld -> found\", (long) stridx));\n\t\t\tduk_xdef_prop_stridx_short(thr, -3, stridx, DUK_PROPDESC_FLAGS_C);\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copying property, stridx=%ld -> not found\", (long) stridx));\n\t\t\tduk_pop_unsafe(thr);\n\t\t}\n\t}\n\n\t/*\n\t *  \"length\" maps to number of formals (E5 Section 13.2) for function\n\t *  declarations/expressions (non-bound functions).  Note that 'nargs'\n\t *  is NOT necessarily equal to the number of arguments.  Use length\n\t *  of _Formals; if missing, assume nargs matches .length.\n\t */\n\n\t/* [ ... closure template ] */\n\n\tformals = duk_hobject_get_formals(thr, (duk_hobject *) fun_temp);\n\tif (formals) {\n\t\tlen_value = (duk_uint_t) formals->length;\n\t\tDUK_DD(DUK_DDPRINT(\"closure length from _Formals -> %ld\", (long) len_value));\n\t} else {\n\t\tlen_value = fun_temp->nargs;\n\t\tDUK_DD(DUK_DDPRINT(\"closure length defaulted from nargs -> %ld\", (long) len_value));\n\t}\n\n\tduk_push_uint(thr, len_value);  /* [ ... closure template len_value ] */\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);\n\n\t/*\n\t *  \"prototype\" is, by default, a fresh object with the \"constructor\"\n\t *  property.\n\t *\n\t *  Note that this creates a circular reference for every function\n\t *  instance (closure) which prevents refcount-based collection of\n\t *  function instances.\n\t *\n\t *  XXX: Try to avoid creating the default prototype object, because\n\t *  many functions are not used as constructors and the default\n\t *  prototype is unnecessary.  Perhaps it could be created on-demand\n\t *  when it is first accessed?\n\t */\n\n\t/* [ ... closure template ] */\n\n\tif (add_auto_proto) {\n\t\tduk_push_object(thr);  /* -> [ ... closure template newobj ] */\n\t\tduk_dup_m3(thr);       /* -> [ ... closure template newobj closure ] */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC);  /* -> [ ... closure template newobj ] */\n\t\tduk_compact(thr, -1);  /* compact the prototype */\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W);     /* -> [ ... closure template ] */\n\t}\n\n\t/*\n\t *  \"arguments\" and \"caller\" must be mapped to throwers for strict\n\t *  mode and bound functions (E5 Section 15.3.5).\n\t *\n\t *  XXX: This is expensive to have for every strict function instance.\n\t *  Try to implement as virtual properties or on-demand created properties.\n\t */\n\n\t/* [ ... closure template ] */\n\n\tif (DUK_HOBJECT_HAS_STRICT(&fun_clos->obj)) {\n\t\tduk_xdef_prop_stridx_thrower(thr, -2, DUK_STRIDX_CALLER);\n\t\tduk_xdef_prop_stridx_thrower(thr, -2, DUK_STRIDX_LC_ARGUMENTS);\n\t} else {\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is non-strict and non-standard 'caller' property in use, add initial 'null' value\"));\n\t\tduk_push_null(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_CALLER, DUK_PROPDESC_FLAGS_NONE);\n#else\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is non-strict and non-standard 'caller' property not used\"));\n#endif\n\t}\n\n\t/*\n\t *  \"name\" used to be non-standard but is now defined by ES2015.\n\t *  In ES2015/ES2016 the .name property is configurable.\n\t */\n\n\t/* [ ... closure template ] */\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\t/* XXX: Look for own property only; doesn't matter much because\n\t * templates are bare objects.\n\t */\n\tif (duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME)) {\n\t\t/* [ ... closure template name ] */\n\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\t\tDUK_DD(DUK_DDPRINT(\"setting function instance name to %!T\", duk_get_tval(thr, -1)));\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);  /* -> [ ... closure template ] */\n\t} else {\n\t\t/* Anonymous functions don't have a .name in ES2015, so don't set\n\t\t * it on the instance either.  The instance will then inherit\n\t\t * it from Function.prototype.name.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"not setting function instance .name\"));\n\t\tduk_pop_unsafe(thr);\n\t}\n#endif\n\n\t/*\n\t *  Compact the closure, in most cases no properties will be added later.\n\t *  Also, without this the closures end up having unused property slots\n\t *  (e.g. in Duktape 0.9.0, 8 slots would be allocated and only 7 used).\n\t *  A better future solution would be to allocate the closure directly\n\t *  to correct size (and setup the properties directly without going\n\t *  through the API).\n\t */\n\n\tduk_compact(thr, -2);\n\n\t/*\n\t *  Some assertions (E5 Section 13.2).\n\t */\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(&fun_clos->obj) == DUK_HOBJECT_CLASS_FUNCTION);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, &fun_clos->obj) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(&fun_clos->obj));\n\tDUK_ASSERT(duk_has_prop_stridx(thr, -2, DUK_STRIDX_LENGTH) != 0);\n\tDUK_ASSERT(add_auto_proto == 0 || duk_has_prop_stridx(thr, -2, DUK_STRIDX_PROTOTYPE) != 0);\n\t/* May be missing .name */\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(&fun_clos->obj) ||\n\t           duk_has_prop_stridx(thr, -2, DUK_STRIDX_CALLER) != 0);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(&fun_clos->obj) ||\n\t           duk_has_prop_stridx(thr, -2, DUK_STRIDX_LC_ARGUMENTS) != 0);\n\n\t/*\n\t *  Finish\n\t */\n\n\t/* [ ... closure template ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"created function instance: template=%!iT -> closure=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (duk_tval *) duk_get_tval(thr, -2)));\n\n\tduk_pop_unsafe(thr);\n\n\t/* [ ... closure ] */\n}\n\n/*\n *  Delayed activation environment record initialization (for functions\n *  with NEWENV).\n *\n *  The non-delayed initialization is handled by duk_handle_call().\n */\n\nDUK_LOCAL void duk__preallocate_env_entries(duk_hthread *thr, duk_hobject *varmap, duk_hobject *env) {\n\tduk_uint_fast32_t i;\n\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(varmap); i++) {\n\t\tduk_hstring *key;\n\n\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, varmap, i);\n\t\tDUK_ASSERT(key != NULL);   /* assume keys are compact in _Varmap */\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, varmap, i));  /* assume plain values */\n\n\t\t/* Predefine as 'undefined' to reserve a property slot.\n\t\t * This makes the unwind process (where register values\n\t\t * are copied to the env object) safe against throwing.\n\t\t *\n\t\t * XXX: This could be made much faster by creating the\n\t\t * property table directly.\n\t\t */\n\t\tduk_push_undefined(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"preallocate env entry for key %!O\", key));\n\t\tduk_hobject_define_property_internal(thr, env, key, DUK_PROPDESC_FLAGS_WE);\n\t}\n}\n\n/* shared helper */\nDUK_INTERNAL\nduk_hobject *duk_create_activation_environment_record(duk_hthread *thr,\n                                                      duk_hobject *func,\n                                                      duk_size_t bottom_byteoff) {\n\tduk_hdecenv *env;\n\tduk_hobject *parent;\n\tduk_hcompfunc *f;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\n\tDUK_STATS_INC(thr->heap, stats_envrec_create);\n\n\tf = (duk_hcompfunc *) func;\n\tparent = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f);\n\tif (!parent) {\n\t\tparent = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t}\n\n\tenv = duk_hdecenv_alloc(thr,\n\t                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\tDUK_ASSERT(env != NULL);\n\tduk_push_hobject(thr, (duk_hobject *) env);\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) env, parent);\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, parent);  /* parent env is the prototype */\n\n\t/* open scope information, for compiled functions only */\n\n\tDUK_ASSERT(env->thread == NULL);\n\tDUK_ASSERT(env->varmap == NULL);\n\tDUK_ASSERT(env->regbase_byteoff == 0);\n\tif (DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\tduk_hobject *varmap;\n\n\t\tvarmap = duk_hobject_get_varmap(thr, func);\n\t\tif (varmap != NULL) {\n\t\t\tenv->varmap = varmap;\n\t\t\tDUK_HOBJECT_INCREF(thr, varmap);\n\t\t\tenv->thread = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tenv->regbase_byteoff = bottom_byteoff;\n\n\t\t\t/* Preallocate env property table to avoid potential\n\t\t\t * for out-of-memory on unwind when the env is closed.\n\t\t\t */\n\t\t\tduk__preallocate_env_entries(thr, varmap, (duk_hobject *) env);\n\t\t} else {\n\t\t\t/* If function has no _Varmap, leave the environment closed. */\n\t\t\tDUK_ASSERT(env->thread == NULL);\n\t\t\tDUK_ASSERT(env->varmap == NULL);\n\t\t\tDUK_ASSERT(env->regbase_byteoff == 0);\n\t\t}\n\t}\n\n\treturn (duk_hobject *) env;\n}\n\nDUK_INTERNAL\nvoid duk_js_init_activation_environment_records_delayed(duk_hthread *thr,\n                                                        duk_activation *act) {\n\tduk_hobject *func;\n\tduk_hobject *env;\n\n\tDUK_ASSERT(thr != NULL);\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));  /* bound functions are never in act 'func' */\n\n\t/*\n\t *  Delayed initialization only occurs for 'NEWENV' functions.\n\t */\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func));\n\tDUK_ASSERT(act->lex_env == NULL);\n\tDUK_ASSERT(act->var_env == NULL);\n\n\tDUK_STATS_INC(thr->heap, stats_envrec_delayedcreate);\n\n\tenv = duk_create_activation_environment_record(thr, func, act->bottom_byteoff);\n\tDUK_ASSERT(env != NULL);\n\t/* 'act' is a stable pointer, so still OK. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"created delayed fresh env: %!ipO\", (duk_heaphdr *) env));\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t{\n\t\tduk_hobject *p = env;\n\t\twhile (p) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"  -> %!ipO\", (duk_heaphdr *) p));\n\t\t\tp = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, p);\n\t\t}\n\t}\n#endif\n\n\tact->lex_env = env;\n\tact->var_env = env;\n\tDUK_HOBJECT_INCREF(thr, env);  /* XXX: incref by count (here 2 times) */\n\tDUK_HOBJECT_INCREF(thr, env);\n\n\tduk_pop_unsafe(thr);\n}\n\n/*\n *  Closing environment records.\n *\n *  The environment record MUST be closed with the thread where its activation\n *  is; i.e. if 'env' is open, 'thr' must match env->thread, and the regbase\n *  and varmap must still be valid.  On entry, 'env' must be reachable.\n */\n\nDUK_INTERNAL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject *env) {\n\tduk_uint_fast32_t i;\n\tduk_hobject *varmap;\n\tduk_hstring *key;\n\tduk_tval *tv;\n\tduk_uint_t regnum;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL);\n\n\tif (DUK_UNLIKELY(!DUK_HOBJECT_IS_DECENV(env))) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"env not a declarative record: %!iO\", (duk_heaphdr *) env));\n\t\treturn;\n\t}\n\n\tvarmap = ((duk_hdecenv *) env)->varmap;\n\tif (varmap == NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"env already closed: %!iO\", (duk_heaphdr *) env));\n\n\t\treturn;\n\t}\n\tDUK_ASSERT(((duk_hdecenv *) env)->thread != NULL);\n\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env);\n\n\tDUK_DDD(DUK_DDDPRINT(\"closing env: %!iO\", (duk_heaphdr *) env));\n\tDUK_DDD(DUK_DDDPRINT(\"varmap: %!O\", (duk_heaphdr *) varmap));\n\n\t/* Env must be closed in the same thread as where it runs. */\n\tDUK_ASSERT(((duk_hdecenv *) env)->thread == thr);\n\n\t/* XXX: additional conditions when to close variables? we don't want to do it\n\t * unless the environment may have \"escaped\" (referenced in a function closure).\n\t * With delayed environments, the existence is probably good enough of a check.\n\t */\n\n\t/* Note: we rely on the _Varmap having a bunch of nice properties, like:\n\t *  - being compacted and unmodified during this process\n\t *  - not containing an array part\n\t *  - having correct value types\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"copying bound register values, %ld bound regs\", (long) DUK_HOBJECT_GET_ENEXT(varmap)));\n\n\t/* Copy over current variable values from value stack to the\n\t * environment record.  The scope object is empty but may\n\t * inherit from another scope which has conflicting names.\n\t */\n\n\t/* XXX: Do this using a once allocated entry area, no side effects.\n\t * Hash part would need special treatment however (maybe copy, and\n\t * then realloc with hash part if large enough).\n\t */\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(varmap); i++) {\n\t\tduk_size_t regbase_byteoff;\n\n\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, varmap, i);\n\t\tDUK_ASSERT(key != NULL);   /* assume keys are compact in _Varmap */\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, varmap, i));  /* assume plain values */\n\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, varmap, i);\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tDUK_ASSERT(DUK_TVAL_GET_NUMBER(tv) <= (duk_double_t) DUK_UINT32_MAX);  /* limits */\n#if defined(DUK_USE_FASTINT)\n\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\t\tregnum = (duk_uint_t) DUK_TVAL_GET_FASTINT_U32(tv);\n#else\n\t\tregnum = (duk_uint_t) DUK_TVAL_GET_NUMBER(tv);\n#endif\n\n\t\tregbase_byteoff = ((duk_hdecenv *) env)->regbase_byteoff;\n\t\tDUK_ASSERT((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum >= (duk_uint8_t *) thr->valstack);\n\t\tDUK_ASSERT((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum < (duk_uint8_t *) thr->valstack_top);\n\n\t\t/* Write register value into env as named properties.\n\t\t * If property already exists, overwrites silently.\n\t\t * Property is writable, but not deletable (not configurable\n\t\t * in terms of property attributes).\n\t\t *\n\t\t * This property write must not throw because we're unwinding\n\t\t * and unwind code is not allowed to throw at present.  The\n\t\t * call itself has no such guarantees, but we've preallocated\n\t\t * entries for each property when the env was created, so no\n\t\t * out-of-memory error should be possible.  If this guarantee\n\t\t * is not provided, problems like GH-476 may happen.\n\t\t */\n\t\tduk_push_tval(thr, (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum));\n\t\tDUK_DDD(DUK_DDDPRINT(\"closing identifier %!O -> reg %ld, value %!T\",\n\t\t                     (duk_heaphdr *) key,\n\t\t                     (long) regnum,\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\tduk_hobject_define_property_internal(thr, env, key, DUK_PROPDESC_FLAGS_WE);\n\t}\n\n\t/* NULL atomically to avoid inconsistent state + side effects. */\n\tDUK_HOBJECT_DECREF_NORZ(thr, ((duk_hdecenv *) env)->thread);\n\tDUK_HOBJECT_DECREF_NORZ(thr, ((duk_hdecenv *) env)->varmap);\n\t((duk_hdecenv *) env)->thread = NULL;\n\t((duk_hdecenv *) env)->varmap = NULL;\n\n\tDUK_DDD(DUK_DDDPRINT(\"env after closing: %!O\", (duk_heaphdr *) env));\n}\n\n/*\n *  GETIDREF: a GetIdentifierReference-like helper.\n *\n *  Provides a parent traversing lookup and a single level lookup\n *  (for HasBinding).\n *\n *  Instead of returning the value, returns a bunch of values allowing\n *  the caller to read, write, or delete the binding.  Value pointers\n *  are duk_tval pointers which can be mutated directly as long as\n *  refcounts are properly updated.  Note that any operation which may\n *  reallocate valstacks or compact objects may invalidate the returned\n *  duk_tval (but not object) pointers, so caller must be very careful.\n *\n *  If starting environment record 'env' is given, 'act' is ignored.\n *  However, if 'env' is NULL, the caller may identify, in 'act', an\n *  activation which hasn't had its declarative environment initialized\n *  yet.  The activation registers are then looked up, and its parent\n *  traversed normally.\n *\n *  The 'out' structure values are only valid if the function returns\n *  success (non-zero).\n */\n\n/* lookup name from an open declarative record's registers */\nDUK_LOCAL\nduk_bool_t duk__getid_open_decl_env_regs(duk_hthread *thr,\n                                         duk_hstring *name,\n                                         duk_hdecenv *env,\n                                         duk__id_lookup_result *out) {\n\tduk_tval *tv;\n\tduk_size_t reg_rel;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(out != NULL);\n\n\tDUK_ASSERT(DUK_HOBJECT_IS_DECENV((duk_hobject *) env));\n\tDUK_HDECENV_ASSERT_VALID(env);\n\n\tif (env->thread == NULL) {\n\t\t/* already closed */\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(env->varmap != NULL);\n\n\ttv = duk_hobject_find_entry_tval_ptr(thr->heap, env->varmap, name);\n\tif (DUK_UNLIKELY(tv == NULL)) {\n\t\treturn 0;\n\t}\n\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\tDUK_ASSERT(DUK_TVAL_GET_NUMBER(tv) <= (duk_double_t) DUK_UINT32_MAX);  /* limits */\n#if defined(DUK_USE_FASTINT)\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\treg_rel = (duk_size_t) DUK_TVAL_GET_FASTINT_U32(tv);\n#else\n\treg_rel = (duk_size_t) DUK_TVAL_GET_NUMBER(tv);\n#endif\n\tDUK_ASSERT_DISABLE(reg_rel >= 0);  /* unsigned */\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) env->thread->valstack + env->regbase_byteoff + sizeof(duk_tval) * reg_rel);\n\tDUK_ASSERT(tv >= env->thread->valstack && tv < env->thread->valstack_end);  /* XXX: more accurate? */\n\n\tout->value = tv;\n\tout->attrs = DUK_PROPDESC_FLAGS_W;  /* registers are mutable, non-deletable */\n\tout->env = (duk_hobject *) env;\n\tout->holder = NULL;\n\tout->has_this = 0;\n\treturn 1;\n}\n\n/* lookup name from current activation record's functions' registers */\nDUK_LOCAL\nduk_bool_t duk__getid_activation_regs(duk_hthread *thr,\n                                      duk_hstring *name,\n                                      duk_activation *act,\n                                      duk__id_lookup_result *out) {\n\tduk_tval *tv;\n\tduk_hobject *func;\n\tduk_hobject *varmap;\n\tduk_size_t reg_rel;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(out != NULL);\n\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func));\n\n\tif (!DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\treturn 0;\n\t}\n\n\t/* XXX: move varmap to duk_hcompfunc struct field? */\n\tvarmap = duk_hobject_get_varmap(thr, func);\n\tif (!varmap) {\n\t\treturn 0;\n\t}\n\n\ttv = duk_hobject_find_entry_tval_ptr(thr->heap, varmap, name);\n\tif (!tv) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\treg_rel = (duk_size_t) DUK_TVAL_GET_NUMBER(tv);\n\tDUK_ASSERT_DISABLE(reg_rel >= 0);\n\tDUK_ASSERT(reg_rel < ((duk_hcompfunc *) func)->nregs);\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff);\n\ttv += reg_rel;\n\n\tout->value = tv;\n\tout->attrs = DUK_PROPDESC_FLAGS_W;  /* registers are mutable, non-deletable */\n\tout->env = NULL;\n\tout->holder = NULL;\n\tout->has_this = 0;\n\treturn 1;\n}\n\nDUK_LOCAL\nduk_bool_t duk__get_identifier_reference(duk_hthread *thr,\n                                         duk_hobject *env,\n                                         duk_hstring *name,\n                                         duk_activation *act,\n                                         duk_bool_t parents,\n                                         duk__id_lookup_result *out) {\n\tduk_tval *tv;\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL || act != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(out != NULL);\n\n\tDUK_ASSERT(!env || DUK_HOBJECT_IS_ENV(env));\n\tDUK_ASSERT(!env || !DUK_HOBJECT_HAS_ARRAY_PART(env));\n\n\t/*\n\t *  Conceptually, we look for the identifier binding by starting from\n\t *  'env' and following to chain of environment records (represented\n\t *  by the prototype chain).\n\t *\n\t *  If 'env' is NULL, the current activation does not yet have an\n\t *  allocated declarative environment record; this should be treated\n\t *  exactly as if the environment record existed but had no bindings\n\t *  other than register bindings.\n\t *\n\t *  Note: we assume that with the DUK_HOBJECT_FLAG_NEWENV cleared\n\t *  the environment will always be initialized immediately; hence\n\t *  a NULL 'env' should only happen with the flag set.  This is the\n\t *  case for: (1) function calls, and (2) strict, direct eval calls.\n\t */\n\n\tif (env == NULL && act != NULL) {\n\t\tduk_hobject *func;\n\t\tduk_hcompfunc *f;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference: env is NULL, activation is non-NULL -> \"\n\t\t                     \"delayed env case, look up activation regs first\"));\n\n\t\t/*\n\t\t *  Try registers\n\t\t */\n\n\t\tif (duk__getid_activation_regs(thr, name, act, out)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t                     \"(found from register bindings when env=NULL)\",\n\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\treturn 1;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"not found in current activation regs\"));\n\n\t\t/*\n\t\t *  Not found in registers, proceed to the parent record.\n\t\t *  Here we need to determine what the parent would be,\n\t\t *  if 'env' was not NULL (i.e. same logic as when initializing\n\t\t *  the record).\n\t\t *\n\t\t *  Note that environment initialization is only deferred when\n\t\t *  DUK_HOBJECT_HAS_NEWENV is set, and this only happens for:\n\t\t *    - Function code\n\t\t *    - Strict eval code\n\t\t *\n\t\t *  We only need to check _Lexenv here; _Varenv exists only if it\n\t\t *  differs from _Lexenv (and thus _Lexenv will also be present).\n\t\t */\n\n\t\tif (!parents) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference failed, no parent traversal \"\n\t\t\t                     \"(not found from register bindings when env=NULL)\"));\n\t\t\tgoto fail_not_found;\n\t\t}\n\n\t\tfunc = DUK_ACT_GET_FUNC(act);\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func));\n\t\tf = (duk_hcompfunc *) func;\n\n\t\tenv = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f);\n\t\tif (!env) {\n\t\t\tenv = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"continue lookup from env: %!iO\",\n\t\t                     (duk_heaphdr *) env));\n\t}\n\n\t/*\n\t *  Prototype walking starting from 'env'.\n\t *\n\t *  ('act' is not needed anywhere here.)\n\t */\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\twhile (env != NULL) {\n\t\tduk_small_uint_t cl;\n\t\tduk_uint_t attrs;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference, name=%!O, considering env=%p -> %!iO\",\n\t\t                     (duk_heaphdr *) name,\n\t\t                     (void *) env,\n\t\t                     (duk_heaphdr *) env));\n\n\t\tDUK_ASSERT(env != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_ENV(env));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(env));\n\n\t\tcl = DUK_HOBJECT_GET_CLASS_NUMBER(env);\n\t\tDUK_ASSERT(cl == DUK_HOBJECT_CLASS_OBJENV || cl == DUK_HOBJECT_CLASS_DECENV);\n\t\tif (cl == DUK_HOBJECT_CLASS_DECENV) {\n\t\t\t/*\n\t\t\t *  Declarative environment record.\n\t\t\t *\n\t\t\t *  Identifiers can never be stored in ancestors and are\n\t\t\t *  always plain values, so we can use an internal helper\n\t\t\t *  and access the value directly with an duk_tval ptr.\n\t\t\t *\n\t\t\t *  A closed environment is only indicated by it missing\n\t\t\t *  the \"book-keeping\" properties required for accessing\n\t\t\t *  register-bound variables.\n\t\t\t */\n\n\t\t\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env);\n\t\t\tif (duk__getid_open_decl_env_regs(thr, name, (duk_hdecenv *) env, out)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t\t                     \"(declarative environment record, scope open, found in regs)\",\n\t\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\ttv = duk_hobject_find_entry_tval_ptr_and_attrs(thr->heap, env, name, &attrs);\n\t\t\tif (tv) {\n\t\t\t\tout->value = tv;\n\t\t\t\tout->attrs = attrs;\n\t\t\t\tout->env = env;\n\t\t\t\tout->holder = env;\n\t\t\t\tout->has_this = 0;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t\t                     \"(declarative environment record, found in properties)\",\n\t\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Object environment record.\n\t\t\t *\n\t\t\t *  Binding (target) object is an external, uncontrolled object.\n\t\t\t *  Identifier may be bound in an ancestor property, and may be\n\t\t\t *  an accessor.  Target can also be a Proxy which we must support\n\t\t\t *  here.\n\t\t\t */\n\n\t\t\t/* XXX: we could save space by using _Target OR _This.  If _Target, assume\n\t\t\t * this binding is undefined.  If _This, assumes this binding is _This, and\n\t\t\t * target is also _This.  One property would then be enough.\n\t\t\t */\n\n\t\t\tduk_hobject *target;\n\t\t\tduk_bool_t found;\n\n\t\t\tDUK_ASSERT(cl == DUK_HOBJECT_CLASS_OBJENV);\n\t\t\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) env);\n\n\t\t\ttarget = ((duk_hobjenv *) env)->target;\n\t\t\tDUK_ASSERT(target != NULL);\n\n\t\t\t/* Target may be a Proxy or property may be an accessor, so we must\n\t\t\t * use an actual, Proxy-aware hasprop check here.\n\t\t\t *\n\t\t\t * out->holder is NOT set to the actual duk_hobject where the\n\t\t\t * property is found, but rather the object binding target object.\n\t\t\t */\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(target))) {\n\t\t\t\tduk_tval tv_name;\n\t\t\t\tduk_tval tv_target_tmp;\n\n\t\t\t\tDUK_ASSERT(name != NULL);\n\t\t\t\tDUK_TVAL_SET_STRING(&tv_name, name);\n\t\t\t\tDUK_TVAL_SET_OBJECT(&tv_target_tmp, target);\n\n\t\t\t\tfound = duk_hobject_hasprop(thr, &tv_target_tmp, &tv_name);\n\t\t\t} else\n#endif  /* DUK_USE_ES6_PROXY */\n\t\t\t{\n\t\t\t\t/* XXX: duk_hobject_hasprop() would be correct for\n\t\t\t\t * non-Proxy objects too, but it is about ~20-25%\n\t\t\t\t * slower at present so separate code paths for\n\t\t\t\t * Proxy and non-Proxy now.\n\t\t\t\t */\n\t\t\t\tfound = duk_hobject_hasprop_raw(thr, target, name);\n\t\t\t}\n\n\t\t\tif (found) {\n\t\t\t\tout->value = NULL;  /* can't get value, may be accessor */\n\t\t\t\tout->attrs = 0;     /* irrelevant when out->value == NULL */\n\t\t\t\tout->env = env;\n\t\t\t\tout->holder = target;\n\t\t\t\tout->has_this = ((duk_hobjenv *) env)->has_this;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t\t                     \"(object environment record)\",\n\t\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\tif (!parents) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference failed, no parent traversal \"\n\t\t\t                     \"(not found from first traversed env)\"));\n\t\t\tgoto fail_not_found;\n\t\t}\n\n                if (DUK_UNLIKELY(sanity-- == 0)) {\n                        DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n                }\n\t\tenv = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, env);\n\t}\n\n\t/*\n\t *  Not found (even in global object)\n\t */\n\n fail_not_found:\n\treturn 0;\n}\n\n/*\n *  HASVAR: check identifier binding from a given environment record\n *  without traversing its parents.\n *\n *  This primitive is not exposed to user code as such, but is used\n *  internally for e.g. declaration binding instantiation.\n *\n *  See E5 Sections:\n *    10.2.1.1.1 HasBinding(N)\n *    10.2.1.2.1 HasBinding(N)\n *\n *  Note: strictness has no bearing on this check.  Hence we don't take\n *  a 'strict' parameter.\n */\n\n#if 0  /*unused*/\nDUK_INTERNAL\nduk_bool_t duk_js_hasvar_envrec(duk_hthread *thr,\n                                duk_hobject *env,\n                                duk_hstring *name) {\n\tduk__id_lookup_result ref;\n\tduk_bool_t parents;\n\n\tDUK_DDD(DUK_DDDPRINT(\"hasvar: thr=%p, env=%p, name=%!O \"\n\t                     \"(env -> %!dO)\",\n\t                     (void *) thr, (void *) env, (duk_heaphdr *) name,\n\t                     (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(name != NULL);\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\n\tDUK_ASSERT(DUK_HOBJECT_IS_ENV(env));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(env));\n\n\t/* lookup results is ignored */\n\tparents = 0;\n\treturn duk__get_identifier_reference(thr, env, name, NULL, parents, &ref);\n}\n#endif\n\n/*\n *  GETVAR\n *\n *  See E5 Sections:\n *    11.1.2 Identifier Reference\n *    10.3.1 Identifier Resolution\n *    11.13.1 Simple Assignment  [example of where the Reference is GetValue'd]\n *    8.7.1 GetValue (V)\n *    8.12.1 [[GetOwnProperty]] (P)\n *    8.12.2 [[GetProperty]] (P)\n *    8.12.3 [[Get]] (P)\n *\n *  If 'throw' is true, always leaves two values on top of stack: [val this].\n *\n *  If 'throw' is false, returns 0 if identifier cannot be resolved, and the\n *  stack will be unaffected in this case.  If identifier is resolved, returns\n *  1 and leaves [val this] on top of stack.\n *\n *  Note: the 'strict' flag of a reference returned by GetIdentifierReference\n *  is ignored by GetValue.  Hence we don't take a 'strict' parameter.\n *\n *  The 'throw' flag is needed for implementing 'typeof' for an unreferenced\n *  identifier.  An unreference identifier in other contexts generates a\n *  ReferenceError.\n */\n\nDUK_LOCAL\nduk_bool_t duk__getvar_helper(duk_hthread *thr,\n                              duk_hobject *env,\n                              duk_activation *act,\n                              duk_hstring *name,\n                              duk_bool_t throw_flag) {\n\tduk__id_lookup_result ref;\n\tduk_tval tv_tmp_obj;\n\tduk_tval tv_tmp_key;\n\tduk_bool_t parents;\n\n\tDUK_DDD(DUK_DDDPRINT(\"getvar: thr=%p, env=%p, act=%p, name=%!O \"\n\t                     \"(env -> %!dO)\",\n\t                     (void *) thr, (void *) env, (void *) act,\n\t                     (duk_heaphdr *) name, (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\t/* env and act may be NULL */\n\n\tDUK_STATS_INC(thr->heap, stats_getvar_all);\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\n\tparents = 1;     /* follow parent chain */\n\tif (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) {\n\t\tif (ref.value) {\n\t\t\tduk_push_tval(thr, ref.value);\n\t\t\tduk_push_undefined(thr);\n\t\t} else {\n\t\t\tDUK_ASSERT(ref.holder != NULL);\n\n\t\t\t/* ref.holder is safe across the getprop call (even\n\t\t\t * with side effects) because 'env' is reachable and\n\t\t\t * ref.holder is a direct heap pointer.\n\t\t\t */\n\n\t\t\tDUK_TVAL_SET_OBJECT(&tv_tmp_obj, ref.holder);\n\t\t\tDUK_TVAL_SET_STRING(&tv_tmp_key, name);\n\t\t\t(void) duk_hobject_getprop(thr, &tv_tmp_obj, &tv_tmp_key);  /* [value] */\n\n\t\t\tif (ref.has_this) {\n\t\t\t\tduk_push_hobject(thr, ref.holder);\n\t\t\t} else {\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t}\n\n\t\t\t/* [value this] */\n\t\t}\n\n\t\treturn 1;\n\t} else {\n\t\tif (throw_flag) {\n\t\t\tDUK_ERROR_FMT1(thr, DUK_ERR_REFERENCE_ERROR,\n\t\t\t               \"identifier '%s' undefined\",\n\t\t\t               (const char *) DUK_HSTRING_GET_DATA(name));\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\n\t\treturn 0;\n\t}\n}\n\nDUK_INTERNAL\nduk_bool_t duk_js_getvar_envrec(duk_hthread *thr,\n                                duk_hobject *env,\n                                duk_hstring *name,\n                                duk_bool_t throw_flag) {\n\treturn duk__getvar_helper(thr, env, NULL, name, throw_flag);\n}\n\nDUK_INTERNAL\nduk_bool_t duk_js_getvar_activation(duk_hthread *thr,\n                                    duk_activation *act,\n                                    duk_hstring *name,\n                                    duk_bool_t throw_flag) {\n\tDUK_ASSERT(act != NULL);\n\treturn duk__getvar_helper(thr, act->lex_env, act, name, throw_flag);\n}\n\n/*\n *  PUTVAR\n *\n *  See E5 Sections:\n *    11.1.2 Identifier Reference\n *    10.3.1 Identifier Resolution\n *    11.13.1 Simple Assignment  [example of where the Reference is PutValue'd]\n *    8.7.2 PutValue (V,W)  [see especially step 3.b, undefined -> automatic global in non-strict mode]\n *    8.12.4 [[CanPut]] (P)\n *    8.12.5 [[Put]] (P)\n *\n *  Note: may invalidate any valstack (or object) duk_tval pointers because\n *  putting a value may reallocate any object or any valstack.  Caller beware.\n */\n\nDUK_LOCAL\nvoid duk__putvar_helper(duk_hthread *thr,\n                        duk_hobject *env,\n                        duk_activation *act,\n                        duk_hstring *name,\n                        duk_tval *val,\n                        duk_bool_t strict) {\n\tduk__id_lookup_result ref;\n\tduk_tval tv_tmp_obj;\n\tduk_tval tv_tmp_key;\n\tduk_bool_t parents;\n\n\tDUK_STATS_INC(thr->heap, stats_putvar_all);\n\n\tDUK_DDD(DUK_DDDPRINT(\"putvar: thr=%p, env=%p, act=%p, name=%!O, val=%p, strict=%ld \"\n\t                     \"(env -> %!dO, val -> %!T)\",\n\t                     (void *) thr, (void *) env, (void *) act,\n\t                     (duk_heaphdr *) name, (void *) val, (long) strict,\n\t                     (duk_heaphdr *) env, (duk_tval *) val));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(val != NULL);\n\t/* env and act may be NULL */\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\tDUK_ASSERT_REFCOUNT_NONZERO_TVAL(val);\n\n\t/*\n\t *  In strict mode E5 protects 'eval' and 'arguments' from being\n\t *  assigned to (or even declared anywhere).  Attempt to do so\n\t *  should result in a compile time SyntaxError.  See the internal\n\t *  design documentation for details.\n\t *\n\t *  Thus, we should never come here, run-time, for strict code,\n\t *  and name 'eval' or 'arguments'.\n\t */\n\n\tDUK_ASSERT(!strict ||\n\t           (name != DUK_HTHREAD_STRING_EVAL(thr) &&\n\t            name != DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)));\n\n\t/*\n\t *  Lookup variable and update in-place if found.\n\t */\n\n\tparents = 1;     /* follow parent chain */\n\n\tif (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) {\n\t\tif (ref.value && (ref.attrs & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t/* Update duk_tval in-place if pointer provided and the\n\t\t\t * property is writable.  If the property is not writable\n\t\t\t * (immutable binding), use duk_hobject_putprop() which\n\t\t\t * will respect mutability.\n\t\t\t */\n\t\t\tduk_tval *tv_val;\n\n\t\t\ttv_val = ref.value;\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv_val, val);  /* side effects */\n\n\t\t\t/* ref.value invalidated here */\n\t\t} else {\n\t\t\tDUK_ASSERT(ref.holder != NULL);\n\n\t\t\tDUK_TVAL_SET_OBJECT(&tv_tmp_obj, ref.holder);\n\t\t\tDUK_TVAL_SET_STRING(&tv_tmp_key, name);\n\t\t\t(void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, strict);\n\n\t\t\t/* ref.value invalidated here */\n\t\t}\n\n\t\treturn;\n\t}\n\n\t/*\n\t *  Not found: write to global object (non-strict) or ReferenceError\n\t *  (strict); see E5 Section 8.7.2, step 3.\n\t */\n\n\tif (strict) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"identifier binding not found, strict => reference error\"));\n\t\tDUK_ERROR_FMT1(thr, DUK_ERR_REFERENCE_ERROR,\n\t\t               \"identifier '%s' undefined\",\n\t\t               (const char *) DUK_HSTRING_GET_DATA(name));\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"identifier binding not found, not strict => set to global\"));\n\n\tDUK_TVAL_SET_OBJECT(&tv_tmp_obj, thr->builtins[DUK_BIDX_GLOBAL]);\n\tDUK_TVAL_SET_STRING(&tv_tmp_key, name);\n\t(void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, 0);  /* 0 = no throw */\n\n\t/* NB: 'val' may be invalidated here because put_value may realloc valstack,\n\t * caller beware.\n\t */\n}\n\nDUK_INTERNAL\nvoid duk_js_putvar_envrec(duk_hthread *thr,\n                          duk_hobject *env,\n                          duk_hstring *name,\n                          duk_tval *val,\n                          duk_bool_t strict) {\n\tduk__putvar_helper(thr, env, NULL, name, val, strict);\n}\n\nDUK_INTERNAL\nvoid duk_js_putvar_activation(duk_hthread *thr,\n                              duk_activation *act,\n                              duk_hstring *name,\n                              duk_tval *val,\n                              duk_bool_t strict) {\n\tDUK_ASSERT(act != NULL);\n\tduk__putvar_helper(thr, act->lex_env, act, name, val, strict);\n}\n\n/*\n *  DELVAR\n *\n *  See E5 Sections:\n *    11.4.1 The delete operator\n *    10.2.1.1.5 DeleteBinding (N)  [declarative environment record]\n *    10.2.1.2.5 DeleteBinding (N)  [object environment record]\n *\n *  Variable bindings established inside eval() are deletable (configurable),\n *  other bindings are not, including variables declared in global level.\n *  Registers are always non-deletable, and the deletion of other bindings\n *  is controlled by the configurable flag.\n *\n *  For strict mode code, the 'delete' operator should fail with a compile\n *  time SyntaxError if applied to identifiers.  Hence, no strict mode\n *  run-time deletion of identifiers should ever happen.  This function\n *  should never be called from strict mode code!\n */\n\nDUK_LOCAL\nduk_bool_t duk__delvar_helper(duk_hthread *thr,\n                              duk_hobject *env,\n                              duk_activation *act,\n                              duk_hstring *name) {\n\tduk__id_lookup_result ref;\n\tduk_bool_t parents;\n\n\tDUK_DDD(DUK_DDDPRINT(\"delvar: thr=%p, env=%p, act=%p, name=%!O \"\n\t                     \"(env -> %!dO)\",\n\t                     (void *) thr, (void *) env, (void *) act,\n\t                     (duk_heaphdr *) name, (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\t/* env and act may be NULL */\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\n\tparents = 1;     /* follow parent chain */\n\n\tif (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) {\n\t\tif (ref.value && !(ref.attrs & DUK_PROPDESC_FLAG_CONFIGURABLE)) {\n\t\t\t/* Identifier found in registers (always non-deletable)\n\t\t\t * or declarative environment record and non-configurable.\n\t\t\t */\n\t\t\treturn 0;\n\t\t}\n\t\tDUK_ASSERT(ref.holder != NULL);\n\n\t\treturn duk_hobject_delprop_raw(thr, ref.holder, name, 0);\n\t}\n\n\t/*\n\t *  Not found (even in global object).\n\t *\n\t *  In non-strict mode this is a silent SUCCESS (!), see E5 Section 11.4.1,\n\t *  step 3.b.  In strict mode this case is a compile time SyntaxError so\n\t *  we should not come here.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"identifier to be deleted not found: name=%!O \"\n\t                     \"(treated as silent success)\",\n\t                     (duk_heaphdr *) name));\n\treturn 1;\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL\nduk_bool_t duk_js_delvar_envrec(duk_hthread *thr,\n                                duk_hobject *env,\n                                duk_hstring *name) {\n\treturn duk__delvar_helper(thr, env, NULL, name);\n}\n#endif\n\nDUK_INTERNAL\nduk_bool_t duk_js_delvar_activation(duk_hthread *thr,\n                                    duk_activation *act,\n                                    duk_hstring *name) {\n\tDUK_ASSERT(act != NULL);\n\treturn duk__delvar_helper(thr, act->lex_env, act, name);\n}\n\n/*\n *  DECLVAR\n *\n *  See E5 Sections:\n *    10.4.3 Entering Function Code\n *    10.5 Declaration Binding Instantion\n *    12.2 Variable Statement\n *    11.1.2 Identifier Reference\n *    10.3.1 Identifier Resolution\n *\n *  Variable declaration behavior is mainly discussed in Section 10.5,\n *  and is not discussed in the execution semantics (Sections 11-13).\n *\n *  Conceptually declarations happen when code (global, eval, function)\n *  is entered, before any user code is executed.  In practice, register-\n *  bound identifiers are 'declared' automatically (by virtue of being\n *  allocated to registers with the initial value 'undefined').  Other\n *  identifiers are declared in the function prologue with this primitive.\n *\n *  Since non-register bindings eventually back to an internal object's\n *  properties, the 'prop_flags' argument is used to specify binding\n *  type:\n *\n *    - Immutable binding: set DUK_PROPDESC_FLAG_WRITABLE to false\n *    - Non-deletable binding: set DUK_PROPDESC_FLAG_CONFIGURABLE to false\n *    - The flag DUK_PROPDESC_FLAG_ENUMERABLE should be set, although it\n *      doesn't really matter for internal objects\n *\n *  All bindings are non-deletable mutable bindings except:\n *\n *    - Declarations in eval code (mutable, deletable)\n *    - 'arguments' binding in strict function code (immutable)\n *    - Function name binding of a function expression (immutable)\n *\n *  Declarations may go to declarative environment records (always\n *  so for functions), but may also go to object environment records\n *  (e.g. global code).  The global object environment has special\n *  behavior when re-declaring a function (but not a variable); see\n *  E5.1 specification, Section 10.5, step 5.e.\n *\n *  Declarations always go to the 'top-most' environment record, i.e.\n *  we never check the record chain.  It's not an error even if a\n *  property (even an immutable or non-deletable one) of the same name\n *  already exists.\n *\n *  If a declared variable already exists, its value needs to be updated\n *  (if possible).  Returns 1 if a PUTVAR needs to be done by the caller;\n *  otherwise returns 0.\n */\n\nDUK_LOCAL\nduk_bool_t duk__declvar_helper(duk_hthread *thr,\n                               duk_hobject *env,\n                               duk_hstring *name,\n                               duk_tval *val,\n                               duk_small_uint_t prop_flags,\n                               duk_bool_t is_func_decl) {\n\tduk_hobject *holder;\n\tduk_bool_t parents;\n\tduk__id_lookup_result ref;\n\tduk_tval *tv;\n\n\tDUK_DDD(DUK_DDDPRINT(\"declvar: thr=%p, env=%p, name=%!O, val=%!T, prop_flags=0x%08lx, is_func_decl=%ld \"\n\t                     \"(env -> %!iO)\",\n\t                     (void *) thr, (void *) env, (duk_heaphdr *) name,\n\t                     (duk_tval *) val, (unsigned long) prop_flags,\n\t                     (unsigned int) is_func_decl, (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(val != NULL);\n\n\t/* Note: in strict mode the compiler should reject explicit\n\t * declaration of 'eval' or 'arguments'.  However, internal\n\t * bytecode may declare 'arguments' in the function prologue.\n\t * We don't bother checking (or asserting) for these now.\n\t */\n\n\t/* Note: val is a stable duk_tval pointer.  The caller makes\n\t * a value copy into its stack frame, so 'tv_val' is not subject\n\t * to side effects here.\n\t */\n\n\t/*\n\t *  Check whether already declared.\n\t *\n\t *  We need to check whether the binding exists in the environment\n\t *  without walking its parents.  However, we still need to check\n\t *  register-bound identifiers and the prototype chain of an object\n\t *  environment target object.\n\t */\n\n\tparents = 0;  /* just check 'env' */\n\tif (duk__get_identifier_reference(thr, env, name, NULL, parents, &ref)) {\n\t\tduk_int_t e_idx;\n\t\tduk_int_t h_idx;\n\t\tduk_small_uint_t flags;\n\n\t\t/*\n\t\t *  Variable already declared, ignore re-declaration.\n\t\t *  The only exception is the updated behavior of E5.1 for\n\t\t *  global function declarations, E5.1 Section 10.5, step 5.e.\n\t\t *  This behavior does not apply to global variable declarations.\n\t\t */\n\n\t\tif (!(is_func_decl && env == thr->builtins[DUK_BIDX_GLOBAL_ENV])) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"re-declare a binding, ignoring\"));\n\t\t\treturn 1;  /* 1 -> needs a PUTVAR */\n\t\t}\n\n\t\t/*\n\t\t *  Special behavior in E5.1.\n\t\t *\n\t\t *  Note that even though parents == 0, the conflicting property\n\t\t *  may be an inherited property (currently our global object's\n\t\t *  prototype is Object.prototype).  Step 5.e first operates on\n\t\t *  the existing property (which is potentially in an ancestor)\n\t\t *  and then defines a new property in the global object (and\n\t\t *  never modifies the ancestor).\n\t\t *\n\t\t *  Also note that this logic would become even more complicated\n\t\t *  if the conflicting property might be a virtual one.  Object\n\t\t *  prototype has no virtual properties, though.\n\t\t *\n\t\t *  XXX: this is now very awkward, rework.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"re-declare a function binding in global object, \"\n\t\t                     \"updated E5.1 processing\"));\n\n\t\tDUK_ASSERT(ref.holder != NULL);\n\t\tholder = ref.holder;\n\n\t\t/* holder will be set to the target object, not the actual object\n\t\t * where the property was found (see duk__get_identifier_reference()).\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(holder) == DUK_HOBJECT_CLASS_GLOBAL);\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(holder));  /* global object doesn't have array part */\n\n\t\t/* XXX: use a helper for prototype traversal; no loop check here */\n\t\t/* must be found: was found earlier, and cannot be inherited */\n\t\tfor (;;) {\n\t\t\tDUK_ASSERT(holder != NULL);\n\t\t\tif (duk_hobject_find_entry(thr->heap, holder, name, &e_idx, &h_idx)) {\n\t\t\t\tDUK_ASSERT(e_idx >= 0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t/* SCANBUILD: NULL pointer dereference, doesn't actually trigger,\n\t\t\t * asserted above.\n\t\t\t */\n\t\t\tholder = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, holder);\n\t\t}\n\t\tDUK_ASSERT(holder != NULL);\n\t\tDUK_ASSERT(e_idx >= 0);\n\t\t/* SCANBUILD: scan-build produces a NULL pointer dereference warning\n\t\t * below; it never actually triggers because holder is actually never\n\t\t * NULL.\n\t\t */\n\n\t\t/* ref.holder is global object, holder is the object with the\n\t\t * conflicting property.\n\t\t */\n\n\t\tflags = DUK_HOBJECT_E_GET_FLAGS(thr->heap, holder, e_idx);\n\t\tif (!(flags & DUK_PROPDESC_FLAG_CONFIGURABLE)) {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"existing property is a non-configurable \"\n\t\t\t\t                     \"accessor -> reject\"));\n\t\t\t\tgoto fail_existing_attributes;\n\t\t\t}\n\t\t\tif (!((flags & DUK_PROPDESC_FLAG_WRITABLE) &&\n\t\t\t      (flags & DUK_PROPDESC_FLAG_ENUMERABLE))) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"existing property is a non-configurable \"\n\t\t\t\t                     \"plain property which is not writable and \"\n\t\t\t\t                     \"enumerable -> reject\"));\n\t\t\t\tgoto fail_existing_attributes;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"existing property is not configurable but \"\n\t\t\t                     \"is plain, enumerable, and writable -> \"\n\t\t\t                     \"allow redeclaration\"));\n\t\t}\n\n\t\tif (holder == ref.holder) {\n\t\t\t/* XXX: if duk_hobject_define_property_internal() was updated\n\t\t\t * to handle a pre-existing accessor property, this would be\n\t\t\t * a simple call (like for the ancestor case).\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"redefine, offending property in global object itself\"));\n\n\t\t\tif (flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t\tduk_hobject *tmp;\n\n\t\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, holder, e_idx);\n\t\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, holder, e_idx, NULL);\n\t\t\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);\n\t\t\t\tDUK_UNREF(tmp);\n\t\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, holder, e_idx);\n\t\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, holder, e_idx, NULL);\n\t\t\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);\n\t\t\t\tDUK_UNREF(tmp);\n\t\t\t} else {\n\t\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx);\n\t\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);\n\t\t\t}\n\n\t\t\t/* Here val would be potentially invalid if we didn't make\n\t\t\t * a value copy at the caller.\n\t\t\t */\n\n\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx);\n\t\t\tDUK_TVAL_SET_TVAL(tv, val);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, holder, e_idx, prop_flags);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"updated global binding, final result: \"\n\t\t\t                     \"value -> %!T, prop_flags=0x%08lx\",\n\t\t\t                     (duk_tval *) DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx),\n\t\t\t                     (unsigned long) prop_flags));\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"redefine, offending property in ancestor\"));\n\n\t\t\tDUK_ASSERT(ref.holder == thr->builtins[DUK_BIDX_GLOBAL]);\n\t\t\tduk_push_tval(thr, val);\n\t\t\tduk_hobject_define_property_internal(thr, ref.holder, name, prop_flags);\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  Not found (in registers or record objects).  Declare\n\t *  to current variable environment.\n\t */\n\n\t/*\n\t *  Get holder object\n\t */\n\n\tif (DUK_HOBJECT_IS_DECENV(env)) {\n\t\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env);\n\t\tholder = env;\n\t} else {\n\t\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) env);\n\t\tholder = ((duk_hobjenv *) env)->target;\n\t\tDUK_ASSERT(holder != NULL);\n\t}\n\n\t/*\n\t *  Define new property\n\t *\n\t *  Note: this may fail if the holder is not extensible.\n\t */\n\n\t/* XXX: this is awkward as we use an internal method which doesn't handle\n\t * extensibility etc correctly.  Basically we'd want to do a [[DefineOwnProperty]]\n\t * or Object.defineProperty() here.\n\t */\n\n\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(holder)) {\n\t\tgoto fail_not_extensible;\n\t}\n\n\tduk_push_hobject(thr, holder);\n\tduk_push_hstring(thr, name);\n\tduk_push_tval(thr, val);\n\tduk_xdef_prop(thr, -3, prop_flags);  /* [holder name val] -> [holder] */\n\tduk_pop_unsafe(thr);\n\n\treturn 0;\n\n fail_existing_attributes:\n fail_not_extensible:\n\tDUK_ERROR_TYPE(thr, \"declaration failed\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL\nduk_bool_t duk_js_declvar_activation(duk_hthread *thr,\n                                     duk_activation *act,\n                                     duk_hstring *name,\n                                     duk_tval *val,\n                                     duk_small_uint_t prop_flags,\n                                     duk_bool_t is_func_decl) {\n\tduk_hobject *env;\n\tduk_tval tv_val_copy;\n\n\tDUK_ASSERT(act != NULL);\n\n\t/*\n\t *  Make a value copy of the input val.  This ensures that\n\t *  side effects cannot invalidate the pointer.\n\t */\n\n\tDUK_TVAL_SET_TVAL(&tv_val_copy, val);\n\tval = &tv_val_copy;\n\n\t/*\n\t *  Delayed env creation check\n\t */\n\n\tif (!act->var_env) {\n\t\tDUK_ASSERT(act->lex_env == NULL);\n\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\t/* 'act' is a stable pointer, so still OK. */\n\t}\n\tDUK_ASSERT(act->lex_env != NULL);\n\tDUK_ASSERT(act->var_env != NULL);\n\n\tenv = act->var_env;\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_ENV(env));\n\n\treturn duk__declvar_helper(thr, env, name, val, prop_flags, is_func_decl);\n}\n/*\n *  Lexer for source files, ToNumber() string conversions, RegExp expressions,\n *  and JSON.\n *\n *  Provides a stream of ECMAScript tokens from an UTF-8/CESU-8 buffer.  The\n *  caller can also rewind the token stream into a certain position which is\n *  needed by the compiler part for multi-pass scanning.  Tokens are\n *  represented as duk_token structures, and contain line number information.\n *  Token types are identified with DUK_TOK_* defines.\n *\n *  Characters are decoded into a fixed size lookup window consisting of\n *  decoded Unicode code points, with window positions past the end of the\n *  input filled with an invalid codepoint (-1).  The tokenizer can thus\n *  perform multiple character lookups efficiently and with few sanity\n *  checks (such as access outside the end of the input), which keeps the\n *  tokenization code small at the cost of performance.\n *\n *  Character data in tokens, such as identifier names and string literals,\n *  is encoded into CESU-8 format on-the-fly while parsing the token in\n *  question.  The string data is made reachable to garbage collection by\n *  placing the token-related values in value stack entries allocated for\n *  this purpose by the caller.  The characters exist in Unicode code point\n *  form only in the fixed size lookup window, which keeps character data\n *  expansion (of especially ASCII data) low.\n *\n *  Token parsing supports the full range of Unicode characters as described\n *  in the E5 specification.  Parsing has been optimized for ASCII characters\n *  because ordinary ECMAScript code consists almost entirely of ASCII\n *  characters.  Matching of complex Unicode codepoint sets (such as in the\n *  IdentifierStart and IdentifierPart productions) is optimized for size,\n *  and is done using a linear scan of a bit-packed list of ranges.  This is\n *  very slow, but should never be entered unless the source code actually\n *  contains Unicode characters.\n *\n *  ECMAScript tokenization is partially context sensitive.  First,\n *  additional future reserved words are recognized in strict mode (see E5\n *  Section 7.6.1.2).  Second, a forward slash character ('/') can be\n *  recognized either as starting a RegExp literal or as a division operator,\n *  depending on context.  The caller must provide necessary context flags\n *  when requesting a new token.\n *\n *  Future work:\n *\n *    * Make line number tracking optional, as it consumes space.\n *\n *    * Add a feature flag for disabling UTF-8 decoding of input, as most\n *      source code is ASCII.  Because of Unicode escapes written in ASCII,\n *      this does not allow Unicode support to be removed from e.g.\n *      duk_unicode_is_identifier_start() nor does it allow removal of CESU-8\n *      encoding of e.g. string literals.\n *\n *    * Add a feature flag for disabling Unicode compliance of e.g. identifier\n *      names.  This allows for a build more than a kilobyte smaller, because\n *      Unicode ranges needed by duk_unicode_is_identifier_start() and\n *      duk_unicode_is_identifier_part() can be dropped.  String literals\n *      should still be allowed to contain escaped Unicode, so this still does\n *      not allow removal of CESU-8 encoding of e.g. string literals.\n *\n *    * Character lookup tables for codepoints above BMP could be stripped.\n *\n *    * Strictly speaking, E5 specification requires that source code consists\n *      of 16-bit code units, and if not, must be conceptually converted to\n *      that format first.  The current lexer processes Unicode code points\n *      and allows characters outside the BMP.  These should be converted to\n *      surrogate pairs while reading the source characters into the window,\n *      not after tokens have been formed (as is done now).  However, the fix\n *      is not trivial because two characters are decoded from one codepoint.\n *\n *    * Optimize for speed as well as size.  Large if-else ladders are (at\n *      least potentially) slow.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Various defines and file specific helper macros\n */\n\n#define DUK__MAX_RE_DECESC_DIGITS     9\n#define DUK__MAX_RE_QUANT_DIGITS      9   /* Does not allow e.g. 2**31-1, but one more would allow overflows of u32. */\n\n/* whether to use macros or helper function depends on call count */\n#define DUK__ISDIGIT(x)          ((x) >= DUK_ASC_0 && (x) <= DUK_ASC_9)\n#define DUK__ISHEXDIGIT(x)       duk__is_hex_digit((x))\n#define DUK__ISOCTDIGIT(x)       ((x) >= DUK_ASC_0 && (x) <= DUK_ASC_7)\n#define DUK__ISDIGIT03(x)        ((x) >= DUK_ASC_0 && (x) <= DUK_ASC_3)\n#define DUK__ISDIGIT47(x)        ((x) >= DUK_ASC_4 && (x) <= DUK_ASC_7)\n\n/* lexer character window helpers */\n#define DUK__LOOKUP(lex_ctx,idx)            ((lex_ctx)->window[(idx)].codepoint)\n#define DUK__ADVANCECHARS(lex_ctx,count)    duk__advance_chars((lex_ctx), (count))\n#define DUK__ADVANCEBYTES(lex_ctx,count)    duk__advance_bytes((lex_ctx), (count))\n#define DUK__INITBUFFER(lex_ctx)            duk__initbuffer((lex_ctx))\n#define DUK__APPENDBUFFER(lex_ctx,x)        duk__appendbuffer((lex_ctx), (duk_codepoint_t) (x))\n#define DUK__APPENDBUFFER_ASCII(lex_ctx,x)  duk__appendbuffer_ascii((lex_ctx), (duk_codepoint_t) (x))\n\n/* lookup shorthands (note: assume context variable is named 'lex_ctx') */\n#define DUK__L0()  DUK__LOOKUP(lex_ctx, 0)\n#define DUK__L1()  DUK__LOOKUP(lex_ctx, 1)\n#define DUK__L2()  DUK__LOOKUP(lex_ctx, 2)\n#define DUK__L3()  DUK__LOOKUP(lex_ctx, 3)\n#define DUK__L4()  DUK__LOOKUP(lex_ctx, 4)\n#define DUK__L5()  DUK__LOOKUP(lex_ctx, 5)\n\n/* packed advance/token number macro used by multiple functions */\n#define DUK__ADVTOK(advbytes,tok)  ((((advbytes) * sizeof(duk_lexer_codepoint)) << 8) + (tok))\n\n/*\n *  Advance lookup window by N characters, filling in new characters as\n *  necessary.  After returning caller is guaranteed a character window of\n *  at least DUK_LEXER_WINDOW_SIZE characters.\n *\n *  The main function duk__advance_bytes() is called at least once per every\n *  token so it has a major lexer/compiler performance impact.  There are two\n *  variants for the main duk__advance_bytes() algorithm: a sliding window\n *  approach which is slightly faster at the cost of larger code footprint,\n *  and a simple copying one.\n *\n *  Decoding directly from the source string would be another lexing option.\n *  But the lookup window based approach has the advantage of hiding the\n *  source string and its encoding effectively which gives more flexibility\n *  going forward to e.g. support chunked streaming of source from flash.\n *\n *  Decodes UTF-8/CESU-8 leniently with support for code points from U+0000 to\n *  U+10FFFF, causing an error if the input is unparseable.  Leniency means:\n *\n *    * Unicode code point validation is intentionally not performed,\n *      except to check that the codepoint does not exceed 0x10ffff.\n *\n *    * In particular, surrogate pairs are allowed and not combined, which\n *      allows source files to represent all SourceCharacters with CESU-8.\n *      Broken surrogate pairs are allowed, as ECMAScript does not mandate\n *      their validation.\n *\n *    * Allow non-shortest UTF-8 encodings.\n *\n *  Leniency here causes few security concerns because all character data is\n *  decoded into Unicode codepoints before lexer processing, and is then\n *  re-encoded into CESU-8.  The source can be parsed as strict UTF-8 with\n *  a compiler option.  However, ECMAScript source characters include -all-\n *  16-bit unsigned integer codepoints, so leniency seems to be appropriate.\n *\n *  Note that codepoints above the BMP are not strictly SourceCharacters,\n *  but the lexer still accepts them as such.  Before ending up in a string\n *  or an identifier name, codepoints above BMP are converted into surrogate\n *  pairs and then CESU-8 encoded, resulting in 16-bit Unicode data as\n *  expected by ECMAScript.\n *\n *  An alternative approach to dealing with invalid or partial sequences\n *  would be to skip them and replace them with e.g. the Unicode replacement\n *  character U+FFFD.  This has limited utility because a replacement character\n *  will most likely cause a parse error, unless it occurs inside a string.\n *  Further, ECMAScript source is typically pure ASCII.\n *\n *  See:\n *\n *     http://en.wikipedia.org/wiki/UTF-8\n *     http://en.wikipedia.org/wiki/CESU-8\n *     http://tools.ietf.org/html/rfc3629\n *     http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences\n *\n *  Future work:\n *\n *    * Reject other invalid Unicode sequences (see Wikipedia entry for examples)\n *      in strict UTF-8 mode.\n *\n *    * Size optimize.  An attempt to use a 16-byte lookup table for the first\n *      byte resulted in a code increase though.\n *\n *    * Is checking against maximum 0x10ffff really useful?  4-byte encoding\n *      imposes a certain limit anyway.\n *\n *    * Support chunked streaming of source code.  Can be implemented either\n *      by streaming chunks of bytes or chunks of codepoints.\n */\n\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\nDUK_LOCAL void duk__fill_lexer_buffer(duk_lexer_ctx *lex_ctx, duk_small_uint_t start_offset_bytes) {\n\tduk_lexer_codepoint *cp, *cp_end;\n\tduk_ucodepoint_t x;\n\tduk_small_uint_t contlen;\n\tconst duk_uint8_t *p, *p_end;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\tduk_ucodepoint_t mincp;\n#endif\n\tduk_int_t input_line;\n\n\t/* Use temporaries and update lex_ctx only when finished. */\n\tinput_line = lex_ctx->input_line;\n\tp = lex_ctx->input + lex_ctx->input_offset;\n\tp_end = lex_ctx->input + lex_ctx->input_length;\n\n\tcp = (duk_lexer_codepoint *) (void *) ((duk_uint8_t *) lex_ctx->buffer + start_offset_bytes);\n\tcp_end = lex_ctx->buffer + DUK_LEXER_BUFFER_SIZE;\n\n\tfor (; cp != cp_end; cp++) {\n\t\tcp->offset = (duk_size_t) (p - lex_ctx->input);\n\t\tcp->line = input_line;\n\n\t\t/* XXX: potential issue with signed pointers, p_end < p. */\n\t\tif (DUK_UNLIKELY(p >= p_end)) {\n\t\t\t/* If input_offset were assigned a negative value, it would\n\t\t\t * result in a large positive value.  Most likely it would be\n\t\t\t * larger than input_length and be caught here.  In any case\n\t\t\t * no memory unsafe behavior would happen.\n\t\t\t */\n\t\t\tcp->codepoint = -1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tx = (duk_ucodepoint_t) (*p++);\n\n\t\t/* Fast path. */\n\n\t\tif (DUK_LIKELY(x < 0x80UL)) {\n\t\t\tDUK_ASSERT(x != 0x2028UL && x != 0x2029UL);  /* not LS/PS */\n\t\t\tif (DUK_UNLIKELY(x <= 0x000dUL)) {\n\t\t\t\tif ((x == 0x000aUL) ||\n\t\t\t\t    ((x == 0x000dUL) && (p >= p_end || *p != 0x000aUL))) {\n\t\t\t\t\t/* lookup for 0x000a above assumes shortest encoding now */\n\n\t\t\t\t\t/* E5 Section 7.3, treat the following as newlines:\n\t\t\t\t\t *   LF\n\t\t\t\t\t *   CR [not followed by LF]\n\t\t\t\t\t *   LS\n\t\t\t\t\t *   PS\n\t\t\t\t\t *\n\t\t\t\t\t * For CR LF, CR is ignored if it is followed by LF, and the LF will bump\n\t\t\t\t\t * the line number.\n\t\t\t\t\t */\n\t\t\t\t\tinput_line++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcp->codepoint = (duk_codepoint_t) x;\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Slow path. */\n\n\t\tif (x < 0xc0UL) {\n\t\t\t/* 10xx xxxx -> invalid */\n\t\t\tgoto error_encoding;\n\t\t} else if (x < 0xe0UL) {\n\t\t\t/* 110x xxxx   10xx xxxx  */\n\t\t\tcontlen = 1;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\t\tmincp = 0x80UL;\n#endif\n\t\t\tx = x & 0x1fUL;\n\t\t} else if (x < 0xf0UL) {\n\t\t\t/* 1110 xxxx   10xx xxxx   10xx xxxx */\n\t\t\tcontlen = 2;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\t\tmincp = 0x800UL;\n#endif\n\t\t\tx = x & 0x0fUL;\n\t\t} else if (x < 0xf8UL) {\n\t\t\t/* 1111 0xxx   10xx xxxx   10xx xxxx   10xx xxxx */\n\t\t\tcontlen = 3;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\t\tmincp = 0x10000UL;\n#endif\n\t\t\tx = x & 0x07UL;\n\t\t} else {\n\t\t\t/* no point in supporting encodings of 5 or more bytes */\n\t\t\tgoto error_encoding;\n\t\t}\n\n\t\tDUK_ASSERT(p_end >= p);\n\t\tif ((duk_size_t) contlen > (duk_size_t) (p_end - p)) {\n\t\t\tgoto error_clipped;\n\t\t}\n\n\t\twhile (contlen > 0) {\n\t\t\tduk_small_uint_t y;\n\t\t\ty = *p++;\n\t\t\tif ((y & 0xc0U) != 0x80U) {\n\t\t\t\t/* check that byte has the form 10xx xxxx */\n\t\t\t\tgoto error_encoding;\n\t\t\t}\n\t\t\tx = x << 6;\n\t\t\tx += y & 0x3fUL;\n\t\t\tcontlen--;\n\t\t}\n\n\t\t/* check final character validity */\n\n\t\tif (x > 0x10ffffUL) {\n\t\t\tgoto error_encoding;\n\t\t}\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tif (x < mincp || (x >= 0xd800UL && x <= 0xdfffUL) || x == 0xfffeUL) {\n\t\t\tgoto error_encoding;\n\t\t}\n#endif\n\n\t\tDUK_ASSERT(x != 0x000aUL && x != 0x000dUL);\n\t\tif ((x == 0x2028UL) || (x == 0x2029UL)) {\n\t\t\tinput_line++;\n\t\t}\n\n\t\tcp->codepoint = (duk_codepoint_t) x;\n\t}\n\n\tlex_ctx->input_offset = (duk_size_t) (p - lex_ctx->input);\n\tlex_ctx->input_line = input_line;\n\treturn;\n\n error_clipped:   /* clipped codepoint */\n error_encoding:  /* invalid codepoint encoding or codepoint */\n\tlex_ctx->input_offset = (duk_size_t) (p - lex_ctx->input);\n\tlex_ctx->input_line = input_line;\n\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_SOURCE_DECODE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__advance_bytes(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_bytes) {\n\tduk_small_uint_t used_bytes, avail_bytes;\n\n\tDUK_ASSERT_DISABLE(count_bytes >= 0);  /* unsigned */\n\tDUK_ASSERT(count_bytes <= (duk_small_uint_t) (DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint)));\n\tDUK_ASSERT(lex_ctx->window >= lex_ctx->buffer);\n\tDUK_ASSERT(lex_ctx->window < lex_ctx->buffer + DUK_LEXER_BUFFER_SIZE);\n\tDUK_ASSERT((duk_uint8_t *) lex_ctx->window + count_bytes <= (duk_uint8_t *) lex_ctx->buffer + DUK_LEXER_BUFFER_SIZE * sizeof(duk_lexer_codepoint));\n\n\t/* Zero 'count' is also allowed to make call sites easier.\n\t * Arithmetic in bytes generates better code in GCC.\n\t */\n\n\tlex_ctx->window = (duk_lexer_codepoint *) (void *) ((duk_uint8_t *) lex_ctx->window + count_bytes);  /* avoid multiply */\n\tused_bytes = (duk_small_uint_t) ((duk_uint8_t *) lex_ctx->window - (duk_uint8_t *) lex_ctx->buffer);\n\tavail_bytes = DUK_LEXER_BUFFER_SIZE * sizeof(duk_lexer_codepoint) - used_bytes;\n\tif (avail_bytes < (duk_small_uint_t) (DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint))) {\n\t\t/* Not enough data to provide a full window, so \"scroll\" window to\n\t\t * start of buffer and fill up the rest.\n\t\t */\n\t\tduk_memmove((void *) lex_ctx->buffer,\n\t\t            (const void *) lex_ctx->window,\n\t\t            (size_t) avail_bytes);\n\t\tlex_ctx->window = lex_ctx->buffer;\n\t\tduk__fill_lexer_buffer(lex_ctx, avail_bytes);\n\t}\n}\n\nDUK_LOCAL void duk__init_lexer_window(duk_lexer_ctx *lex_ctx) {\n\tlex_ctx->window = lex_ctx->buffer;\n\tduk__fill_lexer_buffer(lex_ctx, 0);\n}\n#else  /* DUK_USE_LEXER_SLIDING_WINDOW */\nDUK_LOCAL duk_codepoint_t duk__read_char(duk_lexer_ctx *lex_ctx) {\n\tduk_ucodepoint_t x;\n\tduk_small_uint_t len;\n\tduk_small_uint_t i;\n\tconst duk_uint8_t *p;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\tduk_ucodepoint_t mincp;\n#endif\n\tduk_size_t input_offset;\n\n\tinput_offset = lex_ctx->input_offset;\n\tif (DUK_UNLIKELY(input_offset >= lex_ctx->input_length)) {\n\t\t/* If input_offset were assigned a negative value, it would\n\t\t * result in a large positive value.  Most likely it would be\n\t\t * larger than input_length and be caught here.  In any case\n\t\t * no memory unsafe behavior would happen.\n\t\t */\n\t\treturn -1;\n\t}\n\n\tp = lex_ctx->input + input_offset;\n\tx = (duk_ucodepoint_t) (*p);\n\n\tif (DUK_LIKELY(x < 0x80UL)) {\n\t\t/* 0xxx xxxx -> fast path */\n\n\t\t/* input offset tracking */\n\t\tlex_ctx->input_offset++;\n\n\t\tDUK_ASSERT(x != 0x2028UL && x != 0x2029UL);  /* not LS/PS */\n\t\tif (DUK_UNLIKELY(x <= 0x000dUL)) {\n\t\t\tif ((x == 0x000aUL) ||\n\t\t\t    ((x == 0x000dUL) && (lex_ctx->input_offset >= lex_ctx->input_length ||\n\t\t\t                         lex_ctx->input[lex_ctx->input_offset] != 0x000aUL))) {\n\t\t\t\t/* lookup for 0x000a above assumes shortest encoding now */\n\n\t\t\t\t/* E5 Section 7.3, treat the following as newlines:\n\t\t\t\t *   LF\n\t\t\t\t *   CR [not followed by LF]\n\t\t\t\t *   LS\n\t\t\t\t *   PS\n\t\t\t\t *\n\t\t\t\t * For CR LF, CR is ignored if it is followed by LF, and the LF will bump\n\t\t\t\t * the line number.\n\t\t\t\t */\n\t\t\t\tlex_ctx->input_line++;\n\t\t\t}\n\t\t}\n\n\t\treturn (duk_codepoint_t) x;\n\t}\n\n\t/* Slow path. */\n\n\tif (x < 0xc0UL) {\n\t\t/* 10xx xxxx -> invalid */\n\t\tgoto error_encoding;\n\t} else if (x < 0xe0UL) {\n\t\t/* 110x xxxx   10xx xxxx  */\n\t\tlen = 2;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tmincp = 0x80UL;\n#endif\n\t\tx = x & 0x1fUL;\n\t} else if (x < 0xf0UL) {\n\t\t/* 1110 xxxx   10xx xxxx   10xx xxxx */\n\t\tlen = 3;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tmincp = 0x800UL;\n#endif\n\t\tx = x & 0x0fUL;\n\t} else if (x < 0xf8UL) {\n\t\t/* 1111 0xxx   10xx xxxx   10xx xxxx   10xx xxxx */\n\t\tlen = 4;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tmincp = 0x10000UL;\n#endif\n\t\tx = x & 0x07UL;\n\t} else {\n\t\t/* no point in supporting encodings of 5 or more bytes */\n\t\tgoto error_encoding;\n\t}\n\n\tDUK_ASSERT(lex_ctx->input_length >= lex_ctx->input_offset);\n\tif ((duk_size_t) len > (duk_size_t) (lex_ctx->input_length - lex_ctx->input_offset)) {\n\t\tgoto error_clipped;\n\t}\n\n\tp++;\n\tfor (i = 1; i < len; i++) {\n\t\tduk_small_uint_t y;\n\t\ty = *p++;\n\t\tif ((y & 0xc0U) != 0x80U) {\n\t\t\t/* check that byte has the form 10xx xxxx */\n\t\t\tgoto error_encoding;\n\t\t}\n\t\tx = x << 6;\n\t\tx += y & 0x3fUL;\n\t}\n\n\t/* check final character validity */\n\n\tif (x > 0x10ffffUL) {\n\t\tgoto error_encoding;\n\t}\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\tif (x < mincp || (x >= 0xd800UL && x <= 0xdfffUL) || x == 0xfffeUL) {\n\t\tgoto error_encoding;\n\t}\n#endif\n\n\t/* input offset tracking */\n\tlex_ctx->input_offset += len;\n\n\t/* line tracking */\n\tDUK_ASSERT(x != 0x000aUL && x != 0x000dUL);\n\tif ((x == 0x2028UL) || (x == 0x2029UL)) {\n\t\tlex_ctx->input_line++;\n\t}\n\n\treturn (duk_codepoint_t) x;\n\n error_clipped:   /* clipped codepoint */\n error_encoding:  /* invalid codepoint encoding or codepoint */\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_SOURCE_DECODE_FAILED);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_LOCAL void duk__advance_bytes(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_bytes) {\n\tduk_small_uint_t keep_bytes;\n\tduk_lexer_codepoint *cp, *cp_end;\n\n\tDUK_ASSERT_DISABLE(count_bytes >= 0);  /* unsigned */\n\tDUK_ASSERT(count_bytes <= (duk_small_uint_t) (DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint)));\n\n\t/* Zero 'count' is also allowed to make call sites easier. */\n\n\tkeep_bytes = DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint) - count_bytes;\n\tduk_memmove((void *) lex_ctx->window,\n\t            (const void *) ((duk_uint8_t *) lex_ctx->window + count_bytes),\n\t            (size_t) keep_bytes);\n\n\tcp = (duk_lexer_codepoint *) ((duk_uint8_t *) lex_ctx->window + keep_bytes);\n\tcp_end = lex_ctx->window + DUK_LEXER_WINDOW_SIZE;\n\tfor (; cp != cp_end; cp++) {\n\t\tcp->offset = lex_ctx->input_offset;\n\t\tcp->line = lex_ctx->input_line;\n\t\tcp->codepoint = duk__read_char(lex_ctx);\n\t}\n}\n\nDUK_LOCAL void duk__init_lexer_window(duk_lexer_ctx *lex_ctx) {\n\t/* Call with count == DUK_LEXER_WINDOW_SIZE to fill buffer initially. */\n\tduk__advance_bytes(lex_ctx, DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint));  /* fill window */\n}\n#endif  /* DUK_USE_LEXER_SLIDING_WINDOW */\n\nDUK_LOCAL void duk__advance_chars(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_chars) {\n\tduk__advance_bytes(lex_ctx, count_chars * sizeof(duk_lexer_codepoint));\n}\n\n/*\n *  (Re)initialize the temporary byte buffer.  May be called extra times\n *  with little impact.\n */\n\nDUK_LOCAL void duk__initbuffer(duk_lexer_ctx *lex_ctx) {\n\t/* Reuse buffer as is unless buffer has grown large. */\n\tif (DUK_HBUFFER_DYNAMIC_GET_SIZE(lex_ctx->buf) < DUK_LEXER_TEMP_BUF_LIMIT) {\n\t\t/* Keep current size */\n\t} else {\n\t\tduk_hbuffer_resize(lex_ctx->thr, lex_ctx->buf, DUK_LEXER_TEMP_BUF_LIMIT);\n\t}\n\n\tDUK_BW_INIT_WITHBUF(lex_ctx->thr, &lex_ctx->bw, lex_ctx->buf);\n}\n\n/*\n *  Append a Unicode codepoint to the temporary byte buffer.  Performs\n *  CESU-8 surrogate pair encoding for codepoints above the BMP.\n *  Existing surrogate pairs are allowed and also encoded into CESU-8.\n */\n\nDUK_LOCAL void duk__appendbuffer(duk_lexer_ctx *lex_ctx, duk_codepoint_t x) {\n\t/*\n\t *  Since character data is only generated by decoding the source or by\n\t *  the compiler itself, we rely on the input codepoints being correct\n\t *  and avoid a check here.\n\t *\n\t *  Character data can also come here through decoding of Unicode\n\t *  escapes (\"\\udead\\ubeef\") so all 16-but unsigned values can be\n\t *  present, even when the source file itself is strict UTF-8.\n\t */\n\tDUK_ASSERT(x >= 0 && x <= 0x10ffffL);\n\n\tDUK_BW_WRITE_ENSURE_CESU8(lex_ctx->thr, &lex_ctx->bw, (duk_ucodepoint_t) x);\n}\n\nDUK_LOCAL void duk__appendbuffer_ascii(duk_lexer_ctx *lex_ctx, duk_codepoint_t x) {\n\t/* ASCII characters can be emitted as a single byte without encoding\n\t * which matters for some fast paths.\n\t */\n\tDUK_ASSERT(x >= 0 && x <= 0x7f);\n\n\tDUK_BW_WRITE_ENSURE_U8(lex_ctx->thr, &lex_ctx->bw, (duk_uint8_t) x);\n}\n\n/*\n *  Intern the temporary byte buffer into a valstack slot\n *  (in practice, slot1 or slot2).\n */\n\nDUK_LOCAL duk_hstring *duk__internbuffer(duk_lexer_ctx *lex_ctx, duk_idx_t valstack_idx) {\n\tDUK_ASSERT(valstack_idx == lex_ctx->slot1_idx || valstack_idx == lex_ctx->slot2_idx);\n\n\tDUK_BW_PUSH_AS_STRING(lex_ctx->thr, &lex_ctx->bw);\n\tduk_replace(lex_ctx->thr, valstack_idx);\n\treturn duk_known_hstring(lex_ctx->thr, valstack_idx);\n}\n\n/*\n *  Init lexer context\n */\n\nDUK_INTERNAL void duk_lexer_initctx(duk_lexer_ctx *lex_ctx) {\n\tDUK_ASSERT(lex_ctx != NULL);\n\n\tduk_memzero(lex_ctx, sizeof(*lex_ctx));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\n\tlex_ctx->window = NULL;\n#endif\n\tlex_ctx->thr = NULL;\n\tlex_ctx->input = NULL;\n\tlex_ctx->buf = NULL;\n#endif\n}\n\n/*\n *  Set lexer input position and reinitialize lookup window.\n */\n\nDUK_INTERNAL void duk_lexer_getpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt) {\n\tpt->offset = lex_ctx->window[0].offset;\n\tpt->line = lex_ctx->window[0].line;\n}\n\nDUK_INTERNAL void duk_lexer_setpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt) {\n\tDUK_ASSERT_DISABLE(pt->offset >= 0);  /* unsigned */\n\tDUK_ASSERT(pt->line >= 1);\n\tlex_ctx->input_offset = pt->offset;\n\tlex_ctx->input_line = pt->line;\n\tduk__init_lexer_window(lex_ctx);\n}\n\n/*\n *  Lexing helpers\n */\n\n/* Numeric value of a hex digit (also covers octal and decimal digits) or\n * -1 if not a valid hex digit.\n */\nDUK_LOCAL duk_codepoint_t duk__hexval_validate(duk_codepoint_t x) {\n\tduk_small_int_t t;\n\n\t/* Here 'x' is a Unicode codepoint */\n\tif (DUK_LIKELY(x >= 0 && x <= 0xff)) {\n\t\tt = duk_hex_dectab[x];\n\t\tif (DUK_LIKELY(t >= 0)) {\n\t\t\treturn t;\n\t\t}\n\t}\n\n\treturn -1;\n}\n\n/* Just a wrapper for call sites where 'x' is known to be valid so\n * we assert for it before decoding.\n */\nDUK_LOCAL duk_codepoint_t duk__hexval(duk_codepoint_t x) {\n\tduk_codepoint_t ret;\n\n\tDUK_ASSERT((x >= DUK_ASC_0 && x <= DUK_ASC_9) ||\n\t           (x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_F) ||\n\t           (x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_F));\n\tret = duk__hexval_validate(x);\n\tDUK_ASSERT(ret >= 0 && ret <= 15);\n\treturn ret;\n}\n\n/* having this as a separate function provided a size benefit */\nDUK_LOCAL duk_bool_t duk__is_hex_digit(duk_codepoint_t x) {\n\tif (DUK_LIKELY(x >= 0 && x <= 0xff)) {\n\t\treturn (duk_hex_dectab[x] >= 0);\n\t}\n\treturn 0;\n}\n\n/* Parse a Unicode escape of the form \\xHH, \\uHHHH, or \\u{H+}.  Shared by\n * source and RegExp parsing.\n */\nDUK_LOCAL duk_codepoint_t duk__lexer_parse_escape(duk_lexer_ctx *lex_ctx, duk_bool_t allow_es6) {\n\tduk_small_int_t digits;  /* Initial value 2 or 4 for fixed length escapes, 0 for ES2015 \\u{H+}. */\n\tduk_codepoint_t escval;\n\tduk_codepoint_t x;\n\tduk_small_uint_t adv;\n\n\tDUK_ASSERT(DUK__L0() == DUK_ASC_BACKSLASH);  /* caller responsibilities */\n\tDUK_ASSERT(DUK__L1() == DUK_ASC_LC_X || DUK__L1() == DUK_ASC_LC_U);\n\tDUK_UNREF(allow_es6);\n\n\tadv = 2;\n\tdigits = 2;\n\tif (DUK__L1() == DUK_ASC_LC_U) {\n\t\tdigits = 4;\n#if defined(DUK_USE_ES6_UNICODE_ESCAPE)\n\t\tif (DUK__L2() == DUK_ASC_LCURLY && allow_es6) {\n\t\t\tdigits = 0;\n\t\t\tadv = 3;\n\t\t}\n#endif\n\t}\n\tDUK__ADVANCECHARS(lex_ctx, adv);\n\n\tescval = 0;\n\tfor (;;) {\n\t\t/* One of the escape forms: \\xHH, \\uHHHH, \\u{H+}.\n\t\t * The 'digits' variable tracks parsing state and is\n\t\t * initialized to:\n\t\t *\n\t\t *   \\xHH     2\n\t\t *   \\uHH     4\n\t\t *   \\u{H+}   0 first time, updated to -1 to indicate\n\t\t *            at least one digit has been parsed\n\t\t *\n\t\t * Octal parsing is handled separately because it can be\n\t\t * done with fixed lookahead and also has validation\n\t\t * rules which depend on the escape length (which is\n\t\t * variable).\n\t\t *\n\t\t * We don't need a specific check for x < 0 (end of\n\t\t * input) or duk_unicode_is_line_terminator(x)\n\t\t * because the 'dig' decode will fail and lead to a\n\t\t * SyntaxError.\n\t\t */\n\t\tduk_codepoint_t dig;\n\n\t\tx = DUK__L0();\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\n\t\tdig = duk__hexval_validate(x);\n\t\tif (digits > 0) {\n\t\t\tdigits--;\n\t\t\tif (dig < 0) {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t\tDUK_ASSERT(dig >= 0x00 && dig <= 0x0f);\n\t\t\tescval = (escval << 4) + dig;\n\t\t\tif (digits == 0) {\n\t\t\t\tDUK_ASSERT(escval >= 0 && escval <= 0xffffL);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n#if defined(DUK_USE_ES6_UNICODE_ESCAPE)\n\t\t\tDUK_ASSERT(digits == 0 /* first time */ || digits == -1 /* others */);\n\t\t\tif (dig >= 0) {\n\t\t\t\tDUK_ASSERT(dig >= 0x00 && dig <= 0x0f);\n\t\t\t\tescval = (escval << 4) + dig;\n\t\t\t\tif (escval > 0x10ffffL) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_RCURLY) {\n\t\t\t\tif (digits == 0) {\n\t\t\t\t\t/* Empty escape, \\u{}. */\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(escval >= 0 && escval <= 0x10ffffL);\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t\tdigits = -1;  /* Indicate we have at least one digit. */\n#else  /* DUK_USE_ES6_UNICODE_ESCAPE */\n\t\t\tDUK_ASSERT(0);  /* Never happens if \\u{H+} support disabled. */\n#endif  /* DUK_USE_ES6_UNICODE_ESCAPE */\n\t\t}\n\t}\n\n\treturn escval;\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Parse legacy octal escape of the form \\N{1,3}, e.g. \\0, \\5, \\0377.  Maximum\n * allowed value is \\0377 (U+00FF), longest match is used.  Used for both string\n * RegExp octal escape parsing.  Window[0] must be the slash '\\' and the first\n * digit must already be validated to be in [0-9] by the caller.\n */\nDUK_LOCAL duk_codepoint_t duk__lexer_parse_legacy_octal(duk_lexer_ctx *lex_ctx, duk_small_uint_t *out_adv, duk_bool_t reject_annex_b) {\n\tduk_codepoint_t cp;\n\tduk_small_uint_t lookup_idx;\n\tduk_small_uint_t adv;\n\tduk_codepoint_t tmp;\n\n\tDUK_ASSERT(out_adv != NULL);\n\tDUK_ASSERT(DUK__LOOKUP(lex_ctx, 0) == DUK_ASC_BACKSLASH);\n\tDUK_ASSERT(DUK__LOOKUP(lex_ctx, 1) >= DUK_ASC_0 && DUK__LOOKUP(lex_ctx, 1) <= DUK_ASC_9);\n\n\tcp = 0;\n\ttmp = 0;\n\tfor (lookup_idx = 1; lookup_idx <= 3; lookup_idx++) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"lookup_idx=%ld, cp=%ld\", (long) lookup_idx, (long) cp));\n\t\ttmp = DUK__LOOKUP(lex_ctx, lookup_idx);\n\t\tif (tmp < DUK_ASC_0 || tmp > DUK_ASC_7) {\n\t\t\t/* No more valid digits. */\n\t\t\tbreak;\n\t\t}\n\t\ttmp = (cp << 3) + (tmp - DUK_ASC_0);\n\t\tif (tmp > 0xff) {\n\t\t\t/* Three digit octal escapes above \\377 (= 0xff)\n\t\t\t * are not allowed.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\t\tcp = tmp;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"final lookup_idx=%ld, cp=%ld\", (long) lookup_idx, (long) cp));\n\n\tadv = lookup_idx;\n\tif (lookup_idx == 1) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"\\\\8 or \\\\9 -> treat as literal, accept in strict mode too\"));\n\t\tDUK_ASSERT(tmp == DUK_ASC_8 || tmp == DUK_ASC_9);\n\t\tcp = tmp;\n\t\tadv++;  /* correction to above, eat offending character */\n\t} else if (lookup_idx == 2 && cp == 0) {\n\t\t/* Note: 'foo\\0bar' is OK in strict mode, but 'foo\\00bar' is not.\n\t\t * It won't be interpreted as 'foo\\u{0}0bar' but as a SyntaxError.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"\\\\0 -> accept in strict mode too\"));\n\t} else {\n\t\t/* This clause also handles non-shortest zero, e.g. \\00. */\n\t\tif (reject_annex_b) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-zero octal literal %ld -> reject in strict-mode\", (long) cp));\n\t\t\tcp = -1;\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-zero octal literal %ld -> accepted\", (long) cp));\n\t\t\tDUK_ASSERT(cp >= 0 && cp <= 0xff);\n\t\t}\n\t}\n\n\t*out_adv = adv;\n\n\tDUK_ASSERT((cp >= 0 && cp <= 0xff) || (cp == -1 && reject_annex_b));\n\treturn cp;\n}\n\n/* XXX: move strict mode to lex_ctx? */\nDUK_LOCAL void duk__lexer_parse_string_literal(duk_lexer_ctx *lex_ctx, duk_token *out_token, duk_small_int_t quote, duk_bool_t strict_mode) {\n\tduk_small_uint_t adv;\n\n\tfor (adv = 1 /* initial quote */ ;;) {\n\t\tduk_codepoint_t x;\n\n\t\tDUK__ADVANCECHARS(lex_ctx, adv);  /* eat opening quote on first loop */\n\t\tx = DUK__L0();\n\n\t\tadv = 1;\n\t\tif (x == quote) {\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat closing quote */\n\t\t\tbreak;\n\t\t} else if (x == '\\\\') {\n\t\t\t/* DUK__L0        -> '\\' char\n\t\t\t * DUK__L1 ... DUK__L5 -> more lookup\n\t\t\t */\n\t\t\tduk_small_int_t emitcp = -1;\n\n\t\t\tx = DUK__L1();\n\n\t\t\t/* How much to advance before next loop. */\n\t\t\tadv = 2;  /* note: long live range */\n\n\t\t\tswitch (x) {\n\t\t\tcase '\\'':\n\t\t\t\temitcp = 0x0027;\n\t\t\t\tbreak;\n\t\t\tcase '\"':\n\t\t\t\temitcp = 0x0022;\n\t\t\t\tbreak;\n\t\t\tcase '\\\\':\n\t\t\t\temitcp = 0x005c;\n\t\t\t\tbreak;\n\t\t\tcase 'b':\n\t\t\t\temitcp = 0x0008;\n\t\t\t\tbreak;\n\t\t\tcase 'f':\n\t\t\t\temitcp = 0x000c;\n\t\t\t\tbreak;\n\t\t\tcase 'n':\n\t\t\t\temitcp = 0x000a;\n\t\t\t\tbreak;\n\t\t\tcase 'r':\n\t\t\t\temitcp = 0x000d;\n\t\t\t\tbreak;\n\t\t\tcase 't':\n\t\t\t\temitcp = 0x0009;\n\t\t\t\tbreak;\n\t\t\tcase 'v':\n\t\t\t\temitcp = 0x000b;\n\t\t\t\tbreak;\n\t\t\tcase 'x':\n\t\t\tcase 'u': {\n\t\t\t\tduk_codepoint_t esc_cp;\n\t\t\t\tesc_cp = duk__lexer_parse_escape(lex_ctx, 1 /*allow_es6*/);\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, esc_cp);\n\t\t\t\tadv = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tif (duk_unicode_is_line_terminator(x)) {\n\t\t\t\t\t/* line continuation */\n\t\t\t\t\tif (x == 0x000d && DUK__L2() == 0x000a) {\n\t\t\t\t\t\t/* CR LF again a special case */\n\t\t\t\t\t\tadv = 3;  /* line terminator, CR, LF */\n\t\t\t\t\t}\n\t\t\t\t} else if (DUK__ISDIGIT(x)) {\n\t\t\t\t\t/*\n\t\t\t\t\t *  Octal escape or zero escape:\n\t\t\t\t\t *    \\0                                     (lookahead not OctalDigit)\n\t\t\t\t\t *    \\1 ... \\7                              (lookahead not OctalDigit)\n\t\t\t\t\t *    \\ZeroToThree OctalDigit                (lookahead not OctalDigit)\n\t\t\t\t\t *    \\FourToSeven OctalDigit                (no lookahead restrictions)\n\t\t\t\t\t *    \\ZeroToThree OctalDigit OctalDigit     (no lookahead restrictions)\n\t\t\t\t\t *\n\t\t\t\t\t *  Zero escape is part of the standard syntax.  Octal escapes are\n\t\t\t\t\t *  defined in E5 Section B.1.2, and are only allowed in non-strict mode.\n\t\t\t\t\t *  Any other productions starting with a decimal digit are invalid\n\t\t\t\t\t *  but are in practice treated like identity escapes.\n\t\t\t\t\t *\n\t\t\t\t\t *  Parse octal (up to 3 digits) from the lookup window.\n\t\t\t\t\t */\n\n\t\t\t\t\temitcp = duk__lexer_parse_legacy_octal(lex_ctx, &adv, strict_mode /*reject_annex_b*/);\n\t\t\t\t\tif (emitcp < 0) {\n\t\t\t\t\t\tgoto fail_escape;\n\t\t\t\t\t}\n\t\t\t\t} else if (x < 0) {\n\t\t\t\t\tgoto fail_unterminated;\n\t\t\t\t} else {\n\t\t\t\t\t/* escaped NonEscapeCharacter */\n\t\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t\t}\n\t\t\t}  /* end default clause */\n\t\t\t}  /* end switch */\n\n\t\t\t/* Shared handling for single codepoint escapes. */\n\t\t\tif (emitcp >= 0) {\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, emitcp);\n\t\t\t}\n\n\t\t\t/* Track number of escapes; count not really needed but directive\n\t\t\t * prologues need to detect whether there were any escapes or line\n\t\t\t * continuations or not.\n\t\t\t */\n\t\t\tout_token->num_escapes++;\n\t\t} else if (x >= 0x20 && x <= 0x7f) {\n\t\t\t/* Fast path for ASCII case, avoids line terminator\n\t\t\t * check and CESU-8 encoding.\n\t\t\t */\n\t\t\tDUK_ASSERT(x >= 0);\n\t\t\tDUK_ASSERT(!duk_unicode_is_line_terminator(x));\n\t\t\tDUK_ASSERT(x != quote);\n\t\t\tDUK_ASSERT(x != DUK_ASC_BACKSLASH);\n\t\t\tDUK__APPENDBUFFER_ASCII(lex_ctx, x);\n\t\t} else if (x < 0 || duk_unicode_is_line_terminator(x)) {\n\t\t\tgoto fail_unterminated;\n\t\t} else {\n\t\t\t/* Character which is part of the string but wasn't handled\n\t\t\t * by the fast path.\n\t\t\t */\n\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t}\n\t} /* string parse loop */\n\n\treturn;\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterminated:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_STRING);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Skip to end-of-line (or end-of-file), used for single line comments. */\nDUK_LOCAL void duk__lexer_skip_to_endofline(duk_lexer_ctx *lex_ctx) {\n\tfor (;;) {\n\t\tduk_codepoint_t x;\n\n\t\tx = DUK__L0();\n\t\tif (x < 0 || duk_unicode_is_line_terminator(x)) {\n\t\t\tbreak;\n\t\t}\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t}\n}\n\n/*\n *  Parse ECMAScript source InputElementDiv or InputElementRegExp\n *  (E5 Section 7), skipping whitespace, comments, and line terminators.\n *\n *  Possible results are:\n *    (1) a token\n *    (2) a line terminator (skipped)\n *    (3) a comment (skipped)\n *    (4) EOF\n *\n *  White space is automatically skipped from the current position (but\n *  not after the input element).  If input has already ended, returns\n *  DUK_TOK_EOF indefinitely.  If a parse error occurs, uses an DUK_ERROR()\n *  macro call (and hence a longjmp through current heap longjmp context).\n *  Comments and line terminator tokens are automatically skipped.\n *\n *  The input element being matched is determined by regexp_mode; if set,\n *  parses a InputElementRegExp, otherwise a InputElementDiv.  The\n *  difference between these are handling of productions starting with a\n *  forward slash.\n *\n *  If strict_mode is set, recognizes additional future reserved words\n *  specific to strict mode, and refuses to parse octal literals.\n *\n *  The matching strategy below is to (currently) use a six character\n *  lookup window to quickly determine which production is the -longest-\n *  matching one, and then parse that.  The top-level if-else clauses\n *  match the first character, and the code blocks for each clause\n *  handle -all- alternatives for that first character.  ECMAScript\n *  specification uses the \"longest match wins\" semantics, so the order\n *  of the if-clauses matters.\n *\n *  Misc notes:\n *\n *    * ECMAScript numeric literals do not accept a sign character.\n *      Consequently e.g. \"-1.0\" is parsed as two tokens: a negative\n *      sign and a positive numeric literal.  The compiler performs\n *      the negation during compilation, so this has no adverse impact.\n *\n *    * There is no token for \"undefined\": it is just a value available\n *      from the global object (or simply established by doing a reference\n *      to an undefined value).\n *\n *    * Some contexts want Identifier tokens, which are IdentifierNames\n *      excluding reserved words, while some contexts want IdentifierNames\n *      directly.  In the latter case e.g. \"while\" is interpreted as an\n *      identifier name, not a DUK_TOK_WHILE token.  The solution here is\n *      to provide both token types: DUK_TOK_WHILE goes to 't' while\n *      DUK_TOK_IDENTIFIER goes to 't_nores', and 'slot1' always contains\n *      the identifier / keyword name.\n *\n *    * Directive prologue needs to identify string literals such as\n *      \"use strict\" and 'use strict', which are sensitive to line\n *      continuations and escape sequences.  For instance, \"use\\u0020strict\"\n *      is a valid directive but is distinct from \"use strict\".  The solution\n *      here is to decode escapes while tokenizing, but to keep track of the\n *      number of escapes.  Directive detection can then check that the\n *      number of escapes is zero.\n *\n *    * Multi-line comments with one or more internal LineTerminator are\n *      treated like a line terminator to comply with automatic semicolon\n *      insertion.\n */\n\nDUK_INTERNAL\nvoid duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,\n                                      duk_token *out_token,\n                                      duk_bool_t strict_mode,\n                                      duk_bool_t regexp_mode) {\n\tduk_codepoint_t x;           /* temporary, must be signed and 32-bit to hold Unicode code points */\n\tduk_small_uint_t advtok = 0; /* (advance << 8) + token_type, updated at function end,\n\t                              * init is unnecessary but suppresses \"may be used uninitialized\" warnings.\n\t                              */\n\tduk_bool_t got_lineterm = 0;  /* got lineterm preceding non-whitespace, non-lineterm token */\n\n\tif (++lex_ctx->token_count >= lex_ctx->token_limit) {\n\t\tgoto fail_token_limit;\n\t}\n\n\tout_token->t = DUK_TOK_EOF;\n\tout_token->t_nores = DUK_TOK_INVALID;  /* marker: copy t if not changed */\n#if 0  /* not necessary to init, disabled for faster parsing */\n\tout_token->num = DUK_DOUBLE_NAN;\n\tout_token->str1 = NULL;\n\tout_token->str2 = NULL;\n#endif\n\tout_token->num_escapes = 0;\n\t/* out_token->lineterm set by caller */\n\n\t/* This would be nice, but parsing is faster without resetting the\n\t * value slots.  The only side effect is that references to temporary\n\t * string values may linger until lexing is finished; they're then\n\t * freed normally.\n\t */\n#if 0\n\tduk_to_undefined(lex_ctx->thr, lex_ctx->slot1_idx);\n\tduk_to_undefined(lex_ctx->thr, lex_ctx->slot2_idx);\n#endif\n\n\t/* 'advtok' indicates how much to advance and which token id to assign\n\t * at the end.  This shared functionality minimizes code size.  All\n\t * code paths are required to set 'advtok' to some value, so no default\n\t * init value is used.  Code paths calling DUK_ERROR() never return so\n\t * they don't need to set advtok.\n\t */\n\n\t/*\n\t *  Matching order:\n\t *\n\t *    Punctuator first chars, also covers comments, regexps\n\t *    LineTerminator\n\t *    Identifier or reserved word, also covers null/true/false literals\n\t *    NumericLiteral\n\t *    StringLiteral\n\t *    EOF\n\t *\n\t *  The order does not matter as long as the longest match is\n\t *  always correctly identified.  There are order dependencies\n\t *  in the clauses, so it's not trivial to convert to a switch.\n\t */\n\n restart_lineupdate:\n\tout_token->start_line = lex_ctx->window[0].line;\n\n restart:\n\tout_token->start_offset = lex_ctx->window[0].offset;\n\n\tx = DUK__L0();\n\n\tswitch (x) {\n\tcase DUK_ASC_SPACE:\n\tcase DUK_ASC_HT:  /* fast paths for space and tab */\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\tgoto restart;\n\tcase DUK_ASC_LF:  /* LF line terminator; CR LF and Unicode lineterms are handled in slow path */\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\tgot_lineterm = 1;\n\t\tgoto restart_lineupdate;\n#if defined(DUK_USE_SHEBANG_COMMENTS)\n\tcase DUK_ASC_HASH:  /* '#' */\n\t\tif (DUK__L1() == DUK_ASC_EXCLAMATION && lex_ctx->window[0].offset == 0 &&\n\t\t    (lex_ctx->flags & DUK_COMPILE_SHEBANG)) {\n\t\t\t/* \"Shebang\" comment ('#! ...') on first line. */\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 2) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t}\n\t\tgoto fail_token;\n#endif  /* DUK_USE_SHEBANG_COMMENTS */\n\tcase DUK_ASC_SLASH:  /* '/' */\n\t\tif (DUK__L1() == DUK_ASC_SLASH) {\n\t\t\t/*\n\t\t\t *  E5 Section 7.4, allow SourceCharacter (which is any 16-bit\n\t\t\t *  code point).\n\t\t\t */\n\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 2) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t} else if (DUK__L1() == DUK_ASC_STAR) {\n\t\t\t/*\n\t\t\t *  E5 Section 7.4.  If the multi-line comment contains a newline,\n\t\t\t *  it is treated like a single line terminator for automatic\n\t\t\t *  semicolon insertion.\n\t\t\t */\n\n\t\t\tduk_bool_t last_asterisk = 0;\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 2);\n\t\t\tfor (;;) {\n\t\t\t\tx = DUK__L0();\n\t\t\t\tif (x < 0) {\n\t\t\t\t\tgoto fail_unterm_comment;\n\t\t\t\t}\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t\tif (last_asterisk && x == DUK_ASC_SLASH) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (duk_unicode_is_line_terminator(x)) {\n\t\t\t\t\tgot_lineterm = 1;\n\t\t\t\t}\n\t\t\t\tlast_asterisk = (x == DUK_ASC_STAR);\n\t\t\t}\n\t\t\tgoto restart_lineupdate;\n\t\t} else if (regexp_mode) {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t/*\n\t\t\t *  \"/\" followed by something in regexp mode.  See E5 Section 7.8.5.\n\t\t\t *\n\t\t\t *  RegExp parsing is a bit complex.  First, the regexp body is delimited\n\t\t\t *  by forward slashes, but the body may also contain forward slashes as\n\t\t\t *  part of an escape sequence or inside a character class (delimited by\n\t\t\t *  square brackets).  A mini state machine is used to implement these.\n\t\t\t *\n\t\t\t *  Further, an early (parse time) error must be thrown if the regexp\n\t\t\t *  would cause a run-time error when used in the expression new RegExp(...).\n\t\t\t *  Parsing here simply extracts the (candidate) regexp, and also accepts\n\t\t\t *  invalid regular expressions (which are delimited properly).  The caller\n\t\t\t *  (compiler) must perform final validation and regexp compilation.\n\t\t\t *\n\t\t\t *  RegExp first char may not be '/' (single line comment) or '*' (multi-\n\t\t\t *  line comment).  These have already been checked above, so there is no\n\t\t\t *  need below for special handling of the first regexp character as in\n\t\t\t *  the E5 productions.\n\t\t\t *\n\t\t\t *  About unicode escapes within regexp literals:\n\t\t\t *\n\t\t\t *      E5 Section 7.8.5 grammar does NOT accept \\uHHHH escapes.\n\t\t\t *      However, Section 6 states that regexps accept the escapes,\n\t\t\t *      see paragraph starting with \"In string literals...\".\n\t\t\t *      The regexp grammar, which sees the decoded regexp literal\n\t\t\t *      (after lexical parsing) DOES have a \\uHHHH unicode escape.\n\t\t\t *      So, for instance:\n\t\t\t *\n\t\t\t *          /\\u1234/\n\t\t\t *\n\t\t\t *      should first be parsed by the lexical grammar as:\n\t\t\t *\n\t\t\t *          '\\' 'u'      RegularExpressionBackslashSequence\n\t\t\t *          '1'          RegularExpressionNonTerminator\n\t\t\t *          '2'          RegularExpressionNonTerminator\n\t\t\t *          '3'          RegularExpressionNonTerminator\n\t\t\t *          '4'          RegularExpressionNonTerminator\n\t\t\t *\n\t\t\t *      and the escape itself is then parsed by the regexp engine.\n\t\t\t *      This is the current implementation.\n\t\t\t *\n\t\t\t *  Minor spec inconsistency:\n\t\t\t *\n\t\t\t *      E5 Section 7.8.5 RegularExpressionBackslashSequence is:\n\t\t\t *\n\t\t\t *         \\ RegularExpressionNonTerminator\n\t\t\t *\n\t\t\t *      while Section A.1 RegularExpressionBackslashSequence is:\n\t\t\t *\n\t\t\t *         \\ NonTerminator\n\t\t\t *\n\t\t\t *      The latter is not normative and a typo.\n\t\t\t *\n\t\t\t */\n\n\t\t\t/* first, parse regexp body roughly */\n\n\t\t\tduk_small_int_t state = 0;  /* 0=base, 1=esc, 2=class, 3=class+esc */\n\n\t\t\tDUK__INITBUFFER(lex_ctx);\n\t\t\tfor (;;) {\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* skip opening slash on first loop */\n\t\t\t\tx = DUK__L0();\n\t\t\t\tif (x < 0 || duk_unicode_is_line_terminator(x)) {\n\t\t\t\t\tgoto fail_unterm_regexp;\n\t\t\t\t}\n\t\t\t\tx = DUK__L0();  /* re-read to avoid spill / fetch */\n\t\t\t\tif (state == 0) {\n\t\t\t\t\tif (x == DUK_ASC_SLASH) {\n\t\t\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat closing slash */\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\t\t\t\tstate = 1;\n\t\t\t\t\t} else if (x == DUK_ASC_LBRACKET) {\n\t\t\t\t\t\tstate = 2;\n\t\t\t\t\t}\n\t\t\t\t} else if (state == 1) {\n\t\t\t\t\tstate = 0;\n\t\t\t\t} else if (state == 2) {\n\t\t\t\t\tif (x == DUK_ASC_RBRACKET) {\n\t\t\t\t\t\tstate = 0;\n\t\t\t\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\t\t\t\tstate = 3;\n\t\t\t\t\t}\n\t\t\t\t} else { /* state == 3 */\n\t\t\t\t\tstate = 2;\n\t\t\t\t}\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t}\n\t\t\tout_token->str1 = duk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\n\t\t\t/* second, parse flags */\n\n\t\t\tDUK__INITBUFFER(lex_ctx);\n\t\t\tfor (;;) {\n\t\t\t\tx = DUK__L0();\n\t\t\t\tif (!duk_unicode_is_identifier_part(x)) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tx = DUK__L0();  /* re-read to avoid spill / fetch */\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t}\n\t\t\tout_token->str2 = duk__internbuffer(lex_ctx, lex_ctx->slot2_idx);\n\n\t\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\t\t/* validation of the regexp is caller's responsibility */\n\n\t\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_REGEXP);\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\tgoto fail_regexp_support;\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\t/* \"/=\" and not in regexp mode */\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_DIV_EQ);\n\t\t} else {\n\t\t\t/* \"/\" and not in regexp mode */\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_DIV);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_LCURLY:  /* '{' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LCURLY);\n\t\tbreak;\n\tcase DUK_ASC_RCURLY:  /* '}' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_RCURLY);\n\t\tbreak;\n\tcase DUK_ASC_LPAREN:  /* '(' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LPAREN);\n\t\tbreak;\n\tcase DUK_ASC_RPAREN:  /* ')' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_RPAREN);\n\t\tbreak;\n\tcase DUK_ASC_LBRACKET:  /* '[' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LBRACKET);\n\t\tbreak;\n\tcase DUK_ASC_RBRACKET:  /* ']' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_RBRACKET);\n\t\tbreak;\n\tcase DUK_ASC_PERIOD:  /* '.' */\n\t\tif (DUK__ISDIGIT(DUK__L1())) {\n\t\t\t/* Period followed by a digit can only start DecimalLiteral\n\t\t\t * (handled in slow path).  We could jump straight into the\n\t\t\t * DecimalLiteral handling but should avoid goto to inside\n\t\t\t * a block.\n\t\t\t */\n\t\t\tgoto slow_path;\n\t\t}\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_PERIOD);\n\t\tbreak;\n\tcase DUK_ASC_SEMICOLON:  /* ';' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_SEMICOLON);\n\t\tbreak;\n\tcase DUK_ASC_COMMA:  /* ',' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_COMMA);\n\t\tbreak;\n\tcase DUK_ASC_LANGLE:  /* '<' */\n#if defined(DUK_USE_HTML_COMMENTS)\n\t\tif (DUK__L1() == DUK_ASC_EXCLAMATION && DUK__L2() == DUK_ASC_MINUS && DUK__L3() == DUK_ASC_MINUS) {\n\t\t\t/*\n\t\t\t *  ES2015: B.1.3, handle \"<!--\" SingleLineHTMLOpenComment\n\t\t\t */\n\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 4) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t}\n\t\telse\n#endif  /* DUK_USE_HTML_COMMENTS */\n\t\tif (DUK__L1() == DUK_ASC_LANGLE && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_ALSHIFT_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_LE);\n\t\t} else if (DUK__L1() == DUK_ASC_LANGLE) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_ALSHIFT);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LT);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_RANGLE:  /* '>' */\n\t\tif (DUK__L1() == DUK_ASC_RANGLE && DUK__L2() == DUK_ASC_RANGLE && DUK__L3() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(4, DUK_TOK_RSHIFT_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_RANGLE && DUK__L2() == DUK_ASC_RANGLE) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_RSHIFT);\n\t\t} else if (DUK__L1() == DUK_ASC_RANGLE && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_ARSHIFT_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_GE);\n\t\t} else if (DUK__L1() == DUK_ASC_RANGLE) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_ARSHIFT);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_GT);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_EQUALS:  /* '=' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_SEQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_EQUALSIGN);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_EXCLAMATION:  /* '!' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_SNEQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_NEQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LNOT);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_PLUS:  /* '+' */\n\t\tif (DUK__L1() == DUK_ASC_PLUS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_INCREMENT);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_ADD_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_ADD);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_MINUS:  /* '-' */\n#if defined(DUK_USE_HTML_COMMENTS)\n\t\tif (got_lineterm && DUK__L1() == DUK_ASC_MINUS && DUK__L2() == DUK_ASC_RANGLE) {\n\t\t\t/*\n\t\t\t *  ES2015: B.1.3, handle \"-->\" SingleLineHTMLCloseComment\n\t\t\t *  Only allowed:\n\t\t\t *  - on new line\n\t\t\t *  - preceded only by whitespace\n\t\t\t *  - preceded by end of multiline comment and optional whitespace\n\t\t\t *\n\t\t\t * Since whitespace generates no tokens, and multiline comments\n\t\t\t * are treated as a line ending, consulting `got_lineterm` is\n\t\t\t * sufficient to test for these three options.\n\t\t\t */\n\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 3) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t} else\n#endif  /* DUK_USE_HTML_COMMENTS */\n\t\tif (DUK__L1() == DUK_ASC_MINUS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_DECREMENT);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_SUB_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_SUB);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_STAR:  /* '*' */\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tif (DUK__L1() == DUK_ASC_STAR && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_EXP_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_STAR) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_EXP);\n\t\t} else\n#endif\n\t\tif (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_MUL_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_MUL);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_PERCENT:  /* '%' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_MOD_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_MOD);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_AMP:  /* '&' */\n\t\tif (DUK__L1() == DUK_ASC_AMP) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_LAND);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_BAND_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BAND);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_PIPE:  /* '|' */\n\t\tif (DUK__L1() == DUK_ASC_PIPE) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_LOR);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_BOR_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BOR);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_CARET:  /* '^' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_BXOR_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BXOR);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_TILDE:  /* '~' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BNOT);\n\t\tbreak;\n\tcase DUK_ASC_QUESTION:  /* '?' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_QUESTION);\n\t\tbreak;\n\tcase DUK_ASC_COLON:  /* ':' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_COLON);\n\t\tbreak;\n\tcase DUK_ASC_DOUBLEQUOTE:    /* '\"' */\n\tcase DUK_ASC_SINGLEQUOTE: {  /* '\\'' */\n\t\tDUK__INITBUFFER(lex_ctx);\n\t\tduk__lexer_parse_string_literal(lex_ctx, out_token, x /*quote*/, strict_mode);\n\t\tduk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\t\tout_token->str1 = duk_known_hstring(lex_ctx->thr, lex_ctx->slot1_idx);\n\n\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_STRING);\n\t\tbreak;\n\t}\n\tdefault:\n\t\tgoto slow_path;\n\t}  /* switch */\n\n\tgoto skip_slow_path;\n\n slow_path:\n\tif (duk_unicode_is_line_terminator(x)) {\n\t\tif (x == 0x000d && DUK__L1() == 0x000a) {\n\t\t\t/*\n\t\t\t *  E5 Section 7.3: CR LF is detected as a single line terminator for\n\t\t\t *  line numbers.  Here we also detect it as a single line terminator\n\t\t\t *  token.\n\t\t\t */\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 2);\n\t\t} else {\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t}\n\t\tgot_lineterm = 1;\n\t\tgoto restart_lineupdate;\n\t} else if (duk_unicode_is_identifier_start(x) || x == DUK_ASC_BACKSLASH) {\n\t\t/*\n\t\t *  Parse an identifier and then check whether it is:\n\t\t *    - reserved word (keyword or other reserved word)\n\t\t *    - \"null\"  (NullLiteral)\n\t\t *    - \"true\"  (BooleanLiteral)\n\t\t *    - \"false\" (BooleanLiteral)\n\t\t *    - anything else => identifier\n\t\t *\n\t\t *  This does not follow the E5 productions cleanly, but is\n\t\t *  useful and compact.\n\t\t *\n\t\t *  Note that identifiers may contain Unicode escapes,\n\t\t *  see E5 Sections 6 and 7.6.  They must be decoded first,\n\t\t *  and the result checked against allowed characters.\n\t\t *  The above if-clause accepts an identifier start and an\n\t\t *  '\\' character -- no other token can begin with a '\\'.\n\t\t *\n\t\t *  Note that \"get\" and \"set\" are not reserved words in E5\n\t\t *  specification so they are recognized as plain identifiers\n\t\t *  (the tokens DUK_TOK_GET and DUK_TOK_SET are actually not\n\t\t *  used now).  The compiler needs to work around this.\n\t\t *\n\t\t *  Strictly speaking, following ECMAScript longest match\n\t\t *  specification, an invalid escape for the first character\n\t\t *  should cause a syntax error.  However, an invalid escape\n\t\t *  for IdentifierParts should just terminate the identifier\n\t\t *  early (longest match), and let the next tokenization\n\t\t *  fail.  For instance Rhino croaks with 'foo\\z' when\n\t\t *  parsing the identifier.  This has little practical impact.\n\t\t */\n\n\t\tduk_small_uint_t i, i_end;\n\t\tduk_bool_t first = 1;\n\t\tduk_hstring *str;\n\n\t\tDUK__INITBUFFER(lex_ctx);\n\t\tfor (;;) {\n\t\t\t/* re-lookup first char on first loop */\n\t\t\tif (DUK__L0() == DUK_ASC_BACKSLASH) {\n\t\t\t\tduk_codepoint_t esc_cp;\n\t\t\t\tif (DUK__L1() != DUK_ASC_LC_U) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t\tesc_cp = duk__lexer_parse_escape(lex_ctx, 1 /*allow_es6*/);\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, esc_cp);\n\n\t\t\t\t/* IdentifierStart is stricter than IdentifierPart, so if the first\n\t\t\t\t * character is escaped, must have a stricter check here.\n\t\t\t\t */\n\t\t\t\tif (!(first ? duk_unicode_is_identifier_start(esc_cp) : duk_unicode_is_identifier_part(esc_cp))) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\n\t\t\t\t/* Track number of escapes: necessary for proper keyword\n\t\t\t\t * detection.\n\t\t\t\t */\n\t\t\t\tout_token->num_escapes++;\n\t\t\t} else {\n\t\t\t\t/* Note: first character is checked against this.  But because\n\t\t\t\t * IdentifierPart includes all IdentifierStart characters, and\n\t\t\t\t * the first character (if unescaped) has already been checked\n\t\t\t\t * in the if condition, this is OK.\n\t\t\t\t */\n\t\t\t\tif (!duk_unicode_is_identifier_part(DUK__L0())) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, DUK__L0());\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t}\n\t\t\tfirst = 0;\n\t\t}\n\n\t\tout_token->str1 = duk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\t\tstr = out_token->str1;\n\t\tout_token->t_nores = DUK_TOK_IDENTIFIER;\n\n\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\t/*\n\t\t *  Interned identifier is compared against reserved words, which are\n\t\t *  currently interned into the heap context.  See genbuiltins.py.\n\t\t *\n\t\t *  Note that an escape in the identifier disables recognition of\n\t\t *  keywords; e.g. \"\\u0069f = 1;\" is a valid statement (assigns to\n\t\t *  identifier named \"if\").  This is not necessarily compliant,\n\t\t *  see test-dec-escaped-char-in-keyword.js.\n\t\t *\n\t\t *  Note: \"get\" and \"set\" are awkward.  They are not officially\n\t\t *  ReservedWords (and indeed e.g. \"var set = 1;\" is valid), and\n\t\t *  must come out as DUK_TOK_IDENTIFIER.  The compiler needs to\n\t\t *  work around this a bit.\n\t\t */\n\n\t\t/* XXX: optimize by adding the token numbers directly into the\n\t\t * always interned duk_hstring objects (there should be enough\n\t\t * flag bits free for that)?\n\t\t */\n\n\t\ti_end = (strict_mode ? DUK_STRIDX_END_RESERVED : DUK_STRIDX_START_STRICT_RESERVED);\n\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_IDENTIFIER);\n\t\tif (out_token->num_escapes == 0) {\n\t\t\tfor (i = DUK_STRIDX_START_RESERVED; i < i_end; i++) {\n\t\t\t\tDUK_ASSERT_DISABLE(i >= 0);  /* unsigned */\n\t\t\t\tDUK_ASSERT(i < DUK_HEAP_NUM_STRINGS);\n\t\t\t\tif (DUK_HTHREAD_GET_STRING(lex_ctx->thr, i) == str) {\n\t\t\t\t\tadvtok = DUK__ADVTOK(0, DUK_STRIDX_TO_TOK(i));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if (DUK__ISDIGIT(x) || (x == DUK_ASC_PERIOD)) {\n\t\t/* Note: decimal number may start with a period, but must be followed by a digit */\n\n\t\t/*\n\t\t *  Pre-parsing for decimal, hex, octal (both legacy and ES2015),\n\t\t *  and binary literals, followed by an actual parser step\n\t\t *  provided by numconv.\n\t\t *\n\t\t *  Note: the leading sign character ('+' or '-') is -not- part of\n\t\t *  the production in E5 grammar, and that the a DecimalLiteral\n\t\t *  starting with a '0' must be followed by a non-digit.\n\t\t *\n\t\t *  XXX: the two step parsing process is quite awkward, it would\n\t\t *  be more straightforward to allow numconv to parse the longest\n\t\t *  valid prefix (it already does that, it only needs to indicate\n\t\t *  where the input ended).  However, the lexer decodes characters\n\t\t *  using a limited lookup window, so this is not a trivial change.\n\t\t */\n\n\t\t/* XXX: because of the final check below (that the literal is not\n\t\t * followed by a digit), this could maybe be simplified, if we bail\n\t\t * out early from a leading zero (and if there are no periods etc).\n\t\t * Maybe too complex.\n\t\t */\n\n\t\tduk_double_t val;\n\t\tduk_bool_t legacy_oct = 0;\n\t\tduk_small_int_t state;  /* 0=before period/exp,\n\t\t                         * 1=after period, before exp\n\t\t                         * 2=after exp, allow '+' or '-'\n\t\t                         * 3=after exp and exp sign\n\t\t                         */\n\t\tduk_small_uint_t s2n_flags;\n\t\tduk_codepoint_t y, z;\n\t\tduk_small_int_t s2n_radix = 10;\n\t\tduk_small_uint_t pre_adv = 0;\n\n\t\tDUK__INITBUFFER(lex_ctx);\n\t\ty = DUK__L1();\n\n\t\tif (x == DUK_ASC_0) {\n\t\t\tz = DUK_LOWERCASE_CHAR_ASCII(y);\n\n\t\t\tpre_adv = 2;  /* default for 0xNNN, 0oNNN, 0bNNN. */\n\t\t\tif (z == DUK_ASC_LC_X) {\n\t\t\t\ts2n_radix = 16;\n\t\t\t} else if (z == DUK_ASC_LC_O) {\n\t\t\t\ts2n_radix = 8;\n\t\t\t} else if (z == DUK_ASC_LC_B) {\n\t\t\t\ts2n_radix = 2;\n\t\t\t} else {\n\t\t\t\tpre_adv = 0;\n\t\t\t\tif (DUK__ISDIGIT(y)) {\n\t\t\t\t\tif (strict_mode) {\n\t\t\t\t\t\t/* Reject octal like \\07 but also octal-lookalike\n\t\t\t\t\t\t * decimal like \\08 in strict mode.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tgoto fail_number_literal;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t/* Legacy OctalIntegerLiteral or octal-lookalice\n\t\t\t\t\t\t * decimal.  Deciding between the two happens below\n\t\t\t\t\t\t * in digit scanning.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t\t\t\tpre_adv = 1;\n\t\t\t\t\t\tlegacy_oct = 1;\n\t\t\t\t\t\ts2n_radix = 8;  /* tentative unless conflicting digits found */\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tDUK__ADVANCECHARS(lex_ctx, pre_adv);\n\n\t\t/* XXX: we could parse integers here directly, and fall back\n\t\t * to numconv only when encountering a fractional expression\n\t\t * or when an octal literal turned out to be decimal (0778 etc).\n\t\t */\n\t\tstate = 0;\n\t\tfor (;;) {\n\t\t\tx = DUK__L0();  /* re-lookup curr char on first round */\n\t\t\tif (DUK__ISDIGIT(x)) {\n\t\t\t\t/* Note: intentionally allow leading zeroes here, as the\n\t\t\t\t * actual parser will check for them.\n\t\t\t\t */\n\t\t\t\tif (state == 0 && legacy_oct && (x == DUK_ASC_8 || x == DUK_ASC_9)) {\n\t\t\t\t\t/* Started out as an octal-lookalike\n\t\t\t\t\t * but interpreted as decimal, e.g.\n\t\t\t\t\t * '0779' -> 779.  This also means\n\t\t\t\t\t * that fractions are allowed, e.g.\n\t\t\t\t\t * '0779.123' is allowed but '0777.123'\n\t\t\t\t\t * is not!\n\t\t\t\t\t */\n\t\t\t\t\ts2n_radix = 10;\n\t\t\t\t}\n\t\t\t\tif (state == 2) {\n\t\t\t\t\tstate = 3;\n\t\t\t\t}\n\t\t\t} else if (s2n_radix == 16 && DUK__ISHEXDIGIT(x)) {\n\t\t\t\t/* Note: 'e' and 'E' are also accepted here. */\n\t\t\t\t;\n\t\t\t} else if (x == DUK_ASC_PERIOD) {\n\t\t\t\tif (state >= 1 || s2n_radix != 10) {\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tstate = 1;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_LC_E || x == DUK_ASC_UC_E) {\n\t\t\t\tif (state >= 2 || s2n_radix != 10) {\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tstate = 2;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_MINUS || x == DUK_ASC_PLUS) {\n\t\t\t\tif (state != 2) {\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tstate = 3;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t}\n\n\t\t/* XXX: better coercion */\n\t\t(void) duk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\n\t\tif (s2n_radix != 10) {\n\t\t\t/* For bases other than 10, integer only. */\n\t\t\ts2n_flags = DUK_S2N_FLAG_ALLOW_LEADING_ZERO;\n\t\t} else {\n\t\t\ts2n_flags = DUK_S2N_FLAG_ALLOW_EXP |\n\t\t\t            DUK_S2N_FLAG_ALLOW_FRAC |\n\t\t\t            DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t\t\t            DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t\t\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO;\n\t\t}\n\n\t\tduk_dup(lex_ctx->thr, lex_ctx->slot1_idx);\n\t\tduk_numconv_parse(lex_ctx->thr, s2n_radix, s2n_flags);\n\t\tval = duk_to_number_m1(lex_ctx->thr);\n\t\tif (DUK_ISNAN(val)) {\n\t\t\tgoto fail_number_literal;\n\t\t}\n\t\tduk_replace(lex_ctx->thr, lex_ctx->slot1_idx);  /* could also just pop? */\n\n\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\t/* Section 7.8.3 (note): NumericLiteral must be followed by something other than\n\t\t * IdentifierStart or DecimalDigit.\n\t\t */\n\n\t\tif (DUK__ISDIGIT(DUK__L0()) || duk_unicode_is_identifier_start(DUK__L0())) {\n\t\t\tgoto fail_number_literal;\n\t\t}\n\n\t\tout_token->num = val;\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_NUMBER);\n\t} else if (duk_unicode_is_whitespace(DUK__LOOKUP(lex_ctx, 0))) {\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\tgoto restart;\n\t} else if (x < 0) {\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_EOF);\n\t} else {\n\t\tgoto fail_token;\n\t}\n skip_slow_path:\n\n\t/*\n\t *  Shared exit path\n\t */\n\n\tDUK__ADVANCEBYTES(lex_ctx, advtok >> 8);\n\tout_token->t = advtok & 0xff;\n\tif (out_token->t_nores == DUK_TOK_INVALID) {\n\t\tout_token->t_nores = out_token->t;\n\t}\n\tout_token->lineterm = got_lineterm;\n\n\t/* Automatic semicolon insertion is allowed if a token is preceded\n\t * by line terminator(s), or terminates a statement list (right curly\n\t * or EOF).\n\t */\n\tif (got_lineterm || out_token->t == DUK_TOK_RCURLY || out_token->t == DUK_TOK_EOF) {\n\t\tout_token->allow_auto_semi = 1;\n\t} else {\n\t\tout_token->allow_auto_semi = 0;\n\t}\n\n\treturn;\n\n fail_token_limit:\n\tDUK_ERROR_RANGE(lex_ctx->thr, DUK_STR_TOKEN_LIMIT);\n\tDUK_WO_NORETURN(return;);\n\n fail_token:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_TOKEN);\n\tDUK_WO_NORETURN(return;);\n\n fail_number_literal:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_NUMBER_LITERAL);\n\tDUK_WO_NORETURN(return;);\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterm_regexp:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_REGEXP);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterm_comment:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_COMMENT);\n\tDUK_WO_NORETURN(return;);\n\n#if !defined(DUK_USE_REGEXP_SUPPORT)\n fail_regexp_support:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_REGEXP_SUPPORT_DISABLED);\n\tDUK_WO_NORETURN(return;);\n#endif\n}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Parse a RegExp token.  The grammar is described in E5 Section 15.10.\n *  Terminal constructions (such as quantifiers) are parsed directly here.\n *\n *  0xffffffffU is used as a marker for \"infinity\" in quantifiers.  Further,\n *  DUK__MAX_RE_QUANT_DIGITS limits the maximum number of digits that\n *  will be accepted for a quantifier.\n */\n\nDUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token *out_token) {\n\tduk_small_uint_t advtok = 0;  /* init is unnecessary but suppresses \"may be used uninitialized\" warnings */\n\tduk_codepoint_t x, y;\n\n\tif (++lex_ctx->token_count >= lex_ctx->token_limit) {\n\t\tgoto fail_token_limit;\n\t}\n\n\tduk_memzero(out_token, sizeof(*out_token));\n\n\tx = DUK__L0();\n\ty = DUK__L1();\n\n\tDUK_DDD(DUK_DDDPRINT(\"parsing regexp token, L0=%ld, L1=%ld\", (long) x, (long) y));\n\n\tswitch (x) {\n\tcase DUK_ASC_PIPE: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_DISJUNCTION);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_CARET: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ASSERT_START);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_DOLLAR: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ASSERT_END);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_QUESTION: {\n\t\tout_token->qmin = 0;\n\t\tout_token->qmax = 1;\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 0;\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_STAR: {\n\t\tout_token->qmin = 0;\n\t\tout_token->qmax = DUK_RE_QUANTIFIER_INFINITE;\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 0;\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_PLUS: {\n\t\tout_token->qmin = 1;\n\t\tout_token->qmax = DUK_RE_QUANTIFIER_INFINITE;\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 0;\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LCURLY: {\n\t\t/* Production allows 'DecimalDigits', including leading zeroes */\n\t\tduk_uint32_t val1 = 0;\n\t\tduk_uint32_t val2 = DUK_RE_QUANTIFIER_INFINITE;\n\t\tduk_small_int_t digits = 0;\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\tduk_lexer_point lex_pt;\n#endif\n\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t/* Store lexer position, restoring if quantifier is invalid. */\n\t\tDUK_LEXER_GETPOINT(lex_ctx, &lex_pt);\n#endif\n\n\t\tfor (;;) {\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat '{' on entry */\n\t\t\tx = DUK__L0();\n\t\t\tif (DUK__ISDIGIT(x)) {\n\t\t\t\tdigits++;\n\t\t\t\tval1 = val1 * 10 + (duk_uint32_t) duk__hexval(x);\n\t\t\t} else if (x == DUK_ASC_COMMA) {\n\t\t\t\tif (digits > DUK__MAX_RE_QUANT_DIGITS) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (val2 != DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (DUK__L1() == DUK_ASC_RCURLY) {\n\t\t\t\t\t/* form: { DecimalDigits , }, val1 = min count */\n\t\t\t\t\tif (digits == 0) {\n\t\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t\t}\n\t\t\t\t\tout_token->qmin = val1;\n\t\t\t\t\tout_token->qmax = DUK_RE_QUANTIFIER_INFINITE;\n\t\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tval2 = val1;\n\t\t\t\tval1 = 0;\n\t\t\t\tdigits = 0;  /* not strictly necessary because of lookahead '}' above */\n\t\t\t} else if (x == DUK_ASC_RCURLY) {\n\t\t\t\tif (digits > DUK__MAX_RE_QUANT_DIGITS) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (digits == 0) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (val2 != DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\t/* val2 = min count, val1 = max count */\n\t\t\t\t\tout_token->qmin = val2;\n\t\t\t\t\tout_token->qmax = val1;\n\t\t\t\t} else {\n\t\t\t\t\t/* val1 = count */\n\t\t\t\t\tout_token->qmin = val1;\n\t\t\t\t\tout_token->qmax = val1;\n\t\t\t\t}\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tgoto invalid_quantifier;\n\t\t\t}\n\t\t}\n\t\tif (DUK__L0() == DUK_ASC_QUESTION) {\n\t\t\tout_token->greedy = 0;\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t} else {\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tadvtok = DUK__ADVTOK(0, DUK_RETOK_QUANTIFIER);\n\t\tbreak;\n invalid_quantifier:\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t/* Failed to match the quantifier, restore lexer and parse\n\t\t * opening brace as a literal.\n\t\t */\n\t\tDUK_LEXER_SETPOINT(lex_ctx, &lex_pt);\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_CHAR);\n\t\tout_token->num = DUK_ASC_LCURLY;\n#else\n\t\tgoto fail_quantifier;\n#endif\n\t\tbreak;\n\t}\n\tcase DUK_ASC_PERIOD: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_PERIOD);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_BACKSLASH: {\n\t\t/* The E5.1 specification does not seem to allow IdentifierPart characters\n\t\t * to be used as identity escapes.  Unfortunately this includes '$', which\n\t\t * cannot be escaped as '\\$'; it needs to be escaped e.g. as '\\u0024'.\n\t\t * Many other implementations (including V8 and Rhino, for instance) do\n\t\t * accept '\\$' as a valid identity escape, which is quite pragmatic, and\n\t\t * ES2015 Annex B relaxes the rules to allow these (and other) real world forms.\n\t\t */\n\n\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_CHAR);  /* default: char escape (two chars) */\n\t\tif (y == DUK_ASC_LC_B) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ASSERT_WORD_BOUNDARY);\n\t\t} else if (y == DUK_ASC_UC_B) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY);\n\t\t} else if (y == DUK_ASC_LC_F) {\n\t\t\tout_token->num = 0x000c;\n\t\t} else if (y == DUK_ASC_LC_N) {\n\t\t\tout_token->num = 0x000a;\n\t\t} else if (y == DUK_ASC_LC_T) {\n\t\t\tout_token->num = 0x0009;\n\t\t} else if (y == DUK_ASC_LC_R) {\n\t\t\tout_token->num = 0x000d;\n\t\t} else if (y == DUK_ASC_LC_V) {\n\t\t\tout_token->num = 0x000b;\n\t\t} else if (y == DUK_ASC_LC_C) {\n\t\t\tx = DUK__L2();\n\t\t\tif ((x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_Z) ||\n\t\t\t    (x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_Z)) {\n\t\t\t\tout_token->num = (duk_uint32_t) (x % 32);\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ATOM_CHAR);\n\t\t\t} else {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t} else if (y == DUK_ASC_LC_X || y == DUK_ASC_LC_U) {\n\t\t\t/* The token value is the Unicode codepoint without\n\t\t\t * it being decode into surrogate pair characters\n\t\t\t * here.  The \\u{H+} is only allowed in Unicode mode\n\t\t\t * which we don't support yet.\n\t\t\t */\n\t\t\tout_token->num = (duk_uint32_t) duk__lexer_parse_escape(lex_ctx, 0 /*allow_es6*/);\n\t\t\tadvtok = DUK__ADVTOK(0, DUK_RETOK_ATOM_CHAR);\n\t\t} else if (y == DUK_ASC_LC_D) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_DIGIT);\n\t\t} else if (y == DUK_ASC_UC_D) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_NOT_DIGIT);\n\t\t} else if (y == DUK_ASC_LC_S) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_WHITE);\n\t\t} else if (y == DUK_ASC_UC_S) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_NOT_WHITE);\n\t\t} else if (y == DUK_ASC_LC_W) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_WORD_CHAR);\n\t\t} else if (y == DUK_ASC_UC_W) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_NOT_WORD_CHAR);\n\t\t} else if (DUK__ISDIGIT(y)) {\n\t\t\t/* E5 Section 15.10.2.11 */\n\t\t\tif (y == DUK_ASC_0) {\n\t\t\t\tif (DUK__ISDIGIT(DUK__L2())) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t\tout_token->num = 0x0000;\n\t\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_CHAR);\n\t\t\t} else {\n\t\t\t\t/* XXX: shared parsing? */\n\t\t\t\tduk_uint32_t val = 0;\n\t\t\t\tduk_small_int_t i;\n\t\t\t\tfor (i = 0; ; i++) {\n\t\t\t\t\tif (i >= DUK__MAX_RE_DECESC_DIGITS) {\n\t\t\t\t\t\tgoto fail_escape;\n\t\t\t\t\t}\n\t\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat backslash on entry */\n\t\t\t\t\tx = DUK__L0();\n\t\t\t\t\tif (!DUK__ISDIGIT(x)) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tval = val * 10 + (duk_uint32_t) duk__hexval(x);\n\t\t\t\t}\n\t\t\t\t/* DUK__L0() cannot be a digit, because the loop doesn't terminate if it is */\n\t\t\t\tadvtok = DUK__ADVTOK(0, DUK_RETOK_ATOM_BACKREFERENCE);\n\t\t\t\tout_token->num = val;\n\t\t\t}\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t} else if (y >= 0) {\n\t\t\t/* For ES2015 Annex B, accept any source character as identity\n\t\t\t * escape except 'c' which is used for control characters.\n\t\t\t * http://www.ecma-international.org/ecma-262/6.0/#sec-regular-expressions-patterns\n\t\t\t * Careful not to match end-of-buffer (<0) here.\n\t\t\t * This is not yet full ES2015 Annex B because cases above\n\t\t\t * (like hex escape) won't backtrack.\n\t\t\t */\n\t\t\tDUK_ASSERT(y != DUK_ASC_LC_C);  /* covered above */\n#else  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t} else if ((y >= 0 && !duk_unicode_is_identifier_part(y)) ||\n\t\t           y == DUK_UNICODE_CP_ZWNJ ||\n\t\t           y == DUK_UNICODE_CP_ZWJ) {\n\t\t\t/* For ES5.1 identity escapes are not allowed for identifier\n\t\t\t * parts.  This conflicts with a lot of real world code as this\n\t\t\t * doesn't e.g. allow escaping a dollar sign as /\\$/, see\n\t\t\t * test-regexp-identity-escape-dollar.js.\n\t\t\t */\n#endif  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t\tout_token->num = (duk_uint32_t) y;\n\t\t} else {\n\t\t\tgoto fail_escape;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LPAREN: {\n\t\t/* XXX: naming is inconsistent: ATOM_END_GROUP ends an ASSERT_START_LOOKAHEAD */\n\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tif (DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\t\t/* (?= */\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ASSERT_START_POS_LOOKAHEAD);\n\t\t\t} else if (DUK__L2() == DUK_ASC_EXCLAMATION) {\n\t\t\t\t/* (?! */\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD);\n\t\t\t} else if (DUK__L2() == DUK_ASC_COLON) {\n\t\t\t\t/* (?: */\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ATOM_START_NONCAPTURE_GROUP);\n\t\t\t} else {\n\t\t\t\tgoto fail_group;\n\t\t\t}\n\t\t} else {\n\t\t\t/* ( */\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_START_CAPTURE_GROUP);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_RPAREN: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_END_GROUP);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LBRACKET: {\n\t\t/*\n\t\t *  To avoid creating a heavy intermediate value for the list of ranges,\n\t\t *  only the start token ('[' or '[^') is parsed here.  The regexp\n\t\t *  compiler parses the ranges itself.\n\t\t */\n\n\t\t/* XXX: with DUK_USE_ES6_REGEXP_SYNTAX we should allow left bracket\n\t\t * literal too, but it's not easy to parse without backtracking.\n\t\t */\n\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_START_CHARCLASS);\n\t\tif (y == DUK_ASC_CARET) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_START_CHARCLASS_INVERTED);\n\t\t}\n\t\tbreak;\n\t}\n#if !defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\tcase DUK_ASC_RCURLY:\n\tcase DUK_ASC_RBRACKET: {\n\t\t/* Although these could be parsed as PatternCharacters unambiguously (here),\n\t\t * E5 Section 15.10.1 grammar explicitly forbids these as PatternCharacters.\n\t\t */\n\t\tgoto fail_invalid_char;\n\t\tbreak;\n\t}\n#endif\n\tcase -1: {\n\t\t/* EOF */\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_EOF);\n\t\tbreak;\n\t}\n\tdefault: {\n\t\t/* PatternCharacter, all excluded characters are matched by cases above */\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_CHAR);\n\t\tout_token->num = (duk_uint32_t) x;\n\t\tbreak;\n\t}\n\t}\n\n\t/*\n\t *  Shared exit path\n\t */\n\n\tDUK__ADVANCEBYTES(lex_ctx, advtok >> 8);\n\tout_token->t = advtok & 0xff;\n\treturn;\n\n fail_token_limit:\n\tDUK_ERROR_RANGE(lex_ctx->thr, DUK_STR_TOKEN_LIMIT);\n\tDUK_WO_NORETURN(return;);\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_group:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_GROUP);\n\tDUK_WO_NORETURN(return;);\n\n#if !defined(DUK_USE_ES6_REGEXP_SYNTAX)\n fail_invalid_char:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_CHARACTER);\n\tDUK_WO_NORETURN(return;);\n\n fail_quantifier:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_QUANTIFIER);\n\tDUK_WO_NORETURN(return;);\n#endif\n}\n\n/*\n *  Special parser for character classes; calls callback for every\n *  range parsed and returns the number of ranges present.\n */\n\n/* XXX: this duplicates functionality in duk_regexp.c where a similar loop is\n * required anyway.  We could use that BUT we need to update the regexp compiler\n * 'nranges' too.  Work this out a bit more cleanly to save space.\n */\n\n/* XXX: the handling of character range detection is a bit convoluted.\n * Try to simplify and make smaller.\n */\n\n/* XXX: logic for handling character ranges is now incorrect, it will accept\n * e.g. [\\d-z] whereas it should croak from it?  SMJS accepts this too, though.\n *\n * Needs a read through and a lot of additional tests.\n */\n\nDUK_LOCAL\nvoid duk__emit_u16_direct_ranges(duk_lexer_ctx *lex_ctx,\n                                 duk_re_range_callback gen_range,\n                                 void *userdata,\n                                 const duk_uint16_t *ranges,\n                                 duk_small_int_t num) {\n\tconst duk_uint16_t *ranges_end;\n\n\tDUK_UNREF(lex_ctx);\n\n\tranges_end = ranges + num;\n\twhile (ranges < ranges_end) {\n\t\t/* mark range 'direct', bypass canonicalization (see Wiki) */\n\t\tgen_range(userdata, (duk_codepoint_t) ranges[0], (duk_codepoint_t) ranges[1], 1);\n\t\tranges += 2;\n\t}\n}\n\nDUK_INTERNAL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_range_callback gen_range, void *userdata) {\n\tduk_codepoint_t start = -1;\n\tduk_codepoint_t ch;\n\tduk_codepoint_t x;\n\tduk_bool_t dash = 0;\n\tduk_small_uint_t adv = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"parsing regexp ranges\"));\n\n\tfor (;;) {\n\t\tDUK__ADVANCECHARS(lex_ctx, adv);\n\t\tadv = 1;\n\n\t\tx = DUK__L0();\n\n\t\tch = -1;  /* not strictly necessary, but avoids \"uninitialized variable\" warnings */\n\t\tDUK_UNREF(ch);\n\n\t\tif (x < 0) {\n\t\t\tgoto fail_unterm_charclass;\n\t\t} else if (x == DUK_ASC_RBRACKET) {\n\t\t\tif (start >= 0) {\n\t\t\t\tgen_range(userdata, start, start, 0);\n\t\t\t}\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat ']' before finishing */\n\t\t\tbreak;\n\t\t} else if (x == DUK_ASC_MINUS) {\n\t\t\tif (start >= 0 && !dash && DUK__L1() != DUK_ASC_RBRACKET) {\n\t\t\t\t/* '-' as a range indicator */\n\t\t\t\tdash = 1;\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\t/* '-' verbatim */\n\t\t\t\tch = x;\n\t\t\t}\n\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\t/*\n\t\t\t *  The escapes are same as outside a character class, except that \\b has a\n\t\t\t *  different meaning, and \\B and backreferences are prohibited (see E5\n\t\t\t *  Section 15.10.2.19).  However, it's difficult to share code because we\n\t\t\t *  handle e.g. \"\\n\" very differently: here we generate a single character\n\t\t\t *  range for it.\n\t\t\t */\n\n\t\t\t/* XXX: ES2015 surrogate pair handling. */\n\n\t\t\tx = DUK__L1();\n\n\t\t\tadv = 2;\n\n\t\t\tif (x == DUK_ASC_LC_B) {\n\t\t\t\t/* Note: '\\b' in char class is different than outside (assertion),\n\t\t\t\t * '\\B' is not allowed and is caught by the duk_unicode_is_identifier_part()\n\t\t\t\t * check below.\n\t\t\t\t */\n\t\t\t\tch = 0x0008;\n\t\t\t} else if (x == DUK_ASC_LC_F) {\n\t\t\t\tch = 0x000c;\n\t\t\t} else if (x == DUK_ASC_LC_N) {\n\t\t\t\tch = 0x000a;\n\t\t\t} else if (x == DUK_ASC_LC_T) {\n\t\t\t\tch = 0x0009;\n\t\t\t} else if (x == DUK_ASC_LC_R) {\n\t\t\t\tch = 0x000d;\n\t\t\t} else if (x == DUK_ASC_LC_V) {\n\t\t\t\tch = 0x000b;\n\t\t\t} else if (x == DUK_ASC_LC_C) {\n\t\t\t\tx = DUK__L2();\n\t\t\t\tadv = 3;\n\t\t\t\tif ((x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_Z) ||\n\t\t\t\t    (x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_Z)) {\n\t\t\t\t\tch = (x % 32);\n\t\t\t\t} else {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_LC_X || x == DUK_ASC_LC_U) {\n\t\t\t\t/* The \\u{H+} form is only allowed in Unicode mode which\n\t\t\t\t * we don't support yet.\n\t\t\t\t */\n\t\t\t\tch = duk__lexer_parse_escape(lex_ctx, 0 /*allow_es6*/);\n\t\t\t\tadv = 0;\n\t\t\t} else if (x == DUK_ASC_LC_D) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_digit,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_digit) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_UC_D) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_not_digit,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_not_digit) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_LC_S) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_white,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_white) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_UC_S) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_not_white,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_not_white) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_LC_W) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_wordchar,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_wordchar) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_UC_W) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_not_wordchar,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_not_wordchar) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (DUK__ISDIGIT(x)) {\n\t\t\t\t/* DecimalEscape, only \\0 is allowed, no leading\n\t\t\t\t * zeroes are allowed.\n\t\t\t\t *\n\t\t\t\t * ES2015 Annex B also allows (maximal match) legacy\n\t\t\t\t * octal escapes up to \\377 and \\8 and \\9 are\n\t\t\t\t * accepted as literal '8' and '9', also in strict mode.\n\t\t\t\t */\n\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t\t\tch = duk__lexer_parse_legacy_octal(lex_ctx, &adv, 0 /*reject_annex_b*/);\n\t\t\t\tDUK_ASSERT(ch >= 0);  /* no rejections */\n#else\n\t\t\t\tif (x == DUK_ASC_0 && !DUK__ISDIGIT(DUK__L2())) {\n\t\t\t\t\tch = 0x0000;\n\t\t\t\t} else {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n#endif\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t\t} else if (x >= 0) {\n\t\t\t\t/* IdentityEscape: ES2015 Annex B allows almost all\n\t\t\t\t * source characters here.  Match anything except\n\t\t\t\t * EOF here.\n\t\t\t\t */\n\t\t\t\tch = x;\n#else  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t\t} else if (!duk_unicode_is_identifier_part(x)) {\n\t\t\t\t/* IdentityEscape: ES5.1 doesn't allow identity escape\n\t\t\t\t * for identifier part characters, which conflicts with\n\t\t\t\t * some real world code.  For example, it doesn't allow\n\t\t\t\t * /[\\$]/ which is awkward.\n\t\t\t\t */\n\t\t\t\tch = x;\n#endif  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t\t} else {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t} else {\n\t\t\t/* character represents itself */\n\t\t\tch = x;\n\t\t}\n\n\t\t/* ch is a literal character here or -1 if parsed entity was\n\t\t * an escape such as \"\\s\".\n\t\t */\n\n\t\tif (ch < 0) {\n\t\t\t/* multi-character sets not allowed as part of ranges, see\n\t\t\t * E5 Section 15.10.2.15, abstract operation CharacterRange.\n\t\t\t */\n\t\t\tif (start >= 0) {\n\t\t\t\tif (dash) {\n\t\t\t\t\tgoto fail_range;\n\t\t\t\t} else {\n\t\t\t\t\tgen_range(userdata, start, start, 0);\n\t\t\t\t\tstart = -1;\n\t\t\t\t\t/* dash is already 0 */\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (start >= 0) {\n\t\t\t\tif (dash) {\n\t\t\t\t\tif (start > ch) {\n\t\t\t\t\t\tgoto fail_range;\n\t\t\t\t\t}\n\t\t\t\t\tgen_range(userdata, start, ch, 0);\n\t\t\t\t\tstart = -1;\n\t\t\t\t\tdash = 0;\n\t\t\t\t} else {\n\t\t\t\t\tgen_range(userdata, start, start, 0);\n\t\t\t\t\tstart = ch;\n\t\t\t\t\t/* dash is already 0 */\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstart = ch;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn;\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_range:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_RANGE);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterm_charclass:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_CHARCLASS);\n\tDUK_WO_NORETURN(return;);\n}\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n/* automatic undefs */\n#undef DUK__ADVANCEBYTES\n#undef DUK__ADVANCECHARS\n#undef DUK__ADVTOK\n#undef DUK__APPENDBUFFER\n#undef DUK__APPENDBUFFER_ASCII\n#undef DUK__INITBUFFER\n#undef DUK__ISDIGIT\n#undef DUK__ISDIGIT03\n#undef DUK__ISDIGIT47\n#undef DUK__ISHEXDIGIT\n#undef DUK__ISOCTDIGIT\n#undef DUK__L0\n#undef DUK__L1\n#undef DUK__L2\n#undef DUK__L3\n#undef DUK__L4\n#undef DUK__L5\n#undef DUK__LOOKUP\n#undef DUK__MAX_RE_DECESC_DIGITS\n#undef DUK__MAX_RE_QUANT_DIGITS\n/*\n *  Number-to-string and string-to-number conversions.\n *\n *  Slow path number-to-string and string-to-number conversion is based on\n *  a Dragon4 variant, with fast paths for small integers.  Big integer\n *  arithmetic is needed for guaranteeing that the conversion is correct\n *  and uses a minimum number of digits.  The big number arithmetic has a\n *  fixed maximum size and does not require dynamic allocations.\n *\n *  See: doc/number-conversion.rst.\n */\n\n/* #include duk_internal.h -> already included */\n\n#define DUK__IEEE_DOUBLE_EXP_BIAS  1023\n#define DUK__IEEE_DOUBLE_EXP_MIN   (-1022)   /* biased exp == 0 -> denormal, exp -1022 */\n\n#define DUK__DIGITCHAR(x)  duk_lc_digits[(x)]\n\n/*\n *  Tables generated with util/gennumdigits.py.\n *\n *  duk__str2num_digits_for_radix indicates, for each radix, how many input\n *  digits should be considered significant for string-to-number conversion.\n *  The input is also padded to this many digits to give the Dragon4\n *  conversion enough (apparent) precision to work with.\n *\n *  duk__str2num_exp_limits indicates, for each radix, the radix-specific\n *  minimum/maximum exponent values (for a Dragon4 integer mantissa)\n *  below and above which the number is guaranteed to underflow to zero\n *  or overflow to Infinity.  This allows parsing to keep bigint values\n *  bounded.\n */\n\nDUK_LOCAL const duk_uint8_t duk__str2num_digits_for_radix[] = {\n\t69, 44, 35, 30, 27, 25, 23, 22, 20, 20,    /* 2 to 11 */\n\t20, 19, 19, 18, 18, 17, 17, 17, 16, 16,    /* 12 to 21 */\n\t16, 16, 16, 15, 15, 15, 15, 15, 15, 14,    /* 22 to 31 */\n\t14, 14, 14, 14, 14                         /* 31 to 36 */\n};\n\ntypedef struct {\n\tduk_int16_t upper;\n\tduk_int16_t lower;\n} duk__exp_limits;\n\nDUK_LOCAL const duk__exp_limits duk__str2num_exp_limits[] = {\n\t{ 957, -1147 }, { 605, -725 },  { 479, -575 },  { 414, -496 },\n\t{ 372, -446 },  { 342, -411 },  { 321, -384 },  { 304, -364 },\n\t{ 291, -346 },  { 279, -334 },  { 268, -323 },  { 260, -312 },\n\t{ 252, -304 },  { 247, -296 },  { 240, -289 },  { 236, -283 },\n\t{ 231, -278 },  { 227, -273 },  { 223, -267 },  { 220, -263 },\n\t{ 216, -260 },  { 213, -256 },  { 210, -253 },  { 208, -249 },\n\t{ 205, -246 },  { 203, -244 },  { 201, -241 },  { 198, -239 },\n\t{ 196, -237 },  { 195, -234 },  { 193, -232 },  { 191, -230 },\n\t{ 190, -228 },  { 188, -226 },  { 187, -225 },\n};\n\n/*\n *  Limited functionality bigint implementation.\n *\n *  Restricted to non-negative numbers with less than 32 * DUK__BI_MAX_PARTS bits,\n *  with the caller responsible for ensuring this is never exceeded.  No memory\n *  allocation (except stack) is needed for bigint computation.  Operations\n *  have been tailored for number conversion needs.\n *\n *  Argument order is \"assignment order\", i.e. target first, then arguments:\n *  x <- y * z  -->  duk__bi_mul(x, y, z);\n */\n\n/* This upper value has been experimentally determined; debug build will check\n * bigint size with assertions.\n */\n#define DUK__BI_MAX_PARTS  37  /* 37x32 = 1184 bits */\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK__BI_PRINT(name,x)  duk__bi_print((name),(x))\n#else\n#define DUK__BI_PRINT(name,x)\n#endif\n\n/* Current size is about 152 bytes. */\ntypedef struct {\n\tduk_small_int_t n;\n\tduk_uint32_t v[DUK__BI_MAX_PARTS];  /* low to high */\n} duk__bigint;\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\nDUK_LOCAL void duk__bi_print(const char *name, duk__bigint *x) {\n\t/* Overestimate required size; debug code so not critical to be tight. */\n\tchar buf[DUK__BI_MAX_PARTS * 9 + 64];\n\tchar *p = buf;\n\tduk_small_int_t i;\n\n\t/* No NUL term checks in this debug code. */\n\tp += DUK_SPRINTF(p, \"%p n=%ld\", (void *) x, (long) x->n);\n\tif (x->n == 0) {\n\t\tp += DUK_SPRINTF(p, \" 0\");\n\t}\n\tfor (i = x->n - 1; i >= 0; i--) {\n\t\tp += DUK_SPRINTF(p, \" %08lx\", (unsigned long) x->v[i]);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"%s: %s\", (const char *) name, (const char *) buf));\n}\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_LOCAL duk_small_int_t duk__bi_is_valid(duk__bigint *x) {\n\treturn (duk_small_int_t)\n\t       ( ((x->n >= 0) && (x->n <= DUK__BI_MAX_PARTS)) /* is valid size */ &&\n\t         ((x->n == 0) || (x->v[x->n - 1] != 0)) /* is normalized */ );\n}\n#endif\n\nDUK_LOCAL void duk__bi_normalize(duk__bigint *x) {\n\tduk_small_int_t i;\n\n\tfor (i = x->n - 1; i >= 0; i--) {\n\t\tif (x->v[i] != 0) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* Note: if 'x' is zero, x->n becomes 0 here */\n\tx->n = i + 1;\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* x <- y */\nDUK_LOCAL void duk__bi_copy(duk__bigint *x, duk__bigint *y) {\n\tduk_small_int_t n;\n\n\tn = y->n;\n\tx->n = n;\n\t/* No need to special case n == 0. */\n\tduk_memcpy((void *) x->v, (const void *) y->v, (size_t) (sizeof(duk_uint32_t) * (size_t) n));\n}\n\nDUK_LOCAL void duk__bi_set_small(duk__bigint *x, duk_uint32_t v) {\n\tif (v == 0U) {\n\t\tx->n = 0;\n\t} else {\n\t\tx->n = 1;\n\t\tx->v[0] = v;\n\t}\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* Return value: <0  <=>  x < y\n *                0  <=>  x == y\n *               >0  <=>  x > y\n */\nDUK_LOCAL int duk__bi_compare(duk__bigint *x, duk__bigint *y) {\n\tduk_small_int_t i, nx, ny;\n\tduk_uint32_t tx, ty;\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\tnx = x->n;\n\tny = y->n;\n\tif (nx > ny) {\n\t\tgoto ret_gt;\n\t}\n\tif (nx < ny) {\n\t\tgoto ret_lt;\n\t}\n\tfor (i = nx - 1; i >= 0; i--) {\n\t\ttx = x->v[i];\n\t\tty = y->v[i];\n\n\t\tif (tx > ty) {\n\t\t\tgoto ret_gt;\n\t\t}\n\t\tif (tx < ty) {\n\t\t\tgoto ret_lt;\n\t\t}\n\t}\n\n\treturn 0;\n\n ret_gt:\n\treturn 1;\n\n ret_lt:\n\treturn -1;\n}\n\n/* x <- y + z */\n#if defined(DUK_USE_64BIT_OPS)\nDUK_LOCAL void duk__bi_add(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_uint64_t tmp;\n\tduk_small_int_t i, ny, nz;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\n\tif (z->n > y->n) {\n\t\tduk__bigint *t;\n\t\tt = y; y = z; z = t;\n\t}\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\ttmp = 0U;\n\tfor (i = 0; i < ny; i++) {\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\ttmp += y->v[i];\n\t\tif (i < nz) {\n\t\t\ttmp += z->v[i];\n\t\t}\n\t\tx->v[i] = (duk_uint32_t) (tmp & 0xffffffffUL);\n\t\ttmp = tmp >> 32;\n\t}\n\tif (tmp != 0U) {\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\tx->v[i++] = (duk_uint32_t) tmp;\n\t}\n\tx->n = i;\n\tDUK_ASSERT(x->n <= DUK__BI_MAX_PARTS);\n\n\t/* no need to normalize */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#else  /* DUK_USE_64BIT_OPS */\nDUK_LOCAL void duk__bi_add(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_uint32_t carry, tmp1, tmp2;\n\tduk_small_int_t i, ny, nz;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\n\tif (z->n > y->n) {\n\t\tduk__bigint *t;\n\t\tt = y; y = z; z = t;\n\t}\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\tcarry = 0U;\n\tfor (i = 0; i < ny; i++) {\n\t\t/* Carry is detected based on wrapping which relies on exact 32-bit\n\t\t * types.\n\t\t */\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\ttmp1 = y->v[i];\n\t\ttmp2 = tmp1;\n\t\tif (i < nz) {\n\t\t\ttmp2 += z->v[i];\n\t\t}\n\n\t\t/* Careful with carry condition:\n\t\t *  - If carry not added: 0x12345678 + 0 + 0xffffffff = 0x12345677 (< 0x12345678)\n\t\t *  - If carry added:     0x12345678 + 1 + 0xffffffff = 0x12345678 (== 0x12345678)\n\t\t */\n\t\tif (carry) {\n\t\t\ttmp2++;\n\t\t\tcarry = (tmp2 <= tmp1 ? 1U : 0U);\n\t\t} else {\n\t\t\tcarry = (tmp2 < tmp1 ? 1U : 0U);\n\t\t}\n\n\t\tx->v[i] = tmp2;\n\t}\n\tif (carry) {\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\tDUK_ASSERT(carry == 1U);\n\t\tx->v[i++] = carry;\n\t}\n\tx->n = i;\n\tDUK_ASSERT(x->n <= DUK__BI_MAX_PARTS);\n\n\t/* no need to normalize */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#endif  /* DUK_USE_64BIT_OPS */\n\n/* x <- y + z */\nDUK_LOCAL void duk__bi_add_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) {\n\tduk__bigint tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\t/* XXX: this could be optimized; there is only one call site now though */\n\tduk__bi_set_small(&tmp, z);\n\tduk__bi_add(x, y, &tmp);\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n#if 0  /* unused */\n/* x <- x + y, use t as temp */\nDUK_LOCAL void duk__bi_add_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) {\n\tduk__bi_add(t, x, y);\n\tduk__bi_copy(x, t);\n}\n#endif\n\n/* x <- y - z, require x >= y => z >= 0, i.e. y >= z */\n#if defined(DUK_USE_64BIT_OPS)\nDUK_LOCAL void duk__bi_sub(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_small_int_t i, ny, nz;\n\tduk_uint32_t ty, tz;\n\tduk_int64_t tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\tDUK_ASSERT(duk__bi_compare(y, z) >= 0);\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\ttmp = 0;\n\tfor (i = 0; i < ny; i++) {\n\t\tty = y->v[i];\n\t\tif (i < nz) {\n\t\t\ttz = z->v[i];\n\t\t} else {\n\t\t\ttz = 0;\n\t\t}\n\t\ttmp = (duk_int64_t) ty - (duk_int64_t) tz + tmp;\n\t\tx->v[i] = (duk_uint32_t) ((duk_uint64_t) tmp & 0xffffffffUL);\n\t\ttmp = tmp >> 32;  /* 0 or -1 */\n\t}\n\tDUK_ASSERT(tmp == 0);\n\n\tx->n = i;\n\tduk__bi_normalize(x);  /* need to normalize, may even cancel to 0 */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#else\nDUK_LOCAL void duk__bi_sub(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_small_int_t i, ny, nz;\n\tduk_uint32_t tmp1, tmp2, borrow;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\tDUK_ASSERT(duk__bi_compare(y, z) >= 0);\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\tborrow = 0U;\n\tfor (i = 0; i < ny; i++) {\n\t\t/* Borrow is detected based on wrapping which relies on exact 32-bit\n\t\t * types.\n\t\t */\n\t\ttmp1 = y->v[i];\n\t\ttmp2 = tmp1;\n\t\tif (i < nz) {\n\t\t\ttmp2 -= z->v[i];\n\t\t}\n\n\t\t/* Careful with borrow condition:\n\t\t *  - If borrow not subtracted: 0x12345678 - 0 - 0xffffffff = 0x12345679 (> 0x12345678)\n\t\t *  - If borrow subtracted:     0x12345678 - 1 - 0xffffffff = 0x12345678 (== 0x12345678)\n\t\t */\n\t\tif (borrow) {\n\t\t\ttmp2--;\n\t\t\tborrow = (tmp2 >= tmp1 ? 1U : 0U);\n\t\t} else {\n\t\t\tborrow = (tmp2 > tmp1 ? 1U : 0U);\n\t\t}\n\n\t\tx->v[i] = tmp2;\n\t}\n\tDUK_ASSERT(borrow == 0U);\n\n\tx->n = i;\n\tduk__bi_normalize(x);  /* need to normalize, may even cancel to 0 */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#endif\n\n#if 0  /* unused */\n/* x <- y - z */\nDUK_LOCAL void duk__bi_sub_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) {\n\tduk__bigint tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\t/* XXX: this could be optimized */\n\tduk__bi_set_small(&tmp, z);\n\tduk__bi_sub(x, y, &tmp);\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#endif\n\n/* x <- x - y, use t as temp */\nDUK_LOCAL void duk__bi_sub_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) {\n\tduk__bi_sub(t, x, y);\n\tduk__bi_copy(x, t);\n}\n\n/* x <- y * z */\nDUK_LOCAL void duk__bi_mul(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_small_int_t i, j, nx, nz;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\n\tnx = y->n + z->n;  /* max possible */\n\tDUK_ASSERT(nx <= DUK__BI_MAX_PARTS);\n\n\tif (nx == 0) {\n\t\t/* Both inputs are zero; cases where only one is zero can go\n\t\t * through main algorithm.\n\t\t */\n\t\tx->n = 0;\n\t\treturn;\n\t}\n\n\tduk_memzero((void *) x->v, (size_t) (sizeof(duk_uint32_t) * (size_t) nx));\n\tx->n = nx;\n\n\tnz = z->n;\n\tfor (i = 0; i < y->n; i++) {\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_uint64_t tmp = 0U;\n\t\tfor (j = 0; j < nz; j++) {\n\t\t\ttmp += (duk_uint64_t) y->v[i] * (duk_uint64_t) z->v[j] + x->v[i+j];\n\t\t\tx->v[i+j] = (duk_uint32_t) (tmp & 0xffffffffUL);\n\t\t\ttmp = tmp >> 32;\n\t\t}\n\t\tif (tmp > 0) {\n\t\t\tDUK_ASSERT(i + j < nx);\n\t\t\tDUK_ASSERT(i + j < DUK__BI_MAX_PARTS);\n\t\t\tDUK_ASSERT(x->v[i+j] == 0U);\n\t\t\tx->v[i+j] = (duk_uint32_t) tmp;\n\t\t}\n#else\n\t\t/*\n\t\t *  Multiply + add + carry for 32-bit components using only 16x16->32\n\t\t *  multiplies and carry detection based on unsigned overflow.\n\t\t *\n\t\t *    1st mult, 32-bit: (A*2^16 + B)\n\t\t *    2nd mult, 32-bit: (C*2^16 + D)\n\t\t *    3rd add, 32-bit: E\n\t\t *    4th add, 32-bit: F\n\t\t *\n\t\t *      (AC*2^16 + B) * (C*2^16 + D) + E + F\n\t\t *    = AC*2^32 + AD*2^16 + BC*2^16 + BD + E + F\n\t\t *    = AC*2^32 + (AD + BC)*2^16 + (BD + E + F)\n\t\t *    = AC*2^32 + AD*2^16 + BC*2^16 + (BD + E + F)\n\t\t */\n\t\tduk_uint32_t a, b, c, d, e, f;\n\t\tduk_uint32_t r, s, t;\n\n\t\ta = y->v[i]; b = a & 0xffffUL; a = a >> 16;\n\n\t\tf = 0;\n\t\tfor (j = 0; j < nz; j++) {\n\t\t\tc = z->v[j]; d = c & 0xffffUL; c = c >> 16;\n\t\t\te = x->v[i+j];\n\n\t\t\t/* build result as: (r << 32) + s: start with (BD + E + F) */\n\t\t\tr = 0;\n\t\t\ts = b * d;\n\n\t\t\t/* add E */\n\t\t\tt = s + e;\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add F */\n\t\t\tt = s + f;\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add BC*2^16 */\n\t\t\tt = b * c;\n\t\t\tr += (t >> 16);\n\t\t\tt = s + ((t & 0xffffUL) << 16);\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add AD*2^16 */\n\t\t\tt = a * d;\n\t\t\tr += (t >> 16);\n\t\t\tt = s + ((t & 0xffffUL) << 16);\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add AC*2^32 */\n\t\t\tt = a * c;\n\t\t\tr += t;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"ab=%08lx cd=%08lx ef=%08lx -> rs=%08lx %08lx\",\n\t\t\t                     (unsigned long) y->v[i], (unsigned long) z->v[j],\n\t\t\t                     (unsigned long) x->v[i+j], (unsigned long) r,\n\t\t\t                     (unsigned long) s));\n\n\t\t\tx->v[i+j] = s;\n\t\t\tf = r;\n\t\t}\n\t\tif (f > 0U) {\n\t\t\tDUK_ASSERT(i + j < nx);\n\t\t\tDUK_ASSERT(i + j < DUK__BI_MAX_PARTS);\n\t\t\tDUK_ASSERT(x->v[i+j] == 0U);\n\t\t\tx->v[i+j] = (duk_uint32_t) f;\n\t\t}\n#endif  /* DUK_USE_64BIT_OPS */\n\t}\n\n\tduk__bi_normalize(x);\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* x <- y * z */\nDUK_LOCAL void duk__bi_mul_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) {\n\tduk__bigint tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\t/* XXX: this could be optimized */\n\tduk__bi_set_small(&tmp, z);\n\tduk__bi_mul(x, y, &tmp);\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* x <- x * y, use t as temp */\nDUK_LOCAL void duk__bi_mul_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) {\n\tduk__bi_mul(t, x, y);\n\tduk__bi_copy(x, t);\n}\n\n/* x <- x * y, use t as temp */\nDUK_LOCAL void duk__bi_mul_small_copy(duk__bigint *x, duk_uint32_t y, duk__bigint *t) {\n\tduk__bi_mul_small(t, x, y);\n\tduk__bi_copy(x, t);\n}\n\nDUK_LOCAL int duk__bi_is_even(duk__bigint *x) {\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\treturn (x->n == 0) || ((x->v[0] & 0x01) == 0);\n}\n\nDUK_LOCAL int duk__bi_is_zero(duk__bigint *x) {\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\treturn (x->n == 0);  /* this is the case for normalized numbers */\n}\n\n/* Bigint is 2^52.  Used to detect normalized IEEE double mantissa values\n * which are at the lowest edge (next floating point value downwards has\n * a different exponent).  The lowest mantissa has the form:\n *\n *     1000........000    (52 zeroes; only \"hidden bit\" is set)\n */\nDUK_LOCAL duk_small_int_t duk__bi_is_2to52(duk__bigint *x) {\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\treturn (duk_small_int_t)\n\t        (x->n == 2) && (x->v[0] == 0U) && (x->v[1] == (1U << (52-32)));\n}\n\n/* x <- (1<<y) */\nDUK_LOCAL void duk__bi_twoexp(duk__bigint *x, duk_small_int_t y) {\n\tduk_small_int_t n, r;\n\n\tn = (y / 32) + 1;\n\tDUK_ASSERT(n > 0);\n\tr = y % 32;\n\tduk_memzero((void *) x->v, sizeof(duk_uint32_t) * (size_t) n);\n\tx->n = n;\n\tx->v[n - 1] = (((duk_uint32_t) 1) << r);\n}\n\n/* x <- b^y; use t1 and t2 as temps */\nDUK_LOCAL void duk__bi_exp_small(duk__bigint *x, duk_small_int_t b, duk_small_int_t y, duk__bigint *t1, duk__bigint *t2) {\n\t/* Fast path the binary case */\n\n\tDUK_ASSERT(x != t1 && x != t2 && t1 != t2);  /* distinct bignums, easy mistake to make */\n\tDUK_ASSERT(b >= 0);\n\tDUK_ASSERT(y >= 0);\n\n\tif (b == 2) {\n\t\tduk__bi_twoexp(x, y);\n\t\treturn;\n\t}\n\n\t/* http://en.wikipedia.org/wiki/Exponentiation_by_squaring */\n\n\tDUK_DDD(DUK_DDDPRINT(\"exp_small: b=%ld, y=%ld\", (long) b, (long) y));\n\n\tduk__bi_set_small(x, 1);\n\tduk__bi_set_small(t1, (duk_uint32_t) b);\n\tfor (;;) {\n\t\t/* Loop structure ensures that we don't compute t1^2 unnecessarily\n\t\t * on the final round, as that might create a bignum exceeding the\n\t\t * current DUK__BI_MAX_PARTS limit.\n\t\t */\n\t\tif (y & 0x01) {\n\t\t\tduk__bi_mul_copy(x, t1, t2);\n\t\t}\n\t\ty = y >> 1;\n\t\tif (y == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tduk__bi_mul_copy(t1, t1, t2);\n\t}\n\n\tDUK__BI_PRINT(\"exp_small result\", x);\n}\n\n/*\n *  A Dragon4 number-to-string variant, based on:\n *\n *    Guy L. Steele Jr., Jon L. White: \"How to Print Floating-Point Numbers\n *    Accurately\"\n *\n *    Robert G. Burger, R. Kent Dybvig: \"Printing Floating-Point Numbers\n *    Quickly and Accurately\"\n *\n *  The current algorithm is based on Figure 1 of the Burger-Dybvig paper,\n *  i.e. the base implementation without logarithm estimation speedups\n *  (these would increase code footprint considerably).  Fixed-format output\n *  does not follow the suggestions in the paper; instead, we generate an\n *  extra digit and round-with-carry.\n *\n *  The same algorithm is used for number parsing (with b=10 and B=2)\n *  by generating one extra digit and doing rounding manually.\n *\n *  See doc/number-conversion.rst for limitations.\n */\n\n/* Maximum number of digits generated. */\n#define DUK__MAX_OUTPUT_DIGITS          1040  /* (Number.MAX_VALUE).toString(2).length == 1024, + slack */\n\n/* Maximum number of characters in formatted value. */\n#define DUK__MAX_FORMATTED_LENGTH       1040  /* (-Number.MAX_VALUE).toString(2).length == 1025, + slack */\n\n/* Number and (minimum) size of bigints in the nc_ctx structure. */\n#define DUK__NUMCONV_CTX_NUM_BIGINTS    7\n#define DUK__NUMCONV_CTX_BIGINTS_SIZE   (sizeof(duk__bigint) * DUK__NUMCONV_CTX_NUM_BIGINTS)\n\ntypedef struct {\n\t/* Currently about 7*152 = 1064 bytes.  The space for these\n\t * duk__bigints is used also as a temporary buffer for generating\n\t * the final string.  This is a bit awkard; a union would be\n\t * more correct.\n\t */\n\tduk__bigint f, r, s, mp, mm, t1, t2;\n\n\tduk_small_int_t is_s2n;        /* if 1, doing a string-to-number; else doing a number-to-string */\n\tduk_small_int_t is_fixed;      /* if 1, doing a fixed format output (not free format) */\n\tduk_small_int_t req_digits;    /* requested number of output digits; 0 = free-format */\n\tduk_small_int_t abs_pos;       /* digit position is absolute, not relative */\n\tduk_small_int_t e;             /* exponent for 'f' */\n\tduk_small_int_t b;             /* input radix */\n\tduk_small_int_t B;             /* output radix */\n\tduk_small_int_t k;             /* see algorithm */\n\tduk_small_int_t low_ok;        /* see algorithm */\n\tduk_small_int_t high_ok;       /* see algorithm */\n\tduk_small_int_t unequal_gaps;  /* m+ != m- (very rarely) */\n\n\t/* Buffer used for generated digits, values are in the range [0,B-1]. */\n\tduk_uint8_t digits[DUK__MAX_OUTPUT_DIGITS];\n\tduk_small_int_t count;  /* digit count */\n} duk__numconv_stringify_ctx;\n\n/* Note: computes with 'idx' in assertions, so caller beware.\n * 'idx' is preincremented, i.e. '1' on first call, because it\n * is more convenient for the caller.\n */\n#define DUK__DRAGON4_OUTPUT_PREINC(nc_ctx,preinc_idx,x)  do { \\\n\t\tDUK_ASSERT((preinc_idx) - 1 >= 0); \\\n\t\tDUK_ASSERT((preinc_idx) - 1 < DUK__MAX_OUTPUT_DIGITS); \\\n\t\t((nc_ctx)->digits[(preinc_idx) - 1]) = (duk_uint8_t) (x); \\\n\t} while (0)\n\nDUK_LOCAL duk_size_t duk__dragon4_format_uint32(duk_uint8_t *buf, duk_uint32_t x, duk_small_int_t radix) {\n\tduk_uint8_t *p;\n\tduk_size_t len;\n\tduk_small_int_t dig;\n\tduk_uint32_t t;\n\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(radix >= 2 && radix <= 36);\n\n\t/* A 32-bit unsigned integer formats to at most 32 digits (the\n\t * worst case happens with radix == 2).  Output the digits backwards,\n\t * and use a memmove() to get them in the right place.\n\t */\n\n\tp = buf + 32;\n\tfor (;;) {\n\t\tt = x / (duk_uint32_t) radix;\n\t\tdig = (duk_small_int_t) (x - t * (duk_uint32_t) radix);\n\t\tx = t;\n\n\t\tDUK_ASSERT(dig >= 0 && dig < 36);\n\t\t*(--p) = DUK__DIGITCHAR(dig);\n\n\t\tif (x == 0) {\n\t\t\tbreak;\n\t\t}\n\t}\n\tlen = (duk_size_t) ((buf + 32) - p);\n\n\tduk_memmove((void *) buf, (const void *) p, (size_t) len);\n\n\treturn len;\n}\n\nDUK_LOCAL void duk__dragon4_prepare(duk__numconv_stringify_ctx *nc_ctx) {\n\tduk_small_int_t lowest_mantissa;\n\n#if 1\n\t/* Assume IEEE round-to-even, so that shorter encoding can be used\n\t * when round-to-even would produce correct result.  By removing\n\t * this check (and having low_ok == high_ok == 0) the results would\n\t * still be accurate but in some cases longer than necessary.\n\t */\n\tif (duk__bi_is_even(&nc_ctx->f)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"f is even\"));\n\t\tnc_ctx->low_ok = 1;\n\t\tnc_ctx->high_ok = 1;\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"f is odd\"));\n\t\tnc_ctx->low_ok = 0;\n\t\tnc_ctx->high_ok = 0;\n\t}\n#else\n\t/* Note: not honoring round-to-even should work but now generates incorrect\n\t * results.  For instance, 1e23 serializes to \"a000...\", i.e. the first digit\n\t * equals the radix (10).  Scaling stops one step too early in this case.\n\t * Don't know why this is the case, but since this code path is unused, it\n\t * doesn't matter.\n\t */\n\tnc_ctx->low_ok = 0;\n\tnc_ctx->high_ok = 0;\n#endif\n\n\t/* For string-to-number, pretend we never have the lowest mantissa as there\n\t * is no natural \"precision\" for inputs.  Having lowest_mantissa == 0, we'll\n\t * fall into the base cases for both e >= 0 and e < 0.\n\t */\n\tif (nc_ctx->is_s2n) {\n\t\tlowest_mantissa = 0;\n\t} else {\n\t\tlowest_mantissa = duk__bi_is_2to52(&nc_ctx->f);\n\t}\n\n\tnc_ctx->unequal_gaps = 0;\n\tif (nc_ctx->e >= 0) {\n\t\t/* exponent non-negative (and thus not minimum exponent) */\n\n\t\tif (lowest_mantissa) {\n\t\t\t/* (>= e 0) AND (= f (expt b (- p 1)))\n\t\t\t *\n\t\t\t * be <- (expt b e) == b^e\n\t\t\t * be1 <- (* be b) == (expt b (+ e 1)) == b^(e+1)\n\t\t\t * r <- (* f be1 2) == 2 * f * b^(e+1)    [if b==2 -> f * b^(e+2)]\n\t\t\t * s <- (* b 2)                           [if b==2 -> 4]\n\t\t\t * m+ <- be1 == b^(e+1)\n\t\t\t * m- <- be == b^e\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-negative exponent (not smallest exponent); \"\n\t\t\t                     \"lowest mantissa value for this exponent -> \"\n\t\t\t                     \"unequal gaps\"));\n\n\t\t\tduk__bi_exp_small(&nc_ctx->mm, nc_ctx->b, nc_ctx->e, &nc_ctx->t1, &nc_ctx->t2);  /* mm <- b^e */\n\t\t\tduk__bi_mul_small(&nc_ctx->mp, &nc_ctx->mm, (duk_uint32_t) nc_ctx->b);           /* mp <- b^(e+1) */\n\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, 2);\n\t\t\tduk__bi_mul(&nc_ctx->r, &nc_ctx->t1, &nc_ctx->mp);              /* r <- (2 * f) * b^(e+1) */\n\t\t\tduk__bi_set_small(&nc_ctx->s, (duk_uint32_t) (nc_ctx->b * 2));  /* s <- 2 * b */\n\t\t\tnc_ctx->unequal_gaps = 1;\n\t\t} else {\n\t\t\t/* (>= e 0) AND (not (= f (expt b (- p 1))))\n\t\t\t *\n\t\t\t * be <- (expt b e) == b^e\n\t\t\t * r <- (* f be 2) == 2 * f * b^e    [if b==2 -> f * b^(e+1)]\n\t\t\t * s <- 2\n\t\t\t * m+ <- be == b^e\n\t\t\t * m- <- be == b^e\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-negative exponent (not smallest exponent); \"\n\t\t\t                     \"not lowest mantissa for this exponent -> \"\n\t\t\t                     \"equal gaps\"));\n\n\t\t\tduk__bi_exp_small(&nc_ctx->mm, nc_ctx->b, nc_ctx->e, &nc_ctx->t1, &nc_ctx->t2);  /* mm <- b^e */\n\t\t\tduk__bi_copy(&nc_ctx->mp, &nc_ctx->mm);                /* mp <- b^e */\n\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, 2);\n\t\t\tduk__bi_mul(&nc_ctx->r, &nc_ctx->t1, &nc_ctx->mp);     /* r <- (2 * f) * b^e */\n\t\t\tduk__bi_set_small(&nc_ctx->s, 2);                      /* s <- 2 */\n\t\t}\n\t} else {\n\t\t/* When doing string-to-number, lowest_mantissa is always 0 so\n\t\t * the exponent check, while incorrect, won't matter.\n\t\t */\n\t\tif (nc_ctx->e > DUK__IEEE_DOUBLE_EXP_MIN /*not minimum exponent*/ &&\n\t\t    lowest_mantissa /* lowest mantissa for this exponent*/) {\n\t\t\t/* r <- (* f b 2)                                [if b==2 -> (* f 4)]\n\t\t\t * s <- (* (expt b (- 1 e)) 2) == b^(1-e) * 2    [if b==2 -> b^(2-e)]\n\t\t\t * m+ <- b == 2\n\t\t\t * m- <- 1\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"negative exponent; not minimum exponent and \"\n\t\t\t                     \"lowest mantissa for this exponent -> \"\n\t\t\t                     \"unequal gaps\"));\n\n\t\t\tduk__bi_mul_small(&nc_ctx->r, &nc_ctx->f, (duk_uint32_t) (nc_ctx->b * 2));  /* r <- (2 * b) * f */\n\t\t\tduk__bi_exp_small(&nc_ctx->t1, nc_ctx->b, 1 - nc_ctx->e, &nc_ctx->s, &nc_ctx->t2);  /* NB: use 's' as temp on purpose */\n\t\t\tduk__bi_mul_small(&nc_ctx->s, &nc_ctx->t1, 2);             /* s <- b^(1-e) * 2 */\n\t\t\tduk__bi_set_small(&nc_ctx->mp, 2);\n\t\t\tduk__bi_set_small(&nc_ctx->mm, 1);\n\t\t\tnc_ctx->unequal_gaps = 1;\n\t\t} else {\n\t\t\t/* r <- (* f 2)\n\t\t\t * s <- (* (expt b (- e)) 2) == b^(-e) * 2    [if b==2 -> b^(1-e)]\n\t\t\t * m+ <- 1\n\t\t\t * m- <- 1\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"negative exponent; minimum exponent or not \"\n\t\t\t                     \"lowest mantissa for this exponent -> \"\n\t\t\t                     \"equal gaps\"));\n\n\t\t\tduk__bi_mul_small(&nc_ctx->r, &nc_ctx->f, 2);            /* r <- 2 * f */\n\t\t\tduk__bi_exp_small(&nc_ctx->t1, nc_ctx->b, -nc_ctx->e, &nc_ctx->s, &nc_ctx->t2);  /* NB: use 's' as temp on purpose */\n\t\t\tduk__bi_mul_small(&nc_ctx->s, &nc_ctx->t1, 2);           /* s <- b^(-e) * 2 */\n\t\t\tduk__bi_set_small(&nc_ctx->mp, 1);\n\t\t\tduk__bi_set_small(&nc_ctx->mm, 1);\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__dragon4_scale(duk__numconv_stringify_ctx *nc_ctx) {\n\tduk_small_int_t k = 0;\n\n\t/* This is essentially the 'scale' algorithm, with recursion removed.\n\t * Note that 'k' is either correct immediately, or will move in one\n\t * direction in the loop.  There's no need to do the low/high checks\n\t * on every round (like the Scheme algorithm does).\n\t *\n\t * The scheme algorithm finds 'k' and updates 's' simultaneously,\n\t * while the logical algorithm finds 'k' with 's' having its initial\n\t * value, after which 's' is updated separately (see the Burger-Dybvig\n\t * paper, Section 3.1, steps 2 and 3).\n\t *\n\t * The case where m+ == m- (almost always) is optimized for, because\n\t * it reduces the bigint operations considerably and almost always\n\t * applies.  The scale loop only needs to work with m+, so this works.\n\t */\n\n\t/* XXX: this algorithm could be optimized quite a lot by using e.g.\n\t * a logarithm based estimator for 'k' and performing B^n multiplication\n\t * using a lookup table or using some bit-representation based exp\n\t * algorithm.  Currently we just loop, with significant performance\n\t * impact for very large and very small numbers.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"scale: B=%ld, low_ok=%ld, high_ok=%ld\",\n\t                     (long) nc_ctx->B, (long) nc_ctx->low_ok, (long) nc_ctx->high_ok));\n\tDUK__BI_PRINT(\"r(init)\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s(init)\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp(init)\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm(init)\", &nc_ctx->mm);\n\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"scale loop (inc k), k=%ld\", (long) k));\n\t\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\t\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\t\tDUK__BI_PRINT(\"m+\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"m-\", &nc_ctx->mm);\n\n\t\tduk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp);  /* t1 = (+ r m+) */\n\t\tif (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) >= (nc_ctx->high_ok ? 0 : 1)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"k is too low\"));\n\t\t\t/* r <- r\n\t\t\t * s <- (* s B)\n\t\t\t * m+ <- m+\n\t\t\t * m- <- m-\n\t\t\t * k <- (+ k 1)\n\t\t\t */\n\n\t\t\tduk__bi_mul_small_copy(&nc_ctx->s, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\tk++;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* k > 0 -> k was too low, and cannot be too high */\n\tif (k > 0) {\n\t\tgoto skip_dec_k;\n\t}\n\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"scale loop (dec k), k=%ld\", (long) k));\n\t\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\t\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\t\tDUK__BI_PRINT(\"m+\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"m-\", &nc_ctx->mm);\n\n\t\tduk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp);  /* t1 = (+ r m+) */\n\t\tduk__bi_mul_small(&nc_ctx->t2, &nc_ctx->t1, (duk_uint32_t) nc_ctx->B);   /* t2 = (* (+ r m+) B) */\n\t\tif (duk__bi_compare(&nc_ctx->t2, &nc_ctx->s) <= (nc_ctx->high_ok ? -1 : 0)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"k is too high\"));\n\t\t\t/* r <- (* r B)\n\t\t\t * s <- s\n\t\t\t * m+ <- (* m+ B)\n\t\t\t * m- <- (* m- B)\n\t\t\t * k <- (- k 1)\n\t\t\t */\n\t\t\tduk__bi_mul_small_copy(&nc_ctx->r, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\tduk__bi_mul_small_copy(&nc_ctx->mp, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\tif (nc_ctx->unequal_gaps) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"m+ != m- -> need to update m- too\"));\n\t\t\t\tduk__bi_mul_small_copy(&nc_ctx->mm, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\t}\n\t\t\tk--;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n skip_dec_k:\n\n\tif (!nc_ctx->unequal_gaps) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"equal gaps, copy m- from m+\"));\n\t\tduk__bi_copy(&nc_ctx->mm, &nc_ctx->mp);  /* mm <- mp */\n\t}\n\tnc_ctx->k = k;\n\n\tDUK_DDD(DUK_DDDPRINT(\"final k: %ld\", (long) k));\n\tDUK__BI_PRINT(\"r(final)\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s(final)\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp(final)\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm(final)\", &nc_ctx->mm);\n}\n\nDUK_LOCAL void duk__dragon4_generate(duk__numconv_stringify_ctx *nc_ctx) {\n\tduk_small_int_t tc1, tc2;    /* terminating conditions */\n\tduk_small_int_t d;           /* current digit */\n\tduk_small_int_t count = 0;   /* digit count */\n\n\t/*\n\t *  Digit generation loop.\n\t *\n\t *  Different termination conditions:\n\t *\n\t *    1. Free format output.  Terminate when shortest accurate\n\t *       representation found.\n\t *\n\t *    2. Fixed format output, with specific number of digits.\n\t *       Ignore termination conditions, terminate when digits\n\t *       generated.  Caller requests an extra digit and rounds.\n\t *\n\t *    3. Fixed format output, with a specific absolute cut-off\n\t *       position (e.g. 10 digits after decimal point).  Note\n\t *       that we always generate at least one digit, even if\n\t *       the digit is below the cut-off point already.\n\t */\n\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"generate loop, count=%ld, k=%ld, B=%ld, low_ok=%ld, high_ok=%ld\",\n\t\t                     (long) count, (long) nc_ctx->k, (long) nc_ctx->B,\n\t\t                     (long) nc_ctx->low_ok, (long) nc_ctx->high_ok));\n\t\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\t\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\t\tDUK__BI_PRINT(\"m+\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"m-\", &nc_ctx->mm);\n\n\t\t/* (quotient-remainder (* r B) s) using a dummy subtraction loop */\n\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->r, (duk_uint32_t) nc_ctx->B);       /* t1 <- (* r B) */\n\t\td = 0;\n\t\tfor (;;) {\n\t\t\tif (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) < 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tduk__bi_sub_copy(&nc_ctx->t1, &nc_ctx->s, &nc_ctx->t2);  /* t1 <- t1 - s */\n\t\t\td++;\n\t\t}\n\t\tduk__bi_copy(&nc_ctx->r, &nc_ctx->t1);  /* r <- (remainder (* r B) s) */\n\t\t                                        /* d <- (quotient (* r B) s)   (in range 0...B-1) */\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> d(quot)=%ld\", (long) d));\n\t\tDUK__BI_PRINT(\"r(rem)\", &nc_ctx->r);\n\n\t\tduk__bi_mul_small_copy(&nc_ctx->mp, (duk_uint32_t) nc_ctx->B, &nc_ctx->t2); /* m+ <- (* m+ B) */\n\t\tduk__bi_mul_small_copy(&nc_ctx->mm, (duk_uint32_t) nc_ctx->B, &nc_ctx->t2); /* m- <- (* m- B) */\n\t\tDUK__BI_PRINT(\"mp(upd)\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"mm(upd)\", &nc_ctx->mm);\n\n\t\t/* Terminating conditions.  For fixed width output, we just ignore the\n\t\t * terminating conditions (and pretend that tc1 == tc2 == false).  The\n\t\t * the current shortcut for fixed-format output is to generate a few\n\t\t * extra digits and use rounding (with carry) to finish the output.\n\t\t */\n\n\t\tif (nc_ctx->is_fixed == 0) {\n\t\t\t/* free-form */\n\t\t\ttc1 = (duk__bi_compare(&nc_ctx->r, &nc_ctx->mm) <= (nc_ctx->low_ok ? 0 : -1));\n\n\t\t\tduk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp);  /* t1 <- (+ r m+) */\n\t\t\ttc2 = (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) >= (nc_ctx->high_ok ? 0 : 1));\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=%ld, tc2=%ld\", (long) tc1, (long) tc2));\n\t\t} else {\n\t\t\t/* fixed-format */\n\t\t\ttc1 = 0;\n\t\t\ttc2 = 0;\n\t\t}\n\n\t\t/* Count is incremented before DUK__DRAGON4_OUTPUT_PREINC() call\n\t\t * on purpose, which is taken into account by the macro.\n\t\t */\n\t\tcount++;\n\n\t\tif (tc1) {\n\t\t\tif (tc2) {\n\t\t\t\t/* tc1 = true, tc2 = true */\n\t\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->r, 2);\n\t\t\t\tif (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) < 0) {  /* (< (* r 2) s) */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=true, tc2=true, 2r > s: output d --> %ld (k=%ld)\",\n\t\t\t\t\t                     (long) d, (long) nc_ctx->k));\n\t\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=true, tc2=true, 2r <= s: output d+1 --> %ld (k=%ld)\",\n\t\t\t\t\t                     (long) (d + 1), (long) nc_ctx->k));\n\t\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d + 1);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t/* tc1 = true, tc2 = false */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=true, tc2=false: output d --> %ld (k=%ld)\",\n\t\t\t\t                     (long) d, (long) nc_ctx->k));\n\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (tc2) {\n\t\t\t\t/* tc1 = false, tc2 = true */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=false, tc2=true: output d+1 --> %ld (k=%ld)\",\n\t\t\t\t                     (long) (d + 1), (long) nc_ctx->k));\n\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d + 1);\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t/* tc1 = false, tc2 = false */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=false, tc2=false: output d --> %ld (k=%ld)\",\n\t\t\t\t                     (long) d, (long) nc_ctx->k));\n\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d);\n\n\t\t\t\t/* r <- r    (updated above: r <- (remainder (* r B) s)\n\t\t\t\t * s <- s\n\t\t\t\t * m+ <- m+  (updated above: m+ <- (* m+ B)\n\t\t\t\t * m- <- m-  (updated above: m- <- (* m- B)\n\t\t\t\t * B, low_ok, high_ok are fixed\n\t\t\t\t */\n\n\t\t\t\t/* fall through and continue for-loop */\n\t\t\t}\n\t\t}\n\n\t\t/* fixed-format termination conditions */\n\t\tif (nc_ctx->is_fixed) {\n\t\t\tif (nc_ctx->abs_pos) {\n\t\t\t\tint pos = nc_ctx->k - count + 1;  /* count is already incremented, take into account */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fixed format, absolute: abs pos=%ld, k=%ld, count=%ld, req=%ld\",\n\t\t\t\t                     (long) pos, (long) nc_ctx->k, (long) count, (long) nc_ctx->req_digits));\n\t\t\t\tif (pos <= nc_ctx->req_digits) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"digit position reached req_digits, end generate loop\"));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fixed format, relative: k=%ld, count=%ld, req=%ld\",\n\t\t\t\t                     (long) nc_ctx->k, (long) count, (long) nc_ctx->req_digits));\n\t\t\t\tif (count >= nc_ctx->req_digits) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"digit count reached req_digits, end generate loop\"));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}  /* for */\n\n\tnc_ctx->count = count;\n\n\tDUK_DDD(DUK_DDDPRINT(\"generate finished\"));\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t{\n\t\tduk_uint8_t buf[2048];\n\t\tduk_small_int_t i, t;\n\t\tduk_memzero(buf, sizeof(buf));\n\t\tfor (i = 0; i < nc_ctx->count; i++) {\n\t\t\tt = nc_ctx->digits[i];\n\t\t\tif (t < 0 || t > 36) {\n\t\t\t\tbuf[i] = (duk_uint8_t) '?';\n\t\t\t} else {\n\t\t\t\tbuf[i] = (duk_uint8_t) DUK__DIGITCHAR(t);\n\t\t\t}\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> generated digits; k=%ld, digits='%s'\",\n\t\t                     (long) nc_ctx->k, (const char *) buf));\n\t}\n#endif\n}\n\n/* Round up digits to a given position.  If position is out-of-bounds,\n * does nothing.  If carry propagates over the first digit, a '1' is\n * prepended to digits and 'k' will be updated.  Return value indicates\n * whether carry propagated over the first digit.\n *\n * Note that nc_ctx->count is NOT updated based on the rounding position\n * (it is updated only if carry overflows over the first digit and an\n * extra digit is prepended).\n */\nDUK_LOCAL duk_small_int_t duk__dragon4_fixed_format_round(duk__numconv_stringify_ctx *nc_ctx, duk_small_int_t round_idx) {\n\tduk_small_int_t t;\n\tduk_uint8_t *p;\n\tduk_uint8_t roundup_limit;\n\tduk_small_int_t ret = 0;\n\n\t/*\n\t *  round_idx points to the digit which is considered for rounding; the\n\t *  digit to its left is the final digit of the rounded value.  If round_idx\n\t *  is zero, rounding will be performed; the result will either be an empty\n\t *  rounded value or if carry happens a '1' digit is generated.\n\t */\n\n\tif (round_idx >= nc_ctx->count) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"round_idx out of bounds (%ld >= %ld (count)) -> no rounding\",\n\t\t                     (long) round_idx, (long) nc_ctx->count));\n\t\treturn 0;\n\t} else if (round_idx < 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"round_idx out of bounds (%ld < 0) -> no rounding\",\n\t\t                     (long) round_idx));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  Round-up limit.\n\t *\n\t *  For even values, divides evenly, e.g. 10 -> roundup_limit=5.\n\t *\n\t *  For odd values, rounds up, e.g. 3 -> roundup_limit=2.\n\t *  If radix is 3, 0/3 -> down, 1/3 -> down, 2/3 -> up.\n\t */\n\troundup_limit = (duk_uint8_t) ((nc_ctx->B + 1) / 2);\n\n\tp = &nc_ctx->digits[round_idx];\n\tif (*p >= roundup_limit) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"fixed-format rounding carry required\"));\n\t\t/* carry */\n\t\tfor (;;) {\n\t\t\t*p = 0;\n\t\t\tif (p == &nc_ctx->digits[0]) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"carry propagated to first digit -> special case handling\"));\n\t\t\t\tduk_memmove((void *) (&nc_ctx->digits[1]),\n\t\t\t\t            (const void *) (&nc_ctx->digits[0]),\n\t\t\t\t            (size_t) (sizeof(char) * (size_t) nc_ctx->count));\n\t\t\t\tnc_ctx->digits[0] = 1;  /* don't increase 'count' */\n\t\t\t\tnc_ctx->k++;  /* position of highest digit changed */\n\t\t\t\tnc_ctx->count++;  /* number of digits changed */\n\t\t\t\tret = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fixed-format rounding carry: B=%ld, roundup_limit=%ld, p=%p, digits=%p\",\n\t\t\t                     (long) nc_ctx->B, (long) roundup_limit, (void *) p, (void *) nc_ctx->digits));\n\t\t\tp--;\n\t\t\tt = *p;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"digit before carry: %ld\", (long) t));\n\t\t\tif (++t < nc_ctx->B) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rounding carry terminated\"));\n\t\t\t\t*p = (duk_uint8_t) t;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"wraps, carry to next digit\"));\n\t\t}\n\t}\n\n\treturn ret;\n}\n\n#define DUK__NO_EXP  (65536)  /* arbitrary marker, outside valid exp range */\n\nDUK_LOCAL void duk__dragon4_convert_and_push(duk__numconv_stringify_ctx *nc_ctx,\n                                             duk_hthread *thr,\n                                             duk_small_int_t radix,\n                                             duk_small_int_t digits,\n                                             duk_small_uint_t flags,\n                                             duk_small_int_t neg) {\n\tduk_small_int_t k;\n\tduk_small_int_t pos, pos_end;\n\tduk_small_int_t expt;\n\tduk_small_int_t dig;\n\tduk_uint8_t *q;\n\tduk_uint8_t *buf;\n\n\t/*\n\t *  The string conversion here incorporates all the necessary ECMAScript\n\t *  semantics without attempting to be generic.  nc_ctx->digits contains\n\t *  nc_ctx->count digits (>= 1), with the topmost digit's 'position'\n\t *  indicated by nc_ctx->k as follows:\n\t *\n\t *    digits=\"123\" count=3 k=0   -->   0.123\n\t *    digits=\"123\" count=3 k=1   -->   1.23\n\t *    digits=\"123\" count=3 k=5   -->   12300\n\t *    digits=\"123\" count=3 k=-1  -->   0.0123\n\t *\n\t *  Note that the identifier names used for format selection are different\n\t *  in Burger-Dybvig paper and ECMAScript specification (quite confusingly\n\t *  so, because e.g. 'k' has a totally different meaning in each).  See\n\t *  documentation for discussion.\n\t *\n\t *  ECMAScript doesn't specify any specific behavior for format selection\n\t *  (e.g. when to use exponent notation) for non-base-10 numbers.\n\t *\n\t *  The bigint space in the context is reused for string output, as there\n\t *  is more than enough space for that (>1kB at the moment), and we avoid\n\t *  allocating even more stack.\n\t */\n\n\tDUK_ASSERT(DUK__NUMCONV_CTX_BIGINTS_SIZE >= DUK__MAX_FORMATTED_LENGTH);\n\tDUK_ASSERT(nc_ctx->count >= 1);\n\n\tk = nc_ctx->k;\n\tbuf = (duk_uint8_t *) &nc_ctx->f;  /* XXX: union would be more correct */\n\tq = buf;\n\n\t/* Exponent handling: if exponent format is used, record exponent value and\n\t * fake k such that one leading digit is generated (e.g. digits=123 -> \"1.23\").\n\t *\n\t * toFixed() prevents exponent use; otherwise apply a set of criteria to\n\t * match the other API calls (toString(), toPrecision, etc).\n\t */\n\n\texpt = DUK__NO_EXP;\n\tif (!nc_ctx->abs_pos /* toFixed() */) {\n\t\tif ((flags & DUK_N2S_FLAG_FORCE_EXP) ||             /* exponential notation forced */\n\t\t    ((flags & DUK_N2S_FLAG_NO_ZERO_PAD) &&          /* fixed precision and zero padding would be required */\n\t             (k - digits >= 1)) ||                          /* (e.g. k=3, digits=2 -> \"12X\") */\n\t\t    ((k > 21 || k <= -6) && (radix == 10))) {       /* toString() conditions */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"use exponential notation: k=%ld -> expt=%ld\",\n\t\t\t                     (long) k, (long) (k - 1)));\n\t\t\texpt = k - 1;  /* e.g. 12.3 -> digits=\"123\" k=2 -> 1.23e1 */\n\t\t\tk = 1;  /* generate mantissa with a single leading whole number digit */\n\t\t}\n\t}\n\n\tif (neg) {\n\t\t*q++ = '-';\n\t}\n\n\t/* Start position (inclusive) and end position (exclusive) */\n\tpos = (k >= 1 ? k : 1);\n\tif (nc_ctx->is_fixed) {\n\t\tif (nc_ctx->abs_pos) {\n\t\t\t/* toFixed() */\n\t\t\tpos_end = -digits;\n\t\t} else {\n\t\t\tpos_end = k - digits;\n\t\t}\n\t} else {\n\t\tpos_end = k - nc_ctx->count;\n\t}\n\tif (pos_end > 0) {\n\t\tpos_end = 0;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"expt=%ld, k=%ld, count=%ld, pos=%ld, pos_end=%ld, is_fixed=%ld, \"\n\t                     \"digits=%ld, abs_pos=%ld\",\n\t                     (long) expt, (long) k, (long) nc_ctx->count, (long) pos, (long) pos_end,\n\t                     (long) nc_ctx->is_fixed, (long) digits, (long) nc_ctx->abs_pos));\n\n\t/* Digit generation */\n\twhile (pos > pos_end) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"digit generation: pos=%ld, pos_end=%ld\",\n\t\t                     (long) pos, (long) pos_end));\n\t\tif (pos == 0) {\n\t\t\t*q++ = (duk_uint8_t) '.';\n\t\t}\n\t\tif (pos > k) {\n\t\t\t*q++ = (duk_uint8_t) '0';\n\t\t} else if (pos <= k - nc_ctx->count) {\n\t\t\t*q++ = (duk_uint8_t) '0';\n\t\t} else {\n\t\t\tdig = nc_ctx->digits[k - pos];\n\t\t\tDUK_ASSERT(dig >= 0 && dig < nc_ctx->B);\n\t\t\t*q++ = (duk_uint8_t) DUK__DIGITCHAR(dig);\n\t\t}\n\n\t\tpos--;\n\t}\n\tDUK_ASSERT(pos <= 1);\n\n\t/* Exponent */\n\tif (expt != DUK__NO_EXP) {\n\t\t/*\n\t\t *  Exponent notation for non-base-10 numbers isn't specified in ECMAScript\n\t\t *  specification, as it never explicitly turns up: non-decimal numbers can\n\t\t *  only be formatted with Number.prototype.toString([radix]) and for that,\n\t\t *  behavior is not explicitly specified.\n\t\t *\n\t\t *  Logical choices include formatting the exponent as decimal (e.g. binary\n\t\t *  100000 as 1e+5) or in current radix (e.g. binary 100000 as 1e+101).\n\t\t *  The Dragon4 algorithm (in the original paper) prints the exponent value\n\t\t *  in the target radix B.  However, for radix values 15 and above, the\n\t\t *  exponent separator 'e' is no longer easily parseable.  Consider, for\n\t\t *  instance, the number \"1.faecee+1c\".\n\t\t */\n\n\t\tduk_size_t len;\n\t\tchar expt_sign;\n\n\t\t*q++ = 'e';\n\t\tif (expt >= 0) {\n\t\t\texpt_sign = '+';\n\t\t} else {\n\t\t\texpt_sign = '-';\n\t\t\texpt = -expt;\n\t\t}\n\t\t*q++ = (duk_uint8_t) expt_sign;\n\t\tlen = duk__dragon4_format_uint32(q, (duk_uint32_t) expt, radix);\n\t\tq += len;\n\t}\n\n\tduk_push_lstring(thr, (const char *) buf, (size_t) (q - buf));\n}\n\n/*\n *  Conversion helpers\n */\n\nDUK_LOCAL void duk__dragon4_double_to_ctx(duk__numconv_stringify_ctx *nc_ctx, duk_double_t x) {\n\tduk_double_union u;\n\tduk_uint32_t tmp;\n\tduk_small_int_t expt;\n\n\t/*\n\t *    seeeeeee eeeeffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n\t *       A        B        C        D        E        F        G        H\n\t *\n\t *    s       sign bit\n\t *    eee...  exponent field\n\t *    fff...  fraction\n\t *\n\t *    ieee value = 1.ffff... * 2^(e - 1023)  (normal)\n\t *               = 0.ffff... * 2^(-1022)     (denormal)\n\t *\n\t *    algorithm v = f * b^e\n\t */\n\n\tDUK_DBLUNION_SET_DOUBLE(&u, x);\n\n\tnc_ctx->f.n = 2;\n\n\ttmp = DUK_DBLUNION_GET_LOW32(&u);\n\tnc_ctx->f.v[0] = tmp;\n\ttmp = DUK_DBLUNION_GET_HIGH32(&u);\n\tnc_ctx->f.v[1] = tmp & 0x000fffffUL;\n\texpt = (duk_small_int_t) ((tmp >> 20) & 0x07ffUL);\n\n\tif (expt == 0) {\n\t\t/* denormal */\n\t\texpt = DUK__IEEE_DOUBLE_EXP_MIN - 52;\n\t\tduk__bi_normalize(&nc_ctx->f);\n\t} else {\n\t\t/* normal: implicit leading 1-bit */\n\t\tnc_ctx->f.v[1] |= 0x00100000UL;\n\t\texpt = expt - DUK__IEEE_DOUBLE_EXP_BIAS - 52;\n\t\tDUK_ASSERT(duk__bi_is_valid(&nc_ctx->f));  /* true, because v[1] has at least one bit set */\n\t}\n\n\tDUK_ASSERT(duk__bi_is_valid(&nc_ctx->f));\n\n\tnc_ctx->e = expt;\n}\n\nDUK_LOCAL void duk__dragon4_ctx_to_double(duk__numconv_stringify_ctx *nc_ctx, duk_double_t *x) {\n\tduk_double_union u;\n\tduk_small_int_t expt;\n\tduk_small_int_t i;\n\tduk_small_int_t bitstart;\n\tduk_small_int_t bitround;\n\tduk_small_int_t bitidx;\n\tduk_small_int_t skip_round;\n\tduk_uint32_t t, v;\n\n\tDUK_ASSERT(nc_ctx->count == 53 + 1);\n\n\t/* Sometimes this assert is not true right now; it will be true after\n\t * rounding.  See: test-bug-numconv-mantissa-assert.js.\n\t */\n\tDUK_ASSERT_DISABLE(nc_ctx->digits[0] == 1);  /* zero handled by caller */\n\n\t/* Should not be required because the code below always sets both high\n\t * and low parts, but at least gcc-4.4.5 fails to deduce this correctly\n\t * (perhaps because the low part is set (seemingly) conditionally in a\n\t * loop), so this is here to avoid the bogus warning.\n\t */\n\tduk_memzero((void *) &u, sizeof(u));\n\n\t/*\n\t *  Figure out how generated digits match up with the mantissa,\n\t *  and then perform rounding.  If mantissa overflows, need to\n\t *  recompute the exponent (it is bumped and may overflow to\n\t *  infinity).\n\t *\n\t *  For normal numbers the leading '1' is hidden and ignored,\n\t *  and the last bit is used for rounding:\n\t *\n\t *                          rounding pt\n\t *       <--------52------->|\n\t *     1 x x x x ... x x x x|y  ==>  x x x x ... x x x x\n\t *\n\t *  For denormals, the leading '1' is included in the number,\n\t *  and the rounding point is different:\n\t *\n\t *                      rounding pt\n\t *     <--52 or less--->|\n\t *     1 x x x x ... x x|x x y  ==>  0 0 ... 1 x x ... x x\n\t *\n\t *  The largest denormals will have a mantissa beginning with\n\t *  a '1' (the explicit leading bit); smaller denormals will\n\t *  have leading zero bits.\n\t *\n\t *  If the exponent would become too high, the result becomes\n\t *  Infinity.  If the exponent is so small that the entire\n\t *  mantissa becomes zero, the result becomes zero.\n\t *\n\t *  Note: the Dragon4 'k' is off-by-one with respect to the IEEE\n\t *  exponent.  For instance, k==0 indicates that the leading '1'\n\t *  digit is at the first binary fraction position (0.1xxx...);\n\t *  the corresponding IEEE exponent would be -1.\n\t */\n\n\tskip_round = 0;\n\n recheck_exp:\n\n\texpt = nc_ctx->k - 1;   /* IEEE exp without bias */\n\tif (expt > 1023) {\n\t\t/* Infinity */\n\t\tbitstart = -255;  /* needed for inf: causes mantissa to become zero,\n\t\t                   * and rounding to be skipped.\n\t\t                   */\n\t\texpt = 2047;\n\t} else if (expt >= -1022) {\n\t\t/* normal */\n\t\tbitstart = 1;  /* skip leading digit */\n\t\texpt += DUK__IEEE_DOUBLE_EXP_BIAS;\n\t\tDUK_ASSERT(expt >= 1 && expt <= 2046);\n\t} else {\n\t\t/* denormal or zero */\n\t\tbitstart = 1023 + expt;  /* expt==-1023 -> bitstart=0 (leading 1);\n\t\t                          * expt==-1024 -> bitstart=-1 (one left of leading 1), etc\n\t\t                          */\n\t\texpt = 0;\n\t}\n\tbitround = bitstart + 52;\n\n\tDUK_DDD(DUK_DDDPRINT(\"ieee expt=%ld, bitstart=%ld, bitround=%ld\",\n\t                     (long) expt, (long) bitstart, (long) bitround));\n\n\tif (!skip_round) {\n\t\tif (duk__dragon4_fixed_format_round(nc_ctx, bitround)) {\n\t\t\t/* Corner case: see test-numconv-parse-mant-carry.js.  We could\n\t\t\t * just bump the exponent and update bitstart, but it's more robust\n\t\t\t * to recompute (but avoid rounding twice).\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"rounding caused exponent to be bumped, recheck exponent\"));\n\t\t\tskip_round = 1;\n\t\t\tgoto recheck_exp;\n\t\t}\n\t}\n\n\t/*\n\t *  Create mantissa\n\t */\n\n\tt = 0;\n\tfor (i = 0; i < 52; i++) {\n\t\tbitidx = bitstart + 52 - 1 - i;\n\t\tif (bitidx >= nc_ctx->count) {\n\t\t\tv = 0;\n\t\t} else if (bitidx < 0) {\n\t\t\tv = 0;\n\t\t} else {\n\t\t\tv = nc_ctx->digits[bitidx];\n\t\t}\n\t\tDUK_ASSERT(v == 0 || v == 1);\n\t\tt += v << (i % 32);\n\t\tif (i == 31) {\n\t\t\t/* low 32 bits is complete */\n\t\t\tDUK_DBLUNION_SET_LOW32(&u, t);\n\t\t\tt = 0;\n\t\t}\n\t}\n\t/* t has high mantissa */\n\n\tDUK_DDD(DUK_DDDPRINT(\"mantissa is complete: %08lx %08lx\",\n\t                     (unsigned long) t,\n\t                     (unsigned long) DUK_DBLUNION_GET_LOW32(&u)));\n\n\tDUK_ASSERT(expt >= 0 && expt <= 0x7ffL);\n\tt += ((duk_uint32_t) expt) << 20;\n#if 0  /* caller handles sign change */\n\tif (negative) {\n\t\tt |= 0x80000000U;\n\t}\n#endif\n\tDUK_DBLUNION_SET_HIGH32(&u, t);\n\n\tDUK_DDD(DUK_DDDPRINT(\"number is complete: %08lx %08lx\",\n\t                     (unsigned long) DUK_DBLUNION_GET_HIGH32(&u),\n\t                     (unsigned long) DUK_DBLUNION_GET_LOW32(&u)));\n\n\t*x = DUK_DBLUNION_GET_DOUBLE(&u);\n}\n\n/*\n *  Exposed number-to-string API\n *\n *  Input: [ number ]\n *  Output: [ string ]\n */\n\nDUK_LOCAL DUK_NOINLINE void duk__numconv_stringify_raw(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) {\n\tduk_double_t x;\n\tduk_small_int_t c;\n\tduk_small_int_t neg;\n\tduk_uint32_t uval;\n\tduk__numconv_stringify_ctx nc_ctx_alloc;  /* large context; around 2kB now */\n\tduk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;\n\n\tx = (duk_double_t) duk_require_number(thr, -1);\n\tduk_pop(thr);\n\n\t/*\n\t *  Handle special cases (NaN, infinity, zero).\n\t */\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (DUK_SIGNBIT((double) x)) {\n\t\tx = -x;\n\t\tneg = 1;\n\t} else {\n\t\tneg = 0;\n\t}\n\n\t/* NaN sign bit is platform specific with unpacked, un-normalized NaNs */\n\tDUK_ASSERT(c == DUK_FP_NAN || DUK_SIGNBIT((double) x) == 0);\n\n\tif (c == DUK_FP_NAN) {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_NAN);\n\t\treturn;\n\t} else if (c == DUK_FP_INFINITE) {\n\t\tif (neg) {\n\t\t\t/* -Infinity */\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_MINUS_INFINITY);\n\t\t} else {\n\t\t\t/* Infinity */\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_INFINITY);\n\t\t}\n\t\treturn;\n\t} else if (c == DUK_FP_ZERO) {\n\t\t/* We can't shortcut zero here if it goes through special formatting\n\t\t * (such as forced exponential notation).\n\t\t */\n\t\t;\n\t}\n\n\t/*\n\t *  Handle integers in 32-bit range (that is, [-(2**32-1),2**32-1])\n\t *  specially, as they're very likely for embedded programs.  This\n\t *  is now done for all radix values.  We must be careful not to use\n\t *  the fast path when special formatting (e.g. forced exponential)\n\t *  is in force.\n\t *\n\t *  XXX: could save space by supporting radix 10 only and using\n\t *  sprintf \"%lu\" for the fast path and for exponent formatting.\n\t */\n\n\tuval = duk_double_to_uint32_t(x);\n\tif (((double) uval) == x &&  /* integer number in range */\n\t    flags == 0) {            /* no special formatting */\n\t\t/* use bigint area as a temp */\n\t\tduk_uint8_t *buf = (duk_uint8_t *) (&nc_ctx->f);\n\t\tduk_uint8_t *p = buf;\n\n\t\tDUK_ASSERT(DUK__NUMCONV_CTX_BIGINTS_SIZE >= 32 + 1);  /* max size: radix=2 + sign */\n\t\tif (neg && uval != 0) {\n\t\t\t/* no negative sign for zero */\n\t\t\t*p++ = (duk_uint8_t) '-';\n\t\t}\n\t\tp += duk__dragon4_format_uint32(p, uval, radix);\n\t\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) (p - buf));\n\t\treturn;\n\t}\n\n\t/*\n\t *  Dragon4 setup.\n\t *\n\t *  Convert double from IEEE representation for conversion;\n\t *  normal finite values have an implicit leading 1-bit.  The\n\t *  slow path algorithm doesn't handle zero, so zero is special\n\t *  cased here but still creates a valid nc_ctx, and goes\n\t *  through normal formatting in case special formatting has\n\t *  been requested (e.g. forced exponential format: 0 -> \"0e+0\").\n\t */\n\n\t/* Would be nice to bulk clear the allocation, but the context\n\t * is 1-2 kilobytes and nothing should rely on it being zeroed.\n\t */\n#if 0\n\tduk_memzero((void *) nc_ctx, sizeof(*nc_ctx));  /* slow init, do only for slow path cases */\n#endif\n\n\tnc_ctx->is_s2n = 0;\n\tnc_ctx->b = 2;\n\tnc_ctx->B = radix;\n\tnc_ctx->abs_pos = 0;\n\tif (flags & DUK_N2S_FLAG_FIXED_FORMAT) {\n\t\tnc_ctx->is_fixed = 1;\n\t\tif (flags & DUK_N2S_FLAG_FRACTION_DIGITS) {\n\t\t\t/* absolute req_digits; e.g. digits = 1 -> last digit is 0,\n\t\t\t * but add an extra digit for rounding.\n\t\t\t */\n\t\t\tnc_ctx->abs_pos = 1;\n\t\t\tnc_ctx->req_digits = (-digits + 1) - 1;\n\t\t} else {\n\t\t\tnc_ctx->req_digits = digits + 1;\n\t\t}\n\t} else {\n\t\tnc_ctx->is_fixed = 0;\n\t\tnc_ctx->req_digits = 0;\n\t}\n\n\tif (c == DUK_FP_ZERO) {\n\t\t/* Zero special case: fake requested number of zero digits; ensure\n\t\t * no sign bit is printed.  Relative and absolute fixed format\n\t\t * require separate handling.\n\t\t */\n\t\tduk_small_int_t count;\n\t\tif (nc_ctx->is_fixed) {\n\t\t\tif (nc_ctx->abs_pos) {\n\t\t\t\tcount = digits + 2;  /* lead zero + 'digits' fractions + 1 for rounding */\n\t\t\t} else {\n\t\t\t\tcount = digits + 1;  /* + 1 for rounding */\n\t\t\t}\n\t\t} else {\n\t\t\tcount = 1;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"count=%ld\", (long) count));\n\t\tDUK_ASSERT(count >= 1);\n\t\tduk_memzero((void *) nc_ctx->digits, (size_t) count);\n\t\tnc_ctx->count = count;\n\t\tnc_ctx->k = 1;  /* 0.000... */\n\t\tneg = 0;\n\t\tgoto zero_skip;\n\t}\n\n\tduk__dragon4_double_to_ctx(nc_ctx, x);   /* -> sets 'f' and 'e' */\n\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\tDUK_DDD(DUK_DDDPRINT(\"e=%ld\", (long) nc_ctx->e));\n\n\t/*\n\t *  Dragon4 slow path digit generation.\n\t */\n\n\tduk__dragon4_prepare(nc_ctx);  /* setup many variables in nc_ctx */\n\n\tDUK_DDD(DUK_DDDPRINT(\"after prepare:\"));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_scale(nc_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"after scale; k=%ld\", (long) nc_ctx->k));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_generate(nc_ctx);\n\n\t/*\n\t *  Convert and push final string.\n\t */\n\n zero_skip:\n\n\tif (flags & DUK_N2S_FLAG_FIXED_FORMAT) {\n\t\t/* Perform fixed-format rounding. */\n\t\tduk_small_int_t roundpos;\n\t\tif (flags & DUK_N2S_FLAG_FRACTION_DIGITS) {\n\t\t\t/* 'roundpos' is relative to nc_ctx->k and increases to the right\n\t\t\t * (opposite of how 'k' changes).\n\t\t\t */\n\t\t\troundpos = -digits;  /* absolute position for digit considered for rounding */\n\t\t\troundpos = nc_ctx->k - roundpos;\n\t\t} else {\n\t\t\troundpos = digits;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"rounding: k=%ld, count=%ld, digits=%ld, roundpos=%ld\",\n\t\t                     (long) nc_ctx->k, (long) nc_ctx->count, (long) digits, (long) roundpos));\n\t\t(void) duk__dragon4_fixed_format_round(nc_ctx, roundpos);\n\n\t\t/* Note: 'count' is currently not adjusted by rounding (i.e. the\n\t\t * digits are not \"chopped off\".  That shouldn't matter because\n\t\t * the digit position (absolute or relative) is passed on to the\n\t\t * convert-and-push function.\n\t\t */\n\t}\n\n\tduk__dragon4_convert_and_push(nc_ctx, thr, radix, digits, flags, neg);\n}\n\nDUK_INTERNAL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) {\n\tduk_native_stack_check(thr);\n\tduk__numconv_stringify_raw(thr, radix, digits, flags);\n}\n\n/*\n *  Exposed string-to-number API\n *\n *  Input: [ string ]\n *  Output: [ number ]\n *\n *  If number parsing fails, a NaN is pushed as the result.  If number parsing\n *  fails due to an internal error, an InternalError is thrown.\n */\n\nDUK_LOCAL DUK_NOINLINE void duk__numconv_parse_raw(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags) {\n\tduk__numconv_stringify_ctx nc_ctx_alloc;  /* large context; around 2kB now */\n\tduk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;\n\tduk_double_t res;\n\tduk_hstring *h_str;\n\tduk_int_t expt;\n\tduk_bool_t expt_neg;\n\tduk_small_int_t expt_adj;\n\tduk_small_int_t neg;\n\tduk_small_int_t dig;\n\tduk_small_int_t dig_whole;\n\tduk_small_int_t dig_lzero;\n\tduk_small_int_t dig_frac;\n\tduk_small_int_t dig_expt;\n\tduk_small_int_t dig_prec;\n\tconst duk__exp_limits *explim;\n\tconst duk_uint8_t *p;\n\tduk_small_int_t ch;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse number: %!T, radix=%ld, flags=0x%08lx\",\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (long) radix, (unsigned long) flags));\n\n\tDUK_ASSERT(radix >= 2 && radix <= 36);\n\tDUK_ASSERT(radix - 2 < (duk_small_int_t) sizeof(duk__str2num_digits_for_radix));\n\n\t/*\n\t *  Preliminaries: trim, sign, Infinity check\n\t *\n\t *  We rely on the interned string having a NUL terminator, which will\n\t *  cause a parse failure wherever it is encountered.  As a result, we\n\t *  don't need separate pointer checks.\n\t *\n\t *  There is no special parsing for 'NaN' in the specification although\n\t *  'Infinity' (with an optional sign) is allowed in some contexts.\n\t *  Some contexts allow plus/minus sign, while others only allow the\n\t *  minus sign (like JSON.parse()).\n\t *\n\t *  Automatic hex number detection (leading '0x' or '0X') and octal\n\t *  number detection (leading '0' followed by at least one octal digit)\n\t *  is done here too.\n\t *\n\t *  Symbols are not explicitly rejected here (that's up to the caller).\n\t *  If a symbol were passed here, it should ultimately safely fail\n\t *  parsing due to a syntax error.\n\t */\n\n\tif (flags & DUK_S2N_FLAG_TRIM_WHITE) {\n\t\t/* Leading / trailing whitespace is sometimes accepted and\n\t\t * sometimes not.  After white space trimming, all valid input\n\t\t * characters are pure ASCII.\n\t\t */\n\t\tduk_trim(thr, -1);\n\t}\n\th_str = duk_require_hstring(thr, -1);\n\tDUK_ASSERT(h_str != NULL);\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_str);\n\n\tneg = 0;\n\tch = *p;\n\tif (ch == (duk_small_int_t) '+') {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_PLUS) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: leading plus sign not allowed\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t\tp++;\n\t} else if (ch == (duk_small_int_t) '-') {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_MINUS) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: leading minus sign not allowed\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t\tp++;\n\t\tneg = 1;\n\t}\n\n\tif ((flags & DUK_S2N_FLAG_ALLOW_INF) && DUK_STRNCMP((const char *) p, \"Infinity\", 8) == 0) {\n\t\t/* Don't check for Infinity unless the context allows it.\n\t\t * 'Infinity' is a valid integer literal in e.g. base-36:\n\t\t *\n\t\t *   parseInt('Infinity', 36)\n\t\t *   1461559270678\n\t\t */\n\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_GARBAGE) == 0 && p[8] != DUK_ASC_NUL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: trailing garbage after matching 'Infinity' not allowed\"));\n\t\t\tgoto parse_fail;\n\t\t} else {\n\t\t\tres = DUK_DOUBLE_INFINITY;\n\t\t\tgoto negcheck_and_ret;\n\t\t}\n\t}\n\tch = *p;\n\tif (ch == (duk_small_int_t) '0') {\n\t\tduk_small_int_t detect_radix = 0;\n\t\tch = DUK_LOWERCASE_CHAR_ASCII(p[1]);  /* 'x' or 'X' -> 'x' */\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT) && ch == DUK_ASC_LC_X) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0x/0X hex prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 16;\n#if 0\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_LEGACY_OCT_INT) &&\n\t\t           (ch >= (duk_small_int_t) '0' && ch <= (duk_small_int_t) '9')) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0n oct prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 8;\n\n\t\t\t/* NOTE: if this legacy octal case is added back, it has\n\t\t\t * different flags and 'p' advance so this needs to be\n\t\t\t * reworked.\n\t\t\t */\n\t\t\tflags |= DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO;  /* interpret e.g. '09' as '0', not NaN */\n\t\t\tp += 1;\n#endif\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT) && ch == DUK_ASC_LC_O) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0o oct prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 8;\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT) && ch == DUK_ASC_LC_B) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0b bin prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 2;\n\t\t}\n\t\tif (detect_radix > 0) {\n\t\t\tradix = detect_radix;\n\t\t\t/* Clear empty as zero flag: interpret e.g. '0x' and '0xg' as a NaN (= parse error) */\n\t\t\tflags &= ~(DUK_S2N_FLAG_ALLOW_EXP | DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t\t\t           DUK_S2N_FLAG_ALLOW_FRAC | DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t\t\t           DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO);\n\t\t\tflags |= DUK_S2N_FLAG_ALLOW_LEADING_ZERO;  /* allow e.g. '0x0009' and '0b00010001' */\n\t\t\tp += 2;\n\t\t}\n\t}\n\n\t/*\n\t *  Scan number and setup for Dragon4.\n\t *\n\t *  The fast path case is detected during setup: an integer which\n\t *  can be converted without rounding, no net exponent.  The fast\n\t *  path could be implemented as a separate scan, but may not really\n\t *  be worth it: the multiplications for building 'f' are not\n\t *  expensive when 'f' is small.\n\t *\n\t *  The significand ('f') must contain enough bits of (apparent)\n\t *  accuracy, so that Dragon4 will generate enough binary output digits.\n\t *  For decimal numbers, this means generating a 20-digit significand,\n\t *  which should yield enough practical accuracy to parse IEEE doubles.\n\t *  In fact, the ECMAScript specification explicitly allows an\n\t *  implementation to treat digits beyond 20 as zeroes (and even\n\t *  to round the 20th digit upwards).  For non-decimal numbers, the\n\t *  appropriate number of digits has been precomputed for comparable\n\t *  accuracy.\n\t *\n\t *  Digit counts:\n\t *\n\t *    [ dig_lzero ]\n\t *      |\n\t *     .+-..---[ dig_prec ]----.\n\t *     |  ||                   |\n\t *     0000123.456789012345678901234567890e+123456\n\t *     |     | |                         |  |    |\n\t *     `--+--' `------[ dig_frac ]-------'  `-+--'\n\t *        |                                   |\n\t *    [ dig_whole ]                       [ dig_expt ]\n\t *\n\t *    dig_frac and dig_expt are -1 if not present\n\t *    dig_lzero is only computed for whole number part\n\t *\n\t *  Parsing state\n\t *\n\t *     Parsing whole part      dig_frac < 0 AND dig_expt < 0\n\t *     Parsing fraction part   dig_frac >= 0 AND dig_expt < 0\n\t *     Parsing exponent part   dig_expt >= 0   (dig_frac may be < 0 or >= 0)\n\t *\n\t *  Note: in case we hit an implementation limit (like exponent range),\n\t *  we should throw an error, NOT return NaN or Infinity.  Even with\n\t *  very large exponent (or significand) values the final result may be\n\t *  finite, so NaN/Infinity would be incorrect.\n\t */\n\n\tduk__bi_set_small(&nc_ctx->f, 0);\n\tdig_prec = 0;\n\tdig_lzero = 0;\n\tdig_whole = 0;\n\tdig_frac = -1;\n\tdig_expt = -1;\n\texpt = 0;\n\texpt_adj = 0;  /* essentially tracks digit position of lowest 'f' digit */\n\texpt_neg = 0;\n\tfor (;;) {\n\t\tch = *p++;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse digits: p=%p, ch='%c' (%ld), expt=%ld, expt_adj=%ld, \"\n\t\t                     \"dig_whole=%ld, dig_frac=%ld, dig_expt=%ld, dig_lzero=%ld, dig_prec=%ld\",\n\t\t                     (const void *) p, (int) ((ch >= 0x20 && ch <= 0x7e) ? ch : '?'), (long) ch,\n\t\t                     (long) expt, (long) expt_adj, (long) dig_whole, (long) dig_frac,\n\t\t                     (long) dig_expt, (long) dig_lzero, (long) dig_prec));\n\t\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\n\t\t/* Most common cases first. */\n\t\tif (ch >= (duk_small_int_t) '0' && ch <= (duk_small_int_t) '9') {\n\t\t\tdig = (duk_small_int_t) ch - '0' + 0;\n\t\t} else if (ch == (duk_small_int_t) '.') {\n\t\t\t/* A leading digit is not required in some cases, e.g. accept \".123\".\n\t\t\t * In other cases (JSON.parse()) a leading digit is required.  This\n\t\t\t * is checked for after the loop.\n\t\t\t */\n\t\t\tif (dig_frac >= 0 || dig_expt >= 0) {\n\t\t\t\tif (flags & DUK_S2N_FLAG_ALLOW_GARBAGE) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"garbage termination (invalid period)\"));\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: period not allowed\"));\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_FRAC) == 0) {\n\t\t\t\t/* Some contexts don't allow fractions at all; this can't be a\n\t\t\t\t * post-check because the state ('f' and expt) would be incorrect.\n\t\t\t\t */\n\t\t\t\tif (flags & DUK_S2N_FLAG_ALLOW_GARBAGE) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"garbage termination (invalid first period)\"));\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: fraction part not allowed\"));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"start fraction part\"));\n\t\t\tdig_frac = 0;\n\t\t\tcontinue;\n\t\t} else if (ch == (duk_small_int_t) 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"NUL termination\"));\n\t\t\tbreak;\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_EXP) &&\n\t\t           dig_expt < 0 && (ch == (duk_small_int_t) 'e' || ch == (duk_small_int_t) 'E')) {\n\t\t\t/* Note: we don't parse back exponent notation for anything else\n\t\t\t * than radix 10, so this is not an ambiguous check (e.g. hex\n\t\t\t * exponent values may have 'e' either as a significand digit\n\t\t\t * or as an exponent separator).\n\t\t\t *\n\t\t\t * If the exponent separator occurs twice, 'e' will be interpreted\n\t\t\t * as a digit (= 14) and will be rejected as an invalid decimal\n\t\t\t * digit.\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"start exponent part\"));\n\n\t\t\t/* Exponent without a sign or with a +/- sign is accepted\n\t\t\t * by all call sites (even JSON.parse()).\n\t\t\t */\n\t\t\tch = *p;\n\t\t\tif (ch == (duk_small_int_t) '-') {\n\t\t\t\texpt_neg = 1;\n\t\t\t\tp++;\n\t\t\t} else if (ch == (duk_small_int_t) '+') {\n\t\t\t\tp++;\n\t\t\t}\n\t\t\tdig_expt = 0;\n\t\t\tcontinue;\n\t\t} else if (ch >= (duk_small_int_t) 'a' && ch <= (duk_small_int_t) 'z') {\n\t\t\tdig = (duk_small_int_t) (ch - (duk_small_int_t) 'a' + 0x0a);\n\t\t} else if (ch >= (duk_small_int_t) 'A' && ch <= (duk_small_int_t) 'Z') {\n\t\t\tdig = (duk_small_int_t) (ch - (duk_small_int_t) 'A' + 0x0a);\n\t\t} else {\n\t\t\tdig = 255;  /* triggers garbage digit check below */\n\t\t}\n\t\tDUK_ASSERT((dig >= 0 && dig <= 35) || dig == 255);\n\n\t\tif (dig >= radix) {\n\t\t\tif (flags & DUK_S2N_FLAG_ALLOW_GARBAGE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"garbage termination\"));\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: trailing garbage or invalid digit\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t}\n\n\t\tif (dig_expt < 0) {\n\t\t\t/* whole or fraction digit */\n\n\t\t\tif (dig_prec < duk__str2num_digits_for_radix[radix - 2]) {\n\t\t\t\t/* significant from precision perspective */\n\n\t\t\t\tduk_small_int_t f_zero = duk__bi_is_zero(&nc_ctx->f);\n\t\t\t\tif (f_zero && dig == 0) {\n\t\t\t\t\t/* Leading zero is not counted towards precision digits; not\n\t\t\t\t\t * in the integer part, nor in the fraction part.\n\t\t\t\t\t */\n\t\t\t\t\tif (dig_frac < 0) {\n\t\t\t\t\t\tdig_lzero++;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t/* XXX: join these ops (multiply-accumulate), but only if\n\t\t\t\t\t * code footprint decreases.\n\t\t\t\t\t */\n\t\t\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, (duk_uint32_t) radix);\n\t\t\t\t\tduk__bi_add_small(&nc_ctx->f, &nc_ctx->t1, (duk_uint32_t) dig);\n\t\t\t\t\tdig_prec++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* Ignore digits beyond a radix-specific limit, but note them\n\t\t\t\t * in expt_adj.\n\t\t\t\t */\n\t\t\t\texpt_adj++;\n\t\t\t}\n\n\t\t\tif (dig_frac >= 0) {\n\t\t\t\tdig_frac++;\n\t\t\t\texpt_adj--;\n\t\t\t} else {\n\t\t\t\tdig_whole++;\n\t\t\t}\n\t\t} else {\n\t\t\t/* exponent digit */\n\n\t\t\tDUK_ASSERT(radix == 10);\n\t\t\texpt = expt * radix + dig;\n\t\t\tif (expt > DUK_S2N_MAX_EXPONENT) {\n\t\t\t\t/* Impose a reasonable exponent limit, so that exp\n\t\t\t\t * doesn't need to get tracked using a bigint.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: exponent too large\"));\n\t\t\t\tgoto parse_explimit_error;\n\t\t\t}\n\t\t\tdig_expt++;\n\t\t}\n\t}\n\n\t/* Leading zero. */\n\n\tif (dig_lzero > 0 && dig_whole > 1) {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_LEADING_ZERO) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: leading zeroes not allowed in integer part\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t}\n\n\t/* Validity checks for various fraction formats (\"0.1\", \".1\", \"1.\", \".\"). */\n\n\tif (dig_whole == 0) {\n\t\tif (dig_frac == 0) {\n\t\t\t/* \".\" is not accepted in any format */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: plain period without leading or trailing digits\"));\n\t\t\tgoto parse_fail;\n\t\t} else if (dig_frac > 0) {\n\t\t\t/* \".123\" */\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_NAKED_FRAC) == 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: fraction part not allowed without \"\n\t\t\t\t                     \"leading integer digit(s)\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t} else {\n\t\t\t/* Empty (\"\") is allowed in some formats (e.g. Number(''), as zero,\n\t\t\t * but it must not have a leading +/- sign (GH-2019).  Note that\n\t\t\t * for Number(), h_str is already trimmed so we can check for zero\n\t\t\t * length and still get Number('  +  ') == NaN.\n\t\t\t */\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO) == 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: empty string not allowed (as zero)\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t} else if (DUK_HSTRING_GET_BYTELEN(h_str) != 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: no digits, but not empty (had a +/- sign)\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif (dig_frac == 0) {\n\t\t\t/* \"123.\" is allowed in some formats */\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_EMPTY_FRAC) == 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: empty fractions\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t} else if (dig_frac > 0) {\n\t\t\t/* \"123.456\" */\n\t\t\t;\n\t\t} else {\n\t\t\t/* \"123\" */\n\t\t\t;\n\t\t}\n\t}\n\n\t/* Exponent without digits (e.g. \"1e\" or \"1e+\").  If trailing garbage is\n\t * allowed, ignore exponent part as garbage (= parse as \"1\", i.e. exp 0).\n\t */\n\n\tif (dig_expt == 0) {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_GARBAGE) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: empty exponent\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t\tDUK_ASSERT(expt == 0);\n\t}\n\n\tif (expt_neg) {\n\t\texpt = -expt;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"expt=%ld, expt_adj=%ld, net exponent -> %ld\",\n\t                     (long) expt, (long) expt_adj, (long) (expt + expt_adj)));\n\texpt += expt_adj;\n\n\t/* Fast path check. */\n\n\tif (nc_ctx->f.n <= 1 &&   /* 32-bit value */\n\t    expt == 0    /* no net exponent */) {\n\t\t/* Fast path is triggered for no exponent and also for balanced exponent\n\t\t * and fraction parts, e.g. for \"1.23e2\" == \"123\".  Remember to respect\n\t\t * zero sign.\n\t\t */\n\n\t\t/* XXX: could accept numbers larger than 32 bits, e.g. up to 53 bits? */\n\t\tDUK_DDD(DUK_DDDPRINT(\"fast path number parse\"));\n\t\tif (nc_ctx->f.n == 1) {\n\t\t\tres = (double) nc_ctx->f.v[0];\n\t\t} else {\n\t\t\tres = 0.0;\n\t\t}\n\t\tgoto negcheck_and_ret;\n\t}\n\n\t/* Significand ('f') padding. */\n\n\twhile (dig_prec < duk__str2num_digits_for_radix[radix - 2]) {\n\t\t/* Pad significand with \"virtual\" zero digits so that Dragon4 will\n\t\t * have enough (apparent) precision to work with.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"dig_prec=%ld, pad significand with zero\", (long) dig_prec));\n\t\tduk__bi_mul_small_copy(&nc_ctx->f, (duk_uint32_t) radix, &nc_ctx->t1);\n\t\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\t\texpt--;\n\t\tdig_prec++;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"final exponent: %ld\", (long) expt));\n\n\t/* Detect zero special case. */\n\n\tif (nc_ctx->f.n == 0) {\n\t\t/* This may happen even after the fast path check, if exponent is\n\t\t * not balanced (e.g. \"0e1\").  Remember to respect zero sign.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"significand is zero\"));\n\t\tres = 0.0;\n\t\tgoto negcheck_and_ret;\n\t}\n\n\n\t/* Quick reject of too large or too small exponents.  This check\n\t * would be incorrect for zero (e.g. \"0e1000\" is zero, not Infinity)\n\t * so zero check must be above.\n\t */\n\n\texplim = &duk__str2num_exp_limits[radix - 2];\n\tif (expt > explim->upper) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"exponent too large -> infinite\"));\n\t\tres = (duk_double_t) DUK_DOUBLE_INFINITY;\n\t\tgoto negcheck_and_ret;\n\t} else if (expt < explim->lower) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"exponent too small -> zero\"));\n\t\tres = (duk_double_t) 0.0;\n\t\tgoto negcheck_and_ret;\n\t}\n\n\tnc_ctx->is_s2n = 1;\n\tnc_ctx->e = expt;\n\tnc_ctx->b = radix;\n\tnc_ctx->B = 2;\n\tnc_ctx->is_fixed = 1;\n\tnc_ctx->abs_pos = 0;\n\tnc_ctx->req_digits = 53 + 1;\n\n\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\tDUK_DDD(DUK_DDDPRINT(\"e=%ld\", (long) nc_ctx->e));\n\n\t/*\n\t *  Dragon4 slow path (binary) digit generation.\n\t *  An extra digit is generated for rounding.\n\t */\n\n\tduk__dragon4_prepare(nc_ctx);  /* setup many variables in nc_ctx */\n\n\tDUK_DDD(DUK_DDDPRINT(\"after prepare:\"));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_scale(nc_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"after scale; k=%ld\", (long) nc_ctx->k));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_generate(nc_ctx);\n\n\tDUK_ASSERT(nc_ctx->count == 53 + 1);\n\n\t/*\n\t *  Convert binary digits into an IEEE double.  Need to handle\n\t *  denormals and rounding correctly.\n\t *\n\t *  Some call sites currently assume the result is always a\n\t *  non-fastint double.  If this is changed, check all call\n\t *  sites.\n\t */\n\n\tduk__dragon4_ctx_to_double(nc_ctx, &res);\n\tgoto negcheck_and_ret;\n\n negcheck_and_ret:\n\tif (neg) {\n\t\tres = -res;\n\t}\n\tduk_pop(thr);\n\tduk_push_number(thr, (double) res);\n\tDUK_DDD(DUK_DDDPRINT(\"result: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\treturn;\n\n parse_fail:\n\tDUK_DDD(DUK_DDDPRINT(\"parse failed\"));\n\tduk_pop(thr);\n\tduk_push_nan(thr);\n\treturn;\n\n parse_explimit_error:\n\tDUK_DDD(DUK_DDDPRINT(\"parse failed, internal error, can't return a value\"));\n\tDUK_ERROR_RANGE(thr, \"exponent too large\");\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_INTERNAL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags) {\n\tduk_native_stack_check(thr);\n\tduk__numconv_parse_raw(thr, radix, flags);\n}\n\n/* automatic undefs */\n#undef DUK__BI_MAX_PARTS\n#undef DUK__BI_PRINT\n#undef DUK__DIGITCHAR\n#undef DUK__DRAGON4_OUTPUT_PREINC\n#undef DUK__IEEE_DOUBLE_EXP_BIAS\n#undef DUK__IEEE_DOUBLE_EXP_MIN\n#undef DUK__MAX_FORMATTED_LENGTH\n#undef DUK__MAX_OUTPUT_DIGITS\n#undef DUK__NO_EXP\n#undef DUK__NUMCONV_CTX_BIGINTS_SIZE\n#undef DUK__NUMCONV_CTX_NUM_BIGINTS\n/*\n *  Regexp compilation.\n *\n *  See doc/regexp.rst for a discussion of the compilation approach and\n *  current limitations.\n *\n *  Regexp bytecode assumes jumps can be expressed with signed 32-bit\n *  integers.  Consequently the bytecode size must not exceed 0x7fffffffL.\n *  The implementation casts duk_size_t (buffer size) to duk_(u)int32_t\n *  in many places.  Although this could be changed, the bytecode format\n *  limit would still prevent regexps exceeding the signed 32-bit limit\n *  from working.\n *\n *  XXX: The implementation does not prevent bytecode from exceeding the\n *  maximum supported size.  This could be done by limiting the maximum\n *  input string size (assuming an upper bound can be computed for number\n *  of bytecode bytes emitted per input byte) or checking buffer maximum\n *  size when emitting bytecode (slower).\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Helper macros\n */\n\n#define DUK__RE_INITIAL_BUFSIZE 64\n\n#define DUK__RE_BUFLEN(re_ctx) \\\n\tDUK_BW_GET_SIZE(re_ctx->thr, &re_ctx->bw)\n\n/*\n *  Disjunction struct: result of parsing a disjunction\n */\n\ntypedef struct {\n\t/* Number of characters that the atom matches (e.g. 3 for 'abc'),\n\t * -1 if atom is complex and number of matched characters either\n\t * varies or is not known.\n\t */\n\tduk_int32_t charlen;\n\n#if 0\n\t/* These are not needed to implement quantifier capture handling,\n\t * but might be needed at some point.\n\t */\n\n\t/* re_ctx->captures at start and end of atom parsing.\n\t * Since 'captures' indicates highest capture number emitted\n\t * so far in a DUK_REOP_SAVE, the captures numbers saved by\n\t * the atom are: ]start_captures,end_captures].\n\t */\n\tduk_uint32_t start_captures;\n\tduk_uint32_t end_captures;\n#endif\n} duk__re_disjunction_info;\n\n/*\n *  Encoding helpers\n *\n *  Some of the typing is bytecode based, e.g. slice sizes are unsigned 32-bit\n *  even though the buffer operations will use duk_size_t.\n */\n\n/* XXX: the insert helpers should ensure that the bytecode result is not\n * larger than expected (or at least assert for it).  Many things in the\n * bytecode, like skip offsets, won't work correctly if the bytecode is\n * larger than say 2G.\n */\n\nDUK_LOCAL duk_uint32_t duk__encode_i32(duk_int32_t x) {\n\tif (x < 0) {\n\t\treturn ((duk_uint32_t) (-x)) * 2 + 1;\n\t} else {\n\t\treturn ((duk_uint32_t) x) * 2;\n\t}\n}\n\n/* XXX: return type should probably be duk_size_t, or explicit checks are needed for\n * maximum size.\n */\nDUK_LOCAL duk_uint32_t duk__insert_u32(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_uint32_t x) {\n\tduk_uint8_t buf[DUK_UNICODE_MAX_XUTF8_LENGTH];\n\tduk_small_int_t len;\n\n\tlen = duk_unicode_encode_xutf8((duk_ucodepoint_t) x, buf);\n\tDUK_ASSERT(len >= 0);\n\tDUK_BW_INSERT_ENSURE_BYTES(re_ctx->thr, &re_ctx->bw, offset, buf, (duk_size_t) len);\n\treturn (duk_uint32_t) len;\n}\n\nDUK_LOCAL void duk__append_u32(duk_re_compiler_ctx *re_ctx, duk_uint32_t x) {\n\tDUK_BW_WRITE_ENSURE_XUTF8(re_ctx->thr, &re_ctx->bw, x);\n}\n\nDUK_LOCAL void duk__append_7bit(duk_re_compiler_ctx *re_ctx, duk_uint32_t x) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk__append_u32(re_ctx, x);\n#else\n\tDUK_ASSERT(x <= 0x7fU);\n\tDUK_BW_WRITE_ENSURE_U8(re_ctx->thr, &re_ctx->bw, (duk_uint8_t) x);\n#endif\n}\n\n#if 0\nDUK_LOCAL void duk__append_2bytes(duk_re_compiler_ctx *re_ctx, duk_uint8_t x, duk_uint8_t y) {\n\tDUK_BW_WRITE_ENSURE_U8_2(re_ctx->thr, &re_ctx->bw, x, y);\n}\n#endif\n\nDUK_LOCAL duk_uint32_t duk__insert_i32(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_int32_t x) {\n\treturn duk__insert_u32(re_ctx, offset, duk__encode_i32(x));\n}\n\nDUK_LOCAL void duk__append_reop(duk_re_compiler_ctx *re_ctx, duk_uint32_t reop) {\n\tDUK_ASSERT(reop <= 0x7fU);\n\t(void) duk__append_7bit(re_ctx, reop);\n}\n\n#if 0  /* unused */\nDUK_LOCAL void duk__append_i32(duk_re_compiler_ctx *re_ctx, duk_int32_t x) {\n\tduk__append_u32(re_ctx, duk__encode_i32(x));\n}\n#endif\n\n/* special helper for emitting u16 lists (used for character ranges for built-in char classes) */\nDUK_LOCAL void duk__append_u16_list(duk_re_compiler_ctx *re_ctx, const duk_uint16_t *values, duk_uint32_t count) {\n\t/* Call sites don't need the result length so it's not accumulated. */\n\twhile (count-- > 0) {\n\t\tduk__append_u32(re_ctx, (duk_uint32_t) (*values++));\n\t}\n}\n\nDUK_LOCAL void duk__insert_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_uint32_t data_offset, duk_uint32_t data_length) {\n\tDUK_BW_INSERT_ENSURE_SLICE(re_ctx->thr, &re_ctx->bw, offset, data_offset, data_length);\n}\n\nDUK_LOCAL void duk__append_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t data_offset, duk_uint32_t data_length) {\n\tDUK_BW_WRITE_ENSURE_SLICE(re_ctx->thr, &re_ctx->bw, data_offset, data_length);\n}\n\nDUK_LOCAL void duk__remove_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t data_offset, duk_uint32_t data_length) {\n\tDUK_BW_REMOVE_ENSURE_SLICE(re_ctx->thr, &re_ctx->bw, data_offset, data_length);\n}\n\n/*\n *  Insert a jump offset at 'offset' to complete an instruction\n *  (the jump offset is always the last component of an instruction).\n *  The 'skip' argument must be computed relative to 'offset',\n *  -without- taking into account the skip field being inserted.\n *\n *       ... A B C ins X Y Z ...   (ins may be a JUMP, SPLIT1/SPLIT2, etc)\n *   =>  ... A B C ins SKIP X Y Z\n *\n *  Computing the final (adjusted) skip value, which is relative to the\n *  first byte of the next instruction, is a bit tricky because of the\n *  variable length UTF-8 encoding.  See doc/regexp.rst for discussion.\n */\nDUK_LOCAL duk_uint32_t duk__insert_jump_offset(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_int32_t skip) {\n#if 0\n\t/* Iterative solution. */\n\tif (skip < 0) {\n\t\tduk_small_int_t len;\n\t\t/* two encoding attempts suffices */\n\t\tlen = duk_unicode_get_xutf8_length((duk_codepoint_t) duk__encode_i32(skip));\n\t\tlen = duk_unicode_get_xutf8_length((duk_codepoint_t) duk__encode_i32(skip - (duk_int32_t) len));\n\t\tDUK_ASSERT(duk_unicode_get_xutf8_length(duk__encode_i32(skip - (duk_int32_t) len)) == len);  /* no change */\n\t\tskip -= (duk_int32_t) len;\n\t}\n#endif\n\n#if defined(DUK_USE_PREFER_SIZE)\n\t/* Closed form solution, this produces smallest code.\n\t * See re_neg_jump_offset (closed2).\n\t */\n\tif (skip < 0) {\n\t\tskip--;\n\t\tif (skip < -0x3fL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x3ffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x7fffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0xfffffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x1ffffffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x3fffffffL) {\n\t\t\tskip--;\n\t\t}\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\t/* Closed form solution, this produces fastest code.\n\t * See re_neg_jump_offset (closed1).\n\t */\n\tif (skip < 0) {\n\t\tif (skip >= -0x3eL) {\n\t\t\tskip -= 1;\n\t\t} else if (skip >= -0x3fdL) {\n\t\t\tskip -= 2;\n\t\t} else if (skip >= -0x7ffcL) {\n\t\t\tskip -= 3;\n\t\t} else if (skip >= -0xffffbL) {\n\t\t\tskip -= 4;\n\t\t} else if (skip >= -0x1fffffaL) {\n\t\t\tskip -= 5;\n\t\t} else if (skip >= -0x3ffffff9L) {\n\t\t\tskip -= 6;\n\t\t} else {\n\t\t\tskip -= 7;\n\t\t}\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n\treturn duk__insert_i32(re_ctx, offset, skip);\n}\n\nDUK_LOCAL duk_uint32_t duk__append_jump_offset(duk_re_compiler_ctx *re_ctx, duk_int32_t skip) {\n\treturn (duk_uint32_t) duk__insert_jump_offset(re_ctx, (duk_uint32_t) DUK__RE_BUFLEN(re_ctx), skip);\n}\n\n/*\n *  duk_re_range_callback for generating character class ranges.\n *\n *  When ignoreCase is false, the range is simply emitted as is.  We don't,\n *  for instance, eliminate duplicates or overlapping ranges in a character\n *  class.\n *\n *  When ignoreCase is true but the 'direct' flag is set, the caller knows\n *  that the range canonicalizes to itself for case insensitive matching,\n *  so the range is emitted as is.  This is mainly useful for built-in ranges\n *  like \\W.\n *\n *  Otherwise, when ignoreCase is true, the range needs to be normalized\n *  through canonicalization.  Unfortunately a canonicalized version of a\n *  continuous range is not necessarily continuous (e.g. [x-{] is continuous\n *  but [X-{] is not).  As a result, a single input range may expand to a lot\n *  of output ranges.  The current algorithm creates the canonicalized ranges\n *  footprint efficiently at the cost of compile time execution time; see\n *  doc/regexp.rst for discussion, and some more details below.\n *\n *  Note that the ctx->nranges is a context-wide temporary value.  This is OK\n *  because there cannot be multiple character classes being parsed\n *  simultaneously.\n *\n *  More detail on canonicalization:\n *\n *  Conceptually, a range is canonicalized by scanning the entire range,\n *  normalizing each codepoint by converting it to uppercase, and generating\n *  a set of result ranges.\n *\n *  Ideally a minimal set of output ranges would be emitted by merging all\n *  possible ranges even if they're emitted out of sequence.  Because the\n *  input string is also case normalized during matching, some codepoints\n *  never occur at runtime; these \"don't care\" codepoints can be included or\n *  excluded from ranges when merging/optimizing ranges.\n *\n *  The current algorithm does not do optimal range merging.  Rather, output\n *  codepoints are generated in sequence, and when the output codepoints are\n *  continuous (CP, CP+1, CP+2, ...), they are merged locally into as large a\n *  range as possible.  A small canonicalization bitmap is used to reduce\n *  actual codepoint canonicalizations which are quite slow at present.  The\n *  bitmap provides a \"codepoint block is continuous with respect to\n *  canonicalization\" for N-codepoint blocks.  This allows blocks to be\n *  skipped quickly.\n *\n *  There are a number of shortcomings and future work here:\n *\n *    - Individual codepoint normalizations are slow because they involve\n *      walking bit-packed rules without a lookup index.\n *\n *    - The conceptual algorithm needs to canonicalize every codepoint in the\n *      input range to figure out the output range(s).  Even with the small\n *      canonicalization bitmap the algorithm runs quite slowly for worst case\n *      inputs.  There are many data structure alternatives to improve this.\n *\n *    - While the current algorithm generates maximal output ranges when the\n *      output codepoints are emitted linearly, output ranges are not sorted or\n *      merged otherwise.  In the worst case a lot of ranges are emitted when\n *      most of the ranges could be merged.  In this process one could take\n *      advantage of \"don't care\" codepoints, which are never matched against at\n *      runtime due to canonicalization of input codepoints before comparison,\n *      to merge otherwise discontinuous output ranges.\n *\n *    - The runtime data structure is just a linear list of ranges to match\n *      against.  This can be quite slow if there are a lot of output ranges.\n *      There are various ways to make matching against the ranges faster,\n *      e.g. sorting the ranges and using a binary search; skip lists; tree\n *      based representations; full or approximate codepoint bitmaps, etc.\n *\n *    - Only BMP is supported, codepoints above BMP are assumed to canonicalize\n *      to themselves.  For now this is one place where we don't want to\n *      support chars outside the BMP, because the exhaustive search would be\n *      massively larger.  It would be possible to support non-BMP with a\n *      different algorithm, or perhaps doing case normalization only at match\n *      time.\n */\n\nDUK_LOCAL void duk__regexp_emit_range(duk_re_compiler_ctx *re_ctx, duk_codepoint_t r1, duk_codepoint_t r2) {\n\tDUK_ASSERT(r2 >= r1);\n\tduk__append_u32(re_ctx, (duk_uint32_t) r1);\n\tduk__append_u32(re_ctx, (duk_uint32_t) r2);\n\tre_ctx->nranges++;\n}\n\n#if defined(DUK_USE_REGEXP_CANON_BITMAP)\n/* Find next canonicalization discontinuity (conservative estimate) starting\n * from 'start', not exceeding 'end'.  If continuity is fine up to 'end'\n * inclusive, returns end.  Minimum possible return value is start.\n */\nDUK_LOCAL duk_codepoint_t duk__re_canon_next_discontinuity(duk_codepoint_t start, duk_codepoint_t end) {\n\tduk_uint_t start_blk;\n\tduk_uint_t end_blk;\n\tduk_uint_t blk;\n\tduk_uint_t offset;\n\tduk_uint8_t mask;\n\n\t/* Inclusive block range. */\n\tDUK_ASSERT(start >= 0);\n\tDUK_ASSERT(end >= 0);\n\tDUK_ASSERT(end >= start);\n\tstart_blk = (duk_uint_t) (start >> DUK_CANON_BITMAP_BLKSHIFT);\n\tend_blk = (duk_uint_t) (end >> DUK_CANON_BITMAP_BLKSHIFT);\n\n\tfor (blk = start_blk; blk <= end_blk; blk++) {\n\t\toffset = blk >> 3;\n\t\tmask = 1U << (blk & 0x07);\n\t\tif (offset >= sizeof(duk_unicode_re_canon_bitmap)) {\n\t\t\t/* Reached non-BMP range which is assumed continuous. */\n\t\t\treturn end;\n\t\t}\n\t\tDUK_ASSERT(offset < sizeof(duk_unicode_re_canon_bitmap));\n\t\tif ((duk_unicode_re_canon_bitmap[offset] & mask) == 0) {\n\t\t\t/* Block is discontinuous, continuity is guaranteed\n\t\t\t * only up to end of previous block (+1 for exclusive\n\t\t\t * return value => start of current block).  Start\n\t\t\t * block requires special handling.\n\t\t\t */\n\t\t\tif (blk > start_blk) {\n\t\t\t\treturn (duk_codepoint_t) (blk << DUK_CANON_BITMAP_BLKSHIFT);\n\t\t\t} else {\n\t\t\t\treturn start;\n\t\t\t}\n\t\t}\n\t}\n\tDUK_ASSERT(blk == end_blk + 1);  /* Reached end block which is continuous. */\n\treturn end;\n}\n#else  /* DUK_USE_REGEXP_CANON_BITMAP */\nDUK_LOCAL duk_codepoint_t duk__re_canon_next_discontinuity(duk_codepoint_t start, duk_codepoint_t end) {\n\tDUK_ASSERT(start >= 0);\n\tDUK_ASSERT(end >= 0);\n\tDUK_ASSERT(end >= start);\n\tif (start >= 0x10000) {\n\t\t/* Even without the bitmap, treat non-BMP as continuous. */\n\t\treturn end;\n\t}\n\treturn start;\n}\n#endif  /* DUK_USE_REGEXP_CANON_BITMAP */\n\nDUK_LOCAL void duk__regexp_generate_ranges(void *userdata, duk_codepoint_t r1, duk_codepoint_t r2, duk_bool_t direct) {\n\tduk_re_compiler_ctx *re_ctx = (duk_re_compiler_ctx *) userdata;\n\tduk_codepoint_t r_start;\n\tduk_codepoint_t r_end;\n\tduk_codepoint_t i;\n\tduk_codepoint_t t;\n\tduk_codepoint_t r_disc;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__regexp_generate_ranges(): re_ctx=%p, range=[%ld,%ld] direct=%ld\",\n\t                   (void *) re_ctx, (long) r1, (long) r2, (long) direct));\n\n\tDUK_ASSERT(r2 >= r1);  /* SyntaxError for out of order range. */\n\n\tif (direct || (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) == 0) {\n\t\tDUK_DD(DUK_DDPRINT(\"direct or not case sensitive, emit range: [%ld,%ld]\", (long) r1, (long) r2));\n\t\tduk__regexp_emit_range(re_ctx, r1, r2);\n\t\treturn;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"case sensitive, process range: [%ld,%ld]\", (long) r1, (long) r2));\n\n\tr_start = duk_unicode_re_canonicalize_char(re_ctx->thr, r1);\n\tr_end = r_start;\n\n\tfor (i = r1 + 1; i <= r2;) {\n\t\t/* Input codepoint space processed up to i-1, and\n\t\t * current range in r_{start,end} is up-to-date\n\t\t * (inclusive) and may either break or continue.\n\t\t */\n\t\tr_disc = duk__re_canon_next_discontinuity(i, r2);\n\t\tDUK_ASSERT(r_disc >= i);\n\t\tDUK_ASSERT(r_disc <= r2);\n\n\t\tr_end += r_disc - i;  /* May be zero. */\n\t\tt = duk_unicode_re_canonicalize_char(re_ctx->thr, r_disc);\n\t\tif (t == r_end + 1) {\n\t\t\t/* Not actually a discontinuity, continue range\n\t\t\t * to r_disc and recheck.\n\t\t\t */\n\t\t\tr_end = t;\n\t\t} else {\n\t\t\tduk__regexp_emit_range(re_ctx, r_start, r_end);\n\t\t\tr_start = t;\n\t\t\tr_end = t;\n\t\t}\n\t\ti = r_disc + 1;  /* Guarantees progress. */\n\t}\n\tduk__regexp_emit_range(re_ctx, r_start, r_end);\n\n#if 0  /* Exhaustive search, very slow. */\n\tr_start = duk_unicode_re_canonicalize_char(re_ctx->thr, r1);\n\tr_end = r_start;\n\tfor (i = r1 + 1; i <= r2; i++) {\n\t\tt = duk_unicode_re_canonicalize_char(re_ctx->thr, i);\n\t\tif (t == r_end + 1) {\n\t\t\tr_end = t;\n\t\t} else {\n\t\t\tDUK_DD(DUK_DDPRINT(\"canonicalized, emit range: [%ld,%ld]\", (long) r_start, (long) r_end));\n\t\t\tduk__append_u32(re_ctx, (duk_uint32_t) r_start);\n\t\t\tduk__append_u32(re_ctx, (duk_uint32_t) r_end);\n\t\t\tre_ctx->nranges++;\n\t\t\tr_start = t;\n\t\t\tr_end = t;\n\t\t}\n\t}\n\tDUK_DD(DUK_DDPRINT(\"canonicalized, emit range: [%ld,%ld]\", (long) r_start, (long) r_end));\n\tduk__append_u32(re_ctx, (duk_uint32_t) r_start);\n\tduk__append_u32(re_ctx, (duk_uint32_t) r_end);\n\tre_ctx->nranges++;\n#endif\n}\n\n/*\n *  Parse regexp Disjunction.  Most of regexp compilation happens here.\n *\n *  Handles Disjunction, Alternative, and Term productions directly without\n *  recursion.  The only constructs requiring recursion are positive/negative\n *  lookaheads, capturing parentheses, and non-capturing parentheses.\n *\n *  The function determines whether the entire disjunction is a 'simple atom'\n *  (see doc/regexp.rst discussion on 'simple quantifiers') and if so,\n *  returns the atom character length which is needed by the caller to keep\n *  track of its own atom character length.  A disjunction with more than one\n *  alternative is never considered a simple atom (although in some cases\n *  that might be the case).\n *\n *  Return value: simple atom character length or < 0 if not a simple atom.\n *  Appends the bytecode for the disjunction matcher to the end of the temp\n *  buffer.\n *\n *  Regexp top level structure is:\n *\n *    Disjunction = Term*\n *                | Term* | Disjunction\n *\n *    Term = Assertion\n *         | Atom\n *         | Atom Quantifier\n *\n *  An empty Term sequence is a valid disjunction alternative (e.g. /|||c||/).\n *\n *  Notes:\n *\n *    * Tracking of the 'simple-ness' of the current atom vs. the entire\n *      disjunction are separate matters.  For instance, the disjunction\n *      may be complex, but individual atoms may be simple.  Furthermore,\n *      simple quantifiers are used whenever possible, even if the\n *      disjunction as a whole is complex.\n *\n *    * The estimate of whether an atom is simple is conservative now,\n *      and it would be possible to expand it.  For instance, captures\n *      cause the disjunction to be marked complex, even though captures\n *      -can- be handled by simple quantifiers with some minor modifications.\n *\n *    * Disjunction 'tainting' as 'complex' is handled at the end of the\n *      main for loop collectively for atoms.  Assertions, quantifiers,\n *      and '|' tokens need to taint the result manually if necessary.\n *      Assertions cannot add to result char length, only atoms (and\n *      quantifiers) can; currently quantifiers will taint the result\n *      as complex though.\n */\n\nDUK_LOCAL const duk_uint16_t * const duk__re_range_lookup1[3] = {\n\tduk_unicode_re_ranges_digit,\n\tduk_unicode_re_ranges_white,\n\tduk_unicode_re_ranges_wordchar\n};\nDUK_LOCAL const duk_uint8_t duk__re_range_lookup2[3] = {\n\tsizeof(duk_unicode_re_ranges_digit) / (2 * sizeof(duk_uint16_t)),\n\tsizeof(duk_unicode_re_ranges_white) / (2 * sizeof(duk_uint16_t)),\n\tsizeof(duk_unicode_re_ranges_wordchar) / (2 * sizeof(duk_uint16_t))\n};\n\nDUK_LOCAL void duk__append_range_atom_matcher(duk_re_compiler_ctx *re_ctx, duk_small_uint_t re_op, const duk_uint16_t *ranges, duk_small_uint_t count) {\n#if 0\n\tDUK_ASSERT(re_op <= 0x7fUL);\n\tDUK_ASSERT(count <= 0x7fUL);\n\tduk__append_2bytes(re_ctx, (duk_uint8_t) re_op, (duk_uint8_t) count);\n#endif\n\tduk__append_reop(re_ctx, re_op);\n\tduk__append_7bit(re_ctx, count);\n\tduk__append_u16_list(re_ctx, ranges, count * 2);\n}\n\nDUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t expect_eof, duk__re_disjunction_info *out_atom_info) {\n\tduk_int32_t atom_start_offset = -1;                   /* negative -> no atom matched on previous round */\n\tduk_int32_t atom_char_length = 0;                     /* negative -> complex atom */\n\tduk_uint32_t atom_start_captures = re_ctx->captures;  /* value of re_ctx->captures at start of atom */\n\tduk_int32_t unpatched_disjunction_split = -1;\n\tduk_int32_t unpatched_disjunction_jump = -1;\n\tduk_uint32_t entry_offset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);\n\tduk_int32_t res_charlen = 0;  /* -1 if disjunction is complex, char length if simple */\n\tduk__re_disjunction_info tmp_disj;\n\n\tDUK_ASSERT(out_atom_info != NULL);\n\n\tduk_native_stack_check(re_ctx->thr);\n\tif (re_ctx->recursion_depth >= re_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_COMPILER_RECURSION_LIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tre_ctx->recursion_depth++;\n\n#if 0\n\tout_atom_info->start_captures = re_ctx->captures;\n#endif\n\n\tfor (;;) {\n\t\t/* atom_char_length, atom_start_offset, atom_start_offset reflect the\n\t\t * atom matched on the previous loop.  If a quantifier is encountered\n\t\t * on this loop, these are needed to handle the quantifier correctly.\n\t\t * new_atom_char_length etc are for the atom parsed on this round;\n\t\t * they're written to atom_char_length etc at the end of the round.\n\t\t */\n\t\tduk_int32_t new_atom_char_length;   /* char length of the atom parsed in this loop */\n\t\tduk_int32_t new_atom_start_offset;  /* bytecode start offset of the atom parsed in this loop\n\t\t                                     * (allows quantifiers to copy the atom bytecode)\n\t\t                                     */\n\t\tduk_uint32_t new_atom_start_captures;  /* re_ctx->captures at the start of the atom parsed in this loop */\n\n\t\tduk_lexer_parse_re_token(&re_ctx->lex, &re_ctx->curr_token);\n\n\t\tDUK_DD(DUK_DDPRINT(\"re token: %ld (num=%ld, char=%c)\",\n\t\t                   (long) re_ctx->curr_token.t,\n\t\t                   (long) re_ctx->curr_token.num,\n\t\t                   (re_ctx->curr_token.num >= 0x20 && re_ctx->curr_token.num <= 0x7e) ?\n\t\t                   (int) re_ctx->curr_token.num : (int) '?'));\n\n\t\t/* set by atom case clauses */\n\t\tnew_atom_start_offset = -1;\n\t\tnew_atom_char_length = -1;\n\t\tnew_atom_start_captures = re_ctx->captures;\n\n\t\tswitch (re_ctx->curr_token.t) {\n\t\tcase DUK_RETOK_DISJUNCTION: {\n\t\t\t/*\n\t\t\t *  The handling here is a bit tricky.  If a previous '|' has been processed,\n\t\t\t *  we have a pending split1 and a pending jump (for a previous match).  These\n\t\t\t *  need to be back-patched carefully.  See docs for a detailed example.\n\t\t\t */\n\n\t\t\t/* patch pending jump and split */\n\t\t\tif (unpatched_disjunction_jump >= 0) {\n\t\t\t\tduk_uint32_t offset;\n\n\t\t\t\tDUK_ASSERT(unpatched_disjunction_split >= 0);\n\t\t\t\toffset = (duk_uint32_t) unpatched_disjunction_jump;\n\t\t\t\toffset += duk__insert_jump_offset(re_ctx,\n\t\t\t\t                                  offset,\n\t\t\t\t                                  (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - offset));\n\t\t\t\t/* offset is now target of the pending split (right after jump) */\n\t\t\t\tduk__insert_jump_offset(re_ctx,\n\t\t\t\t                        (duk_uint32_t) unpatched_disjunction_split,\n\t\t\t\t                        (duk_int32_t) offset - unpatched_disjunction_split);\n\t\t\t}\n\n\t\t\t/* add a new pending split to the beginning of the entire disjunction */\n\t\t\t(void) duk__insert_u32(re_ctx,\n\t\t\t                       entry_offset,\n\t\t\t                       DUK_REOP_SPLIT1);   /* prefer direct execution */\n\t\t\tunpatched_disjunction_split = (duk_int32_t) (entry_offset + 1);   /* +1 for opcode */\n\n\t\t\t/* add a new pending match jump for latest finished alternative */\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_JUMP);\n\t\t\tunpatched_disjunction_jump = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\n\t\t\t/* 'taint' result as complex */\n\t\t\tres_charlen = -1;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_QUANTIFIER: {\n\t\t\tif (atom_start_offset < 0) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_INVALID_QUANTIFIER_NO_ATOM);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tif (re_ctx->curr_token.qmin > re_ctx->curr_token.qmax) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_INVALID_QUANTIFIER_VALUES);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tif (atom_char_length >= 0) {\n\t\t\t\t/*\n\t\t\t\t *  Simple atom\n\t\t\t\t *\n\t\t\t\t *  If atom_char_length is zero, we'll have unbounded execution time for e.g.\n\t\t\t\t *  /()*x/.exec('x').  We can't just skip the match because it might have some\n\t\t\t\t *  side effects (for instance, if we allowed captures in simple atoms, the\n\t\t\t\t *  capture needs to happen).  The simple solution below is to force the\n\t\t\t\t *  quantifier to match at most once, since the additional matches have no effect.\n\t\t\t\t *\n\t\t\t\t *  With a simple atom there can be no capture groups, so no captures need\n\t\t\t\t *  to be reset.\n\t\t\t\t */\n\t\t\t\tduk_int32_t atom_code_length;\n\t\t\t\tduk_uint32_t offset;\n\t\t\t\tduk_uint32_t qmin, qmax;\n\n\t\t\t\tqmin = re_ctx->curr_token.qmin;\n\t\t\t\tqmax = re_ctx->curr_token.qmax;\n\t\t\t\tif (atom_char_length == 0) {\n\t\t\t\t\t/* qmin and qmax will be 0 or 1 */\n\t\t\t\t\tif (qmin > 1) {\n\t\t\t\t\t\tqmin = 1;\n\t\t\t\t\t}\n\t\t\t\t\tif (qmax > 1) {\n\t\t\t\t\t\tqmax = 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_MATCH);   /* complete 'sub atom' */\n\t\t\t\tatom_code_length = (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (duk_size_t) atom_start_offset);\n\n\t\t\t\toffset = (duk_uint32_t) atom_start_offset;\n\t\t\t\tif (re_ctx->curr_token.greedy) {\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, DUK_REOP_SQGREEDY);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmin);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmax);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, (duk_uint32_t) atom_char_length);\n\t\t\t\t\toffset += duk__insert_jump_offset(re_ctx, offset, atom_code_length);\n\t\t\t\t} else {\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, DUK_REOP_SQMINIMAL);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmin);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmax);\n\t\t\t\t\toffset += duk__insert_jump_offset(re_ctx, offset, atom_code_length);\n\t\t\t\t}\n\t\t\t\tDUK_UNREF(offset);  /* silence scan-build warning */\n\t\t\t} else {\n\t\t\t\t/*\n\t\t\t\t *  Complex atom\n\t\t\t\t *\n\t\t\t\t *  The original code is used as a template, and removed at the end\n\t\t\t\t *  (this differs from the handling of simple quantifiers).\n\t\t\t\t *\n\t\t\t\t *  NOTE: there is no current solution for empty atoms in complex\n\t\t\t\t *  quantifiers.  This would need some sort of a 'progress' instruction.\n\t\t\t\t *\n\t\t\t\t *  XXX: impose limit on maximum result size, i.e. atom_code_len * atom_copies?\n\t\t\t\t */\n\t\t\t\tduk_int32_t atom_code_length;\n\t\t\t\tduk_uint32_t atom_copies;\n\t\t\t\tduk_uint32_t tmp_qmin, tmp_qmax;\n\n\t\t\t\t/* pre-check how many atom copies we're willing to make (atom_copies not needed below) */\n\t\t\t\tatom_copies = (re_ctx->curr_token.qmax == DUK_RE_QUANTIFIER_INFINITE) ?\n\t\t\t\t              re_ctx->curr_token.qmin : re_ctx->curr_token.qmax;\n\t\t\t\tif (atom_copies > DUK_RE_MAX_ATOM_COPIES) {\n\t\t\t\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_QUANTIFIER_TOO_MANY_COPIES);\n\t\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t\t}\n\n\t\t\t\t/* wipe the capture range made by the atom (if any) */\n\t\t\t\tDUK_ASSERT(atom_start_captures <= re_ctx->captures);\n\t\t\t\tif (atom_start_captures != re_ctx->captures) {\n\t\t\t\t\tDUK_ASSERT(atom_start_captures < re_ctx->captures);\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"must wipe ]atom_start_captures,re_ctx->captures]: ]%ld,%ld]\",\n\t\t\t\t\t                     (long) atom_start_captures, (long) re_ctx->captures));\n\n\t\t\t\t\t/* insert (DUK_REOP_WIPERANGE, start, count) in reverse order so the order ends up right */\n\t\t\t\t\tduk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, (re_ctx->captures - atom_start_captures) * 2U);\n\t\t\t\t\tduk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, (atom_start_captures + 1) * 2);\n\t\t\t\t\tduk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, DUK_REOP_WIPERANGE);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"no need to wipe captures: atom_start_captures == re_ctx->captures == %ld\",\n\t\t\t\t\t                     (long) atom_start_captures));\n\t\t\t\t}\n\n\t\t\t\tatom_code_length = (duk_int32_t) DUK__RE_BUFLEN(re_ctx) - atom_start_offset;\n\n\t\t\t\t/* insert the required matches (qmin) by copying the atom */\n\t\t\t\ttmp_qmin = re_ctx->curr_token.qmin;\n\t\t\t\ttmp_qmax = re_ctx->curr_token.qmax;\n\t\t\t\twhile (tmp_qmin > 0) {\n\t\t\t\t\tduk__append_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t\t\ttmp_qmin--;\n\t\t\t\t\tif (tmp_qmax != DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\t\ttmp_qmax--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(tmp_qmin == 0);\n\n\t\t\t\t/* insert code for matching the remainder - infinite or finite */\n\t\t\t\tif (tmp_qmax == DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\t/* reuse last emitted atom for remaining 'infinite' quantifier */\n\n\t\t\t\t\tif (re_ctx->curr_token.qmin == 0) {\n\t\t\t\t\t\t/* Special case: original qmin was zero so there is nothing\n\t\t\t\t\t\t * to repeat.  Emit an atom copy but jump over it here.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_JUMP);\n\t\t\t\t\t\tduk__append_jump_offset(re_ctx, atom_code_length);\n\t\t\t\t\t\tduk__append_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t\t\t}\n\t\t\t\t\tif (re_ctx->curr_token.greedy) {\n\t\t\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_SPLIT2);   /* prefer jump */\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_SPLIT1);   /* prefer direct */\n\t\t\t\t\t}\n\t\t\t\t\tduk__append_jump_offset(re_ctx, -atom_code_length - 1);  /* -1 for opcode */\n\t\t\t\t} else {\n\t\t\t\t\t/*\n\t\t\t\t\t *  The remaining matches are emitted as sequence of SPLITs and atom\n\t\t\t\t\t *  copies; the SPLITs skip the remaining copies and match the sequel.\n\t\t\t\t\t *  This sequence needs to be emitted starting from the last copy\n\t\t\t\t\t *  because the SPLITs are variable length due to the variable length\n\t\t\t\t\t *  skip offset.  This causes a lot of memory copying now.\n\t\t\t\t\t *\n\t\t\t\t\t *  Example structure (greedy, match maximum # atoms):\n\t\t\t\t\t *\n\t\t\t\t\t *      SPLIT1 LSEQ\n\t\t\t\t\t *      (atom)\n\t\t\t\t\t *      SPLIT1 LSEQ    ; <- the byte length of this instruction is needed\n\t\t\t\t\t *      (atom)         ; to encode the above SPLIT1 correctly\n\t\t\t\t\t *      ...\n\t\t\t\t\t *   LSEQ:\n\t\t\t\t\t */\n\t\t\t\t\tduk_uint32_t offset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\t\t\twhile (tmp_qmax > 0) {\n\t\t\t\t\t\tduk__insert_slice(re_ctx, offset, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t\t\t\tif (re_ctx->curr_token.greedy) {\n\t\t\t\t\t\t\tduk__insert_u32(re_ctx, offset, DUK_REOP_SPLIT1);   /* prefer direct */\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tduk__insert_u32(re_ctx, offset, DUK_REOP_SPLIT2);   /* prefer jump */\n\t\t\t\t\t\t}\n\t\t\t\t\t\tduk__insert_jump_offset(re_ctx,\n\t\t\t\t\t\t                        offset + 1,   /* +1 for opcode */\n\t\t\t\t\t\t                        (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (offset + 1)));\n\t\t\t\t\t\ttmp_qmax--;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* remove the original 'template' atom */\n\t\t\t\tduk__remove_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t}\n\n\t\t\t/* 'taint' result as complex */\n\t\t\tres_charlen = -1;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_START: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_START);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_END: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_END);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_WORD_BOUNDARY: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_WORD_BOUNDARY);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_NOT_WORD_BOUNDARY);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_START_POS_LOOKAHEAD:\n\t\tcase DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD: {\n\t\t\tduk_uint32_t offset;\n\t\t\tduk_uint32_t opcode = (re_ctx->curr_token.t == DUK_RETOK_ASSERT_START_POS_LOOKAHEAD) ?\n\t\t\t                      DUK_REOP_LOOKPOS : DUK_REOP_LOOKNEG;\n\n\t\t\toffset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__parse_disjunction(re_ctx, 0, &tmp_disj);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_MATCH);\n\n\t\t\t(void) duk__insert_u32(re_ctx, offset, opcode);\n\t\t\t(void) duk__insert_jump_offset(re_ctx,\n\t\t\t                               offset + 1,   /* +1 for opcode */\n\t\t\t                               (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (offset + 1)));\n\n\t\t\t/* 'taint' result as complex -- this is conservative,\n\t\t\t * as lookaheads do not backtrack.\n\t\t\t */\n\t\t\tres_charlen = -1;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_PERIOD: {\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_PERIOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_CHAR: {\n\t\t\t/* Note: successive characters could be joined into string matches\n\t\t\t * but this is not trivial (consider e.g. '/xyz+/); see docs for\n\t\t\t * more discussion.\n\t\t\t *\n\t\t\t * No support for \\u{H+} yet.  While only BMP Unicode escapes are\n\t\t\t * supported for RegExps at present, 'ch' may still be a non-BMP\n\t\t\t * codepoint if it is decoded straight from source text UTF-8.\n\t\t\t * There's no non-BMP support yet so this is handled simply by\n\t\t\t * matching the non-BMP character (which is custom behavior).\n\t\t\t */\n\t\t\tduk_uint32_t ch;\n\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_CHAR);\n\t\t\tch = re_ctx->curr_token.num;\n\t\t\tif (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) {\n\t\t\t\tch = (duk_uint32_t) duk_unicode_re_canonicalize_char(re_ctx->thr, (duk_codepoint_t) ch);\n\t\t\t}\n\t\t\tduk__append_u32(re_ctx, ch);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_DIGIT:\n\t\tcase DUK_RETOK_ATOM_NOT_DIGIT:\n\t\tcase DUK_RETOK_ATOM_WHITE:\n\t\tcase DUK_RETOK_ATOM_NOT_WHITE:\n\t\tcase DUK_RETOK_ATOM_WORD_CHAR:\n\t\tcase DUK_RETOK_ATOM_NOT_WORD_CHAR: {\n\t\t\tduk_small_uint_t re_op;\n\t\t\tduk_small_uint_t idx;\n\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_DIGIT & 0x01) != 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_WHITE & 0x01) != 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_WORD_CHAR & 0x01) != 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_NOT_DIGIT & 0x01) == 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_NOT_WHITE & 0x01) == 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_NOT_WORD_CHAR & 0x01) == 0);\n\t\t\tre_op = (re_ctx->curr_token.t & 0x01) ? DUK_REOP_RANGES : DUK_REOP_INVRANGES;\n\n\t\t\tDUK_ASSERT(DUK_RETOK_ATOM_WHITE == DUK_RETOK_ATOM_DIGIT + 2);\n\t\t\tDUK_ASSERT(DUK_RETOK_ATOM_WORD_CHAR == DUK_RETOK_ATOM_DIGIT + 4);\n\t\t\tidx = (duk_small_uint_t) ((re_ctx->curr_token.t - DUK_RETOK_ATOM_DIGIT) >> 1U);\n\t\t\tDUK_ASSERT(idx <= 2U);  /* Assume continuous token numbers; also checks negative underflow. */\n\n\t\t\tduk__append_range_atom_matcher(re_ctx, re_op, duk__re_range_lookup1[idx], duk__re_range_lookup2[idx]);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_BACKREFERENCE: {\n\t\t\tduk_uint32_t backref = (duk_uint32_t) re_ctx->curr_token.num;\n\t\t\tif (backref > re_ctx->highest_backref) {\n\t\t\t\tre_ctx->highest_backref = backref;\n\t\t\t}\n\t\t\tnew_atom_char_length = -1;   /* mark as complex */\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_BACKREFERENCE);\n\t\t\tduk__append_u32(re_ctx, backref);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_START_CAPTURE_GROUP: {\n\t\t\tduk_uint32_t cap;\n\n\t\t\tnew_atom_char_length = -1;   /* mark as complex (capture handling) */\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tcap = ++re_ctx->captures;\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_SAVE);\n\t\t\tduk__append_u32(re_ctx, cap * 2);\n\t\t\tduk__parse_disjunction(re_ctx, 0, &tmp_disj);  /* retval (sub-atom char length) unused, tainted as complex above */\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_SAVE);\n\t\t\tduk__append_u32(re_ctx, cap * 2 + 1);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_START_NONCAPTURE_GROUP: {\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__parse_disjunction(re_ctx, 0, &tmp_disj);\n\t\t\tnew_atom_char_length = tmp_disj.charlen;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_START_CHARCLASS:\n\t\tcase DUK_RETOK_ATOM_START_CHARCLASS_INVERTED: {\n\t\t\t/*\n\t\t\t *  Range parsing is done with a special lexer function which calls\n\t\t\t *  us for every range parsed.  This is different from how rest of\n\t\t\t *  the parsing works, but avoids a heavy, arbitrary size intermediate\n\t\t\t *  value type to hold the ranges.\n\t\t\t *\n\t\t\t *  Another complication is the handling of character ranges when\n\t\t\t *  case insensitive matching is used (see docs for discussion).\n\t\t\t *  The range handler callback given to the lexer takes care of this\n\t\t\t *  as well.\n\t\t\t *\n\t\t\t *  Note that duplicate ranges are not eliminated when parsing character\n\t\t\t *  classes, so that canonicalization of\n\t\t\t *\n\t\t\t *    [0-9a-fA-Fx-{]\n\t\t\t *\n\t\t\t *  creates the result (note the duplicate ranges):\n\t\t\t *\n\t\t\t *    [0-9A-FA-FX-Z{-{]\n\t\t\t *\n\t\t\t *  where [x-{] is split as a result of canonicalization.  The duplicate\n\t\t\t *  ranges are not a semantics issue: they work correctly.\n\t\t\t */\n\n\t\t\tduk_uint32_t offset;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"character class\"));\n\n\t\t\t/* insert ranges instruction, range count patched in later */\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx,\n\t\t\t                 (re_ctx->curr_token.t == DUK_RETOK_ATOM_START_CHARCLASS) ?\n\t\t\t                 DUK_REOP_RANGES : DUK_REOP_INVRANGES);\n\t\t\toffset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);    /* patch in range count later */\n\n\t\t\t/* parse ranges until character class ends */\n\t\t\tre_ctx->nranges = 0;    /* note: ctx-wide temporary */\n\t\t\tduk_lexer_parse_re_ranges(&re_ctx->lex, duk__regexp_generate_ranges, (void *) re_ctx);\n\n\t\t\t/* insert range count */\n\t\t\tduk__insert_u32(re_ctx, offset, re_ctx->nranges);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_END_GROUP: {\n\t\t\tif (expect_eof) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_CLOSING_PAREN);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tgoto done;\n\t\t}\n\t\tcase DUK_RETOK_EOF: {\n\t\t\tif (!expect_eof) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_END_OF_PATTERN);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tgoto done;\n\t\t}\n\t\tdefault: {\n\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_REGEXP_TOKEN);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\t}\n\n\t\t/* a complex (new) atom taints the result */\n\t\tif (new_atom_start_offset >= 0) {\n\t\t\tif (new_atom_char_length < 0) {\n\t\t\t\tres_charlen = -1;\n\t\t\t} else if (res_charlen >= 0) {\n\t\t\t\t/* only advance if not tainted */\n\t\t\t\tres_charlen += new_atom_char_length;\n\t\t\t}\n\t\t}\n\n\t\t/* record previous atom info in case next token is a quantifier */\n\t\tatom_start_offset = new_atom_start_offset;\n\t\tatom_char_length = new_atom_char_length;\n\t\tatom_start_captures = new_atom_start_captures;\n\t}\n\n done:\n\n\t/* finish up pending jump and split for last alternative */\n\tif (unpatched_disjunction_jump >= 0) {\n\t\tduk_uint32_t offset;\n\n\t\tDUK_ASSERT(unpatched_disjunction_split >= 0);\n\t\toffset = (duk_uint32_t) unpatched_disjunction_jump;\n\t\toffset += duk__insert_jump_offset(re_ctx,\n\t\t                                  offset,\n\t\t                                  (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - offset));\n\t\t/* offset is now target of the pending split (right after jump) */\n\t\tduk__insert_jump_offset(re_ctx,\n\t\t                        (duk_uint32_t) unpatched_disjunction_split,\n\t\t                        (duk_int32_t) offset - unpatched_disjunction_split);\n\t}\n\n#if 0\n\tout_atom_info->end_captures = re_ctx->captures;\n#endif\n\tout_atom_info->charlen = res_charlen;\n\tDUK_DDD(DUK_DDDPRINT(\"parse disjunction finished: charlen=%ld\",\n\t                     (long) out_atom_info->charlen));\n\n\tre_ctx->recursion_depth--;\n}\n\n/*\n *  Flags parsing (see E5 Section 15.10.4.1).\n */\n\nDUK_LOCAL duk_uint32_t duk__parse_regexp_flags(duk_hthread *thr, duk_hstring *h) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint32_t flags = 0;\n\n\tp = DUK_HSTRING_GET_DATA(h);\n\tp_end = p + DUK_HSTRING_GET_BYTELEN(h);\n\n\t/* Note: can be safely scanned as bytes (undecoded) */\n\n\twhile (p < p_end) {\n\t\tduk_uint8_t c = *p++;\n\t\tswitch (c) {\n\t\tcase (duk_uint8_t) 'g': {\n\t\t\tif (flags & DUK_RE_FLAG_GLOBAL) {\n\t\t\t\tgoto flags_error;\n\t\t\t}\n\t\t\tflags |= DUK_RE_FLAG_GLOBAL;\n\t\t\tbreak;\n\t\t}\n\t\tcase (duk_uint8_t) 'i': {\n\t\t\tif (flags & DUK_RE_FLAG_IGNORE_CASE) {\n\t\t\t\tgoto flags_error;\n\t\t\t}\n\t\t\tflags |= DUK_RE_FLAG_IGNORE_CASE;\n\t\t\tbreak;\n\t\t}\n\t\tcase (duk_uint8_t) 'm': {\n\t\t\tif (flags & DUK_RE_FLAG_MULTILINE) {\n\t\t\t\tgoto flags_error;\n\t\t\t}\n\t\t\tflags |= DUK_RE_FLAG_MULTILINE;\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tgoto flags_error;\n\t\t}\n\t\t}\n\t}\n\n\treturn flags;\n\n flags_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_REGEXP_FLAGS);\n\tDUK_WO_NORETURN(return 0U;);\n}\n\n/*\n *  Create escaped RegExp source (E5 Section 15.10.3).\n *\n *  The current approach is to special case the empty RegExp\n *  ('' -> '(?:)') and otherwise replace unescaped '/' characters\n *  with '\\/' regardless of where they occur in the regexp.\n *\n *  Note that normalization does not seem to be necessary for\n *  RegExp literals (e.g. '/foo/') because to be acceptable as\n *  a RegExp literal, the text between forward slashes must\n *  already match the escaping requirements (e.g. must not contain\n *  unescaped forward slashes or be empty).  Escaping IS needed\n *  for expressions like 'new Regexp(\"...\", \"\")' however.\n *  Currently, we re-escape in either case.\n *\n *  Also note that we process the source here in UTF-8 encoded\n *  form.  This is correct, because any non-ASCII characters are\n *  passed through without change.\n */\n\nDUK_LOCAL void duk__create_escaped_source(duk_hthread *thr, int idx_pattern) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tduk_uint8_t *q;\n\tduk_size_t i, n;\n\tduk_uint_fast8_t c_prev, c;\n\n\th = duk_known_hstring(thr, idx_pattern);\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tn = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);\n\n\tif (n == 0) {\n\t\tduk_push_literal(thr, \"(?:)\");\n\t\treturn;\n\t}\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, n);\n\tq = DUK_BW_GET_PTR(thr, bw);\n\n\tc_prev = (duk_uint_fast8_t) 0;\n\n\tfor (i = 0; i < n; i++) {\n\t\tc = p[i];\n\n\t\tq = DUK_BW_ENSURE_RAW(thr, bw, 2, q);\n\n\t\tif (c == (duk_uint_fast8_t) '/' && c_prev != (duk_uint_fast8_t) '\\\\') {\n\t\t\t/* Unescaped '/' ANYWHERE in the regexp (in disjunction,\n\t\t\t * inside a character class, ...) => same escape works.\n\t\t\t */\n\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t}\n\t\t*q++ = (duk_uint8_t) c;\n\n\t\tc_prev = c;\n\t}\n\n\tDUK_BW_SETPTR_AND_COMPACT(thr, bw, q);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if input is safe. */\n\n\t/* [ ... escaped_source ] */\n}\n\n/*\n *  Exposed regexp compilation primitive.\n *\n *  Sets up a regexp compilation context, and calls duk__parse_disjunction() to do the\n *  actual parsing.  Handles generation of the compiled regexp header and the\n *  \"boilerplate\" capture of the matching substring (save 0 and 1).  Also does some\n *  global level regexp checks after recursive compilation has finished.\n *\n *  An escaped version of the regexp source, suitable for use as a RegExp instance\n *  'source' property (see E5 Section 15.10.3), is also left on the stack.\n *\n *  Input stack:  [ pattern flags ]\n *  Output stack: [ bytecode escaped_source ]  (both as strings)\n */\n\nDUK_INTERNAL void duk_regexp_compile(duk_hthread *thr) {\n\tduk_re_compiler_ctx re_ctx;\n\tduk_lexer_point lex_point;\n\tduk_hstring *h_pattern;\n\tduk_hstring *h_flags;\n\tduk__re_disjunction_info ign_disj;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/*\n\t *  Args validation\n\t */\n\n\t/* TypeError if fails */\n\th_pattern = duk_require_hstring_notsymbol(thr, -2);\n\th_flags = duk_require_hstring_notsymbol(thr, -1);\n\n\t/*\n\t *  Create normalized 'source' property (E5 Section 15.10.3).\n\t */\n\n\t/* [ ... pattern flags ] */\n\n\tduk__create_escaped_source(thr, -2);\n\n\t/* [ ... pattern flags escaped_source ] */\n\n\t/*\n\t *  Init compilation context\n\t */\n\n\t/* [ ... pattern flags escaped_source buffer ] */\n\n\tduk_memzero(&re_ctx, sizeof(re_ctx));\n\tDUK_LEXER_INITCTX(&re_ctx.lex);  /* duplicate zeroing, expect for (possible) NULL inits */\n\tre_ctx.thr = thr;\n\tre_ctx.lex.thr = thr;\n\tre_ctx.lex.input = DUK_HSTRING_GET_DATA(h_pattern);\n\tre_ctx.lex.input_length = DUK_HSTRING_GET_BYTELEN(h_pattern);\n\tre_ctx.lex.token_limit = DUK_RE_COMPILE_TOKEN_LIMIT;\n\tre_ctx.recursion_limit = DUK_USE_REGEXP_COMPILER_RECLIMIT;\n\tre_ctx.re_flags = duk__parse_regexp_flags(thr, h_flags);\n\n\tDUK_BW_INIT_PUSHBUF(thr, &re_ctx.bw, DUK__RE_INITIAL_BUFSIZE);\n\n\tDUK_DD(DUK_DDPRINT(\"regexp compiler ctx initialized, flags=0x%08lx, recursion_limit=%ld\",\n\t                   (unsigned long) re_ctx.re_flags, (long) re_ctx.recursion_limit));\n\n\t/*\n\t *  Init lexer\n\t */\n\n\tlex_point.offset = 0;  /* expensive init, just want to fill window */\n\tlex_point.line = 1;\n\tDUK_LEXER_SETPOINT(&re_ctx.lex, &lex_point);\n\n\t/*\n\t *  Compilation\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"starting regexp compilation\"));\n\n\tduk__append_reop(&re_ctx, DUK_REOP_SAVE);\n\tduk__append_7bit(&re_ctx, 0);\n\tduk__parse_disjunction(&re_ctx, 1 /*expect_eof*/, &ign_disj);\n\tduk__append_reop(&re_ctx, DUK_REOP_SAVE);\n\tduk__append_7bit(&re_ctx, 1);\n\tduk__append_reop(&re_ctx, DUK_REOP_MATCH);\n\n\t/*\n\t *  Check for invalid backreferences; note that it is NOT an error\n\t *  to back-reference a capture group which has not yet been introduced\n\t *  in the pattern (as in /\\1(foo)/); in fact, the backreference will\n\t *  always match!  It IS an error to back-reference a capture group\n\t *  which will never be introduced in the pattern.  Thus, we can check\n\t *  for such references only after parsing is complete.\n\t */\n\n\tif (re_ctx.highest_backref > re_ctx.captures) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_BACKREFS);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/*\n\t *  Emit compiled regexp header: flags, ncaptures\n\t *  (insertion order inverted on purpose)\n\t */\n\n\tduk__insert_u32(&re_ctx, 0, (re_ctx.captures + 1) * 2);\n\tduk__insert_u32(&re_ctx, 0, re_ctx.re_flags);\n\n\t/* [ ... pattern flags escaped_source buffer ] */\n\n\tDUK_BW_COMPACT(thr, &re_ctx.bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe because flags is at most 7 bit. */\n\n\t/* [ ... pattern flags escaped_source bytecode ] */\n\n\t/*\n\t *  Finalize stack\n\t */\n\n\tduk_remove(thr, -4);     /* -> [ ... flags escaped_source bytecode ] */\n\tduk_remove(thr, -3);     /* -> [ ... escaped_source bytecode ] */\n\n\tDUK_DD(DUK_DDPRINT(\"regexp compilation successful, bytecode: %!T, escaped source: %!T\",\n\t                   (duk_tval *) duk_get_tval(thr, -1), (duk_tval *) duk_get_tval(thr, -2)));\n}\n\n/*\n *  Create a RegExp instance (E5 Section 15.10.7).\n *\n *  Note: the output stack left by duk_regexp_compile() is directly compatible\n *  with the input here.\n *\n *  Input stack:  [ escaped_source bytecode ]  (both as strings)\n *  Output stack: [ RegExp ]\n */\n\nDUK_INTERNAL void duk_regexp_create_instance(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\t/* [ ... escaped_source bytecode ] */\n\n\tduk_push_object(thr);\n\th = duk_known_hobject(thr, -1);\n\tduk_insert(thr, -3);\n\n\t/* [ ... regexp_object escaped_source bytecode ] */\n\n\tDUK_HOBJECT_SET_CLASS_NUMBER(h, DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[DUK_BIDX_REGEXP_PROTOTYPE]);\n\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_BYTECODE, DUK_PROPDESC_FLAGS_NONE);\n\n\t/* [ ... regexp_object escaped_source ] */\n\n\t/* In ES2015 .source, and the .global, .multiline, etc flags are\n\t * inherited getters.  Store the escaped source as an internal\n\t * property for the getter.\n\t */\n\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_SOURCE, DUK_PROPDESC_FLAGS_NONE);\n\n\t/* [ ... regexp_object ] */\n\n\tduk_push_int(thr, 0);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LAST_INDEX, DUK_PROPDESC_FLAGS_W);\n\n\t/* [ ... regexp_object ] */\n}\n\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\n/* regexp support disabled */\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n/* automatic undefs */\n#undef DUK__RE_BUFLEN\n#undef DUK__RE_INITIAL_BUFSIZE\n/*\n *  Regexp executor.\n *\n *  Safety: the ECMAScript executor should prevent user from reading and\n *  replacing regexp bytecode.  Even so, the executor must validate all\n *  memory accesses etc.  When an invalid access is detected (e.g. a 'save'\n *  opcode to invalid, unallocated index) it should fail with an internal\n *  error but not cause a segmentation fault.\n *\n *  Notes:\n *\n *    - Backtrack counts are limited to unsigned 32 bits but should\n *      technically be duk_size_t for strings longer than 4G chars.\n *      This also requires a regexp bytecode change.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Helpers for UTF-8 handling\n *\n *  For bytecode readers the duk_uint32_t and duk_int32_t types are correct\n *  because they're used for more than just codepoints.\n */\n\nDUK_LOCAL duk_uint32_t duk__bc_get_u32(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **pc) {\n\treturn (duk_uint32_t) duk_unicode_decode_xutf8_checked(re_ctx->thr, pc, re_ctx->bytecode, re_ctx->bytecode_end);\n}\n\nDUK_LOCAL duk_int32_t duk__bc_get_i32(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **pc) {\n\tduk_uint32_t t;\n\n\t/* signed integer encoding needed to work with UTF-8 */\n\tt = (duk_uint32_t) duk_unicode_decode_xutf8_checked(re_ctx->thr, pc, re_ctx->bytecode, re_ctx->bytecode_end);\n\tif (t & 1) {\n\t\treturn -((duk_int32_t) (t >> 1));\n\t} else {\n\t\treturn (duk_int32_t) (t >> 1);\n\t}\n}\n\nDUK_LOCAL const duk_uint8_t *duk__utf8_backtrack(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_uint_fast32_t count) {\n\tconst duk_uint8_t *p;\n\n\t/* Note: allow backtracking from p == ptr_end */\n\tp = *ptr;\n\tif (p < ptr_start || p > ptr_end) {\n\t\tgoto fail;\n\t}\n\n\twhile (count > 0) {\n\t\tfor (;;) {\n\t\t\tp--;\n\t\t\tif (p < ptr_start) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tif ((*p & 0xc0) != 0x80) {\n\t\t\t\t/* utf-8 continuation bytes have the form 10xx xxxx */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcount--;\n\t}\n\t*ptr = p;\n\treturn p;\n\n fail:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_LOCAL const duk_uint8_t *duk__utf8_advance(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_uint_fast32_t count) {\n\tconst duk_uint8_t *p;\n\n\tp = *ptr;\n\tif (p < ptr_start || p >= ptr_end) {\n\t\tgoto fail;\n\t}\n\n\twhile (count > 0) {\n\t\tfor (;;) {\n\t\t\tp++;\n\n\t\t\t/* Note: if encoding ends by hitting end of input, we don't check that\n\t\t\t * the encoding is valid, we just assume it is.\n\t\t\t */\n\t\t\tif (p >= ptr_end || ((*p & 0xc0) != 0x80)) {\n\t\t\t\t/* utf-8 continuation bytes have the form 10xx xxxx */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcount--;\n\t}\n\n\t*ptr = p;\n\treturn p;\n\n fail:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Helpers for dealing with the input string\n */\n\n/* Get a (possibly canonicalized) input character from current sp.  The input\n * itself is never modified, and captures always record non-canonicalized\n * characters even in case-insensitive matching.  Return <0 if out of input.\n */\nDUK_LOCAL duk_codepoint_t duk__inp_get_cp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **sp) {\n\tduk_codepoint_t res;\n\n\tif (*sp >= re_ctx->input_end) {\n\t\treturn -1;\n\t}\n\tres = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(re_ctx->thr, sp, re_ctx->input, re_ctx->input_end);\n\tif (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) {\n\t\tres = duk_unicode_re_canonicalize_char(re_ctx->thr, res);\n\t}\n\treturn res;\n}\n\nDUK_LOCAL const duk_uint8_t *duk__inp_backtrack(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **sp, duk_uint_fast32_t count) {\n\treturn duk__utf8_backtrack(re_ctx->thr, sp, re_ctx->input, re_ctx->input_end, count);\n}\n\n/* Backtrack utf-8 input and return a (possibly canonicalized) input character. */\nDUK_LOCAL duk_codepoint_t duk__inp_get_prev_cp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t *sp) {\n\t/* note: caller 'sp' is intentionally not updated here */\n\t(void) duk__inp_backtrack(re_ctx, &sp, (duk_uint_fast32_t) 1);\n\treturn duk__inp_get_cp(re_ctx, &sp);\n}\n\n/*\n *  Regexp recursive matching function.\n *\n *  Returns 'sp' on successful match (points to character after last matched one),\n *  NULL otherwise.\n *\n *  The C recursion depth limit check is only performed in this function, this\n *  suffices because the function is present in all true recursion required by\n *  regexp execution.\n */\n\nDUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t *pc, const duk_uint8_t *sp) {\n\tduk_native_stack_check(re_ctx->thr);\n\tif (re_ctx->recursion_depth >= re_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_EXECUTOR_RECURSION_LIMIT);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\tre_ctx->recursion_depth++;\n\n\tfor (;;) {\n\t\tduk_small_int_t op;\n\n\t\tif (re_ctx->steps_count >= re_ctx->steps_limit) {\n\t\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_EXECUTOR_STEP_LIMIT);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t\tre_ctx->steps_count++;\n\n\t\t/* Opcodes are at most 7 bits now so they encode to one byte.  If this\n\t\t * were not the case or 'pc' is invalid here (due to a bug etc) we'll\n\t\t * still fail safely through the switch default case.\n\t\t */\n\t\tDUK_ASSERT(pc[0] <= 0x7fU);\n#if 0\n\t\top = (duk_small_int_t) duk__bc_get_u32(re_ctx, &pc);\n#endif\n\t\top = *pc++;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"match: rec=%ld, steps=%ld, pc (after op)=%ld, sp=%ld, op=%ld\",\n\t\t                     (long) re_ctx->recursion_depth,\n\t\t                     (long) re_ctx->steps_count,\n\t\t                     (long) (pc - re_ctx->bytecode),\n\t\t                     (long) (sp - re_ctx->input),\n\t\t                     (long) op));\n\n\t\tswitch (op) {\n\t\tcase DUK_REOP_MATCH: {\n\t\t\tgoto match;\n\t\t}\n\t\tcase DUK_REOP_CHAR: {\n\t\t\t/*\n\t\t\t *  Byte-based matching would be possible for case-sensitive\n\t\t\t *  matching but not for case-insensitive matching.  So, we\n\t\t\t *  match by decoding the input and bytecode character normally.\n\t\t\t *\n\t\t\t *  Bytecode characters are assumed to be already canonicalized.\n\t\t\t *  Input characters are canonicalized automatically by\n\t\t\t *  duk__inp_get_cp() if necessary.\n\t\t\t *\n\t\t\t *  There is no opcode for matching multiple characters.  The\n\t\t\t *  regexp compiler has trouble joining strings efficiently\n\t\t\t *  during compilation.  See doc/regexp.rst for more discussion.\n\t\t\t */\n\t\t\tduk_codepoint_t c1, c2;\n\n\t\t\tc1 = (duk_codepoint_t) duk__bc_get_u32(re_ctx, &pc);\n\t\t\tDUK_ASSERT(!(re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) ||\n\t\t\t           c1 == duk_unicode_re_canonicalize_char(re_ctx->thr, c1));  /* canonicalized by compiler */\n\t\t\tc2 = duk__inp_get_cp(re_ctx, &sp);\n\t\t\t/* No need to check for c2 < 0 (end of input): because c1 >= 0, it\n\t\t\t * will fail the match below automatically and cause goto fail.\n\t\t\t */\n#if 0\n\t\t\tif (c2 < 0) {\n\t\t\t\tgoto fail;\n\t\t\t}\n#endif\n\t\t\tDUK_ASSERT(c1 >= 0);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"char match, c1=%ld, c2=%ld\", (long) c1, (long) c2));\n\t\t\tif (c1 != c2) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_PERIOD: {\n\t\t\tduk_codepoint_t c;\n\n\t\t\tc = duk__inp_get_cp(re_ctx, &sp);\n\t\t\tif (c < 0 || duk_unicode_is_line_terminator(c)) {\n\t\t\t\t/* E5 Sections 15.10.2.8, 7.3 */\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_RANGES:\n\t\tcase DUK_REOP_INVRANGES: {\n\t\t\tduk_uint32_t n;\n\t\t\tduk_codepoint_t c;\n\t\t\tduk_small_int_t match;\n\n\t\t\tn = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tc = duk__inp_get_cp(re_ctx, &sp);\n\t\t\tif (c < 0) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\n\t\t\tmatch = 0;\n\t\t\twhile (n) {\n\t\t\t\tduk_codepoint_t r1, r2;\n\t\t\t\tr1 = (duk_codepoint_t) duk__bc_get_u32(re_ctx, &pc);\n\t\t\t\tr2 = (duk_codepoint_t) duk__bc_get_u32(re_ctx, &pc);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"matching ranges/invranges, n=%ld, r1=%ld, r2=%ld, c=%ld\",\n\t\t\t\t                     (long) n, (long) r1, (long) r2, (long) c));\n\t\t\t\tif (c >= r1 && c <= r2) {\n\t\t\t\t\t/* Note: don't bail out early, we must read all the ranges from\n\t\t\t\t\t * bytecode.  Another option is to skip them efficiently after\n\t\t\t\t\t * breaking out of here.  Prefer smallest code.\n\t\t\t\t\t */\n\t\t\t\t\tmatch = 1;\n\t\t\t\t}\n\t\t\t\tn--;\n\t\t\t}\n\n\t\t\tif (op == DUK_REOP_RANGES) {\n\t\t\t\tif (!match) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(op == DUK_REOP_INVRANGES);\n\t\t\t\tif (match) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_ASSERT_START: {\n\t\t\tduk_codepoint_t c;\n\n\t\t\tif (sp <= re_ctx->input) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!(re_ctx->re_flags & DUK_RE_FLAG_MULTILINE)) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tc = duk__inp_get_prev_cp(re_ctx, sp);\n\t\t\tif (duk_unicode_is_line_terminator(c)) {\n\t\t\t\t/* E5 Sections 15.10.2.8, 7.3 */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_ASSERT_END: {\n\t\t\tduk_codepoint_t c;\n\t\t\tconst duk_uint8_t *tmp_sp;\n\n\t\t\ttmp_sp = sp;\n\t\t\tc = duk__inp_get_cp(re_ctx, &tmp_sp);\n\t\t\tif (c < 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!(re_ctx->re_flags & DUK_RE_FLAG_MULTILINE)) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tif (duk_unicode_is_line_terminator(c)) {\n\t\t\t\t/* E5 Sections 15.10.2.8, 7.3 */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_ASSERT_WORD_BOUNDARY:\n\t\tcase DUK_REOP_ASSERT_NOT_WORD_BOUNDARY: {\n\t\t\t/*\n\t\t\t *  E5 Section 15.10.2.6.  The previous and current character\n\t\t\t *  should -not- be canonicalized as they are now.  However,\n\t\t\t *  canonicalization does not affect the result of IsWordChar()\n\t\t\t *  (which depends on Unicode characters never canonicalizing\n\t\t\t *  into ASCII characters) so this does not matter.\n\t\t\t */\n\t\t\tduk_small_int_t w1, w2;\n\n\t\t\tif (sp <= re_ctx->input) {\n\t\t\t\tw1 = 0;  /* not a wordchar */\n\t\t\t} else {\n\t\t\t\tduk_codepoint_t c;\n\t\t\t\tc = duk__inp_get_prev_cp(re_ctx, sp);\n\t\t\t\tw1 = duk_unicode_re_is_wordchar(c);\n\t\t\t}\n\t\t\tif (sp >= re_ctx->input_end) {\n\t\t\t\tw2 = 0;  /* not a wordchar */\n\t\t\t} else {\n\t\t\t\tconst duk_uint8_t *tmp_sp = sp;  /* dummy so sp won't get updated */\n\t\t\t\tduk_codepoint_t c;\n\t\t\t\tc = duk__inp_get_cp(re_ctx, &tmp_sp);\n\t\t\t\tw2 = duk_unicode_re_is_wordchar(c);\n\t\t\t}\n\n\t\t\tif (op == DUK_REOP_ASSERT_WORD_BOUNDARY) {\n\t\t\t\tif (w1 == w2) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(op == DUK_REOP_ASSERT_NOT_WORD_BOUNDARY);\n\t\t\t\tif (w1 != w2) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_JUMP: {\n\t\t\tduk_int32_t skip;\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tpc += skip;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_SPLIT1: {\n\t\t\t/* split1: prefer direct execution (no jump) */\n\t\t\tconst duk_uint8_t *sub_sp;\n\t\t\tduk_int32_t skip;\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\t\t\tpc += skip;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_SPLIT2: {\n\t\t\t/* split2: prefer jump execution (not direct) */\n\t\t\tconst duk_uint8_t *sub_sp;\n\t\t\tduk_int32_t skip;\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_SQMINIMAL: {\n\t\t\tduk_uint32_t q, qmin, qmax;\n\t\t\tduk_int32_t skip;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tqmin = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tqmax = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"minimal quantifier, qmin=%lu, qmax=%lu, skip=%ld\",\n\t\t\t                     (unsigned long) qmin, (unsigned long) qmax, (long) skip));\n\n\t\t\tq = 0;\n\t\t\twhile (q <= qmax) {\n\t\t\t\tif (q >= qmin) {\n\t\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\t\t\tif (sub_sp) {\n\t\t\t\t\t\tsp = sub_sp;\n\t\t\t\t\t\tgoto match;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\t\tif (!sub_sp) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tsp = sub_sp;\n\t\t\t\tq++;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_SQGREEDY: {\n\t\t\tduk_uint32_t q, qmin, qmax, atomlen;\n\t\t\tduk_int32_t skip;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tqmin = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tqmax = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tatomlen = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"greedy quantifier, qmin=%lu, qmax=%lu, atomlen=%lu, skip=%ld\",\n\t\t\t                     (unsigned long) qmin, (unsigned long) qmax, (unsigned long) atomlen, (long) skip));\n\n\t\t\tq = 0;\n\t\t\twhile (q < qmax) {\n\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\t\tif (!sub_sp) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tsp = sub_sp;\n\t\t\t\tq++;\n\t\t\t}\n\t\t\twhile (q >= qmin) {\n\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\t\tif (sub_sp) {\n\t\t\t\t\tsp = sub_sp;\n\t\t\t\t\tgoto match;\n\t\t\t\t}\n\t\t\t\tif (q == qmin) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t/* Note: if atom were to contain e.g. captures, we would need to\n\t\t\t\t * re-match the atom to get correct captures.  Simply quantifiers\n\t\t\t\t * do not allow captures in their atom now, so this is not an issue.\n\t\t\t\t */\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"greedy quantifier, backtrack %ld characters (atomlen)\",\n\t\t\t\t                     (long) atomlen));\n\t\t\t\tsp = duk__inp_backtrack(re_ctx, &sp, (duk_uint_fast32_t) atomlen);\n\t\t\t\tq--;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_SAVE: {\n\t\t\tduk_uint32_t idx;\n\t\t\tconst duk_uint8_t *old;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tidx = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tif (idx >= re_ctx->nsaved) {\n\t\t\t\t/* idx is unsigned, < 0 check is not necessary */\n\t\t\t\tDUK_D(DUK_DPRINT(\"internal error, regexp save index insane: idx=%ld\", (long) idx));\n\t\t\t\tgoto internal_error;\n\t\t\t}\n\t\t\told = re_ctx->saved[idx];\n\t\t\tre_ctx->saved[idx] = sp;\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\t\t\tre_ctx->saved[idx] = old;\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_WIPERANGE: {\n\t\t\t/* Wipe capture range and save old values for backtracking.\n\t\t\t *\n\t\t\t * XXX: this typically happens with a relatively small idx_count.\n\t\t\t * It might be useful to handle cases where the count is small\n\t\t\t * (say <= 8) by saving the values in stack instead.  This would\n\t\t\t * reduce memory churn and improve performance, at the cost of a\n\t\t\t * slightly higher code footprint.\n\t\t\t */\n\t\t\tduk_uint32_t idx_start, idx_count;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\t\tduk_uint32_t idx_end, idx;\n#endif\n\t\t\tduk_uint8_t **range_save;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tidx_start = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tidx_count = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"wipe saved range: start=%ld, count=%ld -> [%ld,%ld] (captures [%ld,%ld])\",\n\t\t\t                     (long) idx_start, (long) idx_count,\n\t\t\t                     (long) idx_start, (long) (idx_start + idx_count - 1),\n\t\t\t                     (long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2)));\n\t\t\tif (idx_start + idx_count > re_ctx->nsaved || idx_count == 0) {\n\t\t\t\t/* idx is unsigned, < 0 check is not necessary */\n\t\t\t\tDUK_D(DUK_DPRINT(\"internal error, regexp wipe indices insane: idx_start=%ld, idx_count=%ld\",\n\t\t\t\t                 (long) idx_start, (long) idx_count));\n\t\t\t\tgoto internal_error;\n\t\t\t}\n\t\t\tDUK_ASSERT(idx_count > 0);\n\n\t\t\tduk_require_stack(re_ctx->thr, 1);\n\t\t\trange_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero(re_ctx->thr,\n\t\t\t                                                           sizeof(duk_uint8_t *) * idx_count);\n\t\t\tDUK_ASSERT(range_save != NULL);\n\t\t\tduk_memcpy(range_save, re_ctx->saved + idx_start, sizeof(duk_uint8_t *) * idx_count);\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\t\tidx_end = idx_start + idx_count;\n\t\t\tfor (idx = idx_start; idx < idx_end; idx++) {\n\t\t\t\tre_ctx->saved[idx] = NULL;\n\t\t\t}\n#else\n\t\t\tduk_memzero((void *) (re_ctx->saved + idx_start), sizeof(duk_uint8_t *) * idx_count);\n#endif\n\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\t/* match: keep wiped/resaved values */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"match: keep wiped/resaved values [%ld,%ld] (captures [%ld,%ld])\",\n\t\t\t\t                     (long) idx_start, (long) (idx_start + idx_count - 1),\n\t\t\t                             (long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2)));\n\t\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\n\t\t\t/* fail: restore saves */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fail: restore wiped/resaved values [%ld,%ld] (captures [%ld,%ld])\",\n\t\t\t                     (long) idx_start, (long) (idx_start + idx_count - 1),\n\t\t\t                     (long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2)));\n\t\t\tduk_memcpy((void *) (re_ctx->saved + idx_start),\n\t\t\t           (const void *) range_save,\n\t\t\t           sizeof(duk_uint8_t *) * idx_count);\n\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_LOOKPOS:\n\t\tcase DUK_REOP_LOOKNEG: {\n\t\t\t/*\n\t\t\t *  Needs a save of multiple saved[] entries depending on what range\n\t\t\t *  may be overwritten.  Because the regexp parser does no such analysis,\n\t\t\t *  we currently save the entire saved array here.  Lookaheads are thus\n\t\t\t *  a bit expensive.  Note that the saved array is not needed for just\n\t\t\t *  the lookahead sub-match, but for the matching of the entire sequel.\n\t\t\t *\n\t\t\t *  The temporary save buffer is pushed on to the valstack to handle\n\t\t\t *  errors correctly.  Each lookahead causes a C recursion and pushes\n\t\t\t *  more stuff on the value stack.  If the C recursion limit is less\n\t\t\t *  than the value stack slack, there is no need to check the stack.\n\t\t\t *  We do so regardless, just in case.\n\t\t\t */\n\n\t\t\tduk_int32_t skip;\n\t\t\tduk_uint8_t **full_save;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tDUK_ASSERT(re_ctx->nsaved > 0);\n\n\t\t\tduk_require_stack(re_ctx->thr, 1);\n\t\t\tfull_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero(re_ctx->thr,\n\t\t\t                                                          sizeof(duk_uint8_t *) * re_ctx->nsaved);\n\t\t\tDUK_ASSERT(full_save != NULL);\n\t\t\tduk_memcpy(full_save, re_ctx->saved, sizeof(duk_uint8_t *) * re_ctx->nsaved);\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (op == DUK_REOP_LOOKPOS) {\n\t\t\t\tif (!sub_sp) {\n\t\t\t\t\tgoto lookahead_fail;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (sub_sp) {\n\t\t\t\t\tgoto lookahead_fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\t/* match: keep saves */\n\t\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\n\t\t\t/* fall through */\n\n\t\t lookahead_fail:\n\t\t\t/* fail: restore saves */\n\t\t\tduk_memcpy((void *) re_ctx->saved,\n\t\t\t           (const void *) full_save,\n\t\t\t           sizeof(duk_uint8_t *) * re_ctx->nsaved);\n\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_BACKREFERENCE: {\n\t\t\t/*\n\t\t\t *  Byte matching for back-references would be OK in case-\n\t\t\t *  sensitive matching.  In case-insensitive matching we need\n\t\t\t *  to canonicalize characters, so back-reference matching needs\n\t\t\t *  to be done with codepoints instead.  So, we just decode\n\t\t\t *  everything normally here, too.\n\t\t\t *\n\t\t\t *  Note: back-reference index which is 0 or higher than\n\t\t\t *  NCapturingParens (= number of capturing parens in the\n\t\t\t *  -entire- regexp) is a compile time error.  However, a\n\t\t\t *  backreference referring to a valid capture which has\n\t\t\t *  not matched anything always succeeds!  See E5 Section\n\t\t\t *  15.10.2.9, step 5, sub-step 3.\n\t\t\t */\n\t\t\tduk_uint32_t idx;\n\t\t\tconst duk_uint8_t *p;\n\n\t\t\tidx = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tidx = idx << 1;  /* backref n -> saved indices [n*2, n*2+1] */\n\t\t\tif (idx < 2 || idx + 1 >= re_ctx->nsaved) {\n\t\t\t\t/* regexp compiler should catch these */\n\t\t\t\tDUK_D(DUK_DPRINT(\"internal error, backreference index insane\"));\n\t\t\t\tgoto internal_error;\n\t\t\t}\n\t\t\tif (!re_ctx->saved[idx] || !re_ctx->saved[idx+1]) {\n\t\t\t\t/* capture is 'undefined', always matches! */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"backreference: saved[%ld,%ld] not complete, always match\",\n\t\t\t\t                     (long) idx, (long) (idx + 1)));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"backreference: match saved[%ld,%ld]\", (long) idx, (long) (idx + 1)));\n\n\t\t\tp = re_ctx->saved[idx];\n\t\t\twhile (p < re_ctx->saved[idx+1]) {\n\t\t\t\tduk_codepoint_t c1, c2;\n\n\t\t\t\t/* Note: not necessary to check p against re_ctx->input_end:\n\t\t\t\t * the memory access is checked by duk__inp_get_cp(), while\n\t\t\t\t * valid compiled regexps cannot write a saved[] entry\n\t\t\t\t * which points to outside the string.\n\t\t\t\t */\n\t\t\t\tc1 = duk__inp_get_cp(re_ctx, &p);\n\t\t\t\tDUK_ASSERT(c1 >= 0);\n\t\t\t\tc2 = duk__inp_get_cp(re_ctx, &sp);\n\t\t\t\t/* No need for an explicit c2 < 0 check: because c1 >= 0,\n\t\t\t\t * the comparison will always fail if c2 < 0.\n\t\t\t\t */\n#if 0\n\t\t\t\tif (c2 < 0) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n#endif\n\t\t\t\tif (c1 != c2) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tDUK_D(DUK_DPRINT(\"internal error, regexp opcode error: %ld\", (long) op));\n\t\t\tgoto internal_error;\n\t\t}\n\t\t}\n\t}\n\n match:\n\tre_ctx->recursion_depth--;\n\treturn sp;\n\n fail:\n\tre_ctx->recursion_depth--;\n\treturn NULL;\n\n internal_error:\n\tDUK_ERROR_INTERNAL(re_ctx->thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Exposed matcher function which provides the semantics of RegExp.prototype.exec().\n *\n *  RegExp.prototype.test() has the same semantics as exec() but does not return the\n *  result object (which contains the matching string and capture groups).  Currently\n *  there is no separate test() helper, so a temporary result object is created and\n *  discarded if test() is needed.  This is intentional, to save code space.\n *\n *  Input stack:  [ ... re_obj input ]\n *  Output stack: [ ... result ]\n */\n\nDUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_global) {\n\tduk_re_matcher_ctx re_ctx;\n\tduk_hobject *h_regexp;\n\tduk_hstring *h_bytecode;\n\tduk_hstring *h_input;\n\tduk_uint8_t *p_buf;\n\tconst duk_uint8_t *pc;\n\tconst duk_uint8_t *sp;\n\tduk_small_int_t match = 0;\n\tduk_small_int_t global;\n\tduk_uint_fast32_t i;\n\tdouble d;\n\tduk_uint32_t char_offset;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"regexp match: regexp=%!T, input=%!T\",\n\t                   (duk_tval *) duk_get_tval(thr, -2),\n\t                   (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/*\n\t *  Regexp instance check, bytecode check, input coercion.\n\t *\n\t *  See E5 Section 15.10.6.\n\t */\n\n\t/* TypeError if wrong; class check, see E5 Section 15.10.6 */\n\th_regexp = duk_require_hobject_with_class(thr, -2, DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_ASSERT(h_regexp != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_regexp) == DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_UNREF(h_regexp);\n\n\th_input = duk_to_hstring(thr, -1);\n\tDUK_ASSERT(h_input != NULL);\n\n\tduk_xget_owndataprop_stridx_short(thr, -2, DUK_STRIDX_INT_BYTECODE);  /* [ ... re_obj input ] -> [ ... re_obj input bc ] */\n\th_bytecode = duk_require_hstring(thr, -1);  /* no regexp instance should exist without a non-configurable bytecode property */\n\tDUK_ASSERT(h_bytecode != NULL);\n\n\t/*\n\t *  Basic context initialization.\n\t *\n\t *  Some init values are read from the bytecode header\n\t *  whose format is (UTF-8 codepoints):\n\t *\n\t *    uint   flags\n\t *    uint   nsaved (even, 2n+2 where n = num captures)\n\t */\n\n\t/* [ ... re_obj input bc ] */\n\n\tduk_memzero(&re_ctx, sizeof(re_ctx));\n\n\tre_ctx.thr = thr;\n\tre_ctx.input = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tre_ctx.input_end = re_ctx.input + DUK_HSTRING_GET_BYTELEN(h_input);\n\tre_ctx.bytecode = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_bytecode);\n\tre_ctx.bytecode_end = re_ctx.bytecode + DUK_HSTRING_GET_BYTELEN(h_bytecode);\n\tre_ctx.saved = NULL;\n\tre_ctx.recursion_limit = DUK_USE_REGEXP_EXECUTOR_RECLIMIT;\n\tre_ctx.steps_limit = DUK_RE_EXECUTE_STEPS_LIMIT;\n\n\t/* read header */\n\tpc = re_ctx.bytecode;\n\tre_ctx.re_flags = duk__bc_get_u32(&re_ctx, &pc);\n\tre_ctx.nsaved = duk__bc_get_u32(&re_ctx, &pc);\n\tre_ctx.bytecode = pc;\n\n\tDUK_ASSERT(DUK_RE_FLAG_GLOBAL < 0x10000UL);  /* must fit into duk_small_int_t */\n\tglobal = (duk_small_int_t) (force_global | (duk_small_int_t) (re_ctx.re_flags & DUK_RE_FLAG_GLOBAL));\n\n\tDUK_ASSERT(re_ctx.nsaved >= 2);\n\tDUK_ASSERT((re_ctx.nsaved % 2) == 0);\n\n\tp_buf = (duk_uint8_t *) duk_push_fixed_buffer(thr, sizeof(duk_uint8_t *) * re_ctx.nsaved);  /* rely on zeroing */\n\tDUK_UNREF(p_buf);\n\tre_ctx.saved = (const duk_uint8_t **) duk_get_buffer(thr, -1, NULL);\n\tDUK_ASSERT(re_ctx.saved != NULL);\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tfor (i = 0; i < re_ctx.nsaved; i++) {\n\t\tre_ctx.saved[i] = (duk_uint8_t *) NULL;\n\t}\n#elif defined(DUK_USE_ZERO_BUFFER_DATA)\n\t/* buffer is automatically zeroed */\n#else\n\tduk_memzero((void *) p_buf, sizeof(duk_uint8_t *) * re_ctx.nsaved);\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"regexp ctx initialized, flags=0x%08lx, nsaved=%ld, recursion_limit=%ld, steps_limit=%ld\",\n\t                     (unsigned long) re_ctx.re_flags, (long) re_ctx.nsaved, (long) re_ctx.recursion_limit,\n\t                     (long) re_ctx.steps_limit));\n\n\t/*\n\t *  Get starting character offset for match, and initialize 'sp' based on it.\n\t *\n\t *  Note: lastIndex is non-configurable so it must be present (we check the\n\t *  internal class of the object above, so we know it is).  User code can set\n\t *  its value to an arbitrary (garbage) value though; E5 requires that lastIndex\n\t *  be coerced to a number before using.  The code below works even if the\n\t *  property is missing: the value will then be coerced to zero.\n\t *\n\t *  Note: lastIndex may be outside Uint32 range even after ToInteger() coercion.\n\t *  For instance, ToInteger(+Infinity) = +Infinity.  We track the match offset\n\t *  as an integer, but pre-check it to be inside the 32-bit range before the loop.\n\t *  If not, the check in E5 Section 15.10.6.2, step 9.a applies.\n\t */\n\n\t/* XXX: lastIndex handling produces a lot of asm */\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n\tduk_get_prop_stridx_short(thr, -4, DUK_STRIDX_LAST_INDEX);  /* -> [ ... re_obj input bc saved_buf lastIndex ] */\n\t(void) duk_to_int(thr, -1);  /* ToInteger(lastIndex) */\n\td = duk_get_number(thr, -1);  /* integer, but may be +/- Infinite, +/- zero (not NaN, though) */\n\tduk_pop_nodecref_unsafe(thr);\n\n\tif (global) {\n\t\tif (d < 0.0 || d > (double) DUK_HSTRING_GET_CHARLEN(h_input)) {\n\t\t\t/* match fail */\n\t\t\tchar_offset = 0;   /* not really necessary */\n\t\t\tDUK_ASSERT(match == 0);\n\t\t\tgoto match_over;\n\t\t}\n\t\tchar_offset = (duk_uint32_t) d;\n\t} else {\n\t\t/* lastIndex must be ignored for non-global regexps, but get the\n\t\t * value for (theoretical) side effects.  No side effects can\n\t\t * really occur, because lastIndex is a normal property and is\n\t\t * always non-configurable for RegExp instances.\n\t\t */\n\t\tchar_offset = (duk_uint32_t) 0;\n\t}\n\n\tDUK_ASSERT(char_offset <= DUK_HSTRING_GET_CHARLEN(h_input));\n\tsp = re_ctx.input + duk_heap_strcache_offset_char2byte(thr, h_input, char_offset);\n\n\t/*\n\t *  Match loop.\n\t *\n\t *  Try matching at different offsets until match found or input exhausted.\n\t */\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n\tDUK_ASSERT(match == 0);\n\n\tfor (;;) {\n\t\t/* char offset in [0, h_input->clen] (both ends inclusive), checked before entry */\n\t\tDUK_ASSERT_DISABLE(char_offset >= 0);\n\t\tDUK_ASSERT(char_offset <= DUK_HSTRING_GET_CHARLEN(h_input));\n\n\t\t/* Note: re_ctx.steps is intentionally not reset, it applies to the entire unanchored match */\n\t\tDUK_ASSERT(re_ctx.recursion_depth == 0);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"attempt match at char offset %ld; %p [%p,%p]\",\n\t\t                     (long) char_offset, (const void *) sp,\n\t\t                     (const void *) re_ctx.input, (const void *) re_ctx.input_end));\n\n\t\t/*\n\t\t *  Note:\n\t\t *\n\t\t *    - duk__match_regexp() is required not to longjmp() in ordinary \"non-match\"\n\t\t *      conditions; a longjmp() will terminate the entire matching process.\n\t\t *\n\t\t *    - Clearing saved[] is not necessary because backtracking does it\n\t\t *\n\t\t *    - Backtracking also rewinds re_ctx.recursion back to zero, unless an\n\t\t *      internal/limit error occurs (which causes a longjmp())\n\t\t *\n\t\t *    - If we supported anchored matches, we would break out here\n\t\t *      unconditionally; however, ECMAScript regexps don't have anchored\n\t\t *      matches.  It might make sense to implement a fast bail-out if\n\t\t *      the regexp begins with '^' and sp is not 0: currently we'll just\n\t\t *      run through the entire input string, trivially failing the match\n\t\t *      at every non-zero offset.\n\t\t */\n\n\t\tif (duk__match_regexp(&re_ctx, re_ctx.bytecode, sp) != NULL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"match at offset %ld\", (long) char_offset));\n\t\t\tmatch = 1;\n\t\t\tbreak;\n\t\t}\n\n\t\t/* advance by one character (code point) and one char_offset */\n\t\tchar_offset++;\n\t\tif (char_offset > DUK_HSTRING_GET_CHARLEN(h_input)) {\n\t\t\t/*\n\t\t\t *  Note:\n\t\t\t *\n\t\t\t *    - Intentionally attempt (empty) match at char_offset == k_input->clen\n\t\t\t *\n\t\t\t *    - Negative char_offsets have been eliminated and char_offset is duk_uint32_t\n\t\t\t *      -> no need or use for a negative check\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"no match after trying all sp offsets\"));\n\t\t\tbreak;\n\t\t}\n\n\t\t/* avoid calling at end of input, will DUK_ERROR (above check suffices to avoid this) */\n\t\t(void) duk__utf8_advance(thr, &sp, re_ctx.input, re_ctx.input_end, (duk_uint_fast32_t) 1);\n\t}\n\n match_over:\n\n\t/*\n\t *  Matching complete, create result array or return a 'null'.  Update lastIndex\n\t *  if necessary.  See E5 Section 15.10.6.2.\n\t *\n\t *  Because lastIndex is a character (not byte) offset, we need the character\n\t *  length of the match which we conveniently get as a side effect of interning\n\t *  the matching substring (0th index of result array).\n\t *\n\t *  saved[0]         start pointer (~ byte offset) of current match\n\t *  saved[1]         end pointer (~ byte offset) of current match (exclusive)\n\t *  char_offset      start character offset of current match (-> .index of result)\n\t *  char_end_offset  end character offset (computed below)\n\t */\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n\tif (match) {\n#if defined(DUK_USE_ASSERTIONS)\n\t\tduk_hobject *h_res;\n#endif\n\t\tduk_uint32_t char_end_offset = 0;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"regexp matches at char_offset %ld\", (long) char_offset));\n\n\t\tDUK_ASSERT(re_ctx.nsaved >= 2);        /* must have start and end */\n\t\tDUK_ASSERT((re_ctx.nsaved % 2) == 0);  /* and even number */\n\n\t\t/* XXX: Array size is known before and (2 * re_ctx.nsaved) but not taken\n\t\t * advantage of now.  The array is not compacted either, as regexp match\n\t\t * objects are usually short lived.\n\t\t */\n\n\t\tduk_push_array(thr);\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\th_res = duk_require_hobject(thr, -1);\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_res));\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(h_res));\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_res) == DUK_HOBJECT_CLASS_ARRAY);\n#endif\n\n\t\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\t\tduk_push_u32(thr, char_offset);\n\t\tduk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INDEX);\n\n\t\tduk_dup_m4(thr);\n\t\tduk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INPUT);\n\n\t\tfor (i = 0; i < re_ctx.nsaved; i += 2) {\n\t\t\t/* Captures which are undefined have NULL pointers and are returned\n\t\t\t * as 'undefined'.  The same is done when saved[] pointers are insane\n\t\t\t * (this should, of course, never happen in practice).\n\t\t\t */\n\t\t\tif (re_ctx.saved[i] && re_ctx.saved[i + 1] && re_ctx.saved[i + 1] >= re_ctx.saved[i]) {\n\t\t\t\tduk_push_lstring(thr,\n\t\t\t\t                 (const char *) re_ctx.saved[i],\n\t\t\t\t                 (duk_size_t) (re_ctx.saved[i+1] - re_ctx.saved[i]));\n\t\t\t\tif (i == 0) {\n\t\t\t\t\t/* Assumes that saved[0] and saved[1] are always\n\t\t\t\t\t * set by regexp bytecode (if not, char_end_offset\n\t\t\t\t\t * will be zero).  Also assumes clen reflects the\n\t\t\t\t\t * correct char length.\n\t\t\t\t\t */\n\t\t\t\t\tchar_end_offset = char_offset + (duk_uint32_t) duk_get_length(thr, -1);  /* add charlen */\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t}\n\n\t\t\t/* [ ... re_obj input bc saved_buf res_obj val ] */\n\t\t\tduk_put_prop_index(thr, -2, (duk_uarridx_t) (i / 2));\n\t\t}\n\n\t\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\t\t/* NB: 'length' property is automatically updated by the array setup loop */\n\n\t\tif (global) {\n\t\t\t/* global regexp: lastIndex updated on match */\n\t\t\tduk_push_u32(thr, char_end_offset);\n\t\t\tduk_put_prop_stridx_short(thr, -6, DUK_STRIDX_LAST_INDEX);\n\t\t} else {\n\t\t\t/* non-global regexp: lastIndex never updated on match */\n\t\t\t;\n\t\t}\n\t} else {\n\t\t/*\n\t\t *  No match, E5 Section 15.10.6.2, step 9.a.i - 9.a.ii apply, regardless\n\t\t *  of 'global' flag of the RegExp.  In particular, if lastIndex is invalid\n\t\t *  initially, it is reset to zero.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"regexp does not match\"));\n\n\t\tduk_push_null(thr);\n\n\t\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\t\tduk_push_int(thr, 0);\n\t\tduk_put_prop_stridx_short(thr, -6, DUK_STRIDX_LAST_INDEX);\n\t}\n\n\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\tduk_insert(thr, -5);\n\n\t/* [ ... res_obj re_obj input bc saved_buf ] */\n\n\tduk_pop_n_unsafe(thr, 4);\n\n\t/* [ ... res_obj ] */\n\n\t/* XXX: these last tricks are unnecessary if the function is made\n\t * a genuine native function.\n\t */\n}\n\nDUK_INTERNAL void duk_regexp_match(duk_hthread *thr) {\n\tduk__regexp_match_helper(thr, 0 /*force_global*/);\n}\n\n/* This variant is needed by String.prototype.split(); it needs to perform\n * global-style matching on a cloned RegExp which is potentially non-global.\n */\nDUK_INTERNAL void duk_regexp_match_force_global(duk_hthread *thr) {\n\tduk__regexp_match_helper(thr, 1 /*force_global*/);\n}\n\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\n/* regexp support disabled */\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n/*\n *  Self tests to ensure execution environment is sane.  Intended to catch\n *  compiler/platform problems which cannot be detected at compile time.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_SELF_TESTS)\n\n/*\n *  Unions and structs for self tests\n */\n\ntypedef union {\n\tdouble d;\n\tduk_uint8_t x[8];\n} duk__test_double_union;\n\n/* Self test failed.  Expects a local variable 'error_count' to exist. */\n#define DUK__FAILED(msg)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"self test failed: \" #msg \" at \" DUK_FILE_MACRO \":\" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO))); \\\n\t\terror_count++; \\\n\t} while (0)\n\n#define DUK__DBLUNION_CMP_TRUE(a,b)  do { \\\n\t\tif (duk_memcmp((const void *) (a), (const void *) (b), sizeof(duk__test_double_union)) != 0) { \\\n\t\t\tDUK__FAILED(\"double union compares false (expected true)\"); \\\n\t\t} \\\n\t} while (0)\n\n#define DUK__DBLUNION_CMP_FALSE(a,b)  do { \\\n\t\tif (duk_memcmp((const void *) (a), (const void *) (b), sizeof(duk__test_double_union)) == 0) { \\\n\t\t\tDUK__FAILED(\"double union compares true (expected false)\"); \\\n\t\t} \\\n\t} while (0)\n\ntypedef union {\n\tduk_uint32_t i;\n\tduk_uint8_t x[8];\n} duk__test_u32_union;\n\n#if defined(DUK_USE_INTEGER_LE)\n#define DUK__U32_INIT(u, a, b, c, d) do { \\\n\t\t(u)->x[0] = (d); (u)->x[1] = (c); (u)->x[2] = (b); (u)->x[3] = (a); \\\n\t} while (0)\n#elif defined(DUK_USE_INTEGER_ME)\n#error integer mixed endian not supported now\n#elif defined(DUK_USE_INTEGER_BE)\n#define DUK__U32_INIT(u, a, b, c, d) do { \\\n\t\t(u)->x[0] = (a); (u)->x[1] = (b); (u)->x[2] = (c); (u)->x[3] = (d); \\\n\t} while (0)\n#else\n#error unknown integer endianness\n#endif\n\n#if defined(DUK_USE_DOUBLE_LE)\n#define DUK__DOUBLE_INIT(u, a, b, c, d, e, f, g, h) do { \\\n\t\t(u)->x[0] = (h); (u)->x[1] = (g); (u)->x[2] = (f); (u)->x[3] = (e); \\\n\t\t(u)->x[4] = (d); (u)->x[5] = (c); (u)->x[6] = (b); (u)->x[7] = (a); \\\n\t} while (0)\n#define DUK__DOUBLE_COMPARE(u, a, b, c, d, e, f, g, h) \\\n\t((u)->x[0] == (h) && (u)->x[1] == (g) && (u)->x[2] == (f) && (u)->x[3] == (e) && \\\n\t (u)->x[4] == (d) && (u)->x[5] == (c) && (u)->x[6] == (b) && (u)->x[7] == (a))\n#elif defined(DUK_USE_DOUBLE_ME)\n#define DUK__DOUBLE_INIT(u, a, b, c, d, e, f, g, h) do { \\\n\t\t(u)->x[0] = (d); (u)->x[1] = (c); (u)->x[2] = (b); (u)->x[3] = (a); \\\n\t\t(u)->x[4] = (h); (u)->x[5] = (g); (u)->x[6] = (f); (u)->x[7] = (e); \\\n\t} while (0)\n#define DUK__DOUBLE_COMPARE(u, a, b, c, d, e, f, g, h) \\\n\t((u)->x[0] == (d) && (u)->x[1] == (c) && (u)->x[2] == (b) && (u)->x[3] == (a) && \\\n\t (u)->x[4] == (h) && (u)->x[5] == (g) && (u)->x[6] == (f) && (u)->x[7] == (e))\n#elif defined(DUK_USE_DOUBLE_BE)\n#define DUK__DOUBLE_INIT(u, a, b, c, d, e, f, g, h) do { \\\n\t\t(u)->x[0] = (a); (u)->x[1] = (b); (u)->x[2] = (c); (u)->x[3] = (d); \\\n\t\t(u)->x[4] = (e); (u)->x[5] = (f); (u)->x[6] = (g); (u)->x[7] = (h); \\\n\t} while (0)\n#define DUK__DOUBLE_COMPARE(u, a, b, c, d, e, f, g, h) \\\n\t((u)->x[0] == (a) && (u)->x[1] == (b) && (u)->x[2] == (c) && (u)->x[3] == (d) && \\\n\t (u)->x[4] == (e) && (u)->x[5] == (f) && (u)->x[6] == (g) && (u)->x[7] == (h))\n#else\n#error unknown double endianness\n#endif\n\n/*\n *  Various sanity checks for typing\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_types(void) {\n\tduk_uint_t error_count = 0;\n\n\tif (!(sizeof(duk_int8_t) == 1 &&\n\t      sizeof(duk_uint8_t) == 1 &&\n\t      sizeof(duk_int16_t) == 2 &&\n\t      sizeof(duk_uint16_t) == 2 &&\n\t      sizeof(duk_int32_t) == 4 &&\n\t      sizeof(duk_uint32_t) == 4)) {\n\t\tDUK__FAILED(\"duk_(u)int{8,16,32}_t size\");\n\t}\n#if defined(DUK_USE_64BIT_OPS)\n\tif (!(sizeof(duk_int64_t) == 8 &&\n\t      sizeof(duk_uint64_t) == 8)) {\n\t\tDUK__FAILED(\"duk_(u)int64_t size\");\n\t}\n#endif\n\n\tif (!(sizeof(duk_size_t) >= sizeof(duk_uint_t))) {\n\t\t/* Some internal code now assumes that all duk_uint_t values\n\t\t * can be expressed with a duk_size_t.\n\t\t */\n\t\tDUK__FAILED(\"duk_size_t is smaller than duk_uint_t\");\n\t}\n\tif (!(sizeof(duk_int_t) >= 4)) {\n\t\tDUK__FAILED(\"duk_int_t is not 32 bits\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Packed tval sanity\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_packed_tval(void) {\n\tduk_uint_t error_count = 0;\n\n#if defined(DUK_USE_PACKED_TVAL)\n\tif (sizeof(void *) > 4) {\n\t\tDUK__FAILED(\"packed duk_tval in use but sizeof(void *) > 4\");\n\t}\n#endif\n\n\treturn error_count;\n}\n\n/*\n *  Two's complement arithmetic.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_twos_complement(void) {\n\tduk_uint_t error_count = 0;\n\tvolatile int test;\n\ttest = -1;\n\n\t/* Note that byte order doesn't affect this test: all bytes in\n\t * 'test' will be 0xFF for two's complement.\n\t */\n\tif (((volatile duk_uint8_t *) &test)[0] != (duk_uint8_t) 0xff) {\n\t\tDUK__FAILED(\"two's complement arithmetic\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Byte order.  Important to self check, because on some exotic platforms\n *  there is no actual detection but rather assumption based on platform\n *  defines.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_byte_order(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_u32_union u1;\n\tduk__test_double_union u2;\n\n\t/*\n\t *  >>> struct.pack('>d', 102030405060).encode('hex')\n\t *  '4237c17c6dc40000'\n\t */\n\n\tDUK__U32_INIT(&u1, 0xde, 0xad, 0xbe, 0xef);\n\tDUK__DOUBLE_INIT(&u2, 0x42, 0x37, 0xc1, 0x7c, 0x6d, 0xc4, 0x00, 0x00);\n\n\tif (u1.i != (duk_uint32_t) 0xdeadbeefUL) {\n\t\tDUK__FAILED(\"duk_uint32_t byte order\");\n\t}\n\n\tif (u2.d != (double) 102030405060.0) {\n\t\tDUK__FAILED(\"double byte order\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  DUK_BSWAP macros\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_bswap_macros(void) {\n\tduk_uint_t error_count = 0;\n\tvolatile duk_uint32_t x32_input, x32_output;\n\tduk_uint32_t x32;\n\tvolatile duk_uint16_t x16_input, x16_output;\n\tduk_uint16_t x16;\n\tduk_double_union du;\n\tduk_double_t du_diff;\n#if defined(DUK_BSWAP64)\n\tvolatile duk_uint64_t x64_input, x64_output;\n\tduk_uint64_t x64;\n#endif\n\n\t/* Cover both compile time and runtime bswap operations, as these\n\t * may have different bugs.\n\t */\n\n\tx16_input = 0xbeefUL;\n\tx16 = x16_input;\n\tx16 = DUK_BSWAP16(x16);\n\tx16_output = x16;\n\tif (x16_output != (duk_uint16_t) 0xefbeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP16\");\n\t}\n\n\tx16 = 0xbeefUL;\n\tx16 = DUK_BSWAP16(x16);\n\tif (x16 != (duk_uint16_t) 0xefbeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP16\");\n\t}\n\n\tx32_input = 0xdeadbeefUL;\n\tx32 = x32_input;\n\tx32 = DUK_BSWAP32(x32);\n\tx32_output = x32;\n\tif (x32_output != (duk_uint32_t) 0xefbeaddeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP32\");\n\t}\n\n\tx32 = 0xdeadbeefUL;\n\tx32 = DUK_BSWAP32(x32);\n\tif (x32 != (duk_uint32_t) 0xefbeaddeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP32\");\n\t}\n\n#if defined(DUK_BSWAP64)\n\tx64_input = DUK_U64_CONSTANT(0x8899aabbccddeeff);\n\tx64 = x64_input;\n\tx64 = DUK_BSWAP64(x64);\n\tx64_output = x64;\n\tif (x64_output != (duk_uint64_t) DUK_U64_CONSTANT(0xffeeddccbbaa9988)) {\n\t\tDUK__FAILED(\"DUK_BSWAP64\");\n\t}\n\n\tx64 = DUK_U64_CONSTANT(0x8899aabbccddeeff);\n\tx64 = DUK_BSWAP64(x64);\n\tif (x64 != (duk_uint64_t) DUK_U64_CONSTANT(0xffeeddccbbaa9988)) {\n\t\tDUK__FAILED(\"DUK_BSWAP64\");\n\t}\n#endif\n\n\t/* >>> struct.unpack('>d', '4000112233445566'.decode('hex'))\n\t * (2.008366013071895,)\n\t */\n\n\tdu.uc[0] = 0x40; du.uc[1] = 0x00; du.uc[2] = 0x11; du.uc[3] = 0x22;\n\tdu.uc[4] = 0x33; du.uc[5] = 0x44; du.uc[6] = 0x55; du.uc[7] = 0x66;\n\tDUK_DBLUNION_DOUBLE_NTOH(&du);\n\tdu_diff = du.d - 2.008366013071895;\n#if 0\n\tDUK_D(DUK_DPRINT(\"du_diff: %lg\\n\", (double) du_diff));\n#endif\n\tif (du_diff > 1e-15) {\n\t\t/* Allow very small lenience because some compilers won't parse\n\t\t * exact IEEE double constants (happened in matrix testing with\n\t\t * Linux gcc-4.8 -m32 at least).\n\t\t */\n#if 0\n\t\tDUK_D(DUK_DPRINT(\"Result of DUK_DBLUNION_DOUBLE_NTOH: %02x %02x %02x %02x %02x %02x %02x %02x\\n\",\n\t\t            (unsigned int) du.uc[0], (unsigned int) du.uc[1],\n\t\t            (unsigned int) du.uc[2], (unsigned int) du.uc[3],\n\t\t            (unsigned int) du.uc[4], (unsigned int) du.uc[5],\n\t\t            (unsigned int) du.uc[6], (unsigned int) du.uc[7]));\n#endif\n\t\tDUK__FAILED(\"DUK_DBLUNION_DOUBLE_NTOH\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Basic double / byte union memory layout.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_union_size(void) {\n\tduk_uint_t error_count = 0;\n\n\tif (sizeof(duk__test_double_union) != 8) {\n\t\tDUK__FAILED(\"invalid union size\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Union aliasing, see misc/clang_aliasing.c.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_aliasing(void) {\n\t/* This testcase fails when Emscripten-generated code runs on Firefox.\n\t * It's not an issue because the failure should only affect packed\n\t * duk_tval representation, which is not used with Emscripten.\n\t */\n#if defined(DUK_USE_PACKED_TVAL)\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union a, b;\n\n\t/* Test signaling NaN and alias assignment in all endianness combinations.\n\t */\n\n\t/* little endian */\n\ta.x[0] = 0x11; a.x[1] = 0x22; a.x[2] = 0x33; a.x[3] = 0x44;\n\ta.x[4] = 0x00; a.x[5] = 0x00; a.x[6] = 0xf1; a.x[7] = 0xff;\n\tb = a;\n\tDUK__DBLUNION_CMP_TRUE(&a, &b);\n\n\t/* big endian */\n\ta.x[0] = 0xff; a.x[1] = 0xf1; a.x[2] = 0x00; a.x[3] = 0x00;\n\ta.x[4] = 0x44; a.x[5] = 0x33; a.x[6] = 0x22; a.x[7] = 0x11;\n\tb = a;\n\tDUK__DBLUNION_CMP_TRUE(&a, &b);\n\n\t/* mixed endian */\n\ta.x[0] = 0x00; a.x[1] = 0x00; a.x[2] = 0xf1; a.x[3] = 0xff;\n\ta.x[4] = 0x11; a.x[5] = 0x22; a.x[6] = 0x33; a.x[7] = 0x44;\n\tb = a;\n\tDUK__DBLUNION_CMP_TRUE(&a, &b);\n\n\treturn error_count;\n#else\n\tDUK_D(DUK_DPRINT(\"skip double aliasing self test when duk_tval is not packed\"));\n\treturn 0;\n#endif\n}\n\n/*\n *  Zero sign, see misc/tcc_zerosign2.c.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_zero_sign(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union a, b;\n\n\ta.d = 0.0;\n\tb.d = -a.d;\n\tDUK__DBLUNION_CMP_FALSE(&a, &b);\n\n\treturn error_count;\n}\n\n/*\n *  Rounding mode: Duktape assumes round-to-nearest, check that this is true.\n *  If we had C99 fenv.h we could check that fegetround() == FE_TONEAREST,\n *  but we don't want to rely on that header; and even if we did, it's good\n *  to ensure the rounding actually works.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_rounding(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union a, b, c;\n\n#if 0\n\t/* Include <fenv.h> and test manually; these trigger failures: */\n\tfesetround(FE_UPWARD);\n\tfesetround(FE_DOWNWARD);\n\tfesetround(FE_TOWARDZERO);\n\n\t/* This is the default and passes. */\n\tfesetround(FE_TONEAREST);\n#endif\n\n\t/* Rounding tests check that none of the other modes (round to\n\t * +Inf, round to -Inf, round to zero) can be active:\n\t * http://www.gnu.org/software/libc/manual/html_node/Rounding.html\n\t */\n\n\t/* 1.0 + 2^(-53): result is midway between 1.0 and 1.0 + ulp.\n\t * Round to nearest: 1.0\n\t * Round to +Inf:    1.0 + ulp\n\t * Round to -Inf:    1.0\n\t * Round to zero:    1.0\n\t * => Correct result eliminates round to +Inf.\n\t */\n\tDUK__DOUBLE_INIT(&a, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);\n\tDUK__DOUBLE_INIT(&b, 0x3c, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);\n\tduk_memset((void *) &c, 0, sizeof(c));\n\tc.d = a.d + b.d;\n\tif (!DUK__DOUBLE_COMPARE(&c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)) {\n\t\tDUK_D(DUK_DPRINT(\"broken result (native endiannesss): %02x %02x %02x %02x %02x %02x %02x %02x\",\n\t\t                 (unsigned int) c.x[0], (unsigned int) c.x[1],\n\t\t                 (unsigned int) c.x[2], (unsigned int) c.x[3],\n\t\t                 (unsigned int) c.x[4], (unsigned int) c.x[5],\n\t\t                 (unsigned int) c.x[6], (unsigned int) c.x[7]));\n\t\tDUK__FAILED(\"invalid result from 1.0 + 0.5ulp\");\n\t}\n\n\t/* (1.0 + ulp) + 2^(-53): result is midway between 1.0 + ulp and 1.0 + 2*ulp.\n\t * Round to nearest: 1.0 + 2*ulp (round to even mantissa)\n\t * Round to +Inf:    1.0 + 2*ulp\n\t * Round to -Inf:    1.0 + ulp\n\t * Round to zero:    1.0 + ulp\n\t * => Correct result eliminates round to -Inf and round to zero.\n\t */\n\tDUK__DOUBLE_INIT(&a, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01);\n\tDUK__DOUBLE_INIT(&b, 0x3c, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);\n\tduk_memset((void *) &c, 0, sizeof(c));\n\tc.d = a.d + b.d;\n\tif (!DUK__DOUBLE_COMPARE(&c, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02)) {\n\t\tDUK_D(DUK_DPRINT(\"broken result (native endiannesss): %02x %02x %02x %02x %02x %02x %02x %02x\",\n\t\t                 (unsigned int) c.x[0], (unsigned int) c.x[1],\n\t\t                 (unsigned int) c.x[2], (unsigned int) c.x[3],\n\t\t                 (unsigned int) c.x[4], (unsigned int) c.x[5],\n\t\t                 (unsigned int) c.x[6], (unsigned int) c.x[7]));\n\t\tDUK__FAILED(\"invalid result from (1.0 + ulp) + 0.5ulp\");\n\t}\n\n\t/* Could do negative number testing too, but the tests above should\n\t * differentiate between IEEE 754 rounding modes.\n\t */\n\treturn error_count;\n}\n\n/*\n *  fmod(): often a portability issue in embedded or bare platform targets.\n *  Check for at least minimally correct behavior.  Unlike some other math\n *  functions (like cos()) Duktape relies on fmod() internally too.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_fmod(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union u1, u2;\n\tvolatile duk_double_t t1, t2, t3;\n\n\t/* fmod() with integer argument and exponent 2^32 is used by e.g.\n\t * ToUint32() and some Duktape internals.\n\t */\n\tu1.d = DUK_FMOD(10.0, 4294967296.0);\n\tu2.d = 10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(4294967306.0, 4294967296.0);\n\tu2.d = 10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(73014444042.0, 4294967296.0);\n\tu2.d = 10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\t/* 52-bit integer split into two parts:\n\t * >>> 0x1fedcba9876543\n\t * 8987183256397123\n\t * >>> float(0x1fedcba9876543) / float(2**53)\n\t * 0.9977777777777778\n\t */\n\tu1.d = DUK_FMOD(8987183256397123.0, 4294967296.0);\n\tu2.d = (duk_double_t) 0xa9876543UL;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\tt1 = 8987183256397123.0;\n\tt2 = 4294967296.0;\n\tt3 = t1 / t2;\n\tu1.d = DUK_FLOOR(t3);\n\tu2.d = (duk_double_t) 0x1fedcbUL;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\t/* C99 behavior is for fmod() result sign to mathc argument sign. */\n\tu1.d = DUK_FMOD(-10.0, 4294967296.0);\n\tu2.d = -10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(-4294967306.0, 4294967296.0);\n\tu2.d = -10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(-73014444042.0, 4294967296.0);\n\tu2.d = -10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\treturn error_count;\n}\n\n/*\n *  Struct size/alignment if platform requires it\n *\n *  There are some compiler specific struct padding pragmas etc in use, this\n *  selftest ensures they're correctly detected and used.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_struct_align(void) {\n\tduk_uint_t error_count = 0;\n\n#if (DUK_USE_ALIGN_BY == 4)\n\tif ((sizeof(duk_hbuffer_fixed) % 4) != 0) {\n\t\tDUK__FAILED(\"sizeof(duk_hbuffer_fixed) not aligned to 4\");\n\t}\n#elif (DUK_USE_ALIGN_BY == 8)\n\tif ((sizeof(duk_hbuffer_fixed) % 8) != 0) {\n\t\tDUK__FAILED(\"sizeof(duk_hbuffer_fixed) not aligned to 8\");\n\t}\n#elif (DUK_USE_ALIGN_BY == 1)\n\t/* no check */\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\treturn error_count;\n}\n\n/*\n *  64-bit arithmetic\n *\n *  There are some platforms/compilers where 64-bit types are available\n *  but don't work correctly.  Test for known cases.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_64bit_arithmetic(void) {\n\tduk_uint_t error_count = 0;\n#if defined(DUK_USE_64BIT_OPS)\n\tvolatile duk_int64_t i;\n\tvolatile duk_double_t d;\n\n\t/* Catch a double-to-int64 cast issue encountered in practice. */\n\td = 2147483648.0;\n\ti = (duk_int64_t) d;\n\tif (i != DUK_I64_CONSTANT(0x80000000)) {\n\t\tDUK__FAILED(\"casting 2147483648.0 to duk_int64_t failed\");\n\t}\n#else\n\t/* nop */\n#endif\n\treturn error_count;\n}\n\n/*\n *  Casting\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_cast_double_to_small_uint(void) {\n\t/*\n\t *  https://github.com/svaarala/duktape/issues/127#issuecomment-77863473\n\t */\n\n\tduk_uint_t error_count = 0;\n\n\tduk_double_t d1, d2;\n\tduk_small_uint_t u;\n\n\tduk_double_t d1v, d2v;\n\tduk_small_uint_t uv;\n\n\t/* Test without volatiles */\n\n\td1 = 1.0;\n\tu = (duk_small_uint_t) d1;\n\td2 = (duk_double_t) u;\n\n\tif (!(d1 == 1.0 && u == 1 && d2 == 1.0 && d1 == d2)) {\n\t\tDUK__FAILED(\"double to duk_small_uint_t cast failed\");\n\t}\n\n\t/* Same test with volatiles */\n\n\td1v = 1.0;\n\tuv = (duk_small_uint_t) d1v;\n\td2v = (duk_double_t) uv;\n\n\tif (!(d1v == 1.0 && uv == 1 && d2v == 1.0 && d1v == d2v)) {\n\t\tDUK__FAILED(\"double to duk_small_uint_t cast failed\");\n\t}\n\n\treturn error_count;\n}\n\nDUK_LOCAL duk_uint_t duk__selftest_cast_double_to_uint32(void) {\n\t/*\n\t *  This test fails on an exotic ARM target; double-to-uint\n\t *  cast is incorrectly clamped to -signed- int highest value.\n\t *\n\t *  https://github.com/svaarala/duktape/issues/336\n\t */\n\n\tduk_uint_t error_count = 0;\n\tduk_double_t dv;\n\tduk_uint32_t uv;\n\n\tdv = 3735928559.0;  /* 0xdeadbeef in decimal */\n\tuv = (duk_uint32_t) dv;\n\n\tif (uv != 0xdeadbeefUL) {\n\t\tDUK__FAILED(\"double to duk_uint32_t cast failed\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Minimal test of user supplied allocation functions\n *\n *    - Basic alloc + realloc + free cycle\n *\n *    - Realloc to significantly larger size to (hopefully) trigger a\n *      relocation and check that relocation copying works\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_alloc_funcs(duk_alloc_function alloc_func,\n                                               duk_realloc_function realloc_func,\n                                               duk_free_function free_func,\n                                               void *udata) {\n\tduk_uint_t error_count = 0;\n\tvoid *ptr;\n\tvoid *new_ptr;\n\tduk_small_int_t i, j;\n\tunsigned char x;\n\n\tif (alloc_func == NULL || realloc_func == NULL || free_func == NULL) {\n\t\treturn 0;\n\t}\n\n\tfor (i = 1; i <= 256; i++) {\n\t\tptr = alloc_func(udata, (duk_size_t) i);\n\t\tif (ptr == NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"alloc failed, ignore\"));\n\t\t\tcontinue;  /* alloc failed, ignore */\n\t\t}\n\t\tfor (j = 0; j < i; j++) {\n\t\t\t((unsigned char *) ptr)[j] = (unsigned char) (0x80 + j);\n\t\t}\n\t\tnew_ptr = realloc_func(udata, ptr, 1024);\n\t\tif (new_ptr == NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"realloc failed, ignore\"));\n\t\t\tfree_func(udata, ptr);\n\t\t\tcontinue;  /* realloc failed, ignore */\n\t\t}\n\t\tptr = new_ptr;\n\t\tfor (j = 0; j < i; j++) {\n\t\t\tx = ((unsigned char *) ptr)[j];\n\t\t\tif (x != (unsigned char) (0x80 + j)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"byte at index %ld doesn't match after realloc: %02lx\",\n\t\t\t\t                 (long) j, (unsigned long) x));\n\t\t\t\tDUK__FAILED(\"byte compare after realloc\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tfree_func(udata, ptr);\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Self test main\n */\n\nDUK_INTERNAL duk_uint_t duk_selftest_run_tests(duk_alloc_function alloc_func,\n                                               duk_realloc_function realloc_func,\n                                               duk_free_function free_func,\n                                               void *udata) {\n\tduk_uint_t error_count = 0;\n\n\tDUK_D(DUK_DPRINT(\"self test starting\"));\n\n\terror_count += duk__selftest_types();\n\terror_count += duk__selftest_packed_tval();\n\terror_count += duk__selftest_twos_complement();\n\terror_count += duk__selftest_byte_order();\n\terror_count += duk__selftest_bswap_macros();\n\terror_count += duk__selftest_double_union_size();\n\terror_count += duk__selftest_double_aliasing();\n\terror_count += duk__selftest_double_zero_sign();\n\terror_count += duk__selftest_double_rounding();\n\terror_count += duk__selftest_fmod();\n\terror_count += duk__selftest_struct_align();\n\terror_count += duk__selftest_64bit_arithmetic();\n\terror_count += duk__selftest_cast_double_to_small_uint();\n\terror_count += duk__selftest_cast_double_to_uint32();\n\terror_count += duk__selftest_alloc_funcs(alloc_func, realloc_func, free_func, udata);\n\n\tDUK_D(DUK_DPRINT(\"self test complete, total error count: %ld\", (long) error_count));\n\n\treturn error_count;\n}\n\n#endif  /* DUK_USE_SELF_TESTS */\n\n/* automatic undefs */\n#undef DUK__DBLUNION_CMP_FALSE\n#undef DUK__DBLUNION_CMP_TRUE\n#undef DUK__DOUBLE_COMPARE\n#undef DUK__DOUBLE_INIT\n#undef DUK__FAILED\n#undef DUK__U32_INIT\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_FASTINT)\n\n/*\n *  Manually optimized double-to-fastint downgrade check.\n *\n *  This check has a large impact on performance, especially for fastint\n *  slow paths, so must be changed carefully.  The code should probably be\n *  optimized for the case where the result does not fit into a fastint,\n *  to minimize the penalty for \"slow path code\" dealing with fractions etc.\n *\n *  At least on one tested soft float ARM platform double-to-int64 coercion\n *  is very slow (and sometimes produces incorrect results, see self tests).\n *  This algorithm combines a fastint compatibility check and extracting the\n *  integer value from an IEEE double for setting the tagged fastint.  For\n *  other platforms a more naive approach might be better.\n *\n *  See doc/fastint.rst for details.\n */\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_tval_set_number_chkfast_fast(duk_tval *tv, duk_double_t x) {\n\tduk_double_union du;\n\tduk_int64_t i;\n\tduk_small_int_t expt;\n\tduk_small_int_t shift;\n\n\t/* XXX: optimize for packed duk_tval directly? */\n\n\tdu.d = x;\n\ti = (duk_int64_t) DUK_DBLUNION_GET_INT64(&du);\n\texpt = (duk_small_int_t) ((i >> 52) & 0x07ff);\n\tshift = expt - 1023;\n\n\tif (shift >= 0 && shift <= 46) {  /* exponents 1023 to 1069 */\n\t\tduk_int64_t t;\n\n\t\tif (((DUK_I64_CONSTANT(0x000fffffffffffff) >> shift) & i) == 0) {\n\t\t\tt = i | DUK_I64_CONSTANT(0x0010000000000000);  /* implicit leading one */\n\t\t\tt = t & DUK_I64_CONSTANT(0x001fffffffffffff);\n\t\t\tt = t >> (52 - shift);\n\t\t\tif (i < 0) {\n\t\t\t\tt = -t;\n\t\t\t}\n\t\t\tDUK_TVAL_SET_FASTINT(tv, t);\n\t\t\treturn;\n\t\t}\n\t} else if (shift == -1023) {  /* exponent 0 */\n\t\tif (i >= 0 && (i & DUK_I64_CONSTANT(0x000fffffffffffff)) == 0) {\n\t\t\t/* Note: reject negative zero. */\n\t\t\tDUK_TVAL_SET_FASTINT(tv, (duk_int64_t) 0);\n\t\t\treturn;\n\t\t}\n\t} else if (shift == 47) {  /* exponent 1070 */\n\t\tif (i < 0 && (i & DUK_I64_CONSTANT(0x000fffffffffffff)) == 0) {\n\t\t\tDUK_TVAL_SET_FASTINT(tv, (duk_int64_t) DUK_FASTINT_MIN);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tDUK_TVAL_SET_DOUBLE(tv, x);\n\treturn;\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_tval_set_number_chkfast_slow(duk_tval *tv, duk_double_t x) {\n\tduk_tval_set_number_chkfast_fast(tv, x);\n}\n\n/*\n *  Manually optimized number-to-double conversion\n */\n\n#if defined(DUK_USE_FASTINT) && defined(DUK_USE_PACKED_TVAL)\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_packed(duk_tval *tv) {\n\tduk_double_union du;\n\tduk_uint64_t t;\n\n\tt = (duk_uint64_t) DUK_DBLUNION_GET_UINT64(tv);\n\tif ((t >> 48) != DUK_TAG_FASTINT) {\n\t\treturn tv->d;\n\t} else if (t & DUK_U64_CONSTANT(0x0000800000000000)) {\n\t\tt = (duk_uint64_t) (-((duk_int64_t) t));  /* avoid unary minus on unsigned */\n\t\tt = t & DUK_U64_CONSTANT(0x0000ffffffffffff);  /* negative */\n\t\tt |= DUK_U64_CONSTANT(0xc330000000000000);\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d + 4503599627370496.0;  /* 1 << 52 */\n\t} else if (t != 0) {\n\t\tt &= DUK_U64_CONSTANT(0x0000ffffffffffff);  /* positive */\n\t\tt |= DUK_U64_CONSTANT(0x4330000000000000);\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d - 4503599627370496.0;  /* 1 << 52 */\n\t} else {\n\t\treturn 0.0;  /* zero */\n\t}\n}\n#endif  /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */\n\n#if 0  /* unused */\n#if defined(DUK_USE_FASTINT) && !defined(DUK_USE_PACKED_TVAL)\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked(duk_tval *tv) {\n\tduk_double_union du;\n\tduk_uint64_t t;\n\n\tDUK_ASSERT(tv->t == DUK_TAG_NUMBER || tv->t == DUK_TAG_FASTINT);\n\n\tif (tv->t == DUK_TAG_FASTINT) {\n\t\tif (tv->v.fi >= 0) {\n\t\t\tt = DUK_U64_CONSTANT(0x4330000000000000) | (duk_uint64_t) tv->v.fi;\n\t\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\t\treturn du.d - 4503599627370496.0;  /* 1 << 52 */\n\t\t} else {\n\t\t\tt = DUK_U64_CONSTANT(0xc330000000000000) | (duk_uint64_t) (-tv->v.fi);\n\t\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\t\treturn du.d + 4503599627370496.0;  /* 1 << 52 */\n\t\t}\n\t} else {\n\t\treturn tv->v.d;\n\t}\n}\n#endif  /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */\n#endif  /* 0 */\n\n#if defined(DUK_USE_FASTINT) && !defined(DUK_USE_PACKED_TVAL)\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked_fastint(duk_tval *tv) {\n\tduk_double_union du;\n\tduk_uint64_t t;\n\n\tDUK_ASSERT(tv->t == DUK_TAG_FASTINT);\n\n\tif (tv->v.fi >= 0) {\n\t\tt = DUK_U64_CONSTANT(0x4330000000000000) | (duk_uint64_t) tv->v.fi;\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d - 4503599627370496.0;  /* 1 << 52 */\n\t} else {\n\t\tt = DUK_U64_CONSTANT(0xc330000000000000) | (duk_uint64_t) (-tv->v.fi);\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d + 4503599627370496.0;  /* 1 << 52 */\n\t}\n}\n#endif  /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */\n\n#endif  /* DUK_USE_FASTINT */\n\n/*\n *  Assertion helpers.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL void duk_tval_assert_valid(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n}\n#endif\n/*\n *  Unicode support tables automatically generated during build.\n */\n\n/* #include duk_internal.h -> already included */\n\n/*\n *  Unicode tables containing ranges of Unicode characters in a\n *  packed format.  These tables are used to match non-ASCII\n *  characters of complex productions by resorting to a linear\n *  range-by-range comparison.  This is very slow, but is expected\n *  to be very rare in practical ECMAScript source code, and thus\n *  compactness is most important.\n *\n *  The tables are matched using uni_range_match() and the format\n *  is described in tools/extract_chars.py.\n */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/* IdentifierStart production with ASCII excluded */\n/* duk_unicode_ids_noa[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_ids_noa[1116] = {\n249,176,176,80,111,7,47,15,47,254,11,197,191,0,72,2,15,115,66,19,50,7,2,34,\n2,240,66,244,50,247,185,249,98,241,99,7,241,159,57,240,181,63,31,241,191,\n21,18,245,50,15,1,24,27,35,15,2,2,240,239,15,244,156,15,10,241,26,21,6,240,\n101,10,4,15,9,240,152,175,39,240,82,127,56,242,100,15,4,8,159,1,240,5,115,\n19,240,98,98,4,52,15,2,14,18,47,0,27,9,85,19,240,98,98,18,18,31,17,50,15,5,\n47,2,130,34,240,98,98,18,68,15,4,15,1,31,9,12,115,19,240,98,98,18,68,15,16,\n18,47,1,15,3,2,84,34,52,18,2,20,20,36,191,8,15,38,114,34,240,114,240,4,15,\n12,38,31,16,5,114,34,240,114,146,68,15,18,2,31,1,31,4,114,34,241,147,15,2,\n6,41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,2,66,240,130,\n2,146,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,2,85,52,4,\n24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,35,63,17,35,\n54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,227,240,18,240,\n166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,21,5,15,53,244,\n152,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,175,40,240,122,\n242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,79,27,43,241,67,\n136,241,179,47,27,50,82,20,6,251,15,50,255,224,8,53,63,22,53,55,32,32,32,\n47,15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,32,\n68,112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,87,\n52,29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,254,\n12,146,240,184,132,52,95,70,114,47,74,35,111,27,47,78,240,63,11,242,127,0,\n255,224,244,255,240,0,138,143,60,255,240,4,14,47,2,255,227,127,243,95,30,\n63,253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,37,52,242,42,\n34,35,47,7,240,255,36,240,15,34,243,5,64,33,207,12,191,7,240,191,13,143,31,\n240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,48,32,\n240,162,58,130,213,53,53,166,38,47,27,43,159,99,240,255,255,0,26,150,223,7,\n95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,18,245,\n207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,127,10,\n207,73,69,53,53,50,241,91,47,10,47,3,33,46,61,241,79,107,243,127,37,255,\n223,13,79,33,242,31,16,239,14,111,22,191,14,63,20,87,36,241,207,142,240,79,\n20,95,20,95,24,159,36,248,239,254,2,154,240,107,127,138,83,2,241,194,20,3,\n240,123,240,122,240,255,51,240,50,27,240,107,240,175,56,242,135,31,50,15,1,\n50,34,240,223,28,240,212,240,223,21,114,240,207,13,242,107,240,107,240,62,\n240,47,96,243,159,41,242,62,242,62,241,79,254,13,15,13,176,159,6,248,207,7,\n223,37,243,223,29,241,47,9,240,207,20,240,240,207,19,64,223,32,240,3,240,\n112,32,241,95,2,47,9,244,102,32,35,46,41,143,31,241,135,49,63,6,38,33,36,\n64,240,64,212,249,15,37,240,67,240,96,241,47,32,240,97,32,250,175,31,241,\n179,241,111,32,240,96,242,223,27,224,243,159,11,253,127,28,246,111,48,241,\n16,249,39,63,23,240,32,32,240,224,191,24,128,240,112,207,30,240,80,241,79,\n41,255,152,47,21,240,48,242,63,14,246,38,33,47,22,240,112,240,181,33,47,16,\n240,0,255,224,59,240,63,254,0,31,254,40,207,88,245,255,3,251,79,254,155,15,\n254,50,31,254,236,95,254,19,159,255,0,16,173,255,225,43,143,15,246,63,14,\n240,79,32,240,35,241,31,5,111,3,255,225,164,243,15,114,243,182,15,52,207,\n50,18,15,14,255,240,0,110,169,255,225,229,255,240,1,64,31,254,1,31,35,47,3,\n57,255,224,126,255,231,248,245,182,196,136,159,255,0,6,90,244,82,243,114,\n19,3,19,50,178,2,98,243,18,51,114,98,240,194,50,66,4,98,255,224,70,63,9,47,\n9,47,15,47,9,47,15,47,9,47,15,47,9,47,15,47,9,39,255,232,40,241,219,111,2,\n15,254,6,95,28,255,228,8,251,95,45,243,72,15,254,58,131,47,11,33,32,48,41,\n35,32,32,112,80,32,32,34,33,32,48,32,32,32,32,33,32,51,38,35,35,32,41,47,1,\n98,36,47,1,255,240,0,3,143,255,0,149,201,241,191,254,242,124,252,227,255,\n240,0,87,79,0,255,240,0,194,63,254,177,63,254,17,0,\n};\n#else\n/* IdentifierStart production with ASCII and non-BMP excluded */\n/* duk_unicode_ids_noabmp[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_ids_noabmp[625] = {\n249,176,176,80,111,7,47,15,47,254,11,197,191,0,72,2,15,115,66,19,50,7,2,34,\n2,240,66,244,50,247,185,249,98,241,99,7,241,159,57,240,181,63,31,241,191,\n21,18,245,50,15,1,24,27,35,15,2,2,240,239,15,244,156,15,10,241,26,21,6,240,\n101,10,4,15,9,240,152,175,39,240,82,127,56,242,100,15,4,8,159,1,240,5,115,\n19,240,98,98,4,52,15,2,14,18,47,0,27,9,85,19,240,98,98,18,18,31,17,50,15,5,\n47,2,130,34,240,98,98,18,68,15,4,15,1,31,9,12,115,19,240,98,98,18,68,15,16,\n18,47,1,15,3,2,84,34,52,18,2,20,20,36,191,8,15,38,114,34,240,114,240,4,15,\n12,38,31,16,5,114,34,240,114,146,68,15,18,2,31,1,31,4,114,34,241,147,15,2,\n6,41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,2,66,240,130,\n2,146,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,2,85,52,4,\n24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,35,63,17,35,\n54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,227,240,18,240,\n166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,21,5,15,53,244,\n152,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,175,40,240,122,\n242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,79,27,43,241,67,\n136,241,179,47,27,50,82,20,6,251,15,50,255,224,8,53,63,22,53,55,32,32,32,\n47,15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,32,\n68,112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,87,\n52,29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,254,\n12,146,240,184,132,52,95,70,114,47,74,35,111,27,47,78,240,63,11,242,127,0,\n255,224,244,255,240,0,138,143,60,255,240,4,14,47,2,255,227,127,243,95,30,\n63,253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,37,52,242,42,\n34,35,47,7,240,255,36,240,15,34,243,5,64,33,207,12,191,7,240,191,13,143,31,\n240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,48,32,\n240,162,58,130,213,53,53,166,38,47,27,43,159,99,240,255,255,0,26,150,223,7,\n95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,18,245,\n207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,127,10,\n207,73,69,53,53,50,0,\n};\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/* IdentifierStart production with Letter and ASCII excluded */\n/* duk_unicode_ids_m_let_noa[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_ids_m_let_noa[42] = {\n255,240,0,94,18,255,233,99,241,51,63,254,215,32,240,184,240,2,255,240,6,89,\n249,255,240,4,148,79,37,255,224,192,9,15,120,79,255,0,15,30,245,240,\n};\n#else\n/* IdentifierStart production with Letter, ASCII, and non-BMP excluded */\n/* duk_unicode_ids_m_let_noabmp[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_ids_m_let_noabmp[24] = {\n255,240,0,94,18,255,233,99,241,51,63,254,215,32,240,184,240,2,255,240,6,89,\n249,0,\n};\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/* IdentifierPart production with IdentifierStart and ASCII excluded */\n/* duk_unicode_idp_m_ids_noa[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_idp_m_ids_noa[576] = {\n255,225,243,246,15,254,0,116,255,191,29,32,33,33,32,243,170,242,47,15,112,\n245,118,53,49,35,57,240,144,241,15,11,244,218,240,25,241,56,160,240,163,40,\n34,36,241,210,246,158,47,17,242,130,47,2,38,177,57,240,50,242,160,38,49,50,\n160,177,57,240,0,50,242,160,36,81,50,64,240,107,64,194,242,160,39,34,34,\n240,97,57,181,34,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240,\n9,240,36,242,182,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240,\n35,242,145,38,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54,\n215,41,244,144,56,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160,\n245,111,4,41,211,82,34,54,67,235,46,255,225,179,47,254,42,98,240,242,240,\n241,241,1,243,47,16,160,57,241,50,57,245,209,241,64,246,139,91,185,247,41,\n242,244,242,185,47,13,58,121,240,141,243,68,242,31,1,201,240,56,210,241,12,\n57,241,237,242,47,4,153,121,246,130,47,5,80,112,50,251,143,42,36,255,225,0,\n31,35,31,5,15,109,197,4,191,254,175,34,247,240,245,47,16,255,225,30,95,91,\n31,255,0,100,121,159,55,5,159,18,31,66,31,254,0,64,64,80,240,148,244,161,\n242,79,2,185,127,2,234,240,231,240,188,241,227,242,29,240,25,192,185,242,\n29,208,145,57,241,50,242,64,34,49,97,32,241,180,97,253,231,33,57,255,240,3,\n225,128,255,225,213,240,15,2,240,4,31,10,47,178,159,23,15,254,27,16,253,64,\n248,116,255,224,25,159,254,68,178,33,99,241,162,80,249,113,255,225,49,57,\n159,254,16,10,250,18,242,126,241,25,240,19,241,250,242,121,114,241,109,41,\n97,241,224,210,242,45,147,73,244,75,112,249,43,105,115,242,145,38,49,50,\n160,177,54,68,251,47,2,169,80,244,63,4,217,252,118,56,240,209,244,79,1,240,\n25,244,60,153,244,94,89,254,78,249,121,253,150,54,64,240,233,241,166,35,\n144,170,242,15,0,255,224,137,114,127,2,159,42,240,98,223,108,84,2,18,98,9,\n159,34,66,18,73,159,254,3,211,255,240,3,165,217,247,132,242,214,240,185,\n255,226,233,2,242,120,63,255,0,59,254,31,255,0,3,186,68,89,115,111,16,63,\n134,47,254,71,223,34,255,224,244,242,117,242,41,15,0,15,8,66,239,254,68,70,\n47,1,54,33,36,255,118,169,255,224,150,223,254,76,166,245,246,105,255,240,\n192,105,175,224,0,\n};\n#else\n/* IdentifierPart production with IdentifierStart, ASCII, and non-BMP excluded */\n/* duk_unicode_idp_m_ids_noabmp[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_idp_m_ids_noabmp[358] = {\n255,225,243,246,15,254,0,116,255,191,29,32,33,33,32,243,170,242,47,15,112,\n245,118,53,49,35,57,240,144,241,15,11,244,218,240,25,241,56,160,240,163,40,\n34,36,241,210,246,158,47,17,242,130,47,2,38,177,57,240,50,242,160,38,49,50,\n160,177,57,240,0,50,242,160,36,81,50,64,240,107,64,194,242,160,39,34,34,\n240,97,57,181,34,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240,\n9,240,36,242,182,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240,\n35,242,145,38,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54,\n215,41,244,144,56,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160,\n245,111,4,41,211,82,34,54,67,235,46,255,225,179,47,254,42,98,240,242,240,\n241,241,1,243,47,16,160,57,241,50,57,245,209,241,64,246,139,91,185,247,41,\n242,244,242,185,47,13,58,121,240,141,243,68,242,31,1,201,240,56,210,241,12,\n57,241,237,242,47,4,153,121,246,130,47,5,80,112,50,251,143,42,36,255,225,0,\n31,35,31,5,15,109,197,4,191,254,175,34,247,240,245,47,16,255,225,30,95,91,\n31,255,0,100,121,159,55,5,159,18,31,66,31,254,0,64,64,80,240,148,244,161,\n242,79,2,185,127,2,234,240,231,240,188,241,227,242,29,240,25,192,185,242,\n29,208,145,57,241,50,242,64,34,49,97,32,241,180,97,253,231,33,57,255,240,3,\n225,128,255,225,213,240,15,2,240,4,31,10,47,178,159,23,0,\n};\n#endif\n\n/*\n *  Case conversion tables generated using tools/extract_caseconv.py.\n */\n\n/* duk_unicode_caseconv_uc[] */\n/* duk_unicode_caseconv_lc[] */\n\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_caseconv_uc[1411] = {\n152,3,128,3,0,184,7,192,6,192,112,35,242,199,224,64,74,192,49,32,128,162,\n128,108,65,1,189,129,254,131,3,173,3,136,6,7,98,7,34,68,15,12,14,140,72,30,\n104,28,112,32,67,0,65,4,0,138,0,128,4,1,88,65,76,83,8,104,14,72,43,16,253,\n28,189,6,39,240,39,224,24,114,12,16,132,16,248,0,248,64,129,241,1,241,128,\n195,228,3,229,2,7,204,7,206,4,15,160,15,164,6,31,96,31,104,16,62,224,63,\n116,8,125,200,127,32,32,251,176,254,208,33,247,129,255,128,67,239,67,253,\n64,135,223,7,254,129,15,216,15,220,2,31,208,31,216,4,63,192,63,208,8,133,\n192,133,128,129,38,129,37,177,162,195,2,192,5,229,160,2,20,9,170,220,4,232,\n40,127,160,255,144,154,136,4,4,4,0,192,9,152,9,144,48,19,160,19,145,0,41,\n96,41,69,192,94,128,94,65,128,193,128,193,2,1,161,1,160,6,3,104,3,102,8,7,\n56,7,52,64,14,248,14,240,144,31,144,31,130,128,68,96,68,66,64,145,192,145,\n130,129,184,129,184,2,3,217,3,216,24,8,194,8,192,68,18,44,18,40,216,38,16,\n38,8,112,77,16,77,6,3,192,35,192,18,199,168,71,168,24,15,168,143,172,132,\n44,104,44,103,6,89,2,89,0,200,179,176,179,172,21,50,13,50,1,122,104,26,104,\n1,212,228,116,228,65,233,204,233,204,143,211,189,83,188,130,167,127,167,\n126,11,79,35,79,32,10,158,94,158,88,85,61,173,61,160,97,192,107,64,107,1,0,\n226,128,226,3,1,198,1,196,6,3,228,3,226,8,10,0,6,152,16,31,192,31,184,34,\n199,50,199,32,65,128,196,0,195,130,1,185,1,184,4,4,205,79,84,8,0,192,143,0,\n142,193,1,52,128,203,2,45,39,16,199,5,253,0,11,80,57,192,15,240,23,128,19,\n16,4,144,23,240,5,48,24,0,36,48,25,32,25,16,25,80,31,96,25,144,25,128,25,\n160,35,208,25,224,34,0,26,128,26,112,27,240,31,112,29,208,24,224,31,48,31,\n16,37,2,198,240,37,18,198,208,37,34,199,0,37,48,24,16,37,64,24,96,37,144,\n24,240,37,176,25,0,37,202,122,176,38,0,25,48,38,26,122,192,38,48,25,64,38,\n90,120,208,38,128,25,112,38,178,198,32,38,202,122,208,39,18,198,224,39,32,\n25,208,39,80,25,240,39,210,198,64,40,42,124,80,40,122,123,16,40,128,26,224,\n40,144,36,64,40,192,36,80,41,32,27,112,41,218,123,32,41,234,123,0,52,80,57,\n144,55,112,55,96,58,192,56,96,60,32,58,48,60,192,56,192,61,0,57,32,61,16,\n57,128,61,80,58,96,61,96,58,0,61,112,60,240,63,0,57,160,63,16,58,16,63,32,\n63,144,63,48,55,240,63,80,57,80,76,240,76,1,200,0,65,33,200,16,65,65,200,\n32,65,225,200,80,66,33,200,96,66,161,200,112,70,33,200,138,100,161,215,154,\n119,209,215,210,198,49,216,234,124,97,233,177,230,1,251,224,57,145,254,81,\n254,194,20,226,19,34,24,66,24,50,198,18,198,2,198,80,35,162,198,96,35,226,\n207,50,207,42,120,202,120,186,121,74,124,74,124,58,124,42,181,58,123,60,\n192,27,240,2,152,2,152,10,76,5,120,0,156,3,225,0,37,1,134,1,200,96,115,32,\n97,0,96,32,118,24,29,40,24,64,24,8,44,60,10,106,10,164,61,45,0,36,1,152,\n143,75,192,10,128,97,3,211,16,2,184,24,80,244,204,0,178,6,20,61,53,0,32,\n129,95,15,168,64,116,160,98,99,234,88,29,40,24,152,24,0,250,166,7,74,6,38,\n6,2,62,173,129,210,129,137,129,161,15,192,67,225,0,115,35,240,48,248,72,28,\n200,252,20,62,20,7,50,63,7,15,133,129,204,143,194,67,225,128,115,35,240,\n176,248,104,28,200,252,52,62,28,7,50,63,15,15,135,129,204,143,196,67,225,0,\n115,35,241,48,248,72,28,200,252,84,62,20,7,50,63,23,15,133,129,204,143,198,\n67,225,128,115,35,241,176,248,104,28,200,252,116,62,28,7,50,63,31,15,135,\n129,204,143,200,67,229,0,115,35,242,48,249,72,28,200,252,148,62,84,7,50,63,\n39,15,149,129,204,143,202,67,229,128,115,35,242,176,249,104,28,200,252,180,\n62,92,7,50,63,47,15,151,129,204,143,204,67,229,0,115,35,243,48,249,72,28,\n200,252,212,62,84,7,50,63,55,15,149,129,204,143,206,67,229,128,115,35,243,\n176,249,104,28,200,252,244,62,92,7,50,63,63,15,151,129,204,143,208,67,237,\n0,115,35,244,48,251,72,28,200,253,20,62,212,7,50,63,71,15,181,129,204,143,\n210,67,237,128,115,35,244,176,251,104,28,200,253,52,62,220,7,50,63,79,15,\n183,129,204,143,212,67,237,0,115,35,245,48,251,72,28,200,253,84,62,212,7,\n50,63,87,15,181,129,204,143,214,67,237,128,115,35,245,176,251,104,28,200,\n253,116,62,220,7,50,63,95,15,183,129,204,143,217,67,247,64,115,35,246,112,\n28,136,28,200,253,164,7,12,7,50,63,109,1,200,129,161,15,219,224,114,32,104,\n64,115,35,247,144,28,136,28,200,254,20,63,148,7,50,63,135,1,203,129,204,\n143,226,64,113,32,115,35,248,208,28,184,26,16,254,62,7,46,6,132,7,50,63,\n153,1,203,129,204,143,233,96,115,32,97,0,96,3,250,120,28,200,24,64,24,8,\n254,180,7,50,6,132,63,175,129,204,129,132,1,161,15,241,96,116,160,97,0,96,\n3,252,120,29,40,24,64,24,8,255,36,7,66,6,38,63,205,1,210,129,161,15,243,\n224,116,160,97,0,104,67,254,80,255,208,28,200,255,156,7,82,7,50,63,233,1,\n199,129,204,143,251,64,117,32,104,67,254,248,29,72,26,16,28,200,255,228,7,\n82,7,51,246,1,0,35,0,35,125,128,192,8,192,9,63,96,80,2,48,2,103,216,30,0,\n140,0,140,0,147,246,9,128,35,0,35,0,38,125,130,192,10,96,10,159,96,208,2,\n152,2,167,216,156,10,136,10,141,246,41,2,162,2,154,253,138,192,168,128,167,\n127,98,208,42,112,42,55,216,188,10,136,10,122,\n};\nconst duk_uint8_t duk_unicode_caseconv_lc[706] = {\n160,3,0,3,128,184,6,192,7,192,112,24,144,37,96,64,54,32,81,64,128,226,0,\n235,65,129,199,1,230,130,3,145,3,177,34,7,70,7,134,36,15,244,13,236,24,32,\n0,34,129,0,65,0,67,4,0,166,32,172,41,132,40,11,64,19,9,208,85,184,80,19,\n240,19,248,12,57,32,33,160,172,114,244,67,244,24,248,64,248,0,129,241,129,\n241,0,195,229,3,228,2,7,206,7,204,4,15,164,15,160,6,31,104,31,96,16,63,16,\n63,0,32,126,96,126,64,64,253,64,253,0,129,251,129,251,0,67,247,67,238,0,\n135,242,7,220,130,15,236,15,232,2,31,218,31,118,4,63,208,63,192,8,127,168,\n125,232,16,255,192,251,192,33,255,161,247,192,68,44,4,46,4,9,45,137,52,13,\n22,0,22,24,47,44,126,2,63,5,254,67,254,130,106,48,16,0,16,19,0,38,64,38,96,\n192,78,64,78,132,0,165,0,165,151,1,121,1,122,6,3,4,3,6,8,6,128,6,132,24,13,\n152,13,160,32,28,176,28,193,32,59,192,59,226,64,124,128,124,193,0,252,0,\n252,148,2,34,2,35,18,4,140,4,142,20,13,192,13,196,16,30,192,30,200,192,70,\n0,70,18,32,145,64,145,102,193,48,65,48,131,130,104,2,104,176,30,0,30,1,150,\n61,64,61,66,192,125,100,125,68,33,99,57,99,64,50,200,2,200,22,69,157,101,\n157,128,169,144,41,144,75,211,64,83,64,142,167,34,167,35,15,78,101,78,102,\n126,157,230,157,232,21,59,245,59,248,90,121,10,121,16,84,242,212,242,226,\n169,237,41,237,67,12,3,76,5,0,8,6,176,6,180,16,14,32,14,48,48,28,80,28,96,\n64,126,224,127,0,139,28,139,28,193,6,3,14,3,16,8,6,224,6,228,21,61,80,19,\n48,32,3,1,150,2,105,4,4,118,4,120,8,67,28,180,156,23,240,192,94,0,63,192,\n96,64,148,192,97,128,149,0,99,128,119,64,99,192,150,64,100,0,150,192,100,\n64,100,128,100,192,152,0,101,0,152,192,101,192,154,0,102,0,102,64,103,64,\n156,128,103,192,157,64,105,192,106,0,107,128,162,0,109,192,164,128,124,64,\n124,192,125,128,101,64,125,192,111,192,136,0,103,128,142,139,25,64,143,64,\n102,128,143,139,25,128,144,192,96,0,145,0,162,64,145,64,163,0,221,128,221,\n192,223,192,252,192,225,128,235,0,227,0,243,0,243,192,245,192,253,0,238,0,\n254,64,252,129,48,1,51,199,167,128,55,199,239,7,236,199,243,7,240,199,251,\n7,249,71,255,7,252,200,73,128,242,72,74,128,26,200,74,192,57,72,76,136,83,\n136,96,200,97,11,24,11,24,75,24,128,154,203,24,199,95,75,25,0,159,75,27,64,\n148,75,27,128,156,75,27,192,148,11,28,0,148,139,60,139,60,233,223,71,94,\n105,226,233,227,41,227,64,153,105,234,192,151,41,235,0,152,105,235,64,155,\n41,236,0,167,169,236,64,161,233,236,128,167,105,236,234,212,233,240,169,\n240,233,241,41,229,41,241,64,160,169,241,135,99,128,128,152,64,13,32,96,\n224,\n};\n\n#if defined(DUK_USE_REGEXP_CANON_WORKAROUND)\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\nconst duk_uint16_t duk_unicode_re_canon_lookup[65536] = {\n0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,\n28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,\n53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,\n78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,65,66,67,68,69,70,\n71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,123,124,125,\n126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,\n144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,\n162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,\n180,924,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,\n198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,\n216,217,218,219,220,221,222,223,192,193,194,195,196,197,198,199,200,201,\n202,203,204,205,206,207,208,209,210,211,212,213,214,247,216,217,218,219,\n220,221,222,376,256,256,258,258,260,260,262,262,264,264,266,266,268,268,\n270,270,272,272,274,274,276,276,278,278,280,280,282,282,284,284,286,286,\n288,288,290,290,292,292,294,294,296,296,298,298,300,300,302,302,304,305,\n306,306,308,308,310,310,312,313,313,315,315,317,317,319,319,321,321,323,\n323,325,325,327,327,329,330,330,332,332,334,334,336,336,338,338,340,340,\n342,342,344,344,346,346,348,348,350,350,352,352,354,354,356,356,358,358,\n360,360,362,362,364,364,366,366,368,368,370,370,372,372,374,374,376,377,\n377,379,379,381,381,383,579,385,386,386,388,388,390,391,391,393,394,395,\n395,397,398,399,400,401,401,403,404,502,406,407,408,408,573,411,412,413,\n544,415,416,416,418,418,420,420,422,423,423,425,426,427,428,428,430,431,\n431,433,434,435,435,437,437,439,440,440,442,443,444,444,446,503,448,449,\n450,451,452,452,452,455,455,455,458,458,458,461,461,463,463,465,465,467,\n467,469,469,471,471,473,473,475,475,398,478,478,480,480,482,482,484,484,\n486,486,488,488,490,490,492,492,494,494,496,497,497,497,500,500,502,503,\n504,504,506,506,508,508,510,510,512,512,514,514,516,516,518,518,520,520,\n522,522,524,524,526,526,528,528,530,530,532,532,534,534,536,536,538,538,\n540,540,542,542,544,545,546,546,548,548,550,550,552,552,554,554,556,556,\n558,558,560,560,562,562,564,565,566,567,568,569,570,571,571,573,574,11390,\n11391,577,577,579,580,581,582,582,584,584,586,586,588,588,590,590,11375,\n11373,11376,385,390,597,393,394,600,399,602,400,42923L,605,606,607,403,\n42924L,610,404,612,42893L,42922L,615,407,406,42926L,11362,42925L,621,622,\n412,624,11374,413,627,628,415,630,631,632,633,634,635,636,11364,638,639,\n422,641,42949L,425,644,645,646,42929L,430,580,433,434,581,653,654,655,656,\n657,439,659,660,661,662,663,664,665,666,667,668,42930L,42928L,671,672,673,\n674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,\n692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,\n710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,\n728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,\n746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,\n764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,\n782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,\n800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,\n818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,\n836,921,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,\n854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,\n872,873,874,875,876,877,878,879,880,880,882,882,884,885,886,886,888,889,\n890,1021,1022,1023,894,895,896,897,898,899,900,901,902,903,904,905,906,907,\n908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,\n926,927,928,929,930,931,932,933,934,935,936,937,938,939,902,904,905,906,\n944,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,\n931,931,932,933,934,935,936,937,938,939,908,910,911,975,914,920,978,979,\n980,934,928,975,984,984,986,986,988,988,990,990,992,992,994,994,996,996,\n998,998,1000,1000,1002,1002,1004,1004,1006,1006,922,929,1017,895,1012,917,\n1014,1015,1015,1017,1018,1018,1020,1021,1022,1023,1024,1025,1026,1027,1028,\n1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,\n1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,\n1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1040,1041,\n1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,\n1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,\n1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,\n1039,1120,1120,1122,1122,1124,1124,1126,1126,1128,1128,1130,1130,1132,1132,\n1134,1134,1136,1136,1138,1138,1140,1140,1142,1142,1144,1144,1146,1146,1148,\n1148,1150,1150,1152,1152,1154,1155,1156,1157,1158,1159,1160,1161,1162,1162,\n1164,1164,1166,1166,1168,1168,1170,1170,1172,1172,1174,1174,1176,1176,1178,\n1178,1180,1180,1182,1182,1184,1184,1186,1186,1188,1188,1190,1190,1192,1192,\n1194,1194,1196,1196,1198,1198,1200,1200,1202,1202,1204,1204,1206,1206,1208,\n1208,1210,1210,1212,1212,1214,1214,1216,1217,1217,1219,1219,1221,1221,1223,\n1223,1225,1225,1227,1227,1229,1229,1216,1232,1232,1234,1234,1236,1236,1238,\n1238,1240,1240,1242,1242,1244,1244,1246,1246,1248,1248,1250,1250,1252,1252,\n1254,1254,1256,1256,1258,1258,1260,1260,1262,1262,1264,1264,1266,1266,1268,\n1268,1270,1270,1272,1272,1274,1274,1276,1276,1278,1278,1280,1280,1282,1282,\n1284,1284,1286,1286,1288,1288,1290,1290,1292,1292,1294,1294,1296,1296,1298,\n1298,1300,1300,1302,1302,1304,1304,1306,1306,1308,1308,1310,1310,1312,1312,\n1314,1314,1316,1316,1318,1318,1320,1320,1322,1322,1324,1324,1326,1326,1328,\n1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,\n1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,\n1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,\n1374,1375,1376,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,\n1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,\n1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1415,1416,1417,1418,\n1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,\n1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,\n1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,\n1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,\n1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,\n1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,\n1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,\n1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,\n1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,\n1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,\n1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,\n1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,\n1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,\n1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,\n1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,\n1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,\n1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,\n1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,\n1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,\n1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,\n1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,\n1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,\n1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,\n1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,\n1779,1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,\n1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808,\n1809,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,\n1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,\n1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,\n1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1867,1868,\n1869,1870,1871,1872,1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,\n1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,1898,\n1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,\n1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,\n1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,\n1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,\n1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,\n1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,\n1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,\n2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,\n2019,2020,2021,2022,2023,2024,2025,2026,2027,2028,2029,2030,2031,2032,2033,\n2034,2035,2036,2037,2038,2039,2040,2041,2042,2043,2044,2045,2046,2047,2048,\n2049,2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063,\n2064,2065,2066,2067,2068,2069,2070,2071,2072,2073,2074,2075,2076,2077,2078,\n2079,2080,2081,2082,2083,2084,2085,2086,2087,2088,2089,2090,2091,2092,2093,\n2094,2095,2096,2097,2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108,\n2109,2110,2111,2112,2113,2114,2115,2116,2117,2118,2119,2120,2121,2122,2123,\n2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2137,2138,\n2139,2140,2141,2142,2143,2144,2145,2146,2147,2148,2149,2150,2151,2152,2153,\n2154,2155,2156,2157,2158,2159,2160,2161,2162,2163,2164,2165,2166,2167,2168,\n2169,2170,2171,2172,2173,2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,\n2184,2185,2186,2187,2188,2189,2190,2191,2192,2193,2194,2195,2196,2197,2198,\n2199,2200,2201,2202,2203,2204,2205,2206,2207,2208,2209,2210,2211,2212,2213,\n2214,2215,2216,2217,2218,2219,2220,2221,2222,2223,2224,2225,2226,2227,2228,\n2229,2230,2231,2232,2233,2234,2235,2236,2237,2238,2239,2240,2241,2242,2243,\n2244,2245,2246,2247,2248,2249,2250,2251,2252,2253,2254,2255,2256,2257,2258,\n2259,2260,2261,2262,2263,2264,2265,2266,2267,2268,2269,2270,2271,2272,2273,\n2274,2275,2276,2277,2278,2279,2280,2281,2282,2283,2284,2285,2286,2287,2288,\n2289,2290,2291,2292,2293,2294,2295,2296,2297,2298,2299,2300,2301,2302,2303,\n2304,2305,2306,2307,2308,2309,2310,2311,2312,2313,2314,2315,2316,2317,2318,\n2319,2320,2321,2322,2323,2324,2325,2326,2327,2328,2329,2330,2331,2332,2333,\n2334,2335,2336,2337,2338,2339,2340,2341,2342,2343,2344,2345,2346,2347,2348,\n2349,2350,2351,2352,2353,2354,2355,2356,2357,2358,2359,2360,2361,2362,2363,\n2364,2365,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,\n2379,2380,2381,2382,2383,2384,2385,2386,2387,2388,2389,2390,2391,2392,2393,\n2394,2395,2396,2397,2398,2399,2400,2401,2402,2403,2404,2405,2406,2407,2408,\n2409,2410,2411,2412,2413,2414,2415,2416,2417,2418,2419,2420,2421,2422,2423,\n2424,2425,2426,2427,2428,2429,2430,2431,2432,2433,2434,2435,2436,2437,2438,\n2439,2440,2441,2442,2443,2444,2445,2446,2447,2448,2449,2450,2451,2452,2453,\n2454,2455,2456,2457,2458,2459,2460,2461,2462,2463,2464,2465,2466,2467,2468,\n2469,2470,2471,2472,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,\n2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2495,2496,2497,2498,\n2499,2500,2501,2502,2503,2504,2505,2506,2507,2508,2509,2510,2511,2512,2513,\n2514,2515,2516,2517,2518,2519,2520,2521,2522,2523,2524,2525,2526,2527,2528,\n2529,2530,2531,2532,2533,2534,2535,2536,2537,2538,2539,2540,2541,2542,2543,\n2544,2545,2546,2547,2548,2549,2550,2551,2552,2553,2554,2555,2556,2557,2558,\n2559,2560,2561,2562,2563,2564,2565,2566,2567,2568,2569,2570,2571,2572,2573,\n2574,2575,2576,2577,2578,2579,2580,2581,2582,2583,2584,2585,2586,2587,2588,\n2589,2590,2591,2592,2593,2594,2595,2596,2597,2598,2599,2600,2601,2602,2603,\n2604,2605,2606,2607,2608,2609,2610,2611,2612,2613,2614,2615,2616,2617,2618,\n2619,2620,2621,2622,2623,2624,2625,2626,2627,2628,2629,2630,2631,2632,2633,\n2634,2635,2636,2637,2638,2639,2640,2641,2642,2643,2644,2645,2646,2647,2648,\n2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,2659,2660,2661,2662,2663,\n2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2674,2675,2676,2677,2678,\n2679,2680,2681,2682,2683,2684,2685,2686,2687,2688,2689,2690,2691,2692,2693,\n2694,2695,2696,2697,2698,2699,2700,2701,2702,2703,2704,2705,2706,2707,2708,\n2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720,2721,2722,2723,\n2724,2725,2726,2727,2728,2729,2730,2731,2732,2733,2734,2735,2736,2737,2738,\n2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750,2751,2752,2753,\n2754,2755,2756,2757,2758,2759,2760,2761,2762,2763,2764,2765,2766,2767,2768,\n2769,2770,2771,2772,2773,2774,2775,2776,2777,2778,2779,2780,2781,2782,2783,\n2784,2785,2786,2787,2788,2789,2790,2791,2792,2793,2794,2795,2796,2797,2798,\n2799,2800,2801,2802,2803,2804,2805,2806,2807,2808,2809,2810,2811,2812,2813,\n2814,2815,2816,2817,2818,2819,2820,2821,2822,2823,2824,2825,2826,2827,2828,\n2829,2830,2831,2832,2833,2834,2835,2836,2837,2838,2839,2840,2841,2842,2843,\n2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856,2857,2858,\n2859,2860,2861,2862,2863,2864,2865,2866,2867,2868,2869,2870,2871,2872,2873,\n2874,2875,2876,2877,2878,2879,2880,2881,2882,2883,2884,2885,2886,2887,2888,\n2889,2890,2891,2892,2893,2894,2895,2896,2897,2898,2899,2900,2901,2902,2903,\n2904,2905,2906,2907,2908,2909,2910,2911,2912,2913,2914,2915,2916,2917,2918,\n2919,2920,2921,2922,2923,2924,2925,2926,2927,2928,2929,2930,2931,2932,2933,\n2934,2935,2936,2937,2938,2939,2940,2941,2942,2943,2944,2945,2946,2947,2948,\n2949,2950,2951,2952,2953,2954,2955,2956,2957,2958,2959,2960,2961,2962,2963,\n2964,2965,2966,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976,2977,2978,\n2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2989,2990,2991,2992,2993,\n2994,2995,2996,2997,2998,2999,3000,3001,3002,3003,3004,3005,3006,3007,3008,\n3009,3010,3011,3012,3013,3014,3015,3016,3017,3018,3019,3020,3021,3022,3023,\n3024,3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037,3038,\n3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,3051,3052,3053,\n3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066,3067,3068,\n3069,3070,3071,3072,3073,3074,3075,3076,3077,3078,3079,3080,3081,3082,3083,\n3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095,3096,3097,3098,\n3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,3109,3110,3111,3112,3113,\n3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3124,3125,3126,3127,3128,\n3129,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140,3141,3142,3143,\n3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156,3157,3158,\n3159,3160,3161,3162,3163,3164,3165,3166,3167,3168,3169,3170,3171,3172,3173,\n3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186,3187,3188,\n3189,3190,3191,3192,3193,3194,3195,3196,3197,3198,3199,3200,3201,3202,3203,\n3204,3205,3206,3207,3208,3209,3210,3211,3212,3213,3214,3215,3216,3217,3218,\n3219,3220,3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3232,3233,\n3234,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248,\n3249,3250,3251,3252,3253,3254,3255,3256,3257,3258,3259,3260,3261,3262,3263,\n3264,3265,3266,3267,3268,3269,3270,3271,3272,3273,3274,3275,3276,3277,3278,\n3279,3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293,\n3294,3295,3296,3297,3298,3299,3300,3301,3302,3303,3304,3305,3306,3307,3308,\n3309,3310,3311,3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323,\n3324,3325,3326,3327,3328,3329,3330,3331,3332,3333,3334,3335,3336,3337,3338,\n3339,3340,3341,3342,3343,3344,3345,3346,3347,3348,3349,3350,3351,3352,3353,\n3354,3355,3356,3357,3358,3359,3360,3361,3362,3363,3364,3365,3366,3367,3368,\n3369,3370,3371,3372,3373,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383,\n3384,3385,3386,3387,3388,3389,3390,3391,3392,3393,3394,3395,3396,3397,3398,\n3399,3400,3401,3402,3403,3404,3405,3406,3407,3408,3409,3410,3411,3412,3413,\n3414,3415,3416,3417,3418,3419,3420,3421,3422,3423,3424,3425,3426,3427,3428,\n3429,3430,3431,3432,3433,3434,3435,3436,3437,3438,3439,3440,3441,3442,3443,\n3444,3445,3446,3447,3448,3449,3450,3451,3452,3453,3454,3455,3456,3457,3458,\n3459,3460,3461,3462,3463,3464,3465,3466,3467,3468,3469,3470,3471,3472,3473,\n3474,3475,3476,3477,3478,3479,3480,3481,3482,3483,3484,3485,3486,3487,3488,\n3489,3490,3491,3492,3493,3494,3495,3496,3497,3498,3499,3500,3501,3502,3503,\n3504,3505,3506,3507,3508,3509,3510,3511,3512,3513,3514,3515,3516,3517,3518,\n3519,3520,3521,3522,3523,3524,3525,3526,3527,3528,3529,3530,3531,3532,3533,\n3534,3535,3536,3537,3538,3539,3540,3541,3542,3543,3544,3545,3546,3547,3548,\n3549,3550,3551,3552,3553,3554,3555,3556,3557,3558,3559,3560,3561,3562,3563,\n3564,3565,3566,3567,3568,3569,3570,3571,3572,3573,3574,3575,3576,3577,3578,\n3579,3580,3581,3582,3583,3584,3585,3586,3587,3588,3589,3590,3591,3592,3593,\n3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607,3608,\n3609,3610,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,3621,3622,3623,\n3624,3625,3626,3627,3628,3629,3630,3631,3632,3633,3634,3635,3636,3637,3638,\n3639,3640,3641,3642,3643,3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,\n3654,3655,3656,3657,3658,3659,3660,3661,3662,3663,3664,3665,3666,3667,3668,\n3669,3670,3671,3672,3673,3674,3675,3676,3677,3678,3679,3680,3681,3682,3683,\n3684,3685,3686,3687,3688,3689,3690,3691,3692,3693,3694,3695,3696,3697,3698,\n3699,3700,3701,3702,3703,3704,3705,3706,3707,3708,3709,3710,3711,3712,3713,\n3714,3715,3716,3717,3718,3719,3720,3721,3722,3723,3724,3725,3726,3727,3728,\n3729,3730,3731,3732,3733,3734,3735,3736,3737,3738,3739,3740,3741,3742,3743,\n3744,3745,3746,3747,3748,3749,3750,3751,3752,3753,3754,3755,3756,3757,3758,\n3759,3760,3761,3762,3763,3764,3765,3766,3767,3768,3769,3770,3771,3772,3773,\n3774,3775,3776,3777,3778,3779,3780,3781,3782,3783,3784,3785,3786,3787,3788,\n3789,3790,3791,3792,3793,3794,3795,3796,3797,3798,3799,3800,3801,3802,3803,\n3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,3814,3815,3816,3817,3818,\n3819,3820,3821,3822,3823,3824,3825,3826,3827,3828,3829,3830,3831,3832,3833,\n3834,3835,3836,3837,3838,3839,3840,3841,3842,3843,3844,3845,3846,3847,3848,\n3849,3850,3851,3852,3853,3854,3855,3856,3857,3858,3859,3860,3861,3862,3863,\n3864,3865,3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877,3878,\n3879,3880,3881,3882,3883,3884,3885,3886,3887,3888,3889,3890,3891,3892,3893,\n3894,3895,3896,3897,3898,3899,3900,3901,3902,3903,3904,3905,3906,3907,3908,\n3909,3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,3920,3921,3922,3923,\n3924,3925,3926,3927,3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,\n3939,3940,3941,3942,3943,3944,3945,3946,3947,3948,3949,3950,3951,3952,3953,\n3954,3955,3956,3957,3958,3959,3960,3961,3962,3963,3964,3965,3966,3967,3968,\n3969,3970,3971,3972,3973,3974,3975,3976,3977,3978,3979,3980,3981,3982,3983,\n3984,3985,3986,3987,3988,3989,3990,3991,3992,3993,3994,3995,3996,3997,3998,\n3999,4000,4001,4002,4003,4004,4005,4006,4007,4008,4009,4010,4011,4012,4013,\n4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,\n4029,4030,4031,4032,4033,4034,4035,4036,4037,4038,4039,4040,4041,4042,4043,\n4044,4045,4046,4047,4048,4049,4050,4051,4052,4053,4054,4055,4056,4057,4058,\n4059,4060,4061,4062,4063,4064,4065,4066,4067,4068,4069,4070,4071,4072,4073,\n4074,4075,4076,4077,4078,4079,4080,4081,4082,4083,4084,4085,4086,4087,4088,\n4089,4090,4091,4092,4093,4094,4095,4096,4097,4098,4099,4100,4101,4102,4103,\n4104,4105,4106,4107,4108,4109,4110,4111,4112,4113,4114,4115,4116,4117,4118,\n4119,4120,4121,4122,4123,4124,4125,4126,4127,4128,4129,4130,4131,4132,4133,\n4134,4135,4136,4137,4138,4139,4140,4141,4142,4143,4144,4145,4146,4147,4148,\n4149,4150,4151,4152,4153,4154,4155,4156,4157,4158,4159,4160,4161,4162,4163,\n4164,4165,4166,4167,4168,4169,4170,4171,4172,4173,4174,4175,4176,4177,4178,\n4179,4180,4181,4182,4183,4184,4185,4186,4187,4188,4189,4190,4191,4192,4193,\n4194,4195,4196,4197,4198,4199,4200,4201,4202,4203,4204,4205,4206,4207,4208,\n4209,4210,4211,4212,4213,4214,4215,4216,4217,4218,4219,4220,4221,4222,4223,\n4224,4225,4226,4227,4228,4229,4230,4231,4232,4233,4234,4235,4236,4237,4238,\n4239,4240,4241,4242,4243,4244,4245,4246,4247,4248,4249,4250,4251,4252,4253,\n4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265,4266,4267,4268,\n4269,4270,4271,4272,4273,4274,4275,4276,4277,4278,4279,4280,4281,4282,4283,\n4284,4285,4286,4287,4288,4289,4290,4291,4292,4293,4294,4295,4296,4297,4298,\n4299,4300,4301,4302,4303,7312,7313,7314,7315,7316,7317,7318,7319,7320,7321,\n7322,7323,7324,7325,7326,7327,7328,7329,7330,7331,7332,7333,7334,7335,7336,\n7337,7338,7339,7340,7341,7342,7343,7344,7345,7346,7347,7348,7349,7350,7351,\n7352,7353,7354,4347,4348,7357,7358,7359,4352,4353,4354,4355,4356,4357,4358,\n4359,4360,4361,4362,4363,4364,4365,4366,4367,4368,4369,4370,4371,4372,4373,\n4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,4387,4388,\n4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403,\n4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,4417,4418,\n4419,4420,4421,4422,4423,4424,4425,4426,4427,4428,4429,4430,4431,4432,4433,\n4434,4435,4436,4437,4438,4439,4440,4441,4442,4443,4444,4445,4446,4447,4448,\n4449,4450,4451,4452,4453,4454,4455,4456,4457,4458,4459,4460,4461,4462,4463,\n4464,4465,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475,4476,4477,4478,\n4479,4480,4481,4482,4483,4484,4485,4486,4487,4488,4489,4490,4491,4492,4493,\n4494,4495,4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507,4508,\n4509,4510,4511,4512,4513,4514,4515,4516,4517,4518,4519,4520,4521,4522,4523,\n4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,4536,4537,4538,\n4539,4540,4541,4542,4543,4544,4545,4546,4547,4548,4549,4550,4551,4552,4553,\n4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567,4568,\n4569,4570,4571,4572,4573,4574,4575,4576,4577,4578,4579,4580,4581,4582,4583,\n4584,4585,4586,4587,4588,4589,4590,4591,4592,4593,4594,4595,4596,4597,4598,\n4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609,4610,4611,4612,4613,\n4614,4615,4616,4617,4618,4619,4620,4621,4622,4623,4624,4625,4626,4627,4628,\n4629,4630,4631,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,4643,\n4644,4645,4646,4647,4648,4649,4650,4651,4652,4653,4654,4655,4656,4657,4658,\n4659,4660,4661,4662,4663,4664,4665,4666,4667,4668,4669,4670,4671,4672,4673,\n4674,4675,4676,4677,4678,4679,4680,4681,4682,4683,4684,4685,4686,4687,4688,\n4689,4690,4691,4692,4693,4694,4695,4696,4697,4698,4699,4700,4701,4702,4703,\n4704,4705,4706,4707,4708,4709,4710,4711,4712,4713,4714,4715,4716,4717,4718,\n4719,4720,4721,4722,4723,4724,4725,4726,4727,4728,4729,4730,4731,4732,4733,\n4734,4735,4736,4737,4738,4739,4740,4741,4742,4743,4744,4745,4746,4747,4748,\n4749,4750,4751,4752,4753,4754,4755,4756,4757,4758,4759,4760,4761,4762,4763,\n4764,4765,4766,4767,4768,4769,4770,4771,4772,4773,4774,4775,4776,4777,4778,\n4779,4780,4781,4782,4783,4784,4785,4786,4787,4788,4789,4790,4791,4792,4793,\n4794,4795,4796,4797,4798,4799,4800,4801,4802,4803,4804,4805,4806,4807,4808,\n4809,4810,4811,4812,4813,4814,4815,4816,4817,4818,4819,4820,4821,4822,4823,\n4824,4825,4826,4827,4828,4829,4830,4831,4832,4833,4834,4835,4836,4837,4838,\n4839,4840,4841,4842,4843,4844,4845,4846,4847,4848,4849,4850,4851,4852,4853,\n4854,4855,4856,4857,4858,4859,4860,4861,4862,4863,4864,4865,4866,4867,4868,\n4869,4870,4871,4872,4873,4874,4875,4876,4877,4878,4879,4880,4881,4882,4883,\n4884,4885,4886,4887,4888,4889,4890,4891,4892,4893,4894,4895,4896,4897,4898,\n4899,4900,4901,4902,4903,4904,4905,4906,4907,4908,4909,4910,4911,4912,4913,\n4914,4915,4916,4917,4918,4919,4920,4921,4922,4923,4924,4925,4926,4927,4928,\n4929,4930,4931,4932,4933,4934,4935,4936,4937,4938,4939,4940,4941,4942,4943,\n4944,4945,4946,4947,4948,4949,4950,4951,4952,4953,4954,4955,4956,4957,4958,\n4959,4960,4961,4962,4963,4964,4965,4966,4967,4968,4969,4970,4971,4972,4973,\n4974,4975,4976,4977,4978,4979,4980,4981,4982,4983,4984,4985,4986,4987,4988,\n4989,4990,4991,4992,4993,4994,4995,4996,4997,4998,4999,5000,5001,5002,5003,\n5004,5005,5006,5007,5008,5009,5010,5011,5012,5013,5014,5015,5016,5017,5018,\n5019,5020,5021,5022,5023,5024,5025,5026,5027,5028,5029,5030,5031,5032,5033,\n5034,5035,5036,5037,5038,5039,5040,5041,5042,5043,5044,5045,5046,5047,5048,\n5049,5050,5051,5052,5053,5054,5055,5056,5057,5058,5059,5060,5061,5062,5063,\n5064,5065,5066,5067,5068,5069,5070,5071,5072,5073,5074,5075,5076,5077,5078,\n5079,5080,5081,5082,5083,5084,5085,5086,5087,5088,5089,5090,5091,5092,5093,\n5094,5095,5096,5097,5098,5099,5100,5101,5102,5103,5104,5105,5106,5107,5108,\n5109,5110,5111,5104,5105,5106,5107,5108,5109,5118,5119,5120,5121,5122,5123,\n5124,5125,5126,5127,5128,5129,5130,5131,5132,5133,5134,5135,5136,5137,5138,\n5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149,5150,5151,5152,5153,\n5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164,5165,5166,5167,5168,\n5169,5170,5171,5172,5173,5174,5175,5176,5177,5178,5179,5180,5181,5182,5183,\n5184,5185,5186,5187,5188,5189,5190,5191,5192,5193,5194,5195,5196,5197,5198,\n5199,5200,5201,5202,5203,5204,5205,5206,5207,5208,5209,5210,5211,5212,5213,\n5214,5215,5216,5217,5218,5219,5220,5221,5222,5223,5224,5225,5226,5227,5228,\n5229,5230,5231,5232,5233,5234,5235,5236,5237,5238,5239,5240,5241,5242,5243,\n5244,5245,5246,5247,5248,5249,5250,5251,5252,5253,5254,5255,5256,5257,5258,\n5259,5260,5261,5262,5263,5264,5265,5266,5267,5268,5269,5270,5271,5272,5273,\n5274,5275,5276,5277,5278,5279,5280,5281,5282,5283,5284,5285,5286,5287,5288,\n5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,\n5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,\n5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5332,5333,\n5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347,5348,\n5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363,\n5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,\n5379,5380,5381,5382,5383,5384,5385,5386,5387,5388,5389,5390,5391,5392,5393,\n5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408,\n5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,\n5424,5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,\n5439,5440,5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,\n5454,5455,5456,5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,\n5469,5470,5471,5472,5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,\n5484,5485,5486,5487,5488,5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,\n5499,5500,5501,5502,5503,5504,5505,5506,5507,5508,5509,5510,5511,5512,5513,\n5514,5515,5516,5517,5518,5519,5520,5521,5522,5523,5524,5525,5526,5527,5528,\n5529,5530,5531,5532,5533,5534,5535,5536,5537,5538,5539,5540,5541,5542,5543,\n5544,5545,5546,5547,5548,5549,5550,5551,5552,5553,5554,5555,5556,5557,5558,\n5559,5560,5561,5562,5563,5564,5565,5566,5567,5568,5569,5570,5571,5572,5573,\n5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584,5585,5586,5587,5588,\n5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600,5601,5602,5603,\n5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616,5617,5618,\n5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632,5633,\n5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648,\n5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,\n5664,5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,\n5679,5680,5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,\n5694,5695,5696,5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,\n5709,5710,5711,5712,5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,\n5724,5725,5726,5727,5728,5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,\n5739,5740,5741,5742,5743,5744,5745,5746,5747,5748,5749,5750,5751,5752,5753,\n5754,5755,5756,5757,5758,5759,5760,5761,5762,5763,5764,5765,5766,5767,5768,\n5769,5770,5771,5772,5773,5774,5775,5776,5777,5778,5779,5780,5781,5782,5783,\n5784,5785,5786,5787,5788,5789,5790,5791,5792,5793,5794,5795,5796,5797,5798,\n5799,5800,5801,5802,5803,5804,5805,5806,5807,5808,5809,5810,5811,5812,5813,\n5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828,\n5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,\n5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856,5857,5858,\n5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872,5873,\n5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888,\n5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,\n5904,5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,\n5919,5920,5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,\n5934,5935,5936,5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,\n5949,5950,5951,5952,5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,\n5964,5965,5966,5967,5968,5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,\n5979,5980,5981,5982,5983,5984,5985,5986,5987,5988,5989,5990,5991,5992,5993,\n5994,5995,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008,\n6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,\n6024,6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036,6037,6038,\n6039,6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052,6053,\n6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068,\n6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,\n6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,\n6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,\n6114,6115,6116,6117,6118,6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,\n6129,6130,6131,6132,6133,6134,6135,6136,6137,6138,6139,6140,6141,6142,6143,\n6144,6145,6146,6147,6148,6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,\n6159,6160,6161,6162,6163,6164,6165,6166,6167,6168,6169,6170,6171,6172,6173,\n6174,6175,6176,6177,6178,6179,6180,6181,6182,6183,6184,6185,6186,6187,6188,\n6189,6190,6191,6192,6193,6194,6195,6196,6197,6198,6199,6200,6201,6202,6203,\n6204,6205,6206,6207,6208,6209,6210,6211,6212,6213,6214,6215,6216,6217,6218,\n6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229,6230,6231,6232,6233,\n6234,6235,6236,6237,6238,6239,6240,6241,6242,6243,6244,6245,6246,6247,6248,\n6249,6250,6251,6252,6253,6254,6255,6256,6257,6258,6259,6260,6261,6262,6263,\n6264,6265,6266,6267,6268,6269,6270,6271,6272,6273,6274,6275,6276,6277,6278,\n6279,6280,6281,6282,6283,6284,6285,6286,6287,6288,6289,6290,6291,6292,6293,\n6294,6295,6296,6297,6298,6299,6300,6301,6302,6303,6304,6305,6306,6307,6308,\n6309,6310,6311,6312,6313,6314,6315,6316,6317,6318,6319,6320,6321,6322,6323,\n6324,6325,6326,6327,6328,6329,6330,6331,6332,6333,6334,6335,6336,6337,6338,\n6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349,6350,6351,6352,6353,\n6354,6355,6356,6357,6358,6359,6360,6361,6362,6363,6364,6365,6366,6367,6368,\n6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380,6381,6382,6383,\n6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,6396,6397,6398,\n6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,\n6414,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,6426,6427,6428,\n6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443,\n6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,6455,6456,6457,6458,\n6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472,6473,\n6474,6475,6476,6477,6478,6479,6480,6481,6482,6483,6484,6485,6486,6487,6488,\n6489,6490,6491,6492,6493,6494,6495,6496,6497,6498,6499,6500,6501,6502,6503,\n6504,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516,6517,6518,\n6519,6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532,6533,\n6534,6535,6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548,\n6549,6550,6551,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563,\n6564,6565,6566,6567,6568,6569,6570,6571,6572,6573,6574,6575,6576,6577,6578,\n6579,6580,6581,6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593,\n6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604,6605,6606,6607,6608,\n6609,6610,6611,6612,6613,6614,6615,6616,6617,6618,6619,6620,6621,6622,6623,\n6624,6625,6626,6627,6628,6629,6630,6631,6632,6633,6634,6635,6636,6637,6638,\n6639,6640,6641,6642,6643,6644,6645,6646,6647,6648,6649,6650,6651,6652,6653,\n6654,6655,6656,6657,6658,6659,6660,6661,6662,6663,6664,6665,6666,6667,6668,\n6669,6670,6671,6672,6673,6674,6675,6676,6677,6678,6679,6680,6681,6682,6683,\n6684,6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,6698,\n6699,6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711,6712,6713,\n6714,6715,6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,\n6729,6730,6731,6732,6733,6734,6735,6736,6737,6738,6739,6740,6741,6742,6743,\n6744,6745,6746,6747,6748,6749,6750,6751,6752,6753,6754,6755,6756,6757,6758,\n6759,6760,6761,6762,6763,6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,\n6774,6775,6776,6777,6778,6779,6780,6781,6782,6783,6784,6785,6786,6787,6788,\n6789,6790,6791,6792,6793,6794,6795,6796,6797,6798,6799,6800,6801,6802,6803,\n6804,6805,6806,6807,6808,6809,6810,6811,6812,6813,6814,6815,6816,6817,6818,\n6819,6820,6821,6822,6823,6824,6825,6826,6827,6828,6829,6830,6831,6832,6833,\n6834,6835,6836,6837,6838,6839,6840,6841,6842,6843,6844,6845,6846,6847,6848,\n6849,6850,6851,6852,6853,6854,6855,6856,6857,6858,6859,6860,6861,6862,6863,\n6864,6865,6866,6867,6868,6869,6870,6871,6872,6873,6874,6875,6876,6877,6878,\n6879,6880,6881,6882,6883,6884,6885,6886,6887,6888,6889,6890,6891,6892,6893,\n6894,6895,6896,6897,6898,6899,6900,6901,6902,6903,6904,6905,6906,6907,6908,\n6909,6910,6911,6912,6913,6914,6915,6916,6917,6918,6919,6920,6921,6922,6923,\n6924,6925,6926,6927,6928,6929,6930,6931,6932,6933,6934,6935,6936,6937,6938,\n6939,6940,6941,6942,6943,6944,6945,6946,6947,6948,6949,6950,6951,6952,6953,\n6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966,6967,6968,\n6969,6970,6971,6972,6973,6974,6975,6976,6977,6978,6979,6980,6981,6982,6983,\n6984,6985,6986,6987,6988,6989,6990,6991,6992,6993,6994,6995,6996,6997,6998,\n6999,7000,7001,7002,7003,7004,7005,7006,7007,7008,7009,7010,7011,7012,7013,\n7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027,7028,\n7029,7030,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,7043,\n7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058,\n7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7073,\n7074,7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7086,7087,7088,\n7089,7090,7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,\n7104,7105,7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,\n7119,7120,7121,7122,7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,\n7134,7135,7136,7137,7138,7139,7140,7141,7142,7143,7144,7145,7146,7147,7148,\n7149,7150,7151,7152,7153,7154,7155,7156,7157,7158,7159,7160,7161,7162,7163,\n7164,7165,7166,7167,7168,7169,7170,7171,7172,7173,7174,7175,7176,7177,7178,\n7179,7180,7181,7182,7183,7184,7185,7186,7187,7188,7189,7190,7191,7192,7193,\n7194,7195,7196,7197,7198,7199,7200,7201,7202,7203,7204,7205,7206,7207,7208,\n7209,7210,7211,7212,7213,7214,7215,7216,7217,7218,7219,7220,7221,7222,7223,\n7224,7225,7226,7227,7228,7229,7230,7231,7232,7233,7234,7235,7236,7237,7238,\n7239,7240,7241,7242,7243,7244,7245,7246,7247,7248,7249,7250,7251,7252,7253,\n7254,7255,7256,7257,7258,7259,7260,7261,7262,7263,7264,7265,7266,7267,7268,\n7269,7270,7271,7272,7273,7274,7275,7276,7277,7278,7279,7280,7281,7282,7283,\n7284,7285,7286,7287,7288,7289,7290,7291,7292,7293,7294,7295,1042,1044,1054,\n1057,1058,1058,1066,1122,42570L,7305,7306,7307,7308,7309,7310,7311,7312,\n7313,7314,7315,7316,7317,7318,7319,7320,7321,7322,7323,7324,7325,7326,7327,\n7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339,7340,7341,7342,\n7343,7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,7354,7355,7356,7357,\n7358,7359,7360,7361,7362,7363,7364,7365,7366,7367,7368,7369,7370,7371,7372,\n7373,7374,7375,7376,7377,7378,7379,7380,7381,7382,7383,7384,7385,7386,7387,\n7388,7389,7390,7391,7392,7393,7394,7395,7396,7397,7398,7399,7400,7401,7402,\n7403,7404,7405,7406,7407,7408,7409,7410,7411,7412,7413,7414,7415,7416,7417,\n7418,7419,7420,7421,7422,7423,7424,7425,7426,7427,7428,7429,7430,7431,7432,\n7433,7434,7435,7436,7437,7438,7439,7440,7441,7442,7443,7444,7445,7446,7447,\n7448,7449,7450,7451,7452,7453,7454,7455,7456,7457,7458,7459,7460,7461,7462,\n7463,7464,7465,7466,7467,7468,7469,7470,7471,7472,7473,7474,7475,7476,7477,\n7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491,7492,\n7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,7503,7504,7505,7506,7507,\n7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,7520,7521,7522,\n7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537,\n7538,7539,7540,7541,7542,7543,7544,42877L,7546,7547,7548,11363,7550,7551,\n7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,\n42950L,7567,7568,7569,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,\n7580,7581,7582,7583,7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,\n7595,7596,7597,7598,7599,7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,\n7610,7611,7612,7613,7614,7615,7616,7617,7618,7619,7620,7621,7622,7623,7624,\n7625,7626,7627,7628,7629,7630,7631,7632,7633,7634,7635,7636,7637,7638,7639,\n7640,7641,7642,7643,7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654,\n7655,7656,7657,7658,7659,7660,7661,7662,7663,7664,7665,7666,7667,7668,7669,\n7670,7671,7672,7673,7674,7675,7676,7677,7678,7679,7680,7680,7682,7682,7684,\n7684,7686,7686,7688,7688,7690,7690,7692,7692,7694,7694,7696,7696,7698,7698,\n7700,7700,7702,7702,7704,7704,7706,7706,7708,7708,7710,7710,7712,7712,7714,\n7714,7716,7716,7718,7718,7720,7720,7722,7722,7724,7724,7726,7726,7728,7728,\n7730,7730,7732,7732,7734,7734,7736,7736,7738,7738,7740,7740,7742,7742,7744,\n7744,7746,7746,7748,7748,7750,7750,7752,7752,7754,7754,7756,7756,7758,7758,\n7760,7760,7762,7762,7764,7764,7766,7766,7768,7768,7770,7770,7772,7772,7774,\n7774,7776,7776,7778,7778,7780,7780,7782,7782,7784,7784,7786,7786,7788,7788,\n7790,7790,7792,7792,7794,7794,7796,7796,7798,7798,7800,7800,7802,7802,7804,\n7804,7806,7806,7808,7808,7810,7810,7812,7812,7814,7814,7816,7816,7818,7818,\n7820,7820,7822,7822,7824,7824,7826,7826,7828,7828,7830,7831,7832,7833,7834,\n7776,7836,7837,7838,7839,7840,7840,7842,7842,7844,7844,7846,7846,7848,7848,\n7850,7850,7852,7852,7854,7854,7856,7856,7858,7858,7860,7860,7862,7862,7864,\n7864,7866,7866,7868,7868,7870,7870,7872,7872,7874,7874,7876,7876,7878,7878,\n7880,7880,7882,7882,7884,7884,7886,7886,7888,7888,7890,7890,7892,7892,7894,\n7894,7896,7896,7898,7898,7900,7900,7902,7902,7904,7904,7906,7906,7908,7908,\n7910,7910,7912,7912,7914,7914,7916,7916,7918,7918,7920,7920,7922,7922,7924,\n7924,7926,7926,7928,7928,7930,7930,7932,7932,7934,7934,7944,7945,7946,7947,\n7948,7949,7950,7951,7944,7945,7946,7947,7948,7949,7950,7951,7960,7961,7962,\n7963,7964,7965,7958,7959,7960,7961,7962,7963,7964,7965,7966,7967,7976,7977,\n7978,7979,7980,7981,7982,7983,7976,7977,7978,7979,7980,7981,7982,7983,7992,\n7993,7994,7995,7996,7997,7998,7999,7992,7993,7994,7995,7996,7997,7998,7999,\n8008,8009,8010,8011,8012,8013,8006,8007,8008,8009,8010,8011,8012,8013,8014,\n8015,8016,8025,8018,8027,8020,8029,8022,8031,8024,8025,8026,8027,8028,8029,\n8030,8031,8040,8041,8042,8043,8044,8045,8046,8047,8040,8041,8042,8043,8044,\n8045,8046,8047,8122,8123,8136,8137,8138,8139,8154,8155,8184,8185,8170,8171,\n8186,8187,8062,8063,8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,\n8075,8076,8077,8078,8079,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,\n8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8102,8103,8104,\n8105,8106,8107,8108,8109,8110,8111,8120,8121,8114,8115,8116,8117,8118,8119,\n8120,8121,8122,8123,8124,8125,921,8127,8128,8129,8130,8131,8132,8133,8134,\n8135,8136,8137,8138,8139,8140,8141,8142,8143,8152,8153,8146,8147,8148,8149,\n8150,8151,8152,8153,8154,8155,8156,8157,8158,8159,8168,8169,8162,8163,8164,\n8172,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175,8176,8177,8178,8179,\n8180,8181,8182,8183,8184,8185,8186,8187,8188,8189,8190,8191,8192,8193,8194,\n8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207,8208,8209,\n8210,8211,8212,8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223,8224,\n8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239,\n8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,\n8255,8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,\n8270,8271,8272,8273,8274,8275,8276,8277,8278,8279,8280,8281,8282,8283,8284,\n8285,8286,8287,8288,8289,8290,8291,8292,8293,8294,8295,8296,8297,8298,8299,\n8300,8301,8302,8303,8304,8305,8306,8307,8308,8309,8310,8311,8312,8313,8314,\n8315,8316,8317,8318,8319,8320,8321,8322,8323,8324,8325,8326,8327,8328,8329,\n8330,8331,8332,8333,8334,8335,8336,8337,8338,8339,8340,8341,8342,8343,8344,\n8345,8346,8347,8348,8349,8350,8351,8352,8353,8354,8355,8356,8357,8358,8359,\n8360,8361,8362,8363,8364,8365,8366,8367,8368,8369,8370,8371,8372,8373,8374,\n8375,8376,8377,8378,8379,8380,8381,8382,8383,8384,8385,8386,8387,8388,8389,\n8390,8391,8392,8393,8394,8395,8396,8397,8398,8399,8400,8401,8402,8403,8404,\n8405,8406,8407,8408,8409,8410,8411,8412,8413,8414,8415,8416,8417,8418,8419,\n8420,8421,8422,8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,8433,8434,\n8435,8436,8437,8438,8439,8440,8441,8442,8443,8444,8445,8446,8447,8448,8449,\n8450,8451,8452,8453,8454,8455,8456,8457,8458,8459,8460,8461,8462,8463,8464,\n8465,8466,8467,8468,8469,8470,8471,8472,8473,8474,8475,8476,8477,8478,8479,\n8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490,8491,8492,8493,8494,\n8495,8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8506,8507,8508,8509,\n8510,8511,8512,8513,8514,8515,8516,8517,8518,8519,8520,8521,8522,8523,8524,\n8525,8498,8527,8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538,8539,\n8540,8541,8542,8543,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,\n8555,8556,8557,8558,8559,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,\n8554,8555,8556,8557,8558,8559,8576,8577,8578,8579,8579,8581,8582,8583,8584,\n8585,8586,8587,8588,8589,8590,8591,8592,8593,8594,8595,8596,8597,8598,8599,\n8600,8601,8602,8603,8604,8605,8606,8607,8608,8609,8610,8611,8612,8613,8614,\n8615,8616,8617,8618,8619,8620,8621,8622,8623,8624,8625,8626,8627,8628,8629,\n8630,8631,8632,8633,8634,8635,8636,8637,8638,8639,8640,8641,8642,8643,8644,\n8645,8646,8647,8648,8649,8650,8651,8652,8653,8654,8655,8656,8657,8658,8659,\n8660,8661,8662,8663,8664,8665,8666,8667,8668,8669,8670,8671,8672,8673,8674,\n8675,8676,8677,8678,8679,8680,8681,8682,8683,8684,8685,8686,8687,8688,8689,\n8690,8691,8692,8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703,8704,\n8705,8706,8707,8708,8709,8710,8711,8712,8713,8714,8715,8716,8717,8718,8719,\n8720,8721,8722,8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,8734,\n8735,8736,8737,8738,8739,8740,8741,8742,8743,8744,8745,8746,8747,8748,8749,\n8750,8751,8752,8753,8754,8755,8756,8757,8758,8759,8760,8761,8762,8763,8764,\n8765,8766,8767,8768,8769,8770,8771,8772,8773,8774,8775,8776,8777,8778,8779,\n8780,8781,8782,8783,8784,8785,8786,8787,8788,8789,8790,8791,8792,8793,8794,\n8795,8796,8797,8798,8799,8800,8801,8802,8803,8804,8805,8806,8807,8808,8809,\n8810,8811,8812,8813,8814,8815,8816,8817,8818,8819,8820,8821,8822,8823,8824,\n8825,8826,8827,8828,8829,8830,8831,8832,8833,8834,8835,8836,8837,8838,8839,\n8840,8841,8842,8843,8844,8845,8846,8847,8848,8849,8850,8851,8852,8853,8854,\n8855,8856,8857,8858,8859,8860,8861,8862,8863,8864,8865,8866,8867,8868,8869,\n8870,8871,8872,8873,8874,8875,8876,8877,8878,8879,8880,8881,8882,8883,8884,\n8885,8886,8887,8888,8889,8890,8891,8892,8893,8894,8895,8896,8897,8898,8899,\n8900,8901,8902,8903,8904,8905,8906,8907,8908,8909,8910,8911,8912,8913,8914,\n8915,8916,8917,8918,8919,8920,8921,8922,8923,8924,8925,8926,8927,8928,8929,\n8930,8931,8932,8933,8934,8935,8936,8937,8938,8939,8940,8941,8942,8943,8944,\n8945,8946,8947,8948,8949,8950,8951,8952,8953,8954,8955,8956,8957,8958,8959,\n8960,8961,8962,8963,8964,8965,8966,8967,8968,8969,8970,8971,8972,8973,8974,\n8975,8976,8977,8978,8979,8980,8981,8982,8983,8984,8985,8986,8987,8988,8989,\n8990,8991,8992,8993,8994,8995,8996,8997,8998,8999,9000,9001,9002,9003,9004,\n9005,9006,9007,9008,9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019,\n9020,9021,9022,9023,9024,9025,9026,9027,9028,9029,9030,9031,9032,9033,9034,\n9035,9036,9037,9038,9039,9040,9041,9042,9043,9044,9045,9046,9047,9048,9049,\n9050,9051,9052,9053,9054,9055,9056,9057,9058,9059,9060,9061,9062,9063,9064,\n9065,9066,9067,9068,9069,9070,9071,9072,9073,9074,9075,9076,9077,9078,9079,\n9080,9081,9082,9083,9084,9085,9086,9087,9088,9089,9090,9091,9092,9093,9094,\n9095,9096,9097,9098,9099,9100,9101,9102,9103,9104,9105,9106,9107,9108,9109,\n9110,9111,9112,9113,9114,9115,9116,9117,9118,9119,9120,9121,9122,9123,9124,\n9125,9126,9127,9128,9129,9130,9131,9132,9133,9134,9135,9136,9137,9138,9139,\n9140,9141,9142,9143,9144,9145,9146,9147,9148,9149,9150,9151,9152,9153,9154,\n9155,9156,9157,9158,9159,9160,9161,9162,9163,9164,9165,9166,9167,9168,9169,\n9170,9171,9172,9173,9174,9175,9176,9177,9178,9179,9180,9181,9182,9183,9184,\n9185,9186,9187,9188,9189,9190,9191,9192,9193,9194,9195,9196,9197,9198,9199,\n9200,9201,9202,9203,9204,9205,9206,9207,9208,9209,9210,9211,9212,9213,9214,\n9215,9216,9217,9218,9219,9220,9221,9222,9223,9224,9225,9226,9227,9228,9229,\n9230,9231,9232,9233,9234,9235,9236,9237,9238,9239,9240,9241,9242,9243,9244,\n9245,9246,9247,9248,9249,9250,9251,9252,9253,9254,9255,9256,9257,9258,9259,\n9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273,9274,\n9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288,9289,\n9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,9303,9304,\n9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,9318,9319,\n9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,9332,9333,9334,\n9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,9346,9347,9348,9349,\n9350,9351,9352,9353,9354,9355,9356,9357,9358,9359,9360,9361,9362,9363,9364,\n9365,9366,9367,9368,9369,9370,9371,9372,9373,9374,9375,9376,9377,9378,9379,\n9380,9381,9382,9383,9384,9385,9386,9387,9388,9389,9390,9391,9392,9393,9394,\n9395,9396,9397,9398,9399,9400,9401,9402,9403,9404,9405,9406,9407,9408,9409,\n9410,9411,9412,9413,9414,9415,9416,9417,9418,9419,9420,9421,9422,9423,9398,\n9399,9400,9401,9402,9403,9404,9405,9406,9407,9408,9409,9410,9411,9412,9413,\n9414,9415,9416,9417,9418,9419,9420,9421,9422,9423,9450,9451,9452,9453,9454,\n9455,9456,9457,9458,9459,9460,9461,9462,9463,9464,9465,9466,9467,9468,9469,\n9470,9471,9472,9473,9474,9475,9476,9477,9478,9479,9480,9481,9482,9483,9484,\n9485,9486,9487,9488,9489,9490,9491,9492,9493,9494,9495,9496,9497,9498,9499,\n9500,9501,9502,9503,9504,9505,9506,9507,9508,9509,9510,9511,9512,9513,9514,\n9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525,9526,9527,9528,9529,\n9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541,9542,9543,9544,\n9545,9546,9547,9548,9549,9550,9551,9552,9553,9554,9555,9556,9557,9558,9559,\n9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,\n9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9588,9589,\n9590,9591,9592,9593,9594,9595,9596,9597,9598,9599,9600,9601,9602,9603,9604,\n9605,9606,9607,9608,9609,9610,9611,9612,9613,9614,9615,9616,9617,9618,9619,\n9620,9621,9622,9623,9624,9625,9626,9627,9628,9629,9630,9631,9632,9633,9634,\n9635,9636,9637,9638,9639,9640,9641,9642,9643,9644,9645,9646,9647,9648,9649,\n9650,9651,9652,9653,9654,9655,9656,9657,9658,9659,9660,9661,9662,9663,9664,\n9665,9666,9667,9668,9669,9670,9671,9672,9673,9674,9675,9676,9677,9678,9679,\n9680,9681,9682,9683,9684,9685,9686,9687,9688,9689,9690,9691,9692,9693,9694,\n9695,9696,9697,9698,9699,9700,9701,9702,9703,9704,9705,9706,9707,9708,9709,\n9710,9711,9712,9713,9714,9715,9716,9717,9718,9719,9720,9721,9722,9723,9724,\n9725,9726,9727,9728,9729,9730,9731,9732,9733,9734,9735,9736,9737,9738,9739,\n9740,9741,9742,9743,9744,9745,9746,9747,9748,9749,9750,9751,9752,9753,9754,\n9755,9756,9757,9758,9759,9760,9761,9762,9763,9764,9765,9766,9767,9768,9769,\n9770,9771,9772,9773,9774,9775,9776,9777,9778,9779,9780,9781,9782,9783,9784,\n9785,9786,9787,9788,9789,9790,9791,9792,9793,9794,9795,9796,9797,9798,9799,\n9800,9801,9802,9803,9804,9805,9806,9807,9808,9809,9810,9811,9812,9813,9814,\n9815,9816,9817,9818,9819,9820,9821,9822,9823,9824,9825,9826,9827,9828,9829,\n9830,9831,9832,9833,9834,9835,9836,9837,9838,9839,9840,9841,9842,9843,9844,\n9845,9846,9847,9848,9849,9850,9851,9852,9853,9854,9855,9856,9857,9858,9859,\n9860,9861,9862,9863,9864,9865,9866,9867,9868,9869,9870,9871,9872,9873,9874,\n9875,9876,9877,9878,9879,9880,9881,9882,9883,9884,9885,9886,9887,9888,9889,\n9890,9891,9892,9893,9894,9895,9896,9897,9898,9899,9900,9901,9902,9903,9904,\n9905,9906,9907,9908,9909,9910,9911,9912,9913,9914,9915,9916,9917,9918,9919,\n9920,9921,9922,9923,9924,9925,9926,9927,9928,9929,9930,9931,9932,9933,9934,\n9935,9936,9937,9938,9939,9940,9941,9942,9943,9944,9945,9946,9947,9948,9949,\n9950,9951,9952,9953,9954,9955,9956,9957,9958,9959,9960,9961,9962,9963,9964,\n9965,9966,9967,9968,9969,9970,9971,9972,9973,9974,9975,9976,9977,9978,9979,\n9980,9981,9982,9983,9984,9985,9986,9987,9988,9989,9990,9991,9992,9993,9994,\n9995,9996,9997,9998,9999,10000,10001,10002,10003,10004,10005,10006,10007,\n10008,10009,10010,10011,10012,10013,10014,10015,10016,10017,10018,10019,\n10020,10021,10022,10023,10024,10025,10026,10027,10028,10029,10030,10031,\n10032,10033,10034,10035,10036,10037,10038,10039,10040,10041,10042,10043,\n10044,10045,10046,10047,10048,10049,10050,10051,10052,10053,10054,10055,\n10056,10057,10058,10059,10060,10061,10062,10063,10064,10065,10066,10067,\n10068,10069,10070,10071,10072,10073,10074,10075,10076,10077,10078,10079,\n10080,10081,10082,10083,10084,10085,10086,10087,10088,10089,10090,10091,\n10092,10093,10094,10095,10096,10097,10098,10099,10100,10101,10102,10103,\n10104,10105,10106,10107,10108,10109,10110,10111,10112,10113,10114,10115,\n10116,10117,10118,10119,10120,10121,10122,10123,10124,10125,10126,10127,\n10128,10129,10130,10131,10132,10133,10134,10135,10136,10137,10138,10139,\n10140,10141,10142,10143,10144,10145,10146,10147,10148,10149,10150,10151,\n10152,10153,10154,10155,10156,10157,10158,10159,10160,10161,10162,10163,\n10164,10165,10166,10167,10168,10169,10170,10171,10172,10173,10174,10175,\n10176,10177,10178,10179,10180,10181,10182,10183,10184,10185,10186,10187,\n10188,10189,10190,10191,10192,10193,10194,10195,10196,10197,10198,10199,\n10200,10201,10202,10203,10204,10205,10206,10207,10208,10209,10210,10211,\n10212,10213,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,\n10224,10225,10226,10227,10228,10229,10230,10231,10232,10233,10234,10235,\n10236,10237,10238,10239,10240,10241,10242,10243,10244,10245,10246,10247,\n10248,10249,10250,10251,10252,10253,10254,10255,10256,10257,10258,10259,\n10260,10261,10262,10263,10264,10265,10266,10267,10268,10269,10270,10271,\n10272,10273,10274,10275,10276,10277,10278,10279,10280,10281,10282,10283,\n10284,10285,10286,10287,10288,10289,10290,10291,10292,10293,10294,10295,\n10296,10297,10298,10299,10300,10301,10302,10303,10304,10305,10306,10307,\n10308,10309,10310,10311,10312,10313,10314,10315,10316,10317,10318,10319,\n10320,10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,10331,\n10332,10333,10334,10335,10336,10337,10338,10339,10340,10341,10342,10343,\n10344,10345,10346,10347,10348,10349,10350,10351,10352,10353,10354,10355,\n10356,10357,10358,10359,10360,10361,10362,10363,10364,10365,10366,10367,\n10368,10369,10370,10371,10372,10373,10374,10375,10376,10377,10378,10379,\n10380,10381,10382,10383,10384,10385,10386,10387,10388,10389,10390,10391,\n10392,10393,10394,10395,10396,10397,10398,10399,10400,10401,10402,10403,\n10404,10405,10406,10407,10408,10409,10410,10411,10412,10413,10414,10415,\n10416,10417,10418,10419,10420,10421,10422,10423,10424,10425,10426,10427,\n10428,10429,10430,10431,10432,10433,10434,10435,10436,10437,10438,10439,\n10440,10441,10442,10443,10444,10445,10446,10447,10448,10449,10450,10451,\n10452,10453,10454,10455,10456,10457,10458,10459,10460,10461,10462,10463,\n10464,10465,10466,10467,10468,10469,10470,10471,10472,10473,10474,10475,\n10476,10477,10478,10479,10480,10481,10482,10483,10484,10485,10486,10487,\n10488,10489,10490,10491,10492,10493,10494,10495,10496,10497,10498,10499,\n10500,10501,10502,10503,10504,10505,10506,10507,10508,10509,10510,10511,\n10512,10513,10514,10515,10516,10517,10518,10519,10520,10521,10522,10523,\n10524,10525,10526,10527,10528,10529,10530,10531,10532,10533,10534,10535,\n10536,10537,10538,10539,10540,10541,10542,10543,10544,10545,10546,10547,\n10548,10549,10550,10551,10552,10553,10554,10555,10556,10557,10558,10559,\n10560,10561,10562,10563,10564,10565,10566,10567,10568,10569,10570,10571,\n10572,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,10583,\n10584,10585,10586,10587,10588,10589,10590,10591,10592,10593,10594,10595,\n10596,10597,10598,10599,10600,10601,10602,10603,10604,10605,10606,10607,\n10608,10609,10610,10611,10612,10613,10614,10615,10616,10617,10618,10619,\n10620,10621,10622,10623,10624,10625,10626,10627,10628,10629,10630,10631,\n10632,10633,10634,10635,10636,10637,10638,10639,10640,10641,10642,10643,\n10644,10645,10646,10647,10648,10649,10650,10651,10652,10653,10654,10655,\n10656,10657,10658,10659,10660,10661,10662,10663,10664,10665,10666,10667,\n10668,10669,10670,10671,10672,10673,10674,10675,10676,10677,10678,10679,\n10680,10681,10682,10683,10684,10685,10686,10687,10688,10689,10690,10691,\n10692,10693,10694,10695,10696,10697,10698,10699,10700,10701,10702,10703,\n10704,10705,10706,10707,10708,10709,10710,10711,10712,10713,10714,10715,\n10716,10717,10718,10719,10720,10721,10722,10723,10724,10725,10726,10727,\n10728,10729,10730,10731,10732,10733,10734,10735,10736,10737,10738,10739,\n10740,10741,10742,10743,10744,10745,10746,10747,10748,10749,10750,10751,\n10752,10753,10754,10755,10756,10757,10758,10759,10760,10761,10762,10763,\n10764,10765,10766,10767,10768,10769,10770,10771,10772,10773,10774,10775,\n10776,10777,10778,10779,10780,10781,10782,10783,10784,10785,10786,10787,\n10788,10789,10790,10791,10792,10793,10794,10795,10796,10797,10798,10799,\n10800,10801,10802,10803,10804,10805,10806,10807,10808,10809,10810,10811,\n10812,10813,10814,10815,10816,10817,10818,10819,10820,10821,10822,10823,\n10824,10825,10826,10827,10828,10829,10830,10831,10832,10833,10834,10835,\n10836,10837,10838,10839,10840,10841,10842,10843,10844,10845,10846,10847,\n10848,10849,10850,10851,10852,10853,10854,10855,10856,10857,10858,10859,\n10860,10861,10862,10863,10864,10865,10866,10867,10868,10869,10870,10871,\n10872,10873,10874,10875,10876,10877,10878,10879,10880,10881,10882,10883,\n10884,10885,10886,10887,10888,10889,10890,10891,10892,10893,10894,10895,\n10896,10897,10898,10899,10900,10901,10902,10903,10904,10905,10906,10907,\n10908,10909,10910,10911,10912,10913,10914,10915,10916,10917,10918,10919,\n10920,10921,10922,10923,10924,10925,10926,10927,10928,10929,10930,10931,\n10932,10933,10934,10935,10936,10937,10938,10939,10940,10941,10942,10943,\n10944,10945,10946,10947,10948,10949,10950,10951,10952,10953,10954,10955,\n10956,10957,10958,10959,10960,10961,10962,10963,10964,10965,10966,10967,\n10968,10969,10970,10971,10972,10973,10974,10975,10976,10977,10978,10979,\n10980,10981,10982,10983,10984,10985,10986,10987,10988,10989,10990,10991,\n10992,10993,10994,10995,10996,10997,10998,10999,11000,11001,11002,11003,\n11004,11005,11006,11007,11008,11009,11010,11011,11012,11013,11014,11015,\n11016,11017,11018,11019,11020,11021,11022,11023,11024,11025,11026,11027,\n11028,11029,11030,11031,11032,11033,11034,11035,11036,11037,11038,11039,\n11040,11041,11042,11043,11044,11045,11046,11047,11048,11049,11050,11051,\n11052,11053,11054,11055,11056,11057,11058,11059,11060,11061,11062,11063,\n11064,11065,11066,11067,11068,11069,11070,11071,11072,11073,11074,11075,\n11076,11077,11078,11079,11080,11081,11082,11083,11084,11085,11086,11087,\n11088,11089,11090,11091,11092,11093,11094,11095,11096,11097,11098,11099,\n11100,11101,11102,11103,11104,11105,11106,11107,11108,11109,11110,11111,\n11112,11113,11114,11115,11116,11117,11118,11119,11120,11121,11122,11123,\n11124,11125,11126,11127,11128,11129,11130,11131,11132,11133,11134,11135,\n11136,11137,11138,11139,11140,11141,11142,11143,11144,11145,11146,11147,\n11148,11149,11150,11151,11152,11153,11154,11155,11156,11157,11158,11159,\n11160,11161,11162,11163,11164,11165,11166,11167,11168,11169,11170,11171,\n11172,11173,11174,11175,11176,11177,11178,11179,11180,11181,11182,11183,\n11184,11185,11186,11187,11188,11189,11190,11191,11192,11193,11194,11195,\n11196,11197,11198,11199,11200,11201,11202,11203,11204,11205,11206,11207,\n11208,11209,11210,11211,11212,11213,11214,11215,11216,11217,11218,11219,\n11220,11221,11222,11223,11224,11225,11226,11227,11228,11229,11230,11231,\n11232,11233,11234,11235,11236,11237,11238,11239,11240,11241,11242,11243,\n11244,11245,11246,11247,11248,11249,11250,11251,11252,11253,11254,11255,\n11256,11257,11258,11259,11260,11261,11262,11263,11264,11265,11266,11267,\n11268,11269,11270,11271,11272,11273,11274,11275,11276,11277,11278,11279,\n11280,11281,11282,11283,11284,11285,11286,11287,11288,11289,11290,11291,\n11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,\n11304,11305,11306,11307,11308,11309,11310,11311,11264,11265,11266,11267,\n11268,11269,11270,11271,11272,11273,11274,11275,11276,11277,11278,11279,\n11280,11281,11282,11283,11284,11285,11286,11287,11288,11289,11290,11291,\n11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,\n11304,11305,11306,11307,11308,11309,11310,11359,11360,11360,11362,11363,\n11364,570,574,11367,11367,11369,11369,11371,11371,11373,11374,11375,11376,\n11377,11378,11378,11380,11381,11381,11383,11384,11385,11386,11387,11388,\n11389,11390,11391,11392,11392,11394,11394,11396,11396,11398,11398,11400,\n11400,11402,11402,11404,11404,11406,11406,11408,11408,11410,11410,11412,\n11412,11414,11414,11416,11416,11418,11418,11420,11420,11422,11422,11424,\n11424,11426,11426,11428,11428,11430,11430,11432,11432,11434,11434,11436,\n11436,11438,11438,11440,11440,11442,11442,11444,11444,11446,11446,11448,\n11448,11450,11450,11452,11452,11454,11454,11456,11456,11458,11458,11460,\n11460,11462,11462,11464,11464,11466,11466,11468,11468,11470,11470,11472,\n11472,11474,11474,11476,11476,11478,11478,11480,11480,11482,11482,11484,\n11484,11486,11486,11488,11488,11490,11490,11492,11493,11494,11495,11496,\n11497,11498,11499,11499,11501,11501,11503,11504,11505,11506,11506,11508,\n11509,11510,11511,11512,11513,11514,11515,11516,11517,11518,11519,4256,\n4257,4258,4259,4260,4261,4262,4263,4264,4265,4266,4267,4268,4269,4270,4271,\n4272,4273,4274,4275,4276,4277,4278,4279,4280,4281,4282,4283,4284,4285,4286,\n4287,4288,4289,4290,4291,4292,4293,11558,4295,11560,11561,11562,11563,\n11564,4301,11566,11567,11568,11569,11570,11571,11572,11573,11574,11575,\n11576,11577,11578,11579,11580,11581,11582,11583,11584,11585,11586,11587,\n11588,11589,11590,11591,11592,11593,11594,11595,11596,11597,11598,11599,\n11600,11601,11602,11603,11604,11605,11606,11607,11608,11609,11610,11611,\n11612,11613,11614,11615,11616,11617,11618,11619,11620,11621,11622,11623,\n11624,11625,11626,11627,11628,11629,11630,11631,11632,11633,11634,11635,\n11636,11637,11638,11639,11640,11641,11642,11643,11644,11645,11646,11647,\n11648,11649,11650,11651,11652,11653,11654,11655,11656,11657,11658,11659,\n11660,11661,11662,11663,11664,11665,11666,11667,11668,11669,11670,11671,\n11672,11673,11674,11675,11676,11677,11678,11679,11680,11681,11682,11683,\n11684,11685,11686,11687,11688,11689,11690,11691,11692,11693,11694,11695,\n11696,11697,11698,11699,11700,11701,11702,11703,11704,11705,11706,11707,\n11708,11709,11710,11711,11712,11713,11714,11715,11716,11717,11718,11719,\n11720,11721,11722,11723,11724,11725,11726,11727,11728,11729,11730,11731,\n11732,11733,11734,11735,11736,11737,11738,11739,11740,11741,11742,11743,\n11744,11745,11746,11747,11748,11749,11750,11751,11752,11753,11754,11755,\n11756,11757,11758,11759,11760,11761,11762,11763,11764,11765,11766,11767,\n11768,11769,11770,11771,11772,11773,11774,11775,11776,11777,11778,11779,\n11780,11781,11782,11783,11784,11785,11786,11787,11788,11789,11790,11791,\n11792,11793,11794,11795,11796,11797,11798,11799,11800,11801,11802,11803,\n11804,11805,11806,11807,11808,11809,11810,11811,11812,11813,11814,11815,\n11816,11817,11818,11819,11820,11821,11822,11823,11824,11825,11826,11827,\n11828,11829,11830,11831,11832,11833,11834,11835,11836,11837,11838,11839,\n11840,11841,11842,11843,11844,11845,11846,11847,11848,11849,11850,11851,\n11852,11853,11854,11855,11856,11857,11858,11859,11860,11861,11862,11863,\n11864,11865,11866,11867,11868,11869,11870,11871,11872,11873,11874,11875,\n11876,11877,11878,11879,11880,11881,11882,11883,11884,11885,11886,11887,\n11888,11889,11890,11891,11892,11893,11894,11895,11896,11897,11898,11899,\n11900,11901,11902,11903,11904,11905,11906,11907,11908,11909,11910,11911,\n11912,11913,11914,11915,11916,11917,11918,11919,11920,11921,11922,11923,\n11924,11925,11926,11927,11928,11929,11930,11931,11932,11933,11934,11935,\n11936,11937,11938,11939,11940,11941,11942,11943,11944,11945,11946,11947,\n11948,11949,11950,11951,11952,11953,11954,11955,11956,11957,11958,11959,\n11960,11961,11962,11963,11964,11965,11966,11967,11968,11969,11970,11971,\n11972,11973,11974,11975,11976,11977,11978,11979,11980,11981,11982,11983,\n11984,11985,11986,11987,11988,11989,11990,11991,11992,11993,11994,11995,\n11996,11997,11998,11999,12000,12001,12002,12003,12004,12005,12006,12007,\n12008,12009,12010,12011,12012,12013,12014,12015,12016,12017,12018,12019,\n12020,12021,12022,12023,12024,12025,12026,12027,12028,12029,12030,12031,\n12032,12033,12034,12035,12036,12037,12038,12039,12040,12041,12042,12043,\n12044,12045,12046,12047,12048,12049,12050,12051,12052,12053,12054,12055,\n12056,12057,12058,12059,12060,12061,12062,12063,12064,12065,12066,12067,\n12068,12069,12070,12071,12072,12073,12074,12075,12076,12077,12078,12079,\n12080,12081,12082,12083,12084,12085,12086,12087,12088,12089,12090,12091,\n12092,12093,12094,12095,12096,12097,12098,12099,12100,12101,12102,12103,\n12104,12105,12106,12107,12108,12109,12110,12111,12112,12113,12114,12115,\n12116,12117,12118,12119,12120,12121,12122,12123,12124,12125,12126,12127,\n12128,12129,12130,12131,12132,12133,12134,12135,12136,12137,12138,12139,\n12140,12141,12142,12143,12144,12145,12146,12147,12148,12149,12150,12151,\n12152,12153,12154,12155,12156,12157,12158,12159,12160,12161,12162,12163,\n12164,12165,12166,12167,12168,12169,12170,12171,12172,12173,12174,12175,\n12176,12177,12178,12179,12180,12181,12182,12183,12184,12185,12186,12187,\n12188,12189,12190,12191,12192,12193,12194,12195,12196,12197,12198,12199,\n12200,12201,12202,12203,12204,12205,12206,12207,12208,12209,12210,12211,\n12212,12213,12214,12215,12216,12217,12218,12219,12220,12221,12222,12223,\n12224,12225,12226,12227,12228,12229,12230,12231,12232,12233,12234,12235,\n12236,12237,12238,12239,12240,12241,12242,12243,12244,12245,12246,12247,\n12248,12249,12250,12251,12252,12253,12254,12255,12256,12257,12258,12259,\n12260,12261,12262,12263,12264,12265,12266,12267,12268,12269,12270,12271,\n12272,12273,12274,12275,12276,12277,12278,12279,12280,12281,12282,12283,\n12284,12285,12286,12287,12288,12289,12290,12291,12292,12293,12294,12295,\n12296,12297,12298,12299,12300,12301,12302,12303,12304,12305,12306,12307,\n12308,12309,12310,12311,12312,12313,12314,12315,12316,12317,12318,12319,\n12320,12321,12322,12323,12324,12325,12326,12327,12328,12329,12330,12331,\n12332,12333,12334,12335,12336,12337,12338,12339,12340,12341,12342,12343,\n12344,12345,12346,12347,12348,12349,12350,12351,12352,12353,12354,12355,\n12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,\n12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,\n12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,\n12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,\n12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,\n12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,\n12428,12429,12430,12431,12432,12433,12434,12435,12436,12437,12438,12439,\n12440,12441,12442,12443,12444,12445,12446,12447,12448,12449,12450,12451,\n12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,12463,\n12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,\n12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,\n12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,\n12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,\n12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,\n12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,12535,\n12536,12537,12538,12539,12540,12541,12542,12543,12544,12545,12546,12547,\n12548,12549,12550,12551,12552,12553,12554,12555,12556,12557,12558,12559,\n12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570,12571,\n12572,12573,12574,12575,12576,12577,12578,12579,12580,12581,12582,12583,\n12584,12585,12586,12587,12588,12589,12590,12591,12592,12593,12594,12595,\n12596,12597,12598,12599,12600,12601,12602,12603,12604,12605,12606,12607,\n12608,12609,12610,12611,12612,12613,12614,12615,12616,12617,12618,12619,\n12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,12631,\n12632,12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643,\n12644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654,12655,\n12656,12657,12658,12659,12660,12661,12662,12663,12664,12665,12666,12667,\n12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679,\n12680,12681,12682,12683,12684,12685,12686,12687,12688,12689,12690,12691,\n12692,12693,12694,12695,12696,12697,12698,12699,12700,12701,12702,12703,\n12704,12705,12706,12707,12708,12709,12710,12711,12712,12713,12714,12715,\n12716,12717,12718,12719,12720,12721,12722,12723,12724,12725,12726,12727,\n12728,12729,12730,12731,12732,12733,12734,12735,12736,12737,12738,12739,\n12740,12741,12742,12743,12744,12745,12746,12747,12748,12749,12750,12751,\n12752,12753,12754,12755,12756,12757,12758,12759,12760,12761,12762,12763,\n12764,12765,12766,12767,12768,12769,12770,12771,12772,12773,12774,12775,\n12776,12777,12778,12779,12780,12781,12782,12783,12784,12785,12786,12787,\n12788,12789,12790,12791,12792,12793,12794,12795,12796,12797,12798,12799,\n12800,12801,12802,12803,12804,12805,12806,12807,12808,12809,12810,12811,\n12812,12813,12814,12815,12816,12817,12818,12819,12820,12821,12822,12823,\n12824,12825,12826,12827,12828,12829,12830,12831,12832,12833,12834,12835,\n12836,12837,12838,12839,12840,12841,12842,12843,12844,12845,12846,12847,\n12848,12849,12850,12851,12852,12853,12854,12855,12856,12857,12858,12859,\n12860,12861,12862,12863,12864,12865,12866,12867,12868,12869,12870,12871,\n12872,12873,12874,12875,12876,12877,12878,12879,12880,12881,12882,12883,\n12884,12885,12886,12887,12888,12889,12890,12891,12892,12893,12894,12895,\n12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906,12907,\n12908,12909,12910,12911,12912,12913,12914,12915,12916,12917,12918,12919,\n12920,12921,12922,12923,12924,12925,12926,12927,12928,12929,12930,12931,\n12932,12933,12934,12935,12936,12937,12938,12939,12940,12941,12942,12943,\n12944,12945,12946,12947,12948,12949,12950,12951,12952,12953,12954,12955,\n12956,12957,12958,12959,12960,12961,12962,12963,12964,12965,12966,12967,\n12968,12969,12970,12971,12972,12973,12974,12975,12976,12977,12978,12979,\n12980,12981,12982,12983,12984,12985,12986,12987,12988,12989,12990,12991,\n12992,12993,12994,12995,12996,12997,12998,12999,13000,13001,13002,13003,\n13004,13005,13006,13007,13008,13009,13010,13011,13012,13013,13014,13015,\n13016,13017,13018,13019,13020,13021,13022,13023,13024,13025,13026,13027,\n13028,13029,13030,13031,13032,13033,13034,13035,13036,13037,13038,13039,\n13040,13041,13042,13043,13044,13045,13046,13047,13048,13049,13050,13051,\n13052,13053,13054,13055,13056,13057,13058,13059,13060,13061,13062,13063,\n13064,13065,13066,13067,13068,13069,13070,13071,13072,13073,13074,13075,\n13076,13077,13078,13079,13080,13081,13082,13083,13084,13085,13086,13087,\n13088,13089,13090,13091,13092,13093,13094,13095,13096,13097,13098,13099,\n13100,13101,13102,13103,13104,13105,13106,13107,13108,13109,13110,13111,\n13112,13113,13114,13115,13116,13117,13118,13119,13120,13121,13122,13123,\n13124,13125,13126,13127,13128,13129,13130,13131,13132,13133,13134,13135,\n13136,13137,13138,13139,13140,13141,13142,13143,13144,13145,13146,13147,\n13148,13149,13150,13151,13152,13153,13154,13155,13156,13157,13158,13159,\n13160,13161,13162,13163,13164,13165,13166,13167,13168,13169,13170,13171,\n13172,13173,13174,13175,13176,13177,13178,13179,13180,13181,13182,13183,\n13184,13185,13186,13187,13188,13189,13190,13191,13192,13193,13194,13195,\n13196,13197,13198,13199,13200,13201,13202,13203,13204,13205,13206,13207,\n13208,13209,13210,13211,13212,13213,13214,13215,13216,13217,13218,13219,\n13220,13221,13222,13223,13224,13225,13226,13227,13228,13229,13230,13231,\n13232,13233,13234,13235,13236,13237,13238,13239,13240,13241,13242,13243,\n13244,13245,13246,13247,13248,13249,13250,13251,13252,13253,13254,13255,\n13256,13257,13258,13259,13260,13261,13262,13263,13264,13265,13266,13267,\n13268,13269,13270,13271,13272,13273,13274,13275,13276,13277,13278,13279,\n13280,13281,13282,13283,13284,13285,13286,13287,13288,13289,13290,13291,\n13292,13293,13294,13295,13296,13297,13298,13299,13300,13301,13302,13303,\n13304,13305,13306,13307,13308,13309,13310,13311,13312,13313,13314,13315,\n13316,13317,13318,13319,13320,13321,13322,13323,13324,13325,13326,13327,\n13328,13329,13330,13331,13332,13333,13334,13335,13336,13337,13338,13339,\n13340,13341,13342,13343,13344,13345,13346,13347,13348,13349,13350,13351,\n13352,13353,13354,13355,13356,13357,13358,13359,13360,13361,13362,13363,\n13364,13365,13366,13367,13368,13369,13370,13371,13372,13373,13374,13375,\n13376,13377,13378,13379,13380,13381,13382,13383,13384,13385,13386,13387,\n13388,13389,13390,13391,13392,13393,13394,13395,13396,13397,13398,13399,\n13400,13401,13402,13403,13404,13405,13406,13407,13408,13409,13410,13411,\n13412,13413,13414,13415,13416,13417,13418,13419,13420,13421,13422,13423,\n13424,13425,13426,13427,13428,13429,13430,13431,13432,13433,13434,13435,\n13436,13437,13438,13439,13440,13441,13442,13443,13444,13445,13446,13447,\n13448,13449,13450,13451,13452,13453,13454,13455,13456,13457,13458,13459,\n13460,13461,13462,13463,13464,13465,13466,13467,13468,13469,13470,13471,\n13472,13473,13474,13475,13476,13477,13478,13479,13480,13481,13482,13483,\n13484,13485,13486,13487,13488,13489,13490,13491,13492,13493,13494,13495,\n13496,13497,13498,13499,13500,13501,13502,13503,13504,13505,13506,13507,\n13508,13509,13510,13511,13512,13513,13514,13515,13516,13517,13518,13519,\n13520,13521,13522,13523,13524,13525,13526,13527,13528,13529,13530,13531,\n13532,13533,13534,13535,13536,13537,13538,13539,13540,13541,13542,13543,\n13544,13545,13546,13547,13548,13549,13550,13551,13552,13553,13554,13555,\n13556,13557,13558,13559,13560,13561,13562,13563,13564,13565,13566,13567,\n13568,13569,13570,13571,13572,13573,13574,13575,13576,13577,13578,13579,\n13580,13581,13582,13583,13584,13585,13586,13587,13588,13589,13590,13591,\n13592,13593,13594,13595,13596,13597,13598,13599,13600,13601,13602,13603,\n13604,13605,13606,13607,13608,13609,13610,13611,13612,13613,13614,13615,\n13616,13617,13618,13619,13620,13621,13622,13623,13624,13625,13626,13627,\n13628,13629,13630,13631,13632,13633,13634,13635,13636,13637,13638,13639,\n13640,13641,13642,13643,13644,13645,13646,13647,13648,13649,13650,13651,\n13652,13653,13654,13655,13656,13657,13658,13659,13660,13661,13662,13663,\n13664,13665,13666,13667,13668,13669,13670,13671,13672,13673,13674,13675,\n13676,13677,13678,13679,13680,13681,13682,13683,13684,13685,13686,13687,\n13688,13689,13690,13691,13692,13693,13694,13695,13696,13697,13698,13699,\n13700,13701,13702,13703,13704,13705,13706,13707,13708,13709,13710,13711,\n13712,13713,13714,13715,13716,13717,13718,13719,13720,13721,13722,13723,\n13724,13725,13726,13727,13728,13729,13730,13731,13732,13733,13734,13735,\n13736,13737,13738,13739,13740,13741,13742,13743,13744,13745,13746,13747,\n13748,13749,13750,13751,13752,13753,13754,13755,13756,13757,13758,13759,\n13760,13761,13762,13763,13764,13765,13766,13767,13768,13769,13770,13771,\n13772,13773,13774,13775,13776,13777,13778,13779,13780,13781,13782,13783,\n13784,13785,13786,13787,13788,13789,13790,13791,13792,13793,13794,13795,\n13796,13797,13798,13799,13800,13801,13802,13803,13804,13805,13806,13807,\n13808,13809,13810,13811,13812,13813,13814,13815,13816,13817,13818,13819,\n13820,13821,13822,13823,13824,13825,13826,13827,13828,13829,13830,13831,\n13832,13833,13834,13835,13836,13837,13838,13839,13840,13841,13842,13843,\n13844,13845,13846,13847,13848,13849,13850,13851,13852,13853,13854,13855,\n13856,13857,13858,13859,13860,13861,13862,13863,13864,13865,13866,13867,\n13868,13869,13870,13871,13872,13873,13874,13875,13876,13877,13878,13879,\n13880,13881,13882,13883,13884,13885,13886,13887,13888,13889,13890,13891,\n13892,13893,13894,13895,13896,13897,13898,13899,13900,13901,13902,13903,\n13904,13905,13906,13907,13908,13909,13910,13911,13912,13913,13914,13915,\n13916,13917,13918,13919,13920,13921,13922,13923,13924,13925,13926,13927,\n13928,13929,13930,13931,13932,13933,13934,13935,13936,13937,13938,13939,\n13940,13941,13942,13943,13944,13945,13946,13947,13948,13949,13950,13951,\n13952,13953,13954,13955,13956,13957,13958,13959,13960,13961,13962,13963,\n13964,13965,13966,13967,13968,13969,13970,13971,13972,13973,13974,13975,\n13976,13977,13978,13979,13980,13981,13982,13983,13984,13985,13986,13987,\n13988,13989,13990,13991,13992,13993,13994,13995,13996,13997,13998,13999,\n14000,14001,14002,14003,14004,14005,14006,14007,14008,14009,14010,14011,\n14012,14013,14014,14015,14016,14017,14018,14019,14020,14021,14022,14023,\n14024,14025,14026,14027,14028,14029,14030,14031,14032,14033,14034,14035,\n14036,14037,14038,14039,14040,14041,14042,14043,14044,14045,14046,14047,\n14048,14049,14050,14051,14052,14053,14054,14055,14056,14057,14058,14059,\n14060,14061,14062,14063,14064,14065,14066,14067,14068,14069,14070,14071,\n14072,14073,14074,14075,14076,14077,14078,14079,14080,14081,14082,14083,\n14084,14085,14086,14087,14088,14089,14090,14091,14092,14093,14094,14095,\n14096,14097,14098,14099,14100,14101,14102,14103,14104,14105,14106,14107,\n14108,14109,14110,14111,14112,14113,14114,14115,14116,14117,14118,14119,\n14120,14121,14122,14123,14124,14125,14126,14127,14128,14129,14130,14131,\n14132,14133,14134,14135,14136,14137,14138,14139,14140,14141,14142,14143,\n14144,14145,14146,14147,14148,14149,14150,14151,14152,14153,14154,14155,\n14156,14157,14158,14159,14160,14161,14162,14163,14164,14165,14166,14167,\n14168,14169,14170,14171,14172,14173,14174,14175,14176,14177,14178,14179,\n14180,14181,14182,14183,14184,14185,14186,14187,14188,14189,14190,14191,\n14192,14193,14194,14195,14196,14197,14198,14199,14200,14201,14202,14203,\n14204,14205,14206,14207,14208,14209,14210,14211,14212,14213,14214,14215,\n14216,14217,14218,14219,14220,14221,14222,14223,14224,14225,14226,14227,\n14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14238,14239,\n14240,14241,14242,14243,14244,14245,14246,14247,14248,14249,14250,14251,\n14252,14253,14254,14255,14256,14257,14258,14259,14260,14261,14262,14263,\n14264,14265,14266,14267,14268,14269,14270,14271,14272,14273,14274,14275,\n14276,14277,14278,14279,14280,14281,14282,14283,14284,14285,14286,14287,\n14288,14289,14290,14291,14292,14293,14294,14295,14296,14297,14298,14299,\n14300,14301,14302,14303,14304,14305,14306,14307,14308,14309,14310,14311,\n14312,14313,14314,14315,14316,14317,14318,14319,14320,14321,14322,14323,\n14324,14325,14326,14327,14328,14329,14330,14331,14332,14333,14334,14335,\n14336,14337,14338,14339,14340,14341,14342,14343,14344,14345,14346,14347,\n14348,14349,14350,14351,14352,14353,14354,14355,14356,14357,14358,14359,\n14360,14361,14362,14363,14364,14365,14366,14367,14368,14369,14370,14371,\n14372,14373,14374,14375,14376,14377,14378,14379,14380,14381,14382,14383,\n14384,14385,14386,14387,14388,14389,14390,14391,14392,14393,14394,14395,\n14396,14397,14398,14399,14400,14401,14402,14403,14404,14405,14406,14407,\n14408,14409,14410,14411,14412,14413,14414,14415,14416,14417,14418,14419,\n14420,14421,14422,14423,14424,14425,14426,14427,14428,14429,14430,14431,\n14432,14433,14434,14435,14436,14437,14438,14439,14440,14441,14442,14443,\n14444,14445,14446,14447,14448,14449,14450,14451,14452,14453,14454,14455,\n14456,14457,14458,14459,14460,14461,14462,14463,14464,14465,14466,14467,\n14468,14469,14470,14471,14472,14473,14474,14475,14476,14477,14478,14479,\n14480,14481,14482,14483,14484,14485,14486,14487,14488,14489,14490,14491,\n14492,14493,14494,14495,14496,14497,14498,14499,14500,14501,14502,14503,\n14504,14505,14506,14507,14508,14509,14510,14511,14512,14513,14514,14515,\n14516,14517,14518,14519,14520,14521,14522,14523,14524,14525,14526,14527,\n14528,14529,14530,14531,14532,14533,14534,14535,14536,14537,14538,14539,\n14540,14541,14542,14543,14544,14545,14546,14547,14548,14549,14550,14551,\n14552,14553,14554,14555,14556,14557,14558,14559,14560,14561,14562,14563,\n14564,14565,14566,14567,14568,14569,14570,14571,14572,14573,14574,14575,\n14576,14577,14578,14579,14580,14581,14582,14583,14584,14585,14586,14587,\n14588,14589,14590,14591,14592,14593,14594,14595,14596,14597,14598,14599,\n14600,14601,14602,14603,14604,14605,14606,14607,14608,14609,14610,14611,\n14612,14613,14614,14615,14616,14617,14618,14619,14620,14621,14622,14623,\n14624,14625,14626,14627,14628,14629,14630,14631,14632,14633,14634,14635,\n14636,14637,14638,14639,14640,14641,14642,14643,14644,14645,14646,14647,\n14648,14649,14650,14651,14652,14653,14654,14655,14656,14657,14658,14659,\n14660,14661,14662,14663,14664,14665,14666,14667,14668,14669,14670,14671,\n14672,14673,14674,14675,14676,14677,14678,14679,14680,14681,14682,14683,\n14684,14685,14686,14687,14688,14689,14690,14691,14692,14693,14694,14695,\n14696,14697,14698,14699,14700,14701,14702,14703,14704,14705,14706,14707,\n14708,14709,14710,14711,14712,14713,14714,14715,14716,14717,14718,14719,\n14720,14721,14722,14723,14724,14725,14726,14727,14728,14729,14730,14731,\n14732,14733,14734,14735,14736,14737,14738,14739,14740,14741,14742,14743,\n14744,14745,14746,14747,14748,14749,14750,14751,14752,14753,14754,14755,\n14756,14757,14758,14759,14760,14761,14762,14763,14764,14765,14766,14767,\n14768,14769,14770,14771,14772,14773,14774,14775,14776,14777,14778,14779,\n14780,14781,14782,14783,14784,14785,14786,14787,14788,14789,14790,14791,\n14792,14793,14794,14795,14796,14797,14798,14799,14800,14801,14802,14803,\n14804,14805,14806,14807,14808,14809,14810,14811,14812,14813,14814,14815,\n14816,14817,14818,14819,14820,14821,14822,14823,14824,14825,14826,14827,\n14828,14829,14830,14831,14832,14833,14834,14835,14836,14837,14838,14839,\n14840,14841,14842,14843,14844,14845,14846,14847,14848,14849,14850,14851,\n14852,14853,14854,14855,14856,14857,14858,14859,14860,14861,14862,14863,\n14864,14865,14866,14867,14868,14869,14870,14871,14872,14873,14874,14875,\n14876,14877,14878,14879,14880,14881,14882,14883,14884,14885,14886,14887,\n14888,14889,14890,14891,14892,14893,14894,14895,14896,14897,14898,14899,\n14900,14901,14902,14903,14904,14905,14906,14907,14908,14909,14910,14911,\n14912,14913,14914,14915,14916,14917,14918,14919,14920,14921,14922,14923,\n14924,14925,14926,14927,14928,14929,14930,14931,14932,14933,14934,14935,\n14936,14937,14938,14939,14940,14941,14942,14943,14944,14945,14946,14947,\n14948,14949,14950,14951,14952,14953,14954,14955,14956,14957,14958,14959,\n14960,14961,14962,14963,14964,14965,14966,14967,14968,14969,14970,14971,\n14972,14973,14974,14975,14976,14977,14978,14979,14980,14981,14982,14983,\n14984,14985,14986,14987,14988,14989,14990,14991,14992,14993,14994,14995,\n14996,14997,14998,14999,15000,15001,15002,15003,15004,15005,15006,15007,\n15008,15009,15010,15011,15012,15013,15014,15015,15016,15017,15018,15019,\n15020,15021,15022,15023,15024,15025,15026,15027,15028,15029,15030,15031,\n15032,15033,15034,15035,15036,15037,15038,15039,15040,15041,15042,15043,\n15044,15045,15046,15047,15048,15049,15050,15051,15052,15053,15054,15055,\n15056,15057,15058,15059,15060,15061,15062,15063,15064,15065,15066,15067,\n15068,15069,15070,15071,15072,15073,15074,15075,15076,15077,15078,15079,\n15080,15081,15082,15083,15084,15085,15086,15087,15088,15089,15090,15091,\n15092,15093,15094,15095,15096,15097,15098,15099,15100,15101,15102,15103,\n15104,15105,15106,15107,15108,15109,15110,15111,15112,15113,15114,15115,\n15116,15117,15118,15119,15120,15121,15122,15123,15124,15125,15126,15127,\n15128,15129,15130,15131,15132,15133,15134,15135,15136,15137,15138,15139,\n15140,15141,15142,15143,15144,15145,15146,15147,15148,15149,15150,15151,\n15152,15153,15154,15155,15156,15157,15158,15159,15160,15161,15162,15163,\n15164,15165,15166,15167,15168,15169,15170,15171,15172,15173,15174,15175,\n15176,15177,15178,15179,15180,15181,15182,15183,15184,15185,15186,15187,\n15188,15189,15190,15191,15192,15193,15194,15195,15196,15197,15198,15199,\n15200,15201,15202,15203,15204,15205,15206,15207,15208,15209,15210,15211,\n15212,15213,15214,15215,15216,15217,15218,15219,15220,15221,15222,15223,\n15224,15225,15226,15227,15228,15229,15230,15231,15232,15233,15234,15235,\n15236,15237,15238,15239,15240,15241,15242,15243,15244,15245,15246,15247,\n15248,15249,15250,15251,15252,15253,15254,15255,15256,15257,15258,15259,\n15260,15261,15262,15263,15264,15265,15266,15267,15268,15269,15270,15271,\n15272,15273,15274,15275,15276,15277,15278,15279,15280,15281,15282,15283,\n15284,15285,15286,15287,15288,15289,15290,15291,15292,15293,15294,15295,\n15296,15297,15298,15299,15300,15301,15302,15303,15304,15305,15306,15307,\n15308,15309,15310,15311,15312,15313,15314,15315,15316,15317,15318,15319,\n15320,15321,15322,15323,15324,15325,15326,15327,15328,15329,15330,15331,\n15332,15333,15334,15335,15336,15337,15338,15339,15340,15341,15342,15343,\n15344,15345,15346,15347,15348,15349,15350,15351,15352,15353,15354,15355,\n15356,15357,15358,15359,15360,15361,15362,15363,15364,15365,15366,15367,\n15368,15369,15370,15371,15372,15373,15374,15375,15376,15377,15378,15379,\n15380,15381,15382,15383,15384,15385,15386,15387,15388,15389,15390,15391,\n15392,15393,15394,15395,15396,15397,15398,15399,15400,15401,15402,15403,\n15404,15405,15406,15407,15408,15409,15410,15411,15412,15413,15414,15415,\n15416,15417,15418,15419,15420,15421,15422,15423,15424,15425,15426,15427,\n15428,15429,15430,15431,15432,15433,15434,15435,15436,15437,15438,15439,\n15440,15441,15442,15443,15444,15445,15446,15447,15448,15449,15450,15451,\n15452,15453,15454,15455,15456,15457,15458,15459,15460,15461,15462,15463,\n15464,15465,15466,15467,15468,15469,15470,15471,15472,15473,15474,15475,\n15476,15477,15478,15479,15480,15481,15482,15483,15484,15485,15486,15487,\n15488,15489,15490,15491,15492,15493,15494,15495,15496,15497,15498,15499,\n15500,15501,15502,15503,15504,15505,15506,15507,15508,15509,15510,15511,\n15512,15513,15514,15515,15516,15517,15518,15519,15520,15521,15522,15523,\n15524,15525,15526,15527,15528,15529,15530,15531,15532,15533,15534,15535,\n15536,15537,15538,15539,15540,15541,15542,15543,15544,15545,15546,15547,\n15548,15549,15550,15551,15552,15553,15554,15555,15556,15557,15558,15559,\n15560,15561,15562,15563,15564,15565,15566,15567,15568,15569,15570,15571,\n15572,15573,15574,15575,15576,15577,15578,15579,15580,15581,15582,15583,\n15584,15585,15586,15587,15588,15589,15590,15591,15592,15593,15594,15595,\n15596,15597,15598,15599,15600,15601,15602,15603,15604,15605,15606,15607,\n15608,15609,15610,15611,15612,15613,15614,15615,15616,15617,15618,15619,\n15620,15621,15622,15623,15624,15625,15626,15627,15628,15629,15630,15631,\n15632,15633,15634,15635,15636,15637,15638,15639,15640,15641,15642,15643,\n15644,15645,15646,15647,15648,15649,15650,15651,15652,15653,15654,15655,\n15656,15657,15658,15659,15660,15661,15662,15663,15664,15665,15666,15667,\n15668,15669,15670,15671,15672,15673,15674,15675,15676,15677,15678,15679,\n15680,15681,15682,15683,15684,15685,15686,15687,15688,15689,15690,15691,\n15692,15693,15694,15695,15696,15697,15698,15699,15700,15701,15702,15703,\n15704,15705,15706,15707,15708,15709,15710,15711,15712,15713,15714,15715,\n15716,15717,15718,15719,15720,15721,15722,15723,15724,15725,15726,15727,\n15728,15729,15730,15731,15732,15733,15734,15735,15736,15737,15738,15739,\n15740,15741,15742,15743,15744,15745,15746,15747,15748,15749,15750,15751,\n15752,15753,15754,15755,15756,15757,15758,15759,15760,15761,15762,15763,\n15764,15765,15766,15767,15768,15769,15770,15771,15772,15773,15774,15775,\n15776,15777,15778,15779,15780,15781,15782,15783,15784,15785,15786,15787,\n15788,15789,15790,15791,15792,15793,15794,15795,15796,15797,15798,15799,\n15800,15801,15802,15803,15804,15805,15806,15807,15808,15809,15810,15811,\n15812,15813,15814,15815,15816,15817,15818,15819,15820,15821,15822,15823,\n15824,15825,15826,15827,15828,15829,15830,15831,15832,15833,15834,15835,\n15836,15837,15838,15839,15840,15841,15842,15843,15844,15845,15846,15847,\n15848,15849,15850,15851,15852,15853,15854,15855,15856,15857,15858,15859,\n15860,15861,15862,15863,15864,15865,15866,15867,15868,15869,15870,15871,\n15872,15873,15874,15875,15876,15877,15878,15879,15880,15881,15882,15883,\n15884,15885,15886,15887,15888,15889,15890,15891,15892,15893,15894,15895,\n15896,15897,15898,15899,15900,15901,15902,15903,15904,15905,15906,15907,\n15908,15909,15910,15911,15912,15913,15914,15915,15916,15917,15918,15919,\n15920,15921,15922,15923,15924,15925,15926,15927,15928,15929,15930,15931,\n15932,15933,15934,15935,15936,15937,15938,15939,15940,15941,15942,15943,\n15944,15945,15946,15947,15948,15949,15950,15951,15952,15953,15954,15955,\n15956,15957,15958,15959,15960,15961,15962,15963,15964,15965,15966,15967,\n15968,15969,15970,15971,15972,15973,15974,15975,15976,15977,15978,15979,\n15980,15981,15982,15983,15984,15985,15986,15987,15988,15989,15990,15991,\n15992,15993,15994,15995,15996,15997,15998,15999,16000,16001,16002,16003,\n16004,16005,16006,16007,16008,16009,16010,16011,16012,16013,16014,16015,\n16016,16017,16018,16019,16020,16021,16022,16023,16024,16025,16026,16027,\n16028,16029,16030,16031,16032,16033,16034,16035,16036,16037,16038,16039,\n16040,16041,16042,16043,16044,16045,16046,16047,16048,16049,16050,16051,\n16052,16053,16054,16055,16056,16057,16058,16059,16060,16061,16062,16063,\n16064,16065,16066,16067,16068,16069,16070,16071,16072,16073,16074,16075,\n16076,16077,16078,16079,16080,16081,16082,16083,16084,16085,16086,16087,\n16088,16089,16090,16091,16092,16093,16094,16095,16096,16097,16098,16099,\n16100,16101,16102,16103,16104,16105,16106,16107,16108,16109,16110,16111,\n16112,16113,16114,16115,16116,16117,16118,16119,16120,16121,16122,16123,\n16124,16125,16126,16127,16128,16129,16130,16131,16132,16133,16134,16135,\n16136,16137,16138,16139,16140,16141,16142,16143,16144,16145,16146,16147,\n16148,16149,16150,16151,16152,16153,16154,16155,16156,16157,16158,16159,\n16160,16161,16162,16163,16164,16165,16166,16167,16168,16169,16170,16171,\n16172,16173,16174,16175,16176,16177,16178,16179,16180,16181,16182,16183,\n16184,16185,16186,16187,16188,16189,16190,16191,16192,16193,16194,16195,\n16196,16197,16198,16199,16200,16201,16202,16203,16204,16205,16206,16207,\n16208,16209,16210,16211,16212,16213,16214,16215,16216,16217,16218,16219,\n16220,16221,16222,16223,16224,16225,16226,16227,16228,16229,16230,16231,\n16232,16233,16234,16235,16236,16237,16238,16239,16240,16241,16242,16243,\n16244,16245,16246,16247,16248,16249,16250,16251,16252,16253,16254,16255,\n16256,16257,16258,16259,16260,16261,16262,16263,16264,16265,16266,16267,\n16268,16269,16270,16271,16272,16273,16274,16275,16276,16277,16278,16279,\n16280,16281,16282,16283,16284,16285,16286,16287,16288,16289,16290,16291,\n16292,16293,16294,16295,16296,16297,16298,16299,16300,16301,16302,16303,\n16304,16305,16306,16307,16308,16309,16310,16311,16312,16313,16314,16315,\n16316,16317,16318,16319,16320,16321,16322,16323,16324,16325,16326,16327,\n16328,16329,16330,16331,16332,16333,16334,16335,16336,16337,16338,16339,\n16340,16341,16342,16343,16344,16345,16346,16347,16348,16349,16350,16351,\n16352,16353,16354,16355,16356,16357,16358,16359,16360,16361,16362,16363,\n16364,16365,16366,16367,16368,16369,16370,16371,16372,16373,16374,16375,\n16376,16377,16378,16379,16380,16381,16382,16383,16384,16385,16386,16387,\n16388,16389,16390,16391,16392,16393,16394,16395,16396,16397,16398,16399,\n16400,16401,16402,16403,16404,16405,16406,16407,16408,16409,16410,16411,\n16412,16413,16414,16415,16416,16417,16418,16419,16420,16421,16422,16423,\n16424,16425,16426,16427,16428,16429,16430,16431,16432,16433,16434,16435,\n16436,16437,16438,16439,16440,16441,16442,16443,16444,16445,16446,16447,\n16448,16449,16450,16451,16452,16453,16454,16455,16456,16457,16458,16459,\n16460,16461,16462,16463,16464,16465,16466,16467,16468,16469,16470,16471,\n16472,16473,16474,16475,16476,16477,16478,16479,16480,16481,16482,16483,\n16484,16485,16486,16487,16488,16489,16490,16491,16492,16493,16494,16495,\n16496,16497,16498,16499,16500,16501,16502,16503,16504,16505,16506,16507,\n16508,16509,16510,16511,16512,16513,16514,16515,16516,16517,16518,16519,\n16520,16521,16522,16523,16524,16525,16526,16527,16528,16529,16530,16531,\n16532,16533,16534,16535,16536,16537,16538,16539,16540,16541,16542,16543,\n16544,16545,16546,16547,16548,16549,16550,16551,16552,16553,16554,16555,\n16556,16557,16558,16559,16560,16561,16562,16563,16564,16565,16566,16567,\n16568,16569,16570,16571,16572,16573,16574,16575,16576,16577,16578,16579,\n16580,16581,16582,16583,16584,16585,16586,16587,16588,16589,16590,16591,\n16592,16593,16594,16595,16596,16597,16598,16599,16600,16601,16602,16603,\n16604,16605,16606,16607,16608,16609,16610,16611,16612,16613,16614,16615,\n16616,16617,16618,16619,16620,16621,16622,16623,16624,16625,16626,16627,\n16628,16629,16630,16631,16632,16633,16634,16635,16636,16637,16638,16639,\n16640,16641,16642,16643,16644,16645,16646,16647,16648,16649,16650,16651,\n16652,16653,16654,16655,16656,16657,16658,16659,16660,16661,16662,16663,\n16664,16665,16666,16667,16668,16669,16670,16671,16672,16673,16674,16675,\n16676,16677,16678,16679,16680,16681,16682,16683,16684,16685,16686,16687,\n16688,16689,16690,16691,16692,16693,16694,16695,16696,16697,16698,16699,\n16700,16701,16702,16703,16704,16705,16706,16707,16708,16709,16710,16711,\n16712,16713,16714,16715,16716,16717,16718,16719,16720,16721,16722,16723,\n16724,16725,16726,16727,16728,16729,16730,16731,16732,16733,16734,16735,\n16736,16737,16738,16739,16740,16741,16742,16743,16744,16745,16746,16747,\n16748,16749,16750,16751,16752,16753,16754,16755,16756,16757,16758,16759,\n16760,16761,16762,16763,16764,16765,16766,16767,16768,16769,16770,16771,\n16772,16773,16774,16775,16776,16777,16778,16779,16780,16781,16782,16783,\n16784,16785,16786,16787,16788,16789,16790,16791,16792,16793,16794,16795,\n16796,16797,16798,16799,16800,16801,16802,16803,16804,16805,16806,16807,\n16808,16809,16810,16811,16812,16813,16814,16815,16816,16817,16818,16819,\n16820,16821,16822,16823,16824,16825,16826,16827,16828,16829,16830,16831,\n16832,16833,16834,16835,16836,16837,16838,16839,16840,16841,16842,16843,\n16844,16845,16846,16847,16848,16849,16850,16851,16852,16853,16854,16855,\n16856,16857,16858,16859,16860,16861,16862,16863,16864,16865,16866,16867,\n16868,16869,16870,16871,16872,16873,16874,16875,16876,16877,16878,16879,\n16880,16881,16882,16883,16884,16885,16886,16887,16888,16889,16890,16891,\n16892,16893,16894,16895,16896,16897,16898,16899,16900,16901,16902,16903,\n16904,16905,16906,16907,16908,16909,16910,16911,16912,16913,16914,16915,\n16916,16917,16918,16919,16920,16921,16922,16923,16924,16925,16926,16927,\n16928,16929,16930,16931,16932,16933,16934,16935,16936,16937,16938,16939,\n16940,16941,16942,16943,16944,16945,16946,16947,16948,16949,16950,16951,\n16952,16953,16954,16955,16956,16957,16958,16959,16960,16961,16962,16963,\n16964,16965,16966,16967,16968,16969,16970,16971,16972,16973,16974,16975,\n16976,16977,16978,16979,16980,16981,16982,16983,16984,16985,16986,16987,\n16988,16989,16990,16991,16992,16993,16994,16995,16996,16997,16998,16999,\n17000,17001,17002,17003,17004,17005,17006,17007,17008,17009,17010,17011,\n17012,17013,17014,17015,17016,17017,17018,17019,17020,17021,17022,17023,\n17024,17025,17026,17027,17028,17029,17030,17031,17032,17033,17034,17035,\n17036,17037,17038,17039,17040,17041,17042,17043,17044,17045,17046,17047,\n17048,17049,17050,17051,17052,17053,17054,17055,17056,17057,17058,17059,\n17060,17061,17062,17063,17064,17065,17066,17067,17068,17069,17070,17071,\n17072,17073,17074,17075,17076,17077,17078,17079,17080,17081,17082,17083,\n17084,17085,17086,17087,17088,17089,17090,17091,17092,17093,17094,17095,\n17096,17097,17098,17099,17100,17101,17102,17103,17104,17105,17106,17107,\n17108,17109,17110,17111,17112,17113,17114,17115,17116,17117,17118,17119,\n17120,17121,17122,17123,17124,17125,17126,17127,17128,17129,17130,17131,\n17132,17133,17134,17135,17136,17137,17138,17139,17140,17141,17142,17143,\n17144,17145,17146,17147,17148,17149,17150,17151,17152,17153,17154,17155,\n17156,17157,17158,17159,17160,17161,17162,17163,17164,17165,17166,17167,\n17168,17169,17170,17171,17172,17173,17174,17175,17176,17177,17178,17179,\n17180,17181,17182,17183,17184,17185,17186,17187,17188,17189,17190,17191,\n17192,17193,17194,17195,17196,17197,17198,17199,17200,17201,17202,17203,\n17204,17205,17206,17207,17208,17209,17210,17211,17212,17213,17214,17215,\n17216,17217,17218,17219,17220,17221,17222,17223,17224,17225,17226,17227,\n17228,17229,17230,17231,17232,17233,17234,17235,17236,17237,17238,17239,\n17240,17241,17242,17243,17244,17245,17246,17247,17248,17249,17250,17251,\n17252,17253,17254,17255,17256,17257,17258,17259,17260,17261,17262,17263,\n17264,17265,17266,17267,17268,17269,17270,17271,17272,17273,17274,17275,\n17276,17277,17278,17279,17280,17281,17282,17283,17284,17285,17286,17287,\n17288,17289,17290,17291,17292,17293,17294,17295,17296,17297,17298,17299,\n17300,17301,17302,17303,17304,17305,17306,17307,17308,17309,17310,17311,\n17312,17313,17314,17315,17316,17317,17318,17319,17320,17321,17322,17323,\n17324,17325,17326,17327,17328,17329,17330,17331,17332,17333,17334,17335,\n17336,17337,17338,17339,17340,17341,17342,17343,17344,17345,17346,17347,\n17348,17349,17350,17351,17352,17353,17354,17355,17356,17357,17358,17359,\n17360,17361,17362,17363,17364,17365,17366,17367,17368,17369,17370,17371,\n17372,17373,17374,17375,17376,17377,17378,17379,17380,17381,17382,17383,\n17384,17385,17386,17387,17388,17389,17390,17391,17392,17393,17394,17395,\n17396,17397,17398,17399,17400,17401,17402,17403,17404,17405,17406,17407,\n17408,17409,17410,17411,17412,17413,17414,17415,17416,17417,17418,17419,\n17420,17421,17422,17423,17424,17425,17426,17427,17428,17429,17430,17431,\n17432,17433,17434,17435,17436,17437,17438,17439,17440,17441,17442,17443,\n17444,17445,17446,17447,17448,17449,17450,17451,17452,17453,17454,17455,\n17456,17457,17458,17459,17460,17461,17462,17463,17464,17465,17466,17467,\n17468,17469,17470,17471,17472,17473,17474,17475,17476,17477,17478,17479,\n17480,17481,17482,17483,17484,17485,17486,17487,17488,17489,17490,17491,\n17492,17493,17494,17495,17496,17497,17498,17499,17500,17501,17502,17503,\n17504,17505,17506,17507,17508,17509,17510,17511,17512,17513,17514,17515,\n17516,17517,17518,17519,17520,17521,17522,17523,17524,17525,17526,17527,\n17528,17529,17530,17531,17532,17533,17534,17535,17536,17537,17538,17539,\n17540,17541,17542,17543,17544,17545,17546,17547,17548,17549,17550,17551,\n17552,17553,17554,17555,17556,17557,17558,17559,17560,17561,17562,17563,\n17564,17565,17566,17567,17568,17569,17570,17571,17572,17573,17574,17575,\n17576,17577,17578,17579,17580,17581,17582,17583,17584,17585,17586,17587,\n17588,17589,17590,17591,17592,17593,17594,17595,17596,17597,17598,17599,\n17600,17601,17602,17603,17604,17605,17606,17607,17608,17609,17610,17611,\n17612,17613,17614,17615,17616,17617,17618,17619,17620,17621,17622,17623,\n17624,17625,17626,17627,17628,17629,17630,17631,17632,17633,17634,17635,\n17636,17637,17638,17639,17640,17641,17642,17643,17644,17645,17646,17647,\n17648,17649,17650,17651,17652,17653,17654,17655,17656,17657,17658,17659,\n17660,17661,17662,17663,17664,17665,17666,17667,17668,17669,17670,17671,\n17672,17673,17674,17675,17676,17677,17678,17679,17680,17681,17682,17683,\n17684,17685,17686,17687,17688,17689,17690,17691,17692,17693,17694,17695,\n17696,17697,17698,17699,17700,17701,17702,17703,17704,17705,17706,17707,\n17708,17709,17710,17711,17712,17713,17714,17715,17716,17717,17718,17719,\n17720,17721,17722,17723,17724,17725,17726,17727,17728,17729,17730,17731,\n17732,17733,17734,17735,17736,17737,17738,17739,17740,17741,17742,17743,\n17744,17745,17746,17747,17748,17749,17750,17751,17752,17753,17754,17755,\n17756,17757,17758,17759,17760,17761,17762,17763,17764,17765,17766,17767,\n17768,17769,17770,17771,17772,17773,17774,17775,17776,17777,17778,17779,\n17780,17781,17782,17783,17784,17785,17786,17787,17788,17789,17790,17791,\n17792,17793,17794,17795,17796,17797,17798,17799,17800,17801,17802,17803,\n17804,17805,17806,17807,17808,17809,17810,17811,17812,17813,17814,17815,\n17816,17817,17818,17819,17820,17821,17822,17823,17824,17825,17826,17827,\n17828,17829,17830,17831,17832,17833,17834,17835,17836,17837,17838,17839,\n17840,17841,17842,17843,17844,17845,17846,17847,17848,17849,17850,17851,\n17852,17853,17854,17855,17856,17857,17858,17859,17860,17861,17862,17863,\n17864,17865,17866,17867,17868,17869,17870,17871,17872,17873,17874,17875,\n17876,17877,17878,17879,17880,17881,17882,17883,17884,17885,17886,17887,\n17888,17889,17890,17891,17892,17893,17894,17895,17896,17897,17898,17899,\n17900,17901,17902,17903,17904,17905,17906,17907,17908,17909,17910,17911,\n17912,17913,17914,17915,17916,17917,17918,17919,17920,17921,17922,17923,\n17924,17925,17926,17927,17928,17929,17930,17931,17932,17933,17934,17935,\n17936,17937,17938,17939,17940,17941,17942,17943,17944,17945,17946,17947,\n17948,17949,17950,17951,17952,17953,17954,17955,17956,17957,17958,17959,\n17960,17961,17962,17963,17964,17965,17966,17967,17968,17969,17970,17971,\n17972,17973,17974,17975,17976,17977,17978,17979,17980,17981,17982,17983,\n17984,17985,17986,17987,17988,17989,17990,17991,17992,17993,17994,17995,\n17996,17997,17998,17999,18000,18001,18002,18003,18004,18005,18006,18007,\n18008,18009,18010,18011,18012,18013,18014,18015,18016,18017,18018,18019,\n18020,18021,18022,18023,18024,18025,18026,18027,18028,18029,18030,18031,\n18032,18033,18034,18035,18036,18037,18038,18039,18040,18041,18042,18043,\n18044,18045,18046,18047,18048,18049,18050,18051,18052,18053,18054,18055,\n18056,18057,18058,18059,18060,18061,18062,18063,18064,18065,18066,18067,\n18068,18069,18070,18071,18072,18073,18074,18075,18076,18077,18078,18079,\n18080,18081,18082,18083,18084,18085,18086,18087,18088,18089,18090,18091,\n18092,18093,18094,18095,18096,18097,18098,18099,18100,18101,18102,18103,\n18104,18105,18106,18107,18108,18109,18110,18111,18112,18113,18114,18115,\n18116,18117,18118,18119,18120,18121,18122,18123,18124,18125,18126,18127,\n18128,18129,18130,18131,18132,18133,18134,18135,18136,18137,18138,18139,\n18140,18141,18142,18143,18144,18145,18146,18147,18148,18149,18150,18151,\n18152,18153,18154,18155,18156,18157,18158,18159,18160,18161,18162,18163,\n18164,18165,18166,18167,18168,18169,18170,18171,18172,18173,18174,18175,\n18176,18177,18178,18179,18180,18181,18182,18183,18184,18185,18186,18187,\n18188,18189,18190,18191,18192,18193,18194,18195,18196,18197,18198,18199,\n18200,18201,18202,18203,18204,18205,18206,18207,18208,18209,18210,18211,\n18212,18213,18214,18215,18216,18217,18218,18219,18220,18221,18222,18223,\n18224,18225,18226,18227,18228,18229,18230,18231,18232,18233,18234,18235,\n18236,18237,18238,18239,18240,18241,18242,18243,18244,18245,18246,18247,\n18248,18249,18250,18251,18252,18253,18254,18255,18256,18257,18258,18259,\n18260,18261,18262,18263,18264,18265,18266,18267,18268,18269,18270,18271,\n18272,18273,18274,18275,18276,18277,18278,18279,18280,18281,18282,18283,\n18284,18285,18286,18287,18288,18289,18290,18291,18292,18293,18294,18295,\n18296,18297,18298,18299,18300,18301,18302,18303,18304,18305,18306,18307,\n18308,18309,18310,18311,18312,18313,18314,18315,18316,18317,18318,18319,\n18320,18321,18322,18323,18324,18325,18326,18327,18328,18329,18330,18331,\n18332,18333,18334,18335,18336,18337,18338,18339,18340,18341,18342,18343,\n18344,18345,18346,18347,18348,18349,18350,18351,18352,18353,18354,18355,\n18356,18357,18358,18359,18360,18361,18362,18363,18364,18365,18366,18367,\n18368,18369,18370,18371,18372,18373,18374,18375,18376,18377,18378,18379,\n18380,18381,18382,18383,18384,18385,18386,18387,18388,18389,18390,18391,\n18392,18393,18394,18395,18396,18397,18398,18399,18400,18401,18402,18403,\n18404,18405,18406,18407,18408,18409,18410,18411,18412,18413,18414,18415,\n18416,18417,18418,18419,18420,18421,18422,18423,18424,18425,18426,18427,\n18428,18429,18430,18431,18432,18433,18434,18435,18436,18437,18438,18439,\n18440,18441,18442,18443,18444,18445,18446,18447,18448,18449,18450,18451,\n18452,18453,18454,18455,18456,18457,18458,18459,18460,18461,18462,18463,\n18464,18465,18466,18467,18468,18469,18470,18471,18472,18473,18474,18475,\n18476,18477,18478,18479,18480,18481,18482,18483,18484,18485,18486,18487,\n18488,18489,18490,18491,18492,18493,18494,18495,18496,18497,18498,18499,\n18500,18501,18502,18503,18504,18505,18506,18507,18508,18509,18510,18511,\n18512,18513,18514,18515,18516,18517,18518,18519,18520,18521,18522,18523,\n18524,18525,18526,18527,18528,18529,18530,18531,18532,18533,18534,18535,\n18536,18537,18538,18539,18540,18541,18542,18543,18544,18545,18546,18547,\n18548,18549,18550,18551,18552,18553,18554,18555,18556,18557,18558,18559,\n18560,18561,18562,18563,18564,18565,18566,18567,18568,18569,18570,18571,\n18572,18573,18574,18575,18576,18577,18578,18579,18580,18581,18582,18583,\n18584,18585,18586,18587,18588,18589,18590,18591,18592,18593,18594,18595,\n18596,18597,18598,18599,18600,18601,18602,18603,18604,18605,18606,18607,\n18608,18609,18610,18611,18612,18613,18614,18615,18616,18617,18618,18619,\n18620,18621,18622,18623,18624,18625,18626,18627,18628,18629,18630,18631,\n18632,18633,18634,18635,18636,18637,18638,18639,18640,18641,18642,18643,\n18644,18645,18646,18647,18648,18649,18650,18651,18652,18653,18654,18655,\n18656,18657,18658,18659,18660,18661,18662,18663,18664,18665,18666,18667,\n18668,18669,18670,18671,18672,18673,18674,18675,18676,18677,18678,18679,\n18680,18681,18682,18683,18684,18685,18686,18687,18688,18689,18690,18691,\n18692,18693,18694,18695,18696,18697,18698,18699,18700,18701,18702,18703,\n18704,18705,18706,18707,18708,18709,18710,18711,18712,18713,18714,18715,\n18716,18717,18718,18719,18720,18721,18722,18723,18724,18725,18726,18727,\n18728,18729,18730,18731,18732,18733,18734,18735,18736,18737,18738,18739,\n18740,18741,18742,18743,18744,18745,18746,18747,18748,18749,18750,18751,\n18752,18753,18754,18755,18756,18757,18758,18759,18760,18761,18762,18763,\n18764,18765,18766,18767,18768,18769,18770,18771,18772,18773,18774,18775,\n18776,18777,18778,18779,18780,18781,18782,18783,18784,18785,18786,18787,\n18788,18789,18790,18791,18792,18793,18794,18795,18796,18797,18798,18799,\n18800,18801,18802,18803,18804,18805,18806,18807,18808,18809,18810,18811,\n18812,18813,18814,18815,18816,18817,18818,18819,18820,18821,18822,18823,\n18824,18825,18826,18827,18828,18829,18830,18831,18832,18833,18834,18835,\n18836,18837,18838,18839,18840,18841,18842,18843,18844,18845,18846,18847,\n18848,18849,18850,18851,18852,18853,18854,18855,18856,18857,18858,18859,\n18860,18861,18862,18863,18864,18865,18866,18867,18868,18869,18870,18871,\n18872,18873,18874,18875,18876,18877,18878,18879,18880,18881,18882,18883,\n18884,18885,18886,18887,18888,18889,18890,18891,18892,18893,18894,18895,\n18896,18897,18898,18899,18900,18901,18902,18903,18904,18905,18906,18907,\n18908,18909,18910,18911,18912,18913,18914,18915,18916,18917,18918,18919,\n18920,18921,18922,18923,18924,18925,18926,18927,18928,18929,18930,18931,\n18932,18933,18934,18935,18936,18937,18938,18939,18940,18941,18942,18943,\n18944,18945,18946,18947,18948,18949,18950,18951,18952,18953,18954,18955,\n18956,18957,18958,18959,18960,18961,18962,18963,18964,18965,18966,18967,\n18968,18969,18970,18971,18972,18973,18974,18975,18976,18977,18978,18979,\n18980,18981,18982,18983,18984,18985,18986,18987,18988,18989,18990,18991,\n18992,18993,18994,18995,18996,18997,18998,18999,19000,19001,19002,19003,\n19004,19005,19006,19007,19008,19009,19010,19011,19012,19013,19014,19015,\n19016,19017,19018,19019,19020,19021,19022,19023,19024,19025,19026,19027,\n19028,19029,19030,19031,19032,19033,19034,19035,19036,19037,19038,19039,\n19040,19041,19042,19043,19044,19045,19046,19047,19048,19049,19050,19051,\n19052,19053,19054,19055,19056,19057,19058,19059,19060,19061,19062,19063,\n19064,19065,19066,19067,19068,19069,19070,19071,19072,19073,19074,19075,\n19076,19077,19078,19079,19080,19081,19082,19083,19084,19085,19086,19087,\n19088,19089,19090,19091,19092,19093,19094,19095,19096,19097,19098,19099,\n19100,19101,19102,19103,19104,19105,19106,19107,19108,19109,19110,19111,\n19112,19113,19114,19115,19116,19117,19118,19119,19120,19121,19122,19123,\n19124,19125,19126,19127,19128,19129,19130,19131,19132,19133,19134,19135,\n19136,19137,19138,19139,19140,19141,19142,19143,19144,19145,19146,19147,\n19148,19149,19150,19151,19152,19153,19154,19155,19156,19157,19158,19159,\n19160,19161,19162,19163,19164,19165,19166,19167,19168,19169,19170,19171,\n19172,19173,19174,19175,19176,19177,19178,19179,19180,19181,19182,19183,\n19184,19185,19186,19187,19188,19189,19190,19191,19192,19193,19194,19195,\n19196,19197,19198,19199,19200,19201,19202,19203,19204,19205,19206,19207,\n19208,19209,19210,19211,19212,19213,19214,19215,19216,19217,19218,19219,\n19220,19221,19222,19223,19224,19225,19226,19227,19228,19229,19230,19231,\n19232,19233,19234,19235,19236,19237,19238,19239,19240,19241,19242,19243,\n19244,19245,19246,19247,19248,19249,19250,19251,19252,19253,19254,19255,\n19256,19257,19258,19259,19260,19261,19262,19263,19264,19265,19266,19267,\n19268,19269,19270,19271,19272,19273,19274,19275,19276,19277,19278,19279,\n19280,19281,19282,19283,19284,19285,19286,19287,19288,19289,19290,19291,\n19292,19293,19294,19295,19296,19297,19298,19299,19300,19301,19302,19303,\n19304,19305,19306,19307,19308,19309,19310,19311,19312,19313,19314,19315,\n19316,19317,19318,19319,19320,19321,19322,19323,19324,19325,19326,19327,\n19328,19329,19330,19331,19332,19333,19334,19335,19336,19337,19338,19339,\n19340,19341,19342,19343,19344,19345,19346,19347,19348,19349,19350,19351,\n19352,19353,19354,19355,19356,19357,19358,19359,19360,19361,19362,19363,\n19364,19365,19366,19367,19368,19369,19370,19371,19372,19373,19374,19375,\n19376,19377,19378,19379,19380,19381,19382,19383,19384,19385,19386,19387,\n19388,19389,19390,19391,19392,19393,19394,19395,19396,19397,19398,19399,\n19400,19401,19402,19403,19404,19405,19406,19407,19408,19409,19410,19411,\n19412,19413,19414,19415,19416,19417,19418,19419,19420,19421,19422,19423,\n19424,19425,19426,19427,19428,19429,19430,19431,19432,19433,19434,19435,\n19436,19437,19438,19439,19440,19441,19442,19443,19444,19445,19446,19447,\n19448,19449,19450,19451,19452,19453,19454,19455,19456,19457,19458,19459,\n19460,19461,19462,19463,19464,19465,19466,19467,19468,19469,19470,19471,\n19472,19473,19474,19475,19476,19477,19478,19479,19480,19481,19482,19483,\n19484,19485,19486,19487,19488,19489,19490,19491,19492,19493,19494,19495,\n19496,19497,19498,19499,19500,19501,19502,19503,19504,19505,19506,19507,\n19508,19509,19510,19511,19512,19513,19514,19515,19516,19517,19518,19519,\n19520,19521,19522,19523,19524,19525,19526,19527,19528,19529,19530,19531,\n19532,19533,19534,19535,19536,19537,19538,19539,19540,19541,19542,19543,\n19544,19545,19546,19547,19548,19549,19550,19551,19552,19553,19554,19555,\n19556,19557,19558,19559,19560,19561,19562,19563,19564,19565,19566,19567,\n19568,19569,19570,19571,19572,19573,19574,19575,19576,19577,19578,19579,\n19580,19581,19582,19583,19584,19585,19586,19587,19588,19589,19590,19591,\n19592,19593,19594,19595,19596,19597,19598,19599,19600,19601,19602,19603,\n19604,19605,19606,19607,19608,19609,19610,19611,19612,19613,19614,19615,\n19616,19617,19618,19619,19620,19621,19622,19623,19624,19625,19626,19627,\n19628,19629,19630,19631,19632,19633,19634,19635,19636,19637,19638,19639,\n19640,19641,19642,19643,19644,19645,19646,19647,19648,19649,19650,19651,\n19652,19653,19654,19655,19656,19657,19658,19659,19660,19661,19662,19663,\n19664,19665,19666,19667,19668,19669,19670,19671,19672,19673,19674,19675,\n19676,19677,19678,19679,19680,19681,19682,19683,19684,19685,19686,19687,\n19688,19689,19690,19691,19692,19693,19694,19695,19696,19697,19698,19699,\n19700,19701,19702,19703,19704,19705,19706,19707,19708,19709,19710,19711,\n19712,19713,19714,19715,19716,19717,19718,19719,19720,19721,19722,19723,\n19724,19725,19726,19727,19728,19729,19730,19731,19732,19733,19734,19735,\n19736,19737,19738,19739,19740,19741,19742,19743,19744,19745,19746,19747,\n19748,19749,19750,19751,19752,19753,19754,19755,19756,19757,19758,19759,\n19760,19761,19762,19763,19764,19765,19766,19767,19768,19769,19770,19771,\n19772,19773,19774,19775,19776,19777,19778,19779,19780,19781,19782,19783,\n19784,19785,19786,19787,19788,19789,19790,19791,19792,19793,19794,19795,\n19796,19797,19798,19799,19800,19801,19802,19803,19804,19805,19806,19807,\n19808,19809,19810,19811,19812,19813,19814,19815,19816,19817,19818,19819,\n19820,19821,19822,19823,19824,19825,19826,19827,19828,19829,19830,19831,\n19832,19833,19834,19835,19836,19837,19838,19839,19840,19841,19842,19843,\n19844,19845,19846,19847,19848,19849,19850,19851,19852,19853,19854,19855,\n19856,19857,19858,19859,19860,19861,19862,19863,19864,19865,19866,19867,\n19868,19869,19870,19871,19872,19873,19874,19875,19876,19877,19878,19879,\n19880,19881,19882,19883,19884,19885,19886,19887,19888,19889,19890,19891,\n19892,19893,19894,19895,19896,19897,19898,19899,19900,19901,19902,19903,\n19904,19905,19906,19907,19908,19909,19910,19911,19912,19913,19914,19915,\n19916,19917,19918,19919,19920,19921,19922,19923,19924,19925,19926,19927,\n19928,19929,19930,19931,19932,19933,19934,19935,19936,19937,19938,19939,\n19940,19941,19942,19943,19944,19945,19946,19947,19948,19949,19950,19951,\n19952,19953,19954,19955,19956,19957,19958,19959,19960,19961,19962,19963,\n19964,19965,19966,19967,19968,19969,19970,19971,19972,19973,19974,19975,\n19976,19977,19978,19979,19980,19981,19982,19983,19984,19985,19986,19987,\n19988,19989,19990,19991,19992,19993,19994,19995,19996,19997,19998,19999,\n20000,20001,20002,20003,20004,20005,20006,20007,20008,20009,20010,20011,\n20012,20013,20014,20015,20016,20017,20018,20019,20020,20021,20022,20023,\n20024,20025,20026,20027,20028,20029,20030,20031,20032,20033,20034,20035,\n20036,20037,20038,20039,20040,20041,20042,20043,20044,20045,20046,20047,\n20048,20049,20050,20051,20052,20053,20054,20055,20056,20057,20058,20059,\n20060,20061,20062,20063,20064,20065,20066,20067,20068,20069,20070,20071,\n20072,20073,20074,20075,20076,20077,20078,20079,20080,20081,20082,20083,\n20084,20085,20086,20087,20088,20089,20090,20091,20092,20093,20094,20095,\n20096,20097,20098,20099,20100,20101,20102,20103,20104,20105,20106,20107,\n20108,20109,20110,20111,20112,20113,20114,20115,20116,20117,20118,20119,\n20120,20121,20122,20123,20124,20125,20126,20127,20128,20129,20130,20131,\n20132,20133,20134,20135,20136,20137,20138,20139,20140,20141,20142,20143,\n20144,20145,20146,20147,20148,20149,20150,20151,20152,20153,20154,20155,\n20156,20157,20158,20159,20160,20161,20162,20163,20164,20165,20166,20167,\n20168,20169,20170,20171,20172,20173,20174,20175,20176,20177,20178,20179,\n20180,20181,20182,20183,20184,20185,20186,20187,20188,20189,20190,20191,\n20192,20193,20194,20195,20196,20197,20198,20199,20200,20201,20202,20203,\n20204,20205,20206,20207,20208,20209,20210,20211,20212,20213,20214,20215,\n20216,20217,20218,20219,20220,20221,20222,20223,20224,20225,20226,20227,\n20228,20229,20230,20231,20232,20233,20234,20235,20236,20237,20238,20239,\n20240,20241,20242,20243,20244,20245,20246,20247,20248,20249,20250,20251,\n20252,20253,20254,20255,20256,20257,20258,20259,20260,20261,20262,20263,\n20264,20265,20266,20267,20268,20269,20270,20271,20272,20273,20274,20275,\n20276,20277,20278,20279,20280,20281,20282,20283,20284,20285,20286,20287,\n20288,20289,20290,20291,20292,20293,20294,20295,20296,20297,20298,20299,\n20300,20301,20302,20303,20304,20305,20306,20307,20308,20309,20310,20311,\n20312,20313,20314,20315,20316,20317,20318,20319,20320,20321,20322,20323,\n20324,20325,20326,20327,20328,20329,20330,20331,20332,20333,20334,20335,\n20336,20337,20338,20339,20340,20341,20342,20343,20344,20345,20346,20347,\n20348,20349,20350,20351,20352,20353,20354,20355,20356,20357,20358,20359,\n20360,20361,20362,20363,20364,20365,20366,20367,20368,20369,20370,20371,\n20372,20373,20374,20375,20376,20377,20378,20379,20380,20381,20382,20383,\n20384,20385,20386,20387,20388,20389,20390,20391,20392,20393,20394,20395,\n20396,20397,20398,20399,20400,20401,20402,20403,20404,20405,20406,20407,\n20408,20409,20410,20411,20412,20413,20414,20415,20416,20417,20418,20419,\n20420,20421,20422,20423,20424,20425,20426,20427,20428,20429,20430,20431,\n20432,20433,20434,20435,20436,20437,20438,20439,20440,20441,20442,20443,\n20444,20445,20446,20447,20448,20449,20450,20451,20452,20453,20454,20455,\n20456,20457,20458,20459,20460,20461,20462,20463,20464,20465,20466,20467,\n20468,20469,20470,20471,20472,20473,20474,20475,20476,20477,20478,20479,\n20480,20481,20482,20483,20484,20485,20486,20487,20488,20489,20490,20491,\n20492,20493,20494,20495,20496,20497,20498,20499,20500,20501,20502,20503,\n20504,20505,20506,20507,20508,20509,20510,20511,20512,20513,20514,20515,\n20516,20517,20518,20519,20520,20521,20522,20523,20524,20525,20526,20527,\n20528,20529,20530,20531,20532,20533,20534,20535,20536,20537,20538,20539,\n20540,20541,20542,20543,20544,20545,20546,20547,20548,20549,20550,20551,\n20552,20553,20554,20555,20556,20557,20558,20559,20560,20561,20562,20563,\n20564,20565,20566,20567,20568,20569,20570,20571,20572,20573,20574,20575,\n20576,20577,20578,20579,20580,20581,20582,20583,20584,20585,20586,20587,\n20588,20589,20590,20591,20592,20593,20594,20595,20596,20597,20598,20599,\n20600,20601,20602,20603,20604,20605,20606,20607,20608,20609,20610,20611,\n20612,20613,20614,20615,20616,20617,20618,20619,20620,20621,20622,20623,\n20624,20625,20626,20627,20628,20629,20630,20631,20632,20633,20634,20635,\n20636,20637,20638,20639,20640,20641,20642,20643,20644,20645,20646,20647,\n20648,20649,20650,20651,20652,20653,20654,20655,20656,20657,20658,20659,\n20660,20661,20662,20663,20664,20665,20666,20667,20668,20669,20670,20671,\n20672,20673,20674,20675,20676,20677,20678,20679,20680,20681,20682,20683,\n20684,20685,20686,20687,20688,20689,20690,20691,20692,20693,20694,20695,\n20696,20697,20698,20699,20700,20701,20702,20703,20704,20705,20706,20707,\n20708,20709,20710,20711,20712,20713,20714,20715,20716,20717,20718,20719,\n20720,20721,20722,20723,20724,20725,20726,20727,20728,20729,20730,20731,\n20732,20733,20734,20735,20736,20737,20738,20739,20740,20741,20742,20743,\n20744,20745,20746,20747,20748,20749,20750,20751,20752,20753,20754,20755,\n20756,20757,20758,20759,20760,20761,20762,20763,20764,20765,20766,20767,\n20768,20769,20770,20771,20772,20773,20774,20775,20776,20777,20778,20779,\n20780,20781,20782,20783,20784,20785,20786,20787,20788,20789,20790,20791,\n20792,20793,20794,20795,20796,20797,20798,20799,20800,20801,20802,20803,\n20804,20805,20806,20807,20808,20809,20810,20811,20812,20813,20814,20815,\n20816,20817,20818,20819,20820,20821,20822,20823,20824,20825,20826,20827,\n20828,20829,20830,20831,20832,20833,20834,20835,20836,20837,20838,20839,\n20840,20841,20842,20843,20844,20845,20846,20847,20848,20849,20850,20851,\n20852,20853,20854,20855,20856,20857,20858,20859,20860,20861,20862,20863,\n20864,20865,20866,20867,20868,20869,20870,20871,20872,20873,20874,20875,\n20876,20877,20878,20879,20880,20881,20882,20883,20884,20885,20886,20887,\n20888,20889,20890,20891,20892,20893,20894,20895,20896,20897,20898,20899,\n20900,20901,20902,20903,20904,20905,20906,20907,20908,20909,20910,20911,\n20912,20913,20914,20915,20916,20917,20918,20919,20920,20921,20922,20923,\n20924,20925,20926,20927,20928,20929,20930,20931,20932,20933,20934,20935,\n20936,20937,20938,20939,20940,20941,20942,20943,20944,20945,20946,20947,\n20948,20949,20950,20951,20952,20953,20954,20955,20956,20957,20958,20959,\n20960,20961,20962,20963,20964,20965,20966,20967,20968,20969,20970,20971,\n20972,20973,20974,20975,20976,20977,20978,20979,20980,20981,20982,20983,\n20984,20985,20986,20987,20988,20989,20990,20991,20992,20993,20994,20995,\n20996,20997,20998,20999,21000,21001,21002,21003,21004,21005,21006,21007,\n21008,21009,21010,21011,21012,21013,21014,21015,21016,21017,21018,21019,\n21020,21021,21022,21023,21024,21025,21026,21027,21028,21029,21030,21031,\n21032,21033,21034,21035,21036,21037,21038,21039,21040,21041,21042,21043,\n21044,21045,21046,21047,21048,21049,21050,21051,21052,21053,21054,21055,\n21056,21057,21058,21059,21060,21061,21062,21063,21064,21065,21066,21067,\n21068,21069,21070,21071,21072,21073,21074,21075,21076,21077,21078,21079,\n21080,21081,21082,21083,21084,21085,21086,21087,21088,21089,21090,21091,\n21092,21093,21094,21095,21096,21097,21098,21099,21100,21101,21102,21103,\n21104,21105,21106,21107,21108,21109,21110,21111,21112,21113,21114,21115,\n21116,21117,21118,21119,21120,21121,21122,21123,21124,21125,21126,21127,\n21128,21129,21130,21131,21132,21133,21134,21135,21136,21137,21138,21139,\n21140,21141,21142,21143,21144,21145,21146,21147,21148,21149,21150,21151,\n21152,21153,21154,21155,21156,21157,21158,21159,21160,21161,21162,21163,\n21164,21165,21166,21167,21168,21169,21170,21171,21172,21173,21174,21175,\n21176,21177,21178,21179,21180,21181,21182,21183,21184,21185,21186,21187,\n21188,21189,21190,21191,21192,21193,21194,21195,21196,21197,21198,21199,\n21200,21201,21202,21203,21204,21205,21206,21207,21208,21209,21210,21211,\n21212,21213,21214,21215,21216,21217,21218,21219,21220,21221,21222,21223,\n21224,21225,21226,21227,21228,21229,21230,21231,21232,21233,21234,21235,\n21236,21237,21238,21239,21240,21241,21242,21243,21244,21245,21246,21247,\n21248,21249,21250,21251,21252,21253,21254,21255,21256,21257,21258,21259,\n21260,21261,21262,21263,21264,21265,21266,21267,21268,21269,21270,21271,\n21272,21273,21274,21275,21276,21277,21278,21279,21280,21281,21282,21283,\n21284,21285,21286,21287,21288,21289,21290,21291,21292,21293,21294,21295,\n21296,21297,21298,21299,21300,21301,21302,21303,21304,21305,21306,21307,\n21308,21309,21310,21311,21312,21313,21314,21315,21316,21317,21318,21319,\n21320,21321,21322,21323,21324,21325,21326,21327,21328,21329,21330,21331,\n21332,21333,21334,21335,21336,21337,21338,21339,21340,21341,21342,21343,\n21344,21345,21346,21347,21348,21349,21350,21351,21352,21353,21354,21355,\n21356,21357,21358,21359,21360,21361,21362,21363,21364,21365,21366,21367,\n21368,21369,21370,21371,21372,21373,21374,21375,21376,21377,21378,21379,\n21380,21381,21382,21383,21384,21385,21386,21387,21388,21389,21390,21391,\n21392,21393,21394,21395,21396,21397,21398,21399,21400,21401,21402,21403,\n21404,21405,21406,21407,21408,21409,21410,21411,21412,21413,21414,21415,\n21416,21417,21418,21419,21420,21421,21422,21423,21424,21425,21426,21427,\n21428,21429,21430,21431,21432,21433,21434,21435,21436,21437,21438,21439,\n21440,21441,21442,21443,21444,21445,21446,21447,21448,21449,21450,21451,\n21452,21453,21454,21455,21456,21457,21458,21459,21460,21461,21462,21463,\n21464,21465,21466,21467,21468,21469,21470,21471,21472,21473,21474,21475,\n21476,21477,21478,21479,21480,21481,21482,21483,21484,21485,21486,21487,\n21488,21489,21490,21491,21492,21493,21494,21495,21496,21497,21498,21499,\n21500,21501,21502,21503,21504,21505,21506,21507,21508,21509,21510,21511,\n21512,21513,21514,21515,21516,21517,21518,21519,21520,21521,21522,21523,\n21524,21525,21526,21527,21528,21529,21530,21531,21532,21533,21534,21535,\n21536,21537,21538,21539,21540,21541,21542,21543,21544,21545,21546,21547,\n21548,21549,21550,21551,21552,21553,21554,21555,21556,21557,21558,21559,\n21560,21561,21562,21563,21564,21565,21566,21567,21568,21569,21570,21571,\n21572,21573,21574,21575,21576,21577,21578,21579,21580,21581,21582,21583,\n21584,21585,21586,21587,21588,21589,21590,21591,21592,21593,21594,21595,\n21596,21597,21598,21599,21600,21601,21602,21603,21604,21605,21606,21607,\n21608,21609,21610,21611,21612,21613,21614,21615,21616,21617,21618,21619,\n21620,21621,21622,21623,21624,21625,21626,21627,21628,21629,21630,21631,\n21632,21633,21634,21635,21636,21637,21638,21639,21640,21641,21642,21643,\n21644,21645,21646,21647,21648,21649,21650,21651,21652,21653,21654,21655,\n21656,21657,21658,21659,21660,21661,21662,21663,21664,21665,21666,21667,\n21668,21669,21670,21671,21672,21673,21674,21675,21676,21677,21678,21679,\n21680,21681,21682,21683,21684,21685,21686,21687,21688,21689,21690,21691,\n21692,21693,21694,21695,21696,21697,21698,21699,21700,21701,21702,21703,\n21704,21705,21706,21707,21708,21709,21710,21711,21712,21713,21714,21715,\n21716,21717,21718,21719,21720,21721,21722,21723,21724,21725,21726,21727,\n21728,21729,21730,21731,21732,21733,21734,21735,21736,21737,21738,21739,\n21740,21741,21742,21743,21744,21745,21746,21747,21748,21749,21750,21751,\n21752,21753,21754,21755,21756,21757,21758,21759,21760,21761,21762,21763,\n21764,21765,21766,21767,21768,21769,21770,21771,21772,21773,21774,21775,\n21776,21777,21778,21779,21780,21781,21782,21783,21784,21785,21786,21787,\n21788,21789,21790,21791,21792,21793,21794,21795,21796,21797,21798,21799,\n21800,21801,21802,21803,21804,21805,21806,21807,21808,21809,21810,21811,\n21812,21813,21814,21815,21816,21817,21818,21819,21820,21821,21822,21823,\n21824,21825,21826,21827,21828,21829,21830,21831,21832,21833,21834,21835,\n21836,21837,21838,21839,21840,21841,21842,21843,21844,21845,21846,21847,\n21848,21849,21850,21851,21852,21853,21854,21855,21856,21857,21858,21859,\n21860,21861,21862,21863,21864,21865,21866,21867,21868,21869,21870,21871,\n21872,21873,21874,21875,21876,21877,21878,21879,21880,21881,21882,21883,\n21884,21885,21886,21887,21888,21889,21890,21891,21892,21893,21894,21895,\n21896,21897,21898,21899,21900,21901,21902,21903,21904,21905,21906,21907,\n21908,21909,21910,21911,21912,21913,21914,21915,21916,21917,21918,21919,\n21920,21921,21922,21923,21924,21925,21926,21927,21928,21929,21930,21931,\n21932,21933,21934,21935,21936,21937,21938,21939,21940,21941,21942,21943,\n21944,21945,21946,21947,21948,21949,21950,21951,21952,21953,21954,21955,\n21956,21957,21958,21959,21960,21961,21962,21963,21964,21965,21966,21967,\n21968,21969,21970,21971,21972,21973,21974,21975,21976,21977,21978,21979,\n21980,21981,21982,21983,21984,21985,21986,21987,21988,21989,21990,21991,\n21992,21993,21994,21995,21996,21997,21998,21999,22000,22001,22002,22003,\n22004,22005,22006,22007,22008,22009,22010,22011,22012,22013,22014,22015,\n22016,22017,22018,22019,22020,22021,22022,22023,22024,22025,22026,22027,\n22028,22029,22030,22031,22032,22033,22034,22035,22036,22037,22038,22039,\n22040,22041,22042,22043,22044,22045,22046,22047,22048,22049,22050,22051,\n22052,22053,22054,22055,22056,22057,22058,22059,22060,22061,22062,22063,\n22064,22065,22066,22067,22068,22069,22070,22071,22072,22073,22074,22075,\n22076,22077,22078,22079,22080,22081,22082,22083,22084,22085,22086,22087,\n22088,22089,22090,22091,22092,22093,22094,22095,22096,22097,22098,22099,\n22100,22101,22102,22103,22104,22105,22106,22107,22108,22109,22110,22111,\n22112,22113,22114,22115,22116,22117,22118,22119,22120,22121,22122,22123,\n22124,22125,22126,22127,22128,22129,22130,22131,22132,22133,22134,22135,\n22136,22137,22138,22139,22140,22141,22142,22143,22144,22145,22146,22147,\n22148,22149,22150,22151,22152,22153,22154,22155,22156,22157,22158,22159,\n22160,22161,22162,22163,22164,22165,22166,22167,22168,22169,22170,22171,\n22172,22173,22174,22175,22176,22177,22178,22179,22180,22181,22182,22183,\n22184,22185,22186,22187,22188,22189,22190,22191,22192,22193,22194,22195,\n22196,22197,22198,22199,22200,22201,22202,22203,22204,22205,22206,22207,\n22208,22209,22210,22211,22212,22213,22214,22215,22216,22217,22218,22219,\n22220,22221,22222,22223,22224,22225,22226,22227,22228,22229,22230,22231,\n22232,22233,22234,22235,22236,22237,22238,22239,22240,22241,22242,22243,\n22244,22245,22246,22247,22248,22249,22250,22251,22252,22253,22254,22255,\n22256,22257,22258,22259,22260,22261,22262,22263,22264,22265,22266,22267,\n22268,22269,22270,22271,22272,22273,22274,22275,22276,22277,22278,22279,\n22280,22281,22282,22283,22284,22285,22286,22287,22288,22289,22290,22291,\n22292,22293,22294,22295,22296,22297,22298,22299,22300,22301,22302,22303,\n22304,22305,22306,22307,22308,22309,22310,22311,22312,22313,22314,22315,\n22316,22317,22318,22319,22320,22321,22322,22323,22324,22325,22326,22327,\n22328,22329,22330,22331,22332,22333,22334,22335,22336,22337,22338,22339,\n22340,22341,22342,22343,22344,22345,22346,22347,22348,22349,22350,22351,\n22352,22353,22354,22355,22356,22357,22358,22359,22360,22361,22362,22363,\n22364,22365,22366,22367,22368,22369,22370,22371,22372,22373,22374,22375,\n22376,22377,22378,22379,22380,22381,22382,22383,22384,22385,22386,22387,\n22388,22389,22390,22391,22392,22393,22394,22395,22396,22397,22398,22399,\n22400,22401,22402,22403,22404,22405,22406,22407,22408,22409,22410,22411,\n22412,22413,22414,22415,22416,22417,22418,22419,22420,22421,22422,22423,\n22424,22425,22426,22427,22428,22429,22430,22431,22432,22433,22434,22435,\n22436,22437,22438,22439,22440,22441,22442,22443,22444,22445,22446,22447,\n22448,22449,22450,22451,22452,22453,22454,22455,22456,22457,22458,22459,\n22460,22461,22462,22463,22464,22465,22466,22467,22468,22469,22470,22471,\n22472,22473,22474,22475,22476,22477,22478,22479,22480,22481,22482,22483,\n22484,22485,22486,22487,22488,22489,22490,22491,22492,22493,22494,22495,\n22496,22497,22498,22499,22500,22501,22502,22503,22504,22505,22506,22507,\n22508,22509,22510,22511,22512,22513,22514,22515,22516,22517,22518,22519,\n22520,22521,22522,22523,22524,22525,22526,22527,22528,22529,22530,22531,\n22532,22533,22534,22535,22536,22537,22538,22539,22540,22541,22542,22543,\n22544,22545,22546,22547,22548,22549,22550,22551,22552,22553,22554,22555,\n22556,22557,22558,22559,22560,22561,22562,22563,22564,22565,22566,22567,\n22568,22569,22570,22571,22572,22573,22574,22575,22576,22577,22578,22579,\n22580,22581,22582,22583,22584,22585,22586,22587,22588,22589,22590,22591,\n22592,22593,22594,22595,22596,22597,22598,22599,22600,22601,22602,22603,\n22604,22605,22606,22607,22608,22609,22610,22611,22612,22613,22614,22615,\n22616,22617,22618,22619,22620,22621,22622,22623,22624,22625,22626,22627,\n22628,22629,22630,22631,22632,22633,22634,22635,22636,22637,22638,22639,\n22640,22641,22642,22643,22644,22645,22646,22647,22648,22649,22650,22651,\n22652,22653,22654,22655,22656,22657,22658,22659,22660,22661,22662,22663,\n22664,22665,22666,22667,22668,22669,22670,22671,22672,22673,22674,22675,\n22676,22677,22678,22679,22680,22681,22682,22683,22684,22685,22686,22687,\n22688,22689,22690,22691,22692,22693,22694,22695,22696,22697,22698,22699,\n22700,22701,22702,22703,22704,22705,22706,22707,22708,22709,22710,22711,\n22712,22713,22714,22715,22716,22717,22718,22719,22720,22721,22722,22723,\n22724,22725,22726,22727,22728,22729,22730,22731,22732,22733,22734,22735,\n22736,22737,22738,22739,22740,22741,22742,22743,22744,22745,22746,22747,\n22748,22749,22750,22751,22752,22753,22754,22755,22756,22757,22758,22759,\n22760,22761,22762,22763,22764,22765,22766,22767,22768,22769,22770,22771,\n22772,22773,22774,22775,22776,22777,22778,22779,22780,22781,22782,22783,\n22784,22785,22786,22787,22788,22789,22790,22791,22792,22793,22794,22795,\n22796,22797,22798,22799,22800,22801,22802,22803,22804,22805,22806,22807,\n22808,22809,22810,22811,22812,22813,22814,22815,22816,22817,22818,22819,\n22820,22821,22822,22823,22824,22825,22826,22827,22828,22829,22830,22831,\n22832,22833,22834,22835,22836,22837,22838,22839,22840,22841,22842,22843,\n22844,22845,22846,22847,22848,22849,22850,22851,22852,22853,22854,22855,\n22856,22857,22858,22859,22860,22861,22862,22863,22864,22865,22866,22867,\n22868,22869,22870,22871,22872,22873,22874,22875,22876,22877,22878,22879,\n22880,22881,22882,22883,22884,22885,22886,22887,22888,22889,22890,22891,\n22892,22893,22894,22895,22896,22897,22898,22899,22900,22901,22902,22903,\n22904,22905,22906,22907,22908,22909,22910,22911,22912,22913,22914,22915,\n22916,22917,22918,22919,22920,22921,22922,22923,22924,22925,22926,22927,\n22928,22929,22930,22931,22932,22933,22934,22935,22936,22937,22938,22939,\n22940,22941,22942,22943,22944,22945,22946,22947,22948,22949,22950,22951,\n22952,22953,22954,22955,22956,22957,22958,22959,22960,22961,22962,22963,\n22964,22965,22966,22967,22968,22969,22970,22971,22972,22973,22974,22975,\n22976,22977,22978,22979,22980,22981,22982,22983,22984,22985,22986,22987,\n22988,22989,22990,22991,22992,22993,22994,22995,22996,22997,22998,22999,\n23000,23001,23002,23003,23004,23005,23006,23007,23008,23009,23010,23011,\n23012,23013,23014,23015,23016,23017,23018,23019,23020,23021,23022,23023,\n23024,23025,23026,23027,23028,23029,23030,23031,23032,23033,23034,23035,\n23036,23037,23038,23039,23040,23041,23042,23043,23044,23045,23046,23047,\n23048,23049,23050,23051,23052,23053,23054,23055,23056,23057,23058,23059,\n23060,23061,23062,23063,23064,23065,23066,23067,23068,23069,23070,23071,\n23072,23073,23074,23075,23076,23077,23078,23079,23080,23081,23082,23083,\n23084,23085,23086,23087,23088,23089,23090,23091,23092,23093,23094,23095,\n23096,23097,23098,23099,23100,23101,23102,23103,23104,23105,23106,23107,\n23108,23109,23110,23111,23112,23113,23114,23115,23116,23117,23118,23119,\n23120,23121,23122,23123,23124,23125,23126,23127,23128,23129,23130,23131,\n23132,23133,23134,23135,23136,23137,23138,23139,23140,23141,23142,23143,\n23144,23145,23146,23147,23148,23149,23150,23151,23152,23153,23154,23155,\n23156,23157,23158,23159,23160,23161,23162,23163,23164,23165,23166,23167,\n23168,23169,23170,23171,23172,23173,23174,23175,23176,23177,23178,23179,\n23180,23181,23182,23183,23184,23185,23186,23187,23188,23189,23190,23191,\n23192,23193,23194,23195,23196,23197,23198,23199,23200,23201,23202,23203,\n23204,23205,23206,23207,23208,23209,23210,23211,23212,23213,23214,23215,\n23216,23217,23218,23219,23220,23221,23222,23223,23224,23225,23226,23227,\n23228,23229,23230,23231,23232,23233,23234,23235,23236,23237,23238,23239,\n23240,23241,23242,23243,23244,23245,23246,23247,23248,23249,23250,23251,\n23252,23253,23254,23255,23256,23257,23258,23259,23260,23261,23262,23263,\n23264,23265,23266,23267,23268,23269,23270,23271,23272,23273,23274,23275,\n23276,23277,23278,23279,23280,23281,23282,23283,23284,23285,23286,23287,\n23288,23289,23290,23291,23292,23293,23294,23295,23296,23297,23298,23299,\n23300,23301,23302,23303,23304,23305,23306,23307,23308,23309,23310,23311,\n23312,23313,23314,23315,23316,23317,23318,23319,23320,23321,23322,23323,\n23324,23325,23326,23327,23328,23329,23330,23331,23332,23333,23334,23335,\n23336,23337,23338,23339,23340,23341,23342,23343,23344,23345,23346,23347,\n23348,23349,23350,23351,23352,23353,23354,23355,23356,23357,23358,23359,\n23360,23361,23362,23363,23364,23365,23366,23367,23368,23369,23370,23371,\n23372,23373,23374,23375,23376,23377,23378,23379,23380,23381,23382,23383,\n23384,23385,23386,23387,23388,23389,23390,23391,23392,23393,23394,23395,\n23396,23397,23398,23399,23400,23401,23402,23403,23404,23405,23406,23407,\n23408,23409,23410,23411,23412,23413,23414,23415,23416,23417,23418,23419,\n23420,23421,23422,23423,23424,23425,23426,23427,23428,23429,23430,23431,\n23432,23433,23434,23435,23436,23437,23438,23439,23440,23441,23442,23443,\n23444,23445,23446,23447,23448,23449,23450,23451,23452,23453,23454,23455,\n23456,23457,23458,23459,23460,23461,23462,23463,23464,23465,23466,23467,\n23468,23469,23470,23471,23472,23473,23474,23475,23476,23477,23478,23479,\n23480,23481,23482,23483,23484,23485,23486,23487,23488,23489,23490,23491,\n23492,23493,23494,23495,23496,23497,23498,23499,23500,23501,23502,23503,\n23504,23505,23506,23507,23508,23509,23510,23511,23512,23513,23514,23515,\n23516,23517,23518,23519,23520,23521,23522,23523,23524,23525,23526,23527,\n23528,23529,23530,23531,23532,23533,23534,23535,23536,23537,23538,23539,\n23540,23541,23542,23543,23544,23545,23546,23547,23548,23549,23550,23551,\n23552,23553,23554,23555,23556,23557,23558,23559,23560,23561,23562,23563,\n23564,23565,23566,23567,23568,23569,23570,23571,23572,23573,23574,23575,\n23576,23577,23578,23579,23580,23581,23582,23583,23584,23585,23586,23587,\n23588,23589,23590,23591,23592,23593,23594,23595,23596,23597,23598,23599,\n23600,23601,23602,23603,23604,23605,23606,23607,23608,23609,23610,23611,\n23612,23613,23614,23615,23616,23617,23618,23619,23620,23621,23622,23623,\n23624,23625,23626,23627,23628,23629,23630,23631,23632,23633,23634,23635,\n23636,23637,23638,23639,23640,23641,23642,23643,23644,23645,23646,23647,\n23648,23649,23650,23651,23652,23653,23654,23655,23656,23657,23658,23659,\n23660,23661,23662,23663,23664,23665,23666,23667,23668,23669,23670,23671,\n23672,23673,23674,23675,23676,23677,23678,23679,23680,23681,23682,23683,\n23684,23685,23686,23687,23688,23689,23690,23691,23692,23693,23694,23695,\n23696,23697,23698,23699,23700,23701,23702,23703,23704,23705,23706,23707,\n23708,23709,23710,23711,23712,23713,23714,23715,23716,23717,23718,23719,\n23720,23721,23722,23723,23724,23725,23726,23727,23728,23729,23730,23731,\n23732,23733,23734,23735,23736,23737,23738,23739,23740,23741,23742,23743,\n23744,23745,23746,23747,23748,23749,23750,23751,23752,23753,23754,23755,\n23756,23757,23758,23759,23760,23761,23762,23763,23764,23765,23766,23767,\n23768,23769,23770,23771,23772,23773,23774,23775,23776,23777,23778,23779,\n23780,23781,23782,23783,23784,23785,23786,23787,23788,23789,23790,23791,\n23792,23793,23794,23795,23796,23797,23798,23799,23800,23801,23802,23803,\n23804,23805,23806,23807,23808,23809,23810,23811,23812,23813,23814,23815,\n23816,23817,23818,23819,23820,23821,23822,23823,23824,23825,23826,23827,\n23828,23829,23830,23831,23832,23833,23834,23835,23836,23837,23838,23839,\n23840,23841,23842,23843,23844,23845,23846,23847,23848,23849,23850,23851,\n23852,23853,23854,23855,23856,23857,23858,23859,23860,23861,23862,23863,\n23864,23865,23866,23867,23868,23869,23870,23871,23872,23873,23874,23875,\n23876,23877,23878,23879,23880,23881,23882,23883,23884,23885,23886,23887,\n23888,23889,23890,23891,23892,23893,23894,23895,23896,23897,23898,23899,\n23900,23901,23902,23903,23904,23905,23906,23907,23908,23909,23910,23911,\n23912,23913,23914,23915,23916,23917,23918,23919,23920,23921,23922,23923,\n23924,23925,23926,23927,23928,23929,23930,23931,23932,23933,23934,23935,\n23936,23937,23938,23939,23940,23941,23942,23943,23944,23945,23946,23947,\n23948,23949,23950,23951,23952,23953,23954,23955,23956,23957,23958,23959,\n23960,23961,23962,23963,23964,23965,23966,23967,23968,23969,23970,23971,\n23972,23973,23974,23975,23976,23977,23978,23979,23980,23981,23982,23983,\n23984,23985,23986,23987,23988,23989,23990,23991,23992,23993,23994,23995,\n23996,23997,23998,23999,24000,24001,24002,24003,24004,24005,24006,24007,\n24008,24009,24010,24011,24012,24013,24014,24015,24016,24017,24018,24019,\n24020,24021,24022,24023,24024,24025,24026,24027,24028,24029,24030,24031,\n24032,24033,24034,24035,24036,24037,24038,24039,24040,24041,24042,24043,\n24044,24045,24046,24047,24048,24049,24050,24051,24052,24053,24054,24055,\n24056,24057,24058,24059,24060,24061,24062,24063,24064,24065,24066,24067,\n24068,24069,24070,24071,24072,24073,24074,24075,24076,24077,24078,24079,\n24080,24081,24082,24083,24084,24085,24086,24087,24088,24089,24090,24091,\n24092,24093,24094,24095,24096,24097,24098,24099,24100,24101,24102,24103,\n24104,24105,24106,24107,24108,24109,24110,24111,24112,24113,24114,24115,\n24116,24117,24118,24119,24120,24121,24122,24123,24124,24125,24126,24127,\n24128,24129,24130,24131,24132,24133,24134,24135,24136,24137,24138,24139,\n24140,24141,24142,24143,24144,24145,24146,24147,24148,24149,24150,24151,\n24152,24153,24154,24155,24156,24157,24158,24159,24160,24161,24162,24163,\n24164,24165,24166,24167,24168,24169,24170,24171,24172,24173,24174,24175,\n24176,24177,24178,24179,24180,24181,24182,24183,24184,24185,24186,24187,\n24188,24189,24190,24191,24192,24193,24194,24195,24196,24197,24198,24199,\n24200,24201,24202,24203,24204,24205,24206,24207,24208,24209,24210,24211,\n24212,24213,24214,24215,24216,24217,24218,24219,24220,24221,24222,24223,\n24224,24225,24226,24227,24228,24229,24230,24231,24232,24233,24234,24235,\n24236,24237,24238,24239,24240,24241,24242,24243,24244,24245,24246,24247,\n24248,24249,24250,24251,24252,24253,24254,24255,24256,24257,24258,24259,\n24260,24261,24262,24263,24264,24265,24266,24267,24268,24269,24270,24271,\n24272,24273,24274,24275,24276,24277,24278,24279,24280,24281,24282,24283,\n24284,24285,24286,24287,24288,24289,24290,24291,24292,24293,24294,24295,\n24296,24297,24298,24299,24300,24301,24302,24303,24304,24305,24306,24307,\n24308,24309,24310,24311,24312,24313,24314,24315,24316,24317,24318,24319,\n24320,24321,24322,24323,24324,24325,24326,24327,24328,24329,24330,24331,\n24332,24333,24334,24335,24336,24337,24338,24339,24340,24341,24342,24343,\n24344,24345,24346,24347,24348,24349,24350,24351,24352,24353,24354,24355,\n24356,24357,24358,24359,24360,24361,24362,24363,24364,24365,24366,24367,\n24368,24369,24370,24371,24372,24373,24374,24375,24376,24377,24378,24379,\n24380,24381,24382,24383,24384,24385,24386,24387,24388,24389,24390,24391,\n24392,24393,24394,24395,24396,24397,24398,24399,24400,24401,24402,24403,\n24404,24405,24406,24407,24408,24409,24410,24411,24412,24413,24414,24415,\n24416,24417,24418,24419,24420,24421,24422,24423,24424,24425,24426,24427,\n24428,24429,24430,24431,24432,24433,24434,24435,24436,24437,24438,24439,\n24440,24441,24442,24443,24444,24445,24446,24447,24448,24449,24450,24451,\n24452,24453,24454,24455,24456,24457,24458,24459,24460,24461,24462,24463,\n24464,24465,24466,24467,24468,24469,24470,24471,24472,24473,24474,24475,\n24476,24477,24478,24479,24480,24481,24482,24483,24484,24485,24486,24487,\n24488,24489,24490,24491,24492,24493,24494,24495,24496,24497,24498,24499,\n24500,24501,24502,24503,24504,24505,24506,24507,24508,24509,24510,24511,\n24512,24513,24514,24515,24516,24517,24518,24519,24520,24521,24522,24523,\n24524,24525,24526,24527,24528,24529,24530,24531,24532,24533,24534,24535,\n24536,24537,24538,24539,24540,24541,24542,24543,24544,24545,24546,24547,\n24548,24549,24550,24551,24552,24553,24554,24555,24556,24557,24558,24559,\n24560,24561,24562,24563,24564,24565,24566,24567,24568,24569,24570,24571,\n24572,24573,24574,24575,24576,24577,24578,24579,24580,24581,24582,24583,\n24584,24585,24586,24587,24588,24589,24590,24591,24592,24593,24594,24595,\n24596,24597,24598,24599,24600,24601,24602,24603,24604,24605,24606,24607,\n24608,24609,24610,24611,24612,24613,24614,24615,24616,24617,24618,24619,\n24620,24621,24622,24623,24624,24625,24626,24627,24628,24629,24630,24631,\n24632,24633,24634,24635,24636,24637,24638,24639,24640,24641,24642,24643,\n24644,24645,24646,24647,24648,24649,24650,24651,24652,24653,24654,24655,\n24656,24657,24658,24659,24660,24661,24662,24663,24664,24665,24666,24667,\n24668,24669,24670,24671,24672,24673,24674,24675,24676,24677,24678,24679,\n24680,24681,24682,24683,24684,24685,24686,24687,24688,24689,24690,24691,\n24692,24693,24694,24695,24696,24697,24698,24699,24700,24701,24702,24703,\n24704,24705,24706,24707,24708,24709,24710,24711,24712,24713,24714,24715,\n24716,24717,24718,24719,24720,24721,24722,24723,24724,24725,24726,24727,\n24728,24729,24730,24731,24732,24733,24734,24735,24736,24737,24738,24739,\n24740,24741,24742,24743,24744,24745,24746,24747,24748,24749,24750,24751,\n24752,24753,24754,24755,24756,24757,24758,24759,24760,24761,24762,24763,\n24764,24765,24766,24767,24768,24769,24770,24771,24772,24773,24774,24775,\n24776,24777,24778,24779,24780,24781,24782,24783,24784,24785,24786,24787,\n24788,24789,24790,24791,24792,24793,24794,24795,24796,24797,24798,24799,\n24800,24801,24802,24803,24804,24805,24806,24807,24808,24809,24810,24811,\n24812,24813,24814,24815,24816,24817,24818,24819,24820,24821,24822,24823,\n24824,24825,24826,24827,24828,24829,24830,24831,24832,24833,24834,24835,\n24836,24837,24838,24839,24840,24841,24842,24843,24844,24845,24846,24847,\n24848,24849,24850,24851,24852,24853,24854,24855,24856,24857,24858,24859,\n24860,24861,24862,24863,24864,24865,24866,24867,24868,24869,24870,24871,\n24872,24873,24874,24875,24876,24877,24878,24879,24880,24881,24882,24883,\n24884,24885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24895,\n24896,24897,24898,24899,24900,24901,24902,24903,24904,24905,24906,24907,\n24908,24909,24910,24911,24912,24913,24914,24915,24916,24917,24918,24919,\n24920,24921,24922,24923,24924,24925,24926,24927,24928,24929,24930,24931,\n24932,24933,24934,24935,24936,24937,24938,24939,24940,24941,24942,24943,\n24944,24945,24946,24947,24948,24949,24950,24951,24952,24953,24954,24955,\n24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,24967,\n24968,24969,24970,24971,24972,24973,24974,24975,24976,24977,24978,24979,\n24980,24981,24982,24983,24984,24985,24986,24987,24988,24989,24990,24991,\n24992,24993,24994,24995,24996,24997,24998,24999,25000,25001,25002,25003,\n25004,25005,25006,25007,25008,25009,25010,25011,25012,25013,25014,25015,\n25016,25017,25018,25019,25020,25021,25022,25023,25024,25025,25026,25027,\n25028,25029,25030,25031,25032,25033,25034,25035,25036,25037,25038,25039,\n25040,25041,25042,25043,25044,25045,25046,25047,25048,25049,25050,25051,\n25052,25053,25054,25055,25056,25057,25058,25059,25060,25061,25062,25063,\n25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074,25075,\n25076,25077,25078,25079,25080,25081,25082,25083,25084,25085,25086,25087,\n25088,25089,25090,25091,25092,25093,25094,25095,25096,25097,25098,25099,\n25100,25101,25102,25103,25104,25105,25106,25107,25108,25109,25110,25111,\n25112,25113,25114,25115,25116,25117,25118,25119,25120,25121,25122,25123,\n25124,25125,25126,25127,25128,25129,25130,25131,25132,25133,25134,25135,\n25136,25137,25138,25139,25140,25141,25142,25143,25144,25145,25146,25147,\n25148,25149,25150,25151,25152,25153,25154,25155,25156,25157,25158,25159,\n25160,25161,25162,25163,25164,25165,25166,25167,25168,25169,25170,25171,\n25172,25173,25174,25175,25176,25177,25178,25179,25180,25181,25182,25183,\n25184,25185,25186,25187,25188,25189,25190,25191,25192,25193,25194,25195,\n25196,25197,25198,25199,25200,25201,25202,25203,25204,25205,25206,25207,\n25208,25209,25210,25211,25212,25213,25214,25215,25216,25217,25218,25219,\n25220,25221,25222,25223,25224,25225,25226,25227,25228,25229,25230,25231,\n25232,25233,25234,25235,25236,25237,25238,25239,25240,25241,25242,25243,\n25244,25245,25246,25247,25248,25249,25250,25251,25252,25253,25254,25255,\n25256,25257,25258,25259,25260,25261,25262,25263,25264,25265,25266,25267,\n25268,25269,25270,25271,25272,25273,25274,25275,25276,25277,25278,25279,\n25280,25281,25282,25283,25284,25285,25286,25287,25288,25289,25290,25291,\n25292,25293,25294,25295,25296,25297,25298,25299,25300,25301,25302,25303,\n25304,25305,25306,25307,25308,25309,25310,25311,25312,25313,25314,25315,\n25316,25317,25318,25319,25320,25321,25322,25323,25324,25325,25326,25327,\n25328,25329,25330,25331,25332,25333,25334,25335,25336,25337,25338,25339,\n25340,25341,25342,25343,25344,25345,25346,25347,25348,25349,25350,25351,\n25352,25353,25354,25355,25356,25357,25358,25359,25360,25361,25362,25363,\n25364,25365,25366,25367,25368,25369,25370,25371,25372,25373,25374,25375,\n25376,25377,25378,25379,25380,25381,25382,25383,25384,25385,25386,25387,\n25388,25389,25390,25391,25392,25393,25394,25395,25396,25397,25398,25399,\n25400,25401,25402,25403,25404,25405,25406,25407,25408,25409,25410,25411,\n25412,25413,25414,25415,25416,25417,25418,25419,25420,25421,25422,25423,\n25424,25425,25426,25427,25428,25429,25430,25431,25432,25433,25434,25435,\n25436,25437,25438,25439,25440,25441,25442,25443,25444,25445,25446,25447,\n25448,25449,25450,25451,25452,25453,25454,25455,25456,25457,25458,25459,\n25460,25461,25462,25463,25464,25465,25466,25467,25468,25469,25470,25471,\n25472,25473,25474,25475,25476,25477,25478,25479,25480,25481,25482,25483,\n25484,25485,25486,25487,25488,25489,25490,25491,25492,25493,25494,25495,\n25496,25497,25498,25499,25500,25501,25502,25503,25504,25505,25506,25507,\n25508,25509,25510,25511,25512,25513,25514,25515,25516,25517,25518,25519,\n25520,25521,25522,25523,25524,25525,25526,25527,25528,25529,25530,25531,\n25532,25533,25534,25535,25536,25537,25538,25539,25540,25541,25542,25543,\n25544,25545,25546,25547,25548,25549,25550,25551,25552,25553,25554,25555,\n25556,25557,25558,25559,25560,25561,25562,25563,25564,25565,25566,25567,\n25568,25569,25570,25571,25572,25573,25574,25575,25576,25577,25578,25579,\n25580,25581,25582,25583,25584,25585,25586,25587,25588,25589,25590,25591,\n25592,25593,25594,25595,25596,25597,25598,25599,25600,25601,25602,25603,\n25604,25605,25606,25607,25608,25609,25610,25611,25612,25613,25614,25615,\n25616,25617,25618,25619,25620,25621,25622,25623,25624,25625,25626,25627,\n25628,25629,25630,25631,25632,25633,25634,25635,25636,25637,25638,25639,\n25640,25641,25642,25643,25644,25645,25646,25647,25648,25649,25650,25651,\n25652,25653,25654,25655,25656,25657,25658,25659,25660,25661,25662,25663,\n25664,25665,25666,25667,25668,25669,25670,25671,25672,25673,25674,25675,\n25676,25677,25678,25679,25680,25681,25682,25683,25684,25685,25686,25687,\n25688,25689,25690,25691,25692,25693,25694,25695,25696,25697,25698,25699,\n25700,25701,25702,25703,25704,25705,25706,25707,25708,25709,25710,25711,\n25712,25713,25714,25715,25716,25717,25718,25719,25720,25721,25722,25723,\n25724,25725,25726,25727,25728,25729,25730,25731,25732,25733,25734,25735,\n25736,25737,25738,25739,25740,25741,25742,25743,25744,25745,25746,25747,\n25748,25749,25750,25751,25752,25753,25754,25755,25756,25757,25758,25759,\n25760,25761,25762,25763,25764,25765,25766,25767,25768,25769,25770,25771,\n25772,25773,25774,25775,25776,25777,25778,25779,25780,25781,25782,25783,\n25784,25785,25786,25787,25788,25789,25790,25791,25792,25793,25794,25795,\n25796,25797,25798,25799,25800,25801,25802,25803,25804,25805,25806,25807,\n25808,25809,25810,25811,25812,25813,25814,25815,25816,25817,25818,25819,\n25820,25821,25822,25823,25824,25825,25826,25827,25828,25829,25830,25831,\n25832,25833,25834,25835,25836,25837,25838,25839,25840,25841,25842,25843,\n25844,25845,25846,25847,25848,25849,25850,25851,25852,25853,25854,25855,\n25856,25857,25858,25859,25860,25861,25862,25863,25864,25865,25866,25867,\n25868,25869,25870,25871,25872,25873,25874,25875,25876,25877,25878,25879,\n25880,25881,25882,25883,25884,25885,25886,25887,25888,25889,25890,25891,\n25892,25893,25894,25895,25896,25897,25898,25899,25900,25901,25902,25903,\n25904,25905,25906,25907,25908,25909,25910,25911,25912,25913,25914,25915,\n25916,25917,25918,25919,25920,25921,25922,25923,25924,25925,25926,25927,\n25928,25929,25930,25931,25932,25933,25934,25935,25936,25937,25938,25939,\n25940,25941,25942,25943,25944,25945,25946,25947,25948,25949,25950,25951,\n25952,25953,25954,25955,25956,25957,25958,25959,25960,25961,25962,25963,\n25964,25965,25966,25967,25968,25969,25970,25971,25972,25973,25974,25975,\n25976,25977,25978,25979,25980,25981,25982,25983,25984,25985,25986,25987,\n25988,25989,25990,25991,25992,25993,25994,25995,25996,25997,25998,25999,\n26000,26001,26002,26003,26004,26005,26006,26007,26008,26009,26010,26011,\n26012,26013,26014,26015,26016,26017,26018,26019,26020,26021,26022,26023,\n26024,26025,26026,26027,26028,26029,26030,26031,26032,26033,26034,26035,\n26036,26037,26038,26039,26040,26041,26042,26043,26044,26045,26046,26047,\n26048,26049,26050,26051,26052,26053,26054,26055,26056,26057,26058,26059,\n26060,26061,26062,26063,26064,26065,26066,26067,26068,26069,26070,26071,\n26072,26073,26074,26075,26076,26077,26078,26079,26080,26081,26082,26083,\n26084,26085,26086,26087,26088,26089,26090,26091,26092,26093,26094,26095,\n26096,26097,26098,26099,26100,26101,26102,26103,26104,26105,26106,26107,\n26108,26109,26110,26111,26112,26113,26114,26115,26116,26117,26118,26119,\n26120,26121,26122,26123,26124,26125,26126,26127,26128,26129,26130,26131,\n26132,26133,26134,26135,26136,26137,26138,26139,26140,26141,26142,26143,\n26144,26145,26146,26147,26148,26149,26150,26151,26152,26153,26154,26155,\n26156,26157,26158,26159,26160,26161,26162,26163,26164,26165,26166,26167,\n26168,26169,26170,26171,26172,26173,26174,26175,26176,26177,26178,26179,\n26180,26181,26182,26183,26184,26185,26186,26187,26188,26189,26190,26191,\n26192,26193,26194,26195,26196,26197,26198,26199,26200,26201,26202,26203,\n26204,26205,26206,26207,26208,26209,26210,26211,26212,26213,26214,26215,\n26216,26217,26218,26219,26220,26221,26222,26223,26224,26225,26226,26227,\n26228,26229,26230,26231,26232,26233,26234,26235,26236,26237,26238,26239,\n26240,26241,26242,26243,26244,26245,26246,26247,26248,26249,26250,26251,\n26252,26253,26254,26255,26256,26257,26258,26259,26260,26261,26262,26263,\n26264,26265,26266,26267,26268,26269,26270,26271,26272,26273,26274,26275,\n26276,26277,26278,26279,26280,26281,26282,26283,26284,26285,26286,26287,\n26288,26289,26290,26291,26292,26293,26294,26295,26296,26297,26298,26299,\n26300,26301,26302,26303,26304,26305,26306,26307,26308,26309,26310,26311,\n26312,26313,26314,26315,26316,26317,26318,26319,26320,26321,26322,26323,\n26324,26325,26326,26327,26328,26329,26330,26331,26332,26333,26334,26335,\n26336,26337,26338,26339,26340,26341,26342,26343,26344,26345,26346,26347,\n26348,26349,26350,26351,26352,26353,26354,26355,26356,26357,26358,26359,\n26360,26361,26362,26363,26364,26365,26366,26367,26368,26369,26370,26371,\n26372,26373,26374,26375,26376,26377,26378,26379,26380,26381,26382,26383,\n26384,26385,26386,26387,26388,26389,26390,26391,26392,26393,26394,26395,\n26396,26397,26398,26399,26400,26401,26402,26403,26404,26405,26406,26407,\n26408,26409,26410,26411,26412,26413,26414,26415,26416,26417,26418,26419,\n26420,26421,26422,26423,26424,26425,26426,26427,26428,26429,26430,26431,\n26432,26433,26434,26435,26436,26437,26438,26439,26440,26441,26442,26443,\n26444,26445,26446,26447,26448,26449,26450,26451,26452,26453,26454,26455,\n26456,26457,26458,26459,26460,26461,26462,26463,26464,26465,26466,26467,\n26468,26469,26470,26471,26472,26473,26474,26475,26476,26477,26478,26479,\n26480,26481,26482,26483,26484,26485,26486,26487,26488,26489,26490,26491,\n26492,26493,26494,26495,26496,26497,26498,26499,26500,26501,26502,26503,\n26504,26505,26506,26507,26508,26509,26510,26511,26512,26513,26514,26515,\n26516,26517,26518,26519,26520,26521,26522,26523,26524,26525,26526,26527,\n26528,26529,26530,26531,26532,26533,26534,26535,26536,26537,26538,26539,\n26540,26541,26542,26543,26544,26545,26546,26547,26548,26549,26550,26551,\n26552,26553,26554,26555,26556,26557,26558,26559,26560,26561,26562,26563,\n26564,26565,26566,26567,26568,26569,26570,26571,26572,26573,26574,26575,\n26576,26577,26578,26579,26580,26581,26582,26583,26584,26585,26586,26587,\n26588,26589,26590,26591,26592,26593,26594,26595,26596,26597,26598,26599,\n26600,26601,26602,26603,26604,26605,26606,26607,26608,26609,26610,26611,\n26612,26613,26614,26615,26616,26617,26618,26619,26620,26621,26622,26623,\n26624,26625,26626,26627,26628,26629,26630,26631,26632,26633,26634,26635,\n26636,26637,26638,26639,26640,26641,26642,26643,26644,26645,26646,26647,\n26648,26649,26650,26651,26652,26653,26654,26655,26656,26657,26658,26659,\n26660,26661,26662,26663,26664,26665,26666,26667,26668,26669,26670,26671,\n26672,26673,26674,26675,26676,26677,26678,26679,26680,26681,26682,26683,\n26684,26685,26686,26687,26688,26689,26690,26691,26692,26693,26694,26695,\n26696,26697,26698,26699,26700,26701,26702,26703,26704,26705,26706,26707,\n26708,26709,26710,26711,26712,26713,26714,26715,26716,26717,26718,26719,\n26720,26721,26722,26723,26724,26725,26726,26727,26728,26729,26730,26731,\n26732,26733,26734,26735,26736,26737,26738,26739,26740,26741,26742,26743,\n26744,26745,26746,26747,26748,26749,26750,26751,26752,26753,26754,26755,\n26756,26757,26758,26759,26760,26761,26762,26763,26764,26765,26766,26767,\n26768,26769,26770,26771,26772,26773,26774,26775,26776,26777,26778,26779,\n26780,26781,26782,26783,26784,26785,26786,26787,26788,26789,26790,26791,\n26792,26793,26794,26795,26796,26797,26798,26799,26800,26801,26802,26803,\n26804,26805,26806,26807,26808,26809,26810,26811,26812,26813,26814,26815,\n26816,26817,26818,26819,26820,26821,26822,26823,26824,26825,26826,26827,\n26828,26829,26830,26831,26832,26833,26834,26835,26836,26837,26838,26839,\n26840,26841,26842,26843,26844,26845,26846,26847,26848,26849,26850,26851,\n26852,26853,26854,26855,26856,26857,26858,26859,26860,26861,26862,26863,\n26864,26865,26866,26867,26868,26869,26870,26871,26872,26873,26874,26875,\n26876,26877,26878,26879,26880,26881,26882,26883,26884,26885,26886,26887,\n26888,26889,26890,26891,26892,26893,26894,26895,26896,26897,26898,26899,\n26900,26901,26902,26903,26904,26905,26906,26907,26908,26909,26910,26911,\n26912,26913,26914,26915,26916,26917,26918,26919,26920,26921,26922,26923,\n26924,26925,26926,26927,26928,26929,26930,26931,26932,26933,26934,26935,\n26936,26937,26938,26939,26940,26941,26942,26943,26944,26945,26946,26947,\n26948,26949,26950,26951,26952,26953,26954,26955,26956,26957,26958,26959,\n26960,26961,26962,26963,26964,26965,26966,26967,26968,26969,26970,26971,\n26972,26973,26974,26975,26976,26977,26978,26979,26980,26981,26982,26983,\n26984,26985,26986,26987,26988,26989,26990,26991,26992,26993,26994,26995,\n26996,26997,26998,26999,27000,27001,27002,27003,27004,27005,27006,27007,\n27008,27009,27010,27011,27012,27013,27014,27015,27016,27017,27018,27019,\n27020,27021,27022,27023,27024,27025,27026,27027,27028,27029,27030,27031,\n27032,27033,27034,27035,27036,27037,27038,27039,27040,27041,27042,27043,\n27044,27045,27046,27047,27048,27049,27050,27051,27052,27053,27054,27055,\n27056,27057,27058,27059,27060,27061,27062,27063,27064,27065,27066,27067,\n27068,27069,27070,27071,27072,27073,27074,27075,27076,27077,27078,27079,\n27080,27081,27082,27083,27084,27085,27086,27087,27088,27089,27090,27091,\n27092,27093,27094,27095,27096,27097,27098,27099,27100,27101,27102,27103,\n27104,27105,27106,27107,27108,27109,27110,27111,27112,27113,27114,27115,\n27116,27117,27118,27119,27120,27121,27122,27123,27124,27125,27126,27127,\n27128,27129,27130,27131,27132,27133,27134,27135,27136,27137,27138,27139,\n27140,27141,27142,27143,27144,27145,27146,27147,27148,27149,27150,27151,\n27152,27153,27154,27155,27156,27157,27158,27159,27160,27161,27162,27163,\n27164,27165,27166,27167,27168,27169,27170,27171,27172,27173,27174,27175,\n27176,27177,27178,27179,27180,27181,27182,27183,27184,27185,27186,27187,\n27188,27189,27190,27191,27192,27193,27194,27195,27196,27197,27198,27199,\n27200,27201,27202,27203,27204,27205,27206,27207,27208,27209,27210,27211,\n27212,27213,27214,27215,27216,27217,27218,27219,27220,27221,27222,27223,\n27224,27225,27226,27227,27228,27229,27230,27231,27232,27233,27234,27235,\n27236,27237,27238,27239,27240,27241,27242,27243,27244,27245,27246,27247,\n27248,27249,27250,27251,27252,27253,27254,27255,27256,27257,27258,27259,\n27260,27261,27262,27263,27264,27265,27266,27267,27268,27269,27270,27271,\n27272,27273,27274,27275,27276,27277,27278,27279,27280,27281,27282,27283,\n27284,27285,27286,27287,27288,27289,27290,27291,27292,27293,27294,27295,\n27296,27297,27298,27299,27300,27301,27302,27303,27304,27305,27306,27307,\n27308,27309,27310,27311,27312,27313,27314,27315,27316,27317,27318,27319,\n27320,27321,27322,27323,27324,27325,27326,27327,27328,27329,27330,27331,\n27332,27333,27334,27335,27336,27337,27338,27339,27340,27341,27342,27343,\n27344,27345,27346,27347,27348,27349,27350,27351,27352,27353,27354,27355,\n27356,27357,27358,27359,27360,27361,27362,27363,27364,27365,27366,27367,\n27368,27369,27370,27371,27372,27373,27374,27375,27376,27377,27378,27379,\n27380,27381,27382,27383,27384,27385,27386,27387,27388,27389,27390,27391,\n27392,27393,27394,27395,27396,27397,27398,27399,27400,27401,27402,27403,\n27404,27405,27406,27407,27408,27409,27410,27411,27412,27413,27414,27415,\n27416,27417,27418,27419,27420,27421,27422,27423,27424,27425,27426,27427,\n27428,27429,27430,27431,27432,27433,27434,27435,27436,27437,27438,27439,\n27440,27441,27442,27443,27444,27445,27446,27447,27448,27449,27450,27451,\n27452,27453,27454,27455,27456,27457,27458,27459,27460,27461,27462,27463,\n27464,27465,27466,27467,27468,27469,27470,27471,27472,27473,27474,27475,\n27476,27477,27478,27479,27480,27481,27482,27483,27484,27485,27486,27487,\n27488,27489,27490,27491,27492,27493,27494,27495,27496,27497,27498,27499,\n27500,27501,27502,27503,27504,27505,27506,27507,27508,27509,27510,27511,\n27512,27513,27514,27515,27516,27517,27518,27519,27520,27521,27522,27523,\n27524,27525,27526,27527,27528,27529,27530,27531,27532,27533,27534,27535,\n27536,27537,27538,27539,27540,27541,27542,27543,27544,27545,27546,27547,\n27548,27549,27550,27551,27552,27553,27554,27555,27556,27557,27558,27559,\n27560,27561,27562,27563,27564,27565,27566,27567,27568,27569,27570,27571,\n27572,27573,27574,27575,27576,27577,27578,27579,27580,27581,27582,27583,\n27584,27585,27586,27587,27588,27589,27590,27591,27592,27593,27594,27595,\n27596,27597,27598,27599,27600,27601,27602,27603,27604,27605,27606,27607,\n27608,27609,27610,27611,27612,27613,27614,27615,27616,27617,27618,27619,\n27620,27621,27622,27623,27624,27625,27626,27627,27628,27629,27630,27631,\n27632,27633,27634,27635,27636,27637,27638,27639,27640,27641,27642,27643,\n27644,27645,27646,27647,27648,27649,27650,27651,27652,27653,27654,27655,\n27656,27657,27658,27659,27660,27661,27662,27663,27664,27665,27666,27667,\n27668,27669,27670,27671,27672,27673,27674,27675,27676,27677,27678,27679,\n27680,27681,27682,27683,27684,27685,27686,27687,27688,27689,27690,27691,\n27692,27693,27694,27695,27696,27697,27698,27699,27700,27701,27702,27703,\n27704,27705,27706,27707,27708,27709,27710,27711,27712,27713,27714,27715,\n27716,27717,27718,27719,27720,27721,27722,27723,27724,27725,27726,27727,\n27728,27729,27730,27731,27732,27733,27734,27735,27736,27737,27738,27739,\n27740,27741,27742,27743,27744,27745,27746,27747,27748,27749,27750,27751,\n27752,27753,27754,27755,27756,27757,27758,27759,27760,27761,27762,27763,\n27764,27765,27766,27767,27768,27769,27770,27771,27772,27773,27774,27775,\n27776,27777,27778,27779,27780,27781,27782,27783,27784,27785,27786,27787,\n27788,27789,27790,27791,27792,27793,27794,27795,27796,27797,27798,27799,\n27800,27801,27802,27803,27804,27805,27806,27807,27808,27809,27810,27811,\n27812,27813,27814,27815,27816,27817,27818,27819,27820,27821,27822,27823,\n27824,27825,27826,27827,27828,27829,27830,27831,27832,27833,27834,27835,\n27836,27837,27838,27839,27840,27841,27842,27843,27844,27845,27846,27847,\n27848,27849,27850,27851,27852,27853,27854,27855,27856,27857,27858,27859,\n27860,27861,27862,27863,27864,27865,27866,27867,27868,27869,27870,27871,\n27872,27873,27874,27875,27876,27877,27878,27879,27880,27881,27882,27883,\n27884,27885,27886,27887,27888,27889,27890,27891,27892,27893,27894,27895,\n27896,27897,27898,27899,27900,27901,27902,27903,27904,27905,27906,27907,\n27908,27909,27910,27911,27912,27913,27914,27915,27916,27917,27918,27919,\n27920,27921,27922,27923,27924,27925,27926,27927,27928,27929,27930,27931,\n27932,27933,27934,27935,27936,27937,27938,27939,27940,27941,27942,27943,\n27944,27945,27946,27947,27948,27949,27950,27951,27952,27953,27954,27955,\n27956,27957,27958,27959,27960,27961,27962,27963,27964,27965,27966,27967,\n27968,27969,27970,27971,27972,27973,27974,27975,27976,27977,27978,27979,\n27980,27981,27982,27983,27984,27985,27986,27987,27988,27989,27990,27991,\n27992,27993,27994,27995,27996,27997,27998,27999,28000,28001,28002,28003,\n28004,28005,28006,28007,28008,28009,28010,28011,28012,28013,28014,28015,\n28016,28017,28018,28019,28020,28021,28022,28023,28024,28025,28026,28027,\n28028,28029,28030,28031,28032,28033,28034,28035,28036,28037,28038,28039,\n28040,28041,28042,28043,28044,28045,28046,28047,28048,28049,28050,28051,\n28052,28053,28054,28055,28056,28057,28058,28059,28060,28061,28062,28063,\n28064,28065,28066,28067,28068,28069,28070,28071,28072,28073,28074,28075,\n28076,28077,28078,28079,28080,28081,28082,28083,28084,28085,28086,28087,\n28088,28089,28090,28091,28092,28093,28094,28095,28096,28097,28098,28099,\n28100,28101,28102,28103,28104,28105,28106,28107,28108,28109,28110,28111,\n28112,28113,28114,28115,28116,28117,28118,28119,28120,28121,28122,28123,\n28124,28125,28126,28127,28128,28129,28130,28131,28132,28133,28134,28135,\n28136,28137,28138,28139,28140,28141,28142,28143,28144,28145,28146,28147,\n28148,28149,28150,28151,28152,28153,28154,28155,28156,28157,28158,28159,\n28160,28161,28162,28163,28164,28165,28166,28167,28168,28169,28170,28171,\n28172,28173,28174,28175,28176,28177,28178,28179,28180,28181,28182,28183,\n28184,28185,28186,28187,28188,28189,28190,28191,28192,28193,28194,28195,\n28196,28197,28198,28199,28200,28201,28202,28203,28204,28205,28206,28207,\n28208,28209,28210,28211,28212,28213,28214,28215,28216,28217,28218,28219,\n28220,28221,28222,28223,28224,28225,28226,28227,28228,28229,28230,28231,\n28232,28233,28234,28235,28236,28237,28238,28239,28240,28241,28242,28243,\n28244,28245,28246,28247,28248,28249,28250,28251,28252,28253,28254,28255,\n28256,28257,28258,28259,28260,28261,28262,28263,28264,28265,28266,28267,\n28268,28269,28270,28271,28272,28273,28274,28275,28276,28277,28278,28279,\n28280,28281,28282,28283,28284,28285,28286,28287,28288,28289,28290,28291,\n28292,28293,28294,28295,28296,28297,28298,28299,28300,28301,28302,28303,\n28304,28305,28306,28307,28308,28309,28310,28311,28312,28313,28314,28315,\n28316,28317,28318,28319,28320,28321,28322,28323,28324,28325,28326,28327,\n28328,28329,28330,28331,28332,28333,28334,28335,28336,28337,28338,28339,\n28340,28341,28342,28343,28344,28345,28346,28347,28348,28349,28350,28351,\n28352,28353,28354,28355,28356,28357,28358,28359,28360,28361,28362,28363,\n28364,28365,28366,28367,28368,28369,28370,28371,28372,28373,28374,28375,\n28376,28377,28378,28379,28380,28381,28382,28383,28384,28385,28386,28387,\n28388,28389,28390,28391,28392,28393,28394,28395,28396,28397,28398,28399,\n28400,28401,28402,28403,28404,28405,28406,28407,28408,28409,28410,28411,\n28412,28413,28414,28415,28416,28417,28418,28419,28420,28421,28422,28423,\n28424,28425,28426,28427,28428,28429,28430,28431,28432,28433,28434,28435,\n28436,28437,28438,28439,28440,28441,28442,28443,28444,28445,28446,28447,\n28448,28449,28450,28451,28452,28453,28454,28455,28456,28457,28458,28459,\n28460,28461,28462,28463,28464,28465,28466,28467,28468,28469,28470,28471,\n28472,28473,28474,28475,28476,28477,28478,28479,28480,28481,28482,28483,\n28484,28485,28486,28487,28488,28489,28490,28491,28492,28493,28494,28495,\n28496,28497,28498,28499,28500,28501,28502,28503,28504,28505,28506,28507,\n28508,28509,28510,28511,28512,28513,28514,28515,28516,28517,28518,28519,\n28520,28521,28522,28523,28524,28525,28526,28527,28528,28529,28530,28531,\n28532,28533,28534,28535,28536,28537,28538,28539,28540,28541,28542,28543,\n28544,28545,28546,28547,28548,28549,28550,28551,28552,28553,28554,28555,\n28556,28557,28558,28559,28560,28561,28562,28563,28564,28565,28566,28567,\n28568,28569,28570,28571,28572,28573,28574,28575,28576,28577,28578,28579,\n28580,28581,28582,28583,28584,28585,28586,28587,28588,28589,28590,28591,\n28592,28593,28594,28595,28596,28597,28598,28599,28600,28601,28602,28603,\n28604,28605,28606,28607,28608,28609,28610,28611,28612,28613,28614,28615,\n28616,28617,28618,28619,28620,28621,28622,28623,28624,28625,28626,28627,\n28628,28629,28630,28631,28632,28633,28634,28635,28636,28637,28638,28639,\n28640,28641,28642,28643,28644,28645,28646,28647,28648,28649,28650,28651,\n28652,28653,28654,28655,28656,28657,28658,28659,28660,28661,28662,28663,\n28664,28665,28666,28667,28668,28669,28670,28671,28672,28673,28674,28675,\n28676,28677,28678,28679,28680,28681,28682,28683,28684,28685,28686,28687,\n28688,28689,28690,28691,28692,28693,28694,28695,28696,28697,28698,28699,\n28700,28701,28702,28703,28704,28705,28706,28707,28708,28709,28710,28711,\n28712,28713,28714,28715,28716,28717,28718,28719,28720,28721,28722,28723,\n28724,28725,28726,28727,28728,28729,28730,28731,28732,28733,28734,28735,\n28736,28737,28738,28739,28740,28741,28742,28743,28744,28745,28746,28747,\n28748,28749,28750,28751,28752,28753,28754,28755,28756,28757,28758,28759,\n28760,28761,28762,28763,28764,28765,28766,28767,28768,28769,28770,28771,\n28772,28773,28774,28775,28776,28777,28778,28779,28780,28781,28782,28783,\n28784,28785,28786,28787,28788,28789,28790,28791,28792,28793,28794,28795,\n28796,28797,28798,28799,28800,28801,28802,28803,28804,28805,28806,28807,\n28808,28809,28810,28811,28812,28813,28814,28815,28816,28817,28818,28819,\n28820,28821,28822,28823,28824,28825,28826,28827,28828,28829,28830,28831,\n28832,28833,28834,28835,28836,28837,28838,28839,28840,28841,28842,28843,\n28844,28845,28846,28847,28848,28849,28850,28851,28852,28853,28854,28855,\n28856,28857,28858,28859,28860,28861,28862,28863,28864,28865,28866,28867,\n28868,28869,28870,28871,28872,28873,28874,28875,28876,28877,28878,28879,\n28880,28881,28882,28883,28884,28885,28886,28887,28888,28889,28890,28891,\n28892,28893,28894,28895,28896,28897,28898,28899,28900,28901,28902,28903,\n28904,28905,28906,28907,28908,28909,28910,28911,28912,28913,28914,28915,\n28916,28917,28918,28919,28920,28921,28922,28923,28924,28925,28926,28927,\n28928,28929,28930,28931,28932,28933,28934,28935,28936,28937,28938,28939,\n28940,28941,28942,28943,28944,28945,28946,28947,28948,28949,28950,28951,\n28952,28953,28954,28955,28956,28957,28958,28959,28960,28961,28962,28963,\n28964,28965,28966,28967,28968,28969,28970,28971,28972,28973,28974,28975,\n28976,28977,28978,28979,28980,28981,28982,28983,28984,28985,28986,28987,\n28988,28989,28990,28991,28992,28993,28994,28995,28996,28997,28998,28999,\n29000,29001,29002,29003,29004,29005,29006,29007,29008,29009,29010,29011,\n29012,29013,29014,29015,29016,29017,29018,29019,29020,29021,29022,29023,\n29024,29025,29026,29027,29028,29029,29030,29031,29032,29033,29034,29035,\n29036,29037,29038,29039,29040,29041,29042,29043,29044,29045,29046,29047,\n29048,29049,29050,29051,29052,29053,29054,29055,29056,29057,29058,29059,\n29060,29061,29062,29063,29064,29065,29066,29067,29068,29069,29070,29071,\n29072,29073,29074,29075,29076,29077,29078,29079,29080,29081,29082,29083,\n29084,29085,29086,29087,29088,29089,29090,29091,29092,29093,29094,29095,\n29096,29097,29098,29099,29100,29101,29102,29103,29104,29105,29106,29107,\n29108,29109,29110,29111,29112,29113,29114,29115,29116,29117,29118,29119,\n29120,29121,29122,29123,29124,29125,29126,29127,29128,29129,29130,29131,\n29132,29133,29134,29135,29136,29137,29138,29139,29140,29141,29142,29143,\n29144,29145,29146,29147,29148,29149,29150,29151,29152,29153,29154,29155,\n29156,29157,29158,29159,29160,29161,29162,29163,29164,29165,29166,29167,\n29168,29169,29170,29171,29172,29173,29174,29175,29176,29177,29178,29179,\n29180,29181,29182,29183,29184,29185,29186,29187,29188,29189,29190,29191,\n29192,29193,29194,29195,29196,29197,29198,29199,29200,29201,29202,29203,\n29204,29205,29206,29207,29208,29209,29210,29211,29212,29213,29214,29215,\n29216,29217,29218,29219,29220,29221,29222,29223,29224,29225,29226,29227,\n29228,29229,29230,29231,29232,29233,29234,29235,29236,29237,29238,29239,\n29240,29241,29242,29243,29244,29245,29246,29247,29248,29249,29250,29251,\n29252,29253,29254,29255,29256,29257,29258,29259,29260,29261,29262,29263,\n29264,29265,29266,29267,29268,29269,29270,29271,29272,29273,29274,29275,\n29276,29277,29278,29279,29280,29281,29282,29283,29284,29285,29286,29287,\n29288,29289,29290,29291,29292,29293,29294,29295,29296,29297,29298,29299,\n29300,29301,29302,29303,29304,29305,29306,29307,29308,29309,29310,29311,\n29312,29313,29314,29315,29316,29317,29318,29319,29320,29321,29322,29323,\n29324,29325,29326,29327,29328,29329,29330,29331,29332,29333,29334,29335,\n29336,29337,29338,29339,29340,29341,29342,29343,29344,29345,29346,29347,\n29348,29349,29350,29351,29352,29353,29354,29355,29356,29357,29358,29359,\n29360,29361,29362,29363,29364,29365,29366,29367,29368,29369,29370,29371,\n29372,29373,29374,29375,29376,29377,29378,29379,29380,29381,29382,29383,\n29384,29385,29386,29387,29388,29389,29390,29391,29392,29393,29394,29395,\n29396,29397,29398,29399,29400,29401,29402,29403,29404,29405,29406,29407,\n29408,29409,29410,29411,29412,29413,29414,29415,29416,29417,29418,29419,\n29420,29421,29422,29423,29424,29425,29426,29427,29428,29429,29430,29431,\n29432,29433,29434,29435,29436,29437,29438,29439,29440,29441,29442,29443,\n29444,29445,29446,29447,29448,29449,29450,29451,29452,29453,29454,29455,\n29456,29457,29458,29459,29460,29461,29462,29463,29464,29465,29466,29467,\n29468,29469,29470,29471,29472,29473,29474,29475,29476,29477,29478,29479,\n29480,29481,29482,29483,29484,29485,29486,29487,29488,29489,29490,29491,\n29492,29493,29494,29495,29496,29497,29498,29499,29500,29501,29502,29503,\n29504,29505,29506,29507,29508,29509,29510,29511,29512,29513,29514,29515,\n29516,29517,29518,29519,29520,29521,29522,29523,29524,29525,29526,29527,\n29528,29529,29530,29531,29532,29533,29534,29535,29536,29537,29538,29539,\n29540,29541,29542,29543,29544,29545,29546,29547,29548,29549,29550,29551,\n29552,29553,29554,29555,29556,29557,29558,29559,29560,29561,29562,29563,\n29564,29565,29566,29567,29568,29569,29570,29571,29572,29573,29574,29575,\n29576,29577,29578,29579,29580,29581,29582,29583,29584,29585,29586,29587,\n29588,29589,29590,29591,29592,29593,29594,29595,29596,29597,29598,29599,\n29600,29601,29602,29603,29604,29605,29606,29607,29608,29609,29610,29611,\n29612,29613,29614,29615,29616,29617,29618,29619,29620,29621,29622,29623,\n29624,29625,29626,29627,29628,29629,29630,29631,29632,29633,29634,29635,\n29636,29637,29638,29639,29640,29641,29642,29643,29644,29645,29646,29647,\n29648,29649,29650,29651,29652,29653,29654,29655,29656,29657,29658,29659,\n29660,29661,29662,29663,29664,29665,29666,29667,29668,29669,29670,29671,\n29672,29673,29674,29675,29676,29677,29678,29679,29680,29681,29682,29683,\n29684,29685,29686,29687,29688,29689,29690,29691,29692,29693,29694,29695,\n29696,29697,29698,29699,29700,29701,29702,29703,29704,29705,29706,29707,\n29708,29709,29710,29711,29712,29713,29714,29715,29716,29717,29718,29719,\n29720,29721,29722,29723,29724,29725,29726,29727,29728,29729,29730,29731,\n29732,29733,29734,29735,29736,29737,29738,29739,29740,29741,29742,29743,\n29744,29745,29746,29747,29748,29749,29750,29751,29752,29753,29754,29755,\n29756,29757,29758,29759,29760,29761,29762,29763,29764,29765,29766,29767,\n29768,29769,29770,29771,29772,29773,29774,29775,29776,29777,29778,29779,\n29780,29781,29782,29783,29784,29785,29786,29787,29788,29789,29790,29791,\n29792,29793,29794,29795,29796,29797,29798,29799,29800,29801,29802,29803,\n29804,29805,29806,29807,29808,29809,29810,29811,29812,29813,29814,29815,\n29816,29817,29818,29819,29820,29821,29822,29823,29824,29825,29826,29827,\n29828,29829,29830,29831,29832,29833,29834,29835,29836,29837,29838,29839,\n29840,29841,29842,29843,29844,29845,29846,29847,29848,29849,29850,29851,\n29852,29853,29854,29855,29856,29857,29858,29859,29860,29861,29862,29863,\n29864,29865,29866,29867,29868,29869,29870,29871,29872,29873,29874,29875,\n29876,29877,29878,29879,29880,29881,29882,29883,29884,29885,29886,29887,\n29888,29889,29890,29891,29892,29893,29894,29895,29896,29897,29898,29899,\n29900,29901,29902,29903,29904,29905,29906,29907,29908,29909,29910,29911,\n29912,29913,29914,29915,29916,29917,29918,29919,29920,29921,29922,29923,\n29924,29925,29926,29927,29928,29929,29930,29931,29932,29933,29934,29935,\n29936,29937,29938,29939,29940,29941,29942,29943,29944,29945,29946,29947,\n29948,29949,29950,29951,29952,29953,29954,29955,29956,29957,29958,29959,\n29960,29961,29962,29963,29964,29965,29966,29967,29968,29969,29970,29971,\n29972,29973,29974,29975,29976,29977,29978,29979,29980,29981,29982,29983,\n29984,29985,29986,29987,29988,29989,29990,29991,29992,29993,29994,29995,\n29996,29997,29998,29999,30000,30001,30002,30003,30004,30005,30006,30007,\n30008,30009,30010,30011,30012,30013,30014,30015,30016,30017,30018,30019,\n30020,30021,30022,30023,30024,30025,30026,30027,30028,30029,30030,30031,\n30032,30033,30034,30035,30036,30037,30038,30039,30040,30041,30042,30043,\n30044,30045,30046,30047,30048,30049,30050,30051,30052,30053,30054,30055,\n30056,30057,30058,30059,30060,30061,30062,30063,30064,30065,30066,30067,\n30068,30069,30070,30071,30072,30073,30074,30075,30076,30077,30078,30079,\n30080,30081,30082,30083,30084,30085,30086,30087,30088,30089,30090,30091,\n30092,30093,30094,30095,30096,30097,30098,30099,30100,30101,30102,30103,\n30104,30105,30106,30107,30108,30109,30110,30111,30112,30113,30114,30115,\n30116,30117,30118,30119,30120,30121,30122,30123,30124,30125,30126,30127,\n30128,30129,30130,30131,30132,30133,30134,30135,30136,30137,30138,30139,\n30140,30141,30142,30143,30144,30145,30146,30147,30148,30149,30150,30151,\n30152,30153,30154,30155,30156,30157,30158,30159,30160,30161,30162,30163,\n30164,30165,30166,30167,30168,30169,30170,30171,30172,30173,30174,30175,\n30176,30177,30178,30179,30180,30181,30182,30183,30184,30185,30186,30187,\n30188,30189,30190,30191,30192,30193,30194,30195,30196,30197,30198,30199,\n30200,30201,30202,30203,30204,30205,30206,30207,30208,30209,30210,30211,\n30212,30213,30214,30215,30216,30217,30218,30219,30220,30221,30222,30223,\n30224,30225,30226,30227,30228,30229,30230,30231,30232,30233,30234,30235,\n30236,30237,30238,30239,30240,30241,30242,30243,30244,30245,30246,30247,\n30248,30249,30250,30251,30252,30253,30254,30255,30256,30257,30258,30259,\n30260,30261,30262,30263,30264,30265,30266,30267,30268,30269,30270,30271,\n30272,30273,30274,30275,30276,30277,30278,30279,30280,30281,30282,30283,\n30284,30285,30286,30287,30288,30289,30290,30291,30292,30293,30294,30295,\n30296,30297,30298,30299,30300,30301,30302,30303,30304,30305,30306,30307,\n30308,30309,30310,30311,30312,30313,30314,30315,30316,30317,30318,30319,\n30320,30321,30322,30323,30324,30325,30326,30327,30328,30329,30330,30331,\n30332,30333,30334,30335,30336,30337,30338,30339,30340,30341,30342,30343,\n30344,30345,30346,30347,30348,30349,30350,30351,30352,30353,30354,30355,\n30356,30357,30358,30359,30360,30361,30362,30363,30364,30365,30366,30367,\n30368,30369,30370,30371,30372,30373,30374,30375,30376,30377,30378,30379,\n30380,30381,30382,30383,30384,30385,30386,30387,30388,30389,30390,30391,\n30392,30393,30394,30395,30396,30397,30398,30399,30400,30401,30402,30403,\n30404,30405,30406,30407,30408,30409,30410,30411,30412,30413,30414,30415,\n30416,30417,30418,30419,30420,30421,30422,30423,30424,30425,30426,30427,\n30428,30429,30430,30431,30432,30433,30434,30435,30436,30437,30438,30439,\n30440,30441,30442,30443,30444,30445,30446,30447,30448,30449,30450,30451,\n30452,30453,30454,30455,30456,30457,30458,30459,30460,30461,30462,30463,\n30464,30465,30466,30467,30468,30469,30470,30471,30472,30473,30474,30475,\n30476,30477,30478,30479,30480,30481,30482,30483,30484,30485,30486,30487,\n30488,30489,30490,30491,30492,30493,30494,30495,30496,30497,30498,30499,\n30500,30501,30502,30503,30504,30505,30506,30507,30508,30509,30510,30511,\n30512,30513,30514,30515,30516,30517,30518,30519,30520,30521,30522,30523,\n30524,30525,30526,30527,30528,30529,30530,30531,30532,30533,30534,30535,\n30536,30537,30538,30539,30540,30541,30542,30543,30544,30545,30546,30547,\n30548,30549,30550,30551,30552,30553,30554,30555,30556,30557,30558,30559,\n30560,30561,30562,30563,30564,30565,30566,30567,30568,30569,30570,30571,\n30572,30573,30574,30575,30576,30577,30578,30579,30580,30581,30582,30583,\n30584,30585,30586,30587,30588,30589,30590,30591,30592,30593,30594,30595,\n30596,30597,30598,30599,30600,30601,30602,30603,30604,30605,30606,30607,\n30608,30609,30610,30611,30612,30613,30614,30615,30616,30617,30618,30619,\n30620,30621,30622,30623,30624,30625,30626,30627,30628,30629,30630,30631,\n30632,30633,30634,30635,30636,30637,30638,30639,30640,30641,30642,30643,\n30644,30645,30646,30647,30648,30649,30650,30651,30652,30653,30654,30655,\n30656,30657,30658,30659,30660,30661,30662,30663,30664,30665,30666,30667,\n30668,30669,30670,30671,30672,30673,30674,30675,30676,30677,30678,30679,\n30680,30681,30682,30683,30684,30685,30686,30687,30688,30689,30690,30691,\n30692,30693,30694,30695,30696,30697,30698,30699,30700,30701,30702,30703,\n30704,30705,30706,30707,30708,30709,30710,30711,30712,30713,30714,30715,\n30716,30717,30718,30719,30720,30721,30722,30723,30724,30725,30726,30727,\n30728,30729,30730,30731,30732,30733,30734,30735,30736,30737,30738,30739,\n30740,30741,30742,30743,30744,30745,30746,30747,30748,30749,30750,30751,\n30752,30753,30754,30755,30756,30757,30758,30759,30760,30761,30762,30763,\n30764,30765,30766,30767,30768,30769,30770,30771,30772,30773,30774,30775,\n30776,30777,30778,30779,30780,30781,30782,30783,30784,30785,30786,30787,\n30788,30789,30790,30791,30792,30793,30794,30795,30796,30797,30798,30799,\n30800,30801,30802,30803,30804,30805,30806,30807,30808,30809,30810,30811,\n30812,30813,30814,30815,30816,30817,30818,30819,30820,30821,30822,30823,\n30824,30825,30826,30827,30828,30829,30830,30831,30832,30833,30834,30835,\n30836,30837,30838,30839,30840,30841,30842,30843,30844,30845,30846,30847,\n30848,30849,30850,30851,30852,30853,30854,30855,30856,30857,30858,30859,\n30860,30861,30862,30863,30864,30865,30866,30867,30868,30869,30870,30871,\n30872,30873,30874,30875,30876,30877,30878,30879,30880,30881,30882,30883,\n30884,30885,30886,30887,30888,30889,30890,30891,30892,30893,30894,30895,\n30896,30897,30898,30899,30900,30901,30902,30903,30904,30905,30906,30907,\n30908,30909,30910,30911,30912,30913,30914,30915,30916,30917,30918,30919,\n30920,30921,30922,30923,30924,30925,30926,30927,30928,30929,30930,30931,\n30932,30933,30934,30935,30936,30937,30938,30939,30940,30941,30942,30943,\n30944,30945,30946,30947,30948,30949,30950,30951,30952,30953,30954,30955,\n30956,30957,30958,30959,30960,30961,30962,30963,30964,30965,30966,30967,\n30968,30969,30970,30971,30972,30973,30974,30975,30976,30977,30978,30979,\n30980,30981,30982,30983,30984,30985,30986,30987,30988,30989,30990,30991,\n30992,30993,30994,30995,30996,30997,30998,30999,31000,31001,31002,31003,\n31004,31005,31006,31007,31008,31009,31010,31011,31012,31013,31014,31015,\n31016,31017,31018,31019,31020,31021,31022,31023,31024,31025,31026,31027,\n31028,31029,31030,31031,31032,31033,31034,31035,31036,31037,31038,31039,\n31040,31041,31042,31043,31044,31045,31046,31047,31048,31049,31050,31051,\n31052,31053,31054,31055,31056,31057,31058,31059,31060,31061,31062,31063,\n31064,31065,31066,31067,31068,31069,31070,31071,31072,31073,31074,31075,\n31076,31077,31078,31079,31080,31081,31082,31083,31084,31085,31086,31087,\n31088,31089,31090,31091,31092,31093,31094,31095,31096,31097,31098,31099,\n31100,31101,31102,31103,31104,31105,31106,31107,31108,31109,31110,31111,\n31112,31113,31114,31115,31116,31117,31118,31119,31120,31121,31122,31123,\n31124,31125,31126,31127,31128,31129,31130,31131,31132,31133,31134,31135,\n31136,31137,31138,31139,31140,31141,31142,31143,31144,31145,31146,31147,\n31148,31149,31150,31151,31152,31153,31154,31155,31156,31157,31158,31159,\n31160,31161,31162,31163,31164,31165,31166,31167,31168,31169,31170,31171,\n31172,31173,31174,31175,31176,31177,31178,31179,31180,31181,31182,31183,\n31184,31185,31186,31187,31188,31189,31190,31191,31192,31193,31194,31195,\n31196,31197,31198,31199,31200,31201,31202,31203,31204,31205,31206,31207,\n31208,31209,31210,31211,31212,31213,31214,31215,31216,31217,31218,31219,\n31220,31221,31222,31223,31224,31225,31226,31227,31228,31229,31230,31231,\n31232,31233,31234,31235,31236,31237,31238,31239,31240,31241,31242,31243,\n31244,31245,31246,31247,31248,31249,31250,31251,31252,31253,31254,31255,\n31256,31257,31258,31259,31260,31261,31262,31263,31264,31265,31266,31267,\n31268,31269,31270,31271,31272,31273,31274,31275,31276,31277,31278,31279,\n31280,31281,31282,31283,31284,31285,31286,31287,31288,31289,31290,31291,\n31292,31293,31294,31295,31296,31297,31298,31299,31300,31301,31302,31303,\n31304,31305,31306,31307,31308,31309,31310,31311,31312,31313,31314,31315,\n31316,31317,31318,31319,31320,31321,31322,31323,31324,31325,31326,31327,\n31328,31329,31330,31331,31332,31333,31334,31335,31336,31337,31338,31339,\n31340,31341,31342,31343,31344,31345,31346,31347,31348,31349,31350,31351,\n31352,31353,31354,31355,31356,31357,31358,31359,31360,31361,31362,31363,\n31364,31365,31366,31367,31368,31369,31370,31371,31372,31373,31374,31375,\n31376,31377,31378,31379,31380,31381,31382,31383,31384,31385,31386,31387,\n31388,31389,31390,31391,31392,31393,31394,31395,31396,31397,31398,31399,\n31400,31401,31402,31403,31404,31405,31406,31407,31408,31409,31410,31411,\n31412,31413,31414,31415,31416,31417,31418,31419,31420,31421,31422,31423,\n31424,31425,31426,31427,31428,31429,31430,31431,31432,31433,31434,31435,\n31436,31437,31438,31439,31440,31441,31442,31443,31444,31445,31446,31447,\n31448,31449,31450,31451,31452,31453,31454,31455,31456,31457,31458,31459,\n31460,31461,31462,31463,31464,31465,31466,31467,31468,31469,31470,31471,\n31472,31473,31474,31475,31476,31477,31478,31479,31480,31481,31482,31483,\n31484,31485,31486,31487,31488,31489,31490,31491,31492,31493,31494,31495,\n31496,31497,31498,31499,31500,31501,31502,31503,31504,31505,31506,31507,\n31508,31509,31510,31511,31512,31513,31514,31515,31516,31517,31518,31519,\n31520,31521,31522,31523,31524,31525,31526,31527,31528,31529,31530,31531,\n31532,31533,31534,31535,31536,31537,31538,31539,31540,31541,31542,31543,\n31544,31545,31546,31547,31548,31549,31550,31551,31552,31553,31554,31555,\n31556,31557,31558,31559,31560,31561,31562,31563,31564,31565,31566,31567,\n31568,31569,31570,31571,31572,31573,31574,31575,31576,31577,31578,31579,\n31580,31581,31582,31583,31584,31585,31586,31587,31588,31589,31590,31591,\n31592,31593,31594,31595,31596,31597,31598,31599,31600,31601,31602,31603,\n31604,31605,31606,31607,31608,31609,31610,31611,31612,31613,31614,31615,\n31616,31617,31618,31619,31620,31621,31622,31623,31624,31625,31626,31627,\n31628,31629,31630,31631,31632,31633,31634,31635,31636,31637,31638,31639,\n31640,31641,31642,31643,31644,31645,31646,31647,31648,31649,31650,31651,\n31652,31653,31654,31655,31656,31657,31658,31659,31660,31661,31662,31663,\n31664,31665,31666,31667,31668,31669,31670,31671,31672,31673,31674,31675,\n31676,31677,31678,31679,31680,31681,31682,31683,31684,31685,31686,31687,\n31688,31689,31690,31691,31692,31693,31694,31695,31696,31697,31698,31699,\n31700,31701,31702,31703,31704,31705,31706,31707,31708,31709,31710,31711,\n31712,31713,31714,31715,31716,31717,31718,31719,31720,31721,31722,31723,\n31724,31725,31726,31727,31728,31729,31730,31731,31732,31733,31734,31735,\n31736,31737,31738,31739,31740,31741,31742,31743,31744,31745,31746,31747,\n31748,31749,31750,31751,31752,31753,31754,31755,31756,31757,31758,31759,\n31760,31761,31762,31763,31764,31765,31766,31767,31768,31769,31770,31771,\n31772,31773,31774,31775,31776,31777,31778,31779,31780,31781,31782,31783,\n31784,31785,31786,31787,31788,31789,31790,31791,31792,31793,31794,31795,\n31796,31797,31798,31799,31800,31801,31802,31803,31804,31805,31806,31807,\n31808,31809,31810,31811,31812,31813,31814,31815,31816,31817,31818,31819,\n31820,31821,31822,31823,31824,31825,31826,31827,31828,31829,31830,31831,\n31832,31833,31834,31835,31836,31837,31838,31839,31840,31841,31842,31843,\n31844,31845,31846,31847,31848,31849,31850,31851,31852,31853,31854,31855,\n31856,31857,31858,31859,31860,31861,31862,31863,31864,31865,31866,31867,\n31868,31869,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879,\n31880,31881,31882,31883,31884,31885,31886,31887,31888,31889,31890,31891,\n31892,31893,31894,31895,31896,31897,31898,31899,31900,31901,31902,31903,\n31904,31905,31906,31907,31908,31909,31910,31911,31912,31913,31914,31915,\n31916,31917,31918,31919,31920,31921,31922,31923,31924,31925,31926,31927,\n31928,31929,31930,31931,31932,31933,31934,31935,31936,31937,31938,31939,\n31940,31941,31942,31943,31944,31945,31946,31947,31948,31949,31950,31951,\n31952,31953,31954,31955,31956,31957,31958,31959,31960,31961,31962,31963,\n31964,31965,31966,31967,31968,31969,31970,31971,31972,31973,31974,31975,\n31976,31977,31978,31979,31980,31981,31982,31983,31984,31985,31986,31987,\n31988,31989,31990,31991,31992,31993,31994,31995,31996,31997,31998,31999,\n32000,32001,32002,32003,32004,32005,32006,32007,32008,32009,32010,32011,\n32012,32013,32014,32015,32016,32017,32018,32019,32020,32021,32022,32023,\n32024,32025,32026,32027,32028,32029,32030,32031,32032,32033,32034,32035,\n32036,32037,32038,32039,32040,32041,32042,32043,32044,32045,32046,32047,\n32048,32049,32050,32051,32052,32053,32054,32055,32056,32057,32058,32059,\n32060,32061,32062,32063,32064,32065,32066,32067,32068,32069,32070,32071,\n32072,32073,32074,32075,32076,32077,32078,32079,32080,32081,32082,32083,\n32084,32085,32086,32087,32088,32089,32090,32091,32092,32093,32094,32095,\n32096,32097,32098,32099,32100,32101,32102,32103,32104,32105,32106,32107,\n32108,32109,32110,32111,32112,32113,32114,32115,32116,32117,32118,32119,\n32120,32121,32122,32123,32124,32125,32126,32127,32128,32129,32130,32131,\n32132,32133,32134,32135,32136,32137,32138,32139,32140,32141,32142,32143,\n32144,32145,32146,32147,32148,32149,32150,32151,32152,32153,32154,32155,\n32156,32157,32158,32159,32160,32161,32162,32163,32164,32165,32166,32167,\n32168,32169,32170,32171,32172,32173,32174,32175,32176,32177,32178,32179,\n32180,32181,32182,32183,32184,32185,32186,32187,32188,32189,32190,32191,\n32192,32193,32194,32195,32196,32197,32198,32199,32200,32201,32202,32203,\n32204,32205,32206,32207,32208,32209,32210,32211,32212,32213,32214,32215,\n32216,32217,32218,32219,32220,32221,32222,32223,32224,32225,32226,32227,\n32228,32229,32230,32231,32232,32233,32234,32235,32236,32237,32238,32239,\n32240,32241,32242,32243,32244,32245,32246,32247,32248,32249,32250,32251,\n32252,32253,32254,32255,32256,32257,32258,32259,32260,32261,32262,32263,\n32264,32265,32266,32267,32268,32269,32270,32271,32272,32273,32274,32275,\n32276,32277,32278,32279,32280,32281,32282,32283,32284,32285,32286,32287,\n32288,32289,32290,32291,32292,32293,32294,32295,32296,32297,32298,32299,\n32300,32301,32302,32303,32304,32305,32306,32307,32308,32309,32310,32311,\n32312,32313,32314,32315,32316,32317,32318,32319,32320,32321,32322,32323,\n32324,32325,32326,32327,32328,32329,32330,32331,32332,32333,32334,32335,\n32336,32337,32338,32339,32340,32341,32342,32343,32344,32345,32346,32347,\n32348,32349,32350,32351,32352,32353,32354,32355,32356,32357,32358,32359,\n32360,32361,32362,32363,32364,32365,32366,32367,32368,32369,32370,32371,\n32372,32373,32374,32375,32376,32377,32378,32379,32380,32381,32382,32383,\n32384,32385,32386,32387,32388,32389,32390,32391,32392,32393,32394,32395,\n32396,32397,32398,32399,32400,32401,32402,32403,32404,32405,32406,32407,\n32408,32409,32410,32411,32412,32413,32414,32415,32416,32417,32418,32419,\n32420,32421,32422,32423,32424,32425,32426,32427,32428,32429,32430,32431,\n32432,32433,32434,32435,32436,32437,32438,32439,32440,32441,32442,32443,\n32444,32445,32446,32447,32448,32449,32450,32451,32452,32453,32454,32455,\n32456,32457,32458,32459,32460,32461,32462,32463,32464,32465,32466,32467,\n32468,32469,32470,32471,32472,32473,32474,32475,32476,32477,32478,32479,\n32480,32481,32482,32483,32484,32485,32486,32487,32488,32489,32490,32491,\n32492,32493,32494,32495,32496,32497,32498,32499,32500,32501,32502,32503,\n32504,32505,32506,32507,32508,32509,32510,32511,32512,32513,32514,32515,\n32516,32517,32518,32519,32520,32521,32522,32523,32524,32525,32526,32527,\n32528,32529,32530,32531,32532,32533,32534,32535,32536,32537,32538,32539,\n32540,32541,32542,32543,32544,32545,32546,32547,32548,32549,32550,32551,\n32552,32553,32554,32555,32556,32557,32558,32559,32560,32561,32562,32563,\n32564,32565,32566,32567,32568,32569,32570,32571,32572,32573,32574,32575,\n32576,32577,32578,32579,32580,32581,32582,32583,32584,32585,32586,32587,\n32588,32589,32590,32591,32592,32593,32594,32595,32596,32597,32598,32599,\n32600,32601,32602,32603,32604,32605,32606,32607,32608,32609,32610,32611,\n32612,32613,32614,32615,32616,32617,32618,32619,32620,32621,32622,32623,\n32624,32625,32626,32627,32628,32629,32630,32631,32632,32633,32634,32635,\n32636,32637,32638,32639,32640,32641,32642,32643,32644,32645,32646,32647,\n32648,32649,32650,32651,32652,32653,32654,32655,32656,32657,32658,32659,\n32660,32661,32662,32663,32664,32665,32666,32667,32668,32669,32670,32671,\n32672,32673,32674,32675,32676,32677,32678,32679,32680,32681,32682,32683,\n32684,32685,32686,32687,32688,32689,32690,32691,32692,32693,32694,32695,\n32696,32697,32698,32699,32700,32701,32702,32703,32704,32705,32706,32707,\n32708,32709,32710,32711,32712,32713,32714,32715,32716,32717,32718,32719,\n32720,32721,32722,32723,32724,32725,32726,32727,32728,32729,32730,32731,\n32732,32733,32734,32735,32736,32737,32738,32739,32740,32741,32742,32743,\n32744,32745,32746,32747,32748,32749,32750,32751,32752,32753,32754,32755,\n32756,32757,32758,32759,32760,32761,32762,32763,32764,32765,32766,32767,\n32768L,32769L,32770L,32771L,32772L,32773L,32774L,32775L,32776L,32777L,\n32778L,32779L,32780L,32781L,32782L,32783L,32784L,32785L,32786L,32787L,\n32788L,32789L,32790L,32791L,32792L,32793L,32794L,32795L,32796L,32797L,\n32798L,32799L,32800L,32801L,32802L,32803L,32804L,32805L,32806L,32807L,\n32808L,32809L,32810L,32811L,32812L,32813L,32814L,32815L,32816L,32817L,\n32818L,32819L,32820L,32821L,32822L,32823L,32824L,32825L,32826L,32827L,\n32828L,32829L,32830L,32831L,32832L,32833L,32834L,32835L,32836L,32837L,\n32838L,32839L,32840L,32841L,32842L,32843L,32844L,32845L,32846L,32847L,\n32848L,32849L,32850L,32851L,32852L,32853L,32854L,32855L,32856L,32857L,\n32858L,32859L,32860L,32861L,32862L,32863L,32864L,32865L,32866L,32867L,\n32868L,32869L,32870L,32871L,32872L,32873L,32874L,32875L,32876L,32877L,\n32878L,32879L,32880L,32881L,32882L,32883L,32884L,32885L,32886L,32887L,\n32888L,32889L,32890L,32891L,32892L,32893L,32894L,32895L,32896L,32897L,\n32898L,32899L,32900L,32901L,32902L,32903L,32904L,32905L,32906L,32907L,\n32908L,32909L,32910L,32911L,32912L,32913L,32914L,32915L,32916L,32917L,\n32918L,32919L,32920L,32921L,32922L,32923L,32924L,32925L,32926L,32927L,\n32928L,32929L,32930L,32931L,32932L,32933L,32934L,32935L,32936L,32937L,\n32938L,32939L,32940L,32941L,32942L,32943L,32944L,32945L,32946L,32947L,\n32948L,32949L,32950L,32951L,32952L,32953L,32954L,32955L,32956L,32957L,\n32958L,32959L,32960L,32961L,32962L,32963L,32964L,32965L,32966L,32967L,\n32968L,32969L,32970L,32971L,32972L,32973L,32974L,32975L,32976L,32977L,\n32978L,32979L,32980L,32981L,32982L,32983L,32984L,32985L,32986L,32987L,\n32988L,32989L,32990L,32991L,32992L,32993L,32994L,32995L,32996L,32997L,\n32998L,32999L,33000L,33001L,33002L,33003L,33004L,33005L,33006L,33007L,\n33008L,33009L,33010L,33011L,33012L,33013L,33014L,33015L,33016L,33017L,\n33018L,33019L,33020L,33021L,33022L,33023L,33024L,33025L,33026L,33027L,\n33028L,33029L,33030L,33031L,33032L,33033L,33034L,33035L,33036L,33037L,\n33038L,33039L,33040L,33041L,33042L,33043L,33044L,33045L,33046L,33047L,\n33048L,33049L,33050L,33051L,33052L,33053L,33054L,33055L,33056L,33057L,\n33058L,33059L,33060L,33061L,33062L,33063L,33064L,33065L,33066L,33067L,\n33068L,33069L,33070L,33071L,33072L,33073L,33074L,33075L,33076L,33077L,\n33078L,33079L,33080L,33081L,33082L,33083L,33084L,33085L,33086L,33087L,\n33088L,33089L,33090L,33091L,33092L,33093L,33094L,33095L,33096L,33097L,\n33098L,33099L,33100L,33101L,33102L,33103L,33104L,33105L,33106L,33107L,\n33108L,33109L,33110L,33111L,33112L,33113L,33114L,33115L,33116L,33117L,\n33118L,33119L,33120L,33121L,33122L,33123L,33124L,33125L,33126L,33127L,\n33128L,33129L,33130L,33131L,33132L,33133L,33134L,33135L,33136L,33137L,\n33138L,33139L,33140L,33141L,33142L,33143L,33144L,33145L,33146L,33147L,\n33148L,33149L,33150L,33151L,33152L,33153L,33154L,33155L,33156L,33157L,\n33158L,33159L,33160L,33161L,33162L,33163L,33164L,33165L,33166L,33167L,\n33168L,33169L,33170L,33171L,33172L,33173L,33174L,33175L,33176L,33177L,\n33178L,33179L,33180L,33181L,33182L,33183L,33184L,33185L,33186L,33187L,\n33188L,33189L,33190L,33191L,33192L,33193L,33194L,33195L,33196L,33197L,\n33198L,33199L,33200L,33201L,33202L,33203L,33204L,33205L,33206L,33207L,\n33208L,33209L,33210L,33211L,33212L,33213L,33214L,33215L,33216L,33217L,\n33218L,33219L,33220L,33221L,33222L,33223L,33224L,33225L,33226L,33227L,\n33228L,33229L,33230L,33231L,33232L,33233L,33234L,33235L,33236L,33237L,\n33238L,33239L,33240L,33241L,33242L,33243L,33244L,33245L,33246L,33247L,\n33248L,33249L,33250L,33251L,33252L,33253L,33254L,33255L,33256L,33257L,\n33258L,33259L,33260L,33261L,33262L,33263L,33264L,33265L,33266L,33267L,\n33268L,33269L,33270L,33271L,33272L,33273L,33274L,33275L,33276L,33277L,\n33278L,33279L,33280L,33281L,33282L,33283L,33284L,33285L,33286L,33287L,\n33288L,33289L,33290L,33291L,33292L,33293L,33294L,33295L,33296L,33297L,\n33298L,33299L,33300L,33301L,33302L,33303L,33304L,33305L,33306L,33307L,\n33308L,33309L,33310L,33311L,33312L,33313L,33314L,33315L,33316L,33317L,\n33318L,33319L,33320L,33321L,33322L,33323L,33324L,33325L,33326L,33327L,\n33328L,33329L,33330L,33331L,33332L,33333L,33334L,33335L,33336L,33337L,\n33338L,33339L,33340L,33341L,33342L,33343L,33344L,33345L,33346L,33347L,\n33348L,33349L,33350L,33351L,33352L,33353L,33354L,33355L,33356L,33357L,\n33358L,33359L,33360L,33361L,33362L,33363L,33364L,33365L,33366L,33367L,\n33368L,33369L,33370L,33371L,33372L,33373L,33374L,33375L,33376L,33377L,\n33378L,33379L,33380L,33381L,33382L,33383L,33384L,33385L,33386L,33387L,\n33388L,33389L,33390L,33391L,33392L,33393L,33394L,33395L,33396L,33397L,\n33398L,33399L,33400L,33401L,33402L,33403L,33404L,33405L,33406L,33407L,\n33408L,33409L,33410L,33411L,33412L,33413L,33414L,33415L,33416L,33417L,\n33418L,33419L,33420L,33421L,33422L,33423L,33424L,33425L,33426L,33427L,\n33428L,33429L,33430L,33431L,33432L,33433L,33434L,33435L,33436L,33437L,\n33438L,33439L,33440L,33441L,33442L,33443L,33444L,33445L,33446L,33447L,\n33448L,33449L,33450L,33451L,33452L,33453L,33454L,33455L,33456L,33457L,\n33458L,33459L,33460L,33461L,33462L,33463L,33464L,33465L,33466L,33467L,\n33468L,33469L,33470L,33471L,33472L,33473L,33474L,33475L,33476L,33477L,\n33478L,33479L,33480L,33481L,33482L,33483L,33484L,33485L,33486L,33487L,\n33488L,33489L,33490L,33491L,33492L,33493L,33494L,33495L,33496L,33497L,\n33498L,33499L,33500L,33501L,33502L,33503L,33504L,33505L,33506L,33507L,\n33508L,33509L,33510L,33511L,33512L,33513L,33514L,33515L,33516L,33517L,\n33518L,33519L,33520L,33521L,33522L,33523L,33524L,33525L,33526L,33527L,\n33528L,33529L,33530L,33531L,33532L,33533L,33534L,33535L,33536L,33537L,\n33538L,33539L,33540L,33541L,33542L,33543L,33544L,33545L,33546L,33547L,\n33548L,33549L,33550L,33551L,33552L,33553L,33554L,33555L,33556L,33557L,\n33558L,33559L,33560L,33561L,33562L,33563L,33564L,33565L,33566L,33567L,\n33568L,33569L,33570L,33571L,33572L,33573L,33574L,33575L,33576L,33577L,\n33578L,33579L,33580L,33581L,33582L,33583L,33584L,33585L,33586L,33587L,\n33588L,33589L,33590L,33591L,33592L,33593L,33594L,33595L,33596L,33597L,\n33598L,33599L,33600L,33601L,33602L,33603L,33604L,33605L,33606L,33607L,\n33608L,33609L,33610L,33611L,33612L,33613L,33614L,33615L,33616L,33617L,\n33618L,33619L,33620L,33621L,33622L,33623L,33624L,33625L,33626L,33627L,\n33628L,33629L,33630L,33631L,33632L,33633L,33634L,33635L,33636L,33637L,\n33638L,33639L,33640L,33641L,33642L,33643L,33644L,33645L,33646L,33647L,\n33648L,33649L,33650L,33651L,33652L,33653L,33654L,33655L,33656L,33657L,\n33658L,33659L,33660L,33661L,33662L,33663L,33664L,33665L,33666L,33667L,\n33668L,33669L,33670L,33671L,33672L,33673L,33674L,33675L,33676L,33677L,\n33678L,33679L,33680L,33681L,33682L,33683L,33684L,33685L,33686L,33687L,\n33688L,33689L,33690L,33691L,33692L,33693L,33694L,33695L,33696L,33697L,\n33698L,33699L,33700L,33701L,33702L,33703L,33704L,33705L,33706L,33707L,\n33708L,33709L,33710L,33711L,33712L,33713L,33714L,33715L,33716L,33717L,\n33718L,33719L,33720L,33721L,33722L,33723L,33724L,33725L,33726L,33727L,\n33728L,33729L,33730L,33731L,33732L,33733L,33734L,33735L,33736L,33737L,\n33738L,33739L,33740L,33741L,33742L,33743L,33744L,33745L,33746L,33747L,\n33748L,33749L,33750L,33751L,33752L,33753L,33754L,33755L,33756L,33757L,\n33758L,33759L,33760L,33761L,33762L,33763L,33764L,33765L,33766L,33767L,\n33768L,33769L,33770L,33771L,33772L,33773L,33774L,33775L,33776L,33777L,\n33778L,33779L,33780L,33781L,33782L,33783L,33784L,33785L,33786L,33787L,\n33788L,33789L,33790L,33791L,33792L,33793L,33794L,33795L,33796L,33797L,\n33798L,33799L,33800L,33801L,33802L,33803L,33804L,33805L,33806L,33807L,\n33808L,33809L,33810L,33811L,33812L,33813L,33814L,33815L,33816L,33817L,\n33818L,33819L,33820L,33821L,33822L,33823L,33824L,33825L,33826L,33827L,\n33828L,33829L,33830L,33831L,33832L,33833L,33834L,33835L,33836L,33837L,\n33838L,33839L,33840L,33841L,33842L,33843L,33844L,33845L,33846L,33847L,\n33848L,33849L,33850L,33851L,33852L,33853L,33854L,33855L,33856L,33857L,\n33858L,33859L,33860L,33861L,33862L,33863L,33864L,33865L,33866L,33867L,\n33868L,33869L,33870L,33871L,33872L,33873L,33874L,33875L,33876L,33877L,\n33878L,33879L,33880L,33881L,33882L,33883L,33884L,33885L,33886L,33887L,\n33888L,33889L,33890L,33891L,33892L,33893L,33894L,33895L,33896L,33897L,\n33898L,33899L,33900L,33901L,33902L,33903L,33904L,33905L,33906L,33907L,\n33908L,33909L,33910L,33911L,33912L,33913L,33914L,33915L,33916L,33917L,\n33918L,33919L,33920L,33921L,33922L,33923L,33924L,33925L,33926L,33927L,\n33928L,33929L,33930L,33931L,33932L,33933L,33934L,33935L,33936L,33937L,\n33938L,33939L,33940L,33941L,33942L,33943L,33944L,33945L,33946L,33947L,\n33948L,33949L,33950L,33951L,33952L,33953L,33954L,33955L,33956L,33957L,\n33958L,33959L,33960L,33961L,33962L,33963L,33964L,33965L,33966L,33967L,\n33968L,33969L,33970L,33971L,33972L,33973L,33974L,33975L,33976L,33977L,\n33978L,33979L,33980L,33981L,33982L,33983L,33984L,33985L,33986L,33987L,\n33988L,33989L,33990L,33991L,33992L,33993L,33994L,33995L,33996L,33997L,\n33998L,33999L,34000L,34001L,34002L,34003L,34004L,34005L,34006L,34007L,\n34008L,34009L,34010L,34011L,34012L,34013L,34014L,34015L,34016L,34017L,\n34018L,34019L,34020L,34021L,34022L,34023L,34024L,34025L,34026L,34027L,\n34028L,34029L,34030L,34031L,34032L,34033L,34034L,34035L,34036L,34037L,\n34038L,34039L,34040L,34041L,34042L,34043L,34044L,34045L,34046L,34047L,\n34048L,34049L,34050L,34051L,34052L,34053L,34054L,34055L,34056L,34057L,\n34058L,34059L,34060L,34061L,34062L,34063L,34064L,34065L,34066L,34067L,\n34068L,34069L,34070L,34071L,34072L,34073L,34074L,34075L,34076L,34077L,\n34078L,34079L,34080L,34081L,34082L,34083L,34084L,34085L,34086L,34087L,\n34088L,34089L,34090L,34091L,34092L,34093L,34094L,34095L,34096L,34097L,\n34098L,34099L,34100L,34101L,34102L,34103L,34104L,34105L,34106L,34107L,\n34108L,34109L,34110L,34111L,34112L,34113L,34114L,34115L,34116L,34117L,\n34118L,34119L,34120L,34121L,34122L,34123L,34124L,34125L,34126L,34127L,\n34128L,34129L,34130L,34131L,34132L,34133L,34134L,34135L,34136L,34137L,\n34138L,34139L,34140L,34141L,34142L,34143L,34144L,34145L,34146L,34147L,\n34148L,34149L,34150L,34151L,34152L,34153L,34154L,34155L,34156L,34157L,\n34158L,34159L,34160L,34161L,34162L,34163L,34164L,34165L,34166L,34167L,\n34168L,34169L,34170L,34171L,34172L,34173L,34174L,34175L,34176L,34177L,\n34178L,34179L,34180L,34181L,34182L,34183L,34184L,34185L,34186L,34187L,\n34188L,34189L,34190L,34191L,34192L,34193L,34194L,34195L,34196L,34197L,\n34198L,34199L,34200L,34201L,34202L,34203L,34204L,34205L,34206L,34207L,\n34208L,34209L,34210L,34211L,34212L,34213L,34214L,34215L,34216L,34217L,\n34218L,34219L,34220L,34221L,34222L,34223L,34224L,34225L,34226L,34227L,\n34228L,34229L,34230L,34231L,34232L,34233L,34234L,34235L,34236L,34237L,\n34238L,34239L,34240L,34241L,34242L,34243L,34244L,34245L,34246L,34247L,\n34248L,34249L,34250L,34251L,34252L,34253L,34254L,34255L,34256L,34257L,\n34258L,34259L,34260L,34261L,34262L,34263L,34264L,34265L,34266L,34267L,\n34268L,34269L,34270L,34271L,34272L,34273L,34274L,34275L,34276L,34277L,\n34278L,34279L,34280L,34281L,34282L,34283L,34284L,34285L,34286L,34287L,\n34288L,34289L,34290L,34291L,34292L,34293L,34294L,34295L,34296L,34297L,\n34298L,34299L,34300L,34301L,34302L,34303L,34304L,34305L,34306L,34307L,\n34308L,34309L,34310L,34311L,34312L,34313L,34314L,34315L,34316L,34317L,\n34318L,34319L,34320L,34321L,34322L,34323L,34324L,34325L,34326L,34327L,\n34328L,34329L,34330L,34331L,34332L,34333L,34334L,34335L,34336L,34337L,\n34338L,34339L,34340L,34341L,34342L,34343L,34344L,34345L,34346L,34347L,\n34348L,34349L,34350L,34351L,34352L,34353L,34354L,34355L,34356L,34357L,\n34358L,34359L,34360L,34361L,34362L,34363L,34364L,34365L,34366L,34367L,\n34368L,34369L,34370L,34371L,34372L,34373L,34374L,34375L,34376L,34377L,\n34378L,34379L,34380L,34381L,34382L,34383L,34384L,34385L,34386L,34387L,\n34388L,34389L,34390L,34391L,34392L,34393L,34394L,34395L,34396L,34397L,\n34398L,34399L,34400L,34401L,34402L,34403L,34404L,34405L,34406L,34407L,\n34408L,34409L,34410L,34411L,34412L,34413L,34414L,34415L,34416L,34417L,\n34418L,34419L,34420L,34421L,34422L,34423L,34424L,34425L,34426L,34427L,\n34428L,34429L,34430L,34431L,34432L,34433L,34434L,34435L,34436L,34437L,\n34438L,34439L,34440L,34441L,34442L,34443L,34444L,34445L,34446L,34447L,\n34448L,34449L,34450L,34451L,34452L,34453L,34454L,34455L,34456L,34457L,\n34458L,34459L,34460L,34461L,34462L,34463L,34464L,34465L,34466L,34467L,\n34468L,34469L,34470L,34471L,34472L,34473L,34474L,34475L,34476L,34477L,\n34478L,34479L,34480L,34481L,34482L,34483L,34484L,34485L,34486L,34487L,\n34488L,34489L,34490L,34491L,34492L,34493L,34494L,34495L,34496L,34497L,\n34498L,34499L,34500L,34501L,34502L,34503L,34504L,34505L,34506L,34507L,\n34508L,34509L,34510L,34511L,34512L,34513L,34514L,34515L,34516L,34517L,\n34518L,34519L,34520L,34521L,34522L,34523L,34524L,34525L,34526L,34527L,\n34528L,34529L,34530L,34531L,34532L,34533L,34534L,34535L,34536L,34537L,\n34538L,34539L,34540L,34541L,34542L,34543L,34544L,34545L,34546L,34547L,\n34548L,34549L,34550L,34551L,34552L,34553L,34554L,34555L,34556L,34557L,\n34558L,34559L,34560L,34561L,34562L,34563L,34564L,34565L,34566L,34567L,\n34568L,34569L,34570L,34571L,34572L,34573L,34574L,34575L,34576L,34577L,\n34578L,34579L,34580L,34581L,34582L,34583L,34584L,34585L,34586L,34587L,\n34588L,34589L,34590L,34591L,34592L,34593L,34594L,34595L,34596L,34597L,\n34598L,34599L,34600L,34601L,34602L,34603L,34604L,34605L,34606L,34607L,\n34608L,34609L,34610L,34611L,34612L,34613L,34614L,34615L,34616L,34617L,\n34618L,34619L,34620L,34621L,34622L,34623L,34624L,34625L,34626L,34627L,\n34628L,34629L,34630L,34631L,34632L,34633L,34634L,34635L,34636L,34637L,\n34638L,34639L,34640L,34641L,34642L,34643L,34644L,34645L,34646L,34647L,\n34648L,34649L,34650L,34651L,34652L,34653L,34654L,34655L,34656L,34657L,\n34658L,34659L,34660L,34661L,34662L,34663L,34664L,34665L,34666L,34667L,\n34668L,34669L,34670L,34671L,34672L,34673L,34674L,34675L,34676L,34677L,\n34678L,34679L,34680L,34681L,34682L,34683L,34684L,34685L,34686L,34687L,\n34688L,34689L,34690L,34691L,34692L,34693L,34694L,34695L,34696L,34697L,\n34698L,34699L,34700L,34701L,34702L,34703L,34704L,34705L,34706L,34707L,\n34708L,34709L,34710L,34711L,34712L,34713L,34714L,34715L,34716L,34717L,\n34718L,34719L,34720L,34721L,34722L,34723L,34724L,34725L,34726L,34727L,\n34728L,34729L,34730L,34731L,34732L,34733L,34734L,34735L,34736L,34737L,\n34738L,34739L,34740L,34741L,34742L,34743L,34744L,34745L,34746L,34747L,\n34748L,34749L,34750L,34751L,34752L,34753L,34754L,34755L,34756L,34757L,\n34758L,34759L,34760L,34761L,34762L,34763L,34764L,34765L,34766L,34767L,\n34768L,34769L,34770L,34771L,34772L,34773L,34774L,34775L,34776L,34777L,\n34778L,34779L,34780L,34781L,34782L,34783L,34784L,34785L,34786L,34787L,\n34788L,34789L,34790L,34791L,34792L,34793L,34794L,34795L,34796L,34797L,\n34798L,34799L,34800L,34801L,34802L,34803L,34804L,34805L,34806L,34807L,\n34808L,34809L,34810L,34811L,34812L,34813L,34814L,34815L,34816L,34817L,\n34818L,34819L,34820L,34821L,34822L,34823L,34824L,34825L,34826L,34827L,\n34828L,34829L,34830L,34831L,34832L,34833L,34834L,34835L,34836L,34837L,\n34838L,34839L,34840L,34841L,34842L,34843L,34844L,34845L,34846L,34847L,\n34848L,34849L,34850L,34851L,34852L,34853L,34854L,34855L,34856L,34857L,\n34858L,34859L,34860L,34861L,34862L,34863L,34864L,34865L,34866L,34867L,\n34868L,34869L,34870L,34871L,34872L,34873L,34874L,34875L,34876L,34877L,\n34878L,34879L,34880L,34881L,34882L,34883L,34884L,34885L,34886L,34887L,\n34888L,34889L,34890L,34891L,34892L,34893L,34894L,34895L,34896L,34897L,\n34898L,34899L,34900L,34901L,34902L,34903L,34904L,34905L,34906L,34907L,\n34908L,34909L,34910L,34911L,34912L,34913L,34914L,34915L,34916L,34917L,\n34918L,34919L,34920L,34921L,34922L,34923L,34924L,34925L,34926L,34927L,\n34928L,34929L,34930L,34931L,34932L,34933L,34934L,34935L,34936L,34937L,\n34938L,34939L,34940L,34941L,34942L,34943L,34944L,34945L,34946L,34947L,\n34948L,34949L,34950L,34951L,34952L,34953L,34954L,34955L,34956L,34957L,\n34958L,34959L,34960L,34961L,34962L,34963L,34964L,34965L,34966L,34967L,\n34968L,34969L,34970L,34971L,34972L,34973L,34974L,34975L,34976L,34977L,\n34978L,34979L,34980L,34981L,34982L,34983L,34984L,34985L,34986L,34987L,\n34988L,34989L,34990L,34991L,34992L,34993L,34994L,34995L,34996L,34997L,\n34998L,34999L,35000L,35001L,35002L,35003L,35004L,35005L,35006L,35007L,\n35008L,35009L,35010L,35011L,35012L,35013L,35014L,35015L,35016L,35017L,\n35018L,35019L,35020L,35021L,35022L,35023L,35024L,35025L,35026L,35027L,\n35028L,35029L,35030L,35031L,35032L,35033L,35034L,35035L,35036L,35037L,\n35038L,35039L,35040L,35041L,35042L,35043L,35044L,35045L,35046L,35047L,\n35048L,35049L,35050L,35051L,35052L,35053L,35054L,35055L,35056L,35057L,\n35058L,35059L,35060L,35061L,35062L,35063L,35064L,35065L,35066L,35067L,\n35068L,35069L,35070L,35071L,35072L,35073L,35074L,35075L,35076L,35077L,\n35078L,35079L,35080L,35081L,35082L,35083L,35084L,35085L,35086L,35087L,\n35088L,35089L,35090L,35091L,35092L,35093L,35094L,35095L,35096L,35097L,\n35098L,35099L,35100L,35101L,35102L,35103L,35104L,35105L,35106L,35107L,\n35108L,35109L,35110L,35111L,35112L,35113L,35114L,35115L,35116L,35117L,\n35118L,35119L,35120L,35121L,35122L,35123L,35124L,35125L,35126L,35127L,\n35128L,35129L,35130L,35131L,35132L,35133L,35134L,35135L,35136L,35137L,\n35138L,35139L,35140L,35141L,35142L,35143L,35144L,35145L,35146L,35147L,\n35148L,35149L,35150L,35151L,35152L,35153L,35154L,35155L,35156L,35157L,\n35158L,35159L,35160L,35161L,35162L,35163L,35164L,35165L,35166L,35167L,\n35168L,35169L,35170L,35171L,35172L,35173L,35174L,35175L,35176L,35177L,\n35178L,35179L,35180L,35181L,35182L,35183L,35184L,35185L,35186L,35187L,\n35188L,35189L,35190L,35191L,35192L,35193L,35194L,35195L,35196L,35197L,\n35198L,35199L,35200L,35201L,35202L,35203L,35204L,35205L,35206L,35207L,\n35208L,35209L,35210L,35211L,35212L,35213L,35214L,35215L,35216L,35217L,\n35218L,35219L,35220L,35221L,35222L,35223L,35224L,35225L,35226L,35227L,\n35228L,35229L,35230L,35231L,35232L,35233L,35234L,35235L,35236L,35237L,\n35238L,35239L,35240L,35241L,35242L,35243L,35244L,35245L,35246L,35247L,\n35248L,35249L,35250L,35251L,35252L,35253L,35254L,35255L,35256L,35257L,\n35258L,35259L,35260L,35261L,35262L,35263L,35264L,35265L,35266L,35267L,\n35268L,35269L,35270L,35271L,35272L,35273L,35274L,35275L,35276L,35277L,\n35278L,35279L,35280L,35281L,35282L,35283L,35284L,35285L,35286L,35287L,\n35288L,35289L,35290L,35291L,35292L,35293L,35294L,35295L,35296L,35297L,\n35298L,35299L,35300L,35301L,35302L,35303L,35304L,35305L,35306L,35307L,\n35308L,35309L,35310L,35311L,35312L,35313L,35314L,35315L,35316L,35317L,\n35318L,35319L,35320L,35321L,35322L,35323L,35324L,35325L,35326L,35327L,\n35328L,35329L,35330L,35331L,35332L,35333L,35334L,35335L,35336L,35337L,\n35338L,35339L,35340L,35341L,35342L,35343L,35344L,35345L,35346L,35347L,\n35348L,35349L,35350L,35351L,35352L,35353L,35354L,35355L,35356L,35357L,\n35358L,35359L,35360L,35361L,35362L,35363L,35364L,35365L,35366L,35367L,\n35368L,35369L,35370L,35371L,35372L,35373L,35374L,35375L,35376L,35377L,\n35378L,35379L,35380L,35381L,35382L,35383L,35384L,35385L,35386L,35387L,\n35388L,35389L,35390L,35391L,35392L,35393L,35394L,35395L,35396L,35397L,\n35398L,35399L,35400L,35401L,35402L,35403L,35404L,35405L,35406L,35407L,\n35408L,35409L,35410L,35411L,35412L,35413L,35414L,35415L,35416L,35417L,\n35418L,35419L,35420L,35421L,35422L,35423L,35424L,35425L,35426L,35427L,\n35428L,35429L,35430L,35431L,35432L,35433L,35434L,35435L,35436L,35437L,\n35438L,35439L,35440L,35441L,35442L,35443L,35444L,35445L,35446L,35447L,\n35448L,35449L,35450L,35451L,35452L,35453L,35454L,35455L,35456L,35457L,\n35458L,35459L,35460L,35461L,35462L,35463L,35464L,35465L,35466L,35467L,\n35468L,35469L,35470L,35471L,35472L,35473L,35474L,35475L,35476L,35477L,\n35478L,35479L,35480L,35481L,35482L,35483L,35484L,35485L,35486L,35487L,\n35488L,35489L,35490L,35491L,35492L,35493L,35494L,35495L,35496L,35497L,\n35498L,35499L,35500L,35501L,35502L,35503L,35504L,35505L,35506L,35507L,\n35508L,35509L,35510L,35511L,35512L,35513L,35514L,35515L,35516L,35517L,\n35518L,35519L,35520L,35521L,35522L,35523L,35524L,35525L,35526L,35527L,\n35528L,35529L,35530L,35531L,35532L,35533L,35534L,35535L,35536L,35537L,\n35538L,35539L,35540L,35541L,35542L,35543L,35544L,35545L,35546L,35547L,\n35548L,35549L,35550L,35551L,35552L,35553L,35554L,35555L,35556L,35557L,\n35558L,35559L,35560L,35561L,35562L,35563L,35564L,35565L,35566L,35567L,\n35568L,35569L,35570L,35571L,35572L,35573L,35574L,35575L,35576L,35577L,\n35578L,35579L,35580L,35581L,35582L,35583L,35584L,35585L,35586L,35587L,\n35588L,35589L,35590L,35591L,35592L,35593L,35594L,35595L,35596L,35597L,\n35598L,35599L,35600L,35601L,35602L,35603L,35604L,35605L,35606L,35607L,\n35608L,35609L,35610L,35611L,35612L,35613L,35614L,35615L,35616L,35617L,\n35618L,35619L,35620L,35621L,35622L,35623L,35624L,35625L,35626L,35627L,\n35628L,35629L,35630L,35631L,35632L,35633L,35634L,35635L,35636L,35637L,\n35638L,35639L,35640L,35641L,35642L,35643L,35644L,35645L,35646L,35647L,\n35648L,35649L,35650L,35651L,35652L,35653L,35654L,35655L,35656L,35657L,\n35658L,35659L,35660L,35661L,35662L,35663L,35664L,35665L,35666L,35667L,\n35668L,35669L,35670L,35671L,35672L,35673L,35674L,35675L,35676L,35677L,\n35678L,35679L,35680L,35681L,35682L,35683L,35684L,35685L,35686L,35687L,\n35688L,35689L,35690L,35691L,35692L,35693L,35694L,35695L,35696L,35697L,\n35698L,35699L,35700L,35701L,35702L,35703L,35704L,35705L,35706L,35707L,\n35708L,35709L,35710L,35711L,35712L,35713L,35714L,35715L,35716L,35717L,\n35718L,35719L,35720L,35721L,35722L,35723L,35724L,35725L,35726L,35727L,\n35728L,35729L,35730L,35731L,35732L,35733L,35734L,35735L,35736L,35737L,\n35738L,35739L,35740L,35741L,35742L,35743L,35744L,35745L,35746L,35747L,\n35748L,35749L,35750L,35751L,35752L,35753L,35754L,35755L,35756L,35757L,\n35758L,35759L,35760L,35761L,35762L,35763L,35764L,35765L,35766L,35767L,\n35768L,35769L,35770L,35771L,35772L,35773L,35774L,35775L,35776L,35777L,\n35778L,35779L,35780L,35781L,35782L,35783L,35784L,35785L,35786L,35787L,\n35788L,35789L,35790L,35791L,35792L,35793L,35794L,35795L,35796L,35797L,\n35798L,35799L,35800L,35801L,35802L,35803L,35804L,35805L,35806L,35807L,\n35808L,35809L,35810L,35811L,35812L,35813L,35814L,35815L,35816L,35817L,\n35818L,35819L,35820L,35821L,35822L,35823L,35824L,35825L,35826L,35827L,\n35828L,35829L,35830L,35831L,35832L,35833L,35834L,35835L,35836L,35837L,\n35838L,35839L,35840L,35841L,35842L,35843L,35844L,35845L,35846L,35847L,\n35848L,35849L,35850L,35851L,35852L,35853L,35854L,35855L,35856L,35857L,\n35858L,35859L,35860L,35861L,35862L,35863L,35864L,35865L,35866L,35867L,\n35868L,35869L,35870L,35871L,35872L,35873L,35874L,35875L,35876L,35877L,\n35878L,35879L,35880L,35881L,35882L,35883L,35884L,35885L,35886L,35887L,\n35888L,35889L,35890L,35891L,35892L,35893L,35894L,35895L,35896L,35897L,\n35898L,35899L,35900L,35901L,35902L,35903L,35904L,35905L,35906L,35907L,\n35908L,35909L,35910L,35911L,35912L,35913L,35914L,35915L,35916L,35917L,\n35918L,35919L,35920L,35921L,35922L,35923L,35924L,35925L,35926L,35927L,\n35928L,35929L,35930L,35931L,35932L,35933L,35934L,35935L,35936L,35937L,\n35938L,35939L,35940L,35941L,35942L,35943L,35944L,35945L,35946L,35947L,\n35948L,35949L,35950L,35951L,35952L,35953L,35954L,35955L,35956L,35957L,\n35958L,35959L,35960L,35961L,35962L,35963L,35964L,35965L,35966L,35967L,\n35968L,35969L,35970L,35971L,35972L,35973L,35974L,35975L,35976L,35977L,\n35978L,35979L,35980L,35981L,35982L,35983L,35984L,35985L,35986L,35987L,\n35988L,35989L,35990L,35991L,35992L,35993L,35994L,35995L,35996L,35997L,\n35998L,35999L,36000L,36001L,36002L,36003L,36004L,36005L,36006L,36007L,\n36008L,36009L,36010L,36011L,36012L,36013L,36014L,36015L,36016L,36017L,\n36018L,36019L,36020L,36021L,36022L,36023L,36024L,36025L,36026L,36027L,\n36028L,36029L,36030L,36031L,36032L,36033L,36034L,36035L,36036L,36037L,\n36038L,36039L,36040L,36041L,36042L,36043L,36044L,36045L,36046L,36047L,\n36048L,36049L,36050L,36051L,36052L,36053L,36054L,36055L,36056L,36057L,\n36058L,36059L,36060L,36061L,36062L,36063L,36064L,36065L,36066L,36067L,\n36068L,36069L,36070L,36071L,36072L,36073L,36074L,36075L,36076L,36077L,\n36078L,36079L,36080L,36081L,36082L,36083L,36084L,36085L,36086L,36087L,\n36088L,36089L,36090L,36091L,36092L,36093L,36094L,36095L,36096L,36097L,\n36098L,36099L,36100L,36101L,36102L,36103L,36104L,36105L,36106L,36107L,\n36108L,36109L,36110L,36111L,36112L,36113L,36114L,36115L,36116L,36117L,\n36118L,36119L,36120L,36121L,36122L,36123L,36124L,36125L,36126L,36127L,\n36128L,36129L,36130L,36131L,36132L,36133L,36134L,36135L,36136L,36137L,\n36138L,36139L,36140L,36141L,36142L,36143L,36144L,36145L,36146L,36147L,\n36148L,36149L,36150L,36151L,36152L,36153L,36154L,36155L,36156L,36157L,\n36158L,36159L,36160L,36161L,36162L,36163L,36164L,36165L,36166L,36167L,\n36168L,36169L,36170L,36171L,36172L,36173L,36174L,36175L,36176L,36177L,\n36178L,36179L,36180L,36181L,36182L,36183L,36184L,36185L,36186L,36187L,\n36188L,36189L,36190L,36191L,36192L,36193L,36194L,36195L,36196L,36197L,\n36198L,36199L,36200L,36201L,36202L,36203L,36204L,36205L,36206L,36207L,\n36208L,36209L,36210L,36211L,36212L,36213L,36214L,36215L,36216L,36217L,\n36218L,36219L,36220L,36221L,36222L,36223L,36224L,36225L,36226L,36227L,\n36228L,36229L,36230L,36231L,36232L,36233L,36234L,36235L,36236L,36237L,\n36238L,36239L,36240L,36241L,36242L,36243L,36244L,36245L,36246L,36247L,\n36248L,36249L,36250L,36251L,36252L,36253L,36254L,36255L,36256L,36257L,\n36258L,36259L,36260L,36261L,36262L,36263L,36264L,36265L,36266L,36267L,\n36268L,36269L,36270L,36271L,36272L,36273L,36274L,36275L,36276L,36277L,\n36278L,36279L,36280L,36281L,36282L,36283L,36284L,36285L,36286L,36287L,\n36288L,36289L,36290L,36291L,36292L,36293L,36294L,36295L,36296L,36297L,\n36298L,36299L,36300L,36301L,36302L,36303L,36304L,36305L,36306L,36307L,\n36308L,36309L,36310L,36311L,36312L,36313L,36314L,36315L,36316L,36317L,\n36318L,36319L,36320L,36321L,36322L,36323L,36324L,36325L,36326L,36327L,\n36328L,36329L,36330L,36331L,36332L,36333L,36334L,36335L,36336L,36337L,\n36338L,36339L,36340L,36341L,36342L,36343L,36344L,36345L,36346L,36347L,\n36348L,36349L,36350L,36351L,36352L,36353L,36354L,36355L,36356L,36357L,\n36358L,36359L,36360L,36361L,36362L,36363L,36364L,36365L,36366L,36367L,\n36368L,36369L,36370L,36371L,36372L,36373L,36374L,36375L,36376L,36377L,\n36378L,36379L,36380L,36381L,36382L,36383L,36384L,36385L,36386L,36387L,\n36388L,36389L,36390L,36391L,36392L,36393L,36394L,36395L,36396L,36397L,\n36398L,36399L,36400L,36401L,36402L,36403L,36404L,36405L,36406L,36407L,\n36408L,36409L,36410L,36411L,36412L,36413L,36414L,36415L,36416L,36417L,\n36418L,36419L,36420L,36421L,36422L,36423L,36424L,36425L,36426L,36427L,\n36428L,36429L,36430L,36431L,36432L,36433L,36434L,36435L,36436L,36437L,\n36438L,36439L,36440L,36441L,36442L,36443L,36444L,36445L,36446L,36447L,\n36448L,36449L,36450L,36451L,36452L,36453L,36454L,36455L,36456L,36457L,\n36458L,36459L,36460L,36461L,36462L,36463L,36464L,36465L,36466L,36467L,\n36468L,36469L,36470L,36471L,36472L,36473L,36474L,36475L,36476L,36477L,\n36478L,36479L,36480L,36481L,36482L,36483L,36484L,36485L,36486L,36487L,\n36488L,36489L,36490L,36491L,36492L,36493L,36494L,36495L,36496L,36497L,\n36498L,36499L,36500L,36501L,36502L,36503L,36504L,36505L,36506L,36507L,\n36508L,36509L,36510L,36511L,36512L,36513L,36514L,36515L,36516L,36517L,\n36518L,36519L,36520L,36521L,36522L,36523L,36524L,36525L,36526L,36527L,\n36528L,36529L,36530L,36531L,36532L,36533L,36534L,36535L,36536L,36537L,\n36538L,36539L,36540L,36541L,36542L,36543L,36544L,36545L,36546L,36547L,\n36548L,36549L,36550L,36551L,36552L,36553L,36554L,36555L,36556L,36557L,\n36558L,36559L,36560L,36561L,36562L,36563L,36564L,36565L,36566L,36567L,\n36568L,36569L,36570L,36571L,36572L,36573L,36574L,36575L,36576L,36577L,\n36578L,36579L,36580L,36581L,36582L,36583L,36584L,36585L,36586L,36587L,\n36588L,36589L,36590L,36591L,36592L,36593L,36594L,36595L,36596L,36597L,\n36598L,36599L,36600L,36601L,36602L,36603L,36604L,36605L,36606L,36607L,\n36608L,36609L,36610L,36611L,36612L,36613L,36614L,36615L,36616L,36617L,\n36618L,36619L,36620L,36621L,36622L,36623L,36624L,36625L,36626L,36627L,\n36628L,36629L,36630L,36631L,36632L,36633L,36634L,36635L,36636L,36637L,\n36638L,36639L,36640L,36641L,36642L,36643L,36644L,36645L,36646L,36647L,\n36648L,36649L,36650L,36651L,36652L,36653L,36654L,36655L,36656L,36657L,\n36658L,36659L,36660L,36661L,36662L,36663L,36664L,36665L,36666L,36667L,\n36668L,36669L,36670L,36671L,36672L,36673L,36674L,36675L,36676L,36677L,\n36678L,36679L,36680L,36681L,36682L,36683L,36684L,36685L,36686L,36687L,\n36688L,36689L,36690L,36691L,36692L,36693L,36694L,36695L,36696L,36697L,\n36698L,36699L,36700L,36701L,36702L,36703L,36704L,36705L,36706L,36707L,\n36708L,36709L,36710L,36711L,36712L,36713L,36714L,36715L,36716L,36717L,\n36718L,36719L,36720L,36721L,36722L,36723L,36724L,36725L,36726L,36727L,\n36728L,36729L,36730L,36731L,36732L,36733L,36734L,36735L,36736L,36737L,\n36738L,36739L,36740L,36741L,36742L,36743L,36744L,36745L,36746L,36747L,\n36748L,36749L,36750L,36751L,36752L,36753L,36754L,36755L,36756L,36757L,\n36758L,36759L,36760L,36761L,36762L,36763L,36764L,36765L,36766L,36767L,\n36768L,36769L,36770L,36771L,36772L,36773L,36774L,36775L,36776L,36777L,\n36778L,36779L,36780L,36781L,36782L,36783L,36784L,36785L,36786L,36787L,\n36788L,36789L,36790L,36791L,36792L,36793L,36794L,36795L,36796L,36797L,\n36798L,36799L,36800L,36801L,36802L,36803L,36804L,36805L,36806L,36807L,\n36808L,36809L,36810L,36811L,36812L,36813L,36814L,36815L,36816L,36817L,\n36818L,36819L,36820L,36821L,36822L,36823L,36824L,36825L,36826L,36827L,\n36828L,36829L,36830L,36831L,36832L,36833L,36834L,36835L,36836L,36837L,\n36838L,36839L,36840L,36841L,36842L,36843L,36844L,36845L,36846L,36847L,\n36848L,36849L,36850L,36851L,36852L,36853L,36854L,36855L,36856L,36857L,\n36858L,36859L,36860L,36861L,36862L,36863L,36864L,36865L,36866L,36867L,\n36868L,36869L,36870L,36871L,36872L,36873L,36874L,36875L,36876L,36877L,\n36878L,36879L,36880L,36881L,36882L,36883L,36884L,36885L,36886L,36887L,\n36888L,36889L,36890L,36891L,36892L,36893L,36894L,36895L,36896L,36897L,\n36898L,36899L,36900L,36901L,36902L,36903L,36904L,36905L,36906L,36907L,\n36908L,36909L,36910L,36911L,36912L,36913L,36914L,36915L,36916L,36917L,\n36918L,36919L,36920L,36921L,36922L,36923L,36924L,36925L,36926L,36927L,\n36928L,36929L,36930L,36931L,36932L,36933L,36934L,36935L,36936L,36937L,\n36938L,36939L,36940L,36941L,36942L,36943L,36944L,36945L,36946L,36947L,\n36948L,36949L,36950L,36951L,36952L,36953L,36954L,36955L,36956L,36957L,\n36958L,36959L,36960L,36961L,36962L,36963L,36964L,36965L,36966L,36967L,\n36968L,36969L,36970L,36971L,36972L,36973L,36974L,36975L,36976L,36977L,\n36978L,36979L,36980L,36981L,36982L,36983L,36984L,36985L,36986L,36987L,\n36988L,36989L,36990L,36991L,36992L,36993L,36994L,36995L,36996L,36997L,\n36998L,36999L,37000L,37001L,37002L,37003L,37004L,37005L,37006L,37007L,\n37008L,37009L,37010L,37011L,37012L,37013L,37014L,37015L,37016L,37017L,\n37018L,37019L,37020L,37021L,37022L,37023L,37024L,37025L,37026L,37027L,\n37028L,37029L,37030L,37031L,37032L,37033L,37034L,37035L,37036L,37037L,\n37038L,37039L,37040L,37041L,37042L,37043L,37044L,37045L,37046L,37047L,\n37048L,37049L,37050L,37051L,37052L,37053L,37054L,37055L,37056L,37057L,\n37058L,37059L,37060L,37061L,37062L,37063L,37064L,37065L,37066L,37067L,\n37068L,37069L,37070L,37071L,37072L,37073L,37074L,37075L,37076L,37077L,\n37078L,37079L,37080L,37081L,37082L,37083L,37084L,37085L,37086L,37087L,\n37088L,37089L,37090L,37091L,37092L,37093L,37094L,37095L,37096L,37097L,\n37098L,37099L,37100L,37101L,37102L,37103L,37104L,37105L,37106L,37107L,\n37108L,37109L,37110L,37111L,37112L,37113L,37114L,37115L,37116L,37117L,\n37118L,37119L,37120L,37121L,37122L,37123L,37124L,37125L,37126L,37127L,\n37128L,37129L,37130L,37131L,37132L,37133L,37134L,37135L,37136L,37137L,\n37138L,37139L,37140L,37141L,37142L,37143L,37144L,37145L,37146L,37147L,\n37148L,37149L,37150L,37151L,37152L,37153L,37154L,37155L,37156L,37157L,\n37158L,37159L,37160L,37161L,37162L,37163L,37164L,37165L,37166L,37167L,\n37168L,37169L,37170L,37171L,37172L,37173L,37174L,37175L,37176L,37177L,\n37178L,37179L,37180L,37181L,37182L,37183L,37184L,37185L,37186L,37187L,\n37188L,37189L,37190L,37191L,37192L,37193L,37194L,37195L,37196L,37197L,\n37198L,37199L,37200L,37201L,37202L,37203L,37204L,37205L,37206L,37207L,\n37208L,37209L,37210L,37211L,37212L,37213L,37214L,37215L,37216L,37217L,\n37218L,37219L,37220L,37221L,37222L,37223L,37224L,37225L,37226L,37227L,\n37228L,37229L,37230L,37231L,37232L,37233L,37234L,37235L,37236L,37237L,\n37238L,37239L,37240L,37241L,37242L,37243L,37244L,37245L,37246L,37247L,\n37248L,37249L,37250L,37251L,37252L,37253L,37254L,37255L,37256L,37257L,\n37258L,37259L,37260L,37261L,37262L,37263L,37264L,37265L,37266L,37267L,\n37268L,37269L,37270L,37271L,37272L,37273L,37274L,37275L,37276L,37277L,\n37278L,37279L,37280L,37281L,37282L,37283L,37284L,37285L,37286L,37287L,\n37288L,37289L,37290L,37291L,37292L,37293L,37294L,37295L,37296L,37297L,\n37298L,37299L,37300L,37301L,37302L,37303L,37304L,37305L,37306L,37307L,\n37308L,37309L,37310L,37311L,37312L,37313L,37314L,37315L,37316L,37317L,\n37318L,37319L,37320L,37321L,37322L,37323L,37324L,37325L,37326L,37327L,\n37328L,37329L,37330L,37331L,37332L,37333L,37334L,37335L,37336L,37337L,\n37338L,37339L,37340L,37341L,37342L,37343L,37344L,37345L,37346L,37347L,\n37348L,37349L,37350L,37351L,37352L,37353L,37354L,37355L,37356L,37357L,\n37358L,37359L,37360L,37361L,37362L,37363L,37364L,37365L,37366L,37367L,\n37368L,37369L,37370L,37371L,37372L,37373L,37374L,37375L,37376L,37377L,\n37378L,37379L,37380L,37381L,37382L,37383L,37384L,37385L,37386L,37387L,\n37388L,37389L,37390L,37391L,37392L,37393L,37394L,37395L,37396L,37397L,\n37398L,37399L,37400L,37401L,37402L,37403L,37404L,37405L,37406L,37407L,\n37408L,37409L,37410L,37411L,37412L,37413L,37414L,37415L,37416L,37417L,\n37418L,37419L,37420L,37421L,37422L,37423L,37424L,37425L,37426L,37427L,\n37428L,37429L,37430L,37431L,37432L,37433L,37434L,37435L,37436L,37437L,\n37438L,37439L,37440L,37441L,37442L,37443L,37444L,37445L,37446L,37447L,\n37448L,37449L,37450L,37451L,37452L,37453L,37454L,37455L,37456L,37457L,\n37458L,37459L,37460L,37461L,37462L,37463L,37464L,37465L,37466L,37467L,\n37468L,37469L,37470L,37471L,37472L,37473L,37474L,37475L,37476L,37477L,\n37478L,37479L,37480L,37481L,37482L,37483L,37484L,37485L,37486L,37487L,\n37488L,37489L,37490L,37491L,37492L,37493L,37494L,37495L,37496L,37497L,\n37498L,37499L,37500L,37501L,37502L,37503L,37504L,37505L,37506L,37507L,\n37508L,37509L,37510L,37511L,37512L,37513L,37514L,37515L,37516L,37517L,\n37518L,37519L,37520L,37521L,37522L,37523L,37524L,37525L,37526L,37527L,\n37528L,37529L,37530L,37531L,37532L,37533L,37534L,37535L,37536L,37537L,\n37538L,37539L,37540L,37541L,37542L,37543L,37544L,37545L,37546L,37547L,\n37548L,37549L,37550L,37551L,37552L,37553L,37554L,37555L,37556L,37557L,\n37558L,37559L,37560L,37561L,37562L,37563L,37564L,37565L,37566L,37567L,\n37568L,37569L,37570L,37571L,37572L,37573L,37574L,37575L,37576L,37577L,\n37578L,37579L,37580L,37581L,37582L,37583L,37584L,37585L,37586L,37587L,\n37588L,37589L,37590L,37591L,37592L,37593L,37594L,37595L,37596L,37597L,\n37598L,37599L,37600L,37601L,37602L,37603L,37604L,37605L,37606L,37607L,\n37608L,37609L,37610L,37611L,37612L,37613L,37614L,37615L,37616L,37617L,\n37618L,37619L,37620L,37621L,37622L,37623L,37624L,37625L,37626L,37627L,\n37628L,37629L,37630L,37631L,37632L,37633L,37634L,37635L,37636L,37637L,\n37638L,37639L,37640L,37641L,37642L,37643L,37644L,37645L,37646L,37647L,\n37648L,37649L,37650L,37651L,37652L,37653L,37654L,37655L,37656L,37657L,\n37658L,37659L,37660L,37661L,37662L,37663L,37664L,37665L,37666L,37667L,\n37668L,37669L,37670L,37671L,37672L,37673L,37674L,37675L,37676L,37677L,\n37678L,37679L,37680L,37681L,37682L,37683L,37684L,37685L,37686L,37687L,\n37688L,37689L,37690L,37691L,37692L,37693L,37694L,37695L,37696L,37697L,\n37698L,37699L,37700L,37701L,37702L,37703L,37704L,37705L,37706L,37707L,\n37708L,37709L,37710L,37711L,37712L,37713L,37714L,37715L,37716L,37717L,\n37718L,37719L,37720L,37721L,37722L,37723L,37724L,37725L,37726L,37727L,\n37728L,37729L,37730L,37731L,37732L,37733L,37734L,37735L,37736L,37737L,\n37738L,37739L,37740L,37741L,37742L,37743L,37744L,37745L,37746L,37747L,\n37748L,37749L,37750L,37751L,37752L,37753L,37754L,37755L,37756L,37757L,\n37758L,37759L,37760L,37761L,37762L,37763L,37764L,37765L,37766L,37767L,\n37768L,37769L,37770L,37771L,37772L,37773L,37774L,37775L,37776L,37777L,\n37778L,37779L,37780L,37781L,37782L,37783L,37784L,37785L,37786L,37787L,\n37788L,37789L,37790L,37791L,37792L,37793L,37794L,37795L,37796L,37797L,\n37798L,37799L,37800L,37801L,37802L,37803L,37804L,37805L,37806L,37807L,\n37808L,37809L,37810L,37811L,37812L,37813L,37814L,37815L,37816L,37817L,\n37818L,37819L,37820L,37821L,37822L,37823L,37824L,37825L,37826L,37827L,\n37828L,37829L,37830L,37831L,37832L,37833L,37834L,37835L,37836L,37837L,\n37838L,37839L,37840L,37841L,37842L,37843L,37844L,37845L,37846L,37847L,\n37848L,37849L,37850L,37851L,37852L,37853L,37854L,37855L,37856L,37857L,\n37858L,37859L,37860L,37861L,37862L,37863L,37864L,37865L,37866L,37867L,\n37868L,37869L,37870L,37871L,37872L,37873L,37874L,37875L,37876L,37877L,\n37878L,37879L,37880L,37881L,37882L,37883L,37884L,37885L,37886L,37887L,\n37888L,37889L,37890L,37891L,37892L,37893L,37894L,37895L,37896L,37897L,\n37898L,37899L,37900L,37901L,37902L,37903L,37904L,37905L,37906L,37907L,\n37908L,37909L,37910L,37911L,37912L,37913L,37914L,37915L,37916L,37917L,\n37918L,37919L,37920L,37921L,37922L,37923L,37924L,37925L,37926L,37927L,\n37928L,37929L,37930L,37931L,37932L,37933L,37934L,37935L,37936L,37937L,\n37938L,37939L,37940L,37941L,37942L,37943L,37944L,37945L,37946L,37947L,\n37948L,37949L,37950L,37951L,37952L,37953L,37954L,37955L,37956L,37957L,\n37958L,37959L,37960L,37961L,37962L,37963L,37964L,37965L,37966L,37967L,\n37968L,37969L,37970L,37971L,37972L,37973L,37974L,37975L,37976L,37977L,\n37978L,37979L,37980L,37981L,37982L,37983L,37984L,37985L,37986L,37987L,\n37988L,37989L,37990L,37991L,37992L,37993L,37994L,37995L,37996L,37997L,\n37998L,37999L,38000L,38001L,38002L,38003L,38004L,38005L,38006L,38007L,\n38008L,38009L,38010L,38011L,38012L,38013L,38014L,38015L,38016L,38017L,\n38018L,38019L,38020L,38021L,38022L,38023L,38024L,38025L,38026L,38027L,\n38028L,38029L,38030L,38031L,38032L,38033L,38034L,38035L,38036L,38037L,\n38038L,38039L,38040L,38041L,38042L,38043L,38044L,38045L,38046L,38047L,\n38048L,38049L,38050L,38051L,38052L,38053L,38054L,38055L,38056L,38057L,\n38058L,38059L,38060L,38061L,38062L,38063L,38064L,38065L,38066L,38067L,\n38068L,38069L,38070L,38071L,38072L,38073L,38074L,38075L,38076L,38077L,\n38078L,38079L,38080L,38081L,38082L,38083L,38084L,38085L,38086L,38087L,\n38088L,38089L,38090L,38091L,38092L,38093L,38094L,38095L,38096L,38097L,\n38098L,38099L,38100L,38101L,38102L,38103L,38104L,38105L,38106L,38107L,\n38108L,38109L,38110L,38111L,38112L,38113L,38114L,38115L,38116L,38117L,\n38118L,38119L,38120L,38121L,38122L,38123L,38124L,38125L,38126L,38127L,\n38128L,38129L,38130L,38131L,38132L,38133L,38134L,38135L,38136L,38137L,\n38138L,38139L,38140L,38141L,38142L,38143L,38144L,38145L,38146L,38147L,\n38148L,38149L,38150L,38151L,38152L,38153L,38154L,38155L,38156L,38157L,\n38158L,38159L,38160L,38161L,38162L,38163L,38164L,38165L,38166L,38167L,\n38168L,38169L,38170L,38171L,38172L,38173L,38174L,38175L,38176L,38177L,\n38178L,38179L,38180L,38181L,38182L,38183L,38184L,38185L,38186L,38187L,\n38188L,38189L,38190L,38191L,38192L,38193L,38194L,38195L,38196L,38197L,\n38198L,38199L,38200L,38201L,38202L,38203L,38204L,38205L,38206L,38207L,\n38208L,38209L,38210L,38211L,38212L,38213L,38214L,38215L,38216L,38217L,\n38218L,38219L,38220L,38221L,38222L,38223L,38224L,38225L,38226L,38227L,\n38228L,38229L,38230L,38231L,38232L,38233L,38234L,38235L,38236L,38237L,\n38238L,38239L,38240L,38241L,38242L,38243L,38244L,38245L,38246L,38247L,\n38248L,38249L,38250L,38251L,38252L,38253L,38254L,38255L,38256L,38257L,\n38258L,38259L,38260L,38261L,38262L,38263L,38264L,38265L,38266L,38267L,\n38268L,38269L,38270L,38271L,38272L,38273L,38274L,38275L,38276L,38277L,\n38278L,38279L,38280L,38281L,38282L,38283L,38284L,38285L,38286L,38287L,\n38288L,38289L,38290L,38291L,38292L,38293L,38294L,38295L,38296L,38297L,\n38298L,38299L,38300L,38301L,38302L,38303L,38304L,38305L,38306L,38307L,\n38308L,38309L,38310L,38311L,38312L,38313L,38314L,38315L,38316L,38317L,\n38318L,38319L,38320L,38321L,38322L,38323L,38324L,38325L,38326L,38327L,\n38328L,38329L,38330L,38331L,38332L,38333L,38334L,38335L,38336L,38337L,\n38338L,38339L,38340L,38341L,38342L,38343L,38344L,38345L,38346L,38347L,\n38348L,38349L,38350L,38351L,38352L,38353L,38354L,38355L,38356L,38357L,\n38358L,38359L,38360L,38361L,38362L,38363L,38364L,38365L,38366L,38367L,\n38368L,38369L,38370L,38371L,38372L,38373L,38374L,38375L,38376L,38377L,\n38378L,38379L,38380L,38381L,38382L,38383L,38384L,38385L,38386L,38387L,\n38388L,38389L,38390L,38391L,38392L,38393L,38394L,38395L,38396L,38397L,\n38398L,38399L,38400L,38401L,38402L,38403L,38404L,38405L,38406L,38407L,\n38408L,38409L,38410L,38411L,38412L,38413L,38414L,38415L,38416L,38417L,\n38418L,38419L,38420L,38421L,38422L,38423L,38424L,38425L,38426L,38427L,\n38428L,38429L,38430L,38431L,38432L,38433L,38434L,38435L,38436L,38437L,\n38438L,38439L,38440L,38441L,38442L,38443L,38444L,38445L,38446L,38447L,\n38448L,38449L,38450L,38451L,38452L,38453L,38454L,38455L,38456L,38457L,\n38458L,38459L,38460L,38461L,38462L,38463L,38464L,38465L,38466L,38467L,\n38468L,38469L,38470L,38471L,38472L,38473L,38474L,38475L,38476L,38477L,\n38478L,38479L,38480L,38481L,38482L,38483L,38484L,38485L,38486L,38487L,\n38488L,38489L,38490L,38491L,38492L,38493L,38494L,38495L,38496L,38497L,\n38498L,38499L,38500L,38501L,38502L,38503L,38504L,38505L,38506L,38507L,\n38508L,38509L,38510L,38511L,38512L,38513L,38514L,38515L,38516L,38517L,\n38518L,38519L,38520L,38521L,38522L,38523L,38524L,38525L,38526L,38527L,\n38528L,38529L,38530L,38531L,38532L,38533L,38534L,38535L,38536L,38537L,\n38538L,38539L,38540L,38541L,38542L,38543L,38544L,38545L,38546L,38547L,\n38548L,38549L,38550L,38551L,38552L,38553L,38554L,38555L,38556L,38557L,\n38558L,38559L,38560L,38561L,38562L,38563L,38564L,38565L,38566L,38567L,\n38568L,38569L,38570L,38571L,38572L,38573L,38574L,38575L,38576L,38577L,\n38578L,38579L,38580L,38581L,38582L,38583L,38584L,38585L,38586L,38587L,\n38588L,38589L,38590L,38591L,38592L,38593L,38594L,38595L,38596L,38597L,\n38598L,38599L,38600L,38601L,38602L,38603L,38604L,38605L,38606L,38607L,\n38608L,38609L,38610L,38611L,38612L,38613L,38614L,38615L,38616L,38617L,\n38618L,38619L,38620L,38621L,38622L,38623L,38624L,38625L,38626L,38627L,\n38628L,38629L,38630L,38631L,38632L,38633L,38634L,38635L,38636L,38637L,\n38638L,38639L,38640L,38641L,38642L,38643L,38644L,38645L,38646L,38647L,\n38648L,38649L,38650L,38651L,38652L,38653L,38654L,38655L,38656L,38657L,\n38658L,38659L,38660L,38661L,38662L,38663L,38664L,38665L,38666L,38667L,\n38668L,38669L,38670L,38671L,38672L,38673L,38674L,38675L,38676L,38677L,\n38678L,38679L,38680L,38681L,38682L,38683L,38684L,38685L,38686L,38687L,\n38688L,38689L,38690L,38691L,38692L,38693L,38694L,38695L,38696L,38697L,\n38698L,38699L,38700L,38701L,38702L,38703L,38704L,38705L,38706L,38707L,\n38708L,38709L,38710L,38711L,38712L,38713L,38714L,38715L,38716L,38717L,\n38718L,38719L,38720L,38721L,38722L,38723L,38724L,38725L,38726L,38727L,\n38728L,38729L,38730L,38731L,38732L,38733L,38734L,38735L,38736L,38737L,\n38738L,38739L,38740L,38741L,38742L,38743L,38744L,38745L,38746L,38747L,\n38748L,38749L,38750L,38751L,38752L,38753L,38754L,38755L,38756L,38757L,\n38758L,38759L,38760L,38761L,38762L,38763L,38764L,38765L,38766L,38767L,\n38768L,38769L,38770L,38771L,38772L,38773L,38774L,38775L,38776L,38777L,\n38778L,38779L,38780L,38781L,38782L,38783L,38784L,38785L,38786L,38787L,\n38788L,38789L,38790L,38791L,38792L,38793L,38794L,38795L,38796L,38797L,\n38798L,38799L,38800L,38801L,38802L,38803L,38804L,38805L,38806L,38807L,\n38808L,38809L,38810L,38811L,38812L,38813L,38814L,38815L,38816L,38817L,\n38818L,38819L,38820L,38821L,38822L,38823L,38824L,38825L,38826L,38827L,\n38828L,38829L,38830L,38831L,38832L,38833L,38834L,38835L,38836L,38837L,\n38838L,38839L,38840L,38841L,38842L,38843L,38844L,38845L,38846L,38847L,\n38848L,38849L,38850L,38851L,38852L,38853L,38854L,38855L,38856L,38857L,\n38858L,38859L,38860L,38861L,38862L,38863L,38864L,38865L,38866L,38867L,\n38868L,38869L,38870L,38871L,38872L,38873L,38874L,38875L,38876L,38877L,\n38878L,38879L,38880L,38881L,38882L,38883L,38884L,38885L,38886L,38887L,\n38888L,38889L,38890L,38891L,38892L,38893L,38894L,38895L,38896L,38897L,\n38898L,38899L,38900L,38901L,38902L,38903L,38904L,38905L,38906L,38907L,\n38908L,38909L,38910L,38911L,38912L,38913L,38914L,38915L,38916L,38917L,\n38918L,38919L,38920L,38921L,38922L,38923L,38924L,38925L,38926L,38927L,\n38928L,38929L,38930L,38931L,38932L,38933L,38934L,38935L,38936L,38937L,\n38938L,38939L,38940L,38941L,38942L,38943L,38944L,38945L,38946L,38947L,\n38948L,38949L,38950L,38951L,38952L,38953L,38954L,38955L,38956L,38957L,\n38958L,38959L,38960L,38961L,38962L,38963L,38964L,38965L,38966L,38967L,\n38968L,38969L,38970L,38971L,38972L,38973L,38974L,38975L,38976L,38977L,\n38978L,38979L,38980L,38981L,38982L,38983L,38984L,38985L,38986L,38987L,\n38988L,38989L,38990L,38991L,38992L,38993L,38994L,38995L,38996L,38997L,\n38998L,38999L,39000L,39001L,39002L,39003L,39004L,39005L,39006L,39007L,\n39008L,39009L,39010L,39011L,39012L,39013L,39014L,39015L,39016L,39017L,\n39018L,39019L,39020L,39021L,39022L,39023L,39024L,39025L,39026L,39027L,\n39028L,39029L,39030L,39031L,39032L,39033L,39034L,39035L,39036L,39037L,\n39038L,39039L,39040L,39041L,39042L,39043L,39044L,39045L,39046L,39047L,\n39048L,39049L,39050L,39051L,39052L,39053L,39054L,39055L,39056L,39057L,\n39058L,39059L,39060L,39061L,39062L,39063L,39064L,39065L,39066L,39067L,\n39068L,39069L,39070L,39071L,39072L,39073L,39074L,39075L,39076L,39077L,\n39078L,39079L,39080L,39081L,39082L,39083L,39084L,39085L,39086L,39087L,\n39088L,39089L,39090L,39091L,39092L,39093L,39094L,39095L,39096L,39097L,\n39098L,39099L,39100L,39101L,39102L,39103L,39104L,39105L,39106L,39107L,\n39108L,39109L,39110L,39111L,39112L,39113L,39114L,39115L,39116L,39117L,\n39118L,39119L,39120L,39121L,39122L,39123L,39124L,39125L,39126L,39127L,\n39128L,39129L,39130L,39131L,39132L,39133L,39134L,39135L,39136L,39137L,\n39138L,39139L,39140L,39141L,39142L,39143L,39144L,39145L,39146L,39147L,\n39148L,39149L,39150L,39151L,39152L,39153L,39154L,39155L,39156L,39157L,\n39158L,39159L,39160L,39161L,39162L,39163L,39164L,39165L,39166L,39167L,\n39168L,39169L,39170L,39171L,39172L,39173L,39174L,39175L,39176L,39177L,\n39178L,39179L,39180L,39181L,39182L,39183L,39184L,39185L,39186L,39187L,\n39188L,39189L,39190L,39191L,39192L,39193L,39194L,39195L,39196L,39197L,\n39198L,39199L,39200L,39201L,39202L,39203L,39204L,39205L,39206L,39207L,\n39208L,39209L,39210L,39211L,39212L,39213L,39214L,39215L,39216L,39217L,\n39218L,39219L,39220L,39221L,39222L,39223L,39224L,39225L,39226L,39227L,\n39228L,39229L,39230L,39231L,39232L,39233L,39234L,39235L,39236L,39237L,\n39238L,39239L,39240L,39241L,39242L,39243L,39244L,39245L,39246L,39247L,\n39248L,39249L,39250L,39251L,39252L,39253L,39254L,39255L,39256L,39257L,\n39258L,39259L,39260L,39261L,39262L,39263L,39264L,39265L,39266L,39267L,\n39268L,39269L,39270L,39271L,39272L,39273L,39274L,39275L,39276L,39277L,\n39278L,39279L,39280L,39281L,39282L,39283L,39284L,39285L,39286L,39287L,\n39288L,39289L,39290L,39291L,39292L,39293L,39294L,39295L,39296L,39297L,\n39298L,39299L,39300L,39301L,39302L,39303L,39304L,39305L,39306L,39307L,\n39308L,39309L,39310L,39311L,39312L,39313L,39314L,39315L,39316L,39317L,\n39318L,39319L,39320L,39321L,39322L,39323L,39324L,39325L,39326L,39327L,\n39328L,39329L,39330L,39331L,39332L,39333L,39334L,39335L,39336L,39337L,\n39338L,39339L,39340L,39341L,39342L,39343L,39344L,39345L,39346L,39347L,\n39348L,39349L,39350L,39351L,39352L,39353L,39354L,39355L,39356L,39357L,\n39358L,39359L,39360L,39361L,39362L,39363L,39364L,39365L,39366L,39367L,\n39368L,39369L,39370L,39371L,39372L,39373L,39374L,39375L,39376L,39377L,\n39378L,39379L,39380L,39381L,39382L,39383L,39384L,39385L,39386L,39387L,\n39388L,39389L,39390L,39391L,39392L,39393L,39394L,39395L,39396L,39397L,\n39398L,39399L,39400L,39401L,39402L,39403L,39404L,39405L,39406L,39407L,\n39408L,39409L,39410L,39411L,39412L,39413L,39414L,39415L,39416L,39417L,\n39418L,39419L,39420L,39421L,39422L,39423L,39424L,39425L,39426L,39427L,\n39428L,39429L,39430L,39431L,39432L,39433L,39434L,39435L,39436L,39437L,\n39438L,39439L,39440L,39441L,39442L,39443L,39444L,39445L,39446L,39447L,\n39448L,39449L,39450L,39451L,39452L,39453L,39454L,39455L,39456L,39457L,\n39458L,39459L,39460L,39461L,39462L,39463L,39464L,39465L,39466L,39467L,\n39468L,39469L,39470L,39471L,39472L,39473L,39474L,39475L,39476L,39477L,\n39478L,39479L,39480L,39481L,39482L,39483L,39484L,39485L,39486L,39487L,\n39488L,39489L,39490L,39491L,39492L,39493L,39494L,39495L,39496L,39497L,\n39498L,39499L,39500L,39501L,39502L,39503L,39504L,39505L,39506L,39507L,\n39508L,39509L,39510L,39511L,39512L,39513L,39514L,39515L,39516L,39517L,\n39518L,39519L,39520L,39521L,39522L,39523L,39524L,39525L,39526L,39527L,\n39528L,39529L,39530L,39531L,39532L,39533L,39534L,39535L,39536L,39537L,\n39538L,39539L,39540L,39541L,39542L,39543L,39544L,39545L,39546L,39547L,\n39548L,39549L,39550L,39551L,39552L,39553L,39554L,39555L,39556L,39557L,\n39558L,39559L,39560L,39561L,39562L,39563L,39564L,39565L,39566L,39567L,\n39568L,39569L,39570L,39571L,39572L,39573L,39574L,39575L,39576L,39577L,\n39578L,39579L,39580L,39581L,39582L,39583L,39584L,39585L,39586L,39587L,\n39588L,39589L,39590L,39591L,39592L,39593L,39594L,39595L,39596L,39597L,\n39598L,39599L,39600L,39601L,39602L,39603L,39604L,39605L,39606L,39607L,\n39608L,39609L,39610L,39611L,39612L,39613L,39614L,39615L,39616L,39617L,\n39618L,39619L,39620L,39621L,39622L,39623L,39624L,39625L,39626L,39627L,\n39628L,39629L,39630L,39631L,39632L,39633L,39634L,39635L,39636L,39637L,\n39638L,39639L,39640L,39641L,39642L,39643L,39644L,39645L,39646L,39647L,\n39648L,39649L,39650L,39651L,39652L,39653L,39654L,39655L,39656L,39657L,\n39658L,39659L,39660L,39661L,39662L,39663L,39664L,39665L,39666L,39667L,\n39668L,39669L,39670L,39671L,39672L,39673L,39674L,39675L,39676L,39677L,\n39678L,39679L,39680L,39681L,39682L,39683L,39684L,39685L,39686L,39687L,\n39688L,39689L,39690L,39691L,39692L,39693L,39694L,39695L,39696L,39697L,\n39698L,39699L,39700L,39701L,39702L,39703L,39704L,39705L,39706L,39707L,\n39708L,39709L,39710L,39711L,39712L,39713L,39714L,39715L,39716L,39717L,\n39718L,39719L,39720L,39721L,39722L,39723L,39724L,39725L,39726L,39727L,\n39728L,39729L,39730L,39731L,39732L,39733L,39734L,39735L,39736L,39737L,\n39738L,39739L,39740L,39741L,39742L,39743L,39744L,39745L,39746L,39747L,\n39748L,39749L,39750L,39751L,39752L,39753L,39754L,39755L,39756L,39757L,\n39758L,39759L,39760L,39761L,39762L,39763L,39764L,39765L,39766L,39767L,\n39768L,39769L,39770L,39771L,39772L,39773L,39774L,39775L,39776L,39777L,\n39778L,39779L,39780L,39781L,39782L,39783L,39784L,39785L,39786L,39787L,\n39788L,39789L,39790L,39791L,39792L,39793L,39794L,39795L,39796L,39797L,\n39798L,39799L,39800L,39801L,39802L,39803L,39804L,39805L,39806L,39807L,\n39808L,39809L,39810L,39811L,39812L,39813L,39814L,39815L,39816L,39817L,\n39818L,39819L,39820L,39821L,39822L,39823L,39824L,39825L,39826L,39827L,\n39828L,39829L,39830L,39831L,39832L,39833L,39834L,39835L,39836L,39837L,\n39838L,39839L,39840L,39841L,39842L,39843L,39844L,39845L,39846L,39847L,\n39848L,39849L,39850L,39851L,39852L,39853L,39854L,39855L,39856L,39857L,\n39858L,39859L,39860L,39861L,39862L,39863L,39864L,39865L,39866L,39867L,\n39868L,39869L,39870L,39871L,39872L,39873L,39874L,39875L,39876L,39877L,\n39878L,39879L,39880L,39881L,39882L,39883L,39884L,39885L,39886L,39887L,\n39888L,39889L,39890L,39891L,39892L,39893L,39894L,39895L,39896L,39897L,\n39898L,39899L,39900L,39901L,39902L,39903L,39904L,39905L,39906L,39907L,\n39908L,39909L,39910L,39911L,39912L,39913L,39914L,39915L,39916L,39917L,\n39918L,39919L,39920L,39921L,39922L,39923L,39924L,39925L,39926L,39927L,\n39928L,39929L,39930L,39931L,39932L,39933L,39934L,39935L,39936L,39937L,\n39938L,39939L,39940L,39941L,39942L,39943L,39944L,39945L,39946L,39947L,\n39948L,39949L,39950L,39951L,39952L,39953L,39954L,39955L,39956L,39957L,\n39958L,39959L,39960L,39961L,39962L,39963L,39964L,39965L,39966L,39967L,\n39968L,39969L,39970L,39971L,39972L,39973L,39974L,39975L,39976L,39977L,\n39978L,39979L,39980L,39981L,39982L,39983L,39984L,39985L,39986L,39987L,\n39988L,39989L,39990L,39991L,39992L,39993L,39994L,39995L,39996L,39997L,\n39998L,39999L,40000L,40001L,40002L,40003L,40004L,40005L,40006L,40007L,\n40008L,40009L,40010L,40011L,40012L,40013L,40014L,40015L,40016L,40017L,\n40018L,40019L,40020L,40021L,40022L,40023L,40024L,40025L,40026L,40027L,\n40028L,40029L,40030L,40031L,40032L,40033L,40034L,40035L,40036L,40037L,\n40038L,40039L,40040L,40041L,40042L,40043L,40044L,40045L,40046L,40047L,\n40048L,40049L,40050L,40051L,40052L,40053L,40054L,40055L,40056L,40057L,\n40058L,40059L,40060L,40061L,40062L,40063L,40064L,40065L,40066L,40067L,\n40068L,40069L,40070L,40071L,40072L,40073L,40074L,40075L,40076L,40077L,\n40078L,40079L,40080L,40081L,40082L,40083L,40084L,40085L,40086L,40087L,\n40088L,40089L,40090L,40091L,40092L,40093L,40094L,40095L,40096L,40097L,\n40098L,40099L,40100L,40101L,40102L,40103L,40104L,40105L,40106L,40107L,\n40108L,40109L,40110L,40111L,40112L,40113L,40114L,40115L,40116L,40117L,\n40118L,40119L,40120L,40121L,40122L,40123L,40124L,40125L,40126L,40127L,\n40128L,40129L,40130L,40131L,40132L,40133L,40134L,40135L,40136L,40137L,\n40138L,40139L,40140L,40141L,40142L,40143L,40144L,40145L,40146L,40147L,\n40148L,40149L,40150L,40151L,40152L,40153L,40154L,40155L,40156L,40157L,\n40158L,40159L,40160L,40161L,40162L,40163L,40164L,40165L,40166L,40167L,\n40168L,40169L,40170L,40171L,40172L,40173L,40174L,40175L,40176L,40177L,\n40178L,40179L,40180L,40181L,40182L,40183L,40184L,40185L,40186L,40187L,\n40188L,40189L,40190L,40191L,40192L,40193L,40194L,40195L,40196L,40197L,\n40198L,40199L,40200L,40201L,40202L,40203L,40204L,40205L,40206L,40207L,\n40208L,40209L,40210L,40211L,40212L,40213L,40214L,40215L,40216L,40217L,\n40218L,40219L,40220L,40221L,40222L,40223L,40224L,40225L,40226L,40227L,\n40228L,40229L,40230L,40231L,40232L,40233L,40234L,40235L,40236L,40237L,\n40238L,40239L,40240L,40241L,40242L,40243L,40244L,40245L,40246L,40247L,\n40248L,40249L,40250L,40251L,40252L,40253L,40254L,40255L,40256L,40257L,\n40258L,40259L,40260L,40261L,40262L,40263L,40264L,40265L,40266L,40267L,\n40268L,40269L,40270L,40271L,40272L,40273L,40274L,40275L,40276L,40277L,\n40278L,40279L,40280L,40281L,40282L,40283L,40284L,40285L,40286L,40287L,\n40288L,40289L,40290L,40291L,40292L,40293L,40294L,40295L,40296L,40297L,\n40298L,40299L,40300L,40301L,40302L,40303L,40304L,40305L,40306L,40307L,\n40308L,40309L,40310L,40311L,40312L,40313L,40314L,40315L,40316L,40317L,\n40318L,40319L,40320L,40321L,40322L,40323L,40324L,40325L,40326L,40327L,\n40328L,40329L,40330L,40331L,40332L,40333L,40334L,40335L,40336L,40337L,\n40338L,40339L,40340L,40341L,40342L,40343L,40344L,40345L,40346L,40347L,\n40348L,40349L,40350L,40351L,40352L,40353L,40354L,40355L,40356L,40357L,\n40358L,40359L,40360L,40361L,40362L,40363L,40364L,40365L,40366L,40367L,\n40368L,40369L,40370L,40371L,40372L,40373L,40374L,40375L,40376L,40377L,\n40378L,40379L,40380L,40381L,40382L,40383L,40384L,40385L,40386L,40387L,\n40388L,40389L,40390L,40391L,40392L,40393L,40394L,40395L,40396L,40397L,\n40398L,40399L,40400L,40401L,40402L,40403L,40404L,40405L,40406L,40407L,\n40408L,40409L,40410L,40411L,40412L,40413L,40414L,40415L,40416L,40417L,\n40418L,40419L,40420L,40421L,40422L,40423L,40424L,40425L,40426L,40427L,\n40428L,40429L,40430L,40431L,40432L,40433L,40434L,40435L,40436L,40437L,\n40438L,40439L,40440L,40441L,40442L,40443L,40444L,40445L,40446L,40447L,\n40448L,40449L,40450L,40451L,40452L,40453L,40454L,40455L,40456L,40457L,\n40458L,40459L,40460L,40461L,40462L,40463L,40464L,40465L,40466L,40467L,\n40468L,40469L,40470L,40471L,40472L,40473L,40474L,40475L,40476L,40477L,\n40478L,40479L,40480L,40481L,40482L,40483L,40484L,40485L,40486L,40487L,\n40488L,40489L,40490L,40491L,40492L,40493L,40494L,40495L,40496L,40497L,\n40498L,40499L,40500L,40501L,40502L,40503L,40504L,40505L,40506L,40507L,\n40508L,40509L,40510L,40511L,40512L,40513L,40514L,40515L,40516L,40517L,\n40518L,40519L,40520L,40521L,40522L,40523L,40524L,40525L,40526L,40527L,\n40528L,40529L,40530L,40531L,40532L,40533L,40534L,40535L,40536L,40537L,\n40538L,40539L,40540L,40541L,40542L,40543L,40544L,40545L,40546L,40547L,\n40548L,40549L,40550L,40551L,40552L,40553L,40554L,40555L,40556L,40557L,\n40558L,40559L,40560L,40561L,40562L,40563L,40564L,40565L,40566L,40567L,\n40568L,40569L,40570L,40571L,40572L,40573L,40574L,40575L,40576L,40577L,\n40578L,40579L,40580L,40581L,40582L,40583L,40584L,40585L,40586L,40587L,\n40588L,40589L,40590L,40591L,40592L,40593L,40594L,40595L,40596L,40597L,\n40598L,40599L,40600L,40601L,40602L,40603L,40604L,40605L,40606L,40607L,\n40608L,40609L,40610L,40611L,40612L,40613L,40614L,40615L,40616L,40617L,\n40618L,40619L,40620L,40621L,40622L,40623L,40624L,40625L,40626L,40627L,\n40628L,40629L,40630L,40631L,40632L,40633L,40634L,40635L,40636L,40637L,\n40638L,40639L,40640L,40641L,40642L,40643L,40644L,40645L,40646L,40647L,\n40648L,40649L,40650L,40651L,40652L,40653L,40654L,40655L,40656L,40657L,\n40658L,40659L,40660L,40661L,40662L,40663L,40664L,40665L,40666L,40667L,\n40668L,40669L,40670L,40671L,40672L,40673L,40674L,40675L,40676L,40677L,\n40678L,40679L,40680L,40681L,40682L,40683L,40684L,40685L,40686L,40687L,\n40688L,40689L,40690L,40691L,40692L,40693L,40694L,40695L,40696L,40697L,\n40698L,40699L,40700L,40701L,40702L,40703L,40704L,40705L,40706L,40707L,\n40708L,40709L,40710L,40711L,40712L,40713L,40714L,40715L,40716L,40717L,\n40718L,40719L,40720L,40721L,40722L,40723L,40724L,40725L,40726L,40727L,\n40728L,40729L,40730L,40731L,40732L,40733L,40734L,40735L,40736L,40737L,\n40738L,40739L,40740L,40741L,40742L,40743L,40744L,40745L,40746L,40747L,\n40748L,40749L,40750L,40751L,40752L,40753L,40754L,40755L,40756L,40757L,\n40758L,40759L,40760L,40761L,40762L,40763L,40764L,40765L,40766L,40767L,\n40768L,40769L,40770L,40771L,40772L,40773L,40774L,40775L,40776L,40777L,\n40778L,40779L,40780L,40781L,40782L,40783L,40784L,40785L,40786L,40787L,\n40788L,40789L,40790L,40791L,40792L,40793L,40794L,40795L,40796L,40797L,\n40798L,40799L,40800L,40801L,40802L,40803L,40804L,40805L,40806L,40807L,\n40808L,40809L,40810L,40811L,40812L,40813L,40814L,40815L,40816L,40817L,\n40818L,40819L,40820L,40821L,40822L,40823L,40824L,40825L,40826L,40827L,\n40828L,40829L,40830L,40831L,40832L,40833L,40834L,40835L,40836L,40837L,\n40838L,40839L,40840L,40841L,40842L,40843L,40844L,40845L,40846L,40847L,\n40848L,40849L,40850L,40851L,40852L,40853L,40854L,40855L,40856L,40857L,\n40858L,40859L,40860L,40861L,40862L,40863L,40864L,40865L,40866L,40867L,\n40868L,40869L,40870L,40871L,40872L,40873L,40874L,40875L,40876L,40877L,\n40878L,40879L,40880L,40881L,40882L,40883L,40884L,40885L,40886L,40887L,\n40888L,40889L,40890L,40891L,40892L,40893L,40894L,40895L,40896L,40897L,\n40898L,40899L,40900L,40901L,40902L,40903L,40904L,40905L,40906L,40907L,\n40908L,40909L,40910L,40911L,40912L,40913L,40914L,40915L,40916L,40917L,\n40918L,40919L,40920L,40921L,40922L,40923L,40924L,40925L,40926L,40927L,\n40928L,40929L,40930L,40931L,40932L,40933L,40934L,40935L,40936L,40937L,\n40938L,40939L,40940L,40941L,40942L,40943L,40944L,40945L,40946L,40947L,\n40948L,40949L,40950L,40951L,40952L,40953L,40954L,40955L,40956L,40957L,\n40958L,40959L,40960L,40961L,40962L,40963L,40964L,40965L,40966L,40967L,\n40968L,40969L,40970L,40971L,40972L,40973L,40974L,40975L,40976L,40977L,\n40978L,40979L,40980L,40981L,40982L,40983L,40984L,40985L,40986L,40987L,\n40988L,40989L,40990L,40991L,40992L,40993L,40994L,40995L,40996L,40997L,\n40998L,40999L,41000L,41001L,41002L,41003L,41004L,41005L,41006L,41007L,\n41008L,41009L,41010L,41011L,41012L,41013L,41014L,41015L,41016L,41017L,\n41018L,41019L,41020L,41021L,41022L,41023L,41024L,41025L,41026L,41027L,\n41028L,41029L,41030L,41031L,41032L,41033L,41034L,41035L,41036L,41037L,\n41038L,41039L,41040L,41041L,41042L,41043L,41044L,41045L,41046L,41047L,\n41048L,41049L,41050L,41051L,41052L,41053L,41054L,41055L,41056L,41057L,\n41058L,41059L,41060L,41061L,41062L,41063L,41064L,41065L,41066L,41067L,\n41068L,41069L,41070L,41071L,41072L,41073L,41074L,41075L,41076L,41077L,\n41078L,41079L,41080L,41081L,41082L,41083L,41084L,41085L,41086L,41087L,\n41088L,41089L,41090L,41091L,41092L,41093L,41094L,41095L,41096L,41097L,\n41098L,41099L,41100L,41101L,41102L,41103L,41104L,41105L,41106L,41107L,\n41108L,41109L,41110L,41111L,41112L,41113L,41114L,41115L,41116L,41117L,\n41118L,41119L,41120L,41121L,41122L,41123L,41124L,41125L,41126L,41127L,\n41128L,41129L,41130L,41131L,41132L,41133L,41134L,41135L,41136L,41137L,\n41138L,41139L,41140L,41141L,41142L,41143L,41144L,41145L,41146L,41147L,\n41148L,41149L,41150L,41151L,41152L,41153L,41154L,41155L,41156L,41157L,\n41158L,41159L,41160L,41161L,41162L,41163L,41164L,41165L,41166L,41167L,\n41168L,41169L,41170L,41171L,41172L,41173L,41174L,41175L,41176L,41177L,\n41178L,41179L,41180L,41181L,41182L,41183L,41184L,41185L,41186L,41187L,\n41188L,41189L,41190L,41191L,41192L,41193L,41194L,41195L,41196L,41197L,\n41198L,41199L,41200L,41201L,41202L,41203L,41204L,41205L,41206L,41207L,\n41208L,41209L,41210L,41211L,41212L,41213L,41214L,41215L,41216L,41217L,\n41218L,41219L,41220L,41221L,41222L,41223L,41224L,41225L,41226L,41227L,\n41228L,41229L,41230L,41231L,41232L,41233L,41234L,41235L,41236L,41237L,\n41238L,41239L,41240L,41241L,41242L,41243L,41244L,41245L,41246L,41247L,\n41248L,41249L,41250L,41251L,41252L,41253L,41254L,41255L,41256L,41257L,\n41258L,41259L,41260L,41261L,41262L,41263L,41264L,41265L,41266L,41267L,\n41268L,41269L,41270L,41271L,41272L,41273L,41274L,41275L,41276L,41277L,\n41278L,41279L,41280L,41281L,41282L,41283L,41284L,41285L,41286L,41287L,\n41288L,41289L,41290L,41291L,41292L,41293L,41294L,41295L,41296L,41297L,\n41298L,41299L,41300L,41301L,41302L,41303L,41304L,41305L,41306L,41307L,\n41308L,41309L,41310L,41311L,41312L,41313L,41314L,41315L,41316L,41317L,\n41318L,41319L,41320L,41321L,41322L,41323L,41324L,41325L,41326L,41327L,\n41328L,41329L,41330L,41331L,41332L,41333L,41334L,41335L,41336L,41337L,\n41338L,41339L,41340L,41341L,41342L,41343L,41344L,41345L,41346L,41347L,\n41348L,41349L,41350L,41351L,41352L,41353L,41354L,41355L,41356L,41357L,\n41358L,41359L,41360L,41361L,41362L,41363L,41364L,41365L,41366L,41367L,\n41368L,41369L,41370L,41371L,41372L,41373L,41374L,41375L,41376L,41377L,\n41378L,41379L,41380L,41381L,41382L,41383L,41384L,41385L,41386L,41387L,\n41388L,41389L,41390L,41391L,41392L,41393L,41394L,41395L,41396L,41397L,\n41398L,41399L,41400L,41401L,41402L,41403L,41404L,41405L,41406L,41407L,\n41408L,41409L,41410L,41411L,41412L,41413L,41414L,41415L,41416L,41417L,\n41418L,41419L,41420L,41421L,41422L,41423L,41424L,41425L,41426L,41427L,\n41428L,41429L,41430L,41431L,41432L,41433L,41434L,41435L,41436L,41437L,\n41438L,41439L,41440L,41441L,41442L,41443L,41444L,41445L,41446L,41447L,\n41448L,41449L,41450L,41451L,41452L,41453L,41454L,41455L,41456L,41457L,\n41458L,41459L,41460L,41461L,41462L,41463L,41464L,41465L,41466L,41467L,\n41468L,41469L,41470L,41471L,41472L,41473L,41474L,41475L,41476L,41477L,\n41478L,41479L,41480L,41481L,41482L,41483L,41484L,41485L,41486L,41487L,\n41488L,41489L,41490L,41491L,41492L,41493L,41494L,41495L,41496L,41497L,\n41498L,41499L,41500L,41501L,41502L,41503L,41504L,41505L,41506L,41507L,\n41508L,41509L,41510L,41511L,41512L,41513L,41514L,41515L,41516L,41517L,\n41518L,41519L,41520L,41521L,41522L,41523L,41524L,41525L,41526L,41527L,\n41528L,41529L,41530L,41531L,41532L,41533L,41534L,41535L,41536L,41537L,\n41538L,41539L,41540L,41541L,41542L,41543L,41544L,41545L,41546L,41547L,\n41548L,41549L,41550L,41551L,41552L,41553L,41554L,41555L,41556L,41557L,\n41558L,41559L,41560L,41561L,41562L,41563L,41564L,41565L,41566L,41567L,\n41568L,41569L,41570L,41571L,41572L,41573L,41574L,41575L,41576L,41577L,\n41578L,41579L,41580L,41581L,41582L,41583L,41584L,41585L,41586L,41587L,\n41588L,41589L,41590L,41591L,41592L,41593L,41594L,41595L,41596L,41597L,\n41598L,41599L,41600L,41601L,41602L,41603L,41604L,41605L,41606L,41607L,\n41608L,41609L,41610L,41611L,41612L,41613L,41614L,41615L,41616L,41617L,\n41618L,41619L,41620L,41621L,41622L,41623L,41624L,41625L,41626L,41627L,\n41628L,41629L,41630L,41631L,41632L,41633L,41634L,41635L,41636L,41637L,\n41638L,41639L,41640L,41641L,41642L,41643L,41644L,41645L,41646L,41647L,\n41648L,41649L,41650L,41651L,41652L,41653L,41654L,41655L,41656L,41657L,\n41658L,41659L,41660L,41661L,41662L,41663L,41664L,41665L,41666L,41667L,\n41668L,41669L,41670L,41671L,41672L,41673L,41674L,41675L,41676L,41677L,\n41678L,41679L,41680L,41681L,41682L,41683L,41684L,41685L,41686L,41687L,\n41688L,41689L,41690L,41691L,41692L,41693L,41694L,41695L,41696L,41697L,\n41698L,41699L,41700L,41701L,41702L,41703L,41704L,41705L,41706L,41707L,\n41708L,41709L,41710L,41711L,41712L,41713L,41714L,41715L,41716L,41717L,\n41718L,41719L,41720L,41721L,41722L,41723L,41724L,41725L,41726L,41727L,\n41728L,41729L,41730L,41731L,41732L,41733L,41734L,41735L,41736L,41737L,\n41738L,41739L,41740L,41741L,41742L,41743L,41744L,41745L,41746L,41747L,\n41748L,41749L,41750L,41751L,41752L,41753L,41754L,41755L,41756L,41757L,\n41758L,41759L,41760L,41761L,41762L,41763L,41764L,41765L,41766L,41767L,\n41768L,41769L,41770L,41771L,41772L,41773L,41774L,41775L,41776L,41777L,\n41778L,41779L,41780L,41781L,41782L,41783L,41784L,41785L,41786L,41787L,\n41788L,41789L,41790L,41791L,41792L,41793L,41794L,41795L,41796L,41797L,\n41798L,41799L,41800L,41801L,41802L,41803L,41804L,41805L,41806L,41807L,\n41808L,41809L,41810L,41811L,41812L,41813L,41814L,41815L,41816L,41817L,\n41818L,41819L,41820L,41821L,41822L,41823L,41824L,41825L,41826L,41827L,\n41828L,41829L,41830L,41831L,41832L,41833L,41834L,41835L,41836L,41837L,\n41838L,41839L,41840L,41841L,41842L,41843L,41844L,41845L,41846L,41847L,\n41848L,41849L,41850L,41851L,41852L,41853L,41854L,41855L,41856L,41857L,\n41858L,41859L,41860L,41861L,41862L,41863L,41864L,41865L,41866L,41867L,\n41868L,41869L,41870L,41871L,41872L,41873L,41874L,41875L,41876L,41877L,\n41878L,41879L,41880L,41881L,41882L,41883L,41884L,41885L,41886L,41887L,\n41888L,41889L,41890L,41891L,41892L,41893L,41894L,41895L,41896L,41897L,\n41898L,41899L,41900L,41901L,41902L,41903L,41904L,41905L,41906L,41907L,\n41908L,41909L,41910L,41911L,41912L,41913L,41914L,41915L,41916L,41917L,\n41918L,41919L,41920L,41921L,41922L,41923L,41924L,41925L,41926L,41927L,\n41928L,41929L,41930L,41931L,41932L,41933L,41934L,41935L,41936L,41937L,\n41938L,41939L,41940L,41941L,41942L,41943L,41944L,41945L,41946L,41947L,\n41948L,41949L,41950L,41951L,41952L,41953L,41954L,41955L,41956L,41957L,\n41958L,41959L,41960L,41961L,41962L,41963L,41964L,41965L,41966L,41967L,\n41968L,41969L,41970L,41971L,41972L,41973L,41974L,41975L,41976L,41977L,\n41978L,41979L,41980L,41981L,41982L,41983L,41984L,41985L,41986L,41987L,\n41988L,41989L,41990L,41991L,41992L,41993L,41994L,41995L,41996L,41997L,\n41998L,41999L,42000L,42001L,42002L,42003L,42004L,42005L,42006L,42007L,\n42008L,42009L,42010L,42011L,42012L,42013L,42014L,42015L,42016L,42017L,\n42018L,42019L,42020L,42021L,42022L,42023L,42024L,42025L,42026L,42027L,\n42028L,42029L,42030L,42031L,42032L,42033L,42034L,42035L,42036L,42037L,\n42038L,42039L,42040L,42041L,42042L,42043L,42044L,42045L,42046L,42047L,\n42048L,42049L,42050L,42051L,42052L,42053L,42054L,42055L,42056L,42057L,\n42058L,42059L,42060L,42061L,42062L,42063L,42064L,42065L,42066L,42067L,\n42068L,42069L,42070L,42071L,42072L,42073L,42074L,42075L,42076L,42077L,\n42078L,42079L,42080L,42081L,42082L,42083L,42084L,42085L,42086L,42087L,\n42088L,42089L,42090L,42091L,42092L,42093L,42094L,42095L,42096L,42097L,\n42098L,42099L,42100L,42101L,42102L,42103L,42104L,42105L,42106L,42107L,\n42108L,42109L,42110L,42111L,42112L,42113L,42114L,42115L,42116L,42117L,\n42118L,42119L,42120L,42121L,42122L,42123L,42124L,42125L,42126L,42127L,\n42128L,42129L,42130L,42131L,42132L,42133L,42134L,42135L,42136L,42137L,\n42138L,42139L,42140L,42141L,42142L,42143L,42144L,42145L,42146L,42147L,\n42148L,42149L,42150L,42151L,42152L,42153L,42154L,42155L,42156L,42157L,\n42158L,42159L,42160L,42161L,42162L,42163L,42164L,42165L,42166L,42167L,\n42168L,42169L,42170L,42171L,42172L,42173L,42174L,42175L,42176L,42177L,\n42178L,42179L,42180L,42181L,42182L,42183L,42184L,42185L,42186L,42187L,\n42188L,42189L,42190L,42191L,42192L,42193L,42194L,42195L,42196L,42197L,\n42198L,42199L,42200L,42201L,42202L,42203L,42204L,42205L,42206L,42207L,\n42208L,42209L,42210L,42211L,42212L,42213L,42214L,42215L,42216L,42217L,\n42218L,42219L,42220L,42221L,42222L,42223L,42224L,42225L,42226L,42227L,\n42228L,42229L,42230L,42231L,42232L,42233L,42234L,42235L,42236L,42237L,\n42238L,42239L,42240L,42241L,42242L,42243L,42244L,42245L,42246L,42247L,\n42248L,42249L,42250L,42251L,42252L,42253L,42254L,42255L,42256L,42257L,\n42258L,42259L,42260L,42261L,42262L,42263L,42264L,42265L,42266L,42267L,\n42268L,42269L,42270L,42271L,42272L,42273L,42274L,42275L,42276L,42277L,\n42278L,42279L,42280L,42281L,42282L,42283L,42284L,42285L,42286L,42287L,\n42288L,42289L,42290L,42291L,42292L,42293L,42294L,42295L,42296L,42297L,\n42298L,42299L,42300L,42301L,42302L,42303L,42304L,42305L,42306L,42307L,\n42308L,42309L,42310L,42311L,42312L,42313L,42314L,42315L,42316L,42317L,\n42318L,42319L,42320L,42321L,42322L,42323L,42324L,42325L,42326L,42327L,\n42328L,42329L,42330L,42331L,42332L,42333L,42334L,42335L,42336L,42337L,\n42338L,42339L,42340L,42341L,42342L,42343L,42344L,42345L,42346L,42347L,\n42348L,42349L,42350L,42351L,42352L,42353L,42354L,42355L,42356L,42357L,\n42358L,42359L,42360L,42361L,42362L,42363L,42364L,42365L,42366L,42367L,\n42368L,42369L,42370L,42371L,42372L,42373L,42374L,42375L,42376L,42377L,\n42378L,42379L,42380L,42381L,42382L,42383L,42384L,42385L,42386L,42387L,\n42388L,42389L,42390L,42391L,42392L,42393L,42394L,42395L,42396L,42397L,\n42398L,42399L,42400L,42401L,42402L,42403L,42404L,42405L,42406L,42407L,\n42408L,42409L,42410L,42411L,42412L,42413L,42414L,42415L,42416L,42417L,\n42418L,42419L,42420L,42421L,42422L,42423L,42424L,42425L,42426L,42427L,\n42428L,42429L,42430L,42431L,42432L,42433L,42434L,42435L,42436L,42437L,\n42438L,42439L,42440L,42441L,42442L,42443L,42444L,42445L,42446L,42447L,\n42448L,42449L,42450L,42451L,42452L,42453L,42454L,42455L,42456L,42457L,\n42458L,42459L,42460L,42461L,42462L,42463L,42464L,42465L,42466L,42467L,\n42468L,42469L,42470L,42471L,42472L,42473L,42474L,42475L,42476L,42477L,\n42478L,42479L,42480L,42481L,42482L,42483L,42484L,42485L,42486L,42487L,\n42488L,42489L,42490L,42491L,42492L,42493L,42494L,42495L,42496L,42497L,\n42498L,42499L,42500L,42501L,42502L,42503L,42504L,42505L,42506L,42507L,\n42508L,42509L,42510L,42511L,42512L,42513L,42514L,42515L,42516L,42517L,\n42518L,42519L,42520L,42521L,42522L,42523L,42524L,42525L,42526L,42527L,\n42528L,42529L,42530L,42531L,42532L,42533L,42534L,42535L,42536L,42537L,\n42538L,42539L,42540L,42541L,42542L,42543L,42544L,42545L,42546L,42547L,\n42548L,42549L,42550L,42551L,42552L,42553L,42554L,42555L,42556L,42557L,\n42558L,42559L,42560L,42560L,42562L,42562L,42564L,42564L,42566L,42566L,\n42568L,42568L,42570L,42570L,42572L,42572L,42574L,42574L,42576L,42576L,\n42578L,42578L,42580L,42580L,42582L,42582L,42584L,42584L,42586L,42586L,\n42588L,42588L,42590L,42590L,42592L,42592L,42594L,42594L,42596L,42596L,\n42598L,42598L,42600L,42600L,42602L,42602L,42604L,42604L,42606L,42607L,\n42608L,42609L,42610L,42611L,42612L,42613L,42614L,42615L,42616L,42617L,\n42618L,42619L,42620L,42621L,42622L,42623L,42624L,42624L,42626L,42626L,\n42628L,42628L,42630L,42630L,42632L,42632L,42634L,42634L,42636L,42636L,\n42638L,42638L,42640L,42640L,42642L,42642L,42644L,42644L,42646L,42646L,\n42648L,42648L,42650L,42650L,42652L,42653L,42654L,42655L,42656L,42657L,\n42658L,42659L,42660L,42661L,42662L,42663L,42664L,42665L,42666L,42667L,\n42668L,42669L,42670L,42671L,42672L,42673L,42674L,42675L,42676L,42677L,\n42678L,42679L,42680L,42681L,42682L,42683L,42684L,42685L,42686L,42687L,\n42688L,42689L,42690L,42691L,42692L,42693L,42694L,42695L,42696L,42697L,\n42698L,42699L,42700L,42701L,42702L,42703L,42704L,42705L,42706L,42707L,\n42708L,42709L,42710L,42711L,42712L,42713L,42714L,42715L,42716L,42717L,\n42718L,42719L,42720L,42721L,42722L,42723L,42724L,42725L,42726L,42727L,\n42728L,42729L,42730L,42731L,42732L,42733L,42734L,42735L,42736L,42737L,\n42738L,42739L,42740L,42741L,42742L,42743L,42744L,42745L,42746L,42747L,\n42748L,42749L,42750L,42751L,42752L,42753L,42754L,42755L,42756L,42757L,\n42758L,42759L,42760L,42761L,42762L,42763L,42764L,42765L,42766L,42767L,\n42768L,42769L,42770L,42771L,42772L,42773L,42774L,42775L,42776L,42777L,\n42778L,42779L,42780L,42781L,42782L,42783L,42784L,42785L,42786L,42786L,\n42788L,42788L,42790L,42790L,42792L,42792L,42794L,42794L,42796L,42796L,\n42798L,42798L,42800L,42801L,42802L,42802L,42804L,42804L,42806L,42806L,\n42808L,42808L,42810L,42810L,42812L,42812L,42814L,42814L,42816L,42816L,\n42818L,42818L,42820L,42820L,42822L,42822L,42824L,42824L,42826L,42826L,\n42828L,42828L,42830L,42830L,42832L,42832L,42834L,42834L,42836L,42836L,\n42838L,42838L,42840L,42840L,42842L,42842L,42844L,42844L,42846L,42846L,\n42848L,42848L,42850L,42850L,42852L,42852L,42854L,42854L,42856L,42856L,\n42858L,42858L,42860L,42860L,42862L,42862L,42864L,42865L,42866L,42867L,\n42868L,42869L,42870L,42871L,42872L,42873L,42873L,42875L,42875L,42877L,\n42878L,42878L,42880L,42880L,42882L,42882L,42884L,42884L,42886L,42886L,\n42888L,42889L,42890L,42891L,42891L,42893L,42894L,42895L,42896L,42896L,\n42898L,42898L,42948L,42901L,42902L,42902L,42904L,42904L,42906L,42906L,\n42908L,42908L,42910L,42910L,42912L,42912L,42914L,42914L,42916L,42916L,\n42918L,42918L,42920L,42920L,42922L,42923L,42924L,42925L,42926L,42927L,\n42928L,42929L,42930L,42931L,42932L,42932L,42934L,42934L,42936L,42936L,\n42938L,42938L,42940L,42940L,42942L,42942L,42944L,42945L,42946L,42946L,\n42948L,42949L,42950L,42951L,42952L,42953L,42954L,42955L,42956L,42957L,\n42958L,42959L,42960L,42961L,42962L,42963L,42964L,42965L,42966L,42967L,\n42968L,42969L,42970L,42971L,42972L,42973L,42974L,42975L,42976L,42977L,\n42978L,42979L,42980L,42981L,42982L,42983L,42984L,42985L,42986L,42987L,\n42988L,42989L,42990L,42991L,42992L,42993L,42994L,42995L,42996L,42997L,\n42998L,42999L,43000L,43001L,43002L,43003L,43004L,43005L,43006L,43007L,\n43008L,43009L,43010L,43011L,43012L,43013L,43014L,43015L,43016L,43017L,\n43018L,43019L,43020L,43021L,43022L,43023L,43024L,43025L,43026L,43027L,\n43028L,43029L,43030L,43031L,43032L,43033L,43034L,43035L,43036L,43037L,\n43038L,43039L,43040L,43041L,43042L,43043L,43044L,43045L,43046L,43047L,\n43048L,43049L,43050L,43051L,43052L,43053L,43054L,43055L,43056L,43057L,\n43058L,43059L,43060L,43061L,43062L,43063L,43064L,43065L,43066L,43067L,\n43068L,43069L,43070L,43071L,43072L,43073L,43074L,43075L,43076L,43077L,\n43078L,43079L,43080L,43081L,43082L,43083L,43084L,43085L,43086L,43087L,\n43088L,43089L,43090L,43091L,43092L,43093L,43094L,43095L,43096L,43097L,\n43098L,43099L,43100L,43101L,43102L,43103L,43104L,43105L,43106L,43107L,\n43108L,43109L,43110L,43111L,43112L,43113L,43114L,43115L,43116L,43117L,\n43118L,43119L,43120L,43121L,43122L,43123L,43124L,43125L,43126L,43127L,\n43128L,43129L,43130L,43131L,43132L,43133L,43134L,43135L,43136L,43137L,\n43138L,43139L,43140L,43141L,43142L,43143L,43144L,43145L,43146L,43147L,\n43148L,43149L,43150L,43151L,43152L,43153L,43154L,43155L,43156L,43157L,\n43158L,43159L,43160L,43161L,43162L,43163L,43164L,43165L,43166L,43167L,\n43168L,43169L,43170L,43171L,43172L,43173L,43174L,43175L,43176L,43177L,\n43178L,43179L,43180L,43181L,43182L,43183L,43184L,43185L,43186L,43187L,\n43188L,43189L,43190L,43191L,43192L,43193L,43194L,43195L,43196L,43197L,\n43198L,43199L,43200L,43201L,43202L,43203L,43204L,43205L,43206L,43207L,\n43208L,43209L,43210L,43211L,43212L,43213L,43214L,43215L,43216L,43217L,\n43218L,43219L,43220L,43221L,43222L,43223L,43224L,43225L,43226L,43227L,\n43228L,43229L,43230L,43231L,43232L,43233L,43234L,43235L,43236L,43237L,\n43238L,43239L,43240L,43241L,43242L,43243L,43244L,43245L,43246L,43247L,\n43248L,43249L,43250L,43251L,43252L,43253L,43254L,43255L,43256L,43257L,\n43258L,43259L,43260L,43261L,43262L,43263L,43264L,43265L,43266L,43267L,\n43268L,43269L,43270L,43271L,43272L,43273L,43274L,43275L,43276L,43277L,\n43278L,43279L,43280L,43281L,43282L,43283L,43284L,43285L,43286L,43287L,\n43288L,43289L,43290L,43291L,43292L,43293L,43294L,43295L,43296L,43297L,\n43298L,43299L,43300L,43301L,43302L,43303L,43304L,43305L,43306L,43307L,\n43308L,43309L,43310L,43311L,43312L,43313L,43314L,43315L,43316L,43317L,\n43318L,43319L,43320L,43321L,43322L,43323L,43324L,43325L,43326L,43327L,\n43328L,43329L,43330L,43331L,43332L,43333L,43334L,43335L,43336L,43337L,\n43338L,43339L,43340L,43341L,43342L,43343L,43344L,43345L,43346L,43347L,\n43348L,43349L,43350L,43351L,43352L,43353L,43354L,43355L,43356L,43357L,\n43358L,43359L,43360L,43361L,43362L,43363L,43364L,43365L,43366L,43367L,\n43368L,43369L,43370L,43371L,43372L,43373L,43374L,43375L,43376L,43377L,\n43378L,43379L,43380L,43381L,43382L,43383L,43384L,43385L,43386L,43387L,\n43388L,43389L,43390L,43391L,43392L,43393L,43394L,43395L,43396L,43397L,\n43398L,43399L,43400L,43401L,43402L,43403L,43404L,43405L,43406L,43407L,\n43408L,43409L,43410L,43411L,43412L,43413L,43414L,43415L,43416L,43417L,\n43418L,43419L,43420L,43421L,43422L,43423L,43424L,43425L,43426L,43427L,\n43428L,43429L,43430L,43431L,43432L,43433L,43434L,43435L,43436L,43437L,\n43438L,43439L,43440L,43441L,43442L,43443L,43444L,43445L,43446L,43447L,\n43448L,43449L,43450L,43451L,43452L,43453L,43454L,43455L,43456L,43457L,\n43458L,43459L,43460L,43461L,43462L,43463L,43464L,43465L,43466L,43467L,\n43468L,43469L,43470L,43471L,43472L,43473L,43474L,43475L,43476L,43477L,\n43478L,43479L,43480L,43481L,43482L,43483L,43484L,43485L,43486L,43487L,\n43488L,43489L,43490L,43491L,43492L,43493L,43494L,43495L,43496L,43497L,\n43498L,43499L,43500L,43501L,43502L,43503L,43504L,43505L,43506L,43507L,\n43508L,43509L,43510L,43511L,43512L,43513L,43514L,43515L,43516L,43517L,\n43518L,43519L,43520L,43521L,43522L,43523L,43524L,43525L,43526L,43527L,\n43528L,43529L,43530L,43531L,43532L,43533L,43534L,43535L,43536L,43537L,\n43538L,43539L,43540L,43541L,43542L,43543L,43544L,43545L,43546L,43547L,\n43548L,43549L,43550L,43551L,43552L,43553L,43554L,43555L,43556L,43557L,\n43558L,43559L,43560L,43561L,43562L,43563L,43564L,43565L,43566L,43567L,\n43568L,43569L,43570L,43571L,43572L,43573L,43574L,43575L,43576L,43577L,\n43578L,43579L,43580L,43581L,43582L,43583L,43584L,43585L,43586L,43587L,\n43588L,43589L,43590L,43591L,43592L,43593L,43594L,43595L,43596L,43597L,\n43598L,43599L,43600L,43601L,43602L,43603L,43604L,43605L,43606L,43607L,\n43608L,43609L,43610L,43611L,43612L,43613L,43614L,43615L,43616L,43617L,\n43618L,43619L,43620L,43621L,43622L,43623L,43624L,43625L,43626L,43627L,\n43628L,43629L,43630L,43631L,43632L,43633L,43634L,43635L,43636L,43637L,\n43638L,43639L,43640L,43641L,43642L,43643L,43644L,43645L,43646L,43647L,\n43648L,43649L,43650L,43651L,43652L,43653L,43654L,43655L,43656L,43657L,\n43658L,43659L,43660L,43661L,43662L,43663L,43664L,43665L,43666L,43667L,\n43668L,43669L,43670L,43671L,43672L,43673L,43674L,43675L,43676L,43677L,\n43678L,43679L,43680L,43681L,43682L,43683L,43684L,43685L,43686L,43687L,\n43688L,43689L,43690L,43691L,43692L,43693L,43694L,43695L,43696L,43697L,\n43698L,43699L,43700L,43701L,43702L,43703L,43704L,43705L,43706L,43707L,\n43708L,43709L,43710L,43711L,43712L,43713L,43714L,43715L,43716L,43717L,\n43718L,43719L,43720L,43721L,43722L,43723L,43724L,43725L,43726L,43727L,\n43728L,43729L,43730L,43731L,43732L,43733L,43734L,43735L,43736L,43737L,\n43738L,43739L,43740L,43741L,43742L,43743L,43744L,43745L,43746L,43747L,\n43748L,43749L,43750L,43751L,43752L,43753L,43754L,43755L,43756L,43757L,\n43758L,43759L,43760L,43761L,43762L,43763L,43764L,43765L,43766L,43767L,\n43768L,43769L,43770L,43771L,43772L,43773L,43774L,43775L,43776L,43777L,\n43778L,43779L,43780L,43781L,43782L,43783L,43784L,43785L,43786L,43787L,\n43788L,43789L,43790L,43791L,43792L,43793L,43794L,43795L,43796L,43797L,\n43798L,43799L,43800L,43801L,43802L,43803L,43804L,43805L,43806L,43807L,\n43808L,43809L,43810L,43811L,43812L,43813L,43814L,43815L,43816L,43817L,\n43818L,43819L,43820L,43821L,43822L,43823L,43824L,43825L,43826L,43827L,\n43828L,43829L,43830L,43831L,43832L,43833L,43834L,43835L,43836L,43837L,\n43838L,43839L,43840L,43841L,43842L,43843L,43844L,43845L,43846L,43847L,\n43848L,43849L,43850L,43851L,43852L,43853L,43854L,43855L,43856L,43857L,\n43858L,42931L,43860L,43861L,43862L,43863L,43864L,43865L,43866L,43867L,\n43868L,43869L,43870L,43871L,43872L,43873L,43874L,43875L,43876L,43877L,\n43878L,43879L,43880L,43881L,43882L,43883L,43884L,43885L,43886L,43887L,5024,\n5025,5026,5027,5028,5029,5030,5031,5032,5033,5034,5035,5036,5037,5038,5039,\n5040,5041,5042,5043,5044,5045,5046,5047,5048,5049,5050,5051,5052,5053,5054,\n5055,5056,5057,5058,5059,5060,5061,5062,5063,5064,5065,5066,5067,5068,5069,\n5070,5071,5072,5073,5074,5075,5076,5077,5078,5079,5080,5081,5082,5083,5084,\n5085,5086,5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,\n5100,5101,5102,5103,43968L,43969L,43970L,43971L,43972L,43973L,43974L,\n43975L,43976L,43977L,43978L,43979L,43980L,43981L,43982L,43983L,43984L,\n43985L,43986L,43987L,43988L,43989L,43990L,43991L,43992L,43993L,43994L,\n43995L,43996L,43997L,43998L,43999L,44000L,44001L,44002L,44003L,44004L,\n44005L,44006L,44007L,44008L,44009L,44010L,44011L,44012L,44013L,44014L,\n44015L,44016L,44017L,44018L,44019L,44020L,44021L,44022L,44023L,44024L,\n44025L,44026L,44027L,44028L,44029L,44030L,44031L,44032L,44033L,44034L,\n44035L,44036L,44037L,44038L,44039L,44040L,44041L,44042L,44043L,44044L,\n44045L,44046L,44047L,44048L,44049L,44050L,44051L,44052L,44053L,44054L,\n44055L,44056L,44057L,44058L,44059L,44060L,44061L,44062L,44063L,44064L,\n44065L,44066L,44067L,44068L,44069L,44070L,44071L,44072L,44073L,44074L,\n44075L,44076L,44077L,44078L,44079L,44080L,44081L,44082L,44083L,44084L,\n44085L,44086L,44087L,44088L,44089L,44090L,44091L,44092L,44093L,44094L,\n44095L,44096L,44097L,44098L,44099L,44100L,44101L,44102L,44103L,44104L,\n44105L,44106L,44107L,44108L,44109L,44110L,44111L,44112L,44113L,44114L,\n44115L,44116L,44117L,44118L,44119L,44120L,44121L,44122L,44123L,44124L,\n44125L,44126L,44127L,44128L,44129L,44130L,44131L,44132L,44133L,44134L,\n44135L,44136L,44137L,44138L,44139L,44140L,44141L,44142L,44143L,44144L,\n44145L,44146L,44147L,44148L,44149L,44150L,44151L,44152L,44153L,44154L,\n44155L,44156L,44157L,44158L,44159L,44160L,44161L,44162L,44163L,44164L,\n44165L,44166L,44167L,44168L,44169L,44170L,44171L,44172L,44173L,44174L,\n44175L,44176L,44177L,44178L,44179L,44180L,44181L,44182L,44183L,44184L,\n44185L,44186L,44187L,44188L,44189L,44190L,44191L,44192L,44193L,44194L,\n44195L,44196L,44197L,44198L,44199L,44200L,44201L,44202L,44203L,44204L,\n44205L,44206L,44207L,44208L,44209L,44210L,44211L,44212L,44213L,44214L,\n44215L,44216L,44217L,44218L,44219L,44220L,44221L,44222L,44223L,44224L,\n44225L,44226L,44227L,44228L,44229L,44230L,44231L,44232L,44233L,44234L,\n44235L,44236L,44237L,44238L,44239L,44240L,44241L,44242L,44243L,44244L,\n44245L,44246L,44247L,44248L,44249L,44250L,44251L,44252L,44253L,44254L,\n44255L,44256L,44257L,44258L,44259L,44260L,44261L,44262L,44263L,44264L,\n44265L,44266L,44267L,44268L,44269L,44270L,44271L,44272L,44273L,44274L,\n44275L,44276L,44277L,44278L,44279L,44280L,44281L,44282L,44283L,44284L,\n44285L,44286L,44287L,44288L,44289L,44290L,44291L,44292L,44293L,44294L,\n44295L,44296L,44297L,44298L,44299L,44300L,44301L,44302L,44303L,44304L,\n44305L,44306L,44307L,44308L,44309L,44310L,44311L,44312L,44313L,44314L,\n44315L,44316L,44317L,44318L,44319L,44320L,44321L,44322L,44323L,44324L,\n44325L,44326L,44327L,44328L,44329L,44330L,44331L,44332L,44333L,44334L,\n44335L,44336L,44337L,44338L,44339L,44340L,44341L,44342L,44343L,44344L,\n44345L,44346L,44347L,44348L,44349L,44350L,44351L,44352L,44353L,44354L,\n44355L,44356L,44357L,44358L,44359L,44360L,44361L,44362L,44363L,44364L,\n44365L,44366L,44367L,44368L,44369L,44370L,44371L,44372L,44373L,44374L,\n44375L,44376L,44377L,44378L,44379L,44380L,44381L,44382L,44383L,44384L,\n44385L,44386L,44387L,44388L,44389L,44390L,44391L,44392L,44393L,44394L,\n44395L,44396L,44397L,44398L,44399L,44400L,44401L,44402L,44403L,44404L,\n44405L,44406L,44407L,44408L,44409L,44410L,44411L,44412L,44413L,44414L,\n44415L,44416L,44417L,44418L,44419L,44420L,44421L,44422L,44423L,44424L,\n44425L,44426L,44427L,44428L,44429L,44430L,44431L,44432L,44433L,44434L,\n44435L,44436L,44437L,44438L,44439L,44440L,44441L,44442L,44443L,44444L,\n44445L,44446L,44447L,44448L,44449L,44450L,44451L,44452L,44453L,44454L,\n44455L,44456L,44457L,44458L,44459L,44460L,44461L,44462L,44463L,44464L,\n44465L,44466L,44467L,44468L,44469L,44470L,44471L,44472L,44473L,44474L,\n44475L,44476L,44477L,44478L,44479L,44480L,44481L,44482L,44483L,44484L,\n44485L,44486L,44487L,44488L,44489L,44490L,44491L,44492L,44493L,44494L,\n44495L,44496L,44497L,44498L,44499L,44500L,44501L,44502L,44503L,44504L,\n44505L,44506L,44507L,44508L,44509L,44510L,44511L,44512L,44513L,44514L,\n44515L,44516L,44517L,44518L,44519L,44520L,44521L,44522L,44523L,44524L,\n44525L,44526L,44527L,44528L,44529L,44530L,44531L,44532L,44533L,44534L,\n44535L,44536L,44537L,44538L,44539L,44540L,44541L,44542L,44543L,44544L,\n44545L,44546L,44547L,44548L,44549L,44550L,44551L,44552L,44553L,44554L,\n44555L,44556L,44557L,44558L,44559L,44560L,44561L,44562L,44563L,44564L,\n44565L,44566L,44567L,44568L,44569L,44570L,44571L,44572L,44573L,44574L,\n44575L,44576L,44577L,44578L,44579L,44580L,44581L,44582L,44583L,44584L,\n44585L,44586L,44587L,44588L,44589L,44590L,44591L,44592L,44593L,44594L,\n44595L,44596L,44597L,44598L,44599L,44600L,44601L,44602L,44603L,44604L,\n44605L,44606L,44607L,44608L,44609L,44610L,44611L,44612L,44613L,44614L,\n44615L,44616L,44617L,44618L,44619L,44620L,44621L,44622L,44623L,44624L,\n44625L,44626L,44627L,44628L,44629L,44630L,44631L,44632L,44633L,44634L,\n44635L,44636L,44637L,44638L,44639L,44640L,44641L,44642L,44643L,44644L,\n44645L,44646L,44647L,44648L,44649L,44650L,44651L,44652L,44653L,44654L,\n44655L,44656L,44657L,44658L,44659L,44660L,44661L,44662L,44663L,44664L,\n44665L,44666L,44667L,44668L,44669L,44670L,44671L,44672L,44673L,44674L,\n44675L,44676L,44677L,44678L,44679L,44680L,44681L,44682L,44683L,44684L,\n44685L,44686L,44687L,44688L,44689L,44690L,44691L,44692L,44693L,44694L,\n44695L,44696L,44697L,44698L,44699L,44700L,44701L,44702L,44703L,44704L,\n44705L,44706L,44707L,44708L,44709L,44710L,44711L,44712L,44713L,44714L,\n44715L,44716L,44717L,44718L,44719L,44720L,44721L,44722L,44723L,44724L,\n44725L,44726L,44727L,44728L,44729L,44730L,44731L,44732L,44733L,44734L,\n44735L,44736L,44737L,44738L,44739L,44740L,44741L,44742L,44743L,44744L,\n44745L,44746L,44747L,44748L,44749L,44750L,44751L,44752L,44753L,44754L,\n44755L,44756L,44757L,44758L,44759L,44760L,44761L,44762L,44763L,44764L,\n44765L,44766L,44767L,44768L,44769L,44770L,44771L,44772L,44773L,44774L,\n44775L,44776L,44777L,44778L,44779L,44780L,44781L,44782L,44783L,44784L,\n44785L,44786L,44787L,44788L,44789L,44790L,44791L,44792L,44793L,44794L,\n44795L,44796L,44797L,44798L,44799L,44800L,44801L,44802L,44803L,44804L,\n44805L,44806L,44807L,44808L,44809L,44810L,44811L,44812L,44813L,44814L,\n44815L,44816L,44817L,44818L,44819L,44820L,44821L,44822L,44823L,44824L,\n44825L,44826L,44827L,44828L,44829L,44830L,44831L,44832L,44833L,44834L,\n44835L,44836L,44837L,44838L,44839L,44840L,44841L,44842L,44843L,44844L,\n44845L,44846L,44847L,44848L,44849L,44850L,44851L,44852L,44853L,44854L,\n44855L,44856L,44857L,44858L,44859L,44860L,44861L,44862L,44863L,44864L,\n44865L,44866L,44867L,44868L,44869L,44870L,44871L,44872L,44873L,44874L,\n44875L,44876L,44877L,44878L,44879L,44880L,44881L,44882L,44883L,44884L,\n44885L,44886L,44887L,44888L,44889L,44890L,44891L,44892L,44893L,44894L,\n44895L,44896L,44897L,44898L,44899L,44900L,44901L,44902L,44903L,44904L,\n44905L,44906L,44907L,44908L,44909L,44910L,44911L,44912L,44913L,44914L,\n44915L,44916L,44917L,44918L,44919L,44920L,44921L,44922L,44923L,44924L,\n44925L,44926L,44927L,44928L,44929L,44930L,44931L,44932L,44933L,44934L,\n44935L,44936L,44937L,44938L,44939L,44940L,44941L,44942L,44943L,44944L,\n44945L,44946L,44947L,44948L,44949L,44950L,44951L,44952L,44953L,44954L,\n44955L,44956L,44957L,44958L,44959L,44960L,44961L,44962L,44963L,44964L,\n44965L,44966L,44967L,44968L,44969L,44970L,44971L,44972L,44973L,44974L,\n44975L,44976L,44977L,44978L,44979L,44980L,44981L,44982L,44983L,44984L,\n44985L,44986L,44987L,44988L,44989L,44990L,44991L,44992L,44993L,44994L,\n44995L,44996L,44997L,44998L,44999L,45000L,45001L,45002L,45003L,45004L,\n45005L,45006L,45007L,45008L,45009L,45010L,45011L,45012L,45013L,45014L,\n45015L,45016L,45017L,45018L,45019L,45020L,45021L,45022L,45023L,45024L,\n45025L,45026L,45027L,45028L,45029L,45030L,45031L,45032L,45033L,45034L,\n45035L,45036L,45037L,45038L,45039L,45040L,45041L,45042L,45043L,45044L,\n45045L,45046L,45047L,45048L,45049L,45050L,45051L,45052L,45053L,45054L,\n45055L,45056L,45057L,45058L,45059L,45060L,45061L,45062L,45063L,45064L,\n45065L,45066L,45067L,45068L,45069L,45070L,45071L,45072L,45073L,45074L,\n45075L,45076L,45077L,45078L,45079L,45080L,45081L,45082L,45083L,45084L,\n45085L,45086L,45087L,45088L,45089L,45090L,45091L,45092L,45093L,45094L,\n45095L,45096L,45097L,45098L,45099L,45100L,45101L,45102L,45103L,45104L,\n45105L,45106L,45107L,45108L,45109L,45110L,45111L,45112L,45113L,45114L,\n45115L,45116L,45117L,45118L,45119L,45120L,45121L,45122L,45123L,45124L,\n45125L,45126L,45127L,45128L,45129L,45130L,45131L,45132L,45133L,45134L,\n45135L,45136L,45137L,45138L,45139L,45140L,45141L,45142L,45143L,45144L,\n45145L,45146L,45147L,45148L,45149L,45150L,45151L,45152L,45153L,45154L,\n45155L,45156L,45157L,45158L,45159L,45160L,45161L,45162L,45163L,45164L,\n45165L,45166L,45167L,45168L,45169L,45170L,45171L,45172L,45173L,45174L,\n45175L,45176L,45177L,45178L,45179L,45180L,45181L,45182L,45183L,45184L,\n45185L,45186L,45187L,45188L,45189L,45190L,45191L,45192L,45193L,45194L,\n45195L,45196L,45197L,45198L,45199L,45200L,45201L,45202L,45203L,45204L,\n45205L,45206L,45207L,45208L,45209L,45210L,45211L,45212L,45213L,45214L,\n45215L,45216L,45217L,45218L,45219L,45220L,45221L,45222L,45223L,45224L,\n45225L,45226L,45227L,45228L,45229L,45230L,45231L,45232L,45233L,45234L,\n45235L,45236L,45237L,45238L,45239L,45240L,45241L,45242L,45243L,45244L,\n45245L,45246L,45247L,45248L,45249L,45250L,45251L,45252L,45253L,45254L,\n45255L,45256L,45257L,45258L,45259L,45260L,45261L,45262L,45263L,45264L,\n45265L,45266L,45267L,45268L,45269L,45270L,45271L,45272L,45273L,45274L,\n45275L,45276L,45277L,45278L,45279L,45280L,45281L,45282L,45283L,45284L,\n45285L,45286L,45287L,45288L,45289L,45290L,45291L,45292L,45293L,45294L,\n45295L,45296L,45297L,45298L,45299L,45300L,45301L,45302L,45303L,45304L,\n45305L,45306L,45307L,45308L,45309L,45310L,45311L,45312L,45313L,45314L,\n45315L,45316L,45317L,45318L,45319L,45320L,45321L,45322L,45323L,45324L,\n45325L,45326L,45327L,45328L,45329L,45330L,45331L,45332L,45333L,45334L,\n45335L,45336L,45337L,45338L,45339L,45340L,45341L,45342L,45343L,45344L,\n45345L,45346L,45347L,45348L,45349L,45350L,45351L,45352L,45353L,45354L,\n45355L,45356L,45357L,45358L,45359L,45360L,45361L,45362L,45363L,45364L,\n45365L,45366L,45367L,45368L,45369L,45370L,45371L,45372L,45373L,45374L,\n45375L,45376L,45377L,45378L,45379L,45380L,45381L,45382L,45383L,45384L,\n45385L,45386L,45387L,45388L,45389L,45390L,45391L,45392L,45393L,45394L,\n45395L,45396L,45397L,45398L,45399L,45400L,45401L,45402L,45403L,45404L,\n45405L,45406L,45407L,45408L,45409L,45410L,45411L,45412L,45413L,45414L,\n45415L,45416L,45417L,45418L,45419L,45420L,45421L,45422L,45423L,45424L,\n45425L,45426L,45427L,45428L,45429L,45430L,45431L,45432L,45433L,45434L,\n45435L,45436L,45437L,45438L,45439L,45440L,45441L,45442L,45443L,45444L,\n45445L,45446L,45447L,45448L,45449L,45450L,45451L,45452L,45453L,45454L,\n45455L,45456L,45457L,45458L,45459L,45460L,45461L,45462L,45463L,45464L,\n45465L,45466L,45467L,45468L,45469L,45470L,45471L,45472L,45473L,45474L,\n45475L,45476L,45477L,45478L,45479L,45480L,45481L,45482L,45483L,45484L,\n45485L,45486L,45487L,45488L,45489L,45490L,45491L,45492L,45493L,45494L,\n45495L,45496L,45497L,45498L,45499L,45500L,45501L,45502L,45503L,45504L,\n45505L,45506L,45507L,45508L,45509L,45510L,45511L,45512L,45513L,45514L,\n45515L,45516L,45517L,45518L,45519L,45520L,45521L,45522L,45523L,45524L,\n45525L,45526L,45527L,45528L,45529L,45530L,45531L,45532L,45533L,45534L,\n45535L,45536L,45537L,45538L,45539L,45540L,45541L,45542L,45543L,45544L,\n45545L,45546L,45547L,45548L,45549L,45550L,45551L,45552L,45553L,45554L,\n45555L,45556L,45557L,45558L,45559L,45560L,45561L,45562L,45563L,45564L,\n45565L,45566L,45567L,45568L,45569L,45570L,45571L,45572L,45573L,45574L,\n45575L,45576L,45577L,45578L,45579L,45580L,45581L,45582L,45583L,45584L,\n45585L,45586L,45587L,45588L,45589L,45590L,45591L,45592L,45593L,45594L,\n45595L,45596L,45597L,45598L,45599L,45600L,45601L,45602L,45603L,45604L,\n45605L,45606L,45607L,45608L,45609L,45610L,45611L,45612L,45613L,45614L,\n45615L,45616L,45617L,45618L,45619L,45620L,45621L,45622L,45623L,45624L,\n45625L,45626L,45627L,45628L,45629L,45630L,45631L,45632L,45633L,45634L,\n45635L,45636L,45637L,45638L,45639L,45640L,45641L,45642L,45643L,45644L,\n45645L,45646L,45647L,45648L,45649L,45650L,45651L,45652L,45653L,45654L,\n45655L,45656L,45657L,45658L,45659L,45660L,45661L,45662L,45663L,45664L,\n45665L,45666L,45667L,45668L,45669L,45670L,45671L,45672L,45673L,45674L,\n45675L,45676L,45677L,45678L,45679L,45680L,45681L,45682L,45683L,45684L,\n45685L,45686L,45687L,45688L,45689L,45690L,45691L,45692L,45693L,45694L,\n45695L,45696L,45697L,45698L,45699L,45700L,45701L,45702L,45703L,45704L,\n45705L,45706L,45707L,45708L,45709L,45710L,45711L,45712L,45713L,45714L,\n45715L,45716L,45717L,45718L,45719L,45720L,45721L,45722L,45723L,45724L,\n45725L,45726L,45727L,45728L,45729L,45730L,45731L,45732L,45733L,45734L,\n45735L,45736L,45737L,45738L,45739L,45740L,45741L,45742L,45743L,45744L,\n45745L,45746L,45747L,45748L,45749L,45750L,45751L,45752L,45753L,45754L,\n45755L,45756L,45757L,45758L,45759L,45760L,45761L,45762L,45763L,45764L,\n45765L,45766L,45767L,45768L,45769L,45770L,45771L,45772L,45773L,45774L,\n45775L,45776L,45777L,45778L,45779L,45780L,45781L,45782L,45783L,45784L,\n45785L,45786L,45787L,45788L,45789L,45790L,45791L,45792L,45793L,45794L,\n45795L,45796L,45797L,45798L,45799L,45800L,45801L,45802L,45803L,45804L,\n45805L,45806L,45807L,45808L,45809L,45810L,45811L,45812L,45813L,45814L,\n45815L,45816L,45817L,45818L,45819L,45820L,45821L,45822L,45823L,45824L,\n45825L,45826L,45827L,45828L,45829L,45830L,45831L,45832L,45833L,45834L,\n45835L,45836L,45837L,45838L,45839L,45840L,45841L,45842L,45843L,45844L,\n45845L,45846L,45847L,45848L,45849L,45850L,45851L,45852L,45853L,45854L,\n45855L,45856L,45857L,45858L,45859L,45860L,45861L,45862L,45863L,45864L,\n45865L,45866L,45867L,45868L,45869L,45870L,45871L,45872L,45873L,45874L,\n45875L,45876L,45877L,45878L,45879L,45880L,45881L,45882L,45883L,45884L,\n45885L,45886L,45887L,45888L,45889L,45890L,45891L,45892L,45893L,45894L,\n45895L,45896L,45897L,45898L,45899L,45900L,45901L,45902L,45903L,45904L,\n45905L,45906L,45907L,45908L,45909L,45910L,45911L,45912L,45913L,45914L,\n45915L,45916L,45917L,45918L,45919L,45920L,45921L,45922L,45923L,45924L,\n45925L,45926L,45927L,45928L,45929L,45930L,45931L,45932L,45933L,45934L,\n45935L,45936L,45937L,45938L,45939L,45940L,45941L,45942L,45943L,45944L,\n45945L,45946L,45947L,45948L,45949L,45950L,45951L,45952L,45953L,45954L,\n45955L,45956L,45957L,45958L,45959L,45960L,45961L,45962L,45963L,45964L,\n45965L,45966L,45967L,45968L,45969L,45970L,45971L,45972L,45973L,45974L,\n45975L,45976L,45977L,45978L,45979L,45980L,45981L,45982L,45983L,45984L,\n45985L,45986L,45987L,45988L,45989L,45990L,45991L,45992L,45993L,45994L,\n45995L,45996L,45997L,45998L,45999L,46000L,46001L,46002L,46003L,46004L,\n46005L,46006L,46007L,46008L,46009L,46010L,46011L,46012L,46013L,46014L,\n46015L,46016L,46017L,46018L,46019L,46020L,46021L,46022L,46023L,46024L,\n46025L,46026L,46027L,46028L,46029L,46030L,46031L,46032L,46033L,46034L,\n46035L,46036L,46037L,46038L,46039L,46040L,46041L,46042L,46043L,46044L,\n46045L,46046L,46047L,46048L,46049L,46050L,46051L,46052L,46053L,46054L,\n46055L,46056L,46057L,46058L,46059L,46060L,46061L,46062L,46063L,46064L,\n46065L,46066L,46067L,46068L,46069L,46070L,46071L,46072L,46073L,46074L,\n46075L,46076L,46077L,46078L,46079L,46080L,46081L,46082L,46083L,46084L,\n46085L,46086L,46087L,46088L,46089L,46090L,46091L,46092L,46093L,46094L,\n46095L,46096L,46097L,46098L,46099L,46100L,46101L,46102L,46103L,46104L,\n46105L,46106L,46107L,46108L,46109L,46110L,46111L,46112L,46113L,46114L,\n46115L,46116L,46117L,46118L,46119L,46120L,46121L,46122L,46123L,46124L,\n46125L,46126L,46127L,46128L,46129L,46130L,46131L,46132L,46133L,46134L,\n46135L,46136L,46137L,46138L,46139L,46140L,46141L,46142L,46143L,46144L,\n46145L,46146L,46147L,46148L,46149L,46150L,46151L,46152L,46153L,46154L,\n46155L,46156L,46157L,46158L,46159L,46160L,46161L,46162L,46163L,46164L,\n46165L,46166L,46167L,46168L,46169L,46170L,46171L,46172L,46173L,46174L,\n46175L,46176L,46177L,46178L,46179L,46180L,46181L,46182L,46183L,46184L,\n46185L,46186L,46187L,46188L,46189L,46190L,46191L,46192L,46193L,46194L,\n46195L,46196L,46197L,46198L,46199L,46200L,46201L,46202L,46203L,46204L,\n46205L,46206L,46207L,46208L,46209L,46210L,46211L,46212L,46213L,46214L,\n46215L,46216L,46217L,46218L,46219L,46220L,46221L,46222L,46223L,46224L,\n46225L,46226L,46227L,46228L,46229L,46230L,46231L,46232L,46233L,46234L,\n46235L,46236L,46237L,46238L,46239L,46240L,46241L,46242L,46243L,46244L,\n46245L,46246L,46247L,46248L,46249L,46250L,46251L,46252L,46253L,46254L,\n46255L,46256L,46257L,46258L,46259L,46260L,46261L,46262L,46263L,46264L,\n46265L,46266L,46267L,46268L,46269L,46270L,46271L,46272L,46273L,46274L,\n46275L,46276L,46277L,46278L,46279L,46280L,46281L,46282L,46283L,46284L,\n46285L,46286L,46287L,46288L,46289L,46290L,46291L,46292L,46293L,46294L,\n46295L,46296L,46297L,46298L,46299L,46300L,46301L,46302L,46303L,46304L,\n46305L,46306L,46307L,46308L,46309L,46310L,46311L,46312L,46313L,46314L,\n46315L,46316L,46317L,46318L,46319L,46320L,46321L,46322L,46323L,46324L,\n46325L,46326L,46327L,46328L,46329L,46330L,46331L,46332L,46333L,46334L,\n46335L,46336L,46337L,46338L,46339L,46340L,46341L,46342L,46343L,46344L,\n46345L,46346L,46347L,46348L,46349L,46350L,46351L,46352L,46353L,46354L,\n46355L,46356L,46357L,46358L,46359L,46360L,46361L,46362L,46363L,46364L,\n46365L,46366L,46367L,46368L,46369L,46370L,46371L,46372L,46373L,46374L,\n46375L,46376L,46377L,46378L,46379L,46380L,46381L,46382L,46383L,46384L,\n46385L,46386L,46387L,46388L,46389L,46390L,46391L,46392L,46393L,46394L,\n46395L,46396L,46397L,46398L,46399L,46400L,46401L,46402L,46403L,46404L,\n46405L,46406L,46407L,46408L,46409L,46410L,46411L,46412L,46413L,46414L,\n46415L,46416L,46417L,46418L,46419L,46420L,46421L,46422L,46423L,46424L,\n46425L,46426L,46427L,46428L,46429L,46430L,46431L,46432L,46433L,46434L,\n46435L,46436L,46437L,46438L,46439L,46440L,46441L,46442L,46443L,46444L,\n46445L,46446L,46447L,46448L,46449L,46450L,46451L,46452L,46453L,46454L,\n46455L,46456L,46457L,46458L,46459L,46460L,46461L,46462L,46463L,46464L,\n46465L,46466L,46467L,46468L,46469L,46470L,46471L,46472L,46473L,46474L,\n46475L,46476L,46477L,46478L,46479L,46480L,46481L,46482L,46483L,46484L,\n46485L,46486L,46487L,46488L,46489L,46490L,46491L,46492L,46493L,46494L,\n46495L,46496L,46497L,46498L,46499L,46500L,46501L,46502L,46503L,46504L,\n46505L,46506L,46507L,46508L,46509L,46510L,46511L,46512L,46513L,46514L,\n46515L,46516L,46517L,46518L,46519L,46520L,46521L,46522L,46523L,46524L,\n46525L,46526L,46527L,46528L,46529L,46530L,46531L,46532L,46533L,46534L,\n46535L,46536L,46537L,46538L,46539L,46540L,46541L,46542L,46543L,46544L,\n46545L,46546L,46547L,46548L,46549L,46550L,46551L,46552L,46553L,46554L,\n46555L,46556L,46557L,46558L,46559L,46560L,46561L,46562L,46563L,46564L,\n46565L,46566L,46567L,46568L,46569L,46570L,46571L,46572L,46573L,46574L,\n46575L,46576L,46577L,46578L,46579L,46580L,46581L,46582L,46583L,46584L,\n46585L,46586L,46587L,46588L,46589L,46590L,46591L,46592L,46593L,46594L,\n46595L,46596L,46597L,46598L,46599L,46600L,46601L,46602L,46603L,46604L,\n46605L,46606L,46607L,46608L,46609L,46610L,46611L,46612L,46613L,46614L,\n46615L,46616L,46617L,46618L,46619L,46620L,46621L,46622L,46623L,46624L,\n46625L,46626L,46627L,46628L,46629L,46630L,46631L,46632L,46633L,46634L,\n46635L,46636L,46637L,46638L,46639L,46640L,46641L,46642L,46643L,46644L,\n46645L,46646L,46647L,46648L,46649L,46650L,46651L,46652L,46653L,46654L,\n46655L,46656L,46657L,46658L,46659L,46660L,46661L,46662L,46663L,46664L,\n46665L,46666L,46667L,46668L,46669L,46670L,46671L,46672L,46673L,46674L,\n46675L,46676L,46677L,46678L,46679L,46680L,46681L,46682L,46683L,46684L,\n46685L,46686L,46687L,46688L,46689L,46690L,46691L,46692L,46693L,46694L,\n46695L,46696L,46697L,46698L,46699L,46700L,46701L,46702L,46703L,46704L,\n46705L,46706L,46707L,46708L,46709L,46710L,46711L,46712L,46713L,46714L,\n46715L,46716L,46717L,46718L,46719L,46720L,46721L,46722L,46723L,46724L,\n46725L,46726L,46727L,46728L,46729L,46730L,46731L,46732L,46733L,46734L,\n46735L,46736L,46737L,46738L,46739L,46740L,46741L,46742L,46743L,46744L,\n46745L,46746L,46747L,46748L,46749L,46750L,46751L,46752L,46753L,46754L,\n46755L,46756L,46757L,46758L,46759L,46760L,46761L,46762L,46763L,46764L,\n46765L,46766L,46767L,46768L,46769L,46770L,46771L,46772L,46773L,46774L,\n46775L,46776L,46777L,46778L,46779L,46780L,46781L,46782L,46783L,46784L,\n46785L,46786L,46787L,46788L,46789L,46790L,46791L,46792L,46793L,46794L,\n46795L,46796L,46797L,46798L,46799L,46800L,46801L,46802L,46803L,46804L,\n46805L,46806L,46807L,46808L,46809L,46810L,46811L,46812L,46813L,46814L,\n46815L,46816L,46817L,46818L,46819L,46820L,46821L,46822L,46823L,46824L,\n46825L,46826L,46827L,46828L,46829L,46830L,46831L,46832L,46833L,46834L,\n46835L,46836L,46837L,46838L,46839L,46840L,46841L,46842L,46843L,46844L,\n46845L,46846L,46847L,46848L,46849L,46850L,46851L,46852L,46853L,46854L,\n46855L,46856L,46857L,46858L,46859L,46860L,46861L,46862L,46863L,46864L,\n46865L,46866L,46867L,46868L,46869L,46870L,46871L,46872L,46873L,46874L,\n46875L,46876L,46877L,46878L,46879L,46880L,46881L,46882L,46883L,46884L,\n46885L,46886L,46887L,46888L,46889L,46890L,46891L,46892L,46893L,46894L,\n46895L,46896L,46897L,46898L,46899L,46900L,46901L,46902L,46903L,46904L,\n46905L,46906L,46907L,46908L,46909L,46910L,46911L,46912L,46913L,46914L,\n46915L,46916L,46917L,46918L,46919L,46920L,46921L,46922L,46923L,46924L,\n46925L,46926L,46927L,46928L,46929L,46930L,46931L,46932L,46933L,46934L,\n46935L,46936L,46937L,46938L,46939L,46940L,46941L,46942L,46943L,46944L,\n46945L,46946L,46947L,46948L,46949L,46950L,46951L,46952L,46953L,46954L,\n46955L,46956L,46957L,46958L,46959L,46960L,46961L,46962L,46963L,46964L,\n46965L,46966L,46967L,46968L,46969L,46970L,46971L,46972L,46973L,46974L,\n46975L,46976L,46977L,46978L,46979L,46980L,46981L,46982L,46983L,46984L,\n46985L,46986L,46987L,46988L,46989L,46990L,46991L,46992L,46993L,46994L,\n46995L,46996L,46997L,46998L,46999L,47000L,47001L,47002L,47003L,47004L,\n47005L,47006L,47007L,47008L,47009L,47010L,47011L,47012L,47013L,47014L,\n47015L,47016L,47017L,47018L,47019L,47020L,47021L,47022L,47023L,47024L,\n47025L,47026L,47027L,47028L,47029L,47030L,47031L,47032L,47033L,47034L,\n47035L,47036L,47037L,47038L,47039L,47040L,47041L,47042L,47043L,47044L,\n47045L,47046L,47047L,47048L,47049L,47050L,47051L,47052L,47053L,47054L,\n47055L,47056L,47057L,47058L,47059L,47060L,47061L,47062L,47063L,47064L,\n47065L,47066L,47067L,47068L,47069L,47070L,47071L,47072L,47073L,47074L,\n47075L,47076L,47077L,47078L,47079L,47080L,47081L,47082L,47083L,47084L,\n47085L,47086L,47087L,47088L,47089L,47090L,47091L,47092L,47093L,47094L,\n47095L,47096L,47097L,47098L,47099L,47100L,47101L,47102L,47103L,47104L,\n47105L,47106L,47107L,47108L,47109L,47110L,47111L,47112L,47113L,47114L,\n47115L,47116L,47117L,47118L,47119L,47120L,47121L,47122L,47123L,47124L,\n47125L,47126L,47127L,47128L,47129L,47130L,47131L,47132L,47133L,47134L,\n47135L,47136L,47137L,47138L,47139L,47140L,47141L,47142L,47143L,47144L,\n47145L,47146L,47147L,47148L,47149L,47150L,47151L,47152L,47153L,47154L,\n47155L,47156L,47157L,47158L,47159L,47160L,47161L,47162L,47163L,47164L,\n47165L,47166L,47167L,47168L,47169L,47170L,47171L,47172L,47173L,47174L,\n47175L,47176L,47177L,47178L,47179L,47180L,47181L,47182L,47183L,47184L,\n47185L,47186L,47187L,47188L,47189L,47190L,47191L,47192L,47193L,47194L,\n47195L,47196L,47197L,47198L,47199L,47200L,47201L,47202L,47203L,47204L,\n47205L,47206L,47207L,47208L,47209L,47210L,47211L,47212L,47213L,47214L,\n47215L,47216L,47217L,47218L,47219L,47220L,47221L,47222L,47223L,47224L,\n47225L,47226L,47227L,47228L,47229L,47230L,47231L,47232L,47233L,47234L,\n47235L,47236L,47237L,47238L,47239L,47240L,47241L,47242L,47243L,47244L,\n47245L,47246L,47247L,47248L,47249L,47250L,47251L,47252L,47253L,47254L,\n47255L,47256L,47257L,47258L,47259L,47260L,47261L,47262L,47263L,47264L,\n47265L,47266L,47267L,47268L,47269L,47270L,47271L,47272L,47273L,47274L,\n47275L,47276L,47277L,47278L,47279L,47280L,47281L,47282L,47283L,47284L,\n47285L,47286L,47287L,47288L,47289L,47290L,47291L,47292L,47293L,47294L,\n47295L,47296L,47297L,47298L,47299L,47300L,47301L,47302L,47303L,47304L,\n47305L,47306L,47307L,47308L,47309L,47310L,47311L,47312L,47313L,47314L,\n47315L,47316L,47317L,47318L,47319L,47320L,47321L,47322L,47323L,47324L,\n47325L,47326L,47327L,47328L,47329L,47330L,47331L,47332L,47333L,47334L,\n47335L,47336L,47337L,47338L,47339L,47340L,47341L,47342L,47343L,47344L,\n47345L,47346L,47347L,47348L,47349L,47350L,47351L,47352L,47353L,47354L,\n47355L,47356L,47357L,47358L,47359L,47360L,47361L,47362L,47363L,47364L,\n47365L,47366L,47367L,47368L,47369L,47370L,47371L,47372L,47373L,47374L,\n47375L,47376L,47377L,47378L,47379L,47380L,47381L,47382L,47383L,47384L,\n47385L,47386L,47387L,47388L,47389L,47390L,47391L,47392L,47393L,47394L,\n47395L,47396L,47397L,47398L,47399L,47400L,47401L,47402L,47403L,47404L,\n47405L,47406L,47407L,47408L,47409L,47410L,47411L,47412L,47413L,47414L,\n47415L,47416L,47417L,47418L,47419L,47420L,47421L,47422L,47423L,47424L,\n47425L,47426L,47427L,47428L,47429L,47430L,47431L,47432L,47433L,47434L,\n47435L,47436L,47437L,47438L,47439L,47440L,47441L,47442L,47443L,47444L,\n47445L,47446L,47447L,47448L,47449L,47450L,47451L,47452L,47453L,47454L,\n47455L,47456L,47457L,47458L,47459L,47460L,47461L,47462L,47463L,47464L,\n47465L,47466L,47467L,47468L,47469L,47470L,47471L,47472L,47473L,47474L,\n47475L,47476L,47477L,47478L,47479L,47480L,47481L,47482L,47483L,47484L,\n47485L,47486L,47487L,47488L,47489L,47490L,47491L,47492L,47493L,47494L,\n47495L,47496L,47497L,47498L,47499L,47500L,47501L,47502L,47503L,47504L,\n47505L,47506L,47507L,47508L,47509L,47510L,47511L,47512L,47513L,47514L,\n47515L,47516L,47517L,47518L,47519L,47520L,47521L,47522L,47523L,47524L,\n47525L,47526L,47527L,47528L,47529L,47530L,47531L,47532L,47533L,47534L,\n47535L,47536L,47537L,47538L,47539L,47540L,47541L,47542L,47543L,47544L,\n47545L,47546L,47547L,47548L,47549L,47550L,47551L,47552L,47553L,47554L,\n47555L,47556L,47557L,47558L,47559L,47560L,47561L,47562L,47563L,47564L,\n47565L,47566L,47567L,47568L,47569L,47570L,47571L,47572L,47573L,47574L,\n47575L,47576L,47577L,47578L,47579L,47580L,47581L,47582L,47583L,47584L,\n47585L,47586L,47587L,47588L,47589L,47590L,47591L,47592L,47593L,47594L,\n47595L,47596L,47597L,47598L,47599L,47600L,47601L,47602L,47603L,47604L,\n47605L,47606L,47607L,47608L,47609L,47610L,47611L,47612L,47613L,47614L,\n47615L,47616L,47617L,47618L,47619L,47620L,47621L,47622L,47623L,47624L,\n47625L,47626L,47627L,47628L,47629L,47630L,47631L,47632L,47633L,47634L,\n47635L,47636L,47637L,47638L,47639L,47640L,47641L,47642L,47643L,47644L,\n47645L,47646L,47647L,47648L,47649L,47650L,47651L,47652L,47653L,47654L,\n47655L,47656L,47657L,47658L,47659L,47660L,47661L,47662L,47663L,47664L,\n47665L,47666L,47667L,47668L,47669L,47670L,47671L,47672L,47673L,47674L,\n47675L,47676L,47677L,47678L,47679L,47680L,47681L,47682L,47683L,47684L,\n47685L,47686L,47687L,47688L,47689L,47690L,47691L,47692L,47693L,47694L,\n47695L,47696L,47697L,47698L,47699L,47700L,47701L,47702L,47703L,47704L,\n47705L,47706L,47707L,47708L,47709L,47710L,47711L,47712L,47713L,47714L,\n47715L,47716L,47717L,47718L,47719L,47720L,47721L,47722L,47723L,47724L,\n47725L,47726L,47727L,47728L,47729L,47730L,47731L,47732L,47733L,47734L,\n47735L,47736L,47737L,47738L,47739L,47740L,47741L,47742L,47743L,47744L,\n47745L,47746L,47747L,47748L,47749L,47750L,47751L,47752L,47753L,47754L,\n47755L,47756L,47757L,47758L,47759L,47760L,47761L,47762L,47763L,47764L,\n47765L,47766L,47767L,47768L,47769L,47770L,47771L,47772L,47773L,47774L,\n47775L,47776L,47777L,47778L,47779L,47780L,47781L,47782L,47783L,47784L,\n47785L,47786L,47787L,47788L,47789L,47790L,47791L,47792L,47793L,47794L,\n47795L,47796L,47797L,47798L,47799L,47800L,47801L,47802L,47803L,47804L,\n47805L,47806L,47807L,47808L,47809L,47810L,47811L,47812L,47813L,47814L,\n47815L,47816L,47817L,47818L,47819L,47820L,47821L,47822L,47823L,47824L,\n47825L,47826L,47827L,47828L,47829L,47830L,47831L,47832L,47833L,47834L,\n47835L,47836L,47837L,47838L,47839L,47840L,47841L,47842L,47843L,47844L,\n47845L,47846L,47847L,47848L,47849L,47850L,47851L,47852L,47853L,47854L,\n47855L,47856L,47857L,47858L,47859L,47860L,47861L,47862L,47863L,47864L,\n47865L,47866L,47867L,47868L,47869L,47870L,47871L,47872L,47873L,47874L,\n47875L,47876L,47877L,47878L,47879L,47880L,47881L,47882L,47883L,47884L,\n47885L,47886L,47887L,47888L,47889L,47890L,47891L,47892L,47893L,47894L,\n47895L,47896L,47897L,47898L,47899L,47900L,47901L,47902L,47903L,47904L,\n47905L,47906L,47907L,47908L,47909L,47910L,47911L,47912L,47913L,47914L,\n47915L,47916L,47917L,47918L,47919L,47920L,47921L,47922L,47923L,47924L,\n47925L,47926L,47927L,47928L,47929L,47930L,47931L,47932L,47933L,47934L,\n47935L,47936L,47937L,47938L,47939L,47940L,47941L,47942L,47943L,47944L,\n47945L,47946L,47947L,47948L,47949L,47950L,47951L,47952L,47953L,47954L,\n47955L,47956L,47957L,47958L,47959L,47960L,47961L,47962L,47963L,47964L,\n47965L,47966L,47967L,47968L,47969L,47970L,47971L,47972L,47973L,47974L,\n47975L,47976L,47977L,47978L,47979L,47980L,47981L,47982L,47983L,47984L,\n47985L,47986L,47987L,47988L,47989L,47990L,47991L,47992L,47993L,47994L,\n47995L,47996L,47997L,47998L,47999L,48000L,48001L,48002L,48003L,48004L,\n48005L,48006L,48007L,48008L,48009L,48010L,48011L,48012L,48013L,48014L,\n48015L,48016L,48017L,48018L,48019L,48020L,48021L,48022L,48023L,48024L,\n48025L,48026L,48027L,48028L,48029L,48030L,48031L,48032L,48033L,48034L,\n48035L,48036L,48037L,48038L,48039L,48040L,48041L,48042L,48043L,48044L,\n48045L,48046L,48047L,48048L,48049L,48050L,48051L,48052L,48053L,48054L,\n48055L,48056L,48057L,48058L,48059L,48060L,48061L,48062L,48063L,48064L,\n48065L,48066L,48067L,48068L,48069L,48070L,48071L,48072L,48073L,48074L,\n48075L,48076L,48077L,48078L,48079L,48080L,48081L,48082L,48083L,48084L,\n48085L,48086L,48087L,48088L,48089L,48090L,48091L,48092L,48093L,48094L,\n48095L,48096L,48097L,48098L,48099L,48100L,48101L,48102L,48103L,48104L,\n48105L,48106L,48107L,48108L,48109L,48110L,48111L,48112L,48113L,48114L,\n48115L,48116L,48117L,48118L,48119L,48120L,48121L,48122L,48123L,48124L,\n48125L,48126L,48127L,48128L,48129L,48130L,48131L,48132L,48133L,48134L,\n48135L,48136L,48137L,48138L,48139L,48140L,48141L,48142L,48143L,48144L,\n48145L,48146L,48147L,48148L,48149L,48150L,48151L,48152L,48153L,48154L,\n48155L,48156L,48157L,48158L,48159L,48160L,48161L,48162L,48163L,48164L,\n48165L,48166L,48167L,48168L,48169L,48170L,48171L,48172L,48173L,48174L,\n48175L,48176L,48177L,48178L,48179L,48180L,48181L,48182L,48183L,48184L,\n48185L,48186L,48187L,48188L,48189L,48190L,48191L,48192L,48193L,48194L,\n48195L,48196L,48197L,48198L,48199L,48200L,48201L,48202L,48203L,48204L,\n48205L,48206L,48207L,48208L,48209L,48210L,48211L,48212L,48213L,48214L,\n48215L,48216L,48217L,48218L,48219L,48220L,48221L,48222L,48223L,48224L,\n48225L,48226L,48227L,48228L,48229L,48230L,48231L,48232L,48233L,48234L,\n48235L,48236L,48237L,48238L,48239L,48240L,48241L,48242L,48243L,48244L,\n48245L,48246L,48247L,48248L,48249L,48250L,48251L,48252L,48253L,48254L,\n48255L,48256L,48257L,48258L,48259L,48260L,48261L,48262L,48263L,48264L,\n48265L,48266L,48267L,48268L,48269L,48270L,48271L,48272L,48273L,48274L,\n48275L,48276L,48277L,48278L,48279L,48280L,48281L,48282L,48283L,48284L,\n48285L,48286L,48287L,48288L,48289L,48290L,48291L,48292L,48293L,48294L,\n48295L,48296L,48297L,48298L,48299L,48300L,48301L,48302L,48303L,48304L,\n48305L,48306L,48307L,48308L,48309L,48310L,48311L,48312L,48313L,48314L,\n48315L,48316L,48317L,48318L,48319L,48320L,48321L,48322L,48323L,48324L,\n48325L,48326L,48327L,48328L,48329L,48330L,48331L,48332L,48333L,48334L,\n48335L,48336L,48337L,48338L,48339L,48340L,48341L,48342L,48343L,48344L,\n48345L,48346L,48347L,48348L,48349L,48350L,48351L,48352L,48353L,48354L,\n48355L,48356L,48357L,48358L,48359L,48360L,48361L,48362L,48363L,48364L,\n48365L,48366L,48367L,48368L,48369L,48370L,48371L,48372L,48373L,48374L,\n48375L,48376L,48377L,48378L,48379L,48380L,48381L,48382L,48383L,48384L,\n48385L,48386L,48387L,48388L,48389L,48390L,48391L,48392L,48393L,48394L,\n48395L,48396L,48397L,48398L,48399L,48400L,48401L,48402L,48403L,48404L,\n48405L,48406L,48407L,48408L,48409L,48410L,48411L,48412L,48413L,48414L,\n48415L,48416L,48417L,48418L,48419L,48420L,48421L,48422L,48423L,48424L,\n48425L,48426L,48427L,48428L,48429L,48430L,48431L,48432L,48433L,48434L,\n48435L,48436L,48437L,48438L,48439L,48440L,48441L,48442L,48443L,48444L,\n48445L,48446L,48447L,48448L,48449L,48450L,48451L,48452L,48453L,48454L,\n48455L,48456L,48457L,48458L,48459L,48460L,48461L,48462L,48463L,48464L,\n48465L,48466L,48467L,48468L,48469L,48470L,48471L,48472L,48473L,48474L,\n48475L,48476L,48477L,48478L,48479L,48480L,48481L,48482L,48483L,48484L,\n48485L,48486L,48487L,48488L,48489L,48490L,48491L,48492L,48493L,48494L,\n48495L,48496L,48497L,48498L,48499L,48500L,48501L,48502L,48503L,48504L,\n48505L,48506L,48507L,48508L,48509L,48510L,48511L,48512L,48513L,48514L,\n48515L,48516L,48517L,48518L,48519L,48520L,48521L,48522L,48523L,48524L,\n48525L,48526L,48527L,48528L,48529L,48530L,48531L,48532L,48533L,48534L,\n48535L,48536L,48537L,48538L,48539L,48540L,48541L,48542L,48543L,48544L,\n48545L,48546L,48547L,48548L,48549L,48550L,48551L,48552L,48553L,48554L,\n48555L,48556L,48557L,48558L,48559L,48560L,48561L,48562L,48563L,48564L,\n48565L,48566L,48567L,48568L,48569L,48570L,48571L,48572L,48573L,48574L,\n48575L,48576L,48577L,48578L,48579L,48580L,48581L,48582L,48583L,48584L,\n48585L,48586L,48587L,48588L,48589L,48590L,48591L,48592L,48593L,48594L,\n48595L,48596L,48597L,48598L,48599L,48600L,48601L,48602L,48603L,48604L,\n48605L,48606L,48607L,48608L,48609L,48610L,48611L,48612L,48613L,48614L,\n48615L,48616L,48617L,48618L,48619L,48620L,48621L,48622L,48623L,48624L,\n48625L,48626L,48627L,48628L,48629L,48630L,48631L,48632L,48633L,48634L,\n48635L,48636L,48637L,48638L,48639L,48640L,48641L,48642L,48643L,48644L,\n48645L,48646L,48647L,48648L,48649L,48650L,48651L,48652L,48653L,48654L,\n48655L,48656L,48657L,48658L,48659L,48660L,48661L,48662L,48663L,48664L,\n48665L,48666L,48667L,48668L,48669L,48670L,48671L,48672L,48673L,48674L,\n48675L,48676L,48677L,48678L,48679L,48680L,48681L,48682L,48683L,48684L,\n48685L,48686L,48687L,48688L,48689L,48690L,48691L,48692L,48693L,48694L,\n48695L,48696L,48697L,48698L,48699L,48700L,48701L,48702L,48703L,48704L,\n48705L,48706L,48707L,48708L,48709L,48710L,48711L,48712L,48713L,48714L,\n48715L,48716L,48717L,48718L,48719L,48720L,48721L,48722L,48723L,48724L,\n48725L,48726L,48727L,48728L,48729L,48730L,48731L,48732L,48733L,48734L,\n48735L,48736L,48737L,48738L,48739L,48740L,48741L,48742L,48743L,48744L,\n48745L,48746L,48747L,48748L,48749L,48750L,48751L,48752L,48753L,48754L,\n48755L,48756L,48757L,48758L,48759L,48760L,48761L,48762L,48763L,48764L,\n48765L,48766L,48767L,48768L,48769L,48770L,48771L,48772L,48773L,48774L,\n48775L,48776L,48777L,48778L,48779L,48780L,48781L,48782L,48783L,48784L,\n48785L,48786L,48787L,48788L,48789L,48790L,48791L,48792L,48793L,48794L,\n48795L,48796L,48797L,48798L,48799L,48800L,48801L,48802L,48803L,48804L,\n48805L,48806L,48807L,48808L,48809L,48810L,48811L,48812L,48813L,48814L,\n48815L,48816L,48817L,48818L,48819L,48820L,48821L,48822L,48823L,48824L,\n48825L,48826L,48827L,48828L,48829L,48830L,48831L,48832L,48833L,48834L,\n48835L,48836L,48837L,48838L,48839L,48840L,48841L,48842L,48843L,48844L,\n48845L,48846L,48847L,48848L,48849L,48850L,48851L,48852L,48853L,48854L,\n48855L,48856L,48857L,48858L,48859L,48860L,48861L,48862L,48863L,48864L,\n48865L,48866L,48867L,48868L,48869L,48870L,48871L,48872L,48873L,48874L,\n48875L,48876L,48877L,48878L,48879L,48880L,48881L,48882L,48883L,48884L,\n48885L,48886L,48887L,48888L,48889L,48890L,48891L,48892L,48893L,48894L,\n48895L,48896L,48897L,48898L,48899L,48900L,48901L,48902L,48903L,48904L,\n48905L,48906L,48907L,48908L,48909L,48910L,48911L,48912L,48913L,48914L,\n48915L,48916L,48917L,48918L,48919L,48920L,48921L,48922L,48923L,48924L,\n48925L,48926L,48927L,48928L,48929L,48930L,48931L,48932L,48933L,48934L,\n48935L,48936L,48937L,48938L,48939L,48940L,48941L,48942L,48943L,48944L,\n48945L,48946L,48947L,48948L,48949L,48950L,48951L,48952L,48953L,48954L,\n48955L,48956L,48957L,48958L,48959L,48960L,48961L,48962L,48963L,48964L,\n48965L,48966L,48967L,48968L,48969L,48970L,48971L,48972L,48973L,48974L,\n48975L,48976L,48977L,48978L,48979L,48980L,48981L,48982L,48983L,48984L,\n48985L,48986L,48987L,48988L,48989L,48990L,48991L,48992L,48993L,48994L,\n48995L,48996L,48997L,48998L,48999L,49000L,49001L,49002L,49003L,49004L,\n49005L,49006L,49007L,49008L,49009L,49010L,49011L,49012L,49013L,49014L,\n49015L,49016L,49017L,49018L,49019L,49020L,49021L,49022L,49023L,49024L,\n49025L,49026L,49027L,49028L,49029L,49030L,49031L,49032L,49033L,49034L,\n49035L,49036L,49037L,49038L,49039L,49040L,49041L,49042L,49043L,49044L,\n49045L,49046L,49047L,49048L,49049L,49050L,49051L,49052L,49053L,49054L,\n49055L,49056L,49057L,49058L,49059L,49060L,49061L,49062L,49063L,49064L,\n49065L,49066L,49067L,49068L,49069L,49070L,49071L,49072L,49073L,49074L,\n49075L,49076L,49077L,49078L,49079L,49080L,49081L,49082L,49083L,49084L,\n49085L,49086L,49087L,49088L,49089L,49090L,49091L,49092L,49093L,49094L,\n49095L,49096L,49097L,49098L,49099L,49100L,49101L,49102L,49103L,49104L,\n49105L,49106L,49107L,49108L,49109L,49110L,49111L,49112L,49113L,49114L,\n49115L,49116L,49117L,49118L,49119L,49120L,49121L,49122L,49123L,49124L,\n49125L,49126L,49127L,49128L,49129L,49130L,49131L,49132L,49133L,49134L,\n49135L,49136L,49137L,49138L,49139L,49140L,49141L,49142L,49143L,49144L,\n49145L,49146L,49147L,49148L,49149L,49150L,49151L,49152L,49153L,49154L,\n49155L,49156L,49157L,49158L,49159L,49160L,49161L,49162L,49163L,49164L,\n49165L,49166L,49167L,49168L,49169L,49170L,49171L,49172L,49173L,49174L,\n49175L,49176L,49177L,49178L,49179L,49180L,49181L,49182L,49183L,49184L,\n49185L,49186L,49187L,49188L,49189L,49190L,49191L,49192L,49193L,49194L,\n49195L,49196L,49197L,49198L,49199L,49200L,49201L,49202L,49203L,49204L,\n49205L,49206L,49207L,49208L,49209L,49210L,49211L,49212L,49213L,49214L,\n49215L,49216L,49217L,49218L,49219L,49220L,49221L,49222L,49223L,49224L,\n49225L,49226L,49227L,49228L,49229L,49230L,49231L,49232L,49233L,49234L,\n49235L,49236L,49237L,49238L,49239L,49240L,49241L,49242L,49243L,49244L,\n49245L,49246L,49247L,49248L,49249L,49250L,49251L,49252L,49253L,49254L,\n49255L,49256L,49257L,49258L,49259L,49260L,49261L,49262L,49263L,49264L,\n49265L,49266L,49267L,49268L,49269L,49270L,49271L,49272L,49273L,49274L,\n49275L,49276L,49277L,49278L,49279L,49280L,49281L,49282L,49283L,49284L,\n49285L,49286L,49287L,49288L,49289L,49290L,49291L,49292L,49293L,49294L,\n49295L,49296L,49297L,49298L,49299L,49300L,49301L,49302L,49303L,49304L,\n49305L,49306L,49307L,49308L,49309L,49310L,49311L,49312L,49313L,49314L,\n49315L,49316L,49317L,49318L,49319L,49320L,49321L,49322L,49323L,49324L,\n49325L,49326L,49327L,49328L,49329L,49330L,49331L,49332L,49333L,49334L,\n49335L,49336L,49337L,49338L,49339L,49340L,49341L,49342L,49343L,49344L,\n49345L,49346L,49347L,49348L,49349L,49350L,49351L,49352L,49353L,49354L,\n49355L,49356L,49357L,49358L,49359L,49360L,49361L,49362L,49363L,49364L,\n49365L,49366L,49367L,49368L,49369L,49370L,49371L,49372L,49373L,49374L,\n49375L,49376L,49377L,49378L,49379L,49380L,49381L,49382L,49383L,49384L,\n49385L,49386L,49387L,49388L,49389L,49390L,49391L,49392L,49393L,49394L,\n49395L,49396L,49397L,49398L,49399L,49400L,49401L,49402L,49403L,49404L,\n49405L,49406L,49407L,49408L,49409L,49410L,49411L,49412L,49413L,49414L,\n49415L,49416L,49417L,49418L,49419L,49420L,49421L,49422L,49423L,49424L,\n49425L,49426L,49427L,49428L,49429L,49430L,49431L,49432L,49433L,49434L,\n49435L,49436L,49437L,49438L,49439L,49440L,49441L,49442L,49443L,49444L,\n49445L,49446L,49447L,49448L,49449L,49450L,49451L,49452L,49453L,49454L,\n49455L,49456L,49457L,49458L,49459L,49460L,49461L,49462L,49463L,49464L,\n49465L,49466L,49467L,49468L,49469L,49470L,49471L,49472L,49473L,49474L,\n49475L,49476L,49477L,49478L,49479L,49480L,49481L,49482L,49483L,49484L,\n49485L,49486L,49487L,49488L,49489L,49490L,49491L,49492L,49493L,49494L,\n49495L,49496L,49497L,49498L,49499L,49500L,49501L,49502L,49503L,49504L,\n49505L,49506L,49507L,49508L,49509L,49510L,49511L,49512L,49513L,49514L,\n49515L,49516L,49517L,49518L,49519L,49520L,49521L,49522L,49523L,49524L,\n49525L,49526L,49527L,49528L,49529L,49530L,49531L,49532L,49533L,49534L,\n49535L,49536L,49537L,49538L,49539L,49540L,49541L,49542L,49543L,49544L,\n49545L,49546L,49547L,49548L,49549L,49550L,49551L,49552L,49553L,49554L,\n49555L,49556L,49557L,49558L,49559L,49560L,49561L,49562L,49563L,49564L,\n49565L,49566L,49567L,49568L,49569L,49570L,49571L,49572L,49573L,49574L,\n49575L,49576L,49577L,49578L,49579L,49580L,49581L,49582L,49583L,49584L,\n49585L,49586L,49587L,49588L,49589L,49590L,49591L,49592L,49593L,49594L,\n49595L,49596L,49597L,49598L,49599L,49600L,49601L,49602L,49603L,49604L,\n49605L,49606L,49607L,49608L,49609L,49610L,49611L,49612L,49613L,49614L,\n49615L,49616L,49617L,49618L,49619L,49620L,49621L,49622L,49623L,49624L,\n49625L,49626L,49627L,49628L,49629L,49630L,49631L,49632L,49633L,49634L,\n49635L,49636L,49637L,49638L,49639L,49640L,49641L,49642L,49643L,49644L,\n49645L,49646L,49647L,49648L,49649L,49650L,49651L,49652L,49653L,49654L,\n49655L,49656L,49657L,49658L,49659L,49660L,49661L,49662L,49663L,49664L,\n49665L,49666L,49667L,49668L,49669L,49670L,49671L,49672L,49673L,49674L,\n49675L,49676L,49677L,49678L,49679L,49680L,49681L,49682L,49683L,49684L,\n49685L,49686L,49687L,49688L,49689L,49690L,49691L,49692L,49693L,49694L,\n49695L,49696L,49697L,49698L,49699L,49700L,49701L,49702L,49703L,49704L,\n49705L,49706L,49707L,49708L,49709L,49710L,49711L,49712L,49713L,49714L,\n49715L,49716L,49717L,49718L,49719L,49720L,49721L,49722L,49723L,49724L,\n49725L,49726L,49727L,49728L,49729L,49730L,49731L,49732L,49733L,49734L,\n49735L,49736L,49737L,49738L,49739L,49740L,49741L,49742L,49743L,49744L,\n49745L,49746L,49747L,49748L,49749L,49750L,49751L,49752L,49753L,49754L,\n49755L,49756L,49757L,49758L,49759L,49760L,49761L,49762L,49763L,49764L,\n49765L,49766L,49767L,49768L,49769L,49770L,49771L,49772L,49773L,49774L,\n49775L,49776L,49777L,49778L,49779L,49780L,49781L,49782L,49783L,49784L,\n49785L,49786L,49787L,49788L,49789L,49790L,49791L,49792L,49793L,49794L,\n49795L,49796L,49797L,49798L,49799L,49800L,49801L,49802L,49803L,49804L,\n49805L,49806L,49807L,49808L,49809L,49810L,49811L,49812L,49813L,49814L,\n49815L,49816L,49817L,49818L,49819L,49820L,49821L,49822L,49823L,49824L,\n49825L,49826L,49827L,49828L,49829L,49830L,49831L,49832L,49833L,49834L,\n49835L,49836L,49837L,49838L,49839L,49840L,49841L,49842L,49843L,49844L,\n49845L,49846L,49847L,49848L,49849L,49850L,49851L,49852L,49853L,49854L,\n49855L,49856L,49857L,49858L,49859L,49860L,49861L,49862L,49863L,49864L,\n49865L,49866L,49867L,49868L,49869L,49870L,49871L,49872L,49873L,49874L,\n49875L,49876L,49877L,49878L,49879L,49880L,49881L,49882L,49883L,49884L,\n49885L,49886L,49887L,49888L,49889L,49890L,49891L,49892L,49893L,49894L,\n49895L,49896L,49897L,49898L,49899L,49900L,49901L,49902L,49903L,49904L,\n49905L,49906L,49907L,49908L,49909L,49910L,49911L,49912L,49913L,49914L,\n49915L,49916L,49917L,49918L,49919L,49920L,49921L,49922L,49923L,49924L,\n49925L,49926L,49927L,49928L,49929L,49930L,49931L,49932L,49933L,49934L,\n49935L,49936L,49937L,49938L,49939L,49940L,49941L,49942L,49943L,49944L,\n49945L,49946L,49947L,49948L,49949L,49950L,49951L,49952L,49953L,49954L,\n49955L,49956L,49957L,49958L,49959L,49960L,49961L,49962L,49963L,49964L,\n49965L,49966L,49967L,49968L,49969L,49970L,49971L,49972L,49973L,49974L,\n49975L,49976L,49977L,49978L,49979L,49980L,49981L,49982L,49983L,49984L,\n49985L,49986L,49987L,49988L,49989L,49990L,49991L,49992L,49993L,49994L,\n49995L,49996L,49997L,49998L,49999L,50000L,50001L,50002L,50003L,50004L,\n50005L,50006L,50007L,50008L,50009L,50010L,50011L,50012L,50013L,50014L,\n50015L,50016L,50017L,50018L,50019L,50020L,50021L,50022L,50023L,50024L,\n50025L,50026L,50027L,50028L,50029L,50030L,50031L,50032L,50033L,50034L,\n50035L,50036L,50037L,50038L,50039L,50040L,50041L,50042L,50043L,50044L,\n50045L,50046L,50047L,50048L,50049L,50050L,50051L,50052L,50053L,50054L,\n50055L,50056L,50057L,50058L,50059L,50060L,50061L,50062L,50063L,50064L,\n50065L,50066L,50067L,50068L,50069L,50070L,50071L,50072L,50073L,50074L,\n50075L,50076L,50077L,50078L,50079L,50080L,50081L,50082L,50083L,50084L,\n50085L,50086L,50087L,50088L,50089L,50090L,50091L,50092L,50093L,50094L,\n50095L,50096L,50097L,50098L,50099L,50100L,50101L,50102L,50103L,50104L,\n50105L,50106L,50107L,50108L,50109L,50110L,50111L,50112L,50113L,50114L,\n50115L,50116L,50117L,50118L,50119L,50120L,50121L,50122L,50123L,50124L,\n50125L,50126L,50127L,50128L,50129L,50130L,50131L,50132L,50133L,50134L,\n50135L,50136L,50137L,50138L,50139L,50140L,50141L,50142L,50143L,50144L,\n50145L,50146L,50147L,50148L,50149L,50150L,50151L,50152L,50153L,50154L,\n50155L,50156L,50157L,50158L,50159L,50160L,50161L,50162L,50163L,50164L,\n50165L,50166L,50167L,50168L,50169L,50170L,50171L,50172L,50173L,50174L,\n50175L,50176L,50177L,50178L,50179L,50180L,50181L,50182L,50183L,50184L,\n50185L,50186L,50187L,50188L,50189L,50190L,50191L,50192L,50193L,50194L,\n50195L,50196L,50197L,50198L,50199L,50200L,50201L,50202L,50203L,50204L,\n50205L,50206L,50207L,50208L,50209L,50210L,50211L,50212L,50213L,50214L,\n50215L,50216L,50217L,50218L,50219L,50220L,50221L,50222L,50223L,50224L,\n50225L,50226L,50227L,50228L,50229L,50230L,50231L,50232L,50233L,50234L,\n50235L,50236L,50237L,50238L,50239L,50240L,50241L,50242L,50243L,50244L,\n50245L,50246L,50247L,50248L,50249L,50250L,50251L,50252L,50253L,50254L,\n50255L,50256L,50257L,50258L,50259L,50260L,50261L,50262L,50263L,50264L,\n50265L,50266L,50267L,50268L,50269L,50270L,50271L,50272L,50273L,50274L,\n50275L,50276L,50277L,50278L,50279L,50280L,50281L,50282L,50283L,50284L,\n50285L,50286L,50287L,50288L,50289L,50290L,50291L,50292L,50293L,50294L,\n50295L,50296L,50297L,50298L,50299L,50300L,50301L,50302L,50303L,50304L,\n50305L,50306L,50307L,50308L,50309L,50310L,50311L,50312L,50313L,50314L,\n50315L,50316L,50317L,50318L,50319L,50320L,50321L,50322L,50323L,50324L,\n50325L,50326L,50327L,50328L,50329L,50330L,50331L,50332L,50333L,50334L,\n50335L,50336L,50337L,50338L,50339L,50340L,50341L,50342L,50343L,50344L,\n50345L,50346L,50347L,50348L,50349L,50350L,50351L,50352L,50353L,50354L,\n50355L,50356L,50357L,50358L,50359L,50360L,50361L,50362L,50363L,50364L,\n50365L,50366L,50367L,50368L,50369L,50370L,50371L,50372L,50373L,50374L,\n50375L,50376L,50377L,50378L,50379L,50380L,50381L,50382L,50383L,50384L,\n50385L,50386L,50387L,50388L,50389L,50390L,50391L,50392L,50393L,50394L,\n50395L,50396L,50397L,50398L,50399L,50400L,50401L,50402L,50403L,50404L,\n50405L,50406L,50407L,50408L,50409L,50410L,50411L,50412L,50413L,50414L,\n50415L,50416L,50417L,50418L,50419L,50420L,50421L,50422L,50423L,50424L,\n50425L,50426L,50427L,50428L,50429L,50430L,50431L,50432L,50433L,50434L,\n50435L,50436L,50437L,50438L,50439L,50440L,50441L,50442L,50443L,50444L,\n50445L,50446L,50447L,50448L,50449L,50450L,50451L,50452L,50453L,50454L,\n50455L,50456L,50457L,50458L,50459L,50460L,50461L,50462L,50463L,50464L,\n50465L,50466L,50467L,50468L,50469L,50470L,50471L,50472L,50473L,50474L,\n50475L,50476L,50477L,50478L,50479L,50480L,50481L,50482L,50483L,50484L,\n50485L,50486L,50487L,50488L,50489L,50490L,50491L,50492L,50493L,50494L,\n50495L,50496L,50497L,50498L,50499L,50500L,50501L,50502L,50503L,50504L,\n50505L,50506L,50507L,50508L,50509L,50510L,50511L,50512L,50513L,50514L,\n50515L,50516L,50517L,50518L,50519L,50520L,50521L,50522L,50523L,50524L,\n50525L,50526L,50527L,50528L,50529L,50530L,50531L,50532L,50533L,50534L,\n50535L,50536L,50537L,50538L,50539L,50540L,50541L,50542L,50543L,50544L,\n50545L,50546L,50547L,50548L,50549L,50550L,50551L,50552L,50553L,50554L,\n50555L,50556L,50557L,50558L,50559L,50560L,50561L,50562L,50563L,50564L,\n50565L,50566L,50567L,50568L,50569L,50570L,50571L,50572L,50573L,50574L,\n50575L,50576L,50577L,50578L,50579L,50580L,50581L,50582L,50583L,50584L,\n50585L,50586L,50587L,50588L,50589L,50590L,50591L,50592L,50593L,50594L,\n50595L,50596L,50597L,50598L,50599L,50600L,50601L,50602L,50603L,50604L,\n50605L,50606L,50607L,50608L,50609L,50610L,50611L,50612L,50613L,50614L,\n50615L,50616L,50617L,50618L,50619L,50620L,50621L,50622L,50623L,50624L,\n50625L,50626L,50627L,50628L,50629L,50630L,50631L,50632L,50633L,50634L,\n50635L,50636L,50637L,50638L,50639L,50640L,50641L,50642L,50643L,50644L,\n50645L,50646L,50647L,50648L,50649L,50650L,50651L,50652L,50653L,50654L,\n50655L,50656L,50657L,50658L,50659L,50660L,50661L,50662L,50663L,50664L,\n50665L,50666L,50667L,50668L,50669L,50670L,50671L,50672L,50673L,50674L,\n50675L,50676L,50677L,50678L,50679L,50680L,50681L,50682L,50683L,50684L,\n50685L,50686L,50687L,50688L,50689L,50690L,50691L,50692L,50693L,50694L,\n50695L,50696L,50697L,50698L,50699L,50700L,50701L,50702L,50703L,50704L,\n50705L,50706L,50707L,50708L,50709L,50710L,50711L,50712L,50713L,50714L,\n50715L,50716L,50717L,50718L,50719L,50720L,50721L,50722L,50723L,50724L,\n50725L,50726L,50727L,50728L,50729L,50730L,50731L,50732L,50733L,50734L,\n50735L,50736L,50737L,50738L,50739L,50740L,50741L,50742L,50743L,50744L,\n50745L,50746L,50747L,50748L,50749L,50750L,50751L,50752L,50753L,50754L,\n50755L,50756L,50757L,50758L,50759L,50760L,50761L,50762L,50763L,50764L,\n50765L,50766L,50767L,50768L,50769L,50770L,50771L,50772L,50773L,50774L,\n50775L,50776L,50777L,50778L,50779L,50780L,50781L,50782L,50783L,50784L,\n50785L,50786L,50787L,50788L,50789L,50790L,50791L,50792L,50793L,50794L,\n50795L,50796L,50797L,50798L,50799L,50800L,50801L,50802L,50803L,50804L,\n50805L,50806L,50807L,50808L,50809L,50810L,50811L,50812L,50813L,50814L,\n50815L,50816L,50817L,50818L,50819L,50820L,50821L,50822L,50823L,50824L,\n50825L,50826L,50827L,50828L,50829L,50830L,50831L,50832L,50833L,50834L,\n50835L,50836L,50837L,50838L,50839L,50840L,50841L,50842L,50843L,50844L,\n50845L,50846L,50847L,50848L,50849L,50850L,50851L,50852L,50853L,50854L,\n50855L,50856L,50857L,50858L,50859L,50860L,50861L,50862L,50863L,50864L,\n50865L,50866L,50867L,50868L,50869L,50870L,50871L,50872L,50873L,50874L,\n50875L,50876L,50877L,50878L,50879L,50880L,50881L,50882L,50883L,50884L,\n50885L,50886L,50887L,50888L,50889L,50890L,50891L,50892L,50893L,50894L,\n50895L,50896L,50897L,50898L,50899L,50900L,50901L,50902L,50903L,50904L,\n50905L,50906L,50907L,50908L,50909L,50910L,50911L,50912L,50913L,50914L,\n50915L,50916L,50917L,50918L,50919L,50920L,50921L,50922L,50923L,50924L,\n50925L,50926L,50927L,50928L,50929L,50930L,50931L,50932L,50933L,50934L,\n50935L,50936L,50937L,50938L,50939L,50940L,50941L,50942L,50943L,50944L,\n50945L,50946L,50947L,50948L,50949L,50950L,50951L,50952L,50953L,50954L,\n50955L,50956L,50957L,50958L,50959L,50960L,50961L,50962L,50963L,50964L,\n50965L,50966L,50967L,50968L,50969L,50970L,50971L,50972L,50973L,50974L,\n50975L,50976L,50977L,50978L,50979L,50980L,50981L,50982L,50983L,50984L,\n50985L,50986L,50987L,50988L,50989L,50990L,50991L,50992L,50993L,50994L,\n50995L,50996L,50997L,50998L,50999L,51000L,51001L,51002L,51003L,51004L,\n51005L,51006L,51007L,51008L,51009L,51010L,51011L,51012L,51013L,51014L,\n51015L,51016L,51017L,51018L,51019L,51020L,51021L,51022L,51023L,51024L,\n51025L,51026L,51027L,51028L,51029L,51030L,51031L,51032L,51033L,51034L,\n51035L,51036L,51037L,51038L,51039L,51040L,51041L,51042L,51043L,51044L,\n51045L,51046L,51047L,51048L,51049L,51050L,51051L,51052L,51053L,51054L,\n51055L,51056L,51057L,51058L,51059L,51060L,51061L,51062L,51063L,51064L,\n51065L,51066L,51067L,51068L,51069L,51070L,51071L,51072L,51073L,51074L,\n51075L,51076L,51077L,51078L,51079L,51080L,51081L,51082L,51083L,51084L,\n51085L,51086L,51087L,51088L,51089L,51090L,51091L,51092L,51093L,51094L,\n51095L,51096L,51097L,51098L,51099L,51100L,51101L,51102L,51103L,51104L,\n51105L,51106L,51107L,51108L,51109L,51110L,51111L,51112L,51113L,51114L,\n51115L,51116L,51117L,51118L,51119L,51120L,51121L,51122L,51123L,51124L,\n51125L,51126L,51127L,51128L,51129L,51130L,51131L,51132L,51133L,51134L,\n51135L,51136L,51137L,51138L,51139L,51140L,51141L,51142L,51143L,51144L,\n51145L,51146L,51147L,51148L,51149L,51150L,51151L,51152L,51153L,51154L,\n51155L,51156L,51157L,51158L,51159L,51160L,51161L,51162L,51163L,51164L,\n51165L,51166L,51167L,51168L,51169L,51170L,51171L,51172L,51173L,51174L,\n51175L,51176L,51177L,51178L,51179L,51180L,51181L,51182L,51183L,51184L,\n51185L,51186L,51187L,51188L,51189L,51190L,51191L,51192L,51193L,51194L,\n51195L,51196L,51197L,51198L,51199L,51200L,51201L,51202L,51203L,51204L,\n51205L,51206L,51207L,51208L,51209L,51210L,51211L,51212L,51213L,51214L,\n51215L,51216L,51217L,51218L,51219L,51220L,51221L,51222L,51223L,51224L,\n51225L,51226L,51227L,51228L,51229L,51230L,51231L,51232L,51233L,51234L,\n51235L,51236L,51237L,51238L,51239L,51240L,51241L,51242L,51243L,51244L,\n51245L,51246L,51247L,51248L,51249L,51250L,51251L,51252L,51253L,51254L,\n51255L,51256L,51257L,51258L,51259L,51260L,51261L,51262L,51263L,51264L,\n51265L,51266L,51267L,51268L,51269L,51270L,51271L,51272L,51273L,51274L,\n51275L,51276L,51277L,51278L,51279L,51280L,51281L,51282L,51283L,51284L,\n51285L,51286L,51287L,51288L,51289L,51290L,51291L,51292L,51293L,51294L,\n51295L,51296L,51297L,51298L,51299L,51300L,51301L,51302L,51303L,51304L,\n51305L,51306L,51307L,51308L,51309L,51310L,51311L,51312L,51313L,51314L,\n51315L,51316L,51317L,51318L,51319L,51320L,51321L,51322L,51323L,51324L,\n51325L,51326L,51327L,51328L,51329L,51330L,51331L,51332L,51333L,51334L,\n51335L,51336L,51337L,51338L,51339L,51340L,51341L,51342L,51343L,51344L,\n51345L,51346L,51347L,51348L,51349L,51350L,51351L,51352L,51353L,51354L,\n51355L,51356L,51357L,51358L,51359L,51360L,51361L,51362L,51363L,51364L,\n51365L,51366L,51367L,51368L,51369L,51370L,51371L,51372L,51373L,51374L,\n51375L,51376L,51377L,51378L,51379L,51380L,51381L,51382L,51383L,51384L,\n51385L,51386L,51387L,51388L,51389L,51390L,51391L,51392L,51393L,51394L,\n51395L,51396L,51397L,51398L,51399L,51400L,51401L,51402L,51403L,51404L,\n51405L,51406L,51407L,51408L,51409L,51410L,51411L,51412L,51413L,51414L,\n51415L,51416L,51417L,51418L,51419L,51420L,51421L,51422L,51423L,51424L,\n51425L,51426L,51427L,51428L,51429L,51430L,51431L,51432L,51433L,51434L,\n51435L,51436L,51437L,51438L,51439L,51440L,51441L,51442L,51443L,51444L,\n51445L,51446L,51447L,51448L,51449L,51450L,51451L,51452L,51453L,51454L,\n51455L,51456L,51457L,51458L,51459L,51460L,51461L,51462L,51463L,51464L,\n51465L,51466L,51467L,51468L,51469L,51470L,51471L,51472L,51473L,51474L,\n51475L,51476L,51477L,51478L,51479L,51480L,51481L,51482L,51483L,51484L,\n51485L,51486L,51487L,51488L,51489L,51490L,51491L,51492L,51493L,51494L,\n51495L,51496L,51497L,51498L,51499L,51500L,51501L,51502L,51503L,51504L,\n51505L,51506L,51507L,51508L,51509L,51510L,51511L,51512L,51513L,51514L,\n51515L,51516L,51517L,51518L,51519L,51520L,51521L,51522L,51523L,51524L,\n51525L,51526L,51527L,51528L,51529L,51530L,51531L,51532L,51533L,51534L,\n51535L,51536L,51537L,51538L,51539L,51540L,51541L,51542L,51543L,51544L,\n51545L,51546L,51547L,51548L,51549L,51550L,51551L,51552L,51553L,51554L,\n51555L,51556L,51557L,51558L,51559L,51560L,51561L,51562L,51563L,51564L,\n51565L,51566L,51567L,51568L,51569L,51570L,51571L,51572L,51573L,51574L,\n51575L,51576L,51577L,51578L,51579L,51580L,51581L,51582L,51583L,51584L,\n51585L,51586L,51587L,51588L,51589L,51590L,51591L,51592L,51593L,51594L,\n51595L,51596L,51597L,51598L,51599L,51600L,51601L,51602L,51603L,51604L,\n51605L,51606L,51607L,51608L,51609L,51610L,51611L,51612L,51613L,51614L,\n51615L,51616L,51617L,51618L,51619L,51620L,51621L,51622L,51623L,51624L,\n51625L,51626L,51627L,51628L,51629L,51630L,51631L,51632L,51633L,51634L,\n51635L,51636L,51637L,51638L,51639L,51640L,51641L,51642L,51643L,51644L,\n51645L,51646L,51647L,51648L,51649L,51650L,51651L,51652L,51653L,51654L,\n51655L,51656L,51657L,51658L,51659L,51660L,51661L,51662L,51663L,51664L,\n51665L,51666L,51667L,51668L,51669L,51670L,51671L,51672L,51673L,51674L,\n51675L,51676L,51677L,51678L,51679L,51680L,51681L,51682L,51683L,51684L,\n51685L,51686L,51687L,51688L,51689L,51690L,51691L,51692L,51693L,51694L,\n51695L,51696L,51697L,51698L,51699L,51700L,51701L,51702L,51703L,51704L,\n51705L,51706L,51707L,51708L,51709L,51710L,51711L,51712L,51713L,51714L,\n51715L,51716L,51717L,51718L,51719L,51720L,51721L,51722L,51723L,51724L,\n51725L,51726L,51727L,51728L,51729L,51730L,51731L,51732L,51733L,51734L,\n51735L,51736L,51737L,51738L,51739L,51740L,51741L,51742L,51743L,51744L,\n51745L,51746L,51747L,51748L,51749L,51750L,51751L,51752L,51753L,51754L,\n51755L,51756L,51757L,51758L,51759L,51760L,51761L,51762L,51763L,51764L,\n51765L,51766L,51767L,51768L,51769L,51770L,51771L,51772L,51773L,51774L,\n51775L,51776L,51777L,51778L,51779L,51780L,51781L,51782L,51783L,51784L,\n51785L,51786L,51787L,51788L,51789L,51790L,51791L,51792L,51793L,51794L,\n51795L,51796L,51797L,51798L,51799L,51800L,51801L,51802L,51803L,51804L,\n51805L,51806L,51807L,51808L,51809L,51810L,51811L,51812L,51813L,51814L,\n51815L,51816L,51817L,51818L,51819L,51820L,51821L,51822L,51823L,51824L,\n51825L,51826L,51827L,51828L,51829L,51830L,51831L,51832L,51833L,51834L,\n51835L,51836L,51837L,51838L,51839L,51840L,51841L,51842L,51843L,51844L,\n51845L,51846L,51847L,51848L,51849L,51850L,51851L,51852L,51853L,51854L,\n51855L,51856L,51857L,51858L,51859L,51860L,51861L,51862L,51863L,51864L,\n51865L,51866L,51867L,51868L,51869L,51870L,51871L,51872L,51873L,51874L,\n51875L,51876L,51877L,51878L,51879L,51880L,51881L,51882L,51883L,51884L,\n51885L,51886L,51887L,51888L,51889L,51890L,51891L,51892L,51893L,51894L,\n51895L,51896L,51897L,51898L,51899L,51900L,51901L,51902L,51903L,51904L,\n51905L,51906L,51907L,51908L,51909L,51910L,51911L,51912L,51913L,51914L,\n51915L,51916L,51917L,51918L,51919L,51920L,51921L,51922L,51923L,51924L,\n51925L,51926L,51927L,51928L,51929L,51930L,51931L,51932L,51933L,51934L,\n51935L,51936L,51937L,51938L,51939L,51940L,51941L,51942L,51943L,51944L,\n51945L,51946L,51947L,51948L,51949L,51950L,51951L,51952L,51953L,51954L,\n51955L,51956L,51957L,51958L,51959L,51960L,51961L,51962L,51963L,51964L,\n51965L,51966L,51967L,51968L,51969L,51970L,51971L,51972L,51973L,51974L,\n51975L,51976L,51977L,51978L,51979L,51980L,51981L,51982L,51983L,51984L,\n51985L,51986L,51987L,51988L,51989L,51990L,51991L,51992L,51993L,51994L,\n51995L,51996L,51997L,51998L,51999L,52000L,52001L,52002L,52003L,52004L,\n52005L,52006L,52007L,52008L,52009L,52010L,52011L,52012L,52013L,52014L,\n52015L,52016L,52017L,52018L,52019L,52020L,52021L,52022L,52023L,52024L,\n52025L,52026L,52027L,52028L,52029L,52030L,52031L,52032L,52033L,52034L,\n52035L,52036L,52037L,52038L,52039L,52040L,52041L,52042L,52043L,52044L,\n52045L,52046L,52047L,52048L,52049L,52050L,52051L,52052L,52053L,52054L,\n52055L,52056L,52057L,52058L,52059L,52060L,52061L,52062L,52063L,52064L,\n52065L,52066L,52067L,52068L,52069L,52070L,52071L,52072L,52073L,52074L,\n52075L,52076L,52077L,52078L,52079L,52080L,52081L,52082L,52083L,52084L,\n52085L,52086L,52087L,52088L,52089L,52090L,52091L,52092L,52093L,52094L,\n52095L,52096L,52097L,52098L,52099L,52100L,52101L,52102L,52103L,52104L,\n52105L,52106L,52107L,52108L,52109L,52110L,52111L,52112L,52113L,52114L,\n52115L,52116L,52117L,52118L,52119L,52120L,52121L,52122L,52123L,52124L,\n52125L,52126L,52127L,52128L,52129L,52130L,52131L,52132L,52133L,52134L,\n52135L,52136L,52137L,52138L,52139L,52140L,52141L,52142L,52143L,52144L,\n52145L,52146L,52147L,52148L,52149L,52150L,52151L,52152L,52153L,52154L,\n52155L,52156L,52157L,52158L,52159L,52160L,52161L,52162L,52163L,52164L,\n52165L,52166L,52167L,52168L,52169L,52170L,52171L,52172L,52173L,52174L,\n52175L,52176L,52177L,52178L,52179L,52180L,52181L,52182L,52183L,52184L,\n52185L,52186L,52187L,52188L,52189L,52190L,52191L,52192L,52193L,52194L,\n52195L,52196L,52197L,52198L,52199L,52200L,52201L,52202L,52203L,52204L,\n52205L,52206L,52207L,52208L,52209L,52210L,52211L,52212L,52213L,52214L,\n52215L,52216L,52217L,52218L,52219L,52220L,52221L,52222L,52223L,52224L,\n52225L,52226L,52227L,52228L,52229L,52230L,52231L,52232L,52233L,52234L,\n52235L,52236L,52237L,52238L,52239L,52240L,52241L,52242L,52243L,52244L,\n52245L,52246L,52247L,52248L,52249L,52250L,52251L,52252L,52253L,52254L,\n52255L,52256L,52257L,52258L,52259L,52260L,52261L,52262L,52263L,52264L,\n52265L,52266L,52267L,52268L,52269L,52270L,52271L,52272L,52273L,52274L,\n52275L,52276L,52277L,52278L,52279L,52280L,52281L,52282L,52283L,52284L,\n52285L,52286L,52287L,52288L,52289L,52290L,52291L,52292L,52293L,52294L,\n52295L,52296L,52297L,52298L,52299L,52300L,52301L,52302L,52303L,52304L,\n52305L,52306L,52307L,52308L,52309L,52310L,52311L,52312L,52313L,52314L,\n52315L,52316L,52317L,52318L,52319L,52320L,52321L,52322L,52323L,52324L,\n52325L,52326L,52327L,52328L,52329L,52330L,52331L,52332L,52333L,52334L,\n52335L,52336L,52337L,52338L,52339L,52340L,52341L,52342L,52343L,52344L,\n52345L,52346L,52347L,52348L,52349L,52350L,52351L,52352L,52353L,52354L,\n52355L,52356L,52357L,52358L,52359L,52360L,52361L,52362L,52363L,52364L,\n52365L,52366L,52367L,52368L,52369L,52370L,52371L,52372L,52373L,52374L,\n52375L,52376L,52377L,52378L,52379L,52380L,52381L,52382L,52383L,52384L,\n52385L,52386L,52387L,52388L,52389L,52390L,52391L,52392L,52393L,52394L,\n52395L,52396L,52397L,52398L,52399L,52400L,52401L,52402L,52403L,52404L,\n52405L,52406L,52407L,52408L,52409L,52410L,52411L,52412L,52413L,52414L,\n52415L,52416L,52417L,52418L,52419L,52420L,52421L,52422L,52423L,52424L,\n52425L,52426L,52427L,52428L,52429L,52430L,52431L,52432L,52433L,52434L,\n52435L,52436L,52437L,52438L,52439L,52440L,52441L,52442L,52443L,52444L,\n52445L,52446L,52447L,52448L,52449L,52450L,52451L,52452L,52453L,52454L,\n52455L,52456L,52457L,52458L,52459L,52460L,52461L,52462L,52463L,52464L,\n52465L,52466L,52467L,52468L,52469L,52470L,52471L,52472L,52473L,52474L,\n52475L,52476L,52477L,52478L,52479L,52480L,52481L,52482L,52483L,52484L,\n52485L,52486L,52487L,52488L,52489L,52490L,52491L,52492L,52493L,52494L,\n52495L,52496L,52497L,52498L,52499L,52500L,52501L,52502L,52503L,52504L,\n52505L,52506L,52507L,52508L,52509L,52510L,52511L,52512L,52513L,52514L,\n52515L,52516L,52517L,52518L,52519L,52520L,52521L,52522L,52523L,52524L,\n52525L,52526L,52527L,52528L,52529L,52530L,52531L,52532L,52533L,52534L,\n52535L,52536L,52537L,52538L,52539L,52540L,52541L,52542L,52543L,52544L,\n52545L,52546L,52547L,52548L,52549L,52550L,52551L,52552L,52553L,52554L,\n52555L,52556L,52557L,52558L,52559L,52560L,52561L,52562L,52563L,52564L,\n52565L,52566L,52567L,52568L,52569L,52570L,52571L,52572L,52573L,52574L,\n52575L,52576L,52577L,52578L,52579L,52580L,52581L,52582L,52583L,52584L,\n52585L,52586L,52587L,52588L,52589L,52590L,52591L,52592L,52593L,52594L,\n52595L,52596L,52597L,52598L,52599L,52600L,52601L,52602L,52603L,52604L,\n52605L,52606L,52607L,52608L,52609L,52610L,52611L,52612L,52613L,52614L,\n52615L,52616L,52617L,52618L,52619L,52620L,52621L,52622L,52623L,52624L,\n52625L,52626L,52627L,52628L,52629L,52630L,52631L,52632L,52633L,52634L,\n52635L,52636L,52637L,52638L,52639L,52640L,52641L,52642L,52643L,52644L,\n52645L,52646L,52647L,52648L,52649L,52650L,52651L,52652L,52653L,52654L,\n52655L,52656L,52657L,52658L,52659L,52660L,52661L,52662L,52663L,52664L,\n52665L,52666L,52667L,52668L,52669L,52670L,52671L,52672L,52673L,52674L,\n52675L,52676L,52677L,52678L,52679L,52680L,52681L,52682L,52683L,52684L,\n52685L,52686L,52687L,52688L,52689L,52690L,52691L,52692L,52693L,52694L,\n52695L,52696L,52697L,52698L,52699L,52700L,52701L,52702L,52703L,52704L,\n52705L,52706L,52707L,52708L,52709L,52710L,52711L,52712L,52713L,52714L,\n52715L,52716L,52717L,52718L,52719L,52720L,52721L,52722L,52723L,52724L,\n52725L,52726L,52727L,52728L,52729L,52730L,52731L,52732L,52733L,52734L,\n52735L,52736L,52737L,52738L,52739L,52740L,52741L,52742L,52743L,52744L,\n52745L,52746L,52747L,52748L,52749L,52750L,52751L,52752L,52753L,52754L,\n52755L,52756L,52757L,52758L,52759L,52760L,52761L,52762L,52763L,52764L,\n52765L,52766L,52767L,52768L,52769L,52770L,52771L,52772L,52773L,52774L,\n52775L,52776L,52777L,52778L,52779L,52780L,52781L,52782L,52783L,52784L,\n52785L,52786L,52787L,52788L,52789L,52790L,52791L,52792L,52793L,52794L,\n52795L,52796L,52797L,52798L,52799L,52800L,52801L,52802L,52803L,52804L,\n52805L,52806L,52807L,52808L,52809L,52810L,52811L,52812L,52813L,52814L,\n52815L,52816L,52817L,52818L,52819L,52820L,52821L,52822L,52823L,52824L,\n52825L,52826L,52827L,52828L,52829L,52830L,52831L,52832L,52833L,52834L,\n52835L,52836L,52837L,52838L,52839L,52840L,52841L,52842L,52843L,52844L,\n52845L,52846L,52847L,52848L,52849L,52850L,52851L,52852L,52853L,52854L,\n52855L,52856L,52857L,52858L,52859L,52860L,52861L,52862L,52863L,52864L,\n52865L,52866L,52867L,52868L,52869L,52870L,52871L,52872L,52873L,52874L,\n52875L,52876L,52877L,52878L,52879L,52880L,52881L,52882L,52883L,52884L,\n52885L,52886L,52887L,52888L,52889L,52890L,52891L,52892L,52893L,52894L,\n52895L,52896L,52897L,52898L,52899L,52900L,52901L,52902L,52903L,52904L,\n52905L,52906L,52907L,52908L,52909L,52910L,52911L,52912L,52913L,52914L,\n52915L,52916L,52917L,52918L,52919L,52920L,52921L,52922L,52923L,52924L,\n52925L,52926L,52927L,52928L,52929L,52930L,52931L,52932L,52933L,52934L,\n52935L,52936L,52937L,52938L,52939L,52940L,52941L,52942L,52943L,52944L,\n52945L,52946L,52947L,52948L,52949L,52950L,52951L,52952L,52953L,52954L,\n52955L,52956L,52957L,52958L,52959L,52960L,52961L,52962L,52963L,52964L,\n52965L,52966L,52967L,52968L,52969L,52970L,52971L,52972L,52973L,52974L,\n52975L,52976L,52977L,52978L,52979L,52980L,52981L,52982L,52983L,52984L,\n52985L,52986L,52987L,52988L,52989L,52990L,52991L,52992L,52993L,52994L,\n52995L,52996L,52997L,52998L,52999L,53000L,53001L,53002L,53003L,53004L,\n53005L,53006L,53007L,53008L,53009L,53010L,53011L,53012L,53013L,53014L,\n53015L,53016L,53017L,53018L,53019L,53020L,53021L,53022L,53023L,53024L,\n53025L,53026L,53027L,53028L,53029L,53030L,53031L,53032L,53033L,53034L,\n53035L,53036L,53037L,53038L,53039L,53040L,53041L,53042L,53043L,53044L,\n53045L,53046L,53047L,53048L,53049L,53050L,53051L,53052L,53053L,53054L,\n53055L,53056L,53057L,53058L,53059L,53060L,53061L,53062L,53063L,53064L,\n53065L,53066L,53067L,53068L,53069L,53070L,53071L,53072L,53073L,53074L,\n53075L,53076L,53077L,53078L,53079L,53080L,53081L,53082L,53083L,53084L,\n53085L,53086L,53087L,53088L,53089L,53090L,53091L,53092L,53093L,53094L,\n53095L,53096L,53097L,53098L,53099L,53100L,53101L,53102L,53103L,53104L,\n53105L,53106L,53107L,53108L,53109L,53110L,53111L,53112L,53113L,53114L,\n53115L,53116L,53117L,53118L,53119L,53120L,53121L,53122L,53123L,53124L,\n53125L,53126L,53127L,53128L,53129L,53130L,53131L,53132L,53133L,53134L,\n53135L,53136L,53137L,53138L,53139L,53140L,53141L,53142L,53143L,53144L,\n53145L,53146L,53147L,53148L,53149L,53150L,53151L,53152L,53153L,53154L,\n53155L,53156L,53157L,53158L,53159L,53160L,53161L,53162L,53163L,53164L,\n53165L,53166L,53167L,53168L,53169L,53170L,53171L,53172L,53173L,53174L,\n53175L,53176L,53177L,53178L,53179L,53180L,53181L,53182L,53183L,53184L,\n53185L,53186L,53187L,53188L,53189L,53190L,53191L,53192L,53193L,53194L,\n53195L,53196L,53197L,53198L,53199L,53200L,53201L,53202L,53203L,53204L,\n53205L,53206L,53207L,53208L,53209L,53210L,53211L,53212L,53213L,53214L,\n53215L,53216L,53217L,53218L,53219L,53220L,53221L,53222L,53223L,53224L,\n53225L,53226L,53227L,53228L,53229L,53230L,53231L,53232L,53233L,53234L,\n53235L,53236L,53237L,53238L,53239L,53240L,53241L,53242L,53243L,53244L,\n53245L,53246L,53247L,53248L,53249L,53250L,53251L,53252L,53253L,53254L,\n53255L,53256L,53257L,53258L,53259L,53260L,53261L,53262L,53263L,53264L,\n53265L,53266L,53267L,53268L,53269L,53270L,53271L,53272L,53273L,53274L,\n53275L,53276L,53277L,53278L,53279L,53280L,53281L,53282L,53283L,53284L,\n53285L,53286L,53287L,53288L,53289L,53290L,53291L,53292L,53293L,53294L,\n53295L,53296L,53297L,53298L,53299L,53300L,53301L,53302L,53303L,53304L,\n53305L,53306L,53307L,53308L,53309L,53310L,53311L,53312L,53313L,53314L,\n53315L,53316L,53317L,53318L,53319L,53320L,53321L,53322L,53323L,53324L,\n53325L,53326L,53327L,53328L,53329L,53330L,53331L,53332L,53333L,53334L,\n53335L,53336L,53337L,53338L,53339L,53340L,53341L,53342L,53343L,53344L,\n53345L,53346L,53347L,53348L,53349L,53350L,53351L,53352L,53353L,53354L,\n53355L,53356L,53357L,53358L,53359L,53360L,53361L,53362L,53363L,53364L,\n53365L,53366L,53367L,53368L,53369L,53370L,53371L,53372L,53373L,53374L,\n53375L,53376L,53377L,53378L,53379L,53380L,53381L,53382L,53383L,53384L,\n53385L,53386L,53387L,53388L,53389L,53390L,53391L,53392L,53393L,53394L,\n53395L,53396L,53397L,53398L,53399L,53400L,53401L,53402L,53403L,53404L,\n53405L,53406L,53407L,53408L,53409L,53410L,53411L,53412L,53413L,53414L,\n53415L,53416L,53417L,53418L,53419L,53420L,53421L,53422L,53423L,53424L,\n53425L,53426L,53427L,53428L,53429L,53430L,53431L,53432L,53433L,53434L,\n53435L,53436L,53437L,53438L,53439L,53440L,53441L,53442L,53443L,53444L,\n53445L,53446L,53447L,53448L,53449L,53450L,53451L,53452L,53453L,53454L,\n53455L,53456L,53457L,53458L,53459L,53460L,53461L,53462L,53463L,53464L,\n53465L,53466L,53467L,53468L,53469L,53470L,53471L,53472L,53473L,53474L,\n53475L,53476L,53477L,53478L,53479L,53480L,53481L,53482L,53483L,53484L,\n53485L,53486L,53487L,53488L,53489L,53490L,53491L,53492L,53493L,53494L,\n53495L,53496L,53497L,53498L,53499L,53500L,53501L,53502L,53503L,53504L,\n53505L,53506L,53507L,53508L,53509L,53510L,53511L,53512L,53513L,53514L,\n53515L,53516L,53517L,53518L,53519L,53520L,53521L,53522L,53523L,53524L,\n53525L,53526L,53527L,53528L,53529L,53530L,53531L,53532L,53533L,53534L,\n53535L,53536L,53537L,53538L,53539L,53540L,53541L,53542L,53543L,53544L,\n53545L,53546L,53547L,53548L,53549L,53550L,53551L,53552L,53553L,53554L,\n53555L,53556L,53557L,53558L,53559L,53560L,53561L,53562L,53563L,53564L,\n53565L,53566L,53567L,53568L,53569L,53570L,53571L,53572L,53573L,53574L,\n53575L,53576L,53577L,53578L,53579L,53580L,53581L,53582L,53583L,53584L,\n53585L,53586L,53587L,53588L,53589L,53590L,53591L,53592L,53593L,53594L,\n53595L,53596L,53597L,53598L,53599L,53600L,53601L,53602L,53603L,53604L,\n53605L,53606L,53607L,53608L,53609L,53610L,53611L,53612L,53613L,53614L,\n53615L,53616L,53617L,53618L,53619L,53620L,53621L,53622L,53623L,53624L,\n53625L,53626L,53627L,53628L,53629L,53630L,53631L,53632L,53633L,53634L,\n53635L,53636L,53637L,53638L,53639L,53640L,53641L,53642L,53643L,53644L,\n53645L,53646L,53647L,53648L,53649L,53650L,53651L,53652L,53653L,53654L,\n53655L,53656L,53657L,53658L,53659L,53660L,53661L,53662L,53663L,53664L,\n53665L,53666L,53667L,53668L,53669L,53670L,53671L,53672L,53673L,53674L,\n53675L,53676L,53677L,53678L,53679L,53680L,53681L,53682L,53683L,53684L,\n53685L,53686L,53687L,53688L,53689L,53690L,53691L,53692L,53693L,53694L,\n53695L,53696L,53697L,53698L,53699L,53700L,53701L,53702L,53703L,53704L,\n53705L,53706L,53707L,53708L,53709L,53710L,53711L,53712L,53713L,53714L,\n53715L,53716L,53717L,53718L,53719L,53720L,53721L,53722L,53723L,53724L,\n53725L,53726L,53727L,53728L,53729L,53730L,53731L,53732L,53733L,53734L,\n53735L,53736L,53737L,53738L,53739L,53740L,53741L,53742L,53743L,53744L,\n53745L,53746L,53747L,53748L,53749L,53750L,53751L,53752L,53753L,53754L,\n53755L,53756L,53757L,53758L,53759L,53760L,53761L,53762L,53763L,53764L,\n53765L,53766L,53767L,53768L,53769L,53770L,53771L,53772L,53773L,53774L,\n53775L,53776L,53777L,53778L,53779L,53780L,53781L,53782L,53783L,53784L,\n53785L,53786L,53787L,53788L,53789L,53790L,53791L,53792L,53793L,53794L,\n53795L,53796L,53797L,53798L,53799L,53800L,53801L,53802L,53803L,53804L,\n53805L,53806L,53807L,53808L,53809L,53810L,53811L,53812L,53813L,53814L,\n53815L,53816L,53817L,53818L,53819L,53820L,53821L,53822L,53823L,53824L,\n53825L,53826L,53827L,53828L,53829L,53830L,53831L,53832L,53833L,53834L,\n53835L,53836L,53837L,53838L,53839L,53840L,53841L,53842L,53843L,53844L,\n53845L,53846L,53847L,53848L,53849L,53850L,53851L,53852L,53853L,53854L,\n53855L,53856L,53857L,53858L,53859L,53860L,53861L,53862L,53863L,53864L,\n53865L,53866L,53867L,53868L,53869L,53870L,53871L,53872L,53873L,53874L,\n53875L,53876L,53877L,53878L,53879L,53880L,53881L,53882L,53883L,53884L,\n53885L,53886L,53887L,53888L,53889L,53890L,53891L,53892L,53893L,53894L,\n53895L,53896L,53897L,53898L,53899L,53900L,53901L,53902L,53903L,53904L,\n53905L,53906L,53907L,53908L,53909L,53910L,53911L,53912L,53913L,53914L,\n53915L,53916L,53917L,53918L,53919L,53920L,53921L,53922L,53923L,53924L,\n53925L,53926L,53927L,53928L,53929L,53930L,53931L,53932L,53933L,53934L,\n53935L,53936L,53937L,53938L,53939L,53940L,53941L,53942L,53943L,53944L,\n53945L,53946L,53947L,53948L,53949L,53950L,53951L,53952L,53953L,53954L,\n53955L,53956L,53957L,53958L,53959L,53960L,53961L,53962L,53963L,53964L,\n53965L,53966L,53967L,53968L,53969L,53970L,53971L,53972L,53973L,53974L,\n53975L,53976L,53977L,53978L,53979L,53980L,53981L,53982L,53983L,53984L,\n53985L,53986L,53987L,53988L,53989L,53990L,53991L,53992L,53993L,53994L,\n53995L,53996L,53997L,53998L,53999L,54000L,54001L,54002L,54003L,54004L,\n54005L,54006L,54007L,54008L,54009L,54010L,54011L,54012L,54013L,54014L,\n54015L,54016L,54017L,54018L,54019L,54020L,54021L,54022L,54023L,54024L,\n54025L,54026L,54027L,54028L,54029L,54030L,54031L,54032L,54033L,54034L,\n54035L,54036L,54037L,54038L,54039L,54040L,54041L,54042L,54043L,54044L,\n54045L,54046L,54047L,54048L,54049L,54050L,54051L,54052L,54053L,54054L,\n54055L,54056L,54057L,54058L,54059L,54060L,54061L,54062L,54063L,54064L,\n54065L,54066L,54067L,54068L,54069L,54070L,54071L,54072L,54073L,54074L,\n54075L,54076L,54077L,54078L,54079L,54080L,54081L,54082L,54083L,54084L,\n54085L,54086L,54087L,54088L,54089L,54090L,54091L,54092L,54093L,54094L,\n54095L,54096L,54097L,54098L,54099L,54100L,54101L,54102L,54103L,54104L,\n54105L,54106L,54107L,54108L,54109L,54110L,54111L,54112L,54113L,54114L,\n54115L,54116L,54117L,54118L,54119L,54120L,54121L,54122L,54123L,54124L,\n54125L,54126L,54127L,54128L,54129L,54130L,54131L,54132L,54133L,54134L,\n54135L,54136L,54137L,54138L,54139L,54140L,54141L,54142L,54143L,54144L,\n54145L,54146L,54147L,54148L,54149L,54150L,54151L,54152L,54153L,54154L,\n54155L,54156L,54157L,54158L,54159L,54160L,54161L,54162L,54163L,54164L,\n54165L,54166L,54167L,54168L,54169L,54170L,54171L,54172L,54173L,54174L,\n54175L,54176L,54177L,54178L,54179L,54180L,54181L,54182L,54183L,54184L,\n54185L,54186L,54187L,54188L,54189L,54190L,54191L,54192L,54193L,54194L,\n54195L,54196L,54197L,54198L,54199L,54200L,54201L,54202L,54203L,54204L,\n54205L,54206L,54207L,54208L,54209L,54210L,54211L,54212L,54213L,54214L,\n54215L,54216L,54217L,54218L,54219L,54220L,54221L,54222L,54223L,54224L,\n54225L,54226L,54227L,54228L,54229L,54230L,54231L,54232L,54233L,54234L,\n54235L,54236L,54237L,54238L,54239L,54240L,54241L,54242L,54243L,54244L,\n54245L,54246L,54247L,54248L,54249L,54250L,54251L,54252L,54253L,54254L,\n54255L,54256L,54257L,54258L,54259L,54260L,54261L,54262L,54263L,54264L,\n54265L,54266L,54267L,54268L,54269L,54270L,54271L,54272L,54273L,54274L,\n54275L,54276L,54277L,54278L,54279L,54280L,54281L,54282L,54283L,54284L,\n54285L,54286L,54287L,54288L,54289L,54290L,54291L,54292L,54293L,54294L,\n54295L,54296L,54297L,54298L,54299L,54300L,54301L,54302L,54303L,54304L,\n54305L,54306L,54307L,54308L,54309L,54310L,54311L,54312L,54313L,54314L,\n54315L,54316L,54317L,54318L,54319L,54320L,54321L,54322L,54323L,54324L,\n54325L,54326L,54327L,54328L,54329L,54330L,54331L,54332L,54333L,54334L,\n54335L,54336L,54337L,54338L,54339L,54340L,54341L,54342L,54343L,54344L,\n54345L,54346L,54347L,54348L,54349L,54350L,54351L,54352L,54353L,54354L,\n54355L,54356L,54357L,54358L,54359L,54360L,54361L,54362L,54363L,54364L,\n54365L,54366L,54367L,54368L,54369L,54370L,54371L,54372L,54373L,54374L,\n54375L,54376L,54377L,54378L,54379L,54380L,54381L,54382L,54383L,54384L,\n54385L,54386L,54387L,54388L,54389L,54390L,54391L,54392L,54393L,54394L,\n54395L,54396L,54397L,54398L,54399L,54400L,54401L,54402L,54403L,54404L,\n54405L,54406L,54407L,54408L,54409L,54410L,54411L,54412L,54413L,54414L,\n54415L,54416L,54417L,54418L,54419L,54420L,54421L,54422L,54423L,54424L,\n54425L,54426L,54427L,54428L,54429L,54430L,54431L,54432L,54433L,54434L,\n54435L,54436L,54437L,54438L,54439L,54440L,54441L,54442L,54443L,54444L,\n54445L,54446L,54447L,54448L,54449L,54450L,54451L,54452L,54453L,54454L,\n54455L,54456L,54457L,54458L,54459L,54460L,54461L,54462L,54463L,54464L,\n54465L,54466L,54467L,54468L,54469L,54470L,54471L,54472L,54473L,54474L,\n54475L,54476L,54477L,54478L,54479L,54480L,54481L,54482L,54483L,54484L,\n54485L,54486L,54487L,54488L,54489L,54490L,54491L,54492L,54493L,54494L,\n54495L,54496L,54497L,54498L,54499L,54500L,54501L,54502L,54503L,54504L,\n54505L,54506L,54507L,54508L,54509L,54510L,54511L,54512L,54513L,54514L,\n54515L,54516L,54517L,54518L,54519L,54520L,54521L,54522L,54523L,54524L,\n54525L,54526L,54527L,54528L,54529L,54530L,54531L,54532L,54533L,54534L,\n54535L,54536L,54537L,54538L,54539L,54540L,54541L,54542L,54543L,54544L,\n54545L,54546L,54547L,54548L,54549L,54550L,54551L,54552L,54553L,54554L,\n54555L,54556L,54557L,54558L,54559L,54560L,54561L,54562L,54563L,54564L,\n54565L,54566L,54567L,54568L,54569L,54570L,54571L,54572L,54573L,54574L,\n54575L,54576L,54577L,54578L,54579L,54580L,54581L,54582L,54583L,54584L,\n54585L,54586L,54587L,54588L,54589L,54590L,54591L,54592L,54593L,54594L,\n54595L,54596L,54597L,54598L,54599L,54600L,54601L,54602L,54603L,54604L,\n54605L,54606L,54607L,54608L,54609L,54610L,54611L,54612L,54613L,54614L,\n54615L,54616L,54617L,54618L,54619L,54620L,54621L,54622L,54623L,54624L,\n54625L,54626L,54627L,54628L,54629L,54630L,54631L,54632L,54633L,54634L,\n54635L,54636L,54637L,54638L,54639L,54640L,54641L,54642L,54643L,54644L,\n54645L,54646L,54647L,54648L,54649L,54650L,54651L,54652L,54653L,54654L,\n54655L,54656L,54657L,54658L,54659L,54660L,54661L,54662L,54663L,54664L,\n54665L,54666L,54667L,54668L,54669L,54670L,54671L,54672L,54673L,54674L,\n54675L,54676L,54677L,54678L,54679L,54680L,54681L,54682L,54683L,54684L,\n54685L,54686L,54687L,54688L,54689L,54690L,54691L,54692L,54693L,54694L,\n54695L,54696L,54697L,54698L,54699L,54700L,54701L,54702L,54703L,54704L,\n54705L,54706L,54707L,54708L,54709L,54710L,54711L,54712L,54713L,54714L,\n54715L,54716L,54717L,54718L,54719L,54720L,54721L,54722L,54723L,54724L,\n54725L,54726L,54727L,54728L,54729L,54730L,54731L,54732L,54733L,54734L,\n54735L,54736L,54737L,54738L,54739L,54740L,54741L,54742L,54743L,54744L,\n54745L,54746L,54747L,54748L,54749L,54750L,54751L,54752L,54753L,54754L,\n54755L,54756L,54757L,54758L,54759L,54760L,54761L,54762L,54763L,54764L,\n54765L,54766L,54767L,54768L,54769L,54770L,54771L,54772L,54773L,54774L,\n54775L,54776L,54777L,54778L,54779L,54780L,54781L,54782L,54783L,54784L,\n54785L,54786L,54787L,54788L,54789L,54790L,54791L,54792L,54793L,54794L,\n54795L,54796L,54797L,54798L,54799L,54800L,54801L,54802L,54803L,54804L,\n54805L,54806L,54807L,54808L,54809L,54810L,54811L,54812L,54813L,54814L,\n54815L,54816L,54817L,54818L,54819L,54820L,54821L,54822L,54823L,54824L,\n54825L,54826L,54827L,54828L,54829L,54830L,54831L,54832L,54833L,54834L,\n54835L,54836L,54837L,54838L,54839L,54840L,54841L,54842L,54843L,54844L,\n54845L,54846L,54847L,54848L,54849L,54850L,54851L,54852L,54853L,54854L,\n54855L,54856L,54857L,54858L,54859L,54860L,54861L,54862L,54863L,54864L,\n54865L,54866L,54867L,54868L,54869L,54870L,54871L,54872L,54873L,54874L,\n54875L,54876L,54877L,54878L,54879L,54880L,54881L,54882L,54883L,54884L,\n54885L,54886L,54887L,54888L,54889L,54890L,54891L,54892L,54893L,54894L,\n54895L,54896L,54897L,54898L,54899L,54900L,54901L,54902L,54903L,54904L,\n54905L,54906L,54907L,54908L,54909L,54910L,54911L,54912L,54913L,54914L,\n54915L,54916L,54917L,54918L,54919L,54920L,54921L,54922L,54923L,54924L,\n54925L,54926L,54927L,54928L,54929L,54930L,54931L,54932L,54933L,54934L,\n54935L,54936L,54937L,54938L,54939L,54940L,54941L,54942L,54943L,54944L,\n54945L,54946L,54947L,54948L,54949L,54950L,54951L,54952L,54953L,54954L,\n54955L,54956L,54957L,54958L,54959L,54960L,54961L,54962L,54963L,54964L,\n54965L,54966L,54967L,54968L,54969L,54970L,54971L,54972L,54973L,54974L,\n54975L,54976L,54977L,54978L,54979L,54980L,54981L,54982L,54983L,54984L,\n54985L,54986L,54987L,54988L,54989L,54990L,54991L,54992L,54993L,54994L,\n54995L,54996L,54997L,54998L,54999L,55000L,55001L,55002L,55003L,55004L,\n55005L,55006L,55007L,55008L,55009L,55010L,55011L,55012L,55013L,55014L,\n55015L,55016L,55017L,55018L,55019L,55020L,55021L,55022L,55023L,55024L,\n55025L,55026L,55027L,55028L,55029L,55030L,55031L,55032L,55033L,55034L,\n55035L,55036L,55037L,55038L,55039L,55040L,55041L,55042L,55043L,55044L,\n55045L,55046L,55047L,55048L,55049L,55050L,55051L,55052L,55053L,55054L,\n55055L,55056L,55057L,55058L,55059L,55060L,55061L,55062L,55063L,55064L,\n55065L,55066L,55067L,55068L,55069L,55070L,55071L,55072L,55073L,55074L,\n55075L,55076L,55077L,55078L,55079L,55080L,55081L,55082L,55083L,55084L,\n55085L,55086L,55087L,55088L,55089L,55090L,55091L,55092L,55093L,55094L,\n55095L,55096L,55097L,55098L,55099L,55100L,55101L,55102L,55103L,55104L,\n55105L,55106L,55107L,55108L,55109L,55110L,55111L,55112L,55113L,55114L,\n55115L,55116L,55117L,55118L,55119L,55120L,55121L,55122L,55123L,55124L,\n55125L,55126L,55127L,55128L,55129L,55130L,55131L,55132L,55133L,55134L,\n55135L,55136L,55137L,55138L,55139L,55140L,55141L,55142L,55143L,55144L,\n55145L,55146L,55147L,55148L,55149L,55150L,55151L,55152L,55153L,55154L,\n55155L,55156L,55157L,55158L,55159L,55160L,55161L,55162L,55163L,55164L,\n55165L,55166L,55167L,55168L,55169L,55170L,55171L,55172L,55173L,55174L,\n55175L,55176L,55177L,55178L,55179L,55180L,55181L,55182L,55183L,55184L,\n55185L,55186L,55187L,55188L,55189L,55190L,55191L,55192L,55193L,55194L,\n55195L,55196L,55197L,55198L,55199L,55200L,55201L,55202L,55203L,55204L,\n55205L,55206L,55207L,55208L,55209L,55210L,55211L,55212L,55213L,55214L,\n55215L,55216L,55217L,55218L,55219L,55220L,55221L,55222L,55223L,55224L,\n55225L,55226L,55227L,55228L,55229L,55230L,55231L,55232L,55233L,55234L,\n55235L,55236L,55237L,55238L,55239L,55240L,55241L,55242L,55243L,55244L,\n55245L,55246L,55247L,55248L,55249L,55250L,55251L,55252L,55253L,55254L,\n55255L,55256L,55257L,55258L,55259L,55260L,55261L,55262L,55263L,55264L,\n55265L,55266L,55267L,55268L,55269L,55270L,55271L,55272L,55273L,55274L,\n55275L,55276L,55277L,55278L,55279L,55280L,55281L,55282L,55283L,55284L,\n55285L,55286L,55287L,55288L,55289L,55290L,55291L,55292L,55293L,55294L,\n55295L,55296L,55297L,55298L,55299L,55300L,55301L,55302L,55303L,55304L,\n55305L,55306L,55307L,55308L,55309L,55310L,55311L,55312L,55313L,55314L,\n55315L,55316L,55317L,55318L,55319L,55320L,55321L,55322L,55323L,55324L,\n55325L,55326L,55327L,55328L,55329L,55330L,55331L,55332L,55333L,55334L,\n55335L,55336L,55337L,55338L,55339L,55340L,55341L,55342L,55343L,55344L,\n55345L,55346L,55347L,55348L,55349L,55350L,55351L,55352L,55353L,55354L,\n55355L,55356L,55357L,55358L,55359L,55360L,55361L,55362L,55363L,55364L,\n55365L,55366L,55367L,55368L,55369L,55370L,55371L,55372L,55373L,55374L,\n55375L,55376L,55377L,55378L,55379L,55380L,55381L,55382L,55383L,55384L,\n55385L,55386L,55387L,55388L,55389L,55390L,55391L,55392L,55393L,55394L,\n55395L,55396L,55397L,55398L,55399L,55400L,55401L,55402L,55403L,55404L,\n55405L,55406L,55407L,55408L,55409L,55410L,55411L,55412L,55413L,55414L,\n55415L,55416L,55417L,55418L,55419L,55420L,55421L,55422L,55423L,55424L,\n55425L,55426L,55427L,55428L,55429L,55430L,55431L,55432L,55433L,55434L,\n55435L,55436L,55437L,55438L,55439L,55440L,55441L,55442L,55443L,55444L,\n55445L,55446L,55447L,55448L,55449L,55450L,55451L,55452L,55453L,55454L,\n55455L,55456L,55457L,55458L,55459L,55460L,55461L,55462L,55463L,55464L,\n55465L,55466L,55467L,55468L,55469L,55470L,55471L,55472L,55473L,55474L,\n55475L,55476L,55477L,55478L,55479L,55480L,55481L,55482L,55483L,55484L,\n55485L,55486L,55487L,55488L,55489L,55490L,55491L,55492L,55493L,55494L,\n55495L,55496L,55497L,55498L,55499L,55500L,55501L,55502L,55503L,55504L,\n55505L,55506L,55507L,55508L,55509L,55510L,55511L,55512L,55513L,55514L,\n55515L,55516L,55517L,55518L,55519L,55520L,55521L,55522L,55523L,55524L,\n55525L,55526L,55527L,55528L,55529L,55530L,55531L,55532L,55533L,55534L,\n55535L,55536L,55537L,55538L,55539L,55540L,55541L,55542L,55543L,55544L,\n55545L,55546L,55547L,55548L,55549L,55550L,55551L,55552L,55553L,55554L,\n55555L,55556L,55557L,55558L,55559L,55560L,55561L,55562L,55563L,55564L,\n55565L,55566L,55567L,55568L,55569L,55570L,55571L,55572L,55573L,55574L,\n55575L,55576L,55577L,55578L,55579L,55580L,55581L,55582L,55583L,55584L,\n55585L,55586L,55587L,55588L,55589L,55590L,55591L,55592L,55593L,55594L,\n55595L,55596L,55597L,55598L,55599L,55600L,55601L,55602L,55603L,55604L,\n55605L,55606L,55607L,55608L,55609L,55610L,55611L,55612L,55613L,55614L,\n55615L,55616L,55617L,55618L,55619L,55620L,55621L,55622L,55623L,55624L,\n55625L,55626L,55627L,55628L,55629L,55630L,55631L,55632L,55633L,55634L,\n55635L,55636L,55637L,55638L,55639L,55640L,55641L,55642L,55643L,55644L,\n55645L,55646L,55647L,55648L,55649L,55650L,55651L,55652L,55653L,55654L,\n55655L,55656L,55657L,55658L,55659L,55660L,55661L,55662L,55663L,55664L,\n55665L,55666L,55667L,55668L,55669L,55670L,55671L,55672L,55673L,55674L,\n55675L,55676L,55677L,55678L,55679L,55680L,55681L,55682L,55683L,55684L,\n55685L,55686L,55687L,55688L,55689L,55690L,55691L,55692L,55693L,55694L,\n55695L,55696L,55697L,55698L,55699L,55700L,55701L,55702L,55703L,55704L,\n55705L,55706L,55707L,55708L,55709L,55710L,55711L,55712L,55713L,55714L,\n55715L,55716L,55717L,55718L,55719L,55720L,55721L,55722L,55723L,55724L,\n55725L,55726L,55727L,55728L,55729L,55730L,55731L,55732L,55733L,55734L,\n55735L,55736L,55737L,55738L,55739L,55740L,55741L,55742L,55743L,55744L,\n55745L,55746L,55747L,55748L,55749L,55750L,55751L,55752L,55753L,55754L,\n55755L,55756L,55757L,55758L,55759L,55760L,55761L,55762L,55763L,55764L,\n55765L,55766L,55767L,55768L,55769L,55770L,55771L,55772L,55773L,55774L,\n55775L,55776L,55777L,55778L,55779L,55780L,55781L,55782L,55783L,55784L,\n55785L,55786L,55787L,55788L,55789L,55790L,55791L,55792L,55793L,55794L,\n55795L,55796L,55797L,55798L,55799L,55800L,55801L,55802L,55803L,55804L,\n55805L,55806L,55807L,55808L,55809L,55810L,55811L,55812L,55813L,55814L,\n55815L,55816L,55817L,55818L,55819L,55820L,55821L,55822L,55823L,55824L,\n55825L,55826L,55827L,55828L,55829L,55830L,55831L,55832L,55833L,55834L,\n55835L,55836L,55837L,55838L,55839L,55840L,55841L,55842L,55843L,55844L,\n55845L,55846L,55847L,55848L,55849L,55850L,55851L,55852L,55853L,55854L,\n55855L,55856L,55857L,55858L,55859L,55860L,55861L,55862L,55863L,55864L,\n55865L,55866L,55867L,55868L,55869L,55870L,55871L,55872L,55873L,55874L,\n55875L,55876L,55877L,55878L,55879L,55880L,55881L,55882L,55883L,55884L,\n55885L,55886L,55887L,55888L,55889L,55890L,55891L,55892L,55893L,55894L,\n55895L,55896L,55897L,55898L,55899L,55900L,55901L,55902L,55903L,55904L,\n55905L,55906L,55907L,55908L,55909L,55910L,55911L,55912L,55913L,55914L,\n55915L,55916L,55917L,55918L,55919L,55920L,55921L,55922L,55923L,55924L,\n55925L,55926L,55927L,55928L,55929L,55930L,55931L,55932L,55933L,55934L,\n55935L,55936L,55937L,55938L,55939L,55940L,55941L,55942L,55943L,55944L,\n55945L,55946L,55947L,55948L,55949L,55950L,55951L,55952L,55953L,55954L,\n55955L,55956L,55957L,55958L,55959L,55960L,55961L,55962L,55963L,55964L,\n55965L,55966L,55967L,55968L,55969L,55970L,55971L,55972L,55973L,55974L,\n55975L,55976L,55977L,55978L,55979L,55980L,55981L,55982L,55983L,55984L,\n55985L,55986L,55987L,55988L,55989L,55990L,55991L,55992L,55993L,55994L,\n55995L,55996L,55997L,55998L,55999L,56000L,56001L,56002L,56003L,56004L,\n56005L,56006L,56007L,56008L,56009L,56010L,56011L,56012L,56013L,56014L,\n56015L,56016L,56017L,56018L,56019L,56020L,56021L,56022L,56023L,56024L,\n56025L,56026L,56027L,56028L,56029L,56030L,56031L,56032L,56033L,56034L,\n56035L,56036L,56037L,56038L,56039L,56040L,56041L,56042L,56043L,56044L,\n56045L,56046L,56047L,56048L,56049L,56050L,56051L,56052L,56053L,56054L,\n56055L,56056L,56057L,56058L,56059L,56060L,56061L,56062L,56063L,56064L,\n56065L,56066L,56067L,56068L,56069L,56070L,56071L,56072L,56073L,56074L,\n56075L,56076L,56077L,56078L,56079L,56080L,56081L,56082L,56083L,56084L,\n56085L,56086L,56087L,56088L,56089L,56090L,56091L,56092L,56093L,56094L,\n56095L,56096L,56097L,56098L,56099L,56100L,56101L,56102L,56103L,56104L,\n56105L,56106L,56107L,56108L,56109L,56110L,56111L,56112L,56113L,56114L,\n56115L,56116L,56117L,56118L,56119L,56120L,56121L,56122L,56123L,56124L,\n56125L,56126L,56127L,56128L,56129L,56130L,56131L,56132L,56133L,56134L,\n56135L,56136L,56137L,56138L,56139L,56140L,56141L,56142L,56143L,56144L,\n56145L,56146L,56147L,56148L,56149L,56150L,56151L,56152L,56153L,56154L,\n56155L,56156L,56157L,56158L,56159L,56160L,56161L,56162L,56163L,56164L,\n56165L,56166L,56167L,56168L,56169L,56170L,56171L,56172L,56173L,56174L,\n56175L,56176L,56177L,56178L,56179L,56180L,56181L,56182L,56183L,56184L,\n56185L,56186L,56187L,56188L,56189L,56190L,56191L,56192L,56193L,56194L,\n56195L,56196L,56197L,56198L,56199L,56200L,56201L,56202L,56203L,56204L,\n56205L,56206L,56207L,56208L,56209L,56210L,56211L,56212L,56213L,56214L,\n56215L,56216L,56217L,56218L,56219L,56220L,56221L,56222L,56223L,56224L,\n56225L,56226L,56227L,56228L,56229L,56230L,56231L,56232L,56233L,56234L,\n56235L,56236L,56237L,56238L,56239L,56240L,56241L,56242L,56243L,56244L,\n56245L,56246L,56247L,56248L,56249L,56250L,56251L,56252L,56253L,56254L,\n56255L,56256L,56257L,56258L,56259L,56260L,56261L,56262L,56263L,56264L,\n56265L,56266L,56267L,56268L,56269L,56270L,56271L,56272L,56273L,56274L,\n56275L,56276L,56277L,56278L,56279L,56280L,56281L,56282L,56283L,56284L,\n56285L,56286L,56287L,56288L,56289L,56290L,56291L,56292L,56293L,56294L,\n56295L,56296L,56297L,56298L,56299L,56300L,56301L,56302L,56303L,56304L,\n56305L,56306L,56307L,56308L,56309L,56310L,56311L,56312L,56313L,56314L,\n56315L,56316L,56317L,56318L,56319L,56320L,56321L,56322L,56323L,56324L,\n56325L,56326L,56327L,56328L,56329L,56330L,56331L,56332L,56333L,56334L,\n56335L,56336L,56337L,56338L,56339L,56340L,56341L,56342L,56343L,56344L,\n56345L,56346L,56347L,56348L,56349L,56350L,56351L,56352L,56353L,56354L,\n56355L,56356L,56357L,56358L,56359L,56360L,56361L,56362L,56363L,56364L,\n56365L,56366L,56367L,56368L,56369L,56370L,56371L,56372L,56373L,56374L,\n56375L,56376L,56377L,56378L,56379L,56380L,56381L,56382L,56383L,56384L,\n56385L,56386L,56387L,56388L,56389L,56390L,56391L,56392L,56393L,56394L,\n56395L,56396L,56397L,56398L,56399L,56400L,56401L,56402L,56403L,56404L,\n56405L,56406L,56407L,56408L,56409L,56410L,56411L,56412L,56413L,56414L,\n56415L,56416L,56417L,56418L,56419L,56420L,56421L,56422L,56423L,56424L,\n56425L,56426L,56427L,56428L,56429L,56430L,56431L,56432L,56433L,56434L,\n56435L,56436L,56437L,56438L,56439L,56440L,56441L,56442L,56443L,56444L,\n56445L,56446L,56447L,56448L,56449L,56450L,56451L,56452L,56453L,56454L,\n56455L,56456L,56457L,56458L,56459L,56460L,56461L,56462L,56463L,56464L,\n56465L,56466L,56467L,56468L,56469L,56470L,56471L,56472L,56473L,56474L,\n56475L,56476L,56477L,56478L,56479L,56480L,56481L,56482L,56483L,56484L,\n56485L,56486L,56487L,56488L,56489L,56490L,56491L,56492L,56493L,56494L,\n56495L,56496L,56497L,56498L,56499L,56500L,56501L,56502L,56503L,56504L,\n56505L,56506L,56507L,56508L,56509L,56510L,56511L,56512L,56513L,56514L,\n56515L,56516L,56517L,56518L,56519L,56520L,56521L,56522L,56523L,56524L,\n56525L,56526L,56527L,56528L,56529L,56530L,56531L,56532L,56533L,56534L,\n56535L,56536L,56537L,56538L,56539L,56540L,56541L,56542L,56543L,56544L,\n56545L,56546L,56547L,56548L,56549L,56550L,56551L,56552L,56553L,56554L,\n56555L,56556L,56557L,56558L,56559L,56560L,56561L,56562L,56563L,56564L,\n56565L,56566L,56567L,56568L,56569L,56570L,56571L,56572L,56573L,56574L,\n56575L,56576L,56577L,56578L,56579L,56580L,56581L,56582L,56583L,56584L,\n56585L,56586L,56587L,56588L,56589L,56590L,56591L,56592L,56593L,56594L,\n56595L,56596L,56597L,56598L,56599L,56600L,56601L,56602L,56603L,56604L,\n56605L,56606L,56607L,56608L,56609L,56610L,56611L,56612L,56613L,56614L,\n56615L,56616L,56617L,56618L,56619L,56620L,56621L,56622L,56623L,56624L,\n56625L,56626L,56627L,56628L,56629L,56630L,56631L,56632L,56633L,56634L,\n56635L,56636L,56637L,56638L,56639L,56640L,56641L,56642L,56643L,56644L,\n56645L,56646L,56647L,56648L,56649L,56650L,56651L,56652L,56653L,56654L,\n56655L,56656L,56657L,56658L,56659L,56660L,56661L,56662L,56663L,56664L,\n56665L,56666L,56667L,56668L,56669L,56670L,56671L,56672L,56673L,56674L,\n56675L,56676L,56677L,56678L,56679L,56680L,56681L,56682L,56683L,56684L,\n56685L,56686L,56687L,56688L,56689L,56690L,56691L,56692L,56693L,56694L,\n56695L,56696L,56697L,56698L,56699L,56700L,56701L,56702L,56703L,56704L,\n56705L,56706L,56707L,56708L,56709L,56710L,56711L,56712L,56713L,56714L,\n56715L,56716L,56717L,56718L,56719L,56720L,56721L,56722L,56723L,56724L,\n56725L,56726L,56727L,56728L,56729L,56730L,56731L,56732L,56733L,56734L,\n56735L,56736L,56737L,56738L,56739L,56740L,56741L,56742L,56743L,56744L,\n56745L,56746L,56747L,56748L,56749L,56750L,56751L,56752L,56753L,56754L,\n56755L,56756L,56757L,56758L,56759L,56760L,56761L,56762L,56763L,56764L,\n56765L,56766L,56767L,56768L,56769L,56770L,56771L,56772L,56773L,56774L,\n56775L,56776L,56777L,56778L,56779L,56780L,56781L,56782L,56783L,56784L,\n56785L,56786L,56787L,56788L,56789L,56790L,56791L,56792L,56793L,56794L,\n56795L,56796L,56797L,56798L,56799L,56800L,56801L,56802L,56803L,56804L,\n56805L,56806L,56807L,56808L,56809L,56810L,56811L,56812L,56813L,56814L,\n56815L,56816L,56817L,56818L,56819L,56820L,56821L,56822L,56823L,56824L,\n56825L,56826L,56827L,56828L,56829L,56830L,56831L,56832L,56833L,56834L,\n56835L,56836L,56837L,56838L,56839L,56840L,56841L,56842L,56843L,56844L,\n56845L,56846L,56847L,56848L,56849L,56850L,56851L,56852L,56853L,56854L,\n56855L,56856L,56857L,56858L,56859L,56860L,56861L,56862L,56863L,56864L,\n56865L,56866L,56867L,56868L,56869L,56870L,56871L,56872L,56873L,56874L,\n56875L,56876L,56877L,56878L,56879L,56880L,56881L,56882L,56883L,56884L,\n56885L,56886L,56887L,56888L,56889L,56890L,56891L,56892L,56893L,56894L,\n56895L,56896L,56897L,56898L,56899L,56900L,56901L,56902L,56903L,56904L,\n56905L,56906L,56907L,56908L,56909L,56910L,56911L,56912L,56913L,56914L,\n56915L,56916L,56917L,56918L,56919L,56920L,56921L,56922L,56923L,56924L,\n56925L,56926L,56927L,56928L,56929L,56930L,56931L,56932L,56933L,56934L,\n56935L,56936L,56937L,56938L,56939L,56940L,56941L,56942L,56943L,56944L,\n56945L,56946L,56947L,56948L,56949L,56950L,56951L,56952L,56953L,56954L,\n56955L,56956L,56957L,56958L,56959L,56960L,56961L,56962L,56963L,56964L,\n56965L,56966L,56967L,56968L,56969L,56970L,56971L,56972L,56973L,56974L,\n56975L,56976L,56977L,56978L,56979L,56980L,56981L,56982L,56983L,56984L,\n56985L,56986L,56987L,56988L,56989L,56990L,56991L,56992L,56993L,56994L,\n56995L,56996L,56997L,56998L,56999L,57000L,57001L,57002L,57003L,57004L,\n57005L,57006L,57007L,57008L,57009L,57010L,57011L,57012L,57013L,57014L,\n57015L,57016L,57017L,57018L,57019L,57020L,57021L,57022L,57023L,57024L,\n57025L,57026L,57027L,57028L,57029L,57030L,57031L,57032L,57033L,57034L,\n57035L,57036L,57037L,57038L,57039L,57040L,57041L,57042L,57043L,57044L,\n57045L,57046L,57047L,57048L,57049L,57050L,57051L,57052L,57053L,57054L,\n57055L,57056L,57057L,57058L,57059L,57060L,57061L,57062L,57063L,57064L,\n57065L,57066L,57067L,57068L,57069L,57070L,57071L,57072L,57073L,57074L,\n57075L,57076L,57077L,57078L,57079L,57080L,57081L,57082L,57083L,57084L,\n57085L,57086L,57087L,57088L,57089L,57090L,57091L,57092L,57093L,57094L,\n57095L,57096L,57097L,57098L,57099L,57100L,57101L,57102L,57103L,57104L,\n57105L,57106L,57107L,57108L,57109L,57110L,57111L,57112L,57113L,57114L,\n57115L,57116L,57117L,57118L,57119L,57120L,57121L,57122L,57123L,57124L,\n57125L,57126L,57127L,57128L,57129L,57130L,57131L,57132L,57133L,57134L,\n57135L,57136L,57137L,57138L,57139L,57140L,57141L,57142L,57143L,57144L,\n57145L,57146L,57147L,57148L,57149L,57150L,57151L,57152L,57153L,57154L,\n57155L,57156L,57157L,57158L,57159L,57160L,57161L,57162L,57163L,57164L,\n57165L,57166L,57167L,57168L,57169L,57170L,57171L,57172L,57173L,57174L,\n57175L,57176L,57177L,57178L,57179L,57180L,57181L,57182L,57183L,57184L,\n57185L,57186L,57187L,57188L,57189L,57190L,57191L,57192L,57193L,57194L,\n57195L,57196L,57197L,57198L,57199L,57200L,57201L,57202L,57203L,57204L,\n57205L,57206L,57207L,57208L,57209L,57210L,57211L,57212L,57213L,57214L,\n57215L,57216L,57217L,57218L,57219L,57220L,57221L,57222L,57223L,57224L,\n57225L,57226L,57227L,57228L,57229L,57230L,57231L,57232L,57233L,57234L,\n57235L,57236L,57237L,57238L,57239L,57240L,57241L,57242L,57243L,57244L,\n57245L,57246L,57247L,57248L,57249L,57250L,57251L,57252L,57253L,57254L,\n57255L,57256L,57257L,57258L,57259L,57260L,57261L,57262L,57263L,57264L,\n57265L,57266L,57267L,57268L,57269L,57270L,57271L,57272L,57273L,57274L,\n57275L,57276L,57277L,57278L,57279L,57280L,57281L,57282L,57283L,57284L,\n57285L,57286L,57287L,57288L,57289L,57290L,57291L,57292L,57293L,57294L,\n57295L,57296L,57297L,57298L,57299L,57300L,57301L,57302L,57303L,57304L,\n57305L,57306L,57307L,57308L,57309L,57310L,57311L,57312L,57313L,57314L,\n57315L,57316L,57317L,57318L,57319L,57320L,57321L,57322L,57323L,57324L,\n57325L,57326L,57327L,57328L,57329L,57330L,57331L,57332L,57333L,57334L,\n57335L,57336L,57337L,57338L,57339L,57340L,57341L,57342L,57343L,57344L,\n57345L,57346L,57347L,57348L,57349L,57350L,57351L,57352L,57353L,57354L,\n57355L,57356L,57357L,57358L,57359L,57360L,57361L,57362L,57363L,57364L,\n57365L,57366L,57367L,57368L,57369L,57370L,57371L,57372L,57373L,57374L,\n57375L,57376L,57377L,57378L,57379L,57380L,57381L,57382L,57383L,57384L,\n57385L,57386L,57387L,57388L,57389L,57390L,57391L,57392L,57393L,57394L,\n57395L,57396L,57397L,57398L,57399L,57400L,57401L,57402L,57403L,57404L,\n57405L,57406L,57407L,57408L,57409L,57410L,57411L,57412L,57413L,57414L,\n57415L,57416L,57417L,57418L,57419L,57420L,57421L,57422L,57423L,57424L,\n57425L,57426L,57427L,57428L,57429L,57430L,57431L,57432L,57433L,57434L,\n57435L,57436L,57437L,57438L,57439L,57440L,57441L,57442L,57443L,57444L,\n57445L,57446L,57447L,57448L,57449L,57450L,57451L,57452L,57453L,57454L,\n57455L,57456L,57457L,57458L,57459L,57460L,57461L,57462L,57463L,57464L,\n57465L,57466L,57467L,57468L,57469L,57470L,57471L,57472L,57473L,57474L,\n57475L,57476L,57477L,57478L,57479L,57480L,57481L,57482L,57483L,57484L,\n57485L,57486L,57487L,57488L,57489L,57490L,57491L,57492L,57493L,57494L,\n57495L,57496L,57497L,57498L,57499L,57500L,57501L,57502L,57503L,57504L,\n57505L,57506L,57507L,57508L,57509L,57510L,57511L,57512L,57513L,57514L,\n57515L,57516L,57517L,57518L,57519L,57520L,57521L,57522L,57523L,57524L,\n57525L,57526L,57527L,57528L,57529L,57530L,57531L,57532L,57533L,57534L,\n57535L,57536L,57537L,57538L,57539L,57540L,57541L,57542L,57543L,57544L,\n57545L,57546L,57547L,57548L,57549L,57550L,57551L,57552L,57553L,57554L,\n57555L,57556L,57557L,57558L,57559L,57560L,57561L,57562L,57563L,57564L,\n57565L,57566L,57567L,57568L,57569L,57570L,57571L,57572L,57573L,57574L,\n57575L,57576L,57577L,57578L,57579L,57580L,57581L,57582L,57583L,57584L,\n57585L,57586L,57587L,57588L,57589L,57590L,57591L,57592L,57593L,57594L,\n57595L,57596L,57597L,57598L,57599L,57600L,57601L,57602L,57603L,57604L,\n57605L,57606L,57607L,57608L,57609L,57610L,57611L,57612L,57613L,57614L,\n57615L,57616L,57617L,57618L,57619L,57620L,57621L,57622L,57623L,57624L,\n57625L,57626L,57627L,57628L,57629L,57630L,57631L,57632L,57633L,57634L,\n57635L,57636L,57637L,57638L,57639L,57640L,57641L,57642L,57643L,57644L,\n57645L,57646L,57647L,57648L,57649L,57650L,57651L,57652L,57653L,57654L,\n57655L,57656L,57657L,57658L,57659L,57660L,57661L,57662L,57663L,57664L,\n57665L,57666L,57667L,57668L,57669L,57670L,57671L,57672L,57673L,57674L,\n57675L,57676L,57677L,57678L,57679L,57680L,57681L,57682L,57683L,57684L,\n57685L,57686L,57687L,57688L,57689L,57690L,57691L,57692L,57693L,57694L,\n57695L,57696L,57697L,57698L,57699L,57700L,57701L,57702L,57703L,57704L,\n57705L,57706L,57707L,57708L,57709L,57710L,57711L,57712L,57713L,57714L,\n57715L,57716L,57717L,57718L,57719L,57720L,57721L,57722L,57723L,57724L,\n57725L,57726L,57727L,57728L,57729L,57730L,57731L,57732L,57733L,57734L,\n57735L,57736L,57737L,57738L,57739L,57740L,57741L,57742L,57743L,57744L,\n57745L,57746L,57747L,57748L,57749L,57750L,57751L,57752L,57753L,57754L,\n57755L,57756L,57757L,57758L,57759L,57760L,57761L,57762L,57763L,57764L,\n57765L,57766L,57767L,57768L,57769L,57770L,57771L,57772L,57773L,57774L,\n57775L,57776L,57777L,57778L,57779L,57780L,57781L,57782L,57783L,57784L,\n57785L,57786L,57787L,57788L,57789L,57790L,57791L,57792L,57793L,57794L,\n57795L,57796L,57797L,57798L,57799L,57800L,57801L,57802L,57803L,57804L,\n57805L,57806L,57807L,57808L,57809L,57810L,57811L,57812L,57813L,57814L,\n57815L,57816L,57817L,57818L,57819L,57820L,57821L,57822L,57823L,57824L,\n57825L,57826L,57827L,57828L,57829L,57830L,57831L,57832L,57833L,57834L,\n57835L,57836L,57837L,57838L,57839L,57840L,57841L,57842L,57843L,57844L,\n57845L,57846L,57847L,57848L,57849L,57850L,57851L,57852L,57853L,57854L,\n57855L,57856L,57857L,57858L,57859L,57860L,57861L,57862L,57863L,57864L,\n57865L,57866L,57867L,57868L,57869L,57870L,57871L,57872L,57873L,57874L,\n57875L,57876L,57877L,57878L,57879L,57880L,57881L,57882L,57883L,57884L,\n57885L,57886L,57887L,57888L,57889L,57890L,57891L,57892L,57893L,57894L,\n57895L,57896L,57897L,57898L,57899L,57900L,57901L,57902L,57903L,57904L,\n57905L,57906L,57907L,57908L,57909L,57910L,57911L,57912L,57913L,57914L,\n57915L,57916L,57917L,57918L,57919L,57920L,57921L,57922L,57923L,57924L,\n57925L,57926L,57927L,57928L,57929L,57930L,57931L,57932L,57933L,57934L,\n57935L,57936L,57937L,57938L,57939L,57940L,57941L,57942L,57943L,57944L,\n57945L,57946L,57947L,57948L,57949L,57950L,57951L,57952L,57953L,57954L,\n57955L,57956L,57957L,57958L,57959L,57960L,57961L,57962L,57963L,57964L,\n57965L,57966L,57967L,57968L,57969L,57970L,57971L,57972L,57973L,57974L,\n57975L,57976L,57977L,57978L,57979L,57980L,57981L,57982L,57983L,57984L,\n57985L,57986L,57987L,57988L,57989L,57990L,57991L,57992L,57993L,57994L,\n57995L,57996L,57997L,57998L,57999L,58000L,58001L,58002L,58003L,58004L,\n58005L,58006L,58007L,58008L,58009L,58010L,58011L,58012L,58013L,58014L,\n58015L,58016L,58017L,58018L,58019L,58020L,58021L,58022L,58023L,58024L,\n58025L,58026L,58027L,58028L,58029L,58030L,58031L,58032L,58033L,58034L,\n58035L,58036L,58037L,58038L,58039L,58040L,58041L,58042L,58043L,58044L,\n58045L,58046L,58047L,58048L,58049L,58050L,58051L,58052L,58053L,58054L,\n58055L,58056L,58057L,58058L,58059L,58060L,58061L,58062L,58063L,58064L,\n58065L,58066L,58067L,58068L,58069L,58070L,58071L,58072L,58073L,58074L,\n58075L,58076L,58077L,58078L,58079L,58080L,58081L,58082L,58083L,58084L,\n58085L,58086L,58087L,58088L,58089L,58090L,58091L,58092L,58093L,58094L,\n58095L,58096L,58097L,58098L,58099L,58100L,58101L,58102L,58103L,58104L,\n58105L,58106L,58107L,58108L,58109L,58110L,58111L,58112L,58113L,58114L,\n58115L,58116L,58117L,58118L,58119L,58120L,58121L,58122L,58123L,58124L,\n58125L,58126L,58127L,58128L,58129L,58130L,58131L,58132L,58133L,58134L,\n58135L,58136L,58137L,58138L,58139L,58140L,58141L,58142L,58143L,58144L,\n58145L,58146L,58147L,58148L,58149L,58150L,58151L,58152L,58153L,58154L,\n58155L,58156L,58157L,58158L,58159L,58160L,58161L,58162L,58163L,58164L,\n58165L,58166L,58167L,58168L,58169L,58170L,58171L,58172L,58173L,58174L,\n58175L,58176L,58177L,58178L,58179L,58180L,58181L,58182L,58183L,58184L,\n58185L,58186L,58187L,58188L,58189L,58190L,58191L,58192L,58193L,58194L,\n58195L,58196L,58197L,58198L,58199L,58200L,58201L,58202L,58203L,58204L,\n58205L,58206L,58207L,58208L,58209L,58210L,58211L,58212L,58213L,58214L,\n58215L,58216L,58217L,58218L,58219L,58220L,58221L,58222L,58223L,58224L,\n58225L,58226L,58227L,58228L,58229L,58230L,58231L,58232L,58233L,58234L,\n58235L,58236L,58237L,58238L,58239L,58240L,58241L,58242L,58243L,58244L,\n58245L,58246L,58247L,58248L,58249L,58250L,58251L,58252L,58253L,58254L,\n58255L,58256L,58257L,58258L,58259L,58260L,58261L,58262L,58263L,58264L,\n58265L,58266L,58267L,58268L,58269L,58270L,58271L,58272L,58273L,58274L,\n58275L,58276L,58277L,58278L,58279L,58280L,58281L,58282L,58283L,58284L,\n58285L,58286L,58287L,58288L,58289L,58290L,58291L,58292L,58293L,58294L,\n58295L,58296L,58297L,58298L,58299L,58300L,58301L,58302L,58303L,58304L,\n58305L,58306L,58307L,58308L,58309L,58310L,58311L,58312L,58313L,58314L,\n58315L,58316L,58317L,58318L,58319L,58320L,58321L,58322L,58323L,58324L,\n58325L,58326L,58327L,58328L,58329L,58330L,58331L,58332L,58333L,58334L,\n58335L,58336L,58337L,58338L,58339L,58340L,58341L,58342L,58343L,58344L,\n58345L,58346L,58347L,58348L,58349L,58350L,58351L,58352L,58353L,58354L,\n58355L,58356L,58357L,58358L,58359L,58360L,58361L,58362L,58363L,58364L,\n58365L,58366L,58367L,58368L,58369L,58370L,58371L,58372L,58373L,58374L,\n58375L,58376L,58377L,58378L,58379L,58380L,58381L,58382L,58383L,58384L,\n58385L,58386L,58387L,58388L,58389L,58390L,58391L,58392L,58393L,58394L,\n58395L,58396L,58397L,58398L,58399L,58400L,58401L,58402L,58403L,58404L,\n58405L,58406L,58407L,58408L,58409L,58410L,58411L,58412L,58413L,58414L,\n58415L,58416L,58417L,58418L,58419L,58420L,58421L,58422L,58423L,58424L,\n58425L,58426L,58427L,58428L,58429L,58430L,58431L,58432L,58433L,58434L,\n58435L,58436L,58437L,58438L,58439L,58440L,58441L,58442L,58443L,58444L,\n58445L,58446L,58447L,58448L,58449L,58450L,58451L,58452L,58453L,58454L,\n58455L,58456L,58457L,58458L,58459L,58460L,58461L,58462L,58463L,58464L,\n58465L,58466L,58467L,58468L,58469L,58470L,58471L,58472L,58473L,58474L,\n58475L,58476L,58477L,58478L,58479L,58480L,58481L,58482L,58483L,58484L,\n58485L,58486L,58487L,58488L,58489L,58490L,58491L,58492L,58493L,58494L,\n58495L,58496L,58497L,58498L,58499L,58500L,58501L,58502L,58503L,58504L,\n58505L,58506L,58507L,58508L,58509L,58510L,58511L,58512L,58513L,58514L,\n58515L,58516L,58517L,58518L,58519L,58520L,58521L,58522L,58523L,58524L,\n58525L,58526L,58527L,58528L,58529L,58530L,58531L,58532L,58533L,58534L,\n58535L,58536L,58537L,58538L,58539L,58540L,58541L,58542L,58543L,58544L,\n58545L,58546L,58547L,58548L,58549L,58550L,58551L,58552L,58553L,58554L,\n58555L,58556L,58557L,58558L,58559L,58560L,58561L,58562L,58563L,58564L,\n58565L,58566L,58567L,58568L,58569L,58570L,58571L,58572L,58573L,58574L,\n58575L,58576L,58577L,58578L,58579L,58580L,58581L,58582L,58583L,58584L,\n58585L,58586L,58587L,58588L,58589L,58590L,58591L,58592L,58593L,58594L,\n58595L,58596L,58597L,58598L,58599L,58600L,58601L,58602L,58603L,58604L,\n58605L,58606L,58607L,58608L,58609L,58610L,58611L,58612L,58613L,58614L,\n58615L,58616L,58617L,58618L,58619L,58620L,58621L,58622L,58623L,58624L,\n58625L,58626L,58627L,58628L,58629L,58630L,58631L,58632L,58633L,58634L,\n58635L,58636L,58637L,58638L,58639L,58640L,58641L,58642L,58643L,58644L,\n58645L,58646L,58647L,58648L,58649L,58650L,58651L,58652L,58653L,58654L,\n58655L,58656L,58657L,58658L,58659L,58660L,58661L,58662L,58663L,58664L,\n58665L,58666L,58667L,58668L,58669L,58670L,58671L,58672L,58673L,58674L,\n58675L,58676L,58677L,58678L,58679L,58680L,58681L,58682L,58683L,58684L,\n58685L,58686L,58687L,58688L,58689L,58690L,58691L,58692L,58693L,58694L,\n58695L,58696L,58697L,58698L,58699L,58700L,58701L,58702L,58703L,58704L,\n58705L,58706L,58707L,58708L,58709L,58710L,58711L,58712L,58713L,58714L,\n58715L,58716L,58717L,58718L,58719L,58720L,58721L,58722L,58723L,58724L,\n58725L,58726L,58727L,58728L,58729L,58730L,58731L,58732L,58733L,58734L,\n58735L,58736L,58737L,58738L,58739L,58740L,58741L,58742L,58743L,58744L,\n58745L,58746L,58747L,58748L,58749L,58750L,58751L,58752L,58753L,58754L,\n58755L,58756L,58757L,58758L,58759L,58760L,58761L,58762L,58763L,58764L,\n58765L,58766L,58767L,58768L,58769L,58770L,58771L,58772L,58773L,58774L,\n58775L,58776L,58777L,58778L,58779L,58780L,58781L,58782L,58783L,58784L,\n58785L,58786L,58787L,58788L,58789L,58790L,58791L,58792L,58793L,58794L,\n58795L,58796L,58797L,58798L,58799L,58800L,58801L,58802L,58803L,58804L,\n58805L,58806L,58807L,58808L,58809L,58810L,58811L,58812L,58813L,58814L,\n58815L,58816L,58817L,58818L,58819L,58820L,58821L,58822L,58823L,58824L,\n58825L,58826L,58827L,58828L,58829L,58830L,58831L,58832L,58833L,58834L,\n58835L,58836L,58837L,58838L,58839L,58840L,58841L,58842L,58843L,58844L,\n58845L,58846L,58847L,58848L,58849L,58850L,58851L,58852L,58853L,58854L,\n58855L,58856L,58857L,58858L,58859L,58860L,58861L,58862L,58863L,58864L,\n58865L,58866L,58867L,58868L,58869L,58870L,58871L,58872L,58873L,58874L,\n58875L,58876L,58877L,58878L,58879L,58880L,58881L,58882L,58883L,58884L,\n58885L,58886L,58887L,58888L,58889L,58890L,58891L,58892L,58893L,58894L,\n58895L,58896L,58897L,58898L,58899L,58900L,58901L,58902L,58903L,58904L,\n58905L,58906L,58907L,58908L,58909L,58910L,58911L,58912L,58913L,58914L,\n58915L,58916L,58917L,58918L,58919L,58920L,58921L,58922L,58923L,58924L,\n58925L,58926L,58927L,58928L,58929L,58930L,58931L,58932L,58933L,58934L,\n58935L,58936L,58937L,58938L,58939L,58940L,58941L,58942L,58943L,58944L,\n58945L,58946L,58947L,58948L,58949L,58950L,58951L,58952L,58953L,58954L,\n58955L,58956L,58957L,58958L,58959L,58960L,58961L,58962L,58963L,58964L,\n58965L,58966L,58967L,58968L,58969L,58970L,58971L,58972L,58973L,58974L,\n58975L,58976L,58977L,58978L,58979L,58980L,58981L,58982L,58983L,58984L,\n58985L,58986L,58987L,58988L,58989L,58990L,58991L,58992L,58993L,58994L,\n58995L,58996L,58997L,58998L,58999L,59000L,59001L,59002L,59003L,59004L,\n59005L,59006L,59007L,59008L,59009L,59010L,59011L,59012L,59013L,59014L,\n59015L,59016L,59017L,59018L,59019L,59020L,59021L,59022L,59023L,59024L,\n59025L,59026L,59027L,59028L,59029L,59030L,59031L,59032L,59033L,59034L,\n59035L,59036L,59037L,59038L,59039L,59040L,59041L,59042L,59043L,59044L,\n59045L,59046L,59047L,59048L,59049L,59050L,59051L,59052L,59053L,59054L,\n59055L,59056L,59057L,59058L,59059L,59060L,59061L,59062L,59063L,59064L,\n59065L,59066L,59067L,59068L,59069L,59070L,59071L,59072L,59073L,59074L,\n59075L,59076L,59077L,59078L,59079L,59080L,59081L,59082L,59083L,59084L,\n59085L,59086L,59087L,59088L,59089L,59090L,59091L,59092L,59093L,59094L,\n59095L,59096L,59097L,59098L,59099L,59100L,59101L,59102L,59103L,59104L,\n59105L,59106L,59107L,59108L,59109L,59110L,59111L,59112L,59113L,59114L,\n59115L,59116L,59117L,59118L,59119L,59120L,59121L,59122L,59123L,59124L,\n59125L,59126L,59127L,59128L,59129L,59130L,59131L,59132L,59133L,59134L,\n59135L,59136L,59137L,59138L,59139L,59140L,59141L,59142L,59143L,59144L,\n59145L,59146L,59147L,59148L,59149L,59150L,59151L,59152L,59153L,59154L,\n59155L,59156L,59157L,59158L,59159L,59160L,59161L,59162L,59163L,59164L,\n59165L,59166L,59167L,59168L,59169L,59170L,59171L,59172L,59173L,59174L,\n59175L,59176L,59177L,59178L,59179L,59180L,59181L,59182L,59183L,59184L,\n59185L,59186L,59187L,59188L,59189L,59190L,59191L,59192L,59193L,59194L,\n59195L,59196L,59197L,59198L,59199L,59200L,59201L,59202L,59203L,59204L,\n59205L,59206L,59207L,59208L,59209L,59210L,59211L,59212L,59213L,59214L,\n59215L,59216L,59217L,59218L,59219L,59220L,59221L,59222L,59223L,59224L,\n59225L,59226L,59227L,59228L,59229L,59230L,59231L,59232L,59233L,59234L,\n59235L,59236L,59237L,59238L,59239L,59240L,59241L,59242L,59243L,59244L,\n59245L,59246L,59247L,59248L,59249L,59250L,59251L,59252L,59253L,59254L,\n59255L,59256L,59257L,59258L,59259L,59260L,59261L,59262L,59263L,59264L,\n59265L,59266L,59267L,59268L,59269L,59270L,59271L,59272L,59273L,59274L,\n59275L,59276L,59277L,59278L,59279L,59280L,59281L,59282L,59283L,59284L,\n59285L,59286L,59287L,59288L,59289L,59290L,59291L,59292L,59293L,59294L,\n59295L,59296L,59297L,59298L,59299L,59300L,59301L,59302L,59303L,59304L,\n59305L,59306L,59307L,59308L,59309L,59310L,59311L,59312L,59313L,59314L,\n59315L,59316L,59317L,59318L,59319L,59320L,59321L,59322L,59323L,59324L,\n59325L,59326L,59327L,59328L,59329L,59330L,59331L,59332L,59333L,59334L,\n59335L,59336L,59337L,59338L,59339L,59340L,59341L,59342L,59343L,59344L,\n59345L,59346L,59347L,59348L,59349L,59350L,59351L,59352L,59353L,59354L,\n59355L,59356L,59357L,59358L,59359L,59360L,59361L,59362L,59363L,59364L,\n59365L,59366L,59367L,59368L,59369L,59370L,59371L,59372L,59373L,59374L,\n59375L,59376L,59377L,59378L,59379L,59380L,59381L,59382L,59383L,59384L,\n59385L,59386L,59387L,59388L,59389L,59390L,59391L,59392L,59393L,59394L,\n59395L,59396L,59397L,59398L,59399L,59400L,59401L,59402L,59403L,59404L,\n59405L,59406L,59407L,59408L,59409L,59410L,59411L,59412L,59413L,59414L,\n59415L,59416L,59417L,59418L,59419L,59420L,59421L,59422L,59423L,59424L,\n59425L,59426L,59427L,59428L,59429L,59430L,59431L,59432L,59433L,59434L,\n59435L,59436L,59437L,59438L,59439L,59440L,59441L,59442L,59443L,59444L,\n59445L,59446L,59447L,59448L,59449L,59450L,59451L,59452L,59453L,59454L,\n59455L,59456L,59457L,59458L,59459L,59460L,59461L,59462L,59463L,59464L,\n59465L,59466L,59467L,59468L,59469L,59470L,59471L,59472L,59473L,59474L,\n59475L,59476L,59477L,59478L,59479L,59480L,59481L,59482L,59483L,59484L,\n59485L,59486L,59487L,59488L,59489L,59490L,59491L,59492L,59493L,59494L,\n59495L,59496L,59497L,59498L,59499L,59500L,59501L,59502L,59503L,59504L,\n59505L,59506L,59507L,59508L,59509L,59510L,59511L,59512L,59513L,59514L,\n59515L,59516L,59517L,59518L,59519L,59520L,59521L,59522L,59523L,59524L,\n59525L,59526L,59527L,59528L,59529L,59530L,59531L,59532L,59533L,59534L,\n59535L,59536L,59537L,59538L,59539L,59540L,59541L,59542L,59543L,59544L,\n59545L,59546L,59547L,59548L,59549L,59550L,59551L,59552L,59553L,59554L,\n59555L,59556L,59557L,59558L,59559L,59560L,59561L,59562L,59563L,59564L,\n59565L,59566L,59567L,59568L,59569L,59570L,59571L,59572L,59573L,59574L,\n59575L,59576L,59577L,59578L,59579L,59580L,59581L,59582L,59583L,59584L,\n59585L,59586L,59587L,59588L,59589L,59590L,59591L,59592L,59593L,59594L,\n59595L,59596L,59597L,59598L,59599L,59600L,59601L,59602L,59603L,59604L,\n59605L,59606L,59607L,59608L,59609L,59610L,59611L,59612L,59613L,59614L,\n59615L,59616L,59617L,59618L,59619L,59620L,59621L,59622L,59623L,59624L,\n59625L,59626L,59627L,59628L,59629L,59630L,59631L,59632L,59633L,59634L,\n59635L,59636L,59637L,59638L,59639L,59640L,59641L,59642L,59643L,59644L,\n59645L,59646L,59647L,59648L,59649L,59650L,59651L,59652L,59653L,59654L,\n59655L,59656L,59657L,59658L,59659L,59660L,59661L,59662L,59663L,59664L,\n59665L,59666L,59667L,59668L,59669L,59670L,59671L,59672L,59673L,59674L,\n59675L,59676L,59677L,59678L,59679L,59680L,59681L,59682L,59683L,59684L,\n59685L,59686L,59687L,59688L,59689L,59690L,59691L,59692L,59693L,59694L,\n59695L,59696L,59697L,59698L,59699L,59700L,59701L,59702L,59703L,59704L,\n59705L,59706L,59707L,59708L,59709L,59710L,59711L,59712L,59713L,59714L,\n59715L,59716L,59717L,59718L,59719L,59720L,59721L,59722L,59723L,59724L,\n59725L,59726L,59727L,59728L,59729L,59730L,59731L,59732L,59733L,59734L,\n59735L,59736L,59737L,59738L,59739L,59740L,59741L,59742L,59743L,59744L,\n59745L,59746L,59747L,59748L,59749L,59750L,59751L,59752L,59753L,59754L,\n59755L,59756L,59757L,59758L,59759L,59760L,59761L,59762L,59763L,59764L,\n59765L,59766L,59767L,59768L,59769L,59770L,59771L,59772L,59773L,59774L,\n59775L,59776L,59777L,59778L,59779L,59780L,59781L,59782L,59783L,59784L,\n59785L,59786L,59787L,59788L,59789L,59790L,59791L,59792L,59793L,59794L,\n59795L,59796L,59797L,59798L,59799L,59800L,59801L,59802L,59803L,59804L,\n59805L,59806L,59807L,59808L,59809L,59810L,59811L,59812L,59813L,59814L,\n59815L,59816L,59817L,59818L,59819L,59820L,59821L,59822L,59823L,59824L,\n59825L,59826L,59827L,59828L,59829L,59830L,59831L,59832L,59833L,59834L,\n59835L,59836L,59837L,59838L,59839L,59840L,59841L,59842L,59843L,59844L,\n59845L,59846L,59847L,59848L,59849L,59850L,59851L,59852L,59853L,59854L,\n59855L,59856L,59857L,59858L,59859L,59860L,59861L,59862L,59863L,59864L,\n59865L,59866L,59867L,59868L,59869L,59870L,59871L,59872L,59873L,59874L,\n59875L,59876L,59877L,59878L,59879L,59880L,59881L,59882L,59883L,59884L,\n59885L,59886L,59887L,59888L,59889L,59890L,59891L,59892L,59893L,59894L,\n59895L,59896L,59897L,59898L,59899L,59900L,59901L,59902L,59903L,59904L,\n59905L,59906L,59907L,59908L,59909L,59910L,59911L,59912L,59913L,59914L,\n59915L,59916L,59917L,59918L,59919L,59920L,59921L,59922L,59923L,59924L,\n59925L,59926L,59927L,59928L,59929L,59930L,59931L,59932L,59933L,59934L,\n59935L,59936L,59937L,59938L,59939L,59940L,59941L,59942L,59943L,59944L,\n59945L,59946L,59947L,59948L,59949L,59950L,59951L,59952L,59953L,59954L,\n59955L,59956L,59957L,59958L,59959L,59960L,59961L,59962L,59963L,59964L,\n59965L,59966L,59967L,59968L,59969L,59970L,59971L,59972L,59973L,59974L,\n59975L,59976L,59977L,59978L,59979L,59980L,59981L,59982L,59983L,59984L,\n59985L,59986L,59987L,59988L,59989L,59990L,59991L,59992L,59993L,59994L,\n59995L,59996L,59997L,59998L,59999L,60000L,60001L,60002L,60003L,60004L,\n60005L,60006L,60007L,60008L,60009L,60010L,60011L,60012L,60013L,60014L,\n60015L,60016L,60017L,60018L,60019L,60020L,60021L,60022L,60023L,60024L,\n60025L,60026L,60027L,60028L,60029L,60030L,60031L,60032L,60033L,60034L,\n60035L,60036L,60037L,60038L,60039L,60040L,60041L,60042L,60043L,60044L,\n60045L,60046L,60047L,60048L,60049L,60050L,60051L,60052L,60053L,60054L,\n60055L,60056L,60057L,60058L,60059L,60060L,60061L,60062L,60063L,60064L,\n60065L,60066L,60067L,60068L,60069L,60070L,60071L,60072L,60073L,60074L,\n60075L,60076L,60077L,60078L,60079L,60080L,60081L,60082L,60083L,60084L,\n60085L,60086L,60087L,60088L,60089L,60090L,60091L,60092L,60093L,60094L,\n60095L,60096L,60097L,60098L,60099L,60100L,60101L,60102L,60103L,60104L,\n60105L,60106L,60107L,60108L,60109L,60110L,60111L,60112L,60113L,60114L,\n60115L,60116L,60117L,60118L,60119L,60120L,60121L,60122L,60123L,60124L,\n60125L,60126L,60127L,60128L,60129L,60130L,60131L,60132L,60133L,60134L,\n60135L,60136L,60137L,60138L,60139L,60140L,60141L,60142L,60143L,60144L,\n60145L,60146L,60147L,60148L,60149L,60150L,60151L,60152L,60153L,60154L,\n60155L,60156L,60157L,60158L,60159L,60160L,60161L,60162L,60163L,60164L,\n60165L,60166L,60167L,60168L,60169L,60170L,60171L,60172L,60173L,60174L,\n60175L,60176L,60177L,60178L,60179L,60180L,60181L,60182L,60183L,60184L,\n60185L,60186L,60187L,60188L,60189L,60190L,60191L,60192L,60193L,60194L,\n60195L,60196L,60197L,60198L,60199L,60200L,60201L,60202L,60203L,60204L,\n60205L,60206L,60207L,60208L,60209L,60210L,60211L,60212L,60213L,60214L,\n60215L,60216L,60217L,60218L,60219L,60220L,60221L,60222L,60223L,60224L,\n60225L,60226L,60227L,60228L,60229L,60230L,60231L,60232L,60233L,60234L,\n60235L,60236L,60237L,60238L,60239L,60240L,60241L,60242L,60243L,60244L,\n60245L,60246L,60247L,60248L,60249L,60250L,60251L,60252L,60253L,60254L,\n60255L,60256L,60257L,60258L,60259L,60260L,60261L,60262L,60263L,60264L,\n60265L,60266L,60267L,60268L,60269L,60270L,60271L,60272L,60273L,60274L,\n60275L,60276L,60277L,60278L,60279L,60280L,60281L,60282L,60283L,60284L,\n60285L,60286L,60287L,60288L,60289L,60290L,60291L,60292L,60293L,60294L,\n60295L,60296L,60297L,60298L,60299L,60300L,60301L,60302L,60303L,60304L,\n60305L,60306L,60307L,60308L,60309L,60310L,60311L,60312L,60313L,60314L,\n60315L,60316L,60317L,60318L,60319L,60320L,60321L,60322L,60323L,60324L,\n60325L,60326L,60327L,60328L,60329L,60330L,60331L,60332L,60333L,60334L,\n60335L,60336L,60337L,60338L,60339L,60340L,60341L,60342L,60343L,60344L,\n60345L,60346L,60347L,60348L,60349L,60350L,60351L,60352L,60353L,60354L,\n60355L,60356L,60357L,60358L,60359L,60360L,60361L,60362L,60363L,60364L,\n60365L,60366L,60367L,60368L,60369L,60370L,60371L,60372L,60373L,60374L,\n60375L,60376L,60377L,60378L,60379L,60380L,60381L,60382L,60383L,60384L,\n60385L,60386L,60387L,60388L,60389L,60390L,60391L,60392L,60393L,60394L,\n60395L,60396L,60397L,60398L,60399L,60400L,60401L,60402L,60403L,60404L,\n60405L,60406L,60407L,60408L,60409L,60410L,60411L,60412L,60413L,60414L,\n60415L,60416L,60417L,60418L,60419L,60420L,60421L,60422L,60423L,60424L,\n60425L,60426L,60427L,60428L,60429L,60430L,60431L,60432L,60433L,60434L,\n60435L,60436L,60437L,60438L,60439L,60440L,60441L,60442L,60443L,60444L,\n60445L,60446L,60447L,60448L,60449L,60450L,60451L,60452L,60453L,60454L,\n60455L,60456L,60457L,60458L,60459L,60460L,60461L,60462L,60463L,60464L,\n60465L,60466L,60467L,60468L,60469L,60470L,60471L,60472L,60473L,60474L,\n60475L,60476L,60477L,60478L,60479L,60480L,60481L,60482L,60483L,60484L,\n60485L,60486L,60487L,60488L,60489L,60490L,60491L,60492L,60493L,60494L,\n60495L,60496L,60497L,60498L,60499L,60500L,60501L,60502L,60503L,60504L,\n60505L,60506L,60507L,60508L,60509L,60510L,60511L,60512L,60513L,60514L,\n60515L,60516L,60517L,60518L,60519L,60520L,60521L,60522L,60523L,60524L,\n60525L,60526L,60527L,60528L,60529L,60530L,60531L,60532L,60533L,60534L,\n60535L,60536L,60537L,60538L,60539L,60540L,60541L,60542L,60543L,60544L,\n60545L,60546L,60547L,60548L,60549L,60550L,60551L,60552L,60553L,60554L,\n60555L,60556L,60557L,60558L,60559L,60560L,60561L,60562L,60563L,60564L,\n60565L,60566L,60567L,60568L,60569L,60570L,60571L,60572L,60573L,60574L,\n60575L,60576L,60577L,60578L,60579L,60580L,60581L,60582L,60583L,60584L,\n60585L,60586L,60587L,60588L,60589L,60590L,60591L,60592L,60593L,60594L,\n60595L,60596L,60597L,60598L,60599L,60600L,60601L,60602L,60603L,60604L,\n60605L,60606L,60607L,60608L,60609L,60610L,60611L,60612L,60613L,60614L,\n60615L,60616L,60617L,60618L,60619L,60620L,60621L,60622L,60623L,60624L,\n60625L,60626L,60627L,60628L,60629L,60630L,60631L,60632L,60633L,60634L,\n60635L,60636L,60637L,60638L,60639L,60640L,60641L,60642L,60643L,60644L,\n60645L,60646L,60647L,60648L,60649L,60650L,60651L,60652L,60653L,60654L,\n60655L,60656L,60657L,60658L,60659L,60660L,60661L,60662L,60663L,60664L,\n60665L,60666L,60667L,60668L,60669L,60670L,60671L,60672L,60673L,60674L,\n60675L,60676L,60677L,60678L,60679L,60680L,60681L,60682L,60683L,60684L,\n60685L,60686L,60687L,60688L,60689L,60690L,60691L,60692L,60693L,60694L,\n60695L,60696L,60697L,60698L,60699L,60700L,60701L,60702L,60703L,60704L,\n60705L,60706L,60707L,60708L,60709L,60710L,60711L,60712L,60713L,60714L,\n60715L,60716L,60717L,60718L,60719L,60720L,60721L,60722L,60723L,60724L,\n60725L,60726L,60727L,60728L,60729L,60730L,60731L,60732L,60733L,60734L,\n60735L,60736L,60737L,60738L,60739L,60740L,60741L,60742L,60743L,60744L,\n60745L,60746L,60747L,60748L,60749L,60750L,60751L,60752L,60753L,60754L,\n60755L,60756L,60757L,60758L,60759L,60760L,60761L,60762L,60763L,60764L,\n60765L,60766L,60767L,60768L,60769L,60770L,60771L,60772L,60773L,60774L,\n60775L,60776L,60777L,60778L,60779L,60780L,60781L,60782L,60783L,60784L,\n60785L,60786L,60787L,60788L,60789L,60790L,60791L,60792L,60793L,60794L,\n60795L,60796L,60797L,60798L,60799L,60800L,60801L,60802L,60803L,60804L,\n60805L,60806L,60807L,60808L,60809L,60810L,60811L,60812L,60813L,60814L,\n60815L,60816L,60817L,60818L,60819L,60820L,60821L,60822L,60823L,60824L,\n60825L,60826L,60827L,60828L,60829L,60830L,60831L,60832L,60833L,60834L,\n60835L,60836L,60837L,60838L,60839L,60840L,60841L,60842L,60843L,60844L,\n60845L,60846L,60847L,60848L,60849L,60850L,60851L,60852L,60853L,60854L,\n60855L,60856L,60857L,60858L,60859L,60860L,60861L,60862L,60863L,60864L,\n60865L,60866L,60867L,60868L,60869L,60870L,60871L,60872L,60873L,60874L,\n60875L,60876L,60877L,60878L,60879L,60880L,60881L,60882L,60883L,60884L,\n60885L,60886L,60887L,60888L,60889L,60890L,60891L,60892L,60893L,60894L,\n60895L,60896L,60897L,60898L,60899L,60900L,60901L,60902L,60903L,60904L,\n60905L,60906L,60907L,60908L,60909L,60910L,60911L,60912L,60913L,60914L,\n60915L,60916L,60917L,60918L,60919L,60920L,60921L,60922L,60923L,60924L,\n60925L,60926L,60927L,60928L,60929L,60930L,60931L,60932L,60933L,60934L,\n60935L,60936L,60937L,60938L,60939L,60940L,60941L,60942L,60943L,60944L,\n60945L,60946L,60947L,60948L,60949L,60950L,60951L,60952L,60953L,60954L,\n60955L,60956L,60957L,60958L,60959L,60960L,60961L,60962L,60963L,60964L,\n60965L,60966L,60967L,60968L,60969L,60970L,60971L,60972L,60973L,60974L,\n60975L,60976L,60977L,60978L,60979L,60980L,60981L,60982L,60983L,60984L,\n60985L,60986L,60987L,60988L,60989L,60990L,60991L,60992L,60993L,60994L,\n60995L,60996L,60997L,60998L,60999L,61000L,61001L,61002L,61003L,61004L,\n61005L,61006L,61007L,61008L,61009L,61010L,61011L,61012L,61013L,61014L,\n61015L,61016L,61017L,61018L,61019L,61020L,61021L,61022L,61023L,61024L,\n61025L,61026L,61027L,61028L,61029L,61030L,61031L,61032L,61033L,61034L,\n61035L,61036L,61037L,61038L,61039L,61040L,61041L,61042L,61043L,61044L,\n61045L,61046L,61047L,61048L,61049L,61050L,61051L,61052L,61053L,61054L,\n61055L,61056L,61057L,61058L,61059L,61060L,61061L,61062L,61063L,61064L,\n61065L,61066L,61067L,61068L,61069L,61070L,61071L,61072L,61073L,61074L,\n61075L,61076L,61077L,61078L,61079L,61080L,61081L,61082L,61083L,61084L,\n61085L,61086L,61087L,61088L,61089L,61090L,61091L,61092L,61093L,61094L,\n61095L,61096L,61097L,61098L,61099L,61100L,61101L,61102L,61103L,61104L,\n61105L,61106L,61107L,61108L,61109L,61110L,61111L,61112L,61113L,61114L,\n61115L,61116L,61117L,61118L,61119L,61120L,61121L,61122L,61123L,61124L,\n61125L,61126L,61127L,61128L,61129L,61130L,61131L,61132L,61133L,61134L,\n61135L,61136L,61137L,61138L,61139L,61140L,61141L,61142L,61143L,61144L,\n61145L,61146L,61147L,61148L,61149L,61150L,61151L,61152L,61153L,61154L,\n61155L,61156L,61157L,61158L,61159L,61160L,61161L,61162L,61163L,61164L,\n61165L,61166L,61167L,61168L,61169L,61170L,61171L,61172L,61173L,61174L,\n61175L,61176L,61177L,61178L,61179L,61180L,61181L,61182L,61183L,61184L,\n61185L,61186L,61187L,61188L,61189L,61190L,61191L,61192L,61193L,61194L,\n61195L,61196L,61197L,61198L,61199L,61200L,61201L,61202L,61203L,61204L,\n61205L,61206L,61207L,61208L,61209L,61210L,61211L,61212L,61213L,61214L,\n61215L,61216L,61217L,61218L,61219L,61220L,61221L,61222L,61223L,61224L,\n61225L,61226L,61227L,61228L,61229L,61230L,61231L,61232L,61233L,61234L,\n61235L,61236L,61237L,61238L,61239L,61240L,61241L,61242L,61243L,61244L,\n61245L,61246L,61247L,61248L,61249L,61250L,61251L,61252L,61253L,61254L,\n61255L,61256L,61257L,61258L,61259L,61260L,61261L,61262L,61263L,61264L,\n61265L,61266L,61267L,61268L,61269L,61270L,61271L,61272L,61273L,61274L,\n61275L,61276L,61277L,61278L,61279L,61280L,61281L,61282L,61283L,61284L,\n61285L,61286L,61287L,61288L,61289L,61290L,61291L,61292L,61293L,61294L,\n61295L,61296L,61297L,61298L,61299L,61300L,61301L,61302L,61303L,61304L,\n61305L,61306L,61307L,61308L,61309L,61310L,61311L,61312L,61313L,61314L,\n61315L,61316L,61317L,61318L,61319L,61320L,61321L,61322L,61323L,61324L,\n61325L,61326L,61327L,61328L,61329L,61330L,61331L,61332L,61333L,61334L,\n61335L,61336L,61337L,61338L,61339L,61340L,61341L,61342L,61343L,61344L,\n61345L,61346L,61347L,61348L,61349L,61350L,61351L,61352L,61353L,61354L,\n61355L,61356L,61357L,61358L,61359L,61360L,61361L,61362L,61363L,61364L,\n61365L,61366L,61367L,61368L,61369L,61370L,61371L,61372L,61373L,61374L,\n61375L,61376L,61377L,61378L,61379L,61380L,61381L,61382L,61383L,61384L,\n61385L,61386L,61387L,61388L,61389L,61390L,61391L,61392L,61393L,61394L,\n61395L,61396L,61397L,61398L,61399L,61400L,61401L,61402L,61403L,61404L,\n61405L,61406L,61407L,61408L,61409L,61410L,61411L,61412L,61413L,61414L,\n61415L,61416L,61417L,61418L,61419L,61420L,61421L,61422L,61423L,61424L,\n61425L,61426L,61427L,61428L,61429L,61430L,61431L,61432L,61433L,61434L,\n61435L,61436L,61437L,61438L,61439L,61440L,61441L,61442L,61443L,61444L,\n61445L,61446L,61447L,61448L,61449L,61450L,61451L,61452L,61453L,61454L,\n61455L,61456L,61457L,61458L,61459L,61460L,61461L,61462L,61463L,61464L,\n61465L,61466L,61467L,61468L,61469L,61470L,61471L,61472L,61473L,61474L,\n61475L,61476L,61477L,61478L,61479L,61480L,61481L,61482L,61483L,61484L,\n61485L,61486L,61487L,61488L,61489L,61490L,61491L,61492L,61493L,61494L,\n61495L,61496L,61497L,61498L,61499L,61500L,61501L,61502L,61503L,61504L,\n61505L,61506L,61507L,61508L,61509L,61510L,61511L,61512L,61513L,61514L,\n61515L,61516L,61517L,61518L,61519L,61520L,61521L,61522L,61523L,61524L,\n61525L,61526L,61527L,61528L,61529L,61530L,61531L,61532L,61533L,61534L,\n61535L,61536L,61537L,61538L,61539L,61540L,61541L,61542L,61543L,61544L,\n61545L,61546L,61547L,61548L,61549L,61550L,61551L,61552L,61553L,61554L,\n61555L,61556L,61557L,61558L,61559L,61560L,61561L,61562L,61563L,61564L,\n61565L,61566L,61567L,61568L,61569L,61570L,61571L,61572L,61573L,61574L,\n61575L,61576L,61577L,61578L,61579L,61580L,61581L,61582L,61583L,61584L,\n61585L,61586L,61587L,61588L,61589L,61590L,61591L,61592L,61593L,61594L,\n61595L,61596L,61597L,61598L,61599L,61600L,61601L,61602L,61603L,61604L,\n61605L,61606L,61607L,61608L,61609L,61610L,61611L,61612L,61613L,61614L,\n61615L,61616L,61617L,61618L,61619L,61620L,61621L,61622L,61623L,61624L,\n61625L,61626L,61627L,61628L,61629L,61630L,61631L,61632L,61633L,61634L,\n61635L,61636L,61637L,61638L,61639L,61640L,61641L,61642L,61643L,61644L,\n61645L,61646L,61647L,61648L,61649L,61650L,61651L,61652L,61653L,61654L,\n61655L,61656L,61657L,61658L,61659L,61660L,61661L,61662L,61663L,61664L,\n61665L,61666L,61667L,61668L,61669L,61670L,61671L,61672L,61673L,61674L,\n61675L,61676L,61677L,61678L,61679L,61680L,61681L,61682L,61683L,61684L,\n61685L,61686L,61687L,61688L,61689L,61690L,61691L,61692L,61693L,61694L,\n61695L,61696L,61697L,61698L,61699L,61700L,61701L,61702L,61703L,61704L,\n61705L,61706L,61707L,61708L,61709L,61710L,61711L,61712L,61713L,61714L,\n61715L,61716L,61717L,61718L,61719L,61720L,61721L,61722L,61723L,61724L,\n61725L,61726L,61727L,61728L,61729L,61730L,61731L,61732L,61733L,61734L,\n61735L,61736L,61737L,61738L,61739L,61740L,61741L,61742L,61743L,61744L,\n61745L,61746L,61747L,61748L,61749L,61750L,61751L,61752L,61753L,61754L,\n61755L,61756L,61757L,61758L,61759L,61760L,61761L,61762L,61763L,61764L,\n61765L,61766L,61767L,61768L,61769L,61770L,61771L,61772L,61773L,61774L,\n61775L,61776L,61777L,61778L,61779L,61780L,61781L,61782L,61783L,61784L,\n61785L,61786L,61787L,61788L,61789L,61790L,61791L,61792L,61793L,61794L,\n61795L,61796L,61797L,61798L,61799L,61800L,61801L,61802L,61803L,61804L,\n61805L,61806L,61807L,61808L,61809L,61810L,61811L,61812L,61813L,61814L,\n61815L,61816L,61817L,61818L,61819L,61820L,61821L,61822L,61823L,61824L,\n61825L,61826L,61827L,61828L,61829L,61830L,61831L,61832L,61833L,61834L,\n61835L,61836L,61837L,61838L,61839L,61840L,61841L,61842L,61843L,61844L,\n61845L,61846L,61847L,61848L,61849L,61850L,61851L,61852L,61853L,61854L,\n61855L,61856L,61857L,61858L,61859L,61860L,61861L,61862L,61863L,61864L,\n61865L,61866L,61867L,61868L,61869L,61870L,61871L,61872L,61873L,61874L,\n61875L,61876L,61877L,61878L,61879L,61880L,61881L,61882L,61883L,61884L,\n61885L,61886L,61887L,61888L,61889L,61890L,61891L,61892L,61893L,61894L,\n61895L,61896L,61897L,61898L,61899L,61900L,61901L,61902L,61903L,61904L,\n61905L,61906L,61907L,61908L,61909L,61910L,61911L,61912L,61913L,61914L,\n61915L,61916L,61917L,61918L,61919L,61920L,61921L,61922L,61923L,61924L,\n61925L,61926L,61927L,61928L,61929L,61930L,61931L,61932L,61933L,61934L,\n61935L,61936L,61937L,61938L,61939L,61940L,61941L,61942L,61943L,61944L,\n61945L,61946L,61947L,61948L,61949L,61950L,61951L,61952L,61953L,61954L,\n61955L,61956L,61957L,61958L,61959L,61960L,61961L,61962L,61963L,61964L,\n61965L,61966L,61967L,61968L,61969L,61970L,61971L,61972L,61973L,61974L,\n61975L,61976L,61977L,61978L,61979L,61980L,61981L,61982L,61983L,61984L,\n61985L,61986L,61987L,61988L,61989L,61990L,61991L,61992L,61993L,61994L,\n61995L,61996L,61997L,61998L,61999L,62000L,62001L,62002L,62003L,62004L,\n62005L,62006L,62007L,62008L,62009L,62010L,62011L,62012L,62013L,62014L,\n62015L,62016L,62017L,62018L,62019L,62020L,62021L,62022L,62023L,62024L,\n62025L,62026L,62027L,62028L,62029L,62030L,62031L,62032L,62033L,62034L,\n62035L,62036L,62037L,62038L,62039L,62040L,62041L,62042L,62043L,62044L,\n62045L,62046L,62047L,62048L,62049L,62050L,62051L,62052L,62053L,62054L,\n62055L,62056L,62057L,62058L,62059L,62060L,62061L,62062L,62063L,62064L,\n62065L,62066L,62067L,62068L,62069L,62070L,62071L,62072L,62073L,62074L,\n62075L,62076L,62077L,62078L,62079L,62080L,62081L,62082L,62083L,62084L,\n62085L,62086L,62087L,62088L,62089L,62090L,62091L,62092L,62093L,62094L,\n62095L,62096L,62097L,62098L,62099L,62100L,62101L,62102L,62103L,62104L,\n62105L,62106L,62107L,62108L,62109L,62110L,62111L,62112L,62113L,62114L,\n62115L,62116L,62117L,62118L,62119L,62120L,62121L,62122L,62123L,62124L,\n62125L,62126L,62127L,62128L,62129L,62130L,62131L,62132L,62133L,62134L,\n62135L,62136L,62137L,62138L,62139L,62140L,62141L,62142L,62143L,62144L,\n62145L,62146L,62147L,62148L,62149L,62150L,62151L,62152L,62153L,62154L,\n62155L,62156L,62157L,62158L,62159L,62160L,62161L,62162L,62163L,62164L,\n62165L,62166L,62167L,62168L,62169L,62170L,62171L,62172L,62173L,62174L,\n62175L,62176L,62177L,62178L,62179L,62180L,62181L,62182L,62183L,62184L,\n62185L,62186L,62187L,62188L,62189L,62190L,62191L,62192L,62193L,62194L,\n62195L,62196L,62197L,62198L,62199L,62200L,62201L,62202L,62203L,62204L,\n62205L,62206L,62207L,62208L,62209L,62210L,62211L,62212L,62213L,62214L,\n62215L,62216L,62217L,62218L,62219L,62220L,62221L,62222L,62223L,62224L,\n62225L,62226L,62227L,62228L,62229L,62230L,62231L,62232L,62233L,62234L,\n62235L,62236L,62237L,62238L,62239L,62240L,62241L,62242L,62243L,62244L,\n62245L,62246L,62247L,62248L,62249L,62250L,62251L,62252L,62253L,62254L,\n62255L,62256L,62257L,62258L,62259L,62260L,62261L,62262L,62263L,62264L,\n62265L,62266L,62267L,62268L,62269L,62270L,62271L,62272L,62273L,62274L,\n62275L,62276L,62277L,62278L,62279L,62280L,62281L,62282L,62283L,62284L,\n62285L,62286L,62287L,62288L,62289L,62290L,62291L,62292L,62293L,62294L,\n62295L,62296L,62297L,62298L,62299L,62300L,62301L,62302L,62303L,62304L,\n62305L,62306L,62307L,62308L,62309L,62310L,62311L,62312L,62313L,62314L,\n62315L,62316L,62317L,62318L,62319L,62320L,62321L,62322L,62323L,62324L,\n62325L,62326L,62327L,62328L,62329L,62330L,62331L,62332L,62333L,62334L,\n62335L,62336L,62337L,62338L,62339L,62340L,62341L,62342L,62343L,62344L,\n62345L,62346L,62347L,62348L,62349L,62350L,62351L,62352L,62353L,62354L,\n62355L,62356L,62357L,62358L,62359L,62360L,62361L,62362L,62363L,62364L,\n62365L,62366L,62367L,62368L,62369L,62370L,62371L,62372L,62373L,62374L,\n62375L,62376L,62377L,62378L,62379L,62380L,62381L,62382L,62383L,62384L,\n62385L,62386L,62387L,62388L,62389L,62390L,62391L,62392L,62393L,62394L,\n62395L,62396L,62397L,62398L,62399L,62400L,62401L,62402L,62403L,62404L,\n62405L,62406L,62407L,62408L,62409L,62410L,62411L,62412L,62413L,62414L,\n62415L,62416L,62417L,62418L,62419L,62420L,62421L,62422L,62423L,62424L,\n62425L,62426L,62427L,62428L,62429L,62430L,62431L,62432L,62433L,62434L,\n62435L,62436L,62437L,62438L,62439L,62440L,62441L,62442L,62443L,62444L,\n62445L,62446L,62447L,62448L,62449L,62450L,62451L,62452L,62453L,62454L,\n62455L,62456L,62457L,62458L,62459L,62460L,62461L,62462L,62463L,62464L,\n62465L,62466L,62467L,62468L,62469L,62470L,62471L,62472L,62473L,62474L,\n62475L,62476L,62477L,62478L,62479L,62480L,62481L,62482L,62483L,62484L,\n62485L,62486L,62487L,62488L,62489L,62490L,62491L,62492L,62493L,62494L,\n62495L,62496L,62497L,62498L,62499L,62500L,62501L,62502L,62503L,62504L,\n62505L,62506L,62507L,62508L,62509L,62510L,62511L,62512L,62513L,62514L,\n62515L,62516L,62517L,62518L,62519L,62520L,62521L,62522L,62523L,62524L,\n62525L,62526L,62527L,62528L,62529L,62530L,62531L,62532L,62533L,62534L,\n62535L,62536L,62537L,62538L,62539L,62540L,62541L,62542L,62543L,62544L,\n62545L,62546L,62547L,62548L,62549L,62550L,62551L,62552L,62553L,62554L,\n62555L,62556L,62557L,62558L,62559L,62560L,62561L,62562L,62563L,62564L,\n62565L,62566L,62567L,62568L,62569L,62570L,62571L,62572L,62573L,62574L,\n62575L,62576L,62577L,62578L,62579L,62580L,62581L,62582L,62583L,62584L,\n62585L,62586L,62587L,62588L,62589L,62590L,62591L,62592L,62593L,62594L,\n62595L,62596L,62597L,62598L,62599L,62600L,62601L,62602L,62603L,62604L,\n62605L,62606L,62607L,62608L,62609L,62610L,62611L,62612L,62613L,62614L,\n62615L,62616L,62617L,62618L,62619L,62620L,62621L,62622L,62623L,62624L,\n62625L,62626L,62627L,62628L,62629L,62630L,62631L,62632L,62633L,62634L,\n62635L,62636L,62637L,62638L,62639L,62640L,62641L,62642L,62643L,62644L,\n62645L,62646L,62647L,62648L,62649L,62650L,62651L,62652L,62653L,62654L,\n62655L,62656L,62657L,62658L,62659L,62660L,62661L,62662L,62663L,62664L,\n62665L,62666L,62667L,62668L,62669L,62670L,62671L,62672L,62673L,62674L,\n62675L,62676L,62677L,62678L,62679L,62680L,62681L,62682L,62683L,62684L,\n62685L,62686L,62687L,62688L,62689L,62690L,62691L,62692L,62693L,62694L,\n62695L,62696L,62697L,62698L,62699L,62700L,62701L,62702L,62703L,62704L,\n62705L,62706L,62707L,62708L,62709L,62710L,62711L,62712L,62713L,62714L,\n62715L,62716L,62717L,62718L,62719L,62720L,62721L,62722L,62723L,62724L,\n62725L,62726L,62727L,62728L,62729L,62730L,62731L,62732L,62733L,62734L,\n62735L,62736L,62737L,62738L,62739L,62740L,62741L,62742L,62743L,62744L,\n62745L,62746L,62747L,62748L,62749L,62750L,62751L,62752L,62753L,62754L,\n62755L,62756L,62757L,62758L,62759L,62760L,62761L,62762L,62763L,62764L,\n62765L,62766L,62767L,62768L,62769L,62770L,62771L,62772L,62773L,62774L,\n62775L,62776L,62777L,62778L,62779L,62780L,62781L,62782L,62783L,62784L,\n62785L,62786L,62787L,62788L,62789L,62790L,62791L,62792L,62793L,62794L,\n62795L,62796L,62797L,62798L,62799L,62800L,62801L,62802L,62803L,62804L,\n62805L,62806L,62807L,62808L,62809L,62810L,62811L,62812L,62813L,62814L,\n62815L,62816L,62817L,62818L,62819L,62820L,62821L,62822L,62823L,62824L,\n62825L,62826L,62827L,62828L,62829L,62830L,62831L,62832L,62833L,62834L,\n62835L,62836L,62837L,62838L,62839L,62840L,62841L,62842L,62843L,62844L,\n62845L,62846L,62847L,62848L,62849L,62850L,62851L,62852L,62853L,62854L,\n62855L,62856L,62857L,62858L,62859L,62860L,62861L,62862L,62863L,62864L,\n62865L,62866L,62867L,62868L,62869L,62870L,62871L,62872L,62873L,62874L,\n62875L,62876L,62877L,62878L,62879L,62880L,62881L,62882L,62883L,62884L,\n62885L,62886L,62887L,62888L,62889L,62890L,62891L,62892L,62893L,62894L,\n62895L,62896L,62897L,62898L,62899L,62900L,62901L,62902L,62903L,62904L,\n62905L,62906L,62907L,62908L,62909L,62910L,62911L,62912L,62913L,62914L,\n62915L,62916L,62917L,62918L,62919L,62920L,62921L,62922L,62923L,62924L,\n62925L,62926L,62927L,62928L,62929L,62930L,62931L,62932L,62933L,62934L,\n62935L,62936L,62937L,62938L,62939L,62940L,62941L,62942L,62943L,62944L,\n62945L,62946L,62947L,62948L,62949L,62950L,62951L,62952L,62953L,62954L,\n62955L,62956L,62957L,62958L,62959L,62960L,62961L,62962L,62963L,62964L,\n62965L,62966L,62967L,62968L,62969L,62970L,62971L,62972L,62973L,62974L,\n62975L,62976L,62977L,62978L,62979L,62980L,62981L,62982L,62983L,62984L,\n62985L,62986L,62987L,62988L,62989L,62990L,62991L,62992L,62993L,62994L,\n62995L,62996L,62997L,62998L,62999L,63000L,63001L,63002L,63003L,63004L,\n63005L,63006L,63007L,63008L,63009L,63010L,63011L,63012L,63013L,63014L,\n63015L,63016L,63017L,63018L,63019L,63020L,63021L,63022L,63023L,63024L,\n63025L,63026L,63027L,63028L,63029L,63030L,63031L,63032L,63033L,63034L,\n63035L,63036L,63037L,63038L,63039L,63040L,63041L,63042L,63043L,63044L,\n63045L,63046L,63047L,63048L,63049L,63050L,63051L,63052L,63053L,63054L,\n63055L,63056L,63057L,63058L,63059L,63060L,63061L,63062L,63063L,63064L,\n63065L,63066L,63067L,63068L,63069L,63070L,63071L,63072L,63073L,63074L,\n63075L,63076L,63077L,63078L,63079L,63080L,63081L,63082L,63083L,63084L,\n63085L,63086L,63087L,63088L,63089L,63090L,63091L,63092L,63093L,63094L,\n63095L,63096L,63097L,63098L,63099L,63100L,63101L,63102L,63103L,63104L,\n63105L,63106L,63107L,63108L,63109L,63110L,63111L,63112L,63113L,63114L,\n63115L,63116L,63117L,63118L,63119L,63120L,63121L,63122L,63123L,63124L,\n63125L,63126L,63127L,63128L,63129L,63130L,63131L,63132L,63133L,63134L,\n63135L,63136L,63137L,63138L,63139L,63140L,63141L,63142L,63143L,63144L,\n63145L,63146L,63147L,63148L,63149L,63150L,63151L,63152L,63153L,63154L,\n63155L,63156L,63157L,63158L,63159L,63160L,63161L,63162L,63163L,63164L,\n63165L,63166L,63167L,63168L,63169L,63170L,63171L,63172L,63173L,63174L,\n63175L,63176L,63177L,63178L,63179L,63180L,63181L,63182L,63183L,63184L,\n63185L,63186L,63187L,63188L,63189L,63190L,63191L,63192L,63193L,63194L,\n63195L,63196L,63197L,63198L,63199L,63200L,63201L,63202L,63203L,63204L,\n63205L,63206L,63207L,63208L,63209L,63210L,63211L,63212L,63213L,63214L,\n63215L,63216L,63217L,63218L,63219L,63220L,63221L,63222L,63223L,63224L,\n63225L,63226L,63227L,63228L,63229L,63230L,63231L,63232L,63233L,63234L,\n63235L,63236L,63237L,63238L,63239L,63240L,63241L,63242L,63243L,63244L,\n63245L,63246L,63247L,63248L,63249L,63250L,63251L,63252L,63253L,63254L,\n63255L,63256L,63257L,63258L,63259L,63260L,63261L,63262L,63263L,63264L,\n63265L,63266L,63267L,63268L,63269L,63270L,63271L,63272L,63273L,63274L,\n63275L,63276L,63277L,63278L,63279L,63280L,63281L,63282L,63283L,63284L,\n63285L,63286L,63287L,63288L,63289L,63290L,63291L,63292L,63293L,63294L,\n63295L,63296L,63297L,63298L,63299L,63300L,63301L,63302L,63303L,63304L,\n63305L,63306L,63307L,63308L,63309L,63310L,63311L,63312L,63313L,63314L,\n63315L,63316L,63317L,63318L,63319L,63320L,63321L,63322L,63323L,63324L,\n63325L,63326L,63327L,63328L,63329L,63330L,63331L,63332L,63333L,63334L,\n63335L,63336L,63337L,63338L,63339L,63340L,63341L,63342L,63343L,63344L,\n63345L,63346L,63347L,63348L,63349L,63350L,63351L,63352L,63353L,63354L,\n63355L,63356L,63357L,63358L,63359L,63360L,63361L,63362L,63363L,63364L,\n63365L,63366L,63367L,63368L,63369L,63370L,63371L,63372L,63373L,63374L,\n63375L,63376L,63377L,63378L,63379L,63380L,63381L,63382L,63383L,63384L,\n63385L,63386L,63387L,63388L,63389L,63390L,63391L,63392L,63393L,63394L,\n63395L,63396L,63397L,63398L,63399L,63400L,63401L,63402L,63403L,63404L,\n63405L,63406L,63407L,63408L,63409L,63410L,63411L,63412L,63413L,63414L,\n63415L,63416L,63417L,63418L,63419L,63420L,63421L,63422L,63423L,63424L,\n63425L,63426L,63427L,63428L,63429L,63430L,63431L,63432L,63433L,63434L,\n63435L,63436L,63437L,63438L,63439L,63440L,63441L,63442L,63443L,63444L,\n63445L,63446L,63447L,63448L,63449L,63450L,63451L,63452L,63453L,63454L,\n63455L,63456L,63457L,63458L,63459L,63460L,63461L,63462L,63463L,63464L,\n63465L,63466L,63467L,63468L,63469L,63470L,63471L,63472L,63473L,63474L,\n63475L,63476L,63477L,63478L,63479L,63480L,63481L,63482L,63483L,63484L,\n63485L,63486L,63487L,63488L,63489L,63490L,63491L,63492L,63493L,63494L,\n63495L,63496L,63497L,63498L,63499L,63500L,63501L,63502L,63503L,63504L,\n63505L,63506L,63507L,63508L,63509L,63510L,63511L,63512L,63513L,63514L,\n63515L,63516L,63517L,63518L,63519L,63520L,63521L,63522L,63523L,63524L,\n63525L,63526L,63527L,63528L,63529L,63530L,63531L,63532L,63533L,63534L,\n63535L,63536L,63537L,63538L,63539L,63540L,63541L,63542L,63543L,63544L,\n63545L,63546L,63547L,63548L,63549L,63550L,63551L,63552L,63553L,63554L,\n63555L,63556L,63557L,63558L,63559L,63560L,63561L,63562L,63563L,63564L,\n63565L,63566L,63567L,63568L,63569L,63570L,63571L,63572L,63573L,63574L,\n63575L,63576L,63577L,63578L,63579L,63580L,63581L,63582L,63583L,63584L,\n63585L,63586L,63587L,63588L,63589L,63590L,63591L,63592L,63593L,63594L,\n63595L,63596L,63597L,63598L,63599L,63600L,63601L,63602L,63603L,63604L,\n63605L,63606L,63607L,63608L,63609L,63610L,63611L,63612L,63613L,63614L,\n63615L,63616L,63617L,63618L,63619L,63620L,63621L,63622L,63623L,63624L,\n63625L,63626L,63627L,63628L,63629L,63630L,63631L,63632L,63633L,63634L,\n63635L,63636L,63637L,63638L,63639L,63640L,63641L,63642L,63643L,63644L,\n63645L,63646L,63647L,63648L,63649L,63650L,63651L,63652L,63653L,63654L,\n63655L,63656L,63657L,63658L,63659L,63660L,63661L,63662L,63663L,63664L,\n63665L,63666L,63667L,63668L,63669L,63670L,63671L,63672L,63673L,63674L,\n63675L,63676L,63677L,63678L,63679L,63680L,63681L,63682L,63683L,63684L,\n63685L,63686L,63687L,63688L,63689L,63690L,63691L,63692L,63693L,63694L,\n63695L,63696L,63697L,63698L,63699L,63700L,63701L,63702L,63703L,63704L,\n63705L,63706L,63707L,63708L,63709L,63710L,63711L,63712L,63713L,63714L,\n63715L,63716L,63717L,63718L,63719L,63720L,63721L,63722L,63723L,63724L,\n63725L,63726L,63727L,63728L,63729L,63730L,63731L,63732L,63733L,63734L,\n63735L,63736L,63737L,63738L,63739L,63740L,63741L,63742L,63743L,63744L,\n63745L,63746L,63747L,63748L,63749L,63750L,63751L,63752L,63753L,63754L,\n63755L,63756L,63757L,63758L,63759L,63760L,63761L,63762L,63763L,63764L,\n63765L,63766L,63767L,63768L,63769L,63770L,63771L,63772L,63773L,63774L,\n63775L,63776L,63777L,63778L,63779L,63780L,63781L,63782L,63783L,63784L,\n63785L,63786L,63787L,63788L,63789L,63790L,63791L,63792L,63793L,63794L,\n63795L,63796L,63797L,63798L,63799L,63800L,63801L,63802L,63803L,63804L,\n63805L,63806L,63807L,63808L,63809L,63810L,63811L,63812L,63813L,63814L,\n63815L,63816L,63817L,63818L,63819L,63820L,63821L,63822L,63823L,63824L,\n63825L,63826L,63827L,63828L,63829L,63830L,63831L,63832L,63833L,63834L,\n63835L,63836L,63837L,63838L,63839L,63840L,63841L,63842L,63843L,63844L,\n63845L,63846L,63847L,63848L,63849L,63850L,63851L,63852L,63853L,63854L,\n63855L,63856L,63857L,63858L,63859L,63860L,63861L,63862L,63863L,63864L,\n63865L,63866L,63867L,63868L,63869L,63870L,63871L,63872L,63873L,63874L,\n63875L,63876L,63877L,63878L,63879L,63880L,63881L,63882L,63883L,63884L,\n63885L,63886L,63887L,63888L,63889L,63890L,63891L,63892L,63893L,63894L,\n63895L,63896L,63897L,63898L,63899L,63900L,63901L,63902L,63903L,63904L,\n63905L,63906L,63907L,63908L,63909L,63910L,63911L,63912L,63913L,63914L,\n63915L,63916L,63917L,63918L,63919L,63920L,63921L,63922L,63923L,63924L,\n63925L,63926L,63927L,63928L,63929L,63930L,63931L,63932L,63933L,63934L,\n63935L,63936L,63937L,63938L,63939L,63940L,63941L,63942L,63943L,63944L,\n63945L,63946L,63947L,63948L,63949L,63950L,63951L,63952L,63953L,63954L,\n63955L,63956L,63957L,63958L,63959L,63960L,63961L,63962L,63963L,63964L,\n63965L,63966L,63967L,63968L,63969L,63970L,63971L,63972L,63973L,63974L,\n63975L,63976L,63977L,63978L,63979L,63980L,63981L,63982L,63983L,63984L,\n63985L,63986L,63987L,63988L,63989L,63990L,63991L,63992L,63993L,63994L,\n63995L,63996L,63997L,63998L,63999L,64000L,64001L,64002L,64003L,64004L,\n64005L,64006L,64007L,64008L,64009L,64010L,64011L,64012L,64013L,64014L,\n64015L,64016L,64017L,64018L,64019L,64020L,64021L,64022L,64023L,64024L,\n64025L,64026L,64027L,64028L,64029L,64030L,64031L,64032L,64033L,64034L,\n64035L,64036L,64037L,64038L,64039L,64040L,64041L,64042L,64043L,64044L,\n64045L,64046L,64047L,64048L,64049L,64050L,64051L,64052L,64053L,64054L,\n64055L,64056L,64057L,64058L,64059L,64060L,64061L,64062L,64063L,64064L,\n64065L,64066L,64067L,64068L,64069L,64070L,64071L,64072L,64073L,64074L,\n64075L,64076L,64077L,64078L,64079L,64080L,64081L,64082L,64083L,64084L,\n64085L,64086L,64087L,64088L,64089L,64090L,64091L,64092L,64093L,64094L,\n64095L,64096L,64097L,64098L,64099L,64100L,64101L,64102L,64103L,64104L,\n64105L,64106L,64107L,64108L,64109L,64110L,64111L,64112L,64113L,64114L,\n64115L,64116L,64117L,64118L,64119L,64120L,64121L,64122L,64123L,64124L,\n64125L,64126L,64127L,64128L,64129L,64130L,64131L,64132L,64133L,64134L,\n64135L,64136L,64137L,64138L,64139L,64140L,64141L,64142L,64143L,64144L,\n64145L,64146L,64147L,64148L,64149L,64150L,64151L,64152L,64153L,64154L,\n64155L,64156L,64157L,64158L,64159L,64160L,64161L,64162L,64163L,64164L,\n64165L,64166L,64167L,64168L,64169L,64170L,64171L,64172L,64173L,64174L,\n64175L,64176L,64177L,64178L,64179L,64180L,64181L,64182L,64183L,64184L,\n64185L,64186L,64187L,64188L,64189L,64190L,64191L,64192L,64193L,64194L,\n64195L,64196L,64197L,64198L,64199L,64200L,64201L,64202L,64203L,64204L,\n64205L,64206L,64207L,64208L,64209L,64210L,64211L,64212L,64213L,64214L,\n64215L,64216L,64217L,64218L,64219L,64220L,64221L,64222L,64223L,64224L,\n64225L,64226L,64227L,64228L,64229L,64230L,64231L,64232L,64233L,64234L,\n64235L,64236L,64237L,64238L,64239L,64240L,64241L,64242L,64243L,64244L,\n64245L,64246L,64247L,64248L,64249L,64250L,64251L,64252L,64253L,64254L,\n64255L,64256L,64257L,64258L,64259L,64260L,64261L,64262L,64263L,64264L,\n64265L,64266L,64267L,64268L,64269L,64270L,64271L,64272L,64273L,64274L,\n64275L,64276L,64277L,64278L,64279L,64280L,64281L,64282L,64283L,64284L,\n64285L,64286L,64287L,64288L,64289L,64290L,64291L,64292L,64293L,64294L,\n64295L,64296L,64297L,64298L,64299L,64300L,64301L,64302L,64303L,64304L,\n64305L,64306L,64307L,64308L,64309L,64310L,64311L,64312L,64313L,64314L,\n64315L,64316L,64317L,64318L,64319L,64320L,64321L,64322L,64323L,64324L,\n64325L,64326L,64327L,64328L,64329L,64330L,64331L,64332L,64333L,64334L,\n64335L,64336L,64337L,64338L,64339L,64340L,64341L,64342L,64343L,64344L,\n64345L,64346L,64347L,64348L,64349L,64350L,64351L,64352L,64353L,64354L,\n64355L,64356L,64357L,64358L,64359L,64360L,64361L,64362L,64363L,64364L,\n64365L,64366L,64367L,64368L,64369L,64370L,64371L,64372L,64373L,64374L,\n64375L,64376L,64377L,64378L,64379L,64380L,64381L,64382L,64383L,64384L,\n64385L,64386L,64387L,64388L,64389L,64390L,64391L,64392L,64393L,64394L,\n64395L,64396L,64397L,64398L,64399L,64400L,64401L,64402L,64403L,64404L,\n64405L,64406L,64407L,64408L,64409L,64410L,64411L,64412L,64413L,64414L,\n64415L,64416L,64417L,64418L,64419L,64420L,64421L,64422L,64423L,64424L,\n64425L,64426L,64427L,64428L,64429L,64430L,64431L,64432L,64433L,64434L,\n64435L,64436L,64437L,64438L,64439L,64440L,64441L,64442L,64443L,64444L,\n64445L,64446L,64447L,64448L,64449L,64450L,64451L,64452L,64453L,64454L,\n64455L,64456L,64457L,64458L,64459L,64460L,64461L,64462L,64463L,64464L,\n64465L,64466L,64467L,64468L,64469L,64470L,64471L,64472L,64473L,64474L,\n64475L,64476L,64477L,64478L,64479L,64480L,64481L,64482L,64483L,64484L,\n64485L,64486L,64487L,64488L,64489L,64490L,64491L,64492L,64493L,64494L,\n64495L,64496L,64497L,64498L,64499L,64500L,64501L,64502L,64503L,64504L,\n64505L,64506L,64507L,64508L,64509L,64510L,64511L,64512L,64513L,64514L,\n64515L,64516L,64517L,64518L,64519L,64520L,64521L,64522L,64523L,64524L,\n64525L,64526L,64527L,64528L,64529L,64530L,64531L,64532L,64533L,64534L,\n64535L,64536L,64537L,64538L,64539L,64540L,64541L,64542L,64543L,64544L,\n64545L,64546L,64547L,64548L,64549L,64550L,64551L,64552L,64553L,64554L,\n64555L,64556L,64557L,64558L,64559L,64560L,64561L,64562L,64563L,64564L,\n64565L,64566L,64567L,64568L,64569L,64570L,64571L,64572L,64573L,64574L,\n64575L,64576L,64577L,64578L,64579L,64580L,64581L,64582L,64583L,64584L,\n64585L,64586L,64587L,64588L,64589L,64590L,64591L,64592L,64593L,64594L,\n64595L,64596L,64597L,64598L,64599L,64600L,64601L,64602L,64603L,64604L,\n64605L,64606L,64607L,64608L,64609L,64610L,64611L,64612L,64613L,64614L,\n64615L,64616L,64617L,64618L,64619L,64620L,64621L,64622L,64623L,64624L,\n64625L,64626L,64627L,64628L,64629L,64630L,64631L,64632L,64633L,64634L,\n64635L,64636L,64637L,64638L,64639L,64640L,64641L,64642L,64643L,64644L,\n64645L,64646L,64647L,64648L,64649L,64650L,64651L,64652L,64653L,64654L,\n64655L,64656L,64657L,64658L,64659L,64660L,64661L,64662L,64663L,64664L,\n64665L,64666L,64667L,64668L,64669L,64670L,64671L,64672L,64673L,64674L,\n64675L,64676L,64677L,64678L,64679L,64680L,64681L,64682L,64683L,64684L,\n64685L,64686L,64687L,64688L,64689L,64690L,64691L,64692L,64693L,64694L,\n64695L,64696L,64697L,64698L,64699L,64700L,64701L,64702L,64703L,64704L,\n64705L,64706L,64707L,64708L,64709L,64710L,64711L,64712L,64713L,64714L,\n64715L,64716L,64717L,64718L,64719L,64720L,64721L,64722L,64723L,64724L,\n64725L,64726L,64727L,64728L,64729L,64730L,64731L,64732L,64733L,64734L,\n64735L,64736L,64737L,64738L,64739L,64740L,64741L,64742L,64743L,64744L,\n64745L,64746L,64747L,64748L,64749L,64750L,64751L,64752L,64753L,64754L,\n64755L,64756L,64757L,64758L,64759L,64760L,64761L,64762L,64763L,64764L,\n64765L,64766L,64767L,64768L,64769L,64770L,64771L,64772L,64773L,64774L,\n64775L,64776L,64777L,64778L,64779L,64780L,64781L,64782L,64783L,64784L,\n64785L,64786L,64787L,64788L,64789L,64790L,64791L,64792L,64793L,64794L,\n64795L,64796L,64797L,64798L,64799L,64800L,64801L,64802L,64803L,64804L,\n64805L,64806L,64807L,64808L,64809L,64810L,64811L,64812L,64813L,64814L,\n64815L,64816L,64817L,64818L,64819L,64820L,64821L,64822L,64823L,64824L,\n64825L,64826L,64827L,64828L,64829L,64830L,64831L,64832L,64833L,64834L,\n64835L,64836L,64837L,64838L,64839L,64840L,64841L,64842L,64843L,64844L,\n64845L,64846L,64847L,64848L,64849L,64850L,64851L,64852L,64853L,64854L,\n64855L,64856L,64857L,64858L,64859L,64860L,64861L,64862L,64863L,64864L,\n64865L,64866L,64867L,64868L,64869L,64870L,64871L,64872L,64873L,64874L,\n64875L,64876L,64877L,64878L,64879L,64880L,64881L,64882L,64883L,64884L,\n64885L,64886L,64887L,64888L,64889L,64890L,64891L,64892L,64893L,64894L,\n64895L,64896L,64897L,64898L,64899L,64900L,64901L,64902L,64903L,64904L,\n64905L,64906L,64907L,64908L,64909L,64910L,64911L,64912L,64913L,64914L,\n64915L,64916L,64917L,64918L,64919L,64920L,64921L,64922L,64923L,64924L,\n64925L,64926L,64927L,64928L,64929L,64930L,64931L,64932L,64933L,64934L,\n64935L,64936L,64937L,64938L,64939L,64940L,64941L,64942L,64943L,64944L,\n64945L,64946L,64947L,64948L,64949L,64950L,64951L,64952L,64953L,64954L,\n64955L,64956L,64957L,64958L,64959L,64960L,64961L,64962L,64963L,64964L,\n64965L,64966L,64967L,64968L,64969L,64970L,64971L,64972L,64973L,64974L,\n64975L,64976L,64977L,64978L,64979L,64980L,64981L,64982L,64983L,64984L,\n64985L,64986L,64987L,64988L,64989L,64990L,64991L,64992L,64993L,64994L,\n64995L,64996L,64997L,64998L,64999L,65000L,65001L,65002L,65003L,65004L,\n65005L,65006L,65007L,65008L,65009L,65010L,65011L,65012L,65013L,65014L,\n65015L,65016L,65017L,65018L,65019L,65020L,65021L,65022L,65023L,65024L,\n65025L,65026L,65027L,65028L,65029L,65030L,65031L,65032L,65033L,65034L,\n65035L,65036L,65037L,65038L,65039L,65040L,65041L,65042L,65043L,65044L,\n65045L,65046L,65047L,65048L,65049L,65050L,65051L,65052L,65053L,65054L,\n65055L,65056L,65057L,65058L,65059L,65060L,65061L,65062L,65063L,65064L,\n65065L,65066L,65067L,65068L,65069L,65070L,65071L,65072L,65073L,65074L,\n65075L,65076L,65077L,65078L,65079L,65080L,65081L,65082L,65083L,65084L,\n65085L,65086L,65087L,65088L,65089L,65090L,65091L,65092L,65093L,65094L,\n65095L,65096L,65097L,65098L,65099L,65100L,65101L,65102L,65103L,65104L,\n65105L,65106L,65107L,65108L,65109L,65110L,65111L,65112L,65113L,65114L,\n65115L,65116L,65117L,65118L,65119L,65120L,65121L,65122L,65123L,65124L,\n65125L,65126L,65127L,65128L,65129L,65130L,65131L,65132L,65133L,65134L,\n65135L,65136L,65137L,65138L,65139L,65140L,65141L,65142L,65143L,65144L,\n65145L,65146L,65147L,65148L,65149L,65150L,65151L,65152L,65153L,65154L,\n65155L,65156L,65157L,65158L,65159L,65160L,65161L,65162L,65163L,65164L,\n65165L,65166L,65167L,65168L,65169L,65170L,65171L,65172L,65173L,65174L,\n65175L,65176L,65177L,65178L,65179L,65180L,65181L,65182L,65183L,65184L,\n65185L,65186L,65187L,65188L,65189L,65190L,65191L,65192L,65193L,65194L,\n65195L,65196L,65197L,65198L,65199L,65200L,65201L,65202L,65203L,65204L,\n65205L,65206L,65207L,65208L,65209L,65210L,65211L,65212L,65213L,65214L,\n65215L,65216L,65217L,65218L,65219L,65220L,65221L,65222L,65223L,65224L,\n65225L,65226L,65227L,65228L,65229L,65230L,65231L,65232L,65233L,65234L,\n65235L,65236L,65237L,65238L,65239L,65240L,65241L,65242L,65243L,65244L,\n65245L,65246L,65247L,65248L,65249L,65250L,65251L,65252L,65253L,65254L,\n65255L,65256L,65257L,65258L,65259L,65260L,65261L,65262L,65263L,65264L,\n65265L,65266L,65267L,65268L,65269L,65270L,65271L,65272L,65273L,65274L,\n65275L,65276L,65277L,65278L,65279L,65280L,65281L,65282L,65283L,65284L,\n65285L,65286L,65287L,65288L,65289L,65290L,65291L,65292L,65293L,65294L,\n65295L,65296L,65297L,65298L,65299L,65300L,65301L,65302L,65303L,65304L,\n65305L,65306L,65307L,65308L,65309L,65310L,65311L,65312L,65313L,65314L,\n65315L,65316L,65317L,65318L,65319L,65320L,65321L,65322L,65323L,65324L,\n65325L,65326L,65327L,65328L,65329L,65330L,65331L,65332L,65333L,65334L,\n65335L,65336L,65337L,65338L,65339L,65340L,65341L,65342L,65343L,65344L,\n65313L,65314L,65315L,65316L,65317L,65318L,65319L,65320L,65321L,65322L,\n65323L,65324L,65325L,65326L,65327L,65328L,65329L,65330L,65331L,65332L,\n65333L,65334L,65335L,65336L,65337L,65338L,65371L,65372L,65373L,65374L,\n65375L,65376L,65377L,65378L,65379L,65380L,65381L,65382L,65383L,65384L,\n65385L,65386L,65387L,65388L,65389L,65390L,65391L,65392L,65393L,65394L,\n65395L,65396L,65397L,65398L,65399L,65400L,65401L,65402L,65403L,65404L,\n65405L,65406L,65407L,65408L,65409L,65410L,65411L,65412L,65413L,65414L,\n65415L,65416L,65417L,65418L,65419L,65420L,65421L,65422L,65423L,65424L,\n65425L,65426L,65427L,65428L,65429L,65430L,65431L,65432L,65433L,65434L,\n65435L,65436L,65437L,65438L,65439L,65440L,65441L,65442L,65443L,65444L,\n65445L,65446L,65447L,65448L,65449L,65450L,65451L,65452L,65453L,65454L,\n65455L,65456L,65457L,65458L,65459L,65460L,65461L,65462L,65463L,65464L,\n65465L,65466L,65467L,65468L,65469L,65470L,65471L,65472L,65473L,65474L,\n65475L,65476L,65477L,65478L,65479L,65480L,65481L,65482L,65483L,65484L,\n65485L,65486L,65487L,65488L,65489L,65490L,65491L,65492L,65493L,65494L,\n65495L,65496L,65497L,65498L,65499L,65500L,65501L,65502L,65503L,65504L,\n65505L,65506L,65507L,65508L,65509L,65510L,65511L,65512L,65513L,65514L,\n65515L,65516L,65517L,65518L,65519L,65520L,65521L,65522L,65523L,65524L,\n65525L,65526L,65527L,65528L,65529L,65530L,65531L,65532L,65533L,65534L,\n65535L,\n};\n#endif\n\n#if defined(DUK_USE_REGEXP_CANON_BITMAP)\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_re_canon_bitmap[256] = {\n23,0,224,19,1,228,255,255,255,255,255,255,255,255,255,255,63,254,255,127,\n255,255,255,255,255,255,255,255,231,231,0,16,255,227,255,255,63,255,255,\n255,255,255,255,255,1,252,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n227,129,255,255,255,147,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,251,\n};\n#endif\n/*\n *  Bitstream decoder.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Decode 'bits' bits from the input stream (bits must be 1...24).\n * When reading past bitstream end, zeroes are shifted in.  The result\n * is signed to match duk_bd_decode_flagged.\n */\nDUK_INTERNAL duk_uint32_t duk_bd_decode(duk_bitdecoder_ctx *ctx, duk_small_int_t bits) {\n\tduk_small_int_t shift;\n\tduk_uint32_t mask;\n\tduk_uint32_t tmp;\n\n\t/* Note: cannot read more than 24 bits without possibly shifting top bits out.\n\t * Fixable, but adds complexity.\n\t */\n\tDUK_ASSERT(bits >= 1 && bits <= 24);\n\n\twhile (ctx->currbits < bits) {\n#if 0\n\t\tDUK_DDD(DUK_DDDPRINT(\"decode_bits: shift more data (bits=%ld, currbits=%ld)\",\n\t\t                     (long) bits, (long) ctx->currbits));\n#endif\n\t\tctx->currval <<= 8;\n\t\tif (ctx->offset < ctx->length) {\n\t\t\t/* If ctx->offset >= ctx->length, we \"shift zeroes in\"\n\t\t\t * instead of croaking.\n\t\t\t */\n\t\t\tctx->currval |= ctx->data[ctx->offset++];\n\t\t}\n\t\tctx->currbits += 8;\n\t}\n#if 0\n\tDUK_DDD(DUK_DDDPRINT(\"decode_bits: bits=%ld, currbits=%ld, currval=0x%08lx\",\n\t                     (long) bits, (long) ctx->currbits, (unsigned long) ctx->currval));\n#endif\n\n\t/* Extract 'top' bits of currval; note that the extracted bits do not need\n\t * to be cleared, we just ignore them on next round.\n\t */\n\tshift = ctx->currbits - bits;\n\tmask = (((duk_uint32_t) 1U) << bits) - 1U;\n\ttmp = (ctx->currval >> shift) & mask;\n\tctx->currbits = shift;  /* remaining */\n\n#if 0\n\tDUK_DDD(DUK_DDDPRINT(\"decode_bits: %ld bits -> 0x%08lx (%ld), currbits=%ld, currval=0x%08lx\",\n\t                     (long) bits, (unsigned long) tmp, (long) tmp, (long) ctx->currbits, (unsigned long) ctx->currval));\n#endif\n\n\treturn tmp;\n}\n\nDUK_INTERNAL duk_small_uint_t duk_bd_decode_flag(duk_bitdecoder_ctx *ctx) {\n\treturn (duk_small_uint_t) duk_bd_decode(ctx, 1);\n}\n\n/* Decode a one-bit flag, and if set, decode a value of 'bits', otherwise return\n * default value.\n */\nDUK_INTERNAL duk_uint32_t duk_bd_decode_flagged(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_uint32_t def_value) {\n\tif (duk_bd_decode_flag(ctx)) {\n\t\treturn duk_bd_decode(ctx, bits);\n\t} else {\n\t\treturn def_value;\n\t}\n}\n\n/* Signed variant, allows negative marker value. */\nDUK_INTERNAL duk_int32_t duk_bd_decode_flagged_signed(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_int32_t def_value) {\n\treturn (duk_int32_t) duk_bd_decode_flagged(ctx, bits, (duk_uint32_t) def_value);\n}\n\n/* Shared varint encoding.  Match dukutil.py BitEncode.varuint(). */\nDUK_INTERNAL duk_uint32_t duk_bd_decode_varuint(duk_bitdecoder_ctx *ctx) {\n\tduk_small_uint_t t;\n\n\t/* The bit encoding choices here are based on manual testing against\n\t * the actual varuints generated by genbuiltins.py.\n\t */\n\tswitch (duk_bd_decode(ctx, 2)) {\n\tcase 0:\n\t\treturn 0;  /* [0,0] */\n\tcase 1:\n\t\treturn duk_bd_decode(ctx, 2) + 1;  /* [1,4] */\n\tcase 2:\n\t\treturn duk_bd_decode(ctx, 5) + 5;  /* [5,36] */\n\tdefault:\n\t\tt = duk_bd_decode(ctx, 7);\n\t\tif (t == 0) {\n\t\t\treturn duk_bd_decode(ctx, 20);\n\t\t}\n\t\treturn (t - 1) + 37;  /* [37,163] */\n\t}\n}\n\n/* Decode a bit packed string from a custom format used by genbuiltins.py.\n * This function is here because it's used for both heap and thread inits.\n * Caller must supply the output buffer whose size is NOT checked!\n */\n\n#define DUK__BITPACK_LETTER_LIMIT  26\n#define DUK__BITPACK_LOOKUP1       26\n#define DUK__BITPACK_LOOKUP2       27\n#define DUK__BITPACK_SWITCH1       28\n#define DUK__BITPACK_SWITCH        29\n#define DUK__BITPACK_UNUSED1       30\n#define DUK__BITPACK_EIGHTBIT      31\n\nDUK_LOCAL const duk_uint8_t duk__bitpacked_lookup[16] = {\n\tDUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3,\n\tDUK_ASC_4, DUK_ASC_5, DUK_ASC_6, DUK_ASC_7,\n\tDUK_ASC_8, DUK_ASC_9, DUK_ASC_UNDERSCORE, DUK_ASC_SPACE,\n\t0x82, 0x80, DUK_ASC_DOUBLEQUOTE, DUK_ASC_LCURLY\n};\n\nDUK_INTERNAL duk_small_uint_t duk_bd_decode_bitpacked_string(duk_bitdecoder_ctx *bd, duk_uint8_t *out) {\n\tduk_small_uint_t len;\n\tduk_small_uint_t mode;\n\tduk_small_uint_t t;\n\tduk_small_uint_t i;\n\n\tlen = duk_bd_decode(bd, 5);\n\tif (len == 31) {\n\t\tlen = duk_bd_decode(bd, 8);  /* Support up to 256 bytes; rare. */\n\t}\n\n\tmode = 32;  /* 0 = uppercase, 32 = lowercase (= 'a' - 'A') */\n\tfor (i = 0; i < len; i++) {\n\t\tt = duk_bd_decode(bd, 5);\n\t\tif (t < DUK__BITPACK_LETTER_LIMIT) {\n\t\t\tt = t + DUK_ASC_UC_A + mode;\n\t\t} else if (t == DUK__BITPACK_LOOKUP1) {\n\t\t\tt = duk__bitpacked_lookup[duk_bd_decode(bd, 3)];\n\t\t} else if (t == DUK__BITPACK_LOOKUP2) {\n\t\t\tt = duk__bitpacked_lookup[8 + duk_bd_decode(bd, 3)];\n\t\t} else if (t == DUK__BITPACK_SWITCH1) {\n\t\t\tt = duk_bd_decode(bd, 5);\n\t\t\tDUK_ASSERT_DISABLE(t >= 0);  /* unsigned */\n\t\t\tDUK_ASSERT(t <= 25);\n\t\t\tt = t + DUK_ASC_UC_A + (mode ^ 32);\n\t\t} else if (t == DUK__BITPACK_SWITCH) {\n\t\t\tmode = mode ^ 32;\n\t\t\tt = duk_bd_decode(bd, 5);\n\t\t\tDUK_ASSERT_DISABLE(t >= 0);\n\t\t\tDUK_ASSERT(t <= 25);\n\t\t\tt = t + DUK_ASC_UC_A + mode;\n\t\t} else if (t == DUK__BITPACK_EIGHTBIT) {\n\t\t\tt = duk_bd_decode(bd, 8);\n\t\t}\n\t\tout[i] = (duk_uint8_t) t;\n\t}\n\n\treturn len;\n}\n\n/* automatic undefs */\n#undef DUK__BITPACK_EIGHTBIT\n#undef DUK__BITPACK_LETTER_LIMIT\n#undef DUK__BITPACK_LOOKUP1\n#undef DUK__BITPACK_LOOKUP2\n#undef DUK__BITPACK_SWITCH\n#undef DUK__BITPACK_SWITCH1\n#undef DUK__BITPACK_UNUSED1\n/*\n *  Bitstream encoder.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL void duk_be_encode(duk_bitencoder_ctx *ctx, duk_uint32_t data, duk_small_int_t bits) {\n\tduk_uint8_t tmp;\n\n\tDUK_ASSERT(ctx != NULL);\n\tDUK_ASSERT(ctx->currbits < 8);\n\n\t/* This limitation would be fixable but adds unnecessary complexity. */\n\tDUK_ASSERT(bits >= 1 && bits <= 24);\n\n\tctx->currval = (ctx->currval << bits) | data;\n\tctx->currbits += bits;\n\n\twhile (ctx->currbits >= 8) {\n\t\tif (ctx->offset < ctx->length) {\n\t\t\ttmp = (duk_uint8_t) ((ctx->currval >> (ctx->currbits - 8)) & 0xff);\n\t\t\tctx->data[ctx->offset++] = tmp;\n\t\t} else {\n\t\t\t/* If buffer has been exhausted, truncate bitstream */\n\t\t\tctx->truncated = 1;\n\t\t}\n\n\t\tctx->currbits -= 8;\n\t}\n}\n\nDUK_INTERNAL void duk_be_finish(duk_bitencoder_ctx *ctx) {\n\tduk_small_int_t npad;\n\n\tDUK_ASSERT(ctx != NULL);\n\tDUK_ASSERT(ctx->currbits < 8);\n\n\tnpad = (duk_small_int_t) (8 - ctx->currbits);\n\tif (npad > 0) {\n\t\tduk_be_encode(ctx, 0, npad);\n\t}\n\tDUK_ASSERT(ctx->currbits == 0);\n}\n/*\n *  Fast buffer writer with slack management.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* XXX: Avoid duk_{memcmp,memmove}_unsafe() by imposing a minimum length of\n * >0 for the underlying dynamic buffer.\n */\n\n/*\n *  Macro support functions (use only macros in calling code)\n */\n\nDUK_LOCAL void duk__bw_update_ptrs(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t curr_offset, duk_size_t new_length) {\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_UNREF(thr);\n\n\t/* 'p' might be NULL when the underlying buffer is zero size.  If so,\n\t * the resulting pointers are not used unsafely.\n\t */\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, bw_ctx->buf);\n\tDUK_ASSERT(p != NULL || (DUK_HBUFFER_DYNAMIC_GET_SIZE(bw_ctx->buf) == 0 && curr_offset == 0 && new_length == 0));\n\tbw_ctx->p = p + curr_offset;\n\tbw_ctx->p_base = p;\n\tbw_ctx->p_limit = p + new_length;\n}\n\nDUK_INTERNAL void duk_bw_init(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_hbuffer_dynamic *h_buf) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_ASSERT(h_buf != NULL);\n\n\tbw_ctx->buf = h_buf;\n\tduk__bw_update_ptrs(thr, bw_ctx, 0, DUK_HBUFFER_DYNAMIC_GET_SIZE(h_buf));\n}\n\nDUK_INTERNAL void duk_bw_init_pushbuf(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t buf_size) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\n\t(void) duk_push_dynamic_buffer(thr, buf_size);\n\tbw_ctx->buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, -1);\n\tDUK_ASSERT(bw_ctx->buf != NULL);\n\tduk__bw_update_ptrs(thr, bw_ctx, 0, buf_size);\n}\n\n/* Resize target buffer for requested size.  Called by the macro only when the\n * fast path test (= there is space) fails.\n */\nDUK_INTERNAL duk_uint8_t *duk_bw_resize(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t sz) {\n\tduk_size_t curr_off;\n\tduk_size_t add_sz;\n\tduk_size_t new_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\n\t/* We could do this operation without caller updating bw_ctx->ptr,\n\t * but by writing it back here we can share code better.\n\t */\n\n\tcurr_off = (duk_size_t) (bw_ctx->p - bw_ctx->p_base);\n\tadd_sz = (curr_off >> DUK_BW_SLACK_SHIFT) + DUK_BW_SLACK_ADD;\n\tnew_sz = curr_off + sz + add_sz;\n\tif (DUK_UNLIKELY(new_sz < curr_off)) {\n\t\t/* overflow */\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_BUFFER_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n#if 0  /* for manual torture testing: tight allocation, useful with valgrind */\n\tnew_sz = curr_off + sz;\n#endif\n\n\t/* This is important to ensure dynamic buffer data pointer is not\n\t * NULL (which is possible if buffer size is zero), which in turn\n\t * causes portability issues with e.g. memmove() and memcpy().\n\t */\n\tDUK_ASSERT(new_sz >= 1);\n\n\tDUK_DD(DUK_DDPRINT(\"resize bufferwriter from %ld to %ld (add_sz=%ld)\", (long) curr_off, (long) new_sz, (long) add_sz));\n\n\tduk_hbuffer_resize(thr, bw_ctx->buf, new_sz);\n\tduk__bw_update_ptrs(thr, bw_ctx, curr_off, new_sz);\n\treturn bw_ctx->p;\n}\n\n/* Make buffer compact, matching current written size. */\nDUK_INTERNAL void duk_bw_compact(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx) {\n\tduk_size_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_UNREF(thr);\n\n\tlen = (duk_size_t) (bw_ctx->p - bw_ctx->p_base);\n\tduk_hbuffer_resize(thr, bw_ctx->buf, len);\n\tduk__bw_update_ptrs(thr, bw_ctx, len, len);\n}\n\nDUK_INTERNAL void duk_bw_write_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len) {\n\tduk_uint8_t *p_base;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tduk_memcpy_unsafe((void *) bw->p,\n\t                  (const void *) (p_base + src_off),\n\t                  (size_t) len);\n\tbw->p += len;\n}\n\nDUK_INTERNAL void duk_bw_write_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\tduk_bw_write_raw_slice(thr, bw, src_off, len);\n}\n\nDUK_INTERNAL void duk_bw_insert_raw_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len) {\n\tduk_uint8_t *p_base;\n\tduk_size_t buf_sz, move_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(buf != NULL);\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tbuf_sz = (duk_size_t) (bw->p - p_base);  /* constrained by maximum buffer size */\n\tmove_sz = buf_sz - dst_off;\n\n\tDUK_ASSERT(p_base != NULL);  /* buffer size is >= 1 */\n\tduk_memmove_unsafe((void *) (p_base + dst_off + len),\n\t                   (const void *) (p_base + dst_off),\n\t                   (size_t) move_sz);\n\tduk_memcpy_unsafe((void *) (p_base + dst_off),\n\t                  (const void *) buf,\n\t                  (size_t) len);\n\tbw->p += len;\n}\n\nDUK_INTERNAL void duk_bw_insert_ensure_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(buf != NULL);\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\tduk_bw_insert_raw_bytes(thr, bw, dst_off, buf, len);\n}\n\nDUK_INTERNAL void duk_bw_insert_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len) {\n\tduk_uint8_t *p_base;\n\tduk_size_t buf_sz, move_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\n\t/* Don't support \"straddled\" source now. */\n\tDUK_ASSERT(dst_off <= src_off || dst_off >= src_off + len);\n\n\tif (dst_off <= src_off) {\n\t\t/* Target is before source.  Source offset is expressed as\n\t\t * a \"before change\" offset.  Account for the memmove.\n\t\t */\n\t\tsrc_off += len;\n\t}\n\n\tbuf_sz = (duk_size_t) (bw->p - p_base);\n\tmove_sz = buf_sz - dst_off;\n\n\tDUK_ASSERT(p_base != NULL);  /* buffer size is >= 1 */\n\tduk_memmove_unsafe((void *) (p_base + dst_off + len),\n\t                   (const void *) (p_base + dst_off),\n\t                   (size_t) move_sz);\n\tduk_memcpy_unsafe((void *) (p_base + dst_off),\n\t                  (const void *) (p_base + src_off),\n\t                  (size_t) len);\n\tbw->p += len;\n}\n\nDUK_INTERNAL void duk_bw_insert_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\n\t/* Don't support \"straddled\" source now. */\n\tDUK_ASSERT(dst_off <= src_off || dst_off >= src_off + len);\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\tduk_bw_insert_raw_slice(thr, bw, dst_off, src_off, len);\n}\n\nDUK_INTERNAL duk_uint8_t *duk_bw_insert_raw_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len) {\n\tduk_uint8_t *p_base, *p_dst, *p_src;\n\tduk_size_t buf_sz, move_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tbuf_sz = (duk_size_t) (bw->p - p_base);\n\tmove_sz = buf_sz - off;\n\tp_dst = p_base + off + len;\n\tp_src = p_base + off;\n\tduk_memmove_unsafe((void *) p_dst, (const void *) p_src, (size_t) move_sz);\n\treturn p_src;  /* point to start of 'reserved area' */\n}\n\nDUK_INTERNAL duk_uint8_t *duk_bw_insert_ensure_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw));\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\treturn duk_bw_insert_raw_area(thr, bw, off, len);\n}\n\nDUK_INTERNAL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len) {\n\tduk_size_t move_sz;\n\n\tduk_uint8_t *p_base;\n\tduk_uint8_t *p_src;\n\tduk_uint8_t *p_dst;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(off + len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tp_dst = p_base + off;\n\tp_src = p_dst + len;\n\tmove_sz = (duk_size_t) (bw->p - p_src);\n\tduk_memmove_unsafe((void *) p_dst,\n\t                   (const void *) p_src,\n\t                   (size_t) move_sz);\n\tbw->p -= len;\n}\n\n/*\n *  Macro support functions for reading/writing raw data.\n *\n *  These are done using mempcy to ensure they're valid even for unaligned\n *  reads/writes on platforms where alignment counts.  On x86 at least gcc\n *  is able to compile these into a bswap+mov.  \"Always inline\" is used to\n *  ensure these macros compile to minimal code.\n *\n *  Not really bufwriter related, but currently used together.\n */\n\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p) {\n\tunion {\n\t\tduk_uint8_t b[2];\n\t\tduk_uint16_t x;\n\t} u;\n\n\tduk_memcpy((void *) u.b, (const void *) (*p), (size_t) 2);\n\tu.x = DUK_NTOH16(u.x);\n\t*p += 2;\n\treturn u.x;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p) {\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tduk_memcpy((void *) u.b, (const void *) (*p), (size_t) 4);\n\tu.x = DUK_NTOH32(u.x);\n\t*p += 4;\n\treturn u.x;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_raw_read_double_be(duk_uint8_t **p) {\n\tduk_double_union du;\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tduk_memcpy((void *) u.b, (const void *) (*p), (size_t) 4);\n\tu.x = DUK_NTOH32(u.x);\n\tdu.ui[DUK_DBL_IDX_UI0] = u.x;\n\tduk_memcpy((void *) u.b, (const void *) (*p + 4), (size_t) 4);\n\tu.x = DUK_NTOH32(u.x);\n\tdu.ui[DUK_DBL_IDX_UI1] = u.x;\n\t*p += 8;\n\n\treturn du.d;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u16_be(duk_uint8_t **p, duk_uint16_t val) {\n\tunion {\n\t\tduk_uint8_t b[2];\n\t\tduk_uint16_t x;\n\t} u;\n\n\tu.x = DUK_HTON16(val);\n\tduk_memcpy((void *) (*p), (const void *) u.b, (size_t) 2);\n\t*p += 2;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u32_be(duk_uint8_t **p, duk_uint32_t val) {\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tu.x = DUK_HTON32(val);\n\tduk_memcpy((void *) (*p), (const void *) u.b, (size_t) 4);\n\t*p += 4;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_double_be(duk_uint8_t **p, duk_double_t val) {\n\tduk_double_union du;\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tdu.d = val;\n\tu.x = du.ui[DUK_DBL_IDX_UI0];\n\tu.x = DUK_HTON32(u.x);\n\tduk_memcpy((void *) (*p), (const void *) u.b, (size_t) 4);\n\tu.x = du.ui[DUK_DBL_IDX_UI1];\n\tu.x = DUK_HTON32(u.x);\n\tduk_memcpy((void *) (*p + 4), (const void *) u.b, (size_t) 4);\n\t*p += 8;\n}\n\n/*\n *  Assertion helpers\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL void duk_bw_assert_valid(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx) {\n\tDUK_UNREF(thr);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_ASSERT(bw_ctx->buf != NULL);\n\tDUK_ASSERT((DUK_HBUFFER_DYNAMIC_GET_SIZE(bw_ctx->buf) == 0) ||\n\t           (bw_ctx->p != NULL &&\n\t            bw_ctx->p_base != NULL &&\n\t            bw_ctx->p_limit != NULL &&\n\t            bw_ctx->p_limit >= bw_ctx->p_base &&\n\t            bw_ctx->p >= bw_ctx->p_base &&\n\t            bw_ctx->p <= bw_ctx->p_limit));\n}\n#endif\n/*\n *  Cast helpers.\n *\n *  C99+ coercion is challenging portability-wise because out-of-range casts\n *  may invoke implementation defined or even undefined behavior.  See e.g.\n *  http://blog.frama-c.com/index.php?post/2013/10/09/Overflow-float-integer.\n *\n *  Provide explicit cast helpers which try to avoid implementation defined\n *  or undefined behavior.  These helpers can then be simplified in the vast\n *  majority of cases where the implementation defined or undefined behavior\n *  is not problematic.\n */\n\n/* #include duk_internal.h -> already included */\n\n/* Portable double-to-integer cast which avoids undefined behavior and avoids\n * relying on fmin(), fmax(), or other intrinsics.  Out-of-range results are\n * not assumed by caller, but here value is clamped, NaN converts to minval.\n */\n#define DUK__DOUBLE_INT_CAST1(tname,minval,maxval)  do { \\\n\t\tif (DUK_LIKELY(x >= (duk_double_t) (minval))) { \\\n\t\t\tDUK_ASSERT(!DUK_ISNAN(x)); \\\n\t\t\tif (DUK_LIKELY(x <= (duk_double_t) (maxval))) { \\\n\t\t\t\treturn (tname) x; \\\n\t\t\t} else { \\\n\t\t\t\treturn (tname) (maxval); \\\n\t\t\t} \\\n\t\t} else { \\\n\t\t\t/* NaN or below minval.  Since we don't care about the result \\\n\t\t\t * for out-of-range values, just return the minimum value for \\\n\t\t\t * both. \\\n\t\t\t */ \\\n\t\t\treturn (tname) (minval); \\\n\t\t} \\\n\t} while (0)\n\n/* Rely on specific NaN behavior for duk_double_{fmin,fmax}(): if either\n * argument is a NaN, return the second argument.  This avoids a\n * NaN-to-integer cast which is undefined behavior.\n */\n#define DUK__DOUBLE_INT_CAST2(tname,minval,maxval)  do { \\\n\t\treturn (tname) duk_double_fmin(duk_double_fmax(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \\\n\t} while (0)\n\n/* Another solution which doesn't need C99+ behavior for fmin() and fmax(). */\n#define DUK__DOUBLE_INT_CAST3(tname,minval,maxval)  do { \\\n\t\tif (DUK_ISNAN(x)) { \\\n\t\t\t/* 0 or any other value is fine. */ \\\n\t\t\treturn (tname) 0; \\\n\t\t} else \\\n\t\t\treturn (tname) DUK_FMIN(DUK_FMAX(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \\\n\t\t} \\\n\t} while (0)\n\n/* C99+ solution: relies on specific fmin() and fmax() behavior in C99: if\n * one argument is NaN but the other isn't, the non-NaN argument is returned.\n * Because the limits are non-NaN values, explicit NaN check is not needed.\n * This may not work on all legacy platforms, and also doesn't seem to inline\n * the fmin() and fmax() calls (unless one uses -ffast-math which we don't\n * support).\n */\n#define DUK__DOUBLE_INT_CAST4(tname,minval,maxval)  do { \\\n\t\treturn (tname) DUK_FMIN(DUK_FMAX(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \\\n\t} while (0)\n\nDUK_INTERNAL duk_int_t duk_double_to_int_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\t/* Real world solution: almost any practical platform will provide\n\t * an integer value without any guarantees what it is (which is fine).\n\t */\n\treturn (duk_int_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_int_t, DUK_INT_MIN, DUK_INT_MAX);\n#endif\n}\n\nDUK_INTERNAL duk_uint_t duk_double_to_uint_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_uint_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_uint_t, DUK_UINT_MIN, DUK_UINT_MAX);\n#endif\n}\n\nDUK_INTERNAL duk_int32_t duk_double_to_int32_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_int32_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_int32_t, DUK_INT32_MIN, DUK_INT32_MAX);\n#endif\n}\n\nDUK_INTERNAL duk_uint32_t duk_double_to_uint32_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_uint32_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_uint32_t, DUK_UINT32_MIN, DUK_UINT32_MAX);\n#endif\n}\n\n/* Largest IEEE double that doesn't round to infinity in the default rounding\n * mode.  The exact midpoint between (1 - 2^(-24)) * 2^128 and 2^128 rounds to\n * infinity, at least on x64.  This number is one double unit below that\n * midpoint.  See misc/float_cast.c.\n */\n#define DUK__FLOAT_ROUND_LIMIT      340282356779733623858607532500980858880.0\n\n/* Maximum IEEE float.  Double-to-float conversion above this would be out of\n * range and thus technically undefined behavior.\n */\n#define DUK__FLOAT_MAX              340282346638528859811704183484516925440.0\n\nDUK_INTERNAL duk_float_t duk_double_to_float_t(duk_double_t x) {\n\t/* Even a double-to-float cast is technically undefined behavior if\n\t * the double is out-of-range.  C99 Section 6.3.1.5:\n\t *\n\t *   If the value being converted is in the range of values that can\n\t *   be represented but cannot be represented exactly, the result is\n\t *   either the nearest higher or nearest lower representable value,\n\t *   chosen in an implementation-defined manner.  If the value being\n\t *   converted is outside the range of values that can be represented,\n\t *   the behavior is undefined.\n\t */\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_float_t) x;\n#else\n\tduk_double_t t;\n\n\tt = DUK_FABS(x);\n\tDUK_ASSERT((DUK_ISNAN(x) && DUK_ISNAN(t)) ||\n\t           (!DUK_ISNAN(x) && !DUK_ISNAN(t)));\n\n\tif (DUK_LIKELY(t <= DUK__FLOAT_MAX)) {\n\t\t/* Standard in-range case, try to get here with a minimum\n\t\t * number of checks and branches.\n\t\t */\n\t\tDUK_ASSERT(!DUK_ISNAN(x));\n\t\treturn (duk_float_t) x;\n\t} else if (t <= DUK__FLOAT_ROUND_LIMIT) {\n\t\t/* Out-of-range, but rounds to min/max float. */\n\t\tDUK_ASSERT(!DUK_ISNAN(x));\n\t\tif (x < 0.0) {\n\t\t\treturn (duk_float_t) -DUK__FLOAT_MAX;\n\t\t} else {\n\t\t\treturn (duk_float_t) DUK__FLOAT_MAX;\n\t\t}\n\t} else if (DUK_ISNAN(x)) {\n\t\t/* Assumes double NaN -> float NaN considered \"in range\". */\n\t\tDUK_ASSERT(DUK_ISNAN(x));\n\t\treturn (duk_float_t) x;\n\t} else {\n\t\t/* Out-of-range, rounds to +/- Infinity. */\n\t\tif (x < 0.0) {\n\t\t\treturn (duk_float_t) -DUK_DOUBLE_INFINITY;\n\t\t} else {\n\t\t\treturn (duk_float_t) DUK_DOUBLE_INFINITY;\n\t\t}\n\t}\n#endif\n}\n\n/* automatic undefs */\n#undef DUK__DOUBLE_INT_CAST1\n#undef DUK__DOUBLE_INT_CAST2\n#undef DUK__DOUBLE_INT_CAST3\n#undef DUK__DOUBLE_INT_CAST4\n#undef DUK__FLOAT_MAX\n#undef DUK__FLOAT_ROUND_LIMIT\n/*\n *  IEEE double helpers.\n */\n\n/* #include duk_internal.h -> already included */\n\nDUK_INTERNAL duk_bool_t duk_double_is_anyinf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn DUK_DBLUNION_IS_ANYINF(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_posinf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn DUK_DBLUNION_IS_POSINF(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_neginf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn DUK_DBLUNION_IS_NEGINF(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\t/* Assumes we're dealing with a Duktape internal NaN which is\n\t * NaN normalized if duk_tval requires it.\n\t */\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\treturn DUK_DBLUNION_IS_NAN(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan_or_zero(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\t/* Assumes we're dealing with a Duktape internal NaN which is\n\t * NaN normalized if duk_tval requires it.\n\t */\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\treturn DUK_DBLUNION_IS_NAN(&du) || DUK_DBLUNION_IS_ANYZERO(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan_or_inf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\t/* If exponent is 0x7FF the argument is either a NaN or an\n\t * infinity.  We don't need to check any other fields.\n\t */\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n\treturn (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000);\n#else\n\treturn (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000);\n#endif\n#else\n\treturn (du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL;\n#endif\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan_zero_inf(duk_double_t x) {\n\tduk_double_union du;\n#if defined(DUK_USE_64BIT_OPS)\n\tduk_uint64_t t;\n#else\n\tduk_uint32_t t;\n#endif\n\tdu.d = x;\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000);\n\tif (t == DUK_U64_CONSTANT(0x0000000000000000)) {\n\t\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x0000000080000000);\n\t\treturn t == 0;\n\t}\n\tif (t == DUK_U64_CONSTANT(0x000000007ff00000)) {\n\t\treturn 1;\n\t}\n#else\n\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000);\n\tif (t == DUK_U64_CONSTANT(0x0000000000000000)) {\n\t\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x8000000000000000);\n\t\treturn t == 0;\n\t}\n\tif (t == DUK_U64_CONSTANT(0x7ff0000000000000)) {\n\t\treturn 1;\n\t}\n#endif\n#else\n\tt = du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL;\n\tif (t == 0x00000000UL) {\n\t\treturn DUK_DBLUNION_IS_ANYZERO(&du);\n\t}\n\tif (t == 0x7ff00000UL) {\n\t\treturn 1;\n\t}\n#endif\n\treturn 0;\n}\n\nDUK_INTERNAL duk_small_uint_t duk_double_signbit(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn (duk_small_uint_t) DUK_DBLUNION_GET_SIGNBIT(&du);\n}\n\nDUK_INTERNAL duk_double_t duk_double_trunc_towards_zero(duk_double_t x) {\n\t/* XXX: optimize */\n\tduk_small_uint_t s = duk_double_signbit(x);\n\tx = DUK_FLOOR(DUK_FABS(x));  /* truncate towards zero */\n\tif (s) {\n\t\tx = -x;\n\t}\n\treturn x;\n}\n\nDUK_INTERNAL duk_bool_t duk_double_same_sign(duk_double_t x, duk_double_t y) {\n\tduk_double_union du1;\n\tduk_double_union du2;\n\tdu1.d = x;\n\tdu2.d = y;\n\n\treturn (((du1.ui[DUK_DBL_IDX_UI0] ^ du2.ui[DUK_DBL_IDX_UI0]) & 0x80000000UL) == 0);\n}\n\nDUK_INTERNAL duk_double_t duk_double_fmin(duk_double_t x, duk_double_t y) {\n\t/* Doesn't replicate fmin() behavior exactly: for fmin() if one\n\t * argument is a NaN, the other argument should be returned.\n\t * Duktape doesn't rely on this behavior so the replacement can\n\t * be simplified.\n\t */\n\treturn (x < y ? x : y);\n}\n\nDUK_INTERNAL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y) {\n\t/* Doesn't replicate fmax() behavior exactly: for fmax() if one\n\t * argument is a NaN, the other argument should be returned.\n\t * Duktape doesn't rely on this behavior so the replacement can\n\t * be simplified.\n\t */\n\treturn (x > y ? x : y);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_finite(duk_double_t x) {\n\treturn !duk_double_is_nan_or_inf(x);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_integer(duk_double_t x) {\n\tif (duk_double_is_nan_or_inf(x)) {\n\t\treturn 0;\n\t} else {\n\t\treturn duk_js_tointeger_number(x) == x;\n\t}\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_safe_integer(duk_double_t x) {\n\t/* >>> 2**53-1\n\t * 9007199254740991\n\t */\n\treturn duk_double_is_integer(x) && DUK_FABS(x) <= 9007199254740991.0;\n}\n\n/* Check whether a duk_double_t is a whole number in the 32-bit range (reject\n * negative zero), and if so, return a duk_int32_t.\n * For compiler use: don't allow negative zero as it will cause trouble with\n * LDINT+LDINTX, positive zero is OK.\n */\nDUK_INTERNAL duk_bool_t duk_is_whole_get_int32_nonegzero(duk_double_t x, duk_int32_t *ival) {\n\tduk_int32_t t;\n\n\tt = duk_double_to_int32_t(x);\n\tif (!((duk_double_t) t == x)) {\n\t\treturn 0;\n\t}\n\tif (t == 0) {\n\t\tduk_double_union du;\n\t\tdu.d = x;\n\t\tif (DUK_DBLUNION_HAS_SIGNBIT(&du)) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\t*ival = t;\n\treturn 1;\n}\n\n/* Check whether a duk_double_t is a whole number in the 32-bit range, and if\n * so, return a duk_int32_t.\n */\nDUK_INTERNAL duk_bool_t duk_is_whole_get_int32(duk_double_t x, duk_int32_t *ival) {\n\tduk_int32_t t;\n\n\tt = duk_double_to_int32_t(x);\n\tif (!((duk_double_t) t == x)) {\n\t\treturn 0;\n\t}\n\t*ival = t;\n\treturn 1;\n}\n\n/* Division: division by zero is undefined behavior (and may in fact trap)\n * so it needs special handling for portability.\n */\n\nDUK_INTERNAL DUK_INLINE duk_double_t duk_double_div(duk_double_t x, duk_double_t y) {\n#if !defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\tif (DUK_UNLIKELY(y == 0.0)) {\n\t\t/* In C99+ division by zero is undefined behavior so\n\t\t * avoid it entirely.  Hopefully the compiler is\n\t\t * smart enough to avoid emitting any actual code\n\t\t * because almost all practical platforms behave as\n\t\t * expected.\n\t\t */\n\t\tif (x > 0.0) {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn -DUK_DOUBLE_INFINITY;\n\t\t\t} else {\n\t\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t\t}\n\t\t} else if (x < 0.0) {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t\t} else {\n\t\t\t\treturn -DUK_DOUBLE_INFINITY;\n\t\t\t}\n\t\t} else {\n\t\t\t/* +/- 0, NaN */\n\t\t\treturn DUK_DOUBLE_NAN;\n\t\t}\n\t}\n#endif\n\n\treturn x / y;\n}\n/*\n *  Hash function duk_util_hashbytes().\n *\n *  Currently, 32-bit MurmurHash2.\n *\n *  Don't rely on specific hash values; hash function may be endianness\n *  dependent, for instance.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_STRHASH_DENSE)\n/* 'magic' constants for Murmurhash2 */\n#define DUK__MAGIC_M  ((duk_uint32_t) 0x5bd1e995UL)\n#define DUK__MAGIC_R  24\n\nDUK_INTERNAL duk_uint32_t duk_util_hashbytes(const duk_uint8_t *data, duk_size_t len, duk_uint32_t seed) {\n\tduk_uint32_t h = seed ^ ((duk_uint32_t) len);\n\n\twhile (len >= 4) {\n\t\t/* Portability workaround is required for platforms without\n\t\t * unaligned access.  The replacement code emulates little\n\t\t * endian access even on big endian architectures, which is\n\t\t * OK as long as it is consistent for a build.\n\t\t */\n#if defined(DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS)\n\t\tduk_uint32_t k = *((const duk_uint32_t *) (const void *) data);\n#else\n\t\tduk_uint32_t k = ((duk_uint32_t) data[0]) |\n\t\t                 (((duk_uint32_t) data[1]) << 8) |\n\t\t                 (((duk_uint32_t) data[2]) << 16) |\n\t\t                 (((duk_uint32_t) data[3]) << 24);\n#endif\n\n\t\tk *= DUK__MAGIC_M;\n\t\tk ^= k >> DUK__MAGIC_R;\n\t\tk *= DUK__MAGIC_M;\n\t\th *= DUK__MAGIC_M;\n\t\th ^= k;\n\t\tdata += 4;\n\t\tlen -= 4;\n\t}\n\n\tswitch (len) {\n\tcase 3: h ^= data[2] << 16;\n\tcase 2: h ^= data[1] << 8;\n\tcase 1: h ^= data[0];\n\t        h *= DUK__MAGIC_M;\n        }\n\n\th ^= h >> 13;\n\th *= DUK__MAGIC_M;\n\th ^= h >> 15;\n\n\treturn h;\n}\n#endif  /* DUK_USE_STRHASH_DENSE */\n\n/* automatic undefs */\n#undef DUK__MAGIC_M\n#undef DUK__MAGIC_R\n/*\n *  Memory utils.\n */\n\n/* #include duk_internal.h -> already included */\n\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL || len == 0U);\n\tDUK_ASSERT(s2 != NULL || len == 0U);\n\treturn DUK_MEMCMP(s1, s2, (size_t) len);\n}\n\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL);\n\tDUK_ASSERT(s2 != NULL);\n\treturn DUK_MEMCMP(s1, s2, (size_t) len);\n}\n#else  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL || len == 0U);\n\tDUK_ASSERT(s2 != NULL || len == 0U);\n\tif (DUK_UNLIKELY(len == 0U)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(s1 != NULL);\n\tDUK_ASSERT(s2 != NULL);\n\treturn duk_memcmp(s1, s2, len);\n}\n\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL);\n\tDUK_ASSERT(s2 != NULL);\n\treturn DUK_MEMCMP(s1, s2, (size_t) len);\n}\n#endif  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\n/*\n *  A tiny random number generator used for Math.random() and other internals.\n *\n *  Default algorithm is xoroshiro128+: http://xoroshiro.di.unimi.it/xoroshiro128plus.c\n *  with SplitMix64 seed preparation: http://xorshift.di.unimi.it/splitmix64.c.\n *\n *  Low memory targets and targets without 64-bit types use a slightly smaller\n *  (but slower) algorithm by Adi Shamir:\n *  http://www.woodmann.com/forum/archive/index.php/t-3100.html.\n *\n */\n\n/* #include duk_internal.h -> already included */\n\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\n\n#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS)\n#define DUK__RANDOM_SHAMIR3OP\n#else\n#define DUK__RANDOM_XOROSHIRO128PLUS\n#endif\n\n#if defined(DUK__RANDOM_SHAMIR3OP)\n#define DUK__UPDATE_RND(rnd) do { \\\n\t\t(rnd) += ((rnd) * (rnd)) | 0x05UL; \\\n\t\t(rnd) = ((rnd) & 0xffffffffUL);       /* if duk_uint32_t is exactly 32 bits, this is a NOP */ \\\n\t} while (0)\n\n#define DUK__RND_BIT(rnd)  ((rnd) >> 31)  /* only use the highest bit */\n\nDUK_INTERNAL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr) {\n\tDUK_UNREF(thr);  /* Nothing now. */\n}\n\nDUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) {\n\tduk_double_t t;\n\tduk_small_int_t n;\n\tduk_uint32_t rnd;\n\n\trnd = thr->heap->rnd_state;\n\n\tn = 53;  /* enough to cover the whole mantissa */\n\tt = 0.0;\n\n\tdo {\n\t\tDUK__UPDATE_RND(rnd);\n\t\tt += DUK__RND_BIT(rnd);\n\t\tt /= 2.0;\n\t} while (--n);\n\n\tthr->heap->rnd_state = rnd;\n\n\tDUK_ASSERT(t >= (duk_double_t) 0.0);\n\tDUK_ASSERT(t < (duk_double_t) 1.0);\n\n\treturn t;\n}\n#endif  /* DUK__RANDOM_SHAMIR3OP */\n\n#if defined(DUK__RANDOM_XOROSHIRO128PLUS)\nDUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__rnd_splitmix64(duk_uint64_t *x) {\n\tduk_uint64_t z;\n\tz = (*x += DUK_U64_CONSTANT(0x9E3779B97F4A7C15));\n\tz = (z ^ (z >> 30U)) * DUK_U64_CONSTANT(0xBF58476D1CE4E5B9);\n\tz = (z ^ (z >> 27U)) * DUK_U64_CONSTANT(0x94D049BB133111EB);\n\treturn z ^ (z >> 31U);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__rnd_rotl(const duk_uint64_t x, duk_small_uint_t k) {\n\treturn (x << k) | (x >> (64U - k));\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__xoroshiro128plus(duk_uint64_t *s) {\n\tduk_uint64_t s0;\n\tduk_uint64_t s1;\n\tduk_uint64_t res;\n\n\ts0 = s[0];\n\ts1 = s[1];\n\tres = s0 + s1;\n\ts1 ^= s0;\n\ts[0] = duk__rnd_rotl(s0, 55) ^ s1 ^ (s1 << 14U);\n\ts[1] = duk__rnd_rotl(s1, 36);\n\n\treturn res;\n}\n\nDUK_INTERNAL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr) {\n\tduk_small_uint_t i;\n\tduk_uint64_t x;\n\n\t/* Mix both halves of the initial seed with SplitMix64.  The intent\n\t * is to ensure that very similar raw seeds (which is usually the case\n\t * because current seed is Date.now()) result in different xoroshiro128+\n\t * seeds.\n\t */\n\tx = thr->heap->rnd_state[0];  /* Only [0] is used as input here. */\n\tfor (i = 0; i < 64; i++) {\n\t\tthr->heap->rnd_state[i & 0x01] = duk__rnd_splitmix64(&x);  /* Keep last 2 values. */\n\t}\n}\n\nDUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) {\n\tduk_uint64_t v;\n\tduk_double_union du;\n\n\t/* For big and little endian the integer and IEEE double byte order\n\t * is the same so a direct assignment works.  For mixed endian the\n\t * 32-bit parts must be swapped.\n\t */\n\tv = (DUK_U64_CONSTANT(0x3ff) << 52U) | (duk__xoroshiro128plus((duk_uint64_t *) thr->heap->rnd_state) >> 12U);\n\tdu.ull[0] = v;\n#if defined(DUK_USE_DOUBLE_ME)\n\tdo {\n\t\tduk_uint32_t tmp;\n\t\ttmp = du.ui[0];\n\t\tdu.ui[0] = du.ui[1];\n\t\tdu.ui[1] = tmp;\n\t} while (0);\n#endif\n\treturn du.d - 1.0;\n}\n#endif  /* DUK__RANDOM_XOROSHIRO128PLUS */\n\n#endif  /* !DUK_USE_GET_RANDOM_DOUBLE */\n\n/* automatic undefs */\n#undef DUK__RANDOM_SHAMIR3OP\n#undef DUK__RANDOM_XOROSHIRO128PLUS\n#undef DUK__RND_BIT\n#undef DUK__UPDATE_RND\n"
  },
  {
    "path": "react_juce/duktape/src-noline/duktape.h",
    "content": "/*\n *  Duktape public API for Duktape 2.4.0.\n *\n *  See the API reference for documentation on call semantics.  The exposed,\n *  supported API is between the \"BEGIN PUBLIC API\" and \"END PUBLIC API\"\n *  comments.  Other parts of the header are Duktape internal and related to\n *  e.g. platform/compiler/feature detection.\n *\n *  Git commit d4f2cff1c592d70f58bab8e1bd85705174c02a58 (v2.4.0).\n *  Git branch master.\n *\n *  See Duktape AUTHORS.rst and LICENSE.txt for copyright and\n *  licensing information.\n */\n\n/* LICENSE.txt */\n/*\n *  ===============\n *  Duktape license\n *  ===============\n *  \n *  (http://opensource.org/licenses/MIT)\n *  \n *  Copyright (c) 2013-2019 by Duktape authors (see AUTHORS.rst)\n *  \n *  Permission is hereby granted, free of charge, to any person obtaining a copy\n *  of this software and associated documentation files (the \"Software\"), to deal\n *  in the Software without restriction, including without limitation the rights\n *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n *  copies of the Software, and to permit persons to whom the Software is\n *  furnished to do so, subject to the following conditions:\n *  \n *  The above copyright notice and this permission notice shall be included in\n *  all copies or substantial portions of the Software.\n *  \n *  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n *  THE SOFTWARE.\n */\n\n/* AUTHORS.rst */\n/*\n *  ===============\n *  Duktape authors\n *  ===============\n *  \n *  Copyright\n *  =========\n *  \n *  Duktape copyrights are held by its authors.  Each author has a copyright\n *  to their contribution, and agrees to irrevocably license the contribution\n *  under the Duktape ``LICENSE.txt``.\n *  \n *  Authors\n *  =======\n *  \n *  Please include an e-mail address, a link to your GitHub profile, or something\n *  similar to allow your contribution to be identified accurately.\n *  \n *  The following people have contributed code, website contents, or Wiki contents,\n *  and agreed to irrevocably license their contributions under the Duktape\n *  ``LICENSE.txt`` (in order of appearance):\n *  \n *  * Sami Vaarala <sami.vaarala@iki.fi>\n *  * Niki Dobrev\n *  * Andreas \\u00d6man <andreas@lonelycoder.com>\n *  * L\\u00e1szl\\u00f3 Lang\\u00f3 <llango.u-szeged@partner.samsung.com>\n *  * Legimet <legimet.calc@gmail.com>\n *  * Karl Skomski <karl@skomski.com>\n *  * Bruce Pascoe <fatcerberus1@gmail.com>\n *  * Ren\\u00e9 Hollander <rene@rene8888.at>\n *  * Julien Hamaide (https://github.com/crazyjul)\n *  * Sebastian G\\u00f6tte (https://github.com/jaseg)\n *  * Tomasz Magulski (https://github.com/magul)\n *  * \\D. Bohdan (https://github.com/dbohdan)\n *  * Ond\\u0159ej Jirman (https://github.com/megous)\n *  * Sa\\u00fal Ibarra Corretg\\u00e9 <saghul@gmail.com>\n *  * Jeremy HU <huxingyi@msn.com>\n *  * Ole Andr\\u00e9 Vadla Ravn\\u00e5s (https://github.com/oleavr)\n *  * Harold Brenes (https://github.com/harold-b)\n *  * Oliver Crow (https://github.com/ocrow)\n *  * Jakub Ch\\u0142api\\u0144ski (https://github.com/jchlapinski)\n *  * Brett Vickers (https://github.com/beevik)\n *  * Dominik Okwieka (https://github.com/okitec)\n *  * Remko Tron\\u00e7on (https://el-tramo.be)\n *  * Romero Malaquias (rbsm@ic.ufal.br)\n *  * Michael Drake <michael.drake@codethink.co.uk>\n *  * Steven Don (https://github.com/shdon)\n *  * Simon Stone (https://github.com/sstone1)\n *  * \\J. McC. (https://github.com/jmhmccr)\n *  * Jakub Nowakowski (https://github.com/jimvonmoon)\n *  * Tommy Nguyen (https://github.com/tn0502)\n *  * Fabrice Fontaine (https://github.com/ffontaine)\n *  * Christopher Hiller (https://github.com/boneskull)\n *  * Gonzalo Diethelm (https://github.com/gonzus)\n *  * Michal Kasperek (https://github.com/michalkas)\n *  * Andrew Janke (https://github.com/apjanke)\n *  * Steve Fan (https://github.com/stevefan1999)\n *  * Edward Betts (https://github.com/edwardbetts)\n *  * Ozhan Duz (https://github.com/webfolderio)\n *  * Akos Kiss (https://github.com/akosthekiss)\n *  * TheBrokenRail (https://github.com/TheBrokenRail)\n *  * Jesse Doyle (https://github.com/jessedoyle)\n *  * Gero Kuehn (https://github.com/dc6jgk)\n *  * James Swift (https://github.com/phraemer)\n *  * Luis de Bethencourt (https://github.com/luisbg)\n *  * Ian Whyman (https://github.com/v00d00)\n *  \n *  Other contributions\n *  ===================\n *  \n *  The following people have contributed something other than code (e.g. reported\n *  bugs, provided ideas, etc; roughly in order of appearance):\n *  \n *  * Greg Burns\n *  * Anthony Rabine\n *  * Carlos Costa\n *  * Aur\\u00e9lien Bouilland\n *  * Preet Desai (Pris Matic)\n *  * judofyr (http://www.reddit.com/user/judofyr)\n *  * Jason Woofenden\n *  * Micha\\u0142 Przyby\\u015b\n *  * Anthony Howe\n *  * Conrad Pankoff\n *  * Jim Schimpf\n *  * Rajaran Gaunker (https://github.com/zimbabao)\n *  * Andreas \\u00d6man\n *  * Doug Sanden\n *  * Josh Engebretson (https://github.com/JoshEngebretson)\n *  * Remo Eichenberger (https://github.com/remoe)\n *  * Mamod Mehyar (https://github.com/mamod)\n *  * David Demelier (https://github.com/markand)\n *  * Tim Caswell (https://github.com/creationix)\n *  * Mitchell Blank Jr (https://github.com/mitchblank)\n *  * https://github.com/yushli\n *  * Seo Sanghyeon (https://github.com/sanxiyn)\n *  * Han ChoongWoo (https://github.com/tunz)\n *  * Joshua Peek (https://github.com/josh)\n *  * Bruce E. Pascoe (https://github.com/fatcerberus)\n *  * https://github.com/Kelledin\n *  * https://github.com/sstruchtrup\n *  * Michael Drake (https://github.com/tlsa)\n *  * https://github.com/chris-y\n *  * Laurent Zubiaur (https://github.com/lzubiaur)\n *  * Neil Kolban (https://github.com/nkolban)\n *  * Wilhelm Wanecek (https://github.com/wanecek)\n *  * Andrew Janke (https://github.com/apjanke)\n *  * Unamer (https://github.com/unamer)\n *  * Karl Dahlke (eklhad@gmail.com)\n *  \n *  If you are accidentally missing from this list, send me an e-mail\n *  (``sami.vaarala@iki.fi``) and I'll fix the omission.\n */\n\n#if !defined(DUKTAPE_H_INCLUDED)\n#define DUKTAPE_H_INCLUDED\n\n#define DUK_SINGLE_FILE\n\n/*\n *  BEGIN PUBLIC API\n */\n\n/*\n *  Version and Git commit identification\n */\n\n/* Duktape version, (major * 10000) + (minor * 100) + patch.  Allows C code\n * to #if (DUK_VERSION >= NNN) against Duktape API version.  The same value\n * is also available to ECMAScript code in Duktape.version.  Unofficial\n * development snapshots have 99 for patch level (e.g. 0.10.99 would be a\n * development version after 0.10.0 but before the next official release).\n */\n#define DUK_VERSION                       20400L\n\n/* Git commit, describe, and branch for Duktape build.  Useful for\n * non-official snapshot builds so that application code can easily log\n * which Duktape snapshot was used.  Not available in the ECMAScript\n * environment.\n */\n#define DUK_GIT_COMMIT                    \"d4f2cff1c592d70f58bab8e1bd85705174c02a58\"\n#define DUK_GIT_DESCRIBE                  \"v2.4.0\"\n#define DUK_GIT_BRANCH                    \"master\"\n\n/* External duk_config.h provides platform/compiler/OS dependent\n * typedefs and macros, and DUK_USE_xxx config options so that\n * the rest of Duktape doesn't need to do any feature detection.\n * DUK_VERSION is defined before including so that configuration\n * snippets can react to it.\n */\n#include \"duk_config.h\"\n\n/*\n *  Avoid C++ name mangling\n */\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/*\n *  Some defines forwarded from feature detection\n */\n\n#undef DUK_API_VARIADIC_MACROS\n#if defined(DUK_USE_VARIADIC_MACROS)\n#define DUK_API_VARIADIC_MACROS\n#endif\n\n#define DUK_API_NORETURN(decl) DUK_NORETURN(decl)\n\n/*\n *  Public API specific typedefs\n *\n *  Many types are wrapped by Duktape for portability to rare platforms\n *  where e.g. 'int' is a 16-bit type.  See practical typing discussion\n *  in Duktape web documentation.\n */\n\nstruct duk_thread_state;\nstruct duk_memory_functions;\nstruct duk_function_list_entry;\nstruct duk_number_list_entry;\nstruct duk_time_components;\n\n/* duk_context is now defined in duk_config.h because it may also be\n * referenced there by prototypes.\n */\ntypedef struct duk_thread_state duk_thread_state;\ntypedef struct duk_memory_functions duk_memory_functions;\ntypedef struct duk_function_list_entry duk_function_list_entry;\ntypedef struct duk_number_list_entry duk_number_list_entry;\ntypedef struct duk_time_components duk_time_components;\n\ntypedef duk_ret_t (*duk_c_function)(duk_context *ctx);\ntypedef void *(*duk_alloc_function) (void *udata, duk_size_t size);\ntypedef void *(*duk_realloc_function) (void *udata, void *ptr, duk_size_t size);\ntypedef void (*duk_free_function) (void *udata, void *ptr);\ntypedef void (*duk_fatal_function) (void *udata, const char *msg);\ntypedef void (*duk_decode_char_function) (void *udata, duk_codepoint_t codepoint);\ntypedef duk_codepoint_t (*duk_map_char_function) (void *udata, duk_codepoint_t codepoint);\ntypedef duk_ret_t (*duk_safe_call_function) (duk_context *ctx, void *udata);\ntypedef duk_size_t (*duk_debug_read_function) (void *udata, char *buffer, duk_size_t length);\ntypedef duk_size_t (*duk_debug_write_function) (void *udata, const char *buffer, duk_size_t length);\ntypedef duk_size_t (*duk_debug_peek_function) (void *udata);\ntypedef void (*duk_debug_read_flush_function) (void *udata);\ntypedef void (*duk_debug_write_flush_function) (void *udata);\ntypedef duk_idx_t (*duk_debug_request_function) (duk_context *ctx, void *udata, duk_idx_t nvalues);\ntypedef void (*duk_debug_detached_function) (duk_context *ctx, void *udata);\n\nstruct duk_thread_state {\n\t/* XXX: Enough space to hold internal suspend/resume structure.\n\t * This is rather awkward and to be fixed when the internal\n\t * structure is visible for the public API header.\n\t */\n\tchar data[128];\n};\n\nstruct duk_memory_functions {\n\tduk_alloc_function alloc_func;\n\tduk_realloc_function realloc_func;\n\tduk_free_function free_func;\n\tvoid *udata;\n};\n\nstruct duk_function_list_entry {\n\tconst char *key;\n\tduk_c_function value;\n\tduk_idx_t nargs;\n};\n\nstruct duk_number_list_entry {\n\tconst char *key;\n\tduk_double_t value;\n};\n\nstruct duk_time_components {\n\tduk_double_t year;          /* year, e.g. 2016, ECMAScript year range */\n\tduk_double_t month;         /* month: 1-12 */\n\tduk_double_t day;           /* day: 1-31 */\n\tduk_double_t hours;         /* hour: 0-59 */\n\tduk_double_t minutes;       /* minute: 0-59 */\n\tduk_double_t seconds;       /* second: 0-59 (in POSIX time no leap second) */\n\tduk_double_t milliseconds;  /* may contain sub-millisecond fractions */\n\tduk_double_t weekday;       /* weekday: 0-6, 0=Sunday, 1=Monday, ..., 6=Saturday */\n};\n\n/*\n *  Constants\n */\n\n/* Duktape debug protocol version used by this build. */\n#define DUK_DEBUG_PROTOCOL_VERSION        2\n\n/* Used to represent invalid index; if caller uses this without checking,\n * this index will map to a non-existent stack entry.  Also used in some\n * API calls as a marker to denote \"no value\".\n */\n#define DUK_INVALID_INDEX                 DUK_IDX_MIN\n\n/* Indicates that a native function does not have a fixed number of args,\n * and the argument stack should not be capped/extended at all.\n */\n#define DUK_VARARGS                       ((duk_int_t) (-1))\n\n/* Number of value stack entries (in addition to actual call arguments)\n * guaranteed to be allocated on entry to a Duktape/C function.\n */\n#define DUK_API_ENTRY_STACK               64U\n\n/* Value types, used by e.g. duk_get_type() */\n#define DUK_TYPE_MIN                      0U\n#define DUK_TYPE_NONE                     0U    /* no value, e.g. invalid index */\n#define DUK_TYPE_UNDEFINED                1U    /* ECMAScript undefined */\n#define DUK_TYPE_NULL                     2U    /* ECMAScript null */\n#define DUK_TYPE_BOOLEAN                  3U    /* ECMAScript boolean: 0 or 1 */\n#define DUK_TYPE_NUMBER                   4U    /* ECMAScript number: double */\n#define DUK_TYPE_STRING                   5U    /* ECMAScript string: CESU-8 / extended UTF-8 encoded */\n#define DUK_TYPE_OBJECT                   6U    /* ECMAScript object: includes objects, arrays, functions, threads */\n#define DUK_TYPE_BUFFER                   7U    /* fixed or dynamic, garbage collected byte buffer */\n#define DUK_TYPE_POINTER                  8U    /* raw void pointer */\n#define DUK_TYPE_LIGHTFUNC                9U    /* lightweight function pointer */\n#define DUK_TYPE_MAX                      9U\n\n/* Value mask types, used by e.g. duk_get_type_mask() */\n#define DUK_TYPE_MASK_NONE                (1U << DUK_TYPE_NONE)\n#define DUK_TYPE_MASK_UNDEFINED           (1U << DUK_TYPE_UNDEFINED)\n#define DUK_TYPE_MASK_NULL                (1U << DUK_TYPE_NULL)\n#define DUK_TYPE_MASK_BOOLEAN             (1U << DUK_TYPE_BOOLEAN)\n#define DUK_TYPE_MASK_NUMBER              (1U << DUK_TYPE_NUMBER)\n#define DUK_TYPE_MASK_STRING              (1U << DUK_TYPE_STRING)\n#define DUK_TYPE_MASK_OBJECT              (1U << DUK_TYPE_OBJECT)\n#define DUK_TYPE_MASK_BUFFER              (1U << DUK_TYPE_BUFFER)\n#define DUK_TYPE_MASK_POINTER             (1U << DUK_TYPE_POINTER)\n#define DUK_TYPE_MASK_LIGHTFUNC           (1U << DUK_TYPE_LIGHTFUNC)\n#define DUK_TYPE_MASK_THROW               (1U << 10)  /* internal flag value: throw if mask doesn't match */\n#define DUK_TYPE_MASK_PROMOTE             (1U << 11)  /* internal flag value: promote to object if mask matches */\n\n/* Coercion hints */\n#define DUK_HINT_NONE                     0    /* prefer number, unless input is a Date, in which\n                                                * case prefer string (E5 Section 8.12.8)\n                                                */\n#define DUK_HINT_STRING                   1    /* prefer string */\n#define DUK_HINT_NUMBER                   2    /* prefer number */\n\n/* Enumeration flags for duk_enum() */\n#define DUK_ENUM_INCLUDE_NONENUMERABLE    (1U << 0)    /* enumerate non-numerable properties in addition to enumerable */\n#define DUK_ENUM_INCLUDE_HIDDEN           (1U << 1)    /* enumerate hidden symbols too (in Duktape 1.x called internal properties) */\n#define DUK_ENUM_INCLUDE_SYMBOLS          (1U << 2)    /* enumerate symbols */\n#define DUK_ENUM_EXCLUDE_STRINGS          (1U << 3)    /* exclude strings */\n#define DUK_ENUM_OWN_PROPERTIES_ONLY      (1U << 4)    /* don't walk prototype chain, only check own properties */\n#define DUK_ENUM_ARRAY_INDICES_ONLY       (1U << 5)    /* only enumerate array indices */\n/* XXX: misleading name */\n#define DUK_ENUM_SORT_ARRAY_INDICES       (1U << 6)    /* sort array indices (applied to full enumeration result, including inherited array indices); XXX: misleading name */\n#define DUK_ENUM_NO_PROXY_BEHAVIOR        (1U << 7)    /* enumerate a proxy object itself without invoking proxy behavior */\n\n/* Compilation flags for duk_compile() and duk_eval() */\n/* DUK_COMPILE_xxx bits 0-2 are reserved for an internal 'nargs' argument.\n */\n#define DUK_COMPILE_EVAL                  (1U << 3)    /* compile eval code (instead of global code) */\n#define DUK_COMPILE_FUNCTION              (1U << 4)    /* compile function code (instead of global code) */\n#define DUK_COMPILE_STRICT                (1U << 5)    /* use strict (outer) context for global, eval, or function code */\n#define DUK_COMPILE_SHEBANG               (1U << 6)    /* allow shebang ('#! ...') comment on first line of source */\n#define DUK_COMPILE_SAFE                  (1U << 7)    /* (internal) catch compilation errors */\n#define DUK_COMPILE_NORESULT              (1U << 8)    /* (internal) omit eval result */\n#define DUK_COMPILE_NOSOURCE              (1U << 9)    /* (internal) no source string on stack */\n#define DUK_COMPILE_STRLEN                (1U << 10)   /* (internal) take strlen() of src_buffer (avoids double evaluation in macro) */\n#define DUK_COMPILE_NOFILENAME            (1U << 11)   /* (internal) no filename on stack */\n#define DUK_COMPILE_FUNCEXPR              (1U << 12)   /* (internal) source is a function expression (used for Function constructor) */\n\n/* Flags for duk_def_prop() and its variants; base flags + a lot of convenience shorthands */\n#define DUK_DEFPROP_WRITABLE              (1U << 0)    /* set writable (effective if DUK_DEFPROP_HAVE_WRITABLE set) */\n#define DUK_DEFPROP_ENUMERABLE            (1U << 1)    /* set enumerable (effective if DUK_DEFPROP_HAVE_ENUMERABLE set) */\n#define DUK_DEFPROP_CONFIGURABLE          (1U << 2)    /* set configurable (effective if DUK_DEFPROP_HAVE_CONFIGURABLE set) */\n#define DUK_DEFPROP_HAVE_WRITABLE         (1U << 3)    /* set/clear writable */\n#define DUK_DEFPROP_HAVE_ENUMERABLE       (1U << 4)    /* set/clear enumerable */\n#define DUK_DEFPROP_HAVE_CONFIGURABLE     (1U << 5)    /* set/clear configurable */\n#define DUK_DEFPROP_HAVE_VALUE            (1U << 6)    /* set value (given on value stack) */\n#define DUK_DEFPROP_HAVE_GETTER           (1U << 7)    /* set getter (given on value stack) */\n#define DUK_DEFPROP_HAVE_SETTER           (1U << 8)    /* set setter (given on value stack) */\n#define DUK_DEFPROP_FORCE                 (1U << 9)    /* force change if possible, may still fail for e.g. virtual properties */\n#define DUK_DEFPROP_SET_WRITABLE          (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE)\n#define DUK_DEFPROP_CLEAR_WRITABLE        DUK_DEFPROP_HAVE_WRITABLE\n#define DUK_DEFPROP_SET_ENUMERABLE        (DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE)\n#define DUK_DEFPROP_CLEAR_ENUMERABLE      DUK_DEFPROP_HAVE_ENUMERABLE\n#define DUK_DEFPROP_SET_CONFIGURABLE      (DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE)\n#define DUK_DEFPROP_CLEAR_CONFIGURABLE    DUK_DEFPROP_HAVE_CONFIGURABLE\n#define DUK_DEFPROP_W                     DUK_DEFPROP_WRITABLE\n#define DUK_DEFPROP_E                     DUK_DEFPROP_ENUMERABLE\n#define DUK_DEFPROP_C                     DUK_DEFPROP_CONFIGURABLE\n#define DUK_DEFPROP_WE                    (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_ENUMERABLE)\n#define DUK_DEFPROP_WC                    (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_CONFIGURABLE)\n#define DUK_DEFPROP_WEC                   (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_CONFIGURABLE)\n#define DUK_DEFPROP_HAVE_W                DUK_DEFPROP_HAVE_WRITABLE\n#define DUK_DEFPROP_HAVE_E                DUK_DEFPROP_HAVE_ENUMERABLE\n#define DUK_DEFPROP_HAVE_C                DUK_DEFPROP_HAVE_CONFIGURABLE\n#define DUK_DEFPROP_HAVE_WE               (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE)\n#define DUK_DEFPROP_HAVE_WC               (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_CONFIGURABLE)\n#define DUK_DEFPROP_HAVE_WEC              (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE)\n#define DUK_DEFPROP_SET_W                 DUK_DEFPROP_SET_WRITABLE\n#define DUK_DEFPROP_SET_E                 DUK_DEFPROP_SET_ENUMERABLE\n#define DUK_DEFPROP_SET_C                 DUK_DEFPROP_SET_CONFIGURABLE\n#define DUK_DEFPROP_SET_WE                (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_ENUMERABLE)\n#define DUK_DEFPROP_SET_WC                (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_CONFIGURABLE)\n#define DUK_DEFPROP_SET_WEC               (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_ENUMERABLE | DUK_DEFPROP_SET_CONFIGURABLE)\n#define DUK_DEFPROP_CLEAR_W               DUK_DEFPROP_CLEAR_WRITABLE\n#define DUK_DEFPROP_CLEAR_E               DUK_DEFPROP_CLEAR_ENUMERABLE\n#define DUK_DEFPROP_CLEAR_C               DUK_DEFPROP_CLEAR_CONFIGURABLE\n#define DUK_DEFPROP_CLEAR_WE              (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_ENUMERABLE)\n#define DUK_DEFPROP_CLEAR_WC              (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_CONFIGURABLE)\n#define DUK_DEFPROP_CLEAR_WEC             (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_ENUMERABLE | DUK_DEFPROP_CLEAR_CONFIGURABLE)\n#define DUK_DEFPROP_ATTR_W                (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_W)\n#define DUK_DEFPROP_ATTR_E                (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_E)\n#define DUK_DEFPROP_ATTR_C                (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_C)\n#define DUK_DEFPROP_ATTR_WE               (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WE)\n#define DUK_DEFPROP_ATTR_WC               (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WC)\n#define DUK_DEFPROP_ATTR_WEC              (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WEC)\n\n/* Flags for duk_push_thread_raw() */\n#define DUK_THREAD_NEW_GLOBAL_ENV         (1U << 0)    /* create a new global environment */\n\n/* Flags for duk_gc() */\n#define DUK_GC_COMPACT                    (1U << 0)    /* compact heap objects */\n\n/* Error codes (must be 8 bits at most, see duk_error.h) */\n#define DUK_ERR_NONE                      0    /* no error (e.g. from duk_get_error_code()) */\n#define DUK_ERR_ERROR                     1    /* Error */\n#define DUK_ERR_EVAL_ERROR                2    /* EvalError */\n#define DUK_ERR_RANGE_ERROR               3    /* RangeError */\n#define DUK_ERR_REFERENCE_ERROR           4    /* ReferenceError */\n#define DUK_ERR_SYNTAX_ERROR              5    /* SyntaxError */\n#define DUK_ERR_TYPE_ERROR                6    /* TypeError */\n#define DUK_ERR_URI_ERROR                 7    /* URIError */\n\n/* Return codes for C functions (shortcut for throwing an error) */\n#define DUK_RET_ERROR                     (-DUK_ERR_ERROR)\n#define DUK_RET_EVAL_ERROR                (-DUK_ERR_EVAL_ERROR)\n#define DUK_RET_RANGE_ERROR               (-DUK_ERR_RANGE_ERROR)\n#define DUK_RET_REFERENCE_ERROR           (-DUK_ERR_REFERENCE_ERROR)\n#define DUK_RET_SYNTAX_ERROR              (-DUK_ERR_SYNTAX_ERROR)\n#define DUK_RET_TYPE_ERROR                (-DUK_ERR_TYPE_ERROR)\n#define DUK_RET_URI_ERROR                 (-DUK_ERR_URI_ERROR)\n\n/* Return codes for protected calls (duk_safe_call(), duk_pcall()) */\n#define DUK_EXEC_SUCCESS                  0\n#define DUK_EXEC_ERROR                    1\n\n/* Debug levels for DUK_USE_DEBUG_WRITE(). */\n#define DUK_LEVEL_DEBUG                   0\n#define DUK_LEVEL_DDEBUG                  1\n#define DUK_LEVEL_DDDEBUG                 2\n\n/*\n *  Macros to create Symbols as C statically constructed strings.\n *\n *  Call e.g. as DUK_HIDDEN_SYMBOL(\"myProperty\") <=> (\"\\xFF\" \"myProperty\").\n *\n *  Local symbols have a unique suffix, caller should take care to avoid\n *  conflicting with the Duktape internal representation by e.g. prepending\n *  a '!' character: DUK_LOCAL_SYMBOL(\"myLocal\", \"!123\").\n *\n *  Note that these can only be used for string constants, not dynamically\n *  created strings.\n *\n *  You shouldn't normally use DUK_INTERNAL_SYMBOL() at all.  It is reserved\n *  for Duktape internal symbols only.  There are no versioning guarantees\n *  for internal symbols.\n */\n\n#define DUK_HIDDEN_SYMBOL(x)     (\"\\xFF\" x)\n#define DUK_GLOBAL_SYMBOL(x)     (\"\\x80\" x)\n#define DUK_LOCAL_SYMBOL(x,uniq) (\"\\x81\" x \"\\xff\" uniq)\n#define DUK_WELLKNOWN_SYMBOL(x)  (\"\\x81\" x \"\\xff\")\n#define DUK_INTERNAL_SYMBOL(x)   (\"\\x82\" x)\n\n/*\n *  If no variadic macros, __FILE__ and __LINE__ are passed through globals\n *  which is ugly and not thread safe.\n */\n\n#if !defined(DUK_API_VARIADIC_MACROS)\nDUK_EXTERNAL_DECL const char *duk_api_global_filename;\nDUK_EXTERNAL_DECL duk_int_t duk_api_global_line;\n#endif\n\n/*\n *  Context management\n */\n\nDUK_EXTERNAL_DECL\nduk_context *duk_create_heap(duk_alloc_function alloc_func,\n                             duk_realloc_function realloc_func,\n                             duk_free_function free_func,\n                             void *heap_udata,\n                             duk_fatal_function fatal_handler);\nDUK_EXTERNAL_DECL void duk_destroy_heap(duk_context *ctx);\n\nDUK_EXTERNAL_DECL void duk_suspend(duk_context *ctx, duk_thread_state *state);\nDUK_EXTERNAL_DECL void duk_resume(duk_context *ctx, const duk_thread_state *state);\n\n#define duk_create_heap_default() \\\n\tduk_create_heap(NULL, NULL, NULL, NULL, NULL)\n\n/*\n *  Memory management\n *\n *  Raw functions have no side effects (cannot trigger GC).\n */\n\nDUK_EXTERNAL_DECL void *duk_alloc_raw(duk_context *ctx, duk_size_t size);\nDUK_EXTERNAL_DECL void duk_free_raw(duk_context *ctx, void *ptr);\nDUK_EXTERNAL_DECL void *duk_realloc_raw(duk_context *ctx, void *ptr, duk_size_t size);\nDUK_EXTERNAL_DECL void *duk_alloc(duk_context *ctx, duk_size_t size);\nDUK_EXTERNAL_DECL void duk_free(duk_context *ctx, void *ptr);\nDUK_EXTERNAL_DECL void *duk_realloc(duk_context *ctx, void *ptr, duk_size_t size);\nDUK_EXTERNAL_DECL void duk_get_memory_functions(duk_context *ctx, duk_memory_functions *out_funcs);\nDUK_EXTERNAL_DECL void duk_gc(duk_context *ctx, duk_uint_t flags);\n\n/*\n *  Error handling\n */\n\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_throw_raw(duk_context *ctx));\n#define duk_throw(ctx) \\\n\t(duk_throw_raw((ctx)), (duk_ret_t) 0)\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_fatal_raw(duk_context *ctx, const char *err_msg));\n#define duk_fatal(ctx,err_msg) \\\n\t(duk_fatal_raw((ctx), (err_msg)), (duk_ret_t) 0)\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...));\n\n#if defined(DUK_API_VARIADIC_MACROS)\n#define duk_error(ctx,err_code,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_generic_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_eval_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_EVAL_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_range_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_RANGE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_reference_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_REFERENCE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_syntax_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_SYNTAX_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_type_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_TYPE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_uri_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_URI_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#else  /* DUK_API_VARIADIC_MACROS */\n/* For legacy compilers without variadic macros a macro hack is used to allow\n * variable arguments.  While the macro allows \"return duk_error(...)\", it\n * will fail with e.g. \"(void) duk_error(...)\".  The calls are noreturn but\n * with a return value to allow the \"return duk_error(...)\" idiom.  This may\n * cause some compiler warnings, but without noreturn the generated code is\n * often worse.  The same approach as with variadic macros (using\n * \"(duk_error(...), 0)\") won't work due to the macro hack structure.\n */\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_error_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_generic_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_eval_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_range_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_reference_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_syntax_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_type_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_uri_error_stash(duk_context *ctx, const char *fmt, ...));\n#define duk_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_error_stash)  /* last value is func pointer, arguments follow in parens */\n#define duk_generic_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_generic_error_stash)\n#define duk_eval_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_eval_error_stash)\n#define duk_range_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_range_error_stash)\n#define duk_reference_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_reference_error_stash)\n#define duk_syntax_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_syntax_error_stash)\n#define duk_type_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_type_error_stash)\n#define duk_uri_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_uri_error_stash)\n#endif  /* DUK_API_VARIADIC_MACROS */\n\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_va_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap));\n\n#define duk_error_va(ctx,err_code,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_generic_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_eval_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_EVAL_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_range_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_RANGE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_reference_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_REFERENCE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_syntax_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_SYNTAX_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_type_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_TYPE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_uri_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_URI_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n\n/*\n *  Other state related functions\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_strict_call(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_constructor_call(duk_context *ctx);\n\n/*\n *  Stack management\n */\n\nDUK_EXTERNAL_DECL duk_idx_t duk_normalize_index(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_valid_index(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_require_valid_index(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL duk_idx_t duk_get_top(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_set_top(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_idx_t duk_get_top_index(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_require_top_index(duk_context *ctx);\n\n/* Although extra/top could be an unsigned type here, using a signed type\n * makes the API more robust to calling code calculation errors or corner\n * cases (where caller might occasionally come up with negative values).\n * Negative values are treated as zero, which is better than casting them\n * to a large unsigned number.  (This principle is used elsewhere in the\n * API too.)\n */\nDUK_EXTERNAL_DECL duk_bool_t duk_check_stack(duk_context *ctx, duk_idx_t extra);\nDUK_EXTERNAL_DECL void duk_require_stack(duk_context *ctx, duk_idx_t extra);\nDUK_EXTERNAL_DECL duk_bool_t duk_check_stack_top(duk_context *ctx, duk_idx_t top);\nDUK_EXTERNAL_DECL void duk_require_stack_top(duk_context *ctx, duk_idx_t top);\n\n/*\n *  Stack manipulation (other than push/pop)\n */\n\nDUK_EXTERNAL_DECL void duk_swap(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL void duk_swap_top(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_dup(duk_context *ctx, duk_idx_t from_idx);\nDUK_EXTERNAL_DECL void duk_dup_top(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_insert(duk_context *ctx, duk_idx_t to_idx);\nDUK_EXTERNAL_DECL void duk_replace(duk_context *ctx, duk_idx_t to_idx);\nDUK_EXTERNAL_DECL void duk_copy(duk_context *ctx, duk_idx_t from_idx, duk_idx_t to_idx);\nDUK_EXTERNAL_DECL void duk_remove(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_xcopymove_raw(duk_context *to_ctx, duk_context *from_ctx, duk_idx_t count, duk_bool_t is_copy);\n\n#define duk_xmove_top(to_ctx,from_ctx,count) \\\n\tduk_xcopymove_raw((to_ctx), (from_ctx), (count), 0 /*is_copy*/)\n#define duk_xcopy_top(to_ctx,from_ctx,count) \\\n\tduk_xcopymove_raw((to_ctx), (from_ctx), (count), 1 /*is_copy*/)\n\n/*\n *  Push operations\n *\n *  Push functions return the absolute (relative to bottom of frame)\n *  position of the pushed value for convenience.\n *\n *  Note: duk_dup() is technically a push.\n */\n\nDUK_EXTERNAL_DECL void duk_push_undefined(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_null(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_boolean(duk_context *ctx, duk_bool_t val);\nDUK_EXTERNAL_DECL void duk_push_true(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_false(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_number(duk_context *ctx, duk_double_t val);\nDUK_EXTERNAL_DECL void duk_push_nan(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_int(duk_context *ctx, duk_int_t val);\nDUK_EXTERNAL_DECL void duk_push_uint(duk_context *ctx, duk_uint_t val);\nDUK_EXTERNAL_DECL const char *duk_push_string(duk_context *ctx, const char *str);\nDUK_EXTERNAL_DECL const char *duk_push_lstring(duk_context *ctx, const char *str, duk_size_t len);\nDUK_EXTERNAL_DECL void duk_push_pointer(duk_context *ctx, void *p);\nDUK_EXTERNAL_DECL const char *duk_push_sprintf(duk_context *ctx, const char *fmt, ...);\nDUK_EXTERNAL_DECL const char *duk_push_vsprintf(duk_context *ctx, const char *fmt, va_list ap);\n\n/* duk_push_literal() may evaluate its argument (a C string literal) more than\n * once on purpose.  When speed is preferred, sizeof() avoids an unnecessary\n * strlen() at runtime.  Sizeof(\"foo\") == 4, so subtract 1.  The argument\n * must be non-NULL and should not contain internal NUL characters as the\n * behavior will then depend on config options.\n */\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_push_literal(ctx,cstring)  duk_push_string((ctx), (cstring))\n#else\nDUK_EXTERNAL_DECL const char *duk_push_literal_raw(duk_context *ctx, const char *str, duk_size_t len);\n#define duk_push_literal(ctx,cstring)  duk_push_literal_raw((ctx), (cstring), sizeof((cstring)) - 1U)\n#endif\n\nDUK_EXTERNAL_DECL void duk_push_this(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_new_target(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_current_function(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_current_thread(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_global_object(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_heap_stash(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_global_stash(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_thread_stash(duk_context *ctx, duk_context *target_ctx);\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_object(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_bare_object(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_array(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_bare_array(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_c_function(duk_context *ctx, duk_c_function func, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_c_lightfunc(duk_context *ctx, duk_c_function func, duk_idx_t nargs, duk_idx_t length, duk_int_t magic);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_thread_raw(duk_context *ctx, duk_uint_t flags);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_proxy(duk_context *ctx, duk_uint_t proxy_flags);\n\n#define duk_push_thread(ctx) \\\n\tduk_push_thread_raw((ctx), 0 /*flags*/)\n\n#define duk_push_thread_new_globalenv(ctx) \\\n\tduk_push_thread_raw((ctx), DUK_THREAD_NEW_GLOBAL_ENV /*flags*/)\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...);\n\n#if defined(DUK_API_VARIADIC_MACROS)\n#define duk_push_error_object(ctx,err_code,...)  \\\n\tduk_push_error_object_raw((ctx), (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__)\n#else\nDUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...);\n/* Note: parentheses are required so that the comma expression works in assignments. */\n#define duk_push_error_object  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_push_error_object_stash)  /* last value is func pointer, arguments follow in parens */\n#endif\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_va_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap);\n#define duk_push_error_object_va(ctx,err_code,fmt,ap)  \\\n\tduk_push_error_object_va_raw((ctx), (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap))\n\n#define DUK_BUF_FLAG_DYNAMIC   (1 << 0)    /* internal flag: dynamic buffer */\n#define DUK_BUF_FLAG_EXTERNAL  (1 << 1)    /* internal flag: external buffer */\n#define DUK_BUF_FLAG_NOZERO    (1 << 2)    /* internal flag: don't zero allocated buffer */\n\nDUK_EXTERNAL_DECL void *duk_push_buffer_raw(duk_context *ctx, duk_size_t size, duk_small_uint_t flags);\n\n#define duk_push_buffer(ctx,size,dynamic) \\\n\tduk_push_buffer_raw((ctx), (size), (dynamic) ? DUK_BUF_FLAG_DYNAMIC : 0)\n#define duk_push_fixed_buffer(ctx,size) \\\n\tduk_push_buffer_raw((ctx), (size), 0 /*flags*/)\n#define duk_push_dynamic_buffer(ctx,size) \\\n\tduk_push_buffer_raw((ctx), (size), DUK_BUF_FLAG_DYNAMIC /*flags*/)\n#define duk_push_external_buffer(ctx) \\\n\t((void) duk_push_buffer_raw((ctx), 0, DUK_BUF_FLAG_DYNAMIC | DUK_BUF_FLAG_EXTERNAL))\n\n#define DUK_BUFOBJ_ARRAYBUFFER         0\n#define DUK_BUFOBJ_NODEJS_BUFFER       1\n#define DUK_BUFOBJ_DATAVIEW            2\n#define DUK_BUFOBJ_INT8ARRAY           3\n#define DUK_BUFOBJ_UINT8ARRAY          4\n#define DUK_BUFOBJ_UINT8CLAMPEDARRAY   5\n#define DUK_BUFOBJ_INT16ARRAY          6\n#define DUK_BUFOBJ_UINT16ARRAY         7\n#define DUK_BUFOBJ_INT32ARRAY          8\n#define DUK_BUFOBJ_UINT32ARRAY         9\n#define DUK_BUFOBJ_FLOAT32ARRAY        10\n#define DUK_BUFOBJ_FLOAT64ARRAY        11\n\nDUK_EXTERNAL_DECL void duk_push_buffer_object(duk_context *ctx, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags);\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_heapptr(duk_context *ctx, void *ptr);\n\n/*\n *  Pop operations\n */\n\nDUK_EXTERNAL_DECL void duk_pop(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_pop_n(duk_context *ctx, duk_idx_t count);\nDUK_EXTERNAL_DECL void duk_pop_2(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_pop_3(duk_context *ctx);\n\n/*\n *  Type checks\n *\n *  duk_is_none(), which would indicate whether index it outside of stack,\n *  is not needed; duk_is_valid_index() gives the same information.\n */\n\nDUK_EXTERNAL_DECL duk_int_t duk_get_type(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_check_type(duk_context *ctx, duk_idx_t idx, duk_int_t type);\nDUK_EXTERNAL_DECL duk_uint_t duk_get_type_mask(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_check_type_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t mask);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_undefined(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_null(duk_context *ctx, duk_idx_t idx);\n#define duk_is_null_or_undefined(ctx, idx) \\\n\t((duk_get_type_mask((ctx), (idx)) & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED)) ? 1 : 0)\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_nan(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_object(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_buffer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_buffer_data(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_lightfunc(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_symbol(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_array(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_c_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_ecmascript_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_bound_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_thread(duk_context *ctx, duk_idx_t idx);\n\n#define duk_is_callable(ctx,idx) \\\n\tduk_is_function((ctx), (idx))\nDUK_EXTERNAL_DECL duk_bool_t duk_is_constructable(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_fixed_buffer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_external_buffer(duk_context *ctx, duk_idx_t idx);\n\n/* Buffers and lightfuncs are not considered primitive because they mimic\n * objects and e.g. duk_to_primitive() will coerce them instead of returning\n * them as is.  Symbols are represented as strings internally.\n */\n#define duk_is_primitive(ctx,idx) \\\n\tduk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_UNDEFINED | \\\n\t                                  DUK_TYPE_MASK_NULL | \\\n\t                                  DUK_TYPE_MASK_BOOLEAN | \\\n\t                                  DUK_TYPE_MASK_NUMBER | \\\n\t                                  DUK_TYPE_MASK_STRING | \\\n\t                                  DUK_TYPE_MASK_POINTER)\n\n/* Symbols are object coercible, covered by DUK_TYPE_MASK_STRING. */\n#define duk_is_object_coercible(ctx,idx) \\\n\tduk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_BOOLEAN | \\\n\t                                  DUK_TYPE_MASK_NUMBER | \\\n\t                                  DUK_TYPE_MASK_STRING | \\\n\t                                  DUK_TYPE_MASK_OBJECT | \\\n\t                                  DUK_TYPE_MASK_BUFFER | \\\n\t                                  DUK_TYPE_MASK_POINTER | \\\n\t                                  DUK_TYPE_MASK_LIGHTFUNC)\n\nDUK_EXTERNAL_DECL duk_errcode_t duk_get_error_code(duk_context *ctx, duk_idx_t idx);\n#define duk_is_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) != 0)\n#define duk_is_eval_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_EVAL_ERROR)\n#define duk_is_range_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_RANGE_ERROR)\n#define duk_is_reference_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_REFERENCE_ERROR)\n#define duk_is_syntax_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_SYNTAX_ERROR)\n#define duk_is_type_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_TYPE_ERROR)\n#define duk_is_uri_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_URI_ERROR)\n\n/*\n *  Get operations: no coercion, returns default value for invalid\n *  indices and invalid value types.\n *\n *  duk_get_undefined() and duk_get_null() would be pointless and\n *  are not included.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_double_t duk_get_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int_t duk_get_int(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint_t duk_get_uint(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_get_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_get_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL void *duk_get_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_get_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_get_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_c_function duk_get_c_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_context *duk_get_context(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void *duk_get_heapptr(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Get-with-explicit default operations: like get operations but with an\n *  explicit default value.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_boolean_default(duk_context *ctx, duk_idx_t idx, duk_bool_t def_value);\nDUK_EXTERNAL_DECL duk_double_t duk_get_number_default(duk_context *ctx, duk_idx_t idx, duk_double_t def_value);\nDUK_EXTERNAL_DECL duk_int_t duk_get_int_default(duk_context *ctx, duk_idx_t idx, duk_int_t def_value);\nDUK_EXTERNAL_DECL duk_uint_t duk_get_uint_default(duk_context *ctx, duk_idx_t idx, duk_uint_t def_value);\nDUK_EXTERNAL_DECL const char *duk_get_string_default(duk_context *ctx, duk_idx_t idx, const char *def_value);\nDUK_EXTERNAL_DECL const char *duk_get_lstring_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_get_buffer_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_get_buffer_data_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_get_pointer_default(duk_context *ctx, duk_idx_t idx, void *def_value);\nDUK_EXTERNAL_DECL duk_c_function duk_get_c_function_default(duk_context *ctx, duk_idx_t idx, duk_c_function def_value);\nDUK_EXTERNAL_DECL duk_context *duk_get_context_default(duk_context *ctx, duk_idx_t idx, duk_context *def_value);\nDUK_EXTERNAL_DECL void *duk_get_heapptr_default(duk_context *ctx, duk_idx_t idx, void *def_value);\n\n/*\n *  Opt operations: like require operations but with an explicit default value\n *  when value is undefined or index is invalid, null and non-matching types\n *  cause a TypeError.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_opt_boolean(duk_context *ctx, duk_idx_t idx, duk_bool_t def_value);\nDUK_EXTERNAL_DECL duk_double_t duk_opt_number(duk_context *ctx, duk_idx_t idx, duk_double_t def_value);\nDUK_EXTERNAL_DECL duk_int_t duk_opt_int(duk_context *ctx, duk_idx_t idx, duk_int_t def_value);\nDUK_EXTERNAL_DECL duk_uint_t duk_opt_uint(duk_context *ctx, duk_idx_t idx, duk_uint_t def_value);\nDUK_EXTERNAL_DECL const char *duk_opt_string(duk_context *ctx, duk_idx_t idx, const char *def_ptr);\nDUK_EXTERNAL_DECL const char *duk_opt_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_opt_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size);\nDUK_EXTERNAL_DECL void *duk_opt_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size);\nDUK_EXTERNAL_DECL void *duk_opt_pointer(duk_context *ctx, duk_idx_t idx, void *def_value);\nDUK_EXTERNAL_DECL duk_c_function duk_opt_c_function(duk_context *ctx, duk_idx_t idx, duk_c_function def_value);\nDUK_EXTERNAL_DECL duk_context *duk_opt_context(duk_context *ctx, duk_idx_t idx, duk_context *def_value);\nDUK_EXTERNAL_DECL void *duk_opt_heapptr(duk_context *ctx, duk_idx_t idx, void *def_value);\n\n/*\n *  Require operations: no coercion, throw error if index or type\n *  is incorrect.  No defaulting.\n */\n\n#define duk_require_type_mask(ctx,idx,mask) \\\n\t((void) duk_check_type_mask((ctx), (idx), (mask) | DUK_TYPE_MASK_THROW))\n\nDUK_EXTERNAL_DECL void duk_require_undefined(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_require_null(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_require_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_double_t duk_require_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int_t duk_require_int(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint_t duk_require_uint(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_require_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_require_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL void duk_require_object(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void *duk_require_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_require_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_require_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_c_function duk_require_c_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_context *duk_require_context(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_require_function(duk_context *ctx, duk_idx_t idx);\n#define duk_require_callable(ctx,idx) \\\n\tduk_require_function((ctx), (idx))\nDUK_EXTERNAL_DECL void duk_require_constructor_call(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_require_constructable(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void *duk_require_heapptr(duk_context *ctx, duk_idx_t idx);\n\n/* Symbols are object coercible and covered by DUK_TYPE_MASK_STRING. */\n#define duk_require_object_coercible(ctx,idx) \\\n\t((void) duk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_BOOLEAN | \\\n\t                                            DUK_TYPE_MASK_NUMBER | \\\n\t                                            DUK_TYPE_MASK_STRING | \\\n\t                                            DUK_TYPE_MASK_OBJECT | \\\n\t                                            DUK_TYPE_MASK_BUFFER | \\\n\t                                            DUK_TYPE_MASK_POINTER | \\\n\t                                            DUK_TYPE_MASK_LIGHTFUNC | \\\n\t                                            DUK_TYPE_MASK_THROW))\n\n/*\n *  Coercion operations: in-place coercion, return coerced value where\n *  applicable.  If index is invalid, throw error.  Some coercions may\n *  throw an expected error (e.g. from a toString() or valueOf() call)\n *  or an internal error (e.g. from out of memory).\n */\n\nDUK_EXTERNAL_DECL void duk_to_undefined(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_to_null(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_to_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_double_t duk_to_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int_t duk_to_int(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint_t duk_to_uint(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int32_t duk_to_int32(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint32_t duk_to_uint32(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint16_t duk_to_uint16(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_to_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, duk_uint_t flags);\nDUK_EXTERNAL_DECL void *duk_to_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_to_object(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_to_primitive(duk_context *ctx, duk_idx_t idx, duk_int_t hint);\n\n#define DUK_BUF_MODE_FIXED      0   /* internal: request fixed buffer result */\n#define DUK_BUF_MODE_DYNAMIC    1   /* internal: request dynamic buffer result */\n#define DUK_BUF_MODE_DONTCARE   2   /* internal: don't care about fixed/dynamic nature */\n\n#define duk_to_buffer(ctx,idx,out_size) \\\n\tduk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_DONTCARE)\n#define duk_to_fixed_buffer(ctx,idx,out_size) \\\n\tduk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_FIXED)\n#define duk_to_dynamic_buffer(ctx,idx,out_size) \\\n\tduk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_DYNAMIC)\n\n/* safe variants of a few coercion operations */\nDUK_EXTERNAL_DECL const char *duk_safe_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL const char *duk_to_stacktrace(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_safe_to_stacktrace(duk_context *ctx, duk_idx_t idx);\n#define duk_safe_to_string(ctx,idx) \\\n\tduk_safe_to_lstring((ctx), (idx), NULL)\n\n/*\n *  Value length\n */\n\nDUK_EXTERNAL_DECL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t idx, duk_size_t len);\n#if 0\n/* duk_require_length()? */\n/* duk_opt_length()? */\n#endif\n\n/*\n *  Misc conversion\n */\n\nDUK_EXTERNAL_DECL const char *duk_base64_encode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_base64_decode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_hex_encode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_hex_decode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_json_encode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_json_decode(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL const char *duk_buffer_to_string(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Buffer\n */\n\nDUK_EXTERNAL_DECL void *duk_resize_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t new_size);\nDUK_EXTERNAL_DECL void *duk_steal_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void duk_config_buffer(duk_context *ctx, duk_idx_t idx, void *ptr, duk_size_t len);\n\n/*\n *  Property access\n *\n *  The basic function assumes key is on stack.  The _(l)string variant takes\n *  a C string as a property name; the _literal variant takes a C literal.\n *  The _index variant takes an array index as a property name (e.g. 123 is\n *  equivalent to the key \"123\").  The _heapptr variant takes a raw, borrowed\n *  heap pointer.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_get_prop_literal(ctx,obj_idx,key)  duk_get_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_get_prop_literal(ctx,obj_idx,key)  duk_get_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_put_prop_literal(ctx,obj_idx,key)  duk_put_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_put_prop_literal(ctx,obj_idx,key)  duk_put_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_del_prop_literal(ctx,obj_idx,key)  duk_del_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_del_prop_literal(ctx,obj_idx,key)  duk_del_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_has_prop_literal(ctx,obj_idx,key)  duk_has_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_has_prop_literal(ctx,obj_idx,key)  duk_has_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\n\nDUK_EXTERNAL_DECL void duk_get_prop_desc(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags);\nDUK_EXTERNAL_DECL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_string(duk_context *ctx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_get_global_literal(ctx,key)  duk_get_global_string((ctx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_literal_raw(duk_context *ctx, const char *key, duk_size_t key_len);\n#define duk_get_global_literal(ctx,key)  duk_get_global_literal_raw((ctx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_heapptr(duk_context *ctx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_string(duk_context *ctx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_put_global_literal(ctx,key)  duk_put_global_string((ctx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_literal_raw(duk_context *ctx, const char *key, duk_size_t key_len);\n#define duk_put_global_literal(ctx,key)  duk_put_global_literal_raw((ctx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_heapptr(duk_context *ctx, void *ptr);\n\n/*\n *  Inspection\n */\n\nDUK_EXTERNAL_DECL void duk_inspect_value(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_inspect_callstack_entry(duk_context *ctx, duk_int_t level);\n\n/*\n *  Object prototype\n */\n\nDUK_EXTERNAL_DECL void duk_get_prototype(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_prototype(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Object finalizer\n */\n\nDUK_EXTERNAL_DECL void duk_get_finalizer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_finalizer(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Global object\n */\n\nDUK_EXTERNAL_DECL void duk_set_global_object(duk_context *ctx);\n\n/*\n *  Duktape/C function magic value\n */\n\nDUK_EXTERNAL_DECL duk_int_t duk_get_magic(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_magic(duk_context *ctx, duk_idx_t idx, duk_int_t magic);\nDUK_EXTERNAL_DECL duk_int_t duk_get_current_magic(duk_context *ctx);\n\n/*\n *  Module helpers: put multiple function or constant properties\n */\n\nDUK_EXTERNAL_DECL void duk_put_function_list(duk_context *ctx, duk_idx_t obj_idx, const duk_function_list_entry *funcs);\nDUK_EXTERNAL_DECL void duk_put_number_list(duk_context *ctx, duk_idx_t obj_idx, const duk_number_list_entry *numbers);\n\n/*\n *  Object operations\n */\n\nDUK_EXTERNAL_DECL void duk_compact(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL void duk_enum(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t enum_flags);\nDUK_EXTERNAL_DECL duk_bool_t duk_next(duk_context *ctx, duk_idx_t enum_idx, duk_bool_t get_value);\nDUK_EXTERNAL_DECL void duk_seal(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL void duk_freeze(duk_context *ctx, duk_idx_t obj_idx);\n\n/*\n *  String manipulation\n */\n\nDUK_EXTERNAL_DECL void duk_concat(duk_context *ctx, duk_idx_t count);\nDUK_EXTERNAL_DECL void duk_join(duk_context *ctx, duk_idx_t count);\nDUK_EXTERNAL_DECL void duk_decode_string(duk_context *ctx, duk_idx_t idx, duk_decode_char_function callback, void *udata);\nDUK_EXTERNAL_DECL void duk_map_string(duk_context *ctx, duk_idx_t idx, duk_map_char_function callback, void *udata);\nDUK_EXTERNAL_DECL void duk_substring(duk_context *ctx, duk_idx_t idx, duk_size_t start_char_offset, duk_size_t end_char_offset);\nDUK_EXTERNAL_DECL void duk_trim(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_codepoint_t duk_char_code_at(duk_context *ctx, duk_idx_t idx, duk_size_t char_offset);\n\n/*\n *  ECMAScript operators\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL duk_bool_t duk_strict_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL duk_bool_t duk_samevalue(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL duk_bool_t duk_instanceof(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\n\n/*\n *  Random\n */\n\nDUK_EXTERNAL_DECL duk_double_t duk_random(duk_context *ctx);\n\n/*\n *  Function (method) calls\n */\n\nDUK_EXTERNAL_DECL void duk_call(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL void duk_call_method(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL void duk_call_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pcall(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pcall_method(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pcall_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL void duk_new(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pnew(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets);\n\n/*\n *  Thread management\n */\n\n/* There are currently no native functions to yield/resume, due to the internal\n * limitations on coroutine handling.  These will be added later.\n */\n\n/*\n *  Compilation and evaluation\n */\n\nDUK_EXTERNAL_DECL duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags);\nDUK_EXTERNAL_DECL duk_int_t duk_compile_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags);\n\n/* plain */\n#define duk_eval(ctx)  \\\n\t((void) duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOFILENAME))\n\n#define duk_eval_noresult(ctx)  \\\n\t((void) duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval(ctx)  \\\n\t(duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_noresult(ctx)  \\\n\t(duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile(ctx,flags)  \\\n\t((void) duk_compile_raw((ctx), NULL, 0, 2 /*args*/ | (flags)))\n\n#define duk_pcompile(ctx,flags)  \\\n\t(duk_compile_raw((ctx), NULL, 0, 2 /*args*/ | (flags) | DUK_COMPILE_SAFE))\n\n/* string */\n#define duk_eval_string(ctx,src)  \\\n\t((void) duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_eval_string_noresult(ctx,src)  \\\n\t((void) duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_string(ctx,src)  \\\n\t(duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_string_noresult(ctx,src)  \\\n\t(duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_string(ctx,flags,src)  \\\n\t((void) duk_compile_raw((ctx), (src), 0, 0 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_string_filename(ctx,flags,src)  \\\n\t((void) duk_compile_raw((ctx), (src), 0, 1 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN))\n\n#define duk_pcompile_string(ctx,flags,src)  \\\n\t(duk_compile_raw((ctx), (src), 0, 0 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_pcompile_string_filename(ctx,flags,src)  \\\n\t(duk_compile_raw((ctx), (src), 0, 1 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN))\n\n/* lstring */\n#define duk_eval_lstring(ctx,buf,len)  \\\n\t((void) duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME))\n\n#define duk_eval_lstring_noresult(ctx,buf,len)  \\\n\t((void) duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_lstring(ctx,buf,len)  \\\n\t(duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_SAFE | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_lstring_noresult(ctx,buf,len)  \\\n\t(duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_lstring(ctx,flags,buf,len)  \\\n\t((void) duk_compile_raw((ctx), buf, len, 0 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_lstring_filename(ctx,flags,buf,len)  \\\n\t((void) duk_compile_raw((ctx), buf, len, 1 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE))\n\n#define duk_pcompile_lstring(ctx,flags,buf,len)  \\\n\t(duk_compile_raw((ctx), buf, len, 0 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME))\n\n#define duk_pcompile_lstring_filename(ctx,flags,buf,len)  \\\n\t(duk_compile_raw((ctx), buf, len, 1 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE))\n\n/*\n *  Bytecode load/dump\n */\n\nDUK_EXTERNAL_DECL void duk_dump_function(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_load_function(duk_context *ctx);\n\n/*\n *  Debugging\n */\n\nDUK_EXTERNAL_DECL void duk_push_context_dump(duk_context *ctx);\n\n/*\n *  Debugger (debug protocol)\n */\n\nDUK_EXTERNAL_DECL void duk_debugger_attach(duk_context *ctx,\n                                           duk_debug_read_function read_cb,\n                                           duk_debug_write_function write_cb,\n                                           duk_debug_peek_function peek_cb,\n                                           duk_debug_read_flush_function read_flush_cb,\n                                           duk_debug_write_flush_function write_flush_cb,\n                                           duk_debug_request_function request_cb,\n                                           duk_debug_detached_function detached_cb,\n                                           void *udata);\nDUK_EXTERNAL_DECL void duk_debugger_detach(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_debugger_cooperate(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_bool_t duk_debugger_notify(duk_context *ctx, duk_idx_t nvalues);\nDUK_EXTERNAL_DECL void duk_debugger_pause(duk_context *ctx);\n\n/*\n *  Time handling\n */\n\nDUK_EXTERNAL_DECL duk_double_t duk_get_now(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_time_to_components(duk_context *ctx, duk_double_t timeval, duk_time_components *comp);\nDUK_EXTERNAL_DECL duk_double_t duk_components_to_time(duk_context *ctx, duk_time_components *comp);\n\n/*\n *  Date provider related constants\n *\n *  NOTE: These are \"semi public\" - you should only use these if you write\n *  your own platform specific Date provider, see doc/datetime.rst.\n */\n\n/* Millisecond count constants. */\n#define DUK_DATE_MSEC_SECOND          1000L\n#define DUK_DATE_MSEC_MINUTE          (60L * 1000L)\n#define DUK_DATE_MSEC_HOUR            (60L * 60L * 1000L)\n#define DUK_DATE_MSEC_DAY             (24L * 60L * 60L * 1000L)\n\n/* ECMAScript date range is 100 million days from Epoch:\n * > 100e6 * 24 * 60 * 60 * 1000  // 100M days in millisecs\n * 8640000000000000\n * (= 8.64e15)\n */\n#define DUK_DATE_MSEC_100M_DAYS         (8.64e15)\n#define DUK_DATE_MSEC_100M_DAYS_LEEWAY  (8.64e15 + 24 * 3600e3)\n\n/* ECMAScript year range:\n * > new Date(100e6 * 24 * 3600e3).toISOString()\n * '+275760-09-13T00:00:00.000Z'\n * > new Date(-100e6 * 24 * 3600e3).toISOString()\n * '-271821-04-20T00:00:00.000Z'\n */\n#define DUK_DATE_MIN_ECMA_YEAR     (-271821L)\n#define DUK_DATE_MAX_ECMA_YEAR     275760L\n\n/* Part indices for internal breakdowns.  Part order from DUK_DATE_IDX_YEAR\n * to DUK_DATE_IDX_MILLISECOND matches argument ordering of ECMAScript API\n * calls (like Date constructor call).  Some functions in duk_bi_date.c\n * depend on the specific ordering, so change with care.  16 bits are not\n * enough for all parts (year, specifically).\n *\n * Must be in-sync with genbuiltins.py.\n */\n#define DUK_DATE_IDX_YEAR           0  /* year */\n#define DUK_DATE_IDX_MONTH          1  /* month: 0 to 11 */\n#define DUK_DATE_IDX_DAY            2  /* day within month: 0 to 30 */\n#define DUK_DATE_IDX_HOUR           3\n#define DUK_DATE_IDX_MINUTE         4\n#define DUK_DATE_IDX_SECOND         5\n#define DUK_DATE_IDX_MILLISECOND    6\n#define DUK_DATE_IDX_WEEKDAY        7  /* weekday: 0 to 6, 0=sunday, 1=monday, etc */\n#define DUK_DATE_IDX_NUM_PARTS      8\n\n/* Internal API call flags, used for various functions in duk_bi_date.c.\n * Certain flags are used by only certain functions, but since the flags\n * don't overlap, a single flags value can be passed around to multiple\n * functions.\n *\n * The unused top bits of the flags field are also used to pass values\n * to helpers (duk__get_part_helper() and duk__set_part_helper()).\n *\n * Must be in-sync with genbuiltins.py.\n */\n\n/* NOTE: when writing a Date provider you only need a few specific\n * flags from here, the rest are internal.  Avoid using anything you\n * don't need.\n */\n\n#define DUK_DATE_FLAG_NAN_TO_ZERO          (1 << 0)  /* timeval breakdown: internal time value NaN -> zero */\n#define DUK_DATE_FLAG_NAN_TO_RANGE_ERROR   (1 << 1)  /* timeval breakdown: internal time value NaN -> RangeError (toISOString) */\n#define DUK_DATE_FLAG_ONEBASED             (1 << 2)  /* timeval breakdown: convert month and day-of-month parts to one-based (default is zero-based) */\n#define DUK_DATE_FLAG_EQUIVYEAR            (1 << 3)  /* timeval breakdown: replace year with equivalent year in the [1971,2037] range for DST calculations */\n#define DUK_DATE_FLAG_LOCALTIME            (1 << 4)  /* convert time value to local time */\n#define DUK_DATE_FLAG_SUB1900              (1 << 5)  /* getter: subtract 1900 from year when getting year part */\n#define DUK_DATE_FLAG_TOSTRING_DATE        (1 << 6)  /* include date part in string conversion result */\n#define DUK_DATE_FLAG_TOSTRING_TIME        (1 << 7)  /* include time part in string conversion result */\n#define DUK_DATE_FLAG_TOSTRING_LOCALE      (1 << 8)  /* use locale specific formatting if available */\n#define DUK_DATE_FLAG_TIMESETTER           (1 << 9)  /* setter: call is a time setter (affects hour, min, sec, ms); otherwise date setter (affects year, month, day-in-month) */\n#define DUK_DATE_FLAG_YEAR_FIXUP           (1 << 10) /* setter: perform 2-digit year fixup (00...99 -> 1900...1999) */\n#define DUK_DATE_FLAG_SEP_T                (1 << 11) /* string conversion: use 'T' instead of ' ' as a separator */\n#define DUK_DATE_FLAG_VALUE_SHIFT          12        /* additional values begin at bit 12 */\n\n/*\n *  ROM pointer compression\n */\n\n/* Support array for ROM pointer compression.  Only declared when ROM\n * pointer compression is active.\n */\n#if defined(DUK_USE_ROM_OBJECTS) && defined(DUK_USE_HEAPPTR16)\nDUK_EXTERNAL_DECL const void * const duk_rom_compressed_pointers[];\n#endif\n\n/*\n *  C++ name mangling\n */\n\n#if defined(__cplusplus)\n/* end 'extern \"C\"' wrapper */\n}\n#endif\n\n/*\n *  END PUBLIC API\n */\n\n#endif  /* DUKTAPE_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_alloc_default.c",
    "content": "/*\n *  Default allocation functions.\n *\n *  Assumes behavior such as malloc allowing zero size, yielding\n *  a NULL or a unique pointer which is a no-op for free.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS)\nDUK_INTERNAL void *duk_default_alloc_function(void *udata, duk_size_t size) {\n\tvoid *res;\n\tDUK_UNREF(udata);\n\tres = DUK_ANSI_MALLOC(size);\n\tDUK_DDD(DUK_DDDPRINT(\"default alloc function: %lu -> %p\",\n\t                     (unsigned long) size, (void *) res));\n\treturn res;\n}\n\nDUK_INTERNAL void *duk_default_realloc_function(void *udata, void *ptr, duk_size_t newsize) {\n\tvoid *res;\n\tDUK_UNREF(udata);\n\tres = DUK_ANSI_REALLOC(ptr, newsize);\n\tDUK_DDD(DUK_DDDPRINT(\"default realloc function: %p %lu -> %p\",\n\t                     (void *) ptr, (unsigned long) newsize, (void *) res));\n\treturn res;\n}\n\nDUK_INTERNAL void duk_default_free_function(void *udata, void *ptr) {\n\tDUK_DDD(DUK_DDDPRINT(\"default free function: %p\", (void *) ptr));\n\tDUK_UNREF(udata);\n\tDUK_ANSI_FREE(ptr);\n}\n#endif  /* DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_api_buffer.c",
    "content": "/*\n *  Buffer\n */\n\n#include \"duk_internal.h\"\n\nDUK_EXTERNAL void *duk_resize_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t new_size) {\n\tduk_hbuffer_dynamic *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer_dynamic *) duk_require_hbuffer(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tif (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\t/* Maximum size check is handled by callee. */\n\tduk_hbuffer_resize(thr, h, new_size);\n\n\treturn DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h);\n}\n\nDUK_EXTERNAL void *duk_steal_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tduk_hbuffer_dynamic *h;\n\tvoid *ptr;\n\tduk_size_t sz;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer_dynamic *) duk_require_hbuffer(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tif (!(DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h))) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\t/* Forget the previous allocation, setting size to 0 and alloc to\n\t * NULL.  Caller is responsible for freeing the previous allocation.\n\t * Getting the allocation and clearing it is done in the same API\n\t * call to avoid any chance of a realloc.\n\t */\n\tptr = DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h);\n\tsz = DUK_HBUFFER_DYNAMIC_GET_SIZE(h);\n\tif (out_size) {\n\t\t*out_size = sz;\n\t}\n\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(thr->heap, h);\n\tDUK_HBUFFER_DYNAMIC_SET_SIZE(h, 0);\n\n\treturn ptr;\n}\n\nDUK_EXTERNAL void duk_config_buffer(duk_hthread *thr, duk_idx_t idx, void *ptr, duk_size_t len) {\n\tduk_hbuffer_external *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer_external *) duk_require_hbuffer(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tif (!DUK_HBUFFER_HAS_EXTERNAL(h)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_WRONG_BUFFER_TYPE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h));\n\n\tDUK_HBUFFER_EXTERNAL_SET_DATA_PTR(thr->heap, h, ptr);\n\tDUK_HBUFFER_EXTERNAL_SET_SIZE(h, len);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_api_bytecode.c",
    "content": "/*\n *  Bytecode dump/load\n *\n *  The bytecode load primitive is more important performance-wise than the\n *  dump primitive.\n *\n *  Unlike most Duktape API calls, bytecode dump/load is not guaranteed to be\n *  memory safe for invalid arguments - caller beware!  There's little point\n *  in trying to achieve memory safety unless bytecode instructions are also\n *  validated which is not easy to do with indirect register references etc.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_BYTECODE_DUMP_SUPPORT)\n\n#define DUK__SER_MARKER  0xbf\n#define DUK__SER_STRING  0x00\n#define DUK__SER_NUMBER  0x01\n#define DUK__BYTECODE_INITIAL_ALLOC 256\n#define DUK__NO_FORMALS  0xffffffffUL\n\n/*\n *  Dump/load helpers, xxx_raw() helpers do no buffer checks\n */\n\nDUK_LOCAL duk_uint8_t *duk__load_string_raw(duk_hthread *thr, duk_uint8_t *p) {\n\tduk_uint32_t len;\n\n\tlen = DUK_RAW_READ_U32_BE(p);\n\tduk_push_lstring(thr, (const char *) p, len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__load_buffer_raw(duk_hthread *thr, duk_uint8_t *p) {\n\tduk_uint32_t len;\n\tduk_uint8_t *buf;\n\n\tlen = DUK_RAW_READ_U32_BE(p);\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) len);\n\tDUK_ASSERT(buf != NULL);\n\tduk_memcpy((void *) buf, (const void *) p, (size_t) len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_hstring_raw(duk_uint8_t *p, duk_hstring *h) {\n\tduk_size_t len;\n\tduk_uint32_t tmp32;\n\n\tDUK_ASSERT(h != NULL);\n\n\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\tDUK_ASSERT(len <= 0xffffffffUL);  /* string limits */\n\ttmp32 = (duk_uint32_t) len;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\tduk_memcpy((void *) p,\n\t           (const void *) DUK_HSTRING_GET_DATA(h),\n\t           len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_hbuffer_raw(duk_hthread *thr, duk_uint8_t *p, duk_hbuffer *h) {\n\tduk_size_t len;\n\tduk_uint32_t tmp32;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\tDUK_UNREF(thr);\n\n\tlen = DUK_HBUFFER_GET_SIZE(h);\n\tDUK_ASSERT(len <= 0xffffffffUL);  /* buffer limits */\n\ttmp32 = (duk_uint32_t) len;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\t/* When len == 0, buffer data pointer may be NULL. */\n\tduk_memcpy_unsafe((void *) p,\n\t                  (const void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h),\n\t                  len);\n\tp += len;\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_string_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx) {\n\tduk_hstring *h_str;\n\tduk_tval *tv;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_STRING(tv)) {\n\t\th_str = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h_str != NULL);\n\t} else {\n\t\th_str = DUK_HTHREAD_STRING_EMPTY_STRING(thr);\n\t\tDUK_ASSERT(h_str != NULL);\n\t}\n\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(h_str), p);\n\tp = duk__dump_hstring_raw(p, h_str);\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_buffer_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx) {\n\tduk_tval *tv;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h_buf;\n\t\th_buf = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h_buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFFER_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HBUFFER_GET_SIZE(h_buf), p);\n\t\tp = duk__dump_hbuffer_raw(thr, p, h_buf);\n\t} else {\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\t\tDUK_RAW_WRITE_U32_BE(p, 0);\n\t}\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_uint32_prop(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func, duk_small_uint_t stridx, duk_uint32_t def_value) {\n\tduk_tval *tv;\n\tduk_uint32_t val;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) func, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_NUMBER(tv)) {\n\t\tval = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv);\n\t} else {\n\t\tval = def_value;\n\t}\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\tDUK_RAW_WRITE_U32_BE(p, val);\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_varmap(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func) {\n\tduk_hobject *h;\n\n\th = duk_hobject_get_varmap(thr, (duk_hobject *) func);\n\tif (h != NULL) {\n\t\tduk_uint_fast32_t i;\n\n\t\t/* We know _Varmap only has own properties so walk property\n\t\t * table directly.  We also know _Varmap is dense and all\n\t\t * values are numbers; assert for these.  GC and finalizers\n\t\t * shouldn't affect _Varmap so side effects should be fine.\n\t\t */\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\t\tduk_hstring *key;\n\t\t\tduk_tval *tv_val;\n\t\t\tduk_uint32_t val;\n\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, h, i);\n\t\t\tDUK_ASSERT(key != NULL);  /* _Varmap is dense */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, h, i));\n\t\t\ttv_val = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, h, i);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_val));  /* known to be number; in fact an integer */\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv_val));\n\t\t\tDUK_ASSERT(DUK_TVAL_GET_FASTINT(tv_val) == (duk_int64_t) DUK_TVAL_GET_FASTINT_U32(tv_val));  /* known to be 32-bit */\n\t\t\tval = DUK_TVAL_GET_FASTINT_U32(tv_val);\n#else\n\t\t\tval = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv_val);\n#endif\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(key) + 4U, p);\n\t\t\tp = duk__dump_hstring_raw(p, key);\n\t\t\tDUK_RAW_WRITE_U32_BE(p, val);\n\t\t}\n\t}\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\tDUK_RAW_WRITE_U32_BE(p, 0);  /* end of _Varmap */\n\treturn p;\n}\n\nDUK_LOCAL duk_uint8_t *duk__dump_formals(duk_hthread *thr, duk_uint8_t *p, duk_bufwriter_ctx *bw_ctx, duk_hobject *func) {\n\tduk_harray *h;\n\n\th = duk_hobject_get_formals(thr, (duk_hobject *) func);\n\tif (h != NULL) {\n\t\tduk_uint32_t i;\n\n\t\t/* Here we rely on _Formals being a dense array containing\n\t\t * strings.  This should be the case unless _Formals has been\n\t\t * tweaked by the application (which we don't support right\n\t\t * now).\n\t\t */\n\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\t\tDUK_ASSERT(h->length != DUK__NO_FORMALS);  /* limits */\n\t\tDUK_RAW_WRITE_U32_BE(p, h->length);\n\n\t\tfor (i = 0; i < h->length; i++) {\n\t\t\tduk_tval *tv_val;\n\t\t\tduk_hstring *varname;\n\n\t\t\ttv_val = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, (duk_hobject *) h, i);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_val));\n\n\t\t\tvarname = DUK_TVAL_GET_STRING(tv_val);\n\t\t\tDUK_ASSERT(varname != NULL);\n\t\t\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(varname) >= 1);\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U + DUK_HSTRING_GET_BYTELEN(varname), p);\n\t\t\tp = duk__dump_hstring_raw(p, varname);\n\t\t}\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"dumping function without _Formals, emit marker to indicate missing _Formals\"));\n\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 4U, p);\n\t\tDUK_RAW_WRITE_U32_BE(p, DUK__NO_FORMALS);  /* marker: no formals */\n\t}\n\treturn p;\n}\n\nstatic duk_uint8_t *duk__dump_func(duk_hthread *thr, duk_hcompfunc *func, duk_bufwriter_ctx *bw_ctx, duk_uint8_t *p) {\n\tduk_tval *tv, *tv_end;\n\tduk_instr_t *ins, *ins_end;\n\tduk_hobject **fn, **fn_end;\n\tduk_hstring *h_str;\n\tduk_uint32_t count_instr;\n\tduk_uint32_t tmp32;\n\tduk_uint16_t tmp16;\n\tduk_double_t d;\n\n\tDUK_DD(DUK_DDPRINT(\"dumping function %p to %p: \"\n\t                   \"consts=[%p,%p[ (%ld bytes, %ld items), \"\n\t                   \"funcs=[%p,%p[ (%ld bytes, %ld items), \"\n\t                   \"code=[%p,%p[ (%ld bytes, %ld items)\",\n\t                   (void *) func,\n\t                   (void *) p,\n\t                   (void *) DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CONSTS_SIZE(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CONSTS_COUNT(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_FUNCS_SIZE(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, func),\n\t                   (void *) DUK_HCOMPFUNC_GET_CODE_END(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CODE_SIZE(thr->heap, func),\n\t                   (long) DUK_HCOMPFUNC_GET_CODE_COUNT(thr->heap, func)));\n\n\tDUK_ASSERT(DUK_USE_ESBC_MAX_BYTES <= 0x7fffffffUL);  /* ensures no overflow */\n\tcount_instr = (duk_uint32_t) DUK_HCOMPFUNC_GET_CODE_COUNT(thr->heap, func);\n\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 3U * 4U + 2U * 2U + 3U * 4U + count_instr * 4U, p);\n\n\t/* Fixed header info. */\n\ttmp32 = count_instr;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp32 = (duk_uint32_t) DUK_HCOMPFUNC_GET_CONSTS_COUNT(thr->heap, func);\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp32 = (duk_uint32_t) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, func);\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp16 = func->nregs;\n\tDUK_RAW_WRITE_U16_BE(p, tmp16);\n\ttmp16 = func->nargs;\n\tDUK_RAW_WRITE_U16_BE(p, tmp16);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\ttmp32 = func->start_line;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\ttmp32 = func->end_line;\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n#else\n\tDUK_RAW_WRITE_U32_BE(p, 0);\n\tDUK_RAW_WRITE_U32_BE(p, 0);\n#endif\n\ttmp32 = DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) func);  /* masks flags, only duk_hobject flags */\n\ttmp32 &= ~(DUK_HOBJECT_FLAG_HAVE_FINALIZER);  /* finalizer flag is lost */\n\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\n\t/* Bytecode instructions: endian conversion needed unless\n\t * platform is big endian.\n\t */\n\tins = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, func);\n\tins_end = DUK_HCOMPFUNC_GET_CODE_END(thr->heap, func);\n\tDUK_ASSERT((duk_size_t) (ins_end - ins) == (duk_size_t) count_instr);\n#if defined(DUK_USE_INTEGER_BE)\n\tduk_memcpy_unsafe((void *) p, (const void *) ins, (size_t) (ins_end - ins));\n\tp += (size_t) (ins_end - ins);\n#else\n\twhile (ins != ins_end) {\n\t\ttmp32 = (duk_uint32_t) (*ins);\n\t\tDUK_RAW_WRITE_U32_BE(p, tmp32);\n\t\tins++;\n\t}\n#endif\n\n\t/* Constants: variable size encoding. */\n\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, func);\n\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, func);\n\twhile (tv != tv_end) {\n\t\t/* constants are strings or numbers now */\n\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv) ||\n\t\t           DUK_TVAL_IS_NUMBER(tv));\n\n\t\tif (DUK_TVAL_IS_STRING(tv)) {\n\t\t\th_str = DUK_TVAL_GET_STRING(tv);\n\t\t\tDUK_ASSERT(h_str != NULL);\n\t\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= 0x7fffffffUL);  /* ensures no overflow */\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1U + 4U + DUK_HSTRING_GET_BYTELEN(h_str), p);\n\t\t\t*p++ = DUK__SER_STRING;\n\t\t\tp = duk__dump_hstring_raw(p, h_str);\n\t\t} else {\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\t\tp = DUK_BW_ENSURE_RAW(thr, bw_ctx, 1U + 8U, p);\n\t\t\t*p++ = DUK__SER_NUMBER;\n\t\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t\t\tDUK_RAW_WRITE_DOUBLE_BE(p, d);\n\t\t}\n\t\ttv++;\n\t}\n\n\t/* Inner functions recursively. */\n\tfn = (duk_hobject **) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, func);\n\tfn_end = (duk_hobject **) DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, func);\n\twhile (fn != fn_end) {\n\t\t/* XXX: This causes recursion up to inner function depth\n\t\t * which is normally not an issue, e.g. mark-and-sweep uses\n\t\t * a recursion limiter to avoid C stack issues.  Avoiding\n\t\t * this would mean some sort of a work list or just refusing\n\t\t * to serialize deep functions.\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(*fn));\n\t\tp = duk__dump_func(thr, (duk_hcompfunc *) *fn, bw_ctx, p);\n\t\tfn++;\n\t}\n\n\t/* Lexenv and varenv are not dumped. */\n\n\t/* Object extra properties.\n\t *\n\t * There are some difference between function templates and functions.\n\t * For example, function templates don't have .length and nargs is\n\t * normally used to instantiate the functions.\n\t */\n\n\tp = duk__dump_uint32_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_LENGTH, (duk_uint32_t) func->nargs);\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tp = duk__dump_string_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_NAME);\n#endif\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tp = duk__dump_string_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_FILE_NAME);\n#endif\n#if defined(DUK_USE_PC2LINE)\n\tp = duk__dump_buffer_prop(thr, p, bw_ctx, (duk_hobject *) func, DUK_STRIDX_INT_PC2LINE);\n#endif\n\tp = duk__dump_varmap(thr, p, bw_ctx, (duk_hobject *) func);\n\tp = duk__dump_formals(thr, p, bw_ctx, (duk_hobject *) func);\n\n\tDUK_DD(DUK_DDPRINT(\"serialized function %p -> final pointer %p\", (void *) func, (void *) p));\n\n\treturn p;\n}\n\n/* Load a function from bytecode.  The function object returned here must\n * match what is created by duk_js_push_closure() with respect to its flags,\n * properties, etc.\n *\n * NOTE: there are intentionally no input buffer length / bound checks.\n * Adding them would be easy but wouldn't ensure memory safety as untrusted\n * or broken bytecode is unsafe during execution unless the opcodes themselves\n * are validated (which is quite complex, especially for indirect opcodes).\n */\n\n#define DUK__ASSERT_LEFT(n) do { \\\n\t\tDUK_ASSERT((duk_size_t) (p_end - p) >= (duk_size_t) (n)); \\\n\t} while (0)\n\nstatic duk_uint8_t *duk__load_func(duk_hthread *thr, duk_uint8_t *p, duk_uint8_t *p_end) {\n\tduk_hcompfunc *h_fun;\n\tduk_hbuffer *h_data;\n\tduk_size_t data_size;\n\tduk_uint32_t count_instr, count_const, count_funcs;\n\tduk_uint32_t n;\n\tduk_uint32_t tmp32;\n\tduk_small_uint_t const_type;\n\tduk_uint8_t *fun_data;\n\tduk_uint8_t *q;\n\tduk_idx_t idx_base;\n\tduk_tval *tv1;\n\tduk_uarridx_t arr_idx;\n\tduk_uarridx_t arr_limit;\n\tduk_hobject *func_env;\n\tduk_bool_t need_pop;\n\n\t/* XXX: There's some overlap with duk_js_closure() here, but\n\t * seems difficult to share code.  Ensure that the final function\n\t * looks the same as created by duk_js_closure().\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"loading function, p=%p, p_end=%p\", (void *) p, (void *) p_end));\n\n\tDUK__ASSERT_LEFT(3 * 4);\n\tcount_instr = DUK_RAW_READ_U32_BE(p);\n\tcount_const = DUK_RAW_READ_U32_BE(p);\n\tcount_funcs = DUK_RAW_READ_U32_BE(p);\n\n\tdata_size = sizeof(duk_tval) * count_const +\n\t            sizeof(duk_hobject *) * count_funcs +\n\t            sizeof(duk_instr_t) * count_instr;\n\n\tDUK_DD(DUK_DDPRINT(\"instr=%ld, const=%ld, funcs=%ld, data_size=%ld\",\n\t                   (long) count_instr, (long) count_const,\n\t                   (long) count_const, (long) data_size));\n\n\t/* Value stack is used to ensure reachability of constants and\n\t * inner functions being loaded.  Require enough space to handle\n\t * large functions correctly.\n\t */\n\tduk_require_stack(thr, (duk_idx_t) (2 + count_const + count_funcs));\n\tidx_base = duk_get_top(thr);\n\n\t/* Push function object, init flags etc.  This must match\n\t * duk_js_push_closure() quite carefully.\n\t */\n\th_fun = duk_push_hcompfunc(thr);\n\tDUK_ASSERT(h_fun != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) h_fun));\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, h_fun) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, h_fun) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, h_fun) == NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_fun) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\n\th_fun->nregs = DUK_RAW_READ_U16_BE(p);\n\th_fun->nargs = DUK_RAW_READ_U16_BE(p);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\th_fun->start_line = DUK_RAW_READ_U32_BE(p);\n\th_fun->end_line = DUK_RAW_READ_U32_BE(p);\n#else\n\tp += 8;  /* skip line info */\n#endif\n\n\t/* duk_hcompfunc flags; quite version specific */\n\ttmp32 = DUK_RAW_READ_U32_BE(p);\n\tDUK_HEAPHDR_SET_FLAGS((duk_heaphdr *) h_fun, tmp32);  /* masks flags to only change duk_hobject flags */\n\n\t/* standard prototype (no need to set here, already set) */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_fun) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#if 0\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, &h_fun->obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#endif\n\n\t/* assert just a few critical flags */\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h_fun) == DUK_HTYPE_OBJECT);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&h_fun->obj));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_IS_PROXY(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(&h_fun->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(&h_fun->obj));\n\n\t/* Create function 'data' buffer but don't attach it yet. */\n\tfun_data = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, data_size);\n\tDUK_ASSERT(fun_data != NULL);\n\n\t/* Load bytecode instructions. */\n\tDUK_ASSERT(sizeof(duk_instr_t) == 4);\n\tDUK__ASSERT_LEFT(count_instr * sizeof(duk_instr_t));\n#if defined(DUK_USE_INTEGER_BE)\n\tq = fun_data + sizeof(duk_tval) * count_const + sizeof(duk_hobject *) * count_funcs;\n\tduk_memcpy((void *) q,\n\t           (const void *) p,\n\t           sizeof(duk_instr_t) * count_instr);\n\tp += sizeof(duk_instr_t) * count_instr;\n#else\n\tq = fun_data + sizeof(duk_tval) * count_const + sizeof(duk_hobject *) * count_funcs;\n\tfor (n = count_instr; n > 0; n--) {\n\t\t*((duk_instr_t *) (void *) q) = DUK_RAW_READ_U32_BE(p);\n\t\tq += sizeof(duk_instr_t);\n\t}\n#endif\n\n\t/* Load constants onto value stack but don't yet copy to buffer. */\n\tfor (n = count_const; n > 0; n--) {\n\t\tDUK__ASSERT_LEFT(1);\n\t\tconst_type = DUK_RAW_READ_U8(p);\n\t\tswitch (const_type) {\n\t\tcase DUK__SER_STRING: {\n\t\t\tp = duk__load_string_raw(thr, p);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK__SER_NUMBER: {\n\t\t\t/* Important to do a fastint check so that constants are\n\t\t\t * properly read back as fastints.\n\t\t\t */\n\t\t\tduk_tval tv_tmp;\n\t\t\tduk_double_t val;\n\t\t\tDUK__ASSERT_LEFT(8);\n\t\t\tval = DUK_RAW_READ_DOUBLE_BE(p);\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(&tv_tmp, val);\n\t\t\tduk_push_tval(thr, &tv_tmp);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tgoto format_error;\n\t\t}\n\t\t}\n\t}\n\n\t/* Load inner functions to value stack, but don't yet copy to buffer. */\n\tfor (n = count_funcs; n > 0; n--) {\n\t\tp = duk__load_func(thr, p, p_end);\n\t\tif (p == NULL) {\n\t\t\tgoto format_error;\n\t\t}\n\t}\n\n\t/* With constants and inner functions on value stack, we can now\n\t * atomically finish the function 'data' buffer, bump refcounts,\n\t * etc.\n\t *\n\t * Here we take advantage of the value stack being just a duk_tval\n\t * array: we can just memcpy() the constants as long as we incref\n\t * them afterwards.\n\t */\n\n\th_data = (duk_hbuffer *) duk_known_hbuffer(thr, idx_base + 1);\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC(h_data));\n\tDUK_HCOMPFUNC_SET_DATA(thr->heap, h_fun, h_data);\n\tDUK_HBUFFER_INCREF(thr, h_data);\n\n\ttv1 = duk_get_tval(thr, idx_base + 2);  /* may be NULL if no constants or inner funcs */\n\tDUK_ASSERT((count_const == 0 && count_funcs == 0) || tv1 != NULL);\n\n\tq = fun_data;\n\tduk_memcpy_unsafe((void *) q, (const void *) tv1, sizeof(duk_tval) * count_const);\n\tfor (n = count_const; n > 0; n--) {\n\t\tDUK_TVAL_INCREF_FAST(thr, (duk_tval *) (void *) q);  /* no side effects */\n\t\tq += sizeof(duk_tval);\n\t}\n\ttv1 += count_const;\n\n\tDUK_HCOMPFUNC_SET_FUNCS(thr->heap, h_fun, (duk_hobject **) (void *) q);\n\tfor (n = count_funcs; n > 0; n--) {\n\t\tduk_hobject *h_obj;\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv1));\n\t\th_obj = DUK_TVAL_GET_OBJECT(tv1);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\ttv1++;\n\t\tDUK_HOBJECT_INCREF(thr, h_obj);\n\n\t\t*((duk_hobject **) (void *) q) = h_obj;\n\t\tq += sizeof(duk_hobject *);\n\t}\n\n\tDUK_HCOMPFUNC_SET_BYTECODE(thr->heap, h_fun, (duk_instr_t *) (void *) q);\n\n\t/* The function object is now reachable and refcounts are fine,\n\t * so we can pop off all the temporaries.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"function is reachable, reset top; func: %!iT\", duk_get_tval(thr, idx_base)));\n\tduk_set_top(thr, idx_base + 1);\n\n\t/* Setup function properties. */\n\ttmp32 = DUK_RAW_READ_U32_BE(p);\n\tduk_push_u32(thr, tmp32);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tp = duk__load_string_raw(thr, p);  /* -> [ func funcname ] */\n\tfunc_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\tDUK_ASSERT(func_env != NULL);\n\tneed_pop = 0;\n\tif (DUK_HOBJECT_HAS_NAMEBINDING((duk_hobject *) h_fun)) {\n\t\t/* Original function instance/template had NAMEBINDING.\n\t\t * Must create a lexical environment on loading to allow\n\t\t * recursive functions like 'function foo() { foo(); }'.\n\t\t */\n\t\tduk_hdecenv *new_env;\n\n\t\tnew_env = duk_hdecenv_alloc(thr,\n\t\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\t\tDUK_ASSERT(new_env != NULL);\n\t\tDUK_ASSERT(new_env->thread == NULL);  /* Closed. */\n\t\tDUK_ASSERT(new_env->varmap == NULL);\n\t\tDUK_ASSERT(new_env->regbase_byteoff == 0);\n\t\tDUK_HDECENV_ASSERT_VALID(new_env);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, func_env);\n\t\tDUK_HOBJECT_INCREF(thr, func_env);\n\n\t\tfunc_env = (duk_hobject *) new_env;\n\n\t\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\n\t\tduk_dup_m2(thr);                                  /* -> [ func funcname env funcname ] */\n\t\tduk_dup(thr, idx_base);                           /* -> [ func funcname env funcname func ] */\n\t\tduk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_NONE);  /* -> [ func funcname env ] */\n\n\t\tneed_pop = 1;  /* Need to pop env, but -after- updating h_fun and increfs. */\n\t}\n\tDUK_ASSERT(func_env != NULL);\n\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, h_fun, func_env);\n\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, h_fun, func_env);\n\tDUK_HOBJECT_INCREF(thr, func_env);\n\tDUK_HOBJECT_INCREF(thr, func_env);\n\tif (need_pop) {\n\t\tduk_pop(thr);\n\t}\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n#endif  /* DUK_USE_FUNC_NAME_PROPERTY */\n\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tp = duk__load_string_raw(thr, p);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C);\n#endif  /* DUK_USE_FUNC_FILENAME_PROPERTY */\n\n\tif (DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) h_fun)) {\n\t\t/* Restore empty external .prototype only for constructable\n\t\t * functions.  The prototype object should inherit from\n\t\t * Object.prototype.\n\t\t */\n\t\tduk_push_object(thr);\n\t\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\t\tduk_dup_m2(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC);  /* func.prototype.constructor = func */\n\t\tduk_compact_m1(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W);\n\t}\n\n#if defined(DUK_USE_PC2LINE)\n\tp = duk__load_buffer_raw(thr, p);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_WC);\n#endif  /* DUK_USE_PC2LINE */\n\n\tduk_push_bare_object(thr);  /* _Varmap */\n\tfor (;;) {\n\t\t/* XXX: awkward */\n\t\tp = duk__load_string_raw(thr, p);\n\t\tif (duk_get_length(thr, -1) == 0) {\n\t\t\tduk_pop(thr);\n\t\t\tbreak;\n\t\t}\n\t\ttmp32 = DUK_RAW_READ_U32_BE(p);\n\t\tduk_push_u32(thr, tmp32);\n\t\tduk_put_prop(thr, -3);\n\t}\n\tduk_compact_m1(thr);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VARMAP, DUK_PROPDESC_FLAGS_NONE);\n\n\t/* _Formals may have been missing in the original function, which is\n\t * handled using a marker length.\n\t */\n\tarr_limit = DUK_RAW_READ_U32_BE(p);\n\tif (arr_limit != DUK__NO_FORMALS) {\n\t\tduk_push_bare_array(thr);  /* _Formals */\n\t\tfor (arr_idx = 0; arr_idx < arr_limit; arr_idx++) {\n\t\t\tp = duk__load_string_raw(thr, p);\n\t\t\tduk_put_prop_index(thr, -2, arr_idx);\n\t\t}\n\t\tduk_compact_m1(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_FORMALS, DUK_PROPDESC_FLAGS_NONE);\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"no _Formals in dumped function\"));\n\t}\n\n\t/* Return with final function pushed on stack top. */\n\tDUK_DD(DUK_DDPRINT(\"final loaded function: %!iT\", duk_get_tval(thr, -1)));\n\tDUK_ASSERT_TOP(thr, idx_base + 1);\n\treturn p;\n\n format_error:\n\treturn NULL;\n}\n\nDUK_EXTERNAL void duk_dump_function(duk_hthread *thr) {\n\tduk_hcompfunc *func;\n\tduk_bufwriter_ctx bw_ctx_alloc;\n\tduk_bufwriter_ctx *bw_ctx = &bw_ctx_alloc;\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Bound functions don't have all properties so we'd either need to\n\t * lookup the non-bound target function or reject bound functions.\n\t * For now, bound functions are rejected with TypeError.\n\t */\n\tfunc = duk_require_hcompfunc(thr, -1);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&func->obj));\n\n\t/* Estimating the result size beforehand would be costly, so\n\t * start with a reasonable size and extend as needed.\n\t */\n\tDUK_BW_INIT_PUSHBUF(thr, bw_ctx, DUK__BYTECODE_INITIAL_ALLOC);\n\tp = DUK_BW_GET_PTR(thr, bw_ctx);\n\t*p++ = DUK__SER_MARKER;\n\tp = duk__dump_func(thr, func, bw_ctx, p);\n\tDUK_BW_SET_PTR(thr, bw_ctx, p);\n\tDUK_BW_COMPACT(thr, bw_ctx);\n\n\tDUK_DD(DUK_DDPRINT(\"serialized result: %!T\", duk_get_tval(thr, -1)));\n\n\tduk_remove_m2(thr);  /* [ ... func buf ] -> [ ... buf ] */\n}\n\nDUK_EXTERNAL void duk_load_function(duk_hthread *thr) {\n\tduk_uint8_t *p_buf, *p, *p_end;\n\tduk_size_t sz;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tp_buf = (duk_uint8_t *) duk_require_buffer(thr, -1, &sz);\n\tDUK_ASSERT(p_buf != NULL);\n\n\t/* The caller is responsible for being sure that bytecode being loaded\n\t * is valid and trusted.  Invalid bytecode can cause memory unsafe\n\t * behavior directly during loading or later during bytecode execution\n\t * (instruction validation would be quite complex to implement).\n\t *\n\t * This signature check is the only sanity check for detecting\n\t * accidental invalid inputs.  The initial byte ensures no ordinary\n\t * string or Symbol will be accepted by accident.\n\t */\n\tp = p_buf;\n\tp_end = p_buf + sz;\n\tif (sz < 1 || p[0] != DUK__SER_MARKER) {\n\t\tgoto format_error;\n\t}\n\tp++;\n\n\tp = duk__load_func(thr, p, p_end);\n\tif (p == NULL) {\n\t\tgoto format_error;\n\t}\n\n\tduk_remove_m2(thr);  /* [ ... buf func ] -> [ ... func ] */\n\treturn;\n\n format_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BYTECODE);\n\tDUK_WO_NORETURN(return;);\n}\n\n#else  /* DUK_USE_BYTECODE_DUMP_SUPPORT */\n\nDUK_EXTERNAL void duk_dump_function(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_load_function(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n#endif  /* DUK_USE_BYTECODE_DUMP_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_api_call.c",
    "content": "/*\n *  Calls.\n *\n *  Protected variants should avoid ever throwing an error.  Must be careful\n *  to catch errors related to value stack manipulation and property lookup,\n *  not just the call itself.\n *\n *  The only exception is when arguments are insane, e.g. nargs/nrets are out\n *  of bounds; in such cases an error is thrown for two reasons.  First, we\n *  can't always respect the value stack input/output guarantees in such cases\n *  so the caller would end up with the value stack in an unexpected state.\n *  Second, an attempt to create an error might itself fail (although this\n *  could be avoided by pushing a preallocated object/string or a primitive\n *  value).\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Helpers\n */\n\nstruct duk__pcall_prop_args {\n\tduk_idx_t obj_idx;\n\tduk_idx_t nargs;\n\tduk_small_uint_t call_flags;\n};\ntypedef struct duk__pcall_prop_args duk__pcall_prop_args;\n\nstruct duk__pcall_method_args {\n\tduk_idx_t nargs;\n\tduk_small_uint_t call_flags;\n};\ntypedef struct duk__pcall_method_args duk__pcall_method_args;\n\nstruct duk__pcall_args {\n\tduk_idx_t nargs;\n\tduk_small_uint_t call_flags;\n};\ntypedef struct duk__pcall_args duk__pcall_args;\n\n/* Compute and validate idx_func for a certain 'nargs' and 'other'\n * parameter count (1 or 2, depending on whether 'this' binding is\n * present).\n */\nDUK_LOCAL duk_idx_t duk__call_get_idx_func(duk_hthread *thr, duk_idx_t nargs, duk_idx_t other) {\n\tduk_idx_t idx_func;\n\n\t/* XXX: byte arithmetic? */\n\n\tDUK_ASSERT(other >= 0);\n\n\tidx_func = duk_get_top(thr) - nargs - other;\n\tif (DUK_UNLIKELY((idx_func | nargs) < 0)) {  /* idx_func < 0 || nargs < 0; OR sign bits */\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\treturn idx_func;\n}\n\n/* Compute idx_func, assume index will be valid.  This is a valid assumption\n * for protected calls: nargs < 0 is checked explicitly and duk_safe_call()\n * validates the argument count.\n */\nDUK_LOCAL duk_idx_t duk__call_get_idx_func_unvalidated(duk_hthread *thr, duk_idx_t nargs, duk_idx_t other) {\n\tduk_idx_t idx_func;\n\n\t/* XXX: byte arithmetic? */\n\n\tDUK_ASSERT(nargs >= 0);\n\tDUK_ASSERT(other >= 0);\n\n\tidx_func = duk_get_top(thr) - nargs - other;\n\tDUK_ASSERT(idx_func >= 0);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\treturn idx_func;\n}\n\n/* Prepare value stack for a method call through an object property.\n * May currently throw an error e.g. when getting the property.\n */\nDUK_LOCAL void duk__call_prop_prep_stack(duk_hthread *thr, duk_idx_t normalized_obj_idx, duk_idx_t nargs) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(nargs >= 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__call_prop_prep_stack, normalized_obj_idx=%ld, nargs=%ld, stacktop=%ld\",\n\t                     (long) normalized_obj_idx, (long) nargs, (long) duk_get_top(thr)));\n\n\t/* [... key arg1 ... argN] */\n\n\t/* duplicate key */\n\tduk_dup(thr, -nargs - 1);  /* Note: -nargs alone would fail for nargs == 0, this is OK */\n\t(void) duk_get_prop(thr, normalized_obj_idx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"func: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\tif (DUK_UNLIKELY(!duk_is_callable(thr, -1))) {\n\t\tduk_tval *tv_base;\n\t\tduk_tval *tv_key;\n\n\t\t/* tv_targ is passed on stack top (at index -1). */\n\t\ttv_base = DUK_GET_TVAL_POSIDX(thr, normalized_obj_idx);\n\t\ttv_key = DUK_GET_TVAL_NEGIDX(thr, -nargs - 2);\n\t\tDUK_ASSERT(tv_base >= thr->valstack_bottom && tv_base < thr->valstack_top);\n\t\tDUK_ASSERT(tv_key >= thr->valstack_bottom && tv_key < thr->valstack_top);\n\n\t\tduk_call_setup_propcall_error(thr, tv_base, tv_key);\n\t}\n#endif\n\n\t/* [... key arg1 ... argN func] */\n\n\tduk_replace(thr, -nargs - 2);\n\n\t/* [... func arg1 ... argN] */\n\n\tduk_dup(thr, normalized_obj_idx);\n\tduk_insert(thr, -nargs - 1);\n\n\t/* [... func this arg1 ... argN] */\n}\n\nDUK_EXTERNAL void duk_call(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_small_uint_t call_flags;\n\tduk_idx_t idx_func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx_func = duk__call_get_idx_func(thr, nargs, 1);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tduk_insert_undefined(thr, idx_func + 1);\n\n\tcall_flags = 0;  /* not protected, respect reclimit, not constructor */\n\tduk_handle_call_unprotected(thr, idx_func, call_flags);\n}\n\nDUK_EXTERNAL void duk_call_method(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_small_uint_t call_flags;\n\tduk_idx_t idx_func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx_func = duk__call_get_idx_func(thr, nargs, 2);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tcall_flags = 0;  /* not protected, respect reclimit, not constructor */\n\tduk_handle_call_unprotected(thr, idx_func, call_flags);\n}\n\nDUK_EXTERNAL void duk_call_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t nargs) {\n\t/*\n\t *  XXX: if duk_handle_call() took values through indices, this could be\n\t *  made much more sensible.  However, duk_handle_call() needs to fudge\n\t *  the 'this' and 'func' values to handle bound functions, which is now\n\t *  done \"in-place\", so this is not a trivial change.\n\t */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);  /* make absolute */\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk__call_prop_prep_stack(thr, obj_idx, nargs);\n\n\tduk_call_method(thr, nargs);\n}\n\nDUK_LOCAL duk_ret_t duk__pcall_raw(duk_hthread *thr, void *udata) {\n\tduk__pcall_args *args;\n\tduk_idx_t idx_func;\n\tduk_int_t ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\targs = (duk__pcall_args *) udata;\n\tidx_func = duk__call_get_idx_func_unvalidated(thr, args->nargs, 1);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tduk_insert_undefined(thr, idx_func + 1);\n\n\tret = duk_handle_call_unprotected(thr, idx_func, args->call_flags);\n\tDUK_ASSERT(ret == 0);\n\tDUK_UNREF(ret);\n\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_pcall(duk_hthread *thr, duk_idx_t nargs) {\n\tduk__pcall_args args;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\targs.nargs = nargs;\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\targs.call_flags = 0;\n\n\treturn duk_safe_call(thr, duk__pcall_raw, (void *) &args /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);\n}\n\nDUK_LOCAL duk_ret_t duk__pcall_method_raw(duk_hthread *thr, void *udata) {\n\tduk__pcall_method_args *args;\n\tduk_idx_t idx_func;\n\tduk_int_t ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\targs = (duk__pcall_method_args *) udata;\n\n\tidx_func = duk__call_get_idx_func_unvalidated(thr, args->nargs, 2);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tret = duk_handle_call_unprotected(thr, idx_func, args->call_flags);\n\tDUK_ASSERT(ret == 0);\n\tDUK_UNREF(ret);\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_int_t duk_pcall_method_flags(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags) {\n\tduk__pcall_method_args args;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\targs.nargs = nargs;\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\targs.call_flags = call_flags;\n\n\treturn duk_safe_call(thr, duk__pcall_method_raw, (void *) &args /*udata*/, nargs + 2 /*nargs*/, 1 /*nrets*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_pcall_method(duk_hthread *thr, duk_idx_t nargs) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_pcall_method_flags(thr, nargs, 0);\n}\n\nDUK_LOCAL duk_ret_t duk__pcall_prop_raw(duk_hthread *thr, void *udata) {\n\tduk__pcall_prop_args *args;\n\tduk_idx_t obj_idx;\n\tduk_int_t ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\targs = (duk__pcall_prop_args *) udata;\n\n\tobj_idx = duk_require_normalize_index(thr, args->obj_idx);  /* make absolute */\n\tduk__call_prop_prep_stack(thr, obj_idx, args->nargs);\n\n\tret = duk_handle_call_unprotected_nargs(thr, args->nargs, args->call_flags);\n\tDUK_ASSERT(ret == 0);\n\tDUK_UNREF(ret);\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_pcall_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t nargs) {\n\tduk__pcall_prop_args args;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\targs.obj_idx = obj_idx;\n\targs.nargs = nargs;\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\targs.call_flags = 0;\n\n\treturn duk_safe_call(thr, duk__pcall_prop_raw, (void *) &args /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_safe_call(duk_hthread *thr, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* nargs condition; fail if: top - bottom < nargs\n\t *                      <=>  top < bottom + nargs\n\t * nrets condition; fail if: end - (top - nargs) < nrets\n\t *                      <=>  end - top + nargs < nrets\n\t *                      <=>  end + nargs < top + nrets\n\t */\n\t/* XXX: check for any reserve? */\n\n\tif (DUK_UNLIKELY((nargs | nrets) < 0 ||  /* nargs < 0 || nrets < 0; OR sign bits */\n\t                 thr->valstack_top < thr->valstack_bottom + nargs ||        /* nargs too large compared to top */\n\t                 thr->valstack_end + nargs < thr->valstack_top + nrets)) {  /* nrets too large compared to reserve */\n\t\tDUK_D(DUK_DPRINT(\"not enough stack reserve for safe call or invalid arguments: \"\n\t\t                 \"nargs=%ld < 0 (?), nrets=%ld < 0 (?), top=%ld < bottom=%ld + nargs=%ld (?), \"\n\t\t                 \"end=%ld + nargs=%ld < top=%ld + nrets=%ld (?)\",\n\t\t                  (long) nargs,\n\t\t                  (long) nrets,\n\t\t                  (long) (thr->valstack_top - thr->valstack),\n\t\t                  (long) (thr->valstack_bottom - thr->valstack),\n\t\t                  (long) nargs,\n\t\t                  (long) (thr->valstack_end - thr->valstack),\n\t\t                  (long) nargs,\n\t\t                  (long) (thr->valstack_top - thr->valstack),\n\t\t                  (long) nrets));\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\n\trc = duk_handle_safe_call(thr,           /* thread */\n\t                          func,          /* func */\n\t                          udata,         /* udata */\n\t                          nargs,         /* num_stack_args */\n\t                          nrets);        /* num_stack_res */\n\n\treturn rc;\n}\n\nDUK_EXTERNAL void duk_new(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_idx_t idx_func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx_func = duk__call_get_idx_func(thr, nargs, 1);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\n\tduk_push_object(thr);  /* default instance; internal proto updated by call handling */\n\tduk_insert(thr, idx_func + 1);\n\n\tduk_handle_call_unprotected(thr, idx_func, DUK_CALL_FLAG_CONSTRUCT);\n}\n\nDUK_LOCAL duk_ret_t duk__pnew_helper(duk_hthread *thr, void *udata) {\n\tduk_idx_t nargs;\n\n\tDUK_ASSERT(udata != NULL);\n\tnargs = *((duk_idx_t *) udata);\n\n\tduk_new(thr, nargs);\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_pnew(duk_hthread *thr, duk_idx_t nargs) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* For now, just use duk_safe_call() to wrap duk_new().  We can't\n\t * simply use a protected duk_handle_call() because pushing the\n\t * default instance might throw.\n\t */\n\n\tif (DUK_UNLIKELY(nargs < 0)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return DUK_EXEC_ERROR;);\n\t}\n\n\trc = duk_safe_call(thr, duk__pnew_helper, (void *) &nargs /*udata*/, nargs + 1 /*nargs*/, 1 /*nrets*/);\n\treturn rc;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_constructor_call(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\treturn ((act->flags & DUK_ACT_FLAG_CONSTRUCT) != 0 ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL void duk_require_constructor_call(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (!duk_is_constructor_call(thr)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_CONSTRUCT_ONLY);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_strict_call(duk_hthread *thr) {\n\tduk_activation *act;\n\n\t/* For user code this could just return 1 (strict) always\n\t * because all Duktape/C functions are considered strict,\n\t * and strict is also the default when nothing is running.\n\t * However, Duktape may call this function internally when\n\t * the current activation is an ECMAScript function, so\n\t * this cannot be replaced by a 'return 1' without fixing\n\t * the internal call sites.\n\t */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\treturn ((act->flags & DUK_ACT_FLAG_STRICT) != 0 ? 1 : 0);\n\t} else {\n\t\t/* Strict by default. */\n\t\treturn 1;\n\t}\n}\n\n/*\n *  Duktape/C function magic\n */\n\nDUK_EXTERNAL duk_int_t duk_get_current_magic(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_hobject *func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act) {\n\t\tfunc = DUK_ACT_GET_FUNC(act);\n\t\tif (!func) {\n\t\t\tduk_tval *tv = &act->tv_func;\n\t\t\tduk_small_uint_t lf_flags;\n\t\t\tlf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv);\n\t\t\treturn (duk_int_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags);\n\t\t}\n\t\tDUK_ASSERT(func != NULL);\n\n\t\tif (DUK_HOBJECT_IS_NATFUNC(func)) {\n\t\t\tduk_hnatfunc *nf = (duk_hnatfunc *) func;\n\t\t\treturn (duk_int_t) nf->magic;\n\t\t}\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_int_t duk_get_magic(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (!DUK_HOBJECT_HAS_NATFUNC(h)) {\n\t\t\tgoto type_error;\n\t\t}\n\t\treturn (duk_int_t) ((duk_hnatfunc *) h)->magic;\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_small_uint_t lf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv);\n\t\treturn (duk_int_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags);\n\t}\n\n\t/* fall through */\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_UNEXPECTED_TYPE);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_EXTERNAL void duk_set_magic(duk_hthread *thr, duk_idx_t idx, duk_int_t magic) {\n\tduk_hnatfunc *nf;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tnf = duk_require_hnatfunc(thr, idx);\n\tDUK_ASSERT(nf != NULL);\n\tnf->magic = (duk_int16_t) magic;\n}\n\n/*\n *  Misc helpers\n */\n\n/* Resolve a bound function on value stack top to a non-bound target\n * (leave other values as is).\n */\nDUK_INTERNAL void duk_resolve_nonbound_function(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_HTHREAD_ASSERT_VALID(thr);\n\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(h)) {\n\t\t\tduk_push_tval(thr, &((duk_hboundfunc *) (void *) h)->target);\n\t\t\tduk_replace(thr, -2);\n#if 0\n\t\t\tDUK_TVAL_SET_TVAL(tv, &((duk_hboundfunc *) h)->target);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tDUK_HOBJECT_DECREF_NORZ(thr, h);\n#endif\n\t\t\t/* Rely on Function.prototype.bind() on never creating a bound\n\t\t\t * function whose target is not proper.  This is now safe\n\t\t\t * because the target is not even an internal property but a\n\t\t\t * struct member.\n\t\t\t */\n\t\t\tDUK_ASSERT(duk_is_lightfunc(thr, -1) || duk_is_callable(thr, -1));\n\t\t}\n\t}\n\n\t/* Lightfuncs cannot be bound but are always callable and\n\t * constructable.\n\t */\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_api_codec.c",
    "content": "/*\n *  Encoding and decoding basic formats: hex, base64.\n *\n *  These are in-place operations which may allow an optimized implementation.\n *\n *  Base-64: https://tools.ietf.org/html/rfc4648#section-4\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Misc helpers\n */\n\n/* Shared handling for encode/decode argument.  Fast path handling for\n * buffer and string values because they're the most common.  In particular,\n * avoid creating a temporary string or buffer when possible.  Return value\n * is guaranteed to be non-NULL, even for zero length input.\n */\nDUK_LOCAL const duk_uint8_t *duk__prep_codec_arg(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tconst void *def_ptr = (const void *) out_len;  /* Any non-NULL pointer will do. */\n\tconst void *ptr;\n\tduk_bool_t isbuffer;\n\n\tDUK_ASSERT(out_len != NULL);\n\tDUK_ASSERT(def_ptr != NULL);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx));  /* checked by caller */\n\n\tptr = (const void *) duk_get_buffer_data_raw(thr, idx, out_len, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, &isbuffer);\n\tif (isbuffer) {\n\t\tDUK_ASSERT(ptr != NULL || *out_len == 0U);\n\t\tif (DUK_UNLIKELY(ptr == NULL)) {\n\t\t\tptr = def_ptr;\n\t\t}\n\t\tDUK_ASSERT(ptr != NULL);\n\t} else {\n\t\t/* For strings a non-NULL pointer is always guaranteed because\n\t\t * at least a NUL will be present.\n\t\t */\n\t\tptr = (const void *) duk_to_lstring(thr, idx, out_len);\n\t\tDUK_ASSERT(ptr != NULL);\n\t}\n\tDUK_ASSERT(ptr != NULL);\n\treturn (const duk_uint8_t *) ptr;\n}\n\n/*\n *  Base64\n */\n\n#if defined(DUK_USE_BASE64_SUPPORT)\n/* Bytes emitted for number of padding characters in range [0,4]. */\nDUK_LOCAL const duk_int8_t duk__base64_decode_nequal_step[5] = {\n\t3,   /* #### -> 24 bits, emit 3 bytes */\n\t2,   /* ###= -> 18 bits, emit 2 bytes */\n\t1,   /* ##== -> 12 bits, emit 1 byte */\n\t-1,  /* #=== -> 6 bits, error */\n\t0,   /* ==== -> 0 bits, emit 0 bytes */\n};\n\n#if defined(DUK_USE_BASE64_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__base64_enctab_fast[64] = {\n\t0x41U, 0x42U, 0x43U, 0x44U, 0x45U, 0x46U, 0x47U, 0x48U, 0x49U, 0x4aU, 0x4bU, 0x4cU, 0x4dU, 0x4eU, 0x4fU, 0x50U,  /* A...P */\n\t0x51U, 0x52U, 0x53U, 0x54U, 0x55U, 0x56U, 0x57U, 0x58U, 0x59U, 0x5aU, 0x61U, 0x62U, 0x63U, 0x64U, 0x65U, 0x66U,  /* Q...f */\n\t0x67U, 0x68U, 0x69U, 0x6aU, 0x6bU, 0x6cU, 0x6dU, 0x6eU, 0x6fU, 0x70U, 0x71U, 0x72U, 0x73U, 0x74U, 0x75U, 0x76U,  /* g...v */\n\t0x77U, 0x78U, 0x79U, 0x7aU, 0x30U, 0x31U, 0x32U, 0x33U, 0x34U, 0x35U, 0x36U, 0x37U, 0x38U, 0x39U, 0x2bU, 0x2fU   /* w.../ */\n};\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\n#if defined(DUK_USE_BASE64_FASTPATH)\n/* Decode table for one byte of input:\n *   -1 = allowed whitespace\n *   -2 = padding\n *   -3 = error\n *    0...63 decoded bytes\n */\nDUK_LOCAL const duk_int8_t duk__base64_dectab_fast[256] = {\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -1, -1, -3, -3, -1, -3, -3,  /* 0x00...0x0f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0x10...0x1f */\n\t-1, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, 62, -3, -3, -3, 63,  /* 0x20...0x2f */\n\t52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -3, -3, -3, -2, -3, -3,  /* 0x30...0x3f */\n\t-3,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,  /* 0x40...0x4f */\n\t15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -3, -3, -3, -3, -3,  /* 0x50...0x5f */\n\t-3, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,  /* 0x60...0x6f */\n\t41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -3, -3, -3, -3, -3,  /* 0x70...0x7f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0x80...0x8f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0x90...0x9f */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xa0...0xaf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xb0...0xbf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xc0...0xcf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xd0...0xdf */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,  /* 0xe0...0xef */\n\t-3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3   /* 0xf0...0xff */\n};\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\n#if defined(DUK_USE_BASE64_FASTPATH)\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_3(const duk_uint8_t *src, duk_uint8_t *dst) {\n\tduk_uint_t t;\n\n\tt = (duk_uint_t) src[0];\n\tt = (t << 8) + (duk_uint_t) src[1];\n\tt = (t << 8) + (duk_uint_t) src[2];\n\n\tdst[0] = duk__base64_enctab_fast[t >> 18];\n\tdst[1] = duk__base64_enctab_fast[(t >> 12) & 0x3fU];\n\tdst[2] = duk__base64_enctab_fast[(t >> 6) & 0x3fU];\n\tdst[3] = duk__base64_enctab_fast[t & 0x3fU];\n\n#if 0\n\t/* Tested: not faster on x64, most likely due to aliasing between\n\t * output and input index computation.\n\t */\n\t/* aaaaaabb bbbbcccc ccdddddd */\n\tdst[0] = duk__base64_enctab_fast[(src[0] >> 2) & 0x3fU];\n\tdst[1] = duk__base64_enctab_fast[((src[0] << 4) & 0x30U) | ((src[1] >> 4) & 0x0fU)];\n\tdst[2] = duk__base64_enctab_fast[((src[1] << 2) & 0x3fU) | ((src[2] >> 6) & 0x03U)];\n\tdst[3] = duk__base64_enctab_fast[src[2] & 0x3fU];\n#endif\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_2(const duk_uint8_t *src, duk_uint8_t *dst) {\n\tduk_uint_t t;\n\n\tt = (duk_uint_t) src[0];\n\tt = (t << 8) + (duk_uint_t) src[1];\n\tdst[0] = duk__base64_enctab_fast[t >> 10];           /* XXXXXX-- -------- */\n\tdst[1] = duk__base64_enctab_fast[(t >> 4) & 0x3fU];  /* ------XX XXXX---- */\n\tdst[2] = duk__base64_enctab_fast[(t << 2) & 0x3fU];  /* -------- ----XXXX */\n\tdst[3] = DUK_ASC_EQUALS;\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__base64_encode_fast_1(const duk_uint8_t *src, duk_uint8_t *dst) {\n\tduk_uint_t t;\n\n\tt = (duk_uint_t) src[0];\n\tdst[0] = duk__base64_enctab_fast[t >> 2];            /* XXXXXX-- */\n\tdst[1] = duk__base64_enctab_fast[(t << 4) & 0x3fU];  /* ------XX */\n\tdst[2] = DUK_ASC_EQUALS;\n\tdst[3] = DUK_ASC_EQUALS;\n}\n\nDUK_LOCAL void duk__base64_encode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst) {\n\tduk_size_t n;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t *q;\n\n\tn = srclen;\n\tp = src;\n\tq = dst;\n\n\tif (n >= 16U) {\n\t\t/* Fast path, unrolled by 4, allows interleaving.  Process\n\t\t * 12-byte input chunks which encode to 16-char output chunks.\n\t\t * Only enter when at least one block is emitted (avoids div+mul\n\t\t * for short inputs too).\n\t\t */\n\t\tconst duk_uint8_t *p_end_fast;\n\n\t\tp_end_fast = p + ((n / 12U) * 12U);\n\t\tDUK_ASSERT(p_end_fast >= p + 12);\n\t\tdo {\n\t\t\tduk__base64_encode_fast_3(p, q);\n\t\t\tduk__base64_encode_fast_3(p + 3, q + 4);\n\t\t\tduk__base64_encode_fast_3(p + 6, q + 8);\n\t\t\tduk__base64_encode_fast_3(p + 9, q + 12);\n\t\t\tp += 12;\n\t\t\tq += 16;\n\t\t} while (DUK_LIKELY(p != p_end_fast));\n\n\t\tDUK_ASSERT(src + srclen >= p);\n\t\tn = (duk_size_t) (src + srclen - p);\n\t\tDUK_ASSERT(n < 12U);\n\t}\n\n\t/* Remainder. */\n\twhile (n >= 3U) {\n\t\tduk__base64_encode_fast_3(p, q);\n\t\tp += 3;\n\t\tq += 4;\n\t\tn -= 3U;\n\t}\n\tDUK_ASSERT(n == 0U || n == 1U || n == 2U);\n\tif (n == 1U) {\n\t\tduk__base64_encode_fast_1(p, q);\n#if 0  /* Unnecessary. */\n\t\tp += 1;\n\t\tq += 4;\n\t\tn -= 1U;\n#endif\n\t} else if (n == 2U) {\n\t\tduk__base64_encode_fast_2(p, q);\n#if 0  /* Unnecessary. */\n\t\tp += 2;\n\t\tq += 4;\n\t\tn -= 2U;\n#endif\n\t} else {\n\t\tDUK_ASSERT(n == 0U);  /* nothing to do */\n\t\t;\n\t}\n}\n#else  /* DUK_USE_BASE64_FASTPATH */\nDUK_LOCAL void duk__base64_encode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst) {\n\tduk_small_uint_t i, npad;\n\tduk_uint_t t, x, y;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint8_t *q;\n\n\tp = src;\n\tp_end = src + srclen;\n\tq = dst;\n\tnpad = 0U;\n\n\twhile (p < p_end) {\n\t\t/* Read 3 bytes into 't', padded by zero. */\n\t\tt = 0;\n\t\tfor (i = 0; i < 3; i++) {\n\t\t\tt = t << 8;\n\t\t\tif (p < p_end) {\n\t\t\t\tt += (duk_uint_t) (*p++);\n\t\t\t} else {\n\t\t\t\t/* This only happens on the last loop and we're\n\t\t\t\t * guaranteed to exit on the next loop.\n\t\t\t\t */\n\t\t\t\tnpad++;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(npad <= 2U);\n\n\t\t/* Emit 4 encoded characters.  If npad > 0, some of the\n\t\t * chars will be incorrect (zero bits) but we fix up the\n\t\t * padding after the loop.  A straightforward 64-byte\n\t\t * lookup would be faster and cleaner, but this is shorter.\n\t\t */\n\t\tfor (i = 0; i < 4; i++) {\n\t\t\tx = ((t >> 18) & 0x3fU);\n\t\t\tt = t << 6;\n\n\t\t\tif (x <= 51U) {\n\t\t\t\tif (x <= 25) {\n\t\t\t\t\ty = x + DUK_ASC_UC_A;\n\t\t\t\t} else {\n\t\t\t\t\ty = x - 26 + DUK_ASC_LC_A;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (x <= 61U) {\n\t\t\t\t\ty = x - 52 + DUK_ASC_0;\n\t\t\t\t} else if (x == 62) {\n\t\t\t\t\ty = DUK_ASC_PLUS;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(x == 63);\n\t\t\t\t\ty = DUK_ASC_SLASH;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t*q++ = (duk_uint8_t) y;\n\t\t}\n\t}\n\n\t/* Handle padding by rewriting 0-2 bogus characters at the end.\n\t *\n\t *  Missing bytes    npad     base64 example\n\t *    0               0         ####\n\t *    1               1         ###=\n\t *    2               2         ##==\n\t */\n\tDUK_ASSERT(npad <= 2U);\n\twhile (npad > 0U) {\n\t\t*(q - npad) = DUK_ASC_EQUALS;\n\t\tnpad--;\n\t}\n}\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\n#if defined(DUK_USE_BASE64_FASTPATH)\nDUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst, duk_uint8_t **out_dst_final) {\n\tduk_int_t x;\n\tduk_uint_t t;\n\tduk_small_uint_t n_equal;\n\tduk_int8_t step;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint8_t *p_end_safe;\n\tduk_uint8_t *q;\n\n\tDUK_ASSERT(src != NULL);  /* Required by pointer arithmetic below, which fails for NULL. */\n\n\tp = src;\n\tp_end = src + srclen;\n\tp_end_safe = p_end - 8;  /* If 'src <= src_end_safe', safe to read 8 bytes. */\n\tq = dst;\n\n\t/* Alternate between a fast path which processes clean groups with no\n\t * padding or whitespace, and a slow path which processes one arbitrary\n\t * group and then re-enters the fast path.  This handles e.g. base64\n\t * with newlines reasonably well because the majority of a line is in\n\t * the fast path.\n\t */\n\tfor (;;) {\n\t\t/* Fast path, on each loop handle two 4-char input groups.\n\t\t * If both are clean, emit 6 bytes and continue.  If first\n\t\t * is clean, emit 3 bytes and drop out; otherwise emit\n\t\t * nothing and drop out.  This approach could be extended to\n\t\t * more groups per loop, but for inputs with e.g. periodic\n\t\t * newlines (which are common) it might not be an improvement.\n\t\t */\n\t\twhile (DUK_LIKELY(p <= p_end_safe)) {\n\t\t\tduk_int_t t1, t2;\n\n\t\t\t/* The lookup byte is intentionally sign extended to\n\t\t\t * (at least) 32 bits and then ORed.  This ensures\n\t\t\t * that is at least 1 byte is negative, the highest\n\t\t\t * bit of the accumulator will be set at the end and\n\t\t\t * we don't need to check every byte.\n\t\t\t *\n\t\t\t * Read all input bytes first before writing output\n\t\t\t * bytes to minimize aliasing.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast loop: p=%p, p_end_safe=%p, p_end=%p\",\n\t\t\t                     (const void *) p, (const void *) p_end_safe, (const void *) p_end));\n\n\t\t\tt1 = (duk_int_t) duk__base64_dectab_fast[p[0]];\n\t\t\tt1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[1]];\n\t\t\tt1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[2]];\n\t\t\tt1 = (duk_int_t) ((duk_uint_t) t1 << 6) | (duk_int_t) duk__base64_dectab_fast[p[3]];\n\n\t\t\tt2 = (duk_int_t) duk__base64_dectab_fast[p[4]];\n\t\t\tt2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[5]];\n\t\t\tt2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[6]];\n\t\t\tt2 = (duk_int_t) ((duk_uint_t) t2 << 6) | (duk_int_t) duk__base64_dectab_fast[p[7]];\n\n\t\t\tq[0] = (duk_uint8_t) (((duk_uint_t) t1 >> 16) & 0xffU);\n\t\t\tq[1] = (duk_uint8_t) (((duk_uint_t) t1 >> 8) & 0xffU);\n\t\t\tq[2] = (duk_uint8_t) ((duk_uint_t) t1 & 0xffU);\n\n\t\t\tq[3] = (duk_uint8_t) (((duk_uint_t) t2 >> 16) & 0xffU);\n\t\t\tq[4] = (duk_uint8_t) (((duk_uint_t) t2 >> 8) & 0xffU);\n\t\t\tq[5] = (duk_uint8_t) ((duk_uint_t) t2 & 0xffU);\n\n\t\t\t/* Optimistic check using one branch. */\n\t\t\tif (DUK_LIKELY((t1 | t2) >= 0)) {\n\t\t\t\tp += 8;\n\t\t\t\tq += 6;\n\t\t\t} else if (t1 >= 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast loop first group was clean, second was not, process one slow path group\"));\n\t\t\t\tDUK_ASSERT(t2 < 0);\n\t\t\t\tp += 4;\n\t\t\t\tq += 3;\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast loop first group was not clean, second does not matter, process one slow path group\"));\n\t\t\t\tDUK_ASSERT(t1 < 0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}  /* fast path */\n\n\t\t/* Slow path step 1: try to scan a 4-character encoded group,\n\t\t * end-of-input, or start-of-padding.  We exit with:\n\t\t *   1. n_chars == 4: full group, no padding, no end-of-input.\n\t\t *   2. n_chars < 4: partial group (may also be 0), encountered\n\t\t *      padding or end of input.\n\t\t *\n\t\t * The accumulator is initialized to 1; this allows us to detect\n\t\t * a full group by comparing >= 0x1000000 without an extra\n\t\t * counter variable.\n\t\t */\n\t\tt = 1UL;\n\t\tfor (;;) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slow loop: p=%p, p_end=%p, t=%lu\",\n\t\t\t                     (const void *) p, (const void *) p_end, (unsigned long) t));\n\n\t\t\tif (DUK_LIKELY(p < p_end)) {\n\t\t\t\tx = duk__base64_dectab_fast[*p++];\n\t\t\t\tif (DUK_LIKELY(x >= 0)) {\n\t\t\t\t\tDUK_ASSERT(x >= 0 && x <= 63);\n\t\t\t\t\tt = (t << 6) + (duk_uint_t) x;\n\t\t\t\t\tif (t >= 0x1000000UL) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t} else if (x == -1) {\n\t\t\t\t\tcontinue;  /* allowed ascii whitespace */\n\t\t\t\t} else if (x == -2) {\n\t\t\t\t\tp--;\n\t\t\t\t\tbreak;  /* start of padding */\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(x == -3);\n\t\t\t\t\tgoto decode_error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tbreak;  /* end of input */\n\t\t\t}\n\t\t}  /* slow path step 1 */\n\n\t\t/* Complete the padding by simulating pad characters,\n\t\t * regardless of actual input padding chars.\n\t\t */\n\t\tn_equal = 0;\n\t\twhile (t < 0x1000000UL) {\n\t\t\tt = (t << 6) + 0U;\n\t\t\tn_equal++;\n\t\t}\n\n\t\t/* Slow path step 2: deal with full/partial group, padding,\n\t\t * etc.  Note that for num chars in [0,3] we intentionally emit\n\t\t * 3 bytes but don't step forward that much, buffer space is\n\t\t * guaranteed in setup.\n\t\t *\n\t\t *  num chars:\n\t\t *   0      ####   no output (= step 0)\n\t\t *   1      #===   reject, 6 bits of data\n\t\t *   2      ##==   12 bits of data, output 1 byte (= step 1)\n\t\t *   3      ###=   18 bits of data, output 2 bytes (= step 2)\n\t\t *   4      ####   24 bits of data, output 3 bytes (= step 3)\n\t\t */\n\t\tq[0] = (duk_uint8_t) ((t >> 16) & 0xffU);\n\t\tq[1] = (duk_uint8_t) ((t >> 8) & 0xffU);\n\t\tq[2] = (duk_uint8_t) (t & 0xffU);\n\n\t\tDUK_ASSERT(n_equal <= 4);\n\t\tstep = duk__base64_decode_nequal_step[n_equal];\n\t\tif (DUK_UNLIKELY(step < 0)) {\n\t\t\tgoto decode_error;\n\t\t}\n\t\tq += step;\n\n\t\t/* Slow path step 3: read and ignore padding and whitespace\n\t\t * until (a) next non-padding and non-whitespace character\n\t\t * after which we resume the fast path, or (b) end of input.\n\t\t * This allows us to accept missing, partial, full, and extra\n\t\t * padding cases uniformly.  We also support concatenated\n\t\t * base-64 documents because we resume scanning afterwards.\n\t\t *\n\t\t * Note that to support concatenated documents well, the '='\n\t\t * padding found inside the input must also allow for 'extra'\n\t\t * padding.  For example, 'Zm===' decodes to 'f' and has one\n\t\t * extra padding char.  So, 'Zm===Zm' should decode 'ff', even\n\t\t * though the standard break-up would be 'Zm==' + '=Zm' which\n\t\t * doesn't make sense.\n\t\t *\n\t\t * We also accept prepended padding like '==Zm9', because it\n\t\t * is equivalent to an empty document with extra padding ('==')\n\t\t * followed by a valid document.\n\t\t */\n\n\t\tfor (;;) {\n\t\t\tif (DUK_UNLIKELY(p >= p_end)) {\n\t\t\t\tgoto done;\n\t\t\t}\n\t\t\tx = duk__base64_dectab_fast[*p++];\n\t\t\tif (x == -1 || x == -2) {\n\t\t\t\t;  /* padding or whitespace, keep eating */\n\t\t\t} else {\n\t\t\t\tp--;\n\t\t\t\tbreak;  /* backtrack and go back to fast path, even for -1 */\n\t\t\t}\n\t\t}  /* slow path step 3 */\n\t}  /* outer fast+slow path loop */\n\n done:\n\tDUK_DDD(DUK_DDDPRINT(\"done; p=%p, p_end=%p\",\n\t                     (const void *) p, (const void *) p_end));\n\n\tDUK_ASSERT(p == p_end);\n\n\t*out_dst_final = q;\n\treturn 1;\n\n decode_error:\n\treturn 0;\n}\n#else  /* DUK_USE_BASE64_FASTPATH */\nDUK_LOCAL duk_bool_t duk__base64_decode_helper(const duk_uint8_t *src, duk_size_t srclen, duk_uint8_t *dst, duk_uint8_t **out_dst_final) {\n\tduk_uint_t t, x;\n\tduk_int_t y;\n\tduk_int8_t step;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint8_t *q;\n\t/* 0x09, 0x0a, or 0x0d */\n\tduk_uint32_t mask_white = (1U << 9) | (1U << 10) | (1U << 13);\n\n\t/* 't' tracks progress of the decoded group:\n\t *\n\t *  t == 1             no valid chars yet\n\t *  t >= 0x40          1x6 = 6 bits shifted in\n\t *  t >= 0x1000        2x6 = 12 bits shifted in\n\t *  t >= 0x40000       3x6 = 18 bits shifted in\n\t *  t >= 0x1000000     4x6 = 24 bits shifted in\n\t *\n\t * By initializing t=1 there's no need for a separate counter for\n\t * the number of characters found so far.\n\t */\n\tp = src;\n\tp_end = src + srclen;\n\tq = dst;\n\tt = 1UL;\n\n\tfor (;;) {\n\t\tduk_small_uint_t n_equal;\n\n\t\tDUK_ASSERT(t >= 1U);\n\t\tif (p >= p_end) {\n\t\t\t/* End of input: if input exists, treat like\n\t\t\t * start of padding, finish the block, then\n\t\t\t * re-enter here to see we're done.\n\t\t\t */\n\t\t\tif (t == 1U) {\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tgoto simulate_padding;\n\t\t\t}\n\t\t}\n\n\t\tx = *p++;\n\n\t\tif (x >= 0x41U) {\n\t\t\t/* Valid: a-z and A-Z. */\n\t\t\tDUK_ASSERT(x >= 0x41U && x <= 0xffU);\n\t\t\tif (x >= 0x61U && x <= 0x7aU) {\n\t\t\t\ty = (duk_int_t) x - 0x61 + 26;\n\t\t\t} else if (x <= 0x5aU) {\n\t\t\t\ty = (duk_int_t) x - 0x41;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t} else if (x >= 0x30U) {\n\t\t\t/* Valid: 0-9 and =. */\n\t\t\tDUK_ASSERT(x >= 0x30U && x <= 0x40U);\n\t\t\tif (x <= 0x39U) {\n\t\t\t\ty = (duk_int_t) x - 0x30 + 52;\n\t\t\t} else if (x == 0x3dU) {\n\t\t\t\t/* Skip padding and whitespace unless we're in the\n\t\t\t\t * middle of a block.  Otherwise complete group by\n\t\t\t\t * simulating shifting in the correct padding.\n\t\t\t\t */\n\t\t\t\tif (t == 1U) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tgoto simulate_padding;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t} else if (x >= 0x20U) {\n\t\t\t/* Valid: +, /, and 0x20 whitespace. */\n\t\t\tDUK_ASSERT(x >= 0x20U && x <= 0x2fU);\n\t\t\tif (x == 0x2bU) {\n\t\t\t\ty = 62;\n\t\t\t} else if (x == 0x2fU) {\n\t\t\t\ty = 63;\n\t\t\t} else if (x == 0x20U) {\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t} else {\n\t\t\t/* Valid: whitespace. */\n\t\t\tduk_uint32_t m;\n\t\t\tDUK_ASSERT(x < 0x20U);  /* 0x00 to 0x1f */\n\t\t\tm = (1U << x);\n\t\t\tif (mask_white & m) {\n\t\t\t\t/* Allow basic ASCII whitespace. */\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\tgoto decode_error;\n\t\t\t}\n\t\t}\n\n\t\tDUK_ASSERT(y >= 0 && y <= 63);\n\t\tt = (t << 6) + (duk_uint_t) y;\n\t\tif (t < 0x1000000UL) {\n\t\t\tcontinue;\n\t\t}\n\t\t/* fall through; no padding will be added */\n\n\t simulate_padding:\n\t\tn_equal = 0;\n\t\twhile (t < 0x1000000UL) {\n\t\t\tt = (t << 6) + 0U;\n\t\t\tn_equal++;\n\t\t}\n\n\t\t/* Output 3 bytes from 't' and advance as needed. */\n\t\tq[0] = (duk_uint8_t) ((t >> 16) & 0xffU);\n\t\tq[1] = (duk_uint8_t) ((t >> 8) & 0xffU);\n\t\tq[2] = (duk_uint8_t) (t & 0xffU);\n\n\t\tDUK_ASSERT(n_equal <= 4U);\n\t\tstep = duk__base64_decode_nequal_step[n_equal];\n\t\tif (step < 0) {\n\t\t\tgoto decode_error;\n\t\t}\n\t\tq += step;\n\n\t\t/* Re-enter loop.  The actual padding characters are skipped\n\t\t * by the main loop.  This handles cases like missing, partial,\n\t\t * full, and extra padding, and allows parsing of concatenated\n\t\t * documents (with extra padding) like: Zm===Zm.  Also extra\n\t\t * prepended padding is accepted: ===Zm9v.\n\t\t */\n\t\tt = 1U;\n\t}\n\tDUK_ASSERT(t == 1UL);\n\n\t*out_dst_final = q;\n\treturn 1;\n\n decode_error:\n\treturn 0;\n}\n#endif  /* DUK_USE_BASE64_FASTPATH */\n\nDUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *src;\n\tduk_size_t srclen;\n\tduk_size_t dstlen;\n\tduk_uint8_t *dst;\n\tconst char *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tsrc = duk__prep_codec_arg(thr, idx, &srclen);\n\tDUK_ASSERT(src != NULL);\n\n\t/* Compute exact output length.  Computation must not wrap; this\n\t * limit works for 32-bit size_t:\n\t * >>> srclen = 3221225469\n\t * >>> '%x' % ((srclen + 2) / 3 * 4)\n\t * 'fffffffc'\n\t */\n\tif (srclen > 3221225469UL) {\n\t\tgoto type_error;\n\t}\n\tdstlen = (srclen + 2U) / 3U * 4U;\n\tdst = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, dstlen);\n\n\tduk__base64_encode_helper((const duk_uint8_t *) src, srclen, dst);\n\n\tret = duk_buffer_to_string(thr, -1);  /* Safe, result is ASCII. */\n\tduk_replace(thr, idx);\n\treturn ret;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_BASE64_ENCODE_FAILED);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *src;\n\tduk_size_t srclen;\n\tduk_size_t dstlen;\n\tduk_uint8_t *dst;\n\tduk_uint8_t *dst_final;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tsrc = duk__prep_codec_arg(thr, idx, &srclen);\n\tDUK_ASSERT(src != NULL);\n\n\t/* Round up and add safety margin.  Avoid addition before division to\n\t * avoid possibility of wrapping.  Margin includes +3 for rounding up,\n\t * and +3 for one extra group: the decoder may emit and then backtrack\n\t * a full group (3 bytes) from zero-sized input for technical reasons.\n\t * Similarly, 'xx' may ecause 1+3 = bytes to be emitted and then\n\t * backtracked.\n\t */\n\tdstlen = (srclen / 4) * 3 + 6;  /* upper limit, assuming no whitespace etc */\n\tdst = (duk_uint8_t *) duk_push_dynamic_buffer(thr, dstlen);\n\t/* Note: for dstlen=0, dst may be NULL */\n\n\tif (!duk__base64_decode_helper((const duk_uint8_t *) src, srclen, dst, &dst_final)) {\n\t\tgoto type_error;\n\t}\n\n\t/* XXX: convert to fixed buffer? */\n\t(void) duk_resize_buffer(thr, -1, (duk_size_t) (dst_final - dst));\n\tduk_replace(thr, idx);\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_BASE64_DECODE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n#else  /* DUK_USE_BASE64_SUPPORT */\nDUK_EXTERNAL const char *duk_base64_encode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_base64_decode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_BASE64_SUPPORT */\n\n/*\n *  Hex\n */\n\n#if defined(DUK_USE_HEX_SUPPORT)\nDUK_EXTERNAL const char *duk_hex_encode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *inp;\n\tduk_size_t len;\n\tduk_size_t i;\n\tduk_uint8_t *buf;\n\tconst char *ret;\n#if defined(DUK_USE_HEX_FASTPATH)\n\tduk_size_t len_safe;\n\tduk_uint16_t *p16;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tinp = duk__prep_codec_arg(thr, idx, &len);\n\tDUK_ASSERT(inp != NULL);\n\n\t/* Fixed buffer, no zeroing because we'll fill all the data. */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len * 2);\n\tDUK_ASSERT(buf != NULL);\n\n#if defined(DUK_USE_HEX_FASTPATH)\n\tDUK_ASSERT((((duk_size_t) buf) & 0x01U) == 0);   /* pointer is aligned, guaranteed for fixed buffer */\n\tp16 = (duk_uint16_t *) (void *) buf;\n\tlen_safe = len & ~0x03U;\n\tfor (i = 0; i < len_safe; i += 4) {\n\t\tp16[0] = duk_hex_enctab[inp[i]];\n\t\tp16[1] = duk_hex_enctab[inp[i + 1]];\n\t\tp16[2] = duk_hex_enctab[inp[i + 2]];\n\t\tp16[3] = duk_hex_enctab[inp[i + 3]];\n\t\tp16 += 4;\n\t}\n\tfor (; i < len; i++) {\n\t\t*p16++ = duk_hex_enctab[inp[i]];\n\t}\n#else  /* DUK_USE_HEX_FASTPATH */\n\tfor (i = 0; i < len; i++) {\n\t\tduk_small_uint_t t;\n\t\tt = (duk_small_uint_t) inp[i];\n\t\tbuf[i*2 + 0] = duk_lc_digits[t >> 4];\n\t\tbuf[i*2 + 1] = duk_lc_digits[t & 0x0f];\n\t}\n#endif  /* DUK_USE_HEX_FASTPATH */\n\n\t/* XXX: Using a string return value forces a string intern which is\n\t * not always necessary.  As a rough performance measure, hex encode\n\t * time for tests/perf/test-hex-encode.js dropped from ~35s to ~15s\n\t * without string coercion.  Change to returning a buffer and let the\n\t * caller coerce to string if necessary?\n\t */\n\n\tret = duk_buffer_to_string(thr, -1);  /* Safe, result is ASCII. */\n\tduk_replace(thr, idx);\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {\n\tconst duk_uint8_t *inp;\n\tduk_size_t len;\n\tduk_size_t i;\n\tduk_int_t t;\n\tduk_uint8_t *buf;\n#if defined(DUK_USE_HEX_FASTPATH)\n\tduk_int_t chk;\n\tduk_uint8_t *p;\n\tduk_size_t len_safe;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tinp = duk__prep_codec_arg(thr, idx, &len);\n\tDUK_ASSERT(inp != NULL);\n\n\tif (len & 0x01) {\n\t\tgoto type_error;\n\t}\n\n\t/* Fixed buffer, no zeroing because we'll fill all the data. */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len / 2);\n\tDUK_ASSERT(buf != NULL);\n\n#if defined(DUK_USE_HEX_FASTPATH)\n\tp = buf;\n\tlen_safe = len & ~0x07U;\n\tfor (i = 0; i < len_safe; i += 8) {\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 1]]);\n\t\tchk = t;\n\t\tp[0] = (duk_uint8_t) t;\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 2]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 3]]);\n\t\tchk |= t;\n\t\tp[1] = (duk_uint8_t) t;\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 4]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 5]]);\n\t\tchk |= t;\n\t\tp[2] = (duk_uint8_t) t;\n\t\tt = ((duk_int_t) duk_hex_dectab_shift4[inp[i + 6]]) |\n\t\t    ((duk_int_t) duk_hex_dectab[inp[i + 7]]);\n\t\tchk |= t;\n\t\tp[3] = (duk_uint8_t) t;\n\t\tp += 4;\n\n\t\t/* Check if any lookup above had a negative result. */\n\t\tif (DUK_UNLIKELY(chk < 0)) {\n\t\t\tgoto type_error;\n\t\t}\n\t}\n\tfor (; i < len; i += 2) {\n\t\t/* First cast to duk_int_t to sign extend, second cast to\n\t\t * duk_uint_t to avoid signed left shift, and final cast to\n\t\t * duk_int_t result type.\n\t\t */\n\t\tt = (duk_int_t) ((((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i]]) << 4U) |\n\t\t                 ((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i + 1]]));\n\t\tif (DUK_UNLIKELY(t < 0)) {\n\t\t\tgoto type_error;\n\t\t}\n\t\t*p++ = (duk_uint8_t) t;\n\t}\n#else  /* DUK_USE_HEX_FASTPATH */\n\tfor (i = 0; i < len; i += 2) {\n\t\t/* For invalid characters the value -1 gets extended to\n\t\t * at least 16 bits.  If either nybble is invalid, the\n\t\t * resulting 't' will be < 0.\n\t\t */\n\t\tt = (duk_int_t) ((((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i]]) << 4U) |\n\t\t                 ((duk_uint_t) (duk_int_t) duk_hex_dectab[inp[i + 1]]));\n\t\tif (DUK_UNLIKELY(t < 0)) {\n\t\t\tgoto type_error;\n\t\t}\n\t\tbuf[i >> 1] = (duk_uint8_t) t;\n\t}\n#endif  /* DUK_USE_HEX_FASTPATH */\n\n\tduk_replace(thr, idx);\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_HEX_DECODE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n#else  /* DUK_USE_HEX_SUPPORT */\nDUK_EXTERNAL const char *duk_hex_encode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\nDUK_EXTERNAL void duk_hex_decode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_HEX_SUPPORT */\n\n/*\n *  JSON\n */\n\n#if defined(DUK_USE_JSON_SUPPORT)\nDUK_EXTERNAL const char *duk_json_encode(duk_hthread *thr, duk_idx_t idx) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t top_at_entry;\n#endif\n\tconst char *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\ttop_at_entry = duk_get_top(thr);\n#endif\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tduk_bi_json_stringify_helper(thr,\n\t                             idx /*idx_value*/,\n\t                             DUK_INVALID_INDEX /*idx_replacer*/,\n\t                             DUK_INVALID_INDEX /*idx_space*/,\n\t                             0 /*flags*/);\n\tDUK_ASSERT(duk_is_string(thr, -1));\n\tduk_replace(thr, idx);\n\tret = duk_get_string(thr, idx);\n\n\tDUK_ASSERT(duk_get_top(thr) == top_at_entry);\n\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_json_decode(duk_hthread *thr, duk_idx_t idx) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t top_at_entry;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\ttop_at_entry = duk_get_top(thr);\n#endif\n\n\tidx = duk_require_normalize_index(thr, idx);\n\tduk_bi_json_parse_helper(thr,\n\t                         idx /*idx_value*/,\n\t                         DUK_INVALID_INDEX /*idx_reviver*/,\n\t                         0 /*flags*/);\n\tduk_replace(thr, idx);\n\n\tDUK_ASSERT(duk_get_top(thr) == top_at_entry);\n}\n#else  /* DUK_USE_JSON_SUPPORT */\nDUK_EXTERNAL const char *duk_json_encode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_EXTERNAL void duk_json_decode(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_JSON_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_api_compile.c",
    "content": "/*\n *  Compilation and evaluation\n */\n\n#include \"duk_internal.h\"\n\ntypedef struct duk__compile_raw_args duk__compile_raw_args;\nstruct duk__compile_raw_args {\n\tduk_size_t src_length;  /* should be first on 64-bit platforms */\n\tconst duk_uint8_t *src_buffer;\n\tduk_uint_t flags;\n};\n\n/* Eval is just a wrapper now. */\nDUK_EXTERNAL duk_int_t duk_eval_raw(duk_hthread *thr, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: strictness is *not* inherited from the current Duktape/C.\n\t * This would be confusing because the current strictness state\n\t * depends on whether we're running inside a Duktape/C activation\n\t * (= strict mode) or outside of any activation (= non-strict mode).\n\t * See tests/api/test-eval-strictness.c for more discussion.\n\t */\n\n\t/* [ ... source? filename? ] (depends on flags) */\n\n\trc = duk_compile_raw(thr, src_buffer, src_length, flags | DUK_COMPILE_EVAL);  /* may be safe, or non-safe depending on flags */\n\n\t/* [ ... closure/error ] */\n\n\tif (rc != DUK_EXEC_SUCCESS) {\n\t\trc = DUK_EXEC_ERROR;\n\t\tgoto got_rc;\n\t}\n\n\tduk_push_global_object(thr);  /* explicit 'this' binding, see GH-164 */\n\n\tif (flags & DUK_COMPILE_SAFE) {\n\t\trc = duk_pcall_method(thr, 0);\n\t} else {\n\t\tduk_call_method(thr, 0);\n\t\trc = DUK_EXEC_SUCCESS;\n\t}\n\n\t/* [ ... result/error ] */\n\n got_rc:\n\tif (flags & DUK_COMPILE_NORESULT) {\n\t\tduk_pop(thr);\n\t}\n\n\treturn rc;\n}\n\n/* Helper which can be called both directly and with duk_safe_call(). */\nDUK_LOCAL duk_ret_t duk__do_compile(duk_hthread *thr, void *udata) {\n\tduk__compile_raw_args *comp_args;\n\tduk_uint_t flags;\n\tduk_hcompfunc *h_templ;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(udata != NULL);\n\n\t/* Note: strictness is not inherited from the current Duktape/C\n\t * context.  Otherwise it would not be possible to compile\n\t * non-strict code inside a Duktape/C activation (which is\n\t * always strict now).  See tests/api/test-eval-strictness.c\n\t * for discussion.\n\t */\n\n\t/* [ ... source? filename? ] (depends on flags) */\n\n\tcomp_args = (duk__compile_raw_args *) udata;\n\tflags = comp_args->flags;\n\n\tif (flags & DUK_COMPILE_NOFILENAME) {\n\t\t/* Automatic filename: 'eval' or 'input'. */\n\t\tduk_push_hstring_stridx(thr, (flags & DUK_COMPILE_EVAL) ? DUK_STRIDX_EVAL : DUK_STRIDX_INPUT);\n\t}\n\n\t/* [ ... source? filename ] */\n\n\tif (!comp_args->src_buffer) {\n\t\tduk_hstring *h_sourcecode;\n\n\t\th_sourcecode = duk_get_hstring(thr, -2);\n\t\tif ((flags & DUK_COMPILE_NOSOURCE) ||  /* args incorrect */\n\t\t    (h_sourcecode == NULL)) {          /* e.g. duk_push_string_file_raw() pushed undefined */\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_NO_SOURCECODE);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tDUK_ASSERT(h_sourcecode != NULL);\n\t\tcomp_args->src_buffer = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_sourcecode);\n\t\tcomp_args->src_length = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sourcecode);\n\t}\n\tDUK_ASSERT(comp_args->src_buffer != NULL);\n\n\tif (flags & DUK_COMPILE_FUNCTION) {\n\t\tflags |= DUK_COMPILE_EVAL | DUK_COMPILE_FUNCEXPR;\n\t}\n\n\t/* [ ... source? filename ] */\n\n\tduk_js_compile(thr, comp_args->src_buffer, comp_args->src_length, flags);\n\n\t/* [ ... source? func_template ] */\n\n\tif (flags & DUK_COMPILE_NOSOURCE) {\n\t\t;\n\t} else {\n\t\tduk_remove_m2(thr);\n\t}\n\n\t/* [ ... func_template ] */\n\n\th_templ = (duk_hcompfunc *) duk_known_hobject(thr, -1);\n\tduk_js_push_closure(thr,\n\t                   h_templ,\n\t                   thr->builtins[DUK_BIDX_GLOBAL_ENV],\n\t                   thr->builtins[DUK_BIDX_GLOBAL_ENV],\n\t                   1 /*add_auto_proto*/);\n\tduk_remove_m2(thr);   /* -> [ ... closure ] */\n\n\t/* [ ... closure ] */\n\n\treturn 1;\n}\n\nDUK_EXTERNAL duk_int_t duk_compile_raw(duk_hthread *thr, const char *src_buffer, duk_size_t src_length, duk_uint_t flags) {\n\tduk__compile_raw_args comp_args_alloc;\n\tduk__compile_raw_args *comp_args = &comp_args_alloc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif ((flags & DUK_COMPILE_STRLEN) && (src_buffer != NULL)) {\n\t\t/* String length is computed here to avoid multiple evaluation\n\t\t * of a macro argument in the calling side.\n\t\t */\n\t\tsrc_length = DUK_STRLEN(src_buffer);\n\t}\n\n\tcomp_args->src_buffer = (const duk_uint8_t *) src_buffer;\n\tcomp_args->src_length = src_length;\n\tcomp_args->flags = flags;\n\n\t/* [ ... source? filename? ] (depends on flags) */\n\n\tif (flags & DUK_COMPILE_SAFE) {\n\t\tduk_int_t rc;\n\t\tduk_int_t nargs;\n\t\tduk_int_t nrets = 1;\n\n\t\t/* Arguments can be: [ source? filename? &comp_args] so that\n\t\t * nargs is 1 to 3.  Call site encodes the correct nargs count\n\t\t * directly into flags.\n\t\t */\n\t\tnargs = flags & 0x07;\n\t\tDUK_ASSERT(nargs == ((flags & DUK_COMPILE_NOSOURCE) ? 0 : 1) +\n\t\t                    ((flags & DUK_COMPILE_NOFILENAME) ? 0 : 1));\n\t\trc = duk_safe_call(thr, duk__do_compile, (void *) comp_args, nargs, nrets);\n\n\t\t/* [ ... closure ] */\n\t\treturn rc;\n\t}\n\n\t(void) duk__do_compile(thr, (void *) comp_args);\n\n\t/* [ ... closure ] */\n\treturn DUK_EXEC_SUCCESS;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_api_debug.c",
    "content": "/*\n *  Debugging related API calls\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_JSON_SUPPORT)\nDUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr) {\n\tduk_idx_t idx;\n\tduk_idx_t top;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* We don't duk_require_stack() here now, but rely on the caller having\n\t * enough space.\n\t */\n\n\ttop = duk_get_top(thr);\n\tduk_push_bare_array(thr);\n\tfor (idx = 0; idx < top; idx++) {\n\t\tduk_dup(thr, idx);\n\t\tduk_put_prop_index(thr, -2, (duk_uarridx_t) idx);\n\t}\n\n\t/* XXX: conversion errors should not propagate outwards.\n\t * Perhaps values need to be coerced individually?\n\t */\n\tduk_bi_json_stringify_helper(thr,\n\t                             duk_get_top_index(thr),  /*idx_value*/\n\t                             DUK_INVALID_INDEX,  /*idx_replacer*/\n\t                             DUK_INVALID_INDEX,  /*idx_space*/\n\t                             DUK_JSON_FLAG_EXT_CUSTOM |\n\t                             DUK_JSON_FLAG_ASCII_ONLY |\n\t                             DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/);\n\n\tduk_push_sprintf(thr, \"ctx: top=%ld, stack=%s\", (long) top, (const char *) duk_safe_to_string(thr, -1));\n\tduk_replace(thr, -3);  /* [ ... arr jsonx(arr) res ] -> [ ... res jsonx(arr) ] */\n\tduk_pop(thr);\n\tDUK_ASSERT(duk_is_string(thr, -1));\n}\n#else  /* DUK_USE_JSON_SUPPORT */\nDUK_EXTERNAL void duk_push_context_dump(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_JSON_SUPPORT */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\nDUK_EXTERNAL void duk_debugger_attach(duk_hthread *thr,\n                                      duk_debug_read_function read_cb,\n                                      duk_debug_write_function write_cb,\n                                      duk_debug_peek_function peek_cb,\n                                      duk_debug_read_flush_function read_flush_cb,\n                                      duk_debug_write_flush_function write_flush_cb,\n                                      duk_debug_request_function request_cb,\n                                      duk_debug_detached_function detached_cb,\n                                      void *udata) {\n\tduk_heap *heap;\n\tconst char *str;\n\tduk_size_t len;\n\n\t/* XXX: should there be an error or an automatic detach if\n\t * already attached?\n\t */\n\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_attach()\"));\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(read_cb != NULL);\n\tDUK_ASSERT(write_cb != NULL);\n\t/* Other callbacks are optional. */\n\n\theap = thr->heap;\n\theap->dbg_read_cb = read_cb;\n\theap->dbg_write_cb = write_cb;\n\theap->dbg_peek_cb = peek_cb;\n\theap->dbg_read_flush_cb = read_flush_cb;\n\theap->dbg_write_flush_cb = write_flush_cb;\n\theap->dbg_request_cb = request_cb;\n\theap->dbg_detached_cb = detached_cb;\n\theap->dbg_udata = udata;\n\theap->dbg_have_next_byte = 0;\n\n\t/* Start in paused state. */\n\theap->dbg_processing = 0;\n\theap->dbg_state_dirty = 0;\n\theap->dbg_force_restart = 0;\n\theap->dbg_pause_flags = 0;\n\theap->dbg_pause_act = NULL;\n\theap->dbg_pause_startline = 0;\n\theap->dbg_exec_counter = 0;\n\theap->dbg_last_counter = 0;\n\theap->dbg_last_time = 0.0;\n\tduk_debug_set_paused(heap);  /* XXX: overlap with fields above */\n\n\t/* Send version identification and flush right afterwards.  Note that\n\t * we must write raw, unframed bytes here.\n\t */\n\tduk_push_sprintf(thr, \"%ld %ld %s %s\\n\",\n\t                 (long) DUK_DEBUG_PROTOCOL_VERSION,\n\t                 (long) DUK_VERSION,\n\t                 (const char *) DUK_GIT_DESCRIBE,\n\t                 (const char *) DUK_USE_TARGET_INFO);\n\tstr = duk_get_lstring(thr, -1, &len);\n\tDUK_ASSERT(str != NULL);\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) str, len);\n\tduk_debug_write_flush(thr);\n\tduk_pop(thr);\n}\n\nDUK_EXTERNAL void duk_debugger_detach(duk_hthread *thr) {\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_detach()\"));\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\t/* Can be called multiple times with no harm. */\n\tduk_debug_do_detach(thr->heap);\n}\n\nDUK_EXTERNAL void duk_debugger_cooperate(duk_hthread *thr) {\n\tduk_bool_t processed_messages;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tif (!duk_debug_is_attached(thr->heap)) {\n\t\treturn;\n\t}\n\tif (thr->callstack_curr != NULL || thr->heap->dbg_processing) {\n\t\t/* Calling duk_debugger_cooperate() while Duktape is being\n\t\t * called into is not supported.  This is not a 100% check\n\t\t * but prevents any damage in most cases.\n\t\t */\n\t\treturn;\n\t}\n\n\tprocessed_messages = duk_debug_process_messages(thr, 1 /*no_block*/);\n\tDUK_UNREF(processed_messages);\n}\n\nDUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_hthread *thr, duk_idx_t nvalues) {\n\tduk_idx_t top;\n\tduk_idx_t idx;\n\tduk_bool_t ret = 0;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_notify() with nvalues=%ld\", (long) nvalues));\n\n\ttop = duk_get_top(thr);\n\tif (top < nvalues) {\n\t\tDUK_ERROR_RANGE(thr, \"not enough stack values for notify\");\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tduk_debug_write_notify(thr, DUK_DBG_CMD_APPNOTIFY);\n\t\tfor (idx = top - nvalues; idx < top; idx++) {\n\t\t\tduk_tval *tv = DUK_GET_TVAL_POSIDX(thr, idx);\n\t\t\tduk_debug_write_tval(thr, tv);\n\t\t}\n\t\tduk_debug_write_eom(thr);\n\n\t\t/* Return non-zero (true) if we have a good reason to believe\n\t\t * the notify was delivered; if we're still attached at least\n\t\t * a transport error was not indicated by the transport write\n\t\t * callback.  This is not a 100% guarantee of course.\n\t\t */\n\t\tif (duk_debug_is_attached(thr->heap)) {\n\t\t\tret = 1;\n\t\t}\n\t}\n\tduk_pop_n(thr, nvalues);\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_debugger_pause(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tDUK_D(DUK_DPRINT(\"application called duk_debugger_pause()\"));\n\n\t/* Treat like a debugger statement: ignore when not attached. */\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tif (duk_debug_is_paused(thr->heap)) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_debugger_pause() called when already paused; ignoring\"));\n\t\t} else {\n\t\t\tduk_debug_set_paused(thr->heap);\n\n\t\t\t/* Pause on the next opcode executed.  This is always safe to do even\n\t\t\t * inside the debugger message loop: the interrupt counter will be reset\n\t\t\t * to its proper value when the message loop exits.\n\t\t\t */\n\t\t\tthr->interrupt_init = 1;\n\t\t\tthr->interrupt_counter = 0;\n\t\t}\n\t}\n}\n\n#else  /* DUK_USE_DEBUGGER_SUPPORT */\n\nDUK_EXTERNAL void duk_debugger_attach(duk_hthread *thr,\n                                      duk_debug_read_function read_cb,\n                                      duk_debug_write_function write_cb,\n                                      duk_debug_peek_function peek_cb,\n                                      duk_debug_read_flush_function read_flush_cb,\n                                      duk_debug_write_flush_function write_flush_cb,\n                                      duk_debug_request_function request_cb,\n                                      duk_debug_detached_function detached_cb,\n                                      void *udata) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(read_cb);\n\tDUK_UNREF(write_cb);\n\tDUK_UNREF(peek_cb);\n\tDUK_UNREF(read_flush_cb);\n\tDUK_UNREF(write_flush_cb);\n\tDUK_UNREF(request_cb);\n\tDUK_UNREF(detached_cb);\n\tDUK_UNREF(udata);\n\tDUK_ERROR_TYPE(thr, \"no debugger support\");\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_debugger_detach(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ERROR_TYPE(thr, \"no debugger support\");\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_debugger_cooperate(duk_hthread *thr) {\n\t/* nop */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n}\n\nDUK_EXTERNAL duk_bool_t duk_debugger_notify(duk_hthread *thr, duk_idx_t nvalues) {\n\tduk_idx_t top;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttop = duk_get_top(thr);\n\tif (top < nvalues) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* No debugger support, just pop values. */\n\tduk_pop_n(thr, nvalues);\n\treturn 0;\n}\n\nDUK_EXTERNAL void duk_debugger_pause(duk_hthread *thr) {\n\t/* Treat like debugger statement: nop */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n}\n\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_api_heap.c",
    "content": "/*\n *  Heap creation and destruction\n */\n\n#include \"duk_internal.h\"\n\ntypedef struct duk_internal_thread_state duk_internal_thread_state;\n\nstruct duk_internal_thread_state {\n\tduk_ljstate lj;\n\tduk_bool_t creating_error;\n\tduk_hthread *curr_thread;\n\tduk_int_t call_recursion_depth;\n};\n\nDUK_EXTERNAL duk_hthread *duk_create_heap(duk_alloc_function alloc_func,\n                                          duk_realloc_function realloc_func,\n                                          duk_free_function free_func,\n                                          void *heap_udata,\n                                          duk_fatal_function fatal_handler) {\n\tduk_heap *heap = NULL;\n\tduk_hthread *thr;\n\n\t/* Assume that either all memory funcs are NULL or non-NULL, mixed\n\t * cases will now be unsafe.\n\t */\n\n\t/* XXX: just assert non-NULL values here and make caller arguments\n\t * do the defaulting to the default implementations (smaller code)?\n\t */\n\n\tif (!alloc_func) {\n\t\tDUK_ASSERT(realloc_func == NULL);\n\t\tDUK_ASSERT(free_func == NULL);\n#if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS)\n\t\talloc_func = duk_default_alloc_function;\n\t\trealloc_func = duk_default_realloc_function;\n\t\tfree_func = duk_default_free_function;\n#else\n\t\tDUK_D(DUK_DPRINT(\"no allocation functions given and no default providers\"));\n\t\treturn NULL;\n#endif\n\t} else {\n\t\tDUK_ASSERT(realloc_func != NULL);\n\t\tDUK_ASSERT(free_func != NULL);\n\t}\n\n\tif (!fatal_handler) {\n\t\tfatal_handler = duk_default_fatal_handler;\n\t}\n\n\tDUK_ASSERT(alloc_func != NULL);\n\tDUK_ASSERT(realloc_func != NULL);\n\tDUK_ASSERT(free_func != NULL);\n\tDUK_ASSERT(fatal_handler != NULL);\n\n\theap = duk_heap_alloc(alloc_func, realloc_func, free_func, heap_udata, fatal_handler);\n\tif (!heap) {\n\t\treturn NULL;\n\t}\n\tthr = heap->heap_thread;\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\treturn thr;\n}\n\nDUK_EXTERNAL void duk_destroy_heap(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tif (!thr) {\n\t\treturn;\n\t}\n\tDUK_ASSERT_API_ENTRY(thr);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tduk_heap_free(heap);\n}\n\nDUK_EXTERNAL void duk_suspend(duk_hthread *thr, duk_thread_state *state) {\n\tduk_internal_thread_state *snapshot = (duk_internal_thread_state *) (void *) state;\n\tduk_heap *heap;\n\tduk_ljstate *lj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(state != NULL);  /* unvalidated */\n\n\t/* Currently not supported when called from within a finalizer.\n\t * If that is done, the finalizer will remain running indefinitely,\n\t * preventing other finalizers from executing.  The assert is a bit\n\t * wider, checking that it would be OK to run pending finalizers.\n\t */\n\tDUK_ASSERT(thr->heap->pf_prevent_count == 0);\n\n\t/* Currently not supported to duk_suspend() from an errCreate()\n\t * call.\n\t */\n\tDUK_ASSERT(thr->heap->creating_error == 0);\n\n\theap = thr->heap;\n\tlj = &heap->lj;\n\n\tduk_push_tval(thr, &lj->value1);\n\tduk_push_tval(thr, &lj->value2);\n\n\t/* XXX: creating_error == 0 is asserted above, so no need to store. */\n\tduk_memcpy((void *) &snapshot->lj, (const void *) lj, sizeof(duk_ljstate));\n\tsnapshot->creating_error = heap->creating_error;\n\tsnapshot->curr_thread = heap->curr_thread;\n\tsnapshot->call_recursion_depth = heap->call_recursion_depth;\n\n\tlj->jmpbuf_ptr = NULL;\n\tlj->type = DUK_LJ_TYPE_UNKNOWN;\n\tDUK_TVAL_SET_UNDEFINED(&lj->value1);\n\tDUK_TVAL_SET_UNDEFINED(&lj->value2);\n\theap->creating_error = 0;\n\theap->curr_thread = NULL;\n\theap->call_recursion_depth = 0;\n}\n\nDUK_EXTERNAL void duk_resume(duk_hthread *thr, const duk_thread_state *state) {\n\tconst duk_internal_thread_state *snapshot = (const duk_internal_thread_state *) (const void *) state;\n\tduk_heap *heap;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(state != NULL);  /* unvalidated */\n\n\t/* Shouldn't be necessary if duk_suspend() is called before\n\t * duk_resume(), but assert in case API sequence is incorrect.\n\t */\n\tDUK_ASSERT(thr->heap->pf_prevent_count == 0);\n\tDUK_ASSERT(thr->heap->creating_error == 0);\n\n\theap = thr->heap;\n\n\tduk_memcpy((void *) &heap->lj, (const void *) &snapshot->lj, sizeof(duk_ljstate));\n\theap->creating_error = snapshot->creating_error;\n\theap->curr_thread = snapshot->curr_thread;\n\theap->call_recursion_depth = snapshot->call_recursion_depth;\n\n\tduk_pop_2(thr);\n}\n\n/* XXX: better place for this */\nDUK_EXTERNAL void duk_set_global_object(duk_hthread *thr) {\n\tduk_hobject *h_glob;\n\tduk_hobject *h_prev_glob;\n\tduk_hobjenv *h_env;\n\tduk_hobject *h_prev_env;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_D(DUK_DPRINT(\"replace global object with: %!T\", duk_get_tval(thr, -1)));\n\n\th_glob = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(h_glob != NULL);\n\n\t/*\n\t *  Replace global object.\n\t */\n\n\th_prev_glob = thr->builtins[DUK_BIDX_GLOBAL];\n\tDUK_UNREF(h_prev_glob);\n\tthr->builtins[DUK_BIDX_GLOBAL] = h_glob;\n\tDUK_HOBJECT_INCREF(thr, h_glob);\n\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, h_prev_glob);  /* side effects, in theory (referenced by global env) */\n\n\t/*\n\t *  Replace lexical environment for global scope\n\t *\n\t *  Create a new object environment for the global lexical scope.\n\t *  We can't just reset the _Target property of the current one,\n\t *  because the lexical scope is shared by other threads with the\n\t *  same (initial) built-ins.\n\t */\n\n\th_env = duk_hobjenv_alloc(thr,\n\t                          DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                          DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\tDUK_ASSERT(h_env != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_env) == NULL);\n\n\tDUK_ASSERT(h_env->target == NULL);\n\tDUK_ASSERT(h_glob != NULL);\n\th_env->target = h_glob;\n\tDUK_HOBJECT_INCREF(thr, h_glob);\n\tDUK_ASSERT(h_env->has_this == 0);\n\n\t/* [ ... new_glob ] */\n\n\th_prev_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\tthr->builtins[DUK_BIDX_GLOBAL_ENV] = (duk_hobject *) h_env;\n\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) h_env);\n\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, h_prev_env);  /* side effects */\n\tDUK_UNREF(h_env);  /* without refcounts */\n\tDUK_UNREF(h_prev_env);\n\n\t/* [ ... new_glob ] */\n\n\tduk_pop(thr);\n\n\t/* [ ... ] */\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_api_inspect.c",
    "content": "/*\n *  Inspection\n */\n\n#include \"duk_internal.h\"\n\n/* For footprint efficient multiple value setting: arrays are much better than\n * varargs, format string with parsing is often better than string pointer arrays.\n */\nDUK_LOCAL void duk__inspect_multiple_uint(duk_hthread *thr, const char *fmt, duk_int_t *vals) {\n\tduk_int_t val;\n\tconst char *p;\n\tconst char *p_curr;\n\tduk_size_t len;\n\n\tfor (p = fmt;;) {\n\t\tlen = DUK_STRLEN(p);\n\t\tp_curr = p;\n\t\tp += len + 1;\n\t\tif (len == 0) {\n\t\t\t/* Double NUL (= empty key) terminates. */\n\t\t\tbreak;\n\t\t}\n\t\tval = *vals++;\n\t\tif (val >= 0) {\n\t\t\t/* Negative values are markers to skip key. */\n\t\t\tduk_push_string(thr, p_curr);\n\t\t\tduk_push_int(thr, val);\n\t\t\tduk_put_prop(thr, -3);\n\t\t}\n\t}\n}\n\n/* Raw helper to extract internal information / statistics about a value.\n * The return value is an object with properties that are version specific.\n * The properties must not expose anything that would lead to security\n * issues (e.g. exposing compiled function 'data' buffer might be an issue).\n * Currently only counts and sizes and such are given so there shouldn't\n * be security implications.\n */\n\n#define DUK__IDX_TYPE     0\n#define DUK__IDX_ITAG     1\n#define DUK__IDX_REFC     2\n#define DUK__IDX_HBYTES   3\n#define DUK__IDX_CLASS    4\n#define DUK__IDX_PBYTES   5\n#define DUK__IDX_ESIZE    6\n#define DUK__IDX_ENEXT    7\n#define DUK__IDX_ASIZE    8\n#define DUK__IDX_HSIZE    9\n#define DUK__IDX_BCBYTES  10\n#define DUK__IDX_DBYTES   11\n#define DUK__IDX_TSTATE   12\n#define DUK__IDX_VARIANT  13\n\nDUK_EXTERNAL void duk_inspect_value(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_heaphdr *h;\n\t/* The temporary values should be in an array rather than individual\n\t * variables which (in practice) ensures that the compiler won't map\n\t * them to registers and emit a lot of unnecessary shuffling code.\n\t */\n\tduk_int_t vals[14];\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Assume two's complement and set everything to -1. */\n\tduk_memset((void *) &vals, (int) 0xff, sizeof(vals));\n\tDUK_ASSERT(vals[DUK__IDX_TYPE] == -1);  /* spot check one */\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\th = (DUK_TVAL_IS_HEAP_ALLOCATED(tv) ? DUK_TVAL_GET_HEAPHDR(tv) : NULL);\n\n\tvals[DUK__IDX_TYPE] = duk_get_type_tval(tv);\n\tvals[DUK__IDX_ITAG] = (duk_int_t) DUK_TVAL_GET_TAG(tv);\n\n\tduk_push_bare_object(thr);  /* Invalidates 'tv'. */\n\ttv = NULL;\n\n\tif (h == NULL) {\n\t\tgoto finish;\n\t}\n\tduk_push_pointer(thr, (void *) h);\n\tduk_put_prop_literal(thr, -2, \"hptr\");\n\n#if 0\n\t/* Covers a lot of information, e.g. buffer and string variants. */\n\tduk_push_uint(thr, (duk_uint_t) DUK_HEAPHDR_GET_FLAGS(h));\n\tduk_put_prop_literal(thr, -2, \"hflags\");\n#endif\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tvals[DUK__IDX_REFC] = (duk_int_t) DUK_HEAPHDR_GET_REFCOUNT(h);\n#endif\n\tvals[DUK__IDX_VARIANT] = 0;\n\n\t/* Heaphdr size and additional allocation size, followed by\n\t * type specific stuff (with varying value count).\n\t */\n\tswitch ((duk_small_int_t) DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h_str = (duk_hstring *) h;\n\t\tvals[DUK__IDX_HBYTES] = (duk_int_t) (sizeof(duk_hstring) + DUK_HSTRING_GET_BYTELEN(h_str) + 1);\n#if defined(DUK_USE_HSTRING_EXTDATA)\n\t\tif (DUK_HSTRING_HAS_EXTDATA(h_str)) {\n\t\t\tvals[DUK__IDX_VARIANT] = 1;\n\t\t}\n#endif\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h_obj = (duk_hobject *) h;\n\n\t\t/* XXX: variants here are maybe pointless; class is enough? */\n\t\tif (DUK_HOBJECT_IS_ARRAY(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_harray);\n\t\t} else if (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hcompfunc);\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hnatfunc);\n\t\t} else if (DUK_HOBJECT_IS_THREAD(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hthread);\n\t\t\tvals[DUK__IDX_TSTATE] = ((duk_hthread *) h_obj)->state;\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\tvals[DUK__IDX_HBYTES] = sizeof(duk_hbufobj);\n\t\t\t/* XXX: some size information */\n#endif\n\t\t} else {\n\t\t\tvals[DUK__IDX_HBYTES] = (duk_small_uint_t) sizeof(duk_hobject);\n\t\t}\n\n\t\tvals[DUK__IDX_CLASS] = (duk_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h_obj);\n\t\tvals[DUK__IDX_PBYTES] = (duk_int_t) DUK_HOBJECT_P_ALLOC_SIZE(h_obj);\n\t\tvals[DUK__IDX_ESIZE] = (duk_int_t) DUK_HOBJECT_GET_ESIZE(h_obj);\n\t\tvals[DUK__IDX_ENEXT] = (duk_int_t) DUK_HOBJECT_GET_ENEXT(h_obj);\n\t\tvals[DUK__IDX_ASIZE] = (duk_int_t) DUK_HOBJECT_GET_ASIZE(h_obj);\n\t\tvals[DUK__IDX_HSIZE] = (duk_int_t) DUK_HOBJECT_GET_HSIZE(h_obj);\n\n\t\t/* Note: e_next indicates the number of gc-reachable entries\n\t\t * in the entry part, and also indicates the index where the\n\t\t * next new property would be inserted.  It does *not* indicate\n\t\t * the number of non-NULL keys present in the object.  That\n\t\t * value could be counted separately but requires a pass through\n\t\t * the key list.\n\t\t */\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tduk_hbuffer *h_data = (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(thr->heap, (duk_hcompfunc *) h_obj);\n\t\t\tvals[DUK__IDX_BCBYTES] = (duk_int_t) (h_data ? DUK_HBUFFER_GET_SIZE(h_data) : 0);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h_buf = (duk_hbuffer *) h;\n\n\t\tif (DUK_HBUFFER_HAS_DYNAMIC(h_buf)) {\n\t\t\tif (DUK_HBUFFER_HAS_EXTERNAL(h_buf)) {\n\t\t\t\tvals[DUK__IDX_VARIANT] = 2;  /* buffer variant 2: external */\n\t\t\t\tvals[DUK__IDX_HBYTES] = (duk_uint_t) (sizeof(duk_hbuffer_external));\n\t\t\t} else {\n\t\t\t\t/* When alloc_size == 0 the second allocation may not\n\t\t\t\t * actually exist.\n\t\t\t\t */\n\t\t\t\tvals[DUK__IDX_VARIANT] = 1;  /* buffer variant 1: dynamic */\n\t\t\t\tvals[DUK__IDX_HBYTES] = (duk_uint_t) (sizeof(duk_hbuffer_dynamic));\n\t\t\t}\n\t\t\tvals[DUK__IDX_DBYTES] = (duk_int_t) (DUK_HBUFFER_GET_SIZE(h_buf));\n\t\t} else {\n\t\t\tDUK_ASSERT(vals[DUK__IDX_VARIANT] == 0);  /* buffer variant 0: fixed */\n\t\t\tvals[DUK__IDX_HBYTES] = (duk_int_t) (sizeof(duk_hbuffer_fixed) + DUK_HBUFFER_GET_SIZE(h_buf));\n\t\t}\n\t\tbreak;\n\t}\n\t}\n\n finish:\n\tduk__inspect_multiple_uint(thr,\n\t    \"type\" \"\\x00\" \"itag\" \"\\x00\" \"refc\" \"\\x00\" \"hbytes\" \"\\x00\" \"class\" \"\\x00\"\n\t    \"pbytes\" \"\\x00\" \"esize\" \"\\x00\" \"enext\" \"\\x00\" \"asize\" \"\\x00\" \"hsize\" \"\\x00\"\n\t    \"bcbytes\" \"\\x00\" \"dbytes\" \"\\x00\" \"tstate\" \"\\x00\" \"variant\" \"\\x00\" \"\\x00\",\n\t    (duk_int_t *) &vals);\n}\n\nDUK_EXTERNAL void duk_inspect_callstack_entry(duk_hthread *thr, duk_int_t level) {\n\tduk_activation *act;\n\tduk_uint_fast32_t pc;\n\tduk_uint_fast32_t line;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* -1   = top callstack entry\n\t * -2   = caller of level -1\n\t * etc\n\t */\n\tact = duk_hthread_get_activation_for_level(thr, level);\n\tif (act == NULL) {\n\t\tduk_push_undefined(thr);\n\t\treturn;\n\t}\n\tduk_push_bare_object(thr);\n\n\t/* Relevant PC is just before current one because PC is\n\t * post-incremented.  This should match what error augment\n\t * code does.\n\t */\n\tpc = duk_hthread_get_act_prev_pc(thr, act);\n\n\tduk_push_tval(thr, &act->tv_func);\n\n\tduk_push_uint(thr, (duk_uint_t) pc);\n\tduk_put_prop_stridx_short(thr, -3, DUK_STRIDX_PC);\n\n#if defined(DUK_USE_PC2LINE)\n\tline = duk_hobject_pc2line_query(thr, -1, pc);\n#else\n\tline = 0;\n#endif\n\tduk_push_uint(thr, (duk_uint_t) line);\n\tduk_put_prop_stridx_short(thr, -3, DUK_STRIDX_LINE_NUMBER);\n\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_LC_FUNCTION);\n\t/* Providing access to e.g. act->lex_env would be dangerous: these\n\t * internal structures must never be accessible to the application.\n\t * Duktape relies on them having consistent data, and this consistency\n\t * is only asserted for, not checked for.\n\t */\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_api_internal.h",
    "content": "/*\n *  Internal API calls which have (stack and other) semantics similar\n *  to the public API.\n */\n\n#if !defined(DUK_API_INTERNAL_H_INCLUDED)\n#define DUK_API_INTERNAL_H_INCLUDED\n\n/* duk_push_sprintf constants */\n#define DUK_PUSH_SPRINTF_INITIAL_SIZE  256L\n#define DUK_PUSH_SPRINTF_SANITY_LIMIT  (1L * 1024L * 1024L * 1024L)\n\n/* Flag ORed to err_code to indicate __FILE__ / __LINE__ is not\n * blamed as source of error for error fileName / lineNumber.\n */\n#define DUK_ERRCODE_FLAG_NOBLAME_FILELINE  (1L << 24)\n\n/* Current convention is to use duk_size_t for value stack sizes and global indices,\n * and duk_idx_t for local frame indices.\n */\nDUK_INTERNAL_DECL void duk_valstack_grow_check_throw(duk_hthread *thr, duk_size_t min_bytes);\nDUK_INTERNAL_DECL duk_bool_t duk_valstack_grow_check_nothrow(duk_hthread *thr, duk_size_t min_bytes);\nDUK_INTERNAL_DECL void duk_valstack_shrink_check_nothrow(duk_hthread *thr, duk_bool_t snug);\n\nDUK_INTERNAL_DECL void duk_copy_tvals_incref(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_size_t count);\n\nDUK_INTERNAL_DECL duk_tval *duk_reserve_gap(duk_hthread *thr, duk_idx_t idx_base, duk_idx_t count);\n\nDUK_INTERNAL_DECL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_set_top_and_wipe(duk_hthread *thr, duk_idx_t top, duk_idx_t idx_wipe_start);\n\nDUK_INTERNAL_DECL void duk_dup_0(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_1(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_2(duk_hthread *thr);\n/* duk_dup_m1() would be same as duk_dup_top() */\nDUK_INTERNAL_DECL void duk_dup_m2(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_m3(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_dup_m4(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_remove_unsafe(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_remove_m2(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_remove_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count);\nDUK_INTERNAL_DECL void duk_remove_n_unsafe(duk_hthread *thr, duk_idx_t idx, duk_idx_t count);\n\nDUK_INTERNAL_DECL duk_int_t duk_get_type_tval(duk_tval *tv);\nDUK_INTERNAL_DECL duk_uint_t duk_get_type_mask_tval(duk_tval *tv);\n\n#if defined(DUK_USE_VERBOSE_ERRORS) && defined(DUK_USE_PARANOID_ERRORS)\nDUK_INTERNAL_DECL const char *duk_get_type_name(duk_hthread *thr, duk_idx_t idx);\n#endif\nDUK_INTERNAL_DECL duk_small_uint_t duk_get_class_number(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_tval *duk_get_tval(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_tval *duk_get_tval_or_unused(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_tval *duk_require_tval(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_push_tval(duk_hthread *thr, duk_tval *tv);\n\n/* Push the current 'this' binding; throw TypeError if binding is not object\n * coercible (CheckObjectCoercible).\n */\nDUK_INTERNAL_DECL void duk_push_this_check_object_coercible(duk_hthread *thr);\n\n/* duk_push_this() + CheckObjectCoercible() + duk_to_object() */\nDUK_INTERNAL_DECL duk_hobject *duk_push_this_coercible_to_object(duk_hthread *thr);\n\n/* duk_push_this() + CheckObjectCoercible() + duk_to_string() */\nDUK_INTERNAL_DECL duk_hstring *duk_push_this_coercible_to_string(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_hstring *duk_push_uint_to_hstring(duk_hthread *thr, duk_uint_t i);\n\n/* Get a borrowed duk_tval pointer to the current 'this' binding.  Caller must\n * make sure there's an active callstack entry.  Note that the returned pointer\n * is unstable with regards to side effects.\n */\nDUK_INTERNAL_DECL duk_tval *duk_get_borrowed_this_tval(duk_hthread *thr);\n\n/* XXX: add fastint support? */\n#define duk_push_u64(thr,val) \\\n\tduk_push_number((thr), (duk_double_t) (val))\n#define duk_push_i64(thr,val) \\\n\tduk_push_number((thr), (duk_double_t) (val))\n\n/* duk_push_(u)int() is guaranteed to support at least (un)signed 32-bit range */\n#define duk_push_u32(thr,val) \\\n\tduk_push_uint((thr), (duk_uint_t) (val))\n#define duk_push_i32(thr,val) \\\n\tduk_push_int((thr), (duk_int_t) (val))\n\n/* sometimes stack and array indices need to go on the stack */\n#define duk_push_idx(thr,val) \\\n\tduk_push_int((thr), (duk_int_t) (val))\n#define duk_push_uarridx(thr,val) \\\n\tduk_push_uint((thr), (duk_uint_t) (val))\n#define duk_push_size_t(thr,val) \\\n\tduk_push_uint((thr), (duk_uint_t) (val))  /* XXX: assumed to fit for now */\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_string_notsymbol(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_callable_tval(duk_hthread *thr, duk_tval *tv);\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_bare_object(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hstring *duk_get_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hstring *duk_get_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL const char *duk_get_string_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hobject *duk_get_hobject(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hbuffer *duk_get_hbuffer(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hthread *duk_get_hthread(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_get_hcompfunc(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_get_hnatfunc(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL void *duk_get_buffer_data_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len, duk_bool_t throw_flag, duk_bool_t *out_isbuffer);\n\nDUK_INTERNAL_DECL duk_hobject *duk_get_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum);\n\nDUK_INTERNAL_DECL duk_hobject *duk_get_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask);\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask);\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject_accept_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask);\n#define duk_require_hobject_promote_lfunc(thr,idx) \\\n\tduk_require_hobject_promote_mask((thr), (idx), DUK_TYPE_MASK_LIGHTFUNC)\n#define duk_get_hobject_promote_lfunc(thr,idx) \\\n\tduk_get_hobject_promote_mask((thr), (idx), DUK_TYPE_MASK_LIGHTFUNC)\n\n#if 0  /*unused*/\nDUK_INTERNAL_DECL void *duk_get_voidptr(duk_hthread *thr, duk_idx_t idx);\n#endif\n\nDUK_INTERNAL_DECL duk_hstring *duk_known_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hobject *duk_known_hobject(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hbuffer *duk_known_hbuffer(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_known_hcompfunc(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_known_hnatfunc(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_double_t duk_to_number_tval(duk_hthread *thr, duk_tval *tv);\n\nDUK_INTERNAL_DECL duk_hstring *duk_to_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hstring *duk_to_hstring_m1(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_hstring *duk_to_hstring_acceptsymbol(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hobject *duk_to_hobject(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_double_t duk_to_number_m1(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_double_t duk_to_number_m2(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_bool_t duk_to_boolean_top_pop(duk_hthread *thr);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* only needed by debugger for now */\nDUK_INTERNAL_DECL duk_hstring *duk_safe_to_hstring(duk_hthread *thr, duk_idx_t idx);\n#endif\nDUK_INTERNAL_DECL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects);\n\nDUK_INTERNAL_DECL duk_int_t duk_to_int_clamped_raw(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped);  /* out_clamped=NULL, RangeError if outside range */\nDUK_INTERNAL_DECL duk_int_t duk_to_int_clamped(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval);\nDUK_INTERNAL_DECL duk_int_t duk_to_int_check_range(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL_DECL duk_uint8_t duk_to_uint8clamped(duk_hthread *thr, duk_idx_t idx);\n#endif\nDUK_INTERNAL_DECL duk_hstring *duk_to_property_key_hstring(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hstring *duk_require_hstring(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hstring *duk_require_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL const char *duk_require_lstring_notsymbol(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len);\nDUK_INTERNAL_DECL const char *duk_require_string_notsymbol(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hbuffer *duk_require_hbuffer(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hthread *duk_require_hthread(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_require_hcompfunc(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_require_hnatfunc(duk_hthread *thr, duk_idx_t idx);\n\nDUK_INTERNAL_DECL duk_hobject *duk_require_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum);\n\nDUK_INTERNAL_DECL void duk_push_hstring(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_push_hstring_stridx(duk_hthread *thr, duk_small_uint_t stridx);\nDUK_INTERNAL_DECL void duk_push_hstring_empty(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_push_hobject(duk_hthread *thr, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_push_hbuffer(duk_hthread *thr, duk_hbuffer *h);\n#define duk_push_hthread(thr,h) \\\n\tduk_push_hobject((thr), (duk_hobject *) (h))\n#define duk_push_hnatfunc(thr,h) \\\n\tduk_push_hobject((thr), (duk_hobject *) (h))\nDUK_INTERNAL_DECL void duk_push_hobject_bidx(duk_hthread *thr, duk_small_int_t builtin_idx);\nDUK_INTERNAL_DECL duk_hobject *duk_push_object_helper(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx);\nDUK_INTERNAL_DECL duk_hobject *duk_push_object_helper_proto(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_hobject *proto);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_push_hcompfunc(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_hboundfunc *duk_push_hboundfunc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_push_c_function_builtin(duk_hthread *thr, duk_c_function func, duk_int_t nargs);\nDUK_INTERNAL_DECL void duk_push_c_function_builtin_noconstruct(duk_hthread *thr, duk_c_function func, duk_int_t nargs);\n\n/* XXX: duk_push_harray() and duk_push_hcompfunc() are inconsistent with\n * duk_push_hobject() etc which don't create a new value.\n */\nDUK_INTERNAL_DECL duk_harray *duk_push_harray(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_harray *duk_push_harray_with_size(duk_hthread *thr, duk_uint32_t size);\nDUK_INTERNAL_DECL duk_tval *duk_push_harray_with_size_outptr(duk_hthread *thr, duk_uint32_t size);\n\nDUK_INTERNAL_DECL void duk_push_string_funcptr(duk_hthread *thr, duk_uint8_t *ptr, duk_size_t sz);\nDUK_INTERNAL_DECL void duk_push_lightfunc_name_raw(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags);\nDUK_INTERNAL_DECL void duk_push_lightfunc_name(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL void duk_push_lightfunc_tostring(duk_hthread *thr, duk_tval *tv);\n#if 0  /* not used yet */\nDUK_INTERNAL_DECL void duk_push_hnatfunc_name(duk_hthread *thr, duk_hnatfunc *h);\n#endif\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL_DECL duk_hbufobj *duk_push_bufobj_raw(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx);\n#endif\n\nDUK_INTERNAL_DECL void *duk_push_fixed_buffer_nozero(duk_hthread *thr, duk_size_t len);\nDUK_INTERNAL_DECL void *duk_push_fixed_buffer_zero(duk_hthread *thr, duk_size_t len);\n\nDUK_INTERNAL_DECL const char *duk_push_string_readable(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL const char *duk_push_string_tval_readable(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL const char *duk_push_string_tval_readable_error(duk_hthread *thr, duk_tval *tv);\n\n/* The duk_xxx_prop_stridx_short() variants expect their arguments to be short\n * enough to be packed into a single 32-bit integer argument.  Argument limits\n * vary per call; typically 16 bits are assigned to the signed value stack index\n * and the stridx.  In practice these work well for footprint with constant\n * arguments and such call sites are also easiest to verify to be correct.\n */\n\nDUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [] -> [val] */\nDUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_get_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t duk_get_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\nDUK_INTERNAL_DECL duk_bool_t duk_get_prop_stridx_boolean(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop);  /* [] -> [] */\n\nDUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop(duk_hthread *thr, duk_idx_t obj_idx);\nDUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);\nDUK_INTERNAL_DECL duk_bool_t duk_xget_owndataprop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_xget_owndataprop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t duk_xget_owndataprop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n\nDUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [val] -> [] */\nDUK_INTERNAL_DECL duk_bool_t duk_put_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_put_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x8000L && (duk_int_t) (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t duk_put_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n\nDUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [] -> [] */\n#if 0  /* Too few call sites to be useful. */\nDUK_INTERNAL_DECL duk_bool_t duk_del_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_del_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((obj_idx) >= -0x8000L && (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((stridx) >= 0 && (stridx) <= 0xffffL), \\\n\t duk_del_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n#endif\n#define duk_del_prop_stridx_short(thr,obj_idx,stridx) \\\n\tduk_del_prop_stridx((thr), (obj_idx), (stridx))\n\nDUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);     /* [] -> [] */\n#if 0  /* Too few call sites to be useful. */\nDUK_INTERNAL_DECL duk_bool_t duk_has_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_has_prop_stridx_short(thr,obj_idx,stridx) \\\n\t(DUK_ASSERT_EXPR((obj_idx) >= -0x8000L && (obj_idx) <= 0x7fffL), \\\n\t DUK_ASSERT_EXPR((stridx) >= 0 && (stridx) <= 0xffffL), \\\n\t duk_has_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 16) + ((duk_uint_t) (stridx))))\n#endif\n#define duk_has_prop_stridx_short(thr,obj_idx,stridx) \\\n\tduk_has_prop_stridx((thr), (obj_idx), (stridx))\n\nDUK_INTERNAL_DECL void duk_xdef_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t desc_flags);  /* [key val] -> [] */\n\nDUK_INTERNAL_DECL void duk_xdef_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags);  /* [val] -> [] */\n\n/* XXX: Because stridx and desc_flags have a limited range, this call could\n * always pack stridx and desc_flags into a single argument.\n */\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags);  /* [val] -> [] */\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args);\n#define duk_xdef_prop_stridx_short(thr,obj_idx,stridx,desc_flags) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (obj_idx) >= -0x80L && (duk_int_t) (obj_idx) <= 0x7fL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (stridx) >= 0 && (duk_int_t) (stridx) <= 0xffffL), \\\n\t DUK_ASSERT_EXPR((duk_int_t) (desc_flags) >= 0 && (duk_int_t) (desc_flags) <= 0xffL), \\\n\t duk_xdef_prop_stridx_short_raw((thr), (((duk_uint_t) (obj_idx)) << 24) + (((duk_uint_t) (stridx)) << 8) + (duk_uint_t) (desc_flags)))\n\n#define duk_xdef_prop_wec(thr,obj_idx) \\\n\tduk_xdef_prop((thr), (obj_idx), DUK_PROPDESC_FLAGS_WEC)\n#define duk_xdef_prop_index_wec(thr,obj_idx,arr_idx) \\\n\tduk_xdef_prop_index((thr), (obj_idx), (arr_idx), DUK_PROPDESC_FLAGS_WEC)\n#define duk_xdef_prop_stridx_wec(thr,obj_idx,stridx) \\\n\tduk_xdef_prop_stridx((thr), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC)\n#define duk_xdef_prop_stridx_short_wec(thr,obj_idx,stridx) \\\n\tduk_xdef_prop_stridx_short((thr), (obj_idx), (stridx), DUK_PROPDESC_FLAGS_WEC)\n\n#if 0  /*unused*/\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx_builtin(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags);  /* [] -> [] */\n#endif\n\nDUK_INTERNAL_DECL void duk_xdef_prop_stridx_thrower(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx);  /* [] -> [] */\n\nDUK_INTERNAL_DECL duk_bool_t duk_get_method_stridx(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t stridx);\n\nDUK_INTERNAL_DECL void duk_pack(duk_hthread *thr, duk_idx_t count);\nDUK_INTERNAL_DECL duk_idx_t duk_unpack_array_like(duk_hthread *thr, duk_idx_t idx);\n#if 0\nDUK_INTERNAL_DECL void duk_unpack(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL void duk_push_symbol_descriptive_string(duk_hthread *thr, duk_hstring *h);\n\nDUK_INTERNAL_DECL void duk_resolve_nonbound_function(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_idx_t duk_get_top_require_min(duk_hthread *thr, duk_idx_t min_top);\nDUK_INTERNAL_DECL duk_idx_t duk_get_top_index_unsafe(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count);\nDUK_INTERNAL_DECL void duk_pop_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_2_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_3_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count);\nDUK_INTERNAL_DECL void duk_pop_nodecref_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_2_nodecref_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_3_nodecref_unsafe(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_pop_undefined(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_compact_m1(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_seal_freeze_raw(duk_hthread *thr, duk_idx_t obj_idx, duk_bool_t is_freeze);\n\nDUK_INTERNAL_DECL void duk_insert_undefined(duk_hthread *thr, duk_idx_t idx);\nDUK_INTERNAL_DECL void duk_insert_undefined_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count);\n\nDUK_INTERNAL_DECL void duk_concat_2(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_int_t duk_pcall_method_flags(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags);\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL_DECL void duk_to_primitive_ordinary(duk_hthread *thr, duk_idx_t idx, duk_int_t hint);\n#endif\n\nDUK_INTERNAL_DECL void duk_clear_prototype(duk_hthread *thr, duk_idx_t idx);\n\n/* Raw internal valstack access macros: access is unsafe so call site\n * must have a guarantee that the index is valid.  When that is the case,\n * using these macro results in faster and smaller code than duk_get_tval().\n * Both 'ctx' and 'idx' are evaluted multiple times, but only for asserts.\n */\n#define DUK_ASSERT_VALID_NEGIDX(thr,idx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (idx) < 0), DUK_ASSERT_EXPR(duk_is_valid_index((thr), (idx))))\n#define DUK_ASSERT_VALID_POSIDX(thr,idx) \\\n\t(DUK_ASSERT_EXPR((duk_int_t) (idx) >= 0), DUK_ASSERT_EXPR(duk_is_valid_index((thr), (idx))))\n#define DUK_GET_TVAL_NEGIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_NEGIDX((thr),(idx)), ((duk_hthread *) (thr))->valstack_top + (idx))\n#define DUK_GET_TVAL_POSIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_POSIDX((thr),(idx)), ((duk_hthread *) (thr))->valstack_bottom + (idx))\n#define DUK_GET_HOBJECT_NEGIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_NEGIDX((thr),(idx)), DUK_TVAL_GET_OBJECT(((duk_hthread *) (thr))->valstack_top + (idx)))\n#define DUK_GET_HOBJECT_POSIDX(thr,idx) \\\n\t(DUK_ASSERT_VALID_POSIDX((thr),(idx)), DUK_TVAL_GET_OBJECT(((duk_hthread *) (thr))->valstack_bottom + (idx)))\n\n#define DUK_GET_THIS_TVAL_PTR(thr) \\\n\t(DUK_ASSERT_EXPR((thr)->valstack_bottom > (thr)->valstack), \\\n\t (thr)->valstack_bottom - 1)\n\nDUK_INTERNAL_DECL duk_double_t duk_time_get_ecmascript_time(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_double_t duk_time_get_ecmascript_time_nofrac(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr);\n\n#endif  /* DUK_API_INTERNAL_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_api_memory.c",
    "content": "/*\n *  Memory calls.\n */\n\n#include \"duk_internal.h\"\n\nDUK_EXTERNAL void *duk_alloc_raw(duk_hthread *thr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn DUK_ALLOC_RAW(thr->heap, size);\n}\n\nDUK_EXTERNAL void duk_free_raw(duk_hthread *thr, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_FREE_RAW(thr->heap, ptr);\n}\n\nDUK_EXTERNAL void *duk_realloc_raw(duk_hthread *thr, void *ptr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn DUK_REALLOC_RAW(thr->heap, ptr, size);\n}\n\nDUK_EXTERNAL void *duk_alloc(duk_hthread *thr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn DUK_ALLOC(thr->heap, size);\n}\n\nDUK_EXTERNAL void duk_free(duk_hthread *thr, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_FREE_CHECKED(thr, ptr);\n}\n\nDUK_EXTERNAL void *duk_realloc(duk_hthread *thr, void *ptr, duk_size_t size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/*\n\t *  Note: since this is an exposed API call, there should be\n\t *  no way a mark-and-sweep could have a side effect on the\n\t *  memory allocation behind 'ptr'; the pointer should never\n\t *  be something that Duktape wants to change.\n\t *\n\t *  Thus, no need to use DUK_REALLOC_INDIRECT (and we don't\n\t *  have the storage location here anyway).\n\t */\n\n\treturn DUK_REALLOC(thr->heap, ptr, size);\n}\n\nDUK_EXTERNAL void duk_get_memory_functions(duk_hthread *thr, duk_memory_functions *out_funcs) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(out_funcs != NULL);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\theap = thr->heap;\n\tout_funcs->alloc_func = heap->alloc_func;\n\tout_funcs->realloc_func = heap->realloc_func;\n\tout_funcs->free_func = heap->free_func;\n\tout_funcs->udata = heap->heap_udata;\n}\n\nDUK_EXTERNAL void duk_gc(duk_hthread *thr, duk_uint_t flags) {\n\tduk_heap *heap;\n\tduk_small_uint_t ms_flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep requested by application\"));\n\tDUK_ASSERT(DUK_GC_COMPACT == DUK_MS_FLAG_EMERGENCY);  /* Compact flag is 1:1 with emergency flag which forces compaction. */\n\tms_flags = (duk_small_uint_t) flags;\n\tduk_heap_mark_and_sweep(heap, ms_flags);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_api_object.c",
    "content": "/*\n *  Object handling: property access and other support functions.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Property handling\n *\n *  The API exposes only the most common property handling functions.\n *  The caller can invoke ECMAScript built-ins for full control (e.g.\n *  defineProperty, getOwnPropertyDescriptor).\n */\n\nDUK_EXTERNAL duk_bool_t duk_get_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property get right now.\n\t */\n\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, -1);\n\n\trc = duk_hobject_getprop(thr, tv_obj, tv_key);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\t/* a value is left on stack regardless of rc */\n\n\tduk_remove_m2(thr);  /* remove key */\n\tDUK_ASSERT(duk_is_undefined(thr, -1) || rc == 1);\n\treturn rc;  /* 1 if property found, 0 otherwise */\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk_get_prop(thr, obj_idx);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_get_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk_get_prop(thr, obj_idx);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_get_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_get_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_get_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_get_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n\nDUK_INTERNAL duk_bool_t duk_get_prop_stridx_boolean(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_bool_t *out_has_prop) {\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\trc = duk_get_prop_stridx(thr, obj_idx, stridx);\n\tif (out_has_prop) {\n\t\t*out_has_prop = rc;\n\t}\n\treturn duk_to_boolean_top_pop(thr);\n}\n\n/* This get variant is for internal use, it differs from standard\n * duk_get_prop() in that:\n *   - Object argument must be an object (primitive values not supported).\n *   - Key argument must be a string (no coercion).\n *   - Only own properties are checked (no inheritance).  Only \"entry part\"\n *     properties are checked (not array index properties).\n *   - Property must be a plain data property, not a getter.\n *   - Proxy traps are not triggered.\n */\nDUK_INTERNAL duk_bool_t duk_xget_owndataprop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_hobject *h_obj;\n\tduk_hstring *h_key;\n\tduk_tval *tv_val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property get right now.\n\t */\n\n\th_obj = duk_get_hobject(thr, obj_idx);\n\tif (h_obj == NULL) {\n\t\treturn 0;\n\t}\n\th_key = duk_require_hstring(thr, -1);\n\n\ttv_val = duk_hobject_find_entry_tval_ptr(thr->heap, h_obj, h_key);\n\tif (tv_val == NULL) {\n\t\treturn 0;\n\t}\n\n\tduk_push_tval(thr, tv_val);\n\tduk_remove_m2(thr);  /* remove key */\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_bool_t duk_xget_owndataprop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_xget_owndataprop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_xget_owndataprop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_xget_owndataprop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                   (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n\nDUK_LOCAL duk_bool_t duk__put_prop_shared(duk_hthread *thr, duk_idx_t obj_idx, duk_idx_t idx_key) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_tval *tv_val;\n\tduk_bool_t throw_flag;\n\tduk_bool_t rc;\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property put right now (putprop protects\n\t * against it internally).\n\t */\n\n\t/* Key and value indices are either (-2, -1) or (-1, -2).  Given idx_key,\n\t * idx_val is always (idx_key ^ 0x01).\n\t */\n\tDUK_ASSERT((idx_key == -2 && (idx_key ^ 1) == -1) ||\n\t           (idx_key == -1 && (idx_key ^ 1) == -2));\n\t/* XXX: Direct access; faster validation. */\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, idx_key);\n\ttv_val = duk_require_tval(thr, idx_key ^ 1);\n\tthrow_flag = duk_is_strict_call(thr);\n\n\trc = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, throw_flag);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\n\tduk_pop_2(thr);  /* remove key and value */\n\treturn rc;  /* 1 if property found, 0 otherwise */\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__put_prop_shared(thr, obj_idx, -2);\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\t/* Careful here and with other duk_put_prop_xxx() helpers: the\n\t * target object and the property value may be in the same value\n\t * stack slot (unusual, but still conceptually clear).\n\t */\n\tobj_idx = duk_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_put_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\n\nDUK_INTERNAL duk_bool_t duk_put_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk__put_prop_shared(thr, obj_idx, -1);\n}\n\nDUK_INTERNAL duk_bool_t duk_put_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_put_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t throw_flag;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property delete right now.\n\t */\n\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, -1);\n\tthrow_flag = duk_is_strict_call(thr);\n\n\trc = duk_hobject_delprop(thr, tv_obj, tv_key, throw_flag);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\n\tduk_pop(thr);  /* remove key */\n\treturn rc;\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk_del_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk_del_prop(thr, obj_idx);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_del_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk_del_prop(thr, obj_idx);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk_del_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_del_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk_del_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_del_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_del_prop(thr, obj_idx);\n}\n\n#if 0\nDUK_INTERNAL duk_bool_t duk_del_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_del_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_has_prop(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: copying tv_obj and tv_key to locals to shield against a valstack\n\t * resize is not necessary for a property existence check right now.\n\t */\n\n\ttv_obj = duk_require_tval(thr, obj_idx);\n\ttv_key = duk_require_tval(thr, -1);\n\n\trc = duk_hobject_hasprop(thr, tv_obj, tv_key);\n\tDUK_ASSERT(rc == 0 || rc == 1);\n\n\tduk_pop(thr);  /* remove key */\n\treturn rc;  /* 1 if property found, 0 otherwise */\n}\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_string(duk_hthread *thr, duk_idx_t obj_idx, const char *key) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_string(thr, key);\n\treturn duk_has_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_lstring(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_lstring(thr, key, key_len);\n\treturn duk_has_prop(thr, obj_idx);\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_has_prop_literal_raw(duk_hthread *thr, duk_idx_t obj_idx, const char *key, duk_size_t key_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_literal_raw(thr, key, key_len);\n\treturn duk_has_prop(thr, obj_idx);\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_uarridx(thr, arr_idx);\n\treturn duk_has_prop(thr, obj_idx);\n}\n\nDUK_EXTERNAL duk_bool_t duk_has_prop_heapptr(duk_hthread *thr, duk_idx_t obj_idx, void *ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\t(void) duk_push_heapptr(thr, ptr);  /* NULL -> 'undefined' */\n\treturn duk_has_prop(thr, obj_idx);\n}\n\nDUK_INTERNAL duk_bool_t duk_has_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n\treturn duk_has_prop(thr, obj_idx);\n}\n\n#if 0\nDUK_INTERNAL duk_bool_t duk_has_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\treturn duk_has_prop_stridx(thr, (duk_idx_t) (duk_int16_t) (packed_args >> 16),\n\t                                (duk_small_uint_t) (packed_args & 0xffffUL));\n}\n#endif\n\n/* Define own property without inheritance lookups and such.  This differs from\n * [[DefineOwnProperty]] because special behaviors (like Array 'length') are\n * not invoked by this method.  The caller must be careful to invoke any such\n * behaviors if necessary.\n */\nDUK_INTERNAL void duk_xdef_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\tkey = duk_to_property_key_hstring(thr, -2);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(duk_require_tval(thr, -1) != NULL);\n\n\tduk_hobject_define_property_internal(thr, obj, key, desc_flags);\n\n\tduk_pop(thr);  /* pop key */\n}\n\nDUK_INTERNAL void duk_xdef_prop_index(duk_hthread *thr, duk_idx_t obj_idx, duk_uarridx_t arr_idx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\n\tduk_hobject_define_property_internal_arridx(thr, obj, arr_idx, desc_flags);\n\t/* value popped by call */\n}\n\nDUK_INTERNAL void duk_xdef_prop_stridx(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\tkey = DUK_HTHREAD_GET_STRING(thr, stridx);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(duk_require_tval(thr, -1) != NULL);\n\n\tduk_hobject_define_property_internal(thr, obj, key, desc_flags);\n\t/* value popped by call */\n}\n\nDUK_INTERNAL void duk_xdef_prop_stridx_short_raw(duk_hthread *thr, duk_uint_t packed_args) {\n\tduk_xdef_prop_stridx(thr, (duk_idx_t) (duk_int8_t) (packed_args >> 24),\n\t                          (duk_small_uint_t) (packed_args >> 8) & 0xffffUL,\n\t                          (duk_small_uint_t) (packed_args & 0xffL));\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL void duk_xdef_prop_stridx_builtin(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx, duk_small_int_t builtin_idx, duk_small_uint_t desc_flags) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\tDUK_ASSERT_BIDX_VALID(builtin_idx);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\tDUK_ASSERT(obj != NULL);\n\tkey = DUK_HTHREAD_GET_STRING(thr, stridx);\n\tDUK_ASSERT(key != NULL);\n\n\tduk_push_hobject(thr, thr->builtins[builtin_idx]);\n\tduk_hobject_define_property_internal(thr, obj, key, desc_flags);\n\t/* value popped by call */\n}\n#endif\n\n/* This is a rare property helper; it sets the global thrower (E5 Section 13.2.3)\n * setter/getter into an object property.  This is needed by the 'arguments'\n * object creation code, function instance creation code, and Function.prototype.bind().\n */\n\nDUK_INTERNAL void duk_xdef_prop_stridx_thrower(duk_hthread *thr, duk_idx_t obj_idx, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tduk_push_hstring_stridx(thr, stridx);\n\tduk_push_hobject_bidx(thr, DUK_BIDX_TYPE_ERROR_THROWER);\n\tduk_dup_top(thr);\n\tduk_def_prop(thr, obj_idx, DUK_DEFPROP_HAVE_SETTER | DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_FORCE);  /* attributes always 0 */\n}\n\n/* Object.getOwnPropertyDescriptor() equivalent C binding. */\nDUK_EXTERNAL void duk_get_prop_desc(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(flags);  /* no flags defined yet */\n\n\tduk_hobject_object_get_own_property_descriptor(thr, obj_idx);  /* [ ... key ] -> [ ... desc ] */\n}\n\n/* Object.defineProperty() equivalent C binding. */\nDUK_EXTERNAL void duk_def_prop(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t flags) {\n\tduk_idx_t idx_base;\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_idx_t idx_value;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\tduk_uint_t is_data_desc;\n\tduk_uint_t is_acc_desc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, obj_idx);\n\n\tis_data_desc = flags & (DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE);\n\tis_acc_desc = flags & (DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER);\n\tif (is_data_desc && is_acc_desc) {\n\t\t/* \"Have\" flags must not be conflicting so that they would\n\t\t * apply to both a plain property and an accessor at the same\n\t\t * time.\n\t\t */\n\t\tgoto fail_invalid_desc;\n\t}\n\n\tidx_base = duk_get_top_index(thr);\n\tif (flags & DUK_DEFPROP_HAVE_SETTER) {\n\t\tduk_require_type_mask(thr, idx_base, DUK_TYPE_MASK_UNDEFINED |\n\t\t                                     DUK_TYPE_MASK_OBJECT |\n\t\t                                     DUK_TYPE_MASK_LIGHTFUNC);\n\t\tset = duk_get_hobject_promote_lfunc(thr, idx_base);\n\t\tif (set != NULL && !DUK_HOBJECT_IS_CALLABLE(set)) {\n\t\t\tgoto fail_not_callable;\n\t\t}\n\t\tidx_base--;\n\t} else {\n\t\tset = NULL;\n\t}\n\tif (flags & DUK_DEFPROP_HAVE_GETTER) {\n\t\tduk_require_type_mask(thr, idx_base, DUK_TYPE_MASK_UNDEFINED |\n\t\t                                     DUK_TYPE_MASK_OBJECT |\n\t\t                                     DUK_TYPE_MASK_LIGHTFUNC);\n\t\tget = duk_get_hobject_promote_lfunc(thr, idx_base);\n\t\tif (get != NULL && !DUK_HOBJECT_IS_CALLABLE(get)) {\n\t\t\tgoto fail_not_callable;\n\t\t}\n\t\tidx_base--;\n\t} else {\n\t\tget = NULL;\n\t}\n\tif (flags & DUK_DEFPROP_HAVE_VALUE) {\n\t\tidx_value = idx_base;\n\t\tidx_base--;\n\t} else {\n\t\tidx_value = (duk_idx_t) -1;\n\t}\n\tkey = duk_to_property_key_hstring(thr, idx_base);\n\tDUK_ASSERT(key != NULL);\n\n\tduk_require_valid_index(thr, idx_base);\n\n\tduk_hobject_define_property_helper(thr,\n\t                                   flags /*defprop_flags*/,\n\t                                   obj,\n\t                                   key,\n\t                                   idx_value,\n\t                                   get,\n\t                                   set,\n\t                                   1 /*throw_flag*/);\n\n\t/* Clean up stack */\n\n\tduk_set_top(thr, idx_base);\n\n\t/* [ ... obj ... ] */\n\n\treturn;\n\n fail_invalid_desc:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_DESCRIPTOR);\n\tDUK_WO_NORETURN(return;);\n\n fail_not_callable:\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Object related\n */\n\nDUK_EXTERNAL void duk_compact(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, obj_idx);\n\tif (obj) {\n\t\t/* Note: this may fail, caller should protect the call if necessary */\n\t\tduk_hobject_compact_props(thr, obj);\n\t}\n}\n\nDUK_INTERNAL void duk_compact_m1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_compact(thr, -1);\n}\n\n/* XXX: the duk_hobject_enum.c stack APIs should be reworked */\n\nDUK_EXTERNAL void duk_enum(duk_hthread *thr, duk_idx_t obj_idx, duk_uint_t enum_flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_dup(thr, obj_idx);\n\tduk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tduk_hobject_enumerator_create(thr, enum_flags);   /* [target] -> [enum] */\n}\n\nDUK_EXTERNAL duk_bool_t duk_next(duk_hthread *thr, duk_idx_t enum_index, duk_bool_t get_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_require_hobject(thr, enum_index);\n\tduk_dup(thr, enum_index);\n\treturn duk_hobject_enumerator_next(thr, get_value);\n}\n\nDUK_INTERNAL void duk_seal_freeze_raw(duk_hthread *thr, duk_idx_t obj_idx, duk_bool_t is_freeze) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, obj_idx);\n\tDUK_ASSERT(tv != NULL);\n\n\t/* Seal/freeze are quite rare in practice so it'd be nice to get the\n\t * correct behavior simply via automatic promotion (at the cost of some\n\t * memory churn).  However, the promoted objects don't behave the same,\n\t * e.g. promoted lightfuncs are extensible.\n\t */\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_BUFFER:\n\t\t/* Plain buffer: already sealed, but not frozen (and can't be frozen\n\t\t * because index properties can't be made non-writable.\n\t\t */\n\t\tif (is_freeze) {\n\t\t\tgoto fail_cannot_freeze;\n\t\t}\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\t/* Lightfunc: already sealed and frozen, success. */\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (is_freeze && DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\t/* Buffer objects cannot be frozen because there's no internal\n\t\t\t * support for making virtual array indices non-writable.\n\t\t\t */\n\t\t\tDUK_DD(DUK_DDPRINT(\"cannot freeze a buffer object\"));\n\t\t\tgoto fail_cannot_freeze;\n\t\t}\n\t\tduk_hobject_object_seal_freeze_helper(thr, h, is_freeze);\n\n\t\t/* Sealed and frozen objects cannot gain any more properties,\n\t\t * so this is a good time to compact them.\n\t\t */\n\t\tduk_hobject_compact_props(thr, h);\n\t\tbreak;\n\tdefault:\n\t\t/* ES2015 Sections 19.1.2.5, 19.1.2.17 */\n\t\tbreak;\n\t}\n\treturn;\n\n fail_cannot_freeze:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);  /* XXX: proper error message */\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_seal(duk_hthread *thr, duk_idx_t obj_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_seal_freeze_raw(thr, obj_idx, 0 /*is_freeze*/);\n}\n\nDUK_EXTERNAL void duk_freeze(duk_hthread *thr, duk_idx_t obj_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_seal_freeze_raw(thr, obj_idx, 1 /*is_freeze*/);\n}\n\n/*\n *  Helpers for writing multiple properties\n */\n\nDUK_EXTERNAL void duk_put_function_list(duk_hthread *thr, duk_idx_t obj_idx, const duk_function_list_entry *funcs) {\n\tconst duk_function_list_entry *ent = funcs;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tif (ent != NULL) {\n\t\twhile (ent->key != NULL) {\n\t\t\tduk_push_c_function(thr, ent->value, ent->nargs);\n\t\t\tduk_put_prop_string(thr, obj_idx, ent->key);\n\t\t\tent++;\n\t\t}\n\t}\n}\n\nDUK_EXTERNAL void duk_put_number_list(duk_hthread *thr, duk_idx_t obj_idx, const duk_number_list_entry *numbers) {\n\tconst duk_number_list_entry *ent = numbers;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj_idx = duk_require_normalize_index(thr, obj_idx);\n\tif (ent != NULL) {\n\t\twhile (ent->key != NULL) {\n\t\t\ttv = thr->valstack_top++;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));  /* value stack init policy */\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv, ent->value);  /* no need for decref/incref */\n\t\t\tduk_put_prop_string(thr, obj_idx, ent->key);\n\t\t\tent++;\n\t\t}\n\t}\n}\n\n/*\n *  Shortcut for accessing global object properties\n */\n\nDUK_EXTERNAL duk_bool_t duk_get_global_string(duk_hthread *thr, const char *key) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_string(thr, -1, key);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_global_lstring(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_lstring(thr, -1, key, key_len);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_get_global_literal_raw(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_literal_raw(thr, -1, key, key_len);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_get_global_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tret = duk_get_prop_heapptr(thr, -1, ptr);\n\tduk_remove_m2(thr);\n\treturn ret;\n}\n\n\nDUK_EXTERNAL duk_bool_t duk_put_global_string(duk_hthread *thr, const char *key) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_string(thr, -2, key);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_bool_t duk_put_global_lstring(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_lstring(thr, -2, key, key_len);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL duk_bool_t duk_put_global_literal_raw(duk_hthread *thr, const char *key, duk_size_t key_len) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\tDUK_ASSERT(key[key_len] == (char) 0);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_literal_raw(thr, -2, key, key_len);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n#endif\n\nDUK_EXTERNAL duk_bool_t duk_put_global_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\n\t/* XXX: direct implementation */\n\n\tduk_push_hobject(thr, thr->builtins[DUK_BIDX_GLOBAL]);\n\tduk_insert(thr, -2);\n\tret = duk_put_prop_heapptr(thr, -2, ptr);  /* [ ... global val ] -> [ ... global ] */\n\tduk_pop(thr);\n\treturn ret;\n}\n\n/*\n *  ES2015 GetMethod()\n */\n\nDUK_INTERNAL duk_bool_t duk_get_method_stridx(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t stridx) {\n\t(void) duk_get_prop_stridx(thr, idx, stridx);\n\tif (duk_is_null_or_undefined(thr, -1)) {\n\t\tduk_pop_nodecref_unsafe(thr);\n\t\treturn 0;\n\t}\n\tif (!duk_is_callable(thr, -1)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 1;\n}\n\n/*\n *  Object prototype\n */\n\nDUK_EXTERNAL void duk_get_prototype(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\n\t/* XXX: shared helper for duk_push_hobject_or_undefined()? */\n\tproto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, obj);\n\tif (proto) {\n\t\tduk_push_hobject(thr, proto);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n}\n\nDUK_EXTERNAL void duk_set_prototype(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\tduk_require_type_mask(thr, -1, DUK_TYPE_MASK_UNDEFINED |\n\t                               DUK_TYPE_MASK_OBJECT);\n\tproto = duk_get_hobject(thr, -1);\n\t/* proto can also be NULL here (allowed explicitly) */\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);  /* XXX: \"read only object\"? */\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, obj, proto);\n\n\tduk_pop(thr);\n}\n\nDUK_INTERNAL void duk_clear_prototype(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);  /* XXX: \"read only object\"? */\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, obj, NULL);\n}\n\nDUK_INTERNAL duk_bool_t duk_is_bare_object(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_require_hobject(thr, idx);\n\tDUK_ASSERT(obj != NULL);\n\n\tproto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, obj);\n\treturn (proto == NULL);\n}\n\n/*\n *  Object finalizer\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n/* XXX: these could be implemented as macros calling an internal function\n * directly.\n * XXX: same issue as with Duktape.fin: there's no way to delete the property\n * now (just set it to undefined).\n */\nDUK_EXTERNAL void duk_get_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* This get intentionally walks the inheritance chain at present,\n\t * which matches how the effective finalizer property is also\n\t * looked up in GC.\n\t */\n\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_INT_FINALIZER);\n}\n\nDUK_EXTERNAL void duk_set_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\tduk_bool_t callable;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hobject(thr, idx);  /* Get before 'put' so that 'idx' is correct. */\n\tcallable = duk_is_callable(thr, -1);\n\n\t/* At present finalizer is stored as a hidden Symbol, with normal\n\t * inheritance and access control.  As a result, finalizer cannot\n\t * currently be set on a non-extensible (sealed or frozen) object.\n\t * It might be useful to allow it.\n\t */\n\tduk_put_prop_stridx(thr, idx, DUK_STRIDX_INT_FINALIZER);\n\n\t/* In addition to setting the finalizer property, keep a \"have\n\t * finalizer\" flag in duk_hobject in sync so that refzero can do\n\t * a very quick finalizer check by walking the prototype chain\n\t * and checking the flag alone.  (Note that this means that just\n\t * setting _Finalizer on an object won't affect finalizer checks.)\n\t *\n\t * NOTE: if the argument is a Proxy object, this flag will be set\n\t * on the Proxy, not the target.  As a result, the target won't get\n\t * a finalizer flag and the Proxy also won't be finalized as there's\n\t * an explicit Proxy check in finalization now.\n\t */\n\tif (callable) {\n\t\tDUK_HOBJECT_SET_HAVE_FINALIZER(h);\n\t} else {\n\t\tDUK_HOBJECT_CLEAR_HAVE_FINALIZER(h);\n\t}\n}\n#else  /* DUK_USE_FINALIZER_SUPPORT */\nDUK_EXTERNAL void duk_get_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_set_finalizer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_api_random.c",
    "content": "/*\n *  Random numbers\n */\n\n#include \"duk_internal.h\"\n\nDUK_EXTERNAL duk_double_t duk_random(duk_hthread *thr) {\n\treturn (duk_double_t) DUK_UTIL_GET_RANDOM_DOUBLE(thr);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_api_stack.c",
    "content": "/*\n *  API calls related to general value stack manipulation: resizing the value\n *  stack, pushing and popping values, type checking and reading values,\n *  coercing values, etc.\n *\n *  Also contains internal functions (such as duk_get_tval()), defined\n *  in duk_api_internal.h, with semantics similar to the public API.\n */\n\n/* XXX: repetition of stack pre-checks -> helper or macro or inline */\n/* XXX: shared api error strings, and perhaps even throw code for rare cases? */\n\n#include \"duk_internal.h\"\n\n/*\n *  Forward declarations\n */\n\nDUK_LOCAL_DECL duk_idx_t duk__push_c_function_raw(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_uint_t flags, duk_small_uint_t proto_bidx);\n\n/*\n *  Global state for working around missing variadic macros\n */\n\n#if !defined(DUK_USE_VARIADIC_MACROS)\nDUK_EXTERNAL const char *duk_api_global_filename = NULL;\nDUK_EXTERNAL duk_int_t duk_api_global_line = 0;\n#endif\n\n/*\n *  Misc helpers\n */\n\nDUK_LOCAL const char * const duk__symbol_type_strings[4] = {\n\t\"hidden\", \"global\", \"local\", \"wellknown\"\n};\n\n#if !defined(DUK_USE_PACKED_TVAL)\nDUK_LOCAL const duk_uint_t duk__type_from_tag[] = {\n\tDUK_TYPE_NUMBER,\n\tDUK_TYPE_NUMBER,  /* fastint */\n\tDUK_TYPE_UNDEFINED,\n\tDUK_TYPE_NULL,\n\tDUK_TYPE_BOOLEAN,\n\tDUK_TYPE_POINTER,\n\tDUK_TYPE_LIGHTFUNC,\n\tDUK_TYPE_NONE,\n\tDUK_TYPE_STRING,\n\tDUK_TYPE_OBJECT,\n\tDUK_TYPE_BUFFER,\n};\nDUK_LOCAL const duk_uint_t duk__type_mask_from_tag[] = {\n\tDUK_TYPE_MASK_NUMBER,\n\tDUK_TYPE_MASK_NUMBER,  /* fastint */\n\tDUK_TYPE_MASK_UNDEFINED,\n\tDUK_TYPE_MASK_NULL,\n\tDUK_TYPE_MASK_BOOLEAN,\n\tDUK_TYPE_MASK_POINTER,\n\tDUK_TYPE_MASK_LIGHTFUNC,\n\tDUK_TYPE_MASK_NONE,\n\tDUK_TYPE_MASK_STRING,\n\tDUK_TYPE_MASK_OBJECT,\n\tDUK_TYPE_MASK_BUFFER,\n};\n#endif  /* !DUK_USE_PACKED_TVAL */\n\n/* Assert that there's room for one value. */\n#define DUK__ASSERT_SPACE() do { \\\n\t\tDUK_ASSERT(!(thr->valstack_top >= thr->valstack_end)); \\\n\t} while (0)\n\n/* Check that there's room to push one value. */\n#if defined(DUK_USE_VALSTACK_UNSAFE)\n/* Faster but value stack overruns are memory unsafe. */\n#define DUK__CHECK_SPACE() DUK__ASSERT_SPACE()\n#else\n#define DUK__CHECK_SPACE() do { \\\n\t\tif (DUK_UNLIKELY(thr->valstack_top >= thr->valstack_end)) { \\\n\t\t\tDUK_ERROR_RANGE_PUSH_BEYOND(thr); \\\n\t\t} \\\n\t} while (0)\n#endif\n\nDUK_LOCAL duk_small_uint_t duk__get_symbol_type(duk_hstring *h) {\n\tconst duk_uint8_t *data;\n\tduk_size_t len;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HSTRING_HAS_SYMBOL(h));\n\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(h) >= 1);  /* always true, symbol prefix */\n\n\tdata = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\tDUK_ASSERT(len >= 1);\n\n\t/* XXX: differentiate between 0x82 and 0xff (hidden vs. internal?)? */\n\n\tif (data[0] == 0xffU) {\n\t\treturn DUK_SYMBOL_TYPE_HIDDEN;\n\t} else if (data[0] == 0x82U) {\n\t\treturn DUK_SYMBOL_TYPE_HIDDEN;\n\t} else if (data[0] == 0x80U) {\n\t\treturn DUK_SYMBOL_TYPE_GLOBAL;\n\t} else if (data[len - 1] != 0xffU) {\n\t\treturn DUK_SYMBOL_TYPE_LOCAL;\n\t} else {\n\t\treturn DUK_SYMBOL_TYPE_WELLKNOWN;\n\t}\n}\n\nDUK_LOCAL const char *duk__get_symbol_type_string(duk_hstring *h) {\n\tduk_small_uint_t idx;\n\tidx = duk__get_symbol_type(h);\n\tDUK_ASSERT(idx < sizeof(duk__symbol_type_strings));\n\treturn duk__symbol_type_strings[idx];\n}\n\nDUK_LOCAL_DECL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t tag);\n\nDUK_LOCAL duk_int_t duk__api_coerce_d2i(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value, duk_bool_t require) {\n\tduk_tval *tv;\n\tduk_small_int_t c;\n\tduk_double_t d;\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\t/*\n\t *  Special cases like NaN and +/- Infinity are handled explicitly\n\t *  because a plain C coercion from double to int handles these cases\n\t *  in undesirable ways.  For instance, NaN may coerce to INT_MIN\n\t *  (not zero), and INT_MAX + 1 may coerce to INT_MIN (not INT_MAX).\n\t *\n\t *  This double-to-int coercion differs from ToInteger() because it\n\t *  has a finite range (ToInteger() allows e.g. +/- Infinity).  It\n\t *  also differs from ToInt32() because the INT_MIN/INT_MAX clamping\n\t *  depends on the size of the int type on the platform.  In particular,\n\t *  on platforms with a 64-bit int type, the full range is allowed.\n\t */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tduk_int64_t t = DUK_TVAL_GET_FASTINT(tv);\n#if (DUK_INT_MAX <= 0x7fffffffL)\n\t\t/* Clamping only necessary for 32-bit ints. */\n\t\tif (t < DUK_INT_MIN) {\n\t\t\tt = DUK_INT_MIN;\n\t\t} else if (t > DUK_INT_MAX) {\n\t\t\tt = DUK_INT_MAX;\n\t\t}\n#endif\n\t\treturn (duk_int_t) t;\n\t}\n#endif\n\n\tif (DUK_TVAL_IS_NUMBER(tv)) {\n\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\t\tif (c == DUK_FP_NAN) {\n\t\t\treturn 0;\n\t\t} else if (d < (duk_double_t) DUK_INT_MIN) {\n\t\t\t/* covers -Infinity */\n\t\t\treturn DUK_INT_MIN;\n\t\t} else if (d > (duk_double_t) DUK_INT_MAX) {\n\t\t\t/* covers +Infinity */\n\t\t\treturn DUK_INT_MAX;\n\t\t} else {\n\t\t\t/* coerce towards zero */\n\t\t\treturn (duk_int_t) d;\n\t\t}\n\t}\n\n\tif (require) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"number\", DUK_STR_NOT_NUMBER);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\treturn def_value;\n}\n\nDUK_LOCAL duk_uint_t duk__api_coerce_d2ui(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value, duk_bool_t require) {\n\tduk_tval *tv;\n\tduk_small_int_t c;\n\tduk_double_t d;\n\n\t/* Same as above but for unsigned int range. */\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tduk_int64_t t = DUK_TVAL_GET_FASTINT(tv);\n\t\tif (t < 0) {\n\t\t\tt = 0;\n\t\t}\n#if (DUK_UINT_MAX <= 0xffffffffUL)\n\t\t/* Clamping only necessary for 32-bit ints. */\n\t\telse if (t > DUK_UINT_MAX) {\n\t\t\tt = DUK_UINT_MAX;\n\t\t}\n#endif\n\t\treturn (duk_uint_t) t;\n\t}\n#endif\n\n\tif (DUK_TVAL_IS_NUMBER(tv)) {\n\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\t\tif (c == DUK_FP_NAN) {\n\t\t\treturn 0;\n\t\t} else if (d < 0.0) {\n\t\t\t/* covers -Infinity */\n\t\t\treturn (duk_uint_t) 0;\n\t\t} else if (d > (duk_double_t) DUK_UINT_MAX) {\n\t\t\t/* covers +Infinity */\n\t\t\treturn (duk_uint_t) DUK_UINT_MAX;\n\t\t} else {\n\t\t\t/* coerce towards zero */\n\t\t\treturn (duk_uint_t) d;\n\t\t}\n\t}\n\n\tif (require) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"number\", DUK_STR_NOT_NUMBER);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\treturn def_value;\n}\n\n/*\n *  Stack index validation/normalization and getting a stack duk_tval ptr.\n *\n *  These are called by many API entrypoints so the implementations must be\n *  fast and \"inlined\".\n *\n *  There's some repetition because of this; keep the functions in sync.\n */\n\nDUK_EXTERNAL duk_idx_t duk_normalize_index(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\t/* Care must be taken to avoid pointer wrapping in the index\n\t * validation.  For instance, on a 32-bit platform with 8-byte\n\t * duk_tval the index 0x20000000UL would wrap the memory space\n\t * once.\n\t */\n\n\t/* Assume value stack sizes (in elements) fits into duk_idx_t. */\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\t/* since index non-negative */\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn (duk_idx_t) uidx;\n\t}\n\treturn DUK_INVALID_INDEX;\n}\n\nDUK_EXTERNAL duk_idx_t duk_require_normalize_index(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn (duk_idx_t) uidx;\n\t}\n\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_tval *duk_get_tval(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn thr->valstack_bottom + uidx;\n\t}\n\treturn NULL;\n}\n\n/* Variant of duk_get_tval() which is guaranteed to return a valid duk_tval\n * pointer.  When duk_get_tval() would return NULL, this variant returns a\n * pointer to a duk_tval with tag DUK_TAG_UNUSED.  This allows the call site\n * to avoid an unnecessary NULL check which sometimes leads to better code.\n * The return duk_tval is read only (at least for the UNUSED value).\n */\nDUK_LOCAL const duk_tval_unused duk__const_tval_unused = DUK_TVAL_UNUSED_INITIALIZER();\n\nDUK_INTERNAL duk_tval *duk_get_tval_or_unused(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval(thr, idx);\n\tif (tv != NULL) {\n\t\treturn tv;\n\t}\n\treturn (duk_tval *) DUK_LOSE_CONST(&duk__const_tval_unused);\n}\n\nDUK_INTERNAL duk_tval *duk_require_tval(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t uidx;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT_DISABLE(vs_size >= 0);  /* unsigned */\n\n\t/* Use unsigned arithmetic to optimize comparison. */\n\tif (idx < 0) {\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\tDUK_ASSERT(idx != DUK_INVALID_INDEX);\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\n\tif (DUK_LIKELY(uidx < vs_size)) {\n\t\treturn thr->valstack_bottom + uidx;\n\t}\n\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/* Non-critical. */\nDUK_EXTERNAL duk_bool_t duk_is_valid_index(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\treturn (duk_normalize_index(thr, idx) >= 0);\n}\n\n/* Non-critical. */\nDUK_EXTERNAL void duk_require_valid_index(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tif (DUK_UNLIKELY(duk_normalize_index(thr, idx) < 0)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\n/*\n *  Value stack top handling\n */\n\nDUK_EXTERNAL duk_idx_t duk_get_top(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n}\n\n/* Internal helper to get current top but to require a minimum top value\n * (TypeError if not met).\n */\nDUK_INTERNAL duk_idx_t duk_get_top_require_min(duk_hthread *thr, duk_idx_t min_top) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tif (DUK_UNLIKELY(ret < min_top)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn ret;\n}\n\n/* Set stack top within currently allocated range, but don't reallocate.\n * This is performance critical especially for call handling, so whenever\n * changing, profile and look at generated code.\n */\nDUK_EXTERNAL void duk_set_top(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t vs_size;\n\tduk_uidx_t vs_limit;\n\tduk_uidx_t uidx;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_INVALID_INDEX < 0);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_bottom);\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\tvs_limit = (duk_uidx_t) (thr->valstack_end - thr->valstack_bottom);\n\n\tif (idx < 0) {\n\t\t/* Negative indices are always within allocated stack but\n\t\t * must not go below zero index.\n\t\t */\n\t\tuidx = vs_size + (duk_uidx_t) idx;\n\t} else {\n\t\t/* Positive index can be higher than valstack top but must\n\t\t * not go above allocated stack (equality is OK).\n\t\t */\n\t\tuidx = (duk_uidx_t) idx;\n\t}\n\n\t/* DUK_INVALID_INDEX won't be accepted as a valid index. */\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_size);\n\tDUK_ASSERT(vs_size + (duk_uidx_t) DUK_INVALID_INDEX >= vs_limit);\n\n#if defined(DUK_USE_VALSTACK_UNSAFE)\n\tDUK_ASSERT(uidx <= vs_limit);\n\tDUK_UNREF(vs_limit);\n#else\n\tif (DUK_UNLIKELY(uidx > vs_limit)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, idx);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\tDUK_ASSERT(uidx <= vs_limit);\n\n\t/* Handle change in value stack top.  Respect value stack\n\t * initialization policy: 'undefined' above top.  Note that\n\t * DECREF may cause a side effect that reallocates valstack,\n\t * so must relookup after DECREF.\n\t */\n\n\tif (uidx >= vs_size) {\n\t\t/* Stack size increases or stays the same. */\n#if defined(DUK_USE_ASSERTIONS)\n\t\tduk_uidx_t count;\n\n\t\tcount = uidx - vs_size;\n\t\twhile (count != 0) {\n\t\t\tcount--;\n\t\t\ttv = thr->valstack_top + count;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\t}\n#endif\n\t\tthr->valstack_top = thr->valstack_bottom + uidx;\n\t} else {\n\t\t/* Stack size decreases. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\tDUK_ASSERT(count > 0);\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);  /* Because count > 0. */\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n\t\tDUK_REFZERO_CHECK_FAST(thr);\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\t}\n}\n\n/* Internal variant with a non-negative index and no runtime size checks. */\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_set_top(thr, idx);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_set_top_unsafe(duk_hthread *thr, duk_idx_t idx) {\n\tduk_uidx_t uidx;\n\tduk_uidx_t vs_size;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_bottom);\n\tDUK_ASSERT(idx >= 0);\n\tDUK_ASSERT(idx <= (duk_idx_t) (thr->valstack_end - thr->valstack_bottom));\n\n\t/* XXX: byte arithmetic */\n\tuidx = (duk_uidx_t) idx;\n\tvs_size = (duk_uidx_t) (thr->valstack_top - thr->valstack_bottom);\n\n\tif (uidx >= vs_size) {\n\t\t/* Stack size increases or stays the same. */\n#if defined(DUK_USE_ASSERTIONS)\n\t\tduk_uidx_t count;\n\n\t\tcount = uidx - vs_size;\n\t\twhile (count != 0) {\n\t\t\tcount--;\n\t\t\ttv = thr->valstack_top + count;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\t}\n#endif\n\t\tthr->valstack_top = thr->valstack_bottom + uidx;\n\t} else {\n\t\t/* Stack size decreases. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\tDUK_ASSERT(count > 0);\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);  /* Because count > 0. */\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n\t\tDUK_REFZERO_CHECK_FAST(thr);\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\t\tduk_uidx_t count;\n\t\tduk_tval *tv_end;\n\n\t\tcount = vs_size - uidx;\n\t\ttv = thr->valstack_top;\n\t\ttv_end = tv - count;\n\t\tDUK_ASSERT(tv > tv_end);\n\t\tdo {\n\t\t\ttv--;\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t\t} while (tv != tv_end);\n\t\tthr->valstack_top = tv_end;\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\t}\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/* Internal helper: set top to 'top', and set [idx_wipe_start,top[ to\n * 'undefined' (doing nothing if idx_wipe_start == top).  Indices are\n * positive and within value stack reserve.  This is used by call handling.\n */\nDUK_INTERNAL void duk_set_top_and_wipe(duk_hthread *thr, duk_idx_t top, duk_idx_t idx_wipe_start) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(top >= 0);\n\tDUK_ASSERT(idx_wipe_start >= 0);\n\tDUK_ASSERT(idx_wipe_start <= top);\n\tDUK_ASSERT(thr->valstack_bottom + top <= thr->valstack_end);\n\tDUK_ASSERT(thr->valstack_bottom + idx_wipe_start <= thr->valstack_end);\n\n\tduk_set_top_unsafe(thr, idx_wipe_start);\n\tduk_set_top_unsafe(thr, top);\n}\n\nDUK_EXTERNAL duk_idx_t duk_get_top_index(duk_hthread *thr) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;\n\tif (DUK_UNLIKELY(ret < 0)) {\n\t\t/* Return invalid index; if caller uses this without checking\n\t\t * in another API call, the index won't map to a valid stack\n\t\t * entry.\n\t\t */\n\t\treturn DUK_INVALID_INDEX;\n\t}\n\treturn ret;\n}\n\n/* Internal variant: call assumes there is at least one element on the value\n * stack frame; this is only asserted for.\n */\nDUK_INTERNAL duk_idx_t duk_get_top_index_unsafe(duk_hthread *thr) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_idx_t duk_require_top_index(duk_hthread *thr) {\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom) - 1;\n\tif (DUK_UNLIKELY(ret < 0)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, -1);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn ret;\n}\n\n/*\n *  Value stack resizing.\n *\n *  This resizing happens above the current \"top\": the value stack can be\n *  grown or shrunk, but the \"top\" is not affected.  The value stack cannot\n *  be resized to a size below the current reserve.\n *\n *  The low level reallocation primitive must carefully recompute all value\n *  stack pointers, and must also work if ALL pointers are NULL.  The resize\n *  is quite tricky because the valstack realloc may cause a mark-and-sweep,\n *  which may run finalizers.  Running finalizers may resize the valstack\n *  recursively (the same value stack we're working on).  So, after realloc\n *  returns, we know that the valstack bottom, top, and reserve should still\n *  be the same (there should not be live values above the \"top\"), but its\n *  underlying size, alloc_end, and base pointer may have changed.\n *\n *  'new_size' is known to be <= DUK_USE_VALSTACK_LIMIT, which ensures that\n *  size_t and pointer arithmetic won't wrap in duk__resize_valstack().\n */\n\n/* Low level valstack resize primitive, used for both grow and shrink.  All\n * adjustments for slack etc have already been done.  Doesn't throw but does\n * have allocation side effects.\n */\nDUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__resize_valstack(duk_hthread *thr, duk_size_t new_size) {\n\tduk_tval *pre_valstack;\n\tduk_tval *pre_bottom;\n\tduk_tval *pre_top;\n\tduk_tval *pre_end;\n\tduk_tval *pre_alloc_end;\n\tduk_ptrdiff_t ptr_diff;\n\tduk_tval *new_valstack;\n\tduk_size_t new_alloc_size;\n\tduk_tval *tv_prev_alloc_end;\n\tduk_tval *p;\n\n\tDUK_HTHREAD_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack) <= new_size);  /* can't resize below 'top' */\n\tDUK_ASSERT(new_size <= DUK_USE_VALSTACK_LIMIT);  /* valstack limit caller has check, prevents wrapping */\n\tDUK_ASSERT(new_size <= DUK_SIZE_MAX / sizeof(duk_tval));  /* specific assert for wrapping */\n\n\t/* Pre-realloc pointer copies for asserts and debug logs. */\n\tpre_valstack = thr->valstack;\n\tpre_bottom = thr->valstack_bottom;\n\tpre_top = thr->valstack_top;\n\tpre_end = thr->valstack_end;\n\tpre_alloc_end = thr->valstack_alloc_end;\n\n\tDUK_UNREF(pre_valstack);\n\tDUK_UNREF(pre_bottom);\n\tDUK_UNREF(pre_top);\n\tDUK_UNREF(pre_end);\n\tDUK_UNREF(pre_alloc_end);\n\n\t/* If finalizer torture enabled, force base pointer change every time\n\t * when it would be allowed.\n\t */\n#if defined(DUK_USE_FINALIZER_TORTURE)\n\tif (thr->heap->pf_prevent_count == 0) {\n\t\tduk_hthread_valstack_torture_realloc(thr);\n\t}\n#endif\n\n\t/* Allocate a new valstack using DUK_REALLOC_DIRECT() to deal with\n\t * a side effect changing the base pointer.\n\t */\n\tnew_alloc_size = sizeof(duk_tval) * new_size;\n\tnew_valstack = (duk_tval *) DUK_REALLOC_INDIRECT(thr->heap, duk_hthread_get_valstack_ptr, (void *) thr, new_alloc_size);\n\tif (DUK_UNLIKELY(new_valstack == NULL)) {\n\t\t/* Because new_size != 0, if condition doesn't need to be\n\t\t * (new_valstack != NULL || new_size == 0).\n\t\t */\n\t\tDUK_ASSERT(new_size != 0);\n\t\tDUK_D(DUK_DPRINT(\"failed to resize valstack to %lu entries (%lu bytes)\",\n\t\t                 (unsigned long) new_size, (unsigned long) new_alloc_size));\n\t\treturn 0;\n\t}\n\n\t/* Debug log any changes in pointer(s) by side effects.  These don't\n\t * necessarily imply any incorrect behavior, but should be rare in\n\t * practice.\n\t */\n#if defined(DUK_USE_DEBUG)\n\tif (thr->valstack != pre_valstack) {\n\t\tDUK_D(DUK_DPRINT(\"valstack base pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_valstack, (void *) thr->valstack));\n\t}\n\tif (thr->valstack_bottom != pre_bottom) {\n\t\tDUK_D(DUK_DPRINT(\"valstack bottom pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_bottom, (void *) thr->valstack_bottom));\n\t}\n\tif (thr->valstack_top != pre_top) {\n\t\tDUK_D(DUK_DPRINT(\"valstack top pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_top, (void *) thr->valstack_top));\n\t}\n\tif (thr->valstack_end != pre_end) {\n\t\tDUK_D(DUK_DPRINT(\"valstack end pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_end, (void *) thr->valstack_end));\n\t}\n\tif (thr->valstack_alloc_end != pre_alloc_end) {\n\t\tDUK_D(DUK_DPRINT(\"valstack alloc_end pointer changed during valstack resize: %p -> %p\",\n\t\t                 (void *) pre_alloc_end, (void *) thr->valstack_alloc_end));\n\t}\n#endif\n\n\t/* Assertions: offsets for bottom, top, and end (reserve) must not\n\t * have changed even with side effects because they are always\n\t * restored in unwind.  For alloc_end there's no guarantee: it may\n\t * have grown or shrunk (but remain above 'end').\n\t */\n\tDUK_ASSERT(thr->valstack_bottom - thr->valstack == pre_bottom - pre_valstack);\n\tDUK_ASSERT(thr->valstack_top - thr->valstack == pre_top - pre_valstack);\n\tDUK_ASSERT(thr->valstack_end - thr->valstack == pre_end - pre_valstack);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\n\t/* Write new pointers.  Most pointers can be handled as a pointer\n\t * difference.\n\t */\n\tptr_diff = (duk_ptrdiff_t) ((duk_uint8_t *) new_valstack - (duk_uint8_t *) thr->valstack);\n\ttv_prev_alloc_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_alloc_end + ptr_diff);\n\tthr->valstack = new_valstack;\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + ptr_diff);\n\tthr->valstack_top = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_top + ptr_diff);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_end + ptr_diff);\n\tthr->valstack_alloc_end = (duk_tval *) (void *) ((duk_uint8_t *) new_valstack + new_alloc_size);\n\n\t/* Assertions: pointer sanity after pointer updates. */\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\n\tDUK_D(DUK_DPRINT(\"resized valstack %lu -> %lu elements (%lu -> %lu bytes): \"\n\t                 \"base=%p -> %p, bottom=%p -> %p (%ld), top=%p -> %p (%ld), \"\n\t                 \"end=%p -> %p (%ld), alloc_end=%p -> %p (%ld);\"\n\t                 \" tv_prev_alloc_end=%p (-> %ld inits; <0 means shrink)\",\n\t                 (unsigned long) (pre_alloc_end - pre_valstack),\n\t                 (unsigned long) new_size,\n\t                 (unsigned long) ((duk_uint8_t *) pre_alloc_end - (duk_uint8_t *) pre_valstack),\n\t                 (unsigned long) new_alloc_size,\n\t                 (void *) pre_valstack, (void *) thr->valstack,\n\t                 (void *) pre_bottom, (void *) thr->valstack_bottom, (long) (thr->valstack_bottom - thr->valstack),\n\t                 (void *) pre_top, (void *) thr->valstack_top, (long) (thr->valstack_top - thr->valstack),\n\t                 (void *) pre_end, (void *) thr->valstack_end, (long) (thr->valstack_end - thr->valstack),\n\t                 (void *) pre_alloc_end, (void *) thr->valstack_alloc_end, (long) (thr->valstack_alloc_end - thr->valstack),\n\t                 (void *) tv_prev_alloc_end, (long) (thr->valstack_alloc_end - tv_prev_alloc_end)));\n\n\t/* If allocation grew, init any new slots to 'undefined'. */\n\tp = tv_prev_alloc_end;\n\twhile (p < thr->valstack_alloc_end) {\n\t\t/* Never executed if new size is smaller. */\n\t\tDUK_TVAL_SET_UNDEFINED(p);\n\t\tp++;\n\t}\n\n\t/* Assert for value stack initialization policy. */\n#if defined(DUK_USE_ASSERTIONS)\n\tp = thr->valstack_top;\n\twhile (p < thr->valstack_alloc_end) {\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(p));\n\t\tp++;\n\t}\n#endif\n\n\treturn 1;\n}\n\nDUK_LOCAL DUK_COLD DUK_NOINLINE duk_bool_t duk__valstack_grow(duk_hthread *thr, duk_size_t min_bytes, duk_bool_t throw_on_error) {\n\tduk_size_t min_size;\n\tduk_size_t new_size;\n\n\tDUK_ASSERT(min_bytes / sizeof(duk_tval) * sizeof(duk_tval) == min_bytes);\n\tmin_size = min_bytes / sizeof(duk_tval);  /* from bytes to slots */\n\n#if defined(DUK_USE_VALSTACK_GROW_SHIFT)\n\t/* New size is minimum size plus a proportional slack, e.g. shift of\n\t * 2 means a 25% slack.\n\t */\n\tnew_size = min_size + (min_size >> DUK_USE_VALSTACK_GROW_SHIFT);\n#else\n\t/* New size is tight with no slack.  This is sometimes preferred in\n\t * low memory environments.\n\t */\n\tnew_size = min_size;\n#endif\n\n\tif (DUK_UNLIKELY(new_size > DUK_USE_VALSTACK_LIMIT || new_size < min_size /*wrap*/)) {\n\t\t/* Note: may be triggered even if minimal new_size would not reach the limit,\n\t\t * plan limit accordingly.\n\t\t */\n\t\tif (throw_on_error) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_VALSTACK_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\treturn 0;\n\t}\n\n\tif (duk__resize_valstack(thr, new_size) == 0) {\n\t\tif (throw_on_error) {\n\t\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\treturn 0;\n\t}\n\n\tthr->valstack_end = thr->valstack + min_size;\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n\n\treturn 1;\n}\n\n/* Hot, inlined value stack grow check.  Because value stack almost never\n * grows, the actual resize call is in a NOINLINE helper.\n */\nDUK_INTERNAL DUK_INLINE void duk_valstack_grow_check_throw(duk_hthread *thr, duk_size_t min_bytes) {\n\tduk_tval *tv;\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + min_bytes);\n\tif (DUK_LIKELY(thr->valstack_end >= tv)) {\n\t\treturn;\n\t}\n\tif (DUK_LIKELY(thr->valstack_alloc_end >= tv)) {\n\t\t/* Values in [valstack_top,valstack_alloc_end[ are initialized\n\t\t * to 'undefined' so we can just move the end pointer.\n\t\t */\n\t\tthr->valstack_end = tv;\n\t\treturn;\n\t}\n\t(void) duk__valstack_grow(thr, min_bytes, 1 /*throw_on_error*/);\n}\n\n/* Hot, inlined value stack grow check which doesn't throw. */\nDUK_INTERNAL DUK_INLINE duk_bool_t duk_valstack_grow_check_nothrow(duk_hthread *thr, duk_size_t min_bytes) {\n\tduk_tval *tv;\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + min_bytes);\n\tif (DUK_LIKELY(thr->valstack_end >= tv)) {\n\t\treturn 1;\n\t}\n\tif (DUK_LIKELY(thr->valstack_alloc_end >= tv)) {\n\t\tthr->valstack_end = tv;\n\t\treturn 1;\n\t}\n\treturn duk__valstack_grow(thr, min_bytes, 0 /*throw_on_error*/);\n}\n\n/* Value stack shrink check, called from mark-and-sweep. */\nDUK_INTERNAL void duk_valstack_shrink_check_nothrow(duk_hthread *thr, duk_bool_t snug) {\n\tduk_size_t alloc_bytes;\n\tduk_size_t reserve_bytes;\n\tduk_size_t shrink_bytes;\n\n\talloc_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_alloc_end - (duk_uint8_t *) thr->valstack);\n\treserve_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tDUK_ASSERT(alloc_bytes >= reserve_bytes);\n\n\t/* We're free to shrink the value stack allocation down to\n\t * reserve_bytes but not more.  If 'snug' (emergency GC)\n\t * shrink whatever we can.  Otherwise only shrink if the new\n\t * size would be considerably smaller.\n\t */\n\n#if defined(DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT)\n\tif (snug) {\n\t\tshrink_bytes = reserve_bytes;\n\t} else {\n\t\tduk_size_t proportion, slack;\n\n\t\t/* Require that value stack shrinks by at least X% of its\n\t\t * current size.  For example, shift of 2 means at least\n\t\t * 25%.  The proportion is computed as bytes and may not\n\t\t * be a multiple of sizeof(duk_tval); that's OK here.\n\t\t */\n\t\tproportion = alloc_bytes >> DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT;\n\t\tif (alloc_bytes - reserve_bytes < proportion) {\n\t\t\t/* Too little would be freed, do nothing. */\n\t\t\treturn;\n\t\t}\n\n\t\t/* Keep a slack after shrinking.  The slack is again a\n\t\t * proportion of the current size (the proportion should\n\t\t * of course be smaller than the check proportion above).\n\t\t */\n#if defined(DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT)\n\t\tDUK_ASSERT(DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT > DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT);\n\t\tslack = alloc_bytes >> DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT;\n#else\n\t\tslack = 0;\n#endif\n\t\tshrink_bytes = reserve_bytes +\n\t\t               slack / sizeof(duk_tval) * sizeof(duk_tval);  /* multiple of duk_tval */\n\t}\n#else  /* DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT */\n\t/* Always snug, useful in some low memory environments. */\n\tDUK_UNREF(snug);\n\tshrink_bytes = reserve_bytes;\n#endif  /* DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT */\n\n\tDUK_D(DUK_DPRINT(\"valstack shrink check: alloc_bytes=%ld, reserve_bytes=%ld, shrink_bytes=%ld (unvalidated)\",\n\t                 (long) alloc_bytes, (long) reserve_bytes, (long) shrink_bytes));\n\tDUK_ASSERT(shrink_bytes >= reserve_bytes);\n\tif (shrink_bytes >= alloc_bytes) {\n\t\t/* Skip if shrink target is same as current one (or higher,\n\t\t * though that shouldn't happen in practice).\n\t\t */\n\t\treturn;\n\t}\n\tDUK_ASSERT(shrink_bytes / sizeof(duk_tval) * sizeof(duk_tval) == shrink_bytes);\n\n\tDUK_D(DUK_DPRINT(\"valstack shrink check: decided to shrink, snug: %ld\", (long) snug));\n\n\tduk__resize_valstack(thr, shrink_bytes / sizeof(duk_tval));\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_stack(duk_hthread *thr, duk_idx_t extra) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\n\tif (DUK_UNLIKELY(extra < 0 || extra > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (extra < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\textra = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\textra = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) extra + DUK_VALSTACK_INTERNAL_EXTRA);\n\treturn duk_valstack_grow_check_nothrow(thr, min_new_bytes);\n}\n\nDUK_EXTERNAL void duk_require_stack(duk_hthread *thr, duk_idx_t extra) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\n\tif (DUK_UNLIKELY(extra < 0 || extra > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (extra < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\textra = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\textra = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) extra + DUK_VALSTACK_INTERNAL_EXTRA);\n\tduk_valstack_grow_check_throw(thr, min_new_bytes);\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_stack_top(duk_hthread *thr, duk_idx_t top) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (DUK_UNLIKELY(top < 0 || top > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (top < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\ttop = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\ttop = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tDUK_ASSERT(top >= 0);\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) top + DUK_VALSTACK_INTERNAL_EXTRA);\n\treturn duk_valstack_grow_check_nothrow(thr, min_new_bytes);\n}\n\nDUK_EXTERNAL void duk_require_stack_top(duk_hthread *thr, duk_idx_t top) {\n\tduk_size_t min_new_bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (DUK_UNLIKELY(top < 0 || top > DUK_USE_VALSTACK_LIMIT)) {\n\t\tif (top < 0) {\n\t\t\t/* Clamping to zero makes the API more robust to calling code\n\t\t\t * calculation errors.\n\t\t\t */\n\t\t\ttop = 0;\n\t\t} else {\n\t\t\t/* Cause grow check to fail without wrapping arithmetic. */\n\t\t\ttop = DUK_USE_VALSTACK_LIMIT;\n\t\t}\n\t}\n\n\tDUK_ASSERT(top >= 0);\n\tmin_new_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) +\n\t                sizeof(duk_tval) * ((duk_size_t) top + DUK_VALSTACK_INTERNAL_EXTRA);\n\tduk_valstack_grow_check_throw(thr, min_new_bytes);\n}\n\n/*\n *  Basic stack manipulation: swap, dup, insert, replace, etc\n */\n\nDUK_EXTERNAL void duk_swap(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n\tduk_tval tv_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_require_tval(thr, idx1);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, idx2);\n\tDUK_ASSERT(tv2 != NULL);\n\n\t/* If tv1==tv2 this is a NOP, no check is needed */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv1);\n\tDUK_TVAL_SET_TVAL(tv1, tv2);\n\tDUK_TVAL_SET_TVAL(tv2, &tv_tmp);\n}\n\nDUK_EXTERNAL void duk_swap_top(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_swap(thr, idx, -1);\n}\n\nDUK_EXTERNAL void duk_dup(duk_hthread *thr, duk_idx_t from_idx) {\n\tduk_tval *tv_from;\n\tduk_tval *tv_to;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\n\ttv_from = duk_require_tval(thr, from_idx);\n\ttv_to = thr->valstack_top++;\n\tDUK_ASSERT(tv_from != NULL);\n\tDUK_ASSERT(tv_to != NULL);\n\tDUK_TVAL_SET_TVAL(tv_to, tv_from);\n\tDUK_TVAL_INCREF(thr, tv_to);  /* no side effects */\n}\n\nDUK_EXTERNAL void duk_dup_top(duk_hthread *thr) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_dup(thr, -1);\n#else\n\tduk_tval *tv_from;\n\tduk_tval *tv_to;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\n\tif (DUK_UNLIKELY(thr->valstack_top - thr->valstack_bottom <= 0)) {\n\t\tDUK_ERROR_RANGE_INDEX(thr, -1);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\ttv_from = thr->valstack_top - 1;\n\ttv_to = thr->valstack_top++;\n\tDUK_ASSERT(tv_from != NULL);\n\tDUK_ASSERT(tv_to != NULL);\n\tDUK_TVAL_SET_TVAL(tv_to, tv_from);\n\tDUK_TVAL_INCREF(thr, tv_to);  /* no side effects */\n#endif\n}\n\nDUK_INTERNAL void duk_dup_0(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, 0);\n}\nDUK_INTERNAL void duk_dup_1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, 1);\n}\nDUK_INTERNAL void duk_dup_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, 2);\n}\nDUK_INTERNAL void duk_dup_m2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, -2);\n}\nDUK_INTERNAL void duk_dup_m3(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, -3);\n}\nDUK_INTERNAL void duk_dup_m4(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_dup(thr, -4);\n}\n\nDUK_EXTERNAL void duk_insert(duk_hthread *thr, duk_idx_t to_idx) {\n\tduk_tval *p;\n\tduk_tval *q;\n\tduk_tval tv_tmp;\n\tduk_size_t nbytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tp = duk_require_tval(thr, to_idx);\n\tDUK_ASSERT(p != NULL);\n\tq = duk_require_tval(thr, -1);\n\tDUK_ASSERT(q != NULL);\n\n\tDUK_ASSERT(q >= p);\n\n\t/*              nbytes\n\t *           <--------->\n\t *    [ ... | p | x | x | q ]\n\t * => [ ... | q | p | x | x ]\n\t */\n\n\tnbytes = (duk_size_t) (((duk_uint8_t *) q) - ((duk_uint8_t *) p));  /* Note: 'q' is top-1 */\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk_insert: to_idx=%ld, p=%p, q=%p, nbytes=%lu\",\n\t                     (long) to_idx, (void *) p, (void *) q, (unsigned long) nbytes));\n\n\t/* No net refcount changes.  No need to special case nbytes == 0\n\t * (p == q).\n\t */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, q);\n\tduk_memmove((void *) (p + 1), (const void *) p, (size_t) nbytes);\n\tDUK_TVAL_SET_TVAL(p, &tv_tmp);\n}\n\nDUK_INTERNAL void duk_insert_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(idx >= 0);  /* Doesn't support negative indices. */\n\n\tduk_push_undefined(thr);\n\tduk_insert(thr, idx);\n}\n\nDUK_INTERNAL void duk_insert_undefined_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) {\n\tduk_tval *tv, *tv_end;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(idx >= 0);  /* Doesn't support negative indices or count. */\n\tDUK_ASSERT(count >= 0);\n\n\ttv = duk_reserve_gap(thr, idx, count);\n\ttv_end = tv + count;\n\twhile (tv != tv_end) {\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t\ttv++;\n\t}\n}\n\nDUK_EXTERNAL void duk_replace(duk_hthread *thr, duk_idx_t to_idx) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n\tduk_tval tv_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, to_idx);\n\tDUK_ASSERT(tv2 != NULL);\n\n\t/* For tv1 == tv2, both pointing to stack top, the end result\n\t * is same as duk_pop(thr).\n\t */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv2);\n\tDUK_TVAL_SET_TVAL(tv2, tv1);\n\tDUK_TVAL_SET_UNDEFINED(tv1);\n\tthr->valstack_top--;\n\tDUK_TVAL_DECREF(thr, &tv_tmp);  /* side effects */\n}\n\nDUK_EXTERNAL void duk_copy(duk_hthread *thr, duk_idx_t from_idx, duk_idx_t to_idx) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_require_tval(thr, from_idx);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, to_idx);\n\tDUK_ASSERT(tv2 != NULL);\n\n\t/* For tv1 == tv2, this is a no-op (no explicit check needed). */\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv2, tv1);  /* side effects */\n}\n\nDUK_EXTERNAL void duk_remove(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *p;\n\tduk_tval *q;\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_tval tv_tmp;\n#endif\n\tduk_size_t nbytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tp = duk_require_tval(thr, idx);\n\tDUK_ASSERT(p != NULL);\n\tq = duk_require_tval(thr, -1);\n\tDUK_ASSERT(q != NULL);\n\n\tDUK_ASSERT(q >= p);\n\n\t/*              nbytes            zero size case\n\t *           <--------->\n\t *    [ ... | p | x | x | q ]     [ ... | p==q ]\n\t * => [ ... | x | x | q ]         [ ... ]\n\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* use a temp: decref only when valstack reachable values are correct */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, p);\n#endif\n\n\tnbytes = (duk_size_t) (((duk_uint8_t *) q) - ((duk_uint8_t *) p));  /* Note: 'q' is top-1 */\n\tduk_memmove((void *) p, (const void *) (p + 1), (size_t) nbytes);\n\n\tDUK_TVAL_SET_UNDEFINED(q);\n\tthr->valstack_top--;\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_DECREF(thr, &tv_tmp);  /* side effects */\n#endif\n}\n\nDUK_INTERNAL void duk_remove_unsafe(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_remove(thr, idx);  /* XXX: no optimization for now */\n}\n\nDUK_INTERNAL void duk_remove_m2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_remove(thr, -2);\n}\n\nDUK_INTERNAL void duk_remove_n(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) {\n#if defined(DUK_USE_PREFER_SIZE)\n\t/* XXX: maybe too slow even when preferring size? */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT(idx >= 0);\n\n\twhile (count-- > 0) {\n\t\tduk_remove(thr, idx);\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_tval *tv_newtop;\n\tduk_tval *tv;\n\tduk_size_t bytes;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT(idx >= 0);\n\n\ttv_dst = thr->valstack_bottom + idx;\n\tDUK_ASSERT(tv_dst <= thr->valstack_top);\n\ttv_src = tv_dst + count;\n\tDUK_ASSERT(tv_src <= thr->valstack_top);\n\tbytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) tv_src);\n\n\tfor (tv = tv_dst; tv < tv_src; tv++) {\n\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t}\n\n\tduk_memmove((void *) tv_dst, (const void *) tv_src, bytes);\n\n\ttv_newtop = thr->valstack_top - count;\n\tfor (tv = tv_newtop; tv < thr->valstack_top; tv++) {\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t}\n\tthr->valstack_top = tv_newtop;\n\n\t/* When not preferring size, only NORZ macros are used; caller\n\t * is expected to DUK_REFZERO_CHECK().\n\t */\n#endif  /* DUK_USE_PREFER_SIZE */\n}\n\nDUK_INTERNAL void duk_remove_n_unsafe(duk_hthread *thr, duk_idx_t idx, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_remove_n(thr, idx, count);  /* XXX: no optimization for now */\n}\n\n/*\n *  Stack slice primitives\n */\n\nDUK_EXTERNAL void duk_xcopymove_raw(duk_hthread *to_thr, duk_hthread *from_thr, duk_idx_t count, duk_bool_t is_copy) {\n\tvoid *src;\n\tduk_size_t nbytes;\n\tduk_tval *p;\n\tduk_tval *q;\n\n\t/* XXX: several pointer comparison issues here */\n\n\tDUK_ASSERT_API_ENTRY(to_thr);\n\tDUK_CTX_ASSERT_VALID(to_thr);\n\tDUK_CTX_ASSERT_VALID(from_thr);\n\tDUK_ASSERT(to_thr->heap == from_thr->heap);\n\n\tif (DUK_UNLIKELY(to_thr == from_thr)) {\n\t\tDUK_ERROR_TYPE(to_thr, DUK_STR_INVALID_CONTEXT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tif (DUK_UNLIKELY((duk_uidx_t) count > (duk_uidx_t) DUK_USE_VALSTACK_LIMIT)) {\n\t\t/* Maximum value check ensures 'nbytes' won't wrap below.\n\t\t * Also handles negative count.\n\t\t */\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(to_thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(count >= 0);\n\n\tnbytes = sizeof(duk_tval) * (duk_size_t) count;\n\tif (DUK_UNLIKELY(nbytes == 0)) {\n\t\treturn;\n\t}\n\tDUK_ASSERT(to_thr->valstack_top <= to_thr->valstack_end);\n\tif (DUK_UNLIKELY((duk_size_t) ((duk_uint8_t *) to_thr->valstack_end - (duk_uint8_t *) to_thr->valstack_top) < nbytes)) {\n\t\tDUK_ERROR_RANGE_PUSH_BEYOND(to_thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tsrc = (void *) ((duk_uint8_t *) from_thr->valstack_top - nbytes);\n\tif (DUK_UNLIKELY(src < (void *) from_thr->valstack_bottom)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(to_thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* Copy values (no overlap even if to_thr == from_thr; that's not\n\t * allowed now anyway).\n\t */\n\tDUK_ASSERT(nbytes > 0);\n\tduk_memcpy((void *) to_thr->valstack_top, (const void *) src, (size_t) nbytes);\n\n\tp = to_thr->valstack_top;\n\tto_thr->valstack_top = (duk_tval *) (void *) (((duk_uint8_t *) p) + nbytes);\n\n\tif (is_copy) {\n\t\t/* Incref copies, keep originals. */\n\t\tq = to_thr->valstack_top;\n\t\twhile (p < q) {\n\t\t\tDUK_TVAL_INCREF(to_thr, p);  /* no side effects */\n\t\t\tp++;\n\t\t}\n\t} else {\n\t\t/* No net refcount change. */\n\t\tp = from_thr->valstack_top;\n\t\tq = (duk_tval *) (void *) (((duk_uint8_t *) p) - nbytes);\n\t\tfrom_thr->valstack_top = q;\n\n\t\twhile (p > q) {\n\t\t\tp--;\n\t\t\tDUK_TVAL_SET_UNDEFINED(p);\n\t\t\t/* XXX: fast primitive to set a bunch of values to UNDEFINED */\n\t\t}\n\t}\n}\n\n/* Internal helper: reserve a gap of 'count' elements at 'idx_base' and return a\n * pointer to the gap.  Values in the gap are garbage and MUST be initialized by\n * the caller before any side effects may occur.  The caller must ensure there's\n * enough stack reserve for 'count' values.\n */\nDUK_INTERNAL duk_tval *duk_reserve_gap(duk_hthread *thr, duk_idx_t idx_base, duk_idx_t count) {\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_size_t gap_bytes;\n\tduk_size_t copy_bytes;\n\n\t/* Caller is responsible for ensuring there's enough preallocated\n\t * value stack.\n\t */\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_end - thr->valstack_top) >= (duk_size_t) count);\n\n\ttv_src = thr->valstack_bottom + idx_base;\n\tgap_bytes = (duk_size_t) count * sizeof(duk_tval);\n\ttv_dst = (duk_tval *) (void *) ((duk_uint8_t *) tv_src + gap_bytes);\n\tcopy_bytes = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) tv_src);\n\tthr->valstack_top = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_top + gap_bytes);\n\tduk_memmove((void *) tv_dst, (const void *) tv_src, copy_bytes);\n\n\t/* Values in the gap are left as garbage: caller must fill them in\n\t * and INCREF them before any side effects.\n\t */\n\treturn tv_src;\n}\n\n/*\n *  Get/opt/require\n */\n\nDUK_EXTERNAL void duk_require_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_UNDEFINED(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"undefined\", DUK_STR_NOT_UNDEFINED);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_EXTERNAL void duk_require_null(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_NULL(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"null\", DUK_STR_NOT_NULL);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_bool_t duk__get_boolean_raw(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) {\n\tduk_bool_t ret;\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BOOLEAN(tv)) {\n\t\tret = DUK_TVAL_GET_BOOLEAN(tv);\n\t\tDUK_ASSERT(ret == 0 || ret == 1);\n\t} else {\n\t\tret = def_value;\n\t\t/* Not guaranteed to be 0 or 1. */\n\t}\n\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_boolean_raw(thr, idx, 0);  /* default: false */\n}\n\nDUK_EXTERNAL duk_bool_t duk_get_boolean_default(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_boolean_raw(thr, idx, def_value);\n}\n\nDUK_EXTERNAL duk_bool_t duk_require_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_LIKELY(DUK_TVAL_IS_BOOLEAN(tv))) {\n\t\tret = DUK_TVAL_GET_BOOLEAN(tv);\n\t\tDUK_ASSERT(ret == 0 || ret == 1);\n\t\treturn ret;\n\t} else {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"boolean\", DUK_STR_NOT_BOOLEAN);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n}\n\nDUK_EXTERNAL duk_bool_t duk_opt_boolean(duk_hthread *thr, duk_idx_t idx, duk_bool_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_boolean(thr, idx);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_double_t duk__get_number_raw(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {\n\tduk_double_union ret;\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tret.d = (duk_double_t) DUK_TVAL_GET_FASTINT(tv);  /* XXX: cast trick */\n\t}\n\telse\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv)) {\n\t\t/* When using packed duk_tval, number must be in NaN-normalized form\n\t\t * for it to be a duk_tval, so no need to normalize.  NOP for unpacked\n\t\t * duk_tval.\n\t\t */\n\t\tret.d = DUK_TVAL_GET_DOUBLE(tv);\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&ret));\n\t} else {\n\t\tret.d = def_value;\n\t\t/* Default value (including NaN) may not be normalized. */\n\t}\n\n\treturn ret.d;\n}\n\nDUK_EXTERNAL duk_double_t duk_get_number(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_number_raw(thr, idx, DUK_DOUBLE_NAN);  /* default: NaN */\n}\n\nDUK_EXTERNAL duk_double_t duk_get_number_default(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_number_raw(thr, idx, def_value);\n}\n\nDUK_EXTERNAL duk_double_t duk_require_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_double_union ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_NUMBER(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"number\", DUK_STR_NOT_NUMBER);\n\t\tDUK_WO_NORETURN(return 0.0;);\n\t}\n\n\tret.d = DUK_TVAL_GET_NUMBER(tv);\n\n\t/* When using packed duk_tval, number must be in NaN-normalized form\n\t * for it to be a duk_tval, so no need to normalize.  NOP for unpacked\n\t * duk_tval.\n\t */\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&ret));\n\treturn ret.d;\n}\n\nDUK_EXTERNAL duk_double_t duk_opt_number(duk_hthread *thr, duk_idx_t idx, duk_double_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\t/* User provided default is not NaN normalized. */\n\t\treturn def_value;\n\t}\n\treturn duk_require_number(thr, idx);\n}\n\nDUK_EXTERNAL duk_int_t duk_get_int(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_get_uint(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_get_int_default(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, def_value, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_get_uint_default(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, def_value, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_require_int(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 1 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_require_uint(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 1 /*require*/);\n}\n\nDUK_EXTERNAL duk_int_t duk_opt_int(duk_hthread *thr, duk_idx_t idx, duk_int_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_int(thr, idx);\n}\n\nDUK_EXTERNAL duk_uint_t duk_opt_uint(duk_hthread *thr, duk_idx_t idx, duk_uint_t def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_uint(thr, idx);\n}\n\nDUK_EXTERNAL const char *duk_get_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tduk_hstring *h;\n\tconst char *ret;\n\tduk_size_t len;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\t\tret = (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\tlen = 0;\n\t\tret = NULL;\n\t}\n\n\tif (out_len != NULL) {\n\t\t*out_len = len;\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL const char *duk_require_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\tif (out_len) {\n\t\t*out_len = DUK_HSTRING_GET_BYTELEN(h);\n\t}\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_INTERNAL const char *duk_require_lstring_notsymbol(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hstring_notsymbol(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\tif (out_len) {\n\t\t*out_len = DUK_HSTRING_GET_BYTELEN(h);\n\t}\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_EXTERNAL const char *duk_get_string(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\treturn NULL;\n\t}\n}\n\nDUK_EXTERNAL const char *duk_opt_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\tif (out_len != NULL) {\n\t\t\t*out_len = def_len;\n\t\t}\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_lstring(thr, idx, out_len);\n}\n\nDUK_EXTERNAL const char *duk_opt_string(duk_hthread *thr, duk_idx_t idx, const char *def_ptr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_string(thr, idx);\n}\n\nDUK_EXTERNAL const char *duk_get_lstring_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len) {\n\tduk_hstring *h;\n\tconst char *ret;\n\tduk_size_t len;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\tlen = DUK_HSTRING_GET_BYTELEN(h);\n\t\tret = (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\tlen = def_len;\n\t\tret = def_ptr;\n\t}\n\n\tif (out_len != NULL) {\n\t\t*out_len = len;\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL const char *duk_get_string_default(duk_hthread *thr, duk_idx_t idx, const char *def_value) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring(thr, idx);\n\tif (h != NULL) {\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\treturn def_value;\n\t}\n}\n\nDUK_INTERNAL const char *duk_get_string_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hstring_notsymbol(thr, idx);\n\tif (h) {\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n\t} else {\n\t\treturn NULL;\n\t}\n}\n\nDUK_EXTERNAL const char *duk_require_string(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_require_lstring(thr, idx, NULL);\n}\n\nDUK_INTERNAL const char *duk_require_string_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hstring_notsymbol(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_EXTERNAL void duk_require_object(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_OBJECT(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"object\", DUK_STR_NOT_OBJECT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_LOCAL void *duk__get_pointer_raw(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tduk_tval *tv;\n\tvoid *p;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (!DUK_TVAL_IS_POINTER(tv)) {\n\t\treturn def_value;\n\t}\n\n\tp = DUK_TVAL_GET_POINTER(tv);  /* may be NULL */\n\treturn p;\n}\n\nDUK_EXTERNAL void *duk_get_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_pointer_raw(thr, idx, NULL /*def_value*/);\n}\n\nDUK_EXTERNAL void *duk_opt_pointer(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_pointer(thr, idx);\n}\n\nDUK_EXTERNAL void *duk_get_pointer_default(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_pointer_raw(thr, idx, def_value);\n}\n\nDUK_EXTERNAL void *duk_require_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *p;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Note: here we must be wary of the fact that a pointer may be\n\t * valid and be a NULL.\n\t */\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_POINTER(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"pointer\", DUK_STR_NOT_POINTER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\tp = DUK_TVAL_GET_POINTER(tv);  /* may be NULL */\n\treturn p;\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL void *duk_get_voidptr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_heaphdr *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (!DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\treturn NULL;\n\t}\n\n\th = DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(h != NULL);\n\treturn (void *) h;\n}\n#endif\n\nDUK_LOCAL void *duk__get_buffer_helper(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size, duk_bool_t throw_flag) {\n\tduk_hbuffer *h;\n\tvoid *ret;\n\tduk_size_t len;\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tif (out_size != NULL) {\n\t\t*out_size = 0;\n\t}\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_LIKELY(DUK_TVAL_IS_BUFFER(tv))) {\n\t\th = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tlen = DUK_HBUFFER_GET_SIZE(h);\n\t\tret = DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);\n\t} else {\n\t\tif (throw_flag) {\n\t\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"buffer\", DUK_STR_NOT_BUFFER);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t\tlen = def_size;\n\t\tret = def_ptr;\n\t}\n\n\tif (out_size != NULL) {\n\t\t*out_size = len;\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL void *duk_get_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_buffer_helper(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/);\n}\n\nDUK_EXTERNAL void *duk_opt_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\tif (out_size != NULL) {\n\t\t\t*out_size = def_size;\n\t\t}\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_buffer(thr, idx, out_size);\n}\n\nDUK_EXTERNAL void *duk_get_buffer_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_buffer_helper(thr, idx, out_size, def_ptr, def_len, 0 /*throw_flag*/);\n}\n\nDUK_EXTERNAL void *duk_require_buffer(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk__get_buffer_helper(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 1 /*throw_flag*/);\n}\n\n/* Get the active buffer data area for a plain buffer or a buffer object.\n * Return NULL if the the value is not a buffer.  Note that a buffer may\n * have a NULL data pointer when its size is zero, the optional 'out_isbuffer'\n * argument allows caller to detect this reliably.\n */\nDUK_INTERNAL void *duk_get_buffer_data_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size, duk_bool_t throw_flag, duk_bool_t *out_isbuffer) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (out_isbuffer != NULL) {\n\t\t*out_isbuffer = 0;\n\t}\n\tif (out_size != NULL) {\n\t\t*out_size = def_size;\n\t}\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (out_size != NULL) {\n\t\t\t*out_size = DUK_HBUFFER_GET_SIZE(h);\n\t\t}\n\t\tif (out_isbuffer != NULL) {\n\t\t\t*out_isbuffer = 1;\n\t\t}\n\t\treturn (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);  /* may be NULL (but only if size is 0) */\n\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\telse if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\t/* XXX: this is probably a useful shared helper: for a\n\t\t\t * duk_hbufobj, get a validated buffer pointer/length.\n\t\t\t */\n\t\t\tduk_hbufobj *h_bufobj = (duk_hbufobj *) h;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t\t\tif (h_bufobj->buf != NULL &&\n\t\t\t    DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {\n\t\t\t\tduk_uint8_t *p;\n\n\t\t\t\tp = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf);\n\t\t\t\tif (out_size != NULL) {\n\t\t\t\t\t*out_size = (duk_size_t) h_bufobj->length;\n\t\t\t\t}\n\t\t\t\tif (out_isbuffer != NULL) {\n\t\t\t\t\t*out_isbuffer = 1;\n\t\t\t\t}\n\t\t\t\treturn (void *) (p + h_bufobj->offset);\n\t\t\t}\n\t\t\t/* if slice not fully valid, treat as error */\n\t\t}\n\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\tif (throw_flag) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"buffer\", DUK_STR_NOT_BUFFER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn def_ptr;\n}\n\nDUK_EXTERNAL void *duk_get_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_buffer_data_raw(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 0 /*throw_flag*/, NULL);\n}\n\nDUK_EXTERNAL void *duk_get_buffer_data_default(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_buffer_data_raw(thr, idx, out_size, def_ptr, def_size, 0 /*throw_flag*/, NULL);\n}\n\nDUK_EXTERNAL void *duk_opt_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\tif (out_size != NULL) {\n\t\t\t*out_size = def_size;\n\t\t}\n\t\treturn def_ptr;\n\t}\n\treturn duk_require_buffer_data(thr, idx, out_size);\n}\n\nDUK_EXTERNAL void *duk_require_buffer_data(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_buffer_data_raw(thr, idx, out_size, NULL /*def_ptr*/, 0 /*def_size*/, 1 /*throw_flag*/, NULL);\n}\n\n/* Raw helper for getting a value from the stack, checking its tag.\n * The tag cannot be a number because numbers don't have an internal\n * tag in the packed representation.\n */\n\nDUK_LOCAL duk_heaphdr *duk__get_tagged_heaphdr_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t tag) {\n\tduk_tval *tv;\n\tduk_heaphdr *ret;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_GET_TAG(tv) != tag) {\n\t\treturn (duk_heaphdr *) NULL;\n\t}\n\n\tret = DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(ret != NULL);  /* tagged null pointers should never occur */\n\treturn ret;\n\n}\n\nDUK_INTERNAL duk_hstring *duk_get_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n}\n\nDUK_INTERNAL duk_hstring *duk_get_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n\tif (DUK_UNLIKELY(h && DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\treturn NULL;\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_require_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"string\", DUK_STR_NOT_STRING);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_require_hstring_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hstring *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_STRING);\n\tif (DUK_UNLIKELY(h == NULL || DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"string\", DUK_STR_NOT_STRING);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_get_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n}\n\nDUK_INTERNAL duk_hobject *duk_require_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"object\", DUK_STR_NOT_OBJECT);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hbuffer *duk_get_hbuffer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn (duk_hbuffer *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_BUFFER);\n}\n\nDUK_INTERNAL duk_hbuffer *duk_require_hbuffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hbuffer *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hbuffer *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_BUFFER);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"buffer\", DUK_STR_NOT_BUFFER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hthread *duk_get_hthread(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_THREAD(h))) {\n\t\th = NULL;\n\t}\n\treturn (duk_hthread *) h;\n}\n\nDUK_INTERNAL duk_hthread *duk_require_hthread(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_THREAD(h)))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"thread\", DUK_STR_NOT_THREAD);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn (duk_hthread *) h;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_get_hcompfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_COMPFUNC(h))) {\n\t\th = NULL;\n\t}\n\treturn (duk_hcompfunc *) h;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_require_hcompfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_COMPFUNC(h)))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"compiledfunction\", DUK_STR_NOT_COMPFUNC);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn (duk_hcompfunc *) h;\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_get_hnatfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_IS_NATFUNC(h))) {\n\t\th = NULL;\n\t}\n\treturn (duk_hnatfunc *) h;\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_require_hnatfunc(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_IS_NATFUNC(h)))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"nativefunction\", DUK_STR_NOT_NATFUNC);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn (duk_hnatfunc *) h;\n}\n\nDUK_EXTERNAL duk_c_function duk_get_c_function(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\tduk_hnatfunc *f;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_OBJECT(tv))) {\n\t\treturn NULL;\n\t}\n\th = DUK_TVAL_GET_OBJECT(tv);\n\tDUK_ASSERT(h != NULL);\n\n\tif (DUK_UNLIKELY(!DUK_HOBJECT_IS_NATFUNC(h))) {\n\t\treturn NULL;\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_HAS_NATFUNC(h));\n\tf = (duk_hnatfunc *) h;\n\n\treturn f->func;\n}\n\nDUK_EXTERNAL duk_c_function duk_opt_c_function(duk_hthread *thr, duk_idx_t idx, duk_c_function def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_c_function(thr, idx);\n}\n\nDUK_EXTERNAL duk_c_function duk_get_c_function_default(duk_hthread *thr, duk_idx_t idx, duk_c_function def_value) {\n\tduk_c_function ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_c_function(thr, idx);\n\tif (ret != NULL) {\n\t\treturn ret;\n\t}\n\n\treturn def_value;\n}\n\nDUK_EXTERNAL duk_c_function duk_require_c_function(duk_hthread *thr, duk_idx_t idx) {\n\tduk_c_function ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_c_function(thr, idx);\n\tif (DUK_UNLIKELY(!ret)) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"nativefunction\", DUK_STR_NOT_NATFUNC);\n\t\tDUK_WO_NORETURN(return ret;);\n\t}\n\treturn ret;\n}\n\nDUK_EXTERNAL void duk_require_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tif (DUK_UNLIKELY(!duk_is_function(thr, idx))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"function\", DUK_STR_NOT_FUNCTION);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\nDUK_EXTERNAL void duk_require_constructable(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_require_hobject_accept_mask(thr, idx, DUK_TYPE_MASK_LIGHTFUNC);\n\tif (DUK_UNLIKELY(h != NULL && !DUK_HOBJECT_HAS_CONSTRUCTABLE(h))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"constructable\", DUK_STR_NOT_CONSTRUCTABLE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\t/* Lightfuncs (h == NULL) are constructable. */\n}\n\nDUK_EXTERNAL duk_hthread *duk_get_context(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_get_hthread(thr, idx);\n}\n\nDUK_EXTERNAL duk_hthread *duk_require_context(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_require_hthread(thr, idx);\n}\n\nDUK_EXTERNAL duk_hthread *duk_opt_context(duk_hthread *thr, duk_idx_t idx, duk_hthread *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_context(thr, idx);\n}\n\nDUK_EXTERNAL duk_hthread *duk_get_context_default(duk_hthread *thr, duk_idx_t idx, duk_hthread *def_value) {\n\tduk_hthread *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_context(thr, idx);\n\tif (ret != NULL) {\n\t\treturn ret;\n\t}\n\n\treturn def_value;\n}\n\nDUK_EXTERNAL void *duk_get_heapptr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_HEAP_ALLOCATED(tv))) {\n\t\treturn (void *) NULL;\n\t}\n\n\tret = (void *) DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(ret != NULL);\n\treturn ret;\n}\n\nDUK_EXTERNAL void *duk_opt_heapptr(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (duk_check_type_mask(thr, idx, DUK_TYPE_MASK_NONE | DUK_TYPE_MASK_UNDEFINED)) {\n\t\treturn def_value;\n\t}\n\treturn duk_require_heapptr(thr, idx);\n}\n\nDUK_EXTERNAL void *duk_get_heapptr_default(duk_hthread *thr, duk_idx_t idx, void *def_value) {\n\tvoid *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_heapptr(thr, idx);\n\tif (ret != NULL) {\n\t\treturn ret;\n\t}\n\n\treturn def_value;\n}\n\nDUK_EXTERNAL void *duk_require_heapptr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_UNLIKELY(!DUK_TVAL_IS_HEAP_ALLOCATED(tv))) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"heapobject\", DUK_STR_UNEXPECTED_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\tret = (void *) DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(ret != NULL);\n\treturn ret;\n}\n\n/* Internal helper for getting/requiring a duk_hobject with possible promotion. */\nDUK_LOCAL duk_hobject *duk__get_hobject_promote_mask_raw(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tduk_uint_t val_mask;\n\tduk_hobject *res;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tres = duk_get_hobject(thr, idx);  /* common case, not promoted */\n\tif (DUK_LIKELY(res != NULL)) {\n\t\tDUK_ASSERT(res != NULL);\n\t\treturn res;\n\t}\n\n\tval_mask = duk_get_type_mask(thr, idx);\n\tif (val_mask & type_mask) {\n\t\tif (type_mask & DUK_TYPE_MASK_PROMOTE) {\n\t\t\tres = duk_to_hobject(thr, idx);\n\t\t\tDUK_ASSERT(res != NULL);\n\t\t\treturn res;\n\t\t} else {\n\t\t\treturn NULL;  /* accept without promoting */\n\t\t}\n\t}\n\n\tif (type_mask & DUK_TYPE_MASK_THROW) {\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, \"object\", DUK_STR_NOT_OBJECT);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn NULL;\n}\n\n/* Get a duk_hobject * at 'idx'; if the value is not an object but matches the\n * supplied 'type_mask', promote it to an object and return the duk_hobject *.\n * This is useful for call sites which want an object but also accept a plain\n * buffer and/or a lightfunc which gets automatically promoted to an object.\n * Return value is NULL if value is neither an object nor a plain type allowed\n * by the mask.\n */\nDUK_INTERNAL duk_hobject *duk_get_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_PROMOTE);\n}\n\n/* Like duk_get_hobject_promote_mask() but throw a TypeError instead of\n * returning a NULL.\n */\nDUK_INTERNAL duk_hobject *duk_require_hobject_promote_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_THROW | DUK_TYPE_MASK_PROMOTE);\n}\n\n/* Require a duk_hobject * at 'idx'; if the value is not an object but matches the\n * supplied 'type_mask', return a NULL instead.  Otherwise throw a TypeError.\n */\nDUK_INTERNAL duk_hobject *duk_require_hobject_accept_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t type_mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__get_hobject_promote_mask_raw(thr, idx, type_mask | DUK_TYPE_MASK_THROW);\n}\n\nDUK_INTERNAL duk_hobject *duk_get_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_DISABLE(classnum >= 0);  /* unsigned */\n\tDUK_ASSERT(classnum <= DUK_HOBJECT_CLASS_MAX);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(h != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h) != classnum)) {\n\t\th = NULL;\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_require_hobject_with_class(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t classnum) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_DISABLE(classnum >= 0);  /* unsigned */\n\tDUK_ASSERT(classnum <= DUK_HOBJECT_CLASS_MAX);\n\n\th = (duk_hobject *) duk__get_tagged_heaphdr_raw(thr, idx, DUK_TAG_OBJECT);\n\tif (DUK_UNLIKELY(!(h != NULL && DUK_HOBJECT_GET_CLASS_NUMBER(h) == classnum))) {\n\t\tduk_hstring *h_class;\n\t\th_class = DUK_HTHREAD_GET_STRING(thr, DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum));\n\t\tDUK_UNREF(h_class);\n\n\t\tDUK_ERROR_REQUIRE_TYPE_INDEX(thr, idx, (const char *) DUK_HSTRING_GET_DATA(h_class), DUK_STR_UNEXPECTED_TYPE);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn h;\n}\n\nDUK_EXTERNAL duk_size_t duk_get_length(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\tcase DUK_TAG_BOOLEAN:\n\tcase DUK_TAG_POINTER:\n\t\treturn 0;\n#if defined(DUK_USE_PREFER_SIZE)\n\t/* String and buffer have a virtual non-configurable .length property\n\t * which is within size_t range so it can be looked up without specific\n\t * type checks.  Lightfuncs inherit from %NativeFunctionPrototype%\n\t * which provides an inherited .length accessor; it could be overwritten\n\t * to produce unexpected types or values, but just number convert and\n\t * duk_size_t cast for now.\n\t */\n\tcase DUK_TAG_STRING:\n\tcase DUK_TAG_BUFFER:\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tduk_size_t ret;\n\t\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n\t\tret = (duk_size_t) duk_to_number_m1(thr);\n\t\tduk_pop_unsafe(thr);\n\t\treturn ret;\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn (duk_size_t) DUK_HSTRING_GET_CHARLEN(h);\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (duk_size_t) DUK_HBUFFER_GET_SIZE(h);\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* We could look up the length from the lightfunc duk_tval,\n\t\t * but since Duktape 2.2 lightfunc .length comes from\n\t\t * %NativeFunctionPrototype% which can be overridden, so\n\t\t * look up the property explicitly.\n\t\t */\n\t\tduk_size_t ret;\n\t\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n\t\tret = (duk_size_t) duk_to_number_m1(thr);\n\t\tduk_pop_unsafe(thr);\n\t\treturn ret;\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (duk_size_t) duk_hobject_get_length(thr, h);\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* number or 'unused' */\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv) || DUK_TVAL_IS_UNUSED(tv));\n\t\treturn 0;\n\t}\n\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  duk_known_xxx() helpers\n *\n *  Used internally when we're 100% sure that a certain index is valid and\n *  contains an object of a certain type.  For example, if we duk_push_object()\n *  we can then safely duk_known_hobject(thr, -1).  These helpers just assert\n *  for the index and type, and if the assumptions are not valid, memory unsafe\n *  behavior happens.\n */\n\nDUK_LOCAL duk_heaphdr *duk__known_heaphdr(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_heaphdr *h;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tif (idx < 0) {\n\t\ttv = thr->valstack_top + idx;\n\t} else {\n\t\ttv = thr->valstack_bottom + idx;\n\t}\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\tDUK_ASSERT(tv < thr->valstack_top);\n\th = DUK_TVAL_GET_HEAPHDR(tv);\n\tDUK_ASSERT(h != NULL);\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_known_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hstring(thr, idx) != NULL);\n\treturn (duk_hstring *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hobject *duk_known_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hobject(thr, idx) != NULL);\n\treturn (duk_hobject *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hbuffer *duk_known_hbuffer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hbuffer(thr, idx) != NULL);\n\treturn (duk_hbuffer *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_known_hcompfunc(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hcompfunc(thr, idx) != NULL);\n\treturn (duk_hcompfunc *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_known_hnatfunc(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_hnatfunc(thr, idx) != NULL);\n\treturn (duk_hnatfunc *) duk__known_heaphdr(thr, idx);\n}\n\nDUK_EXTERNAL void duk_set_length(duk_hthread *thr, duk_idx_t idx, duk_size_t len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_normalize_index(thr, idx);\n\tduk_push_uint(thr, (duk_uint_t) len);\n\tduk_put_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n}\n\n/*\n *  Conversions and coercions\n *\n *  The conversion/coercions are in-place operations on the value stack.\n *  Some operations are implemented here directly, while others call a\n *  helper in duk_js_ops.c after validating arguments.\n */\n\n/* E5 Section 8.12.8 */\n\nDUK_LOCAL duk_bool_t duk__defaultvalue_coerce_attempt(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t func_stridx) {\n\tif (duk_get_prop_stridx(thr, idx, func_stridx)) {\n\t\t/* [ ... func ] */\n\t\tif (duk_is_callable(thr, -1)) {\n\t\t\tduk_dup(thr, idx);         /* -> [ ... func this ] */\n\t\t\tduk_call_method(thr, 0);     /* -> [ ... retval ] */\n\t\t\tif (duk_is_primitive(thr, -1)) {\n\t\t\t\tduk_replace(thr, idx);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\t/* [ ... retval ]; popped below */\n\t\t}\n\t}\n\tduk_pop_unsafe(thr);  /* [ ... func/retval ] -> [ ... ] */\n\treturn 0;\n}\n\nDUK_EXTERNAL void duk_to_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n}\n\nDUK_EXTERNAL void duk_to_null(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tDUK_TVAL_SET_NULL_UPDREF(thr, tv);  /* side effects */\n}\n\n/* E5 Section 9.1 */\nDUK_LOCAL const char * const duk__toprim_hint_strings[3] = {\n\t\"default\", \"string\", \"number\"\n};\nDUK_LOCAL void duk__to_primitive_helper(duk_hthread *thr, duk_idx_t idx, duk_int_t hint, duk_bool_t check_symbol) {\n\t/* Inline initializer for coercers[] is not allowed by old compilers like BCC. */\n\tduk_small_uint_t coercers[2];\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(hint == DUK_HINT_NONE || hint == DUK_HINT_NUMBER || hint == DUK_HINT_STRING);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\t/* If already primitive, return as is. */\n\tif (!duk_check_type_mask(thr, idx, DUK_TYPE_MASK_OBJECT |\n\t                                   DUK_TYPE_MASK_LIGHTFUNC |\n\t                                   DUK_TYPE_MASK_BUFFER)) {\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* duk_to_string() relies on this behavior */\n\t\treturn;\n\t}\n\n\t/* @@toPrimitive lookup.  Also do for plain buffers and lightfuncs\n\t * which mimic objects.\n\t */\n\tif (check_symbol && duk_get_method_stridx(thr, idx, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE)) {\n\t\tDUK_ASSERT(hint >= 0 && (duk_size_t) hint < sizeof(duk__toprim_hint_strings) / sizeof(const char *));\n\t\tduk_dup(thr, idx);\n\t\tduk_push_string(thr, duk__toprim_hint_strings[hint]);\n\t\tduk_call_method(thr, 1);  /* [ ... method value hint ] -> [ ... res] */\n\t\tif (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT |\n\t                                         DUK_TYPE_MASK_LIGHTFUNC |\n\t\t                                 DUK_TYPE_MASK_BUFFER)) {\n\t\t\tgoto fail;\n\t\t}\n\t\tduk_replace(thr, idx);\n\t\treturn;\n\t}\n\n\t/* Objects are coerced based on E5 specification.\n\t * Lightfuncs are coerced because they behave like\n\t * objects even if they're internally a primitive\n\t * type.  Same applies to plain buffers, which behave\n\t * like ArrayBuffer objects since Duktape 2.x.\n\t */\n\n\t/* Hint magic for Date is unnecessary in ES2015 because of\n\t * Date.prototype[@@toPrimitive].  However, it is needed if\n\t * symbol support is not enabled.\n\t */\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\tif (hint == DUK_HINT_NONE) {\n\t\thint = DUK_HINT_NUMBER;\n\t}\n#else  /* DUK_USE_SYMBOL_BUILTIN */\n\tif (hint == DUK_HINT_NONE) {\n\t\tduk_small_uint_t class_number;\n\n\t\tclass_number = duk_get_class_number(thr, idx);\n\t\tif (class_number == DUK_HOBJECT_CLASS_DATE) {\n\t\t\thint = DUK_HINT_STRING;\n\t\t} else {\n\t\t\thint = DUK_HINT_NUMBER;\n\t\t}\n\t}\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n\n\tcoercers[0] = DUK_STRIDX_VALUE_OF;\n\tcoercers[1] = DUK_STRIDX_TO_STRING;\n\tif (hint == DUK_HINT_STRING) {\n\t\tcoercers[0] = DUK_STRIDX_TO_STRING;\n\t\tcoercers[1] = DUK_STRIDX_VALUE_OF;\n\t}\n\n\tif (duk__defaultvalue_coerce_attempt(thr, idx, coercers[0])) {\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* duk_to_string() relies on this behavior */\n\t\treturn;\n\t}\n\n\tif (duk__defaultvalue_coerce_attempt(thr, idx, coercers[1])) {\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* duk_to_string() relies on this behavior */\n\t\treturn;\n\t}\n\n fail:\n\tDUK_ERROR_TYPE(thr, DUK_STR_TOPRIMITIVE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_to_primitive(duk_hthread *thr, duk_idx_t idx, duk_int_t hint) {\n\tduk__to_primitive_helper(thr, idx, hint, 1 /*check_symbol*/);\n}\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL void duk_to_primitive_ordinary(duk_hthread *thr, duk_idx_t idx, duk_int_t hint) {\n\tduk__to_primitive_helper(thr, idx, hint, 0 /*check_symbol*/);\n}\n#endif\n\n/* E5 Section 9.2 */\nDUK_EXTERNAL duk_bool_t duk_to_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_bool_t val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tval = duk_js_toboolean(tv);\n\tDUK_ASSERT(val == 0 || val == 1);\n\n\t/* Note: no need to re-lookup tv, conversion is side effect free. */\n\tDUK_ASSERT(tv != NULL);\n\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv, val);  /* side effects */\n\treturn val;\n}\n\nDUK_INTERNAL duk_bool_t duk_to_boolean_top_pop(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_bool_t val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tval = duk_js_toboolean(tv);\n\tDUK_ASSERT(val == 0 || val == 1);\n\n\tduk_pop_unsafe(thr);\n\treturn val;\n}\n\nDUK_EXTERNAL duk_double_t duk_to_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_double_t d;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: No need to normalize; the whole operation could be inlined here to\n\t * avoid 'tv' re-lookup.\n\t */\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\td = duk_js_tonumber(thr, tv);  /* XXX: fastint coercion? now result will always be a non-fastint */\n\n\t/* ToNumber() may have side effects so must relookup 'tv'. */\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d);  /* side effects */\n\treturn d;\n}\n\nDUK_INTERNAL duk_double_t duk_to_number_m1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_number(thr, -1);\n}\nDUK_INTERNAL duk_double_t duk_to_number_m2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_number(thr, -2);\n}\n\nDUK_INTERNAL duk_double_t duk_to_number_tval(duk_hthread *thr, duk_tval *tv) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_double_t res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_tval(thr, tv);\n\tres = duk_to_number_m1(thr);\n\tduk_pop_unsafe(thr);\n\treturn res;\n#else\n\tduk_double_t res;\n\tduk_tval *tv_dst;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ASSERT_SPACE();\n\n\ttv_dst = thr->valstack_top++;\n\tDUK_TVAL_SET_TVAL(tv_dst, tv);\n\tDUK_TVAL_INCREF(thr, tv_dst);  /* decref not necessary */\n\tres = duk_to_number_m1(thr);  /* invalidates tv_dst */\n\n\ttv_dst = --thr->valstack_top;\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_dst));\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv_dst));  /* plain number */\n\tDUK_TVAL_SET_UNDEFINED(tv_dst);  /* valstack init policy */\n\n\treturn res;\n#endif\n}\n\n/* XXX: combine all the integer conversions: they share everything\n * but the helper function for coercion.\n */\n\ntypedef duk_double_t (*duk__toint_coercer)(duk_hthread *thr, duk_tval *tv);\n\nDUK_LOCAL duk_double_t duk__to_int_uint_helper(duk_hthread *thr, duk_idx_t idx, duk__toint_coercer coerce_func) {\n\tduk_tval *tv;\n\tduk_double_t d;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_FASTINT)\n\t/* If argument is a fastint, guarantee that it remains one.\n\t * There's no downgrade check for other cases.\n\t */\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\t/* XXX: Unnecessary conversion back and forth. */\n\t\treturn (duk_double_t) DUK_TVAL_GET_FASTINT(tv);\n\t}\n#endif\n\td = coerce_func(thr, tv);\n\n\t/* XXX: fastint? */\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv, d);  /* side effects */\n\treturn d;\n}\n\nDUK_EXTERNAL duk_int_t duk_to_int(duk_hthread *thr, duk_idx_t idx) {\n\t/* Value coercion (in stack): ToInteger(), E5 Section 9.4,\n\t * API return value coercion: custom.\n\t */\n\tDUK_ASSERT_API_ENTRY(thr);\n\t(void) duk__to_int_uint_helper(thr, idx, duk_js_tointeger);\n\treturn (duk_int_t) duk__api_coerce_d2i(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_uint_t duk_to_uint(duk_hthread *thr, duk_idx_t idx) {\n\t/* Value coercion (in stack): ToInteger(), E5 Section 9.4,\n\t * API return value coercion: custom.\n\t */\n\tDUK_ASSERT_API_ENTRY(thr);\n\t(void) duk__to_int_uint_helper(thr, idx, duk_js_tointeger);\n\treturn (duk_uint_t) duk__api_coerce_d2ui(thr, idx, 0 /*def_value*/, 0 /*require*/);\n}\n\nDUK_EXTERNAL duk_int32_t duk_to_int32(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_int32_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tret = duk_js_toint32(thr, tv);\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_I32_UPDREF(thr, tv, ret);  /* side effects */\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_uint32_t duk_to_uint32(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_uint32_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tret = duk_js_touint32(thr, tv);\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_U32_UPDREF(thr, tv, ret);  /* side effects */\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_uint16_t duk_to_uint16(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_uint16_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tret = duk_js_touint16(thr, tv);\n\n\t/* Relookup in case coerce_func() has side effects, e.g. ends up coercing an object */\n\ttv = duk_require_tval(thr, idx);\n\tDUK_TVAL_SET_U32_UPDREF(thr, tv, ret);  /* side effects */\n\treturn ret;\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Special coercion for Uint8ClampedArray. */\nDUK_INTERNAL duk_uint8_t duk_to_uint8clamped(duk_hthread *thr, duk_idx_t idx) {\n\tduk_double_t d;\n\tduk_double_t t;\n\tduk_uint8_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: Simplify this algorithm, should be possible to come up with\n\t * a shorter and faster algorithm by inspecting IEEE representation\n\t * directly.\n\t */\n\n\td = duk_to_number(thr, idx);\n\tif (d <= 0.0) {\n\t\treturn 0;\n\t} else if (d >= 255) {\n\t\treturn 255;\n\t} else if (DUK_ISNAN(d)) {\n\t\t/* Avoid NaN-to-integer coercion as it is compiler specific. */\n\t\treturn 0;\n\t}\n\n\tt = d - DUK_FLOOR(d);\n\tif (t == 0.5) {\n\t\t/* Exact halfway, round to even. */\n\t\tret = (duk_uint8_t) d;\n\t\tret = (ret + 1) & 0xfe;  /* Example: d=3.5, t=0.5 -> ret = (3 + 1) & 0xfe = 4 & 0xfe = 4\n\t\t                          * Example: d=4.5, t=0.5 -> ret = (4 + 1) & 0xfe = 5 & 0xfe = 4\n\t\t                          */\n\t} else {\n\t\t/* Not halfway, round to nearest. */\n\t\tret = (duk_uint8_t) (d + 0.5);\n\t}\n\treturn ret;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_EXTERNAL const char *duk_to_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_to_string(thr, idx);\n\tDUK_ASSERT(duk_is_string(thr, idx));\n\treturn duk_require_lstring(thr, idx, out_len);\n}\n\nDUK_LOCAL duk_ret_t duk__safe_to_string_raw(duk_hthread *thr, void *udata) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(udata);\n\n\t(void) duk_to_string(thr, -1);\n\treturn 1;\n}\n\nDUK_EXTERNAL const char *duk_safe_to_lstring(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\t/* We intentionally ignore the duk_safe_call() return value and only\n\t * check the output type.  This way we don't also need to check that\n\t * the returned value is indeed a string in the success case.\n\t */\n\n\tduk_dup(thr, idx);\n\t(void) duk_safe_call(thr, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\tif (!duk_is_string(thr, -1)) {\n\t\t/* Error: try coercing error to string once. */\n\t\t(void) duk_safe_call(thr, duk__safe_to_string_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\t\tif (!duk_is_string(thr, -1)) {\n\t\t\t/* Double error */\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_ERROR);\n\t\t} else {\n\t\t\t;\n\t\t}\n\t} else {\n\t\t/* String; may be a symbol, accepted. */\n\t\t;\n\t}\n\tDUK_ASSERT(duk_is_string(thr, -1));\n\n\tduk_replace(thr, idx);\n\tDUK_ASSERT(duk_get_string(thr, idx) != NULL);\n\treturn duk_get_lstring(thr, idx, out_len);\n}\n\nDUK_EXTERNAL const char *duk_to_stacktrace(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tidx = duk_require_normalize_index(thr, idx);\n\n\t/* The expected argument to the call is an Error object.  The stack\n\t * trace is extracted without an inheritance-based instanceof check\n\t * so that one can also extract the stack trace of a foreign error\n\t * created in another Realm.  Accept only a string .stack property.\n\t */\n\tif (duk_is_object(thr, idx)) {\n\t\t(void) duk_get_prop_string(thr, idx, \"stack\");\n\t\tif (duk_is_string(thr, -1)) {\n\t\t\tduk_replace(thr, idx);\n\t\t} else {\n\t\t\tduk_pop(thr);\n\t\t}\n\t}\n\n\treturn duk_to_string(thr, idx);\n}\n\nDUK_LOCAL duk_ret_t duk__safe_to_stacktrace_raw(duk_hthread *thr, void *udata) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(udata);\n\n\t(void) duk_to_stacktrace(thr, -1);\n\n\treturn 1;\n}\n\nDUK_EXTERNAL const char *duk_safe_to_stacktrace(duk_hthread *thr, duk_idx_t idx) {\n\tduk_int_t rc;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tidx = duk_require_normalize_index(thr, idx);\n\n\tduk_dup(thr, idx);\n\trc = duk_safe_call(thr, duk__safe_to_stacktrace_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\tif (rc != 0) {\n\t\t/* Coercion failed.  Try to coerce the coercion itself error\n\t\t * to a stack trace once.  If that also fails, return a fixed,\n\t\t * preallocated 'Error' string to avoid potential infinite loop.\n\t\t */\n\t\trc = duk_safe_call(thr, duk__safe_to_stacktrace_raw, NULL /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\t\tif (rc != 0) {\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_ERROR);\n\t\t}\n\t}\n\tduk_replace(thr, idx);\n\n\treturn duk_get_string(thr, idx);\n}\n\nDUK_INTERNAL duk_hstring *duk_to_property_key_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_to_primitive(thr, idx, DUK_HINT_STRING);  /* needed for e.g. Symbol objects */\n\th = duk_get_hstring(thr, idx);\n\tif (h == NULL) {\n\t\t/* The \"is string?\" check may seem unnecessary, but as things\n\t\t * are duk_to_hstring() invokes ToString() which fails for\n\t\t * symbols.  But since symbols are already strings for Duktape\n\t\t * C API, we check for that before doing the coercion.\n\t\t */\n\t\th = duk_to_hstring(thr, idx);\n\t}\n\tDUK_ASSERT(h != NULL);\n\treturn h;\n}\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* only needed by debugger for now */\nDUK_INTERNAL duk_hstring *duk_safe_to_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_safe_to_string(thr, idx);\n\tDUK_ASSERT(duk_is_string(thr, idx));\n\tDUK_ASSERT(duk_get_hstring(thr, idx) != NULL);\n\treturn duk_known_hstring(thr, idx);\n}\n#endif\n\n/* Push Object.prototype.toString() output for 'tv'. */\n#if 0  /* See XXX note why this variant doesn't work. */\nDUK_INTERNAL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects) {\n\tduk_uint_t stridx_bidx = 0;  /* (prototype_bidx << 16) + default_tag_stridx */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Conceptually for any non-undefined/null value we should do a\n\t * ToObject() coercion and look up @@toStringTag (from the object\n\t * prototype) to see if a custom tag should be used.  Avoid the\n\t * actual conversion by doing a prototype lookup without the object\n\t * coercion.  However, see problem below.\n\t */\n\n\tduk_push_literal(thr, \"[object \");  /* -> [ ... \"[object\" ] */\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:  /* Treat like 'undefined', shouldn't happen. */\n\tcase DUK_TAG_UNDEFINED: {\n\t\tstridx_bidx = DUK_STRIDX_UC_UNDEFINED;\n\t\tgoto use_stridx;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tstridx_bidx = DUK_STRIDX_UC_NULL;\n\t\tgoto use_stridx;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tstridx_bidx = (DUK_BIDX_BOOLEAN_PROTOTYPE << 16) + DUK_STRIDX_UC_BOOLEAN;\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tstridx_bidx = (DUK_BIDX_POINTER_PROTOTYPE << 16) + DUK_STRIDX_UC_POINTER;\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tstridx_bidx = (DUK_BIDX_FUNCTION_PROTOTYPE << 16) + DUK_STRIDX_UC_FUNCTION;\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\t/* Even without DUK_USE_SYMBOL_BUILTIN the Symbol\n\t\t\t * prototype exists so we can lookup @@toStringTag\n\t\t\t * and provide [object Symbol] for symbol values\n\t\t\t * created from C code.\n\t\t\t */\n\t\t\tstridx_bidx = (DUK_BIDX_SYMBOL_PROTOTYPE << 16) + DUK_STRIDX_UC_SYMBOL;\n\t\t} else {\n\t\t\tstridx_bidx = (DUK_BIDX_STRING_PROTOTYPE << 16) + DUK_STRIDX_UC_STRING;\n\t\t}\n\t\tgoto use_proto_bidx;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_push_tval(thr, tv);\n\t\tstridx_bidx = 0xffffffffUL;  /* Marker value. */\n\t\tgoto use_pushed_object;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\tstridx_bidx = (DUK_BIDX_UINT8ARRAY_PROTOTYPE << 16) + DUK_STRIDX_UINT8_ARRAY;\n\t\tgoto use_proto_bidx;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\t/* Fall through to generic number case. */\n#endif\n\tdefault: {\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));  /* number (maybe fastint) */\n\t\tstridx_bidx = (DUK_BIDX_NUMBER_PROTOTYPE << 16) + DUK_STRIDX_UC_NUMBER;\n\t\tgoto use_proto_bidx;\n\t}\n\t}\n\tDUK_ASSERT(0);  /* Never here. */\n\n use_proto_bidx:\n\tDUK_ASSERT_BIDX_VALID((stridx_bidx >> 16) & 0xffffUL);\n\tduk_push_hobject(thr, thr->builtins[(stridx_bidx >> 16) & 0xffffUL]);\n\t/* Fall through. */\n\n use_pushed_object:\n\t/* [ ... \"[object\" obj ] */\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t/* XXX: better handling with avoid_side_effects == 1; lookup tval\n\t * without Proxy or getter side effects, and use it in sanitized\n\t * form if it's a string.\n\t */\n\tif (!avoid_side_effects) {\n\t\t/* XXX: The problem with using the prototype object as the\n\t\t * lookup base is that if @@toStringTag is a getter, its\n\t\t * 'this' binding must be the ToObject() coerced input value,\n\t\t * not the prototype object of the type.\n\t\t */\n\t\t(void) duk_get_prop_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG);\n\t\tif (duk_is_string_notsymbol(thr, -1)) {\n\t\t\tduk_remove_m2(thr);\n\t\t\tgoto finish;\n\t\t}\n\t\tduk_pop_unsafe(thr);\n\t}\n#endif\n\n\tif (stridx_bidx == 0xffffffffUL) {\n\t\tduk_hobject *h_obj;\n\t\tduk_small_uint_t classnum;\n\n\t\th_obj = duk_known_hobject(thr, -1);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tclassnum = DUK_HOBJECT_GET_CLASS_NUMBER(h_obj);\n\t\tstridx_bidx = DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum);\n\t} else {\n\t\t/* stridx_bidx already has the desired fallback stridx. */\n\t\t;\n\t}\n\tduk_pop_unsafe(thr);\n\t/* Fall through. */\n\n use_stridx:\n\t/* [ ... \"[object\" ] */\n\tduk_push_hstring_stridx(thr, stridx_bidx & 0xffffUL);\n\n finish:\n\t/* [ ... \"[object\" tag ] */\n\tduk_push_literal(thr, \"]\");\n\tduk_concat(thr, 3);  /* [ ... \"[object\" tag \"]\" ] -> [ ... res ] */\n}\n#endif  /* 0 */\n\nDUK_INTERNAL void duk_push_class_string_tval(duk_hthread *thr, duk_tval *tv, duk_bool_t avoid_side_effects) {\n\tduk_hobject *h_obj;\n\tduk_small_uint_t classnum;\n\tduk_small_uint_t stridx;\n\tduk_tval tv_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\t/* Stabilize 'tv', duk_push_literal() may trigger side effects. */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv);\n\ttv = &tv_tmp;\n\n\t/* Conceptually for any non-undefined/null value we should do a\n\t * ToObject() coercion and look up @@toStringTag (from the object\n\t * prototype) to see if a custom result should be used.  We'd like to\n\t * avoid the actual conversion, but even for primitive types the\n\t * prototype may have @@toStringTag.  What's worse, the @@toStringTag\n\t * property may be a getter that must get the object coerced value\n\t * (not the prototype) as its 'this' binding.\n\t *\n\t * For now, do an actual object coercion.  This could be avoided by\n\t * doing a side effect free lookup to see if a getter would be invoked.\n\t * If not, the value can be read directly and the object coercion could\n\t * be avoided.  This may not be worth it in practice, because\n\t * Object.prototype.toString() is usually not performance critical.\n\t */\n\n\tduk_push_literal(thr, \"[object \");  /* -> [ ... \"[object\" ] */\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:  /* Treat like 'undefined', shouldn't happen. */\n\tcase DUK_TAG_UNDEFINED: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_UNDEFINED);\n\t\tgoto finish;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_NULL);\n\t\tgoto finish;\n\t}\n\t}\n\n\tduk_push_tval(thr, tv);\n\ttv = NULL;  /* Invalidated by ToObject(). */\n\tduk_to_object(thr, -1);\n\n\t/* [ ... \"[object\" obj ] */\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t/* XXX: better handling with avoid_side_effects == 1; lookup tval\n\t * without Proxy or getter side effects, and use it in sanitized\n\t * form if it's a string.\n\t */\n\tif (!avoid_side_effects) {\n\t\t(void) duk_get_prop_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG);\n\t\tif (duk_is_string_notsymbol(thr, -1)) {\n\t\t\tduk_remove_m2(thr);\n\t\t\tgoto finish;\n\t\t}\n\t\tduk_pop_unsafe(thr);\n\t}\n#else\n\tDUK_UNREF(avoid_side_effects);\n#endif\n\n\th_obj = duk_known_hobject(thr, -1);\n\tDUK_ASSERT(h_obj != NULL);\n\tclassnum = DUK_HOBJECT_GET_CLASS_NUMBER(h_obj);\n\tstridx = DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(classnum);\n\tduk_pop_unsafe(thr);\n\tduk_push_hstring_stridx(thr, stridx);\n\n finish:\n\t/* [ ... \"[object\" tag ] */\n\tduk_push_literal(thr, \"]\");\n\tduk_concat(thr, 3);  /* [ ... \"[object\" tag \"]\" ] -> [ ... res ] */\n}\n\n/* XXX: other variants like uint, u32 etc */\nDUK_INTERNAL duk_int_t duk_to_int_clamped_raw(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval, duk_bool_t *out_clamped) {\n\tduk_tval *tv;\n\tduk_tval tv_tmp;\n\tduk_double_t d, dmin, dmax;\n\tduk_int_t res;\n\tduk_bool_t clamped = 0;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\td = duk_js_tointeger(thr, tv);  /* E5 Section 9.4, ToInteger() */\n\n\tdmin = (duk_double_t) minval;\n\tdmax = (duk_double_t) maxval;\n\n\tif (d < dmin) {\n\t\tclamped = 1;\n\t\tres = minval;\n\t\td = dmin;\n\t} else if (d > dmax) {\n\t\tclamped = 1;\n\t\tres = maxval;\n\t\td = dmax;\n\t} else {\n\t\tres = (duk_int_t) d;\n\t}\n\tDUK_UNREF(d);  /* SCANBUILD: with suitable dmin/dmax limits 'd' is unused */\n\t/* 'd' and 'res' agree here */\n\n\t/* Relookup in case duk_js_tointeger() ends up e.g. coercing an object. */\n\ttv = duk_get_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);  /* not popped by side effect */\n\tDUK_TVAL_SET_TVAL(&tv_tmp, tv);\n#if defined(DUK_USE_FASTINT)\n#if (DUK_INT_MAX <= 0x7fffffffL)\n\tDUK_TVAL_SET_I32(tv, res);\n#else\n\t/* Clamping needed if duk_int_t is 64 bits. */\n\tif (res >= DUK_FASTINT_MIN && res <= DUK_FASTINT_MAX) {\n\t\tDUK_TVAL_SET_FASTINT(tv, res);\n\t} else {\n\t\tDUK_TVAL_SET_NUMBER(tv, d);\n\t}\n#endif\n#else\n\tDUK_TVAL_SET_NUMBER(tv, d);  /* no need to incref */\n#endif\n\tDUK_TVAL_DECREF(thr, &tv_tmp);  /* side effects */\n\n\tif (out_clamped) {\n\t\t*out_clamped = clamped;\n\t} else {\n\t\t/* coerced value is updated to value stack even when RangeError thrown */\n\t\tif (clamped) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_NUMBER_OUTSIDE_RANGE);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t}\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_int_t duk_to_int_clamped(duk_hthread *thr, duk_idx_t idx, duk_idx_t minval, duk_idx_t maxval) {\n\tduk_bool_t dummy;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_to_int_clamped_raw(thr, idx, minval, maxval, &dummy);\n}\n\nDUK_INTERNAL duk_int_t duk_to_int_check_range(duk_hthread *thr, duk_idx_t idx, duk_int_t minval, duk_int_t maxval) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_int_clamped_raw(thr, idx, minval, maxval, NULL);  /* out_clamped==NULL -> RangeError if outside range */\n}\n\nDUK_EXTERNAL const char *duk_to_string(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_LC_UNDEFINED);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_LC_NULL);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tif (DUK_TVAL_GET_BOOLEAN(tv)) {\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_TRUE);\n\t\t} else {\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_FALSE);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\t/* Nop for actual strings, TypeError for Symbols.\n\t\t * Because various internals rely on ToString() coercion of\n\t\t * internal strings, -allow- (NOP) string coercion for hidden\n\t\t * symbols.\n\t\t */\n#if 1\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CANNOT_STRING_COERCE_SYMBOL);\n\t\t\tDUK_WO_NORETURN(goto skip_replace;);\n\t\t} else {\n\t\t\tgoto skip_replace;\n\t\t}\n#else\n\t\tgoto skip_replace;\n#endif\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: /* Go through Uint8Array.prototype.toString() for coercion. */\n\tcase DUK_TAG_OBJECT: {\n\t\t/* Plain buffers: go through ArrayBuffer.prototype.toString()\n\t\t * for coercion.\n\t\t *\n\t\t * Symbol objects: duk_to_primitive() results in a plain symbol\n\t\t * value, and duk_to_string() then causes a TypeError.\n\t\t */\n\t\tduk_to_primitive(thr, idx, DUK_HINT_STRING);\n\t\tDUK_ASSERT(!duk_is_buffer(thr, idx));  /* ToPrimitive() must guarantee */\n\t\tDUK_ASSERT(!duk_is_object(thr, idx));\n\t\treturn duk_to_string(thr, idx);  /* Note: recursive call */\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tvoid *ptr = DUK_TVAL_GET_POINTER(tv);\n\t\tif (ptr != NULL) {\n\t\t\tduk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) ptr);\n\t\t} else {\n\t\t\t/* Represent a null pointer as 'null' to be consistent with\n\t\t\t * the JX format variant.  Native '%p' format for a NULL\n\t\t\t * pointer may be e.g. '(nil)'.\n\t\t\t */\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_LC_NULL);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Should match Function.prototype.toString() */\n\t\tduk_push_lightfunc_tostring(thr, tv);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tduk_push_tval(thr, tv);\n\t\tduk_numconv_stringify(thr,\n\t\t                      10 /*radix*/,\n\t\t                      0 /*precision:shortest*/,\n\t\t                      0 /*force_exponential*/);\n\t\tbreak;\n\t}\n\t}\n\n\tduk_replace(thr, idx);\n\n skip_replace:\n\tDUK_ASSERT(duk_is_string(thr, idx));\n\treturn duk_require_string(thr, idx);\n}\n\nDUK_INTERNAL duk_hstring *duk_to_hstring(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_to_string(thr, idx);\n\tret = duk_get_hstring(thr, idx);\n\tDUK_ASSERT(ret != NULL);\n\treturn ret;\n}\n\nDUK_INTERNAL duk_hstring *duk_to_hstring_m1(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_to_hstring(thr, -1);\n}\n\nDUK_INTERNAL duk_hstring *duk_to_hstring_acceptsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tret = duk_get_hstring(thr, idx);\n\tif (DUK_UNLIKELY(ret && DUK_HSTRING_HAS_SYMBOL(ret))) {\n\t\treturn ret;\n\t}\n\treturn duk_to_hstring(thr, idx);\n}\n\n/* Convert a plain buffer or any buffer object into a string, using the buffer\n * bytes 1:1 in the internal string representation.  For views the active byte\n * slice (not element slice interpreted as an initializer) is used.  This is\n * necessary in Duktape 2.x because ToString(plainBuffer) no longer creates a\n * string with the same bytes as in the buffer but rather (usually)\n * '[object ArrayBuffer]'.\n */\nDUK_EXTERNAL const char *duk_buffer_to_string(duk_hthread *thr, duk_idx_t idx) {\n\tvoid *ptr_src;\n\tduk_size_t len;\n\tconst char *res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\tptr_src = duk_require_buffer_data(thr, idx, &len);\n\tDUK_ASSERT(ptr_src != NULL || len == 0);\n\n\tres = duk_push_lstring(thr, (const char *) ptr_src, len);\n\tduk_replace(thr, idx);\n\treturn res;\n}\n\nDUK_EXTERNAL void *duk_to_buffer_raw(duk_hthread *thr, duk_idx_t idx, duk_size_t *out_size, duk_uint_t mode) {\n\tduk_hbuffer *h_buf;\n\tconst duk_uint8_t *src_data;\n\tduk_size_t src_size;\n\tduk_uint8_t *dst_data;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\n\th_buf = duk_get_hbuffer(thr, idx);\n\tif (h_buf != NULL) {\n\t\t/* Buffer is kept as is, with the fixed/dynamic nature of the\n\t\t * buffer only changed if requested.  An external buffer\n\t\t * is converted into a non-external dynamic buffer in a\n\t\t * duk_to_dynamic_buffer() call.\n\t\t */\n\t\tduk_uint_t tmp;\n\t\tduk_uint8_t *tmp_ptr;\n\n\t\ttmp_ptr = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_buf);\n\t\tsrc_data = (const duk_uint8_t *) tmp_ptr;\n\t\tsrc_size = DUK_HBUFFER_GET_SIZE(h_buf);\n\n\t\ttmp = (DUK_HBUFFER_HAS_DYNAMIC(h_buf) ? DUK_BUF_MODE_DYNAMIC : DUK_BUF_MODE_FIXED);\n\t\tif ((tmp == mode && !DUK_HBUFFER_HAS_EXTERNAL(h_buf)) ||\n\t\t    mode == DUK_BUF_MODE_DONTCARE) {\n\t\t\t/* Note: src_data may be NULL if input is a zero-size\n\t\t\t * dynamic buffer.\n\t\t\t */\n\t\t\tdst_data = tmp_ptr;\n\t\t\tgoto skip_copy;\n\t\t}\n\t} else {\n\t\t/* Non-buffer value is first ToString() coerced, then converted\n\t\t * to a buffer (fixed buffer is used unless a dynamic buffer is\n\t\t * explicitly requested).  Symbols are rejected with a TypeError.\n\t\t * XXX: C API could maybe allow symbol-to-buffer coercion?\n\t\t */\n\t\tsrc_data = (const duk_uint8_t *) duk_to_lstring(thr, idx, &src_size);\n\t}\n\n\tdst_data = (duk_uint8_t *) duk_push_buffer(thr, src_size, (mode == DUK_BUF_MODE_DYNAMIC) /*dynamic*/);\n\t/* dst_data may be NULL if size is zero. */\n\tduk_memcpy_unsafe((void *) dst_data, (const void *) src_data, (size_t) src_size);\n\n\tduk_replace(thr, idx);\n skip_copy:\n\n\tif (out_size) {\n\t\t*out_size = src_size;\n\t}\n\treturn dst_data;\n}\n\nDUK_EXTERNAL void *duk_to_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tvoid *res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\tcase DUK_TAG_BOOLEAN:\n\t\tres = NULL;\n\t\tbreak;\n\tcase DUK_TAG_POINTER:\n\t\tres = DUK_TVAL_GET_POINTER(tv);\n\t\tbreak;\n\tcase DUK_TAG_STRING:\n\tcase DUK_TAG_OBJECT:\n\tcase DUK_TAG_BUFFER:\n\t\t/* Heap allocated: return heap pointer which is NOT useful\n\t\t * for the caller, except for debugging.\n\t\t */\n\t\tres = (void *) DUK_TVAL_GET_HEAPHDR(tv);\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\t/* Function pointers do not always cast correctly to void *\n\t\t * (depends on memory and segmentation model for instance),\n\t\t * so they coerce to NULL.\n\t\t */\n\t\tres = NULL;\n\t\tbreak;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tres = NULL;\n\t\tbreak;\n\t}\n\n\tduk_push_pointer(thr, res);\n\tduk_replace(thr, idx);\n\treturn res;\n}\n\nDUK_LOCAL void duk__push_func_from_lightfunc(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags) {\n\tduk_idx_t nargs;\n\tduk_uint_t flags = 0;   /* shared flags for a subset of types */\n\tduk_small_uint_t lf_len;\n\tduk_hnatfunc *nf;\n\n\tnargs = (duk_idx_t) DUK_LFUNC_FLAGS_GET_NARGS(lf_flags);\n\tif (nargs == DUK_LFUNC_NARGS_VARARGS) {\n\t\tnargs = (duk_idx_t) DUK_VARARGS;\n\t}\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\t(void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE);\n\n\tlf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags);\n\tif ((duk_idx_t) lf_len != nargs) {\n\t\t/* Explicit length is only needed if it differs from 'nargs'. */\n\t\tduk_push_int(thr, (duk_int_t) lf_len);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tduk_push_lightfunc_name_raw(thr, func, lf_flags);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n#endif\n\n\tnf = duk_known_hnatfunc(thr, -1);\n\tnf->magic = (duk_int16_t) DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags);\n}\n\nDUK_EXTERNAL void duk_to_object(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_uint_t flags = 0;   /* shared flags for a subset of types */\n\tduk_small_int_t proto = 0;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);\n\ttv = DUK_GET_TVAL_POSIDX(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n#if !defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tcase DUK_TAG_BUFFER:  /* With no bufferobject support, don't object coerce. */\n#endif\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL: {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_OBJECT_COERCIBLE);\n\t\tDUK_WO_NORETURN(return;);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_BOOLEAN);\n\t\tproto = DUK_BIDX_BOOLEAN_PROTOTYPE;\n\t\tgoto create_object;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_SYMBOL);\n\t\t\tproto = DUK_BIDX_SYMBOL_PROTOTYPE;\n\t\t} else {\n\t\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t\t        DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ |\n\t\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_STRING);\n\t\t\tproto = DUK_BIDX_STRING_PROTOTYPE;\n\t\t}\n\t\tgoto create_object;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\t/* nop */\n\t\tbreak;\n\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tcase DUK_TAG_BUFFER: {\n\t\t/* A plain buffer object coerces to a full ArrayBuffer which\n\t\t * is not fully transparent behavior (ToObject() should be a\n\t\t * nop for an object).  This behavior matches lightfuncs which\n\t\t * also coerce to an equivalent Function object.  There are\n\t\t * also downsides to defining ToObject(plainBuffer) as a no-op;\n\t\t * for example duk_to_hobject() could result in a NULL pointer.\n\t\t */\n\t\tduk_hbuffer *h_buf;\n\n\t\th_buf = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h_buf != NULL);\n\t\tduk_hbufobj_push_uint8array_from_plain(thr, h_buf);\n\t\tgoto replace_value;\n\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\tcase DUK_TAG_POINTER: {\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER);\n\t\tproto = DUK_BIDX_POINTER_PROTOTYPE;\n\t\tgoto create_object;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Lightfunc coerces to a Function instance with concrete\n\t\t * properties.  Since 'length' is virtual for Duktape/C\n\t\t * functions, don't need to define that.  The result is made\n\t\t * extensible to mimic what happens to strings in object\n\t\t * coercion:\n\t\t *\n\t\t *   > Object.isExtensible(Object('foo'))\n\t\t *   true\n\t\t */\n\t\tduk_small_uint_t lf_flags;\n\t\tduk_c_function func;\n\n\t\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);\n\t\tduk__push_func_from_lightfunc(thr, func, lf_flags);\n\t\tgoto replace_value;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_NUMBER);\n\t\tproto = DUK_BIDX_NUMBER_PROTOTYPE;\n\t\tgoto create_object;\n\t}\n\t}\n\tDUK_ASSERT(duk_is_object(thr, idx));\n\treturn;\n\n create_object:\n\t(void) duk_push_object_helper(thr, flags, proto);\n\n\t/* Note: Boolean prototype's internal value property is not writable,\n\t * but duk_xdef_prop_stridx() disregards the write protection.  Boolean\n\t * instances are immutable.\n\t *\n\t * String and buffer special behaviors are already enabled which is not\n\t * ideal, but a write to the internal value is not affected by them.\n\t */\n\tduk_dup(thr, idx);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\n replace_value:\n\tduk_replace(thr, idx);\n\tDUK_ASSERT(duk_is_object(thr, idx));\n}\n\nDUK_INTERNAL duk_hobject *duk_to_hobject(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_to_object(thr, idx);\n\tret = duk_known_hobject(thr, idx);\n\treturn ret;\n}\n\n/*\n *  Type checking\n */\n\nDUK_LOCAL duk_bool_t duk__tag_check(duk_hthread *thr, duk_idx_t idx, duk_small_uint_t tag) {\n\tduk_tval *tv;\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\treturn (DUK_TVAL_GET_TAG(tv) == tag);\n}\n\nDUK_LOCAL duk_bool_t duk__obj_flag_any_default_false(duk_hthread *thr, duk_idx_t idx, duk_uint_t flag_mask) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, idx);\n\tif (obj) {\n\t\treturn (DUK_HEAPHDR_CHECK_FLAG_BITS((duk_heaphdr *) obj, flag_mask) ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_INTERNAL duk_int_t duk_get_type_tval(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_PACKED_TVAL)\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:\n\t\treturn DUK_TYPE_NONE;\n\tcase DUK_TAG_UNDEFINED:\n\t\treturn DUK_TYPE_UNDEFINED;\n\tcase DUK_TAG_NULL:\n\t\treturn DUK_TYPE_NULL;\n\tcase DUK_TAG_BOOLEAN:\n\t\treturn DUK_TYPE_BOOLEAN;\n\tcase DUK_TAG_STRING:\n\t\treturn DUK_TYPE_STRING;\n\tcase DUK_TAG_OBJECT:\n\t\treturn DUK_TYPE_OBJECT;\n\tcase DUK_TAG_BUFFER:\n\t\treturn DUK_TYPE_BUFFER;\n\tcase DUK_TAG_POINTER:\n\t\treturn DUK_TYPE_POINTER;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\treturn DUK_TYPE_LIGHTFUNC;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* Note: number has no explicit tag (in 8-byte representation) */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\treturn DUK_TYPE_NUMBER;\n\t}\n#else  /* DUK_USE_PACKED_TVAL */\n\tDUK_ASSERT(DUK_TVAL_IS_VALID_TAG(tv));\n\tDUK_ASSERT(sizeof(duk__type_from_tag) / sizeof(duk_uint_t) == DUK_TAG_MAX - DUK_TAG_MIN + 1);\n\treturn (duk_int_t) duk__type_from_tag[DUK_TVAL_GET_TAG(tv) - DUK_TAG_MIN];\n#endif  /* DUK_USE_PACKED_TVAL */\n}\n\nDUK_EXTERNAL duk_int_t duk_get_type(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\treturn duk_get_type_tval(tv);\n}\n\n#if defined(DUK_USE_VERBOSE_ERRORS) && defined(DUK_USE_PARANOID_ERRORS)\nDUK_LOCAL const char * const duk__type_names[] = {\n\t\"none\",\n\t\"undefined\",\n\t\"null\",\n\t\"boolean\",\n\t\"number\",\n\t\"string\",\n\t\"object\",\n\t\"buffer\",\n\t\"pointer\",\n\t\"lightfunc\"\n};\n\nDUK_INTERNAL const char *duk_get_type_name(duk_hthread *thr, duk_idx_t idx) {\n\tduk_int_t type_tag;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttype_tag = duk_get_type(thr, idx);\n\tDUK_ASSERT(type_tag >= DUK_TYPE_MIN && type_tag <= DUK_TYPE_MAX);\n\tDUK_ASSERT(DUK_TYPE_MIN == 0 && sizeof(duk__type_names) / sizeof(const char *) == DUK_TYPE_MAX + 1);\n\n\treturn duk__type_names[type_tag];\n}\n#endif  /* DUK_USE_VERBOSE_ERRORS && DUK_USE_PARANOID_ERRORS */\n\nDUK_INTERNAL duk_small_uint_t duk_get_class_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_OBJECT:\n\t\tobj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(obj != NULL);\n\t\treturn DUK_HOBJECT_GET_CLASS_NUMBER(obj);\n\tcase DUK_TAG_BUFFER:\n\t\t/* Buffers behave like Uint8Array objects. */\n\t\treturn DUK_HOBJECT_CLASS_UINT8ARRAY;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\t/* Lightfuncs behave like Function objects. */\n\t\treturn DUK_HOBJECT_CLASS_FUNCTION;\n\tdefault:\n\t\t/* Primitive or UNUSED, no class number. */\n\t\treturn DUK_HOBJECT_CLASS_NONE;\n\t}\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_type(duk_hthread *thr, duk_idx_t idx, duk_int_t type) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn (duk_get_type(thr, idx) == type) ? 1 : 0;\n}\n\nDUK_INTERNAL duk_uint_t duk_get_type_mask_tval(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n\n#if defined(DUK_USE_PACKED_TVAL)\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNUSED:\n\t\treturn DUK_TYPE_MASK_NONE;\n\tcase DUK_TAG_UNDEFINED:\n\t\treturn DUK_TYPE_MASK_UNDEFINED;\n\tcase DUK_TAG_NULL:\n\t\treturn DUK_TYPE_MASK_NULL;\n\tcase DUK_TAG_BOOLEAN:\n\t\treturn DUK_TYPE_MASK_BOOLEAN;\n\tcase DUK_TAG_STRING:\n\t\treturn DUK_TYPE_MASK_STRING;\n\tcase DUK_TAG_OBJECT:\n\t\treturn DUK_TYPE_MASK_OBJECT;\n\tcase DUK_TAG_BUFFER:\n\t\treturn DUK_TYPE_MASK_BUFFER;\n\tcase DUK_TAG_POINTER:\n\t\treturn DUK_TYPE_MASK_POINTER;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\treturn DUK_TYPE_MASK_LIGHTFUNC;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* Note: number has no explicit tag (in 8-byte representation) */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\treturn DUK_TYPE_MASK_NUMBER;\n\t}\n#else  /* DUK_USE_PACKED_TVAL */\n\tDUK_ASSERT(DUK_TVAL_IS_VALID_TAG(tv));\n\tDUK_ASSERT(sizeof(duk__type_mask_from_tag) / sizeof(duk_uint_t) == DUK_TAG_MAX - DUK_TAG_MIN + 1);\n\treturn duk__type_mask_from_tag[DUK_TVAL_GET_TAG(tv) - DUK_TAG_MIN];\n#endif  /* DUK_USE_PACKED_TVAL */\n}\n\nDUK_EXTERNAL duk_uint_t duk_get_type_mask(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\treturn duk_get_type_mask_tval(tv);\n}\n\nDUK_EXTERNAL duk_bool_t duk_check_type_mask(duk_hthread *thr, duk_idx_t idx, duk_uint_t mask) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (DUK_LIKELY((duk_get_type_mask(thr, idx) & mask) != 0U)) {\n\t\treturn 1;\n\t}\n\tif (mask & DUK_TYPE_MASK_THROW) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_UNEXPECTED_TYPE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_undefined(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_UNDEFINED);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_null(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_NULL);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_boolean(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_BOOLEAN);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_number(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/*\n\t *  Number is special because it doesn't have a specific\n\t *  tag in the 8-byte representation.\n\t */\n\n\t/* XXX: shorter version for unpacked representation? */\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\treturn DUK_TVAL_IS_NUMBER(tv);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_nan(duk_hthread *thr, duk_idx_t idx) {\n\t/* XXX: This will now return false for non-numbers, even though they would\n\t * coerce to NaN (as a general rule).  In particular, duk_get_number()\n\t * returns a NaN for non-numbers, so should this function also return\n\t * true for non-numbers?\n\t */\n\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\n\t/* XXX: for packed duk_tval an explicit \"is number\" check is unnecessary */\n\tif (!DUK_TVAL_IS_NUMBER(tv)) {\n\t\treturn 0;\n\t}\n\treturn (duk_bool_t) DUK_ISNAN(DUK_TVAL_GET_NUMBER(tv));\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_string(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_STRING);\n}\n\nDUK_INTERNAL duk_bool_t duk_is_string_notsymbol(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_get_hstring_notsymbol(thr, idx) != NULL;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_object(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_OBJECT);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_BUFFER);\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\treturn 1;\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\nDUK_EXTERNAL duk_bool_t duk_is_buffer_data(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\treturn duk_is_buffer(thr, idx);\n}\n\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_EXTERNAL duk_bool_t duk_is_pointer(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_POINTER);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_lightfunc(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__tag_check(thr, idx, DUK_TAG_LIGHTFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_symbol(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\th = duk_get_hstring(thr, idx);\n\t/* Use DUK_LIKELY() here because caller may be more likely to type\n\t * check an expected symbol than not.\n\t */\n\tif (DUK_LIKELY(h != NULL && DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_array(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, idx);\n\tif (obj) {\n\t\treturn (DUK_HOBJECT_GET_CLASS_NUMBER(obj) == DUK_HOBJECT_CLASS_ARRAY ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_function(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn DUK_HOBJECT_HAS_CALLABLE(h) ? 1 : 0;\n\t}\n\tif (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_INTERNAL duk_bool_t duk_is_callable_tval(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_UNREF(thr);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn DUK_HOBJECT_HAS_CALLABLE(h) ? 1 : 0;\n\t}\n\tif (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_constructable(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn DUK_HOBJECT_HAS_CONSTRUCTABLE(h) ? 1 : 0;\n\t}\n\tif (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_c_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__obj_flag_any_default_false(thr,\n\t                                       idx,\n\t                                       DUK_HOBJECT_FLAG_NATFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_ecmascript_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__obj_flag_any_default_false(thr,\n\t                                       idx,\n\t                                       DUK_HOBJECT_FLAG_COMPFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_bound_function(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__obj_flag_any_default_false(thr,\n\t                                       idx,\n\t                                       DUK_HOBJECT_FLAG_BOUNDFUNC);\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_thread(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tobj = duk_get_hobject(thr, idx);\n\tif (obj) {\n\t\treturn (DUK_HOBJECT_GET_CLASS_NUMBER(obj) == DUK_HOBJECT_CLASS_THREAD ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_fixed_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HBUFFER_HAS_DYNAMIC(h) ? 0 : 1);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_dynamic_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h) ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_bool_t duk_is_external_buffer(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_get_tval_or_unused(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HBUFFER_HAS_DYNAMIC(h) && DUK_HBUFFER_HAS_EXTERNAL(h) ? 1 : 0);\n\t}\n\treturn 0;\n}\n\nDUK_EXTERNAL duk_errcode_t duk_get_error_code(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hobject *h;\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_get_hobject(thr, idx);\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (!h) {\n\t\t\treturn DUK_ERR_NONE;\n\t\t}\n\n\t\t/* XXX: something more convenient? */\n\n\t\tif (h == thr->builtins[DUK_BIDX_EVAL_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_EVAL_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_RANGE_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_RANGE_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_REFERENCE_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_REFERENCE_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_SYNTAX_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_SYNTAX_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_TYPE_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_TYPE_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_URI_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_URI_ERROR;\n\t\t}\n\t\tif (h == thr->builtins[DUK_BIDX_ERROR_PROTOTYPE]) {\n\t\t\treturn DUK_ERR_ERROR;\n\t\t}\n\n\t\th = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t} while (--sanity > 0);\n\n\treturn DUK_ERR_NONE;\n}\n\n/*\n *  Pushers\n */\n\nDUK_INTERNAL void duk_push_tval(duk_hthread *thr, duk_tval *tv) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_TVAL(tv_slot, tv);\n\tDUK_TVAL_INCREF(thr, tv);  /* no side effects */\n}\n\nDUK_EXTERNAL void duk_push_undefined(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\t/* Because value stack init policy is 'undefined above top',\n\t * we don't need to write, just assert.\n\t */\n\tthr->valstack_top++;\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));\n}\n\nDUK_EXTERNAL void duk_push_null(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NULL(tv_slot);\n}\n\nDUK_EXTERNAL void duk_push_boolean(duk_hthread *thr, duk_bool_t val) {\n\tduk_tval *tv_slot;\n\tduk_small_int_t b;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\tb = (val ? 1 : 0);  /* ensure value is 1 or 0 (not other non-zero) */\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_BOOLEAN(tv_slot, b);\n}\n\nDUK_EXTERNAL void duk_push_true(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_BOOLEAN_TRUE(tv_slot);\n}\n\nDUK_EXTERNAL void duk_push_false(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_BOOLEAN_FALSE(tv_slot);\n}\n\n/* normalize NaN which may not match our canonical internal NaN */\nDUK_EXTERNAL void duk_push_number(duk_hthread *thr, duk_double_t val) {\n\tduk_tval *tv_slot;\n\tduk_double_union du;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\tdu.d = val;\n\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, du.d);\n}\n\nDUK_EXTERNAL void duk_push_int(duk_hthread *thr, duk_int_t val) {\n#if defined(DUK_USE_FASTINT)\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n#if DUK_INT_MAX <= 0x7fffffffL\n\tDUK_TVAL_SET_I32(tv_slot, (duk_int32_t) val);\n#else\n\tif (val >= DUK_FASTINT_MIN && val <= DUK_FASTINT_MAX) {\n\t\tDUK_TVAL_SET_FASTINT(tv_slot, (duk_int64_t) val);\n\t} else {\n\t\tduk_double_t = (duk_double_t) val;\n\t\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n\t}\n#endif\n#else  /* DUK_USE_FASTINT */\n\tduk_tval *tv_slot;\n\tduk_double_t d;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\td = (duk_double_t) val;\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n#endif  /* DUK_USE_FASTINT */\n}\n\nDUK_EXTERNAL void duk_push_uint(duk_hthread *thr, duk_uint_t val) {\n#if defined(DUK_USE_FASTINT)\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n#if DUK_UINT_MAX <= 0xffffffffUL\n\tDUK_TVAL_SET_U32(tv_slot, (duk_uint32_t) val);\n#else\n\tif (val <= DUK_FASTINT_MAX) {  /* val is unsigned so >= 0 */\n\t\t/* XXX: take advantage of val being unsigned, no need to mask */\n\t\tDUK_TVAL_SET_FASTINT(tv_slot, (duk_int64_t) val);\n\t} else {\n\t\tduk_double_t = (duk_double_t) val;\n\t\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n\t}\n#endif\n#else  /* DUK_USE_FASTINT */\n\tduk_tval *tv_slot;\n\tduk_double_t d;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\td = (duk_double_t) val;\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, d);\n#endif  /* DUK_USE_FASTINT */\n}\n\nDUK_EXTERNAL void duk_push_nan(duk_hthread *thr) {\n\tduk_tval *tv_slot;\n\tduk_double_union du;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\tDUK_DBLUNION_SET_NAN(&du);\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_NUMBER(tv_slot, du.d);\n}\n\nDUK_EXTERNAL const char *duk_push_lstring(duk_hthread *thr, const char *str, duk_size_t len) {\n\tduk_hstring *h;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Check stack before interning (avoid hanging temp). */\n\tDUK__CHECK_SPACE();\n\n\t/* NULL with zero length represents an empty string; NULL with higher\n\t * length is also now treated like an empty string although it is\n\t * a bit dubious.  This is unlike duk_push_string() which pushes a\n\t * 'null' if the input string is a NULL.\n\t */\n\tif (DUK_UNLIKELY(str == NULL)) {\n\t\tlen = 0U;\n\t}\n\n\t/* Check for maximum string length. */\n\tif (DUK_UNLIKELY(len > DUK_HSTRING_MAX_BYTELEN)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_STRING_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\th = duk_heap_strtable_intern_checked(thr, (const duk_uint8_t *) str, (duk_uint32_t) len);\n\tDUK_ASSERT(h != NULL);\n\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_STRING(tv_slot, h);\n\tDUK_HSTRING_INCREF(thr, h);  /* no side effects */\n\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n\nDUK_EXTERNAL const char *duk_push_string(duk_hthread *thr, const char *str) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (str) {\n\t\treturn duk_push_lstring(thr, str, DUK_STRLEN(str));\n\t} else {\n\t\tduk_push_null(thr);\n\t\treturn NULL;\n\t}\n}\n\n#if !defined(DUK_USE_PREFER_SIZE)\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_EXTERNAL const char *duk_push_literal_raw(duk_hthread *thr, const char *str, duk_size_t len) {\n\tduk_hstring *h;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(str != NULL);\n\tDUK_ASSERT(str[len] == (char) 0);\n\n\t/* Check for maximum string length. */\n\tif (DUK_UNLIKELY(len > DUK_HSTRING_MAX_BYTELEN)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_STRING_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\th = duk_heap_strtable_intern_literal_checked(thr, (const duk_uint8_t *) str, (duk_uint32_t) len);\n\tDUK_ASSERT(h != NULL);\n\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_STRING(tv_slot, h);\n\tDUK_HSTRING_INCREF(thr, h);  /* no side effects */\n\n\treturn (const char *) DUK_HSTRING_GET_DATA(h);\n}\n#else  /* DUK_USE_LITCACHE_SIZE */\nDUK_EXTERNAL const char *duk_push_literal_raw(duk_hthread *thr, const char *str, duk_size_t len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(str != NULL);\n\tDUK_ASSERT(str[len] == (char) 0);\n\n\treturn duk_push_lstring(thr, str, len);\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n#endif  /* !DUK_USE_PREFER_SIZE */\n\nDUK_EXTERNAL void duk_push_pointer(duk_hthread *thr, void *val) {\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__CHECK_SPACE();\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_POINTER(tv_slot, val);\n}\n\nDUK_INTERNAL duk_hstring *duk_push_uint_to_hstring(duk_hthread *thr, duk_uint_t i) {\n\tduk_hstring *h_tmp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: this could be a direct DUK_SPRINTF to a buffer followed by duk_push_string() */\n\tduk_push_uint(thr, (duk_uint_t) i);\n\th_tmp = duk_to_hstring_m1(thr);\n\tDUK_ASSERT(h_tmp != NULL);\n\treturn h_tmp;\n}\n\nDUK_LOCAL void duk__push_this_helper(duk_hthread *thr, duk_small_uint_t check_object_coercible) {\n\tduk_tval *tv_slot;\n\n\tDUK__CHECK_SPACE();\n\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* because of valstack init policy */\n\ttv_slot = thr->valstack_top++;\n\n\tif (DUK_UNLIKELY(thr->callstack_curr == NULL)) {\n\t\tif (check_object_coercible) {\n\t\t\tgoto type_error;\n\t\t}\n\t\t/* 'undefined' already on stack top */\n\t} else {\n\t\tduk_tval *tv;\n\n\t\t/* 'this' binding is just before current activation's bottom */\n\t\tDUK_ASSERT(thr->valstack_bottom > thr->valstack);\n\t\ttv = thr->valstack_bottom - 1;\n\t\tif (check_object_coercible &&\n\t\t    (DUK_TVAL_IS_UNDEFINED(tv) || DUK_TVAL_IS_NULL(tv))) {\n\t\t\t/* XXX: better macro for DUK_TVAL_IS_UNDEFINED_OR_NULL(tv) */\n\t\t\tgoto type_error;\n\t\t}\n\n\t\tDUK_TVAL_SET_TVAL(tv_slot, tv);\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t}\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_OBJECT_COERCIBLE);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_push_this(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 0 /*check_object_coercible*/);\n}\n\nDUK_INTERNAL void duk_push_this_check_object_coercible(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 1 /*check_object_coercible*/);\n}\n\nDUK_INTERNAL duk_hobject *duk_push_this_coercible_to_object(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 1 /*check_object_coercible*/);\n\th = duk_to_hobject(thr, -1);\n\tDUK_ASSERT(h != NULL);\n\treturn h;\n}\n\nDUK_INTERNAL duk_hstring *duk_push_this_coercible_to_string(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__push_this_helper(thr, 1 /*check_object_coercible*/);\n\treturn duk_to_hstring_m1(thr);  /* This will reject all Symbol values; accepts Symbol objects. */\n}\n\nDUK_INTERNAL duk_tval *duk_get_borrowed_this_tval(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->callstack_top > 0);  /* caller required to know */\n\tDUK_ASSERT(thr->callstack_curr != NULL);  /* caller required to know */\n\tDUK_ASSERT(thr->valstack_bottom > thr->valstack);  /* consequence of above */\n\tDUK_ASSERT(thr->valstack_bottom - 1 >= thr->valstack);  /* 'this' binding exists */\n\n\treturn thr->valstack_bottom - 1;\n}\n\nDUK_EXTERNAL void duk_push_new_target(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* https://www.ecma-international.org/ecma-262/6.0/#sec-meta-properties-runtime-semantics-evaluation\n\t * https://www.ecma-international.org/ecma-262/6.0/#sec-getnewtarget\n\t *\n\t * No newTarget support now, so as a first approximation\n\t * use the resolved (non-bound) target function.\n\t *\n\t * Check CONSTRUCT flag from current function, or if running\n\t * direct eval, from a non-direct-eval parent (with possibly\n\t * more than one nested direct eval).  An alternative to this\n\t * would be to store [[NewTarget]] as a hidden symbol of the\n\t * lexical scope, and then just look up that variable.\n\t *\n\t * Calls from the application will either be for an empty\n\t * call stack, or a Duktape/C function as the top activation.\n\t */\n\n\tact = thr->callstack_curr;\n\tfor (;;) {\n\t\tif (act == NULL) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (act->flags & DUK_ACT_FLAG_CONSTRUCT) {\n\t\t\tduk_push_tval(thr, &act->tv_func);\n\t\t\treturn;\n\t\t} else if (act->flags & DUK_ACT_FLAG_DIRECT_EVAL) {\n\t\t\tact = act->parent;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tduk_push_undefined(thr);\n}\n\nDUK_EXTERNAL void duk_push_current_function(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\tduk_push_tval(thr, &act->tv_func);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n}\n\nDUK_EXTERNAL void duk_push_current_thread(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tif (thr->heap->curr_thread) {\n\t\tduk_push_hobject(thr, (duk_hobject *) thr->heap->curr_thread);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n}\n\nDUK_EXTERNAL void duk_push_global_object(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_hobject_bidx(thr, DUK_BIDX_GLOBAL);\n}\n\n/* XXX: size optimize */\nDUK_LOCAL void duk__push_stash(duk_hthread *thr) {\n\tif (!duk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"creating heap/global/thread stash on first use\"));\n\t\tduk_pop_unsafe(thr);\n\t\tduk_push_bare_object(thr);\n\t\tduk_dup_top(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_C);  /* [ ... parent stash stash ] -> [ ... parent stash ] */\n\t}\n\tduk_remove_m2(thr);\n}\n\nDUK_EXTERNAL void duk_push_heap_stash(duk_hthread *thr) {\n\tduk_heap *heap;\n\tDUK_ASSERT_API_ENTRY(thr);\n\theap = thr->heap;\n\tDUK_ASSERT(heap->heap_object != NULL);\n\tduk_push_hobject(thr, heap->heap_object);\n\tduk__push_stash(thr);\n}\n\nDUK_EXTERNAL void duk_push_global_stash(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_push_global_object(thr);\n\tduk__push_stash(thr);\n}\n\nDUK_EXTERNAL void duk_push_thread_stash(duk_hthread *thr, duk_hthread *target_thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tif (DUK_UNLIKELY(target_thr == NULL)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tduk_push_hobject(thr, (duk_hobject *) target_thr);\n\tduk__push_stash(thr);\n}\n\n/* XXX: duk_ssize_t would be useful here */\nDUK_LOCAL duk_int_t duk__try_push_vsprintf(duk_hthread *thr, void *buf, duk_size_t sz, const char *fmt, va_list ap) {\n\tduk_int_t len;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(thr);\n\n\t/* NUL terminator handling doesn't matter here */\n\tlen = DUK_VSNPRINTF((char *) buf, sz, fmt, ap);\n\tif (len < (duk_int_t) sz) {\n\t\t/* Return value of 'sz' or more indicates output was (potentially)\n\t\t * truncated.\n\t\t */\n\t\treturn (duk_int_t) len;\n\t}\n\treturn -1;\n}\n\nDUK_EXTERNAL const char *duk_push_vsprintf(duk_hthread *thr, const char *fmt, va_list ap) {\n\tduk_uint8_t stack_buf[DUK_PUSH_SPRINTF_INITIAL_SIZE];\n\tduk_size_t sz = DUK_PUSH_SPRINTF_INITIAL_SIZE;\n\tduk_bool_t pushed_buf = 0;\n\tvoid *buf;\n\tduk_int_t len;  /* XXX: duk_ssize_t */\n\tconst char *res;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* special handling of fmt==NULL */\n\tif (!fmt) {\n\t\tduk_hstring *h_str;\n\t\tduk_push_hstring_empty(thr);\n\t\th_str = duk_known_hstring(thr, -1);\n\t\treturn (const char *) DUK_HSTRING_GET_DATA(h_str);\n\t}\n\n\t/* initial estimate based on format string */\n\tsz = DUK_STRLEN(fmt) + 16;  /* format plus something to avoid just missing */\n\tif (sz < DUK_PUSH_SPRINTF_INITIAL_SIZE) {\n\t\tsz = DUK_PUSH_SPRINTF_INITIAL_SIZE;\n\t}\n\tDUK_ASSERT(sz > 0);\n\n\t/* Try to make do with a stack buffer to avoid allocating a temporary buffer.\n\t * This works 99% of the time which is quite nice.\n\t */\n\tfor (;;) {\n\t\tva_list ap_copy;  /* copied so that 'ap' can be reused */\n\n\t\tif (sz <= sizeof(stack_buf)) {\n\t\t\tbuf = stack_buf;\n\t\t} else if (!pushed_buf) {\n\t\t\tpushed_buf = 1;\n\t\t\tbuf = duk_push_dynamic_buffer(thr, sz);\n\t\t} else {\n\t\t\tbuf = duk_resize_buffer(thr, -1, sz);\n\t\t}\n\t\tDUK_ASSERT(buf != NULL);\n\n\t\tDUK_VA_COPY(ap_copy, ap);\n\t\tlen = duk__try_push_vsprintf(thr, buf, sz, fmt, ap_copy);\n\t\tva_end(ap_copy);\n\t\tif (len >= 0) {\n\t\t\tbreak;\n\t\t}\n\n\t\t/* failed, resize and try again */\n\t\tsz = sz * 2;\n\t\tif (DUK_UNLIKELY(sz >= DUK_PUSH_SPRINTF_SANITY_LIMIT)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t}\n\n\t/* Cannot use duk_buffer_to_string() on the buffer because it is\n\t * usually larger than 'len'; 'buf' is also usually a stack buffer.\n\t */\n\tres = duk_push_lstring(thr, (const char *) buf, (duk_size_t) len);  /* [ buf? res ] */\n\tif (pushed_buf) {\n\t\tduk_remove_m2(thr);\n\t}\n\treturn res;\n}\n\nDUK_EXTERNAL const char *duk_push_sprintf(duk_hthread *thr, const char *fmt, ...) {\n\tva_list ap;\n\tconst char *ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* allow fmt==NULL */\n\tva_start(ap, fmt);\n\tret = duk_push_vsprintf(thr, fmt, ap);\n\tva_end(ap);\n\n\treturn ret;\n}\n\nDUK_INTERNAL duk_hobject *duk_push_object_helper(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx) {\n\tduk_tval *tv_slot;\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(prototype_bidx == -1 ||\n\t           (prototype_bidx >= 0 && prototype_bidx < DUK_NUM_BUILTINS));\n\n\tDUK__CHECK_SPACE();\n\n\th = duk_hobject_alloc(thr, hobject_flags_and_class);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"created object with flags: 0x%08lx\", (unsigned long) h->hdr.h_flags));\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, h);\n\tDUK_HOBJECT_INCREF(thr, h);  /* no side effects */\n\tthr->valstack_top++;\n\n\t/* object is now reachable */\n\n\tif (prototype_bidx >= 0) {\n\t\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, h, thr->builtins[prototype_bidx]);\n\t} else {\n\t\tDUK_ASSERT(prototype_bidx == -1);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h) == NULL);\n\t}\n\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_push_object_helper_proto(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_hobject *proto) {\n\tduk_hobject *h;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th = duk_push_object_helper(thr, hobject_flags_and_class, -1);\n\tDUK_ASSERT(h != NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, h, proto);\n\treturn h;\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_object(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              DUK_BIDX_OBJECT_PROTOTYPE);\n\treturn duk_get_top_index_unsafe(thr);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_array(duk_hthread *thr) {\n\tduk_uint_t flags;\n\tduk_harray *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_ARRAY_PART |\n\t        DUK_HOBJECT_FLAG_EXOTIC_ARRAY |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAY);\n\n\tobj = duk_harray_alloc(thr, flags);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[DUK_BIDX_ARRAY_PROTOTYPE]);\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);  /* XXX: could preallocate with refcount = 1 */\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\tDUK_ASSERT(obj->length == 0);  /* Array .length starts at zero. */\n\treturn ret;\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_bare_array(duk_hthread *thr) {\n\tduk_uint_t flags;\n\tduk_harray *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_ARRAY_PART |\n\t        DUK_HOBJECT_FLAG_EXOTIC_ARRAY |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAY);\n\n\tobj = duk_harray_alloc(thr, flags);\n\tDUK_ASSERT(obj != NULL);\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);  /* XXX: could preallocate with refcount = 1 */\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\tDUK_ASSERT(obj->length == 0);  /* Array .length starts at zero. */\n\treturn ret;\n}\n\nDUK_INTERNAL duk_harray *duk_push_harray(duk_hthread *thr) {\n\t/* XXX: API call could do this directly, cast to void in API macro. */\n\tduk_harray *a;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_push_array(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(thr->valstack_top - 1));\n\ta = (duk_harray *) DUK_TVAL_GET_OBJECT(thr->valstack_top - 1);\n\tDUK_ASSERT(a != NULL);\n\treturn a;\n}\n\n/* Push a duk_harray with preallocated size (.length also set to match size).\n * Caller may then populate array part of the duk_harray directly.\n */\nDUK_INTERNAL duk_harray *duk_push_harray_with_size(duk_hthread *thr, duk_uint32_t size) {\n\tduk_harray *a;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ta = duk_push_harray(thr);\n\n\tduk_hobject_realloc_props(thr,\n\t                          (duk_hobject *) a,\n\t                          0,\n\t                          size,\n\t                          0,\n\t                          0);\n\ta->length = size;\n\treturn a;\n}\n\nDUK_INTERNAL duk_tval *duk_push_harray_with_size_outptr(duk_hthread *thr, duk_uint32_t size) {\n\tduk_harray *a;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ta = duk_push_harray_with_size(thr, size);\n\tDUK_ASSERT(a != NULL);\n\treturn DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_thread_raw(duk_hthread *thr, duk_uint_t flags) {\n\tduk_hthread *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\tobj = duk_hthread_alloc(thr,\n\t                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_THREAD));\n\tDUK_ASSERT(obj != NULL);\n\tobj->state = DUK_HTHREAD_STATE_INACTIVE;\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* Nothing to initialize, strs[] is in ROM. */\n#else\n#if defined(DUK_USE_HEAPPTR16)\n\tobj->strs16 = thr->strs16;\n#else\n\tobj->strs = thr->strs;\n#endif\n#endif\n\tDUK_DDD(DUK_DDDPRINT(\"created thread object with flags: 0x%08lx\", (unsigned long) obj->obj.hdr.h_flags));\n\n\t/* make the new thread reachable */\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HTHREAD_INCREF(thr, obj);\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\t/* important to do this *after* pushing, to make the thread reachable for gc */\n\tif (DUK_UNLIKELY(!duk_hthread_init_stacks(thr->heap, obj))) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* initialize built-ins - either by copying or creating new ones */\n\tif (flags & DUK_THREAD_NEW_GLOBAL_ENV) {\n\t\tduk_hthread_create_builtin_objects(obj);\n\t} else {\n\t\tduk_hthread_copy_builtin_objects(thr, obj);\n\t}\n\n\t/* default prototype */\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, obj->builtins[DUK_BIDX_THREAD_PROTOTYPE]);\n\n\t/* Initial stack size satisfies the stack slack constraints so there\n\t * is no need to require stack here.\n\t */\n\tDUK_ASSERT(DUK_VALSTACK_INITIAL_SIZE >=\n\t           DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\n\treturn ret;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_push_hcompfunc(duk_hthread *thr) {\n\tduk_hcompfunc *obj;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\t/* Template functions are not strictly constructable (they don't\n\t * have a \"prototype\" property for instance), so leave the\n\t * DUK_HOBJECT_FLAG_CONSRUCTABLE flag cleared here.\n\t */\n\n\tobj = duk_hcompfunc_alloc(thr,\n\t                          DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                          DUK_HOBJECT_FLAG_CALLABLE |\n\t                          DUK_HOBJECT_FLAG_COMPFUNC |\n\t                          DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION));\n\tif (DUK_UNLIKELY(obj == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"created compiled function object with flags: 0x%08lx\", (unsigned long) obj->obj.hdr.h_flags));\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\tthr->valstack_top++;\n\n\t/* default prototype */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) obj) == NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\n\treturn obj;\n}\n\nDUK_INTERNAL duk_hboundfunc *duk_push_hboundfunc(duk_hthread *thr) {\n\tduk_hboundfunc *obj;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\tobj = duk_hboundfunc_alloc(thr->heap,\n\t                           DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                           DUK_HOBJECT_FLAG_BOUNDFUNC |\n\t                           DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t                           DUK_HOBJECT_FLAG_CALLABLE |\n\t                           DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION));\n\tif (!obj) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\ttv_slot = thr->valstack_top++;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\n\t/* Prototype is left as NULL because the caller always sets it (and\n\t * it depends on the target function).\n\t */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) obj) == NULL);\n\n\treturn obj;\n}\n\nDUK_LOCAL duk_idx_t duk__push_c_function_raw(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_uint_t flags, duk_small_uint_t proto_bidx) {\n\tduk_hnatfunc *obj;\n\tduk_idx_t ret;\n\tduk_tval *tv_slot;\n\tduk_int16_t func_nargs;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tDUK__CHECK_SPACE();\n\n\tif (DUK_UNLIKELY(func == NULL)) {\n\t\tgoto api_error;\n\t}\n\tif (nargs >= 0 && nargs < DUK_HNATFUNC_NARGS_MAX) {\n\t\tfunc_nargs = (duk_int16_t) nargs;\n\t} else if (nargs == DUK_VARARGS) {\n\t\tfunc_nargs = DUK_HNATFUNC_NARGS_VARARGS;\n\t} else {\n\t\tgoto api_error;\n\t}\n\n\tobj = duk_hnatfunc_alloc(thr, flags);\n\tDUK_ASSERT(obj != NULL);\n\n\tobj->func = func;\n\tobj->nargs = func_nargs;\n\n\tDUK_DDD(DUK_DDDPRINT(\"created native function object with flags: 0x%08lx, nargs=%ld\",\n\t                     (unsigned long) obj->obj.hdr.h_flags, (long) obj->nargs));\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tthr->valstack_top++;\n\n\tDUK_ASSERT_BIDX_VALID(proto_bidx);\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[proto_bidx]);\n\treturn ret;\n\n api_error:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_c_function(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\n\t/* Default prototype is a Duktape specific %NativeFunctionPrototype%\n\t * which provides .length and .name getters.\n\t */\n\treturn duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE);\n}\n\nDUK_INTERNAL void duk_push_c_function_builtin(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CONSTRUCTABLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\n\t/* Must use Function.prototype for standard built-in functions. */\n\t(void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_FUNCTION_PROTOTYPE);\n}\n\nDUK_INTERNAL void duk_push_c_function_builtin_noconstruct(duk_hthread *thr, duk_c_function func, duk_int_t nargs) {\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t        DUK_HOBJECT_FLAG_CALLABLE |\n\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t        DUK_HOBJECT_FLAG_NATFUNC |\n\t        DUK_HOBJECT_FLAG_NEWENV |\n\t        DUK_HOBJECT_FLAG_STRICT |\n\t        DUK_HOBJECT_FLAG_NOTAIL |\n\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION);\n\n\t/* Must use Function.prototype for standard built-in functions. */\n\t(void) duk__push_c_function_raw(thr, func, nargs, flags, DUK_BIDX_FUNCTION_PROTOTYPE);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_c_lightfunc(duk_hthread *thr, duk_c_function func, duk_idx_t nargs, duk_idx_t length, duk_int_t magic) {\n\tduk_small_uint_t lf_flags;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\tif (nargs >= DUK_LFUNC_NARGS_MIN && nargs <= DUK_LFUNC_NARGS_MAX) {\n\t\t/* as is */\n\t} else if (nargs == DUK_VARARGS) {\n\t\tnargs = DUK_LFUNC_NARGS_VARARGS;\n\t} else {\n\t\tgoto api_error;\n\t}\n\tif (DUK_UNLIKELY(!(length >= DUK_LFUNC_LENGTH_MIN && length <= DUK_LFUNC_LENGTH_MAX))) {\n\t\tgoto api_error;\n\t}\n\tif (DUK_UNLIKELY(!(magic >= DUK_LFUNC_MAGIC_MIN && magic <= DUK_LFUNC_MAGIC_MAX))) {\n\t\tgoto api_error;\n\t}\n\n\tlf_flags = DUK_LFUNC_FLAGS_PACK((duk_small_int_t) magic, (duk_small_uint_t) length, (duk_small_uint_t) nargs);\n\ttv_slot = thr->valstack_top++;\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_slot));\n\tDUK_TVAL_SET_LIGHTFUNC(tv_slot, func, lf_flags);\n\tDUK_ASSERT(tv_slot >= thr->valstack_bottom);\n\treturn (duk_idx_t) (tv_slot - thr->valstack_bottom);\n\n api_error:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_hbufobj *duk_push_bufobj_raw(duk_hthread *thr, duk_uint_t hobject_flags_and_class, duk_small_int_t prototype_bidx) {\n\tduk_hbufobj *obj;\n\tduk_tval *tv_slot;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(prototype_bidx >= 0);\n\n\tDUK__CHECK_SPACE();\n\n\tobj = duk_hbufobj_alloc(thr, hobject_flags_and_class);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) obj, thr->builtins[prototype_bidx]);\n\tDUK_HBUFOBJ_ASSERT_VALID(obj);\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) obj);\n\tDUK_HOBJECT_INCREF(thr, obj);\n\tthr->valstack_top++;\n\n\treturn obj;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* XXX: There's quite a bit of overlap with buffer creation handling in\n * duk_bi_buffer.c.  Look for overlap and refactor.\n */\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK__PACK_ARGS(classnum,protobidx,elemtype,elemshift,istypedarray) \\\n\t(((classnum) << 24) | ((protobidx) << 16) | ((elemtype) << 8) | ((elemshift) << 4) | (istypedarray))\n\nstatic const duk_uint32_t duk__bufobj_flags_lookup[] = {\n\t/* Node.js Buffers are Uint8Array instances which inherit from Buffer.prototype. */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_ARRAYBUFFER,       DUK_BIDX_ARRAYBUFFER_PROTOTYPE,       DUK_HBUFOBJ_ELEM_UINT8,        0, 0),  /* DUK_BUFOBJ_ARRAYBUFFER */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8ARRAY,        DUK_BIDX_NODEJS_BUFFER_PROTOTYPE,     DUK_HBUFOBJ_ELEM_UINT8,        0, 1),  /* DUK_BUFOBJ_NODEJS_BUFFER */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_DATAVIEW,          DUK_BIDX_DATAVIEW_PROTOTYPE,          DUK_HBUFOBJ_ELEM_UINT8,        0, 0),  /* DUK_BUFOBJ_DATAVIEW */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT8ARRAY,         DUK_BIDX_INT8ARRAY_PROTOTYPE,         DUK_HBUFOBJ_ELEM_INT8,         0, 1),  /* DUK_BUFOBJ_INT8ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8ARRAY,        DUK_BIDX_UINT8ARRAY_PROTOTYPE,        DUK_HBUFOBJ_ELEM_UINT8,        0, 1),  /* DUK_BUFOBJ_UINT8ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY, DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE, DUK_HBUFOBJ_ELEM_UINT8CLAMPED, 0, 1),  /* DUK_BUFOBJ_UINT8CLAMPEDARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT16ARRAY,        DUK_BIDX_INT16ARRAY_PROTOTYPE,        DUK_HBUFOBJ_ELEM_INT16,        1, 1),  /* DUK_BUFOBJ_INT16ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT16ARRAY,       DUK_BIDX_UINT16ARRAY_PROTOTYPE,       DUK_HBUFOBJ_ELEM_UINT16,       1, 1),  /* DUK_BUFOBJ_UINT16ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_INT32ARRAY,        DUK_BIDX_INT32ARRAY_PROTOTYPE,        DUK_HBUFOBJ_ELEM_INT32,        2, 1),  /* DUK_BUFOBJ_INT32ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_UINT32ARRAY,       DUK_BIDX_UINT32ARRAY_PROTOTYPE,       DUK_HBUFOBJ_ELEM_UINT32,       2, 1),  /* DUK_BUFOBJ_UINT32ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_FLOAT32ARRAY,      DUK_BIDX_FLOAT32ARRAY_PROTOTYPE,      DUK_HBUFOBJ_ELEM_FLOAT32,      2, 1),  /* DUK_BUFOBJ_FLOAT32ARRAY */\n\tDUK__PACK_ARGS(DUK_HOBJECT_CLASS_FLOAT64ARRAY,      DUK_BIDX_FLOAT64ARRAY_PROTOTYPE,      DUK_HBUFOBJ_ELEM_FLOAT64,      3, 1)   /* DUK_BUFOBJ_FLOAT64ARRAY */\n};\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags) {\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_hobject *h_arraybuf;\n\tduk_uint32_t tmp;\n\tduk_uint_t classnum;\n\tduk_uint_t protobidx;\n\tduk_uint_t lookupidx;\n\tduk_uint_t uint_offset, uint_length, uint_added;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* The underlying types for offset/length in duk_hbufobj is\n\t * duk_uint_t; make sure argument values fit.\n\t */\n\tuint_offset = (duk_uint_t) byte_offset;\n\tuint_length = (duk_uint_t) byte_length;\n\tif (sizeof(duk_size_t) != sizeof(duk_uint_t)) {\n\t\tif (DUK_UNLIKELY((duk_size_t) uint_offset != byte_offset || (duk_size_t) uint_length != byte_length)) {\n\t\t\tgoto range_error;\n\t\t}\n\t}\n\n\tDUK_ASSERT_DISABLE(flags >= 0);  /* flags is unsigned */\n\tlookupidx = flags;\n\tif (DUK_UNLIKELY(lookupidx >= sizeof(duk__bufobj_flags_lookup) / sizeof(duk_uint32_t))) {\n\t\tgoto arg_error;\n\t}\n\ttmp = duk__bufobj_flags_lookup[lookupidx];\n\tclassnum = tmp >> 24;\n\tprotobidx = (tmp >> 16) & 0xff;\n\n\th_arraybuf = duk_get_hobject(thr, idx_buffer);\n\tif (h_arraybuf != NULL &&  /* argument is an object */\n\t    flags != DUK_BUFOBJ_ARRAYBUFFER &&  /* creating a view */\n\t    DUK_HOBJECT_GET_CLASS_NUMBER(h_arraybuf) == DUK_HOBJECT_CLASS_ARRAYBUFFER  /* argument is ArrayBuffer */) {\n\t\tduk_uint_t tmp_offset;\n\n\t\tDUK_HBUFOBJ_ASSERT_VALID((duk_hbufobj *) h_arraybuf);\n\t\th_val = ((duk_hbufobj *) h_arraybuf)->buf;\n\t\tif (DUK_UNLIKELY(h_val == NULL)) {\n\t\t\tgoto arg_error;\n\t\t}\n\n\t\ttmp_offset = uint_offset + ((duk_hbufobj *) h_arraybuf)->offset;\n\t\tif (DUK_UNLIKELY(tmp_offset < uint_offset)) {\n\t\t\tgoto range_error;\n\t\t}\n\t\tuint_offset = tmp_offset;\n\n\t\t/* Note intentional difference to new TypedArray(): we allow\n\t\t * caller to create an uncovered typed array (which is memory\n\t\t * safe); new TypedArray() rejects it.\n\t\t */\n\t} else {\n\t\t/* Handle unexpected object arguments here too, for nice error\n\t\t * messages.\n\t\t */\n\t\th_arraybuf = NULL;\n\t\th_val = duk_require_hbuffer(thr, idx_buffer);\n\t}\n\n\t/* Wrap check for offset+length. */\n\tuint_added = uint_offset + uint_length;\n\tif (DUK_UNLIKELY(uint_added < uint_offset)) {\n\t\tgoto range_error;\n\t}\n\tDUK_ASSERT(uint_added >= uint_offset && uint_added >= uint_length);\n\n\tDUK_ASSERT(h_val != NULL);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(classnum),\n\t                               (duk_small_int_t) protobidx);\n\tDUK_ASSERT(h_bufobj != NULL);\n\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\th_bufobj->buf_prop = h_arraybuf;\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, h_arraybuf);\n\th_bufobj->offset = uint_offset;\n\th_bufobj->length = uint_length;\n\th_bufobj->shift = (tmp >> 4) & 0x0f;\n\th_bufobj->elem_type = (tmp >> 8) & 0xff;\n\th_bufobj->is_typedarray = tmp & 0x0f;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t/* TypedArray views need an automatic ArrayBuffer which must be\n\t * provided as .buffer property of the view.  The ArrayBuffer is\n\t * referenced via duk_hbufobj->buf_prop and an inherited .buffer\n\t * accessor returns it.  The ArrayBuffer is created lazily on first\n\t * access if necessary so we don't need to do anything more here.\n\t */\n\treturn;\n\n range_error:\n\tDUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARGS);\n\tDUK_WO_NORETURN(return;);\n\n arg_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_ARGS);\n\tDUK_WO_NORETURN(return;);\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\nDUK_EXTERNAL void duk_push_buffer_object(duk_hthread *thr, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(idx_buffer);\n\tDUK_UNREF(byte_offset);\n\tDUK_UNREF(byte_length);\n\tDUK_UNREF(flags);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_EXTERNAL duk_idx_t duk_push_error_object_va_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap) {\n\tduk_hobject *proto;\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tduk_small_uint_t augment_flags;\n#endif\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_UNREF(filename);\n\tDUK_UNREF(line);\n\n\t/* Error code also packs a tracedata related flag. */\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\taugment_flags = 0;\n\tif (err_code & DUK_ERRCODE_FLAG_NOBLAME_FILELINE) {\n\t\taugment_flags = DUK_AUGMENT_FLAG_NOBLAME_FILELINE;\n\t}\n#endif\n\terr_code = err_code & (~DUK_ERRCODE_FLAG_NOBLAME_FILELINE);\n\n\t/* error gets its 'name' from the prototype */\n\tproto = duk_error_prototype_from_code(thr, err_code);\n\t(void) duk_push_object_helper_proto(thr,\n\t                                    DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                    DUK_HOBJECT_FLAG_FASTREFS |\n\t                                    DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ERROR),\n\t                                    proto);\n\n\t/* ... and its 'message' from an instance property */\n\tif (fmt) {\n\t\tduk_push_vsprintf(thr, fmt, ap);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);\n\t} else {\n\t\t/* If no explicit message given, put error code into message field\n\t\t * (as a number).  This is not fully in keeping with the ECMAScript\n\t\t * error model because messages are supposed to be strings (Error\n\t\t * constructors use ToString() on their argument).  However, it's\n\t\t * probably more useful than having a separate 'code' property.\n\t\t */\n\t\tduk_push_int(thr, err_code);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);\n\t}\n\n\t/* XXX: .code = err_code disabled, not sure if useful */\n\n\t/* Creation time error augmentation */\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\t/* filename may be NULL in which case file/line is not recorded */\n\tduk_err_augment_error_create(thr, thr, filename, line, augment_flags);  /* may throw an error */\n#endif\n\n\treturn duk_get_top_index_unsafe(thr);\n}\n\nDUK_EXTERNAL duk_idx_t duk_push_error_object_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...) {\n\tva_list ap;\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tva_start(ap, fmt);\n\tret = duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n\n#if !defined(DUK_USE_VARIADIC_MACROS)\nDUK_EXTERNAL duk_idx_t duk_push_error_object_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, ...) {\n\tconst char *filename = duk_api_global_filename;\n\tduk_int_t line = duk_api_global_line;\n\tva_list ap;\n\tduk_idx_t ret;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_api_global_filename = NULL;\n\tduk_api_global_line = 0;\n\tva_start(ap, fmt);\n\tret = duk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\tva_end(ap);\n\treturn ret;\n}\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\nDUK_EXTERNAL void *duk_push_buffer_raw(duk_hthread *thr, duk_size_t size, duk_small_uint_t flags) {\n\tduk_tval *tv_slot;\n\tduk_hbuffer *h;\n\tvoid *buf_data;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK__CHECK_SPACE();\n\n\t/* Check for maximum buffer length. */\n\tif (DUK_UNLIKELY(size > DUK_HBUFFER_MAX_BYTELEN)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_BUFFER_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\th = duk_hbuffer_alloc(thr->heap, size, flags, &buf_data);\n\tif (DUK_UNLIKELY(h == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n\ttv_slot = thr->valstack_top;\n\tDUK_TVAL_SET_BUFFER(tv_slot, h);\n\tDUK_HBUFFER_INCREF(thr, h);\n\tthr->valstack_top++;\n\n\treturn (void *) buf_data;\n}\n\nDUK_INTERNAL void *duk_push_fixed_buffer_nozero(duk_hthread *thr, duk_size_t len) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_push_buffer_raw(thr, len, DUK_BUF_FLAG_NOZERO);\n}\n\nDUK_INTERNAL void *duk_push_fixed_buffer_zero(duk_hthread *thr, duk_size_t len) {\n\tvoid *ptr;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tptr = duk_push_buffer_raw(thr, len, 0);\n\tDUK_ASSERT(ptr != NULL);\n#if !defined(DUK_USE_ZERO_BUFFER_DATA)\n\t/* ES2015 requires zeroing even when DUK_USE_ZERO_BUFFER_DATA\n\t * is not set.\n\t */\n\tduk_memzero((void *) ptr, (size_t) len);\n#endif\n\treturn ptr;\n}\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_EXTERNAL duk_idx_t duk_push_proxy(duk_hthread *thr, duk_uint_t proxy_flags) {\n\tduk_hobject *h_target;\n\tduk_hobject *h_handler;\n\tduk_hproxy *h_proxy;\n\tduk_tval *tv_slot;\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(proxy_flags);\n\n\t/* DUK__CHECK_SPACE() unnecessary because the Proxy is written to\n\t * value stack in-place.\n\t */\n#if 0\n\tDUK__CHECK_SPACE();\n#endif\n\n\t/* Reject a proxy object as the target because it would need\n\t * special handling in property lookups.  (ES2015 has no such\n\t * restriction.)\n\t */\n\th_target = duk_require_hobject_promote_mask(thr, -2, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(h_target != NULL);\n\tif (DUK_HOBJECT_IS_PROXY(h_target)) {\n\t\tgoto fail_args;\n\t}\n\n\t/* Reject a proxy object as the handler because it would cause\n\t * potentially unbounded recursion.  (ES2015 has no such\n\t * restriction.)\n\t *\n\t * There's little practical reason to use a lightfunc or a plain\n\t * buffer as the handler table: one could only provide traps via\n\t * their prototype objects (Function.prototype and ArrayBuffer.prototype).\n\t * Even so, as lightfuncs and plain buffers mimic their object\n\t * counterparts, they're promoted and accepted here.\n\t */\n\th_handler = duk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(h_handler != NULL);\n\tif (DUK_HOBJECT_IS_PROXY(h_handler)) {\n\t\tgoto fail_args;\n\t}\n\n\t/* XXX: Proxy object currently has no prototype, so ToPrimitive()\n\t * coercion fails which is a bit confusing.\n\t */\n\n\t/* CALLABLE and CONSTRUCTABLE flags are copied from the (initial)\n\t * target, see ES2015 Sections 9.5.15 and 9.5.13.\n\t */\n\tflags = DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h_target) &\n\t        (DUK_HOBJECT_FLAG_CALLABLE | DUK_HOBJECT_FLAG_CONSTRUCTABLE);\n\tflags |= DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t         DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ;\n\tif (flags & DUK_HOBJECT_FLAG_CALLABLE) {\n\t\tflags |= DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_FUNCTION) |\n\t\t         DUK_HOBJECT_FLAG_SPECIAL_CALL;\n\t} else {\n\t\tflags |= DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT);\n\t}\n\n\th_proxy = duk_hproxy_alloc(thr, flags);\n\tDUK_ASSERT(h_proxy != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_proxy) == NULL);\n\n\t/* Initialize Proxy target and handler references; avoid INCREF\n\t * by stealing the value stack refcounts via direct value stack\n\t * manipulation.  INCREF is needed for the Proxy itself however.\n\t */\n\tDUK_ASSERT(h_target != NULL);\n\th_proxy->target = h_target;\n\tDUK_ASSERT(h_handler != NULL);\n\th_proxy->handler = h_handler;\n\tDUK_HPROXY_ASSERT_VALID(h_proxy);\n\n\tDUK_ASSERT(duk_get_hobject(thr, -2) == h_target);\n\tDUK_ASSERT(duk_get_hobject(thr, -1) == h_handler);\n\ttv_slot = thr->valstack_top - 2;\n\tDUK_ASSERT(tv_slot >= thr->valstack_bottom);\n\tDUK_TVAL_SET_OBJECT(tv_slot, (duk_hobject *) h_proxy);\n\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) h_proxy);\n\ttv_slot++;\n\tDUK_TVAL_SET_UNDEFINED(tv_slot);  /* [ ... target handler ] -> [ ... proxy undefined ] */\n\tthr->valstack_top = tv_slot;      /* -> [ ... proxy ] */\n\n\tDUK_DD(DUK_DDPRINT(\"created Proxy: %!iT\", duk_get_tval(thr, -1)));\n\n\treturn (duk_idx_t) (thr->valstack_top - thr->valstack_bottom - 1);\n\n fail_args:\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n#else  /* DUK_USE_ES6_PROXY */\nDUK_EXTERNAL duk_idx_t duk_push_proxy(duk_hthread *thr, duk_uint_t proxy_flags) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(proxy_flags);\n\tDUK_ERROR_UNSUPPORTED(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_LOCAL void duk__validate_push_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_heaphdr *h;\n\tduk_heaphdr *curr;\n\tduk_bool_t found = 0;\n\n\th = (duk_heaphdr *) ptr;\n\tif (h == NULL) {\n\t\t/* Allowed. */\n\t\treturn;\n\t}\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\n\t/* One particular problem case is where an object has been\n\t * queued for finalization but the finalizer hasn't yet been\n\t * executed.\n\t *\n\t * Corner case: we're running in a finalizer for object X, and\n\t * user code calls duk_push_heapptr() for X itself.  In this\n\t * case X will be in finalize_list, and we can detect the case\n\t * by seeing that X's FINALIZED flag is set (which is done before\n\t * the finalizer starts executing).\n\t */\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tfor (curr = thr->heap->finalize_list;\n\t     curr != NULL;\n\t     curr = DUK_HEAPHDR_GET_NEXT(thr->heap, curr)) {\n\t\t/* FINALIZABLE is set for all objects on finalize_list\n\t\t * except for an object being finalized right now.  So\n\t\t * can't assert here.\n\t\t */\n#if 0\n\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZABLE(curr));\n#endif\n\n\t\tif (curr == h) {\n\t\t\tif (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) h)) {\n\t\t\t\t/* Object is currently being finalized. */\n\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\tfound = 1;\n\t\t\t} else {\n\t\t\t\t/* Not being finalized but on finalize_list,\n\t\t\t\t * allowed since Duktape 2.1.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\tfound = 1;\n\t\t\t}\n\t\t}\n\t}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* Because refzero_list is now processed to completion inline with\n\t * no side effects, it's always empty here.\n\t */\n\tDUK_ASSERT(thr->heap->refzero_list == NULL);\n#endif\n\n\t/* If not present in finalize_list (or refzero_list), it\n\t * must be either in heap_allocated or the string table.\n\t */\n\tif (DUK_HEAPHDR_IS_STRING(h)) {\n\t\tduk_uint32_t i;\n\t\tduk_hstring *str;\n\t\tduk_heap *heap = thr->heap;\n\n\t\tDUK_ASSERT(found == 0);\n\t\tfor (i = 0; i < heap->st_size; i++) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\t\tstr = DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, heap->strtable16[i]);\n#else\n\t\t\tstr = heap->strtable[i];\n#endif\n\t\t\twhile (str != NULL) {\n\t\t\t\tif (str == (duk_hstring *) h) {\n\t\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\t\tfound = 1;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tstr = str->hdr.h_next;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(found != 0);\n\t} else {\n\t\tfor (curr = thr->heap->heap_allocated;\n\t\t     curr != NULL;\n\t\t     curr = DUK_HEAPHDR_GET_NEXT(thr->heap, curr)) {\n\t\t\tif (curr == h) {\n\t\t\t\tDUK_ASSERT(found == 0);  /* Would indicate corrupted lists. */\n\t\t\t\tfound = 1;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(found != 0);\n\t}\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\nDUK_EXTERNAL duk_idx_t duk_push_heapptr(duk_hthread *thr, void *ptr) {\n\tduk_idx_t ret;\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Reviving an object using a heap pointer is a dangerous API\n\t * operation: if the application doesn't guarantee that the\n\t * pointer target is always reachable, difficult-to-diagnose\n\t * problems may ensue.  Try to validate the 'ptr' argument to\n\t * the extent possible.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__validate_push_heapptr(thr, ptr);\n#endif\n\n\tDUK__CHECK_SPACE();\n\n\tret = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\ttv = thr->valstack_top++;\n\n\tif (ptr == NULL) {\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\treturn ret;\n\t}\n\n\tDUK_HEAPHDR_ASSERT_VALID((duk_heaphdr *) ptr);\n\n\t/* If the argument is on finalize_list it has technically been\n\t * unreachable before duk_push_heapptr() but it's still safe to\n\t * push it.  Starting from Duktape 2.1 allow application code to\n\t * do so.  There are two main cases:\n\t *\n\t *   (1) The object is on the finalize_list and we're called by\n\t *       the finalizer for the object being finalized.  In this\n\t *       case do nothing: finalize_list handling will deal with\n\t *       the object queueing.  This is detected by the object not\n\t *       having a FINALIZABLE flag despite being on the finalize_list;\n\t *       the flag is cleared for the object being finalized only.\n\t *\n\t *   (2) The object is on the finalize_list but is not currently\n\t *       being processed.  In this case the object can be queued\n\t *       back to heap_allocated with a few flags cleared, in effect\n\t *       cancelling the finalizer.\n\t */\n\tif (DUK_UNLIKELY(DUK_HEAPHDR_HAS_FINALIZABLE((duk_heaphdr *) ptr))) {\n\t\tduk_heaphdr *curr;\n\n\t\tDUK_D(DUK_DPRINT(\"duk_push_heapptr() with a pointer on finalize_list, autorescue\"));\n\n\t\tcurr = (duk_heaphdr *) ptr;\n\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\n\t\t/* Because FINALIZED is set prior to finalizer call, it will\n\t\t * be set for the object being currently finalized, but not\n\t\t * for other objects on finalize_list.\n\t\t */\n\t\tDUK_HEAPHDR_CLEAR_FINALIZED(curr);\n\n\t\t/* Dequeue object from finalize_list and queue it back to\n\t\t * heap_allocated.\n\t\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) >= 1);  /* Preincremented on finalize_list insert. */\n\t\tDUK_HEAPHDR_PREDEC_REFCOUNT(curr);\n#endif\n\t\tDUK_HEAP_REMOVE_FROM_FINALIZE_LIST(thr->heap, curr);\n\t\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(thr->heap, curr);\n\n\t\t/* Continue with the rest. */\n\t}\n\n\tswitch (DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) ptr)) {\n\tcase DUK_HTYPE_STRING:\n\t\tDUK_TVAL_SET_STRING(tv, (duk_hstring *) ptr);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tDUK_TVAL_SET_OBJECT(tv, (duk_hobject *) ptr);\n\t\tbreak;\n\tdefault:\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) ptr) == DUK_HTYPE_BUFFER);\n\t\tDUK_TVAL_SET_BUFFER(tv, (duk_hbuffer *) ptr);\n\t\tbreak;\n\t}\n\n\tDUK_HEAPHDR_INCREF(thr, (duk_heaphdr *) ptr);\n\n\treturn ret;\n}\n\n/* Push object with no prototype, i.e. a \"bare\" object. */\nDUK_EXTERNAL duk_idx_t duk_push_bare_object(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              -1);  /* no prototype */\n\treturn duk_get_top_index_unsafe(thr);\n}\n\nDUK_INTERNAL void duk_push_hstring(duk_hthread *thr, duk_hstring *h) {\n\tduk_tval tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_TVAL_SET_STRING(&tv, h);\n\tduk_push_tval(thr, &tv);\n}\n\nDUK_INTERNAL void duk_push_hstring_stridx(duk_hthread *thr, duk_small_uint_t stridx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n}\n\nDUK_INTERNAL void duk_push_hstring_empty(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_push_hstring(thr, DUK_HTHREAD_GET_STRING(thr, DUK_STRIDX_EMPTY_STRING));\n}\n\nDUK_INTERNAL void duk_push_hobject(duk_hthread *thr, duk_hobject *h) {\n\tduk_tval tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_TVAL_SET_OBJECT(&tv, h);\n\tduk_push_tval(thr, &tv);\n}\n\nDUK_INTERNAL void duk_push_hbuffer(duk_hthread *thr, duk_hbuffer *h) {\n\tduk_tval tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_TVAL_SET_BUFFER(&tv, h);\n\tduk_push_tval(thr, &tv);\n}\n\nDUK_INTERNAL void duk_push_hobject_bidx(duk_hthread *thr, duk_small_int_t builtin_idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(builtin_idx >= 0 && builtin_idx < DUK_NUM_BUILTINS);\n\tDUK_ASSERT(thr->builtins[builtin_idx] != NULL);\n\n\tduk_push_hobject(thr, thr->builtins[builtin_idx]);\n}\n\n/*\n *  Poppers\n */\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_n_unsafe_raw(duk_hthread *thr, duk_idx_t count) {\n\tduk_tval *tv;\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_tval *tv_end;\n#endif\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) count);\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\ttv = thr->valstack_top;\n\ttv_end = tv - count;\n\twhile (tv != tv_end) {\n\t\ttv--;\n\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t}\n\tthr->valstack_top = tv;\n\tDUK_REFZERO_CHECK_FAST(thr);\n#else\n\ttv = thr->valstack_top;\n\twhile (count > 0) {\n\t\tcount--;\n\t\ttv--;\n\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t}\n\tthr->valstack_top = tv;\n#endif\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n\nDUK_EXTERNAL void duk_pop_n(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\n\tif (DUK_UNLIKELY((duk_uidx_t) (thr->valstack_top - thr->valstack_bottom) < (duk_uidx_t) count)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(count >= 0);\n\n\tduk__pop_n_unsafe_raw(thr, count);\n}\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, count);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_pop_n_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk__pop_n_unsafe_raw(thr, count);\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/* Pop N elements without DECREF (in effect \"stealing\" any actual refcounts). */\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(count >= 0);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) count);\n\n\ttv = thr->valstack_top;\n\twhile (count > 0) {\n\t\tcount--;\n\t\ttv--;\n\t\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\t\tDUK_TVAL_SET_UNDEFINED(tv);\n\t}\n\tthr->valstack_top = tv;\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#else  /* DUK_USE_REFERENCE_COUNTING */\nDUK_INTERNAL void duk_pop_n_nodecref_unsafe(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, count);\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/* Popping one element is called so often that when footprint is not an issue,\n * compile a specialized function for it.\n */\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL void duk_pop(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, 1);\n}\nDUK_INTERNAL void duk_pop_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, 1);\n}\nDUK_INTERNAL void duk_pop_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_nodecref_unsafe(thr, 1);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_unsafe_raw(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);\n\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n#else\n\tDUK_TVAL_SET_UNDEFINED(tv);\n#endif\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\nDUK_EXTERNAL void duk_pop(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tif (DUK_UNLIKELY(thr->valstack_top == thr->valstack_bottom)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk__pop_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk__pop_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_nodecref_unsafe(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);\n\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n\tDUK_TVAL_SET_UNDEFINED(tv);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_pop_undefined(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_nodecref_unsafe(thr);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_pop_undefined(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 1);\n\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));\n\tthr->valstack_top--;\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_EXTERNAL void duk_pop_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, 2);\n}\nDUK_INTERNAL void duk_pop_2_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, 2);\n}\nDUK_INTERNAL void duk_pop_2_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_nodecref_unsafe(thr, 2);\n}\n#else\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__pop_2_unsafe_raw(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 2);\n\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n#else\n\tDUK_TVAL_SET_UNDEFINED(tv);\n#endif\n\ttv = --thr->valstack_top;\n\tDUK_ASSERT(tv >= thr->valstack_bottom);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);  /* side effects */\n#else\n\tDUK_TVAL_SET_UNDEFINED(tv);\n#endif\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\nDUK_EXTERNAL void duk_pop_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tif (DUK_UNLIKELY(thr->valstack_top - 2 < thr->valstack_bottom)) {\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk__pop_2_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_2_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk__pop_2_unsafe_raw(thr);\n}\nDUK_INTERNAL void duk_pop_2_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_top != thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) >= (duk_size_t) 2);\n\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 1));\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top - 2));\n\tthr->valstack_top -= 2;\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\nDUK_EXTERNAL void duk_pop_3(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n(thr, 3);\n}\n\nDUK_INTERNAL void duk_pop_3_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_unsafe(thr, 3);\n}\n\nDUK_INTERNAL void duk_pop_3_nodecref_unsafe(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_pop_n_nodecref_unsafe(thr, 3);\n}\n\n/*\n *  Pack and unpack (pack value stack entries into an array and vice versa)\n */\n\n/* XXX: pack index range? array index offset? */\n/* XXX: need ability to pack into a bare array? */\nDUK_INTERNAL void duk_pack(duk_hthread *thr, duk_idx_t count) {\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_tval *tv_curr;\n\tduk_tval *tv_limit;\n\tduk_idx_t top;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\ttop = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT(top >= 0);\n\tif (DUK_UNLIKELY((duk_uidx_t) count > (duk_uidx_t) top)) {\n\t\t/* Also handles negative count. */\n\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(count >= 0);\n\n\t/* Wrapping is controlled by the check above: value stack top can be\n\t * at most DUK_USE_VALSTACK_LIMIT which is low enough so that\n\t * multiplying with sizeof(duk_tval) won't wrap.\n\t */\n\tDUK_ASSERT(count >= 0 && count <= (duk_idx_t) DUK_USE_VALSTACK_LIMIT);\n\tDUK_ASSERT((duk_size_t) count <= DUK_SIZE_MAX / sizeof(duk_tval));  /* no wrapping */\n\n\ttv_dst = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) count);  /* XXX: uninitialized would be OK */\n\tDUK_ASSERT(count == 0 || tv_dst != NULL);\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\t/* Copy value stack values directly to the array part without\n\t * any refcount updates: net refcount changes are zero.\n\t */\n\ttv_src = thr->valstack_top - count - 1;\n\tduk_memcpy_unsafe((void *) tv_dst, (const void *) tv_src, (size_t) count * sizeof(duk_tval));\n\n\t/* Overwrite result array to final value stack location and wipe\n\t * the rest; no refcount operations needed.\n\t */\n\n\ttv_dst = tv_src;  /* when count == 0, same as tv_src (OK) */\n\ttv_src = thr->valstack_top - 1;\n\tDUK_TVAL_SET_TVAL(tv_dst, tv_src);\n\n\t/* XXX: internal helper to wipe a value stack segment? */\n\ttv_curr = tv_dst + 1;\n\ttv_limit = thr->valstack_top;\n\twhile (tv_curr != tv_limit) {\n\t\t/* Wipe policy: keep as 'undefined'. */\n\t\tDUK_TVAL_SET_UNDEFINED(tv_curr);\n\t\ttv_curr++;\n\t}\n\tthr->valstack_top = tv_dst + 1;\n}\n\nDUK_INTERNAL duk_idx_t duk_unpack_array_like(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv = duk_require_tval(thr, idx);\n\tif (DUK_LIKELY(DUK_TVAL_IS_OBJECT(tv))) {\n\t\tduk_hobject *h;\n\t\tduk_uint32_t len;\n\t\tduk_uint32_t i;\n\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_UNREF(h);\n\n#if defined(DUK_USE_ARRAY_FASTPATH)  /* close enough */\n\t\tif (DUK_LIKELY(DUK_HOBJECT_IS_ARRAY(h) &&\n\t\t               ((duk_harray *) h)->length <= DUK_HOBJECT_GET_ASIZE(h))) {\n\t\t\tduk_harray *h_arr;\n\t\t\tduk_tval *tv_src;\n\t\t\tduk_tval *tv_dst;\n\n\t\t\th_arr = (duk_harray *) h;\n\t\t\tlen = h_arr->length;\n\t\t\tif (DUK_UNLIKELY(len >= 0x80000000UL)) {\n\t\t\t\tgoto fail_over_2g;\n\t\t\t}\n\t\t\tduk_require_stack(thr, (duk_idx_t) len);\n\n\t\t\t/* The potential allocation in duk_require_stack() may\n\t\t\t * run a finalizer which modifies the argArray so that\n\t\t\t * e.g. becomes sparse.  So, we need to recheck that the\n\t\t\t * array didn't change size and that there's still a\n\t\t\t * valid backing array part.\n\t\t\t *\n\t\t\t * XXX: alternatively, could prevent finalizers for the\n\t\t\t * duration.\n\t\t\t */\n\t\t\tif (DUK_UNLIKELY(len != h_arr->length ||\n\t\t\t                 h_arr->length > DUK_HOBJECT_GET_ASIZE((duk_hobject *) h_arr))) {\n\t\t\t\tgoto skip_fast;\n\t\t\t}\n\n\t\t\t/* Main fast path: arguments array is almost always\n\t\t\t * an actual array (though it might also be an arguments\n\t\t\t * object).\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path for %ld elements\", (long) h_arr->length));\n\t\t\ttv_src = DUK_HOBJECT_A_GET_BASE(thr->heap, h);\n\t\t\ttv_dst = thr->valstack_top;\n\t\t\twhile (len-- > 0) {\n\t\t\t\tDUK_ASSERT(tv_dst < thr->valstack_end);\n\t\t\t\tif (DUK_UNLIKELY(DUK_TVAL_IS_UNUSED(tv_src))) {\n\t\t\t\t\t/* Gaps are very unlikely.  Skip over them,\n\t\t\t\t\t * without an ancestor lookup (technically\n\t\t\t\t\t * not compliant).\n\t\t\t\t\t */\n\t\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_dst));  /* valstack policy */\n\t\t\t\t} else {\n\t\t\t\t\tDUK_TVAL_SET_TVAL(tv_dst, tv_src);\n\t\t\t\t\tDUK_TVAL_INCREF(thr, tv_dst);\n\t\t\t\t}\n\t\t\t\ttv_src++;\n\t\t\t\ttv_dst++;\n\t\t\t}\n\t\t\tDUK_ASSERT(tv_dst <= thr->valstack_end);\n\t\t\tthr->valstack_top = tv_dst;\n\t\t\treturn (duk_idx_t) h_arr->length;\n\t\t}\n\t skip_fast:\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\n\t\t/* Slow path: actual lookups.  The initial 'length' lookup\n\t\t * decides the output length, regardless of side effects that\n\t\t * may resize or change the argArray while we read the\n\t\t * indices.\n\t\t */\n\t\tidx = duk_normalize_index(thr, idx);\n\t\tduk_get_prop_stridx(thr, idx, DUK_STRIDX_LENGTH);\n\t\tlen = duk_to_uint32(thr, -1);  /* ToUint32() coercion required */\n\t\tif (DUK_UNLIKELY(len >= 0x80000000UL)) {\n\t\t\tgoto fail_over_2g;\n\t\t}\n\t\tduk_pop_unsafe(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"slow path for %ld elements\", (long) len));\n\n\t\tduk_require_stack(thr, (duk_idx_t) len);\n\t\tfor (i = 0; i < len; i++) {\n\t\t\tduk_get_prop_index(thr, idx, (duk_uarridx_t) i);\n\t\t}\n\t\treturn (duk_idx_t) len;\n\t} else if (DUK_TVAL_IS_UNDEFINED(tv) || DUK_TVAL_IS_NULL(tv)) {\n\t\treturn 0;\n\t}\n\n\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\tDUK_WO_NORETURN(return 0;);\n\n fail_over_2g:\n\tDUK_ERROR_RANGE_INVALID_LENGTH(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/*\n *  Error throwing\n */\n\nDUK_EXTERNAL void duk_throw_raw(duk_hthread *thr) {\n\tduk_tval *tv_val;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\n\tif (DUK_UNLIKELY(thr->valstack_top == thr->valstack_bottom)) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* Errors are augmented when they are created, not when they are\n\t * thrown or re-thrown.  The current error handler, however, runs\n\t * just before an error is thrown.\n\t */\n\n\t/* Sync so that augmentation sees up-to-date activations, NULL\n\t * thr->ptr_curr_pc so that it's not used if side effects occur\n\t * in augmentation or longjmp handling.\n\t */\n\tduk_hthread_sync_and_null_currpc(thr);\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (API): %!dT (before throw augment)\", (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_err_augment_error_throw(thr);\n#endif\n\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (API): %!dT (after throw augment)\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\ttv_val = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, tv_val);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_err_check_debugger_integration(thr);\n#endif\n\n\t/* thr->heap->lj.jmpbuf_ptr is checked by duk_err_longjmp() so we don't\n\t * need to check that here.  If the value is NULL, a fatal error occurs\n\t * because we can't return.\n\t */\n\n\tduk_err_longjmp(thr);\n\tDUK_UNREACHABLE();\n}\n\nDUK_EXTERNAL void duk_fatal_raw(duk_hthread *thr, const char *err_msg) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->heap->fatal_func != NULL);\n\n\tDUK_D(DUK_DPRINT(\"fatal error occurred: %s\", err_msg ? err_msg : \"NULL\"));\n\n\t/* fatal_func should be noreturn, but noreturn declarations on function\n\t * pointers has a very spotty support apparently so it's not currently\n\t * done.\n\t */\n\tthr->heap->fatal_func(thr->heap->heap_udata, err_msg);\n\n\t/* If the fatal handler returns, all bets are off.  It'd be nice to\n\t * print something here but since we don't want to depend on stdio,\n\t * there's no way to do so portably.\n\t */\n\tDUK_D(DUK_DPRINT(\"fatal error handler returned, all bets are off!\"));\n\tfor (;;) {\n\t\t/* loop forever, don't return (function marked noreturn) */\n\t}\n}\n\nDUK_EXTERNAL void duk_error_va_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\t(void) duk_throw(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_error_raw(duk_hthread *thr, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...) {\n\tva_list ap;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tva_start(ap, fmt);\n\tduk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\tva_end(ap);\n\t(void) duk_throw(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n#if !defined(DUK_USE_VARIADIC_MACROS)\nDUK_NORETURN(DUK_LOCAL_DECL void duk__throw_error_from_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, va_list ap));\n\nDUK_LOCAL void duk__throw_error_from_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, va_list ap) {\n\tconst char *filename;\n\tduk_int_t line;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tfilename = duk_api_global_filename;\n\tline = duk_api_global_line;\n\tduk_api_global_filename = NULL;\n\tduk_api_global_line = 0;\n\n\tduk_push_error_object_va_raw(thr, err_code, filename, line, fmt, ap);\n\t(void) duk_throw(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n#define DUK__ERROR_STASH_SHARED(code) do { \\\n\t\tva_list ap; \\\n\t\tva_start(ap, fmt); \\\n\t\tduk__throw_error_from_stash(thr, (code), fmt, ap); \\\n\t\tva_end(ap); \\\n\t\tDUK_WO_NORETURN(return 0;); \\\n\t} while (0)\n\nDUK_EXTERNAL duk_ret_t duk_error_stash(duk_hthread *thr, duk_errcode_t err_code, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(err_code);\n}\nDUK_EXTERNAL duk_ret_t duk_generic_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_eval_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_EVAL_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_range_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_RANGE_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_reference_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_REFERENCE_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_syntax_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_SYNTAX_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_type_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_TYPE_ERROR);\n}\nDUK_EXTERNAL duk_ret_t duk_uri_error_stash(duk_hthread *thr, const char *fmt, ...) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK__ERROR_STASH_SHARED(DUK_ERR_URI_ERROR);\n}\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n/*\n *  Comparison\n */\n\nDUK_EXTERNAL duk_bool_t duk_equals(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_get_tval(thr, idx1);\n\ttv2 = duk_get_tval(thr, idx2);\n\tif ((tv1 == NULL) || (tv2 == NULL)) {\n\t\treturn 0;\n\t}\n\n\t/* Coercion may be needed, the helper handles that by pushing the\n\t * tagged values to the stack.\n\t */\n\treturn duk_js_equals(thr, tv1, tv2);\n}\n\nDUK_EXTERNAL duk_bool_t duk_strict_equals(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_get_tval(thr, idx1);\n\ttv2 = duk_get_tval(thr, idx2);\n\tif ((tv1 == NULL) || (tv2 == NULL)) {\n\t\treturn 0;\n\t}\n\n\t/* No coercions or other side effects, so safe */\n\treturn duk_js_strict_equals(tv1, tv2);\n}\n\nDUK_EXTERNAL duk_bool_t duk_samevalue(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\ttv1 = duk_get_tval(thr, idx1);\n\ttv2 = duk_get_tval(thr, idx2);\n\tif ((tv1 == NULL) || (tv2 == NULL)) {\n\t\treturn 0;\n\t}\n\n\t/* No coercions or other side effects, so safe */\n\treturn duk_js_samevalue(tv1, tv2);\n}\n\n/*\n *  instanceof\n */\n\nDUK_EXTERNAL duk_bool_t duk_instanceof(duk_hthread *thr, duk_idx_t idx1, duk_idx_t idx2) {\n\tduk_tval *tv1, *tv2;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* Index validation is strict, which differs from duk_equals().\n\t * The strict behavior mimics how instanceof itself works, e.g.\n\t * it is a TypeError if rval is not a -callable- object.  It would\n\t * be somewhat inconsistent if rval would be allowed to be\n\t * non-existent without a TypeError.\n\t */\n\ttv1 = duk_require_tval(thr, idx1);\n\tDUK_ASSERT(tv1 != NULL);\n\ttv2 = duk_require_tval(thr, idx2);\n\tDUK_ASSERT(tv2 != NULL);\n\n\treturn duk_js_instanceof(thr, tv1, tv2);\n}\n\n/*\n *  Lightfunc\n */\n\nDUK_INTERNAL void duk_push_lightfunc_name_raw(duk_hthread *thr, duk_c_function func, duk_small_uint_t lf_flags) {\n\t/* Lightfunc name, includes Duktape/C native function pointer, which\n\t * can often be used to locate the function from a symbol table.\n\t * The name also includes the 16-bit duk_tval flags field because it\n\t * includes the magic value.  Because a single native function often\n\t * provides different functionality depending on the magic value, it\n\t * seems reasonably to include it in the name.\n\t *\n\t * On the other hand, a complicated name increases string table\n\t * pressure in low memory environments (but only when function name\n\t * is accessed).\n\t */\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk_push_literal(thr, \"light_\");\n\tduk_push_string_funcptr(thr, (duk_uint8_t *) &func, sizeof(func));\n\tduk_push_sprintf(thr, \"_%04x\", (unsigned int) lf_flags);\n\tduk_concat(thr, 3);\n}\n\nDUK_INTERNAL void duk_push_lightfunc_name(duk_hthread *thr, duk_tval *tv) {\n\tduk_c_function func;\n\tduk_small_uint_t lf_flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv));\n\n\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);\n\tduk_push_lightfunc_name_raw(thr, func, lf_flags);\n}\n\nDUK_INTERNAL void duk_push_lightfunc_tostring(duk_hthread *thr, duk_tval *tv) {\n\tduk_c_function func;\n\tduk_small_uint_t lf_flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv));\n\n\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);  /* read before 'tv' potentially invalidated */\n\tduk_push_literal(thr, \"function \");\n\tduk_push_lightfunc_name_raw(thr, func, lf_flags);\n\tduk_push_literal(thr, \"() { [lightfunc code] }\");\n\tduk_concat(thr, 3);\n}\n\n/*\n *  Function pointers\n *\n *  Printing function pointers is non-portable, so we do that by hex printing\n *  bytes from memory.\n */\n\nDUK_INTERNAL void duk_push_string_funcptr(duk_hthread *thr, duk_uint8_t *ptr, duk_size_t sz) {\n\tduk_uint8_t buf[32 * 2];\n\tduk_uint8_t *p, *q;\n\tduk_small_uint_t i;\n\tduk_small_uint_t t;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(sz <= 32);  /* sanity limit for function pointer size */\n\n\tp = buf;\n#if defined(DUK_USE_INTEGER_LE)\n\tq = ptr + sz;\n#else\n\tq = ptr;\n#endif\n\tfor (i = 0; i < sz; i++) {\n#if defined(DUK_USE_INTEGER_LE)\n\t\tt = *(--q);\n#else\n\t\tt = *(q++);\n#endif\n\t\t*p++ = duk_lc_digits[t >> 4];\n\t\t*p++ = duk_lc_digits[t & 0x0f];\n\t}\n\n\tduk_push_lstring(thr, (const char *) buf, sz * 2);\n}\n\n/*\n *  Push readable string summarizing duk_tval.  The operation is side effect\n *  free and will only throw from internal errors (e.g. out of memory).\n *  This is used by e.g. property access code to summarize a key/base safely,\n *  and is not intended to be fast (but small and safe).\n */\n\n/* String limits for summary strings. */\n#define DUK__READABLE_SUMMARY_MAXCHARS 96  /* maximum supported by helper */\n#define DUK__READABLE_STRING_MAXCHARS  32  /* for strings/symbols */\n#define DUK__READABLE_ERRMSG_MAXCHARS  96  /* for error messages */\n\n/* String sanitizer which escapes ASCII control characters and a few other\n * ASCII characters, passes Unicode as is, and replaces invalid UTF-8 with\n * question marks.  No errors are thrown for any input string, except in out\n * of memory situations.\n */\nDUK_LOCAL void duk__push_hstring_readable_unicode(duk_hthread *thr, duk_hstring *h_input, duk_small_uint_t maxchars) {\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_uint8_t buf[DUK_UNICODE_MAX_XUTF8_LENGTH * DUK__READABLE_SUMMARY_MAXCHARS +\n\t                2 /*quotes*/ + 3 /*periods*/];\n\tduk_uint8_t *q;\n\tduk_ucodepoint_t cp;\n\tduk_small_uint_t nchars;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(h_input != NULL);\n\tDUK_ASSERT(maxchars <= DUK__READABLE_SUMMARY_MAXCHARS);\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\tq = buf;\n\n\tnchars = 0;\n\t*q++ = (duk_uint8_t) DUK_ASC_SINGLEQUOTE;\n\tfor (;;) {\n\t\tif (p >= p_end) {\n\t\t\tbreak;\n\t\t}\n\t\tif (nchars == maxchars) {\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_PERIOD;\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_PERIOD;\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_PERIOD;\n\t\t\tbreak;\n\t\t}\n\t\tif (duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp)) {\n\t\t\tif (cp < 0x20 || cp == 0x7f || cp == DUK_ASC_SINGLEQUOTE || cp == DUK_ASC_BACKSLASH) {\n\t\t\t\tDUK_ASSERT(DUK_UNICODE_MAX_XUTF8_LENGTH >= 4);  /* estimate is valid */\n\t\t\t\tDUK_ASSERT((cp >> 4) <= 0x0f);\n\t\t\t\t*q++ = (duk_uint8_t) DUK_ASC_BACKSLASH;\n\t\t\t\t*q++ = (duk_uint8_t) DUK_ASC_LC_X;\n\t\t\t\t*q++ = (duk_uint8_t) duk_lc_digits[cp >> 4];\n\t\t\t\t*q++ = (duk_uint8_t) duk_lc_digits[cp & 0x0f];\n\t\t\t} else {\n\t\t\t\tq += duk_unicode_encode_xutf8(cp, q);\n\t\t\t}\n\t\t} else {\n\t\t\tp++;  /* advance manually */\n\t\t\t*q++ = (duk_uint8_t) DUK_ASC_QUESTION;\n\t\t}\n\t\tnchars++;\n\t}\n\t*q++ = (duk_uint8_t) DUK_ASC_SINGLEQUOTE;\n\n\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) (q - buf));\n}\n\nDUK_LOCAL const char *duk__push_string_tval_readable(duk_hthread *thr, duk_tval *tv, duk_bool_t error_aware) {\n\tDUK_CTX_ASSERT_VALID(thr);\n\t/* 'tv' may be NULL */\n\n\tif (tv == NULL) {\n\t\tduk_push_literal(thr, \"none\");\n\t} else {\n\t\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\t\tcase DUK_TAG_STRING: {\n\t\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\t\tif (DUK_HSTRING_HAS_SYMBOL(h)) {\n\t\t\t\t/* XXX: string summary produces question marks\n\t\t\t\t * so this is not very ideal.\n\t\t\t\t */\n\t\t\t\tduk_push_literal(thr, \"[Symbol \");\n\t\t\t\tduk_push_string(thr, duk__get_symbol_type_string(h));\n\t\t\t\tduk_push_literal(thr, \" \");\n\t\t\t\tduk__push_hstring_readable_unicode(thr, h, DUK__READABLE_STRING_MAXCHARS);\n\t\t\t\tduk_push_literal(thr, \"]\");\n\t\t\t\tduk_concat(thr, 5);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tduk__push_hstring_readable_unicode(thr, h, DUK__READABLE_STRING_MAXCHARS);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_OBJECT: {\n\t\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\t\tDUK_ASSERT(h != NULL);\n\n\t\t\tif (error_aware &&\n\t\t\t    duk_hobject_prototype_chain_contains(thr, h, thr->builtins[DUK_BIDX_ERROR_PROTOTYPE], 1 /*ignore_loop*/)) {\n\t\t\t\t/* Get error message in a side effect free way if\n\t\t\t\t * possible; if not, summarize as a generic object.\n\t\t\t\t * Error message currently gets quoted.\n\t\t\t\t */\n\t\t\t\t/* XXX: better internal getprop call; get without side effects\n\t\t\t\t * but traverse inheritance chain.\n\t\t\t\t */\n\t\t\t\tduk_tval *tv_msg;\n\t\t\t\ttv_msg = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, h, DUK_STRIDX_MESSAGE);\n\t\t\t\tif (tv_msg != NULL && DUK_TVAL_IS_STRING(tv_msg)) {\n\t\t\t\t\t/* It's critical to avoid recursion so\n\t\t\t\t\t * only summarize a string .message.\n\t\t\t\t\t */\n\t\t\t\t\tduk__push_hstring_readable_unicode(thr, DUK_TVAL_GET_STRING(tv_msg), DUK__READABLE_ERRMSG_MAXCHARS);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tduk_push_class_string_tval(thr, tv, 1 /*avoid_side_effects*/);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_BUFFER: {\n\t\t\t/* While plain buffers mimic Uint8Arrays, they summarize differently.\n\t\t\t * This is useful so that the summarized string accurately reflects the\n\t\t\t * internal type which may matter for figuring out bugs etc.\n\t\t\t */\n\t\t\t/* XXX: Hex encoded, length limited buffer summary here? */\n\t\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv);\n\t\t\tDUK_ASSERT(h != NULL);\n\t\t\tduk_push_sprintf(thr, \"[buffer:%ld]\", (long) DUK_HBUFFER_GET_SIZE(h));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_POINTER: {\n\t\t\t/* Surround with parentheses like in JX, ensures NULL pointer\n\t\t\t * is distinguishable from null value (\"(null)\" vs \"null\").\n\t\t\t */\n\t\t\tduk_push_tval(thr, tv);\n\t\t\tduk_push_sprintf(thr, \"(%s)\", duk_to_string(thr, -1));\n\t\t\tduk_remove_m2(thr);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tduk_push_tval(thr, tv);\n\t\t\tbreak;\n\t\t}\n\t\t}\n\t}\n\n\treturn duk_to_string(thr, -1);\n}\nDUK_INTERNAL const char *duk_push_string_tval_readable(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__push_string_tval_readable(thr, tv, 0 /*error_aware*/);\n}\n\nDUK_INTERNAL const char *duk_push_string_readable(duk_hthread *thr, duk_idx_t idx) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk_push_string_tval_readable(thr, duk_get_tval(thr, idx));\n}\n\nDUK_INTERNAL const char *duk_push_string_tval_readable_error(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\treturn duk__push_string_tval_readable(thr, tv, 1 /*error_aware*/);\n}\n\nDUK_INTERNAL void duk_push_symbol_descriptive_string(duk_hthread *thr, duk_hstring *h) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint8_t *q;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* .toString() */\n\tduk_push_literal(thr, \"Symbol(\");\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tp_end = p + DUK_HSTRING_GET_BYTELEN(h);\n\tDUK_ASSERT(p[0] == 0xff || (p[0] & 0xc0) == 0x80);\n\tp++;\n\tfor (q = p; q < p_end; q++) {\n\t\tif (*q == 0xffU) {\n\t\t\t/* Terminate either at end-of-string (but NUL MUST\n\t\t\t * be accepted without terminating description) or\n\t\t\t * 0xFF, which is used to mark start of unique trailer\n\t\t\t * (and cannot occur in CESU-8 / extended UTF-8).\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\t}\n\tduk_push_lstring(thr, (const char *) p, (duk_size_t) (q - p));\n\tduk_push_literal(thr, \")\");\n\tduk_concat(thr, 3);\n}\n\n/*\n *  Functions\n */\n\n#if 0  /* not used yet */\nDUK_INTERNAL void duk_push_hnatfunc_name(duk_hthread *thr, duk_hnatfunc *h) {\n\tduk_c_function func;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h));\n\n\tduk_push_sprintf(thr, \"native_\");\n\tfunc = h->func;\n\tduk_push_string_funcptr(thr, (duk_uint8_t *) &func, sizeof(func));\n\tduk_push_sprintf(thr, \"_%04x_%04x\",\n\t                 (unsigned int) (duk_uint16_t) h->nargs,\n\t                 (unsigned int) (duk_uint16_t) h->magic);\n\tduk_concat(thr, 3);\n}\n#endif\n\n/*\n *  duk_tval slice copy\n */\n\nDUK_INTERNAL void duk_copy_tvals_incref(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_size_t count) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n\tDUK_ASSERT(count * sizeof(duk_tval) >= count);  /* no wrap */\n\n\tduk_memcpy_unsafe((void *) tv_dst, (const void *) tv_src, count * sizeof(duk_tval));\n\n\ttv = tv_dst;\n\twhile (count-- > 0) {\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\ttv++;\n\t}\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_api_string.c",
    "content": "/*\n *  String manipulation\n */\n\n#include \"duk_internal.h\"\n\nDUK_LOCAL void duk__concat_and_join_helper(duk_hthread *thr, duk_idx_t count_in, duk_bool_t is_join) {\n\tduk_uint_t count;\n\tduk_uint_t i;\n\tduk_size_t idx;\n\tduk_size_t len;\n\tduk_hstring *h;\n\tduk_uint8_t *buf;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tif (DUK_UNLIKELY(count_in <= 0)) {\n\t\tif (count_in < 0) {\n\t\t\tDUK_ERROR_RANGE_INVALID_COUNT(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tDUK_ASSERT(count_in == 0);\n\t\tduk_push_hstring_empty(thr);\n\t\treturn;\n\t}\n\tcount = (duk_uint_t) count_in;\n\n\tif (is_join) {\n\t\tduk_size_t t1, t2, limit;\n\t\th = duk_to_hstring(thr, -((duk_idx_t) count) - 1);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* A bit tricky overflow test, see doc/code-issues.rst. */\n\t\tt1 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);\n\t\tt2 = (duk_size_t) (count - 1);\n\t\tlimit = (duk_size_t) DUK_HSTRING_MAX_BYTELEN;\n\t\tif (DUK_UNLIKELY(t2 != 0 && t1 > limit / t2)) {\n\t\t\t/* Combined size of separators already overflows. */\n\t\t\tgoto error_overflow;\n\t\t}\n\t\tlen = (duk_size_t) (t1 * t2);\n\t} else {\n\t\tlen = (duk_size_t) 0;\n\t}\n\n\tfor (i = count; i >= 1; i--) {\n\t\tduk_size_t new_len;\n\t\th = duk_to_hstring(thr, -((duk_idx_t) i));\n\t\tnew_len = len + (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);\n\n\t\t/* Impose a string maximum length, need to handle overflow\n\t\t * correctly.\n\t\t */\n\t\tif (new_len < len ||  /* wrapped */\n\t\t    new_len > (duk_size_t) DUK_HSTRING_MAX_BYTELEN) {\n\t\t\tgoto error_overflow;\n\t\t}\n\t\tlen = new_len;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"join/concat %lu strings, total length %lu bytes\",\n\t                     (unsigned long) count, (unsigned long) len));\n\n\t/* Use stack allocated buffer to ensure reachability in errors\n\t * (e.g. intern error).\n\t */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len);\n\tDUK_ASSERT(buf != NULL);\n\n\t/* [ ... (sep) str1 str2 ... strN buf ] */\n\n\tidx = 0;\n\tfor (i = count; i >= 1; i--) {\n\t\tif (is_join && i != count) {\n\t\t\th = duk_require_hstring(thr, -((duk_idx_t) count) - 2);  /* extra -1 for buffer */\n\t\t\tduk_memcpy(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\t\t\tidx += DUK_HSTRING_GET_BYTELEN(h);\n\t\t}\n\t\th = duk_require_hstring(thr, -((duk_idx_t) i) - 1);  /* extra -1 for buffer */\n\t\tduk_memcpy(buf + idx, DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\t\tidx += DUK_HSTRING_GET_BYTELEN(h);\n\t}\n\n\tDUK_ASSERT(idx == len);\n\n\t/* [ ... (sep) str1 str2 ... strN buf ] */\n\n\t/* Get rid of the strings early to minimize memory use before intern. */\n\n\tif (is_join) {\n\t\tduk_replace(thr, -((duk_idx_t) count) - 2);  /* overwrite sep */\n\t\tduk_pop_n(thr, (duk_idx_t) count);\n\t} else {\n\t\tduk_replace(thr, -((duk_idx_t) count) - 1);  /* overwrite str1 */\n\t\tduk_pop_n(thr, (duk_idx_t) (count - 1));\n\t}\n\n\t/* [ ... buf ] */\n\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if inputs are safe. */\n\n\t/* [ ... res ] */\n\treturn;\n\n error_overflow:\n\tDUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_EXTERNAL void duk_concat(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__concat_and_join_helper(thr, count, 0 /*is_join*/);\n}\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_INTERNAL void duk_concat_2(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tduk_concat(thr, 2);\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_INTERNAL void duk_concat_2(duk_hthread *thr) {\n\tduk_hstring *h1;\n\tduk_hstring *h2;\n\tduk_uint8_t *buf;\n\tduk_size_t len1;\n\tduk_size_t len2;\n\tduk_size_t len;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(duk_get_top(thr) >= 2);  /* Trusted caller. */\n\n\th1 = duk_to_hstring(thr, -2);\n\th2 = duk_to_hstring(thr, -1);\n\tlen1 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1);\n\tlen2 = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2);\n\tlen = len1 + len2;\n\tif (DUK_UNLIKELY(len < len1 ||  /* wrapped */\n\t                 len > (duk_size_t) DUK_HSTRING_MAX_BYTELEN)) {\n\t\tgoto error_overflow;\n\t}\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, len);\n\tDUK_ASSERT(buf != NULL);\n\n\tduk_memcpy((void *) buf, (const void *) DUK_HSTRING_GET_DATA(h1), (size_t) len1);\n\tduk_memcpy((void *) (buf + len1), (const void *) DUK_HSTRING_GET_DATA(h2), (size_t) len2);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if inputs are safe. */\n\n\t/* [ ... str1 str2 buf ] */\n\n\tduk_replace(thr, -3);\n\tduk_pop_unsafe(thr);\n\treturn;\n\n error_overflow:\n\tDUK_ERROR_RANGE(thr, DUK_STR_RESULT_TOO_LONG);\n\tDUK_WO_NORETURN(return;);\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\nDUK_EXTERNAL void duk_join(duk_hthread *thr, duk_idx_t count) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tduk__concat_and_join_helper(thr, count, 1 /*is_join*/);\n}\n\n/* XXX: could map/decode be unified with duk_unicode_support.c code?\n * Case conversion needs also the character surroundings though.\n */\n\nDUK_EXTERNAL void duk_decode_string(duk_hthread *thr, duk_idx_t idx, duk_decode_char_function callback, void *udata) {\n\tduk_hstring *h_input;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\th_input = duk_require_hstring(thr, idx);  /* Accept symbols. */\n\tDUK_ASSERT(h_input != NULL);\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\n\tfor (;;) {\n\t\tif (p >= p_end) {\n\t\t\tbreak;\n\t\t}\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end);\n\t\tcallback(udata, cp);\n\t}\n}\n\nDUK_EXTERNAL void duk_map_string(duk_hthread *thr, duk_idx_t idx, duk_map_char_function callback, void *udata) {\n\tduk_hstring *h_input;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_normalize_index(thr, idx);\n\n\th_input = duk_require_hstring(thr, idx);  /* Accept symbols. */\n\tDUK_ASSERT(h_input != NULL);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input));  /* Reasonable output estimate. */\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\n\tfor (;;) {\n\t\t/* XXX: could write output in chunks with fewer ensure calls,\n\t\t * but relative benefit would be small here.\n\t\t */\n\n\t\tif (p >= p_end) {\n\t\t\tbreak;\n\t\t}\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end);\n\t\tcp = callback(udata, cp);\n\n\t\tDUK_BW_WRITE_ENSURE_XUTF8(thr, bw, cp);\n\t}\n\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe, extended UTF-8 encoded. */\n\tduk_replace(thr, idx);\n}\n\nDUK_EXTERNAL void duk_substring(duk_hthread *thr, duk_idx_t idx, duk_size_t start_offset, duk_size_t end_offset) {\n\tduk_hstring *h;\n\tduk_hstring *res;\n\tduk_size_t start_byte_offset;\n\tduk_size_t end_byte_offset;\n\tduk_size_t charlen;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);  /* Accept symbols. */\n\th = duk_require_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tcharlen = DUK_HSTRING_GET_CHARLEN(h);\n\tif (end_offset >= charlen) {\n\t\tend_offset = charlen;\n\t}\n\tif (start_offset > end_offset) {\n\t\tstart_offset = end_offset;\n\t}\n\n\tDUK_ASSERT_DISABLE(start_offset >= 0);\n\tDUK_ASSERT(start_offset <= end_offset && start_offset <= DUK_HSTRING_GET_CHARLEN(h));\n\tDUK_ASSERT_DISABLE(end_offset >= 0);\n\tDUK_ASSERT(end_offset >= start_offset && end_offset <= DUK_HSTRING_GET_CHARLEN(h));\n\n\t/* Guaranteed by string limits. */\n\tDUK_ASSERT(start_offset <= DUK_UINT32_MAX);\n\tDUK_ASSERT(end_offset <= DUK_UINT32_MAX);\n\n\tstart_byte_offset = (duk_size_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) start_offset);\n\tend_byte_offset = (duk_size_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) end_offset);\n\n\tDUK_ASSERT(end_byte_offset >= start_byte_offset);\n\tDUK_ASSERT(end_byte_offset - start_byte_offset <= DUK_UINT32_MAX);  /* Guaranteed by string limits. */\n\n\t/* No size check is necessary. */\n\tres = duk_heap_strtable_intern_checked(thr,\n\t                                       DUK_HSTRING_GET_DATA(h) + start_byte_offset,\n\t                                       (duk_uint32_t) (end_byte_offset - start_byte_offset));\n\n\tduk_push_hstring(thr, res);\n\tduk_replace(thr, idx);\n}\n\n/* XXX: this is quite clunky.  Add Unicode helpers to scan backwards and\n * forwards with a callback to process codepoints?\n */\nDUK_EXTERNAL void duk_trim(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p, *p_start, *p_end, *p_tmp1, *p_tmp2;  /* pointers for scanning */\n\tconst duk_uint8_t *q_start, *q_end;  /* start (incl) and end (excl) of trimmed part */\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\tidx = duk_require_normalize_index(thr, idx);  /* Accept symbols. */\n\th = duk_require_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\tp_start = DUK_HSTRING_GET_DATA(h);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h);\n\n\tp = p_start;\n\twhile (p < p_end) {\n\t\tp_tmp1 = p;\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p_tmp1, p_start, p_end);\n\t\tif (!(duk_unicode_is_whitespace(cp) || duk_unicode_is_line_terminator(cp))) {\n\t\t\tbreak;\n\t\t}\n\t\tp = p_tmp1;\n\t}\n\tq_start = p;\n\tif (p == p_end) {\n\t\t/* Entire string is whitespace. */\n\t\tq_end = p;\n\t\tgoto scan_done;\n\t}\n\n\tp = p_end;\n\twhile (p > p_start) {\n\t\tp_tmp1 = p;\n\t\twhile (p > p_start) {\n\t\t\tp--;\n\t\t\tif (((*p) & 0xc0) != 0x80) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tp_tmp2 = p;\n\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p_tmp2, p_start, p_end);\n\t\tif (!(duk_unicode_is_whitespace(cp) || duk_unicode_is_line_terminator(cp))) {\n\t\t\tp = p_tmp1;\n\t\t\tbreak;\n\t\t}\n\t}\n\tq_end = p;\n\n scan_done:\n\t/* This may happen when forward and backward scanning disagree\n\t * (possible for non-extended-UTF-8 strings).\n\t */\n\tif (q_end < q_start) {\n\t\tq_end = q_start;\n\t}\n\n\tDUK_ASSERT(q_start >= p_start && q_start <= p_end);\n\tDUK_ASSERT(q_end >= p_start && q_end <= p_end);\n\tDUK_ASSERT(q_end >= q_start);\n\n\tDUK_DDD(DUK_DDDPRINT(\"trim: p_start=%p, p_end=%p, q_start=%p, q_end=%p\",\n\t                     (const void *) p_start, (const void *) p_end,\n\t                     (const void *) q_start, (const void *) q_end));\n\n\tif (q_start == p_start && q_end == p_end) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"nothing was trimmed: avoid interning (hashing etc)\"));\n\t\treturn;\n\t}\n\n\tduk_push_lstring(thr, (const char *) q_start, (duk_size_t) (q_end - q_start));\n\tduk_replace(thr, idx);\n}\n\nDUK_EXTERNAL duk_codepoint_t duk_char_code_at(duk_hthread *thr, duk_idx_t idx, duk_size_t char_offset) {\n\tduk_hstring *h;\n\tduk_ucodepoint_t cp;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\n\t/* XXX: Share code with String.prototype.charCodeAt?  Main difference\n\t * is handling of clamped offsets.\n\t */\n\n\th = duk_require_hstring(thr, idx);  /* Accept symbols. */\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_ASSERT_DISABLE(char_offset >= 0);  /* Always true, arg is unsigned. */\n\tif (char_offset >= DUK_HSTRING_GET_CHARLEN(h)) {\n\t\treturn 0;\n\t}\n\n\tDUK_ASSERT(char_offset <= DUK_UINT_MAX);  /* Guaranteed by string limits. */\n\tcp = duk_hstring_char_code_at_raw(thr, h, (duk_uint_t) char_offset, 0 /*surrogate_aware*/);\n\treturn (duk_codepoint_t) cp;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_api_time.c",
    "content": "/*\n *  Date/time.\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL duk_double_t duk_time_get_ecmascript_time(duk_hthread *thr) {\n\t/* ECMAScript time, with millisecond fractions.  Exposed via\n\t * duk_get_now() for example.\n\t */\n\tDUK_UNREF(thr);\n\treturn (duk_double_t) DUK_USE_DATE_GET_NOW(thr);\n}\n\nDUK_INTERNAL duk_double_t duk_time_get_ecmascript_time_nofrac(duk_hthread *thr) {\n\t/* ECMAScript time without millisecond fractions.  Exposed via\n\t * the Date built-in which doesn't allow fractions.\n\t */\n\tDUK_UNREF(thr);\n\treturn (duk_double_t) DUK_FLOOR(DUK_USE_DATE_GET_NOW(thr));\n}\n\nDUK_INTERNAL duk_double_t duk_time_get_monotonic_time(duk_hthread *thr) {\n\tDUK_UNREF(thr);\n#if defined(DUK_USE_GET_MONOTONIC_TIME)\n\treturn (duk_double_t) DUK_USE_GET_MONOTONIC_TIME(thr);\n#else\n\treturn (duk_double_t) DUK_USE_DATE_GET_NOW(thr);\n#endif\n}\n\nDUK_EXTERNAL duk_double_t duk_get_now(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n\n\t/* This API intentionally allows millisecond fractions. */\n\treturn duk_time_get_ecmascript_time(thr);\n}\n\n#if 0  /* XXX: worth exposing? */\nDUK_EXTERNAL duk_double_t duk_get_monotonic_time(duk_hthread *thr) {\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_UNREF(thr);\n\n\treturn duk_time_get_monotonic_time(thr);\n}\n#endif\n\nDUK_EXTERNAL void duk_time_to_components(duk_hthread *thr, duk_double_t timeval, duk_time_components *comp) {\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(comp != NULL);  /* XXX: or check? */\n\tDUK_UNREF(thr);\n\n\t/* Convert as one-based, but change month to zero-based to match the\n\t * ECMAScript Date built-in behavior 1:1.\n\t */\n\tflags = DUK_DATE_FLAG_ONEBASED | DUK_DATE_FLAG_NAN_TO_ZERO;\n\n\tduk_bi_date_timeval_to_parts(timeval, parts, dparts, flags);\n\n\t/* XXX: sub-millisecond accuracy for the API */\n\n\tDUK_ASSERT(dparts[DUK_DATE_IDX_MONTH] >= 1.0 && dparts[DUK_DATE_IDX_MONTH] <= 12.0);\n\tcomp->year = dparts[DUK_DATE_IDX_YEAR];\n\tcomp->month = dparts[DUK_DATE_IDX_MONTH] - 1.0;\n\tcomp->day = dparts[DUK_DATE_IDX_DAY];\n\tcomp->hours = dparts[DUK_DATE_IDX_HOUR];\n\tcomp->minutes = dparts[DUK_DATE_IDX_MINUTE];\n\tcomp->seconds = dparts[DUK_DATE_IDX_SECOND];\n\tcomp->milliseconds = dparts[DUK_DATE_IDX_MILLISECOND];\n\tcomp->weekday = dparts[DUK_DATE_IDX_WEEKDAY];\n}\n\nDUK_EXTERNAL duk_double_t duk_components_to_time(duk_hthread *thr, duk_time_components *comp) {\n\tduk_double_t d;\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_uint_t flags;\n\n\tDUK_ASSERT_API_ENTRY(thr);\n\tDUK_ASSERT(comp != NULL);  /* XXX: or check? */\n\tDUK_UNREF(thr);\n\n\t/* Match Date constructor behavior (with UTC time).  Month is given\n\t * as zero-based.  Day-of-month is given as one-based so normalize\n\t * it to zero-based as the internal conversion helpers expects all\n\t * components to be zero-based.\n\t */\n\tflags = 0;\n\n\t/* XXX: expensive conversion; use array format in API instead, or unify\n\t * time provider and time API to use same struct?\n\t */\n\n\tdparts[DUK_DATE_IDX_YEAR] = comp->year;\n\tdparts[DUK_DATE_IDX_MONTH] = comp->month;\n\tdparts[DUK_DATE_IDX_DAY] = comp->day - 1.0;\n\tdparts[DUK_DATE_IDX_HOUR] = comp->hours;\n\tdparts[DUK_DATE_IDX_MINUTE] = comp->minutes;\n\tdparts[DUK_DATE_IDX_SECOND] = comp->seconds;\n\tdparts[DUK_DATE_IDX_MILLISECOND] = comp->milliseconds;\n\tdparts[DUK_DATE_IDX_WEEKDAY] = 0;  /* ignored */\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, flags);\n\n\treturn d;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_array.c",
    "content": "/*\n *  Array built-ins\n *\n *  Most Array built-ins are intentionally generic in ECMAScript, and are\n *  intended to work even when the 'this' binding is not an Array instance.\n *  This ECMAScript feature is also used by much real world code.  For this\n *  reason the implementations here don't assume exotic Array behavior or\n *  e.g. presence of a .length property.  However, some algorithms have a\n *  fast path for duk_harray backed actual Array instances, enabled when\n *  footprint is not a concern.\n *\n *  XXX: the \"Throw\" flag should be set for (almost?) all [[Put]] and\n *  [[Delete]] operations, but it's currently false throughout.  Go through\n *  all put/delete cases and check throw flag use.  Need a new API primitive\n *  which allows throws flag to be specified.\n *\n *  XXX: array lengths above 2G won't work reliably.  There are many places\n *  where one needs a full signed 32-bit range ([-0xffffffff, 0xffffffff],\n *  i.e. -33- bits).  Although array 'length' cannot be written to be outside\n *  the unsigned 32-bit range (E5.1 Section 15.4.5.1 throws a RangeError if so)\n *  some intermediate values may be above 0xffffffff and this may not be always\n *  correctly handled now (duk_uint32_t is not enough for all algorithms).\n *  For instance, push() can legitimately write entries beyond length 0xffffffff\n *  and cause a RangeError only at the end.  To do this properly, the current\n *  push() implementation tracks the array index using a 'double' instead of a\n *  duk_uint32_t (which is somewhat awkward).  See test-bi-array-push-maxlen.js.\n *\n *  On using \"put\" vs. \"def\" prop\n *  =============================\n *\n *  Code below must be careful to use the appropriate primitive as it matters\n *  for compliance.  When using \"put\" there may be inherited properties in\n *  Array.prototype which cause side effects when values are written.  When\n *  using \"define\" there are no such side effects, and many test262 test cases\n *  check for this (for real world code, such side effects are very rare).\n *  Both \"put\" and \"define\" are used in the E5.1 specification; as a rule,\n *  \"put\" is used when modifying an existing array (or a non-array 'this'\n *  binding) and \"define\" for setting values into a fresh result array.\n */\n\n#include \"duk_internal.h\"\n\n/* Perform an intermediate join when this many elements have been pushed\n * on the value stack.\n */\n#define  DUK__ARRAY_MID_JOIN_LIMIT  4096\n\n#if defined(DUK_USE_ARRAY_BUILTIN)\n\n/*\n *  Shared helpers.\n */\n\n/* Shared entry code for many Array built-ins: the 'this' binding is pushed\n * on the value stack and object coerced, and the current .length is returned.\n * Note that length is left on stack (it could be popped, but that's not\n * usually necessary because call handling will clean it up automatically).\n */\nDUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32(duk_hthread *thr) {\n\tduk_uint32_t len;\n\n\t/* XXX: push more directly? */\n\t(void) duk_push_this_coercible_to_object(thr);\n\tDUK_HOBJECT_ASSERT_VALID(duk_get_hobject(thr, -1));\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_LENGTH);\n\tlen = duk_to_uint32(thr, -1);\n\n\t/* -> [ ... ToObject(this) ToUint32(length) ] */\n\treturn len;\n}\n\nDUK_LOCAL duk_uint32_t duk__push_this_obj_len_u32_limited(duk_hthread *thr) {\n\t/* Range limited to [0, 0x7fffffff] range, i.e. range that can be\n\t * represented with duk_int32_t.  Use this when the method doesn't\n\t * handle the full 32-bit unsigned range correctly.\n\t */\n\tduk_uint32_t ret = duk__push_this_obj_len_u32(thr);\n\tif (DUK_UNLIKELY(ret >= 0x80000000UL)) {\n\t\tDUK_ERROR_RANGE_INVALID_LENGTH(thr);\n\t\tDUK_WO_NORETURN(return 0U;);\n\t}\n\treturn ret;\n}\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\n/* Check if 'this' binding is an Array instance (duk_harray) which satisfies\n * a few other guarantees for fast path operation.  The fast path doesn't\n * need to handle all operations, even for duk_harrays, but must handle a\n * significant fraction to improve performance.  Return a non-NULL duk_harray\n * pointer when all fast path criteria are met, NULL otherwise.\n */\nDUK_LOCAL duk_harray *duk__arraypart_fastpath_this(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\tduk_uint_t flags_mask, flags_bits, flags_value;\n\n\tDUK_ASSERT(thr->valstack_bottom > thr->valstack);  /* because call in progress */\n\ttv = DUK_GET_THIS_TVAL_PTR(thr);\n\n\t/* Fast path requires that 'this' is a duk_harray.  Read only arrays\n\t * (ROM backed) are also rejected for simplicity.\n\t */\n\tif (!DUK_TVAL_IS_OBJECT(tv)) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject array fast path: not an object\"));\n\t\treturn NULL;\n\t}\n\th = DUK_TVAL_GET_OBJECT(tv);\n\tDUK_ASSERT(h != NULL);\n\tflags_mask = DUK_HOBJECT_FLAG_ARRAY_PART | \\\n\t             DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \\\n\t             DUK_HEAPHDR_FLAG_READONLY;\n\tflags_bits = DUK_HOBJECT_FLAG_ARRAY_PART | \\\n\t             DUK_HOBJECT_FLAG_EXOTIC_ARRAY;\n\tflags_value = DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) h);\n\tif ((flags_value & flags_mask) != flags_bits) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject array fast path: object flag check failed\"));\n\t\treturn NULL;\n\t}\n\n\t/* In some cases a duk_harray's 'length' may be larger than the\n\t * current array part allocation.  Avoid the fast path in these\n\t * cases, so that all fast path code can safely assume that all\n\t * items in the range [0,length[ are backed by the current array\n\t * part allocation.\n\t */\n\tif (((duk_harray *) h)->length > DUK_HOBJECT_GET_ASIZE(h)) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject array fast path: length > array part size\"));\n\t\treturn NULL;\n\t}\n\n\t/* Guarantees for fast path. */\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0 || DUK_HOBJECT_A_GET_BASE(thr->heap, h) != NULL);\n\tDUK_ASSERT(((duk_harray *) h)->length <= DUK_HOBJECT_GET_ASIZE(h));\n\n\tDUK_DD(DUK_DDPRINT(\"array fast path allowed for: %!O\", (duk_heaphdr *) h));\n\treturn (duk_harray *) h;\n}\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_constructor(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_harray *a;\n\tduk_double_t d;\n\tduk_uint32_t len;\n\tduk_uint32_t len_prealloc;\n\n\tnargs = duk_get_top(thr);\n\n\tif (nargs == 1 && duk_is_number(thr, 0)) {\n\t\t/* XXX: expensive check (also shared elsewhere - so add a shared internal API call?) */\n\t\td = duk_get_number(thr, 0);\n\t\tlen = duk_to_uint32(thr, 0);\n\t\tif (((duk_double_t) len) != d) {\n\t\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t\t}\n\n\t\t/* For small lengths create a dense preallocated array.\n\t\t * For large arrays preallocate an initial part.\n\t\t */\n\t\tlen_prealloc = len < 64 ? len : 64;\n\t\ta = duk_push_harray_with_size(thr, len_prealloc);\n\t\tDUK_ASSERT(a != NULL);\n\t\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\t\ta->length = len;\n\t\treturn 1;\n\t}\n\n\tduk_pack(thr, nargs);\n\treturn 1;\n}\n\n/*\n *  isArray()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_constructor_is_array(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\th = duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_ARRAY);\n\tduk_push_boolean(thr, (h != NULL));\n\treturn 1;\n}\n\n/*\n *  toString()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_to_string(duk_hthread *thr) {\n\t(void) duk_push_this_coercible_to_object(thr);\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_JOIN);\n\n\t/* [ ... this func ] */\n\tif (!duk_is_callable(thr, -1)) {\n\t\t/* Fall back to the initial (original) Object.toString().  We don't\n\t\t * currently have pointers to the built-in functions, only the top\n\t\t * level global objects (like \"Array\") so this is now done in a bit\n\t\t * of a hacky manner.  It would be cleaner to push the (original)\n\t\t * function and use duk_call_method().\n\t\t */\n\n\t\t/* XXX: 'this' will be ToObject() coerced twice, which is incorrect\n\t\t * but should have no visible side effects.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"this.join is not callable, fall back to (original) Object.toString\"));\n\t\tduk_set_top(thr, 0);\n\t\treturn duk_bi_object_prototype_to_string(thr);  /* has access to 'this' binding */\n\t}\n\n\t/* [ ... this func ] */\n\n\tduk_insert(thr, -2);\n\n\t/* [ ... func this ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"calling: func=%!iT, this=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_call_method(thr, 0);\n\n\treturn 1;\n}\n\n/*\n *  concat()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_concat(duk_hthread *thr) {\n\tduk_idx_t i, n;\n\tduk_uint32_t j, idx, len;\n\tduk_hobject *h;\n\tduk_size_t tmp_len;\n\n\t/* XXX: In ES2015 Array .length can be up to 2^53-1.  The current\n\t * implementation is limited to 2^32-1.\n\t */\n\n\t/* XXX: Fast path for array 'this' and array element. */\n\n\t/* XXX: The insert here is a bit expensive if there are a lot of items.\n\t * It could also be special cased in the outermost for loop quite easily\n\t * (as the element is dup()'d anyway).\n\t */\n\n\t(void) duk_push_this_coercible_to_object(thr);\n\tduk_insert(thr, 0);\n\tn = duk_get_top(thr);\n\tduk_push_array(thr);  /* -> [ ToObject(this) item1 ... itemN arr ] */\n\n\t/* NOTE: The Array special behaviors are NOT invoked by duk_xdef_prop_index()\n\t * (which differs from the official algorithm).  If no error is thrown, this\n\t * doesn't matter as the length is updated at the end.  However, if an error\n\t * is thrown, the length will be unset.  That shouldn't matter because the\n\t * caller won't get a reference to the intermediate value.\n\t */\n\n\tidx = 0;\n\tfor (i = 0; i < n; i++) {\n\t\tduk_bool_t spreadable;\n\t\tduk_bool_t need_has_check;\n\n\t\tDUK_ASSERT_TOP(thr, n + 1);\n\n\t\t/* [ ToObject(this) item1 ... itemN arr ] */\n\n\t\th = duk_get_hobject(thr, i);\n\n\t\tif (h == NULL) {\n\t\t\tspreadable = 0;\n\t\t} else {\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t\t\tduk_get_prop_stridx(thr, i, DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE);\n\t\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\t\tspreadable = (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY);\n\t\t\t} else {\n\t\t\t\tspreadable = duk_to_boolean(thr, -1);\n\t\t\t}\n\t\t\tduk_pop_nodecref_unsafe(thr);\n#else\n\t\t\tspreadable = (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY);\n#endif\n\t\t}\n\n\t\tif (!spreadable) {\n\t\t\tduk_dup(thr, i);\n\t\t\tduk_xdef_prop_index_wec(thr, -2, idx);\n\t\t\tidx++;\n\t\t\tif (DUK_UNLIKELY(idx == 0U)) {\n\t\t\t\t/* Index after update is 0, and index written\n\t\t\t\t * was 0xffffffffUL which is no longer a valid\n\t\t\t\t * array index.\n\t\t\t\t */\n\t\t\t\tgoto fail_wrap;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_ASSERT(duk_is_object(thr, i));\n\t\tneed_has_check = (DUK_HOBJECT_IS_PROXY(h) != 0);  /* Always 0 w/o Proxy support. */\n\n\t\t/* [ ToObject(this) item1 ... itemN arr ] */\n\n\t\ttmp_len = duk_get_length(thr, i);\n\t\tlen = (duk_uint32_t) tmp_len;\n\t\tif (DUK_UNLIKELY(tmp_len != (duk_size_t) len)) {\n\t\t\tgoto fail_wrap;\n\t\t}\n\t\tif (DUK_UNLIKELY(idx + len < idx)) {\n\t\t\t/* Result length must be at most 0xffffffffUL to be\n\t\t\t * a valid 32-bit array index.\n\t\t\t */\n\t\t\tgoto fail_wrap;\n\t\t}\n\t\tfor (j = 0; j < len; j++) {\n\t\t\t/* For a Proxy element, an explicit 'has' check is\n\t\t\t * needed to allow the Proxy to present gaps.\n\t\t\t */\n\t\t\tif (need_has_check) {\n\t\t\t\tif (duk_has_prop_index(thr, i, j)) {\n\t\t\t\t\tduk_get_prop_index(thr, i, j);\n\t\t\t\t\tduk_xdef_prop_index_wec(thr, -2, idx);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (duk_get_prop_index(thr, i, j)) {\n\t\t\t\t\tduk_xdef_prop_index_wec(thr, -2, idx);\n\t\t\t\t} else {\n\t\t\t\t\tduk_pop_undefined(thr);\n\t\t\t\t}\n\t\t\t}\n\t\t\tidx++;\n\t\t\tDUK_ASSERT(idx != 0U);  /* Wrap check above. */\n\t\t}\n\t}\n\n\t/* ES5.1 has a specification \"bug\" in that nonexistent trailing\n\t * elements don't affect the result .length.  Test262 and other\n\t * engines disagree, and the specification bug was fixed in ES2015\n\t * (see NOTE 1 in https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.concat).\n\t */\n\tduk_push_uarridx(thr, idx);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\n\tDUK_ASSERT_TOP(thr, n + 1);\n\treturn 1;\n\n fail_wrap:\n\tDUK_ERROR_RANGE_INVALID_LENGTH(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/*\n *  join(), toLocaleString()\n *\n *  Note: checking valstack is necessary, but only in the per-element loop.\n *\n *  Note: the trivial approach of pushing all the elements on the value stack\n *  and then calling duk_join() fails when the array contains a large number\n *  of elements.  This problem can't be offloaded to duk_join() because the\n *  elements to join must be handled here and have special handling.  Current\n *  approach is to do intermediate joins with very large number of elements.\n *  There is no fancy handling; the prefix gets re-joined multiple times.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_join_shared(duk_hthread *thr) {\n\tduk_uint32_t len, count;\n\tduk_uint32_t idx;\n\tduk_small_int_t to_locale_string = duk_get_current_magic(thr);\n\tduk_idx_t valstack_required;\n\n\t/* For join(), nargs is 1.  For toLocaleString(), nargs is 0 and\n\t * setting the top essentially pushes an undefined to the stack,\n\t * thus defaulting to a comma separator.\n\t */\n\tduk_set_top(thr, 1);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tduk_pop_undefined(thr);\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_COMMA);\n\t} else {\n\t\tduk_to_string(thr, 0);\n\t}\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\n\t/* [ sep ToObject(this) len ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"sep=%!T, this=%!T, len=%lu\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1),\n\t                     (unsigned long) len));\n\n\t/* The extra (+4) is tight. */\n\tvalstack_required = (duk_idx_t) ((len >= DUK__ARRAY_MID_JOIN_LIMIT ?\n\t                                  DUK__ARRAY_MID_JOIN_LIMIT : len) + 4);\n\tduk_require_stack(thr, valstack_required);\n\n\tduk_dup_0(thr);\n\n\t/* [ sep ToObject(this) len sep ] */\n\n\tcount = 0;\n\tidx = 0;\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"join idx=%ld\", (long) idx));\n\t\tif (count >= DUK__ARRAY_MID_JOIN_LIMIT ||   /* intermediate join to avoid valstack overflow */\n\t\t    idx >= len) { /* end of loop (careful with len==0) */\n\t\t\t/* [ sep ToObject(this) len sep str0 ... str(count-1) ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"mid/final join, count=%ld, idx=%ld, len=%ld\",\n\t\t\t                     (long) count, (long) idx, (long) len));\n\t\t\tduk_join(thr, (duk_idx_t) count);  /* -> [ sep ToObject(this) len str ] */\n\t\t\tduk_dup_0(thr);                    /* -> [ sep ToObject(this) len str sep ] */\n\t\t\tduk_insert(thr, -2);               /* -> [ sep ToObject(this) len sep str ] */\n\t\t\tcount = 1;\n\t\t}\n\t\tif (idx >= len) {\n\t\t\t/* if true, the stack already contains the final result */\n\t\t\tbreak;\n\t\t}\n\n\t\tduk_get_prop_index(thr, 1, (duk_uarridx_t) idx);\n\t\tif (duk_is_null_or_undefined(thr, -1)) {\n\t\t\tduk_pop_nodecref_unsafe(thr);\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tif (to_locale_string) {\n\t\t\t\tduk_to_object(thr, -1);\n\t\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_LOCALE_STRING);\n\t\t\t\tduk_insert(thr, -2);  /* -> [ ... toLocaleString ToObject(val) ] */\n\t\t\t\tduk_call_method(thr, 0);\n\t\t\t}\n\t\t\tduk_to_string(thr, -1);\n\t\t}\n\n\t\tcount++;\n\t\tidx++;\n\t}\n\n\t/* [ sep ToObject(this) len sep result ] */\n\n\treturn 1;\n}\n\n/*\n *  pop(), push()\n */\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\nDUK_LOCAL duk_ret_t duk__array_pop_fastpath(duk_hthread *thr, duk_harray *h_arr) {\n\tduk_tval *tv_arraypart;\n\tduk_tval *tv_val;\n\tduk_uint32_t len;\n\n\ttv_arraypart = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) h_arr);\n\tlen = h_arr->length;\n\tif (len <= 0) {\n\t\t/* nop, return undefined */\n\t\treturn 0;\n\t}\n\n\tlen--;\n\th_arr->length = len;\n\n\t/* Fast path doesn't check for an index property inherited from\n\t * Array.prototype.  This is quite often acceptable; if not,\n\t * disable fast path.\n\t */\n\tDUK_ASSERT_VS_SPACE(thr);\n\ttv_val = tv_arraypart + len;\n\tif (DUK_TVAL_IS_UNUSED(tv_val)) {\n\t\t/* No net refcount change.  Value stack already has\n\t\t * 'undefined' based on value stack init policy.\n\t\t */\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv_val));\n\t} else {\n\t\t/* No net refcount change. */\n\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv_val);\n\t\tDUK_TVAL_SET_UNUSED(tv_val);\n\t}\n\tthr->valstack_top++;\n\n\t/* XXX: there's no shrink check in the fast path now */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_pop(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t idx;\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\tduk_harray *h_arr;\n#endif\n\n\tDUK_ASSERT_TOP(thr, 0);\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\th_arr = duk__arraypart_fastpath_this(thr);\n\tif (h_arr) {\n\t\treturn duk__array_pop_fastpath(thr, h_arr);\n\t}\n#endif\n\n\t/* XXX: Merge fastpath check into a related call (push this, coerce length, etc)? */\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tif (len == 0) {\n\t\tduk_push_int(thr, 0);\n\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\t\treturn 0;\n\t}\n\tidx = len - 1;\n\n\tduk_get_prop_index(thr, 0, (duk_uarridx_t) idx);\n\tduk_del_prop_index(thr, 0, (duk_uarridx_t) idx);\n\tduk_push_u32(thr, idx);\n\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\treturn 1;\n}\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\nDUK_LOCAL duk_ret_t duk__array_push_fastpath(duk_hthread *thr, duk_harray *h_arr) {\n\tduk_tval *tv_arraypart;\n\tduk_tval *tv_src;\n\tduk_tval *tv_dst;\n\tduk_uint32_t len;\n\tduk_idx_t i, n;\n\n\tlen = h_arr->length;\n\ttv_arraypart = DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) h_arr);\n\n\tn = (duk_idx_t) (thr->valstack_top - thr->valstack_bottom);\n\tDUK_ASSERT(n >= 0);\n\tDUK_ASSERT((duk_uint32_t) n <= DUK_UINT32_MAX);\n\tif (DUK_UNLIKELY(len + (duk_uint32_t) n < len)) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.push() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);  /* != 0 return value returned as is by caller */\n\t}\n\tif (len + (duk_uint32_t) n > DUK_HOBJECT_GET_ASIZE((duk_hobject *) h_arr)) {\n\t\t/* Array part would need to be extended.  Rely on slow path\n\t\t * for now.\n\t\t *\n\t\t * XXX: Rework hobject code a bit and add extend support.\n\t\t */\n\t\treturn 0;\n\t}\n\n\ttv_src = thr->valstack_bottom;\n\ttv_dst = tv_arraypart + len;\n\tfor (i = 0; i < n; i++) {\n\t\t/* No net refcount change; reset value stack values to\n\t\t * undefined to satisfy value stack init policy.\n\t\t */\n\t\tDUK_TVAL_SET_TVAL(tv_dst, tv_src);\n\t\tDUK_TVAL_SET_UNDEFINED(tv_src);\n\t\ttv_src++;\n\t\ttv_dst++;\n\t}\n\tthr->valstack_top = thr->valstack_bottom;\n\tlen += (duk_uint32_t) n;\n\th_arr->length = len;\n\n\tDUK_ASSERT((duk_uint_t) len == len);\n\tduk_push_uint(thr, (duk_uint_t) len);\n\treturn 1;\n}\n#endif  /* DUK_USE_ARRAY_FASTPATH */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_push(duk_hthread *thr) {\n\t/* Note: 'this' is not necessarily an Array object.  The push()\n\t * algorithm is supposed to work for other kinds of objects too,\n\t * so the algorithm has e.g. an explicit update for the 'length'\n\t * property which is normally \"magical\" in arrays.\n\t */\n\n\tduk_uint32_t len;\n\tduk_idx_t i, n;\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\tduk_harray *h_arr;\n#endif\n\n#if defined(DUK_USE_ARRAY_FASTPATH)\n\th_arr = duk__arraypart_fastpath_this(thr);\n\tif (h_arr) {\n\t\tduk_ret_t rc;\n\t\trc = duk__array_push_fastpath(thr, h_arr);\n\t\tif (rc != 0) {\n\t\t\treturn rc;\n\t\t}\n\t\tDUK_DD(DUK_DDPRINT(\"array push() fast path exited, resize case\"));\n\t}\n#endif\n\n\tn = duk_get_top(thr);\n\tlen = duk__push_this_obj_len_u32(thr);\n\n\t/* [ arg1 ... argN obj length ] */\n\n\t/* Technically Array.prototype.push() can create an Array with length\n\t * longer than 2^32-1, i.e. outside the 32-bit range.  The final length\n\t * is *not* wrapped to 32 bits in the specification.\n\t *\n\t * This implementation tracks length with a uint32 because it's much\n\t * more practical.\n\t *\n\t * See: test-bi-array-push-maxlen.js.\n\t */\n\n\tif (len + (duk_uint32_t) n < len) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.push() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t}\n\n\tfor (i = 0; i < n; i++) {\n\t\tduk_dup(thr, i);\n\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) (len + (duk_uint32_t) i));\n\t}\n\tlen += (duk_uint32_t) n;\n\n\tduk_push_u32(thr, len);\n\tduk_dup_top(thr);\n\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH);\n\n\t/* [ arg1 ... argN obj length new_length ] */\n\treturn 1;\n}\n\n/*\n *  sort()\n *\n *  Currently qsort with random pivot.  This is now really, really slow,\n *  because there is no fast path for array parts.\n *\n *  Signed indices are used because qsort() leaves and degenerate cases\n *  may use a negative offset.\n */\n\nDUK_LOCAL duk_small_int_t duk__array_sort_compare(duk_hthread *thr, duk_int_t idx1, duk_int_t idx2) {\n\tduk_bool_t have1, have2;\n\tduk_bool_t undef1, undef2;\n\tduk_small_int_t ret;\n\tduk_idx_t idx_obj = 1;  /* fixed offsets in valstack */\n\tduk_idx_t idx_fn = 0;\n\tduk_hstring *h1, *h2;\n\n\t/* Fast exit if indices are identical.  This is valid for a non-existent property,\n\t * for an undefined value, and almost always for ToString() coerced comparison of\n\t * arbitrary values (corner cases where this is not the case include e.g. a an\n\t * object with varying ToString() coercion).\n\t *\n\t * The specification does not prohibit \"caching\" of values read from the array, so\n\t * assuming equality for comparing an index with itself falls into the category of\n\t * \"caching\".\n\t *\n\t * Also, compareFn may be inconsistent, so skipping a call to compareFn here may\n\t * have an effect on the final result.  The specification does not require any\n\t * specific behavior for inconsistent compare functions, so again, this fast path\n\t * is OK.\n\t */\n\n\tif (idx1 == idx2) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__array_sort_compare: idx1=%ld, idx2=%ld -> indices identical, quick exit\",\n\t\t                     (long) idx1, (long) idx2));\n\t\treturn 0;\n\t}\n\n\thave1 = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) idx1);\n\thave2 = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) idx2);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__array_sort_compare: idx1=%ld, idx2=%ld, have1=%ld, have2=%ld, val1=%!T, val2=%!T\",\n\t                     (long) idx1, (long) idx2, (long) have1, (long) have2,\n\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (have1) {\n\t\tif (have2) {\n\t\t\t;\n\t\t} else {\n\t\t\tret = -1;\n\t\t\tgoto pop_ret;\n\t\t}\n\t} else {\n\t\tif (have2) {\n\t\t\tret = 1;\n\t\t\tgoto pop_ret;\n\t\t} else {\n\t\t\tret = 0;\n\t\t\tgoto pop_ret;\n\t\t}\n\t}\n\n\tundef1 = duk_is_undefined(thr, -2);\n\tundef2 = duk_is_undefined(thr, -1);\n\tif (undef1) {\n\t\tif (undef2) {\n\t\t\tret = 0;\n\t\t\tgoto pop_ret;\n\t\t} else {\n\t\t\tret = 1;\n\t\t\tgoto pop_ret;\n\t\t}\n\t} else {\n\t\tif (undef2) {\n\t\t\tret = -1;\n\t\t\tgoto pop_ret;\n\t\t} else {\n\t\t\t;\n\t\t}\n\t}\n\n\tif (!duk_is_undefined(thr, idx_fn)) {\n\t\tduk_double_t d;\n\n\t\t/* No need to check callable; duk_call() will do that. */\n\t\tduk_dup(thr, idx_fn);    /* -> [ ... x y fn ] */\n\t\tduk_insert(thr, -3);     /* -> [ ... fn x y ] */\n\t\tduk_call(thr, 2);        /* -> [ ... res ] */\n\n\t\t/* ES5 is a bit vague about what to do if the return value is\n\t\t * not a number.  ES2015 provides a concrete description:\n\t\t * http://www.ecma-international.org/ecma-262/6.0/#sec-sortcompare.\n\t\t */\n\n\t\td = duk_to_number_m1(thr);\n\t\tif (d < 0.0) {\n\t\t\tret = -1;\n\t\t} else if (d > 0.0) {\n\t\t\tret = 1;\n\t\t} else {\n\t\t\t/* Because NaN compares to false, NaN is handled here\n\t\t\t * without an explicit check above.\n\t\t\t */\n\t\t\tret = 0;\n\t\t}\n\n\t\tduk_pop_nodecref_unsafe(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> result %ld (from comparefn, after coercion)\", (long) ret));\n\t\treturn ret;\n\t}\n\n\t/* string compare is the default (a bit oddly) */\n\n\t/* XXX: any special handling for plain array; causes repeated coercion now? */\n\th1 = duk_to_hstring(thr, -2);\n\th2 = duk_to_hstring_m1(thr);\n\tDUK_ASSERT(h1 != NULL);\n\tDUK_ASSERT(h2 != NULL);\n\n\tret = duk_js_string_compare(h1, h2);  /* retval is directly usable */\n\tgoto pop_ret;\n\n pop_ret:\n\tduk_pop_2_unsafe(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"-> result %ld\", (long) ret));\n\treturn ret;\n}\n\nDUK_LOCAL void duk__array_sort_swap(duk_hthread *thr, duk_int_t l, duk_int_t r) {\n\tduk_bool_t have_l, have_r;\n\tduk_idx_t idx_obj = 1;  /* fixed offset in valstack */\n\n\tif (l == r) {\n\t\treturn;\n\t}\n\n\t/* swap elements; deal with non-existent elements correctly */\n\thave_l = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) l);\n\thave_r = duk_get_prop_index(thr, idx_obj, (duk_uarridx_t) r);\n\n\tif (have_r) {\n\t\t/* right exists, [[Put]] regardless whether or not left exists */\n\t\tduk_put_prop_index(thr, idx_obj, (duk_uarridx_t) l);\n\t} else {\n\t\tduk_del_prop_index(thr, idx_obj, (duk_uarridx_t) l);\n\t\tduk_pop_undefined(thr);\n\t}\n\n\tif (have_l) {\n\t\tduk_put_prop_index(thr, idx_obj, (duk_uarridx_t) r);\n\t} else {\n\t\tduk_del_prop_index(thr, idx_obj, (duk_uarridx_t) r);\n\t\tduk_pop_undefined(thr);\n\t}\n}\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n/* Debug print which visualizes the qsort partitioning process. */\nDUK_LOCAL void duk__debuglog_qsort_state(duk_hthread *thr, duk_int_t lo, duk_int_t hi, duk_int_t pivot) {\n\tchar buf[4096];\n\tchar *ptr = buf;\n\tduk_int_t i, n;\n\tn = (duk_int_t) duk_get_length(thr, 1);\n\tif (n > 4000) {\n\t\tn = 4000;\n\t}\n\t*ptr++ = '[';\n\tfor (i = 0; i < n; i++) {\n\t\tif (i == pivot) {\n\t\t\t*ptr++ = '|';\n\t\t} else if (i == lo) {\n\t\t\t*ptr++ = '<';\n\t\t} else if (i == hi) {\n\t\t\t*ptr++ = '>';\n\t\t} else if (i >= lo && i <= hi) {\n\t\t\t*ptr++ = '-';\n\t\t} else {\n\t\t\t*ptr++ = ' ';\n\t\t}\n\t}\n\t*ptr++ = ']';\n\t*ptr++ = '\\0';\n\n\tDUK_DDD(DUK_DDDPRINT(\"%s   (lo=%ld, hi=%ld, pivot=%ld)\",\n\t                     (const char *) buf, (long) lo, (long) hi, (long) pivot));\n}\n#endif\n\nDUK_LOCAL void duk__array_qsort(duk_hthread *thr, duk_int_t lo, duk_int_t hi) {\n\tduk_int_t p, l, r;\n\n\t/* The lo/hi indices may be crossed and hi < 0 is possible at entry. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__array_qsort: lo=%ld, hi=%ld, obj=%!T\",\n\t                     (long) lo, (long) hi, (duk_tval *) duk_get_tval(thr, 1)));\n\n\tDUK_ASSERT_TOP(thr, 3);\n\n\t/* In some cases it may be that lo > hi, or hi < 0; these\n\t * degenerate cases happen e.g. for empty arrays, and in\n\t * recursion leaves.\n\t */\n\n\t/* trivial cases */\n\tif (hi - lo < 1) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"degenerate case, return immediately\"));\n\t\treturn;\n\t}\n\tDUK_ASSERT(hi > lo);\n\tDUK_ASSERT(hi - lo + 1 >= 2);\n\n\t/* randomized pivot selection */\n\tp = lo + (duk_int_t) (DUK_UTIL_GET_RANDOM_DOUBLE(thr) * (duk_double_t) (hi - lo + 1));\n\tDUK_ASSERT(p >= lo && p <= hi);\n\tDUK_DDD(DUK_DDDPRINT(\"lo=%ld, hi=%ld, chose pivot p=%ld\", (long) lo, (long) hi, (long) p));\n\n\t/* move pivot out of the way */\n\tduk__array_sort_swap(thr, p, lo);\n\tp = lo;\n\tDUK_DDD(DUK_DDDPRINT(\"pivot moved out of the way: %!T\", (duk_tval *) duk_get_tval(thr, 1)));\n\n\tl = lo + 1;\n\tr = hi;\n\tfor (;;) {\n\t\t/* find elements to swap */\n\t\tfor (;;) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"left scan: l=%ld, r=%ld, p=%ld\",\n\t\t\t                     (long) l, (long) r, (long) p));\n\t\t\tif (l >= hi) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (duk__array_sort_compare(thr, l, p) >= 0) {  /* !(l < p) */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tl++;\n\t\t}\n\t\tfor (;;) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"right scan: l=%ld, r=%ld, p=%ld\",\n\t\t\t                     (long) l, (long) r, (long) p));\n\t\t\tif (r <= lo) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (duk__array_sort_compare(thr, p, r) >= 0) {  /* !(p < r) */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tr--;\n\t\t}\n\t\tif (l >= r) {\n\t\t\tgoto done;\n\t\t}\n\t\tDUK_ASSERT(l < r);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"swap %ld and %ld\", (long) l, (long) r));\n\n\t\tduk__array_sort_swap(thr, l, r);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"after swap: %!T\", (duk_tval *) duk_get_tval(thr, 1)));\n\t\tl++;\n\t\tr--;\n\t}\n done:\n\t/* Note that 'l' and 'r' may cross, i.e. r < l */\n\tDUK_ASSERT(l >= lo && l <= hi);\n\tDUK_ASSERT(r >= lo && r <= hi);\n\n\t/* XXX: there's no explicit recursion bound here now.  For the average\n\t * qsort recursion depth O(log n) that's not really necessary: e.g. for\n\t * 2**32 recursion depth would be about 32 which is OK.  However, qsort\n\t * worst case recursion depth is O(n) which may be a problem.\n\t */\n\n\t/* move pivot to its final place */\n\tDUK_DDD(DUK_DDDPRINT(\"before final pivot swap: %!T\", (duk_tval *) duk_get_tval(thr, 1)));\n\tduk__array_sort_swap(thr, lo, r);\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\tduk__debuglog_qsort_state(thr, lo, hi, r);\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"recurse: pivot=%ld, obj=%!T\", (long) r, (duk_tval *) duk_get_tval(thr, 1)));\n\tduk__array_qsort(thr, lo, r - 1);\n\tduk__array_qsort(thr, r + 1, hi);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_sort(duk_hthread *thr) {\n\tduk_uint32_t len;\n\n\t/* XXX: len >= 0x80000000 won't work below because a signed type\n\t * is needed by qsort.\n\t */\n\tlen = duk__push_this_obj_len_u32_limited(thr);\n\n\t/* stack[0] = compareFn\n\t * stack[1] = ToObject(this)\n\t * stack[2] = ToUint32(length)\n\t */\n\n\tif (len > 0) {\n\t\t/* avoid degenerate cases, so that (len - 1) won't underflow */\n\t\tduk__array_qsort(thr, (duk_int_t) 0, (duk_int_t) (len - 1));\n\t}\n\n\tDUK_ASSERT_TOP(thr, 3);\n\tduk_pop_nodecref_unsafe(thr);\n\treturn 1;  /* return ToObject(this) */\n}\n\n/*\n *  splice()\n */\n\n/* XXX: this compiles to over 500 bytes now, even without special handling\n * for an array part.  Uses signed ints so does not handle full array range correctly.\n */\n\n/* XXX: can shift() / unshift() use the same helper?\n *   shift() is (close to?) <--> splice(0, 1)\n *   unshift is (close to?) <--> splice(0, 0, [items])?\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_splice(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_uint32_t len_u32;\n\tduk_int_t len;\n\tduk_bool_t have_delcount;\n\tduk_int_t item_count;\n\tduk_int_t act_start;\n\tduk_int_t del_count;\n\tduk_int_t i, n;\n\n\tDUK_UNREF(have_delcount);\n\n\tnargs = duk_get_top(thr);\n\tif (nargs < 2) {\n\t\tduk_set_top(thr, 2);\n\t\tnargs = 2;\n\t\thave_delcount = 0;\n\t} else {\n\t\thave_delcount = 1;\n\t}\n\n\t/* XXX: len >= 0x80000000 won't work below because we need to be\n\t * able to represent -len.\n\t */\n\tlen_u32 = duk__push_this_obj_len_u32_limited(thr);\n\tlen = (duk_int_t) len_u32;\n\tDUK_ASSERT(len >= 0);\n\n\tact_start = duk_to_int_clamped(thr, 0, -len, len);\n\tif (act_start < 0) {\n\t\tact_start = len + act_start;\n\t}\n\tDUK_ASSERT(act_start >= 0 && act_start <= len);\n\n#if defined(DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT)\n\tif (have_delcount) {\n#endif\n\t\tdel_count = duk_to_int_clamped(thr, 1, 0, len - act_start);\n#if defined(DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT)\n\t} else {\n\t\t/* E5.1 standard behavior when deleteCount is not given would be\n\t\t * to treat it just like if 'undefined' was given, which coerces\n\t\t * ultimately to 0.  Real world behavior is to splice to the end\n\t\t * of array, see test-bi-array-proto-splice-no-delcount.js.\n\t\t */\n\t\tdel_count = len - act_start;\n\t}\n#endif\n\n\tDUK_ASSERT(nargs >= 2);\n\titem_count = (duk_int_t) (nargs - 2);\n\n\tDUK_ASSERT(del_count >= 0 && del_count <= len - act_start);\n\tDUK_ASSERT(del_count + act_start <= len);\n\n\t/* For now, restrict result array into 32-bit length range. */\n\tif (((duk_double_t) len) - ((duk_double_t) del_count) + ((duk_double_t) item_count) > (duk_double_t) DUK_UINT32_MAX) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.splice() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t}\n\n\tduk_push_array(thr);\n\n\t/* stack[0] = start\n\t * stack[1] = deleteCount\n\t * stack[2...nargs-1] = items\n\t * stack[nargs] = ToObject(this)               -3\n\t * stack[nargs+1] = ToUint32(length)           -2\n\t * stack[nargs+2] = result array               -1\n\t */\n\n\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t/* Step 9: copy elements-to-be-deleted into the result array */\n\n\tfor (i = 0; i < del_count; i++) {\n\t\tif (duk_get_prop_index(thr, -3, (duk_uarridx_t) (act_start + i))) {\n\t\t\tduk_xdef_prop_index_wec(thr, -2, (duk_uarridx_t) i);  /* throw flag irrelevant (false in std alg) */\n\t\t} else {\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\t}\n\tduk_push_u32(thr, (duk_uint32_t) del_count);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\n\t/* Steps 12 and 13: reorganize elements to make room for itemCount elements */\n\n\tif (item_count < del_count) {\n\t\t/*    [ A B C D E F G H ]    rel_index = 2, del_count 3, item count 1\n\t\t * -> [ A B F G H ]          (conceptual intermediate step)\n\t\t * -> [ A B . F G H ]        (placeholder marked)\n\t\t *    [ A B C F G H ]        (actual result at this point, C will be replaced)\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t\tn = len - del_count;\n\t\tfor (i = act_start; i < n; i++) {\n\t\t\tif (duk_get_prop_index(thr, -3, (duk_uarridx_t) (i + del_count))) {\n\t\t\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) (i + item_count));\n\t\t\t} else {\n\t\t\t\tduk_pop_undefined(thr);\n\t\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) (i + item_count));\n\t\t\t}\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t\t/* loop iterator init and limit changed from standard algorithm */\n\t\tn = len - del_count + item_count;\n\t\tfor (i = len - 1; i >= n; i--) {\n\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) i);\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\t} else if (item_count > del_count) {\n\t\t/*    [ A B C D E F G H ]    rel_index = 2, del_count 3, item count 4\n\t\t * -> [ A B F G H ]          (conceptual intermediate step)\n\t\t * -> [ A B . . . . F G H ]  (placeholder marked)\n\t\t *    [ A B C D E F F G H ]  (actual result at this point)\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t\t/* loop iterator init and limit changed from standard algorithm */\n\t\tfor (i = len - del_count - 1; i >= act_start; i--) {\n\t\t\tif (duk_get_prop_index(thr, -3, (duk_uarridx_t) (i + del_count))) {\n\t\t\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) (i + item_count));\n\t\t\t} else {\n\t\t\t\tduk_pop_undefined(thr);\n\t\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) (i + item_count));\n\t\t\t}\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, nargs + 3);\n\t} else {\n\t\t/*    [ A B C D E F G H ]    rel_index = 2, del_count 3, item count 3\n\t\t * -> [ A B F G H ]          (conceptual intermediate step)\n\t\t * -> [ A B . . . F G H ]    (placeholder marked)\n\t\t *    [ A B C D E F G H ]    (actual result at this point)\n\t\t */\n\t}\n\tDUK_ASSERT_TOP(thr, nargs + 3);\n\n\t/* Step 15: insert itemCount elements into the hole made above */\n\n\tfor (i = 0; i < item_count; i++) {\n\t\tduk_dup(thr, i + 2);  /* args start at index 2 */\n\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) (act_start + i));\n\t}\n\n\t/* Step 16: update length; note that the final length may be above 32 bit range\n\t * (but we checked above that this isn't the case here)\n\t */\n\n\tduk_push_u32(thr, (duk_uint32_t) (len - del_count + item_count));\n\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH);\n\n\t/* result array is already at the top of stack */\n\tDUK_ASSERT_TOP(thr, nargs + 3);\n\treturn 1;\n}\n\n/*\n *  reverse()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_reverse(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t middle;\n\tduk_uint32_t lower, upper;\n\tduk_bool_t have_lower, have_upper;\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tmiddle = len / 2;\n\n\t/* If len <= 1, middle will be 0 and for-loop bails out\n\t * immediately (0 < 0 -> false).\n\t */\n\n\tfor (lower = 0; lower < middle; lower++) {\n\t\tDUK_ASSERT(len >= 2);\n\t\tDUK_ASSERT_TOP(thr, 2);\n\n\t\tDUK_ASSERT(len >= lower + 1);\n\t\tupper = len - lower - 1;\n\n\t\thave_lower = duk_get_prop_index(thr, -2, (duk_uarridx_t) lower);\n\t\thave_upper = duk_get_prop_index(thr, -3, (duk_uarridx_t) upper);\n\n\t\t/* [ ToObject(this) ToUint32(length) lowerValue upperValue ] */\n\n\t\tif (have_upper) {\n\t\t\tduk_put_prop_index(thr, -4, (duk_uarridx_t) lower);\n\t\t} else {\n\t\t\tduk_del_prop_index(thr, -4, (duk_uarridx_t) lower);\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\n\t\tif (have_lower) {\n\t\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) upper);\n\t\t} else {\n\t\t\tduk_del_prop_index(thr, -3, (duk_uarridx_t) upper);\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t}\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_pop_unsafe(thr);  /* -> [ ToObject(this) ] */\n\treturn 1;\n}\n\n/*\n *  slice()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_slice(duk_hthread *thr) {\n\tduk_uint32_t len_u32;\n\tduk_int_t len;\n\tduk_int_t start, end;\n\tduk_int_t i;\n\tduk_uarridx_t idx;\n\tduk_uint32_t res_length = 0;\n\n\t/* XXX: len >= 0x80000000 won't work below because we need to be\n\t * able to represent -len.\n\t */\n\tlen_u32 = duk__push_this_obj_len_u32_limited(thr);\n\tlen = (duk_int_t) len_u32;\n\tDUK_ASSERT(len >= 0);\n\n\tduk_push_array(thr);\n\n\t/* stack[0] = start\n\t * stack[1] = end\n\t * stack[2] = ToObject(this)\n\t * stack[3] = ToUint32(length)\n\t * stack[4] = result array\n\t */\n\n\tstart = duk_to_int_clamped(thr, 0, -len, len);\n\tif (start < 0) {\n\t\tstart = len + start;\n\t}\n\t/* XXX: could duk_is_undefined() provide defaulting undefined to 'len'\n\t * (the upper limit)?\n\t */\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend = len;\n\t} else {\n\t\tend = duk_to_int_clamped(thr, 1, -len, len);\n\t\tif (end < 0) {\n\t\t\tend = len + end;\n\t\t}\n\t}\n\tDUK_ASSERT(start >= 0 && start <= len);\n\tDUK_ASSERT(end >= 0 && end <= len);\n\n\tidx = 0;\n\tfor (i = start; i < end; i++) {\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t\tif (duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\tduk_xdef_prop_index_wec(thr, 4, idx);\n\t\t\tres_length = idx + 1;\n\t\t} else {\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\t\tidx++;\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t}\n\n\tduk_push_u32(thr, res_length);\n\tduk_xdef_prop_stridx_short(thr, 4, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\n\tDUK_ASSERT_TOP(thr, 5);\n\treturn 1;\n}\n\n/*\n *  shift()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_shift(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t i;\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tif (len == 0) {\n\t\tduk_push_int(thr, 0);\n\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\t\treturn 0;\n\t}\n\n\tduk_get_prop_index(thr, 0, 0);\n\n\t/* stack[0] = object (this)\n\t * stack[1] = ToUint32(length)\n\t * stack[2] = elem at index 0 (retval)\n\t */\n\n\tfor (i = 1; i < len; i++) {\n\t\tDUK_ASSERT_TOP(thr, 3);\n\t\tif (duk_get_prop_index(thr, 0, (duk_uarridx_t) i)) {\n\t\t\t/* fromPresent = true */\n\t\t\tduk_put_prop_index(thr, 0, (duk_uarridx_t) (i - 1));\n\t\t} else {\n\t\t\t/* fromPresent = false */\n\t\t\tduk_del_prop_index(thr, 0, (duk_uarridx_t) (i - 1));\n\t\t\tduk_pop_undefined(thr);\n\t\t}\n\t}\n\tduk_del_prop_index(thr, 0, (duk_uarridx_t) (len - 1));\n\n\tduk_push_u32(thr, (duk_uint32_t) (len - 1));\n\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\n\tDUK_ASSERT_TOP(thr, 3);\n\treturn 1;\n}\n\n/*\n *  unshift()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_unshift(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_uint32_t len;\n\tduk_uint32_t i;\n\n\tnargs = duk_get_top(thr);\n\tlen = duk__push_this_obj_len_u32(thr);\n\n\t/* stack[0...nargs-1] = unshift args (vararg)\n\t * stack[nargs] = ToObject(this)\n\t * stack[nargs+1] = ToUint32(length)\n\t */\n\n\tDUK_ASSERT_TOP(thr, nargs + 2);\n\n\t/* Note: unshift() may operate on indices above unsigned 32-bit range\n\t * and the final length may be >= 2**32.  However, we restrict the\n\t * final result to 32-bit range for practicality.\n\t */\n\n\tif (len + (duk_uint32_t) nargs < len) {\n\t\tDUK_D(DUK_DPRINT(\"Array.prototype.unshift() would go beyond 32-bit length, throw\"));\n\t\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n\t}\n\n\ti = len;\n\twhile (i > 0) {\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t\ti--;\n\t\t/* k+argCount-1; note that may be above 32-bit range */\n\n\t\tif (duk_get_prop_index(thr, -2, (duk_uarridx_t) i)) {\n\t\t\t/* fromPresent = true */\n\t\t\t/* [ ... ToObject(this) ToUint32(length) val ] */\n\t\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) (i + (duk_uint32_t) nargs));  /* -> [ ... ToObject(this) ToUint32(length) ] */\n\t\t} else {\n\t\t\t/* fromPresent = false */\n\t\t\t/* [ ... ToObject(this) ToUint32(length) val ] */\n\t\t\tduk_pop_undefined(thr);\n\t\t\tduk_del_prop_index(thr, -2, (duk_uarridx_t) (i + (duk_uint32_t) nargs));  /* -> [ ... ToObject(this) ToUint32(length) ] */\n\t\t}\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t}\n\n\tfor (i = 0; i < (duk_uint32_t) nargs; i++) {\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t\tduk_dup(thr, (duk_idx_t) i);  /* -> [ ... ToObject(this) ToUint32(length) arg[i] ] */\n\t\tduk_put_prop_index(thr, -3, (duk_uarridx_t) i);\n\t\tDUK_ASSERT_TOP(thr, nargs + 2);\n\t}\n\n\tDUK_ASSERT_TOP(thr, nargs + 2);\n\tduk_push_u32(thr, len + (duk_uint32_t) nargs);\n\tduk_dup_top(thr);  /* -> [ ... ToObject(this) ToUint32(length) final_len final_len ] */\n\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_LENGTH);\n\treturn 1;\n}\n\n/*\n *  indexOf(), lastIndexOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_indexof_shared(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_int_t i, len;\n\tduk_int_t from_idx;\n\tduk_small_int_t idx_step = duk_get_current_magic(thr);  /* idx_step is +1 for indexOf, -1 for lastIndexOf */\n\n\t/* lastIndexOf() needs to be a vararg function because we must distinguish\n\t * between an undefined fromIndex and a \"not given\" fromIndex; indexOf() is\n\t * made vararg for symmetry although it doesn't strictly need to be.\n\t */\n\n\tnargs = duk_get_top(thr);\n\tduk_set_top(thr, 2);\n\n\t/* XXX: must be able to represent -len */\n\tlen = (duk_int_t) duk__push_this_obj_len_u32_limited(thr);\n\tif (len == 0) {\n\t\tgoto not_found;\n\t}\n\n\t/* Index clamping is a bit tricky, we must ensure that we'll only iterate\n\t * through elements that exist and that the specific requirements from E5.1\n\t * Sections 15.4.4.14 and 15.4.4.15 are fulfilled; especially:\n\t *\n\t *   - indexOf: clamp to [-len,len], negative handling -> [0,len],\n\t *     if clamped result is len, for-loop bails out immediately\n\t *\n\t *   - lastIndexOf: clamp to [-len-1, len-1], negative handling -> [-1, len-1],\n\t *     if clamped result is -1, for-loop bails out immediately\n\t *\n\t * If fromIndex is not given, ToInteger(undefined) = 0, which is correct\n\t * for indexOf() but incorrect for lastIndexOf().  Hence special handling,\n\t * and why lastIndexOf() needs to be a vararg function.\n\t */\n\n\tif (nargs >= 2) {\n\t\t/* indexOf: clamp fromIndex to [-len, len]\n\t\t * (if fromIndex == len, for-loop terminates directly)\n\t\t *\n\t\t * lastIndexOf: clamp fromIndex to [-len - 1, len - 1]\n\t\t * (if clamped to -len-1 -> fromIndex becomes -1, terminates for-loop directly)\n\t\t */\n\t\tfrom_idx = duk_to_int_clamped(thr,\n\t\t                              1,\n\t\t                              (idx_step > 0 ? -len : -len - 1),\n\t\t                              (idx_step > 0 ? len : len - 1));\n\t\tif (from_idx < 0) {\n\t\t\t/* for lastIndexOf, result may be -1 (mark immediate termination) */\n\t\t\tfrom_idx = len + from_idx;\n\t\t}\n\t} else {\n\t\t/* for indexOf, ToInteger(undefined) would be 0, i.e. correct, but\n\t\t * handle both indexOf and lastIndexOf specially here.\n\t\t */\n\t\tif (idx_step > 0) {\n\t\t\tfrom_idx = 0;\n\t\t} else {\n\t\t\tfrom_idx = len - 1;\n\t\t}\n\t}\n\n\t/* stack[0] = searchElement\n\t * stack[1] = fromIndex\n\t * stack[2] = object\n\t * stack[3] = length (not needed, but not popped above)\n\t */\n\n\tfor (i = from_idx; i >= 0 && i < len; i += idx_step) {\n\t\tDUK_ASSERT_TOP(thr, 4);\n\n\t\tif (duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t\tif (duk_strict_equals(thr, 0, 4)) {\n\t\t\t\tduk_push_int(thr, i);\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\tduk_pop_unsafe(thr);\n\t}\n\n not_found:\n\tduk_push_int(thr, -1);\n\treturn 1;\n}\n\n/*\n *  every(), some(), forEach(), map(), filter()\n */\n\n#define DUK__ITER_EVERY    0\n#define DUK__ITER_SOME     1\n#define DUK__ITER_FOREACH  2\n#define DUK__ITER_MAP      3\n#define DUK__ITER_FILTER   4\n\n/* XXX: This helper is a bit awkward because the handling for the different iteration\n * callers is quite different.  This now compiles to a bit less than 500 bytes, so with\n * 5 callers the net result is about 100 bytes / caller.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_iter_shared(duk_hthread *thr) {\n\tduk_uint32_t len;\n\tduk_uint32_t i;\n\tduk_uarridx_t k;\n\tduk_bool_t bval;\n\tduk_small_int_t iter_type = duk_get_current_magic(thr);\n\tduk_uint32_t res_length = 0;\n\n\t/* each call this helper serves has nargs==2 */\n\tDUK_ASSERT_TOP(thr, 2);\n\n\tlen = duk__push_this_obj_len_u32(thr);\n\tduk_require_callable(thr, 0);\n\t/* if thisArg not supplied, behave as if undefined was supplied */\n\n\tif (iter_type == DUK__ITER_MAP || iter_type == DUK__ITER_FILTER) {\n\t\tduk_push_array(thr);\n\t} else {\n\t\tduk_push_undefined(thr);\n\t}\n\n\t/* stack[0] = callback\n\t * stack[1] = thisArg\n\t * stack[2] = object\n\t * stack[3] = ToUint32(length)  (unused, but avoid unnecessary pop)\n\t * stack[4] = result array (or undefined)\n\t */\n\n\tk = 0;  /* result index for filter() */\n\tfor (i = 0; i < len; i++) {\n\t\tDUK_ASSERT_TOP(thr, 5);\n\n\t\tif (!duk_get_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\t/* For 'map' trailing missing elements don't invoke the\n\t\t\t * callback but count towards the result length.\n\t\t\t */\n\t\t\tif (iter_type == DUK__ITER_MAP) {\n\t\t\t\tres_length = i + 1;\n\t\t\t}\n\t\t\tduk_pop_undefined(thr);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* The original value needs to be preserved for filter(), hence\n\t\t * this funny order.  We can't re-get the value because of side\n\t\t * effects.\n\t\t */\n\n\t\tduk_dup_0(thr);\n\t\tduk_dup_1(thr);\n\t\tduk_dup_m3(thr);\n\t\tduk_push_u32(thr, i);\n\t\tduk_dup_2(thr);  /* [ ... val callback thisArg val i obj ] */\n\t\tduk_call_method(thr, 3); /* -> [ ... val retval ] */\n\n\t\tswitch (iter_type) {\n\t\tcase DUK__ITER_EVERY:\n\t\t\tbval = duk_to_boolean(thr, -1);\n\t\t\tif (!bval) {\n\t\t\t\t/* stack top contains 'false' */\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase DUK__ITER_SOME:\n\t\t\tbval = duk_to_boolean(thr, -1);\n\t\t\tif (bval) {\n\t\t\t\t/* stack top contains 'true' */\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tbreak;\n\t\tcase DUK__ITER_FOREACH:\n\t\t\t/* nop */\n\t\t\tbreak;\n\t\tcase DUK__ITER_MAP:\n\t\t\tduk_dup_top(thr);\n\t\t\tduk_xdef_prop_index_wec(thr, 4, (duk_uarridx_t) i);  /* retval to result[i] */\n\t\t\tres_length = i + 1;\n\t\t\tbreak;\n\t\tcase DUK__ITER_FILTER:\n\t\t\tbval = duk_to_boolean(thr, -1);\n\t\t\tif (bval) {\n\t\t\t\tduk_dup_m2(thr);  /* orig value */\n\t\t\t\tduk_xdef_prop_index_wec(thr, 4, (duk_uarridx_t) k);\n\t\t\t\tk++;\n\t\t\t\tres_length = k;\n\t\t\t}\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tduk_pop_2_unsafe(thr);\n\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t}\n\n\tswitch (iter_type) {\n\tcase DUK__ITER_EVERY:\n\t\tduk_push_true(thr);\n\t\tbreak;\n\tcase DUK__ITER_SOME:\n\t\tduk_push_false(thr);\n\t\tbreak;\n\tcase DUK__ITER_FOREACH:\n\t\tduk_push_undefined(thr);\n\t\tbreak;\n\tcase DUK__ITER_MAP:\n\tcase DUK__ITER_FILTER:\n\t\tDUK_ASSERT_TOP(thr, 5);\n\t\tDUK_ASSERT(duk_is_array(thr, -1));  /* topmost element is the result array already */\n\t\tduk_push_u32(thr, res_length);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_W);\n\t\tbreak;\n\tdefault:\n\t\tDUK_UNREACHABLE();\n\t\tbreak;\n\t}\n\n\treturn 1;\n}\n\n/*\n *  reduce(), reduceRight()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_array_prototype_reduce_shared(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_bool_t have_acc;\n\tduk_uint32_t i, len;\n\tduk_small_int_t idx_step = duk_get_current_magic(thr);  /* idx_step is +1 for reduce, -1 for reduceRight */\n\n\t/* We're a varargs function because we need to detect whether\n\t * initialValue was given or not.\n\t */\n\tnargs = duk_get_top(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"nargs=%ld\", (long) nargs));\n\n\tduk_set_top(thr, 2);\n\tlen = duk__push_this_obj_len_u32(thr);\n\tduk_require_callable(thr, 0);\n\n\t/* stack[0] = callback fn\n\t * stack[1] = initialValue\n\t * stack[2] = object (coerced this)\n\t * stack[3] = length (not needed, but not popped above)\n\t * stack[4] = accumulator\n\t */\n\n\thave_acc = 0;\n\tif (nargs >= 2) {\n\t\tduk_dup_1(thr);\n\t\thave_acc = 1;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"have_acc=%ld, acc=%!T\",\n\t                     (long) have_acc, (duk_tval *) duk_get_tval(thr, 3)));\n\n\t/* For len == 0, i is initialized to len - 1 which underflows.\n\t * The condition (i < len) will then exit the for-loop on the\n\t * first round which is correct.  Similarly, loop termination\n\t * happens by i underflowing.\n\t */\n\n\tfor (i = (idx_step >= 0 ? 0 : len - 1);\n\t     i < len;  /* i >= 0 would always be true */\n\t     i += (duk_uint32_t) idx_step) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"i=%ld, len=%ld, have_acc=%ld, top=%ld, acc=%!T\",\n\t\t                     (long) i, (long) len, (long) have_acc,\n\t\t                     (long) duk_get_top(thr),\n\t\t                     (duk_tval *) duk_get_tval(thr, 4)));\n\n\t\tDUK_ASSERT((have_acc && duk_get_top(thr) == 5) ||\n\t\t           (!have_acc && duk_get_top(thr) == 4));\n\n\t\tif (!duk_has_prop_index(thr, 2, (duk_uarridx_t) i)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!have_acc) {\n\t\t\tDUK_ASSERT_TOP(thr, 4);\n\t\t\tduk_get_prop_index(thr, 2, (duk_uarridx_t) i);\n\t\t\thave_acc = 1;\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t} else {\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_dup(thr, 4);\n\t\t\tduk_get_prop_index(thr, 2, (duk_uarridx_t) i);\n\t\t\tduk_push_u32(thr, i);\n\t\t\tduk_dup_2(thr);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"calling reduce function: func=%!T, prev=%!T, curr=%!T, idx=%!T, obj=%!T\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -5), (duk_tval *) duk_get_tval(thr, -4),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -3), (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tduk_call(thr, 4);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> result: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tduk_replace(thr, 4);\n\t\t\tDUK_ASSERT_TOP(thr, 5);\n\t\t}\n\t}\n\n\tif (!have_acc) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tDUK_ASSERT_TOP(thr, 5);\n\treturn 1;\n}\n\n#endif  /* DUK_USE_ARRAY_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_boolean.c",
    "content": "/*\n *  Boolean built-ins\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_BOOLEAN_BUILTIN)\n\n/* Shared helper to provide toString() and valueOf().  Checks 'this', gets\n * the primitive value to stack top, and optionally coerces with ToString().\n */\nDUK_INTERNAL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\tduk_small_int_t coerce_tostring = duk_get_current_magic(thr);\n\n\t/* XXX: there is room to use a shared helper here, many built-ins\n\t * check the 'this' type, and if it's an object, check its class,\n\t * then get its internal value, etc.\n\t */\n\n\tduk_push_this(thr);\n\ttv = duk_get_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_BOOLEAN(tv)) {\n\t\tgoto type_ok;\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_BOOLEAN) {\n\t\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t\t\tDUK_ASSERT(duk_is_boolean(thr, -1));\n\t\t\tgoto type_ok;\n\t\t}\n\t}\n\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t/* never here */\n\n type_ok:\n\tif (coerce_tostring) {\n\t\tduk_to_string(thr, -1);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_boolean_constructor(duk_hthread *thr) {\n\tduk_hobject *h_this;\n\n\tduk_to_boolean(thr, 0);\n\n\tif (duk_is_constructor_call(thr)) {\n\t\t/* XXX: helper; rely on Boolean.prototype as being non-writable, non-configurable */\n\t\tduk_push_this(thr);\n\t\th_this = duk_known_hobject(thr, -1);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE]);\n\n\t\tDUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_BOOLEAN);\n\n\t\tduk_dup_0(thr);  /* -> [ val obj val ] */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);  /* XXX: proper flags? */\n\t}  /* unbalanced stack */\n\n\treturn 1;\n}\n\n#endif  /* DUK_USE_BOOLEAN_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_buffer.c",
    "content": "/*\n *  ES2015 TypedArray and Node.js Buffer built-ins\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Helpers for buffer handling, enabled with DUK_USE_BUFFEROBJECT_SUPPORT.\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Map class number (minus DUK_HOBJECT_CLASS_BUFOBJ_MIN) to a bidx for the\n * default internal prototype.\n */\nstatic const duk_uint8_t duk__buffer_proto_from_classnum[] = {\n\tDUK_BIDX_ARRAYBUFFER_PROTOTYPE,\n\tDUK_BIDX_DATAVIEW_PROTOTYPE,\n\tDUK_BIDX_INT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE,\n\tDUK_BIDX_INT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_INT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT64ARRAY_PROTOTYPE\n};\n\n/* Map DUK_HBUFOBJ_ELEM_xxx to duk_hobject class number.\n * Sync with duk_hbufobj.h and duk_hobject.h.\n */\nstatic const duk_uint8_t duk__buffer_class_from_elemtype[9] = {\n\tDUK_HOBJECT_CLASS_UINT8ARRAY,\n\tDUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY,\n\tDUK_HOBJECT_CLASS_INT8ARRAY,\n\tDUK_HOBJECT_CLASS_UINT16ARRAY,\n\tDUK_HOBJECT_CLASS_INT16ARRAY,\n\tDUK_HOBJECT_CLASS_UINT32ARRAY,\n\tDUK_HOBJECT_CLASS_INT32ARRAY,\n\tDUK_HOBJECT_CLASS_FLOAT32ARRAY,\n\tDUK_HOBJECT_CLASS_FLOAT64ARRAY\n};\n\n/* Map DUK_HBUFOBJ_ELEM_xxx to prototype object built-in index.\n * Sync with duk_hbufobj.h.\n */\nstatic const duk_uint8_t duk__buffer_proto_from_elemtype[9] = {\n\tDUK_BIDX_UINT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE,\n\tDUK_BIDX_INT8ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_INT16ARRAY_PROTOTYPE,\n\tDUK_BIDX_UINT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_INT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT32ARRAY_PROTOTYPE,\n\tDUK_BIDX_FLOAT64ARRAY_PROTOTYPE\n};\n\n/* Map DUK__FLD_xxx to byte size. */\nstatic const duk_uint8_t duk__buffer_nbytes_from_fldtype[6] = {\n\t1,  /* DUK__FLD_8BIT */\n\t2,  /* DUK__FLD_16BIT */\n\t4,  /* DUK__FLD_32BIT */\n\t4,  /* DUK__FLD_FLOAT */\n\t8,  /* DUK__FLD_DOUBLE */\n\t0   /* DUK__FLD_VARINT; not relevant here */\n};\n\n/* Bitfield for each DUK_HBUFOBJ_ELEM_xxx indicating which element types\n * are compatible with a blind byte copy for the TypedArray set() method (also\n * used for TypedArray constructor).  Array index is target buffer elem type,\n * bitfield indicates compatible source types.  The types must have same byte\n * size and they must be coercion compatible.\n */\n#if !defined(DUK_USE_PREFER_SIZE)\nstatic duk_uint16_t duk__buffer_elemtype_copy_compatible[9] = {\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT8 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT8) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_UINT8CLAMPED) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT8),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT8CLAMPED\n\t * Note: INT8 is -not- copy compatible, e.g. -1 would coerce to 0x00.\n\t */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT8) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_UINT8CLAMPED),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_INT8 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT8) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_UINT8CLAMPED) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT8),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT16 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT16) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT16),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_INT16 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT16) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT16),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_UINT32 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT32) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT32),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_INT32 */\n\t(1U << DUK_HBUFOBJ_ELEM_UINT32) |\n\t\t(1U << DUK_HBUFOBJ_ELEM_INT32),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_FLOAT32 */\n\t(1U << DUK_HBUFOBJ_ELEM_FLOAT32),\n\n\t/* xxx -> DUK_HBUFOBJ_ELEM_FLOAT64 */\n\t(1U << DUK_HBUFOBJ_ELEM_FLOAT64)\n};\n#endif  /* !DUK_USE_PREFER_SIZE */\n\nDUK_LOCAL duk_hbufobj *duk__hbufobj_promote_this(duk_hthread *thr) {\n\tduk_tval *tv_dst;\n\tduk_hbufobj *res;\n\n\tduk_push_this(thr);\n\tDUK_ASSERT(duk_is_buffer(thr, -1));\n\tres = (duk_hbufobj *) duk_to_hobject(thr, -1);\n\tDUK_HBUFOBJ_ASSERT_VALID(res);\n\tDUK_DD(DUK_DDPRINT(\"promoted 'this' automatically to an ArrayBuffer: %!iT\", duk_get_tval(thr, -1)));\n\n\ttv_dst = duk_get_borrowed_this_tval(thr);\n\tDUK_TVAL_SET_OBJECT_UPDREF(thr, tv_dst, (duk_hobject *) res);\n\tduk_pop(thr);\n\n\treturn res;\n}\n\n#define DUK__BUFOBJ_FLAG_THROW    (1 << 0)\n#define DUK__BUFOBJ_FLAG_PROMOTE  (1 << 1)\n\n/* Shared helper.  When DUK__BUFOBJ_FLAG_PROMOTE is given, the return value is\n * always a duk_hbufobj *.  Without the flag the return value can also be a\n * plain buffer, and the caller must check for it using DUK_HEAPHDR_IS_BUFFER().\n */\nDUK_LOCAL duk_heaphdr *duk__getrequire_bufobj_this(duk_hthread *thr, duk_small_uint_t flags) {\n\tduk_tval *tv;\n\tduk_hbufobj *h_this;\n\n\tDUK_ASSERT(thr != NULL);\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_this = (duk_hbufobj *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_this != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h_this)) {\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\t\t\treturn (duk_heaphdr *) h_this;\n\t\t}\n\t} else if (DUK_TVAL_IS_BUFFER(tv)) {\n\t\tif (flags & DUK__BUFOBJ_FLAG_PROMOTE) {\n\t\t\t/* Promote a plain buffer to a Uint8Array.  This is very\n\t\t\t * inefficient but allows plain buffer to be used wherever an\n\t\t\t * Uint8Array is used with very small cost; hot path functions\n\t\t\t * like index read/write calls should provide direct buffer\n\t\t\t * support to avoid promotion.\n\t\t\t */\n\t\t\t/* XXX: make this conditional to a flag if call sites need it? */\n\t\t\th_this = duk__hbufobj_promote_this(thr);\n\t\t\tDUK_ASSERT(h_this != NULL);\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\t\t\treturn (duk_heaphdr *) h_this;\n\t\t} else {\n\t\t\t/* XXX: ugly, share return pointer for duk_hbuffer. */\n\t\t\treturn (duk_heaphdr *) DUK_TVAL_GET_BUFFER(tv);\n\t\t}\n\t}\n\n\tif (flags & DUK__BUFOBJ_FLAG_THROW) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_BUFFER);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn NULL;\n}\n\n/* Check that 'this' is a duk_hbufobj and return a pointer to it. */\nDUK_LOCAL duk_hbufobj *duk__get_bufobj_this(duk_hthread *thr) {\n\treturn (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_PROMOTE);\n}\n\n/* Check that 'this' is a duk_hbufobj and return a pointer to it\n * (NULL if not).\n */\nDUK_LOCAL duk_hbufobj *duk__require_bufobj_this(duk_hthread *thr) {\n\treturn (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW | DUK__BUFOBJ_FLAG_PROMOTE);\n}\n\n/* Check that value is a duk_hbufobj and return a pointer to it. */\nDUK_LOCAL duk_hbufobj *duk__require_bufobj_value(duk_hthread *thr, duk_idx_t idx) {\n\tduk_tval *tv;\n\tduk_hbufobj *h_obj;\n\n\t/* Don't accept relative indices now. */\n\tDUK_ASSERT(idx >= 0);\n\n\ttv = duk_require_tval(thr, idx);\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_obj = (duk_hbufobj *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tif (DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h_obj)) {\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_obj);\n\t\t\treturn h_obj;\n\t\t}\n\t} else if (DUK_TVAL_IS_BUFFER(tv)) {\n\t\th_obj = (duk_hbufobj *) duk_to_hobject(thr, idx);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tDUK_HBUFOBJ_ASSERT_VALID(h_obj);\n\t\treturn h_obj;\n\t}\n\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_BUFFER);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_LOCAL void duk__set_bufobj_buffer(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_hbuffer *h_val) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tDUK_ASSERT(h_bufobj->buf == NULL);  /* no need to decref */\n\tDUK_ASSERT(h_val != NULL);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\tDUK_UNREF(thr);\n\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\th_bufobj->length = (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_val);\n\tDUK_ASSERT(h_bufobj->shift == 0);\n\tDUK_ASSERT(h_bufobj->elem_type == DUK_HBUFOBJ_ELEM_UINT8);\n\tDUK_ASSERT(h_bufobj->is_typedarray == 0);\n\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n}\n\n/* Shared offset/length coercion helper. */\nDUK_LOCAL void duk__resolve_offset_opt_length(duk_hthread *thr,\n                                              duk_hbufobj *h_bufarg,\n                                              duk_idx_t idx_offset,\n                                              duk_idx_t idx_length,\n                                              duk_uint_t *out_offset,\n                                              duk_uint_t *out_length,\n                                              duk_bool_t throw_flag) {\n\tduk_int_t offset_signed;\n\tduk_int_t length_signed;\n\tduk_uint_t offset;\n\tduk_uint_t length;\n\n\toffset_signed = duk_to_int(thr, idx_offset);\n\tif (offset_signed < 0) {\n\t\tgoto fail_range;\n\t}\n\toffset = (duk_uint_t) offset_signed;\n\tif (offset > h_bufarg->length) {\n\t\tgoto fail_range;\n\t}\n\tDUK_ASSERT_DISABLE(offset >= 0);  /* unsigned */\n\tDUK_ASSERT(offset <= h_bufarg->length);\n\n\tif (duk_is_undefined(thr, idx_length)) {\n\t\tDUK_ASSERT(h_bufarg->length >= offset);\n\t\tlength = h_bufarg->length - offset;  /* >= 0 */\n\t} else {\n\t\tlength_signed = duk_to_int(thr, idx_length);\n\t\tif (length_signed < 0) {\n\t\t\tgoto fail_range;\n\t\t}\n\t\tlength = (duk_uint_t) length_signed;\n\t\tDUK_ASSERT(h_bufarg->length >= offset);\n\t\tif (length > h_bufarg->length - offset) {\n\t\t\t/* Unlike for negative arguments, some call sites\n\t\t\t * want length to be clamped if it's positive.\n\t\t\t */\n\t\t\tif (throw_flag) {\n\t\t\t\tgoto fail_range;\n\t\t\t} else {\n\t\t\t\tlength = h_bufarg->length - offset;\n\t\t\t}\n\t\t}\n\t}\n\tDUK_ASSERT_DISABLE(length >= 0);  /* unsigned */\n\tDUK_ASSERT(offset + length <= h_bufarg->length);\n\n\t*out_offset = offset;\n\t*out_length = length;\n\treturn;\n\n fail_range:\n\tDUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARGS);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Shared lenient buffer length clamping helper.  No negative indices, no\n * element/byte shifting.\n */\nDUK_LOCAL void duk__clamp_startend_nonegidx_noshift(duk_hthread *thr,\n                                                    duk_int_t buffer_length,\n                                                    duk_idx_t idx_start,\n                                                    duk_idx_t idx_end,\n                                                    duk_int_t *out_start_offset,\n                                                    duk_int_t *out_end_offset) {\n\tduk_int_t start_offset;\n\tduk_int_t end_offset;\n\n\tDUK_ASSERT(out_start_offset != NULL);\n\tDUK_ASSERT(out_end_offset != NULL);\n\n\t/* undefined coerces to zero which is correct */\n\tstart_offset = duk_to_int_clamped(thr, idx_start, 0, buffer_length);\n\tif (duk_is_undefined(thr, idx_end)) {\n\t\tend_offset = buffer_length;\n\t} else {\n\t\tend_offset = duk_to_int_clamped(thr, idx_end, start_offset, buffer_length);\n\t}\n\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(start_offset <= buffer_length);\n\tDUK_ASSERT(end_offset >= 0);\n\tDUK_ASSERT(end_offset <= buffer_length);\n\tDUK_ASSERT(start_offset <= end_offset);\n\n\t*out_start_offset = start_offset;\n\t*out_end_offset = end_offset;\n}\n\n/* Shared lenient buffer length clamping helper.  Indices are treated as\n * element indices (though output values are byte offsets) which only\n * really matters for TypedArray views as other buffer object have a zero\n * shift.  Negative indices are counted from end of input slice; crossed\n * indices are clamped to zero length; and final indices are clamped\n * against input slice.  Used for e.g. ArrayBuffer slice().\n */\nDUK_LOCAL void duk__clamp_startend_negidx_shifted(duk_hthread *thr,\n                                                  duk_int_t buffer_length,\n                                                  duk_uint8_t buffer_shift,\n                                                  duk_idx_t idx_start,\n                                                  duk_idx_t idx_end,\n                                                  duk_int_t *out_start_offset,\n                                                  duk_int_t *out_end_offset) {\n\tduk_int_t start_offset;\n\tduk_int_t end_offset;\n\n\tDUK_ASSERT(out_start_offset != NULL);\n\tDUK_ASSERT(out_end_offset != NULL);\n\n\tbuffer_length >>= buffer_shift;  /* as (full) elements */\n\n\t/* Resolve start/end offset as element indices first; arguments\n\t * at idx_start/idx_end are element offsets.  Working with element\n\t * indices first also avoids potential for wrapping.\n\t */\n\n\tstart_offset = duk_to_int(thr, idx_start);\n\tif (start_offset < 0) {\n\t\tstart_offset = buffer_length + start_offset;\n\t}\n\tif (duk_is_undefined(thr, idx_end)) {\n\t\tend_offset = buffer_length;\n\t} else {\n\t\tend_offset = duk_to_int(thr, idx_end);\n\t\tif (end_offset < 0) {\n\t\t\tend_offset = buffer_length + end_offset;\n\t\t}\n\t}\n\t/* Note: start_offset/end_offset can still be < 0 here. */\n\n\tif (start_offset < 0) {\n\t\tstart_offset = 0;\n\t} else if (start_offset > buffer_length) {\n\t\tstart_offset = buffer_length;\n\t}\n\tif (end_offset < start_offset) {\n\t\tend_offset = start_offset;\n\t} else if (end_offset > buffer_length) {\n\t\tend_offset = buffer_length;\n\t}\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(start_offset <= buffer_length);\n\tDUK_ASSERT(end_offset >= 0);\n\tDUK_ASSERT(end_offset <= buffer_length);\n\tDUK_ASSERT(start_offset <= end_offset);\n\n\t/* Convert indices to byte offsets. */\n\tstart_offset <<= buffer_shift;\n\tend_offset <<= buffer_shift;\n\n\t*out_start_offset = start_offset;\n\t*out_end_offset = end_offset;\n}\n\nDUK_INTERNAL void duk_hbufobj_promote_plain(duk_hthread *thr, duk_idx_t idx) {\n\tif (duk_is_buffer(thr, idx)) {\n\t\tduk_to_object(thr, idx);\n\t}\n}\n\nDUK_INTERNAL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_hbuffer *h_buf) {\n\t/* Push Uint8Array which will share the same underlying buffer as\n\t * the plain buffer argument.  Also create an ArrayBuffer with the\n\t * same backing for the result .buffer property.\n\t */\n\n\tduk_push_hbuffer(thr, h_buf);\n\tduk_push_buffer_object(thr, -1, 0, (duk_size_t) DUK_HBUFFER_GET_SIZE(h_buf), DUK_BUFOBJ_UINT8ARRAY);\n\tduk_remove_m2(thr);\n\n#if 0\n\t/* More verbose equivalent; maybe useful if e.g. .buffer is omitted. */\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_UINT8ARRAY),\n\t                               DUK_BIDX_UINT8ARRAY_PROTOTYPE);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tduk__set_bufobj_buffer(thr, h_bufobj, h_buf);\n\th_bufobj->is_typedarray = 1;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\th_arrbuf = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),\n\t                               DUK_BIDX_ARRAYBUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_arrbuf != NULL);\n\tduk__set_bufobj_buffer(thr, h_arrbuf, h_buf);\n\tDUK_ASSERT(h_arrbuf->is_typedarray == 0);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_arrbuf);\n\n\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\th_bufobj->buf_prop = (duk_hobject *) h_arrbuf;\n\tDUK_ASSERT(h_arrbuf != NULL);\n\tDUK_HBUFOBJ_INCREF(thr, h_arrbuf);\n\tduk_pop(thr);\n#endif\n}\n\n/* Indexed read helper for buffer objects, also called from outside this file. */\nDUK_INTERNAL void duk_hbufobj_push_validated_read(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size) {\n\tduk_double_union du;\n\n\tDUK_ASSERT(elem_size > 0);\n\tduk_memcpy((void *) du.uc, (const void *) p, (size_t) elem_size);\n\n\tswitch (h_bufobj->elem_type) {\n\tcase DUK_HBUFOBJ_ELEM_UINT8:\n\tcase DUK_HBUFOBJ_ELEM_UINT8CLAMPED:\n\t\tduk_push_uint(thr, (duk_uint_t) du.uc[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT8:\n\t\tduk_push_int(thr, (duk_int_t) (duk_int8_t) du.uc[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT16:\n\t\tduk_push_uint(thr, (duk_uint_t) du.us[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT16:\n\t\tduk_push_int(thr, (duk_int_t) (duk_int16_t) du.us[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT32:\n\t\tduk_push_uint(thr, (duk_uint_t) du.ui[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT32:\n\t\tduk_push_int(thr, (duk_int_t) (duk_int32_t) du.ui[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT32:\n\t\tduk_push_number(thr, (duk_double_t) du.f[0]);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT64:\n\t\tduk_push_number(thr, (duk_double_t) du.d);\n\t\tbreak;\n\tdefault:\n\t\tDUK_UNREACHABLE();\n\t}\n}\n\n/* Indexed write helper for buffer objects, also called from outside this file. */\nDUK_INTERNAL void duk_hbufobj_validated_write(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size) {\n\tduk_double_union du;\n\n\t/* NOTE! Caller must ensure that any side effects from the\n\t * coercions below are safe.  If that cannot be guaranteed\n\t * (which is normally the case), caller must coerce the\n\t * argument using duk_to_number() before any pointer\n\t * validations; the result of duk_to_number() always coerces\n\t * without side effects here.\n\t */\n\n\tswitch (h_bufobj->elem_type) {\n\tcase DUK_HBUFOBJ_ELEM_UINT8:\n\t\tdu.uc[0] = (duk_uint8_t) duk_to_uint32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT8CLAMPED:\n\t\tdu.uc[0] = (duk_uint8_t) duk_to_uint8clamped(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT8:\n\t\tdu.uc[0] = (duk_uint8_t) duk_to_int32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT16:\n\t\tdu.us[0] = (duk_uint16_t) duk_to_uint32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT16:\n\t\tdu.us[0] = (duk_uint16_t) duk_to_int32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_UINT32:\n\t\tdu.ui[0] = (duk_uint32_t) duk_to_uint32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_INT32:\n\t\tdu.ui[0] = (duk_uint32_t) duk_to_int32(thr, -1);\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT32:\n\t\t/* A double-to-float cast is undefined behavior in C99 if\n\t\t * the cast is out-of-range, so use a helper.  Example:\n\t\t * runtime error: value -1e+100 is outside the range of representable values of type 'float'\n\t\t */\n\t\tdu.f[0] = duk_double_to_float_t(duk_to_number_m1(thr));\n\t\tbreak;\n\tcase DUK_HBUFOBJ_ELEM_FLOAT64:\n\t\tdu.d = (duk_double_t) duk_to_number_m1(thr);\n\t\tbreak;\n\tdefault:\n\t\tDUK_UNREACHABLE();\n\t}\n\n\tDUK_ASSERT(elem_size > 0);\n\tduk_memcpy((void *) p, (const void *) du.uc, (size_t) elem_size);\n}\n\n/* Helper to create a fixed buffer from argument value at index 0.\n * Node.js and allocPlain() compatible.\n */\nDUK_LOCAL duk_hbuffer *duk__hbufobj_fixed_from_argvalue(duk_hthread *thr) {\n\tduk_int_t len;\n\tduk_int_t i;\n\tduk_size_t buf_size;\n\tduk_uint8_t *buf;\n\n\tswitch (duk_get_type(thr, 0)) {\n\tcase DUK_TYPE_NUMBER: {\n\t\tlen = duk_to_int_clamped(thr, 0, 0, DUK_INT_MAX);\n\t\t(void) duk_push_fixed_buffer_zero(thr, (duk_size_t) len);\n\t\tbreak;\n\t}\n\tcase DUK_TYPE_BUFFER: { /* Treat like Uint8Array. */\n\t\tgoto slow_copy;\n\t}\n\tcase DUK_TYPE_OBJECT: {\n\t\tduk_hobject *h;\n\t\tduk_hbufobj *h_bufobj;\n\n\t\t/* For Node.js Buffers \"Passing an ArrayBuffer returns a Buffer\n\t\t * that shares allocated memory with the given ArrayBuffer.\"\n\t\t * https://nodejs.org/api/buffer.html#buffer_buffer_from_buffer_alloc_and_buffer_allocunsafe\n\t\t */\n\n\t\th = duk_known_hobject(thr, 0);\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ(h));\n\t\t\th_bufobj = (duk_hbufobj *) h;\n\t\t\tif (DUK_UNLIKELY(h_bufobj->buf == NULL)) {\n\t\t\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(h_bufobj->offset != 0 || h_bufobj->length != DUK_HBUFFER_GET_SIZE(h_bufobj->buf))) {\n\t\t\t\t/* No support for ArrayBuffers with slice\n\t\t\t\t * offset/length.\n\t\t\t\t */\n\t\t\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t\t}\n\t\t\tduk_push_hbuffer(thr, h_bufobj->buf);\n\t\t\treturn h_bufobj->buf;\n\t\t}\n\t\tgoto slow_copy;\n\t}\n\tcase DUK_TYPE_STRING: {\n\t\t/* ignore encoding for now */\n\t\tduk_require_hstring_notsymbol(thr, 0);\n\t\tduk_dup_0(thr);\n\t\t(void) duk_to_buffer(thr, -1, &buf_size);\n\t\tbreak;\n\t}\n\tdefault:\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\n done:\n\tDUK_ASSERT(duk_is_buffer(thr, -1));\n\treturn duk_known_hbuffer(thr, -1);\n\n slow_copy:\n\t/* XXX: fast path for typed arrays and other buffer objects? */\n\n\t(void) duk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LENGTH);\n\tlen = duk_to_int_clamped(thr, -1, 0, DUK_INT_MAX);\n\tduk_pop(thr);\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) len);  /* no zeroing, all indices get initialized */\n\tfor (i = 0; i < len; i++) {\n\t\t/* XXX: fast path for array or buffer arguments? */\n\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);\n\t\tbuf[i] = (duk_uint8_t) (duk_to_uint32(thr, -1) & 0xffU);\n\t\tduk_pop(thr);\n\t}\n\tgoto done;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer constructor\n *\n *  Node.js Buffers are just Uint8Arrays with internal prototype set to\n *  Buffer.prototype so they're handled otherwise the same as Uint8Array.\n *  However, the constructor arguments are very different so a separate\n *  constructor entry point is used.\n */\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_hthread *thr) {\n\tduk_hbuffer *h_buf;\n\n\th_buf = duk__hbufobj_fixed_from_argvalue(thr);\n\tDUK_ASSERT(h_buf != NULL);\n\n\tduk_push_buffer_object(thr,\n\t                       -1,\n\t                       0,\n\t                       DUK_HBUFFER_FIXED_GET_SIZE((duk_hbuffer_fixed *) (void *) h_buf),\n\t                       DUK_BUFOBJ_UINT8ARRAY);\n\tduk_push_hobject_bidx(thr, DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);\n\tduk_set_prototype(thr, -2);\n\n\t/* XXX: a more direct implementation */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  ArrayBuffer, DataView, and TypedArray constructors\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_arraybuffer_constructor(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_int_t len;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\tduk_require_constructor_call(thr);\n\n\tlen = duk_to_int(thr, 0);\n\tif (len < 0) {\n\t\tgoto fail_length;\n\t}\n\t(void) duk_push_fixed_buffer_zero(thr, (duk_size_t) len);\n\th_val = (duk_hbuffer *) duk_known_hbuffer(thr, -1);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),\n\t                               DUK_BIDX_ARRAYBUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_bufobj != NULL);\n\n\tduk__set_bufobj_buffer(thr, h_bufobj, h_val);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\treturn 1;\n\n fail_length:\n\tDUK_DCERROR_RANGE_INVALID_LENGTH(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\n/* Format of magic, bits:\n *   0...1: elem size shift (0-3)\n *   2...5: elem type (DUK_HBUFOBJ_ELEM_xxx)\n *\n * XXX: add prototype bidx explicitly to magic instead of using a mapping?\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hobject *h_obj;\n\tduk_hbufobj *h_bufobj = NULL;\n\tduk_hbufobj *h_bufarg = NULL;\n\tduk_hbuffer *h_val;\n\tduk_small_uint_t magic;\n\tduk_small_uint_t shift;\n\tduk_small_uint_t elem_type;\n\tduk_small_uint_t elem_size;\n\tduk_small_uint_t class_num;\n\tduk_small_uint_t proto_bidx;\n\tduk_uint_t align_mask;\n\tduk_uint_t elem_length;\n\tduk_int_t elem_length_signed;\n\tduk_uint_t byte_length;\n\tduk_small_uint_t copy_mode;\n\n\t/* XXX: The same copy helpers could be shared with at least some\n\t * buffer functions.\n\t */\n\n\tduk_require_constructor_call(thr);\n\n\t/* We could fit built-in index into magic but that'd make the magic\n\t * number dependent on built-in numbering (genbuiltins.py doesn't\n\t * handle that yet).  So map both class and prototype from the\n\t * element type.\n\t */\n\tmagic = (duk_small_uint_t) duk_get_current_magic(thr);\n\tshift = magic & 0x03U;               /* bits 0...1: shift */\n\telem_type = (magic >> 2) & 0x0fU;    /* bits 2...5: type */\n\telem_size = 1U << shift;\n\talign_mask = elem_size - 1;\n\tDUK_ASSERT(elem_type < sizeof(duk__buffer_proto_from_elemtype) / sizeof(duk_uint8_t));\n\tproto_bidx = duk__buffer_proto_from_elemtype[elem_type];\n\tDUK_ASSERT(proto_bidx < DUK_NUM_BUILTINS);\n\tDUK_ASSERT(elem_type < sizeof(duk__buffer_class_from_elemtype) / sizeof(duk_uint8_t));\n\tclass_num = duk__buffer_class_from_elemtype[elem_type];\n\n\tDUK_DD(DUK_DDPRINT(\"typedarray constructor, magic=%d, shift=%d, elem_type=%d, \"\n\t                   \"elem_size=%d, proto_bidx=%d, class_num=%d\",\n\t                   (int) magic, (int) shift, (int) elem_type, (int) elem_size,\n\t                   (int) proto_bidx, (int) class_num));\n\n\t/* Argument variants.  When the argument is an ArrayBuffer a view to\n\t * the same buffer is created; otherwise a new ArrayBuffer is always\n\t * created.\n\t */\n\n\t/* XXX: initial iteration to treat a plain buffer like an ArrayBuffer:\n\t * coerce to an ArrayBuffer object and use that as .buffer.  The underlying\n\t * buffer will be the same but result .buffer !== inputPlainBuffer.\n\t */\n\tduk_hbufobj_promote_plain(thr, 0);\n\n\ttv = duk_get_tval(thr, 0);\n\tDUK_ASSERT(tv != NULL);  /* arg count */\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_obj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_obj != NULL);\n\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\t\t/* ArrayBuffer: unlike any other argument variant, create\n\t\t\t * a view into the existing buffer.\n\t\t\t */\n\n\t\t\tduk_int_t byte_offset_signed;\n\t\t\tduk_uint_t byte_offset;\n\n\t\t\th_bufarg = (duk_hbufobj *) h_obj;\n\n\t\t\tbyte_offset_signed = duk_to_int(thr, 1);\n\t\t\tif (byte_offset_signed < 0) {\n\t\t\t\tgoto fail_arguments;\n\t\t\t}\n\t\t\tbyte_offset = (duk_uint_t) byte_offset_signed;\n\t\t\tif (byte_offset > h_bufarg->length ||\n\t\t\t    (byte_offset & align_mask) != 0) {\n\t\t\t\t/* Must be >= 0 and multiple of element size. */\n\t\t\t\tgoto fail_arguments;\n\t\t\t}\n\t\t\tif (duk_is_undefined(thr, 2)) {\n\t\t\t\tDUK_ASSERT(h_bufarg->length >= byte_offset);\n\t\t\t\tbyte_length = h_bufarg->length - byte_offset;\n\t\t\t\tif ((byte_length & align_mask) != 0) {\n\t\t\t\t\t/* Must be element size multiple from\n\t\t\t\t\t * start offset to end of buffer.\n\t\t\t\t\t */\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t\telem_length = (byte_length >> shift);\n\t\t\t} else {\n\t\t\t\telem_length_signed = duk_to_int(thr, 2);\n\t\t\t\tif (elem_length_signed < 0) {\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t\telem_length = (duk_uint_t) elem_length_signed;\n\t\t\t\tbyte_length = elem_length << shift;\n\t\t\t\tif ((byte_length >> shift) != elem_length) {\n\t\t\t\t\t/* Byte length would overflow. */\n\t\t\t\t\t/* XXX: easier check with less code? */\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(h_bufarg->length >= byte_offset);\n\t\t\t\tif (byte_length > h_bufarg->length - byte_offset) {\n\t\t\t\t\t/* Not enough data. */\n\t\t\t\t\tgoto fail_arguments;\n\t\t\t\t}\n\t\t\t}\n\t\t\tDUK_UNREF(elem_length);\n\t\t\tDUK_ASSERT_DISABLE(byte_offset >= 0);\n\t\t\tDUK_ASSERT(byte_offset <= h_bufarg->length);\n\t\t\tDUK_ASSERT_DISABLE(byte_length >= 0);\n\t\t\tDUK_ASSERT(byte_offset + byte_length <= h_bufarg->length);\n\t\t\tDUK_ASSERT((elem_length << shift) == byte_length);\n\n\t\t\th_bufobj = duk_push_bufobj_raw(thr,\n\t\t\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t\t\t                               DUK_HOBJECT_CLASS_AS_FLAGS(class_num),\n\t\t\t                               (duk_small_int_t) proto_bidx);\n\t\t\th_val = h_bufarg->buf;\n\t\t\tif (h_val == NULL) {\n\t\t\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t}\n\t\t\th_bufobj->buf = h_val;\n\t\t\tDUK_HBUFFER_INCREF(thr, h_val);\n\t\t\th_bufobj->offset = h_bufarg->offset + byte_offset;\n\t\t\th_bufobj->length = byte_length;\n\t\t\th_bufobj->shift = (duk_uint8_t) shift;\n\t\t\th_bufobj->elem_type = (duk_uint8_t) elem_type;\n\t\t\th_bufobj->is_typedarray = 1;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t\t\t/* Set .buffer to the argument ArrayBuffer. */\n\t\t\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\t\t\th_bufobj->buf_prop = (duk_hobject *) h_bufarg;\n\t\t\tDUK_ASSERT(h_bufarg != NULL);\n\t\t\tDUK_HBUFOBJ_INCREF(thr, h_bufarg);\n\t\t\treturn 1;\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\t/* TypedArray (or other non-ArrayBuffer duk_hbufobj).\n\t\t\t * Conceptually same behavior as for an Array-like argument,\n\t\t\t * with a few fast paths.\n\t\t\t */\n\n\t\t\th_bufarg = (duk_hbufobj *) h_obj;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufarg);\n\t\t\telem_length_signed = (duk_int_t) (h_bufarg->length >> h_bufarg->shift);\n\t\t\tif (h_bufarg->buf == NULL) {\n\t\t\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t\t\t}\n\n\t\t\t/* Select copy mode.  Must take into account element\n\t\t\t * compatibility and validity of the underlying source\n\t\t\t * buffer.\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"selecting copy mode for bufobj arg, \"\n\t\t\t                     \"src byte_length=%ld, src shift=%d, \"\n\t\t\t                     \"src/dst elem_length=%ld; \"\n\t\t\t                     \"dst shift=%d -> dst byte_length=%ld\",\n\t\t\t                     (long) h_bufarg->length, (int) h_bufarg->shift,\n\t\t\t                     (long) elem_length_signed, (int) shift,\n\t\t\t                     (long) (elem_length_signed << shift)));\n\n\t\t\tcopy_mode = 2;  /* default is explicit index read/write copy */\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t/* With a size optimized build copy_mode 2 is enough.\n\t\t\t * Modes 0 and 1 are faster but conceptually the same.\n\t\t\t */\n\t\t\tDUK_ASSERT(elem_type < sizeof(duk__buffer_elemtype_copy_compatible) / sizeof(duk_uint16_t));\n\t\t\tif (DUK_HBUFOBJ_VALID_SLICE(h_bufarg)) {\n\t\t\t\tif ((duk__buffer_elemtype_copy_compatible[elem_type] & (1 << h_bufarg->elem_type)) != 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"source/target are copy compatible, memcpy\"));\n\t\t\t\t\tDUK_ASSERT(shift == h_bufarg->shift);  /* byte sizes will match */\n\t\t\t\t\tcopy_mode = 0;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"source/target not copy compatible but valid, fast copy\"));\n\t\t\t\t\tcopy_mode = 1;\n\t\t\t\t}\n\t\t\t}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\t\t} else {\n\t\t\t/* Array or Array-like */\n\t\t\telem_length_signed = (duk_int_t) duk_get_length(thr, 0);\n\t\t\tcopy_mode = 2;\n\t\t}\n\t} else {\n\t\t/* Non-object argument is simply int coerced, matches\n\t\t * V8 behavior (except for \"null\", which we coerce to\n\t\t * 0 but V8 TypeErrors).\n\t\t */\n\t\telem_length_signed = duk_to_int(thr, 0);\n\t\tcopy_mode = 3;\n\t}\n\tif (elem_length_signed < 0) {\n\t\tgoto fail_arguments;\n\t}\n\telem_length = (duk_uint_t) elem_length_signed;\n\tbyte_length = (duk_uint_t) (elem_length << shift);\n\tif ((byte_length >> shift) != elem_length) {\n\t\t/* Byte length would overflow. */\n\t\t/* XXX: easier check with less code? */\n\t\tgoto fail_arguments;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"elem_length=%ld, byte_length=%ld\",\n\t                     (long) elem_length, (long) byte_length));\n\n\t/* ArrayBuffer argument is handled specially above; the rest of the\n\t * argument variants are handled by shared code below.\n\t *\n\t * ArrayBuffer in h_bufobj->buf_prop is intentionally left unset.\n\t * It will be automatically created by the .buffer accessor on\n\t * first access.\n\t */\n\n\t/* Push the resulting view object on top of a plain fixed buffer. */\n\t(void) duk_push_fixed_buffer(thr, byte_length);\n\th_val = duk_known_hbuffer(thr, -1);\n\tDUK_ASSERT(h_val != NULL);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(class_num),\n\t                               (duk_small_int_t) proto_bidx);\n\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\tDUK_ASSERT(h_bufobj->offset == 0);\n\th_bufobj->length = byte_length;\n\th_bufobj->shift = (duk_uint8_t) shift;\n\th_bufobj->elem_type = (duk_uint8_t) elem_type;\n\th_bufobj->is_typedarray = 1;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t/* Copy values, the copy method depends on the arguments.\n\t *\n\t * Copy mode decision may depend on the validity of the underlying\n\t * buffer of the source argument; there must be no harmful side effects\n\t * from there to here for copy_mode to still be valid.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"copy mode: %d\", (int) copy_mode));\n\tswitch (copy_mode) {\n\t\t/* Copy modes 0 and 1 can be omitted in size optimized build,\n\t\t * copy mode 2 handles them (but more slowly).\n\t\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tcase 0: {\n\t\t/* Use byte copy. */\n\n\t\tduk_uint8_t *p_src;\n\t\tduk_uint8_t *p_dst;\n\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\t\tDUK_ASSERT(h_bufobj->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufobj));\n\t\tDUK_ASSERT(h_bufarg != NULL);\n\t\tDUK_ASSERT(h_bufarg->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufarg));\n\n\t\tp_dst = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj);\n\t\tp_src = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using memcpy: p_src=%p, p_dst=%p, byte_length=%ld\",\n\t\t                     (void *) p_src, (void *) p_dst, (long) byte_length));\n\n\t\tduk_memcpy_unsafe((void *) p_dst, (const void *) p_src, (size_t) byte_length);\n\t\tbreak;\n\t}\n\tcase 1: {\n\t\t/* Copy values through direct validated reads and writes. */\n\n\t\tduk_small_uint_t src_elem_size;\n\t\tduk_small_uint_t dst_elem_size;\n\t\tduk_uint8_t *p_src;\n\t\tduk_uint8_t *p_src_end;\n\t\tduk_uint8_t *p_dst;\n\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\t\tDUK_ASSERT(h_bufobj->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufobj));\n\t\tDUK_ASSERT(h_bufarg != NULL);\n\t\tDUK_ASSERT(h_bufarg->buf != NULL);\n\t\tDUK_ASSERT(DUK_HBUFOBJ_VALID_SLICE(h_bufarg));\n\n\t\tsrc_elem_size = (duk_small_uint_t) (1U << h_bufarg->shift);\n\t\tdst_elem_size = elem_size;\n\n\t\tp_src = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg);\n\t\tp_dst = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj);\n\t\tp_src_end = p_src + h_bufarg->length;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using fast copy: p_src=%p, p_src_end=%p, p_dst=%p, \"\n\t\t                     \"src_elem_size=%d, dst_elem_size=%d\",\n\t\t                     (void *) p_src, (void *) p_src_end, (void *) p_dst,\n\t\t                     (int) src_elem_size, (int) dst_elem_size));\n\n\t\twhile (p_src != p_src_end) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path per element copy loop: \"\n\t\t\t                     \"p_src=%p, p_src_end=%p, p_dst=%p\",\n\t\t\t                     (void *) p_src, (void *) p_src_end, (void *) p_dst));\n\t\t\t/* A validated read() is always a number, so it's write coercion\n\t\t\t * is always side effect free an won't invalidate pointers etc.\n\t\t\t */\n\t\t\tduk_hbufobj_push_validated_read(thr, h_bufarg, p_src, src_elem_size);\n\t\t\tduk_hbufobj_validated_write(thr, h_bufobj, p_dst, dst_elem_size);\n\t\t\tduk_pop(thr);\n\t\t\tp_src += src_elem_size;\n\t\t\tp_dst += dst_elem_size;\n\t\t}\n\t\tbreak;\n\t}\n#endif  /* !DUK_USE_PREFER_SIZE */\n\tcase 2: {\n\t\t/* Copy values by index reads and writes.  Let virtual\n\t\t * property handling take care of coercion.\n\t\t */\n\t\tduk_uint_t i;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using slow copy\"));\n\n\t\tfor (i = 0; i < elem_length; i++) {\n\t\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);\n\t\t\tduk_put_prop_index(thr, -2, (duk_uarridx_t) i);\n\t\t}\n\t\tbreak;\n\t}\n\tdefault:\n\tcase 3: {\n\t\t/* No copy, leave zero bytes in the buffer.  There's no\n\t\t * ambiguity with Float32/Float64 because zero bytes also\n\t\t * represent 0.0.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"using no copy\"));\n\t\tbreak;\n\t}\n\t}\n\n\treturn 1;\n\n fail_arguments:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n/* When bufferobject support is disabled, new Uint8Array() could still be\n * supported to create a plain fixed buffer.  Disabled for now.\n */\n#if 0\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_constructor(duk_hthread *thr) {\n\tduk_int_t elem_length_signed;\n\tduk_uint_t byte_length;\n\n\t/* XXX: The same copy helpers could be shared with at least some\n\t * buffer functions.\n\t */\n\n\tduk_require_constructor_call(thr);\n\n\telem_length_signed = duk_require_int(thr, 0);\n\tif (elem_length_signed < 0) {\n\t\tgoto fail_arguments;\n\t}\n\tbyte_length = (duk_uint_t) elem_length_signed;\n\n\t(void) duk_push_fixed_buffer_zero(thr, (duk_size_t) byte_length);\n\treturn 1;\n\n fail_arguments:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* 0 */\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_dataview_constructor(duk_hthread *thr) {\n\tduk_hbufobj *h_bufarg;\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_uint_t offset;\n\tduk_uint_t length;\n\n\tduk_require_constructor_call(thr);\n\n\th_bufarg = duk__require_bufobj_value(thr, 0);\n\tDUK_ASSERT(h_bufarg != NULL);\n\tif (DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *) h_bufarg) != DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tduk__resolve_offset_opt_length(thr, h_bufarg, 1, 2, &offset, &length, 1 /*throw_flag*/);\n\tDUK_ASSERT(offset <= h_bufarg->length);\n\tDUK_ASSERT(offset + length <= h_bufarg->length);\n\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATAVIEW),\n\t                               DUK_BIDX_DATAVIEW_PROTOTYPE);\n\n\th_val = h_bufarg->buf;\n\tif (h_val == NULL) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\th_bufobj->buf = h_val;\n\tDUK_HBUFFER_INCREF(thr, h_val);\n\th_bufobj->offset = h_bufarg->offset + offset;\n\th_bufobj->length = length;\n\tDUK_ASSERT(h_bufobj->shift == 0);\n\tDUK_ASSERT(h_bufobj->elem_type == DUK_HBUFOBJ_ELEM_UINT8);\n\tDUK_ASSERT(h_bufobj->is_typedarray == 0);\n\n\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\th_bufobj->buf_prop = (duk_hobject *) h_bufarg;\n\tDUK_ASSERT(h_bufarg != NULL);\n\tDUK_HBUFOBJ_INCREF(thr, h_bufarg);\n\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  ArrayBuffer.isView()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_arraybuffer_isview(duk_hthread *thr) {\n\tduk_hobject *h_obj;\n\tduk_bool_t ret = 0;\n\n\tif (duk_is_buffer(thr, 0)) {\n\t\tret = 1;\n\t} else {\n\t\th_obj = duk_get_hobject(thr, 0);\n\t\tif (h_obj != NULL && DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\t/* DataView needs special casing: ArrayBuffer.isView() is\n\t\t\t * true, but ->is_typedarray is 0.\n\t\t\t */\n\t\t\tret = ((duk_hbufobj *) h_obj)->is_typedarray ||\n\t\t\t      (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_DATAVIEW);\n\t\t}\n\t}\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Uint8Array.allocPlain()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_uint8array_allocplain(duk_hthread *thr) {\n\tduk__hbufobj_fixed_from_argvalue(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Uint8Array.plainOf()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_uint8array_plainof(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\t/* Avoid churn if argument is already a plain buffer. */\n\tif (duk_is_buffer(thr, 0)) {\n\t\treturn 1;\n\t}\n#endif\n\n\t/* Promotes plain buffers to ArrayBuffers, so for a plain buffer\n\t * argument we'll create a pointless temporary (but still work\n\t * correctly).\n\t */\n\th_bufobj = duk__require_bufobj_value(thr, 0);\n\tif (h_bufobj->buf == NULL) {\n\t\tduk_push_undefined(thr);\n\t} else {\n\t\tduk_push_hbuffer(thr, h_bufobj->buf);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer: toString([encoding], [start], [end])\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_int_t start_offset, end_offset;\n\tduk_uint8_t *buf_slice;\n\tduk_size_t slice_length;\n\n\th_this = duk__get_bufobj_this(thr);\n\tif (h_this == NULL) {\n\t\t/* XXX: happens e.g. when evaluating: String(Buffer.prototype). */\n\t\tduk_push_literal(thr, \"[object Object]\");\n\t\treturn 1;\n\t}\n\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\n\t/* Ignore encoding for now. */\n\n\tduk__clamp_startend_nonegidx_noshift(thr,\n\t                                     (duk_int_t) h_this->length,\n\t                                     1 /*idx_start*/,\n\t                                     2 /*idx_end*/,\n\t                                     &start_offset,\n\t                                     &end_offset);\n\n\tslice_length = (duk_size_t) (end_offset - start_offset);\n\tbuf_slice = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, slice_length);  /* all bytes initialized below */\n\tDUK_ASSERT(buf_slice != NULL);\n\n\t/* Neutered or uncovered, TypeError. */\n\tif (h_this->buf == NULL ||\n\t    !DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, (duk_size_t) start_offset + slice_length)) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* XXX: ideally we wouldn't make a copy but a view into the buffer for the\n\t * decoding process.  Or the decoding helper could be changed to accept\n\t * the slice info (a buffer pointer is NOT a good approach because guaranteeing\n\t * its stability is difficult).\n\t */\n\n\tDUK_ASSERT(DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, (duk_size_t) start_offset + slice_length));\n\tduk_memcpy_unsafe((void *) buf_slice,\n\t                  (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + start_offset),\n\t                  (size_t) slice_length);\n\n\t/* Use the equivalent of: new TextEncoder().encode(this) to convert the\n\t * string.  Result will be valid UTF-8; non-CESU-8 inputs are currently\n\t * interpreted loosely.  Value stack convention is a bit odd for now.\n\t */\n\tduk_replace(thr, 0);\n\tduk_set_top(thr, 1);\n\treturn duk_textdecoder_decode_utf8_nodejs(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype: toJSON()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_uint8_t *buf;\n\tduk_uint_t i, n;\n\tduk_tval *tv;\n\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\n\tif (h_this->buf == NULL || !DUK_HBUFOBJ_VALID_SLICE(h_this)) {\n\t\t/* Serialize uncovered backing buffer as a null; doesn't\n\t\t * really matter as long we're memory safe.\n\t\t */\n\t\tduk_push_null(thr);\n\t\treturn 1;\n\t}\n\n\tduk_push_object(thr);\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_UC_BUFFER);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_TYPE);\n\n\t/* XXX: uninitialized would be OK */\n\tDUK_ASSERT_DISABLE((duk_size_t) h_this->length <= (duk_size_t) DUK_UINT32_MAX);\n\ttv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) h_this->length);  /* XXX: needs revision with >4G buffers */\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\tDUK_ASSERT(h_this->buf != NULL);\n\tbuf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this);\n\tfor (i = 0, n = h_this->length; i < n; i++) {\n\t\tDUK_TVAL_SET_U32(tv + i, (duk_uint32_t) buf[i]);  /* no need for decref or incref */\n\t}\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_DATA);\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.equals()\n *  Node.js Buffer.prototype.compare()\n *  Node.js Buffer.compare()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_buffer_compare_shared(duk_hthread *thr) {\n\tduk_small_uint_t magic;\n\tduk_hbufobj *h_bufarg1;\n\tduk_hbufobj *h_bufarg2;\n\tduk_small_int_t comp_res;\n\n\t/* XXX: keep support for plain buffers and non-Node.js buffers? */\n\n\tmagic = (duk_small_uint_t) duk_get_current_magic(thr);\n\tif (magic & 0x02U) {\n\t\t/* Static call style. */\n\t\th_bufarg1 = duk__require_bufobj_value(thr, 0);\n\t\th_bufarg2 = duk__require_bufobj_value(thr, 1);\n\t} else {\n\t\th_bufarg1 = duk__require_bufobj_this(thr);\n\t\th_bufarg2 = duk__require_bufobj_value(thr, 0);\n\t}\n\tDUK_ASSERT(h_bufarg1 != NULL);\n\tDUK_ASSERT(h_bufarg2 != NULL);\n\n\t/* We want to compare the slice/view areas of the arguments.\n\t * If either slice/view is invalid (underlying buffer is shorter)\n\t * ensure equals() is false, but otherwise the only thing that\n\t * matters is to be memory safe.\n\t */\n\n\tif (DUK_HBUFOBJ_VALID_SLICE(h_bufarg1) &&\n\t    DUK_HBUFOBJ_VALID_SLICE(h_bufarg2)) {\n\t\tcomp_res = duk_js_data_compare((const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufarg1->buf) + h_bufarg1->offset,\n\t\t                               (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufarg2->buf) + h_bufarg2->offset,\n\t\t                               (duk_size_t) h_bufarg1->length,\n\t\t                               (duk_size_t) h_bufarg2->length);\n\t} else {\n\t\tcomp_res = -1;  /* either nonzero value is ok */\n\t}\n\n\tif (magic & 0x01U) {\n\t\t/* compare: similar to string comparison but for buffer data. */\n\t\tduk_push_int(thr, comp_res);\n\t} else {\n\t\t/* equals */\n\t\tduk_push_boolean(thr, (comp_res == 0));\n\t}\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.fill()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_fill(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tconst duk_uint8_t *fill_str_ptr;\n\tduk_size_t fill_str_len;\n\tduk_uint8_t fill_value;\n\tduk_int_t fill_offset;\n\tduk_int_t fill_end;\n\tduk_size_t fill_length;\n\tduk_uint8_t *p;\n\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\tif (h_this->buf == NULL) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* [ value offset end ] */\n\n\tif (duk_is_string_notsymbol(thr, 0)) {\n\t\tfill_str_ptr = (const duk_uint8_t *) duk_get_lstring(thr, 0, &fill_str_len);\n\t\tDUK_ASSERT(fill_str_ptr != NULL);\n\t} else {\n\t\t/* Symbols get ToNumber() coerced and cause TypeError. */\n\t\tfill_value = (duk_uint8_t) duk_to_uint32(thr, 0);\n\t\tfill_str_ptr = (const duk_uint8_t *) &fill_value;\n\t\tfill_str_len = 1;\n\t}\n\n\t/* Fill offset handling is more lenient than in Node.js. */\n\n\tduk__clamp_startend_nonegidx_noshift(thr,\n\t                                     (duk_int_t) h_this->length,\n\t                                     1 /*idx_start*/,\n\t                                     2 /*idx_end*/,\n\t                                     &fill_offset,\n\t                                     &fill_end);\n\n\tDUK_DDD(DUK_DDDPRINT(\"fill: fill_value=%02x, fill_offset=%ld, fill_end=%ld, view length=%ld\",\n\t                     (unsigned int) fill_value, (long) fill_offset, (long) fill_end, (long) h_this->length));\n\n\tDUK_ASSERT(fill_end - fill_offset >= 0);\n\tDUK_ASSERT(h_this->buf != NULL);\n\n\tp = (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + fill_offset);\n\tfill_length = (duk_size_t) (fill_end - fill_offset);\n\tif (fill_str_len == 1) {\n\t\t/* Handle single character fills as memset() even when\n\t\t * the fill data comes from a one-char argument.\n\t\t */\n\t\tduk_memset_unsafe((void *) p, (int) fill_str_ptr[0], (size_t) fill_length);\n\t} else if (fill_str_len > 1) {\n\t\tduk_size_t i, n, t;\n\n\t\tfor (i = 0, n = (duk_size_t) (fill_end - fill_offset), t = 0; i < n; i++) {\n\t\t\tp[i] = fill_str_ptr[t++];\n\t\t\tif (t >= fill_str_len) {\n\t\t\t\tt = 0;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"zero size fill pattern, ignore silently\"));\n\t}\n\n\t/* Return the Buffer to allow chaining: b.fill(0x11).fill(0x22, 3, 5).toString() */\n\tduk_push_this(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.write(string, [offset], [length], [encoding])\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_write(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_uint_t offset;\n\tduk_uint_t length;\n\tconst duk_uint8_t *str_data;\n\tduk_size_t str_len;\n\n\t/* XXX: very inefficient support for plain buffers */\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\n\t/* Argument must be a string, e.g. a buffer is not allowed. */\n\tstr_data = (const duk_uint8_t *) duk_require_lstring_notsymbol(thr, 0, &str_len);\n\n\tduk__resolve_offset_opt_length(thr, h_this, 1, 2, &offset, &length, 0 /*throw_flag*/);\n\tDUK_ASSERT(offset <= h_this->length);\n\tDUK_ASSERT(offset + length <= h_this->length);\n\n\t/* XXX: encoding is ignored now. */\n\n\tif (length > str_len) {\n\t\tlength = (duk_uint_t) str_len;\n\t}\n\n\tif (DUK_HBUFOBJ_VALID_SLICE(h_this)) {\n\t\t/* Cannot overlap. */\n\t\tduk_memcpy_unsafe((void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + offset),\n\t\t                  (const void *) str_data,\n\t\t                  (size_t) length);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"write() target buffer is not covered, silent ignore\"));\n\t}\n\n\tduk_push_uint(thr, length);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.copy()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_copy(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_hbufobj *h_bufarg;\n\tduk_int_t source_length;\n\tduk_int_t target_length;\n\tduk_int_t target_start, source_start, source_end;\n\tduk_uint_t target_ustart, source_ustart, source_uend;\n\tduk_uint_t copy_size = 0;\n\n\t/* [ targetBuffer targetStart sourceStart sourceEnd ] */\n\n\th_this = duk__require_bufobj_this(thr);\n\th_bufarg = duk__require_bufobj_value(thr, 0);\n\tDUK_ASSERT(h_this != NULL);\n\tDUK_ASSERT(h_bufarg != NULL);\n\tsource_length = (duk_int_t) h_this->length;\n\ttarget_length = (duk_int_t) h_bufarg->length;\n\n\ttarget_start = duk_to_int(thr, 1);\n\tsource_start = duk_to_int(thr, 2);\n\tif (duk_is_undefined(thr, 3)) {\n\t\tsource_end = source_length;\n\t} else {\n\t\tsource_end = duk_to_int(thr, 3);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"checking copy args: target_start=%ld, target_length=%ld, \"\n\t                     \"source_start=%ld, source_end=%ld, source_length=%ld\",\n\t                     (long) target_start, (long) h_bufarg->length,\n\t                     (long) source_start, (long) source_end, (long) source_length));\n\n\t/* This behavior mostly mimics Node.js now. */\n\n\tif (source_start < 0 || source_end < 0 || target_start < 0) {\n\t\t/* Negative offsets cause a RangeError. */\n\t\tgoto fail_bounds;\n\t}\n\tsource_ustart = (duk_uint_t) source_start;\n\tsource_uend = (duk_uint_t) source_end;\n\ttarget_ustart = (duk_uint_t) target_start;\n\tif (source_ustart >= source_uend ||  /* crossed offsets or zero size */\n\t    source_ustart >= (duk_uint_t) source_length ||  /* source out-of-bounds (but positive) */\n\t    target_ustart >= (duk_uint_t) target_length) {  /* target out-of-bounds (but positive) */\n\t\tgoto silent_ignore;\n\t}\n\tif (source_uend >= (duk_uint_t) source_length) {\n\t\t/* Source end clamped silently to available length. */\n\t\tsource_uend = (duk_uint_t) source_length;\n\t}\n\tcopy_size = source_uend - source_ustart;\n\tif (target_ustart + copy_size > (duk_uint_t) target_length) {\n\t\t/* Clamp to target's end if too long.\n\t\t *\n\t\t * NOTE: there's no overflow possibility in the comparison;\n\t\t * both target_ustart and copy_size are >= 0 and based on\n\t\t * values in duk_int_t range.  Adding them as duk_uint_t\n\t\t * values is then guaranteed not to overflow.\n\t\t */\n\t\tDUK_ASSERT(target_ustart + copy_size >= target_ustart);  /* no overflow */\n\t\tDUK_ASSERT(target_ustart + copy_size >= copy_size);  /* no overflow */\n\t\tcopy_size = (duk_uint_t) target_length - target_ustart;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"making copy: target_ustart=%lu source_ustart=%lu copy_size=%lu\",\n\t                     (unsigned long) target_ustart, (unsigned long) source_ustart,\n\t                     (unsigned long) copy_size));\n\n\tDUK_ASSERT(copy_size >= 1);\n\tDUK_ASSERT(source_ustart <= (duk_uint_t) source_length);\n\tDUK_ASSERT(source_ustart + copy_size <= (duk_uint_t) source_length);\n\tDUK_ASSERT(target_ustart <= (duk_uint_t) target_length);\n\tDUK_ASSERT(target_ustart + copy_size <= (duk_uint_t) target_length);\n\n\t/* Ensure copy is covered by underlying buffers. */\n\tDUK_ASSERT(h_bufarg->buf != NULL);  /* length check */\n\tDUK_ASSERT(h_this->buf != NULL);    /* length check */\n\tif (DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufarg, target_ustart + copy_size) &&\n\t    DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, source_ustart + copy_size)) {\n\t\t/* Must use memmove() because copy area may overlap (source and target\n\t\t * buffer may be the same, or from different slices.\n\t\t */\n\t\tduk_memmove_unsafe((void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg) + target_ustart),\n\t\t                   (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + source_ustart),\n\t\t                   (size_t) copy_size);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"buffer copy not covered by underlying buffer(s), ignoring\"));\n\t}\n\n silent_ignore:\n\t/* Return value is like write(), number of bytes written.\n\t * The return value matters because of code like:\n\t * \"off += buf.copy(...)\".\n         */\n\tduk_push_uint(thr, copy_size);\n\treturn 1;\n\n fail_bounds:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  TypedArray.prototype.set()\n *\n *  TypedArray set() is pretty interesting to implement because:\n *\n *    - The source argument may be a plain array or a typedarray.  If the\n *      source is a TypedArray, values are decoded and re-encoded into the\n *      target (not as a plain byte copy).  This may happen even when the\n *      element byte size is the same, e.g. integer values may be re-encoded\n *      into floats.\n *\n *    - Source and target may refer to the same underlying buffer, so that\n *      the set() operation may overlap.  The specification requires that this\n *      must work as if a copy was made before the operation.  Note that this\n *      is NOT a simple memmove() situation because the source and target\n *      byte sizes may be different -- e.g. a 4-byte source (Int8Array) may\n *      expand to a 16-byte target (Uint32Array) so that the target overlaps\n *      the source both from beginning and the end (unlike in typical memmove).\n *\n *    - Even if 'buf' pointers of the source and target differ, there's no\n *      guarantee that their memory areas don't overlap.  This may be the\n *      case with external buffers.\n *\n *  Even so, it is nice to optimize for the common case:\n *\n *    - Source and target separate buffers or non-overlapping.\n *\n *    - Source and target have a compatible type so that a plain byte copy\n *      is possible.  Note that while e.g. uint8 and int8 are compatible\n *      (coercion one way or another doesn't change the byte representation),\n *      e.g. int8 and uint8clamped are NOT compatible when writing int8\n *      values into uint8clamped typedarray (-1 would clamp to 0 for instance).\n *\n *  See test-bi-typedarray-proto-set.js.\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_set(duk_hthread *thr) {\n\tduk_hbufobj *h_this;\n\tduk_hobject *h_obj;\n\tduk_uarridx_t i, n;\n\tduk_int_t offset_signed;\n\tduk_uint_t offset_elems;\n\tduk_uint_t offset_bytes;\n\n\th_this = duk__require_bufobj_this(thr);\n\tDUK_ASSERT(h_this != NULL);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_this);\n\n\tif (h_this->buf == NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"source neutered, skip copy\"));\n\t\treturn 0;\n\t}\n\n\tduk_hbufobj_promote_plain(thr, 0);\n\th_obj = duk_require_hobject(thr, 0);\n\n\t/* XXX: V8 throws a TypeError for negative values.  Would it\n\t * be more useful to interpret negative offsets here from the\n\t * end of the buffer too?\n\t */\n\toffset_signed = duk_to_int(thr, 1);\n\tif (offset_signed < 0) {\n\t\t/* For some reason this is a TypeError (at least in V8). */\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\toffset_elems = (duk_uint_t) offset_signed;\n\toffset_bytes = offset_elems << h_this->shift;\n\tif ((offset_bytes >> h_this->shift) != offset_elems) {\n\t\t/* Byte length would overflow. */\n\t\t/* XXX: easier check with less code? */\n\t\tgoto fail_args;\n\t}\n\tif (offset_bytes > h_this->length) {\n\t\t/* Equality may be OK but >length not.  Checking\n\t\t * this explicitly avoids some overflow cases\n\t\t * below.\n\t\t */\n\t\tgoto fail_args;\n\t}\n\tDUK_ASSERT(offset_bytes <= h_this->length);\n\n\t/* Fast path: source is a TypedArray (or any bufobj). */\n\n\tif (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\tduk_hbufobj *h_bufarg;\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\tduk_uint16_t comp_mask;\n#endif\n\t\tduk_small_int_t no_overlap = 0;\n\t\tduk_uint_t src_length;\n\t\tduk_uint_t dst_length;\n\t\tduk_uint_t dst_length_elems;\n\t\tduk_uint8_t *p_src_base;\n\t\tduk_uint8_t *p_src_end;\n\t\tduk_uint8_t *p_src;\n\t\tduk_uint8_t *p_dst_base;\n\t\tduk_uint8_t *p_dst;\n\t\tduk_small_uint_t src_elem_size;\n\t\tduk_small_uint_t dst_elem_size;\n\n\t\th_bufarg = (duk_hbufobj *) h_obj;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufarg);\n\n\t\tif (h_bufarg->buf == NULL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"target neutered, skip copy\"));\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* Nominal size check. */\n\t\tsrc_length = h_bufarg->length;  /* bytes in source */\n\t\tdst_length_elems = (src_length >> h_bufarg->shift);  /* elems in source and dest */\n\t\tdst_length = dst_length_elems << h_this->shift;  /* bytes in dest */\n\t\tif ((dst_length >> h_this->shift) != dst_length_elems) {\n\t\t\t/* Byte length would overflow. */\n\t\t\t/* XXX: easier check with less code? */\n\t\t\tgoto fail_args;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"nominal size check: src_length=%ld, dst_length=%ld\",\n\t\t                     (long) src_length, (long) dst_length));\n\t\tDUK_ASSERT(offset_bytes <= h_this->length);\n\t\tif (dst_length > h_this->length - offset_bytes) {\n\t\t\t/* Overflow not an issue because subtraction is used on the right\n\t\t\t * side and guaranteed to be >= 0.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copy exceeds target buffer nominal length\"));\n\t\t\tgoto fail_args;\n\t\t}\n\t\tif (!DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_this, offset_bytes + dst_length)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copy not covered by underlying target buffer, ignore\"));\n\t\t\treturn 0;\n\t\t}\n\n\t\tp_src_base = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufarg);\n\t\tp_dst_base = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + offset_bytes;\n\n\t\t/* Check actual underlying buffers for validity and that they\n\t\t * cover the copy.  No side effects are allowed after the check\n\t\t * so that the validity status doesn't change.\n\t\t */\n\t\tif (!DUK_HBUFOBJ_VALID_SLICE(h_this) ||\n\t\t    !DUK_HBUFOBJ_VALID_SLICE(h_bufarg)) {\n\t\t\t/* The condition could be more narrow and check for the\n\t\t\t * copy area only, but there's no need for fine grained\n\t\t\t * behavior when the underlying buffer is misconfigured.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"source and/or target not covered by underlying buffer, skip copy\"));\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* We want to do a straight memory copy if possible: this is\n\t\t * an important operation because .set() is the TypedArray\n\t\t * way to copy chunks of memory.  However, because set()\n\t\t * conceptually works in terms of elements, not all views are\n\t\t * compatible with direct byte copying.\n\t\t *\n\t\t * If we do manage a direct copy, the \"overlap issue\" handled\n\t\t * below can just be solved using memmove() because the source\n\t\t * and destination element sizes are necessarily equal.\n\t\t */\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\tDUK_ASSERT(h_this->elem_type < sizeof(duk__buffer_elemtype_copy_compatible) / sizeof(duk_uint16_t));\n\t\tcomp_mask = duk__buffer_elemtype_copy_compatible[h_this->elem_type];\n\t\tif (comp_mask & (1 << h_bufarg->elem_type)) {\n\t\t\tDUK_ASSERT(src_length == dst_length);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path: able to use memmove() because views are compatible\"));\n\t\t\tduk_memmove_unsafe((void *) p_dst_base, (const void *) p_src_base, (size_t) dst_length);\n\t\t\treturn 0;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"fast path: views are not compatible with a byte copy, copy by item\"));\n#endif  /* !DUK_USE_PREFER_SIZE */\n\n\t\t/* We want to avoid making a copy to process set() but that's\n\t\t * not always possible: the source and the target may overlap\n\t\t * and because element sizes are different, the overlap cannot\n\t\t * always be handled with a memmove() or choosing the copy\n\t\t * direction in a certain way.  For example, if source type is\n\t\t * uint8 and target type is uint32, the target area may exceed\n\t\t * the source area from both ends!\n\t\t *\n\t\t * Note that because external buffers may point to the same\n\t\t * memory areas, we must ultimately make this check using\n\t\t * pointers.\n\t\t *\n\t\t * NOTE: careful with side effects: any side effect may cause\n\t\t * a buffer resize (or external buffer pointer/length update)!\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"overlap check: p_src_base=%p, src_length=%ld, \"\n\t\t                     \"p_dst_base=%p, dst_length=%ld\",\n\t\t                     (void *) p_src_base, (long) src_length,\n\t\t                     (void *) p_dst_base, (long) dst_length));\n\n\t\tif (p_src_base >= p_dst_base + dst_length ||  /* source starts after dest ends */\n\t\t    p_src_base + src_length <= p_dst_base) {   /* source ends before dest starts */\n\t\t\tno_overlap = 1;\n\t\t}\n\n\t\tif (!no_overlap) {\n\t\t\t/* There's overlap: the desired end result is that\n\t\t\t * conceptually a copy is made to avoid \"trampling\"\n\t\t\t * of source data by destination writes.  We make\n\t\t\t * an actual temporary copy to handle this case.\n\t\t\t */\n\t\t\tduk_uint8_t *p_src_copy;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"there is overlap, make a copy of the source\"));\n\t\t\tp_src_copy = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, src_length);\n\t\t\tDUK_ASSERT(p_src_copy != NULL);\n\t\t\tduk_memcpy_unsafe((void *) p_src_copy, (const void *) p_src_base, (size_t) src_length);\n\n\t\t\tp_src_base = p_src_copy;  /* use p_src_base from now on */\n\t\t}\n\t\t/* Value stack intentionally mixed size here. */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"after overlap check: p_src_base=%p, src_length=%ld, \"\n\t\t                     \"p_dst_base=%p, dst_length=%ld, valstack top=%ld\",\n\t\t                     (void *) p_src_base, (long) src_length,\n\t\t                     (void *) p_dst_base, (long) dst_length,\n\t\t                     (long) duk_get_top(thr)));\n\n\t\t/* Ready to make the copy.  We must proceed element by element\n\t\t * and must avoid any side effects that might cause the buffer\n\t\t * validity check above to become invalid.\n\t\t *\n\t\t * Although we work through the value stack here, only plain\n\t\t * numbers are handled which should be side effect safe.\n\t\t */\n\n\t\tsrc_elem_size = (duk_small_uint_t) (1U << h_bufarg->shift);\n\t\tdst_elem_size = (duk_small_uint_t) (1U << h_this->shift);\n\t\tp_src = p_src_base;\n\t\tp_dst = p_dst_base;\n\t\tp_src_end = p_src_base + src_length;\n\n\t\twhile (p_src != p_src_end) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fast path per element copy loop: \"\n\t\t\t                     \"p_src=%p, p_src_end=%p, p_dst=%p\",\n\t\t\t                     (void *) p_src, (void *) p_src_end, (void *) p_dst));\n\t\t\t/* A validated read() is always a number, so it's write coercion\n\t\t\t * is always side effect free an won't invalidate pointers etc.\n\t\t\t */\n\t\t\tduk_hbufobj_push_validated_read(thr, h_bufarg, p_src, src_elem_size);\n\t\t\tduk_hbufobj_validated_write(thr, h_this, p_dst, dst_elem_size);\n\t\t\tduk_pop(thr);\n\t\t\tp_src += src_elem_size;\n\t\t\tp_dst += dst_elem_size;\n\t\t}\n\n\t\treturn 0;\n\t} else {\n\t\t/* Slow path: quite slow, but we save space by using the property code\n\t\t * to write coerce target values.  We don't need to worry about overlap\n\t\t * here because the source is not a TypedArray.\n\t\t *\n\t\t * We could use the bufobj write coercion helper but since the\n\t\t * property read may have arbitrary side effects, full validity checks\n\t\t * would be needed for every element anyway.\n\t\t */\n\n\t\tn = (duk_uarridx_t) duk_get_length(thr, 0);\n\t\tDUK_ASSERT(offset_bytes <= h_this->length);\n\t\tif ((n << h_this->shift) > h_this->length - offset_bytes) {\n\t\t\t/* Overflow not an issue because subtraction is used on the right\n\t\t\t * side and guaranteed to be >= 0.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copy exceeds target buffer nominal length\"));\n\t\t\tgoto fail_args;\n\t\t}\n\n\t\t/* There's no need to check for buffer validity status for the\n\t\t * target here: the property access code will do that for each\n\t\t * element.  Moreover, if we did check the validity here, side\n\t\t * effects from reading the source argument might invalidate\n\t\t * the results anyway.\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t\tduk_push_this(thr);\n\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk_get_prop_index(thr, 0, i);\n\t\t\tduk_put_prop_index(thr, 2, offset_elems + i);\n\t\t}\n\t}\n\n\treturn 0;\n\n fail_args:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.prototype.slice([start], [end])\n *  ArrayBuffer.prototype.slice(begin, [end])\n *  TypedArray.prototype.subarray(begin, [end])\n *\n *  The API calls are almost identical; negative indices are counted from end\n *  of buffer, and final indices are clamped (allowing crossed indices).  Main\n *  differences:\n *\n *    - Copy/view behavior; Node.js .slice() and TypedArray .subarray() create\n *      views, ArrayBuffer .slice() creates a copy\n *\n *    - Resulting object has a different class and prototype depending on the\n *      call (or 'this' argument)\n *\n *    - TypedArray .subarray() arguments are element indices, not byte offsets\n *\n *    - Plain buffer argument creates a plain buffer slice\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL void duk__arraybuffer_plain_slice(duk_hthread *thr, duk_hbuffer *h_val) {\n\tduk_int_t start_offset, end_offset;\n\tduk_uint_t slice_length;\n\tduk_uint8_t *p_copy;\n\tduk_size_t copy_length;\n\n\tduk__clamp_startend_negidx_shifted(thr,\n\t                                   (duk_int_t) DUK_HBUFFER_GET_SIZE(h_val),\n\t                                   0 /*buffer_shift*/,\n\t                                   0 /*idx_start*/,\n\t                                   1 /*idx_end*/,\n\t                                   &start_offset,\n\t                                   &end_offset);\n\tDUK_ASSERT(end_offset <= (duk_int_t) DUK_HBUFFER_GET_SIZE(h_val));\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(end_offset >= start_offset);\n\tslice_length = (duk_uint_t) (end_offset - start_offset);\n\n\tp_copy = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, (duk_size_t) slice_length);\n\tDUK_ASSERT(p_copy != NULL);\n\tcopy_length = slice_length;\n\n\tduk_memcpy_unsafe((void *) p_copy,\n\t                  (const void *) ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_val) + start_offset),\n\t                  copy_length);\n}\n#endif /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Shared helper for slice/subarray operation.\n * Magic: 0x01=isView, 0x02=copy, 0x04=Node.js Buffer special handling.\n */\nDUK_INTERNAL duk_ret_t duk_bi_buffer_slice_shared(duk_hthread *thr) {\n\tduk_small_int_t magic;\n\tduk_small_uint_t res_class_num;\n\tduk_small_int_t res_proto_bidx;\n\tduk_hbufobj *h_this;\n\tduk_hbufobj *h_bufobj;\n\tduk_hbuffer *h_val;\n\tduk_int_t start_offset, end_offset;\n\tduk_uint_t slice_length;\n\tduk_tval *tv;\n\n\t/* [ start end ] */\n\n\tmagic = duk_get_current_magic(thr);\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_BUFFER(tv)) {\n\t\t/* For plain buffers return a plain buffer slice. */\n\t\th_val = DUK_TVAL_GET_BUFFER(tv);\n\t\tDUK_ASSERT(h_val != NULL);\n\n\t\tif (magic & 0x02) {\n\t\t\t/* Make copy: ArrayBuffer.prototype.slice() uses this. */\n\t\t\tduk__arraybuffer_plain_slice(thr, h_val);\n\t\t\treturn 1;\n\t\t} else {\n\t\t\t/* View into existing buffer: cannot be done if the\n\t\t\t * result is a plain buffer because there's no slice\n\t\t\t * info.  So return an ArrayBuffer instance; coerce\n\t\t\t * the 'this' binding into an object and behave as if\n\t\t\t * the original call was for an Object-coerced plain\n\t\t\t * buffer (handled automatically by duk__require_bufobj_this()).\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slice() doesn't handle view into plain buffer, coerce 'this' to ArrayBuffer object\"));\n\t\t\t/* fall through */\n\t\t}\n\t}\n\ttv = NULL;  /* No longer valid nor needed. */\n\n\th_this = duk__require_bufobj_this(thr);\n\n\t/* Slice offsets are element (not byte) offsets, which only matters\n\t * for TypedArray views, Node.js Buffer and ArrayBuffer have shift\n\t * zero so byte and element offsets are the same.  Negative indices\n\t * are counted from end of slice, crossed indices are allowed (and\n\t * result in zero length result), and final values are clamped\n\t * against the current slice.  There's intentionally no check\n\t * against the underlying buffer here.\n\t */\n\n\tduk__clamp_startend_negidx_shifted(thr,\n\t                                   (duk_int_t) h_this->length,\n\t                                   (duk_uint8_t) h_this->shift,\n\t                                   0 /*idx_start*/,\n\t                                   1 /*idx_end*/,\n\t                                   &start_offset,\n\t                                   &end_offset);\n\tDUK_ASSERT(end_offset >= start_offset);\n\tDUK_ASSERT(start_offset >= 0);\n\tDUK_ASSERT(end_offset >= 0);\n\tslice_length = (duk_uint_t) (end_offset - start_offset);\n\n\t/* The resulting buffer object gets the same class and prototype as\n\t * the buffer in 'this', e.g. if the input is a Uint8Array the\n\t * result is a Uint8Array; if the input is a Float32Array, the\n\t * result is a Float32Array.  The result internal prototype should\n\t * be the default prototype for the class (e.g. initial value of\n\t * Uint8Array.prototype), not copied from the argument (Duktape 1.x\n\t * did that).\n\t *\n\t * Node.js Buffers have special handling: they're Uint8Arrays as far\n\t * as the internal class is concerned, so the new Buffer should also\n\t * be an Uint8Array but inherit from Buffer.prototype.\n\t */\n\tres_class_num = DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *) h_this);\n\tDUK_ASSERT(res_class_num >= DUK_HOBJECT_CLASS_BUFOBJ_MIN);  /* type check guarantees */\n\tDUK_ASSERT(res_class_num <= DUK_HOBJECT_CLASS_BUFOBJ_MAX);\n\tres_proto_bidx = duk__buffer_proto_from_classnum[res_class_num - DUK_HOBJECT_CLASS_BUFOBJ_MIN];\n\tif (magic & 0x04) {\n\t\tres_proto_bidx = DUK_BIDX_NODEJS_BUFFER_PROTOTYPE;\n\t}\n\th_bufobj = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(res_class_num),\n\t                               res_proto_bidx);\n\tDUK_ASSERT(h_bufobj != NULL);\n\n\tDUK_ASSERT(h_bufobj->length == 0);\n\th_bufobj->shift = h_this->shift;  /* inherit */\n\th_bufobj->elem_type = h_this->elem_type;  /* inherit */\n\th_bufobj->is_typedarray = magic & 0x01;\n\tDUK_ASSERT(h_bufobj->is_typedarray == 0 || h_bufobj->is_typedarray == 1);\n\n\th_val = h_this->buf;\n\tif (h_val == NULL) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tif (magic & 0x02) {\n\t\t/* non-zero: make copy */\n\t\tduk_uint8_t *p_copy;\n\t\tduk_size_t copy_length;\n\n\t\tp_copy = (duk_uint8_t *) duk_push_fixed_buffer_zero(thr, (duk_size_t) slice_length);  /* must be zeroed, not all bytes always copied */\n\t\tDUK_ASSERT(p_copy != NULL);\n\n\t\t/* Copy slice, respecting underlying buffer limits; remainder\n\t\t * is left as zero.\n\t\t */\n\t\tcopy_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, slice_length);\n\t\tduk_memcpy_unsafe((void *) p_copy,\n\t\t                  (const void *) (DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this) + start_offset),\n\t\t                  copy_length);\n\n\t\th_val = duk_known_hbuffer(thr, -1);\n\n\t\th_bufobj->buf = h_val;\n\t\tDUK_HBUFFER_INCREF(thr, h_val);\n\t\th_bufobj->length = slice_length;\n\t\tDUK_ASSERT(h_bufobj->offset == 0);\n\n\t\tduk_pop(thr);  /* reachable so pop OK */\n\t} else {\n\t\th_bufobj->buf = h_val;\n\t\tDUK_HBUFFER_INCREF(thr, h_val);\n\t\th_bufobj->length = slice_length;\n\t\th_bufobj->offset = h_this->offset + (duk_uint_t) start_offset;\n\n\t\t/* Copy the .buffer property, needed for TypedArray.prototype.subarray().\n\t\t *\n\t\t * XXX: limit copy only for TypedArray classes specifically?\n\t\t */\n\n\t\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\t\th_bufobj->buf_prop = h_this->buf_prop;  /* may be NULL */\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, (duk_hobject *) h_bufobj->buf_prop);\n\t}\n\t/* unbalanced stack on purpose */\n\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.isEncoding()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_encoding(duk_hthread *thr) {\n\tconst char *encoding;\n\n\t/* only accept lowercase 'utf8' now. */\n\n\tencoding = duk_to_string(thr, 0);\n\tDUK_ASSERT(duk_is_string(thr, 0));  /* guaranteed by duk_to_string() */\n\tduk_push_boolean(thr, DUK_STRCMP(encoding, \"utf8\") == 0);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.isBuffer()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_hthread *thr) {\n\tduk_hobject *h;\n\tduk_hobject *h_proto;\n\tduk_bool_t ret = 0;\n\n\tDUK_ASSERT(duk_get_top(thr) >= 1);  /* nargs */\n\th = duk_get_hobject(thr, 0);\n\tif (h != NULL) {\n\t\th_proto = thr->builtins[DUK_BIDX_NODEJS_BUFFER_PROTOTYPE];\n\t\tDUK_ASSERT(h_proto != NULL);\n\n\t\th = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t\tif (h != NULL) {\n\t\t\tret = duk_hobject_prototype_chain_contains(thr, h, h_proto, 0 /*ignore_loop*/);\n\t\t}\n\t}\n\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.byteLength()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_byte_length(duk_hthread *thr) {\n\tconst char *str;\n\tduk_size_t len;\n\n\t/* At the moment Buffer(<str>) will just use the string bytes as\n\t * is (ignoring encoding), so we return the string length here\n\t * unconditionally.\n\t */\n\n\t/* XXX: to be revised; Old Node.js behavior just coerces any buffer\n\t * values to string:\n\t * $ node\n\t * > Buffer.byteLength(new Uint32Array(10))\n\t * 20\n\t * > Buffer.byteLength(new Uint32Array(100))\n\t * 20\n\t * (The 20 comes from '[object Uint32Array]'.length\n\t */\n\n\tstr = duk_to_lstring(thr, 0, &len);\n\tDUK_UNREF(str);\n\tduk_push_size_t(thr, len);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Node.js Buffer.concat()\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_nodejs_buffer_concat(duk_hthread *thr) {\n\tduk_hobject *h_arg;\n\tduk_uint_t total_length;\n\tduk_hbufobj *h_bufobj;\n\tduk_hbufobj *h_bufres;\n\tduk_hbuffer *h_val;\n\tduk_uint_t i, n;\n\tduk_uint8_t *p;\n\tduk_size_t space_left;\n\tduk_size_t copy_size;\n\n\t/* Node.js accepts only actual Arrays. */\n\th_arg = duk_require_hobject(thr, 0);\n\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h_arg) != DUK_HOBJECT_CLASS_ARRAY) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* Compute result length and validate argument buffers. */\n\tn = (duk_uint_t) duk_get_length(thr, 0);\n\ttotal_length = 0;\n\tfor (i = 0; i < n; i++) {\n\t\t/* Neutered checks not necessary here: neutered buffers have\n\t\t * zero 'length' so we'll effectively skip them.\n\t\t */\n\t\tDUK_ASSERT_TOP(thr, 2);  /* [ array totalLength ] */\n\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);  /* -> [ array totalLength buf ] */\n\t\th_bufobj = duk__require_bufobj_value(thr, 2);\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\t\ttotal_length += h_bufobj->length;\n\t\tif (DUK_UNLIKELY(total_length < h_bufobj->length)) {\n\t\t\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);  /* Wrapped. */\n\t\t}\n\t\tduk_pop(thr);\n\t}\n\t/* In Node.js v0.12.1 a 1-element array is special and won't create a\n\t * copy, this was fixed later so an explicit check no longer needed.\n\t */\n\n\t/* User totalLength overrides a computed length, but we'll check\n\t * every copy in the copy loop.  Note that duk_to_int() can\n\t * technically have arbitrary side effects so we need to recheck\n\t * the buffers in the copy loop.\n\t */\n\tif (!duk_is_undefined(thr, 1) && n > 0) {\n\t\t/* For n == 0, Node.js ignores totalLength argument and\n\t\t * returns a zero length buffer.\n\t\t */\n\t\tduk_int_t total_length_signed;\n\t\ttotal_length_signed = duk_to_int(thr, 1);\n\t\tif (total_length_signed < 0) {\n\t\t\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n\t\t}\n\t\ttotal_length = (duk_uint_t) total_length_signed;\n\t}\n\n\th_bufres = duk_push_bufobj_raw(thr,\n\t                               DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                               DUK_HOBJECT_FLAG_BUFOBJ |\n\t                               DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_UINT8ARRAY),\n\t                               DUK_BIDX_NODEJS_BUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_bufres != NULL);\n\n\tp = (duk_uint8_t *) duk_push_fixed_buffer_zero(thr, total_length);  /* must be zeroed, all bytes not necessarily written over */\n\tDUK_ASSERT(p != NULL);\n\tspace_left = (duk_size_t) total_length;\n\n\tfor (i = 0; i < n; i++) {\n\t\tDUK_ASSERT_TOP(thr, 4);  /* [ array totalLength bufres buf ] */\n\n\t\tduk_get_prop_index(thr, 0, (duk_uarridx_t) i);\n\t\th_bufobj = duk__require_bufobj_value(thr, 4);\n\t\tDUK_ASSERT(h_bufobj != NULL);\n\n\t\tcopy_size = h_bufobj->length;\n\t\tif (copy_size > space_left) {\n\t\t\tcopy_size = space_left;\n\t\t}\n\n\t\tif (h_bufobj->buf != NULL &&\n\t\t    DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {\n\t\t\tduk_memcpy_unsafe((void *) p,\n\t\t\t                  (const void *) DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_bufobj),\n\t\t\t                  copy_size);\n\t\t} else {\n\t\t\t/* Just skip, leaving zeroes in the result. */\n\t\t\t;\n\t\t}\n\t\tp += copy_size;\n\t\tspace_left -= copy_size;\n\n\t\tduk_pop(thr);\n\t}\n\n\th_val = duk_known_hbuffer(thr, -1);\n\n\tduk__set_bufobj_buffer(thr, h_bufres, h_val);\n\th_bufres->is_typedarray = 1;\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufres);\n\n\tduk_pop(thr);  /* pop plain buffer, now reachable through h_bufres */\n\n\treturn 1;  /* return h_bufres */\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Shared readfield and writefield methods\n *\n *  The readfield/writefield methods need support for endianness and field\n *  types.  All offsets are byte based so no offset shifting is needed.\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* Format of magic, bits:\n *   0...1: field type; 0=uint8, 1=uint16, 2=uint32, 3=float, 4=double, 5=unused, 6=unused, 7=unused\n *       3: endianness: 0=little, 1=big\n *       4: signed: 1=yes, 0=no\n *       5: typedarray: 1=yes, 0=no\n */\n#define  DUK__FLD_8BIT         0\n#define  DUK__FLD_16BIT        1\n#define  DUK__FLD_32BIT        2\n#define  DUK__FLD_FLOAT        3\n#define  DUK__FLD_DOUBLE       4\n#define  DUK__FLD_VARINT       5\n#define  DUK__FLD_BIGENDIAN    (1 << 3)\n#define  DUK__FLD_SIGNED       (1 << 4)\n#define  DUK__FLD_TYPEDARRAY   (1 << 5)\n\n/* XXX: split into separate functions for each field type? */\nDUK_INTERNAL duk_ret_t duk_bi_buffer_readfield(duk_hthread *thr) {\n\tduk_small_int_t magic = (duk_small_int_t) duk_get_current_magic(thr);\n\tduk_small_int_t magic_ftype;\n\tduk_small_int_t magic_bigendian;\n\tduk_small_int_t magic_signed;\n\tduk_small_int_t magic_typedarray;\n\tduk_small_int_t endswap;\n\tduk_hbufobj *h_this;\n\tduk_bool_t no_assert;\n\tduk_int_t offset_signed;\n\tduk_uint_t offset;\n\tduk_uint_t buffer_length;\n\tduk_uint_t check_length;\n\tduk_uint8_t *buf;\n\tduk_double_union du;\n\n\tmagic_ftype = magic & 0x0007;\n\tmagic_bigendian = magic & 0x0008;\n\tmagic_signed = magic & 0x0010;\n\tmagic_typedarray = magic & 0x0020;\n\n\th_this = duk__require_bufobj_this(thr);  /* XXX: very inefficient for plain buffers */\n\tDUK_ASSERT(h_this != NULL);\n\tbuffer_length = h_this->length;\n\n\t/* [ offset noAssert                 ], when ftype != DUK__FLD_VARINT */\n\t/* [ offset fieldByteLength noAssert ], when ftype == DUK__FLD_VARINT */\n\t/* [ offset littleEndian             ], when DUK__FLD_TYPEDARRAY (regardless of ftype) */\n\n\t/* Handle TypedArray vs. Node.js Buffer arg differences */\n\tif (magic_typedarray) {\n\t\tno_assert = 0;\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = !duk_to_boolean(thr, 1);  /* 1=little endian */\n#else\n\t\tendswap = duk_to_boolean(thr, 1);  /* 1=little endian */\n#endif\n\t} else {\n\t\tno_assert = duk_to_boolean(thr, (magic_ftype == DUK__FLD_VARINT) ? 2 : 1);\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = magic_bigendian;\n#else\n\t\tendswap = !magic_bigendian;\n#endif\n\t}\n\n\t/* Offset is coerced first to signed integer range and then to unsigned.\n\t * This ensures we can add a small byte length (1-8) to the offset in\n\t * bound checks and not wrap.\n\t */\n\toffset_signed = duk_to_int(thr, 0);\n\toffset = (duk_uint_t) offset_signed;\n\tif (offset_signed < 0) {\n\t\tgoto fail_bounds;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"readfield, buffer_length=%ld, offset=%ld, no_assert=%d, \"\n\t                     \"magic=%04x, magic_fieldtype=%d, magic_bigendian=%d, magic_signed=%d, \"\n\t                     \"endswap=%d\",\n\t                     (long) buffer_length, (long) offset, (int) no_assert,\n\t                     (unsigned int) magic, (int) magic_ftype, (int) (magic_bigendian >> 3),\n\t                     (int) (magic_signed >> 4), (int) endswap));\n\n\t/* Update 'buffer_length' to be the effective, safe limit which\n\t * takes into account the underlying buffer.  This value will be\n\t * potentially invalidated by any side effect.\n\t */\n\tcheck_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, buffer_length);\n\tDUK_DDD(DUK_DDDPRINT(\"buffer_length=%ld, check_length=%ld\",\n\t                     (long) buffer_length, (long) check_length));\n\n\tif (h_this->buf) {\n\t\tbuf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this);\n\t} else {\n\t\t/* Neutered.  We could go into the switch-case safely with\n\t\t * buf == NULL because check_length == 0.  To avoid scanbuild\n\t\t * warnings, fail directly instead.\n\t\t */\n\t\tDUK_ASSERT(check_length == 0);\n\t\tgoto fail_neutered;\n\t}\n\tDUK_ASSERT(buf != NULL);\n\n\tswitch (magic_ftype) {\n\tcase DUK__FLD_8BIT: {\n\t\tduk_uint8_t tmp;\n\t\tif (offset + 1U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\ttmp = buf[offset];\n\t\tif (magic_signed) {\n\t\t\tduk_push_int(thr, (duk_int_t) ((duk_int8_t) tmp));\n\t\t} else {\n\t\t\tduk_push_uint(thr, (duk_uint_t) tmp);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK__FLD_16BIT: {\n\t\tduk_uint16_t tmp;\n\t\tif (offset + 2U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 2);\n\t\ttmp = du.us[0];\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP16(tmp);\n\t\t}\n\t\tif (magic_signed) {\n\t\t\tduk_push_int(thr, (duk_int_t) ((duk_int16_t) tmp));\n\t\t} else {\n\t\t\tduk_push_uint(thr, (duk_uint_t) tmp);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK__FLD_32BIT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 4);\n\t\ttmp = du.ui[0];\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t}\n\t\tif (magic_signed) {\n\t\t\tduk_push_int(thr, (duk_int_t) ((duk_int32_t) tmp));\n\t\t} else {\n\t\t\tduk_push_uint(thr, (duk_uint_t) tmp);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK__FLD_FLOAT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 4);\n\t\tif (endswap) {\n\t\t\ttmp = du.ui[0];\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t\tdu.ui[0] = tmp;\n\t\t}\n\t\tduk_push_number(thr, (duk_double_t) du.f[0]);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_DOUBLE: {\n\t\tif (offset + 8U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tduk_memcpy((void *) du.uc, (const void *) (buf + offset), 8);\n\t\tif (endswap) {\n\t\t\tDUK_DBLUNION_BSWAP64(&du);\n\t\t}\n\t\tduk_push_number(thr, (duk_double_t) du.d);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_VARINT: {\n\t\t/* Node.js Buffer variable width integer field.  We don't really\n\t\t * care about speed here, so aim for shortest algorithm.\n\t\t */\n\t\tduk_int_t field_bytelen;\n\t\tduk_int_t i, i_step, i_end;\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_int64_t tmp;\n\t\tduk_small_uint_t shift_tmp;\n#else\n\t\tduk_double_t tmp;\n\t\tduk_small_int_t highbyte;\n#endif\n\t\tconst duk_uint8_t *p;\n\n\t\tfield_bytelen = duk_get_int(thr, 1);  /* avoid side effects! */\n\t\tif (field_bytelen < 1 || field_bytelen > 6) {\n\t\t\tgoto fail_field_length;\n\t\t}\n\t\tif (offset + (duk_uint_t) field_bytelen > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tp = (const duk_uint8_t *) (buf + offset);\n\n\t\t/* Slow gathering of value using either 64-bit arithmetic\n\t\t * or IEEE doubles if 64-bit types not available.  Handling\n\t\t * of negative numbers is a bit non-obvious in both cases.\n\t\t */\n\n\t\tif (magic_bigendian) {\n\t\t\t/* Gather in big endian */\n\t\t\ti = 0;\n\t\t\ti_step = 1;\n\t\t\ti_end = field_bytelen;  /* one i_step over */\n\t\t} else {\n\t\t\t/* Gather in little endian */\n\t\t\ti = field_bytelen - 1;\n\t\t\ti_step = -1;\n\t\t\ti_end = -1;  /* one i_step over */\n\t\t}\n\n#if defined(DUK_USE_64BIT_OPS)\n\t\ttmp = 0;\n\t\tdo {\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\ttmp = (tmp << 8) + (duk_int64_t) p[i];\n\t\t\ti += i_step;\n\t\t} while (i != i_end);\n\n\t\tif (magic_signed) {\n\t\t\t/* Shift to sign extend.  Left shift must be unsigned\n\t\t\t * to avoid undefined behavior; right shift must be\n\t\t\t * signed to sign extend properly.\n\t\t\t */\n\t\t\tshift_tmp = (duk_small_uint_t) (64U - (duk_small_uint_t) field_bytelen * 8U);\n\t\t\ttmp = (duk_int64_t) ((duk_uint64_t) tmp << shift_tmp) >> shift_tmp;\n\t\t}\n\n\t\tduk_push_i64(thr, tmp);\n#else\n\t\thighbyte = p[i];\n\t\tif (magic_signed && (highbyte & 0x80) != 0) {\n\t\t\t/* 0xff => 255 - 256 = -1; 0x80 => 128 - 256 = -128 */\n\t\t\ttmp = (duk_double_t) (highbyte - 256);\n\t\t} else {\n\t\t\ttmp = (duk_double_t) highbyte;\n\t\t}\n\t\tfor (;;) {\n\t\t\ti += i_step;\n\t\t\tif (i == i_end) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\ttmp = (tmp * 256.0) + (duk_double_t) p[i];\n\t\t}\n\n\t\tduk_push_number(thr, tmp);\n#endif\n\t\tbreak;\n\t}\n\tdefault: {  /* should never happen but default here */\n\t\tgoto fail_bounds;\n\t}\n\t}\n\n\treturn 1;\n\n fail_neutered:\n fail_field_length:\n fail_bounds:\n\tif (no_assert) {\n\t\t/* Node.js return value for noAssert out-of-bounds reads is\n\t\t * usually (but not always) NaN.  Return NaN consistently.\n\t\t */\n\t\tduk_push_nan(thr);\n\t\treturn 1;\n\t}\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n/* XXX: split into separate functions for each field type? */\nDUK_INTERNAL duk_ret_t duk_bi_buffer_writefield(duk_hthread *thr) {\n\tduk_small_int_t magic = (duk_small_int_t) duk_get_current_magic(thr);\n\tduk_small_int_t magic_ftype;\n\tduk_small_int_t magic_bigendian;\n\tduk_small_int_t magic_signed;\n\tduk_small_int_t magic_typedarray;\n\tduk_small_int_t endswap;\n\tduk_hbufobj *h_this;\n\tduk_bool_t no_assert;\n\tduk_int_t offset_signed;\n\tduk_uint_t offset;\n\tduk_uint_t buffer_length;\n\tduk_uint_t check_length;\n\tduk_uint8_t *buf;\n\tduk_double_union du;\n\tduk_int_t nbytes = 0;\n\n\tmagic_ftype = magic & 0x0007;\n\tmagic_bigendian = magic & 0x0008;\n\tmagic_signed = magic & 0x0010;\n\tmagic_typedarray = magic & 0x0020;\n\tDUK_UNREF(magic_signed);\n\n\th_this = duk__require_bufobj_this(thr);  /* XXX: very inefficient for plain buffers */\n\tDUK_ASSERT(h_this != NULL);\n\tbuffer_length = h_this->length;\n\n\t/* [ value  offset noAssert                 ], when ftype != DUK__FLD_VARINT */\n\t/* [ value  offset fieldByteLength noAssert ], when ftype == DUK__FLD_VARINT */\n\t/* [ offset value  littleEndian             ], when DUK__FLD_TYPEDARRAY (regardless of ftype) */\n\n\t/* Handle TypedArray vs. Node.js Buffer arg differences */\n\tif (magic_typedarray) {\n\t\tno_assert = 0;\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = !duk_to_boolean(thr, 2);  /* 1=little endian */\n#else\n\t\tendswap = duk_to_boolean(thr, 2);  /* 1=little endian */\n#endif\n\t\tduk_swap(thr, 0, 1);  /* offset/value order different from Node.js */\n\t} else {\n\t\tno_assert = duk_to_boolean(thr, (magic_ftype == DUK__FLD_VARINT) ? 3 : 2);\n#if defined(DUK_USE_INTEGER_LE)\n\t\tendswap = magic_bigendian;\n#else\n\t\tendswap = !magic_bigendian;\n#endif\n\t}\n\n\t/* Offset is coerced first to signed integer range and then to unsigned.\n\t * This ensures we can add a small byte length (1-8) to the offset in\n\t * bound checks and not wrap.\n\t */\n\toffset_signed = duk_to_int(thr, 1);\n\toffset = (duk_uint_t) offset_signed;\n\n\t/* We need 'nbytes' even for a failed offset; return value must be\n\t * (offset + nbytes) even when write fails due to invalid offset.\n\t */\n\tif (magic_ftype != DUK__FLD_VARINT) {\n\t\tDUK_ASSERT(magic_ftype >= 0 && magic_ftype < (duk_small_int_t) (sizeof(duk__buffer_nbytes_from_fldtype) / sizeof(duk_uint8_t)));\n\t\tnbytes = duk__buffer_nbytes_from_fldtype[magic_ftype];\n\t} else {\n\t\tnbytes = duk_get_int(thr, 2);\n\t\tif (nbytes < 1 || nbytes > 6) {\n\t\t\tgoto fail_field_length;\n\t\t}\n\t}\n\tDUK_ASSERT(nbytes >= 1 && nbytes <= 8);\n\n\t/* Now we can check offset validity. */\n\tif (offset_signed < 0) {\n\t\tgoto fail_bounds;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"writefield, value=%!T, buffer_length=%ld, offset=%ld, no_assert=%d, \"\n\t                     \"magic=%04x, magic_fieldtype=%d, magic_bigendian=%d, magic_signed=%d, \"\n\t                     \"endswap=%d\",\n\t                     duk_get_tval(thr, 0), (long) buffer_length, (long) offset, (int) no_assert,\n\t                     (unsigned int) magic, (int) magic_ftype, (int) (magic_bigendian >> 3),\n\t                     (int) (magic_signed >> 4), (int) endswap));\n\n\t/* Coerce value to a number before computing check_length, so that\n\t * the field type specific coercion below can't have side effects\n\t * that would invalidate check_length.\n\t */\n\tduk_to_number(thr, 0);\n\n\t/* Update 'buffer_length' to be the effective, safe limit which\n\t * takes into account the underlying buffer.  This value will be\n\t * potentially invalidated by any side effect.\n\t */\n\tcheck_length = DUK_HBUFOBJ_CLAMP_BYTELENGTH(h_this, buffer_length);\n\tDUK_DDD(DUK_DDDPRINT(\"buffer_length=%ld, check_length=%ld\",\n\t                     (long) buffer_length, (long) check_length));\n\n\tif (h_this->buf) {\n\t\tbuf = DUK_HBUFOBJ_GET_SLICE_BASE(thr->heap, h_this);\n\t} else {\n\t\t/* Neutered.  We could go into the switch-case safely with\n\t\t * buf == NULL because check_length == 0.  To avoid scanbuild\n\t\t * warnings, fail directly instead.\n\t\t */\n\t\tDUK_ASSERT(check_length == 0);\n\t\tgoto fail_neutered;\n\t}\n\tDUK_ASSERT(buf != NULL);\n\n\tswitch (magic_ftype) {\n\tcase DUK__FLD_8BIT: {\n\t\tif (offset + 1U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\t/* sign doesn't matter when writing */\n\t\tbuf[offset] = (duk_uint8_t) duk_to_uint32(thr, 0);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_16BIT: {\n\t\tduk_uint16_t tmp;\n\t\tif (offset + 2U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\ttmp = (duk_uint16_t) duk_to_uint32(thr, 0);\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP16(tmp);\n\t\t}\n\t\tdu.us[0] = tmp;\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 2);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_32BIT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\ttmp = (duk_uint32_t) duk_to_uint32(thr, 0);\n\t\tif (endswap) {\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t}\n\t\tdu.ui[0] = tmp;\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 4);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_FLOAT: {\n\t\tduk_uint32_t tmp;\n\t\tif (offset + 4U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tdu.f[0] = (duk_float_t) duk_to_number(thr, 0);\n\t\tif (endswap) {\n\t\t\ttmp = du.ui[0];\n\t\t\ttmp = DUK_BSWAP32(tmp);\n\t\t\tdu.ui[0] = tmp;\n\t\t}\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 4);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_DOUBLE: {\n\t\tif (offset + 8U > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\t\tdu.d = (duk_double_t) duk_to_number(thr, 0);\n\t\tif (endswap) {\n\t\t\tDUK_DBLUNION_BSWAP64(&du);\n\t\t}\n\t\t/* sign doesn't matter when writing */\n\t\tduk_memcpy((void *) (buf + offset), (const void *) du.uc, 8);\n\t\tbreak;\n\t}\n\tcase DUK__FLD_VARINT: {\n\t\t/* Node.js Buffer variable width integer field.  We don't really\n\t\t * care about speed here, so aim for shortest algorithm.\n\t\t */\n\t\tduk_int_t field_bytelen;\n\t\tduk_int_t i, i_step, i_end;\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_int64_t tmp;\n#else\n\t\tduk_double_t tmp;\n#endif\n\t\tduk_uint8_t *p;\n\n\t\tfield_bytelen = (duk_int_t) nbytes;\n\t\tif (offset + (duk_uint_t) field_bytelen > check_length) {\n\t\t\tgoto fail_bounds;\n\t\t}\n\n\t\t/* Slow writing of value using either 64-bit arithmetic\n\t\t * or IEEE doubles if 64-bit types not available.  There's\n\t\t * no special sign handling when writing varints.\n\t\t */\n\n\t\tif (magic_bigendian) {\n\t\t\t/* Write in big endian */\n\t\t\ti = field_bytelen;  /* one i_step added at top of loop */\n\t\t\ti_step = -1;\n\t\t\ti_end = 0;\n\t\t} else {\n\t\t\t/* Write in little endian */\n\t\t\ti = -1;  /* one i_step added at top of loop */\n\t\t\ti_step = 1;\n\t\t\ti_end = field_bytelen - 1;\n\t\t}\n\n\t\t/* XXX: The duk_to_number() cast followed by integer coercion\n\t\t * is platform specific so NaN, +/- Infinity, and out-of-bounds\n\t\t * values result in platform specific output now.\n\t\t * See: test-bi-nodejs-buffer-proto-varint-special.js\n\t\t */\n\n#if defined(DUK_USE_64BIT_OPS)\n\t\ttmp = (duk_int64_t) duk_to_number(thr, 0);\n\t\tp = (duk_uint8_t *) (buf + offset);\n\t\tdo {\n\t\t\ti += i_step;\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\tp[i] = (duk_uint8_t) (tmp & 0xff);\n\t\t\ttmp = tmp >> 8;  /* unnecessary shift for last byte */\n\t\t} while (i != i_end);\n#else\n\t\ttmp = duk_to_number(thr, 0);\n\t\tp = (duk_uint8_t *) (buf + offset);\n\t\tdo {\n\t\t\ti += i_step;\n\t\t\ttmp = DUK_FLOOR(tmp);\n\t\t\tDUK_ASSERT(i >= 0 && i < field_bytelen);\n\t\t\tp[i] = (duk_uint8_t) (DUK_FMOD(tmp, 256.0));\n\t\t\ttmp = tmp / 256.0;  /* unnecessary div for last byte */\n\t\t} while (i != i_end);\n#endif\n\t\tbreak;\n\t}\n\tdefault: {  /* should never happen but default here */\n\t\tgoto fail_bounds;\n\t}\n\t}\n\n\t/* Node.js Buffer: return offset + #bytes written (i.e. next\n\t * write offset).\n\t */\n\tif (magic_typedarray) {\n\t\t/* For TypedArrays 'undefined' return value is specified\n\t\t * by ES2015 (matches V8).\n\t\t */\n\t\treturn 0;\n\t}\n\tduk_push_uint(thr, offset + (duk_uint_t) nbytes);\n\treturn 1;\n\n fail_neutered:\n fail_field_length:\n fail_bounds:\n\tif (no_assert) {\n\t\t/* Node.js return value for failed writes is offset + #bytes\n\t\t * that would have been written.\n\t\t */\n\t\t/* XXX: for negative input offsets, 'offset' will be a large\n\t\t * positive value so the result here is confusing.\n\t\t */\n\t\tif (magic_typedarray) {\n\t\t\treturn 0;\n\t\t}\n\t\tduk_push_uint(thr, offset + (duk_uint_t) nbytes);\n\t\treturn 1;\n\t}\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  Accessors for .buffer, .byteLength, .byteOffset\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL duk_hbufobj *duk__autospawn_arraybuffer(duk_hthread *thr, duk_hbuffer *h_buf) {\n\tduk_hbufobj *h_res;\n\n\th_res = duk_push_bufobj_raw(thr,\n\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                            DUK_HOBJECT_FLAG_BUFOBJ |\n\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARRAYBUFFER),\n\t                            DUK_BIDX_ARRAYBUFFER_PROTOTYPE);\n\tDUK_ASSERT(h_res != NULL);\n\tDUK_UNREF(h_res);\n\n\tduk__set_bufobj_buffer(thr, h_res, h_buf);\n\tDUK_HBUFOBJ_ASSERT_VALID(h_res);\n\tDUK_ASSERT(h_res->buf_prop == NULL);\n\treturn h_res;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n\th_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW /*flags*/);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tif (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *) h_bufobj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"autospawn ArrayBuffer for plain buffer\"));\n\t\t(void) duk__autospawn_arraybuffer(thr, (duk_hbuffer *) h_bufobj);\n\t\treturn 1;\n\t} else {\n\t\tif (h_bufobj->buf_prop == NULL &&\n\t\t    DUK_HOBJECT_GET_CLASS_NUMBER((duk_hobject *) h_bufobj) != DUK_HOBJECT_CLASS_ARRAYBUFFER &&\n\t\t    h_bufobj->buf != NULL) {\n\t\t\tduk_hbufobj *h_arrbuf;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"autospawn ArrayBuffer for typed array or DataView\"));\n\t\t\th_arrbuf = duk__autospawn_arraybuffer(thr, h_bufobj->buf);\n\n\t\t\tif (h_bufobj->buf_prop == NULL) {\n\t\t\t\t/* Must recheck buf_prop, in case ArrayBuffer\n\t\t\t\t * alloc had a side effect which already filled\n\t\t\t\t * it!\n\t\t\t\t */\n\n\t\t\t\t/* Set ArrayBuffer's .byteOffset and .byteLength based\n\t\t\t\t * on the view so that Arraybuffer[view.byteOffset]\n\t\t\t\t * matches view[0].\n\t\t\t\t */\n\t\t\t\th_arrbuf->offset = 0;\n\t\t\t\tDUK_ASSERT(h_bufobj->offset + h_bufobj->length >= h_bufobj->offset);  /* Wrap check on creation. */\n\t\t\t\th_arrbuf->length = h_bufobj->offset + h_bufobj->length;\n\t\t\t\tDUK_ASSERT(h_arrbuf->buf_prop == NULL);\n\n\t\t\t\tDUK_ASSERT(h_bufobj->buf_prop == NULL);\n\t\t\t\th_bufobj->buf_prop = (duk_hobject *) h_arrbuf;\n\t\t\t\tDUK_HBUFOBJ_INCREF(thr, h_arrbuf);  /* Now reachable and accounted for. */\n\t\t\t}\n\n\t\t\t/* Left on stack; pushed for the second time below (OK). */\n\t\t}\n\t\tif (h_bufobj->buf_prop) {\n\t\t\tduk_push_hobject(thr, h_bufobj->buf_prop);\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n\th_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW /*flags*/);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tif (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *) h_bufobj)) {\n\t\tduk_push_uint(thr, 0);\n\t} else {\n\t\t/* If neutered must return 0; offset is zeroed during\n\t\t * neutering.\n\t\t */\n\t\tduk_push_uint(thr, h_bufobj->offset);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_hthread *thr) {\n\tduk_hbufobj *h_bufobj;\n\n\th_bufobj = (duk_hbufobj *) duk__getrequire_bufobj_this(thr, DUK__BUFOBJ_FLAG_THROW /*flags*/);\n\tDUK_ASSERT(h_bufobj != NULL);\n\tif (DUK_HEAPHDR_IS_BUFFER((duk_heaphdr *) h_bufobj)) {\n\t\tduk_hbuffer *h_buf;\n\n\t\th_buf = (duk_hbuffer *) h_bufobj;\n\t\tDUK_ASSERT(DUK_HBUFFER_GET_SIZE(h_buf) <= DUK_UINT_MAX);  /* Buffer limits. */\n\t\tduk_push_uint(thr, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_buf));\n\t} else {\n\t\t/* If neutered must return 0; length is zeroed during\n\t\t * neutering.\n\t\t */\n\t\tduk_push_uint(thr, h_bufobj->length);\n\t}\n\treturn 1;\n}\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n/* No .buffer getter without ArrayBuffer support. */\n#if 0\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_buffer_getter(duk_hthread *thr) {\n\treturn 0;\n}\n#endif\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_hthread *thr) {\n\tduk_push_uint(thr, 0);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_hthread *thr) {\n\tduk_hbuffer *h_buf;\n\n\t/* XXX: helper? */\n\tduk_push_this(thr);\n\th_buf = duk_require_hbuffer(thr, -1);\n\tduk_push_uint(thr, DUK_HBUFFER_GET_SIZE(h_buf));\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_date.c",
    "content": "/*\n *  Date built-ins\n *\n *  Unlike most built-ins, Date has some platform dependencies for getting\n *  UTC time, converting between UTC and local time, and parsing and\n *  formatting time values.  These are all abstracted behind DUK_USE_xxx\n *  config options.  There are built-in platform specific providers for\n *  POSIX and Windows, but external providers can also be used.\n *\n *  See doc/datetime.rst.\n *\n */\n\n#include \"duk_internal.h\"\n\n/* XXX: currently defines unnecessary symbols when DUK_USE_DATE_BUILTIN is disabled. */\n\n/*\n *  Forward declarations\n */\n\nDUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval_tzoffset(duk_hthread *thr, duk_small_uint_t flags, duk_int_t *out_tzoffset);\nDUK_LOCAL_DECL duk_double_t duk__push_this_get_timeval(duk_hthread *thr, duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__twodigit_year_fixup(duk_hthread *thr, duk_idx_t idx_val);\nDUK_LOCAL_DECL duk_ret_t duk__set_this_timeval_from_dparts(duk_hthread *thr, duk_double_t *dparts, duk_small_uint_t flags);\n\n/*\n *  Other file level defines\n */\n\n/* Debug macro to print all parts and dparts (used manually because of debug level). */\n#define  DUK__DPRINT_PARTS_AND_DPARTS(parts,dparts)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"parts: %ld %ld %ld %ld %ld %ld %ld %ld, dparts: %lf %lf %lf %lf %lf %lf %lf %lf\", \\\n\t\t                 (long) (parts)[0], (long) (parts)[1], \\\n\t\t                 (long) (parts)[2], (long) (parts)[3], \\\n\t\t                 (long) (parts)[4], (long) (parts)[5], \\\n\t\t                 (long) (parts)[6], (long) (parts)[7], \\\n\t\t                 (double) (dparts)[0], (double) (dparts)[1], \\\n\t\t                 (double) (dparts)[2], (double) (dparts)[3], \\\n\t\t                 (double) (dparts)[4], (double) (dparts)[5], \\\n\t\t                 (double) (dparts)[6], (double) (dparts)[7])); \\\n\t} while (0)\n#define  DUK__DPRINT_PARTS(parts)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"parts: %ld %ld %ld %ld %ld %ld %ld %ld\", \\\n\t\t                 (long) (parts)[0], (long) (parts)[1], \\\n\t\t                 (long) (parts)[2], (long) (parts)[3], \\\n\t\t                 (long) (parts)[4], (long) (parts)[5], \\\n\t\t                 (long) (parts)[6], (long) (parts)[7])); \\\n\t} while (0)\n#define  DUK__DPRINT_DPARTS(dparts)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"dparts: %lf %lf %lf %lf %lf %lf %lf %lf\", \\\n\t\t                 (double) (dparts)[0], (double) (dparts)[1], \\\n\t\t                 (double) (dparts)[2], (double) (dparts)[3], \\\n\t\t                 (double) (dparts)[4], (double) (dparts)[5], \\\n\t\t                 (double) (dparts)[6], (double) (dparts)[7])); \\\n\t} while (0)\n\n/* Equivalent year for DST calculations outside [1970,2038[ range, see\n * E5 Section 15.9.1.8.  Equivalent year has the same leap-year-ness and\n * starts with the same weekday on Jan 1.\n * https://bugzilla.mozilla.org/show_bug.cgi?id=351066\n */\n#define DUK__YEAR(x) ((duk_uint8_t) ((x) - 1970))\nDUK_LOCAL duk_uint8_t duk__date_equivyear[14] = {\n#if 1\n\t/* This is based on V8 EquivalentYear() algorithm (see util/genequivyear.py):\n\t * http://code.google.com/p/v8/source/browse/trunk/src/date.h#146\n\t */\n\n\t/* non-leap year: sunday, monday, ... */\n\tDUK__YEAR(2023), DUK__YEAR(2035), DUK__YEAR(2019), DUK__YEAR(2031),\n\tDUK__YEAR(2015), DUK__YEAR(2027), DUK__YEAR(2011),\n\n\t/* leap year: sunday, monday, ... */\n\tDUK__YEAR(2012), DUK__YEAR(2024), DUK__YEAR(2008), DUK__YEAR(2020),\n\tDUK__YEAR(2032), DUK__YEAR(2016), DUK__YEAR(2028)\n#endif\n\n#if 0\n\t/* This is based on Rhino EquivalentYear() algorithm:\n\t * https://github.com/mozilla/rhino/blob/f99cc11d616f0cdda2c42bde72b3484df6182947/src/org/mozilla/javascript/NativeDate.java\n\t */\n\n\t/* non-leap year: sunday, monday, ... */\n\tDUK__YEAR(1978), DUK__YEAR(1973), DUK__YEAR(1985), DUK__YEAR(1986),\n\tDUK__YEAR(1981), DUK__YEAR(1971), DUK__YEAR(1977),\n\n\t/* leap year: sunday, monday, ... */\n\tDUK__YEAR(1984), DUK__YEAR(1996), DUK__YEAR(1980), DUK__YEAR(1992),\n\tDUK__YEAR(1976), DUK__YEAR(1988), DUK__YEAR(1972)\n#endif\n};\n\n/*\n *  ISO 8601 subset parser.\n */\n\n/* Parser part count. */\n#define DUK__NUM_ISO8601_PARSER_PARTS  9\n\n/* Parser part indices. */\n#define DUK__PI_YEAR         0\n#define DUK__PI_MONTH        1\n#define DUK__PI_DAY          2\n#define DUK__PI_HOUR         3\n#define DUK__PI_MINUTE       4\n#define DUK__PI_SECOND       5\n#define DUK__PI_MILLISECOND  6\n#define DUK__PI_TZHOUR       7\n#define DUK__PI_TZMINUTE     8\n\n/* Parser part masks. */\n#define DUK__PM_YEAR         (1 << DUK__PI_YEAR)\n#define DUK__PM_MONTH        (1 << DUK__PI_MONTH)\n#define DUK__PM_DAY          (1 << DUK__PI_DAY)\n#define DUK__PM_HOUR         (1 << DUK__PI_HOUR)\n#define DUK__PM_MINUTE       (1 << DUK__PI_MINUTE)\n#define DUK__PM_SECOND       (1 << DUK__PI_SECOND)\n#define DUK__PM_MILLISECOND  (1 << DUK__PI_MILLISECOND)\n#define DUK__PM_TZHOUR       (1 << DUK__PI_TZHOUR)\n#define DUK__PM_TZMINUTE     (1 << DUK__PI_TZMINUTE)\n\n/* Parser separator indices. */\n#define DUK__SI_PLUS         0\n#define DUK__SI_MINUS        1\n#define DUK__SI_T            2\n#define DUK__SI_SPACE        3\n#define DUK__SI_COLON        4\n#define DUK__SI_PERIOD       5\n#define DUK__SI_Z            6\n#define DUK__SI_NUL          7\n\n/* Parser separator masks. */\n#define DUK__SM_PLUS         (1 << DUK__SI_PLUS)\n#define DUK__SM_MINUS        (1 << DUK__SI_MINUS)\n#define DUK__SM_T            (1 << DUK__SI_T)\n#define DUK__SM_SPACE        (1 << DUK__SI_SPACE)\n#define DUK__SM_COLON        (1 << DUK__SI_COLON)\n#define DUK__SM_PERIOD       (1 << DUK__SI_PERIOD)\n#define DUK__SM_Z            (1 << DUK__SI_Z)\n#define DUK__SM_NUL          (1 << DUK__SI_NUL)\n\n/* Rule control flags. */\n#define DUK__CF_NEG          (1 << 0)  /* continue matching, set neg_tzoffset flag */\n#define DUK__CF_ACCEPT       (1 << 1)  /* accept string */\n#define DUK__CF_ACCEPT_NUL   (1 << 2)  /* accept string if next char is NUL (otherwise reject) */\n\n#define DUK__PACK_RULE(partmask,sepmask,nextpart,flags)  \\\n\t((duk_uint32_t) (partmask) + \\\n\t (((duk_uint32_t) (sepmask)) << 9) + \\\n\t (((duk_uint32_t) (nextpart)) << 17) + \\\n\t (((duk_uint32_t) (flags)) << 21))\n\n#define DUK__UNPACK_RULE(rule,var_nextidx,var_flags)  do { \\\n\t\t(var_nextidx) = (duk_small_uint_t) (((rule) >> 17) & 0x0f); \\\n\t\t(var_flags) = (duk_small_uint_t) ((rule) >> 21); \\\n\t} while (0)\n\n#define DUK__RULE_MASK_PART_SEP  0x1ffffUL\n\n/* Matching separator index is used in the control table */\nDUK_LOCAL const duk_uint8_t duk__parse_iso8601_seps[] = {\n\tDUK_ASC_PLUS /*0*/, DUK_ASC_MINUS /*1*/, DUK_ASC_UC_T /*2*/, DUK_ASC_SPACE /*3*/,\n\tDUK_ASC_COLON /*4*/, DUK_ASC_PERIOD /*5*/, DUK_ASC_UC_Z /*6*/, DUK_ASC_NUL /*7*/\n};\n\n/* Rule table: first matching rule is used to determine what to do next. */\nDUK_LOCAL const duk_uint32_t duk__parse_iso8601_control[] = {\n\tDUK__PACK_RULE(DUK__PM_YEAR, DUK__SM_MINUS, DUK__PI_MONTH, 0),\n\tDUK__PACK_RULE(DUK__PM_MONTH, DUK__SM_MINUS, DUK__PI_DAY, 0),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY, DUK__SM_T | DUK__SM_SPACE, DUK__PI_HOUR, 0),\n\tDUK__PACK_RULE(DUK__PM_HOUR, DUK__SM_COLON, DUK__PI_MINUTE, 0),\n\tDUK__PACK_RULE(DUK__PM_MINUTE, DUK__SM_COLON, DUK__PI_SECOND, 0),\n\tDUK__PACK_RULE(DUK__PM_SECOND, DUK__SM_PERIOD, DUK__PI_MILLISECOND, 0),\n\tDUK__PACK_RULE(DUK__PM_TZHOUR, DUK__SM_COLON, DUK__PI_TZMINUTE, 0),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_PLUS, DUK__PI_TZHOUR, 0),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_MINUS, DUK__PI_TZHOUR, DUK__CF_NEG),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND, DUK__SM_Z, 0, DUK__CF_ACCEPT_NUL),\n\tDUK__PACK_RULE(DUK__PM_YEAR | DUK__PM_MONTH | DUK__PM_DAY | DUK__PM_HOUR /*Note1*/ | DUK__PM_MINUTE | DUK__PM_SECOND | DUK__PM_MILLISECOND | DUK__PM_TZHOUR /*Note2*/ | DUK__PM_TZMINUTE, DUK__SM_NUL, 0, DUK__CF_ACCEPT)\n\n\t/* Note1: the specification doesn't require matching a time form with\n\t *        just hours (\"HH\"), but we accept it here, e.g. \"2012-01-02T12Z\".\n\t *\n\t * Note2: the specification doesn't require matching a timezone offset\n\t *        with just hours (\"HH\"), but accept it here, e.g. \"2012-01-02T03:04:05+02\"\n\t */\n};\n\nDUK_LOCAL duk_bool_t duk__parse_string_iso8601_subset(duk_hthread *thr, const char *str) {\n\tduk_int_t parts[DUK__NUM_ISO8601_PARSER_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t d;\n\tconst duk_uint8_t *p;\n\tduk_small_uint_t part_idx = 0;\n\tduk_int_t accum = 0;\n\tduk_small_uint_t ndigits = 0;\n\tduk_bool_t neg_year = 0;\n\tduk_bool_t neg_tzoffset = 0;\n\tduk_uint_fast8_t ch;\n\tduk_small_uint_t i;\n\n\t/* During parsing, month and day are one-based; set defaults here. */\n\tduk_memzero(parts, sizeof(parts));\n\tDUK_ASSERT(parts[DUK_DATE_IDX_YEAR] == 0);  /* don't care value, year is mandatory */\n\tparts[DUK_DATE_IDX_MONTH] = 1;\n\tparts[DUK_DATE_IDX_DAY] = 1;\n\n\t/* Special handling for year sign. */\n\tp = (const duk_uint8_t *) str;\n\tch = p[0];\n\tif (ch == DUK_ASC_PLUS) {\n\t\tp++;\n\t} else if (ch == DUK_ASC_MINUS) {\n\t\tneg_year = 1;\n\t\tp++;\n\t}\n\n\tfor (;;) {\n\t\tch = *p++;\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsing, part_idx=%ld, char=%ld ('%c')\",\n\t\t                     (long) part_idx, (long) ch,\n\t\t                     (int) ((ch >= 0x20 && ch <= 0x7e) ? ch : DUK_ASC_QUESTION)));\n\n\t\tif (ch >= DUK_ASC_0 && ch <= DUK_ASC_9) {\n\t\t\tif (ndigits >= 9) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"too many digits -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tif (part_idx == DUK__PI_MILLISECOND && ndigits >= 3) {\n\t\t\t\t/* ignore millisecond fractions after 3 */\n\t\t\t} else {\n\t\t\t\taccum = accum * 10 + ((duk_int_t) ch) - ((duk_int_t) DUK_ASC_0) + 0x00;\n\t\t\t\tndigits++;\n\t\t\t}\n\t\t} else {\n\t\t\tduk_uint_fast32_t match_val;\n\t\t\tduk_small_uint_t sep_idx;\n\n\t\t\tif (ndigits <= 0) {\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t\tif (part_idx == DUK__PI_MILLISECOND) {\n\t\t\t\t/* complete the millisecond field */\n\t\t\t\twhile (ndigits < 3) {\n\t\t\t\t\taccum *= 10;\n\t\t\t\t\tndigits++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tparts[part_idx] = accum;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"wrote part %ld -> value %ld\", (long) part_idx, (long) accum));\n\n\t\t\taccum = 0;\n\t\t\tndigits = 0;\n\n\t\t\tfor (i = 0; i < (duk_small_uint_t) (sizeof(duk__parse_iso8601_seps) / sizeof(duk_uint8_t)); i++) {\n\t\t\t\tif (duk__parse_iso8601_seps[i] == ch) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (i == (duk_small_uint_t) (sizeof(duk__parse_iso8601_seps) / sizeof(duk_uint8_t))) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"separator character doesn't match -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\n\t\t\tsep_idx = i;\n\t\t\tmatch_val = (1UL << part_idx) + (1UL << (sep_idx + 9));  /* match against rule part/sep bits */\n\n\t\t\tfor (i = 0; i < (duk_small_uint_t) (sizeof(duk__parse_iso8601_control) / sizeof(duk_uint32_t)); i++) {\n\t\t\t\tduk_uint_fast32_t rule = duk__parse_iso8601_control[i];\n\t\t\t\tduk_small_uint_t nextpart;\n\t\t\t\tduk_small_uint_t cflags;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"part_idx=%ld, sep_idx=%ld, match_val=0x%08lx, considering rule=0x%08lx\",\n\t\t\t\t                     (long) part_idx, (long) sep_idx,\n\t\t\t\t                     (unsigned long) match_val, (unsigned long) rule));\n\n\t\t\t\tif ((rule & match_val) != match_val) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tDUK__UNPACK_RULE(rule, nextpart, cflags);\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rule match -> part_idx=%ld, sep_idx=%ld, match_val=0x%08lx, \"\n\t\t\t\t                     \"rule=0x%08lx -> nextpart=%ld, cflags=0x%02lx\",\n\t\t\t\t                     (long) part_idx, (long) sep_idx,\n\t\t\t\t                     (unsigned long) match_val, (unsigned long) rule,\n\t\t\t\t                     (long) nextpart, (unsigned long) cflags));\n\n\t\t\t\tif (cflags & DUK__CF_NEG) {\n\t\t\t\t\tneg_tzoffset = 1;\n\t\t\t\t}\n\n\t\t\t\tif (cflags & DUK__CF_ACCEPT) {\n\t\t\t\t\tgoto accept;\n\t\t\t\t}\n\n\t\t\t\tif (cflags & DUK__CF_ACCEPT_NUL) {\n\t\t\t\t\tDUK_ASSERT(*(p - 1) != (char) 0);\n\t\t\t\t\tif (*p == DUK_ASC_NUL) {\n\t\t\t\t\t\tgoto accept;\n\t\t\t\t\t}\n\t\t\t\t\tgoto reject;\n\t\t\t\t}\n\n\t\t\t\tpart_idx = nextpart;\n\t\t\t\tbreak;\n\t\t\t}  /* rule match */\n\n\t\t\tif (i == (duk_small_uint_t) (sizeof(duk__parse_iso8601_control) / sizeof(duk_uint32_t))) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"no rule matches -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\n\t\t\tif (ch == 0) {\n\t\t\t\t/* This shouldn't be necessary, but check just in case\n\t\t\t\t * to avoid any chance of overruns.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"NUL after rule matching (should not happen) -> reject\"));\n\t\t\t\tgoto reject;\n\t\t\t}\n\t\t}  /* if-digit-else-ctrl */\n\t}  /* char loop */\n\n\t/* We should never exit the loop above. */\n\tDUK_UNREACHABLE();\n\n reject:\n\tDUK_DDD(DUK_DDDPRINT(\"reject\"));\n\treturn 0;\n\n accept:\n\tDUK_DDD(DUK_DDDPRINT(\"accept\"));\n\n\t/* Apply timezone offset to get the main parts in UTC */\n\tif (neg_year) {\n\t\tparts[DUK__PI_YEAR] = -parts[DUK__PI_YEAR];\n\t}\n\tif (neg_tzoffset) {\n\t\tparts[DUK__PI_HOUR] += parts[DUK__PI_TZHOUR];\n\t\tparts[DUK__PI_MINUTE] += parts[DUK__PI_TZMINUTE];\n\t} else {\n\t\tparts[DUK__PI_HOUR] -= parts[DUK__PI_TZHOUR];\n\t\tparts[DUK__PI_MINUTE] -= parts[DUK__PI_TZMINUTE];\n\t}\n\tparts[DUK__PI_MONTH] -= 1;  /* zero-based month */\n\tparts[DUK__PI_DAY] -= 1;  /* zero-based day */\n\n\t/* Use double parts, they tolerate unnormalized time.\n\t *\n\t * Note: DUK_DATE_IDX_WEEKDAY is initialized with a bogus value (DUK__PI_TZHOUR)\n\t * on purpose.  It won't be actually used by duk_bi_date_get_timeval_from_dparts(),\n\t * but will make the value initialized just in case, and avoid any\n\t * potential for Valgrind issues.\n\t */\n\tfor (i = 0; i < DUK_DATE_IDX_NUM_PARTS; i++) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"part[%ld] = %ld\", (long) i, (long) parts[i]));\n\t\tdparts[i] = parts[i];\n\t}\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);\n\tduk_push_number(thr, d);\n\treturn 1;\n}\n\n/*\n *  Date/time parsing helper.\n *\n *  Parse a datetime string into a time value.  We must first try to parse\n *  the input according to the standard format in E5.1 Section 15.9.1.15.\n *  If that fails, we can try to parse using custom parsing, which can\n *  either be platform neutral (custom code) or platform specific (using\n *  existing platform API calls).\n *\n *  Note in particular that we must parse whatever toString(), toUTCString(),\n *  and toISOString() can produce; see E5.1 Section 15.9.4.2.\n *\n *  Returns 1 to allow tail calling.\n *\n *  There is much room for improvement here with respect to supporting\n *  alternative datetime formats.  For instance, V8 parses '2012-01-01' as\n *  UTC and '2012/01/01' as local time.\n */\n\nDUK_LOCAL duk_ret_t duk__parse_string(duk_hthread *thr, const char *str) {\n\t/* XXX: there is a small risk here: because the ISO 8601 parser is\n\t * very loose, it may end up parsing some datetime values which\n\t * would be better parsed with a platform specific parser.\n\t */\n\n\tDUK_ASSERT(str != NULL);\n\tDUK_DDD(DUK_DDDPRINT(\"parse datetime from string '%s'\", (const char *) str));\n\n\tif (duk__parse_string_iso8601_subset(thr, str) != 0) {\n\t\treturn 1;\n\t}\n\n#if defined(DUK_USE_DATE_PARSE_STRING)\n\t/* Contract, either:\n\t * - Push value on stack and return 1\n\t * - Don't push anything on stack and return 0\n\t */\n\n\tif (DUK_USE_DATE_PARSE_STRING(thr, str) != 0) {\n\t\treturn 1;\n\t}\n#else\n\t/* No platform-specific parsing, this is not an error. */\n#endif\n\n\tduk_push_nan(thr);\n\treturn 1;\n}\n\n/*\n *  Calendar helpers\n *\n *  Some helpers are used for getters and can operate on normalized values\n *  which can be represented with 32-bit signed integers.  Other helpers are\n *  needed by setters and operate on un-normalized double values, must watch\n *  out for non-finite numbers etc.\n */\n\nDUK_LOCAL duk_uint8_t duk__days_in_month[12] = {\n\t(duk_uint8_t) 31, (duk_uint8_t) 28, (duk_uint8_t) 31, (duk_uint8_t) 30,\n\t(duk_uint8_t) 31, (duk_uint8_t) 30, (duk_uint8_t) 31, (duk_uint8_t) 31,\n\t(duk_uint8_t) 30, (duk_uint8_t) 31, (duk_uint8_t) 30, (duk_uint8_t) 31\n};\n\n/* Maximum iteration count for computing UTC-to-local time offset when\n * creating an ECMAScript time value from local parts.\n */\n#define DUK__LOCAL_TZOFFSET_MAXITER   4\n\n/* Because 'day since epoch' can be negative and is used to compute weekday\n * using a modulo operation, add this multiple of 7 to avoid negative values\n * when year is below 1970 epoch.  ECMAScript time values are restricted to\n * +/- 100 million days from epoch, so this adder fits nicely into 32 bits.\n * Round to a multiple of 7 (= floor(100000000 / 7) * 7) and add margin.\n */\n#define DUK__WEEKDAY_MOD_ADDER  (20000000 * 7)  /* 0x08583b00 */\n\nDUK_INTERNAL duk_bool_t duk_bi_date_is_leap_year(duk_int_t year) {\n\tif ((year % 4) != 0) {\n\t\treturn 0;\n\t}\n\tif ((year % 100) != 0) {\n\t\treturn 1;\n\t}\n\tif ((year % 400) != 0) {\n\t\treturn 0;\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_bool_t duk_bi_date_timeval_in_valid_range(duk_double_t x) {\n\treturn (x >= -DUK_DATE_MSEC_100M_DAYS && x <= DUK_DATE_MSEC_100M_DAYS);\n}\n\nDUK_INTERNAL duk_bool_t duk_bi_date_timeval_in_leeway_range(duk_double_t x) {\n\treturn (x >= -DUK_DATE_MSEC_100M_DAYS_LEEWAY && x <= DUK_DATE_MSEC_100M_DAYS_LEEWAY);\n}\n\nDUK_INTERNAL duk_bool_t duk_bi_date_year_in_valid_range(duk_double_t x) {\n\treturn (x >= DUK_DATE_MIN_ECMA_YEAR && x <= DUK_DATE_MAX_ECMA_YEAR);\n}\n\nDUK_LOCAL duk_double_t duk__timeclip(duk_double_t x) {\n\tif (!DUK_ISFINITE(x)) {\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\n\tif (!duk_bi_date_timeval_in_valid_range(x)) {\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\n\tx = duk_js_tointeger_number(x);\n\n\t/* Here we'd have the option to normalize -0 to +0. */\n\treturn x;\n}\n\n/* Integer division which floors also negative values correctly. */\nDUK_LOCAL duk_int_t duk__div_floor(duk_int_t a, duk_int_t b) {\n\tDUK_ASSERT(b > 0);\n\tif (a >= 0) {\n\t\treturn a / b;\n\t} else {\n\t\t/* e.g. a = -4, b = 5  -->  -4 - 5 + 1 / 5  -->  -8 / 5  -->  -1\n\t\t *      a = -5, b = 5  -->  -5 - 5 + 1 / 5  -->  -9 / 5  -->  -1\n\t\t *      a = -6, b = 5  -->  -6 - 5 + 1 / 5  -->  -10 / 5  -->  -2\n\t\t */\n\t\treturn (a - b + 1) / b;\n\t}\n}\n\n/* Compute day number of the first day of a given year. */\nDUK_LOCAL duk_int_t duk__day_from_year(duk_int_t year) {\n\t/* Note: in integer arithmetic, (x / 4) is same as floor(x / 4) for non-negative\n\t * values, but is incorrect for negative ones.\n\t */\n\treturn 365 * (year - 1970)\n\t       + duk__div_floor(year - 1969, 4)\n\t       - duk__div_floor(year - 1901, 100)\n\t       + duk__div_floor(year - 1601, 400);\n}\n\n/* Given a day number, determine year and day-within-year. */\nDUK_LOCAL duk_int_t duk__year_from_day(duk_int_t day, duk_small_int_t *out_day_within_year) {\n\tduk_int_t year;\n\tduk_int_t diff_days;\n\n\t/* estimate year upwards (towards positive infinity), then back down;\n\t * two iterations should be enough\n\t */\n\n\tif (day >= 0) {\n\t\tyear = 1970 + day / 365;\n\t} else {\n\t\tyear = 1970 + day / 366;\n\t}\n\n\tfor (;;) {\n\t\tdiff_days = duk__day_from_year(year) - day;\n\t\tDUK_DDD(DUK_DDDPRINT(\"year=%ld day=%ld, diff_days=%ld\", (long) year, (long) day, (long) diff_days));\n\t\tif (diff_days <= 0) {\n\t\t\tDUK_ASSERT(-diff_days < 366);  /* fits into duk_small_int_t */\n\t\t\t*out_day_within_year = -diff_days;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"--> year=%ld, day-within-year=%ld\",\n\t\t\t                     (long) year, (long) *out_day_within_year));\n\t\t\tDUK_ASSERT(*out_day_within_year >= 0);\n\t\t\tDUK_ASSERT(*out_day_within_year < (duk_bi_date_is_leap_year(year) ? 366 : 365));\n\t\t\treturn year;\n\t\t}\n\n\t\t/* Note: this is very tricky; we must never 'overshoot' the\n\t\t * correction downwards.\n\t\t */\n\t\tyear -= 1 + (diff_days - 1) / 366;  /* conservative */\n\t}\n}\n\n/* Given a (year, month, day-within-month) triple, compute day number.\n * The input triple is un-normalized and may contain non-finite values.\n */\nDUK_LOCAL duk_double_t duk__make_day(duk_double_t year, duk_double_t month, duk_double_t day) {\n\tduk_int_t day_num;\n\tduk_bool_t is_leap;\n\tduk_small_int_t i, n;\n\n\t/* Assume that year, month, day are all coerced to whole numbers.\n\t * They may also be NaN or infinity, in which case this function\n\t * must return NaN or infinity to ensure time value becomes NaN.\n\t * If 'day' is NaN, the final return will end up returning a NaN,\n\t * so it doesn't need to be checked here.\n\t */\n\n\tif (!DUK_ISFINITE(year) || !DUK_ISFINITE(month)) {\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\n\tyear += DUK_FLOOR(month / 12.0);\n\n\tmonth = DUK_FMOD(month, 12.0);\n\tif (month < 0.0) {\n\t\t/* handle negative values */\n\t\tmonth += 12.0;\n\t}\n\n\t/* The algorithm in E5.1 Section 15.9.1.12 normalizes month, but\n\t * does not normalize the day-of-month (nor check whether or not\n\t * it is finite) because it's not necessary for finding the day\n\t * number which matches the (year,month) pair.\n\t *\n\t * We assume that duk__day_from_year() is exact here.\n\t *\n\t * Without an explicit infinity / NaN check in the beginning,\n\t * day_num would be a bogus integer here.\n\t *\n\t * It's possible for 'year' to be out of integer range here.\n\t * If so, we need to return NaN without integer overflow.\n\t * This fixes test-bug-setyear-overflow.js.\n\t */\n\n\tif (!duk_bi_date_year_in_valid_range(year)) {\n\t\tDUK_DD(DUK_DDPRINT(\"year not in ecmascript valid range, avoid integer overflow: %lf\", (double) year));\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n\tday_num = duk__day_from_year((duk_int_t) year);\n\tis_leap = duk_bi_date_is_leap_year((duk_int_t) year);\n\n\tn = (duk_small_int_t) month;\n\tfor (i = 0; i < n; i++) {\n\t\tday_num += duk__days_in_month[i];\n\t\tif (i == 1 && is_leap) {\n\t\t\tday_num++;\n\t\t}\n\t}\n\n\t/* If 'day' is NaN, returns NaN. */\n\treturn (duk_double_t) day_num + day;\n}\n\n/* Split time value into parts.  The time value may contain fractions (it may\n * come from duk_time_to_components() API call) which are truncated.  Possible\n * local time adjustment has already been applied when reading the time value.\n */\nDUK_INTERNAL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts, duk_double_t *dparts, duk_small_uint_t flags) {\n\tduk_double_t d1, d2;\n\tduk_int_t t1, t2;\n\tduk_int_t day_since_epoch;\n\tduk_int_t year;  /* does not fit into 16 bits */\n\tduk_small_int_t day_in_year;\n\tduk_small_int_t month;\n\tduk_small_int_t day;\n\tduk_small_int_t dim;\n\tduk_int_t jan1_since_epoch;\n\tduk_small_int_t jan1_weekday;\n\tduk_int_t equiv_year;\n\tduk_small_uint_t i;\n\tduk_bool_t is_leap;\n\tduk_small_int_t arridx;\n\n\tDUK_ASSERT(DUK_ISFINITE(d));    /* caller checks */\n\td = DUK_FLOOR(d);  /* remove fractions if present */\n\tDUK_ASSERT(DUK_FLOOR(d) == d);\n\n\t/* The timevalue must be in valid ECMAScript range, but since a local\n\t * time offset can be applied, we need to allow a +/- 24h leeway to\n\t * the value.  In other words, although the UTC time is within the\n\t * ECMAScript range, the local part values can be just outside of it.\n\t */\n\tDUK_UNREF(duk_bi_date_timeval_in_leeway_range);\n\tDUK_ASSERT(duk_bi_date_timeval_in_leeway_range(d));\n\n\t/* These computations are guaranteed to be exact for the valid\n\t * E5 time value range, assuming milliseconds without fractions.\n\t */\n\td1 = (duk_double_t) DUK_FMOD(d, (double) DUK_DATE_MSEC_DAY);\n\tif (d1 < 0.0) {\n\t\t/* deal with negative values */\n\t\td1 += (duk_double_t) DUK_DATE_MSEC_DAY;\n\t}\n\td2 = DUK_FLOOR((double) (d / (duk_double_t) DUK_DATE_MSEC_DAY));\n\tDUK_ASSERT(d2 * ((duk_double_t) DUK_DATE_MSEC_DAY) + d1 == d);\n\t/* now expected to fit into a 32-bit integer */\n\tt1 = (duk_int_t) d1;\n\tt2 = (duk_int_t) d2;\n\tday_since_epoch = t2;\n\tDUK_ASSERT((duk_double_t) t1 == d1);\n\tDUK_ASSERT((duk_double_t) t2 == d2);\n\n\t/* t1 = milliseconds within day (fits 32 bit)\n\t * t2 = day number from epoch (fits 32 bit, may be negative)\n\t */\n\n\tparts[DUK_DATE_IDX_MILLISECOND] = t1 % 1000; t1 /= 1000;\n\tparts[DUK_DATE_IDX_SECOND] = t1 % 60; t1 /= 60;\n\tparts[DUK_DATE_IDX_MINUTE] = t1 % 60; t1 /= 60;\n\tparts[DUK_DATE_IDX_HOUR] = t1;\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MILLISECOND] >= 0 && parts[DUK_DATE_IDX_MILLISECOND] <= 999);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_SECOND] >= 0 && parts[DUK_DATE_IDX_SECOND] <= 59);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MINUTE] >= 0 && parts[DUK_DATE_IDX_MINUTE] <= 59);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_HOUR] >= 0 && parts[DUK_DATE_IDX_HOUR] <= 23);\n\n\tDUK_DDD(DUK_DDDPRINT(\"d=%lf, d1=%lf, d2=%lf, t1=%ld, t2=%ld, parts: hour=%ld min=%ld sec=%ld msec=%ld\",\n\t                     (double) d, (double) d1, (double) d2, (long) t1, (long) t2,\n\t                     (long) parts[DUK_DATE_IDX_HOUR],\n\t                     (long) parts[DUK_DATE_IDX_MINUTE],\n\t                     (long) parts[DUK_DATE_IDX_SECOND],\n\t                     (long) parts[DUK_DATE_IDX_MILLISECOND]));\n\n\t/* This assert depends on the input parts representing time inside\n\t * the ECMAScript range.\n\t */\n\tDUK_ASSERT(t2 + DUK__WEEKDAY_MOD_ADDER >= 0);\n\tparts[DUK_DATE_IDX_WEEKDAY] = (t2 + 4 + DUK__WEEKDAY_MOD_ADDER) % 7;  /* E5.1 Section 15.9.1.6 */\n\tDUK_ASSERT(parts[DUK_DATE_IDX_WEEKDAY] >= 0 && parts[DUK_DATE_IDX_WEEKDAY] <= 6);\n\n\tyear = duk__year_from_day(t2, &day_in_year);\n\tday = day_in_year;\n\tis_leap = duk_bi_date_is_leap_year(year);\n\tfor (month = 0; month < 12; month++) {\n\t\tdim = duk__days_in_month[month];\n\t\tif (month == 1 && is_leap) {\n\t\t\tdim++;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"month=%ld, dim=%ld, day=%ld\",\n\t\t                     (long) month, (long) dim, (long) day));\n\t\tif (day < dim) {\n\t\t\tbreak;\n\t\t}\n\t\tday -= dim;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"final month=%ld\", (long) month));\n\tDUK_ASSERT(month >= 0 && month <= 11);\n\tDUK_ASSERT(day >= 0 && day <= 31);\n\n\t/* Equivalent year mapping, used to avoid DST trouble when platform\n\t * may fail to provide reasonable DST answers for dates outside the\n\t * ordinary range (e.g. 1970-2038).  An equivalent year has the same\n\t * leap-year-ness as the original year and begins on the same weekday\n\t * (Jan 1).\n\t *\n\t * The year 2038 is avoided because there seem to be problems with it\n\t * on some platforms.  The year 1970 is also avoided as there were\n\t * practical problems with it; an equivalent year is used for it too,\n\t * which breaks some DST computations for 1970 right now, see e.g.\n\t * test-bi-date-tzoffset-brute-fi.js.\n\t */\n\tif ((flags & DUK_DATE_FLAG_EQUIVYEAR) && (year < 1971 || year > 2037)) {\n\t\tDUK_ASSERT(is_leap == 0 || is_leap == 1);\n\n\t\tjan1_since_epoch = day_since_epoch - day_in_year;  /* day number for Jan 1 since epoch */\n\t\tDUK_ASSERT(jan1_since_epoch + DUK__WEEKDAY_MOD_ADDER >= 0);\n\t\tjan1_weekday = (jan1_since_epoch + 4 + DUK__WEEKDAY_MOD_ADDER) % 7;  /* E5.1 Section 15.9.1.6 */\n\t\tDUK_ASSERT(jan1_weekday >= 0 && jan1_weekday <= 6);\n\t\tarridx = jan1_weekday;\n\t\tif (is_leap) {\n\t\t\tarridx += 7;\n\t\t}\n\t\tDUK_ASSERT(arridx >= 0 && arridx < (duk_small_int_t) (sizeof(duk__date_equivyear) / sizeof(duk_uint8_t)));\n\n\t\tequiv_year = (duk_int_t) duk__date_equivyear[arridx] + 1970;\n\t\tyear = equiv_year;\n\t\tDUK_DDD(DUK_DDDPRINT(\"equiv year mapping, year=%ld, day_in_year=%ld, day_since_epoch=%ld, \"\n\t\t                     \"jan1_since_epoch=%ld, jan1_weekday=%ld -> equiv year %ld\",\n\t\t                     (long) year, (long) day_in_year, (long) day_since_epoch,\n\t\t                     (long) jan1_since_epoch, (long) jan1_weekday, (long) equiv_year));\n\t}\n\n\tparts[DUK_DATE_IDX_YEAR] = year;\n\tparts[DUK_DATE_IDX_MONTH] = month;\n\tparts[DUK_DATE_IDX_DAY] = day;\n\n\tif (flags & DUK_DATE_FLAG_ONEBASED) {\n\t\tparts[DUK_DATE_IDX_MONTH]++;  /* zero-based -> one-based */\n\t\tparts[DUK_DATE_IDX_DAY]++;    /* -\"\"- */\n\t}\n\n\tif (dparts != NULL) {\n\t\tfor (i = 0; i < DUK_DATE_IDX_NUM_PARTS; i++) {\n\t\t\tdparts[i] = (duk_double_t) parts[i];\n\t\t}\n\t}\n}\n\n/* Compute time value from (double) parts.  The parts can be either UTC\n * or local time; if local, they need to be (conceptually) converted into\n * UTC time.  The parts may represent valid or invalid time, and may be\n * wildly out of range (but may cancel each other and still come out in\n * the valid Date range).\n */\nDUK_INTERNAL duk_double_t duk_bi_date_get_timeval_from_dparts(duk_double_t *dparts, duk_small_uint_t flags) {\n#if defined(DUK_USE_PARANOID_DATE_COMPUTATION)\n\t/* See comments below on MakeTime why these are volatile. */\n\tvolatile duk_double_t tmp_time;\n\tvolatile duk_double_t tmp_day;\n\tvolatile duk_double_t d;\n#else\n\tduk_double_t tmp_time;\n\tduk_double_t tmp_day;\n\tduk_double_t d;\n#endif\n\tduk_small_uint_t i;\n\tduk_int_t tzoff, tzoffprev1, tzoffprev2;\n\n\t/* Expects 'this' at top of stack on entry. */\n\n\t/* Coerce all finite parts with ToInteger().  ToInteger() must not\n\t * be called for NaN/Infinity because it will convert e.g. NaN to\n\t * zero.  If ToInteger() has already been called, this has no side\n\t * effects and is idempotent.\n\t *\n\t * Don't read dparts[DUK_DATE_IDX_WEEKDAY]; it will cause Valgrind\n\t * issues if the value is uninitialized.\n\t */\n\tfor (i = 0; i <= DUK_DATE_IDX_MILLISECOND; i++) {\n\t\t/* SCANBUILD: scan-build complains here about assigned value\n\t\t * being garbage or undefined.  This is correct but operating\n\t\t * on undefined values has no ill effect and is ignored by the\n\t\t * caller in the case where this happens.\n\t\t */\n\t\td = dparts[i];\n\t\tif (DUK_ISFINITE(d)) {\n\t\t\tdparts[i] = duk_js_tointeger_number(d);\n\t\t}\n\t}\n\n\t/* Use explicit steps in computation to try to ensure that\n\t * computation happens with intermediate results coerced to\n\t * double values (instead of using something more accurate).\n\t * E.g. E5.1 Section 15.9.1.11 requires use of IEEE 754\n\t * rules (= ECMAScript '+' and '*' operators).\n\t *\n\t * Without 'volatile' even this approach fails on some platform\n\t * and compiler combinations.  For instance, gcc 4.8.1 on Ubuntu\n\t * 64-bit, with -m32 and without -std=c99, test-bi-date-canceling.js\n\t * would fail because of some optimizations when computing tmp_time\n\t * (MakeTime below).  Adding 'volatile' to tmp_time solved this\n\t * particular problem (annoyingly, also adding debug prints or\n\t * running the executable under valgrind hides it).\n\t */\n\n\t/* MakeTime */\n\ttmp_time = 0.0;\n\ttmp_time += dparts[DUK_DATE_IDX_HOUR] * ((duk_double_t) DUK_DATE_MSEC_HOUR);\n\ttmp_time += dparts[DUK_DATE_IDX_MINUTE] * ((duk_double_t) DUK_DATE_MSEC_MINUTE);\n\ttmp_time += dparts[DUK_DATE_IDX_SECOND] * ((duk_double_t) DUK_DATE_MSEC_SECOND);\n\ttmp_time += dparts[DUK_DATE_IDX_MILLISECOND];\n\n\t/* MakeDay */\n\ttmp_day = duk__make_day(dparts[DUK_DATE_IDX_YEAR], dparts[DUK_DATE_IDX_MONTH], dparts[DUK_DATE_IDX_DAY]);\n\n\t/* MakeDate */\n\td = tmp_day * ((duk_double_t) DUK_DATE_MSEC_DAY) + tmp_time;\n\n\tDUK_DDD(DUK_DDDPRINT(\"time=%lf day=%lf --> timeval=%lf\",\n\t                     (double) tmp_time, (double) tmp_day, (double) d));\n\n\t/* Optional UTC conversion. */\n\tif (flags & DUK_DATE_FLAG_LOCALTIME) {\n\t\t/* DUK_USE_DATE_GET_LOCAL_TZOFFSET() needs to be called with a\n\t\t * time value computed from UTC parts.  At this point we only\n\t\t * have 'd' which is a time value computed from local parts, so\n\t\t * it is off by the UTC-to-local time offset which we don't know\n\t\t * yet.  The current solution for computing the UTC-to-local\n\t\t * time offset is to iterate a few times and detect a fixed\n\t\t * point or a two-cycle loop (or a sanity iteration limit),\n\t\t * see test-bi-date-local-parts.js and test-bi-date-tzoffset-basic-fi.js.\n\t\t *\n\t\t * E5.1 Section 15.9.1.9:\n\t\t * UTC(t) = t - LocalTZA - DaylightSavingTA(t - LocalTZA)\n\t\t *\n\t\t * For NaN/inf, DUK_USE_DATE_GET_LOCAL_TZOFFSET() returns 0.\n\t\t */\n\n#if 0\n\t\t/* Old solution: don't iterate, incorrect */\n\t\ttzoff = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);\n\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset w/o iteration, tzoff=%ld\", (long) tzoff));\n\t\td -= tzoff * 1000L;\n\t\tDUK_UNREF(tzoffprev1);\n\t\tDUK_UNREF(tzoffprev2);\n#endif\n\n\t\t/* Iteration solution */\n\t\ttzoff = 0;\n\t\ttzoffprev1 = 999999999L;  /* invalid value which never matches */\n\t\tfor (i = 0; i < DUK__LOCAL_TZOFFSET_MAXITER; i++) {\n\t\t\ttzoffprev2 = tzoffprev1;\n\t\t\ttzoffprev1 = tzoff;\n\t\t\ttzoff = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d - tzoff * 1000L);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration, i=%d, tzoff=%ld, tzoffprev1=%ld tzoffprev2=%ld\",\n\t\t\t                     (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2));\n\t\t\tif (tzoff == tzoffprev1) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration finished, i=%d, tzoff=%ld, tzoffprev1=%ld, tzoffprev2=%ld\",\n\t\t\t\t                     (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2));\n\t\t\t\tbreak;\n\t\t\t} else if (tzoff == tzoffprev2) {\n\t\t\t\t/* Two value cycle, see e.g. test-bi-date-tzoffset-basic-fi.js.\n\t\t\t\t * In these cases, favor a higher tzoffset to get a consistent\n\t\t\t\t * result which is independent of iteration count.  Not sure if\n\t\t\t\t * this is a generically correct solution.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration two-value cycle, i=%d, tzoff=%ld, tzoffprev1=%ld, tzoffprev2=%ld\",\n\t\t\t\t                     (int) i, (long) tzoff, (long) tzoffprev1, (long) tzoffprev2));\n\t\t\t\tif (tzoffprev1 > tzoff) {\n\t\t\t\t\ttzoff = tzoffprev1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"tzoffset iteration, tzoff=%ld\", (long) tzoff));\n\t\td -= tzoff * 1000L;\n\t}\n\n\t/* TimeClip(), which also handles Infinity -> NaN conversion */\n\td = duk__timeclip(d);\n\n\treturn d;\n}\n\n/*\n *  API oriented helpers\n */\n\n/* Push 'this' binding, check that it is a Date object; then push the\n * internal time value.  At the end, stack is: [ ... this timeval ].\n * Returns the time value.  Local time adjustment is done if requested.\n */\nDUK_LOCAL duk_double_t duk__push_this_get_timeval_tzoffset(duk_hthread *thr, duk_small_uint_t flags, duk_int_t *out_tzoffset) {\n\tduk_hobject *h;\n\tduk_double_t d;\n\tduk_int_t tzoffset = 0;\n\n\tduk_push_this(thr);\n\th = duk_get_hobject(thr, -1);  /* XXX: getter with class check, useful in built-ins */\n\tif (h == NULL || DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_DATE) {\n\t\tDUK_ERROR_TYPE(thr, \"expected Date\");\n\t\tDUK_WO_NORETURN(return 0.0;);\n\t}\n\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\td = duk_to_number_m1(thr);\n\tduk_pop(thr);\n\n\tif (DUK_ISNAN(d)) {\n\t\tif (flags & DUK_DATE_FLAG_NAN_TO_ZERO) {\n\t\t\td = 0.0;\n\t\t}\n\t\tif (flags & DUK_DATE_FLAG_NAN_TO_RANGE_ERROR) {\n\t\t\tDUK_ERROR_RANGE(thr, \"Invalid Date\");\n\t\t\tDUK_WO_NORETURN(return 0.0;);\n\t\t}\n\t}\n\t/* if no NaN handling flag, may still be NaN here, but not Inf */\n\tDUK_ASSERT(!DUK_ISINF(d));\n\n\tif (flags & DUK_DATE_FLAG_LOCALTIME) {\n\t\t/* Note: DST adjustment is determined using UTC time.\n\t\t * If 'd' is NaN, tzoffset will be 0.\n\t\t */\n\t\ttzoffset = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);  /* seconds */\n\t\td += tzoffset * 1000L;\n\t}\n\tif (out_tzoffset) {\n\t\t*out_tzoffset = tzoffset;\n\t}\n\n\t/* [ ... this ] */\n\treturn d;\n}\n\nDUK_LOCAL duk_double_t duk__push_this_get_timeval(duk_hthread *thr, duk_small_uint_t flags) {\n\treturn duk__push_this_get_timeval_tzoffset(thr, flags, NULL);\n}\n\n/* Set timeval to 'this' from dparts, push the new time value onto the\n * value stack and return 1 (caller can then tail call us).  Expects\n * the value stack to contain 'this' on the stack top.\n */\nDUK_LOCAL duk_ret_t duk__set_this_timeval_from_dparts(duk_hthread *thr, duk_double_t *dparts, duk_small_uint_t flags) {\n\tduk_double_t d;\n\n\t/* [ ... this ] */\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, flags);\n\tduk_push_number(thr, d);  /* -> [ ... this timeval_new ] */\n\tduk_dup_top(thr);         /* -> [ ... this timeval_new timeval_new ] */\n\n\t/* Must force write because e.g. .setYear() must work even when\n\t * the Date instance is frozen.\n\t */\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\n\t/* Stack top: new time value, return 1 to allow tail calls. */\n\treturn 1;\n}\n\n/* 'out_buf' must be at least DUK_BI_DATE_ISO8601_BUFSIZE long. */\nDUK_LOCAL void duk__format_parts_iso8601(duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags, duk_uint8_t *out_buf) {\n\tchar yearstr[8];   /* \"-123456\\0\" */\n\tchar tzstr[8];     /* \"+11:22\\0\" */\n\tchar sep = (flags & DUK_DATE_FLAG_SEP_T) ? DUK_ASC_UC_T : DUK_ASC_SPACE;\n\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MONTH] >= 1 && parts[DUK_DATE_IDX_MONTH] <= 12);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_DAY] >= 1 && parts[DUK_DATE_IDX_DAY] <= 31);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_YEAR] >= -999999 && parts[DUK_DATE_IDX_YEAR] <= 999999);\n\n\t/* Note: %06d for positive value, %07d for negative value to include\n\t * sign and 6 digits.\n\t */\n\tDUK_SNPRINTF(yearstr,\n\t             sizeof(yearstr),\n\t             (parts[DUK_DATE_IDX_YEAR] >= 0 && parts[DUK_DATE_IDX_YEAR] <= 9999) ? \"%04ld\" :\n\t                    ((parts[DUK_DATE_IDX_YEAR] >= 0) ? \"+%06ld\" : \"%07ld\"),\n\t             (long) parts[DUK_DATE_IDX_YEAR]);\n\tyearstr[sizeof(yearstr) - 1] = (char) 0;\n\n\tif (flags & DUK_DATE_FLAG_LOCALTIME) {\n\t\t/* tzoffset seconds are dropped; 16 bits suffice for\n\t\t * time offset in minutes\n\t\t */\n\t\tconst char *fmt;\n\t\tduk_small_int_t tmp, arg_hours, arg_minutes;\n\n\t\tif (tzoffset >= 0) {\n\t\t\ttmp = tzoffset;\n\t\t\tfmt = \"+%02d:%02d\";\n\t\t} else {\n\t\t\ttmp = -tzoffset;\n\t\t\tfmt = \"-%02d:%02d\";\n\t\t}\n\t\ttmp = tmp / 60;\n\t\targ_hours = tmp / 60;\n\t\targ_minutes = tmp % 60;\n\t\tDUK_ASSERT(arg_hours <= 24);  /* Even less is actually guaranteed for a valid tzoffset. */\n\t\targ_hours = arg_hours & 0x3f;  /* For [0,24] this is a no-op, but fixes GCC 7 warning, see https://github.com/svaarala/duktape/issues/1602. */\n\n\t\tDUK_SNPRINTF(tzstr, sizeof(tzstr), fmt, (int) arg_hours, (int) arg_minutes);\n\t\ttzstr[sizeof(tzstr) - 1] = (char) 0;\n\t} else {\n\t\ttzstr[0] = DUK_ASC_UC_Z;\n\t\ttzstr[1] = (char) 0;\n\t}\n\n\t/* Unlike year, the other parts fit into 16 bits so %d format\n\t * is portable.\n\t */\n\tif ((flags & DUK_DATE_FLAG_TOSTRING_DATE) && (flags & DUK_DATE_FLAG_TOSTRING_TIME)) {\n\t\tDUK_SPRINTF((char *) out_buf, \"%s-%02d-%02d%c%02d:%02d:%02d.%03d%s\",\n\t\t            (const char *) yearstr, (int) parts[DUK_DATE_IDX_MONTH], (int) parts[DUK_DATE_IDX_DAY], (int) sep,\n\t\t            (int) parts[DUK_DATE_IDX_HOUR], (int) parts[DUK_DATE_IDX_MINUTE],\n\t\t            (int) parts[DUK_DATE_IDX_SECOND], (int) parts[DUK_DATE_IDX_MILLISECOND], (const char *) tzstr);\n\t} else if (flags & DUK_DATE_FLAG_TOSTRING_DATE) {\n\t\tDUK_SPRINTF((char *) out_buf, \"%s-%02d-%02d\",\n\t\t            (const char *) yearstr, (int) parts[DUK_DATE_IDX_MONTH], (int) parts[DUK_DATE_IDX_DAY]);\n\t} else {\n\t\tDUK_ASSERT(flags & DUK_DATE_FLAG_TOSTRING_TIME);\n\t\tDUK_SPRINTF((char *) out_buf, \"%02d:%02d:%02d.%03d%s\",\n\t\t            (int) parts[DUK_DATE_IDX_HOUR], (int) parts[DUK_DATE_IDX_MINUTE],\n\t\t            (int) parts[DUK_DATE_IDX_SECOND], (int) parts[DUK_DATE_IDX_MILLISECOND],\n\t\t            (const char *) tzstr);\n\t}\n}\n\n/* Helper for string conversion calls: check 'this' binding, get the\n * internal time value, and format date and/or time in a few formats.\n * Return value allows tail calls.\n */\nDUK_LOCAL duk_ret_t duk__to_string_helper(duk_hthread *thr, duk_small_uint_t flags) {\n\tduk_double_t d;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_int_t tzoffset;  /* seconds, doesn't fit into 16 bits */\n\tduk_bool_t rc;\n\tduk_uint8_t buf[DUK_BI_DATE_ISO8601_BUFSIZE];\n\n\tDUK_UNREF(rc);  /* unreferenced with some options */\n\n\td = duk__push_this_get_timeval_tzoffset(thr, flags, &tzoffset);\n\tif (DUK_ISNAN(d)) {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_INVALID_DATE);\n\t\treturn 1;\n\t}\n\tDUK_ASSERT(DUK_ISFINITE(d));\n\n\t/* formatters always get one-based month/day-of-month */\n\tduk_bi_date_timeval_to_parts(d, parts, NULL, DUK_DATE_FLAG_ONEBASED);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_MONTH] >= 1 && parts[DUK_DATE_IDX_MONTH] <= 12);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_DAY] >= 1 && parts[DUK_DATE_IDX_DAY] <= 31);\n\n\tif (flags & DUK_DATE_FLAG_TOSTRING_LOCALE) {\n\t\t/* try locale specific formatter; if it refuses to format the\n\t\t * string, fall back to an ISO 8601 formatted value in local\n\t\t * time.\n\t\t */\n#if defined(DUK_USE_DATE_FORMAT_STRING)\n\t\t/* Contract, either:\n\t\t * - Push string to value stack and return 1\n\t\t * - Don't push anything and return 0\n\t\t */\n\n\t\trc = DUK_USE_DATE_FORMAT_STRING(thr, parts, tzoffset, flags);\n\t\tif (rc != 0) {\n\t\t\treturn 1;\n\t\t}\n#else\n\t\t/* No locale specific formatter; this is OK, we fall back\n\t\t * to ISO 8601.\n\t\t */\n#endif\n\t}\n\n\t/* Different calling convention than above used because the helper\n\t * is shared.\n\t */\n\tduk__format_parts_iso8601(parts, tzoffset, flags, buf);\n\tduk_push_string(thr, (const char *) buf);\n\treturn 1;\n}\n\n/* Helper for component getter calls: check 'this' binding, get the\n * internal time value, split it into parts (either as UTC time or\n * local time), push a specified component as a return value to the\n * value stack and return 1 (caller can then tail call us).\n */\nDUK_LOCAL duk_ret_t duk__get_part_helper(duk_hthread *thr, duk_small_uint_t flags_and_idx) {\n\tduk_double_t d;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_small_uint_t idx_part = (duk_small_uint_t) (flags_and_idx >> DUK_DATE_FLAG_VALUE_SHIFT);  /* unpack args */\n\n\tDUK_ASSERT_DISABLE(idx_part >= 0);  /* unsigned */\n\tDUK_ASSERT(idx_part < DUK_DATE_IDX_NUM_PARTS);\n\n\td = duk__push_this_get_timeval(thr, flags_and_idx);\n\tif (DUK_ISNAN(d)) {\n\t\tduk_push_nan(thr);\n\t\treturn 1;\n\t}\n\tDUK_ASSERT(DUK_ISFINITE(d));\n\n\tduk_bi_date_timeval_to_parts(d, parts, NULL, flags_and_idx);  /* no need to mask idx portion */\n\n\t/* Setter APIs detect special year numbers (0...99) and apply a +1900\n\t * only in certain cases.  The legacy getYear() getter applies -1900\n\t * unconditionally.\n\t */\n\tduk_push_int(thr, (flags_and_idx & DUK_DATE_FLAG_SUB1900) ? parts[idx_part] - 1900 : parts[idx_part]);\n\treturn 1;\n}\n\n/* Helper for component setter calls: check 'this' binding, get the\n * internal time value, split it into parts (either as UTC time or\n * local time), modify one or more components as specified, recompute\n * the time value, set it as the internal value.  Finally, push the\n * new time value as a return value to the value stack and return 1\n * (caller can then tail call us).\n */\nDUK_LOCAL duk_ret_t duk__set_part_helper(duk_hthread *thr, duk_small_uint_t flags_and_maxnargs) {\n\tduk_double_t d;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_idx_t nargs;\n\tduk_small_uint_t maxnargs = (duk_small_uint_t) (flags_and_maxnargs >> DUK_DATE_FLAG_VALUE_SHIFT);  /* unpack args */\n\tduk_small_uint_t idx_first, idx;\n\tduk_small_uint_t i;\n\n\tnargs = duk_get_top(thr);\n\td = duk__push_this_get_timeval(thr, flags_and_maxnargs);\n\tDUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));\n\n\tif (DUK_ISFINITE(d)) {\n\t\tduk_bi_date_timeval_to_parts(d, parts, dparts, flags_and_maxnargs);\n\t} else {\n\t\t/* NaN timevalue: we need to coerce the arguments, but\n\t\t * the resulting internal timestamp needs to remain NaN.\n\t\t * This works but is not pretty: parts and dparts will\n\t\t * be partially uninitialized, but we only write to them.\n\t\t */\n\t}\n\n\t/*\n\t *  Determining which datetime components to overwrite based on\n\t *  stack arguments is a bit complicated, but important to factor\n\t *  out from setters themselves for compactness.\n\t *\n\t *  If DUK_DATE_FLAG_TIMESETTER, maxnargs indicates setter type:\n\t *\n\t *   1 -> millisecond\n\t *   2 -> second, [millisecond]\n\t *   3 -> minute, [second], [millisecond]\n\t *   4 -> hour, [minute], [second], [millisecond]\n\t *\n\t *  Else:\n\t *\n\t *   1 -> date\n\t *   2 -> month, [date]\n\t *   3 -> year, [month], [date]\n\t *\n\t *  By comparing nargs and maxnargs (and flags) we know which\n\t *  components to override.  We rely on part index ordering.\n\t */\n\n\tif (flags_and_maxnargs & DUK_DATE_FLAG_TIMESETTER) {\n\t\tDUK_ASSERT(maxnargs >= 1 && maxnargs <= 4);\n\t\tidx_first = DUK_DATE_IDX_MILLISECOND - (maxnargs - 1);\n\t} else {\n\t\tDUK_ASSERT(maxnargs >= 1 && maxnargs <= 3);\n\t\tidx_first = DUK_DATE_IDX_DAY - (maxnargs - 1);\n\t}\n\tDUK_ASSERT_DISABLE(idx_first >= 0);  /* unsigned */\n\tDUK_ASSERT(idx_first < DUK_DATE_IDX_NUM_PARTS);\n\n\tfor (i = 0; i < maxnargs; i++) {\n\t\tif ((duk_idx_t) i >= nargs) {\n\t\t\t/* no argument given -> leave components untouched */\n\t\t\tbreak;\n\t\t}\n\t\tidx = idx_first + i;\n\t\tDUK_ASSERT_DISABLE(idx >= 0);  /* unsigned */\n\t\tDUK_ASSERT(idx < DUK_DATE_IDX_NUM_PARTS);\n\n\t\tif (idx == DUK_DATE_IDX_YEAR && (flags_and_maxnargs & DUK_DATE_FLAG_YEAR_FIXUP)) {\n\t\t\tduk__twodigit_year_fixup(thr, (duk_idx_t) i);\n\t\t}\n\n\t\tdparts[idx] = duk_to_number(thr, (duk_idx_t) i);\n\n\t\tif (idx == DUK_DATE_IDX_DAY) {\n\t\t\t/* Day-of-month is one-based in the API, but zero-based\n\t\t\t * internally, so fix here.  Note that month is zero-based\n\t\t\t * both in the API and internally.\n\t\t\t */\n\t\t\t/* SCANBUILD: complains about use of uninitialized values.\n\t\t\t * The complaint is correct, but operating in undefined\n\t\t\t * values here is intentional in some cases and the caller\n\t\t\t * ignores the results.\n\t\t\t */\n\t\t\tdparts[idx] -= 1.0;\n\t\t}\n\t}\n\n\t/* Leaves new timevalue on stack top and returns 1, which is correct\n\t * for part setters.\n\t */\n\tif (DUK_ISFINITE(d)) {\n\t\treturn duk__set_this_timeval_from_dparts(thr, dparts, flags_and_maxnargs);\n\t} else {\n\t\t/* Internal timevalue is already NaN, so don't touch it. */\n\t\tduk_push_nan(thr);\n\t\treturn 1;\n\t}\n}\n\n/* Apply ToNumber() to specified index; if ToInteger(val) in [0,99], add\n * 1900 and replace value at idx_val.\n */\nDUK_LOCAL void duk__twodigit_year_fixup(duk_hthread *thr, duk_idx_t idx_val) {\n\tduk_double_t d;\n\n\t/* XXX: idx_val would fit into 16 bits, but using duk_small_uint_t\n\t * might not generate better code due to casting.\n\t */\n\n\t/* E5 Sections 15.9.3.1, B.2.4, B.2.5 */\n\tduk_to_number(thr, idx_val);\n\tif (duk_is_nan(thr, idx_val)) {\n\t\treturn;\n\t}\n\tduk_dup(thr, idx_val);\n\tduk_to_int(thr, -1);\n\td = duk_get_number(thr, -1);  /* get as double to handle huge numbers correctly */\n\tif (d >= 0.0 && d <= 99.0) {\n\t\td += 1900.0;\n\t\tduk_push_number(thr, d);\n\t\tduk_replace(thr, idx_val);\n\t}\n\tduk_pop(thr);\n}\n\n/* Set datetime parts from stack arguments, defaulting any missing values.\n * Day-of-week is not set; it is not required when setting the time value.\n */\nDUK_LOCAL void duk__set_parts_from_args(duk_hthread *thr, duk_double_t *dparts, duk_idx_t nargs) {\n\tduk_double_t d;\n\tduk_small_uint_t i;\n\tduk_small_uint_t idx;\n\n\t/* Causes a ToNumber() coercion, but doesn't break coercion order since\n\t * year is coerced first anyway.\n\t */\n\tduk__twodigit_year_fixup(thr, 0);\n\n\t/* There are at most 7 args, but we use 8 here so that also\n\t * DUK_DATE_IDX_WEEKDAY gets initialized (to zero) to avoid the potential\n\t * for any Valgrind gripes later.\n\t */\n\tfor (i = 0; i < 8; i++) {\n\t\t/* Note: rely on index ordering */\n\t\tidx = DUK_DATE_IDX_YEAR + i;\n\t\tif ((duk_idx_t) i < nargs) {\n\t\t\td = duk_to_number(thr, (duk_idx_t) i);\n\t\t\tif (idx == DUK_DATE_IDX_DAY) {\n\t\t\t\t/* Convert day from one-based to zero-based (internal).  This may\n\t\t\t\t * cause the day part to be negative, which is OK.\n\t\t\t\t */\n\t\t\t\td -= 1.0;\n\t\t\t}\n\t\t} else {\n\t\t\t/* All components default to 0 except day-of-month which defaults\n\t\t\t * to 1.  However, because our internal day-of-month is zero-based,\n\t\t\t * it also defaults to zero here.\n\t\t\t */\n\t\t\td = 0.0;\n\t\t}\n\t\tdparts[idx] = d;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"parts from args -> %lf %lf %lf %lf %lf %lf %lf %lf\",\n\t                     (double) dparts[0], (double) dparts[1],\n\t                     (double) dparts[2], (double) dparts[3],\n\t                     (double) dparts[4], (double) dparts[5],\n\t                     (double) dparts[6], (double) dparts[7]));\n}\n\n/*\n *  Indirect magic value lookup for Date methods.\n *\n *  Date methods don't put their control flags into the function magic value\n *  because they wouldn't fit into a LIGHTFUNC's magic field.  Instead, the\n *  magic value is set to an index pointing to the array of control flags\n *  below.\n *\n *  This must be kept in strict sync with genbuiltins.py!\n */\n\nstatic duk_uint16_t duk__date_magics[] = {\n\t/* 0: toString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 1: toDateString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 2: toTimeString */\n\tDUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 3: toLocaleString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 4: toLocaleDateString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 5: toLocaleTimeString */\n\tDUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_TOSTRING_LOCALE + DUK_DATE_FLAG_LOCALTIME,\n\n\t/* 6: toUTCString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME,\n\n\t/* 7: toISOString */\n\tDUK_DATE_FLAG_TOSTRING_DATE + DUK_DATE_FLAG_TOSTRING_TIME + DUK_DATE_FLAG_NAN_TO_RANGE_ERROR + DUK_DATE_FLAG_SEP_T,\n\n\t/* 8: getFullYear */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 9: getUTCFullYear */\n\t0 + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 10: getMonth */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MONTH << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 11: getUTCMonth */\n\t0 + (DUK_DATE_IDX_MONTH << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 12: getDate */\n\tDUK_DATE_FLAG_ONEBASED + DUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_DAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 13: getUTCDate */\n\tDUK_DATE_FLAG_ONEBASED + (DUK_DATE_IDX_DAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 14: getDay */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_WEEKDAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 15: getUTCDay */\n\t0 + (DUK_DATE_IDX_WEEKDAY << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 16: getHours */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_HOUR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 17: getUTCHours */\n\t0 + (DUK_DATE_IDX_HOUR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 18: getMinutes */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MINUTE << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 19: getUTCMinutes */\n\t0 + (DUK_DATE_IDX_MINUTE << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 20: getSeconds */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_SECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 21: getUTCSeconds */\n\t0 + (DUK_DATE_IDX_SECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 22: getMilliseconds */\n\tDUK_DATE_FLAG_LOCALTIME + (DUK_DATE_IDX_MILLISECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 23: getUTCMilliseconds */\n\t0 + (DUK_DATE_IDX_MILLISECOND << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 24: setMilliseconds */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 25: setUTCMilliseconds */\n\tDUK_DATE_FLAG_TIMESETTER + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 26: setSeconds */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 27: setUTCSeconds */\n\tDUK_DATE_FLAG_TIMESETTER + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 28: setMinutes */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 29: setUTCMinutes */\n\tDUK_DATE_FLAG_TIMESETTER + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 30: setHours */\n\tDUK_DATE_FLAG_TIMESETTER + DUK_DATE_FLAG_LOCALTIME + (4 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 31: setUTCHours */\n\tDUK_DATE_FLAG_TIMESETTER + (4 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 32: setDate */\n\tDUK_DATE_FLAG_LOCALTIME + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 33: setUTCDate */\n\t0 + (1 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 34: setMonth */\n\tDUK_DATE_FLAG_LOCALTIME + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 35: setUTCMonth */\n\t0 + (2 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 36: setFullYear */\n\tDUK_DATE_FLAG_NAN_TO_ZERO + DUK_DATE_FLAG_LOCALTIME + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 37: setUTCFullYear */\n\tDUK_DATE_FLAG_NAN_TO_ZERO + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 38: getYear */\n\tDUK_DATE_FLAG_LOCALTIME + DUK_DATE_FLAG_SUB1900 + (DUK_DATE_IDX_YEAR << DUK_DATE_FLAG_VALUE_SHIFT),\n\n\t/* 39: setYear */\n\tDUK_DATE_FLAG_NAN_TO_ZERO + DUK_DATE_FLAG_YEAR_FIXUP + (3 << DUK_DATE_FLAG_VALUE_SHIFT),\n};\n\nDUK_LOCAL duk_small_uint_t duk__date_get_indirect_magic(duk_hthread *thr) {\n\tduk_small_uint_t magicidx = (duk_small_uint_t) duk_get_current_magic(thr);\n\tDUK_ASSERT(magicidx < (duk_small_int_t) (sizeof(duk__date_magics) / sizeof(duk_uint16_t)));\n\treturn (duk_small_uint_t) duk__date_magics[magicidx];\n}\n\n#if defined(DUK_USE_DATE_BUILTIN)\n/*\n *  Constructor calls\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor(duk_hthread *thr) {\n\tduk_idx_t nargs = duk_get_top(thr);\n\tduk_bool_t is_cons = duk_is_constructor_call(thr);\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t d;\n\n\tDUK_DDD(DUK_DDDPRINT(\"Date constructor, nargs=%ld, is_cons=%ld\", (long) nargs, (long) is_cons));\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DATE),\n\t                              DUK_BIDX_DATE_PROTOTYPE);\n\n\t/* Unlike most built-ins, the internal [[PrimitiveValue]] of a Date\n\t * is mutable.\n\t */\n\n\tif (nargs == 0 || !is_cons) {\n\t\td = duk__timeclip(duk_time_get_ecmascript_time_nofrac(thr));\n\t\tduk_push_number(thr, d);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\t\tif (!is_cons) {\n\t\t\t/* called as a normal function: return new Date().toString() */\n\t\t\tduk_to_string(thr, -1);\n\t\t}\n\t\treturn 1;\n\t} else if (nargs == 1) {\n\t\tconst char *str;\n\t\tduk_to_primitive(thr, 0, DUK_HINT_NONE);\n\t\tstr = duk_get_string_notsymbol(thr, 0);\n\t\tif (str) {\n\t\t\tduk__parse_string(thr, str);\n\t\t\tduk_replace(thr, 0);  /* may be NaN */\n\t\t}\n\t\td = duk__timeclip(duk_to_number(thr, 0));  /* symbols fail here */\n\t\tduk_push_number(thr, d);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\t\treturn 1;\n\t}\n\n\tduk__set_parts_from_args(thr, dparts, nargs);\n\n\t/* Parts are in local time, convert when setting. */\n\n\t(void) duk__set_this_timeval_from_dparts(thr, dparts, DUK_DATE_FLAG_LOCALTIME /*flags*/);  /* -> [ ... this timeval ] */\n\tduk_pop(thr);  /* -> [ ... this ] */\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor_parse(duk_hthread *thr) {\n\treturn duk__parse_string(thr, duk_to_string(thr, 0));\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor_utc(duk_hthread *thr) {\n\tduk_idx_t nargs = duk_get_top(thr);\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t d;\n\n\t/* Behavior for nargs < 2 is implementation dependent: currently we'll\n\t * set a NaN time value (matching V8 behavior) in this case.\n\t */\n\n\tif (nargs < 2) {\n\t\tduk_push_nan(thr);\n\t} else {\n\t\tduk__set_parts_from_args(thr, dparts, nargs);\n\t\td = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);\n\t\tduk_push_number(thr, d);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_constructor_now(duk_hthread *thr) {\n\tduk_double_t d;\n\n\td = duk_time_get_ecmascript_time_nofrac(thr);\n\tDUK_ASSERT(duk__timeclip(d) == d);  /* TimeClip() should never be necessary */\n\tduk_push_number(thr, d);\n\treturn 1;\n}\n\n/*\n *  String/JSON conversions\n *\n *  Human readable conversions are now basically ISO 8601 with a space\n *  (instead of 'T') as the date/time separator.  This is a good baseline\n *  and is platform independent.\n *\n *  A shared native helper to provide many conversions.  Magic value contains\n *  a set of flags.  The helper provides:\n *\n *    toString()\n *    toDateString()\n *    toTimeString()\n *    toLocaleString()\n *    toLocaleDateString()\n *    toLocaleTimeString()\n *    toUTCString()\n *    toISOString()\n *\n *  Notes:\n *\n *    - Date.prototype.toGMTString() and Date.prototype.toUTCString() are\n *      required to be the same ECMAScript function object (!), so it is\n *      omitted from here.\n *\n *    - Date.prototype.toUTCString(): E5.1 specification does not require a\n *      specific format, but result should be human readable.  The\n *      specification suggests using ISO 8601 format with a space (instead\n *      of 'T') separator if a more human readable format is not available.\n *\n *    - Date.prototype.toISOString(): unlike other conversion functions,\n *      toISOString() requires a RangeError for invalid date values.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_tostring_shared(duk_hthread *thr) {\n\tduk_small_uint_t flags = duk__date_get_indirect_magic(thr);\n\treturn duk__to_string_helper(thr, flags);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_value_of(duk_hthread *thr) {\n\t/* This native function is also used for Date.prototype.getTime()\n\t * as their behavior is identical.\n\t */\n\n\tduk_double_t d = duk__push_this_get_timeval(thr, 0 /*flags*/);  /* -> [ this ] */\n\tDUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));\n\tduk_push_number(thr, d);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_to_json(duk_hthread *thr) {\n\t/* Note: toJSON() is a generic function which works even if 'this'\n\t * is not a Date.  The sole argument is ignored.\n\t */\n\n\tduk_push_this(thr);\n\tduk_to_object(thr, -1);\n\n\tduk_dup_top(thr);\n\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);\n\tif (duk_is_number(thr, -1)) {\n\t\tduk_double_t d = duk_get_number(thr, -1);\n\t\tif (!DUK_ISFINITE(d)) {\n\t\t\tduk_push_null(thr);\n\t\t\treturn 1;\n\t\t}\n\t}\n\tduk_pop(thr);\n\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_ISO_STRING);\n\tduk_dup_m2(thr);  /* -> [ O toIsoString O ] */\n\tduk_call_method(thr, 0);\n\treturn 1;\n}\n\n/*\n *  Getters.\n *\n *  Implementing getters is quite easy.  The internal time value is either\n *  NaN, or represents milliseconds (without fractions) from Jan 1, 1970.\n *  The internal time value can be converted to integer parts, and each\n *  part will be normalized and will fit into a 32-bit signed integer.\n *\n *  A shared native helper to provide all getters.  Magic value contains\n *  a set of flags and also packs the date component index argument.  The\n *  helper provides:\n *\n *    getFullYear()\n *    getUTCFullYear()\n *    getMonth()\n *    getUTCMonth()\n *    getDate()\n *    getUTCDate()\n *    getDay()\n *    getUTCDay()\n *    getHours()\n *    getUTCHours()\n *    getMinutes()\n *    getUTCMinutes()\n *    getSeconds()\n *    getUTCSeconds()\n *    getMilliseconds()\n *    getUTCMilliseconds()\n *    getYear()\n *\n *  Notes:\n *\n *    - Date.prototype.getDate(): 'date' means day-of-month, and is\n *      zero-based in internal calculations but public API expects it to\n *      be one-based.\n *\n *    - Date.prototype.getTime() and Date.prototype.valueOf() have identical\n *      behavior.  They have separate function objects, but share the same C\n *      function (duk_bi_date_prototype_value_of).\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_shared(duk_hthread *thr) {\n\tduk_small_uint_t flags_and_idx = duk__date_get_indirect_magic(thr);\n\treturn duk__get_part_helper(thr, flags_and_idx);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_get_timezone_offset(duk_hthread *thr) {\n\t/*\n\t *  Return (t - LocalTime(t)) in minutes:\n\t *\n\t *    t - LocalTime(t) = t - (t + LocalTZA + DaylightSavingTA(t))\n\t *                     = -(LocalTZA + DaylightSavingTA(t))\n\t *\n\t *  where DaylightSavingTA() is checked for time 't'.\n\t *\n\t *  Note that the sign of the result is opposite to common usage,\n\t *  e.g. for EE(S)T which normally is +2h or +3h from UTC, this\n\t *  function returns -120 or -180.\n\t *\n\t */\n\n\tduk_double_t d;\n\tduk_int_t tzoffset;\n\n\t/* Note: DST adjustment is determined using UTC time. */\n\td = duk__push_this_get_timeval(thr, 0 /*flags*/);\n\tDUK_ASSERT(DUK_ISFINITE(d) || DUK_ISNAN(d));\n\tif (DUK_ISNAN(d)) {\n\t\tduk_push_nan(thr);\n\t} else {\n\t\tDUK_ASSERT(DUK_ISFINITE(d));\n\t\ttzoffset = DUK_USE_DATE_GET_LOCAL_TZOFFSET(d);\n\t\tduk_push_int(thr, -tzoffset / 60);\n\t}\n\treturn 1;\n}\n\n/*\n *  Setters.\n *\n *  Setters are a bit more complicated than getters.  Component setters\n *  break down the current time value into its (normalized) component\n *  parts, replace one or more components with -unnormalized- new values,\n *  and the components are then converted back into a time value.  As an\n *  example of using unnormalized values:\n *\n *    var d = new Date(1234567890);\n *\n *  is equivalent to:\n *\n *    var d = new Date(0);\n *    d.setUTCMilliseconds(1234567890);\n *\n *  A shared native helper to provide almost all setters.  Magic value\n *  contains a set of flags and also packs the \"maxnargs\" argument.  The\n *  helper provides:\n *\n *    setMilliseconds()\n *    setUTCMilliseconds()\n *    setSeconds()\n *    setUTCSeconds()\n *    setMinutes()\n *    setUTCMinutes()\n *    setHours()\n *    setUTCHours()\n *    setDate()\n *    setUTCDate()\n *    setMonth()\n *    setUTCMonth()\n *    setFullYear()\n *    setUTCFullYear()\n *    setYear()\n *\n *  Notes:\n *\n *    - Date.prototype.setYear() (Section B addition): special year check\n *      is omitted.  NaN / Infinity will just flow through and ultimately\n *      result in a NaN internal time value.\n *\n *    - Date.prototype.setYear() does not have optional arguments for\n *      setting month and day-in-month (like setFullYear()), but we indicate\n *      'maxnargs' to be 3 to get the year written to the correct component\n *      index in duk__set_part_helper().  The function has nargs == 1, so only\n *      the year will be set regardless of actual argument count.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_shared(duk_hthread *thr) {\n\tduk_small_uint_t flags_and_maxnargs = duk__date_get_indirect_magic(thr);\n\treturn duk__set_part_helper(thr, flags_and_maxnargs);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_set_time(duk_hthread *thr) {\n\tduk_double_t d;\n\n\t(void) duk__push_this_get_timeval(thr, 0 /*flags*/); /* -> [ timeval this ] */\n\td = duk__timeclip(duk_to_number(thr, 0));\n\tduk_push_number(thr, d);\n\tduk_dup_top(thr);\n\t/* Must force write because .setTime() must work even when\n\t * the Date instance is frozen.\n\t */\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_W);\n\t/* -> [ timeval this timeval ] */\n\n\treturn 1;\n}\n\n/*\n *  Misc.\n */\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_date_prototype_toprimitive(duk_hthread *thr) {\n\tduk_size_t hintlen;\n\tconst char *hintstr;\n\tduk_int_t hint;\n\n\t/* Invokes OrdinaryToPrimitive() with suitable hint.  Note that the\n\t * method is generic, and works on non-Date arguments too.\n\t *\n\t * https://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype-@@toprimitive\n\t */\n\n\tduk_push_this(thr);\n\tduk_require_object(thr, -1);\n\tDUK_ASSERT_TOP(thr, 2);\n\n\thintstr = duk_require_lstring(thr, 0, &hintlen);\n\tif ((hintlen == 6 && DUK_STRCMP(hintstr, \"string\") == 0) ||\n\t    (hintlen == 7 && DUK_STRCMP(hintstr, \"default\") == 0)) {\n\t\thint = DUK_HINT_STRING;\n\t} else if (hintlen == 6 && DUK_STRCMP(hintstr, \"number\") == 0) {\n\t\thint = DUK_HINT_NUMBER;\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\tduk_to_primitive_ordinary(thr, -1, hint);\n\treturn 1;\n}\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n\n#endif  /* DUK_USE_DATE_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_date_unix.c",
    "content": "/*\n *  Unix-like Date providers\n *\n *  Generally useful Unix / POSIX / ANSI Date providers.\n */\n\n#include \"duk_internal.h\"\n\n/* The necessary #includes are in place in duk_config.h. */\n\n/* Buffer sizes for some UNIX calls.  Larger than strictly necessary\n * to avoid Valgrind errors.\n */\n#define DUK__STRPTIME_BUF_SIZE  64\n#define DUK__STRFTIME_BUF_SIZE  64\n\n#if defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)\n/* Get current ECMAScript time (= UNIX/Posix time, but in milliseconds). */\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_gettimeofday(void) {\n\tstruct timeval tv;\n\tduk_double_t d;\n\n\tif (gettimeofday(&tv, NULL) != 0) {\n\t\tDUK_D(DUK_DPRINT(\"gettimeofday() failed\"));\n\t\treturn 0.0;\n\t}\n\n\t/* As of Duktape 2.2.0 allow fractions. */\n\td = ((duk_double_t) tv.tv_sec) * 1000.0 +\n\t    ((duk_double_t) tv.tv_usec) / 1000.0;\n\n\treturn d;\n}\n#endif  /* DUK_USE_DATE_NOW_GETTIMEOFDAY */\n\n#if defined(DUK_USE_DATE_NOW_TIME)\n/* Not a very good provider: only full seconds are available. */\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_time(void) {\n\ttime_t t;\n\n\tt = time(NULL);\n\tif (t == (time_t) -1) {\n\t\tDUK_D(DUK_DPRINT(\"time() failed\"));\n\t\treturn 0.0;\n\t}\n\treturn ((duk_double_t) t) * 1000.0;\n}\n#endif  /* DUK_USE_DATE_NOW_TIME */\n\n#if defined(DUK_USE_DATE_TZO_GMTIME) || defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S)\n/* Get local time offset (in seconds) for a certain (UTC) instant 'd'. */\nDUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d) {\n\ttime_t t, t1, t2;\n\tduk_int_t parts[DUK_DATE_IDX_NUM_PARTS];\n\tduk_double_t dparts[DUK_DATE_IDX_NUM_PARTS];\n\tstruct tm tms[2];\n#if defined(DUK_USE_DATE_TZO_GMTIME)\n\tstruct tm *tm_ptr;\n#endif\n\n\t/* For NaN/inf, the return value doesn't matter. */\n\tif (!DUK_ISFINITE(d)) {\n\t\treturn 0;\n\t}\n\n\t/* If not within ECMAScript range, some integer time calculations\n\t * won't work correctly (and some asserts will fail), so bail out\n\t * if so.  This fixes test-bug-date-insane-setyear.js.  There is\n\t * a +/- 24h leeway in this range check to avoid a test262 corner\n\t * case documented in test-bug-date-timeval-edges.js.\n\t */\n\tif (!duk_bi_date_timeval_in_leeway_range(d)) {\n\t\tDUK_DD(DUK_DDPRINT(\"timeval not within valid range, skip tzoffset computation to avoid integer overflows\"));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  This is a bit tricky to implement portably.  The result depends\n\t *  on the timestamp (specifically, DST depends on the timestamp).\n\t *  If e.g. UNIX APIs are used, they'll have portability issues with\n\t *  very small and very large years.\n\t *\n\t *  Current approach:\n\t *\n\t *  - Stay within portable UNIX limits by using equivalent year mapping.\n\t *    Avoid year 1970 and 2038 as some conversions start to fail, at\n\t *    least on some platforms.  Avoiding 1970 means that there are\n\t *    currently DST discrepancies for 1970.\n\t *\n\t *  - Create a UTC and local time breakdowns from 't'.  Then create\n\t *    a time_t using gmtime() and localtime() and compute the time\n\t *    difference between the two.\n\t *\n\t *  Equivalent year mapping (E5 Section 15.9.1.8):\n\t *\n\t *    If the host environment provides functionality for determining\n\t *    daylight saving time, the implementation of ECMAScript is free\n\t *    to map the year in question to an equivalent year (same\n\t *    leap-year-ness and same starting week day for the year) for which\n\t *    the host environment provides daylight saving time information.\n\t *    The only restriction is that all equivalent years should produce\n\t *    the same result.\n\t *\n\t *  This approach is quite reasonable but not entirely correct, e.g.\n\t *  the specification also states (E5 Section 15.9.1.8):\n\t *\n\t *    The implementation of ECMAScript should not try to determine\n\t *    whether the exact time was subject to daylight saving time, but\n\t *    just whether daylight saving time would have been in effect if\n\t *    the _current daylight saving time algorithm_ had been used at the\n\t *    time.  This avoids complications such as taking into account the\n\t *    years that the locale observed daylight saving time year round.\n\t *\n\t *  Since we rely on the platform APIs for conversions between local\n\t *  time and UTC, we can't guarantee the above.  Rather, if the platform\n\t *  has historical DST rules they will be applied.  This seems to be the\n\t *  general preferred direction in ECMAScript standardization (or at least\n\t *  implementations) anyway, and even the equivalent year mapping should\n\t *  be disabled if the platform is known to handle DST properly for the\n\t *  full ECMAScript range.\n\t *\n\t *  The following has useful discussion and links:\n\t *\n\t *    https://bugzilla.mozilla.org/show_bug.cgi?id=351066\n\t */\n\n\tduk_bi_date_timeval_to_parts(d, parts, dparts, DUK_DATE_FLAG_EQUIVYEAR /*flags*/);\n\tDUK_ASSERT(parts[DUK_DATE_IDX_YEAR] >= 1970 && parts[DUK_DATE_IDX_YEAR] <= 2038);\n\n\td = duk_bi_date_get_timeval_from_dparts(dparts, 0 /*flags*/);\n\tDUK_ASSERT(d >= 0 && d < 2147483648.0 * 1000.0);  /* unsigned 31-bit range */\n\tt = (time_t) (d / 1000.0);\n\tDUK_DDD(DUK_DDDPRINT(\"timeval: %lf -> time_t %ld\", (double) d, (long) t));\n\n\tduk_memzero((void *) tms, sizeof(struct tm) * 2);\n\n#if defined(DUK_USE_DATE_TZO_GMTIME_R)\n\t(void) gmtime_r(&t, &tms[0]);\n\t(void) localtime_r(&t, &tms[1]);\n#elif defined(DUK_USE_DATE_TZO_GMTIME_S)\n\t(void) gmtime_s(&t, &tms[0]);\n\t(void) localtime_s(&t, &tms[1]);\n#elif defined(DUK_USE_DATE_TZO_GMTIME)\n\ttm_ptr = gmtime(&t);\n\tduk_memcpy((void *) &tms[0], tm_ptr, sizeof(struct tm));\n\ttm_ptr = localtime(&t);\n\tduk_memcpy((void *) &tms[1], tm_ptr, sizeof(struct tm));\n#else\n#error internal error\n#endif\n\tDUK_DDD(DUK_DDDPRINT(\"gmtime result: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,\"\n\t                     \"wday:%ld,yday:%ld,isdst:%ld}\",\n\t                     (long) tms[0].tm_sec, (long) tms[0].tm_min, (long) tms[0].tm_hour,\n\t                     (long) tms[0].tm_mday, (long) tms[0].tm_mon, (long) tms[0].tm_year,\n\t                     (long) tms[0].tm_wday, (long) tms[0].tm_yday, (long) tms[0].tm_isdst));\n\tDUK_DDD(DUK_DDDPRINT(\"localtime result: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,\"\n\t                     \"wday:%ld,yday:%ld,isdst:%ld}\",\n\t                     (long) tms[1].tm_sec, (long) tms[1].tm_min, (long) tms[1].tm_hour,\n\t                     (long) tms[1].tm_mday, (long) tms[1].tm_mon, (long) tms[1].tm_year,\n\t                     (long) tms[1].tm_wday, (long) tms[1].tm_yday, (long) tms[1].tm_isdst));\n\n\t/* tm_isdst is both an input and an output to mktime(), use 0 to\n\t * avoid DST handling in mktime():\n\t * - https://github.com/svaarala/duktape/issues/406\n\t * - http://stackoverflow.com/questions/8558919/mktime-and-tm-isdst\n\t */\n\ttms[0].tm_isdst = 0;\n\ttms[1].tm_isdst = 0;\n\tt1 = mktime(&tms[0]);  /* UTC */\n\tt2 = mktime(&tms[1]);  /* local */\n\tif (t1 == (time_t) -1 || t2 == (time_t) -1) {\n\t\t/* This check used to be for (t < 0) but on some platforms\n\t\t * time_t is unsigned and apparently the proper way to detect\n\t\t * an mktime() error return is the cast above.  See e.g.:\n\t\t * http://pubs.opengroup.org/onlinepubs/009695299/functions/mktime.html\n\t\t */\n\t\tgoto mktime_error;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"t1=%ld (utc), t2=%ld (local)\", (long) t1, (long) t2));\n\n\t/* Compute final offset in seconds, positive if local time ahead of\n\t * UTC (returned value is UTC-to-local offset).\n\t *\n\t * difftime() returns a double, so coercion to int generates quite\n\t * a lot of code.  Direct subtraction is not portable, however.\n\t * XXX: allow direct subtraction on known platforms.\n\t */\n#if 0\n\treturn (duk_int_t) (t2 - t1);\n#endif\n\treturn (duk_int_t) difftime(t2, t1);\n\n mktime_error:\n\t/* XXX: return something more useful, so that caller can throw? */\n\tDUK_D(DUK_DPRINT(\"mktime() failed, d=%lf\", (double) d));\n\treturn 0;\n}\n#endif  /* DUK_USE_DATE_TZO_GMTIME */\n\n#if defined(DUK_USE_DATE_PRS_STRPTIME)\nDUK_INTERNAL duk_bool_t duk_bi_date_parse_string_strptime(duk_hthread *thr, const char *str) {\n\tstruct tm tm;\n\ttime_t t;\n\tchar buf[DUK__STRPTIME_BUF_SIZE];\n\n\t/* Copy to buffer with slack to avoid Valgrind gripes from strptime. */\n\tDUK_ASSERT(str != NULL);\n\tduk_memzero(buf, sizeof(buf));  /* valgrind whine without this */\n\tDUK_SNPRINTF(buf, sizeof(buf), \"%s\", (const char *) str);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parsing: '%s'\", (const char *) buf));\n\n\tduk_memzero(&tm, sizeof(tm));\n\tif (strptime((const char *) buf, \"%c\", &tm) != NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"before mktime: tm={sec:%ld,min:%ld,hour:%ld,mday:%ld,mon:%ld,year:%ld,\"\n\t\t                     \"wday:%ld,yday:%ld,isdst:%ld}\",\n\t\t                     (long) tm.tm_sec, (long) tm.tm_min, (long) tm.tm_hour,\n\t\t                     (long) tm.tm_mday, (long) tm.tm_mon, (long) tm.tm_year,\n\t\t                     (long) tm.tm_wday, (long) tm.tm_yday, (long) tm.tm_isdst));\n\t\ttm.tm_isdst = -1;  /* negative: dst info not available */\n\n\t\tt = mktime(&tm);\n\t\tDUK_DDD(DUK_DDDPRINT(\"mktime() -> %ld\", (long) t));\n\t\tif (t >= 0) {\n\t\t\tduk_push_number(thr, ((duk_double_t) t) * 1000.0);\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n#endif  /* DUK_USE_DATE_PRS_STRPTIME */\n\n#if defined(DUK_USE_DATE_PRS_GETDATE)\nDUK_INTERNAL duk_bool_t duk_bi_date_parse_string_getdate(duk_hthread *thr, const char *str) {\n\tstruct tm tm;\n\tduk_small_int_t rc;\n\ttime_t t;\n\n\t/* For this to work, DATEMSK must be set, so this is not very\n\t * convenient for an embeddable interpreter.\n\t */\n\n\tduk_memzero(&tm, sizeof(struct tm));\n\trc = (duk_small_int_t) getdate_r(str, &tm);\n\tDUK_DDD(DUK_DDDPRINT(\"getdate_r() -> %ld\", (long) rc));\n\n\tif (rc == 0) {\n\t\tt = mktime(&tm);\n\t\tDUK_DDD(DUK_DDDPRINT(\"mktime() -> %ld\", (long) t));\n\t\tif (t >= 0) {\n\t\t\tduk_push_number(thr, (duk_double_t) t);\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n#endif  /* DUK_USE_DATE_PRS_GETDATE */\n\n#if defined(DUK_USE_DATE_FMT_STRFTIME)\nDUK_INTERNAL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags) {\n\tchar buf[DUK__STRFTIME_BUF_SIZE];\n\tstruct tm tm;\n\tconst char *fmt;\n\n\tDUK_UNREF(tzoffset);\n\n\t/* If the platform doesn't support the entire ECMAScript range, we need\n\t * to return 0 so that the caller can fall back to the default formatter.\n\t *\n\t * For now, assume that if time_t is 8 bytes or more, the whole ECMAScript\n\t * range is supported.  For smaller time_t values (4 bytes in practice),\n\t * assumes that the signed 32-bit range is supported.\n\t *\n\t * XXX: detect this more correctly per platform.  The size of time_t is\n\t * probably not an accurate guarantee of strftime() supporting or not\n\t * supporting a large time range (the full ECMAScript range).\n\t */\n\tif (sizeof(time_t) < 8 &&\n\t    (parts[DUK_DATE_IDX_YEAR] < 1970 || parts[DUK_DATE_IDX_YEAR] > 2037)) {\n\t\t/* be paranoid for 32-bit time values (even avoiding negative ones) */\n\t\treturn 0;\n\t}\n\n\tduk_memzero(&tm, sizeof(tm));\n\ttm.tm_sec = parts[DUK_DATE_IDX_SECOND];\n\ttm.tm_min = parts[DUK_DATE_IDX_MINUTE];\n\ttm.tm_hour = parts[DUK_DATE_IDX_HOUR];\n\ttm.tm_mday = parts[DUK_DATE_IDX_DAY];       /* already one-based */\n\ttm.tm_mon = parts[DUK_DATE_IDX_MONTH] - 1;  /* one-based -> zero-based */\n\ttm.tm_year = parts[DUK_DATE_IDX_YEAR] - 1900;\n\ttm.tm_wday = parts[DUK_DATE_IDX_WEEKDAY];\n\ttm.tm_isdst = 0;\n\n\tduk_memzero(buf, sizeof(buf));\n\tif ((flags & DUK_DATE_FLAG_TOSTRING_DATE) && (flags & DUK_DATE_FLAG_TOSTRING_TIME)) {\n\t\tfmt = \"%c\";\n\t} else if (flags & DUK_DATE_FLAG_TOSTRING_DATE) {\n\t\tfmt = \"%x\";\n\t} else {\n\t\tDUK_ASSERT(flags & DUK_DATE_FLAG_TOSTRING_TIME);\n\t\tfmt = \"%X\";\n\t}\n\t(void) strftime(buf, sizeof(buf) - 1, fmt, &tm);\n\tDUK_ASSERT(buf[sizeof(buf) - 1] == 0);\n\n\tduk_push_string(thr, buf);\n\treturn 1;\n}\n#endif  /* DUK_USE_DATE_FMT_STRFTIME */\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)\nDUK_INTERNAL duk_double_t duk_bi_date_get_monotonic_time_clock_gettime(void) {\n\tstruct timespec ts;\n\n\tif (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {\n\t\treturn (duk_double_t) ts.tv_sec * 1000.0 + (duk_double_t) ts.tv_nsec / 1000000.0;\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"clock_gettime(CLOCK_MONOTONIC) failed\"));\n\t\treturn 0.0;\n\t}\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_date_windows.c",
    "content": "/*\n *  Windows Date providers\n *\n *  Platform specific links:\n *\n *    - http://msdn.microsoft.com/en-us/library/windows/desktop/ms725473(v=vs.85).aspx\n */\n\n#include \"duk_internal.h\"\n\n/* The necessary #includes are in place in duk_config.h. */\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS) || defined(DUK_USE_DATE_TZO_WINDOWS)\n/* Shared Windows helpers. */\nDUK_LOCAL void duk__convert_systime_to_ularge(const SYSTEMTIME *st, ULARGE_INTEGER *res) {\n\tFILETIME ft;\n\tif (SystemTimeToFileTime(st, &ft) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"SystemTimeToFileTime() failed, returning 0\"));\n\t\tres->QuadPart = 0;\n\t} else {\n\t\tres->LowPart = ft.dwLowDateTime;\n\t\tres->HighPart = ft.dwHighDateTime;\n\t}\n}\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\nDUK_LOCAL void duk__convert_filetime_to_ularge(const FILETIME *ft, ULARGE_INTEGER *res) {\n\tres->LowPart = ft->dwLowDateTime;\n\tres->HighPart = ft->dwHighDateTime;\n}\n#endif  /* DUK_USE_DATE_NOW_WINDOWS_SUBMS */\n\nDUK_LOCAL void duk__set_systime_jan1970(SYSTEMTIME *st) {\n\tduk_memzero((void *) st, sizeof(*st));\n\tst->wYear = 1970;\n\tst->wMonth = 1;\n\tst->wDayOfWeek = 4;  /* not sure whether or not needed; Thursday */\n\tst->wDay = 1;\n\tDUK_ASSERT(st->wHour == 0);\n\tDUK_ASSERT(st->wMinute == 0);\n\tDUK_ASSERT(st->wSecond == 0);\n\tDUK_ASSERT(st->wMilliseconds == 0);\n}\n#endif  /* defined(DUK_USE_DATE_NOW_WINDOWS) || defined(DUK_USE_DATE_TZO_WINDOWS) */\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS)\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_windows(void) {\n\t/* Suggested step-by-step method from documentation of RtlTimeToSecondsSince1970:\n\t * http://msdn.microsoft.com/en-us/library/windows/desktop/ms724928(v=vs.85).aspx\n\t */\n\tSYSTEMTIME st1, st2;\n\tULARGE_INTEGER tmp1, tmp2;\n\n\tGetSystemTime(&st1);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1);\n\n\tduk__set_systime_jan1970(&st2);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);\n\n\t/* Difference is in 100ns units, convert to milliseconds, keeping\n\t * fractions since Duktape 2.2.0.  This is only theoretical because\n\t * SYSTEMTIME is limited to milliseconds.\n\t */\n\treturn (duk_double_t) ((LONGLONG) tmp1.QuadPart - (LONGLONG) tmp2.QuadPart) / 10000.0;\n}\n#endif  /* DUK_USE_DATE_NOW_WINDOWS */\n\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\nDUK_INTERNAL duk_double_t duk_bi_date_get_now_windows_subms(void) {\n\t/* Variant of the basic algorithm using GetSystemTimePreciseAsFileTime()\n\t * for more accuracy.\n\t */\n\tFILETIME ft1;\n\tSYSTEMTIME st2;\n\tULARGE_INTEGER tmp1, tmp2;\n\n\tGetSystemTimePreciseAsFileTime(&ft1);\n\tduk__convert_filetime_to_ularge((const FILETIME *) &ft1, &tmp1);\n\n\tduk__set_systime_jan1970(&st2);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);\n\n\t/* Difference is in 100ns units, convert to milliseconds, keeping\n\t * fractions since Duktape 2.2.0.\n\t */\n\treturn (duk_double_t) ((LONGLONG) tmp1.QuadPart - (LONGLONG) tmp2.QuadPart) / 10000.0;\n}\n#endif  /* DUK_USE_DATE_NOW_WINDOWS */\n\n#if defined(DUK_USE_DATE_TZO_WINDOWS)\nDUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d) {\n\tSYSTEMTIME st1;\n\tSYSTEMTIME st2;\n\tSYSTEMTIME st3;\n\tULARGE_INTEGER tmp1;\n\tULARGE_INTEGER tmp2;\n\tULARGE_INTEGER tmp3;\n\tFILETIME ft1;\n\n\t/* XXX: handling of timestamps outside Windows supported range.\n\t * How does Windows deal with dates before 1600?  Does windows\n\t * support all ECMAScript years (like -200000 and +200000)?\n\t * Should equivalent year mapping be used here too?  If so, use\n\t * a shared helper (currently integrated into timeval-to-parts).\n\t */\n\n\t/* Use the approach described in \"Remarks\" of FileTimeToLocalFileTime:\n\t * http://msdn.microsoft.com/en-us/library/windows/desktop/ms724277(v=vs.85).aspx\n\t */\n\n\tduk__set_systime_jan1970(&st1);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1);\n\ttmp2.QuadPart = (ULONGLONG) (d * 10000.0);  /* millisec -> 100ns units since jan 1, 1970 */\n\ttmp2.QuadPart += tmp1.QuadPart;             /* input 'd' in Windows UTC, 100ns units */\n\n\tft1.dwLowDateTime = tmp2.LowPart;\n\tft1.dwHighDateTime = tmp2.HighPart;\n\tif (FileTimeToSystemTime((const FILETIME *) &ft1, &st2) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"FileTimeToSystemTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tif (SystemTimeToTzSpecificLocalTime((LPTIME_ZONE_INFORMATION) NULL, &st2, &st3) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"SystemTimeToTzSpecificLocalTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st3, &tmp3);\n\n\t/* Positive if local time ahead of UTC. */\n\treturn (duk_int_t) (((LONGLONG) tmp3.QuadPart - (LONGLONG) tmp2.QuadPart) / DUK_I64_CONSTANT(10000000));  /* seconds */\n}\n#endif  /* DUK_USE_DATE_TZO_WINDOWS */\n\n#if defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST)\nDUK_INTERNAL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_t d) {\n\tSYSTEMTIME st1;\n\tSYSTEMTIME st2;\n\tFILETIME ft1;\n\tFILETIME ft2;\n\tULARGE_INTEGER tmp1;\n\tULARGE_INTEGER tmp2;\n\n\t/* Do a similar computation to duk_bi_date_get_local_tzoffset_windows\n\t * but without accounting for daylight savings time.  Use this on\n\t * Windows platforms (like Durango) that don't support the\n\t * SystemTimeToTzSpecificLocalTime() call.\n\t */\n\n\t/* current time not needed for this computation */\n\tDUK_UNREF(d);\n\n\tduk__set_systime_jan1970(&st1);\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st1, &tmp1);\n\n\tft1.dwLowDateTime = tmp1.LowPart;\n\tft1.dwHighDateTime = tmp1.HighPart;\n\tif (FileTimeToLocalFileTime((const FILETIME *) &ft1, &ft2) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"FileTimeToLocalFileTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tif (FileTimeToSystemTime((const FILETIME *) &ft2, &st2) == 0) {\n\t\tDUK_D(DUK_DPRINT(\"FileTimeToSystemTime() failed, return tzoffset 0\"));\n\t\treturn 0;\n\t}\n\tduk__convert_systime_to_ularge((const SYSTEMTIME *) &st2, &tmp2);\n\n\treturn (duk_int_t) (((LONGLONG) tmp2.QuadPart - (LONGLONG) tmp1.QuadPart) / DUK_I64_CONSTANT(10000000));  /* seconds */\n}\n#endif  /* DUK_USE_DATE_TZO_WINDOWS_NO_DST */\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC)\nDUK_INTERNAL duk_double_t duk_bi_date_get_monotonic_time_windows_qpc(void) {\n\tLARGE_INTEGER count, freq;\n\n\t/* There are legacy issues with QueryPerformanceCounter():\n\t * - Potential jumps: https://support.microsoft.com/en-us/help/274323/performance-counter-value-may-unexpectedly-leap-forward\n\t * - Differences between cores (XP): https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx#qpc_support_in_windows_versions\n\t *\n\t * We avoid these by enabling QPC by default only for Vista or later.\n\t */\n\n\tif (QueryPerformanceCounter(&count) && QueryPerformanceFrequency(&freq)) {\n\t\t/* XXX: QueryPerformanceFrequency() can be cached */\n\t\treturn (duk_double_t) count.QuadPart / (duk_double_t) freq.QuadPart * 1000.0;\n\t} else {\n\t\t/* MSDN: \"On systems that run Windows XP or later, the function\n\t\t * will always succeed and will thus never return zero.\"\n\t\t * Provide minimal error path just in case user enables this\n\t\t * feature in pre-XP Windows.\n\t\t */\n\t\treturn 0.0;\n\t}\n}\n#endif  /* DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_duktape.c",
    "content": "/*\n *  Duktape built-ins\n *\n *  Size optimization note: it might seem that vararg multipurpose functions\n *  like fin(), enc(), and dec() are not very size optimal, but using a single\n *  user-visible ECMAScript function saves a lot of run-time footprint; each\n *  Function instance takes >100 bytes.  Using a shared native helper and a\n *  'magic' value won't save much if there are multiple Function instances\n *  anyway.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_DUKTAPE_BUILTIN)\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_info(duk_hthread *thr) {\n\tduk_inspect_value(thr, -1);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_act(duk_hthread *thr) {\n\tduk_int_t level;\n\n\tlevel = duk_to_int(thr, 0);\n\tduk_inspect_callstack_entry(thr, level);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_gc(duk_hthread *thr) {\n\tduk_small_uint_t flags;\n\n\tflags = (duk_small_uint_t) duk_get_uint(thr, 0);\n\tduk_heap_mark_and_sweep(thr->heap, flags);\n\n\t/* XXX: Not sure what the best return value would be in the API.\n\t * Return true for now.\n\t */\n\tduk_push_true(thr);\n\treturn 1;\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_fin(duk_hthread *thr) {\n\t(void) duk_require_hobject(thr, 0);\n\tif (duk_get_top(thr) >= 2) {\n\t\t/* Set: currently a finalizer is disabled by setting it to\n\t\t * undefined; this does not remove the property at the moment.\n\t\t * The value could be type checked to be either a function\n\t\t * or something else; if something else, the property could\n\t\t * be deleted.  Must use duk_set_finalizer() to keep\n\t\t * DUK_HOBJECT_FLAG_HAVE_FINALIZER in sync.\n\t\t */\n\t\tduk_set_top(thr, 2);\n\t\tduk_set_finalizer(thr, 0);\n\t\treturn 0;\n\t} else {\n\t\t/* Get. */\n\t\tDUK_ASSERT(duk_get_top(thr) == 1);\n\t\tduk_get_finalizer(thr, 0);\n\t\treturn 1;\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_enc(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\t/* Vararg function: must be careful to check/require arguments.\n\t * The JSON helpers accept invalid indices and treat them like\n\t * non-existent optional parameters.\n\t */\n\n\th_str = duk_require_hstring(thr, 0);  /* Could reject symbols, but no point: won't match comparisons. */\n\tduk_require_valid_index(thr, 1);\n\n\tif (h_str == DUK_HTHREAD_STRING_HEX(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_hex_encode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t} else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_base64_encode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX)\n\t} else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {\n\t\tduk_bi_json_stringify_helper(thr,\n\t\t                             1 /*idx_value*/,\n\t\t                             2 /*idx_replacer*/,\n\t\t                             3 /*idx_space*/,\n\t\t                             DUK_JSON_FLAG_EXT_CUSTOM |\n\t\t                             DUK_JSON_FLAG_ASCII_ONLY |\n\t\t                             DUK_JSON_FLAG_AVOID_KEY_QUOTES /*flags*/);\n#endif\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC)\n\t} else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {\n\t\tduk_bi_json_stringify_helper(thr,\n\t\t                             1 /*idx_value*/,\n\t\t                             2 /*idx_replacer*/,\n\t\t                             3 /*idx_space*/,\n\t\t                             DUK_JSON_FLAG_EXT_COMPATIBLE |\n\t\t                             DUK_JSON_FLAG_ASCII_ONLY /*flags*/);\n#endif\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_dec(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\t/* Vararg function: must be careful to check/require arguments.\n\t * The JSON helpers accept invalid indices and treat them like\n\t * non-existent optional parameters.\n\t */\n\n\th_str = duk_require_hstring(thr, 0);  /* Could reject symbols, but no point: won't match comparisons */\n\tduk_require_valid_index(thr, 1);\n\n\tif (h_str == DUK_HTHREAD_STRING_HEX(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_hex_decode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t} else if (h_str == DUK_HTHREAD_STRING_BASE64(thr)) {\n\t\tduk_set_top(thr, 2);\n\t\tduk_base64_decode(thr, 1);\n\t\tDUK_ASSERT_TOP(thr, 2);\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JX)\n\t} else if (h_str == DUK_HTHREAD_STRING_JX(thr)) {\n\t\tduk_bi_json_parse_helper(thr,\n\t\t                         1 /*idx_value*/,\n\t\t                         2 /*idx_replacer*/,\n\t\t                         DUK_JSON_FLAG_EXT_CUSTOM /*flags*/);\n#endif\n#if defined(DUK_USE_JSON_SUPPORT) && defined(DUK_USE_JC)\n\t} else if (h_str == DUK_HTHREAD_STRING_JC(thr)) {\n\t\tduk_bi_json_parse_helper(thr,\n\t\t                         1 /*idx_value*/,\n\t\t                         2 /*idx_replacer*/,\n\t\t                         DUK_JSON_FLAG_EXT_COMPATIBLE /*flags*/);\n#endif\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\treturn 1;\n}\n\n/*\n *  Compact an object\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_duktape_object_compact(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 1);\n\tduk_compact(thr, 0);\n\treturn 1;  /* return the argument object */\n}\n\n#endif  /* DUK_USE_DUKTAPE_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_encoding.c",
    "content": "/*\n *  WHATWG Encoding API built-ins\n *\n *  API specification: https://encoding.spec.whatwg.org/#api\n *  Web IDL: https://www.w3.org/TR/WebIDL/\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Data structures for encoding/decoding\n */\n\ntypedef struct {\n\tduk_uint8_t *out;      /* where to write next byte(s) */\n\tduk_codepoint_t lead;  /* lead surrogate */\n} duk__encode_context;\n\ntypedef struct {\n\t/* UTF-8 decoding state */\n\tduk_codepoint_t codepoint;  /* built up incrementally */\n\tduk_uint8_t upper;          /* max value of next byte (decode error otherwise) */\n\tduk_uint8_t lower;          /* min value of next byte (ditto) */\n\tduk_uint8_t needed;         /* how many more bytes we need */\n\tduk_uint8_t bom_handled;    /* BOM seen or no longer expected */\n\n\t/* Decoder configuration */\n\tduk_uint8_t fatal;\n\tduk_uint8_t ignore_bom;\n} duk__decode_context;\n\n/* The signed duk_codepoint_t type is used to signal a decoded codepoint\n * (>= 0) or various other states using negative values.\n */\n#define DUK__CP_CONTINUE   (-1)  /* continue to next byte, no completed codepoint */\n#define DUK__CP_ERROR      (-2)  /* decoding error */\n#define DUK__CP_RETRY      (-3)  /* decoding error; retry last byte */\n\n/*\n *  Raw helpers for encoding/decoding\n */\n\n/* Emit UTF-8 (= CESU-8) encoded U+FFFD (replacement char), i.e. ef bf bd. */\nDUK_LOCAL duk_uint8_t *duk__utf8_emit_repl(duk_uint8_t *ptr) {\n\t*ptr++ = 0xef;\n\t*ptr++ = 0xbf;\n\t*ptr++ = 0xbd;\n\treturn ptr;\n}\n\nDUK_LOCAL void duk__utf8_decode_init(duk__decode_context *dec_ctx) {\n\t/* (Re)init the decoding state of 'dec_ctx' but leave decoder\n\t * configuration fields untouched.\n\t */\n\tdec_ctx->codepoint = 0x0000L;\n\tdec_ctx->upper = 0xbf;\n\tdec_ctx->lower = 0x80;\n\tdec_ctx->needed = 0;\n\tdec_ctx->bom_handled = 0;\n}\n\nDUK_LOCAL duk_codepoint_t duk__utf8_decode_next(duk__decode_context *dec_ctx, duk_uint8_t x) {\n\t/*\n\t *  UTF-8 algorithm based on the Encoding specification:\n\t *  https://encoding.spec.whatwg.org/#utf-8-decoder\n\t *\n\t *  Two main states: decoding initial byte vs. decoding continuation\n\t *  bytes.  Shortest length encoding is validated by restricting the\n\t *  allowed range of first continuation byte using 'lower' and 'upper'.\n\t */\n\n\tif (dec_ctx->needed == 0) {\n\t\t/* process initial byte */\n\t\tif (x <= 0x7f) {\n\t\t\t/* U+0000-U+007F, 1 byte (ASCII) */\n\t\t\treturn (duk_codepoint_t) x;\n\t\t} else if (x >= 0xc2 && x <= 0xdf) {\n\t\t\t/* U+0080-U+07FF, 2 bytes */\n\t\t\tdec_ctx->needed = 1;\n\t\t\tdec_ctx->codepoint = x & 0x1f;\n\t\t\tDUK_ASSERT(dec_ctx->lower == 0x80);\n\t\t\tDUK_ASSERT(dec_ctx->upper == 0xbf);\n\t\t\treturn DUK__CP_CONTINUE;\n\t\t} else if (x >= 0xe0 && x <= 0xef) {\n\t\t\t/* U+0800-U+FFFF, 3 bytes */\n\t\t\tif (x == 0xe0) {\n\t\t\t\tdec_ctx->lower = 0xa0;\n\t\t\t\tDUK_ASSERT(dec_ctx->upper == 0xbf);\n\t\t\t} else if (x == 0xed) {\n\t\t\t\tDUK_ASSERT(dec_ctx->lower == 0x80);\n\t\t\t\tdec_ctx->upper = 0x9f;\n\t\t\t}\n\t\t\tdec_ctx->needed = 2;\n\t\t\tdec_ctx->codepoint = x & 0x0f;\n\t\t\treturn DUK__CP_CONTINUE;\n\t\t} else if (x >= 0xf0 && x <= 0xf4) {\n\t\t\t/* U+010000-U+10FFFF, 4 bytes */\n\t\t\tif (x == 0xf0) {\n\t\t\t\tdec_ctx->lower = 0x90;\n\t\t\t\tDUK_ASSERT(dec_ctx->upper == 0xbf);\n\t\t\t} else if (x == 0xf4) {\n\t\t\t\tDUK_ASSERT(dec_ctx->lower == 0x80);\n\t\t\t\tdec_ctx->upper = 0x8f;\n\t\t\t}\n\t\t\tdec_ctx->needed = 3;\n\t\t\tdec_ctx->codepoint = x & 0x07;\n\t\t\treturn DUK__CP_CONTINUE;\n\t\t} else {\n\t\t\t/* not a legal initial byte */\n\t\t\treturn DUK__CP_ERROR;\n\t\t}\n\t} else {\n\t\t/* process continuation byte */\n\t\tif (x >= dec_ctx->lower && x <= dec_ctx->upper) {\n\t\t\tdec_ctx->lower = 0x80;\n\t\t\tdec_ctx->upper = 0xbf;\n\t\t\tdec_ctx->codepoint = (dec_ctx->codepoint << 6) | (x & 0x3f);\n\t\t\tif (--dec_ctx->needed > 0) {\n\t\t\t\t/* need more bytes */\n\t\t\t\treturn DUK__CP_CONTINUE;\n\t\t\t} else {\n\t\t\t\t/* got a codepoint */\n\t\t\t\tduk_codepoint_t ret;\n\t\t\t\tDUK_ASSERT(dec_ctx->codepoint <= 0x10ffffL);  /* Decoding rules guarantee. */\n\t\t\t\tret = dec_ctx->codepoint;\n\t\t\t\tdec_ctx->codepoint = 0x0000L;\n\t\t\t\tdec_ctx->needed = 0;\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} else {\n\t\t\t/* We just encountered an illegal UTF-8 continuation byte.  This might\n\t\t\t * be the initial byte of the next character; if we return a plain\n\t\t\t * error status and the decoder is in replacement mode, the character\n\t\t\t * will be masked.  We still need to alert the caller to the error\n\t\t\t * though.\n\t\t\t */\n\t\t\tdec_ctx->codepoint = 0x0000L;\n\t\t\tdec_ctx->needed = 0;\n\t\t\tdec_ctx->lower = 0x80;\n\t\t\tdec_ctx->upper = 0xbf;\n\t\t\treturn DUK__CP_RETRY;\n\t\t}\n\t}\n}\n\n#if defined(DUK_USE_ENCODING_BUILTINS)\nDUK_LOCAL void duk__utf8_encode_char(void *udata, duk_codepoint_t codepoint) {\n\tduk__encode_context *enc_ctx;\n\n\tDUK_ASSERT(codepoint >= 0);\n\tenc_ctx = (duk__encode_context *) udata;\n\tDUK_ASSERT(enc_ctx != NULL);\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\tif (codepoint <= 0x7f && enc_ctx->lead == 0x0000L) {\n\t\t/* Fast path for ASCII. */\n\t\t*enc_ctx->out++ = (duk_uint8_t) codepoint;\n\t\treturn;\n\t}\n#endif\n\n\tif (DUK_UNLIKELY(codepoint > 0x10ffffL)) {\n\t\t/* cannot legally encode in UTF-8 */\n\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t} else if (codepoint >= 0xd800L && codepoint <= 0xdfffL) {\n\t\tif (codepoint <= 0xdbffL) {\n\t\t\t/* high surrogate */\n\t\t\tduk_codepoint_t prev_lead = enc_ctx->lead;\n\t\t\tenc_ctx->lead = codepoint;\n\t\t\tif (prev_lead == 0x0000L) {\n\t\t\t\t/* high surrogate, no output */\n\t\t\t\treturn;\n\t\t\t} else {\n\t\t\t\t/* consecutive high surrogates, consider first one unpaired */\n\t\t\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\t}\n\t\t} else {\n\t\t\t/* low surrogate */\n\t\t\tif (enc_ctx->lead != 0x0000L) {\n\t\t\t\tcodepoint = (duk_codepoint_t) (0x010000L + ((enc_ctx->lead - 0xd800L) << 10) + (codepoint - 0xdc00L));\n\t\t\t\tenc_ctx->lead = 0x0000L;\n\t\t\t} else {\n\t\t\t\t/* unpaired low surrogate */\n\t\t\t\tDUK_ASSERT(enc_ctx->lead == 0x0000L);\n\t\t\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif (enc_ctx->lead != 0x0000L) {\n\t\t\t/* unpaired high surrogate: emit replacement character and the input codepoint */\n\t\t\tenc_ctx->lead = 0x0000L;\n\t\t\tenc_ctx->out = duk__utf8_emit_repl(enc_ctx->out);\n\t\t}\n\t}\n\n\t/* Codepoint may be original input, a decoded surrogate pair, or may\n\t * have been replaced with U+FFFD.\n\t */\n\tenc_ctx->out += duk_unicode_encode_xutf8((duk_ucodepoint_t) codepoint, enc_ctx->out);\n}\n#endif  /* DUK_USE_ENCODING_BUILTINS */\n\n/* Shared helper for buffer-to-string using a TextDecoder() compatible UTF-8\n * decoder.\n */\nDUK_LOCAL duk_ret_t duk__decode_helper(duk_hthread *thr, duk__decode_context *dec_ctx) {\n\tconst duk_uint8_t *input;\n\tduk_size_t len = 0;\n\tduk_size_t len_tmp;\n\tduk_bool_t stream = 0;\n\tduk_codepoint_t codepoint;\n\tduk_uint8_t *output;\n\tconst duk_uint8_t *in;\n\tduk_uint8_t *out;\n\n\tDUK_ASSERT(dec_ctx != NULL);\n\n\t/* Careful with input buffer pointer: any side effects involving\n\t * code execution (e.g. getters, coercion calls, and finalizers)\n\t * may cause a resize and invalidate a pointer we've read.  This\n\t * is why the pointer is actually looked up at the last minute.\n\t * Argument validation must still happen first to match WHATWG\n\t * required side effect order.\n\t */\n\n\tif (duk_is_undefined(thr, 0)) {\n\t\tduk_push_fixed_buffer_nozero(thr, 0);\n\t\tduk_replace(thr, 0);\n\t}\n\t(void) duk_require_buffer_data(thr, 0, &len);  /* Need 'len', avoid pointer. */\n\n\tif (duk_check_type_mask(thr, 1, DUK_TYPE_MASK_UNDEFINED |\n\t                                DUK_TYPE_MASK_NULL |\n\t                                DUK_TYPE_MASK_NONE)) {\n\t\t/* Use defaults, treat missing value like undefined. */\n\t} else {\n\t\tduk_require_type_mask(thr, 1, DUK_TYPE_MASK_UNDEFINED |\n\t                                      DUK_TYPE_MASK_NULL |\n\t                                      DUK_TYPE_MASK_LIGHTFUNC |\n\t                                      DUK_TYPE_MASK_BUFFER |\n\t\t                              DUK_TYPE_MASK_OBJECT);\n\t\tif (duk_get_prop_literal(thr, 1, \"stream\")) {\n\t\t\tstream = duk_to_boolean(thr, -1);\n\t\t}\n\t}\n\n\t/* Allowance is 3*len in the general case because all bytes may potentially\n\t * become U+FFFD.  If the first byte completes a non-BMP codepoint it will\n\t * decode to a CESU-8 surrogate pair (6 bytes) so we allow 3 extra bytes to\n\t * compensate: (1*3)+3 = 6.  Non-BMP codepoints are safe otherwise because\n\t * the 4->6 expansion is well under the 3x allowance.\n\t *\n\t * XXX: As with TextEncoder, need a better buffer allocation strategy here.\n\t */\n\tif (len >= (DUK_HBUFFER_MAX_BYTELEN / 3) - 3) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_RESULT_TOO_LONG);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\toutput = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, 3 + (3 * len));  /* used parts will be always manually written over */\n\n\tinput = (const duk_uint8_t *) duk_get_buffer_data(thr, 0, &len_tmp);\n\tDUK_ASSERT(input != NULL || len == 0);\n\tif (DUK_UNLIKELY(len != len_tmp)) {\n\t\t/* Very unlikely but possible: source buffer was resized by\n\t\t * a side effect when fixed buffer was pushed.  Output buffer\n\t\t * may not be large enough to hold output, so just fail if\n\t\t * length has changed.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"input buffer resized by side effect, fail\"));\n\t\tgoto fail_type;\n\t}\n\n\t/* From this point onwards it's critical that no side effect occur\n\t * which may disturb 'input': finalizer execution, property accesses,\n\t * active coercions, etc.  Even an allocation related mark-and-sweep\n\t * may affect the pointer because it may trigger a pending finalizer.\n\t */\n\n\tin = input;\n\tout = output;\n\twhile (in < input + len) {\n\t\tcodepoint = duk__utf8_decode_next(dec_ctx, *in++);\n\t\tif (codepoint < 0) {\n\t\t\tif (codepoint == DUK__CP_CONTINUE) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* Decoding error with or without retry. */\n\t\t\tDUK_ASSERT(codepoint == DUK__CP_ERROR || codepoint == DUK__CP_RETRY);\n\t\t\tif (codepoint == DUK__CP_RETRY) {\n\t\t\t\t--in;  /* retry last byte */\n\t\t\t}\n\t\t\t/* replacement mode: replace with U+FFFD */\n\t\t\tcodepoint = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\tif (dec_ctx->fatal) {\n\t\t\t\t/* fatal mode: throw a TypeError */\n\t\t\t\tgoto fail_type;\n\t\t\t}\n\t\t\t/* Continue with 'codepoint', Unicode replacement. */\n\t\t}\n\t\tDUK_ASSERT(codepoint >= 0x0000L && codepoint <= 0x10ffffL);\n\n\t\tif (!dec_ctx->bom_handled) {\n\t\t\tdec_ctx->bom_handled = 1;\n\t\t\tif (codepoint == 0xfeffL && !dec_ctx->ignore_bom) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\tout += duk_unicode_encode_cesu8((duk_ucodepoint_t) codepoint, out);\n\t\tDUK_ASSERT(out <= output + (3 + (3 * len)));\n\t}\n\n\tif (!stream) {\n\t\tif (dec_ctx->needed != 0) {\n\t\t\t/* truncated sequence at end of buffer */\n\t\t\tif (dec_ctx->fatal) {\n\t\t\t\tgoto fail_type;\n\t\t\t} else {\n\t\t\t\tout += duk_unicode_encode_cesu8(DUK_UNICODE_CP_REPLACEMENT_CHARACTER, out);\n\t\t\t\tDUK_ASSERT(out <= output + (3 + (3 * len)));\n\t\t\t}\n\t\t}\n\t\tduk__utf8_decode_init(dec_ctx);  /* Initialize decoding state for potential reuse. */\n\t}\n\n\t/* Output buffer is fixed and thus stable even if there had been\n\t * side effects (which there shouldn't be).\n\t */\n\tduk_push_lstring(thr, (const char *) output, (duk_size_t) (out - output));\n\treturn 1;\n\n fail_type:\n\tDUK_ERROR_TYPE(thr, DUK_STR_UTF8_DECODE_FAILED);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/*\n *  Built-in bindings\n */\n\n#if defined(DUK_USE_ENCODING_BUILTINS)\nDUK_INTERNAL duk_ret_t duk_bi_textencoder_constructor(duk_hthread *thr) {\n\t/* TextEncoder currently requires no persistent state, so the constructor\n\t * does nothing on purpose.\n\t */\n\n\tduk_require_constructor_call(thr);\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encoding_getter(duk_hthread *thr) {\n\tduk_push_literal(thr, \"utf-8\");\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textencoder_prototype_encode(duk_hthread *thr) {\n\tduk__encode_context enc_ctx;\n\tduk_size_t len;\n\tduk_size_t final_len;\n\tduk_uint8_t *output;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tlen = 0;\n\t} else {\n\t\tduk_hstring *h_input;\n\n\t\th_input = duk_to_hstring(thr, 0);\n\t\tDUK_ASSERT(h_input != NULL);\n\n\t\tlen = (duk_size_t) DUK_HSTRING_GET_CHARLEN(h_input);\n\t\tif (len >= DUK_HBUFFER_MAX_BYTELEN / 3) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_RESULT_TOO_LONG);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t}\n\n\t/* Allowance is 3*len because all bytes can potentially be replaced with\n\t * U+FFFD -- which rather inconveniently encodes to 3 bytes in UTF-8.\n\t * Rely on dynamic buffer data pointer stability: no other code has\n\t * access to the data pointer.\n\t *\n\t * XXX: The buffer allocation strategy used here is rather inefficient.\n\t * Maybe switch to a chunk-based strategy, or preprocess the string to\n\t * figure out the space needed ahead of time?\n\t */\n\tDUK_ASSERT(3 * len >= len);\n\toutput = (duk_uint8_t *) duk_push_dynamic_buffer(thr, 3 * len);\n\n\tif (len > 0) {\n\t\tDUK_ASSERT(duk_is_string(thr, 0));  /* True if len > 0. */\n\n\t\t/* XXX: duk_decode_string() is used to process the input\n\t\t * string.  For standard ECMAScript strings, represented\n\t\t * internally as CESU-8, this is fine.  However, behavior\n\t\t * beyond CESU-8 is not very strict: codepoints using an\n\t\t * extended form of UTF-8 are also accepted, and invalid\n\t\t * codepoint sequences (which are allowed in Duktape strings)\n\t\t * are not handled as well as they could (e.g. invalid\n\t\t * continuation bytes may mask following codepoints).\n\t\t * This is how ECMAScript code would also see such strings.\n\t\t * Maybe replace duk_decode_string() with an explicit strict\n\t\t * CESU-8 decoder here?\n\t\t */\n\t\tenc_ctx.lead = 0x0000L;\n\t\tenc_ctx.out = output;\n\t\tduk_decode_string(thr, 0, duk__utf8_encode_char, (void *) &enc_ctx);\n\t\tif (enc_ctx.lead != 0x0000L) {\n\t\t\t/* unpaired high surrogate at end of string */\n\t\t\tenc_ctx.out = duk__utf8_emit_repl(enc_ctx.out);\n\t\t\tDUK_ASSERT(enc_ctx.out <= output + (3 * len));\n\t\t}\n\n\t\t/* The output buffer is usually very much oversized, so shrink it to\n\t\t * actually needed size.  Pointer stability assumed up to this point.\n\t\t */\n\t\tDUK_ASSERT_TOP(thr, 2);\n\t\tDUK_ASSERT(output == (duk_uint8_t *) duk_get_buffer_data(thr, -1, NULL));\n\n\t\tfinal_len = (duk_size_t) (enc_ctx.out - output);\n\t\tduk_resize_buffer(thr, -1, final_len);\n\t\t/* 'output' and 'enc_ctx.out' are potentially invalidated by the resize. */\n\t} else {\n\t\tfinal_len = 0;\n\t}\n\n\t/* Standard WHATWG output is a Uint8Array.  Here the Uint8Array will\n\t * be backed by a dynamic buffer which differs from e.g. Uint8Arrays\n\t * created as 'new Uint8Array(N)'.  ECMAScript code won't see the\n\t * difference but C code will.  When bufferobjects are not supported,\n\t * returns a plain dynamic buffer.\n\t */\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tduk_push_buffer_object(thr, -1, 0, final_len, DUK_BUFOBJ_UINT8ARRAY);\n#endif\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textdecoder_constructor(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\tduk_bool_t fatal = 0;\n\tduk_bool_t ignore_bom = 0;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_require_constructor_call(thr);\n\tif (!duk_is_undefined(thr, 0)) {\n\t\t/* XXX: For now ignore 'label' (encoding identifier). */\n\t\tduk_to_string(thr, 0);\n\t}\n\tif (!duk_is_null_or_undefined(thr, 1)) {\n\t\tif (duk_get_prop_literal(thr, 1, \"fatal\")) {\n\t\t\tfatal = duk_to_boolean(thr, -1);\n\t\t}\n\t\tif (duk_get_prop_literal(thr, 1, \"ignoreBOM\")) {\n\t\t\tignore_bom = duk_to_boolean(thr, -1);\n\t\t}\n\t}\n\n\tduk_push_this(thr);\n\n\t/* The decode context is not assumed to be zeroed; all fields are\n\t * initialized explicitly.\n\t */\n\tdec_ctx = (duk__decode_context *) duk_push_fixed_buffer(thr, sizeof(duk__decode_context));\n\tdec_ctx->fatal = (duk_uint8_t) fatal;\n\tdec_ctx->ignore_bom = (duk_uint8_t) ignore_bom;\n\tduk__utf8_decode_init(dec_ctx);  /* Initializes remaining fields. */\n\n\tduk_put_prop_literal(thr, -2, DUK_INTERNAL_SYMBOL(\"Context\"));\n\treturn 0;\n}\n\n/* Get TextDecoder context from 'this'; leaves garbage on stack. */\nDUK_LOCAL duk__decode_context *duk__get_textdecoder_context(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\tduk_push_this(thr);\n\tduk_get_prop_literal(thr, -1, DUK_INTERNAL_SYMBOL(\"Context\"));\n\tdec_ctx = (duk__decode_context *) duk_require_buffer(thr, -1, NULL);\n\tDUK_ASSERT(dec_ctx != NULL);\n\treturn dec_ctx;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\tduk_int_t magic;\n\n\tdec_ctx = duk__get_textdecoder_context(thr);\n\tmagic = duk_get_current_magic(thr);\n\tswitch (magic) {\n\tcase 0:\n\t\t/* Encoding is now fixed, so _Context lookup is only needed to\n\t\t * validate the 'this' binding (TypeError if not TextDecoder-like).\n\t\t */\n\t\tduk_push_literal(thr, \"utf-8\");\n\t\tbreak;\n\tcase 1:\n\t\tduk_push_boolean(thr, dec_ctx->fatal);\n\t\tbreak;\n\tdefault:\n\t\tduk_push_boolean(thr, dec_ctx->ignore_bom);\n\t\tbreak;\n\t}\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_hthread *thr) {\n\tduk__decode_context *dec_ctx;\n\n\tdec_ctx = duk__get_textdecoder_context(thr);\n\treturn duk__decode_helper(thr, dec_ctx);\n}\n#endif  /* DUK_USE_ENCODING_BUILTINS */\n\n/*\n *  Internal helper for Node.js Buffer\n */\n\n/* Internal helper used for Node.js Buffer .toString().  Value stack convention\n * is currently odd: it mimics TextDecoder .decode() so that argument must be at\n * index 0, and decode options (not present for Buffer) at index 1.  Return value\n * is a Duktape/C function return value.\n */\nDUK_INTERNAL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_hthread *thr) {\n\tduk__decode_context dec_ctx;\n\n\tdec_ctx.fatal = 0;  /* use replacement chars */\n\tdec_ctx.ignore_bom = 1;  /* ignore BOMs (matches Node.js Buffer .toString()) */\n\tduk__utf8_decode_init(&dec_ctx);\n\n\treturn duk__decode_helper(thr, &dec_ctx);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_error.c",
    "content": "/*\n *  Error built-ins\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL duk_ret_t duk_bi_error_constructor_shared(duk_hthread *thr) {\n\t/* Behavior for constructor and non-constructor call is\n\t * the same except for augmenting the created error.  When\n\t * called as a constructor, the caller (duk_new()) will handle\n\t * augmentation; when called as normal function, we need to do\n\t * it here.\n\t */\n\n\tduk_small_int_t bidx_prototype = duk_get_current_magic(thr);\n\n\t/* same for both error and each subclass like TypeError */\n\tduk_uint_t flags_and_class = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                             DUK_HOBJECT_FLAG_FASTREFS |\n\t                             DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ERROR);\n\n\t(void) duk_push_object_helper(thr, flags_and_class, bidx_prototype);\n\n\t/* If message is undefined, the own property 'message' is not set at\n\t * all to save property space.  An empty message is inherited anyway.\n\t */\n\tif (!duk_is_undefined(thr, 0)) {\n\t\tduk_to_string(thr, 0);\n\t\tduk_dup_0(thr);  /* [ message error message ] */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE, DUK_PROPDESC_FLAGS_WC);\n\t}\n\n\t/* Augment the error if called as a normal function.  __FILE__ and __LINE__\n\t * are not desirable in this case.\n\t */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tif (!duk_is_constructor_call(thr)) {\n\t\tduk_err_augment_error_create(thr, thr, NULL, 0, DUK_AUGMENT_FLAG_NOBLAME_FILELINE);\n\t}\n#endif\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_to_string(duk_hthread *thr) {\n\t/* XXX: optimize with more direct internal access */\n\n\tduk_push_this(thr);\n\t(void) duk_require_hobject_promote_mask(thr, -1, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\n\t/* [ ... this ] */\n\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME);\n\tif (duk_is_undefined(thr, -1)) {\n\t\tduk_pop(thr);\n\t\tduk_push_literal(thr, \"Error\");\n\t} else {\n\t\tduk_to_string(thr, -1);\n\t}\n\n\t/* [ ... this name ] */\n\n\t/* XXX: Are steps 6 and 7 in E5 Section 15.11.4.4 duplicated by\n\t * accident or are they actually needed?  The first ToString()\n\t * could conceivably return 'undefined'.\n\t */\n\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE);\n\tif (duk_is_undefined(thr, -1)) {\n\t\tduk_pop(thr);\n\t\tduk_push_hstring_empty(thr);\n\t} else {\n\t\tduk_to_string(thr, -1);\n\t}\n\n\t/* [ ... this name message ] */\n\n\tif (duk_get_length(thr, -2) == 0) {\n\t\t/* name is empty -> return message */\n\t\treturn 1;\n\t}\n\tif (duk_get_length(thr, -1) == 0) {\n\t\t/* message is empty -> return name */\n\t\tduk_pop(thr);\n\t\treturn 1;\n\t}\n\tduk_push_literal(thr, \": \");\n\tduk_insert(thr, -2);  /* ... name ': ' message */\n\tduk_concat(thr, 3);\n\n\treturn 1;\n}\n\n#if defined(DUK_USE_TRACEBACKS)\n\n/*\n *  Traceback handling\n *\n *  The unified helper decodes the traceback and produces various requested\n *  outputs.  It should be optimized for size, and may leave garbage on stack,\n *  only the topmost return value matters.  For instance, traceback separator\n *  and decoded strings are pushed even when looking for filename only.\n *\n *  NOTE: although _Tracedata is an internal property, user code can currently\n *  write to the array (or replace it with something other than an array).\n *  The code below must tolerate arbitrary _Tracedata.  It can throw errors\n *  etc, but cannot cause a segfault or memory unsafe behavior.\n */\n\n/* constants arbitrary, chosen for small loads */\n#define DUK__OUTPUT_TYPE_TRACEBACK   (-1)\n#define DUK__OUTPUT_TYPE_FILENAME    0\n#define DUK__OUTPUT_TYPE_LINENUMBER  1\n\nDUK_LOCAL duk_ret_t duk__error_getter_helper(duk_hthread *thr, duk_small_int_t output_type) {\n\tduk_idx_t idx_td;\n\tduk_small_int_t i;  /* traceback depth fits into 16 bits */\n\tduk_small_int_t t;  /* stack type fits into 16 bits */\n\tduk_small_int_t count_func = 0;  /* traceback depth ensures fits into 16 bits */\n\tconst char *str_tailcall = \" tailcall\";\n\tconst char *str_strict = \" strict\";\n\tconst char *str_construct = \" construct\";\n\tconst char *str_prevyield = \" preventsyield\";\n\tconst char *str_directeval = \" directeval\";\n\tconst char *str_empty = \"\";\n\n\tDUK_ASSERT_TOP(thr, 0);  /* fixed arg count */\n\n\tduk_push_this(thr);\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_TRACEDATA);\n\tidx_td = duk_get_top_index(thr);\n\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_NEWLINE_4SPACE);\n\tduk_push_this(thr);\n\n\t/* [ ... this tracedata sep this ] */\n\n\t/* XXX: skip null filename? */\n\n\tif (duk_check_type(thr, idx_td, DUK_TYPE_OBJECT)) {\n\t\t/* Current tracedata contains 2 entries per callstack entry. */\n\t\tfor (i = 0; ; i += 2) {\n\t\t\tduk_int_t pc;\n\t\t\tduk_uint_t line;\n\t\t\tduk_uint_t flags;\n\t\t\tduk_double_t d;\n\t\t\tconst char *funcname;\n\t\t\tconst char *filename;\n\t\t\tduk_hobject *h_func;\n\t\t\tduk_hstring *h_name;\n\n\t\t\tduk_require_stack(thr, 5);\n\t\t\tduk_get_prop_index(thr, idx_td, (duk_uarridx_t) i);\n\t\t\tduk_get_prop_index(thr, idx_td, (duk_uarridx_t) (i + 1));\n\t\t\td = duk_to_number_m1(thr);\n\t\t\tpc = duk_double_to_int_t(DUK_FMOD(d, DUK_DOUBLE_2TO32));\n\t\t\tflags = duk_double_to_uint_t(DUK_FLOOR(d / DUK_DOUBLE_2TO32));\n\t\t\tt = (duk_small_int_t) duk_get_type(thr, -2);\n\n\t\t\tif (t == DUK_TYPE_OBJECT || t == DUK_TYPE_LIGHTFUNC) {\n\t\t\t\t/*\n\t\t\t\t *  ECMAScript/native function call or lightfunc call\n\t\t\t\t */\n\n\t\t\t\tcount_func++;\n\n\t\t\t\t/* [ ... v1(func) v2(pc+flags) ] */\n\n\t\t\t\t/* These may be systematically omitted by Duktape\n\t\t\t\t * with certain config options, but allow user to\n\t\t\t\t * set them on a case-by-case basis.\n\t\t\t\t */\n\t\t\t\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME);\n\t\t\t\tduk_get_prop_stridx_short(thr, -3, DUK_STRIDX_FILE_NAME);\n\n#if defined(DUK_USE_PC2LINE)\n\t\t\t\tline = (duk_uint_t) duk_hobject_pc2line_query(thr, -4, (duk_uint_fast32_t) pc);\n#else\n\t\t\t\tline = 0;\n#endif\n\n\t\t\t\t/* [ ... v1 v2 name filename ] */\n\n\t\t\t\t/* When looking for .fileName/.lineNumber, blame first\n\t\t\t\t * function which has a .fileName.\n\t\t\t\t */\n\t\t\t\tif (duk_is_string_notsymbol(thr, -1)) {\n\t\t\t\t\tif (output_type == DUK__OUTPUT_TYPE_FILENAME) {\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t} else if (output_type == DUK__OUTPUT_TYPE_LINENUMBER) {\n\t\t\t\t\t\tduk_push_uint(thr, line);\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* XXX: Change 'anon' handling here too, to use empty string for anonymous functions? */\n\t\t\t\t/* XXX: Could be improved by coercing to a readable duk_tval (especially string escaping) */\n\t\t\t\th_name = duk_get_hstring_notsymbol(thr, -2);  /* may be NULL */\n\t\t\t\tfuncname = (h_name == NULL || h_name == DUK_HTHREAD_STRING_EMPTY_STRING(thr)) ?\n\t\t\t\t           \"[anon]\" : (const char *) DUK_HSTRING_GET_DATA(h_name);\n\t\t\t\tfilename = duk_get_string_notsymbol(thr, -1);\n\t\t\t\tfilename = filename ? filename : \"\";\n\t\t\t\tDUK_ASSERT(funcname != NULL);\n\t\t\t\tDUK_ASSERT(filename != NULL);\n\n\t\t\t\th_func = duk_get_hobject(thr, -4);  /* NULL for lightfunc */\n\n\t\t\t\tif (h_func == NULL) {\n\t\t\t\t\tduk_push_sprintf(thr, \"at %s light%s%s%s%s%s\",\n\t\t\t\t\t                 (const char *) funcname,\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));\n\t\t\t\t} else if (DUK_HOBJECT_HAS_NATFUNC(h_func)) {\n\t\t\t\t\tduk_push_sprintf(thr, \"at %s (%s) native%s%s%s%s%s\",\n\t\t\t\t\t                 (const char *) funcname,\n\t\t\t\t\t                 (const char *) filename,\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));\n\t\t\t\t} else {\n\t\t\t\t\tduk_push_sprintf(thr, \"at %s (%s:%lu)%s%s%s%s%s\",\n\t\t\t\t\t                 (const char *) funcname,\n\t\t\t\t\t                 (const char *) filename,\n\t\t\t\t\t                 (unsigned long) line,\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcall : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_DIRECT_EVAL) ? str_directeval : str_empty),\n\t\t\t\t\t                 (const char *) ((flags & DUK_ACT_FLAG_PREVENT_YIELD) ? str_prevyield : str_empty));\n\t\t\t\t}\n\t\t\t\tduk_replace(thr, -5);   /* [ ... v1 v2 name filename str ] -> [ ... str v2 name filename ] */\n\t\t\t\tduk_pop_3(thr);         /* -> [ ... str ] */\n\t\t\t} else if (t == DUK_TYPE_STRING) {\n\t\t\t\tconst char *str_file;\n\n\t\t\t\t/*\n\t\t\t\t *  __FILE__ / __LINE__ entry, here 'pc' is line number directly.\n\t\t\t\t *  Sometimes __FILE__ / __LINE__ is reported as the source for\n\t\t\t\t *  the error (fileName, lineNumber), sometimes not.\n\t\t\t\t */\n\n\t\t\t\t/* [ ... v1(filename) v2(line+flags) ] */\n\n\t\t\t\t/* When looking for .fileName/.lineNumber, blame compilation\n\t\t\t\t * or C call site unless flagged not to do so.\n\t\t\t\t */\n\t\t\t\tif (!(flags & DUK_TB_FLAG_NOBLAME_FILELINE)) {\n\t\t\t\t\tif (output_type == DUK__OUTPUT_TYPE_FILENAME) {\n\t\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t} else if (output_type == DUK__OUTPUT_TYPE_LINENUMBER) {\n\t\t\t\t\t\tduk_push_int(thr, pc);\n\t\t\t\t\t\treturn 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* Tracedata is trusted but avoid any risk of using a NULL\n\t\t\t\t * for %s format because it has undefined behavior.  Symbols\n\t\t\t\t * don't need to be explicitly rejected as they pose no memory\n\t\t\t\t * safety issues.\n\t\t\t\t */\n\t\t\t\tstr_file = (const char *) duk_get_string(thr, -2);\n\t\t\t\tduk_push_sprintf(thr, \"at [anon] (%s:%ld) internal\",\n\t\t\t\t                 (const char *) (str_file ? str_file : \"null\"), (long) pc);\n\t\t\t\tduk_replace(thr, -3);  /* [ ... v1 v2 str ] -> [ ... str v2 ] */\n\t\t\t\tduk_pop(thr);          /* -> [ ... str ] */\n\t\t\t} else {\n\t\t\t\t/* unknown, ignore */\n\t\t\t\tduk_pop_2(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (count_func >= DUK_USE_TRACEBACK_DEPTH) {\n\t\t\t/* Possibly truncated; there is no explicit truncation\n\t\t\t * marker so this is the best we can do.\n\t\t\t */\n\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_BRACKETED_ELLIPSIS);\n\t\t}\n\t}\n\n\t/* [ ... this tracedata sep this str1 ... strN ] */\n\n\tif (output_type != DUK__OUTPUT_TYPE_TRACEBACK) {\n\t\treturn 0;\n\t} else {\n\t\t/* The 'this' after 'sep' will get ToString() coerced by\n\t\t * duk_join() automatically.  We don't want to do that\n\t\t * coercion when providing .fileName or .lineNumber (GH-254).\n\t\t */\n\t\tduk_join(thr, duk_get_top(thr) - (idx_td + 2) /*count, not including sep*/);\n\t\treturn 1;\n\t}\n}\n\n/* XXX: Output type could be encoded into native function 'magic' value to\n * save space.  For setters the stridx could be encoded into 'magic'.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter(duk_hthread *thr) {\n\treturn duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_TRACEBACK);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter(duk_hthread *thr) {\n\treturn duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_FILENAME);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_hthread *thr) {\n\treturn duk__error_getter_helper(thr, DUK__OUTPUT_TYPE_LINENUMBER);\n}\n\n#else  /* DUK_USE_TRACEBACKS */\n\n/*\n *  Traceback handling when tracebacks disabled.\n *\n *  The fileName / lineNumber stubs are now necessary because built-in\n *  data will include the accessor properties in Error.prototype.  If those\n *  are removed for builds without tracebacks, these can also be removed.\n *  'stack' should still be present and produce a ToString() equivalent:\n *  this is useful for user code which prints a stacktrace and expects to\n *  see something useful.  A normal stacktrace also begins with a ToString()\n *  of the error so this makes sense.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_getter(duk_hthread *thr) {\n\t/* XXX: remove this native function and map 'stack' accessor\n\t * to the toString() implementation directly.\n\t */\n\treturn duk_bi_error_prototype_to_string(thr);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_getter(duk_hthread *thr) {\n\tDUK_UNREF(thr);\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_hthread *thr) {\n\tDUK_UNREF(thr);\n\treturn 0;\n}\n\n#endif  /* DUK_USE_TRACEBACKS */\n\nDUK_LOCAL duk_ret_t duk__error_setter_helper(duk_hthread *thr, duk_small_uint_t stridx_key) {\n\t/* Attempt to write 'stack', 'fileName', 'lineNumber' works as if\n\t * user code called Object.defineProperty() to create an overriding\n\t * own property.  This allows user code to overwrite .fileName etc\n\t * intuitively as e.g. \"err.fileName = 'dummy'\" as one might expect.\n\t * See https://github.com/svaarala/duktape/issues/387.\n\t */\n\n\tDUK_ASSERT_TOP(thr, 1);  /* fixed arg count: value */\n\n\tduk_push_this(thr);\n\tduk_push_hstring_stridx(thr, stridx_key);\n\tduk_dup_0(thr);\n\n\t/* [ ... obj key value ] */\n\n\tDUK_DD(DUK_DDPRINT(\"error setter: %!T %!T %!T\",\n\t                   duk_get_tval(thr, -3), duk_get_tval(thr, -2), duk_get_tval(thr, -1)));\n\n\tduk_def_prop(thr, -3, DUK_DEFPROP_HAVE_VALUE |\n\t                      DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE |\n\t                      DUK_DEFPROP_HAVE_ENUMERABLE | /*not enumerable*/\n\t                      DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE);\n\treturn 0;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_stack_setter(duk_hthread *thr) {\n\treturn duk__error_setter_helper(thr, DUK_STRIDX_STACK);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_filename_setter(duk_hthread *thr) {\n\treturn duk__error_setter_helper(thr, DUK_STRIDX_FILE_NAME);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_error_prototype_linenumber_setter(duk_hthread *thr) {\n\treturn duk__error_setter_helper(thr, DUK_STRIDX_LINE_NUMBER);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_function.c",
    "content": "/*\n *  Function built-ins\n */\n\n#include \"duk_internal.h\"\n\n/* Needed even when Function built-in is disabled. */\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype(duk_hthread *thr) {\n\t/* ignore arguments, return undefined (E5 Section 15.3.4) */\n\tDUK_UNREF(thr);\n\treturn 0;\n}\n\n#if defined(DUK_USE_FUNCTION_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_function_constructor(duk_hthread *thr) {\n\tduk_hstring *h_sourcecode;\n\tduk_idx_t nargs;\n\tduk_idx_t i;\n\tduk_small_uint_t comp_flags;\n\tduk_hcompfunc *func;\n\tduk_hobject *outer_lex_env;\n\tduk_hobject *outer_var_env;\n\n\t/* normal and constructor calls have identical semantics */\n\n\tnargs = duk_get_top(thr);\n\tfor (i = 0; i < nargs; i++) {\n\t\tduk_to_string(thr, i);  /* Rejects Symbols during coercion. */\n\t}\n\n\tif (nargs == 0) {\n\t\tduk_push_hstring_empty(thr);\n\t\tduk_push_hstring_empty(thr);\n\t} else if (nargs == 1) {\n\t\t/* XXX: cover this with the generic >1 case? */\n\t\tduk_push_hstring_empty(thr);\n\t} else {\n\t\tduk_insert(thr, 0);   /* [ arg1 ... argN-1 body] -> [body arg1 ... argN-1] */\n\t\tduk_push_literal(thr, \",\");\n\t\tduk_insert(thr, 1);\n\t\tduk_join(thr, nargs - 1);\n\t}\n\n\t/* [ body formals ], formals is comma separated list that needs to be parsed */\n\n\tDUK_ASSERT_TOP(thr, 2);\n\n\t/* XXX: this placeholder is not always correct, but use for now.\n\t * It will fail in corner cases; see test-dev-func-cons-args.js.\n\t */\n\tduk_push_literal(thr, \"function(\");\n\tduk_dup_1(thr);\n\tduk_push_literal(thr, \"){\");\n\tduk_dup_0(thr);\n\tduk_push_literal(thr, \"\\n}\");  /* Newline is important to handle trailing // comment. */\n\tduk_concat(thr, 5);\n\n\t/* [ body formals source ] */\n\n\tDUK_ASSERT_TOP(thr, 3);\n\n\t/* strictness is not inherited, intentional */\n\tcomp_flags = DUK_COMPILE_FUNCEXPR;\n\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_COMPILE);  /* XXX: copy from caller? */  /* XXX: ignored now */\n\th_sourcecode = duk_require_hstring(thr, -2);  /* no symbol check needed; -2 is concat'd code */\n\tduk_js_compile(thr,\n\t               (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_sourcecode),\n\t               (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sourcecode),\n\t               comp_flags);\n\n\t/* Force .name to 'anonymous' (ES2015). */\n\tduk_push_literal(thr, \"anonymous\");\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n\n\tfunc = (duk_hcompfunc *) duk_known_hobject(thr, -1);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) func));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) func));\n\n\t/* [ body formals source template ] */\n\n\t/* only outer_lex_env matters, as functions always get a new\n\t * variable declaration environment.\n\t */\n\n\touter_lex_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\touter_var_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\n\tduk_js_push_closure(thr, func, outer_var_env, outer_lex_env, 1 /*add_auto_proto*/);\n\n\t/* [ body formals source template closure ] */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_FUNCTION_BUILTIN */\n\n#if defined(DUK_USE_FUNCTION_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_to_string(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\t/*\n\t *  E5 Section 15.3.4.2 places few requirements on the output of\n\t *  this function: the result is implementation dependent, must\n\t *  follow FunctionDeclaration syntax (in particular, must have a\n\t *  name even for anonymous functions or functions with empty name).\n\t *  The output does NOT need to compile into anything useful.\n\t *\n\t *  E6 Section 19.2.3.5 changes the requirements completely: the\n\t *  result must either eval() to a functionally equivalent object\n\t *  OR eval() to a SyntaxError.\n\t *\n\t *  We opt for the SyntaxError approach for now, with a syntax that\n\t *  mimics V8's native function syntax:\n\t *\n\t *      'function cos() { [native code] }'\n\t *\n\t *  but extended with [ecmascript code], [bound code], and\n\t *  [lightfunc code].\n\t */\n\n\tduk_push_this(thr);\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *obj = DUK_TVAL_GET_OBJECT(tv);\n\t\tconst char *func_name;\n\n\t\t/* Function name: missing/undefined is mapped to empty string,\n\t\t * otherwise coerce to string.  No handling for invalid identifier\n\t\t * characters or e.g. '{' in the function name.  This doesn't\n\t\t * really matter as long as a SyntaxError results.  Technically\n\t\t * if the name contained a suitable prefix followed by '//' it\n\t\t * might cause the result to parse without error.\n\t\t */\n\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME);\n\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\tfunc_name = \"\";\n\t\t} else {\n\t\t\tfunc_name = duk_to_string(thr, -1);\n\t\t\tDUK_ASSERT(func_name != NULL);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(obj)) {\n\t\t\tduk_push_sprintf(thr, \"function %s() { [ecmascript code] }\", (const char *) func_name);\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(obj)) {\n\t\t\tduk_push_sprintf(thr, \"function %s() { [native code] }\", (const char *) func_name);\n\t\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(obj)) {\n\t\t\tduk_push_sprintf(thr, \"function %s() { [bound code] }\", (const char *) func_name);\n\t\t} else {\n\t\t\tgoto type_error;\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_push_lightfunc_tostring(thr, tv);\n\t} else {\n\t\tgoto type_error;\n\t}\n\n\treturn 1;\n\n type_error:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n#endif\n\n/* Always present because the native function pointer is needed in call\n * handling.\n */\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_call(duk_hthread *thr) {\n\t/* .call() is dealt with in call handling by simulating its\n\t * effects so this function is actually never called.\n\t */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_apply(duk_hthread *thr) {\n\t/* Like .call(), never actually called. */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_apply(duk_hthread *thr) {\n\t/* Like .call(), never actually called. */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_construct(duk_hthread *thr) {\n\t/* Like .call(), never actually called. */\n\tDUK_UNREF(thr);\n\treturn DUK_RET_TYPE_ERROR;\n}\n\n#if defined(DUK_USE_FUNCTION_BUILTIN)\n/* Create a bound function which points to a target function which may\n * be bound or non-bound.  If the target is bound, the argument lists\n * and 'this' binding of the functions are merged and the resulting\n * function points directly to the non-bound target.\n */\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_bind(duk_hthread *thr) {\n\tduk_hboundfunc *h_bound;\n\tduk_idx_t nargs;  /* bound args, not counting 'this' binding */\n\tduk_idx_t bound_nargs;\n\tduk_int_t bound_len;\n\tduk_tval *tv_prevbound;\n\tduk_idx_t n_prevbound;\n\tduk_tval *tv_res;\n\tduk_tval *tv_tmp;\n\n\t/* XXX: C API call, e.g. duk_push_bound_function(thr, target_idx, nargs); */\n\n\t/* Vararg function, careful arg handling, e.g. thisArg may not\n\t * be present.\n\t */\n\tnargs = duk_get_top(thr) - 1;  /* actual args, not counting 'this' binding */\n\tif (nargs < 0) {\n\t\tnargs++;\n\t\tduk_push_undefined(thr);\n\t}\n\tDUK_ASSERT(nargs >= 0);\n\n\t/* Limit 'nargs' for bound functions to guarantee arithmetic\n\t * below will never wrap.\n\t */\n\tif (nargs > (duk_idx_t) DUK_HBOUNDFUNC_MAX_ARGS) {\n\t\tDUK_DCERROR_RANGE_INVALID_COUNT(thr);\n\t}\n\n\tduk_push_this(thr);\n\tduk_require_callable(thr, -1);\n\n\t/* [ thisArg arg1 ... argN func ]  (thisArg+args == nargs+1 total) */\n\tDUK_ASSERT_TOP(thr, nargs + 2);\n\n\t/* Create bound function object. */\n\th_bound = duk_push_hboundfunc(thr);\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&h_bound->target));\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&h_bound->this_binding));\n\tDUK_ASSERT(h_bound->args == NULL);\n\tDUK_ASSERT(h_bound->nargs == 0);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_bound) == NULL);\n\n\t/* [ thisArg arg1 ... argN func boundFunc ] */\n\n\t/* If the target is a bound function, argument lists must be\n\t * merged.  The 'this' binding closest to the target function\n\t * wins because in call handling the 'this' gets replaced over\n\t * and over again until we call the non-bound function.\n\t */\n\ttv_prevbound = NULL;\n\tn_prevbound = 0;\n\ttv_tmp = DUK_GET_TVAL_POSIDX(thr, 0);\n\tDUK_TVAL_SET_TVAL(&h_bound->this_binding, tv_tmp);\n\ttv_tmp = DUK_GET_TVAL_NEGIDX(thr, -2);\n\tDUK_TVAL_SET_TVAL(&h_bound->target, tv_tmp);\n\n\tif (DUK_TVAL_IS_OBJECT(tv_tmp)) {\n\t\tduk_hobject *h_target;\n\t\tduk_hobject *bound_proto;\n\n\t\th_target = DUK_TVAL_GET_OBJECT(tv_tmp);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(h_target));\n\n\t\t/* Internal prototype must be copied from the target.\n\t\t * For lightfuncs Function.prototype is used and is already\n\t\t * in place.\n\t\t */\n\t\tbound_proto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_target);\n\t\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) h_bound, bound_proto);\n\n\t\t/* The 'strict' flag is copied to get the special [[Get]] of E5.1\n\t\t * Section 15.3.5.4 to apply when a 'caller' value is a strict bound\n\t\t * function.  Not sure if this is correct, because the specification\n\t\t * is a bit ambiguous on this point but it would make sense.\n\t\t */\n\t\t/* Strictness is inherited from target. */\n\t\tif (DUK_HOBJECT_HAS_STRICT(h_target)) {\n\t\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_bound);\n\t\t}\n\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(h_target)) {\n\t\t\tduk_hboundfunc *h_boundtarget;\n\n\t\t\th_boundtarget = (duk_hboundfunc *) (void *) h_target;\n\n\t\t\t/* The final function should always be non-bound, unless\n\t\t\t * there's a bug in the internals.  Assert for it.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(&h_boundtarget->target) ||\n\t\t\t           (DUK_TVAL_IS_OBJECT(&h_boundtarget->target) &&\n\t\t\t            DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(&h_boundtarget->target)) &&\n\t\t\t            !DUK_HOBJECT_IS_BOUNDFUNC(DUK_TVAL_GET_OBJECT(&h_boundtarget->target))));\n\n\t\t\tDUK_TVAL_SET_TVAL(&h_bound->target, &h_boundtarget->target);\n\t\t\tDUK_TVAL_SET_TVAL(&h_bound->this_binding, &h_boundtarget->this_binding);\n\n\t\t\ttv_prevbound = h_boundtarget->args;\n\t\t\tn_prevbound = h_boundtarget->nargs;\n\t\t}\n\t} else {\n\t\t/* Lightfuncs are always strict. */\n\t\tduk_hobject *bound_proto;\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_tmp));\n\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_bound);\n\t\tbound_proto = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];\n\t\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) h_bound, bound_proto);\n\t}\n\n\tDUK_TVAL_INCREF(thr, &h_bound->target);  /* old values undefined, no decref needed */\n\tDUK_TVAL_INCREF(thr, &h_bound->this_binding);\n\n\tbound_nargs = n_prevbound + nargs;\n\tif (bound_nargs > (duk_idx_t) DUK_HBOUNDFUNC_MAX_ARGS) {\n\t\tDUK_DCERROR_RANGE_INVALID_COUNT(thr);\n\t}\n\ttv_res = (duk_tval *) DUK_ALLOC_CHECKED(thr, ((duk_size_t) bound_nargs) * sizeof(duk_tval));\n\tDUK_ASSERT(tv_res != NULL || bound_nargs == 0);\n\tDUK_ASSERT(h_bound->args == NULL);\n\tDUK_ASSERT(h_bound->nargs == 0);\n\th_bound->args = tv_res;\n\th_bound->nargs = bound_nargs;\n\n\tDUK_ASSERT(n_prevbound >= 0);\n\tduk_copy_tvals_incref(thr, tv_res, tv_prevbound, (duk_size_t) n_prevbound);\n\tDUK_ASSERT(nargs >= 0);\n\tduk_copy_tvals_incref(thr, tv_res + n_prevbound, DUK_GET_TVAL_POSIDX(thr, 1), (duk_size_t) nargs);\n\n\t/* [ thisArg arg1 ... argN func boundFunc ] */\n\n\t/* Bound function 'length' property is interesting.\n\t * For lightfuncs, simply read the virtual property.\n\t */\n\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH);\n\tbound_len = duk_get_int(thr, -1);  /* ES2015: no coercion */\n\tif (bound_len < nargs) {\n\t\tbound_len = 0;\n\t} else {\n\t\tbound_len -= nargs;\n\t}\n\tif (sizeof(duk_int_t) > 4 && bound_len > (duk_int_t) DUK_UINT32_MAX) {\n\t\tbound_len = (duk_int_t) DUK_UINT32_MAX;\n\t}\n\tduk_pop(thr);\n\tDUK_ASSERT(bound_len >= 0);\n\ttv_tmp = thr->valstack_top++;\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv_tmp));\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv_tmp));\n\tDUK_TVAL_SET_U32(tv_tmp, (duk_uint32_t) bound_len);  /* in-place update, fastint */\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);  /* attrs in E6 Section 9.2.4 */\n\n\t/* XXX: could these be virtual? */\n\t/* Caller and arguments must use the same thrower, [[ThrowTypeError]]. */\n\tduk_xdef_prop_stridx_thrower(thr, -1, DUK_STRIDX_CALLER);\n\tduk_xdef_prop_stridx_thrower(thr, -1, DUK_STRIDX_LC_ARGUMENTS);\n\n\t/* Function name and fileName (non-standard). */\n\tduk_push_literal(thr, \"bound \");  /* ES2015 19.2.3.2. */\n\tduk_get_prop_stridx(thr, -3, DUK_STRIDX_NAME);\n\tif (!duk_is_string_notsymbol(thr, -1)) {\n\t\t/* ES2015 has requirement to check that .name of target is a string\n\t\t * (also must check for Symbol); if not, targetName should be the\n\t\t * empty string.  ES2015 19.2.3.2.\n\t\t */\n\t\tduk_pop(thr);\n\t\tduk_push_hstring_empty(thr);\n\t}\n\tduk_concat(thr, 2);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C);\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"created bound function: %!iT\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\treturn 1;\n}\n#endif  /* DUK_USE_FUNCTION_BUILTIN */\n\n/* %NativeFunctionPrototype% .length getter. */\nDUK_INTERNAL duk_ret_t duk_bi_native_function_length(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hnatfunc *h;\n\tduk_int16_t func_nargs;\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = (duk_hnatfunc *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (!DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h)) {\n\t\t\tgoto fail_type;\n\t\t}\n\t\tfunc_nargs = h->nargs;\n\t\tduk_push_int(thr, func_nargs == DUK_HNATFUNC_NARGS_VARARGS ? 0 : func_nargs);\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_small_uint_t lf_flags;\n\t\tduk_small_uint_t lf_len;\n\n\t\tlf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv);\n\t\tlf_len = DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags);\n\t\tduk_push_uint(thr, lf_len);\n\t} else {\n\t\tgoto fail_type;\n\t}\n\treturn 1;\n\n fail_type:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n\n/* %NativeFunctionPrototype% .name getter. */\nDUK_INTERNAL duk_ret_t duk_bi_native_function_name(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_hnatfunc *h;\n\n\ttv = duk_get_borrowed_this_tval(thr);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = (duk_hnatfunc *) DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (!DUK_HOBJECT_IS_NATFUNC((duk_hobject *) h)) {\n\t\t\tgoto fail_type;\n\t\t}\n#if 0\n\t\tduk_push_hnatfunc_name(thr, h);\n#endif\n\t\tduk_push_hstring_empty(thr);\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv)) {\n\t\tduk_push_lightfunc_name(thr, tv);\n\t} else {\n\t\tgoto fail_type;\n\t}\n\treturn 1;\n\n fail_type:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_function_prototype_hasinstance(duk_hthread *thr) {\n\t/* This binding: RHS, stack index 0: LHS. */\n\tduk_bool_t ret;\n\n\tret = duk_js_instanceof_ordinary(thr, DUK_GET_TVAL_POSIDX(thr, 0), DUK_GET_THIS_TVAL_PTR(thr));\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_global.c",
    "content": "/*\n *  Global object built-ins\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Encoding/decoding helpers\n */\n\n/* XXX: Could add fast path (for each transform callback) with direct byte\n * lookups (no shifting) and no explicit check for x < 0x80 before table\n * lookup.\n */\n\n/* Macros for creating and checking bitmasks for character encoding.\n * Bit number is a bit counterintuitive, but minimizes code size.\n */\n#define DUK__MKBITS(a,b,c,d,e,f,g,h)  ((duk_uint8_t) ( \\\n\t((a) << 0) | ((b) << 1) | ((c) << 2) | ((d) << 3) | \\\n\t((e) << 4) | ((f) << 5) | ((g) << 6) | ((h) << 7) \\\n\t))\n#define DUK__CHECK_BITMASK(table,cp)  ((table)[(cp) >> 3] & (1 << ((cp) & 0x07)))\n\n/* E5.1 Section 15.1.3.3: uriReserved + uriUnescaped + '#' */\nDUK_LOCAL const duk_uint8_t duk__encode_uriunescaped_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 1, 0, 1, 1, 0, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x20-0x2f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 0, 1, 0, 1),  /* 0x30-0x3f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x40-0x4f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x60-0x6f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 1, 0),  /* 0x70-0x7f */\n};\n\n/* E5.1 Section 15.1.3.4: uriUnescaped */\nDUK_LOCAL const duk_uint8_t duk__encode_uricomponent_unescaped_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 1, 0, 0, 0, 0, 0, 1), DUK__MKBITS(1, 1, 1, 0, 0, 1, 1, 0),  /* 0x20-0x2f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 0, 0, 0, 0, 0, 0),  /* 0x30-0x3f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x40-0x4f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x60-0x6f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 1, 0),  /* 0x70-0x7f */\n};\n\n/* E5.1 Section 15.1.3.1: uriReserved + '#' */\nDUK_LOCAL const duk_uint8_t duk__decode_uri_reserved_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 0, 0, 1, 1, 0, 1, 0), DUK__MKBITS(0, 0, 0, 1, 1, 0, 0, 1),  /* 0x20-0x2f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 1, 1, 0, 1, 0, 1),  /* 0x30-0x3f */\n\tDUK__MKBITS(1, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x40-0x4f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x60-0x6f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x70-0x7f */\n};\n\n/* E5.1 Section 15.1.3.2: empty */\nDUK_LOCAL const duk_uint8_t duk__decode_uri_component_reserved_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x20-0x2f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x30-0x3f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x40-0x4f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x60-0x6f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x70-0x7f */\n};\n\n#if defined(DUK_USE_SECTION_B)\n/* E5.1 Section B.2.2, step 7. */\nDUK_LOCAL const duk_uint8_t duk__escape_unescaped_table[16] = {\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x00-0x0f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0),  /* 0x10-0x1f */\n\tDUK__MKBITS(0, 0, 0, 0, 0, 0, 0, 0), DUK__MKBITS(0, 0, 1, 1, 0, 1, 1, 1),  /* 0x20-0x2f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 0, 0, 0, 0, 0, 0),  /* 0x30-0x3f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x40-0x4f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 1),  /* 0x50-0x5f */\n\tDUK__MKBITS(0, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1),  /* 0x60-0x6f */\n\tDUK__MKBITS(1, 1, 1, 1, 1, 1, 1, 1), DUK__MKBITS(1, 1, 1, 0, 0, 0, 0, 0)   /* 0x70-0x7f */\n};\n#endif  /* DUK_USE_SECTION_B */\n\ntypedef struct {\n\tduk_hthread *thr;\n\tduk_hstring *h_str;\n\tduk_bufwriter_ctx bw;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p_end;\n} duk__transform_context;\n\ntypedef void (*duk__transform_callback)(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp);\n\n/* XXX: refactor and share with other code */\nDUK_LOCAL duk_small_int_t duk__decode_hex_escape(const duk_uint8_t *p, duk_small_int_t n) {\n\tduk_small_int_t ch;\n\tduk_small_int_t t = 0;\n\n\twhile (n > 0) {\n\t\tt = t * 16;\n\t\tch = (duk_small_int_t) duk_hex_dectab[*p++];\n\t\tif (DUK_LIKELY(ch >= 0)) {\n\t\t\tt += ch;\n\t\t} else {\n\t\t\treturn -1;\n\t\t}\n\t\tn--;\n\t}\n\treturn t;\n}\n\nDUK_LOCAL int duk__transform_helper(duk_hthread *thr, duk__transform_callback callback, const void *udata) {\n\tduk__transform_context tfm_ctx_alloc;\n\tduk__transform_context *tfm_ctx = &tfm_ctx_alloc;\n\tduk_codepoint_t cp;\n\n\ttfm_ctx->thr = thr;\n\n\ttfm_ctx->h_str = duk_to_hstring(thr, 0);\n\tDUK_ASSERT(tfm_ctx->h_str != NULL);\n\n\tDUK_BW_INIT_PUSHBUF(thr, &tfm_ctx->bw, DUK_HSTRING_GET_BYTELEN(tfm_ctx->h_str));  /* initial size guess */\n\n\ttfm_ctx->p_start = DUK_HSTRING_GET_DATA(tfm_ctx->h_str);\n\ttfm_ctx->p_end = tfm_ctx->p_start + DUK_HSTRING_GET_BYTELEN(tfm_ctx->h_str);\n\ttfm_ctx->p = tfm_ctx->p_start;\n\n\twhile (tfm_ctx->p < tfm_ctx->p_end) {\n\t\tcp = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &tfm_ctx->p, tfm_ctx->p_start, tfm_ctx->p_end);\n\t\tcallback(tfm_ctx, udata, cp);\n\t}\n\n\tDUK_BW_COMPACT(thr, &tfm_ctx->bw);\n\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if transform is safe. */\n\treturn 1;\n}\n\nDUK_LOCAL void duk__transform_callback_encode_uri(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tduk_uint8_t xutf8_buf[DUK_UNICODE_MAX_XUTF8_LENGTH];\n\tduk_small_int_t len;\n\tduk_codepoint_t cp1, cp2;\n\tduk_small_int_t i, t;\n\tconst duk_uint8_t *unescaped_table = (const duk_uint8_t *) udata;\n\n\t/* UTF-8 encoded bytes escaped as %xx%xx%xx... -> 3 * nbytes.\n\t * Codepoint range is restricted so this is a slightly too large\n\t * but doesn't matter.\n\t */\n\tDUK_BW_ENSURE(tfm_ctx->thr, &tfm_ctx->bw, 3 * DUK_UNICODE_MAX_XUTF8_LENGTH);\n\n\tif (cp < 0) {\n\t\tgoto uri_error;\n\t} else if ((cp < 0x80L) && DUK__CHECK_BITMASK(unescaped_table, cp)) {\n\t\tDUK_BW_WRITE_RAW_U8(tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t) cp);\n\t\treturn;\n\t} else if (cp >= 0xdc00L && cp <= 0xdfffL) {\n\t\tgoto uri_error;\n\t} else if (cp >= 0xd800L && cp <= 0xdbffL) {\n\t\t/* Needs lookahead */\n\t\tif (duk_unicode_decode_xutf8(tfm_ctx->thr, &tfm_ctx->p, tfm_ctx->p_start, tfm_ctx->p_end, (duk_ucodepoint_t *) &cp2) == 0) {\n\t\t\tgoto uri_error;\n\t\t}\n\t\tif (!(cp2 >= 0xdc00L && cp2 <= 0xdfffL)) {\n\t\t\tgoto uri_error;\n\t\t}\n\t\tcp1 = cp;\n\t\tcp = (duk_codepoint_t) (((cp1 - 0xd800L) << 10) + (cp2 - 0xdc00L) + 0x10000L);\n\t} else if (cp > 0x10ffffL) {\n\t\t/* Although we can allow non-BMP characters (they'll decode\n\t\t * back into surrogate pairs), we don't allow extended UTF-8\n\t\t * characters; they would encode to URIs which won't decode\n\t\t * back because of strict UTF-8 checks in URI decoding.\n\t\t * (However, we could just as well allow them here.)\n\t\t */\n\t\tgoto uri_error;\n\t} else {\n\t\t/* Non-BMP characters within valid UTF-8 range: encode as is.\n\t\t * They'll decode back into surrogate pairs if the escaped\n\t\t * output is decoded.\n\t\t */\n\t\t;\n\t}\n\n\tlen = duk_unicode_encode_xutf8((duk_ucodepoint_t) cp, xutf8_buf);\n\tfor (i = 0; i < len; i++) {\n\t\tt = (duk_small_int_t) xutf8_buf[i];\n\t\tDUK_BW_WRITE_RAW_U8_3(tfm_ctx->thr,\n\t\t                      &tfm_ctx->bw,\n\t\t                      DUK_ASC_PERCENT,\n\t\t                      (duk_uint8_t) duk_uc_nybbles[t >> 4],\n                                      (duk_uint8_t) duk_uc_nybbles[t & 0x0f]);\n\t}\n\n\treturn;\n\n uri_error:\n\tDUK_ERROR_URI(tfm_ctx->thr, DUK_STR_INVALID_INPUT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__transform_callback_decode_uri(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tconst duk_uint8_t *reserved_table = (const duk_uint8_t *) udata;\n\tduk_small_uint_t utf8_blen;\n\tduk_codepoint_t min_cp;\n\tduk_small_int_t t;  /* must be signed */\n\tduk_small_uint_t i;\n\n\t/* Maximum write size: XUTF8 path writes max DUK_UNICODE_MAX_XUTF8_LENGTH,\n\t * percent escape path writes max two times CESU-8 encoded BMP length.\n\t */\n\tDUK_BW_ENSURE(tfm_ctx->thr,\n\t              &tfm_ctx->bw,\n\t              (DUK_UNICODE_MAX_XUTF8_LENGTH >= 2 * DUK_UNICODE_MAX_CESU8_BMP_LENGTH ?\n\t              DUK_UNICODE_MAX_XUTF8_LENGTH : DUK_UNICODE_MAX_CESU8_BMP_LENGTH));\n\n\tif (cp == (duk_codepoint_t) '%') {\n\t\tconst duk_uint8_t *p = tfm_ctx->p;\n\t\tduk_size_t left = (duk_size_t) (tfm_ctx->p_end - p);  /* bytes left */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"percent encoding, left=%ld\", (long) left));\n\n\t\tif (left < 2) {\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tt = duk__decode_hex_escape(p, 2);\n\t\tDUK_DDD(DUK_DDDPRINT(\"first byte: %ld\", (long) t));\n\t\tif (t < 0) {\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tif (t < 0x80) {\n\t\t\tif (DUK__CHECK_BITMASK(reserved_table, t)) {\n\t\t\t\t/* decode '%xx' to '%xx' if decoded char in reserved set */\n\t\t\t\tDUK_ASSERT(tfm_ctx->p - 1 >= tfm_ctx->p_start);\n\t\t\t\tDUK_BW_WRITE_RAW_U8_3(tfm_ctx->thr,\n\t\t\t\t                      &tfm_ctx->bw,\n\t\t\t\t                      DUK_ASC_PERCENT,\n\t\t\t\t                      p[0],\n\t\t\t\t                      p[1]);\n\t\t\t} else {\n\t\t\t\tDUK_BW_WRITE_RAW_U8(tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t) t);\n\t\t\t}\n\t\t\ttfm_ctx->p += 2;\n\t\t\treturn;\n\t\t}\n\n\t\t/* Decode UTF-8 codepoint from a sequence of hex escapes.  The\n\t\t * first byte of the sequence has been decoded to 't'.\n\t\t *\n\t\t * Note that UTF-8 validation must be strict according to the\n\t\t * specification: E5.1 Section 15.1.3, decode algorithm step\n\t\t * 4.d.vii.8.  URIError from non-shortest encodings is also\n\t\t * specifically noted in the spec.\n\t\t */\n\n\t\tDUK_ASSERT(t >= 0x80);\n\t\tif (t < 0xc0) {\n\t\t\t/* continuation byte */\n\t\t\tgoto uri_error;\n\t\t} else if (t < 0xe0) {\n\t\t\t/* 110x xxxx; 2 bytes */\n\t\t\tutf8_blen = 2;\n\t\t\tmin_cp = 0x80L;\n\t\t\tcp = t & 0x1f;\n\t\t} else if (t < 0xf0) {\n\t\t\t/* 1110 xxxx; 3 bytes */\n\t\t\tutf8_blen = 3;\n\t\t\tmin_cp = 0x800L;\n\t\t\tcp = t & 0x0f;\n\t\t} else if (t < 0xf8) {\n\t\t\t/* 1111 0xxx; 4 bytes */\n\t\t\tutf8_blen = 4;\n\t\t\tmin_cp = 0x10000L;\n\t\t\tcp = t & 0x07;\n\t\t} else {\n\t\t\t/* extended utf-8 not allowed for URIs */\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tif (left < utf8_blen * 3 - 1) {\n\t\t\t/* '%xx%xx...%xx', p points to char after first '%' */\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\tp += 3;\n\t\tfor (i = 1; i < utf8_blen; i++) {\n\t\t\t/* p points to digit part ('%xy', p points to 'x') */\n\t\t\tt = duk__decode_hex_escape(p, 2);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"i=%ld utf8_blen=%ld cp=%ld t=0x%02lx\",\n\t\t\t                     (long) i, (long) utf8_blen, (long) cp, (unsigned long) t));\n\t\t\tif (t < 0) {\n\t\t\t\tgoto uri_error;\n\t\t\t}\n\t\t\tif ((t & 0xc0) != 0x80) {\n\t\t\t\tgoto uri_error;\n\t\t\t}\n\t\t\tcp = (cp << 6) + (t & 0x3f);\n\t\t\tp += 3;\n\t\t}\n\t\tp--;  /* p overshoots */\n\t\ttfm_ctx->p = p;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"final cp=%ld, min_cp=%ld\", (long) cp, (long) min_cp));\n\n\t\tif (cp < min_cp || cp > 0x10ffffL || (cp >= 0xd800L && cp <= 0xdfffL)) {\n\t\t\tgoto uri_error;\n\t\t}\n\n\t\t/* The E5.1 algorithm checks whether or not a decoded codepoint\n\t\t * is below 0x80 and perhaps may be in the \"reserved\" set.\n\t\t * This seems pointless because the single byte UTF-8 case is\n\t\t * handled separately, and non-shortest encodings are rejected.\n\t\t * So, 'cp' cannot be below 0x80 here, and thus cannot be in\n\t\t * the reserved set.\n\t\t */\n\n\t\t/* utf-8 validation ensures these */\n\t\tDUK_ASSERT(cp >= 0x80L && cp <= 0x10ffffL);\n\n\t\tif (cp >= 0x10000L) {\n\t\t\tcp -= 0x10000L;\n\t\t\tDUK_ASSERT(cp < 0x100000L);\n\n\t\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, ((cp >> 10) + 0xd800L));\n\t\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, ((cp & 0x03ffL) + 0xdc00L));\n\t\t} else {\n\t\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp);\n\t\t}\n\t} else {\n\t\tDUK_BW_WRITE_RAW_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp);\n\t}\n\treturn;\n\n uri_error:\n\tDUK_ERROR_URI(tfm_ctx->thr, DUK_STR_INVALID_INPUT);\n\tDUK_WO_NORETURN(return;);\n}\n\n#if defined(DUK_USE_SECTION_B)\nDUK_LOCAL void duk__transform_callback_escape(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tDUK_UNREF(udata);\n\n\tDUK_BW_ENSURE(tfm_ctx->thr, &tfm_ctx->bw, 6);\n\n\tif (cp < 0) {\n\t\tgoto esc_error;\n\t} else if ((cp < 0x80L) && DUK__CHECK_BITMASK(duk__escape_unescaped_table, cp)) {\n\t\tDUK_BW_WRITE_RAW_U8(tfm_ctx->thr, &tfm_ctx->bw, (duk_uint8_t) cp);\n\t} else if (cp < 0x100L) {\n\t\tDUK_BW_WRITE_RAW_U8_3(tfm_ctx->thr,\n\t\t                      &tfm_ctx->bw,\n\t\t                      (duk_uint8_t) DUK_ASC_PERCENT,\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp >> 4],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp & 0x0f]);\n\t} else if (cp < 0x10000L) {\n\t\tDUK_BW_WRITE_RAW_U8_6(tfm_ctx->thr,\n\t\t                      &tfm_ctx->bw,\n\t\t                      (duk_uint8_t) DUK_ASC_PERCENT,\n\t\t                      (duk_uint8_t) DUK_ASC_LC_U,\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp >> 12],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[(cp >> 8) & 0x0f],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[(cp >> 4) & 0x0f],\n\t\t                      (duk_uint8_t) duk_uc_nybbles[cp & 0x0f]);\n\t} else {\n\t\t/* Characters outside BMP cannot be escape()'d.  We could\n\t\t * encode them as surrogate pairs (for codepoints inside\n\t\t * valid UTF-8 range, but not extended UTF-8).  Because\n\t\t * escape() and unescape() are legacy functions, we don't.\n\t\t */\n\t\tgoto esc_error;\n\t}\n\n\treturn;\n\n esc_error:\n\tDUK_ERROR_TYPE(tfm_ctx->thr, DUK_STR_INVALID_INPUT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__transform_callback_unescape(duk__transform_context *tfm_ctx, const void *udata, duk_codepoint_t cp) {\n\tduk_small_int_t t;\n\n\tDUK_UNREF(udata);\n\n\tif (cp == (duk_codepoint_t) '%') {\n\t\tconst duk_uint8_t *p = tfm_ctx->p;\n\t\tduk_size_t left = (duk_size_t) (tfm_ctx->p_end - p);  /* bytes left */\n\n\t\tif (left >= 5 && p[0] == 'u' &&\n\t\t    ((t = duk__decode_hex_escape(p + 1, 4)) >= 0)) {\n\t\t\tcp = (duk_codepoint_t) t;\n\t\t\ttfm_ctx->p += 5;\n\t\t} else if (left >= 2 &&\n\t\t           ((t = duk__decode_hex_escape(p, 2)) >= 0)) {\n\t\t\tcp = (duk_codepoint_t) t;\n\t\t\ttfm_ctx->p += 2;\n\t\t}\n\t}\n\n\tDUK_BW_WRITE_ENSURE_XUTF8(tfm_ctx->thr, &tfm_ctx->bw, cp);\n}\n#endif  /* DUK_USE_SECTION_B */\n\n/*\n *  Eval\n *\n *  Eval needs to handle both a \"direct eval\" and an \"indirect eval\".\n *  Direct eval handling needs access to the caller's activation so that its\n *  lexical environment can be accessed.  A direct eval is only possible from\n *  ECMAScript code; an indirect eval call is possible also from C code.\n *  When an indirect eval call is made from C code, there may not be a\n *  calling activation at all which needs careful handling.\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_eval(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_activation *act_caller;\n\tduk_activation *act_eval;\n\tduk_hcompfunc *func;\n\tduk_hobject *outer_lex_env;\n\tduk_hobject *outer_var_env;\n\tduk_bool_t this_to_global = 1;\n\tduk_small_uint_t comp_flags;\n\tduk_int_t level = -2;\n\tduk_small_uint_t call_flags;\n\n\tDUK_ASSERT(duk_get_top(thr) == 1 || duk_get_top(thr) == 2);  /* 2 when called by debugger */\n\tDUK_ASSERT(thr->callstack_top >= 1);  /* at least this function exists */\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT((thr->callstack_curr->flags & DUK_ACT_FLAG_DIRECT_EVAL) == 0 || /* indirect eval */\n\t           (thr->callstack_top >= 2));  /* if direct eval, calling activation must exist */\n\n\t/*\n\t *  callstack_top - 1 --> this function\n\t *  callstack_top - 2 --> caller (may not exist)\n\t *\n\t *  If called directly from C, callstack_top might be 1.  If calling\n\t *  activation doesn't exist, call must be indirect.\n\t */\n\n\th = duk_get_hstring_notsymbol(thr, 0);\n\tif (!h) {\n\t\t/* Symbol must be returned as is, like any non-string values. */\n\t\treturn 1;  /* return arg as-is */\n\t}\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* NOTE: level is used only by the debugger and should never be present\n\t * for an ECMAScript eval().\n\t */\n\tDUK_ASSERT(level == -2);  /* by default, use caller's environment */\n\tif (duk_get_top(thr) >= 2 && duk_is_number(thr, 1)) {\n\t\tlevel = duk_get_int(thr, 1);\n\t}\n\tDUK_ASSERT(level <= -2);  /* This is guaranteed by debugger code. */\n#endif\n\n\t/* [ source ] */\n\n\tcomp_flags = DUK_COMPILE_EVAL;\n\tact_eval = thr->callstack_curr;  /* this function */\n\tDUK_ASSERT(act_eval != NULL);\n\tact_caller = duk_hthread_get_activation_for_level(thr, level);\n\tif (act_caller != NULL) {\n\t\t/* Have a calling activation, check for direct eval (otherwise\n\t\t * assume indirect eval.\n\t\t */\n\t\tif ((act_caller->flags & DUK_ACT_FLAG_STRICT) &&\n\t\t    (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL)) {\n\t\t\t/* Only direct eval inherits strictness from calling code\n\t\t\t * (E5.1 Section 10.1.1).\n\t\t\t */\n\t\t\tcomp_flags |= DUK_COMPILE_STRICT;\n\t\t}\n\t} else {\n\t\tDUK_ASSERT((act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) == 0);\n\t}\n\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_INPUT);  /* XXX: copy from caller? */\n\tduk_js_compile(thr,\n\t               (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h),\n\t               (duk_size_t) DUK_HSTRING_GET_BYTELEN(h),\n\t               comp_flags);\n\tfunc = (duk_hcompfunc *) duk_known_hobject(thr, -1);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) func));\n\n\t/* [ source template ] */\n\n\t/* E5 Section 10.4.2 */\n\n\tif (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) {\n\t\tDUK_ASSERT(thr->callstack_top >= 2);\n\t\tDUK_ASSERT(act_caller != NULL);\n\t\tif (act_caller->lex_env == NULL) {\n\t\t\tDUK_ASSERT(act_caller->var_env == NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"delayed environment initialization\"));\n\n\t\t\t/* this may have side effects, so re-lookup act */\n\t\t\tduk_js_init_activation_environment_records_delayed(thr, act_caller);\n\t\t}\n\t\tDUK_ASSERT(act_caller->lex_env != NULL);\n\t\tDUK_ASSERT(act_caller->var_env != NULL);\n\n\t\tthis_to_global = 0;\n\n\t\tif (DUK_HOBJECT_HAS_STRICT((duk_hobject *) func)) {\n\t\t\tduk_hdecenv *new_env;\n\t\t\tduk_hobject *act_lex_env;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"direct eval call to a strict function -> \"\n\t\t\t                     \"var_env and lex_env to a fresh env, \"\n\t\t\t                     \"this_binding to caller's this_binding\"));\n\n\t\t\tact_lex_env = act_caller->lex_env;\n\n\t\t\tnew_env = duk_hdecenv_alloc(thr,\n\t\t\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\t\t\tDUK_ASSERT(new_env != NULL);\n\t\t\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, act_lex_env);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, act_lex_env);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new_env allocated: %!iO\", (duk_heaphdr *) new_env));\n\n\t\t\touter_lex_env = (duk_hobject *) new_env;\n\t\t\touter_var_env = (duk_hobject *) new_env;\n\n\t\t\tduk_insert(thr, 0);  /* stash to bottom of value stack to keep new_env reachable for duration of eval */\n\n\t\t\t/* compiler's responsibility */\n\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV((duk_hobject *) func));\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"direct eval call to a non-strict function -> \"\n\t\t\t                     \"var_env and lex_env to caller's envs, \"\n\t\t\t                     \"this_binding to caller's this_binding\"));\n\n\t\t\touter_lex_env = act_caller->lex_env;\n\t\t\touter_var_env = act_caller->var_env;\n\n\t\t\t/* compiler's responsibility */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV((duk_hobject *) func));\n\t\t}\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"indirect eval call -> var_env and lex_env to \"\n\t\t                     \"global object, this_binding to global object\"));\n\n\t\tthis_to_global = 1;\n\t\touter_lex_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t\touter_var_env = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t}\n\n\t/* Eval code doesn't need an automatic .prototype object. */\n\tduk_js_push_closure(thr, func, outer_var_env, outer_lex_env, 0 /*add_auto_proto*/);\n\n\t/* [ env? source template closure ] */\n\n\tif (this_to_global) {\n\t\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\t\tduk_push_hobject_bidx(thr, DUK_BIDX_GLOBAL);\n\t} else {\n\t\tduk_tval *tv;\n\t\tDUK_ASSERT(thr->callstack_top >= 2);\n\t\tDUK_ASSERT(act_caller != NULL);\n\t\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act_caller->bottom_byteoff - sizeof(duk_tval));  /* this is just beneath bottom */\n\t\tDUK_ASSERT(tv >= thr->valstack);\n\t\tduk_push_tval(thr, tv);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"eval -> lex_env=%!iO, var_env=%!iO, this_binding=%!T\",\n\t                     (duk_heaphdr *) outer_lex_env,\n\t                     (duk_heaphdr *) outer_var_env,\n\t                     duk_get_tval(thr, -1)));\n\n\t/* [ env? source template closure this ] */\n\n\tcall_flags = 0;\n\tif (act_eval->flags & DUK_ACT_FLAG_DIRECT_EVAL) {\n\t\t/* Set DIRECT_EVAL flag for the call; it's not strictly\n\t\t * needed for the 'inner' eval call (the eval body) but\n\t\t * current new.target implementation expects to find it\n\t\t * so it can traverse direct eval chains up to the real\n\t\t * calling function.\n\t\t */\n\t\tcall_flags |= DUK_CALL_FLAG_DIRECT_EVAL;\n\t}\n\tduk_handle_call_unprotected_nargs(thr, 0, call_flags);\n\n\t/* [ env? source template result ] */\n\n\treturn 1;\n}\n\n/*\n *  Parsing of ints and floats\n */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_parse_int(duk_hthread *thr) {\n\tduk_int32_t radix;\n\tduk_small_uint_t s2n_flags;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, 0);  /* Reject symbols. */\n\n\tradix = duk_to_int32(thr, 1);\n\n\t/* While parseInt() recognizes 0xdeadbeef, it doesn't recognize\n\t * ES2015 0o123 or 0b10001.\n\t */\n\ts2n_flags = DUK_S2N_FLAG_TRIM_WHITE |\n\t            DUK_S2N_FLAG_ALLOW_GARBAGE |\n\t            DUK_S2N_FLAG_ALLOW_PLUS |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |\n\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT;\n\n\t/* Specification stripPrefix maps to DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT.\n\t *\n\t * Don't autodetect octals (from leading zeroes), require user code to\n\t * provide an explicit radix 8 for parsing octal.  See write-up from Mozilla:\n\t * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt#ECMAScript_5_Removes_Octal_Interpretation\n\t */\n\n\tif (radix != 0) {\n\t\tif (radix < 2 || radix > 36) {\n\t\t\tgoto ret_nan;\n\t\t}\n\t\tif (radix != 16) {\n\t\t\ts2n_flags &= ~DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT;\n\t\t}\n\t} else {\n\t\tradix = 10;\n\t}\n\n\tduk_dup_0(thr);\n\tduk_numconv_parse(thr, (duk_small_int_t) radix, s2n_flags);\n\treturn 1;\n\n ret_nan:\n\tduk_push_nan(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_parse_float(duk_hthread *thr) {\n\tduk_small_uint_t s2n_flags;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\tduk_to_string(thr, 0);  /* Reject symbols. */\n\n\t/* XXX: check flags */\n\ts2n_flags = DUK_S2N_FLAG_TRIM_WHITE |\n\t            DUK_S2N_FLAG_ALLOW_EXP |\n\t            DUK_S2N_FLAG_ALLOW_GARBAGE |\n\t            DUK_S2N_FLAG_ALLOW_PLUS |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |\n\t            DUK_S2N_FLAG_ALLOW_INF |\n\t            DUK_S2N_FLAG_ALLOW_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO;\n\n\tduk_numconv_parse(thr, 10 /*radix*/, s2n_flags);\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n/*\n *  Number checkers\n */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_is_nan(duk_hthread *thr) {\n\tduk_double_t d = duk_to_number(thr, 0);\n\tduk_push_boolean(thr, (duk_bool_t) DUK_ISNAN(d));\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_is_finite(duk_hthread *thr) {\n\tduk_double_t d = duk_to_number(thr, 0);\n\tduk_push_boolean(thr, (duk_bool_t) DUK_ISFINITE(d));\n\treturn 1;\n}\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n\n/*\n *  URI handling\n */\n\n#if defined(DUK_USE_GLOBAL_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_decode_uri(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_decode_uri, (const void *) duk__decode_uri_reserved_table);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_decode_uri_component(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_decode_uri, (const void *) duk__decode_uri_component_reserved_table);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_encode_uri(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_encode_uri, (const void *) duk__encode_uriunescaped_table);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_encode_uri_component(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_encode_uri, (const void *) duk__encode_uricomponent_unescaped_table);\n}\n\n#if defined(DUK_USE_SECTION_B)\nDUK_INTERNAL duk_ret_t duk_bi_global_object_escape(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_escape, (const void *) NULL);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_global_object_unescape(duk_hthread *thr) {\n\treturn duk__transform_helper(thr, duk__transform_callback_unescape, (const void *) NULL);\n}\n#endif  /* DUK_USE_SECTION_B */\n#endif  /* DUK_USE_GLOBAL_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_json.c",
    "content": "/*\n *  JSON built-ins.\n *\n *  See doc/json.rst.\n *\n *  Codepoints are handled as duk_uint_fast32_t to ensure that the full\n *  unsigned 32-bit range is supported.  This matters to e.g. JX.\n *\n *  Input parsing doesn't do an explicit end-of-input check at all.  This is\n *  safe: input string data is always NUL-terminated (0x00) and valid JSON\n *  inputs never contain plain NUL characters, so that as long as syntax checks\n *  are correct, we'll never read past the NUL.  This approach reduces code size\n *  and improves parsing performance, but it's critical that syntax checks are\n *  indeed correct!\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_JSON_SUPPORT)\n\n/*\n *  Local defines and forward declarations.\n */\n\n#define DUK__JSON_DECSTR_BUFSIZE 128\n#define DUK__JSON_DECSTR_CHUNKSIZE 64\n#define DUK__JSON_ENCSTR_CHUNKSIZE 64\n#define DUK__JSON_STRINGIFY_BUFSIZE 128\n#define DUK__JSON_MAX_ESC_LEN 10  /* '\\Udeadbeef' */\n\nDUK_LOCAL_DECL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx);\n#if defined(DUK_USE_JX)\nDUK_LOCAL_DECL duk_uint8_t duk__dec_peek(duk_json_dec_ctx *js_ctx);\n#endif\nDUK_LOCAL_DECL duk_uint8_t duk__dec_get(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL duk_uint8_t duk__dec_get_nonwhite(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n);\nDUK_LOCAL_DECL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx);\nDUK_LOCAL_DECL void duk__dec_string(duk_json_dec_ctx *js_ctx);\n#if defined(DUK_USE_JX)\nDUK_LOCAL_DECL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_pointer(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_buffer(duk_json_dec_ctx *js_ctx);\n#endif\nDUK_LOCAL_DECL void duk__dec_number(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_object(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_array(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_value(duk_json_dec_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx);\n\nDUK_LOCAL_DECL void duk__emit_1(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch);\nDUK_LOCAL_DECL void duk__emit_2(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch1, duk_uint_fast8_t ch2);\nDUK_LOCAL_DECL void duk__unemit_1(duk_json_enc_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__emit_hstring(duk_json_enc_ctx *js_ctx, duk_hstring *h);\n#if defined(DUK_USE_FASTINT)\nDUK_LOCAL_DECL void duk__emit_cstring(duk_json_enc_ctx *js_ctx, const char *p);\n#endif\nDUK_LOCAL_DECL void duk__emit_stridx(duk_json_enc_ctx *js_ctx, duk_small_uint_t stridx);\nDUK_LOCAL_DECL duk_uint8_t *duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uint_fast32_t cp, duk_uint8_t *q);\nDUK_LOCAL_DECL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k);\nDUK_LOCAL_DECL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str);\nDUK_LOCAL_DECL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top);\nDUK_LOCAL_DECL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top);\nDUK_LOCAL_DECL void duk__enc_object(duk_json_enc_ctx *js_ctx);\nDUK_LOCAL_DECL void duk__enc_array(duk_json_enc_ctx *js_ctx);\nDUK_LOCAL_DECL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder);\nDUK_LOCAL_DECL duk_bool_t duk__enc_allow_into_proplist(duk_tval *tv);\nDUK_LOCAL_DECL void duk__enc_double(duk_json_enc_ctx *js_ctx);\n#if defined(DUK_USE_FASTINT)\nDUK_LOCAL_DECL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv);\n#endif\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL_DECL void duk__enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h);\nDUK_LOCAL_DECL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL_DECL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj);\n#endif\n#endif\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\nDUK_LOCAL_DECL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h);\n#endif\nDUK_LOCAL_DECL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth);\n\n/*\n *  Helper tables\n */\n\n#if defined(DUK_USE_JSON_QUOTESTRING_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_quotestr_lookup[256] = {\n\t/* 0x00 ... 0x7f: as is\n\t * 0x80: escape generically\n\t * 0x81: slow path\n\t * 0xa0 ... 0xff: backslash + one char\n\t */\n\n\t0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xe2, 0xf4, 0xee, 0x80, 0xe6, 0xf2, 0x80, 0x80,\n\t0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,\n\t0x20, 0x21, 0xa2, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,\n\t0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,\n\t0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,\n\t0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0xdc, 0x5d, 0x5e, 0x5f,\n\t0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,\n\t0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81\n};\n#else  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\nDUK_LOCAL const duk_uint8_t duk__json_quotestr_esc[14] = {\n\tDUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL,\n\tDUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL, DUK_ASC_NUL,\n\tDUK_ASC_LC_B, DUK_ASC_LC_T, DUK_ASC_LC_N, DUK_ASC_NUL,\n\tDUK_ASC_LC_F, DUK_ASC_LC_R\n};\n#endif  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\n\n#if defined(DUK_USE_JSON_DECSTRING_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_decstr_lookup[256] = {\n\t/* 0x00: slow path\n\t * other: as is\n\t */\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x20, 0x21, 0x00, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,\n\t0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,\n\t0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,\n\t0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x00, 0x5d, 0x5e, 0x5f,\n\t0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,\n\t0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,\n\t0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,\n\t0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,\n\t0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,\n\t0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,\n\t0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,\n\t0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,\n\t0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,\n\t0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff\n};\n#endif  /* DUK_USE_JSON_DECSTRING_FASTPATH */\n\n#if defined(DUK_USE_JSON_EATWHITE_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_eatwhite_lookup[256] = {\n\t/* 0x00: finish (non-white)\n\t * 0x01: continue\n\t */\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\n#endif  /* DUK_USE_JSON_EATWHITE_FASTPATH */\n\n#if defined(DUK_USE_JSON_DECNUMBER_FASTPATH)\nDUK_LOCAL const duk_uint8_t duk__json_decnumber_lookup[256] = {\n\t/* 0x00: finish (not part of number)\n\t * 0x01: continue\n\t */\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00,\n\t0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\n\t0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\n};\n#endif  /* DUK_USE_JSON_DECNUMBER_FASTPATH */\n\n/*\n *  Parsing implementation.\n *\n *  JSON lexer is now separate from duk_lexer.c because there are numerous\n *  small differences making it difficult to share the lexer.\n *\n *  The parser here works with raw bytes directly; this works because all\n *  JSON delimiters are ASCII characters.  Invalid xUTF-8 encoded values\n *  inside strings will be passed on without normalization; this is not a\n *  compliance concern because compliant inputs will always be valid\n *  CESU-8 encodings.\n */\n\nDUK_LOCAL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx) {\n\t/* Shared handler to minimize parser size.  Cause will be\n\t * hidden, unfortunately, but we'll have an offset which\n\t * is often quite enough.\n\t */\n\tDUK_ERROR_FMT1(js_ctx->thr, DUK_ERR_SYNTAX_ERROR, DUK_STR_FMT_INVALID_JSON,\n\t               (long) (js_ctx->p - js_ctx->p_start));\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx) {\n\tconst duk_uint8_t *p;\n\tduk_uint8_t t;\n\n\tp = js_ctx->p;\n\tfor (;;) {\n\t\tDUK_ASSERT(p <= js_ctx->p_end);\n\t\tt = *p;\n\n#if defined(DUK_USE_JSON_EATWHITE_FASTPATH)\n\t\t/* This fast path is pretty marginal in practice.\n\t\t * XXX: candidate for removal.\n\t\t */\n\t\tDUK_ASSERT(duk__json_eatwhite_lookup[0x00] == 0x00);  /* end-of-input breaks */\n\t\tif (duk__json_eatwhite_lookup[t] == 0) {\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_JSON_EATWHITE_FASTPATH */\n\t\tif (!(t == 0x20 || t == 0x0a || t == 0x0d || t == 0x09)) {\n\t\t\t/* NUL also comes here.  Comparison order matters, 0x20\n\t\t\t * is most common whitespace.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_JSON_EATWHITE_FASTPATH */\n\t\tp++;\n\t}\n\tjs_ctx->p = p;\n}\n\n#if defined(DUK_USE_JX)\nDUK_LOCAL duk_uint8_t duk__dec_peek(duk_json_dec_ctx *js_ctx) {\n\tDUK_ASSERT(js_ctx->p <= js_ctx->p_end);\n\treturn *js_ctx->p;\n}\n#endif\n\nDUK_LOCAL duk_uint8_t duk__dec_get(duk_json_dec_ctx *js_ctx) {\n\tDUK_ASSERT(js_ctx->p <= js_ctx->p_end);\n\treturn *js_ctx->p++;\n}\n\nDUK_LOCAL duk_uint8_t duk__dec_get_nonwhite(duk_json_dec_ctx *js_ctx) {\n\tduk__dec_eat_white(js_ctx);\n\treturn duk__dec_get(js_ctx);\n}\n\n/* For JX, expressing the whole unsigned 32-bit range matters. */\nDUK_LOCAL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n) {\n\tduk_small_uint_t i;\n\tduk_uint_fast32_t res = 0;\n\tduk_uint8_t x;\n\tduk_small_int_t t;\n\n\tfor (i = 0; i < n; i++) {\n\t\t/* XXX: share helper from lexer; duk_lexer.c / hexval(). */\n\n\t\tx = duk__dec_get(js_ctx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"decode_hex_escape: i=%ld, n=%ld, res=%ld, x=%ld\",\n\t\t                     (long) i, (long) n, (long) res, (long) x));\n\n\t\t/* x == 0x00 (EOF) causes syntax_error */\n\t\tDUK_ASSERT(duk_hex_dectab[0] == -1);\n\t\tt = duk_hex_dectab[x & 0xff];\n\t\tif (DUK_LIKELY(t >= 0)) {\n\t\t\tres = (res * 16) + (duk_uint_fast32_t) t;\n\t\t} else {\n\t\t\t/* catches EOF and invalid digits */\n\t\t\tgoto syntax_error;\n\t\t}\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"final hex decoded value: %ld\", (long) res));\n\treturn res;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n\treturn 0;\n}\n\nDUK_LOCAL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t x, y;\n\n\t/* First character has already been eaten and checked by the caller.\n\t * We can scan until a NUL in stridx string because no built-in strings\n\t * have internal NULs.\n\t */\n\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\th = DUK_HTHREAD_GET_STRING(js_ctx->thr, stridx);\n\tDUK_ASSERT(h != NULL);\n\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h) + 1;\n\tDUK_ASSERT(*(js_ctx->p - 1) == *(p - 1));  /* first character has been matched */\n\n\tfor (;;) {\n\t\tx = *p;\n\t\tif (x == 0) {\n\t\t\tbreak;\n\t\t}\n\t\ty = duk__dec_get(js_ctx);\n\t\tif (x != y) {\n\t\t\t/* Catches EOF of JSON input. */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\tp++;\n\t}\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\nDUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_uint8_t **ext_p) {\n\tduk_uint_fast32_t cp;\n\n\t/* EOF (-1) will be cast to an unsigned value first\n\t * and then re-cast for the switch.  In any case, it\n\t * will match the default case (syntax error).\n\t */\n\tcp = (duk_uint_fast32_t) duk__dec_get(js_ctx);\n\tswitch (cp) {\n\tcase DUK_ASC_BACKSLASH: break;\n\tcase DUK_ASC_DOUBLEQUOTE: break;\n\tcase DUK_ASC_SLASH: break;\n\tcase DUK_ASC_LC_T: cp = 0x09; break;\n\tcase DUK_ASC_LC_N: cp = 0x0a; break;\n\tcase DUK_ASC_LC_R: cp = 0x0d; break;\n\tcase DUK_ASC_LC_F: cp = 0x0c; break;\n\tcase DUK_ASC_LC_B: cp = 0x08; break;\n\tcase DUK_ASC_LC_U: {\n\t\tcp = duk__dec_decode_hex_escape(js_ctx, 4);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_JX)\n\tcase DUK_ASC_UC_U: {\n\t\tif (js_ctx->flag_ext_custom) {\n\t\t\tcp = duk__dec_decode_hex_escape(js_ctx, 8);\n\t\t} else {\n\t\t\treturn 1;  /* syntax error */\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LC_X: {\n\t\tif (js_ctx->flag_ext_custom) {\n\t\t\tcp = duk__dec_decode_hex_escape(js_ctx, 2);\n\t\t} else {\n\t\t\treturn 1;  /* syntax error */\n\t\t}\n\t\tbreak;\n\t}\n#endif  /* DUK_USE_JX */\n\tdefault:\n\t\t/* catches EOF (0x00) */\n\t\treturn 1;  /* syntax error */\n\t}\n\n\tDUK_RAW_WRITE_XUTF8(*ext_p, cp);\n\n\treturn 0;\n}\n\nDUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tduk_uint8_t *q;\n\n\t/* '\"' was eaten by caller */\n\n\t/* Note that we currently parse -bytes-, not codepoints.\n\t * All non-ASCII extended UTF-8 will encode to bytes >= 0x80,\n\t * so they'll simply pass through (valid UTF-8 or not).\n\t */\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(js_ctx->thr, bw, DUK__JSON_DECSTR_BUFSIZE);\n\tq = DUK_BW_GET_PTR(js_ctx->thr, bw);\n\n#if defined(DUK_USE_JSON_DECSTRING_FASTPATH)\n\tfor (;;) {\n\t\tduk_small_uint_t safe;\n\t\tduk_uint8_t b, x;\n\t\tconst duk_uint8_t *p;\n\n\t\t/* Select a safe loop count where no output checks are\n\t\t * needed assuming we won't encounter escapes.  Input\n\t\t * bound checks are not necessary as a NUL (guaranteed)\n\t\t * will cause a SyntaxError before we read out of bounds.\n\t\t */\n\n\t\tsafe = DUK__JSON_DECSTR_CHUNKSIZE;\n\n\t\t/* Ensure space for 1:1 output plus one escape. */\n\t\tq = DUK_BW_ENSURE_RAW(js_ctx->thr, bw, safe + DUK_UNICODE_MAX_XUTF8_LENGTH, q);\n\n\t\tp = js_ctx->p;  /* temp copy, write back for next loop */\n\t\tfor (;;) {\n\t\t\tif (safe == 0) {\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tsafe--;\n\n\t\t\t/* End of input (NUL) goes through slow path and causes SyntaxError. */\n\t\t\tDUK_ASSERT(duk__json_decstr_lookup[0] == 0x00);\n\n\t\t\tb = *p++;\n\t\t\tx = (duk_small_int_t) duk__json_decstr_lookup[b];\n\t\t\tif (DUK_LIKELY(x != 0)) {\n\t\t\t\t/* Fast path, decode as is. */\n\t\t\t\t*q++ = b;\n\t\t\t} else if (b == DUK_ASC_DOUBLEQUOTE) {\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tgoto found_quote;\n\t\t\t} else if (b == DUK_ASC_BACKSLASH) {\n\t\t\t\t/* We've ensured space for one escaped input; then\n\t\t\t\t * bail out and recheck (this makes escape handling\n\t\t\t\t * quite slow but it's uncommon).\n\t\t\t\t */\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tif (duk__dec_string_escape(js_ctx, &q) != 0) {\n\t\t\t\t\tgoto syntax_error;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tjs_ctx->p = p;\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t}\n\t}\n found_quote:\n#else  /* DUK_USE_JSON_DECSTRING_FASTPATH */\n\tfor (;;) {\n\t\tduk_uint8_t x;\n\n\t\tq = DUK_BW_ENSURE_RAW(js_ctx->thr, bw, DUK_UNICODE_MAX_XUTF8_LENGTH, q);\n\n\t\tx = duk__dec_get(js_ctx);\n\n\t\tif (x == DUK_ASC_DOUBLEQUOTE) {\n\t\t\tbreak;\n\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\tif (duk__dec_string_escape(js_ctx, &q) != 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t} else if (x < 0x20) {\n\t\t\t/* catches EOF (NUL) */\n\t\t\tgoto syntax_error;\n\t\t} else {\n\t\t\t*q++ = (duk_uint8_t) x;\n\t\t}\n\t}\n#endif  /* DUK_USE_JSON_DECSTRING_FASTPATH */\n\n\tDUK_BW_SETPTR_AND_COMPACT(js_ctx->thr, bw, q);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if input string is safe. */\n\n\t/* [ ... str ] */\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\n#if defined(DUK_USE_JX)\n/* Decode a plain string consisting entirely of identifier characters.\n * Used to parse plain keys (e.g. \"foo: 123\").\n */\nDUK_LOCAL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p;\n\tduk_small_int_t x;\n\n\t/* Caller has already eaten the first char so backtrack one byte. */\n\n\tjs_ctx->p--;  /* safe */\n\tp = js_ctx->p;\n\n\t/* Here again we parse bytes, and non-ASCII UTF-8 will cause end of\n\t * parsing (which is correct except if there are non-shortest encodings).\n\t * There is also no need to check explicitly for end of input buffer as\n\t * the input is NUL padded and NUL will exit the parsing loop.\n\t *\n\t * Because no unescaping takes place, we can just scan to the end of the\n\t * plain string and intern from the input buffer.\n\t */\n\n\tfor (;;) {\n\t\tx = *p;\n\n\t\t/* There is no need to check the first character specially here\n\t\t * (i.e. reject digits): the caller only accepts valid initial\n\t\t * characters and won't call us if the first character is a digit.\n\t\t * This also ensures that the plain string won't be empty.\n\t\t */\n\n\t\tif (!duk_unicode_is_identifier_part((duk_codepoint_t) x)) {\n\t\t\tbreak;\n\t\t}\n\t\tp++;\n\t}\n\n\tduk_push_lstring(thr, (const char *) js_ctx->p, (duk_size_t) (p - js_ctx->p));\n\tjs_ctx->p = p;\n\n\t/* [ ... str ] */\n}\n#endif  /* DUK_USE_JX */\n\n#if defined(DUK_USE_JX)\nDUK_LOCAL void duk__dec_pointer(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p;\n\tduk_small_int_t x;\n\tvoid *voidptr;\n\n\t/* Caller has already eaten the first character ('(') which we don't need. */\n\n\tp = js_ctx->p;\n\n\tfor (;;) {\n\t\tx = *p;\n\n\t\t/* Assume that the native representation never contains a closing\n\t\t * parenthesis.\n\t\t */\n\n\t\tif (x == DUK_ASC_RPAREN) {\n\t\t\tbreak;\n\t\t} else if (x <= 0) {\n\t\t\t/* NUL term or -1 (EOF), NUL check would suffice */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\tp++;\n\t}\n\n\t/* There is no need to NUL delimit the sscanf() call: trailing garbage is\n\t * ignored and there is always a NUL terminator which will force an error\n\t * if no error is encountered before it.  It's possible that the scan\n\t * would scan further than between [js_ctx->p,p[ though and we'd advance\n\t * by less than the scanned value.\n\t *\n\t * Because pointers are platform specific, a failure to scan a pointer\n\t * results in a null pointer which is a better placeholder than a missing\n\t * value or an error.\n\t */\n\n\tvoidptr = NULL;\n\t(void) DUK_SSCANF((const char *) js_ctx->p, DUK_STR_FMT_PTR, &voidptr);\n\tduk_push_pointer(thr, voidptr);\n\tjs_ctx->p = p + 1;  /* skip ')' */\n\n\t/* [ ... ptr ] */\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n#endif  /* DUK_USE_JX */\n\n#if defined(DUK_USE_JX)\nDUK_LOCAL void duk__dec_buffer(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t *buf;\n\tduk_size_t src_len;\n\tduk_small_int_t x;\n\n\t/* Caller has already eaten the first character ('|') which we don't need. */\n\n\tp = js_ctx->p;\n\n\t/* XXX: Would be nice to share the fast path loop from duk_hex_decode()\n\t * and avoid creating a temporary buffer.  However, there are some\n\t * differences which prevent trivial sharing:\n\t *\n\t *   - Pipe char detection\n\t *   - EOF detection\n\t *   - Unknown length of input and output\n\t *\n\t * The best approach here would be a bufwriter and a reasonaly sized\n\t * safe inner loop (e.g. 64 output bytes at a time).\n\t */\n\n\tfor (;;) {\n\t\tx = *p;\n\n\t\t/* This loop intentionally does not ensure characters are valid\n\t\t * ([0-9a-fA-F]) because the hex decode call below will do that.\n\t\t */\n\t\tif (x == DUK_ASC_PIPE) {\n\t\t\tbreak;\n\t\t} else if (x <= 0) {\n\t\t\t/* NUL term or -1 (EOF), NUL check would suffice */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\tp++;\n\t}\n\n\t/* XXX: this is not very nice; unnecessary copy is made. */\n\tsrc_len = (duk_size_t) (p - js_ctx->p);\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, src_len);\n\tDUK_ASSERT(buf != NULL);\n\tduk_memcpy((void *) buf, (const void *) js_ctx->p, src_len);\n\tduk_hex_decode(thr, -1);\n\n\tjs_ctx->p = p + 1;  /* skip '|' */\n\n\t/* [ ... buf ] */\n\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n#endif  /* DUK_USE_JX */\n\n/* Parse a number, other than NaN or +/- Infinity */\nDUK_LOCAL void duk__dec_number(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p;\n\tduk_uint8_t x;\n\tduk_small_uint_t s2n_flags;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_number\"));\n\n\tp_start = js_ctx->p;\n\n\t/* First pass parse is very lenient (e.g. allows '1.2.3') and extracts a\n\t * string for strict number parsing.\n\t */\n\n\tp = js_ctx->p;\n\tfor (;;) {\n\t\tx = *p;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse_number: p_start=%p, p=%p, p_end=%p, x=%ld\",\n\t\t                     (const void *) p_start, (const void *) p,\n\t\t                     (const void *) js_ctx->p_end, (long) x));\n\n#if defined(DUK_USE_JSON_DECNUMBER_FASTPATH)\n\t\t/* This fast path is pretty marginal in practice.\n\t\t * XXX: candidate for removal.\n\t\t */\n\t\tDUK_ASSERT(duk__json_decnumber_lookup[0x00] == 0x00);  /* end-of-input breaks */\n\t\tif (duk__json_decnumber_lookup[x] == 0) {\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_JSON_DECNUMBER_FASTPATH */\n\t\tif (!((x >= DUK_ASC_0 && x <= DUK_ASC_9) ||\n\t\t      (x == DUK_ASC_PERIOD || x == DUK_ASC_LC_E ||\n\t\t       x == DUK_ASC_UC_E || x == DUK_ASC_MINUS || x == DUK_ASC_PLUS))) {\n\t\t\t/* Plus sign must be accepted for positive exponents\n\t\t\t * (e.g. '1.5e+2').  This clause catches NULs.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_JSON_DECNUMBER_FASTPATH */\n\t\tp++;  /* safe, because matched (NUL causes a break) */\n\t}\n\tjs_ctx->p = p;\n\n\tDUK_ASSERT(js_ctx->p > p_start);\n\tduk_push_lstring(thr, (const char *) p_start, (duk_size_t) (p - p_start));\n\n\ts2n_flags = DUK_S2N_FLAG_ALLOW_EXP |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |  /* but don't allow leading plus */\n\t            DUK_S2N_FLAG_ALLOW_FRAC;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_number: string before parsing: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_numconv_parse(thr, 10 /*radix*/, s2n_flags);\n\tif (duk_is_nan(thr, -1)) {\n\t\tduk__dec_syntax_error(js_ctx);\n\t}\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\tDUK_DDD(DUK_DDDPRINT(\"parse_number: final number: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* [ ... num ] */\n}\n\nDUK_LOCAL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_require_stack(thr, DUK_JSON_DEC_REQSTACK);\n\n\t/* c recursion check */\n\n\tDUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0);  /* unsigned */\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tif (js_ctx->recursion_depth >= js_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_JSONDEC_RECLIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tjs_ctx->recursion_depth++;\n}\n\nDUK_LOCAL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx) {\n\t/* c recursion check */\n\n\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tjs_ctx->recursion_depth--;\n}\n\nDUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_int_t key_count;  /* XXX: a \"first\" flag would suffice */\n\tduk_uint8_t x;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_object\"));\n\n\tduk__dec_objarr_entry(js_ctx);\n\n\tduk_push_object(thr);\n\n\t/* Initial '{' has been checked and eaten by caller. */\n\n\tkey_count = 0;\n\tfor (;;) {\n\t\tx = duk__dec_get_nonwhite(js_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse_object: obj=%!T, x=%ld, key_count=%ld\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t\t                     (long) x, (long) key_count));\n\n\t\t/* handle comma and closing brace */\n\n\t\tif (x == DUK_ASC_COMMA && key_count > 0) {\n\t\t\t/* accept comma, expect new value */\n\t\t\tx = duk__dec_get_nonwhite(js_ctx);\n\t\t} else if (x == DUK_ASC_RCURLY) {\n\t\t\t/* eat closing brace */\n\t\t\tbreak;\n\t\t} else if (key_count == 0) {\n\t\t\t/* accept anything, expect first value (EOF will be\n\t\t\t * caught by key parsing below.\n\t\t\t */\n\t\t\t;\n\t\t} else {\n\t\t\t/* catches EOF (NUL) and initial comma */\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/* parse key and value */\n\n\t\tif (x == DUK_ASC_DOUBLEQUOTE) {\n\t\t\tduk__dec_string(js_ctx);\n#if defined(DUK_USE_JX)\n\t\t} else if (js_ctx->flag_ext_custom &&\n\t\t           duk_unicode_is_identifier_start((duk_codepoint_t) x)) {\n\t\t\tduk__dec_plain_string(js_ctx);\n#endif\n\t\t} else {\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/* [ ... obj key ] */\n\n\t\tx = duk__dec_get_nonwhite(js_ctx);\n\t\tif (x != DUK_ASC_COLON) {\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\tduk__dec_value(js_ctx);\n\n\t\t/* [ ... obj key val ] */\n\n\t\tduk_xdef_prop_wec(thr, -3);\n\n\t\t/* [ ... obj ] */\n\n\t\tkey_count++;\n\t}\n\n\t/* [ ... obj ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_object: final object is %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__dec_objarr_exit(js_ctx);\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\nDUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_uarridx_t arr_idx;\n\tduk_uint8_t x;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_array\"));\n\n\tduk__dec_objarr_entry(js_ctx);\n\n\tduk_push_array(thr);\n\n\t/* Initial '[' has been checked and eaten by caller. */\n\n\tarr_idx = 0;\n\tfor (;;) {\n\t\tx = duk__dec_get_nonwhite(js_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse_array: arr=%!T, x=%ld, arr_idx=%ld\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t\t                     (long) x, (long) arr_idx));\n\n\t\t/* handle comma and closing bracket */\n\n\t\tif ((x == DUK_ASC_COMMA) && (arr_idx != 0)) {\n\t\t\t/* accept comma, expect new value */\n\t\t\t;\n\t\t} else if (x == DUK_ASC_RBRACKET) {\n\t\t\t/* eat closing bracket */\n\t\t\tbreak;\n\t\t} else if (arr_idx == 0) {\n\t\t\t/* accept anything, expect first value (EOF will be\n\t\t\t * caught by duk__dec_value() below.\n\t\t\t */\n\t\t\tjs_ctx->p--;  /* backtrack (safe) */\n\t\t} else {\n\t\t\t/* catches EOF (NUL) and initial comma */\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/* parse value */\n\n\t\tduk__dec_value(js_ctx);\n\n\t\t/* [ ... arr val ] */\n\n\t\tduk_xdef_prop_index_wec(thr, -2, arr_idx);\n\t\tarr_idx++;\n\t}\n\n\t/* Must set 'length' explicitly when using duk_xdef_prop_xxx() to\n\t * set the values.\n\t */\n\n\tduk_set_length(thr, -1, arr_idx);\n\n\t/* [ ... arr ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_array: final array is %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__dec_objarr_exit(js_ctx);\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\nDUK_LOCAL void duk__dec_value(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_uint8_t x;\n\n\tx = duk__dec_get_nonwhite(js_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse_value: initial x=%ld\", (long) x));\n\n\t/* Note: duk__dec_req_stridx() backtracks one char */\n\n\tif (x == DUK_ASC_DOUBLEQUOTE) {\n\t\tduk__dec_string(js_ctx);\n\t} else if ((x >= DUK_ASC_0 && x <= DUK_ASC_9) || (x == DUK_ASC_MINUS)) {\n#if defined(DUK_USE_JX)\n\t\tif (js_ctx->flag_ext_custom && x == DUK_ASC_MINUS && duk__dec_peek(js_ctx) == DUK_ASC_UC_I) {\n\t\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_MINUS_INFINITY);  /* \"-Infinity\", '-' has been eaten */\n\t\t\tduk_push_number(thr, -DUK_DOUBLE_INFINITY);\n\t\t} else {\n#else\n\t\t{  /* unconditional block */\n#endif\n\t\t\t/* We already ate 'x', so backup one byte. */\n\t\t\tjs_ctx->p--;  /* safe */\n\t\t\tduk__dec_number(js_ctx);\n\t\t}\n\t} else if (x == DUK_ASC_LC_T) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_TRUE);\n\t\tduk_push_true(thr);\n\t} else if (x == DUK_ASC_LC_F) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_FALSE);\n\t\tduk_push_false(thr);\n\t} else if (x == DUK_ASC_LC_N) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_NULL);\n\t\tduk_push_null(thr);\n#if defined(DUK_USE_JX)\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_LC_U) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_UNDEFINED);\n\t\tduk_push_undefined(thr);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_N) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_NAN);\n\t\tduk_push_nan(thr);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_I) {\n\t\tduk__dec_req_stridx(js_ctx, DUK_STRIDX_INFINITY);\n\t\tduk_push_number(thr, DUK_DOUBLE_INFINITY);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_LPAREN) {\n\t\tduk__dec_pointer(js_ctx);\n\t} else if (js_ctx->flag_ext_custom && x == DUK_ASC_PIPE) {\n\t\tduk__dec_buffer(js_ctx);\n#endif\n\t} else if (x == DUK_ASC_LCURLY) {\n\t\tduk__dec_object(js_ctx);\n\t} else if (x == DUK_ASC_LBRACKET) {\n\t\tduk__dec_array(js_ctx);\n\t} else {\n\t\t/* catches EOF (NUL) */\n\t\tgoto syntax_error;\n\t}\n\n\tduk__dec_eat_white(js_ctx);\n\n\t/* [ ... val ] */\n\treturn;\n\n syntax_error:\n\tduk__dec_syntax_error(js_ctx);\n\tDUK_UNREACHABLE();\n}\n\n/* Recursive value reviver, implements the Walk() algorithm.  No C recursion\n * check is done here because the initial parsing step will already ensure\n * there is a reasonable limit on C recursion depth and hence object depth.\n */\nDUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hobject *h;\n\tduk_uarridx_t i, arr_len;\n\n\tDUK_DDD(DUK_DDDPRINT(\"walk: top=%ld, holder=%!T, name=%!T\",\n\t                     (long) duk_get_top(thr),\n\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk_dup_top(thr);\n\tduk_get_prop(thr, -3);  /* -> [ ... holder name val ] */\n\n\th = duk_get_hobject(thr, -1);\n\tif (h != NULL) {\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tarr_len = (duk_uarridx_t) duk_get_length(thr, -1);\n\t\t\tfor (i = 0; i < arr_len; i++) {\n\t\t\t\t/* [ ... holder name val ] */\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"walk: array, top=%ld, i=%ld, arr_len=%ld, holder=%!T, name=%!T, val=%!T\",\n\t\t\t\t                     (long) duk_get_top(thr), (long) i, (long) arr_len,\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -3), (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t\tduk_dup_top(thr);\n\t\t\t\t(void) duk_push_uint_to_hstring(thr, (duk_uint_t) i);  /* -> [ ... holder name val val ToString(i) ] */\n\t\t\t\tduk__dec_reviver_walk(js_ctx);  /* -> [ ... holder name val new_elem ] */\n\n\t\t\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\tduk_del_prop_index(thr, -1, i);\n\t\t\t\t} else {\n\t\t\t\t\t/* XXX: duk_xdef_prop_index_wec() would be more appropriate\n\t\t\t\t\t * here but it currently makes some assumptions that might\n\t\t\t\t\t * not hold (e.g. that previous property is not an accessor).\n\t\t\t\t\t */\n\t\t\t\t\tduk_put_prop_index(thr, -2, i);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t/* [ ... holder name val ] */\n\t\t\tduk_enum(thr, -1, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/);\n\t\t\twhile (duk_next(thr, -1 /*enum_index*/, 0 /*get_value*/)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"walk: object, top=%ld, holder=%!T, name=%!T, val=%!T, enum=%!iT, obj_key=%!T\",\n\t\t\t\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, -5),\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -4), (duk_tval *) duk_get_tval(thr, -3),\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t\t/* [ ... holder name val enum obj_key ] */\n\t\t\t\tduk_dup_m3(thr);\n\t\t\t\tduk_dup_m2(thr);\n\n\t\t\t\t/* [ ... holder name val enum obj_key val obj_key ] */\n\t\t\t\tduk__dec_reviver_walk(js_ctx);\n\n\t\t\t\t/* [ ... holder name val enum obj_key new_elem ] */\n\t\t\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\tduk_del_prop(thr, -3);\n\t\t\t\t} else {\n\t\t\t\t\t/* XXX: duk_xdef_prop_index_wec() would be more appropriate\n\t\t\t\t\t * here but it currently makes some assumptions that might\n\t\t\t\t\t * not hold (e.g. that previous property is not an accessor).\n\t\t\t\t\t *\n\t\t\t\t\t * Using duk_put_prop() works incorrectly with '__proto__'\n\t\t\t\t\t * if the own property with that name has been deleted.  This\n\t\t\t\t\t * does not happen normally, but a clever reviver can trigger\n\t\t\t\t\t * that, see complex reviver case in: test-bug-json-parse-__proto__.js.\n\t\t\t\t\t */\n\t\t\t\t\tduk_put_prop(thr, -4);\n\t\t\t\t}\n\t\t\t}\n\t\t\tduk_pop(thr);  /* pop enum */\n\t\t}\n\t}\n\n\t/* [ ... holder name val ] */\n\n\tduk_dup(thr, js_ctx->idx_reviver);\n\tduk_insert(thr, -4);  /* -> [ ... reviver holder name val ] */\n\tduk_call_method(thr, 2);  /* -> [ ... res ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"walk: top=%ld, result=%!T\",\n\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, -1)));\n}\n\n/*\n *  Stringify implementation.\n */\n\n#define DUK__EMIT_1(js_ctx,ch)          duk__emit_1((js_ctx), (duk_uint_fast8_t) (ch))\n#define DUK__EMIT_2(js_ctx,ch1,ch2)     duk__emit_2((js_ctx), (duk_uint_fast8_t) (ch1), (duk_uint_fast8_t) (ch2))\n#define DUK__EMIT_HSTR(js_ctx,h)        duk__emit_hstring((js_ctx), (h))\n#if defined(DUK_USE_FASTINT) || defined(DUK_USE_JX) || defined(DUK_USE_JC)\n#define DUK__EMIT_CSTR(js_ctx,p)        duk__emit_cstring((js_ctx), (p))\n#endif\n#define DUK__EMIT_STRIDX(js_ctx,i)      duk__emit_stridx((js_ctx), (i))\n#define DUK__UNEMIT_1(js_ctx)           duk__unemit_1((js_ctx))\n\nDUK_LOCAL void duk__emit_1(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch) {\n\tDUK_BW_WRITE_ENSURE_U8(js_ctx->thr, &js_ctx->bw, ch);\n}\n\nDUK_LOCAL void duk__emit_2(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch1, duk_uint_fast8_t ch2) {\n\tDUK_BW_WRITE_ENSURE_U8_2(js_ctx->thr, &js_ctx->bw, ch1, ch2);\n}\n\nDUK_LOCAL void duk__emit_hstring(duk_json_enc_ctx *js_ctx, duk_hstring *h) {\n\tDUK_BW_WRITE_ENSURE_HSTRING(js_ctx->thr, &js_ctx->bw, h);\n}\n\n#if defined(DUK_USE_FASTINT) || defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL void duk__emit_cstring(duk_json_enc_ctx *js_ctx, const char *str) {\n\tDUK_BW_WRITE_ENSURE_CSTRING(js_ctx->thr, &js_ctx->bw, str);\n}\n#endif\n\nDUK_LOCAL void duk__emit_stridx(duk_json_enc_ctx *js_ctx, duk_small_uint_t stridx) {\n\tduk_hstring *h;\n\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\th = DUK_HTHREAD_GET_STRING(js_ctx->thr, stridx);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_BW_WRITE_ENSURE_HSTRING(js_ctx->thr, &js_ctx->bw, h);\n}\n\nDUK_LOCAL void duk__unemit_1(duk_json_enc_ctx *js_ctx) {\n\tDUK_ASSERT(DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw) >= 1);\n\tDUK_BW_ADD_PTR(js_ctx->thr, &js_ctx->bw, -1);\n}\n\n#define DUK__MKESC(nybbles,esc1,esc2)  \\\n\t(((duk_uint_fast32_t) (nybbles)) << 16) | \\\n\t(((duk_uint_fast32_t) (esc1)) << 8) | \\\n\t((duk_uint_fast32_t) (esc2))\n\nDUK_LOCAL duk_uint8_t *duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uint_fast32_t cp, duk_uint8_t *q) {\n\tduk_uint_fast32_t tmp;\n\tduk_small_uint_t dig;\n\n\tDUK_UNREF(js_ctx);\n\n\t/* Caller ensures space for at least DUK__JSON_MAX_ESC_LEN. */\n\n\t/* Select appropriate escape format automatically, and set 'tmp' to a\n\t * value encoding both the escape format character and the nybble count:\n\t *\n\t *   (nybble_count << 16) | (escape_char1) | (escape_char2)\n\t */\n\n#if defined(DUK_USE_JX)\n\tif (DUK_LIKELY(cp < 0x100UL)) {\n\t\tif (DUK_UNLIKELY(js_ctx->flag_ext_custom != 0U)) {\n\t\t\ttmp = DUK__MKESC(2, DUK_ASC_BACKSLASH, DUK_ASC_LC_X);\n\t\t} else {\n\t\t\ttmp = DUK__MKESC(4, DUK_ASC_BACKSLASH, DUK_ASC_LC_U);\n\t\t}\n\t} else\n#endif\n\tif (DUK_LIKELY(cp < 0x10000UL)) {\n\t\ttmp = DUK__MKESC(4, DUK_ASC_BACKSLASH, DUK_ASC_LC_U);\n\t} else {\n#if defined(DUK_USE_JX)\n\t\tif (DUK_LIKELY(js_ctx->flag_ext_custom != 0U)) {\n\t\t\ttmp = DUK__MKESC(8, DUK_ASC_BACKSLASH, DUK_ASC_UC_U);\n\t\t} else\n#endif\n\t\t{\n\t\t\t/* In compatible mode and standard JSON mode, output\n\t\t\t * something useful for non-BMP characters.  This won't\n\t\t\t * roundtrip but will still be more or less readable and\n\t\t\t * more useful than an error.\n\t\t\t */\n\t\t\ttmp = DUK__MKESC(8, DUK_ASC_UC_U, DUK_ASC_PLUS);\n\t\t}\n\t}\n\n\t*q++ = (duk_uint8_t) ((tmp >> 8) & 0xff);\n\t*q++ = (duk_uint8_t) (tmp & 0xff);\n\n\ttmp = tmp >> 16;\n\twhile (tmp > 0) {\n\t\ttmp--;\n\t\tdig = (duk_small_uint_t) ((cp >> (4 * tmp)) & 0x0f);\n\t\t*q++ = duk_lc_digits[dig];\n\t}\n\n\treturn q;\n}\n\nDUK_LOCAL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k) {\n\tconst duk_int8_t *p, *p_start, *p_end;  /* Note: intentionally signed. */\n\tduk_size_t k_len;\n\tduk_codepoint_t cp;\n\n\tDUK_ASSERT(k != NULL);\n\n\t/* Accept ASCII strings which conform to identifier requirements\n\t * as being emitted without key quotes.  Since we only accept ASCII\n\t * there's no need for actual decoding: 'p' is intentionally signed\n\t * so that bytes >= 0x80 extend to negative values and are rejected\n\t * as invalid identifier codepoints.\n\t */\n\n\tif (js_ctx->flag_avoid_key_quotes) {\n\t\tk_len = DUK_HSTRING_GET_BYTELEN(k);\n\t\tp_start = (const duk_int8_t *) DUK_HSTRING_GET_DATA(k);\n\t\tp_end = p_start + k_len;\n\t\tp = p_start;\n\n\t\tif (p == p_end) {\n\t\t\t/* Zero length string is not accepted without quotes */\n\t\t\tgoto quote_normally;\n\t\t}\n\t\tcp = (duk_codepoint_t) (*p++);\n\t\tif (DUK_UNLIKELY(!duk_unicode_is_identifier_start(cp))) {\n\t\t\tgoto quote_normally;\n\t\t}\n\t\twhile (p < p_end) {\n\t\t\tcp = (duk_codepoint_t) (*p++);\n\t\t\tif (DUK_UNLIKELY(!duk_unicode_is_identifier_part(cp))) {\n\t\t\t\tgoto quote_normally;\n\t\t\t}\n\t\t}\n\n\t\t/* This seems faster than emitting bytes one at a time and\n\t\t * then potentially rewinding.\n\t\t */\n\t\tDUK__EMIT_HSTR(js_ctx, k);\n\t\treturn;\n\t}\n\n quote_normally:\n\tduk__enc_quote_string(js_ctx, k);\n}\n\n/* The Quote(value) operation: quote a string.\n *\n * Stack policy: [ ] -> [ ].\n */\n\nDUK_LOCAL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str) {\n\tduk_hthread *thr = js_ctx->thr;\n\tconst duk_uint8_t *p, *p_start, *p_end, *p_now, *p_tmp;\n\tduk_uint8_t *q;\n\tduk_ucodepoint_t cp;  /* typed for duk_unicode_decode_xutf8() */\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_quote_string: h_str=%!O\", (duk_heaphdr *) h_str));\n\n\tDUK_ASSERT(h_str != NULL);\n\tp_start = DUK_HSTRING_GET_DATA(h_str);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_str);\n\tp = p_start;\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_DOUBLEQUOTE);\n\n\t/* Encode string in small chunks, estimating the maximum expansion so that\n\t * there's no need to ensure space while processing the chunk.\n\t */\n\n\twhile (p < p_end) {\n\t\tduk_size_t left, now, space;\n\n\t\tleft = (duk_size_t) (p_end - p);\n\t\tnow = (left > DUK__JSON_ENCSTR_CHUNKSIZE ?\n\t\t       DUK__JSON_ENCSTR_CHUNKSIZE : left);\n\n\t\t/* Maximum expansion per input byte is 6:\n\t\t *   - invalid UTF-8 byte causes \"\\uXXXX\" to be emitted (6/1 = 6).\n\t\t *   - 2-byte UTF-8 encodes as \"\\uXXXX\" (6/2 = 3).\n\t\t *   - 4-byte UTF-8 encodes as \"\\Uxxxxxxxx\" (10/4 = 2.5).\n\t\t */\n\t\tspace = now * 6;\n\t\tq = DUK_BW_ENSURE_GETPTR(thr, &js_ctx->bw, space);\n\n\t\tp_now = p + now;\n\n\t\twhile (p < p_now) {\n#if defined(DUK_USE_JSON_QUOTESTRING_FASTPATH)\n\t\t\tduk_uint8_t b;\n\n\t\t\tb = duk__json_quotestr_lookup[*p++];\n\t\t\tif (DUK_LIKELY(b < 0x80)) {\n\t\t\t\t/* Most input bytes go through here. */\n\t\t\t\t*q++ = b;\n\t\t\t} else if (b >= 0xa0) {\n\t\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t\t\t*q++ = (duk_uint8_t) (b - 0x80);\n\t\t\t} else if (b == 0x80) {\n\t\t\t\tcp = (duk_ucodepoint_t) (*(p - 1));\n\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t} else if (b == 0x7f && js_ctx->flag_ascii_only) {\n\t\t\t\t/* 0x7F is special */\n\t\t\t\tDUK_ASSERT(b == 0x81);\n\t\t\t\tcp = (duk_ucodepoint_t) 0x7f;\n\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(b == 0x81);\n\t\t\t\tp--;\n\n\t\t\t\t/* slow path is shared */\n#else  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\n\t\t\tcp = *p;\n\n\t\t\tif (DUK_LIKELY(cp <= 0x7f)) {\n\t\t\t\t/* ascii fast path: avoid decoding utf-8 */\n\t\t\t\tp++;\n\t\t\t\tif (cp == 0x22 || cp == 0x5c) {\n\t\t\t\t\t/* double quote or backslash */\n\t\t\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t\t\t\t*q++ = (duk_uint8_t) cp;\n\t\t\t\t} else if (cp < 0x20) {\n\t\t\t\t\tduk_uint_fast8_t esc_char;\n\n\t\t\t\t\t/* This approach is a bit shorter than a straight\n\t\t\t\t\t * if-else-ladder and also a bit faster.\n\t\t\t\t\t */\n\t\t\t\t\tif (cp < (sizeof(duk__json_quotestr_esc) / sizeof(duk_uint8_t)) &&\n\t\t\t\t\t    (esc_char = duk__json_quotestr_esc[cp]) != 0) {\n\t\t\t\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t\t\t\t\t*q++ = (duk_uint8_t) esc_char;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t\t\t}\n\t\t\t\t} else if (cp == 0x7f && js_ctx->flag_ascii_only) {\n\t\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t\t} else {\n\t\t\t\t\t/* any other printable -> as is */\n\t\t\t\t\t*q++ = (duk_uint8_t) cp;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* slow path is shared */\n#endif  /* DUK_USE_JSON_QUOTESTRING_FASTPATH */\n\n\t\t\t\t/* slow path decode */\n\n\t\t\t\t/* If XUTF-8 decoding fails, treat the offending byte as a codepoint directly\n\t\t\t\t * and go forward one byte.  This is of course very lossy, but allows some kind\n\t\t\t\t * of output to be produced even for internal strings which don't conform to\n\t\t\t\t * XUTF-8.  All standard ECMAScript strings are always CESU-8, so this behavior\n\t\t\t\t * does not violate the ECMAScript specification.  The behavior is applied to\n\t\t\t\t * all modes, including ECMAScript standard JSON.  Because the current XUTF-8\n\t\t\t\t * decoding is not very strict, this behavior only really affects initial bytes\n\t\t\t\t * and truncated codepoints.\n\t\t\t\t *\n\t\t\t\t * Another alternative would be to scan forwards to start of next codepoint\n\t\t\t\t * (or end of input) and emit just one replacement codepoint.\n\t\t\t\t */\n\n\t\t\t\tp_tmp = p;\n\t\t\t\tif (!duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp)) {\n\t\t\t\t\t/* Decode failed. */\n\t\t\t\t\tcp = *p_tmp;\n\t\t\t\t\tp = p_tmp + 1;\n\t\t\t\t}\n\n#if defined(DUK_USE_NONSTD_JSON_ESC_U2028_U2029)\n\t\t\t\tif (js_ctx->flag_ascii_only || cp == 0x2028 || cp == 0x2029) {\n#else\n\t\t\t\tif (js_ctx->flag_ascii_only) {\n#endif\n\t\t\t\t\tq = duk__emit_esc_auto_fast(js_ctx, cp, q);\n\t\t\t\t} else {\n\t\t\t\t\t/* as is */\n\t\t\t\t\tDUK_RAW_WRITE_XUTF8(q, cp);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tDUK_BW_SET_PTR(thr, &js_ctx->bw, q);\n\t}\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_DOUBLEQUOTE);\n}\n\n/* Encode a double (checked by caller) from stack top.  Stack top may be\n * replaced by serialized string but is not popped (caller does that).\n */\nDUK_LOCAL void duk__enc_double(duk_json_enc_ctx *js_ctx) {\n\tduk_hthread *thr;\n\tduk_tval *tv;\n\tduk_double_t d;\n\tduk_small_int_t c;\n\tduk_small_int_t s;\n\tduk_small_uint_t stridx;\n\tduk_small_uint_t n2s_flags;\n\tduk_hstring *h_str;\n\n\tDUK_ASSERT(js_ctx != NULL);\n\tthr = js_ctx->thr;\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Caller must ensure 'tv' is indeed a double and not a fastint! */\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\td = DUK_TVAL_GET_DOUBLE(tv);\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\ts = (duk_small_int_t) DUK_SIGNBIT(d);\n\tDUK_UNREF(s);\n\n\tif (DUK_LIKELY(!(c == DUK_FP_INFINITE || c == DUK_FP_NAN))) {\n\t\tDUK_ASSERT(DUK_ISFINITE(d));\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t/* Negative zero needs special handling in JX/JC because\n\t\t * it would otherwise serialize to '0', not '-0'.\n\t\t */\n\t\tif (DUK_UNLIKELY(c == DUK_FP_ZERO && s != 0 &&\n\t\t                 (js_ctx->flag_ext_custom_or_compatible))) {\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_MINUS_ZERO);  /* '-0' */\n\t\t} else\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\t\t{\n\t\t\tn2s_flags = 0;\n\t\t\t/* [ ... number ] -> [ ... string ] */\n\t\t\tduk_numconv_stringify(thr, 10 /*radix*/, 0 /*digits*/, n2s_flags);\n\t\t}\n\t\th_str = duk_known_hstring(thr, -1);\n\t\tDUK__EMIT_HSTR(js_ctx, h_str);\n\t\treturn;\n\t}\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tif (!(js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM |\n\t                       DUK_JSON_FLAG_EXT_COMPATIBLE))) {\n\t\tstridx = DUK_STRIDX_LC_NULL;\n\t} else if (c == DUK_FP_NAN) {\n\t\tstridx = js_ctx->stridx_custom_nan;\n\t} else if (s == 0) {\n\t\tstridx = js_ctx->stridx_custom_posinf;\n\t} else {\n\t\tstridx = js_ctx->stridx_custom_neginf;\n\t}\n#else\n\tstridx = DUK_STRIDX_LC_NULL;\n#endif\n\tDUK__EMIT_STRIDX(js_ctx, stridx);\n}\n\n#if defined(DUK_USE_FASTINT)\n/* Encode a fastint from duk_tval ptr, no value stack effects. */\nDUK_LOCAL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv) {\n\tduk_int64_t v;\n\n\t/* Fastint range is signed 48-bit so longest value is -2^47 = -140737488355328\n\t * (16 chars long), longest signed 64-bit value is -2^63 = -9223372036854775808\n\t * (20 chars long).  Alloc space for 64-bit range to be safe.\n\t */\n\tduk_uint8_t buf[20 + 1];\n\n\t/* Caller must ensure 'tv' is indeed a fastint! */\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\tv = DUK_TVAL_GET_FASTINT(tv);\n\n\t/* XXX: There are no format strings in duk_config.h yet, could add\n\t * one for formatting duk_int64_t.  For now, assumes \"%lld\" and that\n\t * \"long long\" type exists.  Could also rely on C99 directly but that\n\t * won't work for older MSVC.\n\t */\n\tDUK_SPRINTF((char *) buf, \"%lld\", (long long) v);\n\tDUK__EMIT_CSTR(js_ctx, (const char *) buf);\n}\n#endif\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n#if defined(DUK_USE_HEX_FASTPATH)\nDUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) {\n\tduk_uint8_t *q;\n\tduk_uint16_t *q16;\n\tduk_small_uint_t x;\n\tduk_size_t i, len_safe;\n#if !defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)\n\tduk_bool_t shift_dst;\n#endif\n\n\t/* Unlike in duk_hex_encode() 'dst' is not necessarily aligned by 2.\n\t * For platforms where unaligned accesses are not allowed, shift 'dst'\n\t * ahead by 1 byte to get alignment and then duk_memmove() the result\n\t * in place.  The faster encoding loop makes up the difference.\n\t * There's always space for one extra byte because a terminator always\n\t * follows the hex data and that's been accounted for by the caller.\n\t */\n\n#if defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)\n\tq16 = (duk_uint16_t *) (void *) dst;\n#else\n\tshift_dst = (duk_bool_t) (((duk_size_t) dst) & 0x01U);\n\tif (shift_dst) {\n\t\tDUK_DD(DUK_DDPRINT(\"unaligned accesses not possible, dst not aligned -> step to dst + 1\"));\n\t\tq16 = (duk_uint16_t *) (void *) (dst + 1);\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"unaligned accesses not possible, dst is aligned\"));\n\t\tq16 = (duk_uint16_t *) (void *) dst;\n\t}\n\tDUK_ASSERT((((duk_size_t) q16) & 0x01U) == 0);\n#endif\n\n\tlen_safe = src_len & ~0x03U;\n\tfor (i = 0; i < len_safe; i += 4) {\n\t\tq16[0] = duk_hex_enctab[src[i]];\n\t\tq16[1] = duk_hex_enctab[src[i + 1]];\n\t\tq16[2] = duk_hex_enctab[src[i + 2]];\n\t\tq16[3] = duk_hex_enctab[src[i + 3]];\n\t\tq16 += 4;\n\t}\n\tq = (duk_uint8_t *) q16;\n\n#if !defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)\n\tif (shift_dst) {\n\t\tq--;\n\t\tduk_memmove((void *) dst, (const void *) (dst + 1), 2 * len_safe);\n\t\tDUK_ASSERT(dst + 2 * len_safe == q);\n\t}\n#endif\n\n\tfor (; i < src_len; i++) {\n\t\tx = src[i];\n\t\t*q++ = duk_lc_digits[x >> 4];\n\t\t*q++ = duk_lc_digits[x & 0x0f];\n\t}\n\n\treturn q;\n}\n#else  /* DUK_USE_HEX_FASTPATH */\nDUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint8_t *q;\n\tduk_small_uint_t x;\n\n\tp = src;\n\tp_end = src + src_len;\n\tq = dst;\n\twhile (p != p_end) {\n\t\tx = *p++;\n\t\t*q++ = duk_lc_digits[x >> 4];\n\t\t*q++ = duk_lc_digits[x & 0x0f];\n\t}\n\n\treturn q;\n}\n#endif  /* DUK_USE_HEX_FASTPATH */\n\nDUK_LOCAL void duk__enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_data, duk_size_t buf_len) {\n\tduk_hthread *thr;\n\tduk_uint8_t *q;\n\tduk_size_t space;\n\n\tthr = js_ctx->thr;\n\n\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);  /* caller checks */\n\tDUK_ASSERT(js_ctx->flag_ext_custom_or_compatible);\n\n\t/* Buffer values are encoded in (lowercase) hex to make the\n\t * binary data readable.  Base64 or similar would be more\n\t * compact but less readable, and the point of JX/JC\n\t * variants is to be as useful to a programmer as possible.\n\t */\n\n\t/* The #if defined() clutter here needs to handle the three\n\t * cases: (1) JX+JC, (2) JX only, (3) JC only.\n\t */\n\n\t/* Note: space must cater for both JX and JC. */\n\tspace = 9 + buf_len * 2 + 2;\n\tDUK_ASSERT(DUK_HBUFFER_MAX_BYTELEN <= 0x7ffffffeUL);\n\tDUK_ASSERT((space - 2) / 2 >= buf_len);  /* overflow not possible, buffer limits */\n\tq = DUK_BW_ENSURE_GETPTR(thr, &js_ctx->bw, space);\n\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\tif (js_ctx->flag_ext_custom)\n#endif\n#if defined(DUK_USE_JX)\n\t{\n\t\t*q++ = DUK_ASC_PIPE;\n\t\tq = duk__enc_buffer_data_hex(buf_data, buf_len, q);\n\t\t*q++ = DUK_ASC_PIPE;\n\n\t}\n#endif\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\telse\n#endif\n#if defined(DUK_USE_JC)\n\t{\n\t\tDUK_ASSERT(js_ctx->flag_ext_compatible);\n\t\tduk_memcpy((void *) q, (const void *) \"{\\\"_buf\\\":\\\"\", 9);  /* len: 9 */\n\t\tq += 9;\n\t\tq = duk__enc_buffer_data_hex(buf_data, buf_len, q);\n\t\t*q++ = DUK_ASC_DOUBLEQUOTE;\n\t\t*q++ = DUK_ASC_RCURLY;\n\t}\n#endif\n\n\tDUK_BW_SET_PTR(thr, &js_ctx->bw, q);\n}\n\nDUK_LOCAL void duk__enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) {\n\tduk__enc_buffer_data(js_ctx,\n\t                     (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(js_ctx->thr->heap, h),\n\t                     (duk_size_t) DUK_HBUFFER_GET_SIZE(h));\n}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\nDUK_LOCAL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) {\n\tduk_size_t i, n;\n\tconst duk_uint8_t *buf;\n\tduk_uint8_t *q;\n\n\tn = DUK_HBUFFER_GET_SIZE(h);\n\tif (n == 0) {\n\t\tDUK__EMIT_2(js_ctx, DUK_ASC_LCURLY, DUK_ASC_RCURLY);\n\t\treturn;\n\t}\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);\n\n\t/* Maximum encoded length with 32-bit index: 1 + 10 + 2 + 3 + 1 + 1 = 18,\n\t * with 64-bit index: 1 + 20 + 2 + 3 + 1 + 1 = 28.  32 has some slack.\n\t *\n\t * Note that because the output buffer is reallocated from time to time,\n\t * side effects (such as finalizers) affecting the buffer 'h' must be\n\t * disabled.  This is the case in the JSON.stringify() fast path.\n\t */\n\n\tbuf = (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(js_ctx->thr->heap, h);\n\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth + 1);\n\t\t\tq = DUK_BW_ENSURE_GETPTR(js_ctx->thr, &js_ctx->bw, 32);\n\t\t\tq += DUK_SPRINTF((char *) q, \"\\\"%lu\\\": %u,\", (unsigned long) i, (unsigned int) buf[i]);\n\t\t\tDUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, q);\n\t\t}\n\t} else {\n\t\tq = DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw);\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tq = DUK_BW_ENSURE_RAW(js_ctx->thr, &js_ctx->bw, 32, q);\n\t\t\tq += DUK_SPRINTF((char *) q, \"\\\"%lu\\\":%u,\", (unsigned long) i, (unsigned int) buf[i]);\n\t\t}\n\t\tDUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, q);\n\t}\n\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\n\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t}\n\tDUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);\n}\n#endif  /* DUK_USE_JSON_STRINGIFY_FASTPATH */\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr) {\n\tchar buf[64];  /* XXX: how to figure correct size? */\n\tconst char *fmt;\n\n\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);  /* caller checks */\n\tDUK_ASSERT(js_ctx->flag_ext_custom_or_compatible);\n\n\tduk_memzero(buf, sizeof(buf));\n\n\t/* The #if defined() clutter here needs to handle the three\n\t * cases: (1) JX+JC, (2) JX only, (3) JC only.\n\t */\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\tif (js_ctx->flag_ext_custom)\n#endif\n#if defined(DUK_USE_JX)\n\t{\n\t\tfmt = ptr ? \"(%p)\" : \"(null)\";\n\t}\n#endif\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\telse\n#endif\n#if defined(DUK_USE_JC)\n\t{\n\t\tDUK_ASSERT(js_ctx->flag_ext_compatible);\n\t\tfmt = ptr ? \"{\\\"_ptr\\\":\\\"%p\\\"}\" : \"{\\\"_ptr\\\":\\\"null\\\"}\";\n\t}\n#endif\n\n\t/* When ptr == NULL, the format argument is unused. */\n\tDUK_SNPRINTF(buf, sizeof(buf) - 1, fmt, ptr);  /* must not truncate */\n\tDUK__EMIT_CSTR(js_ctx, buf);\n}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\nDUK_LOCAL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj) {\n\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\tif (h_bufobj->buf == NULL || !DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t} else {\n\t\t/* Handle both full and partial slice (as long as covered). */\n\t\tduk__enc_buffer_data(js_ctx,\n\t\t                     (duk_uint8_t *) DUK_HBUFOBJ_GET_SLICE_BASE(js_ctx->thr->heap, h_bufobj),\n\t\t                     (duk_size_t) h_bufobj->length);\n\t}\n}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* Indent helper.  Calling code relies on js_ctx->recursion_depth also being\n * directly related to indent depth.\n */\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) {\n\tDUK_ASSERT(js_ctx->h_gap != NULL);\n\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) > 0);  /* caller guarantees */\n\n\tDUK__EMIT_1(js_ctx, 0x0a);\n\twhile (depth-- > 0) {\n\t\tDUK__EMIT_HSTR(js_ctx, js_ctx->h_gap);\n\t}\n}\n#else  /* DUK_USE_PREFER_SIZE */\nDUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) {\n\tconst duk_uint8_t *gap_data;\n\tduk_size_t gap_len;\n\tduk_size_t avail_bytes;   /* bytes of indent available for copying */\n\tduk_size_t need_bytes;    /* bytes of indent still needed */\n\tduk_uint8_t *p_start;\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT(js_ctx->h_gap != NULL);\n\tDUK_ASSERT(DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) > 0);  /* caller guarantees */\n\n\tDUK__EMIT_1(js_ctx, 0x0a);\n\tif (DUK_UNLIKELY(depth == 0)) {\n\t\treturn;\n\t}\n\n\t/* To handle deeper indents efficiently, make use of copies we've\n\t * already emitted.  In effect we can emit a sequence of 1, 2, 4,\n\t * 8, etc copies, and then finish the last run.  Byte counters\n\t * avoid multiply with gap_len on every loop.\n\t */\n\n\tgap_data = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(js_ctx->h_gap);\n\tgap_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap);\n\tDUK_ASSERT(gap_len > 0);\n\n\tneed_bytes = gap_len * depth;\n\tp = DUK_BW_ENSURE_GETPTR(js_ctx->thr, &js_ctx->bw, need_bytes);\n\tp_start = p;\n\n\tduk_memcpy((void *) p, (const void *) gap_data, (size_t) gap_len);\n\tp += gap_len;\n\tavail_bytes = gap_len;\n\tDUK_ASSERT(need_bytes >= gap_len);\n\tneed_bytes -= gap_len;\n\n\twhile (need_bytes >= avail_bytes) {\n\t\tduk_memcpy((void *) p, (const void *) p_start, (size_t) avail_bytes);\n\t\tp += avail_bytes;\n\t\tneed_bytes -= avail_bytes;\n\t\tavail_bytes <<= 1;\n\t}\n\n\tDUK_ASSERT(need_bytes < avail_bytes);  /* need_bytes may be zero */\n\tduk_memcpy((void *) p, (const void *) p_start, (size_t) need_bytes);\n\tp += need_bytes;\n\t/*avail_bytes += need_bytes*/\n\n\tDUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, p);\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/* Shared entry handling for object/array serialization. */\nDUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hobject *h_target;\n\tduk_uint_fast32_t i, n;\n\n\t*entry_top = duk_get_top(thr);\n\n\tduk_require_stack(thr, DUK_JSON_ENC_REQSTACK);\n\n\t/* Loop check using a hybrid approach: a fixed-size visited[] array\n\t * with overflow in a loop check object.\n\t */\n\n\th_target = duk_known_hobject(thr, -1);  /* object or array */\n\n\tn = js_ctx->recursion_depth;\n\tif (DUK_UNLIKELY(n > DUK_JSON_ENC_LOOPARRAY)) {\n\t\tn = DUK_JSON_ENC_LOOPARRAY;\n\t}\n\tfor (i = 0; i < n; i++) {\n\t\tif (DUK_UNLIKELY(js_ctx->visiting[i] == h_target)) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"slow path loop detect\"));\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CYCLIC_INPUT);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t}\n\tif (js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY) {\n\t\tjs_ctx->visiting[js_ctx->recursion_depth] = h_target;\n\t} else {\n\t\tduk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) h_target);\n\t\tduk_dup_top(thr);  /* -> [ ... voidp voidp ] */\n\t\tif (duk_has_prop(thr, js_ctx->idx_loop)) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CYCLIC_INPUT);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tduk_push_true(thr);  /* -> [ ... voidp true ] */\n\t\tduk_put_prop(thr, js_ctx->idx_loop);  /* -> [ ... ] */\n\t}\n\n\t/* C recursion check. */\n\n\tDUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0);  /* unsigned */\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tif (js_ctx->recursion_depth >= js_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_JSONENC_RECLIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tjs_ctx->recursion_depth++;\n\n\tDUK_DDD(DUK_DDDPRINT(\"shared entry finished: top=%ld, loop=%!T\",\n\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop)));\n}\n\n/* Shared exit handling for object/array serialization. */\nDUK_LOCAL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hobject *h_target;\n\n\t/* C recursion check. */\n\n\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\tjs_ctx->recursion_depth--;\n\n\t/* Loop check. */\n\n\th_target = duk_known_hobject(thr, *entry_top - 1);  /* original target at entry_top - 1 */\n\n\tif (js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY) {\n\t\t/* Previous entry was inside visited[], nothing to do. */\n\t} else {\n\t\tduk_push_sprintf(thr, DUK_STR_FMT_PTR, (void *) h_target);\n\t\tduk_del_prop(thr, js_ctx->idx_loop);  /* -> [ ... ] */\n\t}\n\n\t/* Restore stack top after unbalanced code paths. */\n\tduk_set_top(thr, *entry_top);\n\n\tDUK_DDD(DUK_DDDPRINT(\"shared entry finished: top=%ld, loop=%!T\",\n\t                     (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop)));\n}\n\n/* The JO(value) operation: encode object.\n *\n * Stack policy: [ object ] -> [ object ].\n */\nDUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_hstring *h_key;\n\tduk_idx_t entry_top;\n\tduk_idx_t idx_obj;\n\tduk_idx_t idx_keys;\n\tduk_bool_t emitted;\n\tduk_uarridx_t arr_len, i;\n\tduk_size_t prev_size;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_object: obj=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__enc_objarr_entry(js_ctx, &entry_top);\n\n\tidx_obj = entry_top - 1;\n\n\tif (js_ctx->idx_proplist >= 0) {\n\t\tidx_keys = js_ctx->idx_proplist;\n\t} else {\n\t\t/* XXX: would be nice to enumerate an object at specified index */\n\t\tduk_dup(thr, idx_obj);\n\t\t(void) duk_hobject_get_enumerated_keys(thr, DUK_ENUM_OWN_PROPERTIES_ONLY /*flags*/);  /* [ ... target ] -> [ ... target keys ] */\n\t\tidx_keys = duk_require_normalize_index(thr, -1);\n\t\t/* leave stack unbalanced on purpose */\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"idx_keys=%ld, h_keys=%!T\",\n\t                     (long) idx_keys, (duk_tval *) duk_get_tval(thr, idx_keys)));\n\n\t/* Steps 8-10 have been merged to avoid a \"partial\" variable. */\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);\n\n\t/* XXX: keys is an internal object with all keys to be processed\n\t * in its (gapless) array part.  Because nobody can touch the keys\n\t * object, we could iterate its array part directly (keeping in mind\n\t * that it can be reallocated).\n\t */\n\n\tarr_len = (duk_uarridx_t) duk_get_length(thr, idx_keys);\n\temitted = 0;\n\tfor (i = 0; i < arr_len; i++) {\n\t\tduk_get_prop_index(thr, idx_keys, i);  /* -> [ ... key ] */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"object property loop: holder=%!T, key=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_obj),\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\th_key = duk_known_hstring(thr, -1);\n\t\tDUK_ASSERT(h_key != NULL);\n\t\tDUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(h_key));  /* proplist filtering; enum options */\n\n\t\tprev_size = DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw);\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t\tduk__enc_key_autoquote(js_ctx, h_key);\n\t\t\tDUK__EMIT_2(js_ctx, DUK_ASC_COLON, DUK_ASC_SPACE);\n\t\t} else {\n\t\t\tduk__enc_key_autoquote(js_ctx, h_key);\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COLON);\n\t\t}\n\n\t\t/* [ ... key ] */\n\n\t\tif (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_obj) == 0)) {\n\t\t\t/* Value would yield 'undefined', so skip key altogether.\n\t\t\t * Side effects have already happened.\n\t\t\t */\n\t\t\tDUK_BW_SET_SIZE(js_ctx->thr, &js_ctx->bw, prev_size);\n\t\t} else {\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\t\temitted = 1;\n\t\t}\n\n\t\t/* [ ... ] */\n\t}\n\n\tif (emitted) {\n\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t}\n\t}\n\tDUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);\n\n\tduk__enc_objarr_exit(js_ctx, &entry_top);\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n}\n\n/* The JA(value) operation: encode array.\n *\n * Stack policy: [ array ] -> [ array ].\n */\nDUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_idx_t entry_top;\n\tduk_idx_t idx_arr;\n\tduk_bool_t emitted;\n\tduk_uarridx_t i, arr_len;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_array: array=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tduk__enc_objarr_entry(js_ctx, &entry_top);\n\n\tidx_arr = entry_top - 1;\n\n\t/* Steps 8-10 have been merged to avoid a \"partial\" variable. */\n\n\tDUK__EMIT_1(js_ctx, DUK_ASC_LBRACKET);\n\n\tarr_len = (duk_uarridx_t) duk_get_length(thr, idx_arr);\n\temitted = 0;\n\tfor (i = 0; i < arr_len; i++) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"array entry loop: array=%!T, index=%ld, arr_len=%ld\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_arr),\n\t\t                     (long) i, (long) arr_len));\n\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t}\n\n\t\t(void) duk_push_uint_to_hstring(thr, (duk_uint_t) i);  /* -> [ ... key ] */\n\n\t\t/* [ ... key ] */\n\n\t\tif (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_arr) == 0)) {\n\t\t\t/* Value would normally be omitted, replace with 'null'. */\n\t\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\t} else {\n\t\t\t;\n\t\t}\n\n\t\t/* [ ... ] */\n\n\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\temitted = 1;\n\t}\n\n\tif (emitted) {\n\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t}\n\t}\n\tDUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET);\n\n\tduk__enc_objarr_exit(js_ctx, &entry_top);\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n}\n\n/* The Str(key, holder) operation.\n *\n * Stack policy: [ ... key ] -> [ ... ]\n */\nDUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder) {\n\tduk_hthread *thr = js_ctx->thr;\n\tduk_tval *tv;\n\tduk_tval *tv_holder;\n\tduk_tval *tv_key;\n\tduk_small_int_t c;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__enc_value: idx_holder=%ld, holder=%!T, key=%!T\",\n\t                     (long) idx_holder, (duk_tval *) duk_get_tval(thr, idx_holder),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\ttv_holder = DUK_GET_TVAL_POSIDX(thr, idx_holder);\n\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_holder));\n\ttv_key = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_key));\n\tDUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(DUK_TVAL_GET_STRING(tv_key)));  /* Caller responsible. */\n\t(void) duk_hobject_getprop(thr, tv_holder, tv_key);\n\n\t/* -> [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* Standard JSON checks for .toJSON() only for actual objects; for\n\t * example, setting Number.prototype.toJSON and then serializing a\n\t * number won't invoke the .toJSON() method.  However, lightfuncs and\n\t * plain buffers mimic objects so we check for their .toJSON() method.\n\t */\n\tif (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT |\n\t                                 DUK_TYPE_MASK_LIGHTFUNC |\n\t                                 DUK_TYPE_MASK_BUFFER)) {\n\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_TO_JSON);\n\t\tif (duk_is_callable(thr, -1)) {  /* toJSON() can also be a lightfunc */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is object, has callable toJSON() -> call it\"));\n\t\t\t/* XXX: duk_dup_unvalidated(thr, -2) etc. */\n\t\t\tduk_dup_m2(thr);          /* -> [ ... key val toJSON val ] */\n\t\t\tduk_dup_m4(thr);          /* -> [ ... key val toJSON val key ] */\n\t\t\tduk_call_method(thr, 1);  /* -> [ ... key val val' ] */\n\t\t\tduk_remove_m2(thr);       /* -> [ ... key val' ] */\n\t\t} else {\n\t\t\tduk_pop(thr);             /* -> [ ... key val ] */\n\t\t}\n\t}\n\n\t/* [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (js_ctx->h_replacer) {\n\t\t/* XXX: Here a \"slice copy\" would be useful. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"replacer is set, call replacer\"));\n\t\tduk_push_hobject(thr, js_ctx->h_replacer);  /* -> [ ... key val replacer ] */\n\t\tduk_dup(thr, idx_holder);                   /* -> [ ... key val replacer holder ] */\n\t\tduk_dup_m4(thr);                            /* -> [ ... key val replacer holder key ] */\n\t\tduk_dup_m4(thr);                            /* -> [ ... key val replacer holder key val ] */\n\t\tduk_call_method(thr, 2);                    /* -> [ ... key val val' ] */\n\t\tduk_remove_m2(thr);                         /* -> [ ... key val' ] */\n\t}\n\n\t/* [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h) &&\n\t\t    js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE)) {\n\t\t\t/* With JX/JC a bufferobject gets serialized specially. */\n\t\t\tduk_hbufobj *h_bufobj;\n\t\t\th_bufobj = (duk_hbufobj *) h;\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\t\t\tduk__enc_bufobj(js_ctx, h_bufobj);\n\t\t\tgoto pop2_emitted;\n\t\t}\n\t\t/* Otherwise bufferobjects get serialized as normal objects. */\n#endif  /* JX || JC */\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t\tc = (duk_small_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h);\n\t\tswitch (c) {\n\t\tcase DUK_HOBJECT_CLASS_NUMBER: {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is a Number object -> coerce with ToNumber()\"));\n\t\t\tduk_to_number_m1(thr);\n\t\t\t/* The coercion potentially invokes user .valueOf() and .toString()\n\t\t\t * but can't result in a function value because ToPrimitive() would\n\t\t\t * reject such a result: test-dev-json-stringify-coercion-1.js.\n\t\t\t */\n\t\t\tDUK_ASSERT(!duk_is_callable(thr, -1));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_HOBJECT_CLASS_STRING: {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is a String object -> coerce with ToString()\"));\n\t\t\tduk_to_string(thr, -1);\n\t\t\t/* Same coercion behavior as for Number. */\n\t\t\tDUK_ASSERT(!duk_is_callable(thr, -1));\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tcase DUK_HOBJECT_CLASS_POINTER:\n#endif\n\t\tcase DUK_HOBJECT_CLASS_BOOLEAN: {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"value is a Boolean/Buffer/Pointer object -> get internal value\"));\n\t\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t\t\tduk_remove_m2(thr);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\t/* Normal object which doesn't get automatically coerced to a\n\t\t\t * primitive value.  Functions are checked for specially.  The\n\t\t\t * primitive value coercions for Number, String, Pointer, and\n\t\t\t * Boolean can't result in functions so suffices to check here.\n\t\t\t * Symbol objects are handled like plain objects (their primitive\n\t\t\t * value is NOT looked up like for e.g. String objects).\n\t\t\t */\n\t\t\tDUK_ASSERT(h != NULL);\n\t\t\tif (DUK_HOBJECT_IS_CALLABLE(h)) {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t\t\tif (js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM |\n\t\t\t\t                     DUK_JSON_FLAG_EXT_COMPATIBLE)) {\n\t\t\t\t\t/* We only get here when doing non-standard JSON encoding */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> function allowed, serialize to custom format\"));\n\t\t\t\t\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);\n\t\t\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function);\n\t\t\t\t\tgoto pop2_emitted;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> will result in undefined (function)\"));\n\t\t\t\t\tgoto pop2_undef;\n\t\t\t\t}\n#else  /* DUK_USE_JX || DUK_USE_JC */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> will result in undefined (function)\"));\n\t\t\t\tgoto pop2_undef;\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\t\t\t}\n\t\t}\n\t\t}  /* end switch */\n\t}\n\n\t/* [ ... key val ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"value=%!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (duk_check_type_mask(thr, -1, js_ctx->mask_for_undefined)) {\n\t\t/* will result in undefined */\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> will result in undefined (type mask check)\"));\n\t\tgoto pop2_undef;\n\t}\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t/* When JX/JC not in use, the type mask above will avoid this case if needed. */\n\tcase DUK_TAG_UNDEFINED: {\n\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined);\n\t\tbreak;\n\t}\n#endif\n\tcase DUK_TAG_NULL: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_TVAL_GET_BOOLEAN(tv) ?\n\t\t                 DUK_STRIDX_TRUE : DUK_STRIDX_FALSE);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t/* When JX/JC not in use, the type mask above will avoid this case if needed. */\n\tcase DUK_TAG_POINTER: {\n\t\tduk__enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv));\n\t\tbreak;\n\t}\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tgoto pop2_undef;\n\t\t}\n\t\tduk__enc_quote_string(js_ctx, h);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* Function values are handled completely above (including\n\t\t * coercion results):\n\t\t */\n\t\tDUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE(h));\n\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tduk__enc_array(js_ctx);\n\t\t} else {\n\t\t\tduk__enc_object(js_ctx);\n\t\t}\n\t\tbreak;\n\t}\n\t/* Because plain buffers mimics Uint8Array, they have enumerable\n\t * index properties [0,byteLength[.  Because JSON only serializes\n\t * enumerable own properties, no properties can be serialized for\n\t * plain buffers (all virtual properties are non-enumerable).  However,\n\t * there may be a .toJSON() method which was already handled above.\n\t */\n\tcase DUK_TAG_BUFFER: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tduk__enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv));\n\t\t\tbreak;\n\t\t}\n#endif\n\n\t\t/* Could implement a fastpath, but the fast path would need\n\t\t * to handle realloc side effects correctly.\n\t\t */\n\t\tduk_to_object(thr, -1);\n\t\tduk__enc_object(js_ctx);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t/* We only get here when doing non-standard JSON encoding */\n\t\tDUK_ASSERT(js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible);\n\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function);\n#else\n\t\t/* Standard JSON omits functions */\n\t\tDUK_UNREACHABLE();\n#endif\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\t/* Number serialization has a significant impact relative to\n\t\t * other fast path code, so careful fast path for fastints.\n\t\t */\n\t\tduk__enc_fastint_tval(js_ctx, tv);\n\t\tbreak;\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\t/* XXX: A fast path for usual integers would be useful when\n\t\t * fastint support is not enabled.\n\t\t */\n\t\tduk__enc_double(js_ctx);\n\t\tbreak;\n\t}\n\t}\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n pop2_emitted:\n#endif\n\tduk_pop_2(thr); /* [ ... key val ] -> [ ... ] */\n\treturn 1;  /* emitted */\n\n pop2_undef:\n\tduk_pop_2(thr);  /* [ ... key val ] -> [ ... ] */\n\treturn 0;  /* not emitted */\n}\n\n/* E5 Section 15.12.3, main algorithm, step 4.b.ii steps 1-4. */\nDUK_LOCAL duk_bool_t duk__enc_allow_into_proplist(duk_tval *tv) {\n\tduk_small_int_t c;\n\n\t/* XXX: some kind of external internal type checker?\n\t * - type mask; symbol flag; class mask\n\t */\n\tDUK_ASSERT(tv != NULL);\n\tif (DUK_TVAL_IS_STRING(tv)) {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn 1;\n\t} else if (DUK_TVAL_IS_NUMBER(tv)) {\n\t\treturn 1;\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h;\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tc = (duk_small_int_t) DUK_HOBJECT_GET_CLASS_NUMBER(h);\n\t\tif (c == DUK_HOBJECT_CLASS_STRING || c == DUK_HOBJECT_CLASS_NUMBER) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n/*\n *  JSON.stringify() fast path\n *\n *  Otherwise supports full JSON, JX, and JC features, but bails out on any\n *  possible side effect which might change the value being serialized.  The\n *  fast path can take advantage of the fact that the value being serialized\n *  is unchanged so that we can walk directly through property tables etc.\n */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\nDUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, duk_tval *tv) {\n\tduk_uint_fast32_t i, n;\n\n\tDUK_DDD(DUK_DDDPRINT(\"stringify fast: %!T\", tv));\n\n\tDUK_ASSERT(js_ctx != NULL);\n\tDUK_ASSERT(js_ctx->thr != NULL);\n\n#if 0 /* disabled for now */\n restart_match:\n#endif\n\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom || js_ctx->flag_ext_compatible) {\n\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined);\n\t\t\tbreak;\n\t\t} else {\n\t\t\tgoto emit_undefined;\n\t\t}\n#else\n\t\tgoto emit_undefined;\n#endif\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK__EMIT_STRIDX(js_ctx, DUK_TVAL_GET_BOOLEAN(tv) ?\n\t\t                 DUK_STRIDX_TRUE : DUK_STRIDX_FALSE);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h;\n\t\th = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tgoto emit_undefined;\n\t\t}\n\t\tduk__enc_quote_string(js_ctx, h);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *obj;\n\t\tduk_tval *tv_val;\n\t\tduk_bool_t emitted = 0;\n\t\tduk_uint32_t c_bit, c_all, c_array, c_unbox, c_undef,\n\t\t             c_func, c_bufobj, c_object, c_abort;\n\n\t\t/* For objects JSON.stringify() only looks for own, enumerable\n\t\t * properties which is nice for the fast path here.\n\t\t *\n\t\t * For arrays JSON.stringify() uses [[Get]] so it will actually\n\t\t * inherit properties during serialization!  This fast path\n\t\t * supports gappy arrays as long as there's no actual inherited\n\t\t * property (which might be a getter etc).\n\t\t *\n\t\t * Since recursion only happens for objects, we can have both\n\t\t * recursion and loop checks here.  We use a simple, depth-limited\n\t\t * loop check in the fast path because the object-based tracking\n\t\t * is very slow (when tested, it accounted for 50% of fast path\n\t\t * execution time for input data with a lot of small objects!).\n\t\t */\n\n\t\t/* XXX: for real world code, could just ignore array inheritance\n\t\t * and only look at array own properties.\n\t\t */\n\n\t\t/* We rely on a few object flag / class number relationships here,\n\t\t * assert for them.\n\t\t */\n\n\t\tobj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(obj != NULL);\n\t\tDUK_HOBJECT_ASSERT_VALID(obj);\n\n\t\t/* Once recursion depth is increased, exit path must decrease\n\t\t * it (though it's OK to abort the fast path).\n\t\t */\n\n\t\tDUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0);  /* unsigned */\n\t\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\t\tif (js_ctx->recursion_depth >= js_ctx->recursion_limit) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"fast path recursion limit\"));\n\t\t\tDUK_ERROR_RANGE(js_ctx->thr, DUK_STR_JSONDEC_RECLIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\n\t\tfor (i = 0, n = (duk_uint_fast32_t) js_ctx->recursion_depth; i < n; i++) {\n\t\t\tif (DUK_UNLIKELY(js_ctx->visiting[i] == obj)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"fast path loop detect\"));\n\t\t\t\tDUK_ERROR_TYPE(js_ctx->thr, DUK_STR_CYCLIC_INPUT);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\n\t\t/* Guaranteed by recursion_limit setup so we don't have to\n\t\t * check twice.\n\t\t */\n\t\tDUK_ASSERT(js_ctx->recursion_depth < DUK_JSON_ENC_LOOPARRAY);\n\t\tjs_ctx->visiting[js_ctx->recursion_depth] = obj;\n\t\tjs_ctx->recursion_depth++;\n\n\t\t/* If object has a .toJSON() property, we can't be certain\n\t\t * that it wouldn't mutate any value arbitrarily, so bail\n\t\t * out of the fast path.\n\t\t *\n\t\t * If an object is a Proxy we also can't avoid side effects\n\t\t * so abandon.\n\t\t */\n\t\t/* XXX: non-callable .toJSON() doesn't need to cause an abort\n\t\t * but does at the moment, probably not worth fixing.\n\t\t */\n\t\tif (duk_hobject_hasprop_raw(js_ctx->thr, obj, DUK_HTHREAD_STRING_TO_JSON(js_ctx->thr)) ||\n\t\t    DUK_HOBJECT_IS_PROXY(obj)) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"object has a .toJSON property or object is a Proxy, abort fast path\"));\n\t\t\tgoto abort_fastpath;\n\t\t}\n\n\t\t/* We could use a switch-case for the class number but it turns out\n\t\t * a small if-else ladder on class masks is better.  The if-ladder\n\t\t * should be in order of relevancy.\n\t\t */\n\n\t\t/* XXX: move masks to js_ctx? they don't change during one\n\t\t * fast path invocation.\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_CLASS_MAX <= 31);\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tc_all = DUK_HOBJECT_CMASK_ALL;\n\t\t\tc_array = DUK_HOBJECT_CMASK_ARRAY;\n\t\t\tc_unbox = DUK_HOBJECT_CMASK_NUMBER |\n\t\t\t          DUK_HOBJECT_CMASK_STRING |\n\t\t\t          DUK_HOBJECT_CMASK_BOOLEAN |\n\t\t\t          DUK_HOBJECT_CMASK_POINTER;  /* Symbols are not unboxed. */\n\t\t\tc_func = DUK_HOBJECT_CMASK_FUNCTION;\n\t\t\tc_bufobj = DUK_HOBJECT_CMASK_ALL_BUFOBJS;\n\t\t\tc_undef = 0;\n\t\t\tc_abort = 0;\n\t\t\tc_object = c_all & ~(c_array | c_unbox | c_func | c_bufobj | c_undef | c_abort);\n\t\t}\n\t\telse\n#endif\n\t\t{\n\t\t\tc_all = DUK_HOBJECT_CMASK_ALL;\n\t\t\tc_array = DUK_HOBJECT_CMASK_ARRAY;\n\t\t\tc_unbox = DUK_HOBJECT_CMASK_NUMBER |\n\t\t\t          DUK_HOBJECT_CMASK_STRING |\n\t\t\t          DUK_HOBJECT_CMASK_BOOLEAN;  /* Symbols are not unboxed. */\n\t\t\tc_func = 0;\n\t\t\tc_bufobj = 0;\n\t\t\tc_undef = DUK_HOBJECT_CMASK_FUNCTION |\n\t\t\t          DUK_HOBJECT_CMASK_POINTER;\n\t\t\t/* As the fast path doesn't currently properly support\n\t\t\t * duk_hbufobj virtual properties, abort fast path if\n\t\t\t * we encounter them in plain JSON mode.\n\t\t\t */\n\t\t\tc_abort = DUK_HOBJECT_CMASK_ALL_BUFOBJS;\n\t\t\tc_object = c_all & ~(c_array | c_unbox | c_func | c_bufobj | c_undef | c_abort);\n\t\t}\n\n\t\tc_bit = (duk_uint32_t) DUK_HOBJECT_GET_CLASS_MASK(obj);\n\t\tif (c_bit & c_object) {\n\t\t\t/* All other object types. */\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_LCURLY);\n\n\t\t\t/* A non-Array object should not have an array part in practice.\n\t\t\t * But since it is supported internally (and perhaps used at some\n\t\t\t * point), check and abandon if that's the case.\n\t\t\t */\n\t\t\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"non-Array object has array part, abort fast path\"));\n\t\t\t\tgoto abort_fastpath;\n\t\t\t}\n\n\t\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\t\tduk_hstring *k;\n\t\t\t\tduk_size_t prev_size;\n\n\t\t\t\tk = DUK_HOBJECT_E_GET_KEY(js_ctx->thr->heap, obj, i);\n\t\t\t\tif (!k) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (DUK_HSTRING_HAS_ARRIDX(k)) {\n\t\t\t\t\t/* If an object has array index keys we would need\n\t\t\t\t\t * to sort them into the ES2015 enumeration order to\n\t\t\t\t\t * be consistent with the slow path.  Abort the fast\n\t\t\t\t\t * path and handle in the slow path for now.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"property key is an array index, abort fast path\"));\n\t\t\t\t\tgoto abort_fastpath;\n\t\t\t\t}\n\t\t\t\tif (!DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(js_ctx->thr->heap, obj, i)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(js_ctx->thr->heap, obj, i)) {\n\t\t\t\t\t/* Getter might have arbitrary side effects,\n\t\t\t\t\t * so bail out.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"property is an accessor, abort fast path\"));\n\t\t\t\t\tgoto abort_fastpath;\n\t\t\t\t}\n\t\t\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(k))) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\ttv_val = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(js_ctx->thr->heap, obj, i);\n\n\t\t\t\tprev_size = DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw);\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t\t\t\tduk__enc_key_autoquote(js_ctx, k);\n\t\t\t\t\tDUK__EMIT_2(js_ctx, DUK_ASC_COLON, DUK_ASC_SPACE);\n\t\t\t\t} else {\n\t\t\t\t\tduk__enc_key_autoquote(js_ctx, k);\n\t\t\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COLON);\n\t\t\t\t}\n\n\t\t\t\tif (duk__json_stringify_fast_value(js_ctx, tv_val) == 0) {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"prop value not supported, rewind key and colon\"));\n\t\t\t\t\tDUK_BW_SET_SIZE(js_ctx->thr, &js_ctx->bw, prev_size);\n\t\t\t\t} else {\n\t\t\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\t\t\t\temitted = 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* If any non-Array value had enumerable virtual own\n\t\t\t * properties, they should be serialized here (actually,\n\t\t\t * before the explicit properties).  Standard types don't.\n\t\t\t */\n\n\t\t\tif (emitted) {\n\t\t\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\t\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t\t\t}\n\t\t\t}\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_RCURLY);\n\t\t} else if (c_bit & c_array) {\n\t\t\tduk_uint_fast32_t arr_len;\n\t\t\tduk_uint_fast32_t asize;\n\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_LBRACKET);\n\n\t\t\t/* Assume arrays are dense in the fast path. */\n\t\t\tif (!DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"Array object is sparse, abort fast path\"));\n\t\t\t\tgoto abort_fastpath;\n\t\t\t}\n\n\t\t\tarr_len = (duk_uint_fast32_t) ((duk_harray *) obj)->length;\n\t\t\tasize = (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(obj);\n\t\t\t/* Array part may be larger than 'length'; if so, iterate\n\t\t\t * only up to array 'length'.  Array part may also be smaller\n\t\t\t * than 'length' in some cases.\n\t\t\t */\n\t\t\tfor (i = 0; i < arr_len; i++) {\n\t\t\t\tduk_tval *tv_arrval;\n\t\t\t\tduk_hstring *h_tmp;\n\t\t\t\tduk_bool_t has_inherited;\n\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth);\n\t\t\t\t}\n\n\t\t\t\tif (DUK_LIKELY(i < asize)) {\n\t\t\t\t\ttv_arrval = DUK_HOBJECT_A_GET_VALUE_PTR(js_ctx->thr->heap, obj, i);\n\t\t\t\t\tif (DUK_LIKELY(!DUK_TVAL_IS_UNUSED(tv_arrval))) {\n\t\t\t\t\t\t/* Expected case: element is present. */\n\t\t\t\t\t\tif (duk__json_stringify_fast_value(js_ctx, tv_arrval) == 0) {\n\t\t\t\t\t\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tgoto elem_done;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* Gap in array; check for inherited property,\n\t\t\t\t * bail out if one exists.  This should be enough\n\t\t\t\t * to support gappy arrays for all practical code.\n\t\t\t\t */\n\n\t\t\t\th_tmp = duk_push_uint_to_hstring(js_ctx->thr, (duk_uint_t) i);\n\t\t\t\thas_inherited = duk_hobject_hasprop_raw(js_ctx->thr, obj, h_tmp);\n\t\t\t\tduk_pop(js_ctx->thr);\n\t\t\t\tif (has_inherited) {\n\t\t\t\t\tDUK_D(DUK_DPRINT(\"gap in array, conflicting inherited property, abort fast path\"));\n\t\t\t\t\tgoto abort_fastpath;\n\t\t\t\t}\n\n\t\t\t\t/* Ordinary gap, undefined encodes to 'null' in\n\t\t\t\t * standard JSON, but JX/JC use their form for\n\t\t\t\t * undefined to better preserve the typing.\n\t\t\t\t */\n\t\t\t\tDUK_D(DUK_DPRINT(\"gap in array, no conflicting inherited property, remain on fast path\"));\n#if defined(DUK_USE_JX)\n\t\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_undefined);\n#else\n\t\t\t\tDUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL);\n#endif\n\t\t\t\t/* fall through */\n\n\t\t\t elem_done:\n\t\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_COMMA);\n\t\t\t\temitted = 1;\n\t\t\t}\n\n\t\t\tif (emitted) {\n\t\t\t\tDUK_ASSERT(*((duk_uint8_t *) DUK_BW_GET_PTR(js_ctx->thr, &js_ctx->bw) - 1) == DUK_ASC_COMMA);\n\t\t\t\tDUK__UNEMIT_1(js_ctx);  /* eat trailing comma */\n\t\t\t\tif (DUK_UNLIKELY(js_ctx->h_gap != NULL)) {\n\t\t\t\t\tDUK_ASSERT(js_ctx->recursion_depth >= 1);\n\t\t\t\t\tduk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U);\n\t\t\t\t}\n\t\t\t}\n\t\t\tDUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET);\n\t\t} else if (c_bit & c_unbox) {\n\t\t\t/* Certain boxed types are required to go through\n\t\t\t * automatic unboxing.  Rely on internal value being\n\t\t\t * sane (to avoid infinite recursion).\n\t\t\t */\n\t\t\tDUK_ASSERT((c_bit & DUK_HOBJECT_CMASK_SYMBOL) == 0);  /* Symbols are not unboxed. */\n\n#if 1\n\t\t\t/* The code below is incorrect if .toString() or .valueOf() have\n\t\t\t * have been overridden.  The correct approach would be to look up\n\t\t\t * the method(s) and if they resolve to the built-in function we\n\t\t\t * can safely bypass it and look up the internal value directly.\n\t\t\t * Unimplemented for now, abort fast path for boxed values.\n\t\t\t */\n\t\t\tgoto abort_fastpath;\n#else  /* disabled */\n\t\t\t/* Disabled until fixed, see above. */\n\t\t\tduk_tval *tv_internal;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"auto unboxing in fast path\"));\n\n\t\t\ttv_internal = duk_hobject_get_internal_value_tval_ptr(js_ctx->thr->heap, obj);\n\t\t\tDUK_ASSERT(tv_internal != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_internal) ||\n\t\t\t           DUK_TVAL_IS_NUMBER(tv_internal) ||\n\t\t\t           DUK_TVAL_IS_BOOLEAN(tv_internal) ||\n\t\t\t           DUK_TVAL_IS_POINTER(tv_internal));\n\n\t\t\ttv = tv_internal;\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\t\t\tjs_ctx->recursion_depth--;  /* required to keep recursion depth correct */\n\t\t\tgoto restart_match;\n#endif  /* disabled */\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\t} else if (c_bit & c_func) {\n\t\t\tDUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t} else if (c_bit & c_bufobj) {\n\t\t\tduk__enc_bufobj(js_ctx, (duk_hbufobj *) obj);\n#endif\n#endif\n\t\t} else if (c_bit & c_abort) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"abort fast path for unsupported type\"));\n\t\t\tgoto abort_fastpath;\n\t\t} else {\n\t\t\tDUK_ASSERT((c_bit & c_undef) != 0);\n\n\t\t\t/* Must decrease recursion depth before returning. */\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\t\t\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\t\t\tjs_ctx->recursion_depth--;\n\t\t\tgoto emit_undefined;\n\t\t}\n\n\t\tDUK_ASSERT(js_ctx->recursion_depth > 0);\n\t\tDUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit);\n\t\tjs_ctx->recursion_depth--;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\t/* Plain buffers are treated like Uint8Arrays: they have\n\t\t * enumerable indices.  Other virtual properties are not\n\t\t * enumerable, and inherited properties are not serialized.\n\t\t * However, there can be a replacer (not relevant here) or\n\t\t * a .toJSON() method (which we need to check for explicitly).\n\t\t */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (duk_hobject_hasprop_raw(js_ctx->thr,\n\t\t                            js_ctx->thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE],\n\t\t                            DUK_HTHREAD_STRING_TO_JSON(js_ctx->thr))) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"value is a plain buffer and there's an inherited .toJSON, abort fast path\"));\n\t\t\tgoto abort_fastpath;\n\t\t}\n#endif\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tduk__enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv));\n\t\t\tbreak;\n\t\t}\n#endif\n\n\t\t/* Plain buffers mimic Uint8Arrays, and have enumerable index\n\t\t * properties.\n\t\t */\n\t\tduk__enc_buffer_json_fastpath(js_ctx, DUK_TVAL_GET_BUFFER(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_POINTER: {\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\t\tif (js_ctx->flag_ext_custom_or_compatible) {\n\t\t\tduk__enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv));\n\t\t\tbreak;\n\t\t} else {\n\t\t\tgoto emit_undefined;\n\t\t}\n#else\n\t\tgoto emit_undefined;\n#endif\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* A lightfunc might also inherit a .toJSON() so just bail out. */\n\t\t/* XXX: Could just lookup .toJSON() and continue in fast path,\n\t\t * as it would almost never be defined.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"value is a lightfunc, abort fast path\"));\n\t\tgoto abort_fastpath;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT: {\n\t\t/* Number serialization has a significant impact relative to\n\t\t * other fast path code, so careful fast path for fastints.\n\t\t */\n\t\tduk__enc_fastint_tval(js_ctx, tv);\n\t\tbreak;\n\t}\n#endif\n\tdefault: {\n\t\t/* XXX: A fast path for usual integers would be useful when\n\t\t * fastint support is not enabled.\n\t\t */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\n\t\t/* XXX: Stack discipline is annoying, could be changed in numconv. */\n\t\tduk_push_tval(js_ctx->thr, tv);\n\t\tduk__enc_double(js_ctx);\n\t\tduk_pop(js_ctx->thr);\n\n#if 0\n\t\t/* Could also rely on native sprintf(), but it will handle\n\t\t * values like NaN, Infinity, -0, exponent notation etc in\n\t\t * a JSON-incompatible way.\n\t\t */\n\t\tduk_double_t d;\n\t\tchar buf[64];\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\t\td = DUK_TVAL_GET_DOUBLE(tv);\n\t\tDUK_SPRINTF(buf, \"%lg\", d);\n\t\tDUK__EMIT_CSTR(js_ctx, buf);\n#endif\n\t}\n\t}\n\treturn 1;  /* not undefined */\n\n emit_undefined:\n\treturn 0;  /* value was undefined/unsupported */\n\n abort_fastpath:\n\t/* Error message doesn't matter: the error is ignored anyway. */\n\tDUK_DD(DUK_DDPRINT(\"aborting fast path\"));\n\tDUK_ERROR_INTERNAL(js_ctx->thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_LOCAL duk_ret_t duk__json_stringify_fast(duk_hthread *thr, void *udata) {\n\tduk_json_enc_ctx *js_ctx;\n\tduk_tval *tv;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(udata != NULL);\n\n\tjs_ctx = (duk_json_enc_ctx *) udata;\n\tDUK_ASSERT(js_ctx != NULL);\n\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tif (duk__json_stringify_fast_value(js_ctx, tv) == 0) {\n\t\tDUK_DD(DUK_DDPRINT(\"top level value not supported, fail fast path\"));\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);  /* Error message is ignored, so doesn't matter. */\n\t}\n\n\treturn 0;\n}\n#endif  /* DUK_USE_JSON_STRINGIFY_FASTPATH */\n\n/*\n *  Top level wrappers\n */\n\nDUK_INTERNAL\nvoid duk_bi_json_parse_helper(duk_hthread *thr,\n                              duk_idx_t idx_value,\n                              duk_idx_t idx_reviver,\n                              duk_small_uint_t flags) {\n\tduk_json_dec_ctx js_ctx_alloc;\n\tduk_json_dec_ctx *js_ctx = &js_ctx_alloc;\n\tduk_hstring *h_text;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top = duk_get_top(thr);\n#endif\n\n\t/* negative top-relative indices not allowed now */\n\tDUK_ASSERT(idx_value == DUK_INVALID_INDEX || idx_value >= 0);\n\tDUK_ASSERT(idx_reviver == DUK_INVALID_INDEX || idx_reviver >= 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON parse start: text=%!T, reviver=%!T, flags=0x%08lx, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_reviver),\n\t                     (unsigned long) flags,\n\t                     (long) duk_get_top(thr)));\n\n\tduk_memzero(&js_ctx_alloc, sizeof(js_ctx_alloc));\n\tjs_ctx->thr = thr;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t/* nothing now */\n#endif\n\tjs_ctx->recursion_limit = DUK_USE_JSON_DEC_RECLIMIT;\n\tDUK_ASSERT(js_ctx->recursion_depth == 0);\n\n\t/* Flag handling currently assumes that flags are consistent.  This is OK\n\t * because the call sites are now strictly controlled.\n\t */\n\n\tjs_ctx->flags = flags;\n#if defined(DUK_USE_JX)\n\tjs_ctx->flag_ext_custom = flags & DUK_JSON_FLAG_EXT_CUSTOM;\n#endif\n#if defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_compatible = flags & DUK_JSON_FLAG_EXT_COMPATIBLE;\n#endif\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_custom_or_compatible = flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE);\n#endif\n\n\th_text = duk_to_hstring(thr, idx_value);  /* coerce in-place; rejects Symbols */\n\tDUK_ASSERT(h_text != NULL);\n\n\t/* JSON parsing code is allowed to read [p_start,p_end]: p_end is\n\t * valid and points to the string NUL terminator (which is always\n\t * guaranteed for duk_hstrings.\n\t */\n\tjs_ctx->p_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_text);\n\tjs_ctx->p = js_ctx->p_start;\n\tjs_ctx->p_end = ((const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_text)) +\n\t                DUK_HSTRING_GET_BYTELEN(h_text);\n\tDUK_ASSERT(*(js_ctx->p_end) == 0x00);\n\n\tduk__dec_value(js_ctx);  /* -> [ ... value ] */\n\n\t/* Trailing whitespace has been eaten by duk__dec_value(), so if\n\t * we're not at end of input here, it's a SyntaxError.\n\t */\n\n\tif (js_ctx->p != js_ctx->p_end) {\n\t\tduk__dec_syntax_error(js_ctx);\n\t}\n\n\tif (duk_is_callable(thr, idx_reviver)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"applying reviver: %!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_reviver)));\n\n\t\tjs_ctx->idx_reviver = idx_reviver;\n\n\t\tduk_push_object(thr);\n\t\tduk_dup_m2(thr);  /* -> [ ... val root val ] */\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_EMPTY_STRING);  /* default attrs ok */\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_EMPTY_STRING);  /* -> [ ... val root \"\" ] */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"start reviver walk, root=%!T, name=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\tduk__dec_reviver_walk(js_ctx);  /* [ ... val root \"\" ] -> [ ... val val' ] */\n\t\tduk_remove_m2(thr);             /* -> [ ... val' ] */\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"reviver does not exist or is not callable: %!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, idx_reviver)));\n\t}\n\n\t/* Final result is at stack top. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON parse end: text=%!T, reviver=%!T, flags=0x%08lx, result=%!T, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_reviver),\n\t                     (unsigned long) flags,\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (long) duk_get_top(thr)));\n\n\tDUK_ASSERT(duk_get_top(thr) == entry_top + 1);\n}\n\nDUK_INTERNAL\nvoid duk_bi_json_stringify_helper(duk_hthread *thr,\n                                  duk_idx_t idx_value,\n                                  duk_idx_t idx_replacer,\n                                  duk_idx_t idx_space,\n                                  duk_small_uint_t flags) {\n\tduk_json_enc_ctx js_ctx_alloc;\n\tduk_json_enc_ctx *js_ctx = &js_ctx_alloc;\n\tduk_hobject *h;\n\tduk_idx_t idx_holder;\n\tduk_idx_t entry_top;\n\n\t/* negative top-relative indices not allowed now */\n\tDUK_ASSERT(idx_value == DUK_INVALID_INDEX || idx_value >= 0);\n\tDUK_ASSERT(idx_replacer == DUK_INVALID_INDEX || idx_replacer >= 0);\n\tDUK_ASSERT(idx_space == DUK_INVALID_INDEX || idx_space >= 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON stringify start: value=%!T, replacer=%!T, space=%!T, flags=0x%08lx, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_replacer),\n\t                     (duk_tval *) duk_get_tval(thr, idx_space),\n\t                     (unsigned long) flags,\n\t                     (long) duk_get_top(thr)));\n\n\tentry_top = duk_get_top(thr);\n\n\t/*\n\t *  Context init\n\t */\n\n\tduk_memzero(&js_ctx_alloc, sizeof(js_ctx_alloc));\n\tjs_ctx->thr = thr;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tjs_ctx->h_replacer = NULL;\n\tjs_ctx->h_gap = NULL;\n#endif\n\tjs_ctx->idx_proplist = -1;\n\n\t/* Flag handling currently assumes that flags are consistent.  This is OK\n\t * because the call sites are now strictly controlled.\n\t */\n\n\tjs_ctx->flags = flags;\n\tjs_ctx->flag_ascii_only = flags & DUK_JSON_FLAG_ASCII_ONLY;\n\tjs_ctx->flag_avoid_key_quotes = flags & DUK_JSON_FLAG_AVOID_KEY_QUOTES;\n#if defined(DUK_USE_JX)\n\tjs_ctx->flag_ext_custom = flags & DUK_JSON_FLAG_EXT_CUSTOM;\n#endif\n#if defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_compatible = flags & DUK_JSON_FLAG_EXT_COMPATIBLE;\n#endif\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tjs_ctx->flag_ext_custom_or_compatible = flags & (DUK_JSON_FLAG_EXT_CUSTOM | DUK_JSON_FLAG_EXT_COMPATIBLE);\n#endif\n\n\t/* The #if defined() clutter here handles the JX/JC enable/disable\n\t * combinations properly.\n\t */\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tjs_ctx->stridx_custom_undefined = DUK_STRIDX_LC_NULL;  /* standard JSON; array gaps */\n#if defined(DUK_USE_JX)\n\tif (flags & DUK_JSON_FLAG_EXT_CUSTOM) {\n\t\tjs_ctx->stridx_custom_undefined = DUK_STRIDX_LC_UNDEFINED;\n\t\tjs_ctx->stridx_custom_nan = DUK_STRIDX_NAN;\n\t\tjs_ctx->stridx_custom_neginf = DUK_STRIDX_MINUS_INFINITY;\n\t\tjs_ctx->stridx_custom_posinf = DUK_STRIDX_INFINITY;\n\t\tjs_ctx->stridx_custom_function =\n\t\t        (flags & DUK_JSON_FLAG_AVOID_KEY_QUOTES) ?\n\t\t                DUK_STRIDX_JSON_EXT_FUNCTION2 :\n\t\t                DUK_STRIDX_JSON_EXT_FUNCTION1;\n\t}\n#endif  /* DUK_USE_JX */\n#if defined(DUK_USE_JX) && defined(DUK_USE_JC)\n\telse\n#endif  /* DUK_USE_JX && DUK_USE_JC */\n#if defined(DUK_USE_JC)\n\tif (js_ctx->flags & DUK_JSON_FLAG_EXT_COMPATIBLE) {\n\t\tjs_ctx->stridx_custom_undefined = DUK_STRIDX_JSON_EXT_UNDEFINED;\n\t\tjs_ctx->stridx_custom_nan = DUK_STRIDX_JSON_EXT_NAN;\n\t\tjs_ctx->stridx_custom_neginf = DUK_STRIDX_JSON_EXT_NEGINF;\n\t\tjs_ctx->stridx_custom_posinf = DUK_STRIDX_JSON_EXT_POSINF;\n\t\tjs_ctx->stridx_custom_function = DUK_STRIDX_JSON_EXT_FUNCTION1;\n\t}\n#endif  /* DUK_USE_JC */\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tif (js_ctx->flags & (DUK_JSON_FLAG_EXT_CUSTOM |\n\t                     DUK_JSON_FLAG_EXT_COMPATIBLE)) {\n\t\tDUK_ASSERT(js_ctx->mask_for_undefined == 0);  /* already zero */\n\t}\n\telse\n#endif  /* DUK_USE_JX || DUK_USE_JC */\n\t{\n\t\t/* Plain buffer is treated like ArrayBuffer and serialized.\n\t\t * Lightfuncs are treated like objects, but JSON explicitly\n\t\t * skips serializing Function objects so we can just reject\n\t\t * lightfuncs here.\n\t\t */\n\t\tjs_ctx->mask_for_undefined = DUK_TYPE_MASK_UNDEFINED |\n\t\t                             DUK_TYPE_MASK_POINTER |\n\t\t                             DUK_TYPE_MASK_LIGHTFUNC;\n\t}\n\n\tDUK_BW_INIT_PUSHBUF(thr, &js_ctx->bw, DUK__JSON_STRINGIFY_BUFSIZE);\n\n\tjs_ctx->idx_loop = duk_push_bare_object(thr);\n\tDUK_ASSERT(js_ctx->idx_loop >= 0);\n\n\t/* [ ... buf loop ] */\n\n\t/*\n\t *  Process replacer/proplist (2nd argument to JSON.stringify)\n\t */\n\n\th = duk_get_hobject(thr, idx_replacer);\n\tif (h != NULL) {\n\t\tif (DUK_HOBJECT_IS_CALLABLE(h)) {\n\t\t\tjs_ctx->h_replacer = h;\n\t\t} else if (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\t/* Here the specification requires correct array index enumeration\n\t\t\t * which is a bit tricky for sparse arrays (it is handled by the\n\t\t\t * enum setup code).  We now enumerate ancestors too, although the\n\t\t\t * specification is not very clear on whether that is required.\n\t\t\t */\n\n\t\t\tduk_uarridx_t plist_idx = 0;\n\t\t\tduk_small_uint_t enum_flags;\n\n\t\t\tjs_ctx->idx_proplist = duk_push_array(thr);  /* XXX: array internal? */\n\n\t\t\tenum_flags = DUK_ENUM_ARRAY_INDICES_ONLY |\n\t\t\t             DUK_ENUM_SORT_ARRAY_INDICES;  /* expensive flag */\n\t\t\tduk_enum(thr, idx_replacer, enum_flags);\n\t\t\twhile (duk_next(thr, -1 /*enum_index*/, 1 /*get_value*/)) {\n\t\t\t\t/* [ ... proplist enum_obj key val ] */\n\t\t\t\tif (duk__enc_allow_into_proplist(duk_get_tval(thr, -1))) {\n\t\t\t\t\t/* XXX: duplicates should be eliminated here */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proplist enum: key=%!T, val=%!T --> accept\",\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\t\t\tduk_to_string(thr, -1);  /* extra coercion of strings is OK */\n\t\t\t\t\tduk_put_prop_index(thr, -4, plist_idx);  /* -> [ ... proplist enum_obj key ] */\n\t\t\t\t\tplist_idx++;\n\t\t\t\t\tduk_pop(thr);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proplist enum: key=%!T, val=%!T --> reject\",\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\t\t\tduk_pop_2(thr);\n\t\t\t\t}\n                        }\n                        duk_pop(thr);  /* pop enum */\n\n\t\t\t/* [ ... proplist ] */\n\t\t}\n\t}\n\n\t/* [ ... buf loop (proplist) ] */\n\n\t/*\n\t *  Process space (3rd argument to JSON.stringify)\n\t */\n\n\th = duk_get_hobject(thr, idx_space);\n\tif (h != NULL) {\n\t\tduk_small_uint_t c = DUK_HOBJECT_GET_CLASS_NUMBER(h);\n\t\tif (c == DUK_HOBJECT_CLASS_NUMBER) {\n\t\t\tduk_to_number(thr, idx_space);\n\t\t} else if (c == DUK_HOBJECT_CLASS_STRING) {\n\t\t\tduk_to_string(thr, idx_space);\n\t\t}\n\t}\n\n\tif (duk_is_number(thr, idx_space)) {\n\t\tduk_small_int_t nspace;\n\t\t/* spaces[] must be static to allow initializer with old compilers like BCC */\n\t\tstatic const char spaces[10] = {\n\t\t\tDUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE,\n\t\t\tDUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE, DUK_ASC_SPACE,\n\t\t\tDUK_ASC_SPACE, DUK_ASC_SPACE\n\t\t};  /* XXX: helper */\n\n\t\t/* ToInteger() coercion; NaN -> 0, infinities are clamped to 0 and 10 */\n\t\tnspace = (duk_small_int_t) duk_to_int_clamped(thr, idx_space, 0 /*minval*/, 10 /*maxval*/);\n\t\tDUK_ASSERT(nspace >= 0 && nspace <= 10);\n\n\t\tduk_push_lstring(thr, spaces, (duk_size_t) nspace);\n\t\tjs_ctx->h_gap = duk_known_hstring(thr, -1);\n\t\tDUK_ASSERT(js_ctx->h_gap != NULL);\n\t} else if (duk_is_string_notsymbol(thr, idx_space)) {\n\t\tduk_dup(thr, idx_space);\n\t\tduk_substring(thr, -1, 0, 10);  /* clamp to 10 chars */\n\t\tjs_ctx->h_gap = duk_known_hstring(thr, -1);\n\t} else {\n\t\t/* nop */\n\t}\n\n\tif (js_ctx->h_gap != NULL) {\n\t\t/* If gap is empty, behave as if not given at all.  Check\n\t\t * against byte length because character length is more\n\t\t * expensive.\n\t\t */\n\t\tif (DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) == 0) {\n\t\t\tjs_ctx->h_gap = NULL;\n\t\t}\n\t}\n\n\t/* [ ... buf loop (proplist) (gap) ] */\n\n\t/*\n\t *  Fast path: assume no mutation, iterate object property tables\n\t *  directly; bail out if that assumption doesn't hold.\n\t */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\n\tif (js_ctx->h_replacer == NULL &&  /* replacer is a mutation risk */\n\t    js_ctx->idx_proplist == -1) {  /* proplist is very rare */\n\t\tduk_int_t pcall_rc;\n\t\tduk_small_uint_t prev_ms_base_flags;\n\n\t\tDUK_DD(DUK_DDPRINT(\"try JSON.stringify() fast path\"));\n\n\t\t/* Use recursion_limit to ensure we don't overwrite js_ctx->visiting[]\n\t\t * array so we don't need two counter checks in the fast path.  The\n\t\t * slow path has a much larger recursion limit which we'll use if\n\t\t * necessary.\n\t\t */\n\t\tDUK_ASSERT(DUK_USE_JSON_ENC_RECLIMIT >= DUK_JSON_ENC_LOOPARRAY);\n\t\tjs_ctx->recursion_limit = DUK_JSON_ENC_LOOPARRAY;\n\t\tDUK_ASSERT(js_ctx->recursion_depth == 0);\n\n\t\t/* Execute the fast path in a protected call.  If any error is thrown,\n\t\t * fall back to the slow path.  This includes e.g. recursion limit\n\t\t * because the fast path has a smaller recursion limit (and simpler,\n\t\t * limited loop detection).\n\t\t */\n\n\t\tduk_dup(thr, idx_value);\n\n\t\t/* Must prevent finalizers which may have arbitrary side effects. */\n\t\tprev_ms_base_flags = thr->heap->ms_base_flags;\n\t\tthr->heap->ms_base_flags |=\n\t\t        DUK_MS_FLAG_NO_OBJECT_COMPACTION;      /* Avoid attempt to compact any objects. */\n\t\tthr->heap->pf_prevent_count++;                 /* Prevent finalizers. */\n\t\tDUK_ASSERT(thr->heap->pf_prevent_count != 0);  /* Wrap. */\n\n\t\tpcall_rc = duk_safe_call(thr, duk__json_stringify_fast, (void *) js_ctx /*udata*/, 1 /*nargs*/, 0 /*nret*/);\n\n\t\tDUK_ASSERT(thr->heap->pf_prevent_count > 0);\n\t\tthr->heap->pf_prevent_count--;\n\t\tthr->heap->ms_base_flags = prev_ms_base_flags;\n\n\t\tif (pcall_rc == DUK_EXEC_SUCCESS) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"fast path successful\"));\n\t\t\tDUK_BW_PUSH_AS_STRING(thr, &js_ctx->bw);\n\t\t\tgoto replace_finished;\n\t\t}\n\n\t\t/* We come here for actual aborts (like encountering .toJSON())\n\t\t * but also for recursion/loop errors.  Bufwriter size can be\n\t\t * kept because we'll probably need at least as much as we've\n\t\t * allocated so far.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"fast path failed, serialize using slow path instead\"));\n\t\tDUK_BW_RESET_SIZE(thr, &js_ctx->bw);\n\t\tjs_ctx->recursion_depth = 0;\n\t}\n#endif\n\n\t/*\n\t *  Create wrapper object and serialize\n\t */\n\n\tidx_holder = duk_push_object(thr);\n\tduk_dup(thr, idx_value);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_EMPTY_STRING);\n\n\tDUK_DDD(DUK_DDDPRINT(\"before: flags=0x%08lx, loop=%!T, replacer=%!O, \"\n\t                     \"proplist=%!T, gap=%!O, holder=%!T\",\n\t                     (unsigned long) js_ctx->flags,\n\t                     (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop),\n\t                     (duk_heaphdr *) js_ctx->h_replacer,\n\t                     (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(thr, js_ctx->idx_proplist) : NULL),\n\t                     (duk_heaphdr *) js_ctx->h_gap,\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* serialize the wrapper with empty string key */\n\n\tduk_push_hstring_empty(thr);\n\n\t/* [ ... buf loop (proplist) (gap) holder \"\" ] */\n\n\tjs_ctx->recursion_limit = DUK_USE_JSON_ENC_RECLIMIT;\n\tDUK_ASSERT(js_ctx->recursion_depth == 0);\n\n\tif (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_holder) == 0)) {  /* [ ... holder key ] -> [ ... holder ] */\n\t\t/* Result is undefined. */\n\t\tduk_push_undefined(thr);\n\t} else {\n\t\t/* Convert buffer to result string. */\n\t\tDUK_BW_PUSH_AS_STRING(thr, &js_ctx->bw);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"after: flags=0x%08lx, loop=%!T, replacer=%!O, \"\n\t                     \"proplist=%!T, gap=%!O, holder=%!T\",\n\t                     (unsigned long) js_ctx->flags,\n\t                     (duk_tval *) duk_get_tval(thr, js_ctx->idx_loop),\n\t                     (duk_heaphdr *) js_ctx->h_replacer,\n\t                     (duk_tval *) (js_ctx->idx_proplist >= 0 ? duk_get_tval(thr, js_ctx->idx_proplist) : NULL),\n\t                     (duk_heaphdr *) js_ctx->h_gap,\n\t                     (duk_tval *) duk_get_tval(thr, idx_holder)));\n\n\t/* The stack has a variable shape here, so force it to the\n\t * desired one explicitly.\n\t */\n\n#if defined(DUK_USE_JSON_STRINGIFY_FASTPATH)\n replace_finished:\n#endif\n\tduk_replace(thr, entry_top);\n\tduk_set_top(thr, entry_top + 1);\n\n\tDUK_DDD(DUK_DDDPRINT(\"JSON stringify end: value=%!T, replacer=%!T, space=%!T, \"\n\t                     \"flags=0x%08lx, result=%!T, stack_top=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, idx_value),\n\t                     (duk_tval *) duk_get_tval(thr, idx_replacer),\n\t                     (duk_tval *) duk_get_tval(thr, idx_space),\n\t                     (unsigned long) flags,\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (long) duk_get_top(thr)));\n\n\tDUK_ASSERT(duk_get_top(thr) == entry_top + 1);\n}\n\n#if defined(DUK_USE_JSON_BUILTIN)\n\n/*\n *  Entry points\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_json_object_parse(duk_hthread *thr) {\n\tduk_bi_json_parse_helper(thr,\n\t                         0 /*idx_value*/,\n\t                         1 /*idx_replacer*/,\n\t                         0 /*flags*/);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_json_object_stringify(duk_hthread *thr) {\n\tduk_bi_json_stringify_helper(thr,\n\t                             0 /*idx_value*/,\n\t                             1 /*idx_replacer*/,\n\t                             2 /*idx_space*/,\n\t                             0 /*flags*/);\n\treturn 1;\n}\n\n#endif  /* DUK_USE_JSON_BUILTIN */\n\n#endif  /* DUK_USE_JSON_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_math.c",
    "content": "/*\n *  Math built-ins\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_MATH_BUILTIN)\n\n/*\n *  Use static helpers which can work with math.h functions matching\n *  the following signatures. This is not portable if any of these math\n *  functions is actually a macro.\n *\n *  Typing here is intentionally 'double' wherever values interact with\n *  the standard library APIs.\n */\n\ntypedef double (*duk__one_arg_func)(double);\ntypedef double (*duk__two_arg_func)(double, double);\n\nDUK_LOCAL duk_ret_t duk__math_minmax(duk_hthread *thr, duk_double_t initial, duk__two_arg_func min_max) {\n\tduk_idx_t n = duk_get_top(thr);\n\tduk_idx_t i;\n\tduk_double_t res = initial;\n\tduk_double_t t;\n\n\t/*\n\t *  Note: fmax() does not match the E5 semantics.  E5 requires\n\t *  that if -any- input to Math.max() is a NaN, the result is a\n\t *  NaN.  fmax() will return a NaN only if -both- inputs are NaN.\n\t *  Same applies to fmin().\n\t *\n\t *  Note: every input value must be coerced with ToNumber(), even\n\t *  if we know the result will be a NaN anyway: ToNumber() may have\n\t *  side effects for which even order of evaluation matters.\n\t */\n\n\tfor (i = 0; i < n; i++) {\n\t\tt = duk_to_number(thr, i);\n\t\tif (DUK_FPCLASSIFY(t) == DUK_FP_NAN || DUK_FPCLASSIFY(res) == DUK_FP_NAN) {\n\t\t\t/* Note: not normalized, but duk_push_number() will normalize */\n\t\t\tres = (duk_double_t) DUK_DOUBLE_NAN;\n\t\t} else {\n\t\t\tres = (duk_double_t) min_max(res, (double) t);\n\t\t}\n\t}\n\n\tduk_push_number(thr, res);\n\treturn 1;\n}\n\nDUK_LOCAL double duk__fmin_fixed(double x, double y) {\n\t/* fmin() with args -0 and +0 is not guaranteed to return\n\t * -0 as ECMAScript requires.\n\t */\n\tif (x == 0 && y == 0) {\n\t\tduk_double_union du1, du2;\n\t\tdu1.d = x;\n\t\tdu2.d = y;\n\n\t\t/* Already checked to be zero so these must hold, and allow us\n\t\t * to check for \"x is -0 or y is -0\" by ORing the high parts\n\t\t * for comparison.\n\t\t */\n\t\tDUK_ASSERT(du1.ui[DUK_DBL_IDX_UI0] == 0 || du1.ui[DUK_DBL_IDX_UI0] == 0x80000000UL);\n\t\tDUK_ASSERT(du2.ui[DUK_DBL_IDX_UI0] == 0 || du2.ui[DUK_DBL_IDX_UI0] == 0x80000000UL);\n\n\t\t/* XXX: what's the safest way of creating a negative zero? */\n\t\tif ((du1.ui[DUK_DBL_IDX_UI0] | du2.ui[DUK_DBL_IDX_UI0]) != 0) {\n\t\t\t/* Enter here if either x or y (or both) is -0. */\n\t\t\treturn -0.0;\n\t\t} else {\n\t\t\treturn +0.0;\n\t\t}\n\t}\n\treturn duk_double_fmin(x, y);\n}\n\nDUK_LOCAL double duk__fmax_fixed(double x, double y) {\n\t/* fmax() with args -0 and +0 is not guaranteed to return\n\t * +0 as ECMAScript requires.\n\t */\n\tif (x == 0 && y == 0) {\n\t\tif (DUK_SIGNBIT(x) == 0 || DUK_SIGNBIT(y) == 0) {\n\t\t\treturn +0.0;\n\t\t} else {\n\t\t\treturn -0.0;\n\t\t}\n\t}\n\treturn duk_double_fmax(x, y);\n}\n\n#if defined(DUK_USE_ES6)\nDUK_LOCAL double duk__cbrt(double x) {\n\t/* cbrt() is C99.  To avoid hassling embedders with the need to provide a\n\t * cube root function, we can get by with pow().  The result is not\n\t * identical, but that's OK: ES2015 says it's implementation-dependent.\n\t */\n\n#if defined(DUK_CBRT)\n\t/* cbrt() matches ES2015 requirements. */\n\treturn DUK_CBRT(x);\n#else\n\tduk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\n\t/* pow() does not, however. */\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE || c == DUK_FP_ZERO) {\n\t\treturn x;\n\t}\n\tif (DUK_SIGNBIT(x)) {\n\t\treturn -DUK_POW(-x, 1.0 / 3.0);\n\t} else {\n\t\treturn DUK_POW(x, 1.0 / 3.0);\n\t}\n#endif\n}\n\nDUK_LOCAL double duk__log2(double x) {\n#if defined(DUK_LOG2)\n\treturn DUK_LOG2(x);\n#else\n\treturn DUK_LOG(x) * DUK_DOUBLE_LOG2E;\n#endif\n}\n\nDUK_LOCAL double duk__log10(double x) {\n#if defined(DUK_LOG10)\n\treturn DUK_LOG10(x);\n#else\n\treturn DUK_LOG(x) * DUK_DOUBLE_LOG10E;\n#endif\n}\n\nDUK_LOCAL double duk__trunc(double x) {\n#if defined(DUK_TRUNC)\n\treturn DUK_TRUNC(x);\n#else\n\t/* Handles -0 correctly: -0.0 matches 'x >= 0.0' but floor()\n\t * is required to return -0 when the argument is -0.\n\t */\n\treturn x >= 0.0 ? DUK_FLOOR(x) : DUK_CEIL(x);\n#endif\n}\n#endif  /* DUK_USE_ES6 */\n\nDUK_LOCAL double duk__round_fixed(double x) {\n\t/* Numbers half-way between integers must be rounded towards +Infinity,\n\t * e.g. -3.5 must be rounded to -3 (not -4).  When rounded to zero, zero\n\t * sign must be set appropriately.  E5.1 Section 15.8.2.15.\n\t *\n\t * Note that ANSI C round() is \"round to nearest integer, away from zero\",\n\t * which is incorrect for negative values.  Here we make do with floor().\n\t */\n\n\tduk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE || c == DUK_FP_ZERO) {\n\t\treturn x;\n\t}\n\n\t/*\n\t *  x is finite and non-zero\n\t *\n\t *  -1.6 -> floor(-1.1) -> -2\n\t *  -1.5 -> floor(-1.0) -> -1  (towards +Inf)\n\t *  -1.4 -> floor(-0.9) -> -1\n\t *  -0.5 -> -0.0               (special case)\n\t *  -0.1 -> -0.0               (special case)\n\t *  +0.1 -> +0.0               (special case)\n\t *  +0.5 -> floor(+1.0) -> 1   (towards +Inf)\n\t *  +1.4 -> floor(+1.9) -> 1\n\t *  +1.5 -> floor(+2.0) -> 2   (towards +Inf)\n\t *  +1.6 -> floor(+2.1) -> 2\n\t */\n\n\tif (x >= -0.5 && x < 0.5) {\n\t\t/* +0.5 is handled by floor, this is on purpose */\n\t\tif (x < 0.0) {\n\t\t\treturn -0.0;\n\t\t} else {\n\t\t\treturn +0.0;\n\t\t}\n\t}\n\n\treturn DUK_FLOOR(x + 0.5);\n}\n\n/* Wrappers for calling standard math library methods.  These may be required\n * on platforms where one or more of the math built-ins are defined as macros\n * or inline functions and are thus not suitable to be used as function pointers.\n */\n#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)\nDUK_LOCAL double duk__fabs(double x) {\n\treturn DUK_FABS(x);\n}\nDUK_LOCAL double duk__acos(double x) {\n\treturn DUK_ACOS(x);\n}\nDUK_LOCAL double duk__asin(double x) {\n\treturn DUK_ASIN(x);\n}\nDUK_LOCAL double duk__atan(double x) {\n\treturn DUK_ATAN(x);\n}\nDUK_LOCAL double duk__ceil(double x) {\n\treturn DUK_CEIL(x);\n}\nDUK_LOCAL double duk__cos(double x) {\n\treturn DUK_COS(x);\n}\nDUK_LOCAL double duk__exp(double x) {\n\treturn DUK_EXP(x);\n}\nDUK_LOCAL double duk__floor(double x) {\n\treturn DUK_FLOOR(x);\n}\nDUK_LOCAL double duk__log(double x) {\n\treturn DUK_LOG(x);\n}\nDUK_LOCAL double duk__sin(double x) {\n\treturn DUK_SIN(x);\n}\nDUK_LOCAL double duk__sqrt(double x) {\n\treturn DUK_SQRT(x);\n}\nDUK_LOCAL double duk__tan(double x) {\n\treturn DUK_TAN(x);\n}\nDUK_LOCAL double duk__atan2_fixed(double x, double y) {\n#if defined(DUK_USE_ATAN2_WORKAROUNDS)\n\t/* Specific fixes to common atan2() implementation issues:\n\t * - test-bug-mingw-math-issues.js\n\t */\n\tif (DUK_ISINF(x) && DUK_ISINF(y)) {\n\t\tif (DUK_SIGNBIT(x)) {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn -2.356194490192345;\n\t\t\t} else {\n\t\t\t\treturn -0.7853981633974483;\n\t\t\t}\n\t\t} else {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn 2.356194490192345;\n\t\t\t} else {\n\t\t\t\treturn 0.7853981633974483;\n\t\t\t}\n\t\t}\n\t}\n#else\n\t/* Some ISO C assumptions. */\n\tDUK_ASSERT(DUK_ATAN2(DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY) == 0.7853981633974483);\n\tDUK_ASSERT(DUK_ATAN2(-DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY) == -0.7853981633974483);\n\tDUK_ASSERT(DUK_ATAN2(DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY) == 2.356194490192345);\n\tDUK_ASSERT(DUK_ATAN2(-DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY) == -2.356194490192345);\n#endif\n\n\treturn DUK_ATAN2(x, y);\n}\n#endif  /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */\n\n/* order must match constants in genbuiltins.py */\nDUK_LOCAL const duk__one_arg_func duk__one_arg_funcs[] = {\n#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)\n\tduk__fabs,\n\tduk__acos,\n\tduk__asin,\n\tduk__atan,\n\tduk__ceil,\n\tduk__cos,\n\tduk__exp,\n\tduk__floor,\n\tduk__log,\n\tduk__round_fixed,\n\tduk__sin,\n\tduk__sqrt,\n\tduk__tan,\n#if defined(DUK_USE_ES6)\n\tduk__cbrt,\n\tduk__log2,\n\tduk__log10,\n\tduk__trunc\n#endif\n#else  /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */\n\tDUK_FABS,\n\tDUK_ACOS,\n\tDUK_ASIN,\n\tDUK_ATAN,\n\tDUK_CEIL,\n\tDUK_COS,\n\tDUK_EXP,\n\tDUK_FLOOR,\n\tDUK_LOG,\n\tduk__round_fixed,\n\tDUK_SIN,\n\tDUK_SQRT,\n\tDUK_TAN,\n#if defined(DUK_USE_ES6)\n\tduk__cbrt,\n\tduk__log2,\n\tduk__log10,\n\tduk__trunc\n#endif\n#endif  /* DUK_USE_AVOID_PLATFORM_FUNCPTRS */\n};\n\n/* order must match constants in genbuiltins.py */\nDUK_LOCAL const duk__two_arg_func duk__two_arg_funcs[] = {\n#if defined(DUK_USE_AVOID_PLATFORM_FUNCPTRS)\n\tduk__atan2_fixed,\n\tduk_js_arith_pow\n#else\n\tduk__atan2_fixed,\n\tduk_js_arith_pow\n#endif\n};\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_onearg_shared(duk_hthread *thr) {\n\tduk_small_int_t fun_idx = duk_get_current_magic(thr);\n\tduk__one_arg_func fun;\n\tduk_double_t arg1;\n\n\tDUK_ASSERT(fun_idx >= 0);\n\tDUK_ASSERT(fun_idx < (duk_small_int_t) (sizeof(duk__one_arg_funcs) / sizeof(duk__one_arg_func)));\n\targ1 = duk_to_number(thr, 0);\n\tfun = duk__one_arg_funcs[fun_idx];\n\tduk_push_number(thr, (duk_double_t) fun((double) arg1));\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_twoarg_shared(duk_hthread *thr) {\n\tduk_small_int_t fun_idx = duk_get_current_magic(thr);\n\tduk__two_arg_func fun;\n\tduk_double_t arg1;\n\tduk_double_t arg2;\n\n\tDUK_ASSERT(fun_idx >= 0);\n\tDUK_ASSERT(fun_idx < (duk_small_int_t) (sizeof(duk__two_arg_funcs) / sizeof(duk__two_arg_func)));\n\targ1 = duk_to_number(thr, 0);  /* explicit ordered evaluation to match coercion semantics */\n\targ2 = duk_to_number(thr, 1);\n\tfun = duk__two_arg_funcs[fun_idx];\n\tduk_push_number(thr, (duk_double_t) fun((double) arg1, (double) arg2));\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_max(duk_hthread *thr) {\n\treturn duk__math_minmax(thr, -DUK_DOUBLE_INFINITY, duk__fmax_fixed);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_min(duk_hthread *thr) {\n\treturn duk__math_minmax(thr, DUK_DOUBLE_INFINITY, duk__fmin_fixed);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_math_object_random(duk_hthread *thr) {\n\tduk_push_number(thr, (duk_double_t) DUK_UTIL_GET_RANDOM_DOUBLE(thr));\n\treturn 1;\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_hypot(duk_hthread *thr) {\n\t/*\n\t *  E6 Section 20.2.2.18: Math.hypot\n\t *\n\t *  - If no arguments are passed, the result is +0.\n\t *  - If any argument is +inf, the result is +inf.\n\t *  - If any argument is -inf, the result is +inf.\n\t *  - If no argument is +inf or -inf, and any argument is NaN, the result is\n\t *    NaN.\n\t *  - If all arguments are either +0 or -0, the result is +0.\n\t */\n\n\tduk_idx_t nargs;\n\tduk_idx_t i;\n\tduk_bool_t found_nan;\n\tduk_double_t max;\n\tduk_double_t sum, summand;\n\tduk_double_t comp, prelim;\n\tduk_double_t t;\n\n\tnargs = duk_get_top(thr);\n\n\t/* Find the highest value.  Also ToNumber() coerces. */\n\tmax = 0.0;\n\tfound_nan = 0;\n\tfor (i = 0; i < nargs; i++) {\n\t\tt = DUK_FABS(duk_to_number(thr, i));\n\t\tif (DUK_FPCLASSIFY(t) == DUK_FP_NAN) {\n\t\t\tfound_nan = 1;\n\t\t} else {\n\t\t\tmax = duk_double_fmax(max, t);\n\t\t}\n\t}\n\n\t/* Early return cases. */\n\tif (max == DUK_DOUBLE_INFINITY) {\n\t\tduk_push_number(thr, DUK_DOUBLE_INFINITY);\n\t\treturn 1;\n\t} else if (found_nan) {\n\t\tduk_push_number(thr, DUK_DOUBLE_NAN);\n\t\treturn 1;\n\t} else if (max == 0.0) {\n\t\tduk_push_number(thr, 0.0);\n\t\t/* Otherwise we'd divide by zero. */\n\t\treturn 1;\n\t}\n\n\t/* Use Kahan summation and normalize to the highest value to minimize\n\t * floating point rounding error and avoid overflow.\n\t *\n\t * https://en.wikipedia.org/wiki/Kahan_summation_algorithm\n\t */\n\tsum = 0.0;\n\tcomp = 0.0;\n\tfor (i = 0; i < nargs; i++) {\n\t\tt = DUK_FABS(duk_get_number(thr, i)) / max;\n\t\tsummand = (t * t) - comp;\n\t\tprelim = sum + summand;\n\t\tcomp = (prelim - sum) - summand;\n\t\tsum = prelim;\n\t}\n\n\tduk_push_number(thr, (duk_double_t) DUK_SQRT(sum) * max);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_sign(duk_hthread *thr) {\n\tduk_double_t d;\n\n\td = duk_to_number(thr, 0);\n\tif (duk_double_is_nan(d)) {\n\t\tDUK_ASSERT(duk_is_nan(thr, -1));\n\t\treturn 1;  /* NaN input -> return NaN */\n\t}\n\tif (d == 0.0) {\n\t\t/* Zero sign kept, i.e. -0 -> -0, +0 -> +0. */\n\t\treturn 1;\n\t}\n\tduk_push_int(thr, (d > 0.0 ? 1 : -1));\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_clz32(duk_hthread *thr) {\n\tduk_uint32_t x;\n\tduk_small_uint_t i;\n\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_uint32_t mask;\n\n\tx = duk_to_uint32(thr, 0);\n\tfor (i = 0, mask = 0x80000000UL; mask != 0; mask >>= 1) {\n\t\tif (x & mask) {\n\t\t\tbreak;\n\t\t}\n\t\ti++;\n\t}\n\tDUK_ASSERT(i <= 32);\n\tduk_push_uint(thr, i);\n\treturn 1;\n#else  /* DUK_USE_PREFER_SIZE */\n\ti = 0;\n\tx = duk_to_uint32(thr, 0);\n\tif (x & 0xffff0000UL) {\n\t\tx >>= 16;\n\t} else {\n\t\ti += 16;\n\t}\n\tif (x & 0x0000ff00UL) {\n\t\tx >>= 8;\n\t} else {\n\t\ti += 8;\n\t}\n\tif (x & 0x000000f0UL) {\n\t\tx >>= 4;\n\t} else {\n\t\ti += 4;\n\t}\n\tif (x & 0x0000000cUL) {\n\t\tx >>= 2;\n\t} else {\n\t\ti += 2;\n\t}\n\tif (x & 0x00000002UL) {\n\t\tx >>= 1;\n\t} else {\n\t\ti += 1;\n\t}\n\tif (x & 0x00000001UL) {\n\t\t;\n\t} else {\n\t\ti += 1;\n\t}\n\tDUK_ASSERT(i <= 32);\n\tduk_push_uint(thr, i);\n\treturn 1;\n#endif  /* DUK_USE_PREFER_SIZE */\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_math_object_imul(duk_hthread *thr) {\n\tduk_uint32_t x, y, z;\n\n\tx = duk_to_uint32(thr, 0);\n\ty = duk_to_uint32(thr, 1);\n\tz = x * y;\n\n\t/* While arguments are ToUint32() coerced and the multiplication\n\t * is unsigned as such, the final result is curiously interpreted\n\t * as a signed 32-bit value.\n\t */\n\tduk_push_i32(thr, (duk_int32_t) z);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#endif  /* DUK_USE_MATH_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_number.c",
    "content": "/*\n *  Number built-ins\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_NUMBER_BUILTIN)\n\nDUK_LOCAL duk_double_t duk__push_this_number_plain(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\t/* Number built-in accepts a plain number or a Number object (whose\n\t * internal value is operated on).  Other types cause TypeError.\n\t */\n\n\tduk_push_this(thr);\n\tif (duk_is_number(thr, -1)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"plain number value: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\t\tgoto done;\n\t}\n\th = duk_get_hobject(thr, -1);\n\tif (!h ||\n\t    (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_NUMBER)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"unacceptable this value: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\t\tDUK_ERROR_TYPE(thr, \"number expected\");\n\t\tDUK_WO_NORETURN(return 0.0;);\n\t}\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\tDUK_DDD(DUK_DDDPRINT(\"number object: %!T, internal value: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\tduk_remove_m2(thr);\n\n done:\n\treturn duk_get_number(thr, -1);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_constructor(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_hobject *h_this;\n\n\t/*\n\t *  The Number constructor uses ToNumber(arg) for number coercion\n\t *  (coercing an undefined argument to NaN).  However, if the\n\t *  argument is not given at all, +0 must be used instead.  To do\n\t *  this, a vararg function is used.\n\t */\n\n\tnargs = duk_get_top(thr);\n\tif (nargs == 0) {\n\t\tduk_push_int(thr, 0);\n\t}\n\tduk_to_number(thr, 0);\n\tduk_set_top(thr, 1);\n\tDUK_ASSERT_TOP(thr, 1);\n\n\tif (!duk_is_constructor_call(thr)) {\n\t\treturn 1;\n\t}\n\n\t/*\n\t *  E5 Section 15.7.2.1 requires that the constructed object\n\t *  must have the original Number.prototype as its internal\n\t *  prototype.  However, since Number.prototype is non-writable\n\t *  and non-configurable, this doesn't have to be enforced here:\n\t *  The default object (bound to 'this') is OK, though we have\n\t *  to change its class.\n\t *\n\t *  Internal value set to ToNumber(arg) or +0; if no arg given,\n\t *  ToNumber(undefined) = NaN, so special treatment is needed\n\t *  (above).  String internal value is immutable.\n\t */\n\n\t/* XXX: helper */\n\tduk_push_this(thr);\n\th_this = duk_known_hobject(thr, -1);\n\tDUK_HOBJECT_SET_CLASS_NUMBER(h_this, DUK_HOBJECT_CLASS_NUMBER);\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_this) == thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE]);\n\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_this) == DUK_HOBJECT_CLASS_NUMBER);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_this));\n\n\tduk_dup_0(thr);  /* -> [ val obj val ] */\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\treturn 0;  /* no return value -> don't replace created value */\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_value_of(duk_hthread *thr) {\n\t(void) duk__push_this_number_plain(thr);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_string(duk_hthread *thr) {\n\tduk_small_int_t radix;\n\tduk_small_uint_t n2s_flags;\n\n\t(void) duk__push_this_number_plain(thr);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tradix = 10;\n\t} else {\n\t\tradix = (duk_small_int_t) duk_to_int_check_range(thr, 0, 2, 36);\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"radix=%ld\", (long) radix));\n\n\tn2s_flags = 0;\n\n\tduk_numconv_stringify(thr,\n\t                      radix /*radix*/,\n\t                      0 /*digits*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_locale_string(duk_hthread *thr) {\n\t/* XXX: just use toString() for now; permitted although not recommended.\n\t * nargs==1, so radix is passed to toString().\n\t */\n\treturn duk_bi_number_prototype_to_string(thr);\n}\n\n/*\n *  toFixed(), toExponential(), toPrecision()\n */\n\n/* XXX: shared helper for toFixed(), toExponential(), toPrecision()? */\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_fixed(duk_hthread *thr) {\n\tduk_small_int_t frac_digits;\n\tduk_double_t d;\n\tduk_small_int_t c;\n\tduk_small_uint_t n2s_flags;\n\n\t/* In ES5.1 frac_digits is coerced first; in ES2015 the 'this number\n\t * value' check is done first.\n\t */\n\td = duk__push_this_number_plain(thr);\n\tfrac_digits = (duk_small_int_t) duk_to_int_check_range(thr, 0, 0, 20);\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\tgoto use_to_string;\n\t}\n\n\tif (d >= 1.0e21 || d <= -1.0e21) {\n\t\tgoto use_to_string;\n\t}\n\n\tn2s_flags = DUK_N2S_FLAG_FIXED_FORMAT |\n\t            DUK_N2S_FLAG_FRACTION_DIGITS;\n\n\tduk_numconv_stringify(thr,\n\t                      10 /*radix*/,\n\t                      frac_digits /*digits*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n\n use_to_string:\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, -1);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_exponential(duk_hthread *thr) {\n\tduk_bool_t frac_undefined;\n\tduk_small_int_t frac_digits;\n\tduk_double_t d;\n\tduk_small_int_t c;\n\tduk_small_uint_t n2s_flags;\n\n\td = duk__push_this_number_plain(thr);\n\n\tfrac_undefined = duk_is_undefined(thr, 0);\n\tduk_to_int(thr, 0);  /* for side effects */\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\tgoto use_to_string;\n\t}\n\n\tfrac_digits = (duk_small_int_t) duk_to_int_check_range(thr, 0, 0, 20);\n\n\tn2s_flags = DUK_N2S_FLAG_FORCE_EXP |\n\t           (frac_undefined ? 0 : DUK_N2S_FLAG_FIXED_FORMAT);\n\n\tduk_numconv_stringify(thr,\n\t                      10 /*radix*/,\n\t                      frac_digits + 1 /*leading digit + fractions*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n\n use_to_string:\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, -1);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_number_prototype_to_precision(duk_hthread *thr) {\n\t/* The specification has quite awkward order of coercion and\n\t * checks for toPrecision().  The operations below are a bit\n\t * reordered, within constraints of observable side effects.\n\t */\n\n\tduk_double_t d;\n\tduk_small_int_t prec;\n\tduk_small_int_t c;\n\tduk_small_uint_t n2s_flags;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\n\td = duk__push_this_number_plain(thr);\n\tif (duk_is_undefined(thr, 0)) {\n\t\tgoto use_to_string;\n\t}\n\tDUK_ASSERT_TOP(thr, 2);\n\n\tduk_to_int(thr, 0);  /* for side effects */\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(d);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\tgoto use_to_string;\n\t}\n\n\tprec = (duk_small_int_t) duk_to_int_check_range(thr, 0, 1, 21);\n\n\tn2s_flags = DUK_N2S_FLAG_FIXED_FORMAT |\n\t            DUK_N2S_FLAG_NO_ZERO_PAD;\n\n\tduk_numconv_stringify(thr,\n\t                      10 /*radix*/,\n\t                      prec /*digits*/,\n\t                      n2s_flags /*flags*/);\n\treturn 1;\n\n use_to_string:\n\t/* Used when precision is undefined; also used for NaN (-> \"NaN\"),\n\t * and +/- infinity (-> \"Infinity\", \"-Infinity\").\n\t */\n\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_to_string(thr, -1);\n\treturn 1;\n}\n\n/*\n *  ES2015 isFinite() etc\n */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_number_check_shared(duk_hthread *thr) {\n\tduk_int_t magic;\n\tduk_bool_t ret = 0;\n\n\tif (duk_is_number(thr, 0)) {\n\t\tduk_double_t d;\n\n\t\tmagic = duk_get_current_magic(thr);\n\t\td = duk_get_number(thr, 0);\n\n\t\tswitch (magic) {\n\t\tcase 0:  /* isFinite() */\n\t\t\tret = duk_double_is_finite(d);\n\t\t\tbreak;\n\t\tcase 1:  /* isInteger() */\n\t\t\tret = duk_double_is_integer(d);\n\t\t\tbreak;\n\t\tcase 2:  /* isNaN() */\n\t\t\tret = duk_double_is_nan(d);\n\t\t\tbreak;\n\t\tdefault:  /* isSafeInteger() */\n\t\t\tDUK_ASSERT(magic == 3);\n\t\t\tret = duk_double_is_safe_integer(d);\n\t\t}\n\t}\n\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#endif  /* DUK_USE_NUMBER_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_object.c",
    "content": "/*\n *  Object built-ins\n */\n\n#include \"duk_internal.h\"\n\n/* Needed even when Object built-in disabled. */\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_string(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\ttv = DUK_HTHREAD_THIS_PTR(thr);\n\tduk_push_class_string_tval(thr, tv, 0 /*avoid_side_effects*/);\n\treturn 1;\n}\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor(duk_hthread *thr) {\n\tduk_uint_t arg_mask;\n\n\targ_mask = duk_get_type_mask(thr, 0);\n\n\tif (!duk_is_constructor_call(thr) &&  /* not a constructor call */\n\t    ((arg_mask & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED)) == 0)) {  /* and argument not null or undefined */\n\t\tduk_to_object(thr, 0);\n\t\treturn 1;\n\t}\n\n\t/* Pointer and buffer primitive values are treated like other\n\t * primitives values which have a fully fledged object counterpart:\n\t * promote to an object value.  Lightfuncs and plain buffers are\n\t * coerced with ToObject() even they could also be returned as is.\n\t */\n\tif (arg_mask & (DUK_TYPE_MASK_OBJECT |\n\t                DUK_TYPE_MASK_STRING |\n\t                DUK_TYPE_MASK_BOOLEAN |\n\t                DUK_TYPE_MASK_NUMBER |\n\t                DUK_TYPE_MASK_POINTER |\n\t                DUK_TYPE_MASK_BUFFER |\n\t                DUK_TYPE_MASK_LIGHTFUNC)) {\n\t\t/* For DUK_TYPE_OBJECT the coercion is a no-op and could\n\t\t * be checked for explicitly, but Object(obj) calls are\n\t\t * not very common so opt for minimal footprint.\n\t\t */\n\t\tduk_to_object(thr, 0);\n\t\treturn 1;\n\t}\n\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              DUK_BIDX_OBJECT_PROTOTYPE);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) && defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_assign(duk_hthread *thr) {\n\tduk_idx_t nargs;\n\tduk_int_t idx;\n\n\tnargs = duk_get_top_require_min(thr, 1 /*min_top*/);\n\n\tduk_to_object(thr, 0);\n\tfor (idx = 1; idx < nargs; idx++) {\n\t\t/* E7 19.1.2.1 (step 4a) */\n\t\tif (duk_is_null_or_undefined(thr, idx)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* duk_enum() respects ES2015+ [[OwnPropertyKeys]] ordering, which is\n\t\t * convenient here.\n\t\t */\n\t\tduk_to_object(thr, idx);\n\t\tduk_enum(thr, idx, DUK_ENUM_OWN_PROPERTIES_ONLY);\n\t\twhile (duk_next(thr, -1, 1 /*get_value*/)) {\n\t\t\t/* [ target ... enum key value ] */\n\t\t\tduk_put_prop(thr, 0);\n\t\t\t/* [ target ... enum ] */\n\t\t}\n\t\t/* Could pop enumerator, but unnecessary because of duk_set_top()\n\t\t * below.\n\t\t */\n\t}\n\n\tduk_set_top(thr, 1);\n\treturn 1;\n}\n#endif\n\n#if defined(DUK_USE_OBJECT_BUILTIN) && defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_is(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 2);\n\tduk_push_boolean(thr, duk_samevalue(thr, 0, 1));\n\treturn 1;\n}\n#endif\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_create(duk_hthread *thr) {\n\tduk_hobject *proto;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tduk_hbufobj_promote_plain(thr, 0);\n#endif\n\tproto = duk_require_hobject_accept_mask(thr, 0, DUK_TYPE_MASK_NULL);\n\tDUK_ASSERT(proto != NULL || duk_is_null(thr, 0));\n\n\t(void) duk_push_object_helper_proto(thr,\n\t                                    DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                    DUK_HOBJECT_FLAG_FASTREFS |\n\t                                    DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                                    proto);\n\n\tif (!duk_is_undefined(thr, 1)) {\n\t\t/* [ O Properties obj ] */\n\n\t\tduk_replace(thr, 0);\n\n\t\t/* [ obj Properties ] */\n\n\t\t/* Just call the \"original\" Object.defineProperties() to\n\t\t * finish up.\n\t\t */\n\n\t\treturn duk_bi_object_constructor_define_properties(thr);\n\t}\n\n\t/* [ O Properties obj ] */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_properties(duk_hthread *thr) {\n\tduk_small_uint_t pass;\n\tduk_uint_t defprop_flags;\n\tduk_hobject *obj;\n\tduk_idx_t idx_value;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\n\t/* Lightfunc and plain buffer handling by ToObject() coercion. */\n\tobj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(obj != NULL);\n\n\tduk_to_object(thr, 1);        /* properties object */\n\n\tDUK_DDD(DUK_DDDPRINT(\"target=%!iT, properties=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\n\t/*\n\t *  Two pass approach to processing the property descriptors.\n\t *  On first pass validate and normalize all descriptors before\n\t *  any changes are made to the target object.  On second pass\n\t *  make the actual modifications to the target object.\n\t *\n\t *  Right now we'll just use the same normalize/validate helper\n\t *  on both passes, ignoring its outputs on the first pass.\n\t */\n\n\tfor (pass = 0; pass < 2; pass++) {\n\t\tduk_set_top(thr, 2);  /* -> [ hobject props ] */\n\t\tduk_enum(thr, 1, DUK_ENUM_OWN_PROPERTIES_ONLY | DUK_ENUM_INCLUDE_SYMBOLS /*enum_flags*/);\n\n\t\tfor (;;) {\n\t\t\tduk_hstring *key;\n\n\t\t\t/* [ hobject props enum(props) ] */\n\n\t\t\tduk_set_top(thr, 3);\n\n\t\t\tif (!duk_next(thr, 2, 1 /*get_value*/)) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> key=%!iT, desc=%!iT\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t/* [ hobject props enum(props) key desc ] */\n\n\t\t\tduk_hobject_prepare_property_descriptor(thr,\n\t\t\t                                        4 /*idx_desc*/,\n\t\t\t                                        &defprop_flags,\n\t\t\t                                        &idx_value,\n\t\t\t                                        &get,\n\t\t\t                                        &set);\n\n\t\t\t/* [ hobject props enum(props) key desc [multiple values] ] */\n\n\t\t\tif (pass == 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* This allows symbols on purpose. */\n\t\t\tkey = duk_known_hstring(thr, 3);\n\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\tduk_hobject_define_property_helper(thr,\n\t\t\t                                   defprop_flags,\n\t\t\t                                   obj,\n\t\t\t                                   key,\n\t\t\t                                   idx_value,\n\t\t\t                                   get,\n\t\t\t                                   set,\n\t\t\t                                   1 /*throw_flag*/);\n\t\t}\n\t}\n\n\t/*\n\t *  Return target object\n\t */\n\n\tduk_dup_0(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_seal_freeze_shared(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 1);\n\n\tduk_seal_freeze_raw(thr, 0, (duk_bool_t) duk_get_current_magic(thr) /*is_freeze*/);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_sealed_frozen_shared(duk_hthread *thr) {\n\tduk_hobject *h;\n\tduk_bool_t is_frozen;\n\tduk_uint_t mask;\n\n\tis_frozen = (duk_bool_t) duk_get_current_magic(thr);\n\tmask = duk_get_type_mask(thr, 0);\n\tif (mask & (DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER)) {\n\t\tDUK_ASSERT(is_frozen == 0 || is_frozen == 1);\n\t\tduk_push_boolean(thr, (mask & DUK_TYPE_MASK_LIGHTFUNC) ?\n\t\t                          1 :               /* lightfunc always frozen and sealed */\n\t\t                          (is_frozen ^ 1)); /* buffer sealed but not frozen (index props writable) */\n\t} else {\n\t\t/* ES2015 Sections 19.1.2.12, 19.1.2.13: anything other than an object\n\t\t * is considered to be already sealed and frozen.\n\t\t */\n\t\th = duk_get_hobject(thr, 0);\n\t\tduk_push_boolean(thr, (h == NULL) ||\n\t\t                      duk_hobject_object_is_sealed_frozen_helper(thr, h, is_frozen /*is_frozen*/));\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_to_locale_string(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 0);\n\t(void) duk_push_this_coercible_to_object(thr);\n\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_TO_STRING);\n#if 0  /* This is mentioned explicitly in the E5.1 spec, but duk_call_method() checks for it in practice. */\n\tduk_require_callable(thr, 1);\n#endif\n\tduk_dup_0(thr);  /* -> [ O toString O ] */\n\tduk_call_method(thr, 0);  /* XXX: call method tail call? */\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_value_of(duk_hthread *thr) {\n\t/* For lightfuncs and plain buffers, returns Object() coerced. */\n\t(void) duk_push_this_coercible_to_object(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_hthread *thr) {\n\tduk_hobject *h_v;\n\tduk_hobject *h_obj;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\n\th_v = duk_get_hobject(thr, 0);\n\tif (!h_v) {\n\t\tduk_push_false(thr);  /* XXX: tail call: return duk_push_false(thr) */\n\t\treturn 1;\n\t}\n\n\th_obj = duk_push_this_coercible_to_object(thr);\n\tDUK_ASSERT(h_obj != NULL);\n\n\t/* E5.1 Section 15.2.4.6, step 3.a, lookup proto once before compare.\n\t * Prototype loops should cause an error to be thrown.\n\t */\n\tduk_push_boolean(thr, duk_hobject_prototype_chain_contains(thr, DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_v), h_obj, 0 /*ignore_loop*/));\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_has_own_property(duk_hthread *thr) {\n\treturn (duk_ret_t) duk_hobject_object_ownprop_helper(thr, 0 /*required_desc_flags*/);\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_property_is_enumerable(duk_hthread *thr) {\n\treturn (duk_ret_t) duk_hobject_object_ownprop_helper(thr, DUK_PROPDESC_FLAG_ENUMERABLE /*required_desc_flags*/);\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\n/* Shared helper to implement Object.getPrototypeOf,\n * Object.prototype.__proto__ getter, and Reflect.getPrototypeOf.\n *\n * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-get-object.prototype.__proto__\n */\nDUK_INTERNAL duk_ret_t duk_bi_object_getprototype_shared(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: __proto__ getter\n\t *  magic = 1: Object.getPrototypeOf()\n\t *  magic = 2: Reflect.getPrototypeOf()\n\t */\n\n\tduk_hobject *h;\n\tduk_hobject *proto;\n\tduk_tval *tv;\n\tduk_int_t magic;\n\n\tmagic = duk_get_current_magic(thr);\n\n\tif (magic == 0) {\n\t\tDUK_ASSERT_TOP(thr, 0);\n\t\tduk_push_this_coercible_to_object(thr);\n\t}\n\tDUK_ASSERT(duk_get_top(thr) >= 1);\n\tif (magic < 2) {\n\t\t/* ES2015 Section 19.1.2.9, step 1 */\n\t\tduk_to_object(thr, 0);\n\t}\n\ttv = DUK_GET_TVAL_POSIDX(thr, 0);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_BUFFER:\n\t\tproto = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\tproto = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tproto = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t\tbreak;\n\tdefault:\n\t\t/* This implicitly handles CheckObjectCoercible() caused\n\t\t * TypeError.\n\t\t */\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\tif (proto != NULL) {\n\t\tduk_push_hobject(thr, proto);\n\t} else {\n\t\tduk_push_null(thr);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\n/* Shared helper to implement ES2015 Object.setPrototypeOf,\n * Object.prototype.__proto__ setter, and Reflect.setPrototypeOf.\n *\n * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-get-object.prototype.__proto__\n * http://www.ecma-international.org/ecma-262/6.0/index.html#sec-object.setprototypeof\n */\nDUK_INTERNAL duk_ret_t duk_bi_object_setprototype_shared(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: __proto__ setter\n\t *  magic = 1: Object.setPrototypeOf()\n\t *  magic = 2: Reflect.setPrototypeOf()\n\t */\n\n\tduk_hobject *h_obj;\n\tduk_hobject *h_new_proto;\n\tduk_hobject *h_curr;\n\tduk_ret_t ret_success = 1;  /* retval for success path */\n\tduk_uint_t mask;\n\tduk_int_t magic;\n\n\t/* Preliminaries for __proto__ and setPrototypeOf (E6 19.1.2.18 steps 1-4). */\n\tmagic = duk_get_current_magic(thr);\n\tif (magic == 0) {\n\t\tduk_push_this_check_object_coercible(thr);\n\t\tduk_insert(thr, 0);\n\t\tif (!duk_check_type_mask(thr, 1, DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_OBJECT)) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t/* __proto__ setter returns 'undefined' on success unlike the\n\t\t * setPrototypeOf() call which returns the target object.\n\t\t */\n\t\tret_success = 0;\n\t} else {\n\t\tif (magic == 1) {\n\t\t\tduk_require_object_coercible(thr, 0);\n\t\t} else {\n\t\t\tduk_require_hobject_accept_mask(thr, 0,\n\t\t\t                                DUK_TYPE_MASK_LIGHTFUNC |\n\t\t\t                                DUK_TYPE_MASK_BUFFER);\n\t\t}\n\t\tduk_require_type_mask(thr, 1, DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_OBJECT);\n\t}\n\n\th_new_proto = duk_get_hobject(thr, 1);\n\t/* h_new_proto may be NULL */\n\n\tmask = duk_get_type_mask(thr, 0);\n\tif (mask & (DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER)) {\n\t\tduk_hobject *curr_proto;\n\t\tcurr_proto = thr->builtins[(mask & DUK_TYPE_MASK_LIGHTFUNC) ?\n\t\t                               DUK_BIDX_FUNCTION_PROTOTYPE :\n\t\t                               DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tif (h_new_proto == curr_proto) {\n\t\t\tgoto skip;\n\t\t}\n\t\tgoto fail_nonextensible;\n\t}\n\th_obj = duk_get_hobject(thr, 0);\n\tif (h_obj == NULL) {\n\t\tgoto skip;\n\t}\n\tDUK_ASSERT(h_obj != NULL);\n\n\t/* [[SetPrototypeOf]] standard behavior, E6 9.1.2. */\n\t/* TODO: implement Proxy object support here */\n\n\tif (h_new_proto == DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_obj)) {\n\t\tgoto skip;\n\t}\n\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(h_obj)) {\n\t\tgoto fail_nonextensible;\n\t}\n\tfor (h_curr = h_new_proto; h_curr != NULL; h_curr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_curr)) {\n\t\t/* Loop prevention. */\n\t\tif (h_curr == h_obj) {\n\t\t\tgoto fail_loop;\n\t\t}\n\t}\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h_obj, h_new_proto);\n\t/* fall thru */\n\n skip:\n\tduk_set_top(thr, 1);\n\tif (magic == 2) {\n\t\tduk_push_true(thr);\n\t}\n\treturn ret_success;\n\n fail_nonextensible:\n fail_loop:\n\tif (magic != 2) {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t} else {\n\t\tduk_push_false(thr);\n\t\treturn 1;\n\t}\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_define_property(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: Object.defineProperty()\n\t *  magic = 1: Reflect.defineProperty()\n\t */\n\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\tduk_idx_t idx_value;\n\tduk_uint_t defprop_flags;\n\tduk_small_uint_t magic;\n\tduk_bool_t throw_flag;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"Object.defineProperty(): ctx=%p obj=%!T key=%!T desc=%!T\",\n\t                     (void *) thr,\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1),\n\t                     (duk_tval *) duk_get_tval(thr, 2)));\n\n\t/* [ obj key desc ] */\n\n\tmagic = (duk_small_uint_t) duk_get_current_magic(thr);\n\n\t/* Lightfuncs are currently supported by coercing to a temporary\n\t * Function object; changes will be allowed (the coerced value is\n\t * extensible) but will be lost.  Same for plain buffers.\n\t */\n\tobj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tDUK_ASSERT(obj != NULL);\n\tkey = duk_to_property_key_hstring(thr, 1);\n\t(void) duk_require_hobject(thr, 2);\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(duk_get_hobject(thr, 2) != NULL);\n\n\t/*\n\t *  Validate and convert argument property descriptor (an ECMAScript\n\t *  object) into a set of defprop_flags and possibly property value,\n\t *  getter, and/or setter values on the value stack.\n\t *\n\t *  Lightfunc set/get values are coerced to full Functions.\n\t */\n\n\tduk_hobject_prepare_property_descriptor(thr,\n\t                                        2 /*idx_desc*/,\n\t                                        &defprop_flags,\n\t                                        &idx_value,\n\t                                        &get,\n\t                                        &set);\n\n\t/*\n\t *  Use Object.defineProperty() helper for the actual operation.\n\t */\n\n\tDUK_ASSERT(magic == 0U || magic == 1U);\n\tthrow_flag = magic ^ 1U;\n\tret = duk_hobject_define_property_helper(thr,\n\t                                         defprop_flags,\n\t                                         obj,\n\t                                         key,\n\t                                         idx_value,\n\t                                         get,\n\t                                         set,\n\t                                         throw_flag);\n\n\t/* Ignore the normalize/validate helper outputs on the value stack,\n\t * they're popped automatically.\n\t */\n\n\tif (magic == 0U) {\n\t\t/* Object.defineProperty(): return target object. */\n\t\tduk_push_hobject(thr, obj);\n\t} else {\n\t\t/* Reflect.defineProperty(): return success/fail. */\n\t\tduk_push_boolean(thr, ret);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_get_own_property_descriptor(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 2);\n\n\t/* ES2015 Section 19.1.2.6, step 1 */\n\tif (duk_get_current_magic(thr) == 0) {\n\t\tduk_to_object(thr, 0);\n\t}\n\n\t/* [ obj key ] */\n\n\tduk_hobject_object_get_own_property_descriptor(thr, -2);\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_is_extensible(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: Object.isExtensible()\n\t *  magic = 1: Reflect.isExtensible()\n\t */\n\n\tduk_hobject *h;\n\n\tif (duk_get_current_magic(thr) == 0) {\n\t\th = duk_get_hobject(thr, 0);\n\t} else {\n\t\t/* Reflect.isExtensible(): throw if non-object, but we accept lightfuncs\n\t\t * and plain buffers here because they pretend to be objects.\n\t\t */\n\t\th = duk_require_hobject_accept_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\t}\n\n\tduk_push_boolean(thr, (h != NULL) && DUK_HOBJECT_HAS_EXTENSIBLE(h));\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\n/* Shared helper for various key/symbol listings, magic:\n * 0=Object.keys()\n * 1=Object.getOwnPropertyNames(),\n * 2=Object.getOwnPropertySymbols(),\n * 3=Reflect.ownKeys()\n */\nDUK_LOCAL const duk_small_uint_t duk__object_keys_enum_flags[4] = {\n\t/* Object.keys() */\n\tDUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR,\n\n\t/* Object.getOwnPropertyNames() */\n\tDUK_ENUM_INCLUDE_NONENUMERABLE |\n\t    DUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR,\n\n\t/* Object.getOwnPropertySymbols() */\n\tDUK_ENUM_INCLUDE_SYMBOLS |\n\t    DUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_EXCLUDE_STRINGS |\n\t    DUK_ENUM_INCLUDE_NONENUMERABLE |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR,\n\n\t/* Reflect.ownKeys() */\n\tDUK_ENUM_INCLUDE_SYMBOLS |\n\t    DUK_ENUM_OWN_PROPERTIES_ONLY |\n\t    DUK_ENUM_INCLUDE_NONENUMERABLE |\n\t    DUK_ENUM_NO_PROXY_BEHAVIOR\n};\n\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_keys_shared(duk_hthread *thr) {\n\tduk_hobject *obj;\n#if defined(DUK_USE_ES6_PROXY)\n\tduk_hobject *h_proxy_target;\n\tduk_hobject *h_proxy_handler;\n\tduk_hobject *h_trap_result;\n#endif\n\tduk_small_uint_t enum_flags;\n\tduk_int_t magic;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\n\tmagic = duk_get_current_magic(thr);\n\tif (magic == 3) {\n\t\t/* ES2015 Section 26.1.11 requires a TypeError for non-objects.  Lightfuncs\n\t\t * and plain buffers pretend to be objects, so accept those too.\n\t\t */\n\t\tobj = duk_require_hobject_promote_mask(thr, 0, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\t} else {\n\t\t/* ES2015: ToObject coerce. */\n\t\tobj = duk_to_hobject(thr, 0);\n\t}\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(obj);\n\n\t/* XXX: proxy chains */\n\n#if defined(DUK_USE_ES6_PROXY)\n\t/* XXX: better sharing of code between proxy target call sites */\n\tif (DUK_LIKELY(!duk_hobject_proxy_check(obj,\n\t                                        &h_proxy_target,\n\t                                        &h_proxy_handler))) {\n\t\tgoto skip_proxy;\n\t}\n\n\tduk_push_hobject(thr, h_proxy_handler);\n\tif (!duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_OWN_KEYS)) {\n\t\t/* Careful with reachability here: don't pop 'obj' before pushing\n\t\t * proxy target.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"no ownKeys trap, get keys of target instead\"));\n\t\tduk_pop_2(thr);\n\t\tduk_push_hobject(thr, h_proxy_target);\n\t\tduk_replace(thr, 0);\n\t\tDUK_ASSERT_TOP(thr, 1);\n\t\tgoto skip_proxy;\n\t}\n\n\t/* [ obj handler trap ] */\n\tduk_insert(thr, -2);\n\tduk_push_hobject(thr, h_proxy_target);  /* -> [ obj trap handler target ] */\n\tduk_call_method(thr, 1 /*nargs*/);      /* -> [ obj trap_result ] */\n\th_trap_result = duk_require_hobject(thr, -1);\n\tDUK_UNREF(h_trap_result);\n\n\tmagic = duk_get_current_magic(thr);\n\tDUK_ASSERT(magic >= 0 && magic < (duk_int_t) (sizeof(duk__object_keys_enum_flags) / sizeof(duk_small_uint_t)));\n\tenum_flags = duk__object_keys_enum_flags[magic];\n\n\tduk_proxy_ownkeys_postprocess(thr, h_proxy_target, enum_flags);\n\treturn 1;\n\n skip_proxy:\n#endif  /* DUK_USE_ES6_PROXY */\n\n\tDUK_ASSERT_TOP(thr, 1);\n\tmagic = duk_get_current_magic(thr);\n\tDUK_ASSERT(magic >= 0 && magic < (duk_int_t) (sizeof(duk__object_keys_enum_flags) / sizeof(duk_small_uint_t)));\n\tenum_flags = duk__object_keys_enum_flags[magic];\n\treturn duk_hobject_get_enumerated_keys(thr, enum_flags);\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n#if defined(DUK_USE_OBJECT_BUILTIN) || defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_hthread *thr) {\n\t/*\n\t *  magic = 0: Object.preventExtensions()\n\t *  magic = 1: Reflect.preventExtensions()\n\t */\n\n\tduk_hobject *h;\n\tduk_uint_t mask;\n\tduk_int_t magic;\n\n\tmagic = duk_get_current_magic(thr);\n\n\t/* Silent success for lightfuncs and plain buffers always. */\n\tmask = DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER;\n\n\t/* Object.preventExtensions() silent success for non-object. */\n\tif (magic == 0) {\n\t\tmask |= DUK_TYPE_MASK_UNDEFINED |\n\t\t        DUK_TYPE_MASK_NULL |\n\t\t        DUK_TYPE_MASK_BOOLEAN |\n\t\t        DUK_TYPE_MASK_NUMBER |\n\t\t        DUK_TYPE_MASK_STRING |\n\t\t        DUK_TYPE_MASK_POINTER;\n\t}\n\n\tif (duk_check_type_mask(thr, 0, mask)) {\n\t\t/* Not an object, already non-extensible so always success. */\n\t\tgoto done;\n\t}\n\th = duk_require_hobject(thr, 0);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_HOBJECT_CLEAR_EXTENSIBLE(h);\n\n\t/* A non-extensible object cannot gain any more properties,\n\t * so this is a good time to compact.\n\t */\n\tduk_hobject_compact_props(thr, h);\n\n done:\n\tif (magic == 1) {\n\t\tduk_push_true(thr);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_OBJECT_BUILTIN || DUK_USE_REFLECT_BUILTIN */\n\n/*\n *  __defineGetter__, __defineSetter__, __lookupGetter__, __lookupSetter__\n */\n\n#if defined(DUK_USE_ES8)\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_defineaccessor(duk_hthread *thr) {\n\tduk_push_this(thr);\n\tduk_insert(thr, 0);\n\tduk_to_object(thr, 0);\n\tduk_require_callable(thr, 2);\n\n\t/* [ ToObject(this) key getter/setter ] */\n\n\t/* ToPropertyKey() coercion is not needed, duk_def_prop() does it. */\n\tduk_def_prop(thr, 0, DUK_DEFPROP_SET_ENUMERABLE |\n\t                     DUK_DEFPROP_SET_CONFIGURABLE |\n\t                     (duk_get_current_magic(thr) ? DUK_DEFPROP_HAVE_SETTER : DUK_DEFPROP_HAVE_GETTER));\n\treturn 0;\n}\nDUK_INTERNAL duk_ret_t duk_bi_object_prototype_lookupaccessor(duk_hthread *thr) {\n\tduk_uint_t sanity;\n\n\tduk_push_this(thr);\n\tduk_to_object(thr, -1);\n\n\t/* XXX: Prototype walk (with sanity) should be a core property\n\t * operation, could add a flag to e.g. duk_get_prop_desc().\n\t */\n\n\t/* ToPropertyKey() coercion is not needed, duk_get_prop_desc() does it. */\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\twhile (!duk_is_undefined(thr, -1)) {\n\t\t/* [ key obj ] */\n\t\tduk_dup(thr, 0);\n\t\tduk_get_prop_desc(thr, 1, 0 /*flags*/);\n\t\tif (!duk_is_undefined(thr, -1)) {\n\t\t\tduk_get_prop_stridx(thr, -1, (duk_get_current_magic(thr) != 0 ? DUK_STRIDX_SET : DUK_STRIDX_GET));\n\t\t\treturn 1;\n\t\t}\n\t\tduk_pop(thr);\n\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\n\t\tduk_get_prototype(thr, -1);\n\t\tduk_remove(thr, -2);\n\t}\n\treturn 1;\n}\n#endif  /* DUK_USE_ES8 */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_performance.c",
    "content": "/*\n *  High resolution time API (performance.now() et al)\n *\n *  API specification: https://encoding.spec.whatwg.org/#ap://www.w3.org/TR/hr-time/\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_PERFORMANCE_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_performance_now(duk_hthread *thr) {\n\t/* From API spec:\n\t * The DOMHighResTimeStamp type is used to store a time value in\n\t * milliseconds, measured relative from the time origin, global\n\t * monotonic clock, or a time value that represents a duration\n\t * between two DOMHighResTimeStamp's.\n\t */\n\tduk_push_number(thr, duk_time_get_monotonic_time(thr));\n\treturn 1;\n}\n\n#if 0  /* Missing until semantics decided. */\nDUK_INTERNAL duk_ret_t duk_bi_performance_timeorigin_getter(duk_hthread *thr) {\n\t/* No decision yet how to handle timeOrigins, e.g. should one be\n\t * initialized per heap, or per global object set.  See\n\t * https://www.w3.org/TR/hr-time/#time-origin.\n\t */\n\tduk_push_uint(thr, 0);\n\treturn 1;\n}\n#endif  /* 0 */\n#endif  /* DUK_USE_PERFORMANCE_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_pointer.c",
    "content": "/*\n *  Pointer built-ins\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_pointer_constructor(duk_hthread *thr) {\n\t/* XXX: this behavior is quite useless now; it would be nice to be able\n\t * to create pointer values from e.g. numbers or strings.  Numbers are\n\t * problematic on 64-bit platforms though.  Hex encoded strings?\n\t */\n\tif (duk_get_top(thr) == 0) {\n\t\tduk_push_pointer(thr, NULL);\n\t} else {\n\t\tduk_to_pointer(thr, 0);\n\t}\n\tDUK_ASSERT(duk_is_pointer(thr, 0));\n\tduk_set_top(thr, 1);\n\n\tif (duk_is_constructor_call(thr)) {\n\t\t(void) duk_push_object_helper(thr,\n\t\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_POINTER),\n\t\t                              DUK_BIDX_POINTER_PROTOTYPE);\n\n\t\t/* Pointer object internal value is immutable. */\n\t\tduk_dup_0(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\t/* Note: unbalanced stack on purpose */\n\n\treturn 1;\n}\n\n/*\n *  toString(), valueOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_hthread *thr) {\n\tduk_tval *tv;\n\tduk_small_int_t to_string = duk_get_current_magic(thr);\n\n\tduk_push_this(thr);\n\ttv = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_POINTER(tv)) {\n\t\t/* nop */\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* Must be a \"pointer object\", i.e. class \"Pointer\" */\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_POINTER) {\n\t\t\tgoto type_error;\n\t\t}\n\n\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t} else {\n\t\tgoto type_error;\n\t}\n\n\tif (to_string) {\n\t\tduk_to_string(thr, -1);\n\t}\n\treturn 1;\n\n type_error:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_promise.c",
    "content": "/*\n *  Promise built-in\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_PROMISE_BUILTIN)\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_constructor(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_all(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_race(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_reject(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_resolve(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_catch(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_promise_then(duk_hthread *thr) {\n\tDUK_ERROR_TYPE(thr, \"unimplemented\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\n#endif  /* DUK_USE_PROMISE_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_protos.h",
    "content": "/*\n *  Prototypes for built-in functions not automatically covered by the\n *  header declarations emitted by genbuiltins.py.\n */\n\n#if !defined(DUK_BUILTIN_PROTOS_H_INCLUDED)\n#define DUK_BUILTIN_PROTOS_H_INCLUDED\n\n/* Buffer size needed for ISO 8601 formatting.\n * Accurate value is 32 + 1 for NUL termination:\n *   >>> len('+123456-01-23T12:34:56.123+12:34')\n *   32\n * Include additional space to be safe.\n */\n#define  DUK_BI_DATE_ISO8601_BUFSIZE  40\n\n/* Helpers exposed for internal use */\nDUK_INTERNAL_DECL void duk_bi_date_timeval_to_parts(duk_double_t d, duk_int_t *parts, duk_double_t *dparts, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_timeval_from_dparts(duk_double_t *dparts, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_is_leap_year(duk_int_t year);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_timeval_in_valid_range(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_year_in_valid_range(duk_double_t year);\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_timeval_in_leeway_range(duk_double_t x);\n/* Built-in providers */\n#if defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_gettimeofday(void);\n#endif\n#if defined(DUK_USE_DATE_NOW_TIME)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_time(void);\n#endif\n#if defined(DUK_USE_DATE_NOW_WINDOWS)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows(void);\n#endif\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_now_windows_subms(void);\n#endif\n#if defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S) || defined(DUK_USE_DATE_TZO_GMTIME)\nDUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_gmtime(duk_double_t d);\n#endif\n#if defined(DUK_USE_DATE_TZO_WINDOWS)\nDUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows(duk_double_t d);\n#endif\n#if defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST)\nDUK_INTERNAL_DECL duk_int_t duk_bi_date_get_local_tzoffset_windows_no_dst(duk_double_t d);\n#endif\n#if defined(DUK_USE_DATE_PRS_STRPTIME)\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_strptime(duk_hthread *thr, const char *str);\n#endif\n#if defined(DUK_USE_DATE_PRS_GETDATE)\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_parse_string_getdate(duk_hthread *thr, const char *str);\n#endif\n#if defined(DUK_USE_DATE_FMT_STRFTIME)\nDUK_INTERNAL_DECL duk_bool_t duk_bi_date_format_parts_strftime(duk_hthread *thr, duk_int_t *parts, duk_int_t tzoffset, duk_small_uint_t flags);\n#endif\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_monotonic_time_clock_gettime(void);\n#endif\n#if defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC)\nDUK_INTERNAL_DECL duk_double_t duk_bi_date_get_monotonic_time_windows_qpc(void);\n#endif\n\nDUK_INTERNAL_DECL\nvoid duk_bi_json_parse_helper(duk_hthread *thr,\n                              duk_idx_t idx_value,\n                              duk_idx_t idx_reviver,\n                              duk_small_uint_t flags);\nDUK_INTERNAL_DECL\nvoid duk_bi_json_stringify_helper(duk_hthread *thr,\n                                  duk_idx_t idx_value,\n                                  duk_idx_t idx_replacer,\n                                  duk_idx_t idx_space,\n                                  duk_small_uint_t flags);\n\nDUK_INTERNAL_DECL duk_ret_t duk_textdecoder_decode_utf8_nodejs(duk_hthread *thr);\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL_DECL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h_proxy_target, duk_uint_t flags);\n#endif\n\n#endif  /* DUK_BUILTIN_PROTOS_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_proxy.c",
    "content": "/*\n *  Proxy built-in (ES2015)\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_ES6_PROXY)\n/* Post-process a Proxy ownKeys() result at stack top.  Push a cleaned up\n * array of valid result keys (strings or symbols).  TypeError for invalid\n * values.  Flags are shared with duk_enum().\n */\nDUK_INTERNAL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h_proxy_target, duk_uint_t flags) {\n\tduk_uarridx_t i, len, idx;\n\tduk_propdesc desc;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(h_proxy_target != NULL);\n\n\tlen = (duk_uarridx_t) duk_get_length(thr, -1);\n\tidx = 0;\n\tduk_push_array(thr);\n\t/* XXX: preallocated dense array, fill in directly */\n\tfor (i = 0; i < len; i++) {\n\t\tduk_hstring *h;\n\n\t\t/* [ obj trap_result res_arr ] */\n\t\t(void) duk_get_prop_index(thr, -2, i);\n\t\th = duk_get_hstring(thr, -1);\n\t\tif (h == NULL) {\n\t\t\tDUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\n\t\tif (!(flags & DUK_ENUM_INCLUDE_NONENUMERABLE)) {\n\t\t\t/* No support for 'getOwnPropertyDescriptor' trap yet,\n\t\t\t * so check enumerability always from target object\n\t\t\t * descriptor.\n\t\t\t */\n\t\t\tif (duk_hobject_get_own_propdesc(thr, h_proxy_target, duk_known_hstring(thr, -1), &desc, 0 /*flags*/)) {\n\t\t\t\tif ((desc.flags & DUK_PROPDESC_FLAG_ENUMERABLE) == 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore non-enumerable property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\t\tgoto skip_key;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore non-existent property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t}\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tif (!(flags & DUK_ENUM_INCLUDE_SYMBOLS)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore symbol property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t\tif (DUK_HSTRING_HAS_HIDDEN(h) && !(flags & DUK_ENUM_INCLUDE_HIDDEN)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore hidden symbol property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t} else {\n\t\t\tif (flags & DUK_ENUM_EXCLUDE_STRINGS) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"ignore string property: %!T\", duk_get_tval(thr, -1)));\n\t\t\t\tgoto skip_key;\n\t\t\t}\n\t\t}\n\n\t\t/* [ obj trap_result res_arr propname ] */\n\t\tduk_put_prop_index(thr, -2, idx++);\n\t\tcontinue;\n\n\t skip_key:\n\t\tduk_pop(thr);\n\t\tcontinue;\n\t}\n\n\t/* XXX: Missing trap result validation for non-configurable target keys\n\t * (must be present), for non-extensible target all target keys must be\n\t * present and no extra keys can be present.\n\t * http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys\n\t */\n\n\t/* XXX: The key enumerability check should trigger the \"getOwnPropertyDescriptor\"\n\t * trap which has not yet been implemented.  In the absence of such a trap,\n\t * the enumerability should be checked from the target object; this is\n\t * handled above.\n\t */\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL duk_ret_t duk_bi_proxy_constructor(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 2);  /* [ target handler ] */\n\n\tduk_require_constructor_call(thr);\n\tduk_push_proxy(thr, 0 /*flags*/);  /* [ target handler ] -> [ proxy ] */\n\treturn 1;  /* replacement */\n}\n#endif  /* DUK_USE_ES6_PROXY */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_reflect.c",
    "content": "/*\n *  'Reflect' built-in (ES2016 Section 26.1)\n *  http://www.ecma-international.org/ecma-262/7.0/#sec-reflect-object\n *\n *  Many Reflect built-in functions are provided by shared helpers in\n *  duk_bi_object.c or duk_bi_function.c.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_REFLECT_BUILTIN)\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_delete_property(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\n\t/* [ target key ] */\n\n\tDUK_ASSERT(thr != NULL);\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\tret = duk_hobject_delprop(thr, tv_obj, tv_key, 0 /*throw_flag*/);\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_get(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_idx_t nargs;\n\n\tDUK_ASSERT(thr != NULL);\n\tnargs = duk_get_top_require_min(thr, 2 /*min_top*/);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\tif (nargs >= 3 && !duk_strict_equals(thr, 0, 2)) {\n\t\t/* XXX: [[Get]] receiver currently unsupported */\n\t\tDUK_ERROR_UNSUPPORTED(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* [ target key receiver? ...? ] */\n\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\t(void) duk_hobject_getprop(thr, tv_obj, tv_key);  /* This could also be a duk_get_prop(). */\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_has(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT_TOP(thr, 2);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\n\t/* [ target key ] */\n\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\tret = duk_hobject_hasprop(thr, tv_obj, tv_key);\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_reflect_object_set(duk_hthread *thr) {\n\tduk_tval *tv_obj;\n\tduk_tval *tv_key;\n\tduk_tval *tv_val;\n\tduk_idx_t nargs;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\tnargs = duk_get_top_require_min(thr, 3 /*min_top*/);\n\t(void) duk_require_hobject(thr, 0);\n\t(void) duk_to_string(thr, 1);\n\tif (nargs >= 4 && !duk_strict_equals(thr, 0, 3)) {\n\t\t/* XXX: [[Set]] receiver currently unsupported */\n\t\tDUK_ERROR_UNSUPPORTED(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* [ target key value receiver? ...? ] */\n\n\ttv_obj = DUK_GET_TVAL_POSIDX(thr, 0);\n\ttv_key = DUK_GET_TVAL_POSIDX(thr, 1);\n\ttv_val = DUK_GET_TVAL_POSIDX(thr, 2);\n\tret = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, 0 /*throw_flag*/);\n\tduk_push_boolean(thr, ret);\n\treturn 1;\n}\n#endif  /* DUK_USE_REFLECT_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_regexp.c",
    "content": "/*\n *  RegExp built-ins\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\nDUK_LOCAL void duk__get_this_regexp(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\tduk_push_this(thr);\n\th = duk_require_hobject_with_class(thr, -1, DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_ASSERT(h != NULL);\n\tDUK_UNREF(h);\n\tduk_insert(thr, 0);  /* prepend regexp to valstack 0 index */\n}\n\n/* XXX: much to improve (code size) */\nDUK_INTERNAL duk_ret_t duk_bi_regexp_constructor(duk_hthread *thr) {\n\tduk_hobject *h_pattern;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\th_pattern = duk_get_hobject(thr, 0);\n\n\tif (!duk_is_constructor_call(thr) &&\n\t    h_pattern != NULL &&\n\t    DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP &&\n\t    duk_is_undefined(thr, 1)) {\n\t\t/* Called as a function, pattern has [[Class]] \"RegExp\" and\n\t\t * flags is undefined -> return object as is.\n\t\t */\n\t\t/* XXX: ES2015 has a NewTarget SameValue() check which is not\n\t\t * yet implemented.\n\t\t */\n\t\tduk_dup_0(thr);\n\t\treturn 1;\n\t}\n\n\t/* Else functionality is identical for function call and constructor\n\t * call.\n\t */\n\n\tif (h_pattern != NULL &&\n\t    DUK_HOBJECT_GET_CLASS_NUMBER(h_pattern) == DUK_HOBJECT_CLASS_REGEXP) {\n\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_SOURCE);\n\t\tif (duk_is_undefined(thr, 1)) {\n\t\t\t/* In ES5 one would need to read the flags individually;\n\t\t\t * in ES2015 just read .flags.\n\t\t\t */\n\t\t\tduk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS);\n\t\t} else {\n\t\t\t/* In ES2015 allowed; overrides argument RegExp flags. */\n\t\t\tduk_dup_1(thr);\n\t\t}\n\t} else {\n\t\tif (duk_is_undefined(thr, 0)) {\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_to_string(thr, -1);  /* Rejects Symbols. */\n\t\t}\n\t\tif (duk_is_undefined(thr, 1)) {\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tduk_dup_1(thr);\n\t\t\tduk_to_string(thr, -1);  /* Rejects Symbols. */\n\t\t}\n\n\t\t/* [ ... pattern flags ] */\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"RegExp constructor/function call, pattern=%!T, flags=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* [ ... pattern flags ] (both uncoerced) */\n\n\tduk_to_string(thr, -2);\n\tduk_to_string(thr, -1);\n\tduk_regexp_compile(thr);\n\n\t/* [ ... bytecode escaped_source ] */\n\n\tduk_regexp_create_instance(thr);\n\n\t/* [ ... RegExp ] */\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_exec(duk_hthread *thr) {\n\tduk__get_this_regexp(thr);\n\n\t/* [ regexp input ] */\n\n\tduk_regexp_match(thr);\n\n\t/* [ result ] */\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_test(duk_hthread *thr) {\n\tduk__get_this_regexp(thr);\n\n\t/* [ regexp input ] */\n\n\t/* result object is created and discarded; wasteful but saves code space */\n\tduk_regexp_match(thr);\n\n\t/* [ result ] */\n\n\tduk_push_boolean(thr, (duk_is_null(thr, -1) ? 0 : 1));\n\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_tostring(duk_hthread *thr) {\n\t/* This must be generic in ES2015 and later. */\n\tDUK_ASSERT_TOP(thr, 0);\n\tduk_push_this(thr);\n\tduk_push_literal(thr, \"/\");\n\tduk_get_prop_stridx(thr, 0, DUK_STRIDX_SOURCE);\n\tduk_dup_m2(thr);  /* another \"/\" */\n\tduk_get_prop_stridx(thr, 0, DUK_STRIDX_FLAGS);\n\tduk_concat(thr, 4);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_flags(duk_hthread *thr) {\n\t/* .flags is ES2015 but present even when ES2015 bindings are\n\t * disabled because the constructor relies on it.\n\t */\n\tduk_uint8_t buf[8];  /* enough for all flags + NUL */\n\tduk_uint8_t *p = buf;\n\n\t/* .flags is generic and works on any object. */\n\tduk_push_this(thr);\n\t(void) duk_require_hobject(thr, -1);\n\tif (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL)) {\n\t\t*p++ = DUK_ASC_LC_G;\n\t}\n\tif (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_IGNORE_CASE, NULL)) {\n\t\t*p++ = DUK_ASC_LC_I;\n\t}\n\tif (duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_MULTILINE, NULL)) {\n\t\t*p++ = DUK_ASC_LC_M;\n\t}\n\t/* .unicode: to be added */\n\t/* .sticky: to be added */\n\t*p++ = DUK_ASC_NUL;\n\tDUK_ASSERT((duk_size_t) (p - buf) <= sizeof(buf));\n\n\tduk_push_string(thr, (const char *) buf);\n\treturn 1;\n}\n\n/* Shared helper for providing .source, .global, .multiline, etc getters. */\nDUK_INTERNAL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_hthread *thr) {\n\tduk_hstring *h_bc;\n\tduk_small_uint_t re_flags;\n\tduk_hobject *h;\n\tduk_int_t magic;\n\n\tDUK_ASSERT_TOP(thr, 0);\n\n\tduk_push_this(thr);\n\th = duk_require_hobject(thr, -1);\n\tmagic = duk_get_current_magic(thr);\n\n\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_REGEXP) {\n\t\tduk_xget_owndataprop_stridx_short(thr, 0, DUK_STRIDX_INT_SOURCE);\n\t\tduk_xget_owndataprop_stridx_short(thr, 0, DUK_STRIDX_INT_BYTECODE);\n\t\th_bc = duk_require_hstring(thr, -1);\n\t\tre_flags = (duk_small_uint_t) DUK_HSTRING_GET_DATA(h_bc)[0];  /* Safe even if h_bc length is 0 (= NUL) */\n\t\tduk_pop(thr);\n\t} else if (h == thr->builtins[DUK_BIDX_REGEXP_PROTOTYPE]) {\n\t\t/* In ES2015 and ES2016 a TypeError would be thrown here.\n\t\t * However, this had real world issues so ES2017 draft\n\t\t * allows RegExp.prototype specifically, returning '(?:)'\n\t\t * for .source and undefined for all flags.\n\t\t */\n\t\tif (magic != 16 /* .source */) {\n\t\t\treturn 0;\n\t\t}\n\t\tduk_push_literal(thr, \"(?:)\");  /* .source handled by switch-case */\n\t\tre_flags = 0;\n\t} else {\n\t\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n\t}\n\n\t/* [ regexp source ] */\n\n\tswitch (magic) {\n\tcase 0: {  /* global */\n\t\tduk_push_boolean(thr, (re_flags & DUK_RE_FLAG_GLOBAL));\n\t\tbreak;\n\t}\n\tcase 1: {  /* ignoreCase */\n\t\tduk_push_boolean(thr, (re_flags & DUK_RE_FLAG_IGNORE_CASE));\n\t\tbreak;\n\t}\n\tcase 2: {  /* multiline */\n\t\tduk_push_boolean(thr, (re_flags & DUK_RE_FLAG_MULTILINE));\n\t\tbreak;\n\t}\n#if 0\n\t/* Don't provide until implemented to avoid interfering with feature\n\t * detection in user code.\n\t */\n\tcase 3:    /* sticky */\n\tcase 4: {  /* unicode */\n\t\tduk_push_false(thr);\n\t\tbreak;\n\t}\n#endif\n\tdefault: {  /* source */\n\t\t/* leave 'source' on top */\n\t\tbreak;\n\t}\n\t}\n\n\treturn 1;\n}\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_string.c",
    "content": "/*\n *  String built-ins\n *\n *  Most String built-ins must only accept strings (or String objects).\n *  Symbols, represented internally as strings, must be generally rejected.\n *  The duk_push_this_coercible_to_string() helper does this automatically.\n */\n\n/* XXX: There are several limitations in the current implementation for\n * strings with >= 0x80000000UL characters.  In some cases one would need\n * to be able to represent the range [-0xffffffff,0xffffffff] and so on.\n * Generally character and byte length are assumed to fit into signed 32\n * bits (< 0x80000000UL).  Places with issues are not marked explicitly\n * below in all cases, look for signed type usage (duk_int_t etc) for\n * offsets/lengths.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_STRING_BUILTIN)\n\n/*\n *  Helpers\n */\n\nDUK_LOCAL duk_hstring *duk__str_tostring_notregexp(duk_hthread *thr, duk_idx_t idx) {\n\tduk_hstring *h;\n\n\tif (duk_get_class_number(thr, idx) == DUK_HOBJECT_CLASS_REGEXP) {\n\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\th = duk_to_hstring(thr, idx);\n\tDUK_ASSERT(h != NULL);\n\n\treturn h;\n}\n\nDUK_LOCAL duk_int_t duk__str_search_shared(duk_hthread *thr, duk_hstring *h_this, duk_hstring *h_search, duk_int_t start_cpos, duk_bool_t backwards) {\n\tduk_int_t cpos;\n\tduk_int_t bpos;\n\tconst duk_uint8_t *p_start, *p_end, *p;\n\tconst duk_uint8_t *q_start;\n\tduk_int_t q_blen;\n\tduk_uint8_t firstbyte;\n\tduk_uint8_t t;\n\n\tcpos = start_cpos;\n\n\t/* Empty searchstring always matches; cpos must be clamped here.\n\t * (If q_blen were < 0 due to clamped coercion, it would also be\n\t * caught here.)\n\t */\n\tq_start = DUK_HSTRING_GET_DATA(h_search);\n\tq_blen = (duk_int_t) DUK_HSTRING_GET_BYTELEN(h_search);\n\tif (q_blen <= 0) {\n\t\treturn cpos;\n\t}\n\tDUK_ASSERT(q_blen > 0);\n\n\tbpos = (duk_int_t) duk_heap_strcache_offset_char2byte(thr, h_this, (duk_uint32_t) cpos);\n\n\tp_start = DUK_HSTRING_GET_DATA(h_this);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_this);\n\tp = p_start + bpos;\n\n\t/* This loop is optimized for size.  For speed, there should be\n\t * two separate loops, and we should ensure that memcmp() can be\n\t * used without an extra \"will searchstring fit\" check.  Doing\n\t * the preconditioning for 'p' and 'p_end' is easy but cpos\n\t * must be updated if 'p' is wound back (backward scanning).\n\t */\n\n\tfirstbyte = q_start[0];  /* leading byte of match string */\n\twhile (p <= p_end && p >= p_start) {\n\t\tt = *p;\n\n\t\t/* For ECMAScript strings, this check can only match for\n\t\t * initial UTF-8 bytes (not continuation bytes).  For other\n\t\t * strings all bets are off.\n\t\t */\n\n\t\tif ((t == firstbyte) && ((duk_size_t) (p_end - p) >= (duk_size_t) q_blen)) {\n\t\t\tDUK_ASSERT(q_blen > 0);\n\t\t\tif (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {\n\t\t\t\treturn cpos;\n\t\t\t}\n\t\t}\n\n\t\t/* track cpos while scanning */\n\t\tif (backwards) {\n\t\t\t/* when going backwards, we decrement cpos 'early';\n\t\t\t * 'p' may point to a continuation byte of the char\n\t\t\t * at offset 'cpos', but that's OK because we'll\n\t\t\t * backtrack all the way to the initial byte.\n\t\t\t */\n\t\t\tif ((t & 0xc0) != 0x80) {\n\t\t\t\tcpos--;\n\t\t\t}\n\t\t\tp--;\n\t\t} else {\n\t\t\tif ((t & 0xc0) != 0x80) {\n\t\t\t\tcpos++;\n\t\t\t}\n\t\t\tp++;\n\t\t}\n\t}\n\n\t/* Not found.  Empty string case is handled specially above. */\n\treturn -1;\n}\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_constructor(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_uint_t flags;\n\n\t/* String constructor needs to distinguish between an argument not given at all\n\t * vs. given as 'undefined'.  We're a vararg function to handle this properly.\n\t */\n\n\t/* XXX: copy current activation flags to thr, including current magic,\n\t * is_constructor_call etc.  This takes a few bytes in duk_hthread but\n\t * makes call sites smaller (there are >30 is_constructor_call and get\n\t * current magic call sites.\n\t */\n\n\tif (duk_get_top(thr) == 0) {\n\t\tduk_push_hstring_empty(thr);\n\t} else {\n\t\th = duk_to_hstring_acceptsymbol(thr, 0);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h) && !duk_is_constructor_call(thr))) {\n\t\t\tduk_push_symbol_descriptive_string(thr, h);\n\t\t\tduk_replace(thr, 0);\n\t\t}\n\t}\n\tduk_to_string(thr, 0);  /* catches symbol argument for constructor call */\n\tDUK_ASSERT(duk_is_string(thr, 0));\n\tduk_set_top(thr, 1);  /* Top may be 1 or larger. */\n\n\tif (duk_is_constructor_call(thr)) {\n\t\t/* String object internal value is immutable */\n\t\tflags = DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t        DUK_HOBJECT_FLAG_FASTREFS |\n\t\t        DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ |\n\t\t        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_STRING);\n\t\tduk_push_object_helper(thr, flags, DUK_BIDX_STRING_PROTOTYPE);\n\t\tduk_dup_0(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VALUE, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\t/* Note: unbalanced stack on purpose */\n\n\treturn 1;\n}\n\nDUK_LOCAL duk_ret_t duk__construct_from_codepoints(duk_hthread *thr, duk_bool_t nonbmp) {\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tduk_idx_t i, n;\n\tduk_ucodepoint_t cp;\n\n\t/* XXX: It would be nice to build the string directly but ToUint16()\n\t * coercion is needed so a generic helper would not be very\n\t * helpful (perhaps coerce the value stack first here and then\n\t * build a string from a duk_tval number sequence in one go?).\n\t */\n\n\tn = duk_get_top(thr);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, (duk_size_t) n);  /* initial estimate for ASCII only codepoints */\n\n\tfor (i = 0; i < n; i++) {\n\t\t/* XXX: could improve bufwriter handling to write multiple codepoints\n\t\t * with one ensure call but the relative benefit would be quite small.\n\t\t */\n\n\t\tif (nonbmp) {\n\t\t\t/* ES2015 requires that (1) SameValue(cp, ToInteger(cp)) and\n\t\t\t * (2) cp >= 0 and cp <= 0x10ffff.  This check does not\n\t\t\t * implement the steps exactly but the outcome should be\n\t\t\t * the same.\n\t\t\t */\n\t\t\tduk_int32_t i32 = 0;\n\t\t\tif (!duk_is_whole_get_int32(duk_to_number(thr, i), &i32) ||\n\t\t\t    i32 < 0 || i32 > 0x10ffffL) {\n\t\t\t\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n\t\t\t}\n\t\t\tDUK_ASSERT(i32 >= 0 && i32 <= 0x10ffffL);\n\t\t\tcp = (duk_ucodepoint_t) i32;\n\t\t\tDUK_BW_WRITE_ENSURE_CESU8(thr, bw, cp);\n\t\t} else {\n#if defined(DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT)\n\t\t\t/* ToUint16() coercion is mandatory in the E5.1 specification, but\n\t\t\t * this non-compliant behavior makes more sense because we support\n\t\t\t * non-BMP codepoints.  Don't use CESU-8 because that'd create\n\t\t\t * surrogate pairs.\n\t\t\t */\n\t\t\tcp = (duk_ucodepoint_t) duk_to_uint32(thr, i);\n\t\t\tDUK_BW_WRITE_ENSURE_XUTF8(thr, bw, cp);\n#else\n\t\t\tcp = (duk_ucodepoint_t) duk_to_uint16(thr, i);\n\t\t\tDUK_ASSERT(cp >= 0 && cp <= 0x10ffffL);\n\t\t\tDUK_BW_WRITE_ENSURE_CESU8(thr, bw, cp);\n#endif\n\t\t}\n\t}\n\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe, extended UTF-8 or CESU-8 encoded. */\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_string_constructor_from_char_code(duk_hthread *thr) {\n\treturn duk__construct_from_codepoints(thr, 0 /*nonbmp*/);\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_constructor_from_code_point(duk_hthread *thr) {\n\treturn duk__construct_from_codepoints(thr, 1 /*nonbmp*/);\n}\n#endif\n\n/*\n *  toString(), valueOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_to_string(duk_hthread *thr) {\n\tduk_tval *tv;\n\n\tduk_push_this(thr);\n\ttv = duk_require_tval(thr, -1);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_IS_STRING(tv)) {\n\t\t/* return as is */\n\t} else if (DUK_TVAL_IS_OBJECT(tv)) {\n\t\tduk_hobject *h = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\t/* Must be a \"string object\", i.e. class \"String\" */\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_STRING) {\n\t\t\tgoto type_error;\n\t\t}\n\n\t\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_VALUE);\n\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\t} else {\n\t\tgoto type_error;\n\t}\n\n\t(void) duk_require_hstring_notsymbol(thr, -1);  /* Reject symbols (and wrapped symbols). */\n\treturn 1;\n\n type_error:\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n\n/*\n *  Character and charcode access\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_at(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t pos;\n\n\t/* XXX: faster implementation */\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tpos = duk_to_int(thr, 0);\n\n\tif (sizeof(duk_size_t) >= sizeof(duk_uint_t)) {\n\t\t/* Cast to duk_size_t works in this case:\n\t\t * - If pos < 0, (duk_size_t) pos will always be\n\t\t *   >= max_charlen, and result will be the empty string\n\t\t *   (see duk_substring()).\n\t\t * - If pos >= 0, pos + 1 cannot wrap.\n\t\t */\n\t\tDUK_ASSERT((duk_size_t) DUK_INT_MIN >= DUK_HSTRING_MAX_BYTELEN);\n\t\tDUK_ASSERT((duk_size_t) DUK_INT_MAX + 1U > (duk_size_t) DUK_INT_MAX);\n\t\tduk_substring(thr, -1, (duk_size_t) pos, (duk_size_t) pos + 1U);\n\t} else {\n\t\t/* If size_t is smaller than int, explicit bounds checks\n\t\t * are needed because an int may wrap multiple times.\n\t\t */\n\t\tif (DUK_UNLIKELY(pos < 0 || (duk_uint_t) pos >= (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h))) {\n\t\t\tduk_push_hstring_empty(thr);\n\t\t} else {\n\t\t\tduk_substring(thr, -1, (duk_size_t) pos, (duk_size_t) pos + 1U);\n\t\t}\n\t}\n\n\treturn 1;\n}\n\n/* Magic: 0=charCodeAt, 1=codePointAt */\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_char_code_at(duk_hthread *thr) {\n\tduk_int_t pos;\n\tduk_hstring *h;\n\tduk_bool_t clamped;\n\tduk_uint32_t cp;\n\tduk_int_t magic;\n\n\t/* XXX: faster implementation */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arg=%!T\", (duk_tval *) duk_get_tval(thr, 0)));\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\tpos = duk_to_int_clamped_raw(thr,\n\t                             0 /*index*/,\n\t                             0 /*min(incl)*/,\n\t                             (duk_int_t) DUK_HSTRING_GET_CHARLEN(h) - 1 /*max(incl)*/,\n\t                             &clamped /*out_clamped*/);\n#if defined(DUK_USE_ES6)\n\tmagic = duk_get_current_magic(thr);\n#else\n\tDUK_ASSERT(duk_get_current_magic(thr) == 0);\n\tmagic = 0;\n#endif\n\tif (clamped) {\n\t\t/* For out-of-bounds indices .charCodeAt() returns NaN and\n\t\t * .codePointAt() returns undefined.\n\t\t */\n\t\tif (magic != 0) {\n\t\t\treturn 0;\n\t\t}\n\t\tduk_push_nan(thr);\n\t} else {\n\t\tDUK_ASSERT(pos >= 0);\n\t\tcp = (duk_uint32_t) duk_hstring_char_code_at_raw(thr, h, (duk_uint_t) pos, (duk_bool_t) magic /*surrogate_aware*/);\n\t\tduk_push_u32(thr, cp);\n\t}\n\treturn 1;\n}\n\n/*\n *  substring(), substr(), slice()\n */\n\n/* XXX: any chance of merging these three similar but still slightly\n * different algorithms so that footprint would be reduced?\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_substring(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t start_pos, end_pos;\n\tduk_int_t len;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\n\t/* [ start end str ] */\n\n\tstart_pos = duk_to_int_clamped(thr, 0, 0, len);\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend_pos = len;\n\t} else {\n\t\tend_pos = duk_to_int_clamped(thr, 1, 0, len);\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\tDUK_ASSERT(end_pos >= 0 && end_pos <= len);\n\n\tif (start_pos > end_pos) {\n\t\tduk_int_t tmp = start_pos;\n\t\tstart_pos = end_pos;\n\t\tend_pos = tmp;\n\t}\n\n\tDUK_ASSERT(end_pos >= start_pos);\n\n\tduk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);\n\treturn 1;\n}\n\n#if defined(DUK_USE_SECTION_B)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_substr(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t start_pos, end_pos;\n\tduk_int_t len;\n\n\t/* Unlike non-obsolete String calls, substr() algorithm in E5.1\n\t * specification will happily coerce undefined and null to strings\n\t * (\"undefined\" and \"null\").\n\t */\n\tduk_push_this(thr);\n\th = duk_to_hstring_m1(thr);  /* Reject Symbols. */\n\tDUK_ASSERT(h != NULL);\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\n\t/* [ start length str ] */\n\n\t/* The implementation for computing of start_pos and end_pos differs\n\t * from the standard algorithm, but is intended to result in the exactly\n\t * same behavior.  This is not always obvious.\n\t */\n\n\t/* combines steps 2 and 5; -len ensures max() not needed for step 5 */\n\tstart_pos = duk_to_int_clamped(thr, 0, -len, len);\n\tif (start_pos < 0) {\n\t\tstart_pos = len + start_pos;\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\n\t/* combines steps 3, 6; step 7 is not needed */\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend_pos = len;\n\t} else {\n\t\tDUK_ASSERT(start_pos <= len);\n\t\tend_pos = start_pos + duk_to_int_clamped(thr, 1, 0, len - start_pos);\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\tDUK_ASSERT(end_pos >= 0 && end_pos <= len);\n\tDUK_ASSERT(end_pos >= start_pos);\n\n\tduk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);\n\treturn 1;\n}\n#endif  /* DUK_USE_SECTION_B */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_slice(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_int_t start_pos, end_pos;\n\tduk_int_t len;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\n\t/* [ start end str ] */\n\n\tstart_pos = duk_to_int_clamped(thr, 0, -len, len);\n\tif (start_pos < 0) {\n\t\tstart_pos = len + start_pos;\n\t}\n\tif (duk_is_undefined(thr, 1)) {\n\t\tend_pos = len;\n\t} else {\n\t\tend_pos = duk_to_int_clamped(thr, 1, -len, len);\n\t\tif (end_pos < 0) {\n\t\t\tend_pos = len + end_pos;\n\t\t}\n\t}\n\tDUK_ASSERT(start_pos >= 0 && start_pos <= len);\n\tDUK_ASSERT(end_pos >= 0 && end_pos <= len);\n\n\tif (end_pos < start_pos) {\n\t\tend_pos = start_pos;\n\t}\n\n\tDUK_ASSERT(end_pos >= start_pos);\n\n\tduk_substring(thr, -1, (duk_size_t) start_pos, (duk_size_t) end_pos);\n\treturn 1;\n}\n\n/*\n *  Case conversion\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_caseconv_shared(duk_hthread *thr) {\n\tduk_small_int_t uppercase = duk_get_current_magic(thr);\n\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk_unicode_case_convert_string(thr, (duk_bool_t) uppercase);\n\treturn 1;\n}\n\n/*\n *  indexOf() and lastIndexOf()\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_indexof_shared(duk_hthread *thr) {\n\tduk_hstring *h_this;\n\tduk_hstring *h_search;\n\tduk_int_t clen_this;\n\tduk_int_t cpos;\n\tduk_small_uint_t is_lastindexof = (duk_small_uint_t) duk_get_current_magic(thr);  /* 0=indexOf, 1=lastIndexOf */\n\n\th_this = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_this != NULL);\n\tclen_this = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h_this);\n\n\th_search = duk_to_hstring(thr, 0);\n\tDUK_ASSERT(h_search != NULL);\n\n\tduk_to_number(thr, 1);\n\tif (duk_is_nan(thr, 1) && is_lastindexof) {\n\t\t/* indexOf: NaN should cause pos to be zero.\n\t\t * lastIndexOf: NaN should cause pos to be +Infinity\n\t\t * (and later be clamped to len).\n\t\t */\n\t\tcpos = clen_this;\n\t} else {\n\t\tcpos = duk_to_int_clamped(thr, 1, 0, clen_this);\n\t}\n\n\tcpos = duk__str_search_shared(thr, h_this, h_search, cpos, is_lastindexof /*backwards*/);\n\tduk_push_int(thr, cpos);\n\treturn 1;\n}\n\n/*\n *  replace()\n */\n\n/* XXX: the current implementation works but is quite clunky; it compiles\n * to almost 1,4kB of x86 code so it needs to be simplified (better approach,\n * shared helpers, etc).  Some ideas for refactoring:\n *\n * - a primitive to convert a string into a regexp matcher (reduces matching\n *   code at the cost of making matching much slower)\n * - use replace() as a basic helper for match() and split(), which are both\n *   much simpler\n * - API call to get_prop and to_boolean\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) {\n\tduk_hstring *h_input;\n\tduk_hstring *h_match;\n\tduk_hstring *h_search;\n\tduk_hobject *h_re;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tduk_bool_t is_regexp;\n\tduk_bool_t is_global;\n#endif\n\tduk_bool_t is_repl_func;\n\tduk_uint32_t match_start_coff, match_start_boff;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tduk_int_t match_caps;\n#endif\n\tduk_uint32_t prev_match_end_boff;\n\tconst duk_uint8_t *r_start, *r_end, *r;   /* repl string scan */\n\tduk_size_t tmp_sz;\n\n\tDUK_ASSERT_TOP(thr, 2);\n\th_input = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_input != NULL);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input));  /* input size is good output starting point */\n\n\tDUK_ASSERT_TOP(thr, 4);\n\n\t/* stack[0] = search value\n\t * stack[1] = replace value\n\t * stack[2] = input string\n\t * stack[3] = result buffer\n\t */\n\n\th_re = duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_REGEXP);\n\tif (h_re) {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tis_regexp = 1;\n\t\tis_global = duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL);\n\n\t\tif (is_global) {\n\t\t\t/* start match from beginning */\n\t\t\tduk_push_int(thr, 0);\n\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t}\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\tDUK_DCERROR_UNSUPPORTED(thr);\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t} else {\n\t\tduk_to_string(thr, 0);  /* rejects symbols */\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tis_regexp = 0;\n\t\tis_global = 0;\n#endif\n\t}\n\n\tif (duk_is_function(thr, 1)) {\n\t\tis_repl_func = 1;\n\t\tr_start = NULL;\n\t\tr_end = NULL;\n\t} else {\n\t\tduk_hstring *h_repl;\n\n\t\tis_repl_func = 0;\n\t\th_repl = duk_to_hstring(thr, 1);  /* reject symbols */\n\t\tDUK_ASSERT(h_repl != NULL);\n\t\tr_start = DUK_HSTRING_GET_DATA(h_repl);\n\t\tr_end = r_start + DUK_HSTRING_GET_BYTELEN(h_repl);\n\t}\n\n\tprev_match_end_boff = 0;\n\n\tfor (;;) {\n\t\t/*\n\t\t *  If matching with a regexp:\n\t\t *    - non-global RegExp: lastIndex not touched on a match, zeroed\n\t\t *      on a non-match\n\t\t *    - global RegExp: on match, lastIndex will be updated by regexp\n\t\t *      executor to point to next char after the matching part (so that\n\t\t *      characters in the matching part are not matched again)\n\t\t *\n\t\t *  If matching with a string:\n\t\t *    - always non-global match, find first occurrence\n\t\t *\n\t\t *  We need:\n\t\t *    - The character offset of start-of-match for the replacer function\n\t\t *    - The byte offsets for start-of-match and end-of-match to implement\n\t\t *      the replacement values $&, $`, and $', and to copy non-matching\n\t\t *      input string portions (including header and trailer) verbatim.\n\t\t *\n\t\t *  NOTE: the E5.1 specification is a bit vague how the RegExp should\n\t\t *  behave in the replacement process; e.g. is matching done first for\n\t\t *  all matches (in the global RegExp case) before any replacer calls\n\t\t *  are made?  See: test-bi-string-proto-replace.js for discussion.\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, 4);\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (is_regexp) {\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_dup_2(thr);\n\t\t\tduk_regexp_match(thr);  /* [ ... regexp input ] -> [ res_obj ] */\n\t\t\tif (!duk_is_object(thr, -1)) {\n\t\t\t\tduk_pop(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX);\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tmatch_start_coff = duk_get_uint(thr, -1);\n\t\t\tduk_pop(thr);\n\n\t\t\tduk_get_prop_index(thr, -1, 0);\n\t\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\t\t\th_match = duk_known_hstring(thr, -1);\n\t\t\tduk_pop(thr);  /* h_match is borrowed, remains reachable through match_obj */\n\n\t\t\tif (DUK_HSTRING_GET_BYTELEN(h_match) == 0) {\n\t\t\t\t/* This should be equivalent to match() algorithm step 8.f.iii.2:\n\t\t\t\t * detect an empty match and allow it, but don't allow it twice.\n\t\t\t\t */\n\t\t\t\tduk_uint32_t last_index;\n\n\t\t\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\t\tlast_index = (duk_uint32_t) duk_get_uint(thr, -1);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"empty match, bump lastIndex: %ld -> %ld\",\n\t\t\t\t                     (long) last_index, (long) (last_index + 1)));\n\t\t\t\tduk_pop(thr);\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) (last_index + 1));\n\t\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\t}\n\n\t\t\tDUK_ASSERT(duk_get_length(thr, -1) <= DUK_INT_MAX);  /* string limits */\n\t\t\tmatch_caps = (duk_int_t) duk_get_length(thr, -1);\n\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\tconst duk_uint8_t *p_start, *p_end, *p;   /* input string scan */\n\t\t\tconst duk_uint8_t *q_start;               /* match string */\n\t\t\tduk_size_t q_blen;\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\tDUK_ASSERT(!is_global);  /* single match always */\n#endif\n\n\t\t\tp_start = DUK_HSTRING_GET_DATA(h_input);\n\t\t\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\t\t\tp = p_start;\n\n\t\t\th_search = duk_known_hstring(thr, 0);\n\t\t\tq_start = DUK_HSTRING_GET_DATA(h_search);\n\t\t\tq_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_search);\n\n\t\t\tp_end -= q_blen;  /* ensure full memcmp() fits in while */\n\n\t\t\tmatch_start_coff = 0;\n\n\t\t\twhile (p <= p_end) {\n\t\t\t\tDUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + DUK_HSTRING_GET_BYTELEN(h_input));\n\t\t\t\tif (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {\n\t\t\t\t\tduk_dup_0(thr);\n\t\t\t\t\th_match = duk_known_hstring(thr, -1);\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t\t\tmatch_caps = 0;\n#endif\n\t\t\t\t\tgoto found;\n\t\t\t\t}\n\n\t\t\t\t/* track utf-8 non-continuation bytes */\n\t\t\t\tif ((p[0] & 0xc0) != 0x80) {\n\t\t\t\t\tmatch_start_coff++;\n\t\t\t\t}\n\t\t\t\tp++;\n\t\t\t}\n\n\t\t\t/* not found */\n\t\t\tbreak;\n\t\t}\n\t found:\n\n\t\t/* stack[0] = search value\n\t\t * stack[1] = replace value\n\t\t * stack[2] = input string\n\t\t * stack[3] = result buffer\n\t\t * stack[4] = regexp match OR match string\n\t\t */\n\n\t\tmatch_start_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h_input, match_start_coff);\n\n\t\ttmp_sz = (duk_size_t) (match_start_boff - prev_match_end_boff);\n\t\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff, tmp_sz);\n\n\t\tprev_match_end_boff = match_start_boff + DUK_HSTRING_GET_BYTELEN(h_match);\n\n\t\tif (is_repl_func) {\n\t\t\tduk_idx_t idx_args;\n\t\t\tduk_hstring *h_repl;\n\n\t\t\t/* regexp res_obj is at index 4 */\n\n\t\t\tduk_dup_1(thr);\n\t\t\tidx_args = duk_get_top(thr);\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\tif (is_regexp) {\n\t\t\t\tduk_int_t idx;\n\t\t\t\tduk_require_stack(thr, match_caps + 2);\n\t\t\t\tfor (idx = 0; idx < match_caps; idx++) {\n\t\t\t\t\t/* match followed by capture(s) */\n\t\t\t\t\tduk_get_prop_index(thr, 4, (duk_uarridx_t) idx);\n\t\t\t\t}\n\t\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t\t/* match == search string, by definition */\n\t\t\t\tduk_dup_0(thr);\n\t\t\t}\n\t\t\tduk_push_uint(thr, (duk_uint_t) match_start_coff);\n\t\t\tduk_dup_2(thr);\n\n\t\t\t/* [ ... replacer match [captures] match_char_offset input ] */\n\n\t\t\tduk_call(thr, duk_get_top(thr) - idx_args);\n\t\t\th_repl = duk_to_hstring_m1(thr);  /* -> [ ... repl_value ] */\n\t\t\tDUK_ASSERT(h_repl != NULL);\n\n\t\t\tDUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_repl);\n\n\t\t\tduk_pop(thr);  /* repl_value */\n\t\t} else {\n\t\t\tr = r_start;\n\n\t\t\twhile (r < r_end) {\n\t\t\t\tduk_int_t ch1;\n\t\t\t\tduk_int_t ch2;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t\tduk_int_t ch3;\n#endif\n\t\t\t\tduk_size_t left;\n\n\t\t\t\tch1 = *r++;\n\t\t\t\tif (ch1 != DUK_ASC_DOLLAR) {\n\t\t\t\t\tgoto repl_write;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(r <= r_end);\n\t\t\t\tleft = (duk_size_t) (r_end - r);\n\n\t\t\t\tif (left <= 0) {\n\t\t\t\t\tgoto repl_write;\n\t\t\t\t}\n\n\t\t\t\tch2 = r[0];\n\t\t\t\tswitch (ch2) {\n\t\t\t\tcase DUK_ASC_DOLLAR: {\n\t\t\t\t\tch1 = (1 << 8) + DUK_ASC_DOLLAR;\n\t\t\t\t\tgoto repl_write;\n\t\t\t\t}\n\t\t\t\tcase DUK_ASC_AMP: {\n\t\t\t\t\tDUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_match);\n\t\t\t\t\tr++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcase DUK_ASC_GRAVE: {\n\t\t\t\t\ttmp_sz = (duk_size_t) match_start_boff;\n\t\t\t\t\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input), tmp_sz);\n\t\t\t\t\tr++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tcase DUK_ASC_SINGLEQUOTE: {\n\t\t\t\t\tduk_uint32_t match_end_boff;\n\n\t\t\t\t\t/* Use match charlen instead of bytelen, just in case the input and\n\t\t\t\t\t * match codepoint encodings would have different lengths.\n\t\t\t\t\t */\n\t\t\t\t\t/* XXX: charlen computed here, and also in char2byte helper. */\n\t\t\t\t\tmatch_end_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr,\n\t\t\t\t\t                                                                   h_input,\n\t\t\t\t\t                                                                   match_start_coff + (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h_match));\n\n\t\t\t\t\ttmp_sz = (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - match_end_boff);\n\t\t\t\t\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + match_end_boff, tmp_sz);\n\t\t\t\t\tr++;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tdefault: {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t\t\tduk_int_t capnum, captmp, capadv;\n\t\t\t\t\t/* XXX: optional check, match_caps is zero if no regexp,\n\t\t\t\t\t * so dollar will be interpreted literally anyway.\n\t\t\t\t\t */\n\n\t\t\t\t\tif (!is_regexp) {\n\t\t\t\t\t\tgoto repl_write;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!(ch2 >= DUK_ASC_0 && ch2 <= DUK_ASC_9)) {\n\t\t\t\t\t\tgoto repl_write;\n\t\t\t\t\t}\n\t\t\t\t\tcapnum = ch2 - DUK_ASC_0;\n\t\t\t\t\tcapadv = 1;\n\n\t\t\t\t\tif (left >= 2) {\n\t\t\t\t\t\tch3 = r[1];\n\t\t\t\t\t\tif (ch3 >= DUK_ASC_0 && ch3 <= DUK_ASC_9) {\n\t\t\t\t\t\t\tcaptmp = capnum * 10 + (ch3 - DUK_ASC_0);\n\t\t\t\t\t\t\tif (captmp < match_caps) {\n\t\t\t\t\t\t\t\tcapnum = captmp;\n\t\t\t\t\t\t\t\tcapadv = 2;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (capnum > 0 && capnum < match_caps) {\n\t\t\t\t\t\tDUK_ASSERT(is_regexp != 0);  /* match_caps == 0 without regexps */\n\n\t\t\t\t\t\t/* regexp res_obj is at offset 4 */\n\t\t\t\t\t\tduk_get_prop_index(thr, 4, (duk_uarridx_t) capnum);\n\t\t\t\t\t\tif (duk_is_string(thr, -1)) {\n\t\t\t\t\t\t\tduk_hstring *h_tmp_str;\n\n\t\t\t\t\t\t\th_tmp_str = duk_known_hstring(thr, -1);\n\n\t\t\t\t\t\t\tDUK_BW_WRITE_ENSURE_HSTRING(thr, bw, h_tmp_str);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t/* undefined -> skip (replaced with empty) */\n\t\t\t\t\t\t}\n\t\t\t\t\t\tduk_pop(thr);\n\t\t\t\t\t\tr += capadv;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgoto repl_write;\n\t\t\t\t\t}\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t\t\tgoto repl_write;  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t\t}  /* default case */\n\t\t\t\t}  /* switch (ch2) */\n\n\t\t\t repl_write:\n\t\t\t\t/* ch1 = (r_increment << 8) + byte */\n\n\t\t\t\tDUK_BW_WRITE_ENSURE_U8(thr, bw, (duk_uint8_t) (ch1 & 0xff));\n\t\t\t\tr += ch1 >> 8;\n\t\t\t}  /* while repl */\n\t\t}  /* if (is_repl_func) */\n\n\t\tduk_pop(thr);  /* pop regexp res_obj or match string */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (!is_global) {\n#else\n\t\t{  /* unconditionally; is_global==0 */\n#endif\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* trailer */\n\ttmp_sz = (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - prev_match_end_boff);\n\tDUK_BW_WRITE_ENSURE_BYTES(thr, bw, DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff, tmp_sz);\n\n\tDUK_ASSERT_TOP(thr, 4);\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if inputs are safe. */\n\treturn 1;\n}\n\n/*\n *  split()\n */\n\n/* XXX: very messy now, but works; clean up, remove unused variables (nomimally\n * used so compiler doesn't complain).\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_split(duk_hthread *thr) {\n\tduk_hstring *h_input;\n\tduk_hstring *h_sep;\n\tduk_uint32_t limit;\n\tduk_uint32_t arr_idx;\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tduk_bool_t is_regexp;\n#endif\n\tduk_bool_t matched;  /* set to 1 if any match exists (needed for empty input special case) */\n\tduk_uint32_t prev_match_end_coff, prev_match_end_boff;\n\tduk_uint32_t match_start_boff, match_start_coff;\n\tduk_uint32_t match_end_boff, match_end_coff;\n\n\th_input = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_input != NULL);\n\n\tduk_push_array(thr);\n\n\tif (duk_is_undefined(thr, 1)) {\n\t\tlimit = 0xffffffffUL;\n\t} else {\n\t\tlimit = duk_to_uint32(thr, 1);\n\t}\n\n\tif (limit == 0) {\n\t\treturn 1;\n\t}\n\n\t/* If the separator is a RegExp, make a \"clone\" of it.  The specification\n\t * algorithm calls [[Match]] directly for specific indices; we emulate this\n\t * by tweaking lastIndex and using a \"force global\" variant of duk_regexp_match()\n\t * which will use global-style matching even when the RegExp itself is non-global.\n\t */\n\n\tif (duk_is_undefined(thr, 0)) {\n\t\t/* The spec algorithm first does \"R = ToString(separator)\" before checking\n\t\t * whether separator is undefined.  Since this is side effect free, we can\n\t\t * skip the ToString() here.\n\t\t */\n\t\tduk_dup_2(thr);\n\t\tduk_put_prop_index(thr, 3, 0);\n\t\treturn 1;\n\t} else if (duk_get_hobject_with_class(thr, 0, DUK_HOBJECT_CLASS_REGEXP) != NULL) {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tduk_push_hobject_bidx(thr, DUK_BIDX_REGEXP_CONSTRUCTOR);\n\t\tduk_dup_0(thr);\n\t\tduk_new(thr, 1);  /* [ ... RegExp val ] -> [ ... res ] */\n\t\tduk_replace(thr, 0);\n\t\t/* lastIndex is initialized to zero by new RegExp() */\n\t\tis_regexp = 1;\n#else\n\t\tDUK_DCERROR_UNSUPPORTED(thr);\n#endif\n\t} else {\n\t\tduk_to_string(thr, 0);\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tis_regexp = 0;\n#endif\n\t}\n\n\t/* stack[0] = separator (string or regexp)\n\t * stack[1] = limit\n\t * stack[2] = input string\n\t * stack[3] = result array\n\t */\n\n\tprev_match_end_boff = 0;\n\tprev_match_end_coff = 0;\n\tarr_idx = 0;\n\tmatched = 0;\n\n\tfor (;;) {\n\t\t/*\n\t\t *  The specification uses RegExp [[Match]] to attempt match at specific\n\t\t *  offsets.  We don't have such a primitive, so we use an actual RegExp\n\t\t *  and tweak lastIndex.  Since the RegExp may be non-global, we use a\n\t\t *  special variant which forces global-like behavior for matching.\n\t\t */\n\n\t\tDUK_ASSERT_TOP(thr, 4);\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (is_regexp) {\n\t\t\tduk_dup_0(thr);\n\t\t\tduk_dup_2(thr);\n\t\t\tduk_regexp_match_force_global(thr);  /* [ ... regexp input ] -> [ res_obj ] */\n\t\t\tif (!duk_is_object(thr, -1)) {\n\t\t\t\tduk_pop(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched = 1;\n\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX);\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tmatch_start_coff = duk_get_uint(thr, -1);\n\t\t\tmatch_start_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h_input, match_start_coff);\n\t\t\tduk_pop(thr);\n\n\t\t\tif (match_start_coff == DUK_HSTRING_GET_CHARLEN(h_input)) {\n\t\t\t\t/* don't allow an empty match at the end of the string */\n\t\t\t\tduk_pop(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tmatch_end_coff = duk_get_uint(thr, -1);\n\t\t\tmatch_end_boff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h_input, match_end_coff);\n\t\t\tduk_pop(thr);\n\n\t\t\t/* empty match -> bump and continue */\n\t\t\tif (prev_match_end_boff == match_end_boff) {\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) (match_end_coff + 1));\n\t\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t\t\tduk_pop(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\tconst duk_uint8_t *p_start, *p_end, *p;   /* input string scan */\n\t\t\tconst duk_uint8_t *q_start;               /* match string */\n\t\t\tduk_size_t q_blen, q_clen;\n\n\t\t\tp_start = DUK_HSTRING_GET_DATA(h_input);\n\t\t\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\t\t\tp = p_start + prev_match_end_boff;\n\n\t\t\th_sep = duk_known_hstring(thr, 0);  /* symbol already rejected above */\n\t\t\tq_start = DUK_HSTRING_GET_DATA(h_sep);\n\t\t\tq_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_sep);\n\t\t\tq_clen = (duk_size_t) DUK_HSTRING_GET_CHARLEN(h_sep);\n\n\t\t\tp_end -= q_blen;  /* ensure full memcmp() fits in while */\n\n\t\t\tmatch_start_coff = prev_match_end_coff;\n\n\t\t\tif (q_blen == 0) {\n\t\t\t\t/* Handle empty separator case: it will always match, and always\n\t\t\t\t * triggers the check in step 13.c.iii initially.  Note that we\n\t\t\t\t * must skip to either end of string or start of first codepoint,\n\t\t\t\t * skipping over any continuation bytes!\n\t\t\t\t *\n\t\t\t\t * Don't allow an empty string to match at the end of the input.\n\t\t\t\t */\n\n\t\t\t\tmatched = 1;  /* empty separator can always match */\n\n\t\t\t\tmatch_start_coff++;\n\t\t\t\tp++;\n\t\t\t\twhile (p < p_end) {\n\t\t\t\t\tif ((p[0] & 0xc0) != 0x80) {\n\t\t\t\t\t\tgoto found;\n\t\t\t\t\t}\n\t\t\t\t\tp++;\n\t\t\t\t}\n\t\t\t\tgoto not_found;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(q_blen > 0 && q_clen > 0);\n\t\t\twhile (p <= p_end) {\n\t\t\t\tDUK_ASSERT(p + q_blen <= DUK_HSTRING_GET_DATA(h_input) + DUK_HSTRING_GET_BYTELEN(h_input));\n\t\t\t\tDUK_ASSERT(q_blen > 0);  /* no issues with empty memcmp() */\n\t\t\t\tif (duk_memcmp((const void *) p, (const void *) q_start, (size_t) q_blen) == 0) {\n\t\t\t\t\t/* never an empty match, so step 13.c.iii can't be triggered */\n\t\t\t\t\tgoto found;\n\t\t\t\t}\n\n\t\t\t\t/* track utf-8 non-continuation bytes */\n\t\t\t\tif ((p[0] & 0xc0) != 0x80) {\n\t\t\t\t\tmatch_start_coff++;\n\t\t\t\t}\n\t\t\t\tp++;\n\t\t\t}\n\n\t\t not_found:\n\t\t\t/* not found */\n\t\t\tbreak;\n\n\t\t found:\n\t\t\tmatched = 1;\n\t\t\tmatch_start_boff = (duk_uint32_t) (p - p_start);\n\t\t\tmatch_end_coff = (duk_uint32_t) (match_start_coff + q_clen);  /* constrained by string length */\n\t\t\tmatch_end_boff = (duk_uint32_t) (match_start_boff + q_blen);  /* ditto */\n\n\t\t\t/* empty match (may happen with empty separator) -> bump and continue */\n\t\t\tif (prev_match_end_boff == match_end_boff) {\n\t\t\t\tprev_match_end_boff++;\n\t\t\t\tprev_match_end_coff++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}  /* if (is_regexp) */\n\n\t\t/* stack[0] = separator (string or regexp)\n\t\t * stack[1] = limit\n\t\t * stack[2] = input string\n\t\t * stack[3] = result array\n\t\t * stack[4] = regexp res_obj (if is_regexp)\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"split; match_start b=%ld,c=%ld, match_end b=%ld,c=%ld, prev_end b=%ld,c=%ld\",\n\t\t                     (long) match_start_boff, (long) match_start_coff,\n\t\t                     (long) match_end_boff, (long) match_end_coff,\n\t\t                     (long) prev_match_end_boff, (long) prev_match_end_coff));\n\n\t\tduk_push_lstring(thr,\n\t\t                 (const char *) (DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff),\n\t\t                 (duk_size_t) (match_start_boff - prev_match_end_boff));\n\t\tduk_put_prop_index(thr, 3, arr_idx);\n\t\tarr_idx++;\n\t\tif (arr_idx >= limit) {\n\t\t\tgoto hit_limit;\n\t\t}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tif (is_regexp) {\n\t\t\tduk_size_t i, len;\n\n\t\t\tlen = duk_get_length(thr, 4);\n\t\t\tfor (i = 1; i < len; i++) {\n\t\t\t\tDUK_ASSERT(i <= DUK_UARRIDX_MAX);  /* cannot have >4G captures */\n\t\t\t\tduk_get_prop_index(thr, 4, (duk_uarridx_t) i);\n\t\t\t\tduk_put_prop_index(thr, 3, arr_idx);\n\t\t\t\tarr_idx++;\n\t\t\t\tif (arr_idx >= limit) {\n\t\t\t\t\tgoto hit_limit;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_pop(thr);\n\t\t\t/* lastIndex already set up for next match */\n\t\t} else {\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t{  /* unconditionally */\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\t/* no action */\n\t\t}\n\n\t\tprev_match_end_boff = match_end_boff;\n\t\tprev_match_end_coff = match_end_coff;\n\t\tcontinue;\n\t}  /* for */\n\n\t/* Combined step 11 (empty string special case) and 14-15. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"split trailer; prev_end b=%ld,c=%ld\",\n\t                     (long) prev_match_end_boff, (long) prev_match_end_coff));\n\n\tif (DUK_HSTRING_GET_BYTELEN(h_input) > 0 || !matched) {\n\t\t/* Add trailer if:\n\t\t *   a) non-empty input\n\t\t *   b) empty input and no (zero size) match found (step 11)\n\t\t */\n\n\t\tduk_push_lstring(thr,\n\t\t                 (const char *) DUK_HSTRING_GET_DATA(h_input) + prev_match_end_boff,\n\t\t                 (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h_input) - prev_match_end_boff));\n\t\tduk_put_prop_index(thr, 3, arr_idx);\n\t\t/* No arr_idx update or limit check */\n\t}\n\n\treturn 1;\n\n hit_limit:\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\tif (is_regexp) {\n\t\tduk_pop(thr);\n\t}\n#endif\n\n\treturn 1;\n}\n\n/*\n *  Various\n */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_LOCAL void duk__to_regexp_helper(duk_hthread *thr, duk_idx_t idx, duk_bool_t force_new) {\n\tduk_hobject *h;\n\n\t/* Shared helper for match() steps 3-4, search() steps 3-4. */\n\n\tDUK_ASSERT(idx >= 0);\n\n\tif (force_new) {\n\t\tgoto do_new;\n\t}\n\n\th = duk_get_hobject_with_class(thr, idx, DUK_HOBJECT_CLASS_REGEXP);\n\tif (!h) {\n\t\tgoto do_new;\n\t}\n\treturn;\n\n do_new:\n\tduk_push_hobject_bidx(thr, DUK_BIDX_REGEXP_CONSTRUCTOR);\n\tduk_dup(thr, idx);\n\tduk_new(thr, 1);  /* [ ... RegExp val ] -> [ ... res ] */\n\tduk_replace(thr, idx);\n}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_search(duk_hthread *thr) {\n\t/* Easiest way to implement the search required by the specification\n\t * is to do a RegExp test() with lastIndex forced to zero.  To avoid\n\t * side effects on the argument, \"clone\" the RegExp if a RegExp was\n\t * given as input.\n\t *\n\t * The global flag of the RegExp should be ignored; setting lastIndex\n\t * to zero (which happens when \"cloning\" the RegExp) should have an\n\t * equivalent effect.\n\t */\n\n\tDUK_ASSERT_TOP(thr, 1);\n\t(void) duk_push_this_coercible_to_string(thr);  /* at index 1 */\n\tduk__to_regexp_helper(thr, 0 /*index*/, 1 /*force_new*/);\n\n\t/* stack[0] = regexp\n\t * stack[1] = string\n\t */\n\n\t/* Avoid using RegExp.prototype methods, as they're writable and\n\t * configurable and may have been changed.\n\t */\n\n\tduk_dup_0(thr);\n\tduk_dup_1(thr);  /* [ ... re_obj input ] */\n\tduk_regexp_match(thr);  /* -> [ ... res_obj ] */\n\n\tif (!duk_is_object(thr, -1)) {\n\t\tduk_push_int(thr, -1);\n\t\treturn 1;\n\t}\n\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INDEX);\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\treturn 1;\n}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_match(duk_hthread *thr) {\n\tduk_bool_t global;\n\tduk_int_t prev_last_index;\n\tduk_int_t this_index;\n\tduk_int_t arr_idx;\n\n\tDUK_ASSERT_TOP(thr, 1);\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk__to_regexp_helper(thr, 0 /*index*/, 0 /*force_new*/);\n\tglobal = duk_get_prop_stridx_boolean(thr, 0, DUK_STRIDX_GLOBAL, NULL);\n\tDUK_ASSERT_TOP(thr, 2);\n\n\t/* stack[0] = regexp\n\t * stack[1] = string\n\t */\n\n\tif (!global) {\n\t\tduk_regexp_match(thr);  /* -> [ res_obj ] */\n\t\treturn 1;  /* return 'res_obj' */\n\t}\n\n\t/* Global case is more complex. */\n\n\t/* [ regexp string ] */\n\n\tduk_push_int(thr, 0);\n\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\tduk_push_array(thr);\n\n\t/* [ regexp string res_arr ] */\n\n\tprev_last_index = 0;\n\tarr_idx = 0;\n\n\tfor (;;) {\n\t\tDUK_ASSERT_TOP(thr, 3);\n\n\t\tduk_dup_0(thr);\n\t\tduk_dup_1(thr);\n\t\tduk_regexp_match(thr);  /* -> [ ... regexp string ] -> [ ... res_obj ] */\n\n\t\tif (!duk_is_object(thr, -1)) {\n\t\t\tduk_pop(thr);\n\t\t\tbreak;\n\t\t}\n\n\t\tduk_get_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\tthis_index = duk_get_int(thr, -1);\n\t\tduk_pop(thr);\n\n\t\tif (this_index == prev_last_index) {\n\t\t\tthis_index++;\n\t\t\tduk_push_int(thr, this_index);\n\t\t\tduk_put_prop_stridx_short(thr, 0, DUK_STRIDX_LAST_INDEX);\n\t\t}\n\t\tprev_last_index = this_index;\n\n\t\tduk_get_prop_index(thr, -1, 0);  /* match string */\n\t\tduk_put_prop_index(thr, 2, (duk_uarridx_t) arr_idx);\n\t\tarr_idx++;\n\t\tduk_pop(thr);  /* res_obj */\n\t}\n\n\tif (arr_idx == 0) {\n\t\tduk_push_null(thr);\n\t}\n\n\treturn 1;  /* return 'res_arr' or 'null' */\n}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_concat(duk_hthread *thr) {\n\t/* duk_concat() coerces arguments with ToString() in correct order */\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk_insert(thr, 0);  /* this is relatively expensive */\n\tduk_concat(thr, duk_get_top(thr));\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_trim(duk_hthread *thr) {\n\tDUK_ASSERT_TOP(thr, 0);\n\t(void) duk_push_this_coercible_to_string(thr);\n\tduk_trim(thr, 0);\n\tDUK_ASSERT_TOP(thr, 1);\n\treturn 1;\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_repeat(duk_hthread *thr) {\n\tduk_hstring *h_input;\n\tduk_size_t input_blen;\n\tduk_size_t result_len;\n\tduk_int_t count_signed;\n\tduk_uint_t count;\n\tconst duk_uint8_t *src;\n\tduk_uint8_t *buf;\n\tduk_uint8_t *p;\n\tduk_double_t d;\n#if !defined(DUK_USE_PREFER_SIZE)\n\tduk_size_t copy_size;\n\tduk_uint8_t *p_end;\n#endif\n\n\tDUK_ASSERT_TOP(thr, 1);\n\th_input = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h_input != NULL);\n\tinput_blen = DUK_HSTRING_GET_BYTELEN(h_input);\n\n\t/* Count is ToNumber() coerced; +Infinity must be always rejected\n\t * (even if input string is zero length), as well as negative values\n\t * and -Infinity.  -Infinity doesn't require an explicit check\n\t * because duk_get_int() clamps it to DUK_INT_MIN which gets rejected\n\t * as a negative value (regardless of input string length).\n\t */\n\td = duk_to_number(thr, 0);\n\tif (duk_double_is_posinf(d)) {\n\t\tgoto fail_range;\n\t}\n\tcount_signed = duk_get_int(thr, 0);\n\tif (count_signed < 0) {\n\t\tgoto fail_range;\n\t}\n\tcount = (duk_uint_t) count_signed;\n\n\t/* Overflow check for result length. */\n\tresult_len = count * input_blen;\n\tif (count != 0 && result_len / count != input_blen) {\n\t\tgoto fail_range;\n\t}\n\n\t/* Temporary fixed buffer, later converted to string. */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer_nozero(thr, result_len);\n\tDUK_ASSERT(buf != NULL);\n\tsrc = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tDUK_ASSERT(src != NULL);\n\n#if defined(DUK_USE_PREFER_SIZE)\n\tp = buf;\n\twhile (count-- > 0) {\n\t\tduk_memcpy((void *) p, (const void *) src, input_blen);  /* copy size may be zero, but pointers are valid */\n\t\tp += input_blen;\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\t/* Take advantage of already copied pieces to speed up the process\n\t * especially for small repeated strings.\n\t */\n\tp = buf;\n\tp_end = p + result_len;\n\tcopy_size = input_blen;\n\tfor (;;) {\n\t\tduk_size_t remain = (duk_size_t) (p_end - p);\n\t\tDUK_DDD(DUK_DDDPRINT(\"remain=%ld, copy_size=%ld, input_blen=%ld, result_len=%ld\",\n\t\t                     (long) remain, (long) copy_size, (long) input_blen,\n\t\t                     (long) result_len));\n\t\tif (remain <= copy_size) {\n\t\t\t/* If result_len is zero, this case is taken and does\n\t\t\t * a zero size copy (with valid pointers).\n\t\t\t */\n\t\t\tduk_memcpy((void *) p, (const void *) src, remain);\n\t\t\tbreak;\n\t\t} else {\n\t\t\tduk_memcpy((void *) p, (const void *) src, copy_size);\n\t\t\tp += copy_size;\n\t\t}\n\n\t\tsrc = (const duk_uint8_t *) buf;  /* Use buf as source for larger copies. */\n\t\tcopy_size = (duk_size_t) (p - buf);\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n\t/* XXX: It would be useful to be able to create a duk_hstring with\n\t * a certain byte size whose data area wasn't initialized and which\n\t * wasn't in the string table yet.  This would allow a string to be\n\t * constructed directly without a buffer temporary and when it was\n\t * finished, it could be injected into the string table.  Currently\n\t * this isn't possible because duk_hstrings are only tracked by the\n\t * intern table (they are not in heap_allocated).\n\t */\n\n\tduk_buffer_to_string(thr, -1);  /* Safe if input is safe. */\n\treturn 1;\n\n fail_range:\n\tDUK_DCERROR_RANGE_INVALID_ARGS(thr);\n}\n#endif  /* DUK_USE_ES6 */\n\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_locale_compare(duk_hthread *thr) {\n\tduk_hstring *h1;\n\tduk_hstring *h2;\n\tduk_size_t h1_len, h2_len, prefix_len;\n\tduk_small_int_t ret = 0;\n\tduk_small_int_t rc;\n\n\t/* The current implementation of localeCompare() is simply a codepoint\n\t * by codepoint comparison, implemented with a simple string compare\n\t * because UTF-8 should preserve codepoint ordering (assuming valid\n\t * shortest UTF-8 encoding).\n\t *\n\t * The specification requires that the return value must be related\n\t * to the sort order: e.g. negative means that 'this' comes before\n\t * 'that' in sort order.  We assume an ascending sort order.\n\t */\n\n\t/* XXX: could share code with duk_js_ops.c, duk_js_compare_helper */\n\n\th1 = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h1 != NULL);\n\n\th2 = duk_to_hstring(thr, 0);\n\tDUK_ASSERT(h2 != NULL);\n\n\th1_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1);\n\th2_len = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2);\n\tprefix_len = (h1_len <= h2_len ? h1_len : h2_len);\n\n\trc = (duk_small_int_t) duk_memcmp((const void *) DUK_HSTRING_GET_DATA(h1),\n\t                                  (const void *) DUK_HSTRING_GET_DATA(h2),\n\t                                  (size_t) prefix_len);\n\n\tif (rc < 0) {\n\t\tret = -1;\n\t\tgoto done;\n\t} else if (rc > 0) {\n\t\tret = 1;\n\t\tgoto done;\n\t}\n\n\t/* prefix matches, lengths matter now */\n\tif (h1_len > h2_len) {\n\t\tret = 1;\n\t\tgoto done;\n\t} else if (h1_len == h2_len) {\n\t\tDUK_ASSERT(ret == 0);\n\t\tgoto done;\n\t}\n\tret = -1;\n\tgoto done;\n\n done:\n\tduk_push_int(thr, (duk_int_t) ret);\n\treturn 1;\n}\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_hthread *thr) {\n\tduk_int_t magic;\n\tduk_hstring *h;\n\tduk_hstring *h_search;\n\tduk_size_t blen_search;\n\tconst duk_uint8_t *p_cmp_start;\n\tduk_bool_t result;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\th_search = duk__str_tostring_notregexp(thr, 0);\n\tDUK_ASSERT(h_search != NULL);\n\n\tmagic = duk_get_current_magic(thr);\n\n\tp_cmp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tblen_search = DUK_HSTRING_GET_BYTELEN(h_search);\n\n\tif (duk_is_undefined(thr, 1)) {\n\t\tif (magic) {\n\t\t\tp_cmp_start = p_cmp_start + DUK_HSTRING_GET_BYTELEN(h) - blen_search;\n\t\t} else {\n\t\t\t/* p_cmp_start already OK */\n\t\t}\n\t} else {\n\t\tduk_int_t len;\n\t\tduk_int_t pos;\n\n\t\tDUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= DUK_INT_MAX);\n\t\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\t\tpos = duk_to_int_clamped(thr, 1, 0, len);\n\t\tDUK_ASSERT(pos >= 0 && pos <= len);\n\n\t\tif (magic) {\n\t\t\tp_cmp_start -= blen_search;  /* Conceptually subtracted last, but do already here. */\n\t\t}\n\t\tDUK_ASSERT(pos >= 0 && pos <= len);\n\n\t\tp_cmp_start += duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) pos);\n\t}\n\n\t/* The main comparison can be done using a memcmp() rather than\n\t * doing codepoint comparisons: for CESU-8 strings there is a\n\t * canonical representation for every codepoint.  But we do need\n\t * to deal with the char/byte offset translation to find the\n\t * comparison range.\n\t */\n\n\tresult = 0;\n\tif (p_cmp_start >= DUK_HSTRING_GET_DATA(h) &&\n\t    (duk_size_t) (p_cmp_start - (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h)) + blen_search <= DUK_HSTRING_GET_BYTELEN(h)) {\n\t\tif (duk_memcmp((const void *) p_cmp_start,\n\t\t               (const void *) DUK_HSTRING_GET_DATA(h_search),\n\t\t               (size_t) blen_search) == 0) {\n\t\t\tresult = 1;\n\t\t}\n\t}\n\n\tduk_push_boolean(thr, result);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n\n#if defined(DUK_USE_ES6)\nDUK_INTERNAL duk_ret_t duk_bi_string_prototype_includes(duk_hthread *thr) {\n\tduk_hstring *h;\n\tduk_hstring *h_search;\n\tduk_int_t len;\n\tduk_int_t pos;\n\n\th = duk_push_this_coercible_to_string(thr);\n\tDUK_ASSERT(h != NULL);\n\n\th_search = duk__str_tostring_notregexp(thr, 0);\n\tDUK_ASSERT(h_search != NULL);\n\n\tlen = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h);\n\tpos = duk_to_int_clamped(thr, 1, 0, len);\n\tDUK_ASSERT(pos >= 0 && pos <= len);\n\n\tpos = duk__str_search_shared(thr, h, h_search, pos, 0 /*backwards*/);\n\tduk_push_boolean(thr, pos >= 0);\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6 */\n#endif  /* DUK_USE_STRING_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_symbol.c",
    "content": "/*\n *  Symbol built-in\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\n/*\n *  Constructor\n */\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_constructor_shared(duk_hthread *thr) {\n\tconst duk_uint8_t *desc;\n\tduk_size_t len;\n\tduk_uint8_t *buf;\n\tduk_uint8_t *p;\n\tduk_int_t magic;\n\n\tmagic = duk_get_current_magic(thr);\n\tif (duk_is_undefined(thr, 0) && (magic == 0)) {\n\t\t/* Symbol() accepts undefined and empty string, but they are\n\t\t * treated differently.\n\t\t */\n\t\tdesc = NULL;\n\t\tlen = 0;\n\t} else {\n\t\t/* Symbol.for() coerces undefined to 'undefined' */\n\t\tdesc = (const duk_uint8_t *) duk_to_lstring(thr, 0, &len);\n\t}\n\n\t/* Maximum symbol data length:\n\t *   +1    initial byte (0x80 or 0x81)\n\t *   +len  description\n\t *   +1    0xff after description, before unique suffix\n\t *   +17   autogenerated unique suffix: 'ffffffff-ffffffff' is longest\n\t *   +1    0xff after unique suffix for symbols with undefined description\n\t */\n\tbuf = (duk_uint8_t *) duk_push_fixed_buffer(thr, 1 + len + 1 + 17 + 1);\n\tDUK_ASSERT(buf != NULL);\n\tp = buf + 1;\n\tDUK_ASSERT(desc != NULL || len == 0);  /* may be NULL if len is 0 */\n\tduk_memcpy_unsafe((void *) p, (const void *) desc, len);\n\tp += len;\n\tif (magic == 0) {\n\t\t/* Symbol(): create unique symbol.  Use two 32-bit values\n\t\t * to avoid dependency on 64-bit types and 64-bit integer\n\t\t * formatting (at least for now).\n\t\t */\n\t\tif (++thr->heap->sym_counter[0] == 0) {\n\t\t\tthr->heap->sym_counter[1]++;\n\t\t}\n\t\tp += DUK_SPRINTF((char *) p, \"\\xFF\" \"%lx-%lx\",\n\t\t                 (unsigned long) thr->heap->sym_counter[1],\n\t\t                 (unsigned long) thr->heap->sym_counter[0]);\n\t\tif (desc == NULL) {\n\t\t\t/* Special case for 'undefined' description, trailing\n\t\t\t * 0xff distinguishes from empty string description,\n\t\t\t * but needs minimal special case handling elsewhere.\n\t\t\t */\n\t\t\t*p++ = 0xff;\n\t\t}\n\t\tbuf[0] = 0x81;\n\t} else {\n\t\t/* Symbol.for(): create a global symbol */\n\t\tbuf[0] = 0x80;\n\t}\n\n\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) (p - buf));\n\tDUK_DDD(DUK_DDDPRINT(\"created symbol: %!T\", duk_get_tval(thr, -1)));\n\treturn 1;\n}\n\nDUK_LOCAL duk_hstring *duk__auto_unbox_symbol(duk_hthread *thr, duk_tval *tv_arg) {\n\tduk_tval *tv;\n\tduk_hobject *h_obj;\n\tduk_hstring *h_str;\n\n\tDUK_ASSERT(tv_arg != NULL);\n\n\t/* XXX: add internal helper: duk_auto_unbox_tval(thr, tv, mask); */\n\t/* XXX: add internal helper: duk_auto_unbox(thr, tv, idx); */\n\n\ttv = tv_arg;\n\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\th_obj = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h_obj != NULL);\n\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(h_obj) == DUK_HOBJECT_CLASS_SYMBOL) {\n\t\t\ttv = duk_hobject_get_internal_value_tval_ptr(thr->heap, h_obj);\n\t\t\tif (tv == NULL) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t} else {\n\t\t\treturn NULL;\n\t\t}\n\t}\n\n\tif (!DUK_TVAL_IS_STRING(tv)) {\n\t\treturn NULL;\n\t}\n\th_str = DUK_TVAL_GET_STRING(tv);\n\tDUK_ASSERT(h_str != NULL);\n\n\t/* Here symbol is more expected than not. */\n\tif (DUK_UNLIKELY(!DUK_HSTRING_HAS_SYMBOL(h_str))) {\n\t\treturn NULL;\n\t}\n\n\treturn h_str;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_tostring_shared(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\th_str = duk__auto_unbox_symbol(thr, DUK_HTHREAD_THIS_PTR(thr));\n\tif (h_str == NULL) {\n\t\treturn DUK_RET_TYPE_ERROR;\n\t}\n\n\tif (duk_get_current_magic(thr) == 0) {\n\t\t/* .toString() */\n\t\tduk_push_symbol_descriptive_string(thr, h_str);\n\t} else {\n\t\t/* .valueOf() */\n\t\tduk_push_hstring(thr, h_str);\n\t}\n\treturn 1;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_key_for(duk_hthread *thr) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p;\n\n\t/* Argument must be a symbol but not checked here.  The initial byte\n\t * check will catch non-symbol strings.\n\t */\n\th = duk_require_hstring(thr, 0);\n\tDUK_ASSERT(h != NULL);\n\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tDUK_ASSERT(p != NULL);\n\n\t/* Even for zero length strings there's at least one NUL byte so\n\t * we can safely check the initial byte.\n\t */\n\tif (p[0] == 0x80) {\n\t\t/* Global symbol, return its key (bytes just after the initial byte). */\n\t\tduk_push_lstring(thr, (const char *) (p + 1), (duk_size_t) (DUK_HSTRING_GET_BYTELEN(h) - 1));\n\t\treturn 1;\n\t} else if (p[0] == 0x81 || p[0] == 0x82 || p[0] == 0xff) {\n\t\t/* Local symbol or hidden symbol, return undefined. */\n\t\treturn 0;\n\t}\n\n\t/* Covers normal strings and unknown initial bytes. */\n\treturn DUK_RET_TYPE_ERROR;\n}\n\nDUK_INTERNAL duk_ret_t duk_bi_symbol_toprimitive(duk_hthread *thr) {\n\tduk_hstring *h_str;\n\n\th_str = duk__auto_unbox_symbol(thr, DUK_HTHREAD_THIS_PTR(thr));\n\tif (h_str == NULL) {\n\t\treturn DUK_RET_TYPE_ERROR;\n\t}\n\tduk_push_hstring(thr, h_str);\n\treturn 1;\n}\n\n#endif  /* DUK_USE_SYMBOL_BUILTIN */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_thread.c",
    "content": "/*\n *  Thread builtins\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Constructor\n */\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_constructor(duk_hthread *thr) {\n\tduk_hthread *new_thr;\n\tduk_hobject *func;\n\n\t/* Check that the argument is callable; this is not 100% because we\n\t * don't allow native functions to be a thread's initial function.\n\t * Resume will reject such functions in any case.\n\t */\n\t/* XXX: need a duk_require_func_promote_lfunc() */\n\tfunc = duk_require_hobject_promote_lfunc(thr, 0);\n\tDUK_ASSERT(func != NULL);\n\tduk_require_callable(thr, 0);\n\n\tduk_push_thread(thr);\n\tnew_thr = (duk_hthread *) duk_known_hobject(thr, -1);\n\tnew_thr->state = DUK_HTHREAD_STATE_INACTIVE;\n\n\t/* push initial function call to new thread stack; this is\n\t * picked up by resume().\n\t */\n\tduk_push_hobject(new_thr, func);\n\n\treturn 1;  /* return thread */\n}\n#endif\n\n/*\n *  Resume a thread.\n *\n *  The thread must be in resumable state, either (a) new thread which hasn't\n *  yet started, or (b) a thread which has previously yielded.  This method\n *  must be called from an ECMAScript function.\n *\n *  Args:\n *    - thread\n *    - value\n *    - isError (defaults to false)\n *\n *  Note: yield and resume handling is currently asymmetric.\n */\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_resume(duk_hthread *ctx) {\n\tduk_hthread *thr = (duk_hthread *) ctx;\n\tduk_hthread *thr_resume;\n\tduk_hobject *caller_func;\n\tduk_small_uint_t is_error;\n\n\tDUK_DDD(DUK_DDDPRINT(\"Duktape.Thread.resume(): thread=%!T, value=%!T, is_error=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1),\n\t                     (duk_tval *) duk_get_tval(thr, 2)));\n\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\tDUK_ASSERT(thr->heap->curr_thread == thr);\n\n\tthr_resume = duk_require_hthread(thr, 0);\n\tDUK_ASSERT(duk_get_top(thr) == 3);\n\tis_error = (duk_small_uint_t) duk_to_boolean_top_pop(thr);\n\tDUK_ASSERT(duk_get_top(thr) == 2);\n\n\t/* [ thread value ] */\n\n\t/*\n\t *  Thread state and calling context checks\n\t */\n\n\tif (thr->callstack_top < 2) {\n\t\tDUK_DD(DUK_DDPRINT(\"resume state invalid: callstack should contain at least 2 entries (caller and Duktape.Thread.resume)\"));\n\t\tgoto state_error;\n\t}\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);  /* us */\n\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL);  /* caller */\n\n\tcaller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent);\n\tif (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) {\n\t\tDUK_DD(DUK_DDPRINT(\"resume state invalid: caller must be ECMAScript code\"));\n\t\tgoto state_error;\n\t}\n\n\t/* Note: there is no requirement that: 'thr->callstack_preventcount == 1'\n\t * like for yield.\n\t */\n\n\tif (thr_resume->state != DUK_HTHREAD_STATE_INACTIVE &&\n\t    thr_resume->state != DUK_HTHREAD_STATE_YIELDED) {\n\t\tDUK_DD(DUK_DDPRINT(\"resume state invalid: target thread must be INACTIVE or YIELDED\"));\n\t\tgoto state_error;\n\t}\n\n\tDUK_ASSERT(thr_resume->state == DUK_HTHREAD_STATE_INACTIVE ||\n\t           thr_resume->state == DUK_HTHREAD_STATE_YIELDED);\n\n\t/* Further state-dependent pre-checks */\n\n\tif (thr_resume->state == DUK_HTHREAD_STATE_YIELDED) {\n\t\t/* no pre-checks now, assume a previous yield() has left things in\n\t\t * tip-top shape (longjmp handler will assert for these).\n\t\t */\n\t} else {\n\t\tduk_hobject *h_fun;\n\n\t\tDUK_ASSERT(thr_resume->state == DUK_HTHREAD_STATE_INACTIVE);\n\n\t\t/* The initial function must be an ECMAScript function (but\n\t\t * can be bound).  We must make sure of that before we longjmp\n\t\t * because an error in the RESUME handler call processing will\n\t\t * not be handled very cleanly.\n\t\t */\n\t\tif ((thr_resume->callstack_top != 0) ||\n\t\t    (thr_resume->valstack_top - thr_resume->valstack != 1)) {\n\t\t\tgoto state_error;\n\t\t}\n\n\t\tduk_push_tval(thr, DUK_GET_TVAL_NEGIDX(thr_resume, -1));\n\t\tduk_resolve_nonbound_function(thr);\n\t\th_fun = duk_require_hobject(thr, -1);  /* reject lightfuncs on purpose */\n\t\tif (!DUK_HOBJECT_IS_CALLABLE(h_fun) || !DUK_HOBJECT_IS_COMPFUNC(h_fun)) {\n\t\t\tgoto state_error;\n\t\t}\n\t\tduk_pop(thr);\n\t}\n\n#if 0\n\t/* This check would prevent a heap destruction time finalizer from\n\t * launching a coroutine, which would ensure that during finalization\n\t * 'thr' would always equal heap_thread.  Normal runtime finalizers\n\t * run with ms_running == 0, i.e. outside mark-and-sweep.  See GH-2030.\n\t */\n\tif (thr->heap->ms_running) {\n\t\tDUK_D(DUK_DPRINT(\"refuse Duktape.Thread.resume() when ms_running != 0\"));\n\t\tgoto state_error;\n\t}\n#endif\n\n\t/*\n\t *  The error object has been augmented with a traceback and other\n\t *  info from its creation point -- usually another thread.  The\n\t *  error handler is called here right before throwing, but it also\n\t *  runs in the resumer's thread.  It might be nice to get a traceback\n\t *  from the resumee but this is not the case now.\n\t */\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\tif (is_error) {\n\t\tDUK_ASSERT_TOP(thr, 2);  /* value (error) is at stack top */\n\t\tduk_err_augment_error_throw(thr);  /* in resumer's context */\n\t}\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\tif (is_error) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"RESUME ERROR: thread=%!T, value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\t} else if (thr_resume->state == DUK_HTHREAD_STATE_YIELDED) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"RESUME NORMAL: thread=%!T, value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"RESUME INITIAL: thread=%!T, value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\t}\n#endif\n\n\tthr->heap->lj.type = DUK_LJ_TYPE_RESUME;\n\n\t/* lj value2: thread */\n\tDUK_ASSERT(thr->valstack_bottom < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value2, &thr->valstack_bottom[0]);  /* side effects */\n\n\t/* lj value1: value */\n\tDUK_ASSERT(thr->valstack_bottom + 1 < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, &thr->valstack_bottom[1]);  /* side effects */\n\tDUK_TVAL_CHKFAST_INPLACE_SLOW(&thr->heap->lj.value1);\n\n\tthr->heap->lj.iserror = is_error;\n\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* call is from executor, so we know we have a jmpbuf */\n\tduk_err_longjmp(thr);  /* execution resumes in bytecode executor */\n\tDUK_UNREACHABLE();\n\t/* Never here, fall through to error (from compiler point of view). */\n\n state_error:\n\tDUK_DCERROR_TYPE_INVALID_STATE(thr);\n}\n#endif\n\n/*\n *  Yield the current thread.\n *\n *  The thread must be in yieldable state: it must have a resumer, and there\n *  must not be any yield-preventing calls (native calls and constructor calls,\n *  currently) in the thread's call stack (otherwise a resume would not be\n *  possible later).  This method must be called from an ECMAScript function.\n *\n *  Args:\n *    - value\n *    - isError (defaults to false)\n *\n *  Note: yield and resume handling is currently asymmetric.\n */\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_yield(duk_hthread *thr) {\n\tduk_hobject *caller_func;\n\tduk_small_uint_t is_error;\n\n\tDUK_DDD(DUK_DDDPRINT(\"Duktape.Thread.yield(): value=%!T, is_error=%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, 0),\n\t                     (duk_tval *) duk_get_tval(thr, 1)));\n\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\tDUK_ASSERT(thr->heap->curr_thread == thr);\n\n\tDUK_ASSERT(duk_get_top(thr) == 2);\n\tis_error = (duk_small_uint_t) duk_to_boolean_top_pop(thr);\n\tDUK_ASSERT(duk_get_top(thr) == 1);\n\n\t/* [ value ] */\n\n\t/*\n\t *  Thread state and calling context checks\n\t */\n\n\tif (!thr->resumer) {\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: current thread must have a resumer\"));\n\t\tgoto state_error;\n\t}\n\tDUK_ASSERT(thr->resumer->state == DUK_HTHREAD_STATE_RESUMED);\n\n\tif (thr->callstack_top < 2) {\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: callstack should contain at least 2 entries (caller and Duktape.Thread.yield)\"));\n\t\tgoto state_error;\n\t}\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);  /* us */\n\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL);  /* caller */\n\n\tcaller_func = DUK_ACT_GET_FUNC(thr->callstack_curr->parent);\n\tif (!DUK_HOBJECT_IS_COMPFUNC(caller_func)) {\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: caller must be ECMAScript code\"));\n\t\tgoto state_error;\n\t}\n\n\tDUK_ASSERT(thr->callstack_preventcount >= 1);  /* should never be zero, because we (Duktape.Thread.yield) are on the stack */\n\tif (thr->callstack_preventcount != 1) {\n\t\t/* Note: the only yield-preventing call is Duktape.Thread.yield(), hence check for 1, not 0 */\n\t\tDUK_DD(DUK_DDPRINT(\"yield state invalid: there must be no yield-preventing calls in current thread callstack (preventcount is %ld)\",\n\t\t                   (long) thr->callstack_preventcount));\n\t\tgoto state_error;\n\t}\n\n\t/*\n\t *  The error object has been augmented with a traceback and other\n\t *  info from its creation point -- usually the current thread.\n\t *  The error handler, however, is called right before throwing\n\t *  and runs in the yielder's thread.\n\t */\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\tif (is_error) {\n\t\tDUK_ASSERT_TOP(thr, 1);  /* value (error) is at stack top */\n\t\tduk_err_augment_error_throw(thr);  /* in yielder's context */\n\t}\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\tif (is_error) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"YIELD ERROR: value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0)));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"YIELD NORMAL: value=%!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, 0)));\n\t}\n#endif\n\n\t/*\n\t *  Process yield\n\t *\n\t *  After longjmp(), processing continues in bytecode executor longjmp\n\t *  handler, which will e.g. update thr->resumer to NULL.\n\t */\n\n\tthr->heap->lj.type = DUK_LJ_TYPE_YIELD;\n\n\t/* lj value1: value */\n\tDUK_ASSERT(thr->valstack_bottom < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, &thr->heap->lj.value1, &thr->valstack_bottom[0]);  /* side effects */\n\tDUK_TVAL_CHKFAST_INPLACE_SLOW(&thr->heap->lj.value1);\n\n\tthr->heap->lj.iserror = is_error;\n\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* call is from executor, so we know we have a jmpbuf */\n\tduk_err_longjmp(thr);  /* execution resumes in bytecode executor */\n\tDUK_UNREACHABLE();\n\t/* Never here, fall through to error (from compiler point of view). */\n\n state_error:\n\tDUK_DCERROR_TYPE_INVALID_STATE(thr);\n}\n#endif\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_INTERNAL duk_ret_t duk_bi_thread_current(duk_hthread *thr) {\n\tduk_push_current_thread(thr);\n\treturn 1;\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_bi_thrower.c",
    "content": "/*\n *  Type error thrower, E5 Section 13.2.3.\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL duk_ret_t duk_bi_type_error_thrower(duk_hthread *thr) {\n\tDUK_DCERROR_TYPE_INVALID_ARGS(thr);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_builtins.c",
    "content": "/*\n *  Automatically generated by genbuiltins.py, do not edit!\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_ASSERTIONS)\n#define DUK__REFCINIT(refc) 0 /*h_assert_refcount*/, (refc) /*actual*/\n#else\n#define DUK__REFCINIT(refc) (refc) /*actual*/\n#endif\n\n#if defined(DUK_USE_ROM_STRINGS)\n#error ROM support not enabled, rerun configure.py with --rom-support\n#else  /* DUK_USE_ROM_STRINGS */\nDUK_INTERNAL const duk_uint8_t duk_strings_data[967] = {\n79,40,209,144,168,105,6,78,54,139,89,185,44,48,46,90,120,8,154,140,35,103,\n35,113,193,73,5,52,112,180,104,166,135,52,188,4,98,12,27,146,156,80,211,31,\n129,115,150,64,52,220,109,24,18,68,156,24,38,67,114,36,55,9,119,151,132,\n140,93,18,113,128,153,201,212,201,205,2,248,8,196,24,224,104,82,146,40,224,\n193,48,114,168,37,147,196,54,123,28,4,98,12,43,148,67,103,177,192,70,32,\n196,121,68,54,123,28,18,192,199,144,124,4,98,12,43,136,108,244,117,184,8,\n196,24,95,40,134,207,71,91,128,140,65,133,113,13,158,158,151,1,24,131,11,\n229,16,217,233,233,112,17,136,48,206,21,110,4,244,244,184,8,196,24,103,10,\n183,2,122,218,156,4,98,12,24,203,112,64,179,113,193,79,8,218,155,131,32,\n184,70,212,220,13,10,82,68,252,123,144,217,146,38,228,207,18,0,100,37,64,\n178,212,11,161,17,104,162,96,10,200,193,57,165,65,169,16,5,100,81,27,70,18,\n32,10,200,68,185,13,116,221,197,184,64,89,57,41,197,13,49,234,5,208,156,\n113,87,55,118,147,20,187,56,161,166,92,221,212,73,210,236,226,134,153,115,\n119,76,201,203,179,138,26,99,73,212,136,136,164,25,174,137,56,32,72,137,\n101,23,52,45,13,34,86,9,79,136,104,201,114,149,96,52,138,134,140,151,75,\n226,233,186,120,121,22,39,54,83,141,5,55,68,236,36,164,3,16,225,115,150,64,\n52,205,163,2,72,154,83,138,26,99,75,12,11,150,103,5,36,20,211,70,140,133,\n67,72,49,241,160,227,81,196,52,168,106,39,132,252,183,136,105,80,212,79,2,\n249,110,128,126,88,95,133,109,237,237,237,151,235,127,46,249,119,203,190,\n186,206,33,181,2,208,61,190,12,19,34,65,19,81,132,108,228,97,1,107,33,12,\n32,45,100,137,64,247,175,9,19,155,41,198,130,155,134,69,146,100,227,226,\n231,146,51,192,204,73,140,224,145,221,102,241,68,196,169,248,30,75,12,11,\n151,242,233,187,143,138,24,137,162,164,255,253,63,3,201,97,129,114,254,92,\n112,75,136,108,166,6,136,159,255,167,224,121,44,48,46,95,203,166,238,74,\n113,67,77,201,128,223,255,223,224,121,44,48,46,95,203,145,46,9,205,16,39,\n201,62,36,0,192,21,147,255,238,145,39,199,197,211,116,240,242,113,197,78,\n214,211,226,233,187,107,105,19,119,37,56,161,166,52,221,212,201,205,36,240,\n242,16,96,152,12,178,52,211,56,228,73,150,83,0,148,39,137,75,67,73,198,209,\n129,36,85,185,201,196,2,32,193,48,17,160,97,16,84,44,156,104,24,67,189,200,\n108,201,19,238,114,96,137,137,50,238,113,164,188,211,185,192,226,100,19,\n134,68,110,112,174,139,0,185,31,115,149,4,88,7,159,115,146,117,34,34,35,\n115,143,22,146,208,210,19,115,140,3,207,185,202,130,36,109,85,185,194,161,\n160,90,50,72,155,115,149,2,232,67,137,204,122,22,66,161,175,164,210,72,199,\n130,137,1,50,32,145,143,38,120,186,195,35,106,51,146,230,8,36,77,109,65,38,\n226,72,159,191,189,181,70,140,133,222,249,212,227,66,125,245,187,251,219,\n77,3,119,190,117,56,208,159,125,110,254,246,210,26,93,239,157,78,52,39,223,\n93,191,189,180,212,52,187,223,58,156,104,79,190,187,127,123,104,180,104,\n183,190,117,56,208,159,125,102,254,209,104,209,124,234,113,161,62,250,80,\n196,128,81,4,9,16,162,4,196,116,9,205,154,27,66,32,100,13,12,98,68,227,33,\n65,69,204,195,34,201,50,8,110,33,23,34,28,168,104,22,188,12,174,138,11,70,\n138,104,115,68,130,137,13,82,27,41,129,162,35,138,54,146,198,137,39,72,180,\n210,178,38,35,146,103,68,139,51,197,214,28,227,131,79,15,35,138,58,130,37,\n19,155,41,146,174,64,203,99,161,100,37,145,51,148,75,4,164,66,54,140,49,46,\n247,70,103,37,230,70,142,70,67,30,232,204,178,163,201,18,54,139,89,39,26,\n16,165,2,228,69,33,143,89,24,70,206,73,67,102,72,148,2,32,214,73,157,224,\n18,128,98,29,241,69,65,50,37,241,116,200,41,144,102,125,2,180,8,210,152,38,\n129,23,8,34,198,\n};\n#endif  /* DUK_USE_ROM_STRINGS */\n\n#if defined(DUK_USE_ROM_OBJECTS)\n#error ROM support not enabled, rerun configure.py with --rom-support\n#else  /* DUK_USE_ROM_OBJECTS */\n/* native functions: 183 */\nDUK_INTERNAL const duk_c_function duk_bi_native_functions[183] = {\n\tNULL,\n\tduk_bi_array_constructor,\n\tduk_bi_array_constructor_is_array,\n\tduk_bi_array_prototype_concat,\n\tduk_bi_array_prototype_indexof_shared,\n\tduk_bi_array_prototype_iter_shared,\n\tduk_bi_array_prototype_join_shared,\n\tduk_bi_array_prototype_pop,\n\tduk_bi_array_prototype_push,\n\tduk_bi_array_prototype_reduce_shared,\n\tduk_bi_array_prototype_reverse,\n\tduk_bi_array_prototype_shift,\n\tduk_bi_array_prototype_slice,\n\tduk_bi_array_prototype_sort,\n\tduk_bi_array_prototype_splice,\n\tduk_bi_array_prototype_to_string,\n\tduk_bi_array_prototype_unshift,\n\tduk_bi_arraybuffer_constructor,\n\tduk_bi_arraybuffer_isview,\n\tduk_bi_boolean_constructor,\n\tduk_bi_boolean_prototype_tostring_shared,\n\tduk_bi_buffer_compare_shared,\n\tduk_bi_buffer_readfield,\n\tduk_bi_buffer_slice_shared,\n\tduk_bi_buffer_writefield,\n\tduk_bi_dataview_constructor,\n\tduk_bi_date_constructor,\n\tduk_bi_date_constructor_now,\n\tduk_bi_date_constructor_parse,\n\tduk_bi_date_constructor_utc,\n\tduk_bi_date_prototype_get_shared,\n\tduk_bi_date_prototype_get_timezone_offset,\n\tduk_bi_date_prototype_set_shared,\n\tduk_bi_date_prototype_set_time,\n\tduk_bi_date_prototype_to_json,\n\tduk_bi_date_prototype_toprimitive,\n\tduk_bi_date_prototype_tostring_shared,\n\tduk_bi_date_prototype_value_of,\n\tduk_bi_duktape_object_act,\n\tduk_bi_duktape_object_compact,\n\tduk_bi_duktape_object_dec,\n\tduk_bi_duktape_object_enc,\n\tduk_bi_duktape_object_fin,\n\tduk_bi_duktape_object_gc,\n\tduk_bi_duktape_object_info,\n\tduk_bi_error_constructor_shared,\n\tduk_bi_error_prototype_filename_getter,\n\tduk_bi_error_prototype_filename_setter,\n\tduk_bi_error_prototype_linenumber_getter,\n\tduk_bi_error_prototype_linenumber_setter,\n\tduk_bi_error_prototype_stack_getter,\n\tduk_bi_error_prototype_stack_setter,\n\tduk_bi_error_prototype_to_string,\n\tduk_bi_function_constructor,\n\tduk_bi_function_prototype,\n\tduk_bi_function_prototype_apply,\n\tduk_bi_function_prototype_bind,\n\tduk_bi_function_prototype_call,\n\tduk_bi_function_prototype_hasinstance,\n\tduk_bi_function_prototype_to_string,\n\tduk_bi_global_object_decode_uri,\n\tduk_bi_global_object_decode_uri_component,\n\tduk_bi_global_object_encode_uri,\n\tduk_bi_global_object_encode_uri_component,\n\tduk_bi_global_object_escape,\n\tduk_bi_global_object_eval,\n\tduk_bi_global_object_is_finite,\n\tduk_bi_global_object_is_nan,\n\tduk_bi_global_object_parse_float,\n\tduk_bi_global_object_parse_int,\n\tduk_bi_global_object_unescape,\n\tduk_bi_json_object_parse,\n\tduk_bi_json_object_stringify,\n\tduk_bi_math_object_clz32,\n\tduk_bi_math_object_hypot,\n\tduk_bi_math_object_imul,\n\tduk_bi_math_object_max,\n\tduk_bi_math_object_min,\n\tduk_bi_math_object_onearg_shared,\n\tduk_bi_math_object_random,\n\tduk_bi_math_object_sign,\n\tduk_bi_math_object_twoarg_shared,\n\tduk_bi_native_function_length,\n\tduk_bi_native_function_name,\n\tduk_bi_nodejs_buffer_byte_length,\n\tduk_bi_nodejs_buffer_concat,\n\tduk_bi_nodejs_buffer_constructor,\n\tduk_bi_nodejs_buffer_copy,\n\tduk_bi_nodejs_buffer_fill,\n\tduk_bi_nodejs_buffer_is_buffer,\n\tduk_bi_nodejs_buffer_is_encoding,\n\tduk_bi_nodejs_buffer_tojson,\n\tduk_bi_nodejs_buffer_tostring,\n\tduk_bi_nodejs_buffer_write,\n\tduk_bi_number_check_shared,\n\tduk_bi_number_constructor,\n\tduk_bi_number_prototype_to_exponential,\n\tduk_bi_number_prototype_to_fixed,\n\tduk_bi_number_prototype_to_locale_string,\n\tduk_bi_number_prototype_to_precision,\n\tduk_bi_number_prototype_to_string,\n\tduk_bi_number_prototype_value_of,\n\tduk_bi_object_constructor,\n\tduk_bi_object_constructor_assign,\n\tduk_bi_object_constructor_create,\n\tduk_bi_object_constructor_define_properties,\n\tduk_bi_object_constructor_define_property,\n\tduk_bi_object_constructor_get_own_property_descriptor,\n\tduk_bi_object_constructor_is,\n\tduk_bi_object_constructor_is_extensible,\n\tduk_bi_object_constructor_is_sealed_frozen_shared,\n\tduk_bi_object_constructor_keys_shared,\n\tduk_bi_object_constructor_prevent_extensions,\n\tduk_bi_object_constructor_seal_freeze_shared,\n\tduk_bi_object_getprototype_shared,\n\tduk_bi_object_prototype_defineaccessor,\n\tduk_bi_object_prototype_has_own_property,\n\tduk_bi_object_prototype_is_prototype_of,\n\tduk_bi_object_prototype_lookupaccessor,\n\tduk_bi_object_prototype_property_is_enumerable,\n\tduk_bi_object_prototype_to_locale_string,\n\tduk_bi_object_prototype_to_string,\n\tduk_bi_object_prototype_value_of,\n\tduk_bi_object_setprototype_shared,\n\tduk_bi_performance_now,\n\tduk_bi_pointer_constructor,\n\tduk_bi_pointer_prototype_tostring_shared,\n\tduk_bi_proxy_constructor,\n\tduk_bi_reflect_apply,\n\tduk_bi_reflect_construct,\n\tduk_bi_reflect_object_delete_property,\n\tduk_bi_reflect_object_get,\n\tduk_bi_reflect_object_has,\n\tduk_bi_reflect_object_set,\n\tduk_bi_regexp_constructor,\n\tduk_bi_regexp_prototype_exec,\n\tduk_bi_regexp_prototype_flags,\n\tduk_bi_regexp_prototype_shared_getter,\n\tduk_bi_regexp_prototype_test,\n\tduk_bi_regexp_prototype_tostring,\n\tduk_bi_string_constructor,\n\tduk_bi_string_constructor_from_char_code,\n\tduk_bi_string_constructor_from_code_point,\n\tduk_bi_string_prototype_caseconv_shared,\n\tduk_bi_string_prototype_char_at,\n\tduk_bi_string_prototype_char_code_at,\n\tduk_bi_string_prototype_concat,\n\tduk_bi_string_prototype_includes,\n\tduk_bi_string_prototype_indexof_shared,\n\tduk_bi_string_prototype_locale_compare,\n\tduk_bi_string_prototype_match,\n\tduk_bi_string_prototype_repeat,\n\tduk_bi_string_prototype_replace,\n\tduk_bi_string_prototype_search,\n\tduk_bi_string_prototype_slice,\n\tduk_bi_string_prototype_split,\n\tduk_bi_string_prototype_startswith_endswith,\n\tduk_bi_string_prototype_substr,\n\tduk_bi_string_prototype_substring,\n\tduk_bi_string_prototype_to_string,\n\tduk_bi_string_prototype_trim,\n\tduk_bi_symbol_constructor_shared,\n\tduk_bi_symbol_key_for,\n\tduk_bi_symbol_toprimitive,\n\tduk_bi_symbol_tostring_shared,\n\tduk_bi_textdecoder_constructor,\n\tduk_bi_textdecoder_prototype_decode,\n\tduk_bi_textdecoder_prototype_shared_getter,\n\tduk_bi_textencoder_constructor,\n\tduk_bi_textencoder_prototype_encode,\n\tduk_bi_textencoder_prototype_encoding_getter,\n\tduk_bi_thread_constructor,\n\tduk_bi_thread_current,\n\tduk_bi_thread_resume,\n\tduk_bi_thread_yield,\n\tduk_bi_type_error_thrower,\n\tduk_bi_typedarray_buffer_getter,\n\tduk_bi_typedarray_bytelength_getter,\n\tduk_bi_typedarray_byteoffset_getter,\n\tduk_bi_typedarray_constructor,\n\tduk_bi_typedarray_set,\n\tduk_bi_uint8array_allocplain,\n\tduk_bi_uint8array_plainof,\n};\n#if defined(DUK_USE_DOUBLE_LE)\nDUK_INTERNAL const duk_uint8_t duk_builtins_data[4251] = {\n144,148,105,225,32,68,52,228,126,12,104,201,37,132,52,167,194,138,105,244,\n124,57,28,211,57,18,64,52,238,254,44,138,111,171,241,164,19,87,137,30,33,\n167,18,145,159,8,211,137,9,225,42,5,240,145,139,163,163,8,211,137,10,228,\n64,211,19,132,140,93,29,56,70,156,72,119,34,66,146,36,104,137,194,70,46,\n142,172,35,78,36,47,146,195,102,11,240,145,139,163,175,8,211,137,9,228,240,\n242,112,145,139,163,179,8,211,137,8,237,34,130,118,49,116,118,225,26,48,0,\n1,94,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,\n33,8,66,26,180,41,97,167,64,150,34,33,154,112,0,1,87,247,35,79,103,237,198,\n174,216,47,31,23,95,17,13,31,217,96,211,49,50,53,212,77,141,24,0,0,179,10,\n228,240,242,15,128,140,65,128,134,188,0,0,89,167,97,181,224,0,2,205,62,53,\n224,0,2,205,66,237,120,0,0,179,81,204,107,192,0,5,154,150,67,94,0,0,44,212,\n245,90,240,0,1,102,169,162,215,128,0,11,53,93,150,188,0,0,89,171,111,53,\n108,150,163,70,0,0,42,2,249,50,94,124,35,68,225,146,49,13,24,0,0,165,161,\n124,153,47,62,12,130,112,201,24,132,56,97,115,16,0,0,0,0,0,0,62,31,243,48,\n0,0,0,0,0,0,60,31,242,241,32,26,193,55,132,112,161,156,72,135,26,41,200,\n140,114,163,156,201,7,56,79,9,80,47,132,140,93,19,160,43,145,3,76,78,18,49,\n116,78,144,238,68,133,36,72,209,19,132,140,93,19,168,47,146,195,102,11,240,\n145,139,162,117,132,242,120,121,56,72,197,209,59,2,59,72,160,157,140,93,19,\n181,36,242,50,143,36,31,131,162,166,7,144,238,133,227,226,235,224,242,161,\n249,18,21,100,20,207,44,199,151,180,122,89,135,152,154,121,153,199,156,158,\n121,218,7,158,162,121,250,71,160,166,122,26,135,162,170,122,58,199,164,16,\n240,70,68,226,27,51,199,138,120,35,34,112,171,112,38,121,1,124,153,47,62,\n17,162,112,201,19,211,11,228,201,121,240,100,19,134,72,158,160,91,201,18,\n186,44,3,68,79,122,168,151,115,165,40,21,18,227,65,198,231,200,8,68,184,84,\n53,19,38,120,128,145,144,78,25,59,72,163,48,64,144,200,39,12,157,164,80,46,\n185,143,115,72,217,230,72,9,35,68,225,147,180,138,51,68,9,17,162,112,201,\n218,69,2,235,152,247,52,141,158,108,128,98,72,64,121,51,132,4,81,164,144,\n128,242,104,136,0,16,92,38,14,49,39,199,197,211,116,240,242,113,197,231,18,\n53,189,116,65,131,18,124,117,155,199,197,207,36,103,142,12,146,20,80,249,\n186,60,116,4,204,73,241,214,111,31,23,60,145,158,56,208,48,146,229,146,3,2,\n82,65,155,195,94,3,10,36,4,201,196,64,56,100,42,26,78,62,46,121,35,60,113,\n152,16,25,10,134,147,143,139,158,72,205,4,151,21,0,73,16,11,230,144,12,88,\n144,153,39,52,144,69,241,37,72,217,240,151,153,27,36,57,178,230,16,16,137,\n114,68,2,200,62,81,1,8,151,11,23,100,141,229,18,6,34,92,37,230,70,201,1,89,\n57,36,2,40,152,151,44,129,83,18,124,117,155,199,197,207,36,103,142,75,12,\n11,151,46,89,40,18,37,200,64,12,154,236,252,238,185,23,95,213,1,132,234,0,\n194,245,128,14,56,37,199,89,188,124,92,242,70,120,232,16,26,137,113,241,\n116,221,60,60,156,113,122,36,10,62,46,121,35,60,113,18,225,27,70,18,32,10,\n201,211,32,67,107,104,100,42,26,78,24,147,153,35,181,181,207,64,67,107,104,\n100,42,26,78,72,147,153,35,181,181,207,68,16,218,218,91,156,170,63,134,36,\n230,72,237,109,116,136,16,218,218,91,156,170,63,146,36,230,72,237,109,116,\n137,16,96,128,228,2,6,191,46,3,71,147,68,4,16,22,188,169,240,16,40,104,242,\n135,198,171,44,68,65,5,217,231,215,6,231,62,188,8,49,1,3,162,92,4,98,12,41,\n7,33,148,53,242,128,97,32,130,3,9,205,16,38,199,198,14,9,0,111,115,225,0,8,\n250,72,240,207,128,241,37,73,25,18,40,0,178,58,11,56,192,2,201,104,17,35,\n160,9,39,70,114,8,6,147,214,129,18,74,240,30,141,145,208,89,203,62,3,161,\n163,37,248,226,185,244,11,88,37,62,33,163,37,248,226,185,252,0,127,255,130,\n146,164,142,32,26,1,36,230,18,1,164,7,43,163,194,0,71,128,105,64,216,7,192,\n52,192,197,66,230,72,192,52,224,209,32,232,34,68,62,129,113,32,232,34,114,\n40,49,231,16,254,0,63,255,208,99,2,140,44,92,206,8,224,143,4,225,147,210,\n124,13,44,92,206,9,195,39,30,228,54,126,163,225,200,169,198,133,42,166,191,\n246,3,11,251,0,24,71,4,120,9,251,8,10,17,193,30,9,195,39,1,63,105,1,98,112,\n201,199,185,13,159,1,63,105,32,48,156,209,2,126,227,224,58,26,50,95,142,47,\n192,208,22,176,74,124,67,70,75,241,197,248,26,64,213,184,64,89,56,39,49,\n224,137,62,36,2,176,19,17,254,68,3,196,143,88,4,79,162,0,210,32,34,35,253,\n72,5,146,208,34,125,144,5,147,214,137,253,208,9,149,3,41,197,13,55,233,0,\n185,187,139,117,137,30,8,18,39,172,1,25,187,139,112,128,178,113,110,177,35,\n193,2,68,245,128,23,55,114,143,121,35,193,2,68,245,130,8,205,220,91,132,5,\n147,148,123,201,30,8,18,39,172,16,18,113,67,63,128,3,68,143,32,39,243,32,\n42,83,4,103,46,89,19,63,224,208,16,70,142,92,178,38,127,193,164,8,67,68,\n186,12,146,247,154,1,165,64,202,113,252,160,131,32,7,35,167,26,50,235,231,\n130,48,179,192,65,148,69,19,214,2,251,85,2,232,72,31,255,255,255,255,255,\n253,239,226,122,196,55,106,160,93,9,0,4,0,0,0,0,0,0,3,49,0,0,0,0,0,0,3,225,\n252,143,94,233,34,104,169,54,144,210,161,168,158,32,0,0,0,0,0,0,120,63,145,\n235,72,96,77,21,38,210,26,84,53,19,196,0,0,0,0,0,0,15,15,240,253,35,228,\n133,185,176,0,0,0,0,0,0,44,15,8,117,128,190,212,128,82,109,33,179,33,137,\n24,31,255,255,255,255,255,231,232,100,58,196,55,106,64,41,54,144,217,144,\n196,140,15,255,255,255,255,255,243,252,49,15,4,100,78,33,179,60,120,167,\n130,50,39,10,183,2,103,144,113,8,151,10,134,162,100,221,16,18,137,113,13,\n153,12,72,238,137,1,81,46,52,28,110,232,148,53,18,228,128,82,113,13,153,12,\n72,238,137,142,73,78,52,0,0,0,0,0,0,0,0,8,58,254,1,12,38,248,134,23,130,0,\n60,221,194,162,228,30,244,128,217,187,132,187,220,210,54,104,2,247,132,5,\n205,220,124,72,36,73,14,110,252,132,25,128,193,94,8,200,149,200,3,237,38,\n43,31,192,54,186,213,128,57,45,56,210,0,0,0,0,0,0,62,31,241,90,251,224,6,\n77,220,24,38,78,74,113,67,77,124,16,50,110,228,208,194,114,83,138,26,107,\n224,172,37,240,97,41,187,139,112,128,178,112,96,153,57,41,197,13,53,240,\n113,41,187,139,112,128,178,114,104,97,57,41,197,13,53,240,128,195,95,8,44,\n61,240,132,216,93,33,133,192,128,14,98,79,147,67,9,129,0,44,196,159,11,69,\n175,152,32,35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,\n39,198,57,179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,\n240,96,153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,\n197,144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,\n150,22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,\n161,166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,\n100,39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,\n18,32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,\n72,68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,\n46,16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,\n117,11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,\n178,36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,\n173,191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,\n117,35,43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,\n131,4,201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,\n102,123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,\n162,215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,\n192,131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,181,55,136,\n200,51,128,114,108,28,100,128,0,0,0,0,0,0,0,12,110,127,32,98,115,249,73,\n117,243,249,67,21,159,202,38,47,63,148,86,8,75,144,94,50,1,38,73,79,204,67,\n95,231,1,6,128,14,79,129,185,40,249,18,149,181,207,142,199,155,172,248,172,\n89,183,207,140,198,137,175,200,0,159,72,10,5,21,220,138,120,74,129,124,36,\n98,232,228,74,81,62,160,20,10,107,185,21,114,32,105,137,194,70,46,142,68,\n165,19,235,1,64,170,187,145,119,34,66,146,36,104,137,194,70,46,142,68,165,\n19,236,1,64,174,187,145,95,37,134,204,23,225,35,23,71,34,82,137,246,128,\n160,89,93,200,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,145,\n71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,0,0,0,0,0,118,\n105,160,91,60,165,195,201,194,8,134,149,216,130,0,192,41,224,136,2,48,176,\n228,1,149,13,195,15,0,200,209,97,71,128,99,32,176,131,192,113,57,143,0,167,\n131,32,230,80,28,202,139,175,237,2,48,189,160,20,1,119,48,87,193,186,129,\n89,56,72,197,209,200,193,185,35,23,71,109,13,219,36,98,232,237,156,13,26,\n208,211,14,102,19,87,137,91,95,128,0,10,64,24,92,0,0,82,2,53,63,240,49,204,\n202,10,14,38,78,44,141,52,207,31,0,0,22,32,129,100,180,8,148,145,78,102,\n152,80,113,50,113,100,105,166,120,248,0,0,177,1,65,196,201,199,20,178,36,\n227,224,0,2,200,3,6,133,41,35,31,0,0,22,1,44,57,137,62,33,179,216,162,152,\n192,131,18,124,162,27,61,138,41,108,32,196,159,16,217,232,235,81,76,104,73,\n137,62,81,13,158,142,181,20,184,16,98,79,136,108,244,244,168,166,56,36,196,\n159,40,134,207,79,74,138,93,10,49,39,194,173,192,158,158,149,20,188,20,98,\n79,133,91,129,61,109,74,41,124,30,68,159,16,217,236,83,108,96,68,137,62,81,\n13,158,197,54,182,17,34,79,136,108,244,117,169,182,52,38,68,159,40,134,207,\n71,90,155,92,8,145,39,196,54,122,122,84,219,28,19,34,79,148,67,103,167,165,\n77,174,133,72,147,225,86,224,79,79,74,155,94,10,145,39,194,173,192,158,182,\n165,54,190,206,25,212,35,208,226,100,150,211,201,29,162,44,140,35,103,0,0,\n0,0,0,0,3,192,252,206,25,228,35,208,226,100,150,211,201,29,162,44,140,35,\n103,0,0,0,0,0,0,3,192,252,206,25,244,35,208,226,100,150,211,201,29,162,44,\n140,35,103,0,0,0,0,0,0,3,192,252,206,26,4,35,208,226,100,150,211,201,29,\n162,44,140,35,103,0,0,0,0,0,0,0,1,0,206,26,20,35,208,226,100,150,211,201,\n29,162,44,140,35,103,0,0,0,0,0,0,0,1,0,206,26,36,35,208,226,100,150,211,\n201,29,162,44,140,35,103,0,0,0,0,0,0,0,65,0,206,26,52,35,208,226,100,150,\n211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,65,0,206,26,68,35,208,226,100,\n150,211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,65,0,206,26,84,35,208,226,\n100,150,211,201,29,162,44,140,35,103,0,0,0,0,0,0,0,129,0,195,154,99,16,38,\n36,0,251,68,117,179,216,162,128,68,72,1,241,13,158,197,20,150,25,18,0,125,\n162,58,217,232,235,117,100,162,136,25,18,0,125,162,58,217,232,235,116,36,\n162,145,2,226,64,15,136,108,244,117,186,178,81,73,129,113,32,7,196,54,122,\n58,221,9,40,165,64,200,144,3,237,17,214,207,79,75,171,37,20,80,200,144,3,\n237,17,214,207,79,75,161,37,20,138,23,18,0,124,67,103,167,165,213,146,138,\n77,11,137,0,62,33,179,211,210,232,73,69,42,133,196,128,31,10,183,2,125,89,\n40,163,5,196,128,31,10,183,2,125,9,40,164,96,200,144,3,224,221,64,172,157,\n89,40,163,134,68,128,31,6,234,5,100,232,73,69,35,133,68,128,31,104,142,182,\n125,89,40,180,0,168,144,3,237,17,214,207,161,37,22,144,19,18,0,124,67,103,\n213,146,139,80,9,137,0,62,33,179,232,73,69,172,5,90,40,153,59,68,117,179,\n216,166,192,77,162,137,147,136,108,246,41,180,176,219,69,19,39,104,142,182,\n122,58,221,89,41,178,6,218,40,153,59,68,117,179,209,214,232,73,77,162,6,90,\n40,153,56,134,207,71,91,171,37,54,152,25,104,162,100,226,27,61,29,110,132,\n148,218,160,109,162,137,147,180,71,91,61,61,46,172,148,217,67,109,20,76,\n157,162,58,217,233,233,116,36,166,209,67,45,20,76,156,67,103,167,165,213,\n146,155,77,12,180,81,50,113,13,158,158,151,66,74,109,84,50,209,68,201,194,\n173,192,159,86,74,108,193,150,138,38,78,21,110,4,250,18,83,104,193,182,138,\n38,78,13,212,10,201,213,146,155,56,109,162,137,147,131,117,2,178,116,36,\n166,209,194,237,20,76,157,162,58,217,245,100,167,16,2,237,20,76,157,162,58,\n217,244,36,167,18,2,173,20,76,156,67,103,213,146,156,80,10,180,81,50,113,\n13,159,66,74,113,97,175,220,48,216,109,192,4,42,22,189,163,0,196,133,0,185,\n80,32,28,78,99,193,18,80,36,4,19,159,141,156,0,178,90,4,74,73,0,22,209,68,\n201,185,129,4,2,8,3,132,64,60,36,6,149,113,72,176,171,240,84,0,157,91,116,\n116,32,11,42,218,221,216,181,129,32,3,234,219,165,3,188,231,235,249,8,187,\n152,252,47,86,227,105,18,7,244,17,91,42,56,175,185,248,110,173,198,209,208,\n36,0,238,82,97,87,188,189,179,240,93,122,32,12,22,162,42,125,144,132,160,7,\n236,161,25,232,237,105,64,205,59,127,102,158,160,230,63,11,217,66,51,210,\n129,154,118,254,205,61,65,236,127,171,197,34,168,48,6,90,162,1,0,39,75,84,\n72,8,9,33,186,162,80,64,76,13,213,19,2,130,96,110,150,181,0,65,6,51,213,20,\n128,65,17,11,213,19,130,137,121,211,210,210,144,6,39,75,84,80,0,201,119,\n234,138,8,41,86,231,71,84,80,129,79,135,186,122,101,224,34,25,69,233,208,3,\n91,141,170,40,96,139,113,180,181,69,36,21,110,54,142,134,168,165,1,176,23,\n212,47,0,216,134,234,87,128,111,117,181,168,128,209,3,70,230,106,192,5,139,\n168,209,234,138,32,36,144,102,235,8,3,146,27,170,40,160,146,132,103,170,40,\n192,115,3,117,69,28,22,113,163,69,170,41,103,1,66,188,17,145,52,104,4,202,\n113,67,76,130,227,72,194,13,240,108,0,0,83,96,0,2,185,0,104,146,84,97,48,0,\n1,90,192,56,169,24,145,179,192,0,5,96,8,56,16,32,128,56,18,52,125,198,86,\n147,186,140,28,50,21,13,39,31,23,60,145,158,56,204,141,47,121,6,155,190,\n188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,199,68,\n14,49,39,199,197,211,116,240,242,113,197,231,18,180,254,4,3,17,46,18,243,\n35,100,128,172,156,146,70,163,150,76,34,248,146,164,108,248,75,204,141,146,\n28,217,115,9,27,79,11,241,173,235,162,160,224,200,2,206,9,113,13,148,192,\n209,18,22,164,146,37,193,57,162,4,249,39,196,128,24,2,178,66,213,136,68,\n201,16,77,209,131,31,192,242,88,96,92,191,151,34,100,136,38,232,255,252,92,\n221,199,197,12,68,209,82,66,212,11,155,185,41,197,13,55,38,3,66,213,47,131,\n250,72,12,162,99,133,116,127,196,32,225,1,3,34,92,170,9,105,164,32,225,64,\n131,156,1,193,133,7,19,39,22,70,154,103,143,128,0,11,16,20,28,76,156,113,\n75,34,78,62,0,0,44,128,48,104,82,146,49,240,0,1,96,11,180,192,0,5,162,1,18,\n160,65,24,131,20,145,25,188,48,132,122,28,76,146,218,121,35,180,69,145,132,\n108,224,0,0,0,0,0,0,120,31,153,188,56,132,122,28,76,146,218,121,35,180,69,\n145,132,108,224,0,0,0,0,0,0,120,31,168,160,45,110,23,30,176,33,184,0,0,181,\n32,29,235,2,27,199,23,0,0,22,196,51,120,129,8,244,56,153,37,180,242,71,104,\n139,35,8,217,192,0,0,0,0,0,0,240,63,51,120,145,8,244,56,153,37,180,242,71,\n104,139,35,8,217,192,0,0,0,0,0,0,0,64,51,120,161,8,244,56,153,37,180,242,\n71,104,139,35,8,217,192,0,0,0,0,0,0,0,64,51,120,177,8,244,56,153,37,180,\n242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,120,193,8,244,56,153,37,\n180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,120,209,8,244,56,153,\n37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,16,64,51,120,225,8,244,56,\n153,37,180,242,71,104,139,35,8,217,192,0,0,0,0,0,0,32,64,32,227,194,0,97,\n57,162,4,246,40,5,34,92,35,68,225,161,166,219,16,16,137,112,52,41,73,29,\n169,1,65,196,201,197,145,166,153,246,8,3,137,204,120,34,74,8,200,58,128,28,\n211,160,130,52,78,26,26,110,248,0,0,170,4,12,70,137,195,38,0,0,42,68,159,7,\n84,3,154,150,16,70,137,195,67,77,223,0,0,20,224,20,160,152,23,223,0,0,20,\n226,9,65,154,232,147,161,115,59,224,0,2,156,84,12,50,9,195,38,0,0,41,133,\n30,224,32,54,186,221,128,60,\n};\n#elif defined(DUK_USE_DOUBLE_BE)\nDUK_INTERNAL const duk_uint8_t duk_builtins_data[4251] = {\n144,148,105,225,32,68,52,228,126,12,104,201,37,132,52,167,194,138,105,244,\n124,57,28,211,57,18,64,52,238,254,44,138,111,171,241,164,19,87,137,30,33,\n167,18,145,159,8,211,137,9,225,42,5,240,145,139,163,163,8,211,137,10,228,\n64,211,19,132,140,93,29,56,70,156,72,119,34,66,146,36,104,137,194,70,46,\n142,172,35,78,36,47,146,195,102,11,240,145,139,163,175,8,211,137,9,228,240,\n242,112,145,139,163,179,8,211,137,8,237,34,130,118,49,116,118,225,26,48,0,\n1,94,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,\n33,8,66,26,180,41,97,167,64,150,34,33,154,112,0,1,87,247,35,79,103,237,198,\n174,216,47,31,23,95,17,13,31,217,96,211,49,50,53,212,77,141,24,0,0,179,10,\n228,240,242,15,128,140,65,128,134,188,0,0,89,167,97,181,224,0,2,205,62,53,\n224,0,2,205,66,237,120,0,0,179,81,204,107,192,0,5,154,150,67,94,0,0,44,212,\n245,90,240,0,1,102,169,162,215,128,0,11,53,93,150,188,0,0,89,171,111,53,\n108,150,163,70,0,0,42,2,249,50,94,124,35,68,225,146,49,13,24,0,0,165,161,\n124,153,47,62,12,130,112,201,24,132,56,97,115,16,31,254,0,0,0,0,0,0,51,48,\n31,252,0,0,0,0,0,0,50,241,32,26,193,55,132,112,161,156,72,135,26,41,200,\n140,114,163,156,201,7,56,79,9,80,47,132,140,93,19,160,43,145,3,76,78,18,49,\n116,78,144,238,68,133,36,72,209,19,132,140,93,19,168,47,146,195,102,11,240,\n145,139,162,117,132,242,120,121,56,72,197,209,59,2,59,72,160,157,140,93,19,\n181,36,242,50,143,36,31,131,162,166,7,144,238,133,227,226,235,224,242,161,\n249,18,21,100,20,207,44,199,151,180,122,89,135,152,154,121,153,199,156,158,\n121,218,7,158,162,121,250,71,160,166,122,26,135,162,170,122,58,199,164,16,\n240,70,68,226,27,51,199,138,120,35,34,112,171,112,38,121,1,124,153,47,62,\n17,162,112,201,19,211,11,228,201,121,240,100,19,134,72,158,160,91,201,18,\n186,44,3,68,79,122,168,151,115,165,40,21,18,227,65,198,231,200,8,68,184,84,\n53,19,38,120,128,145,144,78,25,59,72,163,48,64,144,200,39,12,157,164,80,46,\n185,143,115,72,217,230,72,9,35,68,225,147,180,138,51,68,9,17,162,112,201,\n218,69,2,235,152,247,52,141,158,108,128,98,72,64,121,51,132,4,81,164,144,\n128,242,104,136,0,16,92,38,14,49,39,199,197,211,116,240,242,113,197,231,18,\n53,189,116,65,131,18,124,117,155,199,197,207,36,103,142,12,146,20,80,249,\n186,60,116,4,204,73,241,214,111,31,23,60,145,158,56,208,48,146,229,146,3,2,\n82,65,155,195,94,3,10,36,4,201,196,64,56,100,42,26,78,62,46,121,35,60,113,\n152,16,25,10,134,147,143,139,158,72,205,4,151,21,0,73,16,11,230,144,12,88,\n144,153,39,52,144,69,241,37,72,217,240,151,153,27,36,57,178,230,16,16,137,\n114,68,2,200,62,81,1,8,151,11,23,100,141,229,18,6,34,92,37,230,70,201,1,89,\n57,36,2,40,152,151,44,129,83,18,124,117,155,199,197,207,36,103,142,75,12,\n11,151,46,89,40,18,37,200,64,12,154,236,252,238,185,23,95,213,1,132,234,0,\n194,245,128,14,56,37,199,89,188,124,92,242,70,120,232,16,26,137,113,241,\n116,221,60,60,156,113,122,36,10,62,46,121,35,60,113,18,225,27,70,18,32,10,\n201,211,32,67,107,104,100,42,26,78,24,147,153,35,181,181,207,64,67,107,104,\n100,42,26,78,72,147,153,35,181,181,207,68,16,218,218,91,156,170,63,134,36,\n230,72,237,109,116,136,16,218,218,91,156,170,63,146,36,230,72,237,109,116,\n137,16,96,128,228,2,6,191,46,3,71,147,68,4,16,22,188,169,240,16,40,104,242,\n135,198,171,44,68,65,5,217,231,215,6,231,62,188,8,49,1,3,162,92,4,98,12,41,\n7,33,148,53,242,128,97,32,130,3,9,205,16,38,199,198,14,9,0,111,115,225,0,8,\n250,72,240,207,128,241,37,73,25,18,40,0,178,58,11,56,192,2,201,104,17,35,\n160,9,39,70,114,8,6,147,214,129,18,74,240,30,141,145,208,89,203,62,3,161,\n163,37,248,226,185,244,11,88,37,62,33,163,37,248,226,185,252,0,127,255,130,\n146,164,142,32,26,1,36,230,18,1,164,7,43,163,194,0,71,128,105,64,216,7,192,\n52,192,197,66,230,72,192,52,224,209,32,232,34,68,62,129,113,32,232,34,114,\n40,49,231,16,254,0,63,255,208,99,2,140,44,92,206,8,224,143,4,225,147,210,\n124,13,44,92,206,9,195,39,30,228,54,126,163,225,200,169,198,133,42,166,191,\n246,3,11,251,0,24,71,4,120,9,251,8,10,17,193,30,9,195,39,1,63,105,1,98,112,\n201,199,185,13,159,1,63,105,32,48,156,209,2,126,227,224,58,26,50,95,142,47,\n192,208,22,176,74,124,67,70,75,241,197,248,26,64,213,184,64,89,56,39,49,\n224,137,62,36,2,176,19,17,254,68,3,196,143,88,4,79,162,0,210,32,34,35,253,\n72,5,146,208,34,125,144,5,147,214,137,253,208,9,149,3,41,197,13,55,233,0,\n185,187,139,117,137,30,8,18,39,172,1,25,187,139,112,128,178,113,110,177,35,\n193,2,68,245,128,23,55,114,143,121,35,193,2,68,245,130,8,205,220,91,132,5,\n147,148,123,201,30,8,18,39,172,16,18,113,67,63,128,3,68,143,32,39,243,32,\n42,83,4,103,46,89,19,63,224,208,16,70,142,92,178,38,127,193,164,8,67,68,\n186,12,146,247,154,1,165,64,202,113,252,160,131,32,7,35,167,26,50,235,231,\n130,48,179,192,65,148,69,19,214,2,251,85,2,232,72,15,253,255,255,255,255,\n255,255,226,122,196,55,106,160,93,9,0,0,0,0,0,0,0,0,7,49,1,255,224,0,0,0,0,\n0,0,143,94,233,34,104,169,54,144,210,161,168,158,32,63,248,0,0,0,0,0,0,17,\n235,72,96,77,21,38,210,26,84,53,19,196,15,255,0,0,0,0,0,0,0,253,35,228,133,\n185,176,15,44,0,0,0,0,0,0,8,117,128,190,212,128,82,109,33,179,33,137,24,8,\n103,255,255,255,255,255,255,228,58,196,55,106,64,41,54,144,217,144,196,140,\n12,51,255,255,255,255,255,255,241,15,4,100,78,33,179,60,120,167,130,50,39,\n10,183,2,103,144,113,8,151,10,134,162,100,221,16,18,137,113,13,153,12,72,\n238,137,1,81,46,52,28,110,232,148,53,18,228,128,82,113,13,153,12,72,238,\n137,142,73,78,52,0,0,0,0,0,0,0,0,8,58,254,1,12,38,248,134,23,130,0,60,221,\n194,162,228,30,244,128,217,187,132,187,220,210,54,104,2,247,132,5,205,220,\n124,72,36,73,14,110,252,132,25,128,193,94,8,200,149,200,3,237,38,43,31,192,\n54,186,213,128,57,45,56,210,31,254,0,0,0,0,0,0,49,90,251,224,6,77,220,24,\n38,78,74,113,67,77,124,16,50,110,228,208,194,114,83,138,26,107,224,172,37,\n240,97,41,187,139,112,128,178,112,96,153,57,41,197,13,53,240,113,41,187,\n139,112,128,178,114,104,97,57,41,197,13,53,240,128,195,95,8,44,61,240,132,\n216,93,33,133,192,128,14,98,79,147,67,9,129,0,44,196,159,11,69,175,152,32,\n35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,39,198,57,\n179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,240,96,\n153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,197,\n144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,150,\n22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,161,\n166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,100,\n39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,18,\n32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,72,\n68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,46,\n16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,117,\n11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,178,\n36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,173,\n191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,117,35,\n43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,131,4,\n201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,102,\n123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,162,\n215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,192,\n131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,181,55,136,200,\n51,128,114,108,28,100,128,0,0,0,0,0,0,0,12,110,127,32,98,115,249,73,117,\n243,249,67,21,159,202,38,47,63,148,86,8,75,144,94,50,1,38,73,79,204,67,95,\n231,1,6,128,14,79,129,185,40,249,18,149,181,207,142,199,155,172,248,172,89,\n183,207,140,198,137,175,200,0,159,72,10,5,21,220,138,120,74,129,124,36,98,\n232,228,74,81,62,160,20,10,107,185,21,114,32,105,137,194,70,46,142,68,165,\n19,235,1,64,170,187,145,119,34,66,146,36,104,137,194,70,46,142,68,165,19,\n236,1,64,174,187,145,95,37,134,204,23,225,35,23,71,34,82,137,246,128,160,\n89,93,200,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,145,71,\n105,20,19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,32,105,246,0,0,0,\n0,0,91,60,165,195,201,194,8,134,149,216,130,0,192,41,224,136,2,48,176,228,\n1,149,13,195,15,0,200,209,97,71,128,99,32,176,131,192,113,57,143,0,167,131,\n32,230,80,28,202,139,175,237,2,48,189,160,20,1,119,48,87,193,186,129,89,56,\n72,197,209,200,193,185,35,23,71,109,13,219,36,98,232,237,156,13,26,208,211,\n14,102,19,87,137,91,95,128,0,10,64,24,92,0,0,82,2,53,63,240,49,204,202,10,\n14,38,78,44,141,52,207,31,0,0,22,32,129,100,180,8,148,145,78,102,152,80,\n113,50,113,100,105,166,120,248,0,0,177,1,65,196,201,199,20,178,36,227,224,\n0,2,200,3,6,133,41,35,31,0,0,22,1,44,57,137,62,33,179,216,162,152,192,131,\n18,124,162,27,61,138,41,108,32,196,159,16,217,232,235,81,76,104,73,137,62,\n81,13,158,142,181,20,184,16,98,79,136,108,244,244,168,166,56,36,196,159,40,\n134,207,79,74,138,93,10,49,39,194,173,192,158,158,149,20,188,20,98,79,133,\n91,129,61,109,74,41,124,30,68,159,16,217,236,83,108,96,68,137,62,81,13,158,\n197,54,182,17,34,79,136,108,244,117,169,182,52,38,68,159,40,134,207,71,90,\n155,92,8,145,39,196,54,122,122,84,219,28,19,34,79,148,67,103,167,165,77,\n174,133,72,147,225,86,224,79,79,74,155,94,10,145,39,194,173,192,158,182,\n165,54,190,206,25,212,35,208,226,100,150,211,201,29,162,44,140,35,103,0,\n255,192,0,0,0,0,0,0,206,25,228,35,208,226,100,150,211,201,29,162,44,140,35,\n103,0,255,192,0,0,0,0,0,0,206,25,244,35,208,226,100,150,211,201,29,162,44,\n140,35,103,0,255,192,0,0,0,0,0,0,206,26,4,35,208,226,100,150,211,201,29,\n162,44,140,35,103,1,0,0,0,0,0,0,0,0,206,26,20,35,208,226,100,150,211,201,\n29,162,44,140,35,103,1,0,0,0,0,0,0,0,0,206,26,36,35,208,226,100,150,211,\n201,29,162,44,140,35,103,1,0,64,0,0,0,0,0,0,206,26,52,35,208,226,100,150,\n211,201,29,162,44,140,35,103,1,0,64,0,0,0,0,0,0,206,26,68,35,208,226,100,\n150,211,201,29,162,44,140,35,103,1,0,64,0,0,0,0,0,0,206,26,84,35,208,226,\n100,150,211,201,29,162,44,140,35,103,1,0,128,0,0,0,0,0,0,195,154,99,16,38,\n36,0,251,68,117,179,216,162,128,68,72,1,241,13,158,197,20,150,25,18,0,125,\n162,58,217,232,235,117,100,162,136,25,18,0,125,162,58,217,232,235,116,36,\n162,145,2,226,64,15,136,108,244,117,186,178,81,73,129,113,32,7,196,54,122,\n58,221,9,40,165,64,200,144,3,237,17,214,207,79,75,171,37,20,80,200,144,3,\n237,17,214,207,79,75,161,37,20,138,23,18,0,124,67,103,167,165,213,146,138,\n77,11,137,0,62,33,179,211,210,232,73,69,42,133,196,128,31,10,183,2,125,89,\n40,163,5,196,128,31,10,183,2,125,9,40,164,96,200,144,3,224,221,64,172,157,\n89,40,163,134,68,128,31,6,234,5,100,232,73,69,35,133,68,128,31,104,142,182,\n125,89,40,180,0,168,144,3,237,17,214,207,161,37,22,144,19,18,0,124,67,103,\n213,146,139,80,9,137,0,62,33,179,232,73,69,172,5,90,40,153,59,68,117,179,\n216,166,192,77,162,137,147,136,108,246,41,180,176,219,69,19,39,104,142,182,\n122,58,221,89,41,178,6,218,40,153,59,68,117,179,209,214,232,73,77,162,6,90,\n40,153,56,134,207,71,91,171,37,54,152,25,104,162,100,226,27,61,29,110,132,\n148,218,160,109,162,137,147,180,71,91,61,61,46,172,148,217,67,109,20,76,\n157,162,58,217,233,233,116,36,166,209,67,45,20,76,156,67,103,167,165,213,\n146,155,77,12,180,81,50,113,13,158,158,151,66,74,109,84,50,209,68,201,194,\n173,192,159,86,74,108,193,150,138,38,78,21,110,4,250,18,83,104,193,182,138,\n38,78,13,212,10,201,213,146,155,56,109,162,137,147,131,117,2,178,116,36,\n166,209,194,237,20,76,157,162,58,217,245,100,167,16,2,237,20,76,157,162,58,\n217,244,36,167,18,2,173,20,76,156,67,103,213,146,156,80,10,180,81,50,113,\n13,159,66,74,113,97,175,220,48,216,109,192,4,42,22,189,163,0,196,133,0,185,\n80,32,28,78,99,193,18,80,36,4,19,159,141,156,0,178,90,4,74,73,0,22,209,68,\n201,185,129,4,2,8,3,132,64,60,36,4,0,91,240,168,177,69,118,144,157,91,116,\n116,32,32,1,53,216,221,218,170,139,3,234,219,165,0,255,152,185,11,251,232,\n231,188,47,86,227,105,18,1,255,184,170,59,41,92,23,240,110,173,198,209,208,\n36,3,253,188,183,177,82,110,80,224,93,122,32,32,4,144,253,170,34,22,140,7,\n236,161,25,232,237,105,64,63,230,160,158,102,127,59,205,11,217,66,51,210,\n128,127,237,65,60,204,254,119,155,171,197,34,168,48,6,90,162,1,0,39,75,84,\n72,8,9,33,186,162,80,64,76,13,213,19,2,130,96,110,150,181,0,65,6,51,213,20,\n128,65,17,11,213,19,130,137,121,211,210,210,144,6,39,75,84,80,0,201,119,\n234,138,8,41,86,231,71,84,80,129,79,135,186,122,101,224,34,25,69,233,208,3,\n91,141,170,40,96,139,113,180,181,69,36,21,110,54,142,134,168,165,1,176,23,\n212,47,0,216,134,234,87,128,111,117,181,168,128,209,3,70,230,106,192,5,139,\n168,209,234,138,32,36,144,102,235,8,3,146,27,170,40,160,146,132,103,170,40,\n192,115,3,117,69,28,22,113,163,69,170,41,103,1,66,188,17,145,52,104,4,202,\n113,67,76,130,227,72,194,13,240,108,0,0,83,96,0,2,185,0,104,146,84,97,48,0,\n1,90,192,56,169,24,145,179,192,0,5,96,8,56,16,32,128,56,18,52,125,198,86,\n147,186,140,28,50,21,13,39,31,23,60,145,158,56,204,141,47,121,6,155,190,\n188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,199,68,\n14,49,39,199,197,211,116,240,242,113,197,231,18,180,254,4,3,17,46,18,243,\n35,100,128,172,156,146,70,163,150,76,34,248,146,164,108,248,75,204,141,146,\n28,217,115,9,27,79,11,241,173,235,162,160,224,200,2,206,9,113,13,148,192,\n209,18,22,164,146,37,193,57,162,4,249,39,196,128,24,2,178,66,213,136,68,\n201,16,77,209,131,31,192,242,88,96,92,191,151,34,100,136,38,232,255,252,92,\n221,199,197,12,68,209,82,66,212,11,155,185,41,197,13,55,38,3,66,213,47,131,\n250,72,12,162,99,133,116,127,196,32,225,1,3,34,92,170,9,105,164,32,225,64,\n131,156,1,193,133,7,19,39,22,70,154,103,143,128,0,11,16,20,28,76,156,113,\n75,34,78,62,0,0,44,128,48,104,82,146,49,240,0,1,96,11,180,192,0,5,162,1,18,\n160,65,24,131,20,145,25,188,48,132,122,28,76,146,218,121,35,180,69,145,132,\n108,224,31,248,0,0,0,0,0,0,25,188,56,132,122,28,76,146,218,121,35,180,69,\n145,132,108,224,31,248,0,0,0,0,0,0,40,160,45,110,23,30,176,33,184,0,0,181,\n32,29,235,2,27,199,23,0,0,22,196,51,120,129,8,244,56,153,37,180,242,71,104,\n139,35,8,217,192,63,240,0,0,0,0,0,0,51,120,145,8,244,56,153,37,180,242,71,\n104,139,35,8,217,192,64,0,0,0,0,0,0,0,51,120,161,8,244,56,153,37,180,242,\n71,104,139,35,8,217,192,64,0,0,0,0,0,0,0,51,120,177,8,244,56,153,37,180,\n242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,120,193,8,244,56,153,37,\n180,242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,120,209,8,244,56,153,\n37,180,242,71,104,139,35,8,217,192,64,16,0,0,0,0,0,0,51,120,225,8,244,56,\n153,37,180,242,71,104,139,35,8,217,192,64,32,0,0,0,0,0,0,32,227,194,0,97,\n57,162,4,246,40,5,34,92,35,68,225,161,166,219,16,16,137,112,52,41,73,29,\n169,1,65,196,201,197,145,166,153,246,8,3,137,204,120,34,74,8,200,58,128,28,\n211,160,130,52,78,26,26,110,248,0,0,170,4,12,70,137,195,38,0,0,42,68,159,7,\n84,3,154,150,16,70,137,195,67,77,223,0,0,20,224,20,160,152,23,223,0,0,20,\n226,9,65,154,232,147,161,115,59,224,0,2,156,84,12,50,9,195,38,0,0,41,133,\n30,224,32,54,186,221,128,60,\n};\n#elif defined(DUK_USE_DOUBLE_ME)\nDUK_INTERNAL const duk_uint8_t duk_builtins_data[4251] = {\n144,148,105,225,32,68,52,228,126,12,104,201,37,132,52,167,194,138,105,244,\n124,57,28,211,57,18,64,52,238,254,44,138,111,171,241,164,19,87,137,30,33,\n167,18,145,159,8,211,137,9,225,42,5,240,145,139,163,163,8,211,137,10,228,\n64,211,19,132,140,93,29,56,70,156,72,119,34,66,146,36,104,137,194,70,46,\n142,172,35,78,36,47,146,195,102,11,240,145,139,163,175,8,211,137,9,228,240,\n242,112,145,139,163,179,8,211,137,8,237,34,130,118,49,116,118,225,26,48,0,\n1,94,29,201,158,46,183,39,135,147,132,140,93,16,132,76,66,33,8,66,16,132,\n33,8,66,26,180,41,97,167,64,150,34,33,154,112,0,1,87,247,35,79,103,237,198,\n174,216,47,31,23,95,17,13,31,217,96,211,49,50,53,212,77,141,24,0,0,179,10,\n228,240,242,15,128,140,65,128,134,188,0,0,89,167,97,181,224,0,2,205,62,53,\n224,0,2,205,66,237,120,0,0,179,81,204,107,192,0,5,154,150,67,94,0,0,44,212,\n245,90,240,0,1,102,169,162,215,128,0,11,53,93,150,188,0,0,89,171,111,53,\n108,150,163,70,0,0,42,2,249,50,94,124,35,68,225,146,49,13,24,0,0,165,161,\n124,153,47,62,12,130,112,201,24,132,56,97,115,16,0,0,62,31,192,0,0,0,51,48,\n0,0,60,31,192,0,0,0,50,241,32,26,193,55,132,112,161,156,72,135,26,41,200,\n140,114,163,156,201,7,56,79,9,80,47,132,140,93,19,160,43,145,3,76,78,18,49,\n116,78,144,238,68,133,36,72,209,19,132,140,93,19,168,47,146,195,102,11,240,\n145,139,162,117,132,242,120,121,56,72,197,209,59,2,59,72,160,157,140,93,19,\n181,36,242,50,143,36,31,131,162,166,7,144,238,133,227,226,235,224,242,161,\n249,18,21,100,20,207,44,199,151,180,122,89,135,152,154,121,153,199,156,158,\n121,218,7,158,162,121,250,71,160,166,122,26,135,162,170,122,58,199,164,16,\n240,70,68,226,27,51,199,138,120,35,34,112,171,112,38,121,1,124,153,47,62,\n17,162,112,201,19,211,11,228,201,121,240,100,19,134,72,158,160,91,201,18,\n186,44,3,68,79,122,168,151,115,165,40,21,18,227,65,198,231,200,8,68,184,84,\n53,19,38,120,128,145,144,78,25,59,72,163,48,64,144,200,39,12,157,164,80,46,\n185,143,115,72,217,230,72,9,35,68,225,147,180,138,51,68,9,17,162,112,201,\n218,69,2,235,152,247,52,141,158,108,128,98,72,64,121,51,132,4,81,164,144,\n128,242,104,136,0,16,92,38,14,49,39,199,197,211,116,240,242,113,197,231,18,\n53,189,116,65,131,18,124,117,155,199,197,207,36,103,142,12,146,20,80,249,\n186,60,116,4,204,73,241,214,111,31,23,60,145,158,56,208,48,146,229,146,3,2,\n82,65,155,195,94,3,10,36,4,201,196,64,56,100,42,26,78,62,46,121,35,60,113,\n152,16,25,10,134,147,143,139,158,72,205,4,151,21,0,73,16,11,230,144,12,88,\n144,153,39,52,144,69,241,37,72,217,240,151,153,27,36,57,178,230,16,16,137,\n114,68,2,200,62,81,1,8,151,11,23,100,141,229,18,6,34,92,37,230,70,201,1,89,\n57,36,2,40,152,151,44,129,83,18,124,117,155,199,197,207,36,103,142,75,12,\n11,151,46,89,40,18,37,200,64,12,154,236,252,238,185,23,95,213,1,132,234,0,\n194,245,128,14,56,37,199,89,188,124,92,242,70,120,232,16,26,137,113,241,\n116,221,60,60,156,113,122,36,10,62,46,121,35,60,113,18,225,27,70,18,32,10,\n201,211,32,67,107,104,100,42,26,78,24,147,153,35,181,181,207,64,67,107,104,\n100,42,26,78,72,147,153,35,181,181,207,68,16,218,218,91,156,170,63,134,36,\n230,72,237,109,116,136,16,218,218,91,156,170,63,146,36,230,72,237,109,116,\n137,16,96,128,228,2,6,191,46,3,71,147,68,4,16,22,188,169,240,16,40,104,242,\n135,198,171,44,68,65,5,217,231,215,6,231,62,188,8,49,1,3,162,92,4,98,12,41,\n7,33,148,53,242,128,97,32,130,3,9,205,16,38,199,198,14,9,0,111,115,225,0,8,\n250,72,240,207,128,241,37,73,25,18,40,0,178,58,11,56,192,2,201,104,17,35,\n160,9,39,70,114,8,6,147,214,129,18,74,240,30,141,145,208,89,203,62,3,161,\n163,37,248,226,185,244,11,88,37,62,33,163,37,248,226,185,252,0,127,255,130,\n146,164,142,32,26,1,36,230,18,1,164,7,43,163,194,0,71,128,105,64,216,7,192,\n52,192,197,66,230,72,192,52,224,209,32,232,34,68,62,129,113,32,232,34,114,\n40,49,231,16,254,0,63,255,208,99,2,140,44,92,206,8,224,143,4,225,147,210,\n124,13,44,92,206,9,195,39,30,228,54,126,163,225,200,169,198,133,42,166,191,\n246,3,11,251,0,24,71,4,120,9,251,8,10,17,193,30,9,195,39,1,63,105,1,98,112,\n201,199,185,13,159,1,63,105,32,48,156,209,2,126,227,224,58,26,50,95,142,47,\n192,208,22,176,74,124,67,70,75,241,197,248,26,64,213,184,64,89,56,39,49,\n224,137,62,36,2,176,19,17,254,68,3,196,143,88,4,79,162,0,210,32,34,35,253,\n72,5,146,208,34,125,144,5,147,214,137,253,208,9,149,3,41,197,13,55,233,0,\n185,187,139,117,137,30,8,18,39,172,1,25,187,139,112,128,178,113,110,177,35,\n193,2,68,245,128,23,55,114,143,121,35,193,2,68,245,130,8,205,220,91,132,5,\n147,148,123,201,30,8,18,39,172,16,18,113,67,63,128,3,68,143,32,39,243,32,\n42,83,4,103,46,89,19,63,224,208,16,70,142,92,178,38,127,193,164,8,67,68,\n186,12,146,247,154,1,165,64,202,113,252,160,131,32,7,35,167,26,50,235,231,\n130,48,179,192,65,148,69,19,214,2,251,85,2,232,72,31,255,253,239,255,255,\n255,255,226,122,196,55,106,160,93,9,0,0,0,0,0,4,0,0,3,49,0,0,3,225,252,0,0,\n0,0,143,94,233,34,104,169,54,144,210,161,168,158,32,0,0,120,63,128,0,0,0,\n17,235,72,96,77,21,38,210,26,84,53,19,196,0,0,15,15,240,0,0,0,0,253,35,228,\n133,185,176,0,0,44,15,0,0,0,0,8,117,128,190,212,128,82,109,33,179,33,137,\n24,31,255,231,232,127,255,255,255,228,58,196,55,106,64,41,54,144,217,144,\n196,140,15,255,243,252,63,255,255,255,241,15,4,100,78,33,179,60,120,167,\n130,50,39,10,183,2,103,144,113,8,151,10,134,162,100,221,16,18,137,113,13,\n153,12,72,238,137,1,81,46,52,28,110,232,148,53,18,228,128,82,113,13,153,12,\n72,238,137,142,73,78,52,0,0,0,0,0,0,0,0,8,58,254,1,12,38,248,134,23,130,0,\n60,221,194,162,228,30,244,128,217,187,132,187,220,210,54,104,2,247,132,5,\n205,220,124,72,36,73,14,110,252,132,25,128,193,94,8,200,149,200,3,237,38,\n43,31,192,54,186,213,128,57,45,56,210,0,0,62,31,192,0,0,0,49,90,251,224,6,\n77,220,24,38,78,74,113,67,77,124,16,50,110,228,208,194,114,83,138,26,107,\n224,172,37,240,97,41,187,139,112,128,178,112,96,153,57,41,197,13,53,240,\n113,41,187,139,112,128,178,114,104,97,57,41,197,13,53,240,128,195,95,8,44,\n61,240,132,216,93,33,133,192,128,14,98,79,147,67,9,129,0,44,196,159,11,69,\n175,152,32,35,100,33,135,24,147,237,38,34,246,139,95,48,64,70,200,68,8,49,\n39,198,57,179,61,144,138,22,98,79,180,152,153,215,54,103,178,17,129,204,73,\n240,96,153,44,132,112,163,18,125,164,196,62,130,100,178,18,1,140,73,240,96,\n197,144,146,18,98,79,180,152,135,208,98,200,74,8,49,39,195,186,145,149,144,\n150,22,98,79,180,152,143,215,82,50,178,19,2,140,73,241,136,109,38,73,89,9,\n161,166,36,251,73,137,157,67,105,50,74,200,78,10,49,39,201,16,78,104,229,\n100,39,134,152,147,237,38,41,116,130,115,71,43,33,64,60,196,159,24,133,173,\n18,32,156,209,202,200,81,18,49,39,218,76,76,234,22,180,72,130,115,71,43,33,\n72,68,196,159,38,134,19,46,105,56,226,150,68,157,160,1,228,73,242,104,97,\n46,16,31,34,79,140,66,214,137,16,78,104,229,108,169,137,72,147,237,38,38,\n117,11,90,36,65,57,163,149,178,168,21,34,79,146,32,156,209,202,218,250,161,\n178,36,251,73,138,93,32,156,209,202,218,250,193,82,36,248,196,54,147,36,\n173,191,174,27,34,79,180,152,153,212,54,147,36,173,191,176,17,34,79,135,\n117,35,43,115,236,133,200,147,237,38,35,245,212,140,173,207,180,15,34,79,\n131,4,201,108,173,133,72,147,237,38,33,244,19,37,178,184,17,34,79,140,115,\n102,123,107,238,133,200,147,237,38,38,117,205,153,237,175,188,23,34,79,133,\n162,215,204,16,17,182,254,248,116,137,62,210,98,47,104,181,243,4,4,109,191,\n192,131,152,147,230,8,8,217,12,16,60,137,62,96,128,141,178,193,181,55,136,\n200,51,128,114,108,28,100,128,0,0,0,0,0,0,0,12,110,127,32,98,115,249,73,\n117,243,249,67,21,159,202,38,47,63,148,86,8,75,144,94,50,1,38,73,79,204,67,\n95,231,1,6,128,14,79,129,185,40,249,18,149,181,207,142,199,155,172,248,172,\n89,183,207,140,198,137,175,200,0,159,72,10,5,21,220,138,120,74,129,124,36,\n98,232,228,74,81,62,160,20,10,107,185,21,114,32,105,137,194,70,46,142,68,\n165,19,235,1,64,170,187,145,119,34,66,146,36,104,137,194,70,46,142,68,165,\n19,236,1,64,174,187,145,95,37,134,204,23,225,35,23,71,34,82,137,246,128,\n160,89,93,200,167,147,195,201,194,70,46,142,68,165,19,238,1,64,182,187,145,\n71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70,72,115,96,0,118,105,160,\n0,0,0,0,91,60,165,195,201,194,8,134,149,216,130,0,192,41,224,136,2,48,176,\n228,1,149,13,195,15,0,200,209,97,71,128,99,32,176,131,192,113,57,143,0,167,\n131,32,230,80,28,202,139,175,237,2,48,189,160,20,1,119,48,87,193,186,129,\n89,56,72,197,209,200,193,185,35,23,71,109,13,219,36,98,232,237,156,13,26,\n208,211,14,102,19,87,137,91,95,128,0,10,64,24,92,0,0,82,2,53,63,240,49,204,\n202,10,14,38,78,44,141,52,207,31,0,0,22,32,129,100,180,8,148,145,78,102,\n152,80,113,50,113,100,105,166,120,248,0,0,177,1,65,196,201,199,20,178,36,\n227,224,0,2,200,3,6,133,41,35,31,0,0,22,1,44,57,137,62,33,179,216,162,152,\n192,131,18,124,162,27,61,138,41,108,32,196,159,16,217,232,235,81,76,104,73,\n137,62,81,13,158,142,181,20,184,16,98,79,136,108,244,244,168,166,56,36,196,\n159,40,134,207,79,74,138,93,10,49,39,194,173,192,158,158,149,20,188,20,98,\n79,133,91,129,61,109,74,41,124,30,68,159,16,217,236,83,108,96,68,137,62,81,\n13,158,197,54,182,17,34,79,136,108,244,117,169,182,52,38,68,159,40,134,207,\n71,90,155,92,8,145,39,196,54,122,122,84,219,28,19,34,79,148,67,103,167,165,\n77,174,133,72,147,225,86,224,79,79,74,155,94,10,145,39,194,173,192,158,182,\n165,54,190,206,25,212,35,208,226,100,150,211,201,29,162,44,140,35,103,0,0,\n3,192,252,0,0,0,0,206,25,228,35,208,226,100,150,211,201,29,162,44,140,35,\n103,0,0,3,192,252,0,0,0,0,206,25,244,35,208,226,100,150,211,201,29,162,44,\n140,35,103,0,0,3,192,252,0,0,0,0,206,26,4,35,208,226,100,150,211,201,29,\n162,44,140,35,103,0,0,0,1,0,0,0,0,0,206,26,20,35,208,226,100,150,211,201,\n29,162,44,140,35,103,0,0,0,1,0,0,0,0,0,206,26,36,35,208,226,100,150,211,\n201,29,162,44,140,35,103,0,0,0,65,0,0,0,0,0,206,26,52,35,208,226,100,150,\n211,201,29,162,44,140,35,103,0,0,0,65,0,0,0,0,0,206,26,68,35,208,226,100,\n150,211,201,29,162,44,140,35,103,0,0,0,65,0,0,0,0,0,206,26,84,35,208,226,\n100,150,211,201,29,162,44,140,35,103,0,0,0,129,0,0,0,0,0,195,154,99,16,38,\n36,0,251,68,117,179,216,162,128,68,72,1,241,13,158,197,20,150,25,18,0,125,\n162,58,217,232,235,117,100,162,136,25,18,0,125,162,58,217,232,235,116,36,\n162,145,2,226,64,15,136,108,244,117,186,178,81,73,129,113,32,7,196,54,122,\n58,221,9,40,165,64,200,144,3,237,17,214,207,79,75,171,37,20,80,200,144,3,\n237,17,214,207,79,75,161,37,20,138,23,18,0,124,67,103,167,165,213,146,138,\n77,11,137,0,62,33,179,211,210,232,73,69,42,133,196,128,31,10,183,2,125,89,\n40,163,5,196,128,31,10,183,2,125,9,40,164,96,200,144,3,224,221,64,172,157,\n89,40,163,134,68,128,31,6,234,5,100,232,73,69,35,133,68,128,31,104,142,182,\n125,89,40,180,0,168,144,3,237,17,214,207,161,37,22,144,19,18,0,124,67,103,\n213,146,139,80,9,137,0,62,33,179,232,73,69,172,5,90,40,153,59,68,117,179,\n216,166,192,77,162,137,147,136,108,246,41,180,176,219,69,19,39,104,142,182,\n122,58,221,89,41,178,6,218,40,153,59,68,117,179,209,214,232,73,77,162,6,90,\n40,153,56,134,207,71,91,171,37,54,152,25,104,162,100,226,27,61,29,110,132,\n148,218,160,109,162,137,147,180,71,91,61,61,46,172,148,217,67,109,20,76,\n157,162,58,217,233,233,116,36,166,209,67,45,20,76,156,67,103,167,165,213,\n146,155,77,12,180,81,50,113,13,158,158,151,66,74,109,84,50,209,68,201,194,\n173,192,159,86,74,108,193,150,138,38,78,21,110,4,250,18,83,104,193,182,138,\n38,78,13,212,10,201,213,146,155,56,109,162,137,147,131,117,2,178,116,36,\n166,209,194,237,20,76,157,162,58,217,245,100,167,16,2,237,20,76,157,162,58,\n217,244,36,167,18,2,173,20,76,156,67,103,213,146,156,80,10,180,81,50,113,\n13,159,66,74,113,97,175,220,48,216,109,192,4,42,22,189,163,0,196,133,0,185,\n80,32,28,78,99,193,18,80,36,4,19,159,141,156,0,178,90,4,74,73,0,22,209,68,\n201,185,129,4,2,8,3,132,64,60,36,0,171,240,84,6,149,113,72,176,157,91,116,\n116,32,88,181,129,32,11,42,218,221,131,234,219,165,1,8,187,152,255,188,231,\n235,248,47,86,227,105,18,2,56,175,185,255,244,17,91,40,110,173,198,209,208,\n36,7,188,189,179,240,238,82,97,80,93,122,32,125,144,132,160,12,22,162,42,7,\n236,161,25,232,237,105,64,158,160,230,63,205,59,127,102,11,217,66,51,210,\n129,61,65,236,127,154,118,254,205,171,197,34,168,48,6,90,162,1,0,39,75,84,\n72,8,9,33,186,162,80,64,76,13,213,19,2,130,96,110,150,181,0,65,6,51,213,20,\n128,65,17,11,213,19,130,137,121,211,210,210,144,6,39,75,84,80,0,201,119,\n234,138,8,41,86,231,71,84,80,129,79,135,186,122,101,224,34,25,69,233,208,3,\n91,141,170,40,96,139,113,180,181,69,36,21,110,54,142,134,168,165,1,176,23,\n212,47,0,216,134,234,87,128,111,117,181,168,128,209,3,70,230,106,192,5,139,\n168,209,234,138,32,36,144,102,235,8,3,146,27,170,40,160,146,132,103,170,40,\n192,115,3,117,69,28,22,113,163,69,170,41,103,1,66,188,17,145,52,104,4,202,\n113,67,76,130,227,72,194,13,240,108,0,0,83,96,0,2,185,0,104,146,84,97,48,0,\n1,90,192,56,169,24,145,179,192,0,5,96,8,56,16,32,128,56,18,52,125,198,86,\n147,186,140,28,50,21,13,39,31,23,60,145,158,56,204,141,47,121,6,155,190,\n188,24,49,39,199,89,188,124,92,242,70,120,224,201,33,69,15,155,163,199,68,\n14,49,39,199,197,211,116,240,242,113,197,231,18,180,254,4,3,17,46,18,243,\n35,100,128,172,156,146,70,163,150,76,34,248,146,164,108,248,75,204,141,146,\n28,217,115,9,27,79,11,241,173,235,162,160,224,200,2,206,9,113,13,148,192,\n209,18,22,164,146,37,193,57,162,4,249,39,196,128,24,2,178,66,213,136,68,\n201,16,77,209,131,31,192,242,88,96,92,191,151,34,100,136,38,232,255,252,92,\n221,199,197,12,68,209,82,66,212,11,155,185,41,197,13,55,38,3,66,213,47,131,\n250,72,12,162,99,133,116,127,196,32,225,1,3,34,92,170,9,105,164,32,225,64,\n131,156,1,193,133,7,19,39,22,70,154,103,143,128,0,11,16,20,28,76,156,113,\n75,34,78,62,0,0,44,128,48,104,82,146,49,240,0,1,96,11,180,192,0,5,162,1,18,\n160,65,24,131,20,145,25,188,48,132,122,28,76,146,218,121,35,180,69,145,132,\n108,224,0,0,120,31,128,0,0,0,25,188,56,132,122,28,76,146,218,121,35,180,69,\n145,132,108,224,0,0,120,31,128,0,0,0,40,160,45,110,23,30,176,33,184,0,0,\n181,32,29,235,2,27,199,23,0,0,22,196,51,120,129,8,244,56,153,37,180,242,71,\n104,139,35,8,217,192,0,0,240,63,0,0,0,0,51,120,145,8,244,56,153,37,180,242,\n71,104,139,35,8,217,192,0,0,0,64,0,0,0,0,51,120,161,8,244,56,153,37,180,\n242,71,104,139,35,8,217,192,0,0,0,64,0,0,0,0,51,120,177,8,244,56,153,37,\n180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,120,193,8,244,56,153,\n37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,120,209,8,244,56,\n153,37,180,242,71,104,139,35,8,217,192,0,0,16,64,0,0,0,0,51,120,225,8,244,\n56,153,37,180,242,71,104,139,35,8,217,192,0,0,32,64,0,0,0,0,32,227,194,0,\n97,57,162,4,246,40,5,34,92,35,68,225,161,166,219,16,16,137,112,52,41,73,29,\n169,1,65,196,201,197,145,166,153,246,8,3,137,204,120,34,74,8,200,58,128,28,\n211,160,130,52,78,26,26,110,248,0,0,170,4,12,70,137,195,38,0,0,42,68,159,7,\n84,3,154,150,16,70,137,195,67,77,223,0,0,20,224,20,160,152,23,223,0,0,20,\n226,9,65,154,232,147,161,115,59,224,0,2,156,84,12,50,9,195,38,0,0,41,133,\n30,224,32,54,186,221,128,60,\n};\n#else\n#error invalid endianness defines\n#endif\n#endif  /* DUK_USE_ROM_OBJECTS */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_builtins.h",
    "content": "/*\n *  Automatically generated by genbuiltins.py, do not edit!\n */\n\n#if !defined(DUK_BUILTINS_H_INCLUDED)\n#define DUK_BUILTINS_H_INCLUDED\n\n#if defined(DUK_USE_ROM_STRINGS)\n#error ROM support not enabled, rerun configure.py with --rom-support\n#else  /* DUK_USE_ROM_STRINGS */\n#define DUK_STRIDX_UC_UNDEFINED                                       0                              /* 'Undefined' */\n#define DUK_HEAP_STRING_UC_UNDEFINED(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_UNDEFINED)\n#define DUK_HTHREAD_STRING_UC_UNDEFINED(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_UNDEFINED)\n#define DUK_STRIDX_UC_NULL                                            1                              /* 'Null' */\n#define DUK_HEAP_STRING_UC_NULL(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_NULL)\n#define DUK_HTHREAD_STRING_UC_NULL(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_NULL)\n#define DUK_STRIDX_UC_SYMBOL                                          2                              /* 'Symbol' */\n#define DUK_HEAP_STRING_UC_SYMBOL(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_SYMBOL)\n#define DUK_HTHREAD_STRING_UC_SYMBOL(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_SYMBOL)\n#define DUK_STRIDX_UC_ARGUMENTS                                       3                              /* 'Arguments' */\n#define DUK_HEAP_STRING_UC_ARGUMENTS(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_ARGUMENTS)\n#define DUK_HTHREAD_STRING_UC_ARGUMENTS(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_ARGUMENTS)\n#define DUK_STRIDX_UC_OBJECT                                          4                              /* 'Object' */\n#define DUK_HEAP_STRING_UC_OBJECT(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_OBJECT)\n#define DUK_HTHREAD_STRING_UC_OBJECT(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_OBJECT)\n#define DUK_STRIDX_UC_FUNCTION                                        5                              /* 'Function' */\n#define DUK_HEAP_STRING_UC_FUNCTION(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_FUNCTION)\n#define DUK_HTHREAD_STRING_UC_FUNCTION(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_FUNCTION)\n#define DUK_STRIDX_ARRAY                                              6                              /* 'Array' */\n#define DUK_HEAP_STRING_ARRAY(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ARRAY)\n#define DUK_HTHREAD_STRING_ARRAY(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ARRAY)\n#define DUK_STRIDX_UC_STRING                                          7                              /* 'String' */\n#define DUK_HEAP_STRING_UC_STRING(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_STRING)\n#define DUK_HTHREAD_STRING_UC_STRING(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_STRING)\n#define DUK_STRIDX_UC_BOOLEAN                                         8                              /* 'Boolean' */\n#define DUK_HEAP_STRING_UC_BOOLEAN(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_BOOLEAN)\n#define DUK_HTHREAD_STRING_UC_BOOLEAN(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_BOOLEAN)\n#define DUK_STRIDX_UC_NUMBER                                          9                              /* 'Number' */\n#define DUK_HEAP_STRING_UC_NUMBER(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_NUMBER)\n#define DUK_HTHREAD_STRING_UC_NUMBER(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_NUMBER)\n#define DUK_STRIDX_DATE                                               10                             /* 'Date' */\n#define DUK_HEAP_STRING_DATE(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DATE)\n#define DUK_HTHREAD_STRING_DATE(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DATE)\n#define DUK_STRIDX_REG_EXP                                            11                             /* 'RegExp' */\n#define DUK_HEAP_STRING_REG_EXP(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_REG_EXP)\n#define DUK_HTHREAD_STRING_REG_EXP(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_REG_EXP)\n#define DUK_STRIDX_UC_ERROR                                           12                             /* 'Error' */\n#define DUK_HEAP_STRING_UC_ERROR(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_ERROR)\n#define DUK_HTHREAD_STRING_UC_ERROR(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_ERROR)\n#define DUK_STRIDX_MATH                                               13                             /* 'Math' */\n#define DUK_HEAP_STRING_MATH(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MATH)\n#define DUK_HTHREAD_STRING_MATH(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MATH)\n#define DUK_STRIDX_JSON                                               14                             /* 'JSON' */\n#define DUK_HEAP_STRING_JSON(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON)\n#define DUK_HTHREAD_STRING_JSON(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON)\n#define DUK_STRIDX_EMPTY_STRING                                       15                             /* '' */\n#define DUK_HEAP_STRING_EMPTY_STRING(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EMPTY_STRING)\n#define DUK_HTHREAD_STRING_EMPTY_STRING(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EMPTY_STRING)\n#define DUK_STRIDX_ARRAY_BUFFER                                       16                             /* 'ArrayBuffer' */\n#define DUK_HEAP_STRING_ARRAY_BUFFER(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ARRAY_BUFFER)\n#define DUK_HTHREAD_STRING_ARRAY_BUFFER(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ARRAY_BUFFER)\n#define DUK_STRIDX_DATA_VIEW                                          17                             /* 'DataView' */\n#define DUK_HEAP_STRING_DATA_VIEW(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DATA_VIEW)\n#define DUK_HTHREAD_STRING_DATA_VIEW(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DATA_VIEW)\n#define DUK_STRIDX_INT8_ARRAY                                         18                             /* 'Int8Array' */\n#define DUK_HEAP_STRING_INT8_ARRAY(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT8_ARRAY)\n#define DUK_HTHREAD_STRING_INT8_ARRAY(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT8_ARRAY)\n#define DUK_STRIDX_UINT8_ARRAY                                        19                             /* 'Uint8Array' */\n#define DUK_HEAP_STRING_UINT8_ARRAY(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT8_ARRAY)\n#define DUK_HTHREAD_STRING_UINT8_ARRAY(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT8_ARRAY)\n#define DUK_STRIDX_UINT8_CLAMPED_ARRAY                                20                             /* 'Uint8ClampedArray' */\n#define DUK_HEAP_STRING_UINT8_CLAMPED_ARRAY(heap)                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT8_CLAMPED_ARRAY)\n#define DUK_HTHREAD_STRING_UINT8_CLAMPED_ARRAY(thr)                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT8_CLAMPED_ARRAY)\n#define DUK_STRIDX_INT16_ARRAY                                        21                             /* 'Int16Array' */\n#define DUK_HEAP_STRING_INT16_ARRAY(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT16_ARRAY)\n#define DUK_HTHREAD_STRING_INT16_ARRAY(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT16_ARRAY)\n#define DUK_STRIDX_UINT16_ARRAY                                       22                             /* 'Uint16Array' */\n#define DUK_HEAP_STRING_UINT16_ARRAY(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT16_ARRAY)\n#define DUK_HTHREAD_STRING_UINT16_ARRAY(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT16_ARRAY)\n#define DUK_STRIDX_INT32_ARRAY                                        23                             /* 'Int32Array' */\n#define DUK_HEAP_STRING_INT32_ARRAY(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT32_ARRAY)\n#define DUK_HTHREAD_STRING_INT32_ARRAY(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT32_ARRAY)\n#define DUK_STRIDX_UINT32_ARRAY                                       24                             /* 'Uint32Array' */\n#define DUK_HEAP_STRING_UINT32_ARRAY(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UINT32_ARRAY)\n#define DUK_HTHREAD_STRING_UINT32_ARRAY(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UINT32_ARRAY)\n#define DUK_STRIDX_FLOAT32_ARRAY                                      25                             /* 'Float32Array' */\n#define DUK_HEAP_STRING_FLOAT32_ARRAY(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FLOAT32_ARRAY)\n#define DUK_HTHREAD_STRING_FLOAT32_ARRAY(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FLOAT32_ARRAY)\n#define DUK_STRIDX_FLOAT64_ARRAY                                      26                             /* 'Float64Array' */\n#define DUK_HEAP_STRING_FLOAT64_ARRAY(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FLOAT64_ARRAY)\n#define DUK_HTHREAD_STRING_FLOAT64_ARRAY(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FLOAT64_ARRAY)\n#define DUK_STRIDX_GLOBAL                                             27                             /* 'global' */\n#define DUK_HEAP_STRING_GLOBAL(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_GLOBAL)\n#define DUK_HTHREAD_STRING_GLOBAL(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_GLOBAL)\n#define DUK_STRIDX_OBJ_ENV                                            28                             /* 'ObjEnv' */\n#define DUK_HEAP_STRING_OBJ_ENV(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_OBJ_ENV)\n#define DUK_HTHREAD_STRING_OBJ_ENV(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_OBJ_ENV)\n#define DUK_STRIDX_DEC_ENV                                            29                             /* 'DecEnv' */\n#define DUK_HEAP_STRING_DEC_ENV(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEC_ENV)\n#define DUK_HTHREAD_STRING_DEC_ENV(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEC_ENV)\n#define DUK_STRIDX_UC_BUFFER                                          30                             /* 'Buffer' */\n#define DUK_HEAP_STRING_UC_BUFFER(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_BUFFER)\n#define DUK_HTHREAD_STRING_UC_BUFFER(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_BUFFER)\n#define DUK_STRIDX_UC_POINTER                                         31                             /* 'Pointer' */\n#define DUK_HEAP_STRING_UC_POINTER(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_POINTER)\n#define DUK_HTHREAD_STRING_UC_POINTER(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_POINTER)\n#define DUK_STRIDX_UC_THREAD                                          32                             /* 'Thread' */\n#define DUK_HEAP_STRING_UC_THREAD(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_UC_THREAD)\n#define DUK_HTHREAD_STRING_UC_THREAD(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_UC_THREAD)\n#define DUK_STRIDX_EVAL                                               33                             /* 'eval' */\n#define DUK_HEAP_STRING_EVAL(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EVAL)\n#define DUK_HTHREAD_STRING_EVAL(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EVAL)\n#define DUK_STRIDX_VALUE                                              34                             /* 'value' */\n#define DUK_HEAP_STRING_VALUE(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VALUE)\n#define DUK_HTHREAD_STRING_VALUE(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VALUE)\n#define DUK_STRIDX_WRITABLE                                           35                             /* 'writable' */\n#define DUK_HEAP_STRING_WRITABLE(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WRITABLE)\n#define DUK_HTHREAD_STRING_WRITABLE(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WRITABLE)\n#define DUK_STRIDX_CONFIGURABLE                                       36                             /* 'configurable' */\n#define DUK_HEAP_STRING_CONFIGURABLE(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONFIGURABLE)\n#define DUK_HTHREAD_STRING_CONFIGURABLE(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONFIGURABLE)\n#define DUK_STRIDX_ENUMERABLE                                         37                             /* 'enumerable' */\n#define DUK_HEAP_STRING_ENUMERABLE(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENUMERABLE)\n#define DUK_HTHREAD_STRING_ENUMERABLE(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENUMERABLE)\n#define DUK_STRIDX_JOIN                                               38                             /* 'join' */\n#define DUK_HEAP_STRING_JOIN(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JOIN)\n#define DUK_HTHREAD_STRING_JOIN(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JOIN)\n#define DUK_STRIDX_TO_LOCALE_STRING                                   39                             /* 'toLocaleString' */\n#define DUK_HEAP_STRING_TO_LOCALE_STRING(heap)                        DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_LOCALE_STRING)\n#define DUK_HTHREAD_STRING_TO_LOCALE_STRING(thr)                      DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_LOCALE_STRING)\n#define DUK_STRIDX_VALUE_OF                                           40                             /* 'valueOf' */\n#define DUK_HEAP_STRING_VALUE_OF(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VALUE_OF)\n#define DUK_HTHREAD_STRING_VALUE_OF(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VALUE_OF)\n#define DUK_STRIDX_TO_UTC_STRING                                      41                             /* 'toUTCString' */\n#define DUK_HEAP_STRING_TO_UTC_STRING(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_UTC_STRING)\n#define DUK_HTHREAD_STRING_TO_UTC_STRING(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_UTC_STRING)\n#define DUK_STRIDX_TO_ISO_STRING                                      42                             /* 'toISOString' */\n#define DUK_HEAP_STRING_TO_ISO_STRING(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_ISO_STRING)\n#define DUK_HTHREAD_STRING_TO_ISO_STRING(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_ISO_STRING)\n#define DUK_STRIDX_TO_GMT_STRING                                      43                             /* 'toGMTString' */\n#define DUK_HEAP_STRING_TO_GMT_STRING(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_GMT_STRING)\n#define DUK_HTHREAD_STRING_TO_GMT_STRING(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_GMT_STRING)\n#define DUK_STRIDX_SOURCE                                             44                             /* 'source' */\n#define DUK_HEAP_STRING_SOURCE(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SOURCE)\n#define DUK_HTHREAD_STRING_SOURCE(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SOURCE)\n#define DUK_STRIDX_IGNORE_CASE                                        45                             /* 'ignoreCase' */\n#define DUK_HEAP_STRING_IGNORE_CASE(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IGNORE_CASE)\n#define DUK_HTHREAD_STRING_IGNORE_CASE(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IGNORE_CASE)\n#define DUK_STRIDX_MULTILINE                                          46                             /* 'multiline' */\n#define DUK_HEAP_STRING_MULTILINE(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MULTILINE)\n#define DUK_HTHREAD_STRING_MULTILINE(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MULTILINE)\n#define DUK_STRIDX_LAST_INDEX                                         47                             /* 'lastIndex' */\n#define DUK_HEAP_STRING_LAST_INDEX(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LAST_INDEX)\n#define DUK_HTHREAD_STRING_LAST_INDEX(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LAST_INDEX)\n#define DUK_STRIDX_FLAGS                                              48                             /* 'flags' */\n#define DUK_HEAP_STRING_FLAGS(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FLAGS)\n#define DUK_HTHREAD_STRING_FLAGS(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FLAGS)\n#define DUK_STRIDX_INDEX                                              49                             /* 'index' */\n#define DUK_HEAP_STRING_INDEX(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INDEX)\n#define DUK_HTHREAD_STRING_INDEX(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INDEX)\n#define DUK_STRIDX_PROTOTYPE                                          50                             /* 'prototype' */\n#define DUK_HEAP_STRING_PROTOTYPE(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PROTOTYPE)\n#define DUK_HTHREAD_STRING_PROTOTYPE(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PROTOTYPE)\n#define DUK_STRIDX_CONSTRUCTOR                                        51                             /* 'constructor' */\n#define DUK_HEAP_STRING_CONSTRUCTOR(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONSTRUCTOR)\n#define DUK_HTHREAD_STRING_CONSTRUCTOR(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONSTRUCTOR)\n#define DUK_STRIDX_MESSAGE                                            52                             /* 'message' */\n#define DUK_HEAP_STRING_MESSAGE(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MESSAGE)\n#define DUK_HTHREAD_STRING_MESSAGE(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MESSAGE)\n#define DUK_STRIDX_LC_BOOLEAN                                         53                             /* 'boolean' */\n#define DUK_HEAP_STRING_LC_BOOLEAN(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_BOOLEAN)\n#define DUK_HTHREAD_STRING_LC_BOOLEAN(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_BOOLEAN)\n#define DUK_STRIDX_LC_NUMBER                                          54                             /* 'number' */\n#define DUK_HEAP_STRING_LC_NUMBER(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_NUMBER)\n#define DUK_HTHREAD_STRING_LC_NUMBER(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_NUMBER)\n#define DUK_STRIDX_LC_STRING                                          55                             /* 'string' */\n#define DUK_HEAP_STRING_LC_STRING(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_STRING)\n#define DUK_HTHREAD_STRING_LC_STRING(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_STRING)\n#define DUK_STRIDX_LC_SYMBOL                                          56                             /* 'symbol' */\n#define DUK_HEAP_STRING_LC_SYMBOL(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_SYMBOL)\n#define DUK_HTHREAD_STRING_LC_SYMBOL(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_SYMBOL)\n#define DUK_STRIDX_LC_OBJECT                                          57                             /* 'object' */\n#define DUK_HEAP_STRING_LC_OBJECT(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_OBJECT)\n#define DUK_HTHREAD_STRING_LC_OBJECT(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_OBJECT)\n#define DUK_STRIDX_LC_UNDEFINED                                       58                             /* 'undefined' */\n#define DUK_HEAP_STRING_LC_UNDEFINED(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_UNDEFINED)\n#define DUK_HTHREAD_STRING_LC_UNDEFINED(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_UNDEFINED)\n#define DUK_STRIDX_NAN                                                59                             /* 'NaN' */\n#define DUK_HEAP_STRING_NAN(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NAN)\n#define DUK_HTHREAD_STRING_NAN(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NAN)\n#define DUK_STRIDX_INFINITY                                           60                             /* 'Infinity' */\n#define DUK_HEAP_STRING_INFINITY(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INFINITY)\n#define DUK_HTHREAD_STRING_INFINITY(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INFINITY)\n#define DUK_STRIDX_MINUS_INFINITY                                     61                             /* '-Infinity' */\n#define DUK_HEAP_STRING_MINUS_INFINITY(heap)                          DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MINUS_INFINITY)\n#define DUK_HTHREAD_STRING_MINUS_INFINITY(thr)                        DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MINUS_INFINITY)\n#define DUK_STRIDX_MINUS_ZERO                                         62                             /* '-0' */\n#define DUK_HEAP_STRING_MINUS_ZERO(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_MINUS_ZERO)\n#define DUK_HTHREAD_STRING_MINUS_ZERO(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_MINUS_ZERO)\n#define DUK_STRIDX_COMMA                                              63                             /* ',' */\n#define DUK_HEAP_STRING_COMMA(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_COMMA)\n#define DUK_HTHREAD_STRING_COMMA(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_COMMA)\n#define DUK_STRIDX_NEWLINE_4SPACE                                     64                             /* '\\n    ' */\n#define DUK_HEAP_STRING_NEWLINE_4SPACE(heap)                          DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NEWLINE_4SPACE)\n#define DUK_HTHREAD_STRING_NEWLINE_4SPACE(thr)                        DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NEWLINE_4SPACE)\n#define DUK_STRIDX_BRACKETED_ELLIPSIS                                 65                             /* '[...]' */\n#define DUK_HEAP_STRING_BRACKETED_ELLIPSIS(heap)                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BRACKETED_ELLIPSIS)\n#define DUK_HTHREAD_STRING_BRACKETED_ELLIPSIS(thr)                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BRACKETED_ELLIPSIS)\n#define DUK_STRIDX_INVALID_DATE                                       66                             /* 'Invalid Date' */\n#define DUK_HEAP_STRING_INVALID_DATE(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INVALID_DATE)\n#define DUK_HTHREAD_STRING_INVALID_DATE(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INVALID_DATE)\n#define DUK_STRIDX_LC_ARGUMENTS                                       67                             /* 'arguments' */\n#define DUK_HEAP_STRING_LC_ARGUMENTS(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_ARGUMENTS)\n#define DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_ARGUMENTS)\n#define DUK_STRIDX_CALLEE                                             68                             /* 'callee' */\n#define DUK_HEAP_STRING_CALLEE(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CALLEE)\n#define DUK_HTHREAD_STRING_CALLEE(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CALLEE)\n#define DUK_STRIDX_CALLER                                             69                             /* 'caller' */\n#define DUK_HEAP_STRING_CALLER(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CALLER)\n#define DUK_HTHREAD_STRING_CALLER(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CALLER)\n#define DUK_STRIDX_APPLY                                              70                             /* 'apply' */\n#define DUK_HEAP_STRING_APPLY(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_APPLY)\n#define DUK_HTHREAD_STRING_APPLY(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_APPLY)\n#define DUK_STRIDX_CONSTRUCT                                          71                             /* 'construct' */\n#define DUK_HEAP_STRING_CONSTRUCT(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONSTRUCT)\n#define DUK_HTHREAD_STRING_CONSTRUCT(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONSTRUCT)\n#define DUK_STRIDX_DELETE_PROPERTY                                    72                             /* 'deleteProperty' */\n#define DUK_HEAP_STRING_DELETE_PROPERTY(heap)                         DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DELETE_PROPERTY)\n#define DUK_HTHREAD_STRING_DELETE_PROPERTY(thr)                       DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DELETE_PROPERTY)\n#define DUK_STRIDX_GET                                                73                             /* 'get' */\n#define DUK_HEAP_STRING_GET(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_GET)\n#define DUK_HTHREAD_STRING_GET(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_GET)\n#define DUK_STRIDX_HAS                                                74                             /* 'has' */\n#define DUK_HEAP_STRING_HAS(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_HAS)\n#define DUK_HTHREAD_STRING_HAS(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_HAS)\n#define DUK_STRIDX_OWN_KEYS                                           75                             /* 'ownKeys' */\n#define DUK_HEAP_STRING_OWN_KEYS(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_OWN_KEYS)\n#define DUK_HTHREAD_STRING_OWN_KEYS(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_OWN_KEYS)\n#define DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE                      76                             /* '\\x81Symbol.toPrimitive\\xff' */\n#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_TO_PRIMITIVE(heap)           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE)\n#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_TO_PRIMITIVE(thr)         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE)\n#define DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE                      77                             /* '\\x81Symbol.hasInstance\\xff' */\n#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_HAS_INSTANCE(heap)           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE)\n#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_HAS_INSTANCE(thr)         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE)\n#define DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG                     78                             /* '\\x81Symbol.toStringTag\\xff' */\n#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_TO_STRING_TAG(heap)          DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG)\n#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_TO_STRING_TAG(thr)        DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG)\n#define DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE              79                             /* '\\x81Symbol.isConcatSpreadable\\xff' */\n#define DUK_HEAP_STRING_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE(heap)   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE)\n#define DUK_HTHREAD_STRING_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE(thr)  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE)\n#define DUK_STRIDX_SET_PROTOTYPE_OF                                   80                             /* 'setPrototypeOf' */\n#define DUK_HEAP_STRING_SET_PROTOTYPE_OF(heap)                        DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SET_PROTOTYPE_OF)\n#define DUK_HTHREAD_STRING_SET_PROTOTYPE_OF(thr)                      DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SET_PROTOTYPE_OF)\n#define DUK_STRIDX___PROTO__                                          81                             /* '__proto__' */\n#define DUK_HEAP_STRING___PROTO__(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX___PROTO__)\n#define DUK_HTHREAD_STRING___PROTO__(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX___PROTO__)\n#define DUK_STRIDX_TO_STRING                                          82                             /* 'toString' */\n#define DUK_HEAP_STRING_TO_STRING(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_STRING)\n#define DUK_HTHREAD_STRING_TO_STRING(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_STRING)\n#define DUK_STRIDX_TO_JSON                                            83                             /* 'toJSON' */\n#define DUK_HEAP_STRING_TO_JSON(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TO_JSON)\n#define DUK_HTHREAD_STRING_TO_JSON(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TO_JSON)\n#define DUK_STRIDX_TYPE                                               84                             /* 'type' */\n#define DUK_HEAP_STRING_TYPE(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TYPE)\n#define DUK_HTHREAD_STRING_TYPE(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TYPE)\n#define DUK_STRIDX_DATA                                               85                             /* 'data' */\n#define DUK_HEAP_STRING_DATA(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DATA)\n#define DUK_HTHREAD_STRING_DATA(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DATA)\n#define DUK_STRIDX_LENGTH                                             86                             /* 'length' */\n#define DUK_HEAP_STRING_LENGTH(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LENGTH)\n#define DUK_HTHREAD_STRING_LENGTH(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LENGTH)\n#define DUK_STRIDX_SET                                                87                             /* 'set' */\n#define DUK_HEAP_STRING_SET(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SET)\n#define DUK_HTHREAD_STRING_SET(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SET)\n#define DUK_STRIDX_STACK                                              88                             /* 'stack' */\n#define DUK_HEAP_STRING_STACK(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_STACK)\n#define DUK_HTHREAD_STRING_STACK(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_STACK)\n#define DUK_STRIDX_PC                                                 89                             /* 'pc' */\n#define DUK_HEAP_STRING_PC(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PC)\n#define DUK_HTHREAD_STRING_PC(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PC)\n#define DUK_STRIDX_LINE_NUMBER                                        90                             /* 'lineNumber' */\n#define DUK_HEAP_STRING_LINE_NUMBER(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LINE_NUMBER)\n#define DUK_HTHREAD_STRING_LINE_NUMBER(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LINE_NUMBER)\n#define DUK_STRIDX_INT_TRACEDATA                                      91                             /* '\\x82Tracedata' */\n#define DUK_HEAP_STRING_INT_TRACEDATA(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_TRACEDATA)\n#define DUK_HTHREAD_STRING_INT_TRACEDATA(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_TRACEDATA)\n#define DUK_STRIDX_NAME                                               92                             /* 'name' */\n#define DUK_HEAP_STRING_NAME(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NAME)\n#define DUK_HTHREAD_STRING_NAME(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NAME)\n#define DUK_STRIDX_FILE_NAME                                          93                             /* 'fileName' */\n#define DUK_HEAP_STRING_FILE_NAME(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FILE_NAME)\n#define DUK_HTHREAD_STRING_FILE_NAME(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FILE_NAME)\n#define DUK_STRIDX_LC_POINTER                                         94                             /* 'pointer' */\n#define DUK_HEAP_STRING_LC_POINTER(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_POINTER)\n#define DUK_HTHREAD_STRING_LC_POINTER(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_POINTER)\n#define DUK_STRIDX_INT_TARGET                                         95                             /* '\\x82Target' */\n#define DUK_HEAP_STRING_INT_TARGET(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_TARGET)\n#define DUK_HTHREAD_STRING_INT_TARGET(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_TARGET)\n#define DUK_STRIDX_INT_NEXT                                           96                             /* '\\x82Next' */\n#define DUK_HEAP_STRING_INT_NEXT(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_NEXT)\n#define DUK_HTHREAD_STRING_INT_NEXT(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_NEXT)\n#define DUK_STRIDX_INT_BYTECODE                                       97                             /* '\\x82Bytecode' */\n#define DUK_HEAP_STRING_INT_BYTECODE(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_BYTECODE)\n#define DUK_HTHREAD_STRING_INT_BYTECODE(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_BYTECODE)\n#define DUK_STRIDX_INT_FORMALS                                        98                             /* '\\x82Formals' */\n#define DUK_HEAP_STRING_INT_FORMALS(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_FORMALS)\n#define DUK_HTHREAD_STRING_INT_FORMALS(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_FORMALS)\n#define DUK_STRIDX_INT_VARMAP                                         99                             /* '\\x82Varmap' */\n#define DUK_HEAP_STRING_INT_VARMAP(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VARMAP)\n#define DUK_HTHREAD_STRING_INT_VARMAP(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VARMAP)\n#define DUK_STRIDX_INT_SOURCE                                         100                            /* '\\x82Source' */\n#define DUK_HEAP_STRING_INT_SOURCE(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_SOURCE)\n#define DUK_HTHREAD_STRING_INT_SOURCE(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_SOURCE)\n#define DUK_STRIDX_INT_PC2LINE                                        101                            /* '\\x82Pc2line' */\n#define DUK_HEAP_STRING_INT_PC2LINE(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_PC2LINE)\n#define DUK_HTHREAD_STRING_INT_PC2LINE(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_PC2LINE)\n#define DUK_STRIDX_INT_MAP                                            102                            /* '\\x82Map' */\n#define DUK_HEAP_STRING_INT_MAP(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_MAP)\n#define DUK_HTHREAD_STRING_INT_MAP(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_MAP)\n#define DUK_STRIDX_INT_VARENV                                         103                            /* '\\x82Varenv' */\n#define DUK_HEAP_STRING_INT_VARENV(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VARENV)\n#define DUK_HTHREAD_STRING_INT_VARENV(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VARENV)\n#define DUK_STRIDX_INT_FINALIZER                                      104                            /* '\\x82Finalizer' */\n#define DUK_HEAP_STRING_INT_FINALIZER(heap)                           DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_FINALIZER)\n#define DUK_HTHREAD_STRING_INT_FINALIZER(thr)                         DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_FINALIZER)\n#define DUK_STRIDX_INT_VALUE                                          105                            /* '\\x82Value' */\n#define DUK_HEAP_STRING_INT_VALUE(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INT_VALUE)\n#define DUK_HTHREAD_STRING_INT_VALUE(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INT_VALUE)\n#define DUK_STRIDX_COMPILE                                            106                            /* 'compile' */\n#define DUK_HEAP_STRING_COMPILE(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_COMPILE)\n#define DUK_HTHREAD_STRING_COMPILE(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_COMPILE)\n#define DUK_STRIDX_INPUT                                              107                            /* 'input' */\n#define DUK_HEAP_STRING_INPUT(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INPUT)\n#define DUK_HTHREAD_STRING_INPUT(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INPUT)\n#define DUK_STRIDX_ERR_CREATE                                         108                            /* 'errCreate' */\n#define DUK_HEAP_STRING_ERR_CREATE(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ERR_CREATE)\n#define DUK_HTHREAD_STRING_ERR_CREATE(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ERR_CREATE)\n#define DUK_STRIDX_ERR_THROW                                          109                            /* 'errThrow' */\n#define DUK_HEAP_STRING_ERR_THROW(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ERR_THROW)\n#define DUK_HTHREAD_STRING_ERR_THROW(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ERR_THROW)\n#define DUK_STRIDX_ENV                                                110                            /* 'env' */\n#define DUK_HEAP_STRING_ENV(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENV)\n#define DUK_HTHREAD_STRING_ENV(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENV)\n#define DUK_STRIDX_HEX                                                111                            /* 'hex' */\n#define DUK_HEAP_STRING_HEX(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_HEX)\n#define DUK_HTHREAD_STRING_HEX(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_HEX)\n#define DUK_STRIDX_BASE64                                             112                            /* 'base64' */\n#define DUK_HEAP_STRING_BASE64(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BASE64)\n#define DUK_HTHREAD_STRING_BASE64(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BASE64)\n#define DUK_STRIDX_JX                                                 113                            /* 'jx' */\n#define DUK_HEAP_STRING_JX(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JX)\n#define DUK_HTHREAD_STRING_JX(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JX)\n#define DUK_STRIDX_JC                                                 114                            /* 'jc' */\n#define DUK_HEAP_STRING_JC(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JC)\n#define DUK_HTHREAD_STRING_JC(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JC)\n#define DUK_STRIDX_JSON_EXT_UNDEFINED                                 115                            /* '{\"_undef\":true}' */\n#define DUK_HEAP_STRING_JSON_EXT_UNDEFINED(heap)                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_UNDEFINED)\n#define DUK_HTHREAD_STRING_JSON_EXT_UNDEFINED(thr)                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_UNDEFINED)\n#define DUK_STRIDX_JSON_EXT_NAN                                       116                            /* '{\"_nan\":true}' */\n#define DUK_HEAP_STRING_JSON_EXT_NAN(heap)                            DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_NAN)\n#define DUK_HTHREAD_STRING_JSON_EXT_NAN(thr)                          DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_NAN)\n#define DUK_STRIDX_JSON_EXT_POSINF                                    117                            /* '{\"_inf\":true}' */\n#define DUK_HEAP_STRING_JSON_EXT_POSINF(heap)                         DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_POSINF)\n#define DUK_HTHREAD_STRING_JSON_EXT_POSINF(thr)                       DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_POSINF)\n#define DUK_STRIDX_JSON_EXT_NEGINF                                    118                            /* '{\"_ninf\":true}' */\n#define DUK_HEAP_STRING_JSON_EXT_NEGINF(heap)                         DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_NEGINF)\n#define DUK_HTHREAD_STRING_JSON_EXT_NEGINF(thr)                       DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_NEGINF)\n#define DUK_STRIDX_JSON_EXT_FUNCTION1                                 119                            /* '{\"_func\":true}' */\n#define DUK_HEAP_STRING_JSON_EXT_FUNCTION1(heap)                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_FUNCTION1)\n#define DUK_HTHREAD_STRING_JSON_EXT_FUNCTION1(thr)                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_FUNCTION1)\n#define DUK_STRIDX_JSON_EXT_FUNCTION2                                 120                            /* '{_func:true}' */\n#define DUK_HEAP_STRING_JSON_EXT_FUNCTION2(heap)                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_JSON_EXT_FUNCTION2)\n#define DUK_HTHREAD_STRING_JSON_EXT_FUNCTION2(thr)                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_JSON_EXT_FUNCTION2)\n#define DUK_STRIDX_BREAK                                              121                            /* 'break' */\n#define DUK_HEAP_STRING_BREAK(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_BREAK)\n#define DUK_HTHREAD_STRING_BREAK(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_BREAK)\n#define DUK_STRIDX_CASE                                               122                            /* 'case' */\n#define DUK_HEAP_STRING_CASE(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CASE)\n#define DUK_HTHREAD_STRING_CASE(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CASE)\n#define DUK_STRIDX_CATCH                                              123                            /* 'catch' */\n#define DUK_HEAP_STRING_CATCH(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CATCH)\n#define DUK_HTHREAD_STRING_CATCH(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CATCH)\n#define DUK_STRIDX_CONTINUE                                           124                            /* 'continue' */\n#define DUK_HEAP_STRING_CONTINUE(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONTINUE)\n#define DUK_HTHREAD_STRING_CONTINUE(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONTINUE)\n#define DUK_STRIDX_DEBUGGER                                           125                            /* 'debugger' */\n#define DUK_HEAP_STRING_DEBUGGER(heap)                                DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEBUGGER)\n#define DUK_HTHREAD_STRING_DEBUGGER(thr)                              DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEBUGGER)\n#define DUK_STRIDX_DEFAULT                                            126                            /* 'default' */\n#define DUK_HEAP_STRING_DEFAULT(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DEFAULT)\n#define DUK_HTHREAD_STRING_DEFAULT(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DEFAULT)\n#define DUK_STRIDX_DELETE                                             127                            /* 'delete' */\n#define DUK_HEAP_STRING_DELETE(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DELETE)\n#define DUK_HTHREAD_STRING_DELETE(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DELETE)\n#define DUK_STRIDX_DO                                                 128                            /* 'do' */\n#define DUK_HEAP_STRING_DO(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_DO)\n#define DUK_HTHREAD_STRING_DO(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_DO)\n#define DUK_STRIDX_ELSE                                               129                            /* 'else' */\n#define DUK_HEAP_STRING_ELSE(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ELSE)\n#define DUK_HTHREAD_STRING_ELSE(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ELSE)\n#define DUK_STRIDX_FINALLY                                            130                            /* 'finally' */\n#define DUK_HEAP_STRING_FINALLY(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FINALLY)\n#define DUK_HTHREAD_STRING_FINALLY(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FINALLY)\n#define DUK_STRIDX_FOR                                                131                            /* 'for' */\n#define DUK_HEAP_STRING_FOR(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FOR)\n#define DUK_HTHREAD_STRING_FOR(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FOR)\n#define DUK_STRIDX_LC_FUNCTION                                        132                            /* 'function' */\n#define DUK_HEAP_STRING_LC_FUNCTION(heap)                             DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_FUNCTION)\n#define DUK_HTHREAD_STRING_LC_FUNCTION(thr)                           DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_FUNCTION)\n#define DUK_STRIDX_IF                                                 133                            /* 'if' */\n#define DUK_HEAP_STRING_IF(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IF)\n#define DUK_HTHREAD_STRING_IF(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IF)\n#define DUK_STRIDX_IN                                                 134                            /* 'in' */\n#define DUK_HEAP_STRING_IN(heap)                                      DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IN)\n#define DUK_HTHREAD_STRING_IN(thr)                                    DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IN)\n#define DUK_STRIDX_INSTANCEOF                                         135                            /* 'instanceof' */\n#define DUK_HEAP_STRING_INSTANCEOF(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INSTANCEOF)\n#define DUK_HTHREAD_STRING_INSTANCEOF(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INSTANCEOF)\n#define DUK_STRIDX_NEW                                                136                            /* 'new' */\n#define DUK_HEAP_STRING_NEW(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_NEW)\n#define DUK_HTHREAD_STRING_NEW(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_NEW)\n#define DUK_STRIDX_RETURN                                             137                            /* 'return' */\n#define DUK_HEAP_STRING_RETURN(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_RETURN)\n#define DUK_HTHREAD_STRING_RETURN(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_RETURN)\n#define DUK_STRIDX_SWITCH                                             138                            /* 'switch' */\n#define DUK_HEAP_STRING_SWITCH(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SWITCH)\n#define DUK_HTHREAD_STRING_SWITCH(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SWITCH)\n#define DUK_STRIDX_THIS                                               139                            /* 'this' */\n#define DUK_HEAP_STRING_THIS(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_THIS)\n#define DUK_HTHREAD_STRING_THIS(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_THIS)\n#define DUK_STRIDX_THROW                                              140                            /* 'throw' */\n#define DUK_HEAP_STRING_THROW(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_THROW)\n#define DUK_HTHREAD_STRING_THROW(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_THROW)\n#define DUK_STRIDX_TRY                                                141                            /* 'try' */\n#define DUK_HEAP_STRING_TRY(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TRY)\n#define DUK_HTHREAD_STRING_TRY(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TRY)\n#define DUK_STRIDX_TYPEOF                                             142                            /* 'typeof' */\n#define DUK_HEAP_STRING_TYPEOF(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TYPEOF)\n#define DUK_HTHREAD_STRING_TYPEOF(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TYPEOF)\n#define DUK_STRIDX_VAR                                                143                            /* 'var' */\n#define DUK_HEAP_STRING_VAR(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VAR)\n#define DUK_HTHREAD_STRING_VAR(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VAR)\n#define DUK_STRIDX_CONST                                              144                            /* 'const' */\n#define DUK_HEAP_STRING_CONST(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CONST)\n#define DUK_HTHREAD_STRING_CONST(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CONST)\n#define DUK_STRIDX_VOID                                               145                            /* 'void' */\n#define DUK_HEAP_STRING_VOID(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_VOID)\n#define DUK_HTHREAD_STRING_VOID(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_VOID)\n#define DUK_STRIDX_WHILE                                              146                            /* 'while' */\n#define DUK_HEAP_STRING_WHILE(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WHILE)\n#define DUK_HTHREAD_STRING_WHILE(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WHILE)\n#define DUK_STRIDX_WITH                                               147                            /* 'with' */\n#define DUK_HEAP_STRING_WITH(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_WITH)\n#define DUK_HTHREAD_STRING_WITH(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_WITH)\n#define DUK_STRIDX_CLASS                                              148                            /* 'class' */\n#define DUK_HEAP_STRING_CLASS(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_CLASS)\n#define DUK_HTHREAD_STRING_CLASS(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_CLASS)\n#define DUK_STRIDX_ENUM                                               149                            /* 'enum' */\n#define DUK_HEAP_STRING_ENUM(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_ENUM)\n#define DUK_HTHREAD_STRING_ENUM(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_ENUM)\n#define DUK_STRIDX_EXPORT                                             150                            /* 'export' */\n#define DUK_HEAP_STRING_EXPORT(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EXPORT)\n#define DUK_HTHREAD_STRING_EXPORT(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EXPORT)\n#define DUK_STRIDX_EXTENDS                                            151                            /* 'extends' */\n#define DUK_HEAP_STRING_EXTENDS(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_EXTENDS)\n#define DUK_HTHREAD_STRING_EXTENDS(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_EXTENDS)\n#define DUK_STRIDX_IMPORT                                             152                            /* 'import' */\n#define DUK_HEAP_STRING_IMPORT(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IMPORT)\n#define DUK_HTHREAD_STRING_IMPORT(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IMPORT)\n#define DUK_STRIDX_SUPER                                              153                            /* 'super' */\n#define DUK_HEAP_STRING_SUPER(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_SUPER)\n#define DUK_HTHREAD_STRING_SUPER(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_SUPER)\n#define DUK_STRIDX_LC_NULL                                            154                            /* 'null' */\n#define DUK_HEAP_STRING_LC_NULL(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LC_NULL)\n#define DUK_HTHREAD_STRING_LC_NULL(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LC_NULL)\n#define DUK_STRIDX_TRUE                                               155                            /* 'true' */\n#define DUK_HEAP_STRING_TRUE(heap)                                    DUK_HEAP_GET_STRING((heap),DUK_STRIDX_TRUE)\n#define DUK_HTHREAD_STRING_TRUE(thr)                                  DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_TRUE)\n#define DUK_STRIDX_FALSE                                              156                            /* 'false' */\n#define DUK_HEAP_STRING_FALSE(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_FALSE)\n#define DUK_HTHREAD_STRING_FALSE(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_FALSE)\n#define DUK_STRIDX_IMPLEMENTS                                         157                            /* 'implements' */\n#define DUK_HEAP_STRING_IMPLEMENTS(heap)                              DUK_HEAP_GET_STRING((heap),DUK_STRIDX_IMPLEMENTS)\n#define DUK_HTHREAD_STRING_IMPLEMENTS(thr)                            DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_IMPLEMENTS)\n#define DUK_STRIDX_INTERFACE                                          158                            /* 'interface' */\n#define DUK_HEAP_STRING_INTERFACE(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_INTERFACE)\n#define DUK_HTHREAD_STRING_INTERFACE(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_INTERFACE)\n#define DUK_STRIDX_LET                                                159                            /* 'let' */\n#define DUK_HEAP_STRING_LET(heap)                                     DUK_HEAP_GET_STRING((heap),DUK_STRIDX_LET)\n#define DUK_HTHREAD_STRING_LET(thr)                                   DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_LET)\n#define DUK_STRIDX_PACKAGE                                            160                            /* 'package' */\n#define DUK_HEAP_STRING_PACKAGE(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PACKAGE)\n#define DUK_HTHREAD_STRING_PACKAGE(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PACKAGE)\n#define DUK_STRIDX_PRIVATE                                            161                            /* 'private' */\n#define DUK_HEAP_STRING_PRIVATE(heap)                                 DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PRIVATE)\n#define DUK_HTHREAD_STRING_PRIVATE(thr)                               DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PRIVATE)\n#define DUK_STRIDX_PROTECTED                                          162                            /* 'protected' */\n#define DUK_HEAP_STRING_PROTECTED(heap)                               DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PROTECTED)\n#define DUK_HTHREAD_STRING_PROTECTED(thr)                             DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PROTECTED)\n#define DUK_STRIDX_PUBLIC                                             163                            /* 'public' */\n#define DUK_HEAP_STRING_PUBLIC(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_PUBLIC)\n#define DUK_HTHREAD_STRING_PUBLIC(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_PUBLIC)\n#define DUK_STRIDX_STATIC                                             164                            /* 'static' */\n#define DUK_HEAP_STRING_STATIC(heap)                                  DUK_HEAP_GET_STRING((heap),DUK_STRIDX_STATIC)\n#define DUK_HTHREAD_STRING_STATIC(thr)                                DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_STATIC)\n#define DUK_STRIDX_YIELD                                              165                            /* 'yield' */\n#define DUK_HEAP_STRING_YIELD(heap)                                   DUK_HEAP_GET_STRING((heap),DUK_STRIDX_YIELD)\n#define DUK_HTHREAD_STRING_YIELD(thr)                                 DUK_HTHREAD_GET_STRING((thr),DUK_STRIDX_YIELD)\n\n#define DUK_HEAP_NUM_STRINGS                                          166\n#define DUK_STRIDX_START_RESERVED                                     121\n#define DUK_STRIDX_START_STRICT_RESERVED                              157\n#define DUK_STRIDX_END_RESERVED                                       166                            /* exclusive endpoint */\n\n/* To convert a heap stridx to a token number, subtract\n * DUK_STRIDX_START_RESERVED and add DUK_TOK_START_RESERVED.\n */\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_strings_data[967];\n#endif  /* !DUK_SINGLE_FILE */\n#define DUK_STRDATA_MAX_STRLEN                                        27\n#define DUK_STRDATA_DATA_LENGTH                                       967\n#endif  /* DUK_USE_ROM_STRINGS */\n\n#if defined(DUK_USE_ROM_OBJECTS)\n#error RAM support not enabled, rerun configure.py with --ram-support\n#else  /* DUK_USE_ROM_OBJECTS */\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_boolean_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_constructor_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_type_error_thrower(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_parse_int(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_parse_float(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_thread_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_pointer_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_proxy_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_constructor_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_arraybuffer_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_dataview_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_constructor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_eval(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_is_nan(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_is_finite(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_decode_uri(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_decode_uri_component(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_encode_uri(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_encode_uri_component(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_escape(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_global_object_unescape(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_getprototype_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_setprototype_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_get_own_property_descriptor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_keys_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_assign(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_create(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_define_property(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_define_properties(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_seal_freeze_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_prevent_extensions(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_is_sealed_frozen_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_is_extensible(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_constructor_is(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_locale_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_value_of(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_has_own_property(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_is_prototype_of(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_property_is_enumerable(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_defineaccessor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_lookupaccessor(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_apply(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_call(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_bind(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype_hasinstance(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_native_function_length(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_native_function_name(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_constructor_is_array(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_join_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_concat(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_pop(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_push(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_reverse(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_shift(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_slice(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_sort(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_splice(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_unshift(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_indexof_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_iter_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_array_prototype_reduce_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_constructor_from_char_code(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_constructor_from_code_point(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_char_at(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_char_code_at(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_concat(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_indexof_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_locale_compare(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_match(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_replace(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_search(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_slice(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_split(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_substring(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_caseconv_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_trim(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_repeat(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_includes(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_string_prototype_substr(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_boolean_prototype_tostring_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_check_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_locale_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_value_of(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_fixed(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_exponential(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_number_prototype_to_precision(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor_parse(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor_utc(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_constructor_now(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_tostring_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_to_json(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_value_of(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_get_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_get_timezone_offset(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_set_time(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_set_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_date_prototype_toprimitive(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_exec(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_test(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_tostring(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_flags(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_regexp_prototype_shared_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_stack_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_stack_setter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_filename_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_filename_setter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_linenumber_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_linenumber_setter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_error_prototype_to_string(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_onearg_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_twoarg_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_clz32(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_hypot(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_imul(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_max(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_min(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_random(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_math_object_sign(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_json_object_parse(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_json_object_stringify(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_info(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_act(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_gc(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_fin(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_enc(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_dec(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_duktape_object_compact(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_thread_yield(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_thread_resume(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_thread_current(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_pointer_prototype_tostring_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_apply(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_construct(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_delete_property(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_get(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_has(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_reflect_object_set(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_key_for(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_tostring_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_symbol_toprimitive(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_arraybuffer_isview(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_bytelength_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_slice_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_byteoffset_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_buffer_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_readfield(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_writefield(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_typedarray_set(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_uint8array_allocplain(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_uint8array_plainof(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_concat(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_is_encoding(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_is_buffer(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_byte_length(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_buffer_compare_shared(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_tostring(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_tojson(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_fill(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_copy(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_nodejs_buffer_write(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_prototype_encoding_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textencoder_prototype_encode(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_shared_getter(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_textdecoder_prototype_decode(duk_context *ctx);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_performance_now(duk_context *ctx);\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[183];\n#endif  /* !DUK_SINGLE_FILE */\n#define DUK_BIDX_GLOBAL                                               0\n#define DUK_BIDX_GLOBAL_ENV                                           1\n#define DUK_BIDX_OBJECT_CONSTRUCTOR                                   2\n#define DUK_BIDX_OBJECT_PROTOTYPE                                     3\n#define DUK_BIDX_FUNCTION_CONSTRUCTOR                                 4\n#define DUK_BIDX_FUNCTION_PROTOTYPE                                   5\n#define DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE                            6\n#define DUK_BIDX_ARRAY_CONSTRUCTOR                                    7\n#define DUK_BIDX_ARRAY_PROTOTYPE                                      8\n#define DUK_BIDX_STRING_CONSTRUCTOR                                   9\n#define DUK_BIDX_STRING_PROTOTYPE                                     10\n#define DUK_BIDX_BOOLEAN_CONSTRUCTOR                                  11\n#define DUK_BIDX_BOOLEAN_PROTOTYPE                                    12\n#define DUK_BIDX_NUMBER_CONSTRUCTOR                                   13\n#define DUK_BIDX_NUMBER_PROTOTYPE                                     14\n#define DUK_BIDX_DATE_CONSTRUCTOR                                     15\n#define DUK_BIDX_DATE_PROTOTYPE                                       16\n#define DUK_BIDX_REGEXP_CONSTRUCTOR                                   17\n#define DUK_BIDX_REGEXP_PROTOTYPE                                     18\n#define DUK_BIDX_ERROR_CONSTRUCTOR                                    19\n#define DUK_BIDX_ERROR_PROTOTYPE                                      20\n#define DUK_BIDX_EVAL_ERROR_CONSTRUCTOR                               21\n#define DUK_BIDX_EVAL_ERROR_PROTOTYPE                                 22\n#define DUK_BIDX_RANGE_ERROR_CONSTRUCTOR                              23\n#define DUK_BIDX_RANGE_ERROR_PROTOTYPE                                24\n#define DUK_BIDX_REFERENCE_ERROR_CONSTRUCTOR                          25\n#define DUK_BIDX_REFERENCE_ERROR_PROTOTYPE                            26\n#define DUK_BIDX_SYNTAX_ERROR_CONSTRUCTOR                             27\n#define DUK_BIDX_SYNTAX_ERROR_PROTOTYPE                               28\n#define DUK_BIDX_TYPE_ERROR_CONSTRUCTOR                               29\n#define DUK_BIDX_TYPE_ERROR_PROTOTYPE                                 30\n#define DUK_BIDX_URI_ERROR_CONSTRUCTOR                                31\n#define DUK_BIDX_URI_ERROR_PROTOTYPE                                  32\n#define DUK_BIDX_TYPE_ERROR_THROWER                                   33\n#define DUK_BIDX_DUKTAPE                                              34\n#define DUK_BIDX_THREAD_PROTOTYPE                                     35\n#define DUK_BIDX_POINTER_PROTOTYPE                                    36\n#define DUK_BIDX_DOUBLE_ERROR                                         37\n#define DUK_BIDX_SYMBOL_PROTOTYPE                                     38\n#define DUK_BIDX_ARRAYBUFFER_PROTOTYPE                                39\n#define DUK_BIDX_DATAVIEW_PROTOTYPE                                   40\n#define DUK_BIDX_INT8ARRAY_PROTOTYPE                                  41\n#define DUK_BIDX_UINT8ARRAY_PROTOTYPE                                 42\n#define DUK_BIDX_UINT8CLAMPEDARRAY_PROTOTYPE                          43\n#define DUK_BIDX_INT16ARRAY_PROTOTYPE                                 44\n#define DUK_BIDX_UINT16ARRAY_PROTOTYPE                                45\n#define DUK_BIDX_INT32ARRAY_PROTOTYPE                                 46\n#define DUK_BIDX_UINT32ARRAY_PROTOTYPE                                47\n#define DUK_BIDX_FLOAT32ARRAY_PROTOTYPE                               48\n#define DUK_BIDX_FLOAT64ARRAY_PROTOTYPE                               49\n#define DUK_BIDX_NODEJS_BUFFER_PROTOTYPE                              50\n#define DUK_NUM_BUILTINS                                              51\n#define DUK_NUM_BIDX_BUILTINS                                         51\n#define DUK_NUM_ALL_BUILTINS                                          79\n#if defined(DUK_USE_DOUBLE_LE)\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4251];\n#endif  /* !DUK_SINGLE_FILE */\n#define DUK_BUILTINS_DATA_LENGTH                                      4251\n#elif defined(DUK_USE_DOUBLE_BE)\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4251];\n#endif  /* !DUK_SINGLE_FILE */\n#define DUK_BUILTINS_DATA_LENGTH                                      4251\n#elif defined(DUK_USE_DOUBLE_ME)\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[4251];\n#endif  /* !DUK_SINGLE_FILE */\n#define DUK_BUILTINS_DATA_LENGTH                                      4251\n#else\n#error invalid endianness defines\n#endif\n#endif  /* DUK_USE_ROM_OBJECTS */\n#endif  /* DUK_BUILTINS_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_config.h",
    "content": "/*\n *  duk_config.h configuration header generated by genconfig.py.\n *\n *  Git commit: d4f2cff1c592d70f58bab8e1bd85705174c02a58\n *  Git describe: v2.4.0\n *  Git branch: master\n *\n *  Supported platforms:\n *      - Mac OSX, iPhone, Darwin\n *      - Orbis\n *      - OpenBSD\n *      - Generic BSD\n *      - Atari ST TOS\n *      - AmigaOS\n *      - Durango (XboxOne)\n *      - Windows\n *      - Flashplayer (Crossbridge)\n *      - QNX\n *      - TI-Nspire\n *      - Emscripten\n *      - Android\n *      - Linux\n *      - Solaris\n *      - AIX\n *      - HPUX\n *      - Generic POSIX\n *      - Cygwin\n *      - Generic UNIX\n *      - Generic fallback\n *\n *  Supported architectures:\n *      - x86\n *      - x64\n *      - x32\n *      - ARM 32-bit\n *      - ARM 64-bit\n *      - MIPS 32-bit\n *      - MIPS 64-bit\n *      - PowerPC 32-bit\n *      - PowerPC 64-bit\n *      - SPARC 32-bit\n *      - SPARC 64-bit\n *      - SuperH\n *      - Motorola 68k\n *      - Emscripten\n *      - Generic\n *\n *  Supported compilers:\n *      - Clang\n *      - GCC\n *      - MSVC\n *      - Emscripten\n *      - TinyC\n *      - VBCC\n *      - Bruce's C compiler\n *      - Generic\n *\n */\n\n#if !defined(DUK_CONFIG_H_INCLUDED)\n#define DUK_CONFIG_H_INCLUDED\n\n/*\n *  Intermediate helper defines\n */\n\n/* DLL build detection */\n/* not configured for DLL build */\n#undef DUK_F_DLL_BUILD\n\n/* Apple OSX, iOS */\n#if defined(__APPLE__)\n#define DUK_F_APPLE\n#endif\n\n/* FreeBSD */\n#if defined(__FreeBSD__) || defined(__FreeBSD)\n#define DUK_F_FREEBSD\n#endif\n\n/* Orbis (PS4) variant */\n#if defined(DUK_F_FREEBSD) && defined(__ORBIS__)\n#define DUK_F_ORBIS\n#endif\n\n/* OpenBSD */\n#if defined(__OpenBSD__) || defined(__OpenBSD)\n#define DUK_F_OPENBSD\n#endif\n\n/* NetBSD */\n#if defined(__NetBSD__) || defined(__NetBSD)\n#define DUK_F_NETBSD\n#endif\n\n/* BSD variant */\n#if defined(DUK_F_FREEBSD) || defined(DUK_F_NETBSD) || defined(DUK_F_OPENBSD) || \\\n    defined(__bsdi__) || defined(__DragonFly__)\n#define DUK_F_BSD\n#endif\n\n/* Atari ST TOS.  __TOS__ defined by PureC.  No platform define in VBCC\n * apparently, so to use with VBCC user must define __TOS__ manually.\n  */\n#if defined(__TOS__)\n#define DUK_F_TOS\n#endif\n\n/* Motorola 68K.  Not defined by VBCC, so user must define one of these\n * manually when using VBCC.\n */\n#if defined(__m68k__) || defined(M68000) || defined(__MC68K__)\n#define DUK_F_M68K\n#endif\n\n/* AmigaOS.  Neither AMIGA nor __amigaos__ is defined on VBCC, so user must\n * define 'AMIGA' manually when using VBCC.\n */\n#if defined(AMIGA) || defined(__amigaos__)\n#define DUK_F_AMIGAOS\n#endif\n\n/* PowerPC */\n#if defined(__powerpc) || defined(__powerpc__) || defined(__PPC__)\n#define DUK_F_PPC\n#if defined(__PPC64__) || defined(__LP64__) || defined(_LP64)\n#define DUK_F_PPC64\n#else\n#define DUK_F_PPC32\n#endif\n#endif\n\n/* Durango (Xbox One) */\n#if defined(_DURANGO) || defined(_XBOX_ONE)\n#define DUK_F_DURANGO\n#endif\n\n/* Windows, both 32-bit and 64-bit */\n#if defined(_WIN32) || defined(WIN32) || defined(_WIN64) || defined(WIN64) || \\\n    defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__)\n#define DUK_F_WINDOWS\n#if defined(_WIN64) || defined(WIN64)\n#define DUK_F_WIN64\n#else\n#define DUK_F_WIN32\n#endif\n#endif\n\n/* Flash player (e.g. Crossbridge) */\n#if defined(__FLASHPLAYER__)\n#define DUK_F_FLASHPLAYER\n#endif\n\n/* QNX */\n#if defined(__QNX__)\n#define DUK_F_QNX\n#endif\n\n/* TI-Nspire (using Ndless) */\n#if defined(_TINSPIRE)\n#define DUK_F_TINSPIRE\n#endif\n\n/* Emscripten (provided explicitly by user), improve if possible */\n#if defined(EMSCRIPTEN)\n#define DUK_F_EMSCRIPTEN\n#endif\n\n/* BCC (Bruce's C compiler): this is a \"torture target\" for compilation */\n#if defined(__BCC__) || defined(__BCC_VERSION__)\n#define DUK_F_BCC\n#endif\n\n#if defined(ANDROID) || defined(__ANDROID__)\n#define DUK_F_ANDROID\n#endif\n\n/* Linux */\n#if defined(__linux) || defined(__linux__) || defined(linux)\n#define DUK_F_LINUX\n#endif\n\n/* illumos / Solaris */\n#if defined(__sun) && defined(__SVR4)\n#define DUK_F_SUN\n#if defined(__SUNPRO_C) && (__SUNPRO_C < 0x550)\n#define DUK_F_OLD_SOLARIS\n/* Defines _ILP32 / _LP64 required by DUK_F_X86/DUK_F_X64.  Platforms\n * are processed before architectures, so this happens before the\n * DUK_F_X86/DUK_F_X64 detection is emitted.\n */\n#include <sys/isa_defs.h>\n#endif\n#endif\n\n/* AIX */\n#if defined(_AIX)\n/* defined(__xlc__) || defined(__IBMC__): works but too wide */\n#define DUK_F_AIX\n#endif\n\n/* HPUX */\n#if defined(__hpux)\n#define DUK_F_HPUX\n#if defined(__ia64)\n#define DUK_F_HPUX_ITANIUM\n#endif\n#endif\n\n/* POSIX */\n#if defined(__posix)\n#define DUK_F_POSIX\n#endif\n\n/* Cygwin */\n#if defined(__CYGWIN__)\n#define DUK_F_CYGWIN\n#endif\n\n/* Generic Unix (includes Cygwin) */\n#if defined(__unix) || defined(__unix__) || defined(unix) || \\\n    defined(DUK_F_LINUX) || defined(DUK_F_BSD)\n#define DUK_F_UNIX\n#endif\n\n/* Intel x86 (32-bit), x64 (64-bit) or x32 (64-bit but 32-bit pointers),\n * define only one of DUK_F_X86, DUK_F_X64, DUK_F_X32.\n * https://sites.google.com/site/x32abi/\n *\n * With DUK_F_OLD_SOLARIS the <sys/isa_defs.h> header must be included\n * before this.\n */\n#if defined(__amd64__) || defined(__amd64) || \\\n    defined(__x86_64__) || defined(__x86_64) || \\\n    defined(_M_X64) || defined(_M_AMD64)\n#if defined(__ILP32__) || defined(_ILP32)\n#define DUK_F_X32\n#else\n#define DUK_F_X64\n#endif\n#elif defined(i386) || defined(__i386) || defined(__i386__) || \\\n      defined(__i486__) || defined(__i586__) || defined(__i686__) || \\\n      defined(__IA32__) || defined(_M_IX86) || defined(__X86__) || \\\n      defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__)\n#if defined(__LP64__) || defined(_LP64)\n/* This should not really happen, but would indicate x64. */\n#define DUK_F_X64\n#else\n#define DUK_F_X86\n#endif\n#endif\n\n/* ARM */\n#if defined(__arm__) || defined(__thumb__) || defined(_ARM) || defined(_M_ARM) || defined(_M_ARM64) || defined(__aarch64__)\n#define DUK_F_ARM\n#if defined(__LP64__) || defined(_LP64) || defined(__arm64) || defined(__arm64__) || defined(_M_ARM64) || defined(__aarch64__)\n#define DUK_F_ARM64\n#else\n#define DUK_F_ARM32\n#endif\n#endif\n\n/* MIPS.  Related defines: __MIPSEB__, __MIPSEL__, __mips_isa_rev, __LP64__ */\n#if defined(__mips__) || defined(mips) || defined(_MIPS_ISA) || \\\n    defined(_R3000) || defined(_R4000) || defined(_R5900) || \\\n    defined(_MIPS_ISA_MIPS1) || defined(_MIPS_ISA_MIPS2) || \\\n    defined(_MIPS_ISA_MIPS3) || defined(_MIPS_ISA_MIPS4) || \\\n    defined(__mips) || defined(__MIPS__)\n#define DUK_F_MIPS\n#if defined(__LP64__) || defined(_LP64) || defined(__mips64) || \\\n    defined(__mips64__) || defined(__mips_n64)\n#define DUK_F_MIPS64\n#else\n#define DUK_F_MIPS32\n#endif\n#endif\n\n/* SPARC */\n#if defined(sparc) || defined(__sparc) || defined(__sparc__)\n#define DUK_F_SPARC\n#if defined(__LP64__) || defined(_LP64)\n#define DUK_F_SPARC64\n#else\n#define DUK_F_SPARC32\n#endif\n#endif\n\n/* SuperH */\n#if defined(__sh__) || \\\n    defined(__sh1__) || defined(__SH1__) || \\\n    defined(__sh2__) || defined(__SH2__) || \\\n    defined(__sh3__) || defined(__SH3__) || \\\n    defined(__sh4__) || defined(__SH4__) || \\\n    defined(__sh5__) || defined(__SH5__)\n#define DUK_F_SUPERH\n#endif\n\n/* Clang */\n#if defined(__clang__)\n#define DUK_F_CLANG\n#endif\n\n/* C++ */\n#undef DUK_F_CPP\n#if defined(__cplusplus)\n#define DUK_F_CPP\n#endif\n\n/* C99 or above */\n#undef DUK_F_C99\n#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)\n#define DUK_F_C99\n#endif\n\n/* C++11 or above */\n#undef DUK_F_CPP11\n#if defined(__cplusplus) && (__cplusplus >= 201103L)\n#define DUK_F_CPP11\n#endif\n\n/* GCC.  Clang also defines __GNUC__ so don't detect GCC if using Clang. */\n#if defined(__GNUC__) && !defined(__clang__) && !defined(DUK_F_CLANG)\n#define DUK_F_GCC\n#if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)\n/* Convenience, e.g. gcc 4.5.1 == 40501; http://stackoverflow.com/questions/6031819/emulating-gccs-builtin-unreachable */\n#define DUK_F_GCC_VERSION  (__GNUC__ * 10000L + __GNUC_MINOR__ * 100L + __GNUC_PATCHLEVEL__)\n#else\n#error cannot figure out gcc version\n#endif\n#endif\n\n/* MinGW.  Also GCC flags (DUK_F_GCC) are enabled now. */\n#if defined(__MINGW32__) || defined(__MINGW64__)\n#define DUK_F_MINGW\n#endif\n\n/* MSVC */\n#if defined(_MSC_VER)\n/* MSVC preprocessor defines: http://msdn.microsoft.com/en-us/library/b0084kay.aspx\n * _MSC_FULL_VER includes the build number, but it has at least two formats, see e.g.\n * BOOST_MSVC_FULL_VER in http://www.boost.org/doc/libs/1_52_0/boost/config/compiler/visualc.hpp\n */\n#define DUK_F_MSVC\n#if defined(_MSC_FULL_VER)\n#if (_MSC_FULL_VER > 100000000)\n#define DUK_F_MSVC_FULL_VER _MSC_FULL_VER\n#else\n#define DUK_F_MSCV_FULL_VER (_MSC_FULL_VER * 10)\n#endif\n#endif\n#endif  /* _MSC_VER */\n\n/* TinyC */\n#if defined(__TINYC__)\n/* http://bellard.org/tcc/tcc-doc.html#SEC9 */\n#define DUK_F_TINYC\n#endif\n\n/* VBCC */\n#if defined(__VBCC__)\n#define DUK_F_VBCC\n#endif\n\n/* Atari Mint */\n#if defined(__MINT__)\n#define DUK_F_MINT\n#endif\n\n/*\n *  Platform autodetection\n */\n\n/* Workaround for older C++ compilers before including <inttypes.h>,\n * see e.g.: https://sourceware.org/bugzilla/show_bug.cgi?id=15366\n */\n#if defined(__cplusplus) && !defined(__STDC_LIMIT_MACROS)\n#define __STDC_LIMIT_MACROS\n#endif\n#if defined(__cplusplus) && !defined(__STDC_CONSTANT_MACROS)\n#define __STDC_CONSTANT_MACROS\n#endif\n\n#if defined(DUK_F_APPLE)\n/* --- Mac OSX, iPhone, Darwin --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <TargetConditionals.h>\n#include <architecture/byte_order.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n/* http://stackoverflow.com/questions/5919996/how-to-detect-reliably-mac-os-x-ios-linux-windows-in-c-preprocessor */\n#if TARGET_IPHONE_SIMULATOR\n#define DUK_USE_OS_STRING \"iphone-sim\"\n#elif TARGET_OS_IPHONE\n#define DUK_USE_OS_STRING \"iphone\"\n#elif TARGET_OS_MAC\n#define DUK_USE_OS_STRING \"osx\"\n#else\n#define DUK_USE_OS_STRING \"osx-unknown\"\n#endif\n\n/* Use _setjmp() on Apple by default, see GH-55. */\n#define DUK_JMPBUF_TYPE       jmp_buf\n#define DUK_SETJMP(jb)        _setjmp((jb))\n#define DUK_LONGJMP(jb)       _longjmp((jb), 1)\n#elif defined(DUK_F_ORBIS)\n/* --- Orbis --- */\n/* Orbis = PS4 */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_S\n/* no parsing (not an error) */\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <machine/endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"orbis\"\n#elif defined(DUK_F_OPENBSD)\n/* --- OpenBSD --- */\n/* http://www.monkey.org/openbsd/archive/ports/0401/msg00089.html */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"openbsd\"\n#elif defined(DUK_F_BSD)\n/* --- Generic BSD --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"bsd\"\n#elif defined(DUK_F_TOS)\n/* --- Atari ST TOS --- */\n#define DUK_USE_DATE_NOW_TIME\n#define DUK_USE_DATE_TZO_GMTIME\n/* no parsing (not an error) */\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n\n#define DUK_USE_OS_STRING  \"tos\"\n\n/* TOS on M68K is always big endian. */\n#if !defined(DUK_USE_BYTEORDER) && defined(DUK_F_M68K)\n#define DUK_USE_BYTEORDER 3\n#endif\n#elif defined(DUK_F_AMIGAOS)\n/* --- AmigaOS --- */\n#if defined(DUK_F_M68K)\n/* AmigaOS on M68k */\n#define DUK_USE_DATE_NOW_TIME\n#define DUK_USE_DATE_TZO_GMTIME\n/* no parsing (not an error) */\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n#elif defined(DUK_F_PPC)\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n#if !defined(UINTPTR_MAX)\n#define UINTPTR_MAX UINT_MAX\n#endif\n#else\n#error AmigaOS but not M68K/PPC, not supported now\n#endif\n\n#define DUK_USE_OS_STRING \"amigaos\"\n\n/* AmigaOS on M68K or PPC is always big endian. */\n#if !defined(DUK_USE_BYTEORDER) && (defined(DUK_F_M68K) || defined(DUK_F_PPC))\n#define DUK_USE_BYTEORDER 3\n#endif\n#elif defined(DUK_F_DURANGO)\n/* --- Durango (XboxOne) --- */\n/* Durango = XboxOne\n * Configuration is nearly identical to Windows, except for\n * DUK_USE_DATE_TZO_WINDOWS.\n */\n\n/* Initial fix: disable secure CRT related warnings when compiling Duktape\n * itself (must be defined before including Windows headers).  Don't define\n * for user code including duktape.h.\n */\n#if defined(DUK_COMPILING_DUKTAPE) && !defined(_CRT_SECURE_NO_WARNINGS)\n#define _CRT_SECURE_NO_WARNINGS\n#endif\n\n/* MSVC does not have sys/param.h */\n#define DUK_USE_DATE_NOW_WINDOWS\n#define DUK_USE_DATE_TZO_WINDOWS_NO_DST\n/* Note: PRS and FMT are intentionally left undefined for now.  This means\n * there is no platform specific date parsing/formatting but there is still\n * the ISO 8601 standard format.\n */\n#if defined(DUK_COMPILING_DUKTAPE)\n/* Only include when compiling Duktape to avoid polluting application build\n * with a lot of unnecessary defines.\n */\n#include <windows.h>\n#endif\n\n#define DUK_USE_OS_STRING \"durango\"\n\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#elif defined(DUK_F_WINDOWS)\n/* --- Windows --- */\n/* Windows version can't obviously be determined at compile time,\n * but _WIN32_WINNT indicates the minimum version targeted:\n * - https://msdn.microsoft.com/en-us/library/6sehtctf.aspx\n */\n\n/* Initial fix: disable secure CRT related warnings when compiling Duktape\n * itself (must be defined before including Windows headers).  Don't define\n * for user code including duktape.h.\n */\n#if defined(DUK_COMPILING_DUKTAPE) && !defined(_CRT_SECURE_NO_WARNINGS)\n#define _CRT_SECURE_NO_WARNINGS\n#endif\n\n/* Windows 32-bit and 64-bit are currently the same. */\n/* MSVC does not have sys/param.h */\n\n#if defined(DUK_COMPILING_DUKTAPE)\n/* Only include when compiling Duktape to avoid polluting application build\n * with a lot of unnecessary defines.\n */\n#include <windows.h>\n#endif\n\n/* GetSystemTimePreciseAsFileTime() available from Windows 8:\n * https://msdn.microsoft.com/en-us/library/windows/desktop/hh706895(v=vs.85).aspx\n */\n#if defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS) || defined(DUK_USE_DATE_NOW_WINDOWS)\n/* User forced provider. */\n#else\n#if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0602)\n#define DUK_USE_DATE_NOW_WINDOWS_SUBMS\n#else\n#define DUK_USE_DATE_NOW_WINDOWS\n#endif\n#endif\n\n#define DUK_USE_DATE_TZO_WINDOWS\n\n/* Note: PRS and FMT are intentionally left undefined for now.  This means\n * there is no platform specific date parsing/formatting but there is still\n * the ISO 8601 standard format.\n */\n\n/* QueryPerformanceCounter() may go backwards in Windows XP, so enable for\n * Vista and later: https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx#qpc_support_in_windows_versions\n */\n#if !defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC) && \\\n    defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0600)\n#define DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC\n#endif\n\n#define DUK_USE_OS_STRING \"windows\"\n\n/* On Windows, assume we're little endian.  Even Itanium which has a\n * configurable endianness runs little endian in Windows.\n */\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#elif defined(DUK_F_FLASHPLAYER)\n/* --- Flashplayer (Crossbridge) --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"flashplayer\"\n\n#if !defined(DUK_USE_BYTEORDER) && defined(DUK_F_FLASHPLAYER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#elif defined(DUK_F_QNX)\n/* --- QNX --- */\n#if defined(DUK_F_QNX) && defined(DUK_COMPILING_DUKTAPE)\n/* See: /opt/qnx650/target/qnx6/usr/include/sys/platform.h */\n#define _XOPEN_SOURCE    600\n#define _POSIX_C_SOURCE  200112L\n#endif\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"qnx\"\n#elif defined(DUK_F_TINSPIRE)\n/* --- TI-Nspire --- */\n#if defined(DUK_COMPILING_DUKTAPE) && !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"tinspire\"\n#elif defined(DUK_F_EMSCRIPTEN)\n/* --- Emscripten --- */\n#if defined(DUK_COMPILING_DUKTAPE)\n#if !defined(_POSIX_C_SOURCE)\n#define _POSIX_C_SOURCE  200809L\n#endif\n#if !defined(_GNU_SOURCE)\n#define _GNU_SOURCE      /* e.g. getdate_r */\n#endif\n#if !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n#endif  /* DUK_COMPILING_DUKTAPE */\n\n#include <sys/types.h>\n#if defined(DUK_F_BCC)\n/* no endian.h */\n#else\n#include <endian.h>\n#endif  /* DUK_F_BCC */\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n#include <stdint.h>\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#define DUK_USE_OS_STRING \"emscripten\"\n#elif defined(DUK_F_ANDROID)\n/* --- Android --- */\n#if defined(DUK_COMPILING_DUKTAPE)\n#if !defined(_POSIX_C_SOURCE)\n#define _POSIX_C_SOURCE  200809L\n#endif\n#if !defined(_GNU_SOURCE)\n#define _GNU_SOURCE      /* e.g. getdate_r */\n#endif\n#if !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n#endif  /* DUK_COMPILING_DUKTAPE */\n\n#include <sys/types.h>\n#if defined(DUK_F_BCC)\n/* no endian.h or stdint.h */\n#else\n#include <endian.h>\n#include <stdint.h>\n#endif  /* DUK_F_BCC */\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#if 0  /* XXX: safe condition? */\n#define DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME\n#endif\n\n#define DUK_USE_OS_STRING \"android\"\n#elif defined(DUK_F_LINUX)\n/* --- Linux --- */\n#if defined(DUK_COMPILING_DUKTAPE)\n#if !defined(_POSIX_C_SOURCE)\n#define _POSIX_C_SOURCE  200809L\n#endif\n#if !defined(_GNU_SOURCE)\n#define _GNU_SOURCE      /* e.g. getdate_r */\n#endif\n#if !defined(_XOPEN_SOURCE)\n#define _XOPEN_SOURCE    /* e.g. strptime */\n#endif\n#endif  /* DUK_COMPILING_DUKTAPE */\n\n#include <sys/types.h>\n#if defined(DUK_F_BCC)\n/* no endian.h or stdint.h */\n#else\n#include <endian.h>\n#include <stdint.h>\n#endif  /* DUK_F_BCC */\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#if 0  /* XXX: safe condition? */\n#define DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME\n#endif\n\n#define DUK_USE_OS_STRING \"linux\"\n#elif defined(DUK_F_SUN)\n/* --- Solaris --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n\n#include <sys/types.h>\n#if defined(DUK_F_OLD_SOLARIS)\n/* Old Solaris with no endian.h, stdint.h */\n#define DUK_F_NO_STDINT_H\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#else  /* DUK_F_OLD_SOLARIS */\n#include <ast/endian.h>\n#endif  /* DUK_F_OLD_SOLARIS */\n\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"solaris\"\n#elif defined(DUK_F_AIX)\n/* --- AIX --- */\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"aix\"\n#elif defined(DUK_F_HPUX)\n/* --- HPUX --- */\n#define DUK_F_NO_STDINT_H\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"hpux\"\n#elif defined(DUK_F_POSIX)\n/* --- Generic POSIX --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"posix\"\n#elif defined(DUK_F_CYGWIN)\n/* --- Cygwin --- */\n/* don't use strptime() for now */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <sys/types.h>\n#include <endian.h>\n#include <sys/param.h>\n#include <sys/time.h>\n#include <time.h>\n\n#define DUK_JMPBUF_TYPE       jmp_buf\n#define DUK_SETJMP(jb)        _setjmp((jb))\n#define DUK_LONGJMP(jb)       _longjmp((jb), 1)\n\n#define DUK_USE_OS_STRING \"windows\"\n#elif defined(DUK_F_UNIX)\n/* --- Generic UNIX --- */\n#define DUK_USE_DATE_NOW_GETTIMEOFDAY\n#define DUK_USE_DATE_TZO_GMTIME_R\n#define DUK_USE_DATE_PRS_STRPTIME\n#define DUK_USE_DATE_FMT_STRFTIME\n#include <time.h>\n#include <sys/time.h>\n#define DUK_USE_OS_STRING \"unknown\"\n#else\n/* --- Generic fallback --- */\n/* The most portable current time provider is time(), but it only has a\n * one second resolution.\n */\n#define DUK_USE_DATE_NOW_TIME\n\n/* The most portable way to figure out local time offset is gmtime(),\n * but it's not thread safe so use with caution.\n */\n#define DUK_USE_DATE_TZO_GMTIME\n\n/* Avoid custom date parsing and formatting for portability. */\n#undef DUK_USE_DATE_PRS_STRPTIME\n#undef DUK_USE_DATE_FMT_STRFTIME\n\n/* Rely on C89 headers only; time.h must be here. */\n#include <time.h>\n\n#define DUK_USE_OS_STRING \"unknown\"\n#endif  /* autodetect platform */\n\n/* Shared includes: C89 */\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdarg.h>  /* varargs */\n#include <setjmp.h>\n#include <stddef.h>  /* e.g. ptrdiff_t */\n#include <math.h>\n#include <limits.h>\n\n/* date.h is omitted, and included per platform */\n\n/* Shared includes: stdint.h is C99 */\n#if defined(DUK_F_NO_STDINT_H)\n/* stdint.h not available */\n#else\n/* Technically C99 (C++11) but found in many systems.  On some systems\n * __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS must be defined before\n * including stdint.h (see above).\n */\n#include <stdint.h>\n#endif\n\n/* <exception> is only included if needed, based on DUK_USE_xxx flags. */\n\n/*\n *  Architecture autodetection\n */\n\n#if defined(DUK_F_X86)\n/* --- x86 --- */\n#define DUK_USE_ARCH_STRING \"x86\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n\n#define DUK_USE_PACKED_TVAL\n\n/* FreeBSD, -m32, and clang prior to 5.0 has union aliasing issues which\n * break duk_tval copying.  Disable packed duk_tval automatically.\n */\n#if defined(DUK_F_FREEBSD) && defined(DUK_F_X86) && \\\n    defined(__clang__) && defined(__clang_major__) && (__clang_major__ < 5)\n#undef DUK_USE_PACKED_TVAL\n#endif\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_X64)\n/* --- x64 --- */\n#define DUK_USE_ARCH_STRING \"x64\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_X32)\n/* --- x32 --- */\n#define DUK_USE_ARCH_STRING \"x32\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_ARM32)\n/* --- ARM 32-bit --- */\n#define DUK_USE_ARCH_STRING \"arm32\"\n/* Byte order varies, so rely on autodetect. */\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_ARM64)\n/* --- ARM 64-bit --- */\n#define DUK_USE_ARCH_STRING \"arm64\"\n/* Byte order varies, so rely on autodetect. */\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_MIPS32)\n/* --- MIPS 32-bit --- */\n#define DUK_USE_ARCH_STRING \"mips32\"\n/* MIPS byte order varies so rely on autodetection. */\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_MIPS64)\n/* --- MIPS 64-bit --- */\n#define DUK_USE_ARCH_STRING \"mips64\"\n/* MIPS byte order varies so rely on autodetection. */\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_PPC32)\n/* --- PowerPC 32-bit --- */\n#define DUK_USE_ARCH_STRING \"ppc32\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_PPC64)\n/* --- PowerPC 64-bit --- */\n#define DUK_USE_ARCH_STRING \"ppc64\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_SPARC32)\n/* --- SPARC 32-bit --- */\n#define DUK_USE_ARCH_STRING \"sparc32\"\n/* SPARC byte order varies so rely on autodetection. */\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_SPARC64)\n/* --- SPARC 64-bit --- */\n#define DUK_USE_ARCH_STRING \"sparc64\"\n/* SPARC byte order varies so rely on autodetection. */\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_SUPERH)\n/* --- SuperH --- */\n#define DUK_USE_ARCH_STRING \"sh\"\n/* Byte order varies, rely on autodetection. */\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_M68K)\n/* --- Motorola 68k --- */\n#define DUK_USE_ARCH_STRING \"m68k\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 3\n#endif\n#define DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#elif defined(DUK_F_EMSCRIPTEN)\n/* --- Emscripten --- */\n#define DUK_USE_ARCH_STRING \"emscripten\"\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#undef DUK_USE_PACKED_TVAL\n#define DUK_F_PACKED_TVAL_PROVIDED\n#else\n/* --- Generic --- */\n/* These are necessary wild guesses. */\n#define DUK_USE_ARCH_STRING \"generic\"\n/* Rely on autodetection for byte order, alignment, and packed tval. */\n#endif  /* autodetect architecture */\n\n/*\n *  Compiler autodetection\n */\n\n#if defined(DUK_F_CLANG)\n/* --- Clang --- */\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n/* C99 / C++11 and above: rely on va_copy() which is required. */\n#define DUK_VA_COPY(dest,src) va_copy(dest,src)\n#else\n/* Clang: assume we have __va_copy() in non-C99 mode. */\n#define DUK_VA_COPY(dest,src) __va_copy(dest,src)\n#endif\n\n#define DUK_NORETURN(decl)  decl __attribute__((noreturn))\n\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unreachable)\n#define DUK_UNREACHABLE()  do { __builtin_unreachable(); } while (0)\n#endif\n#endif\n\n#define DUK_USE_BRANCH_HINTS\n#define DUK_LIKELY(x)    __builtin_expect((x), 1)\n#define DUK_UNLIKELY(x)  __builtin_expect((x), 0)\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unpredictable)\n#define DUK_UNPREDICTABLE(x)  __builtin_unpredictable((x))\n#endif\n#endif\n\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_NOINLINE        __attribute__((noinline))\n#define DUK_INLINE          inline\n#define DUK_ALWAYS_INLINE   inline __attribute__((always_inline))\n#endif\n\n/* DUK_HOT */\n/* DUK_COLD */\n\n#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS)\n/* MSVC dllexport/dllimport: appropriate __declspec depends on whether we're\n * compiling Duktape or the application.\n */\n#if defined(DUK_COMPILING_DUKTAPE)\n#define DUK_EXTERNAL_DECL  extern __declspec(dllexport)\n#define DUK_EXTERNAL       __declspec(dllexport)\n#else\n#define DUK_EXTERNAL_DECL  extern __declspec(dllimport)\n#define DUK_EXTERNAL       should_not_happen\n#endif\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#else\n#define DUK_INTERNAL_DECL  extern\n#define DUK_INTERNAL       /*empty*/\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n#else\n#define DUK_EXTERNAL_DECL  __attribute__ ((visibility(\"default\"))) extern\n#define DUK_EXTERNAL       __attribute__ ((visibility(\"default\")))\n#if defined(DUK_SINGLE_FILE)\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n/* Minimize warnings for unused internal functions with GCC >= 3.1.1 and\n * Clang.  Based on documentation it should suffice to have the attribute\n * in the declaration only, but in practice some warnings are generated unless\n * the attribute is also applied to the definition.\n */\n#define DUK_INTERNAL_DECL  static __attribute__ ((unused))\n#define DUK_INTERNAL       static __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#endif\n#else\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused)) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\")))\n#endif\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n#endif\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"clang\"\n#else\n#define DUK_USE_COMPILER_STRING \"clang\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#define DUK_USE_UNION_INITIALIZERS\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#undef DUK_USE_GCC_PRAGMAS\n#define DUK_USE_PACK_CLANG_ATTR\n\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_bswap64)\n#define DUK_BSWAP64(x) ((duk_uint64_t) __builtin_bswap64((duk_uint64_t) (x)))\n#endif\n#if __has_builtin(__builtin_bswap32)\n#define DUK_BSWAP32(x) ((duk_uint32_t) __builtin_bswap32((duk_uint32_t) (x)))\n#endif\n#if __has_builtin(__builtin_bswap16)\n#define DUK_BSWAP16(x) ((duk_uint16_t) __builtin_bswap16((duk_uint16_t) (x)))\n#endif\n#endif\n#elif defined(DUK_F_GCC)\n/* --- GCC --- */\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n/* C99 / C++11 and above: rely on va_copy() which is required. */\n#define DUK_VA_COPY(dest,src) va_copy(dest,src)\n#else\n/* GCC: assume we have __va_copy() in non-C99 mode. */\n#define DUK_VA_COPY(dest,src) __va_copy(dest,src)\n#endif\n\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 20500L) && (DUK_F_GCC_VERSION < 50000L)\n/* Since gcc-2.5.\n *\n * Disabled temporarily in GCC 5+ because of an unresolved noreturn-related\n * issue: https://github.com/svaarala/duktape/issues/2155.\n */\n#define DUK_NORETURN(decl)  decl __attribute__((noreturn))\n#endif\n\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L)\n/* Since gcc-4.5. */\n#define DUK_UNREACHABLE()  do { __builtin_unreachable(); } while (0)\n#endif\n\n#define DUK_USE_BRANCH_HINTS\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40500L)\n/* GCC: test not very accurate; enable only in relatively recent builds\n * because of bugs in gcc-4.4 (http://lists.debian.org/debian-gcc/2010/04/msg00000.html)\n */\n#define DUK_LIKELY(x)    __builtin_expect((x), 1)\n#define DUK_UNLIKELY(x)  __builtin_expect((x), 0)\n#endif\n/* XXX: equivalent of clang __builtin_unpredictable? */\n\n#if (defined(DUK_F_C99) || defined(DUK_F_CPP11)) && \\\n    defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 30101)\n#define DUK_NOINLINE        __attribute__((noinline))\n#define DUK_INLINE          inline\n#define DUK_ALWAYS_INLINE   inline __attribute__((always_inline))\n#endif\n\n#if (defined(DUK_F_C99) || defined(DUK_F_CPP11)) && \\\n    defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40300)\n#define DUK_HOT             __attribute__((hot))\n#define DUK_COLD            __attribute__((cold))\n#endif\n\n#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS)\n/* MSVC dllexport/dllimport: appropriate __declspec depends on whether we're\n * compiling Duktape or the application.\n */\n#if defined(DUK_COMPILING_DUKTAPE)\n#define DUK_EXTERNAL_DECL  extern __declspec(dllexport)\n#define DUK_EXTERNAL       __declspec(dllexport)\n#else\n#define DUK_EXTERNAL_DECL  extern __declspec(dllimport)\n#define DUK_EXTERNAL       should_not_happen\n#endif\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#else\n#define DUK_INTERNAL_DECL  extern\n#define DUK_INTERNAL       /*empty*/\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n#elif defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40000)\n#define DUK_EXTERNAL_DECL  __attribute__ ((visibility(\"default\"))) extern\n#define DUK_EXTERNAL       __attribute__ ((visibility(\"default\")))\n#if defined(DUK_SINGLE_FILE)\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n/* Minimize warnings for unused internal functions with GCC >= 3.1.1 and\n * Clang.  Based on documentation it should suffice to have the attribute\n * in the declaration only, but in practice some warnings are generated unless\n * the attribute is also applied to the definition.\n */\n#define DUK_INTERNAL_DECL  static __attribute__ ((unused))\n#define DUK_INTERNAL       static __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#endif\n#else\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused)) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\")))\n#endif\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n#endif\n\n#if defined(DUK_F_MINGW)\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"mingw++\"\n#else\n#define DUK_USE_COMPILER_STRING \"mingw\"\n#endif\n#else\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"g++\"\n#else\n#define DUK_USE_COMPILER_STRING \"gcc\"\n#endif\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || (defined(DUK_F_CPP11) && defined(__GNUC__))\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#define DUK_USE_UNION_INITIALIZERS\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 40600)\n#define DUK_USE_GCC_PRAGMAS\n#else\n#undef DUK_USE_GCC_PRAGMAS\n#endif\n\n#define DUK_USE_PACK_GCC_ATTR\n\n/* Availability varies based on platform (between GCC 4.4 and 4.8), and there\n * are apparently some bugs in GCC 4.x.  Check for GCC 5.0 before enabling\n * these to be safe.\n */\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION >= 50000L)\n#define DUK_BSWAP64(x) ((duk_uint64_t) __builtin_bswap64((duk_uint64_t) (x)))\n#define DUK_BSWAP32(x) ((duk_uint32_t) __builtin_bswap32((duk_uint32_t) (x)))\n#define DUK_BSWAP16(x) ((duk_uint16_t) __builtin_bswap16((duk_uint16_t) (x)))\n#endif\n#elif defined(DUK_F_MSVC)\n/* --- MSVC --- */\n/* http://msdn.microsoft.com/en-us/library/aa235362(VS.60).aspx */\n#define DUK_NORETURN(decl)  __declspec(noreturn) decl\n\n/* XXX: DUK_UNREACHABLE for msvc? */\n\n#undef DUK_USE_BRANCH_HINTS\n\n/* XXX: DUK_LIKELY, DUK_UNLIKELY for msvc? */\n/* XXX: DUK_NOINLINE, DUK_INLINE, DUK_ALWAYS_INLINE for msvc? */\n\n#if defined(DUK_F_DLL_BUILD) && defined(DUK_F_WINDOWS)\n/* MSVC dllexport/dllimport: appropriate __declspec depends on whether we're\n * compiling Duktape or the application.\n */\n#if defined(DUK_COMPILING_DUKTAPE)\n#define DUK_EXTERNAL_DECL  extern __declspec(dllexport)\n#define DUK_EXTERNAL       __declspec(dllexport)\n#else\n#define DUK_EXTERNAL_DECL  extern __declspec(dllimport)\n#define DUK_EXTERNAL       should_not_happen\n#endif\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#else\n#define DUK_INTERNAL_DECL  extern\n#define DUK_INTERNAL       /*empty*/\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n#endif\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"msvc++\"\n#else\n#define DUK_USE_COMPILER_STRING \"msvc\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99)\n#define DUK_USE_VARIADIC_MACROS\n#elif defined(_MSC_VER) && (_MSC_VER >= 1400)\n/* VS2005+ should have variadic macros even when they're not C99. */\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#undef DUK_USE_UNION_INITIALIZERS\n#if defined(_MSC_VER) && (_MSC_VER >= 1800)\n/* VS2013+ supports union initializers but there's a bug involving union-inside-struct:\n * https://connect.microsoft.com/VisualStudio/feedback/details/805981\n * The bug was fixed (at least) in VS2015 so check for VS2015 for now:\n * https://blogs.msdn.microsoft.com/vcblog/2015/07/01/c-compiler-front-end-fixes-in-vs2015/\n * Manually tested using VS2013, CL reports 18.00.31101, so enable for VS2013 too.\n */\n#define DUK_USE_UNION_INITIALIZERS\n#endif\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#undef DUK_USE_GCC_PRAGMAS\n\n#define DUK_USE_PACK_MSVC_PRAGMA\n\n/* These have been tested from VS2008 onwards; may work in older VS versions\n * too but not enabled by default.\n */\n#if defined(_MSC_VER) && (_MSC_VER >= 1500)\n#define DUK_NOINLINE        __declspec(noinline)\n#define DUK_INLINE          __inline\n#define DUK_ALWAYS_INLINE   __forceinline\n#endif\n\n#if defined(_MSC_VER) && (_MSC_VER >= 1900)\n#define DUK_SNPRINTF     snprintf\n#define DUK_VSNPRINTF    vsnprintf\n#else\n/* (v)snprintf() is missing before MSVC 2015.  Note that _(v)snprintf() does\n * NOT NUL terminate on truncation, but Duktape code never assumes that.\n * http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010\n */\n#define DUK_SNPRINTF     _snprintf\n#define DUK_VSNPRINTF    _vsnprintf\n#endif\n\n/* Avoid warning when doing DUK_UNREF(some_function). */\n#if defined(_MSC_VER) && (_MSC_VER < 1500)\n#pragma warning(disable: 4100 4101 4550 4551)\n#define DUK_UNREF(x)\n#else\n#define DUK_UNREF(x)  do { __pragma(warning(suppress:4100 4101 4550 4551)) (x); } while (0)\n#endif\n\n/* Older versions of MSVC don't support the LL/ULL suffix. */\n#define DUK_U64_CONSTANT(x) x##ui64\n#define DUK_I64_CONSTANT(x) x##i64\n#elif defined(DUK_F_EMSCRIPTEN)\n/* --- Emscripten --- */\n#define DUK_NORETURN(decl)  decl __attribute__((noreturn))\n\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unreachable)\n#define DUK_UNREACHABLE()  do { __builtin_unreachable(); } while (0)\n#endif\n#endif\n\n#define DUK_USE_BRANCH_HINTS\n#define DUK_LIKELY(x)    __builtin_expect((x), 1)\n#define DUK_UNLIKELY(x)  __builtin_expect((x), 0)\n#if defined(__clang__) && defined(__has_builtin)\n#if __has_builtin(__builtin_unpredictable)\n#define DUK_UNPREDICTABLE(x)  __builtin_unpredictable((x))\n#endif\n#endif\n\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_NOINLINE        __attribute__((noinline))\n#define DUK_INLINE          inline\n#define DUK_ALWAYS_INLINE   inline __attribute__((always_inline))\n#endif\n\n#define DUK_EXTERNAL_DECL  __attribute__ ((visibility(\"default\"))) extern\n#define DUK_EXTERNAL       __attribute__ ((visibility(\"default\")))\n#if defined(DUK_SINGLE_FILE)\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n/* Minimize warnings for unused internal functions with GCC >= 3.1.1 and\n * Clang.  Based on documentation it should suffice to have the attribute\n * in the declaration only, but in practice some warnings are generated unless\n * the attribute is also applied to the definition.\n */\n#define DUK_INTERNAL_DECL  static __attribute__ ((unused))\n#define DUK_INTERNAL       static __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  static\n#define DUK_INTERNAL       static\n#endif\n#else\n#if (defined(DUK_F_GCC_VERSION) && DUK_F_GCC_VERSION >= 30101) || defined(DUK_F_CLANG)\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused)) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\"))) __attribute__ ((unused))\n#else\n#define DUK_INTERNAL_DECL  __attribute__ ((visibility(\"hidden\"))) extern\n#define DUK_INTERNAL       __attribute__ ((visibility(\"hidden\")))\n#endif\n#endif\n#define DUK_LOCAL_DECL     static\n#define DUK_LOCAL          static\n\n#define DUK_USE_COMPILER_STRING \"emscripten\"\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n#define DUK_USE_UNION_INITIALIZERS\n\n#undef DUK_USE_FLEX_C99\n#undef DUK_USE_FLEX_ZEROSIZE\n#undef DUK_USE_FLEX_ONESIZE\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE\n#endif\n\n#undef DUK_USE_GCC_PRAGMAS\n#define DUK_USE_PACK_CLANG_ATTR\n#elif defined(DUK_F_TINYC)\n/* --- TinyC --- */\n#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"tinyc++\"\n#else\n#define DUK_USE_COMPILER_STRING \"tinyc\"\n#endif\n\n/* http://bellard.org/tcc/tcc-doc.html#SEC7 */\n#define DUK_USE_VARIADIC_MACROS\n\n#define DUK_USE_UNION_INITIALIZERS\n\n/* Most portable, wastes space */\n#define DUK_USE_FLEX_ONESIZE\n\n/* Most portable, potentially wastes space */\n#define DUK_USE_PACK_DUMMY_MEMBER\n#elif defined(DUK_F_VBCC)\n/* --- VBCC --- */\n#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"vbcc-c++\"\n#else\n#define DUK_USE_COMPILER_STRING \"vbcc\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n/* VBCC supports C99 so check only for C99 for union initializer support.\n * Designated union initializers would possibly work even without a C99 check.\n */\n#undef DUK_USE_UNION_INITIALIZERS\n#if defined(DUK_F_C99)\n#define DUK_USE_UNION_INITIALIZERS\n#endif\n\n#define DUK_USE_FLEX_ZEROSIZE\n#define DUK_USE_PACK_DUMMY_MEMBER\n#elif defined(DUK_F_BCC)\n/* --- Bruce's C compiler --- */\n#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"bcc++\"\n#else\n#define DUK_USE_COMPILER_STRING \"bcc\"\n#endif\n\n/* Most portable */\n#undef DUK_USE_VARIADIC_MACROS\n\n/* Most portable, wastes space */\n#undef DUK_USE_UNION_INITIALIZERS\n\n/* Most portable, wastes space */\n#define DUK_USE_FLEX_ONESIZE\n\n/* Most portable, potentially wastes space */\n#define DUK_USE_PACK_DUMMY_MEMBER\n\n/* BCC, assume we're on x86. */\n#if !defined(DUK_USE_BYTEORDER)\n#define DUK_USE_BYTEORDER 1\n#endif\n#else\n/* --- Generic --- */\n#undef DUK_USE_BRANCH_HINTS\n\n#if defined(DUK_F_CPP)\n#define DUK_USE_COMPILER_STRING \"generic-c++\"\n#else\n#define DUK_USE_COMPILER_STRING \"generic\"\n#endif\n\n#undef DUK_USE_VARIADIC_MACROS\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_USE_VARIADIC_MACROS\n#endif\n\n/* C++ doesn't have standard designated union initializers ({ .foo = 1 }). */\n#undef DUK_USE_UNION_INITIALIZERS\n#if defined(DUK_F_C99)\n#define DUK_USE_UNION_INITIALIZERS\n#endif\n\n/* Most portable, wastes space */\n#define DUK_USE_FLEX_ONESIZE\n\n/* Most portable, potentially wastes space */\n#define DUK_USE_PACK_DUMMY_MEMBER\n#endif  /* autodetect compiler */\n\n/* uclibc */\n#if defined(__UCLIBC__)\n#define DUK_F_UCLIBC\n#endif\n\n/*\n *  Wrapper typedefs and constants for integer types, also sanity check types.\n *\n *  C99 typedefs are quite good but not always available, and we want to avoid\n *  forcibly redefining the C99 typedefs.  So, there are Duktape wrappers for\n *  all C99 typedefs and Duktape code should only use these typedefs.  Type\n *  detection when C99 is not supported is best effort and may end up detecting\n *  some types incorrectly.\n *\n *  Pointer sizes are a portability problem: pointers to different types may\n *  have a different size and function pointers are very difficult to manage\n *  portably.\n *\n *  http://en.wikipedia.org/wiki/C_data_types#Fixed-width_integer_types\n *\n *  Note: there's an interesting corner case when trying to define minimum\n *  signed integer value constants which leads to the current workaround of\n *  defining e.g. -0x80000000 as (-0x7fffffffL - 1L).  See doc/code-issues.txt\n *  for a longer discussion.\n *\n *  Note: avoid typecasts and computations in macro integer constants as they\n *  can then no longer be used in macro relational expressions (such as\n *  #if DUK_SIZE_MAX < 0xffffffffUL).  There is internal code which relies on\n *  being able to compare DUK_SIZE_MAX against a limit.\n */\n\n/* XXX: add feature options to force basic types from outside? */\n\n#if !defined(INT_MAX)\n#error INT_MAX not defined\n#endif\n\n/* Check that architecture is two's complement, standard C allows e.g.\n * INT_MIN to be -2**31+1 (instead of -2**31).\n */\n#if defined(INT_MAX) && defined(INT_MIN)\n#if INT_MAX != -(INT_MIN + 1)\n#error platform does not seem complement of two\n#endif\n#else\n#error cannot check complement of two\n#endif\n\n/* Pointer size determination based on __WORDSIZE or architecture when\n * that's not available.\n */\n#if defined(DUK_F_X86) || defined(DUK_F_X32) || \\\n    defined(DUK_F_M68K) || defined(DUK_F_PPC32) || \\\n    defined(DUK_F_BCC) || \\\n    (defined(__WORDSIZE) && (__WORDSIZE == 32)) || \\\n    ((defined(DUK_F_OLD_SOLARIS) || defined(DUK_F_AIX) || \\\n      defined(DUK_F_HPUX)) && defined(_ILP32)) || \\\n    defined(DUK_F_ARM32)\n#define DUK_F_32BIT_PTRS\n#elif defined(DUK_F_X64) || \\\n      (defined(__WORDSIZE) && (__WORDSIZE == 64)) || \\\n   ((defined(DUK_F_OLD_SOLARIS) || defined(DUK_F_AIX) || \\\n     defined(DUK_F_HPUX)) && defined(_LP64)) || \\\n    defined(DUK_F_ARM64)\n#define DUK_F_64BIT_PTRS\n#else\n/* not sure, not needed with C99 anyway */\n#endif\n\n/* Intermediate define for 'have inttypes.h' */\n#undef DUK_F_HAVE_INTTYPES\n#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \\\n    !(defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC))\n/* vbcc + AmigaOS has C99 but no inttypes.h */\n#define DUK_F_HAVE_INTTYPES\n#elif defined(__cplusplus) && (__cplusplus >= 201103L)\n/* C++11 apparently ratified stdint.h */\n#define DUK_F_HAVE_INTTYPES\n#endif\n\n/* Basic integer typedefs and limits, preferably from inttypes.h, otherwise\n * through automatic detection.\n */\n#if defined(DUK_F_HAVE_INTTYPES)\n/* C99 or compatible */\n\n#define DUK_F_HAVE_64BIT\n#include <inttypes.h>\n\ntypedef uint8_t duk_uint8_t;\ntypedef int8_t duk_int8_t;\ntypedef uint16_t duk_uint16_t;\ntypedef int16_t duk_int16_t;\ntypedef uint32_t duk_uint32_t;\ntypedef int32_t duk_int32_t;\ntypedef uint64_t duk_uint64_t;\ntypedef int64_t duk_int64_t;\ntypedef uint_least8_t duk_uint_least8_t;\ntypedef int_least8_t duk_int_least8_t;\ntypedef uint_least16_t duk_uint_least16_t;\ntypedef int_least16_t duk_int_least16_t;\ntypedef uint_least32_t duk_uint_least32_t;\ntypedef int_least32_t duk_int_least32_t;\ntypedef uint_least64_t duk_uint_least64_t;\ntypedef int_least64_t duk_int_least64_t;\ntypedef uint_fast8_t duk_uint_fast8_t;\ntypedef int_fast8_t duk_int_fast8_t;\ntypedef uint_fast16_t duk_uint_fast16_t;\ntypedef int_fast16_t duk_int_fast16_t;\ntypedef uint_fast32_t duk_uint_fast32_t;\ntypedef int_fast32_t duk_int_fast32_t;\ntypedef uint_fast64_t duk_uint_fast64_t;\ntypedef int_fast64_t duk_int_fast64_t;\ntypedef uintptr_t duk_uintptr_t;\ntypedef intptr_t duk_intptr_t;\ntypedef uintmax_t duk_uintmax_t;\ntypedef intmax_t duk_intmax_t;\n\n#define DUK_UINT8_MIN         0\n#define DUK_UINT8_MAX         UINT8_MAX\n#define DUK_INT8_MIN          INT8_MIN\n#define DUK_INT8_MAX          INT8_MAX\n#define DUK_UINT_LEAST8_MIN   0\n#define DUK_UINT_LEAST8_MAX   UINT_LEAST8_MAX\n#define DUK_INT_LEAST8_MIN    INT_LEAST8_MIN\n#define DUK_INT_LEAST8_MAX    INT_LEAST8_MAX\n#define DUK_UINT_FAST8_MIN    0\n#define DUK_UINT_FAST8_MAX    UINT_FAST8_MAX\n#define DUK_INT_FAST8_MIN     INT_FAST8_MIN\n#define DUK_INT_FAST8_MAX     INT_FAST8_MAX\n#define DUK_UINT16_MIN        0\n#define DUK_UINT16_MAX        UINT16_MAX\n#define DUK_INT16_MIN         INT16_MIN\n#define DUK_INT16_MAX         INT16_MAX\n#define DUK_UINT_LEAST16_MIN  0\n#define DUK_UINT_LEAST16_MAX  UINT_LEAST16_MAX\n#define DUK_INT_LEAST16_MIN   INT_LEAST16_MIN\n#define DUK_INT_LEAST16_MAX   INT_LEAST16_MAX\n#define DUK_UINT_FAST16_MIN   0\n#define DUK_UINT_FAST16_MAX   UINT_FAST16_MAX\n#define DUK_INT_FAST16_MIN    INT_FAST16_MIN\n#define DUK_INT_FAST16_MAX    INT_FAST16_MAX\n#define DUK_UINT32_MIN        0\n#define DUK_UINT32_MAX        UINT32_MAX\n#define DUK_INT32_MIN         INT32_MIN\n#define DUK_INT32_MAX         INT32_MAX\n#define DUK_UINT_LEAST32_MIN  0\n#define DUK_UINT_LEAST32_MAX  UINT_LEAST32_MAX\n#define DUK_INT_LEAST32_MIN   INT_LEAST32_MIN\n#define DUK_INT_LEAST32_MAX   INT_LEAST32_MAX\n#define DUK_UINT_FAST32_MIN   0\n#define DUK_UINT_FAST32_MAX   UINT_FAST32_MAX\n#define DUK_INT_FAST32_MIN    INT_FAST32_MIN\n#define DUK_INT_FAST32_MAX    INT_FAST32_MAX\n#define DUK_UINT64_MIN        0\n#define DUK_UINT64_MAX        UINT64_MAX\n#define DUK_INT64_MIN         INT64_MIN\n#define DUK_INT64_MAX         INT64_MAX\n#define DUK_UINT_LEAST64_MIN  0\n#define DUK_UINT_LEAST64_MAX  UINT_LEAST64_MAX\n#define DUK_INT_LEAST64_MIN   INT_LEAST64_MIN\n#define DUK_INT_LEAST64_MAX   INT_LEAST64_MAX\n#define DUK_UINT_FAST64_MIN   0\n#define DUK_UINT_FAST64_MAX   UINT_FAST64_MAX\n#define DUK_INT_FAST64_MIN    INT_FAST64_MIN\n#define DUK_INT_FAST64_MAX    INT_FAST64_MAX\n\n#define DUK_UINTPTR_MIN       0\n#define DUK_UINTPTR_MAX       UINTPTR_MAX\n#define DUK_INTPTR_MIN        INTPTR_MIN\n#define DUK_INTPTR_MAX        INTPTR_MAX\n\n#define DUK_UINTMAX_MIN       0\n#define DUK_UINTMAX_MAX       UINTMAX_MAX\n#define DUK_INTMAX_MIN        INTMAX_MIN\n#define DUK_INTMAX_MAX        INTMAX_MAX\n\n#define DUK_SIZE_MIN          0\n#define DUK_SIZE_MAX          SIZE_MAX\n#undef DUK_SIZE_MAX_COMPUTED\n\n#else  /* C99 types */\n\n/* When C99 types are not available, we use heuristic detection to get\n * the basic 8, 16, 32, and (possibly) 64 bit types.  The fast/least\n * types are then assumed to be exactly the same for now: these could\n * be improved per platform but C99 types are very often now available.\n * 64-bit types are not available on all platforms; this is OK at least\n * on 32-bit platforms.\n *\n * This detection code is necessarily a bit hacky and can provide typedefs\n * and defines that won't work correctly on some exotic platform.\n */\n\n#if (defined(CHAR_BIT) && (CHAR_BIT == 8)) || \\\n    (defined(UCHAR_MAX) && (UCHAR_MAX == 255))\ntypedef unsigned char duk_uint8_t;\ntypedef signed char duk_int8_t;\n#else\n#error cannot detect 8-bit type\n#endif\n\n#if defined(USHRT_MAX) && (USHRT_MAX == 65535UL)\ntypedef unsigned short duk_uint16_t;\ntypedef signed short duk_int16_t;\n#elif defined(UINT_MAX) && (UINT_MAX == 65535UL)\n/* On some platforms int is 16-bit but long is 32-bit (e.g. PureC) */\ntypedef unsigned int duk_uint16_t;\ntypedef signed int duk_int16_t;\n#else\n#error cannot detect 16-bit type\n#endif\n\n#if defined(UINT_MAX) && (UINT_MAX == 4294967295UL)\ntypedef unsigned int duk_uint32_t;\ntypedef signed int duk_int32_t;\n#elif defined(ULONG_MAX) && (ULONG_MAX == 4294967295UL)\n/* On some platforms int is 16-bit but long is 32-bit (e.g. PureC) */\ntypedef unsigned long duk_uint32_t;\ntypedef signed long duk_int32_t;\n#else\n#error cannot detect 32-bit type\n#endif\n\n/* 64-bit type detection is a bit tricky.\n *\n * ULLONG_MAX is a standard define.  __LONG_LONG_MAX__ and __ULONG_LONG_MAX__\n * are used by at least GCC (even if system headers don't provide ULLONG_MAX).\n * Some GCC variants may provide __LONG_LONG_MAX__ but not __ULONG_LONG_MAX__.\n *\n * ULL / LL constants are rejected / warned about by some compilers, even if\n * the compiler has a 64-bit type and the compiler/system headers provide an\n * unsupported constant (ULL/LL)!  Try to avoid using ULL / LL constants.\n * As a side effect we can only check that e.g. ULONG_MAX is larger than 32\n * bits but can't be sure it is exactly 64 bits.  Self tests will catch such\n * cases.\n */\n#undef DUK_F_HAVE_64BIT\n#if !defined(DUK_F_HAVE_64BIT) && defined(ULONG_MAX)\n#if (ULONG_MAX > 4294967295UL)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long duk_uint64_t;\ntypedef signed long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(ULLONG_MAX)\n#if (ULLONG_MAX > 4294967295UL)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long long duk_uint64_t;\ntypedef signed long long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(__ULONG_LONG_MAX__)\n#if (__ULONG_LONG_MAX__ > 4294967295UL)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long long duk_uint64_t;\ntypedef signed long long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(__LONG_LONG_MAX__)\n#if (__LONG_LONG_MAX__ > 2147483647L)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long long duk_uint64_t;\ntypedef signed long long duk_int64_t;\n#endif\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(DUK_F_MINGW)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned long duk_uint64_t;\ntypedef signed long duk_int64_t;\n#endif\n#if !defined(DUK_F_HAVE_64BIT) && defined(DUK_F_MSVC)\n#define DUK_F_HAVE_64BIT\ntypedef unsigned __int64 duk_uint64_t;\ntypedef signed __int64 duk_int64_t;\n#endif\n#if !defined(DUK_F_HAVE_64BIT)\n/* cannot detect 64-bit type, not always needed so don't error */\n#endif\n\ntypedef duk_uint8_t duk_uint_least8_t;\ntypedef duk_int8_t duk_int_least8_t;\ntypedef duk_uint16_t duk_uint_least16_t;\ntypedef duk_int16_t duk_int_least16_t;\ntypedef duk_uint32_t duk_uint_least32_t;\ntypedef duk_int32_t duk_int_least32_t;\ntypedef duk_uint8_t duk_uint_fast8_t;\ntypedef duk_int8_t duk_int_fast8_t;\ntypedef duk_uint16_t duk_uint_fast16_t;\ntypedef duk_int16_t duk_int_fast16_t;\ntypedef duk_uint32_t duk_uint_fast32_t;\ntypedef duk_int32_t duk_int_fast32_t;\n#if defined(DUK_F_HAVE_64BIT)\ntypedef duk_uint64_t duk_uint_least64_t;\ntypedef duk_int64_t duk_int_least64_t;\ntypedef duk_uint64_t duk_uint_fast64_t;\ntypedef duk_int64_t duk_int_fast64_t;\n#endif\n#if defined(DUK_F_HAVE_64BIT)\ntypedef duk_uint64_t duk_uintmax_t;\ntypedef duk_int64_t duk_intmax_t;\n#else\ntypedef duk_uint32_t duk_uintmax_t;\ntypedef duk_int32_t duk_intmax_t;\n#endif\n\n/* Note: the funny looking computations for signed minimum 16-bit, 32-bit, and\n * 64-bit values are intentional as the obvious forms (e.g. -0x80000000L) are\n * -not- portable.  See code-issues.txt for a detailed discussion.\n */\n#define DUK_UINT8_MIN         0UL\n#define DUK_UINT8_MAX         0xffUL\n#define DUK_INT8_MIN          (-0x80L)\n#define DUK_INT8_MAX          0x7fL\n#define DUK_UINT_LEAST8_MIN   0UL\n#define DUK_UINT_LEAST8_MAX   0xffUL\n#define DUK_INT_LEAST8_MIN    (-0x80L)\n#define DUK_INT_LEAST8_MAX    0x7fL\n#define DUK_UINT_FAST8_MIN    0UL\n#define DUK_UINT_FAST8_MAX    0xffUL\n#define DUK_INT_FAST8_MIN     (-0x80L)\n#define DUK_INT_FAST8_MAX     0x7fL\n#define DUK_UINT16_MIN        0UL\n#define DUK_UINT16_MAX        0xffffUL\n#define DUK_INT16_MIN         (-0x7fffL - 1L)\n#define DUK_INT16_MAX         0x7fffL\n#define DUK_UINT_LEAST16_MIN  0UL\n#define DUK_UINT_LEAST16_MAX  0xffffUL\n#define DUK_INT_LEAST16_MIN   (-0x7fffL - 1L)\n#define DUK_INT_LEAST16_MAX   0x7fffL\n#define DUK_UINT_FAST16_MIN   0UL\n#define DUK_UINT_FAST16_MAX   0xffffUL\n#define DUK_INT_FAST16_MIN    (-0x7fffL - 1L)\n#define DUK_INT_FAST16_MAX    0x7fffL\n#define DUK_UINT32_MIN        0UL\n#define DUK_UINT32_MAX        0xffffffffUL\n#define DUK_INT32_MIN         (-0x7fffffffL - 1L)\n#define DUK_INT32_MAX         0x7fffffffL\n#define DUK_UINT_LEAST32_MIN  0UL\n#define DUK_UINT_LEAST32_MAX  0xffffffffUL\n#define DUK_INT_LEAST32_MIN   (-0x7fffffffL - 1L)\n#define DUK_INT_LEAST32_MAX   0x7fffffffL\n#define DUK_UINT_FAST32_MIN   0UL\n#define DUK_UINT_FAST32_MAX   0xffffffffUL\n#define DUK_INT_FAST32_MIN    (-0x7fffffffL - 1L)\n#define DUK_INT_FAST32_MAX    0x7fffffffL\n\n/* 64-bit constants.  Since LL / ULL constants are not always available,\n * use computed values.  These values can't be used in preprocessor\n * comparisons; flag them as such.\n */\n#if defined(DUK_F_HAVE_64BIT)\n#define DUK_UINT64_MIN        ((duk_uint64_t) 0)\n#define DUK_UINT64_MAX        ((duk_uint64_t) -1)\n#define DUK_INT64_MIN         ((duk_int64_t) (~(DUK_UINT64_MAX >> 1)))\n#define DUK_INT64_MAX         ((duk_int64_t) (DUK_UINT64_MAX >> 1))\n#define DUK_UINT_LEAST64_MIN  DUK_UINT64_MIN\n#define DUK_UINT_LEAST64_MAX  DUK_UINT64_MAX\n#define DUK_INT_LEAST64_MIN   DUK_INT64_MIN\n#define DUK_INT_LEAST64_MAX   DUK_INT64_MAX\n#define DUK_UINT_FAST64_MIN   DUK_UINT64_MIN\n#define DUK_UINT_FAST64_MAX   DUK_UINT64_MAX\n#define DUK_INT_FAST64_MIN    DUK_INT64_MIN\n#define DUK_INT_FAST64_MAX    DUK_INT64_MAX\n#define DUK_UINT64_MIN_COMPUTED\n#define DUK_UINT64_MAX_COMPUTED\n#define DUK_INT64_MIN_COMPUTED\n#define DUK_INT64_MAX_COMPUTED\n#define DUK_UINT_LEAST64_MIN_COMPUTED\n#define DUK_UINT_LEAST64_MAX_COMPUTED\n#define DUK_INT_LEAST64_MIN_COMPUTED\n#define DUK_INT_LEAST64_MAX_COMPUTED\n#define DUK_UINT_FAST64_MIN_COMPUTED\n#define DUK_UINT_FAST64_MAX_COMPUTED\n#define DUK_INT_FAST64_MIN_COMPUTED\n#define DUK_INT_FAST64_MAX_COMPUTED\n#endif\n\n#if defined(DUK_F_HAVE_64BIT)\n#define DUK_UINTMAX_MIN       DUK_UINT64_MIN\n#define DUK_UINTMAX_MAX       DUK_UINT64_MAX\n#define DUK_INTMAX_MIN        DUK_INT64_MIN\n#define DUK_INTMAX_MAX        DUK_INT64_MAX\n#define DUK_UINTMAX_MIN_COMPUTED\n#define DUK_UINTMAX_MAX_COMPUTED\n#define DUK_INTMAX_MIN_COMPUTED\n#define DUK_INTMAX_MAX_COMPUTED\n#else\n#define DUK_UINTMAX_MIN       0UL\n#define DUK_UINTMAX_MAX       0xffffffffUL\n#define DUK_INTMAX_MIN        (-0x7fffffffL - 1L)\n#define DUK_INTMAX_MAX        0x7fffffffL\n#endif\n\n/* This detection is not very reliable. */\n#if defined(DUK_F_32BIT_PTRS)\ntypedef duk_int32_t duk_intptr_t;\ntypedef duk_uint32_t duk_uintptr_t;\n#define DUK_UINTPTR_MIN       DUK_UINT32_MIN\n#define DUK_UINTPTR_MAX       DUK_UINT32_MAX\n#define DUK_INTPTR_MIN        DUK_INT32_MIN\n#define DUK_INTPTR_MAX        DUK_INT32_MAX\n#elif defined(DUK_F_64BIT_PTRS) && defined(DUK_F_HAVE_64BIT)\ntypedef duk_int64_t duk_intptr_t;\ntypedef duk_uint64_t duk_uintptr_t;\n#define DUK_UINTPTR_MIN       DUK_UINT64_MIN\n#define DUK_UINTPTR_MAX       DUK_UINT64_MAX\n#define DUK_INTPTR_MIN        DUK_INT64_MIN\n#define DUK_INTPTR_MAX        DUK_INT64_MAX\n#define DUK_UINTPTR_MIN_COMPUTED\n#define DUK_UINTPTR_MAX_COMPUTED\n#define DUK_INTPTR_MIN_COMPUTED\n#define DUK_INTPTR_MAX_COMPUTED\n#else\n#error cannot determine intptr type\n#endif\n\n/* SIZE_MAX may be missing so use an approximate value for it. */\n#undef DUK_SIZE_MAX_COMPUTED\n#if !defined(SIZE_MAX)\n#define DUK_SIZE_MAX_COMPUTED\n#define SIZE_MAX              ((size_t) (-1))\n#endif\n#define DUK_SIZE_MIN          0\n#define DUK_SIZE_MAX          SIZE_MAX\n\n#endif  /* C99 types */\n\n/* A few types are assumed to always exist. */\ntypedef size_t duk_size_t;\ntypedef ptrdiff_t duk_ptrdiff_t;\n\n/* The best type for an \"all around int\" in Duktape internals is \"at least\n * 32 bit signed integer\" which is most convenient.  Same for unsigned type.\n * Prefer 'int' when large enough, as it is almost always a convenient type.\n */\n#if defined(UINT_MAX) && (UINT_MAX >= 0xffffffffUL)\ntypedef int duk_int_t;\ntypedef unsigned int duk_uint_t;\n#define DUK_INT_MIN           INT_MIN\n#define DUK_INT_MAX           INT_MAX\n#define DUK_UINT_MIN          0\n#define DUK_UINT_MAX          UINT_MAX\n#else\ntypedef duk_int_fast32_t duk_int_t;\ntypedef duk_uint_fast32_t duk_uint_t;\n#define DUK_INT_MIN           DUK_INT_FAST32_MIN\n#define DUK_INT_MAX           DUK_INT_FAST32_MAX\n#define DUK_UINT_MIN          DUK_UINT_FAST32_MIN\n#define DUK_UINT_MAX          DUK_UINT_FAST32_MAX\n#endif\n\n/* Same as 'duk_int_t' but guaranteed to be a 'fast' variant if this\n * distinction matters for the CPU.  These types are used mainly in the\n * executor where it might really matter.\n */\ntypedef duk_int_fast32_t duk_int_fast_t;\ntypedef duk_uint_fast32_t duk_uint_fast_t;\n#define DUK_INT_FAST_MIN      DUK_INT_FAST32_MIN\n#define DUK_INT_FAST_MAX      DUK_INT_FAST32_MAX\n#define DUK_UINT_FAST_MIN     DUK_UINT_FAST32_MIN\n#define DUK_UINT_FAST_MAX     DUK_UINT_FAST32_MAX\n\n/* Small integers (16 bits or more) can fall back to the 'int' type, but\n * have a typedef so they are marked \"small\" explicitly.\n */\ntypedef int duk_small_int_t;\ntypedef unsigned int duk_small_uint_t;\n#define DUK_SMALL_INT_MIN     INT_MIN\n#define DUK_SMALL_INT_MAX     INT_MAX\n#define DUK_SMALL_UINT_MIN    0\n#define DUK_SMALL_UINT_MAX    UINT_MAX\n\n/* Fast variants of small integers, again for really fast paths like the\n * executor.\n */\ntypedef duk_int_fast16_t duk_small_int_fast_t;\ntypedef duk_uint_fast16_t duk_small_uint_fast_t;\n#define DUK_SMALL_INT_FAST_MIN    DUK_INT_FAST16_MIN\n#define DUK_SMALL_INT_FAST_MAX    DUK_INT_FAST16_MAX\n#define DUK_SMALL_UINT_FAST_MIN   DUK_UINT_FAST16_MIN\n#define DUK_SMALL_UINT_FAST_MAX   DUK_UINT_FAST16_MAX\n\n/* Boolean values are represented with the platform 'unsigned int'. */\ntypedef duk_small_uint_t duk_bool_t;\n#define DUK_BOOL_MIN              DUK_SMALL_UINT_MIN\n#define DUK_BOOL_MAX              DUK_SMALL_UINT_MAX\n\n/* Index values must have at least 32-bit signed range. */\ntypedef duk_int_t duk_idx_t;\n#define DUK_IDX_MIN               DUK_INT_MIN\n#define DUK_IDX_MAX               DUK_INT_MAX\n\n/* Unsigned index variant. */\ntypedef duk_uint_t duk_uidx_t;\n#define DUK_UIDX_MIN              DUK_UINT_MIN\n#define DUK_UIDX_MAX              DUK_UINT_MAX\n\n/* Array index values, could be exact 32 bits.\n * Currently no need for signed duk_arridx_t.\n */\ntypedef duk_uint_t duk_uarridx_t;\n#define DUK_UARRIDX_MIN           DUK_UINT_MIN\n#define DUK_UARRIDX_MAX           DUK_UINT_MAX\n\n/* Duktape/C function return value, platform int is enough for now to\n * represent 0, 1, or negative error code.  Must be compatible with\n * assigning truth values (e.g. duk_ret_t rc = (foo == bar);).\n */\ntypedef duk_small_int_t duk_ret_t;\n#define DUK_RET_MIN               DUK_SMALL_INT_MIN\n#define DUK_RET_MAX               DUK_SMALL_INT_MAX\n\n/* Error codes are represented with platform int.  High bits are used\n * for flags and such, so 32 bits are needed.\n */\ntypedef duk_int_t duk_errcode_t;\n#define DUK_ERRCODE_MIN           DUK_INT_MIN\n#define DUK_ERRCODE_MAX           DUK_INT_MAX\n\n/* Codepoint type.  Must be 32 bits or more because it is used also for\n * internal codepoints.  The type is signed because negative codepoints\n * are used as internal markers (e.g. to mark EOF or missing argument).\n * (X)UTF-8/CESU-8 encode/decode take and return an unsigned variant to\n * ensure duk_uint32_t casts back and forth nicely.  Almost everything\n * else uses the signed one.\n */\ntypedef duk_int_t duk_codepoint_t;\ntypedef duk_uint_t duk_ucodepoint_t;\n#define DUK_CODEPOINT_MIN         DUK_INT_MIN\n#define DUK_CODEPOINT_MAX         DUK_INT_MAX\n#define DUK_UCODEPOINT_MIN        DUK_UINT_MIN\n#define DUK_UCODEPOINT_MAX        DUK_UINT_MAX\n\n/* IEEE float/double typedef. */\ntypedef float duk_float_t;\ntypedef double duk_double_t;\n\n/* We're generally assuming that we're working on a platform with a 32-bit\n * address space.  If DUK_SIZE_MAX is a typecast value (which is necessary\n * if SIZE_MAX is missing), the check must be avoided because the\n * preprocessor can't do a comparison.\n */\n#if !defined(DUK_SIZE_MAX)\n#error DUK_SIZE_MAX is undefined, probably missing SIZE_MAX\n#elif !defined(DUK_SIZE_MAX_COMPUTED)\n#if DUK_SIZE_MAX < 0xffffffffUL\n/* On some systems SIZE_MAX can be smaller than max unsigned 32-bit value\n * which seems incorrect if size_t is (at least) an unsigned 32-bit type.\n * However, it doesn't seem useful to error out compilation if this is the\n * case.\n */\n#endif\n#endif\n\n/* Type used in public API declarations and user code.  Typedef maps to\n * 'struct duk_hthread' like the 'duk_hthread' typedef which is used\n * exclusively in internals.\n */\ntypedef struct duk_hthread duk_context;\n\n/* Check whether we should use 64-bit integers or not.\n *\n * Quite incomplete now.  Use 64-bit types if detected (C99 or other detection)\n * unless they are known to be unreliable.  For instance, 64-bit types are\n * available on VBCC but seem to misbehave.\n */\n#if defined(DUK_F_HAVE_64BIT) && !defined(DUK_F_VBCC)\n#define DUK_USE_64BIT_OPS\n#else\n#undef DUK_USE_64BIT_OPS\n#endif\n\n/*\n *  Fill-ins for platform, architecture, and compiler\n */\n\n/* An abort()-like primitive is needed by the default fatal error handler. */\n#if !defined(DUK_ABORT)\n#define DUK_ABORT             abort\n#endif\n\n#if !defined(DUK_SETJMP)\n#define DUK_JMPBUF_TYPE       jmp_buf\n#define DUK_SETJMP(jb)        setjmp((jb))\n#define DUK_LONGJMP(jb)       longjmp((jb), 1)\n#endif\n\n#if 0\n/* sigsetjmp() alternative */\n#define DUK_JMPBUF_TYPE       sigjmp_buf\n#define DUK_SETJMP(jb)        sigsetjmp((jb))\n#define DUK_LONGJMP(jb)       siglongjmp((jb), 1)\n#endif\n\n/* Special naming to avoid conflict with e.g. DUK_FREE() in duk_heap.h\n * (which is unfortunately named).  May sometimes need replacement, e.g.\n * some compilers don't handle zero length or NULL correctly in realloc().\n */\n#if !defined(DUK_ANSI_MALLOC)\n#define DUK_ANSI_MALLOC      malloc\n#endif\n#if !defined(DUK_ANSI_REALLOC)\n#define DUK_ANSI_REALLOC     realloc\n#endif\n#if !defined(DUK_ANSI_CALLOC)\n#define DUK_ANSI_CALLOC      calloc\n#endif\n#if !defined(DUK_ANSI_FREE)\n#define DUK_ANSI_FREE        free\n#endif\n\n/* ANSI C (various versions) and some implementations require that the\n * pointer arguments to memset(), memcpy(), and memmove() be valid values\n * even when byte size is 0 (even a NULL pointer is considered invalid in\n * this context).  Zero-size operations as such are allowed, as long as their\n * pointer arguments point to a valid memory area.  The DUK_MEMSET(),\n * DUK_MEMCPY(), and DUK_MEMMOVE() macros require this same behavior, i.e.:\n * (1) pointers must be valid and non-NULL, (2) zero size must otherwise be\n * allowed.  If these are not fulfilled, a macro wrapper is needed.\n *\n *   http://stackoverflow.com/questions/5243012/is-it-guaranteed-to-be-safe-to-perform-memcpy0-0-0\n *   http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-October/011065.html\n *\n * Not sure what's the required behavior when a pointer points just past the\n * end of a buffer, which often happens in practice (e.g. zero size memmoves).\n * For example, if allocation size is 3, the following pointer would not\n * technically point to a valid memory byte:\n *\n *   <-- alloc -->\n *   | 0 | 1 | 2 | .....\n *                 ^-- p=3, points after last valid byte (2)\n */\n#if !defined(DUK_MEMCPY)\n#if defined(DUK_F_UCLIBC)\n/* Old uclibcs have a broken memcpy so use memmove instead (this is overly wide\n * now on purpose): http://lists.uclibc.org/pipermail/uclibc-cvs/2008-October/025511.html\n */\n#define DUK_MEMCPY       memmove\n#else\n#define DUK_MEMCPY       memcpy\n#endif\n#endif\n#if !defined(DUK_MEMMOVE)\n#define DUK_MEMMOVE      memmove\n#endif\n#if !defined(DUK_MEMCMP)\n#define DUK_MEMCMP       memcmp\n#endif\n#if !defined(DUK_MEMSET)\n#define DUK_MEMSET       memset\n#endif\n#if !defined(DUK_STRLEN)\n#define DUK_STRLEN       strlen\n#endif\n#if !defined(DUK_STRCMP)\n#define DUK_STRCMP       strcmp\n#endif\n#if !defined(DUK_STRNCMP)\n#define DUK_STRNCMP      strncmp\n#endif\n#if !defined(DUK_SPRINTF)\n#define DUK_SPRINTF      sprintf\n#endif\n#if !defined(DUK_SNPRINTF)\n/* snprintf() is technically not part of C89 but usually available. */\n#define DUK_SNPRINTF     snprintf\n#endif\n#if !defined(DUK_VSPRINTF)\n#define DUK_VSPRINTF     vsprintf\n#endif\n#if !defined(DUK_VSNPRINTF)\n/* vsnprintf() is technically not part of C89 but usually available. */\n#define DUK_VSNPRINTF    vsnprintf\n#endif\n#if !defined(DUK_SSCANF)\n#define DUK_SSCANF       sscanf\n#endif\n#if !defined(DUK_VSSCANF)\n#define DUK_VSSCANF      vsscanf\n#endif\n#if !defined(DUK_MEMZERO)\n#define DUK_MEMZERO(p,n) DUK_MEMSET((p), 0, (n))\n#endif\n\n#if !defined(DUK_DOUBLE_INFINITY)\n#undef DUK_USE_COMPUTED_INFINITY\n#if defined(DUK_F_GCC_VERSION) && (DUK_F_GCC_VERSION < 40600)\n/* GCC older than 4.6: avoid overflow warnings related to using INFINITY */\n#define DUK_DOUBLE_INFINITY  (__builtin_inf())\n#elif defined(INFINITY)\n#define DUK_DOUBLE_INFINITY  ((double) INFINITY)\n#elif !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) && !defined(DUK_F_BCC) && \\\n      !defined(DUK_F_OLD_SOLARIS) && !defined(DUK_F_AIX)\n#define DUK_DOUBLE_INFINITY  (1.0 / 0.0)\n#else\n/* In VBCC (1.0 / 0.0) results in a warning and 0.0 instead of infinity.\n * Use a computed infinity (initialized when a heap is created at the\n * latest).\n */\n#define DUK_USE_COMPUTED_INFINITY\n#define DUK_DOUBLE_INFINITY  duk_computed_infinity\n#endif\n#endif\n\n#if !defined(DUK_DOUBLE_NAN)\n#undef DUK_USE_COMPUTED_NAN\n#if defined(NAN)\n#define DUK_DOUBLE_NAN       NAN\n#elif !defined(DUK_F_VBCC) && !defined(DUK_F_MSVC) && !defined(DUK_F_BCC) && \\\n      !defined(DUK_F_OLD_SOLARIS) && !defined(DUK_F_AIX)\n#define DUK_DOUBLE_NAN       (0.0 / 0.0)\n#else\n/* In VBCC (0.0 / 0.0) results in a warning and 0.0 instead of NaN.\n * In MSVC (VS2010 Express) (0.0 / 0.0) results in a compile error.\n * Use a computed NaN (initialized when a heap is created at the\n * latest).\n */\n#define DUK_USE_COMPUTED_NAN\n#define DUK_DOUBLE_NAN       duk_computed_nan\n#endif\n#endif\n\n/* Many platforms are missing fpclassify() and friends, so use replacements\n * if necessary.  The replacement constants (FP_NAN etc) can be anything but\n * match Linux constants now.\n */\n#undef DUK_USE_REPL_FPCLASSIFY\n#undef DUK_USE_REPL_SIGNBIT\n#undef DUK_USE_REPL_ISFINITE\n#undef DUK_USE_REPL_ISNAN\n#undef DUK_USE_REPL_ISINF\n\n/* Complex condition broken into separate parts. */\n#undef DUK_F_USE_REPL_ALL\n#if !(defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO) && \\\n      defined(FP_SUBNORMAL) && defined(FP_NORMAL))\n/* Missing some obvious constants. */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_AMIGAOS) && defined(DUK_F_VBCC)\n/* VBCC is missing the built-ins even in C99 mode (perhaps a header issue). */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_AMIGAOS) && defined(DUK_F_M68K)\n/* AmigaOS + M68K seems to have math issues even when using GCC cross\n * compilation.  Use replacements for all AmigaOS versions on M68K\n * regardless of compiler.\n */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_FREEBSD) && defined(DUK_F_CLANG)\n/* Placeholder fix for (detection is wider than necessary):\n * http://llvm.org/bugs/show_bug.cgi?id=17788\n */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_UCLIBC)\n/* At least some uclibc versions have broken floating point math.  For\n * example, fpclassify() can incorrectly classify certain NaN formats.\n * To be safe, use replacements.\n */\n#define DUK_F_USE_REPL_ALL\n#elif defined(DUK_F_AIX)\n/* Older versions may be missing isnan(), etc. */\n#define DUK_F_USE_REPL_ALL\n#endif\n\n#if defined(DUK_F_USE_REPL_ALL)\n#define DUK_USE_REPL_FPCLASSIFY\n#define DUK_USE_REPL_SIGNBIT\n#define DUK_USE_REPL_ISFINITE\n#define DUK_USE_REPL_ISNAN\n#define DUK_USE_REPL_ISINF\n#define DUK_FPCLASSIFY       duk_repl_fpclassify\n#define DUK_SIGNBIT          duk_repl_signbit\n#define DUK_ISFINITE         duk_repl_isfinite\n#define DUK_ISNAN            duk_repl_isnan\n#define DUK_ISINF            duk_repl_isinf\n#define DUK_FP_NAN           0\n#define DUK_FP_INFINITE      1\n#define DUK_FP_ZERO          2\n#define DUK_FP_SUBNORMAL     3\n#define DUK_FP_NORMAL        4\n#else\n#define DUK_FPCLASSIFY       fpclassify\n#define DUK_SIGNBIT          signbit\n#define DUK_ISFINITE         isfinite\n#define DUK_ISNAN            isnan\n#define DUK_ISINF            isinf\n#define DUK_FP_NAN           FP_NAN\n#define DUK_FP_INFINITE      FP_INFINITE\n#define DUK_FP_ZERO          FP_ZERO\n#define DUK_FP_SUBNORMAL     FP_SUBNORMAL\n#define DUK_FP_NORMAL        FP_NORMAL\n#endif\n\n#if defined(DUK_F_USE_REPL_ALL)\n#undef DUK_F_USE_REPL_ALL\n#endif\n\n/* These functions don't currently need replacement but are wrapped for\n * completeness.  Because these are used as function pointers, they need\n * to be defined as concrete C functions (not macros).\n */\n#if !defined(DUK_FABS)\n#define DUK_FABS             fabs\n#endif\n#if !defined(DUK_FLOOR)\n#define DUK_FLOOR            floor\n#endif\n#if !defined(DUK_CEIL)\n#define DUK_CEIL             ceil\n#endif\n#if !defined(DUK_FMOD)\n#define DUK_FMOD             fmod\n#endif\n#if !defined(DUK_POW)\n#define DUK_POW              pow\n#endif\n#if !defined(DUK_ACOS)\n#define DUK_ACOS             acos\n#endif\n#if !defined(DUK_ASIN)\n#define DUK_ASIN             asin\n#endif\n#if !defined(DUK_ATAN)\n#define DUK_ATAN             atan\n#endif\n#if !defined(DUK_ATAN2)\n#define DUK_ATAN2            atan2\n#endif\n#if !defined(DUK_SIN)\n#define DUK_SIN              sin\n#endif\n#if !defined(DUK_COS)\n#define DUK_COS              cos\n#endif\n#if !defined(DUK_TAN)\n#define DUK_TAN              tan\n#endif\n#if !defined(DUK_EXP)\n#define DUK_EXP              exp\n#endif\n#if !defined(DUK_LOG)\n#define DUK_LOG              log\n#endif\n#if !defined(DUK_SQRT)\n#define DUK_SQRT             sqrt\n#endif\n\n/* The functions below exist only in C99/C++11 or later and need a workaround\n * for platforms that don't include them.  MSVC isn't detected as C99, but\n * these functions also exist in MSVC 2013 and later so include a clause for\n * that too.  Android doesn't have log2; disable all of these for Android.\n */\n#if (defined(DUK_F_C99) || defined(DUK_F_CPP11) || (defined(_MSC_VER) && (_MSC_VER >= 1800))) && \\\n    !defined(DUK_F_ANDROID) && !defined(DUK_F_MINT)\n#if !defined(DUK_CBRT)\n#define DUK_CBRT             cbrt\n#endif\n#if !defined(DUK_LOG2)\n#define DUK_LOG2             log2\n#endif\n#if !defined(DUK_LOG10)\n#define DUK_LOG10            log10\n#endif\n#if !defined(DUK_TRUNC)\n#define DUK_TRUNC            trunc\n#endif\n#endif  /* DUK_F_C99 etc */\n\n/* NetBSD 6.0 x86 (at least) has a few problems with pow() semantics,\n * see test-bug-netbsd-math-pow.js.  MinGW has similar (but different)\n * issues, see test-bug-mingw-math-issues.js.  Enable pow() workarounds\n * for these targets.\n */\n#undef DUK_USE_POW_WORKAROUNDS\n#if defined(DUK_F_NETBSD) || defined(DUK_F_MINGW)\n#define DUK_USE_POW_WORKAROUNDS\n#endif\n\n/* Similar workarounds for atan2() semantics issues.  MinGW issues are\n * documented in test-bug-mingw-math-issues.js.\n */\n#undef DUK_USE_ATAN2_WORKAROUNDS\n#if defined(DUK_F_MINGW)\n#define DUK_USE_ATAN2_WORKAROUNDS\n#endif\n\n/* Rely as little as possible on compiler behavior for NaN comparison,\n * signed zero handling, etc.  Currently never activated but may be needed\n * for broken compilers.\n */\n#undef DUK_USE_PARANOID_MATH\n\n/* There was a curious bug where test-bi-date-canceling.js would fail e.g.\n * on 64-bit Ubuntu, gcc-4.8.1, -m32, and no -std=c99.  Some date computations\n * using doubles would be optimized which then broke some corner case tests.\n * The problem goes away by adding 'volatile' to the datetime computations.\n * Not sure what the actual triggering conditions are, but using this on\n * non-C99 systems solves the known issues and has relatively little cost\n * on other platforms.\n */\n#undef DUK_USE_PARANOID_DATE_COMPUTATION\n#if !defined(DUK_F_C99)\n#define DUK_USE_PARANOID_DATE_COMPUTATION\n#endif\n\n/*\n *  Byte order and double memory layout detection\n *\n *  Endianness detection is a major portability hassle because the macros\n *  and headers are not standardized.  There's even variance across UNIX\n *  platforms.  Even with \"standard\" headers, details like underscore count\n *  varies between platforms, e.g. both __BYTE_ORDER and _BYTE_ORDER are used\n *  (Crossbridge has a single underscore, for instance).\n *\n *  The checks below are structured with this in mind: several approaches are\n *  used, and at the end we check if any of them worked.  This allows generic\n *  approaches to be tried first, and platform/compiler specific hacks tried\n *  last.  As a last resort, the user can force a specific endianness, as it's\n *  not likely that automatic detection will work on the most exotic platforms.\n *\n *  Duktape supports little and big endian machines.  There's also support\n *  for a hybrid used by some ARM machines where integers are little endian\n *  but IEEE double values use a mixed order (12345678 -> 43218765).  This\n *  byte order for doubles is referred to as \"mixed endian\".\n */\n\n/* GCC and Clang provide endianness defines as built-in predefines, with\n * leading and trailing double underscores (e.g. __BYTE_ORDER__).  See\n * output of \"make gccpredefs\" and \"make clangpredefs\".  Clang doesn't\n * seem to provide __FLOAT_WORD_ORDER__; assume not mixed endian for clang.\n * http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html\n */\n#if !defined(DUK_USE_BYTEORDER) && defined(__BYTE_ORDER__)\n#if defined(__ORDER_LITTLE_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__)\n#define DUK_USE_BYTEORDER 1\n#elif defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__)\n#define DUK_USE_BYTEORDER 2\n#elif !defined(__FLOAT_WORD_ORDER__)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 1\n#else\n/* Byte order is little endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#elif defined(__ORDER_BIG_ENDIAN__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__)\n#define DUK_USE_BYTEORDER 3\n#elif !defined(__FLOAT_WORD_ORDER__)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 3\n#else\n/* Byte order is big endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#else\n/* Cannot determine byte order; __ORDER_PDP_ENDIAN__ is related to 32-bit\n * integer ordering and is not relevant.\n */\n#endif  /* integer byte order */\n#endif  /* !defined(DUK_USE_BYTEORDER) && defined(__BYTE_ORDER__) */\n\n/* More or less standard endianness predefines provided by header files.\n * The ARM hybrid case is detected by assuming that __FLOAT_WORD_ORDER\n * will be big endian, see: http://lists.mysql.com/internals/443.\n * On some platforms some defines may be present with an empty value which\n * causes comparisons to fail: https://github.com/svaarala/duktape/issues/453.\n */\n#if !defined(DUK_USE_BYTEORDER)\n#if defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN) || \\\n    defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN) || \\\n    defined(__LITTLE_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER) && defined(__LITTLE_ENDIAN) && (__FLOAT_WORD_ORDER == __LITTLE_ENDIAN) || \\\n    defined(_FLOAT_WORD_ORDER) && defined(_LITTLE_ENDIAN) && (_FLOAT_WORD_ORDER == _LITTLE_ENDIAN)\n#define DUK_USE_BYTEORDER 1\n#elif defined(__FLOAT_WORD_ORDER) && defined(__BIG_ENDIAN) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN) || \\\n      defined(_FLOAT_WORD_ORDER) && defined(_BIG_ENDIAN) && (_FLOAT_WORD_ORDER == _BIG_ENDIAN)\n#define DUK_USE_BYTEORDER 2\n#elif !defined(__FLOAT_WORD_ORDER) && !defined(_FLOAT_WORD_ORDER)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 1\n#else\n/* Byte order is little endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#elif defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN) || \\\n      defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN) || \\\n      defined(__BIG_ENDIAN__)\n#if defined(__FLOAT_WORD_ORDER) && defined(__BIG_ENDIAN) && (__FLOAT_WORD_ORDER == __BIG_ENDIAN) || \\\n    defined(_FLOAT_WORD_ORDER) && defined(_BIG_ENDIAN) && (_FLOAT_WORD_ORDER == _BIG_ENDIAN)\n#define DUK_USE_BYTEORDER 3\n#elif !defined(__FLOAT_WORD_ORDER) && !defined(_FLOAT_WORD_ORDER)\n/* Float word order not known, assume not a hybrid. */\n#define DUK_USE_BYTEORDER 3\n#else\n/* Byte order is big endian but cannot determine IEEE double word order. */\n#endif  /* float word order */\n#else\n/* Cannot determine byte order. */\n#endif  /* integer byte order */\n#endif  /* !defined(DUK_USE_BYTEORDER) */\n\n/* QNX gcc cross compiler seems to define e.g. __LITTLEENDIAN__ or __BIGENDIAN__:\n *  $ /opt/qnx650/host/linux/x86/usr/bin/i486-pc-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian\n *  67:#define __LITTLEENDIAN__ 1\n *  $ /opt/qnx650/host/linux/x86/usr/bin/mips-unknown-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian\n *  81:#define __BIGENDIAN__ 1\n *  $ /opt/qnx650/host/linux/x86/usr/bin/arm-unknown-nto-qnx6.5.0-gcc -dM -E - </dev/null | grep -ni endian\n *  70:#define __LITTLEENDIAN__ 1\n */\n#if !defined(DUK_USE_BYTEORDER)\n#if defined(__LITTLEENDIAN__)\n#define DUK_USE_BYTEORDER 1\n#elif defined(__BIGENDIAN__)\n#define DUK_USE_BYTEORDER 3\n#endif\n#endif\n\n/*\n *  Alignment requirement and support for unaligned accesses\n *\n *  Assume unaligned accesses are not supported unless specifically allowed\n *  in the target platform.  Some platforms may support unaligned accesses\n *  but alignment to 4 or 8 may still be desirable.  Note that unaligned\n *  accesses (and even pointers) relative to natural alignment (regardless\n *  of target alignment) are technically undefined behavior and thus\n *  compiler/architecture specific.\n */\n\n/* If not forced, use safe default for alignment. */\n#if !defined(DUK_USE_ALIGN_BY)\n#define DUK_USE_ALIGN_BY 8\n#endif\n\n/* Compiler specific hackery needed to force struct size to match alignment,\n * see e.g. duk_hbuffer.h.\n *\n * http://stackoverflow.com/questions/11130109/c-struct-size-alignment\n * http://stackoverflow.com/questions/10951039/specifying-64-bit-alignment\n */\n#if !(defined(DUK_USE_PACK_MSVC_PRAGMA) || defined(DUK_USE_PACK_GCC_ATTR) || \\\n      defined(DUK_USE_PACK_CLANG_ATTR) || defined(DUK_USE_PACK_DUMMY_MEMBER))\n#define DUK_USE_PACK_DUMMY_MEMBER\n#endif\n\n#if !defined(DUK_U64_CONSTANT)\n#define DUK_U64_CONSTANT(x) x##ULL\n#endif\n#if !defined(DUK_I64_CONSTANT)\n#define DUK_I64_CONSTANT(x) x##LL\n#endif\n\n#if !defined(DUK_VA_COPY)\n/* We need va_copy() which is defined in C99 / C++11, so an awkward\n * replacement is needed for pre-C99 / pre-C++11 environments.  This\n * will quite likely need portability hacks for some non-C99\n * environments.\n */\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n/* C99 / C++11 and above: rely on va_copy() which is required.\n * Omit parenthesis on macro right side on purpose to minimize differences\n * to direct use.\n */\n#define DUK_VA_COPY(dest,src) va_copy(dest,src)\n#else\n/* Pre-C99: va_list type is implementation dependent.  This replacement\n * assumes it is a plain value so that a simple assignment will work.\n * This is not the case on all platforms (it may be a single-array element,\n * for instance).\n */\n#define DUK_VA_COPY(dest,src) do { (dest) = (src); } while (0)\n#endif\n#endif\n\n#if !defined(DUK_MACRO_STRINGIFY)\n/* Macro hackery to convert e.g. __LINE__ to a string without formatting,\n * see: http://stackoverflow.com/questions/240353/convert-a-preprocessor-token-to-a-string\n */\n#define DUK_MACRO_STRINGIFY_HELPER(x)  #x\n#define DUK_MACRO_STRINGIFY(x)  DUK_MACRO_STRINGIFY_HELPER(x)\n#endif\n\n#if !defined(DUK_CAUSE_SEGFAULT)\n/* This can be used for testing; valgrind will then indicate the C call stack\n * leading to the call site.\n */\n#define DUK_CAUSE_SEGFAULT()  do { *((volatile duk_uint32_t *) NULL) = (duk_uint32_t) 0xdeadbeefUL; } while (0)\n#endif\n\n#if !defined(DUK_UNREF)\n/* Macro for suppressing warnings for potentially unreferenced variables.\n * The variables can be actually unreferenced or unreferenced in some\n * specific cases only; for instance, if a variable is only debug printed,\n * it is unreferenced when debug printing is disabled.  May cause warnings\n * for volatile arguments.\n */\n#define DUK_UNREF(x)  do { (void) (x); } while (0)\n#endif\n\n/* Fillin for DUK_NORETURN; DUK_WO_NORETURN() is used to insert dummy\n * dummy statements after noreturn calls to silence harmless compiler\n * warnings, e.g.:\n *\n *   DUK_ERROR_TYPE(thr, \"aiee\");\n *   DUK_WO_NORETURN(return 0;);\n *\n * Statements inside DUK_WO_NORETURN() must NEVER be actually reachable,\n * and they're only included to satisfy the compiler.\n */\n#if defined(DUK_NORETURN)\n#define DUK_WO_NORETURN(stmt) do { } while (0)\n#else\n#define DUK_NORETURN(decl)  decl\n#define DUK_WO_NORETURN(stmt) do { stmt } while (0)\n#endif\n\n#if !defined(DUK_UNREACHABLE)\n/* Don't know how to declare unreachable point, so don't do it; this\n * may cause some spurious compilation warnings (e.g. \"variable used\n * uninitialized\").\n */\n#define DUK_UNREACHABLE()  do { } while (0)\n#endif\n\n#if !defined(DUK_LOSE_CONST)\n/* Convert any input pointer into a \"void *\", losing a const qualifier.\n * This is not fully portable because casting through duk_uintptr_t may\n * not work on all architectures (e.g. those with long, segmented pointers).\n */\n#define DUK_LOSE_CONST(src) ((void *) (duk_uintptr_t) (src))\n#endif\n\n#if !defined(DUK_LIKELY)\n#define DUK_LIKELY(x)    (x)\n#endif\n#if !defined(DUK_UNLIKELY)\n#define DUK_UNLIKELY(x)  (x)\n#endif\n#if !defined(DUK_UNPREDICTABLE)\n#define DUK_UNPREDICTABLE(x)  (x)\n#endif\n\n#if !defined(DUK_NOINLINE)\n#define DUK_NOINLINE       /*nop*/\n#endif\n#if !defined(DUK_INLINE)\n#define DUK_INLINE         /*nop*/\n#endif\n#if !defined(DUK_ALWAYS_INLINE)\n#define DUK_ALWAYS_INLINE  /*nop*/\n#endif\n\n#if !defined(DUK_HOT)\n#define DUK_HOT            /*nop*/\n#endif\n#if !defined(DUK_COLD)\n#define DUK_COLD           /*nop*/\n#endif\n\n#if !defined(DUK_EXTERNAL_DECL)\n#define DUK_EXTERNAL_DECL  extern\n#endif\n#if !defined(DUK_EXTERNAL)\n#define DUK_EXTERNAL       /*empty*/\n#endif\n#if !defined(DUK_INTERNAL_DECL)\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL_DECL  static\n#else\n#define DUK_INTERNAL_DECL  extern\n#endif\n#endif\n#if !defined(DUK_INTERNAL)\n#if defined(DUK_SINGLE_FILE)\n#define DUK_INTERNAL       static\n#else\n#define DUK_INTERNAL       /*empty*/\n#endif\n#endif\n#if !defined(DUK_LOCAL_DECL)\n#define DUK_LOCAL_DECL     static\n#endif\n#if !defined(DUK_LOCAL)\n#define DUK_LOCAL          static\n#endif\n\n#if !defined(DUK_FILE_MACRO)\n#define DUK_FILE_MACRO  __FILE__\n#endif\n#if !defined(DUK_LINE_MACRO)\n#define DUK_LINE_MACRO  __LINE__\n#endif\n#if !defined(DUK_FUNC_MACRO)\n#if defined(DUK_F_C99) || defined(DUK_F_CPP11)\n#define DUK_FUNC_MACRO  __func__\n#elif defined(__FUNCTION__)\n#define DUK_FUNC_MACRO  __FUNCTION__\n#else\n#define DUK_FUNC_MACRO  \"unknown\"\n#endif\n#endif\n\n#if defined(DUK_F_HAVE_64BIT)\n#if !defined(DUK_BSWAP64)\n#define DUK_BSWAP64(x) \\\n\t((((duk_uint64_t) (x)) >> 56U) | \\\n\t ((((duk_uint64_t) (x)) >> 40U) & DUK_U64_CONSTANT(0xff00)) | \\\n\t ((((duk_uint64_t) (x)) >> 24U) & DUK_U64_CONSTANT(0xff0000)) | \\\n\t ((((duk_uint64_t) (x)) >> 8U) & DUK_U64_CONSTANT(0xff000000)) | \\\n\t ((((duk_uint64_t) (x)) << 8U) & DUK_U64_CONSTANT(0xff00000000)) | \\\n\t ((((duk_uint64_t) (x)) << 24U) & DUK_U64_CONSTANT(0xff0000000000)) | \\\n\t ((((duk_uint64_t) (x)) << 40U) & DUK_U64_CONSTANT(0xff000000000000)) | \\\n\t (((duk_uint64_t) (x)) << 56U))\n#endif\n#endif\n#if !defined(DUK_BSWAP32)\n#define DUK_BSWAP32(x) \\\n\t((((duk_uint32_t) (x)) >> 24U) | \\\n\t ((((duk_uint32_t) (x)) >> 8U) & 0xff00UL) | \\\n\t ((((duk_uint32_t) (x)) << 8U) & 0xff0000UL) | \\\n\t (((duk_uint32_t) (x)) << 24U))\n#endif\n#if !defined(DUK_BSWAP16)\n#define DUK_BSWAP16(x) \\\n\t((duk_uint16_t) (x) >> 8U) | \\\n\t((duk_uint16_t) (x) << 8U)\n#endif\n\n/* DUK_USE_VARIADIC_MACROS: required from compilers, so no fill-in. */\n/* DUK_USE_UNION_INITIALIZERS: required from compilers, so no fill-in. */\n\n#if !(defined(DUK_USE_FLEX_C99) || defined(DUK_USE_FLEX_ZEROSIZE) || defined(DUK_USE_FLEX_ONESIZE))\n#if defined(DUK_F_C99)\n#define DUK_USE_FLEX_C99\n#else\n#define DUK_USE_FLEX_ZEROSIZE  /* Not standard but common enough */\n#endif\n#endif\n\n#if !(defined(DUK_USE_PACK_GCC_ATTR) || defined(DUK_USE_PACK_CLANG_ATTR) || \\\n      defined(DUK_USE_PACK_MSVC_PRAGMA) || defined(DUK_USE_PACK_DUMMY_MEMBER))\n#define DUK_USE_PACK_DUMMY_MEMBER\n#endif\n\n#if 0  /* not defined by default */\n#undef DUK_USE_GCC_PRAGMAS\n#endif\n\n/* Workaround for GH-323: avoid inlining control when compiling from\n * multiple sources, as it causes compiler portability trouble.\n */\n#if !defined(DUK_SINGLE_FILE)\n#undef DUK_NOINLINE\n#undef DUK_INLINE\n#undef DUK_ALWAYS_INLINE\n#define DUK_NOINLINE       /*nop*/\n#define DUK_INLINE         /*nop*/\n#define DUK_ALWAYS_INLINE  /*nop*/\n#endif\n\n/*\n *  Check whether or not a packed duk_tval representation is possible.\n *  What's basically required is that pointers are 32-bit values\n *  (sizeof(void *) == 4).  Best effort check, not always accurate.\n *  If guess goes wrong, crashes may result; self tests also verify\n *  the guess.\n */\n\n/* Explicit marker needed; may be 'defined', 'undefined, 'or 'not provided'. */\n#if !defined(DUK_F_PACKED_TVAL_PROVIDED)\n#undef DUK_F_PACKED_TVAL_POSSIBLE\n\n/* Strict C99 case: DUK_UINTPTR_MAX (= UINTPTR_MAX) should be very reliable */\n#if !defined(DUK_F_PACKED_TVAL_POSSIBLE) && defined(DUK_UINTPTR_MAX)\n#if (DUK_UINTPTR_MAX <= 0xffffffffUL)\n#define DUK_F_PACKED_TVAL_POSSIBLE\n#endif\n#endif\n\n/* Non-C99 case, still relying on DUK_UINTPTR_MAX, as long as it is not a computed value */\n#if !defined(DUK_F_PACKED_TVAL_POSSIBLE) && defined(DUK_UINTPTR_MAX) && !defined(DUK_UINTPTR_MAX_COMPUTED)\n#if (DUK_UINTPTR_MAX <= 0xffffffffUL)\n#define DUK_F_PACKED_TVAL_POSSIBLE\n#endif\n#endif\n\n/* DUK_SIZE_MAX (= SIZE_MAX) is often reliable */\n#if !defined(DUK_F_PACKED_TVAL_POSSIBLE) && defined(DUK_SIZE_MAX) && !defined(DUK_SIZE_MAX_COMPUTED)\n#if (DUK_SIZE_MAX <= 0xffffffffUL)\n#define DUK_F_PACKED_TVAL_POSSIBLE\n#endif\n#endif\n\n#undef DUK_USE_PACKED_TVAL\n#if defined(DUK_F_PACKED_TVAL_POSSIBLE)\n#define DUK_USE_PACKED_TVAL\n#endif\n#undef DUK_F_PACKED_TVAL_POSSIBLE\n\n#endif  /* DUK_F_PACKED_TVAL_PROVIDED */\n/* Object property allocation layout has implications for memory and code\n * footprint and generated code size/speed.  The best layout also depends\n * on whether the platform has alignment requirements or benefits from\n * having mostly aligned accesses.\n */\n#undef DUK_USE_HOBJECT_LAYOUT_1\n#undef DUK_USE_HOBJECT_LAYOUT_2\n#undef DUK_USE_HOBJECT_LAYOUT_3\n#if (DUK_USE_ALIGN_BY == 1)\n/* On platforms without any alignment issues, layout 1 is preferable\n * because it compiles to slightly less code and provides direct access\n * to property keys.\n */\n#define DUK_USE_HOBJECT_LAYOUT_1\n#else\n/* On other platforms use layout 2, which requires some padding but\n * is a bit more natural than layout 3 in ordering the entries.  Layout\n * 3 is currently not used.\n */\n#define DUK_USE_HOBJECT_LAYOUT_2\n#endif\n\n/* GCC/clang inaccurate math would break compliance and probably duk_tval,\n * so refuse to compile.  Relax this if -ffast-math is tested to work.\n */\n#if defined(__FAST_MATH__)\n#error __FAST_MATH__ defined, refusing to compile\n#endif\n\n/*\n *  Autogenerated defaults\n */\n\n#undef DUK_USE_ALLOW_UNDEFINED_BEHAVIOR\n#define DUK_USE_ARRAY_BUILTIN\n#define DUK_USE_ARRAY_FASTPATH\n#define DUK_USE_ARRAY_PROP_FASTPATH\n#undef DUK_USE_ASSERTIONS\n#define DUK_USE_AUGMENT_ERROR_CREATE\n#define DUK_USE_AUGMENT_ERROR_THROW\n#define DUK_USE_AVOID_PLATFORM_FUNCPTRS\n#define DUK_USE_BASE64_FASTPATH\n#define DUK_USE_BASE64_SUPPORT\n#define DUK_USE_BOOLEAN_BUILTIN\n#define DUK_USE_BUFFEROBJECT_SUPPORT\n#undef DUK_USE_BUFLEN16\n#define DUK_USE_BYTECODE_DUMP_SUPPORT\n#define DUK_USE_CACHE_ACTIVATION\n#define DUK_USE_CACHE_CATCHER\n#define DUK_USE_CALLSTACK_LIMIT 10000\n#define DUK_USE_COMPILER_RECLIMIT 2500\n#define DUK_USE_COROUTINE_SUPPORT\n#undef DUK_USE_CPP_EXCEPTIONS\n#undef DUK_USE_DATAPTR16\n#undef DUK_USE_DATAPTR_DEC16\n#undef DUK_USE_DATAPTR_ENC16\n#define DUK_USE_DATE_BUILTIN\n#undef DUK_USE_DATE_FORMAT_STRING\n#undef DUK_USE_DATE_GET_LOCAL_TZOFFSET\n#undef DUK_USE_DATE_GET_NOW\n#undef DUK_USE_DATE_PARSE_STRING\n#undef DUK_USE_DATE_PRS_GETDATE\n#undef DUK_USE_DEBUG\n#undef DUK_USE_DEBUGGER_DUMPHEAP\n#undef DUK_USE_DEBUGGER_INSPECT\n#undef DUK_USE_DEBUGGER_PAUSE_UNCAUGHT\n#undef DUK_USE_DEBUGGER_SUPPORT\n#define DUK_USE_DEBUGGER_THROW_NOTIFY\n#undef DUK_USE_DEBUGGER_TRANSPORT_TORTURE\n#define DUK_USE_DEBUG_BUFSIZE 65536L\n#define DUK_USE_DEBUG_LEVEL 0\n#undef DUK_USE_DEBUG_WRITE\n#define DUK_USE_DOUBLE_LINKED_HEAP\n#define DUK_USE_DUKTAPE_BUILTIN\n#define DUK_USE_ENCODING_BUILTINS\n#define DUK_USE_ERRCREATE\n#define DUK_USE_ERRTHROW\n#define DUK_USE_ES6\n#define DUK_USE_ES6_OBJECT_PROTO_PROPERTY\n#define DUK_USE_ES6_OBJECT_SETPROTOTYPEOF\n#define DUK_USE_ES6_PROXY\n#define DUK_USE_ES6_REGEXP_SYNTAX\n#define DUK_USE_ES6_UNICODE_ESCAPE\n#define DUK_USE_ES7\n#define DUK_USE_ES7_EXP_OPERATOR\n#define DUK_USE_ES8\n#define DUK_USE_ES9\n#define DUK_USE_ESBC_LIMITS\n#define DUK_USE_ESBC_MAX_BYTES 2147418112L\n#define DUK_USE_ESBC_MAX_LINENUMBER 2147418112L\n#undef DUK_USE_EXEC_FUN_LOCAL\n#undef DUK_USE_EXEC_INDIRECT_BOUND_CHECK\n#undef DUK_USE_EXEC_PREFER_SIZE\n#define DUK_USE_EXEC_REGCONST_OPTIMIZE\n#undef DUK_USE_EXEC_TIMEOUT_CHECK\n#undef DUK_USE_EXPLICIT_NULL_INIT\n#undef DUK_USE_EXTSTR_FREE\n#undef DUK_USE_EXTSTR_INTERN_CHECK\n#undef DUK_USE_FASTINT\n#define DUK_USE_FAST_REFCOUNT_DEFAULT\n#undef DUK_USE_FATAL_HANDLER\n#define DUK_USE_FATAL_MAXLEN 128\n#define DUK_USE_FINALIZER_SUPPORT\n#undef DUK_USE_FINALIZER_TORTURE\n#undef DUK_USE_FUNCPTR16\n#undef DUK_USE_FUNCPTR_DEC16\n#undef DUK_USE_FUNCPTR_ENC16\n#define DUK_USE_FUNCTION_BUILTIN\n#define DUK_USE_FUNC_FILENAME_PROPERTY\n#define DUK_USE_FUNC_NAME_PROPERTY\n#undef DUK_USE_GC_TORTURE\n#undef DUK_USE_GET_MONOTONIC_TIME\n#undef DUK_USE_GET_RANDOM_DOUBLE\n#undef DUK_USE_GLOBAL_BINDING\n#define DUK_USE_GLOBAL_BUILTIN\n#undef DUK_USE_HEAPPTR16\n#undef DUK_USE_HEAPPTR_DEC16\n#undef DUK_USE_HEAPPTR_ENC16\n#define DUK_USE_HEX_FASTPATH\n#define DUK_USE_HEX_SUPPORT\n#define DUK_USE_HOBJECT_ARRAY_ABANDON_LIMIT 2\n#define DUK_USE_HOBJECT_ARRAY_FAST_RESIZE_LIMIT 9\n#define DUK_USE_HOBJECT_ARRAY_MINGROW_ADD 16\n#define DUK_USE_HOBJECT_ARRAY_MINGROW_DIVISOR 8\n#define DUK_USE_HOBJECT_ENTRY_MINGROW_ADD 16\n#define DUK_USE_HOBJECT_ENTRY_MINGROW_DIVISOR 8\n#define DUK_USE_HOBJECT_HASH_PART\n#define DUK_USE_HOBJECT_HASH_PROP_LIMIT 8\n#define DUK_USE_HSTRING_ARRIDX\n#define DUK_USE_HSTRING_CLEN\n#undef DUK_USE_HSTRING_EXTDATA\n#define DUK_USE_HSTRING_LAZY_CLEN\n#define DUK_USE_HTML_COMMENTS\n#define DUK_USE_IDCHAR_FASTPATH\n#undef DUK_USE_INJECT_HEAP_ALLOC_ERROR\n#undef DUK_USE_INTERRUPT_COUNTER\n#undef DUK_USE_INTERRUPT_DEBUG_FIXUP\n#define DUK_USE_JC\n#define DUK_USE_JSON_BUILTIN\n#define DUK_USE_JSON_DECNUMBER_FASTPATH\n#define DUK_USE_JSON_DECSTRING_FASTPATH\n#define DUK_USE_JSON_DEC_RECLIMIT 1000\n#define DUK_USE_JSON_EATWHITE_FASTPATH\n#define DUK_USE_JSON_ENC_RECLIMIT 1000\n#define DUK_USE_JSON_QUOTESTRING_FASTPATH\n#undef DUK_USE_JSON_STRINGIFY_FASTPATH\n#define DUK_USE_JSON_SUPPORT\n#define DUK_USE_JX\n#define DUK_USE_LEXER_SLIDING_WINDOW\n#undef DUK_USE_LIGHTFUNC_BUILTINS\n#define DUK_USE_LITCACHE_SIZE 256\n#define DUK_USE_MARK_AND_SWEEP_RECLIMIT 256\n#define DUK_USE_MATH_BUILTIN\n#define DUK_USE_NATIVE_CALL_RECLIMIT 1000\n#undef DUK_USE_NATIVE_STACK_CHECK\n#define DUK_USE_NONSTD_ARRAY_SPLICE_DELCOUNT\n#undef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY\n#undef DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY\n#define DUK_USE_NONSTD_FUNC_STMT\n#define DUK_USE_NONSTD_GETTER_KEY_ARGUMENT\n#define DUK_USE_NONSTD_JSON_ESC_U2028_U2029\n#define DUK_USE_NONSTD_SETTER_KEY_ARGUMENT\n#define DUK_USE_NONSTD_STRING_FROMCHARCODE_32BIT\n#define DUK_USE_NUMBER_BUILTIN\n#define DUK_USE_OBJECT_BUILTIN\n#undef DUK_USE_OBJSIZES16\n#undef DUK_USE_PARANOID_ERRORS\n#define DUK_USE_PC2LINE\n#define DUK_USE_PERFORMANCE_BUILTIN\n#undef DUK_USE_PREFER_SIZE\n#undef DUK_USE_PROMISE_BUILTIN\n#define DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS\n#undef DUK_USE_REFCOUNT16\n#define DUK_USE_REFCOUNT32\n#define DUK_USE_REFERENCE_COUNTING\n#define DUK_USE_REFLECT_BUILTIN\n#define DUK_USE_REGEXP_CANON_BITMAP\n#undef DUK_USE_REGEXP_CANON_WORKAROUND\n#define DUK_USE_REGEXP_COMPILER_RECLIMIT 10000\n#define DUK_USE_REGEXP_EXECUTOR_RECLIMIT 10000\n#define DUK_USE_REGEXP_SUPPORT\n#undef DUK_USE_ROM_GLOBAL_CLONE\n#undef DUK_USE_ROM_GLOBAL_INHERIT\n#undef DUK_USE_ROM_OBJECTS\n#define DUK_USE_ROM_PTRCOMP_FIRST 63488L\n#undef DUK_USE_ROM_STRINGS\n#define DUK_USE_SECTION_B\n#undef DUK_USE_SELF_TESTS\n#define DUK_USE_SHEBANG_COMMENTS\n#undef DUK_USE_SHUFFLE_TORTURE\n#define DUK_USE_SOURCE_NONBMP\n#undef DUK_USE_STRHASH16\n#undef DUK_USE_STRHASH_DENSE\n#define DUK_USE_STRHASH_SKIP_SHIFT 5\n#define DUK_USE_STRICT_DECL\n#undef DUK_USE_STRICT_UTF8_SOURCE\n#define DUK_USE_STRING_BUILTIN\n#undef DUK_USE_STRLEN16\n#define DUK_USE_STRTAB_GROW_LIMIT 17\n#define DUK_USE_STRTAB_MAXSIZE 268435456L\n#define DUK_USE_STRTAB_MINSIZE 1024\n#undef DUK_USE_STRTAB_PTRCOMP\n#define DUK_USE_STRTAB_RESIZE_CHECK_MASK 255\n#define DUK_USE_STRTAB_SHRINK_LIMIT 6\n#undef DUK_USE_STRTAB_TORTURE\n#define DUK_USE_SYMBOL_BUILTIN\n#define DUK_USE_TAILCALL\n#define DUK_USE_TARGET_INFO \"unknown\"\n#define DUK_USE_TRACEBACKS\n#define DUK_USE_TRACEBACK_DEPTH 10\n#define DUK_USE_VALSTACK_GROW_SHIFT 2\n#define DUK_USE_VALSTACK_LIMIT 1000000L\n#define DUK_USE_VALSTACK_SHRINK_CHECK_SHIFT 2\n#define DUK_USE_VALSTACK_SHRINK_SLACK_SHIFT 4\n#undef DUK_USE_VALSTACK_UNSAFE\n#define DUK_USE_VERBOSE_ERRORS\n#define DUK_USE_VERBOSE_EXECUTOR_ERRORS\n#define DUK_USE_VOLUNTARY_GC\n#define DUK_USE_ZERO_BUFFER_DATA\n\n/*\n *  You may add overriding #define/#undef directives below for\n *  customization.  You of course cannot un-#include or un-typedef\n *  anything; these require direct changes above.\n */\n\n/* __OVERRIDE_DEFINES__ */\n\n/*\n *  Conditional includes\n */\n\n#if defined(DUK_F_CPP) && defined(DUK_USE_CPP_EXCEPTIONS)\n#include <exception>  /* std::exception */\n#include <stdexcept>  /* std::runtime_error */\n#endif\n\n/*\n *  Date provider selection\n *\n *  User may define DUK_USE_DATE_GET_NOW() etc directly, in which case we'll\n *  rely on an external provider.  If this is not done, revert to previous\n *  behavior and use Unix/Windows built-in provider.\n */\n\n#if defined(DUK_COMPILING_DUKTAPE)\n\n#if defined(DUK_USE_DATE_GET_NOW)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_NOW_GETTIMEOFDAY)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_gettimeofday()\n#elif defined(DUK_USE_DATE_NOW_TIME)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_time()\n#elif defined(DUK_USE_DATE_NOW_WINDOWS)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_windows()\n#elif defined(DUK_USE_DATE_NOW_WINDOWS_SUBMS)\n#define DUK_USE_DATE_GET_NOW(ctx)            duk_bi_date_get_now_windows_subms()\n#else\n#error no provider for DUK_USE_DATE_GET_NOW()\n#endif\n\n#if defined(DUK_USE_DATE_GET_LOCAL_TZOFFSET)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_TZO_GMTIME_R) || defined(DUK_USE_DATE_TZO_GMTIME_S) || defined(DUK_USE_DATE_TZO_GMTIME)\n#define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d)   duk_bi_date_get_local_tzoffset_gmtime((d))\n#elif defined(DUK_USE_DATE_TZO_WINDOWS)\n#define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d)   duk_bi_date_get_local_tzoffset_windows((d))\n#elif defined(DUK_USE_DATE_TZO_WINDOWS_NO_DST)\n#define DUK_USE_DATE_GET_LOCAL_TZOFFSET(d)   duk_bi_date_get_local_tzoffset_windows_no_dst((d))\n#else\n#error no provider for DUK_USE_DATE_GET_LOCAL_TZOFFSET()\n#endif\n\n#if defined(DUK_USE_DATE_PARSE_STRING)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_PRS_STRPTIME)\n#define DUK_USE_DATE_PARSE_STRING(ctx,str)   duk_bi_date_parse_string_strptime((ctx), (str))\n#elif defined(DUK_USE_DATE_PRS_GETDATE)\n#define DUK_USE_DATE_PARSE_STRING(ctx,str)   duk_bi_date_parse_string_getdate((ctx), (str))\n#else\n/* No provider for DUK_USE_DATE_PARSE_STRING(), fall back to ISO 8601 only. */\n#endif\n\n#if defined(DUK_USE_DATE_FORMAT_STRING)\n/* External provider already defined. */\n#elif defined(DUK_USE_DATE_FMT_STRFTIME)\n#define DUK_USE_DATE_FORMAT_STRING(ctx,parts,tzoffset,flags) \\\n\tduk_bi_date_format_parts_strftime((ctx), (parts), (tzoffset), (flags))\n#else\n/* No provider for DUK_USE_DATE_FORMAT_STRING(), fall back to ISO 8601 only. */\n#endif\n\n#if defined(DUK_USE_GET_MONOTONIC_TIME)\n/* External provider already defined. */\n#elif defined(DUK_USE_GET_MONOTONIC_TIME_CLOCK_GETTIME)\n#define DUK_USE_GET_MONOTONIC_TIME(ctx)  duk_bi_date_get_monotonic_time_clock_gettime()\n#elif defined(DUK_USE_GET_MONOTONIC_TIME_WINDOWS_QPC)\n#define DUK_USE_GET_MONOTONIC_TIME(ctx)  duk_bi_date_get_monotonic_time_windows_qpc()\n#else\n/* No provider for DUK_USE_GET_MONOTONIC_TIME(), fall back to DUK_USE_DATE_GET_NOW(). */\n#endif\n\n#endif  /* DUK_COMPILING_DUKTAPE */\n\n/*\n *  Checks for legacy feature options (DUK_OPT_xxx)\n */\n\n#if defined(DUK_OPT_ASSERTIONS)\n#error unsupported legacy feature option DUK_OPT_ASSERTIONS used\n#endif\n#if defined(DUK_OPT_BUFFEROBJECT_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_BUFFEROBJECT_SUPPORT used\n#endif\n#if defined(DUK_OPT_BUFLEN16)\n#error unsupported legacy feature option DUK_OPT_BUFLEN16 used\n#endif\n#if defined(DUK_OPT_DATAPTR16)\n#error unsupported legacy feature option DUK_OPT_DATAPTR16 used\n#endif\n#if defined(DUK_OPT_DATAPTR_DEC16)\n#error unsupported legacy feature option DUK_OPT_DATAPTR_DEC16 used\n#endif\n#if defined(DUK_OPT_DATAPTR_ENC16)\n#error unsupported legacy feature option DUK_OPT_DATAPTR_ENC16 used\n#endif\n#if defined(DUK_OPT_DDDPRINT)\n#error unsupported legacy feature option DUK_OPT_DDDPRINT used\n#endif\n#if defined(DUK_OPT_DDPRINT)\n#error unsupported legacy feature option DUK_OPT_DDPRINT used\n#endif\n#if defined(DUK_OPT_DEBUG)\n#error unsupported legacy feature option DUK_OPT_DEBUG used\n#endif\n#if defined(DUK_OPT_DEBUGGER_DUMPHEAP)\n#error unsupported legacy feature option DUK_OPT_DEBUGGER_DUMPHEAP used\n#endif\n#if defined(DUK_OPT_DEBUGGER_FWD_LOGGING)\n#error unsupported legacy feature option DUK_OPT_DEBUGGER_FWD_LOGGING used\n#endif\n#if defined(DUK_OPT_DEBUGGER_FWD_PRINTALERT)\n#error unsupported legacy feature option DUK_OPT_DEBUGGER_FWD_PRINTALERT used\n#endif\n#if defined(DUK_OPT_DEBUGGER_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_DEBUGGER_SUPPORT used\n#endif\n#if defined(DUK_OPT_DEBUGGER_TRANSPORT_TORTURE)\n#error unsupported legacy feature option DUK_OPT_DEBUGGER_TRANSPORT_TORTURE used\n#endif\n#if defined(DUK_OPT_DEBUG_BUFSIZE)\n#error unsupported legacy feature option DUK_OPT_DEBUG_BUFSIZE used\n#endif\n#if defined(DUK_OPT_DECLARE)\n#error unsupported legacy feature option DUK_OPT_DECLARE used\n#endif\n#if defined(DUK_OPT_DEEP_C_STACK)\n#error unsupported legacy feature option DUK_OPT_DEEP_C_STACK used\n#endif\n#if defined(DUK_OPT_DLL_BUILD)\n#error unsupported legacy feature option DUK_OPT_DLL_BUILD used\n#endif\n#if defined(DUK_OPT_DPRINT)\n#error unsupported legacy feature option DUK_OPT_DPRINT used\n#endif\n#if defined(DUK_OPT_DPRINT_COLORS)\n#error unsupported legacy feature option DUK_OPT_DPRINT_COLORS used\n#endif\n#if defined(DUK_OPT_DPRINT_RDTSC)\n#error unsupported legacy feature option DUK_OPT_DPRINT_RDTSC used\n#endif\n#if defined(DUK_OPT_EXEC_TIMEOUT_CHECK)\n#error unsupported legacy feature option DUK_OPT_EXEC_TIMEOUT_CHECK used\n#endif\n#if defined(DUK_OPT_EXTERNAL_STRINGS)\n#error unsupported legacy feature option DUK_OPT_EXTERNAL_STRINGS used\n#endif\n#if defined(DUK_OPT_EXTSTR_FREE)\n#error unsupported legacy feature option DUK_OPT_EXTSTR_FREE used\n#endif\n#if defined(DUK_OPT_EXTSTR_INTERN_CHECK)\n#error unsupported legacy feature option DUK_OPT_EXTSTR_INTERN_CHECK used\n#endif\n#if defined(DUK_OPT_FASTINT)\n#error unsupported legacy feature option DUK_OPT_FASTINT used\n#endif\n#if defined(DUK_OPT_FORCE_ALIGN)\n#error unsupported legacy feature option DUK_OPT_FORCE_ALIGN used\n#endif\n#if defined(DUK_OPT_FORCE_BYTEORDER)\n#error unsupported legacy feature option DUK_OPT_FORCE_BYTEORDER used\n#endif\n#if defined(DUK_OPT_FUNCPTR16)\n#error unsupported legacy feature option DUK_OPT_FUNCPTR16 used\n#endif\n#if defined(DUK_OPT_FUNCPTR_DEC16)\n#error unsupported legacy feature option DUK_OPT_FUNCPTR_DEC16 used\n#endif\n#if defined(DUK_OPT_FUNCPTR_ENC16)\n#error unsupported legacy feature option DUK_OPT_FUNCPTR_ENC16 used\n#endif\n#if defined(DUK_OPT_FUNC_NONSTD_CALLER_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_FUNC_NONSTD_CALLER_PROPERTY used\n#endif\n#if defined(DUK_OPT_FUNC_NONSTD_SOURCE_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_FUNC_NONSTD_SOURCE_PROPERTY used\n#endif\n#if defined(DUK_OPT_GC_TORTURE)\n#error unsupported legacy feature option DUK_OPT_GC_TORTURE used\n#endif\n#if defined(DUK_OPT_HAVE_CUSTOM_H)\n#error unsupported legacy feature option DUK_OPT_HAVE_CUSTOM_H used\n#endif\n#if defined(DUK_OPT_HEAPPTR16)\n#error unsupported legacy feature option DUK_OPT_HEAPPTR16 used\n#endif\n#if defined(DUK_OPT_HEAPPTR_DEC16)\n#error unsupported legacy feature option DUK_OPT_HEAPPTR_DEC16 used\n#endif\n#if defined(DUK_OPT_HEAPPTR_ENC16)\n#error unsupported legacy feature option DUK_OPT_HEAPPTR_ENC16 used\n#endif\n#if defined(DUK_OPT_INTERRUPT_COUNTER)\n#error unsupported legacy feature option DUK_OPT_INTERRUPT_COUNTER used\n#endif\n#if defined(DUK_OPT_JSON_STRINGIFY_FASTPATH)\n#error unsupported legacy feature option DUK_OPT_JSON_STRINGIFY_FASTPATH used\n#endif\n#if defined(DUK_OPT_LIGHTFUNC_BUILTINS)\n#error unsupported legacy feature option DUK_OPT_LIGHTFUNC_BUILTINS used\n#endif\n#if defined(DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY used\n#endif\n#if defined(DUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY used\n#endif\n#if defined(DUK_OPT_NO_ARRAY_SPLICE_NONSTD_DELCOUNT)\n#error unsupported legacy feature option DUK_OPT_NO_ARRAY_SPLICE_NONSTD_DELCOUNT used\n#endif\n#if defined(DUK_OPT_NO_AUGMENT_ERRORS)\n#error unsupported legacy feature option DUK_OPT_NO_AUGMENT_ERRORS used\n#endif\n#if defined(DUK_OPT_NO_BROWSER_LIKE)\n#error unsupported legacy feature option DUK_OPT_NO_BROWSER_LIKE used\n#endif\n#if defined(DUK_OPT_NO_BUFFEROBJECT_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_NO_BUFFEROBJECT_SUPPORT used\n#endif\n#if defined(DUK_OPT_NO_BYTECODE_DUMP_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_NO_BYTECODE_DUMP_SUPPORT used\n#endif\n#if defined(DUK_OPT_NO_COMMONJS_MODULES)\n#error unsupported legacy feature option DUK_OPT_NO_COMMONJS_MODULES used\n#endif\n#if defined(DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY used\n#endif\n#if defined(DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF)\n#error unsupported legacy feature option DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF used\n#endif\n#if defined(DUK_OPT_NO_ES6_PROXY)\n#error unsupported legacy feature option DUK_OPT_NO_ES6_PROXY used\n#endif\n#if defined(DUK_OPT_NO_FILE_IO)\n#error unsupported legacy feature option DUK_OPT_NO_FILE_IO used\n#endif\n#if defined(DUK_OPT_NO_FUNC_STMT)\n#error unsupported legacy feature option DUK_OPT_NO_FUNC_STMT used\n#endif\n#if defined(DUK_OPT_NO_JC)\n#error unsupported legacy feature option DUK_OPT_NO_JC used\n#endif\n#if defined(DUK_OPT_NO_JSONC)\n#error unsupported legacy feature option DUK_OPT_NO_JSONC used\n#endif\n#if defined(DUK_OPT_NO_JSONX)\n#error unsupported legacy feature option DUK_OPT_NO_JSONX used\n#endif\n#if defined(DUK_OPT_NO_JX)\n#error unsupported legacy feature option DUK_OPT_NO_JX used\n#endif\n#if defined(DUK_OPT_NO_MARK_AND_SWEEP)\n#error unsupported legacy feature option DUK_OPT_NO_MARK_AND_SWEEP used\n#endif\n#if defined(DUK_OPT_NO_MS_STRINGTABLE_RESIZE)\n#error unsupported legacy feature option DUK_OPT_NO_MS_STRINGTABLE_RESIZE used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_ACCESSOR_KEY_ARGUMENT)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_ACCESSOR_KEY_ARGUMENT used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_ARRAY_CONCAT_TRAILER)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_ARRAY_CONCAT_TRAILER used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_ARRAY_MAP_TRAILER)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_ARRAY_MAP_TRAILER used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_FUNC_STMT)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_FUNC_STMT used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_JSON_ESC_U2028_U2029)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_JSON_ESC_U2028_U2029 used\n#endif\n#if defined(DUK_OPT_NO_NONSTD_STRING_FROMCHARCODE_32BIT)\n#error unsupported legacy feature option DUK_OPT_NO_NONSTD_STRING_FROMCHARCODE_32BIT used\n#endif\n#if defined(DUK_OPT_NO_OBJECT_ES6_PROTO_PROPERTY)\n#error unsupported legacy feature option DUK_OPT_NO_OBJECT_ES6_PROTO_PROPERTY used\n#endif\n#if defined(DUK_OPT_NO_OBJECT_ES6_SETPROTOTYPEOF)\n#error unsupported legacy feature option DUK_OPT_NO_OBJECT_ES6_SETPROTOTYPEOF used\n#endif\n#if defined(DUK_OPT_NO_OCTAL_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_NO_OCTAL_SUPPORT used\n#endif\n#if defined(DUK_OPT_NO_PACKED_TVAL)\n#error unsupported legacy feature option DUK_OPT_NO_PACKED_TVAL used\n#endif\n#if defined(DUK_OPT_NO_PC2LINE)\n#error unsupported legacy feature option DUK_OPT_NO_PC2LINE used\n#endif\n#if defined(DUK_OPT_NO_REFERENCE_COUNTING)\n#error unsupported legacy feature option DUK_OPT_NO_REFERENCE_COUNTING used\n#endif\n#if defined(DUK_OPT_NO_REGEXP_SUPPORT)\n#error unsupported legacy feature option DUK_OPT_NO_REGEXP_SUPPORT used\n#endif\n#if defined(DUK_OPT_NO_SECTION_B)\n#error unsupported legacy feature option DUK_OPT_NO_SECTION_B used\n#endif\n#if defined(DUK_OPT_NO_SOURCE_NONBMP)\n#error unsupported legacy feature option DUK_OPT_NO_SOURCE_NONBMP used\n#endif\n#if defined(DUK_OPT_NO_STRICT_DECL)\n#error unsupported legacy feature option DUK_OPT_NO_STRICT_DECL used\n#endif\n#if defined(DUK_OPT_NO_TRACEBACKS)\n#error unsupported legacy feature option DUK_OPT_NO_TRACEBACKS used\n#endif\n#if defined(DUK_OPT_NO_VERBOSE_ERRORS)\n#error unsupported legacy feature option DUK_OPT_NO_VERBOSE_ERRORS used\n#endif\n#if defined(DUK_OPT_NO_VOLUNTARY_GC)\n#error unsupported legacy feature option DUK_OPT_NO_VOLUNTARY_GC used\n#endif\n#if defined(DUK_OPT_NO_ZERO_BUFFER_DATA)\n#error unsupported legacy feature option DUK_OPT_NO_ZERO_BUFFER_DATA used\n#endif\n#if defined(DUK_OPT_OBJSIZES16)\n#error unsupported legacy feature option DUK_OPT_OBJSIZES16 used\n#endif\n#if defined(DUK_OPT_PANIC_HANDLER)\n#error unsupported legacy feature option DUK_OPT_PANIC_HANDLER used\n#endif\n#if defined(DUK_OPT_REFCOUNT16)\n#error unsupported legacy feature option DUK_OPT_REFCOUNT16 used\n#endif\n#if defined(DUK_OPT_SEGFAULT_ON_PANIC)\n#error unsupported legacy feature option DUK_OPT_SEGFAULT_ON_PANIC used\n#endif\n#if defined(DUK_OPT_SELF_TESTS)\n#error unsupported legacy feature option DUK_OPT_SELF_TESTS used\n#endif\n#if defined(DUK_OPT_SETJMP)\n#error unsupported legacy feature option DUK_OPT_SETJMP used\n#endif\n#if defined(DUK_OPT_SHUFFLE_TORTURE)\n#error unsupported legacy feature option DUK_OPT_SHUFFLE_TORTURE used\n#endif\n#if defined(DUK_OPT_SIGSETJMP)\n#error unsupported legacy feature option DUK_OPT_SIGSETJMP used\n#endif\n#if defined(DUK_OPT_STRHASH16)\n#error unsupported legacy feature option DUK_OPT_STRHASH16 used\n#endif\n#if defined(DUK_OPT_STRICT_UTF8_SOURCE)\n#error unsupported legacy feature option DUK_OPT_STRICT_UTF8_SOURCE used\n#endif\n#if defined(DUK_OPT_STRLEN16)\n#error unsupported legacy feature option DUK_OPT_STRLEN16 used\n#endif\n#if defined(DUK_OPT_STRTAB_CHAIN)\n#error unsupported legacy feature option DUK_OPT_STRTAB_CHAIN used\n#endif\n#if defined(DUK_OPT_STRTAB_CHAIN_SIZE)\n#error unsupported legacy feature option DUK_OPT_STRTAB_CHAIN_SIZE used\n#endif\n#if defined(DUK_OPT_TARGET_INFO)\n#error unsupported legacy feature option DUK_OPT_TARGET_INFO used\n#endif\n#if defined(DUK_OPT_TRACEBACK_DEPTH)\n#error unsupported legacy feature option DUK_OPT_TRACEBACK_DEPTH used\n#endif\n#if defined(DUK_OPT_UNDERSCORE_SETJMP)\n#error unsupported legacy feature option DUK_OPT_UNDERSCORE_SETJMP used\n#endif\n#if defined(DUK_OPT_USER_INITJS)\n#error unsupported legacy feature option DUK_OPT_USER_INITJS used\n#endif\n\n/*\n *  Checks for config option consistency (DUK_USE_xxx)\n */\n\n#if defined(DUK_USE_32BIT_PTRS)\n#error unsupported config option used (option has been removed): DUK_USE_32BIT_PTRS\n#endif\n#if defined(DUK_USE_ALIGN_4)\n#error unsupported config option used (option has been removed): DUK_USE_ALIGN_4\n#endif\n#if defined(DUK_USE_ALIGN_8)\n#error unsupported config option used (option has been removed): DUK_USE_ALIGN_8\n#endif\n#if defined(DUK_USE_BROWSER_LIKE)\n#error unsupported config option used (option has been removed): DUK_USE_BROWSER_LIKE\n#endif\n#if defined(DUK_USE_BUILTIN_INITJS)\n#error unsupported config option used (option has been removed): DUK_USE_BUILTIN_INITJS\n#endif\n#if defined(DUK_USE_BYTEORDER_FORCED)\n#error unsupported config option used (option has been removed): DUK_USE_BYTEORDER_FORCED\n#endif\n#if defined(DUK_USE_COMMONJS_MODULES)\n#error unsupported config option used (option has been removed): DUK_USE_COMMONJS_MODULES\n#endif\n#if defined(DUK_USE_DATAPTR_DEC16) && !defined(DUK_USE_DATAPTR16)\n#error config option DUK_USE_DATAPTR_DEC16 requires option DUK_USE_DATAPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_DATAPTR_ENC16) && !defined(DUK_USE_DATAPTR16)\n#error config option DUK_USE_DATAPTR_ENC16 requires option DUK_USE_DATAPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_DDDPRINT)\n#error unsupported config option used (option has been removed): DUK_USE_DDDPRINT\n#endif\n#if defined(DUK_USE_DDPRINT)\n#error unsupported config option used (option has been removed): DUK_USE_DDPRINT\n#endif\n#if defined(DUK_USE_DEBUGGER_FWD_LOGGING)\n#error unsupported config option used (option has been removed): DUK_USE_DEBUGGER_FWD_LOGGING\n#endif\n#if defined(DUK_USE_DEBUGGER_FWD_PRINTALERT)\n#error unsupported config option used (option has been removed): DUK_USE_DEBUGGER_FWD_PRINTALERT\n#endif\n#if defined(DUK_USE_DEBUGGER_SUPPORT) && !defined(DUK_USE_INTERRUPT_COUNTER)\n#error config option DUK_USE_DEBUGGER_SUPPORT requires option DUK_USE_INTERRUPT_COUNTER (which is missing)\n#endif\n#if defined(DUK_USE_DEEP_C_STACK)\n#error unsupported config option used (option has been removed): DUK_USE_DEEP_C_STACK\n#endif\n#if defined(DUK_USE_DOUBLE_BE)\n#error unsupported config option used (option has been removed): DUK_USE_DOUBLE_BE\n#endif\n#if defined(DUK_USE_DOUBLE_BE) && defined(DUK_USE_DOUBLE_LE)\n#error config option DUK_USE_DOUBLE_BE conflicts with option DUK_USE_DOUBLE_LE (which is also defined)\n#endif\n#if defined(DUK_USE_DOUBLE_BE) && defined(DUK_USE_DOUBLE_ME)\n#error config option DUK_USE_DOUBLE_BE conflicts with option DUK_USE_DOUBLE_ME (which is also defined)\n#endif\n#if defined(DUK_USE_DOUBLE_LE)\n#error unsupported config option used (option has been removed): DUK_USE_DOUBLE_LE\n#endif\n#if defined(DUK_USE_DOUBLE_LE) && defined(DUK_USE_DOUBLE_BE)\n#error config option DUK_USE_DOUBLE_LE conflicts with option DUK_USE_DOUBLE_BE (which is also defined)\n#endif\n#if defined(DUK_USE_DOUBLE_LE) && defined(DUK_USE_DOUBLE_ME)\n#error config option DUK_USE_DOUBLE_LE conflicts with option DUK_USE_DOUBLE_ME (which is also defined)\n#endif\n#if defined(DUK_USE_DOUBLE_ME)\n#error unsupported config option used (option has been removed): DUK_USE_DOUBLE_ME\n#endif\n#if defined(DUK_USE_DOUBLE_ME) && defined(DUK_USE_DOUBLE_LE)\n#error config option DUK_USE_DOUBLE_ME conflicts with option DUK_USE_DOUBLE_LE (which is also defined)\n#endif\n#if defined(DUK_USE_DOUBLE_ME) && defined(DUK_USE_DOUBLE_BE)\n#error config option DUK_USE_DOUBLE_ME conflicts with option DUK_USE_DOUBLE_BE (which is also defined)\n#endif\n#if defined(DUK_USE_DPRINT)\n#error unsupported config option used (option has been removed): DUK_USE_DPRINT\n#endif\n#if defined(DUK_USE_DPRINT) && !defined(DUK_USE_DEBUG)\n#error config option DUK_USE_DPRINT requires option DUK_USE_DEBUG (which is missing)\n#endif\n#if defined(DUK_USE_DPRINT_COLORS)\n#error unsupported config option used (option has been removed): DUK_USE_DPRINT_COLORS\n#endif\n#if defined(DUK_USE_DPRINT_RDTSC)\n#error unsupported config option used (option has been removed): DUK_USE_DPRINT_RDTSC\n#endif\n#if defined(DUK_USE_ES6_REGEXP_BRACES)\n#error unsupported config option used (option has been removed): DUK_USE_ES6_REGEXP_BRACES\n#endif\n#if defined(DUK_USE_ESBC_MAX_BYTES) && !defined(DUK_USE_ESBC_LIMITS)\n#error config option DUK_USE_ESBC_MAX_BYTES requires option DUK_USE_ESBC_LIMITS (which is missing)\n#endif\n#if defined(DUK_USE_ESBC_MAX_LINENUMBER) && !defined(DUK_USE_ESBC_LIMITS)\n#error config option DUK_USE_ESBC_MAX_LINENUMBER requires option DUK_USE_ESBC_LIMITS (which is missing)\n#endif\n#if defined(DUK_USE_EXEC_TIMEOUT_CHECK) && !defined(DUK_USE_INTERRUPT_COUNTER)\n#error config option DUK_USE_EXEC_TIMEOUT_CHECK requires option DUK_USE_INTERRUPT_COUNTER (which is missing)\n#endif\n#if defined(DUK_USE_EXTSTR_FREE) && !defined(DUK_USE_HSTRING_EXTDATA)\n#error config option DUK_USE_EXTSTR_FREE requires option DUK_USE_HSTRING_EXTDATA (which is missing)\n#endif\n#if defined(DUK_USE_EXTSTR_INTERN_CHECK) && !defined(DUK_USE_HSTRING_EXTDATA)\n#error config option DUK_USE_EXTSTR_INTERN_CHECK requires option DUK_USE_HSTRING_EXTDATA (which is missing)\n#endif\n#if defined(DUK_USE_FASTINT) && !defined(DUK_USE_64BIT_OPS)\n#error config option DUK_USE_FASTINT requires option DUK_USE_64BIT_OPS (which is missing)\n#endif\n#if defined(DUK_USE_FILE_IO)\n#error unsupported config option used (option has been removed): DUK_USE_FILE_IO\n#endif\n#if defined(DUK_USE_FULL_TVAL)\n#error unsupported config option used (option has been removed): DUK_USE_FULL_TVAL\n#endif\n#if defined(DUK_USE_FUNCPTR_DEC16) && !defined(DUK_USE_FUNCPTR16)\n#error config option DUK_USE_FUNCPTR_DEC16 requires option DUK_USE_FUNCPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_FUNCPTR_ENC16) && !defined(DUK_USE_FUNCPTR16)\n#error config option DUK_USE_FUNCPTR_ENC16 requires option DUK_USE_FUNCPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS)\n#error unsupported config option used (option has been removed): DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS\n#endif\n#if defined(DUK_USE_HEAPPTR16) && defined(DUK_USE_DEBUG)\n#error config option DUK_USE_HEAPPTR16 conflicts with option DUK_USE_DEBUG (which is also defined)\n#endif\n#if defined(DUK_USE_HEAPPTR_DEC16) && !defined(DUK_USE_HEAPPTR16)\n#error config option DUK_USE_HEAPPTR_DEC16 requires option DUK_USE_HEAPPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_HEAPPTR_ENC16) && !defined(DUK_USE_HEAPPTR16)\n#error config option DUK_USE_HEAPPTR_ENC16 requires option DUK_USE_HEAPPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_INTEGER_BE)\n#error unsupported config option used (option has been removed): DUK_USE_INTEGER_BE\n#endif\n#if defined(DUK_USE_INTEGER_BE) && defined(DUK_USE_INTEGER_LE)\n#error config option DUK_USE_INTEGER_BE conflicts with option DUK_USE_INTEGER_LE (which is also defined)\n#endif\n#if defined(DUK_USE_INTEGER_BE) && defined(DUK_USE_INTEGER_ME)\n#error config option DUK_USE_INTEGER_BE conflicts with option DUK_USE_INTEGER_ME (which is also defined)\n#endif\n#if defined(DUK_USE_INTEGER_LE)\n#error unsupported config option used (option has been removed): DUK_USE_INTEGER_LE\n#endif\n#if defined(DUK_USE_INTEGER_LE) && defined(DUK_USE_INTEGER_BE)\n#error config option DUK_USE_INTEGER_LE conflicts with option DUK_USE_INTEGER_BE (which is also defined)\n#endif\n#if defined(DUK_USE_INTEGER_LE) && defined(DUK_USE_INTEGER_ME)\n#error config option DUK_USE_INTEGER_LE conflicts with option DUK_USE_INTEGER_ME (which is also defined)\n#endif\n#if defined(DUK_USE_INTEGER_ME)\n#error unsupported config option used (option has been removed): DUK_USE_INTEGER_ME\n#endif\n#if defined(DUK_USE_INTEGER_ME) && defined(DUK_USE_INTEGER_LE)\n#error config option DUK_USE_INTEGER_ME conflicts with option DUK_USE_INTEGER_LE (which is also defined)\n#endif\n#if defined(DUK_USE_INTEGER_ME) && defined(DUK_USE_INTEGER_BE)\n#error config option DUK_USE_INTEGER_ME conflicts with option DUK_USE_INTEGER_BE (which is also defined)\n#endif\n#if defined(DUK_USE_MARKANDSWEEP_FINALIZER_TORTURE)\n#error unsupported config option used (option has been removed): DUK_USE_MARKANDSWEEP_FINALIZER_TORTURE\n#endif\n#if defined(DUK_USE_MARK_AND_SWEEP)\n#error unsupported config option used (option has been removed): DUK_USE_MARK_AND_SWEEP\n#endif\n#if defined(DUK_USE_MATH_FMAX)\n#error unsupported config option used (option has been removed): DUK_USE_MATH_FMAX\n#endif\n#if defined(DUK_USE_MATH_FMIN)\n#error unsupported config option used (option has been removed): DUK_USE_MATH_FMIN\n#endif\n#if defined(DUK_USE_MATH_ROUND)\n#error unsupported config option used (option has been removed): DUK_USE_MATH_ROUND\n#endif\n#if defined(DUK_USE_MS_STRINGTABLE_RESIZE)\n#error unsupported config option used (option has been removed): DUK_USE_MS_STRINGTABLE_RESIZE\n#endif\n#if defined(DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER)\n#error unsupported config option used (option has been removed): DUK_USE_NONSTD_ARRAY_CONCAT_TRAILER\n#endif\n#if defined(DUK_USE_NONSTD_ARRAY_MAP_TRAILER)\n#error unsupported config option used (option has been removed): DUK_USE_NONSTD_ARRAY_MAP_TRAILER\n#endif\n#if defined(DUK_USE_NONSTD_REGEXP_DOLLAR_ESCAPE)\n#error unsupported config option used (option has been removed): DUK_USE_NONSTD_REGEXP_DOLLAR_ESCAPE\n#endif\n#if defined(DUK_USE_NO_DOUBLE_ALIASING_SELFTEST)\n#error unsupported config option used (option has been removed): DUK_USE_NO_DOUBLE_ALIASING_SELFTEST\n#endif\n#if defined(DUK_USE_OCTAL_SUPPORT)\n#error unsupported config option used (option has been removed): DUK_USE_OCTAL_SUPPORT\n#endif\n#if defined(DUK_USE_PACKED_TVAL_POSSIBLE)\n#error unsupported config option used (option has been removed): DUK_USE_PACKED_TVAL_POSSIBLE\n#endif\n#if defined(DUK_USE_PANIC_ABORT)\n#error unsupported config option used (option has been removed): DUK_USE_PANIC_ABORT\n#endif\n#if defined(DUK_USE_PANIC_EXIT)\n#error unsupported config option used (option has been removed): DUK_USE_PANIC_EXIT\n#endif\n#if defined(DUK_USE_PANIC_HANDLER)\n#error unsupported config option used (option has been removed): DUK_USE_PANIC_HANDLER\n#endif\n#if defined(DUK_USE_PANIC_SEGFAULT)\n#error unsupported config option used (option has been removed): DUK_USE_PANIC_SEGFAULT\n#endif\n#if defined(DUK_USE_POW_NETBSD_WORKAROUND)\n#error unsupported config option used (option has been removed): DUK_USE_POW_NETBSD_WORKAROUND\n#endif\n#if defined(DUK_USE_RDTSC)\n#error unsupported config option used (option has been removed): DUK_USE_RDTSC\n#endif\n#if defined(DUK_USE_REFZERO_FINALIZER_TORTURE)\n#error unsupported config option used (option has been removed): DUK_USE_REFZERO_FINALIZER_TORTURE\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) && !defined(DUK_USE_ROM_STRINGS)\n#error config option DUK_USE_ROM_GLOBAL_CLONE requires option DUK_USE_ROM_STRINGS (which is missing)\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) && !defined(DUK_USE_ROM_OBJECTS)\n#error config option DUK_USE_ROM_GLOBAL_CLONE requires option DUK_USE_ROM_OBJECTS (which is missing)\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) && defined(DUK_USE_ROM_GLOBAL_INHERIT)\n#error config option DUK_USE_ROM_GLOBAL_CLONE conflicts with option DUK_USE_ROM_GLOBAL_INHERIT (which is also defined)\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_INHERIT) && !defined(DUK_USE_ROM_STRINGS)\n#error config option DUK_USE_ROM_GLOBAL_INHERIT requires option DUK_USE_ROM_STRINGS (which is missing)\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_INHERIT) && !defined(DUK_USE_ROM_OBJECTS)\n#error config option DUK_USE_ROM_GLOBAL_INHERIT requires option DUK_USE_ROM_OBJECTS (which is missing)\n#endif\n#if defined(DUK_USE_ROM_GLOBAL_INHERIT) && defined(DUK_USE_ROM_GLOBAL_CLONE)\n#error config option DUK_USE_ROM_GLOBAL_INHERIT conflicts with option DUK_USE_ROM_GLOBAL_CLONE (which is also defined)\n#endif\n#if defined(DUK_USE_ROM_OBJECTS) && !defined(DUK_USE_ROM_STRINGS)\n#error config option DUK_USE_ROM_OBJECTS requires option DUK_USE_ROM_STRINGS (which is missing)\n#endif\n#if defined(DUK_USE_ROM_STRINGS) && !defined(DUK_USE_ROM_OBJECTS)\n#error config option DUK_USE_ROM_STRINGS requires option DUK_USE_ROM_OBJECTS (which is missing)\n#endif\n#if defined(DUK_USE_SETJMP)\n#error unsupported config option used (option has been removed): DUK_USE_SETJMP\n#endif\n#if defined(DUK_USE_SIGSETJMP)\n#error unsupported config option used (option has been removed): DUK_USE_SIGSETJMP\n#endif\n#if defined(DUK_USE_STRTAB_CHAIN)\n#error unsupported config option used (option has been removed): DUK_USE_STRTAB_CHAIN\n#endif\n#if defined(DUK_USE_STRTAB_CHAIN_SIZE)\n#error unsupported config option used (option has been removed): DUK_USE_STRTAB_CHAIN_SIZE\n#endif\n#if defined(DUK_USE_STRTAB_CHAIN_SIZE) && !defined(DUK_USE_STRTAB_CHAIN)\n#error config option DUK_USE_STRTAB_CHAIN_SIZE requires option DUK_USE_STRTAB_CHAIN (which is missing)\n#endif\n#if defined(DUK_USE_STRTAB_PROBE)\n#error unsupported config option used (option has been removed): DUK_USE_STRTAB_PROBE\n#endif\n#if defined(DUK_USE_STRTAB_PTRCOMP) && !defined(DUK_USE_HEAPPTR16)\n#error config option DUK_USE_STRTAB_PTRCOMP requires option DUK_USE_HEAPPTR16 (which is missing)\n#endif\n#if defined(DUK_USE_TAILCALL) && defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n#error config option DUK_USE_TAILCALL conflicts with option DUK_USE_NONSTD_FUNC_CALLER_PROPERTY (which is also defined)\n#endif\n#if defined(DUK_USE_UNALIGNED_ACCESSES_POSSIBLE)\n#error unsupported config option used (option has been removed): DUK_USE_UNALIGNED_ACCESSES_POSSIBLE\n#endif\n#if defined(DUK_USE_UNDERSCORE_SETJMP)\n#error unsupported config option used (option has been removed): DUK_USE_UNDERSCORE_SETJMP\n#endif\n#if defined(DUK_USE_USER_DECLARE)\n#error unsupported config option used (option has been removed): DUK_USE_USER_DECLARE\n#endif\n#if defined(DUK_USE_USER_INITJS)\n#error unsupported config option used (option has been removed): DUK_USE_USER_INITJS\n#endif\n\n#if defined(DUK_USE_CPP_EXCEPTIONS) && !defined(__cplusplus)\n#error DUK_USE_CPP_EXCEPTIONS enabled but not compiling with a C++ compiler\n#endif\n\n/*\n *  Convert DUK_USE_BYTEORDER, from whatever source, into currently used\n *  internal defines.  If detection failed, #error out.\n */\n\n#if defined(DUK_USE_BYTEORDER)\n#if (DUK_USE_BYTEORDER == 1)\n#define DUK_USE_INTEGER_LE\n#define DUK_USE_DOUBLE_LE\n#elif (DUK_USE_BYTEORDER == 2)\n#define DUK_USE_INTEGER_LE  /* integer endianness is little on purpose */\n#define DUK_USE_DOUBLE_ME\n#elif (DUK_USE_BYTEORDER == 3)\n#define DUK_USE_INTEGER_BE\n#define DUK_USE_DOUBLE_BE\n#else\n#error unsupported: byte order invalid\n#endif  /* byte order */\n#else\n#error unsupported: byte order detection failed\n#endif  /* defined(DUK_USE_BYTEORDER) */\n\n#endif  /* DUK_CONFIG_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_dblunion.h",
    "content": "/*\n *  Union to access IEEE double memory representation, indexes for double\n *  memory representation, and some macros for double manipulation.\n *\n *  Also used by packed duk_tval.  Use a union for bit manipulation to\n *  minimize aliasing issues in practice.  The C99 standard does not\n *  guarantee that this should work, but it's a very widely supported\n *  practice for low level manipulation.\n *\n *  IEEE double format summary:\n *\n *    seeeeeee eeeeffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n *       A        B        C        D        E        F        G        H\n *\n *    s       sign bit\n *    eee...  exponent field\n *    fff...  fraction\n *\n *  See http://en.wikipedia.org/wiki/Double_precision_floating-point_format.\n *\n *  NaNs are represented as exponent 0x7ff and mantissa != 0.  The NaN is a\n *  signaling NaN when the highest bit of the mantissa is zero, and a quiet\n *  NaN when the highest bit is set.\n *\n *  At least three memory layouts are relevant here:\n *\n *    A B C D E F G H    Big endian (e.g. 68k)           DUK_USE_DOUBLE_BE\n *    H G F E D C B A    Little endian (e.g. x86)        DUK_USE_DOUBLE_LE\n *    D C B A H G F E    Mixed/cross endian (e.g. ARM)   DUK_USE_DOUBLE_ME\n *\n *  ARM is a special case: ARM double values are in mixed/cross endian\n *  format while ARM duk_uint64_t values are in standard little endian\n *  format (H G F E D C B A).  When a double is read as a duk_uint64_t\n *  from memory, the register will contain the (logical) value\n *  E F G H A B C D.  This requires some special handling below.\n *\n *  Indexes of various types (8-bit, 16-bit, 32-bit) in memory relative to\n *  the logical (big endian) order:\n *\n *  byte order      duk_uint8_t    duk_uint16_t     duk_uint32_t\n *    BE             01234567         0123               01\n *    LE             76543210         3210               10\n *    ME (ARM)       32107654         1032               01\n *\n *  Some processors may alter NaN values in a floating point load+store.\n *  For instance, on X86 a FLD + FSTP may convert a signaling NaN to a\n *  quiet one.  This is catastrophic when NaN space is used in packed\n *  duk_tval values.  See: misc/clang_aliasing.c.\n */\n\n#if !defined(DUK_DBLUNION_H_INCLUDED)\n#define DUK_DBLUNION_H_INCLUDED\n\n/*\n *  Union for accessing double parts, also serves as packed duk_tval\n */\n\nunion duk_double_union {\n\tdouble d;\n\tfloat f[2];\n#if defined(DUK_USE_64BIT_OPS)\n\tduk_uint64_t ull[1];\n#endif\n\tduk_uint32_t ui[2];\n\tduk_uint16_t us[4];\n\tduk_uint8_t uc[8];\n#if defined(DUK_USE_PACKED_TVAL)\n\tvoid *vp[2];  /* used by packed duk_tval, assumes sizeof(void *) == 4 */\n#endif\n};\n\ntypedef union duk_double_union duk_double_union;\n\n/*\n *  Indexes of various types with respect to big endian (logical) layout\n */\n\n#if defined(DUK_USE_DOUBLE_LE)\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBL_IDX_ULL0   0\n#endif\n#define DUK_DBL_IDX_UI0    1\n#define DUK_DBL_IDX_UI1    0\n#define DUK_DBL_IDX_US0    3\n#define DUK_DBL_IDX_US1    2\n#define DUK_DBL_IDX_US2    1\n#define DUK_DBL_IDX_US3    0\n#define DUK_DBL_IDX_UC0    7\n#define DUK_DBL_IDX_UC1    6\n#define DUK_DBL_IDX_UC2    5\n#define DUK_DBL_IDX_UC3    4\n#define DUK_DBL_IDX_UC4    3\n#define DUK_DBL_IDX_UC5    2\n#define DUK_DBL_IDX_UC6    1\n#define DUK_DBL_IDX_UC7    0\n#define DUK_DBL_IDX_VP0    DUK_DBL_IDX_UI0  /* packed tval */\n#define DUK_DBL_IDX_VP1    DUK_DBL_IDX_UI1  /* packed tval */\n#elif defined(DUK_USE_DOUBLE_BE)\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBL_IDX_ULL0   0\n#endif\n#define DUK_DBL_IDX_UI0    0\n#define DUK_DBL_IDX_UI1    1\n#define DUK_DBL_IDX_US0    0\n#define DUK_DBL_IDX_US1    1\n#define DUK_DBL_IDX_US2    2\n#define DUK_DBL_IDX_US3    3\n#define DUK_DBL_IDX_UC0    0\n#define DUK_DBL_IDX_UC1    1\n#define DUK_DBL_IDX_UC2    2\n#define DUK_DBL_IDX_UC3    3\n#define DUK_DBL_IDX_UC4    4\n#define DUK_DBL_IDX_UC5    5\n#define DUK_DBL_IDX_UC6    6\n#define DUK_DBL_IDX_UC7    7\n#define DUK_DBL_IDX_VP0    DUK_DBL_IDX_UI0  /* packed tval */\n#define DUK_DBL_IDX_VP1    DUK_DBL_IDX_UI1  /* packed tval */\n#elif defined(DUK_USE_DOUBLE_ME)\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBL_IDX_ULL0   0  /* not directly applicable, byte order differs from a double */\n#endif\n#define DUK_DBL_IDX_UI0    0\n#define DUK_DBL_IDX_UI1    1\n#define DUK_DBL_IDX_US0    1\n#define DUK_DBL_IDX_US1    0\n#define DUK_DBL_IDX_US2    3\n#define DUK_DBL_IDX_US3    2\n#define DUK_DBL_IDX_UC0    3\n#define DUK_DBL_IDX_UC1    2\n#define DUK_DBL_IDX_UC2    1\n#define DUK_DBL_IDX_UC3    0\n#define DUK_DBL_IDX_UC4    7\n#define DUK_DBL_IDX_UC5    6\n#define DUK_DBL_IDX_UC6    5\n#define DUK_DBL_IDX_UC7    4\n#define DUK_DBL_IDX_VP0    DUK_DBL_IDX_UI0  /* packed tval */\n#define DUK_DBL_IDX_VP1    DUK_DBL_IDX_UI1  /* packed tval */\n#else\n#error internal error\n#endif\n\n/*\n *  Helper macros for reading/writing memory representation parts, used\n *  by duk_numconv.c and duk_tval.h.\n */\n\n#define DUK_DBLUNION_SET_DOUBLE(u,v)  do {  \\\n\t\t(u)->d = (v); \\\n\t} while (0)\n\n#define DUK_DBLUNION_SET_HIGH32(u,v)  do {  \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) (v); \\\n\t} while (0)\n\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = (duk_uint64_t) (v); \\\n\t} while (0)\n#else\n#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = ((duk_uint64_t) (v)) << 32; \\\n\t} while (0)\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n#define DUK_DBLUNION_SET_HIGH32_ZERO_LOW32(u,v)  do { \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) (v); \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0; \\\n\t} while (0)\n#endif  /* DUK_USE_64BIT_OPS */\n\n#define DUK_DBLUNION_SET_LOW32(u,v)  do {  \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (v); \\\n\t} while (0)\n\n#define DUK_DBLUNION_GET_DOUBLE(u)  ((u)->d)\n#define DUK_DBLUNION_GET_HIGH32(u)  ((u)->ui[DUK_DBL_IDX_UI0])\n#define DUK_DBLUNION_GET_LOW32(u)   ((u)->ui[DUK_DBL_IDX_UI1])\n\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK_DBLUNION_SET_UINT64(u,v)  do { \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) ((v) >> 32); \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (v); \\\n\t} while (0)\n#define DUK_DBLUNION_GET_UINT64(u) \\\n\t((((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI0]) << 32) | \\\n\t ((duk_uint64_t) (u)->ui[DUK_DBL_IDX_UI1]))\n#else\n#define DUK_DBLUNION_SET_UINT64(u,v)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = (duk_uint64_t) (v); \\\n\t} while (0)\n#define DUK_DBLUNION_GET_UINT64(u)  ((u)->ull[DUK_DBL_IDX_ULL0])\n#endif\n#define DUK_DBLUNION_SET_INT64(u,v) DUK_DBLUNION_SET_UINT64((u), (duk_uint64_t) (v))\n#define DUK_DBLUNION_GET_INT64(u)   ((duk_int64_t) DUK_DBLUNION_GET_UINT64((u)))\n#endif  /* DUK_USE_64BIT_OPS */\n\n/*\n *  Double NaN manipulation macros related to NaN normalization needed when\n *  using the packed duk_tval representation.  NaN normalization is necessary\n *  to keep double values compatible with the duk_tval format.\n *\n *  When packed duk_tval is used, the NaN space is used to store pointers\n *  and other tagged values in addition to NaNs.  Actual NaNs are normalized\n *  to a specific quiet NaN.  The macros below are used by the implementation\n *  to check and normalize NaN values when they might be created.  The macros\n *  are essentially NOPs when the non-packed duk_tval representation is used.\n *\n *  A FULL check is exact and checks all bits.  A NOTFULL check is used by\n *  the packed duk_tval and works correctly for all NaNs except those that\n *  begin with 0x7ff0.  Since the 'normalized NaN' values used with packed\n *  duk_tval begin with 0x7ff8, the partial check is reliable when packed\n *  duk_tval is used.  The 0x7ff8 prefix means the normalized NaN will be a\n *  quiet NaN regardless of its remaining lower bits.\n *\n *  The ME variant below is specifically for ARM byte order, which has the\n *  feature that while doubles have a mixed byte order (32107654), unsigned\n *  long long values has a little endian byte order (76543210).  When writing\n *  a logical double value through a ULL pointer, the 32-bit words need to be\n *  swapped; hence the #if defined()s below for ULL writes with DUK_USE_DOUBLE_ME.\n *  This is not full ARM support but suffices for some environments.\n */\n\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n/* Macros for 64-bit ops + mixed endian doubles. */\n#define DUK__DBLUNION_SET_NAN_FULL(u)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x000000007ff80000); \\\n\t} while (0)\n#define DUK__DBLUNION_IS_NAN_FULL(u) \\\n\t((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000)) && \\\n\t ((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0xffffffff000fffff)) != 0))\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff80000))\n#define DUK__DBLUNION_IS_ANYINF(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x000000007ff00000))\n#define DUK__DBLUNION_IS_POSINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x000000007ff00000))\n#define DUK__DBLUNION_IS_NEGINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x00000000fff00000))\n#define DUK__DBLUNION_IS_ANYZERO(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0xffffffff7fffffff)) == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_POSZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_NEGZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000080000000))\n#else\n/* Macros for 64-bit ops + big/little endian doubles. */\n#define DUK__DBLUNION_SET_NAN_FULL(u)  do { \\\n\t\t(u)->ull[DUK_DBL_IDX_ULL0] = DUK_U64_CONSTANT(0x7ff8000000000000); \\\n\t} while (0)\n#define DUK__DBLUNION_IS_NAN_FULL(u) \\\n\t((((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000)) && \\\n\t ((((u)->ull[DUK_DBL_IDX_ULL0]) & DUK_U64_CONSTANT(0x000fffffffffffff)) != 0))\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff8000000000000))\n#define DUK__DBLUNION_IS_ANYINF(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x7ff0000000000000))\n#define DUK__DBLUNION_IS_POSINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x7ff0000000000000))\n#define DUK__DBLUNION_IS_NEGINF(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0xfff0000000000000))\n#define DUK__DBLUNION_IS_ANYZERO(u) \\\n\t(((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7fffffffffffffff)) == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_POSZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x0000000000000000))\n#define DUK__DBLUNION_IS_NEGZERO(u) \\\n\t((u)->ull[DUK_DBL_IDX_ULL0] == DUK_U64_CONSTANT(0x8000000000000000))\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n/* Macros for no 64-bit ops, any endianness. */\n#define DUK__DBLUNION_SET_NAN_FULL(u)  do { \\\n\t\t(u)->ui[DUK_DBL_IDX_UI0] = (duk_uint32_t) 0x7ff80000UL; \\\n\t\t(u)->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) 0x00000000UL; \\\n\t} while (0)\n#define DUK__DBLUNION_IS_NAN_FULL(u) \\\n\t((((u)->ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL) && \\\n\t (((u)->ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) != 0 || \\\n          (u)->ui[DUK_DBL_IDX_UI1] != 0))\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_FULL(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff80000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_ANYINF(u) \\\n\t((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x7ff00000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_POSINF(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x7ff00000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_NEGINF(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0xfff00000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_ANYZERO(u) \\\n\t((((u)->ui[DUK_DBL_IDX_UI0] & 0x7fffffffUL) == 0x00000000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_POSZERO(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x00000000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#define DUK__DBLUNION_IS_NEGZERO(u) \\\n\t(((u)->ui[DUK_DBL_IDX_UI0] == 0x80000000UL) && \\\n\t ((u)->ui[DUK_DBL_IDX_UI1] == 0x00000000UL))\n#endif  /* DUK_USE_64BIT_OPS */\n\n#define DUK__DBLUNION_SET_NAN_NOTFULL(u)  do { \\\n\t\t(u)->us[DUK_DBL_IDX_US0] = 0x7ff8UL; \\\n\t} while (0)\n\n#define DUK__DBLUNION_IS_NAN_NOTFULL(u) \\\n\t/* E == 0x7ff, topmost four bits of F != 0 => assume NaN */ \\\n\t((((u)->us[DUK_DBL_IDX_US0] & 0x7ff0UL) == 0x7ff0UL) && \\\n\t (((u)->us[DUK_DBL_IDX_US0] & 0x000fUL) != 0x0000UL))\n\n#define DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL(u) \\\n\t/* E == 0x7ff, F == 8 => normalized NaN */ \\\n\t((u)->us[DUK_DBL_IDX_US0] == 0x7ff8UL)\n\n#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL(u)  do { \\\n\t\tif (DUK__DBLUNION_IS_NAN_FULL((u))) { \\\n\t\t\tDUK__DBLUNION_SET_NAN_FULL((u)); \\\n\t\t} \\\n\t} while (0)\n\n#define DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL(u)  do { \\\n\t\tif (DUK__DBLUNION_IS_NAN_NOTFULL((u))) { \\\n\t\t\tDUK__DBLUNION_SET_NAN_NOTFULL((u)); \\\n\t\t} \\\n\t} while (0)\n\n/* Concrete macros for NaN handling used by the implementation internals.\n * Chosen so that they match the duk_tval representation: with a packed\n * duk_tval, ensure NaNs are properly normalized; with a non-packed duk_tval\n * these are essentially NOPs.\n */\n\n#if defined(DUK_USE_PACKED_TVAL)\n#if defined(DUK_USE_FULL_TVAL)\n#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u)  DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL((u))\n#define DUK_DBLUNION_IS_NAN(u)               DUK__DBLUNION_IS_NAN_FULL((u))\n#define DUK_DBLUNION_IS_NORMALIZED_NAN(u)    DUK__DBLUNION_IS_NORMALIZED_NAN_FULL((u))\n#define DUK_DBLUNION_SET_NAN(d)              DUK__DBLUNION_SET_NAN_FULL((d))\n#else\n#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u)  DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL((u))\n#define DUK_DBLUNION_IS_NAN(u)               DUK__DBLUNION_IS_NAN_NOTFULL((u))\n#define DUK_DBLUNION_IS_NORMALIZED_NAN(u)    DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL((u))\n#define DUK_DBLUNION_SET_NAN(d)              DUK__DBLUNION_SET_NAN_NOTFULL((d))\n#endif\n#define DUK_DBLUNION_IS_NORMALIZED(u) \\\n\t(!DUK_DBLUNION_IS_NAN((u)) ||  /* either not a NaN */ \\\n\t DUK_DBLUNION_IS_NORMALIZED_NAN((u)))  /* or is a normalized NaN */\n#else  /* DUK_USE_PACKED_TVAL */\n#define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u)  /* nop: no need to normalize */\n#define DUK_DBLUNION_IS_NAN(u)               DUK__DBLUNION_IS_NAN_FULL((u))  /* (DUK_ISNAN((u)->d)) */\n#define DUK_DBLUNION_IS_NORMALIZED_NAN(u)    DUK__DBLUNION_IS_NAN_FULL((u))  /* (DUK_ISNAN((u)->d)) */\n#define DUK_DBLUNION_IS_NORMALIZED(u)        1  /* all doubles are considered normalized */\n#define DUK_DBLUNION_SET_NAN(u)  do { \\\n\t\t/* in non-packed representation we don't care about which NaN is used */ \\\n\t\t(u)->d = DUK_DOUBLE_NAN; \\\n\t} while (0)\n#endif  /* DUK_USE_PACKED_TVAL */\n\n#define DUK_DBLUNION_IS_ANYINF(u) DUK__DBLUNION_IS_ANYINF((u))\n#define DUK_DBLUNION_IS_POSINF(u) DUK__DBLUNION_IS_POSINF((u))\n#define DUK_DBLUNION_IS_NEGINF(u) DUK__DBLUNION_IS_NEGINF((u))\n\n#define DUK_DBLUNION_IS_ANYZERO(u) DUK__DBLUNION_IS_ANYZERO((u))\n#define DUK_DBLUNION_IS_POSZERO(u) DUK__DBLUNION_IS_POSZERO((u))\n#define DUK_DBLUNION_IS_NEGZERO(u) DUK__DBLUNION_IS_NEGZERO((u))\n\n/* XXX: native 64-bit byteswaps when available */\n\n/* 64-bit byteswap, same operation independent of target endianness. */\n#define DUK_DBLUNION_BSWAP64(u) do { \\\n\t\tduk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \\\n\t\tduk__bswaptmp1 = (u)->ui[0]; \\\n\t\tduk__bswaptmp2 = (u)->ui[1]; \\\n\t\tduk__bswaptmp1 = DUK_BSWAP32(duk__bswaptmp1); \\\n\t\tduk__bswaptmp2 = DUK_BSWAP32(duk__bswaptmp2); \\\n\t\t(u)->ui[0] = duk__bswaptmp2; \\\n\t\t(u)->ui[1] = duk__bswaptmp1; \\\n\t} while (0)\n\n/* Byteswap an IEEE double in the duk_double_union from host to network\n * order.  For a big endian target this is a no-op.\n */\n#if defined(DUK_USE_DOUBLE_LE)\n#define DUK_DBLUNION_DOUBLE_HTON(u) do { \\\n\t\tduk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \\\n\t\tduk__bswaptmp1 = (u)->ui[0]; \\\n\t\tduk__bswaptmp2 = (u)->ui[1]; \\\n\t\tduk__bswaptmp1 = DUK_BSWAP32(duk__bswaptmp1); \\\n\t\tduk__bswaptmp2 = DUK_BSWAP32(duk__bswaptmp2); \\\n\t\t(u)->ui[0] = duk__bswaptmp2; \\\n\t\t(u)->ui[1] = duk__bswaptmp1; \\\n\t} while (0)\n#elif defined(DUK_USE_DOUBLE_ME)\n#define DUK_DBLUNION_DOUBLE_HTON(u) do { \\\n\t\tduk_uint32_t duk__bswaptmp1, duk__bswaptmp2; \\\n\t\tduk__bswaptmp1 = (u)->ui[0]; \\\n\t\tduk__bswaptmp2 = (u)->ui[1]; \\\n\t\tduk__bswaptmp1 = DUK_BSWAP32(duk__bswaptmp1); \\\n\t\tduk__bswaptmp2 = DUK_BSWAP32(duk__bswaptmp2); \\\n\t\t(u)->ui[0] = duk__bswaptmp1; \\\n\t\t(u)->ui[1] = duk__bswaptmp2; \\\n\t} while (0)\n#elif defined(DUK_USE_DOUBLE_BE)\n#define DUK_DBLUNION_DOUBLE_HTON(u) do { } while (0)\n#else\n#error internal error, double endianness insane\n#endif\n\n/* Reverse operation is the same. */\n#define DUK_DBLUNION_DOUBLE_NTOH(u) DUK_DBLUNION_DOUBLE_HTON((u))\n\n/* Some sign bit helpers. */\n#if defined(DUK_USE_64BIT_OPS)\n#define DUK_DBLUNION_HAS_SIGNBIT(u) (((u)->ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x8000000000000000)) != 0)\n#define DUK_DBLUNION_GET_SIGNBIT(u) (((u)->ull[DUK_DBL_IDX_ULL0] >> 63U))\n#else\n#define DUK_DBLUNION_HAS_SIGNBIT(u) (((u)->ui[DUK_DBL_IDX_UI0] & 0x80000000UL) != 0)\n#define DUK_DBLUNION_GET_SIGNBIT(u) (((u)->ui[DUK_DBL_IDX_UI0] >> 31U))\n#endif\n\n#endif  /* DUK_DBLUNION_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_debug.h",
    "content": "/*\n *  Debugging macros, DUK_DPRINT() and its variants in particular.\n *\n *  DUK_DPRINT() allows formatted debug prints, and supports standard\n *  and Duktape specific formatters.  See duk_debug_vsnprintf.c for details.\n *\n *  DUK_D(x), DUK_DD(x), and DUK_DDD(x) are used together with log macros\n *  for technical reasons.  They are concretely used to hide 'x' from the\n *  compiler when the corresponding log level is disabled.  This allows\n *  clean builds on non-C99 compilers, at the cost of more verbose code.\n *  Examples:\n *\n *    DUK_D(DUK_DPRINT(\"foo\"));\n *    DUK_DD(DUK_DDPRINT(\"foo\"));\n *    DUK_DDD(DUK_DDDPRINT(\"foo\"));\n *\n *  This approach is preferable to the old \"double parentheses\" hack because\n *  double parentheses make the C99 solution worse: __FILE__ and __LINE__ can\n *  no longer be added transparently without going through globals, which\n *  works poorly with threading.\n */\n\n#if !defined(DUK_DEBUG_H_INCLUDED)\n#define DUK_DEBUG_H_INCLUDED\n\n#if defined(DUK_USE_DEBUG)\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0)\n#define DUK_D(x) x\n#else\n#define DUK_D(x) do { } while (0) /* omit */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n#define DUK_DD(x) x\n#else\n#define DUK_DD(x) do { } while (0) /* omit */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK_DDD(x) x\n#else\n#define DUK_DDD(x) do { } while (0) /* omit */\n#endif\n\n/*\n *  Exposed debug macros: debugging enabled\n */\n\n#if defined(DUK_USE_VARIADIC_MACROS)\n\n/* Note: combining __FILE__, __LINE__, and __func__ into fmt would be\n * possible compile time, but waste some space with shared function names.\n */\n#define DUK__DEBUG_LOG(lev,...)  duk_debug_log((duk_int_t) (lev), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, DUK_FUNC_MACRO, __VA_ARGS__);\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0)\n#define DUK_DPRINT(...)          DUK__DEBUG_LOG(DUK_LEVEL_DEBUG, __VA_ARGS__)\n#else\n#define DUK_DPRINT(...)\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n#define DUK_DDPRINT(...)         DUK__DEBUG_LOG(DUK_LEVEL_DDEBUG, __VA_ARGS__)\n#else\n#define DUK_DDPRINT(...)\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK_DDDPRINT(...)        DUK__DEBUG_LOG(DUK_LEVEL_DDDEBUG, __VA_ARGS__)\n#else\n#define DUK_DDDPRINT(...)\n#endif\n\n#else  /* DUK_USE_VARIADIC_MACROS */\n\n#define DUK__DEBUG_STASH(lev)    \\\n\t(void) DUK_SNPRINTF(duk_debug_file_stash, DUK_DEBUG_STASH_SIZE, \"%s\", (const char *) DUK_FILE_MACRO), \\\n\t(void) (duk_debug_file_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), \\\n\t(void) (duk_debug_line_stash = (duk_int_t) DUK_LINE_MACRO), \\\n\t(void) DUK_SNPRINTF(duk_debug_func_stash, DUK_DEBUG_STASH_SIZE, \"%s\", (const char *) DUK_FUNC_MACRO), \\\n\t(void) (duk_debug_func_stash[DUK_DEBUG_STASH_SIZE - 1] = (char) 0), \\\n\t(void) (duk_debug_level_stash = (lev))\n\n/* Without variadic macros resort to comma expression trickery to handle debug\n * prints.  This generates a lot of harmless warnings.  These hacks are not\n * needed normally because DUK_D() and friends will hide the entire debug log\n * statement from the compiler.\n */\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 0)\n#define DUK_DPRINT  DUK__DEBUG_STASH(DUK_LEVEL_DEBUG), (void) duk_debug_log  /* args go here in parens */\n#else\n#define DUK_DPRINT  0 && /* args go here as a comma expression in parens */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n#define DUK_DDPRINT  DUK__DEBUG_STASH(DUK_LEVEL_DDEBUG), (void) duk_debug_log  /* args go here in parens */\n#else\n#define DUK_DDPRINT  0 && /* args */\n#endif\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK_DDDPRINT  DUK__DEBUG_STASH(DUK_LEVEL_DDDEBUG), (void) duk_debug_log  /* args go here in parens */\n#else\n#define DUK_DDDPRINT  0 && /* args */\n#endif\n\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n#else  /* DUK_USE_DEBUG */\n\n/*\n *  Exposed debug macros: debugging disabled\n */\n\n#define DUK_D(x) do { } while (0) /* omit */\n#define DUK_DD(x) do { } while (0) /* omit */\n#define DUK_DDD(x) do { } while (0) /* omit */\n\n#if defined(DUK_USE_VARIADIC_MACROS)\n\n#define DUK_DPRINT(...)\n#define DUK_DDPRINT(...)\n#define DUK_DDDPRINT(...)\n\n#else  /* DUK_USE_VARIADIC_MACROS */\n\n#define DUK_DPRINT    0 && /* args go here as a comma expression in parens */\n#define DUK_DDPRINT   0 && /* args */\n#define DUK_DDDPRINT  0 && /* args */\n\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n#endif  /* DUK_USE_DEBUG */\n\n/*\n *  Structs\n */\n\n#if defined(DUK_USE_DEBUG)\nstruct duk_fixedbuffer {\n\tduk_uint8_t *buffer;\n\tduk_size_t length;\n\tduk_size_t offset;\n\tduk_bool_t truncated;\n};\n#endif\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_INTERNAL_DECL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const char *format, va_list ap);\n#if 0  /*unused*/\nDUK_INTERNAL_DECL duk_int_t duk_debug_snprintf(char *str, duk_size_t size, const char *format, ...);\n#endif\nDUK_INTERNAL_DECL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_uint8_t *fptr, duk_size_t fptr_size);\n\n#if defined(DUK_USE_VARIADIC_MACROS)\nDUK_INTERNAL_DECL void duk_debug_log(duk_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...);\n#else  /* DUK_USE_VARIADIC_MACROS */\n/* parameter passing, not thread safe */\n#define DUK_DEBUG_STASH_SIZE  128\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL_DECL duk_int_t duk_debug_line_stash;\nDUK_INTERNAL_DECL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL_DECL duk_int_t duk_debug_level_stash;\n#endif\nDUK_INTERNAL_DECL void duk_debug_log(const char *fmt, ...);\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\nDUK_INTERNAL_DECL void duk_fb_put_bytes(duk_fixedbuffer *fb, const duk_uint8_t *buffer, duk_size_t length);\nDUK_INTERNAL_DECL void duk_fb_put_byte(duk_fixedbuffer *fb, duk_uint8_t x);\nDUK_INTERNAL_DECL void duk_fb_put_cstring(duk_fixedbuffer *fb, const char *x);\nDUK_INTERNAL_DECL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...);\nDUK_INTERNAL_DECL void duk_fb_put_funcptr(duk_fixedbuffer *fb, duk_uint8_t *fptr, duk_size_t fptr_size);\nDUK_INTERNAL_DECL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb);\n\n#endif  /* DUK_USE_DEBUG */\n\n#endif  /* DUK_DEBUG_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_debug_fixedbuffer.c",
    "content": "/*\n *  Fixed buffer helper useful for debugging, requires no allocation\n *  which is critical for debugging.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_DEBUG)\n\nDUK_INTERNAL void duk_fb_put_bytes(duk_fixedbuffer *fb, const duk_uint8_t *buffer, duk_size_t length) {\n\tduk_size_t avail;\n\tduk_size_t copylen;\n\n\tavail = (fb->offset >= fb->length ? (duk_size_t) 0 : (duk_size_t) (fb->length - fb->offset));\n\tif (length > avail) {\n\t\tcopylen = avail;\n\t\tfb->truncated = 1;\n\t} else {\n\t\tcopylen = length;\n\t}\n\tduk_memcpy_unsafe(fb->buffer + fb->offset, buffer, copylen);\n\tfb->offset += copylen;\n}\n\nDUK_INTERNAL void duk_fb_put_byte(duk_fixedbuffer *fb, duk_uint8_t x) {\n\tduk_fb_put_bytes(fb, (const duk_uint8_t *) &x, 1);\n}\n\nDUK_INTERNAL void duk_fb_put_cstring(duk_fixedbuffer *fb, const char *x) {\n\tduk_fb_put_bytes(fb, (const duk_uint8_t *) x, (duk_size_t) DUK_STRLEN(x));\n}\n\nDUK_INTERNAL void duk_fb_sprintf(duk_fixedbuffer *fb, const char *fmt, ...) {\n\tduk_size_t avail;\n\tva_list ap;\n\n\tva_start(ap, fmt);\n\tavail = (fb->offset >= fb->length ? (duk_size_t) 0 : (duk_size_t) (fb->length - fb->offset));\n\tif (avail > 0) {\n\t\tduk_int_t res = (duk_int_t) DUK_VSNPRINTF((char *) (fb->buffer + fb->offset), avail, fmt, ap);\n\t\tif (res < 0) {\n\t\t\t/* error */\n\t\t} else if ((duk_size_t) res >= avail) {\n\t\t\t/* (maybe) truncated */\n\t\t\tfb->offset += avail;\n\t\t\tif ((duk_size_t) res > avail) {\n\t\t\t\t/* actual chars dropped (not just NUL term) */\n\t\t\t\tfb->truncated = 1;\n\t\t\t}\n\t\t} else {\n\t\t\t/* normal */\n\t\t\tfb->offset += (duk_size_t) res;\n\t\t}\n\t}\n\tva_end(ap);\n}\n\nDUK_INTERNAL void duk_fb_put_funcptr(duk_fixedbuffer *fb, duk_uint8_t *fptr, duk_size_t fptr_size) {\n\tchar buf[64+1];\n\tduk_debug_format_funcptr(buf, sizeof(buf), fptr, fptr_size);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\tduk_fb_put_cstring(fb, buf);\n}\n\nDUK_INTERNAL duk_bool_t duk_fb_is_full(duk_fixedbuffer *fb) {\n\treturn (fb->offset >= fb->length);\n}\n\n#endif  /* DUK_USE_DEBUG */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_debug_macros.c",
    "content": "/*\n *  Debugging macro calls.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_DEBUG)\n\n/*\n *  Debugging enabled\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdarg.h>\n\n#if !defined(DUK_USE_DEBUG_WRITE)\n#error debugging enabled (DUK_USE_DEBUG) but DUK_USE_DEBUG_WRITE not defined\n#endif\n\n#define DUK__DEBUG_BUFSIZE  DUK_USE_DEBUG_BUFSIZE\n\n#if defined(DUK_USE_VARIADIC_MACROS)\n\nDUK_INTERNAL void duk_debug_log(duk_int_t level, const char *file, duk_int_t line, const char *func, const char *fmt, ...) {\n\tva_list ap;\n\tlong arg_level;\n\tconst char *arg_file;\n\tlong arg_line;\n\tconst char *arg_func;\n\tconst char *arg_msg;\n\tchar buf[DUK__DEBUG_BUFSIZE];\n\n\tva_start(ap, fmt);\n\n\tduk_memzero((void *) buf, (size_t) DUK__DEBUG_BUFSIZE);\n\tduk_debug_vsnprintf(buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap);\n\n\targ_level = (long) level;\n\targ_file = (const char *) file;\n\targ_line = (long) line;\n\targ_func = (const char *) func;\n\targ_msg = (const char *) buf;\n\tDUK_USE_DEBUG_WRITE(arg_level, arg_file, arg_line, arg_func, arg_msg);\n\n\tva_end(ap);\n}\n\n#else  /* DUK_USE_VARIADIC_MACROS */\n\nDUK_INTERNAL char duk_debug_file_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL duk_int_t duk_debug_line_stash;\nDUK_INTERNAL char duk_debug_func_stash[DUK_DEBUG_STASH_SIZE];\nDUK_INTERNAL duk_int_t duk_debug_level_stash;\n\nDUK_INTERNAL void duk_debug_log(const char *fmt, ...) {\n\tva_list ap;\n\tlong arg_level;\n\tconst char *arg_file;\n\tlong arg_line;\n\tconst char *arg_func;\n\tconst char *arg_msg;\n\tchar buf[DUK__DEBUG_BUFSIZE];\n\n\tva_start(ap, fmt);\n\n\tduk_memzero((void *) buf, (size_t) DUK__DEBUG_BUFSIZE);\n\tduk_debug_vsnprintf(buf, DUK__DEBUG_BUFSIZE - 1, fmt, ap);\n\n\targ_level = (long) duk_debug_level_stash;\n\targ_file = (const char *) duk_debug_file_stash;\n\targ_line = (long) duk_debug_line_stash;\n\targ_func = (const char *) duk_debug_func_stash;\n\targ_msg = (const char *) buf;\n\tDUK_USE_DEBUG_WRITE(arg_level, arg_file, arg_line, arg_func, arg_msg);\n\n\tva_end(ap);\n}\n\n#endif  /* DUK_USE_VARIADIC_MACROS */\n\n#else  /* DUK_USE_DEBUG */\n\n/*\n *  Debugging disabled\n */\n\n#endif  /* DUK_USE_DEBUG */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_debug_vsnprintf.c",
    "content": "/*\n *  Custom formatter for debug printing, allowing Duktape specific data\n *  structures (such as tagged values and heap objects) to be printed with\n *  a nice format string.  Because debug printing should not affect execution\n *  state, formatting here must be independent of execution (see implications\n *  below) and must not allocate memory.\n *\n *  Custom format tags begin with a '%!' to safely distinguish them from\n *  standard format tags.  The following conversions are supported:\n *\n *     %!T    tagged value (duk_tval *)\n *     %!O    heap object (duk_heaphdr *)\n *     %!I    decoded bytecode instruction\n *     %!X    bytecode instruction opcode name (arg is long)\n *     %!C    catcher (duk_catcher *)\n *     %!A    activation (duk_activation *)\n *\n *  Everything is serialized in a JSON-like manner.  The default depth is one\n *  level, internal prototype is not followed, and internal properties are not\n *  serialized.  The following modifiers change this behavior:\n *\n *     @      print pointers\n *     #      print binary representations (where applicable)\n *     d      deep traversal of own properties (not prototype)\n *     p      follow prototype chain (useless without 'd')\n *     i      include internal properties (other than prototype)\n *     x      hexdump buffers\n *     h      heavy formatting\n *\n *  For instance, the following serializes objects recursively, but does not\n *  follow the prototype chain nor print internal properties: \"%!dO\".\n *\n *  Notes:\n *\n *    * Standard snprintf return value semantics seem to vary.  This\n *      implementation returns the number of bytes it actually wrote\n *      (excluding the null terminator).  If retval == buffer size,\n *      output was truncated (except for corner cases).\n *\n *    * Output format is intentionally different from ECMAScript\n *      formatting requirements, as formatting here serves debugging\n *      of internals.\n *\n *    * Depth checking (and updating) is done in each type printer\n *      separately, to allow them to call each other freely.\n *\n *    * Some pathological structures might take ages to print (e.g.\n *      self recursion with 100 properties pointing to the object\n *      itself).  To guard against these, each printer also checks\n *      whether the output buffer is full; if so, early exit.\n *\n *    * Reference loops are detected using a loop stack.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_DEBUG)\n\n#include <stdio.h>\n#include <stdarg.h>\n#include <string.h>\n\n/* list of conversion specifiers that terminate a format tag;\n * this is unfortunately guesswork.\n */\n#define DUK__ALLOWED_STANDARD_SPECIFIERS  \"diouxXeEfFgGaAcsCSpnm\"\n\n/* maximum length of standard format tag that we support */\n#define DUK__MAX_FORMAT_TAG_LENGTH  32\n\n/* heapobj recursion depth when deep printing is selected */\n#define DUK__DEEP_DEPTH_LIMIT  8\n\n/* maximum recursion depth for loop detection stacks */\n#define DUK__LOOP_STACK_DEPTH  256\n\n/* must match bytecode defines now; build autogenerate? */\nDUK_LOCAL const char * const duk__bc_optab[256] = {\n\t\"LDREG\", \"STREG\", \"JUMP\", \"LDCONST\", \"LDINT\", \"LDINTX\", \"LDTHIS\", \"LDUNDEF\",\n\t\"LDNULL\", \"LDTRUE\", \"LDFALSE\", \"GETVAR\", \"BNOT\", \"LNOT\", \"UNM\", \"UNP\",\n\t\"EQ_RR\", \"EQ_CR\", \"EQ_RC\", \"EQ_CC\", \"NEQ_RR\", \"NEQ_CR\", \"NEQ_RC\", \"NEQ_CC\",\n\t\"SEQ_RR\", \"SEQ_CR\", \"SEQ_RC\", \"SEQ_CC\", \"SNEQ_RR\", \"SNEQ_CR\", \"SNEQ_RC\", \"SNEQ_CC\",\n\n\t\"GT_RR\", \"GT_CR\", \"GT_RC\", \"GT_CC\", \"GE_RR\", \"GE_CR\", \"GE_RC\", \"GE_CC\",\n\t\"LT_RR\", \"LT_CR\", \"LT_RC\", \"LT_CC\", \"LE_RR\", \"LE_CR\", \"LE_RC\", \"LE_CC\",\n\t\"IFTRUE_R\", \"IFTRUE_C\", \"IFFALSE_R\", \"IFFALSE_C\", \"ADD_RR\", \"ADD_CR\", \"ADD_RC\", \"ADD_CC\",\n\t\"SUB_RR\", \"SUB_CR\", \"SUB_RC\", \"SUB_CC\", \"MUL_RR\", \"MUL_CR\", \"MUL_RC\", \"MUL_CC\",\n\n\t\"DIV_RR\", \"DIV_CR\", \"DIV_RC\", \"DIV_CC\", \"MOD_RR\", \"MOD_CR\", \"MOD_RC\", \"MOD_CC\",\n\t\"EXP_RR\", \"EXP_CR\", \"EXP_RC\", \"EXP_CC\", \"BAND_RR\", \"BAND_CR\", \"BAND_RC\", \"BAND_CC\",\n\t\"BOR_RR\", \"BOR_CR\", \"BOR_RC\", \"BOR_CC\", \"BXOR_RR\", \"BXOR_CR\", \"BXOR_RC\", \"BXOR_CC\",\n\t\"BASL_RR\", \"BASL_CR\", \"BASL_RC\", \"BASL_CC\", \"BLSR_RR\", \"BLSR_CR\", \"BLSR_RC\", \"BLSR_CC\",\n\n\t\"BASR_RR\", \"BASR_CR\", \"BASR_RC\", \"BASR_CC\", \"INSTOF_RR\", \"INSTOF_CR\", \"INSTOF_RC\", \"INSTOF_CC\",\n\t\"IN_RR\", \"IN_CR\", \"IN_RC\", \"IN_CC\", \"GETPROP_RR\", \"GETPROP_CR\", \"GETPROP_RC\", \"GETPROP_CC\",\n\t\"PUTPROP_RR\", \"PUTPROP_CR\", \"PUTPROP_RC\", \"PUTPROP_CC\", \"DELPROP_RR\", \"DELPROP_CR\", \"DELPROP_RC\", \"DELPROP_CC\",\n\t\"PREINCR\", \"PREDECR\", \"POSTINCR\", \"POSTDECR\", \"PREINCV\", \"PREDECV\", \"POSTINCV\", \"POSTDECV\",\n\n\t\"PREINCP_RR\", \"PREINCP_CR\", \"PREINCP_RC\", \"PREINCP_CC\", \"PREDECP_RR\", \"PREDECP_CR\", \"PREDECP_RC\", \"PREDECP_CC\",\n\t\"POSTINCP_RR\", \"POSTINCP_CR\", \"POSTINCP_RC\", \"POSTINCP_CC\", \"POSTDECP_RR\", \"POSTDECP_CR\", \"POSTDECP_RC\", \"POSTDECP_CC\",\n\t\"DECLVAR_RR\", \"DECLVAR_CR\", \"DECLVAR_RC\", \"DECLVAR_CC\", \"REGEXP_RR\", \"REGEXP_RC\", \"REGEXP_CR\", \"REGEXP_CC\",\n\t\"CLOSURE\", \"TYPEOF\", \"TYPEOFID\", \"PUTVAR\", \"DELVAR\", \"RETREG\", \"RETUNDEF\", \"RETCONST\",\n\n\t\"RETCONSTN\", \"LABEL\", \"ENDLABEL\", \"BREAK\", \"CONTINUE\", \"TRYCATCH\", \"ENDTRY\", \"ENDCATCH\",\n\t\"ENDFIN\", \"THROW\", \"INVLHS\", \"CSREG\", \"CSVAR_RR\", \"CSVAR_CR\", \"CSVAR_RC\", \"CSVAR_CC\",\n\t\"CALL0\", \"CALL1\", \"CALL2\", \"CALL3\", \"CALL4\", \"CALL5\", \"CALL6\", \"CALL7\",\n\t\"CALL8\", \"CALL9\", \"CALL10\", \"CALL11\", \"CALL12\", \"CALL13\", \"CALL14\", \"CALL15\",\n\n\t\"NEWOBJ\", \"NEWARR\", \"MPUTOBJ\", \"MPUTOBJI\", \"INITSET\", \"INITGET\", \"MPUTARR\", \"MPUTARRI\",\n\t\"SETALEN\", \"INITENUM\", \"NEXTENUM\", \"NEWTARGET\", \"DEBUGGER\", \"NOP\", \"INVALID\", \"UNUSED207\",\n\t\"GETPROPC_RR\", \"GETPROPC_CR\", \"GETPROPC_RC\", \"GETPROPC_CC\", \"UNUSED212\", \"UNUSED213\", \"UNUSED214\", \"UNUSED215\",\n\t\"UNUSED216\", \"UNUSED217\", \"UNUSED218\", \"UNUSED219\", \"UNUSED220\", \"UNUSED221\", \"UNUSED222\", \"UNUSED223\",\n\n\t\"UNUSED224\", \"UNUSED225\", \"UNUSED226\", \"UNUSED227\", \"UNUSED228\", \"UNUSED229\", \"UNUSED230\", \"UNUSED231\",\n\t\"UNUSED232\", \"UNUSED233\", \"UNUSED234\", \"UNUSED235\", \"UNUSED236\", \"UNUSED237\", \"UNUSED238\", \"UNUSED239\",\n\t\"UNUSED240\", \"UNUSED241\", \"UNUSED242\", \"UNUSED243\", \"UNUSED244\", \"UNUSED245\", \"UNUSED246\", \"UNUSED247\",\n\t\"UNUSED248\", \"UNUSED249\", \"UNUSED250\", \"UNUSED251\", \"UNUSED252\", \"UNUSED253\", \"UNUSED254\", \"UNUSED255\"\n};\n\ntypedef struct duk__dprint_state duk__dprint_state;\nstruct duk__dprint_state {\n\tduk_fixedbuffer *fb;\n\n\t/* loop_stack_index could be perhaps be replaced by 'depth', but it's nice\n\t * to not couple these two mechanisms unnecessarily.\n\t */\n\tduk_hobject *loop_stack[DUK__LOOP_STACK_DEPTH];\n\tduk_int_t loop_stack_index;\n\tduk_int_t loop_stack_limit;\n\n\tduk_int_t depth;\n\tduk_int_t depth_limit;\n\n\tduk_bool_t pointer;\n\tduk_bool_t heavy;\n\tduk_bool_t binary;\n\tduk_bool_t follow_proto;\n\tduk_bool_t internal;\n\tduk_bool_t hexdump;\n};\n\n/* helpers */\nDUK_LOCAL_DECL void duk__print_hstring(duk__dprint_state *st, duk_hstring *k, duk_bool_t quotes);\nDUK_LOCAL_DECL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h);\nDUK_LOCAL_DECL void duk__print_hbuffer(duk__dprint_state *st, duk_hbuffer *h);\nDUK_LOCAL_DECL void duk__print_tval(duk__dprint_state *st, duk_tval *tv);\nDUK_LOCAL_DECL void duk__print_instr(duk__dprint_state *st, duk_instr_t ins);\nDUK_LOCAL_DECL void duk__print_heaphdr(duk__dprint_state *st, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__print_shared_heaphdr(duk__dprint_state *st, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__print_shared_heaphdr_string(duk__dprint_state *st, duk_heaphdr_string *h);\n\nDUK_LOCAL void duk__print_shared_heaphdr(duk__dprint_state *st, duk_heaphdr *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"(%p)\", (void *) h);\n\t}\n\n\tif (!h) {\n\t\treturn;\n\t}\n\n\tif (st->binary) {\n\t\tduk_size_t i;\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET);\n\t\tfor (i = 0; i < (duk_size_t) sizeof(*h); i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) ((duk_uint8_t *)h)[i]);\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET);\n\t}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)  /* currently implicitly also DUK_USE_DOUBLE_LINKED_HEAP */\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_next=%p,h_prev=%p,h_refcount=%lu,h_flags=%08lx,type=%ld,\"\n\t\t               \"reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (void *) DUK_HEAPHDR_GET_NEXT(NULL, h),\n\t\t               (void *) DUK_HEAPHDR_GET_PREV(NULL, h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS(h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE(h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED(h) ? 1 : 0));\n\t}\n#else\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_next=%p,h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (void *) DUK_HEAPHDR_GET_NEXT(NULL, h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS(h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE(h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE(h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED(h) ? 1 : 0));\n\t}\n#endif\n}\n\nDUK_LOCAL void duk__print_shared_heaphdr_string(duk__dprint_state *st, duk_heaphdr_string *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"(%p)\", (void *) h);\n\t}\n\n\tif (!h) {\n\t\treturn;\n\t}\n\n\tif (st->binary) {\n\t\tduk_size_t i;\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET);\n\t\tfor (i = 0; i < (duk_size_t) sizeof(*h); i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) ((duk_uint8_t *)h)[i]);\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET);\n\t}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_refcount=%lu,h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (unsigned long) DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h),\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) h) ? 1 : 0));\n\t}\n#else\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"[h_flags=%08lx,type=%ld,reachable=%ld,temproot=%ld,finalizable=%ld,finalized=%ld]\",\n\t\t               (unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) h),\n\t\t               (long) DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h),\n\t\t               (long) (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_TEMPROOT((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZABLE((duk_heaphdr *) h) ? 1 : 0),\n\t\t               (long) (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) h) ? 1 : 0));\n\t}\n#endif\n}\n\nDUK_LOCAL void duk__print_hstring(duk__dprint_state *st, duk_hstring *h, duk_bool_t quotes) {\n\tduk_fixedbuffer *fb = st->fb;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\n\t/* terminal type: no depth check */\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tduk__print_shared_heaphdr_string(st, &h->hdr);\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tp = DUK_HSTRING_GET_DATA(h);\n\tp_end = p + DUK_HSTRING_GET_BYTELEN(h);\n\n\tif (p_end > p && p[0] == DUK_ASC_UNDERSCORE) {\n\t\t/* If property key begins with underscore, encode it with\n\t\t * forced quotes (e.g. \"_Foo\") to distinguish it from encoded\n\t\t * internal properties (e.g. \\x82Bar -> _Bar).\n\t\t */\n\t\tquotes = 1;\n\t}\n\n\tif (quotes) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_DOUBLEQUOTE);\n\t}\n\twhile (p < p_end) {\n\t\tduk_uint8_t ch = *p++;\n\n\t\t/* two special escapes: '\\' and '\"', other printables as is */\n\t\tif (ch == '\\\\') {\n\t\t\tduk_fb_sprintf(fb, \"\\\\\\\\\");\n\t\t} else if (ch == '\"') {\n\t\t\tduk_fb_sprintf(fb, \"\\\\\\\"\");\n\t\t} else if (ch >= 0x20 && ch <= 0x7e) {\n\t\t\tduk_fb_put_byte(fb, ch);\n\t\t} else if (ch == 0x82 && !quotes) {\n\t\t\t/* encode \\x82Bar as _Bar if no quotes are\n\t\t\t * applied, this is for readable internal keys.\n\t\t\t */\n\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_UNDERSCORE);\n\t\t} else {\n\t\t\tduk_fb_sprintf(fb, \"\\\\x%02lx\", (unsigned long) ch);\n\t\t}\n\t}\n\tif (quotes) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_DOUBLEQUOTE);\n\t}\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* XXX: limit to quoted strings only, to save keys from being cluttered? */\n\tduk_fb_sprintf(fb, \"/%lu\", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(&h->hdr));\n#endif\n}\n\n#define DUK__COMMA()  do { \\\n\t\tif (first) { \\\n\t\t\tfirst = 0; \\\n\t\t} else { \\\n\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COMMA); \\\n\t\t} \\\n\t} while (0)\n\nDUK_LOCAL void duk__print_hobject(duk__dprint_state *st, duk_hobject *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\tduk_uint_fast32_t i;\n\tduk_tval *tv;\n\tduk_hstring *key;\n\tduk_bool_t first = 1;\n\tconst char *brace1 = \"{\";\n\tconst char *brace2 = \"}\";\n\tduk_bool_t pushed_loopstack = 0;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tduk__print_shared_heaphdr(st, &h->hdr);\n\n\tif (h && DUK_HOBJECT_HAS_ARRAY_PART(h)) {\n\t\tbrace1 = \"[\";\n\t\tbrace2 = \"]\";\n\t}\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\tgoto finished;\n\t}\n\n\tif (st->depth >= st->depth_limit) {\n\t\tconst char *subtype = \"generic\";\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\t\tsubtype = \"compfunc\";\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\t\tsubtype = \"natfunc\";\n\t\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\t\tsubtype = \"thread\";\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\tsubtype = \"bufobj\";\n\t\t} else if (DUK_HOBJECT_IS_ARRAY(h)) {\n\t\t\tsubtype = \"array\";\n\t\t}\n\t\tduk_fb_sprintf(fb, \"%sobject/%s %p%s\", (const char *) brace1, subtype, (void *) h, (const char *) brace2);\n\t\treturn;\n\t}\n\n\tfor (i = 0; i < (duk_uint_fast32_t) st->loop_stack_index; i++) {\n\t\tif (st->loop_stack[i] == h) {\n\t\t\tduk_fb_sprintf(fb, \"%sLOOP:%p%s\", (const char *) brace1, (void *) h, (const char *) brace2);\n\t\t\treturn;\n\t\t}\n\t}\n\n\t/* after this, return paths should 'goto finished' for decrement */\n\tst->depth++;\n\n\tif (st->loop_stack_index >= st->loop_stack_limit) {\n\t\tduk_fb_sprintf(fb, \"%sOUT-OF-LOOP-STACK%s\", (const char *) brace1, (const char *) brace2);\n\t\tgoto finished;\n\t}\n\tst->loop_stack[st->loop_stack_index++] = h;\n\tpushed_loopstack = 1;\n\n\t/*\n\t *  Notation: double underscore used for internal properties which are not\n\t *  stored in the property allocation (e.g. '__valstack').\n\t */\n\n\tduk_fb_put_cstring(fb, brace1);\n\n\tif (DUK_HOBJECT_GET_PROPS(NULL, h)) {\n\t\tduk_uint32_t a_limit;\n\n\t\ta_limit = DUK_HOBJECT_GET_ASIZE(h);\n\t\tif (st->internal) {\n\t\t\t/* dump all allocated entries, unused entries print as 'unused',\n\t\t\t * note that these may extend beyond current 'length' and look\n\t\t\t * a bit funny.\n\t\t\t */\n\t\t} else {\n\t\t\t/* leave out trailing 'unused' elements */\n\t\t\twhile (a_limit > 0) {\n\t\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(NULL, h, a_limit - 1);\n\t\t\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\ta_limit--;\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < a_limit; i++) {\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(NULL, h, i);\n\t\t\tDUK__COMMA();\n\t\t\tduk__print_tval(st, tv);\n\t\t}\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(NULL, h, i);\n\t\t\tif (!key) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!st->internal && DUK_HSTRING_HAS_HIDDEN(key)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tDUK__COMMA();\n\t\t\tduk__print_hstring(st, key, 0);\n\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COLON);\n\t\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(NULL, h, i)) {\n\t\t\t\tduk_fb_sprintf(fb, \"[get:%p,set:%p]\",\n\t\t\t\t               (void *) DUK_HOBJECT_E_GET_VALUE(NULL, h, i).a.get,\n\t\t\t\t               (void *) DUK_HOBJECT_E_GET_VALUE(NULL, h, i).a.set);\n\t\t\t} else {\n\t\t\t\ttv = &DUK_HOBJECT_E_GET_VALUE(NULL, h, i).v;\n\t\t\t\tduk__print_tval(st, tv);\n\t\t\t}\n\t\t\tif (st->heavy) {\n\t\t\t\tduk_fb_sprintf(fb, \"<%02lx>\", (unsigned long) DUK_HOBJECT_E_GET_FLAGS(NULL, h, i));\n\t\t\t}\n\t\t}\n\t}\n\tif (st->internal) {\n\t\tif (DUK_HOBJECT_IS_ARRAY(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__array:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXTENSIBLE(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__extensible:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_CONSTRUCTABLE(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__constructable:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__boundfunc:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_COMPFUNC(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__compfunc:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NATFUNC(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__natfunc:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_BUFOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__bufobj:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_IS_THREAD(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__thread:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_ARRAY_PART(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__array_part:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_STRICT(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__strict:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NOTAIL(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__notail:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NEWENV(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__newenv:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_NAMEBINDING(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__namebinding:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_CREATEARGS(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__createargs:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_array:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_stringobj:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_arguments:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_bufobj:true\");\n\t\t}\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)) {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__exotic_proxyobj:true\");\n\t\t}\n\t}\n\n\tif (st->internal && DUK_HOBJECT_IS_ARRAY(h)) {\n\t\tduk_harray *a = (duk_harray *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__length:%ld\", (long) a->length);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__length_nonwritable:%ld\", (long) a->length_nonwritable);\n\t} else if (st->internal && DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__data:\");\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(NULL, f));\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__lexenv:\"); duk__print_hobject(st, DUK_HCOMPFUNC_GET_LEXENV(NULL, f));\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__varenv:\"); duk__print_hobject(st, DUK_HCOMPFUNC_GET_VARENV(NULL, f));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__nregs:%ld\", (long) f->nregs);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__nargs:%ld\", (long) f->nargs);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__start_line:%ld\", (long) f->start_line);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__end_line:%ld\", (long) f->end_line);\n#endif\n\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__data:\");\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(NULL, f));\n\t} else if (st->internal && DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\tduk_hnatfunc *f = (duk_hnatfunc *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__func:\");\n\t\tduk_fb_put_funcptr(fb, (duk_uint8_t *) &f->func, sizeof(f->func));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__nargs:%ld\", (long) f->nargs);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__magic:%ld\", (long) f->magic);\n\t} else if (st->internal && DUK_HOBJECT_IS_DECENV(h)) {\n\t\tduk_hdecenv *e = (duk_hdecenv *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__thread:\"); duk__print_hobject(st, (duk_hobject *) e->thread);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__varmap:\"); duk__print_hobject(st, (duk_hobject *) e->varmap);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__regbase_byteoff:%ld\", (long) e->regbase_byteoff);\n\t} else if (st->internal && DUK_HOBJECT_IS_OBJENV(h)) {\n\t\tduk_hobjenv *e = (duk_hobjenv *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__target:\"); duk__print_hobject(st, (duk_hobject *) e->target);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__has_this:%ld\", (long) e->has_this);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t} else if (st->internal && DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\tduk_hbufobj *b = (duk_hbufobj *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__buf:\");\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) b->buf);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__buf_prop:\");\n\t\tduk__print_hobject(st, (duk_hobject *) b->buf_prop);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__offset:%ld\", (long) b->offset);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__length:%ld\", (long) b->length);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__shift:%ld\", (long) b->shift);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__elemtype:%ld\", (long) b->elem_type);\n#endif\n\t} else if (st->internal && DUK_HOBJECT_IS_PROXY(h)) {\n\t\tduk_hproxy *p = (duk_hproxy *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__target:\");\n\t\tduk__print_hobject(st, p->target);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__handler:\");\n\t\tduk__print_hobject(st, p->handler);\n\t} else if (st->internal && DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__ptr_curr_pc:%p\", (void *) t->ptr_curr_pc);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__heap:%p\", (void *) t->heap);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__strict:%ld\", (long) t->strict);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__state:%ld\", (long) t->state);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__unused1:%ld\", (long) t->unused1);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__unused2:%ld\", (long) t->unused2);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack:%p\", (void *) t->valstack);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_end:%p/%ld\", (void *) t->valstack_end, (long) (t->valstack_end - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_alloc_end:%p/%ld\", (void *) t->valstack_alloc_end, (long) (t->valstack_alloc_end - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_bottom:%p/%ld\", (void *) t->valstack_bottom, (long) (t->valstack_bottom - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__valstack_top:%p/%ld\", (void *) t->valstack_top, (long) (t->valstack_top - t->valstack));\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__callstack_curr:%p\", (void *) t->callstack_curr);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__callstack_top:%ld\", (long) t->callstack_top);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__callstack_preventcount:%ld\", (long) t->callstack_preventcount);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__resumer:\"); duk__print_hobject(st, (duk_hobject *) t->resumer);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__compile_ctx:%p\", (void *) t->compile_ctx);\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__interrupt_counter:%ld\", (long) t->interrupt_counter);\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__interrupt_init:%ld\", (long) t->interrupt_init);\n#endif\n\n\t\t/* XXX: print built-ins array? */\n\n\t}\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tif (st->internal) {\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__refcount:%lu\", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h));\n\t}\n#endif\n\tif (st->internal) {\n\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__class:%ld\", (long) DUK_HOBJECT_GET_CLASS_NUMBER(h));\n\t}\n\n\tDUK__COMMA(); duk_fb_sprintf(fb, \"__heapptr:%p\", (void *) h);  /* own pointer */\n\n\t/* prototype should be last, for readability */\n\tif (DUK_HOBJECT_GET_PROTOTYPE(NULL, h)) {\n\t\tif (st->follow_proto) {\n\t\t\tDUK__COMMA(); duk_fb_put_cstring(fb, \"__prototype:\"); duk__print_hobject(st, DUK_HOBJECT_GET_PROTOTYPE(NULL, h));\n\t\t} else {\n\t\t\tDUK__COMMA(); duk_fb_sprintf(fb, \"__prototype:%p\", (void *) DUK_HOBJECT_GET_PROTOTYPE(NULL, h));\n\t\t}\n\t}\n\n\tduk_fb_put_cstring(fb, brace2);\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (st->heavy && DUK_HOBJECT_GET_HSIZE(h) > 0) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LANGLE);\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_HSIZE(h); i++) {\n\t\t\tduk_uint_t h_idx = DUK_HOBJECT_H_GET_INDEX(NULL, h, i);\n\t\t\tif (i > 0) {\n\t\t\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_COMMA);\n\t\t\t}\n\t\t\tif (h_idx == DUK_HOBJECT_HASHIDX_UNUSED) {\n\t\t\t\tduk_fb_sprintf(fb, \"u\");\n\t\t\t} else if (h_idx == DUK_HOBJECT_HASHIDX_DELETED) {\n\t\t\t\tduk_fb_sprintf(fb, \"d\");\n\t\t\t} else {\n\t\t\t\tduk_fb_sprintf(fb, \"%ld\", (long) h_idx);\n\t\t\t}\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RANGLE);\n\t}\n#endif\n\n finished:\n\tst->depth--;\n\tif (pushed_loopstack) {\n\t\tst->loop_stack_index--;\n\t\tst->loop_stack[st->loop_stack_index] = NULL;\n\t}\n}\n\nDUK_LOCAL void duk__print_hbuffer(duk__dprint_state *st, duk_hbuffer *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\tduk_size_t i, n;\n\tduk_uint8_t *p;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\t/* terminal type: no depth check */\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tif (DUK_HBUFFER_HAS_DYNAMIC(h)) {\n\t\tif (DUK_HBUFFER_HAS_EXTERNAL(h)) {\n\t\t\tduk_hbuffer_external *g = (duk_hbuffer_external *) h;\n\t\t\tduk_fb_sprintf(fb, \"buffer:external:%p:%ld\",\n\t\t\t               (void *) DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(NULL, g),\n\t\t\t               (long) DUK_HBUFFER_EXTERNAL_GET_SIZE(g));\n\t\t} else {\n\t\t\tduk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h;\n\t\t\tduk_fb_sprintf(fb, \"buffer:dynamic:%p:%ld\",\n\t\t\t               (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(NULL, g),\n\t\t\t               (long) DUK_HBUFFER_DYNAMIC_GET_SIZE(g));\n\t\t}\n\t} else {\n\t\tduk_fb_sprintf(fb, \"buffer:fixed:%ld\", (long) DUK_HBUFFER_GET_SIZE(h));\n\t}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_fb_sprintf(fb, \"/%lu\", (unsigned long) DUK_HEAPHDR_GET_REFCOUNT(&h->hdr));\n#endif\n\n\tif (st->hexdump) {\n\t\tduk_fb_sprintf(fb, \"=[\");\n\t\tn = DUK_HBUFFER_GET_SIZE(h);\n\t\tp = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(NULL, h);\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) p[i]);\n\t\t}\n\t\tduk_fb_sprintf(fb, \"]\");\n\t}\n}\n\nDUK_LOCAL void duk__print_heaphdr(duk__dprint_state *st, duk_heaphdr *h) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tif (!h) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING:\n\t\tduk__print_hstring(st, (duk_hstring *) h, 1);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tduk__print_hobject(st, (duk_hobject *) h);\n\t\tbreak;\n\tcase DUK_HTYPE_BUFFER:\n\t\tduk__print_hbuffer(st, (duk_hbuffer *) h);\n\t\tbreak;\n\tdefault:\n\t\tduk_fb_sprintf(fb, \"[unknown htype %ld]\", (long) DUK_HEAPHDR_GET_TYPE(h));\n\t\tbreak;\n\t}\n}\n\nDUK_LOCAL void duk__print_tval(duk__dprint_state *st, duk_tval *tv) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\t/* depth check is done when printing an actual type */\n\n\tif (st->heavy) {\n\t\tduk_fb_sprintf(fb, \"(%p)\", (void *) tv);\n\t}\n\n\tif (!tv) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tif (st->binary) {\n\t\tduk_size_t i;\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LBRACKET);\n\t\tfor (i = 0; i < (duk_size_t) sizeof(*tv); i++) {\n\t\t\tduk_fb_sprintf(fb, \"%02lx\", (unsigned long) ((duk_uint8_t *)tv)[i]);\n\t\t}\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RBRACKET);\n\t}\n\n\tif (st->heavy) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_LANGLE);\n\t}\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\tduk_fb_put_cstring(fb, \"undefined\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_UNUSED: {\n\t\tduk_fb_put_cstring(fb, \"unused\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\tduk_fb_put_cstring(fb, \"null\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tduk_fb_put_cstring(fb, DUK_TVAL_GET_BOOLEAN(tv) ? \"true\" : \"false\");\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\t/* Note: string is a terminal heap object, so no depth check here */\n\t\tduk__print_hstring(st, DUK_TVAL_GET_STRING(tv), 1);\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk__print_hobject(st, DUK_TVAL_GET_OBJECT(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\tduk__print_hbuffer(st, DUK_TVAL_GET_BUFFER(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tduk_fb_sprintf(fb, \"pointer:%p\", (void *) DUK_TVAL_GET_POINTER(tv));\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tduk_c_function func;\n\t\tduk_small_uint_t lf_flags;\n\n\t\tDUK_TVAL_GET_LIGHTFUNC(tv, func, lf_flags);\n\t\tduk_fb_sprintf(fb, \"lightfunc:\");\n\t\tduk_fb_put_funcptr(fb, (duk_uint8_t *) &func, sizeof(func));\n\t\tduk_fb_sprintf(fb, \":%04lx\", (long) lf_flags);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tduk_fb_sprintf(fb, \"%.18g_F\", (double) DUK_TVAL_GET_NUMBER(tv));\n\t\tbreak;\n#endif\n\tdefault: {\n\t\t/* IEEE double is approximately 16 decimal digits; print a couple extra */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tduk_fb_sprintf(fb, \"%.18g\", (double) DUK_TVAL_GET_NUMBER(tv));\n\t\tbreak;\n\t}\n\t}\n\tif (st->heavy) {\n\t\tduk_fb_put_byte(fb, (duk_uint8_t) DUK_ASC_RANGLE);\n\t}\n}\n\nDUK_LOCAL void duk__print_instr(duk__dprint_state *st, duk_instr_t ins) {\n\tduk_fixedbuffer *fb = st->fb;\n\tduk_small_int_t op;\n\tconst char *op_name;\n\n\top = (duk_small_int_t) DUK_DEC_OP(ins);\n\top_name = duk__bc_optab[op];\n\n\t/* XXX: option to fix opcode length so it lines up nicely */\n\n\tif (op == DUK_OP_JUMP) {\n\t\tduk_int_t diff1 = (duk_int_t) (DUK_DEC_ABC(ins) - DUK_BC_JUMP_BIAS);  /* from next pc */\n\t\tduk_int_t diff2 = diff1 + 1;                                          /* from curr pc */\n\n\t\tduk_fb_sprintf(fb, \"%s %ld (to pc%c%ld)\",\n\t\t               (const char *) op_name, (long) diff1,\n\t\t               (int) (diff2 >= 0 ? '+' : '-'),  /* char format: use int */\n\t\t               (long) (diff2 >= 0 ? diff2 : -diff2));\n\t} else {\n\t\tduk_fb_sprintf(fb, \"%s %ld, %ld, %ld\",\n\t\t               (const char *) op_name, (long) DUK_DEC_A(ins),\n\t\t               (long) DUK_DEC_B(ins), (long) DUK_DEC_C(ins));\n\t}\n}\n\nDUK_LOCAL void duk__print_opcode(duk__dprint_state *st, duk_small_int_t opcode) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (opcode < DUK_BC_OP_MIN || opcode > DUK_BC_OP_MAX) {\n\t\tduk_fb_sprintf(fb, \"?(%ld)\", (long) opcode);\n\t} else {\n\t\tduk_fb_sprintf(fb, \"%s\", (const char *) duk__bc_optab[opcode]);\n\t}\n}\n\nDUK_LOCAL void duk__print_catcher(duk__dprint_state *st, duk_catcher *cat) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tif (!cat) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\tduk_fb_sprintf(fb, \"[catcher ptr=%p parent=%p varname=%p pc_base=%p, idx_base=%ld, flags=0x%08lx]\",\n\t               (void *) cat,\n\t               (void *) cat->parent, (void *) cat->h_varname, (void *) cat->pc_base,\n\t\t       (long) cat->idx_base, (unsigned long) cat->flags);\n}\n\n\nDUK_LOCAL void duk__print_activation(duk__dprint_state *st, duk_activation *act) {\n\tduk_fixedbuffer *fb = st->fb;\n\n\tif (duk_fb_is_full(fb)) {\n\t\treturn;\n\t}\n\n\tif (!act) {\n\t\tduk_fb_put_cstring(fb, \"NULL\");\n\t\treturn;\n\t}\n\n\t/* prev_caller: conditional, omitted on purpose, it's rarely used. */\n\t/* prev_line: conditional, omitted on purpose (but would be nice). */\n\tduk_fb_sprintf(fb, \"[activation ptr=%p tv_func=<omit> func=%p parent=%p var_env=%p lex_env=%p cat=%p curr_pc=%p bottom_byteoff=%ld retval_byteoff=%ld reserve_byteoff=%ld flags=%ld]\",\n\t               (void *) act,\n\t               (void *) act->func, (void *) act->parent, (void *) act->var_env,\n\t\t       (void *) act->lex_env, (void *) act->cat, (void *) act->curr_pc,\n\t\t       (long) act->bottom_byteoff, (long) act->retval_byteoff, (long) act->reserve_byteoff,\n\t\t       (long) act->flags);\n}\n\nDUK_INTERNAL duk_int_t duk_debug_vsnprintf(char *str, duk_size_t size, const char *format, va_list ap) {\n\tduk_fixedbuffer fb;\n\tconst char *p = format;\n\tconst char *p_end = p + DUK_STRLEN(format);\n\tduk_int_t retval;\n\n\tduk_memzero(&fb, sizeof(fb));\n\tfb.buffer = (duk_uint8_t *) str;\n\tfb.length = size;\n\tfb.offset = 0;\n\tfb.truncated = 0;\n\n\twhile (p < p_end) {\n\t\tchar ch = *p++;\n\t\tconst char *p_begfmt = NULL;\n\t\tduk_bool_t got_exclamation = 0;\n\t\tduk_bool_t got_long = 0;  /* %lf, %ld etc */\n\t\tduk__dprint_state st;\n\n\t\tif (ch != DUK_ASC_PERCENT) {\n\t\t\tduk_fb_put_byte(&fb, (duk_uint8_t) ch);\n\t\t\tcontinue;\n\t\t}\n\n\t\t/*\n\t\t *  Format tag parsing.  Since we don't understand all the\n\t\t *  possible format tags allowed, we just scan for a terminating\n\t\t *  specifier and keep track of relevant modifiers that we do\n\t\t *  understand.  See man 3 printf.\n\t\t */\n\n\t\tduk_memzero(&st, sizeof(st));\n\t\tst.fb = &fb;\n\t\tst.depth = 0;\n\t\tst.depth_limit = 1;\n\t\tst.loop_stack_index = 0;\n\t\tst.loop_stack_limit = DUK__LOOP_STACK_DEPTH;\n\n\t\tp_begfmt = p - 1;\n\t\twhile (p < p_end) {\n\t\t\tch = *p++;\n\n\t\t\tif (ch == DUK_ASC_STAR) {\n\t\t\t\t/* unsupported: would consume multiple args */\n\t\t\t\tgoto format_error;\n\t\t\t} else if (ch == DUK_ASC_PERCENT) {\n\t\t\t\tduk_fb_put_byte(&fb, (duk_uint8_t) DUK_ASC_PERCENT);\n\t\t\t\tbreak;\n\t\t\t} else if (ch == DUK_ASC_EXCLAMATION) {\n\t\t\t\tgot_exclamation = 1;\n\t\t\t} else if (!got_exclamation && ch == DUK_ASC_LC_L) {\n\t\t\t\tgot_long = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_D) {\n\t\t\t\tst.depth_limit = DUK__DEEP_DEPTH_LIMIT;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_P) {\n\t\t\t\tst.follow_proto = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_I) {\n\t\t\t\tst.internal = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_X) {\n\t\t\t\tst.hexdump = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_LC_H) {\n\t\t\t\tst.heavy = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_ATSIGN) {\n\t\t\t\tst.pointer = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_HASH) {\n\t\t\t\tst.binary = 1;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_T) {\n\t\t\t\tduk_tval *t = va_arg(ap, duk_tval *);\n\t\t\t\tif (st.pointer && !st.heavy) {\n\t\t\t\t\tduk_fb_sprintf(&fb, \"(%p)\", (void *) t);\n\t\t\t\t}\n\t\t\t\tduk__print_tval(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_O) {\n\t\t\t\tduk_heaphdr *t = va_arg(ap, duk_heaphdr *);\n\t\t\t\tif (st.pointer && !st.heavy) {\n\t\t\t\t\tduk_fb_sprintf(&fb, \"(%p)\", (void *) t);\n\t\t\t\t}\n\t\t\t\tduk__print_heaphdr(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_I) {\n\t\t\t\tduk_instr_t t = va_arg(ap, duk_instr_t);\n\t\t\t\tduk__print_instr(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_X) {\n\t\t\t\tlong t = va_arg(ap, long);\n\t\t\t\tduk__print_opcode(&st, (duk_small_int_t) t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_C) {\n\t\t\t\tduk_catcher *t = va_arg(ap, duk_catcher *);\n\t\t\t\tduk__print_catcher(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (got_exclamation && ch == DUK_ASC_UC_A) {\n\t\t\t\tduk_activation *t = va_arg(ap, duk_activation *);\n\t\t\t\tduk__print_activation(&st, t);\n\t\t\t\tbreak;\n\t\t\t} else if (!got_exclamation && strchr(DUK__ALLOWED_STANDARD_SPECIFIERS, (int) ch)) {\n\t\t\t\tchar fmtbuf[DUK__MAX_FORMAT_TAG_LENGTH];\n\t\t\t\tduk_size_t fmtlen;\n\n\t\t\t\tDUK_ASSERT(p >= p_begfmt);\n\t\t\t\tfmtlen = (duk_size_t) (p - p_begfmt);\n\t\t\t\tif (fmtlen >= sizeof(fmtbuf)) {\n\t\t\t\t\t/* format is too large, abort */\n\t\t\t\t\tgoto format_error;\n\t\t\t\t}\n\t\t\t\tduk_memzero(fmtbuf, sizeof(fmtbuf));\n\t\t\t\tduk_memcpy(fmtbuf, p_begfmt, fmtlen);\n\n\t\t\t\t/* assume exactly 1 arg, which is why '*' is forbidden; arg size still\n\t\t\t\t * depends on type though.\n\t\t\t\t */\n\n\t\t\t\tif (ch == DUK_ASC_LC_F || ch == DUK_ASC_LC_G || ch == DUK_ASC_LC_E) {\n\t\t\t\t\t/* %f and %lf both consume a 'long' */\n\t\t\t\t\tdouble arg = va_arg(ap, double);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_D && got_long) {\n\t\t\t\t\t/* %ld */\n\t\t\t\t\tlong arg = va_arg(ap, long);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_D) {\n\t\t\t\t\t/* %d; only 16 bits are guaranteed */\n\t\t\t\t\tint arg = va_arg(ap, int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_U && got_long) {\n\t\t\t\t\t/* %lu */\n\t\t\t\t\tunsigned long arg = va_arg(ap, unsigned long);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_U) {\n\t\t\t\t\t/* %u; only 16 bits are guaranteed */\n\t\t\t\t\tunsigned int arg = va_arg(ap, unsigned int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_X && got_long) {\n\t\t\t\t\t/* %lx */\n\t\t\t\t\tunsigned long arg = va_arg(ap, unsigned long);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_X) {\n\t\t\t\t\t/* %x; only 16 bits are guaranteed */\n\t\t\t\t\tunsigned int arg = va_arg(ap, unsigned int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else if (ch == DUK_ASC_LC_S) {\n\t\t\t\t\t/* %s */\n\t\t\t\t\tconst char *arg = va_arg(ap, const char *);\n\t\t\t\t\tif (arg == NULL) {\n\t\t\t\t\t\t/* '%s' and NULL is not portable, so special case\n\t\t\t\t\t\t * it for debug printing.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk_fb_sprintf(&fb, \"NULL\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t\t}\n\t\t\t\t} else if (ch == DUK_ASC_LC_P) {\n\t\t\t\t\t/* %p */\n\t\t\t\t\tvoid *arg = va_arg(ap, void *);\n\t\t\t\t\tif (arg == NULL) {\n\t\t\t\t\t\t/* '%p' and NULL is portable, but special case it\n\t\t\t\t\t\t * anyway to get a standard NULL marker in logs.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk_fb_sprintf(&fb, \"NULL\");\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t\t}\n\t\t\t\t} else if (ch == DUK_ASC_LC_C) {\n\t\t\t\t\t/* '%c', passed concretely as int */\n\t\t\t\t\tint arg = va_arg(ap, int);\n\t\t\t\t\tduk_fb_sprintf(&fb, fmtbuf, arg);\n\t\t\t\t} else {\n\t\t\t\t\t/* Should not happen. */\n\t\t\t\t\tduk_fb_sprintf(&fb, \"INVALID-FORMAT(%s)\", (const char *) fmtbuf);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t/* ignore */\n\t\t\t}\n\t\t}\n\t}\n\tgoto done;\n\n format_error:\n\tduk_fb_put_cstring(&fb, \"FMTERR\");\n\t/* fall through */\n\n done:\n\tretval = (duk_int_t) fb.offset;\n\tduk_fb_put_byte(&fb, (duk_uint8_t) 0);\n\n\t/* return total chars written excluding terminator */\n\treturn retval;\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL duk_int_t duk_debug_snprintf(char *str, duk_size_t size, const char *format, ...) {\n\tduk_int_t retval;\n\tva_list ap;\n\tva_start(ap, format);\n\tretval = duk_debug_vsnprintf(str, size, format, ap);\n\tva_end(ap);\n\treturn retval;\n}\n#endif\n\n/* Formatting function pointers is tricky: there is no standard pointer for\n * function pointers and the size of a function pointer may depend on the\n * specific pointer type.  This helper formats a function pointer based on\n * its memory layout to get something useful on most platforms.\n */\nDUK_INTERNAL void duk_debug_format_funcptr(char *buf, duk_size_t buf_size, duk_uint8_t *fptr, duk_size_t fptr_size) {\n\tduk_size_t i;\n\tduk_uint8_t *p = (duk_uint8_t *) buf;\n\tduk_uint8_t *p_end = (duk_uint8_t *) (buf + buf_size - 1);\n\n\tDUK_ASSERT(buf != NULL);\n\tduk_memzero(buf, buf_size);\n\n\tfor (i = 0; i < fptr_size; i++) {\n\t\tduk_int_t left = (duk_int_t) (p_end - p);\n\t\tduk_uint8_t ch;\n\t\tif (left <= 0) {\n\t\t\tbreak;\n\t\t}\n\n\t\t/* Quite approximate but should be useful for little and big endian. */\n#if defined(DUK_USE_INTEGER_BE)\n\t\tch = fptr[i];\n#else\n\t\tch = fptr[fptr_size - 1 - i];\n#endif\n\t\tp += DUK_SNPRINTF((char *) p, (duk_size_t) left, \"%02lx\", (unsigned long) ch);\n\t}\n}\n\n#endif  /* DUK_USE_DEBUG */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_debugger.c",
    "content": "/*\n *  Duktape debugger\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\n/*\n *  Assert helpers\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n#define DUK__DBG_TPORT_ENTER() do { \\\n\t\tDUK_ASSERT(heap->dbg_calling_transport == 0); \\\n\t\theap->dbg_calling_transport = 1; \\\n\t} while (0)\n#define DUK__DBG_TPORT_EXIT() do { \\\n\t\tDUK_ASSERT(heap->dbg_calling_transport == 1); \\\n\t\theap->dbg_calling_transport = 0; \\\n\t} while (0)\n#else\n#define DUK__DBG_TPORT_ENTER() do {} while (0)\n#define DUK__DBG_TPORT_EXIT() do {} while (0)\n#endif\n\n/*\n *  Helper structs\n */\n\ntypedef union {\n\tvoid *p;\n\tduk_uint_t b[1];\n\t/* Use b[] to access the size of the union, which is strictly not\n\t * correct.  Can't use fixed size unless there's feature detection\n\t * for pointer byte size.\n\t */\n} duk__ptr_union;\n\n/*\n *  Detach handling\n */\n\n#define DUK__SET_CONN_BROKEN(thr,reason) do { \\\n\t\t/* For now shared handler is fine. */ \\\n\t\tduk__debug_do_detach1((thr)->heap, (reason)); \\\n\t} while (0)\n\nDUK_LOCAL void duk__debug_do_detach1(duk_heap *heap, duk_int_t reason) {\n\t/* Can be called multiple times with no harm.  Mark the transport\n\t * bad (dbg_read_cb == NULL) and clear state except for the detached\n\t * callback and the udata field.  The detached callback is delayed\n\t * to the message loop so that it can be called between messages;\n\t * this avoids corner cases related to immediate debugger reattach\n\t * inside the detached callback.\n\t */\n\n\tif (heap->dbg_detaching) {\n\t\tDUK_D(DUK_DPRINT(\"debugger already detaching, ignore detach1\"));\n\t\treturn;\n\t}\n\n\tDUK_D(DUK_DPRINT(\"debugger transport detaching, marking transport broken\"));\n\n\theap->dbg_detaching = 1;  /* prevent multiple in-progress detaches */\n\n\tif (heap->dbg_write_cb != NULL) {\n\t\tduk_hthread *thr;\n\n\t\tthr = heap->heap_thread;\n\t\tDUK_ASSERT(thr != NULL);\n\n\t\tduk_debug_write_notify(thr, DUK_DBG_CMD_DETACHING);\n\t\tduk_debug_write_int(thr, reason);\n\t\tduk_debug_write_eom(thr);\n\t}\n\n\theap->dbg_read_cb = NULL;\n\theap->dbg_write_cb = NULL;\n\theap->dbg_peek_cb = NULL;\n\theap->dbg_read_flush_cb = NULL;\n\theap->dbg_write_flush_cb = NULL;\n\theap->dbg_request_cb = NULL;\n\t/* heap->dbg_detached_cb: keep */\n\t/* heap->dbg_udata: keep */\n\t/* heap->dbg_processing: keep on purpose to avoid debugger re-entry in detaching state */\n\theap->dbg_state_dirty = 0;\n\theap->dbg_force_restart = 0;\n\theap->dbg_pause_flags = 0;\n\theap->dbg_pause_act = NULL;\n\theap->dbg_pause_startline = 0;\n\theap->dbg_have_next_byte = 0;\n\tduk_debug_clear_paused(heap);  /* XXX: some overlap with field inits above */\n\theap->dbg_state_dirty = 0;     /* XXX: clear_paused sets dirty; rework? */\n\n\t/* Ensure there are no stale active breakpoint pointers.\n\t * Breakpoint list is currently kept - we could empty it\n\t * here but we'd need to handle refcounts correctly, and\n\t * we'd need a 'thr' reference for that.\n\t *\n\t * XXX: clear breakpoint on either attach or detach?\n\t */\n\theap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;\n}\n\nDUK_LOCAL void duk__debug_do_detach2(duk_heap *heap) {\n\tduk_debug_detached_function detached_cb;\n\tvoid *detached_udata;\n\tduk_hthread *thr;\n\n\tthr = heap->heap_thread;\n\tif (thr == NULL) {\n\t\tDUK_ASSERT(heap->dbg_detached_cb == NULL);\n\t\treturn;\n\t}\n\n\t/* Safe to call multiple times. */\n\n\tdetached_cb = heap->dbg_detached_cb;\n\tdetached_udata = heap->dbg_udata;\n\theap->dbg_detached_cb = NULL;\n\theap->dbg_udata = NULL;\n\n\tif (detached_cb) {\n\t\t/* Careful here: state must be wiped before the call\n\t\t * so that we can cleanly handle a re-attach from\n\t\t * inside the callback.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"detached during message loop, delayed call to detached_cb\"));\n\t\tdetached_cb(thr, detached_udata);\n\t}\n\n\theap->dbg_detaching = 0;\n}\n\nDUK_INTERNAL void duk_debug_do_detach(duk_heap *heap) {\n\tduk__debug_do_detach1(heap, 0);\n\tduk__debug_do_detach2(heap);\n}\n\n/* Called on a read/write error: NULL all callbacks except the detached\n * callback so that we never accidentally call them after a read/write\n * error has been indicated.  This is especially important for the transport\n * I/O callbacks to fulfill guaranteed callback semantics.\n */\nDUK_LOCAL void duk__debug_null_most_callbacks(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\n\theap = thr->heap;\n\tDUK_D(DUK_DPRINT(\"transport read/write error, NULL all callbacks expected detached\"));\n\theap->dbg_read_cb = NULL;\n\theap->dbg_write_cb = NULL;  /* this is especially critical to avoid another write call in detach1() */\n\theap->dbg_peek_cb = NULL;\n\theap->dbg_read_flush_cb = NULL;\n\theap->dbg_write_flush_cb = NULL;\n\theap->dbg_request_cb = NULL;\n\t/* keep heap->dbg_detached_cb */\n}\n\n/*\n *  Pause handling\n */\n\nDUK_LOCAL void duk__debug_set_pause_state(duk_hthread *thr, duk_heap *heap, duk_small_uint_t pause_flags) {\n\tduk_uint_fast32_t line;\n\n\tline = duk_debug_curr_line(thr);\n\tif (line == 0) {\n\t\t/* No line info for current function. */\n\t\tduk_small_uint_t updated_flags;\n\n\t\tupdated_flags = pause_flags & ~(DUK_PAUSE_FLAG_LINE_CHANGE);\n\t\tDUK_D(DUK_DPRINT(\"no line info for current activation, disable line-based pause flags: 0x%08lx -> 0x%08lx\",\n\t\t                 (long) pause_flags, (long) updated_flags));\n\t\tpause_flags = updated_flags;\n\t}\n\n\theap->dbg_pause_flags = pause_flags;\n\theap->dbg_pause_act = thr->callstack_curr;\n\theap->dbg_pause_startline = (duk_uint32_t) line;\n\theap->dbg_state_dirty = 1;\n\n\tDUK_D(DUK_DPRINT(\"set state for automatic pause triggers, flags=0x%08lx, act=%p, startline=%ld\",\n\t                 (long) heap->dbg_pause_flags, (void *) heap->dbg_pause_act,\n\t                 (long) heap->dbg_pause_startline));\n}\n\n/*\n *  Debug connection peek and flush primitives\n */\n\nDUK_INTERNAL duk_bool_t duk_debug_read_peek(duk_hthread *thr) {\n\tduk_heap *heap;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to peek in detached state, return zero (= no data)\"));\n\t\treturn 0;\n\t}\n\tif (heap->dbg_peek_cb == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"no peek callback, return zero (= no data)\"));\n\t\treturn 0;\n\t}\n\n\tDUK__DBG_TPORT_ENTER();\n\tret = (duk_bool_t) (heap->dbg_peek_cb(heap->dbg_udata) > 0);\n\tDUK__DBG_TPORT_EXIT();\n\treturn ret;\n}\n\nDUK_INTERNAL void duk_debug_read_flush(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to read flush in detached state, ignore\"));\n\t\treturn;\n\t}\n\tif (heap->dbg_read_flush_cb == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"no read flush callback, ignore\"));\n\t\treturn;\n\t}\n\n\tDUK__DBG_TPORT_ENTER();\n\theap->dbg_read_flush_cb(heap->dbg_udata);\n\tDUK__DBG_TPORT_EXIT();\n}\n\nDUK_INTERNAL void duk_debug_write_flush(duk_hthread *thr) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to write flush in detached state, ignore\"));\n\t\treturn;\n\t}\n\tif (heap->dbg_write_flush_cb == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"no write flush callback, ignore\"));\n\t\treturn;\n\t}\n\n\tDUK__DBG_TPORT_ENTER();\n\theap->dbg_write_flush_cb(heap->dbg_udata);\n\tDUK__DBG_TPORT_EXIT();\n}\n\n/*\n *  Debug connection skip primitives\n */\n\n/* Skip fully. */\nDUK_INTERNAL void duk_debug_skip_bytes(duk_hthread *thr, duk_size_t length) {\n\tduk_uint8_t dummy[64];\n\tduk_size_t now;\n\n\tDUK_ASSERT(thr != NULL);\n\n\twhile (length > 0) {\n\t\tnow = (length > sizeof(dummy) ? sizeof(dummy) : length);\n\t\tduk_debug_read_bytes(thr, dummy, now);\n\t\tlength -= now;\n\t}\n}\n\nDUK_INTERNAL void duk_debug_skip_byte(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\t(void) duk_debug_read_byte(thr);\n}\n\n/*\n *  Debug connection read primitives\n */\n\n/* Peek ahead in the stream one byte. */\nDUK_INTERNAL uint8_t duk_debug_peek_byte(duk_hthread *thr) {\n\t/* It is important not to call this if the last byte read was an EOM.\n\t * Reading ahead in this scenario would cause unnecessary blocking if\n\t * another message is not available.\n\t */\n\n\tduk_uint8_t x;\n\n\tx = duk_debug_read_byte(thr);\n\tthr->heap->dbg_have_next_byte = 1;\n\tthr->heap->dbg_next_byte = x;\n\treturn x;\n}\n\n/* Read fully. */\nDUK_INTERNAL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_size_t length) {\n\tduk_heap *heap;\n\tduk_uint8_t *p;\n\tduk_size_t left;\n\tduk_size_t got;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(data != NULL);\n\n\tif (heap->dbg_read_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to read %ld bytes in detached state, return zero data\", (long) length));\n\t\tgoto fail;\n\t}\n\n\t/* NOTE: length may be zero */\n\tp = data;\n\tif (length >= 1 && heap->dbg_have_next_byte) {\n\t\theap->dbg_have_next_byte = 0;\n\t\t*p++ = heap->dbg_next_byte;\n\t}\n\tfor (;;) {\n\t\tleft = (duk_size_t) ((data + length) - p);\n\t\tif (left == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tDUK_ASSERT(heap->dbg_read_cb != NULL);\n\t\tDUK_ASSERT(left >= 1);\n#if defined(DUK_USE_DEBUGGER_TRANSPORT_TORTURE)\n\t\tleft = 1;\n#endif\n\t\tDUK__DBG_TPORT_ENTER();\n\t\tgot = heap->dbg_read_cb(heap->dbg_udata, (char *) p, left);\n\t\tDUK__DBG_TPORT_EXIT();\n\n\t\tif (got == 0 || got > left) {\n\t\t\tDUK_D(DUK_DPRINT(\"connection error during read, return zero data\"));\n\t\t\tduk__debug_null_most_callbacks(thr);  /* avoid calling write callback in detach1() */\n\t\t\tDUK__SET_CONN_BROKEN(thr, 1);\n\t\t\tgoto fail;\n\t\t}\n\t\tp += got;\n\t}\n\treturn;\n\n fail:\n\tduk_memzero((void *) data, (size_t) length);\n}\n\nDUK_INTERNAL duk_uint8_t duk_debug_read_byte(duk_hthread *thr) {\n\tduk_uint8_t x;\n\n\tx = 0;  /* just in case callback is broken and won't write 'x' */\n\tduk_debug_read_bytes(thr, &x, 1);\n\treturn x;\n}\n\nDUK_LOCAL duk_uint32_t duk__debug_read_uint32_raw(duk_hthread *thr) {\n\tduk_uint8_t buf[4];\n\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_read_bytes(thr, buf, 4);\n\treturn ((duk_uint32_t) buf[0] << 24) |\n\t       ((duk_uint32_t) buf[1] << 16) |\n\t       ((duk_uint32_t) buf[2] << 8) |\n\t       (duk_uint32_t) buf[3];\n}\n\nDUK_LOCAL duk_int32_t duk__debug_read_int32_raw(duk_hthread *thr) {\n\treturn (duk_int32_t) duk__debug_read_uint32_raw(thr);\n}\n\nDUK_LOCAL duk_uint16_t duk__debug_read_uint16_raw(duk_hthread *thr) {\n\tduk_uint8_t buf[2];\n\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_read_bytes(thr, buf, 2);\n\treturn ((duk_uint16_t) buf[0] << 8) |\n\t       (duk_uint16_t) buf[1];\n}\n\nDUK_INTERNAL duk_int32_t duk_debug_read_int(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\tduk_small_uint_t t;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x >= 0xc0) {\n\t\tt = duk_debug_read_byte(thr);\n\t\treturn (duk_int32_t) (((x - 0xc0) << 8) + t);\n\t} else if (x >= 0x80) {\n\t\treturn (duk_int32_t) (x - 0x80);\n\t} else if (x == DUK_DBG_IB_INT4) {\n\t\treturn (duk_int32_t) duk__debug_read_uint32_raw(thr);\n\t}\n\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode int\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn 0;\n}\n\nDUK_LOCAL duk_hstring *duk__debug_read_hstring_raw(duk_hthread *thr, duk_uint32_t len) {\n\tduk_uint8_t buf[31];\n\tduk_uint8_t *p;\n\n\tif (len <= sizeof(buf)) {\n\t\tduk_debug_read_bytes(thr, buf, (duk_size_t) len);\n\t\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) len);\n\t} else {\n\t\tp = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len);  /* zero for paranoia */\n\t\tDUK_ASSERT(p != NULL);\n\t\tduk_debug_read_bytes(thr, p, (duk_size_t) len);\n\t\t(void) duk_buffer_to_string(thr, -1);  /* Safety relies on debug client, which is OK. */\n\t}\n\n\treturn duk_require_hstring(thr, -1);\n}\n\nDUK_INTERNAL duk_hstring *duk_debug_read_hstring(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\tduk_uint32_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x >= 0x60 && x <= 0x7f) {\n\t\t/* For short strings, use a fixed temp buffer. */\n\t\tlen = (duk_uint32_t) (x - 0x60);\n\t} else if (x == DUK_DBG_IB_STR2) {\n\t\tlen = (duk_uint32_t) duk__debug_read_uint16_raw(thr);\n\t} else if (x == DUK_DBG_IB_STR4) {\n\t\tlen = (duk_uint32_t) duk__debug_read_uint32_raw(thr);\n\t} else {\n\t\tgoto fail;\n\t}\n\n\treturn duk__debug_read_hstring_raw(thr, len);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode int\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\tduk_push_hstring_empty(thr);  /* always push some string */\n\treturn duk_require_hstring(thr, -1);\n}\n\nDUK_LOCAL duk_hbuffer *duk__debug_read_hbuffer_raw(duk_hthread *thr, duk_uint32_t len) {\n\tduk_uint8_t *p;\n\n\tp = (duk_uint8_t *) duk_push_fixed_buffer(thr, (duk_size_t) len);  /* zero for paranoia */\n\tDUK_ASSERT(p != NULL);\n\tduk_debug_read_bytes(thr, p, (duk_size_t) len);\n\n\treturn duk_require_hbuffer(thr, -1);\n}\n\nDUK_LOCAL void *duk__debug_read_pointer_raw(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\tduk__ptr_union pu;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x != sizeof(pu)) {\n\t\tgoto fail;\n\t}\n\tduk_debug_read_bytes(thr, (duk_uint8_t *) &pu.p, sizeof(pu));\n#if defined(DUK_USE_INTEGER_LE)\n\tduk_byteswap_bytes((duk_uint8_t *) pu.b, sizeof(pu));\n#endif\n\treturn (void *) pu.p;\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode pointer\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn (void *) NULL;\n}\n\nDUK_LOCAL duk_double_t duk__debug_read_double_raw(duk_hthread *thr) {\n\tduk_double_union du;\n\n\tDUK_ASSERT(sizeof(du.uc) == 8);\n\tduk_debug_read_bytes(thr, (duk_uint8_t *) du.uc, sizeof(du.uc));\n\tDUK_DBLUNION_DOUBLE_NTOH(&du);\n\treturn du.d;\n}\n\n#if 0\nDUK_INTERNAL duk_heaphdr *duk_debug_read_heapptr(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tif (x != DUK_DBG_IB_HEAPPTR) {\n\t\tgoto fail;\n\t}\n\n\treturn (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode heapptr\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn NULL;\n}\n#endif\n\nDUK_INTERNAL duk_heaphdr *duk_debug_read_any_ptr(duk_hthread *thr) {\n\tduk_small_uint_t x;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\tswitch (x) {\n\tcase DUK_DBG_IB_OBJECT:\n\tcase DUK_DBG_IB_POINTER:\n\tcase DUK_DBG_IB_HEAPPTR:\n\t\t/* Accept any pointer-like value; for 'object' dvalue, read\n\t\t * and ignore the class number.\n\t\t */\n\t\tif (x == DUK_DBG_IB_OBJECT) {\n\t\t\tduk_debug_skip_byte(thr);\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\tgoto fail;\n\t}\n\n\treturn (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode any pointer (object, pointer, heapptr)\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_tval *duk_debug_read_tval(duk_hthread *thr) {\n\tduk_uint8_t x;\n\tduk_uint_t t;\n\tduk_uint32_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tx = duk_debug_read_byte(thr);\n\n\tif (x >= 0xc0) {\n\t\tt = (duk_uint_t) (x - 0xc0);\n\t\tt = (t << 8) + duk_debug_read_byte(thr);\n\t\tduk_push_uint(thr, (duk_uint_t) t);\n\t\tgoto return_ptr;\n\t}\n\tif (x >= 0x80) {\n\t\tduk_push_uint(thr, (duk_uint_t) (x - 0x80));\n\t\tgoto return_ptr;\n\t}\n\tif (x >= 0x60) {\n\t\tlen = (duk_uint32_t) (x - 0x60);\n\t\tduk__debug_read_hstring_raw(thr, len);\n\t\tgoto return_ptr;\n\t}\n\n\tswitch (x) {\n\tcase DUK_DBG_IB_INT4: {\n\t\tduk_int32_t i = duk__debug_read_int32_raw(thr);\n\t\tduk_push_i32(thr, i);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_STR4: {\n\t\tlen = duk__debug_read_uint32_raw(thr);\n\t\tduk__debug_read_hstring_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_STR2: {\n\t\tlen = duk__debug_read_uint16_raw(thr);\n\t\tduk__debug_read_hstring_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_BUF4: {\n\t\tlen = duk__debug_read_uint32_raw(thr);\n\t\tduk__debug_read_hbuffer_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_BUF2: {\n\t\tlen = duk__debug_read_uint16_raw(thr);\n\t\tduk__debug_read_hbuffer_raw(thr, len);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_UNDEFINED: {\n\t\tduk_push_undefined(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_NULL: {\n\t\tduk_push_null(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_TRUE: {\n\t\tduk_push_true(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_FALSE: {\n\t\tduk_push_false(thr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_NUMBER: {\n\t\tduk_double_t d;\n\t\td = duk__debug_read_double_raw(thr);\n\t\tduk_push_number(thr, d);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_OBJECT: {\n\t\tduk_heaphdr *h;\n\t\tduk_debug_skip_byte(thr);\n\t\th = (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\t\tduk_push_heapptr(thr, (void *) h);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_POINTER: {\n\t\tvoid *ptr;\n\t\tptr = duk__debug_read_pointer_raw(thr);\n\t\tduk_push_pointer(thr, ptr);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_LIGHTFUNC: {\n\t\t/* XXX: Not needed for now, so not implemented.  Note that\n\t\t * function pointers may have different size/layout than\n\t\t * a void pointer.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"reading lightfunc values unimplemented\"));\n\t\tgoto fail;\n\t}\n\tcase DUK_DBG_IB_HEAPPTR: {\n\t\tduk_heaphdr *h;\n\t\th = (duk_heaphdr *) duk__debug_read_pointer_raw(thr);\n\t\tduk_push_heapptr(thr, (void *) h);\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_UNUSED:  /* unused: not accepted in inbound messages */\n\tdefault:\n\t\tgoto fail;\n\t}\n\n return_ptr:\n\treturn DUK_GET_TVAL_NEGIDX(thr, -1);\n\n fail:\n\tDUK_D(DUK_DPRINT(\"debug connection error: failed to decode tval\"));\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn NULL;\n}\n\n/*\n *  Debug connection write primitives\n */\n\n/* Write fully. */\nDUK_INTERNAL void duk_debug_write_bytes(duk_hthread *thr, const duk_uint8_t *data, duk_size_t length) {\n\tduk_heap *heap;\n\tconst duk_uint8_t *p;\n\tduk_size_t left;\n\tduk_size_t got;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(length == 0 || data != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_write_cb == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"attempt to write %ld bytes in detached state, ignore\", (long) length));\n\t\treturn;\n\t}\n\tif (length == 0) {\n\t\t/* Avoid doing an actual write callback with length == 0,\n\t\t * because that's reserved for a write flush.\n\t\t */\n\t\treturn;\n\t}\n\tDUK_ASSERT(data != NULL);\n\n\tp = data;\n\tfor (;;) {\n\t\tleft = (duk_size_t) ((data + length) - p);\n\t\tif (left == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tDUK_ASSERT(heap->dbg_write_cb != NULL);\n\t\tDUK_ASSERT(left >= 1);\n#if defined(DUK_USE_DEBUGGER_TRANSPORT_TORTURE)\n\t\tleft = 1;\n#endif\n\t\tDUK__DBG_TPORT_ENTER();\n\t\tgot = heap->dbg_write_cb(heap->dbg_udata, (const char *) p, left);\n\t\tDUK__DBG_TPORT_EXIT();\n\n\t\tif (got == 0 || got > left) {\n\t\t\tduk__debug_null_most_callbacks(thr);  /* avoid calling write callback in detach1() */\n\t\t\tDUK_D(DUK_DPRINT(\"connection error during write\"));\n\t\t\tDUK__SET_CONN_BROKEN(thr, 1);\n\t\t\treturn;\n\t\t}\n\t\tp += got;\n\t}\n}\n\nDUK_INTERNAL void duk_debug_write_byte(duk_hthread *thr, duk_uint8_t x) {\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &x, 1);\n}\n\nDUK_INTERNAL void duk_debug_write_unused(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_UNUSED);\n}\n\nDUK_INTERNAL void duk_debug_write_undefined(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_UNDEFINED);\n}\n\n#if defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL void duk_debug_write_null(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_NULL);\n}\n#endif\n\nDUK_INTERNAL void duk_debug_write_boolean(duk_hthread *thr, duk_uint_t val) {\n\tduk_debug_write_byte(thr, val ? DUK_DBG_IB_TRUE : DUK_DBG_IB_FALSE);\n}\n\n/* Write signed 32-bit integer. */\nDUK_INTERNAL void duk_debug_write_int(duk_hthread *thr, duk_int32_t x) {\n\tduk_uint8_t buf[5];\n\tduk_size_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tif (x >= 0 && x <= 0x3fL) {\n\t\tbuf[0] = (duk_uint8_t) (0x80 + x);\n\t\tlen = 1;\n\t} else if (x >= 0 && x <= 0x3fffL) {\n\t\tbuf[0] = (duk_uint8_t) (0xc0 + (x >> 8));\n\t\tbuf[1] = (duk_uint8_t) (x & 0xff);\n\t\tlen = 2;\n\t} else {\n\t\t/* Signed integers always map to 4 bytes now. */\n\t\tbuf[0] = (duk_uint8_t) DUK_DBG_IB_INT4;\n\t\tbuf[1] = (duk_uint8_t) ((x >> 24) & 0xff);\n\t\tbuf[2] = (duk_uint8_t) ((x >> 16) & 0xff);\n\t\tbuf[3] = (duk_uint8_t) ((x >> 8) & 0xff);\n\t\tbuf[4] = (duk_uint8_t) (x & 0xff);\n\t\tlen = 5;\n\t}\n\tduk_debug_write_bytes(thr, buf, len);\n}\n\n/* Write unsigned 32-bit integer. */\nDUK_INTERNAL void duk_debug_write_uint(duk_hthread *thr, duk_uint32_t x) {\n\t/* The debugger protocol doesn't support a plain integer encoding for\n\t * the full 32-bit unsigned range (only 32-bit signed).  For now,\n\t * unsigned 32-bit values simply written as signed ones.  This is not\n\t * a concrete issue except for 32-bit heaphdr fields.  Proper solutions\n\t * would be to (a) write such integers as IEEE doubles or (b) add an\n\t * unsigned 32-bit dvalue.\n\t */\n\tif (x >= 0x80000000UL) {\n\t\tDUK_D(DUK_DPRINT(\"writing unsigned integer 0x%08lx as signed integer\",\n\t\t                 (long) x));\n\t}\n\tduk_debug_write_int(thr, (duk_int32_t) x);\n}\n\nDUK_INTERNAL void duk_debug_write_strbuf(duk_hthread *thr, const char *data, duk_size_t length, duk_uint8_t marker_base) {\n\tduk_uint8_t buf[5];\n\tduk_size_t buflen;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(length == 0 || data != NULL);\n\n\tif (length <= 0x1fUL && marker_base == DUK_DBG_IB_STR4) {\n\t\t/* For strings, special form for short lengths. */\n\t\tbuf[0] = (duk_uint8_t) (0x60 + length);\n\t\tbuflen = 1;\n\t} else if (length <= 0xffffUL) {\n\t\tbuf[0] = (duk_uint8_t) (marker_base + 1);\n\t\tbuf[1] = (duk_uint8_t) (length >> 8);\n\t\tbuf[2] = (duk_uint8_t) (length & 0xff);\n\t\tbuflen = 3;\n\t} else {\n\t\tbuf[0] = (duk_uint8_t) marker_base;\n\t\tbuf[1] = (duk_uint8_t) (length >> 24);\n\t\tbuf[2] = (duk_uint8_t) ((length >> 16) & 0xff);\n\t\tbuf[3] = (duk_uint8_t) ((length >> 8) & 0xff);\n\t\tbuf[4] = (duk_uint8_t) (length & 0xff);\n\t\tbuflen = 5;\n\t}\n\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) buf, buflen);\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) data, length);\n}\n\nDUK_INTERNAL void duk_debug_write_string(duk_hthread *thr, const char *data, duk_size_t length) {\n\tduk_debug_write_strbuf(thr, data, length, DUK_DBG_IB_STR4);\n}\n\nDUK_INTERNAL void duk_debug_write_cstring(duk_hthread *thr, const char *data) {\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_write_string(thr,\n\t                       data,\n\t                       data ? DUK_STRLEN(data) : 0);\n}\n\nDUK_INTERNAL void duk_debug_write_hstring(duk_hthread *thr, duk_hstring *h) {\n\tDUK_ASSERT(thr != NULL);\n\n\t/* XXX: differentiate null pointer from empty string? */\n\tduk_debug_write_string(thr,\n\t                       (h != NULL ? (const char *) DUK_HSTRING_GET_DATA(h) : NULL),\n\t                       (h != NULL ? (duk_size_t) DUK_HSTRING_GET_BYTELEN(h) : 0));\n}\n\nDUK_LOCAL void duk__debug_write_hstring_safe_top(duk_hthread *thr) {\n\tduk_debug_write_hstring(thr, duk_safe_to_hstring(thr, -1));\n}\n\nDUK_INTERNAL void duk_debug_write_buffer(duk_hthread *thr, const char *data, duk_size_t length) {\n\tduk_debug_write_strbuf(thr, data, length, DUK_DBG_IB_BUF4);\n}\n\nDUK_INTERNAL void duk_debug_write_hbuffer(duk_hthread *thr, duk_hbuffer *h) {\n\tDUK_ASSERT(thr != NULL);\n\n\tduk_debug_write_buffer(thr,\n\t                       (h != NULL ? (const char *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h) : NULL),\n\t                       (h != NULL ? (duk_size_t) DUK_HBUFFER_GET_SIZE(h) : 0));\n}\n\nDUK_LOCAL void duk__debug_write_pointer_raw(duk_hthread *thr, void *ptr, duk_uint8_t ibyte) {\n\tduk_uint8_t buf[2];\n\tduk__ptr_union pu;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(sizeof(ptr) >= 1 && sizeof(ptr) <= 16);\n\t/* ptr may be NULL */\n\n\tbuf[0] = ibyte;\n\tbuf[1] = sizeof(pu);\n\tduk_debug_write_bytes(thr, buf, 2);\n\tpu.p = (void *) ptr;\n#if defined(DUK_USE_INTEGER_LE)\n\tduk_byteswap_bytes((duk_uint8_t *) pu.b, sizeof(pu));\n#endif\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &pu.p, (duk_size_t) sizeof(pu));\n}\n\nDUK_INTERNAL void duk_debug_write_pointer(duk_hthread *thr, void *ptr) {\n\tduk__debug_write_pointer_raw(thr, ptr, DUK_DBG_IB_POINTER);\n}\n\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP) || defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL void duk_debug_write_heapptr(duk_hthread *thr, duk_heaphdr *h) {\n\tduk__debug_write_pointer_raw(thr, (void *) h, DUK_DBG_IB_HEAPPTR);\n}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP || DUK_USE_DEBUGGER_INSPECT */\n\nDUK_INTERNAL void duk_debug_write_hobject(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint8_t buf[3];\n\tduk__ptr_union pu;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(sizeof(obj) >= 1 && sizeof(obj) <= 16);\n\tDUK_ASSERT(obj != NULL);\n\n\tbuf[0] = DUK_DBG_IB_OBJECT;\n\tbuf[1] = (duk_uint8_t) DUK_HOBJECT_GET_CLASS_NUMBER(obj);\n\tbuf[2] = sizeof(pu);\n\tduk_debug_write_bytes(thr, buf, 3);\n\tpu.p = (void *) obj;\n#if defined(DUK_USE_INTEGER_LE)\n\tduk_byteswap_bytes((duk_uint8_t *) pu.b, sizeof(pu));\n#endif\n\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &pu.p, (duk_size_t) sizeof(pu));\n}\n\nDUK_INTERNAL void duk_debug_write_tval(duk_hthread *thr, duk_tval *tv) {\n\tduk_c_function lf_func;\n\tduk_small_uint_t lf_flags;\n\tduk_uint8_t buf[4];\n\tduk_double_union du1;\n\tduk_double_union du2;\n\tduk_int32_t i32;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\t\tduk_debug_write_byte(thr, DUK_DBG_IB_UNDEFINED);\n\t\tbreak;\n\tcase DUK_TAG_UNUSED:\n\t\tduk_debug_write_byte(thr, DUK_DBG_IB_UNUSED);\n\t\tbreak;\n\tcase DUK_TAG_NULL:\n\t\tduk_debug_write_byte(thr, DUK_DBG_IB_NULL);\n\t\tbreak;\n\tcase DUK_TAG_BOOLEAN:\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv) == 0 ||\n\t\t           DUK_TVAL_GET_BOOLEAN(tv) == 1);\n\t\tduk_debug_write_boolean(thr, DUK_TVAL_GET_BOOLEAN(tv));\n\t\tbreak;\n\tcase DUK_TAG_POINTER:\n\t\tduk_debug_write_pointer(thr, (void *) DUK_TVAL_GET_POINTER(tv));\n\t\tbreak;\n\tcase DUK_TAG_LIGHTFUNC:\n\t\tDUK_TVAL_GET_LIGHTFUNC(tv, lf_func, lf_flags);\n\t\tbuf[0] = DUK_DBG_IB_LIGHTFUNC;\n\t\tbuf[1] = (duk_uint8_t) (lf_flags >> 8);\n\t\tbuf[2] = (duk_uint8_t) (lf_flags & 0xff);\n\t\tbuf[3] = sizeof(lf_func);\n\t\tduk_debug_write_bytes(thr, buf, 4);\n\t\tduk_debug_write_bytes(thr, (const duk_uint8_t *) &lf_func, sizeof(lf_func));\n\t\tbreak;\n\tcase DUK_TAG_STRING:\n\t\tduk_debug_write_hstring(thr, DUK_TVAL_GET_STRING(tv));\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\tduk_debug_write_hobject(thr, DUK_TVAL_GET_OBJECT(tv));\n\t\tbreak;\n\tcase DUK_TAG_BUFFER:\n\t\tduk_debug_write_hbuffer(thr, DUK_TVAL_GET_BUFFER(tv));\n\t\tbreak;\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault:\n\t\t/* Numbers are normalized to big (network) endian.  We can\n\t\t * (but are not required) to use integer dvalues when there's\n\t\t * no loss of precision.\n\t\t *\n\t\t * XXX: share check with other code; this check is slow but\n\t\t * reliable and doesn't require careful exponent/mantissa\n\t\t * mask tricks as in the fastint downgrade code.\n\t\t */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tdu1.d = DUK_TVAL_GET_NUMBER(tv);\n\t\ti32 = (duk_int32_t) du1.d;\n\t\tdu2.d = (duk_double_t) i32;\n\n\t\tDUK_DD(DUK_DDPRINT(\"i32=%ld du1=%02x%02x%02x%02x%02x%02x%02x%02x \"\n\t\t                   \"du2=%02x%02x%02x%02x%02x%02x%02x%02x\",\n\t\t                   (long) i32,\n\t\t                   (unsigned int) du1.uc[0], (unsigned int) du1.uc[1],\n\t\t                   (unsigned int) du1.uc[2], (unsigned int) du1.uc[3],\n\t\t                   (unsigned int) du1.uc[4], (unsigned int) du1.uc[5],\n\t\t                   (unsigned int) du1.uc[6], (unsigned int) du1.uc[7],\n\t\t                   (unsigned int) du2.uc[0], (unsigned int) du2.uc[1],\n\t\t                   (unsigned int) du2.uc[2], (unsigned int) du2.uc[3],\n\t\t                   (unsigned int) du2.uc[4], (unsigned int) du2.uc[5],\n\t\t                   (unsigned int) du2.uc[6], (unsigned int) du2.uc[7]));\n\n\t\tif (duk_memcmp((const void *) du1.uc, (const void *) du2.uc, sizeof(du1.uc)) == 0) {\n\t\t\tduk_debug_write_int(thr, i32);\n\t\t} else {\n\t\t\tDUK_DBLUNION_DOUBLE_HTON(&du1);\n\t\t\tduk_debug_write_byte(thr, DUK_DBG_IB_NUMBER);\n\t\t\tduk_debug_write_bytes(thr, (const duk_uint8_t *) du1.uc, sizeof(du1.uc));\n\t\t}\n\t}\n}\n\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP)\n/* Variant for writing duk_tvals so that any heap allocated values are\n * written out as tagged heap pointers.\n */\nDUK_LOCAL void duk__debug_write_tval_heapptr(duk_hthread *thr, duk_tval *tv) {\n\tif (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tduk_debug_write_heapptr(thr, h);\n\t} else {\n\t\tduk_debug_write_tval(thr, tv);\n\t}\n}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP */\n\n/*\n *  Debug connection message write helpers\n */\n\n#if 0  /* unused */\nDUK_INTERNAL void duk_debug_write_request(duk_hthread *thr, duk_small_uint_t command) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_REQUEST);\n\tduk_debug_write_int(thr, command);\n}\n#endif\n\nDUK_INTERNAL void duk_debug_write_reply(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_REPLY);\n}\n\nDUK_INTERNAL void duk_debug_write_error_eom(duk_hthread *thr, duk_small_uint_t err_code, const char *msg) {\n\t/* Allow NULL 'msg' */\n\tduk_debug_write_byte(thr, DUK_DBG_IB_ERROR);\n\tduk_debug_write_int(thr, (duk_int32_t) err_code);\n\tduk_debug_write_cstring(thr, msg);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_INTERNAL void duk_debug_write_notify(duk_hthread *thr, duk_small_uint_t command) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_NOTIFY);\n\tduk_debug_write_int(thr, (duk_int32_t) command);\n}\n\nDUK_INTERNAL void duk_debug_write_eom(duk_hthread *thr) {\n\tduk_debug_write_byte(thr, DUK_DBG_IB_EOM);\n\n\t/* As an initial implementation, write flush after every EOM (and the\n\t * version identifier).  A better implementation would flush only when\n\t * Duktape is finished processing messages so that a flush only happens\n\t * after all outbound messages are finished on that occasion.\n\t */\n\tduk_debug_write_flush(thr);\n}\n\n/*\n *  Status message and helpers\n */\n\nDUK_INTERNAL duk_uint_fast32_t duk_debug_curr_line(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_uint_fast32_t line;\n\tduk_uint_fast32_t pc;\n\n\tact = thr->callstack_curr;\n\tif (act == NULL) {\n\t\treturn 0;\n\t}\n\n\t/* We're conceptually between two opcodes; act->pc indicates the next\n\t * instruction to be executed.  This is usually the correct pc/line to\n\t * indicate in Status.  (For the 'debugger' statement this now reports\n\t * the pc/line after the debugger statement because the debugger opcode\n\t * has already been executed.)\n\t */\n\n\tpc = duk_hthread_get_act_curr_pc(thr, act);\n\n\t/* XXX: this should be optimized to be a raw query and avoid valstack\n\t * operations if possible.\n\t */\n\tduk_push_tval(thr, &act->tv_func);\n\tline = duk_hobject_pc2line_query(thr, -1, pc);\n\tduk_pop(thr);\n\treturn line;\n}\n\nDUK_INTERNAL void duk_debug_send_status(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tduk_debug_write_notify(thr, DUK_DBG_CMD_STATUS);\n\tduk_debug_write_int(thr, (DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) ? 1 : 0));\n\n\tact = thr->callstack_curr;\n\tif (act == NULL) {\n\t\tduk_debug_write_undefined(thr);\n\t\tduk_debug_write_undefined(thr);\n\t\tduk_debug_write_int(thr, 0);\n\t\tduk_debug_write_int(thr, 0);\n\t} else {\n\t\tduk_push_tval(thr, &act->tv_func);\n\t\tduk_get_prop_literal(thr, -1, \"fileName\");\n\t\tduk__debug_write_hstring_safe_top(thr);\n\t\tduk_get_prop_literal(thr, -2, \"name\");\n\t\tduk__debug_write_hstring_safe_top(thr);\n\t\tduk_pop_3(thr);\n\t\t/* Report next pc/line to be executed. */\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) duk_debug_curr_line(thr));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) duk_hthread_get_act_curr_pc(thr, act));\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n\n#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)\nDUK_INTERNAL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal) {\n\t/*\n\t *  NFY <int: 5> <int: fatal> <str: msg> <str: filename> <int: linenumber> EOM\n\t */\n\n\tduk_activation *act;\n\tduk_uint32_t pc;\n\n\tDUK_ASSERT(thr->valstack_top > thr->valstack);  /* At least: ... [err] */\n\n\tduk_debug_write_notify(thr, DUK_DBG_CMD_THROW);\n\tduk_debug_write_int(thr, (duk_int32_t) fatal);\n\n\t/* Report thrown value to client coerced to string */\n\tduk_dup_top(thr);\n\tduk__debug_write_hstring_safe_top(thr);\n\tduk_pop(thr);\n\n\tif (duk_is_error(thr, -1)) {\n\t\t/* Error instance, use augmented error data directly */\n\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME);\n\t\tduk__debug_write_hstring_safe_top(thr);\n\t\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_LINE_NUMBER);\n\t\tduk_debug_write_uint(thr, duk_get_uint(thr, -1));\n\t\tduk_pop_2(thr);\n\t} else {\n\t\t/* For anything other than an Error instance, we calculate the\n\t\t * error location directly from the current activation if one\n\t\t * exists.\n\t\t */\n\t\tact = thr->callstack_curr;\n\t\tif (act != NULL) {\n\t\t\tduk_push_tval(thr, &act->tv_func);\n\t\t\tduk_get_prop_literal(thr, -1, \"fileName\");\n\t\t\tduk__debug_write_hstring_safe_top(thr);\n\t\t\tpc = (duk_uint32_t) duk_hthread_get_act_prev_pc(thr, act);\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) duk_hobject_pc2line_query(thr, -2, pc));\n\t\t\tduk_pop_2(thr);\n\t\t} else {\n\t\t\t/* Can happen if duk_throw() is called on an empty\n\t\t\t * callstack.\n\t\t\t */\n\t\t\tduk_debug_write_cstring(thr, \"\");\n\t\t\tduk_debug_write_uint(thr, 0);\n\t\t}\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n#endif  /* DUK_USE_DEBUGGER_THROW_NOTIFY */\n\n/*\n *  Debug message processing\n */\n\n/* Skip dvalue. */\nDUK_LOCAL duk_bool_t duk__debug_skip_dvalue(duk_hthread *thr) {\n\tduk_uint8_t x;\n\tduk_uint32_t len;\n\n\tx = duk_debug_read_byte(thr);\n\n\tif (x >= 0xc0) {\n\t\tduk_debug_skip_byte(thr);\n\t\treturn 0;\n\t}\n\tif (x >= 0x80) {\n\t\treturn 0;\n\t}\n\tif (x >= 0x60) {\n\t\tduk_debug_skip_bytes(thr, (duk_size_t) (x - 0x60));\n\t\treturn 0;\n\t}\n\tswitch(x) {\n\tcase DUK_DBG_IB_EOM:\n\t\treturn 1;  /* Return 1: got EOM */\n\tcase DUK_DBG_IB_REQUEST:\n\tcase DUK_DBG_IB_REPLY:\n\tcase DUK_DBG_IB_ERROR:\n\tcase DUK_DBG_IB_NOTIFY:\n\t\tbreak;\n\tcase DUK_DBG_IB_INT4:\n\t\t(void) duk__debug_read_uint32_raw(thr);\n\t\tbreak;\n\tcase DUK_DBG_IB_STR4:\n\tcase DUK_DBG_IB_BUF4:\n\t\tlen = duk__debug_read_uint32_raw(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_STR2:\n\tcase DUK_DBG_IB_BUF2:\n\t\tlen = duk__debug_read_uint16_raw(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_UNUSED:\n\tcase DUK_DBG_IB_UNDEFINED:\n\tcase DUK_DBG_IB_NULL:\n\tcase DUK_DBG_IB_TRUE:\n\tcase DUK_DBG_IB_FALSE:\n\t\tbreak;\n\tcase DUK_DBG_IB_NUMBER:\n\t\tduk_debug_skip_bytes(thr, 8);\n\t\tbreak;\n\tcase DUK_DBG_IB_OBJECT:\n\t\tduk_debug_skip_byte(thr);\n\t\tlen = duk_debug_read_byte(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_POINTER:\n\tcase DUK_DBG_IB_HEAPPTR:\n\t\tlen = duk_debug_read_byte(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tcase DUK_DBG_IB_LIGHTFUNC:\n\t\tduk_debug_skip_bytes(thr, 2);\n\t\tlen = duk_debug_read_byte(thr);\n\t\tduk_debug_skip_bytes(thr, len);\n\t\tbreak;\n\tdefault:\n\t\tgoto fail;\n\t}\n\n\treturn 0;\n\n fail:\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn 1;  /* Pretend like we got EOM */\n}\n\n/* Skip dvalues to EOM. */\nDUK_LOCAL void duk__debug_skip_to_eom(duk_hthread *thr) {\n\tfor (;;) {\n\t\tif (duk__debug_skip_dvalue(thr)) {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/* Read and validate a call stack index.  If index is invalid, write out an\n * error message and return zero.\n */\nDUK_LOCAL duk_int32_t duk__debug_read_validate_csindex(duk_hthread *thr) {\n\tduk_int32_t level;\n\tlevel = duk_debug_read_int(thr);\n\tif (level >= 0 || -level > (duk_int32_t) thr->callstack_top) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid callstack index\");\n\t\treturn 0;  /* zero indicates failure */\n\t}\n\treturn level;\n}\n\n/* Read a call stack index and lookup the corresponding duk_activation.\n * If index is invalid, write out an error message and return NULL.\n */\nDUK_LOCAL duk_activation *duk__debug_read_level_get_activation(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_int32_t level;\n\n\tlevel = duk_debug_read_int(thr);\n\tact = duk_hthread_get_activation_for_level(thr, level);\n\tif (act == NULL) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid callstack index\");\n\t}\n\treturn act;\n}\n\n/*\n *  Simple commands\n */\n\nDUK_LOCAL void duk__debug_handle_basic_info(duk_hthread *thr, duk_heap *heap) {\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command Version\"));\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_int(thr, DUK_VERSION);\n\tduk_debug_write_cstring(thr, DUK_GIT_DESCRIBE);\n\tduk_debug_write_cstring(thr, DUK_USE_TARGET_INFO);\n#if defined(DUK_USE_DOUBLE_LE)\n\tduk_debug_write_int(thr, 1);\n#elif defined(DUK_USE_DOUBLE_ME)\n\tduk_debug_write_int(thr, 2);\n#elif defined(DUK_USE_DOUBLE_BE)\n\tduk_debug_write_int(thr, 3);\n#else\n\tduk_debug_write_int(thr, 0);\n#endif\n\tduk_debug_write_int(thr, (duk_int_t) sizeof(void *));\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_trigger_status(duk_hthread *thr, duk_heap *heap) {\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command TriggerStatus\"));\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n\theap->dbg_state_dirty = 1;\n}\n\nDUK_LOCAL void duk__debug_handle_pause(duk_hthread *thr, duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"debug command Pause\"));\n\tduk_debug_set_paused(heap);\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_resume(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_uint_t pause_flags;\n\n\tDUK_D(DUK_DPRINT(\"debug command Resume\"));\n\n\tduk_debug_clear_paused(heap);\n\n\tpause_flags = 0;\n#if 0  /* manual testing */\n\tpause_flags |= DUK_PAUSE_FLAG_ONE_OPCODE;\n\tpause_flags |= DUK_PAUSE_FLAG_CAUGHT_ERROR;\n\tpause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;\n#endif\n#if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)\n\tpause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;\n#endif\n\n\tduk__debug_set_pause_state(thr, heap, pause_flags);\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_step(duk_hthread *thr, duk_heap *heap, duk_int32_t cmd) {\n\tduk_small_uint_t pause_flags;\n\n\tDUK_D(DUK_DPRINT(\"debug command StepInto/StepOver/StepOut: %d\", (int) cmd));\n\n\tif (cmd == DUK_DBG_CMD_STEPINTO) {\n\t\tpause_flags = DUK_PAUSE_FLAG_LINE_CHANGE |\n\t\t              DUK_PAUSE_FLAG_FUNC_ENTRY |\n\t\t              DUK_PAUSE_FLAG_FUNC_EXIT;\n\t} else if (cmd == DUK_DBG_CMD_STEPOVER) {\n\t\tpause_flags = DUK_PAUSE_FLAG_LINE_CHANGE |\n\t\t              DUK_PAUSE_FLAG_FUNC_EXIT;\n\t} else {\n\t\tDUK_ASSERT(cmd == DUK_DBG_CMD_STEPOUT);\n\t\tpause_flags = DUK_PAUSE_FLAG_FUNC_EXIT;\n\t}\n#if defined(DUK_USE_DEBUGGER_PAUSE_UNCAUGHT)\n\tpause_flags |= DUK_PAUSE_FLAG_UNCAUGHT_ERROR;\n#endif\n\n\t/* If current activation doesn't have line information, line-based\n\t * pause flags are automatically disabled.  As a result, e.g.\n\t * StepInto will then pause on (native) function entry or exit.\n\t */\n\tduk_debug_clear_paused(heap);\n\tduk__debug_set_pause_state(thr, heap, pause_flags);\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_list_break(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_int_t i;\n\n\tDUK_D(DUK_DPRINT(\"debug command ListBreak\"));\n\tduk_debug_write_reply(thr);\n\tfor (i = 0; i < (duk_small_int_t) heap->dbg_breakpoint_count; i++) {\n\t\tduk_debug_write_hstring(thr, heap->dbg_breakpoints[i].filename);\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) heap->dbg_breakpoints[i].line);\n\t}\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_add_break(duk_hthread *thr, duk_heap *heap) {\n\tduk_hstring *filename;\n\tduk_uint32_t linenumber;\n\tduk_small_int_t idx;\n\n\tDUK_UNREF(heap);\n\n\tfilename = duk_debug_read_hstring(thr);\n\tlinenumber = (duk_uint32_t) duk_debug_read_int(thr);\n\tDUK_D(DUK_DPRINT(\"debug command AddBreak: %!O:%ld\", (duk_hobject *) filename, (long) linenumber));\n\tidx = duk_debug_add_breakpoint(thr, filename, linenumber);\n\tif (idx >= 0) {\n\t\tduk_debug_write_reply(thr);\n\t\tduk_debug_write_int(thr, (duk_int32_t) idx);\n\t\tduk_debug_write_eom(thr);\n\t} else {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_TOOMANY, \"no space for breakpoint\");\n\t}\n}\n\nDUK_LOCAL void duk__debug_handle_del_break(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_uint_t idx;\n\n\tDUK_UNREF(heap);\n\n\tDUK_D(DUK_DPRINT(\"debug command DelBreak\"));\n\tidx = (duk_small_uint_t) duk_debug_read_int(thr);\n\tif (duk_debug_remove_breakpoint(thr, idx)) {\n\t\tduk_debug_write_reply(thr);\n\t\tduk_debug_write_eom(thr);\n\t} else {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid breakpoint index\");\n\t}\n}\n\nDUK_LOCAL void duk__debug_handle_get_var(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hstring *str;\n\tduk_bool_t rc;\n\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command GetVar\"));\n\n\tact = duk__debug_read_level_get_activation(thr);\n\tif (act == NULL) {\n\t\treturn;\n\t}\n\tstr = duk_debug_read_hstring(thr);  /* push to stack */\n\tDUK_ASSERT(str != NULL);\n\n\trc = duk_js_getvar_activation(thr, act, str, 0);\n\n\tduk_debug_write_reply(thr);\n\tif (rc) {\n\t\tduk_debug_write_int(thr, 1);\n\t\tDUK_ASSERT(duk_get_tval(thr, -2) != NULL);\n\t\tduk_debug_write_tval(thr, duk_get_tval(thr, -2));\n\t} else {\n\t\tduk_debug_write_int(thr, 0);\n\t\tduk_debug_write_unused(thr);\n\t}\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_put_var(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hstring *str;\n\tduk_tval *tv;\n\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command PutVar\"));\n\n\tact = duk__debug_read_level_get_activation(thr);\n\tif (act == NULL) {\n\t\treturn;\n\t}\n\tstr = duk_debug_read_hstring(thr);  /* push to stack */\n\tDUK_ASSERT(str != NULL);\n\ttv = duk_debug_read_tval(thr);\n\tif (tv == NULL) {\n\t\t/* detached */\n\t\treturn;\n\t}\n\n\tduk_js_putvar_activation(thr, act, str, tv, 0);\n\n\t/* XXX: Current putvar implementation doesn't have a success flag,\n\t * add one and send to debug client?\n\t */\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_get_call_stack(duk_hthread *thr, duk_heap *heap) {\n\tduk_hthread *curr_thr = thr;\n\tduk_activation *curr_act;\n\tduk_uint_fast32_t pc;\n\tduk_uint_fast32_t line;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_UNREF(heap);\n\n\tduk_debug_write_reply(thr);\n\twhile (curr_thr != NULL) {\n\t\tfor (curr_act = curr_thr->callstack_curr; curr_act != NULL; curr_act = curr_act->parent) {\n\t\t\t/* PC/line semantics here are:\n\t\t\t *   - For callstack top we're conceptually between two\n\t\t\t *     opcodes and current PC indicates next line to\n\t\t\t *     execute, so report that (matches Status).\n\t\t\t *   - For other activations we're conceptually still\n\t\t\t *     executing the instruction at PC-1, so report that\n\t\t\t *     (matches error stacktrace behavior).\n\t\t\t *   - See: https://github.com/svaarala/duktape/issues/281\n\t\t\t */\n\n\t\t\t/* XXX: optimize to use direct reads, i.e. avoid\n\t\t\t * value stack operations.\n\t\t\t */\n\t\t\tduk_push_tval(thr, &curr_act->tv_func);\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME);\n\t\t\tduk__debug_write_hstring_safe_top(thr);\n\t\t\tduk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME);\n\t\t\tduk__debug_write_hstring_safe_top(thr);\n\t\t\tpc = duk_hthread_get_act_curr_pc(thr, curr_act);\n\t\t\tif (curr_act != curr_thr->callstack_curr && pc > 0) {\n\t\t\t\tpc--;\n\t\t\t}\n\t\t\tline = duk_hobject_pc2line_query(thr, -3, pc);\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) line);\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) pc);\n\t\t\tduk_pop_3(thr);\n\t\t}\n\t\tcurr_thr = curr_thr->resumer;\n\t}\n\t/* SCANBUILD: warning about 'thr' potentially being NULL here,\n\t * warning is incorrect because thr != NULL always here.\n\t */\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_get_locals(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hstring *varname;\n\n\tDUK_UNREF(heap);\n\n\tact = duk__debug_read_level_get_activation(thr);\n\tif (act == NULL) {\n\t\treturn;\n\t}\n\n\tduk_debug_write_reply(thr);\n\n\t/* XXX: several nice-to-have improvements here:\n\t *   - Use direct reads avoiding value stack operations\n\t *   - Avoid triggering getters, indicate getter values to debug client\n\t *   - If side effects are possible, add error catching\n\t */\n\n\tif (DUK_TVAL_IS_OBJECT(&act->tv_func)) {\n\t\tduk_hobject *h_func = DUK_TVAL_GET_OBJECT(&act->tv_func);\n\t\tduk_hobject *h_varmap;\n\n\t\th_varmap = duk_hobject_get_varmap(thr, h_func);\n\t\tif (h_varmap != NULL) {\n\t\t\tduk_push_hobject(thr, h_varmap);\n\t\t\tduk_enum(thr, -1, 0 /*enum_flags*/);\n\t\t\twhile (duk_next(thr, -1 /*enum_index*/, 0 /*get_value*/)) {\n\t\t\t\tvarname = duk_known_hstring(thr, -1);\n\n\t\t\t\tduk_js_getvar_activation(thr, act, varname, 0 /*throw_flag*/);\n\t\t\t\t/* [ ... func varmap enum key value this ] */\n\t\t\t\tduk_debug_write_hstring(thr, duk_get_hstring(thr, -3));\n\t\t\t\tduk_debug_write_tval(thr, duk_get_tval(thr, -2));\n\t\t\t\tduk_pop_3(thr);  /* -> [ ... func varmap enum ] */\n\t\t\t}\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"varmap missing in GetLocals, ignore\"));\n\t\t}\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"varmap is not an object in GetLocals, ignore\"));\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_eval(duk_hthread *thr, duk_heap *heap) {\n\tduk_small_uint_t call_flags;\n\tduk_int_t call_ret;\n\tduk_small_int_t eval_err;\n\tduk_bool_t direct_eval;\n\tduk_int32_t level;\n\tduk_idx_t idx_func;\n\n\tDUK_UNREF(heap);\n\n\tDUK_D(DUK_DPRINT(\"debug command Eval\"));\n\n\t/* The eval code is executed within the lexical environment of a specified\n\t * activation.  For now, use global object eval() function, with the eval\n\t * considered a 'direct call to eval'.\n\t *\n\t * Callstack index for debug commands only affects scope -- the callstack\n\t * as seen by, e.g. Duktape.act() will be the same regardless.\n\t */\n\n\t/* nargs == 2 so we can pass a callstack index to eval(). */\n\tidx_func = duk_get_top(thr);\n\tduk_push_c_function(thr, duk_bi_global_object_eval, 2 /*nargs*/);\n\tduk_push_undefined(thr);  /* 'this' binding shouldn't matter here */\n\n\t/* Read callstack index, if non-null. */\n\tif (duk_debug_peek_byte(thr) == DUK_DBG_IB_NULL) {\n\t\tdirect_eval = 0;\n\t\tlevel = -1;  /* Not needed, but silences warning. */\n\t\t(void) duk_debug_read_byte(thr);\n\t} else {\n\t\tdirect_eval = 1;\n\t\tlevel = duk__debug_read_validate_csindex(thr);\n\t\tif (level == 0) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\tDUK_ASSERT(!direct_eval ||\n\t           (level < 0 && -level <= (duk_int32_t) thr->callstack_top));\n\n\t(void) duk_debug_read_hstring(thr);\n\tif (direct_eval) {\n\t\tduk_push_int(thr, level - 1);  /* compensate for eval() call */\n\t}\n\n\t/* [ ... eval \"eval\" eval_input level? ] */\n\n\tcall_flags = 0;\n\tif (direct_eval) {\n\t\tduk_activation *act;\n\t\tduk_hobject *fun;\n\n\t\tact = duk_hthread_get_activation_for_level(thr, level);\n\t\tif (act != NULL) {\n\t\t\tfun = DUK_ACT_GET_FUNC(act);\n\t\t\tif (fun != NULL && DUK_HOBJECT_IS_COMPFUNC(fun)) {\n\t\t\t\t/* Direct eval requires that there's a current\n\t\t\t\t * activation and it is an ECMAScript function.\n\t\t\t\t * When Eval is executed from e.g. cooperate API\n\t\t\t\t * call we'll need to do an indirect eval instead.\n\t\t\t\t */\n\t\t\t\tcall_flags |= DUK_CALL_FLAG_DIRECT_EVAL;\n\t\t\t}\n\t\t}\n\t}\n\n\tcall_ret = duk_pcall_method_flags(thr, duk_get_top(thr) - (idx_func + 2), call_flags);\n\n\tif (call_ret == DUK_EXEC_SUCCESS) {\n\t\teval_err = 0;\n\t\t/* Use result value as is. */\n\t} else {\n\t\t/* For errors a string coerced result is most informative\n\t\t * right now, as the debug client doesn't have the capability\n\t\t * to traverse the error object.\n\t\t */\n\t\teval_err = 1;\n\t\tduk_safe_to_string(thr, -1);\n\t}\n\n\t/* [ ... result ] */\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_int(thr, (duk_int32_t) eval_err);\n\tDUK_ASSERT(duk_get_tval(thr, -1) != NULL);\n\tduk_debug_write_tval(thr, duk_get_tval(thr, -1));\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_detach(duk_hthread *thr, duk_heap *heap) {\n\tDUK_UNREF(heap);\n\tDUK_D(DUK_DPRINT(\"debug command Detach\"));\n\n\tduk_debug_write_reply(thr);\n\tduk_debug_write_eom(thr);\n\n\tDUK_D(DUK_DPRINT(\"debug connection detached, mark broken\"));\n\tDUK__SET_CONN_BROKEN(thr, 0);  /* not an error */\n}\n\nDUK_LOCAL void duk__debug_handle_apprequest(duk_hthread *thr, duk_heap *heap) {\n\tduk_idx_t old_top;\n\n\tDUK_D(DUK_DPRINT(\"debug command AppRequest\"));\n\n\told_top = duk_get_top(thr);  /* save stack top */\n\n\tif (heap->dbg_request_cb != NULL) {\n\t\tduk_idx_t nrets;\n\t\tduk_idx_t nvalues = 0;\n\t\tduk_idx_t top, idx;\n\n\t\t/* Read tvals from the message and push them onto the valstack,\n\t\t * then call the request callback to process the request.\n\t\t */\n\t\twhile (duk_debug_peek_byte(thr) != DUK_DBG_IB_EOM) {\n\t\t\tduk_tval *tv;\n\t\t\tif (!duk_check_stack(thr, 1)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"failed to allocate space for request dvalue(s)\"));\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\ttv = duk_debug_read_tval(thr);  /* push to stack */\n\t\t\tif (tv == NULL) {\n\t\t\t\t/* detached */\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tnvalues++;\n\t\t}\n\t\tDUK_ASSERT(duk_get_top(thr) == old_top + nvalues);\n\n\t\t/* Request callback should push values for reply to client onto valstack */\n\t\tDUK_D(DUK_DPRINT(\"calling into AppRequest request_cb with nvalues=%ld, old_top=%ld, top=%ld\",\n\t\t                 (long) nvalues, (long) old_top, (long) duk_get_top(thr)));\n\t\tnrets = heap->dbg_request_cb(thr, heap->dbg_udata, nvalues);\n\t\tDUK_D(DUK_DPRINT(\"returned from AppRequest request_cb; nvalues=%ld -> nrets=%ld, old_top=%ld, top=%ld\",\n\t\t                 (long) nvalues, (long) nrets, (long) old_top, (long) duk_get_top(thr)));\n\t\tif (nrets >= 0) {\n\t\t\tDUK_ASSERT(duk_get_top(thr) >= old_top + nrets);\n\t\t\tif (duk_get_top(thr) < old_top + nrets) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"AppRequest callback doesn't match value stack configuration, \"\n\t\t\t\t                 \"top=%ld < old_top=%ld + nrets=%ld; \"\n\t\t\t\t                 \"this might mean it's unsafe to continue!\",\n\t\t\t\t                 (long) duk_get_top(thr), (long) old_top, (long) nrets));\n\t\t\t\tgoto fail;\n\t\t\t}\n\n\t\t\t/* Reply with tvals pushed by request callback */\n\t\t\tduk_debug_write_byte(thr, DUK_DBG_IB_REPLY);\n\t\t\ttop = duk_get_top(thr);\n\t\t\tfor (idx = top - nrets; idx < top; idx++) {\n\t\t\t\tduk_debug_write_tval(thr, DUK_GET_TVAL_POSIDX(thr, idx));\n\t\t\t}\n\t\t\tduk_debug_write_eom(thr);\n\t\t} else {\n\t\t\tDUK_ASSERT(duk_get_top(thr) >= old_top + 1);\n\t\t\tif (duk_get_top(thr) < old_top + 1) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"request callback return value doesn't match value stack configuration\"));\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_APPLICATION, duk_get_string(thr, -1));\n\t\t}\n\n\t\tduk_set_top(thr, old_top);  /* restore stack top */\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"no request callback, treat AppRequest as unsupported\"));\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNSUPPORTED, \"AppRequest unsupported by target\");\n\t}\n\n\treturn;\n\n fail:\n\tduk_set_top(thr, old_top);  /* restore stack top */\n\tDUK__SET_CONN_BROKEN(thr, 1);\n}\n\n/*\n *  DumpHeap command\n */\n\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP)\n/* XXX: this has some overlap with object inspection; remove this and make\n * DumpHeap return lists of heapptrs instead?\n */\nDUK_LOCAL void duk__debug_dump_heaphdr(duk_hthread *thr, duk_heap *heap, duk_heaphdr *hdr) {\n\tDUK_UNREF(heap);\n\n\tduk_debug_write_heapptr(thr, hdr);\n\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HEAPHDR_GET_TYPE(hdr));\n\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HEAPHDR_GET_FLAGS_RAW(hdr));\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HEAPHDR_GET_REFCOUNT(hdr));\n#else\n\tduk_debug_write_int(thr, (duk_int32_t) -1);\n#endif\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(hdr)) {\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h = (duk_hstring *) hdr;\n\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_BYTELEN(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_CHARLEN(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HSTRING_GET_HASH(h));\n\t\tduk_debug_write_hstring(thr, h);\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h = (duk_hobject *) hdr;\n\t\tduk_hstring *k;\n\t\tduk_uint_fast32_t i;\n\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_CLASS_NUMBER(h));\n\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(heap, h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_ESIZE(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_ENEXT(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_ASIZE(h));\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_GET_HSIZE(h));\n\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HOBJECT_E_GET_FLAGS(heap, h, i));\n\t\t\tk = DUK_HOBJECT_E_GET_KEY(heap, h, i);\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) k);\n\t\t\tif (k == NULL) {\n\t\t\t\tduk_debug_write_int(thr, 0);  /* isAccessor */\n\t\t\t\tduk_debug_write_unused(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)) {\n\t\t\t\tduk_debug_write_int(thr, 1);  /* isAccessor */\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.get);\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.set);\n\t\t\t} else {\n\t\t\t\tduk_debug_write_int(thr, 0);  /* isAccessor */\n\n\t\t\t\tduk__debug_write_tval_heapptr(thr, &DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->v);\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(h); i++) {\n\t\t\t/* Note: array dump will include elements beyond\n\t\t\t * 'length'.\n\t\t\t */\n\t\t\tduk__debug_write_tval_heapptr(thr, DUK_HOBJECT_A_GET_VALUE_PTR(heap, h, i));\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h = (duk_hbuffer *) hdr;\n\n\t\tduk_debug_write_uint(thr, (duk_uint32_t) DUK_HBUFFER_GET_SIZE(h));\n\t\tduk_debug_write_buffer(thr, (const char *) DUK_HBUFFER_GET_DATA_PTR(heap, h), (duk_size_t) DUK_HBUFFER_GET_SIZE(h));\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tDUK_D(DUK_DPRINT(\"invalid htype: %d\", (int) DUK_HEAPHDR_GET_TYPE(hdr)));\n\t}\n\t}\n}\n\nDUK_LOCAL void duk__debug_dump_heap_allocated(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\n\thdr = heap->heap_allocated;\n\twhile (hdr != NULL) {\n\t\tduk__debug_dump_heaphdr(thr, heap, hdr);\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n}\n\nDUK_LOCAL void duk__debug_dump_strtab(duk_hthread *thr, duk_heap *heap) {\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\n\tfor (i = 0; i < heap->st_size; i++) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\th = DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, heap->strtable16[i]);\n#else\n\t\th = heap->strtable[i];\n#endif\n\t\twhile (h != NULL) {\n\t\t\tduk__debug_dump_heaphdr(thr, heap, (duk_heaphdr *) h);\n\t\t\th = h->hdr.h_next;\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__debug_handle_dump_heap(duk_hthread *thr, duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"debug command DumpHeap\"));\n\n\tduk_debug_write_reply(thr);\n\tduk__debug_dump_heap_allocated(thr, heap);\n\tduk__debug_dump_strtab(thr, heap);\n\tduk_debug_write_eom(thr);\n}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP */\n\nDUK_LOCAL void duk__debug_handle_get_bytecode(duk_hthread *thr, duk_heap *heap) {\n\tduk_activation *act;\n\tduk_hcompfunc *fun = NULL;\n\tduk_size_t i, n;\n\tduk_tval *tv;\n\tduk_hobject **fn;\n\tduk_int32_t level = -1;\n\tduk_uint8_t ibyte;\n\n\tDUK_UNREF(heap);\n\n\tDUK_D(DUK_DPRINT(\"debug command GetBytecode\"));\n\n\tibyte = duk_debug_peek_byte(thr);\n\tif (ibyte != DUK_DBG_IB_EOM) {\n\t\ttv = duk_debug_read_tval(thr);\n\t\tif (tv == NULL) {\n\t\t\t/* detached */\n\t\t\treturn;\n\t\t}\n\t\tif (DUK_TVAL_IS_OBJECT(tv)) {\n\t\t\t/* tentative, checked later */\n\t\t\tfun = (duk_hcompfunc *) DUK_TVAL_GET_OBJECT(tv);\n\t\t\tDUK_ASSERT(fun != NULL);\n\t\t} else if (DUK_TVAL_IS_NUMBER(tv)) {\n\t\t\tlevel = (duk_int32_t) DUK_TVAL_GET_NUMBER(tv);\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"invalid argument to GetBytecode: %!T\", tv));\n\t\t\tgoto fail_args;\n\t\t}\n\t}\n\n\tif (fun == NULL) {\n\t\tact = duk_hthread_get_activation_for_level(thr, level);\n\t\tif (act == NULL) {\n\t\t\tgoto fail_index;\n\t\t}\n\t\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\t}\n\n\tif (fun == NULL || !DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun)) {\n\t\tDUK_D(DUK_DPRINT(\"invalid argument to GetBytecode: %!O\", fun));\n\t\tgoto fail_args;\n\t}\n\tDUK_ASSERT(fun != NULL && DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun));\n\n\tduk_debug_write_reply(thr);\n\tn = DUK_HCOMPFUNC_GET_CONSTS_COUNT(heap, fun);\n\tduk_debug_write_int(thr, (duk_int32_t) n);\n\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, fun);\n\tfor (i = 0; i < n; i++) {\n\t\tduk_debug_write_tval(thr, tv);\n\t\ttv++;\n\t}\n\tn = DUK_HCOMPFUNC_GET_FUNCS_COUNT(heap, fun);\n\tduk_debug_write_int(thr, (duk_int32_t) n);\n\tfn = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, fun);\n\tfor (i = 0; i < n; i++) {\n\t\tduk_debug_write_hobject(thr, *fn);\n\t\tfn++;\n\t}\n\tduk_debug_write_string(thr,\n\t                       (const char *) DUK_HCOMPFUNC_GET_CODE_BASE(heap, fun),\n\t                       (duk_size_t) DUK_HCOMPFUNC_GET_CODE_SIZE(heap, fun));\n\tduk_debug_write_eom(thr);\n\treturn;\n\n fail_args:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid argument\");\n\treturn;\n\n fail_index:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"invalid callstack index\");\n\treturn;\n}\n\n/*\n *  Object inspection commands: GetHeapObjInfo, GetObjPropDesc,\n *  GetObjPropDescRange\n */\n\n#if defined(DUK_USE_DEBUGGER_INSPECT)\n\n#if 0 /* pruned */\nDUK_LOCAL const char * const duk__debug_getinfo_heaphdr_keys[] = {\n\t\"reachable\",\n\t\"temproot\",\n\t\"finalizable\",\n\t\"finalized\",\n\t\"readonly\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_heaphdr_masks[] = {\n\tDUK_HEAPHDR_FLAG_REACHABLE,\n\tDUK_HEAPHDR_FLAG_TEMPROOT,\n\tDUK_HEAPHDR_FLAG_FINALIZABLE,\n\tDUK_HEAPHDR_FLAG_FINALIZED,\n\tDUK_HEAPHDR_FLAG_READONLY,\n\t0  /* terminator */\n};\n#endif\nDUK_LOCAL const char * const duk__debug_getinfo_hstring_keys[] = {\n#if 0\n\t\"arridx\",\n\t\"symbol\",\n\t\"hidden\",\n\t\"reserved_word\",\n\t\"strict_reserved_word\",\n\t\"eval_or_arguments\",\n#endif\n\t\"extdata\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_hstring_masks[] = {\n#if 0\n\tDUK_HSTRING_FLAG_ARRIDX,\n\tDUK_HSTRING_FLAG_SYMBOL,\n\tDUK_HSTRING_FLAG_HIDDEN,\n\tDUK_HSTRING_FLAG_RESERVED_WORD,\n\tDUK_HSTRING_FLAG_STRICT_RESERVED_WORD,\n\tDUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS,\n#endif\n\tDUK_HSTRING_FLAG_EXTDATA,\n\t0  /* terminator */\n};\nDUK_LOCAL const char * const duk__debug_getinfo_hobject_keys[] = {\n\t\"extensible\",\n\t\"constructable\",\n\t\"callable\",\n\t\"boundfunc\",\n\t\"compfunc\",\n\t\"natfunc\",\n\t\"bufobj\",\n\t\"fastrefs\",\n\t\"array_part\",\n\t\"strict\",\n\t\"notail\",\n\t\"newenv\",\n\t\"namebinding\",\n\t\"createargs\",\n\t\"have_finalizer\",\n\t\"exotic_array\",\n\t\"exotic_stringobj\",\n\t\"exotic_arguments\",\n\t\"exotic_proxyobj\",\n\t\"special_call\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_hobject_masks[] = {\n\tDUK_HOBJECT_FLAG_EXTENSIBLE,\n\tDUK_HOBJECT_FLAG_CONSTRUCTABLE,\n\tDUK_HOBJECT_FLAG_CALLABLE,\n\tDUK_HOBJECT_FLAG_BOUNDFUNC,\n\tDUK_HOBJECT_FLAG_COMPFUNC,\n\tDUK_HOBJECT_FLAG_NATFUNC,\n\tDUK_HOBJECT_FLAG_BUFOBJ,\n\tDUK_HOBJECT_FLAG_FASTREFS,\n\tDUK_HOBJECT_FLAG_ARRAY_PART,\n\tDUK_HOBJECT_FLAG_STRICT,\n\tDUK_HOBJECT_FLAG_NOTAIL,\n\tDUK_HOBJECT_FLAG_NEWENV,\n\tDUK_HOBJECT_FLAG_NAMEBINDING,\n\tDUK_HOBJECT_FLAG_CREATEARGS,\n\tDUK_HOBJECT_FLAG_HAVE_FINALIZER,\n\tDUK_HOBJECT_FLAG_EXOTIC_ARRAY,\n\tDUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ,\n\tDUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS,\n\tDUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ,\n\tDUK_HOBJECT_FLAG_SPECIAL_CALL,\n\t0  /* terminator */\n};\nDUK_LOCAL const char * const duk__debug_getinfo_hbuffer_keys[] = {\n\t\"dynamic\",\n\t\"external\"\n\t/* NULL not needed here */\n};\nDUK_LOCAL duk_uint_t duk__debug_getinfo_hbuffer_masks[] = {\n\tDUK_HBUFFER_FLAG_DYNAMIC,\n\tDUK_HBUFFER_FLAG_EXTERNAL,\n\t0  /* terminator */\n};\n\nDUK_LOCAL void duk__debug_getinfo_flags_key(duk_hthread *thr, const char *key) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n}\n\nDUK_LOCAL void duk__debug_getinfo_prop_uint(duk_hthread *thr, const char *key, duk_uint_t val) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n\tduk_debug_write_uint(thr, val);\n}\n\nDUK_LOCAL void duk__debug_getinfo_prop_int(duk_hthread *thr, const char *key, duk_int_t val) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n\tduk_debug_write_int(thr, val);\n}\n\nDUK_LOCAL void duk__debug_getinfo_prop_bool(duk_hthread *thr, const char *key, duk_bool_t val) {\n\tduk_debug_write_uint(thr, 0);\n\tduk_debug_write_cstring(thr, key);\n\tduk_debug_write_boolean(thr, val);\n}\n\nDUK_LOCAL void duk__debug_getinfo_bitmask(duk_hthread *thr, const char * const * keys, duk_uint_t *masks, duk_uint_t flags) {\n\tconst char *key;\n\tduk_uint_t mask;\n\n\tfor (;;) {\n\t\tmask = *masks++;\n\t\tif (mask == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tkey = *keys++;\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tDUK_DD(DUK_DDPRINT(\"inspect bitmask: key=%s, mask=0x%08lx, flags=0x%08lx\", key, (unsigned long) mask, (unsigned long) flags));\n\t\tduk__debug_getinfo_prop_bool(thr, key, flags & mask);\n\t}\n}\n\n/* Inspect a property using a virtual index into a conceptual property list\n * consisting of (1) all array part items from [0,a_size[ (even when above\n * .length) and (2) all entry part items from [0,e_next[.  Unused slots are\n * indicated using dvalue 'unused'.\n */\nDUK_LOCAL duk_bool_t duk__debug_getprop_index(duk_hthread *thr, duk_heap *heap, duk_hobject *h_obj, duk_uint_t idx) {\n\tduk_uint_t a_size;\n\tduk_tval *tv;\n\tduk_hstring *h_key;\n\tduk_hobject *h_getset;\n\tduk_uint_t flags;\n\n\tDUK_UNREF(heap);\n\n\ta_size = DUK_HOBJECT_GET_ASIZE(h_obj);\n\tif (idx < a_size) {\n\t\tduk_debug_write_uint(thr, DUK_PROPDESC_FLAGS_WEC);\n\t\tduk_debug_write_uint(thr, idx);\n\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(heap, h_obj, idx);\n\t\tduk_debug_write_tval(thr, tv);\n\t\treturn 1;\n\t}\n\n\tidx -= a_size;\n\tif (idx >= DUK_HOBJECT_GET_ENEXT(h_obj)) {\n\t\treturn 0;\n\t}\n\n\th_key = DUK_HOBJECT_E_GET_KEY(heap, h_obj, idx);\n\tif (h_key == NULL) {\n\t\tduk_debug_write_uint(thr, 0);\n\t\tduk_debug_write_null(thr);\n\t\tduk_debug_write_unused(thr);\n\t\treturn 1;\n\t}\n\n\tflags = DUK_HOBJECT_E_GET_FLAGS(heap, h_obj, idx);\n\tif (DUK_HSTRING_HAS_SYMBOL(h_key)) {\n\t\tflags |= DUK_DBG_PROPFLAG_SYMBOL;\n\t}\n\tif (DUK_HSTRING_HAS_HIDDEN(h_key)) {\n\t\tflags |= DUK_DBG_PROPFLAG_HIDDEN;\n\t}\n\tduk_debug_write_uint(thr, flags);\n\tduk_debug_write_hstring(thr, h_key);\n\tif (flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\th_getset = DUK_HOBJECT_E_GET_VALUE_GETTER(heap, h_obj, idx);\n\t\tif (h_getset) {\n\t\t\tduk_debug_write_hobject(thr, h_getset);\n\t\t} else {\n\t\t\tduk_debug_write_null(thr);\n\t\t}\n\t\th_getset = DUK_HOBJECT_E_GET_VALUE_SETTER(heap, h_obj, idx);\n\t\tif (h_getset) {\n\t\t\tduk_debug_write_hobject(thr, h_getset);\n\t\t} else {\n\t\t\tduk_debug_write_null(thr);\n\t\t}\n\t} else {\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, h_obj, idx);\n\t\tduk_debug_write_tval(thr, tv);\n\t}\n\treturn 1;\n}\n\nDUK_LOCAL void duk__debug_handle_get_heap_obj_info(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *h;\n\n\tDUK_D(DUK_DPRINT(\"debug command GetHeapObjInfo\"));\n\tDUK_UNREF(heap);\n\n\tDUK_ASSERT(sizeof(duk__debug_getinfo_hstring_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hstring_masks) / sizeof(duk_uint_t) - 1);\n\tDUK_ASSERT(sizeof(duk__debug_getinfo_hobject_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hobject_masks) / sizeof(duk_uint_t) - 1);\n\tDUK_ASSERT(sizeof(duk__debug_getinfo_hbuffer_keys) / sizeof(const char *) == sizeof(duk__debug_getinfo_hbuffer_masks) / sizeof(duk_uint_t) - 1);\n\n\th = duk_debug_read_any_ptr(thr);\n\tif (!h) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid target\");\n\t\treturn;\n\t}\n\n\tduk_debug_write_reply(thr);\n\n\t/* As with all inspection code, we rely on the debug client providing\n\t * a valid, non-stale pointer: there's no portable way to safely\n\t * validate the pointer here.\n\t */\n\n\tduk__debug_getinfo_flags_key(thr, \"heapptr\");\n\tduk_debug_write_heapptr(thr, h);\n\n\t/* XXX: comes out as signed now */\n\tduk__debug_getinfo_prop_uint(thr, \"heaphdr_flags\", (duk_uint_t) DUK_HEAPHDR_GET_FLAGS(h));\n\tduk__debug_getinfo_prop_uint(thr, \"heaphdr_type\", (duk_uint_t) DUK_HEAPHDR_GET_TYPE(h));\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__debug_getinfo_prop_uint(thr, \"refcount\", (duk_uint_t) DUK_HEAPHDR_GET_REFCOUNT(h));\n#endif\n#if 0 /* pruned */\n\tduk__debug_getinfo_bitmask(thr,\n\t                           duk__debug_getinfo_heaphdr_keys,\n\t                           duk__debug_getinfo_heaphdr_masks,\n\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n#endif\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h_str;\n\n\t\th_str = (duk_hstring *) h;\n\t\tduk__debug_getinfo_bitmask(thr,\n\t\t                           duk__debug_getinfo_hstring_keys,\n\t\t                           duk__debug_getinfo_hstring_masks,\n\t\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n\t\tduk__debug_getinfo_prop_uint(thr, \"bytelen\", (duk_uint_t) DUK_HSTRING_GET_BYTELEN(h_str));\n\t\tduk__debug_getinfo_prop_uint(thr, \"charlen\", (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h_str));\n\t\tduk__debug_getinfo_prop_uint(thr, \"hash\", (duk_uint_t) DUK_HSTRING_GET_HASH(h_str));\n\t\tduk__debug_getinfo_flags_key(thr, \"data\");\n\t\tduk_debug_write_hstring(thr, h_str);\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h_obj;\n\t\tduk_hobject *h_proto;\n\n\t\th_obj = (duk_hobject *) h;\n\t\th_proto = DUK_HOBJECT_GET_PROTOTYPE(heap, h_obj);\n\n\t\t/* duk_hobject specific fields. */\n\t\tduk__debug_getinfo_bitmask(thr,\n\t\t                           duk__debug_getinfo_hobject_keys,\n\t\t                           duk__debug_getinfo_hobject_masks,\n\t\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n\t\tduk__debug_getinfo_prop_uint(thr, \"class_number\", DUK_HOBJECT_GET_CLASS_NUMBER(h_obj));\n\t\tduk__debug_getinfo_flags_key(thr, \"class_name\");\n\t\tduk_debug_write_hstring(thr, DUK_HOBJECT_GET_CLASS_STRING(heap, h_obj));\n\t\tduk__debug_getinfo_flags_key(thr, \"prototype\");\n\t\tif (h_proto != NULL) {\n\t\t\tduk_debug_write_hobject(thr, h_proto);\n\t\t} else {\n\t\t\tduk_debug_write_null(thr);\n\t\t}\n\t\tduk__debug_getinfo_flags_key(thr, \"props\");\n\t\tduk_debug_write_pointer(thr, (void *) DUK_HOBJECT_GET_PROPS(heap, h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"e_size\", (duk_uint_t) DUK_HOBJECT_GET_ESIZE(h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"e_next\", (duk_uint_t) DUK_HOBJECT_GET_ENEXT(h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"a_size\", (duk_uint_t) DUK_HOBJECT_GET_ASIZE(h_obj));\n\t\tduk__debug_getinfo_prop_uint(thr, \"h_size\", (duk_uint_t) DUK_HOBJECT_GET_HSIZE(h_obj));\n\n\t\tif (DUK_HOBJECT_IS_ARRAY(h_obj)) {\n\t\t\tduk_harray *h_arr;\n\t\t\th_arr = (duk_harray *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"length\", (duk_uint_t) h_arr->length);\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"length_nonwritable\", h_arr->length_nonwritable);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_NATFUNC(h_obj)) {\n\t\t\tduk_hnatfunc *h_fun;\n\t\t\th_fun = (duk_hnatfunc *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_int(thr, \"nargs\", h_fun->nargs);\n\t\t\tduk__debug_getinfo_prop_int(thr, \"magic\", h_fun->magic);\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"varargs\", h_fun->magic == DUK_HNATFUNC_NARGS_VARARGS);\n\t\t\t/* Native function pointer may be different from a void pointer,\n\t\t\t * and we serialize it from memory directly now (no byte swapping etc).\n\t\t\t */\n\t\t\tduk__debug_getinfo_flags_key(thr, \"funcptr\");\n\t\t\tduk_debug_write_buffer(thr, (const char *) &h_fun->func, sizeof(h_fun->func));\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tduk_hcompfunc *h_fun;\n\t\t\tduk_hbuffer *h_buf;\n\t\t\tduk_hobject *h_lexenv;\n\t\t\tduk_hobject *h_varenv;\n\t\t\th_fun = (duk_hcompfunc *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_int(thr, \"nregs\", h_fun->nregs);\n\t\t\tduk__debug_getinfo_prop_int(thr, \"nargs\", h_fun->nargs);\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"lex_env\");\n\t\t\th_lexenv = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, h_fun);\n\t\t\tif (h_lexenv != NULL) {\n\t\t\t\tduk_debug_write_hobject(thr, h_lexenv);\n\t\t\t} else {\n\t\t\t\tduk_debug_write_null(thr);\n\t\t\t}\n\t\t\tduk__debug_getinfo_flags_key(thr, \"var_env\");\n\t\t\th_varenv = DUK_HCOMPFUNC_GET_VARENV(thr->heap, h_fun);\n\t\t\tif (h_varenv != NULL) {\n\t\t\t\tduk_debug_write_hobject(thr, h_varenv);\n\t\t\t} else {\n\t\t\t\tduk_debug_write_null(thr);\n\t\t\t}\n\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"start_line\", h_fun->start_line);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"end_line\", h_fun->end_line);\n\t\t\th_buf = (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(thr->heap, h_fun);\n\t\t\tif (h_buf != NULL) {\n\t\t\t\tduk__debug_getinfo_flags_key(thr, \"data\");\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) h_buf);\n\t\t\t}\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_BOUNDFUNC(h_obj)) {\n\t\t\tduk_hboundfunc *h_bfun;\n\t\t\th_bfun = (duk_hboundfunc *) (void *) h_obj;\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"target\");\n\t\t\tduk_debug_write_tval(thr, &h_bfun->target);\n\t\t\tduk__debug_getinfo_flags_key(thr, \"this_binding\");\n\t\t\tduk_debug_write_tval(thr, &h_bfun->this_binding);\n\t\t\tduk__debug_getinfo_flags_key(thr, \"nargs\");\n\t\t\tduk_debug_write_int(thr, h_bfun->nargs);\n\t\t\t/* h_bfun->args not exposed now */\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_THREAD(h_obj)) {\n\t\t\t/* XXX: Currently no inspection of threads, e.g. value stack, call\n\t\t\t * stack, catch stack, etc.\n\t\t\t */\n\t\t\tduk_hthread *h_thr;\n\t\t\th_thr = (duk_hthread *) h_obj;\n\t\t\tDUK_UNREF(h_thr);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_DECENV(h_obj)) {\n\t\t\tduk_hdecenv *h_env;\n\t\t\th_env = (duk_hdecenv *) h_obj;\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"thread\");\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->thread));\n\t\t\tduk__debug_getinfo_flags_key(thr, \"varmap\");\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->varmap));\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"regbase\", (duk_uint_t) h_env->regbase_byteoff);\n\t\t}\n\n\t\tif (DUK_HOBJECT_IS_OBJENV(h_obj)) {\n\t\t\tduk_hobjenv *h_env;\n\t\t\th_env = (duk_hobjenv *) h_obj;\n\n\t\t\tduk__debug_getinfo_flags_key(thr, \"target\");\n\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) (h_env->target));\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"has_this\", h_env->has_this);\n\t\t}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n\t\t\tduk_hbufobj *h_bufobj;\n\t\t\th_bufobj = (duk_hbufobj *) h_obj;\n\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"slice_offset\", h_bufobj->offset);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"slice_length\", h_bufobj->length);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"elem_shift\", (duk_uint_t) h_bufobj->shift);\n\t\t\tduk__debug_getinfo_prop_uint(thr, \"elem_type\", (duk_uint_t) h_bufobj->elem_type);\n\t\t\tduk__debug_getinfo_prop_bool(thr, \"is_typedarray\", (duk_uint_t) h_bufobj->is_typedarray);\n\t\t\tif (h_bufobj->buf != NULL) {\n\t\t\t\tduk__debug_getinfo_flags_key(thr, \"buffer\");\n\t\t\t\tduk_debug_write_heapptr(thr, (duk_heaphdr *) h_bufobj->buf);\n\t\t\t}\n\t\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h_buf;\n\n\t\th_buf = (duk_hbuffer *) h;\n\t\tduk__debug_getinfo_bitmask(thr,\n\t\t                           duk__debug_getinfo_hbuffer_keys,\n\t\t                           duk__debug_getinfo_hbuffer_masks,\n\t\t                           DUK_HEAPHDR_GET_FLAGS_RAW(h));\n\t\tduk__debug_getinfo_prop_uint(thr, \"size\", (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_buf));\n\t\tduk__debug_getinfo_flags_key(thr, \"dataptr\");\n\t\tduk_debug_write_pointer(thr, (void *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_buf));\n\t\tduk__debug_getinfo_flags_key(thr, \"data\");\n\t\tduk_debug_write_hbuffer(thr, h_buf);  /* tolerates NULL h_buf */\n\t\tbreak;\n\t}\n\tdefault: {\n\t\t/* Since we already started writing the reply, just emit nothing. */\n\t\tDUK_D(DUK_DPRINT(\"inspect target pointer has invalid heaphdr type\"));\n\t}\n\t}\n\n\tduk_debug_write_eom(thr);\n}\n\nDUK_LOCAL void duk__debug_handle_get_obj_prop_desc(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *h;\n\tduk_hobject *h_obj;\n\tduk_hstring *h_key;\n\tduk_propdesc desc;\n\n\tDUK_D(DUK_DPRINT(\"debug command GetObjPropDesc\"));\n\tDUK_UNREF(heap);\n\n\th = duk_debug_read_any_ptr(thr);\n\tif (!h) {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid target\");\n\t\treturn;\n\t}\n\th_key = duk_debug_read_hstring(thr);\n\tif (h == NULL || DUK_HEAPHDR_GET_TYPE(h) != DUK_HTYPE_OBJECT || h_key == NULL) {\n\t\tgoto fail_args;\n\t}\n\th_obj = (duk_hobject *) h;\n\n\tif (duk_hobject_get_own_propdesc(thr, h_obj, h_key, &desc, 0 /*flags*/)) {\n\t\tduk_int_t virtual_idx;\n\t\tduk_bool_t rc;\n\n\t\t/* To use the shared helper need the virtual index. */\n\t\tDUK_ASSERT(desc.e_idx >= 0 || desc.a_idx >= 0);\n\t\tvirtual_idx = (desc.a_idx >= 0 ? desc.a_idx :\n\t\t               (duk_int_t) DUK_HOBJECT_GET_ASIZE(h_obj) + desc.e_idx);\n\n\t\tduk_debug_write_reply(thr);\n\t\trc = duk__debug_getprop_index(thr, heap, h_obj, (duk_uint_t) virtual_idx);\n\t\tDUK_ASSERT(rc == 1);\n\t\tDUK_UNREF(rc);\n\t\tduk_debug_write_eom(thr);\n\t} else {\n\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_NOTFOUND, \"not found\");\n\t}\n\treturn;\n\n fail_args:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid args\");\n}\n\nDUK_LOCAL void duk__debug_handle_get_obj_prop_desc_range(duk_hthread *thr, duk_heap *heap) {\n\tduk_heaphdr *h;\n\tduk_hobject *h_obj;\n\tduk_uint_t idx, idx_start, idx_end;\n\n\tDUK_D(DUK_DPRINT(\"debug command GetObjPropDescRange\"));\n\tDUK_UNREF(heap);\n\n\th = duk_debug_read_any_ptr(thr);\n\tidx_start = (duk_uint_t) duk_debug_read_int(thr);\n\tidx_end = (duk_uint_t) duk_debug_read_int(thr);\n\tif (h == NULL || DUK_HEAPHDR_GET_TYPE(h) != DUK_HTYPE_OBJECT) {\n\t\tgoto fail_args;\n\t}\n\th_obj = (duk_hobject *) h;\n\n\t/* The index range space is conceptually the array part followed by the\n\t * entry part.  Unlike normal enumeration all slots are exposed here as\n\t * is and return 'unused' if the slots are not in active use.  In particular\n\t * the array part is included for the full a_size regardless of what the\n\t * array .length is.\n\t */\n\n\tduk_debug_write_reply(thr);\n\tfor (idx = idx_start; idx < idx_end; idx++) {\n\t\tif (!duk__debug_getprop_index(thr, heap, h_obj, idx)) {\n\t\t\tbreak;\n\t\t}\n\t}\n\tduk_debug_write_eom(thr);\n\treturn;\n\n fail_args:\n\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNKNOWN, \"invalid args\");\n}\n\n#endif  /* DUK_USE_DEBUGGER_INSPECT */\n\n/*\n *  Process incoming debug requests\n *\n *  Individual request handlers can push temporaries on the value stack and\n *  rely on duk__debug_process_message() to restore the value stack top\n *  automatically.\n */\n\n/* Process one debug message.  Automatically restore value stack top to its\n * entry value, so that individual message handlers don't need exact value\n * stack handling which is convenient.\n */\nDUK_LOCAL void duk__debug_process_message(duk_hthread *thr) {\n\tduk_heap *heap;\n\tduk_uint8_t x;\n\tduk_int32_t cmd;\n\tduk_idx_t entry_top;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tentry_top = duk_get_top(thr);\n\n\tx = duk_debug_read_byte(thr);\n\tswitch (x) {\n\tcase DUK_DBG_IB_REQUEST: {\n\t\tcmd = duk_debug_read_int(thr);\n\t\tswitch (cmd) {\n\t\tcase DUK_DBG_CMD_BASICINFO: {\n\t\t\tduk__debug_handle_basic_info(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_TRIGGERSTATUS: {\n\t\t\tduk__debug_handle_trigger_status(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_PAUSE: {\n\t\t\tduk__debug_handle_pause(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_RESUME: {\n\t\t\tduk__debug_handle_resume(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_STEPINTO:\n\t\tcase DUK_DBG_CMD_STEPOVER:\n\t\tcase DUK_DBG_CMD_STEPOUT: {\n\t\t\tduk__debug_handle_step(thr, heap, cmd);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_LISTBREAK: {\n\t\t\tduk__debug_handle_list_break(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_ADDBREAK: {\n\t\t\tduk__debug_handle_add_break(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_DELBREAK: {\n\t\t\tduk__debug_handle_del_break(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETVAR: {\n\t\t\tduk__debug_handle_get_var(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_PUTVAR: {\n\t\t\tduk__debug_handle_put_var(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETCALLSTACK: {\n\t\t\tduk__debug_handle_get_call_stack(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETLOCALS: {\n\t\t\tduk__debug_handle_get_locals(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_EVAL: {\n\t\t\tduk__debug_handle_eval(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_DETACH: {\n\t\t\t/* The actual detached_cb call is postponed to message loop so\n\t\t\t * we don't need any special precautions here (just skip to EOM\n\t\t\t * on the already closed connection).\n\t\t\t */\n\t\t\tduk__debug_handle_detach(thr, heap);\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP)\n\t\tcase DUK_DBG_CMD_DUMPHEAP: {\n\t\t\tduk__debug_handle_dump_heap(thr, heap);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_DEBUGGER_DUMPHEAP */\n\t\tcase DUK_DBG_CMD_GETBYTECODE: {\n\t\t\tduk__debug_handle_get_bytecode(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_APPREQUEST: {\n\t\t\tduk__debug_handle_apprequest(thr, heap);\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_DEBUGGER_INSPECT)\n\t\tcase DUK_DBG_CMD_GETHEAPOBJINFO: {\n\t\t\tduk__debug_handle_get_heap_obj_info(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETOBJPROPDESC: {\n\t\t\tduk__debug_handle_get_obj_prop_desc(thr, heap);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_DBG_CMD_GETOBJPROPDESCRANGE: {\n\t\t\tduk__debug_handle_get_obj_prop_desc_range(thr, heap);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_DEBUGGER_INSPECT */\n\t\tdefault: {\n\t\t\tDUK_D(DUK_DPRINT(\"debug command unsupported: %d\", (int) cmd));\n\t\t\tduk_debug_write_error_eom(thr, DUK_DBG_ERR_UNSUPPORTED, \"unsupported command\");\n\t\t}\n\t\t}  /* switch cmd */\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_REPLY: {\n\t\tDUK_D(DUK_DPRINT(\"debug reply, skipping\"));\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_ERROR: {\n\t\tDUK_D(DUK_DPRINT(\"debug error, skipping\"));\n\t\tbreak;\n\t}\n\tcase DUK_DBG_IB_NOTIFY: {\n\t\tDUK_D(DUK_DPRINT(\"debug notify, skipping\"));\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tDUK_D(DUK_DPRINT(\"invalid initial byte, drop connection: %d\", (int) x));\n\t\tgoto fail;\n\t}\n\t}  /* switch initial byte */\n\n\tDUK_ASSERT(duk_get_top(thr) >= entry_top);\n\tduk_set_top(thr, entry_top);\n\tduk__debug_skip_to_eom(thr);\n\treturn;\n\n fail:\n\tDUK_ASSERT(duk_get_top(thr) >= entry_top);\n\tduk_set_top(thr, entry_top);\n\tDUK__SET_CONN_BROKEN(thr, 1);\n\treturn;\n}\n\nDUK_LOCAL void duk__check_resend_status(duk_hthread *thr) {\n\tif (thr->heap->dbg_read_cb != NULL && thr->heap->dbg_state_dirty) {\n\t\tduk_debug_send_status(thr);\n\t\tthr->heap->dbg_state_dirty = 0;\n\t}\n}\n\nDUK_INTERNAL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t no_block) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top;\n#endif\n\tduk_bool_t retval = 0;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\n\tDUK_D(DUK_DPRINT(\"process debug messages: read_cb=%s, no_block=%ld, detaching=%ld, processing=%ld\",\n\t                 thr->heap->dbg_read_cb ? \"not NULL\" : \"NULL\", (long) no_block,\n\t                 (long) thr->heap->dbg_detaching, (long) thr->heap->dbg_processing));\n\tDUK_DD(DUK_DDPRINT(\"top at entry: %ld\", (long) duk_get_top(thr)));\n\n\t/* thr->heap->dbg_detaching may be != 0 if a debugger write outside\n\t * the message loop caused a transport error and detach1() to run.\n\t */\n\tDUK_ASSERT(thr->heap->dbg_detaching == 0 || thr->heap->dbg_detaching == 1);\n\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\tthr->heap->dbg_processing = 1;\n\n\t/* Ensure dirty state causes a Status even if never process any\n\t * messages.  This is expected by the bytecode executor when in\n\t * the running state.\n\t */\n\tduk__check_resend_status(thr);\n\n\tfor (;;) {\n\t\t/* Process messages until we're no longer paused or we peek\n\t\t * and see there's nothing to read right now.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"top at loop top: %ld\", (long) duk_get_top(thr)));\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 1);\n\n\t\twhile (thr->heap->dbg_read_cb == NULL && thr->heap->dbg_detaching) {\n\t\t\t/* Detach is pending; can be triggered from outside the\n\t\t\t * debugger loop (e.g. Status notify write error) or by\n\t\t\t * previous message handling.  Call detached callback\n\t\t\t * here, in a controlled state, to ensure a possible\n\t\t\t * reattach inside the detached_cb is handled correctly.\n\t\t\t *\n\t\t\t * Recheck for detach in a while loop: an immediate\n\t\t\t * reattach involves a call to duk_debugger_attach()\n\t\t\t * which writes a debugger handshake line immediately\n\t\t\t * inside the API call.  If the transport write fails\n\t\t\t * for that handshake, we can immediately end up in a\n\t\t\t * \"transport broken, detaching\" case several times here.\n\t\t\t * Loop back until we're either cleanly attached or\n\t\t\t * fully detached.\n\t\t\t *\n\t\t\t * NOTE: Reset dbg_processing = 1 forcibly, in case we\n\t\t\t * re-attached; duk_debugger_attach() sets dbg_processing\n\t\t\t * to 0 at the moment.\n\t\t\t */\n\n\t\t\tDUK_D(DUK_DPRINT(\"detach pending (dbg_read_cb == NULL, dbg_detaching != 0), call detach2\"));\n\n\t\t\tduk__debug_do_detach2(thr->heap);\n\t\t\tthr->heap->dbg_processing = 1;  /* may be set to 0 by duk_debugger_attach() inside callback */\n\n\t\t\tDUK_D(DUK_DPRINT(\"after detach2 (and possible reattach): dbg_read_cb=%s, dbg_detaching=%ld\",\n\t\t\t                 thr->heap->dbg_read_cb ? \"not NULL\" : \"NULL\", (long) thr->heap->dbg_detaching));\n\t\t}\n\t\tDUK_ASSERT(thr->heap->dbg_detaching == 0);  /* true even with reattach */\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 1);  /* even after a detach and possible reattach */\n\n\t\tif (thr->heap->dbg_read_cb == NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"debug connection broken (and not detaching), stop processing messages\"));\n\t\t\tbreak;\n\t\t}\n\n\t\tif (!DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || no_block) {\n\t\t\tif (!duk_debug_read_peek(thr)) {\n\t\t\t\t/* Note: peek cannot currently trigger a detach\n\t\t\t\t * so the dbg_detaching == 0 assert outside the\n\t\t\t\t * loop is correct.\n\t\t\t\t */\n\t\t\t\tDUK_D(DUK_DPRINT(\"processing debug message, peek indicated no data, stop processing messages\"));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_D(DUK_DPRINT(\"processing debug message, peek indicated there is data, handle it\"));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"paused, process debug message, blocking if necessary\"));\n\t\t}\n\n\t\tduk__check_resend_status(thr);\n\t\tduk__debug_process_message(thr);\n\t\tduk__check_resend_status(thr);\n\n\t\tretval = 1;  /* processed one or more messages */\n\t}\n\n\tDUK_ASSERT(thr->heap->dbg_detaching == 0);\n\tDUK_ASSERT(thr->heap->dbg_processing == 1);\n\tthr->heap->dbg_processing = 0;\n\n\t/* As an initial implementation, read flush after exiting the message\n\t * loop.  If transport is broken, this is a no-op (with debug logs).\n\t */\n\tduk_debug_read_flush(thr);  /* this cannot initiate a detach */\n\tDUK_ASSERT(thr->heap->dbg_detaching == 0);\n\n\tDUK_DD(DUK_DDPRINT(\"top at exit: %ld\", (long) duk_get_top(thr)));\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Easy to get wrong, so assert for it. */\n\tDUK_ASSERT(entry_top == duk_get_top(thr));\n#endif\n\n\treturn retval;\n}\n\n/*\n *  Halt execution helper\n */\n\n/* Halt execution and enter a debugger message loop until execution is resumed\n * by the client.  PC for the current activation may be temporarily decremented\n * so that the \"current\" instruction will be shown by the client.  This helper\n * is callable from anywhere, also outside bytecode executor.\n */\n\nDUK_INTERNAL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev_pc) {\n\tduk_activation *act;\n\tduk_hcompfunc *fun;\n\tduk_instr_t *old_pc = NULL;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(duk_debug_is_attached(thr->heap));\n\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\tDUK_ASSERT(!duk_debug_is_paused(thr->heap));\n\n\tduk_debug_set_paused(thr->heap);\n\n\tact = thr->callstack_curr;\n\n\t/* NOTE: act may be NULL if an error is thrown outside of any activation,\n\t * which may happen in the case of, e.g. syntax errors.\n\t */\n\n\t/* Decrement PC if that was requested, this requires a PC sync. */\n\tif (act != NULL) {\n\t\tduk_hthread_sync_currpc(thr);\n\t\told_pc = act->curr_pc;\n\t\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\n\t\t/* Short circuit if is safe: if act->curr_pc != NULL, 'fun' is\n\t\t * guaranteed to be a non-NULL ECMAScript function.\n\t\t */\n\t\tDUK_ASSERT(act->curr_pc == NULL ||\n\t\t           (fun != NULL && DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun)));\n\t\tif (use_prev_pc &&\n\t\t    act->curr_pc != NULL &&\n\t\t    act->curr_pc > DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, fun)) {\n\t\t\tact->curr_pc--;\n\t\t}\n\t}\n\n\t/* Process debug messages until we are no longer paused. */\n\n\t/* NOTE: This is a bit fragile.  It's important to ensure that\n\t * duk_debug_process_messages() never throws an error or\n\t * act->curr_pc will never be reset.\n\t */\n\n\tthr->heap->dbg_state_dirty = 1;\n\twhile (DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap)) {\n\t\tDUK_ASSERT(duk_debug_is_attached(thr->heap));\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\t\tduk_debug_process_messages(thr, 0 /*no_block*/);\n\t}\n\n\t/* XXX: Decrementing and restoring act->curr_pc works now, but if the\n\t * debugger message loop gains the ability to adjust the current PC\n\t * (e.g. a forced jump) restoring the PC here will break.  Another\n\t * approach would be to use a state flag for the \"decrement 1 from\n\t * topmost activation's PC\" and take it into account whenever dealing\n\t * with PC values.\n\t */\n\tif (act != NULL) {\n\t\tact->curr_pc = old_pc;  /* restore PC */\n\t}\n}\n\n/*\n *  Breakpoint management\n */\n\nDUK_INTERNAL duk_small_int_t duk_debug_add_breakpoint(duk_hthread *thr, duk_hstring *filename, duk_uint32_t line) {\n\tduk_heap *heap;\n\tduk_breakpoint *b;\n\n\t/* Caller must trigger recomputation of active breakpoint list.  To\n\t * ensure stale values are not used if that doesn't happen, clear the\n\t * active breakpoint list here.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(filename != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\n\tif (heap->dbg_breakpoint_count >= DUK_HEAP_MAX_BREAKPOINTS) {\n\t\tDUK_D(DUK_DPRINT(\"failed to add breakpoint for %O:%ld, all breakpoint slots used\",\n\t\t                 (duk_heaphdr *) filename, (long) line));\n\t\treturn -1;\n\t}\n\theap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;\n\tb = heap->dbg_breakpoints + (heap->dbg_breakpoint_count++);\n\tb->filename = filename;\n\tb->line = line;\n\tDUK_HSTRING_INCREF(thr, filename);\n\n\treturn (duk_small_int_t) (heap->dbg_breakpoint_count - 1);  /* index */\n}\n\nDUK_INTERNAL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_small_uint_t breakpoint_index) {\n\tduk_heap *heap;\n\tduk_hstring *h;\n\tduk_breakpoint *b;\n\tduk_size_t move_size;\n\n\t/* Caller must trigger recomputation of active breakpoint list.  To\n\t * ensure stale values are not used if that doesn't happen, clear the\n\t * active breakpoint list here.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(duk_debug_is_attached(thr->heap));\n\tDUK_ASSERT_DISABLE(breakpoint_index >= 0);  /* unsigned */\n\n\tif (breakpoint_index >= heap->dbg_breakpoint_count) {\n\t\tDUK_D(DUK_DPRINT(\"invalid breakpoint index: %ld\", (long) breakpoint_index));\n\t\treturn 0;\n\t}\n\tb = heap->dbg_breakpoints + breakpoint_index;\n\n\th = b->filename;\n\tDUK_ASSERT(h != NULL);\n\n\tmove_size = sizeof(duk_breakpoint) * (heap->dbg_breakpoint_count - breakpoint_index - 1);\n\tduk_memmove((void *) b,\n\t            (const void *) (b + 1),\n\t            (size_t) move_size);\n\n\theap->dbg_breakpoint_count--;\n\theap->dbg_breakpoints_active[0] = (duk_breakpoint *) NULL;\n\n\tDUK_HSTRING_DECREF(thr, h);  /* side effects */\n\tDUK_UNREF(h);  /* w/o refcounting */\n\n\t/* Breakpoint entries above the used area are left as garbage. */\n\n\treturn 1;\n}\n\n/*\n *  Misc state management\n */\n\nDUK_INTERNAL duk_bool_t duk_debug_is_attached(duk_heap *heap) {\n\treturn (heap->dbg_read_cb != NULL);\n}\n\nDUK_INTERNAL duk_bool_t duk_debug_is_paused(duk_heap *heap) {\n\treturn (DUK_HEAP_HAS_DEBUGGER_PAUSED(heap) != 0);\n}\n\nDUK_INTERNAL void duk_debug_set_paused(duk_heap *heap) {\n\tif (duk_debug_is_paused(heap)) {\n\t\tDUK_D(DUK_DPRINT(\"trying to set paused state when already paused, ignoring\"));\n\t} else {\n\t\tDUK_HEAP_SET_DEBUGGER_PAUSED(heap);\n\t\theap->dbg_state_dirty = 1;\n\t\tduk_debug_clear_pause_state(heap);\n\t\tDUK_ASSERT(heap->ms_running == 0);  /* debugger can't be triggered within mark-and-sweep */\n\t\theap->ms_running = 2;  /* prevent mark-and-sweep, prevent refzero queueing */\n\t\theap->ms_prevent_count++;\n\t\tDUK_ASSERT(heap->ms_prevent_count != 0);  /* Wrap. */\n\t\tDUK_ASSERT(heap->heap_thread != NULL);\n\t}\n}\n\nDUK_INTERNAL void duk_debug_clear_paused(duk_heap *heap) {\n\tif (duk_debug_is_paused(heap)) {\n\t\tDUK_HEAP_CLEAR_DEBUGGER_PAUSED(heap);\n\t\theap->dbg_state_dirty = 1;\n\t\tduk_debug_clear_pause_state(heap);\n\t\tDUK_ASSERT(heap->ms_running == 2);\n\t\tDUK_ASSERT(heap->ms_prevent_count > 0);\n\t\theap->ms_prevent_count--;\n\t\theap->ms_running = 0;\n\t\tDUK_ASSERT(heap->heap_thread != NULL);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"trying to clear paused state when not paused, ignoring\"));\n\t}\n}\n\nDUK_INTERNAL void duk_debug_clear_pause_state(duk_heap *heap) {\n\theap->dbg_pause_flags = 0;\n\theap->dbg_pause_act = NULL;\n\theap->dbg_pause_startline = 0;\n}\n\n#else  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/* No debugger support. */\n\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_debugger.h",
    "content": "#if !defined(DUK_DEBUGGER_H_INCLUDED)\n#define DUK_DEBUGGER_H_INCLUDED\n\n/* Debugger protocol version is defined in the public API header. */\n\n/* Initial bytes for markers. */\n#define DUK_DBG_IB_EOM                   0x00\n#define DUK_DBG_IB_REQUEST               0x01\n#define DUK_DBG_IB_REPLY                 0x02\n#define DUK_DBG_IB_ERROR                 0x03\n#define DUK_DBG_IB_NOTIFY                0x04\n\n/* Other initial bytes. */\n#define DUK_DBG_IB_INT4                  0x10\n#define DUK_DBG_IB_STR4                  0x11\n#define DUK_DBG_IB_STR2                  0x12\n#define DUK_DBG_IB_BUF4                  0x13\n#define DUK_DBG_IB_BUF2                  0x14\n#define DUK_DBG_IB_UNUSED                0x15\n#define DUK_DBG_IB_UNDEFINED             0x16\n#define DUK_DBG_IB_NULL                  0x17\n#define DUK_DBG_IB_TRUE                  0x18\n#define DUK_DBG_IB_FALSE                 0x19\n#define DUK_DBG_IB_NUMBER                0x1a\n#define DUK_DBG_IB_OBJECT                0x1b\n#define DUK_DBG_IB_POINTER               0x1c\n#define DUK_DBG_IB_LIGHTFUNC             0x1d\n#define DUK_DBG_IB_HEAPPTR               0x1e\n/* The short string/integer initial bytes starting from 0x60 don't have\n * defines now.\n */\n\n/* Error codes. */\n#define DUK_DBG_ERR_UNKNOWN              0x00\n#define DUK_DBG_ERR_UNSUPPORTED          0x01\n#define DUK_DBG_ERR_TOOMANY              0x02\n#define DUK_DBG_ERR_NOTFOUND             0x03\n#define DUK_DBG_ERR_APPLICATION          0x04\n\n/* Commands and notifys initiated by Duktape. */\n#define DUK_DBG_CMD_STATUS               0x01\n#define DUK_DBG_CMD_UNUSED_2             0x02  /* Duktape 1.x: print notify */\n#define DUK_DBG_CMD_UNUSED_3             0x03  /* Duktape 1.x: alert notify */\n#define DUK_DBG_CMD_UNUSED_4             0x04  /* Duktape 1.x: log notify */\n#define DUK_DBG_CMD_THROW                0x05\n#define DUK_DBG_CMD_DETACHING            0x06\n#define DUK_DBG_CMD_APPNOTIFY            0x07\n\n/* Commands initiated by debug client. */\n#define DUK_DBG_CMD_BASICINFO            0x10\n#define DUK_DBG_CMD_TRIGGERSTATUS        0x11\n#define DUK_DBG_CMD_PAUSE                0x12\n#define DUK_DBG_CMD_RESUME               0x13\n#define DUK_DBG_CMD_STEPINTO             0x14\n#define DUK_DBG_CMD_STEPOVER             0x15\n#define DUK_DBG_CMD_STEPOUT              0x16\n#define DUK_DBG_CMD_LISTBREAK            0x17\n#define DUK_DBG_CMD_ADDBREAK             0x18\n#define DUK_DBG_CMD_DELBREAK             0x19\n#define DUK_DBG_CMD_GETVAR               0x1a\n#define DUK_DBG_CMD_PUTVAR               0x1b\n#define DUK_DBG_CMD_GETCALLSTACK         0x1c\n#define DUK_DBG_CMD_GETLOCALS            0x1d\n#define DUK_DBG_CMD_EVAL                 0x1e\n#define DUK_DBG_CMD_DETACH               0x1f\n#define DUK_DBG_CMD_DUMPHEAP             0x20\n#define DUK_DBG_CMD_GETBYTECODE          0x21\n#define DUK_DBG_CMD_APPREQUEST           0x22\n#define DUK_DBG_CMD_GETHEAPOBJINFO       0x23\n#define DUK_DBG_CMD_GETOBJPROPDESC       0x24\n#define DUK_DBG_CMD_GETOBJPROPDESCRANGE  0x25\n\n/* The low 8 bits map directly to duk_hobject.h DUK_PROPDESC_FLAG_xxx.\n * The remaining flags are specific to the debugger.\n */\n#define DUK_DBG_PROPFLAG_SYMBOL          (1U << 8)\n#define DUK_DBG_PROPFLAG_HIDDEN          (1U << 9)\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL_DECL void duk_debug_do_detach(duk_heap *heap);\n\nDUK_INTERNAL_DECL duk_bool_t duk_debug_read_peek(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_write_flush(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_debug_skip_bytes(duk_hthread *thr, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_skip_byte(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_debug_read_bytes(duk_hthread *thr, duk_uint8_t *data, duk_size_t length);\nDUK_INTERNAL_DECL duk_uint8_t duk_debug_read_byte(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_int32_t duk_debug_read_int(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_hstring *duk_debug_read_hstring(duk_hthread *thr);\n/* XXX: exposed duk_debug_read_pointer */\n/* XXX: exposed duk_debug_read_buffer */\n/* XXX: exposed duk_debug_read_hbuffer */\n#if 0\nDUK_INTERNAL_DECL duk_heaphdr *duk_debug_read_heapptr(duk_hthread *thr);\n#endif\n#if defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL_DECL duk_heaphdr *duk_debug_read_any_ptr(duk_hthread *thr);\n#endif\nDUK_INTERNAL_DECL duk_tval *duk_debug_read_tval(duk_hthread *thr);\n\nDUK_INTERNAL_DECL void duk_debug_write_bytes(duk_hthread *thr, const duk_uint8_t *data, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_write_byte(duk_hthread *thr, duk_uint8_t x);\nDUK_INTERNAL_DECL void duk_debug_write_unused(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_write_undefined(duk_hthread *thr);\n#if defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL_DECL void duk_debug_write_null(duk_hthread *thr);\n#endif\nDUK_INTERNAL_DECL void duk_debug_write_boolean(duk_hthread *thr, duk_uint_t val);\nDUK_INTERNAL_DECL void duk_debug_write_int(duk_hthread *thr, duk_int32_t x);\nDUK_INTERNAL_DECL void duk_debug_write_uint(duk_hthread *thr, duk_uint32_t x);\nDUK_INTERNAL_DECL void duk_debug_write_string(duk_hthread *thr, const char *data, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_write_cstring(duk_hthread *thr, const char *data);\nDUK_INTERNAL_DECL void duk_debug_write_hstring(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_debug_write_buffer(duk_hthread *thr, const char *data, duk_size_t length);\nDUK_INTERNAL_DECL void duk_debug_write_hbuffer(duk_hthread *thr, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_debug_write_pointer(duk_hthread *thr, void *ptr);\n#if defined(DUK_USE_DEBUGGER_DUMPHEAP) || defined(DUK_USE_DEBUGGER_INSPECT)\nDUK_INTERNAL_DECL void duk_debug_write_heapptr(duk_hthread *thr, duk_heaphdr *h);\n#endif\nDUK_INTERNAL_DECL void duk_debug_write_hobject(duk_hthread *thr, duk_hobject *obj);\nDUK_INTERNAL_DECL void duk_debug_write_tval(duk_hthread *thr, duk_tval *tv);\n#if 0  /* unused */\nDUK_INTERNAL_DECL void duk_debug_write_request(duk_hthread *thr, duk_small_uint_t command);\n#endif\nDUK_INTERNAL_DECL void duk_debug_write_reply(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_write_error_eom(duk_hthread *thr, duk_small_uint_t err_code, const char *msg);\nDUK_INTERNAL_DECL void duk_debug_write_notify(duk_hthread *thr, duk_small_uint_t command);\nDUK_INTERNAL_DECL void duk_debug_write_eom(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_debug_curr_line(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_debug_send_status(duk_hthread *thr);\n#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)\nDUK_INTERNAL_DECL void duk_debug_send_throw(duk_hthread *thr, duk_bool_t fatal);\n#endif\n\nDUK_INTERNAL_DECL void duk_debug_halt_execution(duk_hthread *thr, duk_bool_t use_prev_pc);\nDUK_INTERNAL_DECL duk_bool_t duk_debug_process_messages(duk_hthread *thr, duk_bool_t no_block);\n\nDUK_INTERNAL_DECL duk_small_int_t duk_debug_add_breakpoint(duk_hthread *thr, duk_hstring *filename, duk_uint32_t line);\nDUK_INTERNAL_DECL duk_bool_t duk_debug_remove_breakpoint(duk_hthread *thr, duk_small_uint_t breakpoint_index);\n\nDUK_INTERNAL_DECL duk_bool_t duk_debug_is_attached(duk_heap *heap);\nDUK_INTERNAL_DECL duk_bool_t duk_debug_is_paused(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_debug_set_paused(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_debug_clear_paused(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_debug_clear_pause_state(duk_heap *heap);\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n#endif  /* DUK_DEBUGGER_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_error.h",
    "content": "/*\n *  Error handling macros, assertion macro, error codes.\n *\n *  There are three types of 'errors':\n *\n *    1. Ordinary errors relative to a thread, cause a longjmp, catchable.\n *    2. Fatal errors relative to a heap, cause fatal handler to be called.\n *    3. Fatal errors without context, cause the default (not heap specific)\n *       fatal handler to be called.\n *\n *  Fatal errors without context are used by debug code such as assertions.\n *  By providing a fatal error handler for a Duktape heap, user code can\n *  avoid fatal errors without context in non-debug builds.\n */\n\n#if !defined(DUK_ERROR_H_INCLUDED)\n#define DUK_ERROR_H_INCLUDED\n\n/*\n *  Error codes: defined in duktape.h\n *\n *  Error codes are used as a shorthand to throw exceptions from inside\n *  the implementation.  The appropriate ECMAScript object is constructed\n *  based on the code.  ECMAScript code throws objects directly.  The error\n *  codes are defined in the public API header because they are also used\n *  by calling code.\n */\n\n/*\n *  Normal error\n *\n *  Normal error is thrown with a longjmp() through the current setjmp()\n *  catchpoint record in the duk_heap.  The 'curr_thread' of the duk_heap\n *  identifies the throwing thread.\n *\n *  Error formatting is usually unnecessary.  The error macros provide a\n *  zero argument version (no formatting) and separate macros for small\n *  argument counts.  Variadic macros are not used to avoid portability\n *  issues and avoid the need for stash-based workarounds when they're not\n *  available.  Vararg calls are avoided for non-formatted error calls\n *  because vararg call sites are larger than normal, and there are a lot\n *  of call sites with no formatting.\n *\n *  Note that special formatting provided by debug macros is NOT available.\n *\n *  The _RAW variants allow the caller to specify file and line.  This makes\n *  it easier to write checked calls which want to use the call site of the\n *  checked function, not the error macro call inside the checked function.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\n/* Because there are quite many call sites, pack error code (require at most\n * 8-bit) into a single argument.\n */\n#define DUK_ERROR(thr,err,msg) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (msg)); \\\n\t} while (0)\n#define DUK_ERROR_RAW(thr,file,line,err,msg) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (msg)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT1(thr,err,fmt,arg1) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT1(thr,file,line,err,fmt,arg1) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT2(thr,err,fmt,arg1,arg2) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT2(thr,file,line,err,fmt,arg1,arg2) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT3(thr,err,fmt,arg1,arg2,arg3) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT3(thr,file,line,err,fmt,arg1,arg2,arg3) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3)); \\\n\t} while (0)\n\n#define DUK_ERROR_FMT4(thr,err,fmt,arg1,arg2,arg3,arg4) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) DUK_LINE_MACRO; \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), DUK_FILE_MACRO, (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3), (arg4)); \\\n\t} while (0)\n#define DUK_ERROR_RAW_FMT4(thr,file,line,err,fmt,arg1,arg2,arg3,arg4) do { \\\n\t\tduk_errcode_t duk__err = (err); duk_int_t duk__line = (duk_int_t) (line); \\\n\t\tDUK_ASSERT(duk__err >= 0 && duk__err <= 0xff); DUK_ASSERT(duk__line >= 0 && duk__line <= 0x00ffffffL); \\\n\t\tduk_err_handle_error_fmt((thr), (file), (((duk_uint_t) duk__err) << 24) | ((duk_uint_t) duk__line), (fmt), (arg1), (arg2), (arg3), (arg4)); \\\n\t} while (0)\n\n#else  /* DUK_USE_VERBOSE_ERRORS */\n\n#define DUK_ERROR(thr,err,msg)                    duk_err_handle_error((thr), (err))\n#define DUK_ERROR_RAW(thr,file,line,err,msg)      duk_err_handle_error((thr), (err))\n\n#define DUK_ERROR_FMT1(thr,err,fmt,arg1) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT1(thr,file,line,err,fmt,arg1) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#define DUK_ERROR_FMT2(thr,err,fmt,arg1,arg2) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT2(thr,file,line,err,fmt,arg1,arg2) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#define DUK_ERROR_FMT3(thr,err,fmt,arg1,arg2,arg3) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT3(thr,file,line,err,fmt,arg1,arg2,arg3) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#define DUK_ERROR_FMT4(thr,err,fmt,arg1,arg2,arg3,arg4) DUK_ERROR((thr),(err),(fmt))\n#define DUK_ERROR_RAW_FMT4(thr,file,line,err,fmt,arg1,arg2,arg3,arg4) DUK_ERROR_RAW((thr),(file),(line),(err),(fmt))\n\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n/*\n *  Fatal error without context\n *\n *  The macro is an expression to make it compatible with DUK_ASSERT_EXPR().\n */\n\n#define DUK_FATAL_WITHOUT_CONTEXT(msg) \\\n\tduk_default_fatal_handler(NULL, (msg))\n\n/*\n *  Error throwing helpers\n *\n *  The goal is to provide verbose and configurable error messages.  Call\n *  sites should be clean in source code and compile to a small footprint.\n *  Small footprint is also useful for performance because small cold paths\n *  reduce code cache pressure.  Adding macros here only makes sense if there\n *  are enough call sites to get concrete benefits.\n *\n *  DUK_ERROR_xxx() macros are generic and can be used anywhere.\n *\n *  DUK_DCERROR_xxx() macros can only be used in Duktape/C functions where\n *  the \"return DUK_RET_xxx;\" shorthand is available for low memory targets.\n *  The DUK_DCERROR_xxx() macros always either throw or perform a\n *  'return DUK_RET_xxx' from the calling function.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n/* Verbose errors with key/value summaries (non-paranoid) or without key/value\n * summaries (paranoid, for some security sensitive environments), the paranoid\n * vs. non-paranoid distinction affects only a few specific errors.\n */\n#if defined(DUK_USE_PARANOID_ERRORS)\n#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \\\n\t\tduk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx), (expectname)); \\\n\t} while (0)\n#else  /* DUK_USE_PARANOID_ERRORS */\n#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \\\n\t\tduk_err_require_type_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx), (expectname)); \\\n\t} while (0)\n#endif  /* DUK_USE_PARANOID_ERRORS */\n\n#define DUK_ERROR_INTERNAL(thr) do { \\\n\t\tduk_err_error_internal((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_INTERNAL(thr) do { \\\n\t\tDUK_ERROR_INTERNAL((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_ALLOC_FAILED(thr) do { \\\n\t\tduk_err_error_alloc_failed((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_ERROR_UNSUPPORTED(thr) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_ERROR, DUK_STR_UNSUPPORTED); \\\n\t} while (0)\n#define DUK_DCERROR_UNSUPPORTED(thr) do { \\\n\t\tDUK_ERROR_UNSUPPORTED((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_ERROR(thr,msg) do { \\\n\t\tduk_err_error((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INDEX(thr,idx) do { \\\n\t\tduk_err_range_index((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (idx)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) do { \\\n\t\tduk_err_range_push_beyond((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tDUK_ERROR_RANGE((thr), DUK_STR_INVALID_ARGS); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tDUK_ERROR_RANGE_INVALID_ARGS((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tDUK_ERROR_RANGE((thr), DUK_STR_INVALID_COUNT); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tDUK_ERROR_RANGE_INVALID_COUNT((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tDUK_ERROR_RANGE((thr), DUK_STR_INVALID_LENGTH); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tDUK_ERROR_RANGE_INVALID_LENGTH((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_RANGE(thr,msg) do { \\\n\t\tduk_err_range((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_EVAL(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_EVAL_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_REFERENCE(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_REFERENCE_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_SYNTAX(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_SYNTAX_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tduk_err_type_invalid_args((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tDUK_ERROR_TYPE_INVALID_ARGS((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tduk_err_type_invalid_state((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tDUK_ERROR_TYPE_INVALID_STATE((thr)); \\\n\t\treturn 0; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tduk_err_type_invalid_trap_result((thr), DUK_FILE_MACRO, (duk_int_t) DUK_LINE_MACRO); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tDUK_ERROR_TYPE((thr), DUK_STR_INVALID_TRAP_RESULT); \\\n\t} while (0)\n#define DUK_ERROR_TYPE(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_TYPE_ERROR, (msg)); \\\n\t} while (0)\n#define DUK_ERROR_URI(thr,msg) do { \\\n\t\tDUK_ERROR((thr), DUK_ERR_URI_ERROR, (msg)); \\\n\t} while (0)\n#else  /* DUK_USE_VERBOSE_ERRORS */\n/* Non-verbose errors for low memory targets: no file, line, or message. */\n\n#define DUK_ERROR_REQUIRE_TYPE_INDEX(thr,idx,expectname,lowmemstr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n\n#define DUK_ERROR_INTERNAL(thr) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_INTERNAL(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_ALLOC_FAILED(thr) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_ERROR_UNSUPPORTED(thr) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_UNSUPPORTED(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_ERROR(thr,msg) do { \\\n\t\tduk_err_error((thr)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INDEX(thr,idx) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_PUSH_BEYOND(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_ARGS(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_RANGE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_COUNT(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_RANGE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_RANGE_INVALID_LENGTH(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_RANGE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_RANGE(thr,msg) do { \\\n\t\tduk_err_range((thr)); \\\n\t} while (0)\n#define DUK_ERROR_EVAL(thr,msg) do { \\\n\t\tduk_err_eval((thr)); \\\n\t} while (0)\n#define DUK_ERROR_REFERENCE(thr,msg) do { \\\n\t\tduk_err_reference((thr)); \\\n\t} while (0)\n#define DUK_ERROR_SYNTAX(thr,msg) do { \\\n\t\tduk_err_syntax((thr)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_ARGS(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_TYPE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_STATE(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_DCERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tDUK_UNREF((thr)); \\\n\t\treturn DUK_RET_TYPE_ERROR; \\\n\t} while (0)\n#define DUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_ERROR_TYPE(thr,msg) do { \\\n\t\tduk_err_type((thr)); \\\n\t} while (0)\n#define DUK_ERROR_URI(thr,msg) do { \\\n\t\tduk_err_uri((thr)); \\\n\t} while (0)\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n/*\n *  Assert macro: failure causes a fatal error.\n *\n *  NOTE: since the assert macro doesn't take a heap/context argument, there's\n *  no way to look up a heap/context specific fatal error handler which may have\n *  been given by the application.  Instead, assertion failures always use the\n *  internal default fatal error handler; it can be replaced via duk_config.h\n *  and then applies to all Duktape heaps.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n\n/* The message should be a compile time constant without formatting (less risk);\n * we don't care about assertion text size because they're not used in production\n * builds.\n */\n#define DUK_ASSERT(x)  do { \\\n\tif (!(x)) { \\\n\t\tDUK_FATAL_WITHOUT_CONTEXT(\"assertion failed: \" #x \\\n\t\t\t\" (\" DUK_FILE_MACRO \":\" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) \")\"); \\\n\t} \\\n\t} while (0)\n\n/* Assertion compatible inside a comma expression, evaluates to void. */\n#define DUK_ASSERT_EXPR(x) \\\n\t((void) ((x) ? 0 : (DUK_FATAL_WITHOUT_CONTEXT(\"assertion failed: \" #x \\\n\t\t\t\t\" (\" DUK_FILE_MACRO \":\" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO) \")\"), 0)))\n\n#else  /* DUK_USE_ASSERTIONS */\n\n#define DUK_ASSERT(x)  do { /* assertion omitted */ } while (0)\n\n#define DUK_ASSERT_EXPR(x)  ((void) 0)\n\n#endif  /* DUK_USE_ASSERTIONS */\n\n/* this variant is used when an assert would generate a compile warning by\n * being always true (e.g. >= 0 comparison for an unsigned value\n */\n#define DUK_ASSERT_DISABLE(x)  do { /* assertion disabled */ } while (0)\n\n/*\n *  Assertion helpers\n */\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h)  do { \\\n\t\tDUK_ASSERT((h) == NULL || DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) (h)) > 0); \\\n\t} while (0)\n#define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv)  do { \\\n\t\tif ((tv) != NULL && DUK_TVAL_IS_HEAP_ALLOCATED((tv))) { \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(DUK_TVAL_GET_HEAPHDR((tv))) > 0); \\\n\t\t} \\\n\t} while (0)\n#else\n#define DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(h)  /* no refcount check */\n#define DUK_ASSERT_REFCOUNT_NONZERO_TVAL(tv)    /* no refcount check */\n#endif\n\n#define DUK_ASSERT_TOP(ctx,n)  DUK_ASSERT((duk_idx_t) duk_get_top((ctx)) == (duk_idx_t) (n))\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_PACKED_TVAL)\n#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval)  do { \\\n\t\tduk_double_union duk__assert_tmp_du; \\\n\t\tduk__assert_tmp_du.d = (dval); \\\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&duk__assert_tmp_du)); \\\n\t} while (0)\n#else\n#define DUK_ASSERT_DOUBLE_IS_NORMALIZED(dval)  /* nop */\n#endif\n\n#define DUK_ASSERT_VS_SPACE(thr) \\\n\tDUK_ASSERT(thr->valstack_top < thr->valstack_end)\n\n/*\n *  Helper to initialize a memory area (e.g. struct) with garbage when\n *  assertions enabled.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n#define DUK_ASSERT_SET_GARBAGE(ptr,size) do { \\\n\t\tduk_memset_unsafe((void *) (ptr), 0x5a, size); \\\n\t} while (0)\n#else\n#define DUK_ASSERT_SET_GARBAGE(ptr,size) do {} while (0)\n#endif\n\n/*\n *  Helper for valstack space\n *\n *  Caller of DUK_ASSERT_VALSTACK_SPACE() estimates the number of free stack entries\n *  required for its own use, and any child calls which are not (a) Duktape API calls\n *  or (b) Duktape calls which involve extending the valstack (e.g. getter call).\n */\n\n#define DUK_VALSTACK_ASSERT_EXTRA  5  /* this is added to checks to allow for Duktape\n                                       * API calls in addition to function's own use\n                                       */\n#if defined(DUK_USE_ASSERTIONS)\n#define DUK_ASSERT_VALSTACK_SPACE(thr,n)   do { \\\n\t\tDUK_ASSERT((thr) != NULL); \\\n\t\tDUK_ASSERT((thr)->valstack_end - (thr)->valstack_top >= (n) + DUK_VALSTACK_ASSERT_EXTRA); \\\n\t} while (0)\n#else\n#define DUK_ASSERT_VALSTACK_SPACE(thr,n)   /* no valstack space check */\n#endif\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *msg));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error_fmt(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *fmt, ...));\n#else  /* DUK_USE_VERBOSE_ERRORS */\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_handle_error(duk_hthread *thr, duk_errcode_t code));\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code, const char *msg, const char *filename, duk_int_t line));\n#else\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code));\n#endif\n\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t rc));\n\n#define DUK_AUGMENT_FLAG_NOBLAME_FILELINE  (1U << 0)  /* if set, don't blame C file/line for .fileName and .lineNumber */\n#define DUK_AUGMENT_FLAG_SKIP_ONE          (1U << 1)  /* if set, skip topmost activation in traceback construction */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_INTERNAL_DECL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *filename, duk_int_t line, duk_small_uint_t flags);\n#endif\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\nDUK_INTERNAL_DECL void duk_err_augment_error_throw(duk_hthread *thr);\n#endif\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name));\n#else\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name));\n#endif\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error_alloc_failed(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range_push_beyond(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_args(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_state(duk_hthread *thr, const char *filename, duk_int_t linenumber));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type_invalid_trap_result(duk_hthread *thr, const char *filename, duk_int_t linenumber));\n#else  /* DUK_VERBOSE_ERRORS */\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_error(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_range(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_eval(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_reference(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_syntax(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_type(duk_hthread *thr));\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_uri(duk_hthread *thr));\n#endif /* DUK_VERBOSE_ERRORS */\n\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_err_longjmp(duk_hthread *thr));\n\nDUK_NORETURN(DUK_INTERNAL_DECL void duk_default_fatal_handler(void *udata, const char *msg));\n\nDUK_INTERNAL_DECL void duk_err_setup_ljstate1(duk_hthread *thr, duk_small_uint_t lj_type, duk_tval *tv_val);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL_DECL void duk_err_check_debugger_integration(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_errcode_t err_code);\n\n#endif  /* DUK_ERROR_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_error_augment.c",
    "content": "/*\n *  Augmenting errors at their creation site and their throw site.\n *\n *  When errors are created, traceback data is added by built-in code\n *  and a user error handler (if defined) can process or replace the\n *  error.  Similarly, when errors are thrown, a user error handler\n *  (if defined) can process or replace the error.\n *\n *  Augmentation and other processing at error creation time is nice\n *  because an error is only created once, but it may be thrown and\n *  rethrown multiple times.  User error handler registered for processing\n *  an error at its throw site must be careful to handle rethrowing in\n *  a useful manner.\n *\n *  Error augmentation may throw an internal error (e.g. alloc error).\n *\n *  ECMAScript allows throwing any values, so all values cannot be\n *  augmented.  Currently, the built-in augmentation at error creation\n *  only augments error values which are Error instances (= have the\n *  built-in Error.prototype in their prototype chain) and are also\n *  extensible.  User error handlers have no limitations in this respect.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Helper for calling a user error handler.\n *\n *  'thr' must be the currently active thread; the error handler is called\n *  in its context.  The valstack of 'thr' must have the error value on\n *  top, and will be replaced by another error value based on the return\n *  value of the error handler.\n *\n *  The helper calls duk_handle_call() recursively in protected mode.\n *  Before that call happens, no longjmps should happen; as a consequence,\n *  we must assume that the valstack contains enough temporary space for\n *  arguments and such.\n *\n *  While the error handler runs, any errors thrown will not trigger a\n *  recursive error handler call (this is implemented using a heap level\n *  flag which will \"follow\" through any coroutines resumed inside the\n *  error handler).  If the error handler is not callable or throws an\n *  error, the resulting error replaces the original error (for Duktape\n *  internal errors, duk_error_throw.c further substitutes this error with\n *  a DoubleError which is not ideal).  This would be easy to change and\n *  even signal to the caller.\n *\n *  The user error handler is stored in 'Duktape.errCreate' or\n *  'Duktape.errThrow' depending on whether we're augmenting the error at\n *  creation or throw time.  There are several alternatives to this approach,\n *  see doc/error-objects.rst for discussion.\n *\n *  Note: since further longjmp()s may occur while calling the error handler\n *  (for many reasons, e.g. a labeled 'break' inside the handler), the\n *  caller can make no assumptions on the thr->heap->lj state after the\n *  call (this affects especially duk_error_throw.c).  This is not an issue\n *  as long as the caller writes to the lj state only after the error handler\n *  finishes.\n */\n\n#if defined(DUK_USE_ERRTHROW) || defined(DUK_USE_ERRCREATE)\nDUK_LOCAL void duk__err_augment_user(duk_hthread *thr, duk_small_uint_t stridx_cb) {\n\tduk_tval *tv_hnd;\n\tduk_int_t rc;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT_STRIDX_VALID(stridx_cb);\n\n\tif (thr->heap->augmenting_error) {\n\t\tDUK_D(DUK_DPRINT(\"recursive call to error augmentation, ignore\"));\n\t\treturn;\n\t}\n\n\t/*\n\t *  Check whether or not we have an error handler.\n\t *\n\t *  We must be careful of not triggering an error when looking up the\n\t *  property.  For instance, if the property is a getter, we don't want\n\t *  to call it, only plain values are allowed.  The value, if it exists,\n\t *  is not checked.  If the value is not a function, a TypeError happens\n\t *  when it is called and that error replaces the original one.\n\t */\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, 4);  /* 3 entries actually needed below */\n\n\t/* [ ... errval ] */\n\n\tif (thr->builtins[DUK_BIDX_DUKTAPE] == NULL) {\n\t\t/* When creating built-ins, some of the built-ins may not be set\n\t\t * and we want to tolerate that when throwing errors.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"error occurred when DUK_BIDX_DUKTAPE is NULL, ignoring\"));\n\t\treturn;\n\t}\n\ttv_hnd = duk_hobject_find_entry_tval_ptr_stridx(thr->heap,\n\t                                                thr->builtins[DUK_BIDX_DUKTAPE],\n\t                                                stridx_cb);\n\tif (tv_hnd == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"error handler does not exist or is not a plain value: %!T\",\n\t\t                   (duk_tval *) tv_hnd));\n\t\treturn;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"error handler dump (callability not checked): %!T\",\n\t                     (duk_tval *) tv_hnd));\n\tduk_push_tval(thr, tv_hnd);\n\n\t/* [ ... errval errhandler ] */\n\n\tduk_insert(thr, -2);  /* -> [ ... errhandler errval ] */\n\tduk_push_undefined(thr);\n\tduk_insert(thr, -2);  /* -> [ ... errhandler undefined(= this) errval ] */\n\n\t/* [ ... errhandler undefined errval ] */\n\n\t/*\n\t *  heap->augmenting_error prevents recursive re-entry and also causes\n\t *  call handling to use a larger (but not unbounded) call stack limit\n\t *  for the duration of error augmentation.\n\t *\n\t *  We ignore errors now: a success return and an error value both\n\t *  replace the original error value.  (This would be easy to change.)\n\t */\n\n\tDUK_ASSERT(thr->heap->augmenting_error == 0);\n\tthr->heap->augmenting_error = 1;\n\n\trc = duk_pcall_method(thr, 1);\n\tDUK_UNREF(rc);  /* no need to check now: both success and error are OK */\n\n\tDUK_ASSERT(thr->heap->augmenting_error == 1);\n\tthr->heap->augmenting_error = 0;\n\n\t/* [ ... errval ] */\n}\n#endif  /* DUK_USE_ERRTHROW || DUK_USE_ERRCREATE */\n\n/*\n *  Add ._Tracedata to an error on the stack top.\n */\n\n#if defined(DUK_USE_TRACEBACKS)\nDUK_LOCAL void duk__add_traceback(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {\n\tduk_activation *act;\n\tduk_int_t depth;\n\tduk_int_t arr_size;\n\tduk_tval *tv;\n\tduk_hstring *s;\n\tduk_uint32_t u32;\n\tduk_double_t d;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr_callstack != NULL);\n\n\t/* [ ... error ] */\n\n\t/*\n\t *  The traceback format is pretty arcane in an attempt to keep it compact\n\t *  and cheap to create.  It may change arbitrarily from version to version.\n\t *  It should be decoded/accessed through version specific accessors only.\n\t *\n\t *  See doc/error-objects.rst.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"adding traceback to object: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* Preallocate array to correct size, so that we can just write out\n\t * the _Tracedata values into the array part.\n\t */\n\tact = thr->callstack_curr;\n\tdepth = DUK_USE_TRACEBACK_DEPTH;\n\tDUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX);  /* callstack limits */\n\tif (depth > (duk_int_t) thr_callstack->callstack_top) {\n\t\tdepth = (duk_int_t) thr_callstack->callstack_top;\n\t}\n\tif (depth > 0) {\n\t\tif (flags & DUK_AUGMENT_FLAG_SKIP_ONE) {\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\tact = act->parent;\n\t\t\tdepth--;\n\t\t}\n\t}\n\tarr_size = depth * 2;\n\tif (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) {\n\t\tarr_size += 2;\n\t}\n\tif (c_filename) {\n\t\t/* We need the C filename to be interned before getting the\n\t\t * array part pointer to avoid any GC interference while the\n\t\t * array part is populated.\n\t\t */\n\t\tduk_push_string(thr, c_filename);\n\t\tarr_size += 2;\n\t}\n\n\t/* XXX: Uninitialized would be OK.  Maybe add internal primitive to\n\t * push bare duk_harray with size?\n\t */\n\tDUK_D(DUK_DPRINT(\"preallocated _Tracedata to %ld items\", (long) arr_size));\n\ttv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) arr_size);\n\tduk_clear_prototype(thr, -1);\n\tDUK_ASSERT(duk_is_bare_object(thr, -1));\n\tDUK_ASSERT(arr_size == 0 || tv != NULL);\n\n\t/* Compiler SyntaxErrors (and other errors) come first, and are\n\t * blamed by default (not flagged \"noblame\").\n\t */\n\tif (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) {\n\t\ts = thr->compile_ctx->h_filename;\n\t\tDUK_TVAL_SET_STRING(tv, s);\n\t\tDUK_HSTRING_INCREF(thr, s);\n\t\ttv++;\n\n\t\tu32 = (duk_uint32_t) thr->compile_ctx->curr_token.start_line;  /* (flags<<32) + (line), flags = 0 */\n\t\tDUK_TVAL_SET_U32(tv, u32);\n\t\ttv++;\n\t}\n\n\t/* Filename/line from C macros (__FILE__, __LINE__) are added as an\n\t * entry with a special format: (string, number).  The number contains\n\t * the line and flags.\n\t */\n\n\t/* [ ... error c_filename? arr ] */\n\n\tif (c_filename) {\n\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(thr->valstack_top - 2));\n\t\ts = DUK_TVAL_GET_STRING(thr->valstack_top - 2);  /* interned c_filename */\n\t\tDUK_ASSERT(s != NULL);\n\t\tDUK_TVAL_SET_STRING(tv, s);\n\t\tDUK_HSTRING_INCREF(thr, s);\n\t\ttv++;\n\n\t\td = ((flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE) ? ((duk_double_t) DUK_TB_FLAG_NOBLAME_FILELINE) * DUK_DOUBLE_2TO32 : 0.0) +\n\t\t    (duk_double_t) c_line;\n\t\tDUK_TVAL_SET_DOUBLE(tv, d);\n\t\ttv++;\n\t}\n\n\t/* Traceback depth doesn't take into account the filename/line\n\t * special handling above (intentional).\n\t */\n\tfor (; depth-- > 0; act = act->parent) {\n\t\tduk_uint32_t pc;\n\t\tduk_tval *tv_src;\n\n\t\t/* [... arr] */\n\n\t\tDUK_ASSERT(act != NULL);  /* depth check above, assumes book-keeping is correct */\n\t\tDUK_ASSERT_DISABLE(act->pc >= 0);  /* unsigned */\n\n\t\t/* Add function object. */\n\t\ttv_src = &act->tv_func;  /* object (function) or lightfunc */\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv_src) || DUK_TVAL_IS_LIGHTFUNC(tv_src));\n\t\tDUK_TVAL_SET_TVAL(tv, tv_src);\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\ttv++;\n\n\t\t/* Add a number containing: pc, activation flags.\n\t\t *\n\t\t * PC points to next instruction, find offending PC.  Note that\n\t\t * PC == 0 for native code.\n\t\t */\n\t\tpc = (duk_uint32_t) duk_hthread_get_act_prev_pc(thr_callstack, act);\n\t\tDUK_ASSERT_DISABLE(pc >= 0);  /* unsigned */\n\t\tDUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32);  /* assume PC is at most 32 bits and non-negative */\n\t\td = ((duk_double_t) act->flags) * DUK_DOUBLE_2TO32 + (duk_double_t) pc;\n\t\tDUK_TVAL_SET_DOUBLE(tv, d);\n\t\ttv++;\n\t}\n\n#if defined(DUK_USE_ASSERTIONS)\n\t{\n\t\tduk_harray *a;\n\t\ta = (duk_harray *) duk_known_hobject(thr, -1);\n\t\tDUK_ASSERT(a != NULL);\n\t\tDUK_ASSERT((duk_uint32_t) (tv - DUK_HOBJECT_A_GET_BASE(thr->heap, (duk_hobject *) a)) == a->length);\n\t\tDUK_ASSERT(a->length == (duk_uint32_t) arr_size);\n\t\tDUK_ASSERT(duk_is_bare_object(thr, -1));\n\t}\n#endif\n\n\t/* [ ... error c_filename? arr ] */\n\n\tif (c_filename) {\n\t\tduk_remove_m2(thr);\n\t}\n\n\t/* [ ... error arr ] */\n\n\tduk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INT_TRACEDATA);  /* -> [ ... error ] */\n}\n#endif  /* DUK_USE_TRACEBACKS */\n\n/*\n *  Add .fileName and .lineNumber to an error on the stack top.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE) && !defined(DUK_USE_TRACEBACKS)\nDUK_LOCAL void duk__add_fileline(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_int_t entry_top;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\n\t/*\n\t *  If tracebacks are disabled, 'fileName' and 'lineNumber' are added\n\t *  as plain own properties.  Since Error.prototype has accessors of\n\t *  the same name, we need to define own properties directly (cannot\n\t *  just use e.g. duk_put_prop_stridx).  Existing properties are not\n\t *  overwritten in case they already exist.\n\t */\n\n\tif (thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL) {\n\t\t/* Compiler SyntaxError (or other error) gets the primary blame.\n\t\t * Currently no flag to prevent blaming.\n\t\t */\n\t\tduk_push_uint(thr, (duk_uint_t) thr->compile_ctx->curr_token.start_line);\n\t\tduk_push_hstring(thr, thr->compile_ctx->h_filename);\n\t} else if (c_filename && (flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE) == 0) {\n\t\t/* C call site gets blamed next, unless flagged not to do so.\n\t\t * XXX: file/line is disabled in minimal builds, so disable this\n\t\t * too when appropriate.\n\t\t */\n\t\tduk_push_int(thr, c_line);\n\t\tduk_push_string(thr, c_filename);\n\t} else {\n\t\t/* Finally, blame the innermost callstack entry which has a\n\t\t * .fileName property.\n\t\t */\n\t\tduk_small_uint_t depth;\n\t\tduk_uint32_t ecma_line;\n\t\tduk_activation *act;\n\n\t\tDUK_ASSERT(thr_callstack->callstack_top <= DUK_INT_MAX);  /* callstack limits */\n\t\tdepth = DUK_USE_TRACEBACK_DEPTH;\n\t\tif (depth > thr_callstack->callstack_top) {\n\t\t\tdepth = thr_callstack->callstack_top;\n\t\t}\n\t\tfor (act = thr_callstack->callstack_curr; depth-- > 0; act = act->parent) {\n\t\t\tduk_hobject *func;\n\t\t\tduk_uint32_t pc;\n\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\tfunc = DUK_ACT_GET_FUNC(act);\n\t\t\tif (func == NULL) {\n\t\t\t\t/* Lightfunc, not blamed now. */\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* PC points to next instruction, find offending PC,\n\t\t\t * PC == 0 for native code.\n\t\t\t */\n\t\t\tpc = duk_hthread_get_act_prev_pc(thr, act);  /* thr argument only used for thr->heap, so specific thread doesn't matter */\n\t\t\tDUK_UNREF(pc);\n\t\t\tDUK_ASSERT_DISABLE(pc >= 0);  /* unsigned */\n\t\t\tDUK_ASSERT((duk_double_t) pc < DUK_DOUBLE_2TO32);  /* assume PC is at most 32 bits and non-negative */\n\n\t\t\tduk_push_hobject(thr, func);\n\n\t\t\t/* [ ... error func ] */\n\n\t\t\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_FILE_NAME);\n\t\t\tif (!duk_is_string_notsymbol(thr, -1)) {\n\t\t\t\tduk_pop_2(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* [ ... error func fileName ] */\n\n\t\t\tecma_line = 0;\n#if defined(DUK_USE_PC2LINE)\n\t\t\tif (DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\t\t\tecma_line = duk_hobject_pc2line_query(thr, -2, (duk_uint_fast32_t) pc);\n\t\t\t} else {\n\t\t\t\t/* Native function, no relevant lineNumber. */\n\t\t\t}\n#endif  /* DUK_USE_PC2LINE */\n\t\t\tduk_push_u32(thr, ecma_line);\n\n\t\t\t/* [ ... error func fileName lineNumber ] */\n\n\t\t\tduk_replace(thr, -3);\n\n\t\t\t/* [ ... error lineNumber fileName ] */\n\t\t\tgoto define_props;\n\t\t}\n\n\t\t/* No activation matches, use undefined for both .fileName and\n\t\t * .lineNumber (matches what we do with a _Tracedata based\n\t\t * no-match lookup.\n\t\t */\n\t\tduk_push_undefined(thr);\n\t\tduk_push_undefined(thr);\n\t}\n\n define_props:\n\t/* [ ... error lineNumber fileName ] */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(duk_get_top(thr) == entry_top + 2);\n#endif\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LINE_NUMBER, DUK_PROPDESC_FLAGS_C | DUK_PROPDESC_FLAG_NO_OVERWRITE);\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE && !DUK_USE_TRACEBACKS */\n\n/*\n *  Add line number to a compiler error.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_LOCAL void duk__add_compiler_error_line(duk_hthread *thr) {\n\n\t/* Append a \"(line NNN)\" to the \"message\" property of any error\n\t * thrown during compilation.  Usually compilation errors are\n\t * SyntaxErrors but they can also be out-of-memory errors and\n\t * the like.\n\t */\n\n\t/* [ ... error ] */\n\n\tDUK_ASSERT(duk_is_object(thr, -1));\n\n\tif (!(thr->compile_ctx != NULL && thr->compile_ctx->h_filename != NULL)) {\n\t\treturn;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"compile error, before adding line info: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tif (duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_MESSAGE)) {\n\t\tduk_push_sprintf(thr, \" (line %ld)\", (long) thr->compile_ctx->curr_token.start_line);\n\t\tduk_concat(thr, 2);\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_MESSAGE);\n\t} else {\n\t\tduk_pop(thr);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"compile error, after adding line info: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE */\n\n/*\n *  Augment an error being created using Duktape specific properties\n *  like _Tracedata or .fileName/.lineNumber.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_LOCAL void duk__err_augment_builtin_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_hobject *obj, duk_small_uint_t flags) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_int_t entry_top;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_UNREF(obj);  /* unreferenced w/o tracebacks */\n\n\tduk__add_compiler_error_line(thr);\n\n#if defined(DUK_USE_TRACEBACKS)\n\t/* If tracebacks are enabled, the '_Tracedata' property is the only\n\t * thing we need: 'fileName' and 'lineNumber' are virtual properties\n\t * which use '_Tracedata'.  (Check _Tracedata only as own property.)\n\t */\n\tif (duk_hobject_find_entry_tval_ptr_stridx(thr->heap, obj, DUK_STRIDX_INT_TRACEDATA) != NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"error value already has a '_Tracedata' property, not modifying it\"));\n\t} else {\n\t\tduk__add_traceback(thr, thr_callstack, c_filename, c_line, flags);\n\t}\n#else\n\t/* Without tracebacks the concrete .fileName and .lineNumber need\n\t * to be added directly.\n\t */\n\tduk__add_fileline(thr, thr_callstack, c_filename, c_line, flags);\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(duk_get_top(thr) == entry_top);\n#endif\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE */\n\n/*\n *  Augment an error at creation time with _Tracedata/fileName/lineNumber\n *  and allow a user error handler (if defined) to process/replace the error.\n *  The error to be augmented is at the stack top.\n *\n *  thr: thread containing the error value\n *  thr_callstack: thread which should be used for generating callstack etc.\n *  c_filename: C __FILE__ related to the error\n *  c_line: C __LINE__ related to the error\n *  flags & DUK_AUGMENT_FLAG_NOBLAME_FILELINE:\n *      if true, don't fileName/line as error source, otherwise use traceback\n *      (needed because user code filename/line are reported but internal ones\n *      are not)\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\nDUK_INTERNAL void duk_err_augment_error_create(duk_hthread *thr, duk_hthread *thr_callstack, const char *c_filename, duk_int_t c_line, duk_small_uint_t flags) {\n\tduk_hobject *obj;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr_callstack != NULL);\n\n\t/* [ ... error ] */\n\n\t/*\n\t *  Criteria for augmenting:\n\t *\n\t *   - augmentation enabled in build (naturally)\n\t *   - error value internal prototype chain contains the built-in\n\t *     Error prototype object (i.e. 'val instanceof Error')\n\t *\n\t *  Additional criteria for built-in augmenting:\n\t *\n\t *   - error value is an extensible object\n\t */\n\n\tobj = duk_get_hobject(thr, -1);\n\tif (!obj) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"value is not an object, skip both built-in and user augment\"));\n\t\treturn;\n\t}\n\tif (!duk_hobject_prototype_chain_contains(thr, obj, thr->builtins[DUK_BIDX_ERROR_PROTOTYPE], 1 /*ignore_loop*/)) {\n\t\t/* If the value has a prototype loop, it's critical not to\n\t\t * throw here.  Instead, assume the value is not to be\n\t\t * augmented.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"value is not an error instance, skip both built-in and user augment\"));\n\t\treturn;\n\t}\n\tif (DUK_HOBJECT_HAS_EXTENSIBLE(obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"error meets criteria, built-in augment\"));\n\t\tduk__err_augment_builtin_create(thr, thr_callstack, c_filename, c_line, obj, flags);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"error does not meet criteria, no built-in augment\"));\n\t}\n\n\t/* [ ... error ] */\n\n#if defined(DUK_USE_ERRCREATE)\n\tduk__err_augment_user(thr, DUK_STRIDX_ERR_CREATE);\n#endif\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_CREATE */\n\n/*\n *  Augment an error at throw time; allow a user error handler (if defined)\n *  to process/replace the error.  The error to be augmented is at the\n *  stack top.\n */\n\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\nDUK_INTERNAL void duk_err_augment_error_throw(duk_hthread *thr) {\n#if defined(DUK_USE_ERRTHROW)\n\tduk__err_augment_user(thr, DUK_STRIDX_ERR_THROW);\n#endif  /* DUK_USE_ERRTHROW */\n}\n#endif  /* DUK_USE_AUGMENT_ERROR_THROW */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_error_longjmp.c",
    "content": "/*\n *  Do a longjmp call, calling the fatal error handler if no\n *  catchpoint exists.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_PREFER_SIZE)\nDUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_minimal(duk_hthread *thr));\nDUK_LOCAL void duk__uncaught_minimal(duk_hthread *thr) {\n\t(void) duk_fatal(thr, \"uncaught error\");\n\tDUK_WO_NORETURN(return;);\n}\n#endif\n\n#if 0\nDUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_readable(duk_hthread *thr));\nDUK_LOCAL void duk__uncaught_readable(duk_hthread *thr) {\n\tconst char *summary;\n\tchar buf[DUK_USE_FATAL_MAXLEN];\n\n\tsummary = duk_push_string_tval_readable(thr, &thr->heap->lj.value1);\n\tDUK_SNPRINTF(buf, sizeof(buf), \"uncaught: %s\", summary);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\t(void) duk_fatal(thr, (const char *) buf);\n\tDUK_WO_NORETURN(return;);\n}\n#endif\n\n#if !defined(DUK_USE_PREFER_SIZE)\nDUK_NORETURN(DUK_LOCAL_DECL void duk__uncaught_error_aware(duk_hthread *thr));\nDUK_LOCAL void duk__uncaught_error_aware(duk_hthread *thr) {\n\tconst char *summary;\n\tchar buf[DUK_USE_FATAL_MAXLEN];\n\n\tsummary = duk_push_string_tval_readable_error(thr, &thr->heap->lj.value1);\n\tDUK_ASSERT(summary != NULL);\n\tDUK_SNPRINTF(buf, sizeof(buf), \"uncaught: %s\", summary);\n\tbuf[sizeof(buf) - 1] = (char) 0;\n\t(void) duk_fatal(thr, (const char *) buf);\n\tDUK_WO_NORETURN(return;);\n}\n#endif\n\nDUK_INTERNAL void duk_err_longjmp(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"longjmp error: type=%d iserror=%d value1=%!T value2=%!T\",\n\t                   (int) thr->heap->lj.type, (int) thr->heap->lj.iserror,\n\t                   &thr->heap->lj.value1, &thr->heap->lj.value2));\n\n\t/* Prevent finalizer execution during error handling.  All error\n\t * handling sites will process pending finalizers once error handling\n\t * is complete and we're ready for the side effects.  Does not prevent\n\t * refzero freeing or mark-and-sweep during error handling.\n\t *\n\t * NOTE: when we come here some calling code may have used DECREF\n\t * NORZ macros without an explicit DUK_REFZERO_CHECK_xxx() call.\n\t * We don't want to do it here because it would just check for\n\t * pending finalizers and we prevent that explicitly.  Instead,\n\t * the error catcher will run the finalizers once error handling\n\t * is complete.\n\t */\n\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\n\tthr->heap->pf_prevent_count++;\n\tDUK_ASSERT(thr->heap->pf_prevent_count != 0);  /* Wrap. */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* XXX: set this immediately when longjmp state is set */\n\tDUK_ASSERT(thr->heap->error_not_allowed == 0);  /* Detect error within critical section. */\n\tthr->heap->error_not_allowed = 1;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"about to longjmp, pf_prevent_count=%ld\", (long) thr->heap->pf_prevent_count));\n\n\t/* If we don't have a jmpbuf_ptr, there is little we can do except\n\t * cause a fatal error.  The caller's expectation is that we never\n\t * return.\n\t */\n\tif (!thr->heap->lj.jmpbuf_ptr) {\n\t\tDUK_D(DUK_DPRINT(\"uncaught error: type=%d iserror=%d value1=%!T value2=%!T\",\n\t\t                 (int) thr->heap->lj.type, (int) thr->heap->lj.iserror,\n\t\t                 &thr->heap->lj.value1, &thr->heap->lj.value2));\n\n#if defined(DUK_USE_PREFER_SIZE)\n\t\tduk__uncaught_minimal(thr);\n#else\n\t\tduk__uncaught_error_aware(thr);\n#endif\n\t\tDUK_UNREACHABLE();\n\t}\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\tthrow duk_internal_exception();  /* dummy */\n#else\n\tDUK_LONGJMP(thr->heap->lj.jmpbuf_ptr->jb);\n#endif\n\n\tDUK_UNREACHABLE();\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_error_macros.c",
    "content": "/*\n *  Error and fatal handling.\n */\n\n#include \"duk_internal.h\"\n\n#define DUK__ERRFMT_BUFSIZE  256  /* size for formatting buffers */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\nDUK_INTERNAL DUK_COLD void duk_err_handle_error_fmt(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *fmt, ...) {\n\tva_list ap;\n\tchar msg[DUK__ERRFMT_BUFSIZE];\n\tva_start(ap, fmt);\n\t(void) DUK_VSNPRINTF(msg, sizeof(msg), fmt, ap);\n\tmsg[sizeof(msg) - 1] = (char) 0;\n\tduk_err_create_and_throw(thr, (duk_errcode_t) (line_and_code >> 24), msg, filename, (duk_int_t) (line_and_code & 0x00ffffffL));\n\tva_end(ap);  /* dead code, but ensures portability (see Linux man page notes) */\n}\n\nDUK_INTERNAL DUK_COLD void duk_err_handle_error(duk_hthread *thr, const char *filename, duk_uint_t line_and_code, const char *msg) {\n\tduk_err_create_and_throw(thr, (duk_errcode_t) (line_and_code >> 24), msg, filename, (duk_int_t) (line_and_code & 0x00ffffffL));\n}\n\n#else  /* DUK_USE_VERBOSE_ERRORS */\n\nDUK_INTERNAL DUK_COLD void duk_err_handle_error(duk_hthread *thr, duk_errcode_t code) {\n\tduk_err_create_and_throw(thr, code);\n}\n\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n\n/*\n *  Error throwing helpers\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\nDUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) {\n\tDUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, \"%s required, found %s (stack index %ld)\",\n\t                   expect_name, duk_get_type_name(thr, idx), (long) idx);\n}\n#else\nDUK_INTERNAL DUK_COLD void duk_err_require_type_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx, const char *expect_name) {\n\tDUK_ERROR_RAW_FMT3(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, \"%s required, found %s (stack index %ld)\",\n\t                   expect_name, duk_push_string_readable(thr, idx), (long) idx);\n}\n#endif\nDUK_INTERNAL DUK_COLD void duk_err_error_internal(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, DUK_STR_INTERNAL_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_error_alloc_failed(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, DUK_STR_ALLOC_FAILED);\n}\nDUK_INTERNAL DUK_COLD void duk_err_error(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_ERROR, message);\n}\nDUK_INTERNAL DUK_COLD void duk_err_range(duk_hthread *thr, const char *filename, duk_int_t linenumber, const char *message) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, message);\n}\nDUK_INTERNAL DUK_COLD void duk_err_range_index(duk_hthread *thr, const char *filename, duk_int_t linenumber, duk_idx_t idx) {\n\tDUK_ERROR_RAW_FMT1(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, \"invalid stack index %ld\", (long) (idx));\n}\nDUK_INTERNAL DUK_COLD void duk_err_range_push_beyond(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_RANGE_ERROR, DUK_STR_PUSH_BEYOND_ALLOC_STACK);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type_invalid_args(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_ARGS);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type_invalid_state(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_STATE);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type_invalid_trap_result(duk_hthread *thr, const char *filename, duk_int_t linenumber) {\n\tDUK_ERROR_RAW(thr, filename, linenumber, DUK_ERR_TYPE_ERROR, DUK_STR_INVALID_TRAP_RESULT);\n}\n#else\n/* The file/line arguments are NULL and 0, they're ignored by DUK_ERROR_RAW()\n * when non-verbose errors are used.\n */\n\nDUK_NORETURN(DUK_LOCAL_DECL void duk__err_shared(duk_hthread *thr, duk_errcode_t code));\nDUK_LOCAL void duk__err_shared(duk_hthread *thr, duk_errcode_t code) {\n\tDUK_ERROR_RAW(thr, NULL, 0, code, NULL);\n}\nDUK_INTERNAL DUK_COLD void duk_err_error(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_range(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_RANGE_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_eval(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_EVAL_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_reference(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_REFERENCE_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_syntax(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_SYNTAX_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_type(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_TYPE_ERROR);\n}\nDUK_INTERNAL DUK_COLD void duk_err_uri(duk_hthread *thr) {\n\tduk__err_shared(thr, DUK_ERR_URI_ERROR);\n}\n#endif\n\n/*\n *  Default fatal error handler\n */\n\nDUK_INTERNAL DUK_COLD void duk_default_fatal_handler(void *udata, const char *msg) {\n\tDUK_UNREF(udata);\n\tDUK_UNREF(msg);\n\n\tmsg = msg ? msg : \"NULL\";\n\n#if defined(DUK_USE_FATAL_HANDLER)\n\t/* duk_config.h provided a custom default fatal handler. */\n\tDUK_D(DUK_DPRINT(\"custom default fatal error handler called: %s\", msg));\n\tDUK_USE_FATAL_HANDLER(udata, msg);\n#elif defined(DUK_USE_CPP_EXCEPTIONS)\n\t/* With C++ use a duk_fatal_exception which user code can catch in\n\t * a natural way.\n\t */\n\tDUK_D(DUK_DPRINT(\"built-in default C++ fatal error handler called: %s\", msg));\n\tthrow duk_fatal_exception(msg);\n#else\n\t/* Default behavior is to abort() on error.  There's no printout\n\t * which makes this awkward, so it's always recommended to use an\n\t * explicit fatal error handler.\n\t *\n\t * ====================================================================\n\t * NOTE: If you are seeing this, you are most likely dealing with an\n\t * uncaught error.  You should provide a fatal error handler in Duktape\n\t * heap creation, and should consider using a protected call as your\n\t * first call into an empty Duktape context to properly handle errors.\n\t * See:\n\t *   - http://duktape.org/guide.html#error-handling\n\t *   - http://wiki.duktape.org/HowtoFatalErrors.html\n\t *   - http://duktape.org/api.html#taglist-protected\n\t * ====================================================================\n\t */\n\tDUK_D(DUK_DPRINT(\"built-in default fatal error handler called: %s\", msg));\n\tDUK_ABORT();\n#endif\n\n\tDUK_D(DUK_DPRINT(\"fatal error handler returned, enter forever loop\"));\n\tfor (;;) {\n\t\t/* Loop forever to ensure we don't return. */\n\t}\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_error_misc.c",
    "content": "/*\n *  Error helpers\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Helper to walk the thread chain and see if there is an active error\n *  catcher.  Protected calls or finally blocks aren't considered catching.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_LOCAL duk_bool_t duk__have_active_catcher(duk_hthread *thr) {\n\t/* As noted above, a protected API call won't be counted as a\n\t * catcher.  This is usually convenient, e.g. in the case of a top-\n\t * level duk_pcall(), but may not always be desirable.  Perhaps add\n\t * an argument to treat them as catchers?\n\t */\n\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tfor (; thr != NULL; thr = thr->resumer) {\n\t\tfor (act = thr->callstack_curr; act != NULL; act = act->parent) {\n\t\t\tfor (cat = act->cat; cat != NULL; cat = cat->parent) {\n\t\t\t\tif (DUK_CAT_HAS_CATCH_ENABLED(cat)) {\n\t\t\t\t\treturn 1;  /* all we need to know */\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn 0;\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/*\n *  Get prototype object for an integer error code.\n */\n\nDUK_INTERNAL duk_hobject *duk_error_prototype_from_code(duk_hthread *thr, duk_errcode_t code) {\n\tswitch (code) {\n\tcase DUK_ERR_EVAL_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_EVAL_ERROR_PROTOTYPE];\n\tcase DUK_ERR_RANGE_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_RANGE_ERROR_PROTOTYPE];\n\tcase DUK_ERR_REFERENCE_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_REFERENCE_ERROR_PROTOTYPE];\n\tcase DUK_ERR_SYNTAX_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_SYNTAX_ERROR_PROTOTYPE];\n\tcase DUK_ERR_TYPE_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_TYPE_ERROR_PROTOTYPE];\n\tcase DUK_ERR_URI_ERROR:\n\t\treturn thr->builtins[DUK_BIDX_URI_ERROR_PROTOTYPE];\n\tcase DUK_ERR_ERROR:\n\tdefault:\n\t\treturn thr->builtins[DUK_BIDX_ERROR_PROTOTYPE];\n\t}\n}\n\n/*\n *  Helper for debugger throw notify and pause-on-uncaught integration.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL void duk_err_check_debugger_integration(duk_hthread *thr) {\n\tduk_bool_t uncaught;\n\tduk_tval *tv_obj;\n\n\t/* If something is thrown with the debugger attached and nobody will\n\t * catch it, execution is paused before the longjmp, turning over\n\t * control to the debug client.  This allows local state to be examined\n\t * before the stack is unwound.  Errors are not intercepted when debug\n\t * message loop is active (e.g. for Eval).\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\t/* XXX: Allow customizing the pause and notify behavior at runtime\n\t * using debugger runtime flags.  For now the behavior is fixed using\n\t * config options.\n\t */\n\n\tif (!duk_debug_is_attached(thr->heap) ||\n\t    thr->heap->dbg_processing ||\n\t    thr->heap->lj.type != DUK_LJ_TYPE_THROW ||\n\t    thr->heap->creating_error) {\n\t\tDUK_D(DUK_DPRINT(\"skip debugger error integration; not attached, debugger processing, not THROW, or error thrown while creating error\"));\n\t\treturn;\n\t}\n\n\t/* Don't intercept a DoubleError, we may have caused the initial double\n\t * fault and attempting to intercept it will cause us to be called\n\t * recursively and exhaust the C stack.  (This should no longer happen\n\t * for the initial throw because DoubleError path doesn't do a debugger\n\t * integration check, but it might happen for rethrows.)\n\t */\n\ttv_obj = &thr->heap->lj.value1;\n\tif (DUK_TVAL_IS_OBJECT(tv_obj) && DUK_TVAL_GET_OBJECT(tv_obj) == thr->builtins[DUK_BIDX_DOUBLE_ERROR]) {\n\t\tDUK_D(DUK_DPRINT(\"built-in DoubleError instance (re)thrown, not intercepting\"));\n\t\treturn;\n\t}\n\n\tuncaught = !duk__have_active_catcher(thr);\n\n\t/* Debugger code expects the value at stack top.  This also serves\n\t * as a backup: we need to store/restore the longjmp state because\n\t * when the debugger is paused Eval commands may be executed and\n\t * they can arbitrarily clobber the longjmp state.\n\t */\n\tduk_push_tval(thr, tv_obj);\n\n\t/* Store and reset longjmp state. */\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\tDUK_TVAL_DECREF_NORZ(thr, tv_obj);\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value2));  /* Always for THROW type. */\n\tDUK_TVAL_SET_UNDEFINED(tv_obj);\n\tthr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n#if defined(DUK_USE_DEBUGGER_THROW_NOTIFY)\n\t/* Report it to the debug client */\n\tDUK_D(DUK_DPRINT(\"throw with debugger attached, report to client\"));\n\tduk_debug_send_throw(thr, uncaught);\n#endif\n\n\tif (uncaught) {\n\t\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_UNCAUGHT_ERROR) {\n\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by uncaught error\"));\n\t\t\tduk_debug_halt_execution(thr, 1 /*use_prev_pc*/);\n\t\t}\n\t} else {\n\t\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_CAUGHT_ERROR) {\n\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by caught error\"));\n\t\t\tduk_debug_halt_execution(thr, 1 /*use_prev_pc*/);\n\t\t}\n\t}\n\n\t/* Restore longjmp state. */\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\tthr->heap->lj.type = DUK_LJ_TYPE_THROW;\n\ttv_obj = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value1));\n\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&thr->heap->lj.value2));\n\tDUK_TVAL_SET_TVAL(&thr->heap->lj.value1, tv_obj);\n\tDUK_TVAL_INCREF(thr, tv_obj);\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\n\tduk_pop(thr);\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/*\n *  Helpers for setting up heap longjmp state.\n */\n\nDUK_INTERNAL void duk_err_setup_ljstate1(duk_hthread *thr, duk_small_uint_t lj_type, duk_tval *tv_val) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\theap = thr->heap;\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(tv_val != NULL);\n\n\tDUK_ASSERT_LJSTATE_UNSET(heap);\n\n\theap->lj.type = lj_type;\n\tDUK_TVAL_SET_TVAL(&heap->lj.value1, tv_val);\n\tDUK_TVAL_INCREF(thr, tv_val);\n\n\tDUK_ASSERT_LJSTATE_SET(heap);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_error_throw.c",
    "content": "/*\n *  Create and throw an ECMAScript error object based on a code and a message.\n *\n *  Used when we throw errors internally.  ECMAScript generated error objects\n *  are created by ECMAScript code, and the throwing is handled by the bytecode\n *  executor.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Create and throw an error (originating from Duktape internally)\n *\n *  Push an error object on top of the stack, possibly throw augmenting\n *  the error, and finally longjmp.\n *\n *  If an error occurs while we're dealing with the current error, we might\n *  enter an infinite recursion loop.  This is prevented by detecting a\n *  \"double fault\" through the heap->creating_error flag; the recursion\n *  then stops at the second level.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code, const char *msg, const char *filename, duk_int_t line) {\n#else\nDUK_INTERNAL void duk_err_create_and_throw(duk_hthread *thr, duk_errcode_t code) {\n#endif\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\tDUK_DD(DUK_DDPRINT(\"duk_err_create_and_throw(): code=%ld, msg=%s, filename=%s, line=%ld\",\n\t                   (long) code, (const char *) msg,\n\t                   (const char *) filename, (long) line));\n#else\n\tDUK_DD(DUK_DDPRINT(\"duk_err_create_and_throw(): code=%ld\", (long) code));\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Even though nested call is possible because we throw an error when\n\t * trying to create an error, the potential errors must happen before\n\t * the longjmp state is configured.\n\t */\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\t/* Sync so that augmentation sees up-to-date activations, NULL\n\t * thr->ptr_curr_pc so that it's not used if side effects occur\n\t * in augmentation or longjmp handling.\n\t */\n\tduk_hthread_sync_and_null_currpc(thr);\n\n\t/*\n\t *  Create and push an error object onto the top of stack.\n\t *  The error is potentially augmented before throwing.\n\t *\n\t *  If a \"double error\" occurs, use a fixed error instance\n\t *  to avoid further trouble.\n\t */\n\n\tif (thr->heap->creating_error) {\n\t\tduk_tval tv_val;\n\t\tduk_hobject *h_err;\n\n\t\tthr->heap->creating_error = 0;\n\n\t\th_err = thr->builtins[DUK_BIDX_DOUBLE_ERROR];\n\t\tif (h_err != NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"double fault detected -> use built-in fixed 'double error' instance\"));\n\t\t\tDUK_TVAL_SET_OBJECT(&tv_val, h_err);\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"double fault detected; there is no built-in fixed 'double error' instance \"\n\t\t\t                 \"-> use the error code as a number\"));\n\t\t\tDUK_TVAL_SET_I32(&tv_val, (duk_int32_t) code);\n\t\t}\n\n\t\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, &tv_val);\n\n\t\t/* No augmentation to avoid any allocations or side effects. */\n\t} else {\n\t\t/* Prevent infinite recursion.  Extra call stack and C\n\t\t * recursion headroom (see GH-191) is added for augmentation.\n\t\t * That is now signalled by heap->augmenting error and taken\n\t\t * into account in call handling without an explicit limit bump.\n\t\t */\n\t\tthr->heap->creating_error = 1;\n\n\t\tduk_require_stack(thr, 1);\n\n\t\t/* XXX: usually unnecessary '%s' formatting here, but cannot\n\t\t * use 'msg' as a format string directly.\n\t\t */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\tduk_push_error_object_raw(thr,\n\t\t                          code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t\t                          filename,\n\t\t                          line,\n\t\t                          \"%s\",\n\t\t                          (const char *) msg);\n#else\n\t\tduk_push_error_object_raw(thr,\n\t\t                          code | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t\t                          NULL,\n\t\t                          0,\n\t\t                          NULL);\n#endif\n\n\t\t/* Note that an alloc error may happen during error augmentation.\n\t\t * This may happen both when the original error is an alloc error\n\t\t * and when it's something else.  Because any error in augmentation\n\t\t * must be handled correctly anyway, there's no special check for\n\t\t * avoiding it for alloc errors (this differs from Duktape 1.x).\n\t\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\t\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (INTERNAL): %!iT (before throw augment)\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\tduk_err_augment_error_throw(thr);\n#endif\n\n\t\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, DUK_GET_TVAL_NEGIDX(thr, -1));\n\t\tthr->heap->creating_error = 0;\n\n\t\t/* Error is now created and we assume no errors can occur any\n\t\t * more.  Check for debugger Throw integration only when the\n\t\t * error is complete.  If we enter debugger message loop,\n\t\t * creating_error must be 0 so that errors can be thrown in\n\t\t * the paused state, e.g. in Eval commands.\n\t\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tduk_err_check_debugger_integration(thr);\n#endif\n\t}\n\n\t/*\n\t *  Finally, longjmp\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (INTERNAL): %!iT, %!iT (after throw augment)\",\n\t                     (duk_tval *) &thr->heap->lj.value1, (duk_tval *) &thr->heap->lj.value2));\n\n\tduk_err_longjmp(thr);\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  Helper for C function call negative return values.\n */\n\nDUK_INTERNAL void duk_error_throw_from_negative_rc(duk_hthread *thr, duk_ret_t rc) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(rc < 0);\n\n\t/*\n\t *  The __FILE__ and __LINE__ information is intentionally not used in the\n\t *  creation of the error object, as it isn't useful in the tracedata.  The\n\t *  tracedata still contains the function which returned the negative return\n\t *  code, and having the file/line of this function isn't very useful.\n\t *\n\t *  The error messages for DUK_RET_xxx shorthand are intentionally very\n\t *  minimal: they're only really useful for low memory targets.\n\t */\n\n\tduk_error_raw(thr, -rc, NULL, 0, \"error (rc %ld)\", (long) rc);\n\tDUK_WO_NORETURN(return;);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_exception.h",
    "content": "/*\n *  Exceptions for Duktape internal throws when C++ exceptions are used\n *  for long control transfers.\n */\n\n#if !defined(DUK_EXCEPTION_H_INCLUDED)\n#define DUK_EXCEPTION_H_INCLUDED\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n/* Internal exception used as a setjmp-longjmp replacement.  User code should\n * NEVER see or catch this exception, so it doesn't inherit from any base\n * class which should minimize the chance of user code accidentally catching\n * the exception.\n */\nclass duk_internal_exception {\n\t/* intentionally empty */\n};\n\n/* Fatal error, thrown as a specific C++ exception with C++ exceptions\n * enabled.  It is unsafe to continue; doing so may cause crashes or memory\n * leaks.  This is intended to be either uncaught, or caught by user code\n * aware of the \"unsafe to continue\" semantics.\n */\nclass duk_fatal_exception : public virtual std::runtime_error {\n public:\n\tduk_fatal_exception(const char *message) : std::runtime_error(message) {}\n};\n#endif\n\n#endif  /* DUK_EXCEPTION_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_forwdecl.h",
    "content": "/*\n *  Forward declarations for all Duktape structures.\n */\n\n#if !defined(DUK_FORWDECL_H_INCLUDED)\n#define DUK_FORWDECL_H_INCLUDED\n\n/*\n *  Forward declarations\n */\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\nclass duk_internal_exception;\n#else\nstruct duk_jmpbuf;\n#endif\n\n/* duk_tval intentionally skipped */\nstruct duk_heaphdr;\nstruct duk_heaphdr_string;\nstruct duk_harray;\nstruct duk_hstring;\nstruct duk_hstring_external;\nstruct duk_hobject;\nstruct duk_hcompfunc;\nstruct duk_hnatfunc;\nstruct duk_hboundfunc;\nstruct duk_hthread;\nstruct duk_hbufobj;\nstruct duk_hdecenv;\nstruct duk_hobjenv;\nstruct duk_hproxy;\nstruct duk_hbuffer;\nstruct duk_hbuffer_fixed;\nstruct duk_hbuffer_dynamic;\nstruct duk_hbuffer_external;\n\nstruct duk_propaccessor;\nunion duk_propvalue;\nstruct duk_propdesc;\n\nstruct duk_heap;\nstruct duk_breakpoint;\n\nstruct duk_activation;\nstruct duk_catcher;\nstruct duk_ljstate;\nstruct duk_strcache_entry;\nstruct duk_litcache_entry;\nstruct duk_strtab_entry;\n\n#if defined(DUK_USE_DEBUG)\nstruct duk_fixedbuffer;\n#endif\n\nstruct duk_bitdecoder_ctx;\nstruct duk_bitencoder_ctx;\nstruct duk_bufwriter_ctx;\n\nstruct duk_token;\nstruct duk_re_token;\nstruct duk_lexer_point;\nstruct duk_lexer_ctx;\nstruct duk_lexer_codepoint;\n\nstruct duk_compiler_instr;\nstruct duk_compiler_func;\nstruct duk_compiler_ctx;\n\nstruct duk_re_matcher_ctx;\nstruct duk_re_compiler_ctx;\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n/* no typedef */\n#else\ntypedef struct duk_jmpbuf duk_jmpbuf;\n#endif\n\n/* duk_tval intentionally skipped */\ntypedef struct duk_heaphdr duk_heaphdr;\ntypedef struct duk_heaphdr_string duk_heaphdr_string;\ntypedef struct duk_harray duk_harray;\ntypedef struct duk_hstring duk_hstring;\ntypedef struct duk_hstring_external duk_hstring_external;\ntypedef struct duk_hobject duk_hobject;\ntypedef struct duk_hcompfunc duk_hcompfunc;\ntypedef struct duk_hnatfunc duk_hnatfunc;\ntypedef struct duk_hboundfunc duk_hboundfunc;\ntypedef struct duk_hthread duk_hthread;\ntypedef struct duk_hbufobj duk_hbufobj;\ntypedef struct duk_hdecenv duk_hdecenv;\ntypedef struct duk_hobjenv duk_hobjenv;\ntypedef struct duk_hproxy duk_hproxy;\ntypedef struct duk_hbuffer duk_hbuffer;\ntypedef struct duk_hbuffer_fixed duk_hbuffer_fixed;\ntypedef struct duk_hbuffer_dynamic duk_hbuffer_dynamic;\ntypedef struct duk_hbuffer_external duk_hbuffer_external;\n\ntypedef struct duk_propaccessor duk_propaccessor;\ntypedef union duk_propvalue duk_propvalue;\ntypedef struct duk_propdesc duk_propdesc;\n\ntypedef struct duk_heap duk_heap;\ntypedef struct duk_breakpoint duk_breakpoint;\n\ntypedef struct duk_activation duk_activation;\ntypedef struct duk_catcher duk_catcher;\ntypedef struct duk_ljstate duk_ljstate;\ntypedef struct duk_strcache_entry duk_strcache_entry;\ntypedef struct duk_litcache_entry duk_litcache_entry;\ntypedef struct duk_strtab_entry duk_strtab_entry;\n\n#if defined(DUK_USE_DEBUG)\ntypedef struct duk_fixedbuffer duk_fixedbuffer;\n#endif\n\ntypedef struct duk_bitdecoder_ctx duk_bitdecoder_ctx;\ntypedef struct duk_bitencoder_ctx duk_bitencoder_ctx;\ntypedef struct duk_bufwriter_ctx duk_bufwriter_ctx;\n\ntypedef struct duk_token duk_token;\ntypedef struct duk_re_token duk_re_token;\ntypedef struct duk_lexer_point duk_lexer_point;\ntypedef struct duk_lexer_ctx duk_lexer_ctx;\ntypedef struct duk_lexer_codepoint duk_lexer_codepoint;\n\ntypedef struct duk_compiler_instr duk_compiler_instr;\ntypedef struct duk_compiler_func duk_compiler_func;\ntypedef struct duk_compiler_ctx duk_compiler_ctx;\n\ntypedef struct duk_re_matcher_ctx duk_re_matcher_ctx;\ntypedef struct duk_re_compiler_ctx duk_re_compiler_ctx;\n\n#endif  /* DUK_FORWDECL_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_harray.h",
    "content": "/*\n *  Array object representation, used for actual Array instances.\n *\n *  All objects with the exotic array behavior (which must coincide with having\n *  internal class array) MUST be duk_harrays.  No other object can be a\n *  duk_harray.  However, duk_harrays may not always have an array part.\n */\n\n#if !defined(DUK_HARRAY_H_INCLUDED)\n#define DUK_HARRAY_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_harray_assert_valid(duk_harray *h);\n#define DUK_HARRAY_ASSERT_VALID(h)  do { duk_harray_assert_valid((h)); } while (0)\n#else\n#define DUK_HARRAY_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n#define DUK_HARRAY_LENGTH_WRITABLE(h)         (!(h)->length_nonwritable)\n#define DUK_HARRAY_LENGTH_NONWRITABLE(h)      ((h)->length_nonwritable)\n#define DUK_HARRAY_SET_LENGTH_WRITABLE(h)     do { (h)->length_nonwritable = 0; } while (0)\n#define DUK_HARRAY_SET_LENGTH_NONWRITABLE(h)  do { (h)->length_nonwritable = 1; } while (0)\n\nstruct duk_harray {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Array .length.\n\t *\n\t * At present Array .length may be smaller, equal, or even larger\n\t * than the allocated underlying array part.  Fast path code must\n\t * always take this into account carefully.\n\t */\n\tduk_uint32_t length;\n\n\t/* Array .length property attributes.  The property is always\n\t * non-enumerable and non-configurable.  It's initially writable\n\t * but per Object.defineProperty() rules it can be made non-writable\n\t * even if it is non-configurable.  Thus we need to track the\n\t * writability explicitly.\n\t *\n\t * XXX: this field to be eliminated and moved into duk_hobject\n\t * flags field to save space.\n\t */\n\tduk_bool_t length_nonwritable;\n};\n\n#endif  /* DUK_HARRAY_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hboundfunc.h",
    "content": "/*\n *  Bound function representation.\n */\n\n#if !defined(DUK_HBOUNDFUNC_H_INCLUDED)\n#define DUK_HBOUNDFUNC_H_INCLUDED\n\n/* Artificial limit for args length.  Ensures arithmetic won't overflow\n * 32 bits when combining bound functions.\n */\n#define DUK_HBOUNDFUNC_MAX_ARGS 0x20000000UL\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hboundfunc_assert_valid(duk_hboundfunc *h);\n#define DUK_HBOUNDFUNC_ASSERT_VALID(h)  do { duk_hboundfunc_assert_valid((h)); } while (0)\n#else\n#define DUK_HBOUNDFUNC_ASSERT_VALID(h)  do {} while (0)\n#endif\n\nstruct duk_hboundfunc {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Final target function, stored as duk_tval so that lightfunc can be\n\t * represented too.\n\t */\n\tduk_tval target;\n\n\t/* This binding. */\n\tduk_tval this_binding;\n\n\t/* Arguments to prepend. */\n\tduk_tval *args;  /* Separate allocation. */\n\tduk_idx_t nargs;\n};\n\n#endif  /* DUK_HBOUNDFUNC_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hbuffer.h",
    "content": "/*\n *  Heap buffer representation.\n *\n *  Heap allocated user data buffer which is either:\n *\n *    1. A fixed size buffer (data follows header statically)\n *    2. A dynamic size buffer (data pointer follows header)\n *\n *  The data pointer for a variable size buffer of zero size may be NULL.\n */\n\n#if !defined(DUK_HBUFFER_H_INCLUDED)\n#define DUK_HBUFFER_H_INCLUDED\n\n/*\n *  Flags\n *\n *  Fixed buffer:     0\n *  Dynamic buffer:   DUK_HBUFFER_FLAG_DYNAMIC\n *  External buffer:  DUK_HBUFFER_FLAG_DYNAMIC | DUK_HBUFFER_FLAG_EXTERNAL\n */\n\n#define DUK_HBUFFER_FLAG_DYNAMIC                  DUK_HEAPHDR_USER_FLAG(0)    /* buffer is behind a pointer, dynamic or external */\n#define DUK_HBUFFER_FLAG_EXTERNAL                 DUK_HEAPHDR_USER_FLAG(1)    /* buffer pointer is to an externally allocated buffer */\n\n#define DUK_HBUFFER_HAS_DYNAMIC(x)                DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)\n#define DUK_HBUFFER_HAS_EXTERNAL(x)               DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL)\n\n#define DUK_HBUFFER_SET_DYNAMIC(x)                DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)\n#define DUK_HBUFFER_SET_EXTERNAL(x)               DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL)\n\n#define DUK_HBUFFER_CLEAR_DYNAMIC(x)              DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_DYNAMIC)\n#define DUK_HBUFFER_CLEAR_EXTERNAL(x)             DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HBUFFER_FLAG_EXTERNAL)\n\n/*\n *  Misc defines\n */\n\n/* Impose a maximum buffer length for now.  Restricted artificially to\n * ensure resize computations or adding a heap header length won't\n * overflow size_t and that a signed duk_int_t can hold a buffer\n * length.  The limit should be synchronized with DUK_HSTRING_MAX_BYTELEN.\n */\n\n#if defined(DUK_USE_BUFLEN16)\n#define DUK_HBUFFER_MAX_BYTELEN                   (0x0000ffffUL)\n#else\n/* Intentionally not 0x7fffffffUL; at least JSON code expects that\n * 2*len + 2 fits in 32 bits.\n */\n#define DUK_HBUFFER_MAX_BYTELEN                   (0x7ffffffeUL)\n#endif\n\n/*\n *  Field access\n */\n\n#if defined(DUK_USE_BUFLEN16)\n/* size stored in duk_heaphdr unused flag bits */\n#define DUK_HBUFFER_GET_SIZE(x)     ((x)->hdr.h_flags >> 16)\n#define DUK_HBUFFER_SET_SIZE(x,v)   do { \\\n\t\tduk_size_t duk__v; \\\n\t\tduk__v = (v); \\\n\t\tDUK_ASSERT(duk__v <= 0xffffUL); \\\n\t\t(x)->hdr.h_flags = ((x)->hdr.h_flags & 0x0000ffffUL) | (((duk_uint32_t) duk__v) << 16); \\\n\t} while (0)\n#define DUK_HBUFFER_ADD_SIZE(x,dv)  do { \\\n\t\t(x)->hdr.h_flags += ((dv) << 16); \\\n\t} while (0)\n#define DUK_HBUFFER_SUB_SIZE(x,dv)  do { \\\n\t\t(x)->hdr.h_flags -= ((dv) << 16); \\\n\t} while (0)\n#else\n#define DUK_HBUFFER_GET_SIZE(x)     (((duk_hbuffer *) (x))->size)\n#define DUK_HBUFFER_SET_SIZE(x,v)   do { \\\n\t\t((duk_hbuffer *) (x))->size = (v); \\\n\t} while (0)\n#define DUK_HBUFFER_ADD_SIZE(x,dv)  do { \\\n\t\t(x)->size += (dv); \\\n\t} while (0)\n#define DUK_HBUFFER_SUB_SIZE(x,dv)  do { \\\n\t\t(x)->size -= (dv); \\\n\t} while (0)\n#endif\n\n#define DUK_HBUFFER_FIXED_GET_SIZE(x)       DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x))\n#define DUK_HBUFFER_FIXED_SET_SIZE(x,v)     DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x))\n\n#define DUK_HBUFFER_DYNAMIC_GET_SIZE(x)     DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x))\n#define DUK_HBUFFER_DYNAMIC_SET_SIZE(x,v)   DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x), (v))\n#define DUK_HBUFFER_DYNAMIC_ADD_SIZE(x,dv)  DUK_HBUFFER_ADD_SIZE((duk_hbuffer *) (x), (dv))\n#define DUK_HBUFFER_DYNAMIC_SUB_SIZE(x,dv)  DUK_HBUFFER_SUB_SIZE((duk_hbuffer *) (x), (dv))\n\n#define DUK_HBUFFER_EXTERNAL_GET_SIZE(x)    DUK_HBUFFER_GET_SIZE((duk_hbuffer *) (x))\n#define DUK_HBUFFER_EXTERNAL_SET_SIZE(x,v)  DUK_HBUFFER_SET_SIZE((duk_hbuffer *) (x), (v))\n\n#define DUK_HBUFFER_FIXED_GET_DATA_PTR(heap,x)    ((duk_uint8_t *) (((duk_hbuffer_fixed *) (void *) (x)) + 1))\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap,x) \\\n\t((void *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, ((duk_heaphdr *) (x))->h_extra16))\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t((duk_heaphdr *) (x))->h_extra16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t((duk_heaphdr *) (x))->h_extra16 = 0;  /* assume 0 <=> NULL */ \\\n\t} while (0)\n#else\n#define DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap,x)       ((x)->curr_alloc)\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t(x)->curr_alloc = (void *) (v); \\\n\t} while (0)\n#define DUK_HBUFFER_DYNAMIC_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t(x)->curr_alloc = (void *) NULL; \\\n\t} while (0)\n#endif\n\n/* No pointer compression because pointer is potentially outside of\n * Duktape heap.\n */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap,x) \\\n\t((void *) (x)->curr_alloc)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t(x)->curr_alloc = (void *) (v); \\\n\t} while (0)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t(x)->curr_alloc = (void *) NULL; \\\n\t} while (0)\n#else\n#define DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap,x) \\\n\t((void *) (x)->curr_alloc)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap,x,v)     do { \\\n\t\t(x)->curr_alloc = (void *) (v); \\\n\t} while (0)\n#define DUK_HBUFFER_EXTERNAL_SET_DATA_PTR_NULL(heap,x)  do { \\\n\t\t(x)->curr_alloc = (void *) NULL; \\\n\t} while (0)\n#endif\n\n/* Get a pointer to the current buffer contents (matching current allocation\n * size).  May be NULL for zero size dynamic/external buffer.\n */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HBUFFER_GET_DATA_PTR(heap,x)  ( \\\n\tDUK_HBUFFER_HAS_DYNAMIC((x)) ? \\\n\t\t( \\\n\t\t\tDUK_HBUFFER_HAS_EXTERNAL((x)) ? \\\n\t\t\t\tDUK_HBUFFER_EXTERNAL_GET_DATA_PTR((heap), (duk_hbuffer_external *) (x)) : \\\n\t\t\t\tDUK_HBUFFER_DYNAMIC_GET_DATA_PTR((heap), (duk_hbuffer_dynamic *) (x)) \\\n\t\t) : \\\n\t\tDUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (void *) (x)) \\\n\t)\n#else\n/* Without heap pointer compression duk_hbuffer_dynamic and duk_hbuffer_external\n * have the same layout so checking for fixed vs. dynamic (or external) is enough.\n */\n#define DUK_HBUFFER_GET_DATA_PTR(heap,x)  ( \\\n\tDUK_HBUFFER_HAS_DYNAMIC((x)) ? \\\n\t\tDUK_HBUFFER_DYNAMIC_GET_DATA_PTR((heap), (duk_hbuffer_dynamic *) (x)) : \\\n\t\tDUK_HBUFFER_FIXED_GET_DATA_PTR((heap), (duk_hbuffer_fixed *) (void *) (x)) \\\n\t)\n#endif\n\n/* Validity assert. */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hbuffer_assert_valid(duk_hbuffer *h);\n#define DUK_HBUFFER_ASSERT_VALID(h)  do { duk_hbuffer_assert_valid((h)); } while (0)\n#else\n#define DUK_HBUFFER_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Structs\n */\n\n/* Shared prefix for all buffer types. */\nstruct duk_hbuffer {\n\tduk_heaphdr hdr;\n\n\t/* It's not strictly necessary to track the current size, but\n\t * it is useful for writing robust native code.\n\t */\n\n\t/* Current size. */\n#if defined(DUK_USE_BUFLEN16)\n\t/* Stored in duk_heaphdr unused flags. */\n#else\n\tduk_size_t size;\n#endif\n\n\t/*\n\t *  Data following the header depends on the DUK_HBUFFER_FLAG_DYNAMIC\n\t *  flag.\n\t *\n\t *  If the flag is clear (the buffer is a fixed size one), the buffer\n\t *  data follows the header directly, consisting of 'size' bytes.\n\t *\n\t *  If the flag is set, the actual buffer is allocated separately, and\n\t *  a few control fields follow the header.  Specifically:\n\t *\n\t *    - a \"void *\" pointing to the current allocation\n\t *    - a duk_size_t indicating the full allocated size (always >= 'size')\n\t *\n\t *  If DUK_HBUFFER_FLAG_EXTERNAL is set, the buffer has been allocated\n\t *  by user code, so that Duktape won't be able to resize it and won't\n\t *  free it.  This allows buffers to point to e.g. an externally\n\t *  allocated structure such as a frame buffer.\n\t *\n\t *  Unlike strings, no terminator byte (NUL) is guaranteed after the\n\t *  data.  This would be convenient, but would pad aligned user buffers\n\t *  unnecessarily upwards in size.  For instance, if user code requested\n\t *  a 64-byte dynamic buffer, 65 bytes would actually be allocated which\n\t *  would then potentially round upwards to perhaps 68 or 72 bytes.\n\t */\n};\n\n/* Fixed buffer; data follows struct, with proper alignment guaranteed by\n * struct size.\n */\n#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)\n#pragma pack(push, 8)\n#endif\nstruct duk_hbuffer_fixed {\n\t/* A union is used here as a portable struct size / alignment trick:\n\t * by adding a 32-bit or a 64-bit (unused) union member, the size of\n\t * the struct is effectively forced to be a multiple of 4 or 8 bytes\n\t * (respectively) without increasing the size of the struct unless\n\t * necessary.\n\t */\n\tunion {\n\t\tstruct {\n\t\t\tduk_heaphdr hdr;\n#if defined(DUK_USE_BUFLEN16)\n\t\t\t/* Stored in duk_heaphdr unused flags. */\n#else\n\t\t\tduk_size_t size;\n#endif\n\t\t} s;\n#if (DUK_USE_ALIGN_BY == 4)\n\t\tduk_uint32_t dummy_for_align4;\n#elif (DUK_USE_ALIGN_BY == 8)\n\t\tduk_double_t dummy_for_align8_1;\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_uint64_t dummy_for_align8_2;\n#endif\n#elif (DUK_USE_ALIGN_BY == 1)\n\t\t/* no extra padding */\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\t} u;\n\n\t/*\n\t *  Data follows the struct header.  The struct size is padded by the\n\t *  compiler based on the struct members.  This guarantees that the\n\t *  buffer data will be aligned-by-4 but not necessarily aligned-by-8.\n\t *\n\t *  On platforms where alignment does not matter, the struct padding\n\t *  could be removed (if there is any).  On platforms where alignment\n\t *  by 8 is required, the struct size must be forced to be a multiple\n\t *  of 8 by some means.  Without it, some user code may break, and also\n\t *  Duktape itself breaks (e.g. the compiler stores duk_tvals in a\n\t *  dynamic buffer).\n\t */\n}\n#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_GCC_ATTR)\n__attribute__ ((aligned (8)))\n#elif (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_CLANG_ATTR)\n__attribute__ ((aligned (8)))\n#endif\n;\n#if (DUK_USE_ALIGN_BY == 8) && defined(DUK_USE_PACK_MSVC_PRAGMA)\n#pragma pack(pop)\n#endif\n\n/* Dynamic buffer with 'curr_alloc' pointing to a dynamic area allocated using\n * heap allocation primitives.  Also used for external buffers when low memory\n * options are not used.\n */\nstruct duk_hbuffer_dynamic {\n\tduk_heaphdr hdr;\n\n#if defined(DUK_USE_BUFLEN16)\n\t/* Stored in duk_heaphdr unused flags. */\n#else\n\tduk_size_t size;\n#endif\n\n#if defined(DUK_USE_HEAPPTR16)\n\t/* Stored in duk_heaphdr h_extra16. */\n#else\n\tvoid *curr_alloc;  /* may be NULL if alloc_size == 0 */\n#endif\n\n\t/*\n\t *  Allocation size for 'curr_alloc' is alloc_size.  There is no\n\t *  automatic NUL terminator for buffers (see above for rationale).\n\t *\n\t *  'curr_alloc' is explicitly allocated with heap allocation\n\t *  primitives and will thus always have alignment suitable for\n\t *  e.g. duk_tval and an IEEE double.\n\t */\n};\n\n/* External buffer with 'curr_alloc' managed by user code and pointing to an\n * arbitrary address.  When heap pointer compression is not used, this struct\n * has the same layout as duk_hbuffer_dynamic.\n */\nstruct duk_hbuffer_external {\n\tduk_heaphdr hdr;\n\n#if defined(DUK_USE_BUFLEN16)\n\t/* Stored in duk_heaphdr unused flags. */\n#else\n\tduk_size_t size;\n#endif\n\n\t/* Cannot be compressed as a heap pointer because may point to\n\t * an arbitrary address.\n\t */\n\tvoid *curr_alloc;  /* may be NULL if alloc_size == 0 */\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk_small_uint_t flags, void **out_bufdata);\nDUK_INTERNAL_DECL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud);  /* indirect allocs */\n\n/* dynamic buffer ops */\nDUK_INTERNAL_DECL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf, duk_size_t new_size);\nDUK_INTERNAL_DECL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *buf);\n\n#endif  /* DUK_HBUFFER_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hbuffer_alloc.c",
    "content": "/*\n *  duk_hbuffer allocation and freeing.\n */\n\n#include \"duk_internal.h\"\n\n/* Allocate a new duk_hbuffer of a certain type and return a pointer to it\n * (NULL on error).  Write buffer data pointer to 'out_bufdata' (only if\n * allocation successful).\n */\nDUK_INTERNAL duk_hbuffer *duk_hbuffer_alloc(duk_heap *heap, duk_size_t size, duk_small_uint_t flags, void **out_bufdata) {\n\tduk_hbuffer *res = NULL;\n\tduk_size_t header_size;\n\tduk_size_t alloc_size;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(out_bufdata != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"allocate hbuffer\"));\n\n\t/* Size sanity check.  Should not be necessary because caller is\n\t * required to check this, but we don't want to cause a segfault\n\t * if the size wraps either in duk_size_t computation or when\n\t * storing the size in a 16-bit field.\n\t */\n\tif (size > DUK_HBUFFER_MAX_BYTELEN) {\n\t\tDUK_D(DUK_DPRINT(\"hbuffer alloc failed: size too large: %ld\", (long) size));\n\t\treturn NULL;  /* no need to write 'out_bufdata' */\n\t}\n\n\tif (flags & DUK_BUF_FLAG_EXTERNAL) {\n\t\theader_size = sizeof(duk_hbuffer_external);\n\t\talloc_size = sizeof(duk_hbuffer_external);\n\t} else if (flags & DUK_BUF_FLAG_DYNAMIC) {\n\t\theader_size = sizeof(duk_hbuffer_dynamic);\n\t\talloc_size = sizeof(duk_hbuffer_dynamic);\n\t} else {\n\t\theader_size = sizeof(duk_hbuffer_fixed);\n\t\talloc_size = sizeof(duk_hbuffer_fixed) + size;\n\t\tDUK_ASSERT(alloc_size >= sizeof(duk_hbuffer_fixed));  /* no wrapping */\n\t}\n\n\tres = (duk_hbuffer *) DUK_ALLOC(heap, alloc_size);\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\tgoto alloc_error;\n\t}\n\n\t/* zero everything unless requested not to do so */\n#if defined(DUK_USE_ZERO_BUFFER_DATA)\n\tduk_memzero((void *) res,\n\t            (flags & DUK_BUF_FLAG_NOZERO) ? header_size : alloc_size);\n#else\n\tduk_memzero((void *) res, header_size);\n#endif\n\n\tif (flags & DUK_BUF_FLAG_EXTERNAL) {\n\t\tduk_hbuffer_external *h;\n\t\th = (duk_hbuffer_external *) res;\n\t\tDUK_UNREF(h);\n\t\t*out_bufdata = NULL;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_HEAPPTR16)\n/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */\n#else\n\t\tDUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap, h, NULL);\n#endif\n#endif\n\t\tDUK_ASSERT(DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap, h) == NULL);\n\t} else if (flags & DUK_BUF_FLAG_DYNAMIC) {\n\t\tduk_hbuffer_dynamic *h = (duk_hbuffer_dynamic *) res;\n\t\tvoid *ptr;\n\n\t\tif (size > 0) {\n\t\t\tDUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL));  /* alloc external with size zero */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"dynamic buffer with nonzero size, alloc actual buffer\"));\n#if defined(DUK_USE_ZERO_BUFFER_DATA)\n\t\t\tptr = DUK_ALLOC_ZEROED(heap, size);\n#else\n\t\t\tptr = DUK_ALLOC(heap, size);\n#endif\n\t\t\tif (DUK_UNLIKELY(ptr == NULL)) {\n\t\t\t\t/* Because size > 0, NULL check is correct */\n\t\t\t\tgoto alloc_error;\n\t\t\t}\n\t\t\t*out_bufdata = ptr;\n\n\t\t\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, ptr);\n\t\t} else {\n\t\t\t*out_bufdata = NULL;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_HEAPPTR16)\n/* the compressed pointer is zeroed which maps to NULL, so nothing to do. */\n#else\n\t\t\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap, h, NULL);\n#endif\n#endif\n\t\t\tDUK_ASSERT(DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, h) == NULL);\n\t\t}\n\t} else {\n\t\t*out_bufdata = (void *) ((duk_hbuffer_fixed *) (void *) res + 1);\n\t}\n\n\tDUK_HBUFFER_SET_SIZE(res, size);\n\n\tDUK_HEAPHDR_SET_TYPE(&res->hdr, DUK_HTYPE_BUFFER);\n\tif (flags & DUK_BUF_FLAG_DYNAMIC) {\n\t\tDUK_HBUFFER_SET_DYNAMIC(res);\n\t\tif (flags & DUK_BUF_FLAG_EXTERNAL) {\n\t\t\tDUK_HBUFFER_SET_EXTERNAL(res);\n\t\t}\n\t} else {\n\t\tDUK_ASSERT(!(flags & DUK_BUF_FLAG_EXTERNAL));\n\t}\n        DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &res->hdr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"allocated hbuffer: %p\", (void *) res));\n\treturn res;\n\n alloc_error:\n\tDUK_DD(DUK_DDPRINT(\"hbuffer allocation failed\"));\n\n\tDUK_FREE(heap, res);\n\treturn NULL;  /* no need to write 'out_bufdata' */\n}\n\n/* For indirect allocs. */\n\nDUK_INTERNAL void *duk_hbuffer_get_dynalloc_ptr(duk_heap *heap, void *ud) {\n\tduk_hbuffer_dynamic *buf = (duk_hbuffer_dynamic *) ud;\n\tDUK_UNREF(heap);\n\treturn (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, buf);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hbuffer_assert.c",
    "content": "/*\n *  duk_hbuffer assertion helpers\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_ASSERTIONS)\n\nDUK_INTERNAL void duk_hbuffer_assert_valid(duk_hbuffer *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hbuffer_ops.c",
    "content": "/*\n *  duk_hbuffer operations such as resizing and inserting/appending data to\n *  a dynamic buffer.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Resizing\n */\n\nDUK_INTERNAL void duk_hbuffer_resize(duk_hthread *thr, duk_hbuffer_dynamic *buf, duk_size_t new_size) {\n\tvoid *res;\n\tduk_size_t prev_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf));\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf));\n\n\t/*\n\t *  Maximum size check\n\t */\n\n\tif (new_size > DUK_HBUFFER_MAX_BYTELEN) {\n\t\tDUK_ERROR_RANGE(thr, \"buffer too long\");\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/*\n\t *  Note: use indirect realloc variant just in case mark-and-sweep\n\t *  (finalizers) might resize this same buffer during garbage\n\t *  collection.\n\t */\n\n\tres = DUK_REALLOC_INDIRECT(thr->heap, duk_hbuffer_get_dynalloc_ptr, (void *) buf, new_size);\n\tif (DUK_LIKELY(res != NULL || new_size == 0)) {\n\t\t/* 'res' may be NULL if new allocation size is 0. */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"resized dynamic buffer %p:%ld -> %p:%ld\",\n\t\t                     (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, buf),\n\t\t                     (long) DUK_HBUFFER_DYNAMIC_GET_SIZE(buf),\n\t\t                     (void *) res,\n\t\t                     (long) new_size));\n\n\t\t/*\n\t\t *  The entire allocated buffer area, regardless of actual used\n\t\t *  size, is kept zeroed in resizes for simplicity.  If the buffer\n\t\t *  is grown, zero the new part.\n\t\t */\n\n\t\tprev_size = DUK_HBUFFER_DYNAMIC_GET_SIZE(buf);\n\t\tif (new_size > prev_size) {\n\t\t\tDUK_ASSERT(new_size - prev_size > 0);\n#if defined(DUK_USE_ZERO_BUFFER_DATA)\n\t\t\tduk_memzero((void *) ((char *) res + prev_size),\n\t\t\t            (duk_size_t) (new_size - prev_size));\n#endif\n\t\t}\n\n\t\tDUK_HBUFFER_DYNAMIC_SET_SIZE(buf, new_size);\n\t\tDUK_HBUFFER_DYNAMIC_SET_DATA_PTR(thr->heap, buf, res);\n\t} else {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_ASSERT(res != NULL || new_size == 0);\n}\n\nDUK_INTERNAL void duk_hbuffer_reset(duk_hthread *thr, duk_hbuffer_dynamic *buf) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(buf));\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_EXTERNAL(buf));\n\n\tduk_hbuffer_resize(thr, buf, 0);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hbufobj.h",
    "content": "/*\n *  Heap Buffer object representation.  Used for all Buffer variants.\n */\n\n#if !defined(DUK_HBUFOBJ_H_INCLUDED)\n#define DUK_HBUFOBJ_H_INCLUDED\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\n/* All element accessors are host endian now (driven by TypedArray spec). */\n#define DUK_HBUFOBJ_ELEM_UINT8           0\n#define DUK_HBUFOBJ_ELEM_UINT8CLAMPED    1\n#define DUK_HBUFOBJ_ELEM_INT8            2\n#define DUK_HBUFOBJ_ELEM_UINT16          3\n#define DUK_HBUFOBJ_ELEM_INT16           4\n#define DUK_HBUFOBJ_ELEM_UINT32          5\n#define DUK_HBUFOBJ_ELEM_INT32           6\n#define DUK_HBUFOBJ_ELEM_FLOAT32         7\n#define DUK_HBUFOBJ_ELEM_FLOAT64         8\n#define DUK_HBUFOBJ_ELEM_MAX             8\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hbufobj_assert_valid(duk_hbufobj *h);\n#define DUK_HBUFOBJ_ASSERT_VALID(h)  do { duk_hbufobj_assert_valid((h)); } while (0)\n#else\n#define DUK_HBUFOBJ_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/* Get the current data pointer (caller must ensure buf != NULL) as a\n * duk_uint8_t ptr.  Note that the result may be NULL if the underlying\n * buffer has zero size and is not a fixed buffer.\n */\n#define DUK_HBUFOBJ_GET_SLICE_BASE(heap,h) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t(((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR((heap), (h)->buf)) + (h)->offset))\n\n/* True if slice is full, i.e. offset is zero and length covers the entire\n * buffer.  This status may change independently of the duk_hbufobj if\n * the underlying buffer is dynamic and changes without the hbufobj\n * being changed.\n */\n#define DUK_HBUFOBJ_FULL_SLICE(h) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset == 0 && (h)->length == DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n/* Validate that the whole slice [0,length[ is contained in the underlying\n * buffer.  Caller must ensure 'buf' != NULL.\n */\n#define DUK_HBUFOBJ_VALID_SLICE(h) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset + (h)->length <= DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n/* Validate byte read/write for virtual 'offset', i.e. check that the\n * offset, taking into account h->offset, is within the underlying\n * buffer size.  This is a safety check which is needed to ensure\n * that even a misconfigured duk_hbufobj never causes memory unsafe\n * behavior (e.g. if an underlying dynamic buffer changes after being\n * setup).  Caller must ensure 'buf' != NULL.\n */\n#define DUK_HBUFOBJ_VALID_BYTEOFFSET_INCL(h,off) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset + (off) < DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n#define DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h,off) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), DUK_ASSERT_EXPR((h)->buf != NULL), \\\n\t((h)->offset + (off) <= DUK_HBUFFER_GET_SIZE((h)->buf)))\n\n/* Clamp an input byte length (already assumed to be within the nominal\n * duk_hbufobj 'length') to the current dynamic buffer limits to yield\n * a byte length limit that's safe for memory accesses.  This value can\n * be invalidated by any side effect because it may trigger a user\n * callback that resizes the underlying buffer.\n */\n#define DUK_HBUFOBJ_CLAMP_BYTELENGTH(h,len) \\\n\t(DUK_ASSERT_EXPR((h) != NULL), \\\n\tduk_hbufobj_clamp_bytelength((h), (len)))\n\n/* Typed arrays have virtual indices, ArrayBuffer and DataView do not. */\n#define DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h)  ((h)->is_typedarray)\n\nstruct duk_hbufobj {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Underlying buffer (refcounted), may be NULL. */\n\tduk_hbuffer *buf;\n\n\t/* .buffer reference to an ArrayBuffer, may be NULL. */\n\tduk_hobject *buf_prop;\n\n\t/* Slice and accessor information.\n\t *\n\t * Because the underlying buffer may be dynamic, these may be\n\t * invalidated by the buffer being modified so that both offset\n\t * and length should be validated before every access.  Behavior\n\t * when the underlying buffer has changed doesn't need to be clean:\n\t * virtual 'length' doesn't need to be affected, reads can return\n\t * zero/NaN, and writes can be ignored.\n\t *\n\t * Note that a data pointer cannot be precomputed because 'buf' may\n\t * be dynamic and its pointer unstable.\n\t */\n\n\tduk_uint_t offset;       /* byte offset to buf */\n\tduk_uint_t length;       /* byte index limit for element access, exclusive */\n\tduk_uint8_t shift;       /* element size shift:\n\t                          *   0 = u8/i8\n\t                          *   1 = u16/i16\n\t                          *   2 = u32/i32/float\n\t                          *   3 = double\n\t                          */\n\tduk_uint8_t elem_type;   /* element type */\n\tduk_uint8_t is_typedarray;\n};\n\nDUK_INTERNAL_DECL duk_uint_t duk_hbufobj_clamp_bytelength(duk_hbufobj *h_bufobj, duk_uint_t len);\nDUK_INTERNAL_DECL void duk_hbufobj_push_uint8array_from_plain(duk_hthread *thr, duk_hbuffer *h_buf);\nDUK_INTERNAL_DECL void duk_hbufobj_push_validated_read(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);\nDUK_INTERNAL_DECL void duk_hbufobj_validated_write(duk_hthread *thr, duk_hbufobj *h_bufobj, duk_uint8_t *p, duk_small_uint_t elem_size);\nDUK_INTERNAL_DECL void duk_hbufobj_promote_plain(duk_hthread *thr, duk_idx_t idx);\n\n#else  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* nothing */\n\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n#endif  /* DUK_HBUFOBJ_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hbufobj_misc.c",
    "content": "#include \"duk_internal.h\"\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_uint_t duk_hbufobj_clamp_bytelength(duk_hbufobj *h_bufobj, duk_uint_t len) {\n\tduk_uint_t buf_size;\n\tduk_uint_t buf_avail;\n\n\tDUK_ASSERT(h_bufobj != NULL);\n\tDUK_ASSERT(h_bufobj->buf != NULL);\n\n\tbuf_size = (duk_uint_t) DUK_HBUFFER_GET_SIZE(h_bufobj->buf);\n\tif (h_bufobj->offset > buf_size) {\n\t\t/* Slice starting point is beyond current length. */\n\t\treturn 0;\n\t}\n\tbuf_avail = buf_size - h_bufobj->offset;\n\n\treturn buf_avail >= len ? len : buf_avail;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hcompfunc.h",
    "content": "/*\n *  Heap compiled function (ECMAScript function) representation.\n *\n *  There is a single data buffer containing the ECMAScript function's\n *  bytecode, constants, and inner functions.\n */\n\n#if !defined(DUK_HCOMPFUNC_H_INCLUDED)\n#define DUK_HCOMPFUNC_H_INCLUDED\n\n/*\n *  Field accessor macros\n */\n\n/* XXX: casts could be improved, especially for GET/SET DATA */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HCOMPFUNC_GET_DATA(heap,h) \\\n\t((duk_hbuffer_fixed *) (void *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->data16))\n#define DUK_HCOMPFUNC_SET_DATA(heap,h,v) do { \\\n\t\t(h)->data16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_FUNCS(heap,h)  \\\n\t((duk_hobject **) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->funcs16)))\n#define DUK_HCOMPFUNC_SET_FUNCS(heap,h,v)  do { \\\n\t\t(h)->funcs16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_BYTECODE(heap,h)  \\\n\t((duk_instr_t *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->bytecode16)))\n#define DUK_HCOMPFUNC_SET_BYTECODE(heap,h,v)  do { \\\n\t\t(h)->bytecode16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_LEXENV(heap,h)  \\\n\t((duk_hobject *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->lex_env16)))\n#define DUK_HCOMPFUNC_SET_LEXENV(heap,h,v)  do { \\\n\t\t(h)->lex_env16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_VARENV(heap,h)  \\\n\t((duk_hobject *) (void *) (DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->var_env16)))\n#define DUK_HCOMPFUNC_SET_VARENV(heap,h,v)  do { \\\n\t\t(h)->var_env16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (v)); \\\n\t} while (0)\n#else\n#define DUK_HCOMPFUNC_GET_DATA(heap,h)  ((duk_hbuffer_fixed *) (void *) (h)->data)\n#define DUK_HCOMPFUNC_SET_DATA(heap,h,v) do { \\\n\t\t(h)->data = (duk_hbuffer *) (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_FUNCS(heap,h)  ((h)->funcs)\n#define DUK_HCOMPFUNC_SET_FUNCS(heap,h,v)  do { \\\n\t\t(h)->funcs = (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_BYTECODE(heap,h)  ((h)->bytecode)\n#define DUK_HCOMPFUNC_SET_BYTECODE(heap,h,v)  do { \\\n\t\t(h)->bytecode = (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_LEXENV(heap,h)  ((h)->lex_env)\n#define DUK_HCOMPFUNC_SET_LEXENV(heap,h,v)  do { \\\n\t\t(h)->lex_env = (v); \\\n\t} while (0)\n#define DUK_HCOMPFUNC_GET_VARENV(heap,h)  ((h)->var_env)\n#define DUK_HCOMPFUNC_SET_VARENV(heap,h,v)  do { \\\n\t\t(h)->var_env = (v); \\\n\t} while (0)\n#endif\n\n/*\n *  Accessor macros for function specific data areas\n */\n\n/* Note: assumes 'data' is always a fixed buffer */\n#define DUK_HCOMPFUNC_GET_BUFFER_BASE(heap,h)  \\\n\tDUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPFUNC_GET_DATA((heap), (h)))\n\n#define DUK_HCOMPFUNC_GET_CONSTS_BASE(heap,h)  \\\n\t((duk_tval *) (void *) DUK_HCOMPFUNC_GET_BUFFER_BASE((heap), (h)))\n\n#define DUK_HCOMPFUNC_GET_FUNCS_BASE(heap,h)  \\\n\tDUK_HCOMPFUNC_GET_FUNCS((heap), (h))\n\n#define DUK_HCOMPFUNC_GET_CODE_BASE(heap,h)  \\\n\tDUK_HCOMPFUNC_GET_BYTECODE((heap), (h))\n\n#define DUK_HCOMPFUNC_GET_CONSTS_END(heap,h)  \\\n\t((duk_tval *) (void *) DUK_HCOMPFUNC_GET_FUNCS((heap), (h)))\n\n#define DUK_HCOMPFUNC_GET_FUNCS_END(heap,h)  \\\n\t((duk_hobject **) (void *) DUK_HCOMPFUNC_GET_BYTECODE((heap), (h)))\n\n/* XXX: double evaluation of DUK_HCOMPFUNC_GET_DATA() */\n#define DUK_HCOMPFUNC_GET_CODE_END(heap,h)  \\\n\t((duk_instr_t *) (void *) (DUK_HBUFFER_FIXED_GET_DATA_PTR((heap), DUK_HCOMPFUNC_GET_DATA((heap), (h))) + \\\n\t                DUK_HBUFFER_GET_SIZE((duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA((heap), h))))\n\n#define DUK_HCOMPFUNC_GET_CONSTS_SIZE(heap,h)  \\\n\t( \\\n\t (duk_size_t) \\\n\t ( \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CONSTS_END((heap), (h))) - \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CONSTS_BASE((heap), (h))) \\\n\t ) \\\n\t)\n\n#define DUK_HCOMPFUNC_GET_FUNCS_SIZE(heap,h)  \\\n\t( \\\n\t (duk_size_t) \\\n\t ( \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_FUNCS_END((heap), (h))) - \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_FUNCS_BASE((heap), (h))) \\\n\t ) \\\n\t)\n\n#define DUK_HCOMPFUNC_GET_CODE_SIZE(heap,h)  \\\n\t( \\\n\t (duk_size_t) \\\n\t ( \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CODE_END((heap),(h))) - \\\n\t   ((const duk_uint8_t *) DUK_HCOMPFUNC_GET_CODE_BASE((heap),(h))) \\\n\t ) \\\n\t)\n\n#define DUK_HCOMPFUNC_GET_CONSTS_COUNT(heap,h)  \\\n\t((duk_size_t) (DUK_HCOMPFUNC_GET_CONSTS_SIZE((heap), (h)) / sizeof(duk_tval)))\n\n#define DUK_HCOMPFUNC_GET_FUNCS_COUNT(heap,h)  \\\n\t((duk_size_t) (DUK_HCOMPFUNC_GET_FUNCS_SIZE((heap), (h)) / sizeof(duk_hobject *)))\n\n#define DUK_HCOMPFUNC_GET_CODE_COUNT(heap,h)  \\\n\t((duk_size_t) (DUK_HCOMPFUNC_GET_CODE_SIZE((heap), (h)) / sizeof(duk_instr_t)))\n\n/*\n *  Validity assert\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hcompfunc_assert_valid(duk_hcompfunc *h);\n#define DUK_HCOMPFUNC_ASSERT_VALID(h)  do { duk_hcompfunc_assert_valid((h)); } while (0)\n#else\n#define DUK_HCOMPFUNC_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Main struct\n */\n\nstruct duk_hcompfunc {\n\t/* shared object part */\n\tduk_hobject obj;\n\n\t/*\n\t *  Pointers to function data area for faster access.  Function\n\t *  data is a buffer shared between all closures of the same\n\t *  \"template\" function.  The data buffer is always fixed (non-\n\t *  dynamic, hence stable), with a layout as follows:\n\t *\n\t *    constants (duk_tval)\n\t *    inner functions (duk_hobject *)\n\t *    bytecode (duk_instr_t)\n\t *\n\t *  Note: bytecode end address can be computed from 'data' buffer\n\t *  size.  It is not strictly necessary functionally, assuming\n\t *  bytecode never jumps outside its allocated area.  However,\n\t *  it's a safety/robustness feature for avoiding the chance of\n\t *  executing random data as bytecode due to a compiler error.\n\t *\n\t *  Note: values in the data buffer must be incref'd (they will\n\t *  be decref'd on release) for every compiledfunction referring\n\t *  to the 'data' element.\n\t */\n\n\t/* Data area, fixed allocation, stable data ptrs. */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t data16;\n#else\n\tduk_hbuffer *data;\n#endif\n\n\t/* No need for constants pointer (= same as data).\n\t *\n\t * When using 16-bit packing alignment to 4 is nice.  'funcs' will be\n\t * 4-byte aligned because 'constants' are duk_tvals.  For now the\n\t * inner function pointers are not compressed, so that 'bytecode' will\n\t * also be 4-byte aligned.\n\t */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t funcs16;\n\tduk_uint16_t bytecode16;\n#else\n\tduk_hobject **funcs;\n\tduk_instr_t *bytecode;\n#endif\n\n\t/* Lexenv: lexical environment of closure, NULL for templates.\n\t * Varenv: variable environment of closure, NULL for templates.\n\t */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t lex_env16;\n\tduk_uint16_t var_env16;\n#else\n\tduk_hobject *lex_env;\n\tduk_hobject *var_env;\n#endif\n\n\t/*\n\t *  'nregs' registers are allocated on function entry, at most 'nargs'\n\t *  are initialized to arguments, and the rest to undefined.  Arguments\n\t *  above 'nregs' are not mapped to registers.  All registers in the\n\t *  active stack range must be initialized because they are GC reachable.\n\t *  'nargs' is needed so that if the function is given more than 'nargs'\n\t *  arguments, the additional arguments do not 'clobber' registers\n\t *  beyond 'nregs' which must be consistently initialized to undefined.\n\t *\n\t *  Usually there is no need to know which registers are mapped to\n\t *  local variables.  Registers may be allocated to variable in any\n\t *  way (even including gaps).  However, a register-variable mapping\n\t *  must be the same for the duration of the function execution and\n\t *  the register cannot be used for anything else.\n\t *\n\t *  When looking up variables by name, the '_Varmap' map is used.\n\t *  When an activation closes, registers mapped to arguments are\n\t *  copied into the environment record based on the same map.  The\n\t *  reverse map (from register to variable) is not currently needed\n\t *  at run time, except for debugging, so it is not maintained.\n\t */\n\n\tduk_uint16_t nregs;                /* regs to allocate */\n\tduk_uint16_t nargs;                /* number of arguments allocated to regs */\n\n\t/*\n\t *  Additional control information is placed into the object itself\n\t *  as internal properties to avoid unnecessary fields for the\n\t *  majority of functions.  The compiler tries to omit internal\n\t *  control fields when possible.\n\t *\n\t *  Function templates:\n\t *\n\t *    {\n\t *      name: \"func\",    // declaration, named function expressions\n\t *      fileName: <debug info for creating nice errors>\n\t *      _Varmap: { \"arg1\": 0, \"arg2\": 1, \"varname\": 2 },\n\t *      _Formals: [ \"arg1\", \"arg2\" ],\n\t *      _Source: \"function func(arg1, arg2) { ... }\",\n\t *      _Pc2line: <debug info for pc-to-line mapping>,\n\t *    }\n\t *\n\t *  Function instances:\n\t *\n\t *    {\n\t *      length: 2,\n\t *      prototype: { constructor: <func> },\n\t *      caller: <thrower>,\n\t *      arguments: <thrower>,\n\t *      name: \"func\",    // declaration, named function expressions\n\t *      fileName: <debug info for creating nice errors>\n\t *      _Varmap: { \"arg1\": 0, \"arg2\": 1, \"varname\": 2 },\n\t *      _Formals: [ \"arg1\", \"arg2\" ],\n\t *      _Source: \"function func(arg1, arg2) { ... }\",\n\t *      _Pc2line: <debug info for pc-to-line mapping>,\n\t *    }\n\t *\n\t *  More detailed description of these properties can be found\n\t *  in the documentation.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* Line number range for function.  Needed during debugging to\n\t * determine active breakpoints.\n\t */\n\tduk_uint32_t start_line;\n\tduk_uint32_t end_line;\n#endif\n};\n\n#endif  /* DUK_HCOMPFUNC_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_heap.h",
    "content": "/*\n *  Heap structure.\n *\n *  Heap contains allocated heap objects, interned strings, and built-in\n *  strings for one or more threads.\n */\n\n#if !defined(DUK_HEAP_H_INCLUDED)\n#define DUK_HEAP_H_INCLUDED\n\n/* alloc function typedefs in duktape.h */\n\n/*\n *  Heap flags\n */\n\n#define DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED            (1U << 0)  /* mark-and-sweep marking reached a recursion limit and must use multi-pass marking */\n#define DUK_HEAP_FLAG_INTERRUPT_RUNNING                        (1U << 1)  /* executor interrupt running (used to avoid nested interrupts) */\n#define DUK_HEAP_FLAG_FINALIZER_NORESCUE                       (1U << 2)  /* heap destruction ongoing, finalizer rescue no longer possible */\n#define DUK_HEAP_FLAG_DEBUGGER_PAUSED                          (1U << 3)  /* debugger is paused: talk with debug client until step/resume */\n\n#define DUK__HEAP_HAS_FLAGS(heap,bits)               ((heap)->flags & (bits))\n#define DUK__HEAP_SET_FLAGS(heap,bits)  do { \\\n\t\t(heap)->flags |= (bits); \\\n\t} while (0)\n#define DUK__HEAP_CLEAR_FLAGS(heap,bits)  do { \\\n\t\t(heap)->flags &= ~(bits); \\\n\t} while (0)\n\n#define DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap)   DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)\n#define DUK_HEAP_HAS_INTERRUPT_RUNNING(heap)               DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)\n#define DUK_HEAP_HAS_FINALIZER_NORESCUE(heap)              DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE)\n#define DUK_HEAP_HAS_DEBUGGER_PAUSED(heap)                 DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED)\n\n#define DUK_HEAP_SET_MARKANDSWEEP_RECLIMIT_REACHED(heap)   DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)\n#define DUK_HEAP_SET_INTERRUPT_RUNNING(heap)               DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)\n#define DUK_HEAP_SET_FINALIZER_NORESCUE(heap)              DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE)\n#define DUK_HEAP_SET_DEBUGGER_PAUSED(heap)                 DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED)\n\n#define DUK_HEAP_CLEAR_MARKANDSWEEP_RECLIMIT_REACHED(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)\n#define DUK_HEAP_CLEAR_INTERRUPT_RUNNING(heap)             DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)\n#define DUK_HEAP_CLEAR_FINALIZER_NORESCUE(heap)            DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_FINALIZER_NORESCUE)\n#define DUK_HEAP_CLEAR_DEBUGGER_PAUSED(heap)               DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_DEBUGGER_PAUSED)\n\n/*\n *  Longjmp types, also double as identifying continuation type for a rethrow (in 'finally')\n */\n\n#define DUK_LJ_TYPE_UNKNOWN      0    /* unused */\n#define DUK_LJ_TYPE_THROW        1    /* value1 -> error object */\n#define DUK_LJ_TYPE_YIELD        2    /* value1 -> yield value, iserror -> error / normal */\n#define DUK_LJ_TYPE_RESUME       3    /* value1 -> resume value, value2 -> resumee thread, iserror -> error/normal */\n#define DUK_LJ_TYPE_BREAK        4    /* value1 -> label number, pseudo-type to indicate a break continuation (for ENDFIN) */\n#define DUK_LJ_TYPE_CONTINUE     5    /* value1 -> label number, pseudo-type to indicate a continue continuation (for ENDFIN) */\n#define DUK_LJ_TYPE_RETURN       6    /* value1 -> return value, pseudo-type to indicate a return continuation (for ENDFIN) */\n#define DUK_LJ_TYPE_NORMAL       7    /* no value, pseudo-type to indicate a normal continuation (for ENDFIN) */\n\n/*\n *  Mark-and-sweep flags\n *\n *  These are separate from heap level flags now but could be merged.\n *  The heap structure only contains a 'base mark-and-sweep flags'\n *  field and the GC caller can impose further flags.\n */\n\n/* Emergency mark-and-sweep: try extra hard, even at the cost of\n * performance.\n */\n#define DUK_MS_FLAG_EMERGENCY                (1U << 0)\n\n/* Voluntary mark-and-sweep: triggered periodically. */\n#define DUK_MS_FLAG_VOLUNTARY                (1U << 1)\n\n/* Postpone rescue decisions for reachable objects with FINALIZED set.\n * Used during finalize_list processing to avoid incorrect rescue\n * decisions due to finalize_list being a reachability root.\n */\n#define DUK_MS_FLAG_POSTPONE_RESCUE          (1U << 2)\n\n/* Don't compact objects; needed during object property table resize\n * to prevent a recursive resize.  It would suffice to protect only the\n * current object being resized, but this is not yet implemented.\n */\n#define DUK_MS_FLAG_NO_OBJECT_COMPACTION     (1U << 3)\n\n/*\n *  Thread switching\n *\n *  To switch heap->curr_thread, use the macro below so that interrupt counters\n *  get updated correctly.  The macro allows a NULL target thread because that\n *  happens e.g. in call handling.\n */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n#define DUK_HEAP_SWITCH_THREAD(heap,newthr)  duk_heap_switch_thread((heap), (newthr))\n#else\n#define DUK_HEAP_SWITCH_THREAD(heap,newthr)  do { \\\n\t\t(heap)->curr_thread = (newthr); \\\n\t} while (0)\n#endif\n\n/*\n *  Stats\n */\n\n#if defined(DUK_USE_DEBUG)\n#define DUK_STATS_INC(heap,fieldname) do { \\\n\t\t(heap)->fieldname += 1; \\\n\t} while (0)\n#else\n#define DUK_STATS_INC(heap,fieldname) do {} while (0)\n#endif\n\n/*\n *  Other heap related defines\n */\n\n/* Mark-and-sweep interval is relative to combined count of objects and\n * strings kept in the heap during the latest mark-and-sweep pass.\n * Fixed point .8 multiplier and .0 adder.  Trigger count (interval) is\n * decreased by each (re)allocation attempt (regardless of size), and each\n * refzero processed object.\n *\n * 'SKIP' indicates how many (re)allocations to wait until a retry if\n * GC is skipped because there is no thread do it with yet (happens\n * only during init phases).\n */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT              12800L  /* 50x heap size */\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD               1024L\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_SKIP              256L\n#else\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT              256L    /* 1x heap size */\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD               1024L\n#define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_SKIP              256L\n#endif\n\n/* GC torture. */\n#if defined(DUK_USE_GC_TORTURE)\n#define DUK_GC_TORTURE(heap) do { duk_heap_mark_and_sweep((heap), 0); } while (0)\n#else\n#define DUK_GC_TORTURE(heap) do { } while (0)\n#endif\n\n/* Stringcache is used for speeding up char-offset-to-byte-offset\n * translations for non-ASCII strings.\n */\n#define DUK_HEAP_STRCACHE_SIZE                            4\n#define DUK_HEAP_STRINGCACHE_NOCACHE_LIMIT                16  /* strings up to the this length are not cached */\n\n/* Some list management macros. */\n#define DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap,hdr)     duk_heap_insert_into_heap_allocated((heap), (hdr))\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_HEAP_REMOVE_FROM_HEAP_ALLOCATED(heap,hdr)     duk_heap_remove_from_heap_allocated((heap), (hdr))\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n#define DUK_HEAP_INSERT_INTO_FINALIZE_LIST(heap,hdr)      duk_heap_insert_into_finalize_list((heap), (hdr))\n#define DUK_HEAP_REMOVE_FROM_FINALIZE_LIST(heap,hdr)      duk_heap_remove_from_finalize_list((heap), (hdr))\n#endif\n\n/*\n *  Built-in strings\n */\n\n/* heap string indices are autogenerated in duk_strings.h */\n#if defined(DUK_USE_ROM_STRINGS)\n#define DUK_HEAP_GET_STRING(heap,idx) \\\n\t((duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_stridx[(idx)]))\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HEAP_GET_STRING(heap,idx) \\\n\t((duk_hstring *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (heap)->strs16[(idx)]))\n#else\n#define DUK_HEAP_GET_STRING(heap,idx) \\\n\t((heap)->strs[(idx)])\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n/*\n *  Raw memory calls: relative to heap, but no GC interaction\n */\n\n#define DUK_ALLOC_RAW(heap,size) \\\n\t((heap)->alloc_func((heap)->heap_udata, (size)))\n\n#define DUK_REALLOC_RAW(heap,ptr,newsize) \\\n\t((heap)->realloc_func((heap)->heap_udata, (void *) (ptr), (newsize)))\n\n#define DUK_FREE_RAW(heap,ptr) \\\n\t((heap)->free_func((heap)->heap_udata, (void *) (ptr)))\n\n/*\n *  Memory calls: relative to heap, GC interaction, but no error throwing.\n *\n *  XXX: Currently a mark-and-sweep triggered by memory allocation will run\n *  using the heap->heap_thread.  This thread is also used for running\n *  mark-and-sweep finalization; this is not ideal because it breaks the\n *  isolation between multiple global environments.\n *\n *  Notes:\n *\n *    - DUK_FREE() is required to ignore NULL and any other possible return\n *      value of a zero-sized alloc/realloc (same as ANSI C free()).\n *\n *    - There is no DUK_REALLOC_ZEROED because we don't assume to know the\n *      old size.  Caller must zero the reallocated memory.\n *\n *    - DUK_REALLOC_INDIRECT() must be used when a mark-and-sweep triggered\n *      by an allocation failure might invalidate the original 'ptr', thus\n *      causing a realloc retry to use an invalid pointer.  Example: we're\n *      reallocating the value stack and a finalizer resizes the same value\n *      stack during mark-and-sweep.  The indirect variant requests for the\n *      current location of the pointer being reallocated using a callback\n *      right before every realloc attempt; this circuitous approach is used\n *      to avoid strict aliasing issues in a more straightforward indirect\n *      pointer (void **) approach.  Note: the pointer in the storage\n *      location is read but is NOT updated; the caller must do that.\n */\n\n/* callback for indirect reallocs, request for current pointer */\ntypedef void *(*duk_mem_getptr)(duk_heap *heap, void *ud);\n\n#define DUK_ALLOC(heap,size)                            duk_heap_mem_alloc((heap), (size))\n#define DUK_ALLOC_ZEROED(heap,size)                     duk_heap_mem_alloc_zeroed((heap), (size))\n#define DUK_REALLOC(heap,ptr,newsize)                   duk_heap_mem_realloc((heap), (ptr), (newsize))\n#define DUK_REALLOC_INDIRECT(heap,cb,ud,newsize)        duk_heap_mem_realloc_indirect((heap), (cb), (ud), (newsize))\n#define DUK_FREE(heap,ptr)                              duk_heap_mem_free((heap), (ptr))\n\n/*\n *  Checked allocation, relative to a thread\n *\n *  DUK_FREE_CHECKED() doesn't actually throw, but accepts a 'thr' argument\n *  for convenience.\n */\n\n#define DUK_ALLOC_CHECKED(thr,size)                     duk_heap_mem_alloc_checked((thr), (size))\n#define DUK_ALLOC_CHECKED_ZEROED(thr,size)              duk_heap_mem_alloc_checked_zeroed((thr), (size))\n#define DUK_FREE_CHECKED(thr,ptr)                       duk_heap_mem_free((thr)->heap, (ptr))\n\n/*\n *  Memory constants\n */\n\n#define DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT           10  /* Retry allocation after mark-and-sweep for this\n                                                              * many times.  A single mark-and-sweep round is\n                                                              * not guaranteed to free all unreferenced memory\n                                                              * because of finalization (in fact, ANY number of\n                                                              * rounds is strictly not enough).\n                                                              */\n\n#define DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT  3  /* Starting from this round, use emergency mode\n                                                              * for mark-and-sweep.\n                                                              */\n\n/*\n *  Debugger support\n */\n\n/* Maximum number of breakpoints.  Only breakpoints that are set are\n * consulted so increasing this has no performance impact.\n */\n#define DUK_HEAP_MAX_BREAKPOINTS          16\n\n/* Opcode interval for a Date-based status/peek rate limit check.  Only\n * relevant when debugger is attached.  Requesting a timestamp may be a\n * slow operation on some platforms so this shouldn't be too low.  On the\n * other hand a high value makes Duktape react to a pause request slowly.\n */\n#define DUK_HEAP_DBG_RATELIMIT_OPCODES    4000\n\n/* Milliseconds between status notify and transport peeks. */\n#define DUK_HEAP_DBG_RATELIMIT_MILLISECS  200\n\n/* Debugger pause flags. */\n#define DUK_PAUSE_FLAG_ONE_OPCODE        (1U << 0)   /* pause when a single opcode has been executed */\n#define DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE (1U << 1)   /* one opcode pause actually active; artifact of current implementation */\n#define DUK_PAUSE_FLAG_LINE_CHANGE       (1U << 2)   /* pause when current line number changes */\n#define DUK_PAUSE_FLAG_FUNC_ENTRY        (1U << 3)   /* pause when entering a function */\n#define DUK_PAUSE_FLAG_FUNC_EXIT         (1U << 4)   /* pause when exiting current function */\n#define DUK_PAUSE_FLAG_CAUGHT_ERROR      (1U << 5)   /* pause when about to throw an error that is caught */\n#define DUK_PAUSE_FLAG_UNCAUGHT_ERROR    (1U << 6)   /* pause when about to throw an error that won't be caught */\n\nstruct duk_breakpoint {\n\tduk_hstring *filename;\n\tduk_uint32_t line;\n};\n\n/*\n *  String cache should ideally be at duk_hthread level, but that would\n *  cause string finalization to slow down relative to the number of\n *  threads; string finalization must check the string cache for \"weak\"\n *  references to the string being finalized to avoid dead pointers.\n *\n *  Thus, string caches are now at the heap level now.\n */\n\nstruct duk_strcache_entry {\n\tduk_hstring *h;\n\tduk_uint32_t bidx;\n\tduk_uint32_t cidx;\n};\n\n/*\n *  Longjmp state, contains the information needed to perform a longjmp.\n *  Longjmp related values are written to value1, value2, and iserror.\n */\n\nstruct duk_ljstate {\n\tduk_jmpbuf *jmpbuf_ptr;   /* current setjmp() catchpoint */\n\tduk_small_uint_t type;    /* longjmp type */\n\tduk_bool_t iserror;       /* isError flag for yield */\n\tduk_tval value1;          /* 1st related value (type specific) */\n\tduk_tval value2;          /* 2nd related value (type specific) */\n};\n\n#define DUK_ASSERT_LJSTATE_UNSET(heap) do { \\\n\t\tDUK_ASSERT(heap != NULL); \\\n\t\tDUK_ASSERT(heap->lj.type == DUK_LJ_TYPE_UNKNOWN); \\\n\t\tDUK_ASSERT(heap->lj.iserror == 0); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&heap->lj.value1)); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(&heap->lj.value2)); \\\n\t} while (0)\n#define DUK_ASSERT_LJSTATE_SET(heap) do { \\\n\t\tDUK_ASSERT(heap != NULL); \\\n\t\tDUK_ASSERT(heap->lj.type != DUK_LJ_TYPE_UNKNOWN); \\\n\t} while (0)\n\n/*\n *  Literal intern cache\n */\n\nstruct duk_litcache_entry {\n\tconst duk_uint8_t *addr;\n\tduk_hstring *h;\n};\n\n/*\n *  Main heap structure\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_heap_assert_valid(duk_heap *heap);\n#define DUK_HEAP_ASSERT_VALID(heap)  do { duk_heap_assert_valid((heap)); } while (0)\n#else\n#define DUK_HEAP_ASSERT_VALID(heap)  do {} while (0)\n#endif\n\nstruct duk_heap {\n\tduk_small_uint_t flags;\n\n\t/* Allocator functions. */\n\tduk_alloc_function alloc_func;\n\tduk_realloc_function realloc_func;\n\tduk_free_function free_func;\n\n\t/* Heap udata, used for allocator functions but also for other heap\n\t * level callbacks like fatal function, pointer compression, etc.\n\t */\n\tvoid *heap_udata;\n\n\t/* Fatal error handling, called e.g. when a longjmp() is needed but\n\t * lj.jmpbuf_ptr is NULL.  fatal_func must never return; it's not\n\t * declared as \"noreturn\" because doing that for typedefs is a bit\n\t * challenging portability-wise.\n\t */\n\tduk_fatal_function fatal_func;\n\n\t/* Main list of allocated heap objects.  Objects are either here,\n\t * in finalize_list waiting for processing, or in refzero_list\n\t * temporarily while a DECREF refzero cascade finishes.\n\t */\n\tduk_heaphdr *heap_allocated;\n\n\t/* Temporary work list for freeing a cascade of objects when a DECREF\n\t * (or DECREF_NORZ) encounters a zero refcount.  Using a work list\n\t * allows fixed C stack size when refcounts go to zero for a chain of\n\t * objects.  Outside of DECREF this is always a NULL because DECREF is\n\t * processed without side effects (only memory free calls).\n\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_heaphdr *refzero_list;\n#endif\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t/* Work list for objects to be finalized. */\n\tduk_heaphdr *finalize_list;\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Object whose finalizer is executing right now (no nesting). */\n\tduk_heaphdr *currently_finalizing;\n#endif\n#endif\n\n\t/* Freelist for duk_activations and duk_catchers. */\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\tduk_activation *activation_free;\n#endif\n#if defined(DUK_USE_CACHE_CATCHER)\n\tduk_catcher *catcher_free;\n#endif\n\n\t/* Voluntary mark-and-sweep trigger counter.  Intentionally signed\n\t * because we continue decreasing the value when voluntary GC cannot\n\t * run.\n\t */\n#if defined(DUK_USE_VOLUNTARY_GC)\n\tduk_int_t ms_trigger_counter;\n#endif\n\n\t/* Mark-and-sweep recursion control: too deep recursion causes\n\t * multi-pass processing to avoid growing C stack without bound.\n\t */\n\tduk_uint_t ms_recursion_depth;\n\n\t/* Mark-and-sweep flags automatically active (used for critical sections). */\n\tduk_small_uint_t ms_base_flags;\n\n\t/* Mark-and-sweep running flag.  Prevents re-entry, and also causes\n\t * refzero events to be ignored (= objects won't be queued to refzero_list).\n\t *\n\t * 0: mark-and-sweep not running\n\t * 1: mark-and-sweep is running\n\t * 2: heap destruction active or debugger active, prevent mark-and-sweep\n\t *    and refzero processing (but mark-and-sweep not itself running)\n\t */\n\tduk_uint_t ms_running;\n\n\t/* Mark-and-sweep prevent count, stacking.  Used to avoid M&S side\n\t * effects (besides finalizers which are controlled separately) such\n\t * as compacting the string table or object property tables.  This\n\t * is also bumped when ms_running is set to prevent recursive re-entry.\n\t * Can also be bumped when mark-and-sweep is not running.\n\t */\n\tduk_uint_t ms_prevent_count;\n\n\t/* Finalizer processing prevent count, stacking.  Bumped when finalizers\n\t * are processed to prevent recursive finalizer processing (first call site\n\t * processing finalizers handles all finalizers until the list is empty).\n\t * Can also be bumped explicitly to prevent finalizer execution.\n\t */\n\tduk_uint_t pf_prevent_count;\n\n\t/* When processing finalize_list, don't actually run finalizers but\n\t * queue finalizable objects back to heap_allocated as is.  This is\n\t * used during heap destruction to deal with finalizers that keep\n\t * on creating more finalizable garbage.\n\t */\n\tduk_uint_t pf_skip_finalizers;\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Set when we're in a critical path where an error throw would cause\n\t * e.g. sandboxing/protected call violations or state corruption.  This\n\t * is just used for asserts.\n\t */\n\tduk_bool_t error_not_allowed;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Set when heap is still being initialized, helps with writing\n\t * some assertions.\n\t */\n\tduk_bool_t heap_initializing;\n#endif\n\n\t/* Marker for detecting internal \"double faults\", errors thrown when\n\t * we're trying to create an error object, see duk_error_throw.c.\n\t */\n\tduk_bool_t creating_error;\n\n\t/* Marker for indicating we're calling a user error augmentation\n\t * (errCreate/errThrow) function.  Errors created/thrown during\n\t * such a call are not augmented.\n\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tduk_bool_t augmenting_error;\n#endif\n\n\t/* Longjmp state. */\n\tduk_ljstate lj;\n\n\t/* Heap thread, used internally and for finalization. */\n\tduk_hthread *heap_thread;\n\n\t/* Current running thread. */\n\tduk_hthread *curr_thread;\n\n\t/* Heap level \"stash\" object (e.g., various reachability roots). */\n\tduk_hobject *heap_object;\n\n\t/* duk_handle_call / duk_handle_safe_call recursion depth limiting */\n\tduk_int_t call_recursion_depth;\n\tduk_int_t call_recursion_limit;\n\n\t/* Mix-in value for computing string hashes; should be reasonably unpredictable. */\n\tduk_uint32_t hash_seed;\n\n\t/* Random number state for duk_util_tinyrandom.c. */\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\n#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS)\n\tduk_uint32_t rnd_state;  /* State for Shamir's three-op algorithm */\n#else\n\tduk_uint64_t rnd_state[2];  /* State for xoroshiro128+ */\n#endif\n#endif\n\n\t/* Counter for unique local symbol creation. */\n\t/* XXX: When 64-bit types are available, it would be more efficient to\n\t * use a duk_uint64_t at least for incrementing but maybe also for\n\t * string formatting in the Symbol constructor.\n\t */\n\tduk_uint32_t sym_counter[2];\n\n\t/* For manual debugging: instruction count based on executor and\n\t * interrupt counter book-keeping.  Inspect debug logs to see how\n\t * they match up.\n\t */\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\tduk_int_t inst_count_exec;\n\tduk_int_t inst_count_interrupt;\n#endif\n\n\t/* Debugger state. */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* Callbacks and udata; dbg_read_cb != NULL is used to indicate attached state. */\n\tduk_debug_read_function dbg_read_cb;                /* required, NULL implies detached */\n\tduk_debug_write_function dbg_write_cb;              /* required */\n\tduk_debug_peek_function dbg_peek_cb;\n\tduk_debug_read_flush_function dbg_read_flush_cb;\n\tduk_debug_write_flush_function dbg_write_flush_cb;\n\tduk_debug_request_function dbg_request_cb;\n\tduk_debug_detached_function dbg_detached_cb;\n\tvoid *dbg_udata;\n\n\t/* The following are only relevant when debugger is attached. */\n\tduk_bool_t dbg_processing;              /* currently processing messages or breakpoints: don't enter message processing recursively (e.g. no breakpoints when processing debugger eval) */\n\tduk_bool_t dbg_state_dirty;             /* resend state next time executor is about to run */\n\tduk_bool_t dbg_force_restart;           /* force executor restart to recheck breakpoints; used to handle function returns (see GH-303) */\n\tduk_bool_t dbg_detaching;               /* debugger detaching; used to avoid calling detach handler recursively */\n\tduk_small_uint_t dbg_pause_flags;       /* flags for automatic pause behavior */\n\tduk_activation *dbg_pause_act;          /* activation related to pause behavior (pause on line change, function entry/exit) */\n\tduk_uint32_t dbg_pause_startline;       /* starting line number for line change related pause behavior */\n\tduk_breakpoint dbg_breakpoints[DUK_HEAP_MAX_BREAKPOINTS];  /* breakpoints: [0,breakpoint_count[ gc reachable */\n\tduk_small_uint_t dbg_breakpoint_count;\n\tduk_breakpoint *dbg_breakpoints_active[DUK_HEAP_MAX_BREAKPOINTS + 1];  /* currently active breakpoints: NULL term, borrowed pointers */\n\t/* XXX: make active breakpoints actual copies instead of pointers? */\n\n\t/* These are for rate limiting Status notifications and transport peeking. */\n\tduk_uint_t dbg_exec_counter;            /* cumulative opcode execution count (overflows are OK) */\n\tduk_uint_t dbg_last_counter;            /* value of dbg_exec_counter when we last did a Date-based check */\n\tduk_double_t dbg_last_time;             /* time when status/peek was last done (Date-based rate limit) */\n\n\t/* Used to support single-byte stream lookahead. */\n\tduk_bool_t dbg_have_next_byte;\n\tduk_uint8_t dbg_next_byte;\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_bool_t dbg_calling_transport;       /* transport call in progress, calling into Duktape forbidden */\n#endif\n\n\t/* String intern table (weak refs). */\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable16;\n#else\n\tduk_hstring **strtable;\n#endif\n\tduk_uint32_t st_mask;    /* mask for lookup, st_size - 1 */\n\tduk_uint32_t st_size;    /* stringtable size */\n#if (DUK_USE_STRTAB_MINSIZE != DUK_USE_STRTAB_MAXSIZE)\n\tduk_uint32_t st_count;   /* string count for resize load factor checks */\n#endif\n\tduk_bool_t st_resizing;  /* string table is being resized; avoid recursive resize */\n\n\t/* String access cache (codepoint offset -> byte offset) for fast string\n\t * character looping; 'weak' reference which needs special handling in GC.\n\t */\n\tduk_strcache_entry strcache[DUK_HEAP_STRCACHE_SIZE];\n\n#if defined(DUK_USE_LITCACHE_SIZE)\n\t/* Literal intern cache.  When enabled, strings interned as literals\n\t * (e.g. duk_push_literal()) will be pinned and cached for the lifetime\n\t * of the heap.\n\t */\n\tduk_litcache_entry litcache[DUK_USE_LITCACHE_SIZE];\n#endif\n\n\t/* Built-in strings. */\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* No field needed when strings are in ROM. */\n#else\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t strs16[DUK_HEAP_NUM_STRINGS];\n#else\n\tduk_hstring *strs[DUK_HEAP_NUM_STRINGS];\n#endif\n#endif\n\n\t/* Stats. */\n#if defined(DUK_USE_DEBUG)\n\tduk_int_t stats_exec_opcodes;\n\tduk_int_t stats_exec_interrupt;\n\tduk_int_t stats_exec_throw;\n\tduk_int_t stats_call_all;\n\tduk_int_t stats_call_tailcall;\n\tduk_int_t stats_call_ecmatoecma;\n\tduk_int_t stats_safecall_all;\n\tduk_int_t stats_safecall_nothrow;\n\tduk_int_t stats_safecall_throw;\n\tduk_int_t stats_ms_try_count;\n\tduk_int_t stats_ms_skip_count;\n\tduk_int_t stats_ms_emergency_count;\n\tduk_int_t stats_strtab_intern_hit;\n\tduk_int_t stats_strtab_intern_miss;\n\tduk_int_t stats_strtab_resize_check;\n\tduk_int_t stats_strtab_resize_grow;\n\tduk_int_t stats_strtab_resize_shrink;\n\tduk_int_t stats_strtab_litcache_hit;\n\tduk_int_t stats_strtab_litcache_miss;\n\tduk_int_t stats_strtab_litcache_pin;\n\tduk_int_t stats_object_realloc_props;\n\tduk_int_t stats_object_abandon_array;\n\tduk_int_t stats_getownpropdesc_count;\n\tduk_int_t stats_getownpropdesc_hit;\n\tduk_int_t stats_getownpropdesc_miss;\n\tduk_int_t stats_getpropdesc_count;\n\tduk_int_t stats_getpropdesc_hit;\n\tduk_int_t stats_getpropdesc_miss;\n\tduk_int_t stats_getprop_all;\n\tduk_int_t stats_getprop_arrayidx;\n\tduk_int_t stats_getprop_bufobjidx;\n\tduk_int_t stats_getprop_bufferidx;\n\tduk_int_t stats_getprop_bufferlen;\n\tduk_int_t stats_getprop_stringidx;\n\tduk_int_t stats_getprop_stringlen;\n\tduk_int_t stats_getprop_proxy;\n\tduk_int_t stats_getprop_arguments;\n\tduk_int_t stats_putprop_all;\n\tduk_int_t stats_putprop_arrayidx;\n\tduk_int_t stats_putprop_bufobjidx;\n\tduk_int_t stats_putprop_bufferidx;\n\tduk_int_t stats_putprop_proxy;\n\tduk_int_t stats_getvar_all;\n\tduk_int_t stats_putvar_all;\n\tduk_int_t stats_envrec_delayedcreate;\n\tduk_int_t stats_envrec_create;\n\tduk_int_t stats_envrec_newenv;\n\tduk_int_t stats_envrec_oldenv;\n\tduk_int_t stats_envrec_pushclosure;\n#endif\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL\nduk_heap *duk_heap_alloc(duk_alloc_function alloc_func,\n                         duk_realloc_function realloc_func,\n                         duk_free_function free_func,\n                         void *heap_udata,\n                         duk_fatal_function fatal_func);\nDUK_INTERNAL_DECL void duk_heap_free(duk_heap *heap);\nDUK_INTERNAL_DECL void duk_free_hobject(duk_heap *heap, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_free_hbuffer(duk_heap *heap, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_free_hstring(duk_heap *heap, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr);\n\nDUK_INTERNAL_DECL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphdr *hdr);\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL_DECL void duk_heap_remove_from_heap_allocated(duk_heap *heap, duk_heaphdr *hdr);\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL_DECL void duk_heap_insert_into_finalize_list(duk_heap *heap, duk_heaphdr *hdr);\nDUK_INTERNAL_DECL void duk_heap_remove_from_finalize_list(duk_heap *heap, duk_heaphdr *hdr);\n#endif\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL duk_bool_t duk_heap_in_heap_allocated(duk_heap *heap, duk_heaphdr *ptr);\n#endif\n#if defined(DUK_USE_INTERRUPT_COUNTER)\nDUK_INTERNAL_DECL void duk_heap_switch_thread(duk_heap *heap, duk_hthread *new_thr);\n#endif\n\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen);\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t len);\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_literal_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen);\n#endif\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_u32(duk_heap *heap, duk_uint32_t val);\nDUK_INTERNAL_DECL duk_hstring *duk_heap_strtable_intern_u32_checked(duk_hthread *thr, duk_uint32_t val);\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL_DECL void duk_heap_strtable_unlink(duk_heap *heap, duk_hstring *h);\n#endif\nDUK_INTERNAL_DECL void duk_heap_strtable_unlink_prev(duk_heap *heap, duk_hstring *h, duk_hstring *prev);\nDUK_INTERNAL_DECL void duk_heap_strtable_force_resize(duk_heap *heap);\nDUK_INTERNAL void duk_heap_strtable_free(duk_heap *heap);\n#if defined(DUK_USE_DEBUG)\nDUK_INTERNAL void duk_heap_strtable_dump(duk_heap *heap);\n#endif\n\nDUK_INTERNAL_DECL void duk_heap_strcache_string_remove(duk_heap *heap, duk_hstring *h);\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *thr, duk_hstring *h, duk_uint_fast32_t char_offset);\n\n#if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS)\nDUK_INTERNAL_DECL void *duk_default_alloc_function(void *udata, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_default_realloc_function(void *udata, void *ptr, duk_size_t newsize);\nDUK_INTERNAL_DECL void duk_default_free_function(void *udata, void *ptr);\n#endif\n\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc(duk_heap *heap, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc_zeroed(duk_heap *heap, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc_checked(duk_hthread *thr, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_alloc_checked_zeroed(duk_hthread *thr, duk_size_t size);\nDUK_INTERNAL_DECL void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, duk_size_t newsize);\nDUK_INTERNAL_DECL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize);\nDUK_INTERNAL_DECL void duk_heap_mem_free(duk_heap *heap, void *ptr);\n\nDUK_INTERNAL_DECL void duk_heap_free_freelists(duk_heap *heap);\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL_DECL void duk_heap_run_finalizer(duk_heap *heap, duk_hobject *obj);\nDUK_INTERNAL_DECL void duk_heap_process_finalize_list(duk_heap *heap);\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_INTERNAL_DECL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags);\n\nDUK_INTERNAL_DECL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len);\n\n#endif  /* DUK_HEAP_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_heap_alloc.c",
    "content": "/*\n *  duk_heap allocation and freeing.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_ROM_STRINGS)\n/* Fixed seed value used with ROM strings. */\n#define DUK__FIXED_HASH_SEED       0xabcd1234\n#endif\n\n/*\n *  Free a heap object.\n *\n *  Free heap object and its internal (non-heap) pointers.  Assumes that\n *  caller has removed the object from heap allocated list or the string\n *  intern table, and any weak references (which strings may have) have\n *  been already dealt with.\n */\n\nDUK_INTERNAL void duk_free_hobject(duk_heap *heap, duk_hobject *h) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_FREE(heap, DUK_HOBJECT_GET_PROPS(heap, h));\n\n\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tDUK_UNREF(f);\n\t\t/* Currently nothing to free; 'data' is a heap object */\n\t} else if (DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\tduk_hnatfunc *f = (duk_hnatfunc *) h;\n\t\tDUK_UNREF(f);\n\t\t/* Currently nothing to free */\n\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tduk_activation *act;\n\n\t\tDUK_FREE(heap, t->valstack);\n\n\t\t/* Don't free h->resumer because it exists in the heap.\n\t\t * Callstack entries also contain function pointers which\n\t\t * are not freed for the same reason.  They are decref\n\t\t * finalized and the targets are freed if necessary based\n\t\t * on their refcount (or reachability).\n\t\t */\n\t\tfor (act = t->callstack_curr; act != NULL;) {\n\t\t\tduk_activation *act_next;\n\t\t\tduk_catcher *cat;\n\n\t\t\tfor (cat = act->cat; cat != NULL;) {\n\t\t\t\tduk_catcher *cat_next;\n\n\t\t\t\tcat_next = cat->parent;\n\t\t\t\tDUK_FREE(heap, (void *) cat);\n\t\t\t\tcat = cat_next;\n\t\t\t}\n\n\t\t\tact_next = act->parent;\n\t\t\tDUK_FREE(heap, (void *) act);\n\t\t\tact = act_next;\n\t\t}\n\n\t\t/* XXX: with 'caller' property the callstack would need\n\t\t * to be unwound to update the 'caller' properties of\n\t\t * functions in the callstack.\n\t\t */\n\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {\n\t\tduk_hboundfunc *f = (duk_hboundfunc *) (void *) h;\n\n\t\tDUK_FREE(heap, f->args);\n\t}\n\n\tDUK_FREE(heap, (void *) h);\n}\n\nDUK_INTERNAL void duk_free_hbuffer(duk_heap *heap, duk_hbuffer *h) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n\tif (DUK_HBUFFER_HAS_DYNAMIC(h) && !DUK_HBUFFER_HAS_EXTERNAL(h)) {\n\t\tduk_hbuffer_dynamic *g = (duk_hbuffer_dynamic *) h;\n\t\tDUK_DDD(DUK_DDDPRINT(\"free dynamic buffer %p\", (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, g)));\n\t\tDUK_FREE(heap, DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap, g));\n\t}\n\tDUK_FREE(heap, (void *) h);\n}\n\nDUK_INTERNAL void duk_free_hstring(duk_heap *heap, duk_hstring *h) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n\tDUK_UNREF(heap);\n\tDUK_UNREF(h);\n\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_FREE)\n\tif (DUK_HSTRING_HAS_EXTDATA(h)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"free extstr: hstring %!O, extdata: %p\",\n\t\t                     h, DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) h)));\n\t\tDUK_USE_EXTSTR_FREE(heap->heap_udata, (const void *) DUK_HSTRING_GET_EXTDATA((duk_hstring_external *) h));\n\t}\n#endif\n\tDUK_FREE(heap, (void *) h);\n}\n\nDUK_INTERNAL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr) {\n\tDUK_ASSERT(heap);\n\tDUK_ASSERT(hdr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"free heaphdr %p, htype %ld\", (void *) hdr, (long) DUK_HEAPHDR_GET_TYPE(hdr)));\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(hdr)) {\n\tcase DUK_HTYPE_STRING:\n\t\tduk_free_hstring(heap, (duk_hstring *) hdr);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tduk_free_hobject(heap, (duk_hobject *) hdr);\n\t\tbreak;\n\tdefault:\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) == DUK_HTYPE_BUFFER);\n\t\tduk_free_hbuffer(heap, (duk_hbuffer *) hdr);\n\t}\n\n}\n\n/*\n *  Free the heap.\n *\n *  Frees heap-related non-heap-tracked allocations such as the\n *  string intern table; then frees the heap allocated objects;\n *  and finally frees the heap structure itself.  Reference counts\n *  and GC markers are ignored (and not updated) in this process,\n *  and finalizers won't be called.\n *\n *  The heap pointer and heap object pointers must not be used\n *  after this call.\n */\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\nDUK_LOCAL duk_size_t duk__heap_free_activation_freelist(duk_heap *heap) {\n\tduk_activation *act;\n\tduk_activation *act_next;\n\tduk_size_t count_act = 0;\n\n\tfor (act = heap->activation_free; act != NULL;) {\n\t\tact_next = act->parent;\n\t\tDUK_FREE(heap, (void *) act);\n\t\tact = act_next;\n#if defined(DUK_USE_DEBUG)\n\t\tcount_act++;\n#endif\n\t}\n\theap->activation_free = NULL;  /* needed when called from mark-and-sweep */\n\treturn count_act;\n}\n#endif  /* DUK_USE_CACHE_ACTIVATION */\n\n#if defined(DUK_USE_CACHE_CATCHER)\nDUK_LOCAL duk_size_t duk__heap_free_catcher_freelist(duk_heap *heap) {\n\tduk_catcher *cat;\n\tduk_catcher *cat_next;\n\tduk_size_t count_cat = 0;\n\n\tfor (cat = heap->catcher_free; cat != NULL;) {\n\t\tcat_next = cat->parent;\n\t\tDUK_FREE(heap, (void *) cat);\n\t\tcat = cat_next;\n#if defined(DUK_USE_DEBUG)\n\t\tcount_cat++;\n#endif\n\t}\n\theap->catcher_free = NULL;  /* needed when called from mark-and-sweep */\n\n\treturn count_cat;\n}\n#endif  /* DUK_USE_CACHE_CATCHER */\n\nDUK_INTERNAL void duk_heap_free_freelists(duk_heap *heap) {\n\tduk_size_t count_act = 0;\n\tduk_size_t count_cat = 0;\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\tcount_act = duk__heap_free_activation_freelist(heap);\n#endif\n#if defined(DUK_USE_CACHE_CATCHER)\n\tcount_cat = duk__heap_free_catcher_freelist(heap);\n#endif\n\tDUK_UNREF(heap);\n\tDUK_UNREF(count_act);\n\tDUK_UNREF(count_cat);\n\n\tDUK_D(DUK_DPRINT(\"freed %ld activation freelist entries, %ld catcher freelist entries\",\n\t                 (long) count_act, (long) count_cat));\n}\n\nDUK_LOCAL void duk__free_allocated(duk_heap *heap) {\n\tduk_heaphdr *curr;\n\tduk_heaphdr *next;\n\n\tcurr = heap->heap_allocated;\n\twhile (curr) {\n\t\t/* We don't log or warn about freeing zero refcount objects\n\t\t * because they may happen with finalizer processing.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"FINALFREE (allocated): %!iO\",\n\t\t                     (duk_heaphdr *) curr));\n\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\tduk_heap_free_heaphdr_raw(heap, curr);\n\t\tcurr = next;\n\t}\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__free_finalize_list(duk_heap *heap) {\n\tduk_heaphdr *curr;\n\tduk_heaphdr *next;\n\n\tcurr = heap->finalize_list;\n\twhile (curr) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"FINALFREE (finalize_list): %!iO\",\n\t\t                     (duk_heaphdr *) curr));\n\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\tduk_heap_free_heaphdr_raw(heap, curr);\n\t\tcurr = next;\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_LOCAL void duk__free_stringtable(duk_heap *heap) {\n\t/* strings are only tracked by stringtable */\n\tduk_heap_strtable_free(heap);\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__free_run_finalizers(duk_heap *heap) {\n\tduk_heaphdr *curr;\n\tduk_uint_t round_no;\n\tduk_size_t count_all;\n\tduk_size_t count_finalized;\n\tduk_size_t curr_limit;\n\n\tDUK_ASSERT(heap != NULL);\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* refzero not running -> must be empty */\n#endif\n\tDUK_ASSERT(heap->finalize_list == NULL);  /* mark-and-sweep last pass */\n\n\tif (heap->heap_thread == NULL) {\n\t\t/* May happen when heap allocation fails right off.  There\n\t\t * cannot be any finalizable objects in this case.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"no heap_thread in heap destruct, assume no finalizable objects\"));\n\t\treturn;\n\t}\n\n\t/* Prevent finalize_list processing and mark-and-sweep entirely.\n\t * Setting ms_running != 0 also prevents refzero handling from moving\n\t * objects away from the heap_allocated list.  The flag name is a bit\n\t * misleading here.\n\t *\n\t * Use a distinct value for ms_running here (== 2) so that assertions\n\t * can detect this situation separate from the normal runtime\n\t * mark-and-sweep case.  This allows better assertions (GH-2030).\n\t */\n\tDUK_ASSERT(heap->pf_prevent_count == 0);\n\tDUK_ASSERT(heap->ms_running == 0);\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\theap->pf_prevent_count = 1;\n\theap->ms_running = 2;  /* Use distinguishable value. */\n\theap->ms_prevent_count = 1;  /* Bump, because mark-and-sweep assumes it's bumped when ms_running is set. */\n\n\tcurr_limit = 0;  /* suppress warning, not used */\n\tfor (round_no = 0; ; round_no++) {\n\t\tcurr = heap->heap_allocated;\n\t\tcount_all = 0;\n\t\tcount_finalized = 0;\n\t\twhile (curr) {\n\t\t\tcount_all++;\n\t\t\tif (DUK_HEAPHDR_IS_OBJECT(curr)) {\n\t\t\t\t/* Only objects in heap_allocated may have finalizers.  Check that\n\t\t\t\t * the object itself has a _Finalizer property (own or inherited)\n\t\t\t\t * so that we don't execute finalizers for e.g. Proxy objects.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(curr != NULL);\n\n\t\t\t\tif (DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) curr)) {\n\t\t\t\t\tif (!DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) curr)) {\n\t\t\t\t\t\tDUK_ASSERT(DUK_HEAP_HAS_FINALIZER_NORESCUE(heap));  /* maps to finalizer 2nd argument */\n\t\t\t\t\t\tduk_heap_run_finalizer(heap, (duk_hobject *) curr);\n\t\t\t\t\t\tcount_finalized++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcurr = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\t}\n\n\t\t/* Each round of finalizer execution may spawn new finalizable objects\n\t\t * which is normal behavior for some applications.  Allow multiple\n\t\t * rounds of finalization, but use a shrinking limit based on the\n\t\t * first round to detect the case where a runaway finalizer creates\n\t\t * an unbounded amount of new finalizable objects.  Finalizer rescue\n\t\t * is not supported: the semantics are unclear because most of the\n\t\t * objects being finalized here are already reachable.  The finalizer\n\t\t * is given a boolean to indicate that rescue is not possible.\n\t\t *\n\t\t * See discussion in: https://github.com/svaarala/duktape/pull/473\n\t\t */\n\n\t\tif (round_no == 0) {\n\t\t\t/* Cannot wrap: each object is at least 8 bytes so count is\n\t\t\t * at most 1/8 of that.\n\t\t\t */\n\t\t\tcurr_limit = count_all * 2;\n\t\t} else {\n\t\t\tcurr_limit = (curr_limit * 3) / 4;   /* Decrease by 25% every round */\n\t\t}\n\t\tDUK_D(DUK_DPRINT(\"finalizer round %ld complete, %ld objects, tried to execute %ld finalizers, current limit is %ld\",\n\t\t                 (long) round_no, (long) count_all, (long) count_finalized, (long) curr_limit));\n\n\t\tif (count_finalized == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"no more finalizable objects, forced finalization finished\"));\n\t\t\tbreak;\n\t\t}\n\t\tif (count_finalized >= curr_limit) {\n\t\t\tDUK_D(DUK_DPRINT(\"finalizer count above limit, potentially runaway finalizer; skip remaining finalizers\"));\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tDUK_ASSERT(heap->ms_running == 2);\n\tDUK_ASSERT(heap->pf_prevent_count == 1);\n\theap->ms_running = 0;\n\theap->pf_prevent_count = 0;\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\nDUK_INTERNAL void duk_heap_free(duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"free heap: %p\", (void *) heap));\n\n#if defined(DUK_USE_DEBUG)\n\tduk_heap_strtable_dump(heap);\n#endif\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t/* Detach a debugger if attached (can be called multiple times)\n\t * safely.\n\t */\n\t/* XXX: Add a flag to reject an attempt to re-attach?  Otherwise\n\t * the detached callback may immediately reattach.\n\t */\n\tduk_debug_do_detach(heap);\n#endif\n\n\t/* Execute finalizers before freeing the heap, even for reachable\n\t * objects.  This gives finalizers the chance to free any native\n\t * resources like file handles, allocations made outside Duktape,\n\t * etc.  This is quite tricky to get right, so that all finalizer\n\t * guarantees are honored.\n\t *\n\t * Run mark-and-sweep a few times just in case (unreachable object\n\t * finalizers run already here).  The last round must rescue objects\n\t * from the previous round without running any more finalizers.  This\n\t * ensures rescued objects get their FINALIZED flag cleared so that\n\t * their finalizer is called once more in forced finalization to\n\t * satisfy finalizer guarantees.  However, we don't want to run any\n\t * more finalizers because that'd required one more loop, and so on.\n\t *\n\t * XXX: this perhaps requires an execution time limit.\n\t */\n\tDUK_D(DUK_DPRINT(\"execute finalizers before freeing heap\"));\n\tDUK_ASSERT(heap->pf_skip_finalizers == 0);\n\tDUK_D(DUK_DPRINT(\"forced gc #1 in heap destruction\"));\n\tduk_heap_mark_and_sweep(heap, 0);\n\tDUK_D(DUK_DPRINT(\"forced gc #2 in heap destruction\"));\n\tduk_heap_mark_and_sweep(heap, 0);\n\tDUK_D(DUK_DPRINT(\"forced gc #3 in heap destruction (don't run finalizers)\"));\n\theap->pf_skip_finalizers = 1;\n\tduk_heap_mark_and_sweep(heap, 0);  /* Skip finalizers; queue finalizable objects to heap_allocated. */\n\n\t/* There are never objects in refzero_list at this point, or at any\n\t * point beyond a DECREF (even a DECREF_NORZ).  Since Duktape 2.1\n\t * refzero_list processing is side effect free, so it is always\n\t * processed to completion by a DECREF initially triggering a zero\n\t * refcount.\n\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always processed to completion inline. */\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tDUK_ASSERT(heap->finalize_list == NULL);  /* Last mark-and-sweep with skip_finalizers. */\n#endif\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tDUK_D(DUK_DPRINT(\"run finalizers for remaining finalizable objects\"));\n\tDUK_HEAP_SET_FINALIZER_NORESCUE(heap);  /* Rescue no longer supported. */\n\tduk__free_run_finalizers(heap);\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n\t/* Note: heap->heap_thread, heap->curr_thread, and heap->heap_object\n\t * are on the heap allocated list.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"freeing temporary freelists\"));\n\tduk_heap_free_freelists(heap);\n\n\tDUK_D(DUK_DPRINT(\"freeing heap_allocated of heap: %p\", (void *) heap));\n\tduk__free_allocated(heap);\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always processed to completion inline. */\n#endif\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tDUK_D(DUK_DPRINT(\"freeing finalize_list of heap: %p\", (void *) heap));\n\tduk__free_finalize_list(heap);\n#endif\n\n\tDUK_D(DUK_DPRINT(\"freeing string table of heap: %p\", (void *) heap));\n\tduk__free_stringtable(heap);\n\n\tDUK_D(DUK_DPRINT(\"freeing heap structure: %p\", (void *) heap));\n\theap->free_func(heap->heap_udata, heap);\n}\n\n/*\n *  Allocate a heap.\n *\n *  String table is initialized with built-in strings from genbuiltins.py,\n *  either by dynamically creating the strings or by referring to ROM strings.\n */\n\n#if defined(DUK_USE_ROM_STRINGS)\nDUK_LOCAL duk_bool_t duk__init_heap_strings(duk_heap *heap) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_small_uint_t i;\n#endif\n\n\tDUK_UNREF(heap);\n\n\t/* With ROM-based strings, heap->strs[] and thr->strs[] are omitted\n\t * so nothing to initialize for strs[].\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tfor (i = 0; i < sizeof(duk_rom_strings_lookup) / sizeof(const duk_hstring *); i++) {\n\t\tconst duk_hstring *h;\n\t\tduk_uint32_t hash;\n\n\t\th = duk_rom_strings_lookup[i];\n\t\twhile (h != NULL) {\n\t\t\thash = duk_heap_hashstring(heap, (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\t\t\tDUK_DD(DUK_DDPRINT(\"duk_rom_strings_lookup[%d] -> hash 0x%08lx, computed 0x%08lx\",\n\t\t\t                   (int) i, (unsigned long) DUK_HSTRING_GET_HASH(h), (unsigned long) hash));\n\t\t\tDUK_ASSERT(hash == (duk_uint32_t) DUK_HSTRING_GET_HASH(h));\n\n\t\t\th = (const duk_hstring *) h->hdr.h_next;\n\t\t}\n\t}\n#endif\n\treturn 1;\n}\n#else  /* DUK_USE_ROM_STRINGS */\n\nDUK_LOCAL duk_bool_t duk__init_heap_strings(duk_heap *heap) {\n\tduk_bitdecoder_ctx bd_ctx;\n\tduk_bitdecoder_ctx *bd = &bd_ctx;  /* convenience */\n\tduk_small_uint_t i;\n\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tbd->data = (const duk_uint8_t *) duk_strings_data;\n\tbd->length = (duk_size_t) DUK_STRDATA_DATA_LENGTH;\n\n\tfor (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) {\n\t\tduk_uint8_t tmp[DUK_STRDATA_MAX_STRLEN];\n\t\tduk_small_uint_t len;\n\t\tduk_hstring *h;\n\n\t\tlen = duk_bd_decode_bitpacked_string(bd, tmp);\n\n\t\t/* No need to length check string: it will never exceed even\n\t\t * the 16-bit length maximum.\n\t\t */\n\t\tDUK_ASSERT(len <= 0xffffUL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"intern built-in string %ld\", (long) i));\n\t\th = duk_heap_strtable_intern(heap, tmp, len);\n\t\tif (!h) {\n\t\t\tgoto failed;\n\t\t}\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h));\n\n\t\t/* Special flags checks.  Since these strings are always\n\t\t * reachable and a string cannot appear twice in the string\n\t\t * table, there's no need to check/set these flags elsewhere.\n\t\t * The 'internal' flag is set by string intern code.\n\t\t */\n\t\tif (i == DUK_STRIDX_EVAL || i == DUK_STRIDX_LC_ARGUMENTS) {\n\t\t\tDUK_HSTRING_SET_EVAL_OR_ARGUMENTS(h);\n\t\t}\n\t\tif (i >= DUK_STRIDX_START_RESERVED && i < DUK_STRIDX_END_RESERVED) {\n\t\t\tDUK_HSTRING_SET_RESERVED_WORD(h);\n\t\t\tif (i >= DUK_STRIDX_START_STRICT_RESERVED) {\n\t\t\t\tDUK_HSTRING_SET_STRICT_RESERVED_WORD(h);\n\t\t\t}\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"interned: %!O\", (duk_heaphdr *) h));\n\n\t\t/* XXX: The incref macro takes a thread pointer but doesn't\n\t\t * use it right now.\n\t\t */\n\t\tDUK_HSTRING_INCREF(_never_referenced_, h);\n\n#if defined(DUK_USE_HEAPPTR16)\n\t\theap->strs16[i] = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) h);\n#else\n\t\theap->strs[i] = h;\n#endif\n\t}\n\n\treturn 1;\n\n failed:\n\treturn 0;\n}\n#endif  /* DUK_USE_ROM_STRINGS */\n\nDUK_LOCAL duk_bool_t duk__init_heap_thread(duk_heap *heap) {\n\tduk_hthread *thr;\n\n\tDUK_D(DUK_DPRINT(\"heap init: alloc heap thread\"));\n\tthr = duk_hthread_alloc_unchecked(heap,\n\t                                  DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                  DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_THREAD));\n\tif (thr == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"failed to alloc heap_thread\"));\n\t\treturn 0;\n\t}\n\tthr->state = DUK_HTHREAD_STATE_INACTIVE;\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* No strs[] pointer. */\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n\tthr->strs16 = heap->strs16;\n#else\n\tthr->strs = heap->strs;\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n\theap->heap_thread = thr;\n\tDUK_HTHREAD_INCREF(thr, thr);  /* Note: first argument not really used */\n\n\t/* 'thr' is now reachable */\n\n\tDUK_D(DUK_DPRINT(\"heap init: init heap thread stacks\"));\n\tif (!duk_hthread_init_stacks(heap, thr)) {\n\t\treturn 0;\n\t}\n\n\t/* XXX: this may now fail, and is not handled correctly */\n\tduk_hthread_create_builtin_objects(thr);\n\n\t/* default prototype */\n\tDUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr, (duk_hobject *) thr, thr->builtins[DUK_BIDX_THREAD_PROTOTYPE]);\n\n\treturn 1;\n}\n\n#if defined(DUK_USE_DEBUG)\n#define DUK__DUMPSZ(t)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"\" #t \"=%ld\", (long) sizeof(t))); \\\n\t} while (0)\n\n/* These is not 100% because format would need to be non-portable \"long long\".\n * Also print out as doubles to catch cases where the \"long\" type is not wide\n * enough; the limits will then not be printed accurately but the magnitude\n * will be correct.\n */\n#define DUK__DUMPLM_SIGNED_RAW(t,a,b)  do { \\\n\t\tDUK_D(DUK_DPRINT(t \"=[%ld,%ld]=[%lf,%lf]\", \\\n\t\t                 (long) (a), (long) (b), \\\n\t\t                 (double) (a), (double) (b))); \\\n\t} while (0)\n#define DUK__DUMPLM_UNSIGNED_RAW(t,a,b)  do { \\\n\t\tDUK_D(DUK_DPRINT(t \"=[%lu,%lu]=[%lf,%lf]\", \\\n\t\t                 (unsigned long) (a), (unsigned long) (b), \\\n\t\t                 (double) (a), (double) (b))); \\\n\t} while (0)\n#define DUK__DUMPLM_SIGNED(t)  do { \\\n\t\tDUK__DUMPLM_SIGNED_RAW(\"DUK_\" #t \"_{MIN,MAX}\", DUK_##t##_MIN, DUK_##t##_MAX); \\\n\t} while (0)\n#define DUK__DUMPLM_UNSIGNED(t)  do { \\\n\t\tDUK__DUMPLM_UNSIGNED_RAW(\"DUK_\" #t \"_{MIN,MAX}\", DUK_##t##_MIN, DUK_##t##_MAX); \\\n\t} while (0)\n\nDUK_LOCAL void duk__dump_type_sizes(void) {\n\tDUK_D(DUK_DPRINT(\"sizeof()\"));\n\n\t/* basic platform types */\n\tDUK__DUMPSZ(char);\n\tDUK__DUMPSZ(short);\n\tDUK__DUMPSZ(int);\n\tDUK__DUMPSZ(long);\n\tDUK__DUMPSZ(double);\n\tDUK__DUMPSZ(void *);\n\tDUK__DUMPSZ(size_t);\n\n\t/* basic types from duk_features.h */\n\tDUK__DUMPSZ(duk_uint8_t);\n\tDUK__DUMPSZ(duk_int8_t);\n\tDUK__DUMPSZ(duk_uint16_t);\n\tDUK__DUMPSZ(duk_int16_t);\n\tDUK__DUMPSZ(duk_uint32_t);\n\tDUK__DUMPSZ(duk_int32_t);\n\tDUK__DUMPSZ(duk_uint64_t);\n\tDUK__DUMPSZ(duk_int64_t);\n\tDUK__DUMPSZ(duk_uint_least8_t);\n\tDUK__DUMPSZ(duk_int_least8_t);\n\tDUK__DUMPSZ(duk_uint_least16_t);\n\tDUK__DUMPSZ(duk_int_least16_t);\n\tDUK__DUMPSZ(duk_uint_least32_t);\n\tDUK__DUMPSZ(duk_int_least32_t);\n#if defined(DUK_USE_64BIT_OPS)\n\tDUK__DUMPSZ(duk_uint_least64_t);\n\tDUK__DUMPSZ(duk_int_least64_t);\n#endif\n\tDUK__DUMPSZ(duk_uint_fast8_t);\n\tDUK__DUMPSZ(duk_int_fast8_t);\n\tDUK__DUMPSZ(duk_uint_fast16_t);\n\tDUK__DUMPSZ(duk_int_fast16_t);\n\tDUK__DUMPSZ(duk_uint_fast32_t);\n\tDUK__DUMPSZ(duk_int_fast32_t);\n#if defined(DUK_USE_64BIT_OPS)\n\tDUK__DUMPSZ(duk_uint_fast64_t);\n\tDUK__DUMPSZ(duk_int_fast64_t);\n#endif\n\tDUK__DUMPSZ(duk_uintptr_t);\n\tDUK__DUMPSZ(duk_intptr_t);\n\tDUK__DUMPSZ(duk_uintmax_t);\n\tDUK__DUMPSZ(duk_intmax_t);\n\tDUK__DUMPSZ(duk_double_t);\n\n\t/* important chosen base types */\n\tDUK__DUMPSZ(duk_int_t);\n\tDUK__DUMPSZ(duk_uint_t);\n\tDUK__DUMPSZ(duk_int_fast_t);\n\tDUK__DUMPSZ(duk_uint_fast_t);\n\tDUK__DUMPSZ(duk_small_int_t);\n\tDUK__DUMPSZ(duk_small_uint_t);\n\tDUK__DUMPSZ(duk_small_int_fast_t);\n\tDUK__DUMPSZ(duk_small_uint_fast_t);\n\n\t/* some derived types */\n\tDUK__DUMPSZ(duk_codepoint_t);\n\tDUK__DUMPSZ(duk_ucodepoint_t);\n\tDUK__DUMPSZ(duk_idx_t);\n\tDUK__DUMPSZ(duk_errcode_t);\n\tDUK__DUMPSZ(duk_uarridx_t);\n\n\t/* tval */\n\tDUK__DUMPSZ(duk_double_union);\n\tDUK__DUMPSZ(duk_tval);\n\n\t/* structs from duk_forwdecl.h */\n\tDUK__DUMPSZ(duk_jmpbuf);  /* just one 'int' for C++ exceptions */\n\tDUK__DUMPSZ(duk_heaphdr);\n\tDUK__DUMPSZ(duk_heaphdr_string);\n\tDUK__DUMPSZ(duk_hstring);\n\tDUK__DUMPSZ(duk_hstring_external);\n\tDUK__DUMPSZ(duk_hobject);\n\tDUK__DUMPSZ(duk_harray);\n\tDUK__DUMPSZ(duk_hcompfunc);\n\tDUK__DUMPSZ(duk_hnatfunc);\n\tDUK__DUMPSZ(duk_hdecenv);\n\tDUK__DUMPSZ(duk_hobjenv);\n\tDUK__DUMPSZ(duk_hthread);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\tDUK__DUMPSZ(duk_hbufobj);\n#endif\n\tDUK__DUMPSZ(duk_hproxy);\n\tDUK__DUMPSZ(duk_hbuffer);\n\tDUK__DUMPSZ(duk_hbuffer_fixed);\n\tDUK__DUMPSZ(duk_hbuffer_dynamic);\n\tDUK__DUMPSZ(duk_hbuffer_external);\n\tDUK__DUMPSZ(duk_propaccessor);\n\tDUK__DUMPSZ(duk_propvalue);\n\tDUK__DUMPSZ(duk_propdesc);\n\tDUK__DUMPSZ(duk_heap);\n\tDUK__DUMPSZ(duk_activation);\n\tDUK__DUMPSZ(duk_catcher);\n\tDUK__DUMPSZ(duk_strcache_entry);\n\tDUK__DUMPSZ(duk_litcache_entry);\n\tDUK__DUMPSZ(duk_ljstate);\n\tDUK__DUMPSZ(duk_fixedbuffer);\n\tDUK__DUMPSZ(duk_bitdecoder_ctx);\n\tDUK__DUMPSZ(duk_bitencoder_ctx);\n\tDUK__DUMPSZ(duk_token);\n\tDUK__DUMPSZ(duk_re_token);\n\tDUK__DUMPSZ(duk_lexer_point);\n\tDUK__DUMPSZ(duk_lexer_ctx);\n\tDUK__DUMPSZ(duk_compiler_instr);\n\tDUK__DUMPSZ(duk_compiler_func);\n\tDUK__DUMPSZ(duk_compiler_ctx);\n\tDUK__DUMPSZ(duk_re_matcher_ctx);\n\tDUK__DUMPSZ(duk_re_compiler_ctx);\n}\nDUK_LOCAL void duk__dump_type_limits(void) {\n\tDUK_D(DUK_DPRINT(\"limits\"));\n\n\t/* basic types */\n\tDUK__DUMPLM_SIGNED(INT8);\n\tDUK__DUMPLM_UNSIGNED(UINT8);\n\tDUK__DUMPLM_SIGNED(INT_FAST8);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST8);\n\tDUK__DUMPLM_SIGNED(INT_LEAST8);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST8);\n\tDUK__DUMPLM_SIGNED(INT16);\n\tDUK__DUMPLM_UNSIGNED(UINT16);\n\tDUK__DUMPLM_SIGNED(INT_FAST16);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST16);\n\tDUK__DUMPLM_SIGNED(INT_LEAST16);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST16);\n\tDUK__DUMPLM_SIGNED(INT32);\n\tDUK__DUMPLM_UNSIGNED(UINT32);\n\tDUK__DUMPLM_SIGNED(INT_FAST32);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST32);\n\tDUK__DUMPLM_SIGNED(INT_LEAST32);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST32);\n#if defined(DUK_USE_64BIT_OPS)\n\tDUK__DUMPLM_SIGNED(INT64);\n\tDUK__DUMPLM_UNSIGNED(UINT64);\n\tDUK__DUMPLM_SIGNED(INT_FAST64);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST64);\n\tDUK__DUMPLM_SIGNED(INT_LEAST64);\n\tDUK__DUMPLM_UNSIGNED(UINT_LEAST64);\n#endif\n\tDUK__DUMPLM_SIGNED(INTPTR);\n\tDUK__DUMPLM_UNSIGNED(UINTPTR);\n\tDUK__DUMPLM_SIGNED(INTMAX);\n\tDUK__DUMPLM_UNSIGNED(UINTMAX);\n\n\t/* derived types */\n\tDUK__DUMPLM_SIGNED(INT);\n\tDUK__DUMPLM_UNSIGNED(UINT);\n\tDUK__DUMPLM_SIGNED(INT_FAST);\n\tDUK__DUMPLM_UNSIGNED(UINT_FAST);\n\tDUK__DUMPLM_SIGNED(SMALL_INT);\n\tDUK__DUMPLM_UNSIGNED(SMALL_UINT);\n\tDUK__DUMPLM_SIGNED(SMALL_INT_FAST);\n\tDUK__DUMPLM_UNSIGNED(SMALL_UINT_FAST);\n}\n\nDUK_LOCAL void duk__dump_misc_options(void) {\n\tDUK_D(DUK_DPRINT(\"DUK_VERSION: %ld\", (long) DUK_VERSION));\n\tDUK_D(DUK_DPRINT(\"DUK_GIT_DESCRIBE: %s\", DUK_GIT_DESCRIBE));\n\tDUK_D(DUK_DPRINT(\"OS string: %s\", DUK_USE_OS_STRING));\n\tDUK_D(DUK_DPRINT(\"architecture string: %s\", DUK_USE_ARCH_STRING));\n\tDUK_D(DUK_DPRINT(\"compiler string: %s\", DUK_USE_COMPILER_STRING));\n\tDUK_D(DUK_DPRINT(\"debug level: %ld\", (long) DUK_USE_DEBUG_LEVEL));\n#if defined(DUK_USE_PACKED_TVAL)\n\tDUK_D(DUK_DPRINT(\"DUK_USE_PACKED_TVAL: yes\"));\n#else\n\tDUK_D(DUK_DPRINT(\"DUK_USE_PACKED_TVAL: no\"));\n#endif\n#if defined(DUK_USE_VARIADIC_MACROS)\n\tDUK_D(DUK_DPRINT(\"DUK_USE_VARIADIC_MACROS: yes\"));\n#else\n\tDUK_D(DUK_DPRINT(\"DUK_USE_VARIADIC_MACROS: no\"));\n#endif\n#if defined(DUK_USE_INTEGER_LE)\n\tDUK_D(DUK_DPRINT(\"integer endianness: little\"));\n#elif defined(DUK_USE_INTEGER_ME)\n\tDUK_D(DUK_DPRINT(\"integer endianness: mixed\"));\n#elif defined(DUK_USE_INTEGER_BE)\n\tDUK_D(DUK_DPRINT(\"integer endianness: big\"));\n#else\n\tDUK_D(DUK_DPRINT(\"integer endianness: ???\"));\n#endif\n#if defined(DUK_USE_DOUBLE_LE)\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: little\"));\n#elif defined(DUK_USE_DOUBLE_ME)\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: mixed\"));\n#elif defined(DUK_USE_DOUBLE_BE)\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: big\"));\n#else\n\tDUK_D(DUK_DPRINT(\"IEEE double endianness: ???\"));\n#endif\n}\n#endif  /* DUK_USE_DEBUG */\n\nDUK_INTERNAL\nduk_heap *duk_heap_alloc(duk_alloc_function alloc_func,\n                         duk_realloc_function realloc_func,\n                         duk_free_function free_func,\n                         void *heap_udata,\n                         duk_fatal_function fatal_func) {\n\tduk_heap *res = NULL;\n\tduk_uint32_t st_initsize;\n\n\tDUK_D(DUK_DPRINT(\"allocate heap\"));\n\n\t/*\n\t *  Random config sanity asserts\n\t */\n\n\tDUK_ASSERT(DUK_USE_STRTAB_MINSIZE >= 64);\n\n\tDUK_ASSERT((DUK_HTYPE_STRING & 0x01U) == 0);\n\tDUK_ASSERT((DUK_HTYPE_BUFFER & 0x01U) == 0);\n\tDUK_ASSERT((DUK_HTYPE_OBJECT & 0x01U) == 1);  /* DUK_HEAPHDR_IS_OBJECT() relies ont his. */\n\n\t/*\n\t *  Debug dump type sizes\n\t */\n\n#if defined(DUK_USE_DEBUG)\n\tduk__dump_misc_options();\n\tduk__dump_type_sizes();\n\tduk__dump_type_limits();\n#endif\n\n\t/*\n\t *  If selftests enabled, run them as early as possible.\n\t */\n\n#if defined(DUK_USE_SELF_TESTS)\n\tDUK_D(DUK_DPRINT(\"run self tests\"));\n\tif (duk_selftest_run_tests(alloc_func, realloc_func, free_func, heap_udata) > 0) {\n\t\tfatal_func(heap_udata, \"self test(s) failed\");\n\t}\n\tDUK_D(DUK_DPRINT(\"self tests passed\"));\n#endif\n\n\t/*\n\t *  Important assert-like checks that should be enabled even\n\t *  when assertions are otherwise not enabled.\n\t */\n\n#if defined(DUK_USE_EXEC_REGCONST_OPTIMIZE)\n\t/* Can't check sizeof() using preprocessor so explicit check.\n\t * This will be optimized away in practice; unfortunately a\n\t * warning is generated on some compilers as a result.\n\t */\n#if defined(DUK_USE_PACKED_TVAL)\n\tif (sizeof(duk_tval) != 8) {\n#else\n\tif (sizeof(duk_tval) != 16) {\n#endif\n\t\tfatal_func(heap_udata, \"sizeof(duk_tval) not 8 or 16, cannot use DUK_USE_EXEC_REGCONST_OPTIMIZE option\");\n\t}\n#endif  /* DUK_USE_EXEC_REGCONST_OPTIMIZE */\n\n\t/*\n\t *  Computed values (e.g. INFINITY)\n\t */\n\n#if defined(DUK_USE_COMPUTED_NAN)\n\tdo {\n\t\t/* Workaround for some exotic platforms where NAN is missing\n\t\t * and the expression (0.0 / 0.0) does NOT result in a NaN.\n\t\t * Such platforms use the global 'duk_computed_nan' which must\n\t\t * be initialized at runtime.  Use 'volatile' to ensure that\n\t\t * the compiler will actually do the computation and not try\n\t\t * to do constant folding which might result in the original\n\t\t * problem.\n\t\t */\n\t\tvolatile double dbl1 = 0.0;\n\t\tvolatile double dbl2 = 0.0;\n\t\tduk_computed_nan = dbl1 / dbl2;\n\t} while (0);\n#endif\n\n#if defined(DUK_USE_COMPUTED_INFINITY)\n\tdo {\n\t\t/* Similar workaround for INFINITY. */\n\t\tvolatile double dbl1 = 1.0;\n\t\tvolatile double dbl2 = 0.0;\n\t\tduk_computed_infinity = dbl1 / dbl2;\n\t} while (0);\n#endif\n\n\t/*\n\t *  Allocate heap struct\n\t *\n\t *  Use a raw call, all macros expect the heap to be initialized\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 1)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"alloc duk_heap object\"));\n\tres = (duk_heap *) alloc_func(heap_udata, sizeof(duk_heap));\n\tif (!res) {\n\t\tgoto failed;\n\t}\n\n\t/*\n\t *  Zero the struct, and start initializing roughly in order\n\t */\n\n\tduk_memzero(res, sizeof(*res));\n#if defined(DUK_USE_ASSERTIONS)\n\tres->heap_initializing = 1;\n#endif\n\n\t/* explicit NULL inits */\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->heap_udata = NULL;\n\tres->heap_allocated = NULL;\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tres->refzero_list = NULL;\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tres->finalize_list = NULL;\n#if defined(DUK_USE_ASSERTIONS)\n\tres->currently_finalizing = NULL;\n#endif\n#endif\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\tres->activation_free = NULL;\n#endif\n#if defined(DUK_USE_CACHE_CATCHER)\n\tres->catcher_free = NULL;\n#endif\n\tres->heap_thread = NULL;\n\tres->curr_thread = NULL;\n\tres->heap_object = NULL;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tres->strtable16 = NULL;\n#else\n\tres->strtable = NULL;\n#endif\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* no res->strs[] */\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n\t/* res->strs16[] is zeroed and zero decodes to NULL, so no NULL inits. */\n#else\n\t{\n\t\tduk_small_uint_t i;\n\t        for (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) {\n\t\t\tres->strs[i] = NULL;\n\t        }\n\t}\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tres->dbg_read_cb = NULL;\n\tres->dbg_write_cb = NULL;\n\tres->dbg_peek_cb = NULL;\n\tres->dbg_read_flush_cb = NULL;\n\tres->dbg_write_flush_cb = NULL;\n\tres->dbg_request_cb = NULL;\n\tres->dbg_udata = NULL;\n\tres->dbg_pause_act = NULL;\n#endif\n#endif  /* DUK_USE_EXPLICIT_NULL_INIT */\n\n\tres->alloc_func = alloc_func;\n\tres->realloc_func = realloc_func;\n\tres->free_func = free_func;\n\tres->heap_udata = heap_udata;\n\tres->fatal_func = fatal_func;\n\n\t/* XXX: for now there's a pointer packing zero assumption, i.e.\n\t * NULL <=> compressed pointer 0.  If this is removed, may need\n\t * to precompute e.g. null16 here.\n\t */\n\n\t/* res->ms_trigger_counter == 0 -> now causes immediate GC; which is OK */\n\n\t/* Prevent mark-and-sweep and finalizer execution until heap is completely\n\t * initialized.\n\t */\n\tDUK_ASSERT(res->ms_prevent_count == 0);\n\tDUK_ASSERT(res->pf_prevent_count == 0);\n\tres->ms_prevent_count = 1;\n\tres->pf_prevent_count = 1;\n\tDUK_ASSERT(res->ms_running == 0);\n\n\tres->call_recursion_depth = 0;\n\tres->call_recursion_limit = DUK_USE_NATIVE_CALL_RECLIMIT;\n\n\t/* XXX: use the pointer as a seed for now: mix in time at least */\n\n\t/* The casts through duk_uintptr_t is to avoid the following GCC warning:\n\t *\n\t *   warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]\n\t *\n\t * This still generates a /Wp64 warning on VS2010 when compiling for x86.\n\t */\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* XXX: make a common DUK_USE_ option, and allow custom fixed seed? */\n\tDUK_D(DUK_DPRINT(\"using rom strings, force heap hash_seed to fixed value 0x%08lx\", (long) DUK__FIXED_HASH_SEED));\n\tres->hash_seed = (duk_uint32_t) DUK__FIXED_HASH_SEED;\n#else  /* DUK_USE_ROM_STRINGS */\n\tres->hash_seed = (duk_uint32_t) (duk_uintptr_t) res;\n#if !defined(DUK_USE_STRHASH_DENSE)\n\tres->hash_seed ^= 5381;  /* Bernstein hash init value is normally 5381; XOR it in in case pointer low bits are 0 */\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->lj.jmpbuf_ptr = NULL;\n#endif\n\tDUK_ASSERT(res->lj.type == DUK_LJ_TYPE_UNKNOWN);  /* zero */\n\tDUK_ASSERT(res->lj.iserror == 0);\n\tDUK_TVAL_SET_UNDEFINED(&res->lj.value1);\n\tDUK_TVAL_SET_UNDEFINED(&res->lj.value2);\n\n\tDUK_ASSERT_LJSTATE_UNSET(res);\n\n\t/*\n\t *  Init stringtable: fixed variant\n\t */\n\n\tst_initsize = DUK_USE_STRTAB_MINSIZE;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tres->strtable16 = (duk_uint16_t *) alloc_func(heap_udata, sizeof(duk_uint16_t) * st_initsize);\n\tif (res->strtable16 == NULL) {\n\t\tgoto failed;\n\t}\n#else\n\tres->strtable = (duk_hstring **) alloc_func(heap_udata, sizeof(duk_hstring *) * st_initsize);\n\tif (res->strtable == NULL) {\n\t\tgoto failed;\n\t}\n#endif\n\tres->st_size = st_initsize;\n\tres->st_mask = st_initsize - 1;\n#if (DUK_USE_STRTAB_MINSIZE != DUK_USE_STRTAB_MAXSIZE)\n\tDUK_ASSERT(res->st_count == 0);\n#endif\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t/* zero assumption */\n\tduk_memzero(res->strtable16, sizeof(duk_uint16_t) * st_initsize);\n#else\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t{\n\t\tduk_uint32_t i;\n\t        for (i = 0; i < st_initsize; i++) {\n\t\t\tres->strtable[i] = NULL;\n\t        }\n\t}\n#else\n\tduk_memzero(res->strtable, sizeof(duk_hstring *) * st_initsize);\n#endif  /* DUK_USE_EXPLICIT_NULL_INIT */\n#endif  /* DUK_USE_STRTAB_PTRCOMP */\n\n\t/*\n\t *  Init stringcache\n\t */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t{\n\t\tduk_uint_t i;\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tres->strcache[i].h = NULL;\n\t\t}\n\t}\n#endif\n\n\t/*\n\t *  Init litcache\n\t */\n#if defined(DUK_USE_LITCACHE_SIZE)\n\tDUK_ASSERT(DUK_USE_LITCACHE_SIZE > 0);\n\tDUK_ASSERT(DUK_IS_POWER_OF_TWO((duk_uint_t) DUK_USE_LITCACHE_SIZE));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t{\n\t\tduk_uint_t i;\n\t\tfor (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) {\n\t\t\tres->litcache[i].addr = NULL;\n\t\t\tres->litcache[i].h = NULL;\n\t\t}\n\t}\n#endif\n#endif  /* DUK_USE_LITCACHE_SIZE */\n\n\t/* XXX: error handling is incomplete.  It would be cleanest if\n\t * there was a setjmp catchpoint, so that all init code could\n\t * freely throw errors.  If that were the case, the return code\n\t * passing here could be removed.\n\t */\n\n\t/*\n\t *  Init built-in strings\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 2)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"heap init: initialize heap strings\"));\n\tif (!duk__init_heap_strings(res)) {\n\t\tgoto failed;\n\t}\n\n\t/*\n\t *  Init the heap thread\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 3)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"heap init: initialize heap thread\"));\n\tif (!duk__init_heap_thread(res)) {\n\t\tgoto failed;\n\t}\n\n\t/*\n\t *  Init the heap object\n\t */\n\n#if defined(DUK_USE_INJECT_HEAP_ALLOC_ERROR) && (DUK_USE_INJECT_HEAP_ALLOC_ERROR == 4)\n\tgoto failed;\n#endif\n\tDUK_D(DUK_DPRINT(\"heap init: initialize heap object\"));\n\tDUK_ASSERT(res->heap_thread != NULL);\n\tres->heap_object = duk_hobject_alloc_unchecked(res, DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                                    DUK_HOBJECT_FLAG_FASTREFS |\n\t                                                    DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT));\n\tif (res->heap_object == NULL) {\n\t\tgoto failed;\n\t}\n\tDUK_HOBJECT_INCREF(res->heap_thread, res->heap_object);\n\n\t/*\n\t *  Odds and ends depending on the heap thread\n\t */\n\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\n#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS)\n\tres->rnd_state = (duk_uint32_t) duk_time_get_ecmascript_time(res->heap_thread);\n\tduk_util_tinyrandom_prepare_seed(res->heap_thread);\n#else\n\tres->rnd_state[0] = (duk_uint64_t) duk_time_get_ecmascript_time(res->heap_thread);\n\tDUK_ASSERT(res->rnd_state[1] == 0);  /* Not filled here, filled in by seed preparation. */\n#if 0  /* Manual test values matching misc/xoroshiro128plus_test.c. */\n\tres->rnd_state[0] = DUK_U64_CONSTANT(0xdeadbeef12345678);\n\tres->rnd_state[1] = DUK_U64_CONSTANT(0xcafed00d12345678);\n#endif\n\tduk_util_tinyrandom_prepare_seed(res->heap_thread);\n\t/* Mix in heap pointer: this ensures that if two Duktape heaps are\n\t * created on the same millisecond, they get a different PRNG\n\t * sequence (unless e.g. virtual memory addresses cause also the\n\t * heap object pointer to be the same).\n\t */\n\t{\n\t\tduk_uint64_t tmp_u64;\n\t\ttmp_u64 = 0;\n\t\tduk_memcpy((void *) &tmp_u64,\n\t\t           (const void *) &res,\n\t\t           (size_t) (sizeof(void *) >= sizeof(duk_uint64_t) ? sizeof(duk_uint64_t) : sizeof(void *)));\n\t\tres->rnd_state[1] ^= tmp_u64;\n\t}\n\tdo {\n\t\tduk_small_uint_t i;\n\t\tfor (i = 0; i < 10; i++) {\n\t\t\t/* Throw away a few initial random numbers just in\n\t\t\t * case.  Probably unnecessary due to SplitMix64\n\t\t\t * preparation.\n\t\t\t */\n\t\t\t(void) duk_util_tinyrandom_get_double(res->heap_thread);\n\t\t}\n\t} while (0);\n#endif\n#endif\n\n\t/*\n\t *  Allow finalizer and mark-and-sweep processing.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"heap init: allow finalizer/mark-and-sweep processing\"));\n\tDUK_ASSERT(res->ms_prevent_count == 1);\n\tDUK_ASSERT(res->pf_prevent_count == 1);\n\tres->ms_prevent_count = 0;\n\tres->pf_prevent_count = 0;\n\tDUK_ASSERT(res->ms_running == 0);\n#if defined(DUK_USE_ASSERTIONS)\n\tres->heap_initializing = 0;\n#endif\n\n\t/*\n\t *  All done.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"allocated heap: %p\", (void *) res));\n\treturn res;\n\n failed:\n\tDUK_D(DUK_DPRINT(\"heap allocation failed\"));\n\n\tif (res != NULL) {\n\t\t/* Assumes that allocated pointers and alloc funcs are valid\n\t\t * if res exists.\n\t\t */\n\t\tDUK_ASSERT(res->ms_prevent_count == 1);\n\t\tDUK_ASSERT(res->pf_prevent_count == 1);\n\t\tDUK_ASSERT(res->ms_running == 0);\n\t\tif (res->heap_thread != NULL) {\n\t\t\tres->ms_prevent_count = 0;\n\t\t\tres->pf_prevent_count = 0;\n\t\t}\n#if defined(DUK_USE_ASSERTIONS)\n\t\tres->heap_initializing = 0;\n#endif\n\n\t\tDUK_ASSERT(res->alloc_func != NULL);\n\t\tDUK_ASSERT(res->realloc_func != NULL);\n\t\tDUK_ASSERT(res->free_func != NULL);\n\t\tduk_heap_free(res);\n\t}\n\n\treturn NULL;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_heap_finalize.c",
    "content": "/*\n *  Finalizer handling.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\n/*\n *  Fake torture finalizer.\n */\n\n#if defined(DUK_USE_FINALIZER_TORTURE)\nDUK_LOCAL duk_ret_t duk__fake_global_finalizer(duk_hthread *thr) {\n\tDUK_DD(DUK_DDPRINT(\"fake global torture finalizer executed\"));\n\n\t/* Require a lot of stack to force a value stack grow/shrink. */\n\tduk_require_stack(thr, 100000);\n\n\t/* Force a reallocation with pointer change for value stack\n\t * to maximize side effects.\n\t */\n\tduk_hthread_valstack_torture_realloc(thr);\n\n\t/* Inner function call, error throw. */\n\tduk_eval_string_noresult(thr,\n\t\t\"(function dummy() {\\n\"\n\t\t\"    dummy.prototype = null;  /* break reference loop */\\n\"\n\t\t\"    try {\\n\"\n\t\t\"        throw 'fake-finalizer-dummy-error';\\n\"\n\t\t\"    } catch (e) {\\n\"\n\t\t\"        void e;\\n\"\n\t\t\"    }\\n\"\n\t\t\"})()\");\n\n\t/* The above creates garbage (e.g. a function instance).  Because\n\t * the function/prototype reference loop is broken, it gets collected\n\t * immediately by DECREF.  If Function.prototype has a _Finalizer\n\t * property (happens in some test cases), the garbage gets queued to\n\t * finalize_list.  This still won't cause an infinite loop because\n\t * the torture finalizer is called once per finalize_list run and\n\t * the garbage gets handled in the same run.  (If the garbage needs\n\t * mark-and-sweep collection, an infinite loop might ensue.)\n\t */\n\treturn 0;\n}\n\nDUK_LOCAL void duk__run_global_torture_finalizer(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Avoid fake finalization when callstack limit is near.  Otherwise\n\t * a callstack limit error will be created, then refzero'ed.  The\n\t * +5 headroom is conservative.\n\t */\n\tif (thr->heap->call_recursion_depth + 5 >= thr->heap->call_recursion_limit ||\n\t    thr->callstack_top + 5 >= DUK_USE_CALLSTACK_LIMIT) {\n\t\tDUK_D(DUK_DPRINT(\"skip global torture finalizer, too little headroom for call recursion or call stack size\"));\n\t\treturn;\n\t}\n\n\t/* Run fake finalizer.  Avoid creating unnecessary garbage. */\n\tduk_push_c_function(thr, duk__fake_global_finalizer, 0 /*nargs*/);\n\t(void) duk_pcall(thr, 0 /*nargs*/);\n\tduk_pop(thr);\n}\n#endif  /* DUK_USE_FINALIZER_TORTURE */\n\n/*\n *  Process the finalize_list to completion.\n *\n *  An object may be placed on finalize_list by either refcounting or\n *  mark-and-sweep.  The refcount of objects placed by refcounting will be\n *  zero; the refcount of objects placed by mark-and-sweep is > 0.  In both\n *  cases the refcount is bumped by 1 artificially so that a REFZERO event\n *  can never happen while an object is waiting for finalization.  Without\n *  this bump a REFZERO could now happen because user code may call\n *  duk_push_heapptr() and then pop a value even when it's on finalize_list.\n *\n *  List processing assumes refcounts are kept up-to-date at all times, so\n *  that once the finalizer returns, a zero refcount is a reliable reason to\n *  free the object immediately rather than place it back to the heap.  This\n *  is the case because we run outside of refzero_list processing so that\n *  DECREF cascades are handled fully inline.\n *\n *  For mark-and-sweep queued objects (had_zero_refcount false) the object\n *  may be freed immediately if its refcount is zero after the finalizer call\n *  (i.e. finalizer removed the reference loop for the object).  If not, the\n *  next mark-and-sweep will collect the object unless it has become reachable\n *  (i.e. rescued) by that time and its refcount hasn't fallen to zero before\n *  that.  Mark-and-sweep detects these objects because their FINALIZED flag\n *  is set.\n *\n *  There's an inherent limitation for mark-and-sweep finalizer rescuing: an\n *  object won't get refinalized if (1) it's rescued, but (2) becomes\n *  unreachable before mark-and-sweep has had time to notice it.  The next\n *  mark-and-sweep round simply doesn't have any information of whether the\n *  object has been unreachable the whole time or not (the only way to get\n *  that information would be a mark-and-sweep pass for *every finalized\n *  object*).  This is awkward for the application because the mark-and-sweep\n *  round is not generally visible or under full application control.\n *\n *  For refcount queued objects (had_zero_refcount true) the object is either\n *  immediately freed or rescued, and waiting for a mark-and-sweep round is not\n *  necessary (or desirable); FINALIZED is cleared when a rescued object is\n *  queued back to heap_allocated.  The object is eligible for finalization\n *  again (either via refcounting or mark-and-sweep) immediately after being\n *  rescued.  If a refcount finalized object is placed into an unreachable\n *  reference loop by its finalizer, it will get collected by mark-and-sweep\n *  and currently the finalizer will execute again.\n *\n *  There's a special case where:\n *\n *    - Mark-and-sweep queues an object to finalize_list for finalization.\n *    - The finalizer is executed, FINALIZED is set, and object is queued\n *      back to heap_allocated, waiting for a new mark-and-sweep round.\n *    - The object's refcount drops to zero before mark-and-sweep has a\n *      chance to run another round and make a rescue/free decision.\n *\n *  This is now handled by refzero code: if an object has a finalizer but\n *  FINALIZED is already set, the object is freed without finalizer processing.\n *  The outcome is the same as if mark-and-sweep was executed at that point;\n *  mark-and-sweep would also free the object without another finalizer run.\n *  This could also be changed so that the refzero-triggered finalizer *IS*\n *  executed: being refzero collected implies someone has operated on the\n *  object so it hasn't been totally unreachable the whole time.  This would\n *  risk a finalizer loop however.\n */\n\nDUK_INTERNAL void duk_heap_process_finalize_list(duk_heap *heap) {\n\tduk_heaphdr *curr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count = 0;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk_heap_process_finalize_list: %p\", (void *) heap));\n\n\tif (heap->pf_prevent_count != 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"skip finalize_list processing: pf_prevent_count != 0\"));\n\t\treturn;\n\t}\n\n\t/* Heap alloc prevents mark-and-sweep before heap_thread is ready. */\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(heap->heap_thread->valstack != NULL);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);\n#endif\n\n\tDUK_ASSERT(heap->pf_prevent_count == 0);\n\theap->pf_prevent_count = 1;\n\n\t/* Mark-and-sweep no longer needs to be prevented when running\n\t * finalizers: mark-and-sweep skips any rescue decisions if there\n\t * are any objects in finalize_list when mark-and-sweep is entered.\n\t * This protects finalized objects from incorrect rescue decisions\n\t * caused by finalize_list being a reachability root and only\n\t * partially processed.  Freeing decisions are not postponed.\n\t */\n\n\t/* When finalizer torture is enabled, make a fake finalizer call with\n\t * maximum side effects regardless of whether finalize_list is empty.\n\t */\n#if defined(DUK_USE_FINALIZER_TORTURE)\n\tduk__run_global_torture_finalizer(heap->heap_thread);\n#endif\n\n\t/* Process finalize_list until it becomes empty.  There's currently no\n\t * protection against a finalizer always creating more garbage.\n\t */\n\twhile ((curr = heap->finalize_list) != NULL) {\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tduk_bool_t queue_back;\n#endif\n\n\t\tDUK_DD(DUK_DDPRINT(\"processing finalize_list entry: %p -> %!iO\", (void *) curr, curr));\n\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);  /* Only objects have finalizers. */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(curr));\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(curr));\n\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZABLE(curr));  /* All objects on finalize_list will have this flag (except object being finalized right now). */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));   /* Queueing code ensures. */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(curr));  /* ROM objects never get freed (or finalized). */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\tDUK_ASSERT(heap->currently_finalizing == NULL);\n\t\theap->currently_finalizing = curr;\n#endif\n\n\t\t/* Clear FINALIZABLE for object being finalized, so that\n\t\t * duk_push_heapptr() can properly ignore the object.\n\t\t */\n\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\n\t\tif (DUK_LIKELY(!heap->pf_skip_finalizers)) {\n\t\t\t/* Run the finalizer, duk_heap_run_finalizer() sets\n\t\t\t * and checks for FINALIZED to prevent the finalizer\n\t\t\t * from executing multiple times per finalization cycle.\n\t\t\t * (This safeguard shouldn't be actually needed anymore).\n\t\t\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tduk_bool_t had_zero_refcount;\n#endif\n\n\t\t\t/* The object's refcount is >0 throughout so it won't be\n\t\t\t * refzero processed prematurely.\n\t\t\t */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) >= 1);\n\t\t\thad_zero_refcount = (DUK_HEAPHDR_GET_REFCOUNT(curr) == 1);  /* Preincremented on finalize_list insert. */\n#endif\n\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));\n\t\t\tduk_heap_run_finalizer(heap, (duk_hobject *) curr);  /* must never longjmp */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZED(curr));\n\t\t\t/* XXX: assert that object is still in finalize_list\n\t\t\t * when duk_push_heapptr() allows automatic rescue.\n\t\t\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tDUK_DD(DUK_DDPRINT(\"refcount after finalizer (includes bump): %ld\", (long) DUK_HEAPHDR_GET_REFCOUNT(curr)));\n\t\t\tif (DUK_HEAPHDR_GET_REFCOUNT(curr) == 1) {  /* Only artificial bump in refcount? */\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tif (had_zero_refcount) {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"finalized object's refcount is zero -> free immediately (refcount queued)\"));\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"finalized object's refcount is zero -> free immediately (mark-and-sweep queued)\"));\n\t\t\t\t}\n#endif\n\t\t\t\tqueue_back = 0;\n\t\t\t} else\n#endif\n\t\t\t{\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t\tqueue_back = 1;\n\t\t\t\tif (had_zero_refcount) {\n\t\t\t\t\t/* When finalization is triggered\n\t\t\t\t\t * by refzero and we queue the object\n\t\t\t\t\t * back, clear FINALIZED right away\n\t\t\t\t\t * so that the object can be refinalized\n\t\t\t\t\t * immediately if necessary.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_HEAPHDR_CLEAR_FINALIZED(curr);\n\t\t\t\t}\n#endif\n\t\t\t}\n\t\t} else {\n\t\t\t/* Used during heap destruction: don't actually run finalizers\n\t\t\t * because we're heading into forced finalization.  Instead,\n\t\t\t * queue finalizable objects back to the heap_allocated list.\n\t\t\t */\n\t\t\tDUK_D(DUK_DPRINT(\"skip finalizers flag set, queue object to heap_allocated without finalizing\"));\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\tqueue_back = 1;\n#endif\n\t\t}\n\n\t\t/* Dequeue object from finalize_list.  Note that 'curr' may no\n\t\t * longer be finalize_list head because new objects may have\n\t\t * been queued to the list.  As a result we can't optimize for\n\t\t * the single-linked heap case and must scan the list for\n\t\t * removal, typically the scan is very short however.\n\t\t */\n\t\tDUK_HEAP_REMOVE_FROM_FINALIZE_LIST(heap, curr);\n\n\t\t/* Queue back to heap_allocated or free immediately. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\tif (queue_back) {\n\t\t\t/* FINALIZED is only cleared if object originally\n\t\t\t * queued for finalization by refcounting.  For\n\t\t\t * mark-and-sweep FINALIZED is left set, so that\n\t\t\t * next mark-and-sweep round can make a rescue/free\n\t\t\t * decision.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) >= 1);\n\t\t\tDUK_HEAPHDR_PREDEC_REFCOUNT(curr);  /* Remove artificial refcount bump. */\n\t\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\t\t\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, curr);\n\t\t} else {\n\t\t\t/* No need to remove the refcount bump here. */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);  /* currently, always the case */\n\t\t\tDUK_DD(DUK_DDPRINT(\"refcount finalize after finalizer call: %!O\", curr));\n\t\t\tduk_hobject_refcount_finalize_norz(heap, (duk_hobject *) curr);\n\t\t\tduk_free_hobject(heap, (duk_hobject *) curr);\n\t\t\tDUK_DD(DUK_DDPRINT(\"freed hobject after finalization: %p\", (void *) curr));\n\t\t}\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\t\tDUK_HEAPHDR_CLEAR_FINALIZABLE(curr);\n\t\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, curr);\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_DEBUG)\n\t\tcount++;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\tDUK_ASSERT(heap->currently_finalizing != NULL);\n\t\theap->currently_finalizing = NULL;\n#endif\n\t}\n\n\t/* finalize_list will always be processed completely. */\n\tDUK_ASSERT(heap->finalize_list == NULL);\n\n#if 0\n\t/* While NORZ macros are used above, this is unnecessary because the\n\t * only pending side effects are now finalizers, and finalize_list is\n\t * empty.\n\t */\n\tDUK_REFZERO_CHECK_SLOW(heap->heap_thread);\n#endif\n\n\t/* Prevent count may be bumped while finalizers run, but should always\n\t * be reliably unbumped by the time we get here.\n\t */\n\tDUK_ASSERT(heap->pf_prevent_count == 1);\n\theap->pf_prevent_count = 0;\n\n#if defined(DUK_USE_DEBUG)\n\tDUK_DD(DUK_DDPRINT(\"duk_heap_process_finalize_list: %ld finalizers called\", (long) count));\n#endif\n}\n\n/*\n *  Run an duk_hobject finalizer.  Must never throw an uncaught error\n *  (but may throw caught errors).\n *\n *  There is no return value.  Any return value or error thrown by\n *  the finalizer is ignored (although errors are debug logged).\n *\n *  Notes:\n *\n *    - The finalizer thread 'top' assertions are there because it is\n *      critical that strict stack policy is observed (i.e. no cruft\n *      left on the finalizer stack).\n */\n\nDUK_LOCAL duk_ret_t duk__finalize_helper(duk_hthread *thr, void *udata) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_UNREF(udata);\n\n\tDUK_DDD(DUK_DDDPRINT(\"protected finalization helper running\"));\n\n\t/* [... obj] */\n\n\t/* _Finalizer property is read without checking if the value is\n\t * callable or even exists.  This is intentional, and handled\n\t * by throwing an error which is caught by the safe call wrapper.\n\t *\n\t * XXX: Finalizer lookup should traverse the prototype chain (to allow\n\t * inherited finalizers) but should not invoke accessors or proxy object\n\t * behavior.  At the moment this lookup will invoke proxy behavior, so\n\t * caller must ensure that this function is not called if the target is\n\t * a Proxy.\n\t */\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_FINALIZER);  /* -> [... obj finalizer] */\n\tduk_dup_m2(thr);\n\tduk_push_boolean(thr, DUK_HEAP_HAS_FINALIZER_NORESCUE(thr->heap));\n\tDUK_DDD(DUK_DDDPRINT(\"calling finalizer\"));\n\tduk_call(thr, 2);  /* [ ... obj finalizer obj heapDestruct ]  -> [ ... obj retval ] */\n\tDUK_DDD(DUK_DDDPRINT(\"finalizer returned successfully\"));\n\treturn 0;\n\n\t/* Note: we rely on duk_safe_call() to fix up the stack for the caller,\n\t * so we don't need to pop stuff here.  There is no return value;\n\t * caller determines rescued status based on object refcount.\n\t */\n}\n\nDUK_INTERNAL void duk_heap_run_finalizer(duk_heap *heap, duk_hobject *obj) {\n\tduk_hthread *thr;\n\tduk_ret_t rc;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"running duk_hobject finalizer for object: %p\", (void *) obj));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tthr = heap->heap_thread;\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(heap->heap_thread, 1);\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\t/*\n\t *  Get and call the finalizer.  All of this must be wrapped\n\t *  in a protected call, because even getting the finalizer\n\t *  may trigger an error (getter may throw one, for instance).\n\t */\n\n\t/* ROM objects could inherit a finalizer, but they are never deemed\n\t * unreachable by mark-and-sweep, and their refcount never falls to 0.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\n\t/* Duktape 2.1: finalize_list never contains objects with FINALIZED\n\t * set, so no need to check here.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) obj));\n#if 0\n\tif (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) obj)) {\n\t\tDUK_D(DUK_DPRINT(\"object already finalized, avoid running finalizer twice: %!O\", obj));\n\t\treturn;\n\t}\n#endif\n\tDUK_HEAPHDR_SET_FINALIZED((duk_heaphdr *) obj);  /* ensure never re-entered until rescue cycle complete */\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (DUK_HOBJECT_IS_PROXY(obj)) {\n\t\t/* This may happen if duk_set_finalizer() or Duktape.fin() is\n\t\t * called for a Proxy object.  In such cases the fast finalizer\n\t\t * flag will be set on the Proxy, not the target, and neither\n\t\t * will be finalized.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"object is a Proxy, skip finalizer call\"));\n\t\treturn;\n\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\tduk_push_hobject(thr, obj);  /* this also increases refcount by one */\n\trc = duk_safe_call(thr, duk__finalize_helper, NULL /*udata*/, 0 /*nargs*/, 1 /*nrets*/);  /* -> [... obj retval/error] */\n\tDUK_ASSERT_TOP(thr, entry_top + 2);  /* duk_safe_call discipline */\n\n\tif (rc != DUK_EXEC_SUCCESS) {\n\t\t/* Note: we ask for one return value from duk_safe_call to get this\n\t\t * error debugging here.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"wrapped finalizer call failed for object %p (ignored); error: %!T\",\n\t\t                 (void *) obj, (duk_tval *) duk_get_tval(thr, -1)));\n\t}\n\tduk_pop_2(thr);  /* -> [...] */\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n}\n\n#else  /* DUK_USE_FINALIZER_SUPPORT */\n\n/* nothing */\n\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_heap_hashstring.c",
    "content": "/*\n *  String hash computation (interning).\n *\n *  String hashing is performance critical because a string hash is computed\n *  for all new strings which are candidates to be added to the string table.\n *  However, strings actually added to the string table go through a codepoint\n *  length calculation which dominates performance because it goes through\n *  every byte of the input string (but only for strings added).\n *\n *  The string hash algorithm should be fast, but on the other hand provide\n *  good enough hashes to ensure both string table and object property table\n *  hash tables work reasonably well (i.e., there aren't too many collisions\n *  with real world inputs).  Unless the hash is cryptographic, it's always\n *  possible to craft inputs with maximal hash collisions.\n *\n *  NOTE: The hash algorithms must match tools/dukutil.py:duk_heap_hashstring()\n *  for ROM string support!\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_STRHASH_DENSE)\n/* Constants for duk_hashstring(). */\n#define DUK__STRHASH_SHORTSTRING   4096L\n#define DUK__STRHASH_MEDIUMSTRING  (256L * 1024L)\n#define DUK__STRHASH_BLOCKSIZE     256L\n\nDUK_INTERNAL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len) {\n\tduk_uint32_t hash;\n\n\t/* Use Murmurhash2 directly for short strings, and use \"block skipping\"\n\t * for long strings: hash an initial part and then sample the rest of\n\t * the string with reasonably sized chunks.  An initial offset for the\n\t * sampling is computed based on a hash of the initial part of the string;\n\t * this is done to (usually) avoid the case where all long strings have\n\t * certain offset ranges which are never sampled.\n\t *\n\t * Skip should depend on length and bound the total time to roughly\n\t * logarithmic.  With current values:\n\t *\n\t *   1M string => 256 * 241 = 61696 bytes (0.06M) of hashing\n\t *   1G string => 256 * 16321 = 4178176 bytes (3.98M) of hashing\n\t *\n\t * XXX: It would be better to compute the skip offset more \"smoothly\"\n\t * instead of having a few boundary values.\n\t */\n\n\t/* note: mixing len into seed improves hashing when skipping */\n\tduk_uint32_t str_seed = heap->hash_seed ^ ((duk_uint32_t) len);\n\n\tif (len <= DUK__STRHASH_SHORTSTRING) {\n\t\thash = duk_util_hashbytes(str, len, str_seed);\n\t} else {\n\t\tduk_size_t off;\n\t\tduk_size_t skip;\n\n\t\tif (len <= DUK__STRHASH_MEDIUMSTRING) {\n\t\t\tskip = (duk_size_t) (16 * DUK__STRHASH_BLOCKSIZE + DUK__STRHASH_BLOCKSIZE);\n\t\t} else {\n\t\t\tskip = (duk_size_t) (256 * DUK__STRHASH_BLOCKSIZE + DUK__STRHASH_BLOCKSIZE);\n\t\t}\n\n\t\thash = duk_util_hashbytes(str, (duk_size_t) DUK__STRHASH_SHORTSTRING, str_seed);\n\t\toff = DUK__STRHASH_SHORTSTRING + (skip * (hash % 256)) / 256;\n\n\t\t/* XXX: inefficient loop */\n\t\twhile (off < len) {\n\t\t\tduk_size_t left = len - off;\n\t\t\tduk_size_t now = (duk_size_t) (left > DUK__STRHASH_BLOCKSIZE ? DUK__STRHASH_BLOCKSIZE : left);\n\t\t\thash ^= duk_util_hashbytes(str + off, now, str_seed);\n\t\t\toff += skip;\n\t\t}\n\t}\n\n#if defined(DUK_USE_STRHASH16)\n\t/* Truncate to 16 bits here, so that a computed hash can be compared\n\t * against a hash stored in a 16-bit field.\n\t */\n\thash &= 0x0000ffffUL;\n#endif\n\treturn hash;\n}\n#else  /* DUK_USE_STRHASH_DENSE */\nDUK_INTERNAL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len) {\n\tduk_uint32_t hash;\n\tduk_size_t step;\n\tduk_size_t off;\n\n\t/* Slightly modified \"Bernstein hash\" from:\n\t *\n\t *     http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx\n\t *\n\t * Modifications: string skipping and reverse direction similar to\n\t * Lua 5.1.5, and different hash initializer.\n\t *\n\t * The reverse direction ensures last byte it always included in the\n\t * hash which is a good default as changing parts of the string are\n\t * more often in the suffix than in the prefix.\n\t */\n\n\thash = heap->hash_seed ^ ((duk_uint32_t) len);  /* Bernstein hash init value is normally 5381 */\n\tstep = (len >> DUK_USE_STRHASH_SKIP_SHIFT) + 1;\n\tfor (off = len; off >= step; off -= step) {\n\t\tDUK_ASSERT(off >= 1);  /* off >= step, and step >= 1 */\n\t\thash = (hash * 33) + str[off - 1];\n\t}\n\n#if defined(DUK_USE_STRHASH16)\n\t/* Truncate to 16 bits here, so that a computed hash can be compared\n\t * against a hash stored in a 16-bit field.\n\t */\n\thash &= 0x0000ffffUL;\n#endif\n\treturn hash;\n}\n#endif  /* DUK_USE_STRHASH_DENSE */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_heap_markandsweep.c",
    "content": "/*\n *  Mark-and-sweep garbage collection.\n */\n\n#include \"duk_internal.h\"\n\nDUK_LOCAL_DECL void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__mark_heaphdr_nonnull(duk_heap *heap, duk_heaphdr *h);\nDUK_LOCAL_DECL void duk__mark_tval(duk_heap *heap, duk_tval *tv);\nDUK_LOCAL_DECL void duk__mark_tvals(duk_heap *heap, duk_tval *tv, duk_idx_t count);\n\n/*\n *  Marking functions for heap types: mark children recursively.\n */\n\nDUK_LOCAL void duk__mark_hstring(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\tDUK_UNREF(h);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_hstring: %p\", (void *) h));\n\tDUK_ASSERT(h);\n\tDUK_HSTRING_ASSERT_VALID(h);\n\n\t/* nothing to process */\n}\n\nDUK_LOCAL void duk__mark_hobject(duk_heap *heap, duk_hobject *h) {\n\tduk_uint_fast32_t i;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_hobject: %p\", (void *) h));\n\n\tDUK_ASSERT(h);\n\tDUK_HOBJECT_ASSERT_VALID(h);\n\n\t/* XXX: use advancing pointers instead of index macros -> faster and smaller? */\n\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {\n\t\tduk_hstring *key = DUK_HOBJECT_E_GET_KEY(heap, h, i);\n\t\tif (key == NULL) {\n\t\t\tcontinue;\n\t\t}\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) key);\n\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)) {\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.get);\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->a.set);\n\t\t} else {\n\t\t\tduk__mark_tval(heap, &DUK_HOBJECT_E_GET_VALUE_PTR(heap, h, i)->v);\n\t\t}\n\t}\n\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(h); i++) {\n\t\tduk__mark_tval(heap, DUK_HOBJECT_A_GET_VALUE_PTR(heap, h, i));\n\t}\n\n\t/* Hash part is a 'weak reference' and does not contribute. */\n\n\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HOBJECT_GET_PROTOTYPE(heap, h));\n\n\t/* Fast path for objects which don't have a subclass struct, or have a\n\t * subclass struct but nothing that needs marking in the subclass struct.\n\t */\n\tif (DUK_HOBJECT_HAS_FASTREFS(h)) {\n\t\tDUK_ASSERT(DUK_HOBJECT_ALLOWS_FASTREFS(h));\n\t\treturn;\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_PROHIBITS_FASTREFS(h));\n\n\t/* XXX: reorg, more common first */\n\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tduk_tval *tv, *tv_end;\n\t\tduk_hobject **fn, **fn_end;\n\n\t\tDUK_HCOMPFUNC_ASSERT_VALID(f);\n\n\t\t/* 'data' is reachable through every compiled function which\n\t\t * contains a reference.\n\t\t */\n\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_DATA(heap, f));\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_LEXENV(heap, f));\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_HCOMPFUNC_GET_VARENV(heap, f));\n\n\t\tif (DUK_HCOMPFUNC_GET_DATA(heap, f) != NULL) {\n\t\t\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, f);\n\t\t\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(heap, f);\n\t\t\twhile (tv < tv_end) {\n\t\t\t\tduk__mark_tval(heap, tv);\n\t\t\t\ttv++;\n\t\t\t}\n\n\t\t\tfn = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, f);\n\t\t\tfn_end = DUK_HCOMPFUNC_GET_FUNCS_END(heap, f);\n\t\t\twhile (fn < fn_end) {\n\t\t\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) *fn);\n\t\t\t\tfn++;\n\t\t\t}\n\t\t} else {\n\t\t\t/* May happen in some out-of-memory corner cases. */\n\t\t\tDUK_D(DUK_DPRINT(\"duk_hcompfunc 'data' is NULL, skipping marking\"));\n\t\t}\n\t} else if (DUK_HOBJECT_IS_DECENV(h)) {\n\t\tduk_hdecenv *e = (duk_hdecenv *) h;\n\t\tDUK_HDECENV_ASSERT_VALID(e);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) e->thread);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) e->varmap);\n\t} else if (DUK_HOBJECT_IS_OBJENV(h)) {\n\t\tduk_hobjenv *e = (duk_hobjenv *) h;\n\t\tDUK_HOBJENV_ASSERT_VALID(e);\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) e->target);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\tduk_hbufobj *b = (duk_hbufobj *) h;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(b);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) b->buf);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) b->buf_prop);\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {\n\t\tduk_hboundfunc *f = (duk_hboundfunc *) (void *) h;\n\t\tDUK_HBOUNDFUNC_ASSERT_VALID(f);\n\t\tduk__mark_tval(heap, &f->target);\n\t\tduk__mark_tval(heap, &f->this_binding);\n\t\tduk__mark_tvals(heap, f->args, f->nargs);\n#if defined(DUK_USE_ES6_PROXY)\n\t} else if (DUK_HOBJECT_IS_PROXY(h)) {\n\t\tduk_hproxy *p = (duk_hproxy *) h;\n\t\tDUK_HPROXY_ASSERT_VALID(p);\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) p->target);\n\t\tduk__mark_heaphdr_nonnull(heap, (duk_heaphdr *) p->handler);\n#endif  /* DUK_USE_ES6_PROXY */\n\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tduk_activation *act;\n\t\tduk_tval *tv;\n\n\t\tDUK_HTHREAD_ASSERT_VALID(t);\n\n\t\ttv = t->valstack;\n\t\twhile (tv < t->valstack_top) {\n\t\t\tduk__mark_tval(heap, tv);\n\t\t\ttv++;\n\t\t}\n\n\t\tfor (act = t->callstack_curr; act != NULL; act = act->parent) {\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) DUK_ACT_GET_FUNC(act));\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) act->var_env);\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) act->lex_env);\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) act->prev_caller);\n#endif\n#if 0  /* nothing now */\n\t\t\tfor (cat = act->cat; cat != NULL; cat = cat->parent) {\n\t\t\t}\n#endif\n\t\t}\n\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) t->resumer);\n\n\t\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) t->builtins[i]);\n\t\t}\n\t} else {\n\t\t/* We may come here if the object should have a FASTREFS flag\n\t\t * but it's missing for some reason.  Assert for never getting\n\t\t * here; however, other than performance, this is harmless.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"missing FASTREFS flag for: %!iO\", h));\n\t\tDUK_ASSERT(0);\n\t}\n}\n\n/* Mark any duk_heaphdr type.  Recursion tracking happens only here. */\nDUK_LOCAL void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_heaphdr %p, type %ld\",\n\t                     (void *) h,\n\t                     (h != NULL ? (long) DUK_HEAPHDR_GET_TYPE(h) : (long) -1)));\n\n\t/* XXX: add non-null variant? */\n\tif (h == NULL) {\n\t\treturn;\n\t}\n\n\tDUK_HEAPHDR_ASSERT_VALID(h);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(h) || DUK_HEAPHDR_HAS_REACHABLE(h));\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\tif (!DUK_HEAPHDR_HAS_READONLY(h)) {\n\t\th->h_assert_refcount++;  /* Comparison refcount: bump even if already reachable. */\n\t}\n#endif\n\tif (DUK_HEAPHDR_HAS_REACHABLE(h)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"already marked reachable, skip\"));\n\t\treturn;\n\t}\n#if defined(DUK_USE_ROM_OBJECTS)\n\t/* READONLY objects always have REACHABLE set, so the check above\n\t * will prevent READONLY objects from being marked here.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(h));\n#endif\n\n\tDUK_HEAPHDR_SET_REACHABLE(h);\n\n\tif (heap->ms_recursion_depth >= DUK_USE_MARK_AND_SWEEP_RECLIMIT) {\n\t\tDUK_D(DUK_DPRINT(\"mark-and-sweep recursion limit reached, marking as temproot: %p\", (void *) h));\n\t\tDUK_HEAP_SET_MARKANDSWEEP_RECLIMIT_REACHED(heap);\n\t\tDUK_HEAPHDR_SET_TEMPROOT(h);\n\t\treturn;\n\t}\n\n\theap->ms_recursion_depth++;\n\tDUK_ASSERT(heap->ms_recursion_depth != 0);  /* Wrap. */\n\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_STRING:\n\t\tduk__mark_hstring(heap, (duk_hstring *) h);\n\t\tbreak;\n\tcase DUK_HTYPE_OBJECT:\n\t\tduk__mark_hobject(heap, (duk_hobject *) h);\n\t\tbreak;\n\tcase DUK_HTYPE_BUFFER:\n\t\t/* nothing to mark */\n\t\tbreak;\n\tdefault:\n\t\tDUK_D(DUK_DPRINT(\"attempt to mark heaphdr %p with invalid htype %ld\", (void *) h, (long) DUK_HEAPHDR_GET_TYPE(h)));\n\t\tDUK_UNREACHABLE();\n\t}\n\n\tDUK_ASSERT(heap->ms_recursion_depth > 0);\n\theap->ms_recursion_depth--;\n}\n\nDUK_LOCAL void duk__mark_tval(duk_heap *heap, duk_tval *tv) {\n\tDUK_DDD(DUK_DDDPRINT(\"duk__mark_tval %p\", (void *) tv));\n\tif (tv == NULL) {\n\t\treturn;\n\t}\n\tDUK_TVAL_ASSERT_VALID(tv);\n\tif (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\tduk_heaphdr *h;\n\t\th = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tduk__mark_heaphdr_nonnull(heap, h);\n\t}\n}\n\nDUK_LOCAL void duk__mark_tvals(duk_heap *heap, duk_tval *tv, duk_idx_t count) {\n\tDUK_ASSERT(count == 0 || tv != NULL);\n\n\twhile (count-- > 0) {\n\t\tDUK_TVAL_ASSERT_VALID(tv);\n\t\tif (DUK_TVAL_IS_HEAP_ALLOCATED(tv)) {\n\t\t\tduk_heaphdr *h;\n\t\t\th = DUK_TVAL_GET_HEAPHDR(tv);\n\t\t\tDUK_ASSERT(h != NULL);\n\t\t\tduk__mark_heaphdr_nonnull(heap, h);\n\t\t}\n\t\ttv++;\n\t}\n}\n\n/* Mark any duk_heaphdr type, caller guarantees a non-NULL pointer. */\nDUK_LOCAL void duk__mark_heaphdr_nonnull(duk_heap *heap, duk_heaphdr *h) {\n\t/* For now, just call the generic handler.  Change when call sites\n\t * are changed too.\n\t */\n\tduk__mark_heaphdr(heap, h);\n}\n\n/*\n *  Mark the heap.\n */\n\nDUK_LOCAL void duk__mark_roots_heap(duk_heap *heap) {\n\tduk_small_uint_t i;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_roots_heap: %p\", (void *) heap));\n\n\tduk__mark_heaphdr(heap, (duk_heaphdr *) heap->heap_thread);\n\tduk__mark_heaphdr(heap, (duk_heaphdr *) heap->heap_object);\n\n\tfor (i = 0; i < DUK_HEAP_NUM_STRINGS; i++) {\n\t\tduk_hstring *h = DUK_HEAP_GET_STRING(heap, i);\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) h);\n\t}\n\n\tduk__mark_tval(heap, &heap->lj.value1);\n\tduk__mark_tval(heap, &heap->lj.value2);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tfor (i = 0; i < heap->dbg_breakpoint_count; i++) {\n\t\tduk__mark_heaphdr(heap, (duk_heaphdr *) heap->dbg_breakpoints[i].filename);\n\t}\n#endif\n}\n\n/*\n *  Mark unreachable, finalizable objects.\n *\n *  Such objects will be moved aside and their finalizers run later.  They\n *  have to be treated as reachability roots for their properties etc to\n *  remain allocated.  This marking is only done for unreachable values which\n *  would be swept later.\n *\n *  Objects are first marked FINALIZABLE and only then marked as reachability\n *  roots; otherwise circular references might be handled inconsistently.\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__mark_finalizable(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\tduk_size_t count_finalizable = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_finalizable: %p\", (void *) heap));\n\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\n\thdr = heap->heap_allocated;\n\twhile (hdr != NULL) {\n\t\t/* A finalizer is looked up from the object and up its\n\t\t * prototype chain (which allows inherited finalizers).\n\t\t * The finalizer is checked for using a duk_hobject flag\n\t\t * which is kept in sync with the presence and callability\n\t\t * of a _Finalizer hidden symbol.\n\t\t */\n\n\t\tif (!DUK_HEAPHDR_HAS_REACHABLE(hdr) &&\n\t\t    DUK_HEAPHDR_IS_OBJECT(hdr) &&\n\t\t    !DUK_HEAPHDR_HAS_FINALIZED(hdr) &&\n\t\t    DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) hdr)) {\n\t\t\t/* heaphdr:\n\t\t\t *  - is not reachable\n\t\t\t *  - is an object\n\t\t\t *  - is not a finalized object waiting for rescue/keep decision\n\t\t\t *  - has a finalizer\n\t\t\t */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"unreachable heap object will be \"\n\t\t\t                   \"finalized -> mark as finalizable \"\n\t\t\t                   \"and treat as a reachability root: %p\",\n\t\t\t                   (void *) hdr));\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(hdr));\n\t\t\tDUK_HEAPHDR_SET_FINALIZABLE(hdr);\n\t\t\tcount_finalizable++;\n\t\t}\n\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n\n\tif (count_finalizable == 0) {\n\t\treturn;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"marked %ld heap objects as finalizable, now mark them reachable\",\n\t                   (long) count_finalizable));\n\n\thdr = heap->heap_allocated;\n\twhile (hdr != NULL) {\n\t\tif (DUK_HEAPHDR_HAS_FINALIZABLE(hdr)) {\n\t\t\tduk__mark_heaphdr_nonnull(heap, hdr);\n\t\t}\n\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n\n\t/* Caller will finish the marking process if we hit a recursion limit. */\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Mark objects on finalize_list.\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__mark_finalize_list(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_finalize_list = 0;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_finalize_list: %p\", (void *) heap));\n\n\thdr = heap->finalize_list;\n\twhile (hdr != NULL) {\n\t\tduk__mark_heaphdr_nonnull(heap, hdr);\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n#if defined(DUK_USE_DEBUG)\n\t\tcount_finalize_list++;\n#endif\n\t}\n\n#if defined(DUK_USE_DEBUG)\n\tif (count_finalize_list > 0) {\n\t\tDUK_D(DUK_DPRINT(\"marked %ld objects on the finalize_list as reachable (previous finalizer run skipped)\",\n\t\t                 (long) count_finalize_list));\n\t}\n#endif\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Fallback marking handler if recursion limit is reached.\n *\n *  Iterates 'temproots' until recursion limit is no longer hit.  Temproots\n *  can be in heap_allocated or finalize_list; refzero_list is now always\n *  empty for mark-and-sweep.  A temproot may occur in finalize_list now if\n *  there are objects on the finalize_list and user code creates a reference\n *  from an object in heap_allocated to the object in finalize_list (which is\n *  now allowed), and it happened to coincide with the recursion depth limit.\n *\n *  This is a slow scan, but guarantees that we finish with a bounded C stack.\n *\n *  Note that nodes may have been marked as temproots before this scan begun,\n *  OR they may have been marked during the scan (as we process nodes\n *  recursively also during the scan).  This is intended behavior.\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__handle_temproot(duk_heap *heap, duk_heaphdr *hdr, duk_size_t *count) {\n#else\nDUK_LOCAL void duk__handle_temproot(duk_heap *heap, duk_heaphdr *hdr) {\n#endif\n\tDUK_ASSERT(hdr != NULL);\n\n\tif (!DUK_HEAPHDR_HAS_TEMPROOT(hdr)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"not a temp root: %p\", (void *) hdr));\n\t\treturn;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"found a temp root: %p\", (void *) hdr));\n\tDUK_HEAPHDR_CLEAR_TEMPROOT(hdr);\n\tDUK_HEAPHDR_CLEAR_REACHABLE(hdr);  /* Done so that duk__mark_heaphdr() works correctly. */\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\thdr->h_assert_refcount--;  /* Same node visited twice. */\n#endif\n\tduk__mark_heaphdr_nonnull(heap, hdr);\n\n#if defined(DUK_USE_DEBUG)\n\t(*count)++;\n#endif\n}\n\nDUK_LOCAL void duk__mark_temproots_by_heap_scan(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"duk__mark_temproots_by_heap_scan: %p\", (void *) heap));\n\n\twhile (DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap)) {\n\t\tDUK_DD(DUK_DDPRINT(\"recursion limit reached, doing heap scan to continue from temproots\"));\n\n#if defined(DUK_USE_DEBUG)\n\t\tcount = 0;\n#endif\n\t\tDUK_HEAP_CLEAR_MARKANDSWEEP_RECLIMIT_REACHED(heap);\n\n\t\thdr = heap->heap_allocated;\n\t\twhile (hdr) {\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk__handle_temproot(heap, hdr, &count);\n#else\n\t\t\tduk__handle_temproot(heap, hdr);\n#endif\n\t\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t\t}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\thdr = heap->finalize_list;\n\t\twhile (hdr) {\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk__handle_temproot(heap, hdr, &count);\n#else\n\t\t\tduk__handle_temproot(heap, hdr);\n#endif\n\t\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t\t}\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\t\tDUK_DD(DUK_DDPRINT(\"temproot mark heap scan processed %ld temp roots\", (long) count));\n#endif\n\t}\n}\n\n/*\n *  Finalize refcounts for heap elements just about to be freed.\n *  This must be done for all objects before freeing to avoid any\n *  stale pointer dereferences.\n *\n *  Note that this must deduce the set of objects to be freed\n *  identically to duk__sweep_heap().\n */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_LOCAL void duk__finalize_refcounts(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"duk__finalize_refcounts: heap=%p\", (void *) heap));\n\n\thdr = heap->heap_allocated;\n\twhile (hdr) {\n\t\tif (!DUK_HEAPHDR_HAS_REACHABLE(hdr)) {\n\t\t\t/*\n\t\t\t *  Unreachable object about to be swept.  Finalize target refcounts\n\t\t\t *  (objects which the unreachable object points to) without doing\n\t\t\t *  refzero processing.  Recursive decrefs are also prevented when\n\t\t\t *  refzero processing is disabled.\n\t\t\t *\n\t\t\t *  Value cannot be a finalizable object, as they have been made\n\t\t\t *  temporarily reachable for this round.\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"unreachable object, refcount finalize before sweeping: %p\", (void *) hdr));\n\n\t\t\t/* Finalize using heap->heap_thread; DECREF has a\n\t\t\t * suppress check for mark-and-sweep which is based\n\t\t\t * on heap->ms_running.\n\t\t\t */\n\t\t\tduk_heaphdr_refcount_finalize_norz(heap, hdr);\n\t\t}\n\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/*\n *  Clear (reachable) flags of finalize_list.\n *\n *  We could mostly do in the sweep phase when we move objects from the\n *  heap into the finalize_list.  However, if a finalizer run is skipped\n *  during a mark-and-sweep, the objects on the finalize_list will be marked\n *  reachable during the next mark-and-sweep.  Since they're already on the\n *  finalize_list, no-one will be clearing their REACHABLE flag so we do it\n *  here.  (This now overlaps with the sweep handling in a harmless way.)\n */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_LOCAL void duk__clear_finalize_list_flags(duk_heap *heap) {\n\tduk_heaphdr *hdr;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__clear_finalize_list_flags: %p\", (void *) heap));\n\n\thdr = heap->finalize_list;\n\twhile (hdr) {\n\t\tDUK_HEAPHDR_CLEAR_REACHABLE(hdr);\n#if defined(DUK_USE_ASSERTIONS)\n\t\tDUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZABLE(hdr) || \\\n\t\t           (heap->currently_finalizing == hdr));\n#endif\n\t\t/* DUK_HEAPHDR_FLAG_FINALIZED may be set. */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(hdr));\n\t\thdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Sweep stringtable.\n */\n\nDUK_LOCAL void duk__sweep_stringtable(duk_heap *heap, duk_size_t *out_count_keep) {\n\tduk_hstring *h;\n\tduk_hstring *prev;\n\tduk_uint32_t i;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_free = 0;\n#endif\n\tduk_size_t count_keep = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__sweep_stringtable: %p\", (void *) heap));\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tif (heap->strtable16 == NULL) {\n#else\n\tif (heap->strtable == NULL) {\n#endif\n\t\tgoto done;\n\t}\n\n\tfor (i = 0; i < heap->st_size; i++) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\th = DUK_USE_HEAPPTR_DEC16(heap->heap_udata, heap->strtable16[i]);\n#else\n\t\th = heap->strtable[i];\n#endif\n\t\tprev = NULL;\n\t\twhile (h != NULL) {\n\t\t\tduk_hstring *next;\n\t\t\tnext = h->hdr.h_next;\n\n\t\t\tif (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h))\n\t\t\t{\n\t\t\t\tDUK_HEAPHDR_CLEAR_REACHABLE((duk_heaphdr *) h);\n\t\t\t\tcount_keep++;\n\t\t\t\tprev = h;\n\t\t\t} else {\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tcount_free++;\n#endif\n\n\t\t\t\t/* For pinned strings the refcount has been\n\t\t\t\t * bumped.  We could unbump it here before\n\t\t\t\t * freeing, but that's actually not necessary\n\t\t\t\t * except for assertions.\n\t\t\t\t */\n#if 0\n\t\t\t\tif (DUK_HSTRING_HAS_PINNED_LITERAL(h)) {\n\t\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) > 0U);\n\t\t\t\t\tDUK_HSTRING_DECREF_NORZ(heap->heap_thread, h);\n\t\t\t\t\tDUK_HSTRING_CLEAR_PINNED_LITERAL(h);\n\t\t\t\t}\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t\t/* Non-zero refcounts should not happen for unreachable strings,\n\t\t\t\t * because we refcount finalize all unreachable objects which\n\t\t\t\t * should have decreased unreachable string refcounts to zero\n\t\t\t\t * (even for cycles).  However, pinned strings have a +1 bump.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) ==\n\t\t\t\t           DUK_HSTRING_HAS_PINNED_LITERAL(h) ? 1U : 0U);\n#endif\n\n\t\t\t\t/* Deal with weak references first. */\n\t\t\t\tduk_heap_strcache_string_remove(heap, (duk_hstring *) h);\n\n\t\t\t\t/* Remove the string from the string table. */\n\t\t\t\tduk_heap_strtable_unlink_prev(heap, (duk_hstring *) h, (duk_hstring *) prev);\n\n\t\t\t\t/* Free inner references (these exist e.g. when external\n\t\t\t\t * strings are enabled) and the struct itself.\n\t\t\t\t */\n\t\t\t\tduk_free_hstring(heap, (duk_hstring *) h);\n\n\t\t\t\t/* Don't update 'prev'; it should be last string kept. */\n\t\t\t}\n\n\t\t\th = next;\n\t\t}\n\t}\n\n done:\n#if defined(DUK_USE_DEBUG)\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep sweep stringtable: %ld freed, %ld kept\",\n\t                 (long) count_free, (long) count_keep));\n#endif\n\t*out_count_keep = count_keep;\n}\n\n/*\n *  Sweep heap.\n */\n\nDUK_LOCAL void duk__sweep_heap(duk_heap *heap, duk_small_uint_t flags, duk_size_t *out_count_keep) {\n\tduk_heaphdr *prev;  /* last element that was left in the heap */\n\tduk_heaphdr *curr;\n\tduk_heaphdr *next;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_free = 0;\n\tduk_size_t count_finalize = 0;\n\tduk_size_t count_rescue = 0;\n#endif\n\tduk_size_t count_keep = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__sweep_heap: %p\", (void *) heap));\n\n\tprev = NULL;\n\tcurr = heap->heap_allocated;\n\theap->heap_allocated = NULL;\n\twhile (curr) {\n\t\t/* Strings and ROM objects are never placed on the heap allocated list. */\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) != DUK_HTYPE_STRING);\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(curr));\n\n\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\n\t\tif (DUK_HEAPHDR_HAS_REACHABLE(curr)) {\n\t\t\t/*\n\t\t\t *  Reachable object:\n\t\t\t *    - If FINALIZABLE -> actually unreachable (but marked\n\t\t\t *      artificially reachable), queue to finalize_list.\n\t\t\t *    - If !FINALIZABLE but FINALIZED -> rescued after\n\t\t\t *      finalizer execution.\n\t\t\t *    - Otherwise just a normal, reachable object.\n\t\t\t *\n\t\t\t *  Objects which are kept are queued to heap_allocated\n\t\t\t *  tail (we're essentially filtering heap_allocated in\n\t\t\t *  practice).\n\t\t\t */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\t\tif (DUK_UNLIKELY(DUK_HEAPHDR_HAS_FINALIZABLE(curr))) {\n\t\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));\n\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable, finalizable --> move to finalize_list: %p\", (void *) curr));\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(curr);  /* Bump refcount so that refzero never occurs when pending a finalizer call. */\n#endif\n\t\t\t\tDUK_HEAP_INSERT_INTO_FINALIZE_LIST(heap, curr);\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tcount_finalize++;\n#endif\n\t\t\t}\n\t\t\telse\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\t\t\t{\n\t\t\t\tif (DUK_UNLIKELY(DUK_HEAPHDR_HAS_FINALIZED(curr))) {\n\t\t\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(curr));\n\t\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);\n\n\t\t\t\t\tif (flags & DUK_MS_FLAG_POSTPONE_RESCUE) {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable, finalized, but postponing rescue decisions --> keep object (with FINALIZED set): %!iO\", curr));\n\t\t\t\t\t\tcount_keep++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable, finalized --> rescued after finalization: %p\", (void *) curr));\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\t\t\t\t\tDUK_HEAPHDR_CLEAR_FINALIZED(curr);\n#endif\n#if defined(DUK_USE_DEBUG)\n\t\t\t\t\t\tcount_rescue++;\n#endif\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; reachable --> keep: %!iO\", curr));\n\t\t\t\t\tcount_keep++;\n\t\t\t\t}\n\n\t\t\t\tif (prev != NULL) {\n\t\t\t\t\tDUK_ASSERT(heap->heap_allocated != NULL);\n\t\t\t\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, curr);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(heap->heap_allocated == NULL);\n\t\t\t\t\theap->heap_allocated = curr;\n\t\t\t\t}\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\t\t\t\tDUK_HEAPHDR_SET_PREV(heap, curr, prev);\n#endif\n\t\t\t\tDUK_HEAPHDR_ASSERT_LINKS(heap, prev);\n\t\t\t\tDUK_HEAPHDR_ASSERT_LINKS(heap, curr);\n\t\t\t\tprev = curr;\n\t\t\t}\n\n\t\t\t/*\n\t\t\t *  Shrink check for value stacks here.  We're inside\n\t\t\t *  ms_prevent_count protection which prevents recursive\n\t\t\t *  mark-and-sweep and refzero finalizers, so there are\n\t\t\t *  no side effects that would affect the heap lists.\n\t\t\t */\n\t\t\tif (DUK_HEAPHDR_IS_OBJECT(curr) && DUK_HOBJECT_IS_THREAD((duk_hobject *) curr)) {\n\t\t\t\tduk_hthread *thr_curr = (duk_hthread *) curr;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"value stack shrink check for thread: %!O\", curr));\n\t\t\t\tduk_valstack_shrink_check_nothrow(thr_curr, flags & DUK_MS_FLAG_EMERGENCY /*snug*/);\n\t\t\t}\n\n\t\t\tDUK_HEAPHDR_CLEAR_REACHABLE(curr);\n\t\t\t/* Keep FINALIZED if set, used if rescue decisions are postponed. */\n\t\t\t/* Keep FINALIZABLE for objects on finalize_list. */\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(curr));\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Unreachable object:\n\t\t\t *    - If FINALIZED, object was finalized but not\n\t\t\t *      rescued.  This doesn't affect freeing.\n\t\t\t *    - Otherwise normal unreachable object.\n\t\t\t *\n\t\t\t *  There's no guard preventing a FINALIZED object\n\t\t\t *  from being freed while finalizers execute: the\n\t\t\t *  artificial finalize_list reachability roots can't\n\t\t\t *  cause an incorrect free decision (but can cause\n\t\t\t *  an incorrect rescue decision).\n\t\t\t */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t/* Non-zero refcounts should not happen because we refcount\n\t\t\t * finalize all unreachable objects which should cancel out\n\t\t\t * refcounts (even for cycles).\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(curr) == 0);\n#endif\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(curr));\n\n#if defined(DUK_USE_DEBUG)\n\t\t\tif (DUK_HEAPHDR_HAS_FINALIZED(curr)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; unreachable, finalized --> finalized object not rescued: %p\", (void *) curr));\n\t\t\t} else {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"sweep; not reachable --> free: %p\", (void *) curr));\n\t\t\t}\n\n#endif\n\n\t\t\t/* Note: object cannot be a finalizable unreachable object, as\n\t\t\t * they have been marked temporarily reachable for this round,\n\t\t\t * and are handled above.\n\t\t\t */\n\n#if defined(DUK_USE_DEBUG)\n\t\t\tcount_free++;\n#endif\n\n\t\t\t/* Weak refs should be handled here, but no weak refs for\n\t\t\t * any non-string objects exist right now.\n\t\t\t */\n\n\t\t\t/* Free object and all auxiliary (non-heap) allocs. */\n\t\t\tduk_heap_free_heaphdr_raw(heap, curr);\n\t\t}\n\n\t\tcurr = next;\n\t}\n\n\tif (prev != NULL) {\n\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, NULL);\n\t}\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, prev);\n\n#if defined(DUK_USE_DEBUG)\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep sweep objects (non-string): %ld freed, %ld kept, %ld rescued, %ld queued for finalization\",\n\t                 (long) count_free, (long) count_keep, (long) count_rescue, (long) count_finalize));\n#endif\n\t*out_count_keep = count_keep;\n}\n\n/*\n *  Litcache helpers.\n */\n\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_LOCAL void duk__wipe_litcache(duk_heap *heap) {\n\tduk_uint_t i;\n\tduk_litcache_entry *e;\n\n\te = heap->litcache;\n\tfor (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) {\n\t\te->addr = NULL;\n\t\t/* e->h does not need to be invalidated: when e->addr is\n\t\t * NULL, e->h is considered garbage.\n\t\t */\n\t\te++;\n\t}\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n\n/*\n *  Object compaction.\n *\n *  Compaction is assumed to never throw an error.\n */\n\nDUK_LOCAL int duk__protected_compact_object(duk_hthread *thr, void *udata) {\n\tduk_hobject *obj;\n\t/* XXX: for threads, compact stacks? */\n\n\tDUK_UNREF(udata);\n\tobj = duk_known_hobject(thr, -1);\n\tduk_hobject_compact_props(thr, obj);\n\treturn 0;\n}\n\n#if defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__compact_object_list(duk_heap *heap, duk_hthread *thr, duk_heaphdr *start, duk_size_t *p_count_check, duk_size_t *p_count_compact, duk_size_t *p_count_bytes_saved) {\n#else\nDUK_LOCAL void duk__compact_object_list(duk_heap *heap, duk_hthread *thr, duk_heaphdr *start) {\n#endif\n\tduk_heaphdr *curr;\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t old_size, new_size;\n#endif\n\tduk_hobject *obj;\n\n\tDUK_UNREF(heap);\n\n\tcurr = start;\n\twhile (curr) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"mark-and-sweep compact: %p\", (void *) curr));\n\n\t\tif (DUK_HEAPHDR_GET_TYPE(curr) != DUK_HTYPE_OBJECT) {\n\t\t\tgoto next;\n\t\t}\n\t\tobj = (duk_hobject *) curr;\n\n#if defined(DUK_USE_DEBUG)\n\t\told_size = DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_ASIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_HSIZE(obj));\n#endif\n\n\t\tDUK_DD(DUK_DDPRINT(\"compact object: %p\", (void *) obj));\n\t\tduk_push_hobject(thr, obj);\n\t\t/* XXX: disable error handlers for duration of compaction? */\n\t\tduk_safe_call(thr, duk__protected_compact_object, NULL, 1, 0);\n\n#if defined(DUK_USE_DEBUG)\n\t\tnew_size = DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_ASIZE(obj),\n\t\t                                      DUK_HOBJECT_GET_HSIZE(obj));\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\t\t(*p_count_compact)++;\n\t\t(*p_count_bytes_saved) += (duk_size_t) (old_size - new_size);\n#endif\n\n\t next:\n\t\tcurr = DUK_HEAPHDR_GET_NEXT(heap, curr);\n#if defined(DUK_USE_DEBUG)\n\t\t(*p_count_check)++;\n#endif\n\t}\n}\n\nDUK_LOCAL void duk__compact_objects(duk_heap *heap) {\n\t/* XXX: which lists should participate?  to be finalized? */\n#if defined(DUK_USE_DEBUG)\n\tduk_size_t count_check = 0;\n\tduk_size_t count_compact = 0;\n\tduk_size_t count_bytes_saved = 0;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"duk__compact_objects: %p\", (void *) heap));\n\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\n#if defined(DUK_USE_DEBUG)\n\tduk__compact_object_list(heap, heap->heap_thread, heap->heap_allocated, &count_check, &count_compact, &count_bytes_saved);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__compact_object_list(heap, heap->heap_thread, heap->finalize_list, &count_check, &count_compact, &count_bytes_saved);\n#endif\n#else\n\tduk__compact_object_list(heap, heap->heap_thread, heap->heap_allocated);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__compact_object_list(heap, heap->heap_thread, heap->finalize_list);\n#endif\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always handled to completion inline in DECREF. */\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\tDUK_D(DUK_DPRINT(\"mark-and-sweep compact objects: %ld checked, %ld compaction attempts, %ld bytes saved by compaction\",\n\t                 (long) count_check, (long) count_compact, (long) count_bytes_saved));\n#endif\n}\n\n/*\n *  Assertion helpers.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\ntypedef void (*duk__gc_heaphdr_assert)(duk_heap *heap, duk_heaphdr *h);\ntypedef void (*duk__gc_hstring_assert)(duk_heap *heap, duk_hstring *h);\n\nDUK_LOCAL void duk__assert_walk_list(duk_heap *heap, duk_heaphdr *start, duk__gc_heaphdr_assert func) {\n\tduk_heaphdr *curr;\n\tfor (curr = start; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) {\n\t\tfunc(heap, curr);\n\t}\n}\n\nDUK_LOCAL void duk__assert_walk_strtable(duk_heap *heap, duk__gc_hstring_assert func) {\n\tduk_uint32_t i;\n\n\tfor (i = 0; i < heap->st_size; i++) {\n\t\tduk_hstring *h;\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\th = DUK_USE_HEAPPTR_DEC16(heap->heap_udata, heap->strtable16[i]);\n#else\n\t\th = heap->strtable[i];\n#endif\n\t\twhile (h != NULL) {\n\t\t\tfunc(heap, h);\n\t\t\th = h->hdr.h_next;\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__assert_heaphdr_flags_cb(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(h));\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(h));\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(h));\n\t/* may have FINALIZED */\n}\nDUK_LOCAL void duk__assert_heaphdr_flags(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__assert_heaphdr_flags_cb);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);  /* Always handled to completion inline in DECREF. */\n#endif\n\t/* XXX: Assertions for finalize_list? */\n}\n\nDUK_LOCAL void duk__assert_validity_cb1(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tDUK_ASSERT(DUK_HEAPHDR_IS_OBJECT(h) || DUK_HEAPHDR_IS_BUFFER(h));\n\tduk_heaphdr_assert_valid_subclassed(h);\n}\nDUK_LOCAL void duk__assert_validity_cb2(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\tDUK_ASSERT(DUK_HEAPHDR_IS_STRING((duk_heaphdr *) h));\n\tduk_heaphdr_assert_valid_subclassed((duk_heaphdr *) h);\n}\nDUK_LOCAL void duk__assert_validity(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__assert_validity_cb1);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__assert_walk_list(heap, heap->finalize_list, duk__assert_validity_cb1);\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__assert_walk_list(heap, heap->refzero_list, duk__assert_validity_cb1);\n#endif\n\tduk__assert_walk_strtable(heap, duk__assert_validity_cb2);\n}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_LOCAL void duk__assert_valid_refcounts_cb(duk_heap *heap, duk_heaphdr *h) {\n\t/* Cannot really assert much w.r.t. refcounts now. */\n\n\tDUK_UNREF(heap);\n\tif (DUK_HEAPHDR_GET_REFCOUNT(h) == 0 &&\n\t    DUK_HEAPHDR_HAS_FINALIZED(h)) {\n\t\t/* An object may be in heap_allocated list with a zero\n\t\t * refcount if it has just been finalized and is waiting\n\t\t * to be collected by the next cycle.\n\t\t * (This doesn't currently happen however.)\n\t\t */\n\t} else if (DUK_HEAPHDR_GET_REFCOUNT(h) == 0) {\n\t\t/* An object may be in heap_allocated list with a zero\n\t\t * refcount also if it is a temporary object created\n\t\t * during debugger paused state.  It will get collected\n\t\t * by mark-and-sweep based on its reachability status\n\t\t * (presumably not reachable because refcount is 0).\n\t\t */\n\t}\n\tDUK_ASSERT_DISABLE(DUK_HEAPHDR_GET_REFCOUNT(h) >= 0);  /* Unsigned. */\n}\nDUK_LOCAL void duk__assert_valid_refcounts(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__assert_valid_refcounts_cb);\n}\n\nDUK_LOCAL void duk__clear_assert_refcounts_cb1(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\th->h_assert_refcount = 0;\n}\nDUK_LOCAL void duk__clear_assert_refcounts_cb2(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\t((duk_heaphdr *) h)->h_assert_refcount = 0;\n}\nDUK_LOCAL void duk__clear_assert_refcounts(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__clear_assert_refcounts_cb1);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__assert_walk_list(heap, heap->finalize_list, duk__clear_assert_refcounts_cb1);\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__assert_walk_list(heap, heap->refzero_list, duk__clear_assert_refcounts_cb1);\n#endif\n\tduk__assert_walk_strtable(heap, duk__clear_assert_refcounts_cb2);\n}\n\nDUK_LOCAL void duk__check_refcount_heaphdr(duk_heaphdr *hdr) {\n\tduk_bool_t count_ok;\n\tduk_size_t expect_refc;\n\n\t/* The refcount check only makes sense for reachable objects on\n\t * heap_allocated or string table, after the sweep phase.  Prior to\n\t * sweep phase refcounts will include references that are not visible\n\t * via reachability roots.\n\t *\n\t * Because we're called after the sweep phase, all heap objects on\n\t * heap_allocated are reachable.  REACHABLE flags have already been\n\t * cleared so we can't check them.\n\t */\n\n\t/* ROM objects have intentionally incorrect refcount (1), but we won't\n\t * check them.\n\t */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(hdr));\n\n\texpect_refc = hdr->h_assert_refcount;\n\tif (DUK_HEAPHDR_IS_STRING(hdr) && DUK_HSTRING_HAS_PINNED_LITERAL((duk_hstring *) hdr)) {\n\t\texpect_refc++;\n\t}\n\tcount_ok = ((duk_size_t) DUK_HEAPHDR_GET_REFCOUNT(hdr) == expect_refc);\n\tif (!count_ok) {\n\t\tDUK_D(DUK_DPRINT(\"refcount mismatch for: %p: header=%ld counted=%ld --> %!iO\",\n\t\t                 (void *) hdr, (long) DUK_HEAPHDR_GET_REFCOUNT(hdr),\n\t\t                 (long) hdr->h_assert_refcount, hdr));\n\t\tDUK_ASSERT(0);\n\t}\n}\n\nDUK_LOCAL void duk__check_assert_refcounts_cb1(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tduk__check_refcount_heaphdr(h);\n}\nDUK_LOCAL void duk__check_assert_refcounts_cb2(duk_heap *heap, duk_hstring *h) {\n\tDUK_UNREF(heap);\n\tduk__check_refcount_heaphdr((duk_heaphdr *) h);\n}\nDUK_LOCAL void duk__check_assert_refcounts(duk_heap *heap) {\n\tduk__assert_walk_list(heap, heap->heap_allocated, duk__check_assert_refcounts_cb1);\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__assert_walk_list(heap, heap->finalize_list, duk__check_assert_refcounts_cb1);\n#endif\n\t/* XXX: Assert anything for refzero_list? */\n\tduk__assert_walk_strtable(heap, duk__check_assert_refcounts_cb2);\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_LOCAL void duk__assert_litcache_nulls(duk_heap *heap) {\n\tduk_uint_t i;\n\tduk_litcache_entry *e;\n\n\te = heap->litcache;\n\tfor (i = 0; i < DUK_USE_LITCACHE_SIZE; i++) {\n\t\t/* Entry addresses were NULLed before mark-and-sweep, check\n\t\t * that they're still NULL afterwards to ensure no pointers\n\t\t * were recorded through any side effects.\n\t\t */\n\t\tDUK_ASSERT(e->addr == NULL);\n\t}\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n#endif  /* DUK_USE_ASSERTIONS */\n\n/*\n *  Stats dump.\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__dump_stats(duk_heap *heap) {\n\tDUK_D(DUK_DPRINT(\"stats executor: opcodes=%ld, interrupt=%ld, throw=%ld\",\n\t                 (long) heap->stats_exec_opcodes, (long) heap->stats_exec_interrupt,\n\t                 (long) heap->stats_exec_throw));\n\tDUK_D(DUK_DPRINT(\"stats call: all=%ld, tailcall=%ld, ecmatoecma=%ld\",\n\t                 (long) heap->stats_call_all, (long) heap->stats_call_tailcall,\n\t                 (long) heap->stats_call_ecmatoecma));\n\tDUK_D(DUK_DPRINT(\"stats safecall: all=%ld, nothrow=%ld, throw=%ld\",\n\t                 (long) heap->stats_safecall_all, (long) heap->stats_safecall_nothrow,\n\t                 (long) heap->stats_safecall_throw));\n\tDUK_D(DUK_DPRINT(\"stats mark-and-sweep: try_count=%ld, skip_count=%ld, emergency_count=%ld\",\n\t                 (long) heap->stats_ms_try_count, (long) heap->stats_ms_skip_count,\n\t                 (long) heap->stats_ms_emergency_count));\n\tDUK_D(DUK_DPRINT(\"stats stringtable: intern_hit=%ld, intern_miss=%ld, \"\n\t                 \"resize_check=%ld, resize_grow=%ld, resize_shrink=%ld, \"\n\t                 \"litcache_hit=%ld, litcache_miss=%ld, litcache_pin=%ld\",\n\t                 (long) heap->stats_strtab_intern_hit, (long) heap->stats_strtab_intern_miss,\n\t                 (long) heap->stats_strtab_resize_check, (long) heap->stats_strtab_resize_grow,\n\t                 (long) heap->stats_strtab_resize_shrink, (long) heap->stats_strtab_litcache_hit,\n\t                 (long) heap->stats_strtab_litcache_miss, (long) heap->stats_strtab_litcache_pin));\n\tDUK_D(DUK_DPRINT(\"stats object: realloc_props=%ld, abandon_array=%ld\",\n\t                 (long) heap->stats_object_realloc_props, (long) heap->stats_object_abandon_array));\n\tDUK_D(DUK_DPRINT(\"stats getownpropdesc: count=%ld, hit=%ld, miss=%ld\",\n\t                 (long) heap->stats_getownpropdesc_count, (long) heap->stats_getownpropdesc_hit,\n\t                 (long) heap->stats_getownpropdesc_miss));\n\tDUK_D(DUK_DPRINT(\"stats getpropdesc: count=%ld, hit=%ld, miss=%ld\",\n\t                 (long) heap->stats_getpropdesc_count, (long) heap->stats_getpropdesc_hit,\n\t                 (long) heap->stats_getpropdesc_miss));\n\tDUK_D(DUK_DPRINT(\"stats getprop: all=%ld, arrayidx=%ld, bufobjidx=%ld, \"\n\t                 \"bufferidx=%ld, bufferlen=%ld, stringidx=%ld, stringlen=%ld, \"\n\t                 \"proxy=%ld, arguments=%ld\",\n\t                 (long) heap->stats_getprop_all, (long) heap->stats_getprop_arrayidx,\n\t                 (long) heap->stats_getprop_bufobjidx, (long) heap->stats_getprop_bufferidx,\n\t                 (long) heap->stats_getprop_bufferlen, (long) heap->stats_getprop_stringidx,\n\t                 (long) heap->stats_getprop_stringlen, (long) heap->stats_getprop_proxy,\n\t                 (long) heap->stats_getprop_arguments));\n\tDUK_D(DUK_DPRINT(\"stats putprop: all=%ld, arrayidx=%ld, bufobjidx=%ld, \"\n\t                 \"bufferidx=%ld, proxy=%ld\",\n\t                 (long) heap->stats_putprop_all, (long) heap->stats_putprop_arrayidx,\n\t                 (long) heap->stats_putprop_bufobjidx, (long) heap->stats_putprop_bufferidx,\n\t                 (long) heap->stats_putprop_proxy));\n\tDUK_D(DUK_DPRINT(\"stats getvar: all=%ld\",\n\t                 (long) heap->stats_getvar_all));\n\tDUK_D(DUK_DPRINT(\"stats putvar: all=%ld\",\n\t                 (long) heap->stats_putvar_all));\n\tDUK_D(DUK_DPRINT(\"stats envrec: delayedcreate=%ld, create=%ld, newenv=%ld, oldenv=%ld, pushclosure=%ld\",\n\t                 (long) heap->stats_envrec_delayedcreate,\n\t                 (long) heap->stats_envrec_create,\n\t                 (long) heap->stats_envrec_newenv,\n\t                 (long) heap->stats_envrec_oldenv,\n\t                 (long) heap->stats_envrec_pushclosure));\n}\n#endif  /* DUK_USE_DEBUG */\n\n/*\n *  Main mark-and-sweep function.\n *\n *  'flags' represents the features requested by the caller.  The current\n *  heap->ms_base_flags is ORed automatically into the flags; the base flags\n *  mask typically prevents certain mark-and-sweep operation to avoid trouble.\n */\n\nDUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags) {\n\tduk_size_t count_keep_obj;\n\tduk_size_t count_keep_str;\n#if defined(DUK_USE_VOLUNTARY_GC)\n\tduk_size_t tmp;\n#endif\n\n\tDUK_STATS_INC(heap, stats_ms_try_count);\n#if defined(DUK_USE_DEBUG)\n\tif (flags & DUK_MS_FLAG_EMERGENCY) {\n\t\tDUK_STATS_INC(heap, stats_ms_emergency_count);\n\t}\n#endif\n\n\t/* If debugger is paused, garbage collection is disabled by default.\n\t * This is achieved by bumping ms_prevent_count when becoming paused.\n\t */\n\tDUK_ASSERT(!DUK_HEAP_HAS_DEBUGGER_PAUSED(heap) || heap->ms_prevent_count > 0);\n\n\t/* Prevention/recursion check as soon as possible because we may\n\t * be called a number of times when voluntary mark-and-sweep is\n\t * pending.\n\t */\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_DD(DUK_DDPRINT(\"reject recursive mark-and-sweep\"));\n\t\tDUK_STATS_INC(heap, stats_ms_skip_count);\n\t\treturn;\n\t}\n\tDUK_ASSERT(heap->ms_running == 0);  /* ms_prevent_count is bumped when ms_running is set */\n\n\t/* Heap_thread is used during mark-and-sweep for refcount finalization\n\t * (it's also used for finalizer execution once mark-and-sweep is\n\t * complete).  Heap allocation code ensures heap_thread is set and\n\t * properly initialized before setting ms_prevent_count to 0.\n\t */\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(heap->heap_thread->valstack != NULL);\n\n\tDUK_D(DUK_DPRINT(\"garbage collect (mark-and-sweep) starting, requested flags: 0x%08lx, effective flags: 0x%08lx\",\n\t                 (unsigned long) flags, (unsigned long) (flags | heap->ms_base_flags)));\n\n\tflags |= heap->ms_base_flags;\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tif (heap->finalize_list != NULL) {\n\t\tflags |= DUK_MS_FLAG_POSTPONE_RESCUE;\n\t}\n#endif\n\n\t/*\n\t *  Assertions before\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\tDUK_ASSERT(heap->ms_running == 0);\n\tDUK_ASSERT(!DUK_HEAP_HAS_DEBUGGER_PAUSED(heap));\n\tDUK_ASSERT(!DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap));\n\tDUK_ASSERT(heap->ms_recursion_depth == 0);\n\tduk__assert_heaphdr_flags(heap);\n\tduk__assert_validity(heap);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* Note: heap->refzero_free_running may be true; a refcount\n\t * finalizer may trigger a mark-and-sweep.\n\t */\n\tduk__assert_valid_refcounts(heap);\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n#endif  /* DUK_USE_ASSERTIONS */\n\n\t/*\n\t *  Begin\n\t */\n\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\tDUK_ASSERT(heap->ms_running == 0);\n\theap->ms_prevent_count = 1;\n\theap->ms_running = 1;\n\n\t/*\n\t *  Free activation/catcher freelists on every mark-and-sweep for now.\n\t *  This is an initial rough draft; ideally we'd keep count of the\n\t *  freelist size and free only excess entries.\n\t */\n\n\tDUK_D(DUK_DPRINT(\"freeing temporary freelists\"));\n\tduk_heap_free_freelists(heap);\n\n\t/*\n\t *  Mark roots, hoping that recursion limit is not normally hit.\n\t *  If recursion limit is hit, run additional reachability rounds\n\t *  starting from \"temproots\" until marking is complete.\n\t *\n\t *  Marking happens in two phases: first we mark actual reachability\n\t *  roots (and run \"temproots\" to complete the process).  Then we\n\t *  check which objects are unreachable and are finalizable; such\n\t *  objects are marked as FINALIZABLE and marked as reachability\n\t *  (and \"temproots\" is run again to complete the process).\n\t *\n\t *  The heap finalize_list must also be marked as a reachability root.\n\t *  There may be objects on the list from a previous round if the\n\t *  previous run had finalizer skip flag.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__clear_assert_refcounts(heap);\n#endif\n#if defined(DUK_USE_LITCACHE_SIZE)\n\tduk__wipe_litcache(heap);\n#endif\n\tduk__mark_roots_heap(heap);               /* Mark main reachability roots. */\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);   /* Always handled to completion inline in DECREF. */\n#endif\n\tduk__mark_temproots_by_heap_scan(heap);   /* Temproots. */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__mark_finalizable(heap);              /* Mark finalizable as reachability roots. */\n\tduk__mark_finalize_list(heap);            /* Mark finalizer work list as reachability roots. */\n#endif\n\tduk__mark_temproots_by_heap_scan(heap);   /* Temproots. */\n\n\t/*\n\t *  Sweep garbage and remove marking flags, and move objects with\n\t *  finalizers to the finalizer work list.\n\t *\n\t *  Objects to be swept need to get their refcounts finalized before\n\t *  they are swept.  In other words, their target object refcounts\n\t *  need to be decreased.  This has to be done before freeing any\n\t *  objects to avoid decref'ing dangling pointers (which may happen\n\t *  even without bugs, e.g. with reference loops)\n\t *\n\t *  Because strings don't point to other heap objects, similar\n\t *  finalization is not necessary for strings.\n\t */\n\n\t/* XXX: more emergency behavior, e.g. find smaller hash sizes etc */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__finalize_refcounts(heap);\n#endif\n\tduk__sweep_heap(heap, flags, &count_keep_obj);\n\tduk__sweep_stringtable(heap, &count_keep_str);\n#if defined(DUK_USE_ASSERTIONS) && defined(DUK_USE_REFERENCE_COUNTING)\n\tduk__check_assert_refcounts(heap);\n#endif\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tDUK_ASSERT(heap->refzero_list == NULL);   /* Always handled to completion inline in DECREF. */\n#endif\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\tduk__clear_finalize_list_flags(heap);\n#endif\n\n\t/*\n\t *  Object compaction (emergency only).\n\t *\n\t *  Object compaction is a separate step after sweeping, as there is\n\t *  more free memory for it to work with.  Also, currently compaction\n\t *  may insert new objects into the heap allocated list and the string\n\t *  table which we don't want to do during a sweep (the reachability\n\t *  flags of such objects would be incorrect).  The objects inserted\n\t *  are currently:\n\t *\n\t *    - a temporary duk_hbuffer for a new properties allocation\n\t *    - if array part is abandoned, string keys are interned\n\t *\n\t *  The object insertions go to the front of the list, so they do not\n\t *  cause an infinite loop (they are not compacted).\n\t *\n\t *  At present compaction is not allowed when mark-and-sweep runs\n\t *  during error handling because it involves a duk_safe_call()\n\t *  interfering with error state.\n\t */\n\n\tif ((flags & DUK_MS_FLAG_EMERGENCY) &&\n\t    !(flags & DUK_MS_FLAG_NO_OBJECT_COMPACTION)) {\n\t\tif (heap->lj.type != DUK_LJ_TYPE_UNKNOWN) {\n\t\t\tDUK_D(DUK_DPRINT(\"lj.type (%ld) not DUK_LJ_TYPE_UNKNOWN, skip object compaction\", (long) heap->lj.type));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"object compaction\"));\n\t\t\tduk__compact_objects(heap);\n\t\t}\n\t}\n\n\t/*\n\t *  String table resize check.\n\t *\n\t *  This is mainly useful in emergency GC: if the string table load\n\t *  factor is really low for some reason, we can shrink the string\n\t *  table to a smaller size and free some memory in the process.\n\t *  Only execute in emergency GC.  String table has internal flags\n\t *  to protect against recursive resizing if this mark-and-sweep pass\n\t *  was triggered by a string table resize.\n\t */\n\n\tif (flags & DUK_MS_FLAG_EMERGENCY) {\n\t\tDUK_D(DUK_DPRINT(\"stringtable resize check in emergency gc\"));\n\t\tduk_heap_strtable_force_resize(heap);\n\t}\n\n\t/*\n\t *  Finish\n\t */\n\n\tDUK_ASSERT(heap->ms_prevent_count == 1);\n\tDUK_ASSERT(heap->ms_running == 1);\n\theap->ms_prevent_count = 0;\n\theap->ms_running = 0;\n\n\t/*\n\t *  Assertions after\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(heap->ms_prevent_count == 0);\n\tDUK_ASSERT(!DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap));\n\tDUK_ASSERT(heap->ms_recursion_depth == 0);\n\tduk__assert_heaphdr_flags(heap);\n\tduk__assert_validity(heap);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t/* Note: heap->refzero_free_running may be true; a refcount\n\t * finalizer may trigger a mark-and-sweep.\n\t */\n\tduk__assert_valid_refcounts(heap);\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n#if defined(DUK_USE_LITCACHE_SIZE)\n\tduk__assert_litcache_nulls(heap);\n#endif  /* DUK_USE_LITCACHE_SIZE */\n#endif  /* DUK_USE_ASSERTIONS */\n\n\t/*\n\t *  Reset trigger counter\n\t */\n\n#if defined(DUK_USE_VOLUNTARY_GC)\n\ttmp = (count_keep_obj + count_keep_str) / 256;\n\theap->ms_trigger_counter = (duk_int_t) (\n\t    (tmp * DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT) +\n\t    DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD);\n\tDUK_D(DUK_DPRINT(\"garbage collect (mark-and-sweep) finished: %ld objects kept, %ld strings kept, trigger reset to %ld\",\n\t                 (long) count_keep_obj, (long) count_keep_str, (long) heap->ms_trigger_counter));\n#else\n\tDUK_D(DUK_DPRINT(\"garbage collect (mark-and-sweep) finished: %ld objects kept, %ld strings kept, no voluntary trigger\",\n\t                 (long) count_keep_obj, (long) count_keep_str));\n#endif\n\n\t/*\n\t *  Stats dump\n\t */\n\n#if defined(DUK_USE_DEBUG)\n\tduk__dump_stats(heap);\n#endif\n\n\t/*\n\t *  Finalize objects in the finalization work list.  Finalized\n\t *  objects are queued back to heap_allocated with FINALIZED set.\n\t *\n\t *  Since finalizers may cause arbitrary side effects, they are\n\t *  prevented e.g. during string table and object property allocation\n\t *  resizing using heap->pf_prevent_count.  In this case the objects\n\t *  remain in the finalization work list after mark-and-sweep exits\n\t *  and they may be finalized on the next pass or any DECREF checking\n\t *  for finalize_list.\n\t *\n\t *  As of Duktape 2.1 finalization happens outside mark-and-sweep\n\t *  protection.  Mark-and-sweep is allowed while the finalize_list\n\t *  is being processed, but no rescue decisions are done while the\n\t *  process is on-going.  This avoids incorrect rescue decisions\n\t *  if an object is considered reachable (and thus rescued) because\n\t *  of a reference via finalize_list (which is considered a reachability\n\t *  root).  When finalize_list is being processed, reachable objects\n\t *  with FINALIZED set will just keep their FINALIZED flag for later\n\t *  mark-and-sweep processing.\n\t *\n\t *  This could also be handled (a bit better) by having a more refined\n\t *  notion of reachability for rescue/free decisions.\n\t *\n\t *  XXX: avoid finalizer execution when doing emergency GC?\n\t */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t/* Attempt to process finalize_list, pf_prevent_count check\n\t * is inside the target.\n\t */\n\tduk_heap_process_finalize_list(heap);\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_heap_memory.c",
    "content": "/*\n *  Memory allocation handling.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Voluntary GC check\n */\n\n#if defined(DUK_USE_VOLUNTARY_GC)\nDUK_LOCAL DUK_INLINE void duk__check_voluntary_gc(duk_heap *heap) {\n\tif (DUK_UNLIKELY(--(heap)->ms_trigger_counter < 0)) {\n#if defined(DUK_USE_DEBUG)\n\t\tif (heap->ms_prevent_count == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"triggering voluntary mark-and-sweep\"));\n\t\t} else {\n\t\t\tDUK_DD(DUK_DDPRINT(\"gc blocked -> skip voluntary mark-and-sweep now\"));\n\t\t}\n#endif\n\n\t\t/* Prevention checks in the call target handle cases where\n\t\t * voluntary GC is not allowed.  The voluntary GC trigger\n\t\t * counter is only rewritten if mark-and-sweep actually runs.\n\t\t */\n\t\tduk_heap_mark_and_sweep(heap, DUK_MS_FLAG_VOLUNTARY /*flags*/);\n\t}\n}\n#define DUK__VOLUNTARY_PERIODIC_GC(heap)  do { duk__check_voluntary_gc((heap)); } while (0)\n#else\n#define DUK__VOLUNTARY_PERIODIC_GC(heap)  /* no voluntary gc */\n#endif  /* DUK_USE_VOLUNTARY_GC */\n\n/*\n *  Allocate memory with garbage collection\n */\n\nDUK_INTERNAL void *duk_heap_mem_alloc(duk_heap *heap, duk_size_t size) {\n\tvoid *res;\n\tduk_small_int_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT_DISABLE(size >= 0);\n\n\t/*\n\t *  Voluntary periodic GC (if enabled)\n\t */\n\n\tDUK__VOLUNTARY_PERIODIC_GC(heap);\n\n\t/*\n\t *  First attempt\n\t */\n\n#if defined(DUK_USE_GC_TORTURE)\n\t/* Simulate alloc failure on every alloc, except when mark-and-sweep\n\t * is running.\n\t */\n\tif (heap->ms_prevent_count == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"gc torture enabled, pretend that first alloc attempt fails\"));\n\t\tres = NULL;\n\t\tDUK_UNREF(res);\n\t\tgoto skip_attempt;\n\t}\n#endif\n\tres = heap->alloc_func(heap->heap_udata, size);\n\tif (DUK_LIKELY(res || size == 0)) {\n\t\t/* For zero size allocations NULL is allowed. */\n\t\treturn res;\n\t}\n#if defined(DUK_USE_GC_TORTURE)\n skip_attempt:\n#endif\n\n\tDUK_D(DUK_DPRINT(\"first alloc attempt failed, attempt to gc and retry\"));\n\n#if 0\n\t/*\n\t *  Avoid a GC if GC is already running.  This can happen at a late\n\t *  stage in a GC when we try to e.g. resize the stringtable\n\t *  or compact objects.\n\t *\n\t *  NOTE: explicit handling isn't actually be needed: if the GC is\n\t *  not allowed, duk_heap_mark_and_sweep() will reject it for every\n\t *  attempt in the loop below, resulting in a NULL same as here.\n\t */\n\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_alloc() failed, gc in progress (gc skipped), alloc size %ld\", (long) size));\n\t\treturn NULL;\n\t}\n#endif\n\n\t/*\n\t *  Retry with several GC attempts.  Initial attempts are made without\n\t *  emergency mode; later attempts use emergency mode which minimizes\n\t *  memory allocations forcibly.\n\t */\n\n\tfor (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) {\n\t\tduk_small_uint_t flags;\n\n\t\tflags = 0;\n\t\tif (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) {\n\t\t\tflags |= DUK_MS_FLAG_EMERGENCY;\n\t\t}\n\n\t\tduk_heap_mark_and_sweep(heap, flags);\n\n\t\tres = heap->alloc_func(heap->heap_udata, size);\n\t\tif (res) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_alloc() succeeded after gc (pass %ld), alloc size %ld\",\n\t\t\t                 (long) (i + 1), (long) size));\n\t\t\treturn res;\n\t\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"duk_heap_mem_alloc() failed even after gc, alloc size %ld\", (long) size));\n\treturn NULL;\n}\n\nDUK_INTERNAL void *duk_heap_mem_alloc_zeroed(duk_heap *heap, duk_size_t size) {\n\tvoid *res;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT_DISABLE(size >= 0);\n\n\tres = DUK_ALLOC(heap, size);\n\tif (DUK_LIKELY(res != NULL)) {\n\t\tduk_memzero(res, size);\n\t}\n\treturn res;\n}\n\nDUK_INTERNAL void *duk_heap_mem_alloc_checked(duk_hthread *thr, duk_size_t size) {\n\tvoid *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tres = duk_heap_mem_alloc(thr->heap, size);\n\tif (DUK_LIKELY(res != NULL || size == 0)) {\n\t\treturn res;\n\t}\n\tDUK_ERROR_ALLOC_FAILED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_INTERNAL void *duk_heap_mem_alloc_checked_zeroed(duk_hthread *thr, duk_size_t size) {\n\tvoid *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tres = duk_heap_mem_alloc_zeroed(thr->heap, size);\n\tif (DUK_LIKELY(res != NULL || size == 0)) {\n\t\treturn res;\n\t}\n\tDUK_ERROR_ALLOC_FAILED(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Reallocate memory with garbage collection\n */\n\nDUK_INTERNAL void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, duk_size_t newsize) {\n\tvoid *res;\n\tduk_small_int_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\t/* ptr may be NULL */\n\tDUK_ASSERT_DISABLE(newsize >= 0);\n\n\t/*\n\t *  Voluntary periodic GC (if enabled)\n\t */\n\n\tDUK__VOLUNTARY_PERIODIC_GC(heap);\n\n\t/*\n\t *  First attempt\n\t */\n\n#if defined(DUK_USE_GC_TORTURE)\n\t/* Simulate alloc failure on every realloc, except when mark-and-sweep\n\t * is running.\n\t */\n\tif (heap->ms_prevent_count == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"gc torture enabled, pretend that first realloc attempt fails\"));\n\t\tres = NULL;\n\t\tDUK_UNREF(res);\n\t\tgoto skip_attempt;\n\t}\n#endif\n\tres = heap->realloc_func(heap->heap_udata, ptr, newsize);\n\tif (DUK_LIKELY(res || newsize == 0)) {\n\t\t/* For zero size allocations NULL is allowed. */\n\t\treturn res;\n\t}\n#if defined(DUK_USE_GC_TORTURE)\n skip_attempt:\n#endif\n\n\tDUK_D(DUK_DPRINT(\"first realloc attempt failed, attempt to gc and retry\"));\n\n#if 0\n\t/*\n\t *  Avoid a GC if GC is already running.  See duk_heap_mem_alloc().\n\t */\n\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc() failed, gc in progress (gc skipped), alloc size %ld\", (long) newsize));\n\t\treturn NULL;\n\t}\n#endif\n\n\t/*\n\t *  Retry with several GC attempts.  Initial attempts are made without\n\t *  emergency mode; later attempts use emergency mode which minimizes\n\t *  memory allocations forcibly.\n\t */\n\n\tfor (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) {\n\t\tduk_small_uint_t flags;\n\n\t\tflags = 0;\n\t\tif (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) {\n\t\t\tflags |= DUK_MS_FLAG_EMERGENCY;\n\t\t}\n\n\t\tduk_heap_mark_and_sweep(heap, flags);\n\n\t\tres = heap->realloc_func(heap->heap_udata, ptr, newsize);\n\t\tif (res || newsize == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc() succeeded after gc (pass %ld), alloc size %ld\",\n\t\t\t                 (long) (i + 1), (long) newsize));\n\t\t\treturn res;\n\t\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc() failed even after gc, alloc size %ld\", (long) newsize));\n\treturn NULL;\n}\n\n/*\n *  Reallocate memory with garbage collection, using a callback to provide\n *  the current allocated pointer.  This variant is used when a mark-and-sweep\n *  (e.g. finalizers) might change the original pointer.\n */\n\nDUK_INTERNAL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize) {\n\tvoid *res;\n\tduk_small_int_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT_DISABLE(newsize >= 0);\n\n\t/*\n\t *  Voluntary periodic GC (if enabled)\n\t */\n\n\tDUK__VOLUNTARY_PERIODIC_GC(heap);\n\n\t/*\n\t *  First attempt\n\t */\n\n#if defined(DUK_USE_GC_TORTURE)\n\t/* Simulate alloc failure on every realloc, except when mark-and-sweep\n\t * is running.\n\t */\n\tif (heap->ms_prevent_count == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"gc torture enabled, pretend that first indirect realloc attempt fails\"));\n\t\tres = NULL;\n\t\tDUK_UNREF(res);\n\t\tgoto skip_attempt;\n\t}\n#endif\n\tres = heap->realloc_func(heap->heap_udata, cb(heap, ud), newsize);\n\tif (DUK_LIKELY(res || newsize == 0)) {\n\t\t/* For zero size allocations NULL is allowed. */\n\t\treturn res;\n\t}\n#if defined(DUK_USE_GC_TORTURE)\n skip_attempt:\n#endif\n\n\tDUK_D(DUK_DPRINT(\"first indirect realloc attempt failed, attempt to gc and retry\"));\n\n#if 0\n\t/*\n\t *  Avoid a GC if GC is already running.  See duk_heap_mem_alloc().\n\t */\n\n\tif (heap->ms_prevent_count != 0) {\n\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc_indirect() failed, gc in progress (gc skipped), alloc size %ld\", (long) newsize));\n\t\treturn NULL;\n\t}\n#endif\n\n\t/*\n\t *  Retry with several GC attempts.  Initial attempts are made without\n\t *  emergency mode; later attempts use emergency mode which minimizes\n\t *  memory allocations forcibly.\n\t */\n\n\tfor (i = 0; i < DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT; i++) {\n\t\tduk_small_uint_t flags;\n\n#if defined(DUK_USE_DEBUG)\n\t\tvoid *ptr_pre;\n\t\tvoid *ptr_post;\n#endif\n\n#if defined(DUK_USE_DEBUG)\n\t\tptr_pre = cb(heap, ud);\n#endif\n\t\tflags = 0;\n\t\tif (i >= DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT - 1) {\n\t\t\tflags |= DUK_MS_FLAG_EMERGENCY;\n\t\t}\n\n\t\tduk_heap_mark_and_sweep(heap, flags);\n#if defined(DUK_USE_DEBUG)\n\t\tptr_post = cb(heap, ud);\n\t\tif (ptr_pre != ptr_post) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"realloc base pointer changed by mark-and-sweep: %p -> %p\",\n\t\t\t                   (void *) ptr_pre, (void *) ptr_post));\n\t\t}\n#endif\n\n\t\t/* Note: key issue here is to re-lookup the base pointer on every attempt.\n\t\t * The pointer being reallocated may change after every mark-and-sweep.\n\t\t */\n\n\t\tres = heap->realloc_func(heap->heap_udata, cb(heap, ud), newsize);\n\t\tif (res || newsize == 0) {\n\t\t\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc_indirect() succeeded after gc (pass %ld), alloc size %ld\",\n\t\t\t                 (long) (i + 1), (long) newsize));\n\t\t\treturn res;\n\t\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"duk_heap_mem_realloc_indirect() failed even after gc, alloc size %ld\", (long) newsize));\n\treturn NULL;\n}\n\n/*\n *  Free memory\n */\n\nDUK_INTERNAL void duk_heap_mem_free(duk_heap *heap, void *ptr) {\n\tDUK_ASSERT(heap != NULL);\n\t/* ptr may be NULL */\n\n\t/* Must behave like a no-op with NULL and any pointer returned from\n\t * malloc/realloc with zero size.\n\t */\n\theap->free_func(heap->heap_udata, ptr);\n\n\t/* Never perform a GC (even voluntary) in a memory free, otherwise\n\t * all call sites doing frees would need to deal with the side effects.\n\t * No need to update voluntary GC counter either.\n\t */\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_heap_misc.c",
    "content": "/*\n *  Support functions for duk_heap.\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphdr *hdr) {\n\tduk_heaphdr *root;\n\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) != DUK_HTYPE_STRING);\n\n\troot = heap->heap_allocated;\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tif (root != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, root) == NULL);\n\t\tDUK_HEAPHDR_SET_PREV(heap, root, hdr);\n\t}\n\tDUK_HEAPHDR_SET_PREV(heap, hdr, NULL);\n#endif\n\tDUK_HEAPHDR_SET_NEXT(heap, hdr, root);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, hdr);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, root);\n\theap->heap_allocated = hdr;\n}\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\nDUK_INTERNAL void duk_heap_remove_from_heap_allocated(duk_heap *heap, duk_heaphdr *hdr) {\n\tduk_heaphdr *prev;\n\tduk_heaphdr *next;\n\n\t/* Strings are in string table. */\n\tDUK_ASSERT(hdr != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(hdr) != DUK_HTYPE_STRING);\n\n\t/* Target 'hdr' must be in heap_allocated (not e.g. finalize_list).\n\t * If not, heap lists will become corrupted so assert early for it.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\t{\n\t\tduk_heaphdr *tmp;\n\t\tfor (tmp = heap->heap_allocated; tmp != NULL; tmp = DUK_HEAPHDR_GET_NEXT(heap, tmp)) {\n\t\t\tif (tmp == hdr) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(tmp == hdr);\n\t}\n#endif\n\n\t/* Read/write only once to minimize pointer compression calls. */\n\tprev = DUK_HEAPHDR_GET_PREV(heap, hdr);\n\tnext = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\n\tif (prev != NULL) {\n\t\tDUK_ASSERT(heap->heap_allocated != hdr);\n\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, next);\n\t} else {\n\t\tDUK_ASSERT(heap->heap_allocated == hdr);\n\t\theap->heap_allocated = next;\n\t}\n\tif (next != NULL) {\n\t\tDUK_HEAPHDR_SET_PREV(heap, next, prev);\n\t} else {\n\t\t;\n\t}\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL void duk_heap_insert_into_finalize_list(duk_heap *heap, duk_heaphdr *hdr) {\n\tduk_heaphdr *root;\n\n\troot = heap->finalize_list;\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tDUK_HEAPHDR_SET_PREV(heap, hdr, NULL);\n\tif (root != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, root) == NULL);\n\t\tDUK_HEAPHDR_SET_PREV(heap, root, hdr);\n\t}\n#endif\n\tDUK_HEAPHDR_SET_NEXT(heap, hdr, root);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, hdr);\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, root);\n\theap->finalize_list = hdr;\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL void duk_heap_remove_from_finalize_list(duk_heap *heap, duk_heaphdr *hdr) {\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tduk_heaphdr *next;\n\tduk_heaphdr *prev;\n\n\tnext = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\tprev = DUK_HEAPHDR_GET_PREV(heap, hdr);\n\tif (next != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, next) == hdr);\n\t\tDUK_HEAPHDR_SET_PREV(heap, next, prev);\n\t}\n\tif (prev == NULL) {\n\t\tDUK_ASSERT(hdr == heap->finalize_list);\n\t\theap->finalize_list = next;\n\t} else {\n\t\tDUK_ASSERT(hdr != heap->finalize_list);\n\t\tDUK_HEAPHDR_SET_NEXT(heap, prev, next);\n\t}\n#else\n\tduk_heaphdr *next;\n\tduk_heaphdr *curr;\n\n\t/* Random removal is expensive: we need to locate the previous element\n\t * because we don't have a 'prev' pointer.\n\t */\n\tcurr = heap->finalize_list;\n\tif (curr == hdr) {\n\t\theap->finalize_list = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t} else {\n\t\tDUK_ASSERT(hdr != heap->finalize_list);\n\t\tfor (;;) {\n\t\t\tDUK_ASSERT(curr != NULL);  /* Caller responsibility. */\n\n\t\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, curr);\n\t\t\tif (next == hdr) {\n\t\t\t\tnext = DUK_HEAPHDR_GET_NEXT(heap, hdr);\n\t\t\t\tDUK_HEAPHDR_SET_NEXT(heap, curr, next);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n#endif\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL duk_bool_t duk_heap_in_heap_allocated(duk_heap *heap, duk_heaphdr *ptr) {\n\tduk_heaphdr *curr;\n\tDUK_ASSERT(heap != NULL);\n\n\tfor (curr = heap->heap_allocated; curr != NULL; curr = DUK_HEAPHDR_GET_NEXT(heap, curr)) {\n\t\tif (curr == ptr) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\treturn 0;\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\nDUK_INTERNAL void duk_heap_switch_thread(duk_heap *heap, duk_hthread *new_thr) {\n\tduk_hthread *curr_thr;\n\n\tDUK_ASSERT(heap != NULL);\n\n\tif (new_thr != NULL) {\n\t\tcurr_thr = heap->curr_thread;\n\t\tif (curr_thr == NULL) {\n\t\t\t/* For initial entry use default value; zero forces an\n\t\t\t * interrupt before executing the first insturction.\n\t\t\t */\n\t\t\tDUK_DD(DUK_DDPRINT(\"switch thread, initial entry, init default interrupt counter\"));\n\t\t\tnew_thr->interrupt_counter = 0;\n\t\t\tnew_thr->interrupt_init = 0;\n\t\t} else {\n\t\t\t/* Copy interrupt counter/init value state to new thread (if any).\n\t\t\t * It's OK for new_thr to be the same as curr_thr.\n\t\t\t */\n#if defined(DUK_USE_DEBUG)\n\t\t\tif (new_thr != curr_thr) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"switch thread, not initial entry, copy interrupt counter\"));\n\t\t\t}\n#endif\n\t\t\tnew_thr->interrupt_counter = curr_thr->interrupt_counter;\n\t\t\tnew_thr->interrupt_init = curr_thr->interrupt_init;\n\t\t}\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"switch thread, new thread is NULL, no interrupt counter changes\"));\n\t}\n\n\theap->curr_thread = new_thr;  /* may be NULL */\n}\n#endif  /* DUK_USE_INTERRUPT_COUNTER */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL void duk_heap_assert_valid(duk_heap *heap) {\n\tDUK_ASSERT(heap != NULL);\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_heap_refcount.c",
    "content": "/*\n *  Reference counting implementation.\n *\n *  INCREF/DECREF, finalization and freeing of objects whose refcount reaches\n *  zero (refzero).  These operations are very performance sensitive, so\n *  various small tricks are used in an attempt to maximize speed.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\n#if !defined(DUK_USE_DOUBLE_LINKED_HEAP)\n#error internal error, reference counting requires a double linked heap\n#endif\n\n/*\n *  Heap object refcount finalization.\n *\n *  When an object is about to be freed, all other objects it refers to must\n *  be decref'd.  Refcount finalization does NOT free the object or its inner\n *  allocations (mark-and-sweep shares these helpers), it just manipulates\n *  the refcounts.\n *\n *  Note that any of the DECREFs may cause a refcount to drop to zero.  If so,\n *  the object won't be refzero processed inline, but will just be queued to\n *  refzero_list and processed by an earlier caller working on refzero_list,\n *  eliminating C recursion from even long refzero cascades.  If refzero\n *  finalization is triggered by mark-and-sweep, refzero conditions are ignored\n *  (objects are not even queued to refzero_list) because mark-and-sweep deals\n *  with them; refcounts are still updated so that they remain in sync with\n *  actual references.\n */\n\nDUK_LOCAL void duk__decref_tvals_norz(duk_hthread *thr, duk_tval *tv, duk_idx_t count) {\n\tDUK_ASSERT(count == 0 || tv != NULL);\n\n\twhile (count-- > 0) {\n\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t\ttv++;\n\t}\n}\n\nDUK_INTERNAL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject *h) {\n\tduk_hthread *thr;\n\tduk_uint_fast32_t i;\n\tduk_uint_fast32_t n;\n\tduk_propvalue *p_val;\n\tduk_tval *p_tv;\n\tduk_hstring **p_key;\n\tduk_uint8_t *p_flag;\n\tduk_hobject *h_proto;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(h);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) h) == DUK_HTYPE_OBJECT);\n\n\tthr = heap->heap_thread;\n\tDUK_ASSERT(thr != NULL);\n\n\tp_key = DUK_HOBJECT_E_GET_KEY_BASE(heap, h);\n\tp_val = DUK_HOBJECT_E_GET_VALUE_BASE(heap, h);\n\tp_flag = DUK_HOBJECT_E_GET_FLAGS_BASE(heap, h);\n\tn = DUK_HOBJECT_GET_ENEXT(h);\n\twhile (n-- > 0) {\n\t\tduk_hstring *key;\n\n\t\tkey = p_key[n];\n\t\tif (DUK_UNLIKELY(key == NULL)) {\n\t\t\tcontinue;\n\t\t}\n\t\tDUK_HSTRING_DECREF_NORZ(thr, key);\n\t\tif (DUK_UNLIKELY(p_flag[n] & DUK_PROPDESC_FLAG_ACCESSOR)) {\n\t\t\tduk_hobject *h_getset;\n\t\t\th_getset = p_val[n].a.get;\n\t\t\tDUK_ASSERT(h_getset == NULL || DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_getset));\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h_getset);\n\t\t\th_getset = p_val[n].a.set;\n\t\t\tDUK_ASSERT(h_getset == NULL || DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_getset));\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h_getset);\n\t\t} else {\n\t\t\tduk_tval *tv_val;\n\t\t\ttv_val = &p_val[n].v;\n\t\t\tDUK_TVAL_DECREF_NORZ(thr, tv_val);\n\t\t}\n\t}\n\n\tp_tv = DUK_HOBJECT_A_GET_BASE(heap, h);\n\tn = DUK_HOBJECT_GET_ASIZE(h);\n\twhile (n-- > 0) {\n\t\tduk_tval *tv_val;\n\t\ttv_val = p_tv + n;\n\t\tDUK_TVAL_DECREF_NORZ(thr, tv_val);\n\t}\n\n\t/* Hash part is a 'weak reference' and doesn't contribute to refcounts. */\n\n\th_proto = (duk_hobject *) DUK_HOBJECT_GET_PROTOTYPE(heap, h);\n\tDUK_ASSERT(h_proto == NULL || DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_proto));\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, h_proto);\n\n\t/* XXX: Object subclass tests are quite awkward at present, ideally\n\t * we should be able to switch-case here with a dense index (subtype\n\t * number or something).  For now, fast path plain objects and arrays\n\t * and bit test the rest individually.\n\t */\n\n\tif (DUK_HOBJECT_HAS_FASTREFS(h)) {\n\t\t/* Plain object or array, nothing more to do.  While a\n\t\t * duk_harray has additional fields, none of them need\n\t\t * DECREF updates.\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_ALLOWS_FASTREFS(h));\n\t\treturn;\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_PROHIBITS_FASTREFS(h));\n\n\t/* Slow path: special object, start bit checks from most likely. */\n\n\t/* XXX: reorg, more common first */\n\tif (DUK_HOBJECT_IS_COMPFUNC(h)) {\n\t\tduk_hcompfunc *f = (duk_hcompfunc *) h;\n\t\tduk_tval *tv, *tv_end;\n\t\tduk_hobject **funcs, **funcs_end;\n\n\t\tDUK_HCOMPFUNC_ASSERT_VALID(f);\n\n\t\tif (DUK_LIKELY(DUK_HCOMPFUNC_GET_DATA(heap, f) != NULL)) {\n\t\t\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(heap, f);\n\t\t\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(heap, f);\n\t\t\twhile (tv < tv_end) {\n\t\t\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t\t\t\ttv++;\n\t\t\t}\n\n\t\t\tfuncs = DUK_HCOMPFUNC_GET_FUNCS_BASE(heap, f);\n\t\t\tfuncs_end = DUK_HCOMPFUNC_GET_FUNCS_END(heap, f);\n\t\t\twhile (funcs < funcs_end) {\n\t\t\t\tduk_hobject *h_func;\n\t\t\t\th_func = *funcs;\n\t\t\t\tDUK_ASSERT(h_func != NULL);\n\t\t\t\tDUK_ASSERT(DUK_HEAPHDR_IS_OBJECT((duk_heaphdr *) h_func));\n\t\t\t\tDUK_HCOMPFUNC_DECREF_NORZ(thr, (duk_hcompfunc *) h_func);\n\t\t\t\tfuncs++;\n\t\t\t}\n\t\t} else {\n\t\t\t/* May happen in some out-of-memory corner cases. */\n\t\t\tDUK_D(DUK_DPRINT(\"duk_hcompfunc 'data' is NULL, skipping decref\"));\n\t\t}\n\n\t\tDUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_heaphdr *) DUK_HCOMPFUNC_GET_LEXENV(heap, f));\n\t\tDUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_heaphdr *) DUK_HCOMPFUNC_GET_VARENV(heap, f));\n\t\tDUK_HEAPHDR_DECREF_ALLOWNULL(thr, (duk_hbuffer *) DUK_HCOMPFUNC_GET_DATA(heap, f));\n\t} else if (DUK_HOBJECT_IS_DECENV(h)) {\n\t\tduk_hdecenv *e = (duk_hdecenv *) h;\n\t\tDUK_HDECENV_ASSERT_VALID(e);\n\t\tDUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr, e->thread);\n\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, e->varmap);\n\t} else if (DUK_HOBJECT_IS_OBJENV(h)) {\n\t\tduk_hobjenv *e = (duk_hobjenv *) h;\n\t\tDUK_HOBJENV_ASSERT_VALID(e);\n\t\tDUK_ASSERT(e->target != NULL);  /* Required for object environments. */\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, e->target);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t} else if (DUK_HOBJECT_IS_BUFOBJ(h)) {\n\t\tduk_hbufobj *b = (duk_hbufobj *) h;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(b);\n\t\tDUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr, (duk_hbuffer *) b->buf);\n\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) b->buf_prop);\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h)) {\n\t\tduk_hboundfunc *f = (duk_hboundfunc *) (void *) h;\n\t\tDUK_HBOUNDFUNC_ASSERT_VALID(f);\n\t\tDUK_TVAL_DECREF_NORZ(thr, &f->target);\n\t\tDUK_TVAL_DECREF_NORZ(thr, &f->this_binding);\n\t\tduk__decref_tvals_norz(thr, f->args, f->nargs);\n#if defined(DUK_USE_ES6_PROXY)\n\t} else if (DUK_HOBJECT_IS_PROXY(h)) {\n\t\tduk_hproxy *p = (duk_hproxy *) h;\n\t\tDUK_HPROXY_ASSERT_VALID(p);\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, p->target);\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, p->handler);\n#endif  /* DUK_USE_ES6_PROXY */\n\t} else if (DUK_HOBJECT_IS_THREAD(h)) {\n\t\tduk_hthread *t = (duk_hthread *) h;\n\t\tduk_activation *act;\n\t\tduk_tval *tv;\n\n\t\tDUK_HTHREAD_ASSERT_VALID(t);\n\n\t\ttv = t->valstack;\n\t\twhile (tv < t->valstack_top) {\n\t\t\tDUK_TVAL_DECREF_NORZ(thr, tv);\n\t\t\ttv++;\n\t\t}\n\n\t\tfor (act = t->callstack_curr; act != NULL; act = act->parent) {\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) DUK_ACT_GET_FUNC(act));\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->var_env);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->lex_env);\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) act->prev_caller);\n#endif\n#if 0  /* nothing now */\n\t\t\tfor (cat = act->cat; cat != NULL; cat = cat->parent) {\n\t\t\t}\n#endif\n\t\t}\n\n\n\t\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, (duk_hobject *) t->builtins[i]);\n\t\t}\n\n\t\tDUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr, (duk_hthread *) t->resumer);\n\t} else {\n\t\t/* We may come here if the object should have a FASTREFS flag\n\t\t * but it's missing for some reason.  Assert for never getting\n\t\t * here; however, other than performance, this is harmless.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"missing FASTREFS flag for: %!iO\", h));\n\t\tDUK_ASSERT(0);\n\t}\n}\n\nDUK_INTERNAL void duk_heaphdr_refcount_finalize_norz(duk_heap *heap, duk_heaphdr *hdr) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(hdr != NULL);\n\n\tif (DUK_HEAPHDR_IS_OBJECT(hdr)) {\n\t\tduk_hobject_refcount_finalize_norz(heap, (duk_hobject *) hdr);\n\t}\n\t/* DUK_HTYPE_BUFFER: nothing to finalize */\n\t/* DUK_HTYPE_STRING: nothing to finalize */\n}\n\n/*\n *  Refzero processing for duk_hobject: queue a refzero'ed object to either\n *  finalize_list or refzero_list and process the relevent list(s) if\n *  necessary.\n *\n *  Refzero_list is single linked, with only 'prev' pointers set and valid.\n *  All 'next' pointers are intentionally left as garbage.  This doesn't\n *  matter because refzero_list is processed to completion before any other\n *  code (like mark-and-sweep) might walk the list.\n *\n *  In more detail:\n *\n *  - On first insert refzero_list is NULL and the new object becomes the\n *    first and only element on the list; duk__refcount_free_pending() is\n *    called and it starts processing the list from the initial element,\n *    i.e. the list tail.\n *\n *  - As each object is refcount finalized, new objects may be queued to\n *    refzero_list head.  Their 'next' pointers are left as garbage, but\n *    'prev' points are set correctly, with the element at refzero_list\n *    having a NULL 'prev' pointer.  The fact that refzero_list is non-NULL\n *    is used to reject (1) recursive duk__refcount_free_pending() and\n *    (2) finalize_list processing calls.\n *\n *  - When we're done with the current object, read its 'prev' pointer and\n *    free the object.  If 'prev' is NULL, we've reached head of list and are\n *    done: set refzero_list to NULL and process pending finalizers.  Otherwise\n *    continue processing the list.\n *\n *  A refzero cascade is free of side effects because it only involves\n *  queueing more objects and freeing memory; finalizer execution is blocked\n *  in the code path queueing objects to finalize_list.  As a result the\n *  initial refzero call (which triggers duk__refcount_free_pending()) must\n *  check finalize_list so that finalizers are executed snappily.\n *\n *  If finalize_list processing starts first, refzero may occur while we're\n *  processing finalizers.  That's fine: that particular refzero cascade is\n *  handled to completion without side effects.  Once the cascade is complete,\n *  we'll run pending finalizers but notice that we're already doing that and\n *  return.\n *\n *  This could be expanded to allow incremental freeing: just bail out\n *  early and resume at a future alloc/decref/refzero.  However, if that\n *  were done, the list structure would need to be kept consistent at all\n *  times, mark-and-sweep would need to handle refzero_list, etc.\n */\n\nDUK_LOCAL void duk__refcount_free_pending(duk_heap *heap) {\n\tduk_heaphdr *curr;\n#if defined(DUK_USE_DEBUG)\n\tduk_int_t count = 0;\n#endif\n\n\tDUK_ASSERT(heap != NULL);\n\n\tcurr = heap->refzero_list;\n\tDUK_ASSERT(curr != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, curr) == NULL);  /* We're called on initial insert only. */\n\t/* curr->next is GARBAGE. */\n\n\tdo {\n\t\tduk_heaphdr *prev;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"refzero processing %p: %!O\", (void *) curr, (duk_heaphdr *) curr));\n\n#if defined(DUK_USE_DEBUG)\n\t\tcount++;\n#endif\n\n\t\tDUK_ASSERT(curr != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT);  /* currently, always the case */\n\t\t/* FINALIZED may be set; don't care about flags here. */\n\n\t\t/* Refcount finalize 'curr'.  Refzero_list must be non-NULL\n\t\t * here to prevent recursive entry to duk__refcount_free_pending().\n\t\t */\n\t\tDUK_ASSERT(heap->refzero_list != NULL);\n\t\tduk_hobject_refcount_finalize_norz(heap, (duk_hobject *) curr);\n\n\t\tprev = DUK_HEAPHDR_GET_PREV(heap, curr);\n\t\tDUK_ASSERT((prev == NULL && heap->refzero_list == curr) || \\\n\t\t           (prev != NULL && heap->refzero_list != curr));\n\t\t/* prev->next is intentionally not updated and is garbage. */\n\n\t\tduk_free_hobject(heap, (duk_hobject *) curr);  /* Invalidates 'curr'. */\n\n\t\tcurr = prev;\n\t} while (curr != NULL);\n\n\theap->refzero_list = NULL;\n\n\tDUK_DD(DUK_DDPRINT(\"refzero processed %ld objects\", (long) count));\n}\n\nDUK_LOCAL DUK_INLINE void duk__refcount_refzero_hobject(duk_heap *heap, duk_hobject *obj, duk_bool_t skip_free_pending) {\n\tduk_heaphdr *hdr;\n\tduk_heaphdr *root;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) obj) == DUK_HTYPE_OBJECT);\n\n\thdr = (duk_heaphdr *) obj;\n\n\t/* Refzero'd objects must be in heap_allocated.  They can't be in\n\t * finalize_list because all objects on finalize_list have an\n\t * artificial +1 refcount bump.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(duk_heap_in_heap_allocated(heap, (duk_heaphdr *) obj));\n#endif\n\n\tDUK_HEAP_REMOVE_FROM_HEAP_ALLOCATED(heap, hdr);\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t/* This finalizer check MUST BE side effect free.  It should also be\n\t * as fast as possible because it's applied to every object freed.\n\t */\n\tif (DUK_UNLIKELY(DUK_HOBJECT_HAS_FINALIZER_FAST(heap, (duk_hobject *) hdr) != 0U)) {\n\t\t/* Special case: FINALIZED may be set if mark-and-sweep queued\n\t\t * object for finalization, the finalizer was executed (and\n\t\t * FINALIZED set), mark-and-sweep hasn't yet processed the\n\t\t * object again, but its refcount drops to zero.  Free without\n\t\t * running the finalizer again.\n\t\t */\n\t\tif (DUK_HEAPHDR_HAS_FINALIZED(hdr)) {\n\t\t\tDUK_D(DUK_DPRINT(\"refzero'd object has finalizer and FINALIZED is set -> free\"));\n\t\t} else {\n\t\t\t/* Set FINALIZABLE flag so that all objects on finalize_list\n\t\t\t * will have it set and are thus detectable based on the\n\t\t\t * flag alone.\n\t\t\t */\n\t\t\tDUK_HEAPHDR_SET_FINALIZABLE(hdr);\n\t\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(hdr));\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t/* Bump refcount on finalize_list insert so that a\n\t\t\t * refzero can never occur when an object is waiting\n\t\t\t * for its finalizer call.  Refzero might otherwise\n\t\t\t * now happen because we allow duk_push_heapptr() for\n\t\t\t * objects pending finalization.\n\t\t\t */\n\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(hdr);\n#endif\n\t\t\tDUK_HEAP_INSERT_INTO_FINALIZE_LIST(heap, hdr);\n\n\t\t\t/* Process finalizers unless skipping is explicitly\n\t\t\t * requested (NORZ) or refzero_list is being processed\n\t\t\t * (avoids side effects during a refzero cascade).\n\t\t\t * If refzero_list is processed, the initial refzero\n\t\t\t * call will run pending finalizers when refzero_list\n\t\t\t * is done.\n\t\t\t */\n\t\t\tif (!skip_free_pending && heap->refzero_list == NULL) {\n\t\t\t\tduk_heap_process_finalize_list(heap);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n\t/* No need to finalize, free object via refzero_list. */\n\n\troot = heap->refzero_list;\n\n\tDUK_HEAPHDR_SET_PREV(heap, hdr, NULL);\n\t/* 'next' is left as GARBAGE. */\n\theap->refzero_list = hdr;\n\n\tif (root == NULL) {\n\t\t/* Object is now queued.  Refzero_list was NULL so\n\t\t * no-one is currently processing it; do it here.\n\t\t * With refzero processing just doing a cascade of\n\t\t * free calls, we can process it directly even when\n\t\t * NORZ macros are used: there are no side effects.\n\t\t */\n\t\tduk__refcount_free_pending(heap);\n\t\tDUK_ASSERT(heap->refzero_list == NULL);\n\n\t\t/* Process finalizers only after the entire cascade\n\t\t * is finished.  In most cases there's nothing to\n\t\t * finalize, so fast path check to avoid a call.\n\t\t */\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n\t\tif (!skip_free_pending && DUK_UNLIKELY(heap->finalize_list != NULL)) {\n\t\t\tduk_heap_process_finalize_list(heap);\n\t\t}\n#endif\n\t} else {\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_PREV(heap, root) == NULL);\n\t\tDUK_HEAPHDR_SET_PREV(heap, root, hdr);\n\n\t\t/* Object is now queued.  Because refzero_list was\n\t\t * non-NULL, it's already being processed by someone\n\t\t * in the C call stack, so we're done.\n\t\t */\n\t}\n}\n\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_refzero_check_fast(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->heap->refzero_list == NULL);  /* Processed to completion inline. */\n\n\tif (DUK_UNLIKELY(thr->heap->finalize_list != NULL)) {\n\t\tduk_heap_process_finalize_list(thr->heap);\n\t}\n}\n\nDUK_INTERNAL void duk_refzero_check_slow(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->heap->refzero_list == NULL);  /* Processed to completion inline. */\n\n\tif (DUK_UNLIKELY(thr->heap->finalize_list != NULL)) {\n\t\tduk_heap_process_finalize_list(thr->heap);\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Refzero processing for duk_hstring.\n */\n\nDUK_LOCAL DUK_INLINE void duk__refcount_refzero_hstring(duk_heap *heap, duk_hstring *str) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(str != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) str) == DUK_HTYPE_STRING);\n\n\tduk_heap_strcache_string_remove(heap, str);\n\tduk_heap_strtable_unlink(heap, str);\n\tduk_free_hstring(heap, str);\n}\n\n/*\n *  Refzero processing for duk_hbuffer.\n */\n\nDUK_LOCAL DUK_INLINE void duk__refcount_refzero_hbuffer(duk_heap *heap, duk_hbuffer *buf) {\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->heap_thread != NULL);\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) buf) == DUK_HTYPE_BUFFER);\n\n\tDUK_HEAP_REMOVE_FROM_HEAP_ALLOCATED(heap, (duk_heaphdr *) buf);\n\tduk_free_hbuffer(heap, buf);\n}\n\n/*\n *  Incref and decref functions.\n *\n *  Decref may trigger immediate refzero handling, which may free and finalize\n *  an arbitrary number of objects (a \"DECREF cascade\").\n *\n *  Refzero handling is skipped entirely if (1) mark-and-sweep is running or\n *  (2) execution is paused in the debugger.  The objects are left in the heap,\n *  and will be freed by mark-and-sweep or eventual heap destruction.\n *\n *  This is necessary during mark-and-sweep because refcounts are also updated\n *  during the sweep phase (otherwise objects referenced by a swept object\n *  would have incorrect refcounts) which then calls here.  This could be\n *  avoided by using separate decref macros in mark-and-sweep; however,\n *  mark-and-sweep also calls finalizers which would use the ordinary decref\n *  macros anyway.\n *\n *  We can't process refzeros (= free objects) when the debugger is running\n *  as the debugger might make an object unreachable but still continue\n *  inspecting it (or even cause it to be pushed back).  So we must rely on\n *  mark-and-sweep to collect them.\n *\n *  The DUK__RZ_SUPPRESS_CHECK() condition is also used in heap destruction\n *  when running finalizers for remaining objects: the flag prevents objects\n *  from being moved around in heap linked lists while that's being done.\n *\n *  The suppress condition is important to performance.\n */\n\n#define DUK__RZ_SUPPRESS_ASSERT1() do { \\\n\t\tDUK_ASSERT(thr != NULL); \\\n\t\tDUK_ASSERT(thr->heap != NULL); \\\n\t\t/* When mark-and-sweep runs, heap_thread must exist. */ \\\n\t\tDUK_ASSERT(thr->heap->ms_running == 0 || thr->heap->heap_thread != NULL); \\\n\t\t/* In normal operation finalizers are executed with ms_running == 0 \\\n\t\t * so we should never see ms_running == 1 and thr != heap_thread. \\\n\t\t * In heap destruction finalizers are executed with ms_running != 0 \\\n\t\t * to e.g. prevent refzero; a special value ms_running == 2 is used \\\n\t\t * in that case so it can be distinguished from the normal runtime \\\n\t\t * case, and allows a stronger assertion here (GH-2030). \\\n\t\t */ \\\n\t\tDUK_ASSERT(!(thr->heap->ms_running == 1 && thr != thr->heap->heap_thread)); \\\n\t\t/* We may be called when the heap is initializing and we process \\\n\t\t * refzeros normally, but mark-and-sweep and finalizers are prevented \\\n\t\t * if that's the case. \\\n\t\t */ \\\n\t\tDUK_ASSERT(thr->heap->heap_initializing == 0 || thr->heap->ms_prevent_count > 0); \\\n\t\tDUK_ASSERT(thr->heap->heap_initializing == 0 || thr->heap->pf_prevent_count > 0); \\\n\t} while (0)\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n#define DUK__RZ_SUPPRESS_ASSERT2() do { \\\n\t\t/* When debugger is paused, ms_running is set. */ \\\n\t\tDUK_ASSERT(!DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || thr->heap->ms_running != 0); \\\n\t} while (0)\n#define DUK__RZ_SUPPRESS_COND()  (heap->ms_running != 0)\n#else\n#define DUK__RZ_SUPPRESS_ASSERT2() do { } while (0)\n#define DUK__RZ_SUPPRESS_COND()  (heap->ms_running != 0)\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n#define DUK__RZ_SUPPRESS_CHECK() do { \\\n\t\tDUK__RZ_SUPPRESS_ASSERT1(); \\\n\t\tDUK__RZ_SUPPRESS_ASSERT2(); \\\n\t\tif (DUK_UNLIKELY(DUK__RZ_SUPPRESS_COND())) { \\\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"refzero handling suppressed (not even queued) when mark-and-sweep running, object: %p\", (void *) h)); \\\n\t\t\treturn; \\\n\t\t} \\\n\t} while (0)\n\n#define DUK__RZ_STRING() do { \\\n\t\tduk__refcount_refzero_hstring(heap, (duk_hstring *) h); \\\n\t} while (0)\n#define DUK__RZ_BUFFER() do { \\\n\t\tduk__refcount_refzero_hbuffer(heap, (duk_hbuffer *) h); \\\n\t} while (0)\n#define DUK__RZ_OBJECT() do { \\\n\t\tduk__refcount_refzero_hobject(heap, (duk_hobject *) h, skip_free_pending); \\\n\t} while (0)\n\n/* XXX: test the effect of inlining here vs. NOINLINE in refzero helpers */\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n#define DUK__RZ_INLINE DUK_ALWAYS_INLINE\n#else\n#define DUK__RZ_INLINE /*nop*/\n#endif\n\nDUK_LOCAL DUK__RZ_INLINE void duk__hstring_refzero_helper(duk_hthread *thr, duk_hstring *h) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\tDUK__RZ_SUPPRESS_CHECK();\n\tDUK__RZ_STRING();\n}\n\nDUK_LOCAL DUK__RZ_INLINE void duk__hbuffer_refzero_helper(duk_hthread *thr, duk_hbuffer *h) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\tDUK__RZ_SUPPRESS_CHECK();\n\tDUK__RZ_BUFFER();\n}\n\nDUK_LOCAL DUK__RZ_INLINE void duk__hobject_refzero_helper(duk_hthread *thr, duk_hobject *h, duk_bool_t skip_free_pending) {\n\tduk_heap *heap;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\tDUK__RZ_SUPPRESS_CHECK();\n\tDUK__RZ_OBJECT();\n}\n\nDUK_LOCAL DUK__RZ_INLINE void duk__heaphdr_refzero_helper(duk_hthread *thr, duk_heaphdr *h, duk_bool_t skip_free_pending) {\n\tduk_heap *heap;\n\tduk_small_uint_t htype;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\theap = thr->heap;\n\n\thtype = (duk_small_uint_t) DUK_HEAPHDR_GET_TYPE(h);\n\tDUK_DDD(DUK_DDDPRINT(\"ms_running=%ld, heap_thread=%p\", (long) thr->heap->ms_running, thr->heap->heap_thread));\n\tDUK__RZ_SUPPRESS_CHECK();\n\n\tswitch (htype) {\n\tcase DUK_HTYPE_STRING:\n\t\t/* Strings have no internal references but do have \"weak\"\n\t\t * references in the string cache.  Also note that strings\n\t\t * are not on the heap_allocated list like other heap\n\t\t * elements.\n\t\t */\n\n\t\tDUK__RZ_STRING();\n\t\tbreak;\n\n\tcase DUK_HTYPE_OBJECT:\n\t\t/* Objects have internal references.  Must finalize through\n\t\t * the \"refzero\" work list.\n\t\t */\n\n\t\tDUK__RZ_OBJECT();\n\t\tbreak;\n\n\tdefault:\n\t\t/* Buffers have no internal references.  However, a dynamic\n\t\t * buffer has a separate allocation for the buffer.  This is\n\t\t * freed by duk_heap_free_heaphdr_raw().\n\t\t */\n\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(h) == DUK_HTYPE_BUFFER);\n\t\tDUK__RZ_BUFFER();\n\t\tbreak;\n\t}\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h) {\n\tduk__heaphdr_refzero_helper(thr, h, 0 /*skip_free_pending*/);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_heaphdr_refzero_norz(duk_hthread *thr, duk_heaphdr *h) {\n\tduk__heaphdr_refzero_helper(thr, h, 1 /*skip_free_pending*/);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hstring_refzero(duk_hthread *thr, duk_hstring *h) {\n\tduk__hstring_refzero_helper(thr, h);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hbuffer_refzero(duk_hthread *thr, duk_hbuffer *h) {\n\tduk__hbuffer_refzero_helper(thr, h);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hobject_refzero(duk_hthread *thr, duk_hobject *h) {\n\tduk__hobject_refzero_helper(thr, h, 0 /*skip_free_pending*/);\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_hobject_refzero_norz(duk_hthread *thr, duk_hobject *h) {\n\tduk__hobject_refzero_helper(thr, h, 1 /*skip_free_pending*/);\n}\n\n#if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\nDUK_INTERNAL void duk_tval_incref(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\t\tDUK_ASSERT_DISABLE(h->h_refcount >= 0);\n\t\tDUK_HEAPHDR_PREINC_REFCOUNT(h);\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) != 0);  /* No wrapping. */\n\t}\n}\n\nDUK_INTERNAL void duk_tval_decref(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) >= 1);\n#if 0\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(h) != 0) {\n\t\t\treturn;\n\t\t}\n\t\tduk_heaphdr_refzero(thr, h);\n#else\n\t\tduk_heaphdr_decref(thr, h);\n#endif\n\t}\n}\n\nDUK_INTERNAL void duk_tval_decref_norz(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(h) >= 1);\n#if 0\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(h) != 0) {\n\t\t\treturn;\n\t\t}\n\t\tduk_heaphdr_refzero_norz(thr, h);\n#else\n\t\tduk_heaphdr_decref_norz(thr, h);\n#endif\n\t}\n}\n#endif  /* !DUK_USE_FAST_REFCOUNT_DEFAULT */\n\n#define DUK__DECREF_ASSERTS() do { \\\n\t\tDUK_ASSERT(thr != NULL); \\\n\t\tDUK_ASSERT(thr->heap != NULL); \\\n\t\tDUK_ASSERT(h != NULL); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID((duk_heaphdr *) h)); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) >= 1); \\\n\t} while (0)\n#if defined(DUK_USE_ROM_OBJECTS)\n#define DUK__INCREF_SHARED() do { \\\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t\tDUK_HEAPHDR_PREINC_REFCOUNT((duk_heaphdr *) h); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) != 0);  /* No wrapping. */ \\\n\t} while (0)\n#define DUK__DECREF_SHARED() do { \\\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT((duk_heaphdr *) h) != 0) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t} while (0)\n#else\n#define DUK__INCREF_SHARED() do { \\\n\t\tDUK_HEAPHDR_PREINC_REFCOUNT((duk_heaphdr *) h); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) != 0);  /* No wrapping. */ \\\n\t} while (0)\n#define DUK__DECREF_SHARED() do { \\\n\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT((duk_heaphdr *) h) != 0) { \\\n\t\t\treturn; \\\n\t\t} \\\n\t} while (0)\n#endif\n\n#if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n/* This will in practice be inlined because it's just an INC instructions\n * and a bit test + INC when ROM objects are enabled.\n */\nDUK_INTERNAL void duk_heaphdr_incref(duk_heaphdr *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n\tDUK_ASSERT_DISABLE(DUK_HEAPHDR_GET_REFCOUNT(h) >= 0);\n\n\tDUK__INCREF_SHARED();\n}\n\nDUK_INTERNAL void duk_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_heaphdr_refzero(thr, h);\n\n\t/* Forced mark-and-sweep when GC torture enabled; this could happen\n\t * on any DECREF (but not DECREF_NORZ).\n\t */\n\tDUK_GC_TORTURE(thr->heap);\n}\nDUK_INTERNAL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_heaphdr_refzero_norz(thr, h);\n}\n#endif  /* !DUK_USE_FAST_REFCOUNT_DEFAULT */\n\n#if 0  /* Not needed. */\nDUK_INTERNAL void duk_hstring_decref(duk_hthread *thr, duk_hstring *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hstring_refzero(thr, h);\n}\nDUK_INTERNAL void duk_hstring_decref_norz(duk_hthread *thr, duk_hstring *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hstring_refzero_norz(thr, h);\n}\nDUK_INTERNAL void duk_hbuffer_decref(duk_hthread *thr, duk_hbuffer *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hbuffer_refzero(thr, h);\n}\nDUK_INTERNAL void duk_hbuffer_decref_norz(duk_hthread *thr, duk_hbuffer *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hbuffer_refzero_norz(thr, h);\n}\nDUK_INTERNAL void duk_hobject_decref(duk_hthread *thr, duk_hobject *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hobject_refzero(thr, h);\n}\nDUK_INTERNAL void duk_hobject_decref_norz(duk_hthread *thr, duk_hobject *h) {\n\tDUK__DECREF_ASSERTS();\n\tDUK__DECREF_SHARED();\n\tduk_hobject_refzero_norz(thr, h);\n}\n#endif\n\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\n/* no refcounting */\n\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_heap_stringcache.c",
    "content": "/*\n *  String cache.\n *\n *  Provides a cache to optimize indexed string lookups.  The cache keeps\n *  track of (byte offset, char offset) states for a fixed number of strings.\n *  Otherwise we'd need to scan from either end of the string, as we store\n *  strings in (extended) UTF-8.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Delete references to given hstring from the heap string cache.\n *\n *  String cache references are 'weak': they are not counted towards\n *  reference counts, nor serve as roots for mark-and-sweep.  When an\n *  object is about to be freed, such references need to be removed.\n */\n\nDUK_INTERNAL void duk_heap_strcache_string_remove(duk_heap *heap, duk_hstring *h) {\n\tduk_uint_t i;\n\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\tduk_strcache_entry *c = heap->strcache + i;\n\t\tif (c->h == h) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"deleting weak strcache reference to hstring %p from heap %p\",\n\t\t\t                   (void *) h, (void *) heap));\n\t\t\tc->h = NULL;\n\n\t\t\t/* XXX: the string shouldn't appear twice, but we now loop to the\n\t\t\t * end anyway; if fixed, add a looping assertion to ensure there\n\t\t\t * is no duplicate.\n\t\t\t */\n\t\t}\n\t}\n}\n\n/*\n *  String scanning helpers\n *\n *  All bytes other than UTF-8 continuation bytes ([0x80,0xbf]) are\n *  considered to contribute a character.  This must match how string\n *  character length is computed.\n */\n\nDUK_LOCAL const duk_uint8_t *duk__scan_forwards(const duk_uint8_t *p, const duk_uint8_t *q, duk_uint_fast32_t n) {\n\twhile (n > 0) {\n\t\tfor (;;) {\n\t\t\tp++;\n\t\t\tif (p >= q) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\tif ((*p & 0xc0) != 0x80) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tn--;\n\t}\n\treturn p;\n}\n\nDUK_LOCAL const duk_uint8_t *duk__scan_backwards(const duk_uint8_t *p, const duk_uint8_t *q, duk_uint_fast32_t n) {\n\twhile (n > 0) {\n\t\tfor (;;) {\n\t\t\tp--;\n\t\t\tif (p < q) {\n\t\t\t\treturn NULL;\n\t\t\t}\n\t\t\tif ((*p & 0xc0) != 0x80) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tn--;\n\t}\n\treturn p;\n}\n\n/*\n *  Convert char offset to byte offset\n *\n *  Avoid using the string cache if possible: for ASCII strings byte and\n *  char offsets are equal and for short strings direct scanning may be\n *  better than using the string cache (which may evict a more important\n *  entry).\n *\n *  Typing now assumes 32-bit string byte/char offsets (duk_uint_fast32_t).\n *  Better typing might be to use duk_size_t.\n *\n *  Caller should ensure 'char_offset' is within the string bounds [0,charlen]\n *  (endpoint is inclusive).  If this is not the case, no memory unsafe\n *  behavior will happen but an error will be thrown.\n */\n\nDUK_INTERNAL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *thr, duk_hstring *h, duk_uint_fast32_t char_offset) {\n\tduk_heap *heap;\n\tduk_strcache_entry *sce;\n\tduk_uint_fast32_t byte_offset;\n\tduk_uint_t i;\n\tduk_bool_t use_cache;\n\tduk_uint_fast32_t dist_start, dist_end, dist_sce;\n\tduk_uint_fast32_t char_length;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint8_t *p_found;\n\n\t/*\n\t *  For ASCII strings, the answer is simple.\n\t */\n\n\tif (DUK_LIKELY(DUK_HSTRING_IS_ASCII(h))) {\n\t\treturn char_offset;\n\t}\n\n\tchar_length = (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h);\n\tDUK_ASSERT(char_offset <= char_length);\n\n\tif (DUK_LIKELY(DUK_HSTRING_IS_ASCII(h))) {\n\t\t/* Must recheck because the 'is ascii' flag may be set\n\t\t * lazily.  Alternatively, we could just compare charlen\n\t\t * to bytelen.\n\t\t */\n\t\treturn char_offset;\n\t}\n\n\t/*\n\t *  For non-ASCII strings, we need to scan forwards or backwards\n\t *  from some starting point.  The starting point may be the start\n\t *  or end of the string, or some cached midpoint in the string\n\t *  cache.\n\t *\n\t *  For \"short\" strings we simply scan without checking or updating\n\t *  the cache.  For longer strings we check and update the cache as\n\t *  necessary, inserting a new cache entry if none exists.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string %p, char_offset=%ld, clen=%ld, blen=%ld\",\n\t                     (void *) h, (long) char_offset,\n\t                     (long) DUK_HSTRING_GET_CHARLEN(h),\n\t                     (long) DUK_HSTRING_GET_BYTELEN(h)));\n\n\theap = thr->heap;\n\tsce = NULL;\n\tuse_cache = (char_length > DUK_HEAP_STRINGCACHE_NOCACHE_LIMIT);\n\n\tif (use_cache) {\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t\tDUK_DDD(DUK_DDDPRINT(\"stringcache before char2byte (using cache):\"));\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tduk_strcache_entry *c = heap->strcache + i;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"  [%ld] -> h=%p, cidx=%ld, bidx=%ld\",\n\t\t\t                     (long) i, (void *) c->h, (long) c->cidx, (long) c->bidx));\n\t\t}\n#endif\n\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tduk_strcache_entry *c = heap->strcache + i;\n\n\t\t\tif (c->h == h) {\n\t\t\t\tsce = c;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t/*\n\t *  Scan from shortest distance:\n\t *    - start of string\n\t *    - end of string\n\t *    - cache entry (if exists)\n\t */\n\n\tDUK_ASSERT(DUK_HSTRING_GET_CHARLEN(h) >= char_offset);\n\tdist_start = char_offset;\n\tdist_end = char_length - char_offset;\n\tdist_sce = 0; DUK_UNREF(dist_sce);  /* initialize for debug prints, needed if sce==NULL */\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tp_end = (const duk_uint8_t *) (p_start + DUK_HSTRING_GET_BYTELEN(h));\n\tp_found = NULL;\n\n\tif (sce) {\n\t\tif (char_offset >= sce->cidx) {\n\t\t\tdist_sce = char_offset - sce->cidx;\n\t\t\tif ((dist_sce <= dist_start) && (dist_sce <= dist_end)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t\t\t                     \"scan forwards from sce\",\n\t\t\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\t\t\tp_found = duk__scan_forwards(p_start + sce->bidx,\n\t\t\t\t                             p_end,\n\t\t\t\t                             dist_sce);\n\t\t\t\tgoto scan_done;\n\t\t\t}\n\t\t} else {\n\t\t\tdist_sce = sce->cidx - char_offset;\n\t\t\tif ((dist_sce <= dist_start) && (dist_sce <= dist_end)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t\t\t                     \"scan backwards from sce\",\n\t\t\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\t\t\tp_found = duk__scan_backwards(p_start + sce->bidx,\n\t\t\t\t                              p_start,\n\t\t\t\t                              dist_sce);\n\t\t\t\tgoto scan_done;\n\t\t\t}\n\t\t}\n\t}\n\n\t/* no sce, or sce scan not best */\n\n\tif (dist_start <= dist_end) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t                     \"scan forwards from string start\",\n\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\tp_found = duk__scan_forwards(p_start,\n\t\t                             p_end,\n\t\t                             dist_start);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-ascii string, use_cache=%ld, sce=%p:%ld:%ld, \"\n\t\t                     \"dist_start=%ld, dist_end=%ld, dist_sce=%ld => \"\n\t\t                     \"scan backwards from string end\",\n\t\t                     (long) use_cache, (void *) (sce ? sce->h : NULL),\n\t\t                     (sce ? (long) sce->cidx : (long) -1),\n\t\t                     (sce ? (long) sce->bidx : (long) -1),\n\t\t                     (long) dist_start, (long) dist_end, (long) dist_sce));\n\n\t\tp_found = duk__scan_backwards(p_end,\n\t\t                              p_start,\n\t\t                              dist_end);\n\t}\n\n scan_done:\n\n\tif (DUK_UNLIKELY(p_found == NULL)) {\n\t\t/* Scan error: this shouldn't normally happen; it could happen if\n\t\t * string is not valid UTF-8 data, and clen/blen are not consistent\n\t\t * with the scanning algorithm.\n\t\t */\n\t\tgoto scan_error;\n\t}\n\n\tDUK_ASSERT(p_found >= p_start);\n\tDUK_ASSERT(p_found <= p_end);  /* may be equal */\n\tbyte_offset = (duk_uint32_t) (p_found - p_start);\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> string %p, cidx %ld -> bidx %ld\",\n\t                     (void *) h, (long) char_offset, (long) byte_offset));\n\n\t/*\n\t *  Update cache entry (allocating if necessary), and move the\n\t *  cache entry to the first place (in an \"LRU\" policy).\n\t */\n\n\tif (use_cache) {\n\t\t/* update entry, allocating if necessary */\n\t\tif (!sce) {\n\t\t\tsce = heap->strcache + DUK_HEAP_STRCACHE_SIZE - 1;  /* take last entry */\n\t\t\tsce->h = h;\n\t\t}\n\t\tDUK_ASSERT(sce != NULL);\n\t\tsce->bidx = (duk_uint32_t) (p_found - p_start);\n\t\tsce->cidx = (duk_uint32_t) char_offset;\n\n\t\t/* LRU: move our entry to first */\n\t\tif (sce > &heap->strcache[0]) {\n\t\t\t/*\n\t\t\t *   A                  C\n\t\t\t *   B                  A\n\t\t\t *   C <- sce    ==>    B\n\t\t\t *   D                  D\n\t\t\t */\n\t\t\tduk_strcache_entry tmp;\n\n\t\t\ttmp = *sce;\n\t\t\tduk_memmove((void *) (&heap->strcache[1]),\n\t\t\t            (const void *) (&heap->strcache[0]),\n\t\t\t            (size_t) (((char *) sce) - ((char *) &heap->strcache[0])));\n\t\t\theap->strcache[0] = tmp;\n\n\t\t\t/* 'sce' points to the wrong entry here, but is no longer used */\n\t\t}\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t\tDUK_DDD(DUK_DDDPRINT(\"stringcache after char2byte (using cache):\"));\n\t\tfor (i = 0; i < DUK_HEAP_STRCACHE_SIZE; i++) {\n\t\t\tduk_strcache_entry *c = heap->strcache + i;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"  [%ld] -> h=%p, cidx=%ld, bidx=%ld\",\n\t\t\t                     (long) i, (void *) c->h, (long) c->cidx, (long) c->bidx));\n\t\t}\n#endif\n\t}\n\n\treturn byte_offset;\n\n scan_error:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_heap_stringtable.c",
    "content": "/*\n *  Heap string table handling, string interning.\n */\n\n#include \"duk_internal.h\"\n\n/* Resize checks not needed if minsize == maxsize, typical for low memory\n * targets.\n */\n#define DUK__STRTAB_RESIZE_CHECK\n#if (DUK_USE_STRTAB_MINSIZE == DUK_USE_STRTAB_MAXSIZE)\n#undef DUK__STRTAB_RESIZE_CHECK\n#endif\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n#define DUK__HEAPPTR_ENC16(heap,ptr)    DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (ptr))\n#define DUK__HEAPPTR_DEC16(heap,val)    DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (val))\n#define DUK__GET_STRTABLE(heap)         ((heap)->strtable16)\n#else\n#define DUK__HEAPPTR_ENC16(heap,ptr)    (ptr)\n#define DUK__HEAPPTR_DEC16(heap,val)    (val)\n#define DUK__GET_STRTABLE(heap)         ((heap)->strtable)\n#endif\n\n#define DUK__STRTAB_U32_MAX_STRLEN      10               /* 4'294'967'295 */\n\n/*\n *  Debug dump stringtable.\n */\n\n#if defined(DUK_USE_DEBUG)\nDUK_INTERNAL void duk_heap_strtable_dump(duk_heap *heap) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable;\n#else\n\tduk_hstring **strtable;\n#endif\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_size_t count_total = 0;\n\tduk_size_t count_chain;\n\tduk_size_t count_chain_min = DUK_SIZE_MAX;\n\tduk_size_t count_chain_max = 0;\n\tduk_size_t count_len[8];  /* chain lengths from 0 to 7 */\n\n\tif (heap == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"string table, heap=NULL\"));\n\t\treturn;\n\t}\n\n\tstrtable = DUK__GET_STRTABLE(heap);\n\tif (strtable == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"string table, strtab=NULL\"));\n\t\treturn;\n\t}\n\n\tduk_memzero((void *) count_len, sizeof(count_len));\n\tfor (i = 0; i < heap->st_size; i++) {\n\t\th = DUK__HEAPPTR_DEC16(heap, strtable[i]);\n\t\tcount_chain = 0;\n\t\twhile (h != NULL) {\n\t\t\tcount_chain++;\n\t\t\th = h->hdr.h_next;\n\t\t}\n\t\tif (count_chain < sizeof(count_len) / sizeof(duk_size_t)) {\n\t\t\tcount_len[count_chain]++;\n\t\t}\n\t\tcount_chain_max = (count_chain > count_chain_max ? count_chain : count_chain_max);\n\t\tcount_chain_min = (count_chain < count_chain_min ? count_chain : count_chain_min);\n\t\tcount_total += count_chain;\n\t}\n\n\tDUK_D(DUK_DPRINT(\"string table, strtab=%p, count=%lu, chain min=%lu max=%lu avg=%lf: \"\n\t                 \"counts: %lu %lu %lu %lu %lu %lu %lu %lu ...\",\n\t                 (void *) heap->strtable, (unsigned long) count_total,\n\t                 (unsigned long) count_chain_min, (unsigned long) count_chain_max,\n\t                 (double) count_total / (double) heap->st_size,\n\t                 (unsigned long) count_len[0], (unsigned long) count_len[1],\n\t                 (unsigned long) count_len[2], (unsigned long) count_len[3],\n\t                 (unsigned long) count_len[4], (unsigned long) count_len[5],\n\t                 (unsigned long) count_len[6], (unsigned long) count_len[7]));\n}\n#endif  /* DUK_USE_DEBUG */\n\n/*\n *  Assertion helper to ensure strtable is populated correctly.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_LOCAL void duk__strtable_assert_checks(duk_heap *heap) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable;\n#else\n\tduk_hstring **strtable;\n#endif\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_size_t count = 0;\n\n\tDUK_ASSERT(heap != NULL);\n\n\tstrtable = DUK__GET_STRTABLE(heap);\n\tif (strtable != NULL) {\n\t\tDUK_ASSERT(heap->st_size != 0);\n\t\tDUK_ASSERT(heap->st_mask == heap->st_size - 1);\n\n\t\tfor (i = 0; i < heap->st_size; i++) {\n\t\t\th = DUK__HEAPPTR_DEC16(heap, strtable[i]);\n\t\t\twhile (h != NULL) {\n\t\t\t\tDUK_ASSERT((DUK_HSTRING_GET_HASH(h) & heap->st_mask) == i);\n\t\t\t\tcount++;\n\t\t\t\th = h->hdr.h_next;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_ASSERT(heap->st_size == 0);\n\t\tDUK_ASSERT(heap->st_mask == 0);\n\t}\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tDUK_ASSERT(count == (duk_size_t) heap->st_count);\n#endif\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\n/*\n *  Allocate and initialize a duk_hstring.\n *\n *  Returns a NULL if allocation or initialization fails for some reason.\n *\n *  The string won't be inserted into the string table and isn't tracked in\n *  any way (link pointers will be NULL).  The caller must place the string\n *  into the string table without any risk of a longjmp, otherwise the string\n *  is leaked.\n */\n\nDUK_LOCAL duk_hstring *duk__strtable_alloc_hstring(duk_heap *heap,\n                                                   const duk_uint8_t *str,\n                                                   duk_uint32_t blen,\n                                                   duk_uint32_t strhash,\n                                                   const duk_uint8_t *extdata) {\n\tduk_hstring *res;\n\tconst duk_uint8_t *data;\n#if !defined(DUK_USE_HSTRING_ARRIDX)\n\tduk_uarridx_t dummy;\n#endif\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_UNREF(extdata);\n\n#if defined(DUK_USE_STRLEN16)\n\t/* If blen <= 0xffffUL, clen is also guaranteed to be <= 0xffffUL. */\n\tif (blen > 0xffffUL) {\n\t\tDUK_D(DUK_DPRINT(\"16-bit string blen/clen active and blen over 16 bits, reject intern\"));\n\t\tgoto alloc_error;\n\t}\n#endif\n\n\t/* XXX: Memzeroing the allocated structure is not really necessary\n\t * because we could just initialize all fields explicitly (almost\n\t * all fields are initialized explicitly anyway).\n\t */\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK)\n\tif (extdata) {\n\t\tres = (duk_hstring *) DUK_ALLOC(heap, sizeof(duk_hstring_external));\n\t\tif (DUK_UNLIKELY(res == NULL)) {\n\t\t\tgoto alloc_error;\n\t\t}\n\t\tduk_memzero(res, sizeof(duk_hstring_external));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\tDUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr);\n#endif\n\t\tDUK_HEAPHDR_SET_TYPE_AND_FLAGS(&res->hdr, DUK_HTYPE_STRING, DUK_HSTRING_FLAG_EXTDATA);\n\n\t\tDUK_ASSERT(extdata[blen] == 0);  /* Application responsibility. */\n\t\tdata = extdata;\n\t\t((duk_hstring_external *) res)->extdata = extdata;\n\t} else\n#endif  /* DUK_USE_HSTRING_EXTDATA && DUK_USE_EXTSTR_INTERN_CHECK */\n\t{\n\t\tduk_uint8_t *data_tmp;\n\n\t\t/* NUL terminate for convenient C access */\n\t\tDUK_ASSERT(sizeof(duk_hstring) + blen + 1 > blen);  /* No wrap, limits ensure. */\n\t\tres = (duk_hstring *) DUK_ALLOC(heap, sizeof(duk_hstring) + blen + 1);\n\t\tif (DUK_UNLIKELY(res == NULL)) {\n\t\t\tgoto alloc_error;\n\t\t}\n\t\tduk_memzero(res, sizeof(duk_hstring));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\tDUK_HEAPHDR_STRING_INIT_NULLS(&res->hdr);\n#endif\n\t\tDUK_HEAPHDR_SET_TYPE_AND_FLAGS(&res->hdr, DUK_HTYPE_STRING, 0);\n\n\t\tdata_tmp = (duk_uint8_t *) (res + 1);\n\t\tduk_memcpy(data_tmp, str, blen);\n\t\tdata_tmp[blen] = (duk_uint8_t) 0;\n\t\tdata = (const duk_uint8_t *) data_tmp;\n\t}\n\n\tDUK_HSTRING_SET_BYTELEN(res, blen);\n\tDUK_HSTRING_SET_HASH(res, strhash);\n\n\tDUK_ASSERT(!DUK_HSTRING_HAS_ARRIDX(res));\n#if defined(DUK_USE_HSTRING_ARRIDX)\n\tres->arridx = duk_js_to_arrayindex_string(data, blen);\n\tif (res->arridx != DUK_HSTRING_NO_ARRAY_INDEX) {\n#else\n\tdummy = duk_js_to_arrayindex_string(data, blen);\n\tif (dummy != DUK_HSTRING_NO_ARRAY_INDEX) {\n#endif\n\t\t/* Array index strings cannot be symbol strings,\n\t\t * and they're always pure ASCII so blen == clen.\n\t\t */\n\t\tDUK_HSTRING_SET_ARRIDX(res);\n\t\tDUK_HSTRING_SET_ASCII(res);\n\t\tDUK_ASSERT(duk_unicode_unvalidated_utf8_length(data, (duk_size_t) blen) == blen);\n\t} else {\n\t\t/* Because 'data' is NUL-terminated, we don't need a\n\t\t * blen > 0 check here.  For NUL (0x00) the symbol\n\t\t * checks will be false.\n\t\t */\n\t\tif (DUK_UNLIKELY(data[0] >= 0x80U)) {\n\t\t\tif (data[0] <= 0x81) {\n\t\t\t\tDUK_HSTRING_SET_SYMBOL(res);\n\t\t\t} else if (data[0] == 0x82U || data[0] == 0xffU) {\n\t\t\t\tDUK_HSTRING_SET_HIDDEN(res);\n\t\t\t\tDUK_HSTRING_SET_SYMBOL(res);\n\t\t\t}\n\t\t}\n\n\t\t/* Using an explicit 'ASCII' flag has larger footprint (one call site\n\t\t * only) but is quite useful for the case when there's no explicit\n\t\t * 'clen' in duk_hstring.\n\t\t *\n\t\t * The flag is set lazily for RAM strings.\n\t\t */\n\t\tDUK_ASSERT(!DUK_HSTRING_HAS_ASCII(res));\n\n#if defined(DUK_USE_HSTRING_LAZY_CLEN)\n\t\t/* Charlen initialized to 0, updated on-the-fly. */\n#else\n\t\tduk_hstring_init_charlen(res);  /* Also sets ASCII flag. */\n#endif\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"interned string, hash=0x%08lx, blen=%ld, has_arridx=%ld, has_extdata=%ld\",\n\t                     (unsigned long) DUK_HSTRING_GET_HASH(res),\n\t                     (long) DUK_HSTRING_GET_BYTELEN(res),\n\t                     (long) (DUK_HSTRING_HAS_ARRIDX(res) ? 1 : 0),\n\t                     (long) (DUK_HSTRING_HAS_EXTDATA(res) ? 1 : 0)));\n\n\tDUK_ASSERT(res != NULL);\n\treturn res;\n\n alloc_error:\n\treturn NULL;\n}\n\n/*\n *  Grow strtable allocation in-place.\n */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL void duk__strtable_grow_inplace(duk_heap *heap) {\n\tduk_uint32_t new_st_size;\n\tduk_uint32_t old_st_size;\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_hstring *next;\n\tduk_hstring *prev;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *new_ptr;\n\tduk_uint16_t *new_ptr_high;\n#else\n\tduk_hstring **new_ptr;\n\tduk_hstring **new_ptr_high;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"grow in-place: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size * 2));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->st_resizing == 1);\n\tDUK_ASSERT(heap->st_size >= 2);\n\tDUK_ASSERT((heap->st_size & (heap->st_size - 1)) == 0);  /* 2^N */\n\tDUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL);\n\n\tDUK_STATS_INC(heap, stats_strtab_resize_grow);\n\n\tnew_st_size = heap->st_size << 1U;\n\tDUK_ASSERT(new_st_size > heap->st_size);  /* No overflow. */\n\n\t/* Reallocate the strtable first and then work in-place to rehash\n\t * strings.  We don't need an indirect allocation here: even if GC\n\t * is triggered to satisfy the allocation, recursive strtable resize\n\t * is prevented by flags.  This is also why we don't need to use\n\t * DUK_REALLOC_INDIRECT().\n\t */\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tnew_ptr = (duk_uint16_t *) DUK_REALLOC(heap, heap->strtable16, sizeof(duk_uint16_t) * new_st_size);\n#else\n\tnew_ptr = (duk_hstring **) DUK_REALLOC(heap, heap->strtable, sizeof(duk_hstring *) * new_st_size);\n#endif\n\tif (DUK_UNLIKELY(new_ptr == NULL)) {\n\t\t/* If realloc fails we can continue normally: the string table\n\t\t * won't \"fill up\" although chains will gradually get longer.\n\t\t * When string insertions continue, we'll quite soon try again\n\t\t * with no special handling.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"string table grow failed, ignoring\"));\n\t\treturn;\n\t}\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\theap->strtable16 = new_ptr;\n#else\n\theap->strtable = new_ptr;\n#endif\n\n\t/* Rehash a single bucket into two separate ones.  When we grow\n\t * by x2 the highest 'new' bit determines whether a string remains\n\t * in its old position (bit is 0) or goes to a new one (bit is 1).\n\t */\n\n\told_st_size = heap->st_size;\n\tnew_ptr_high = new_ptr + old_st_size;\n\tfor (i = 0; i < old_st_size; i++) {\n\t\tduk_hstring *new_root;\n\t\tduk_hstring *new_root_high;\n\n\t\th = DUK__HEAPPTR_DEC16(heap, new_ptr[i]);\n\t\tnew_root = h;\n\t\tnew_root_high = NULL;\n\n\t\tprev = NULL;\n\t\twhile (h != NULL) {\n\t\t\tduk_uint32_t mask;\n\n\t\t\tDUK_ASSERT((DUK_HSTRING_GET_HASH(h) & heap->st_mask) == i);\n\t\t\tnext = h->hdr.h_next;\n\n\t\t\t/* Example: if previous size was 256, previous mask is 0xFF\n\t\t\t * and size is 0x100 which corresponds to the new bit that\n\t\t\t * comes into play.\n\t\t\t */\n\t\t\tDUK_ASSERT(heap->st_mask == old_st_size - 1);\n\t\t\tmask = old_st_size;\n\t\t\tif (DUK_HSTRING_GET_HASH(h) & mask) {\n\t\t\t\tif (prev != NULL) {\n\t\t\t\t\tprev->hdr.h_next = h->hdr.h_next;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_ASSERT(h == new_root);\n\t\t\t\t\tnew_root = h->hdr.h_next;\n\t\t\t\t}\n\n\t\t\t\th->hdr.h_next = new_root_high;\n\t\t\t\tnew_root_high = h;\n\t\t\t} else {\n\t\t\t\tprev = h;\n\t\t\t}\n\t\t\th = next;\n\t\t}\n\n\t\tnew_ptr[i] = DUK__HEAPPTR_ENC16(heap, new_root);\n\t\tnew_ptr_high[i] = DUK__HEAPPTR_ENC16(heap, new_root_high);\n\t}\n\n\theap->st_size = new_st_size;\n\theap->st_mask = new_st_size - 1;\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__strtable_assert_checks(heap);\n#endif\n}\n#endif  /* DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Shrink strtable allocation in-place.\n */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL void duk__strtable_shrink_inplace(duk_heap *heap) {\n\tduk_uint32_t new_st_size;\n\tduk_uint32_t i;\n\tduk_hstring *h;\n\tduk_hstring *other;\n\tduk_hstring *root;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *old_ptr;\n\tduk_uint16_t *old_ptr_high;\n\tduk_uint16_t *new_ptr;\n#else\n\tduk_hstring **old_ptr;\n\tduk_hstring **old_ptr_high;\n\tduk_hstring **new_ptr;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"shrink in-place: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size / 2));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(heap->st_resizing == 1);\n\tDUK_ASSERT(heap->st_size >= 2);\n\tDUK_ASSERT((heap->st_size & (heap->st_size - 1)) == 0);  /* 2^N */\n\tDUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL);\n\n\tDUK_STATS_INC(heap, stats_strtab_resize_shrink);\n\n\tnew_st_size = heap->st_size >> 1U;\n\n\t/* Combine two buckets into a single one.  When we shrink, one hash\n\t * bit (highest) disappears.\n\t */\n\told_ptr = DUK__GET_STRTABLE(heap);\n\told_ptr_high = old_ptr + new_st_size;\n\tfor (i = 0; i < new_st_size; i++) {\n\t\th = DUK__HEAPPTR_DEC16(heap, old_ptr[i]);\n\t\tother = DUK__HEAPPTR_DEC16(heap, old_ptr_high[i]);\n\n\t\tif (h == NULL) {\n\t\t\t/* First chain is empty, so use second one as is. */\n\t\t\troot = other;\n\t\t} else {\n\t\t\t/* Find end of first chain, and link in the second. */\n\t\t\troot = h;\n\t\t\twhile (h->hdr.h_next != NULL) {\n\t\t\t\th = h->hdr.h_next;\n\t\t\t}\n\t\t\th->hdr.h_next = other;\n\t\t}\n\n\t\told_ptr[i] = DUK__HEAPPTR_ENC16(heap, root);\n\t}\n\n\theap->st_size = new_st_size;\n\theap->st_mask = new_st_size - 1;\n\n\t/* The strtable is now consistent and we can realloc safely.  Even\n\t * if side effects cause string interning or removal the strtable\n\t * updates are safe.  Recursive resize has been prevented by caller.\n\t * This is also why we don't need to use DUK_REALLOC_INDIRECT().\n\t *\n\t * We assume a realloc() to a smaller size is guaranteed to succeed.\n\t * It would be relatively straightforward to handle the error by\n\t * essentially performing a \"grow\" step to recover.\n\t */\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tnew_ptr = (duk_uint16_t *) DUK_REALLOC(heap, heap->strtable16, sizeof(duk_uint16_t) * new_st_size);\n\tDUK_ASSERT(new_ptr != NULL);\n\theap->strtable16 = new_ptr;\n#else\n\tnew_ptr = (duk_hstring **) DUK_REALLOC(heap, heap->strtable, sizeof(duk_hstring *) * new_st_size);\n\tDUK_ASSERT(new_ptr != NULL);\n\theap->strtable = new_ptr;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__strtable_assert_checks(heap);\n#endif\n}\n#endif  /* DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Grow/shrink check.\n */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL DUK_COLD DUK_NOINLINE void duk__strtable_resize_check(duk_heap *heap) {\n\tduk_uint32_t load_factor;  /* fixed point */\n\n\tDUK_ASSERT(heap != NULL);\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tDUK_ASSERT(heap->strtable16 != NULL);\n#else\n\tDUK_ASSERT(heap->strtable != NULL);\n#endif\n\n\tDUK_STATS_INC(heap, stats_strtab_resize_check);\n\n\t/* Prevent recursive resizing. */\n\tif (DUK_UNLIKELY(heap->st_resizing != 0U)) {\n\t\tDUK_D(DUK_DPRINT(\"prevent recursive strtable resize\"));\n\t\treturn;\n\t}\n\n\theap->st_resizing = 1;\n\n\tDUK_ASSERT(heap->st_size >= 16U);\n\tDUK_ASSERT((heap->st_size >> 4U) >= 1);\n\tload_factor = heap->st_count / (heap->st_size >> 4U);\n\n\tDUK_DD(DUK_DDPRINT(\"resize check string table: size=%lu, count=%lu, load_factor=%lu (fixed point .4; float %lf)\",\n\t                   (unsigned long) heap->st_size, (unsigned long) heap->st_count,\n\t                   (unsigned long) load_factor,\n\t                   (double) heap->st_count / (double) heap->st_size));\n\n\tif (load_factor >= DUK_USE_STRTAB_GROW_LIMIT) {\n\t\tif (heap->st_size >= DUK_USE_STRTAB_MAXSIZE) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"want to grow strtable (based on load factor) but already maximum size\"));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"grow string table: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size * 2));\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk_heap_strtable_dump(heap);\n#endif\n\t\t\tduk__strtable_grow_inplace(heap);\n\t\t}\n\t} else if (load_factor <= DUK_USE_STRTAB_SHRINK_LIMIT) {\n\t\tif (heap->st_size <= DUK_USE_STRTAB_MINSIZE) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"want to shrink strtable (based on load factor) but already minimum size\"));\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"shrink string table: %lu -> %lu\", (unsigned long) heap->st_size, (unsigned long) heap->st_size / 2));\n#if defined(DUK_USE_DEBUG)\n\t\t\tduk_heap_strtable_dump(heap);\n#endif\n\t\t\tduk__strtable_shrink_inplace(heap);\n\t\t}\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"no need for strtable resize\"));\n\t}\n\n\theap->st_resizing = 0;\n}\n#endif  /* DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Torture grow/shrink: unconditionally grow and shrink back.\n */\n\n#if defined(DUK_USE_STRTAB_TORTURE) && defined(DUK__STRTAB_RESIZE_CHECK)\nDUK_LOCAL void duk__strtable_resize_torture(duk_heap *heap) {\n\tduk_uint32_t old_st_size;\n\n\tDUK_ASSERT(heap != NULL);\n\n\told_st_size = heap->st_size;\n\tif (old_st_size >= DUK_USE_STRTAB_MAXSIZE) {\n\t\treturn;\n\t}\n\n\theap->st_resizing = 1;\n\tduk__strtable_grow_inplace(heap);\n\tif (heap->st_size > old_st_size) {\n\t\tduk__strtable_shrink_inplace(heap);\n\t}\n\theap->st_resizing = 0;\n}\n#endif  /* DUK_USE_STRTAB_TORTURE && DUK__STRTAB_RESIZE_CHECK */\n\n/*\n *  Raw intern; string already checked not to be present.\n */\n\nDUK_LOCAL duk_hstring *duk__strtable_do_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen, duk_uint32_t strhash) {\n\tduk_hstring *res;\n\tconst duk_uint8_t *extdata;\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *slot;\n#else\n\tduk_hstring **slot;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"do_intern: heap=%p, str=%p, blen=%lu, strhash=%lx, st_size=%lu, st_count=%lu, load=%lf\",\n\t                     (void *) heap, (const void *) str, (unsigned long) blen, (unsigned long) strhash,\n\t                     (unsigned long) heap->st_size, (unsigned long) heap->st_count,\n\t                     (double) heap->st_count / (double) heap->st_size));\n\n\tDUK_ASSERT(heap != NULL);\n\n\t/* Prevent any side effects on the string table and the caller provided\n\t * str/blen arguments while interning is in progress.  For example, if\n\t * the caller provided str/blen from a dynamic buffer, a finalizer\n\t * might resize or modify that dynamic buffer, invalidating the call\n\t * arguments.\n\t *\n\t * While finalizers must be prevented, mark-and-sweep itself is fine.\n\t * Recursive string table resize is prevented explicitly here.\n\t */\n\n\theap->pf_prevent_count++;\n\tDUK_ASSERT(heap->pf_prevent_count != 0);  /* Wrap. */\n\n#if defined(DUK_USE_STRTAB_TORTURE) && defined(DUK__STRTAB_RESIZE_CHECK)\n\tduk__strtable_resize_torture(heap);\n#endif\n\n\t/* String table grow/shrink check.  Because of chaining (and no\n\t * accumulation issues as with hash probe chains and DELETED\n\t * markers) there's never a mandatory need to resize right now.\n\t * Check for the resize only periodically, based on st_count\n\t * bit pattern.  Because string table removal doesn't do a shrink\n\t * check, we do that also here.\n\t *\n\t * Do the resize and possible grow/shrink before the new duk_hstring\n\t * has been allocated.  Otherwise we may trigger a GC when the result\n\t * duk_hstring is not yet strongly referenced.\n\t */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tif (DUK_UNLIKELY((heap->st_count & DUK_USE_STRTAB_RESIZE_CHECK_MASK) == 0)) {\n\t\tduk__strtable_resize_check(heap);\n\t}\n#endif\n\n\t/* External string check (low memory optimization). */\n\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK)\n\textdata = (const duk_uint8_t *) DUK_USE_EXTSTR_INTERN_CHECK(heap->heap_udata, (void *) DUK_LOSE_CONST(str), (duk_size_t) blen);\n#else\n\textdata = (const duk_uint8_t *) NULL;\n#endif\n\n\t/* Allocate and initialize string, not yet linked.  This may cause a\n\t * GC which may cause other strings to be interned and inserted into\n\t * the string table before we insert our string.  Finalizer execution\n\t * is disabled intentionally to avoid a finalizer from e.g. resizing\n\t * a buffer used as a data area for 'str'.\n\t */\n\n\tres = duk__strtable_alloc_hstring(heap, str, blen, strhash, extdata);\n\n\t/* Allow side effects again: GC must be avoided until duk_hstring\n\t * result (if successful) has been INCREF'd.\n\t */\n\tDUK_ASSERT(heap->pf_prevent_count > 0);\n\theap->pf_prevent_count--;\n\n\t/* Alloc error handling. */\n\n\tif (DUK_UNLIKELY(res == NULL)) {\n#if defined(DUK_USE_HSTRING_EXTDATA) && defined(DUK_USE_EXTSTR_INTERN_CHECK)\n\t\tif (extdata != NULL) {\n\t\t\tDUK_USE_EXTSTR_FREE(heap->heap_udata, (const void *) extdata);\n\t\t}\n#endif\n\t\treturn NULL;\n\t}\n\n\t/* Insert into string table. */\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tslot = heap->strtable16 + (strhash & heap->st_mask);\n#else\n\tslot = heap->strtable + (strhash & heap->st_mask);\n#endif\n\tDUK_ASSERT(res->hdr.h_next == NULL);  /* This is the case now, but unnecessary zeroing/NULLing. */\n\tres->hdr.h_next = DUK__HEAPPTR_DEC16(heap, *slot);\n\t*slot = DUK__HEAPPTR_ENC16(heap, res);\n\n\t/* Update string count only for successful inserts. */\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\theap->st_count++;\n#endif\n\n\t/* The duk_hstring is in the string table but is not yet strongly\n\t * reachable.  Calling code MUST NOT make any allocations or other\n\t * side effects before the duk_hstring has been INCREF'd and made\n\t * reachable.\n\t */\n\n\treturn res;\n}\n\n/*\n *  Intern a string from str/blen, returning either an existing duk_hstring\n *  or adding a new one into the string table.  The input string does -not-\n *  need to be NUL terminated.\n *\n *  The input 'str' argument may point to a Duktape managed data area such as\n *  the data area of a dynamic buffer.  It's crucial to avoid any side effects\n *  that might affect the data area (e.g. resize the dynamic buffer, or write\n *  to the buffer) before the string is fully interned.\n */\n\n#if defined(DUK_USE_ROM_STRINGS)\nDUK_LOCAL duk_hstring *duk__strtab_romstring_lookup(duk_heap *heap, const duk_uint8_t *str, duk_size_t blen, duk_uint32_t strhash) {\n\tduk_size_t lookup_hash;\n\tduk_hstring *curr;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_UNREF(heap);\n\n\tlookup_hash = (blen << 4);\n\tif (blen > 0) {\n\t\tlookup_hash += str[0];\n\t}\n\tlookup_hash &= 0xff;\n\n\tcurr = (duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_lookup[lookup_hash]);\n\twhile (curr != NULL) {\n\t\t/* Unsafe memcmp() because for zero blen, str may be NULL. */\n\t\tif (strhash == DUK_HSTRING_GET_HASH(curr) &&\n\t\t    blen == DUK_HSTRING_GET_BYTELEN(curr) &&\n\t\t    duk_memcmp_unsafe((const void *) str, (const void *) DUK_HSTRING_GET_DATA(curr), blen) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"intern check: rom string: %!O, computed hash 0x%08lx, rom hash 0x%08lx\",\n\t\t\t                     curr, (unsigned long) strhash, (unsigned long) DUK_HSTRING_GET_HASH(curr)));\n\t\t\treturn curr;\n\t\t}\n\t\tcurr = curr->hdr.h_next;\n\t}\n\n\treturn NULL;\n}\n#endif  /* DUK_USE_ROM_STRINGS */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uint32_t strhash;\n\tduk_hstring *h;\n\n\tDUK_DDD(DUK_DDDPRINT(\"intern check: heap=%p, str=%p, blen=%lu\", (void *) heap, (const void *) str, (unsigned long) blen));\n\n\t/* Preliminaries. */\n\n\t/* XXX: maybe just require 'str != NULL' even for zero size? */\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(blen == 0 || str != NULL);\n\tDUK_ASSERT(blen <= DUK_HSTRING_MAX_BYTELEN);  /* Caller is responsible for ensuring this. */\n\tstrhash = duk_heap_hashstring(heap, str, (duk_size_t) blen);\n\n\t/* String table lookup. */\n\n\tDUK_ASSERT(DUK__GET_STRTABLE(heap) != NULL);\n\tDUK_ASSERT(heap->st_size > 0);\n\tDUK_ASSERT(heap->st_size == heap->st_mask + 1);\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\th = DUK__HEAPPTR_DEC16(heap, heap->strtable16[strhash & heap->st_mask]);\n#else\n\th = heap->strtable[strhash & heap->st_mask];\n#endif\n\twhile (h != NULL) {\n\t\tif (DUK_HSTRING_GET_HASH(h) == strhash &&\n\t\t    DUK_HSTRING_GET_BYTELEN(h) == blen &&\n\t\t    duk_memcmp_unsafe((const void *) str, (const void *) DUK_HSTRING_GET_DATA(h), (size_t) blen) == 0) {\n\t\t\t/* Found existing entry. */\n\t\t\tDUK_STATS_INC(heap, stats_strtab_intern_hit);\n\t\t\treturn h;\n\t\t}\n\t\th = h->hdr.h_next;\n\t}\n\n\t/* ROM table lookup.  Because this lookup is slower, do it only after\n\t * RAM lookup.  This works because no ROM string is ever interned into\n\t * the RAM string table.\n\t */\n\n#if defined(DUK_USE_ROM_STRINGS)\n\th = duk__strtab_romstring_lookup(heap, str, blen, strhash);\n\tif (h != NULL) {\n\t\tDUK_STATS_INC(heap, stats_strtab_intern_hit);\n\t\treturn h;\n\t}\n#endif\n\n\t/* Not found in string table; insert. */\n\n\tDUK_STATS_INC(heap, stats_strtab_intern_miss);\n\th = duk__strtable_do_intern(heap, str, blen, strhash);\n\treturn h;  /* may be NULL */\n}\n\n/*\n *  Intern a string from u32.\n */\n\n/* XXX: Could arrange some special handling because we know that the result\n * will have an arridx flag and an ASCII flag, won't need a clen check, etc.\n */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_u32(duk_heap *heap, duk_uint32_t val) {\n\tduk_uint8_t buf[DUK__STRTAB_U32_MAX_STRLEN];\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT(heap != NULL);\n\n\t/* This is smaller and faster than a %lu sprintf. */\n\tp = buf + sizeof(buf);\n\tdo {\n\t\tp--;\n\t\t*p = duk_lc_digits[val % 10];\n\t\tval = val / 10;\n\t} while (val != 0);  /* For val == 0, emit exactly one '0'. */\n\tDUK_ASSERT(p >= buf);\n\n\treturn duk_heap_strtable_intern(heap, (const duk_uint8_t *) p, (duk_uint32_t) ((buf + sizeof(buf)) - p));\n}\n\n/*\n *  Checked convenience variants.\n *\n *  XXX: Because the main use case is for the checked variants, make them the\n *  main functionality and provide a safe variant separately (it is only needed\n *  during heap init).  The problem with that is that longjmp state and error\n *  creation must already be possible to throw.\n */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_hstring *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(blen == 0 || str != NULL);\n\n\tres = duk_heap_strtable_intern(thr->heap, str, blen);\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn res;\n}\n\n#if defined(DUK_USE_LITCACHE_SIZE)\nDUK_LOCAL duk_uint_t duk__strtable_litcache_key(const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uintptr_t key;\n\n\tDUK_ASSERT(DUK_USE_LITCACHE_SIZE > 0);\n\tDUK_ASSERT(DUK_IS_POWER_OF_TWO((duk_uint_t) DUK_USE_LITCACHE_SIZE));\n\n\tkey = (duk_uintptr_t) blen ^ (duk_uintptr_t) str;\n\tkey &= (duk_uintptr_t) (DUK_USE_LITCACHE_SIZE - 1);  /* Assumes size is power of 2. */\n\t/* Due to masking, cast is in 32-bit range. */\n\tDUK_ASSERT(key <= DUK_UINT_MAX);\n\treturn (duk_uint_t) key;\n}\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_literal_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uint_t key;\n\tduk_litcache_entry *ent;\n\tduk_hstring *h;\n\n\t/* Fast path check: literal exists in literal cache. */\n\tkey = duk__strtable_litcache_key(str, blen);\n\tent = thr->heap->litcache + key;\n\tif (ent->addr == str) {\n\t\tDUK_DD(DUK_DDPRINT(\"intern check for cached, pinned literal: str=%p, blen=%ld -> duk_hstring %!O\",\n\t\t                   (const void *) str, (long) blen, (duk_heaphdr *) ent->h));\n\t\tDUK_ASSERT(ent->h != NULL);\n\t\tDUK_ASSERT(DUK_HSTRING_HAS_PINNED_LITERAL(ent->h));\n\t\tDUK_STATS_INC(thr->heap, stats_strtab_litcache_hit);\n\t\treturn ent->h;\n\t}\n\n\t/* Intern and update (overwrite) cache entry. */\n\th = duk_heap_strtable_intern_checked(thr, str, blen);\n\tent->addr = str;\n\tent->h = h;\n\tDUK_STATS_INC(thr->heap, stats_strtab_litcache_miss);\n\n\t/* Pin the duk_hstring until the next mark-and-sweep.  This means\n\t * litcache entries don't need to be invalidated until the next\n\t * mark-and-sweep as their target duk_hstring is not freed before\n\t * the mark-and-sweep happens.  The pin remains even if the literal\n\t * cache entry is overwritten, and is still useful to avoid string\n\t * table traffic.\n\t */\n\tif (!DUK_HSTRING_HAS_PINNED_LITERAL(h)) {\n\t\tDUK_DD(DUK_DDPRINT(\"pin duk_hstring because it is a literal: %!O\", (duk_heaphdr *) h));\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h));\n\t\tDUK_HSTRING_INCREF(thr, h);\n\t\tDUK_HSTRING_SET_PINNED_LITERAL(h);\n\t\tDUK_STATS_INC(thr->heap, stats_strtab_litcache_pin);\n\t}\n\n\treturn h;\n}\n#endif  /* DUK_USE_LITCACHE_SIZE */\n\nDUK_INTERNAL duk_hstring *duk_heap_strtable_intern_u32_checked(duk_hthread *thr, duk_uint32_t val) {\n\tduk_hstring *res;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tres = duk_heap_strtable_intern_u32(thr->heap, val);\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn res;\n}\n\n/*\n *  Remove (unlink) a string from the string table.\n *\n *  Just unlinks the duk_hstring, leaving link pointers as garbage.\n *  Caller must free the string itself.\n */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n/* Unlink without a 'prev' pointer. */\nDUK_INTERNAL void duk_heap_strtable_unlink(duk_heap *heap, duk_hstring *h) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *slot;\n#else\n\tduk_hstring **slot;\n#endif\n\tduk_hstring *other;\n\tduk_hstring *prev;\n\n\tDUK_DDD(DUK_DDDPRINT(\"remove: heap=%p, h=%p, blen=%lu, strhash=%lx\",\n\t                     (void *) heap, (void *) h,\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_BYTELEN(h) : 0),\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_HASH(h) : 0)));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tDUK_ASSERT(heap->st_count > 0);\n\theap->st_count--;\n#endif\n\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tslot = heap->strtable16 + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#else\n\tslot = heap->strtable + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#endif\n\tother = DUK__HEAPPTR_DEC16(heap, *slot);\n\tDUK_ASSERT(other != NULL);  /* At least argument string is in the chain. */\n\n\tprev = NULL;\n\twhile (other != h) {\n\t\tprev = other;\n\t\tother = other->hdr.h_next;\n\t\tDUK_ASSERT(other != NULL);  /* We'll eventually find 'h'. */\n\t}\n\tif (prev != NULL) {\n\t\t/* Middle of list. */\n\t\tprev->hdr.h_next = h->hdr.h_next;\n\t} else {\n\t\t/* Head of list. */\n\t\t*slot = DUK__HEAPPTR_ENC16(heap, h->hdr.h_next);\n\t}\n\n\t/* There's no resize check on a string free.  The next string\n\t * intern will do one.\n\t */\n}\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/* Unlink with a 'prev' pointer. */\nDUK_INTERNAL void duk_heap_strtable_unlink_prev(duk_heap *heap, duk_hstring *h, duk_hstring *prev) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *slot;\n#else\n\tduk_hstring **slot;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"remove: heap=%p, prev=%p, h=%p, blen=%lu, strhash=%lx\",\n\t                     (void *) heap, (void *) prev, (void *) h,\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_BYTELEN(h) : 0),\n\t                     (unsigned long) (h != NULL ? DUK_HSTRING_GET_HASH(h) : 0)));\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(prev == NULL || prev->hdr.h_next == h);\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n\tDUK_ASSERT(heap->st_count > 0);\n\theap->st_count--;\n#endif\n\n\tif (prev != NULL) {\n\t\t/* Middle of list. */\n\t\tprev->hdr.h_next = h->hdr.h_next;\n\t} else {\n\t\t/* Head of list. */\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\tslot = heap->strtable16 + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#else\n\t\tslot = heap->strtable + (DUK_HSTRING_GET_HASH(h) & heap->st_mask);\n#endif\n\t\tDUK_ASSERT(DUK__HEAPPTR_DEC16(heap, *slot) == h);\n\t\t*slot = DUK__HEAPPTR_ENC16(heap, h->hdr.h_next);\n\t}\n}\n\n/*\n *  Force string table resize check in mark-and-sweep.\n */\n\nDUK_INTERNAL void duk_heap_strtable_force_resize(duk_heap *heap) {\n\t/* Does only one grow/shrink step if needed.  The heap->st_resizing\n\t * flag protects against recursive resizing.\n\t */\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_UNREF(heap);\n\n#if defined(DUK__STRTAB_RESIZE_CHECK)\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tif (heap->strtable16 != NULL) {\n#else\n\tif (heap->strtable != NULL) {\n#endif\n\t\tduk__strtable_resize_check(heap);\n\t}\n#endif\n}\n\n/*\n *  Free strings in the string table and the string table itself.\n */\n\nDUK_INTERNAL void duk_heap_strtable_free(duk_heap *heap) {\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\tduk_uint16_t *strtable;\n\tduk_uint16_t *st;\n#else\n\tduk_hstring **strtable;\n\tduk_hstring **st;\n#endif\n\tduk_hstring *h;\n\n\tDUK_ASSERT(heap != NULL);\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk__strtable_assert_checks(heap);\n#endif\n\n\t/* Strtable can be NULL if heap init fails.  However, in that case\n\t * heap->st_size is 0, so strtable == strtable_end and we skip the\n\t * loop without a special check.\n\t */\n\tstrtable = DUK__GET_STRTABLE(heap);\n\tst = strtable + heap->st_size;\n\tDUK_ASSERT(strtable != NULL || heap->st_size == 0);\n\n\twhile (strtable != st) {\n\t\t--st;\n\t\th = DUK__HEAPPTR_DEC16(heap, *st);\n\t\twhile (h) {\n\t\t\tduk_hstring *h_next;\n\t\t\th_next = h->hdr.h_next;\n\n\t\t\t/* Strings may have inner refs (extdata) in some cases. */\n\t\t\tduk_free_hstring(heap, h);\n\n\t\t\th = h_next;\n\t\t}\n\t}\n\n\tDUK_FREE(heap, strtable);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_heaphdr.h",
    "content": "/*\n *  Heap header definition and assorted macros, including ref counting.\n *  Access all fields through the accessor macros.\n */\n\n#if !defined(DUK_HEAPHDR_H_INCLUDED)\n#define DUK_HEAPHDR_H_INCLUDED\n\n/*\n *  Common heap header\n *\n *  All heap objects share the same flags and refcount fields.  Objects other\n *  than strings also need to have a single or double linked list pointers\n *  for insertion into the \"heap allocated\" list.  Strings have single linked\n *  list pointers for string table chaining.\n *\n *  Technically, 'h_refcount' must be wide enough to guarantee that it cannot\n *  wrap; otherwise objects might be freed incorrectly after wrapping.  The\n *  default refcount field is 32 bits even on 64-bit systems: while that's in\n *  theory incorrect, the Duktape heap needs to be larger than 64GB for the\n *  count to actually wrap (assuming 16-byte duk_tvals).  This is very unlikely\n *  to ever be an issue, but if it is, disabling DUK_USE_REFCOUNT32 causes\n *  Duktape to use size_t for refcounts which should always be safe.\n *\n *  Heap header size on 32-bit platforms: 8 bytes without reference counting,\n *  16 bytes with reference counting.\n *\n *  Note that 'raw' macros such as DUK_HEAPHDR_GET_REFCOUNT() are not\n *  defined without DUK_USE_REFERENCE_COUNTING, so caller must #if defined()\n *  around them.\n */\n\n/* XXX: macro for shared header fields (avoids some padding issues) */\n\nstruct duk_heaphdr {\n\tduk_uint32_t h_flags;\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#if defined(DUK_USE_ASSERTIONS)\n\t/* When assertions enabled, used by mark-and-sweep for refcount\n\t * validation.  Largest reasonable type; also detects overflows.\n\t */\n\tduk_size_t h_assert_refcount;\n#endif\n#if defined(DUK_USE_REFCOUNT16)\n\tduk_uint16_t h_refcount;\n#elif defined(DUK_USE_REFCOUNT32)\n\tduk_uint32_t h_refcount;\n#else\n\tduk_size_t h_refcount;\n#endif\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t h_next16;\n#else\n\tduk_heaphdr *h_next;\n#endif\n\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\t/* refcounting requires direct heap frees, which in turn requires a dual linked heap */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t h_prev16;\n#else\n\tduk_heaphdr *h_prev;\n#endif\n#endif\n\n\t/* When DUK_USE_HEAPPTR16 (and DUK_USE_REFCOUNT16) is in use, the\n\t * struct won't align nicely to 4 bytes.  This 16-bit extra field\n\t * is added to make the alignment clean; the field can be used by\n\t * heap objects when 16-bit packing is used.  This field is now\n\t * conditional to DUK_USE_HEAPPTR16 only, but it is intended to be\n\t * used with DUK_USE_REFCOUNT16 and DUK_USE_DOUBLE_LINKED_HEAP;\n\t * this only matter to low memory environments anyway.\n\t */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t h_extra16;\n#endif\n};\n\nstruct duk_heaphdr_string {\n\t/* 16 bits would be enough for shared heaphdr flags and duk_hstring\n\t * flags.  The initial parts of duk_heaphdr_string and duk_heaphdr\n\t * must match so changing the flags field size here would be quite\n\t * awkward.  However, to minimize struct size, we can pack at least\n\t * 16 bits of duk_hstring data into the flags field.\n\t */\n\tduk_uint32_t h_flags;\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#if defined(DUK_USE_ASSERTIONS)\n\t/* When assertions enabled, used by mark-and-sweep for refcount\n\t * validation.  Largest reasonable type; also detects overflows.\n\t */\n\tduk_size_t h_assert_refcount;\n#endif\n#if defined(DUK_USE_REFCOUNT16)\n\tduk_uint16_t h_refcount;\n\tduk_uint16_t h_strextra16;  /* round out to 8 bytes */\n#elif defined(DUK_USE_REFCOUNT32)\n\tduk_uint32_t h_refcount;\n#else\n\tduk_size_t h_refcount;\n#endif\n#else\n\tduk_uint16_t h_strextra16;\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n\tduk_hstring *h_next;\n\t/* No 'h_prev' pointer for strings. */\n};\n\n#define DUK_HEAPHDR_FLAGS_TYPE_MASK      0x00000003UL\n#define DUK_HEAPHDR_FLAGS_FLAG_MASK      (~DUK_HEAPHDR_FLAGS_TYPE_MASK)\n\n                                             /* 2 bits for heap type */\n#define DUK_HEAPHDR_FLAGS_HEAP_START     2   /* 5 heap flags */\n#define DUK_HEAPHDR_FLAGS_USER_START     7   /* 25 user flags */\n\n#define DUK_HEAPHDR_HEAP_FLAG_NUMBER(n)  (DUK_HEAPHDR_FLAGS_HEAP_START + (n))\n#define DUK_HEAPHDR_USER_FLAG_NUMBER(n)  (DUK_HEAPHDR_FLAGS_USER_START + (n))\n#define DUK_HEAPHDR_HEAP_FLAG(n)         (1UL << (DUK_HEAPHDR_FLAGS_HEAP_START + (n)))\n#define DUK_HEAPHDR_USER_FLAG(n)         (1UL << (DUK_HEAPHDR_FLAGS_USER_START + (n)))\n\n#define DUK_HEAPHDR_FLAG_REACHABLE       DUK_HEAPHDR_HEAP_FLAG(0)  /* mark-and-sweep: reachable */\n#define DUK_HEAPHDR_FLAG_TEMPROOT        DUK_HEAPHDR_HEAP_FLAG(1)  /* mark-and-sweep: children not processed */\n#define DUK_HEAPHDR_FLAG_FINALIZABLE     DUK_HEAPHDR_HEAP_FLAG(2)  /* mark-and-sweep: finalizable (on current pass) */\n#define DUK_HEAPHDR_FLAG_FINALIZED       DUK_HEAPHDR_HEAP_FLAG(3)  /* mark-and-sweep: finalized (on previous pass) */\n#define DUK_HEAPHDR_FLAG_READONLY        DUK_HEAPHDR_HEAP_FLAG(4)  /* read-only object, in code section */\n\n#define DUK_HTYPE_MIN                    0\n#define DUK_HTYPE_STRING                 0\n#define DUK_HTYPE_OBJECT                 1\n#define DUK_HTYPE_BUFFER                 2\n#define DUK_HTYPE_MAX                    2\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HEAPHDR_GET_NEXT(heap,h) \\\n\t((duk_heaphdr *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->h_next16))\n#define DUK_HEAPHDR_SET_NEXT(heap,h,val)   do { \\\n\t\t(h)->h_next16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) val); \\\n\t} while (0)\n#else\n#define DUK_HEAPHDR_GET_NEXT(heap,h)  ((h)->h_next)\n#define DUK_HEAPHDR_SET_NEXT(heap,h,val)   do { \\\n\t\t(h)->h_next = (val); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HEAPHDR_GET_PREV(heap,h) \\\n\t((duk_heaphdr *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->h_prev16))\n#define DUK_HEAPHDR_SET_PREV(heap,h,val)   do { \\\n\t\t(h)->h_prev16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (val)); \\\n\t} while (0)\n#else\n#define DUK_HEAPHDR_GET_PREV(heap,h)       ((h)->h_prev)\n#define DUK_HEAPHDR_SET_PREV(heap,h,val)   do { \\\n\t\t(h)->h_prev = (val); \\\n\t} while (0)\n#endif\n#endif\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#define DUK_HEAPHDR_GET_REFCOUNT(h)   ((h)->h_refcount)\n#define DUK_HEAPHDR_SET_REFCOUNT(h,val)  do { \\\n\t\t(h)->h_refcount = (val); \\\n\t\tDUK_ASSERT((h)->h_refcount == (val));  /* No truncation. */ \\\n\t} while (0)\n#define DUK_HEAPHDR_PREINC_REFCOUNT(h)  (++(h)->h_refcount)  /* result: updated refcount */\n#define DUK_HEAPHDR_PREDEC_REFCOUNT(h)  (--(h)->h_refcount)  /* result: updated refcount */\n#else\n/* refcount macros not defined without refcounting, caller must #if defined() now */\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/*\n *  Note: type is treated as a field separate from flags, so some masking is\n *  involved in the macros below.\n */\n\n#define DUK_HEAPHDR_GET_FLAGS_RAW(h)  ((h)->h_flags)\n#define DUK_HEAPHDR_SET_FLAGS_RAW(h,val)  do { \\\n\t\t(h)->h_flags = (val); } \\\n\t}\n#define DUK_HEAPHDR_GET_FLAGS(h)      ((h)->h_flags & DUK_HEAPHDR_FLAGS_FLAG_MASK)\n#define DUK_HEAPHDR_SET_FLAGS(h,val)  do { \\\n\t\t(h)->h_flags = ((h)->h_flags & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) | (val); \\\n\t} while (0)\n#define DUK_HEAPHDR_GET_TYPE(h)       ((h)->h_flags & DUK_HEAPHDR_FLAGS_TYPE_MASK)\n#define DUK_HEAPHDR_SET_TYPE(h,val)   do { \\\n\t\t(h)->h_flags = ((h)->h_flags & ~(DUK_HEAPHDR_FLAGS_TYPE_MASK)) | (val); \\\n\t} while (0)\n\n/* Comparison for type >= DUK_HTYPE_MIN skipped; because DUK_HTYPE_MIN is zero\n * and the comparison is unsigned, it's always true and generates warnings.\n */\n#define DUK_HEAPHDR_HTYPE_VALID(h)    ( \\\n\tDUK_HEAPHDR_GET_TYPE((h)) <= DUK_HTYPE_MAX \\\n\t)\n\n#define DUK_HEAPHDR_SET_TYPE_AND_FLAGS(h,tval,fval)  do { \\\n\t\t(h)->h_flags = ((tval) & DUK_HEAPHDR_FLAGS_TYPE_MASK) | \\\n\t\t               ((fval) & DUK_HEAPHDR_FLAGS_FLAG_MASK); \\\n\t} while (0)\n\n#define DUK_HEAPHDR_SET_FLAG_BITS(h,bits)  do { \\\n\t\tDUK_ASSERT(((bits) & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) == 0); \\\n\t\t(h)->h_flags |= (bits); \\\n\t} while (0)\n\n#define DUK_HEAPHDR_CLEAR_FLAG_BITS(h,bits)  do { \\\n\t\tDUK_ASSERT(((bits) & ~(DUK_HEAPHDR_FLAGS_FLAG_MASK)) == 0); \\\n\t\t(h)->h_flags &= ~((bits)); \\\n\t} while (0)\n\n#define DUK_HEAPHDR_CHECK_FLAG_BITS(h,bits)  (((h)->h_flags & (bits)) != 0)\n\n#define DUK_HEAPHDR_SET_REACHABLE(h)      DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_REACHABLE)\n#define DUK_HEAPHDR_CLEAR_REACHABLE(h)    DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_REACHABLE)\n#define DUK_HEAPHDR_HAS_REACHABLE(h)      DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_REACHABLE)\n\n#define DUK_HEAPHDR_SET_TEMPROOT(h)       DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_TEMPROOT)\n#define DUK_HEAPHDR_CLEAR_TEMPROOT(h)     DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_TEMPROOT)\n#define DUK_HEAPHDR_HAS_TEMPROOT(h)       DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_TEMPROOT)\n\n#define DUK_HEAPHDR_SET_FINALIZABLE(h)    DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZABLE)\n#define DUK_HEAPHDR_CLEAR_FINALIZABLE(h)  DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZABLE)\n#define DUK_HEAPHDR_HAS_FINALIZABLE(h)    DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZABLE)\n\n#define DUK_HEAPHDR_SET_FINALIZED(h)      DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZED)\n#define DUK_HEAPHDR_CLEAR_FINALIZED(h)    DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZED)\n#define DUK_HEAPHDR_HAS_FINALIZED(h)      DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_FINALIZED)\n\n#define DUK_HEAPHDR_SET_READONLY(h)       DUK_HEAPHDR_SET_FLAG_BITS((h),DUK_HEAPHDR_FLAG_READONLY)\n#define DUK_HEAPHDR_CLEAR_READONLY(h)     DUK_HEAPHDR_CLEAR_FLAG_BITS((h),DUK_HEAPHDR_FLAG_READONLY)\n#define DUK_HEAPHDR_HAS_READONLY(h)       DUK_HEAPHDR_CHECK_FLAG_BITS((h),DUK_HEAPHDR_FLAG_READONLY)\n\n/* get or set a range of flags; m=first bit number, n=number of bits */\n#define DUK_HEAPHDR_GET_FLAG_RANGE(h,m,n)  (((h)->h_flags >> (m)) & ((1UL << (n)) - 1UL))\n\n#define DUK_HEAPHDR_SET_FLAG_RANGE(h,m,n,v)  do { \\\n\t\t(h)->h_flags = \\\n\t\t\t((h)->h_flags & (~(((1UL << (n)) - 1UL) << (m)))) \\\n\t\t\t| ((v) << (m)); \\\n\t} while (0)\n\n/* init pointer fields to null */\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n#define DUK_HEAPHDR_INIT_NULLS(h)       do { \\\n\t\tDUK_HEAPHDR_SET_NEXT((h), (void *) NULL); \\\n\t\tDUK_HEAPHDR_SET_PREV((h), (void *) NULL); \\\n\t} while (0)\n#else\n#define DUK_HEAPHDR_INIT_NULLS(h)       do { \\\n\t\tDUK_HEAPHDR_SET_NEXT((h), (void *) NULL); \\\n\t} while (0)\n#endif\n\n#define DUK_HEAPHDR_STRING_INIT_NULLS(h)  do { \\\n\t\t(h)->h_next = NULL; \\\n\t} while (0)\n\n/*\n *  Type tests\n */\n\n/* Take advantage of the fact that for DUK_HTYPE_xxx numbers the lowest bit\n * is only set for DUK_HTYPE_OBJECT (= 1).\n */\n#if 0\n#define DUK_HEAPHDR_IS_OBJECT(h) (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_OBJECT)\n#endif\n#define DUK_HEAPHDR_IS_OBJECT(h) ((h)->h_flags & 0x01UL)\n#define DUK_HEAPHDR_IS_STRING(h) (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_STRING)\n#define DUK_HEAPHDR_IS_BUFFER(h) (DUK_HEAPHDR_GET_TYPE((h)) == DUK_HTYPE_BUFFER)\n\n/*\n *  Assert helpers\n */\n\n/* Check that prev/next links are consistent: if e.g. h->prev is != NULL,\n * h->prev->next should point back to h.\n */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_heaphdr_assert_valid_subclassed(duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_assert_valid(duk_heaphdr *h);\n#define DUK_HEAPHDR_ASSERT_LINKS(heap,h)  do { duk_heaphdr_assert_links((heap), (h)); } while (0)\n#define DUK_HEAPHDR_ASSERT_VALID(h)  do { duk_heaphdr_assert_valid((h)); } while (0)\n#else\n#define DUK_HEAPHDR_ASSERT_LINKS(heap,h)  do {} while (0)\n#define DUK_HEAPHDR_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n#endif  /* DUK_HEAPHDR_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_heaphdr_assert.c",
    "content": "/*\n *  duk_heaphdr assertion helpers\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_ASSERTIONS)\n\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\nDUK_INTERNAL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tif (h != NULL) {\n\t\tduk_heaphdr *h_prev, *h_next;\n\t\th_prev = DUK_HEAPHDR_GET_PREV(heap, h);\n\t\th_next = DUK_HEAPHDR_GET_NEXT(heap, h);\n\t\tDUK_ASSERT(h_prev == NULL || (DUK_HEAPHDR_GET_NEXT(heap, h_prev) == h));\n\t\tDUK_ASSERT(h_next == NULL || (DUK_HEAPHDR_GET_PREV(heap, h_next) == h));\n\t}\n}\n#else\nDUK_INTERNAL void duk_heaphdr_assert_links(duk_heap *heap, duk_heaphdr *h) {\n\tDUK_UNREF(heap);\n\tDUK_UNREF(h);\n}\n#endif\n\nDUK_INTERNAL void duk_heaphdr_assert_valid(duk_heaphdr *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(h));\n}\n\n/* Assert validity of a heaphdr, including all subclasses. */\nDUK_INTERNAL void duk_heaphdr_assert_valid_subclassed(duk_heaphdr *h) {\n\tswitch (DUK_HEAPHDR_GET_TYPE(h)) {\n\tcase DUK_HTYPE_OBJECT: {\n\t\tduk_hobject *h_obj = (duk_hobject *) h;\n\t\tDUK_HOBJECT_ASSERT_VALID(h_obj);\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(h_obj)) {\n\t\t\tDUK_HCOMPFUNC_ASSERT_VALID((duk_hcompfunc *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h_obj)) {\n\t\t\tDUK_HNATFUNC_ASSERT_VALID((duk_hnatfunc *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_DECENV(h_obj)) {\n\t\t\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_OBJENV(h_obj)) {\n\t\t\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_BUFOBJ(h_obj)) {\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t\tDUK_HBUFOBJ_ASSERT_VALID((duk_hbufobj *) h_obj);\n#endif\n\t\t} else if (DUK_HOBJECT_IS_BOUNDFUNC(h_obj)) {\n\t\t\tDUK_HBOUNDFUNC_ASSERT_VALID((duk_hboundfunc *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_PROXY(h_obj)) {\n\t\t\tDUK_HPROXY_ASSERT_VALID((duk_hproxy *) h_obj);\n\t\t} else if (DUK_HOBJECT_IS_THREAD(h_obj)) {\n\t\t\tDUK_HTHREAD_ASSERT_VALID((duk_hthread *) h_obj);\n\t\t} else {\n\t\t\t/* Just a plain object. */\n\t\t\t;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_STRING: {\n\t\tduk_hstring *h_str = (duk_hstring *) h;\n\t\tDUK_HSTRING_ASSERT_VALID(h_str);\n\t\tbreak;\n\t}\n\tcase DUK_HTYPE_BUFFER: {\n\t\tduk_hbuffer *h_buf = (duk_hbuffer *) h;\n\t\tDUK_HBUFFER_ASSERT_VALID(h_buf);\n\t\tbreak;\n\t}\n\tdefault: {\n\t\tDUK_ASSERT(0);\n\t}\n\t}\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_henv.h",
    "content": "/*\n *  Environment object representation.\n */\n\n#if !defined(DUK_HENV_H_INCLUDED)\n#define DUK_HENV_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hdecenv_assert_valid(duk_hdecenv *h);\nDUK_INTERNAL_DECL void duk_hobjenv_assert_valid(duk_hobjenv *h);\n#define DUK_HDECENV_ASSERT_VALID(h)  do { duk_hdecenv_assert_valid((h)); } while (0)\n#define DUK_HOBJENV_ASSERT_VALID(h)  do { duk_hobjenv_assert_valid((h)); } while (0)\n#else\n#define DUK_HDECENV_ASSERT_VALID(h)  do {} while (0)\n#define DUK_HOBJENV_ASSERT_VALID(h)  do {} while (0)\n#endif\n\nstruct duk_hdecenv {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* These control variables provide enough information to access live\n\t * variables for a closure that is still open.  If thread == NULL,\n\t * the record is closed and the identifiers are in the property table.\n\t */\n\tduk_hthread *thread;\n\tduk_hobject *varmap;\n\tduk_size_t regbase_byteoff;\n};\n\nstruct duk_hobjenv {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Target object and 'this' binding for object binding. */\n\tduk_hobject *target;\n\n\t/* The 'target' object is used as a this binding in only some object\n\t * environments.  For example, the global environment does not provide\n\t * a this binding, but a with statement does.\n\t */\n\tduk_bool_t has_this;\n};\n\n#endif  /* DUK_HENV_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hnatfunc.h",
    "content": "/*\n *  Heap native function representation.\n */\n\n#if !defined(DUK_HNATFUNC_H_INCLUDED)\n#define DUK_HNATFUNC_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hnatfunc_assert_valid(duk_hnatfunc *h);\n#define DUK_HNATFUNC_ASSERT_VALID(h)  do { duk_hnatfunc_assert_valid((h)); } while (0)\n#else\n#define DUK_HNATFUNC_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n#define DUK_HNATFUNC_NARGS_VARARGS  ((duk_int16_t) -1)\n#define DUK_HNATFUNC_NARGS_MAX      ((duk_int16_t) 0x7fff)\n\nstruct duk_hnatfunc {\n\t/* shared object part */\n\tduk_hobject obj;\n\n\tduk_c_function func;\n\tduk_int16_t nargs;\n\tduk_int16_t magic;\n\n\t/* The 'magic' field allows an opaque 16-bit field to be accessed by the\n\t * Duktape/C function.  This allows, for instance, the same native function\n\t * to be used for a set of very similar functions, with the 'magic' field\n\t * providing the necessary non-argument flags / values to guide the behavior\n\t * of the native function.  The value is signed on purpose: it is easier to\n\t * convert a signed value to unsigned (simply AND with 0xffff) than vice\n\t * versa.\n\t *\n\t * Note: cannot place nargs/magic into the heaphdr flags, because\n\t * duk_hobject takes almost all flags already.\n\t */\n};\n\n#endif  /* DUK_HNATFUNC_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hobject.h",
    "content": "/*\n *  Heap object representation.\n *\n *  Heap objects are used for ECMAScript objects, arrays, and functions,\n *  but also for internal control like declarative and object environment\n *  records.  Compiled functions, native functions, and threads are also\n *  objects but with an extended C struct.\n *\n *  Objects provide the required ECMAScript semantics and exotic behaviors\n *  especially for property access.\n *\n *  Properties are stored in three conceptual parts:\n *\n *    1. A linear 'entry part' contains ordered key-value-attributes triples\n *       and is the main method of string properties.\n *\n *    2. An optional linear 'array part' is used for array objects to store a\n *       (dense) range of [0,N[ array indexed entries with default attributes\n *       (writable, enumerable, configurable).  If the array part would become\n *       sparse or non-default attributes are required, the array part is\n *       abandoned and moved to the 'entry part'.\n *\n *    3. An optional 'hash part' is used to optimize lookups of the entry\n *       part; it is used only for objects with sufficiently many properties\n *       and can be abandoned without loss of information.\n *\n *  These three conceptual parts are stored in a single memory allocated area.\n *  This minimizes memory allocation overhead but also means that all three\n *  parts are resized together, and makes property access a bit complicated.\n */\n\n#if !defined(DUK_HOBJECT_H_INCLUDED)\n#define DUK_HOBJECT_H_INCLUDED\n\n/* Object flags.  Make sure this stays in sync with debugger object\n * inspection code.\n */\n\n/* XXX: some flags are object subtype specific (e.g. common to all function\n * subtypes, duk_harray, etc) and could be reused for different subtypes.\n */\n#define DUK_HOBJECT_FLAG_EXTENSIBLE            DUK_HEAPHDR_USER_FLAG(0)   /* object is extensible */\n#define DUK_HOBJECT_FLAG_CONSTRUCTABLE         DUK_HEAPHDR_USER_FLAG(1)   /* object is constructable */\n#define DUK_HOBJECT_FLAG_CALLABLE              DUK_HEAPHDR_USER_FLAG(2)   /* object is callable */\n#define DUK_HOBJECT_FLAG_BOUNDFUNC             DUK_HEAPHDR_USER_FLAG(3)   /* object established using Function.prototype.bind() */\n#define DUK_HOBJECT_FLAG_COMPFUNC              DUK_HEAPHDR_USER_FLAG(4)   /* object is a compiled function (duk_hcompfunc) */\n#define DUK_HOBJECT_FLAG_NATFUNC               DUK_HEAPHDR_USER_FLAG(5)   /* object is a native function (duk_hnatfunc) */\n#define DUK_HOBJECT_FLAG_BUFOBJ                DUK_HEAPHDR_USER_FLAG(6)   /* object is a buffer object (duk_hbufobj) (always exotic) */\n#define DUK_HOBJECT_FLAG_FASTREFS              DUK_HEAPHDR_USER_FLAG(7)   /* object has no fields needing DECREF/marking beyond base duk_hobject header */\n#define DUK_HOBJECT_FLAG_ARRAY_PART            DUK_HEAPHDR_USER_FLAG(8)   /* object has an array part (a_size may still be 0) */\n#define DUK_HOBJECT_FLAG_STRICT                DUK_HEAPHDR_USER_FLAG(9)   /* function: function object is strict */\n#define DUK_HOBJECT_FLAG_NOTAIL                DUK_HEAPHDR_USER_FLAG(10)  /* function: function must not be tail called */\n#define DUK_HOBJECT_FLAG_NEWENV                DUK_HEAPHDR_USER_FLAG(11)  /* function: create new environment when called (see duk_hcompfunc) */\n#define DUK_HOBJECT_FLAG_NAMEBINDING           DUK_HEAPHDR_USER_FLAG(12)  /* function: create binding for func name (function templates only, used for named function expressions) */\n#define DUK_HOBJECT_FLAG_CREATEARGS            DUK_HEAPHDR_USER_FLAG(13)  /* function: create an arguments object on function call */\n#define DUK_HOBJECT_FLAG_HAVE_FINALIZER        DUK_HEAPHDR_USER_FLAG(14)  /* object has a callable (own) finalizer property */\n#define DUK_HOBJECT_FLAG_EXOTIC_ARRAY          DUK_HEAPHDR_USER_FLAG(15)  /* 'Array' object, array length and index exotic behavior */\n#define DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ      DUK_HEAPHDR_USER_FLAG(16)  /* 'String' object, array index exotic behavior */\n#define DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS      DUK_HEAPHDR_USER_FLAG(17)  /* 'Arguments' object and has arguments exotic behavior (non-strict callee) */\n#define DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ       DUK_HEAPHDR_USER_FLAG(18)  /* 'Proxy' object */\n#define DUK_HOBJECT_FLAG_SPECIAL_CALL          DUK_HEAPHDR_USER_FLAG(19)  /* special casing in call behavior, for .call(), .apply(), etc. */\n\n#define DUK_HOBJECT_FLAG_CLASS_BASE            DUK_HEAPHDR_USER_FLAG_NUMBER(20)\n#define DUK_HOBJECT_FLAG_CLASS_BITS            5\n\n#define DUK_HOBJECT_GET_CLASS_NUMBER(h)        \\\n\tDUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS)\n#define DUK_HOBJECT_SET_CLASS_NUMBER(h,v)      \\\n\tDUK_HEAPHDR_SET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS, (v))\n\n#define DUK_HOBJECT_GET_CLASS_MASK(h)          \\\n\t(1UL << DUK_HEAPHDR_GET_FLAG_RANGE(&(h)->hdr, DUK_HOBJECT_FLAG_CLASS_BASE, DUK_HOBJECT_FLAG_CLASS_BITS))\n\n/* Macro for creating flag initializer from a class number.\n * Unsigned type cast is needed to avoid warnings about coercing\n * a signed integer to an unsigned one; the largest class values\n * have the highest bit (bit 31) set which causes this.\n */\n#define DUK_HOBJECT_CLASS_AS_FLAGS(v)          (((duk_uint_t) (v)) << DUK_HOBJECT_FLAG_CLASS_BASE)\n\n/* E5 Section 8.6.2 + custom classes */\n#define DUK_HOBJECT_CLASS_NONE                 0\n#define DUK_HOBJECT_CLASS_OBJECT               1\n#define DUK_HOBJECT_CLASS_ARRAY                2\n#define DUK_HOBJECT_CLASS_FUNCTION             3\n#define DUK_HOBJECT_CLASS_ARGUMENTS            4\n#define DUK_HOBJECT_CLASS_BOOLEAN              5\n#define DUK_HOBJECT_CLASS_DATE                 6\n#define DUK_HOBJECT_CLASS_ERROR                7\n#define DUK_HOBJECT_CLASS_JSON                 8\n#define DUK_HOBJECT_CLASS_MATH                 9\n#define DUK_HOBJECT_CLASS_NUMBER               10\n#define DUK_HOBJECT_CLASS_REGEXP               11\n#define DUK_HOBJECT_CLASS_STRING               12\n#define DUK_HOBJECT_CLASS_GLOBAL               13\n#define DUK_HOBJECT_CLASS_SYMBOL               14\n#define DUK_HOBJECT_CLASS_OBJENV               15  /* custom */\n#define DUK_HOBJECT_CLASS_DECENV               16  /* custom */\n#define DUK_HOBJECT_CLASS_POINTER              17  /* custom */\n#define DUK_HOBJECT_CLASS_THREAD               18  /* custom; implies DUK_HOBJECT_IS_THREAD */\n#define DUK_HOBJECT_CLASS_BUFOBJ_MIN           19\n#define DUK_HOBJECT_CLASS_ARRAYBUFFER          19  /* implies DUK_HOBJECT_IS_BUFOBJ */\n#define DUK_HOBJECT_CLASS_DATAVIEW             20\n#define DUK_HOBJECT_CLASS_INT8ARRAY            21\n#define DUK_HOBJECT_CLASS_UINT8ARRAY           22\n#define DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY    23\n#define DUK_HOBJECT_CLASS_INT16ARRAY           24\n#define DUK_HOBJECT_CLASS_UINT16ARRAY          25\n#define DUK_HOBJECT_CLASS_INT32ARRAY           26\n#define DUK_HOBJECT_CLASS_UINT32ARRAY          27\n#define DUK_HOBJECT_CLASS_FLOAT32ARRAY         28\n#define DUK_HOBJECT_CLASS_FLOAT64ARRAY         29\n#define DUK_HOBJECT_CLASS_BUFOBJ_MAX           29\n#define DUK_HOBJECT_CLASS_MAX                  29\n\n/* Class masks. */\n#define DUK_HOBJECT_CMASK_ALL                  ((1UL << (DUK_HOBJECT_CLASS_MAX + 1)) - 1UL)\n#define DUK_HOBJECT_CMASK_NONE                 (1UL << DUK_HOBJECT_CLASS_NONE)\n#define DUK_HOBJECT_CMASK_ARGUMENTS            (1UL << DUK_HOBJECT_CLASS_ARGUMENTS)\n#define DUK_HOBJECT_CMASK_ARRAY                (1UL << DUK_HOBJECT_CLASS_ARRAY)\n#define DUK_HOBJECT_CMASK_BOOLEAN              (1UL << DUK_HOBJECT_CLASS_BOOLEAN)\n#define DUK_HOBJECT_CMASK_DATE                 (1UL << DUK_HOBJECT_CLASS_DATE)\n#define DUK_HOBJECT_CMASK_ERROR                (1UL << DUK_HOBJECT_CLASS_ERROR)\n#define DUK_HOBJECT_CMASK_FUNCTION             (1UL << DUK_HOBJECT_CLASS_FUNCTION)\n#define DUK_HOBJECT_CMASK_JSON                 (1UL << DUK_HOBJECT_CLASS_JSON)\n#define DUK_HOBJECT_CMASK_MATH                 (1UL << DUK_HOBJECT_CLASS_MATH)\n#define DUK_HOBJECT_CMASK_NUMBER               (1UL << DUK_HOBJECT_CLASS_NUMBER)\n#define DUK_HOBJECT_CMASK_OBJECT               (1UL << DUK_HOBJECT_CLASS_OBJECT)\n#define DUK_HOBJECT_CMASK_REGEXP               (1UL << DUK_HOBJECT_CLASS_REGEXP)\n#define DUK_HOBJECT_CMASK_STRING               (1UL << DUK_HOBJECT_CLASS_STRING)\n#define DUK_HOBJECT_CMASK_GLOBAL               (1UL << DUK_HOBJECT_CLASS_GLOBAL)\n#define DUK_HOBJECT_CMASK_SYMBOL               (1UL << DUK_HOBJECT_CLASS_SYMBOL)\n#define DUK_HOBJECT_CMASK_OBJENV               (1UL << DUK_HOBJECT_CLASS_OBJENV)\n#define DUK_HOBJECT_CMASK_DECENV               (1UL << DUK_HOBJECT_CLASS_DECENV)\n#define DUK_HOBJECT_CMASK_POINTER              (1UL << DUK_HOBJECT_CLASS_POINTER)\n#define DUK_HOBJECT_CMASK_ARRAYBUFFER          (1UL << DUK_HOBJECT_CLASS_ARRAYBUFFER)\n#define DUK_HOBJECT_CMASK_DATAVIEW             (1UL << DUK_HOBJECT_CLASS_DATAVIEW)\n#define DUK_HOBJECT_CMASK_INT8ARRAY            (1UL << DUK_HOBJECT_CLASS_INT8ARRAY)\n#define DUK_HOBJECT_CMASK_UINT8ARRAY           (1UL << DUK_HOBJECT_CLASS_UINT8ARRAY)\n#define DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY    (1UL << DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY)\n#define DUK_HOBJECT_CMASK_INT16ARRAY           (1UL << DUK_HOBJECT_CLASS_INT16ARRAY)\n#define DUK_HOBJECT_CMASK_UINT16ARRAY          (1UL << DUK_HOBJECT_CLASS_UINT16ARRAY)\n#define DUK_HOBJECT_CMASK_INT32ARRAY           (1UL << DUK_HOBJECT_CLASS_INT32ARRAY)\n#define DUK_HOBJECT_CMASK_UINT32ARRAY          (1UL << DUK_HOBJECT_CLASS_UINT32ARRAY)\n#define DUK_HOBJECT_CMASK_FLOAT32ARRAY         (1UL << DUK_HOBJECT_CLASS_FLOAT32ARRAY)\n#define DUK_HOBJECT_CMASK_FLOAT64ARRAY         (1UL << DUK_HOBJECT_CLASS_FLOAT64ARRAY)\n\n#define DUK_HOBJECT_CMASK_ALL_BUFOBJS \\\n\t(DUK_HOBJECT_CMASK_ARRAYBUFFER | \\\n\t DUK_HOBJECT_CMASK_DATAVIEW | \\\n\t DUK_HOBJECT_CMASK_INT8ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT8ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT8CLAMPEDARRAY | \\\n\t DUK_HOBJECT_CMASK_INT16ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT16ARRAY | \\\n\t DUK_HOBJECT_CMASK_INT32ARRAY | \\\n\t DUK_HOBJECT_CMASK_UINT32ARRAY | \\\n\t DUK_HOBJECT_CMASK_FLOAT32ARRAY | \\\n\t DUK_HOBJECT_CMASK_FLOAT64ARRAY)\n\n#define DUK_HOBJECT_IS_OBJENV(h)               (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_OBJENV)\n#define DUK_HOBJECT_IS_DECENV(h)               (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_DECENV)\n#define DUK_HOBJECT_IS_ENV(h)                  (DUK_HOBJECT_IS_OBJENV((h)) || DUK_HOBJECT_IS_DECENV((h)))\n#define DUK_HOBJECT_IS_ARRAY(h)                DUK_HOBJECT_HAS_EXOTIC_ARRAY((h))  /* Rely on class Array <=> exotic Array */\n#define DUK_HOBJECT_IS_BOUNDFUNC(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_IS_COMPFUNC(h)             DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_IS_NATFUNC(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_IS_BUFOBJ(h)               DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#else\n#define DUK_HOBJECT_IS_BUFOBJ(h)               0\n#endif\n#define DUK_HOBJECT_IS_THREAD(h)               (DUK_HOBJECT_GET_CLASS_NUMBER((h)) == DUK_HOBJECT_CLASS_THREAD)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_IS_PROXY(h)                DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ((h))\n#else\n#define DUK_HOBJECT_IS_PROXY(h)                0\n#endif\n\n#define DUK_HOBJECT_IS_NONBOUND_FUNCTION(h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \\\n                                                        DUK_HOBJECT_FLAG_COMPFUNC | \\\n                                                        DUK_HOBJECT_FLAG_NATFUNC)\n\n#define DUK_HOBJECT_IS_FUNCTION(h)             DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, \\\n                                                        DUK_HOBJECT_FLAG_BOUNDFUNC | \\\n                                                        DUK_HOBJECT_FLAG_COMPFUNC | \\\n                                                        DUK_HOBJECT_FLAG_NATFUNC)\n\n#define DUK_HOBJECT_IS_CALLABLE(h)             DUK_HOBJECT_HAS_CALLABLE((h))\n\n/* Object has any exotic behavior(s). */\n#define DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS      (DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | \\\n                                                DUK_HOBJECT_FLAG_BUFOBJ | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#define DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR(h)     DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_EXOTIC_BEHAVIOR_FLAGS)\n\n/* Object has any virtual properties (not counting Proxy behavior). */\n#define DUK_HOBJECT_VIRTUAL_PROPERTY_FLAGS     (DUK_HOBJECT_FLAG_EXOTIC_ARRAY | \\\n                                                DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ | \\\n                                                DUK_HOBJECT_FLAG_BUFOBJ)\n#define DUK_HOBJECT_HAS_VIRTUAL_PROPERTIES(h)  DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_VIRTUAL_PROPERTY_FLAGS)\n\n#define DUK_HOBJECT_HAS_EXTENSIBLE(h)          DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)\n#define DUK_HOBJECT_HAS_CONSTRUCTABLE(h)       DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)\n#define DUK_HOBJECT_HAS_CALLABLE(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE)\n#define DUK_HOBJECT_HAS_BOUNDFUNC(h)           DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_HAS_COMPFUNC(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_HAS_NATFUNC(h)             DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_HAS_BUFOBJ(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#else\n#define DUK_HOBJECT_HAS_BUFOBJ(h)              0\n#endif\n#define DUK_HOBJECT_HAS_FASTREFS(h)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)\n#define DUK_HOBJECT_HAS_ARRAY_PART(h)          DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)\n#define DUK_HOBJECT_HAS_STRICT(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)\n#define DUK_HOBJECT_HAS_NOTAIL(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)\n#define DUK_HOBJECT_HAS_NEWENV(h)              DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)\n#define DUK_HOBJECT_HAS_NAMEBINDING(h)         DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)\n#define DUK_HOBJECT_HAS_CREATEARGS(h)          DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)\n#define DUK_HOBJECT_HAS_HAVE_FINALIZER(h)      DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER)\n#define DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)        DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)\n#define DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)\n#define DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h)    DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)     DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#else\n#define DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(h)     0\n#endif\n#define DUK_HOBJECT_HAS_SPECIAL_CALL(h)        DUK_HEAPHDR_CHECK_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)\n\n#define DUK_HOBJECT_SET_EXTENSIBLE(h)          DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)\n#define DUK_HOBJECT_SET_CONSTRUCTABLE(h)       DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)\n#define DUK_HOBJECT_SET_CALLABLE(h)            DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE)\n#define DUK_HOBJECT_SET_BOUNDFUNC(h)           DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_SET_COMPFUNC(h)            DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_SET_NATFUNC(h)             DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_SET_BUFOBJ(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#endif\n#define DUK_HOBJECT_SET_FASTREFS(h)            DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)\n#define DUK_HOBJECT_SET_ARRAY_PART(h)          DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)\n#define DUK_HOBJECT_SET_STRICT(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)\n#define DUK_HOBJECT_SET_NOTAIL(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)\n#define DUK_HOBJECT_SET_NEWENV(h)              DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)\n#define DUK_HOBJECT_SET_NAMEBINDING(h)         DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)\n#define DUK_HOBJECT_SET_CREATEARGS(h)          DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)\n#define DUK_HOBJECT_SET_HAVE_FINALIZER(h)      DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER)\n#define DUK_HOBJECT_SET_EXOTIC_ARRAY(h)        DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)\n#define DUK_HOBJECT_SET_EXOTIC_STRINGOBJ(h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)\n#define DUK_HOBJECT_SET_EXOTIC_ARGUMENTS(h)    DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_SET_EXOTIC_PROXYOBJ(h)     DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#endif\n#define DUK_HOBJECT_SET_SPECIAL_CALL(h)        DUK_HEAPHDR_SET_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)\n\n#define DUK_HOBJECT_CLEAR_EXTENSIBLE(h)        DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXTENSIBLE)\n#define DUK_HOBJECT_CLEAR_CONSTRUCTABLE(h)     DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CONSTRUCTABLE)\n#define DUK_HOBJECT_CLEAR_CALLABLE(h)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CALLABLE)\n#define DUK_HOBJECT_CLEAR_BOUNDFUNC(h)         DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BOUNDFUNC)\n#define DUK_HOBJECT_CLEAR_COMPFUNC(h)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_COMPFUNC)\n#define DUK_HOBJECT_CLEAR_NATFUNC(h)           DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NATFUNC)\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n#define DUK_HOBJECT_CLEAR_BUFOBJ(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_BUFOBJ)\n#endif\n#define DUK_HOBJECT_CLEAR_FASTREFS(h)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_FASTREFS)\n#define DUK_HOBJECT_CLEAR_ARRAY_PART(h)        DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_ARRAY_PART)\n#define DUK_HOBJECT_CLEAR_STRICT(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_STRICT)\n#define DUK_HOBJECT_CLEAR_NOTAIL(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NOTAIL)\n#define DUK_HOBJECT_CLEAR_NEWENV(h)            DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NEWENV)\n#define DUK_HOBJECT_CLEAR_NAMEBINDING(h)       DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_NAMEBINDING)\n#define DUK_HOBJECT_CLEAR_CREATEARGS(h)        DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_CREATEARGS)\n#define DUK_HOBJECT_CLEAR_HAVE_FINALIZER(h)    DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_HAVE_FINALIZER)\n#define DUK_HOBJECT_CLEAR_EXOTIC_ARRAY(h)      DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARRAY)\n#define DUK_HOBJECT_CLEAR_EXOTIC_STRINGOBJ(h)  DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ)\n#define DUK_HOBJECT_CLEAR_EXOTIC_ARGUMENTS(h)  DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS)\n#if defined(DUK_USE_ES6_PROXY)\n#define DUK_HOBJECT_CLEAR_EXOTIC_PROXYOBJ(h)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_EXOTIC_PROXYOBJ)\n#endif\n#define DUK_HOBJECT_CLEAR_SPECIAL_CALL(h)      DUK_HEAPHDR_CLEAR_FLAG_BITS(&(h)->hdr, DUK_HOBJECT_FLAG_SPECIAL_CALL)\n\n/* Object can/cannot use FASTREFS, i.e. has no strong reference fields beyond\n * duk_hobject base header.  This is used just for asserts so doesn't need to\n * be optimized.\n */\n#define DUK_HOBJECT_PROHIBITS_FASTREFS(h) \\\n\t(DUK_HOBJECT_IS_COMPFUNC((h)) || DUK_HOBJECT_IS_DECENV((h)) || DUK_HOBJECT_IS_OBJENV((h)) || \\\n\t DUK_HOBJECT_IS_BUFOBJ((h)) || DUK_HOBJECT_IS_THREAD((h)) || DUK_HOBJECT_IS_PROXY((h)) || \\\n\t DUK_HOBJECT_IS_BOUNDFUNC((h)))\n#define DUK_HOBJECT_ALLOWS_FASTREFS(h) (!DUK_HOBJECT_PROHIBITS_FASTREFS((h)))\n\n/* Flags used for property attributes in duk_propdesc and packed flags.\n * Must fit into 8 bits.\n */\n#define DUK_PROPDESC_FLAG_WRITABLE              (1U << 0)    /* E5 Section 8.6.1 */\n#define DUK_PROPDESC_FLAG_ENUMERABLE            (1U << 1)    /* E5 Section 8.6.1 */\n#define DUK_PROPDESC_FLAG_CONFIGURABLE          (1U << 2)    /* E5 Section 8.6.1 */\n#define DUK_PROPDESC_FLAG_ACCESSOR              (1U << 3)    /* accessor */\n#define DUK_PROPDESC_FLAG_VIRTUAL               (1U << 4)    /* property is virtual: used in duk_propdesc, never stored\n                                                             * (used by e.g. buffer virtual properties)\n                                                             */\n#define DUK_PROPDESC_FLAGS_MASK                 (DUK_PROPDESC_FLAG_WRITABLE | \\\n                                                 DUK_PROPDESC_FLAG_ENUMERABLE | \\\n                                                 DUK_PROPDESC_FLAG_CONFIGURABLE | \\\n                                                 DUK_PROPDESC_FLAG_ACCESSOR)\n\n/* Additional flags which are passed in the same flags argument as property\n * flags but are not stored in object properties.\n */\n#define DUK_PROPDESC_FLAG_NO_OVERWRITE          (1U << 4)    /* internal define property: skip write silently if exists */\n\n/* Convenience defines for property attributes. */\n#define DUK_PROPDESC_FLAGS_NONE                 0\n#define DUK_PROPDESC_FLAGS_W                    (DUK_PROPDESC_FLAG_WRITABLE)\n#define DUK_PROPDESC_FLAGS_E                    (DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_PROPDESC_FLAGS_C                    (DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_PROPDESC_FLAGS_WE                   (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_PROPDESC_FLAGS_WC                   (DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_PROPDESC_FLAGS_EC                   (DUK_PROPDESC_FLAG_ENUMERABLE | DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_PROPDESC_FLAGS_WEC                  (DUK_PROPDESC_FLAG_WRITABLE | \\\n                                                 DUK_PROPDESC_FLAG_ENUMERABLE | \\\n                                                 DUK_PROPDESC_FLAG_CONFIGURABLE)\n\n/* Flags for duk_hobject_get_own_propdesc() and variants. */\n#define DUK_GETDESC_FLAG_PUSH_VALUE          (1U << 0)  /* push value to stack */\n#define DUK_GETDESC_FLAG_IGNORE_PROTOLOOP    (1U << 1)  /* don't throw for prototype loop */\n\n/*\n *  Macro for object validity check\n *\n *  Assert for currently guaranteed relations between flags, for instance.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hobject_assert_valid(duk_hobject *h);\n#define DUK_HOBJECT_ASSERT_VALID(h)  do { duk_hobject_assert_valid((h)); } while (0)\n#else\n#define DUK_HOBJECT_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Macros to access the 'props' allocation.\n */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HOBJECT_GET_PROPS(heap,h) \\\n\t((duk_uint8_t *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, ((duk_heaphdr *) (h))->h_extra16))\n#define DUK_HOBJECT_SET_PROPS(heap,h,x) do { \\\n\t\t((duk_heaphdr *) (h))->h_extra16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \\\n\t} while (0)\n#else\n#define DUK_HOBJECT_GET_PROPS(heap,h) \\\n\t((h)->props)\n#define DUK_HOBJECT_SET_PROPS(heap,h,x) do { \\\n\t\t(h)->props = (duk_uint8_t *) (x); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_HOBJECT_LAYOUT_1)\n/* LAYOUT 1 */\n#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \\\n\t((duk_hstring **) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) \\\n\t))\n#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \\\n\t((duk_propvalue *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_hstring *) \\\n\t))\n#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \\\n\t((duk_uint8_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \\\n\t))\n#define DUK_HOBJECT_A_GET_BASE(heap,h) \\\n\t((duk_tval *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) \\\n\t))\n#define DUK_HOBJECT_H_GET_BASE(heap,h) \\\n\t((duk_uint32_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \\\n\t( \\\n\t\t(n_ent) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t(n_arr) * sizeof(duk_tval) + \\\n\t\t(n_hash) * sizeof(duk_uint32_t) \\\n\t)\n#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash)  do { \\\n\t\t(set_e_k) = (duk_hstring **) (void *) (p_base); \\\n\t\t(set_e_pv) = (duk_propvalue *) (void *) ((set_e_k) + (n_ent)); \\\n\t\t(set_e_f) = (duk_uint8_t *) (void *) ((set_e_pv) + (n_ent)); \\\n\t\t(set_a) = (duk_tval *) (void *) ((set_e_f) + (n_ent)); \\\n\t\t(set_h) = (duk_uint32_t *) (void *) ((set_a) + (n_arr)); \\\n\t} while (0)\n#elif defined(DUK_USE_HOBJECT_LAYOUT_2)\n/* LAYOUT 2 */\n#if (DUK_USE_ALIGN_BY == 4)\n#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) ((4 - (e_sz)) & 0x03)\n#elif (DUK_USE_ALIGN_BY == 8)\n#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) ((8 - (e_sz)) & 0x07)\n#elif (DUK_USE_ALIGN_BY == 1)\n#define DUK_HOBJECT_E_FLAG_PADDING(e_sz) 0\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \\\n\t((duk_hstring **) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) \\\n\t))\n#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \\\n\t((duk_propvalue *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) \\\n\t))\n#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \\\n\t((duk_uint8_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + DUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue)) \\\n\t))\n#define DUK_HOBJECT_A_GET_BASE(heap,h) \\\n\t((duk_tval *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t\tDUK_HOBJECT_E_FLAG_PADDING(DUK_HOBJECT_GET_ESIZE((h))) \\\n\t))\n#define DUK_HOBJECT_H_GET_BASE(heap,h) \\\n\t((duk_uint32_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\t\tDUK_HOBJECT_E_FLAG_PADDING(DUK_HOBJECT_GET_ESIZE((h))) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \\\n\t( \\\n\t\t(n_ent) * (sizeof(duk_hstring *) + sizeof(duk_propvalue) + sizeof(duk_uint8_t)) + \\\n\t\tDUK_HOBJECT_E_FLAG_PADDING((n_ent)) + \\\n\t\t(n_arr) * sizeof(duk_tval) + \\\n\t\t(n_hash) * sizeof(duk_uint32_t) \\\n\t)\n#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash)  do { \\\n\t\t(set_e_pv) = (duk_propvalue *) (void *) (p_base); \\\n\t\t(set_e_k) = (duk_hstring **) (void *) ((set_e_pv) + (n_ent)); \\\n\t\t(set_e_f) = (duk_uint8_t *) (void *) ((set_e_k) + (n_ent)); \\\n\t\t(set_a) = (duk_tval *) (void *) (((duk_uint8_t *) (set_e_f)) + \\\n\t\t                                 sizeof(duk_uint8_t) * (n_ent) + \\\n\t\t                                 DUK_HOBJECT_E_FLAG_PADDING((n_ent))); \\\n\t\t(set_h) = (duk_uint32_t *) (void *) ((set_a) + (n_arr)); \\\n\t} while (0)\n#elif defined(DUK_USE_HOBJECT_LAYOUT_3)\n/* LAYOUT 3 */\n#define DUK_HOBJECT_E_GET_KEY_BASE(heap,h) \\\n\t((duk_hstring **) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_E_GET_VALUE_BASE(heap,h) \\\n\t((duk_propvalue *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) \\\n\t))\n#define DUK_HOBJECT_E_GET_FLAGS_BASE(heap,h) \\\n\t((duk_uint8_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_propvalue) + sizeof(duk_hstring *)) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) + \\\n\t\t\tDUK_HOBJECT_GET_HSIZE((h)) * sizeof(duk_uint32_t) \\\n\t))\n#define DUK_HOBJECT_A_GET_BASE(heap,h) \\\n\t((duk_tval *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * sizeof(duk_propvalue) \\\n\t))\n#define DUK_HOBJECT_H_GET_BASE(heap,h) \\\n\t((duk_uint32_t *) (void *) ( \\\n\t\tDUK_HOBJECT_GET_PROPS((heap), (h)) + \\\n\t\t\tDUK_HOBJECT_GET_ESIZE((h)) * (sizeof(duk_propvalue) + sizeof(duk_hstring *)) + \\\n\t\t\tDUK_HOBJECT_GET_ASIZE((h)) * sizeof(duk_tval) \\\n\t))\n#define DUK_HOBJECT_P_COMPUTE_SIZE(n_ent,n_arr,n_hash) \\\n\t( \\\n\t\t(n_ent) * (sizeof(duk_propvalue) + sizeof(duk_hstring *) + sizeof(duk_uint8_t)) + \\\n\t\t(n_arr) * sizeof(duk_tval) + \\\n\t\t(n_hash) * sizeof(duk_uint32_t) \\\n\t)\n#define DUK_HOBJECT_P_SET_REALLOC_PTRS(p_base,set_e_k,set_e_pv,set_e_f,set_a,set_h,n_ent,n_arr,n_hash)  do { \\\n\t\t(set_e_pv) = (duk_propvalue *) (void *) (p_base); \\\n\t\t(set_a) = (duk_tval *) (void *) ((set_e_pv) + (n_ent)); \\\n\t\t(set_e_k) = (duk_hstring **) (void *) ((set_a) + (n_arr)); \\\n\t\t(set_h) = (duk_uint32_t *) (void *) ((set_e_k) + (n_ent)); \\\n\t\t(set_e_f) = (duk_uint8_t *) (void *) ((set_h) + (n_hash)); \\\n\t} while (0)\n#else\n#error invalid hobject layout defines\n#endif  /* hobject property layout */\n\n#define DUK_HOBJECT_P_ALLOC_SIZE(h) \\\n\tDUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE((h)), DUK_HOBJECT_GET_ASIZE((h)), DUK_HOBJECT_GET_HSIZE((h)))\n\n#define DUK_HOBJECT_E_GET_KEY(heap,h,i)              (DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_KEY_PTR(heap,h,i)          (&DUK_HOBJECT_E_GET_KEY_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_VALUE(heap,h,i)            (DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_VALUE_PTR(heap,h,i)        (&DUK_HOBJECT_E_GET_VALUE_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_VALUE_TVAL(heap,h,i)       (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)\n#define DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap,h,i)   (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v)\n#define DUK_HOBJECT_E_GET_VALUE_GETTER(heap,h,i)     (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)\n#define DUK_HOBJECT_E_GET_VALUE_GETTER_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get)\n#define DUK_HOBJECT_E_GET_VALUE_SETTER(heap,h,i)     (DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)\n#define DUK_HOBJECT_E_GET_VALUE_SETTER_PTR(heap,h,i) (&DUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set)\n#define DUK_HOBJECT_E_GET_FLAGS(heap,h,i)            (DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_E_GET_FLAGS_PTR(heap,h,i)        (&DUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_A_GET_VALUE(heap,h,i)            (DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_A_GET_VALUE_PTR(heap,h,i)        (&DUK_HOBJECT_A_GET_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_H_GET_INDEX(heap,h,i)            (DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])\n#define DUK_HOBJECT_H_GET_INDEX_PTR(heap,h,i)        (&DUK_HOBJECT_H_GET_BASE((heap), (h))[(i)])\n\n#define DUK_HOBJECT_E_SET_KEY(heap,h,i,k)  do { \\\n\t\tDUK_HOBJECT_E_GET_KEY((heap), (h), (i)) = (k); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)) = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE_TVAL(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).v = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE_GETTER(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.get = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_VALUE_SETTER(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_E_GET_VALUE((heap), (h), (i)).a.set = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_E_SET_FLAGS(heap,h,i,f)  do { \\\n\t\tDUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) = (duk_uint8_t) (f); \\\n\t} while (0)\n#define DUK_HOBJECT_A_SET_VALUE(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_A_GET_VALUE((heap), (h), (i)) = (v); \\\n\t} while (0)\n#define DUK_HOBJECT_A_SET_VALUE_TVAL(heap,h,i,v) \\\n\tDUK_HOBJECT_A_SET_VALUE((heap), (h), (i), (v))  /* alias for above */\n#define DUK_HOBJECT_H_SET_INDEX(heap,h,i,v)  do { \\\n\t\tDUK_HOBJECT_H_GET_INDEX((heap), (h), (i)) = (v); \\\n\t} while (0)\n\n#define DUK_HOBJECT_E_SET_FLAG_BITS(heap,h,i,mask)  do { \\\n\t\tDUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] |= (mask); \\\n\t} while (0)\n\n#define DUK_HOBJECT_E_CLEAR_FLAG_BITS(heap,h,i,mask)  do { \\\n\t\tDUK_HOBJECT_E_GET_FLAGS_BASE((heap), (h))[(i)] &= ~(mask); \\\n\t} while (0)\n\n#define DUK_HOBJECT_E_SLOT_IS_WRITABLE(heap,h,i)     ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_WRITABLE) != 0)\n#define DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(heap,h,i)   ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)\n#define DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(heap,h,i) ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)\n#define DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap,h,i)     ((DUK_HOBJECT_E_GET_FLAGS((heap), (h), (i)) & DUK_PROPDESC_FLAG_ACCESSOR) != 0)\n\n#define DUK_HOBJECT_E_SLOT_SET_WRITABLE(heap,h,i)        DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)\n#define DUK_HOBJECT_E_SLOT_SET_ENUMERABLE(heap,h,i)      DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_HOBJECT_E_SLOT_SET_CONFIGURABLE(heap,h,i)    DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_HOBJECT_E_SLOT_SET_ACCESSOR(heap,h,i)        DUK_HOBJECT_E_SET_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)\n\n#define DUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(heap,h,i)      DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_WRITABLE)\n#define DUK_HOBJECT_E_SLOT_CLEAR_ENUMERABLE(heap,h,i)    DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ENUMERABLE)\n#define DUK_HOBJECT_E_SLOT_CLEAR_CONFIGURABLE(heap,h,i)  DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_CONFIGURABLE)\n#define DUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(heap,h,i)      DUK_HOBJECT_E_CLEAR_FLAG_BITS((heap), (h), (i),DUK_PROPDESC_FLAG_ACCESSOR)\n\n#define DUK_PROPDESC_IS_WRITABLE(p)             (((p)->flags & DUK_PROPDESC_FLAG_WRITABLE) != 0)\n#define DUK_PROPDESC_IS_ENUMERABLE(p)           (((p)->flags & DUK_PROPDESC_FLAG_ENUMERABLE) != 0)\n#define DUK_PROPDESC_IS_CONFIGURABLE(p)         (((p)->flags & DUK_PROPDESC_FLAG_CONFIGURABLE) != 0)\n#define DUK_PROPDESC_IS_ACCESSOR(p)             (((p)->flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0)\n\n#define DUK_HOBJECT_HASHIDX_UNUSED              0xffffffffUL\n#define DUK_HOBJECT_HASHIDX_DELETED             0xfffffffeUL\n\n/*\n *  Macros for accessing size fields\n */\n\n#if defined(DUK_USE_OBJSIZES16)\n#define DUK_HOBJECT_GET_ESIZE(h) ((h)->e_size16)\n#define DUK_HOBJECT_SET_ESIZE(h,v) do { (h)->e_size16 = (v); } while (0)\n#define DUK_HOBJECT_GET_ENEXT(h) ((h)->e_next16)\n#define DUK_HOBJECT_SET_ENEXT(h,v) do { (h)->e_next16 = (v); } while (0)\n#define DUK_HOBJECT_POSTINC_ENEXT(h) ((h)->e_next16++)\n#define DUK_HOBJECT_GET_ASIZE(h) ((h)->a_size16)\n#define DUK_HOBJECT_SET_ASIZE(h,v) do { (h)->a_size16 = (v); } while (0)\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n#define DUK_HOBJECT_GET_HSIZE(h) ((h)->h_size16)\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { (h)->h_size16 = (v); } while (0)\n#else\n#define DUK_HOBJECT_GET_HSIZE(h) 0\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { DUK_ASSERT((v) == 0); } while (0)\n#endif\n#else\n#define DUK_HOBJECT_GET_ESIZE(h) ((h)->e_size)\n#define DUK_HOBJECT_SET_ESIZE(h,v) do { (h)->e_size = (v); } while (0)\n#define DUK_HOBJECT_GET_ENEXT(h) ((h)->e_next)\n#define DUK_HOBJECT_SET_ENEXT(h,v) do { (h)->e_next = (v); } while (0)\n#define DUK_HOBJECT_POSTINC_ENEXT(h) ((h)->e_next++)\n#define DUK_HOBJECT_GET_ASIZE(h) ((h)->a_size)\n#define DUK_HOBJECT_SET_ASIZE(h,v) do { (h)->a_size = (v); } while (0)\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n#define DUK_HOBJECT_GET_HSIZE(h) ((h)->h_size)\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { (h)->h_size = (v); } while (0)\n#else\n#define DUK_HOBJECT_GET_HSIZE(h) 0\n#define DUK_HOBJECT_SET_HSIZE(h,v) do { DUK_ASSERT((v) == 0); } while (0)\n#endif\n#endif\n\n/*\n *  Misc\n */\n\n/* Maximum prototype traversal depth.  Sanity limit which handles e.g.\n * prototype loops (even complex ones like 1->2->3->4->2->3->4->2->3->4).\n */\n#define DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY      10000L\n\n/*\n *  ECMAScript [[Class]]\n */\n\n/* range check not necessary because all 4-bit values are mapped */\n#define DUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(n)  duk_class_number_to_stridx[(n)]\n\n#define DUK_HOBJECT_GET_CLASS_STRING(heap,h)          \\\n\tDUK_HEAP_GET_STRING( \\\n\t\t(heap), \\\n\t\tDUK_HOBJECT_CLASS_NUMBER_TO_STRIDX(DUK_HOBJECT_GET_CLASS_NUMBER((h))) \\\n\t)\n\n/*\n *  Macros for property handling\n */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HOBJECT_GET_PROTOTYPE(heap,h) \\\n\t((duk_hobject *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (h)->prototype16))\n#define DUK_HOBJECT_SET_PROTOTYPE(heap,h,x) do { \\\n\t\t(h)->prototype16 = DUK_USE_HEAPPTR_ENC16((heap)->heap_udata, (void *) (x)); \\\n\t} while (0)\n#else\n#define DUK_HOBJECT_GET_PROTOTYPE(heap,h) \\\n\t((h)->prototype)\n#define DUK_HOBJECT_SET_PROTOTYPE(heap,h,x) do { \\\n\t\t(h)->prototype = (x); \\\n\t} while (0)\n#endif\n\n/* Set prototype, DECREF earlier value, INCREF new value (tolerating NULLs). */\n#define DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr,h,p)       duk_hobject_set_prototype_updref((thr), (h), (p))\n\n/* Set initial prototype, assume NULL previous prototype, INCREF new value,\n * tolerate NULL.\n */\n#define DUK_HOBJECT_SET_PROTOTYPE_INIT_INCREF(thr,h,proto) do { \\\n\t\tduk_hthread *duk__thr = (thr); \\\n\t\tduk_hobject *duk__obj = (h); \\\n\t\tduk_hobject *duk__proto = (proto); \\\n\t\tDUK_UNREF(duk__thr); \\\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(duk__thr->heap, duk__obj) == NULL); \\\n\t\tDUK_HOBJECT_SET_PROTOTYPE(duk__thr->heap, duk__obj, duk__proto); \\\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(duk__thr, duk__proto); \\\n\t} while (0)\n\n/*\n *  Finalizer check\n */\n\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HOBJECT_HAS_FINALIZER_FAST(heap,h) duk_hobject_has_finalizer_fast_raw((heap), (h))\n#else\n#define DUK_HOBJECT_HAS_FINALIZER_FAST(heap,h) duk_hobject_has_finalizer_fast_raw((h))\n#endif\n\n/*\n *  Resizing and hash behavior\n */\n\n/* Sanity limit on max number of properties (allocated, not necessarily used).\n * This is somewhat arbitrary, but if we're close to 2**32 properties some\n * algorithms will fail (e.g. hash size selection, next prime selection).\n * Also, we use negative array/entry table indices to indicate 'not found',\n * so anything above 0x80000000 will cause trouble now.\n */\n#if defined(DUK_USE_OBJSIZES16)\n#define DUK_HOBJECT_MAX_PROPERTIES       0x0000ffffUL\n#else\n#define DUK_HOBJECT_MAX_PROPERTIES       0x3fffffffUL   /* 2**30-1 ~= 1G properties */\n#endif\n\n/* internal align target for props allocation, must be 2*n for some n */\n#if (DUK_USE_ALIGN_BY == 4)\n#define DUK_HOBJECT_ALIGN_TARGET         4\n#elif (DUK_USE_ALIGN_BY == 8)\n#define DUK_HOBJECT_ALIGN_TARGET         8\n#elif (DUK_USE_ALIGN_BY == 1)\n#define DUK_HOBJECT_ALIGN_TARGET         1\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\n/*\n *  PC-to-line constants\n */\n\n#define DUK_PC2LINE_SKIP    64\n\n/* maximum length for a SKIP-1 diffstream: 35 bits per entry, rounded up to bytes */\n#define DUK_PC2LINE_MAX_DIFF_LENGTH    (((DUK_PC2LINE_SKIP - 1) * 35 + 7) / 8)\n\n/*\n *  Struct defs\n */\n\nstruct duk_propaccessor {\n\tduk_hobject *get;\n\tduk_hobject *set;\n};\n\nunion duk_propvalue {\n\t/* The get/set pointers could be 16-bit pointer compressed but it\n\t * would make no difference on 32-bit platforms because duk_tval is\n\t * 8 bytes or more anyway.\n\t */\n\tduk_tval v;\n\tduk_propaccessor a;\n};\n\nstruct duk_propdesc {\n\t/* read-only values 'lifted' for ease of use */\n\tduk_small_uint_t flags;\n\tduk_hobject *get;\n\tduk_hobject *set;\n\n\t/* for updating (all are set to < 0 for virtual properties) */\n\tduk_int_t e_idx;  /* prop index in 'entry part', < 0 if not there */\n\tduk_int_t h_idx;  /* prop index in 'hash part', < 0 if not there */\n\tduk_int_t a_idx;  /* prop index in 'array part', < 0 if not there */\n};\n\nstruct duk_hobject {\n\tduk_heaphdr hdr;\n\n\t/*\n\t *  'props' contains {key,value,flags} entries, optional array entries, and\n\t *  an optional hash lookup table for non-array entries in a single 'sliced'\n\t *  allocation.  There are several layout options, which differ slightly in\n\t *  generated code size/speed and alignment/padding; duk_features.h selects\n\t *  the layout used.\n\t *\n\t *  Layout 1 (DUK_USE_HOBJECT_LAYOUT_1):\n\t *\n\t *    e_size * sizeof(duk_hstring *)         bytes of   entry keys (e_next gc reachable)\n\t *    e_size * sizeof(duk_propvalue)         bytes of   entry values (e_next gc reachable)\n\t *    e_size * sizeof(duk_uint8_t)           bytes of   entry flags (e_next gc reachable)\n\t *    a_size * sizeof(duk_tval)              bytes of   (opt) array values (plain only) (all gc reachable)\n\t *    h_size * sizeof(duk_uint32_t)          bytes of   (opt) hash indexes to entries (e_size),\n\t *                                                      0xffffffffUL = unused, 0xfffffffeUL = deleted\n\t *\n\t *  Layout 2 (DUK_USE_HOBJECT_LAYOUT_2):\n\t *\n\t *    e_size * sizeof(duk_propvalue)         bytes of   entry values (e_next gc reachable)\n\t *    e_size * sizeof(duk_hstring *)         bytes of   entry keys (e_next gc reachable)\n\t *    e_size * sizeof(duk_uint8_t) + pad     bytes of   entry flags (e_next gc reachable)\n\t *    a_size * sizeof(duk_tval)              bytes of   (opt) array values (plain only) (all gc reachable)\n\t *    h_size * sizeof(duk_uint32_t)          bytes of   (opt) hash indexes to entries (e_size),\n\t *                                                      0xffffffffUL = unused, 0xfffffffeUL = deleted\n\t *\n\t *  Layout 3 (DUK_USE_HOBJECT_LAYOUT_3):\n\t *\n\t *    e_size * sizeof(duk_propvalue)         bytes of   entry values (e_next gc reachable)\n\t *    a_size * sizeof(duk_tval)              bytes of   (opt) array values (plain only) (all gc reachable)\n\t *    e_size * sizeof(duk_hstring *)         bytes of   entry keys (e_next gc reachable)\n\t *    h_size * sizeof(duk_uint32_t)          bytes of   (opt) hash indexes to entries (e_size),\n\t *                                                      0xffffffffUL = unused, 0xfffffffeUL = deleted\n\t *    e_size * sizeof(duk_uint8_t)           bytes of   entry flags (e_next gc reachable)\n\t *\n\t *  In layout 1, the 'e_next' count is rounded to 4 or 8 on platforms\n\t *  requiring 4 or 8 byte alignment.  This ensures proper alignment\n\t *  for the entries, at the cost of memory footprint.  However, it's\n\t *  probably preferable to use another layout on such platforms instead.\n\t *\n\t *  In layout 2, the key and value parts are swapped to avoid padding\n\t *  the key array on platforms requiring alignment by 8.  The flags part\n\t *  is padded to get alignment for array entries.  The 'e_next' count does\n\t *  not need to be rounded as in layout 1.\n\t *\n\t *  In layout 3, entry values and array values are always aligned properly,\n\t *  and assuming pointers are at most 8 bytes, so are the entry keys.  Hash\n\t *  indices will be properly aligned (assuming pointers are at least 4 bytes).\n\t *  Finally, flags don't need additional alignment.  This layout provides\n\t *  compact allocations without padding (even on platforms with alignment\n\t *  requirements) at the cost of a bit slower lookups.\n\t *\n\t *  Objects with few keys don't have a hash index; keys are looked up linearly,\n\t *  which is cache efficient because the keys are consecutive.  Larger objects\n\t *  have a hash index part which contains integer indexes to the entries part.\n\t *\n\t *  A single allocation reduces memory allocation overhead but requires more\n\t *  work when any part needs to be resized.  A sliced allocation for entries\n\t *  makes linear key matching faster on most platforms (more locality) and\n\t *  skimps on flags size (which would be followed by 3 bytes of padding in\n\t *  most architectures if entries were placed in a struct).\n\t *\n\t *  'props' also contains internal properties distinguished with a non-BMP\n\t *  prefix.  Often used properties should be placed early in 'props' whenever\n\t *  possible to make accessing them as fast a possible.\n\t */\n\n#if defined(DUK_USE_HEAPPTR16)\n\t/* Located in duk_heaphdr h_extra16.  Subclasses of duk_hobject (like\n\t * duk_hcompfunc) are not free to use h_extra16 for this reason.\n\t */\n#else\n\tduk_uint8_t *props;\n#endif\n\n\t/* prototype: the only internal property lifted outside 'e' as it is so central */\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t prototype16;\n#else\n\tduk_hobject *prototype;\n#endif\n\n#if defined(DUK_USE_OBJSIZES16)\n\tduk_uint16_t e_size16;\n\tduk_uint16_t e_next16;\n\tduk_uint16_t a_size16;\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tduk_uint16_t h_size16;\n#endif\n#else\n\tduk_uint32_t e_size;  /* entry part size */\n\tduk_uint32_t e_next;  /* index for next new key ([0,e_next[ are gc reachable) */\n\tduk_uint32_t a_size;  /* array part size (entirely gc reachable) */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tduk_uint32_t h_size;  /* hash part size or 0 if unused */\n#endif\n#endif\n};\n\n/*\n *  Exposed data\n */\n\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL duk_uint8_t duk_class_number_to_stridx[32];\n#endif  /* !DUK_SINGLE_FILE */\n\n/*\n *  Prototypes\n */\n\n/* alloc and init */\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_harray *duk_harray_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hcompfunc *duk_hcompfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hnatfunc *duk_hnatfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hboundfunc *duk_hboundfunc_alloc(duk_heap *heap, duk_uint_t hobject_flags);\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL_DECL duk_hbufobj *duk_hbufobj_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\n#endif\nDUK_INTERNAL_DECL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hthread *duk_hthread_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hdecenv *duk_hdecenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hobjenv *duk_hobjenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\nDUK_INTERNAL_DECL duk_hproxy *duk_hproxy_alloc(duk_hthread *thr, duk_uint_t hobject_flags);\n\n/* resize */\nDUK_INTERNAL_DECL void duk_hobject_realloc_props(duk_hthread *thr,\n                                                 duk_hobject *obj,\n                                                 duk_uint32_t new_e_size,\n                                                 duk_uint32_t new_a_size,\n                                                 duk_uint32_t new_h_size,\n                                                 duk_bool_t abandon_array);\nDUK_INTERNAL_DECL void duk_hobject_resize_entrypart(duk_hthread *thr,\n                                                    duk_hobject *obj,\n                                                    duk_uint32_t new_e_size);\n#if 0  /*unused*/\nDUK_INTERNAL_DECL void duk_hobject_resize_arraypart(duk_hthread *thr,\n                                                    duk_hobject *obj,\n                                                    duk_uint32_t new_a_size);\n#endif\n\n/* low-level property functions */\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_find_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs);\nDUK_INTERNAL_DECL duk_tval *duk_hobject_find_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_get_own_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags);\n\n/* core property functions */\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_tval *tv_val, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key);\n\n/* internal property functions */\n#define DUK_DELPROP_FLAG_THROW  (1U << 0)\n#define DUK_DELPROP_FLAG_FORCE  (1U << 1)\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key);\nDUK_INTERNAL_DECL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags);\nDUK_INTERNAL_DECL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj);\n#if defined(DUK_USE_HEAPPTR16)\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_heap *heap, duk_hobject *obj);\n#else\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_hobject *obj);\n#endif\n\n/* helpers for defineProperty() and defineProperties() */\nDUK_INTERNAL_DECL void duk_hobject_prepare_property_descriptor(duk_hthread *thr,\n                                                               duk_idx_t idx_in,\n                                                               duk_uint_t *out_defprop_flags,\n                                                               duk_idx_t *out_idx_value,\n                                                               duk_hobject **out_getter,\n                                                               duk_hobject **out_setter);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,\n                                                                duk_uint_t defprop_flags,\n                                                                duk_hobject *obj,\n                                                                duk_hstring *key,\n                                                                duk_idx_t idx_value,\n                                                                duk_hobject *get,\n                                                                duk_hobject *set,\n                                                                duk_bool_t throw_flag);\n\n/* Object built-in methods */\nDUK_INTERNAL_DECL void duk_hobject_object_get_own_property_descriptor(duk_hthread *thr, duk_idx_t obj_idx);\nDUK_INTERNAL_DECL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_object_ownprop_helper(duk_hthread *thr, duk_small_uint_t required_desc_flags);\n\n/* internal properties */\nDUK_INTERNAL_DECL duk_tval *duk_hobject_get_internal_value_tval_ptr(duk_heap *heap, duk_hobject *obj);\nDUK_INTERNAL_DECL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *heap, duk_hobject *obj);\nDUK_INTERNAL_DECL duk_harray *duk_hobject_get_formals(duk_hthread *thr, duk_hobject *obj);\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_get_varmap(duk_hthread *thr, duk_hobject *obj);\n\n/* hobject management functions */\nDUK_INTERNAL_DECL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj);\n\n/* ES2015 proxy */\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_proxy_check(duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler);\nDUK_INTERNAL_DECL duk_hobject *duk_hobject_resolve_proxy_target(duk_hobject *obj);\n#endif\n\n/* enumeration */\nDUK_INTERNAL_DECL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint_t enum_flags);\nDUK_INTERNAL_DECL duk_ret_t duk_hobject_get_enumerated_keys(duk_hthread *thr, duk_small_uint_t enum_flags);\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_enumerator_next(duk_hthread *thr, duk_bool_t get_value);\n\n/* macros */\nDUK_INTERNAL_DECL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject *h, duk_hobject *p);\n\n/* pc2line */\n#if defined(DUK_USE_PC2LINE)\nDUK_INTERNAL_DECL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr *instrs, duk_uint_fast32_t length);\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_hobject_pc2line_query(duk_hthread *thr, duk_idx_t idx_func, duk_uint_fast32_t pc);\n#endif\n\n/* misc */\nDUK_INTERNAL_DECL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, duk_hobject *h, duk_hobject *p, duk_bool_t ignore_loop);\n\n#if !defined(DUK_USE_OBJECT_BUILTIN)\n/* These declarations are needed when related built-in is disabled and\n * genbuiltins.py won't automatically emit the declerations.\n */\nDUK_INTERNAL_DECL duk_ret_t duk_bi_object_prototype_to_string(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_ret_t duk_bi_function_prototype(duk_hthread *thr);\n#endif\n\n#endif  /* DUK_HOBJECT_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hobject_alloc.c",
    "content": "/*\n *  Hobject allocation.\n *\n *  Provides primitive allocation functions for all object types (plain object,\n *  compiled function, native function, thread).  The object return is not yet\n *  in \"heap allocated\" list and has a refcount of zero, so caller must careful.\n */\n\n/* XXX: In most cases there's no need for plain allocation without pushing\n * to the value stack.  Maybe rework contract?\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Helpers.\n */\n\nDUK_LOCAL void duk__init_object_parts(duk_heap *heap, duk_uint_t hobject_flags, duk_hobject *obj) {\n\tDUK_ASSERT(obj != NULL);\n\t/* Zeroed by caller. */\n\n\tobj->hdr.h_flags = hobject_flags | DUK_HTYPE_OBJECT;\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE(&obj->hdr) == DUK_HTYPE_OBJECT);  /* Assume zero shift. */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tDUK_HOBJECT_SET_PROTOTYPE(heap, obj, NULL);\n\tDUK_HOBJECT_SET_PROPS(heap, obj, NULL);\n#endif\n#if defined(DUK_USE_HEAPPTR16)\n\t/* Zero encoded pointer is required to match NULL. */\n\tDUK_HEAPHDR_SET_NEXT(heap, &obj->hdr, NULL);\n#if defined(DUK_USE_DOUBLE_LINKED_HEAP)\n\tDUK_HEAPHDR_SET_PREV(heap, &obj->hdr, NULL);\n#endif\n#endif\n\tDUK_HEAPHDR_ASSERT_LINKS(heap, &obj->hdr);\n\tDUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, &obj->hdr);\n\n\t/* obj->props is intentionally left as NULL, and duk_hobject_props.c must deal\n\t * with this properly.  This is intentional: empty objects consume a minimum\n\t * amount of memory.  Further, an initial allocation might fail and cause\n\t * 'obj' to \"leak\" (require a mark-and-sweep) since it is not reachable yet.\n\t */\n}\n\nDUK_LOCAL void *duk__hobject_alloc_init(duk_hthread *thr, duk_uint_t hobject_flags, duk_size_t size) {\n\tvoid *res;\n\n\tres = (void *) DUK_ALLOC_CHECKED_ZEROED(thr, size);\n\tDUK_ASSERT(res != NULL);\n\tduk__init_object_parts(thr->heap, hobject_flags, (duk_hobject *) res);\n\treturn res;\n}\n\n/*\n *  Allocate an duk_hobject.\n *\n *  The allocated object has no allocation for properties; the caller may\n *  want to force a resize if a desired size is known.\n *\n *  The allocated object has zero reference count and is not reachable.\n *  The caller MUST make the object reachable and increase its reference\n *  count before invoking any operation that might require memory allocation.\n */\n\nDUK_INTERNAL duk_hobject *duk_hobject_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags) {\n\tduk_hobject *res;\n\n\tDUK_ASSERT(heap != NULL);\n\n\t/* different memory layout, alloc size, and init */\n\tDUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_COMPFUNC) == 0);\n\tDUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_NATFUNC) == 0);\n\tDUK_ASSERT((hobject_flags & DUK_HOBJECT_FLAG_BOUNDFUNC) == 0);\n\n\tres = (duk_hobject *) DUK_ALLOC_ZEROED(heap, sizeof(duk_hobject));\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\treturn NULL;\n\t}\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(res));\n\n\tduk__init_object_parts(heap, hobject_flags, res);\n\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(res));\n\treturn res;\n}\n\nDUK_INTERNAL duk_hobject *duk_hobject_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hobject *res;\n\n\tres = (duk_hobject *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hobject));\n\treturn res;\n}\n\nDUK_INTERNAL duk_hcompfunc *duk_hcompfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hcompfunc *res;\n\n\tres = (duk_hcompfunc *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hcompfunc));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_HEAPPTR16)\n\t/* NULL pointer is required to encode to zero, so memset is enough. */\n#else\n\tres->data = NULL;\n\tres->funcs = NULL;\n\tres->bytecode = NULL;\n#endif\n\tres->lex_env = NULL;\n\tres->var_env = NULL;\n#endif\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hnatfunc *duk_hnatfunc_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hnatfunc *res;\n\n\tres = (duk_hnatfunc *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hnatfunc));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->func = NULL;\n#endif\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hboundfunc *duk_hboundfunc_alloc(duk_heap *heap, duk_uint_t hobject_flags) {\n\tduk_hboundfunc *res;\n\n\tres = (duk_hboundfunc *) DUK_ALLOC(heap, sizeof(duk_hboundfunc));\n\tif (!res) {\n\t\treturn NULL;\n\t}\n\tduk_memzero(res, sizeof(duk_hboundfunc));\n\n\tduk__init_object_parts(heap, hobject_flags, &res->obj);\n\n\tDUK_TVAL_SET_UNDEFINED(&res->target);\n\tDUK_TVAL_SET_UNDEFINED(&res->this_binding);\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->args = NULL;\n#endif\n\n\treturn res;\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL duk_hbufobj *duk_hbufobj_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hbufobj *res;\n\n\tres = (duk_hbufobj *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hbufobj));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->buf = NULL;\n\tres->buf_prop = NULL;\n#endif\n\n\tDUK_HBUFOBJ_ASSERT_VALID(res);\n\treturn res;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/* Allocate a new thread.\n *\n * Leaves the built-ins array uninitialized.  The caller must either\n * initialize a new global context or share existing built-ins from\n * another thread.\n */\nDUK_INTERNAL duk_hthread *duk_hthread_alloc_unchecked(duk_heap *heap, duk_uint_t hobject_flags) {\n\tduk_hthread *res;\n\n\tres = (duk_hthread *) DUK_ALLOC(heap, sizeof(duk_hthread));\n\tif (DUK_UNLIKELY(res == NULL)) {\n\t\treturn NULL;\n\t}\n\tduk_memzero(res, sizeof(duk_hthread));\n\n\tduk__init_object_parts(heap, hobject_flags, &res->obj);\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->ptr_curr_pc = NULL;\n\tres->heap = NULL;\n\tres->valstack = NULL;\n\tres->valstack_end = NULL;\n\tres->valstack_alloc_end = NULL;\n\tres->valstack_bottom = NULL;\n\tres->valstack_top = NULL;\n\tres->callstack_curr = NULL;\n\tres->resumer = NULL;\n\tres->compile_ctx = NULL,\n#if defined(DUK_USE_HEAPPTR16)\n\tres->strs16 = NULL;\n#else\n\tres->strs = NULL;\n#endif\n\t{\n\t\tduk_small_uint_t i;\n\t\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\t\tres->builtins[i] = NULL;\n\t\t}\n\t}\n#endif\n\t/* When nothing is running, API calls are in non-strict mode. */\n\tDUK_ASSERT(res->strict == 0);\n\n\tres->heap = heap;\n\n\t/* XXX: Any reason not to merge duk_hthread_alloc.c here? */\n\treturn res;\n}\n\nDUK_INTERNAL duk_hthread *duk_hthread_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hthread *res;\n\n\tres = duk_hthread_alloc_unchecked(thr->heap, hobject_flags);\n\tif (res == NULL) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\treturn res;\n}\n\nDUK_INTERNAL duk_harray *duk_harray_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_harray *res;\n\n\tres = (duk_harray *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_harray));\n\n\tDUK_ASSERT(res->length == 0);\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hdecenv *duk_hdecenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hdecenv *res;\n\n\tres = (duk_hdecenv *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hdecenv));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->thread = NULL;\n\tres->varmap = NULL;\n#endif\n\n\tDUK_ASSERT(res->thread == NULL);\n\tDUK_ASSERT(res->varmap == NULL);\n\tDUK_ASSERT(res->regbase_byteoff == 0);\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hobjenv *duk_hobjenv_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hobjenv *res;\n\n\tres = (duk_hobjenv *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hobjenv));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tres->target = NULL;\n#endif\n\n\tDUK_ASSERT(res->target == NULL);\n\n\treturn res;\n}\n\nDUK_INTERNAL duk_hproxy *duk_hproxy_alloc(duk_hthread *thr, duk_uint_t hobject_flags) {\n\tduk_hproxy *res;\n\n\tres = (duk_hproxy *) duk__hobject_alloc_init(thr, hobject_flags, sizeof(duk_hproxy));\n\n\t/* Leave ->target and ->handler uninitialized, as caller will always\n\t * explicitly initialize them before any side effects are possible.\n\t */\n\n\treturn res;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hobject_assert.c",
    "content": "/*\n *  duk_hobject and subclass assertion helpers\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_ASSERTIONS)\n\nDUK_INTERNAL void duk_hobject_assert_valid(duk_hobject *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE(h) ||\n\t           DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FUNCTION);\n\tDUK_ASSERT(!DUK_HOBJECT_IS_BUFOBJ(h) ||\n\t           (DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAYBUFFER ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_DATAVIEW ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT8ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT8ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT8CLAMPEDARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT16ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT16ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_INT32ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_UINT32ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FLOAT32ARRAY ||\n\t            DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_FLOAT64ARRAY));\n\t/* Object is an Array <=> object has exotic array behavior */\n\tDUK_ASSERT((DUK_HOBJECT_GET_CLASS_NUMBER(h) == DUK_HOBJECT_CLASS_ARRAY && DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)) ||\n\t           (DUK_HOBJECT_GET_CLASS_NUMBER(h) != DUK_HOBJECT_CLASS_ARRAY && !DUK_HOBJECT_HAS_EXOTIC_ARRAY(h)));\n}\n\nDUK_INTERNAL void duk_harray_assert_valid(duk_harray *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) h));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY((duk_hobject *) h));\n}\n\nDUK_INTERNAL void duk_hboundfunc_assert_valid(duk_hboundfunc *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_BOUNDFUNC((duk_hobject *) h));\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(&h->target) ||\n\t           (DUK_TVAL_IS_OBJECT(&h->target) &&\n\t            DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(&h->target))));\n\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(&h->this_binding));\n\tDUK_ASSERT(h->nargs == 0 || h->args != NULL);\n}\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_INTERNAL void duk_hbufobj_assert_valid(duk_hbufobj *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(h->shift <= 3);\n\tDUK_ASSERT(h->elem_type <= DUK_HBUFOBJ_ELEM_MAX);\n\tDUK_ASSERT((h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT8) ||\n\t           (h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT8CLAMPED) ||\n\t           (h->shift == 0 && h->elem_type == DUK_HBUFOBJ_ELEM_INT8) ||\n\t           (h->shift == 1 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT16) ||\n\t           (h->shift == 1 && h->elem_type == DUK_HBUFOBJ_ELEM_INT16) ||\n\t           (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_UINT32) ||\n\t           (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_INT32) ||\n\t           (h->shift == 2 && h->elem_type == DUK_HBUFOBJ_ELEM_FLOAT32) ||\n\t           (h->shift == 3 && h->elem_type == DUK_HBUFOBJ_ELEM_FLOAT64));\n\tDUK_ASSERT(h->is_typedarray == 0 || h->is_typedarray == 1);\n\tDUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ((duk_hobject *) h));\n\tif (h->buf == NULL) {\n\t\tDUK_ASSERT(h->offset == 0);\n\t\tDUK_ASSERT(h->length == 0);\n\t} else {\n\t\t/* No assertions for offset or length; in particular,\n\t\t * it's OK for length to be longer than underlying\n\t\t * buffer.  Just ensure they don't wrap when added.\n\t\t */\n\t\tDUK_ASSERT(h->offset + h->length >= h->offset);\n\t}\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\nDUK_INTERNAL void duk_hcompfunc_assert_valid(duk_hcompfunc *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\nDUK_INTERNAL void duk_hnatfunc_assert_valid(duk_hnatfunc *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\nDUK_INTERNAL void duk_hdecenv_assert_valid(duk_hdecenv *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_DECENV((duk_hobject *) h));\n\tDUK_ASSERT(h->thread == NULL || h->varmap != NULL);\n}\n\nDUK_INTERNAL void duk_hobjenv_assert_valid(duk_hobjenv *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_OBJENV((duk_hobject *) h));\n\tDUK_ASSERT(h->target != NULL);\n\tDUK_ASSERT(h->has_this == 0 || h->has_this == 1);\n}\n\nDUK_INTERNAL void duk_hproxy_assert_valid(duk_hproxy *h) {\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(h->target != NULL);\n\tDUK_ASSERT(h->handler != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ((duk_hobject *) h));\n}\n\nDUK_INTERNAL void duk_hthread_assert_valid(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(DUK_HEAPHDR_GET_TYPE((duk_heaphdr *) thr) == DUK_HTYPE_OBJECT);\n\tDUK_ASSERT(DUK_HOBJECT_IS_THREAD((duk_hobject *) thr));\n\tDUK_ASSERT(thr->unused1 == 0);\n\tDUK_ASSERT(thr->unused2 == 0);\n}\n\nDUK_INTERNAL void duk_ctx_assert_valid(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_HTHREAD_ASSERT_VALID(thr);\n\tDUK_ASSERT(thr->valstack != NULL);\n\tDUK_ASSERT(thr->valstack_bottom != NULL);\n\tDUK_ASSERT(thr->valstack_top != NULL);\n\tDUK_ASSERT(thr->valstack_end != NULL);\n\tDUK_ASSERT(thr->valstack_alloc_end != NULL);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_alloc_end >= thr->valstack_end);\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hobject_class.c",
    "content": "/*\n *  Hobject ECMAScript [[Class]].\n */\n\n#include \"duk_internal.h\"\n\n#if (DUK_STRIDX_UC_ARGUMENTS > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_BOOLEAN > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_DATE > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_ERROR > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_FUNCTION > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_JSON > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_MATH > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_NUMBER > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_OBJECT > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_REG_EXP > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_STRING > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_GLOBAL > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_OBJ_ENV > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_DEC_ENV > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_POINTER > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UC_THREAD > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_ARRAY_BUFFER > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_DATA_VIEW > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_INT8_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT8_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT8_CLAMPED_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_INT16_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT16_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_INT32_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_UINT32_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_FLOAT32_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_FLOAT64_ARRAY > 255)\n#error constant too large\n#endif\n#if (DUK_STRIDX_EMPTY_STRING > 255)\n#error constant too large\n#endif\n\n/* Note: assumes that these string indexes are 8-bit, genstrings.py must ensure that */\nDUK_INTERNAL duk_uint8_t duk_class_number_to_stridx[32] = {\n\tDUK_STRIDX_EMPTY_STRING,  /* NONE, intentionally empty */\n\tDUK_STRIDX_UC_OBJECT,\n\tDUK_STRIDX_ARRAY,\n\tDUK_STRIDX_UC_FUNCTION,\n\tDUK_STRIDX_UC_ARGUMENTS,\n\tDUK_STRIDX_UC_BOOLEAN,\n\tDUK_STRIDX_DATE,\n\tDUK_STRIDX_UC_ERROR,\n\tDUK_STRIDX_JSON,\n\tDUK_STRIDX_MATH,\n\tDUK_STRIDX_UC_NUMBER,\n\tDUK_STRIDX_REG_EXP,\n\tDUK_STRIDX_UC_STRING,\n\tDUK_STRIDX_GLOBAL,\n\tDUK_STRIDX_UC_SYMBOL,\n\tDUK_STRIDX_OBJ_ENV,\n\tDUK_STRIDX_DEC_ENV,\n\tDUK_STRIDX_UC_POINTER,\n\tDUK_STRIDX_UC_THREAD,\n\tDUK_STRIDX_ARRAY_BUFFER,\n\tDUK_STRIDX_DATA_VIEW,\n\tDUK_STRIDX_INT8_ARRAY,\n\tDUK_STRIDX_UINT8_ARRAY,\n\tDUK_STRIDX_UINT8_CLAMPED_ARRAY,\n\tDUK_STRIDX_INT16_ARRAY,\n\tDUK_STRIDX_UINT16_ARRAY,\n\tDUK_STRIDX_INT32_ARRAY,\n\tDUK_STRIDX_UINT32_ARRAY,\n\tDUK_STRIDX_FLOAT32_ARRAY,\n\tDUK_STRIDX_FLOAT64_ARRAY,\n\tDUK_STRIDX_EMPTY_STRING,  /* UNUSED, intentionally empty */\n\tDUK_STRIDX_EMPTY_STRING,  /* UNUSED, intentionally empty */\n};\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hobject_enum.c",
    "content": "/*\n *  Object enumeration support.\n *\n *  Creates an internal enumeration state object to be used e.g. with for-in\n *  enumeration.  The state object contains a snapshot of target object keys\n *  and internal control state for enumeration.  Enumerator flags allow caller\n *  to e.g. request internal/non-enumerable properties, and to enumerate only\n *  \"own\" properties.\n *\n *  Also creates the result value for e.g. Object.keys() based on the same\n *  internal structure.\n *\n *  This snapshot-based enumeration approach is used to simplify enumeration:\n *  non-snapshot-based approaches are difficult to reconcile with mutating\n *  the enumeration target, running multiple long-lived enumerators at the\n *  same time, garbage collection details, etc.  The downside is that the\n *  enumerator object is memory inefficient especially for iterating arrays.\n */\n\n#include \"duk_internal.h\"\n\n/* XXX: identify enumeration target with an object index (not top of stack) */\n\n/* First enumerated key index in enumerator object, must match exactly the\n * number of control properties inserted to the enumerator.\n */\n#define DUK__ENUM_START_INDEX  2\n\n/* Current implementation suffices for ES2015 for now because there's no symbol\n * sorting, so commented out for now.\n */\n\n/*\n *  Helper to sort enumeration keys using a callback for pairwise duk_hstring\n *  comparisons.  The keys are in the enumeration object entry part, starting\n *  from DUK__ENUM_START_INDEX, and the entry part is dense.  Entry part values\n *  are all \"true\", e.g. \"1\" -> true, \"3\" -> true, \"foo\" -> true, \"2\" -> true,\n *  so it suffices to just switch keys without switching values.\n *\n *  ES2015 [[OwnPropertyKeys]] enumeration order for ordinary objects:\n *  (1) array indices in ascending order,\n *  (2) non-array-index keys in insertion order, and\n *  (3) symbols in insertion order.\n *  http://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys.\n *\n *  This rule is applied to \"own properties\" at each inheritance level;\n *  non-duplicate parent keys always follow child keys.  For example,\n *  an inherited array index will enumerate -after- a symbol in the\n *  child.\n *\n *  Insertion sort is used because (1) it's simple and compact, (2) works\n *  in-place, (3) minimizes operations if data is already nearly sorted,\n *  (4) doesn't reorder elements considered equal.\n *  http://en.wikipedia.org/wiki/Insertion_sort\n */\n\n/* Sort key, must hold array indices, \"not array index\" marker, and one more\n * higher value for symbols.\n */\n#if !defined(DUK_USE_SYMBOL_BUILTIN)\ntypedef duk_uint32_t duk__sort_key_t;\n#elif defined(DUK_USE_64BIT_OPS)\ntypedef duk_uint64_t duk__sort_key_t;\n#else\ntypedef duk_double_t duk__sort_key_t;\n#endif\n\n/* Get sort key for a duk_hstring. */\nDUK_LOCAL duk__sort_key_t duk__hstring_sort_key(duk_hstring *x) {\n\tduk__sort_key_t val;\n\n\t/* For array indices [0,0xfffffffe] use the array index as is.\n\t * For strings, use 0xffffffff, the marker 'arridx' already in\n\t * duk_hstring.  For symbols, any value above 0xffffffff works,\n\t * as long as it is the same for all symbols; currently just add\n\t * the masked flag field into the arridx temporary.\n\t */\n\tDUK_ASSERT(x != NULL);\n\tDUK_ASSERT(!DUK_HSTRING_HAS_SYMBOL(x) || DUK_HSTRING_GET_ARRIDX_FAST(x) == DUK_HSTRING_NO_ARRAY_INDEX);\n\n\tval = (duk__sort_key_t) DUK_HSTRING_GET_ARRIDX_FAST(x);\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\tval = val + (duk__sort_key_t) (DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) x) & DUK_HSTRING_FLAG_SYMBOL);\n#endif\n\n\treturn (duk__sort_key_t) val;\n}\n\n/* Insert element 'b' after element 'a'? */\nDUK_LOCAL duk_bool_t duk__sort_compare_es6(duk_hstring *a, duk_hstring *b, duk__sort_key_t val_b) {\n\tduk__sort_key_t val_a;\n\n\tDUK_ASSERT(a != NULL);\n\tDUK_ASSERT(b != NULL);\n\tDUK_UNREF(b);  /* Not actually needed now, val_b suffices. */\n\n\tval_a = duk__hstring_sort_key(a);\n\n\tif (val_a > val_b) {\n\t\treturn 0;\n\t} else {\n\t\treturn 1;\n\t}\n}\n\nDUK_LOCAL void duk__sort_enum_keys_es6(duk_hthread *thr, duk_hobject *h_obj, duk_int_fast32_t idx_start, duk_int_fast32_t idx_end) {\n\tduk_hstring **keys;\n\tduk_int_fast32_t idx;\n\n\tDUK_ASSERT(h_obj != NULL);\n\tDUK_ASSERT(idx_start >= DUK__ENUM_START_INDEX);\n\tDUK_ASSERT(idx_end >= idx_start);\n\tDUK_UNREF(thr);\n\n\tif (idx_end <= idx_start + 1) {\n\t\treturn;  /* Zero or one element(s). */\n\t}\n\n\tkeys = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, h_obj);\n\n\tfor (idx = idx_start + 1; idx < idx_end; idx++) {\n\t\tduk_hstring *h_curr;\n\t\tduk_int_fast32_t idx_insert;\n\t\tduk__sort_key_t val_curr;\n\n\t\th_curr = keys[idx];\n\t\tDUK_ASSERT(h_curr != NULL);\n\n\t\t/* Scan backwards for insertion place.  This works very well\n\t\t * when the elements are nearly in order which is the common\n\t\t * (and optimized for) case.\n\t\t */\n\n\t\tval_curr = duk__hstring_sort_key(h_curr);  /* Remains same during scanning. */\n\t\tfor (idx_insert = idx - 1; idx_insert >= idx_start; idx_insert--) {\n\t\t\tduk_hstring *h_insert;\n\t\t\th_insert = keys[idx_insert];\n\t\t\tDUK_ASSERT(h_insert != NULL);\n\n\t\t\tif (duk__sort_compare_es6(h_insert, h_curr, val_curr)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t/* If we're out of indices, idx_insert == idx_start - 1 and idx_insert++\n\t\t * brings us back to idx_start.\n\t\t */\n\t\tidx_insert++;\n\t\tDUK_ASSERT(idx_insert >= 0 && idx_insert <= idx);\n\n\t\t/*        .-- p_insert   .-- p_curr\n\t\t *        v              v\n\t\t *  | ... | insert | ... | curr\n\t\t */\n\n\t\t/* This could also done when the keys are in order, i.e.\n\t\t * idx_insert == idx.  The result would be an unnecessary\n\t\t * memmove() but we use an explicit check because the keys\n\t\t * are very often in order already.\n\t\t */\n\t\tif (idx != idx_insert) {\n\t\t\tduk_memmove((void *) (keys + idx_insert + 1),\n\t\t\t            (const void *) (keys + idx_insert),\n\t\t\t            ((size_t) (idx - idx_insert) * sizeof(duk_hstring *)));\n\t\t\tkeys[idx_insert] = h_curr;\n\t\t}\n\t}\n}\n\n/*\n *  Create an internal enumerator object E, which has its keys ordered\n *  to match desired enumeration ordering.  Also initialize internal control\n *  properties for enumeration.\n *\n *  Note: if an array was used to hold enumeration keys instead, an array\n *  scan would be needed to eliminate duplicates found in the prototype chain.\n */\n\nDUK_LOCAL void duk__add_enum_key(duk_hthread *thr, duk_hstring *k) {\n\t/* 'k' may be unreachable on entry so must push without any\n\t * potential for GC.\n\t */\n\tduk_push_hstring(thr, k);\n\tduk_push_true(thr);\n\tduk_put_prop(thr, -3);\n}\n\nDUK_LOCAL void duk__add_enum_key_stridx(duk_hthread *thr, duk_small_uint_t stridx) {\n\tduk__add_enum_key(thr, DUK_HTHREAD_GET_STRING(thr, stridx));\n}\n\nDUK_INTERNAL void duk_hobject_enumerator_create(duk_hthread *thr, duk_small_uint_t enum_flags) {\n\tduk_hobject *enum_target;\n\tduk_hobject *curr;\n\tduk_hobject *res;\n#if defined(DUK_USE_ES6_PROXY)\n\tduk_hobject *h_proxy_target;\n\tduk_hobject *h_proxy_handler;\n\tduk_hobject *h_trap_result;\n#endif\n\tduk_uint_fast32_t i, len;  /* used for array, stack, and entry indices */\n\tduk_uint_fast32_t sort_start_index;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tenum_target = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(enum_target != NULL);\n\n\tduk_push_bare_object(thr);\n\tres = duk_known_hobject(thr, -1);\n\n\t/* [enum_target res] */\n\n\t/* Target must be stored so that we can recheck whether or not\n\t * keys still exist when we enumerate.  This is not done if the\n\t * enumeration result comes from a proxy trap as there is no\n\t * real object to check against.\n\t */\n\tduk_push_hobject(thr, enum_target);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_TARGET);  /* Target is bare, plain put OK. */\n\n\t/* Initialize index so that we skip internal control keys. */\n\tduk_push_int(thr, DUK__ENUM_START_INDEX);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_NEXT);  /* Target is bare, plain put OK. */\n\n\t/*\n\t *  Proxy object handling\n\t */\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (DUK_LIKELY((enum_flags & DUK_ENUM_NO_PROXY_BEHAVIOR) != 0)) {\n\t\tgoto skip_proxy;\n\t}\n\tif (DUK_LIKELY(!duk_hobject_proxy_check(enum_target,\n\t                                        &h_proxy_target,\n\t                                        &h_proxy_handler))) {\n\t\tgoto skip_proxy;\n\t}\n\n\t/* XXX: share code with Object.keys() Proxy handling */\n\n\t/* In ES2015 for-in invoked the \"enumerate\" trap; in ES2016 \"enumerate\"\n\t * has been obsoleted and \"ownKeys\" is used instead.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"proxy enumeration\"));\n\tduk_push_hobject(thr, h_proxy_handler);\n\tif (!duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_OWN_KEYS)) {\n\t\t/* No need to replace the 'enum_target' value in stack, only the\n\t\t * enum_target reference.  This also ensures that the original\n\t\t * enum target is reachable, which keeps the proxy and the proxy\n\t\t * target reachable.  We do need to replace the internal _Target.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"no ownKeys trap, enumerate proxy target instead\"));\n\t\tDUK_DDD(DUK_DDDPRINT(\"h_proxy_target=%!O\", (duk_heaphdr *) h_proxy_target));\n\t\tenum_target = h_proxy_target;\n\n\t\tduk_push_hobject(thr, enum_target);  /* -> [ ... enum_target res handler undefined target ] */\n\t\tduk_put_prop_stridx_short(thr, -4, DUK_STRIDX_INT_TARGET);  /* Target is bare, plain put OK. */\n\n\t\tduk_pop_2(thr);  /* -> [ ... enum_target res ] */\n\t\tgoto skip_proxy;\n\t}\n\n\t/* [ ... enum_target res handler trap ] */\n\tduk_insert(thr, -2);\n\tduk_push_hobject(thr, h_proxy_target);    /* -> [ ... enum_target res trap handler target ] */\n\tduk_call_method(thr, 1 /*nargs*/);        /* -> [ ... enum_target res trap_result ] */\n\th_trap_result = duk_require_hobject(thr, -1);\n\tDUK_UNREF(h_trap_result);\n\n\tduk_proxy_ownkeys_postprocess(thr, h_proxy_target, enum_flags);\n\t/* -> [ ... enum_target res trap_result keys_array ] */\n\n\t/* Copy cleaned up trap result keys into the enumerator object. */\n\t/* XXX: result is a dense array; could make use of that. */\n\tDUK_ASSERT(duk_is_array(thr, -1));\n\tlen = (duk_uint_fast32_t) duk_get_length(thr, -1);\n\tfor (i = 0; i < len; i++) {\n\t\t(void) duk_get_prop_index(thr, -1, (duk_uarridx_t) i);\n\t\tDUK_ASSERT(duk_is_string(thr, -1));  /* postprocess cleaned up */\n\t\t/* [ ... enum_target res trap_result keys_array val ] */\n\t\tduk_push_true(thr);\n\t\t/* [ ... enum_target res trap_result keys_array val true ] */\n\t\tduk_put_prop(thr, -5);\n\t}\n\t/* [ ... enum_target res trap_result keys_array ] */\n\tduk_pop_2(thr);\n\tduk_remove_m2(thr);\n\n\t/* [ ... res ] */\n\n\t/* The internal _Target property is kept pointing to the original\n\t * enumeration target (the proxy object), so that the enumerator\n\t * 'next' operation can read property values if so requested.  The\n\t * fact that the _Target is a proxy disables key existence check\n\t * during enumeration.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"proxy enumeration, final res: %!O\", (duk_heaphdr *) res));\n\tgoto compact_and_return;\n\n skip_proxy:\n#endif  /* DUK_USE_ES6_PROXY */\n\n\tcurr = enum_target;\n\tsort_start_index = DUK__ENUM_START_INDEX;\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(res) == DUK__ENUM_START_INDEX);\n\twhile (curr) {\n\t\tduk_uint_fast32_t sort_end_index;\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\tduk_bool_t need_sort = 0;\n#endif\n\t\tduk_bool_t cond;\n\n\t\t/* Enumeration proceeds by inheritance level.  Virtual\n\t\t * properties need to be handled specially, followed by\n\t\t * array part, and finally entry part.\n\t\t *\n\t\t * If there are array index keys in the entry part or any\n\t\t * other risk of the ES2015 [[OwnPropertyKeys]] order being\n\t\t * violated, need_sort is set and an explicit ES2015 sort is\n\t\t * done for the inheritance level.\n\t\t */\n\n\t\t/* XXX: inheriting from proxy */\n\n\t\t/*\n\t\t *  Virtual properties.\n\t\t *\n\t\t *  String and buffer indices are virtual and always enumerable,\n\t\t *  'length' is virtual and non-enumerable.  Array and arguments\n\t\t *  object props have special behavior but are concrete.\n\t\t *\n\t\t *  String and buffer objects don't have an array part so as long\n\t\t *  as virtual array index keys are enumerated first, we don't\n\t\t *  need to set need_sort.\n\t\t */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tcond = DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr) || DUK_HOBJECT_IS_BUFOBJ(curr);\n#else\n\t\tcond = DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr);\n#endif\n\t\tcond = cond && !(enum_flags & DUK_ENUM_EXCLUDE_STRINGS);\n\t\tif (cond) {\n\t\t\tduk_bool_t have_length = 1;\n\n\t\t\t/* String and buffer enumeration behavior is identical now,\n\t\t\t * so use shared handler.\n\t\t\t */\n\t\t\tif (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(curr)) {\n\t\t\t\tduk_hstring *h_val;\n\t\t\t\th_val = duk_hobject_get_internal_value_string(thr->heap, curr);\n\t\t\t\tDUK_ASSERT(h_val != NULL);  /* string objects must not created without internal value */\n\t\t\t\tlen = (duk_uint_fast32_t) DUK_HSTRING_GET_CHARLEN(h_val);\n\t\t\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t\telse {\n\t\t\t\tduk_hbufobj *h_bufobj;\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_BUFOBJ(curr));\n\t\t\t\th_bufobj = (duk_hbufobj *) curr;\n\n\t\t\t\tif (h_bufobj == NULL || !h_bufobj->is_typedarray) {\n\t\t\t\t\t/* Zero length seems like a good behavior for neutered buffers.\n\t\t\t\t\t * ArrayBuffer (non-view) and DataView don't have index properties\n\t\t\t\t\t * or .length property.\n\t\t\t\t\t */\n\t\t\t\t\tlen = 0;\n\t\t\t\t\thave_length = 0;\n\t\t\t\t} else {\n\t\t\t\t\t/* There's intentionally no check for\n\t\t\t\t\t * current underlying buffer length.\n\t\t\t\t\t */\n\t\t\t\t\tlen = (duk_uint_fast32_t) (h_bufobj->length >> h_bufobj->shift);\n\t\t\t\t}\n\t\t\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\tduk_hstring *k;\n\n\t\t\t\t/* This is a bit fragile: the string is not\n\t\t\t\t * reachable until it is pushed by the helper.\n\t\t\t\t */\n\t\t\t\tk = duk_heap_strtable_intern_u32_checked(thr, (duk_uint32_t) i);\n\t\t\t\tDUK_ASSERT(k);\n\n\t\t\t\tduk__add_enum_key(thr, k);\n\n\t\t\t\t/* [enum_target res] */\n\t\t\t}\n\n\t\t\t/* 'length' and other virtual properties are not\n\t\t\t * enumerable, but are included if non-enumerable\n\t\t\t * properties are requested.\n\t\t\t */\n\n\t\t\tif (have_length && (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE)) {\n\t\t\t\tduk__add_enum_key_stridx(thr, DUK_STRIDX_LENGTH);\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t *  Array part\n\t\t */\n\n\t\tcond = !(enum_flags & DUK_ENUM_EXCLUDE_STRINGS);\n\t\tif (cond) {\n\t\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(curr); i++) {\n\t\t\t\tduk_hstring *k;\n\t\t\t\tduk_tval *tv;\n\n\t\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, curr, i);\n\t\t\t\tif (DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tk = duk_heap_strtable_intern_u32_checked(thr, (duk_uint32_t) i);  /* Fragile reachability. */\n\t\t\t\tDUK_ASSERT(k);\n\n\t\t\t\tduk__add_enum_key(thr, k);\n\n\t\t\t\t/* [enum_target res] */\n\t\t\t}\n\n\t\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(curr)) {\n\t\t\t\t/* Array .length comes after numeric indices. */\n\t\t\t\tif (enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) {\n\t\t\t\t\tduk__add_enum_key_stridx(thr, DUK_STRIDX_LENGTH);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t *  Entries part\n\t\t */\n\n\t\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(curr); i++) {\n\t\t\tduk_hstring *k;\n\n\t\t\tk = DUK_HOBJECT_E_GET_KEY(thr->heap, curr, i);\n\t\t\tif (!k) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!(enum_flags & DUK_ENUM_INCLUDE_NONENUMERABLE) &&\n\t\t\t    !DUK_HOBJECT_E_SLOT_IS_ENUMERABLE(thr->heap, curr, i)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(k))) {\n\t\t\t\tif (!(enum_flags & DUK_ENUM_INCLUDE_HIDDEN) &&\n\t\t\t\t    DUK_HSTRING_HAS_HIDDEN(k)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (!(enum_flags & DUK_ENUM_INCLUDE_SYMBOLS)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t\tneed_sort = 1;\n#endif\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(!DUK_HSTRING_HAS_HIDDEN(k));  /* would also have symbol flag */\n\t\t\t\tif (enum_flags & DUK_ENUM_EXCLUDE_STRINGS) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (DUK_HSTRING_HAS_ARRIDX(k)) {\n\t\t\t\t/* This in currently only possible if the\n\t\t\t\t * object has no array part: the array part\n\t\t\t\t * is exhaustive when it is present.\n\t\t\t\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t\tneed_sort = 1;\n#endif\n\t\t\t} else {\n\t\t\t\tif (enum_flags & DUK_ENUM_ARRAY_INDICES_ONLY) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, curr, i) ||\n\t\t\t           !DUK_TVAL_IS_UNUSED(&DUK_HOBJECT_E_GET_VALUE_PTR(thr->heap, curr, i)->v));\n\n\t\t\tduk__add_enum_key(thr, k);\n\n\t\t\t/* [enum_target res] */\n\t\t}\n\n\t\t/* Sort enumerated keys according to ES2015 requirements for\n\t\t * the \"inheritance level\" just processed.  This is far from\n\t\t * optimal, ES2015 semantics could be achieved more efficiently\n\t\t * by handling array index string keys (and symbol keys)\n\t\t * specially above in effect doing the sort inline.\n\t\t *\n\t\t * Skip the sort if array index sorting is requested because\n\t\t * we must consider all keys, also inherited, so an explicit\n\t\t * sort is done for the whole result after we're done with the\n\t\t * prototype chain.\n\t\t *\n\t\t * Also skip the sort if need_sort == 0, i.e. we know for\n\t\t * certain that the enumerated order is already correct.\n\t\t */\n\t\tsort_end_index = DUK_HOBJECT_GET_ENEXT(res);\n\n\t\tif (!(enum_flags & DUK_ENUM_SORT_ARRAY_INDICES)) {\n#if defined(DUK_USE_PREFER_SIZE)\n\t\t\tduk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) sort_start_index, (duk_int_fast32_t) sort_end_index);\n#else\n\t\t\tif (need_sort) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"need to sort\"));\n\t\t\t\tduk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) sort_start_index, (duk_int_fast32_t) sort_end_index);\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"no need to sort\"));\n\t\t\t}\n#endif\n\t\t}\n\n\t\tsort_start_index = sort_end_index;\n\n\t\tif (enum_flags & DUK_ENUM_OWN_PROPERTIES_ONLY) {\n\t\t\tbreak;\n\t\t}\n\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t}\n\n\t/* [enum_target res] */\n\n\tduk_remove_m2(thr);\n\n\t/* [res] */\n\n\tif (enum_flags & DUK_ENUM_SORT_ARRAY_INDICES) {\n\t\t/* Some E5/E5.1 algorithms require that array indices are iterated\n\t\t * in a strictly ascending order.  This is the case for e.g.\n\t\t * Array.prototype.forEach() and JSON.stringify() PropertyList\n\t\t * handling.  The caller can request an explicit sort in these\n\t\t * cases.\n\t\t */\n\n\t\t/* Sort to ES2015 order which works for pure array incides but\n\t\t * also for mixed keys.\n\t\t */\n\t\tduk__sort_enum_keys_es6(thr, res, (duk_int_fast32_t) DUK__ENUM_START_INDEX, (duk_int_fast32_t) DUK_HOBJECT_GET_ENEXT(res));\n\t}\n\n#if defined(DUK_USE_ES6_PROXY)\n compact_and_return:\n#endif\n\t/* compact; no need to seal because object is internal */\n\tduk_hobject_compact_props(thr, res);\n\n\tDUK_DDD(DUK_DDDPRINT(\"created enumerator object: %!iT\", (duk_tval *) duk_get_tval(thr, -1)));\n}\n\n/*\n *  Returns non-zero if a key and/or value was enumerated, and:\n *\n *   [enum] -> [key]        (get_value == 0)\n *   [enum] -> [key value]  (get_value == 1)\n *\n *  Returns zero without pushing anything on the stack otherwise.\n */\nDUK_INTERNAL duk_bool_t duk_hobject_enumerator_next(duk_hthread *thr, duk_bool_t get_value) {\n\tduk_hobject *e;\n\tduk_hobject *enum_target;\n\tduk_hstring *res = NULL;\n\tduk_uint_fast32_t idx;\n\tduk_bool_t check_existence;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* [... enum] */\n\n\te = duk_require_hobject(thr, -1);\n\n\t/* XXX use get tval ptr, more efficient */\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_INT_NEXT);\n\tidx = (duk_uint_fast32_t) duk_require_uint(thr, -1);\n\tduk_pop(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"enumeration: index is: %ld\", (long) idx));\n\n\t/* Enumeration keys are checked against the enumeration target (to see\n\t * that they still exist).  In the proxy enumeration case _Target will\n\t * be the proxy, and checking key existence against the proxy is not\n\t * required (or sensible, as the keys may be fully virtual).\n\t */\n\tduk_xget_owndataprop_stridx_short(thr, -1, DUK_STRIDX_INT_TARGET);\n\tenum_target = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(enum_target != NULL);\n#if defined(DUK_USE_ES6_PROXY)\n\tcheck_existence = (!DUK_HOBJECT_IS_PROXY(enum_target));\n#else\n\tcheck_existence = 1;\n#endif\n\tduk_pop(thr);  /* still reachable */\n\n\tDUK_DDD(DUK_DDDPRINT(\"getting next enum value, enum_target=%!iO, enumerator=%!iT\",\n\t                     (duk_heaphdr *) enum_target, (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/* no array part */\n\tfor (;;) {\n\t\tduk_hstring *k;\n\n\t\tif (idx >= DUK_HOBJECT_GET_ENEXT(e)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"enumeration: ran out of elements\"));\n\t\t\tbreak;\n\t\t}\n\n\t\t/* we know these because enum objects are internally created */\n\t\tk = DUK_HOBJECT_E_GET_KEY(thr->heap, e, idx);\n\t\tDUK_ASSERT(k != NULL);\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, e, idx));\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(&DUK_HOBJECT_E_GET_VALUE(thr->heap, e, idx).v));\n\n\t\tidx++;\n\n\t\t/* recheck that the property still exists */\n\t\tif (check_existence && !duk_hobject_hasprop_raw(thr, enum_target, k)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property deleted during enumeration, skip\"));\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"enumeration: found element, key: %!O\", (duk_heaphdr *) k));\n\t\tres = k;\n\t\tbreak;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"enumeration: updating next index to %ld\", (long) idx));\n\n\tduk_push_u32(thr, (duk_uint32_t) idx);\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_INT_NEXT);\n\n\t/* [... enum] */\n\n\tif (res) {\n\t\tduk_push_hstring(thr, res);\n\t\tif (get_value) {\n\t\t\tduk_push_hobject(thr, enum_target);\n\t\t\tduk_dup_m2(thr);       /* -> [... enum key enum_target key] */\n\t\t\tduk_get_prop(thr, -2); /* -> [... enum key enum_target val] */\n\t\t\tduk_remove_m2(thr);    /* -> [... enum key val] */\n\t\t\tduk_remove(thr, -3);   /* -> [... key val] */\n\t\t} else {\n\t\t\tduk_remove_m2(thr);    /* -> [... key] */\n\t\t}\n\t\treturn 1;\n\t} else {\n\t\tduk_pop(thr);  /* -> [...] */\n\t\treturn 0;\n\t}\n}\n\n/*\n *  Get enumerated keys in an ECMAScript array.  Matches Object.keys() behavior\n *  described in E5 Section 15.2.3.14.\n */\n\nDUK_INTERNAL duk_ret_t duk_hobject_get_enumerated_keys(duk_hthread *thr, duk_small_uint_t enum_flags) {\n\tduk_hobject *e;\n\tduk_hstring **keys;\n\tduk_tval *tv;\n\tduk_uint_fast32_t count;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(duk_get_hobject(thr, -1) != NULL);\n\n\t/* Create a temporary enumerator to get the (non-duplicated) key list;\n\t * the enumerator state is initialized without being needed, but that\n\t * has little impact.\n\t */\n\n\tduk_hobject_enumerator_create(thr, enum_flags);\n\te = duk_known_hobject(thr, -1);\n\n\t/* [enum_target enum res] */\n\n\t/* Create dense result array to exact size. */\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(e) >= DUK__ENUM_START_INDEX);\n\tcount = (duk_uint32_t) (DUK_HOBJECT_GET_ENEXT(e) - DUK__ENUM_START_INDEX);\n\n\t/* XXX: uninit would be OK */\n\ttv = duk_push_harray_with_size_outptr(thr, (duk_uint32_t) count);\n\tDUK_ASSERT(count == 0 || tv != NULL);\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\t/* Fill result array, no side effects. */\n\n\tkeys = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, e);\n\tkeys += DUK__ENUM_START_INDEX;\n\n\twhile (count-- > 0) {\n\t\tduk_hstring *k;\n\n\t\tk = *keys++;\n\t\tDUK_ASSERT(k != NULL);  /* enumerator must have no keys deleted */\n\n\t\tDUK_TVAL_SET_STRING(tv, k);\n\t\ttv++;\n\t\tDUK_HSTRING_INCREF(thr, k);\n\t}\n\n\t/* [enum_target enum res] */\n\tduk_remove_m2(thr);\n\n\t/* [enum_target res] */\n\n\treturn 1;  /* return 1 to allow callers to tail call */\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hobject_misc.c",
    "content": "/*\n *  Misc support functions\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL duk_bool_t duk_hobject_prototype_chain_contains(duk_hthread *thr, duk_hobject *h, duk_hobject *p, duk_bool_t ignore_loop) {\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* False if the object is NULL or the prototype 'p' is NULL.\n\t * In particular, false if both are NULL (don't compare equal).\n\t */\n\tif (h == NULL || p == NULL) {\n\t\treturn 0;\n\t}\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (h == p) {\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (sanity-- == 0) {\n\t\t\tif (ignore_loop) {\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\t\th = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\t} while (h);\n\n\treturn 0;\n}\n\nDUK_INTERNAL void duk_hobject_set_prototype_updref(duk_hthread *thr, duk_hobject *h, duk_hobject *p) {\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_hobject *tmp;\n\n\tDUK_ASSERT(h);\n\ttmp = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, h, p);\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, p);  /* avoid problems if p == h->prototype */\n\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);\n#else\n\tDUK_ASSERT(h);\n\tDUK_UNREF(thr);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, h, p);\n#endif\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hobject_pc2line.c",
    "content": "/*\n *  Helpers for creating and querying pc2line debug data, which\n *  converts a bytecode program counter to a source line number.\n *\n *  The run-time pc2line data is bit-packed, and documented in:\n *\n *    doc/function-objects.rst\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_PC2LINE)\n\n/* Generate pc2line data for an instruction sequence, leaving a buffer on stack top. */\nDUK_INTERNAL void duk_hobject_pc2line_pack(duk_hthread *thr, duk_compiler_instr *instrs, duk_uint_fast32_t length) {\n\tduk_hbuffer_dynamic *h_buf;\n\tduk_bitencoder_ctx be_ctx_alloc;\n\tduk_bitencoder_ctx *be_ctx = &be_ctx_alloc;\n\tduk_uint32_t *hdr;\n\tduk_size_t new_size;\n\tduk_uint_fast32_t num_header_entries;\n\tduk_uint_fast32_t curr_offset;\n\tduk_int_fast32_t curr_line, next_line, diff_line;\n\tduk_uint_fast32_t curr_pc;\n\tduk_uint_fast32_t hdr_index;\n\n\tDUK_ASSERT(length <= DUK_COMPILER_MAX_BYTECODE_LENGTH);\n\n\tnum_header_entries = (length + DUK_PC2LINE_SKIP - 1) / DUK_PC2LINE_SKIP;\n\tcurr_offset = (duk_uint_fast32_t) (sizeof(duk_uint32_t) + num_header_entries * sizeof(duk_uint32_t) * 2);\n\n\tduk_push_dynamic_buffer(thr, (duk_size_t) curr_offset);\n\th_buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, -1);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(h_buf) && !DUK_HBUFFER_HAS_EXTERNAL(h_buf));\n\n\thdr = (duk_uint32_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h_buf);\n\tDUK_ASSERT(hdr != NULL);\n\thdr[0] = (duk_uint32_t) length;  /* valid pc range is [0, length[ */\n\n\tcurr_pc = 0U;\n\twhile (curr_pc < length) {\n\t\tnew_size = (duk_size_t) (curr_offset + DUK_PC2LINE_MAX_DIFF_LENGTH);\n\t\tduk_hbuffer_resize(thr, h_buf, new_size);\n\n\t\thdr = (duk_uint32_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, h_buf);\n\t\tDUK_ASSERT(hdr != NULL);\n\t\tDUK_ASSERT(curr_pc < length);\n\t\thdr_index = 1 + (curr_pc / DUK_PC2LINE_SKIP) * 2;\n\t\tcurr_line = (duk_int_fast32_t) instrs[curr_pc].line;\n\t\thdr[hdr_index + 0] = (duk_uint32_t) curr_line;\n\t\thdr[hdr_index + 1] = (duk_uint32_t) curr_offset;\n\n#if 0\n\t\tDUK_DDD(DUK_DDDPRINT(\"hdr[%ld]: pc=%ld line=%ld offset=%ld\",\n\t\t                     (long) (curr_pc / DUK_PC2LINE_SKIP),\n\t\t                     (long) curr_pc,\n\t\t                     (long) hdr[hdr_index + 0],\n\t\t                     (long) hdr[hdr_index + 1]));\n#endif\n\n\t\tduk_memzero(be_ctx, sizeof(*be_ctx));\n\t\tbe_ctx->data = ((duk_uint8_t *) hdr) + curr_offset;\n\t\tbe_ctx->length = (duk_size_t) DUK_PC2LINE_MAX_DIFF_LENGTH;\n\n\t\tfor (;;) {\n\t\t\tcurr_pc++;\n\t\t\tif ( ((curr_pc % DUK_PC2LINE_SKIP) == 0) ||  /* end of diff run */\n\t\t\t     (curr_pc >= length) ) {                 /* end of bytecode */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_ASSERT(curr_pc < length);\n\t\t\tnext_line = (duk_int32_t) instrs[curr_pc].line;\n\t\t\tdiff_line = next_line - curr_line;\n\n#if 0\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"curr_line=%ld, next_line=%ld -> diff_line=%ld\",\n\t\t\t                     (long) curr_line, (long) next_line, (long) diff_line));\n#endif\n\n\t\t\tif (diff_line == 0) {\n\t\t\t\t/* 0 */\n\t\t\t\tduk_be_encode(be_ctx, 0, 1);\n\t\t\t} else if (diff_line >= 1 && diff_line <= 4) {\n\t\t\t\t/* 1 0 <2 bits> */\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) ((0x02 << 2) + (diff_line - 1)), 4);\n\t\t\t} else if (diff_line >= -0x80 && diff_line <= 0x7f) {\n\t\t\t\t/* 1 1 0 <8 bits> */\n\t\t\t\tDUK_ASSERT(diff_line + 0x80 >= 0 && diff_line + 0x80 <= 0xff);\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) ((0x06 << 8) + (diff_line + 0x80)), 11);\n\t\t\t} else {\n\t\t\t\t/* 1 1 1 <32 bits>\n\t\t\t\t * Encode in two parts to avoid bitencode 24-bit limitation\n\t\t\t\t */\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) ((0x07 << 16) + ((next_line >> 16) & 0xffff)), 19);\n\t\t\t\tduk_be_encode(be_ctx, (duk_uint32_t) (next_line & 0xffff), 16);\n\t\t\t}\n\n\t\t\tcurr_line = next_line;\n\t\t}\n\n\t\tduk_be_finish(be_ctx);\n\t\tDUK_ASSERT(!be_ctx->truncated);\n\n\t\t/* be_ctx->offset == length of encoded bitstream */\n\t\tcurr_offset += (duk_uint_fast32_t) be_ctx->offset;\n\t}\n\n\t/* compact */\n\tnew_size = (duk_size_t) curr_offset;\n\tduk_hbuffer_resize(thr, h_buf, new_size);\n\n\t(void) duk_to_fixed_buffer(thr, -1, NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"final pc2line data: pc_limit=%ld, length=%ld, %lf bits/opcode --> %!ixT\",\n\t                     (long) length, (long) new_size, (double) new_size * 8.0 / (double) length,\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n}\n\n/* PC is unsigned.  If caller does PC arithmetic and gets a negative result,\n * it will map to a large PC which is out of bounds and causes a zero to be\n * returned.\n */\nDUK_LOCAL duk_uint_fast32_t duk__hobject_pc2line_query_raw(duk_hthread *thr, duk_hbuffer_fixed *buf, duk_uint_fast32_t pc) {\n\tduk_bitdecoder_ctx bd_ctx_alloc;\n\tduk_bitdecoder_ctx *bd_ctx = &bd_ctx_alloc;\n\tduk_uint32_t *hdr;\n\tduk_uint_fast32_t start_offset;\n\tduk_uint_fast32_t pc_limit;\n\tduk_uint_fast32_t hdr_index;\n\tduk_uint_fast32_t pc_base;\n\tduk_uint_fast32_t n;\n\tduk_uint_fast32_t curr_line;\n\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) buf) && !DUK_HBUFFER_HAS_EXTERNAL((duk_hbuffer *) buf));\n\tDUK_UNREF(thr);\n\n\t/*\n\t *  Use the index in the header to find the right starting point\n\t */\n\n\thdr_index = pc / DUK_PC2LINE_SKIP;\n\tpc_base = hdr_index * DUK_PC2LINE_SKIP;\n\tn = pc - pc_base;\n\n\tif (DUK_HBUFFER_FIXED_GET_SIZE(buf) <= sizeof(duk_uint32_t)) {\n\t\tDUK_DD(DUK_DDPRINT(\"pc2line lookup failed: buffer is smaller than minimal header\"));\n\t\tgoto pc2line_error;\n\t}\n\n\thdr = (duk_uint32_t *) (void *) DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, buf);\n\tpc_limit = hdr[0];\n\tif (pc >= pc_limit) {\n\t\t/* Note: pc is unsigned and cannot be negative */\n\t\tDUK_DD(DUK_DDPRINT(\"pc2line lookup failed: pc out of bounds (pc=%ld, limit=%ld)\",\n\t\t                   (long) pc, (long) pc_limit));\n\t\tgoto pc2line_error;\n\t}\n\n\tcurr_line = hdr[1 + hdr_index * 2];\n\tstart_offset = hdr[1 + hdr_index * 2 + 1];\n\tif ((duk_size_t) start_offset > DUK_HBUFFER_FIXED_GET_SIZE(buf)) {\n\t\tDUK_DD(DUK_DDPRINT(\"pc2line lookup failed: start_offset out of bounds (start_offset=%ld, buffer_size=%ld)\",\n\t\t                   (long) start_offset, (long) DUK_HBUFFER_GET_SIZE((duk_hbuffer *) buf)));\n\t\tgoto pc2line_error;\n\t}\n\n\t/*\n\t *  Iterate the bitstream (line diffs) until PC is reached\n\t */\n\n\tduk_memzero(bd_ctx, sizeof(*bd_ctx));\n\tbd_ctx->data = ((duk_uint8_t *) hdr) + start_offset;\n\tbd_ctx->length = (duk_size_t) (DUK_HBUFFER_FIXED_GET_SIZE(buf) - start_offset);\n\n#if 0\n\tDUK_DDD(DUK_DDDPRINT(\"pc2line lookup: pc=%ld -> hdr_index=%ld, pc_base=%ld, n=%ld, start_offset=%ld\",\n\t                     (long) pc, (long) hdr_index, (long) pc_base, (long) n, (long) start_offset));\n#endif\n\n\twhile (n > 0) {\n#if 0\n\t\tDUK_DDD(DUK_DDDPRINT(\"lookup: n=%ld, curr_line=%ld\", (long) n, (long) curr_line));\n#endif\n\n\t\tif (duk_bd_decode_flag(bd_ctx)) {\n\t\t\tif (duk_bd_decode_flag(bd_ctx)) {\n\t\t\t\tif (duk_bd_decode_flag(bd_ctx)) {\n\t\t\t\t\t/* 1 1 1 <32 bits> */\n\t\t\t\t\tduk_uint_fast32_t t;\n\t\t\t\t\tt = duk_bd_decode(bd_ctx, 16);  /* workaround: max nbits = 24 now */\n\t\t\t\t\tt = (t << 16) + duk_bd_decode(bd_ctx, 16);\n\t\t\t\t\tcurr_line = t;\n\t\t\t\t} else {\n\t\t\t\t\t/* 1 1 0 <8 bits> */\n\t\t\t\t\tduk_uint_fast32_t t;\n\t\t\t\t\tt = duk_bd_decode(bd_ctx, 8);\n\t\t\t\t\tcurr_line = curr_line + t - 0x80;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* 1 0 <2 bits> */\n\t\t\t\tduk_uint_fast32_t t;\n\t\t\t\tt = duk_bd_decode(bd_ctx, 2);\n\t\t\t\tcurr_line = curr_line + t + 1;\n\t\t\t}\n\t\t} else {\n\t\t\t/* 0: no change */\n\t\t}\n\n\t\tn--;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"pc2line lookup result: pc %ld -> line %ld\", (long) pc, (long) curr_line));\n\treturn curr_line;\n\n pc2line_error:\n\tDUK_D(DUK_DPRINT(\"pc2line conversion failed for pc=%ld\", (long) pc));\n\treturn 0;\n}\n\nDUK_INTERNAL duk_uint_fast32_t duk_hobject_pc2line_query(duk_hthread *thr, duk_idx_t idx_func, duk_uint_fast32_t pc) {\n\tduk_hbuffer_fixed *pc2line;\n\tduk_uint_fast32_t line;\n\n\t/* XXX: now that pc2line is used by the debugger quite heavily in\n\t * checked execution, this should be optimized to avoid value stack\n\t * and perhaps also implement some form of pc2line caching (see\n\t * future work in debugger.rst).\n\t */\n\n\tduk_xget_owndataprop_stridx_short(thr, idx_func, DUK_STRIDX_INT_PC2LINE);\n\tpc2line = (duk_hbuffer_fixed *) (void *) duk_get_hbuffer(thr, -1);\n\tif (pc2line != NULL) {\n\t\tDUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC((duk_hbuffer *) pc2line) && !DUK_HBUFFER_HAS_EXTERNAL((duk_hbuffer *) pc2line));\n\t\tline = duk__hobject_pc2line_query_raw(thr, pc2line, (duk_uint_fast32_t) pc);\n\t} else {\n\t\tline = 0;\n\t}\n\tduk_pop(thr);\n\n\treturn line;\n}\n\n#endif  /* DUK_USE_PC2LINE */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hobject_props.c",
    "content": "/*\n *  duk_hobject property access functionality.\n *\n *  This is very central functionality for size, performance, and compliance.\n *  It is also rather intricate; see hobject-algorithms.rst for discussion on\n *  the algorithms and memory-management.rst for discussion on refcounts and\n *  side effect issues.\n *\n *  Notes:\n *\n *    - It might be tempting to assert \"refcount nonzero\" for objects\n *      being operated on, but that's not always correct: objects with\n *      a zero refcount may be operated on by the refcount implementation\n *      (finalization) for instance.  Hence, no refcount assertions are made.\n *\n *    - Many operations (memory allocation, identifier operations, etc)\n *      may cause arbitrary side effects (e.g. through GC and finalization).\n *      These side effects may invalidate duk_tval pointers which point to\n *      areas subject to reallocation (like value stack).  Heap objects\n *      themselves have stable pointers.  Holding heap object pointers or\n *      duk_tval copies is not problematic with respect to side effects;\n *      care must be taken when holding and using argument duk_tval pointers.\n *\n *    - If a finalizer is executed, it may operate on the the same object\n *      we're currently dealing with.  For instance, the finalizer might\n *      delete a certain property which has already been looked up and\n *      confirmed to exist.  Ideally finalizers would be disabled if GC\n *      happens during property access.  At the moment property table realloc\n *      disables finalizers, and all DECREFs may cause arbitrary changes so\n *      handle DECREF carefully.\n *\n *    - The order of operations for a DECREF matters.  When DECREF is executed,\n *      the entire object graph must be consistent; note that a refzero may\n *      lead to a mark-and-sweep through a refcount finalizer.  Use NORZ macros\n *      and an explicit DUK_REFZERO_CHECK_xxx() if achieving correct order is hard.\n */\n\n/*\n *  XXX: array indices are mostly typed as duk_uint32_t here; duk_uarridx_t\n *  might be more appropriate.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Local defines\n */\n\n#define DUK__NO_ARRAY_INDEX             DUK_HSTRING_NO_ARRAY_INDEX\n\n/* Marker values for hash part. */\n#define DUK__HASH_UNUSED                DUK_HOBJECT_HASHIDX_UNUSED\n#define DUK__HASH_DELETED               DUK_HOBJECT_HASHIDX_DELETED\n\n/* Valstack space that suffices for all local calls, excluding any recursion\n * into ECMAScript or Duktape/C calls (Proxy, getters, etc).\n */\n#define DUK__VALSTACK_SPACE             10\n\n/* Valstack space allocated especially for proxy lookup which does a\n * recursive property lookup.\n */\n#define DUK__VALSTACK_PROXY_LOOKUP      20\n\n/*\n *  Local prototypes\n */\n\nDUK_LOCAL_DECL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc);\nDUK_LOCAL_DECL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc, duk_bool_t throw_flag);\nDUK_LOCAL_DECL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc);\n\nDUK_LOCAL_DECL duk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr, duk_hobject *obj, duk_uint32_t old_len, duk_uint32_t new_len, duk_bool_t force_flag, duk_uint32_t *out_result_len);\nDUK_LOCAL_DECL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject *obj);\n\nDUK_LOCAL_DECL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags);\nDUK_LOCAL_DECL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_uint32_t arr_idx, duk_propdesc *out_desc, duk_small_uint_t flags);\n\nDUK_LOCAL_DECL void duk__abandon_array_part(duk_hthread *thr, duk_hobject *obj);\nDUK_LOCAL_DECL void duk__grow_props_for_array_item(duk_hthread *thr, duk_hobject *obj, duk_uint32_t highest_arr_idx);\n\n/*\n *  Misc helpers\n */\n\n/* Convert a duk_tval number (caller checks) to a 32-bit index.  Returns\n * DUK__NO_ARRAY_INDEX if the number is not whole or not a valid array\n * index.\n */\n/* XXX: for fastints, could use a variant which assumes a double duk_tval\n * (and doesn't need to check for fastint again).\n */\nDUK_LOCAL duk_uint32_t duk__tval_number_to_arr_idx(duk_tval *tv) {\n\tduk_double_t dbl;\n\tduk_uint32_t idx;\n\n\tDUK_ASSERT(tv != NULL);\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\n\t/* -0 is accepted here as index 0 because ToString(-0) == \"0\" which is\n\t * in canonical form and thus an array index.\n\t */\n\tdbl = DUK_TVAL_GET_NUMBER(tv);\n\tidx = (duk_uint32_t) dbl;\n\tif ((duk_double_t) idx == dbl) {\n\t        /* Is whole and within 32 bit range.  If the value happens to be 0xFFFFFFFF,\n\t\t * it's not a valid array index but will then match DUK__NO_ARRAY_INDEX.\n\t\t */\n\t\treturn idx;\n\t}\n\treturn DUK__NO_ARRAY_INDEX;\n}\n\n#if defined(DUK_USE_FASTINT)\n/* Convert a duk_tval fastint (caller checks) to a 32-bit index. */\nDUK_LOCAL duk_uint32_t duk__tval_fastint_to_arr_idx(duk_tval *tv) {\n\tduk_int64_t t;\n\n\tDUK_ASSERT(tv != NULL);\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\n\tt = DUK_TVAL_GET_FASTINT(tv);\n\tif (((duk_uint64_t) t & ~DUK_U64_CONSTANT(0xffffffff)) != 0) {\n\t\t/* Catches >0x100000000 and negative values. */\n\t\treturn DUK__NO_ARRAY_INDEX;\n\t}\n\n\t/* If the value happens to be 0xFFFFFFFF, it's not a valid array index\n\t * but will then match DUK__NO_ARRAY_INDEX.\n\t */\n\treturn (duk_uint32_t) t;\n}\n#endif  /* DUK_USE_FASTINT */\n\n/* Convert a duk_tval on the value stack (in a trusted index we don't validate)\n * to a string or symbol using ES2015 ToPropertyKey():\n * http://www.ecma-international.org/ecma-262/6.0/#sec-topropertykey.\n *\n * Also check if it's a valid array index and return that (or DUK__NO_ARRAY_INDEX\n * if not).\n */\nDUK_LOCAL duk_uint32_t duk__to_property_key(duk_hthread *thr, duk_idx_t idx, duk_hstring **out_h) {\n\tduk_uint32_t arr_idx;\n\tduk_hstring *h;\n\tduk_tval *tv_dst;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(out_h != NULL);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx));\n\tDUK_ASSERT(idx < 0);\n\n\t/* XXX: The revised ES2015 ToPropertyKey() handling (ES5.1 was just\n\t * ToString()) involves a ToPrimitive(), a symbol check, and finally\n\t * a ToString().  Figure out the best way to have a good fast path\n\t * but still be compliant and share code.\n\t */\n\n\ttv_dst = DUK_GET_TVAL_NEGIDX(thr, idx);  /* intentionally unvalidated */\n\tif (DUK_TVAL_IS_STRING(tv_dst)) {\n\t\t/* Most important path: strings and plain symbols are used as\n\t\t * is.  For symbols the array index check below is unnecessary\n\t\t * (they're never valid array indices) but checking that the\n\t\t * string is a symbol would make the plain string path slower\n\t\t * unnecessarily.\n\t\t */\n\t\th = DUK_TVAL_GET_STRING(tv_dst);\n\t} else {\n\t\th = duk_to_property_key_hstring(thr, idx);\n\t}\n\tDUK_ASSERT(h != NULL);\n\t*out_h = h;\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_FAST(h);\n\treturn arr_idx;\n}\n\nDUK_LOCAL duk_uint32_t duk__push_tval_to_property_key(duk_hthread *thr, duk_tval *tv_key, duk_hstring **out_h) {\n\tduk_push_tval(thr, tv_key);  /* XXX: could use an unsafe push here */\n\treturn duk__to_property_key(thr, -1, out_h);\n}\n\n/* String is an own (virtual) property of a plain buffer. */\nDUK_LOCAL duk_bool_t duk__key_is_plain_buf_ownprop(duk_hthread *thr, duk_hbuffer *buf, duk_hstring *key, duk_uint32_t arr_idx) {\n\tDUK_UNREF(thr);\n\n\t/* Virtual index properties.  Checking explicitly for\n\t * 'arr_idx != DUK__NO_ARRAY_INDEX' is not necessary\n\t * because DUK__NO_ARRAY_INDEXi is always larger than\n\t * maximum allowed buffer size.\n\t */\n\tDUK_ASSERT(DUK__NO_ARRAY_INDEX >= DUK_HBUFFER_GET_SIZE(buf));\n\tif (arr_idx < DUK_HBUFFER_GET_SIZE(buf)) {\n\t\treturn 1;\n\t}\n\n\t/* Other virtual properties. */\n\treturn (key == DUK_HTHREAD_STRING_LENGTH(thr));\n}\n\n/*\n *  Helpers for managing property storage size\n */\n\n/* Get default hash part size for a certain entry part size. */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\nDUK_LOCAL duk_uint32_t duk__get_default_h_size(duk_uint32_t e_size) {\n\tDUK_ASSERT(e_size <= DUK_HOBJECT_MAX_PROPERTIES);\n\n\tif (e_size >= DUK_USE_HOBJECT_HASH_PROP_LIMIT) {\n\t\tduk_uint32_t res;\n\t\tduk_uint32_t tmp;\n\n\t\t/* Hash size should be 2^N where N is chosen so that 2^N is\n\t\t * larger than e_size.  Extra shifting is used to ensure hash\n\t\t * is relatively sparse.\n\t\t */\n\t\ttmp = e_size;\n\t\tres = 2;  /* Result will be 2 ** (N + 1). */\n\t\twhile (tmp >= 0x40) {\n\t\t\ttmp >>= 6;\n\t\t\tres <<= 6;\n\t\t}\n\t\twhile (tmp != 0) {\n\t\t\ttmp >>= 1;\n\t\t\tres <<= 1;\n\t\t}\n\t\tDUK_ASSERT((DUK_HOBJECT_MAX_PROPERTIES << 2U) > DUK_HOBJECT_MAX_PROPERTIES);  /* Won't wrap, even shifted by 2. */\n\t\tDUK_ASSERT(res > e_size);\n\t\treturn res;\n\t} else {\n\t\treturn 0;\n\t}\n}\n#endif  /* USE_PROP_HASH_PART */\n\n/* Get minimum entry part growth for a certain size. */\nDUK_LOCAL duk_uint32_t duk__get_min_grow_e(duk_uint32_t e_size) {\n\tduk_uint32_t res;\n\n\tres = (e_size + DUK_USE_HOBJECT_ENTRY_MINGROW_ADD) / DUK_USE_HOBJECT_ENTRY_MINGROW_DIVISOR;\n\tDUK_ASSERT(res >= 1);  /* important for callers */\n\treturn res;\n}\n\n/* Get minimum array part growth for a certain size. */\nDUK_LOCAL duk_uint32_t duk__get_min_grow_a(duk_uint32_t a_size) {\n\tduk_uint32_t res;\n\n\tres = (a_size + DUK_USE_HOBJECT_ARRAY_MINGROW_ADD) / DUK_USE_HOBJECT_ARRAY_MINGROW_DIVISOR;\n\tDUK_ASSERT(res >= 1);  /* important for callers */\n\treturn res;\n}\n\n/* Count actually used entry part entries (non-NULL keys). */\nDUK_LOCAL duk_uint32_t duk__count_used_e_keys(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint_fast32_t i;\n\tduk_uint_fast32_t n = 0;\n\tduk_hstring **e;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(thr);\n\n\te = DUK_HOBJECT_E_GET_KEY_BASE(thr->heap, obj);\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tif (*e++) {\n\t\t\tn++;\n\t\t}\n\t}\n\treturn (duk_uint32_t) n;\n}\n\n/* Count actually used array part entries and array minimum size.\n * NOTE: 'out_min_size' can be computed much faster by starting from the\n * end and breaking out early when finding first used entry, but this is\n * not needed now.\n */\nDUK_LOCAL void duk__compute_a_stats(duk_hthread *thr, duk_hobject *obj, duk_uint32_t *out_used, duk_uint32_t *out_min_size) {\n\tduk_uint_fast32_t i;\n\tduk_uint_fast32_t used = 0;\n\tduk_uint_fast32_t highest_idx = (duk_uint_fast32_t) -1;  /* see below */\n\tduk_tval *a;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(out_used != NULL);\n\tDUK_ASSERT(out_min_size != NULL);\n\tDUK_UNREF(thr);\n\n\ta = DUK_HOBJECT_A_GET_BASE(thr->heap, obj);\n\tfor (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\tduk_tval *tv = a++;\n\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\tused++;\n\t\t\thighest_idx = i;\n\t\t}\n\t}\n\n\t/* Initial value for highest_idx is -1 coerced to unsigned.  This\n\t * is a bit odd, but (highest_idx + 1) will then wrap to 0 below\n\t * for out_min_size as intended.\n\t */\n\n\t*out_used = (duk_uint32_t) used;\n\t*out_min_size = (duk_uint32_t) (highest_idx + 1);  /* 0 if no used entries */\n}\n\n/* Check array density and indicate whether or not the array part should be abandoned. */\nDUK_LOCAL duk_bool_t duk__abandon_array_density_check(duk_uint32_t a_used, duk_uint32_t a_size) {\n\t/*\n\t *  Array abandon check; abandon if:\n\t *\n\t *    new_used / new_size < limit\n\t *    new_used < limit * new_size        || limit is 3 bits fixed point\n\t *    new_used < limit' / 8 * new_size   || *8\n\t *    8*new_used < limit' * new_size     || :8\n\t *    new_used < limit' * (new_size / 8)\n\t *\n\t *  Here, new_used = a_used, new_size = a_size.\n\t *\n\t *  Note: some callers use approximate values for a_used and/or a_size\n\t *  (e.g. dropping a '+1' term).  This doesn't affect the usefulness\n\t *  of the check, but may confuse debugging.\n\t */\n\n\treturn (a_used < DUK_USE_HOBJECT_ARRAY_ABANDON_LIMIT * (a_size >> 3));\n}\n\n/* Fast check for extending array: check whether or not a slow density check is required. */\nDUK_LOCAL duk_bool_t duk__abandon_array_slow_check_required(duk_uint32_t arr_idx, duk_uint32_t old_size) {\n\t/*\n\t *  In a fast check we assume old_size equals old_used (i.e., existing\n\t *  array is fully dense).\n\t *\n\t *  Slow check if:\n\t *\n\t *    (new_size - old_size) / old_size > limit\n\t *    new_size - old_size > limit * old_size\n\t *    new_size > (1 + limit) * old_size        || limit' is 3 bits fixed point\n\t *    new_size > (1 + (limit' / 8)) * old_size || * 8\n\t *    8 * new_size > (8 + limit') * old_size   || : 8\n\t *    new_size > (8 + limit') * (old_size / 8)\n\t *    new_size > limit'' * (old_size / 8)      || limit'' = 9 -> max 25% increase\n\t *    arr_idx + 1 > limit'' * (old_size / 8)\n\t *\n\t *  This check doesn't work well for small values, so old_size is rounded\n\t *  up for the check (and the '+ 1' of arr_idx can be ignored in practice):\n\t *\n\t *    arr_idx > limit'' * ((old_size + 7) / 8)\n\t */\n\n\treturn (arr_idx > DUK_USE_HOBJECT_ARRAY_FAST_RESIZE_LIMIT * ((old_size + 7) >> 3));\n}\n\nDUK_LOCAL duk_bool_t duk__abandon_array_check(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) {\n\tduk_uint32_t min_size;\n\tduk_uint32_t old_used;\n\tduk_uint32_t old_size;\n\n\tif (!duk__abandon_array_slow_check_required(arr_idx, DUK_HOBJECT_GET_ASIZE(obj))) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"=> fast resize is OK\"));\n\t\treturn 0;\n\t}\n\n\tduk__compute_a_stats(thr, obj, &old_used, &old_size);\n\n\tDUK_DDD(DUK_DDDPRINT(\"abandon check, array stats: old_used=%ld, old_size=%ld, arr_idx=%ld\",\n\t                     (long) old_used, (long) old_size, (long) arr_idx));\n\n\tmin_size = arr_idx + 1;\n#if defined(DUK_USE_OBJSIZES16)\n\tif (min_size > DUK_UINT16_MAX) {\n\t\tgoto do_abandon;\n\t}\n#endif\n\tDUK_UNREF(min_size);\n\n\t/* Note: intentionally use approximations to shave a few instructions:\n\t *   a_used = old_used  (accurate: old_used + 1)\n\t *   a_size = arr_idx   (accurate: arr_idx + 1)\n\t */\n\tif (duk__abandon_array_density_check(old_used, arr_idx)) {\n\t\tDUK_DD(DUK_DDPRINT(\"write to new array entry beyond current length, \"\n\t\t                   \"decided to abandon array part (would become too sparse)\"));\n\n\t\t/* Abandoning requires a props allocation resize and\n\t\t * 'rechecks' the valstack, invalidating any existing\n\t\t * valstack value pointers.\n\t\t */\n\t\tgoto do_abandon;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"=> decided to keep array part\"));\n\treturn 0;\n\n do_abandon:\n\tduk__abandon_array_part(thr, obj);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\treturn 1;\n}\n\nDUK_LOCAL duk_tval *duk__obtain_arridx_slot_slowpath(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) {\n\t/*\n\t *  Array needs to grow, but we don't want it becoming too sparse.\n\t *  If it were to become sparse, abandon array part, moving all\n\t *  array entries into the entries part (for good).\n\t *\n\t *  Since we don't keep track of actual density (used vs. size) of\n\t *  the array part, we need to estimate somehow.  The check is made\n\t *  in two parts:\n\t *\n\t *    - Check whether the resize need is small compared to the\n\t *      current size (relatively); if so, resize without further\n\t *      checking (essentially we assume that the original part is\n\t *      \"dense\" so that the result would be dense enough).\n\t *\n\t *    - Otherwise, compute the resize using an actual density\n\t *      measurement based on counting the used array entries.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"write to new array requires array resize, decide whether to do a \"\n\t                     \"fast resize without abandon check (arr_idx=%ld, old_size=%ld)\",\n\t                     (long) arr_idx, (long) DUK_HOBJECT_GET_ASIZE(obj)));\n\n\tif (DUK_UNLIKELY(duk__abandon_array_check(thr, arr_idx, obj) != 0)) {\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\treturn NULL;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"write to new array entry beyond current length, \"\n\t                   \"decided to extend current allocation\"));\n\n\t/* In principle it's possible to run out of memory extending the\n\t * array but with the allocation going through if we were to abandon\n\t * the array part and try again.  In practice this should be rare\n\t * because abandoned arrays have a higher per-entry footprint.\n\t */\n\n\tduk__grow_props_for_array_item(thr, obj, arr_idx);\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\tDUK_ASSERT(arr_idx < DUK_HOBJECT_GET_ASIZE(obj));\n\treturn DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n}\n\nDUK_LOCAL DUK_INLINE duk_tval *duk__obtain_arridx_slot(duk_hthread *thr, duk_uint32_t arr_idx, duk_hobject *obj) {\n\tif (DUK_LIKELY(arr_idx < DUK_HOBJECT_GET_ASIZE(obj))) {\n\t\treturn DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n\t} else {\n\t\treturn duk__obtain_arridx_slot_slowpath(thr, arr_idx, obj);\n\t}\n}\n\n/*\n *  Proxy helpers\n */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL duk_bool_t duk_hobject_proxy_check(duk_hobject *obj, duk_hobject **out_target, duk_hobject **out_handler) {\n\tduk_hproxy *h_proxy;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(out_target != NULL);\n\tDUK_ASSERT(out_handler != NULL);\n\n\t/* Caller doesn't need to check exotic proxy behavior (but does so for\n\t * some fast paths).\n\t */\n\tif (DUK_LIKELY(!DUK_HOBJECT_IS_PROXY(obj))) {\n\t\treturn 0;\n\t}\n\th_proxy = (duk_hproxy *) obj;\n\tDUK_HPROXY_ASSERT_VALID(h_proxy);\n\n\tDUK_ASSERT(h_proxy->handler != NULL);\n\tDUK_ASSERT(h_proxy->target != NULL);\n\t*out_handler = h_proxy->handler;\n\t*out_target = h_proxy->target;\n\n\treturn 1;\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n/* Get Proxy target object.  If the argument is not a Proxy, return it as is.\n * If a Proxy is revoked, an error is thrown.\n */\n#if defined(DUK_USE_ES6_PROXY)\nDUK_INTERNAL duk_hobject *duk_hobject_resolve_proxy_target(duk_hobject *obj) {\n\tDUK_ASSERT(obj != NULL);\n\n\t/* Resolve Proxy targets until Proxy chain ends.  No explicit check for\n\t * a Proxy loop: user code cannot create such a loop (it would only be\n\t * possible by editing duk_hproxy references directly).\n\t */\n\n\twhile (DUK_HOBJECT_IS_PROXY(obj)) {\n\t\tduk_hproxy *h_proxy;\n\n\t\th_proxy = (duk_hproxy *) obj;\n\t\tDUK_HPROXY_ASSERT_VALID(h_proxy);\n\t\tobj = h_proxy->target;\n\t\tDUK_ASSERT(obj != NULL);\n\t}\n\n\tDUK_ASSERT(obj != NULL);\n\treturn obj;\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_LOCAL duk_bool_t duk__proxy_check_prop(duk_hthread *thr, duk_hobject *obj, duk_small_uint_t stridx_trap, duk_tval *tv_key, duk_hobject **out_target) {\n\tduk_hobject *h_handler;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\tDUK_ASSERT(out_target != NULL);\n\n\tif (!duk_hobject_proxy_check(obj, out_target, &h_handler)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(*out_target != NULL);\n\tDUK_ASSERT(h_handler != NULL);\n\n\t/* XXX: At the moment Duktape accesses internal keys like _Finalizer using a\n\t * normal property set/get which would allow a proxy handler to interfere with\n\t * such behavior and to get access to internal key strings.  This is not a problem\n\t * as such because internal key strings can be created in other ways too (e.g.\n\t * through buffers).  The best fix is to change Duktape internal lookups to\n\t * skip proxy behavior.  Until that, internal property accesses bypass the\n\t * proxy and are applied to the target (as if the handler did not exist).\n\t * This has some side effects, see test-bi-proxy-internal-keys.js.\n\t */\n\n\tif (DUK_TVAL_IS_STRING(tv_key)) {\n\t\tduk_hstring *h_key = (duk_hstring *) DUK_TVAL_GET_STRING(tv_key);\n\t\tDUK_ASSERT(h_key != NULL);\n\t\tif (DUK_HSTRING_HAS_HIDDEN(h_key)) {\n\t\t\t/* Symbol accesses must go through proxy lookup in ES2015.\n\t\t\t * Hidden symbols behave like Duktape 1.x internal keys\n\t\t\t * and currently won't.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"hidden key, skip proxy handler and apply to target\"));\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* The handler is looked up with a normal property lookup; it may be an\n\t * accessor or the handler object itself may be a proxy object.  If the\n\t * handler is a proxy, we need to extend the valstack as we make a\n\t * recursive proxy check without a function call in between (in fact\n\t * there is no limit to the potential recursion here).\n\t *\n\t * (For sanity, proxy creation rejects another proxy object as either\n\t * the handler or the target at the moment so recursive proxy cases\n\t * are not realized now.)\n\t */\n\n\t/* XXX: C recursion limit if proxies are allowed as handler/target values */\n\n\tduk_require_stack(thr, DUK__VALSTACK_PROXY_LOOKUP);\n\tduk_push_hobject(thr, h_handler);\n\tif (duk_get_prop_stridx_short(thr, -1, stridx_trap)) {\n\t\t/* -> [ ... handler trap ] */\n\t\tduk_insert(thr, -2);  /* -> [ ... trap handler ] */\n\n\t\t/* stack prepped for func call: [ ... trap handler ] */\n\t\treturn 1;\n\t} else {\n\t\tduk_pop_2_unsafe(thr);\n\t\treturn 0;\n\t}\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n/*\n *  Reallocate property allocation, moving properties to the new allocation.\n *\n *  Includes key compaction, rehashing, and can also optionally abandon\n *  the array part, 'migrating' array entries into the beginning of the\n *  new entry part.\n *\n *  There is no support for in-place reallocation or just compacting keys\n *  without resizing the property allocation.  This is intentional to keep\n *  code size minimal, but would be useful future work.\n *\n *  The implementation is relatively straightforward, except for the array\n *  abandonment process.  Array abandonment requires that new string keys\n *  are interned, which may trigger GC.  All keys interned so far must be\n *  reachable for GC at all times and correctly refcounted for; valstack is\n *  used for that now.\n *\n *  Also, a GC triggered during this reallocation process must not interfere\n *  with the object being resized.  This is currently controlled by preventing\n *  finalizers (as they may affect ANY object) and object compaction in\n *  mark-and-sweep.  It would suffice to protect only this particular object\n *  from compaction, however.  DECREF refzero cascades are side effect free\n *  and OK.\n *\n *  Note: because we need to potentially resize the valstack (as part\n *  of abandoning the array part), any tval pointers to the valstack\n *  will become invalid after this call.\n */\n\nDUK_INTERNAL void duk_hobject_realloc_props(duk_hthread *thr,\n                                            duk_hobject *obj,\n                                            duk_uint32_t new_e_size,\n                                            duk_uint32_t new_a_size,\n                                            duk_uint32_t new_h_size,\n                                            duk_bool_t abandon_array) {\n\tduk_small_uint_t prev_ms_base_flags;\n\tduk_uint32_t new_alloc_size;\n\tduk_uint32_t new_e_size_adjusted;\n\tduk_uint8_t *new_p;\n\tduk_hstring **new_e_k;\n\tduk_propvalue *new_e_pv;\n\tduk_uint8_t *new_e_f;\n\tduk_tval *new_a;\n\tduk_uint32_t *new_h;\n\tduk_uint32_t new_e_next;\n\tduk_uint_fast32_t i;\n\tduk_size_t array_copy_size;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_bool_t prev_error_not_allowed;\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(!abandon_array || new_a_size == 0);  /* if abandon_array, new_a_size must be 0 */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL || (DUK_HOBJECT_GET_ESIZE(obj) == 0 && DUK_HOBJECT_GET_ASIZE(obj) == 0));\n\tDUK_ASSERT(new_h_size == 0 || new_h_size >= new_e_size);  /* required to guarantee success of rehashing,\n\t                                                           * intentionally use unadjusted new_e_size\n\t                                                           */\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_object_realloc_props);\n\n\t/*\n\t *  Pre resize assertions.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* XXX: pre-checks (such as no duplicate keys) */\n#endif\n\n\t/*\n\t *  For property layout 1, tweak e_size to ensure that the whole entry\n\t *  part (key + val + flags) is a suitable multiple for alignment\n\t *  (platform specific).\n\t *\n\t *  Property layout 2 does not require this tweaking and is preferred\n\t *  on low RAM platforms requiring alignment.\n\t */\n\n#if defined(DUK_USE_HOBJECT_LAYOUT_2) || defined(DUK_USE_HOBJECT_LAYOUT_3)\n\tDUK_DDD(DUK_DDDPRINT(\"using layout 2 or 3, no need to pad e_size: %ld\", (long) new_e_size));\n\tnew_e_size_adjusted = new_e_size;\n#elif defined(DUK_USE_HOBJECT_LAYOUT_1) && (DUK_HOBJECT_ALIGN_TARGET == 1)\n\tDUK_DDD(DUK_DDDPRINT(\"using layout 1, but no need to pad e_size: %ld\", (long) new_e_size));\n\tnew_e_size_adjusted = new_e_size;\n#elif defined(DUK_USE_HOBJECT_LAYOUT_1) && ((DUK_HOBJECT_ALIGN_TARGET == 4) || (DUK_HOBJECT_ALIGN_TARGET == 8))\n\tnew_e_size_adjusted = (new_e_size + (duk_uint32_t) DUK_HOBJECT_ALIGN_TARGET - 1U) &\n\t                      (~((duk_uint32_t) DUK_HOBJECT_ALIGN_TARGET - 1U));\n\tDUK_DDD(DUK_DDDPRINT(\"using layout 1, and alignment target is %ld, adjusted e_size: %ld -> %ld\",\n\t                     (long) DUK_HOBJECT_ALIGN_TARGET, (long) new_e_size, (long) new_e_size_adjusted));\n\tDUK_ASSERT(new_e_size_adjusted >= new_e_size);\n#else\n#error invalid hobject layout defines\n#endif\n\n\t/*\n\t *  Debug logging after adjustment.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"attempt to resize hobject %p props (%ld -> %ld bytes), from {p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld} to \"\n\t                     \"{e_size=%ld,a_size=%ld,h_size=%ld}, abandon_array=%ld, unadjusted new_e_size=%ld\",\n\t                     (void *) obj,\n\t                     (long) DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t                                                       DUK_HOBJECT_GET_ASIZE(obj),\n\t                                                       DUK_HOBJECT_GET_HSIZE(obj)),\n\t                     (long) DUK_HOBJECT_P_COMPUTE_SIZE(new_e_size_adjusted, new_a_size, new_h_size),\n\t                     (void *) DUK_HOBJECT_GET_PROPS(thr->heap, obj),\n\t                     (long) DUK_HOBJECT_GET_ESIZE(obj),\n\t                     (long) DUK_HOBJECT_GET_ENEXT(obj),\n\t                     (long) DUK_HOBJECT_GET_ASIZE(obj),\n\t                     (long) DUK_HOBJECT_GET_HSIZE(obj),\n\t                     (long) new_e_size_adjusted,\n\t                     (long) new_a_size,\n\t                     (long) new_h_size,\n\t                     (long) abandon_array,\n\t                     (long) new_e_size));\n\n\t/*\n\t *  Property count check.  This is the only point where we ensure that\n\t *  we don't get more (allocated) property space that we can handle.\n\t *  There aren't hard limits as such, but some algorithms may fail\n\t *  if we get too close to the 4G property limit.\n\t *\n\t *  Since this works based on allocation size (not actually used size),\n\t *  the limit is a bit approximate but good enough in practice.\n\t */\n\n\tif (new_e_size_adjusted + new_a_size > DUK_HOBJECT_MAX_PROPERTIES) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size_adjusted > DUK_UINT16_MAX || new_a_size > DUK_UINT16_MAX) {\n\t\t/* If caller gave us sizes larger than what we can store,\n\t\t * fail memory safely with an internal error rather than\n\t\t * truncating the sizes.\n\t\t */\n\t\tDUK_ERROR_INTERNAL(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\t/*\n\t *  Compute new alloc size and alloc new area.\n\t *\n\t *  The new area is not tracked in the heap at all, so it's critical\n\t *  we get to free/keep it in a controlled manner.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Whole path must be error throw free, but we may be called from\n\t * within error handling so can't assert for error_not_allowed == 0.\n\t */\n\tprev_error_not_allowed = thr->heap->error_not_allowed;\n\tthr->heap->error_not_allowed = 1;\n#endif\n\tprev_ms_base_flags = thr->heap->ms_base_flags;\n\tthr->heap->ms_base_flags |=\n\t        DUK_MS_FLAG_NO_OBJECT_COMPACTION;      /* Avoid attempt to compact the current object (all objects really). */\n\tthr->heap->pf_prevent_count++;                 /* Avoid finalizers. */\n\tDUK_ASSERT(thr->heap->pf_prevent_count != 0);  /* Wrap. */\n\n\tnew_alloc_size = DUK_HOBJECT_P_COMPUTE_SIZE(new_e_size_adjusted, new_a_size, new_h_size);\n\tDUK_DDD(DUK_DDDPRINT(\"new hobject allocation size is %ld\", (long) new_alloc_size));\n\tif (new_alloc_size == 0) {\n\t\tDUK_ASSERT(new_e_size_adjusted == 0);\n\t\tDUK_ASSERT(new_a_size == 0);\n\t\tDUK_ASSERT(new_h_size == 0);\n\t\tnew_p = NULL;\n\t} else {\n\t\t/* Alloc may trigger mark-and-sweep but no compaction, and\n\t\t * cannot throw.\n\t\t */\n#if 0  /* XXX: inject test */\n\t\tif (1) {\n\t\t\tnew_p = NULL;\n\t\t\tgoto alloc_failed;\n\t\t}\n#endif\n\t\tnew_p = (duk_uint8_t *) DUK_ALLOC(thr->heap, new_alloc_size);\n\t\tif (new_p == NULL) {\n\t\t\t/* NULL always indicates alloc failure because\n\t\t\t * new_alloc_size > 0.\n\t\t\t */\n\t\t\tgoto alloc_failed;\n\t\t}\n\t}\n\n\t/* Set up pointers to the new property area: this is hidden behind a macro\n\t * because it is memory layout specific.\n\t */\n\tDUK_HOBJECT_P_SET_REALLOC_PTRS(new_p, new_e_k, new_e_pv, new_e_f, new_a, new_h,\n\t                               new_e_size_adjusted, new_a_size, new_h_size);\n\tDUK_UNREF(new_h);  /* happens when hash part dropped */\n\tnew_e_next = 0;\n\n\t/* if new_p == NULL, all of these pointers are NULL */\n\tDUK_ASSERT((new_p != NULL) ||\n\t           (new_e_k == NULL && new_e_pv == NULL && new_e_f == NULL &&\n\t            new_a == NULL && new_h == NULL));\n\n\tDUK_DDD(DUK_DDDPRINT(\"new alloc size %ld, new_e_k=%p, new_e_pv=%p, new_e_f=%p, new_a=%p, new_h=%p\",\n\t                     (long) new_alloc_size, (void *) new_e_k, (void *) new_e_pv, (void *) new_e_f,\n\t                     (void *) new_a, (void *) new_h));\n\n\t/*\n\t *  Migrate array part to start of entries if requested.\n\t *\n\t *  Note: from an enumeration perspective the order of entry keys matters.\n\t *  Array keys should appear wherever they appeared before the array abandon\n\t *  operation.  (This no longer matters much because keys are ES2015 sorted.)\n\t */\n\n\tif (abandon_array) {\n\t\t/* Assuming new_a_size == 0, and that entry part contains\n\t\t * no conflicting keys, refcounts do not need to be adjusted for\n\t\t * the values, as they remain exactly the same.\n\t\t *\n\t\t * The keys, however, need to be interned, incref'd, and be\n\t\t * reachable for GC.  Any intern attempt may trigger a GC and\n\t\t * claim any non-reachable strings, so every key must be reachable\n\t\t * at all times.  Refcounts must be correct to satisfy refcount\n\t\t * assertions.\n\t\t *\n\t\t * A longjmp must not occur here, as the new_p allocation would\n\t\t * leak.  Refcounts would come out correctly as the interned\n\t\t * strings are valstack tracked.\n\t\t */\n\t\tDUK_ASSERT(new_a_size == 0);\n\n\t\tDUK_STATS_INC(thr->heap, stats_object_abandon_array);\n\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_tval *tv2;\n\t\t\tduk_hstring *key;\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);\n\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\t\tif (DUK_TVAL_IS_UNUSED(tv1)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(new_p != NULL && new_e_k != NULL &&\n\t\t\t           new_e_pv != NULL && new_e_f != NULL);\n\n\t\t\t/*\n\t\t\t *  Intern key via the valstack to ensure reachability behaves\n\t\t\t *  properly.  We must avoid longjmp's here so use non-checked\n\t\t\t *  primitives.\n\t\t\t *\n\t\t\t *  Note: duk_check_stack() potentially reallocs the valstack,\n\t\t\t *  invalidating any duk_tval pointers to valstack.  Callers\n\t\t\t *  must be careful.\n\t\t\t */\n\n#if 0  /* XXX: inject test */\n\t\t\tif (1) {\n\t\t\t\tgoto abandon_error;\n\t\t\t}\n#endif\n\t\t\t/* Never shrinks; auto-adds DUK_VALSTACK_INTERNAL_EXTRA, which\n\t\t\t * is generous.\n\t\t\t */\n\t\t\tif (!duk_check_stack(thr, 1)) {\n\t\t\t\tgoto abandon_error;\n\t\t\t}\n\t\t\tDUK_ASSERT_VALSTACK_SPACE(thr, 1);\n\t\t\tkey = duk_heap_strtable_intern_u32(thr->heap, (duk_uint32_t) i);\n\t\t\tif (key == NULL) {\n\t\t\t\tgoto abandon_error;\n\t\t\t}\n\t\t\tduk_push_hstring(thr, key);  /* keep key reachable for GC etc; guaranteed not to fail */\n\n\t\t\t/* Key is now reachable in the valstack, don't INCREF\n\t\t\t * the new allocation yet (we'll steal the refcounts\n\t\t\t * from the value stack once all keys are done).\n\t\t\t */\n\n\t\t\tnew_e_k[new_e_next] = key;\n\t\t\ttv2 = &new_e_pv[new_e_next].v;  /* array entries are all plain values */\n\t\t\tDUK_TVAL_SET_TVAL(tv2, tv1);\n\t\t\tnew_e_f[new_e_next] = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t                      DUK_PROPDESC_FLAG_ENUMERABLE |\n\t\t\t                      DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\tnew_e_next++;\n\n\t\t\t/* Note: new_e_next matches pushed temp key count, and nothing can\n\t\t\t * fail above between the push and this point.\n\t\t\t */\n\t\t}\n\n\t\t/* Steal refcounts from value stack. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"abandon array: pop %ld key temps from valstack\", (long) new_e_next));\n\t\tduk_pop_n_nodecref_unsafe(thr, (duk_idx_t) new_e_next);\n\t}\n\n\t/*\n\t *  Copy keys and values in the entry part (compacting them at the same time).\n\t */\n\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tduk_hstring *key;\n\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL);\n\n\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);\n\t\tif (key == NULL) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_ASSERT(new_p != NULL && new_e_k != NULL &&\n\t\t           new_e_pv != NULL && new_e_f != NULL);\n\n\t\tnew_e_k[new_e_next] = key;\n\t\tnew_e_pv[new_e_next] = DUK_HOBJECT_E_GET_VALUE(thr->heap, obj, i);\n\t\tnew_e_f[new_e_next] = DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, i);\n\t\tnew_e_next++;\n\t}\n\t/* the entries [new_e_next, new_e_size_adjusted[ are left uninitialized on purpose (ok, not gc reachable) */\n\n\t/*\n\t *  Copy array elements to new array part.  If the new array part is\n\t *  larger, initialize the unused entries as UNUSED because they are\n\t *  GC reachable.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* Caller must have decref'd values above new_a_size (if that is necessary). */\n\tif (!abandon_array) {\n\t\tfor (i = new_a_size; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\t\tduk_tval *tv;\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv));\n\t\t}\n\t}\n#endif\n\tif (new_a_size > DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\tarray_copy_size = sizeof(duk_tval) * DUK_HOBJECT_GET_ASIZE(obj);\n\t} else {\n\t\tarray_copy_size = sizeof(duk_tval) * new_a_size;\n\t}\n\n\tDUK_ASSERT(new_a != NULL || array_copy_size == 0U);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, obj) != NULL || array_copy_size == 0U);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) > 0 || array_copy_size == 0U);\n\tduk_memcpy_unsafe((void *) new_a,\n\t                  (const void *) DUK_HOBJECT_A_GET_BASE(thr->heap, obj),\n\t                  array_copy_size);\n\n\tfor (i = DUK_HOBJECT_GET_ASIZE(obj); i < new_a_size; i++) {\n\t\tduk_tval *tv = &new_a[i];\n\t\tDUK_TVAL_SET_UNUSED(tv);\n\t}\n\n\t/*\n\t *  Rebuild the hash part always from scratch (guaranteed to finish\n\t *  as long as caller gave consistent parameters).\n\t *\n\t *  Any resize of hash part requires rehashing.  In addition, by rehashing\n\t *  get rid of any elements marked deleted (DUK__HASH_DELETED) which is critical\n\t *  to ensuring the hash part never fills up.\n\t */\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (new_h_size == 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"no hash part, no rehash\"));\n\t} else {\n\t\tduk_uint32_t mask;\n\n\t\tDUK_ASSERT(new_h != NULL);\n\n\t\t/* fill new_h with u32 0xff = UNUSED */\n\t\tDUK_ASSERT(new_h_size > 0);\n\t\tduk_memset(new_h, 0xff, sizeof(duk_uint32_t) * new_h_size);\n\n\t\tDUK_ASSERT(new_e_next <= new_h_size);  /* equality not actually possible */\n\n\t\tmask = new_h_size - 1;\n\t\tfor (i = 0; i < new_e_next; i++) {\n\t\t\tduk_hstring *key = new_e_k[i];\n\t\t\tduk_uint32_t j, step;\n\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tj = DUK_HSTRING_GET_HASH(key) & mask;\n\t\t\tstep = 1;  /* Cache friendly but clustering prone. */\n\n\t\t\tfor (;;) {\n\t\t\t\tDUK_ASSERT(new_h[j] != DUK__HASH_DELETED);  /* should never happen */\n\t\t\t\tif (new_h[j] == DUK__HASH_UNUSED) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rebuild hit %ld -> %ld\", (long) j, (long) i));\n\t\t\t\t\tnew_h[j] = (duk_uint32_t) i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rebuild miss %ld, step %ld\", (long) j, (long) step));\n\t\t\t\tj = (j + step) & mask;\n\n\t\t\t\t/* Guaranteed to finish (hash is larger than #props). */\n\t\t\t}\n\t\t}\n\t}\n#endif  /* DUK_USE_HOBJECT_HASH_PART */\n\n\t/*\n\t *  Nice debug log.\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"resized hobject %p props (%ld -> %ld bytes), from {p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld} to \"\n\t                   \"{p=%p,e_size=%ld,e_next=%ld,a_size=%ld,h_size=%ld}, abandon_array=%ld, unadjusted new_e_size=%ld\",\n\t                   (void *) obj,\n\t                   (long) DUK_HOBJECT_P_COMPUTE_SIZE(DUK_HOBJECT_GET_ESIZE(obj),\n\t                                                     DUK_HOBJECT_GET_ASIZE(obj),\n\t                                                     DUK_HOBJECT_GET_HSIZE(obj)),\n\t                   (long) new_alloc_size,\n\t                   (void *) DUK_HOBJECT_GET_PROPS(thr->heap, obj),\n\t                   (long) DUK_HOBJECT_GET_ESIZE(obj),\n\t                   (long) DUK_HOBJECT_GET_ENEXT(obj),\n\t                   (long) DUK_HOBJECT_GET_ASIZE(obj),\n\t                   (long) DUK_HOBJECT_GET_HSIZE(obj),\n\t                   (void *) new_p,\n\t                   (long) new_e_size_adjusted,\n\t                   (long) new_e_next,\n\t                   (long) new_a_size,\n\t                   (long) new_h_size,\n\t                   (long) abandon_array,\n\t                   (long) new_e_size));\n\n\t/*\n\t *  All done, switch properties ('p') allocation to new one.\n\t */\n\n\tDUK_FREE_CHECKED(thr, DUK_HOBJECT_GET_PROPS(thr->heap, obj));  /* NULL obj->p is OK */\n\tDUK_HOBJECT_SET_PROPS(thr->heap, obj, new_p);\n\tDUK_HOBJECT_SET_ESIZE(obj, new_e_size_adjusted);\n\tDUK_HOBJECT_SET_ENEXT(obj, new_e_next);\n\tDUK_HOBJECT_SET_ASIZE(obj, new_a_size);\n\tDUK_HOBJECT_SET_HSIZE(obj, new_h_size);\n\n\t/* Clear array part flag only after switching. */\n\tif (abandon_array) {\n\t\tDUK_HOBJECT_CLEAR_ARRAY_PART(obj);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"resize result: %!O\", (duk_heaphdr *) obj));\n\n\tDUK_ASSERT(thr->heap->pf_prevent_count > 0);\n\tthr->heap->pf_prevent_count--;\n\tthr->heap->ms_base_flags = prev_ms_base_flags;\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->heap->error_not_allowed == 1);\n\tthr->heap->error_not_allowed = prev_error_not_allowed;\n#endif\n\n\t/*\n\t *  Post resize assertions.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* XXX: post-checks (such as no duplicate keys) */\n#endif\n\treturn;\n\n\t/*\n\t *  Abandon array failed.  We don't need to DECREF anything\n\t *  because the references in the new allocation are not\n\t *  INCREF'd until abandon is complete.  The string interned\n\t *  keys are on the value stack and are handled normally by\n\t *  unwind.\n\t */\n\n abandon_error:\n alloc_failed:\n\tDUK_D(DUK_DPRINT(\"object property table resize failed\"));\n\n\tDUK_FREE_CHECKED(thr, new_p);  /* OK for NULL. */\n\n\tthr->heap->pf_prevent_count--;\n\tthr->heap->ms_base_flags = prev_ms_base_flags;\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->heap->error_not_allowed == 1);\n\tthr->heap->error_not_allowed = prev_error_not_allowed;\n#endif\n\n\tDUK_ERROR_ALLOC_FAILED(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Helpers to resize properties allocation on specific needs.\n */\n\nDUK_INTERNAL void duk_hobject_resize_entrypart(duk_hthread *thr,\n                                               duk_hobject *obj,\n                                               duk_uint32_t new_e_size) {\n\tduk_uint32_t old_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_h_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\told_e_size = DUK_HOBJECT_GET_ESIZE(obj);\n\tif (old_e_size > new_e_size) {\n\t\tnew_e_size = old_e_size;\n\t}\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tnew_h_size = duk__get_default_h_size(new_e_size);\n#else\n\tnew_h_size = 0;\n#endif\n\tnew_a_size = DUK_HOBJECT_GET_ASIZE(obj);\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);\n}\n\n/* Grow entry part allocation for one additional entry. */\nDUK_LOCAL void duk__grow_props_for_new_entry_item(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint32_t old_e_used;  /* actually used, non-NULL entries */\n\tduk_uint32_t new_e_size_minimum;\n\tduk_uint32_t new_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_h_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\t/* Duktape 0.11.0 and prior tried to optimize the resize by not\n\t * counting the number of actually used keys prior to the resize.\n\t * This worked mostly well but also caused weird leak-like behavior\n\t * as in: test-bug-object-prop-alloc-unbounded.js.  So, now we count\n\t * the keys explicitly to compute the new entry part size.\n\t */\n\n\told_e_used = duk__count_used_e_keys(thr, obj);\n\tnew_e_size_minimum = old_e_used + 1;\n\tnew_e_size = old_e_used + duk__get_min_grow_e(old_e_used);\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tnew_h_size = duk__get_default_h_size(new_e_size);\n#else\n\tnew_h_size = 0;\n#endif\n\tnew_a_size = DUK_HOBJECT_GET_ASIZE(obj);\n\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size > DUK_UINT16_MAX) {\n\t\tnew_e_size = DUK_UINT16_MAX;\n\t}\n\tif (new_h_size > DUK_UINT16_MAX) {\n\t\tnew_h_size = DUK_UINT16_MAX;\n\t}\n\tif (new_a_size > DUK_UINT16_MAX) {\n\t\tnew_a_size = DUK_UINT16_MAX;\n\t}\n#endif\n\tDUK_ASSERT(new_h_size == 0 || new_h_size >= new_e_size);\n\n\tif (!(new_e_size >= new_e_size_minimum)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);\n}\n\n/* Grow array part for a new highest array index. */\nDUK_LOCAL void duk__grow_props_for_array_item(duk_hthread *thr, duk_hobject *obj, duk_uint32_t highest_arr_idx) {\n\tduk_uint32_t new_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_a_size_minimum;\n\tduk_uint32_t new_h_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(highest_arr_idx >= DUK_HOBJECT_GET_ASIZE(obj));\n\n\tnew_e_size = DUK_HOBJECT_GET_ESIZE(obj);\n\tnew_h_size = DUK_HOBJECT_GET_HSIZE(obj);\n\tnew_a_size_minimum = highest_arr_idx + 1;\n\tnew_a_size = highest_arr_idx + duk__get_min_grow_a(highest_arr_idx);\n\tDUK_ASSERT(new_a_size >= highest_arr_idx + 1);  /* duk__get_min_grow_a() is always >= 1 */\n\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size > DUK_UINT16_MAX) {\n\t\tnew_e_size = DUK_UINT16_MAX;\n\t}\n\tif (new_h_size > DUK_UINT16_MAX) {\n\t\tnew_h_size = DUK_UINT16_MAX;\n\t}\n\tif (new_a_size > DUK_UINT16_MAX) {\n\t\tnew_a_size = DUK_UINT16_MAX;\n\t}\n#endif\n\n\tif (!(new_a_size >= new_a_size_minimum)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 0);\n}\n\n/* Abandon array part, moving array entries into entries part.\n * This requires a props resize, which is a heavy operation.\n * We also compact the entries part while we're at it, although\n * this is not strictly required.\n */\nDUK_LOCAL void duk__abandon_array_part(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint32_t new_e_size_minimum;\n\tduk_uint32_t new_e_size;\n\tduk_uint32_t new_a_size;\n\tduk_uint32_t new_h_size;\n\tduk_uint32_t e_used;  /* actually used, non-NULL keys */\n\tduk_uint32_t a_used;\n\tduk_uint32_t a_size;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\te_used = duk__count_used_e_keys(thr, obj);\n\tduk__compute_a_stats(thr, obj, &a_used, &a_size);\n\n\t/*\n\t *  Must guarantee all actually used array entries will fit into\n\t *  new entry part.  Add one growth step to ensure we don't run out\n\t *  of space right away.\n\t */\n\n\tnew_e_size_minimum = e_used + a_used;\n\tnew_e_size = new_e_size_minimum + duk__get_min_grow_e(new_e_size_minimum);\n\tnew_a_size = 0;\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tnew_h_size = duk__get_default_h_size(new_e_size);\n#else\n\tnew_h_size = 0;\n#endif\n\n#if defined(DUK_USE_OBJSIZES16)\n\tif (new_e_size > DUK_UINT16_MAX) {\n\t\tnew_e_size = DUK_UINT16_MAX;\n\t}\n\tif (new_h_size > DUK_UINT16_MAX) {\n\t\tnew_h_size = DUK_UINT16_MAX;\n\t}\n\tif (new_a_size > DUK_UINT16_MAX) {\n\t\tnew_a_size = DUK_UINT16_MAX;\n\t}\n#endif\n\n\tif (!(new_e_size >= new_e_size_minimum)) {\n\t\tDUK_ERROR_ALLOC_FAILED(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"abandon array part for hobject %p, \"\n\t                   \"array stats before: e_used=%ld, a_used=%ld, a_size=%ld; \"\n\t                   \"resize to e_size=%ld, a_size=%ld, h_size=%ld\",\n\t                   (void *) obj, (long) e_used, (long) a_used, (long) a_size,\n\t                   (long) new_e_size, (long) new_a_size, (long) new_h_size));\n\n\tduk_hobject_realloc_props(thr, obj, new_e_size, new_a_size, new_h_size, 1);\n}\n\n/*\n *  Compact an object.  Minimizes allocation size for objects which are\n *  not likely to be extended.  This is useful for internal and non-\n *  extensible objects, but can also be called for non-extensible objects.\n *  May abandon the array part if it is computed to be too sparse.\n *\n *  This call is relatively expensive, as it needs to scan both the\n *  entries and the array part.\n *\n *  The call may fail due to allocation error.\n */\n\nDUK_INTERNAL void duk_hobject_compact_props(duk_hthread *thr, duk_hobject *obj) {\n\tduk_uint32_t e_size;       /* currently used -> new size */\n\tduk_uint32_t a_size;       /* currently required */\n\tduk_uint32_t a_used;       /* actually used */\n\tduk_uint32_t h_size;\n\tduk_bool_t abandon_array;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"ignore attempt to compact a rom object\"));\n\t\treturn;\n\t}\n#endif\n\n\te_size = duk__count_used_e_keys(thr, obj);\n\tduk__compute_a_stats(thr, obj, &a_used, &a_size);\n\n\tDUK_DD(DUK_DDPRINT(\"compacting hobject, used e keys %ld, used a keys %ld, min a size %ld, \"\n\t                   \"resized array density would be: %ld/%ld = %lf\",\n\t                   (long) e_size, (long) a_used, (long) a_size,\n\t                   (long) a_used, (long) a_size,\n\t                   (double) a_used / (double) a_size));\n\n\tif (duk__abandon_array_density_check(a_used, a_size)) {\n\t\tDUK_DD(DUK_DDPRINT(\"decided to abandon array during compaction, a_used=%ld, a_size=%ld\",\n\t\t                   (long) a_used, (long) a_size));\n\t\tabandon_array = 1;\n\t\te_size += a_used;\n\t\ta_size = 0;\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"decided to keep array during compaction\"));\n\t\tabandon_array = 0;\n\t}\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (e_size >= DUK_USE_HOBJECT_HASH_PROP_LIMIT) {\n\t\th_size = duk__get_default_h_size(e_size);\n\t} else {\n\t\th_size = 0;\n\t}\n#else\n\th_size = 0;\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"compacting hobject -> new e_size %ld, new a_size=%ld, new h_size=%ld, abandon_array=%ld\",\n\t                   (long) e_size, (long) a_size, (long) h_size, (long) abandon_array));\n\n\tduk_hobject_realloc_props(thr, obj, e_size, a_size, h_size, abandon_array);\n}\n\n/*\n *  Find an existing key from entry part either by linear scan or by\n *  using the hash index (if it exists).\n *\n *  Sets entry index (and possibly the hash index) to output variables,\n *  which allows the caller to update the entry and hash entries in-place.\n *  If entry is not found, both values are set to -1.  If entry is found\n *  but there is no hash part, h_idx is set to -1.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_find_entry(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_int_t *e_idx, duk_int_t *h_idx) {\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(e_idx != NULL);\n\tDUK_ASSERT(h_idx != NULL);\n\tDUK_UNREF(heap);\n\n\tif (DUK_LIKELY(DUK_HOBJECT_GET_HSIZE(obj) == 0))\n\t{\n\t\t/* Linear scan: more likely because most objects are small.\n\t\t * This is an important fast path.\n\t\t *\n\t\t * XXX: this might be worth inlining for property lookups.\n\t\t */\n\t\tduk_uint_fast32_t i;\n\t\tduk_uint_fast32_t n;\n\t\tduk_hstring **h_keys_base;\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk_hobject_find_entry() using linear scan for lookup\"));\n\n\t\th_keys_base = DUK_HOBJECT_E_GET_KEY_BASE(heap, obj);\n\t\tn = DUK_HOBJECT_GET_ENEXT(obj);\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tif (h_keys_base[i] == key) {\n\t\t\t\t*e_idx = (duk_int_t) i;\n\t\t\t\t*h_idx = -1;\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t}\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\telse\n\t{\n\t\t/* hash lookup */\n\t\tduk_uint32_t n;\n\t\tduk_uint32_t i, step;\n\t\tduk_uint32_t *h_base;\n\t\tduk_uint32_t mask;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk_hobject_find_entry() using hash part for lookup\"));\n\n\t\th_base = DUK_HOBJECT_H_GET_BASE(heap, obj);\n\t\tn = DUK_HOBJECT_GET_HSIZE(obj);\n\t\tmask = n - 1;\n\t\ti = DUK_HSTRING_GET_HASH(key) & mask;\n\t\tstep = 1;  /* Cache friendly but clustering prone. */\n\n\t\tfor (;;) {\n\t\t\tduk_uint32_t t;\n\n\t\t\tDUK_ASSERT_DISABLE(i >= 0);  /* unsigned */\n\t\t\tDUK_ASSERT(i < DUK_HOBJECT_GET_HSIZE(obj));\n\t\t\tt = h_base[i];\n\t\t\tDUK_ASSERT(t == DUK__HASH_UNUSED || t == DUK__HASH_DELETED ||\n\t\t\t           (t < DUK_HOBJECT_GET_ESIZE(obj)));  /* t >= 0 always true, unsigned */\n\n\t\t\tif (t == DUK__HASH_UNUSED) {\n\t\t\t\tbreak;\n\t\t\t} else if (t == DUK__HASH_DELETED) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"lookup miss (deleted) i=%ld, t=%ld\",\n\t\t\t\t                     (long) i, (long) t));\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(t < DUK_HOBJECT_GET_ESIZE(obj));\n\t\t\t\tif (DUK_HOBJECT_E_GET_KEY(heap, obj, t) == key) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"lookup hit i=%ld, t=%ld -> key %p\",\n\t\t\t\t\t                     (long) i, (long) t, (void *) key));\n\t\t\t\t\t*e_idx = (duk_int_t) t;\n\t\t\t\t\t*h_idx = (duk_int_t) i;\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"lookup miss i=%ld, t=%ld\",\n\t\t\t\t                     (long) i, (long) t));\n\t\t\t}\n\t\t\ti = (i + step) & mask;\n\n\t\t\t/* Guaranteed to finish (hash is larger than #props). */\n\t\t}\n\t}\n#endif  /* DUK_USE_HOBJECT_HASH_PART */\n\n\t/* Not found, leave e_idx and h_idx unset. */\n\treturn 0;\n}\n\n/* For internal use: get non-accessor entry value */\nDUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_hstring *key) {\n\tduk_int_t e_idx;\n\tduk_int_t h_idx;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_UNREF(heap);\n\n\tif (duk_hobject_find_entry(heap, obj, key, &e_idx, &h_idx)) {\n\t\tDUK_ASSERT(e_idx >= 0);\n\t\tif (!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {\n\t\t\treturn DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);\n\t\t}\n\t}\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx) {\n\treturn duk_hobject_find_entry_tval_ptr(heap, obj, DUK_HEAP_GET_STRING(heap, stridx));\n}\n\n/* For internal use: get non-accessor entry value and attributes */\nDUK_INTERNAL duk_tval *duk_hobject_find_entry_tval_ptr_and_attrs(duk_heap *heap, duk_hobject *obj, duk_hstring *key, duk_uint_t *out_attrs) {\n\tduk_int_t e_idx;\n\tduk_int_t h_idx;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_attrs != NULL);\n\tDUK_UNREF(heap);\n\n\tif (duk_hobject_find_entry(heap, obj, key, &e_idx, &h_idx)) {\n\t\tDUK_ASSERT(e_idx >= 0);\n\t\tif (!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, obj, e_idx)) {\n\t\t\t*out_attrs = DUK_HOBJECT_E_GET_FLAGS(heap, obj, e_idx);\n\t\t\treturn DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, obj, e_idx);\n\t\t}\n\t}\n\t/* If not found, out_attrs is left unset. */\n\treturn NULL;\n}\n\n/* For internal use: get array part value */\nDUK_INTERNAL duk_tval *duk_hobject_find_array_entry_tval_ptr(duk_heap *heap, duk_hobject *obj, duk_uarridx_t i) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(heap);\n\n\tif (!DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\treturn NULL;\n\t}\n\tif (i >= DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\treturn NULL;\n\t}\n\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(heap, obj, i);\n\treturn tv;\n}\n\n/*\n *  Allocate and initialize a new entry, resizing the properties allocation\n *  if necessary.  Returns entry index (e_idx) or throws an error if alloc fails.\n *\n *  Sets the key of the entry (increasing the key's refcount), and updates\n *  the hash part if it exists.  Caller must set value and flags, and update\n *  the entry value refcount.  A decref for the previous value is not necessary.\n */\n\nDUK_LOCAL duk_int_t duk__hobject_alloc_entry_checked(duk_hthread *thr, duk_hobject *obj, duk_hstring *key) {\n\tduk_uint32_t idx;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(obj) <= DUK_HOBJECT_GET_ESIZE(obj));\n\n#if defined(DUK_USE_ASSERTIONS)\n\t/* key must not already exist in entry part */\n\t{\n\t\tduk_uint_fast32_t i;\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != key);\n\t\t}\n\t}\n#endif\n\n\tif (DUK_HOBJECT_GET_ENEXT(obj) >= DUK_HOBJECT_GET_ESIZE(obj)) {\n\t\t/* only need to guarantee 1 more slot, but allocation growth is in chunks */\n\t\tDUK_DDD(DUK_DDDPRINT(\"entry part full, allocate space for one more entry\"));\n\t\tduk__grow_props_for_new_entry_item(thr, obj);\n\t}\n\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(obj) < DUK_HOBJECT_GET_ESIZE(obj));\n\tidx = DUK_HOBJECT_POSTINC_ENEXT(obj);\n\n\t/* previous value is assumed to be garbage, so don't touch it */\n\tDUK_HOBJECT_E_SET_KEY(thr->heap, obj, idx, key);\n\tDUK_HSTRING_INCREF(thr, key);\n\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\tif (DUK_UNLIKELY(DUK_HOBJECT_GET_HSIZE(obj) > 0)) {\n\t\tduk_uint32_t n, mask;\n\t\tduk_uint32_t i, step;\n\t\tduk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(thr->heap, obj);\n\n\t\tn = DUK_HOBJECT_GET_HSIZE(obj);\n\t\tmask = n - 1;\n\t\ti = DUK_HSTRING_GET_HASH(key) & mask;\n\t\tstep = 1;  /* Cache friendly but clustering prone. */\n\n\t\tfor (;;) {\n\t\t\tduk_uint32_t t = h_base[i];\n\t\t\tif (t == DUK__HASH_UNUSED || t == DUK__HASH_DELETED) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__hobject_alloc_entry_checked() inserted key into hash part, %ld -> %ld\",\n\t\t\t\t                     (long) i, (long) idx));\n\t\t\t\tDUK_ASSERT_DISABLE(i >= 0);  /* unsigned */\n\t\t\t\tDUK_ASSERT(i < DUK_HOBJECT_GET_HSIZE(obj));\n\t\t\t\tDUK_ASSERT_DISABLE(idx >= 0);\n\t\t\t\tDUK_ASSERT(idx < DUK_HOBJECT_GET_ESIZE(obj));\n\t\t\t\th_base[i] = idx;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__hobject_alloc_entry_checked() miss %ld\", (long) i));\n\t\t\ti = (i + step) & mask;\n\n\t\t\t/* Guaranteed to finish (hash is larger than #props). */\n\t\t}\n\t}\n#endif  /* DUK_USE_HOBJECT_HASH_PART */\n\n\t/* Note: we could return the hash index here too, but it's not\n\t * needed right now.\n\t */\n\n\tDUK_ASSERT_DISABLE(idx >= 0);\n\tDUK_ASSERT(idx < DUK_HOBJECT_GET_ESIZE(obj));\n\tDUK_ASSERT(idx < DUK_HOBJECT_GET_ENEXT(obj));\n\treturn (duk_int_t) idx;\n}\n\n/*\n *  Object internal value\n *\n *  Returned value is guaranteed to be reachable / incref'd, caller does not need\n *  to incref OR decref.  No proxies or accessors are invoked, no prototype walk.\n */\n\nDUK_INTERNAL duk_tval *duk_hobject_get_internal_value_tval_ptr(duk_heap *heap, duk_hobject *obj) {\n\treturn duk_hobject_find_entry_tval_ptr_stridx(heap, obj, DUK_STRIDX_INT_VALUE);\n}\n\nDUK_LOCAL duk_heaphdr *duk_hobject_get_internal_value_heaphdr(duk_heap *heap, duk_hobject *obj) {\n\tduk_tval *tv;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\ttv = duk_hobject_get_internal_value_tval_ptr(heap, obj);\n\tif (tv != NULL) {\n\t\tduk_heaphdr *h = DUK_TVAL_GET_HEAPHDR(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn h;\n\t}\n\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_hstring *duk_hobject_get_internal_value_string(duk_heap *heap, duk_hobject *obj) {\n\tduk_hstring *h;\n\n\th = (duk_hstring *) duk_hobject_get_internal_value_heaphdr(heap, obj);\n\tif (h != NULL) {\n\t\tDUK_ASSERT(DUK_HEAPHDR_IS_STRING((duk_heaphdr *) h));\n\t}\n\treturn h;\n}\n\nDUK_LOCAL duk_hobject *duk__hobject_get_entry_object_stridx(duk_heap *heap, duk_hobject *obj, duk_small_uint_t stridx) {\n\tduk_tval *tv;\n\tduk_hobject *h;\n\n\ttv = duk_hobject_find_entry_tval_ptr_stridx(heap, obj, stridx);\n\tif (tv != NULL && DUK_TVAL_IS_OBJECT(tv)) {\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn h;\n\t}\n\treturn NULL;\n}\n\nDUK_INTERNAL duk_harray *duk_hobject_get_formals(duk_hthread *thr, duk_hobject *obj) {\n\tduk_harray *h;\n\n\th = (duk_harray *) duk__hobject_get_entry_object_stridx(thr->heap, obj, DUK_STRIDX_INT_FORMALS);\n\tif (h != NULL) {\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY((duk_hobject *) h));\n\t\tDUK_ASSERT(h->length <= DUK_HOBJECT_GET_ASIZE((duk_hobject *) h));\n\t}\n\treturn h;\n}\n\nDUK_INTERNAL duk_hobject *duk_hobject_get_varmap(duk_hthread *thr, duk_hobject *obj) {\n\tduk_hobject *h;\n\n\th = duk__hobject_get_entry_object_stridx(thr->heap, obj, DUK_STRIDX_INT_VARMAP);\n\treturn h;\n}\n\n/*\n *  Arguments handling helpers (argument map mainly).\n *\n *  An arguments object has exotic behavior for some numeric indices.\n *  Accesses may translate to identifier operations which may have\n *  arbitrary side effects (potentially invalidating any duk_tval\n *  pointers).\n */\n\n/* Lookup 'key' from arguments internal 'map', perform a variable lookup\n * if mapped, and leave the result on top of stack (and return non-zero).\n * Used in E5 Section 10.6 algorithms [[Get]] and [[GetOwnProperty]].\n */\nDUK_LOCAL\nduk_bool_t duk__lookup_arguments_map(duk_hthread *thr,\n                                     duk_hobject *obj,\n                                     duk_hstring *key,\n                                     duk_propdesc *temp_desc,\n                                     duk_hobject **out_map,\n                                     duk_hobject **out_varenv) {\n\tduk_hobject *map;\n\tduk_hobject *varenv;\n\tduk_bool_t rc;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments map lookup: thr=%p, obj=%p, key=%p, temp_desc=%p \"\n\t                     \"(obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (void *) temp_desc,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tif (!duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_MAP(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> no 'map'\"));\n\t\treturn 0;\n\t}\n\n\tmap = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(map != NULL);\n\tduk_pop_unsafe(thr);  /* map is reachable through obj */\n\n\tif (!duk_hobject_get_own_propdesc(thr, map, key, temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> 'map' exists, but key not in map\"));\n\t\treturn 0;\n\t}\n\n\t/* [... varname] */\n\tDUK_DDD(DUK_DDDPRINT(\"-> 'map' exists, and contains key, key is mapped to argument/variable binding %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\tDUK_ASSERT(duk_is_string(thr, -1));  /* guaranteed when building arguments */\n\n\t/* get varenv for varname (callee's declarative lexical environment) */\n\trc = duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_VARENV(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE);\n\tDUK_UNREF(rc);\n\tDUK_ASSERT(rc != 0);  /* arguments MUST have an initialized lexical environment reference */\n\tvarenv = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(varenv != NULL);\n\tduk_pop_unsafe(thr);  /* varenv remains reachable through 'obj' */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments varenv is: %!dO\", (duk_heaphdr *) varenv));\n\n\t/* success: leave varname in stack */\n\t*out_map = map;\n\t*out_varenv = varenv;\n\treturn 1;  /* [... varname] */\n}\n\n/* Lookup 'key' from arguments internal 'map', and leave replacement value\n * on stack top if mapped (and return non-zero).\n * Used in E5 Section 10.6 algorithm for [[GetOwnProperty]] (used by [[Get]]).\n */\nDUK_LOCAL duk_bool_t duk__check_arguments_map_for_get(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc) {\n\tduk_hobject *map;\n\tduk_hobject *varenv;\n\tduk_hstring *varname;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk__lookup_arguments_map(thr, obj, key, temp_desc, &map, &varenv)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arguments: key not mapped, no exotic get behavior\"));\n\t\treturn 0;\n\t}\n\n\t/* [... varname] */\n\n\tvarname = duk_require_hstring(thr, -1);\n\tDUK_ASSERT(varname != NULL);\n\tduk_pop_unsafe(thr);  /* varname is still reachable */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments object automatic getvar for a bound variable; \"\n\t                     \"key=%!O, varname=%!O\",\n\t                     (duk_heaphdr *) key,\n\t                     (duk_heaphdr *) varname));\n\n\t(void) duk_js_getvar_envrec(thr, varenv, varname, 1 /*throw*/);\n\n\t/* [... value this_binding] */\n\n\tduk_pop_unsafe(thr);\n\n\t/* leave result on stack top */\n\treturn 1;\n}\n\n/* Lookup 'key' from arguments internal 'map', perform a variable write if mapped.\n * Used in E5 Section 10.6 algorithm for [[DefineOwnProperty]] (used by [[Put]]).\n * Assumes stack top contains 'put' value (which is NOT popped).\n */\nDUK_LOCAL void duk__check_arguments_map_for_put(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc, duk_bool_t throw_flag) {\n\tduk_hobject *map;\n\tduk_hobject *varenv;\n\tduk_hstring *varname;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk__lookup_arguments_map(thr, obj, key, temp_desc, &map, &varenv)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arguments: key not mapped, no exotic put behavior\"));\n\t\treturn;\n\t}\n\n\t/* [... put_value varname] */\n\n\tvarname = duk_require_hstring(thr, -1);\n\tDUK_ASSERT(varname != NULL);\n\tduk_pop_unsafe(thr);  /* varname is still reachable */\n\n\tDUK_DDD(DUK_DDDPRINT(\"arguments object automatic putvar for a bound variable; \"\n\t                     \"key=%!O, varname=%!O, value=%!T\",\n\t                     (duk_heaphdr *) key,\n\t                     (duk_heaphdr *) varname,\n\t                     (duk_tval *) duk_require_tval(thr, -1)));\n\n\t/* [... put_value] */\n\n\t/*\n\t *  Note: although arguments object variable mappings are only established\n\t *  for non-strict functions (and a call to a non-strict function created\n\t *  the arguments object in question), an inner strict function may be doing\n\t *  the actual property write.  Hence the throw_flag applied here comes from\n\t *  the property write call.\n\t */\n\n\tduk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(thr, -1), throw_flag);\n\n\t/* [... put_value] */\n}\n\n/* Lookup 'key' from arguments internal 'map', delete mapping if found.\n * Used in E5 Section 10.6 algorithm for [[Delete]].  Note that the\n * variable/argument itself (where the map points) is not deleted.\n */\nDUK_LOCAL void duk__check_arguments_map_for_delete(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *temp_desc) {\n\tduk_hobject *map;\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk_hobject_get_own_propdesc(thr, obj, DUK_HTHREAD_STRING_INT_MAP(thr), temp_desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arguments: key not mapped, no exotic delete behavior\"));\n\t\treturn;\n\t}\n\n\tmap = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(map != NULL);\n\tduk_pop_unsafe(thr);  /* map is reachable through obj */\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> have 'map', delete key %!O from map (if exists)); ignore result\",\n\t                     (duk_heaphdr *) key));\n\n\t/* Note: no recursion issue, we can trust 'map' to behave */\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_BEHAVIOR(map));\n\tDUK_DDD(DUK_DDDPRINT(\"map before deletion: %!O\", (duk_heaphdr *) map));\n\t(void) duk_hobject_delprop_raw(thr, map, key, 0);  /* ignore result */\n\tDUK_DDD(DUK_DDDPRINT(\"map after deletion: %!O\", (duk_heaphdr *) map));\n}\n\n/*\n *  ECMAScript compliant [[GetOwnProperty]](P), for internal use only.\n *\n *  If property is found:\n *    - Fills descriptor fields to 'out_desc'\n *    - If DUK_GETDESC_FLAG_PUSH_VALUE is set, pushes a value related to the\n *      property onto the stack ('undefined' for accessor properties).\n *    - Returns non-zero\n *\n *  If property is not found:\n *    - 'out_desc' is left in untouched state (possibly garbage)\n *    - Nothing is pushed onto the stack (not even with DUK_GETDESC_FLAG_PUSH_VALUE\n *      set)\n *    - Returns zero\n *\n *  Notes:\n *\n *    - Getting a property descriptor may cause an allocation (and hence\n *      GC) to take place, hence reachability and refcount of all related\n *      values matter.  Reallocation of value stack, properties, etc may\n *      invalidate many duk_tval pointers (concretely, those which reside\n *      in memory areas subject to reallocation).  However, heap object\n *      pointers are never affected (heap objects have stable pointers).\n *\n *    - The value of a plain property is always reachable and has a non-zero\n *      reference count.\n *\n *    - The value of a virtual property is not necessarily reachable from\n *      elsewhere and may have a refcount of zero.  Hence we push it onto\n *      the valstack for the caller, which ensures it remains reachable\n *      while it is needed.\n *\n *    - There are no virtual accessor properties.  Hence, all getters and\n *      setters are always related to concretely stored properties, which\n *      ensures that the get/set functions in the resulting descriptor are\n *      reachable and have non-zero refcounts.  Should there be virtual\n *      accessor properties later, this would need to change.\n */\n\nDUK_LOCAL duk_bool_t duk__get_own_propdesc_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_uint32_t arr_idx, duk_propdesc *out_desc, duk_small_uint_t flags) {\n\tduk_tval *tv;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk_hobject_get_own_propdesc: thr=%p, obj=%p, key=%p, out_desc=%p, flags=%lx, \"\n\t                     \"arr_idx=%ld (obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (void *) out_desc,\n\t                     (long) flags, (long) arr_idx,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_desc != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_getownpropdesc_count);\n\n\t/* Each code path returning 1 (= found) must fill in all the output\n\t * descriptor fields.  We don't do it beforehand because it'd be\n\t * unnecessary work if the property isn't found and would happen\n\t * multiple times for an inheritance chain.\n\t */\n\tDUK_ASSERT_SET_GARBAGE(out_desc, sizeof(*out_desc));\n#if 0\n\tout_desc->flags = 0;\n\tout_desc->get = NULL;\n\tout_desc->set = NULL;\n\tout_desc->e_idx = -1;\n\tout_desc->h_idx = -1;\n\tout_desc->a_idx = -1;\n#endif\n\n\t/*\n\t *  Try entries part first because it's the common case.\n\t *\n\t *  Array part lookups are usually handled by the array fast path, and\n\t *  are not usually inherited.  Array and entry parts never contain the\n\t *  same keys so the entry part vs. array part order doesn't matter.\n\t */\n\n\tif (duk_hobject_find_entry(thr->heap, obj, key, &out_desc->e_idx, &out_desc->h_idx)) {\n\t\tduk_int_t e_idx = out_desc->e_idx;\n\t\tDUK_ASSERT(out_desc->e_idx >= 0);\n\t\tout_desc->a_idx = -1;\n\t\tout_desc->flags = DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, e_idx);\n\t\tout_desc->get = NULL;\n\t\tout_desc->set = NULL;\n\t\tif (DUK_UNLIKELY(out_desc->flags & DUK_PROPDESC_FLAG_ACCESSOR)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found accessor property in entry part\"));\n\t\t\tout_desc->get = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, e_idx);\n\t\t\tout_desc->set = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, e_idx);\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t/* a dummy undefined value is pushed to make valstack\n\t\t\t\t * behavior uniform for caller\n\t\t\t\t */\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t}\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found plain property in entry part\"));\n\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\tduk_push_tval(thr, tv);\n\t\t\t}\n\t\t}\n\t\tgoto prop_found;\n\t}\n\n\t/*\n\t *  Try array part.\n\t */\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj) && arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\tif (arr_idx < DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n\t\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found in array part\"));\n\t\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t\tduk_push_tval(thr, tv);\n\t\t\t\t}\n\t\t\t\t/* implicit attributes */\n\t\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t\t                  DUK_PROPDESC_FLAG_CONFIGURABLE |\n\t\t\t\t                  DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t\tout_desc->get = NULL;\n\t\t\t\tout_desc->set = NULL;\n\t\t\t\tout_desc->e_idx = -1;\n\t\t\t\tout_desc->h_idx = -1;\n\t\t\t\tout_desc->a_idx = (duk_int_t) arr_idx;  /* XXX: limit 2G due to being signed */\n\t\t\t\tgoto prop_found;\n\t\t\t}\n\t\t}\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> not found as a concrete property\"));\n\n\t/*\n\t *  Not found as a concrete property, check for virtual properties.\n\t */\n\n\tif (!DUK_HOBJECT_HAS_VIRTUAL_PROPERTIES(obj)) {\n\t\t/* Quick skip. */\n\t\tgoto prop_not_found;\n\t}\n\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\tduk_harray *a;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array object exotic property get for key: %!O, arr_idx: %ld\",\n\t\t                     (duk_heaphdr *) key, (long) arr_idx));\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, key is 'length', length exotic behavior\"));\n\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) a->length);\n\t\t\t}\n\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\tif (DUK_HARRAY_LENGTH_WRITABLE(a)) {\n\t\t\t\tout_desc->flags |= DUK_PROPDESC_FLAG_WRITABLE;\n\t\t\t}\n\t\t\tout_desc->get = NULL;\n\t\t\tout_desc->set = NULL;\n\t\t\tout_desc->e_idx = -1;\n\t\t\tout_desc->h_idx = -1;\n\t\t\tout_desc->a_idx = -1;\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t}\n\t} else if (DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"string object exotic property get for key: %!O, arr_idx: %ld\",\n\t\t                     (duk_heaphdr *) key, (long) arr_idx));\n\n\t\t/* XXX: charlen; avoid multiple lookups? */\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t\tduk_hstring *h_val;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index exists\"));\n\n\t\t\th_val = duk_hobject_get_internal_value_string(thr->heap, obj);\n\t\t\tDUK_ASSERT(h_val);\n\t\t\tif (arr_idx < DUK_HSTRING_GET_CHARLEN(h_val)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, array index inside string\"));\n\t\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t\tduk_push_hstring(thr, h_val);\n\t\t\t\t\tduk_substring(thr, -1, arr_idx, arr_idx + 1);  /* [str] -> [substr] */\n\t\t\t\t}\n\t\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_ENUMERABLE |  /* E5 Section 15.5.5.2 */\n\t\t\t\t                  DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\t\tout_desc->get = NULL;\n\t\t\t\tout_desc->set = NULL;\n\t\t\t\tout_desc->e_idx = -1;\n\t\t\t\tout_desc->h_idx = -1;\n\t\t\t\tout_desc->a_idx = -1;\n\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t\t} else {\n\t\t\t\t/* index is above internal string length -> property is fully normal */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index outside string -> normal property\"));\n\t\t\t}\n\t\t} else if (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tduk_hstring *h_val;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, key is 'length', length exotic behavior\"));\n\n\t\t\th_val = duk_hobject_get_internal_value_string(thr->heap, obj);\n\t\t\tDUK_ASSERT(h_val != NULL);\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\tduk_push_uint(thr, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h_val));\n\t\t\t}\n\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;  /* E5 Section 15.5.5.1 */\n\t\t\tout_desc->get = NULL;\n\t\t\tout_desc->set = NULL;\n\t\t\tout_desc->e_idx = -1;\n\t\t\tout_desc->h_idx = -1;\n\t\t\tout_desc->a_idx = -1;\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t}\n\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\telse if (DUK_HOBJECT_IS_BUFOBJ(obj)) {\n\t\tduk_hbufobj *h_bufobj;\n\t\tduk_uint_t byte_off;\n\t\tduk_small_uint_t elem_size;\n\n\t\th_bufobj = (duk_hbufobj *) obj;\n\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\t\tDUK_DDD(DUK_DDDPRINT(\"bufobj property get for key: %!O, arr_idx: %ld\",\n\t\t                     (duk_heaphdr *) key, (long) arr_idx));\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index exists\"));\n\n\t\t\t/* Careful with wrapping: arr_idx upshift may easily wrap, whereas\n\t\t\t * length downshift won't.\n\t\t\t */\n\t\t\tif (arr_idx < (h_bufobj->length >> h_bufobj->shift)) {\n\t\t\t\tbyte_off = arr_idx << h_bufobj->shift;  /* no wrap assuming h_bufobj->length is valid */\n\t\t\t\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\t\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t\tduk_uint8_t *data;\n\n\t\t\t\t\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\t\t\t\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\t\t\t\t\tduk_hbufobj_push_validated_read(thr, h_bufobj, data, elem_size);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (read zero)\"));\n\t\t\t\t\t\tduk_push_uint(thr, 0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t\t                  DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\t\tif (DUK_HOBJECT_GET_CLASS_NUMBER(obj) != DUK_HOBJECT_CLASS_ARRAYBUFFER) {\n\t\t\t\t\t/* ArrayBuffer indices are non-standard and are\n\t\t\t\t\t * non-enumerable to avoid their serialization.\n\t\t\t\t\t */\n\t\t\t\t\tout_desc->flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t\t}\n\t\t\t\tout_desc->get = NULL;\n\t\t\t\tout_desc->set = NULL;\n\t\t\t\tout_desc->e_idx = -1;\n\t\t\t\tout_desc->h_idx = -1;\n\t\t\t\tout_desc->a_idx = -1;\n\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\t\tgoto prop_found_noexotic;  /* cannot be e.g. arguments exotic, since exotic 'traits' are mutually exclusive */\n\t\t\t} else {\n\t\t\t\t/* index is above internal buffer length -> property is fully normal */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index outside buffer -> normal property\"));\n\t\t\t}\n\t\t} else if (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> found, key is 'length', length exotic behavior\"));\n\n\t\t\tif (flags & DUK_GETDESC_FLAG_PUSH_VALUE) {\n\t\t\t\t/* Length in elements: take into account shift, but\n\t\t\t\t * intentionally don't check the underlying buffer here.\n\t\t\t\t */\n\t\t\t\tduk_push_uint(thr, h_bufobj->length >> h_bufobj->shift);\n\t\t\t}\n\t\t\tout_desc->flags = DUK_PROPDESC_FLAG_VIRTUAL;\n\t\t\tout_desc->get = NULL;\n\t\t\tout_desc->set = NULL;\n\t\t\tout_desc->e_idx = -1;\n\t\t\tout_desc->h_idx = -1;\n\t\t\tout_desc->a_idx = -1;\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj));\n\t\t\tgoto prop_found_noexotic;  /* cannot be arguments exotic */\n\t\t}\n\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\t/* Array properties have exotic behavior but they are concrete,\n\t * so no special handling here.\n\t *\n\t * Arguments exotic behavior (E5 Section 10.6, [[GetOwnProperty]]\n\t * is only relevant as a post-check implemented below; hence no\n\t * check here.\n\t */\n\n\t/*\n\t *  Not found as concrete or virtual.\n\t */\n\n prop_not_found:\n\tDUK_DDD(DUK_DDDPRINT(\"-> not found (virtual, entry part, or array part)\"));\n\tDUK_STATS_INC(thr->heap, stats_getownpropdesc_miss);\n\treturn 0;\n\n\t/*\n\t *  Found.\n\t *\n\t *  Arguments object has exotic post-processing, see E5 Section 10.6,\n\t *  description of [[GetOwnProperty]] variant for arguments.\n\t */\n\n prop_found:\n\tDUK_DDD(DUK_DDDPRINT(\"-> property found, checking for arguments exotic post-behavior\"));\n\n\t/* Notes:\n\t *  - Only numbered indices are relevant, so arr_idx fast reject is good\n\t *    (this is valid unless there are more than 4**32-1 arguments).\n\t *  - Since variable lookup has no side effects, this can be skipped if\n\t *    DUK_GETDESC_FLAG_PUSH_VALUE is not set.\n\t */\n\n\tif (DUK_UNLIKELY(DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) &&\n\t                 arr_idx != DUK__NO_ARRAY_INDEX &&\n\t                 (flags & DUK_GETDESC_FLAG_PUSH_VALUE))) {\n\t\tduk_propdesc temp_desc;\n\n\t\t/* Magically bound variable cannot be an accessor.  However,\n\t\t * there may be an accessor property (or a plain property) in\n\t\t * place with magic behavior removed.  This happens e.g. when\n\t\t * a magic property is redefined with defineProperty().\n\t\t * Cannot assert for \"not accessor\" here.\n\t\t */\n\n\t\t/* replaces top of stack with new value if necessary */\n\t\tDUK_ASSERT((flags & DUK_GETDESC_FLAG_PUSH_VALUE) != 0);\n\n\t\t/* This can perform a variable lookup but only into a declarative\n\t\t * environment which has no side effects.\n\t\t */\n\t\tif (duk__check_arguments_map_for_get(thr, obj, key, &temp_desc)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> arguments exotic behavior overrides result: %!T -> %!T\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\t/* [... old_result result] -> [... result] */\n\t\t\tduk_remove_m2(thr);\n\t\t}\n\t}\n\n prop_found_noexotic:\n\tDUK_STATS_INC(thr->heap, stats_getownpropdesc_hit);\n\treturn 1;\n}\n\nDUK_INTERNAL duk_bool_t duk_hobject_get_own_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_desc != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\treturn duk__get_own_propdesc_raw(thr, obj, key, DUK_HSTRING_GET_ARRIDX_SLOW(key), out_desc, flags);\n}\n\n/*\n *  ECMAScript compliant [[GetProperty]](P), for internal use only.\n *\n *  If property is found:\n *    - Fills descriptor fields to 'out_desc'\n *    - If DUK_GETDESC_FLAG_PUSH_VALUE is set, pushes a value related to the\n *      property onto the stack ('undefined' for accessor properties).\n *    - Returns non-zero\n *\n *  If property is not found:\n *    - 'out_desc' is left in untouched state (possibly garbage)\n *    - Nothing is pushed onto the stack (not even with DUK_GETDESC_FLAG_PUSH_VALUE\n *      set)\n *    - Returns zero\n *\n *  May cause arbitrary side effects and invalidate (most) duk_tval\n *  pointers.\n */\n\nDUK_LOCAL duk_bool_t duk__get_propdesc(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_propdesc *out_desc, duk_small_uint_t flags) {\n\tduk_hobject *curr;\n\tduk_uint32_t arr_idx;\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(out_desc != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_getpropdesc_count);\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__get_propdesc: thr=%p, obj=%p, key=%p, out_desc=%p, flags=%lx, \"\n\t                     \"arr_idx=%ld (obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (void *) out_desc,\n\t                     (long) flags, (long) arr_idx,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tcurr = obj;\n\tDUK_ASSERT(curr != NULL);\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (duk__get_own_propdesc_raw(thr, curr, key, arr_idx, out_desc, flags)) {\n\t\t\t/* stack contains value (if requested), 'out_desc' is set */\n\t\t\tDUK_STATS_INC(thr->heap, stats_getpropdesc_hit);\n\t\t\treturn 1;\n\t\t}\n\n\t\t/* not found in 'curr', next in prototype chain; impose max depth */\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tif (flags & DUK_GETDESC_FLAG_IGNORE_PROTOLOOP) {\n\t\t\t\t/* treat like property not found */\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t} while (curr != NULL);\n\n\t/* out_desc is left untouched (possibly garbage), caller must use return\n\t * value to determine whether out_desc can be looked up\n\t */\n\n\tDUK_STATS_INC(thr->heap, stats_getpropdesc_miss);\n\treturn 0;\n}\n\n/*\n *  Shallow fast path checks for accessing array elements with numeric\n *  indices.  The goal is to try to avoid coercing an array index to an\n *  (interned) string for the most common lookups, in particular, for\n *  standard Array objects.\n *\n *  Interning is avoided but only for a very narrow set of cases:\n *    - Object has array part, index is within array allocation, and\n *      value is not unused (= key exists)\n *    - Object has no interfering exotic behavior (e.g. arguments or\n *      string object exotic behaviors interfere, array exotic\n *      behavior does not).\n *\n *  Current shortcoming: if key does not exist (even if it is within\n *  the array allocation range) a slow path lookup with interning is\n *  always required.  This can probably be fixed so that there is a\n *  quick fast path for non-existent elements as well, at least for\n *  standard Array objects.\n */\n\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\nDUK_LOCAL duk_tval *duk__getprop_shallow_fastpath_array_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key) {\n\tduk_tval *tv;\n\tduk_uint32_t idx;\n\n\tDUK_UNREF(thr);\n\n\tif (!(DUK_HOBJECT_HAS_ARRAY_PART(obj) &&\n\t     !DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj) &&\n\t     !DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(obj) &&\n\t     !DUK_HOBJECT_IS_BUFOBJ(obj) &&\n\t     !DUK_HOBJECT_IS_PROXY(obj))) {\n\t\t/* Must have array part and no conflicting exotic behaviors.\n\t\t * Doesn't need to have array special behavior, e.g. Arguments\n\t\t * object has array part.\n\t\t */\n\t\treturn NULL;\n\t}\n\n\t/* Arrays never have other exotic behaviors. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"fast path attempt (no exotic string/arguments/buffer \"\n\t                     \"behavior, object has array part)\"));\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"key is not a number\"));\n\t\treturn NULL;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside object 'a_size'.\n\t */\n\n\tif (idx >= DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"key is not an array index or outside array part\"));\n\t\treturn NULL;\n\t}\n\tDUK_ASSERT(idx != 0xffffffffUL);\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\t/* XXX: for array instances we could take a shortcut here and assume\n\t * Array.prototype doesn't contain an array index property.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"key is a valid array index and inside array part\"));\n\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, idx);\n\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> fast path successful\"));\n\t\treturn tv;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"fast path attempt failed, fall back to slow path\"));\n\treturn NULL;\n}\n\nDUK_LOCAL duk_bool_t duk__putprop_shallow_fastpath_array_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val) {\n\tduk_tval *tv;\n\tduk_harray *a;\n\tduk_uint32_t idx;\n\tduk_uint32_t old_len, new_len;\n\n\tif (!(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj) &&\n\t      DUK_HOBJECT_HAS_ARRAY_PART(obj) &&\n\t      DUK_HOBJECT_HAS_EXTENSIBLE(obj))) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));  /* caller ensures */\n\n\ta = (duk_harray *) obj;\n\tDUK_HARRAY_ASSERT_VALID(a);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"key is not a number\"));\n\t\treturn 0;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside object 'a_size'.\n\t */\n\n\tif (idx >= DUK_HOBJECT_GET_ASIZE(obj)) {  /* for resizing of array part, use slow path */\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(idx != 0xffffffffUL);\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\told_len = a->length;\n\n\tif (idx >= old_len) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"write new array entry requires length update \"\n\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t                     (long) idx, (long) old_len));\n\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a)) {\n\t\t\t/* The correct behavior here is either a silent error\n\t\t\t * or a TypeError, depending on strictness.  Fall back\n\t\t\t * to the slow path to handle the situation.\n\t\t\t */\n\t\t\treturn 0;\n\t\t}\n\t\tnew_len = idx + 1;\n\n\t\t((duk_harray *) obj)->length = new_len;\n\t}\n\n\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, idx);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val);  /* side effects */\n\n\tDUK_DDD(DUK_DDDPRINT(\"array fast path success for index %ld\", (long) idx));\n\treturn 1;\n}\n#endif  /* DUK_USE_ARRAY_PROP_FASTPATH */\n\n/*\n *  Fast path for bufobj getprop/putprop\n */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL duk_bool_t duk__getprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key) {\n\tduk_uint32_t idx;\n\tduk_hbufobj *h_bufobj;\n\tduk_uint_t byte_off;\n\tduk_small_uint_t elem_size;\n\tduk_uint8_t *data;\n\n\tif (!DUK_HOBJECT_IS_BUFOBJ(obj)) {\n\t\treturn 0;\n\t}\n\th_bufobj = (duk_hbufobj *) obj;\n\tif (!DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\treturn 0;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\treturn 0;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside bufobj length.\n\t */\n\n\t/* Careful with wrapping (left shifting idx would be unsafe). */\n\tif (idx >= (h_bufobj->length >> h_bufobj->shift)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\tbyte_off = idx << h_bufobj->shift;  /* no wrap assuming h_bufobj->length is valid */\n\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\n\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\tduk_hbufobj_push_validated_read(thr, h_bufobj, data, elem_size);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (read zero)\"));\n\t\tduk_push_uint(thr, 0);\n\t}\n\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\nDUK_LOCAL duk_bool_t duk__putprop_fastpath_bufobj_tval(duk_hthread *thr, duk_hobject *obj, duk_tval *tv_key, duk_tval *tv_val) {\n\tduk_uint32_t idx;\n\tduk_hbufobj *h_bufobj;\n\tduk_uint_t byte_off;\n\tduk_small_uint_t elem_size;\n\tduk_uint8_t *data;\n\n\tif (!(DUK_HOBJECT_IS_BUFOBJ(obj) &&\n\t      DUK_TVAL_IS_NUMBER(tv_val))) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));  /* caller ensures; rom objects are never bufobjs now */\n\n\th_bufobj = (duk_hbufobj *) obj;\n\tif (!DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\treturn 0;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\tidx = duk__tval_fastint_to_arr_idx(tv_key);\n\t} else\n#endif\n\tif (DUK_TVAL_IS_DOUBLE(tv_key)) {\n\t\tidx = duk__tval_number_to_arr_idx(tv_key);\n\t} else {\n\t\treturn 0;\n\t}\n\n\t/* If index is not valid, idx will be DUK__NO_ARRAY_INDEX which\n\t * is 0xffffffffUL.  We don't need to check for that explicitly\n\t * because 0xffffffffUL will never be inside bufobj length.\n\t */\n\n\t/* Careful with wrapping (left shifting idx would be unsafe). */\n\tif (idx >= (h_bufobj->length >> h_bufobj->shift)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(idx != DUK__NO_ARRAY_INDEX);\n\n\tbyte_off = idx << h_bufobj->shift;  /* no wrap assuming h_bufobj->length is valid */\n\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\n\t/* Value is required to be a number in the fast path so there\n\t * are no side effects in write coercion.\n\t */\n\tduk_push_tval(thr, tv_val);\n\tDUK_ASSERT(duk_is_number(thr, -1));\n\n\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\tduk_hbufobj_validated_write(thr, h_bufobj, data, elem_size);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (write skipped)\"));\n\t}\n\n\tduk_pop_unsafe(thr);\n\treturn 1;\n}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n/*\n *  GETPROP: ECMAScript property read.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_getprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) {\n\tduk_tval tv_obj_copy;\n\tduk_tval tv_key_copy;\n\tduk_hobject *curr = NULL;\n\tduk_hstring *key = NULL;\n\tduk_uint32_t arr_idx = DUK__NO_ARRAY_INDEX;\n\tduk_propdesc desc;\n\tduk_uint_t sanity;\n\n\tDUK_DDD(DUK_DDDPRINT(\"getprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key,\n\t                     (duk_tval *) tv_obj, (duk_tval *) tv_key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_getprop_all);\n\n\t/*\n\t *  Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of\n\t *  them being invalidated by a valstack resize.\n\t *\n\t *  XXX: this is now an overkill for many fast paths.  Rework this\n\t *  to be faster (although switching to a valstack discipline might\n\t *  be a better solution overall).\n\t */\n\n\tDUK_TVAL_SET_TVAL(&tv_obj_copy, tv_obj);\n\tDUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);\n\ttv_obj = &tv_obj_copy;\n\ttv_key = &tv_key_copy;\n\n\t/*\n\t *  Coercion and fast path processing\n\t */\n\n\tswitch (DUK_TVAL_GET_TAG(tv_obj)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL: {\n\t\t/* Note: unconditional throw */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is undefined or null -> reject\"));\n#if defined(DUK_USE_PARANOID_ERRORS)\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\t\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot read property %s of %s\",\n\t\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\t\tDUK_WO_NORETURN(return 0;);\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a boolean, start lookup from boolean prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);\n\t\tduk_int_t pop_count;\n\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\t/* Symbols (ES2015 or hidden) don't have virtual properties. */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a symbol, start lookup from symbol prototype\"));\n\t\t\tcurr = thr->builtins[DUK_BIDX_SYMBOL_PROTOTYPE];\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_FASTINT)\n\t\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\t\tarr_idx = duk__tval_fastint_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a fast-path fastint; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else\n#endif\n\t\tif (DUK_TVAL_IS_NUMBER(tv_key)) {\n\t\t\tarr_idx = duk__tval_number_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a fast-path number; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t\tpop_count = 1;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {\n\t\t\tduk_pop_n_unsafe(thr, pop_count);\n\t\t\tduk_push_hstring(thr, h);\n\t\t\tduk_substring(thr, -1, arr_idx, arr_idx + 1);  /* [str] -> [substr] */\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_stringidx);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is string, key is an index inside string length \"\n\t\t\t                     \"after coercion -> return char)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (pop_count == 0) {\n\t\t\t/* This is a pretty awkward control flow, but we need to recheck the\n\t\t\t * key coercion here.\n\t\t\t */\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object string, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tduk_pop_unsafe(thr);  /* [key] -> [] */\n\t\t\tduk_push_uint(thr, (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h));  /* [] -> [res] */\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_stringlen);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is string, key is 'length' after coercion -> \"\n\t\t\t                     \"return string length)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a string, start lookup from string prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_STRING_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_OBJECT: {\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\n\t\tduk_tval *tmp;\n#endif\n\n\t\tcurr = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(curr != NULL);\n\n\t\t/* XXX: array .length fast path (important in e.g. loops)? */\n\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\n\t\ttmp = duk__getprop_shallow_fastpath_array_tval(thr, curr, tv_key);\n\t\tif (tmp) {\n\t\t\tduk_push_tval(thr, tmp);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is object, key is a number, array part \"\n\t\t\t                     \"fast path)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_arrayidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (duk__getprop_fastpath_bufobj_tval(thr, curr, tv_key) != 0) {\n\t\t\t/* Read value pushed on stack. */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is bufobj, key is a number, bufobj \"\n\t\t\t                     \"fast path)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_bufobjidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(curr))) {\n\t\t\tduk_hobject *h_target;\n\n\t\t\tif (duk__proxy_check_prop(thr, curr, DUK_STRIDX_GET, tv_key, &h_target)) {\n\t\t\t\t/* -> [ ... trap handler ] */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'get' for key %!T\", (duk_tval *) tv_key));\n\t\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_proxy);\n\t\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\t\tduk_push_tval(thr, tv_key);       /* P */\n\t\t\t\tduk_push_tval(thr, tv_obj);       /* Receiver: Proxy object */\n\t\t\t\tduk_call_method(thr, 3 /*nargs*/);\n\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\t\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\t\t\t\tduk_tval *tv_hook = duk_require_tval(thr, -3);  /* value from hook */\n\t\t\t\t\tduk_tval *tv_targ = duk_require_tval(thr, -1);  /* value from target */\n\t\t\t\t\tduk_bool_t datadesc_reject;\n\t\t\t\t\tduk_bool_t accdesc_reject;\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'get': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; tv_hook=%!T, tv_targ=%!T, desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (duk_tval *) tv_hook, (duk_tval *) tv_targ,\n\t\t\t\t\t                     (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\n\t\t\t\t\tdatadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) &&\n\t\t\t\t\t                  !duk_js_samevalue(tv_hook, tv_targ);\n\t\t\t\t\taccdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                 !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                 (desc.get == NULL) &&\n\t\t\t\t\t                 !DUK_TVAL_IS_UNDEFINED(tv_hook);\n\t\t\t\t\tif (datadesc_reject || accdesc_reject) {\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\n\t\t\t\t\tduk_pop_2_unsafe(thr);\n\t\t\t\t} else {\n\t\t\t\t\tduk_pop_unsafe(thr);\n\t\t\t\t}\n\t\t\t\treturn 1;  /* return value */\n\t\t\t}\n\n\t\t\tcurr = h_target;  /* resume lookup from target */\n\t\t\tDUK_TVAL_SET_OBJECT(tv_obj, curr);\n\t\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t\tif (DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(curr)) {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_arguments);\n\t\t\tif (duk__check_arguments_map_for_get(thr, curr, key, &desc)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is object with arguments exotic behavior, \"\n\t\t\t\t                     \"key matches magically bound property -> skip standard \"\n\t\t\t\t                     \"Get with replacement value)\",\n\t\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t\t/* no need for 'caller' post-check, because 'key' must be an array index */\n\n\t\t\t\tduk_remove_m2(thr);  /* [key result] -> [result] */\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tgoto lookup;  /* avoid double coercion */\n\t\t}\n\t\tbreak;\n\t}\n\n\t/* Buffer has virtual properties similar to string, but indexed values\n\t * are numbers, not 1-byte buffers/strings which would perform badly.\n\t */\n\tcase DUK_TAG_BUFFER: {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);\n\t\tduk_int_t pop_count;\n\n\t\t/*\n\t\t *  Because buffer values are often looped over, a number fast path\n\t\t *  is important.\n\t\t */\n\n#if defined(DUK_USE_FASTINT)\n\t\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\t\tarr_idx = duk__tval_fastint_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path fastint; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t}\n\t\telse\n#endif\n\t\tif (DUK_TVAL_IS_NUMBER(tv_key)) {\n\t\t\tarr_idx = duk__tval_number_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path number; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t\tpop_count = 1;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HBUFFER_GET_SIZE(h)) {\n\t\t\tduk_pop_n_unsafe(thr, pop_count);\n\t\t\tduk_push_uint(thr, ((duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h))[arr_idx]);\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_bufferidx);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is buffer, key is an index inside buffer length \"\n\t\t\t                     \"after coercion -> return byte as number)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (pop_count == 0) {\n\t\t\t/* This is a pretty awkward control flow, but we need to recheck the\n\t\t\t * key coercion here.\n\t\t\t */\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tduk_pop_unsafe(thr);  /* [key] -> [] */\n\t\t\tduk_push_uint(thr, (duk_uint_t) DUK_HBUFFER_GET_SIZE(h));  /* [] -> [res] */\n\t\t\tDUK_STATS_INC(thr->heap, stats_getprop_bufferlen);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (base is buffer, key is 'length' \"\n\t\t\t                     \"after coercion -> return buffer length)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\treturn 1;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a buffer, start lookup from Uint8Array prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_POINTER: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a pointer, start lookup from pointer prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Lightfuncs inherit getter .name and .length from %NativeFunctionPrototype%. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a lightfunc, start lookup from function prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE];\n\t\tbreak;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a number, start lookup from number prototype\"));\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_obj));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_obj));\n\t\tcurr = thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE];\n\t\tbreak;\n\t}\n\t}\n\n\t/* key coercion (unless already coerced above) */\n\tDUK_ASSERT(key == NULL);\n\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\tDUK_ASSERT(key != NULL);\n\t/*\n\t *  Property lookup\n\t */\n\n lookup:\n\t/* [key] (coerced) */\n\tDUK_ASSERT(curr != NULL);\n\tDUK_ASSERT(key != NULL);\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (!duk__get_own_propdesc_raw(thr, curr, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\t\tgoto next_in_chain;\n\t\t}\n\n\t\tif (desc.get != NULL) {\n\t\t\t/* accessor with defined getter */\n\t\t\tDUK_ASSERT((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) != 0);\n\n\t\t\tduk_pop_unsafe(thr);              /* [key undefined] -> [key] */\n\t\t\tduk_push_hobject(thr, desc.get);\n\t\t\tduk_push_tval(thr, tv_obj);       /* note: original, uncoerced base */\n#if defined(DUK_USE_NONSTD_GETTER_KEY_ARGUMENT)\n\t\t\tduk_dup_m3(thr);\n\t\t\tduk_call_method(thr, 1);          /* [key getter this key] -> [key retval] */\n#else\n\t\t\tduk_call_method(thr, 0);          /* [key getter this] -> [key retval] */\n#endif\n\t\t} else {\n\t\t\t/* [key value] or [key undefined] */\n\n\t\t\t/* data property or accessor without getter */\n\t\t\tDUK_ASSERT(((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) == 0) ||\n\t\t\t           (desc.get == NULL));\n\n\t\t\t/* if accessor without getter, return value is undefined */\n\t\t\tDUK_ASSERT(((desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) == 0) ||\n\t\t\t           duk_is_undefined(thr, -1));\n\n\t\t\t/* Note: for an accessor without getter, falling through to\n\t\t\t * check for \"caller\" exotic behavior is unnecessary as\n\t\t\t * \"undefined\" will never activate the behavior.  But it does\n\t\t\t * no harm, so we'll do it anyway.\n\t\t\t */\n\t\t}\n\n\t\tgoto found;  /* [key result] */\n\n\t next_in_chain:\n\t\t/* XXX: option to pretend property doesn't exist if sanity limit is\n\t\t * hit might be useful.\n\t\t */\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t} while (curr != NULL);\n\n\t/*\n\t *  Not found\n\t */\n\n\tduk_to_undefined(thr, -1);  /* [key] -> [undefined] (default value) */\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (not found)\", (duk_tval *) duk_get_tval(thr, -1)));\n\treturn 0;\n\n\t/*\n\t *  Found; post-processing (Function and arguments objects)\n\t */\n\n found:\n\t/* [key result] */\n\n#if !defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t/* Special behavior for 'caller' property of (non-bound) function objects\n\t * and non-strict Arguments objects: if 'caller' -value- (!) is a strict\n\t * mode function, throw a TypeError (E5 Sections 15.3.5.4, 10.6).\n\t * Quite interestingly, a non-strict function with no formal arguments\n\t * will get an arguments object -without- special 'caller' behavior!\n\t *\n\t * The E5.1 spec is a bit ambiguous if this special behavior applies when\n\t * a bound function is the base value (not the 'caller' value): Section\n\t * 15.3.4.5 (describing bind()) states that [[Get]] for bound functions\n\t * matches that of Section 15.3.5.4 ([[Get]] for Function instances).\n\t * However, Section 13.3.5.4 has \"NOTE: Function objects created using\n\t * Function.prototype.bind use the default [[Get]] internal method.\"\n\t * The current implementation assumes this means that bound functions\n\t * should not have the special [[Get]] behavior.\n\t *\n\t * The E5.1 spec is also a bit unclear if the TypeError throwing is\n\t * applied if the 'caller' value is a strict bound function.  The\n\t * current implementation will throw even for both strict non-bound\n\t * and strict bound functions.\n\t *\n\t * See test-dev-strict-func-as-caller-prop-value.js for quite extensive\n\t * tests.\n\t *\n\t * This exotic behavior is disabled when the non-standard 'caller' property\n\t * is enabled, as it conflicts with the free use of 'caller'.\n\t */\n\tif (key == DUK_HTHREAD_STRING_CALLER(thr) &&\n\t    DUK_TVAL_IS_OBJECT(tv_obj)) {\n\t\tduk_hobject *orig = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(orig != NULL);\n\n\t\tif (DUK_HOBJECT_IS_NONBOUND_FUNCTION(orig) ||\n\t\t    DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(orig)) {\n\t\t\tduk_hobject *h;\n\n\t\t\t/* XXX: The TypeError is currently not applied to bound\n\t\t\t * functions because the 'strict' flag is not copied by\n\t\t\t * bind().  This may or may not be correct, the specification\n\t\t\t * only refers to the value being a \"strict mode Function\n\t\t\t * object\" which is ambiguous.\n\t\t\t */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(orig));\n\n\t\t\th = duk_get_hobject(thr, -1);  /* NULL if not an object */\n\t\t\tif (h &&\n\t\t\t    DUK_HOBJECT_IS_FUNCTION(h) &&\n\t\t\t    DUK_HOBJECT_HAS_STRICT(h)) {\n\t\t\t\t/* XXX: sufficient to check 'strict', assert for 'is function' */\n\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_STRICT_CALLER_READ);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t}\n\t}\n#endif   /* !DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */\n\n\tduk_remove_m2(thr);  /* [key result] -> [result] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"-> %!T (found)\", (duk_tval *) duk_get_tval(thr, -1)));\n\treturn 1;\n}\n\n/*\n *  HASPROP: ECMAScript property existence check (\"in\" operator).\n *\n *  Interestingly, the 'in' operator does not do any coercion of\n *  the target object.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_hasprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key) {\n\tduk_tval tv_key_copy;\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_uint32_t arr_idx;\n\tduk_bool_t rc;\n\tduk_propdesc desc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"hasprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key,\n\t                     (duk_tval *) tv_obj, (duk_tval *) tv_key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);\n\ttv_key = &tv_key_copy;\n\n\t/*\n\t *  The 'in' operator requires an object as its right hand side,\n\t *  throwing a TypeError unconditionally if this is not the case.\n\t *\n\t *  However, lightfuncs need to behave like fully fledged objects\n\t *  here to be maximally transparent, so we need to handle them\n\t *  here.  Same goes for plain buffers which behave like ArrayBuffers.\n\t */\n\n\t/* XXX: Refactor key coercion so that it's only called once.  It can't\n\t * be trivially lifted here because the object must be type checked\n\t * first.\n\t */\n\n\tif (DUK_TVAL_IS_OBJECT(tv_obj)) {\n\t\tobj = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(obj != NULL);\n\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t} else if (DUK_TVAL_IS_BUFFER(tv_obj)) {\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\tif (duk__key_is_plain_buf_ownprop(thr, DUK_TVAL_GET_BUFFER(tv_obj), key, arr_idx)) {\n\t\t\trc = 1;\n\t\t\tgoto pop_and_return;\n\t\t}\n\t\tobj = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) {\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\n\t\t/* If not found, resume existence check from %NativeFunctionPrototype%.\n\t\t * We can just substitute the value in this case; nothing will\n\t\t * need the original base value (as would be the case with e.g.\n\t\t * setters/getters.\n\t\t */\n\t\tobj = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE];\n\t} else {\n\t\t/* Note: unconditional throw */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is not an object -> reject\"));\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* XXX: fast path for arrays? */\n\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(arr_idx);\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(obj))) {\n\t\tduk_hobject *h_target;\n\t\tduk_bool_t tmp_bool;\n\n\t\t/* XXX: the key in 'key in obj' is string coerced before we're called\n\t\t * (which is the required behavior in E5/E5.1/E6) so the key is a string\n\t\t * here already.\n\t\t */\n\n\t\tif (duk__proxy_check_prop(thr, obj, DUK_STRIDX_HAS, tv_key, &h_target)) {\n\t\t\t/* [ ... key trap handler ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'has' for key %!T\", (duk_tval *) tv_key));\n\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\tduk_push_tval(thr, tv_key);       /* P */\n\t\t\tduk_call_method(thr, 2 /*nargs*/);\n\t\t\ttmp_bool = duk_to_boolean_top_pop(thr);\n\t\t\tif (!tmp_bool) {\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'has': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\t\t\t\t\t/* XXX: Extensibility check for target uses IsExtensible().  If we\n\t\t\t\t\t * implemented the isExtensible trap and didn't reject proxies as\n\t\t\t\t\t * proxy targets, it should be respected here.\n\t\t\t\t\t */\n\t\t\t\t\tif (!((desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&  /* property is configurable and */\n\t\t\t\t\t      DUK_HOBJECT_HAS_EXTENSIBLE(h_target))) {          /* ... target is extensible */\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_pop_unsafe(thr);  /* [ key ] -> [] */\n\t\t\treturn tmp_bool;\n\t\t}\n\n\t\tobj = h_target;  /* resume check from proxy target */\n\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t/* XXX: inline into a prototype walking loop? */\n\n\trc = duk__get_propdesc(thr, obj, key, &desc, 0 /*flags*/);  /* don't push value */\n\t/* fall through */\n\n pop_and_return:\n\tduk_pop_unsafe(thr);  /* [ key ] -> [] */\n\treturn rc;\n}\n\n/*\n *  HASPROP variant used internally.\n *\n *  This primitive must never throw an error, callers rely on this.\n *  In particular, don't throw an error for prototype loops; instead,\n *  pretend like the property doesn't exist if a prototype sanity limit\n *  is reached.\n *\n *  Does not implement proxy behavior: if applied to a proxy object,\n *  returns key existence on the proxy object itself.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key) {\n\tduk_propdesc dummy;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\treturn duk__get_propdesc(thr, obj, key, &dummy, DUK_GETDESC_FLAG_IGNORE_PROTOLOOP);  /* don't push value */\n}\n\n/*\n *  Helper: handle Array object 'length' write which automatically\n *  deletes properties, see E5 Section 15.4.5.1, step 3.  This is\n *  quite tricky to get right.\n *\n *  Used by duk_hobject_putprop().\n */\n\n/* Coerce a new .length candidate to a number and check that it's a valid\n * .length.\n */\nDUK_LOCAL duk_uint32_t duk__to_new_array_length_checked(duk_hthread *thr, duk_tval *tv) {\n\tduk_uint32_t res;\n\tduk_double_t d;\n\n#if !defined(DUK_USE_PREFER_SIZE)\n#if defined(DUK_USE_FASTINT)\n\t/* When fastints are enabled, the most interesting case is assigning\n\t * a fastint to .length (e.g. arr.length = 0).\n\t */\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\t/* Very common case. */\n\t\tduk_int64_t fi;\n\t\tfi = DUK_TVAL_GET_FASTINT(tv);\n\t\tif (fi < 0 || fi > DUK_I64_CONSTANT(0xffffffff)) {\n\t\t\tgoto fail_range;\n\t\t}\n\t\treturn (duk_uint32_t) fi;\n\t}\n#else  /* DUK_USE_FASTINT */\n\t/* When fastints are not enabled, the most interesting case is any\n\t * number.\n\t */\n\tif (DUK_TVAL_IS_DOUBLE(tv)) {\n\t\td = DUK_TVAL_GET_NUMBER(tv);\n\t}\n#endif  /* DUK_USE_FASTINT */\n\telse\n#endif  /* !DUK_USE_PREFER_SIZE */\n\t{\n\t\t/* In all other cases, and when doing a size optimized build,\n\t\t * fall back to the comprehensive handler.\n\t\t */\n\t\td = duk_js_tonumber(thr, tv);\n\t}\n\n\t/* Refuse to update an Array's 'length' to a value outside the\n\t * 32-bit range.  Negative zero is accepted as zero.\n\t */\n\tres = duk_double_to_uint32_t(d);\n\tif ((duk_double_t) res != d) {\n\t\tgoto fail_range;\n\t}\n\n\treturn res;\n\n fail_range:\n\tDUK_ERROR_RANGE(thr, DUK_STR_INVALID_ARRAY_LENGTH);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Delete elements required by a smaller length, taking into account\n * potentially non-configurable elements.  Returns non-zero if all\n * elements could be deleted, and zero if all or some elements could\n * not be deleted.  Also writes final \"target length\" to 'out_result_len'.\n * This is the length value that should go into the 'length' property\n * (must be set by the caller).  Never throws an error.\n */\nDUK_LOCAL\nduk_bool_t duk__handle_put_array_length_smaller(duk_hthread *thr,\n                                                duk_hobject *obj,\n                                                duk_uint32_t old_len,\n                                                duk_uint32_t new_len,\n                                                duk_bool_t force_flag,\n                                                duk_uint32_t *out_result_len) {\n\tduk_uint32_t target_len;\n\tduk_uint_fast32_t i;\n\tduk_uint32_t arr_idx;\n\tduk_hstring *key;\n\tduk_tval *tv;\n\tduk_bool_t rc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"new array length smaller than old (%ld -> %ld), \"\n\t                     \"probably need to remove elements\",\n\t                     (long) old_len, (long) new_len));\n\n\t/*\n\t *  New length is smaller than old length, need to delete properties above\n\t *  the new length.\n\t *\n\t *  If array part exists, this is straightforward: array entries cannot\n\t *  be non-configurable so this is guaranteed to work.\n\t *\n\t *  If array part does not exist, array-indexed values are scattered\n\t *  in the entry part, and some may not be configurable (preventing length\n\t *  from becoming lower than their index + 1).  To handle the algorithm\n\t *  in E5 Section 15.4.5.1, step l correctly, we scan the entire property\n\t *  set twice.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(new_len < old_len);\n\tDUK_ASSERT(out_result_len != NULL);\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj));\n\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY(obj));\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t/*\n\t\t *  All defined array-indexed properties are in the array part\n\t\t *  (we assume the array part is comprehensive), and all array\n\t\t *  entries are writable, configurable, and enumerable.  Thus,\n\t\t *  nothing can prevent array entries from being deleted.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"have array part, easy case\"));\n\n\t\tif (old_len < DUK_HOBJECT_GET_ASIZE(obj)) {\n\t\t\t/* XXX: assertion that entries >= old_len are already unused */\n\t\t\ti = old_len;\n\t\t} else {\n\t\t\ti = DUK_HOBJECT_GET_ASIZE(obj);\n\t\t}\n\t\tDUK_ASSERT(i <= DUK_HOBJECT_GET_ASIZE(obj));\n\n\t\twhile (i > new_len) {\n\t\t\ti--;\n\t\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\t\tDUK_TVAL_SET_UNUSED_UPDREF(thr, tv);  /* side effects */\n\t\t}\n\n\t\t*out_result_len = new_len;\n\t\treturn 1;\n\t} else {\n\t\t/*\n\t\t *  Entries part is a bit more complex.\n\t\t */\n\n\t\t/* Stage 1: find highest preventing non-configurable entry (if any).\n\t\t * When forcing, ignore non-configurability.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"no array part, slow case\"));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part, stage 1: find target_len \"\n\t\t                     \"(highest preventing non-configurable entry (if any))\"));\n\n\t\ttarget_len = new_len;\n\t\tif (force_flag) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part; force flag -> skip stage 1\"));\n\t\t\tgoto skip_stage1;\n\t\t}\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);\n\t\t\tif (!key) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: null key\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!DUK_HSTRING_HAS_ARRIDX(key)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key not an array index\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(key));  /* XXX: macro checks for array index flag, which is unnecessary here */\n\t\t\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\t\t\tDUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX);\n\t\t\tDUK_ASSERT(arr_idx < old_len);  /* consistency requires this */\n\n\t\t\tif (arr_idx < new_len) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key is array index %ld, below new_len\",\n\t\t\t\t                     (long) i, (long) arr_idx));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(thr->heap, obj, i)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key is a relevant array index %ld, but configurable\",\n\t\t\t\t                     (long) i, (long) arr_idx));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* relevant array index is non-configurable, blocks write */\n\t\t\tif (arr_idx >= target_len) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"entry at index %ld has arr_idx %ld, is not configurable, \"\n\t\t\t\t                     \"update target_len %ld -> %ld\",\n\t\t\t\t                     (long) i, (long) arr_idx, (long) target_len,\n\t\t\t\t                     (long) (arr_idx + 1)));\n\t\t\t\ttarget_len = arr_idx + 1;\n\t\t\t}\n\t\t}\n\t skip_stage1:\n\n\t\t/* stage 2: delete configurable entries above target length */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"old_len=%ld, new_len=%ld, target_len=%ld\",\n\t\t                     (long) old_len, (long) new_len, (long) target_len));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part, stage 2: remove \"\n\t\t                     \"entries >= target_len\"));\n\n\t\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i);\n\t\t\tif (!key) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: null key\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!DUK_HSTRING_HAS_ARRIDX(key)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key not an array index\", (long) i));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tDUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(key));  /* XXX: macro checks for array index flag, which is unnecessary here */\n\t\t\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\t\t\tDUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX);\n\t\t\tDUK_ASSERT(arr_idx < old_len);  /* consistency requires this */\n\n\t\t\tif (arr_idx < target_len) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"skip entry index %ld: key is array index %ld, below target_len\",\n\t\t\t\t                     (long) i, (long) arr_idx));\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tDUK_ASSERT(force_flag || DUK_HOBJECT_E_SLOT_IS_CONFIGURABLE(thr->heap, obj, i));  /* stage 1 guarantees */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"delete entry index %ld: key is array index %ld\",\n\t\t\t                     (long) i, (long) arr_idx));\n\n\t\t\t/*\n\t\t\t *  Slow delete, but we don't care as we're already in a very slow path.\n\t\t\t *  The delete always succeeds: key has no exotic behavior, property\n\t\t\t *  is configurable, and no resize occurs.\n\t\t\t */\n\t\t\trc = duk_hobject_delprop_raw(thr, obj, key, force_flag ? DUK_DELPROP_FLAG_FORCE : 0);\n\t\t\tDUK_UNREF(rc);\n\t\t\tDUK_ASSERT(rc != 0);\n\t\t}\n\n\t\t/* stage 3: update length (done by caller), decide return code */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array length write, no array part, stage 3: update length (done by caller)\"));\n\n\t\t*out_result_len = target_len;\n\n\t\tif (target_len == new_len) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"target_len matches new_len, return success\"));\n\t\t\treturn 1;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"target_len does not match new_len (some entry prevented \"\n\t\t                     \"full length adjustment), return error\"));\n\t\treturn 0;\n\t}\n\n\tDUK_UNREACHABLE();\n}\n\n/* XXX: is valstack top best place for argument? */\nDUK_LOCAL duk_bool_t duk__handle_put_array_length(duk_hthread *thr, duk_hobject *obj) {\n\tduk_harray *a;\n\tduk_uint32_t old_len;\n\tduk_uint32_t new_len;\n\tduk_uint32_t result_len;\n\tduk_bool_t rc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"handling a put operation to array 'length' exotic property, \"\n\t                     \"new val: %!T\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj));\n\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY(obj));\n\ta = (duk_harray *) obj;\n\tDUK_HARRAY_ASSERT_VALID(a);\n\n\tDUK_ASSERT(duk_is_valid_index(thr, -1));\n\n\t/*\n\t *  Get old and new length\n\t */\n\n\told_len = a->length;\n\tnew_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_NEGIDX(thr, -1));\n\tDUK_DDD(DUK_DDDPRINT(\"old_len=%ld, new_len=%ld\", (long) old_len, (long) new_len));\n\n\t/*\n\t *  Writability check\n\t */\n\n\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"length is not writable, fail\"));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  New length not lower than old length => no changes needed\n\t *  (not even array allocation).\n\t */\n\n\tif (new_len >= old_len) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"new length is same or higher than old length, just update length, no deletions\"));\n\t\ta->length = new_len;\n\t\treturn 1;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"new length is lower than old length, probably must delete entries\"));\n\n\t/*\n\t *  New length lower than old length => delete elements, then\n\t *  update length.\n\t *\n\t *  Note: even though a bunch of elements have been deleted, the 'desc' is\n\t *  still valid as properties haven't been resized (and entries compacted).\n\t */\n\n\trc = duk__handle_put_array_length_smaller(thr, obj, old_len, new_len, 0 /*force_flag*/, &result_len);\n\tDUK_ASSERT(result_len >= new_len && result_len <= old_len);\n\n\ta->length = result_len;\n\n\t/* XXX: shrink array allocation or entries compaction here? */\n\n\treturn rc;\n}\n\n/*\n *  PUTPROP: ECMAScript property write.\n *\n *  Unlike ECMAScript primitive which returns nothing, returns 1 to indicate\n *  success and 0 to indicate failure (assuming throw is not set).\n *\n *  This is an extremely tricky function.  Some examples:\n *\n *    * Currently a decref may trigger a GC, which may compact an object's\n *      property allocation.  Consequently, any entry indices (e_idx) will\n *      be potentially invalidated by a decref.\n *\n *    * Exotic behaviors (strings, arrays, arguments object) require,\n *      among other things:\n *\n *      - Preprocessing before and postprocessing after an actual property\n *        write.  For example, array index write requires pre-checking the\n *        array 'length' property for access control, and may require an\n *        array 'length' update after the actual write has succeeded (but\n *        not if it fails).\n *\n *      - Deletion of multiple entries, as a result of array 'length' write.\n *\n *    * Input values are taken as pointers which may point to the valstack.\n *      If valstack is resized because of the put (this may happen at least\n *      when the array part is abandoned), the pointers can be invalidated.\n *      (We currently make a copy of all of the input values to avoid issues.)\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_putprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_tval *tv_val, duk_bool_t throw_flag) {\n\tduk_tval tv_obj_copy;\n\tduk_tval tv_key_copy;\n\tduk_tval tv_val_copy;\n\tduk_hobject *orig = NULL;  /* NULL if tv_obj is primitive */\n\tduk_hobject *curr;\n\tduk_hstring *key = NULL;\n\tduk_propdesc desc;\n\tduk_tval *tv;\n\tduk_uint32_t arr_idx;\n\tduk_bool_t rc;\n\tduk_int_t e_idx;\n\tduk_uint_t sanity;\n\tduk_uint32_t new_array_length = 0;  /* 0 = no update */\n\n\tDUK_DDD(DUK_DDDPRINT(\"putprop: thr=%p, obj=%p, key=%p, val=%p, throw=%ld \"\n\t                     \"(obj -> %!T, key -> %!T, val -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key, (void *) tv_val,\n\t                     (long) throw_flag, (duk_tval *) tv_obj, (duk_tval *) tv_key, (duk_tval *) tv_val));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\tDUK_ASSERT(tv_val != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tDUK_STATS_INC(thr->heap, stats_putprop_all);\n\n\t/*\n\t *  Make a copy of tv_obj, tv_key, and tv_val to avoid any issues of\n\t *  them being invalidated by a valstack resize.\n\t *\n\t *  XXX: this is an overkill for some paths, so optimize this later\n\t *  (or maybe switch to a stack arguments model entirely).\n\t */\n\n\tDUK_TVAL_SET_TVAL(&tv_obj_copy, tv_obj);\n\tDUK_TVAL_SET_TVAL(&tv_key_copy, tv_key);\n\tDUK_TVAL_SET_TVAL(&tv_val_copy, tv_val);\n\ttv_obj = &tv_obj_copy;\n\ttv_key = &tv_key_copy;\n\ttv_val = &tv_val_copy;\n\n\t/*\n\t *  Coercion and fast path processing.\n\t */\n\n\tswitch (DUK_TVAL_GET_TAG(tv_obj)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL: {\n\t\t/* Note: unconditional throw */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is undefined or null -> reject (object=%!iT)\",\n\t\t                     (duk_tval *) tv_obj));\n#if defined(DUK_USE_PARANOID_ERRORS)\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\t\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot write property %s of %s\",\n\t\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\t\tDUK_WO_NORETURN(return 0;);\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_BOOLEAN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a boolean, start lookup from boolean prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_BOOLEAN_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);\n\n\t\t/*\n\t\t *  Note: currently no fast path for array index writes.\n\t\t *  They won't be possible anyway as strings are immutable.\n\t\t */\n\n\t\tDUK_ASSERT(key == NULL);\n\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\t/* Symbols (ES2015 or hidden) don't have virtual properties. */\n\t\t\tcurr = thr->builtins[DUK_BIDX_SYMBOL_PROTOTYPE];\n\t\t\tgoto lookup;\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_writable;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {\n\t\t\tgoto fail_not_writable;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a string, start lookup from string prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_STRING_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_OBJECT: {\n\t\torig = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(orig != NULL);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\t\t/* With this check in place fast paths won't need read-only\n\t\t * object checks.  This is technically incorrect if there are\n\t\t * setters that cause no writes to ROM objects, but current\n\t\t * built-ins don't have such setters.\n\t\t */\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"attempt to putprop on read-only target object\"));\n\t\t\tgoto fail_not_writable_no_pop;  /* Must avoid duk_pop() in exit path */\n\t\t}\n#endif\n\n\t\t/* The fast path for array property put is not fully compliant:\n\t\t * If one places conflicting number-indexed properties into\n\t\t * Array.prototype (for example, a non-writable Array.prototype[7])\n\t\t * the fast path will incorrectly ignore them.\n\t\t *\n\t\t * This fast path could be made compliant by falling through\n\t\t * to the slow path if the previous value was UNUSED.  This would\n\t\t * also remove the need to check for extensibility.  Right now a\n\t\t * non-extensible array is slower than an extensible one as far\n\t\t * as writes are concerned.\n\t\t *\n\t\t * The fast path behavior is documented in more detail here:\n\t\t * tests/ecmascript/test-misc-array-fast-write.js\n\t\t */\n\n\t\t/* XXX: array .length? */\n\n#if defined(DUK_USE_ARRAY_PROP_FASTPATH)\n\t\tif (duk__putprop_shallow_fastpath_array_tval(thr, orig, tv_key, tv_val) != 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array fast path success\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_arrayidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\tif (duk__putprop_fastpath_bufobj_tval(thr, orig, tv_key, tv_val) != 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base is bufobj, key is a number, bufobj fast path\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_bufobjidx);\n\t\t\treturn 1;\n\t\t}\n#endif\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(orig))) {\n\t\t\tduk_hobject *h_target;\n\t\t\tduk_bool_t tmp_bool;\n\n\t\t\tif (duk__proxy_check_prop(thr, orig, DUK_STRIDX_SET, tv_key, &h_target)) {\n\t\t\t\t/* -> [ ... trap handler ] */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'set' for key %!T\", (duk_tval *) tv_key));\n\t\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_proxy);\n\t\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\t\tduk_push_tval(thr, tv_key);       /* P */\n\t\t\t\tduk_push_tval(thr, tv_val);       /* V */\n\t\t\t\tduk_push_tval(thr, tv_obj);       /* Receiver: Proxy object */\n\t\t\t\tduk_call_method(thr, 4 /*nargs*/);\n\t\t\t\ttmp_bool = duk_to_boolean_top_pop(thr);\n\t\t\t\tif (!tmp_bool) {\n\t\t\t\t\tgoto fail_proxy_rejected;\n\t\t\t\t}\n\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\t\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\t\t\t\tduk_tval *tv_targ = duk_require_tval(thr, -1);\n\t\t\t\t\tduk_bool_t datadesc_reject;\n\t\t\t\t\tduk_bool_t accdesc_reject;\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'set': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; tv_val=%!T, tv_targ=%!T, desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (duk_tval *) tv_val, (duk_tval *) tv_targ,\n\t\t\t\t\t                     (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\n\t\t\t\t\tdatadesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                  !(desc.flags & DUK_PROPDESC_FLAG_WRITABLE) &&\n\t\t\t\t\t                  !duk_js_samevalue(tv_val, tv_targ);\n\t\t\t\t\taccdesc_reject = (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t\t\t\t                 !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) &&\n\t\t\t\t\t                 (desc.set == NULL);\n\t\t\t\t\tif (datadesc_reject || accdesc_reject) {\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\n\t\t\t\t\tduk_pop_2_unsafe(thr);\n\t\t\t\t} else {\n\t\t\t\t\tduk_pop_unsafe(thr);\n\t\t\t\t}\n\t\t\t\treturn 1;  /* success */\n\t\t\t}\n\n\t\t\torig = h_target;  /* resume write to target */\n\t\t\tDUK_TVAL_SET_OBJECT(tv_obj, orig);\n\t\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t\tcurr = orig;\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_BUFFER: {\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);\n\t\tduk_int_t pop_count = 0;\n\n\t\t/*\n\t\t *  Because buffer values may be looped over and read/written\n\t\t *  from, an array index fast path is important.\n\t\t */\n\n#if defined(DUK_USE_FASTINT)\n\t\tif (DUK_TVAL_IS_FASTINT(tv_key)) {\n\t\t\tarr_idx = duk__tval_fastint_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path fastint; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else\n#endif\n\t\tif (DUK_TVAL_IS_NUMBER(tv_key)) {\n\t\t\tarr_idx = duk__tval_number_to_arr_idx(tv_key);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a fast-path number; arr_idx %ld\", (long) arr_idx));\n\t\t\tpop_count = 0;\n\t\t} else {\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t\tpop_count = 1;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HBUFFER_GET_SIZE(h)) {\n\t\t\tduk_uint8_t *data;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"writing to buffer data at index %ld\", (long) arr_idx));\n\t\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h);\n\n\t\t\t/* XXX: duk_to_int() ensures we'll get 8 lowest bits as\n\t\t\t * as input is within duk_int_t range (capped outside it).\n\t\t\t */\n#if defined(DUK_USE_FASTINT)\n\t\t\t/* Buffer writes are often integers. */\n\t\t\tif (DUK_TVAL_IS_FASTINT(tv_val)) {\n\t\t\t\tdata[arr_idx] = (duk_uint8_t) DUK_TVAL_GET_FASTINT_U32(tv_val);\n\t\t\t}\n\t\t\telse\n#endif\n\t\t\t{\n\t\t\t\tduk_push_tval(thr, tv_val);\n\t\t\t\tdata[arr_idx] = (duk_uint8_t) duk_to_uint32(thr, -1);\n\t\t\t\tpop_count++;\n\t\t\t}\n\n\t\t\tduk_pop_n_unsafe(thr, pop_count);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"result: success (buffer data write)\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_putprop_bufferidx);\n\t\t\treturn 1;\n\t\t}\n\n\t\tif (pop_count == 0) {\n\t\t\t/* This is a pretty awkward control flow, but we need to recheck the\n\t\t\t * key coercion here.\n\t\t\t */\n\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\tDUK_ASSERT(key != NULL);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"base object buffer, key is a non-fast-path number; after \"\n\t\t\t                     \"coercion key is %!T, arr_idx %ld\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) arr_idx));\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_writable;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a buffer, start lookup from Uint8Array prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tgoto lookup;  /* avoid double coercion */\n\t}\n\n\tcase DUK_TAG_POINTER: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a pointer, start lookup from pointer prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];\n\t\tbreak;\n\t}\n\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* Lightfuncs have no own properties and are considered non-extensible.\n\t\t * However, the write may be captured by an inherited setter which\n\t\t * means we can't stop the lookup here.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a lightfunc, start lookup from function prototype\"));\n\t\tcurr = thr->builtins[DUK_BIDX_NATIVE_FUNCTION_PROTOTYPE];\n\t\tbreak;\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is a number, start lookup from number prototype\"));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_obj));\n\t\tcurr = thr->builtins[DUK_BIDX_NUMBER_PROTOTYPE];\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_ASSERT(key == NULL);\n\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\tDUK_ASSERT(key != NULL);\n\n lookup:\n\n\t/*\n\t *  Check whether the property already exists in the prototype chain.\n\t *  Note that the actual write goes into the original base object\n\t *  (except if an accessor property captures the write).\n\t */\n\n\t/* [key] */\n\n\tDUK_ASSERT(curr != NULL);\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (!duk__get_own_propdesc_raw(thr, curr, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\t\tgoto next_in_chain;\n\t\t}\n\n\t\tif (desc.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t/*\n\t\t\t *  Found existing accessor property (own or inherited).\n\t\t\t *  Call setter with 'this' set to orig, and value as the only argument.\n\t\t\t *  Setter calls are OK even for ROM objects.\n\t\t\t *\n\t\t\t *  Note: no exotic arguments object behavior, because [[Put]] never\n\t\t\t *  calls [[DefineOwnProperty]] (E5 Section 8.12.5, step 5.b).\n\t\t\t */\n\n\t\t\tduk_hobject *setter;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"put to an own or inherited accessor, calling setter\"));\n\n\t\t\tsetter = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, curr, desc.e_idx);\n\t\t\tif (!setter) {\n\t\t\t\tgoto fail_no_setter;\n\t\t\t}\n\t\t\tduk_push_hobject(thr, setter);\n\t\t\tduk_push_tval(thr, tv_obj);  /* note: original, uncoerced base */\n\t\t\tduk_push_tval(thr, tv_val);  /* [key setter this val] */\n#if defined(DUK_USE_NONSTD_SETTER_KEY_ARGUMENT)\n\t\t\tduk_dup_m4(thr);\n\t\t\tduk_call_method(thr, 2);     /* [key setter this val key] -> [key retval] */\n#else\n\t\t\tduk_call_method(thr, 1);     /* [key setter this val] -> [key retval] */\n#endif\n\t\t\tduk_pop_unsafe(thr);         /* ignore retval -> [key] */\n\t\t\tgoto success_no_arguments_exotic;\n\t\t}\n\n\t\tif (orig == NULL) {\n\t\t\t/*\n\t\t\t *  Found existing own or inherited plain property, but original\n\t\t\t *  base is a primitive value.\n\t\t\t */\n\t\t\tDUK_DD(DUK_DDPRINT(\"attempt to create a new property in a primitive base object\"));\n\t\t\tgoto fail_base_primitive;\n\t\t}\n\n\t\tif (curr != orig) {\n\t\t\t/*\n\t\t\t *  Found existing inherited plain property.\n\t\t\t *  Do an access control check, and if OK, write\n\t\t\t *  new property to 'orig'.\n\t\t\t */\n\t\t\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(orig)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing inherited plain property, but original object is not extensible\"));\n\t\t\t\tgoto fail_not_extensible;\n\t\t\t}\n\t\t\tif (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing inherited plain property, original object is extensible, but inherited property is not writable\"));\n\t\t\t\tgoto fail_not_writable;\n\t\t\t}\n\t\t\tDUK_DD(DUK_DDPRINT(\"put to new property, object extensible, inherited property found and is writable\"));\n\t\t\tgoto create_new;\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Found existing own (non-inherited) plain property.\n\t\t\t *  Do an access control check and update in place.\n\t\t\t */\n\n\t\t\tif (!(desc.flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing own (non-inherited) plain property, but property is not writable\"));\n\t\t\t\tgoto fail_not_writable;\n\t\t\t}\n\t\t\tif (desc.flags & DUK_PROPDESC_FLAG_VIRTUAL) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"found existing own (non-inherited) virtual property, property is writable\"));\n\n\t\t\t\tif (DUK_HOBJECT_IS_ARRAY(curr)) {\n\t\t\t\t\t/*\n\t\t\t\t\t *  Write to 'length' of an array is a very complex case\n\t\t\t\t\t *  handled in a helper which updates both the array elements\n\t\t\t\t\t *  and writes the new 'length'.  The write may result in an\n\t\t\t\t\t *  unconditional RangeError or a partial write (indicated\n\t\t\t\t\t *  by a return code).\n\t\t\t\t\t *\n\t\t\t\t\t *  Note: the helper has an unnecessary writability check\n\t\t\t\t\t *  for 'length', we already know it is writable.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_ASSERT(key == DUK_HTHREAD_STRING_LENGTH(thr));  /* only virtual array property */\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"writing existing 'length' property to array exotic, invoke complex helper\"));\n\n\t\t\t\t\t/* XXX: the helper currently assumes stack top contains new\n\t\t\t\t\t * 'length' value and the whole calling convention is not very\n\t\t\t\t\t * compatible with what we need.\n\t\t\t\t\t */\n\n\t\t\t\t\tduk_push_tval(thr, tv_val);  /* [key val] */\n\t\t\t\t\trc = duk__handle_put_array_length(thr, orig);\n\t\t\t\t\tduk_pop_unsafe(thr);  /* [key val] -> [key] */\n\t\t\t\t\tif (!rc) {\n\t\t\t\t\t\tgoto fail_array_length_partial;\n\t\t\t\t\t}\n\n\t\t\t\t\t/* key is 'length', cannot match argument exotic behavior */\n\t\t\t\t\tgoto success_no_arguments_exotic;\n\t\t\t\t}\n#if defined(DUK_USE_BUFFEROBJECT_SUPPORT)\n\t\t\t\telse if (DUK_HOBJECT_IS_BUFOBJ(curr)) {\n\t\t\t\t\tduk_hbufobj *h_bufobj;\n\t\t\t\t\tduk_uint_t byte_off;\n\t\t\t\t\tduk_small_uint_t elem_size;\n\n\t\t\t\t\th_bufobj = (duk_hbufobj *) curr;\n\t\t\t\t\tDUK_HBUFOBJ_ASSERT_VALID(h_bufobj);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"writable virtual property is in buffer object\"));\n\n\t\t\t\t\t/* Careful with wrapping: arr_idx upshift may easily wrap, whereas\n\t\t\t\t\t * length downshift won't.\n\t\t\t\t\t */\n\t\t\t\t\tif (arr_idx < (h_bufobj->length >> h_bufobj->shift) && DUK_HBUFOBJ_HAS_VIRTUAL_INDICES(h_bufobj)) {\n\t\t\t\t\t\tduk_uint8_t *data;\n\t\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"writing to buffer data at index %ld\", (long) arr_idx));\n\n\t\t\t\t\t\tDUK_ASSERT(arr_idx != DUK__NO_ARRAY_INDEX);  /* index/length check guarantees */\n\t\t\t\t\t\tbyte_off = arr_idx << h_bufobj->shift;       /* no wrap assuming h_bufobj->length is valid */\n\t\t\t\t\t\telem_size = (duk_small_uint_t) (1U << h_bufobj->shift);\n\n\t\t\t\t\t\t/* Coerce to number before validating pointers etc so that the\n\t\t\t\t\t\t * number coercions in duk_hbufobj_validated_write() are\n\t\t\t\t\t\t * guaranteed to be side effect free and not invalidate the\n\t\t\t\t\t\t * pointer checks we do here.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk_push_tval(thr, tv_val);\n\t\t\t\t\t\t(void) duk_to_number_m1(thr);\n\n\t\t\t\t\t\tif (h_bufobj->buf != NULL && DUK_HBUFOBJ_VALID_BYTEOFFSET_EXCL(h_bufobj, byte_off + elem_size)) {\n\t\t\t\t\t\t\tdata = (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(thr->heap, h_bufobj->buf) + h_bufobj->offset + byte_off;\n\t\t\t\t\t\t\tduk_hbufobj_validated_write(thr, h_bufobj, data, elem_size);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tDUK_D(DUK_DPRINT(\"bufobj access out of underlying buffer, ignoring (write skipped)\"));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tduk_pop_unsafe(thr);\n\t\t\t\t\t\tgoto success_no_arguments_exotic;\n\t\t\t\t\t}\n\t\t\t\t}\n#endif  /* DUK_USE_BUFFEROBJECT_SUPPORT */\n\n\t\t\t\tDUK_D(DUK_DPRINT(\"should not happen, key %!O\", key));\n\t\t\t\tgoto fail_internal;  /* should not happen */\n\t\t\t}\n\t\t\tDUK_DD(DUK_DDPRINT(\"put to existing own plain property, property is writable\"));\n\t\t\tgoto update_old;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\n\t next_in_chain:\n\t\t/* XXX: option to pretend property doesn't exist if sanity limit is\n\t\t * hit might be useful.\n\t\t */\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tcurr = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, curr);\n\t} while (curr != NULL);\n\n\t/*\n\t *  Property not found in prototype chain.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"property not found in prototype chain\"));\n\n\tif (orig == NULL) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to create a new property in a primitive base object\"));\n\t\tgoto fail_base_primitive;\n\t}\n\n\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(orig)) {\n\t\tDUK_DD(DUK_DDPRINT(\"put to a new property (not found in prototype chain), but original object not extensible\"));\n\t\tgoto fail_not_extensible;\n\t}\n\n\tgoto create_new;\n\n update_old:\n\n\t/*\n\t *  Update an existing property of the base object.\n\t */\n\n\t/* [key] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"update an existing property of the original object\"));\n\n\tDUK_ASSERT(orig != NULL);\n#if defined(DUK_USE_ROM_OBJECTS)\n\t/* This should not happen because DUK_TAG_OBJECT case checks\n\t * for this already, but check just in case.\n\t */\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {\n\t\tgoto fail_not_writable;\n\t}\n#endif\n\n\t/* Although there are writable virtual properties (e.g. plain buffer\n\t * and buffer object number indices), they are handled before we come\n\t * here.\n\t */\n\tDUK_ASSERT((desc.flags & DUK_PROPDESC_FLAG_VIRTUAL) == 0);\n\tDUK_ASSERT(desc.a_idx >= 0 || desc.e_idx >= 0);\n\n\t/* Array own property .length is handled above. */\n\tDUK_ASSERT(!(DUK_HOBJECT_IS_ARRAY(orig) && key == DUK_HTHREAD_STRING_LENGTH(thr)));\n\n\tif (desc.e_idx >= 0) {\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, desc.e_idx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"previous entry value: %!iT\", (duk_tval *) tv));\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val);  /* side effects; e_idx may be invalidated */\n\t\t/* don't touch property attributes or hash part */\n\t\tDUK_DD(DUK_DDPRINT(\"put to an existing entry at index %ld -> new value %!iT\",\n\t\t                   (long) desc.e_idx, (duk_tval *) tv));\n\t} else {\n\t\t/* Note: array entries are always writable, so the writability check\n\t\t * above is pointless for them.  The check could be avoided with some\n\t\t * refactoring but is probably not worth it.\n\t\t */\n\n\t\tDUK_ASSERT(desc.a_idx >= 0);\n\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, orig, desc.a_idx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"previous array value: %!iT\", (duk_tval *) tv));\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv_val);  /* side effects; a_idx may be invalidated */\n\t\tDUK_DD(DUK_DDPRINT(\"put to an existing array entry at index %ld -> new value %!iT\",\n\t\t                   (long) desc.a_idx, (duk_tval *) tv));\n\t}\n\n\t/* Regardless of whether property is found in entry or array part,\n\t * it may have arguments exotic behavior (array indices may reside\n\t * in entry part for abandoned / non-existent array parts).\n\t */\n\tgoto success_with_arguments_exotic;\n\n create_new:\n\n\t/*\n\t *  Create a new property in the original object.\n\t *\n\t *  Exotic properties need to be reconsidered here from a write\n\t *  perspective (not just property attributes perspective).\n\t *  However, the property does not exist in the object already,\n\t *  so this limits the kind of exotic properties that apply.\n\t */\n\n\t/* [key] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"create new property to original object\"));\n\n\tDUK_ASSERT(orig != NULL);\n\n\t/* Array own property .length is handled above. */\n\tDUK_ASSERT(!(DUK_HOBJECT_IS_ARRAY(orig) && key == DUK_HTHREAD_STRING_LENGTH(thr)));\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\t/* This should not happen because DUK_TAG_OBJECT case checks\n\t * for this already, but check just in case.\n\t */\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) orig)) {\n\t\tgoto fail_not_writable;\n\t}\n#endif\n\n\t/* Not possible because array object 'length' is present\n\t * from its creation and cannot be deleted, and is thus\n\t * caught as an existing property above.\n\t */\n\tDUK_ASSERT(!(DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig) &&\n\t             key == DUK_HTHREAD_STRING_LENGTH(thr)));\n\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig) &&\n\t    arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t/* automatic length update */\n\t\tduk_uint32_t old_len;\n\t\tduk_harray *a;\n\n\t\ta = (duk_harray *) orig;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\told_len = a->length;\n\n\t\tif (arr_idx >= old_len) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"write new array entry requires length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\n\t\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a)) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"attempt to extend array, but array 'length' is not writable\"));\n\t\t\t\tgoto fail_not_writable;\n\t\t\t}\n\n\t\t\t/* Note: actual update happens once write has been completed\n\t\t\t * without error below.  The write should always succeed\n\t\t\t * from a specification viewpoint, but we may e.g. run out\n\t\t\t * of memory.  It's safer in this order.\n\t\t\t */\n\n\t\t\tDUK_ASSERT(arr_idx != 0xffffffffUL);\n\t\t\tnew_array_length = arr_idx + 1;  /* flag for later write */\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"write new array entry does not require length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\t\t}\n\t}\n\n /* write_to_array_part: */\n\n\t/*\n\t *  Write to array part?\n\t *\n\t *  Note: array abandonding requires a property resize which uses\n\t *  'rechecks' valstack for temporaries and may cause any existing\n\t *  valstack pointers to be invalidated.  To protect against this,\n\t *  tv_obj, tv_key, and tv_val are copies of the original inputs.\n\t */\n\n\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(orig)) {\n\t\ttv = duk__obtain_arridx_slot(thr, arr_idx, orig);\n\t\tif (tv == NULL) {\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(orig));\n\t\t\tgoto write_to_entry_part;\n\t\t}\n\n\t\t/* prev value must be unused, no decref */\n\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_TVAL_SET_TVAL(tv, tv_val);\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\tDUK_DD(DUK_DDPRINT(\"put to new array entry: %ld -> %!T\",\n\t\t                   (long) arr_idx, (duk_tval *) tv));\n\n\t\t/* Note: array part values are [[Writable]], [[Enumerable]],\n\t\t * and [[Configurable]] which matches the required attributes\n\t\t * here.\n\t\t */\n\t\tgoto entry_updated;\n\t}\n\n write_to_entry_part:\n\n\t/*\n\t *  Write to entry part\n\t */\n\n\t/* entry allocation updates hash part and increases the key\n\t * refcount; may need a props allocation resize but doesn't\n\t * 'recheck' the valstack.\n\t */\n\te_idx = duk__hobject_alloc_entry_checked(thr, orig, key);\n\tDUK_ASSERT(e_idx >= 0);\n\n\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, orig, e_idx);\n\t/* prev value can be garbage, no decref */\n\tDUK_TVAL_SET_TVAL(tv, tv_val);\n\tDUK_TVAL_INCREF(thr, tv);\n\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, orig, e_idx, DUK_PROPDESC_FLAGS_WEC);\n\tgoto entry_updated;\n\n entry_updated:\n\n\t/*\n\t *  Possible pending array length update, which must only be done\n\t *  if the actual entry write succeeded.\n\t */\n\n\tif (new_array_length > 0) {\n\t\t/* Note: zero works as a \"no update\" marker because the new length\n\t\t * can never be zero after a new property is written.\n\t\t */\n\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(orig));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"write successful, pending array length update to: %ld\",\n\t\t                     (long) new_array_length));\n\n\t\t((duk_harray *) orig)->length = new_array_length;\n\t}\n\n\t/*\n\t *  Arguments exotic behavior not possible for new properties: all\n\t *  magically bound properties are initially present in the arguments\n\t *  object, and if they are deleted, the binding is also removed from\n\t *  parameter map.\n\t */\n\n\tgoto success_no_arguments_exotic;\n\n success_with_arguments_exotic:\n\n\t/*\n\t *  Arguments objects have exotic [[DefineOwnProperty]] which updates\n\t *  the internal 'map' of arguments for writes to currently mapped\n\t *  arguments.  More conretely, writes to mapped arguments generate\n\t *  a write to a bound variable.\n\t *\n\t *  The [[Put]] algorithm invokes [[DefineOwnProperty]] for existing\n\t *  data properties and new properties, but not for existing accessors.\n\t *  Hence, in E5 Section 10.6 ([[DefinedOwnProperty]] algorithm), we\n\t *  have a Desc with 'Value' (and possibly other properties too), and\n\t *  we end up in step 5.b.i.\n\t */\n\n\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t    DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(orig)) {\n\t\t/* Note: only numbered indices are relevant, so arr_idx fast reject\n\t\t * is good (this is valid unless there are more than 4**32-1 arguments).\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"putprop successful, arguments exotic behavior needed\"));\n\n\t\t/* Note: we can reuse 'desc' here */\n\n\t\t/* XXX: top of stack must contain value, which helper doesn't touch,\n\t\t * rework to use tv_val directly?\n\t\t */\n\n\t\tduk_push_tval(thr, tv_val);\n\t\t(void) duk__check_arguments_map_for_put(thr, orig, key, &desc, throw_flag);\n\t\tduk_pop_unsafe(thr);\n\t}\n\t/* fall thru */\n\n success_no_arguments_exotic:\n\t/* shared exit path now */\n\tDUK_DDD(DUK_DDDPRINT(\"result: success\"));\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 1;\n\n#if defined(DUK_USE_ES6_PROXY)\n fail_proxy_rejected:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, proxy rejects\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\t/* Note: no key on stack */\n\treturn 0;\n#endif\n\n fail_base_primitive:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, base primitive\"));\n\tif (throw_flag) {\n#if defined(DUK_USE_PARANOID_ERRORS)\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\t\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot write property %s of %s\",\n\t\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_not_extensible:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, not extensible\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_not_writable:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, not writable\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n#if defined(DUK_USE_ROM_OBJECTS)\n fail_not_writable_no_pop:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, not writable\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_WRITABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n#endif\n\n fail_array_length_partial:\n\tDUK_DD(DUK_DDPRINT(\"result: error, array length write only partially successful\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_no_setter:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, accessor property without setter\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_SETTER_UNDEFINED);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n\n fail_internal:\n\tDUK_DDD(DUK_DDDPRINT(\"result: error, internal\"));\n\tif (throw_flag) {\n\t\tDUK_ERROR_INTERNAL(thr);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_pop_unsafe(thr);  /* remove key */\n\treturn 0;\n}\n\n/*\n *  ECMAScript compliant [[Delete]](P, Throw).\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_delprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags) {\n\tduk_propdesc desc;\n\tduk_tval *tv;\n\tduk_uint32_t arr_idx;\n\tduk_bool_t throw_flag;\n\tduk_bool_t force_flag;\n\n\tthrow_flag = (flags & DUK_DELPROP_FLAG_THROW);\n\tforce_flag = (flags & DUK_DELPROP_FLAG_FORCE);\n\n\tDUK_DDD(DUK_DDDPRINT(\"delprop_raw: thr=%p, obj=%p, key=%p, throw=%ld, force=%ld (obj -> %!O, key -> %!O)\",\n\t                     (void *) thr, (void *) obj, (void *) key, (long) throw_flag, (long) force_flag,\n\t                     (duk_heaphdr *) obj, (duk_heaphdr *) key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_FAST(key);\n\n\t/* 0 = don't push current value */\n\tif (!duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\tDUK_DDD(DUK_DDDPRINT(\"property not found, succeed always\"));\n\t\tgoto success;\n\t}\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to delprop on read-only target object\"));\n\t\tgoto fail_not_configurable;\n\t}\n#endif\n\n\tif ((desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) == 0 && !force_flag) {\n\t\tgoto fail_not_configurable;\n\t}\n\tif (desc.a_idx < 0 && desc.e_idx < 0) {\n\t\t/* Currently there are no deletable virtual properties, but\n\t\t * with force_flag we might attempt to delete one.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"delete failed: property found, force flag, but virtual (and implicitly non-configurable)\"));\n\t\tgoto fail_virtual;\n\t}\n\n\tif (desc.a_idx >= 0) {\n\t\tDUK_ASSERT(desc.e_idx < 0);\n\n\t\ttv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx);\n\t\tDUK_TVAL_SET_UNUSED_UPDREF(thr, tv);  /* side effects */\n\t\tgoto success;\n\t} else {\n\t\tDUK_ASSERT(desc.a_idx < 0);\n\n\t\t/* remove hash entry (no decref) */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n\t\tif (desc.h_idx >= 0) {\n\t\t\tduk_uint32_t *h_base = DUK_HOBJECT_H_GET_BASE(thr->heap, obj);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"removing hash entry at h_idx %ld\", (long) desc.h_idx));\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) > 0);\n\t\t\tDUK_ASSERT((duk_uint32_t) desc.h_idx < DUK_HOBJECT_GET_HSIZE(obj));\n\t\t\th_base[desc.h_idx] = DUK__HASH_DELETED;\n\t\t} else {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) == 0);\n\t\t}\n#else\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(obj) == 0);\n#endif\n\n\t\t/* Remove value.  This requires multiple writes so avoid side\n\t\t * effects via no-refzero macros so that e_idx is not\n\t\t * invalidated.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"before removing value, e_idx %ld, key %p, key at slot %p\",\n\t\t                     (long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)));\n\t\tDUK_DDD(DUK_DDDPRINT(\"removing value at e_idx %ld\", (long) desc.e_idx));\n\t\tif (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx)) {\n\t\t\tduk_hobject *tmp;\n\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, desc.e_idx);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, desc.e_idx, NULL);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, desc.e_idx);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, desc.e_idx, NULL);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\t\t} else {\n\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv);\n\t\t}\n#if 0\n\t\t/* Not strictly necessary because if key == NULL, flag MUST be ignored. */\n\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, 0);\n#endif\n\n\t\t/* Remove key. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"before removing key, e_idx %ld, key %p, key at slot %p\",\n\t\t                     (long) desc.e_idx, (void *) key, (void *) DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx)));\n\t\tDUK_DDD(DUK_DDDPRINT(\"removing key at e_idx %ld\", (long) desc.e_idx));\n\t\tDUK_ASSERT(key == DUK_HOBJECT_E_GET_KEY(thr->heap, obj, desc.e_idx));\n\t\tDUK_HOBJECT_E_SET_KEY(thr->heap, obj, desc.e_idx, NULL);\n\t\tDUK_HSTRING_DECREF_NORZ(thr, key);\n\n\t\t/* Trigger refzero side effects only when we're done as a\n\t\t * finalizer might operate on the object and affect the\n\t\t * e_idx we're supposed to use.\n\t\t */\n\t\tDUK_REFZERO_CHECK_SLOW(thr);\n\t\tgoto success;\n\t}\n\n\tDUK_UNREACHABLE();\n\n success:\n\t/*\n\t *  Argument exotic [[Delete]] behavior (E5 Section 10.6) is\n\t *  a post-check, keeping arguments internal 'map' in sync with\n\t *  any successful deletes (note that property does not need to\n\t *  exist for delete to 'succeed').\n\t *\n\t *  Delete key from 'map'.  Since 'map' only contains array index\n\t *  keys, we can use arr_idx for a fast skip.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"delete successful, check for arguments exotic behavior\"));\n\n\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)) {\n\t\t/* Note: only numbered indices are relevant, so arr_idx fast reject\n\t\t * is good (this is valid unless there are more than 4**32-1 arguments).\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"delete successful, arguments exotic behavior needed\"));\n\n\t\t/* Note: we can reuse 'desc' here */\n\t\t(void) duk__check_arguments_map_for_delete(thr, obj, key, &desc);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"delete successful\"));\n\treturn 1;\n\n fail_virtual:  /* just use the same \"not configurable\" error message */\n fail_not_configurable:\n\tDUK_DDD(DUK_DDDPRINT(\"delete failed: property found, not configurable\"));\n\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n}\n\n/*\n *  DELPROP: ECMAScript property deletion.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_delprop(duk_hthread *thr, duk_tval *tv_obj, duk_tval *tv_key, duk_bool_t throw_flag) {\n\tduk_hstring *key = NULL;\n#if defined(DUK_USE_ES6_PROXY)\n\tduk_propdesc desc;\n#endif\n\tduk_int_t entry_top;\n\tduk_uint32_t arr_idx = DUK__NO_ARRAY_INDEX;\n\tduk_bool_t rc;\n\n\tDUK_DDD(DUK_DDDPRINT(\"delprop: thr=%p, obj=%p, key=%p (obj -> %!T, key -> %!T)\",\n\t                     (void *) thr, (void *) tv_obj, (void *) tv_key,\n\t                     (duk_tval *) tv_obj, (duk_tval *) tv_key));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(tv_obj != NULL);\n\tDUK_ASSERT(tv_key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\t/* Storing the entry top is cheaper here to ensure stack is correct at exit,\n\t * as there are several paths out.\n\t */\n\tentry_top = duk_get_top(thr);\n\n\tif (DUK_TVAL_IS_UNDEFINED(tv_obj) ||\n\t    DUK_TVAL_IS_NULL(tv_obj)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"base object is undefined or null -> reject\"));\n\t\tgoto fail_invalid_base_uncond;\n\t}\n\n\tduk_push_tval(thr, tv_obj);\n\tduk_push_tval(thr, tv_key);\n\n\ttv_obj = DUK_GET_TVAL_NEGIDX(thr, -2);\n\tif (DUK_TVAL_IS_OBJECT(tv_obj)) {\n\t\tduk_hobject *obj = DUK_TVAL_GET_OBJECT(tv_obj);\n\t\tDUK_ASSERT(obj != NULL);\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(obj))) {\n\t\t\tduk_hobject *h_target;\n\t\t\tduk_bool_t tmp_bool;\n\n\t\t\t/* Note: proxy handling must happen before key is string coerced. */\n\n\t\t\tif (duk__proxy_check_prop(thr, obj, DUK_STRIDX_DELETE_PROPERTY, tv_key, &h_target)) {\n\t\t\t\t/* -> [ ... obj key trap handler ] */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"-> proxy object 'deleteProperty' for key %!T\", (duk_tval *) tv_key));\n\t\t\t\tduk_push_hobject(thr, h_target);  /* target */\n\t\t\t\tduk_dup_m4(thr);  /* P */\n\t\t\t\tduk_call_method(thr, 2 /*nargs*/);\n\t\t\t\ttmp_bool = duk_to_boolean_top_pop(thr);\n\t\t\t\tif (!tmp_bool) {\n\t\t\t\t\tgoto fail_proxy_rejected;  /* retval indicates delete failed */\n\t\t\t\t}\n\n\t\t\t\t/* Target object must be checked for a conflicting\n\t\t\t\t * non-configurable property.\n\t\t\t\t */\n\t\t\t\ttv_key = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\t\t\tarr_idx = duk__push_tval_to_property_key(thr, tv_key, &key);\n\t\t\t\tDUK_ASSERT(key != NULL);\n\n\t\t\t\tif (duk__get_own_propdesc_raw(thr, h_target, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\t\t\t\tduk_small_int_t desc_reject;\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"proxy 'deleteProperty': target has matching property %!O, check for \"\n\t\t\t\t\t                     \"conflicting property; desc.flags=0x%08lx, \"\n\t\t\t\t\t                     \"desc.get=%p, desc.set=%p\",\n\t\t\t\t\t                     (duk_heaphdr *) key, (unsigned long) desc.flags,\n\t\t\t\t\t                     (void *) desc.get, (void *) desc.set));\n\n\t\t\t\t\tdesc_reject = !(desc.flags & DUK_PROPDESC_FLAG_CONFIGURABLE);\n\t\t\t\t\tif (desc_reject) {\n\t\t\t\t\t\t/* unconditional */\n\t\t\t\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\t\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\trc = 1;  /* success */\n\t\t\t\tgoto done_rc;\n\t\t\t}\n\n\t\t\tobj = h_target;  /* resume delete to target */\n\t\t}\n#endif  /* DUK_USE_ES6_PROXY */\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\trc = duk_hobject_delprop_raw(thr, obj, key, throw_flag ? DUK_DELPROP_FLAG_THROW : 0);\n\t\tgoto done_rc;\n\t} else if (DUK_TVAL_IS_STRING(tv_obj)) {\n\t\t/* String has .length and array index virtual properties\n\t\t * which can't be deleted.  No need for a symbol check;\n\t\t * no offending virtual symbols exist.\n\t\t */\n\t\t/* XXX: unnecessary string coercion for array indices,\n\t\t * intentional to keep small.\n\t\t */\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv_obj);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HSTRING_GET_CHARLEN(h)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\t} else if (DUK_TVAL_IS_BUFFER(tv_obj)) {\n\t\t/* XXX: unnecessary string coercion for array indices,\n\t\t * intentional to keep small; some overlap with string\n\t\t * handling.\n\t\t */\n\t\tduk_hbuffer *h = DUK_TVAL_GET_BUFFER(tv_obj);\n\t\tDUK_ASSERT(h != NULL);\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX &&\n\t\t    arr_idx < DUK_HBUFFER_GET_SIZE(h)) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_obj)) {\n\t\t/* Lightfunc has no virtual properties since Duktape 2.2\n\t\t * so success.  Still must coerce key for side effects.\n\t\t */\n\n\t\tarr_idx = duk__to_property_key(thr, -1, &key);\n\t\tDUK_ASSERT(key != NULL);\n\t\tDUK_UNREF(key);\n\t}\n\n\t/* non-object base, no offending virtual property */\n\trc = 1;\n\tgoto done_rc;\n\n done_rc:\n\tduk_set_top_unsafe(thr, entry_top);\n\treturn rc;\n\n fail_invalid_base_uncond:\n\t/* Note: unconditional throw */\n\tDUK_ASSERT(duk_get_top(thr) == entry_top);\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_BASE);\n#else\n\tDUK_ERROR_FMT2(thr, DUK_ERR_TYPE_ERROR, \"cannot delete property %s of %s\",\n\t               duk_push_string_tval_readable(thr, tv_key), duk_push_string_tval_readable(thr, tv_obj));\n#endif\n\tDUK_WO_NORETURN(return 0;);\n\n#if defined(DUK_USE_ES6_PROXY)\n fail_proxy_rejected:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_PROXY_REJECTED);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_set_top_unsafe(thr, entry_top);\n\treturn 0;\n#endif\n\n fail_not_configurable:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tduk_set_top_unsafe(thr, entry_top);\n\treturn 0;\n}\n\n/*\n *  Internal helper to define a property with specific flags, ignoring\n *  normal semantics such as extensibility, write protection etc.\n *  Overwrites any existing value and attributes unless caller requests\n *  that value only be updated if it doesn't already exists.\n *\n *  Does not support:\n *    - virtual properties (error if write attempted)\n *    - getter/setter properties (error if write attempted)\n *    - non-default (!= WEC) attributes for array entries (error if attempted)\n *    - array abandoning: if array part exists, it is always extended\n *    - array 'length' updating\n *\n *  Stack: [... in_val] -> []\n *\n *  Used for e.g. built-in initialization and environment record\n *  operations.\n */\n\nDUK_INTERNAL void duk_hobject_define_property_internal(duk_hthread *thr, duk_hobject *obj, duk_hstring *key, duk_small_uint_t flags) {\n\tduk_propdesc desc;\n\tduk_uint32_t arr_idx;\n\tduk_int_t e_idx;\n\tduk_tval *tv1 = NULL;\n\tduk_tval *tv2 = NULL;\n\tduk_small_uint_t propflags = flags & DUK_PROPDESC_FLAGS_MASK;  /* mask out flags not actually stored */\n\n\tDUK_DDD(DUK_DDDPRINT(\"define new property (internal): thr=%p, obj=%!O, key=%!O, flags=0x%02lx, val=%!T\",\n\t                     (void *) thr, (duk_heaphdr *) obj, (duk_heaphdr *) key,\n\t                     (unsigned long) flags, (duk_tval *) duk_get_tval(thr, -1)));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\tDUK_ASSERT(duk_is_valid_index(thr, -1));  /* contains value */\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\n\tif (duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &desc, 0 /*flags*/)) {  /* don't push value */\n\t\tif (desc.e_idx >= 0) {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the entry part -> skip as requested\"));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the entry part -> update value and attributes\"));\n\t\t\tif (DUK_UNLIKELY(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, desc.e_idx))) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"existing property is an accessor, not supported\"));\n\t\t\t\tgoto error_internal;\n\t\t\t}\n\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, desc.e_idx, propflags);\n\t\t\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, desc.e_idx);\n\t\t} else if (desc.a_idx >= 0) {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the array part -> skip as requested\"));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists in the array part -> update value (assert attributes)\"));\n\t\t\tif (propflags != DUK_PROPDESC_FLAGS_WEC) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"existing property in array part, but propflags not WEC (0x%02lx)\",\n\t\t\t\t                 (unsigned long) propflags));\n\t\t\t\tgoto error_internal;\n\t\t\t}\n\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, desc.a_idx);\n\t\t} else {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property already exists but is virtual -> skip as requested\"));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\t\t\tduk_uint32_t new_len;\n#if defined(DUK_USE_DEBUG)\n\t\t\t\tduk_uint32_t prev_len;\n\t\t\t\tprev_len = ((duk_harray *) obj)->length;\n#endif\n\t\t\t\tnew_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_NEGIDX(thr, -1));\n\t\t\t\t((duk_harray *) obj)->length = new_len;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"internal define property for array .length: %ld -> %ld\",\n\t\t\t\t                   (long) prev_len, (long) ((duk_harray *) obj)->length));\n\t\t\t\tgoto pop_exit;\n\t\t\t}\n\t\t\tDUK_DD(DUK_DDPRINT(\"property already exists but is virtual -> failure\"));\n\t\t\tgoto error_virtual;\n\t\t}\n\n\t\tgoto write_value;\n\t}\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\tif (arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"property does not exist, object has array part -> possibly extend array part and write value (assert attributes)\"));\n\t\t\tDUK_ASSERT(propflags == DUK_PROPDESC_FLAGS_WEC);\n\n\t\t\ttv1 = duk__obtain_arridx_slot(thr, arr_idx, obj);\n\t\t\tif (tv1 == NULL) {\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\t\t\tgoto write_to_entry_part;\n\t\t\t}\n\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, arr_idx);\n\t\t\tgoto write_value;\n\t\t}\n\t}\n\n write_to_entry_part:\n\tDUK_DDD(DUK_DDDPRINT(\"property does not exist, object belongs in entry part -> allocate new entry and write value and attributes\"));\n\te_idx = duk__hobject_alloc_entry_checked(thr, obj, key);  /* increases key refcount */\n\tDUK_ASSERT(e_idx >= 0);\n\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, propflags);\n\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);\n\t/* new entry: previous value is garbage; set to undefined to share write_value */\n\tDUK_TVAL_SET_UNDEFINED(tv1);\n\tgoto write_value;\n\n write_value:\n\t/* tv1 points to value storage */\n\n\ttv2 = duk_require_tval(thr, -1);  /* late lookup, avoid side effects */\n\tDUK_DDD(DUK_DDDPRINT(\"writing/updating value: %!T -> %!T\",\n\t                     (duk_tval *) tv1, (duk_tval *) tv2));\n\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\tgoto pop_exit;\n\n pop_exit:\n\tduk_pop_unsafe(thr);  /* remove in_val */\n\treturn;\n\n error_virtual:  /* share error message */\n error_internal:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Fast path for defining array indexed values without interning the key.\n *  This is used by e.g. code for Array prototype and traceback creation so\n *  must avoid interning.\n */\n\nDUK_INTERNAL void duk_hobject_define_property_internal_arridx(duk_hthread *thr, duk_hobject *obj, duk_uarridx_t arr_idx, duk_small_uint_t flags) {\n\tduk_hstring *key;\n\tduk_tval *tv1, *tv2;\n\n\tDUK_DDD(DUK_DDDPRINT(\"define new property (internal) arr_idx fast path: thr=%p, obj=%!O, \"\n\t                     \"arr_idx=%ld, flags=0x%02lx, val=%!T\",\n\t                     (void *) thr, obj, (long) arr_idx, (unsigned long) flags,\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));\n\n\tif (DUK_HOBJECT_HAS_ARRAY_PART(obj) &&\n\t    arr_idx != DUK__NO_ARRAY_INDEX &&\n\t    flags == DUK_PROPDESC_FLAGS_WEC) {\n\t\tDUK_ASSERT((flags & DUK_PROPDESC_FLAG_NO_OVERWRITE) == 0);  /* covered by comparison */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"define property to array part (property may or may not exist yet)\"));\n\n\t\ttv1 = duk__obtain_arridx_slot(thr, arr_idx, obj);\n\t\tif (tv1 == NULL) {\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\t\tgoto write_slow;\n\t\t}\n\t\ttv2 = duk_require_tval(thr, -1);\n\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\n\t\tduk_pop_unsafe(thr);  /* [ ...val ] -> [ ... ] */\n\t\treturn;\n\t}\n\n write_slow:\n\tDUK_DDD(DUK_DDDPRINT(\"define property fast path didn't work, use slow path\"));\n\n\tkey = duk_push_uint_to_hstring(thr, (duk_uint_t) arr_idx);\n\tDUK_ASSERT(key != NULL);\n\tduk_insert(thr, -2);  /* [ ... val key ] -> [ ... key val ] */\n\n\tduk_hobject_define_property_internal(thr, obj, key, flags);\n\n\tduk_pop_unsafe(thr);  /* [ ... key ] -> [ ... ] */\n}\n\n/*\n *  Internal helpers for managing object 'length'\n */\n\nDUK_INTERNAL duk_size_t duk_hobject_get_length(duk_hthread *thr, duk_hobject *obj) {\n\tduk_double_t val;\n\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(obj != NULL);\n\n\t/* Fast path for Arrays. */\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\treturn ((duk_harray *) obj)->length;\n\t}\n\n\t/* Slow path, .length can be e.g. accessor, obj can be a Proxy, etc. */\n\tduk_push_hobject(thr, obj);\n\tduk_push_hstring_stridx(thr, DUK_STRIDX_LENGTH);\n\t(void) duk_hobject_getprop(thr,\n\t                           DUK_GET_TVAL_NEGIDX(thr, -2),\n\t                           DUK_GET_TVAL_NEGIDX(thr, -1));\n\tval = duk_to_number_m1(thr);\n\tduk_pop_3_unsafe(thr);\n\n\t/* This isn't part of ECMAScript semantics; return a value within\n\t * duk_size_t range, or 0 otherwise.\n\t */\n\tif (val >= 0.0 && val <= (duk_double_t) DUK_SIZE_MAX) {\n\t\treturn (duk_size_t) val;\n\t}\n\treturn 0;\n}\n\n/*\n *  Fast finalizer check for an object.  Walks the prototype chain, checking\n *  for finalizer presence using DUK_HOBJECT_FLAG_HAVE_FINALIZER which is kept\n *  in sync with the actual property when setting/removing the finalizer.\n */\n\n#if defined(DUK_USE_HEAPPTR16)\nDUK_INTERNAL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_heap *heap, duk_hobject *obj) {\n#else\nDUK_INTERNAL duk_bool_t duk_hobject_has_finalizer_fast_raw(duk_hobject *obj) {\n#endif\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(obj != NULL);\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\tif (DUK_UNLIKELY(DUK_HOBJECT_HAS_HAVE_FINALIZER(obj))) {\n\t\t\treturn 1;\n\t\t}\n\t\tif (DUK_UNLIKELY(sanity-- == 0)) {\n\t\t\tDUK_D(DUK_DPRINT(\"prototype loop when checking for finalizer existence; returning false\"));\n\t\t\treturn 0;\n\t\t}\n#if defined(DUK_USE_HEAPPTR16)\n\t\tDUK_ASSERT(heap != NULL);\n\t\tobj = DUK_HOBJECT_GET_PROTOTYPE(heap, obj);\n#else\n\t\tobj = DUK_HOBJECT_GET_PROTOTYPE(NULL, obj);  /* 'heap' arg ignored */\n#endif\n\t} while (obj != NULL);\n\n\treturn 0;\n}\n\n/*\n *  Object.getOwnPropertyDescriptor()  (E5 Sections 15.2.3.3, 8.10.4)\n *\n *  [ ... key ] -> [ ... desc/undefined ]\n */\n\nDUK_INTERNAL void duk_hobject_object_get_own_property_descriptor(duk_hthread *thr, duk_idx_t obj_idx) {\n\tduk_hobject *obj;\n\tduk_hstring *key;\n\tduk_propdesc pd;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n\tobj = duk_require_hobject_promote_mask(thr, obj_idx, DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\tkey = duk_to_property_key_hstring(thr, -1);\n\tDUK_ASSERT(key != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\tif (!duk_hobject_get_own_propdesc(thr, obj, key, &pd, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tduk_push_undefined(thr);\n\t\tduk_remove_m2(thr);\n\t\treturn;\n\t}\n\n\tduk_push_object(thr);\n\n\t/* [ ... key value desc ] */\n\n\tif (DUK_PROPDESC_IS_ACCESSOR(&pd)) {\n\t\t/* If a setter/getter is missing (undefined), the descriptor must\n\t\t * still have the property present with the value 'undefined'.\n\t\t */\n\t\tif (pd.get) {\n\t\t\tduk_push_hobject(thr, pd.get);\n\t\t} else {\n\t\t\tduk_push_undefined(thr);\n\t\t}\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_GET);\n\t\tif (pd.set) {\n\t\t\tduk_push_hobject(thr, pd.set);\n\t\t} else {\n\t\t\tduk_push_undefined(thr);\n\t\t}\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_SET);\n\t} else {\n\t\tduk_dup_m2(thr);\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_VALUE);\n\t\tduk_push_boolean(thr, DUK_PROPDESC_IS_WRITABLE(&pd));\n\t\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_WRITABLE);\n\t}\n\tduk_push_boolean(thr, DUK_PROPDESC_IS_ENUMERABLE(&pd));\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_ENUMERABLE);\n\tduk_push_boolean(thr, DUK_PROPDESC_IS_CONFIGURABLE(&pd));\n\tduk_put_prop_stridx_short(thr, -2, DUK_STRIDX_CONFIGURABLE);\n\n\t/* [ ... key value desc ] */\n\n\tduk_replace(thr, -3);\n\tduk_pop_unsafe(thr);  /* -> [ ... desc ] */\n}\n\n/*\n *  NormalizePropertyDescriptor() related helper.\n *\n *  Internal helper which validates and normalizes a property descriptor\n *  represented as an ECMAScript object (e.g. argument to defineProperty()).\n *  The output of this conversion is a set of defprop_flags and possibly\n *  some values pushed on the value stack to (1) ensure borrowed pointers\n *  remain valid, and (2) avoid unnecessary pops for footprint reasons.\n *  Caller must manage stack top carefully because the number of values\n *  pushed depends on the input property descriptor.\n *\n *  The original descriptor object must not be altered in the process.\n */\n\n/* XXX: very basic optimization -> duk_get_prop_stridx_top */\n\nDUK_INTERNAL\nvoid duk_hobject_prepare_property_descriptor(duk_hthread *thr,\n                                             duk_idx_t idx_in,\n                                             duk_uint_t *out_defprop_flags,\n                                             duk_idx_t *out_idx_value,\n                                             duk_hobject **out_getter,\n                                             duk_hobject **out_setter) {\n\tduk_idx_t idx_value = -1;\n\tduk_hobject *getter = NULL;\n\tduk_hobject *setter = NULL;\n\tduk_bool_t is_data_desc = 0;\n\tduk_bool_t is_acc_desc = 0;\n\tduk_uint_t defprop_flags = 0;\n\n\tDUK_ASSERT(out_defprop_flags != NULL);\n\tDUK_ASSERT(out_idx_value != NULL);\n\tDUK_ASSERT(out_getter != NULL);\n\tDUK_ASSERT(out_setter != NULL);\n\tDUK_ASSERT(idx_in <= 0x7fffL);  /* short variants would be OK, but not used to avoid shifts */\n\n\t/* Must be an object, otherwise TypeError (E5.1 Section 8.10.5, step 1). */\n\tidx_in = duk_require_normalize_index(thr, idx_in);\n\t(void) duk_require_hobject(thr, idx_in);\n\n\t/* The coercion order must match the ToPropertyDescriptor() algorithm\n\t * so that side effects in coercion happen in the correct order.\n\t * (This order also happens to be compatible with duk_def_prop(),\n\t * although it doesn't matter in practice.)\n\t */\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_VALUE)) {\n\t\tis_data_desc = 1;\n\t\tdefprop_flags |= DUK_DEFPROP_HAVE_VALUE;\n\t\tidx_value = duk_get_top_index(thr);\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_WRITABLE)) {\n\t\tis_data_desc = 1;\n\t\tif (duk_to_boolean_top_pop(thr)) {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE;\n\t\t} else {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_WRITABLE;\n\t\t}\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_GET)) {\n\t\tduk_tval *tv = duk_require_tval(thr, -1);\n\t\tduk_hobject *h_get;\n\n\t\tif (DUK_TVAL_IS_UNDEFINED(tv)) {\n\t\t\t/* undefined is accepted */\n\t\t\tDUK_ASSERT(getter == NULL);\n\t\t} else {\n\t\t\t/* NOTE: lightfuncs are coerced to full functions because\n\t\t\t * lightfuncs don't fit into a property value slot.  This\n\t\t\t * has some side effects, see test-dev-lightfunc-accessor.js.\n\t\t\t */\n\t\t\th_get = duk_get_hobject_promote_lfunc(thr, -1);\n\t\t\tif (h_get == NULL || !DUK_HOBJECT_IS_CALLABLE(h_get)) {\n\t\t\t\tgoto type_error;\n\t\t\t}\n\t\t\tgetter = h_get;\n\t\t}\n\t\tis_acc_desc = 1;\n\t\tdefprop_flags |= DUK_DEFPROP_HAVE_GETTER;\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_SET)) {\n\t\tduk_tval *tv = duk_require_tval(thr, -1);\n\t\tduk_hobject *h_set;\n\n\t\tif (DUK_TVAL_IS_UNDEFINED(tv)) {\n\t\t\t/* undefined is accepted */\n\t\t\tDUK_ASSERT(setter == NULL);\n\t\t}  else {\n\t\t\t/* NOTE: lightfuncs are coerced to full functions because\n\t\t\t * lightfuncs don't fit into a property value slot.  This\n\t\t\t * has some side effects, see test-dev-lightfunc-accessor.js.\n\t\t\t */\n\t\t\th_set = duk_get_hobject_promote_lfunc(thr, -1);\n\t\t\tif (h_set == NULL || !DUK_HOBJECT_IS_CALLABLE(h_set)) {\n\t\t\t\tgoto type_error;\n\t\t\t}\n\t\t\tsetter = h_set;\n\t\t}\n\t\tis_acc_desc = 1;\n\t\tdefprop_flags |= DUK_DEFPROP_HAVE_SETTER;\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_ENUMERABLE)) {\n\t\tif (duk_to_boolean_top_pop(thr)) {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE;\n\t\t} else {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE;\n\t\t}\n\t}\n\n\tif (duk_get_prop_stridx(thr, idx_in, DUK_STRIDX_CONFIGURABLE)) {\n\t\tif (duk_to_boolean_top_pop(thr)) {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE;\n\t\t} else {\n\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_CONFIGURABLE;\n\t\t}\n\t}\n\n\tif (is_data_desc && is_acc_desc) {\n\t\tgoto type_error;\n\t}\n\n\t*out_defprop_flags = defprop_flags;\n\t*out_idx_value = idx_value;\n\t*out_getter = getter;\n\t*out_setter = setter;\n\n\t/* [ ... [multiple values] ] */\n\treturn;\n\n type_error:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_DESCRIPTOR);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Object.defineProperty() related helper (E5 Section 15.2.3.6).\n *  Also handles ES2015 Reflect.defineProperty().\n *\n *  Inlines all [[DefineOwnProperty]] exotic behaviors.\n *\n *  Note: ECMAScript compliant [[DefineOwnProperty]](P, Desc, Throw) is not\n *  implemented directly, but Object.defineProperty() serves its purpose.\n *  We don't need the [[DefineOwnProperty]] internally and we don't have a\n *  property descriptor with 'missing values' so it's easier to avoid it\n *  entirely.\n *\n *  Note: this is only called for actual objects, not primitive values.\n *  This must support virtual properties for full objects (e.g. Strings)\n *  but not for plain values (e.g. strings).  Lightfuncs, even though\n *  primitive in a sense, are treated like objects and accepted as target\n *  values.\n */\n\n/* XXX: this is a major target for size optimization */\nDUK_INTERNAL\nduk_bool_t duk_hobject_define_property_helper(duk_hthread *thr,\n                                              duk_uint_t defprop_flags,\n                                              duk_hobject *obj,\n                                              duk_hstring *key,\n                                              duk_idx_t idx_value,\n                                              duk_hobject *get,\n                                              duk_hobject *set,\n                                              duk_bool_t throw_flag) {\n\tduk_uint32_t arr_idx;\n\tduk_tval tv;\n\tduk_bool_t has_enumerable;\n\tduk_bool_t has_configurable;\n\tduk_bool_t has_writable;\n\tduk_bool_t has_value;\n\tduk_bool_t has_get;\n\tduk_bool_t has_set;\n\tduk_bool_t is_enumerable;\n\tduk_bool_t is_configurable;\n\tduk_bool_t is_writable;\n\tduk_bool_t force_flag;\n\tduk_small_uint_t new_flags;\n\tduk_propdesc curr;\n\tduk_uint32_t arridx_new_array_length;  /* != 0 => post-update for array 'length' (used when key is an array index) */\n\tduk_uint32_t arrlen_old_len;\n\tduk_uint32_t arrlen_new_len;\n\tduk_bool_t pending_write_protect;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\tDUK_ASSERT(key != NULL);\n\t/* idx_value may be < 0 (no value), set and get may be NULL */\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n\t/* All the flags fit in 16 bits, so will fit into duk_bool_t. */\n\n\thas_writable = (defprop_flags & DUK_DEFPROP_HAVE_WRITABLE);\n\thas_enumerable = (defprop_flags & DUK_DEFPROP_HAVE_ENUMERABLE);\n\thas_configurable = (defprop_flags & DUK_DEFPROP_HAVE_CONFIGURABLE);\n\thas_value = (defprop_flags & DUK_DEFPROP_HAVE_VALUE);\n\thas_get = (defprop_flags & DUK_DEFPROP_HAVE_GETTER);\n\thas_set = (defprop_flags & DUK_DEFPROP_HAVE_SETTER);\n\tis_writable = (defprop_flags & DUK_DEFPROP_WRITABLE);\n\tis_enumerable = (defprop_flags & DUK_DEFPROP_ENUMERABLE);\n\tis_configurable = (defprop_flags & DUK_DEFPROP_CONFIGURABLE);\n\tforce_flag = (defprop_flags & DUK_DEFPROP_FORCE);\n\n\tarr_idx = DUK_HSTRING_GET_ARRIDX_SLOW(key);\n\n\tarridx_new_array_length = 0;\n\tpending_write_protect = 0;\n\tarrlen_old_len = 0;\n\tarrlen_new_len = 0;\n\n\tDUK_DDD(DUK_DDDPRINT(\"has_enumerable=%ld is_enumerable=%ld \"\n\t                     \"has_configurable=%ld is_configurable=%ld \"\n\t                     \"has_writable=%ld is_writable=%ld \"\n\t                     \"has_value=%ld value=%!T \"\n\t                     \"has_get=%ld get=%p=%!O \"\n\t                     \"has_set=%ld set=%p=%!O \"\n\t                     \"arr_idx=%ld throw_flag=!%ld\",\n\t                     (long) has_enumerable, (long) is_enumerable,\n\t                     (long) has_configurable, (long) is_configurable,\n\t                     (long) has_writable, (long) is_writable,\n\t                     (long) has_value, (duk_tval *) (idx_value >= 0 ? duk_get_tval(thr, idx_value) : NULL),\n\t                     (long) has_get, (void *) get, (duk_heaphdr *) get,\n\t                     (long) has_set, (void *) set, (duk_heaphdr *) set,\n\t                     (long) arr_idx, (long) throw_flag));\n\n\t/*\n\t *  Array exotic behaviors can be implemented at this point.  The local variables\n\t *  are essentially a 'value copy' of the input descriptor (Desc), which is modified\n\t *  by the Array [[DefineOwnProperty]] (E5 Section 15.4.5.1).\n\t */\n\n\tif (!DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\tgoto skip_array_exotic;\n\t}\n\n\tif (key == DUK_HTHREAD_STRING_LENGTH(thr)) {\n\t\tduk_harray *a;\n\n\t\t/* E5 Section 15.4.5.1, step 3, steps a - i are implemented here, j - n at the end */\n\t\tif (!has_value) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"exotic array behavior for 'length', but no value in descriptor -> normal behavior\"));\n\t\t\tgoto skip_array_exotic;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"exotic array behavior for 'length', value present in descriptor -> exotic behavior\"));\n\n\t\t/*\n\t\t *  Get old and new length\n\t\t */\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\t\tarrlen_old_len = a->length;\n\n\t\tDUK_ASSERT(idx_value >= 0);\n\t\tarrlen_new_len = duk__to_new_array_length_checked(thr, DUK_GET_TVAL_POSIDX(thr, idx_value));\n\t\tduk_push_u32(thr, arrlen_new_len);\n\t\tduk_replace(thr, idx_value);  /* step 3.e: replace 'Desc.[[Value]]' */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"old_len=%ld, new_len=%ld\", (long) arrlen_old_len, (long) arrlen_new_len));\n\n\t\tif (arrlen_new_len >= arrlen_old_len) {\n\t\t\t/* standard behavior, step 3.f.i */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new length is same or higher as previous => standard behavior\"));\n\t\t\tgoto skip_array_exotic;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"new length is smaller than previous => exotic post behavior\"));\n\n\t\t/* XXX: consolidated algorithm step 15.f -> redundant? */\n\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a) && !force_flag) {\n\t\t\t/* Array .length is always non-configurable; if it's also\n\t\t\t * non-writable, don't allow it to be written.\n\t\t\t */\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\n\t\t/* steps 3.h and 3.i */\n\t\tif (has_writable && !is_writable) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"desc writable is false, force it back to true, and flag pending write protect\"));\n\t\t\tis_writable = 1;\n\t\t\tpending_write_protect = 1;\n\t\t}\n\n\t\t/* remaining actual steps are carried out if standard DefineOwnProperty succeeds */\n\t} else if (arr_idx != DUK__NO_ARRAY_INDEX) {\n\t\t/* XXX: any chance of unifying this with the 'length' key handling? */\n\n\t\t/* E5 Section 15.4.5.1, step 4 */\n\t\tduk_uint32_t old_len;\n\t\tduk_harray *a;\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\told_len = a->length;\n\n\t\tif (arr_idx >= old_len) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty requires array length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld)\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\n\t\t\tif (DUK_HARRAY_LENGTH_NONWRITABLE(a) && !force_flag) {\n\t\t\t\t/* Array .length is always non-configurable, so\n\t\t\t\t * if it's also non-writable, don't allow a value\n\t\t\t\t * write.  With force flag allow writing.\n\t\t\t\t */\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\n\t\t\t/* actual update happens once write has been completed without\n\t\t\t * error below.\n\t\t\t */\n\t\t\tDUK_ASSERT(arr_idx != 0xffffffffUL);\n\t\t\tarridx_new_array_length = arr_idx + 1;\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty does not require length update \"\n\t\t\t                     \"(arr_idx=%ld, old_len=%ld) -> standard behavior\",\n\t\t\t                     (long) arr_idx, (long) old_len));\n\t\t}\n\t}\n skip_array_exotic:\n\n\t/* XXX: There is currently no support for writing buffer object\n\t * indexed elements here.  Attempt to do so will succeed and\n\t * write a concrete property into the buffer object.  This should\n\t * be fixed at some point but because buffers are a custom feature\n\t * anyway, this is relatively unimportant.\n\t */\n\n\t/*\n\t *  Actual Object.defineProperty() default algorithm.\n\t */\n\n\t/*\n\t *  First check whether property exists; if not, simple case.  This covers\n\t *  steps 1-4.\n\t */\n\n\tif (!duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"property does not exist\"));\n\n\t\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(obj) && !force_flag) {\n\t\t\tgoto fail_not_extensible;\n\t\t}\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\t\t/* ROM objects are never extensible but force flag may\n\t\t * allow us to come here anyway.\n\t\t */\n\t\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj) || !DUK_HOBJECT_HAS_EXTENSIBLE(obj));\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\t\tDUK_D(DUK_DPRINT(\"attempt to define property on a read-only target object\"));\n\t\t\tgoto fail_not_configurable;\n\t\t}\n#endif\n\n\t\t/* XXX: share final setting code for value and flags?  difficult because\n\t\t * refcount code is different.  Share entry allocation?  But can't allocate\n\t\t * until array index checked.\n\t\t */\n\n\t\t/* steps 4.a and 4.b are tricky */\n\t\tif (has_set || has_get) {\n\t\t\tduk_int_t e_idx;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"create new accessor property\"));\n\n\t\t\tDUK_ASSERT(has_set || set == NULL);\n\t\t\tDUK_ASSERT(has_get || get == NULL);\n\t\t\tDUK_ASSERT(!has_value);\n\t\t\tDUK_ASSERT(!has_writable);\n\n\t\t\tnew_flags = DUK_PROPDESC_FLAG_ACCESSOR;  /* defaults, E5 Section 8.6.1, Table 7 */\n\t\t\tif (has_enumerable && is_enumerable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t}\n\t\t\tif (has_configurable && is_configurable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t}\n\n\t\t\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"accessor cannot go to array part, abandon array\"));\n\t\t\t\tduk__abandon_array_part(thr, obj);\n\t\t\t}\n\n\t\t\t/* write to entry part */\n\t\t\te_idx = duk__hobject_alloc_entry_checked(thr, obj, key);\n\t\t\tDUK_ASSERT(e_idx >= 0);\n\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, e_idx, get);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, e_idx, set);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, get);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, set);\n\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags);\n\t\t\tgoto success_exotics;\n\t\t} else {\n\t\t\tduk_int_t e_idx;\n\t\t\tduk_tval *tv2;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"create new data property\"));\n\n\t\t\tDUK_ASSERT(!has_set);\n\t\t\tDUK_ASSERT(!has_get);\n\n\t\t\tnew_flags = 0;  /* defaults, E5 Section 8.6.1, Table 7 */\n\t\t\tif (has_writable && is_writable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_WRITABLE;\n\t\t\t}\n\t\t\tif (has_enumerable && is_enumerable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t}\n\t\t\tif (has_configurable && is_configurable) {\n\t\t\t\tnew_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t}\n\t\t\tif (has_value) {\n\t\t\t\tduk_tval *tv_tmp = duk_require_tval(thr, idx_value);\n\t\t\t\tDUK_TVAL_SET_TVAL(&tv, tv_tmp);\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_UNDEFINED(&tv);  /* default value */\n\t\t\t}\n\n\t\t\tif (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_ARRAY_PART(obj)) {\n\t\t\t\tif (new_flags == DUK_PROPDESC_FLAGS_WEC) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"new data property attributes match array defaults, attempt to write to array part\"));\n\t\t\t\t\ttv2 = duk__obtain_arridx_slot(thr, arr_idx, obj);\n\t\t\t\t\tif (tv2 == NULL) {\n\t\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"failed writing to array part, abandoned array\"));\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"success in writing to array part\"));\n\t\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(obj));\n\t\t\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNUSED(tv2));\n\t\t\t\t\t\tDUK_TVAL_SET_TVAL(tv2, &tv);\n\t\t\t\t\t\tDUK_TVAL_INCREF(thr, tv2);\n\t\t\t\t\t\tgoto success_exotics;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"new data property cannot go to array part, abandon array\"));\n\t\t\t\t\tduk__abandon_array_part(thr, obj);\n\t\t\t\t}\n\t\t\t\t/* fall through */\n\t\t\t}\n\n\t\t\t/* write to entry part */\n\t\t\te_idx = duk__hobject_alloc_entry_checked(thr, obj, key);\n\t\t\tDUK_ASSERT(e_idx >= 0);\n\t\t\ttv2 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, e_idx);\n\t\t\tDUK_TVAL_SET_TVAL(tv2, &tv);\n\t\t\tDUK_TVAL_INCREF(thr, tv2);\n\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, e_idx, new_flags);\n\t\t\tgoto success_exotics;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\t}\n\n\t/* we currently assume virtual properties are not configurable (as none of them are) */\n\tDUK_ASSERT((curr.e_idx >= 0 || curr.a_idx >= 0) || !(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE));\n\n\t/* [obj key desc value get set curr_value] */\n\n\t/*\n\t *  Property already exists.  Steps 5-6 detect whether any changes need\n\t *  to be made.\n\t */\n\n\tif (has_enumerable) {\n\t\tif (is_enumerable) {\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE)) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t}\n\t}\n\tif (has_configurable) {\n\t\tif (is_configurable) {\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE)) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t}\n\t}\n\tif (has_value) {\n\t\tduk_tval *tmp1;\n\t\tduk_tval *tmp2;\n\n\t\t/* attempt to change from accessor to data property */\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tgoto need_check;\n\t\t}\n\n\t\ttmp1 = duk_require_tval(thr, -1);         /* curr value */\n\t\ttmp2 = duk_require_tval(thr, idx_value);  /* new value */\n\t\tif (!duk_js_samevalue(tmp1, tmp2)) {\n\t\t\tgoto need_check;\n\t\t}\n\t}\n\tif (has_writable) {\n\t\t/* attempt to change from accessor to data property */\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tgoto need_check;\n\t\t}\n\n\t\tif (is_writable) {\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_WRITABLE) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t}\n\t}\n\tif (has_set) {\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tif (set != curr.set) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tgoto need_check;\n\t\t}\n\t}\n\tif (has_get) {\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tif (get != curr.get) {\n\t\t\t\tgoto need_check;\n\t\t\t}\n\t\t} else {\n\t\t\tgoto need_check;\n\t\t}\n\t}\n\n\t/* property exists, either 'desc' is empty, or all values\n\t * match (SameValue)\n\t */\n\tgoto success_no_exotics;\n\n need_check:\n\n\t/*\n\t *  Some change(s) need to be made.  Steps 7-11.\n\t */\n\n\t/* shared checks for all descriptor types */\n\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\tif (has_configurable && is_configurable) {\n\t\t\tgoto fail_not_configurable;\n\t\t}\n\t\tif (has_enumerable) {\n\t\t\tif (curr.flags & DUK_PROPDESC_FLAG_ENUMERABLE) {\n\t\t\t\tif (!is_enumerable) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (is_enumerable) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/* Virtual properties don't have backing so they can't mostly be\n\t * edited.  Some virtual properties are, however, writable: for\n\t * example, virtual index properties of buffer objects and Array\n\t * instance .length.  These are not configurable so the checks\n\t * above mostly cover attempts to change them, except when the\n\t * duk_def_prop() call is used with DUK_DEFPROP_FORCE; even in\n\t * that case we can't forcibly change the property attributes\n\t * because they don't have concrete backing.\n\t */\n\n\t/* XXX: for ROM objects too it'd be best if value modify was\n\t * allowed if the value matches SameValue.\n\t */\n\t/* Reject attempt to change a read-only object. */\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to define property on read-only target object\"));\n\t\tgoto fail_not_configurable;\n\t}\n#endif\n\n\t/* descriptor type specific checks */\n\tif (has_set || has_get) {\n\t\t/* IsAccessorDescriptor(desc) == true */\n\t\tDUK_ASSERT(!has_writable);\n\t\tDUK_ASSERT(!has_value);\n\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t/* curr and desc are accessors */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tif (has_set && set != curr.set) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t\tif (has_get && get != curr.get) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tduk_bool_t rc;\n\t\t\tduk_tval *tv1;\n\n\t\t\t/* curr is data, desc is accessor */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"convert property to accessor property\"));\n\t\t\tif (curr.a_idx >= 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"property to convert is stored in an array entry, abandon array and re-lookup\"));\n\t\t\t\tduk__abandon_array_part(thr, obj);\n\t\t\t\tduk_pop_unsafe(thr);  /* remove old value */\n\t\t\t\trc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);\n\t\t\t\tDUK_UNREF(rc);\n\t\t\t\tDUK_ASSERT(rc != 0);\n\t\t\t\tDUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);\n\t\t\t}\n\t\t\tif (curr.e_idx < 0) {\n\t\t\t\tDUK_ASSERT(curr.a_idx < 0 && curr.e_idx < 0);\n\t\t\t\tgoto fail_virtual;  /* safeguard for virtual property */\n\t\t\t}\n\n\t\t\tDUK_ASSERT(curr.e_idx >= 0);\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\n\t\t\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, tv1);  /* XXX: just decref */\n\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_HOBJECT_E_SLOT_SET_ACCESSOR(thr->heap, obj, curr.e_idx);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"flags after data->accessor conversion: 0x%02lx\",\n\t\t\t                     (unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));\n\t\t\t/* Update curr.flags; faster than a re-lookup. */\n\t\t\tcurr.flags &= ~DUK_PROPDESC_FLAG_WRITABLE;\n\t\t\tcurr.flags |= DUK_PROPDESC_FLAG_ACCESSOR;\n\t\t}\n\t} else if (has_value || has_writable) {\n\t\t/* IsDataDescriptor(desc) == true */\n\t\tDUK_ASSERT(!has_set);\n\t\tDUK_ASSERT(!has_get);\n\n\t\tif (curr.flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\tduk_hobject *tmp;\n\n\t\t\t/* curr is accessor, desc is data */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\n\t\t\t/* curr is accessor -> cannot be in array part. */\n\t\t\tDUK_ASSERT(curr.a_idx < 0);\n\t\t\tif (curr.e_idx < 0) {\n\t\t\t\tgoto fail_virtual;  /* safeguard; no virtual accessors now */\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"convert property to data property\"));\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_UNREF(tmp);\n\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, NULL);\n\t\t\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\n\t\t\tDUK_TVAL_SET_UNDEFINED(DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx));\n\t\t\tDUK_HOBJECT_E_SLOT_CLEAR_WRITABLE(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_HOBJECT_E_SLOT_CLEAR_ACCESSOR(thr->heap, obj, curr.e_idx);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"flags after accessor->data conversion: 0x%02lx\",\n\t\t\t                     (unsigned long) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, curr.e_idx)));\n\n\t\t\t/* Update curr.flags; faster than a re-lookup. */\n\t\t\tcurr.flags &= ~(DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_ACCESSOR);\n\t\t} else {\n\t\t\t/* curr and desc are data */\n\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_CONFIGURABLE) && !force_flag) {\n\t\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && has_writable && is_writable) {\n\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t}\n\t\t\t\t/* Note: changing from writable to non-writable is OK */\n\t\t\t\tif (!(curr.flags & DUK_PROPDESC_FLAG_WRITABLE) && has_value) {\n\t\t\t\t\tduk_tval *tmp1 = duk_require_tval(thr, -1);         /* curr value */\n\t\t\t\t\tduk_tval *tmp2 = duk_require_tval(thr, idx_value);  /* new value */\n\t\t\t\t\tif (!duk_js_samevalue(tmp1, tmp2)) {\n\t\t\t\t\t\tgoto fail_not_configurable;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else {\n\t\t/* IsGenericDescriptor(desc) == true; this means in practice that 'desc'\n\t\t * only has [[Enumerable]] or [[Configurable]] flag updates, which are\n\t\t * allowed at this point.\n\t\t */\n\n\t\tDUK_ASSERT(!has_value && !has_writable && !has_get && !has_set);\n\t}\n\n\t/*\n\t *  Start doing property attributes updates.  Steps 12-13.\n\t *\n\t *  Start by computing new attribute flags without writing yet.\n\t *  Property type conversion is done above if necessary.\n\t */\n\n\tnew_flags = curr.flags;\n\n\tif (has_enumerable) {\n\t\tif (is_enumerable) {\n\t\t\tnew_flags |= DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t} else {\n\t\t\tnew_flags &= ~DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t}\n\t}\n\tif (has_configurable) {\n\t\tif (is_configurable) {\n\t\t\tnew_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t} else {\n\t\t\tnew_flags &= ~DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t}\n\t}\n\tif (has_writable) {\n\t\tif (is_writable) {\n\t\t\tnew_flags |= DUK_PROPDESC_FLAG_WRITABLE;\n\t\t} else {\n\t\t\tnew_flags &= ~DUK_PROPDESC_FLAG_WRITABLE;\n\t\t}\n\t}\n\n\t/* XXX: write protect after flag? -> any chance of handling it here? */\n\n\tDUK_DDD(DUK_DDDPRINT(\"new flags that we want to write: 0x%02lx\",\n\t                     (unsigned long) new_flags));\n\n\t/*\n\t *  Check whether we need to abandon an array part (if it exists)\n\t */\n\n\tif (curr.a_idx >= 0) {\n\t\tduk_bool_t rc;\n\n\t\tDUK_ASSERT(curr.e_idx < 0);\n\n\t\tif (new_flags == DUK_PROPDESC_FLAGS_WEC) {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"array index, new property attributes match array defaults, update in-place\"));\n\n\t\t\tDUK_ASSERT(curr.flags == DUK_PROPDESC_FLAGS_WEC);  /* must have been, since in array part */\n\t\t\tDUK_ASSERT(!has_set);\n\t\t\tDUK_ASSERT(!has_get);\n\t\t\tDUK_ASSERT(idx_value >= 0);  /* must be: if attributes match and we get here the value must differ (otherwise no change) */\n\n\t\t\ttv2 = duk_require_tval(thr, idx_value);\n\t\t\ttv1 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, curr.a_idx);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects; may invalidate a_idx */\n\t\t\tgoto success_exotics;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"array index, new property attributes do not match array defaults, abandon array and re-lookup\"));\n\t\tduk__abandon_array_part(thr, obj);\n\t\tduk_pop_unsafe(thr);  /* remove old value */\n\t\trc = duk__get_own_propdesc_raw(thr, obj, key, arr_idx, &curr, DUK_GETDESC_FLAG_PUSH_VALUE);\n\t\tDUK_UNREF(rc);\n\t\tDUK_ASSERT(rc != 0);\n\t\tDUK_ASSERT(curr.e_idx >= 0 && curr.a_idx < 0);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"updating existing property in entry part\"));\n\n\t/* Array case is handled comprehensively above: either in entry\n\t * part or a virtual property.\n\t */\n\tDUK_ASSERT(curr.a_idx < 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"update existing property attributes\"));\n\tif (curr.e_idx >= 0) {\n\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, obj, curr.e_idx, new_flags);\n\t} else {\n\t\t/* For Array .length the only allowed transition is for .length\n\t\t * to become non-writable.\n\t\t */\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\t\tduk_harray *a;\n\t\t\ta = (duk_harray *) obj;\n\t\t\tDUK_DD(DUK_DDPRINT(\"Object.defineProperty() attribute update for duk_harray .length -> %02lx\", (unsigned long) new_flags));\n\t\t\tDUK_HARRAY_ASSERT_VALID(a);\n\t\t\tif ((new_flags & DUK_PROPDESC_FLAGS_EC) != (curr.flags & DUK_PROPDESC_FLAGS_EC)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"Object.defineProperty() attempt to change virtual array .length enumerable or configurable attribute, fail\"));\n\t\t\t\tgoto fail_virtual;\n\t\t\t}\n\t\t\tif (new_flags & DUK_PROPDESC_FLAG_WRITABLE) {\n\t\t\t\tDUK_HARRAY_SET_LENGTH_WRITABLE(a);\n\t\t\t} else {\n\t\t\t\tDUK_HARRAY_SET_LENGTH_NONWRITABLE(a);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (has_set) {\n\t\tduk_hobject *tmp;\n\n\t\t/* Virtual properties are non-configurable but with a 'force'\n\t\t * flag we might come here so check explicitly for virtual.\n\t\t */\n\t\tif (curr.e_idx < 0) {\n\t\t\tgoto fail_virtual;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"update existing property setter\"));\n\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\n\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, obj, curr.e_idx);\n\t\tDUK_UNREF(tmp);\n\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, obj, curr.e_idx, set);\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, set);\n\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);  /* side effects; may invalidate e_idx */\n\t}\n\tif (has_get) {\n\t\tduk_hobject *tmp;\n\n\t\tif (curr.e_idx < 0) {\n\t\t\tgoto fail_virtual;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"update existing property getter\"));\n\t\tDUK_ASSERT(DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\n\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, obj, curr.e_idx);\n\t\tDUK_UNREF(tmp);\n\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, obj, curr.e_idx, get);\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, get);\n\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);  /* side effects; may invalidate e_idx */\n\t}\n\tif (has_value) {\n\t\tduk_tval *tv1, *tv2;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"update existing property value\"));\n\n\t\tif (curr.e_idx >= 0) {\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, obj, curr.e_idx));\n\t\t\ttv2 = duk_require_tval(thr, idx_value);\n\t\t\ttv1 = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, obj, curr.e_idx);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects; may invalidate e_idx */\n\t\t} else {\n\t\t\tDUK_ASSERT(curr.a_idx < 0);  /* array part case handled comprehensively previously */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"Object.defineProperty(), value update for virtual property\"));\n\t\t\t/* XXX: Uint8Array and other typed array virtual writes not currently\n\t\t\t * handled.\n\t\t\t */\n\t\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\t\t\tduk_harray *a;\n\t\t\t\ta = (duk_harray *) obj;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"Object.defineProperty() value update for duk_harray .length -> %ld\", (long) arrlen_new_len));\n\t\t\t\tDUK_HARRAY_ASSERT_VALID(a);\n\t\t\t\ta->length = arrlen_new_len;\n\t\t\t} else {\n\t\t\t\tgoto fail_virtual;  /* should not happen */\n\t\t\t}\n\t\t}\n\t}\n\n\t/*\n\t *  Standard algorithm succeeded without errors, check for exotic post-behaviors.\n\t *\n\t *  Arguments exotic behavior in E5 Section 10.6 occurs after the standard\n\t *  [[DefineOwnProperty]] has completed successfully.\n\t *\n\t *  Array exotic behavior in E5 Section 15.4.5.1 is implemented partly\n\t *  prior to the default [[DefineOwnProperty]], but:\n\t *    - for an array index key (e.g. \"10\") the final 'length' update occurs here\n\t *    - for 'length' key the element deletion and 'length' update occurs here\n\t */\n\n success_exotics:\n\n\t/* curr.a_idx or curr.e_idx may have been invalidated by side effects\n\t * above.\n\t */\n\n\t/* [obj key desc value get set curr_value] */\n\n\tif (DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj)) {\n\t\tduk_harray *a;\n\n\t\ta = (duk_harray *) obj;\n\t\tDUK_HARRAY_ASSERT_VALID(a);\n\n\t\tif (arridx_new_array_length > 0) {\n\t\t\t/*\n\t\t\t *  Note: zero works as a \"no update\" marker because the new length\n\t\t\t *  can never be zero after a new property is written.\n\t\t\t */\n\n\t\t\t/* E5 Section 15.4.5.1, steps 4.e.i - 4.e.ii */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, pending array length update to: %ld\",\n\t\t\t                     (long) arridx_new_array_length));\n\n\t\t\ta->length = arridx_new_array_length;\n\t\t}\n\n\t\tif (key == DUK_HTHREAD_STRING_LENGTH(thr) && arrlen_new_len < arrlen_old_len) {\n\t\t\t/*\n\t\t\t *  E5 Section 15.4.5.1, steps 3.k - 3.n.  The order at the end combines\n\t\t\t *  the error case 3.l.iii and the success case 3.m-3.n.\n\t\t\t */\n\n\t\t\t/* XXX: investigate whether write protect can be handled above, if we\n\t\t\t * just update length here while ignoring its protected status\n\t\t\t */\n\n\t\t\tduk_uint32_t result_len;\n\t\t\tduk_bool_t rc;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key is 'length', exotic array behavior, \"\n\t\t\t                     \"doing array element deletion and length update\"));\n\n\t\t\trc = duk__handle_put_array_length_smaller(thr, obj, arrlen_old_len, arrlen_new_len, force_flag, &result_len);\n\n\t\t\t/* update length (curr points to length, and we assume it's still valid) */\n\t\t\tDUK_ASSERT(result_len >= arrlen_new_len && result_len <= arrlen_old_len);\n\n\t\t\ta->length = result_len;\n\n\t\t\tif (pending_write_protect) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"setting array length non-writable (pending writability update)\"));\n\t\t\t\tDUK_HARRAY_SET_LENGTH_NONWRITABLE(a);\n\t\t\t}\n\n\t\t\t/* XXX: shrink array allocation or entries compaction here? */\n\t\t\tif (!rc) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"array length write only partially successful\"));\n\t\t\t\tgoto fail_not_configurable;\n\t\t\t}\n\t\t}\n\t} else if (arr_idx != DUK__NO_ARRAY_INDEX && DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(obj)) {\n\t\tduk_hobject *map;\n\t\tduk_hobject *varenv;\n\n\t\tDUK_ASSERT(arridx_new_array_length == 0);\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(obj));  /* traits are separate; in particular, arguments not an array */\n\n\t\tmap = NULL;\n\t\tvarenv = NULL;\n\t\tif (!duk__lookup_arguments_map(thr, obj, key, &curr, &map, &varenv)) {\n\t\t\tgoto success_no_exotics;\n\t\t}\n\t\tDUK_ASSERT(map != NULL);\n\t\tDUK_ASSERT(varenv != NULL);\n\n\t\t/* [obj key desc value get set curr_value varname] */\n\n\t\tif (has_set || has_get) {\n\t\t\t/* = IsAccessorDescriptor(Desc) */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map' \"\n\t\t\t                     \"changed to an accessor, delete arguments binding\"));\n\n\t\t\t(void) duk_hobject_delprop_raw(thr, map, key, 0);  /* ignore result */\n\t\t} else {\n\t\t\t/* Note: this order matters (final value before deleting map entry must be done) */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map', \"\n\t\t\t                     \"check for value update / binding deletion\"));\n\n\t\t\tif (has_value) {\n\t\t\t\tduk_hstring *varname;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map', \"\n\t\t\t\t                     \"update bound value (variable/argument)\"));\n\n\t\t\t\tvarname = duk_require_hstring(thr, -1);\n\t\t\t\tDUK_ASSERT(varname != NULL);\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"arguments object automatic putvar for a bound variable; \"\n\t\t\t\t                     \"key=%!O, varname=%!O, value=%!T\",\n\t\t\t\t                     (duk_heaphdr *) key,\n\t\t\t\t                     (duk_heaphdr *) varname,\n\t\t\t\t                     (duk_tval *) duk_require_tval(thr, idx_value)));\n\n\t\t\t\t/* strict flag for putvar comes from our caller (currently: fixed) */\n\t\t\t\tduk_js_putvar_envrec(thr, varenv, varname, duk_require_tval(thr, idx_value), 1 /*throw_flag*/);\n\t\t\t}\n\t\t\tif (has_writable && !is_writable) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"defineProperty successful, key mapped to arguments 'map', \"\n\t\t\t\t                     \"changed to non-writable, delete arguments binding\"));\n\n\t\t\t\t(void) duk_hobject_delprop_raw(thr, map, key, 0);  /* ignore result */\n\t\t\t}\n\t\t}\n\n\t\t/* 'varname' is in stack in this else branch, leaving an unbalanced stack below,\n\t\t * but this doesn't matter now.\n\t\t */\n\t}\n\n success_no_exotics:\n\t/* Some code paths use NORZ macros for simplicity, ensure refzero\n\t * handling is completed.\n\t */\n\tDUK_REFZERO_CHECK_SLOW(thr);\n\treturn 1;\n\n fail_not_extensible:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_EXTENSIBLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n\n fail_virtual:  /* just use the same \"not configurable\" error message\" */\n fail_not_configurable:\n\tif (throw_flag) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\treturn 0;\n}\n\n/*\n *  Object.prototype.hasOwnProperty() and Object.prototype.propertyIsEnumerable().\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_object_ownprop_helper(duk_hthread *thr, duk_small_uint_t required_desc_flags) {\n\tduk_hstring *h_v;\n\tduk_hobject *h_obj;\n\tduk_propdesc desc;\n\tduk_bool_t ret;\n\n\t/* coercion order matters */\n\th_v = duk_to_hstring_acceptsymbol(thr, 0);\n\tDUK_ASSERT(h_v != NULL);\n\n\th_obj = duk_push_this_coercible_to_object(thr);\n\tDUK_ASSERT(h_obj != NULL);\n\n\tret = duk_hobject_get_own_propdesc(thr, h_obj, h_v, &desc, 0 /*flags*/);  /* don't push value */\n\n\tduk_push_boolean(thr, ret && ((desc.flags & required_desc_flags) == required_desc_flags));\n\treturn 1;\n}\n\n/*\n *  Object.seal() and Object.freeze()  (E5 Sections 15.2.3.8 and 15.2.3.9)\n *\n *  Since the algorithms are similar, a helper provides both functions.\n *  Freezing is essentially sealing + making plain properties non-writable.\n *\n *  Note: virtual (non-concrete) properties which are non-configurable but\n *  writable would pose some problems, but such properties do not currently\n *  exist (all virtual properties are non-configurable and non-writable).\n *  If they did exist, the non-configurability does NOT prevent them from\n *  becoming non-writable.  However, this change should be recorded somehow\n *  so that it would turn up (e.g. when getting the property descriptor),\n *  requiring some additional flags in the object.\n */\n\nDUK_INTERNAL void duk_hobject_object_seal_freeze_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_freeze) {\n\tduk_uint_fast32_t i;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(obj != NULL);\n\n\tDUK_ASSERT_VALSTACK_SPACE(thr, DUK__VALSTACK_SPACE);\n\n#if defined(DUK_USE_ROM_OBJECTS)\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj)) {\n\t\tDUK_DD(DUK_DDPRINT(\"attempt to seal/freeze a readonly object, reject\"));\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONFIGURABLE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n#endif\n\n\t/*\n\t *  Abandon array part because all properties must become non-configurable.\n\t *  Note that this is now done regardless of whether this is always the case\n\t *  (skips check, but performance problem if caller would do this many times\n\t *  for the same object; not likely).\n\t */\n\n\tduk__abandon_array_part(thr, obj);\n\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(obj) == 0);\n\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tduk_uint8_t *fp;\n\n\t\t/* since duk__abandon_array_part() causes a resize, there should be no gaps in keys */\n\t\tDUK_ASSERT(DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i) != NULL);\n\n\t\t/* avoid multiple computations of flags address; bypasses macros */\n\t\tfp = DUK_HOBJECT_E_GET_FLAGS_PTR(thr->heap, obj, i);\n\t\tif (is_freeze && !((*fp) & DUK_PROPDESC_FLAG_ACCESSOR)) {\n\t\t\t*fp &= ~(DUK_PROPDESC_FLAG_WRITABLE | DUK_PROPDESC_FLAG_CONFIGURABLE);\n\t\t} else {\n\t\t\t*fp &= ~DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t}\n\t}\n\n\tDUK_HOBJECT_CLEAR_EXTENSIBLE(obj);\n\n\t/* no need to compact since we already did that in duk__abandon_array_part()\n\t * (regardless of whether an array part existed or not.\n\t */\n\n\treturn;\n}\n\n/*\n *  Object.isSealed() and Object.isFrozen()  (E5 Sections 15.2.3.11, 15.2.3.13)\n *\n *  Since the algorithms are similar, a helper provides both functions.\n *  Freezing is essentially sealing + making plain properties non-writable.\n *\n *  Note: all virtual (non-concrete) properties are currently non-configurable\n *  and non-writable (and there are no accessor virtual properties), so they don't\n *  need to be considered here now.\n */\n\nDUK_INTERNAL duk_bool_t duk_hobject_object_is_sealed_frozen_helper(duk_hthread *thr, duk_hobject *obj, duk_bool_t is_frozen) {\n\tduk_uint_fast32_t i;\n\n\tDUK_ASSERT(obj != NULL);\n\tDUK_UNREF(thr);\n\n\t/* Note: no allocation pressure, no need to check refcounts etc */\n\n\t/* must not be extensible */\n\tif (DUK_HOBJECT_HAS_EXTENSIBLE(obj)) {\n\t\treturn 0;\n\t}\n\n\t/* all virtual properties are non-configurable and non-writable */\n\n\t/* entry part must not contain any configurable properties, or\n\t * writable properties (if is_frozen).\n\t */\n\tfor (i = 0; i < DUK_HOBJECT_GET_ENEXT(obj); i++) {\n\t\tduk_small_uint_t flags;\n\n\t\tif (!DUK_HOBJECT_E_GET_KEY(thr->heap, obj, i)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* avoid multiple computations of flags address; bypasses macros */\n\t\tflags = (duk_small_uint_t) DUK_HOBJECT_E_GET_FLAGS(thr->heap, obj, i);\n\n\t\tif (flags & DUK_PROPDESC_FLAG_CONFIGURABLE) {\n\t\t\treturn 0;\n\t\t}\n\t\tif (is_frozen &&\n\t\t    !(flags & DUK_PROPDESC_FLAG_ACCESSOR) &&\n\t\t    (flags & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/* array part must not contain any non-unused properties, as they would\n\t * be configurable and writable.\n\t */\n\tfor (i = 0; i < DUK_HOBJECT_GET_ASIZE(obj); i++) {\n\t\tduk_tval *tv = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, obj, i);\n\t\tif (!DUK_TVAL_IS_UNUSED(tv)) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\treturn 1;\n}\n\n/*\n *  Object.preventExtensions() and Object.isExtensible()  (E5 Sections 15.2.3.10, 15.2.3.13)\n *\n *  Not needed, implemented by macros DUK_HOBJECT_{HAS,CLEAR,SET}_EXTENSIBLE\n *  and the Object built-in bindings.\n */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hproxy.h",
    "content": "/*\n *  Proxy object representation.\n */\n\n#if !defined(DUK_HPROXY_H_INCLUDED)\n#define DUK_HPROXY_H_INCLUDED\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hproxy_assert_valid(duk_hproxy *h);\n#define DUK_HPROXY_ASSERT_VALID(h)  do { duk_hproxy_assert_valid((h)); } while (0)\n#else\n#define DUK_HPROXY_ASSERT_VALID(h)  do {} while (0)\n#endif\n\nstruct duk_hproxy {\n\t/* Shared object part. */\n\tduk_hobject obj;\n\n\t/* Proxy target object. */\n\tduk_hobject *target;\n\n\t/* Proxy handlers (traps). */\n\tduk_hobject *handler;\n};\n\n#endif  /* DUK_HPROXY_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hstring.h",
    "content": "/*\n *  Heap string representation.\n *\n *  Strings are byte sequences ordinarily stored in extended UTF-8 format,\n *  allowing values larger than the official UTF-8 range (used internally)\n *  and also allowing UTF-8 encoding of surrogate pairs (CESU-8 format).\n *  Strings may also be invalid UTF-8 altogether which is the case e.g. with\n *  strings used as internal property names and raw buffers converted to\n *  strings.  In such cases the 'clen' field contains an inaccurate value.\n *\n *  ECMAScript requires support for 32-bit long strings.  However, since each\n *  16-bit codepoint can take 3 bytes in CESU-8, this representation can only\n *  support about 1.4G codepoint long strings in extreme cases.  This is not\n *  really a practical issue.\n */\n\n#if !defined(DUK_HSTRING_H_INCLUDED)\n#define DUK_HSTRING_H_INCLUDED\n\n/* Impose a maximum string length for now.  Restricted artificially to\n * ensure adding a heap header length won't overflow size_t.  The limit\n * should be synchronized with DUK_HBUFFER_MAX_BYTELEN.\n *\n * E5.1 makes provisions to support strings longer than 4G characters.\n * This limit should be eliminated on 64-bit platforms (and increased\n * closer to maximum support on 32-bit platforms).\n */\n\n#if defined(DUK_USE_STRLEN16)\n#define DUK_HSTRING_MAX_BYTELEN                     (0x0000ffffUL)\n#else\n#define DUK_HSTRING_MAX_BYTELEN                     (0x7fffffffUL)\n#endif\n\n/* XXX: could add flags for \"is valid CESU-8\" (ECMAScript compatible strings),\n * \"is valid UTF-8\", \"is valid extended UTF-8\" (internal strings are not,\n * regexp bytecode is), and \"contains non-BMP characters\".  These are not\n * needed right now.\n */\n\n/* With lowmem builds the high 16 bits of duk_heaphdr are used for other\n * purposes, so this leaves 7 duk_heaphdr flags and 9 duk_hstring flags.\n */\n#define DUK_HSTRING_FLAG_ASCII                      DUK_HEAPHDR_USER_FLAG(0)  /* string is ASCII, clen == blen */\n#define DUK_HSTRING_FLAG_ARRIDX                     DUK_HEAPHDR_USER_FLAG(1)  /* string is a valid array index */\n#define DUK_HSTRING_FLAG_SYMBOL                     DUK_HEAPHDR_USER_FLAG(2)  /* string is a symbol (invalid utf-8) */\n#define DUK_HSTRING_FLAG_HIDDEN                     DUK_HEAPHDR_USER_FLAG(3)  /* string is a hidden symbol (implies symbol, Duktape 1.x internal string) */\n#define DUK_HSTRING_FLAG_RESERVED_WORD              DUK_HEAPHDR_USER_FLAG(4)  /* string is a reserved word (non-strict) */\n#define DUK_HSTRING_FLAG_STRICT_RESERVED_WORD       DUK_HEAPHDR_USER_FLAG(5)  /* string is a reserved word (strict) */\n#define DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS          DUK_HEAPHDR_USER_FLAG(6)  /* string is 'eval' or 'arguments' */\n#define DUK_HSTRING_FLAG_EXTDATA                    DUK_HEAPHDR_USER_FLAG(7)  /* string data is external (duk_hstring_external) */\n#define DUK_HSTRING_FLAG_PINNED_LITERAL             DUK_HEAPHDR_USER_FLAG(8)  /* string is a literal, and pinned */\n\n#define DUK_HSTRING_HAS_ASCII(x)                    DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII)\n#define DUK_HSTRING_HAS_ARRIDX(x)                   DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX)\n#define DUK_HSTRING_HAS_SYMBOL(x)                   DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL)\n#define DUK_HSTRING_HAS_HIDDEN(x)                   DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN)\n#define DUK_HSTRING_HAS_RESERVED_WORD(x)            DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD)\n#define DUK_HSTRING_HAS_STRICT_RESERVED_WORD(x)     DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD)\n#define DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(x)        DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS)\n#define DUK_HSTRING_HAS_EXTDATA(x)                  DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA)\n#define DUK_HSTRING_HAS_PINNED_LITERAL(x)           DUK_HEAPHDR_CHECK_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL)\n\n#define DUK_HSTRING_SET_ASCII(x)                    DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII)\n#define DUK_HSTRING_SET_ARRIDX(x)                   DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX)\n#define DUK_HSTRING_SET_SYMBOL(x)                   DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL)\n#define DUK_HSTRING_SET_HIDDEN(x)                   DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN)\n#define DUK_HSTRING_SET_RESERVED_WORD(x)            DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD)\n#define DUK_HSTRING_SET_STRICT_RESERVED_WORD(x)     DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD)\n#define DUK_HSTRING_SET_EVAL_OR_ARGUMENTS(x)        DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS)\n#define DUK_HSTRING_SET_EXTDATA(x)                  DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA)\n#define DUK_HSTRING_SET_PINNED_LITERAL(x)           DUK_HEAPHDR_SET_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL)\n\n#define DUK_HSTRING_CLEAR_ASCII(x)                  DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ASCII)\n#define DUK_HSTRING_CLEAR_ARRIDX(x)                 DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_ARRIDX)\n#define DUK_HSTRING_CLEAR_SYMBOL(x)                 DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_SYMBOL)\n#define DUK_HSTRING_CLEAR_HIDDEN(x)                 DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_HIDDEN)\n#define DUK_HSTRING_CLEAR_RESERVED_WORD(x)          DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_RESERVED_WORD)\n#define DUK_HSTRING_CLEAR_STRICT_RESERVED_WORD(x)   DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_STRICT_RESERVED_WORD)\n#define DUK_HSTRING_CLEAR_EVAL_OR_ARGUMENTS(x)      DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS)\n#define DUK_HSTRING_CLEAR_EXTDATA(x)                DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_EXTDATA)\n#define DUK_HSTRING_CLEAR_PINNED_LITERAL(x)         DUK_HEAPHDR_CLEAR_FLAG_BITS(&(x)->hdr, DUK_HSTRING_FLAG_PINNED_LITERAL)\n\n#if 0  /* Slightly smaller code without explicit flag, but explicit flag\n        * is very useful when 'clen' is dropped.\n        */\n#define DUK_HSTRING_IS_ASCII(x)                     (DUK_HSTRING_GET_BYTELEN((x)) == DUK_HSTRING_GET_CHARLEN((x)))\n#endif\n#define DUK_HSTRING_IS_ASCII(x)                     DUK_HSTRING_HAS_ASCII((x))  /* lazily set! */\n#define DUK_HSTRING_IS_EMPTY(x)                     (DUK_HSTRING_GET_BYTELEN((x)) == 0)\n\n#if defined(DUK_USE_STRHASH16)\n#define DUK_HSTRING_GET_HASH(x)                     ((x)->hdr.h_flags >> 16)\n#define DUK_HSTRING_SET_HASH(x,v) do { \\\n\t\t(x)->hdr.h_flags = ((x)->hdr.h_flags & 0x0000ffffUL) | ((v) << 16); \\\n\t} while (0)\n#else\n#define DUK_HSTRING_GET_HASH(x)                     ((x)->hash)\n#define DUK_HSTRING_SET_HASH(x,v) do { \\\n\t\t(x)->hash = (v); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_STRLEN16)\n#define DUK_HSTRING_GET_BYTELEN(x)                  ((x)->hdr.h_strextra16)\n#define DUK_HSTRING_SET_BYTELEN(x,v) do { \\\n\t\t(x)->hdr.h_strextra16 = (v); \\\n\t} while (0)\n#if defined(DUK_USE_HSTRING_CLEN)\n#define DUK_HSTRING_GET_CHARLEN(x)                  duk_hstring_get_charlen((x))\n#define DUK_HSTRING_SET_CHARLEN(x,v) do { \\\n\t\t(x)->clen16 = (v); \\\n\t} while (0)\n#else\n#define DUK_HSTRING_GET_CHARLEN(x)                  duk_hstring_get_charlen((x))\n#define DUK_HSTRING_SET_CHARLEN(x,v) do { \\\n\t\tDUK_ASSERT(0);  /* should never be called */ \\\n\t} while (0)\n#endif\n#else\n#define DUK_HSTRING_GET_BYTELEN(x)                  ((x)->blen)\n#define DUK_HSTRING_SET_BYTELEN(x,v) do { \\\n\t\t(x)->blen = (v); \\\n\t} while (0)\n#define DUK_HSTRING_GET_CHARLEN(x)                  duk_hstring_get_charlen((x))\n#define DUK_HSTRING_SET_CHARLEN(x,v) do { \\\n\t\t(x)->clen = (v); \\\n\t} while (0)\n#endif\n\n#if defined(DUK_USE_HSTRING_EXTDATA)\n#define DUK_HSTRING_GET_EXTDATA(x) \\\n\t((x)->extdata)\n#define DUK_HSTRING_GET_DATA(x) \\\n\t(DUK_HSTRING_HAS_EXTDATA((x)) ? \\\n\t\tDUK_HSTRING_GET_EXTDATA((const duk_hstring_external *) (x)) : ((const duk_uint8_t *) ((x) + 1)))\n#else\n#define DUK_HSTRING_GET_DATA(x) \\\n\t((const duk_uint8_t *) ((x) + 1))\n#endif\n\n#define DUK_HSTRING_GET_DATA_END(x) \\\n\t(DUK_HSTRING_GET_DATA((x)) + (x)->blen)\n\n/* Marker value; in E5 2^32-1 is not a valid array index (2^32-2 is highest\n * valid).\n */\n#define DUK_HSTRING_NO_ARRAY_INDEX  (0xffffffffUL)\n\n#if defined(DUK_USE_HSTRING_ARRIDX)\n#define DUK_HSTRING_GET_ARRIDX_FAST(h)  ((h)->arridx)\n#define DUK_HSTRING_GET_ARRIDX_SLOW(h)  ((h)->arridx)\n#else\n/* Get array index related to string (or return DUK_HSTRING_NO_ARRAY_INDEX);\n * avoids helper call if string has no array index value.\n */\n#define DUK_HSTRING_GET_ARRIDX_FAST(h)  \\\n\t(DUK_HSTRING_HAS_ARRIDX((h)) ? duk_js_to_arrayindex_hstring_fast_known((h)) : DUK_HSTRING_NO_ARRAY_INDEX)\n\n/* Slower but more compact variant. */\n#define DUK_HSTRING_GET_ARRIDX_SLOW(h)  \\\n\t(duk_js_to_arrayindex_hstring_fast((h)))\n#endif\n\n/* XXX: these actually fit into duk_hstring */\n#define DUK_SYMBOL_TYPE_HIDDEN 0\n#define DUK_SYMBOL_TYPE_GLOBAL 1\n#define DUK_SYMBOL_TYPE_LOCAL 2\n#define DUK_SYMBOL_TYPE_WELLKNOWN 3\n\n/* Assertion for duk_hstring validity. */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_hstring_assert_valid(duk_hstring *h);\n#define DUK_HSTRING_ASSERT_VALID(h)  do { duk_hstring_assert_valid((h)); } while (0)\n#else\n#define DUK_HSTRING_ASSERT_VALID(h)  do {} while (0)\n#endif\n\n/*\n *  Misc\n */\n\nstruct duk_hstring {\n\t/* Smaller heaphdr than for other objects, because strings are held\n\t * in string intern table which requires no link pointers.  Much of\n\t * the 32-bit flags field is unused by flags, so we can stuff a 16-bit\n\t * field in there.\n\t */\n\tduk_heaphdr_string hdr;\n\n\t/* String hash. */\n#if defined(DUK_USE_STRHASH16)\n\t/* If 16-bit hash is in use, stuff it into duk_heaphdr_string flags. */\n#else\n\tduk_uint32_t hash;\n#endif\n\n\t/* Precomputed array index (or DUK_HSTRING_NO_ARRAY_INDEX). */\n#if defined(DUK_USE_HSTRING_ARRIDX)\n\tduk_uarridx_t arridx;\n#endif\n\n\t/* Length in bytes (not counting NUL term). */\n#if defined(DUK_USE_STRLEN16)\n\t/* placed in duk_heaphdr_string */\n#else\n\tduk_uint32_t blen;\n#endif\n\n\t/* Length in codepoints (must be E5 compatible). */\n#if defined(DUK_USE_STRLEN16)\n#if defined(DUK_USE_HSTRING_CLEN)\n\tduk_uint16_t clen16;\n#else\n\t/* computed live */\n#endif\n#else\n\tduk_uint32_t clen;\n#endif\n\n\t/*\n\t *  String data of 'blen+1' bytes follows (+1 for NUL termination\n\t *  convenience for C API).  No alignment needs to be guaranteed\n\t *  for strings, but fields above should guarantee alignment-by-4\n\t *  (but not alignment-by-8).\n\t */\n};\n\n/* The external string struct is defined even when the feature is inactive. */\nstruct duk_hstring_external {\n\tduk_hstring str;\n\n\t/*\n\t *  For an external string, the NUL-terminated string data is stored\n\t *  externally.  The user must guarantee that data behind this pointer\n\t *  doesn't change while it's used.\n\t */\n\n\tconst duk_uint8_t *extdata;\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, duk_uint_t pos, duk_bool_t surrogate_aware);\nDUK_INTERNAL_DECL duk_bool_t duk_hstring_equals_ascii_cstring(duk_hstring *h, const char *cstr);\nDUK_INTERNAL_DECL duk_size_t duk_hstring_get_charlen(duk_hstring *h);\n#if !defined(DUK_USE_HSTRING_LAZY_CLEN)\nDUK_INTERNAL_DECL void duk_hstring_init_charlen(duk_hstring *h);\n#endif\n\n#endif  /* DUK_HSTRING_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hstring_assert.c",
    "content": "/*\n *  duk_hstring assertion helpers.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_ASSERTIONS)\n\nDUK_INTERNAL void duk_hstring_assert_valid(duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n}\n\n#endif  /* DUK_USE_ASSERTIONS */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hstring_misc.c",
    "content": "/*\n *  Misc support functions\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  duk_hstring charCodeAt, with and without surrogate awareness\n */\n\nDUK_INTERNAL duk_ucodepoint_t duk_hstring_char_code_at_raw(duk_hthread *thr, duk_hstring *h, duk_uint_t pos, duk_bool_t surrogate_aware) {\n\tduk_uint32_t boff;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_ucodepoint_t cp1;\n\tduk_ucodepoint_t cp2;\n\n\t/* Caller must check character offset to be inside the string. */\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT_DISABLE(pos >= 0);  /* unsigned */\n\tDUK_ASSERT(pos < (duk_uint_t) DUK_HSTRING_GET_CHARLEN(h));\n\n\tboff = (duk_uint32_t) duk_heap_strcache_offset_char2byte(thr, h, (duk_uint32_t) pos);\n\tDUK_DDD(DUK_DDDPRINT(\"charCodeAt: pos=%ld -> boff=%ld, str=%!O\",\n\t                     (long) pos, (long) boff, (duk_heaphdr *) h));\n\tDUK_ASSERT_DISABLE(boff >= 0);\n\tDUK_ASSERT(boff < DUK_HSTRING_GET_BYTELEN(h));\n\n\tp_start = DUK_HSTRING_GET_DATA(h);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h);\n\tp = p_start + boff;\n\tDUK_DDD(DUK_DDDPRINT(\"p_start=%p, p_end=%p, p=%p\",\n\t                     (const void *) p_start, (const void *) p_end,\n\t                     (const void *) p));\n\n\t/* For invalid UTF-8 (never happens for standard ECMAScript strings)\n\t * return U+FFFD replacement character.\n\t */\n\tif (duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp1)) {\n\t\tif (surrogate_aware && cp1 >= 0xd800UL && cp1 <= 0xdbffUL) {\n\t\t\t/* The decode helper is memory safe even if 'cp1' was\n\t\t\t * decoded at the end of the string and 'p' is no longer\n\t\t\t * within string memory range.\n\t\t\t */\n\t\t\tcp2 = 0;  /* If call fails, this is left untouched and won't match cp2 check. */\n\t\t\t(void) duk_unicode_decode_xutf8(thr, &p, p_start, p_end, &cp2);\n\t\t\tif (cp2 >= 0xdc00UL && cp2 <= 0xdfffUL) {\n\t\t\t\tcp1 = (duk_ucodepoint_t) (((cp1 - 0xd800UL) << 10) + (cp2 - 0xdc00UL) + 0x10000UL);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tcp1 = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t}\n\n\treturn cp1;\n}\n\n/*\n *  duk_hstring charlen, when lazy charlen disabled\n */\n\n#if !defined(DUK_USE_HSTRING_LAZY_CLEN)\n#if !defined(DUK_USE_HSTRING_CLEN)\n#error non-lazy duk_hstring charlen but DUK_USE_HSTRING_CLEN not set\n#endif\nDUK_INTERNAL void duk_hstring_init_charlen(duk_hstring *h) {\n\tduk_uint32_t clen;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(!DUK_HSTRING_HAS_ASCII(h));\n\tDUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h));\n\n\tclen = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n#if defined(DUK_USE_STRLEN16)\n\tDUK_ASSERT(clen <= 0xffffUL);  /* Bytelength checked during interning. */\n\th->clen16 = (duk_uint16_t) clen;\n#else\n\th->clen = (duk_uint32_t) clen;\n#endif\n\tif (DUK_LIKELY(clen == DUK_HSTRING_GET_BYTELEN(h))) {\n\t\tDUK_HSTRING_SET_ASCII(h);\n\t}\n}\n\nDUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {\n#if defined(DUK_USE_STRLEN16)\n\treturn h->clen16;\n#else\n\treturn h->clen;\n#endif\n}\n#endif  /* !DUK_USE_HSTRING_LAZY_CLEN */\n\n/*\n *  duk_hstring charlen, when lazy charlen enabled\n */\n\n#if defined(DUK_USE_HSTRING_LAZY_CLEN)\n#if defined(DUK_USE_HSTRING_CLEN)\nDUK_LOCAL DUK_COLD duk_size_t duk__hstring_get_charlen_slowpath(duk_hstring *h) {\n\tduk_size_t res;\n\n\tDUK_ASSERT(h->clen == 0);  /* Checked by caller. */\n\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* ROM strings have precomputed clen, but if the computed clen is zero\n\t * we can still come here and can't write anything.\n\t */\n\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) {\n\t\treturn 0;\n\t}\n#endif\n\n\tres = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n#if defined(DUK_USE_STRLEN16)\n\tDUK_ASSERT(res <= 0xffffUL);  /* Bytelength checked during interning. */\n\th->clen16 = (duk_uint16_t) res;\n#else\n\th->clen = (duk_uint32_t) res;\n#endif\n\tif (DUK_LIKELY(res == DUK_HSTRING_GET_BYTELEN(h))) {\n\t\tDUK_HSTRING_SET_ASCII(h);\n\t}\n\treturn res;\n}\n#else  /* DUK_USE_HSTRING_CLEN */\nDUK_LOCAL duk_size_t duk__hstring_get_charlen_slowpath(duk_hstring *h) {\n\tif (DUK_LIKELY(DUK_HSTRING_HAS_ASCII(h))) {\n\t\t/* Most practical strings will go here. */\n\t\treturn DUK_HSTRING_GET_BYTELEN(h);\n\t} else {\n\t\t/* ASCII flag is lazy, so set it here. */\n\t\tduk_size_t res;\n\n\t\t/* XXX: here we could use the strcache to speed up the\n\t\t * computation (matters for 'i < str.length' loops).\n\t\t */\n\n\t\tres = duk_unicode_unvalidated_utf8_length(DUK_HSTRING_GET_DATA(h), DUK_HSTRING_GET_BYTELEN(h));\n\n#if defined(DUK_USE_ROM_STRINGS)\n\t\tif (DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) h)) {\n\t\t\t/* For ROM strings, can't write anything; ASCII flag\n\t\t\t * is preset so we don't need to update it.\n\t\t\t */\n\t\t\treturn res;\n\t\t}\n#endif\n\t\tif (DUK_LIKELY(res == DUK_HSTRING_GET_BYTELEN(h))) {\n\t\t\tDUK_HSTRING_SET_ASCII(h);\n\t\t}\n\t\treturn res;\n\t}\n}\n#endif  /* DUK_USE_HSTRING_CLEN */\n\n#if defined(DUK_USE_HSTRING_CLEN)\nDUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {\n#if defined(DUK_USE_STRLEN16)\n\tif (DUK_LIKELY(h->clen16 != 0)) {\n\t\treturn h->clen16;\n\t}\n#else\n\tif (DUK_LIKELY(h->clen != 0)) {\n\t\treturn h->clen;\n\t}\n#endif\n\treturn duk__hstring_get_charlen_slowpath(h);\n}\n#else  /* DUK_USE_HSTRING_CLEN */\nDUK_INTERNAL DUK_HOT duk_size_t duk_hstring_get_charlen(duk_hstring *h) {\n\t/* Always use slow path. */\n\treturn duk__hstring_get_charlen_slowpath(h);\n}\n#endif  /* DUK_USE_HSTRING_CLEN */\n#endif  /* DUK_USE_HSTRING_LAZY_CLEN */\n\n/*\n *  Compare duk_hstring to an ASCII cstring.\n */\n\nDUK_INTERNAL duk_bool_t duk_hstring_equals_ascii_cstring(duk_hstring *h, const char *cstr) {\n\tduk_size_t len;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(cstr != NULL);\n\n\tlen = DUK_STRLEN(cstr);\n\tif (len != DUK_HSTRING_GET_BYTELEN(h)) {\n\t\treturn 0;\n\t}\n\tif (duk_memcmp((const void *) cstr, (const void *) DUK_HSTRING_GET_DATA(h), len) == 0) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hthread.h",
    "content": "/*\n *  Heap thread object representation.\n *\n *  duk_hthread is also the 'context' for public API functions via a\n *  different typedef.  Most API calls operate on the topmost frame\n *  of the value stack only.\n */\n\n#if !defined(DUK_HTHREAD_H_INCLUDED)\n#define DUK_HTHREAD_H_INCLUDED\n\n/*\n *  Stack constants\n */\n\n/* Initial valstack size, roughly 0.7kiB. */\n#define DUK_VALSTACK_INITIAL_SIZE       96U\n\n/* Internal extra elements assumed on function entry, always added to\n * user-defined 'extra' for e.g. the duk_check_stack() call.\n */\n#define DUK_VALSTACK_INTERNAL_EXTRA     32U\n\n/* Number of elements guaranteed to be user accessible (in addition to call\n * arguments) on Duktape/C function entry.  This is the major public API\n * commitment.\n */\n#define DUK_VALSTACK_API_ENTRY_MINIMUM  DUK_API_ENTRY_STACK\n\n/*\n *  Activation defines\n */\n\n#define DUK_ACT_FLAG_STRICT             (1U << 0)  /* function executes in strict mode */\n#define DUK_ACT_FLAG_TAILCALLED         (1U << 1)  /* activation has tail called one or more times */\n#define DUK_ACT_FLAG_CONSTRUCT          (1U << 2)  /* function executes as a constructor (called via \"new\") */\n#define DUK_ACT_FLAG_PREVENT_YIELD      (1U << 3)  /* activation prevents yield (native call or \"new\") */\n#define DUK_ACT_FLAG_DIRECT_EVAL        (1U << 4)  /* activation is a direct eval call */\n#define DUK_ACT_FLAG_CONSTRUCT_PROXY    (1U << 5)  /* activation is for Proxy 'construct' call, special return value handling */\n#define DUK_ACT_FLAG_BREAKPOINT_ACTIVE  (1U << 6)  /* activation has active breakpoint(s) */\n\n#define DUK_ACT_GET_FUNC(act)           ((act)->func)\n\n/*\n *  Flags for __FILE__ / __LINE__ registered into tracedata\n */\n\n#define DUK_TB_FLAG_NOBLAME_FILELINE    (1U << 0)  /* don't report __FILE__ / __LINE__ as fileName/lineNumber */\n\n/*\n *  Catcher defines\n */\n\n/* XXX: remove catcher type entirely */\n\n/* flags field: LLLLLLFT, L = label (24 bits), F = flags (4 bits), T = type (4 bits) */\n#define DUK_CAT_TYPE_MASK            0x0000000fUL\n#define DUK_CAT_TYPE_BITS            4\n#define DUK_CAT_LABEL_MASK           0xffffff00UL\n#define DUK_CAT_LABEL_BITS           24\n#define DUK_CAT_LABEL_SHIFT          8\n\n#define DUK_CAT_FLAG_CATCH_ENABLED          (1U << 4)   /* catch part will catch */\n#define DUK_CAT_FLAG_FINALLY_ENABLED        (1U << 5)   /* finally part will catch */\n#define DUK_CAT_FLAG_CATCH_BINDING_ENABLED  (1U << 6)   /* request to create catch binding */\n#define DUK_CAT_FLAG_LEXENV_ACTIVE          (1U << 7)   /* catch or with binding is currently active */\n\n#define DUK_CAT_TYPE_UNKNOWN         0\n#define DUK_CAT_TYPE_TCF             1\n#define DUK_CAT_TYPE_LABEL           2\n\n#define DUK_CAT_GET_TYPE(c)          ((c)->flags & DUK_CAT_TYPE_MASK)\n#define DUK_CAT_GET_LABEL(c)         (((c)->flags & DUK_CAT_LABEL_MASK) >> DUK_CAT_LABEL_SHIFT)\n\n#define DUK_CAT_HAS_CATCH_ENABLED(c)           ((c)->flags & DUK_CAT_FLAG_CATCH_ENABLED)\n#define DUK_CAT_HAS_FINALLY_ENABLED(c)         ((c)->flags & DUK_CAT_FLAG_FINALLY_ENABLED)\n#define DUK_CAT_HAS_CATCH_BINDING_ENABLED(c)   ((c)->flags & DUK_CAT_FLAG_CATCH_BINDING_ENABLED)\n#define DUK_CAT_HAS_LEXENV_ACTIVE(c)           ((c)->flags & DUK_CAT_FLAG_LEXENV_ACTIVE)\n\n#define DUK_CAT_SET_CATCH_ENABLED(c)    do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_CATCH_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_SET_FINALLY_ENABLED(c)  do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_FINALLY_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_SET_CATCH_BINDING_ENABLED(c)    do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_CATCH_BINDING_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_SET_LEXENV_ACTIVE(c)    do { \\\n\t\t(c)->flags |= DUK_CAT_FLAG_LEXENV_ACTIVE; \\\n\t} while (0)\n\n#define DUK_CAT_CLEAR_CATCH_ENABLED(c)    do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_CATCH_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_CLEAR_FINALLY_ENABLED(c)  do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_FINALLY_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_CLEAR_CATCH_BINDING_ENABLED(c)    do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_CATCH_BINDING_ENABLED; \\\n\t} while (0)\n#define DUK_CAT_CLEAR_LEXENV_ACTIVE(c)    do { \\\n\t\t(c)->flags &= ~DUK_CAT_FLAG_LEXENV_ACTIVE; \\\n\t} while (0)\n\n/*\n *  Thread defines\n */\n\n#if defined(DUK_USE_ROM_STRINGS)\n#define DUK_HTHREAD_GET_STRING(thr,idx) \\\n\t((duk_hstring *) DUK_LOSE_CONST(duk_rom_strings_stridx[(idx)]))\n#else  /* DUK_USE_ROM_STRINGS */\n#if defined(DUK_USE_HEAPPTR16)\n#define DUK_HTHREAD_GET_STRING(thr,idx) \\\n\t((duk_hstring *) DUK_USE_HEAPPTR_DEC16((thr)->heap->heap_udata, (thr)->strs16[(idx)]))\n#else\n#define DUK_HTHREAD_GET_STRING(thr,idx) \\\n\t((thr)->strs[(idx)])\n#endif\n#endif  /* DUK_USE_ROM_STRINGS */\n\n/* values for the state field */\n#define DUK_HTHREAD_STATE_INACTIVE     1   /* thread not currently running */\n#define DUK_HTHREAD_STATE_RUNNING      2   /* thread currently running (only one at a time) */\n#define DUK_HTHREAD_STATE_RESUMED      3   /* thread resumed another thread (active but not running) */\n#define DUK_HTHREAD_STATE_YIELDED      4   /* thread has yielded */\n#define DUK_HTHREAD_STATE_TERMINATED   5   /* thread has terminated */\n\n/* Executor interrupt default interval when nothing else requires a\n * smaller value.  The default interval must be small enough to allow\n * for reasonable execution timeout checking but large enough to keep\n * impact on execution performance low.\n */\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n#define DUK_HTHREAD_INTCTR_DEFAULT     (256L * 1024L)\n#endif\n\n/*\n *  Assert context is valid: non-NULL pointer, fields look sane.\n *\n *  This is used by public API call entrypoints to catch invalid 'ctx' pointers\n *  as early as possible; invalid 'ctx' pointers cause very odd and difficult to\n *  diagnose behavior so it's worth checking even when the check is not 100%.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\n/* Assertions for internals. */\nDUK_INTERNAL_DECL void duk_hthread_assert_valid(duk_hthread *thr);\n#define DUK_HTHREAD_ASSERT_VALID(thr)  do { duk_hthread_assert_valid((thr)); } while (0)\n\n/* Assertions for public API calls; a bit stronger. */\nDUK_INTERNAL_DECL void duk_ctx_assert_valid(duk_hthread *thr);\n#define DUK_CTX_ASSERT_VALID(thr)  do { duk_ctx_assert_valid((thr)); } while (0)\n#else\n#define DUK_HTHREAD_ASSERT_VALID(thr)  do {} while (0)\n#define DUK_CTX_ASSERT_VALID(thr)  do {} while (0)\n#endif\n\n/* Assertions for API call entry specifically.  Checks 'ctx' but also may\n * check internal state (e.g. not in a debugger transport callback).\n */\n#define DUK_ASSERT_API_ENTRY(thr) do { \\\n\t\tDUK_CTX_ASSERT_VALID((thr)); \\\n\t\tDUK_ASSERT((thr)->heap != NULL); \\\n\t\tDUK_ASSERT((thr)->heap->dbg_calling_transport == 0); \\\n\t} while (0)\n\n/*\n *  Assertion helpers.\n */\n\n#define DUK_ASSERT_STRIDX_VALID(val) \\\n\tDUK_ASSERT((duk_uint_t) (val) < DUK_HEAP_NUM_STRINGS)\n\n#define DUK_ASSERT_BIDX_VALID(val) \\\n\tDUK_ASSERT((duk_uint_t) (val) < DUK_NUM_BUILTINS)\n\n/*\n *  Misc\n */\n\n/* Fast access to 'this' binding.  Assumes there's a call in progress. */\n#define DUK_HTHREAD_THIS_PTR(thr) \\\n\t(DUK_ASSERT_EXPR((thr) != NULL), \\\n\t DUK_ASSERT_EXPR((thr)->valstack_bottom > (thr)->valstack), \\\n\t (thr)->valstack_bottom - 1)\n\n/*\n *  Struct defines\n */\n\n/* Fields are ordered for alignment/packing. */\nstruct duk_activation {\n\tduk_tval tv_func;       /* borrowed: full duk_tval for function being executed; for lightfuncs */\n\tduk_hobject *func;      /* borrowed: function being executed; for bound function calls, this is the final, real function, NULL for lightfuncs */\n\tduk_activation *parent; /* previous (parent) activation (or NULL if none) */\n\tduk_hobject *var_env;   /* current variable environment (may be NULL if delayed) */\n\tduk_hobject *lex_env;   /* current lexical environment (may be NULL if delayed) */\n\tduk_catcher *cat;       /* current catcher (or NULL) */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t/* Previous value of 'func' caller, restored when unwound.  Only in use\n\t * when 'func' is non-strict.\n\t */\n\tduk_hobject *prev_caller;\n#endif\n\n\tduk_instr_t *curr_pc;   /* next instruction to execute (points to 'func' bytecode, stable pointer), NULL for native calls */\n\n\t/* bottom_byteoff and retval_byteoff are only used for book-keeping\n\t * of ECMAScript-initiated calls, to allow returning to an ECMAScript\n\t * function properly.\n\t */\n\n\t/* Bottom of valstack for this activation, used to reset\n\t * valstack_bottom on return; offset is absolute.  There's\n\t * no need to track 'top' because native call handling deals\n\t * with that using locals, and for ECMAScript returns 'nregs'\n\t * indicates the necessary top.\n\t */\n\tduk_size_t bottom_byteoff;\n\n\t/* Return value when returning to this activation (points to caller\n\t * reg, not callee reg); offset is absolute (only set if activation is\n\t * not topmost).\n\t *\n\t * Note: bottom_byteoff is always set, while retval_byteoff is only\n\t * applicable for activations below the topmost one.  Currently\n\t * retval_byteoff for the topmost activation is considered garbage\n\t * (and it not initialized on entry or cleared on return; may contain\n\t * previous or garbage values).\n\t */\n\tduk_size_t retval_byteoff;\n\n\t/* Current 'this' binding is the value just below bottom.\n\t * Previously, 'this' binding was handled with an index to the\n\t * (calling) valstack.  This works for everything except tail\n\t * calls, which must not \"accumulate\" valstack temps.\n\t */\n\n\t/* Value stack reserve (valstack_end) byte offset to be restored\n\t * when returning to this activation.  Only used by the bytecode\n\t * executor.\n\t */\n\tduk_size_t reserve_byteoff;\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_uint32_t prev_line; /* needed for stepping */\n#endif\n\n\tduk_small_uint_t flags;\n};\n\nstruct duk_catcher {\n\tduk_catcher *parent;            /* previous (parent) catcher (or NULL if none) */\n\tduk_hstring *h_varname;         /* borrowed reference to catch variable name (or NULL if none) */\n\t                                /* (reference is valid as long activation exists) */\n\tduk_instr_t *pc_base;           /* resume execution from pc_base or pc_base+1 (points to 'func' bytecode, stable pointer) */\n\tduk_size_t idx_base;            /* idx_base and idx_base+1 get completion value and type */\n\tduk_uint32_t flags;             /* type and control flags, label number */\n\t/* XXX: could pack 'flags' and 'idx_base' to same value in practice,\n\t * on 32-bit targets this would make duk_catcher 16 bytes.\n\t */\n};\n\nstruct duk_hthread {\n\t/* Shared object part */\n\tduk_hobject obj;\n\n\t/* Pointer to bytecode executor's 'curr_pc' variable.  Used to copy\n\t * the current PC back into the topmost activation when activation\n\t * state is about to change (or \"syncing\" is otherwise needed).  This\n\t * is rather awkward but important for performance, see execution.rst.\n\t */\n\tduk_instr_t **ptr_curr_pc;\n\n\t/* Backpointers. */\n\tduk_heap *heap;\n\n\t/* Current strictness flag: affects API calls. */\n\tduk_uint8_t strict;\n\n\t/* Thread state. */\n\tduk_uint8_t state;\n\tduk_uint8_t unused1;\n\tduk_uint8_t unused2;\n\n\t/* XXX: Valstack and callstack are currently assumed to have non-NULL\n\t * pointers.  Relaxing this would not lead to big benefits (except\n\t * perhaps for terminated threads).\n\t */\n\n\t/* Value stack: these are expressed as pointers for faster stack\n\t * manipulation.  [valstack,valstack_top[ is GC-reachable,\n\t * [valstack_top,valstack_alloc_end[ is not GC-reachable but kept\n\t * initialized as 'undefined'.  [valstack,valstack_end[ is the\n\t * guaranteed/reserved space and the valstack cannot be resized to\n\t * a smaller size.  [valstack_end,valstack_alloc_end[ is currently\n\t * allocated slack that can be used to grow the current guaranteed\n\t * space but may be shrunk away without notice.\n\t *\n\t *\n\t * <----------------------- guaranteed --->\n\t *                                        <---- slack --->\n\t *               <--- frame --->\n\t * .-------------+=============+----------+--------------.\n\t * |xxxxxxxxxxxxx|yyyyyyyyyyyyy|uuuuuuuuuu|uuuuuuuuuuuuuu|\n\t * `-------------+=============+----------+--------------'\n\t *\n\t * ^             ^             ^          ^              ^\n\t * |             |             |          |              |\n\t * valstack      bottom        top        end            alloc_end\n\t *\n\t *     xxx = arbitrary values, below current frame\n\t *     yyy = arbitrary values, inside current frame\n\t *     uuu = outside active value stack, initialized to 'undefined'\n\t */\n\tduk_tval *valstack;                     /* start of valstack allocation */\n\tduk_tval *valstack_end;                 /* end of valstack reservation/guarantee (exclusive) */\n\tduk_tval *valstack_alloc_end;           /* end of valstack allocation */\n\tduk_tval *valstack_bottom;              /* bottom of current frame */\n\tduk_tval *valstack_top;                 /* top of current frame (exclusive) */\n\n\t/* Call stack, represented as a linked list starting from the current\n\t * activation (or NULL if nothing is active).\n\t */\n\tduk_activation *callstack_curr;         /* current activation (or NULL if none) */\n\tduk_size_t callstack_top;               /* number of activation records in callstack (0 if none) */\n\tduk_size_t callstack_preventcount;      /* number of activation records in callstack preventing a yield */\n\n\t/* Yield/resume book-keeping. */\n\tduk_hthread *resumer;                   /* who resumed us (if any) */\n\n\t/* Current compiler state (if any), used for augmenting SyntaxErrors. */\n\tduk_compiler_ctx *compile_ctx;\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\t/* Interrupt counter for triggering a slow path check for execution\n\t * timeout, debugger interaction such as breakpoints, etc.  The value\n\t * is valid for the current running thread, and both the init and\n\t * counter values are copied whenever a thread switch occurs.  It's\n\t * important for the counter to be conveniently accessible for the\n\t * bytecode executor inner loop for performance reasons.\n\t */\n\tduk_int_t interrupt_counter;    /* countdown state */\n\tduk_int_t interrupt_init;       /* start value for current countdown */\n#endif\n\n\t/* Builtin-objects; may or may not be shared with other threads,\n\t * threads existing in different \"compartments\" will have different\n\t * built-ins.  Must be stored on a per-thread basis because there\n\t * is no intermediate structure for a thread group / compartment.\n\t * This takes quite a lot of space, currently 43x4 = 172 bytes on\n\t * 32-bit platforms.\n\t *\n\t * In some cases the builtins array could be ROM based, but it's\n\t * sometimes edited (e.g. for sandboxing) so it's better to keep\n\t * this array in RAM.\n\t */\n\tduk_hobject *builtins[DUK_NUM_BUILTINS];\n\n\t/* Convenience copies from heap/vm for faster access. */\n#if defined(DUK_USE_ROM_STRINGS)\n\t/* No field needed when strings are in ROM. */\n#else\n#if defined(DUK_USE_HEAPPTR16)\n\tduk_uint16_t *strs16;\n#else\n\tduk_hstring **strs;\n#endif\n#endif\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_hthread_copy_builtin_objects(duk_hthread *thr_from, duk_hthread *thr_to);\nDUK_INTERNAL_DECL void duk_hthread_create_builtin_objects(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_terminate(duk_hthread *thr);\n\nDUK_INTERNAL_DECL duk_activation *duk_hthread_activation_alloc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_activation_free(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_hthread_activation_unwind_norz(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_activation_unwind_reuse_norz(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_activation *duk_hthread_get_activation_for_level(duk_hthread *thr, duk_int_t level);\n\nDUK_INTERNAL_DECL duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_catcher_free(duk_hthread *thr, duk_catcher *cat);\nDUK_INTERNAL_DECL void duk_hthread_catcher_unwind_norz(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_hthread_catcher_unwind_nolexenv_norz(duk_hthread *thr, duk_activation *act);\n\n#if defined(DUK_USE_FINALIZER_TORTURE)\nDUK_INTERNAL_DECL void duk_hthread_valstack_torture_realloc(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud);  /* indirect allocs */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_hthread_get_act_curr_pc(duk_hthread *thr, duk_activation *act);\n#endif\nDUK_INTERNAL_DECL duk_uint_fast32_t duk_hthread_get_act_prev_pc(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_hthread_sync_currpc(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_hthread_sync_and_null_currpc(duk_hthread *thr);\n\n#endif  /* DUK_HTHREAD_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hthread_alloc.c",
    "content": "/*\n *  duk_hthread allocation and freeing.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Allocate initial stacks for a thread.  Note that 'thr' must be reachable\n *  as a garbage collection may be triggered by the allocation attempts.\n *  Returns zero (without leaking memory) if init fails.\n */\n\nDUK_INTERNAL duk_bool_t duk_hthread_init_stacks(duk_heap *heap, duk_hthread *thr) {\n\tduk_size_t alloc_size;\n\tduk_size_t i;\n\n\tDUK_ASSERT(heap != NULL);\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->valstack == NULL);\n\tDUK_ASSERT(thr->valstack_end == NULL);\n\tDUK_ASSERT(thr->valstack_alloc_end == NULL);\n\tDUK_ASSERT(thr->valstack_bottom == NULL);\n\tDUK_ASSERT(thr->valstack_top == NULL);\n\tDUK_ASSERT(thr->callstack_curr == NULL);\n\n\t/* valstack */\n\tDUK_ASSERT(DUK_VALSTACK_API_ENTRY_MINIMUM <= DUK_VALSTACK_INITIAL_SIZE);\n\talloc_size = sizeof(duk_tval) * DUK_VALSTACK_INITIAL_SIZE;\n\tthr->valstack = (duk_tval *) DUK_ALLOC(heap, alloc_size);\n\tif (!thr->valstack) {\n\t\tgoto fail;\n\t}\n\tduk_memzero(thr->valstack, alloc_size);\n\tthr->valstack_end = thr->valstack + DUK_VALSTACK_API_ENTRY_MINIMUM;\n\tthr->valstack_alloc_end = thr->valstack + DUK_VALSTACK_INITIAL_SIZE;\n\tthr->valstack_bottom = thr->valstack;\n\tthr->valstack_top = thr->valstack;\n\n\tfor (i = 0; i < DUK_VALSTACK_INITIAL_SIZE; i++) {\n\t\tDUK_TVAL_SET_UNDEFINED(&thr->valstack[i]);\n\t}\n\n\treturn 1;\n\n fail:\n\tDUK_FREE(heap, thr->valstack);\n\tDUK_ASSERT(thr->callstack_curr == NULL);\n\n\tthr->valstack = NULL;\n\treturn 0;\n}\n\n/* For indirect allocs. */\n\nDUK_INTERNAL void *duk_hthread_get_valstack_ptr(duk_heap *heap, void *ud) {\n\tduk_hthread *thr = (duk_hthread *) ud;\n\tDUK_UNREF(heap);\n\treturn (void *) thr->valstack;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hthread_builtins.c",
    "content": "/*\n *  Initialize built-in objects.  Current thread must have a valstack\n *  and initialization errors may longjmp, so a setjmp() catch point\n *  must exist.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Encoding constants, must match genbuiltins.py\n */\n\n#define DUK__PROP_FLAGS_BITS             3\n#define DUK__LENGTH_PROP_BITS            3\n#define DUK__NARGS_BITS                  3\n#define DUK__PROP_TYPE_BITS              3\n\n#define DUK__NARGS_VARARGS_MARKER        0x07\n\n#define DUK__PROP_TYPE_DOUBLE            0\n#define DUK__PROP_TYPE_STRING            1\n#define DUK__PROP_TYPE_STRIDX            2\n#define DUK__PROP_TYPE_BUILTIN           3\n#define DUK__PROP_TYPE_UNDEFINED         4\n#define DUK__PROP_TYPE_BOOLEAN_TRUE      5\n#define DUK__PROP_TYPE_BOOLEAN_FALSE     6\n#define DUK__PROP_TYPE_ACCESSOR          7\n\n/*\n *  Create built-in objects by parsing an init bitstream generated\n *  by genbuiltins.py.\n */\n\n#if defined(DUK_USE_ROM_OBJECTS)\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) || defined(DUK_USE_ROM_GLOBAL_INHERIT)\nDUK_LOCAL void duk__duplicate_ram_global_object(duk_hthread *thr) {\n\tduk_hobject *h_global;\n#if defined(DUK_USE_ROM_GLOBAL_CLONE)\n\tduk_hobject *h_oldglobal;\n\tduk_uint8_t *props;\n\tduk_size_t alloc_size;\n#endif\n\tduk_hobject *h_objenv;\n\n\t/* XXX: refactor into internal helper, duk_clone_hobject() */\n\n#if defined(DUK_USE_ROM_GLOBAL_INHERIT)\n\t/* Inherit from ROM-based global object: less RAM usage, less transparent. */\n\th_global = duk_push_object_helper(thr,\n\t                                  DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                  DUK_HOBJECT_FLAG_FASTREFS |\n\t                                  DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL),\n\t                                  DUK_BIDX_GLOBAL);\n\tDUK_ASSERT(h_global != NULL);\n#elif defined(DUK_USE_ROM_GLOBAL_CLONE)\n\t/* Clone the properties of the ROM-based global object to create a\n\t * fully RAM-based global object.  Uses more memory than the inherit\n\t * model but more compliant.\n\t */\n\th_global = duk_push_object_helper(thr,\n\t                                  DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                  DUK_HOBJECT_FLAG_FASTREFS |\n\t                                  DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_GLOBAL),\n\t                                  DUK_BIDX_OBJECT_PROTOTYPE);\n\tDUK_ASSERT(h_global != NULL);\n\th_oldglobal = thr->builtins[DUK_BIDX_GLOBAL];\n\tDUK_ASSERT(h_oldglobal != NULL);\n\n\t/* Copy the property table verbatim; this handles attributes etc.\n\t * For ROM objects it's not necessary (or possible) to update\n\t * refcounts so leave them as is.\n\t */\n\talloc_size = DUK_HOBJECT_P_ALLOC_SIZE(h_oldglobal);\n\tDUK_ASSERT(alloc_size > 0);\n\tprops = DUK_ALLOC_CHECKED(thr, alloc_size);\n\tDUK_ASSERT(props != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, h_oldglobal) != NULL);\n\tduk_memcpy((void *) props, (const void *) DUK_HOBJECT_GET_PROPS(thr->heap, h_oldglobal), alloc_size);\n\n\t/* XXX: keep property attributes or tweak them here?\n\t * Properties will now be non-configurable even when they're\n\t * normally configurable for the global object.\n\t */\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROPS(thr->heap, h_global) == NULL);\n\tDUK_HOBJECT_SET_PROPS(thr->heap, h_global, props);\n\tDUK_HOBJECT_SET_ESIZE(h_global, DUK_HOBJECT_GET_ESIZE(h_oldglobal));\n\tDUK_HOBJECT_SET_ENEXT(h_global, DUK_HOBJECT_GET_ENEXT(h_oldglobal));\n\tDUK_HOBJECT_SET_ASIZE(h_global, DUK_HOBJECT_GET_ASIZE(h_oldglobal));\n\tDUK_HOBJECT_SET_HSIZE(h_global, DUK_HOBJECT_GET_HSIZE(h_oldglobal));\n#else\n#error internal error in config defines\n#endif\n\n\tduk_hobject_compact_props(thr, h_global);\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL] != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE((duk_heaphdr *) thr->builtins[DUK_BIDX_GLOBAL]));  /* no need to decref: ROM object */\n\tthr->builtins[DUK_BIDX_GLOBAL] = h_global;\n\tDUK_HOBJECT_INCREF(thr, h_global);\n\tDUK_D(DUK_DPRINT(\"duplicated global object: %!O\", h_global));\n\n\t/* Create a fresh object environment for the global scope.  This is\n\t * needed so that the global scope points to the newly created RAM-based\n\t * global object.\n\t */\n\th_objenv = (duk_hobject *) duk_hobjenv_alloc(thr,\n\t                                             DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                             DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\tDUK_ASSERT(h_objenv != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, h_objenv) == NULL);\n\tduk_push_hobject(thr, h_objenv);\n\n\tDUK_ASSERT(h_global != NULL);\n\t((duk_hobjenv *) h_objenv)->target = h_global;\n\tDUK_HOBJECT_INCREF(thr, h_global);\n\tDUK_ASSERT(((duk_hobjenv *) h_objenv)->has_this == 0);\n\n\tDUK_ASSERT(thr->builtins[DUK_BIDX_GLOBAL_ENV] != NULL);\n\tDUK_ASSERT(!DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE((duk_heaphdr *) thr->builtins[DUK_BIDX_GLOBAL_ENV]));  /* no need to decref: ROM object */\n\tthr->builtins[DUK_BIDX_GLOBAL_ENV] = h_objenv;\n\tDUK_HOBJECT_INCREF(thr, h_objenv);\n\tDUK_D(DUK_DPRINT(\"duplicated global env: %!O\", h_objenv));\n\n\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) h_objenv);\n\n\tduk_pop_2(thr);  /* Pop global object and global env. */\n}\n#endif  /* DUK_USE_ROM_GLOBAL_CLONE || DUK_USE_ROM_GLOBAL_INHERIT */\n\nDUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {\n\t/* Setup builtins from ROM objects.  All heaps/threads will share\n\t * the same readonly objects.\n\t */\n\tduk_small_uint_t i;\n\n\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\tduk_hobject *h;\n\t\th = (duk_hobject *) DUK_LOSE_CONST(duk_rom_builtins_bidx[i]);\n\t\tDUK_ASSERT(h != NULL);\n\t\tthr->builtins[i] = h;\n\t}\n\n#if defined(DUK_USE_ROM_GLOBAL_CLONE) || defined(DUK_USE_ROM_GLOBAL_INHERIT)\n\t/* By default the global object is read-only which is often much\n\t * more of an issue than having read-only built-in objects (like\n\t * RegExp, Date, etc).  Use a RAM-based copy of the global object\n\t * and the global environment object for convenience.\n\t */\n\tduk__duplicate_ram_global_object(thr);\n#endif\n}\n#else  /* DUK_USE_ROM_OBJECTS */\nDUK_LOCAL void duk__push_stridx(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\tduk_small_uint_t n;\n\n\tn = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\tDUK_ASSERT_DISABLE(n >= 0);  /* unsigned */\n\tDUK_ASSERT(n < DUK_HEAP_NUM_STRINGS);\n\tduk_push_hstring_stridx(thr, n);\n}\nDUK_LOCAL void duk__push_string(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\t/* XXX: built-ins data could provide a maximum length that is\n\t * actually needed; bitpacked max length is now 256 bytes.\n\t */\n\tduk_uint8_t tmp[DUK_BD_BITPACKED_STRING_MAXLEN];\n\tduk_small_uint_t len;\n\n\tlen = duk_bd_decode_bitpacked_string(bd, tmp);\n\tduk_push_lstring(thr, (const char *) tmp, (duk_size_t) len);\n}\nDUK_LOCAL void duk__push_stridx_or_string(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\tduk_small_uint_t n;\n\n\tn = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\tif (n == 0) {\n\t\tduk__push_string(thr, bd);\n\t} else {\n\t\tn--;\n\t\tDUK_ASSERT(n < DUK_HEAP_NUM_STRINGS);\n\t\tduk_push_hstring_stridx(thr, n);\n\t}\n}\nDUK_LOCAL void duk__push_double(duk_hthread *thr, duk_bitdecoder_ctx *bd) {\n\tduk_double_union du;\n\tduk_small_uint_t i;\n\n\tfor (i = 0; i < 8; i++) {\n\t\t/* Encoding endianness must match target memory layout,\n\t\t * build scripts and genbuiltins.py must ensure this.\n\t\t */\n\t\tdu.uc[i] = (duk_uint8_t) duk_bd_decode(bd, 8);\n\t}\n\n\tduk_push_number(thr, du.d);  /* push operation normalizes NaNs */\n}\n\nDUK_INTERNAL void duk_hthread_create_builtin_objects(duk_hthread *thr) {\n\tduk_bitdecoder_ctx bd_ctx;\n\tduk_bitdecoder_ctx *bd = &bd_ctx;  /* convenience */\n\tduk_hobject *h;\n\tduk_small_uint_t i, j;\n\n\tDUK_D(DUK_DPRINT(\"INITBUILTINS BEGIN: DUK_NUM_BUILTINS=%d, DUK_NUM_BUILTINS_ALL=%d\", (int) DUK_NUM_BUILTINS, (int) DUK_NUM_ALL_BUILTINS));\n\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tbd->data = (const duk_uint8_t *) duk_builtins_data;\n\tbd->length = (duk_size_t) DUK_BUILTINS_DATA_LENGTH;\n\n\t/*\n\t *  First create all built-in bare objects on the empty valstack.\n\t *\n\t *  Built-ins in the index range [0,DUK_NUM_BUILTINS-1] have value\n\t *  stack indices matching their eventual thr->builtins[] index.\n\t *\n\t *  Built-ins in the index range [DUK_NUM_BUILTINS,DUK_NUM_ALL_BUILTINS]\n\t *  will exist on the value stack during init but won't be placed\n\t *  into thr->builtins[].  These are objects referenced in some way\n\t *  from thr->builtins[] roots but which don't need to be indexed by\n\t *  Duktape through thr->builtins[] (e.g. user custom objects).\n\t *\n\t *  Internal prototypes will be incorrect (NULL) at this stage.\n\t */\n\n\tduk_require_stack(thr, DUK_NUM_ALL_BUILTINS);\n\n\tDUK_DD(DUK_DDPRINT(\"create empty built-ins\"));\n\tDUK_ASSERT_TOP(thr, 0);\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tduk_small_uint_t class_num;\n\t\tduk_small_int_t len = -1;  /* must be signed */\n\n\t\tclass_num = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tlen = (duk_small_int_t) duk_bd_decode_flagged_signed(bd, DUK__LENGTH_PROP_BITS, (duk_int32_t) -1 /*def_value*/);\n\n\t\tif (class_num == DUK_HOBJECT_CLASS_FUNCTION) {\n\t\t\tduk_small_uint_t natidx;\n\t\t\tduk_small_int_t c_nargs;  /* must hold DUK_VARARGS */\n\t\t\tduk_c_function c_func;\n\t\t\tduk_int16_t magic;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"len=%ld\", (long) len));\n\t\t\tDUK_ASSERT(len >= 0);\n\n\t\t\tnatidx = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\tDUK_ASSERT(natidx != 0);\n\t\t\tc_func = duk_bi_native_functions[natidx];\n\t\t\tDUK_ASSERT(c_func != NULL);\n\n\t\t\tc_nargs = (duk_small_int_t) duk_bd_decode_flagged_signed(bd, DUK__NARGS_BITS, len /*def_value*/);\n\t\t\tif (c_nargs == DUK__NARGS_VARARGS_MARKER) {\n\t\t\t\tc_nargs = DUK_VARARGS;\n\t\t\t}\n\n\t\t\t/* XXX: set magic directly here? (it could share the c_nargs arg) */\n\t\t\t(void) duk_push_c_function_builtin(thr, c_func, c_nargs);\n\t\t\th = duk_known_hobject(thr, -1);\n\n\t\t\t/* Currently all built-in native functions are strict.\n\t\t\t * duk_push_c_function() now sets strict flag, so\n\t\t\t * assert for it.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_STRICT(h));\n\n\t\t\t/* XXX: function properties */\n\n\t\t\tduk__push_stridx_or_string(thr, bd);\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\t\t\tduk_xdef_prop_stridx_short(thr,\n\t\t\t                           -2,\n\t\t\t                           DUK_STRIDX_NAME,\n\t\t\t                           DUK_PROPDESC_FLAGS_C);\n#else\n\t\t\tduk_pop(thr);  /* Not very ideal but good enough for now. */\n#endif\n\n\t\t\t/* Almost all global level Function objects are constructable\n\t\t\t * but not all: Function.prototype is a non-constructable,\n\t\t\t * callable Function.\n\t\t\t */\n\t\t\tif (duk_bd_decode_flag(bd)) {\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_CONSTRUCTABLE(h));\n\t\t\t} else {\n\t\t\t\tDUK_HOBJECT_CLEAR_CONSTRUCTABLE(h);\n\t\t\t}\n\n\t\t\t/* Cast converts magic to 16-bit signed value */\n\t\t\tmagic = (duk_int16_t) duk_bd_decode_varuint(bd);\n\t\t\t((duk_hnatfunc *) h)->magic = magic;\n\t\t} else if (class_num == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tduk_push_array(thr);\n\t\t} else if (class_num == DUK_HOBJECT_CLASS_OBJENV) {\n\t\t\tduk_hobjenv *env;\n\t\t\tduk_hobject *global;\n\n\t\t\tDUK_ASSERT(i == DUK_BIDX_GLOBAL_ENV);\n\t\t\tDUK_ASSERT(DUK_BIDX_GLOBAL_ENV > DUK_BIDX_GLOBAL);\n\n\t\t\tenv = duk_hobjenv_alloc(thr,\n\t                                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\t\t\tDUK_ASSERT(env->target == NULL);\n\t\t\tduk_push_hobject(thr, (duk_hobject *) env);\n\n\t\t\tglobal = duk_known_hobject(thr, DUK_BIDX_GLOBAL);\n\t\t\tDUK_ASSERT(global != NULL);\n\t\t\tenv->target = global;\n\t\t\tDUK_HOBJECT_INCREF(thr, global);\n\t\t\tDUK_ASSERT(env->has_this == 0);\n\n\t\t\tDUK_HOBJENV_ASSERT_VALID(env);\n\t\t} else {\n\t\t\tDUK_ASSERT(class_num != DUK_HOBJECT_CLASS_DECENV);\n\n\t\t\t(void) duk_push_object_helper(thr,\n\t\t\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t\t\t                              DUK_HOBJECT_FLAG_EXTENSIBLE,\n\t\t\t                              -1);  /* no prototype or class yet */\n\n\t\t}\n\n\t\th = duk_known_hobject(thr, -1);\n\t\tDUK_HOBJECT_SET_CLASS_NUMBER(h, class_num);\n\n\t\tif (i < DUK_NUM_BUILTINS) {\n\t\t\tthr->builtins[i] = h;\n\t\t\tDUK_HOBJECT_INCREF(thr, &h->hdr);\n\t\t}\n\n\t\tif (len >= 0) {\n\t\t\t/* In ES2015+ built-in function object .length property\n\t\t\t * has property attributes C (configurable only):\n\t\t\t * http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-standard-built-in-objects\n\t\t\t *\n\t\t\t * Array.prototype remains an Array instance in ES2015+\n\t\t\t * and its length has attributes W (writable only).\n\t\t\t * Because .length is now virtual for duk_harray, it is\n\t\t\t * not encoded explicitly in init data.\n\t\t\t */\n\n\t\t\tDUK_ASSERT(class_num != DUK_HOBJECT_CLASS_ARRAY);  /* .length is virtual */\n\t\t\tduk_push_int(thr, len);\n\t\t\tduk_xdef_prop_stridx_short(thr,\n\t\t\t                           -2,\n\t\t\t                           DUK_STRIDX_LENGTH,\n\t\t\t                           DUK_PROPDESC_FLAGS_C);\n\t\t}\n\n\t\t/* enable exotic behaviors last */\n\n\t\tif (class_num == DUK_HOBJECT_CLASS_ARRAY) {\n\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(h));  /* set by duk_push_array() */\n\t\t}\n\t\tif (class_num == DUK_HOBJECT_CLASS_STRING) {\n\t\t\tDUK_HOBJECT_SET_EXOTIC_STRINGOBJ(h);\n\t\t}\n\n\t\t/* some assertions */\n\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h));\n\t\t/* DUK_HOBJECT_FLAG_CONSTRUCTABLE varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_COMPFUNC(h));\n\t\t/* DUK_HOBJECT_FLAG_NATFUNC varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_IS_PROXY(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(h) || class_num == DUK_HOBJECT_CLASS_ARRAY);\n\t\t/* DUK_HOBJECT_FLAG_STRICT varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(h) ||  /* all native functions have NEWENV */\n\t\t           DUK_HOBJECT_HAS_NEWENV(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NAMEBINDING(h));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(h));\n\t\t/* DUK_HOBJECT_FLAG_EXOTIC_ARRAY varies */\n\t\t/* DUK_HOBJECT_FLAG_EXOTIC_STRINGOBJ varies */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(h));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"created built-in %ld, class=%ld, length=%ld\", (long) i, (long) class_num, (long) len));\n\t}\n\n\t/*\n\t *  Then decode the builtins init data (see genbuiltins.py) to\n\t *  init objects.  Internal prototypes are set at this stage,\n\t *  with thr->builtins[] populated.\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"initialize built-in object properties\"));\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tduk_small_uint_t t;\n\t\tduk_small_uint_t num;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"initializing built-in object at index %ld\", (long) i));\n\t\th = duk_known_hobject(thr, (duk_idx_t) i);\n\n\t\tt = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tif (t > 0) {\n\t\t\tt--;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"set internal prototype: built-in %ld\", (long) t));\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, duk_known_hobject(thr, (duk_idx_t) t));\n\t\t} else if (DUK_HOBJECT_IS_NATFUNC(h)) {\n\t\t\t/* Standard native built-ins cannot inherit from\n\t\t\t * %NativeFunctionPrototype%, they are required to\n\t\t\t * inherit from Function.prototype directly.\n\t\t\t */\n\t\t\tDUK_ASSERT(thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE] != NULL);\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\t\t}\n\n\t\tt = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tif (t > 0) {\n\t\t\t/* 'prototype' property for all built-in objects (which have it) has attributes:\n\t\t\t *  [[Writable]] = false,\n\t\t\t *  [[Enumerable]] = false,\n\t\t\t *  [[Configurable]] = false\n\t\t\t */\n\t\t\tt--;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"set external prototype: built-in %ld\", (long) t));\n\t\t\tduk_dup(thr, (duk_idx_t) t);\n\t\t\tduk_xdef_prop_stridx(thr, (duk_idx_t) i, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_NONE);\n\t\t}\n\n\t\tt = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tif (t > 0) {\n\t\t\t/* 'constructor' property for all built-in objects (which have it) has attributes:\n\t\t\t *  [[Writable]] = true,\n\t\t\t *  [[Enumerable]] = false,\n\t\t\t *  [[Configurable]] = true\n\t\t\t */\n\t\t\tt--;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"set external constructor: built-in %ld\", (long) t));\n\t\t\tduk_dup(thr, (duk_idx_t) t);\n\t\t\tduk_xdef_prop_stridx(thr, (duk_idx_t) i, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC);\n\t\t}\n\n\t\t/* normal valued properties */\n\t\tnum = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tDUK_DDD(DUK_DDDPRINT(\"built-in object %ld, %ld normal valued properties\", (long) i, (long) num));\n\t\tfor (j = 0; j < num; j++) {\n\t\t\tduk_small_uint_t defprop_flags;\n\n\t\t\tduk__push_stridx_or_string(thr, bd);\n\n\t\t\t/*\n\t\t\t *  Property attribute defaults are defined in E5 Section 15 (first\n\t\t\t *  few pages); there is a default for all properties and a special\n\t\t\t *  default for 'length' properties.  Variation from the defaults is\n\t\t\t *  signaled using a single flag bit in the bitstream.\n\t\t\t */\n\n\t\t\tdefprop_flags = (duk_small_uint_t) duk_bd_decode_flagged(bd,\n\t\t\t                                                         DUK__PROP_FLAGS_BITS,\n\t\t\t                                                         (duk_uint32_t) DUK_PROPDESC_FLAGS_WC);\n\t\t\tdefprop_flags |= DUK_DEFPROP_FORCE |\n\t\t\t                 DUK_DEFPROP_HAVE_VALUE |\n\t\t\t                 DUK_DEFPROP_HAVE_WRITABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_ENUMERABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_CONFIGURABLE;  /* Defaults for data properties. */\n\n\t\t\t/* The writable, enumerable, configurable flags in prop_flags\n\t\t\t * match both duk_def_prop() and internal property flags.\n\t\t\t */\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_WRITABLE == DUK_DEFPROP_WRITABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_ENUMERABLE == DUK_DEFPROP_ENUMERABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_CONFIGURABLE == DUK_DEFPROP_CONFIGURABLE);\n\n\t\t\tt = (duk_small_uint_t) duk_bd_decode(bd, DUK__PROP_TYPE_BITS);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"built-in %ld, normal-valued property %ld, key %!T, flags 0x%02lx, type %ld\",\n\t\t\t                     (long) i, (long) j, duk_get_tval(thr, -1), (unsigned long) defprop_flags, (long) t));\n\n\t\t\tswitch (t) {\n\t\t\tcase DUK__PROP_TYPE_DOUBLE: {\n\t\t\t\tduk__push_double(thr, bd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_STRING: {\n\t\t\t\tduk__push_string(thr, bd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_STRIDX: {\n\t\t\t\tduk__push_stridx(thr, bd);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_BUILTIN: {\n\t\t\t\tduk_small_uint_t bidx;\n\n\t\t\t\tbidx = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_dup(thr, (duk_idx_t) bidx);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_UNDEFINED: {\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_BOOLEAN_TRUE: {\n\t\t\t\tduk_push_true(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_BOOLEAN_FALSE: {\n\t\t\t\tduk_push_false(thr);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase DUK__PROP_TYPE_ACCESSOR: {\n\t\t\t\tduk_small_uint_t natidx_getter = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_small_uint_t natidx_setter = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_small_uint_t accessor_magic = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\t\t\tduk_c_function c_func_getter;\n\t\t\t\tduk_c_function c_func_setter;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"built-in accessor property: objidx=%ld, key=%!T, getteridx=%ld, setteridx=%ld, flags=0x%04lx\",\n\t\t\t\t                     (long) i, duk_get_tval(thr, -1), (long) natidx_getter, (long) natidx_setter, (unsigned long) defprop_flags));\n\n\t\t\t\tc_func_getter = duk_bi_native_functions[natidx_getter];\n\t\t\t\tif (c_func_getter != NULL) {\n\t\t\t\t\tduk_push_c_function_builtin_noconstruct(thr, c_func_getter, 0);  /* always 0 args */\n\t\t\t\t\tduk_set_magic(thr, -1, (duk_int_t) accessor_magic);\n\t\t\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_GETTER;\n\t\t\t\t}\n\t\t\t\tc_func_setter = duk_bi_native_functions[natidx_setter];\n\t\t\t\tif (c_func_setter != NULL) {\n\t\t\t\t\tduk_push_c_function_builtin_noconstruct(thr, c_func_setter, 1);  /* always 1 arg */\n\t\t\t\t\tduk_set_magic(thr, -1, (duk_int_t) accessor_magic);\n\t\t\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_SETTER;\n\t\t\t\t}\n\n\t\t\t\t/* Writable flag doesn't make sense for an accessor. */\n\t\t\t\tDUK_ASSERT((defprop_flags & DUK_PROPDESC_FLAG_WRITABLE) == 0);  /* genbuiltins.py ensures */\n\n\t\t\t\tdefprop_flags &= ~(DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_HAVE_WRITABLE);\n\t\t\t\tdefprop_flags |= DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t/* exhaustive */\n\t\t\t\tDUK_UNREACHABLE();\n\t\t\t}\n\t\t\t}\n\n\t\t\tduk_def_prop(thr, (duk_idx_t) i, defprop_flags);\n\t\t\tDUK_ASSERT_TOP(thr, DUK_NUM_ALL_BUILTINS);\n\t\t}\n\n\t\t/* native function properties */\n\t\tnum = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\t\tDUK_DDD(DUK_DDDPRINT(\"built-in object %ld, %ld function valued properties\", (long) i, (long) num));\n\t\tfor (j = 0; j < num; j++) {\n\t\t\tduk_hstring *h_key;\n\t\t\tduk_small_uint_t natidx;\n\t\t\tduk_int_t c_nargs;  /* must hold DUK_VARARGS */\n\t\t\tduk_small_uint_t c_length;\n\t\t\tduk_int16_t magic;\n\t\t\tduk_c_function c_func;\n\t\t\tduk_hnatfunc *h_func;\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t\tduk_small_int_t lightfunc_eligible;\n#endif\n\t\t\tduk_small_uint_t defprop_flags;\n\n\t\t\tduk__push_stridx_or_string(thr, bd);\n\t\t\th_key = duk_known_hstring(thr, -1);\n\t\t\tDUK_UNREF(h_key);\n\t\t\tnatidx = (duk_small_uint_t) duk_bd_decode_varuint(bd);\n\n\t\t\tc_length = (duk_small_uint_t) duk_bd_decode(bd, DUK__LENGTH_PROP_BITS);\n\t\t\tc_nargs = (duk_int_t) duk_bd_decode_flagged(bd, DUK__NARGS_BITS, (duk_uint32_t) c_length /*def_value*/);\n\t\t\tif (c_nargs == DUK__NARGS_VARARGS_MARKER) {\n\t\t\t\tc_nargs = DUK_VARARGS;\n\t\t\t}\n\n\t\t\tc_func = duk_bi_native_functions[natidx];\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"built-in %ld, function-valued property %ld, key %!O, natidx %ld, length %ld, nargs %ld\",\n\t\t\t                     (long) i, (long) j, (duk_heaphdr *) h_key, (long) natidx, (long) c_length,\n\t\t\t                     (c_nargs == DUK_VARARGS ? (long) -1 : (long) c_nargs)));\n\n\t\t\t/* Cast converts magic to 16-bit signed value */\n\t\t\tmagic = (duk_int16_t) duk_bd_decode_varuint(bd);\n\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t\tlightfunc_eligible =\n\t\t\t\t((c_nargs >= DUK_LFUNC_NARGS_MIN && c_nargs <= DUK_LFUNC_NARGS_MAX) || (c_nargs == DUK_VARARGS)) &&\n\t\t\t\t(c_length <= DUK_LFUNC_LENGTH_MAX) &&\n\t\t\t\t(magic >= DUK_LFUNC_MAGIC_MIN && magic <= DUK_LFUNC_MAGIC_MAX);\n\n\t\t\t/* These functions have trouble working as lightfuncs.\n\t\t\t * Some of them have specific asserts and some may have\n\t\t         * additional properties (e.g. 'require.id' may be written).\n\t\t\t */\n\t\t\tif (c_func == duk_bi_global_object_eval) {\n\t\t\t\tlightfunc_eligible = 0;\n\t\t\t}\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\t\t\tif (c_func == duk_bi_thread_yield ||\n\t\t\t    c_func == duk_bi_thread_resume) {\n\t\t\t\tlightfunc_eligible = 0;\n\t\t\t}\n#endif\n\t\t\tif (c_func == duk_bi_function_prototype_call ||\n\t\t\t    c_func == duk_bi_function_prototype_apply ||\n\t\t\t    c_func == duk_bi_reflect_apply ||\n\t\t\t    c_func == duk_bi_reflect_construct) {\n\t\t\t\tlightfunc_eligible = 0;\n\t\t\t}\n\n\t\t\tif (lightfunc_eligible) {\n\t\t\t\tduk_tval tv_lfunc;\n\t\t\t\tduk_small_uint_t lf_nargs = (duk_small_uint_t) (c_nargs == DUK_VARARGS ? DUK_LFUNC_NARGS_VARARGS : c_nargs);\n\t\t\t\tduk_small_uint_t lf_flags = DUK_LFUNC_FLAGS_PACK(magic, c_length, lf_nargs);\n\t\t\t\tDUK_TVAL_SET_LIGHTFUNC(&tv_lfunc, c_func, lf_flags);\n\t\t\t\tduk_push_tval(thr, &tv_lfunc);\n\t\t\t\tDUK_D(DUK_DPRINT(\"built-in function eligible as light function: i=%d, j=%d c_length=%ld, c_nargs=%ld, magic=%ld -> %!iT\", (int) i, (int) j, (long) c_length, (long) c_nargs, (long) magic, duk_get_tval(thr, -1)));\n\t\t\t\tgoto lightfunc_skip;\n\t\t\t}\n\n\t\t\tDUK_D(DUK_DPRINT(\"built-in function NOT ELIGIBLE as light function: i=%d, j=%d c_length=%ld, c_nargs=%ld, magic=%ld\", (int) i, (int) j, (long) c_length, (long) c_nargs, (long) magic));\n#endif  /* DUK_USE_LIGHTFUNC_BUILTINS */\n\n\t\t\t/* [ (builtin objects) name ] */\n\n\t\t\tduk_push_c_function_builtin_noconstruct(thr, c_func, c_nargs);\n\t\t\th_func = duk_known_hnatfunc(thr, -1);\n\t\t\tDUK_UNREF(h_func);\n\n\t\t\t/* XXX: add into init data? */\n\n\t\t\t/* Special call handling, not described in init data. */\n\t\t\tif (c_func == duk_bi_global_object_eval ||\n\t\t\t    c_func == duk_bi_function_prototype_call ||\n\t\t\t    c_func == duk_bi_function_prototype_apply ||\n\t\t\t    c_func == duk_bi_reflect_apply ||\n\t\t\t    c_func == duk_bi_reflect_construct) {\n\t\t\t\tDUK_HOBJECT_SET_SPECIAL_CALL((duk_hobject *) h_func);\n\t\t\t}\n\n\t\t\t/* Currently all built-in native functions are strict.\n\t\t\t * This doesn't matter for many functions, but e.g.\n\t\t\t * String.prototype.charAt (and other string functions)\n\t\t\t * rely on being strict so that their 'this' binding is\n\t\t\t * not automatically coerced.\n\t\t\t */\n\t\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_func);\n\n\t\t\t/* No built-in functions are constructable except the top\n\t\t\t * level ones (Number, etc).\n\t\t\t */\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CONSTRUCTABLE((duk_hobject *) h_func));\n\n\t\t\t/* XXX: any way to avoid decoding magic bit; there are quite\n\t\t\t * many function properties and relatively few with magic values.\n\t\t\t */\n\t\t\th_func->magic = magic;\n\n\t\t\t/* [ (builtin objects) name func ] */\n\n\t\t\tduk_push_uint(thr, c_length);\n\t\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);\n\n\t\t\tduk_dup_m2(thr);\n\t\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);\n\n\t\t\t/* XXX: other properties of function instances; 'arguments', 'caller'. */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"built-in object %ld, function property %ld -> %!T\",\n\t\t\t                   (long) i, (long) j, (duk_tval *) duk_get_tval(thr, -1)));\n\n\t\t\t/* [ (builtin objects) name func ] */\n\n\t\t\t/*\n\t\t\t *  The default property attributes are correct for all\n\t\t\t *  function valued properties of built-in objects now.\n\t\t\t */\n\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t lightfunc_skip:\n#endif\n\n\t\t\tdefprop_flags = (duk_small_uint_t) duk_bd_decode_flagged(bd,\n\t\t\t                                                         DUK__PROP_FLAGS_BITS,\n\t\t\t                                                         (duk_uint32_t) DUK_PROPDESC_FLAGS_WC);\n\t\t\tdefprop_flags |= DUK_DEFPROP_FORCE |\n\t\t\t                 DUK_DEFPROP_HAVE_VALUE |\n\t\t\t                 DUK_DEFPROP_HAVE_WRITABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_ENUMERABLE |\n\t\t\t                 DUK_DEFPROP_HAVE_CONFIGURABLE;\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_WRITABLE == DUK_DEFPROP_WRITABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_ENUMERABLE == DUK_DEFPROP_ENUMERABLE);\n\t\t\tDUK_ASSERT(DUK_PROPDESC_FLAG_CONFIGURABLE == DUK_DEFPROP_CONFIGURABLE);\n\n\t\t\tduk_def_prop(thr, (duk_idx_t) i, defprop_flags);\n\n\t\t\t/* [ (builtin objects) ] */\n\t\t}\n\t}\n\n\t/*\n\t *  Special post-tweaks, for cases not covered by the init data format.\n\t *\n\t *  - Set Date.prototype.toGMTString to Date.prototype.toUTCString.\n\t *    toGMTString is required to have the same Function object as\n\t *    toUTCString in E5 Section B.2.6.  Note that while Smjs respects\n\t *    this, V8 does not (the Function objects are distinct).\n\t *\n\t *  - Make DoubleError non-extensible.\n\t *\n\t *  - Add info about most important effective compile options to Duktape.\n\t *\n\t *  - Possibly remove some properties (values or methods) which are not\n\t *    desirable with current feature options but are not currently\n\t *    conditional in init data.\n\t */\n\n#if defined(DUK_USE_DATE_BUILTIN)\n\tduk_get_prop_stridx_short(thr, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_UTC_STRING);\n\tduk_xdef_prop_stridx_short(thr, DUK_BIDX_DATE_PROTOTYPE, DUK_STRIDX_TO_GMT_STRING, DUK_PROPDESC_FLAGS_WC);\n#endif\n\n\th = duk_known_hobject(thr, DUK_BIDX_DOUBLE_ERROR);\n\tDUK_HOBJECT_CLEAR_EXTENSIBLE(h);\n\n#if !defined(DUK_USE_ES6_OBJECT_PROTO_PROPERTY)\n\tDUK_DD(DUK_DDPRINT(\"delete Object.prototype.__proto__ built-in which is not enabled in features\"));\n\t(void) duk_hobject_delprop_raw(thr, thr->builtins[DUK_BIDX_OBJECT_PROTOTYPE], DUK_HTHREAD_STRING___PROTO__(thr), DUK_DELPROP_FLAG_THROW);\n#endif\n\n#if !defined(DUK_USE_ES6_OBJECT_SETPROTOTYPEOF)\n\tDUK_DD(DUK_DDPRINT(\"delete Object.setPrototypeOf built-in which is not enabled in features\"));\n\t(void) duk_hobject_delprop_raw(thr, thr->builtins[DUK_BIDX_OBJECT_CONSTRUCTOR], DUK_HTHREAD_STRING_SET_PROTOTYPE_OF(thr), DUK_DELPROP_FLAG_THROW);\n#endif\n\n\t/* XXX: relocate */\n\tduk_push_string(thr,\n\t\t\t/* Endianness indicator */\n#if defined(DUK_USE_INTEGER_LE)\n\t                \"l\"\n#elif defined(DUK_USE_INTEGER_BE)\n\t                \"b\"\n#elif defined(DUK_USE_INTEGER_ME)  /* integer mixed endian not really used now */\n\t                \"m\"\n#else\n\t                \"?\"\n#endif\n#if defined(DUK_USE_DOUBLE_LE)\n\t                \"l\"\n#elif defined(DUK_USE_DOUBLE_BE)\n\t                \"b\"\n#elif defined(DUK_USE_DOUBLE_ME)\n\t                \"m\"\n#else\n\t                \"?\"\n#endif\n\t                \" \"\n\t\t\t/* Packed or unpacked tval */\n#if defined(DUK_USE_PACKED_TVAL)\n\t                \"p\"\n#else\n\t                \"u\"\n#endif\n#if defined(DUK_USE_FASTINT)\n\t\t\t\"f\"\n#endif\n\t\t\t\" \"\n\t\t\t/* Low memory/performance options */\n#if defined(DUK_USE_STRTAB_PTRCOMP)\n\t\t\t\"s\"\n#endif\n#if !defined(DUK_USE_HEAPPTR16) && !defined(DUK_DATAPTR16) && !defined(DUK_FUNCPTR16)\n\t\t\t\"n\"\n#endif\n#if defined(DUK_USE_HEAPPTR16)\n\t\t\t\"h\"\n#endif\n#if defined(DUK_USE_DATAPTR16)\n\t\t\t\"d\"\n#endif\n#if defined(DUK_USE_FUNCPTR16)\n\t\t\t\"f\"\n#endif\n#if defined(DUK_USE_REFCOUNT16)\n\t\t\t\"R\"\n#endif\n#if defined(DUK_USE_STRHASH16)\n\t\t\t\"H\"\n#endif\n#if defined(DUK_USE_STRLEN16)\n\t\t\t\"S\"\n#endif\n#if defined(DUK_USE_BUFLEN16)\n\t\t\t\"B\"\n#endif\n#if defined(DUK_USE_OBJSIZES16)\n\t\t\t\"O\"\n#endif\n#if defined(DUK_USE_LIGHTFUNC_BUILTINS)\n\t\t\t\"L\"\n#endif\n#if defined(DUK_USE_ROM_STRINGS) || defined(DUK_USE_ROM_OBJECTS)\n\t\t\t/* XXX: This won't be shown in practice now\n\t\t\t * because this code is not run when builtins\n\t\t\t * are in ROM.\n\t\t\t */\n\t\t\t\"Z\"\n#endif\n#if defined(DUK_USE_LITCACHE_SIZE)\n\t\t\t\"l\"\n#endif\n\t                \" \"\n\t\t\t/* Object property allocation layout */\n#if defined(DUK_USE_HOBJECT_LAYOUT_1)\n\t\t\t\"p1\"\n#elif defined(DUK_USE_HOBJECT_LAYOUT_2)\n\t\t\t\"p2\"\n#elif defined(DUK_USE_HOBJECT_LAYOUT_3)\n\t\t\t\"p3\"\n#else\n\t\t\t\"p?\"\n#endif\n\t\t\t\" \"\n\t\t\t/* Alignment guarantee */\n#if (DUK_USE_ALIGN_BY == 4)\n\t\t\t\"a4\"\n#elif (DUK_USE_ALIGN_BY == 8)\n\t\t\t\"a8\"\n#elif (DUK_USE_ALIGN_BY == 1)\n\t\t\t\"a1\"\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\t\t\t\" \"\n\t\t\t/* Architecture, OS, and compiler strings */\n\t                DUK_USE_ARCH_STRING\n\t\t\t\" \"\n\t                DUK_USE_OS_STRING\n\t\t\t\" \"\n\t                DUK_USE_COMPILER_STRING);\n\tduk_xdef_prop_stridx_short(thr, DUK_BIDX_DUKTAPE, DUK_STRIDX_ENV, DUK_PROPDESC_FLAGS_WC);\n\n\t/*\n\t *  Since built-ins are not often extended, compact them.\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"compact built-ins\"));\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tduk_hobject_compact_props(thr, duk_known_hobject(thr, (duk_idx_t) i));\n\t}\n\n\tDUK_D(DUK_DPRINT(\"INITBUILTINS END\"));\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 1)\n\tfor (i = 0; i < DUK_NUM_ALL_BUILTINS; i++) {\n\t\tDUK_DD(DUK_DDPRINT(\"built-in object %ld after initialization and compacting: %!@iO\",\n\t\t                   (long) i, (duk_heaphdr *) duk_require_hobject(thr, (duk_idx_t) i)));\n\t}\n#endif\n\n\t/*\n\t *  Pop built-ins from stack: they are now INCREF'd and\n\t *  reachable from the builtins[] array or indirectly\n\t *  through builtins[].\n\t */\n\n\tduk_set_top(thr, 0);\n\tDUK_ASSERT_TOP(thr, 0);\n}\n#endif  /* DUK_USE_ROM_OBJECTS */\n\nDUK_INTERNAL void duk_hthread_copy_builtin_objects(duk_hthread *thr_from, duk_hthread *thr_to) {\n\tduk_small_uint_t i;\n\n\tfor (i = 0; i < DUK_NUM_BUILTINS; i++) {\n\t\tthr_to->builtins[i] = thr_from->builtins[i];\n\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr_to, thr_to->builtins[i]);  /* side effect free */\n\t}\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hthread_misc.c",
    "content": "/*\n *  Thread support.\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL void duk_hthread_terminate(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\twhile (thr->callstack_curr != NULL) {\n\t\tduk_hthread_activation_unwind_norz(thr);\n\t}\n\n\tthr->valstack_bottom = thr->valstack;\n\tduk_set_top(thr, 0);  /* unwinds valstack, updating refcounts */\n\n\tthr->state = DUK_HTHREAD_STATE_TERMINATED;\n\n\t/* Here we could remove references to built-ins, but it may not be\n\t * worth the effort because built-ins are quite likely to be shared\n\t * with another (unterminated) thread, and terminated threads are also\n\t * usually garbage collected quite quickly.\n\t *\n\t * We could also shrink the value stack here, but that also may not\n\t * be worth the effort for the same reason.\n\t */\n\n\tDUK_REFZERO_CHECK_SLOW(thr);\n}\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_curr_pc(duk_hthread *thr, duk_activation *act) {\n\tduk_instr_t *bcode;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_UNREF(thr);\n\n\t/* XXX: store 'bcode' pointer to activation for faster lookup? */\n\tif (act->func && DUK_HOBJECT_IS_COMPFUNC(act->func)) {\n\t\tbcode = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) (act->func));\n\t\treturn (duk_uint_fast32_t) (act->curr_pc - bcode);\n\t}\n\treturn 0;\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\nDUK_INTERNAL duk_uint_fast32_t duk_hthread_get_act_prev_pc(duk_hthread *thr, duk_activation *act) {\n\tduk_instr_t *bcode;\n\tduk_uint_fast32_t ret;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_UNREF(thr);\n\n\tif (act->func && DUK_HOBJECT_IS_COMPFUNC(act->func)) {\n\t\tbcode = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) (act->func));\n\t\tret = (duk_uint_fast32_t) (act->curr_pc - bcode);\n\t\tif (ret > 0) {\n\t\t\tret--;\n\t\t}\n\t\treturn ret;\n\t}\n\treturn 0;\n}\n\n/* Write bytecode executor's curr_pc back to topmost activation (if any). */\nDUK_INTERNAL void duk_hthread_sync_currpc(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tif (thr->ptr_curr_pc != NULL) {\n\t\t/* ptr_curr_pc != NULL only when bytecode executor is active. */\n\t\tDUK_ASSERT(thr->callstack_top > 0);\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tact = thr->callstack_curr;\n\t\tDUK_ASSERT(act != NULL);\n\t\tact->curr_pc = *thr->ptr_curr_pc;\n\t}\n}\n\nDUK_INTERNAL void duk_hthread_sync_and_null_currpc(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tif (thr->ptr_curr_pc != NULL) {\n\t\t/* ptr_curr_pc != NULL only when bytecode executor is active. */\n\t\tDUK_ASSERT(thr->callstack_top > 0);\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tact = thr->callstack_curr;\n\t\tDUK_ASSERT(act != NULL);\n\t\tact->curr_pc = *thr->ptr_curr_pc;\n\t\tthr->ptr_curr_pc = NULL;\n\t}\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_hthread_stacks.c",
    "content": "/*\n *  Thread stack (mainly call stack) primitives: allocation of activations,\n *  unwinding catchers and activations, etc.\n *\n *  Value stack handling is a part of the API implementation.\n */\n\n#include \"duk_internal.h\"\n\n/* Unwind the topmost catcher of the current activation (caller must check that\n * both exist) without side effects.\n */\nDUK_INTERNAL void duk_hthread_catcher_unwind_norz(duk_hthread *thr, duk_activation *act) {\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(act->cat != NULL);  /* caller must check */\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"unwinding catch stack entry %p (lexenv check is done)\", (void *) cat));\n\n\tif (DUK_CAT_HAS_LEXENV_ACTIVE(cat)) {\n\t\tduk_hobject *env;\n\n\t\tenv = act->lex_env;             /* current lex_env of the activation (created for catcher) */\n\t\tDUK_ASSERT(env != NULL);        /* must be, since env was created when catcher was created */\n\t\tact->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, env);  /* prototype is lex_env before catcher created */\n\t\tDUK_HOBJECT_INCREF(thr, act->lex_env);\n\t\tDUK_HOBJECT_DECREF_NORZ(thr, env);\n\n\t\t/* There is no need to decref anything else than 'env': if 'env'\n\t\t * becomes unreachable, refzero will handle decref'ing its prototype.\n\t\t */\n\t}\n\n\tact->cat = cat->parent;\n\tduk_hthread_catcher_free(thr, cat);\n}\n\n/* Same as above, but caller is certain no catcher-related lexenv may exist. */\nDUK_INTERNAL void duk_hthread_catcher_unwind_nolexenv_norz(duk_hthread *thr, duk_activation *act) {\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(act->cat != NULL);  /* caller must check */\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tDUK_DDD(DUK_DDDPRINT(\"unwinding catch stack entry %p (lexenv check is not done)\", (void *) cat));\n\n\tDUK_ASSERT(!DUK_CAT_HAS_LEXENV_ACTIVE(cat));\n\n\tact->cat = cat->parent;\n\tduk_hthread_catcher_free(thr, cat);\n}\n\nDUK_LOCAL\n#if defined(DUK_USE_CACHE_CATCHER)\nDUK_NOINLINE\n#endif\nduk_catcher *duk__hthread_catcher_alloc_slow(duk_hthread *thr) {\n\tduk_catcher *cat;\n\n\tcat = (duk_catcher *) DUK_ALLOC_CHECKED(thr, sizeof(duk_catcher));\n\tDUK_ASSERT(cat != NULL);\n\treturn cat;\n}\n\n#if defined(DUK_USE_CACHE_CATCHER)\nDUK_INTERNAL DUK_INLINE duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr) {\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tcat = thr->heap->catcher_free;\n\tif (DUK_LIKELY(cat != NULL)) {\n\t\tthr->heap->catcher_free = cat->parent;\n\t\treturn cat;\n\t}\n\n\treturn duk__hthread_catcher_alloc_slow(thr);\n}\n#else  /* DUK_USE_CACHE_CATCHER */\nDUK_INTERNAL duk_catcher *duk_hthread_catcher_alloc(duk_hthread *thr) {\n\treturn duk__hthread_catcher_alloc_slow(thr);\n}\n#endif  /* DUK_USE_CACHE_CATCHER */\n\nDUK_INTERNAL void duk_hthread_catcher_free(duk_hthread *thr, duk_catcher *cat) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(cat != NULL);\n\n#if defined(DUK_USE_CACHE_CATCHER)\n\t/* Unconditional caching for now; freed in mark-and-sweep. */\n\tcat->parent = thr->heap->catcher_free;\n\tthr->heap->catcher_free = cat;\n#else\n\tDUK_FREE_CHECKED(thr, (void *) cat);\n#endif\n}\n\nDUK_LOCAL\n#if defined(DUK_USE_CACHE_ACTIVATION)\nDUK_NOINLINE\n#endif\nduk_activation *duk__hthread_activation_alloc_slow(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tact = (duk_activation *) DUK_ALLOC_CHECKED(thr, sizeof(duk_activation));\n\tDUK_ASSERT(act != NULL);\n\treturn act;\n}\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\nDUK_INTERNAL DUK_INLINE duk_activation *duk_hthread_activation_alloc(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tact = thr->heap->activation_free;\n\tif (DUK_LIKELY(act != NULL)) {\n\t\tthr->heap->activation_free = act->parent;\n\t\treturn act;\n\t}\n\n\treturn duk__hthread_activation_alloc_slow(thr);\n}\n#else  /* DUK_USE_CACHE_ACTIVATION */\nDUK_INTERNAL duk_activation *duk_hthread_activation_alloc(duk_hthread *thr) {\n\treturn duk__hthread_activation_alloc_slow(thr);\n}\n#endif  /* DUK_USE_CACHE_ACTIVATION */\n\n\nDUK_INTERNAL void duk_hthread_activation_free(duk_hthread *thr, duk_activation *act) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\n#if defined(DUK_USE_CACHE_ACTIVATION)\n\t/* Unconditional caching for now; freed in mark-and-sweep. */\n\tact->parent = thr->heap->activation_free;\n\tthr->heap->activation_free = act;\n#else\n\tDUK_FREE_CHECKED(thr, (void *) act);\n#endif\n}\n\n/* Internal helper: process the unwind for the topmost activation of a thread,\n * but leave the duk_activation in place for possible tailcall reuse.\n */\nDUK_LOCAL void duk__activation_unwind_nofree_norz(duk_hthread *thr) {\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_heap *heap;\n#endif\n\tduk_activation *act;\n\tduk_hobject *func;\n\tduk_hobject *tmp;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->callstack_curr != NULL);  /* caller must check */\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\t/* With lightfuncs, act 'func' may be NULL. */\n\n\t/* With duk_activation records allocated separately, 'act' is a stable\n\t * pointer and not affected by side effects.\n\t */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t/*\n\t *  Restore 'caller' property for non-strict callee functions.\n\t */\n\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tif (func != NULL && !DUK_HOBJECT_HAS_STRICT(func)) {\n\t\tduk_tval *tv_caller;\n\t\tduk_tval tv_tmp;\n\t\tduk_hobject *h_tmp;\n\n\t\ttv_caller = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, func, DUK_STRIDX_CALLER);\n\n\t\t/* The act->prev_caller should only be set if the entry for 'caller'\n\t\t * exists (as it is only set in that case, and the property is not\n\t\t * configurable), but handle all the cases anyway.\n\t\t */\n\n\t\tif (tv_caller) {\n\t\t\tDUK_TVAL_SET_TVAL(&tv_tmp, tv_caller);\n\t\t\tif (act->prev_caller) {\n\t\t\t\t/* Just transfer the refcount from act->prev_caller to tv_caller,\n\t\t\t\t * so no need for a refcount update.  This is the expected case.\n\t\t\t\t */\n\t\t\t\tDUK_TVAL_SET_OBJECT(tv_caller, act->prev_caller);\n\t\t\t\tact->prev_caller = NULL;\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_NULL(tv_caller);   /* no incref needed */\n\t\t\t\tDUK_ASSERT(act->prev_caller == NULL);\n\t\t\t}\n\t\t\tDUK_TVAL_DECREF_NORZ(thr, &tv_tmp);\n\t\t} else {\n\t\t\th_tmp = act->prev_caller;\n\t\t\tif (h_tmp) {\n\t\t\t\tact->prev_caller = NULL;\n\t\t\t\tDUK_HOBJECT_DECREF_NORZ(thr, h_tmp);\n\t\t\t}\n\t\t}\n\t\tDUK_ASSERT(act->prev_caller == NULL);\n\t}\n#endif\n\n\t/*\n\t *  Unwind debugger state.  If we unwind while stepping\n\t *  (for any step type), pause execution.  This is the\n\t *  only place explicitly handling a step out.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\theap = thr->heap;\n\tif (heap->dbg_pause_act == thr->callstack_curr) {\n\t\tif (heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_EXIT) {\n\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by function exit\"));\n\t\t\tduk_debug_set_paused(heap);\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"unwound past dbg_pause_act, set to NULL\"));\n\t\t\theap->dbg_pause_act = NULL;  /* avoid stale pointers */\n\t\t}\n\t\tDUK_ASSERT(heap->dbg_pause_act == NULL);\n\t}\n#endif\n\n\t/*\n\t *  Unwind catchers.\n\t *\n\t *  Since there are no references in the catcher structure,\n\t *  unwinding is quite simple.  The only thing we need to\n\t *  look out for is popping a possible lexical environment\n\t *  established for an active catch clause.\n\t */\n\n\twhile (act->cat != NULL) {\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t}\n\n\t/*\n\t *  Close environment record(s) if they exist.\n\t *\n\t *  Only variable environments are closed.  If lex_env != var_env, it\n\t *  cannot currently contain any register bound declarations.\n\t *\n\t *  Only environments created for a NEWENV function are closed.  If an\n\t *  environment is created for e.g. an eval call, it must not be closed.\n\t */\n\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tif (func != NULL && !DUK_HOBJECT_HAS_NEWENV(func)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"skip closing environments, envs not owned by this activation\"));\n\t\tgoto skip_env_close;\n\t}\n\t/* func is NULL for lightfunc */\n\n\t/* Catch sites are required to clean up their environments\n\t * in FINALLY part before propagating, so this should\n\t * always hold here.\n\t */\n\tDUK_ASSERT(act->lex_env == act->var_env);\n\n\t/* XXX: Closing the environment record copies values from registers\n\t * into the scope object.  It's side effect free as such, but may\n\t * currently run out of memory which causes an error throw.  This is\n\t * an actual sandboxing problem for error unwinds, and needs to be\n\t * fixed e.g. by preallocating the scope property slots.\n\t */\n\tif (act->var_env != NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"closing var_env record %p -> %!O\",\n\t\t                     (void *) act->var_env, (duk_heaphdr *) act->var_env));\n\t\tduk_js_close_environment_record(thr, act->var_env);\n\t}\n\n skip_env_close:\n\n\t/*\n\t *  Update preventcount\n\t */\n\n\tif (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) {\n\t\tDUK_ASSERT(thr->callstack_preventcount >= 1);\n\t\tthr->callstack_preventcount--;\n\t}\n\n\t/*\n\t *  Reference count updates, using NORZ macros so we don't\n\t *  need to handle side effects.\n\t *\n\t *  duk_activation pointers like act->var_env are intentionally\n\t *  left as garbage and not NULLed.  Without side effects they\n\t *  can't be used when the values are dangling/garbage.\n\t */\n\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, act->var_env);\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, act->lex_env);\n\ttmp = DUK_ACT_GET_FUNC(act);\n\tDUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr, tmp);\n\tDUK_UNREF(tmp);\n}\n\n/* Unwind topmost duk_activation of a thread, caller must ensure that an\n * activation exists.  The call is side effect free, except that scope\n * closure may currently throw an out-of-memory error.\n */\nDUK_INTERNAL void duk_hthread_activation_unwind_norz(duk_hthread *thr) {\n\tduk_activation *act;\n\n\tduk__activation_unwind_nofree_norz(thr);\n\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tact = thr->callstack_curr;\n\tthr->callstack_curr = act->parent;\n\tthr->callstack_top--;\n\n\t/* Ideally we'd restore value stack reserve here to caller's value.\n\t * This doesn't work for current unwind call sites however, because\n\t * the current (unwound) value stack top may be above the reserve.\n\t * Thus value stack reserve is restored by the call sites.\n\t */\n\n\t/* XXX: inline for performance builds? */\n\tduk_hthread_activation_free(thr, act);\n\n\t/* We could clear the book-keeping variables like retval_byteoff for\n\t * the topmost activation, but don't do so now as it's not necessary.\n\t */\n}\n\nDUK_INTERNAL void duk_hthread_activation_unwind_reuse_norz(duk_hthread *thr) {\n\tduk__activation_unwind_nofree_norz(thr);\n}\n\n/* Get duk_activation for given callstack level or NULL if level is invalid\n * or deeper than the call stack.  Level -1 refers to current activation, -2\n * to its caller, etc.  Starting from Duktape 2.2 finding the activation is\n * a linked list scan which gets more expensive the deeper the lookup is.\n */\nDUK_INTERNAL duk_activation *duk_hthread_get_activation_for_level(duk_hthread *thr, duk_int_t level) {\n\tduk_activation *act;\n\n\tif (level >= 0) {\n\t\treturn NULL;\n\t}\n\tact = thr->callstack_curr;\n\tfor (;;) {\n\t\tif (act == NULL) {\n\t\t\treturn act;\n\t\t}\n\t\tif (level == -1) {\n\t\t\treturn act;\n\t\t}\n\t\tlevel++;\n\t\tact = act->parent;\n\t}\n\t/* never here */\n}\n\n#if defined(DUK_USE_FINALIZER_TORTURE)\nDUK_INTERNAL void duk_hthread_valstack_torture_realloc(duk_hthread *thr) {\n\tduk_size_t alloc_size;\n\tduk_tval *new_ptr;\n\tduk_ptrdiff_t alloc_end_off;\n\tduk_ptrdiff_t end_off;\n\tduk_ptrdiff_t bottom_off;\n\tduk_ptrdiff_t top_off;\n\n\tif (thr->valstack == NULL) {\n\t\tDUK_D(DUK_DPRINT(\"skip valstack torture realloc, valstack is NULL\"));\n\t\treturn;\n\t}\n\n\talloc_end_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_alloc_end - (duk_uint8_t *) thr->valstack);\n\tend_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tbottom_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);\n\ttop_off = (duk_ptrdiff_t) ((duk_uint8_t *) thr->valstack_top - (duk_uint8_t *) thr->valstack);\n\talloc_size = (duk_size_t) alloc_end_off;\n\tif (alloc_size == 0) {\n\t\tDUK_D(DUK_DPRINT(\"skip valstack torture realloc, alloc_size is zero\"));\n\t\treturn;\n\t}\n\n\t/* Use DUK_ALLOC_RAW() to avoid side effects. */\n\tnew_ptr = (duk_tval *) DUK_ALLOC_RAW(thr->heap, alloc_size);\n\tif (new_ptr != NULL) {\n\t\tduk_memcpy((void *) new_ptr, (const void *) thr->valstack, alloc_size);\n\t\tduk_memset((void *) thr->valstack, 0x55, alloc_size);\n\t\tDUK_FREE_CHECKED(thr, (void *) thr->valstack);\n\t\tthr->valstack = new_ptr;\n\t\tthr->valstack_alloc_end = (duk_tval *) ((duk_uint8_t *) new_ptr + alloc_end_off);\n\t\tthr->valstack_end = (duk_tval *) ((duk_uint8_t *) new_ptr + end_off);\n\t\tthr->valstack_bottom = (duk_tval *) ((duk_uint8_t *) new_ptr + bottom_off);\n\t\tthr->valstack_top = (duk_tval *) ((duk_uint8_t *) new_ptr + top_off);\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"failed to realloc valstack for torture, ignore\"));\n\t}\n}\n#endif  /* DUK_USE_FINALIZER_TORTURE */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_internal.h",
    "content": "/*\n *  Top-level include file to be used for all (internal) source files.\n *\n *  Source files should not include individual header files, as they\n *  have not been designed to be individually included.\n */\n\n#if !defined(DUK_INTERNAL_H_INCLUDED)\n#define DUK_INTERNAL_H_INCLUDED\n\n/*\n *  The 'duktape.h' header provides the public API, but also handles all\n *  compiler and platform specific feature detection, Duktape feature\n *  resolution, inclusion of system headers, etc.  These have been merged\n *  because the public API is also dependent on e.g. detecting appropriate\n *  C types which is quite platform/compiler specific especially for a non-C99\n *  build.  The public API is also dependent on the resolved feature set.\n *\n *  Some actions taken by the merged header (such as including system headers)\n *  are not appropriate for building a user application.  The define\n *  DUK_COMPILING_DUKTAPE allows the merged header to skip/include some\n *  sections depending on what is being built.\n */\n\n#define DUK_COMPILING_DUKTAPE\n#include \"duktape.h\"\n\n/*\n *  Duktape includes (other than duk_features.h)\n *\n *  The header files expect to be included in an order which satisfies header\n *  dependencies correctly (the headers themselves don't include any other\n *  includes).  Forward declarations are used to break circular struct/typedef\n *  dependencies.\n */\n\n#include \"duk_dblunion.h\"\n#include \"duk_replacements.h\"\n#include \"duk_jmpbuf.h\"\n#include \"duk_exception.h\"\n#include \"duk_forwdecl.h\"\n#include \"duk_tval.h\"      /* builtins need e.g. duk_tval tag definitions */\n#include \"duk_builtins.h\"  /* autogenerated: strings and built-in object init data */\n\n#include \"duk_util.h\"\n#include \"duk_strings.h\"\n#include \"duk_js_bytecode.h\"\n#include \"duk_lexer.h\"\n#include \"duk_js_compiler.h\"\n#include \"duk_regexp.h\"\n#include \"duk_heaphdr.h\"\n#include \"duk_refcount.h\"\n#include \"duk_api_internal.h\"\n#include \"duk_hstring.h\"\n#include \"duk_hobject.h\"\n#include \"duk_hcompfunc.h\"\n#include \"duk_hnatfunc.h\"\n#include \"duk_hboundfunc.h\"\n#include \"duk_hbufobj.h\"\n#include \"duk_hthread.h\"\n#include \"duk_harray.h\"\n#include \"duk_henv.h\"\n#include \"duk_hbuffer.h\"\n#include \"duk_hproxy.h\"\n#include \"duk_heap.h\"\n#include \"duk_debugger.h\"\n#include \"duk_debug.h\"\n#include \"duk_error.h\"\n#include \"duk_unicode.h\"\n#include \"duk_json.h\"\n#include \"duk_js.h\"\n#include \"duk_numconv.h\"\n#include \"duk_bi_protos.h\"\n#include \"duk_selftest.h\"\n\n#endif  /* DUK_INTERNAL_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_jmpbuf.h",
    "content": "/*\n *  Wrapper for jmp_buf.\n *\n *  This is used because jmp_buf is an array type for backward compatibility.\n *  Wrapping jmp_buf in a struct makes pointer references, sizeof, etc,\n *  behave more intuitively.\n *\n *  http://en.wikipedia.org/wiki/Setjmp.h#Member_types\n */\n\n#if !defined(DUK_JMPBUF_H_INCLUDED)\n#define DUK_JMPBUF_H_INCLUDED\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\nstruct duk_jmpbuf {\n\tduk_small_int_t dummy;  /* unused */\n};\n#else\nstruct duk_jmpbuf {\n\tDUK_JMPBUF_TYPE jb;\n};\n#endif\n\n#endif  /* DUK_JMPBUF_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_js.h",
    "content": "/*\n *  ECMAScript execution, support primitives.\n */\n\n#if !defined(DUK_JS_H_INCLUDED)\n#define DUK_JS_H_INCLUDED\n\n/* Flags for call handling.  Lowest flags must match bytecode DUK_BC_CALL_FLAG_xxx 1:1. */\n#define DUK_CALL_FLAG_TAILCALL                 (1U << 0)  /* setup for a tail call */\n#define DUK_CALL_FLAG_CONSTRUCT                (1U << 1)  /* constructor call (i.e. called as 'new Foo()') */\n#define DUK_CALL_FLAG_CALLED_AS_EVAL           (1U << 2)  /* call was made using the identifier 'eval' */\n#define DUK_CALL_FLAG_ALLOW_ECMATOECMA         (1U << 3)  /* ecma-to-ecma call with executor reuse is possible */\n#define DUK_CALL_FLAG_DIRECT_EVAL              (1U << 4)  /* call is a direct eval call */\n#define DUK_CALL_FLAG_CONSTRUCT_PROXY          (1U << 5)  /* handled via 'construct' proxy trap, check return value invariant(s) */\n#define DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED (1U << 6)  /* prototype of 'default instance' updated, temporary flag in call handling */\n\n/* Flags for duk_js_equals_helper(). */\n#define DUK_EQUALS_FLAG_SAMEVALUE            (1U << 0)  /* use SameValue instead of non-strict equality */\n#define DUK_EQUALS_FLAG_STRICT               (1U << 1)  /* use strict equality instead of non-strict equality */\n\n/* Flags for duk_js_compare_helper(). */\n#define DUK_COMPARE_FLAG_NEGATE              (1U << 0)  /* negate result */\n#define DUK_COMPARE_FLAG_EVAL_LEFT_FIRST     (1U << 1)  /* eval left argument first */\n\n/* conversions, coercions, comparison, etc */\nDUK_INTERNAL_DECL duk_bool_t duk_js_toboolean(duk_tval *tv);\nDUK_INTERNAL_DECL duk_double_t duk_js_tonumber(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_double_t duk_js_tointeger_number(duk_double_t x);\nDUK_INTERNAL_DECL duk_double_t duk_js_tointeger(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_uint32_t duk_js_touint32(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_int32_t duk_js_toint32(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_uint16_t duk_js_touint16(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_string(const duk_uint8_t *str, duk_uint32_t blen);\n#if !defined(DUK_USE_HSTRING_ARRIDX)\nDUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_hstring_fast_known(duk_hstring *h);\nDUK_INTERNAL_DECL duk_uarridx_t duk_js_to_arrayindex_hstring_fast(duk_hstring *h);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_small_int_t duk_js_data_compare(const duk_uint8_t *buf1, const duk_uint8_t *buf2, duk_size_t len1, duk_size_t len2);\nDUK_INTERNAL_DECL duk_small_int_t duk_js_string_compare(duk_hstring *h1, duk_hstring *h2);\n#if 0  /* unused */\nDUK_INTERNAL_DECL duk_small_int_t duk_js_buffer_compare(duk_heap *heap, duk_hbuffer *h1, duk_hbuffer *h2);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags);\nDUK_INTERNAL_DECL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL_DECL duk_bool_t duk_js_instanceof_ordinary(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_in(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y);\nDUK_INTERNAL_DECL duk_small_uint_t duk_js_typeof_stridx(duk_tval *tv_x);\n\n/* arithmetic */\nDUK_INTERNAL_DECL double duk_js_arith_pow(double x, double y);\nDUK_INTERNAL_DECL double duk_js_arith_mod(double x, double y);\n\n#define duk_js_equals(thr,tv_x,tv_y) \\\n\tduk_js_equals_helper((thr), (tv_x), (tv_y), 0)\n#define duk_js_strict_equals(tv_x,tv_y) \\\n\tduk_js_equals_helper(NULL, (tv_x), (tv_y), DUK_EQUALS_FLAG_STRICT)\n#define duk_js_samevalue(tv_x,tv_y) \\\n\tduk_js_equals_helper(NULL, (tv_x), (tv_y), DUK_EQUALS_FLAG_SAMEVALUE)\n\n/* E5 Sections 11.8.1, 11.8.5; x < y */\n#define duk_js_lessthan(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_x), (tv_Y), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST)\n\n/* E5 Sections 11.8.2, 11.8.5; x > y  -->  y < x */\n#define duk_js_greaterthan(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_y), (tv_x), 0)\n\n/* E5 Sections 11.8.3, 11.8.5; x <= y  -->  not (x > y)  -->  not (y < x) */\n#define duk_js_lessthanorequal(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_y), (tv_x), DUK_COMPARE_FLAG_NEGATE)\n\n/* E5 Sections 11.8.4, 11.8.5; x >= y  -->  not (x < y) */\n#define duk_js_greaterthanorequal(thr,tv_x,tv_y) \\\n\tduk_js_compare_helper((thr), (tv_x), (tv_y), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST | DUK_COMPARE_FLAG_NEGATE)\n\n/* identifiers and environment handling */\n#if 0  /*unused*/\nDUK_INTERNAL duk_bool_t duk_js_hasvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_getvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL duk_bool_t duk_js_getvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_bool_t throw_flag);\nDUK_INTERNAL_DECL void duk_js_putvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name, duk_tval *val, duk_bool_t strict);\nDUK_INTERNAL_DECL void duk_js_putvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_tval *val, duk_bool_t strict);\n#if 0  /*unused*/\nDUK_INTERNAL_DECL duk_bool_t duk_js_delvar_envrec(duk_hthread *thr, duk_hobject *env, duk_hstring *name);\n#endif\nDUK_INTERNAL_DECL duk_bool_t duk_js_delvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name);\nDUK_INTERNAL_DECL duk_bool_t duk_js_declvar_activation(duk_hthread *thr, duk_activation *act, duk_hstring *name, duk_tval *val, duk_small_uint_t prop_flags, duk_bool_t is_func_decl);\nDUK_INTERNAL_DECL void duk_js_init_activation_environment_records_delayed(duk_hthread *thr, duk_activation *act);\nDUK_INTERNAL_DECL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject *env);\nDUK_INTERNAL_DECL duk_hobject *duk_create_activation_environment_record(duk_hthread *thr, duk_hobject *func, duk_size_t bottom_byteoff);\nDUK_INTERNAL_DECL void duk_js_push_closure(duk_hthread *thr,\n                                           duk_hcompfunc *fun_temp,\n                                           duk_hobject *outer_var_env,\n                                           duk_hobject *outer_lex_env,\n                                           duk_bool_t add_auto_proto);\n\n/* call handling */\nDUK_INTERNAL_DECL void duk_native_stack_check(duk_hthread *thr);\nDUK_INTERNAL_DECL duk_int_t duk_handle_call_unprotected(duk_hthread *thr, duk_idx_t idx_func, duk_small_uint_t call_flags);\nDUK_INTERNAL_DECL duk_int_t duk_handle_call_unprotected_nargs(duk_hthread *thr, duk_idx_t nargs, duk_small_uint_t call_flags);\nDUK_INTERNAL_DECL duk_int_t duk_handle_safe_call(duk_hthread *thr, duk_safe_call_function func, void *udata, duk_idx_t num_stack_args, duk_idx_t num_stack_res);\nDUK_INTERNAL_DECL void duk_call_construct_postprocess(duk_hthread *thr, duk_small_uint_t proxy_invariant);\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_INTERNAL_DECL void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_base, duk_tval *tv_key);\n#endif\n\n/* bytecode execution */\nDUK_INTERNAL_DECL void duk_js_execute_bytecode(duk_hthread *exec_thr);\n\n#endif  /* DUK_JS_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_js_arith.c",
    "content": "/*\n *  Shared helpers for arithmetic operations\n */\n\n#include \"duk_internal.h\"\n\n/* ECMAScript modulus ('%') does not match IEEE 754 \"remainder\" operation\n * (implemented by remainder() in C99) but does seem to match ANSI C fmod().\n * Compare E5 Section 11.5.3 and \"man fmod\".\n */\nDUK_INTERNAL double duk_js_arith_mod(double d1, double d2) {\n#if defined(DUK_USE_POW_WORKAROUNDS)\n\t/* Specific fixes to common fmod() implementation issues:\n\t * - test-bug-mingw-math-issues.js\n\t */\n\tif (DUK_ISINF(d2)) {\n\t\tif (DUK_ISINF(d1)) {\n\t\t\treturn DUK_DOUBLE_NAN;\n\t\t} else {\n\t\t\treturn d1;\n\t\t}\n\t} else if (d1 == 0.0) {\n\t\t/* d1 +/-0 is returned as is (preserving sign) except when\n\t\t * d2 is zero or NaN.\n\t\t */\n\t\tif (d2 == 0.0 || DUK_ISNAN(d2)) {\n\t\t\treturn DUK_DOUBLE_NAN;\n\t\t} else {\n\t\t\treturn d1;\n\t\t}\n\t}\n#else\n\t/* Some ISO C assumptions. */\n\tDUK_ASSERT(DUK_FMOD(1.0, DUK_DOUBLE_INFINITY) == 1.0);\n\tDUK_ASSERT(DUK_FMOD(-1.0, DUK_DOUBLE_INFINITY) == -1.0);\n\tDUK_ASSERT(DUK_FMOD(1.0, -DUK_DOUBLE_INFINITY) == 1.0);\n\tDUK_ASSERT(DUK_FMOD(-1.0, -DUK_DOUBLE_INFINITY) == -1.0);\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-DUK_DOUBLE_INFINITY, DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-DUK_DOUBLE_INFINITY, -DUK_DOUBLE_INFINITY)));\n\tDUK_ASSERT(DUK_FMOD(0.0, 1.0) == 0.0 && DUK_SIGNBIT(DUK_FMOD(0.0, 1.0)) == 0);\n\tDUK_ASSERT(DUK_FMOD(-0.0, 1.0) == 0.0 && DUK_SIGNBIT(DUK_FMOD(-0.0, 1.0)) != 0);\n\tDUK_ASSERT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY)) == 0);\n\tDUK_ASSERT(DUK_FMOD(-0.0, DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(-0.0, DUK_DOUBLE_INFINITY)) != 0);\n\tDUK_ASSERT(DUK_FMOD(0.0, -DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(0.0, DUK_DOUBLE_INFINITY)) == 0);\n\tDUK_ASSERT(DUK_FMOD(-0.0, -DUK_DOUBLE_INFINITY) == 0.0 && DUK_SIGNBIT(DUK_FMOD(-0.0, -DUK_DOUBLE_INFINITY)) != 0);\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, 0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, 0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, -0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, -0.0)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(0.0, DUK_DOUBLE_NAN)));\n\tDUK_ASSERT(DUK_ISNAN(DUK_FMOD(-0.0, DUK_DOUBLE_NAN)));\n#endif\n\n\treturn (duk_double_t) DUK_FMOD((double) d1, (double) d2);\n}\n\n/* Shared helper for Math.pow() and exponentiation operator. */\nDUK_INTERNAL double duk_js_arith_pow(double x, double y) {\n\t/* The ANSI C pow() semantics differ from ECMAScript.\n\t *\n\t * E.g. when x==1 and y is +/- infinite, the ECMAScript required\n\t * result is NaN, while at least Linux pow() returns 1.\n\t */\n\n\tduk_small_int_t cx, cy, sx;\n\n\tDUK_UNREF(cx);\n\tDUK_UNREF(sx);\n\tcy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\n\tif (cy == DUK_FP_NAN) {\n\t\tgoto ret_nan;\n\t}\n\tif (DUK_FABS(x) == 1.0 && cy == DUK_FP_INFINITE) {\n\t\tgoto ret_nan;\n\t}\n\n#if defined(DUK_USE_POW_WORKAROUNDS)\n\t/* Specific fixes to common pow() implementation issues:\n\t *   - test-bug-netbsd-math-pow.js: NetBSD 6.0 on x86 (at least)\n\t *   - test-bug-mingw-math-issues.js\n\t */\n\tcx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (cx == DUK_FP_ZERO && y < 0.0) {\n\t\tsx = (duk_small_int_t) DUK_SIGNBIT(x);\n\t\tif (sx == 0) {\n\t\t\t/* Math.pow(+0,y) should be Infinity when y<0.  NetBSD pow()\n\t\t\t * returns -Infinity instead when y is <0 and finite.  The\n\t\t\t * if-clause also catches y == -Infinity (which works even\n\t\t\t * without the fix).\n\t\t\t */\n\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t} else {\n\t\t\t/* Math.pow(-0,y) where y<0 should be:\n\t\t\t *   - -Infinity if y<0 and an odd integer\n\t\t\t *   - Infinity if y<0 but not an odd integer\n\t\t\t * NetBSD pow() returns -Infinity for all finite y<0.  The\n\t\t\t * if-clause also catches y == -Infinity (which works even\n\t\t\t * without the fix).\n\t\t\t */\n\n\t\t\t/* fmod() return value has same sign as input (negative) so\n\t\t\t * the result here will be in the range ]-2,0], -1 indicates\n\t\t\t * odd.  If x is -Infinity, NaN is returned and the odd check\n\t\t\t * always concludes \"not odd\" which results in desired outcome.\n\t\t\t */\n\t\t\tdouble tmp = DUK_FMOD(y, 2);\n\t\t\tif (tmp == -1.0) {\n\t\t\t\treturn -DUK_DOUBLE_INFINITY;\n\t\t\t} else {\n\t\t\t\t/* Not odd, or y == -Infinity */\n\t\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t\t}\n\t\t}\n\t} else if (cx == DUK_FP_NAN) {\n\t\tif (y == 0.0) {\n\t\t\t/* NaN ** +/- 0 should always be 1, but is NaN on\n\t\t\t * at least some Cygwin/MinGW versions.\n\t\t\t */\n\t\t\treturn 1.0;\n\t\t}\n\t}\n#else\n\t/* Some ISO C assumptions. */\n\tDUK_ASSERT(DUK_POW(DUK_DOUBLE_NAN, 0.0) == 1.0);\n\tDUK_ASSERT(DUK_ISINF(DUK_POW(0.0, -1.0)) && DUK_SIGNBIT(DUK_POW(0.0, -1.0)) == 0);\n\tDUK_ASSERT(DUK_ISINF(DUK_POW(-0.0, -2.0)) && DUK_SIGNBIT(DUK_POW(-0.0, -2.0)) == 0);\n\tDUK_ASSERT(DUK_ISINF(DUK_POW(-0.0, -3.0)) && DUK_SIGNBIT(DUK_POW(-0.0, -3.0)) != 0);\n#endif\n\n\treturn DUK_POW(x, y);\n\n ret_nan:\n\treturn DUK_DOUBLE_NAN;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_js_bytecode.h",
    "content": "/*\n *  ECMAScript bytecode\n */\n\n#if !defined(DUK_JS_BYTECODE_H_INCLUDED)\n#define DUK_JS_BYTECODE_H_INCLUDED\n\n/*\n *  Bytecode instruction layout\n *  ===========================\n *\n *  Instructions are unsigned 32-bit integers divided as follows:\n *\n *  !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! !\n *  !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!\n *  +-----------------------------------------------+---------------+\n *  !       C       !       B       !       A       !       OP      !\n *  +-----------------------------------------------+---------------+\n *\n *  OP (8 bits):  opcode (DUK_OP_*), access should be fastest\n *                consecutive opcodes allocated when opcode needs flags\n *   A (8 bits):  typically a target register number\n *   B (8 bits):  typically first source register/constant number\n *   C (8 bits):  typically second source register/constant number\n *\n *  Some instructions combine BC or ABC together for larger parameter values.\n *  Signed integers (e.g. jump offsets) are encoded as unsigned, with an\n *  opcode specific bias.\n *\n *  Some opcodes have flags which are handled by allocating consecutive\n *  opcodes to make space for 1-N flags.  Flags can also be e.g. in the 'A'\n *  field when there's room for the specific opcode.\n *\n *  For example, if three flags were needed, they could be allocated from\n *  the opcode field as follows:\n *\n *  !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! !\n *  !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!\n *  +-----------------------------------------------+---------------+\n *  !       C       !       B       !       A       !    OP   !Z!Y!X!\n *  +-----------------------------------------------+---------------+\n *\n *  Some opcodes accept a reg/const argument which is handled by allocating\n *  flags in the OP field, see DUK_BC_ISREG() and DUK_BC_ISCONST().  The\n *  following convention is shared by most opcodes, so that the compiler\n *  can handle reg/const flagging without opcode specific code paths:\n *\n *  !3!3!2!2!2!2!2!2!2!2!2!2!1!1!1!1!1!1!1!1!1!1! ! ! ! ! ! ! ! ! ! !\n *  !1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!9!8!7!6!5!4!3!2!1!0!\n *  +-----------------------------------------------+---------------+\n *  !       C       !       B       !       A       !     OP    !Y!X!\n *  +-----------------------------------------------+---------------+\n *\n *    X  1=B is const, 0=B is reg\n *    Y  1=C is const, 0=C is reg\n *\n *    In effect OP, OP + 1, OP + 2, and OP + 3 are allocated from the\n *    8-bit opcode space for a single logical opcode.  The base opcode\n *    number should be divisible by 4.  If the opcode is called 'FOO'\n *    the following opcode constants would be defined:\n *\n *      DUK_OP_FOO     100       // base opcode number\n *      DUK_OP_FOO_RR  100       // FOO, B=reg, C=reg\n *      DUK_OP_FOO_CR  101       // FOO, B=const, C=reg\n *      DUK_OP_FOO_RC  102       // FOO, B=reg, C=const\n *      DUK_OP_FOO_CC  103       // FOO, B=const, C=const\n *\n *  If only B or C is a reg/const, the unused opcode combinations can be\n *  used for other opcodes (which take no reg/const argument).  However,\n *  such opcode values are initially reserved, at least while opcode space\n *  is available.  For example, if 'BAR' uses B for a register field and\n *  C is a reg/const:\n *\n *      DUK_OP_BAR            116    // base opcode number\n *      DUK_OP_BAR_RR         116    // BAR, B=reg, C=reg\n *      DUK_OP_BAR_CR_UNUSED  117    // unused, could be repurposed\n *      DUK_OP_BAR_RC         118    // BAR, B=reg, C=const\n *      DUK_OP_BAR_CC_UNUSED  119    // unused, could be repurposed\n *\n *  Macro naming is a bit misleading, e.g. \"ABC\" in macro name but the\n *  field layout is concretely \"CBA\" in the register.\n */\n\ntypedef duk_uint32_t duk_instr_t;\n\n#define DUK_BC_SHIFT_OP             0\n#define DUK_BC_SHIFT_A              8\n#define DUK_BC_SHIFT_B              16\n#define DUK_BC_SHIFT_C              24\n#define DUK_BC_SHIFT_BC             DUK_BC_SHIFT_B\n#define DUK_BC_SHIFT_ABC            DUK_BC_SHIFT_A\n\n#define DUK_BC_UNSHIFTED_MASK_OP    0xffUL\n#define DUK_BC_UNSHIFTED_MASK_A     0xffUL\n#define DUK_BC_UNSHIFTED_MASK_B     0xffUL\n#define DUK_BC_UNSHIFTED_MASK_C     0xffUL\n#define DUK_BC_UNSHIFTED_MASK_BC    0xffffUL\n#define DUK_BC_UNSHIFTED_MASK_ABC   0xffffffUL\n\n#define DUK_BC_SHIFTED_MASK_OP      (DUK_BC_UNSHIFTED_MASK_OP << DUK_BC_SHIFT_OP)\n#define DUK_BC_SHIFTED_MASK_A       (DUK_BC_UNSHIFTED_MASK_A << DUK_BC_SHIFT_A)\n#define DUK_BC_SHIFTED_MASK_B       (DUK_BC_UNSHIFTED_MASK_B << DUK_BC_SHIFT_B)\n#define DUK_BC_SHIFTED_MASK_C       (DUK_BC_UNSHIFTED_MASK_C << DUK_BC_SHIFT_C)\n#define DUK_BC_SHIFTED_MASK_BC      (DUK_BC_UNSHIFTED_MASK_BC << DUK_BC_SHIFT_BC)\n#define DUK_BC_SHIFTED_MASK_ABC     (DUK_BC_UNSHIFTED_MASK_ABC << DUK_BC_SHIFT_ABC)\n\n#define DUK_DEC_OP(x)               ((x) & 0xffUL)\n#define DUK_DEC_A(x)                (((x) >> 8) & 0xffUL)\n#define DUK_DEC_B(x)                (((x) >> 16) & 0xffUL)\n#define DUK_DEC_C(x)                (((x) >> 24) & 0xffUL)\n#define DUK_DEC_BC(x)               (((x) >> 16) & 0xffffUL)\n#define DUK_DEC_ABC(x)              (((x) >> 8) & 0xffffffUL)\n\n#define DUK_ENC_OP(op)              ((duk_instr_t) (op))\n#define DUK_ENC_OP_ABC(op,abc)      ((duk_instr_t) ( \\\n                                        (((duk_instr_t) (abc)) << 8) | \\\n                                        ((duk_instr_t) (op)) \\\n                                    ))\n#define DUK_ENC_OP_A_BC(op,a,bc)    ((duk_instr_t) ( \\\n                                        (((duk_instr_t) (bc)) << 16) | \\\n                                        (((duk_instr_t) (a)) << 8) | \\\n                                        ((duk_instr_t) (op)) \\\n                                    ))\n#define DUK_ENC_OP_A_B_C(op,a,b,c)  ((duk_instr_t) ( \\\n                                        (((duk_instr_t) (c)) << 24) | \\\n                                        (((duk_instr_t) (b)) << 16) | \\\n                                        (((duk_instr_t) (a)) << 8) | \\\n                                        ((duk_instr_t) (op)) \\\n                                    ))\n#define DUK_ENC_OP_A_B(op,a,b)      DUK_ENC_OP_A_B_C((op),(a),(b),0)\n#define DUK_ENC_OP_A(op,a)          DUK_ENC_OP_A_B_C((op),(a),0,0)\n#define DUK_ENC_OP_BC(op,bc)        DUK_ENC_OP_A_BC((op),0,(bc))\n\n/* Get opcode base value with B/C reg/const flags cleared. */\n#define DUK_BC_NOREGCONST_OP(op)    ((op) & 0xfc)\n\n/* Constants should be signed so that signed arithmetic involving them\n * won't cause values to be coerced accidentally to unsigned.\n */\n#define DUK_BC_OP_MIN               0\n#define DUK_BC_OP_MAX               0xffL\n#define DUK_BC_A_MIN                0\n#define DUK_BC_A_MAX                0xffL\n#define DUK_BC_B_MIN                0\n#define DUK_BC_B_MAX                0xffL\n#define DUK_BC_C_MIN                0\n#define DUK_BC_C_MAX                0xffL\n#define DUK_BC_BC_MIN               0\n#define DUK_BC_BC_MAX               0xffffL\n#define DUK_BC_ABC_MIN              0\n#define DUK_BC_ABC_MAX              0xffffffL\n\n/* Masks for B/C reg/const indicator in opcode field. */\n#define DUK_BC_REGCONST_B           (0x01UL)\n#define DUK_BC_REGCONST_C           (0x02UL)\n\n/* Misc. masks for opcode field. */\n#define DUK_BC_INCDECP_FLAG_DEC     (0x04UL)\n#define DUK_BC_INCDECP_FLAG_POST    (0x08UL)\n\n/* Opcodes. */\n#define DUK_OP_LDREG                0\n#define DUK_OP_STREG                1\n#define DUK_OP_JUMP                 2\n#define DUK_OP_LDCONST              3\n#define DUK_OP_LDINT                4\n#define DUK_OP_LDINTX               5\n#define DUK_OP_LDTHIS               6\n#define DUK_OP_LDUNDEF              7\n#define DUK_OP_LDNULL               8\n#define DUK_OP_LDTRUE               9\n#define DUK_OP_LDFALSE              10\n#define DUK_OP_GETVAR               11\n#define DUK_OP_BNOT                 12\n#define DUK_OP_LNOT                 13\n#define DUK_OP_UNM                  14\n#define DUK_OP_UNP                  15\n#define DUK_OP_EQ                   16\n#define DUK_OP_EQ_RR                16\n#define DUK_OP_EQ_CR                17\n#define DUK_OP_EQ_RC                18\n#define DUK_OP_EQ_CC                19\n#define DUK_OP_NEQ                  20\n#define DUK_OP_NEQ_RR               20\n#define DUK_OP_NEQ_CR               21\n#define DUK_OP_NEQ_RC               22\n#define DUK_OP_NEQ_CC               23\n#define DUK_OP_SEQ                  24\n#define DUK_OP_SEQ_RR               24\n#define DUK_OP_SEQ_CR               25\n#define DUK_OP_SEQ_RC               26\n#define DUK_OP_SEQ_CC               27\n#define DUK_OP_SNEQ                 28\n#define DUK_OP_SNEQ_RR              28\n#define DUK_OP_SNEQ_CR              29\n#define DUK_OP_SNEQ_RC              30\n#define DUK_OP_SNEQ_CC              31\n#define DUK_OP_GT                   32\n#define DUK_OP_GT_RR                32\n#define DUK_OP_GT_CR                33\n#define DUK_OP_GT_RC                34\n#define DUK_OP_GT_CC                35\n#define DUK_OP_GE                   36\n#define DUK_OP_GE_RR                36\n#define DUK_OP_GE_CR                37\n#define DUK_OP_GE_RC                38\n#define DUK_OP_GE_CC                39\n#define DUK_OP_LT                   40\n#define DUK_OP_LT_RR                40\n#define DUK_OP_LT_CR                41\n#define DUK_OP_LT_RC                42\n#define DUK_OP_LT_CC                43\n#define DUK_OP_LE                   44\n#define DUK_OP_LE_RR                44\n#define DUK_OP_LE_CR                45\n#define DUK_OP_LE_RC                46\n#define DUK_OP_LE_CC                47\n#define DUK_OP_IFTRUE               48\n#define DUK_OP_IFTRUE_R             48\n#define DUK_OP_IFTRUE_C             49\n#define DUK_OP_IFFALSE              50\n#define DUK_OP_IFFALSE_R            50\n#define DUK_OP_IFFALSE_C            51\n#define DUK_OP_ADD                  52\n#define DUK_OP_ADD_RR               52\n#define DUK_OP_ADD_CR               53\n#define DUK_OP_ADD_RC               54\n#define DUK_OP_ADD_CC               55\n#define DUK_OP_SUB                  56\n#define DUK_OP_SUB_RR               56\n#define DUK_OP_SUB_CR               57\n#define DUK_OP_SUB_RC               58\n#define DUK_OP_SUB_CC               59\n#define DUK_OP_MUL                  60\n#define DUK_OP_MUL_RR               60\n#define DUK_OP_MUL_CR               61\n#define DUK_OP_MUL_RC               62\n#define DUK_OP_MUL_CC               63\n#define DUK_OP_DIV                  64\n#define DUK_OP_DIV_RR               64\n#define DUK_OP_DIV_CR               65\n#define DUK_OP_DIV_RC               66\n#define DUK_OP_DIV_CC               67\n#define DUK_OP_MOD                  68\n#define DUK_OP_MOD_RR               68\n#define DUK_OP_MOD_CR               69\n#define DUK_OP_MOD_RC               70\n#define DUK_OP_MOD_CC               71\n#define DUK_OP_EXP                  72\n#define DUK_OP_EXP_RR               72\n#define DUK_OP_EXP_CR               73\n#define DUK_OP_EXP_RC               74\n#define DUK_OP_EXP_CC               75\n#define DUK_OP_BAND                 76\n#define DUK_OP_BAND_RR              76\n#define DUK_OP_BAND_CR              77\n#define DUK_OP_BAND_RC              78\n#define DUK_OP_BAND_CC              79\n#define DUK_OP_BOR                  80\n#define DUK_OP_BOR_RR               80\n#define DUK_OP_BOR_CR               81\n#define DUK_OP_BOR_RC               82\n#define DUK_OP_BOR_CC               83\n#define DUK_OP_BXOR                 84\n#define DUK_OP_BXOR_RR              84\n#define DUK_OP_BXOR_CR              85\n#define DUK_OP_BXOR_RC              86\n#define DUK_OP_BXOR_CC              87\n#define DUK_OP_BASL                 88\n#define DUK_OP_BASL_RR              88\n#define DUK_OP_BASL_CR              89\n#define DUK_OP_BASL_RC              90\n#define DUK_OP_BASL_CC              91\n#define DUK_OP_BLSR                 92\n#define DUK_OP_BLSR_RR              92\n#define DUK_OP_BLSR_CR              93\n#define DUK_OP_BLSR_RC              94\n#define DUK_OP_BLSR_CC              95\n#define DUK_OP_BASR                 96\n#define DUK_OP_BASR_RR              96\n#define DUK_OP_BASR_CR              97\n#define DUK_OP_BASR_RC              98\n#define DUK_OP_BASR_CC              99\n#define DUK_OP_INSTOF               100\n#define DUK_OP_INSTOF_RR            100\n#define DUK_OP_INSTOF_CR            101\n#define DUK_OP_INSTOF_RC            102\n#define DUK_OP_INSTOF_CC            103\n#define DUK_OP_IN                   104\n#define DUK_OP_IN_RR                104\n#define DUK_OP_IN_CR                105\n#define DUK_OP_IN_RC                106\n#define DUK_OP_IN_CC                107\n#define DUK_OP_GETPROP              108\n#define DUK_OP_GETPROP_RR           108\n#define DUK_OP_GETPROP_CR           109\n#define DUK_OP_GETPROP_RC           110\n#define DUK_OP_GETPROP_CC           111\n#define DUK_OP_PUTPROP              112\n#define DUK_OP_PUTPROP_RR           112\n#define DUK_OP_PUTPROP_CR           113\n#define DUK_OP_PUTPROP_RC           114\n#define DUK_OP_PUTPROP_CC           115\n#define DUK_OP_DELPROP              116\n#define DUK_OP_DELPROP_RR           116\n#define DUK_OP_DELPROP_CR_UNUSED    117  /* unused now */\n#define DUK_OP_DELPROP_RC           118\n#define DUK_OP_DELPROP_CC_UNUSED    119  /* unused now */\n#define DUK_OP_PREINCR              120  /* pre/post opcode values have constraints, */\n#define DUK_OP_PREDECR              121  /* see duk_js_executor.c and duk_js_compiler.c. */\n#define DUK_OP_POSTINCR             122\n#define DUK_OP_POSTDECR             123\n#define DUK_OP_PREINCV              124\n#define DUK_OP_PREDECV              125\n#define DUK_OP_POSTINCV             126\n#define DUK_OP_POSTDECV             127\n#define DUK_OP_PREINCP              128  /* pre/post inc/dec prop opcodes have constraints */\n#define DUK_OP_PREINCP_RR           128\n#define DUK_OP_PREINCP_CR           129\n#define DUK_OP_PREINCP_RC           130\n#define DUK_OP_PREINCP_CC           131\n#define DUK_OP_PREDECP              132\n#define DUK_OP_PREDECP_RR           132\n#define DUK_OP_PREDECP_CR           133\n#define DUK_OP_PREDECP_RC           134\n#define DUK_OP_PREDECP_CC           135\n#define DUK_OP_POSTINCP             136\n#define DUK_OP_POSTINCP_RR          136\n#define DUK_OP_POSTINCP_CR          137\n#define DUK_OP_POSTINCP_RC          138\n#define DUK_OP_POSTINCP_CC          139\n#define DUK_OP_POSTDECP             140\n#define DUK_OP_POSTDECP_RR          140\n#define DUK_OP_POSTDECP_CR          141\n#define DUK_OP_POSTDECP_RC          142\n#define DUK_OP_POSTDECP_CC          143\n#define DUK_OP_DECLVAR              144\n#define DUK_OP_DECLVAR_RR           144\n#define DUK_OP_DECLVAR_CR           145\n#define DUK_OP_DECLVAR_RC           146\n#define DUK_OP_DECLVAR_CC           147\n#define DUK_OP_REGEXP               148\n#define DUK_OP_REGEXP_RR            148\n#define DUK_OP_REGEXP_CR            149\n#define DUK_OP_REGEXP_RC            150\n#define DUK_OP_REGEXP_CC            151\n#define DUK_OP_CLOSURE              152\n#define DUK_OP_TYPEOF               153\n#define DUK_OP_TYPEOFID             154\n#define DUK_OP_PUTVAR               155\n#define DUK_OP_DELVAR               156\n#define DUK_OP_RETREG               157\n#define DUK_OP_RETUNDEF             158\n#define DUK_OP_RETCONST             159\n#define DUK_OP_RETCONSTN            160  /* return const without incref (e.g. number) */\n#define DUK_OP_LABEL                161\n#define DUK_OP_ENDLABEL             162\n#define DUK_OP_BREAK                163\n#define DUK_OP_CONTINUE             164\n#define DUK_OP_TRYCATCH             165\n#define DUK_OP_ENDTRY               166\n#define DUK_OP_ENDCATCH             167\n#define DUK_OP_ENDFIN               168\n#define DUK_OP_THROW                169\n#define DUK_OP_INVLHS               170\n#define DUK_OP_CSREG                171\n#define DUK_OP_CSVAR                172\n#define DUK_OP_CSVAR_RR             172\n#define DUK_OP_CSVAR_CR             173\n#define DUK_OP_CSVAR_RC             174\n#define DUK_OP_CSVAR_CC             175\n#define DUK_OP_CALL0                176  /* DUK_OP_CALL0 & 0x0F must be zero. */\n#define DUK_OP_CALL1                177\n#define DUK_OP_CALL2                178\n#define DUK_OP_CALL3                179\n#define DUK_OP_CALL4                180\n#define DUK_OP_CALL5                181\n#define DUK_OP_CALL6                182\n#define DUK_OP_CALL7                183\n#define DUK_OP_CALL8                184\n#define DUK_OP_CALL9                185\n#define DUK_OP_CALL10               186\n#define DUK_OP_CALL11               187\n#define DUK_OP_CALL12               188\n#define DUK_OP_CALL13               189\n#define DUK_OP_CALL14               190\n#define DUK_OP_CALL15               191\n#define DUK_OP_NEWOBJ               192\n#define DUK_OP_NEWARR               193\n#define DUK_OP_MPUTOBJ              194\n#define DUK_OP_MPUTOBJI             195\n#define DUK_OP_INITSET              196\n#define DUK_OP_INITGET              197\n#define DUK_OP_MPUTARR              198\n#define DUK_OP_MPUTARRI             199\n#define DUK_OP_SETALEN              200\n#define DUK_OP_INITENUM             201\n#define DUK_OP_NEXTENUM             202\n#define DUK_OP_NEWTARGET            203\n#define DUK_OP_DEBUGGER             204\n#define DUK_OP_NOP                  205\n#define DUK_OP_INVALID              206\n#define DUK_OP_UNUSED207            207\n#define DUK_OP_GETPROPC             208\n#define DUK_OP_GETPROPC_RR          208\n#define DUK_OP_GETPROPC_CR          209\n#define DUK_OP_GETPROPC_RC          210\n#define DUK_OP_GETPROPC_CC          211\n#define DUK_OP_UNUSED212            212\n#define DUK_OP_UNUSED213            213\n#define DUK_OP_UNUSED214            214\n#define DUK_OP_UNUSED215            215\n#define DUK_OP_UNUSED216            216\n#define DUK_OP_UNUSED217            217\n#define DUK_OP_UNUSED218            218\n#define DUK_OP_UNUSED219            219\n#define DUK_OP_UNUSED220            220\n#define DUK_OP_UNUSED221            221\n#define DUK_OP_UNUSED222            222\n#define DUK_OP_UNUSED223            223\n#define DUK_OP_UNUSED224            224\n#define DUK_OP_UNUSED225            225\n#define DUK_OP_UNUSED226            226\n#define DUK_OP_UNUSED227            227\n#define DUK_OP_UNUSED228            228\n#define DUK_OP_UNUSED229            229\n#define DUK_OP_UNUSED230            230\n#define DUK_OP_UNUSED231            231\n#define DUK_OP_UNUSED232            232\n#define DUK_OP_UNUSED233            233\n#define DUK_OP_UNUSED234            234\n#define DUK_OP_UNUSED235            235\n#define DUK_OP_UNUSED236            236\n#define DUK_OP_UNUSED237            237\n#define DUK_OP_UNUSED238            238\n#define DUK_OP_UNUSED239            239\n#define DUK_OP_UNUSED240            240\n#define DUK_OP_UNUSED241            241\n#define DUK_OP_UNUSED242            242\n#define DUK_OP_UNUSED243            243\n#define DUK_OP_UNUSED244            244\n#define DUK_OP_UNUSED245            245\n#define DUK_OP_UNUSED246            246\n#define DUK_OP_UNUSED247            247\n#define DUK_OP_UNUSED248            248\n#define DUK_OP_UNUSED249            249\n#define DUK_OP_UNUSED250            250\n#define DUK_OP_UNUSED251            251\n#define DUK_OP_UNUSED252            252\n#define DUK_OP_UNUSED253            253\n#define DUK_OP_UNUSED254            254\n#define DUK_OP_UNUSED255            255\n#define DUK_OP_NONE                 256  /* dummy value used as marker (doesn't fit in 8-bit field) */\n\n/* XXX: Allocate flags from opcode field?  Would take 16 opcode slots\n * but avoids shuffling in more cases.  Maybe not worth it.\n */\n/* DUK_OP_TRYCATCH flags in A. */\n#define DUK_BC_TRYCATCH_FLAG_HAVE_CATCH     (1U << 0)\n#define DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY   (1U << 1)\n#define DUK_BC_TRYCATCH_FLAG_CATCH_BINDING  (1U << 2)\n#define DUK_BC_TRYCATCH_FLAG_WITH_BINDING   (1U << 3)\n\n/* DUK_OP_DECLVAR flags in A; bottom bits are reserved for propdesc flags\n * (DUK_PROPDESC_FLAG_XXX).\n */\n#define DUK_BC_DECLVAR_FLAG_FUNC_DECL       (1U << 4)  /* function declaration */\n\n/* DUK_OP_CALLn flags, part of opcode field.  Three lowest bits must match\n * DUK_CALL_FLAG_xxx directly.\n */\n#define DUK_BC_CALL_FLAG_TAILCALL           (1U << 0)\n#define DUK_BC_CALL_FLAG_CONSTRUCT          (1U << 1)\n#define DUK_BC_CALL_FLAG_CALLED_AS_EVAL     (1U << 2)\n#define DUK_BC_CALL_FLAG_INDIRECT           (1U << 3)\n\n/* Misc constants and helper macros. */\n#define DUK_BC_LDINT_BIAS           (1L << 15)\n#define DUK_BC_LDINTX_SHIFT         16\n#define DUK_BC_JUMP_BIAS            (1L << 23)\n\n#endif  /* DUK_JS_BYTECODE_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_js_call.c",
    "content": "/*\n *  Call handling.\n *\n *  duk_handle_call_unprotected():\n *\n *    - Unprotected call to ECMAScript or Duktape/C function, from native\n *      code or bytecode executor.\n *\n *    - Also handles Ecma-to-Ecma calls which reuses a currently running\n *      executor instance to avoid native recursion.  Call setup is done\n *      normally, but just before calling the bytecode executor a special\n *      return code is used to indicate that a calling executor is reused.\n *\n *    - Also handles tailcalls, i.e. reuse of current duk_activation.\n *\n *    - Also handles setup for initial Duktape.Thread.resume().\n *\n *  duk_handle_safe_call():\n *\n *    - Protected C call within current activation.\n *\n *  setjmp() and local variables have a nasty interaction, see execution.rst;\n *  non-volatile locals modified after setjmp() call are not guaranteed to\n *  keep their value and can cause compiler or compiler version specific\n *  difficult to replicate issues.\n *\n *  See 'execution.rst'.\n */\n\n#include \"duk_internal.h\"\n\n/* XXX: heap->error_not_allowed for success path too? */\n\n/*\n *  Limit check helpers.\n */\n\n/* Check native stack space if DUK_USE_NATIVE_STACK_CHECK() defined. */\nDUK_INTERNAL void duk_native_stack_check(duk_hthread *thr) {\n#if defined(DUK_USE_NATIVE_STACK_CHECK)\n\tif (DUK_USE_NATIVE_STACK_CHECK() != 0) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_NATIVE_STACK_LIMIT);\n\t}\n#else\n\tDUK_UNREF(thr);\n#endif\n}\n\n/* Allow headroom for calls during error augmentation (see GH-191).\n * We allow space for 10 additional recursions, with one extra\n * for, e.g. a print() call at the deepest level, and an extra\n * +1 for protected call wrapping.\n */\n#define DUK__AUGMENT_CALL_RELAX_COUNT  (10 + 2)\n\n/* Stack space required by call handling entry. */\n#define DUK__CALL_HANDLING_REQUIRE_STACK  8\n\nDUK_LOCAL DUK_NOINLINE void duk__call_c_recursion_limit_check_slowpath(duk_hthread *thr) {\n\t/* When augmenting an error, the effective limit is a bit higher.\n\t * Check for it only if the fast path check fails.\n\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tif (thr->heap->augmenting_error) {\n\t\tif (thr->heap->call_recursion_depth < thr->heap->call_recursion_limit + DUK__AUGMENT_CALL_RELAX_COUNT) {\n\t\t\tDUK_D(DUK_DPRINT(\"C recursion limit reached but augmenting error and within relaxed limit\"));\n\t\t\treturn;\n\t\t}\n\t}\n#endif\n\n\tDUK_D(DUK_DPRINT(\"call prevented because C recursion limit reached\"));\n\tDUK_ERROR_RANGE(thr, DUK_STR_NATIVE_STACK_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__call_c_recursion_limit_check(duk_hthread *thr) {\n\tDUK_ASSERT(thr->heap->call_recursion_depth >= 0);\n\tDUK_ASSERT(thr->heap->call_recursion_depth <= thr->heap->call_recursion_limit);\n\n\tduk_native_stack_check(thr);\n\n\t/* This check is forcibly inlined because it's very cheap and almost\n\t * always passes.  The slow path is forcibly noinline.\n\t */\n\tif (DUK_LIKELY(thr->heap->call_recursion_depth < thr->heap->call_recursion_limit)) {\n\t\treturn;\n\t}\n\n\tduk__call_c_recursion_limit_check_slowpath(thr);\n}\n\nDUK_LOCAL DUK_NOINLINE void duk__call_callstack_limit_check_slowpath(duk_hthread *thr) {\n\t/* When augmenting an error, the effective limit is a bit higher.\n\t * Check for it only if the fast path check fails.\n\t */\n#if defined(DUK_USE_AUGMENT_ERROR_THROW) || defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\tif (thr->heap->augmenting_error) {\n\t\tif (thr->callstack_top < DUK_USE_CALLSTACK_LIMIT + DUK__AUGMENT_CALL_RELAX_COUNT) {\n\t\t\tDUK_D(DUK_DPRINT(\"call stack limit reached but augmenting error and within relaxed limit\"));\n\t\t\treturn;\n\t\t}\n\t}\n#endif\n\n\t/* XXX: error message is a bit misleading: we reached a recursion\n\t * limit which is also essentially the same as a C callstack limit\n\t * (except perhaps with some relaxed threading assumptions).\n\t */\n\tDUK_D(DUK_DPRINT(\"call prevented because call stack limit reached\"));\n\tDUK_ERROR_RANGE(thr, DUK_STR_CALLSTACK_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE void duk__call_callstack_limit_check(duk_hthread *thr) {\n\t/* This check is forcibly inlined because it's very cheap and almost\n\t * always passes.  The slow path is forcibly noinline.\n\t */\n\tif (DUK_LIKELY(thr->callstack_top < DUK_USE_CALLSTACK_LIMIT)) {\n\t\treturn;\n\t}\n\n\tduk__call_callstack_limit_check_slowpath(thr);\n}\n\n/*\n *  Interrupt counter fixup (for development only).\n */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\nDUK_LOCAL void duk__interrupt_fixup(duk_hthread *thr, duk_hthread *entry_curr_thread) {\n\t/* Currently the bytecode executor and executor interrupt\n\t * instruction counts are off because we don't execute the\n\t * interrupt handler when we're about to exit from the initial\n\t * user call into Duktape.\n\t *\n\t * If we were to execute the interrupt handler here, the counts\n\t * would match.  You can enable this block manually to check\n\t * that this is the case.\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\n#if defined(DUK_USE_INTERRUPT_DEBUG_FIXUP)\n\tif (entry_curr_thread == NULL) {\n\t\tthr->interrupt_init = thr->interrupt_init - thr->interrupt_counter;\n\t\tthr->heap->inst_count_interrupt += thr->interrupt_init;\n\t\tDUK_DD(DUK_DDPRINT(\"debug test: updated interrupt count on exit to \"\n\t\t                   \"user code, instruction counts: executor=%ld, interrupt=%ld\",\n\t\t                   (long) thr->heap->inst_count_exec, (long) thr->heap->inst_count_interrupt));\n\t\tDUK_ASSERT(thr->heap->inst_count_exec == thr->heap->inst_count_interrupt);\n\t}\n#else\n\tDUK_UNREF(thr);\n\tDUK_UNREF(entry_curr_thread);\n#endif\n}\n#endif\n\n/*\n *  Arguments object creation.\n *\n *  Creating arguments objects involves many small details, see E5 Section\n *  10.6 for the specific requirements.  Much of the arguments object exotic\n *  behavior is implemented in duk_hobject_props.c, and is enabled by the\n *  object flag DUK_HOBJECT_FLAG_EXOTIC_ARGUMENTS.\n */\n\nDUK_LOCAL void duk__create_arguments_object(duk_hthread *thr,\n                                            duk_hobject *func,\n                                            duk_hobject *varenv,\n                                            duk_idx_t idx_args) {\n\tduk_hobject *arg;          /* 'arguments' */\n\tduk_hobject *formals;      /* formals for 'func' (may be NULL if func is a C function) */\n\tduk_idx_t i_arg;\n\tduk_idx_t i_map;\n\tduk_idx_t i_mappednames;\n\tduk_idx_t i_formals;\n\tduk_idx_t i_argbase;\n\tduk_idx_t n_formals;\n\tduk_idx_t idx;\n\tduk_idx_t num_stack_args;\n\tduk_bool_t need_map;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_NONBOUND_FUNCTION(func));\n\tDUK_ASSERT(varenv != NULL);\n\n\t/* [ ... func this arg1(@idx_args) ... argN envobj ]\n\t * [ arg1(@idx_args) ... argN envobj ] (for tailcalls)\n\t */\n\n\tneed_map = 0;\n\n\ti_argbase = idx_args;\n\tnum_stack_args = duk_get_top(thr) - i_argbase - 1;\n\tDUK_ASSERT(i_argbase >= 0);\n\tDUK_ASSERT(num_stack_args >= 0);\n\n\tformals = (duk_hobject *) duk_hobject_get_formals(thr, (duk_hobject *) func);\n\tif (formals) {\n\t\tn_formals = (duk_idx_t) ((duk_harray *) formals)->length;\n\t\tduk_push_hobject(thr, formals);\n\t} else {\n\t\t/* This shouldn't happen without tampering of internal\n\t\t * properties: if a function accesses 'arguments', _Formals\n\t\t * is kept.  Check for the case anyway in case internal\n\t\t * properties have been modified manually.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"_Formals is undefined when creating arguments, use n_formals == 0\"));\n\t\tn_formals = 0;\n\t\tduk_push_undefined(thr);\n\t}\n\ti_formals = duk_require_top_index(thr);\n\n\tDUK_ASSERT(n_formals >= 0);\n\tDUK_ASSERT(formals != NULL || n_formals == 0);\n\n\tDUK_DDD(DUK_DDDPRINT(\"func=%!O, formals=%!O, n_formals=%ld\",\n\t                     (duk_heaphdr *) func, (duk_heaphdr *) formals,\n\t                     (long) n_formals));\n\n\t/* [ ... formals ] */\n\n\t/*\n\t *  Create required objects:\n\t *    - 'arguments' object: array-like, but not an array\n\t *    - 'map' object: internal object, tied to 'arguments' (bare)\n\t *    - 'mappedNames' object: temporary value used during construction (bare)\n\t */\n\n\targ = duk_push_object_helper(thr,\n\t                             DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                             DUK_HOBJECT_FLAG_FASTREFS |\n\t                             DUK_HOBJECT_FLAG_ARRAY_PART |\n\t                             DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_ARGUMENTS),\n\t                             DUK_BIDX_OBJECT_PROTOTYPE);\n\tDUK_ASSERT(arg != NULL);\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              -1);  /* no prototype */\n\t(void) duk_push_object_helper(thr,\n\t                              DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                              DUK_HOBJECT_FLAG_FASTREFS |\n\t                              DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJECT),\n\t                              -1);  /* no prototype */\n\ti_arg = duk_get_top(thr) - 3;\n\ti_map = i_arg + 1;\n\ti_mappednames = i_arg + 2;\n\tDUK_ASSERT(!duk_is_bare_object(thr, -3));  /* arguments */\n\tDUK_ASSERT(duk_is_bare_object(thr, -2));  /* map */\n\tDUK_ASSERT(duk_is_bare_object(thr, -1));  /* mappedNames */\n\n\t/* [ ... formals arguments map mappedNames ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"created arguments related objects: \"\n\t                     \"arguments at index %ld -> %!O \"\n\t                     \"map at index %ld -> %!O \"\n\t                     \"mappednames at index %ld -> %!O\",\n\t                     (long) i_arg, (duk_heaphdr *) duk_get_hobject(thr, i_arg),\n\t                     (long) i_map, (duk_heaphdr *) duk_get_hobject(thr, i_map),\n\t                     (long) i_mappednames, (duk_heaphdr *) duk_get_hobject(thr, i_mappednames)));\n\n\t/*\n\t *  Init arguments properties, map, etc.\n\t */\n\n\tduk_push_int(thr, num_stack_args);\n\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_WC);\n\n\t/*\n\t *  Init argument related properties.\n\t */\n\n\t/* step 11 */\n\tidx = num_stack_args - 1;\n\twhile (idx >= 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"arg idx %ld, argbase=%ld, argidx=%ld\",\n\t\t                     (long) idx, (long) i_argbase, (long) (i_argbase + idx)));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"define arguments[%ld]=arg\", (long) idx));\n\t\tduk_dup(thr, i_argbase + idx);\n\t\tduk_xdef_prop_index_wec(thr, i_arg, (duk_uarridx_t) idx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"defined arguments[%ld]=arg\", (long) idx));\n\n\t\t/* step 11.c is relevant only if non-strict (checked in 11.c.ii) */\n\t\tif (!DUK_HOBJECT_HAS_STRICT(func) && idx < n_formals) {\n\t\t\tDUK_ASSERT(formals != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"strict function, index within formals (%ld < %ld)\",\n\t\t\t                     (long) idx, (long) n_formals));\n\n\t\t\tduk_get_prop_index(thr, i_formals, (duk_uarridx_t) idx);\n\t\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\n\t\t\tduk_dup_top(thr);  /* [ ... name name ] */\n\n\t\t\tif (!duk_has_prop(thr, i_mappednames)) {\n\t\t\t\t/* steps 11.c.ii.1 - 11.c.ii.4, but our internal book-keeping\n\t\t\t\t * differs from the reference model\n\t\t\t\t */\n\n\t\t\t\t/* [ ... name ] */\n\n\t\t\t\tneed_map = 1;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"set mappednames[%s]=%ld\",\n\t\t\t\t                     (const char *) duk_get_string(thr, -1),\n\t\t\t\t                     (long) idx));\n\t\t\t\tduk_dup_top(thr);                      /* name */\n\t\t\t\t(void) duk_push_uint_to_hstring(thr, (duk_uint_t) idx);  /* index */\n\t\t\t\tduk_xdef_prop_wec(thr, i_mappednames);  /* out of spec, must be configurable */\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"set map[%ld]=%s\",\n\t\t\t\t                     (long) idx,\n\t\t\t\t                     duk_get_string(thr, -1)));\n\t\t\t\tduk_dup_top(thr);         /* name */\n\t\t\t\tduk_xdef_prop_index_wec(thr, i_map, (duk_uarridx_t) idx);  /* out of spec, must be configurable */\n\t\t\t} else {\n\t\t\t\t/* duk_has_prop() popped the second 'name' */\n\t\t\t}\n\n\t\t\t/* [ ... name ] */\n\t\t\tduk_pop(thr);  /* pop 'name' */\n\t\t}\n\n\t\tidx--;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"actual arguments processed\"));\n\n\t/* step 12 */\n\tif (need_map) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"adding 'map' and 'varenv' to arguments object\"));\n\n\t\t/* should never happen for a strict callee */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(func));\n\n\t\tduk_dup(thr, i_map);\n\t\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_INT_MAP, DUK_PROPDESC_FLAGS_NONE);  /* out of spec, don't care */\n\n\t\t/* The variable environment for magic variable bindings needs to be\n\t\t * given by the caller and recorded in the arguments object.\n\t\t *\n\t\t * See E5 Section 10.6, the creation of setters/getters.\n\t\t *\n\t\t * The variable environment also provides access to the callee, so\n\t\t * an explicit (internal) callee property is not needed.\n\t\t */\n\n\t\tduk_push_hobject(thr, varenv);\n\t\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_INT_VARENV, DUK_PROPDESC_FLAGS_NONE);  /* out of spec, don't care */\n\t}\n\n\t/* steps 13-14 */\n\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t/* Callee/caller are throwers and are not deletable etc.  They\n\t\t * could be implemented as virtual properties, but currently\n\t\t * there is no support for virtual properties which are accessors\n\t\t * (only plain virtual properties).  This would not be difficult\n\t\t * to change in duk_hobject_props, but we can make the throwers\n\t\t * normal, concrete properties just as easily.\n\t\t *\n\t\t * Note that the specification requires that the *same* thrower\n\t\t * built-in object is used here!  See E5 Section 10.6 main\n\t\t * algoritm, step 14, and Section 13.2.3 which describes the\n\t\t * thrower.  See test case test-arguments-throwers.js.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"strict function, setting caller/callee to throwers\"));\n\n\t\t/* In ES2017 .caller is no longer set at all. */\n\t\tduk_xdef_prop_stridx_thrower(thr, i_arg, DUK_STRIDX_CALLEE);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-strict function, setting callee to actual value\"));\n\t\tduk_push_hobject(thr, func);\n\t\tduk_xdef_prop_stridx(thr, i_arg, DUK_STRIDX_CALLEE, DUK_PROPDESC_FLAGS_WC);\n\t}\n\n\t/* set exotic behavior only after we're done */\n\tif (need_map) {\n\t\t/* Exotic behaviors are only enabled for arguments objects\n\t\t * which have a parameter map (see E5 Section 10.6 main\n\t\t * algorithm, step 12).\n\t\t *\n\t\t * In particular, a non-strict arguments object with no\n\t\t * mapped formals does *NOT* get exotic behavior, even\n\t\t * for e.g. \"caller\" property.  This seems counterintuitive\n\t\t * but seems to be the case.\n\t\t */\n\n\t\t/* cannot be strict (never mapped variables) */\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(func));\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"enabling exotic behavior for arguments object\"));\n\t\tDUK_HOBJECT_SET_EXOTIC_ARGUMENTS(arg);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"not enabling exotic behavior for arguments object\"));\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"final arguments related objects: \"\n\t                     \"arguments at index %ld -> %!O \"\n\t                     \"map at index %ld -> %!O \"\n\t                     \"mappednames at index %ld -> %!O\",\n\t                     (long) i_arg, (duk_heaphdr *) duk_get_hobject(thr, i_arg),\n\t                     (long) i_map, (duk_heaphdr *) duk_get_hobject(thr, i_map),\n\t                     (long) i_mappednames, (duk_heaphdr *) duk_get_hobject(thr, i_mappednames)));\n\n\t/* [ args(n) envobj formals arguments map mappednames ] */\n\n\tduk_pop_2(thr);\n\tduk_remove_m2(thr);\n\n\t/* [ args(n) envobj arguments ] */\n}\n\n/* Helper for creating the arguments object and adding it to the env record\n * on top of the value stack.\n */\nDUK_LOCAL void duk__handle_createargs_for_call(duk_hthread *thr,\n                                               duk_hobject *func,\n                                               duk_hobject *env,\n                                               duk_idx_t idx_args) {\n\tDUK_DDD(DUK_DDDPRINT(\"creating arguments object for function call\"));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_CREATEARGS(func));\n\n\t/* [ ... arg1 ... argN envobj ] */\n\n\tduk__create_arguments_object(thr,\n\t                             func,\n\t                             env,\n\t                             idx_args);\n\n\t/* [ ... arg1 ... argN envobj argobj ] */\n\n\tduk_xdef_prop_stridx_short(thr,\n\t                           -2,\n\t                           DUK_STRIDX_LC_ARGUMENTS,\n\t                           DUK_HOBJECT_HAS_STRICT(func) ? DUK_PROPDESC_FLAGS_E :   /* strict: non-deletable, non-writable */\n\t                                                          DUK_PROPDESC_FLAGS_WE);  /* non-strict: non-deletable, writable */\n\t/* [ ... arg1 ... argN envobj ] */\n}\n\n/*\n *  Helpers for constructor call handling.\n *\n *  There are two [[Construct]] operations in the specification:\n *\n *    - E5 Section 13.2.2: for Function objects\n *    - E5 Section 15.3.4.5.2: for \"bound\" Function objects\n *\n *  The chain of bound functions is resolved in Section 15.3.4.5.2,\n *  with arguments \"piling up\" until the [[Construct]] internal\n *  method is called on the final, actual Function object.  Note\n *  that the \"prototype\" property is looked up *only* from the\n *  final object, *before* calling the constructor.\n *\n *  Since Duktape 2.2 bound functions are represented with the\n *  duk_hboundfunc internal type, and bound function chains are\n *  collapsed when a bound function is created.  As a result, the\n *  direct target of a duk_hboundfunc is always non-bound and the\n *  this/argument lists have been resolved.\n *\n *  When constructing new Array instances, an unnecessary object is\n *  created and discarded now: the standard [[Construct]] creates an\n *  object, and calls the Array constructor.  The Array constructor\n *  returns an Array instance, which is used as the result value for\n *  the \"new\" operation; the object created before the Array constructor\n *  call is discarded.\n *\n *  This would be easy to fix, e.g. by knowing that the Array constructor\n *  will always create a replacement object and skip creating the fallback\n *  object in that case.\n */\n\n/* Update default instance prototype for constructor call. */\nDUK_LOCAL void duk__update_default_instance_proto(duk_hthread *thr, duk_idx_t idx_func) {\n\tduk_hobject *proto;\n\tduk_hobject *fallback;\n\n\tDUK_ASSERT(duk_is_constructable(thr, idx_func));\n\n\tduk_get_prop_stridx_short(thr, idx_func, DUK_STRIDX_PROTOTYPE);\n\tproto = duk_get_hobject(thr, -1);\n\tif (proto == NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"constructor has no 'prototype' property, or value not an object \"\n\t\t                     \"-> leave standard Object prototype as fallback prototype\"));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"constructor has 'prototype' property with object value \"\n\t\t                     \"-> set fallback prototype to that value: %!iO\", (duk_heaphdr *) proto));\n\t\t/* Original fallback (default instance) is untouched when\n\t\t * resolving bound functions etc.\n\t\t */\n\t\tfallback = duk_known_hobject(thr, idx_func + 1);\n\t\tDUK_ASSERT(fallback != NULL);\n\t\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, fallback, proto);\n\t}\n\tduk_pop(thr);\n}\n\n/* Postprocess: return value special handling, error augmentation. */\nDUK_INTERNAL void duk_call_construct_postprocess(duk_hthread *thr, duk_small_uint_t proxy_invariant) {\n\t/* Use either fallback (default instance) or retval depending\n\t * on retval type.  Needs to be called before unwind because\n\t * the default instance is read from the current (immutable)\n\t * 'this' binding.\n\t *\n\t * For Proxy 'construct' calls the return value must be an\n\t * Object (we accept object-like values like buffers and\n\t * lightfuncs too).  If not, TypeError.\n\t */\n\tif (duk_check_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT |\n\t                                 DUK_TYPE_MASK_BUFFER |\n\t                                 DUK_TYPE_MASK_LIGHTFUNC)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"replacement value\"));\n\t} else {\n\t\tif (DUK_UNLIKELY(proxy_invariant != 0U)) {\n\t\t\t/* Proxy 'construct' return value invariant violated. */\n\t\t\tDUK_ERROR_TYPE_INVALID_TRAP_RESULT(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\t/* XXX: direct value stack access */\n\t\tduk_pop(thr);\n\t\tduk_push_this(thr);\n\t}\n\n#if defined(DUK_USE_AUGMENT_ERROR_CREATE)\n\t/* Augment created errors upon creation, not when they are thrown or\n\t * rethrown.  __FILE__ and __LINE__ are not desirable here; the call\n\t * stack reflects the caller which is correct.  Skip topmost, unwound\n\t * activation when creating a traceback.  If thr->ptr_curr_pc was !=\n\t * NULL we'd need to sync the current PC so that the traceback comes\n\t * out right; however it is always synced here so just assert for it.\n\t */\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\tduk_err_augment_error_create(thr, thr, NULL, 0, DUK_AUGMENT_FLAG_NOBLAME_FILELINE |\n\t                                                DUK_AUGMENT_FLAG_SKIP_ONE);\n#endif\n}\n\n/*\n *  Helper for handling a bound function when a call is being made.\n *\n *  Assumes that bound function chains have been \"collapsed\" so that either\n *  the target is non-bound or there is one bound function that points to a\n *  nonbound target.\n *\n *  Prepends the bound arguments to the value stack (at idx_func + 2).\n *  The 'this' binding is also updated if necessary (at idx_func + 1).\n *  Note that for constructor calls the 'this' binding is never updated by\n *  [[BoundThis]].\n */\n\nDUK_LOCAL void duk__handle_bound_chain_for_call(duk_hthread *thr,\n                                                duk_idx_t idx_func,\n                                                duk_bool_t is_constructor_call) {\n\tduk_tval *tv_func;\n\tduk_hobject *func;\n\tduk_idx_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* On entry, item at idx_func is a bound, non-lightweight function,\n\t * but we don't rely on that below.\n\t */\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\ttv_func = duk_require_tval(thr, idx_func);\n\tDUK_ASSERT(tv_func != NULL);\n\n\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\n\t\t/* XXX: separate helper function, out of fast path? */\n\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {\n\t\t\tduk_hboundfunc *h_bound;\n\t\t\tduk_tval *tv_args;\n\t\t\tduk_tval *tv_gap;\n\n\t\t\th_bound = (duk_hboundfunc *) (void *) func;\n\t\t\ttv_args = h_bound->args;\n\t\t\tlen = h_bound->nargs;\n\t\t\tDUK_ASSERT(len == 0 || tv_args != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"bound function encountered, ptr=%p: %!T\",\n\t\t\t                     (void *) DUK_TVAL_GET_OBJECT(tv_func), tv_func));\n\n\t\t\t/* [ ... func this arg1 ... argN ] */\n\n\t\t\tif (is_constructor_call) {\n\t\t\t\t/* See: tests/ecmascript/test-spec-bound-constructor.js */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"constructor call: don't update this binding\"));\n\t\t\t} else {\n\t\t\t\t/* XXX: duk_replace_tval */\n\t\t\t\tduk_push_tval(thr, &h_bound->this_binding);\n\t\t\t\tduk_replace(thr, idx_func + 1);  /* idx_this = idx_func + 1 */\n\t\t\t}\n\n\t\t\t/* [ ... func this arg1 ... argN ] */\n\n\t\t\tduk_require_stack(thr, len);\n\n\t\t\ttv_gap = duk_reserve_gap(thr, idx_func + 2, len);\n\t\t\tduk_copy_tvals_incref(thr, tv_gap, tv_args, (duk_size_t) len);\n\n\t\t\t/* [ ... func this <bound args> arg1 ... argN ] */\n\n\t\t\tduk_push_tval(thr, &h_bound->target);\n\t\t\tduk_replace(thr, idx_func);  /* replace in stack */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"bound function handled, idx_func=%ld, curr func=%!T\",\n\t\t\t                     (long) idx_func, duk_get_tval(thr, idx_func)));\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {\n\t\t/* Lightweight function: never bound, so terminate. */\n\t\t;\n\t} else {\n\t\t/* Shouldn't happen, so ugly error is enough. */\n\t\tDUK_ERROR_INTERNAL(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\tDUK_DDD(DUK_DDDPRINT(\"final non-bound function is: %!T\", duk_get_tval(thr, idx_func)));\n\n#if defined(DUK_USE_ASSERTIONS)\n\ttv_func = duk_require_tval(thr, idx_func);\n\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func) || DUK_TVAL_IS_OBJECT(tv_func));\n\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func) ||\n\t\t           DUK_HOBJECT_HAS_NATFUNC(func) ||\n\t\t           DUK_HOBJECT_IS_PROXY(func));\n\t}\n#endif\n}\n\n/*\n *  Helper for inline handling of .call(), .apply(), and .construct().\n */\n\nDUK_LOCAL duk_bool_t duk__handle_specialfuncs_for_call(duk_hthread *thr, duk_idx_t idx_func, duk_hobject *func, duk_small_uint_t *call_flags, duk_bool_t first) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_c_function natfunc;\n#endif\n\tduk_tval *tv_args;\n\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT((*call_flags & DUK_CALL_FLAG_CONSTRUCT) == 0);  /* Caller. */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tnatfunc = ((duk_hnatfunc *) func)->func;\n\tDUK_ASSERT(natfunc != NULL);\n#endif\n\n\t/* On every round of function resolution at least target function and\n\t * 'this' binding are set.  We can assume that here, and must guarantee\n\t * it on exit.  Value stack reserve is extended for bound function and\n\t * .apply() unpacking so we don't need to extend it here when we need a\n\t * few slots.\n\t */\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\t/* Handle native 'eval' specially.  A direct eval check is only made\n\t * for the first resolution attempt; e.g. a bound eval call is -not-\n\t * a direct eval call.\n\t */\n\tif (DUK_UNLIKELY(((duk_hnatfunc *) func)->magic == 15)) {\n\t\t/* For now no special handling except for direct eval\n\t\t * detection.\n\t\t */\n\t\tDUK_ASSERT(((duk_hnatfunc *) func)->func == duk_bi_global_object_eval);\n\t\tif (first && (*call_flags & DUK_CALL_FLAG_CALLED_AS_EVAL)) {\n\t\t\t*call_flags = (*call_flags & ~DUK_CALL_FLAG_CALLED_AS_EVAL) | DUK_CALL_FLAG_DIRECT_EVAL;\n\t\t}\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\t\treturn 1;  /* stop resolving */\n\t}\n\n\t/* Handle special functions based on the DUK_HOBJECT_FLAG_SPECIAL_CALL\n\t * flag; their magic value is used for switch-case.\n\t *\n\t * NOTE: duk_unpack_array_like() reserves value stack space\n\t * for the result values (unlike most other value stack calls).\n\t */\n\tswitch (((duk_hnatfunc *) func)->magic) {\n\tcase 0: {  /* 0=Function.prototype.call() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Function.prototype.call()  [removed]\n\t\t * idx_func + 1: this binding for .call (target function)\n\t\t * idx_func + 2: 1st argument to .call, desired 'this' binding\n\t\t * idx_func + 3: 2nd argument to .call, desired 1st argument for ultimate target\n\t\t * ...\n\t\t *\n\t\t * Remove idx_func + 0 to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding\n\t\t * idx_func + 2: call arguments\n\t\t * ...\n\t\t */\n\t\tDUK_ASSERT(natfunc == duk_bi_function_prototype_call);\n\t\tduk_remove_unsafe(thr, idx_func);\n\t\ttv_args = thr->valstack_bottom + idx_func + 2;\n\t\tif (thr->valstack_top < tv_args) {\n\t\t\tDUK_ASSERT(tv_args <= thr->valstack_end);\n\t\t\tthr->valstack_top = tv_args;  /* at least target function and 'this' binding present */\n\t\t}\n\t\tbreak;\n\t}\n\tcase 1: {  /* 1=Function.prototype.apply() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Function.prototype.apply()  [removed]\n\t\t * idx_func + 1: this binding for .apply (target function)\n\t\t * idx_func + 2: 1st argument to .apply, desired 'this' binding\n\t\t * idx_func + 3: 2nd argument to .apply, argArray\n\t\t * [anything after this MUST be ignored]\n\t\t *\n\t\t * Remove idx_func + 0 and unpack the argArray to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding\n\t\t * idx_func + 2: call arguments\n\t\t * ...\n\t\t */\n\t\tDUK_ASSERT(natfunc == duk_bi_function_prototype_apply);\n\t\tduk_remove_unsafe(thr, idx_func);\n\t\tgoto apply_shared;\n\t}\n#if defined(DUK_USE_REFLECT_BUILTIN)\n\tcase 2: {  /* 2=Reflect.apply() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Reflect.apply()  [removed]\n\t\t * idx_func + 1: this binding for .apply (ignored, usually Reflect)  [removed]\n\t\t * idx_func + 2: 1st argument to .apply, target function\n\t\t * idx_func + 3: 2nd argument to .apply, desired 'this' binding\n\t\t * idx_func + 4: 3rd argument to .apply, argArray\n\t\t * [anything after this MUST be ignored]\n\t\t *\n\t\t * Remove idx_func + 0 and idx_func + 1, and unpack the argArray to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding\n\t\t * idx_func + 2: call arguments\n\t\t * ...\n\t\t */\n\t\tDUK_ASSERT(natfunc == duk_bi_reflect_apply);\n\t\tduk_remove_n_unsafe(thr, idx_func, 2);\n\t\tgoto apply_shared;\n\t}\n\tcase 3: {  /* 3=Reflect.construct() */\n\t\t/* Value stack:\n\t\t * idx_func + 0: Reflect.construct()  [removed]\n\t\t * idx_func + 1: this binding for .construct (ignored, usually Reflect)  [removed]\n\t\t * idx_func + 2: 1st argument to .construct, target function\n\t\t * idx_func + 3: 2nd argument to .construct, argArray\n\t\t * idx_func + 4: 3rd argument to .construct, newTarget\n\t\t * [anything after this MUST be ignored]\n\t\t *\n\t\t * Remove idx_func + 0 and idx_func + 1, unpack the argArray,\n\t\t * and insert default instance (prototype not yet updated), to get:\n\t\t * idx_func + 0: target function\n\t\t * idx_func + 1: this binding (default instance)\n\t\t * idx_func + 2: constructor call arguments\n\t\t * ...\n\t\t *\n\t\t * Call flags must be updated to reflect the fact that we're\n\t\t * now dealing with a constructor call, and e.g. the 'this'\n\t\t * binding cannot be overwritten if the target is bound.\n\t\t *\n\t\t * newTarget is checked but not yet passed onwards.\n\t\t */\n\n\t\tduk_idx_t top;\n\n\t\tDUK_ASSERT(natfunc == duk_bi_reflect_construct);\n\t\t*call_flags |= DUK_CALL_FLAG_CONSTRUCT;\n\t\tduk_remove_n_unsafe(thr, idx_func, 2);\n\t\ttop = duk_get_top(thr);\n\t\tif (!duk_is_constructable(thr, idx_func)) {\n\t\t\t/* Target constructability must be checked before\n\t\t\t * unpacking argArray (which may cause side effects).\n\t\t\t * Just return; caller will throw the error.\n\t\t\t */\n\t\t\tduk_set_top_unsafe(thr, idx_func + 2);  /* satisfy asserts */\n\t\t\tbreak;\n\t\t}\n\t\tduk_push_object(thr);\n\t\tduk_insert(thr, idx_func + 1);  /* default instance */\n\n\t\t/* [ ... func default_instance argArray newTarget? ] */\n\n\t\ttop = duk_get_top(thr);\n\t\tif (top < idx_func + 3) {\n\t\t\t/* argArray is a mandatory argument for Reflect.construct(). */\n\t\t\tDUK_ERROR_TYPE_INVALID_ARGS(thr);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t\tif (top > idx_func + 3) {\n\t\t\tif (!duk_strict_equals(thr, idx_func, idx_func + 3)) {\n\t\t\t\t/* XXX: [[Construct]] newTarget currently unsupported */\n\t\t\t\tDUK_ERROR_UNSUPPORTED(thr);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\t\t\tduk_set_top_unsafe(thr, idx_func + 3);  /* remove any args beyond argArray */\n\t\t}\n\t\tDUK_ASSERT(duk_get_top(thr) == idx_func + 3);\n\t\tDUK_ASSERT(duk_is_valid_index(thr, idx_func + 2));\n\t\t(void) duk_unpack_array_like(thr, idx_func + 2);  /* XXX: should also remove target to be symmetric with duk_pack()? */\n\t\tduk_remove(thr, idx_func + 2);\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\t\tbreak;\n\t}\n#endif  /* DUK_USE_REFLECT_BUILTIN */\n\tdefault: {\n\t\tDUK_ASSERT(0);\n\t\tDUK_UNREACHABLE();\n\t}\n\t}\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\treturn 0;  /* keep resolving */\n\n apply_shared:\n\ttv_args = thr->valstack_bottom + idx_func + 2;\n\tif (thr->valstack_top <= tv_args) {\n\t\tDUK_ASSERT(tv_args <= thr->valstack_end);\n\t\tthr->valstack_top = tv_args;  /* at least target func and 'this' binding present */\n\t\t/* No need to check for argArray. */\n\t} else {\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 3);  /* idx_func + 2 covered above */\n\t\tif (thr->valstack_top > tv_args + 1) {\n\t\t\tduk_set_top_unsafe(thr, idx_func + 3);  /* remove any args beyond argArray */\n\t\t}\n\t\tDUK_ASSERT(duk_is_valid_index(thr, idx_func + 2));\n\t\tif (!duk_is_callable(thr, idx_func)) {\n\t\t\t/* Avoid unpack side effects if the target isn't callable.\n\t\t\t * Calling code will throw the actual error.\n\t\t\t */\n\t\t} else {\n\t\t\t(void) duk_unpack_array_like(thr, idx_func + 2);\n\t\t\tduk_remove(thr, idx_func + 2);\n\t\t}\n\t}\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\treturn 0;  /* keep resolving */\n}\n\n/*\n *  Helper for Proxy handling.\n */\n\n#if defined(DUK_USE_ES6_PROXY)\nDUK_LOCAL void duk__handle_proxy_for_call(duk_hthread *thr, duk_idx_t idx_func, duk_hproxy *h_proxy, duk_small_uint_t *call_flags) {\n\tduk_bool_t rc;\n\n\t/* Value stack:\n\t * idx_func + 0: Proxy object\n\t * idx_func + 1: this binding for call\n\t * idx_func + 2: 1st argument for call\n\t * idx_func + 3: 2nd argument for call\n\t * ...\n\t *\n\t * If Proxy doesn't have a trap for the call ('apply' or 'construct'),\n\t * replace Proxy object with target object.\n\t *\n\t * If we're dealing with a normal call and the Proxy has an 'apply'\n\t * trap, manipulate value stack to:\n\t *\n\t * idx_func + 0: trap\n\t * idx_func + 1: Proxy's handler\n\t * idx_func + 2: Proxy's target\n\t * idx_func + 3: this binding for call (from idx_func + 1)\n\t * idx_func + 4: call arguments packed to an array\n\t *\n\t * If we're dealing with a constructor call and the Proxy has a\n\t * 'construct' trap, manipulate value stack to:\n\t *\n\t * idx_func + 0: trap\n\t * idx_func + 1: Proxy's handler\n\t * idx_func + 2: Proxy's target\n\t * idx_func + 3: call arguments packed to an array\n\t * idx_func + 4: newTarget == Proxy object here\n\t *\n\t * As we don't yet have proper newTarget support, the newTarget at\n\t * idx_func + 3 is just the original constructor being called, i.e.\n\t * the Proxy object (not the target).  Note that the default instance\n\t * (original 'this' binding) is dropped and ignored.\n\t */\n\n\tduk_push_hobject(thr, h_proxy->handler);\n\trc = duk_get_prop_stridx_short(thr, -1, (*call_flags & DUK_CALL_FLAG_CONSTRUCT) ? DUK_STRIDX_CONSTRUCT : DUK_STRIDX_APPLY);\n\tif (rc == 0) {\n\t\t/* Not found, continue to target.  If this is a construct\n\t\t * call, update default instance prototype using the Proxy,\n\t\t * not the target.\n\t\t */\n\t\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\t\tif (!(*call_flags & DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED)) {\n\t\t\t\t*call_flags |= DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED;\n\t\t\t\tduk__update_default_instance_proto(thr, idx_func);\n\t\t\t}\n\t\t}\n\t\tduk_pop_2(thr);\n\t\tduk_push_hobject(thr, h_proxy->target);\n\t\tduk_replace(thr, idx_func);\n\t\treturn;\n\t}\n\n\t/* Here we must be careful not to replace idx_func while\n\t * h_proxy is still needed, otherwise h_proxy may become\n\t * dangling.  This could be improved e.g. using a\n\t * duk_pack_slice() with a freeform slice.\n\t */\n\n\t/* Here:\n\t * idx_func + 0: Proxy object\n\t * idx_func + 1: this binding for call\n\t * idx_func + 2: 1st argument for call\n\t * idx_func + 3: 2nd argument for call\n\t * ...\n\t * idx_func + N: handler\n\t * idx_func + N + 1: trap\n\t */\n\n\tduk_insert(thr, idx_func + 1);\n\tduk_insert(thr, idx_func + 2);\n\tduk_push_hobject(thr, h_proxy->target);\n\tduk_insert(thr, idx_func + 3);\n\tduk_pack(thr, duk_get_top(thr) - (idx_func + 5));\n\tDUK_ASSERT(!duk_is_bare_object(thr, -1));\n\n\t/* Here:\n\t * idx_func + 0: Proxy object\n\t * idx_func + 1: trap\n\t * idx_func + 2: Proxy's handler\n\t * idx_func + 3: Proxy's target\n\t * idx_func + 4: this binding for call\n\t * idx_func + 5: arguments array\n\t */\n\tDUK_ASSERT(duk_get_top(thr) == idx_func + 6);\n\n\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\t*call_flags |= DUK_CALL_FLAG_CONSTRUCT_PROXY;  /* Enable 'construct' trap return invariant check. */\n\t\t*call_flags &= ~(DUK_CALL_FLAG_CONSTRUCT);     /* Resume as non-constructor call to the trap. */\n\n\t\t/* 'apply' args: target, thisArg, argArray\n\t\t * 'construct' args: target, argArray, newTarget\n\t\t */\n\t\tduk_remove(thr, idx_func + 4);\n\t\tduk_push_hobject(thr, (duk_hobject *) h_proxy);\n\t}\n\n\t/* Finalize value stack layout by removing Proxy reference. */\n\tduk_remove(thr, idx_func);\n\th_proxy = NULL;  /* invalidated */\n\tDUK_ASSERT(duk_get_top(thr) == idx_func + 5);\n}\n#endif  /* DUK_USE_ES6_PROXY */\n\n/*\n *  Helper for setting up var_env and lex_env of an activation,\n *  assuming it does NOT have the DUK_HOBJECT_FLAG_NEWENV flag.\n */\n\nDUK_LOCAL void duk__handle_oldenv_for_call(duk_hthread *thr,\n                                           duk_hobject *func,\n                                           duk_activation *act) {\n\tduk_hcompfunc *f;\n\tduk_hobject *h_lex;\n\tduk_hobject *h_var;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV(func));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(func));\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(func));\n\tDUK_UNREF(thr);\n\n\tf = (duk_hcompfunc *) func;\n\th_lex = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f);\n\th_var = DUK_HCOMPFUNC_GET_VARENV(thr->heap, f);\n\tDUK_ASSERT(h_lex != NULL);  /* Always true for closures (not for templates) */\n\tDUK_ASSERT(h_var != NULL);\n\tact->lex_env = h_lex;\n\tact->var_env = h_var;\n\tDUK_HOBJECT_INCREF(thr, h_lex);\n\tDUK_HOBJECT_INCREF(thr, h_var);\n}\n\n/*\n *  Helper for updating callee 'caller' property.\n */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\nDUK_LOCAL void duk__update_func_caller_prop(duk_hthread *thr, duk_hobject *func) {\n\tduk_tval *tv_caller;\n\tduk_hobject *h_tmp;\n\tduk_activation *act_callee;\n\tduk_activation *act_caller;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));  /* bound chain resolved */\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\n\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t/* Strict functions don't get their 'caller' updated. */\n\t\treturn;\n\t}\n\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tact_callee = thr->callstack_curr;\n\tDUK_ASSERT(act_callee != NULL);\n\tact_caller = (thr->callstack_top >= 2 ? act_callee->parent : NULL);\n\n\t/* XXX: check .caller writability? */\n\n\t/* Backup 'caller' property and update its value. */\n\ttv_caller = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, func, DUK_STRIDX_CALLER);\n\tif (tv_caller) {\n\t\t/* If caller is global/eval code, 'caller' should be set to\n\t\t * 'null'.\n\t\t *\n\t\t * XXX: there is no exotic flag to infer this correctly now.\n\t\t * The NEWENV flag is used now which works as intended for\n\t\t * everything (global code, non-strict eval code, and functions)\n\t\t * except strict eval code.  Bound functions are never an issue\n\t\t * because 'func' has been resolved to a non-bound function.\n\t\t */\n\n\t\tif (act_caller != NULL) {\n\t\t\t/* act_caller->func may be NULL in some finalization cases,\n\t\t\t * just treat like we don't know the caller.\n\t\t\t */\n\t\t\tif (act_caller->func && !DUK_HOBJECT_HAS_NEWENV(act_caller->func)) {\n\t\t\t\t/* Setting to NULL causes 'caller' to be set to\n\t\t\t\t * 'null' as desired.\n\t\t\t\t */\n\t\t\t\tact_caller = NULL;\n\t\t\t}\n\t\t}\n\n\t\tif (DUK_TVAL_IS_OBJECT(tv_caller)) {\n\t\t\th_tmp = DUK_TVAL_GET_OBJECT(tv_caller);\n\t\t\tDUK_ASSERT(h_tmp != NULL);\n\t\t\tact_callee->prev_caller = h_tmp;\n\n\t\t\t/* Previous value doesn't need refcount changes because its ownership\n\t\t\t * is transferred to prev_caller.\n\t\t\t */\n\n\t\t\tif (act_caller != NULL) {\n\t\t\t\tDUK_ASSERT(act_caller->func != NULL);\n\t\t\t\tDUK_TVAL_SET_OBJECT(tv_caller, act_caller->func);\n\t\t\t\tDUK_TVAL_INCREF(thr, tv_caller);\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_NULL(tv_caller);  /* no incref */\n\t\t\t}\n\t\t} else {\n\t\t\t/* 'caller' must only take on 'null' or function value */\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_caller));\n\t\t\tDUK_ASSERT(act_callee->prev_caller == NULL);\n\t\t\tif (act_caller != NULL && act_caller->func) {\n\t\t\t\t/* Tolerate act_caller->func == NULL which happens in\n\t\t\t\t * some finalization cases; treat like unknown caller.\n\t\t\t\t */\n\t\t\t\tDUK_TVAL_SET_OBJECT(tv_caller, act_caller->func);\n\t\t\t\tDUK_TVAL_INCREF(thr, tv_caller);\n\t\t\t} else {\n\t\t\t\tDUK_TVAL_SET_NULL(tv_caller);  /* no incref */\n\t\t\t}\n\t\t}\n\t}\n}\n#endif  /* DUK_USE_NONSTD_FUNC_CALLER_PROPERTY */\n\n/*\n *  Shared helpers for resolving the final, non-bound target function of the\n *  call and the effective 'this' binding.  Resolves bound functions and\n *  applies .call(), .apply(), and .construct() inline.\n *\n *  Proxy traps are also handled inline so that if the target is a Proxy with\n *  a 'call' or 'construct' trap, the trap handler is called with a modified\n *  argument list.\n *\n *  Once the bound function / .call() / .apply() / .construct() sequence has\n *  been resolved, the value at idx_func + 1 may need coercion described in\n *  E5 Section 10.4.3.\n *\n *  A call that begins as a non-constructor call may be converted into a\n *  constructor call during the resolution process if Reflect.construct()\n *  is invoked.  This is handled by updating the caller's call_flags.\n *\n *  For global and eval code (E5 Sections 10.4.1 and 10.4.2), we assume\n *  that the caller has provided the correct 'this' binding explicitly\n *  when calling, i.e.:\n *\n *    - global code: this=global object\n *    - direct eval: this=copy from eval() caller's this binding\n *    - other eval:  this=global object\n *\n *  The 'this' coercion may cause a recursive function call with arbitrary\n *  side effects, because ToObject() may be called.\n */\n\nDUK_LOCAL DUK_INLINE void duk__coerce_nonstrict_this_binding(duk_hthread *thr, duk_idx_t idx_this) {\n\tduk_tval *tv_this;\n\tduk_hobject *obj_global;\n\n\ttv_this = thr->valstack_bottom + idx_this;\n\tswitch (DUK_TVAL_GET_TAG(tv_this)) {\n\tcase DUK_TAG_OBJECT:\n\t\tDUK_DDD(DUK_DDDPRINT(\"this binding: non-strict, object -> use directly\"));\n\t\tbreak;\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\t\tDUK_DDD(DUK_DDDPRINT(\"this binding: non-strict, undefined/null -> use global object\"));\n\t\tobj_global = thr->builtins[DUK_BIDX_GLOBAL];\n\t\t/* XXX: avoid this check somehow */\n\t\tif (DUK_LIKELY(obj_global != NULL)) {\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_this));  /* no need to decref previous value */\n\t\t\tDUK_TVAL_SET_OBJECT(tv_this, obj_global);\n\t\t\tDUK_HOBJECT_INCREF(thr, obj_global);\n\t\t} else {\n\t\t\t/* This may only happen if built-ins are being \"torn down\".\n\t\t\t * This behavior is out of specification scope.\n\t\t\t */\n\t\t\tDUK_D(DUK_DPRINT(\"this binding: wanted to use global object, but it is NULL -> using undefined instead\"));\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv_this));  /* no need to decref previous value */\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv_this);  /* nothing to incref */\n\t\t}\n\t\tbreak;\n\tdefault:\n\t\t/* Plain buffers and lightfuncs are object coerced.  Lightfuncs\n\t\t * very rarely come here however, because the call target would\n\t\t * need to be a non-strict non-lightfunc (lightfuncs are considered\n\t\t * strict) with an explicit lightfunc 'this' binding.\n\t\t */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_this));\n\t\tDUK_DDD(DUK_DDDPRINT(\"this binding: non-strict, not object/undefined/null -> use ToObject(value)\"));\n\t\tduk_to_object(thr, idx_this);  /* may have side effects */\n\t\tbreak;\n\t}\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_bool_t duk__resolve_target_fastpath_check(duk_hthread *thr, duk_idx_t idx_func, duk_hobject **out_func, duk_small_uint_t call_flags) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tDUK_UNREF(thr);\n\tDUK_UNREF(idx_func);\n\tDUK_UNREF(out_func);\n\tDUK_UNREF(call_flags);\n#else  /* DUK_USE_PREFER_SIZE */\n\tduk_tval *tv_func;\n\tduk_hobject *func;\n\n\tif (DUK_UNLIKELY(call_flags & DUK_CALL_FLAG_CONSTRUCT)) {\n\t\treturn 0;\n\t}\n\n\ttv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);\n\tDUK_ASSERT(tv_func != NULL);\n\n\tif (DUK_LIKELY(DUK_TVAL_IS_OBJECT(tv_func))) {\n\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\t\tif (DUK_HOBJECT_IS_CALLABLE(func) &&\n\t\t    !DUK_HOBJECT_HAS_BOUNDFUNC(func) &&\n\t\t    !DUK_HOBJECT_HAS_SPECIAL_CALL(func)) {\n\t\t\t*out_func = func;\n\n\t\t\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t\t\t/* Strict function: no 'this' coercion. */\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tduk__coerce_nonstrict_this_binding(thr, idx_func + 1);\n\t\t\treturn 1;\n\t\t}\n\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {\n\t\t*out_func = NULL;\n\n\t\t/* Lightfuncs are considered strict, so 'this' binding is\n\t\t * used as is.  They're never bound, always constructable,\n\t\t * and never special functions.\n\t\t */\n\t\treturn 1;\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\treturn 0;  /* let slow path deal with it */\n}\n\nDUK_LOCAL duk_hobject *duk__resolve_target_func_and_this_binding(duk_hthread *thr,\n                                                                 duk_idx_t idx_func,\n                                                                 duk_small_uint_t *call_flags) {\n\tduk_tval *tv_func;\n\tduk_hobject *func;\n\tduk_bool_t first;\n\n\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\tfor (first = 1;; first = 0) {\n\t\tDUK_ASSERT(duk_get_top(thr) >= idx_func + 2);\n\n\t\ttv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);\n\t\tDUK_ASSERT(tv_func != NULL);\n\n\t\tDUK_DD(DUK_DDPRINT(\"target func: %!iT\", tv_func));\n\n\t\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\t\tfunc = DUK_TVAL_GET_OBJECT(tv_func);\n\n\t\t\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\t\t\tif (DUK_UNLIKELY(!DUK_HOBJECT_HAS_CONSTRUCTABLE(func))) {\n\t\t\t\t\tgoto not_constructable;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (DUK_UNLIKELY(!DUK_HOBJECT_IS_CALLABLE(func))) {\n\t\t\t\t\tgoto not_callable;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (DUK_LIKELY(!DUK_HOBJECT_HAS_BOUNDFUNC(func) &&\n\t\t\t               !DUK_HOBJECT_HAS_SPECIAL_CALL(func) &&\n\t\t\t               !DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(func))) {\n\t\t\t\t/* Common case, so test for using a single bitfield test.\n\t\t\t\t * Break out to handle this coercion etc.\n\t\t\t\t */\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/* XXX: could set specialcall for boundfuncs too, simplify check above */\n\n\t\t\tif (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_SPECIAL_CALL(func));\n\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_IS_NATFUNC(func));\n\n\t\t\t\t/* Callable/constructable flags are the same\n\t\t\t\t * for the bound function and its target, so\n\t\t\t\t * we don't need to check them here, we can\n\t\t\t\t * check them from the target only.\n\t\t\t\t */\n\t\t\t\tduk__handle_bound_chain_for_call(thr, idx_func, *call_flags & DUK_CALL_FLAG_CONSTRUCT);\n\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(duk_require_tval(thr, idx_func)) ||\n\t\t\t\t           DUK_TVAL_IS_LIGHTFUNC(duk_require_tval(thr, idx_func)));\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_SPECIAL_CALL(func));\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\t\t\tif (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(func)) {\n\t\t\t\t\t/* If no trap, resume processing from Proxy trap.\n\t\t\t\t\t * If trap exists, helper converts call into a trap\n\t\t\t\t\t * call; this may change a constructor call into a\n\t\t\t\t\t * normal (non-constructor) trap call.  We must\n\t\t\t\t\t * continue processing even when a trap is found as\n\t\t\t\t\t * the trap may be bound.\n\t\t\t\t\t */\n\t\t\t\t\tduk__handle_proxy_for_call(thr, idx_func, (duk_hproxy *) func, call_flags);\n\t\t\t\t}\n\t\t\t\telse\n#endif\n\t\t\t\t{\n\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(func));\n\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_CALLABLE(func));\n\t\t\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CONSTRUCTABLE(func));\n\t\t\t\t\t/* Constructable check already done above. */\n\n\t\t\t\t\tif (duk__handle_specialfuncs_for_call(thr, idx_func, func, call_flags, first) != 0) {\n\t\t\t\t\t\t/* Encountered native eval call, normal call\n\t\t\t\t\t\t * context.  Break out, handle this coercion etc.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* Retry loop. */\n\t\t} else if (DUK_TVAL_IS_LIGHTFUNC(tv_func)) {\n\t\t\t/* Lightfuncs are:\n\t\t\t *   - Always strict, so no 'this' coercion.\n\t\t\t *   - Always callable.\n\t\t\t *   - Always constructable.\n\t\t\t *   - Never specialfuncs.\n\t\t\t */\n\t\t\tfunc = NULL;\n\t\t\tgoto finished;\n\t\t} else {\n\t\t\tgoto not_callable;\n\t\t}\n\t}\n\n\tDUK_ASSERT(func != NULL);\n\n\tif (!DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t/* Non-strict target needs 'this' coercion.\n\t\t * This has potential side effects invalidating\n\t\t * 'tv_func'.\n\t\t */\n\t\tduk__coerce_nonstrict_this_binding(thr, idx_func + 1);\n\t}\n\tif (*call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tif (!(*call_flags & DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED)) {\n\t\t\t*call_flags |= DUK_CALL_FLAG_DEFAULT_INSTANCE_UPDATED;\n\t\t\tduk__update_default_instance_proto(thr, idx_func);\n\t\t}\n\t}\n\n finished:\n\n#if defined(DUK_USE_ASSERTIONS)\n\t{\n\t\tduk_tval *tv_tmp;\n\n\t\ttv_tmp = duk_get_tval(thr, idx_func);\n\t\tDUK_ASSERT(tv_tmp != NULL);\n\n\t\tDUK_ASSERT((DUK_TVAL_IS_OBJECT(tv_tmp) && DUK_HOBJECT_IS_CALLABLE(DUK_TVAL_GET_OBJECT(tv_tmp))) ||\n\t\t           DUK_TVAL_IS_LIGHTFUNC(tv_tmp));\n\t\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\t\tDUK_ASSERT(func == NULL || (DUK_HOBJECT_IS_COMPFUNC(func) ||\n\t\t                            DUK_HOBJECT_IS_NATFUNC(func)));\n\t\tDUK_ASSERT(func == NULL || (DUK_HOBJECT_HAS_CONSTRUCTABLE(func) ||\n\t\t                            (*call_flags & DUK_CALL_FLAG_CONSTRUCT) == 0));\n\t}\n#endif\n\n\treturn func;\n\n not_callable:\n\tDUK_ASSERT(tv_func != NULL);\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t/* GETPROPC delayed error handling: when target is not callable,\n\t * GETPROPC replaces idx_func+0 with a non-callable wrapper object\n\t * with a hidden Symbol to signify it's to be handled here.  If\n\t * found, unwrap the original Error and throw it as is here.  The\n\t * hidden Symbol is only checked as an own property, not inherited\n\t * (which would be dangerous).\n\t */\n\tif (DUK_TVAL_IS_OBJECT(tv_func)) {\n\t\tduk_tval *tv_wrap = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, DUK_TVAL_GET_OBJECT(tv_func), DUK_STRIDX_INT_TARGET);\n\t\tif (tv_wrap != NULL) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"delayed error from GETPROPC: %!T\", tv_wrap));\n\t\t\tduk_push_tval(thr, tv_wrap);\n\t\t\t(void) duk_throw(thr);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t}\n#endif\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not callable\", duk_get_type_name(thr, idx_func));\n#else\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not callable\", duk_push_string_tval_readable(thr, tv_func));\n#endif\n#else\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CALLABLE);\n#endif\n\tDUK_WO_NORETURN(return NULL;);\n\n not_constructable:\n\t/* For now GETPROPC delayed error not needed for constructor calls. */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not constructable\", duk_get_type_name(thr, idx_func));\n#else\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"%s not constructable\", duk_push_string_tval_readable(thr, tv_func));\n#endif\n#else\n\tDUK_ERROR_TYPE(thr, DUK_STR_NOT_CONSTRUCTABLE);\n#endif\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Manipulate value stack so that exactly 'num_stack_rets' return\n *  values are at 'idx_retbase' in every case, assuming there are\n *  'rc' return values on top of stack.\n *\n *  This is a bit tricky, because the called C function operates in\n *  the same activation record and may have e.g. popped the stack\n *  empty (below idx_retbase).\n */\n\nDUK_LOCAL void duk__safe_call_adjust_valstack(duk_hthread *thr, duk_idx_t idx_retbase, duk_idx_t num_stack_rets, duk_idx_t num_actual_rets) {\n\tduk_idx_t idx_rcbase;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(idx_retbase >= 0);\n\tDUK_ASSERT(num_stack_rets >= 0);\n\tDUK_ASSERT(num_actual_rets >= 0);\n\n\tidx_rcbase = duk_get_top(thr) - num_actual_rets;  /* base of known return values */\n\tif (DUK_UNLIKELY(idx_rcbase < 0)) {\n\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_CFUNC_RC);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"adjust valstack after func call: \"\n\t                     \"num_stack_rets=%ld, num_actual_rets=%ld, stack_top=%ld, idx_retbase=%ld, idx_rcbase=%ld\",\n\t                     (long) num_stack_rets, (long) num_actual_rets, (long) duk_get_top(thr),\n\t                     (long) idx_retbase, (long) idx_rcbase));\n\n\tDUK_ASSERT(idx_rcbase >= 0);  /* caller must check */\n\n\t/* Space for num_stack_rets was reserved before the safe call.\n\t * Because value stack reserve cannot shrink except in call returns,\n\t * the reserve is still in place.  Adjust valstack, carefully\n\t * ensuring we don't overstep the reserve.\n\t */\n\n\t/* Match idx_rcbase with idx_retbase so that the return values\n\t * start at the correct index.\n\t */\n\tif (idx_rcbase > idx_retbase) {\n\t\tduk_idx_t count = idx_rcbase - idx_retbase;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"elements at/after idx_retbase have enough to cover func retvals \"\n\t\t                     \"(idx_retbase=%ld, idx_rcbase=%ld)\", (long) idx_retbase, (long) idx_rcbase));\n\n\t\t/* Remove values between irc_rcbase (start of intended return\n\t\t * values) and idx_retbase to lower return values to idx_retbase.\n\t\t */\n\t\tDUK_ASSERT(count > 0);\n\t\tduk_remove_n(thr, idx_retbase, count);  /* may be NORZ */\n\t} else {\n\t\tduk_idx_t count = idx_retbase - idx_rcbase;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"not enough elements at/after idx_retbase to cover func retvals \"\n\t\t                     \"(idx_retbase=%ld, idx_rcbase=%ld)\", (long) idx_retbase, (long) idx_rcbase));\n\n\t\t/* Insert 'undefined' at idx_rcbase (start of intended return\n\t\t * values) to lift return values to idx_retbase.\n\t\t */\n\t\tDUK_ASSERT(count >= 0);\n\t\tDUK_ASSERT(thr->valstack_end - thr->valstack_top >= count);  /* reserve cannot shrink */\n\t\tduk_insert_undefined_n(thr, idx_rcbase, count);\n\t}\n\n\t/* Chop extra retvals away / extend with undefined. */\n\tduk_set_top_unsafe(thr, idx_retbase + num_stack_rets);\n}\n\n/*\n *  Activation setup for tailcalls and non-tailcalls.\n */\n\n#if defined(DUK_USE_TAILCALL)\nDUK_LOCAL duk_small_uint_t duk__call_setup_act_attempt_tailcall(duk_hthread *thr,\n                                                                duk_small_uint_t call_flags,\n                                                                duk_idx_t idx_func,\n                                                                duk_hobject *func,\n                                                                duk_size_t entry_valstack_bottom_byteoff,\n                                                                duk_size_t entry_valstack_end_byteoff,\n                                                                duk_idx_t *out_nargs,\n                                                                duk_idx_t *out_nregs,\n                                                                duk_size_t *out_vs_min_bytes,\n                                                                duk_activation **out_act) {\n\tduk_activation *act;\n\tduk_tval *tv1, *tv2;\n\tduk_idx_t idx_args;\n\tduk_small_uint_t flags1, flags2;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_activation *prev_pause_act;\n#endif\n\n\tDUK_UNREF(entry_valstack_end_byteoff);\n\n\t/* Tailcall cannot be flagged to resume calls, and a\n\t * previous frame must exist.\n\t */\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\t*out_act = act;\n\n\tif (func == NULL || !DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by target not being ecma function\"));\n\t\treturn 0;\n\t}\n\tif (act->flags & DUK_ACT_FLAG_PREVENT_YIELD) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by current activation having DUK_ACT_FLAG_PREVENT_YIELD\"));\n\t\treturn 0;\n\t}\n\t/* Tailcall is only allowed if current and candidate\n\t * function have identical return value handling.  There\n\t * are three possible return value handling cases:\n\t *   1. Normal function call, no special return value handling.\n\t *   2. Constructor call, return value replacement object check.\n\t *   3. Proxy 'construct' trap call, return value invariant check.\n\t */\n\tflags1 = (duk_small_uint_t) ((act->flags & DUK_ACT_FLAG_CONSTRUCT) ? 1 : 0)\n#if defined(DUK_USE_ES6_PROXY)\n\t         | (duk_small_uint_t) ((act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) ? 2 : 0)\n#endif\n\t         ;\n\tflags2 = (duk_small_uint_t) ((call_flags & DUK_CALL_FLAG_CONSTRUCT) ? 1 : 0)\n#if defined(DUK_USE_ES6_PROXY)\n\t         | (duk_small_uint_t) ((call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) ? 2 : 0);\n#endif\n\t         ;\n\tif (flags1 != flags2) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by incompatible return value handling\"));\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(((act->flags & DUK_ACT_FLAG_CONSTRUCT) && (call_flags & DUK_CALL_FLAG_CONSTRUCT)) ||\n\t           (!(act->flags & DUK_ACT_FLAG_CONSTRUCT) && !(call_flags & DUK_CALL_FLAG_CONSTRUCT)));\n\tDUK_ASSERT(((act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) && (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY)) ||\n\t           (!(act->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY) && !(call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY)));\n\tif (DUK_HOBJECT_HAS_NOTAIL(func)) {\n\t\t/* See: test-bug-tailcall-preventyield-assert.c. */\n\t\tDUK_DDD(DUK_DDDPRINT(\"tail call prevented by function having a notail flag\"));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  Tailcall handling\n\t *\n\t *  Although the callstack entry is reused, we need to explicitly unwind\n\t *  the current activation (or simulate an unwind).  In particular, the\n\t *  current activation must be closed, otherwise something like\n\t *  test-bug-reduce-judofyr.js results.  Also catchers need to be unwound\n\t *  because there may be non-error-catching label entries in valid tail calls.\n\t *\n\t *  Special attention is needed for debugger and pause behavior when\n\t *  reusing an activation.\n\t *    - Disable StepOut processing for the activation unwind because\n\t *      we reuse the activation, see:\n\t *      https://github.com/svaarala/duktape/issues/1684.\n\t *    - Disable line change pause flag permanently if act == dbg_pause_act\n\t *      (if set) because it would no longer be relevant, see:\n\t *      https://github.com/svaarala/duktape/issues/1726,\n\t *      https://github.com/svaarala/duktape/issues/1786.\n\t *    - Check for function entry (e.g. StepInto) pause flag here, because\n\t *      the executor pause check won't trigger due to shared activation, see:\n\t *      https://github.com/svaarala/duktape/issues/1726.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"is tail call, reusing activation at callstack top, at index %ld\",\n                             (long) (thr->callstack_top - 1)));\n\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(func));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));\n\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\tDUK_ASSERT(call_flags & DUK_CALL_FLAG_ALLOW_ECMATOECMA);\n\n\t/* Unwind the topmost callstack entry before reusing it.  This\n\t * also unwinds the catchers related to the topmost entry.\n\t */\n\tDUK_ASSERT(thr->callstack_top > 0);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (act == thr->heap->dbg_pause_act) {\n\t\tthr->heap->dbg_pause_flags &= ~DUK_PAUSE_FLAG_LINE_CHANGE;\n\t}\n\n\tprev_pause_act = thr->heap->dbg_pause_act;\n\tthr->heap->dbg_pause_act = NULL;\n\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_ENTRY) {\n\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by function entry (tailcall)\"));\n\t\tduk_debug_set_paused(thr->heap);\n\t}\n#endif\n\tduk_hthread_activation_unwind_reuse_norz(thr);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tthr->heap->dbg_pause_act = prev_pause_act;\n#endif\n\tDUK_ASSERT(act == thr->callstack_curr);\n\n\t/* XXX: We could restore the caller's value stack reserve\n\t * here, as if we did an actual unwind-and-call.  Without\n\t * the restoration, value stack reserve may remain higher\n\t * than would otherwise be possible until we return to a\n\t * non-tailcall.\n\t */\n\n\t/* Then reuse the unwound activation. */\n\tact->cat = NULL;\n\tact->var_env = NULL;\n\tact->lex_env = NULL;\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));\n\tact->func = func;  /* don't want an intermediate exposed state with func == NULL */\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\tact->prev_caller = NULL;\n#endif\n\t/* don't want an intermediate exposed state with invalid pc */\n\tact->curr_pc = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) func);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tact->prev_line = 0;\n#endif\n\tDUK_TVAL_SET_OBJECT(&act->tv_func, func);  /* borrowed, no refcount */\n\tDUK_HOBJECT_INCREF(thr, func);\n\n\tact->flags = DUK_ACT_FLAG_TAILCALLED;\n\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\tact->flags |= DUK_ACT_FLAG_STRICT;\n\t}\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT;\n\t}\n#if defined(DUK_USE_ES6_PROXY)\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT_PROXY;\n\t}\n#endif\n\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) == func);      /* already updated */\n\tDUK_ASSERT(act->var_env == NULL);\n\tDUK_ASSERT(act->lex_env == NULL);\n\tact->bottom_byteoff = entry_valstack_bottom_byteoff;  /* tail call -> reuse current \"frame\" */\n#if 0\n\t/* Topmost activation retval_byteoff is considered garbage, no need to init. */\n\tact->retval_byteoff = 0;\n#endif\n\t/* Filled in when final reserve is known, dummy value doesn't matter\n\t * even in error unwind because reserve_byteoff is only used when\n\t * returning to -this- activation.\n\t */\n\tact->reserve_byteoff = 0;\n\n\t/*\n\t *  Manipulate valstack so that args are on the current bottom and the\n\t *  previous caller's 'this' binding (which is the value preceding the\n\t *  current bottom) is replaced with the new 'this' binding:\n\t *\n\t *       [ ... this_old | (crud) func this_new arg1 ... argN ]\n\t *  -->  [ ... this_new | arg1 ... argN ]\n\t *\n\t *  For tail calling to work properly, the valstack bottom must not grow\n\t *  here; otherwise crud would accumulate on the valstack.\n\t */\n\n\ttv1 = thr->valstack_bottom - 1;\n\ttv2 = thr->valstack_bottom + idx_func + 1;\n\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);  /* tv1 is -below- valstack_bottom */\n\tDUK_ASSERT(tv2 >= thr->valstack_bottom && tv2 < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\n\tidx_args = idx_func + 2;\n\tduk_remove_n(thr, 0, idx_args);  /* may be NORZ */\n\n\tidx_func = 0; DUK_UNREF(idx_func);  /* really 'not applicable' anymore, should not be referenced after this */\n\tidx_args = 0;\n\n\t*out_nargs = ((duk_hcompfunc *) func)->nargs;\n\t*out_nregs = ((duk_hcompfunc *) func)->nregs;\n\tDUK_ASSERT(*out_nregs >= 0);\n\tDUK_ASSERT(*out_nregs >= *out_nargs);\n\t*out_vs_min_bytes = entry_valstack_bottom_byteoff + sizeof(duk_tval) * ((duk_size_t) *out_nregs + DUK_VALSTACK_INTERNAL_EXTRA);\n\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n#if defined(DUK_USE_TAILCALL)\n#error incorrect options: tail calls enabled with function caller property\n#endif\n\t/* XXX: This doesn't actually work properly for tail calls, so\n\t * tail calls are disabled when DUK_USE_NONSTD_FUNC_CALLER_PROPERTY\n\t * is in use.\n\t */\n\tduk__update_func_caller_prop(thr, func);\n#endif\n\n\t/* [ ... this_new | arg1 ... argN ] */\n\n\treturn 1;\n}\n#endif  /* DUK_USE_TAILCALL */\n\nDUK_LOCAL void duk__call_setup_act_not_tailcall(duk_hthread *thr,\n                                                duk_small_uint_t call_flags,\n                                                duk_idx_t idx_func,\n                                                duk_hobject *func,\n                                                duk_size_t entry_valstack_bottom_byteoff,\n                                                duk_size_t entry_valstack_end_byteoff,\n                                                duk_idx_t *out_nargs,\n                                                duk_idx_t *out_nregs,\n                                                duk_size_t *out_vs_min_bytes,\n                                                duk_activation **out_act) {\n\tduk_activation *act;\n\tduk_activation *new_act;\n\n\tDUK_UNREF(entry_valstack_end_byteoff);\n\n\tDUK_DDD(DUK_DDDPRINT(\"not a tail call, pushing a new activation to callstack, to index %ld\",\n\t                     (long) (thr->callstack_top)));\n\n\tduk__call_callstack_limit_check(thr);\n\tnew_act = duk_hthread_activation_alloc(thr);\n\tDUK_ASSERT(new_act != NULL);\n\n\tact = thr->callstack_curr;\n\tif (act != NULL) {\n\t\t/*\n\t\t *  Update return value stack index of current activation (if any).\n\t\t *\n\t\t *  Although it might seem this is not necessary (bytecode executor\n\t\t *  does this for ECMAScript-to-ECMAScript calls; other calls are\n\t\t *  handled here), this turns out to be necessary for handling yield\n\t\t *  and resume.  For them, an ECMAScript-to-native call happens, and\n\t\t *  the ECMAScript call's retval_byteoff must be set for things to work.\n\t\t */\n\n\t\tact->retval_byteoff = entry_valstack_bottom_byteoff + (duk_size_t) idx_func * sizeof(duk_tval);\n\t}\n\n\tnew_act->parent = act;\n\tthr->callstack_curr = new_act;\n\tthr->callstack_top++;\n\tact = new_act;\n\t*out_act = act;\n\n\tDUK_ASSERT(thr->valstack_top > thr->valstack_bottom);  /* at least effective 'this' */\n\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\n\tact->cat = NULL;\n\n\tact->flags = 0;\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT;\n\t}\n#if defined(DUK_USE_ES6_PROXY)\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY) {\n\t\tact->flags |= DUK_ACT_FLAG_CONSTRUCT_PROXY;\n\t}\n#endif\n\tif (call_flags & DUK_CALL_FLAG_DIRECT_EVAL) {\n\t\tact->flags |= DUK_ACT_FLAG_DIRECT_EVAL;\n\t}\n\n\t/* start of arguments: idx_func + 2. */\n\tact->func = func;  /* NULL for lightfunc */\n\tif (DUK_LIKELY(func != NULL)) {\n\t\tDUK_TVAL_SET_OBJECT(&act->tv_func, func);  /* borrowed, no refcount */\n\t\tif (DUK_HOBJECT_HAS_STRICT(func)) {\n\t\t\tact->flags |= DUK_ACT_FLAG_STRICT;\n\t\t}\n\t\tif (DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\t\t*out_nargs = ((duk_hcompfunc *) func)->nargs;\n\t\t\t*out_nregs = ((duk_hcompfunc *) func)->nregs;\n\t\t\tDUK_ASSERT(*out_nregs >= 0);\n\t\t\tDUK_ASSERT(*out_nregs >= *out_nargs);\n\t\t\t*out_vs_min_bytes = entry_valstack_bottom_byteoff +\n\t\t\t\tsizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nregs + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t} else {\n\t\t\t/* True because of call target lookup checks. */\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_NATFUNC(func));\n\n\t\t\t*out_nargs = ((duk_hnatfunc *) func)->nargs;\n\t\t\t*out_nregs = *out_nargs;\n\t\t\tif (*out_nargs >= 0) {\n\t\t\t\t*out_vs_min_bytes = entry_valstack_bottom_byteoff +\n\t\t\t\t\tsizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nregs + DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t\t} else {\n\t\t\t\t/* Vararg function. */\n\t\t\t\tduk_size_t valstack_top_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - ((duk_uint8_t *) thr->valstack));\n\t\t\t\t*out_vs_min_bytes = valstack_top_byteoff +\n\t\t\t\t\tsizeof(duk_tval) * (DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tduk_small_uint_t lf_flags;\n\t\tduk_tval *tv_func;\n\n\t\tact->flags |= DUK_ACT_FLAG_STRICT;\n\n\t\ttv_func = DUK_GET_TVAL_POSIDX(thr, idx_func);\n\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func));\n\t\tDUK_TVAL_SET_TVAL(&act->tv_func, tv_func);  /* borrowed, no refcount */\n\n\t\tlf_flags = DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv_func);\n\t\t*out_nargs = DUK_LFUNC_FLAGS_GET_NARGS(lf_flags);\n\t\tif (*out_nargs != DUK_LFUNC_NARGS_VARARGS) {\n\t\t\t*out_vs_min_bytes = entry_valstack_bottom_byteoff +\n\t\t\t\tsizeof(duk_tval) * ((duk_size_t) idx_func + 2U + (duk_size_t) *out_nargs + DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t} else {\n\t\t\tduk_size_t valstack_top_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_top - ((duk_uint8_t *) thr->valstack));\n\t\t\t*out_vs_min_bytes = valstack_top_byteoff +\n\t\t\t\tsizeof(duk_tval) * (DUK_VALSTACK_API_ENTRY_MINIMUM + DUK_VALSTACK_INTERNAL_EXTRA);\n\t\t\t*out_nargs = -1;  /* vararg */\n\t\t}\n\t\t*out_nregs = *out_nargs;\n\t}\n\n\tact->var_env = NULL;\n\tact->lex_env = NULL;\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\tact->prev_caller = NULL;\n#endif\n\tact->curr_pc = NULL;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tact->prev_line = 0;\n#endif\n\tact->bottom_byteoff = entry_valstack_bottom_byteoff + sizeof(duk_tval) * ((duk_size_t) idx_func + 2U);\n#if 0\n\tact->retval_byteoff = 0;   /* topmost activation retval_byteoff is considered garbage, no need to init */\n#endif\n\t/* Filled in when final reserve is known, dummy value doesn't matter\n\t * even in error unwind because reserve_byteoff is only used when\n\t * returning to -this- activation.\n\t */\n\tact->reserve_byteoff = 0;  /* filled in by caller */\n\n\t/* XXX: Is this INCREF necessary? 'func' is always a borrowed\n\t * reference reachable through the value stack?  If changed, stack\n\t * unwind code also needs to be fixed to match.\n\t */\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, func);  /* act->func */\n\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\tif (func) {\n\t\tduk__update_func_caller_prop(thr, func);\n\t}\n#endif\n}\n\n/*\n *  Environment setup.\n */\n\nDUK_LOCAL void duk__call_env_setup(duk_hthread *thr, duk_hobject *func, duk_activation *act, duk_idx_t idx_args) {\n\tduk_hobject *env;\n\n\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));  /* bound function has already been resolved */\n\n\tif (DUK_LIKELY(func != NULL)) {\n\t\tif (DUK_LIKELY(DUK_HOBJECT_HAS_NEWENV(func))) {\n\t\t\tDUK_STATS_INC(thr->heap, stats_envrec_newenv);\n\t\t\tif (DUK_LIKELY(!DUK_HOBJECT_HAS_CREATEARGS(func))) {\n\t\t\t\t/* Use a new environment but there's no 'arguments' object;\n\t\t\t\t * delayed environment initialization.  This is the most\n\t\t\t\t * common case.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(act->lex_env == NULL);\n\t\t\t\tDUK_ASSERT(act->var_env == NULL);\n\t\t\t} else {\n\t\t\t\t/* Use a new environment and there's an 'arguments' object.\n\t\t\t\t * We need to initialize it right now.\n\t\t\t\t */\n\n\t\t\t\t/* third arg: absolute index (to entire valstack) of bottom_byteoff of new activation */\n\t\t\t\tenv = duk_create_activation_environment_record(thr, func, act->bottom_byteoff);\n\t\t\t\tDUK_ASSERT(env != NULL);\n\n\t\t\t\t/* [ ... func this arg1 ... argN envobj ] */\n\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_CREATEARGS(func));\n\t\t\t\tduk__handle_createargs_for_call(thr, func, env, idx_args);\n\n\t\t\t\t/* [ ... func this arg1 ... argN envobj ] */\n\n\t\t\t\tact->lex_env = env;\n\t\t\t\tact->var_env = env;\n\t\t\t\tDUK_HOBJECT_INCREF(thr, env);\n\t\t\t\tDUK_HOBJECT_INCREF(thr, env);  /* XXX: incref by count (2) directly */\n\t\t\t\tduk_pop(thr);\n\t\t\t}\n\t\t} else {\n\t\t\t/* Use existing env (e.g. for non-strict eval); cannot have\n\t\t\t * an own 'arguments' object (but can refer to an existing one).\n\t\t\t */\n\n\t\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_CREATEARGS(func));\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_envrec_oldenv);\n\t\t\tduk__handle_oldenv_for_call(thr, func, act);\n\n\t\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\t\tDUK_ASSERT(act->var_env != NULL);\n\t\t}\n\t} else {\n\t\t/* Lightfuncs are always native functions and have \"newenv\". */\n\t\tDUK_ASSERT(act->lex_env == NULL);\n\t\tDUK_ASSERT(act->var_env == NULL);\n\t\tDUK_STATS_INC(thr->heap, stats_envrec_newenv);\n\t}\n}\n\n/*\n *  Misc shared helpers.\n */\n\n/* Check thread state, update current thread. */\nDUK_LOCAL void duk__call_thread_state_update(duk_hthread *thr) {\n\tDUK_ASSERT(thr != NULL);\n\n\tif (DUK_LIKELY(thr == thr->heap->curr_thread)) {\n\t\tif (DUK_UNLIKELY(thr->state != DUK_HTHREAD_STATE_RUNNING)) {\n\t\t\t/* Should actually never happen, but check anyway. */\n\t\t\tgoto thread_state_error;\n\t\t}\n\t} else {\n\t\tDUK_ASSERT(thr->heap->curr_thread == NULL ||\n\t\t           thr->heap->curr_thread->state == DUK_HTHREAD_STATE_RUNNING);\n\t\tif (DUK_UNLIKELY(thr->state != DUK_HTHREAD_STATE_INACTIVE)) {\n\t\t\tgoto thread_state_error;\n\t\t}\n\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, thr);\n\t\tthr->state = DUK_HTHREAD_STATE_RUNNING;\n\n\t\t/* Multiple threads may be simultaneously in the RUNNING\n\t\t * state, but not in the same \"resume chain\".\n\t\t */\n\t}\n\tDUK_ASSERT(thr->heap->curr_thread == thr);\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\treturn;\n\n thread_state_error:\n\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"invalid thread state (%ld)\", (long) thr->state);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Main unprotected call handler, handles:\n *\n *    - All combinations of native/ECMAScript caller and native/ECMAScript\n *      target.\n *\n *    - Optimized ECMAScript-to-ECMAScript call where call handling only\n *      sets up a new duk_activation but reuses an existing bytecode executor\n *      (the caller) without native recursion.\n *\n *    - Tailcalls, where an activation is reused without increasing call\n *      stack (duk_activation) depth.\n *\n *    - Setup for an initial Duktape.Thread.resume().\n *\n *  The call handler doesn't provide any protection guarantees, protected calls\n *  must be implemented e.g. by wrapping the call in a duk_safe_call().\n *  Call setup may fail at any stage, even when the new activation is in\n *  place; the only guarantee is that the state is consistent for unwinding.\n */\n\nDUK_LOCAL duk_int_t duk__handle_call_raw(duk_hthread *thr,\n                                         duk_idx_t idx_func,\n                                         duk_small_uint_t call_flags) {\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_activation *entry_act;\n\tduk_size_t entry_callstack_top;\n#endif\n\tduk_size_t entry_valstack_bottom_byteoff;\n\tduk_size_t entry_valstack_end_byteoff;\n\tduk_int_t entry_call_recursion_depth;\n\tduk_hthread *entry_curr_thread;\n\tduk_uint_fast8_t entry_thread_state;\n\tduk_instr_t **entry_ptr_curr_pc;\n\tduk_idx_t idx_args;\n\tduk_idx_t nargs;            /* # argument registers target function wants (< 0 => \"as is\") */\n\tduk_idx_t nregs;            /* # total registers target function wants on entry (< 0 => \"as is\") */\n\tduk_size_t vs_min_bytes;    /* minimum value stack size (bytes) for handling call */\n\tduk_hobject *func;          /* 'func' on stack (borrowed reference) */\n\tduk_activation *act;\n\tduk_ret_t rc;\n\tduk_small_uint_t use_tailcall;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\t/* Asserts for heap->curr_thread omitted: it may be NULL, 'thr', or\n\t * any other thread (e.g. when heap thread is used to run finalizers).\n\t */\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\tDUK_ASSERT(idx_func >= 0);\n\n\tDUK_STATS_INC(thr->heap, stats_call_all);\n\n\t/* If a tail call:\n\t *   - an ECMAScript activation must be on top of the callstack\n\t *   - there cannot be any catch stack entries that would catch\n\t *     a return\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tif (call_flags & DUK_CALL_FLAG_TAILCALL) {\n\t\tduk_activation *tmp_act;\n\t\tduk_catcher *tmp_cat;\n\n\t\tDUK_ASSERT(thr->callstack_top >= 1);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\t\t/* No entry in the catch stack which would actually catch a\n\t\t * throw can refer to the callstack entry being reused.\n\t\t * There *can* be catch stack entries referring to the current\n\t\t * callstack entry as long as they don't catch (e.g. label sites).\n\t\t */\n\n\t\ttmp_act = thr->callstack_curr;\n\t\tfor (tmp_cat = tmp_act->cat; tmp_cat != NULL; tmp_cat = tmp_cat->parent) {\n\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(tmp_cat) == DUK_CAT_TYPE_LABEL); /* a non-catching entry */\n\t\t}\n\t}\n#endif  /* DUK_USE_ASSERTIONS */\n\n\t/*\n\t *  Store entry state.\n\t */\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_act = thr->callstack_curr;\n\tentry_callstack_top = thr->callstack_top;\n#endif\n\tentry_valstack_bottom_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);\n\tentry_valstack_end_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tentry_call_recursion_depth = thr->heap->call_recursion_depth;\n\tentry_curr_thread = thr->heap->curr_thread;  /* may be NULL if first call */\n\tentry_thread_state = thr->state;\n\tentry_ptr_curr_pc = thr->ptr_curr_pc;  /* may be NULL */\n\n\t/* If thr->ptr_curr_pc is set, sync curr_pc to act->pc.  Then NULL\n\t * thr->ptr_curr_pc so that it's not accidentally used with an incorrect\n\t * activation when side effects occur.\n\t */\n\tduk_hthread_sync_and_null_currpc(thr);\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"duk__handle_call_raw: thr=%p, idx_func=%ld, \"\n\t                   \"call_flags=0x%08lx (constructor=%ld), \"\n\t                   \"valstack_top=%ld, idx_func=%ld, idx_args=%ld, rec_depth=%ld/%ld, \"\n\t                   \"entry_valstack_bottom_byteoff=%ld, entry_valstack_end_byteoff=%ld, \"\n\t                   \"entry_call_recursion_depth=%ld, \"\n\t                   \"entry_curr_thread=%p, entry_thread_state=%ld\",\n\t                   (void *) thr,\n\t                   (long) idx_func,\n\t                   (unsigned long) call_flags,\n\t                   (long) ((call_flags & DUK_CALL_FLAG_CONSTRUCT) != 0 ? 1 : 0),\n\t                   (long) duk_get_top(thr),\n\t                   (long) idx_func,\n\t                   (long) (idx_func + 2),\n\t                   (long) thr->heap->call_recursion_depth,\n\t                   (long) thr->heap->call_recursion_limit,\n\t                   (long) entry_valstack_bottom_byteoff,\n\t                   (long) entry_valstack_end_byteoff,\n\t                   (long) entry_call_recursion_depth,\n\t                   (void *) entry_curr_thread,\n\t                   (long) entry_thread_state));\n\n\t/*\n\t *  Thread state check and book-keeping.\n\t */\n\n\tduk__call_thread_state_update(thr);\n\n\t/*\n\t *  Increase call recursion depth as early as possible so that if we\n\t *  enter a recursive call for any reason there's a backstop to native\n\t *  recursion.  This can happen e.g. for almost any property read\n\t *  because it may cause a getter call or a Proxy trap (GC and finalizers\n\t *  are not an issue because they are not recursive).  If we end up\n\t *  doing an Ecma-to-Ecma call, revert the increase.  (See GH-2032.)\n\t *\n\t *  For similar reasons, ensure there is a known value stack spare\n\t *  even before we actually prepare the value stack for the target\n\t *  function.  If this isn't done, early recursion may consume the\n\t *  value stack space.\n\t *\n\t *  XXX: Should bump yield preventcount early, for the same reason.\n\t */\n\n\tduk__call_c_recursion_limit_check(thr);\n\tthr->heap->call_recursion_depth++;\n\tduk_require_stack(thr, DUK__CALL_HANDLING_REQUIRE_STACK);\n\n\t/*\n\t *  Resolve final target function; handle bound functions and special\n\t *  functions like .call() and .apply().  Also figure out the effective\n\t *  'this' binding, which replaces the current value at idx_func + 1.\n\t */\n\n\tif (DUK_LIKELY(duk__resolve_target_fastpath_check(thr, idx_func, &func, call_flags) != 0U)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"fast path target resolve\"));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"slow path target resolve\"));\n\t\tfunc = duk__resolve_target_func_and_this_binding(thr, idx_func, &call_flags);\n\t}\n\tDUK_ASSERT(duk_get_top(thr) - idx_func >= 2);  /* at least func and this present */\n\n\tDUK_ASSERT(func == NULL || !DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\tDUK_ASSERT(func == NULL || (DUK_HOBJECT_IS_COMPFUNC(func) ||\n\t                            DUK_HOBJECT_IS_NATFUNC(func)));\n\n\t/* [ ... func this arg1 ... argN ] */\n\n\t/*\n\t *  Setup a preliminary activation and figure out nargs/nregs and\n\t *  value stack minimum size.\n\t *\n\t *  Don't touch valstack_bottom or valstack_top yet so that Duktape API\n\t *  calls work normally.\n\t *\n\t *  Because 'act' is not zeroed, all fields must be filled in.\n\t */\n\n\t/* Should not be necessary, but initialize to silence warnings. */\n\tact = NULL;\n\tnargs = 0;\n\tnregs = 0;\n\tvs_min_bytes = 0;\n\n#if defined(DUK_USE_TAILCALL)\n\tuse_tailcall = (call_flags & DUK_CALL_FLAG_TAILCALL);\n\tif (use_tailcall) {\n\t\tuse_tailcall = duk__call_setup_act_attempt_tailcall(thr,\n\t\t                                                    call_flags,\n\t\t                                                    idx_func,\n\t\t                                                    func,\n\t\t                                                    entry_valstack_bottom_byteoff,\n\t\t                                                    entry_valstack_end_byteoff,\n\t\t                                                    &nargs,\n\t\t                                                    &nregs,\n\t\t                                                    &vs_min_bytes,\n\t\t                                                    &act);\n\t}\n#else\n\tDUK_ASSERT((call_flags & DUK_CALL_FLAG_TAILCALL) == 0);  /* compiler ensures this */\n\tuse_tailcall = 0;\n#endif\n\n\tif (use_tailcall) {\n\t\tidx_args = 0;\n\t\tDUK_STATS_INC(thr->heap, stats_call_tailcall);\n\t} else {\n\t\tduk__call_setup_act_not_tailcall(thr,\n\t\t                                 call_flags,\n\t\t                                 idx_func,\n\t\t                                 func,\n\t\t                                 entry_valstack_bottom_byteoff,\n\t\t                                 entry_valstack_end_byteoff,\n\t\t                                 &nargs,\n\t\t                                 &nregs,\n\t\t                                 &vs_min_bytes,\n\t\t                                 &act);\n\t\tidx_args = idx_func + 2;\n\t}\n\t/* After this point idx_func is no longer valid for tailcalls. */\n\n\tDUK_ASSERT(act != NULL);\n\n\t/* [ ... func this arg1 ... argN ] */\n\n\t/*\n\t *  Environment record creation and 'arguments' object creation.\n\t *  Named function expression name binding is handled by the\n\t *  compiler; the compiled function's parent env will contain\n\t *  the (immutable) binding already.\n\t *\n\t *  This handling is now identical for C and ECMAScript functions.\n\t *  C functions always have the 'NEWENV' flag set, so their\n\t *  environment record initialization is delayed (which is good).\n\t *\n\t *  Delayed creation (on demand) is handled in duk_js_var.c.\n\t */\n\n\tduk__call_env_setup(thr, func, act, idx_args);\n\n\t/* [ ... func this arg1 ... argN ] */\n\n\t/*\n\t *  Setup value stack: clamp to 'nargs', fill up to 'nregs',\n\t *  ensure value stack size matches target requirements, and\n\t *  switch value stack bottom.  Valstack top is kept.\n\t *\n\t *  Value stack can only grow here.\n\t */\n\n\tduk_valstack_grow_check_throw(thr, vs_min_bytes);\n\tact->reserve_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\n\tif (use_tailcall) {\n\t\tDUK_ASSERT(nregs >= 0);\n\t\tDUK_ASSERT(nregs >= nargs);\n\t\tduk_set_top_and_wipe(thr, nregs, nargs);\n\t} else {\n\t\tif (nregs >= 0) {\n\t\t\tDUK_ASSERT(nregs >= nargs);\n\t\t\tduk_set_top_and_wipe(thr, idx_func + 2 + nregs, idx_func + 2 + nargs);\n\t\t} else {\n\t\t\t;\n\t\t}\n\t\tthr->valstack_bottom = thr->valstack_bottom + idx_func + 2;\n\t}\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\n\t/*\n\t *  Make the actual call.  For Ecma-to-Ecma calls detect that\n\t *  setup is complete, then return with a status code that allows\n\t *  the caller to reuse the running executor.\n\t */\n\n\tif (func != NULL && DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\t/*\n\t\t *  ECMAScript call.\n\t\t */\n\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(func));\n\t\tact->curr_pc = DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, (duk_hcompfunc *) func);\n\n\t\tif (call_flags & DUK_CALL_FLAG_ALLOW_ECMATOECMA) {\n\t\t\tDUK_DD(DUK_DDPRINT(\"avoid native call, use existing executor\"));\n\t\t\tDUK_STATS_INC(thr->heap, stats_call_ecmatoecma);\n\t\t\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\t\t\tDUK_REFZERO_CHECK_FAST(thr);\n\t\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\t\tthr->heap->call_recursion_depth--;  /* No recursion increase for this case. */\n\t\t\treturn 1;  /* 1=reuse executor */\n\t\t}\n\t\tDUK_ASSERT(use_tailcall == 0);\n\n\t\t/* duk_hthread_activation_unwind_norz() will decrease this on unwind */\n\t\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\t\tact->flags |= DUK_ACT_FLAG_PREVENT_YIELD;\n\t\tthr->callstack_preventcount++;\n\n\t\t/* [ ... func this | arg1 ... argN ] ('this' must precede new bottom) */\n\n\t\t/*\n\t\t *  Bytecode executor call.\n\t\t *\n\t\t *  Execute bytecode, handling any recursive function calls and\n\t\t *  thread resumptions.  Returns when execution would return from\n\t\t *  the entry level activation.  When the executor returns, a\n\t\t *  single return value is left on the stack top.\n\t\t *\n\t\t *  The only possible longjmp() is an error (DUK_LJ_TYPE_THROW),\n\t\t *  other types are handled internally by the executor.\n\t\t */\n\n\t\t/* thr->ptr_curr_pc is set by bytecode executor early on entry */\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"entering bytecode execution\"));\n\t\tduk_js_execute_bytecode(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"returned from bytecode execution\"));\n\t} else {\n\t\t/*\n\t\t *  Native call.\n\t\t */\n\n\t\tDUK_ASSERT(func == NULL || ((duk_hnatfunc *) func)->func != NULL);\n\t\tDUK_ASSERT(use_tailcall == 0);\n\n\t\t/* [ ... func this | arg1 ... argN ] ('this' must precede new bottom) */\n\n\t\t/* duk_hthread_activation_unwind_norz() will decrease this on unwind */\n\t\tDUK_ASSERT((act->flags & DUK_ACT_FLAG_PREVENT_YIELD) == 0);\n\t\tact->flags |= DUK_ACT_FLAG_PREVENT_YIELD;\n\t\tthr->callstack_preventcount++;\n\n\t\t/* For native calls must be NULL so we don't sync back */\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\n\t\t/* XXX: native funcptr could come out of call setup. */\n\t\tif (func) {\n\t\t\trc = ((duk_hnatfunc *) func)->func(thr);\n\t\t} else {\n\t\t\tduk_tval *tv_func;\n\t\t\tduk_c_function funcptr;\n\n\t\t\ttv_func = &act->tv_func;\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_LIGHTFUNC(tv_func));\n\t\t\tfuncptr = DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv_func);\n\t\t\trc = funcptr(thr);\n\t\t}\n\n\t\t/* Automatic error throwing, retval check. */\n\n\t\tif (rc == 0) {\n\t\t\tDUK_ASSERT(thr->valstack < thr->valstack_end);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));\n\t\t\tthr->valstack_top++;\n\t\t} else if (rc == 1) {\n\t\t\t;\n\t\t} else if (rc < 0) {\n\t\t\tduk_error_throw_from_negative_rc(thr, rc);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t} else {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_CFUNC_RC);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\t}\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\tDUK_ASSERT(use_tailcall == 0);\n\n\t/*\n\t *  Constructor call post processing.\n\t */\n\n#if defined(DUK_USE_ES6_PROXY)\n\tif (call_flags & (DUK_CALL_FLAG_CONSTRUCT | DUK_CALL_FLAG_CONSTRUCT_PROXY)) {\n\t\tduk_call_construct_postprocess(thr, call_flags & DUK_CALL_FLAG_CONSTRUCT_PROXY);\n\t}\n#else\n\tif (call_flags & DUK_CALL_FLAG_CONSTRUCT) {\n\t\tduk_call_construct_postprocess(thr, 0);\n\t}\n#endif\n\n\t/*\n\t *  Unwind, restore valstack bottom and other book-keeping.\n\t */\n\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(thr->callstack_curr->parent == entry_act);\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top + 1);\n\tduk_hthread_activation_unwind_norz(thr);\n\tDUK_ASSERT(thr->callstack_curr == entry_act);\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_bottom_byteoff);\n\t/* keep current valstack_top */\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\tDUK_ASSERT(thr->valstack_top - thr->valstack_bottom >= idx_func + 1);\n\n\t/* Return value handling. */\n\n\t/* [ ... func this (crud) retval ] */\n\n\t{\n\t\tduk_tval *tv_ret;\n\t\tduk_tval *tv_funret;\n\n\t\ttv_ret = thr->valstack_bottom + idx_func;\n\t\ttv_funret = thr->valstack_top - 1;\n#if defined(DUK_USE_FASTINT)\n\t\t/* Explicit check for fastint downgrade. */\n\t\tDUK_TVAL_CHKFAST_INPLACE_FAST(tv_funret);\n#endif\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv_ret, tv_funret);  /* side effects */\n\t}\n\n\tduk_set_top_unsafe(thr, idx_func + 1);\n\n\t/* [ ... retval ] */\n\n\t/* Restore caller's value stack reserve (cannot fail). */\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff >= (duk_uint8_t *) thr->valstack_top);\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff <= (duk_uint8_t *) thr->valstack_alloc_end);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_end_byteoff);\n\n\t/* XXX: Trial value stack shrink would be OK here, but we'd need\n\t * to prevent side effects of the potential realloc.\n\t */\n\n\t/* Restore entry thread executor curr_pc stack frame pointer. */\n\tthr->ptr_curr_pc = entry_ptr_curr_pc;\n\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread);  /* may be NULL */\n\tthr->state = (duk_uint8_t) entry_thread_state;\n\n\t/* Disabled assert: triggered with some torture tests. */\n#if 0\n\tDUK_ASSERT((thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread == NULL) ||  /* first call */\n\t           (thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread != NULL) ||  /* other call */\n\t           (thr->state == DUK_HTHREAD_STATE_RUNNING && thr->heap->curr_thread == thr));     /* current thread */\n#endif\n\n\tthr->heap->call_recursion_depth = entry_call_recursion_depth;\n\n\t/* If the debugger is active we need to force an interrupt so that\n\t * debugger breakpoints are rechecked.  This is important for function\n\t * calls caused by side effects (e.g. when doing a DUK_OP_GETPROP), see\n\t * GH-303.  Only needed for success path, error path always causes a\n\t * breakpoint recheck in the executor.  It would be enough to set this\n\t * only when returning to an ECMAScript activation, but setting the flag\n\t * on every return should have no ill effect.\n\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tDUK_DD(DUK_DDPRINT(\"returning with debugger enabled, force interrupt\"));\n\t\tDUK_ASSERT(thr->interrupt_counter <= thr->interrupt_init);\n\t\tthr->interrupt_init -= thr->interrupt_counter;\n\t\tthr->interrupt_counter = 0;\n\t\tthr->heap->dbg_force_restart = 1;\n\t}\n#endif\n\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\tduk__interrupt_fixup(thr, entry_curr_thread);\n#endif\n\n\t/* Restored by success path. */\n\tDUK_ASSERT(thr->heap->call_recursion_depth == entry_call_recursion_depth);\n\tDUK_ASSERT(thr->ptr_curr_pc == entry_ptr_curr_pc);\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\tDUK_REFZERO_CHECK_FAST(thr);\n\n\treturn 0;  /* 0=call handled inline */\n}\n\nDUK_INTERNAL duk_int_t duk_handle_call_unprotected_nargs(duk_hthread *thr,\n                                                         duk_idx_t nargs,\n                                                         duk_small_uint_t call_flags) {\n\tduk_idx_t idx_func;\n\tDUK_ASSERT(duk_get_top(thr) >= nargs + 2);\n\tidx_func = duk_get_top(thr) - (nargs + 2);\n\tDUK_ASSERT(idx_func >= 0);\n\treturn duk_handle_call_unprotected(thr, idx_func, call_flags);\n}\n\nDUK_INTERNAL duk_int_t duk_handle_call_unprotected(duk_hthread *thr,\n                                                   duk_idx_t idx_func,\n                                                   duk_small_uint_t call_flags) {\n\tDUK_ASSERT(duk_is_valid_index(thr, idx_func));\n\tDUK_ASSERT(idx_func >= 0);\n\treturn duk__handle_call_raw(thr, idx_func, call_flags);\n}\n\n/*\n *  duk_handle_safe_call(): make a \"C protected call\" within the\n *  current activation.\n *\n *  The allowed thread states for making a call are the same as for\n *  duk_handle_call_protected().\n *\n *  Even though this call is protected, errors are thrown for insane arguments\n *  and may result in a fatal error unless there's another protected call which\n *  catches such errors.\n *\n *  The error handling path should be error free, even for out-of-memory\n *  errors, to ensure safe sandboxing.  (As of Duktape 2.2.0 this is not\n *  yet the case for environment closing which may run out of memory, see\n *  XXX notes below.)\n */\n\nDUK_LOCAL void duk__handle_safe_call_inner(duk_hthread *thr,\n                                           duk_safe_call_function func,\n                                           void *udata,\n#if defined(DUK_USE_ASSERTIONS)\n                                           duk_size_t entry_valstack_bottom_byteoff,\n                                           duk_size_t entry_callstack_top,\n#endif\n                                           duk_hthread *entry_curr_thread,\n                                           duk_uint_fast8_t entry_thread_state,\n                                           duk_idx_t idx_retbase,\n                                           duk_idx_t num_stack_rets) {\n\tduk_ret_t rc;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\t/*\n\t *  Thread state check and book-keeping.\n\t */\n\n\tduk__call_thread_state_update(thr);\n\n\t/*\n\t *  Recursion limit check.\n\t */\n\n\tduk__call_c_recursion_limit_check(thr);\n\tthr->heap->call_recursion_depth++;\n\n\t/*\n\t *  Make the C call.\n\t */\n\n\trc = func(thr, udata);\n\n\tDUK_DDD(DUK_DDDPRINT(\"safe_call, func rc=%ld\", (long) rc));\n\n\t/*\n\t *  Valstack manipulation for results.\n\t */\n\n\t/* we're running inside the caller's activation, so no change in call/catch stack or valstack bottom */\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\tDUK_ASSERT(thr->valstack_bottom >= thr->valstack);\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) == entry_valstack_bottom_byteoff);\n\tDUK_ASSERT(thr->valstack_top >= thr->valstack_bottom);\n\tDUK_ASSERT(thr->valstack_end >= thr->valstack_top);\n\n\tif (DUK_UNLIKELY(rc < 0)) {\n\t\tduk_error_throw_from_negative_rc(thr, rc);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tDUK_ASSERT(rc >= 0);\n\n\tduk__safe_call_adjust_valstack(thr, idx_retbase, num_stack_rets, rc);  /* throws for insane rc */\n\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread);  /* may be NULL */\n\tthr->state = (duk_uint8_t) entry_thread_state;\n}\n\nDUK_LOCAL void duk__handle_safe_call_error(duk_hthread *thr,\n                                           duk_activation *entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n                                           duk_size_t entry_callstack_top,\n#endif\n                                           duk_hthread *entry_curr_thread,\n                                           duk_uint_fast8_t entry_thread_state,\n                                           duk_idx_t idx_retbase,\n                                           duk_idx_t num_stack_rets,\n                                           duk_size_t entry_valstack_bottom_byteoff,\n                                           duk_jmpbuf *old_jmpbuf_ptr) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_CTX_ASSERT_VALID(thr);\n\n\t/*\n\t *  Error during call.  The error value is at heap->lj.value1.\n\t *\n\t *  The very first thing we do is restore the previous setjmp catcher.\n\t *  This means that any error in error handling will propagate outwards\n\t *  instead of causing a setjmp() re-entry above.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"error caught during protected duk_handle_safe_call()\"));\n\n\t/* Other longjmp types are handled by executor before propagating\n\t * the error here.\n\t */\n\tDUK_ASSERT(thr->heap->lj.type == DUK_LJ_TYPE_THROW);\n\tDUK_ASSERT_LJSTATE_SET(thr->heap);\n\n\t/* Either pointer may be NULL (at entry), so don't assert. */\n\tthr->heap->lj.jmpbuf_ptr = old_jmpbuf_ptr;\n\n\t/* XXX: callstack unwind may now throw an error when closing\n\t * scopes; this is a sandboxing issue, described in:\n\t * https://github.com/svaarala/duktape/issues/476\n\t */\n\t/* XXX: \"unwind to\" primitive? */\n\n\tDUK_ASSERT(thr->callstack_top >= entry_callstack_top);\n\twhile (thr->callstack_curr != entry_act) {\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tduk_hthread_activation_unwind_norz(thr);\n\t}\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\n\t/* Switch active thread before any side effects to avoid a\n\t * dangling curr_thread pointer.\n\t */\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread);  /* may be NULL */\n\tthr->state = (duk_uint8_t) entry_thread_state;\n\n\tDUK_ASSERT(thr->heap->curr_thread == entry_curr_thread);\n\tDUK_ASSERT(thr->state == entry_thread_state);\n\n\t/* Restore valstack bottom. */\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + entry_valstack_bottom_byteoff);\n\n\t/* [ ... | (crud) ] */\n\n\t/* XXX: ensure space in valstack (now relies on internal reserve)? */\n\tduk_push_tval(thr, &thr->heap->lj.value1);\n\n\t/* [ ... | (crud) errobj ] */\n\n\tDUK_ASSERT(duk_get_top(thr) >= 1);  /* at least errobj must be on stack */\n\n\tduk__safe_call_adjust_valstack(thr, idx_retbase, num_stack_rets, 1);  /* 1 = num actual 'return values' */\n\n\t/* [ ... | ] or [ ... | errobj (M * undefined)] where M = num_stack_rets - 1 */\n\n\t/* Reset longjmp state. */\n\tthr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;\n\tthr->heap->lj.iserror = 0;\n\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, &thr->heap->lj.value1);\n\tDUK_TVAL_SET_UNDEFINED_UPDREF_NORZ(thr, &thr->heap->lj.value2);\n\n\t/* Error handling complete, remove side effect protections.  Caller\n\t * will process pending finalizers.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->heap->error_not_allowed == 1);\n\tthr->heap->error_not_allowed = 0;\n#endif\n\tDUK_ASSERT(thr->heap->pf_prevent_count > 0);\n\tthr->heap->pf_prevent_count--;\n\tDUK_DD(DUK_DDPRINT(\"safe call error handled, pf_prevent_count updated to %ld\", (long) thr->heap->pf_prevent_count));\n\n\t/* thr->ptr_curr_pc is restored by\n\t * duk__handle_safe_call_shared_unwind() which is also used for\n\t * success path.\n\t */\n}\n\nDUK_LOCAL void duk__handle_safe_call_shared_unwind(duk_hthread *thr,\n                                                   duk_idx_t idx_retbase,\n                                                   duk_idx_t num_stack_rets,\n#if defined(DUK_USE_ASSERTIONS)\n                                                   duk_size_t entry_callstack_top,\n#endif\n                                                   duk_int_t entry_call_recursion_depth,\n                                                   duk_hthread *entry_curr_thread,\n                                                   duk_instr_t **entry_ptr_curr_pc) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_CTX_ASSERT_VALID(thr);\n\tDUK_UNREF(idx_retbase);\n\tDUK_UNREF(num_stack_rets);\n\tDUK_UNREF(entry_curr_thread);\n\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\n\t/* Restore entry thread executor curr_pc stack frame pointer.\n\t * XXX: would be enough to do in error path only, should nest\n\t * cleanly in success path.\n\t */\n\tthr->ptr_curr_pc = entry_ptr_curr_pc;\n\n\tthr->heap->call_recursion_depth = entry_call_recursion_depth;\n\n\t/* stack discipline consistency check */\n\tDUK_ASSERT(duk_get_top(thr) == idx_retbase + num_stack_rets);\n\n\t/* A debugger forced interrupt check is not needed here, as\n\t * problematic safe calls are not caused by side effects.\n\t */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\tduk__interrupt_fixup(thr, entry_curr_thread);\n#endif\n}\n\nDUK_INTERNAL duk_int_t duk_handle_safe_call(duk_hthread *thr,\n                                            duk_safe_call_function func,\n                                            void *udata,\n                                            duk_idx_t num_stack_args,\n                                            duk_idx_t num_stack_rets) {\n\tduk_activation *entry_act;\n\tduk_size_t entry_valstack_bottom_byteoff;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_size_t entry_valstack_end_byteoff;\n\tduk_size_t entry_callstack_top;\n\tduk_size_t entry_callstack_preventcount;\n#endif\n\tduk_int_t entry_call_recursion_depth;\n\tduk_hthread *entry_curr_thread;\n\tduk_uint_fast8_t entry_thread_state;\n\tduk_instr_t **entry_ptr_curr_pc;\n\tduk_jmpbuf *old_jmpbuf_ptr = NULL;\n\tduk_jmpbuf our_jmpbuf;\n\tduk_idx_t idx_retbase;\n\tduk_int_t retval;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(duk_get_top(thr) >= num_stack_args);  /* Caller ensures. */\n\n\tDUK_STATS_INC(thr->heap, stats_safecall_all);\n\n\t/* Value stack reserve handling: safe call assumes caller has reserved\n\t * space for nrets (assuming optimal unwind processing).  Value stack\n\t * reserve is not stored/restored as for normal calls because a safe\n\t * call conceptually happens in the same activation.\n\t */\n\n\t/* Careful with indices like '-x'; if 'x' is zero, it refers to bottom */\n\tentry_act = thr->callstack_curr;\n\tentry_valstack_bottom_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack);\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_valstack_end_byteoff = (duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack);\n\tentry_callstack_top = thr->callstack_top;\n\tentry_callstack_preventcount = thr->callstack_preventcount;\n#endif\n\tentry_call_recursion_depth = thr->heap->call_recursion_depth;\n\tentry_curr_thread = thr->heap->curr_thread;  /* may be NULL if first call */\n\tentry_thread_state = thr->state;\n\tentry_ptr_curr_pc = thr->ptr_curr_pc;  /* may be NULL */\n\tidx_retbase = duk_get_top(thr) - num_stack_args;  /* not a valid stack index if num_stack_args == 0 */\n\tDUK_ASSERT(idx_retbase >= 0);\n\n\tDUK_ASSERT((duk_idx_t) (thr->valstack_top - thr->valstack_bottom) >= num_stack_args);  /* Caller ensures. */\n\tDUK_ASSERT((duk_idx_t) (thr->valstack_end - (thr->valstack_bottom + idx_retbase)) >= num_stack_rets);  /* Caller ensures. */\n\n\t/* Cannot portably debug print a function pointer, hence 'func' not printed! */\n\tDUK_DD(DUK_DDPRINT(\"duk_handle_safe_call: thr=%p, num_stack_args=%ld, num_stack_rets=%ld, \"\n\t                   \"valstack_top=%ld, idx_retbase=%ld, rec_depth=%ld/%ld, \"\n\t                   \"entry_act=%p, entry_valstack_bottom_byteoff=%ld, entry_call_recursion_depth=%ld, \"\n\t                   \"entry_curr_thread=%p, entry_thread_state=%ld\",\n\t                   (void *) thr,\n\t                   (long) num_stack_args,\n\t                   (long) num_stack_rets,\n\t                   (long) duk_get_top(thr),\n\t                   (long) idx_retbase,\n\t                   (long) thr->heap->call_recursion_depth,\n\t                   (long) thr->heap->call_recursion_limit,\n\t                   (void *) entry_act,\n\t                   (long) entry_valstack_bottom_byteoff,\n\t                   (long) entry_call_recursion_depth,\n\t                   (void *) entry_curr_thread,\n\t                   (long) entry_thread_state));\n\n\t/* Setjmp catchpoint setup. */\n\told_jmpbuf_ptr = thr->heap->lj.jmpbuf_ptr;\n\tthr->heap->lj.jmpbuf_ptr = &our_jmpbuf;\n\n\t/* Prevent yields for the duration of the safe call.  This only\n\t * matters if the executor makes safe calls to functions that\n\t * yield, this doesn't currently happen.\n\t */\n\tthr->callstack_preventcount++;\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\ttry {\n#else\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr == &our_jmpbuf);\n\tif (DUK_SETJMP(our_jmpbuf.jb) == 0) {\n\t\t/* Success path. */\n#endif\n\t\tDUK_DDD(DUK_DDDPRINT(\"safe_call setjmp catchpoint setup complete\"));\n\n\t\tduk__handle_safe_call_inner(thr,\n\t\t                            func,\n\t\t                            udata,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t                            entry_valstack_bottom_byteoff,\n\t\t                            entry_callstack_top,\n#endif\n\t\t                            entry_curr_thread,\n\t\t                            entry_thread_state,\n\t\t                            idx_retbase,\n\t\t                            num_stack_rets);\n\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_nothrow);\n\n\t\t/* Either pointer may be NULL (at entry), so don't assert */\n\t\tthr->heap->lj.jmpbuf_ptr = old_jmpbuf_ptr;\n\n\t\t/* If calls happen inside the safe call, these are restored by\n\t\t * whatever calls are made.  Reserve cannot decrease.\n\t\t */\n\t\tDUK_ASSERT(thr->callstack_curr == entry_act);\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\n\t\tretval = DUK_EXEC_SUCCESS;\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t} catch (duk_internal_exception &exc) {\n\t\tDUK_UNREF(exc);\n#else\n\t} else {\n\t\t/* Error path. */\n#endif\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_throw);\n\n\t\tduk__handle_safe_call_error(thr,\n\t\t                            entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t                            entry_callstack_top,\n#endif\n\t\t                            entry_curr_thread,\n\t\t                            entry_thread_state,\n\t\t                            idx_retbase,\n\t\t                            num_stack_rets,\n\t\t                            entry_valstack_bottom_byteoff,\n\t\t                            old_jmpbuf_ptr);\n\n\t\tretval = DUK_EXEC_ERROR;\n\t}\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\tcatch (duk_fatal_exception &exc) {\n\t\tDUK_D(DUK_DPRINT(\"rethrow duk_fatal_exception\"));\n\t\tthrow;\n\t} catch (std::exception &exc) {\n\t\tconst char *what = exc.what();\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_throw);\n\t\tif (!what) {\n\t\t\twhat = \"unknown\";\n\t\t}\n\t\tDUK_D(DUK_DPRINT(\"unexpected c++ std::exception (perhaps thrown by user code)\"));\n\t\ttry {\n\t\t\tDUK_ERROR_FMT1(thr, DUK_ERR_TYPE_ERROR, \"caught invalid c++ std::exception '%s' (perhaps thrown by user code)\", what);\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t} catch (duk_internal_exception exc) {\n\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ std::exception\"));\n\t\t\tDUK_UNREF(exc);\n\t\t\tduk__handle_safe_call_error(thr,\n\t\t\t                            entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t                            entry_callstack_top,\n#endif\n\t\t\t                            entry_curr_thread,\n\t\t\t                            entry_thread_state,\n\t\t\t                            idx_retbase,\n\t\t\t                            num_stack_rets,\n\t\t\t                            entry_valstack_bottom_byteoff,\n\t\t\t                            old_jmpbuf_ptr);\n\t\t\tretval = DUK_EXEC_ERROR;\n\t\t}\n\t} catch (...) {\n\t\tDUK_D(DUK_DPRINT(\"unexpected c++ exception (perhaps thrown by user code)\"));\n\t\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\t\tDUK_STATS_INC(thr->heap, stats_safecall_throw);\n\t\ttry {\n\t\t\tDUK_ERROR_TYPE(thr, \"caught invalid c++ exception (perhaps thrown by user code)\");\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t} catch (duk_internal_exception exc) {\n\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ exception\"));\n\t\t\tDUK_UNREF(exc);\n\t\t\tduk__handle_safe_call_error(thr,\n\t\t\t                            entry_act,\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t                            entry_callstack_top,\n#endif\n\t\t\t                            entry_curr_thread,\n\t\t\t                            entry_thread_state,\n\t\t\t                            idx_retbase,\n\t\t\t                            num_stack_rets,\n\t\t\t                            entry_valstack_bottom_byteoff,\n\t\t\t                            old_jmpbuf_ptr);\n\t\t\tretval = DUK_EXEC_ERROR;\n\t\t}\n\t}\n#endif\n\n\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr == old_jmpbuf_ptr);  /* success/error path both do this */\n\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\tduk__handle_safe_call_shared_unwind(thr,\n\t                                    idx_retbase,\n\t                                    num_stack_rets,\n#if defined(DUK_USE_ASSERTIONS)\n\t                                    entry_callstack_top,\n#endif\n\t                                    entry_call_recursion_depth,\n\t                                    entry_curr_thread,\n\t                                    entry_ptr_curr_pc);\n\n\t/* Restore preventcount. */\n\tthr->callstack_preventcount--;\n\tDUK_ASSERT(thr->callstack_preventcount == entry_callstack_preventcount);\n\n\t/* Final asserts. */\n\tDUK_ASSERT(thr->callstack_curr == entry_act);\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_bottom - (duk_uint8_t *) thr->valstack) == entry_valstack_bottom_byteoff);\n\tDUK_ASSERT((duk_size_t) ((duk_uint8_t *) thr->valstack_end - (duk_uint8_t *) thr->valstack) >= entry_valstack_end_byteoff);\n\tDUK_ASSERT(thr->callstack_top == entry_callstack_top);\n\tDUK_ASSERT(thr->heap->call_recursion_depth == entry_call_recursion_depth);\n\tDUK_ASSERT(thr->heap->curr_thread == entry_curr_thread);\n\tDUK_ASSERT(thr->state == entry_thread_state);\n\tDUK_ASSERT(thr->ptr_curr_pc == entry_ptr_curr_pc);\n\tDUK_ASSERT(duk_get_top(thr) == idx_retbase + num_stack_rets);\n\tDUK_ASSERT_LJSTATE_UNSET(thr->heap);\n\n\t/* Pending side effects. */\n\tDUK_REFZERO_CHECK_FAST(thr);\n\n\treturn retval;\n}\n\n/*\n *  Property-based call (foo.noSuch()) error setup: replace target function\n *  on stack top with a hidden Symbol tagged non-callable wrapper object\n *  holding the error.  The error gets thrown in call handling at the\n *  proper spot to follow ECMAScript semantics.\n */\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\nDUK_INTERNAL DUK_NOINLINE DUK_COLD void duk_call_setup_propcall_error(duk_hthread *thr, duk_tval *tv_base, duk_tval *tv_key) {\n\tconst char *str_targ, *str_key, *str_base;\n\tduk_idx_t entry_top;\n\n\tentry_top = duk_get_top(thr);\n\n\t/* [ <nargs> target ] */\n\n\t/* Must stabilize pointers first.  tv_targ is already on stack top. */\n\tduk_push_tval(thr, tv_base);\n\tduk_push_tval(thr, tv_key);\n\n\tDUK_GC_TORTURE(thr->heap);\n\n\tduk_push_bare_object(thr);\n\n\t/* [ <nargs> target base key {} ] */\n\n\t/* We only push a wrapped error, replacing the call target (at\n\t * idx_func) with the error to ensure side effects come out\n\t * correctly:\n\t * - Property read\n\t * - Call argument evaluation\n\t * - Callability check and error thrown\n\t *\n\t * A hidden Symbol on the wrapper object pushed above is used by\n\t * call handling to figure out the error is to be thrown as is.\n\t * It is CRITICAL that the hidden Symbol can never occur on a\n\t * user visible object that may get thrown.\n\t */\n\n#if defined(DUK_USE_PARANOID_ERRORS)\n\tstr_targ = duk_get_type_name(thr, -4);\n\tstr_key = duk_get_type_name(thr, -2);\n\tstr_base = duk_get_type_name(thr, -3);\n\tduk_push_error_object(thr,\n\t                      DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t                      \"%s not callable (property %s of %s)\", str_targ, str_key, str_base);\n\tduk_xdef_prop_stridx(thr, -2, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE);  /* Marker property, reuse _Target. */\n\t/* [ <nargs> target base key { _Target: error } ] */\n\tduk_replace(thr, entry_top - 1);\n#else\n\tstr_targ = duk_push_string_readable(thr, -4);\n\tstr_key = duk_push_string_readable(thr, -3);\n\tstr_base = duk_push_string_readable(thr, -5);\n\tduk_push_error_object(thr,\n\t                      DUK_ERR_TYPE_ERROR | DUK_ERRCODE_FLAG_NOBLAME_FILELINE,\n\t                      \"%s not callable (property %s of %s)\", str_targ, str_key, str_base);\n\t/* [ <nargs> target base key {} str_targ str_key str_base error ] */\n\tduk_xdef_prop_stridx(thr, -5, DUK_STRIDX_INT_TARGET, DUK_PROPDESC_FLAGS_NONE);  /* Marker property, reuse _Target. */\n\t/* [ <nargs> target base key { _Target: error } str_targ str_key str_base ] */\n\tduk_swap(thr, -4, entry_top - 1);\n\t/* [ <nargs> { _Target: error } base key target str_targ str_key str_base ] */\n#endif\n\n\t/* [ <nregs> { _Target: error } <variable> */\n\tduk_set_top(thr, entry_top);\n\n\t/* [ <nregs> { _Target: error } */\n\tDUK_ASSERT(!duk_is_callable(thr, -1));  /* Critical so that call handling will throw the error. */\n}\n#endif  /* DUK_USE_VERBOSE_ERRORS */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_js_compiler.c",
    "content": "/*\n *  ECMAScript compiler.\n *\n *  Parses an input string and generates a function template result.\n *  Compilation may happen in multiple contexts (global code, eval\n *  code, function code).\n *\n *  The parser uses a traditional top-down recursive parsing for the\n *  statement level, and an operator precedence based top-down approach\n *  for the expression level.  The attempt is to minimize the C stack\n *  depth.  Bytecode is generated directly without an intermediate\n *  representation (tree), at the cost of needing two (and sometimes\n *  three) passes over each function.\n *\n *  The top-down recursive parser functions are named \"duk__parse_XXX\".\n *\n *  Recursion limits are in key functions to prevent arbitrary C recursion:\n *  function body parsing, statement parsing, and expression parsing.\n *\n *  See doc/compiler.rst for discussion on the design.\n *\n *  A few typing notes:\n *\n *    - duk_regconst_t: signed, highest bit set (< 0) means constant,\n *      some call sites use -1 for \"none\" (equivalent to constant 0x7fffffff)\n *    - PC values: duk_int_t, negative values used as markers\n */\n\n#include \"duk_internal.h\"\n\n/* If highest bit of a register number is set, it refers to a constant instead.\n * When interpreted as a signed value, this means const values are always\n * negative (when interpreted as two's complement).  For example DUK__ISREG_TEMP()\n * uses this approach to avoid an explicit DUK__ISREG() check (the condition is\n * logically \"'x' is a register AND 'x' >= temp_first\").\n */\n#define DUK__CONST_MARKER                   DUK_REGCONST_CONST_MARKER\n#define DUK__REMOVECONST(x)                 ((x) & ~DUK__CONST_MARKER)\n#define DUK__ISREG(x)                       ((x) >= 0)\n#define DUK__ISCONST(x)                     ((x) < 0)\n#define DUK__ISREG_TEMP(comp_ctx,x)         ((duk_int32_t) (x) >= (duk_int32_t) ((comp_ctx)->curr_func.temp_first))   /* Check for x >= temp_first && x >= 0 by comparing as signed. */\n#define DUK__ISREG_NOTTEMP(comp_ctx,x)      ((duk_uint32_t) (x) < (duk_uint32_t) ((comp_ctx)->curr_func.temp_first))  /* Check for x >= 0 && x < temp_first by interpreting as unsigned. */\n#define DUK__GETTEMP(comp_ctx)              ((comp_ctx)->curr_func.temp_next)\n#define DUK__SETTEMP(comp_ctx,x)            ((comp_ctx)->curr_func.temp_next = (x))  /* dangerous: must only lower (temp_max not updated) */\n#define DUK__SETTEMP_CHECKMAX(comp_ctx,x)   duk__settemp_checkmax((comp_ctx),(x))\n#define DUK__ALLOCTEMP(comp_ctx)            duk__alloctemp((comp_ctx))\n#define DUK__ALLOCTEMPS(comp_ctx,count)     duk__alloctemps((comp_ctx),(count))\n\n/* Init value set size for array and object literals. */\n#define DUK__MAX_ARRAY_INIT_VALUES        20\n#define DUK__MAX_OBJECT_INIT_PAIRS        10\n\n/* XXX: hack, remove when const lookup is not O(n) */\n#define DUK__GETCONST_MAX_CONSTS_CHECK    256\n\n/* These limits are based on bytecode limits.  Max temps is limited\n * by duk_hcompfunc nargs/nregs fields being 16 bits.\n */\n#define DUK__MAX_CONSTS                   DUK_BC_BC_MAX\n#define DUK__MAX_FUNCS                    DUK_BC_BC_MAX\n#define DUK__MAX_TEMPS                    0xffffL\n\n/* Initial bytecode size allocation. */\n#if defined(DUK_USE_PREFER_SIZE)\n#define DUK__BC_INITIAL_INSTS             16\n#else\n#define DUK__BC_INITIAL_INSTS             256\n#endif\n\n#define DUK__RECURSION_INCREASE(comp_ctx,thr)  do { \\\n\t\tDUK_DDD(DUK_DDDPRINT(\"RECURSION INCREASE: %s:%ld\", (const char *) DUK_FILE_MACRO, (long) DUK_LINE_MACRO)); \\\n\t\tduk__comp_recursion_increase((comp_ctx)); \\\n\t} while (0)\n\n#define DUK__RECURSION_DECREASE(comp_ctx,thr)  do { \\\n\t\tDUK_DDD(DUK_DDDPRINT(\"RECURSION DECREASE: %s:%ld\", (const char *) DUK_FILE_MACRO, (long) DUK_LINE_MACRO)); \\\n\t\tduk__comp_recursion_decrease((comp_ctx)); \\\n\t} while (0)\n\n/* Value stack slot limits: these are quite approximate right now, and\n * because they overlap in control flow, some could be eliminated.\n */\n#define DUK__COMPILE_ENTRY_SLOTS          8\n#define DUK__FUNCTION_INIT_REQUIRE_SLOTS  16\n#define DUK__FUNCTION_BODY_REQUIRE_SLOTS  16\n#define DUK__PARSE_STATEMENTS_SLOTS       16\n#define DUK__PARSE_EXPR_SLOTS             16\n\n/* Temporary structure used to pass a stack allocated region through\n * duk_safe_call().\n */\ntypedef struct {\n\tduk_small_uint_t flags;\n\tduk_compiler_ctx comp_ctx_alloc;\n\tduk_lexer_point lex_pt_alloc;\n} duk__compiler_stkstate;\n\n/*\n *  Prototypes\n */\n\n/* lexing */\nDUK_LOCAL_DECL void duk__advance_helper(duk_compiler_ctx *comp_ctx, duk_small_int_t expect);\nDUK_LOCAL_DECL void duk__advance_expect(duk_compiler_ctx *comp_ctx, duk_small_int_t expect);\nDUK_LOCAL_DECL void duk__advance(duk_compiler_ctx *ctx);\n\n/* function helpers */\nDUK_LOCAL_DECL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ctx, duk_regconst_t *out_stmt_value_reg);\nDUK_LOCAL_DECL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx);\n\n/* code emission */\nDUK_LOCAL_DECL duk_int_t duk__get_current_pc(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_compiler_instr *duk__get_instr_ptr(duk_compiler_ctx *comp_ctx, duk_int_t pc);\nDUK_LOCAL_DECL void duk__emit(duk_compiler_ctx *comp_ctx, duk_instr_t ins);\nDUK_LOCAL_DECL void duk__emit_op_only(duk_compiler_ctx *comp_ctx, duk_small_uint_t op);\nDUK_LOCAL_DECL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b, duk_regconst_t c);\nDUK_LOCAL_DECL void duk__emit_a_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b);\nDUK_LOCAL_DECL void duk__emit_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b, duk_regconst_t c);\n#if 0  /* unused */\nDUK_LOCAL_DECL void duk__emit_a(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a);\nDUK_LOCAL_DECL void duk__emit_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b);\n#endif\nDUK_LOCAL_DECL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t bc);\nDUK_LOCAL_DECL void duk__emit_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t bc);\nDUK_LOCAL_DECL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t abc);\nDUK_LOCAL_DECL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val);\nDUK_LOCAL_DECL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val);\nDUK_LOCAL_DECL void duk__emit_jump(duk_compiler_ctx *comp_ctx, duk_int_t target_pc);\nDUK_LOCAL_DECL duk_int_t duk__emit_jump_empty(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc);\nDUK_LOCAL_DECL void duk__patch_jump(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc, duk_int_t target_pc);\nDUK_LOCAL_DECL void duk__patch_jump_here(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc);\nDUK_LOCAL_DECL void duk__patch_trycatch(duk_compiler_ctx *comp_ctx, duk_int_t ldconst_pc, duk_int_t trycatch_pc, duk_regconst_t reg_catch, duk_regconst_t const_varname, duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__emit_if_false_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst);\nDUK_LOCAL_DECL void duk__emit_if_true_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst);\nDUK_LOCAL_DECL void duk__emit_invalid(duk_compiler_ctx *comp_ctx);\n\n/* ivalue/ispec helpers */\nDUK_LOCAL_DECL void duk__ivalue_regconst(duk_ivalue *x, duk_regconst_t regconst);\nDUK_LOCAL_DECL void duk__ivalue_plain_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL void duk__ivalue_var_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL void duk__ivalue_var_hstring(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_hstring *h);\nDUK_LOCAL_DECL void duk__copy_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *src, duk_ispec *dst);\nDUK_LOCAL_DECL void duk__copy_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *src, duk_ivalue *dst);\nDUK_LOCAL_DECL duk_regconst_t duk__alloctemps(duk_compiler_ctx *comp_ctx, duk_small_int_t num);\nDUK_LOCAL_DECL duk_regconst_t duk__alloctemp(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, duk_regconst_t temp_next);\nDUK_LOCAL_DECL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL\nduk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                         duk_ispec *x,\n                                         duk_regconst_t forced_reg,\n                                         duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ispec *x, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL void duk__ivalue_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL void duk__ivalue_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL\nduk_regconst_t duk__ivalue_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                          duk_ivalue *x,\n                                          duk_regconst_t forced_reg,\n                                          duk_small_uint_t flags);\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\n#endif\nDUK_LOCAL_DECL void duk__ivalue_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_int_t forced_reg);\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\nDUK_LOCAL_DECL duk_regconst_t duk__ivalue_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x);\n\n/* identifier handling */\nDUK_LOCAL_DECL duk_regconst_t duk__lookup_active_register_binding(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *ctx, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname);\n\n/* label handling */\nDUK_LOCAL_DECL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_int_t pc_label, duk_int_t label_id);\nDUK_LOCAL_DECL void duk__update_label_flags(duk_compiler_ctx *comp_ctx, duk_int_t label_id, duk_small_uint_t flags);\nDUK_LOCAL_DECL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_bool_t is_break, duk_int_t *out_label_id, duk_int_t *out_label_catch_depth, duk_int_t *out_label_pc, duk_bool_t *out_is_closest);\nDUK_LOCAL_DECL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, duk_size_t len);\n\n/* top-down expression parser */\nDUK_LOCAL_DECL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_ivalue *res);\nDUK_LOCAL_DECL duk_small_uint_t duk__expr_lbp(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL duk_bool_t duk__expr_is_empty(duk_compiler_ctx *comp_ctx);\n\n/* exprtop is the top level variant which resets nud/led counts */\nDUK_LOCAL_DECL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\nDUK_LOCAL_DECL void duk__exprtop(duk_compiler_ctx *ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n\n/* convenience helpers */\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__expr_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__expr_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\nDUK_LOCAL_DECL void duk__expr_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL duk_regconst_t duk__expr_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__expr_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\nDUK_LOCAL_DECL void duk__expr_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\nDUK_LOCAL_DECL void duk__expr_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\nDUK_LOCAL_DECL duk_regconst_t duk__exprtop_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#if 0  /* unused */\nDUK_LOCAL_DECL duk_regconst_t duk__exprtop_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\nDUK_LOCAL_DECL void duk__exprtop_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg);\nDUK_LOCAL_DECL duk_regconst_t duk__exprtop_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#if 0  /* unused */\nDUK_LOCAL_DECL void duk__exprtop_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags);\n#endif\n\n/* expression parsing helpers */\nDUK_LOCAL_DECL duk_int_t duk__parse_arguments(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\n\n/* statement parsing */\nDUK_LOCAL_DECL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname);\nDUK_LOCAL_DECL void duk__parse_var_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags);\nDUK_LOCAL_DECL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_if_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_do_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_while_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site);\nDUK_LOCAL_DECL void duk__parse_break_or_continue_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_throw_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res);\nDUK_LOCAL_DECL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_bool_t allow_source_elem);\nDUK_LOCAL_DECL duk_int_t duk__stmt_label_site(duk_compiler_ctx *comp_ctx, duk_int_t label_id);\nDUK_LOCAL_DECL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_source_elem, duk_bool_t expect_eof, duk_bool_t regexp_after);\n\nDUK_LOCAL_DECL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expect_eof, duk_bool_t implicit_return_value, duk_bool_t regexp_after, duk_small_int_t expect_token);\nDUK_LOCAL_DECL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx);\nDUK_LOCAL_DECL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags);\nDUK_LOCAL_DECL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags);\n\n#define DUK__FUNC_FLAG_DECL            (1 << 0)   /* Parsing a function declaration. */\n#define DUK__FUNC_FLAG_GETSET          (1 << 1)   /* Parsing an object literal getter/setter. */\n#define DUK__FUNC_FLAG_METDEF          (1 << 2)   /* Parsing an object literal method definition shorthand. */\n#define DUK__FUNC_FLAG_PUSHNAME_PASS1  (1 << 3)   /* Push function name when creating template (first pass only). */\n#define DUK__FUNC_FLAG_USE_PREVTOKEN   (1 << 4)   /* Use prev_token to start function parsing (workaround for object literal). */\n\n/*\n *  Parser control values for tokens.  The token table is ordered by the\n *  DUK_TOK_XXX defines.\n *\n *  The binding powers are for lbp() use (i.e. for use in led() context).\n *  Binding powers are positive for typing convenience, and bits at the\n *  top should be reserved for flags.  Binding power step must be higher\n *  than 1 so that binding power \"lbp - 1\" can be used for right associative\n *  operators.  Currently a step of 2 is used (which frees one more bit for\n *  flags).\n */\n\n/* XXX: actually single step levels would work just fine, clean up */\n\n/* binding power \"levels\" (see doc/compiler.rst) */\n#define DUK__BP_INVALID                0             /* always terminates led() */\n#define DUK__BP_EOF                    2\n#define DUK__BP_CLOSING                4             /* token closes expression, e.g. ')', ']' */\n#define DUK__BP_FOR_EXPR               DUK__BP_CLOSING    /* bp to use when parsing a top level Expression */\n#define DUK__BP_COMMA                  6\n#define DUK__BP_ASSIGNMENT             8\n#define DUK__BP_CONDITIONAL            10\n#define DUK__BP_LOR                    12\n#define DUK__BP_LAND                   14\n#define DUK__BP_BOR                    16\n#define DUK__BP_BXOR                   18\n#define DUK__BP_BAND                   20\n#define DUK__BP_EQUALITY               22\n#define DUK__BP_RELATIONAL             24\n#define DUK__BP_SHIFT                  26\n#define DUK__BP_ADDITIVE               28\n#define DUK__BP_MULTIPLICATIVE         30\n#define DUK__BP_EXPONENTIATION         32\n#define DUK__BP_POSTFIX                34\n#define DUK__BP_CALL                   36\n#define DUK__BP_MEMBER                 38\n\n#define DUK__TOKEN_LBP_BP_MASK         0x1f\n#define DUK__TOKEN_LBP_FLAG_NO_REGEXP  (1 << 5)   /* regexp literal must not follow this token */\n#define DUK__TOKEN_LBP_FLAG_TERMINATES (1 << 6)   /* terminates expression; e.g. post-increment/-decrement */\n#define DUK__TOKEN_LBP_FLAG_UNUSED     (1 << 7)   /* unused */\n\n#define DUK__TOKEN_LBP_GET_BP(x)       ((duk_small_uint_t) (((x) & DUK__TOKEN_LBP_BP_MASK) * 2))\n\n#define DUK__MK_LBP(bp)                ((bp) >> 1)    /* bp is assumed to be even */\n#define DUK__MK_LBP_FLAGS(bp,flags)    (((bp) >> 1) | (flags))\n\nDUK_LOCAL const duk_uint8_t duk__token_lbp[] = {\n\tDUK__MK_LBP(DUK__BP_EOF),                                 /* DUK_TOK_EOF */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_IDENTIFIER */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_BREAK */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CASE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CATCH */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CONTINUE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DEBUGGER */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DEFAULT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DELETE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_DO */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_ELSE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_FINALLY */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_FOR */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_FUNCTION */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_IF */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_IN */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_INSTANCEOF */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_NEW */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_RETURN */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SWITCH */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_THIS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_THROW */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_TRY */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_TYPEOF */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_VAR */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CONST */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_VOID */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_WHILE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_WITH */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_CLASS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_ENUM */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_EXPORT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_EXTENDS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_IMPORT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SUPER */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_NULL */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_TRUE */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_FALSE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_GET */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SET */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_IMPLEMENTS */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_INTERFACE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_LET */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PACKAGE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PRIVATE */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PROTECTED */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_PUBLIC */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_STATIC */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_YIELD */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_LCURLY */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_RCURLY */\n\tDUK__MK_LBP(DUK__BP_MEMBER),                              /* DUK_TOK_LBRACKET */\n\tDUK__MK_LBP_FLAGS(DUK__BP_CLOSING, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_RBRACKET */\n\tDUK__MK_LBP(DUK__BP_CALL),                                /* DUK_TOK_LPAREN */\n\tDUK__MK_LBP_FLAGS(DUK__BP_CLOSING, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_RPAREN */\n\tDUK__MK_LBP(DUK__BP_MEMBER),                              /* DUK_TOK_PERIOD */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_SEMICOLON */\n\tDUK__MK_LBP(DUK__BP_COMMA),                               /* DUK_TOK_COMMA */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_LT */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_GT */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_LE */\n\tDUK__MK_LBP(DUK__BP_RELATIONAL),                          /* DUK_TOK_GE */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_EQ */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_NEQ */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_SEQ */\n\tDUK__MK_LBP(DUK__BP_EQUALITY),                            /* DUK_TOK_SNEQ */\n\tDUK__MK_LBP(DUK__BP_ADDITIVE),                            /* DUK_TOK_ADD */\n\tDUK__MK_LBP(DUK__BP_ADDITIVE),                            /* DUK_TOK_SUB */\n\tDUK__MK_LBP(DUK__BP_MULTIPLICATIVE),                      /* DUK_TOK_MUL */\n\tDUK__MK_LBP(DUK__BP_MULTIPLICATIVE),                      /* DUK_TOK_DIV */\n\tDUK__MK_LBP(DUK__BP_MULTIPLICATIVE),                      /* DUK_TOK_MOD */\n\tDUK__MK_LBP(DUK__BP_EXPONENTIATION),                      /* DUK_TOK_EXP */\n\tDUK__MK_LBP_FLAGS(DUK__BP_POSTFIX, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_INCREMENT */\n\tDUK__MK_LBP_FLAGS(DUK__BP_POSTFIX, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_DECREMENT */\n\tDUK__MK_LBP(DUK__BP_SHIFT),                               /* DUK_TOK_ALSHIFT */\n\tDUK__MK_LBP(DUK__BP_SHIFT),                               /* DUK_TOK_ARSHIFT */\n\tDUK__MK_LBP(DUK__BP_SHIFT),                               /* DUK_TOK_RSHIFT */\n\tDUK__MK_LBP(DUK__BP_BAND),                                /* DUK_TOK_BAND */\n\tDUK__MK_LBP(DUK__BP_BOR),                                 /* DUK_TOK_BOR */\n\tDUK__MK_LBP(DUK__BP_BXOR),                                /* DUK_TOK_BXOR */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_LNOT */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_BNOT */\n\tDUK__MK_LBP(DUK__BP_LAND),                                /* DUK_TOK_LAND */\n\tDUK__MK_LBP(DUK__BP_LOR),                                 /* DUK_TOK_LOR */\n\tDUK__MK_LBP(DUK__BP_CONDITIONAL),                         /* DUK_TOK_QUESTION */\n\tDUK__MK_LBP(DUK__BP_INVALID),                             /* DUK_TOK_COLON */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_EQUALSIGN */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_ADD_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_SUB_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_MUL_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_DIV_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_MOD_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_EXP_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_ALSHIFT_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_ARSHIFT_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_RSHIFT_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_BAND_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_BOR_EQ */\n\tDUK__MK_LBP(DUK__BP_ASSIGNMENT),                          /* DUK_TOK_BXOR_EQ */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_NUMBER */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_STRING */\n\tDUK__MK_LBP_FLAGS(DUK__BP_INVALID, DUK__TOKEN_LBP_FLAG_NO_REGEXP),  /* DUK_TOK_REGEXP */\n};\n\n/*\n *  Misc helpers\n */\n\nDUK_LOCAL void duk__comp_recursion_increase(duk_compiler_ctx *comp_ctx) {\n\tDUK_ASSERT(comp_ctx != NULL);\n\tDUK_ASSERT(comp_ctx->recursion_depth >= 0);\n\tif (comp_ctx->recursion_depth >= comp_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_COMPILER_RECURSION_LIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tcomp_ctx->recursion_depth++;\n}\n\nDUK_LOCAL void duk__comp_recursion_decrease(duk_compiler_ctx *comp_ctx) {\n\tDUK_ASSERT(comp_ctx != NULL);\n\tDUK_ASSERT(comp_ctx->recursion_depth > 0);\n\tcomp_ctx->recursion_depth--;\n}\n\nDUK_LOCAL duk_bool_t duk__hstring_is_eval_or_arguments(duk_compiler_ctx *comp_ctx, duk_hstring *h) {\n\tDUK_UNREF(comp_ctx);\n\tDUK_ASSERT(h != NULL);\n\treturn DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(h);\n}\n\nDUK_LOCAL duk_bool_t duk__hstring_is_eval_or_arguments_in_strict_mode(duk_compiler_ctx *comp_ctx, duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n\treturn (comp_ctx->curr_func.is_strict &&\n\t        DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(h));\n}\n\n/*\n *  Parser duk__advance() token eating functions\n */\n\n/* XXX: valstack handling is awkward.  Add a valstack helper which\n * avoids dup():ing; valstack_copy(src, dst)?\n */\n\nDUK_LOCAL void duk__advance_helper(duk_compiler_ctx *comp_ctx, duk_small_int_t expect) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t regexp;\n\n\tDUK_ASSERT_DISABLE(comp_ctx->curr_token.t >= 0);  /* unsigned */\n\tDUK_ASSERT(comp_ctx->curr_token.t <= DUK_TOK_MAXVAL);  /* MAXVAL is inclusive */\n\n\t/*\n\t *  Use current token to decide whether a RegExp can follow.\n\t *\n\t *  We can use either 't' or 't_nores'; the latter would not\n\t *  recognize keywords.  Some keywords can be followed by a\n\t *  RegExp (e.g. \"return\"), so using 't' is better.  This is\n\t *  not trivial, see doc/compiler.rst.\n\t */\n\n\tregexp = 1;\n\tif (duk__token_lbp[comp_ctx->curr_token.t] & DUK__TOKEN_LBP_FLAG_NO_REGEXP) {\n\t\tregexp = 0;\n\t}\n\tif (comp_ctx->curr_func.reject_regexp_in_adv) {\n\t\tcomp_ctx->curr_func.reject_regexp_in_adv = 0;\n\t\tregexp = 0;\n\t}\n\tif (comp_ctx->curr_func.allow_regexp_in_adv) {\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 0;\n\t\tregexp = 1;\n\t}\n\n\tif (expect >= 0 && comp_ctx->curr_token.t != (duk_small_uint_t) expect) {\n\t\tDUK_D(DUK_DPRINT(\"parse error: expect=%ld, got=%ld\",\n\t\t                 (long) expect, (long) comp_ctx->curr_token.t));\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* make current token the previous; need to fiddle with valstack \"backing store\" */\n\tduk_memcpy(&comp_ctx->prev_token, &comp_ctx->curr_token, sizeof(duk_token));\n\tduk_copy(thr, comp_ctx->tok11_idx, comp_ctx->tok21_idx);\n\tduk_copy(thr, comp_ctx->tok12_idx, comp_ctx->tok22_idx);\n\n\t/* parse new token */\n\tduk_lexer_parse_js_input_element(&comp_ctx->lex,\n\t                                 &comp_ctx->curr_token,\n\t                                 comp_ctx->curr_func.is_strict,\n\t                                 regexp);\n\n\tDUK_DDD(DUK_DDDPRINT(\"advance: curr: tok=%ld/%ld,%ld,term=%ld,%!T,%!T \"\n\t                     \"prev: tok=%ld/%ld,%ld,term=%ld,%!T,%!T\",\n\t                     (long) comp_ctx->curr_token.t,\n\t                     (long) comp_ctx->curr_token.t_nores,\n\t                     (long) comp_ctx->curr_token.start_line,\n\t                     (long) comp_ctx->curr_token.lineterm,\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok11_idx),\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok12_idx),\n\t                     (long) comp_ctx->prev_token.t,\n\t                     (long) comp_ctx->prev_token.t_nores,\n\t                     (long) comp_ctx->prev_token.start_line,\n\t                     (long) comp_ctx->prev_token.lineterm,\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok21_idx),\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->tok22_idx)));\n}\n\n/* advance, expecting current token to be a specific token; parse next token in regexp context */\nDUK_LOCAL void duk__advance_expect(duk_compiler_ctx *comp_ctx, duk_small_int_t expect) {\n\tduk__advance_helper(comp_ctx, expect);\n}\n\n/* advance, whatever the current token is; parse next token in regexp context */\nDUK_LOCAL void duk__advance(duk_compiler_ctx *comp_ctx) {\n\tduk__advance_helper(comp_ctx, -1);\n}\n\n/*\n *  Helpers for duk_compiler_func.\n */\n\n/* init function state: inits valstack allocations */\nDUK_LOCAL void duk__init_func_valstack_slots(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func = &comp_ctx->curr_func;\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_idx_t entry_top;\n\n\tentry_top = duk_get_top(thr);\n\n\tduk_memzero(func, sizeof(*func));  /* intentional overlap with earlier memzero */\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tfunc->h_name = NULL;\n\tfunc->h_consts = NULL;\n\tfunc->h_funcs = NULL;\n\tfunc->h_decls = NULL;\n\tfunc->h_labelnames = NULL;\n\tfunc->h_labelinfos = NULL;\n\tfunc->h_argnames = NULL;\n\tfunc->h_varmap = NULL;\n#endif\n\n\tduk_require_stack(thr, DUK__FUNCTION_INIT_REQUIRE_SLOTS);\n\n\tDUK_BW_INIT_PUSHBUF(thr, &func->bw_code, DUK__BC_INITIAL_INSTS * sizeof(duk_compiler_instr));\n\t/* code_idx = entry_top + 0 */\n\n\tduk_push_bare_array(thr);\n\tfunc->consts_idx = entry_top + 1;\n\tfunc->h_consts = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 1);\n\tDUK_ASSERT(func->h_consts != NULL);\n\n\tduk_push_bare_array(thr);\n\tfunc->funcs_idx = entry_top + 2;\n\tfunc->h_funcs = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 2);\n\tDUK_ASSERT(func->h_funcs != NULL);\n\tDUK_ASSERT(func->fnum_next == 0);\n\n\tduk_push_bare_array(thr);\n\tfunc->decls_idx = entry_top + 3;\n\tfunc->h_decls = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 3);\n\tDUK_ASSERT(func->h_decls != NULL);\n\n\tduk_push_bare_array(thr);\n\tfunc->labelnames_idx = entry_top + 4;\n\tfunc->h_labelnames = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 4);\n\tDUK_ASSERT(func->h_labelnames != NULL);\n\n\tduk_push_dynamic_buffer(thr, 0);\n\tfunc->labelinfos_idx = entry_top + 5;\n\tfunc->h_labelinfos = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, entry_top + 5);\n\tDUK_ASSERT(func->h_labelinfos != NULL);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(func->h_labelinfos) && !DUK_HBUFFER_HAS_EXTERNAL(func->h_labelinfos));\n\n\tduk_push_bare_array(thr);\n\tfunc->argnames_idx = entry_top + 6;\n\tfunc->h_argnames = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 6);\n\tDUK_ASSERT(func->h_argnames != NULL);\n\n\tduk_push_bare_object(thr);\n\tfunc->varmap_idx = entry_top + 7;\n\tfunc->h_varmap = DUK_GET_HOBJECT_POSIDX(thr, entry_top + 7);\n\tDUK_ASSERT(func->h_varmap != NULL);\n}\n\n/* reset function state (prepare for pass 2) */\nDUK_LOCAL void duk__reset_func_for_pass2(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func = &comp_ctx->curr_func;\n\tduk_hthread *thr = comp_ctx->thr;\n\n\t/* reset bytecode buffer but keep current size; pass 2 will\n\t * require same amount or more.\n\t */\n\tDUK_BW_RESET_SIZE(thr, &func->bw_code);\n\n\tduk_set_length(thr, func->consts_idx, 0);\n\t/* keep func->h_funcs; inner functions are not reparsed to avoid O(depth^2) parsing */\n\tfunc->fnum_next = 0;\n\t/* duk_set_length(thr, func->funcs_idx, 0); */\n\tduk_set_length(thr, func->labelnames_idx, 0);\n\tduk_hbuffer_reset(thr, func->h_labelinfos);\n\t/* keep func->h_argnames; it is fixed for all passes */\n\n\t/* truncated in case pass 3 needed */\n\tduk_push_bare_object(thr);\n\tduk_replace(thr, func->varmap_idx);\n\tfunc->h_varmap = DUK_GET_HOBJECT_POSIDX(thr, func->varmap_idx);\n\tDUK_ASSERT(func->h_varmap != NULL);\n}\n\n/* cleanup varmap from any null entries, compact it, etc; returns number\n * of final entries after cleanup.\n */\nDUK_LOCAL duk_int_t duk__cleanup_varmap(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hobject *h_varmap;\n\tduk_hstring *h_key;\n\tduk_tval *tv;\n\tduk_uint32_t i, e_next;\n\tduk_int_t ret;\n\n\t/* [ ... varmap ] */\n\n\th_varmap = DUK_GET_HOBJECT_NEGIDX(thr, -1);\n\tDUK_ASSERT(h_varmap != NULL);\n\n\tret = 0;\n\te_next = DUK_HOBJECT_GET_ENEXT(h_varmap);\n\tfor (i = 0; i < e_next; i++) {\n\t\th_key = DUK_HOBJECT_E_GET_KEY(thr->heap, h_varmap, i);\n\t\tif (!h_key) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, h_varmap, i));\n\n\t\t/* The entries can either be register numbers or 'null' values.\n\t\t * Thus, no need to DECREF them and get side effects.  DECREF'ing\n\t\t * the keys (strings) can cause memory to be freed but no side\n\t\t * effects as strings don't have finalizers.  This is why we can\n\t\t * rely on the object properties not changing from underneath us.\n\t\t */\n\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, h_varmap, i);\n\t\tif (!DUK_TVAL_IS_NUMBER(tv)) {\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv));\n\t\t\tDUK_HOBJECT_E_SET_KEY(thr->heap, h_varmap, i, NULL);\n\t\t\tDUK_HSTRING_DECREF(thr, h_key);\n\t\t\t/* when key is NULL, value is garbage so no need to set */\n\t\t} else {\n\t\t\tret++;\n\t\t}\n\t}\n\n\tduk_compact_m1(thr);\n\n\treturn ret;\n}\n\n/* Convert duk_compiler_func into a function template, leaving the result\n * on top of stack.\n */\n/* XXX: awkward and bloated asm -- use faster internal accesses */\nDUK_LOCAL void duk__convert_to_func_template(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func = &comp_ctx->curr_func;\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hcompfunc *h_res;\n\tduk_hbuffer_fixed *h_data;\n\tduk_size_t consts_count;\n\tduk_size_t funcs_count;\n\tduk_size_t code_count;\n\tduk_size_t code_size;\n\tduk_size_t data_size;\n\tduk_size_t i;\n\tduk_tval *p_const;\n\tduk_hobject **p_func;\n\tduk_instr_t *p_instr;\n\tduk_compiler_instr *q_instr;\n\tduk_tval *tv;\n\tduk_bool_t keep_varmap;\n\tduk_bool_t keep_formals;\n#if !defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_size_t formals_length;\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"converting duk_compiler_func to function/template\"));\n\n\t/*\n\t *  Push result object and init its flags\n\t */\n\n\t/* Valstack should suffice here, required on function valstack init */\n\n\th_res = duk_push_hcompfunc(thr);\n\tDUK_ASSERT(h_res != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) h_res) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, (duk_hobject *) h_res, NULL);  /* Function templates are \"bare objects\". */\n\n\tif (func->is_function) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function -> set NEWENV\"));\n\t\tDUK_HOBJECT_SET_NEWENV((duk_hobject *) h_res);\n\n\t\tif (!func->is_arguments_shadowed) {\n\t\t\t/* arguments object would be accessible; note that shadowing\n\t\t\t * bindings are arguments or function declarations, neither\n\t\t\t * of which are deletable, so this is safe.\n\t\t\t */\n\n\t\t\tif (func->id_access_arguments || func->may_direct_eval) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"function may access 'arguments' object directly or \"\n\t\t\t\t                     \"indirectly -> set CREATEARGS\"));\n\t\t\t\tDUK_HOBJECT_SET_CREATEARGS((duk_hobject *) h_res);\n\t\t\t}\n\t\t}\n\t} else if (func->is_eval && func->is_strict) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"strict eval code -> set NEWENV\"));\n\t\tDUK_HOBJECT_SET_NEWENV((duk_hobject *) h_res);\n\t} else {\n\t\t/* non-strict eval: env is caller's env or global env (direct vs. indirect call)\n\t\t * global code: env is is global env\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"non-strict eval code or global code -> no NEWENV\"));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NEWENV((duk_hobject *) h_res));\n\t}\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tif (func->is_function && func->is_namebinding && func->h_name != NULL) {\n\t\t/* Object literal set/get functions have a name (property\n\t\t * name) but must not have a lexical name binding, see\n\t\t * test-bug-getset-func-name.js.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"function expression with a name -> set NAMEBINDING\"));\n\t\tDUK_HOBJECT_SET_NAMEBINDING((duk_hobject *) h_res);\n\t}\n#endif\n\n\tif (func->is_strict) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is strict -> set STRICT\"));\n\t\tDUK_HOBJECT_SET_STRICT((duk_hobject *) h_res);\n\t}\n\n\tif (func->is_notail) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is notail -> set NOTAIL\"));\n\t\tDUK_HOBJECT_SET_NOTAIL((duk_hobject *) h_res);\n\t}\n\n\tif (func->is_constructable) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is constructable -> set CONSTRUCTABLE\"));\n\t\tDUK_HOBJECT_SET_CONSTRUCTABLE((duk_hobject *) h_res);\n\t}\n\n\t/*\n\t *  Build function fixed size 'data' buffer, which contains bytecode,\n\t *  constants, and inner function references.\n\t *\n\t *  During the building phase 'data' is reachable but incomplete.\n\t *  Only incref's occur during building (no refzero or GC happens),\n\t *  so the building process is atomic.\n\t */\n\n\tconsts_count = duk_hobject_get_length(thr, func->h_consts);\n\tfuncs_count = duk_hobject_get_length(thr, func->h_funcs) / 3;\n\tcode_count = DUK_BW_GET_SIZE(thr, &func->bw_code) / sizeof(duk_compiler_instr);\n\tcode_size = code_count * sizeof(duk_instr_t);\n\n\tdata_size = consts_count * sizeof(duk_tval) +\n\t            funcs_count * sizeof(duk_hobject *) +\n\t            code_size;\n\n\tDUK_DDD(DUK_DDDPRINT(\"consts_count=%ld, funcs_count=%ld, code_size=%ld -> \"\n\t                     \"data_size=%ld*%ld + %ld*%ld + %ld = %ld\",\n\t                     (long) consts_count, (long) funcs_count, (long) code_size,\n\t                     (long) consts_count, (long) sizeof(duk_tval),\n\t                     (long) funcs_count, (long) sizeof(duk_hobject *),\n\t                     (long) code_size, (long) data_size));\n\n\tduk_push_fixed_buffer_nozero(thr, data_size);\n\th_data = (duk_hbuffer_fixed *) (void *) duk_known_hbuffer(thr, -1);\n\n\tDUK_HCOMPFUNC_SET_DATA(thr->heap, h_res, (duk_hbuffer *) h_data);\n\tDUK_HEAPHDR_INCREF(thr, h_data);\n\n\tp_const = (duk_tval *) (void *) DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, h_data);\n\tfor (i = 0; i < consts_count; i++) {\n\t\tDUK_ASSERT(i <= DUK_UARRIDX_MAX);  /* const limits */\n\t\ttv = duk_hobject_find_array_entry_tval_ptr(thr->heap, func->h_consts, (duk_uarridx_t) i);\n\t\tDUK_ASSERT(tv != NULL);\n\t\tDUK_TVAL_SET_TVAL(p_const, tv);\n\t\tp_const++;\n\t\tDUK_TVAL_INCREF(thr, tv);  /* may be a string constant */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"constant: %!T\", (duk_tval *) tv));\n\t}\n\n\tp_func = (duk_hobject **) p_const;\n\tDUK_HCOMPFUNC_SET_FUNCS(thr->heap, h_res, p_func);\n\tfor (i = 0; i < funcs_count; i++) {\n\t\tduk_hobject *h;\n\t\tDUK_ASSERT(i * 3 <= DUK_UARRIDX_MAX);  /* func limits */\n\t\ttv = duk_hobject_find_array_entry_tval_ptr(thr->heap, func->h_funcs, (duk_uarridx_t) (i * 3));\n\t\tDUK_ASSERT(tv != NULL);\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));\n\t\th = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(h));\n\t\t*p_func++ = h;\n\t\tDUK_HOBJECT_INCREF(thr, h);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"inner function: %p -> %!iO\",\n\t\t                     (void *) h, (duk_heaphdr *) h));\n\t}\n\n\tp_instr = (duk_instr_t *) p_func;\n\tDUK_HCOMPFUNC_SET_BYTECODE(thr->heap, h_res, p_instr);\n\n\t/* copy bytecode instructions one at a time */\n\tq_instr = (duk_compiler_instr *) (void *) DUK_BW_GET_BASEPTR(thr, &func->bw_code);\n\tfor (i = 0; i < code_count; i++) {\n\t\tp_instr[i] = q_instr[i].ins;\n\t}\n\t/* Note: 'q_instr' is still used below */\n\n\tDUK_ASSERT((duk_uint8_t *) (p_instr + code_count) == DUK_HBUFFER_FIXED_GET_DATA_PTR(thr->heap, h_data) + data_size);\n\n\tduk_pop(thr);  /* 'data' (and everything in it) is reachable through h_res now */\n\n\t/*\n\t *  Init non-property result fields\n\t *\n\t *  'nregs' controls how large a register frame is allocated.\n\t *\n\t *  'nargs' controls how many formal arguments are written to registers:\n\t *  r0, ... r(nargs-1).  The remaining registers are initialized to\n\t *  undefined.\n\t */\n\n\tDUK_ASSERT(func->temp_max >= 0);\n\th_res->nregs = (duk_uint16_t) func->temp_max;\n\th_res->nargs = (duk_uint16_t) duk_hobject_get_length(thr, func->h_argnames);\n\tDUK_ASSERT(h_res->nregs >= h_res->nargs);  /* pass2 allocation handles this */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\th_res->start_line = (duk_uint32_t) func->min_line;\n\th_res->end_line = (duk_uint32_t) func->max_line;\n#endif\n\n\t/*\n\t *  Init object properties\n\t *\n\t *  Properties should be added in decreasing order of access frequency.\n\t *  (Not very critical for function templates.)\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"init function properties\"));\n\n\t/* [ ... res ] */\n\n\t/* _Varmap: omitted if function is guaranteed not to do a slow path\n\t * identifier access that might be caught by locally declared variables.\n\t * The varmap can also be omitted if it turns out empty of actual\n\t * register mappings after a cleanup.  When debugging is enabled, we\n\t * always need the varmap to be able to lookup variables at any point.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tDUK_DD(DUK_DDPRINT(\"keeping _Varmap because debugger support is enabled\"));\n\tkeep_varmap = 1;\n#else\n\tif (func->id_access_slow_own ||   /* directly uses slow accesses that may match own variables */\n\t    func->id_access_arguments ||  /* accesses 'arguments' directly */\n\t    func->may_direct_eval ||      /* may indirectly slow access through a direct eval */\n\t    funcs_count > 0) {            /* has inner functions which may slow access (XXX: this can be optimized by looking at the inner functions) */\n\t\tDUK_DD(DUK_DDPRINT(\"keeping _Varmap because of direct eval, slow path access that may match local variables, or presence of inner functions\"));\n\t\tkeep_varmap = 1;\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"dropping _Varmap\"));\n\t\tkeep_varmap = 0;\n\t}\n#endif\n\n\tif (keep_varmap) {\n\t\tduk_int_t num_used;\n\t\tduk_dup(thr, func->varmap_idx);\n\t\tnum_used = duk__cleanup_varmap(comp_ctx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"cleaned up varmap: %!T (num_used=%ld)\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -1), (long) num_used));\n\n\t\tif (num_used > 0) {\n\t\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_VARMAP, DUK_PROPDESC_FLAGS_NONE);\n\t\t} else {\n\t\t\tDUK_DD(DUK_DDPRINT(\"varmap is empty after cleanup -> no need to add\"));\n\t\t\tduk_pop(thr);\n\t\t}\n\t}\n\n\t/* _Formals: omitted if function is guaranteed not to need a (non-strict)\n\t * arguments object, and _Formals.length matches nargs exactly.\n\t *\n\t * Non-arrow functions can't see an outer function's 'argument' binding\n\t * (because they have their own), but arrow functions can.  When arrow\n\t * functions are added, this condition would need to be added:\n\t *     inner_arrow_funcs_count > 0   inner arrow functions may access 'arguments'\n\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tDUK_DD(DUK_DDPRINT(\"keeping _Formals because debugger support is enabled\"));\n\tkeep_formals = 1;\n#else\n\tformals_length = duk_get_length(thr, func->argnames_idx);\n\tif (formals_length != (duk_size_t) h_res->nargs) {\n\t\t/* Nargs not enough for closure .length: keep _Formals regardless\n\t\t * of its length.  Shouldn't happen in practice at the moment.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"keeping _Formals because _Formals.length != nargs\"));\n\t\tkeep_formals = 1;\n\t} else if ((func->id_access_arguments || func->may_direct_eval) &&\n\t           (formals_length > 0)) {\n\t\t/* Direct eval (may access 'arguments') or accesses 'arguments'\n\t\t * explicitly: keep _Formals unless it is zero length.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"keeping _Formals because of direct eval or explicit access to 'arguments', and _Formals.length != 0\"));\n\t\tkeep_formals = 1;\n\t} else {\n\t\tDUK_DD(DUK_DDPRINT(\"omitting _Formals, nargs matches _Formals.length, so no properties added\"));\n\t\tkeep_formals = 0;\n\t}\n#endif\n\n\tif (keep_formals) {\n\t\tduk_dup(thr, func->argnames_idx);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_FORMALS, DUK_PROPDESC_FLAGS_NONE);\n\t}\n\n\t/* name */\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\tif (func->h_name) {\n\t\tduk_push_hstring(thr, func->h_name);\n\t\tDUK_DD(DUK_DDPRINT(\"setting function template .name to %!T\", duk_get_tval(thr, -1)));\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_NONE);\n\t}\n#endif  /* DUK_USE_FUNC_NAME_PROPERTY */\n\n\t/* _Source */\n#if defined(DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY)\n\tif (0) {\n\t\t/* XXX: Currently function source code is not stored, as it is not\n\t\t * required by the standard.  Source code should not be stored by\n\t\t * default (user should enable it explicitly), and the source should\n\t\t * probably be compressed with a trivial text compressor; average\n\t\t * compression of 20-30% is quite easy to achieve even with a trivial\n\t\t * compressor (RLE + backwards lookup).\n\t\t *\n\t\t * Debugging needs source code to be useful: sometimes input code is\n\t\t * not found in files as it may be generated and then eval()'d, given\n\t\t * by dynamic C code, etc.\n\t\t *\n\t\t * Other issues:\n\t\t *\n\t\t *   - Need tokenizer indices for start and end to substring\n\t\t *   - Always normalize function declaration part?\n\t\t *   - If we keep _Formals, only need to store body\n\t\t */\n\n\t\t/*\n\t\t *  For global or eval code this is straightforward.  For functions\n\t\t *  created with the Function constructor we only get the source for\n\t\t *  the body and must manufacture the \"function ...\" part.\n\t\t *\n\t\t *  For instance, for constructed functions (v8):\n\t\t *\n\t\t *    > a = new Function(\"foo\", \"bar\", \"print(foo)\");\n\t\t *    [Function]\n\t\t *    > a.toString()\n\t\t *    'function anonymous(foo,bar) {\\nprint(foo)\\n}'\n\t\t *\n\t\t *  Similarly for e.g. getters (v8):\n\t\t *\n\t\t *    > x = { get a(foo,bar) { print(foo); } }\n\t\t *    { a: [Getter] }\n\t\t *    > Object.getOwnPropertyDescriptor(x, 'a').get.toString()\n\t\t *    'function a(foo,bar) { print(foo); }'\n\t\t */\n\n#if 0\n\t\tduk_push_literal(thr, \"XXX\");\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_SOURCE, DUK_PROPDESC_FLAGS_NONE);\n#endif\n\t}\n#endif  /* DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY */\n\n\t/* _Pc2line */\n#if defined(DUK_USE_PC2LINE)\n\tif (1) {\n\t\t/*\n\t\t *  Size-optimized pc->line mapping.\n\t\t */\n\n\t\tDUK_ASSERT(code_count <= DUK_COMPILER_MAX_BYTECODE_LENGTH);\n\t\tduk_hobject_pc2line_pack(thr, q_instr, (duk_uint_fast32_t) code_count);  /* -> pushes fixed buffer */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_PC2LINE, DUK_PROPDESC_FLAGS_NONE);\n\n\t\t/* XXX: if assertions enabled, walk through all valid PCs\n\t\t * and check line mapping.\n\t\t */\n\t}\n#endif  /* DUK_USE_PC2LINE */\n\n\t/* fileName */\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tif (comp_ctx->h_filename) {\n\t\t/*\n\t\t *  Source filename (or equivalent), for identifying thrown errors.\n\t\t */\n\n\t\tduk_push_hstring(thr, comp_ctx->h_filename);\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_FILE_NAME, DUK_PROPDESC_FLAGS_NONE);\n\t}\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"converted function: %!ixT\",\n\t                   (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/*\n\t *  Compact the function template.\n\t */\n\n\tduk_compact_m1(thr);\n\n\t/*\n\t *  Debug dumping\n\t */\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t{\n\t\tduk_hcompfunc *h;\n\t\tduk_instr_t *p, *p_start, *p_end;\n\n\t\th = (duk_hcompfunc *) duk_get_hobject(thr, -1);\n\t\tp_start = (duk_instr_t *) DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, h);\n\t\tp_end = (duk_instr_t *) DUK_HCOMPFUNC_GET_CODE_END(thr->heap, h);\n\n\t\tp = p_start;\n\t\twhile (p < p_end) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"BC %04ld: %!I        ; 0x%08lx op=%ld (%!X) a=%ld b=%ld c=%ld\",\n\t\t\t                     (long) (p - p_start),\n\t\t\t                     (duk_instr_t) (*p),\n\t\t\t                     (unsigned long) (*p),\n\t\t\t                     (long) DUK_DEC_OP(*p),\n\t\t\t                     (long) DUK_DEC_OP(*p),\n\t\t\t                     (long) DUK_DEC_A(*p),\n\t\t\t                     (long) DUK_DEC_B(*p),\n\t\t\t                     (long) DUK_DEC_C(*p)));\n\t\t\tp++;\n\t\t}\n\t}\n#endif\n}\n\n/*\n *  Code emission helpers\n *\n *  Some emission helpers understand the range of target and source reg/const\n *  values and automatically emit shuffling code if necessary.  This is the\n *  case when the slot in question (A, B, C) is used in the standard way and\n *  for opcodes the emission helpers explicitly understand (like DUK_OP_MPUTOBJ).\n *\n *  The standard way is that:\n *    - slot A is a target register\n *    - slot B is a source register/constant\n *    - slot C is a source register/constant\n *\n *  If a slot is used in a non-standard way the caller must indicate this\n *  somehow.  If a slot is used as a target instead of a source (or vice\n *  versa), this can be indicated with a flag to trigger proper shuffling\n *  (e.g. DUK__EMIT_FLAG_B_IS_TARGET).  If the value in the slot is not\n *  register/const related at all, the caller must ensure that the raw value\n *  fits into the corresponding slot so as to not trigger shuffling.  The\n *  caller must set a \"no shuffle\" flag to ensure compilation fails if\n *  shuffling were to be triggered because of an internal error.\n *\n *  For slots B and C the raw slot size is 9 bits but one bit is reserved for\n *  the reg/const indicator.  To use the full 9-bit range for a raw value,\n *  shuffling must be disabled with the DUK__EMIT_FLAG_NO_SHUFFLE_{B,C} flag.\n *  Shuffling is only done for A, B, and C slots, not the larger BC or ABC slots.\n *\n *  There is call handling specific understanding in the A-B-C emitter to\n *  convert call setup and call instructions into indirect ones if necessary.\n */\n\n/* Code emission flags, passed in the 'opcode' field.  Opcode + flags\n * fit into 16 bits for now, so use duk_small_uint_t.\n */\n#define DUK__EMIT_FLAG_NO_SHUFFLE_A      (1 << 8)\n#define DUK__EMIT_FLAG_NO_SHUFFLE_B      (1 << 9)\n#define DUK__EMIT_FLAG_NO_SHUFFLE_C      (1 << 10)\n#define DUK__EMIT_FLAG_A_IS_SOURCE       (1 << 11)  /* slot A is a source (default: target) */\n#define DUK__EMIT_FLAG_B_IS_TARGET       (1 << 12)  /* slot B is a target (default: source) */\n#define DUK__EMIT_FLAG_C_IS_TARGET       (1 << 13)  /* slot C is a target (default: source) */\n#define DUK__EMIT_FLAG_BC_REGCONST       (1 << 14)  /* slots B and C are reg/const */\n#define DUK__EMIT_FLAG_RESERVE_JUMPSLOT  (1 << 15)  /* reserve a jumpslot after instr before target spilling, used for NEXTENUM */\n\n/* XXX: macro smaller than call? */\nDUK_LOCAL duk_int_t duk__get_current_pc(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_func *func;\n\tfunc = &comp_ctx->curr_func;\n\treturn (duk_int_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &func->bw_code) / sizeof(duk_compiler_instr));\n}\n\nDUK_LOCAL duk_compiler_instr *duk__get_instr_ptr(duk_compiler_ctx *comp_ctx, duk_int_t pc) {\n\tDUK_ASSERT(pc >= 0);\n\tDUK_ASSERT((duk_size_t) pc < (duk_size_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr)));\n\treturn ((duk_compiler_instr *) (void *) DUK_BW_GET_BASEPTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code)) + pc;\n}\n\n/* emit instruction; could return PC but that's not needed in the majority\n * of cases.\n */\nDUK_LOCAL void duk__emit(duk_compiler_ctx *comp_ctx, duk_instr_t ins) {\n#if defined(DUK_USE_PC2LINE)\n\tduk_int_t line;\n#endif\n\tduk_compiler_instr *instr;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__emit: 0x%08lx curr_token.start_line=%ld prev_token.start_line=%ld pc=%ld --> %!I\",\n\t                     (unsigned long) ins,\n\t                     (long) comp_ctx->curr_token.start_line,\n\t                     (long) comp_ctx->prev_token.start_line,\n\t                     (long) duk__get_current_pc(comp_ctx),\n\t                     (duk_instr_t) ins));\n\n\tinstr = (duk_compiler_instr *) (void *) DUK_BW_ENSURE_GETPTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, sizeof(duk_compiler_instr));\n\tDUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, sizeof(duk_compiler_instr));\n\n#if defined(DUK_USE_PC2LINE)\n\t/* The line number tracking is a bit inconsistent right now, which\n\t * affects debugger accuracy.  Mostly call sites emit opcodes when\n\t * they have parsed a token (say a terminating semicolon) and called\n\t * duk__advance().  In this case the line number of the previous\n\t * token is the most accurate one (except in prologue where\n\t * prev_token.start_line is 0).  This is probably not 100% correct\n\t * right now.\n\t */\n\t/* approximation, close enough */\n\tline = comp_ctx->prev_token.start_line;\n\tif (line == 0) {\n\t\tline = comp_ctx->curr_token.start_line;\n\t}\n#endif\n\n\tinstr->ins = ins;\n#if defined(DUK_USE_PC2LINE)\n\tinstr->line = (duk_uint32_t) line;\n#endif\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (line < comp_ctx->curr_func.min_line) {\n\t\tcomp_ctx->curr_func.min_line = line;\n\t}\n\tif (line > comp_ctx->curr_func.max_line) {\n\t\tcomp_ctx->curr_func.max_line = line;\n\t}\n#endif\n\n\t/* Limit checks for bytecode byte size and line number. */\n\tif (DUK_UNLIKELY(DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) > DUK_USE_ESBC_MAX_BYTES)) {\n\t\tgoto fail_bc_limit;\n\t}\n#if defined(DUK_USE_PC2LINE) && defined(DUK_USE_ESBC_LIMITS)\n#if defined(DUK_USE_BUFLEN16)\n\t/* Buffer length is bounded to 0xffff automatically, avoid compile warning. */\n\tif (DUK_UNLIKELY(line > DUK_USE_ESBC_MAX_LINENUMBER)) {\n\t\tgoto fail_bc_limit;\n\t}\n#else\n\tif (DUK_UNLIKELY(line > DUK_USE_ESBC_MAX_LINENUMBER)) {\n\t\tgoto fail_bc_limit;\n\t}\n#endif\n#endif\n\n\treturn;\n\n  fail_bc_limit:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_BYTECODE_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Update function min/max line from current token.  Needed to improve\n * function line range information for debugging, so that e.g. opening\n * curly brace is covered by line range even when no opcodes are emitted\n * for the line containing the brace.\n */\nDUK_LOCAL void duk__update_lineinfo_currtoken(duk_compiler_ctx *comp_ctx) {\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_int_t line;\n\n\tline = comp_ctx->curr_token.start_line;\n\tif (line == 0) {\n\t\treturn;\n\t}\n\tif (line < comp_ctx->curr_func.min_line) {\n\t\tcomp_ctx->curr_func.min_line = line;\n\t}\n\tif (line > comp_ctx->curr_func.max_line) {\n\t\tcomp_ctx->curr_func.max_line = line;\n\t}\n#else\n\tDUK_UNREF(comp_ctx);\n#endif\n}\n\nDUK_LOCAL void duk__emit_op_only(duk_compiler_ctx *comp_ctx, duk_small_uint_t op) {\n\tduk__emit(comp_ctx, DUK_ENC_OP_ABC(op, 0));\n}\n\n/* Important main primitive. */\nDUK_LOCAL void duk__emit_a_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b, duk_regconst_t c) {\n\tduk_instr_t ins = 0;\n\tduk_int_t a_out = -1;\n\tduk_int_t b_out = -1;\n\tduk_int_t c_out = -1;\n\tduk_int_t tmp;\n\tduk_small_uint_t op = op_flags & 0xffU;\n\n\tDUK_DDD(DUK_DDDPRINT(\"emit: op_flags=%04lx, a=%ld, b=%ld, c=%ld\",\n\t                     (unsigned long) op_flags, (long) a, (long) b, (long) c));\n\n\t/* We could rely on max temp/const checks: if they don't exceed BC\n\t * limit, nothing here can either (just asserts would be enough).\n\t * Currently we check for the limits, which provides additional\n\t * protection against creating invalid bytecode due to compiler\n\t * bugs.\n\t */\n\n\tDUK_ASSERT_DISABLE((op_flags & 0xff) >= DUK_BC_OP_MIN);  /* unsigned */\n\tDUK_ASSERT((op_flags & 0xff) <= DUK_BC_OP_MAX);\n\tDUK_ASSERT(DUK__ISREG(a));\n\tDUK_ASSERT(b != -1);  /* Not 'none'. */\n\tDUK_ASSERT(c != -1);  /* Not 'none'. */\n\n\t/* Input shuffling happens before the actual operation, while output\n\t * shuffling happens afterwards.  Output shuffling decisions are still\n\t * made at the same time to reduce branch clutter; output shuffle decisions\n\t * are recorded into X_out variables.\n\t */\n\n\t/* Slot A: currently no support for reg/const. */\n\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\tif (a <= DUK_BC_A_MAX && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A)) {\n#else\n\tif (a <= DUK_BC_A_MAX) {\n#endif\n\t\t;\n\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A) {\n\t\tDUK_D(DUK_DPRINT(\"out of regs: 'a' (reg) needs shuffling but shuffle prohibited, a: %ld\", (long) a));\n\t\tgoto error_outofregs;\n\t} else if (a <= DUK_BC_BC_MAX) {\n\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\ttmp = comp_ctx->curr_func.shuffle1;\n\t\tif (op_flags & DUK__EMIT_FLAG_A_IS_SOURCE) {\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, a));\n\t\t} else {\n\t\t\t/* Output shuffle needed after main operation */\n\t\t\ta_out = a;\n\n\t\t\t/* The DUK_OP_CSVAR output shuffle assumes shuffle registers are\n\t\t\t * consecutive.\n\t\t\t */\n\t\t\tDUK_ASSERT((comp_ctx->curr_func.shuffle1 == 0 && comp_ctx->curr_func.shuffle2 == 0) ||\n\t\t\t           (comp_ctx->curr_func.shuffle2 == comp_ctx->curr_func.shuffle1 + 1));\n\t\t\tif (op == DUK_OP_CSVAR) {\n\t\t\t\t/* For CSVAR the limit is one smaller because output shuffle\n\t\t\t\t * must be able to express 'a + 1' in BC.\n\t\t\t\t */\n\t\t\t\tif (a + 1 > DUK_BC_BC_MAX) {\n\t\t\t\t\tgoto error_outofregs;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ta = tmp;\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"out of regs: 'a' (reg) needs shuffling but does not fit into BC, a: %ld\", (long) a));\n\t\tgoto error_outofregs;\n\t}\n\n\t/* Slot B: reg/const support, mapped to bit 0 of opcode. */\n\n\tif ((b & DUK__CONST_MARKER) != 0) {\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B) == 0);\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_B_IS_TARGET) == 0);\n\t\tb = b & ~DUK__CONST_MARKER;\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (0) {\n#else\n\t\tif (b <= 0xff) {\n#endif\n\t\t\tif (op_flags & DUK__EMIT_FLAG_BC_REGCONST) {\n\t\t\t\t/* Opcode follows B/C reg/const convention. */\n\t\t\t\tDUK_ASSERT((op & 0x01) == 0);\n\t\t\t\tins |= DUK_ENC_OP_A_B_C(0x01, 0, 0, 0);  /* const flag for B */\n\t\t\t} else {\n\t\t\t\tDUK_D(DUK_DPRINT(\"B is const, opcode is not B/C reg/const: %x\", op_flags));\n\t\t\t}\n\t\t} else if (b <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle2;\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDCONST, tmp, b));\n\t\t\tb = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'b' (const) needs shuffling but does not fit into BC, b: %ld\", (long) b));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t} else {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (b <= 0xff && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B)) {\n#else\n\t\tif (b <= 0xff) {\n#endif\n\t\t\t;\n\t\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_B) {\n\t\t\tif (b > DUK_BC_B_MAX) {\n\t\t\t\t/* Note: 0xff != DUK_BC_B_MAX */\n\t\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'b' (reg) needs shuffling but shuffle prohibited, b: %ld\", (long) b));\n\t\t\t\tgoto error_outofregs;\n\t\t\t}\n\t\t} else if (b <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle2;\n\t\t\tif (op_flags & DUK__EMIT_FLAG_B_IS_TARGET) {\n\t\t\t\t/* Output shuffle needed after main operation */\n\t\t\t\tb_out = b;\n\t\t\t}\n\t\t\tif (!(op_flags & DUK__EMIT_FLAG_B_IS_TARGET)) {\n\t\t\t\tif (op == DUK_OP_MPUTOBJ || op == DUK_OP_MPUTARR) {\n\t\t\t\t\t/* Special handling for MPUTOBJ/MPUTARR shuffling.\n\t\t\t\t\t * For each, slot B identifies the first register of a range\n\t\t\t\t\t * of registers, so normal shuffling won't work.  Instead,\n\t\t\t\t\t * an indirect version of the opcode is used.\n\t\t\t\t\t */\n\t\t\t\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_B_IS_TARGET) == 0);\n\t\t\t\t\tduk__emit_load_int32_noshuffle(comp_ctx, tmp, b);\n\t\t\t\t\tDUK_ASSERT(DUK_OP_MPUTOBJI == DUK_OP_MPUTOBJ + 1);\n\t\t\t\t\tDUK_ASSERT(DUK_OP_MPUTARRI == DUK_OP_MPUTARR + 1);\n\t\t\t\t\top_flags++;  /* indirect opcode follows direct */\n\t\t\t\t} else {\n\t\t\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, b));\n\t\t\t\t}\n\t\t\t}\n\t\t\tb = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'b' (reg) needs shuffling but does not fit into BC, b: %ld\", (long) b));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t}\n\n\t/* Slot C: reg/const support, mapped to bit 1 of opcode. */\n\n\tif ((c & DUK__CONST_MARKER) != 0) {\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C) == 0);\n\t\tDUK_ASSERT((op_flags & DUK__EMIT_FLAG_C_IS_TARGET) == 0);\n\t\tc = c & ~DUK__CONST_MARKER;\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (0) {\n#else\n\t\tif (c <= 0xff) {\n#endif\n\t\t\tif (op_flags & DUK__EMIT_FLAG_BC_REGCONST) {\n\t\t\t\t/* Opcode follows B/C reg/const convention. */\n\t\t\t\tDUK_ASSERT((op & 0x02) == 0);\n\t\t\t\tins |= DUK_ENC_OP_A_B_C(0x02, 0, 0, 0);  /* const flag for C */\n\t\t\t} else {\n\t\t\t\tDUK_D(DUK_DPRINT(\"C is const, opcode is not B/C reg/const: %x\", op_flags));\n\t\t\t}\n\t\t} else if (c <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle3;\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDCONST, tmp, c));\n\t\t\tc = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'c' (const) needs shuffling but does not fit into BC, c: %ld\", (long) c));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t} else {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\t\tif (c <= 0xff && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C)) {\n#else\n\t\tif (c <= 0xff) {\n#endif\n\t\t\t;\n\t\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_C) {\n\t\t\tif (c > DUK_BC_C_MAX) {\n\t\t\t\t/* Note: 0xff != DUK_BC_C_MAX */\n\t\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'c' (reg) needs shuffling but shuffle prohibited, c: %ld\", (long) c));\n\t\t\t\tgoto error_outofregs;\n\t\t\t}\n\t\t} else if (c <= DUK_BC_BC_MAX) {\n\t\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\t\ttmp = comp_ctx->curr_func.shuffle3;\n\t\t\tif (op_flags & DUK__EMIT_FLAG_C_IS_TARGET) {\n\t\t\t\t/* Output shuffle needed after main operation */\n\t\t\t\tc_out = c;\n\t\t\t} else {\n\t\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, c));\n\t\t\t}\n\t\t\tc = tmp;\n\t\t} else {\n\t\t\tDUK_D(DUK_DPRINT(\"out of regs: 'c' (reg) needs shuffling but does not fit into BC, c: %ld\", (long) c));\n\t\t\tgoto error_outofregs;\n\t\t}\n\t}\n\n\t/* Main operation */\n\n\tDUK_ASSERT(a >= DUK_BC_A_MIN);\n\tDUK_ASSERT(a <= DUK_BC_A_MAX);\n\tDUK_ASSERT(b >= DUK_BC_B_MIN);\n\tDUK_ASSERT(b <= DUK_BC_B_MAX);\n\tDUK_ASSERT(c >= DUK_BC_C_MIN);\n\tDUK_ASSERT(c <= DUK_BC_C_MAX);\n\n\tins |= DUK_ENC_OP_A_B_C(op_flags & 0xff, a, b, c);\n\tduk__emit(comp_ctx, ins);\n\n\t/* NEXTENUM needs a jump slot right after the main instruction.\n\t * When the JUMP is taken, output spilling is not needed so this\n\t * workaround is possible.  The jump slot PC is exceptionally\n\t * plumbed through comp_ctx to minimize call sites.\n\t */\n\tif (op_flags & DUK__EMIT_FLAG_RESERVE_JUMPSLOT) {\n\t\tcomp_ctx->emit_jumpslot_pc = duk__get_current_pc(comp_ctx);\n\t\tduk__emit_abc(comp_ctx, DUK_OP_JUMP, 0);\n\t}\n\n\t/* Output shuffling: only one output register is realistically possible.\n\t *\n\t * (Zero would normally be an OK marker value: if the target register\n\t * was zero, it would never be shuffled.  But with DUK_USE_SHUFFLE_TORTURE\n\t * this is no longer true, so use -1 as a marker instead.)\n\t */\n\n\tif (a_out >= 0) {\n\t\tDUK_ASSERT(b_out < 0);\n\t\tDUK_ASSERT(c_out < 0);\n\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, a, a_out));\n\n\t\tif (op == DUK_OP_CSVAR) {\n\t\t\t/* Special handling for CSVAR shuffling.  The variable lookup\n\t\t\t * results in a <value, this binding> pair in successive\n\t\t\t * registers so use two shuffle registers and two output\n\t\t\t * loads.  (In practice this is dead code because temp/const\n\t\t\t * limit is reached first.)\n\t\t\t */\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, a + 1, a_out + 1));\n\t\t}\n\t} else if (b_out >= 0) {\n\t\tDUK_ASSERT(a_out < 0);\n\t\tDUK_ASSERT(c_out < 0);\n\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, b, b_out));\n\t} else if (c_out >= 0) {\n\t\tDUK_ASSERT(b_out < 0);\n\t\tDUK_ASSERT(c_out < 0);\n\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, c, c_out));\n\t}\n\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* For many of the helpers below it'd be technically correct to add\n * \"no shuffle\" flags for parameters passed in as zero.  For example,\n * duk__emit_a_b() should call duk__emit_a_b_c() with C set to 0, and\n * DUK__EMIT_FLAG_NO_SHUFFLE_C added to op_flags.  However, since the\n * C value is 0, it'll never get shuffled so adding the flag is just\n * unnecessary additional code.  This is unfortunately not true for\n * \"shuffle torture\" mode which needs special handling.\n */\n\nDUK_LOCAL void duk__emit_a_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t b) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_C;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, a, b, 0);\n}\n\nDUK_LOCAL void duk__emit_b_c(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b, duk_regconst_t c) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_A;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, 0, b, c);\n}\n\n#if 0  /* unused */\nDUK_LOCAL void duk__emit_a(duk_compiler_ctx *comp_ctx, int op_flags, int a) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_B | DUK__EMIT_FLAG_NO_SHUFFLE_C;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, a, 0, 0);\n}\n#endif\n\n#if 0  /* unused */\nDUK_LOCAL void duk__emit_b(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t b) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top_flags |= DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_NO_SHUFFLE_C;\n#endif\n\tduk__emit_a_b_c(comp_ctx, op_flags, 0, b, 0);\n}\n#endif\n\nDUK_LOCAL void duk__emit_a_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op_flags, duk_regconst_t a, duk_regconst_t bc) {\n\tduk_instr_t ins;\n\tduk_int_t tmp;\n\n\t/* allow caller to give a const number with the DUK__CONST_MARKER */\n\tDUK_ASSERT(bc != -1);  /* Not 'none'. */\n\tbc = bc & (~DUK__CONST_MARKER);\n\n\tDUK_ASSERT_DISABLE((op_flags & 0xff) >= DUK_BC_OP_MIN);  /* unsigned */\n\tDUK_ASSERT((op_flags & 0xff) <= DUK_BC_OP_MAX);\n\tDUK_ASSERT(bc >= DUK_BC_BC_MIN);\n\tDUK_ASSERT(bc <= DUK_BC_BC_MAX);\n\tDUK_ASSERT((bc & DUK__CONST_MARKER) == 0);\n\n\tif (bc <= DUK_BC_BC_MAX) {\n\t\t;\n\t} else {\n\t\t/* No BC shuffling now. */\n\t\tgoto error_outofregs;\n\t}\n\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\tif (a <= DUK_BC_A_MAX && (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A)) {\n#else\n\tif (a <= DUK_BC_A_MAX) {\n#endif\n\t\tins = DUK_ENC_OP_A_BC(op_flags & 0xff, a, bc);\n\t\tduk__emit(comp_ctx, ins);\n\t} else if (op_flags & DUK__EMIT_FLAG_NO_SHUFFLE_A) {\n\t\tgoto error_outofregs;\n\t} else if ((op_flags & 0xf0U) == DUK_OP_CALL0) {\n\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\ttmp = comp_ctx->curr_func.shuffle1;\n\t\tduk__emit_load_int32_noshuffle(comp_ctx, tmp, a);\n\t\top_flags |= DUK_BC_CALL_FLAG_INDIRECT;\n\t\tins = DUK_ENC_OP_A_BC(op_flags & 0xff, tmp, bc);\n\t\tduk__emit(comp_ctx, ins);\n\t} else if (a <= DUK_BC_BC_MAX) {\n\t\tcomp_ctx->curr_func.needs_shuffle = 1;\n\t\ttmp = comp_ctx->curr_func.shuffle1;\n\t\tins = DUK_ENC_OP_A_BC(op_flags & 0xff, tmp, bc);\n\t\tif (op_flags & DUK__EMIT_FLAG_A_IS_SOURCE) {\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_LDREG, tmp, a));\n\t\t\tduk__emit(comp_ctx, ins);\n\t\t} else {\n\t\t\tduk__emit(comp_ctx, ins);\n\t\t\tduk__emit(comp_ctx, DUK_ENC_OP_A_BC(DUK_OP_STREG, tmp, a));\n\t\t}\n\t} else {\n\t\tgoto error_outofregs;\n\t}\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__emit_bc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t bc) {\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n\top |= DUK__EMIT_FLAG_NO_SHUFFLE_A;\n#endif\n\tduk__emit_a_bc(comp_ctx, op, 0, bc);\n}\n\nDUK_LOCAL void duk__emit_abc(duk_compiler_ctx *comp_ctx, duk_small_uint_t op, duk_regconst_t abc) {\n\tduk_instr_t ins;\n\n\tDUK_ASSERT_DISABLE(op >= DUK_BC_OP_MIN);  /* unsigned */\n\tDUK_ASSERT(op <= DUK_BC_OP_MAX);\n\tDUK_ASSERT_DISABLE(abc >= DUK_BC_ABC_MIN);  /* unsigned */\n\tDUK_ASSERT(abc <= DUK_BC_ABC_MAX);\n\tDUK_ASSERT((abc & DUK__CONST_MARKER) == 0);\n\tDUK_ASSERT(abc != -1);  /* Not 'none'. */\n\n\tif (abc <= DUK_BC_ABC_MAX) {\n\t\t;\n\t} else {\n\t\tgoto error_outofregs;\n\t}\n\tins = DUK_ENC_OP_ABC(op, abc);\n\tDUK_DDD(DUK_DDDPRINT(\"duk__emit_abc: 0x%08lx line=%ld pc=%ld op=%ld (%!X) abc=%ld (%!I)\",\n\t                     (unsigned long) ins, (long) comp_ctx->curr_token.start_line,\n\t                     (long) duk__get_current_pc(comp_ctx), (long) op, (long) op,\n\t                     (long) abc, (duk_instr_t) ins));\n\tduk__emit(comp_ctx, ins);\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__emit_load_int32_raw(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val, duk_small_uint_t op_flags) {\n\t/* XXX: Shuffling support could be implemented here so that LDINT+LDINTX\n\t * would only shuffle once (instead of twice).  The current code works\n\t * though, and has a smaller compiler footprint.\n\t */\n\n\tif ((val >= (duk_int32_t) DUK_BC_BC_MIN - (duk_int32_t) DUK_BC_LDINT_BIAS) &&\n\t    (val <= (duk_int32_t) DUK_BC_BC_MAX - (duk_int32_t) DUK_BC_LDINT_BIAS)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"emit LDINT to reg %ld for %ld\", (long) reg, (long) val));\n\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDINT | op_flags, reg, (duk_regconst_t) (val + (duk_int32_t) DUK_BC_LDINT_BIAS));\n\t} else {\n\t\tduk_int32_t hi = val >> DUK_BC_LDINTX_SHIFT;\n\t\tduk_int32_t lo = val & ((((duk_int32_t) 1) << DUK_BC_LDINTX_SHIFT) - 1);\n\t\tDUK_ASSERT(lo >= 0);\n\t\tDUK_DDD(DUK_DDDPRINT(\"emit LDINT+LDINTX to reg %ld for %ld -> hi %ld, lo %ld\",\n\t\t                     (long) reg, (long) val, (long) hi, (long) lo));\n\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDINT | op_flags, reg, (duk_regconst_t) (hi + (duk_int32_t) DUK_BC_LDINT_BIAS));\n\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDINTX | op_flags, reg, (duk_regconst_t) lo);\n\t}\n}\n\nDUK_LOCAL void duk__emit_load_int32(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val) {\n\tduk__emit_load_int32_raw(comp_ctx, reg, val, 0 /*op_flags*/);\n}\n\n#if defined(DUK_USE_SHUFFLE_TORTURE)\n/* Used by duk__emit*() calls so that we don't shuffle the loadints that\n * are needed to handle indirect opcodes.\n */\nDUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val) {\n\tduk__emit_load_int32_raw(comp_ctx, reg, val, DUK__EMIT_FLAG_NO_SHUFFLE_A /*op_flags*/);\n}\n#else\nDUK_LOCAL void duk__emit_load_int32_noshuffle(duk_compiler_ctx *comp_ctx, duk_regconst_t reg, duk_int32_t val) {\n\t/* When torture not enabled, can just use the same helper because\n\t * 'reg' won't get spilled.\n\t */\n\tDUK_ASSERT(reg <= DUK_BC_A_MAX);\n\tduk__emit_load_int32(comp_ctx, reg, val);\n}\n#endif\n\nDUK_LOCAL void duk__emit_jump(duk_compiler_ctx *comp_ctx, duk_int_t target_pc) {\n\tduk_int_t curr_pc;\n\tduk_int_t offset;\n\n\tcurr_pc = (duk_int_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr));\n\toffset = (duk_int_t) target_pc - (duk_int_t) curr_pc - 1;\n\tDUK_ASSERT(offset + DUK_BC_JUMP_BIAS >= DUK_BC_ABC_MIN);\n\tDUK_ASSERT(offset + DUK_BC_JUMP_BIAS <= DUK_BC_ABC_MAX);\n\tduk__emit_abc(comp_ctx, DUK_OP_JUMP, (duk_regconst_t) (offset + DUK_BC_JUMP_BIAS));\n}\n\nDUK_LOCAL duk_int_t duk__emit_jump_empty(duk_compiler_ctx *comp_ctx) {\n\tduk_int_t ret;\n\n\tret = duk__get_current_pc(comp_ctx);  /* useful for patching jumps later */\n\tduk__emit_op_only(comp_ctx, DUK_OP_JUMP);\n\treturn ret;\n}\n\n/* Insert an empty jump in the middle of code emitted earlier.  This is\n * currently needed for compiling for-in.\n */\nDUK_LOCAL void duk__insert_jump_entry(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc) {\n#if defined(DUK_USE_PC2LINE)\n\tduk_int_t line;\n#endif\n\tduk_compiler_instr *instr;\n\tduk_size_t offset;\n\n\tDUK_ASSERT(jump_pc >= 0);\n\toffset = (duk_size_t) jump_pc * sizeof(duk_compiler_instr);\n\tinstr = (duk_compiler_instr *) (void *)\n\t        DUK_BW_INSERT_ENSURE_AREA(comp_ctx->thr,\n\t                                  &comp_ctx->curr_func.bw_code,\n\t                                  offset,\n\t                                  sizeof(duk_compiler_instr));\n\n#if defined(DUK_USE_PC2LINE)\n\tline = comp_ctx->curr_token.start_line;  /* approximation, close enough */\n#endif\n\tinstr->ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, 0);\n#if defined(DUK_USE_PC2LINE)\n\tinstr->line = (duk_uint32_t) line;\n#endif\n\n\tDUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, sizeof(duk_compiler_instr));\n\tif (DUK_UNLIKELY(DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) > DUK_USE_ESBC_MAX_BYTES)) {\n\t\tgoto fail_bc_limit;\n\t}\n\treturn;\n\n  fail_bc_limit:\n\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_BYTECODE_LIMIT);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Does not assume that jump_pc contains a DUK_OP_JUMP previously; this is intentional\n * to allow e.g. an INVALID opcode be overwritten with a JUMP (label management uses this).\n */\nDUK_LOCAL void duk__patch_jump(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc, duk_int_t target_pc) {\n\tduk_compiler_instr *instr;\n\tduk_int_t offset;\n\n\t/* allow negative PCs, behave as a no-op */\n\tif (jump_pc < 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__patch_jump(): nop call, jump_pc=%ld (<0), target_pc=%ld\",\n\t\t                     (long) jump_pc, (long) target_pc));\n\t\treturn;\n\t}\n\tDUK_ASSERT(jump_pc >= 0);\n\n\t/* XXX: range assert */\n\tinstr = duk__get_instr_ptr(comp_ctx, jump_pc);\n\tDUK_ASSERT(instr != NULL);\n\n\t/* XXX: range assert */\n\toffset = target_pc - jump_pc - 1;\n\n\tinstr->ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, offset + DUK_BC_JUMP_BIAS);\n\tDUK_DDD(DUK_DDDPRINT(\"duk__patch_jump(): jump_pc=%ld, target_pc=%ld, offset=%ld\",\n\t                     (long) jump_pc, (long) target_pc, (long) offset));\n}\n\nDUK_LOCAL void duk__patch_jump_here(duk_compiler_ctx *comp_ctx, duk_int_t jump_pc) {\n\tduk__patch_jump(comp_ctx, jump_pc, duk__get_current_pc(comp_ctx));\n}\n\nDUK_LOCAL void duk__patch_trycatch(duk_compiler_ctx *comp_ctx, duk_int_t ldconst_pc, duk_int_t trycatch_pc, duk_regconst_t reg_catch, duk_regconst_t const_varname, duk_small_uint_t flags) {\n\tduk_compiler_instr *instr;\n\n\tDUK_ASSERT(DUK__ISREG(reg_catch));\n\n\tinstr = duk__get_instr_ptr(comp_ctx, ldconst_pc);\n\tDUK_ASSERT(DUK_DEC_OP(instr->ins) == DUK_OP_LDCONST);\n\tDUK_ASSERT(instr != NULL);\n\tif (const_varname & DUK__CONST_MARKER) {\n\t\t/* Have a catch variable. */\n\t\tconst_varname = const_varname & (~DUK__CONST_MARKER);\n\t\tif (reg_catch > DUK_BC_BC_MAX || const_varname > DUK_BC_BC_MAX) {\n\t\t\t/* Catch attempts to use out-of-range reg/const.  Without this\n\t\t\t * check Duktape 0.12.0 could generate invalid code which caused\n\t\t\t * an assert failure on execution.  This error is triggered e.g.\n\t\t\t * for functions with a lot of constants and a try-catch statement.\n\t\t\t * Shuffling or opcode semantics change is needed to fix the issue.\n\t\t\t * See: test-bug-trycatch-many-constants.js.\n\t\t\t */\n\t\t\tDUK_D(DUK_DPRINT(\"failed to patch trycatch: flags=%ld, reg_catch=%ld, const_varname=%ld (0x%08lx)\",\n\t\t\t                 (long) flags, (long) reg_catch, (long) const_varname, (long) const_varname));\n\t\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_REG_LIMIT);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tinstr->ins |= DUK_ENC_OP_A_BC(0, 0, const_varname);\n\t} else {\n\t\t/* No catch variable, e.g. a try-finally; replace LDCONST with\n\t\t * NOP to avoid a bogus LDCONST.\n\t\t */\n\t\tinstr->ins = DUK_ENC_OP(DUK_OP_NOP);\n\t}\n\n\tinstr = duk__get_instr_ptr(comp_ctx, trycatch_pc);\n\tDUK_ASSERT(instr != NULL);\n\tDUK_ASSERT_DISABLE(flags >= DUK_BC_A_MIN);\n\tDUK_ASSERT(flags <= DUK_BC_A_MAX);\n\tinstr->ins = DUK_ENC_OP_A_BC(DUK_OP_TRYCATCH, flags, reg_catch);\n}\n\nDUK_LOCAL void duk__emit_if_false_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst) {\n\tduk_small_uint_t op;\n\n\top = DUK__ISREG(regconst) ? DUK_OP_IFFALSE_R : DUK_OP_IFFALSE_C;\n\tduk__emit_bc(comp_ctx, op, regconst);  /* helper will remove const flag */\n}\n\nDUK_LOCAL void duk__emit_if_true_skip(duk_compiler_ctx *comp_ctx, duk_regconst_t regconst) {\n\tduk_small_uint_t op;\n\n\top = DUK__ISREG(regconst) ? DUK_OP_IFTRUE_R : DUK_OP_IFTRUE_C;\n\tduk__emit_bc(comp_ctx, op, regconst);  /* helper will remove const flag */\n}\n\nDUK_LOCAL void duk__emit_invalid(duk_compiler_ctx *comp_ctx) {\n\tduk__emit_op_only(comp_ctx, DUK_OP_INVALID);\n}\n\n/*\n *  Peephole optimizer for finished bytecode.\n *\n *  Does not remove opcodes; currently only straightens out unconditional\n *  jump chains which are generated by several control structures.\n */\n\nDUK_LOCAL void duk__peephole_optimize_bytecode(duk_compiler_ctx *comp_ctx) {\n\tduk_compiler_instr *bc;\n\tduk_small_uint_t iter;\n\tduk_int_t i, n;\n\tduk_int_t count_opt;\n\n\tbc = (duk_compiler_instr *) (void *) DUK_BW_GET_BASEPTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code);\n#if defined(DUK_USE_BUFLEN16)\n\t/* No need to assert, buffer size maximum is 0xffff. */\n#else\n\tDUK_ASSERT((duk_size_t) DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr) <= (duk_size_t) DUK_INT_MAX);  /* bytecode limits */\n#endif\n\tn = (duk_int_t) (DUK_BW_GET_SIZE(comp_ctx->thr, &comp_ctx->curr_func.bw_code) / sizeof(duk_compiler_instr));\n\n\tfor (iter = 0; iter < DUK_COMPILER_PEEPHOLE_MAXITER; iter++) {\n\t\tcount_opt = 0;\n\n\t\tfor (i = 0; i < n; i++) {\n\t\t\tduk_instr_t ins;\n\t\t\tduk_int_t target_pc1;\n\t\t\tduk_int_t target_pc2;\n\n\t\t\tins = bc[i].ins;\n\t\t\tif (DUK_DEC_OP(ins) != DUK_OP_JUMP) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttarget_pc1 = i + 1 + (duk_int_t) DUK_DEC_ABC(ins) - (duk_int_t) DUK_BC_JUMP_BIAS;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"consider jump at pc %ld; target_pc=%ld\", (long) i, (long) target_pc1));\n\t\t\tDUK_ASSERT(target_pc1 >= 0);\n\t\t\tDUK_ASSERT(target_pc1 < n);\n\n\t\t\t/* Note: if target_pc1 == i, we'll optimize a jump to itself.\n\t\t\t * This does not need to be checked for explicitly; the case\n\t\t\t * is rare and max iter breaks us out.\n\t\t\t */\n\n\t\t\tins = bc[target_pc1].ins;\n\t\t\tif (DUK_DEC_OP(ins) != DUK_OP_JUMP) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\ttarget_pc2 = target_pc1 + 1 + (duk_int_t) DUK_DEC_ABC(ins) - (duk_int_t) DUK_BC_JUMP_BIAS;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"optimizing jump at pc %ld; old target is %ld -> new target is %ld\",\n\t\t\t                     (long) i, (long) target_pc1, (long) target_pc2));\n\n\t\t\tbc[i].ins = DUK_ENC_OP_ABC(DUK_OP_JUMP, target_pc2 - (i + 1) + DUK_BC_JUMP_BIAS);\n\n\t\t\tcount_opt++;\n\t\t}\n\n\t\tDUK_DD(DUK_DDPRINT(\"optimized %ld jumps on peephole round %ld\", (long) count_opt, (long) (iter + 1)));\n\n\t\tif (count_opt == 0) {\n\t\t\tbreak;\n\t\t}\n\t}\n}\n\n/*\n *  Intermediate value helpers\n */\n\n/* Flags for intermediate value coercions.  A flag for using a forced reg\n * is not needed, the forced_reg argument suffices and generates better\n * code (it is checked as it is used).\n */\n/* XXX: DUK__IVAL_FLAG_REQUIRE_SHORT is passed but not currently implemented\n * by ispec/ivalue operations.\n */\n#define DUK__IVAL_FLAG_ALLOW_CONST          (1 << 0)  /* allow a constant to be returned */\n#define DUK__IVAL_FLAG_REQUIRE_TEMP         (1 << 1)  /* require a (mutable) temporary as a result (or a const if allowed) */\n#define DUK__IVAL_FLAG_REQUIRE_SHORT        (1 << 2)  /* require a short (8-bit) reg/const which fits into bytecode B/C slot */\n\n/* XXX: some code might benefit from DUK__SETTEMP_IFTEMP(thr,x) */\n\n#if 0  /* enable manually for dumping */\n#define DUK__DUMP_ISPEC(compctx,ispec) do { duk__dump_ispec((compctx), (ispec)); } while (0)\n#define DUK__DUMP_IVALUE(compctx,ivalue) do { duk__dump_ivalue((compctx), (ivalue)); } while (0)\n\nDUK_LOCAL void duk__dump_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *x) {\n\tDUK_D(DUK_DPRINT(\"ispec dump: t=%ld regconst=0x%08lx, valstack_idx=%ld, value=%!T\",\n\t                 (long) x->t, (unsigned long) x->regconst, (long) x->valstack_idx,\n\t                 duk_get_tval(comp_ctx->thr, x->valstack_idx)));\n}\nDUK_LOCAL void duk__dump_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tDUK_D(DUK_DPRINT(\"ivalue dump: t=%ld op=%ld \"\n\t                 \"x1={t=%ld regconst=0x%08lx valstack_idx=%ld value=%!T} \"\n\t                 \"x2={t=%ld regconst=0x%08lx valstack_idx=%ld value=%!T}\",\n\t\t         (long) x->t, (long) x->op,\n\t                 (long) x->x1.t, (unsigned long) x->x1.regconst, (long) x->x1.valstack_idx,\n\t                 duk_get_tval(comp_ctx->thr, x->x1.valstack_idx),\n\t                 (long) x->x2.t, (unsigned long) x->x2.regconst, (long) x->x2.valstack_idx,\n\t                 duk_get_tval(comp_ctx->thr, x->x2.valstack_idx)));\n}\n#else\n#define DUK__DUMP_ISPEC(comp_ctx,x) do {} while (0)\n#define DUK__DUMP_IVALUE(comp_ctx,x) do {} while (0)\n#endif\n\nDUK_LOCAL void duk__ivalue_regconst(duk_ivalue *x, duk_regconst_t regconst) {\n\tx->t = DUK_IVAL_PLAIN;\n\tx->x1.t = DUK_ISPEC_REGCONST;\n\tx->x1.regconst = regconst;\n}\n\nDUK_LOCAL void duk__ivalue_plain_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tx->t = DUK_IVAL_PLAIN;\n\tx->x1.t = DUK_ISPEC_VALUE;\n\tduk_replace(comp_ctx->thr, x->x1.valstack_idx);\n}\n\nDUK_LOCAL void duk__ivalue_var_fromstack(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tx->t = DUK_IVAL_VAR;\n\tx->x1.t = DUK_ISPEC_VALUE;\n\tduk_replace(comp_ctx->thr, x->x1.valstack_idx);\n}\n\nDUK_LOCAL_DECL void duk__ivalue_var_hstring(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n\tduk_push_hstring(comp_ctx->thr, h);\n\tduk__ivalue_var_fromstack(comp_ctx, x);\n}\n\nDUK_LOCAL void duk__copy_ispec(duk_compiler_ctx *comp_ctx, duk_ispec *src, duk_ispec *dst) {\n\tdst->t = src->t;\n\tdst->regconst = src->regconst;\n\tduk_copy(comp_ctx->thr, src->valstack_idx, dst->valstack_idx);\n}\n\nDUK_LOCAL void duk__copy_ivalue(duk_compiler_ctx *comp_ctx, duk_ivalue *src, duk_ivalue *dst) {\n\tdst->t = src->t;\n\tdst->op = src->op;\n\tdst->x1.t = src->x1.t;\n\tdst->x1.regconst = src->x1.regconst;\n\tdst->x2.t = src->x2.t;\n\tdst->x2.regconst = src->x2.regconst;\n\tduk_copy(comp_ctx->thr, src->x1.valstack_idx, dst->x1.valstack_idx);\n\tduk_copy(comp_ctx->thr, src->x2.valstack_idx, dst->x2.valstack_idx);\n}\n\nDUK_LOCAL duk_regconst_t duk__alloctemps(duk_compiler_ctx *comp_ctx, duk_small_int_t num) {\n\tduk_regconst_t res;\n\n\tres = comp_ctx->curr_func.temp_next;\n\tcomp_ctx->curr_func.temp_next += num;\n\n\tif (comp_ctx->curr_func.temp_next > DUK__MAX_TEMPS) {  /* == DUK__MAX_TEMPS is OK */\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_TEMP_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* maintain highest 'used' temporary, needed to figure out nregs of function */\n\tif (comp_ctx->curr_func.temp_next > comp_ctx->curr_func.temp_max) {\n\t\tcomp_ctx->curr_func.temp_max = comp_ctx->curr_func.temp_next;\n\t}\n\n\treturn res;\n}\n\nDUK_LOCAL duk_regconst_t duk__alloctemp(duk_compiler_ctx *comp_ctx) {\n\treturn duk__alloctemps(comp_ctx, 1);\n}\n\nDUK_LOCAL void duk__settemp_checkmax(duk_compiler_ctx *comp_ctx, duk_regconst_t temp_next) {\n\tcomp_ctx->curr_func.temp_next = temp_next;\n\tif (temp_next > comp_ctx->curr_func.temp_max) {\n\t\tcomp_ctx->curr_func.temp_max = temp_next;\n\t}\n}\n\n/* get const for value at valstack top */\nDUK_LOCAL duk_regconst_t duk__getconst(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_compiler_func *f = &comp_ctx->curr_func;\n\tduk_tval *tv1;\n\tduk_int_t i, n, n_check;\n\n\tn = (duk_int_t) duk_get_length(thr, f->consts_idx);\n\n\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\tDUK_ASSERT(tv1 != NULL);\n\n#if defined(DUK_USE_FASTINT)\n\t/* Explicit check for fastint downgrade. */\n\tDUK_TVAL_CHKFAST_INPLACE_SLOW(tv1);\n#endif\n\n\t/* Sanity workaround for handling functions with a large number of\n\t * constants at least somewhat reasonably.  Otherwise checking whether\n\t * we already have the constant would grow very slow (as it is O(N^2)).\n\t */\n\tn_check = (n > DUK__GETCONST_MAX_CONSTS_CHECK ? DUK__GETCONST_MAX_CONSTS_CHECK : n);\n\tfor (i = 0; i < n_check; i++) {\n\t\tduk_tval *tv2 = DUK_HOBJECT_A_GET_VALUE_PTR(thr->heap, f->h_consts, i);\n\n\t\t/* Strict equality is NOT enough, because we cannot use the same\n\t\t * constant for e.g. +0 and -0.\n\t\t */\n\t\tif (duk_js_samevalue(tv1, tv2)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"reused existing constant for %!T -> const index %ld\",\n\t\t\t                     (duk_tval *) tv1, (long) i));\n\t\t\tduk_pop(thr);\n\t\t\treturn (duk_regconst_t) i | (duk_regconst_t) DUK__CONST_MARKER;\n\t\t}\n\t}\n\n\tif (n > DUK__MAX_CONSTS) {\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_CONST_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"allocating new constant for %!T -> const index %ld\",\n\t                     (duk_tval *) tv1, (long) n));\n\t(void) duk_put_prop_index(thr, f->consts_idx, (duk_uarridx_t) n);  /* invalidates tv1, tv2 */\n\treturn (duk_regconst_t) n | (duk_regconst_t) DUK__CONST_MARKER;\n}\n\nDUK_LOCAL duk_bool_t duk__const_needs_refcount(duk_compiler_ctx *comp_ctx, duk_regconst_t rc) {\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\tduk_compiler_func *f = &comp_ctx->curr_func;\n\tduk_bool_t ret;\n\n\tDUK_ASSERT((rc & DUK__CONST_MARKER) == 0);  /* caller removes const marker */\n\t(void) duk_get_prop_index(comp_ctx->thr, f->consts_idx, (duk_uarridx_t) rc);\n\tret = !duk_is_number(comp_ctx->thr, -1);  /* now only number/string, so conservative check */\n\tduk_pop(comp_ctx->thr);\n\treturn ret;\n#else\n\tDUK_UNREF(comp_ctx);\n\tDUK_UNREF(rc);\n\tDUK_ASSERT((rc & DUK__CONST_MARKER) == 0);  /* caller removes const marker */\n\treturn 0;\n#endif\n}\n\n/* Get the value represented by an duk_ispec to a register or constant.\n * The caller can control the result by indicating whether or not:\n *\n *   (1) a constant is allowed (sometimes the caller needs the result to\n *       be in a register)\n *\n *   (2) a temporary register is required (usually when caller requires\n *       the register to be safely mutable; normally either a bound\n *       register or a temporary register are both OK)\n *\n *   (3) a forced register target needs to be used\n *\n * Bytecode may be emitted to generate the necessary value.  The return\n * value is either a register or a constant.\n */\n\nDUK_LOCAL\nduk_regconst_t duk__ispec_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                         duk_ispec *x,\n                                         duk_regconst_t forced_reg,\n                                         duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__ispec_toregconst_raw(): x={%ld:%ld:%!T}, \"\n\t                     \"forced_reg=%ld, flags 0x%08lx: allow_const=%ld require_temp=%ld require_short=%ld\",\n\t                     (long) x->t,\n\t                     (long) x->regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->valstack_idx),\n\t                     (long) forced_reg,\n\t                     (unsigned long) flags,\n\t                     (long) ((flags & DUK__IVAL_FLAG_ALLOW_CONST) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_SHORT) ? 1 : 0)));\n\n\tswitch (x->t) {\n\tcase DUK_ISPEC_VALUE: {\n\t\tduk_tval *tv;\n\n\t\ttv = DUK_GET_TVAL_POSIDX(thr, x->valstack_idx);\n\t\tDUK_ASSERT(tv != NULL);\n\n\t\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\t\tcase DUK_TAG_UNDEFINED: {\n\t\t\t/* Note: although there is no 'undefined' literal, undefined\n\t\t\t * values can occur during compilation as a result of e.g.\n\t\t\t * the 'void' operator.\n\t\t\t */\n\t\t\tduk_regconst_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_LDUNDEF, dest);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_NULL: {\n\t\t\tduk_regconst_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_LDNULL, dest);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_BOOLEAN: {\n\t\t\tduk_regconst_t dest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             (DUK_TVAL_GET_BOOLEAN(tv) ? DUK_OP_LDTRUE : DUK_OP_LDFALSE),\n\t\t\t             dest);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_POINTER: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_STRING: {\n\t\t\tduk_hstring *h;\n\t\t\tduk_regconst_t dest;\n\t\t\tduk_regconst_t constidx;\n\n\t\t\th = DUK_TVAL_GET_STRING(tv);\n\t\t\tDUK_UNREF(h);\n\t\t\tDUK_ASSERT(h != NULL);\n\n#if 0  /* XXX: to be implemented? */\n\t\t\t/* Use special opcodes to load short strings */\n\t\t\tif (DUK_HSTRING_GET_BYTELEN(h) <= 2) {\n\t\t\t\t/* Encode into a single opcode (18 bits can encode 1-2 bytes + length indicator) */\n\t\t\t} else if (DUK_HSTRING_GET_BYTELEN(h) <= 6) {\n\t\t\t\t/* Encode into a double constant (53 bits can encode 6*8 = 48 bits + 3-bit length */\n\t\t\t}\n#endif\n\t\t\tduk_dup(thr, x->valstack_idx);\n\t\t\tconstidx = duk__getconst(comp_ctx);\n\n\t\t\tif (flags & DUK__IVAL_FLAG_ALLOW_CONST) {\n\t\t\t\treturn constidx;\n\t\t\t}\n\n\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, constidx);\n\t\t\treturn dest;\n\t\t}\n\t\tcase DUK_TAG_OBJECT: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_BUFFER: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_TAG_LIGHTFUNC: {\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_FASTINT)\n\t\tcase DUK_TAG_FASTINT:\n#endif\n\t\tdefault: {\n\t\t\t/* number */\n\t\t\tduk_regconst_t dest;\n\t\t\tduk_regconst_t constidx;\n\t\t\tduk_double_t dval;\n\t\t\tduk_int32_t ival;\n\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\t\tdval = DUK_TVAL_GET_NUMBER(tv);\n\n\t\t\tif (!(flags & DUK__IVAL_FLAG_ALLOW_CONST)) {\n\t\t\t\t/* A number can be loaded either through a constant, using\n\t\t\t\t * LDINT, or using LDINT+LDINTX.  LDINT is always a size win,\n\t\t\t\t * LDINT+LDINTX is not if the constant is used multiple times.\n\t\t\t\t * Currently always prefer LDINT+LDINTX over a double constant.\n\t\t\t\t */\n\n\t\t\t\tif (duk_is_whole_get_int32_nonegzero(dval, &ival)) {\n\t\t\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\t\t\tduk__emit_load_int32(comp_ctx, dest, ival);\n\t\t\t\t\treturn dest;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_dup(thr, x->valstack_idx);\n\t\t\tconstidx = duk__getconst(comp_ctx);\n\n\t\t\tif (flags & DUK__IVAL_FLAG_ALLOW_CONST) {\n\t\t\t\treturn constidx;\n\t\t\t} else {\n\t\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, constidx);\n\t\t\t\treturn dest;\n\t\t\t}\n\t\t}\n\t\t}  /* end switch */\n\t\tgoto fail_internal;  /* never here */\n\t}\n\tcase DUK_ISPEC_REGCONST: {\n\t\tif (forced_reg >= 0) {\n\t\t\tif (DUK__ISCONST(x->regconst)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, forced_reg, x->regconst);\n\t\t\t} else if (x->regconst != forced_reg) {\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDREG, forced_reg, x->regconst);\n\t\t\t} else {\n\t\t\t\t; /* already in correct reg */\n\t\t\t}\n\t\t\treturn forced_reg;\n\t\t}\n\n\t\tDUK_ASSERT(forced_reg < 0);\n\t\tif (DUK__ISCONST(x->regconst)) {\n\t\t\tif (!(flags & DUK__IVAL_FLAG_ALLOW_CONST)) {\n\t\t\t\tduk_regconst_t dest = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, dest, x->regconst);\n\t\t\t\treturn dest;\n\t\t\t}\n\t\t\treturn x->regconst;\n\t\t}\n\n\t\tDUK_ASSERT(forced_reg < 0 && !DUK__ISCONST(x->regconst));\n\t\tif ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) && !DUK__ISREG_TEMP(comp_ctx, x->regconst)) {\n\t\t\tduk_regconst_t dest = DUK__ALLOCTEMP(comp_ctx);\n\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_LDREG, dest, x->regconst);\n\t\t\treturn dest;\n\t\t}\n\t\treturn x->regconst;\n\t}\n\tdefault: {\n\t\tbreak;  /* never here */\n\t}\n\t}\n\n fail_internal:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_LOCAL void duk__ispec_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ispec *x, duk_regconst_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\t(void) duk__ispec_toregconst_raw(comp_ctx, x, forced_reg, 0 /*flags*/);\n}\n\n/* Coerce an duk_ivalue to a 'plain' value by generating the necessary\n * arithmetic operations, property access, or variable access bytecode.\n * The duk_ivalue argument ('x') is converted into a plain value as a\n * side effect.\n */\nDUK_LOCAL void duk__ivalue_toplain_raw(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_regconst_t forced_reg) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__ivalue_toplain_raw(): x={t=%ld,op=%ld,x1={%ld:%ld:%!T},x2={%ld:%ld:%!T}}, \"\n\t                     \"forced_reg=%ld\",\n\t                     (long) x->t, (long) x->op,\n\t                     (long) x->x1.t, (long) x->x1.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x1.valstack_idx),\n\t                     (long) x->x2.t, (long) x->x2.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x2.valstack_idx),\n\t                     (long) forced_reg));\n\n\tswitch (x->t) {\n\tcase DUK_IVAL_PLAIN: {\n\t\treturn;\n\t}\n\t/* XXX: support unary arithmetic ivalues (useful?) */\n\tcase DUK_IVAL_ARITH: {\n\t\tduk_regconst_t arg1;\n\t\tduk_regconst_t arg2;\n\t\tduk_regconst_t dest;\n\t\tduk_tval *tv1;\n\t\tduk_tval *tv2;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"arith to plain conversion\"));\n\n\t\t/* inline arithmetic check for constant values */\n\t\t/* XXX: use the exactly same arithmetic function here as in executor */\n\t\tif (x->x1.t == DUK_ISPEC_VALUE && x->x2.t == DUK_ISPEC_VALUE && x->t == DUK_IVAL_ARITH) {\n\t\t\ttv1 = DUK_GET_TVAL_POSIDX(thr, x->x1.valstack_idx);\n\t\t\ttv2 = DUK_GET_TVAL_POSIDX(thr, x->x2.valstack_idx);\n\t\t\tDUK_ASSERT(tv1 != NULL);\n\t\t\tDUK_ASSERT(tv2 != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"arith: tv1=%!T, tv2=%!T\",\n\t\t\t                     (duk_tval *) tv1,\n\t\t\t                     (duk_tval *) tv2));\n\n\t\t\tif (DUK_TVAL_IS_NUMBER(tv1) && DUK_TVAL_IS_NUMBER(tv2)) {\n\t\t\t\tduk_double_t d1 = DUK_TVAL_GET_NUMBER(tv1);\n\t\t\t\tduk_double_t d2 = DUK_TVAL_GET_NUMBER(tv2);\n\t\t\t\tduk_double_t d3;\n\t\t\t\tduk_bool_t accept_fold = 1;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"arith inline check: d1=%lf, d2=%lf, op=%ld\",\n\t\t\t\t                     (double) d1, (double) d2, (long) x->op));\n\t\t\t\tswitch (x->op) {\n\t\t\t\tcase DUK_OP_ADD: {\n\t\t\t\t\td3 = d1 + d2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_SUB: {\n\t\t\t\t\td3 = d1 - d2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_MUL: {\n\t\t\t\t\td3 = d1 * d2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_DIV: {\n\t\t\t\t\t/* Division-by-zero is undefined\n\t\t\t\t\t * behavior, so rely on a helper.\n\t\t\t\t\t */\n\t\t\t\t\td3 = duk_double_div(d1, d2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase DUK_OP_EXP: {\n\t\t\t\t\td3 = (duk_double_t) duk_js_arith_pow((double) d1, (double) d2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tdefault: {\n\t\t\t\t\td3 = 0.0;  /* Won't be used, but silence MSVC /W4 warning. */\n\t\t\t\t\taccept_fold = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (accept_fold) {\n\t\t\t\t\tduk_double_union du;\n\t\t\t\t\tdu.d = d3;\n\t\t\t\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\t\t\t\t\td3 = du.d;\n\n\t\t\t\t\tx->t = DUK_IVAL_PLAIN;\n\t\t\t\t\tDUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE);\n\t\t\t\t\tDUK_TVAL_SET_NUMBER(tv1, d3);  /* old value is number: no refcount */\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else if (x->op == DUK_OP_ADD && DUK_TVAL_IS_STRING(tv1) && DUK_TVAL_IS_STRING(tv2)) {\n\t\t\t\t/* Inline string concatenation.  No need to check for\n\t\t\t\t * symbols, as all inputs are valid ECMAScript strings.\n\t\t\t\t */\n\t\t\t\tduk_dup(thr, x->x1.valstack_idx);\n\t\t\t\tduk_dup(thr, x->x2.valstack_idx);\n\t\t\t\tduk_concat(thr, 2);\n\t\t\t\tduk_replace(thr, x->x1.valstack_idx);\n\t\t\t\tx->t = DUK_IVAL_PLAIN;\n\t\t\t\tDUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\targ1 = duk__ispec_toregconst_raw(comp_ctx, &x->x1, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\t\targ2 = duk__ispec_toregconst_raw(comp_ctx, &x->x2, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\n\t\t/* If forced reg, use it as destination.  Otherwise try to\n\t\t * use either coerced ispec if it is a temporary.\n\t\t */\n\t\tif (forced_reg >= 0) {\n\t\t\tdest = forced_reg;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg1)) {\n\t\t\tdest = arg1;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg2)) {\n\t\t\tdest = arg2;\n\t\t} else {\n\t\t\tdest = DUK__ALLOCTEMP(comp_ctx);\n\t\t}\n\n\t\tDUK_ASSERT(DUK__ISREG(dest));\n\t\tduk__emit_a_b_c(comp_ctx, x->op | DUK__EMIT_FLAG_BC_REGCONST, dest, arg1, arg2);\n\n\t\tduk__ivalue_regconst(x, dest);\n\t\treturn;\n\t}\n\tcase DUK_IVAL_PROP: {\n\t\t/* XXX: very similar to DUK_IVAL_ARITH - merge? */\n\t\tduk_regconst_t arg1;\n\t\tduk_regconst_t arg2;\n\t\tduk_regconst_t dest;\n\n\t\t/* Need a short reg/const, does not have to be a mutable temp. */\n\t\targ1 = duk__ispec_toregconst_raw(comp_ctx, &x->x1, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\t\targ2 = duk__ispec_toregconst_raw(comp_ctx, &x->x2, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_SHORT /*flags*/);\n\n\t\t/* Pick a destination register.  If either base value or key\n\t\t * happens to be a temp value, reuse it as the destination.\n\t\t *\n\t\t * XXX: The temp must be a \"mutable\" one, i.e. such that no\n\t\t * other expression is using it anymore.  Here this should be\n\t\t * the case because the value of a property access expression\n\t\t * is neither the base nor the key, but the lookup result.\n\t\t */\n\n\t\tif (forced_reg >= 0) {\n\t\t\tdest = forced_reg;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg1)) {\n\t\t\tdest = arg1;\n\t\t} else if (DUK__ISREG_TEMP(comp_ctx, arg2)) {\n\t\t\tdest = arg2;\n\t\t} else {\n\t\t\tdest = DUK__ALLOCTEMP(comp_ctx);\n\t\t}\n\n\t\tduk__emit_a_b_c(comp_ctx,\n\t\t                DUK_OP_GETPROP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t                dest,\n\t\t                arg1,\n\t\t                arg2);\n\n\t\tduk__ivalue_regconst(x, dest);\n\t\treturn;\n\t}\n\tcase DUK_IVAL_VAR: {\n\t\t/* x1 must be a string */\n\t\tduk_regconst_t dest;\n\t\tduk_regconst_t reg_varbind;\n\t\tduk_regconst_t rc_varname;\n\n\t\tDUK_ASSERT(x->x1.t == DUK_ISPEC_VALUE);\n\n\t\tduk_dup(thr, x->x1.valstack_idx);\n\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\tduk__ivalue_regconst(x, reg_varbind);\n\t\t} else {\n\t\t\tdest = (forced_reg >= 0 ? forced_reg : DUK__ALLOCTEMP(comp_ctx));\n\t\t\tduk__emit_a_bc(comp_ctx, DUK_OP_GETVAR, dest, rc_varname);\n\t\t\tduk__ivalue_regconst(x, dest);\n\t\t}\n\t\treturn;\n\t}\n\tcase DUK_IVAL_NONE:\n\tdefault: {\n\t\tDUK_D(DUK_DPRINT(\"invalid ivalue type: %ld\", (long) x->t));\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* evaluate to plain value, no forced register (temp/bound reg both ok) */\nDUK_LOCAL void duk__ivalue_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tduk__ivalue_toplain_raw(comp_ctx, x, -1 /*forced_reg*/);\n}\n\n/* evaluate to final form (e.g. coerce GETPROP to code), throw away temp */\nDUK_LOCAL void duk__ivalue_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\tduk_regconst_t temp;\n\n\t/* If duk__ivalue_toplain_raw() allocates a temp, forget it and\n\t * restore next temp state.\n\t */\n\ttemp = DUK__GETTEMP(comp_ctx);\n\tduk__ivalue_toplain_raw(comp_ctx, x, -1 /*forced_reg*/);\n\tDUK__SETTEMP(comp_ctx, temp);\n}\n\n/* Coerce an duk_ivalue to a register or constant; result register may\n * be a temp or a bound register.\n *\n * The duk_ivalue argument ('x') is converted into a regconst as a\n * side effect.\n */\nDUK_LOCAL\nduk_regconst_t duk__ivalue_toregconst_raw(duk_compiler_ctx *comp_ctx,\n                                          duk_ivalue *x,\n                                          duk_regconst_t forced_reg,\n                                          duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg;\n\tDUK_UNREF(thr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__ivalue_toregconst_raw(): x={t=%ld,op=%ld,x1={%ld:%ld:%!T},x2={%ld:%ld:%!T}}, \"\n\t                     \"forced_reg=%ld, flags 0x%08lx: allow_const=%ld require_temp=%ld require_short=%ld\",\n\t                     (long) x->t, (long) x->op,\n\t                     (long) x->x1.t, (long) x->x1.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x1.valstack_idx),\n\t                     (long) x->x2.t, (long) x->x2.regconst,\n\t                     (duk_tval *) duk_get_tval(thr, x->x2.valstack_idx),\n\t                     (long) forced_reg,\n\t                     (unsigned long) flags,\n\t                     (long) ((flags & DUK__IVAL_FLAG_ALLOW_CONST) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_TEMP) ? 1 : 0),\n\t                     (long) ((flags & DUK__IVAL_FLAG_REQUIRE_SHORT) ? 1 : 0)));\n\n\t/* first coerce to a plain value */\n\tduk__ivalue_toplain_raw(comp_ctx, x, forced_reg);\n\tDUK_ASSERT(x->t == DUK_IVAL_PLAIN);\n\n\t/* then to a register */\n\treg = duk__ispec_toregconst_raw(comp_ctx, &x->x1, forced_reg, flags);\n\tduk__ivalue_regconst(x, reg);\n\n\treturn reg;\n}\n\nDUK_LOCAL duk_regconst_t duk__ivalue_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, 0 /*flags*/);\n}\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__ivalue_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/);\n}\n#endif\n\nDUK_LOCAL void duk__ivalue_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *x, duk_int_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\t(void) duk__ivalue_toregconst_raw(comp_ctx, x, forced_reg, 0 /*flags*/);\n}\n\nDUK_LOCAL duk_regconst_t duk__ivalue_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n}\n\nDUK_LOCAL duk_regconst_t duk__ivalue_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *x) {\n\treturn duk__ivalue_toregconst_raw(comp_ctx, x, -1, DUK__IVAL_FLAG_ALLOW_CONST | DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/);\n}\n\n/* The issues below can be solved with better flags */\n\n/* XXX: many operations actually want toforcedtemp() -- brand new temp? */\n/* XXX: need a toplain_ignore() which will only coerce a value to a temp\n * register if it might have a side effect.  Side-effect free values do not\n * need to be coerced.\n */\n\n/*\n *  Identifier handling\n */\n\nDUK_LOCAL duk_regconst_t duk__lookup_active_register_binding(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hstring *h_varname;\n\tduk_regconst_t ret;\n\n\tDUK_DDD(DUK_DDDPRINT(\"resolving identifier reference to '%!T'\",\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/*\n\t *  Special name handling\n\t */\n\n\th_varname = duk_known_hstring(thr, -1);\n\n\tif (h_varname == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"flagging function as accessing 'arguments'\"));\n\t\tcomp_ctx->curr_func.id_access_arguments = 1;\n\t}\n\n\t/*\n\t *  Inside one or more 'with' statements fall back to slow path always.\n\t *  (See e.g. test-stmt-with.js.)\n\t */\n\n\tif (comp_ctx->curr_func.with_depth > 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup inside a 'with' -> fall back to slow path\"));\n\t\tgoto slow_path_own;\n\t}\n\n\t/*\n\t *  Any catch bindings (\"catch (e)\") also affect identifier binding.\n\t *\n\t *  Currently, the varmap is modified for the duration of the catch\n\t *  clause to ensure any identifier accesses with the catch variable\n\t *  name will use slow path.\n\t */\n\n\tduk_get_prop(thr, comp_ctx->curr_func.varmap_idx);\n\tif (duk_is_number(thr, -1)) {\n\t\tret = duk_to_int(thr, -1);\n\t\tduk_pop(thr);\n\t} else {\n\t\tduk_pop(thr);\n\t\tif (comp_ctx->curr_func.catch_depth > 0 || comp_ctx->curr_func.with_depth > 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slow path access from inside a try-catch or with needs _Varmap\"));\n\t\t\tgoto slow_path_own;\n\t\t} else {\n\t\t\t/* In this case we're doing a variable lookup that doesn't\n\t\t\t * match our own variables, so _Varmap won't be needed at\n\t\t\t * run time.\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"slow path access outside of try-catch and with, no need for _Varmap\"));\n\t\t\tgoto slow_path_notown;\n\t\t}\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup -> reg %ld\", (long) ret));\n\treturn ret;\n\n slow_path_notown:\n\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup -> slow path, not own variable\"));\n\n\tcomp_ctx->curr_func.id_access_slow = 1;\n\treturn (duk_regconst_t) -1;\n\n slow_path_own:\n\tDUK_DDD(DUK_DDDPRINT(\"identifier lookup -> slow path, may be own variable\"));\n\n\tcomp_ctx->curr_func.id_access_slow = 1;\n\tcomp_ctx->curr_func.id_access_slow_own = 1;\n\treturn (duk_regconst_t) -1;\n}\n\n/* Lookup an identifier name in the current varmap, indicating whether the\n * identifier is register-bound and if not, allocating a constant for the\n * identifier name.  Returns 1 if register-bound, 0 otherwise.  Caller can\n * also check (out_reg_varbind >= 0) to check whether or not identifier is\n * register bound.  The caller must NOT use out_rc_varname at all unless\n * return code is 0 or out_reg_varbind is < 0; this is becuase out_rc_varname\n * is unsigned and doesn't have a \"unused\" / none value.\n */\nDUK_LOCAL duk_bool_t duk__lookup_lhs(duk_compiler_ctx *comp_ctx, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg_varbind;\n\tduk_regconst_t rc_varname;\n\n\t/* [ ... varname ] */\n\n\tduk_dup_top(thr);\n\treg_varbind = duk__lookup_active_register_binding(comp_ctx);\n\n\tif (reg_varbind >= 0) {\n\t\t*out_reg_varbind = reg_varbind;\n\t\t*out_rc_varname = 0;  /* duk_regconst_t is unsigned, so use 0 as dummy value (ignored by caller) */\n\t\tduk_pop(thr);\n\t\treturn 1;\n\t} else {\n\t\trc_varname = duk__getconst(comp_ctx);\n\t\t*out_reg_varbind = -1;\n\t\t*out_rc_varname = rc_varname;\n\t\treturn 0;\n\t}\n}\n\n/*\n *  Label handling\n *\n *  Labels are initially added with flags prohibiting both break and continue.\n *  When the statement type is finally uncovered (after potentially multiple\n *  labels), all the labels are updated to allow/prohibit break and continue.\n */\n\nDUK_LOCAL void duk__add_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_int_t pc_label, duk_int_t label_id) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_size_t n;\n\tduk_size_t new_size;\n\tduk_uint8_t *p;\n\tduk_labelinfo *li_start, *li;\n\n\t/* Duplicate (shadowing) labels are not allowed, except for the empty\n\t * labels (which are used as default labels for switch and iteration\n\t * statements).\n\t *\n\t * We could also allow shadowing of non-empty pending labels without any\n\t * other issues than breaking the required label shadowing requirements\n\t * of the E5 specification, see Section 12.12.\n\t */\n\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tli = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\tn = (duk_size_t) (li - li_start);\n\n\twhile (li > li_start) {\n\t\tli--;\n\n\t\tif (li->h_label == h_label && h_label != DUK_HTHREAD_STRING_EMPTY_STRING(thr)) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_DUPLICATE_LABEL);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t}\n\n\tduk_push_hstring(thr, h_label);\n\tDUK_ASSERT(n <= DUK_UARRIDX_MAX);  /* label limits */\n\t(void) duk_put_prop_index(thr, comp_ctx->curr_func.labelnames_idx, (duk_uarridx_t) n);\n\n\tnew_size = (n + 1) * sizeof(duk_labelinfo);\n\tduk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, new_size);\n\t/* XXX: slack handling, slow now */\n\n\t/* relookup after possible realloc */\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tDUK_UNREF(li_start);  /* silence scan-build warning */\n\tli = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\tli--;\n\n\t/* Labels can be used for iteration statements but also for other statements,\n\t * in particular a label can be used for a block statement.  All cases of a\n\t * named label accept a 'break' so that flag is set here.  Iteration statements\n\t * also allow 'continue', so that flag is updated when we figure out the\n\t * statement type.\n\t */\n\n\tli->flags = DUK_LABEL_FLAG_ALLOW_BREAK;\n\tli->label_id = label_id;\n\tli->h_label = h_label;\n\tli->catch_depth = comp_ctx->curr_func.catch_depth;   /* catch depth from current func */\n\tli->pc_label = pc_label;\n\n\tDUK_DDD(DUK_DDDPRINT(\"registered label: flags=0x%08lx, id=%ld, name=%!O, catch_depth=%ld, pc_label=%ld\",\n\t                     (unsigned long) li->flags, (long) li->label_id, (duk_heaphdr *) li->h_label,\n\t                     (long) li->catch_depth, (long) li->pc_label));\n}\n\n/* Update all labels with matching label_id. */\nDUK_LOCAL void duk__update_label_flags(duk_compiler_ctx *comp_ctx, duk_int_t label_id, duk_small_uint_t flags) {\n\tduk_uint8_t *p;\n\tduk_labelinfo *li_start, *li;\n\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(comp_ctx->thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tli = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\n\t/* Match labels starting from latest; once label_id no longer matches, we can\n\t * safely exit without checking the rest of the labels (only the topmost labels\n\t * are ever updated).\n\t */\n\twhile (li > li_start) {\n\t\tli--;\n\n\t\tif (li->label_id != label_id) {\n\t\t\tbreak;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"updating (overwriting) label flags for li=%p, label_id=%ld, flags=%ld\",\n\t\t                     (void *) li, (long) label_id, (long) flags));\n\n\t\tli->flags = flags;\n\t}\n}\n\n/* Lookup active label information.  Break/continue distinction is necessary to handle switch\n * statement related labels correctly: a switch will only catch a 'break', not a 'continue'.\n *\n * An explicit label cannot appear multiple times in the active set, but empty labels (unlabelled\n * iteration and switch statements) can.  A break will match the closest unlabelled or labelled\n * statement.  A continue will match the closest unlabelled or labelled iteration statement.  It is\n * a syntax error if a continue matches a labelled switch statement; because an explicit label cannot\n * be duplicated, the continue cannot match any valid label outside the switch.\n *\n * A side effect of these rules is that a LABEL statement related to a switch should never actually\n * catch a continue abrupt completion at run-time.  Hence an INVALID opcode can be placed in the\n * continue slot of the switch's LABEL statement.\n */\n\n/* XXX: awkward, especially the bunch of separate output values -> output struct? */\nDUK_LOCAL void duk__lookup_active_label(duk_compiler_ctx *comp_ctx, duk_hstring *h_label, duk_bool_t is_break, duk_int_t *out_label_id, duk_int_t *out_label_catch_depth, duk_int_t *out_label_pc, duk_bool_t *out_is_closest) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_uint8_t *p;\n\tduk_labelinfo *li_start, *li_end, *li;\n\tduk_bool_t match = 0;\n\n\tDUK_DDD(DUK_DDDPRINT(\"looking up active label: label='%!O', is_break=%ld\",\n\t                     (duk_heaphdr *) h_label, (long) is_break));\n\n\tDUK_UNREF(thr);\n\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, comp_ctx->curr_func.h_labelinfos);\n\tli_start = (duk_labelinfo *) (void *) p;\n\tli_end = (duk_labelinfo *) (void *) (p + DUK_HBUFFER_GET_SIZE(comp_ctx->curr_func.h_labelinfos));\n\tli = li_end;\n\n\t/* Match labels starting from latest label because there can be duplicate empty\n\t * labels in the label set.\n\t */\n\twhile (li > li_start) {\n\t\tli--;\n\n\t\tif (li->h_label != h_label) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"labelinfo[%ld] ->'%!O' != %!O\",\n\t\t\t                     (long) (li - li_start),\n\t\t\t                     (duk_heaphdr *) li->h_label,\n\t\t\t                     (duk_heaphdr *) h_label));\n\t\t\tcontinue;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"labelinfo[%ld] -> '%!O' label name matches (still need to check type)\",\n\t\t                     (long) (li - li_start), (duk_heaphdr *) h_label));\n\n\t\t/* currently all labels accept a break, so no explicit check for it now */\n\t\tDUK_ASSERT(li->flags & DUK_LABEL_FLAG_ALLOW_BREAK);\n\n\t\tif (is_break) {\n\t\t\t/* break matches always */\n\t\t\tmatch = 1;\n\t\t\tbreak;\n\t\t} else if (li->flags & DUK_LABEL_FLAG_ALLOW_CONTINUE) {\n\t\t\t/* iteration statements allow continue */\n\t\t\tmatch = 1;\n\t\t\tbreak;\n\t\t} else {\n\t\t\t/* continue matched this label -- we can only continue if this is the empty\n\t\t\t * label, for which duplication is allowed, and thus there is hope of\n\t\t\t * finding a match deeper in the label stack.\n\t\t\t */\n\t\t\tif (h_label != DUK_HTHREAD_STRING_EMPTY_STRING(thr)) {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LABEL);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"continue matched an empty label which does not \"\n\t\t\t\t                     \"allow a continue -> continue lookup deeper in label stack\"));\n\t\t\t}\n\t\t}\n\t}\n\t/* XXX: match flag is awkward, rework */\n\tif (!match) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LABEL);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"label match: %!O -> label_id %ld, catch_depth=%ld, pc_label=%ld\",\n\t                     (duk_heaphdr *) h_label, (long) li->label_id,\n\t                     (long) li->catch_depth, (long) li->pc_label));\n\n\t*out_label_id = li->label_id;\n\t*out_label_catch_depth = li->catch_depth;\n\t*out_label_pc = li->pc_label;\n\t*out_is_closest = (li == li_end - 1);\n}\n\nDUK_LOCAL void duk__reset_labels_to_length(duk_compiler_ctx *comp_ctx, duk_size_t len) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\tduk_set_length(thr, comp_ctx->curr_func.labelnames_idx, len);\n\tduk_hbuffer_resize(thr, comp_ctx->curr_func.h_labelinfos, sizeof(duk_labelinfo) * len);\n}\n\n/*\n *  Expression parsing: duk__expr_nud(), duk__expr_led(), duk__expr_lbp(), and helpers.\n *\n *  - duk__expr_nud(): (\"null denotation\"): process prev_token as a \"start\" of an expression (e.g. literal)\n *  - duk__expr_led(): (\"left denotation\"): process prev_token in the \"middle\" of an expression (e.g. operator)\n *  - duk__expr_lbp(): (\"left-binding power\"): return left-binding power of curr_token\n */\n\n/* object literal key tracking flags */\n#define DUK__OBJ_LIT_KEY_PLAIN  (1 << 0)  /* key encountered as a plain property */\n#define DUK__OBJ_LIT_KEY_GET    (1 << 1)  /* key encountered as a getter */\n#define DUK__OBJ_LIT_KEY_SET    (1 << 2)  /* key encountered as a setter */\n\nDUK_LOCAL void duk__nud_array_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg_obj;                 /* result reg */\n\tduk_regconst_t reg_temp;                /* temp reg */\n\tduk_regconst_t temp_start;              /* temp reg value for start of loop */\n\tduk_small_uint_t max_init_values;  /* max # of values initialized in one MPUTARR set */\n\tduk_small_uint_t num_values;       /* number of values in current MPUTARR set */\n\tduk_uarridx_t curr_idx;            /* current (next) array index */\n\tduk_uarridx_t start_idx;           /* start array index of current MPUTARR set */\n\tduk_uarridx_t init_idx;            /* last array index explicitly initialized, +1 */\n\tduk_bool_t require_comma;          /* next loop requires a comma */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tduk_int_t pc_newarr;\n\tduk_compiler_instr *instr;\n#endif\n\n\t/* DUK_TOK_LBRACKET already eaten, current token is right after that */\n\tDUK_ASSERT(comp_ctx->prev_token.t == DUK_TOK_LBRACKET);\n\n\tmax_init_values = DUK__MAX_ARRAY_INIT_VALUES;  /* XXX: depend on available temps? */\n\n\treg_obj = DUK__ALLOCTEMP(comp_ctx);\n#if !defined(DUK_USE_PREFER_SIZE)\n\tpc_newarr = duk__get_current_pc(comp_ctx);\n#endif\n\tduk__emit_bc(comp_ctx, DUK_OP_NEWARR, reg_obj);  /* XXX: patch initial size hint afterwards? */\n\ttemp_start = DUK__GETTEMP(comp_ctx);\n\n\t/*\n\t *  Emit initializers in sets of maximum max_init_values.\n\t *  Corner cases such as single value initializers do not have\n\t *  special handling now.\n\t *\n\t *  Elided elements must not be emitted as 'undefined' values,\n\t *  because such values would be enumerable (which is incorrect).\n\t *  Also note that trailing elisions must be reflected in the\n\t *  length of the final array but cause no elements to be actually\n\t *  inserted.\n\t */\n\n\tcurr_idx = 0;\n\tinit_idx = 0;         /* tracks maximum initialized index + 1 */\n\tstart_idx = 0;\n\trequire_comma = 0;\n\n\tfor (;;) {\n\t\tnum_values = 0;\n\t\tDUK__SETTEMP(comp_ctx, temp_start);\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RBRACKET) {\n\t\t\tbreak;\n\t\t}\n\n\t\tfor (;;) {\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_RBRACKET) {\n\t\t\t\t/* the outer loop will recheck and exit */\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/* comma check */\n\t\t\tif (require_comma) {\n\t\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_COMMA) {\n\t\t\t\t\t/* comma after a value, expected */\n\t\t\t\t\tduk__advance(comp_ctx);\n\t\t\t\t\trequire_comma = 0;\n\t\t\t\t\tcontinue;\n\t\t\t\t} else {\n\t\t\t\t\tgoto syntax_error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_COMMA) {\n\t\t\t\t\t/* elision - flush */\n\t\t\t\t\tcurr_idx++;\n\t\t\t\t\tduk__advance(comp_ctx);\n\t\t\t\t\t/* if num_values > 0, MPUTARR emitted by outer loop after break */\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t/* else an array initializer element */\n\n\t\t\t/* initial index */\n\t\t\tif (num_values == 0) {\n\t\t\t\tstart_idx = curr_idx;\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_load_int32(comp_ctx, reg_temp, (duk_int32_t) start_idx);\n\t\t\t}\n\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);   /* alloc temp just in case, to update max temp */\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp);\n\t\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp /*forced_reg*/);\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\n\t\t\tnum_values++;\n\t\t\tcurr_idx++;\n\t\t\trequire_comma = 1;\n\n\t\t\tif (num_values >= max_init_values) {\n\t\t\t\t/* MPUTARR emitted by outer loop */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (num_values > 0) {\n\t\t\t/* - A is a source register (it's not a write target, but used\n\t\t\t *   to identify the target object) but can be shuffled.\n\t\t\t * - B cannot be shuffled normally because it identifies a range\n\t\t\t *   of registers, the emitter has special handling for this\n\t\t\t *   (the \"no shuffle\" flag must not be set).\n\t\t\t * - C is a non-register number and cannot be shuffled, but\n\t\t\t *   never needs to be.\n\t\t\t */\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_MPUTARR |\n\t\t\t                    DUK__EMIT_FLAG_NO_SHUFFLE_C |\n\t\t\t                    DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t                reg_obj,\n\t\t\t                temp_start,\n\t\t\t                (duk_regconst_t) (num_values + 1));\n\t\t\tinit_idx = start_idx + num_values;\n\n\t\t\t/* num_values and temp_start reset at top of outer loop */\n\t\t}\n\t}\n\n\t/* Update initil size for NEWARR, doesn't need to be exact and is\n\t * capped at A field limit.\n\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tinstr = duk__get_instr_ptr(comp_ctx, pc_newarr);\n\tinstr->ins |= DUK_ENC_OP_A(0, curr_idx > DUK_BC_A_MAX ? DUK_BC_A_MAX : curr_idx);\n#endif\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RBRACKET);\n\tduk__advance(comp_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"array literal done, curridx=%ld, initidx=%ld\",\n\t                     (long) curr_idx, (long) init_idx));\n\n\t/* trailing elisions? */\n\tif (curr_idx > init_idx) {\n\t\t/* yes, must set array length explicitly */\n\t\tDUK_DDD(DUK_DDDPRINT(\"array literal has trailing elisions which affect its length\"));\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk__emit_load_int32(comp_ctx, reg_temp, (duk_int_t) curr_idx);\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               DUK_OP_SETALEN | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t               reg_obj,\n\t\t               reg_temp);\n\t}\n\n\tDUK__SETTEMP(comp_ctx, temp_start);\n\n\tduk__ivalue_regconst(res, reg_obj);\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_ARRAY_LITERAL);\n\tDUK_WO_NORETURN(return;);\n}\n\ntypedef struct {\n\tduk_regconst_t reg_obj;\n\tduk_regconst_t temp_start;\n\tduk_small_uint_t num_pairs;\n\tduk_small_uint_t num_total_pairs;\n} duk__objlit_state;\n\nDUK_LOCAL void duk__objlit_flush_keys(duk_compiler_ctx *comp_ctx, duk__objlit_state *st) {\n\tif (st->num_pairs > 0) {\n\t\t/* - A is a source register (it's not a write target, but used\n\t\t *   to identify the target object) but can be shuffled.\n\t\t * - B cannot be shuffled normally because it identifies a range\n\t\t *   of registers, the emitter has special handling for this\n\t\t *   (the \"no shuffle\" flag must not be set).\n\t\t * - C is a non-register number and cannot be shuffled, but\n\t\t *   never needs to be.\n\t\t */\n\t\tDUK_ASSERT(st->num_pairs > 0);\n\t\tduk__emit_a_b_c(comp_ctx,\n\t\t                DUK_OP_MPUTOBJ |\n\t\t                    DUK__EMIT_FLAG_NO_SHUFFLE_C |\n\t\t                    DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t                st->reg_obj,\n\t\t                st->temp_start,\n\t\t                (duk_regconst_t) (st->num_pairs * 2));\n\t\tst->num_total_pairs += st->num_pairs;\n\t\tst->num_pairs = 0;\n\t}\n\tDUK__SETTEMP(comp_ctx, st->temp_start);\n}\n\nDUK_LOCAL duk_bool_t duk__objlit_load_key(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_token *tok, duk_regconst_t reg_temp) {\n\tif (tok->t_nores == DUK_TOK_IDENTIFIER || tok->t_nores == DUK_TOK_STRING) {\n\t\t/* same handling for identifiers and strings */\n\t\tDUK_ASSERT(tok->str1 != NULL);\n\t\tduk_push_hstring(comp_ctx->thr, tok->str1);\n\t} else if (tok->t == DUK_TOK_NUMBER) {\n\t\t/* numbers can be loaded as numbers and coerced on the fly */\n\t\tduk_push_number(comp_ctx->thr, tok->num);\n\t} else {\n\t\treturn 1;  /* error */\n\t}\n\n\tduk__ivalue_plain_fromstack(comp_ctx, res);\n\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\tduk__ivalue_toforcedreg(comp_ctx, res, reg_temp);\n\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\treturn 0;\n}\n\nDUK_LOCAL void duk__nud_object_literal(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk__objlit_state st;\n\tduk_regconst_t reg_temp;          /* temp reg */\n\tduk_small_uint_t max_init_pairs;  /* max # of key-value pairs initialized in one MPUTOBJ set */\n\tduk_bool_t first;                 /* first value: comma must not precede the value */\n\tduk_bool_t is_set, is_get;        /* temps */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tduk_int_t pc_newobj;\n\tduk_compiler_instr *instr;\n#endif\n\n\tDUK_ASSERT(comp_ctx->prev_token.t == DUK_TOK_LCURLY);\n\n\tmax_init_pairs = DUK__MAX_OBJECT_INIT_PAIRS;  /* XXX: depend on available temps? */\n\n\tst.reg_obj = DUK__ALLOCTEMP(comp_ctx);    /* target object */\n\tst.temp_start = DUK__GETTEMP(comp_ctx);   /* start of MPUTOBJ argument list */\n\tst.num_pairs = 0;                         /* number of key/value pairs emitted for current MPUTOBJ set */\n\tst.num_total_pairs = 0;                   /* number of key/value pairs emitted overall */\n\n#if !defined(DUK_USE_PREFER_SIZE)\n\tpc_newobj = duk__get_current_pc(comp_ctx);\n#endif\n\tduk__emit_bc(comp_ctx, DUK_OP_NEWOBJ, st.reg_obj);\n\n\t/*\n\t *  Emit initializers in sets of maximum max_init_pairs keys.\n\t *  Setter/getter is handled separately and terminates the\n\t *  current set of initializer values.  Corner cases such as\n\t *  single value initializers do not have special handling now.\n\t */\n\n\tfirst = 1;\n\tfor (;;) {\n\t\t/*\n\t\t *  ES5 and ES2015+ provide a lot of different PropertyDefinition\n\t\t *  formats, see http://www.ecma-international.org/ecma-262/6.0/#sec-object-initializer.\n\t\t *\n\t\t *  PropertyName can be IdentifierName (includes reserved words), a string\n\t\t *  literal, or a number literal.  Note that IdentifierName allows 'get' and\n\t\t *  'set' too, so we need to look ahead to the next token to distinguish:\n\t\t *\n\t\t *     { get : 1 }\n\t\t *\n\t\t *  and\n\t\t *\n\t\t *     { get foo() { return 1 } }\n\t\t *     { get get() { return 1 } }    // 'get' as getter propertyname\n\t\t *\n\t\t *  Finally, a trailing comma is allowed.\n\t\t *\n\t\t *  Key name is coerced to string at compile time (and ends up as a\n\t\t *  a string constant) even for numeric keys (e.g. \"{1:'foo'}\").\n\t\t *  These could be emitted using e.g. LDINT, but that seems hardly\n\t\t *  worth the effort and would increase code size.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"object literal loop, curr_token->t = %ld\",\n\t\t                     (long) comp_ctx->curr_token.t));\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (first) {\n\t\t\tfirst = 0;\n\t\t} else {\n\t\t\tif (comp_ctx->curr_token.t != DUK_TOK_COMMA) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t\tduk__advance(comp_ctx);\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\t\t/* trailing comma followed by rcurly */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* Advance to get one step of lookup. */\n\t\tduk__advance(comp_ctx);\n\n\t\t/* Flush current MPUTOBJ if enough many pairs gathered. */\n\t\tif (st.num_pairs >= max_init_pairs) {\n\t\t\tduk__objlit_flush_keys(comp_ctx, &st);\n\t\t\tDUK_ASSERT(st.num_pairs == 0);\n\t\t}\n\n\t\t/* Reset temp register state and reserve reg_temp and\n\t\t * reg_temp + 1 for handling the current property.\n\t\t */\n\t\tDUK__SETTEMP(comp_ctx, st.temp_start + 2 * (duk_regconst_t) st.num_pairs);\n\t\treg_temp = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\t\t/* NOTE: \"get\" and \"set\" are not officially ReservedWords and the lexer\n\t\t * currently treats them always like ordinary identifiers (DUK_TOK_GET\n\t\t * and DUK_TOK_SET are unused).  They need to be detected based on the\n\t\t * identifier string content.\n\t\t */\n\n\t\tis_get = (comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t          comp_ctx->prev_token.str1 == DUK_HTHREAD_STRING_GET(thr));\n\t\tis_set = (comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t          comp_ctx->prev_token.str1 == DUK_HTHREAD_STRING_SET(thr));\n\t\tif ((is_get || is_set) && comp_ctx->curr_token.t != DUK_TOK_COLON) {\n\t\t\t/* getter/setter */\n\t\t\tduk_int_t fnum;\n\n\t\t\tduk__objlit_flush_keys(comp_ctx, &st);\n\t\t\tDUK_ASSERT(DUK__GETTEMP(comp_ctx) == st.temp_start);  /* 2 regs are guaranteed to be allocated w.r.t. temp_max */\n\t\t\treg_temp = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\t\t\tif (duk__objlit_load_key(comp_ctx, res, &comp_ctx->curr_token, reg_temp) != 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\t/* curr_token = get/set name */\n\t\t\tfnum = duk__parse_func_like_fnum(comp_ctx, DUK__FUNC_FLAG_GETSET);\n\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CLOSURE,\n\t\t\t               st.temp_start + 1,\n\t\t\t               (duk_regconst_t) fnum);\n\n\t\t\t/* Slot C is used in a non-standard fashion (range of regs),\n\t\t\t * emitter code has special handling for it (must not set the\n\t\t\t * \"no shuffle\" flag).\n\t\t\t */\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t              (is_get ? DUK_OP_INITGET : DUK_OP_INITSET) | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t              st.reg_obj,\n\t\t\t              st.temp_start);   /* temp_start+0 = key, temp_start+1 = closure */\n\n\t\t\tDUK_ASSERT(st.num_pairs == 0);  /* temp state is reset on next loop */\n#if defined(DUK_USE_ES6)\n\t\t} else if (comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t           (comp_ctx->curr_token.t == DUK_TOK_COMMA || comp_ctx->curr_token.t == DUK_TOK_RCURLY)) {\n\t\t\tduk_bool_t load_rc;\n\n\t\t\tload_rc = duk__objlit_load_key(comp_ctx, res, &comp_ctx->prev_token, reg_temp);\n\t\t\tDUK_UNREF(load_rc);\n\t\t\tDUK_ASSERT(load_rc == 0);  /* always succeeds because token is identifier */\n\n\t\t\tduk__ivalue_var_hstring(comp_ctx, res, comp_ctx->prev_token.str1);\n\t\t\tDUK_ASSERT(DUK__GETTEMP(comp_ctx) == reg_temp + 1);\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_temp + 1);\n\n\t\t\tst.num_pairs++;\n\t\t} else if ((comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER ||\n\t\t            comp_ctx->prev_token.t == DUK_TOK_STRING ||\n\t\t            comp_ctx->prev_token.t == DUK_TOK_NUMBER) &&\n\t\t           comp_ctx->curr_token.t == DUK_TOK_LPAREN) {\n\t\t\tduk_int_t fnum;\n\n\t\t\t/* Parsing-wise there's a small hickup here: the token parsing\n\t\t\t * state is one step too advanced for the function parse helper\n\t\t\t * compared to other cases.  The current solution is an extra\n\t\t\t * flag to indicate whether function parsing should use the\n\t\t\t * current or the previous token to starting parsing from.\n\t\t\t */\n\n\t\t\tif (duk__objlit_load_key(comp_ctx, res, &comp_ctx->prev_token, reg_temp) != 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\tfnum = duk__parse_func_like_fnum(comp_ctx, DUK__FUNC_FLAG_USE_PREVTOKEN | DUK__FUNC_FLAG_METDEF);\n\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CLOSURE,\n\t\t\t               reg_temp + 1,\n\t\t\t               (duk_regconst_t) fnum);\n\n\t\t\tst.num_pairs++;\n#endif  /* DUK_USE_ES6 */\n\t\t} else {\n#if defined(DUK_USE_ES6)\n\t\t\tif (comp_ctx->prev_token.t == DUK_TOK_LBRACKET) {\n\t\t\t\t/* ES2015 computed property name.  Executor ToPropertyKey()\n\t\t\t\t * coerces the key at runtime.\n\t\t\t\t */\n\t\t\t\tDUK__SETTEMP(comp_ctx, reg_temp);\n\t\t\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_FOR_EXPR, reg_temp);\n\t\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_RBRACKET);\n\n\t\t\t\t/* XXX: If next token is '(' we're dealing with\n\t\t\t\t * the method shorthand with a computed name,\n\t\t\t\t * e.g. { [Symbol.for('foo')](a,b) {} }.  This\n\t\t\t\t * form is not yet supported and causes a\n\t\t\t\t * SyntaxError on the DUK_TOK_COLON check below.\n\t\t\t\t */\n\t\t\t}\n\t\t\telse\n#endif  /* DUK_USE_ES6 */\n\t\t\t{\n\t\t\t\tif (duk__objlit_load_key(comp_ctx, res, &comp_ctx->prev_token, reg_temp) != 0) {\n\t\t\t\t\tgoto syntax_error;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\t\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp + 1 /*forced_reg*/);\n\n\t\t\tst.num_pairs++;\n\t\t}\n\t}  /* property loop */\n\n\t/* Flush remaining properties. */\n\tduk__objlit_flush_keys(comp_ctx, &st);\n\tDUK_ASSERT(st.num_pairs == 0);\n\tDUK_ASSERT(DUK__GETTEMP(comp_ctx) == st.temp_start);\n\n\t/* Update initial size for NEWOBJ.  The init size doesn't need to be\n\t * exact as the purpose is just to avoid object resizes in common\n\t * cases.  The size is capped to field A limit, and will be too high\n\t * if the object literal contains duplicate keys (this is harmless but\n\t * increases memory traffic if the object is compacted later on).\n\t */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tinstr = duk__get_instr_ptr(comp_ctx, pc_newobj);\n\tinstr->ins |= DUK_ENC_OP_A(0, st.num_total_pairs > DUK_BC_A_MAX ? DUK_BC_A_MAX : st.num_total_pairs);\n#endif\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RCURLY);\n\tduk__advance(comp_ctx);  /* No RegExp after object literal. */\n\n\tduk__ivalue_regconst(res, st.reg_obj);\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_OBJECT_LITERAL);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Parse argument list.  Arguments are written to temps starting from\n * \"next temp\".  Returns number of arguments parsed.  Expects left paren\n * to be already eaten, and eats the right paren before returning.\n */\nDUK_LOCAL duk_int_t duk__parse_arguments(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_int_t nargs = 0;\n\tduk_regconst_t reg_temp;\n\n\t/* Note: expect that caller has already eaten the left paren */\n\n\tDUK_DDD(DUK_DDDPRINT(\"start parsing arguments, prev_token.t=%ld, curr_token.t=%ld\",\n\t                     (long) comp_ctx->prev_token.t, (long) comp_ctx->curr_token.t));\n\n\tfor (;;) {\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RPAREN) {\n\t\t\tbreak;\n\t\t}\n\t\tif (nargs > 0) {\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COMMA);\n\t\t}\n\n\t\t/* We want the argument expression value to go to \"next temp\"\n\t\t * without additional moves.  That should almost always be the\n\t\t * case, but we double check after expression parsing.\n\t\t *\n\t\t * This is not the cleanest possible approach.\n\t\t */\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);  /* bump up \"allocated\" reg count, just in case */\n\t\tDUK__SETTEMP(comp_ctx, reg_temp);\n\n\t\t/* binding power must be high enough to NOT allow comma expressions directly */\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp);  /* always allow 'in', coerce to 'tr' just in case */\n\n\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\t\tnargs++;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"argument #%ld written into reg %ld\", (long) nargs, (long) reg_temp));\n\t}\n\n\t/* eat the right paren */\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* RegExp mode does not matter. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing arguments\"));\n\n\treturn nargs;\n}\n\nDUK_LOCAL duk_bool_t duk__expr_is_empty(duk_compiler_ctx *comp_ctx) {\n\t/* empty expressions can be detected conveniently with nud/led counts */\n\treturn (comp_ctx->curr_func.nud_count == 0) &&\n\t       (comp_ctx->curr_func.led_count == 0);\n}\n\nDUK_LOCAL void duk__expr_nud(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_token *tk;\n\tduk_regconst_t temp_at_entry;\n\tduk_small_uint_t tok;\n\tduk_uint32_t args;  /* temp variable to pass constants and flags to shared code */\n\n\t/*\n\t *  ctx->prev_token     token to process with duk__expr_nud()\n\t *  ctx->curr_token     updated by caller\n\t *\n\t *  Note: the token in the switch below has already been eaten.\n\t */\n\n\ttemp_at_entry = DUK__GETTEMP(comp_ctx);\n\n\tcomp_ctx->curr_func.nud_count++;\n\n\ttk = &comp_ctx->prev_token;\n\ttok = tk->t;\n\tres->t = DUK_IVAL_NONE;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__expr_nud(), prev_token.t=%ld, allow_in=%ld, paren_level=%ld\",\n\t                     (long) tk->t, (long) comp_ctx->curr_func.allow_in, (long) comp_ctx->curr_func.paren_level));\n\n\tswitch (tok) {\n\n\t/* PRIMARY EXPRESSIONS */\n\n\tcase DUK_TOK_THIS: {\n\t\tduk_regconst_t reg_temp;\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk__emit_bc(comp_ctx,\n\t\t             DUK_OP_LDTHIS,\n\t\t             reg_temp);\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\tcase DUK_TOK_IDENTIFIER: {\n\t\tduk__ivalue_var_hstring(comp_ctx, res, tk->str1);\n\t\treturn;\n\t}\n\tcase DUK_TOK_NULL: {\n\t\tduk_push_null(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_TRUE: {\n\t\tduk_push_true(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_FALSE: {\n\t\tduk_push_false(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_NUMBER: {\n\t\tduk_push_number(thr, tk->num);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_STRING: {\n\t\tDUK_ASSERT(tk->str1 != NULL);\n\t\tduk_push_hstring(thr, tk->str1);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_REGEXP: {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\tduk_regconst_t reg_temp;\n\t\tduk_regconst_t rc_re_bytecode;  /* const */\n\t\tduk_regconst_t rc_re_source;    /* const */\n\n\t\tDUK_ASSERT(tk->str1 != NULL);\n\t\tDUK_ASSERT(tk->str2 != NULL);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"emitting regexp op, str1=%!O, str2=%!O\",\n\t\t                     (duk_heaphdr *) tk->str1,\n\t\t                     (duk_heaphdr *) tk->str2));\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk_push_hstring(thr, tk->str1);\n\t\tduk_push_hstring(thr, tk->str2);\n\n\t\t/* [ ... pattern flags ] */\n\n\t\tduk_regexp_compile(thr);\n\n\t\t/* [ ... escaped_source bytecode ] */\n\n\t\trc_re_bytecode = duk__getconst(comp_ctx);\n\t\trc_re_source = duk__getconst(comp_ctx);\n\n\t\tduk__emit_a_b_c(comp_ctx,\n\t\t                DUK_OP_REGEXP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t                reg_temp /*a*/,\n\t\t                rc_re_bytecode /*b*/,\n\t\t                rc_re_source /*c*/);\n\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\tgoto syntax_error;\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t}\n\tcase DUK_TOK_LBRACKET: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsing array literal\"));\n\t\tduk__nud_array_literal(comp_ctx, res);\n\t\treturn;\n\t}\n\tcase DUK_TOK_LCURLY: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsing object literal\"));\n\t\tduk__nud_object_literal(comp_ctx, res);\n\t\treturn;\n\t}\n\tcase DUK_TOK_LPAREN: {\n\t\tduk_bool_t prev_allow_in;\n\n\t\tcomp_ctx->curr_func.paren_level++;\n\t\tprev_allow_in = comp_ctx->curr_func.allow_in;\n\t\tcomp_ctx->curr_func.allow_in = 1; /* reset 'allow_in' for parenthesized expression */\n\n\t\tduk__expr(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);  /* Expression, terminates at a ')' */\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* No RegExp after parenthesized expression. */\n\t\tcomp_ctx->curr_func.allow_in = prev_allow_in;\n\t\tcomp_ctx->curr_func.paren_level--;\n\t\treturn;\n\t}\n\n\t/* MEMBER/NEW/CALL EXPRESSIONS */\n\n\tcase DUK_TOK_NEW: {\n\t\t/*\n\t\t *  Parsing an expression starting with 'new' is tricky because\n\t\t *  there are multiple possible productions deriving from\n\t\t *  LeftHandSideExpression which begin with 'new'.\n\t\t *\n\t\t *  We currently resort to one-token lookahead to distinguish the\n\t\t *  cases.  Hopefully this is correct.  The binding power must be\n\t\t *  such that parsing ends at an LPAREN (CallExpression) but not at\n\t\t *  a PERIOD or LBRACKET (MemberExpression).\n\t\t *\n\t\t *  See doc/compiler.rst for discussion on the parsing approach,\n\t\t *  and testcases/test-dev-new.js for a bunch of documented tests.\n\t\t */\n\n\t\tduk_regconst_t reg_target;\n\t\tduk_int_t nargs;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"begin parsing new expression\"));\n\n\t\treg_target = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n#if defined(DUK_USE_ES6)\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_PERIOD) {\n\t\t\t/* new.target */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new.target\"));\n\t\t\tduk__advance(comp_ctx);\n\t\t\tif (comp_ctx->curr_token.t_nores != DUK_TOK_IDENTIFIER ||\n\t\t\t    !duk_hstring_equals_ascii_cstring(comp_ctx->curr_token.str1, \"target\")) {\n\t\t\t\tgoto syntax_error_newtarget;\n\t\t\t}\n\t\t\tif (comp_ctx->curr_func.is_global) {\n\t\t\t\tgoto syntax_error_newtarget;\n\t\t\t}\n\t\t\tduk__advance(comp_ctx);\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_NEWTARGET,\n\t\t\t             reg_target);\n\t\t\tduk__ivalue_regconst(res, reg_target);\n\t\t\treturn;\n\t\t}\n#endif  /* DUK_USE_ES6 */\n\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_CALL /*rbp_flags*/, reg_target /*forced_reg*/);\n\t\tduk__emit_bc(comp_ctx, DUK_OP_NEWOBJ, reg_target + 1);  /* default instance */\n\t\tDUK__SETTEMP(comp_ctx, reg_target + 2);\n\n\t\t/* XXX: 'new obj.noSuch()' doesn't use GETPROPC now which\n\t\t * makes the error message worse than for obj.noSuch().\n\t\t */\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_LPAREN) {\n\t\t\t/* 'new' MemberExpression Arguments */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new expression has argument list\"));\n\t\t\tduk__advance(comp_ctx);\n\t\t\tnargs = duk__parse_arguments(comp_ctx, res);  /* parse args starting from \"next temp\", reg_target + 1 */\n\t\t\t/* right paren eaten */\n\t\t} else {\n\t\t\t/* 'new' MemberExpression */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"new expression has no argument list\"));\n\t\t\tnargs = 0;\n\t\t}\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t              DUK_OP_CALL0 | DUK_BC_CALL_FLAG_CONSTRUCT,\n\t\t              nargs /*num_args*/,\n\t\t              reg_target /*target*/);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"end parsing new expression\"));\n\n\t\tduk__ivalue_regconst(res, reg_target);\n\t\treturn;\n\t}\n\n\t/* FUNCTION EXPRESSIONS */\n\n\tcase DUK_TOK_FUNCTION: {\n\t\t/* Function expression.  Note that any statement beginning with 'function'\n\t\t * is handled by the statement parser as a function declaration, or a\n\t\t * non-standard function expression/statement (or a SyntaxError).  We only\n\t\t * handle actual function expressions (occurring inside an expression) here.\n\t\t *\n\t\t * O(depth^2) parse count for inner functions is handled by recording a\n\t\t * lexer offset on the first compilation pass, so that the function can\n\t\t * be efficiently skipped on the second pass.  This is encapsulated into\n\t\t * duk__parse_func_like_fnum().\n\t\t */\n\n\t\tduk_regconst_t reg_temp;\n\t\tduk_int_t fnum;\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t/* curr_token follows 'function' */\n\t\tfnum = duk__parse_func_like_fnum(comp_ctx, 0 /*flags*/);\n\t\tDUK_DDD(DUK_DDDPRINT(\"parsed inner function -> fnum %ld\", (long) fnum));\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               DUK_OP_CLOSURE,\n\t\t               reg_temp /*a*/,\n\t\t               (duk_regconst_t) fnum /*bc*/);\n\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\n\t/* UNARY EXPRESSIONS */\n\n\tcase DUK_TOK_DELETE: {\n\t\t/* Delete semantics are a bit tricky.  The description in E5 specification\n\t\t * is kind of confusing, because it distinguishes between resolvability of\n\t\t * a reference (which is only known at runtime) seemingly at compile time\n\t\t * (= SyntaxError throwing).\n\t\t */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\t/* not allowed in strict mode, regardless of whether resolves;\n\t\t\t * in non-strict mode DELVAR handles both non-resolving and\n\t\t\t * resolving cases (the specification description is a bit confusing).\n\t\t\t */\n\n\t\t\tduk_regconst_t reg_temp;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\tif (comp_ctx->curr_func.is_strict) {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_CANNOT_DELETE_IDENTIFIER);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\n\t\t\tDUK__SETTEMP(comp_ctx, temp_at_entry);\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\t/* register bound variables are non-configurable -> always false */\n\t\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t\t             DUK_OP_LDFALSE,\n\t\t\t\t             reg_temp);\n\t\t\t} else {\n\t\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\t\trc_varname = duk__getconst(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_DELVAR,\n\t\t\t\t               reg_temp,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\t\t\tduk__ivalue_regconst(res, reg_temp);\n\t\t} else if (res->t == DUK_IVAL_PROP) {\n\t\t\tduk_regconst_t reg_temp;\n\t\t\tduk_regconst_t reg_obj;\n\t\t\tduk_regconst_t rc_key;\n\n\t\t\tDUK__SETTEMP(comp_ctx, temp_at_entry);\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_DELPROP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_temp,\n\t\t\t                reg_obj,\n\t\t\t                rc_key);\n\n\t\t\tduk__ivalue_regconst(res, reg_temp);\n\t\t} else {\n\t\t\t/* non-Reference deletion is always 'true', even in strict mode */\n\t\t\tduk_push_true(thr);\n\t\t\tgoto plain_value;\n\t\t}\n\t\treturn;\n\t}\n\tcase DUK_TOK_VOID: {\n\t\tduk__expr_toplain_ignore(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tduk_push_undefined(thr);\n\t\tgoto plain_value;\n\t}\n\tcase DUK_TOK_TYPEOF: {\n\t\t/* 'typeof' must handle unresolvable references without throwing\n\t\t * a ReferenceError (E5 Section 11.4.3).  Register mapped values\n\t\t * will never be unresolvable so special handling is only required\n\t\t * when an identifier is a \"slow path\" one.\n\t\t */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\n\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\t\t\tduk_regconst_t reg_temp;\n\n\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\tif (!duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"typeof for an identifier name which could not be resolved \"\n\t\t\t\t                     \"at compile time, need to use special run-time handling\"));\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_TYPEOFID,\n\t\t\t\t               reg_temp,\n\t\t\t\t               rc_varname);\n\t\t\t\tduk__ivalue_regconst(res, reg_temp);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\targs = DUK_OP_TYPEOF;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_INCREMENT: {\n\t\targs = (DUK_OP_PREINCP << 8) + DUK_OP_PREINCR;\n\t\tgoto preincdec;\n\t}\n\tcase DUK_TOK_DECREMENT: {\n\t\targs = (DUK_OP_PREDECP << 8) + DUK_OP_PREDECR;\n\t\tgoto preincdec;\n\t}\n\tcase DUK_TOK_ADD: {\n\t\t/* unary plus */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE &&\n\t\t    duk_is_number(thr, res->x1.valstack_idx)) {\n\t\t\t/* unary plus of a number is identity */\n\t\t\treturn;\n\t\t}\n\t\targs = DUK_OP_UNP;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_SUB: {\n\t\t/* unary minus */\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE &&\n\t\t    duk_is_number(thr, res->x1.valstack_idx)) {\n\t\t\t/* this optimization is important to handle negative literals\n\t\t\t * (which are not directly provided by the lexical grammar)\n\t\t\t */\n\t\t\tduk_tval *tv_num;\n\t\t\tduk_double_union du;\n\n\t\t\ttv_num = DUK_GET_TVAL_POSIDX(thr, res->x1.valstack_idx);\n\t\t\tDUK_ASSERT(tv_num != NULL);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_num));\n\t\t\tdu.d = DUK_TVAL_GET_NUMBER(tv_num);\n\t\t\tdu.d = -du.d;\n\t\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\t\t\tDUK_TVAL_SET_NUMBER(tv_num, du.d);\n\t\t\treturn;\n\t\t}\n\t\targs = DUK_OP_UNM;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_BNOT: {\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\targs = DUK_OP_BNOT;\n\t\tgoto unary;\n\t}\n\tcase DUK_TOK_LNOT: {\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_VALUE) {\n\t\t\t/* Very minimal inlining to handle common idioms '!0' and '!1',\n\t\t\t * and also boolean arguments like '!false' and '!true'.\n\t\t\t */\n\t\t\tduk_tval *tv_val;\n\n\t\t\ttv_val = DUK_GET_TVAL_POSIDX(thr, res->x1.valstack_idx);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tif (DUK_TVAL_IS_NUMBER(tv_val)) {\n\t\t\t\tduk_double_t d;\n\t\t\t\td = DUK_TVAL_GET_NUMBER(tv_val);\n\t\t\t\tif (d == 0.0) {\n\t\t\t\t\t/* Matches both +0 and -0 on purpose. */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"inlined lnot: !0 -> true\"));\n\t\t\t\t\tDUK_TVAL_SET_BOOLEAN_TRUE(tv_val);\n\t\t\t\t\treturn;\n\t\t\t\t} else if (d == 1.0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"inlined lnot: !1 -> false\"));\n\t\t\t\t\tDUK_TVAL_SET_BOOLEAN_FALSE(tv_val);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t} else if (DUK_TVAL_IS_BOOLEAN(tv_val)) {\n\t\t\t\tduk_small_uint_t v;\n\t\t\t\tv = DUK_TVAL_GET_BOOLEAN(tv_val);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"inlined lnot boolean: %ld\", (long) v));\n\t\t\t\tDUK_ASSERT(v == 0 || v == 1);\n\t\t\t\tDUK_TVAL_SET_BOOLEAN(tv_val, v ^ 0x01);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\targs = DUK_OP_LNOT;\n\t\tgoto unary;\n\t}\n\n\t}  /* end switch */\n\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);\n\tDUK_WO_NORETURN(return;);\n\n unary:\n\t{\n\t\t/* Unary opcodes use just the 'BC' register source because it\n\t\t * matches current shuffle limits, and maps cleanly to 16 high\n\t\t * bits of the opcode.\n\t\t */\n\n\t\tduk_regconst_t reg_src, reg_res;\n\n\t\treg_src = duk__ivalue_toregconst_raw(comp_ctx, res, -1 /*forced_reg*/, 0 /*flags*/);\n\t\tif (DUK__ISREG_TEMP(comp_ctx, reg_src)) {\n\t\t\treg_res = reg_src;\n\t\t} else {\n\t\t\treg_res = DUK__ALLOCTEMP(comp_ctx);\n\t\t}\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t             args,\n\t\t             reg_res,\n\t\t             reg_src);\n\t\tduk__ivalue_regconst(res, reg_res);\n\t\treturn;\n\t}\n\n preincdec:\n\t{\n\t\t/* preincrement and predecrement */\n\t\tduk_regconst_t reg_res;\n\t\tduk_small_uint_t args_op1 = args & 0xff;  /* DUK_OP_PREINCR/DUK_OP_PREDECR */\n\t\tduk_small_uint_t args_op2 = args >> 8;    /* DUK_OP_PREINCP_RR/DUK_OP_PREDECP_RR */\n\n\t\t/* Specific assumptions for opcode numbering. */\n\t\tDUK_ASSERT(DUK_OP_PREINCR + 4 == DUK_OP_PREINCV);\n\t\tDUK_ASSERT(DUK_OP_PREDECR + 4 == DUK_OP_PREDECV);\n\n\t\treg_res = DUK__ALLOCTEMP(comp_ctx);\n\n\t\tduk__expr(comp_ctx, res, DUK__BP_MULTIPLICATIVE /*rbp_flags*/);  /* UnaryExpression */\n\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\th_varname = duk_known_hstring(thr, res->x1.valstack_idx);\n\n\t\t\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               args_op1,  /* e.g. DUK_OP_PREINCR */\n\t\t\t\t               reg_res,\n\t\t\t\t               reg_varbind);\n\t\t\t} else {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t                args_op1 + 4,  /* e.g. DUK_OP_PREINCV */\n\t\t\t\t                reg_res,\n\t\t\t\t                rc_varname);\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"preincdec to '%!O' -> reg_varbind=%ld, rc_varname=%ld\",\n\t\t\t                     (duk_heaphdr *) h_varname, (long) reg_varbind, (long) rc_varname));\n\t\t} else if (res->t == DUK_IVAL_PROP) {\n\t\t\tduk_regconst_t reg_obj;  /* allocate to reg only (not const) */\n\t\t\tduk_regconst_t rc_key;\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                args_op2 | DUK__EMIT_FLAG_BC_REGCONST,  /* e.g. DUK_OP_PREINCP */\n\t\t\t                reg_res,\n\t\t\t                reg_obj,\n\t\t\t                rc_key);\n\t\t} else {\n\t\t\t/* Technically return value is not needed because INVLHS will\n\t\t\t * unconditially throw a ReferenceError.  Coercion is necessary\n\t\t\t * for proper semantics (consider ToNumber() called for an object).\n\t\t\t * Use DUK_OP_UNP with a dummy register to get ToNumber().\n\t\t\t */\n\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_res);\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_UNP,\n\t\t\t             reg_res);  /* for side effects, result ignored */\n\t\t\tduk__emit_op_only(comp_ctx,\n\t\t\t                  DUK_OP_INVLHS);\n\t\t}\n\t\tDUK__SETTEMP(comp_ctx, reg_res + 1);\n\t\tduk__ivalue_regconst(res, reg_res);\n\t\treturn;\n\t}\n\n plain_value:\n\t{\n\t\t/* Stack top contains plain value */\n\t\tduk__ivalue_plain_fromstack(comp_ctx, res);\n\t\treturn;\n\t}\n\n#if defined(DUK_USE_ES6)\n syntax_error_newtarget:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_NEWTARGET);\n\tDUK_WO_NORETURN(return;);\n#endif\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_EXPRESSION);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* XXX: add flag to indicate whether caller cares about return value; this\n * affects e.g. handling of assignment expressions.  This change needs API\n * changes elsewhere too.\n */\nDUK_LOCAL void duk__expr_led(duk_compiler_ctx *comp_ctx, duk_ivalue *left, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_token *tk;\n\tduk_small_uint_t tok;\n\tduk_uint32_t args;  /* temp variable to pass constants and flags to shared code */\n\n\t/*\n\t *  ctx->prev_token     token to process with duk__expr_led()\n\t *  ctx->curr_token     updated by caller\n\t */\n\n\tcomp_ctx->curr_func.led_count++;\n\n\t/* The token in the switch has already been eaten here */\n\ttk = &comp_ctx->prev_token;\n\ttok = tk->t;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__expr_led(), prev_token.t=%ld, allow_in=%ld, paren_level=%ld\",\n\t                     (long) tk->t, (long) comp_ctx->curr_func.allow_in, (long) comp_ctx->curr_func.paren_level));\n\n\t/* XXX: default priority for infix operators is duk__expr_lbp(tok) -> get it here? */\n\n\tswitch (tok) {\n\n\t/* PRIMARY EXPRESSIONS */\n\n\tcase DUK_TOK_PERIOD: {\n\t\t/* Property access expressions are critical for correct LHS ordering,\n\t\t * see comments in duk__expr()!\n\t\t *\n\t\t * A conservative approach would be to use duk__ivalue_totempconst()\n\t\t * for 'left'.  However, allowing a reg-bound variable seems safe here\n\t\t * and is nice because \"foo.bar\" is a common expression.  If the ivalue\n\t\t * is used in an expression a GETPROP will occur before any changes to\n\t\t * the base value can occur.  If the ivalue is used as an assignment\n\t\t * LHS, the assignment code will ensure the base value is safe from\n\t\t * RHS mutation.\n\t\t */\n\n\t\t/* XXX: This now coerces an identifier into a GETVAR to a temp, which\n\t\t * causes an extra LDREG in call setup.  It's sufficient to coerce to a\n\t\t * unary ivalue?\n\t\t */\n\t\tduk__ivalue_toplain(comp_ctx, left);\n\n\t\t/* NB: must accept reserved words as property name */\n\t\tif (comp_ctx->curr_token.t_nores != DUK_TOK_IDENTIFIER) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EXPECTED_IDENTIFIER);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\n\t\tres->t = DUK_IVAL_PROP;\n\t\tduk__copy_ispec(comp_ctx, &left->x1, &res->x1);  /* left.x1 -> res.x1 */\n\t\tDUK_ASSERT(comp_ctx->curr_token.str1 != NULL);\n\t\tduk_push_hstring(thr, comp_ctx->curr_token.str1);\n\t\tduk_replace(thr, res->x2.valstack_idx);\n\t\tres->x2.t = DUK_ISPEC_VALUE;\n\n\t\t/* special RegExp literal handling after IdentifierName */\n\t\tcomp_ctx->curr_func.reject_regexp_in_adv = 1;\n\n\t\tduk__advance(comp_ctx);\n\t\treturn;\n\t}\n\tcase DUK_TOK_LBRACKET: {\n\t\t/* Property access expressions are critical for correct LHS ordering,\n\t\t * see comments in duk__expr()!\n\t\t */\n\n\t\t/* XXX: optimize temp reg use */\n\t\t/* XXX: similar coercion issue as in DUK_TOK_PERIOD */\n\t\t/* XXX: coerce to regs? it might be better for enumeration use, where the\n\t\t * same PROP ivalue is used multiple times.  Or perhaps coerce PROP further\n\t\t * there?\n\t\t */\n\t\t/* XXX: for simple cases like x['y'] an unnecessary LDREG is\n\t\t * emitted for the base value; could avoid it if we knew that\n\t\t * the key expression is safe (e.g. just a single literal).\n\t\t */\n\n\t\t/* The 'left' value must not be a register bound variable\n\t\t * because it may be mutated during the rest of the expression\n\t\t * and E5.1 Section 11.2.1 specifies the order of evaluation\n\t\t * so that the base value is evaluated first.\n\t\t * See: test-bug-nested-prop-mutate.js.\n\t\t */\n\t\tduk__ivalue_totempconst(comp_ctx, left);\n\t\tduk__expr_toplain(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);  /* Expression, ']' terminates */\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RBRACKET);\n\n\t\tres->t = DUK_IVAL_PROP;\n\t\tduk__copy_ispec(comp_ctx, &res->x1, &res->x2);   /* res.x1 -> res.x2 */\n\t\tduk__copy_ispec(comp_ctx, &left->x1, &res->x1);  /* left.x1 -> res.x1 */\n\t\treturn;\n\t}\n\tcase DUK_TOK_LPAREN: {\n\t\t/* function call */\n\t\tduk_regconst_t reg_cs = DUK__ALLOCTEMPS(comp_ctx, 2);\n\t\tduk_int_t nargs;\n\t\tduk_small_uint_t call_op = DUK_OP_CALL0;\n\n\t\t/* XXX: attempt to get the call result to \"next temp\" whenever\n\t\t * possible to avoid unnecessary register shuffles.\n\t\t */\n\n\t\t/*\n\t\t *  Setup call: target and 'this' binding.  Three cases:\n\t\t *\n\t\t *    1. Identifier base (e.g. \"foo()\")\n\t\t *    2. Property base (e.g. \"foo.bar()\")\n\t\t *    3. Register base (e.g. \"foo()()\"; i.e. when a return value is a function)\n\t\t */\n\n\t\tif (left->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with identifier base\"));\n\n\t\t\th_varname = duk_known_hstring(thr, left->x1.valstack_idx);\n\t\t\tif (h_varname == DUK_HTHREAD_STRING_EVAL(thr)) {\n\t\t\t\t/* Potential direct eval call detected, flag the CALL\n\t\t\t\t * so that a run-time \"direct eval\" check is made and\n\t\t\t\t * special behavior may be triggered.  Note that this\n\t\t\t\t * does not prevent 'eval' from being register bound.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with identifier 'eval' \"\n\t\t\t\t                     \"-> using EVALCALL, marking function \"\n\t\t\t\t                     \"as may_direct_eval\"));\n\t\t\t\tcall_op |= DUK_BC_CALL_FLAG_CALLED_AS_EVAL;\n\t\t\t\tcomp_ctx->curr_func.may_direct_eval = 1;\n\t\t\t}\n\n\t\t\tduk_dup(thr, left->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t              DUK_OP_CSREG | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t              reg_varbind,\n\t\t\t\t              reg_cs + 0);\n\t\t\t} else {\n\t\t\t\t/* XXX: expand target register or constant field to\n\t\t\t\t * reduce shuffling.\n\t\t\t\t */\n\t\t\t\tDUK_ASSERT(DUK__ISCONST(rc_varname));\n\t\t\t\tduk__emit_a_b(comp_ctx,\n\t\t\t\t              DUK_OP_CSVAR | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t              reg_cs + 0,\n\t\t\t\t              rc_varname);\n\t\t\t}\n\t\t} else if (left->t == DUK_IVAL_PROP) {\n\t\t\t/* Call through a property lookup, E5 Section 11.2.3, step 6.a.i,\n\t\t\t * E5 Section 10.4.3.  There used to be a separate CSPROP opcode\n\t\t\t * but a typical call setup took 3 opcodes (e.g. LDREG, LDCONST,\n\t\t\t * CSPROP) and the same can be achieved with ordinary loads.\n\t\t\t */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\t\tduk_regconst_t reg_key;\n#endif\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with property base\"));\n\n\t\t\t/* XXX: For Math.sin() this generates: LDCONST + LDREG +\n\t\t\t * GETPROPC + call.  The LDREG is unnecessary because LDCONST\n\t\t\t * could be loaded directly into reg_cs + 1.  This doesn't\n\t\t\t * happen now because a variable cannot be in left->x1 of a\n\t\t\t * DUK_IVAL_PROP.  We could notice that left->x1 is a temp\n\t\t\t * and reuse, but it would still be in the wrong position\n\t\t\t * (reg_cs + 0 rather than reg_cs + 1).\n\t\t\t */\n\t\t\tduk__ispec_toforcedreg(comp_ctx, &left->x1, reg_cs + 1);  /* base */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\t\treg_key = duk__ispec_toregconst_raw(comp_ctx, &left->x2, -1, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_GETPROPC | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_cs + 0,\n\t\t\t                reg_cs + 1,\n\t\t\t                reg_key);\n#else\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_cs + 0);  /* base[key] */\n#endif\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function call with register base\"));\n\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_cs + 0);\n#if 0\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CSREG | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t               reg_cs + 0,\n\t\t\t               reg_cs + 0);  /* in-place setup */\n#endif\n\t\t\t/* Because of in-place setup, REGCS is equivalent to\n\t\t\t * just this LDUNDEF.\n\t\t\t */\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_LDUNDEF, reg_cs + 1);\n\t\t}\n\n\t\tDUK__SETTEMP(comp_ctx, reg_cs + 2);\n\t\tnargs = duk__parse_arguments(comp_ctx, res);  /* parse args starting from \"next temp\" */\n\n\t\t/* Tailcalls are handled by back-patching the already emitted opcode\n\t\t * later in return statement parser.\n\t\t */\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               call_op,\n\t\t               (duk_regconst_t) nargs /*numargs*/,\n\t\t               reg_cs /*basereg*/);\n\t\tDUK__SETTEMP(comp_ctx, reg_cs + 1);    /* result in csreg */\n\n\t\tduk__ivalue_regconst(res, reg_cs);\n\t\treturn;\n\t}\n\n\t/* POSTFIX EXPRESSION */\n\n\tcase DUK_TOK_INCREMENT: {\n\t\targs = (DUK_OP_POSTINCP_RR << 16) + (DUK_OP_POSTINCR << 8) + 0;\n\t\tgoto postincdec;\n\t}\n\tcase DUK_TOK_DECREMENT: {\n\t\targs = (DUK_OP_POSTDECP_RR << 16) + (DUK_OP_POSTDECR << 8) + 0;\n\t\tgoto postincdec;\n\t}\n\n\t/* EXPONENTIATION EXPRESSION */\n\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\tcase DUK_TOK_EXP: {\n\t\targs = (DUK_OP_EXP << 8) + DUK__BP_EXPONENTIATION - 1;  /* UnaryExpression */\n\t\tgoto binary;\n\t}\n#endif\n\n\t/* MULTIPLICATIVE EXPRESSION */\n\n\tcase DUK_TOK_MUL: {\n\t\targs = (DUK_OP_MUL << 8) + DUK__BP_MULTIPLICATIVE;  /* ExponentiationExpression */\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_DIV: {\n\t\targs = (DUK_OP_DIV << 8) + DUK__BP_MULTIPLICATIVE;  /* ExponentiationExpression */\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_MOD: {\n\t\targs = (DUK_OP_MOD << 8) + DUK__BP_MULTIPLICATIVE;  /* ExponentiationExpression */\n\t\tgoto binary;\n\t}\n\n\t/* ADDITIVE EXPRESSION */\n\n\tcase DUK_TOK_ADD: {\n\t\targs = (DUK_OP_ADD << 8) + DUK__BP_ADDITIVE;  /* MultiplicativeExpression */\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_SUB: {\n\t\targs = (DUK_OP_SUB << 8) + DUK__BP_ADDITIVE;  /* MultiplicativeExpression */\n\t\tgoto binary;\n\t}\n\n\t/* SHIFT EXPRESSION */\n\n\tcase DUK_TOK_ALSHIFT: {\n\t\t/* << */\n\t\targs = (DUK_OP_BASL << 8) + DUK__BP_SHIFT;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_ARSHIFT: {\n\t\t/* >> */\n\t\targs = (DUK_OP_BASR << 8) + DUK__BP_SHIFT;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_RSHIFT: {\n\t\t/* >>> */\n\t\targs = (DUK_OP_BLSR << 8) + DUK__BP_SHIFT;\n\t\tgoto binary;\n\t}\n\n\t/* RELATIONAL EXPRESSION */\n\n\tcase DUK_TOK_LT: {\n\t\t/* < */\n\t\targs = (DUK_OP_LT << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_GT: {\n\t\targs = (DUK_OP_GT << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_LE: {\n\t\targs = (DUK_OP_LE << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_GE: {\n\t\targs = (DUK_OP_GE << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_INSTANCEOF: {\n\t\targs = (DUK_OP_INSTOF << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_IN: {\n\t\targs = (DUK_OP_IN << 8) + DUK__BP_RELATIONAL;\n\t\tgoto binary;\n\t}\n\n\t/* EQUALITY EXPRESSION */\n\n\tcase DUK_TOK_EQ: {\n\t\targs = (DUK_OP_EQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_NEQ: {\n\t\targs = (DUK_OP_NEQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_SEQ: {\n\t\targs = (DUK_OP_SEQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_SNEQ: {\n\t\targs = (DUK_OP_SNEQ << 8) + DUK__BP_EQUALITY;\n\t\tgoto binary;\n\t}\n\n\t/* BITWISE EXPRESSIONS */\n\n\tcase DUK_TOK_BAND: {\n\t\targs = (DUK_OP_BAND << 8) + DUK__BP_BAND;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_BXOR: {\n\t\targs = (DUK_OP_BXOR << 8) + DUK__BP_BXOR;\n\t\tgoto binary;\n\t}\n\tcase DUK_TOK_BOR: {\n\t\targs = (DUK_OP_BOR << 8) + DUK__BP_BOR;\n\t\tgoto binary;\n\t}\n\n\t/* LOGICAL EXPRESSIONS */\n\n\tcase DUK_TOK_LAND: {\n\t\t/* syntactically left-associative but parsed as right-associative */\n\t\targs = (1 << 8) + DUK__BP_LAND - 1;\n\t\tgoto binary_logical;\n\t}\n\tcase DUK_TOK_LOR: {\n\t\t/* syntactically left-associative but parsed as right-associative */\n\t\targs = (0 << 8) + DUK__BP_LOR - 1;\n\t\tgoto binary_logical;\n\t}\n\n\t/* CONDITIONAL EXPRESSION */\n\n\tcase DUK_TOK_QUESTION: {\n\t\t/* XXX: common reg allocation need is to reuse a sub-expression's temp reg,\n\t\t * but only if it really is a temp.  Nothing fancy here now.\n\t\t */\n\t\tduk_regconst_t reg_temp;\n\t\tduk_int_t pc_jump1;\n\t\tduk_int_t pc_jump2;\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_temp);\n\t\tduk__emit_if_true_skip(comp_ctx, reg_temp);\n\t\tpc_jump1 = duk__emit_jump_empty(comp_ctx);  /* jump to false */\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp /*forced_reg*/);  /* AssignmentExpression */\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\t\tpc_jump2 = duk__emit_jump_empty(comp_ctx);  /* jump to end */\n\t\tduk__patch_jump_here(comp_ctx, pc_jump1);\n\t\tduk__expr_toforcedreg(comp_ctx, res, DUK__BP_COMMA /*rbp_flags*/, reg_temp /*forced_reg*/);  /* AssignmentExpression */\n\t\tduk__patch_jump_here(comp_ctx, pc_jump2);\n\n\t\tDUK__SETTEMP(comp_ctx, reg_temp + 1);\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\n\t/* ASSIGNMENT EXPRESSION */\n\n\tcase DUK_TOK_EQUALSIGN: {\n\t\t/*\n\t\t *  Assignments are right associative, allows e.g.\n\t\t *    a = 5;\n\t\t *    a += b = 9;   // same as a += (b = 9)\n\t\t *  -> expression value 14, a = 14, b = 9\n\t\t *\n\t\t *  Right associativiness is reflected in the BP for recursion,\n\t\t *  \"-1\" ensures assignment operations are allowed.\n\t\t *\n\t\t *  XXX: just use DUK__BP_COMMA (i.e. no need for 2-step bp levels)?\n\t\t */\n\t\targs = (DUK_OP_NONE << 8) + DUK__BP_ASSIGNMENT - 1;   /* DUK_OP_NONE marks a 'plain' assignment */\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_ADD_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_ADD << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_SUB_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_SUB << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_MUL_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_MUL << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_DIV_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_DIV << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_MOD_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_MOD << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\tcase DUK_TOK_EXP_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_EXP << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n#endif\n\tcase DUK_TOK_ALSHIFT_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BASL << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_ARSHIFT_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BASR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_RSHIFT_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BLSR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_BAND_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BAND << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_BOR_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BOR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\tcase DUK_TOK_BXOR_EQ: {\n\t\t/* right associative */\n\t\targs = (DUK_OP_BXOR << 8) + DUK__BP_ASSIGNMENT - 1;\n\t\tgoto assign;\n\t}\n\n\t/* COMMA */\n\n\tcase DUK_TOK_COMMA: {\n\t\t/* right associative */\n\n\t\tduk__ivalue_toplain_ignore(comp_ctx, left);  /* need side effects, not value */\n\t\tduk__expr_toplain(comp_ctx, res, DUK__BP_COMMA - 1 /*rbp_flags*/);\n\n\t\t/* return 'res' (of right part) as our result */\n\t\treturn;\n\t}\n\n\tdefault: {\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_D(DUK_DPRINT(\"parse error: unexpected token: %ld\", (long) tok));\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_PARSE_ERROR);\n\tDUK_WO_NORETURN(return;);\n\n#if 0\n\t/* XXX: shared handling for 'duk__expr_lhs'? */\n\tif (comp_ctx->curr_func.paren_level == 0 && XXX) {\n\t\tcomp_ctx->curr_func.duk__expr_lhs = 0;\n\t}\n#endif\n\n binary:\n\t/*\n\t *  Shared handling of binary operations\n\t *\n\t *  args = (opcode << 8) + rbp\n\t */\n\t{\n\t\tduk__ivalue_toplain(comp_ctx, left);\n\t\tduk__expr_toplain(comp_ctx, res, args & 0xff /*rbp_flags*/);\n\n\t\t/* combine left->x1 and res->x1 (right->x1, really) -> (left->x1 OP res->x1) */\n\t\tDUK_ASSERT(left->t == DUK_IVAL_PLAIN);\n\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN);\n\n\t\tres->t = DUK_IVAL_ARITH;\n\t\tres->op = (args >> 8) & 0xff;\n\n\t\tres->x2.t = res->x1.t;\n\t\tres->x2.regconst = res->x1.regconst;\n\t\tduk_copy(thr, res->x1.valstack_idx, res->x2.valstack_idx);\n\n\t\tres->x1.t = left->x1.t;\n\t\tres->x1.regconst = left->x1.regconst;\n\t\tduk_copy(thr, left->x1.valstack_idx, res->x1.valstack_idx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"binary op, res: t=%ld, x1.t=%ld, x1.regconst=0x%08lx, x2.t=%ld, x2.regconst=0x%08lx\",\n\t\t                     (long) res->t, (long) res->x1.t, (unsigned long) res->x1.regconst, (long) res->x2.t, (unsigned long) res->x2.regconst));\n\t\treturn;\n\t}\n\n binary_logical:\n\t/*\n\t *  Shared handling for logical AND and logical OR.\n\t *\n\t *  args = (truthval << 8) + rbp\n\t *\n\t *  Truthval determines when to skip right-hand-side.\n\t *  For logical AND truthval=1, for logical OR truthval=0.\n\t *\n\t *  See doc/compiler.rst for discussion on compiling logical\n\t *  AND and OR expressions.  The approach here is very simplistic,\n\t *  generating extra jumps and multiple evaluations of truth values,\n\t *  but generates code on-the-fly with only local back-patching.\n\t *\n\t *  Both logical AND and OR are syntactically left-associated.\n\t *  However, logical ANDs are compiled as right associative\n\t *  expressions, i.e. \"A && B && C\" as \"A && (B && C)\", to allow\n\t *  skip jumps to skip over the entire tail.  Similarly for logical OR.\n\t */\n\n\t{\n\t\tduk_regconst_t reg_temp;\n\t\tduk_int_t pc_jump;\n\t\tduk_small_uint_t args_truthval = args >> 8;\n\t\tduk_small_uint_t args_rbp = args & 0xff;\n\n\t\t/* XXX: unoptimal use of temps, resetting */\n\n\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_temp);\n\t\tDUK_ASSERT(DUK__ISREG(reg_temp));\n\t\tduk__emit_bc(comp_ctx,\n\t\t            (args_truthval ? DUK_OP_IFTRUE_R : DUK_OP_IFFALSE_R),\n\t\t            reg_temp);  /* skip jump conditionally */\n\t\tpc_jump = duk__emit_jump_empty(comp_ctx);\n\t\tduk__expr_toforcedreg(comp_ctx, res, args_rbp /*rbp_flags*/, reg_temp /*forced_reg*/);\n\t\tduk__patch_jump_here(comp_ctx, pc_jump);\n\n\t\tduk__ivalue_regconst(res, reg_temp);\n\t\treturn;\n\t}\n\n assign:\n\t/*\n\t *  Shared assignment expression handling\n\t *\n\t *  args = (opcode << 8) + rbp\n\t *\n\t *  If 'opcode' is DUK_OP_NONE, plain assignment without arithmetic.\n\t *  Syntactically valid left-hand-side forms which are not accepted as\n\t *  left-hand-side values (e.g. as in \"f() = 1\") must NOT cause a\n\t *  SyntaxError, but rather a run-time ReferenceError.\n\t *\n\t *  When evaluating X <op>= Y, the LHS (X) is conceptually evaluated\n\t *  to a temporary first.  The RHS is then evaluated.  Finally, the\n\t *  <op> is applied to the initial value of RHS (not the value after\n\t *  RHS evaluation), and written to X.  Doing so concretely generates\n\t *  inefficient code so we'd like to avoid the temporary when possible.\n\t *  See: https://github.com/svaarala/duktape/pull/992.\n\t *\n\t *  The expression value (final LHS value, written to RHS) is\n\t *  conceptually copied into a fresh temporary so that it won't\n\t *  change even if the LHS/RHS values change in outer expressions.\n\t *  For example, it'd be generally incorrect for the expression value\n\t *  to be the RHS register binding, unless there's a guarantee that it\n\t *  won't change during further expression evaluation.  Using the\n\t *  temporary concretely produces inefficient bytecode, so we try to\n\t *  avoid the extra temporary for some known-to-be-safe cases.\n\t *  Currently the only safe case we detect is a \"top level assignment\",\n\t *  for example \"x = y + z;\", where the assignment expression value is\n\t *  ignored.\n\t *  See: test-dev-assign-expr.js and test-bug-assign-mutate-gh381.js.\n\t */\n\n\t{\n\t\tduk_small_uint_t args_op = args >> 8;\n\t\tduk_small_uint_t args_rbp = args & 0xff;\n\t\tduk_bool_t toplevel_assign;\n\n\t\t/* XXX: here we need to know if 'left' is left-hand-side compatible.\n\t\t * That information is no longer available from current expr parsing\n\t\t * state; it would need to be carried into the 'left' ivalue or by\n\t\t * some other means.\n\t\t */\n\n\t\t/* A top-level assignment is e.g. \"x = y;\".  For these it's safe\n\t\t * to use the RHS as-is as the expression value, even if the RHS\n\t\t * is a reg-bound identifier.  The RHS ('res') is right associative\n\t\t * so it has consumed all other assignment level operations; the\n\t\t * only relevant lower binding power construct is comma operator\n\t\t * which will ignore the expression value provided here.  Usually\n\t\t * the top level assignment expression value is ignored, but it\n\t\t * is relevant for e.g. eval code.\n\t\t */\n\t\ttoplevel_assign = (comp_ctx->curr_func.nud_count == 1 && /* one token before */\n\t\t                   comp_ctx->curr_func.led_count == 1);  /* one operator (= assign) */\n\t\tDUK_DDD(DUK_DDDPRINT(\"assignment: nud_count=%ld, led_count=%ld, toplevel_assign=%ld\",\n\t\t                     (long) comp_ctx->curr_func.nud_count,\n\t\t                     (long) comp_ctx->curr_func.led_count,\n\t\t                     (long) toplevel_assign));\n\n\t\tif (left->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\tDUK_ASSERT(left->x1.t == DUK_ISPEC_VALUE);  /* LHS is already side effect free */\n\n\t\t\th_varname = duk_known_hstring(thr, left->x1.valstack_idx);\n\t\t\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\t\t\t/* E5 Section 11.13.1 (and others for other assignments), step 4. */\n\t\t\t\tgoto syntax_error_lvalue;\n\t\t\t}\n\t\t\tduk_dup(thr, left->x1.valstack_idx);\n\t\t\t(void) duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname);\n\n\t\t\tif (args_op == DUK_OP_NONE) {\n\t\t\t\tduk__expr(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\tif (toplevel_assign) {\n\t\t\t\t\t/* Any 'res' will do. */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"plain assignment, toplevel assign, use as is\"));\n\t\t\t\t} else {\n\t\t\t\t\t/* 'res' must be a plain ivalue, and not register-bound variable. */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"plain assignment, not toplevel assign, ensure not a reg-bound identifier\"));\n\t\t\t\t\tif (res->t != DUK_IVAL_PLAIN || (res->x1.t == DUK_ISPEC_REGCONST &&\n\t\t\t\t\t                                 DUK__ISREG_NOTTEMP(comp_ctx, res->x1.regconst))) {\n\t\t\t\t\t\tduk__ivalue_totempconst(comp_ctx, res);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* For X <op>= Y we need to evaluate the pre-op\n\t\t\t\t * value of X before evaluating the RHS: the RHS\n\t\t\t\t * can change X, but when we do <op> we must use\n\t\t\t\t * the pre-op value.\n\t\t\t\t */\n\t\t\t\tduk_regconst_t reg_temp;\n\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t\t\tif (reg_varbind >= 0) {\n\t\t\t\t\tduk_regconst_t reg_res;\n\t\t\t\t\tduk_regconst_t reg_src;\n\t\t\t\t\tduk_int_t pc_temp_load;\n\t\t\t\t\tduk_int_t pc_before_rhs;\n\t\t\t\t\tduk_int_t pc_after_rhs;\n\n\t\t\t\t\tif (toplevel_assign) {\n\t\t\t\t\t\t/* 'reg_varbind' is the operation result and can also\n\t\t\t\t\t\t * become the expression value for top level assignments\n\t\t\t\t\t\t * such as: \"var x; x += y;\".\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"<op>= expression is top level, write directly to reg_varbind\"));\n\t\t\t\t\t\treg_res = reg_varbind;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t/* Not safe to use 'reg_varbind' as assignment expression\n\t\t\t\t\t\t * value, so go through a temp.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"<op>= expression is not top level, write to reg_temp\"));\n\t\t\t\t\t\treg_res = reg_temp;  /* reg_res should be smallest possible */\n\t\t\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\t\t}\n\n\t\t\t\t\t/* Try to optimize X <op>= Y for reg-bound\n\t\t\t\t\t * variables.  Detect side-effect free RHS\n\t\t\t\t\t * narrowly by seeing whether it emits code.\n\t\t\t\t\t * If not, rewind the code emitter and overwrite\n\t\t\t\t\t * the unnecessary temp reg load.\n\t\t\t\t\t */\n\n\t\t\t\t\tpc_temp_load = duk__get_current_pc(comp_ctx);\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_LDREG,\n\t\t\t\t\t               reg_temp,\n\t\t\t\t\t               reg_varbind);\n\n\t\t\t\t\tpc_before_rhs = duk__get_current_pc(comp_ctx);\n\t\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\t\t\t\t\tpc_after_rhs = duk__get_current_pc(comp_ctx);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"pc_temp_load=%ld, pc_before_rhs=%ld, pc_after_rhs=%ld\",\n\t\t\t\t\t                   (long) pc_temp_load, (long) pc_before_rhs,\n\t\t\t\t\t                   (long) pc_after_rhs));\n\n\t\t\t\t\tif (pc_after_rhs == pc_before_rhs) {\n\t\t\t\t\t\t/* Note: if the reg_temp load generated shuffling\n\t\t\t\t\t\t * instructions, we may need to rewind more than\n\t\t\t\t\t\t * one instruction, so use explicit PC computation.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"rhs is side effect free, rewind and avoid unnecessary temp for reg-based <op>=\"));\n\t\t\t\t\t\tDUK_BW_ADD_PTR(comp_ctx->thr, &comp_ctx->curr_func.bw_code, (pc_temp_load - pc_before_rhs) * (duk_int_t) sizeof(duk_compiler_instr));\n\t\t\t\t\t\treg_src = reg_varbind;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"rhs evaluation emitted code, not sure if rhs is side effect free; use temp reg for LHS\"));\n\t\t\t\t\t\treg_src = reg_temp;\n\t\t\t\t\t}\n\n\t\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t\t                args_op | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t\t                reg_res,\n\t\t\t\t\t                reg_src,\n\t\t\t\t\t                res->x1.regconst);\n\n\t\t\t\t\tres->x1.regconst = reg_res;\n\n\t\t\t\t\t/* Ensure compact use of temps. */\n\t\t\t\t\tif (DUK__ISREG_TEMP(comp_ctx, reg_res)) {\n\t\t\t\t\t\tDUK__SETTEMP(comp_ctx, reg_res + 1);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t/* When LHS is not register bound, always go through a\n\t\t\t\t\t * temporary.  No optimization for top level assignment.\n\t\t\t\t\t */\n\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_GETVAR,\n\t\t\t\t\t               reg_temp,\n\t\t\t\t\t               rc_varname);\n\n\t\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\n\t\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t\t                args_op | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t\t                reg_temp,\n\t\t\t\t\t                reg_temp,\n\t\t\t\t\t                res->x1.regconst);\n\t\t\t\t\tres->x1.regconst = reg_temp;\n\t\t\t\t}\n\n\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\t\t\t}\n\n\t\t\t/* At this point 'res' holds the potential expression value.\n\t\t\t * It can be basically any ivalue here, including a reg-bound\n\t\t\t * identifier (if code above deems it safe) or a unary/binary\n\t\t\t * operation.  Operations must be resolved to a side effect free\n\t\t\t * plain value, and the side effects must happen exactly once.\n\t\t\t */\n\n\t\t\tif (reg_varbind >= 0) {\n\t\t\t\tif (res->t != DUK_IVAL_PLAIN) {\n\t\t\t\t\t/* Resolve 'res' directly into the LHS binding, and use\n\t\t\t\t\t * that as the expression value if safe.  If not safe,\n\t\t\t\t\t * resolve to a temp/const and copy to LHS.\n\t\t\t\t\t */\n\t\t\t\t\tif (toplevel_assign) {\n\t\t\t\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, (duk_int_t) reg_varbind);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk__ivalue_totempconst(comp_ctx, res);\n\t\t\t\t\t\tduk__copy_ivalue(comp_ctx, res, left);  /* use 'left' as a temp */\n\t\t\t\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, (duk_int_t) reg_varbind);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t/* Use 'res' as the expression value (it's side effect\n\t\t\t\t\t * free and may be a plain value, a register, or a\n\t\t\t\t\t * constant) and write it to the LHS binding too.\n\t\t\t\t\t */\n\t\t\t\t\tduk__copy_ivalue(comp_ctx, res, left);  /* use 'left' as a temp */\n\t\t\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, (duk_int_t) reg_varbind);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* Only a reg fits into 'A' so coerce 'res' into a register\n\t\t\t\t * for PUTVAR.\n\t\t\t\t *\n\t\t\t\t * XXX: here the current A/B/C split is suboptimal: we could\n\t\t\t\t * just use 9 bits for reg_res (and support constants) and 17\n\t\t\t\t * instead of 18 bits for the varname const index.\n\t\t\t\t */\n\n\t\t\t\tduk__ivalue_toreg(comp_ctx, res);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t               res->x1.regconst,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\n\t\t\t/* 'res' contains expression value */\n\t\t} else if (left->t == DUK_IVAL_PROP) {\n\t\t\t/* E5 Section 11.13.1 (and others) step 4 never matches for prop writes -> no check */\n\t\t\tduk_regconst_t reg_obj;\n\t\t\tduk_regconst_t rc_key;\n\t\t\tduk_regconst_t rc_res;\n\t\t\tduk_regconst_t reg_temp;\n\n\t\t\t/* Property access expressions ('a[b]') are critical to correct\n\t\t\t * LHS evaluation ordering, see test-dev-assign-eval-order*.js.\n\t\t\t * We must make sure that the LHS target slot (base object and\n\t\t\t * key) don't change during RHS evaluation.  The only concrete\n\t\t\t * problem is a register reference to a variable-bound register\n\t\t\t * (i.e., non-temp).  Require temp regs for both key and base.\n\t\t\t *\n\t\t\t * Don't allow a constant for the object (even for a number\n\t\t\t * etc), as it goes into the 'A' field of the opcode.\n\t\t\t */\n\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx,\n\t\t\t                                    &left->x1,\n\t\t\t                                    -1 /*forced_reg*/,\n\t\t\t                                    DUK__IVAL_FLAG_REQUIRE_TEMP /*flags*/);\n\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx,\n\t\t\t                                   &left->x2,\n\t\t\t                                   -1 /*forced_reg*/,\n\t\t\t                                   DUK__IVAL_FLAG_REQUIRE_TEMP | DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\n\t\t\t/* Evaluate RHS only when LHS is safe. */\n\n\t\t\tif (args_op == DUK_OP_NONE) {\n\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\t\t\t\trc_res = res->x1.regconst;\n\t\t\t} else {\n\t\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                DUK_OP_GETPROP | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                reg_temp,\n\t\t\t\t                reg_obj,\n\t\t\t\t                rc_key);\n\n\t\t\t\tduk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\t\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN && res->x1.t == DUK_ISPEC_REGCONST);\n\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                args_op | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                reg_temp,\n\t\t\t\t                reg_temp,\n\t\t\t\t                res->x1.regconst);\n\t\t\t\trc_res = reg_temp;\n\t\t\t}\n\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_obj,\n\t\t\t                rc_key,\n\t\t\t                rc_res);\n\n\t\t\tduk__ivalue_regconst(res, rc_res);\n\t\t} else {\n\t\t\t/* No support for lvalues returned from new or function call expressions.\n\t\t\t * However, these must NOT cause compile-time SyntaxErrors, but run-time\n\t\t\t * ReferenceErrors.  Both left and right sides of the assignment must be\n\t\t\t * evaluated before throwing a ReferenceError.  For instance:\n\t\t\t *\n\t\t\t *     f() = g();\n\t\t\t *\n\t\t\t * must result in f() being evaluated, then g() being evaluated, and\n\t\t\t * finally, a ReferenceError being thrown.  See E5 Section 11.13.1.\n\t\t\t */\n\n\t\t\tduk_regconst_t rc_res;\n\n\t\t\t/* First evaluate LHS fully to ensure all side effects are out. */\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, left);\n\n\t\t\t/* Then evaluate RHS fully (its value becomes the expression value too).\n\t\t\t * Technically we'd need the side effect safety check here too, but because\n\t\t\t * we always throw using INVLHS the result doesn't matter.\n\t\t\t */\n\t\t\trc_res = duk__expr_toregconst(comp_ctx, res, args_rbp /*rbp_flags*/);\n\n\t\t\tduk__emit_op_only(comp_ctx, DUK_OP_INVLHS);\n\n\t\t\tduk__ivalue_regconst(res, rc_res);\n\t\t}\n\n\t\treturn;\n\t}\n\n postincdec:\n\t{\n\t\t/*\n\t\t *  Post-increment/decrement will return the original value as its\n\t\t *  result value.  However, even that value will be coerced using\n\t\t *  ToNumber() which is quite awkward.  Specific bytecode opcodes\n\t\t *  are used to handle these semantics.\n\t\t *\n\t\t *  Note that post increment/decrement has a \"no LineTerminator here\"\n\t\t *  restriction.  This is handled by duk__expr_lbp(), which forcibly terminates\n\t\t *  the previous expression if a LineTerminator occurs before '++'/'--'.\n\t\t */\n\n\t\tduk_regconst_t reg_res;\n\t\tduk_small_uint_t args_op1 = (args >> 8) & 0xff;  /* DUK_OP_POSTINCR/DUK_OP_POSTDECR */\n\t\tduk_small_uint_t args_op2 = args >> 16;          /* DUK_OP_POSTINCP_RR/DUK_OP_POSTDECP_RR */\n\n\t\t/* Specific assumptions for opcode numbering. */\n\t\tDUK_ASSERT(DUK_OP_POSTINCR + 4 == DUK_OP_POSTINCV);\n\t\tDUK_ASSERT(DUK_OP_POSTDECR + 4 == DUK_OP_POSTDECV);\n\n\t\treg_res = DUK__ALLOCTEMP(comp_ctx);\n\n\t\tif (left->t == DUK_IVAL_VAR) {\n\t\t\tduk_hstring *h_varname;\n\t\t\tduk_regconst_t reg_varbind;\n\t\t\tduk_regconst_t rc_varname;\n\n\t\t\th_varname = duk_known_hstring(thr, left->x1.valstack_idx);\n\n\t\t\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\n\t\t\tduk_dup(thr, left->x1.valstack_idx);\n\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               args_op1,  /* e.g. DUK_OP_POSTINCR */\n\t\t\t\t               reg_res,\n\t\t\t\t               reg_varbind);\n\t\t\t} else {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               args_op1 + 4,  /* e.g. DUK_OP_POSTINCV */\n\t\t\t\t               reg_res,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"postincdec to '%!O' -> reg_varbind=%ld, rc_varname=%ld\",\n\t\t\t                     (duk_heaphdr *) h_varname, (long) reg_varbind, (long) rc_varname));\n\t\t} else if (left->t == DUK_IVAL_PROP) {\n\t\t\tduk_regconst_t reg_obj;  /* allocate to reg only (not const) */\n\t\t\tduk_regconst_t rc_key;\n\n\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &left->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &left->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                args_op2 | DUK__EMIT_FLAG_BC_REGCONST,  /* e.g. DUK_OP_POSTINCP */\n\t\t\t                reg_res,\n\t\t\t                reg_obj,\n\t\t\t                rc_key);\n\t\t} else {\n\t\t\t/* Technically return value is not needed because INVLHS will\n\t\t\t * unconditially throw a ReferenceError.  Coercion is necessary\n\t\t\t * for proper semantics (consider ToNumber() called for an object).\n\t\t\t * Use DUK_OP_UNP with a dummy register to get ToNumber().\n\t\t\t */\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, left, reg_res);\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_UNP,\n\t\t\t             reg_res);  /* for side effects, result ignored */\n\t\t\tduk__emit_op_only(comp_ctx,\n\t\t\t                  DUK_OP_INVLHS);\n\t\t}\n\n\t\tDUK__SETTEMP(comp_ctx, reg_res + 1);\n\t\tduk__ivalue_regconst(res, reg_res);\n\t\treturn;\n\t}\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_EXPRESSION);\n\tDUK_WO_NORETURN(return;);\n\n syntax_error_lvalue:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_LVALUE);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL duk_small_uint_t duk__expr_lbp(duk_compiler_ctx *comp_ctx) {\n\tduk_small_uint_t tok = comp_ctx->curr_token.t;\n\n\tDUK_ASSERT_DISABLE(tok >= DUK_TOK_MINVAL);  /* unsigned */\n\tDUK_ASSERT(tok <= DUK_TOK_MAXVAL);\n\tDUK_ASSERT(sizeof(duk__token_lbp) == DUK_TOK_MAXVAL + 1);\n\n\t/* XXX: integrate support for this into led() instead?\n\t * Similar issue as post-increment/post-decrement.\n\t */\n\n\t/* prevent duk__expr_led() by using a binding power less than anything valid */\n\tif (tok == DUK_TOK_IN && !comp_ctx->curr_func.allow_in) {\n\t\treturn 0;\n\t}\n\n\tif ((tok == DUK_TOK_DECREMENT || tok == DUK_TOK_INCREMENT) &&\n\t    (comp_ctx->curr_token.lineterm)) {\n\t\t/* '++' or '--' in a post-increment/decrement position,\n\t\t * and a LineTerminator occurs between the operator and\n\t\t * the preceding expression.  Force the previous expr\n\t\t * to terminate, in effect treating e.g. \"a,b\\n++\" as\n\t\t * \"a,b;++\" (= SyntaxError).\n\t\t */\n\t\treturn 0;\n\t}\n\n\treturn DUK__TOKEN_LBP_GET_BP(duk__token_lbp[tok]);  /* format is bit packed */\n}\n\n/*\n *  Expression parsing.\n *\n *  Upon entry to 'expr' and its variants, 'curr_tok' is assumed to be the\n *  first token of the expression.  Upon exit, 'curr_tok' will be the first\n *  token not part of the expression (e.g. semicolon terminating an expression\n *  statement).\n */\n\n#define DUK__EXPR_RBP_MASK           0xff\n#define DUK__EXPR_FLAG_REJECT_IN     (1 << 8)   /* reject 'in' token (used for for-in) */\n#define DUK__EXPR_FLAG_ALLOW_EMPTY   (1 << 9)   /* allow empty expression */\n#define DUK__EXPR_FLAG_REQUIRE_INIT  (1 << 10)  /* require initializer for var/const */\n\n/* main expression parser function */\nDUK_LOCAL void duk__expr(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_ivalue tmp_alloc;   /* 'res' is used for \"left\", and 'tmp' for \"right\" */\n\tduk_ivalue *tmp = &tmp_alloc;\n\tduk_small_uint_t rbp;\n\n\tDUK__RECURSION_INCREASE(comp_ctx, thr);\n\n\tduk_require_stack(thr, DUK__PARSE_EXPR_SLOTS);\n\n\t/* filter out flags from exprtop rbp_flags here to save space */\n\trbp = rbp_flags & DUK__EXPR_RBP_MASK;\n\n\tDUK_DDD(DUK_DDDPRINT(\"duk__expr(), rbp_flags=%ld, rbp=%ld, allow_in=%ld, paren_level=%ld\",\n\t                     (long) rbp_flags, (long) rbp, (long) comp_ctx->curr_func.allow_in,\n\t                     (long) comp_ctx->curr_func.paren_level));\n\n\tduk_memzero(&tmp_alloc, sizeof(tmp_alloc));\n\ttmp->x1.valstack_idx = duk_get_top(thr);\n\ttmp->x2.valstack_idx = tmp->x1.valstack_idx + 1;\n\tduk_push_undefined(thr);\n\tduk_push_undefined(thr);\n\n\t/* XXX: where to release temp regs in intermediate expressions?\n\t * e.g. 1+2+3 -> don't inflate temp register count when parsing this.\n\t * that particular expression temp regs can be forced here.\n\t */\n\n\t/* XXX: increase ctx->expr_tokens here for every consumed token\n\t * (this would be a nice statistic)?\n\t */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON || comp_ctx->curr_token.t == DUK_TOK_RPAREN) {\n\t\t/* XXX: possibly incorrect handling of empty expression */\n\t\tDUK_DDD(DUK_DDDPRINT(\"empty expression\"));\n\t\tif (!(rbp_flags & DUK__EXPR_FLAG_ALLOW_EMPTY)) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EMPTY_EXPR_NOT_ALLOWED);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tduk_push_undefined(thr);\n\t\tduk__ivalue_plain_fromstack(comp_ctx, res);\n\t\tgoto cleanup;\n\t}\n\n\tduk__advance(comp_ctx);\n\tduk__expr_nud(comp_ctx, res);  /* reuse 'res' as 'left' */\n\twhile (rbp < duk__expr_lbp(comp_ctx)) {\n\t\tduk__advance(comp_ctx);\n\t\tduk__expr_led(comp_ctx, res, tmp);\n\t\tduk__copy_ivalue(comp_ctx, tmp, res);  /* tmp -> res */\n\t}\n\n cleanup:\n\t/* final result is already in 'res' */\n\n\tduk_pop_2(thr);\n\n\tDUK__RECURSION_DECREASE(comp_ctx, thr);\n}\n\nDUK_LOCAL void duk__exprtop(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\n\t/* Note: these variables must reside in 'curr_func' instead of the global\n\t * context: when parsing function expressions, expression parsing is nested.\n\t */\n\tcomp_ctx->curr_func.nud_count = 0;\n\tcomp_ctx->curr_func.led_count = 0;\n\tcomp_ctx->curr_func.paren_level = 0;\n\tcomp_ctx->curr_func.expr_lhs = 1;\n\tcomp_ctx->curr_func.allow_in = (rbp_flags & DUK__EXPR_FLAG_REJECT_IN ? 0 : 1);\n\n\tduk__expr(comp_ctx, res, rbp_flags);\n\n\tif (!(rbp_flags & DUK__EXPR_FLAG_ALLOW_EMPTY) && duk__expr_is_empty(comp_ctx)) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EMPTY_EXPR_NOT_ALLOWED);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n}\n\n/* A bunch of helpers (for size optimization) that combine duk__expr()/duk__exprtop()\n * and result conversions.\n *\n * Each helper needs at least 2-3 calls to make it worth while to wrap.\n */\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__expr_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toreg(comp_ctx, res);\n}\n#endif\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__expr_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_totemp(comp_ctx, res);\n}\n#endif\n\nDUK_LOCAL void duk__expr_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\tduk__expr(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toforcedreg(comp_ctx, res, forced_reg);\n}\n\nDUK_LOCAL duk_regconst_t duk__expr_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toregconst(comp_ctx, res);\n}\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__expr_totempconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_totempconst(comp_ctx, res);\n}\n#endif\n\nDUK_LOCAL void duk__expr_toplain(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toplain(comp_ctx, res);\n}\n\nDUK_LOCAL void duk__expr_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__expr(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toplain_ignore(comp_ctx, res);\n}\n\nDUK_LOCAL duk_regconst_t duk__exprtop_toreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toreg(comp_ctx, res);\n}\n\n#if 0  /* unused */\nDUK_LOCAL duk_regconst_t duk__exprtop_totemp(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_totemp(comp_ctx, res);\n}\n#endif\n\nDUK_LOCAL void duk__exprtop_toforcedreg(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags, duk_regconst_t forced_reg) {\n\tDUK_ASSERT(forced_reg >= 0);\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toforcedreg(comp_ctx, res, forced_reg);\n}\n\nDUK_LOCAL duk_regconst_t duk__exprtop_toregconst(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\treturn duk__ivalue_toregconst(comp_ctx, res);\n}\n\n#if 0  /* unused */\nDUK_LOCAL void duk__exprtop_toplain_ignore(duk_compiler_ctx *comp_ctx, duk_ivalue *res, int rbp_flags) {\n\tduk__exprtop(comp_ctx, res, rbp_flags);\n\tduk__ivalue_toplain_ignore(comp_ctx, res);\n}\n#endif\n\n/*\n *  Parse an individual source element (top level statement) or a statement.\n *\n *  Handles labeled statements automatically (peeling away labels before\n *  parsing an expression that follows the label(s)).\n *\n *  Upon entry, 'curr_tok' contains the first token of the statement (parsed\n *  in \"allow regexp literal\" mode).  Upon exit, 'curr_tok' contains the first\n *  token following the statement (if the statement has a terminator, this is\n *  the token after the terminator).\n */\n\n#define DUK__HAS_VAL                  (1 << 0)  /* stmt has non-empty value */\n#define DUK__HAS_TERM                 (1 << 1)  /* stmt has explicit/implicit semicolon terminator */\n#define DUK__ALLOW_AUTO_SEMI_ALWAYS   (1 << 2)  /* allow automatic semicolon even without lineterm (compatibility) */\n#define DUK__STILL_PROLOGUE           (1 << 3)  /* statement does not terminate directive prologue */\n#define DUK__IS_TERMINAL              (1 << 4)  /* statement is guaranteed to be terminal (control doesn't flow to next statement) */\n\n/* Parse a single variable declaration (e.g. \"i\" or \"i=10\").  A leading 'var'\n * has already been eaten.  These is no return value in 'res', it is used only\n * as a temporary.\n *\n * When called from 'for-in' statement parser, the initializer expression must\n * not allow the 'in' token.  The caller supply additional expression parsing\n * flags (like DUK__EXPR_FLAG_REJECT_IN) in 'expr_flags'.\n *\n * Finally, out_rc_varname and out_reg_varbind are updated to reflect where\n * the identifier is bound:\n *\n *    If register bound:      out_reg_varbind >= 0, out_rc_varname == 0 (ignore)\n *    If not register bound:  out_reg_varbind < 0, out_rc_varname >= 0\n *\n * These allow the caller to use the variable for further assignment, e.g.\n * as is done in 'for-in' parsing.\n */\n\nDUK_LOCAL void duk__parse_var_decl(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags, duk_regconst_t *out_reg_varbind, duk_regconst_t *out_rc_varname) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hstring *h_varname;\n\tduk_regconst_t reg_varbind;\n\tduk_regconst_t rc_varname;\n\n\t/* assume 'var' has been eaten */\n\n\t/* Note: Identifier rejects reserved words */\n\tif (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) {\n\t\tgoto syntax_error;\n\t}\n\th_varname = comp_ctx->curr_token.str1;\n\n\tDUK_ASSERT(h_varname != NULL);\n\n\t/* strict mode restrictions (E5 Section 12.2.1) */\n\tif (duk__hstring_is_eval_or_arguments_in_strict_mode(comp_ctx, h_varname)) {\n\t\tgoto syntax_error;\n\t}\n\n\t/* register declarations in first pass */\n\tif (comp_ctx->curr_func.in_scanning) {\n\t\tduk_uarridx_t n;\n\t\tDUK_DDD(DUK_DDDPRINT(\"register variable declaration %!O in pass 1\",\n\t\t                     (duk_heaphdr *) h_varname));\n\t\tn = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.decls_idx);\n\t\tduk_push_hstring(thr, h_varname);\n\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n);\n\t\tduk_push_int(thr, DUK_DECL_TYPE_VAR + (0 << 8));\n\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n + 1);\n\t}\n\n\tduk_push_hstring(thr, h_varname);  /* push before advancing to keep reachable */\n\n\t/* register binding lookup is based on varmap (even in first pass) */\n\tduk_dup_top(thr);\n\t(void) duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname);\n\n\tduk__advance(comp_ctx);  /* eat identifier */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_EQUALSIGN) {\n\t\tduk__advance(comp_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"vardecl, assign to '%!O' -> reg_varbind=%ld, rc_varname=%ld\",\n\t\t                     (duk_heaphdr *) h_varname, (long) reg_varbind, (long) rc_varname));\n\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_COMMA | expr_flags /*rbp_flags*/);  /* AssignmentExpression */\n\n\t\tif (reg_varbind >= 0) {\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_varbind);\n\t\t} else {\n\t\t\tduk_regconst_t reg_val;\n\t\t\treg_val = duk__ivalue_toreg(comp_ctx, res);\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t               reg_val,\n\t\t\t               rc_varname);\n\t\t}\n\t} else {\n\t\tif (expr_flags & DUK__EXPR_FLAG_REQUIRE_INIT) {\n\t\t\t/* Used for minimal 'const': initializer required. */\n\t\t\tgoto syntax_error;\n\t\t}\n\t}\n\n\tduk_pop(thr);  /* pop varname */\n\n\t*out_rc_varname = rc_varname;\n\t*out_reg_varbind = reg_varbind;\n\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_VAR_DECLARATION);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_var_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_small_uint_t expr_flags) {\n\tduk_regconst_t reg_varbind;\n\tduk_regconst_t rc_varname;\n\n\tduk__advance(comp_ctx);  /* eat 'var' */\n\n\tfor (;;) {\n\t\t/* rc_varname and reg_varbind are ignored here */\n\t\tduk__parse_var_decl(comp_ctx, res, 0 | expr_flags, &reg_varbind, &rc_varname);\n\n\t\tif (comp_ctx->curr_token.t != DUK_TOK_COMMA) {\n\t\t\tbreak;\n\t\t}\n\t\tduk__advance(comp_ctx);\n\t}\n}\n\nDUK_LOCAL void duk__parse_for_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_int_t pc_v34_lhs;         /* start variant 3/4 left-hand-side code (L1 in doc/compiler.rst example) */\n\tduk_regconst_t temp_reset;    /* knock back \"next temp\" to this whenever possible */\n\tduk_regconst_t reg_temps;     /* preallocated temporaries (2) for variants 3 and 4 */\n\n\tDUK_DDD(DUK_DDDPRINT(\"start parsing a for/for-in statement\"));\n\n\t/* Two temporaries are preallocated here for variants 3 and 4 which need\n\t * registers which are never clobbered by expressions in the loop\n\t * (concretely: for the enumerator object and the next enumerated value).\n\t * Variants 1 and 2 \"release\" these temps.\n\t */\n\n\treg_temps = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\ttemp_reset = DUK__GETTEMP(comp_ctx);\n\n\t/*\n\t *  For/for-in main variants are:\n\t *\n\t *    1. for (ExpressionNoIn_opt; Expression_opt; Expression_opt) Statement\n\t *    2. for (var VariableDeclarationNoIn; Expression_opt; Expression_opt) Statement\n\t *    3. for (LeftHandSideExpression in Expression) Statement\n\t *    4. for (var VariableDeclarationNoIn in Expression) Statement\n\t *\n\t *  Parsing these without arbitrary lookahead or backtracking is relatively\n\t *  tricky but we manage to do so for now.\n\t *\n\t *  See doc/compiler.rst for a detailed discussion of control flow\n\t *  issues, evaluation order issues, etc.\n\t */\n\n\tduk__advance(comp_ctx);  /* eat 'for' */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\tDUK_DDD(DUK_DDDPRINT(\"detecting for/for-in loop variant, pc=%ld\", (long) duk__get_current_pc(comp_ctx)));\n\n\t/* a label site has been emitted by duk__parse_stmt() automatically\n\t * (it will also emit the ENDLABEL).\n\t */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_VAR) {\n\t\t/*\n\t\t *  Variant 2 or 4\n\t\t */\n\n\t\tduk_regconst_t reg_varbind;  /* variable binding register if register-bound (otherwise < 0) */\n\t\tduk_regconst_t rc_varname;   /* variable name reg/const, if variable not register-bound */\n\n\t\tduk__advance(comp_ctx);  /* eat 'var' */\n\t\tduk__parse_var_decl(comp_ctx, res, DUK__EXPR_FLAG_REJECT_IN, &reg_varbind, &rc_varname);\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_IN) {\n\t\t\t/*\n\t\t\t *  Variant 4\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 4: for (var VariableDeclarationNoIn in Expression) Statement\"));\n\t\t\tpc_v34_lhs = duk__get_current_pc(comp_ctx);  /* jump is inserted here */\n\t\t\tif (reg_varbind >= 0) {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_LDREG,\n\t\t\t\t               reg_varbind,\n\t\t\t\t               reg_temps + 0);\n\t\t\t} else {\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t               reg_temps + 0,\n\t\t\t\t               rc_varname);\n\t\t\t}\n\t\t\tgoto parse_3_or_4;\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Variant 2\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 2: for (var VariableDeclarationNoIn; Expression_opt; Expression_opt) Statement\"));\n\t\t\tfor (;;) {\n\t\t\t\t/* more initializers */\n\t\t\t\tif (comp_ctx->curr_token.t != DUK_TOK_COMMA) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"variant 2 has another variable initializer\"));\n\n\t\t\t\tduk__advance(comp_ctx);  /* eat comma */\n\t\t\t\tduk__parse_var_decl(comp_ctx, res, DUK__EXPR_FLAG_REJECT_IN, &reg_varbind, &rc_varname);\n\t\t\t}\n\t\t\tgoto parse_1_or_2;\n\t\t}\n\t} else {\n\t\t/*\n\t\t *  Variant 1 or 3\n\t\t */\n\n\t\tpc_v34_lhs = duk__get_current_pc(comp_ctx);  /* jump is inserted here (variant 3) */\n\n\t\t/* Note that duk__exprtop() here can clobber any reg above current temp_next,\n\t\t * so any loop variables (e.g. enumerator) must be \"preallocated\".\n\t\t */\n\n\t\t/* don't coerce yet to a plain value (variant 3 needs special handling) */\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR | DUK__EXPR_FLAG_REJECT_IN | DUK__EXPR_FLAG_ALLOW_EMPTY /*rbp_flags*/);  /* Expression */\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_IN) {\n\t\t\t/*\n\t\t\t *  Variant 3\n\t\t\t */\n\n\t\t\t/* XXX: need to determine LHS type, and check that it is LHS compatible */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 3: for (LeftHandSideExpression in Expression) Statement\"));\n\t\t\tif (duk__expr_is_empty(comp_ctx)) {\n\t\t\t\tgoto syntax_error;  /* LeftHandSideExpression does not allow empty expression */\n\t\t\t}\n\n\t\t\tif (res->t == DUK_IVAL_VAR) {\n\t\t\t\tduk_regconst_t reg_varbind;\n\t\t\t\tduk_regconst_t rc_varname;\n\n\t\t\t\tduk_dup(thr, res->x1.valstack_idx);\n\t\t\t\tif (duk__lookup_lhs(comp_ctx, &reg_varbind, &rc_varname)) {\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_LDREG,\n\t\t\t\t\t               reg_varbind,\n\t\t\t\t\t               reg_temps + 0);\n\t\t\t\t} else {\n\t\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t\t\t\t               reg_temps + 0,\n\t\t\t\t\t               rc_varname);\n\t\t\t\t}\n\t\t\t} else if (res->t == DUK_IVAL_PROP) {\n\t\t\t\t/* Don't allow a constant for the object (even for a number etc), as\n\t\t\t\t * it goes into the 'A' field of the opcode.\n\t\t\t\t */\n\t\t\t\tduk_regconst_t reg_obj;\n\t\t\t\tduk_regconst_t rc_key;\n\t\t\t\treg_obj = duk__ispec_toregconst_raw(comp_ctx, &res->x1, -1 /*forced_reg*/, 0 /*flags*/);  /* don't allow const */\n\t\t\t\trc_key = duk__ispec_toregconst_raw(comp_ctx, &res->x2, -1 /*forced_reg*/, DUK__IVAL_FLAG_ALLOW_CONST /*flags*/);\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                DUK_OP_PUTPROP | DUK__EMIT_FLAG_A_IS_SOURCE | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                reg_obj,\n\t\t\t\t                rc_key,\n\t\t\t\t                reg_temps + 0);\n\t\t\t} else {\n\t\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);  /* just in case */\n\t\t\t\tduk__emit_op_only(comp_ctx,\n\t\t\t\t                  DUK_OP_INVLHS);\n\t\t\t}\n\t\t\tgoto parse_3_or_4;\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Variant 1\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected for variant 1: for (ExpressionNoIn_opt; Expression_opt; Expression_opt) Statement\"));\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);\n\t\t\tgoto parse_1_or_2;\n\t\t}\n\t}\n\n parse_1_or_2:\n\t/*\n\t *  Parse variant 1 or 2.  The first part expression (which differs\n\t *  in the variants) has already been parsed and its code emitted.\n\t *\n\t *  reg_temps + 0: unused\n\t *  reg_temps + 1: unused\n\t */\n\t{\n\t\tduk_regconst_t rc_cond;\n\t\tduk_int_t pc_l1, pc_l2, pc_l3, pc_l4;\n\t\tduk_int_t pc_jumpto_l3, pc_jumpto_l4;\n\t\tduk_bool_t expr_c_empty;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"shared code for parsing variants 1 and 2\"));\n\n\t\t/* \"release\" preallocated temps since we won't need them */\n\t\ttemp_reset = reg_temps + 0;\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_SEMICOLON);\n\n\t\tpc_l1 = duk__get_current_pc(comp_ctx);\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR | DUK__EXPR_FLAG_ALLOW_EMPTY /*rbp_flags*/);  /* Expression_opt */\n\t\tif (duk__expr_is_empty(comp_ctx)) {\n\t\t\t/* no need to coerce */\n\t\t\tpc_jumpto_l3 = duk__emit_jump_empty(comp_ctx);  /* to body */\n\t\t\tpc_jumpto_l4 = -1;  /* omitted */\n\t\t} else {\n\t\t\trc_cond = duk__ivalue_toregconst(comp_ctx, res);\n\t\t\tduk__emit_if_false_skip(comp_ctx, rc_cond);\n\t\t\tpc_jumpto_l3 = duk__emit_jump_empty(comp_ctx);  /* to body */\n\t\t\tpc_jumpto_l4 = duk__emit_jump_empty(comp_ctx);  /* to exit */\n\t\t}\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_SEMICOLON);\n\n\t\tpc_l2 = duk__get_current_pc(comp_ctx);\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR | DUK__EXPR_FLAG_ALLOW_EMPTY /*rbp_flags*/);  /* Expression_opt */\n\t\tif (duk__expr_is_empty(comp_ctx)) {\n\t\t\t/* no need to coerce */\n\t\t\texpr_c_empty = 1;\n\t\t\t/* JUMP L1 omitted */\n\t\t} else {\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);\n\t\t\texpr_c_empty = 0;\n\t\t\tduk__emit_jump(comp_ctx, pc_l1);\n\t\t}\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\t\tpc_l3 = duk__get_current_pc(comp_ctx);\n\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\t\tif (expr_c_empty) {\n\t\t\tduk__emit_jump(comp_ctx, pc_l1);\n\t\t} else {\n\t\t\tduk__emit_jump(comp_ctx, pc_l2);\n\t\t}\n\t\t/* temp reset is not necessary after duk__parse_stmt(), which already does it */\n\n\t\tpc_l4 = duk__get_current_pc(comp_ctx);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"patching jumps: jumpto_l3: %ld->%ld, jumpto_l4: %ld->%ld, \"\n\t\t                     \"break: %ld->%ld, continue: %ld->%ld\",\n\t\t\t             (long) pc_jumpto_l3, (long) pc_l3, (long) pc_jumpto_l4, (long) pc_l4,\n\t\t                     (long) (pc_label_site + 1), (long) pc_l4, (long) (pc_label_site + 2), (long) pc_l2));\n\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l3, pc_l3);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l4, pc_l4);\n\t\tduk__patch_jump(comp_ctx,\n\t\t                pc_label_site + 1,\n\t\t                pc_l4);                         /* break jump */\n\t\tduk__patch_jump(comp_ctx,\n\t\t                pc_label_site + 2,\n\t\t                expr_c_empty ? pc_l1 : pc_l2);  /* continue jump */\n\t}\n\tgoto finished;\n\n parse_3_or_4:\n\t/*\n\t *  Parse variant 3 or 4.\n\t *\n\t *  For variant 3 (e.g. \"for (A in C) D;\") the code for A (except the\n\t *  final property/variable write) has already been emitted.  The first\n\t *  instruction of that code is at pc_v34_lhs; a JUMP needs to be inserted\n\t *  there to satisfy control flow needs.\n\t *\n\t *  For variant 4, if the variable declaration had an initializer\n\t *  (e.g. \"for (var A = B in C) D;\") the code for the assignment\n\t *  (B) has already been emitted.\n\t *\n\t *  Variables set before entering here:\n\t *\n\t *    pc_v34_lhs:    insert a \"JUMP L2\" here (see doc/compiler.rst example).\n\t *    reg_temps + 0: iteration target value (written to LHS)\n\t *    reg_temps + 1: enumerator object\n\t */\n\t{\n\t\tduk_int_t pc_l1, pc_l2, pc_l3, pc_l4, pc_l5;\n\t\tduk_int_t pc_jumpto_l2, pc_jumpto_l3, pc_jumpto_l4, pc_jumpto_l5;\n\t\tduk_regconst_t reg_target;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"shared code for parsing variants 3 and 4, pc_v34_lhs=%ld\", (long) pc_v34_lhs));\n\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\t/* First we need to insert a jump in the middle of previously\n\t\t * emitted code to get the control flow right.  No jumps can\n\t\t * cross the position where the jump is inserted.  See doc/compiler.rst\n\t\t * for discussion on the intricacies of control flow and side effects\n\t\t * for variants 3 and 4.\n\t\t */\n\n\t\tduk__insert_jump_entry(comp_ctx, pc_v34_lhs);\n\t\tpc_jumpto_l2 = pc_v34_lhs;  /* inserted jump */\n\t\tpc_l1 = pc_v34_lhs + 1;     /* +1, right after inserted jump */\n\n\t\t/* The code for writing reg_temps + 0 to the left hand side has already\n\t\t * been emitted.\n\t\t */\n\n\t\tpc_jumpto_l3 = duk__emit_jump_empty(comp_ctx);  /* -> loop body */\n\n\t\tduk__advance(comp_ctx);  /* eat 'in' */\n\n\t\t/* Parse enumeration target and initialize enumerator.  For 'null' and 'undefined',\n\t\t * INITENUM will creates a 'null' enumerator which works like an empty enumerator\n\t\t * (E5 Section 12.6.4, step 3).  Note that INITENUM requires the value to be in a\n\t\t * register (constant not allowed).\n\t\t */\n\n\t\tpc_l2 = duk__get_current_pc(comp_ctx);\n\t\treg_target = duk__exprtop_toreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);  /* Expression */\n\t\tduk__emit_b_c(comp_ctx,\n\t\t              DUK_OP_INITENUM | DUK__EMIT_FLAG_B_IS_TARGET,\n\t\t              reg_temps + 1,\n\t\t              reg_target);\n\t\tpc_jumpto_l4 = duk__emit_jump_empty(comp_ctx);\n\t\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\t\tpc_l3 = duk__get_current_pc(comp_ctx);\n\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\t\t/* temp reset is not necessary after duk__parse_stmt(), which already does it */\n\n\t\t/* NEXTENUM needs a jump slot right after the main opcode.\n\t\t * We need the code emitter to reserve the slot: if there's\n\t\t * target shuffling, the target shuffle opcodes must happen\n\t\t * after the jump slot (for NEXTENUM the shuffle opcodes are\n\t\t * not needed if the enum is finished).\n\t\t */\n\t\tpc_l4 = duk__get_current_pc(comp_ctx);\n\t\tduk__emit_b_c(comp_ctx,\n\t\t              DUK_OP_NEXTENUM | DUK__EMIT_FLAG_B_IS_TARGET | DUK__EMIT_FLAG_RESERVE_JUMPSLOT,\n\t\t              reg_temps + 0,\n\t\t              reg_temps + 1);\n\t\tpc_jumpto_l5 = comp_ctx->emit_jumpslot_pc;  /* NEXTENUM jump slot: executed when enum finished */\n\t\tduk__emit_jump(comp_ctx, pc_l1);  /* jump to next loop, using reg_v34_iter as iterated value */\n\n\t\tpc_l5 = duk__get_current_pc(comp_ctx);\n\n\t\t/* XXX: since the enumerator may be a memory expensive object,\n\t\t * perhaps clear it explicitly here?  If so, break jump must\n\t\t * go through this clearing operation.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"patching jumps: jumpto_l2: %ld->%ld, jumpto_l3: %ld->%ld, \"\n\t\t                     \"jumpto_l4: %ld->%ld, jumpto_l5: %ld->%ld, \"\n\t\t                     \"break: %ld->%ld, continue: %ld->%ld\",\n\t\t\t             (long) pc_jumpto_l2, (long) pc_l2, (long) pc_jumpto_l3, (long) pc_l3,\n\t\t\t             (long) pc_jumpto_l4, (long) pc_l4, (long) pc_jumpto_l5, (long) pc_l5,\n\t\t                     (long) (pc_label_site + 1), (long) pc_l5, (long) (pc_label_site + 2), (long) pc_l4));\n\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l2, pc_l2);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l3, pc_l3);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l4, pc_l4);\n\t\tduk__patch_jump(comp_ctx, pc_jumpto_l5, pc_l5);\n\t\tduk__patch_jump(comp_ctx, pc_label_site + 1, pc_l5);  /* break jump */\n\t\tduk__patch_jump(comp_ctx, pc_label_site + 2, pc_l4);  /* continue jump */\n\t}\n\tgoto finished;\n\n finished:\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing a for/for-in statement\"));\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_FOR);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_switch_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t temp_at_loop;\n\tduk_regconst_t rc_switch;    /* reg/const for switch value */\n\tduk_regconst_t rc_case;      /* reg/const for case value */\n\tduk_regconst_t reg_temp;     /* general temp register */\n\tduk_int_t pc_prevcase = -1;\n\tduk_int_t pc_prevstmt = -1;\n\tduk_int_t pc_default = -1;   /* -1 == not set, -2 == pending (next statement list) */\n\n\t/* Note: negative pc values are ignored when patching jumps, so no explicit checks needed */\n\n\t/*\n\t *  Switch is pretty complicated because of several conflicting concerns:\n\t *\n\t *    - Want to generate code without an intermediate representation,\n\t *      i.e., in one go\n\t *\n\t *    - Case selectors are expressions, not values, and may thus e.g. throw\n\t *      exceptions (which causes evaluation order concerns)\n\t *\n\t *    - Evaluation semantics of case selectors and default clause need to be\n\t *      carefully implemented to provide correct behavior even with case value\n\t *      side effects\n\t *\n\t *    - Fall through case and default clauses; avoiding dead JUMPs if case\n\t *      ends with an unconditional jump (a break or a continue)\n\t *\n\t *    - The same case value may occur multiple times, but evaluation rules\n\t *      only process the first match before switching to a \"propagation\" mode\n\t *      where case values are no longer evaluated\n\t *\n\t *  See E5 Section 12.11.  Also see doc/compiler.rst for compilation\n\t *  discussion.\n\t */\n\n\tduk__advance(comp_ctx);\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\trc_switch = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* RegExp mode does not matter. */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\n\tDUK_DDD(DUK_DDDPRINT(\"switch value in register %ld\", (long) rc_switch));\n\n\ttemp_at_loop = DUK__GETTEMP(comp_ctx);\n\n\tfor (;;) {\n\t\tduk_int_t num_stmts;\n\t\tduk_small_uint_t tok;\n\n\t\t/* sufficient for keeping temp reg numbers in check */\n\t\tDUK__SETTEMP(comp_ctx, temp_at_loop);\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\tbreak;\n\t\t}\n\n\t\t/*\n\t\t *  Parse a case or default clause.\n\t\t */\n\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_CASE) {\n\t\t\t/*\n\t\t\t *  Case clause.\n\t\t\t *\n\t\t\t *  Note: cannot use reg_case as a temp register (for SEQ target)\n\t\t\t *  because it may be a constant.\n\t\t\t */\n\n\t\t\tduk__patch_jump_here(comp_ctx, pc_prevcase);  /* chain jumps for case\n\t\t\t                                               * evaluation and checking\n\t\t\t                                               */\n\n\t\t\tduk__advance(comp_ctx);\n\t\t\trc_case = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\n\t\t\treg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_SEQ | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                reg_temp,\n\t\t\t                rc_switch,\n\t\t\t                rc_case);\n\t\t\tduk__emit_if_true_skip(comp_ctx, reg_temp);\n\n\t\t\t/* jump to next case clause */\n\t\t\tpc_prevcase = duk__emit_jump_empty(comp_ctx);  /* no match, next case */\n\n\t\t\t/* statements go here (if any) on next loop */\n\t\t} else if (comp_ctx->curr_token.t == DUK_TOK_DEFAULT) {\n\t\t\t/*\n\t\t\t *  Default clause.\n\t\t\t */\n\n\t\t\tif (pc_default >= 0) {\n\t\t\t\tgoto syntax_error;\n\t\t\t}\n\t\t\tduk__advance(comp_ctx);\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COLON);\n\n\t\t\t/* Fix for https://github.com/svaarala/duktape/issues/155:\n\t\t\t * If 'default' is first clause (detected by pc_prevcase < 0)\n\t\t\t * we need to ensure we stay in the matching chain.\n\t\t\t */\n\t\t\tif (pc_prevcase < 0) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"default clause is first, emit prevcase jump\"));\n\t\t\t\tpc_prevcase = duk__emit_jump_empty(comp_ctx);\n\t\t\t}\n\n\t\t\t/* default clause matches next statement list (if any) */\n\t\t\tpc_default = -2;\n\t\t} else {\n\t\t\t/* Code is not accepted before the first case/default clause */\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\t/*\n\t\t *  Parse code after the clause.  Possible terminators are\n\t\t *  'case', 'default', and '}'.\n\t\t *\n\t\t *  Note that there may be no code at all, not even an empty statement,\n\t\t *  between case clauses.  This must be handled just like an empty statement\n\t\t *  (omitting seemingly pointless JUMPs), to avoid situations like\n\t\t *  test-bug-case-fallthrough.js.\n\t\t */\n\n\t\tnum_stmts = 0;\n\t\tif (pc_default == -2) {\n\t\t\tpc_default = duk__get_current_pc(comp_ctx);\n\t\t}\n\n\t\t/* Note: this is correct even for default clause statements:\n\t\t * they participate in 'fall-through' behavior even if the\n\t\t * default clause is in the middle.\n\t\t */\n\t\tduk__patch_jump_here(comp_ctx, pc_prevstmt);  /* chain jumps for 'fall-through'\n\t\t                                               * after a case matches.\n\t\t                                               */\n\n\t\tfor (;;) {\n\t\t\ttok = comp_ctx->curr_token.t;\n\t\t\tif (tok == DUK_TOK_CASE || tok == DUK_TOK_DEFAULT ||\n\t\t\t    tok == DUK_TOK_RCURLY) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tnum_stmts++;\n\t\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\t\t}\n\n\t\t/* fall-through jump to next code of next case (backpatched) */\n\t\tpc_prevstmt = duk__emit_jump_empty(comp_ctx);\n\n\t\t/* XXX: would be nice to omit this jump when the jump is not\n\t\t * reachable, at least in the obvious cases (such as the case\n\t\t * ending with a 'break'.\n\t\t *\n\t\t * Perhaps duk__parse_stmt() could provide some info on whether\n\t\t * the statement is a \"dead end\"?\n\t\t *\n\t\t * If implemented, just set pc_prevstmt to -1 when not needed.\n\t\t */\n\t}\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RCURLY);\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance(comp_ctx);  /* Allow RegExp as part of next stmt. */\n\n\t/* default case control flow patchup; note that if pc_prevcase < 0\n\t * (i.e. no case clauses), control enters default case automatically.\n\t */\n\tif (pc_default >= 0) {\n\t\t/* default case exists: go there if no case matches */\n\t\tduk__patch_jump(comp_ctx, pc_prevcase, pc_default);\n\t} else {\n\t\t/* default case does not exist, or no statements present\n\t\t * after default case: finish case evaluation\n\t\t */\n\t\tduk__patch_jump_here(comp_ctx, pc_prevcase);\n\t}\n\n\t/* fall-through control flow patchup; note that pc_prevstmt may be\n\t * < 0 (i.e. no case clauses), in which case this is a no-op.\n\t */\n\tduk__patch_jump_here(comp_ctx, pc_prevstmt);\n\n\t/* continue jump not patched, an INVALID opcode remains there */\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 1);  /* break jump */\n\n\t/* Note: 'fast' breaks will jump to pc_label_site + 1, which will\n\t * then jump here.  The double jump will be eliminated by a\n\t * peephole pass, resulting in an optimal jump here.  The label\n\t * site jumps will remain in bytecode and will waste code size.\n\t */\n\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_SWITCH);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_if_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_regconst_t temp_reset;\n\tduk_regconst_t rc_cond;\n\tduk_int_t pc_jump_false;\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin parsing if statement\"));\n\n\ttemp_reset = DUK__GETTEMP(comp_ctx);\n\n\tduk__advance(comp_ctx);  /* eat 'if' */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\trc_cond = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_if_true_skip(comp_ctx, rc_cond);\n\tpc_jump_false = duk__emit_jump_empty(comp_ctx);  /* jump to end or else part */\n\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\n\t/* The 'else' ambiguity is resolved by 'else' binding to the innermost\n\t * construct, so greedy matching is correct here.\n\t */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_ELSE) {\n\t\tduk_int_t pc_jump_end;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"if has else part\"));\n\n\t\tduk__advance(comp_ctx);\n\n\t\tpc_jump_end = duk__emit_jump_empty(comp_ctx);  /* jump from true part to end */\n\t\tduk__patch_jump_here(comp_ctx, pc_jump_false);\n\n\t\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\n\t\tduk__patch_jump_here(comp_ctx, pc_jump_end);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"if does not have else part\"));\n\n\t\tduk__patch_jump_here(comp_ctx, pc_jump_false);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing if statement\"));\n}\n\nDUK_LOCAL void duk__parse_do_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_regconst_t rc_cond;\n\tduk_int_t pc_start;\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin parsing do statement\"));\n\n\tduk__advance(comp_ctx);  /* Eat 'do'; allow RegExp as part of next stmt. */\n\n\tpc_start = duk__get_current_pc(comp_ctx);\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 2);  /* continue jump */\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_WHILE);\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\trc_cond = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_if_false_skip(comp_ctx, rc_cond);\n\tduk__emit_jump(comp_ctx, pc_start);\n\t/* no need to reset temps, as we're finished emitting code */\n\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;  /* Allow RegExp as part of next stmt. */\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);\n\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 1);  /* break jump */\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing do statement\"));\n}\n\nDUK_LOCAL void duk__parse_while_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_int_t pc_label_site) {\n\tduk_regconst_t temp_reset;\n\tduk_regconst_t rc_cond;\n\tduk_int_t pc_start;\n\tduk_int_t pc_jump_false;\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin parsing while statement\"));\n\n\ttemp_reset = DUK__GETTEMP(comp_ctx);\n\n\tduk__advance(comp_ctx);  /* eat 'while' */\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\tpc_start = duk__get_current_pc(comp_ctx);\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 2);  /* continue jump */\n\n\trc_cond = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_if_true_skip(comp_ctx, rc_cond);\n\tpc_jump_false = duk__emit_jump_empty(comp_ctx);\n\tDUK__SETTEMP(comp_ctx, temp_reset);\n\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\tduk__emit_jump(comp_ctx, pc_start);\n\n\tduk__patch_jump_here(comp_ctx, pc_jump_false);\n\tduk__patch_jump_here(comp_ctx, pc_label_site + 1);  /* break jump */\n\n\tDUK_DDD(DUK_DDDPRINT(\"end parsing while statement\"));\n}\n\nDUK_LOCAL void duk__parse_break_or_continue_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t is_break = (comp_ctx->curr_token.t == DUK_TOK_BREAK);\n\tduk_int_t label_id;\n\tduk_int_t label_catch_depth;\n\tduk_int_t label_pc;  /* points to LABEL; pc+1 = jump site for break; pc+2 = jump site for continue */\n\tduk_bool_t label_is_closest;\n\n\tDUK_UNREF(res);\n\n\tduk__advance(comp_ctx);  /* eat 'break' or 'continue' */\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON ||  /* explicit semi follows */\n\t    comp_ctx->curr_token.lineterm ||                /* automatic semi will be inserted */\n\t    comp_ctx->curr_token.allow_auto_semi) {         /* automatic semi will be inserted */\n\t\t/* break/continue without label */\n\n\t\tduk__lookup_active_label(comp_ctx, DUK_HTHREAD_STRING_EMPTY_STRING(thr), is_break, &label_id, &label_catch_depth, &label_pc, &label_is_closest);\n\t} else if (comp_ctx->curr_token.t == DUK_TOK_IDENTIFIER) {\n\t\t/* break/continue with label (label cannot be a reserved word, production is 'Identifier' */\n\t\tDUK_ASSERT(comp_ctx->curr_token.str1 != NULL);\n\t\tduk__lookup_active_label(comp_ctx, comp_ctx->curr_token.str1, is_break, &label_id, &label_catch_depth, &label_pc, &label_is_closest);\n\t\tduk__advance(comp_ctx);\n\t} else {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_BREAK_CONT_LABEL);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* Use a fast break/continue when possible.  A fast break/continue is\n\t * just a jump to the LABEL break/continue jump slot, which then jumps\n\t * to an appropriate place (for break, going through ENDLABEL correctly).\n\t * The peephole optimizer will optimize the jump to a direct one.\n\t */\n\n\tif (label_catch_depth == comp_ctx->curr_func.catch_depth &&\n\t    label_is_closest) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"break/continue: is_break=%ld, label_id=%ld, label_is_closest=%ld, \"\n\t\t                     \"label_catch_depth=%ld, catch_depth=%ld \"\n\t\t                     \"-> use fast variant (direct jump)\",\n\t\t                     (long) is_break, (long) label_id, (long) label_is_closest,\n\t\t                     (long) label_catch_depth, (long) comp_ctx->curr_func.catch_depth));\n\n\t\tduk__emit_jump(comp_ctx, label_pc + (is_break ? 1 : 2));\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"break/continue: is_break=%ld, label_id=%ld, label_is_closest=%ld, \"\n\t\t                     \"label_catch_depth=%ld, catch_depth=%ld \"\n\t\t                     \"-> use slow variant (longjmp)\",\n\t\t                     (long) is_break, (long) label_id, (long) label_is_closest,\n\t\t                     (long) label_catch_depth, (long) comp_ctx->curr_func.catch_depth));\n\n\t\tduk__emit_bc(comp_ctx,\n\t\t             is_break ? DUK_OP_BREAK : DUK_OP_CONTINUE,\n\t\t             (duk_regconst_t) label_id);\n\t}\n}\n\nDUK_LOCAL void duk__parse_return_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t rc_val;\n\n\tduk__advance(comp_ctx);  /* eat 'return' */\n\n\t/* A 'return' statement is only allowed inside an actual function body,\n\t * not as part of eval or global code.\n\t */\n\tif (!comp_ctx->curr_func.is_function) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_RETURN);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON ||  /* explicit semi follows */\n\t    comp_ctx->curr_token.lineterm ||                /* automatic semi will be inserted */\n\t    comp_ctx->curr_token.allow_auto_semi) {         /* automatic semi will be inserted */\n\t\tDUK_DDD(DUK_DDDPRINT(\"empty return value -> undefined\"));\n\t\tduk__emit_op_only(comp_ctx, DUK_OP_RETUNDEF);\n\t} else {\n\t\tduk_int_t pc_before_expr;\n\t\tduk_int_t pc_after_expr;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"return with a value\"));\n\n\t\tDUK_UNREF(pc_before_expr);\n\t\tDUK_UNREF(pc_after_expr);\n\n\t\tpc_before_expr = duk__get_current_pc(comp_ctx);\n\t\trc_val = duk__exprtop_toregconst(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\t\tpc_after_expr = duk__get_current_pc(comp_ctx);\n\n\t\t/* Tail call check: if last opcode emitted was CALL, and\n\t\t * the context allows it, add a tailcall flag to the CALL.\n\t\t * This doesn't guarantee that a tail call will be allowed at\n\t\t * runtime, so the RETURN must still be emitted.  (Duktape\n\t\t * 0.10.0 avoided this and simulated a RETURN if a tail call\n\t\t * couldn't be used at runtime; but this didn't work\n\t\t * correctly with a thread yield/resume, see\n\t\t * test-bug-tailcall-thread-yield-resume.js for discussion.)\n\t\t *\n\t\t * In addition to the last opcode being CALL, we also need to\n\t\t * be sure that 'rc_val' is the result register of the CALL.\n\t\t * For instance, for the expression 'return 0, (function ()\n\t\t * { return 1; }), 2' the last opcode emitted is CALL (no\n\t\t * bytecode is emitted for '2') but 'rc_val' indicates\n\t\t * constant '2'.  Similarly if '2' is replaced by a register\n\t\t * bound variable, no opcodes are emitted but tail call would\n\t\t * be incorrect.\n\t\t *\n\t\t * This is tricky and easy to get wrong.  It would be best to\n\t\t * track enough expression metadata to check that 'rc_val' came\n\t\t * from that last CALL instruction.  We don't have that metadata\n\t\t * now, so we check that 'rc_val' is a temporary register result\n\t\t * (not a constant or a register bound variable).  There should\n\t\t * be no way currently for 'rc_val' to be a temporary for an\n\t\t * expression following the CALL instruction without emitting\n\t\t * some opcodes following the CALL.  This proxy check is used\n\t\t * below.\n\t\t *\n\t\t * See: test-bug-comma-expr-gh131.js.\n\t\t *\n\t\t * The non-standard 'caller' property disables tail calls\n\t\t * because they pose some special cases which haven't been\n\t\t * fixed yet.\n\t\t */\n\n#if defined(DUK_USE_TAILCALL)\n\t\tif (comp_ctx->curr_func.catch_depth == 0 &&   /* no catchers */\n\t\t    pc_after_expr > pc_before_expr) {         /* at least one opcode emitted */\n\t\t\tduk_compiler_instr *instr;\n\t\t\tduk_instr_t ins;\n\t\t\tduk_small_uint_t op;\n\n\t\t\tinstr = duk__get_instr_ptr(comp_ctx, pc_after_expr - 1);\n\t\t\tDUK_ASSERT(instr != NULL);\n\n\t\t\tins = instr->ins;\n\t\t\top = (duk_small_uint_t) DUK_DEC_OP(ins);\n\t\t\tif ((op & ~0x0fU) == DUK_OP_CALL0 &&\n\t\t\t    DUK__ISREG_TEMP(comp_ctx, rc_val) /* see above */) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"return statement detected a tail call opportunity: \"\n\t\t\t\t                     \"catch depth is 0, duk__exprtop() emitted >= 1 instructions, \"\n\t\t\t\t                     \"and last instruction is a CALL \"\n\t\t\t\t                     \"-> change to TAILCALL\"));\n\t\t\t\tins |= DUK_ENC_OP(DUK_BC_CALL_FLAG_TAILCALL);\n\t\t\t\tinstr->ins = ins;\n\t\t\t}\n\t\t}\n#endif  /* DUK_USE_TAILCALL */\n\n\t\tif (DUK__ISREG(rc_val)) {\n\t\t\tduk__emit_bc(comp_ctx, DUK_OP_RETREG, rc_val);\n\t\t} else {\n\t\t\trc_val = DUK__REMOVECONST(rc_val);\n\t\t\tif (duk__const_needs_refcount(comp_ctx, rc_val)) {\n\t\t\t\tduk__emit_bc(comp_ctx, DUK_OP_RETCONST, rc_val);\n\t\t\t} else {\n\t\t\t\tduk__emit_bc(comp_ctx, DUK_OP_RETCONSTN, rc_val);\n\t\t\t}\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__parse_throw_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_regconst_t reg_val;\n\n\tduk__advance(comp_ctx);  /* eat 'throw' */\n\n\t/* Unlike break/continue, throw statement does not allow an empty value. */\n\n\tif (comp_ctx->curr_token.lineterm) {\n\t\tDUK_ERROR_SYNTAX(comp_ctx->thr, DUK_STR_INVALID_THROW);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\treg_val = duk__exprtop_toreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\tduk__emit_bc(comp_ctx,\n\t             DUK_OP_THROW,\n\t             reg_val);\n}\n\nDUK_LOCAL void duk__parse_try_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_regconst_t reg_catch;      /* reg_catch+0 and reg_catch+1 are reserved for TRYCATCH */\n\tduk_regconst_t rc_varname = 0;\n\tduk_small_uint_t trycatch_flags = 0;\n\tduk_int_t pc_ldconst = -1;\n\tduk_int_t pc_trycatch = -1;\n\tduk_int_t pc_catch = -1;\n\tduk_int_t pc_finally = -1;\n\n\tDUK_UNREF(res);\n\n\t/*\n\t *  See the following documentation for discussion:\n\t *\n\t *    doc/execution.rst: control flow details\n\t *\n\t *  Try, catch, and finally \"parts\" are Blocks, not Statements, so\n\t *  they must always be delimited by curly braces.  This is unlike e.g.\n\t *  the if statement, which accepts any Statement.  This eliminates any\n\t *  questions of matching parts of nested try statements.  The Block\n\t *  parsing is implemented inline here (instead of calling out).\n\t *\n\t *  Finally part has a 'let scoped' variable, which requires a few kinks\n\t *  here.\n\t */\n\n\tcomp_ctx->curr_func.catch_depth++;\n\n\tduk__advance(comp_ctx);  /* eat 'try' */\n\n\treg_catch = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\t/* The target for this LDCONST may need output shuffling, but we assume\n\t * that 'pc_ldconst' will be the LDCONST that we can patch later.  This\n\t * should be the case because there's no input shuffling.  (If there's\n\t * no catch clause, this LDCONST will be replaced with a NOP.)\n\t */\n\tpc_ldconst = duk__get_current_pc(comp_ctx);\n\tduk__emit_a_bc(comp_ctx, DUK_OP_LDCONST, reg_catch, 0 /*patched later*/);\n\n\tpc_trycatch = duk__get_current_pc(comp_ctx);\n\tduk__emit_invalid(comp_ctx);  /* TRYCATCH, cannot emit now (not enough info) */\n\tduk__emit_invalid(comp_ctx);  /* jump for 'catch' case */\n\tduk__emit_invalid(comp_ctx);  /* jump for 'finally' case or end (if no finally) */\n\n\t/* try part */\n\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\tduk__emit_op_only(comp_ctx, DUK_OP_ENDTRY);\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_CATCH) {\n\t\t/*\n\t\t *  The catch variable must be updated to reflect the new allocated\n\t\t *  register for the duration of the catch clause.  We need to store\n\t\t *  and restore the original value for the varmap entry (if any).\n\t\t */\n\n\t\t/*\n\t\t *  Note: currently register bindings must be fixed for the entire\n\t\t *  function.  So, even though the catch variable is in a register\n\t\t *  we know, we must use an explicit environment record and slow path\n\t\t *  accesses to read/write the catch binding to make closures created\n\t\t *  within the catch clause work correctly.  This restriction should\n\t\t *  be fixable (at least in common cases) later.\n\t\t *\n\t\t *  See: test-bug-catch-binding-2.js.\n\t\t *\n\t\t *  XXX: improve to get fast path access to most catch clauses.\n\t\t */\n\n\t\tduk_hstring *h_var;\n\t\tduk_int_t varmap_value;  /* for storing/restoring the varmap binding for catch variable */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"stack top at start of catch clause: %ld\", (long) duk_get_top(thr)));\n\n\t\ttrycatch_flags |= DUK_BC_TRYCATCH_FLAG_HAVE_CATCH;\n\n\t\tpc_catch = duk__get_current_pc(comp_ctx);\n\n\t\tduk__advance(comp_ctx);\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\t\tif (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) {\n\t\t\t/* Identifier, i.e. don't allow reserved words */\n\t\t\tgoto syntax_error;\n\t\t}\n\t\th_var = comp_ctx->curr_token.str1;\n\t\tDUK_ASSERT(h_var != NULL);\n\n\t\tduk_push_hstring(thr, h_var);  /* keep in on valstack, use borrowed ref below */\n\n\t\tif (comp_ctx->curr_func.is_strict &&\n\t\t    ((h_var == DUK_HTHREAD_STRING_EVAL(thr)) ||\n\t\t     (h_var == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)))) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"catch identifier 'eval' or 'arguments' in strict mode -> SyntaxError\"));\n\t\t\tgoto syntax_error;\n\t\t}\n\n\t\tduk_dup_top(thr);\n\t\trc_varname = duk__getconst(comp_ctx);\n\t\tDUK_DDD(DUK_DDDPRINT(\"catch clause, rc_varname=0x%08lx (%ld)\",\n\t\t                     (unsigned long) rc_varname, (long) rc_varname));\n\n\t\tduk__advance(comp_ctx);\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"varmap before modifying for catch clause: %!iT\",\n\t\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));\n\n\t\tduk_dup_top(thr);\n\t\tduk_get_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\tif (duk_is_undefined(thr, -1)) {\n\t\t\tvarmap_value = -2;\n\t\t} else if (duk_is_null(thr, -1)) {\n\t\t\tvarmap_value = -1;\n\t\t} else {\n\t\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\t\tvarmap_value = duk_get_int(thr, -1);\n\t\t\tDUK_ASSERT(varmap_value >= 0);\n\t\t}\n\t\tduk_pop(thr);\n\n#if 0\n\t\t/* It'd be nice to do something like this - but it doesn't\n\t\t * work for closures created inside the catch clause.\n\t\t */\n\t\tduk_dup_top(thr);\n\t\tduk_push_int(thr, (duk_int_t) (reg_catch + 0));\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);\n#endif\n\t\tduk_dup_top(thr);\n\t\tduk_push_null(thr);\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);\n\n\t\tduk__emit_a_bc(comp_ctx,\n\t\t               DUK_OP_PUTVAR | DUK__EMIT_FLAG_A_IS_SOURCE,\n\t\t               reg_catch + 0 /*value*/,\n\t\t               rc_varname /*varname*/);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"varmap before parsing catch clause: %!iT\",\n\t\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));\n\n\t\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\n\t\tif (varmap_value == -2) {\n\t\t\t/* not present */\n\t\t\tduk_del_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\t} else {\n\t\t\tif (varmap_value == -1) {\n\t\t\t\tduk_push_null(thr);\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(varmap_value >= 0);\n\t\t\t\tduk_push_int(thr, varmap_value);\n\t\t\t}\n\t\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\t}\n\t\t/* varname is popped by above code */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"varmap after restore catch clause: %!iT\",\n\t\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx)));\n\n\t\tduk__emit_op_only(comp_ctx,\n\t\t                  DUK_OP_ENDCATCH);\n\n\t\t/*\n\t\t *  XXX: for now, indicate that an expensive catch binding\n\t\t *  declarative environment is always needed.  If we don't\n\t\t *  need it, we don't need the const_varname either.\n\t\t */\n\n\t\ttrycatch_flags |= DUK_BC_TRYCATCH_FLAG_CATCH_BINDING;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"stack top at end of catch clause: %ld\", (long) duk_get_top(thr)));\n\t}\n\n\tif (comp_ctx->curr_token.t == DUK_TOK_FINALLY) {\n\t\ttrycatch_flags |= DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY;\n\n\t\tpc_finally = duk__get_current_pc(comp_ctx);\n\n\t\tduk__advance(comp_ctx);\n\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_LCURLY);\n\t\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\t\tduk__emit_abc(comp_ctx,\n\t\t              DUK_OP_ENDFIN,\n\t\t              reg_catch);  /* rethrow */\n\t}\n\n\tif (!(trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) &&\n\t    !(trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY)) {\n\t\t/* must have catch and/or finally */\n\t\tgoto syntax_error;\n\t}\n\n\t/* If there's no catch block, rc_varname will be 0 and duk__patch_trycatch()\n\t * will replace the LDCONST with a NOP.  For any actual constant (including\n\t * constant 0) the DUK__CONST_MARKER flag will be set in rc_varname.\n\t */\n\n\tduk__patch_trycatch(comp_ctx,\n\t                    pc_ldconst,\n\t                    pc_trycatch,\n\t                    reg_catch,\n\t                    rc_varname,\n\t                    trycatch_flags);\n\n\tif (trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) {\n\t\tDUK_ASSERT(pc_catch >= 0);\n\t\tduk__patch_jump(comp_ctx, pc_trycatch + 1, pc_catch);\n\t}\n\n\tif (trycatch_flags & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY) {\n\t\tDUK_ASSERT(pc_finally >= 0);\n\t\tduk__patch_jump(comp_ctx, pc_trycatch + 2, pc_finally);\n\t} else {\n\t\t/* without finally, the second jump slot is used to jump to end of stmt */\n\t\tduk__patch_jump_here(comp_ctx, pc_trycatch + 2);\n\t}\n\n\tcomp_ctx->curr_func.catch_depth--;\n\treturn;\n\n syntax_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_TRY);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__parse_with_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res) {\n\tduk_int_t pc_trycatch;\n\tduk_int_t pc_finished;\n\tduk_regconst_t reg_catch;\n\tduk_small_uint_t trycatch_flags;\n\n\tif (comp_ctx->curr_func.is_strict) {\n\t\tDUK_ERROR_SYNTAX(comp_ctx->thr, DUK_STR_WITH_IN_STRICT_MODE);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tcomp_ctx->curr_func.catch_depth++;\n\n\tduk__advance(comp_ctx);  /* eat 'with' */\n\n\treg_catch = DUK__ALLOCTEMPS(comp_ctx, 2);\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\tduk__exprtop_toforcedreg(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/, reg_catch);\n\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\tduk__advance_expect(comp_ctx, DUK_TOK_RPAREN);  /* Allow RegExp as part of next stmt. */\n\n\tpc_trycatch = duk__get_current_pc(comp_ctx);\n\ttrycatch_flags = DUK_BC_TRYCATCH_FLAG_WITH_BINDING;\n\tduk__emit_a_bc(comp_ctx,\n\t                DUK_OP_TRYCATCH | DUK__EMIT_FLAG_NO_SHUFFLE_A,\n\t                (duk_regconst_t) trycatch_flags /*a*/,\n\t                reg_catch /*bc*/);\n\tduk__emit_invalid(comp_ctx);  /* catch jump */\n\tduk__emit_invalid(comp_ctx);  /* finished jump */\n\n\tduk__parse_stmt(comp_ctx, res, 0 /*allow_source_elem*/);\n\tduk__emit_op_only(comp_ctx, DUK_OP_ENDTRY);\n\n\tpc_finished = duk__get_current_pc(comp_ctx);\n\n\tduk__patch_jump(comp_ctx, pc_trycatch + 2, pc_finished);\n\n\tcomp_ctx->curr_func.catch_depth--;\n}\n\nDUK_LOCAL duk_int_t duk__stmt_label_site(duk_compiler_ctx *comp_ctx, duk_int_t label_id) {\n\t/* if a site already exists, nop: max one label site per statement */\n\tif (label_id >= 0) {\n\t\treturn label_id;\n\t}\n\n\tlabel_id = comp_ctx->curr_func.label_next++;\n\tDUK_DDD(DUK_DDDPRINT(\"allocated new label id for label site: %ld\", (long) label_id));\n\n\tduk__emit_bc(comp_ctx,\n\t             DUK_OP_LABEL,\n\t             (duk_regconst_t) label_id);\n\tduk__emit_invalid(comp_ctx);\n\tduk__emit_invalid(comp_ctx);\n\n\treturn label_id;\n}\n\n/* Parse a single statement.\n *\n * Creates a label site (with an empty label) automatically for iteration\n * statements.  Also \"peels off\" any label statements for explicit labels.\n */\nDUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_bool_t allow_source_elem) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t dir_prol_at_entry;    /* directive prologue status at entry */\n\tduk_regconst_t temp_at_entry;\n\tduk_size_t labels_len_at_entry;\n\tduk_int_t pc_at_entry;           /* assumed to also be PC of \"LABEL\" */\n\tduk_int_t stmt_id;\n\tduk_small_uint_t stmt_flags = 0;\n\tduk_int_t label_id = -1;\n\tduk_small_uint_t tok;\n\tduk_bool_t test_func_decl;\n\n\tDUK__RECURSION_INCREASE(comp_ctx, thr);\n\n\ttemp_at_entry = DUK__GETTEMP(comp_ctx);\n\tpc_at_entry = duk__get_current_pc(comp_ctx);\n\tlabels_len_at_entry = duk_get_length(thr, comp_ctx->curr_func.labelnames_idx);\n\tstmt_id = comp_ctx->curr_func.stmt_next++;\n\tdir_prol_at_entry = comp_ctx->curr_func.in_directive_prologue;\n\n\tDUK_UNREF(stmt_id);\n\n\tDUK_DDD(DUK_DDDPRINT(\"parsing a statement, stmt_id=%ld, temp_at_entry=%ld, labels_len_at_entry=%ld, \"\n\t                     \"is_strict=%ld, in_directive_prologue=%ld, catch_depth=%ld\",\n\t                     (long) stmt_id, (long) temp_at_entry, (long) labels_len_at_entry,\n\t                     (long) comp_ctx->curr_func.is_strict, (long) comp_ctx->curr_func.in_directive_prologue,\n\t                     (long) comp_ctx->curr_func.catch_depth));\n\n\t/* The directive prologue flag is cleared by default so that it is\n\t * unset for any recursive statement parsing.  It is only \"revived\"\n\t * if a directive is detected.  (We could also make directives only\n\t * allowed if 'allow_source_elem' was true.)\n\t */\n\tcomp_ctx->curr_func.in_directive_prologue = 0;\n\n retry_parse:\n\n\tDUK_DDD(DUK_DDDPRINT(\"try stmt parse, stmt_id=%ld, label_id=%ld, allow_source_elem=%ld, catch_depth=%ld\",\n\t                     (long) stmt_id, (long) label_id, (long) allow_source_elem,\n\t                     (long) comp_ctx->curr_func.catch_depth));\n\n\t/*\n\t *  Detect iteration statements; if encountered, establish an\n\t *  empty label.\n\t */\n\n\ttok = comp_ctx->curr_token.t;\n\tif (tok == DUK_TOK_FOR || tok == DUK_TOK_DO || tok == DUK_TOK_WHILE ||\n\t    tok == DUK_TOK_SWITCH) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"iteration/switch statement -> add empty label\"));\n\n\t\tlabel_id = duk__stmt_label_site(comp_ctx, label_id);\n\t\tduk__add_label(comp_ctx,\n\t\t               DUK_HTHREAD_STRING_EMPTY_STRING(thr),\n\t\t               pc_at_entry /*pc_label*/,\n\t\t               label_id);\n\t}\n\n\t/*\n\t *  Main switch for statement / source element type.\n\t */\n\n\tswitch (comp_ctx->curr_token.t) {\n\tcase DUK_TOK_FUNCTION: {\n\t\t/*\n\t\t *  Function declaration, function expression, or (non-standard)\n\t\t *  function statement.\n\t\t *\n\t\t *  The E5 specification only allows function declarations at\n\t\t *  the top level (in \"source elements\").  An ExpressionStatement\n\t\t *  is explicitly not allowed to begin with a \"function\" keyword\n\t\t *  (E5 Section 12.4).  Hence any non-error semantics for such\n\t\t *  non-top-level statements are non-standard.  Duktape semantics\n\t\t *  for function statements are modelled after V8, see\n\t\t *  test-dev-func-decl-outside-top.js.\n\t\t */\n\t\ttest_func_decl = allow_source_elem;\n#if defined(DUK_USE_NONSTD_FUNC_STMT)\n\t\t/* Lenient: allow function declarations outside top level in\n\t\t * non-strict mode but reject them in strict mode.\n\t\t */\n\t\ttest_func_decl = test_func_decl || !comp_ctx->curr_func.is_strict;\n#endif  /* DUK_USE_NONSTD_FUNC_STMT */\n\t\t/* Strict: never allow function declarations outside top level. */\n\t\tif (test_func_decl) {\n\t\t\t/* FunctionDeclaration: not strictly a statement but handled as such.\n\t\t\t *\n\t\t\t * O(depth^2) parse count for inner functions is handled by recording a\n\t\t\t * lexer offset on the first compilation pass, so that the function can\n\t\t\t * be efficiently skipped on the second pass.  This is encapsulated into\n\t\t\t * duk__parse_func_like_fnum().\n\t\t\t */\n\n\t\t\tduk_int_t fnum;\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\tduk_idx_t top_before;\n#endif\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"function declaration statement\"));\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\ttop_before = duk_get_top(thr);\n#endif\n\n\t\t\tduk__advance(comp_ctx);  /* eat 'function' */\n\t\t\tfnum = duk__parse_func_like_fnum(comp_ctx, DUK__FUNC_FLAG_DECL | DUK__FUNC_FLAG_PUSHNAME_PASS1);\n\n\t\t\t/* The value stack convention here is a bit odd: the function\n\t\t\t * name is only pushed on pass 1 (in_scanning), and is needed\n\t\t\t * to process function declarations.\n\t\t\t */\n\t\t\tif (comp_ctx->curr_func.in_scanning) {\n\t\t\t\tduk_uarridx_t n;\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t\tDUK_ASSERT(duk_get_top(thr) == top_before + 1);\n#endif\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"register function declaration %!T in pass 1, fnum %ld\",\n\t\t\t\t                     duk_get_tval(thr, -1), (long) fnum));\n\t\t\t\tn = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.decls_idx);\n\t\t\t\t/* funcname is at index -1 */\n\t\t\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n);\n\t\t\t\tduk_push_int(thr, (duk_int_t) (DUK_DECL_TYPE_FUNC + (fnum << 8)));\n\t\t\t\tduk_put_prop_index(thr, comp_ctx->curr_func.decls_idx, n + 1);\n\t\t\t} else {\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t\tDUK_ASSERT(duk_get_top(thr) == top_before);\n#endif\n\t\t\t}\n\n\t\t\t/* no statement value (unlike function expression) */\n\t\t\tstmt_flags = 0;\n\t\t\tbreak;\n\t\t} else {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_FUNC_STMT_NOT_ALLOWED);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TOK_LCURLY: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"block statement\"));\n\t\tduk__advance(comp_ctx);\n\t\tduk__parse_stmts(comp_ctx, 0 /*allow_source_elem*/, 0 /*expect_eof*/, 1 /*regexp_after*/);\n\t\t/* the DUK_TOK_RCURLY is eaten by duk__parse_stmts() */\n\t\tif (label_id >= 0) {\n\t\t\tduk__patch_jump_here(comp_ctx, pc_at_entry + 1);  /* break jump */\n\t\t}\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_CONST: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"constant declaration statement\"));\n\t\tduk__parse_var_stmt(comp_ctx, res, DUK__EXPR_FLAG_REQUIRE_INIT /*expr_flags*/);\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_VAR: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"variable declaration statement\"));\n\t\tduk__parse_var_stmt(comp_ctx, res, 0 /*expr_flags*/);\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_SEMICOLON: {\n\t\t/* empty statement with an explicit semicolon */\n\t\tDUK_DDD(DUK_DDDPRINT(\"empty statement\"));\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_IF: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"if statement\"));\n\t\tduk__parse_if_stmt(comp_ctx, res);\n\t\tif (label_id >= 0) {\n\t\t\tduk__patch_jump_here(comp_ctx, pc_at_entry + 1);  /* break jump */\n\t\t}\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_DO: {\n\t\t/*\n\t\t *  Do-while statement is mostly trivial, but there is special\n\t\t *  handling for automatic semicolon handling (triggered by the\n\t\t *  DUK__ALLOW_AUTO_SEMI_ALWAYS) flag related to a bug filed at:\n\t\t *\n\t\t *    https://bugs.ecmascript.org/show_bug.cgi?id=8\n\t\t *\n\t\t *  See doc/compiler.rst for details.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"do statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK | DUK_LABEL_FLAG_ALLOW_CONTINUE);\n\t\tduk__parse_do_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__ALLOW_AUTO_SEMI_ALWAYS;  /* DUK__ALLOW_AUTO_SEMI_ALWAYS workaround */\n\t\tbreak;\n\t}\n\tcase DUK_TOK_WHILE: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"while statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK | DUK_LABEL_FLAG_ALLOW_CONTINUE);\n\t\tduk__parse_while_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_FOR: {\n\t\t/*\n\t\t *  For/for-in statement is complicated to parse because\n\t\t *  determining the statement type (three-part for vs. a\n\t\t *  for-in) requires potential backtracking.\n\t\t *\n\t\t *  See the helper for the messy stuff.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"for/for-in statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK | DUK_LABEL_FLAG_ALLOW_CONTINUE);\n\t\tduk__parse_for_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_CONTINUE:\n\tcase DUK_TOK_BREAK: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"break/continue statement\"));\n\t\tduk__parse_break_or_continue_stmt(comp_ctx, res);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__IS_TERMINAL;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_RETURN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"return statement\"));\n\t\tduk__parse_return_stmt(comp_ctx, res);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__IS_TERMINAL;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_WITH: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"with statement\"));\n\t\tcomp_ctx->curr_func.with_depth++;\n\t\tduk__parse_with_stmt(comp_ctx, res);\n\t\tif (label_id >= 0) {\n\t\t\tduk__patch_jump_here(comp_ctx, pc_at_entry + 1);  /* break jump */\n\t\t}\n\t\tcomp_ctx->curr_func.with_depth--;\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_SWITCH: {\n\t\t/*\n\t\t *  The switch statement is pretty messy to compile.\n\t\t *  See the helper for details.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"switch statement\"));\n\t\tDUK_ASSERT(label_id >= 0);\n\t\tduk__update_label_flags(comp_ctx,\n\t\t                        label_id,\n\t\t                        DUK_LABEL_FLAG_ALLOW_BREAK);  /* don't allow continue */\n\t\tduk__parse_switch_stmt(comp_ctx, res, pc_at_entry);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_THROW: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"throw statement\"));\n\t\tduk__parse_throw_stmt(comp_ctx, res);\n\t\tstmt_flags = DUK__HAS_TERM | DUK__IS_TERMINAL;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_TRY: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"try statement\"));\n\t\tduk__parse_try_stmt(comp_ctx, res);\n\t\tstmt_flags = 0;\n\t\tbreak;\n\t}\n\tcase DUK_TOK_DEBUGGER: {\n\t\tduk__advance(comp_ctx);\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tDUK_DDD(DUK_DDDPRINT(\"debugger statement: debugging enabled, emit debugger opcode\"));\n\t\tduk__emit_op_only(comp_ctx, DUK_OP_DEBUGGER);\n#else\n\t\tDUK_DDD(DUK_DDDPRINT(\"debugger statement: ignored\"));\n#endif\n\t\tstmt_flags = DUK__HAS_TERM;\n\t\tbreak;\n\t}\n\tdefault: {\n\t\t/*\n\t\t *  Else, must be one of:\n\t\t *    - ExpressionStatement, possibly a directive (String)\n\t\t *    - LabelledStatement (Identifier followed by ':')\n\t\t *\n\t\t *  Expressions beginning with 'function' keyword are covered by a case\n\t\t *  above (such expressions are not allowed in standard E5 anyway).\n\t\t *  Also expressions starting with '{' are interpreted as block\n\t\t *  statements.  See E5 Section 12.4.\n\t\t *\n\t\t *  Directive detection is tricky; see E5 Section 14.1 on directive\n\t\t *  prologue.  A directive is an expression statement with a single\n\t\t *  string literal and an explicit or automatic semicolon.  Escape\n\t\t *  characters are significant and no parens etc are allowed:\n\t\t *\n\t\t *    'use strict';          // valid 'use strict' directive\n\t\t *    'use\\u0020strict';     // valid directive, not a 'use strict' directive\n\t\t *    ('use strict');        // not a valid directive\n\t\t *\n\t\t *  The expression is determined to consist of a single string literal\n\t\t *  based on duk__expr_nud() and duk__expr_led() call counts.  The string literal\n\t\t *  of a 'use strict' directive is determined to lack any escapes based\n\t\t *  num_escapes count from the lexer.  Note that other directives may be\n\t\t *  allowed to contain escapes, so a directive with escapes does not\n\t\t *  terminate a directive prologue.\n\t\t *\n\t\t *  We rely on the fact that the expression parser will not emit any\n\t\t *  code for a single token expression.  However, it will generate an\n\t\t *  intermediate value which we will then successfully ignore.\n\t\t *\n\t\t *  A similar approach is used for labels.\n\t\t */\n\n\t\tduk_bool_t single_token;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"expression statement\"));\n\t\tduk__exprtop(comp_ctx, res, DUK__BP_FOR_EXPR /*rbp_flags*/);\n\n\t\tsingle_token = (comp_ctx->curr_func.nud_count == 1 &&  /* one token */\n\t\t                comp_ctx->curr_func.led_count == 0);   /* no operators */\n\n\t\tif (single_token &&\n\t\t    comp_ctx->prev_token.t == DUK_TOK_IDENTIFIER &&\n\t\t    comp_ctx->curr_token.t == DUK_TOK_COLON) {\n\t\t\t/*\n\t\t\t *  Detected label\n\t\t\t */\n\n\t\t\tduk_hstring *h_lab;\n\n\t\t\t/* expected ival */\n\t\t\tDUK_ASSERT(res->t == DUK_IVAL_VAR);\n\t\t\tDUK_ASSERT(res->x1.t == DUK_ISPEC_VALUE);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(duk_get_tval(thr, res->x1.valstack_idx)));\n\t\t\th_lab = comp_ctx->prev_token.str1;\n\t\t\tDUK_ASSERT(h_lab != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"explicit label site for label '%!O'\",\n\t\t\t                     (duk_heaphdr *) h_lab));\n\n\t\t\tduk__advance(comp_ctx);  /* eat colon */\n\n\t\t\tlabel_id = duk__stmt_label_site(comp_ctx, label_id);\n\n\t\t\tduk__add_label(comp_ctx,\n\t\t\t               h_lab,\n\t\t\t               pc_at_entry /*pc_label*/,\n\t\t\t               label_id);\n\n\t\t\t/* a statement following a label cannot be a source element\n\t\t\t * (a function declaration).\n\t\t\t */\n\t\t\tallow_source_elem = 0;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"label handled, retry statement parsing\"));\n\t\t\tgoto retry_parse;\n\t\t}\n\n\t\tstmt_flags = 0;\n\n\t\tif (dir_prol_at_entry &&                           /* still in prologue */\n\t\t    single_token &&                                /* single string token */\n\t\t    comp_ctx->prev_token.t == DUK_TOK_STRING) {\n\t\t\t/*\n\t\t\t *  Detected a directive\n\t\t\t */\n\t\t\tduk_hstring *h_dir;\n\n\t\t\t/* expected ival */\n\t\t\tDUK_ASSERT(res->t == DUK_IVAL_PLAIN);\n\t\t\tDUK_ASSERT(res->x1.t == DUK_ISPEC_VALUE);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(duk_get_tval(thr, res->x1.valstack_idx)));\n\t\t\th_dir = comp_ctx->prev_token.str1;\n\t\t\tDUK_ASSERT(h_dir != NULL);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"potential directive: %!O\", h_dir));\n\n\t\t\tstmt_flags |= DUK__STILL_PROLOGUE;\n\n\t\t\t/* Note: escaped characters differentiate directives */\n\n\t\t\tif (comp_ctx->prev_token.num_escapes > 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"directive contains escapes: valid directive \"\n\t\t\t\t                     \"but we ignore such directives\"));\n\t\t\t} else {\n\t\t\t\t/*\n\t\t\t\t * The length comparisons are present to handle\n\t\t\t\t * strings like \"use strict\\u0000foo\" as required.\n\t\t\t\t */\n\n\t\t\t\tif (DUK_HSTRING_GET_BYTELEN(h_dir) == 10 &&\n\t\t\t\t    DUK_STRCMP((const char *) DUK_HSTRING_GET_DATA(h_dir), \"use strict\") == 0) {\n#if defined(DUK_USE_STRICT_DECL)\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"use strict directive detected: strict flag %ld -> %ld\",\n\t\t\t\t\t                     (long) comp_ctx->curr_func.is_strict, (long) 1));\n\t\t\t\t\tcomp_ctx->curr_func.is_strict = 1;\n#else\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"use strict detected but strict declarations disabled, ignoring\"));\n#endif\n\t\t\t\t} else if (DUK_HSTRING_GET_BYTELEN(h_dir) == 14 &&\n\t\t\t\t           DUK_STRCMP((const char *) DUK_HSTRING_GET_DATA(h_dir), \"use duk notail\") == 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"use duk notail directive detected: notail flag %ld -> %ld\",\n\t\t\t\t\t                     (long) comp_ctx->curr_func.is_notail, (long) 1));\n\t\t\t\t\tcomp_ctx->curr_func.is_notail = 1;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"unknown directive: '%!O', ignoring but not terminating \"\n\t\t\t\t\t                   \"directive prologue\", (duk_hobject *) h_dir));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-directive expression statement or no longer in prologue; \"\n\t\t\t                     \"prologue terminated if still active\"));\n                }\n\n\t\tstmt_flags |= DUK__HAS_VAL | DUK__HAS_TERM;\n\t}\n\t}  /* end switch (tok) */\n\n\t/*\n\t *  Statement value handling.\n\t *\n\t *  Global code and eval code has an implicit return value\n\t *  which comes from the last statement with a value\n\t *  (technically a non-\"empty\" continuation, which is\n\t *  different from an empty statement).\n\t *\n\t *  Since we don't know whether a later statement will\n\t *  override the value of the current statement, we need\n\t *  to coerce the statement value to a register allocated\n\t *  for implicit return values.  In other cases we need\n\t *  to coerce the statement value to a plain value to get\n\t *  any side effects out (consider e.g. \"foo.bar;\").\n\t */\n\n\t/* XXX: what about statements which leave a half-cooked value in 'res'\n\t * but have no stmt value?  Any such statements?\n\t */\n\n\tif (stmt_flags & DUK__HAS_VAL) {\n\t\tduk_regconst_t reg_stmt_value = comp_ctx->curr_func.reg_stmt_value;\n\t\tif (reg_stmt_value >= 0) {\n\t\t\tduk__ivalue_toforcedreg(comp_ctx, res, reg_stmt_value);\n\t\t} else {\n\t\t\tduk__ivalue_toplain_ignore(comp_ctx, res);\n\t\t}\n\t} else {\n\t\t;\n\t}\n\n\t/*\n\t *  Statement terminator check, including automatic semicolon\n\t *  handling.  After this step, 'curr_tok' should be the first\n\t *  token after a possible statement terminator.\n\t */\n\n\tif (stmt_flags & DUK__HAS_TERM) {\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_SEMICOLON) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"explicit semicolon terminates statement\"));\n\t\t\tduk__advance(comp_ctx);\n\t\t} else {\n\t\t\tif (comp_ctx->curr_token.allow_auto_semi) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"automatic semicolon terminates statement\"));\n\t\t\t} else if (stmt_flags & DUK__ALLOW_AUTO_SEMI_ALWAYS) {\n\t\t\t\t/* XXX: make this lenience dependent on flags or strictness? */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"automatic semicolon terminates statement (allowed for compatibility \"\n\t\t\t\t                     \"even though no lineterm present before next token)\"));\n\t\t\t} else {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_UNTERMINATED_STMT);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"statement has no terminator\"));\n\t}\n\n\t/*\n\t *  Directive prologue tracking.\n\t */\n\n\tif (stmt_flags & DUK__STILL_PROLOGUE) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"setting in_directive_prologue\"));\n\t\tcomp_ctx->curr_func.in_directive_prologue = 1;\n\t}\n\n\t/*\n\t *  Cleanups (all statement parsing flows through here).\n\t *\n\t *  Pop label site and reset labels.  Reset 'next temp' to value at\n\t *  entry to reuse temps.\n\t */\n\n\tif (label_id >= 0) {\n\t\tduk__emit_bc(comp_ctx,\n\t\t             DUK_OP_ENDLABEL,\n\t\t             (duk_regconst_t) label_id);\n\t}\n\n\tDUK__SETTEMP(comp_ctx, temp_at_entry);\n\n\tduk__reset_labels_to_length(comp_ctx, labels_len_at_entry);\n\n\t/* XXX: return indication of \"terminalness\" (e.g. a 'throw' is terminal) */\n\n\tDUK__RECURSION_DECREASE(comp_ctx, thr);\n}\n\n/*\n *  Parse a statement list.\n *\n *  Handles automatic semicolon insertion and implicit return value.\n *\n *  Upon entry, 'curr_tok' should contain the first token of the first\n *  statement (parsed in the \"allow regexp literal\" mode).  Upon exit,\n *  'curr_tok' contains the token following the statement list terminator\n *  (EOF or closing brace).\n */\n\nDUK_LOCAL void duk__parse_stmts(duk_compiler_ctx *comp_ctx, duk_bool_t allow_source_elem, duk_bool_t expect_eof, duk_bool_t regexp_after) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_ivalue res_alloc;\n\tduk_ivalue *res = &res_alloc;\n\n\t/* Setup state.  Initial ivalue is 'undefined'. */\n\n\tduk_require_stack(thr, DUK__PARSE_STATEMENTS_SLOTS);\n\n\t/* XXX: 'res' setup can be moved to function body level; in fact, two 'res'\n\t * intermediate values suffice for parsing of each function.  Nesting is needed\n\t * for nested functions (which may occur inside expressions).\n\t */\n\n\tduk_memzero(&res_alloc, sizeof(res_alloc));\n\tres->t = DUK_IVAL_PLAIN;\n\tres->x1.t = DUK_ISPEC_VALUE;\n\tres->x1.valstack_idx = duk_get_top(thr);\n\tres->x2.valstack_idx = res->x1.valstack_idx + 1;\n\tduk_push_undefined(thr);\n\tduk_push_undefined(thr);\n\n\t/* Parse statements until a closing token (EOF or '}') is found. */\n\n\tfor (;;) {\n\t\t/* Check whether statement list ends. */\n\n\t\tif (expect_eof) {\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_EOF) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (comp_ctx->curr_token.t == DUK_TOK_RCURLY) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* Check statement type based on the first token type.\n\t\t *\n\t\t * Note: expression parsing helpers expect 'curr_tok' to\n\t\t * contain the first token of the expression upon entry.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"TOKEN %ld (non-whitespace, non-comment)\", (long) comp_ctx->curr_token.t));\n\n\t\tduk__parse_stmt(comp_ctx, res, allow_source_elem);\n\t}\n\n\t/* RegExp is allowed / not allowed depending on context.  For function\n\t * declarations RegExp is allowed because it follows a function\n\t * declaration statement and may appear as part of the next statement.\n\t * For function expressions RegExp is not allowed, and it's possible\n\t * to do something like '(function () {} / 123)'.\n\t */\n\tif (regexp_after) {\n\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t}\n\tduk__advance(comp_ctx);\n\n\t/* Tear down state. */\n\n\tduk_pop_2(thr);\n}\n\n/*\n *  Declaration binding instantiation conceptually happens when calling a\n *  function; for us it essentially means that function prologue.  The\n *  conceptual process is described in E5 Section 10.5.\n *\n *  We need to keep track of all encountered identifiers to (1) create an\n *  identifier-to-register map (\"varmap\"); and (2) detect duplicate\n *  declarations.  Identifiers which are not bound to registers still need\n *  to be tracked for detecting duplicates.  Currently such identifiers\n *  are put into the varmap with a 'null' value, which is later cleaned up.\n *\n *  To support functions with a large number of variable and function\n *  declarations, registers are not allocated beyond a certain limit;\n *  after that limit, variables and functions need slow path access.\n *  Arguments are currently always register bound, which imposes a hard\n *  (and relatively small) argument count limit.\n *\n *  Some bindings in E5 are not configurable (= deletable) and almost all\n *  are mutable (writable).  Exceptions are:\n *\n *    - The 'arguments' binding, established only if no shadowing argument\n *      or function declaration exists.  We handle 'arguments' creation\n *      and binding through an explicit slow path environment record.\n *\n *    - The \"name\" binding for a named function expression.  This is also\n *      handled through an explicit slow path environment record.\n */\n\n/* XXX: add support for variables to not be register bound always, to\n * handle cases with a very large number of variables?\n */\n\nDUK_LOCAL void duk__init_varmap_and_prologue_for_pass2(duk_compiler_ctx *comp_ctx, duk_regconst_t *out_stmt_value_reg) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_hstring *h_name;\n\tduk_bool_t configurable_bindings;\n\tduk_uarridx_t num_args;\n\tduk_uarridx_t num_decls;\n\tduk_regconst_t rc_name;\n\tduk_small_uint_t declvar_flags;\n\tduk_uarridx_t i;\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_idx_t entry_top;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tentry_top = duk_get_top(thr);\n#endif\n\n\t/*\n\t *  Preliminaries\n\t */\n\n\tconfigurable_bindings = comp_ctx->curr_func.is_eval;\n\tDUK_DDD(DUK_DDDPRINT(\"configurable_bindings=%ld\", (long) configurable_bindings));\n\n\t/* varmap is already in comp_ctx->curr_func.varmap_idx */\n\n\t/*\n\t *  Function formal arguments, always bound to registers\n\t *  (there's no support for shuffling them now).\n\t */\n\n\tnum_args = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.argnames_idx);\n\tDUK_DDD(DUK_DDDPRINT(\"num_args=%ld\", (long) num_args));\n\t/* XXX: check num_args */\n\n\tfor (i = 0; i < num_args; i++) {\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.argnames_idx, i);\n\t\th_name = duk_known_hstring(thr, -1);\n\n\t\tif (comp_ctx->curr_func.is_strict) {\n\t\t\tif (duk__hstring_is_eval_or_arguments(comp_ctx, h_name)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"arg named 'eval' or 'arguments' in strict mode -> SyntaxError\"));\n\t\t\t\tgoto error_argname;\n\t\t\t}\n\t\t\tduk_dup_top(thr);\n\t\t\tif (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duplicate arg name in strict mode -> SyntaxError\"));\n\t\t\t\tgoto error_argname;\n\t\t\t}\n\n\t\t\t/* Ensure argument name is not a reserved word in current\n\t\t\t * (final) strictness.  Formal argument parsing may not\n\t\t\t * catch reserved names if strictness changes during\n\t\t\t * parsing.\n\t\t\t *\n\t\t\t * We only need to do this in strict mode because non-strict\n\t\t\t * keyword are always detected in formal argument parsing.\n\t\t\t */\n\n\t\t\tif (DUK_HSTRING_HAS_STRICT_RESERVED_WORD(h_name)) {\n\t\t\t\tgoto error_argname;\n\t\t\t}\n\t\t}\n\n\t\t/* overwrite any previous binding of the same name; the effect is\n\t\t * that last argument of a certain name wins.\n\t\t */\n\n\t\t/* only functions can have arguments */\n\t\tDUK_ASSERT(comp_ctx->curr_func.is_function);\n\t\tduk_push_uarridx(thr, i);  /* -> [ ... name index ] */\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx); /* -> [ ... ] */\n\n\t\t/* no code needs to be emitted, the regs already have values */\n\t}\n\n\t/* use temp_next for tracking register allocations */\n\tDUK__SETTEMP_CHECKMAX(comp_ctx, (duk_regconst_t) num_args);\n\n\t/*\n\t *  After arguments, allocate special registers (like shuffling temps)\n\t */\n\n\tif (out_stmt_value_reg) {\n\t\t*out_stmt_value_reg = DUK__ALLOCTEMP(comp_ctx);\n\t}\n\tif (comp_ctx->curr_func.needs_shuffle) {\n\t\tduk_regconst_t shuffle_base = DUK__ALLOCTEMPS(comp_ctx, 3);\n\t\tcomp_ctx->curr_func.shuffle1 = shuffle_base;\n\t\tcomp_ctx->curr_func.shuffle2 = shuffle_base + 1;\n\t\tcomp_ctx->curr_func.shuffle3 = shuffle_base + 2;\n\t\tDUK_D(DUK_DPRINT(\"shuffle registers needed by function, allocated: %ld %ld %ld\",\n\t\t                 (long) comp_ctx->curr_func.shuffle1,\n\t\t                 (long) comp_ctx->curr_func.shuffle2,\n\t\t                 (long) comp_ctx->curr_func.shuffle3));\n\t}\n\tif (comp_ctx->curr_func.temp_next > 0x100) {\n\t\tDUK_D(DUK_DPRINT(\"not enough 8-bit regs: temp_next=%ld\", (long) comp_ctx->curr_func.temp_next));\n\t\tgoto error_outofregs;\n\t}\n\n\t/*\n\t *  Function declarations\n\t */\n\n\tnum_decls = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.decls_idx);\n\tDUK_DDD(DUK_DDDPRINT(\"num_decls=%ld -> %!T\",\n\t                     (long) num_decls,\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.decls_idx)));\n\tfor (i = 0; i < num_decls; i += 2) {\n\t\tduk_int_t decl_type;\n\t\tduk_int_t fnum;\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i + 1);  /* decl type */\n\t\tdecl_type = duk_to_int(thr, -1);\n\t\tfnum = decl_type >> 8;  /* XXX: macros */\n\t\tdecl_type = decl_type & 0xff;\n\t\tduk_pop(thr);\n\n\t\tif (decl_type != DUK_DECL_TYPE_FUNC) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i);  /* decl name */\n\n\t\t/* XXX: spilling */\n\t\tif (comp_ctx->curr_func.is_function) {\n\t\t\tduk_regconst_t reg_bind;\n\t\t\tduk_dup_top(thr);\n\t\t\tif (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) {\n\t\t\t\t/* shadowed; update value */\n\t\t\t\tduk_dup_top(thr);\n\t\t\t\tduk_get_prop(thr, comp_ctx->curr_func.varmap_idx);\n\t\t\t\treg_bind = duk_to_int(thr, -1);  /* [ ... name reg_bind ] */\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_CLOSURE,\n\t\t\t\t               reg_bind,\n\t\t\t\t               (duk_regconst_t) fnum);\n\t\t\t} else {\n\t\t\t\t/* function: always register bound */\n\t\t\t\treg_bind = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t\t               DUK_OP_CLOSURE,\n\t\t\t\t               reg_bind,\n\t\t\t\t               (duk_regconst_t) fnum);\n\t\t\t\tduk_push_int(thr, (duk_int_t) reg_bind);\n\t\t\t}\n\t\t} else {\n\t\t\t/* Function declaration for global/eval code is emitted even\n\t\t\t * for duplicates, because of E5 Section 10.5, step 5.e of\n\t\t\t * E5.1 (special behavior for variable bound to global object).\n\t\t\t *\n\t\t\t * DECLVAR will not re-declare a variable as such, but will\n\t\t\t * update the binding value.\n\t\t\t */\n\n\t\t\tduk_regconst_t reg_temp = DUK__ALLOCTEMP(comp_ctx);\n\t\t\tduk_dup_top(thr);\n\t\t\trc_name = duk__getconst(comp_ctx);\n\t\t\tduk_push_null(thr);\n\n\t\t\tduk__emit_a_bc(comp_ctx,\n\t\t\t               DUK_OP_CLOSURE,\n\t\t\t               reg_temp,\n\t\t\t               (duk_regconst_t) fnum);\n\n\t\t\tdeclvar_flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t                DUK_PROPDESC_FLAG_ENUMERABLE |\n\t\t\t                DUK_BC_DECLVAR_FLAG_FUNC_DECL;\n\n\t\t\tif (configurable_bindings) {\n\t\t\t\tdeclvar_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t}\n\n\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t                DUK_OP_DECLVAR | DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t                (duk_regconst_t) declvar_flags /*flags*/,\n\t\t\t                rc_name /*name*/,\n\t\t\t                reg_temp /*value*/);\n\n\t\t\tDUK__SETTEMP(comp_ctx, reg_temp);  /* forget temp */\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"function declaration to varmap: %!T -> %!T\",\n\t\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n#if defined(DUK_USE_FASTINT)\n\t\tDUK_ASSERT(DUK_TVAL_IS_NULL(duk_get_tval(thr, -1)) || DUK_TVAL_IS_FASTINT(duk_get_tval(thr, -1)));\n#endif\n\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);  /* [ ... name reg/null ] -> [ ... ] */\n\t}\n\n\t/*\n\t *  'arguments' binding is special; if a shadowing argument or\n\t *  function declaration exists, an arguments object will\n\t *  definitely not be needed, regardless of whether the identifier\n\t *  'arguments' is referenced inside the function body.\n\t */\n\n\tif (duk_has_prop_stridx(thr, comp_ctx->curr_func.varmap_idx, DUK_STRIDX_LC_ARGUMENTS)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"'arguments' is shadowed by argument or function declaration \"\n\t\t                     \"-> arguments object creation can be skipped\"));\n\t\tcomp_ctx->curr_func.is_arguments_shadowed = 1;\n\t}\n\n\t/*\n\t *  Variable declarations.\n\t *\n\t *  Unlike function declarations, variable declaration values don't get\n\t *  assigned on entry.  If a binding of the same name already exists, just\n\t *  ignore it silently.\n\t */\n\n\tfor (i = 0; i < num_decls; i += 2) {\n\t\tduk_int_t decl_type;\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i + 1);  /* decl type */\n\t\tdecl_type = duk_to_int(thr, -1);\n\t\tdecl_type = decl_type & 0xff;\n\t\tduk_pop(thr);\n\n\t\tif (decl_type != DUK_DECL_TYPE_VAR) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i);  /* decl name */\n\n\t\tif (duk_has_prop(thr, comp_ctx->curr_func.varmap_idx)) {\n\t\t\t/* shadowed, ignore */\n\t\t} else {\n\t\t\tduk_get_prop_index(thr, comp_ctx->curr_func.decls_idx, i);  /* decl name */\n\t\t\th_name = duk_known_hstring(thr, -1);\n\n\t\t\tif (h_name == DUK_HTHREAD_STRING_LC_ARGUMENTS(thr) &&\n\t\t\t    !comp_ctx->curr_func.is_arguments_shadowed) {\n\t\t\t\t/* E5 Section steps 7-8 */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"'arguments' not shadowed by a function declaration, \"\n\t\t\t\t                     \"but appears as a variable declaration -> treat as \"\n\t\t\t\t                     \"a no-op for variable declaration purposes\"));\n\t\t\t\tduk_pop(thr);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/* XXX: spilling */\n\t\t\tif (comp_ctx->curr_func.is_function) {\n\t\t\t\tduk_regconst_t reg_bind = DUK__ALLOCTEMP(comp_ctx);\n\t\t\t\t/* no need to init reg, it will be undefined on entry */\n\t\t\t\tduk_push_int(thr, (duk_int_t) reg_bind);\n\t\t\t} else {\n\t\t\t\tduk_dup_top(thr);\n\t\t\t\trc_name = duk__getconst(comp_ctx);\n\t\t\t\tduk_push_null(thr);\n\n\t\t\t\tdeclvar_flags = DUK_PROPDESC_FLAG_WRITABLE |\n\t\t\t                        DUK_PROPDESC_FLAG_ENUMERABLE;\n\t\t\t\tif (configurable_bindings) {\n\t\t\t\t\tdeclvar_flags |= DUK_PROPDESC_FLAG_CONFIGURABLE;\n\t\t\t\t}\n\n\t\t\t\tduk__emit_a_b_c(comp_ctx,\n\t\t\t\t                DUK_OP_DECLVAR | DUK__EMIT_FLAG_NO_SHUFFLE_A | DUK__EMIT_FLAG_BC_REGCONST,\n\t\t\t\t                (duk_regconst_t) declvar_flags /*flags*/,\n\t\t\t\t                rc_name /*name*/,\n\t\t\t\t                0 /*value*/);\n\t\t\t}\n\n\t\t\tduk_put_prop(thr, comp_ctx->curr_func.varmap_idx);  /* [ ... name reg/null ] -> [ ... ] */\n\t\t}\n\t}\n\n\t/*\n\t *  Wrap up\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"varmap: %!T, is_arguments_shadowed=%ld\",\n\t                     (duk_tval *) duk_get_tval(thr, comp_ctx->curr_func.varmap_idx),\n\t                     (long) comp_ctx->curr_func.is_arguments_shadowed));\n\n\tDUK_ASSERT_TOP(thr, entry_top);\n\treturn;\n\n error_outofregs:\n\tDUK_ERROR_RANGE(thr, DUK_STR_REG_LIMIT);\n\tDUK_WO_NORETURN(return;);\n\n error_argname:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_ARG_NAME);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Parse a function-body-like expression (FunctionBody or Program\n *  in E5 grammar) using a two-pass parse.  The productions appear\n *  in the following contexts:\n *\n *    - function expression\n *    - function statement\n *    - function declaration\n *    - getter in object literal\n *    - setter in object literal\n *    - global code\n *    - eval code\n *    - Function constructor body\n *\n *  This function only parses the statement list of the body; the argument\n *  list and possible function name must be initialized by the caller.\n *  For instance, for Function constructor, the argument names are originally\n *  on the value stack.  The parsing of statements ends either at an EOF or\n *  a closing brace; this is controlled by an input flag.\n *\n *  Note that there are many differences affecting parsing and even code\n *  generation:\n *\n *    - Global and eval code have an implicit return value generated\n *      by the last statement; function code does not\n *\n *    - Global code, eval code, and Function constructor body end in\n *      an EOF, other bodies in a closing brace ('}')\n *\n *  Upon entry, 'curr_tok' is ignored and the function will pull in the\n *  first token on its own.  Upon exit, 'curr_tok' is the terminating\n *  token (EOF or closing brace).\n */\n\nDUK_LOCAL void duk__parse_func_body(duk_compiler_ctx *comp_ctx, duk_bool_t expect_eof, duk_bool_t implicit_return_value, duk_bool_t regexp_after, duk_small_int_t expect_token) {\n\tduk_compiler_func *func;\n\tduk_hthread *thr;\n\tduk_regconst_t reg_stmt_value = -1;\n\tduk_lexer_point lex_pt;\n\tduk_regconst_t temp_first;\n\tduk_small_int_t compile_round = 1;\n\n\tDUK_ASSERT(comp_ctx != NULL);\n\n\tthr = comp_ctx->thr;\n\tDUK_ASSERT(thr != NULL);\n\n\tfunc = &comp_ctx->curr_func;\n\tDUK_ASSERT(func != NULL);\n\n\tDUK__RECURSION_INCREASE(comp_ctx, thr);\n\n\tduk_require_stack(thr, DUK__FUNCTION_BODY_REQUIRE_SLOTS);\n\n\t/*\n\t *  Store lexer position for a later rewind\n\t */\n\n\tDUK_LEXER_GETPOINT(&comp_ctx->lex, &lex_pt);\n\n\t/*\n\t *  Program code (global and eval code) has an implicit return value\n\t *  from the last statement value (e.g. eval(\"1; 2+3;\") returns 3).\n\t *  This is not the case with functions.  If implicit statement return\n\t *  value is requested, all statements are coerced to a register\n\t *  allocated here, and used in the implicit return statement below.\n\t */\n\n\t/* XXX: this is pointless here because pass 1 is throw-away */\n\tif (implicit_return_value) {\n\t\treg_stmt_value = DUK__ALLOCTEMP(comp_ctx);\n\n\t\t/* If an implicit return value is needed by caller, it must be\n\t\t * initialized to 'undefined' because we don't know whether any\n\t\t * non-empty (where \"empty\" is a continuation type, and different\n\t\t * from an empty statement) statements will be executed.\n\t\t *\n\t\t * However, since 1st pass is a throwaway one, no need to emit\n\t\t * it here.\n\t\t */\n#if 0\n\t\tduk__emit_bc(comp_ctx,\n\t\t             DUK_OP_LDUNDEF,\n\t\t             0);\n#endif\n\t}\n\n\t/*\n\t *  First pass.\n\t *\n\t *  Gather variable/function declarations needed for second pass.\n\t *  Code generated is dummy and discarded.\n\t */\n\n\tfunc->in_directive_prologue = 1;\n\tfunc->in_scanning = 1;\n\tfunc->may_direct_eval = 0;\n\tfunc->id_access_arguments = 0;\n\tfunc->id_access_slow = 0;\n\tfunc->id_access_slow_own = 0;\n\tfunc->reg_stmt_value = reg_stmt_value;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tfunc->min_line = DUK_INT_MAX;\n\tfunc->max_line = 0;\n#endif\n\n\t/* duk__parse_stmts() expects curr_tok to be set; parse in \"allow\n\t * regexp literal\" mode with current strictness.\n\t */\n\tif (expect_token >= 0) {\n\t\t/* Eating a left curly; regexp mode is allowed by left curly\n\t\t * based on duk__token_lbp[] automatically.\n\t\t */\n\t\tDUK_ASSERT(expect_token == DUK_TOK_LCURLY);\n\t\tduk__update_lineinfo_currtoken(comp_ctx);\n\t\tduk__advance_expect(comp_ctx, expect_token);\n\t} else {\n\t\t/* Need to set curr_token.t because lexing regexp mode depends on current\n\t\t * token type.  Zero value causes \"allow regexp\" mode.\n\t\t */\n\t\tcomp_ctx->curr_token.t = 0;\n\t\tduk__advance(comp_ctx);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"begin 1st pass\"));\n\tduk__parse_stmts(comp_ctx,\n\t                 1,             /* allow source elements */\n\t                 expect_eof,    /* expect EOF instead of } */\n\t                 regexp_after); /* regexp after */\n\tDUK_DDD(DUK_DDDPRINT(\"end 1st pass\"));\n\n\t/*\n\t *  Second (and possibly third) pass.\n\t *\n\t *  Generate actual code.  In most cases the need for shuffle\n\t *  registers is detected during pass 1, but in some corner cases\n\t *  we'll only detect it during pass 2 and a third pass is then\n\t *  needed (see GH-115).\n\t */\n\n\tfor (;;) {\n\t\tduk_bool_t needs_shuffle_before = comp_ctx->curr_func.needs_shuffle;\n\t\tcompile_round++;\n\n\t\t/*\n\t\t *  Rewind lexer.\n\t\t *\n\t\t *  duk__parse_stmts() expects curr_tok to be set; parse in \"allow regexp\n\t\t *  literal\" mode with current strictness.\n\t\t *\n\t\t *  curr_token line number info should be initialized for pass 2 before\n\t\t *  generating prologue, to ensure prologue bytecode gets nice line numbers.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"rewind lexer\"));\n\t\tDUK_LEXER_SETPOINT(&comp_ctx->lex, &lex_pt);\n\t\tcomp_ctx->curr_token.t = 0;  /* this is needed for regexp mode */\n\t\tcomp_ctx->curr_token.start_line = 0;  /* needed for line number tracking (becomes prev_token.start_line) */\n\t\tduk__advance(comp_ctx);\n\n\t\t/*\n\t\t *  Reset function state and perform register allocation, which creates\n\t\t *  'varmap' for second pass.  Function prologue for variable declarations,\n\t\t *  binding value initializations etc is emitted as a by-product.\n\t\t *\n\t\t *  Strict mode restrictions for duplicate and invalid argument\n\t\t *  names are checked here now that we know whether the function\n\t\t *  is actually strict.  See: test-dev-strict-mode-boundary.js.\n\t\t *\n\t\t *  Inner functions are compiled during pass 1 and are not reset.\n\t\t */\n\n\t\tduk__reset_func_for_pass2(comp_ctx);\n\t\tfunc->in_directive_prologue = 1;\n\t\tfunc->in_scanning = 0;\n\n\t\t/* must be able to emit code, alloc consts, etc. */\n\n\t\tduk__init_varmap_and_prologue_for_pass2(comp_ctx,\n\t\t                                        (implicit_return_value ? &reg_stmt_value : NULL));\n\t\tfunc->reg_stmt_value = reg_stmt_value;\n\n\t\ttemp_first = DUK__GETTEMP(comp_ctx);\n\n\t\tfunc->temp_first = temp_first;\n\t\tfunc->temp_next = temp_first;\n\t\tfunc->stmt_next = 0;\n\t\tfunc->label_next = 0;\n\n\t\t/* XXX: init or assert catch depth etc -- all values */\n\t\tfunc->id_access_arguments = 0;\n\t\tfunc->id_access_slow = 0;\n\t\tfunc->id_access_slow_own = 0;\n\n\t\t/*\n\t\t *  Check function name validity now that we know strictness.\n\t\t *  This only applies to function declarations and expressions,\n\t\t *  not setter/getter name.\n\t\t *\n\t\t *  See: test-dev-strict-mode-boundary.js\n\t\t */\n\n\t\tif (func->is_function && !func->is_setget && func->h_name != NULL) {\n\t\t\tif (func->is_strict) {\n\t\t\t\tif (duk__hstring_is_eval_or_arguments(comp_ctx, func->h_name)) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"func name is 'eval' or 'arguments' in strict mode\"));\n\t\t\t\t\tgoto error_funcname;\n\t\t\t\t}\n\t\t\t\tif (DUK_HSTRING_HAS_STRICT_RESERVED_WORD(func->h_name)) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"func name is a reserved word in strict mode\"));\n\t\t\t\t\tgoto error_funcname;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (DUK_HSTRING_HAS_RESERVED_WORD(func->h_name) &&\n\t\t\t\t    !DUK_HSTRING_HAS_STRICT_RESERVED_WORD(func->h_name)) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"func name is a reserved word in non-strict mode\"));\n\t\t\t\t\tgoto error_funcname;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t *  Second pass parsing.\n\t\t */\n\n\t\tif (implicit_return_value) {\n\t\t\t/* Default implicit return value. */\n\t\t\tduk__emit_bc(comp_ctx,\n\t\t\t             DUK_OP_LDUNDEF,\n\t\t\t             0);\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"begin 2nd pass\"));\n\t\tduk__parse_stmts(comp_ctx,\n\t\t                 1,             /* allow source elements */\n\t\t                 expect_eof,    /* expect EOF instead of } */\n\t\t                 regexp_after); /* regexp after */\n\t\tDUK_DDD(DUK_DDDPRINT(\"end 2nd pass\"));\n\n\t\tduk__update_lineinfo_currtoken(comp_ctx);\n\n\t\tif (needs_shuffle_before == comp_ctx->curr_func.needs_shuffle) {\n\t\t\t/* Shuffle decision not changed. */\n\t\t\tbreak;\n\t\t}\n\t\tif (compile_round >= 3) {\n\t\t\t/* Should never happen but avoid infinite loop just in case. */\n\t\t\tDUK_D(DUK_DPRINT(\"more than 3 compile passes needed, should never happen\"));\n\t\t\tDUK_ERROR_INTERNAL(thr);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tDUK_D(DUK_DPRINT(\"need additional round to compile function, round now %d\", (int) compile_round));\n\t}\n\n\t/*\n\t *  Emit a final RETURN.\n\t *\n\t *  It would be nice to avoid emitting an unnecessary \"return\" opcode\n\t *  if the current PC is not reachable.  However, this cannot be reliably\n\t *  detected; even if the previous instruction is an unconditional jump,\n\t *  there may be a previous jump which jumps to current PC (which is the\n\t *  case for iteration and conditional statements, for instance).\n\t */\n\n\t/* XXX: request a \"last statement is terminal\" from duk__parse_stmt() and duk__parse_stmts();\n\t * we could avoid the last RETURN if we could ensure there is no way to get here\n\t * (directly or via a jump)\n\t */\n\n\tDUK_ASSERT(comp_ctx->curr_func.catch_depth == 0);\n\tif (reg_stmt_value >= 0) {\n\t\tDUK_ASSERT(DUK__ISREG(reg_stmt_value));\n\t\tduk__emit_bc(comp_ctx, DUK_OP_RETREG, reg_stmt_value /*reg*/);\n\t} else {\n\t\tduk__emit_op_only(comp_ctx, DUK_OP_RETUNDEF);\n\t}\n\n\t/*\n\t *  Peephole optimize JUMP chains.\n\t */\n\n\tduk__peephole_optimize_bytecode(comp_ctx);\n\n\t/*\n\t *  comp_ctx->curr_func is now ready to be converted into an actual\n\t *  function template.\n\t */\n\n\tDUK__RECURSION_DECREASE(comp_ctx, thr);\n\treturn;\n\n error_funcname:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_FUNC_NAME);\n\tDUK_WO_NORETURN(return;);\n}\n\n/*\n *  Parse a function-like expression:\n *\n *    - function expression\n *    - function declaration\n *    - function statement (non-standard)\n *    - setter/getter\n *\n *  Adds the function to comp_ctx->curr_func function table and returns the\n *  function number.\n *\n *  On entry, curr_token points to:\n *\n *    - the token after 'function' for function expression/declaration/statement\n *    - the token after 'set' or 'get' for setter/getter\n */\n\n/* Parse formals. */\nDUK_LOCAL void duk__parse_func_formals(duk_compiler_ctx *comp_ctx) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_bool_t first = 1;\n\tduk_uarridx_t n;\n\n\tfor (;;) {\n\t\tif (comp_ctx->curr_token.t == DUK_TOK_RPAREN) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (first) {\n\t\t\t/* no comma */\n\t\t\tfirst = 0;\n\t\t} else {\n\t\t\tduk__advance_expect(comp_ctx, DUK_TOK_COMMA);\n\t\t}\n\n\t\t/* Note: when parsing a formal list in non-strict context, e.g.\n\t\t * \"implements\" is parsed as an identifier.  When the function is\n\t\t * later detected to be strict, the argument list must be rechecked\n\t\t * against a larger set of reserved words (that of strict mode).\n\t\t * This is handled by duk__parse_func_body().  Here we recognize\n\t\t * whatever tokens are considered reserved in current strictness\n\t\t * (which is not always enough).\n\t\t */\n\n\t\tif (comp_ctx->curr_token.t != DUK_TOK_IDENTIFIER) {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_EXPECTED_IDENTIFIER);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_IDENTIFIER);\n\t\tDUK_ASSERT(comp_ctx->curr_token.str1 != NULL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"formal argument: %!O\",\n\t\t                     (duk_heaphdr *) comp_ctx->curr_token.str1));\n\n\t\t/* XXX: append primitive */\n\t\tduk_push_hstring(thr, comp_ctx->curr_token.str1);\n\t\tn = (duk_uarridx_t) duk_get_length(thr, comp_ctx->curr_func.argnames_idx);\n\t\tduk_put_prop_index(thr, comp_ctx->curr_func.argnames_idx, n);\n\n\t\tduk__advance(comp_ctx);  /* eat identifier */\n\t}\n}\n\n/* Parse a function-like expression, assuming that 'comp_ctx->curr_func' is\n * correctly set up.  Assumes that curr_token is just after 'function' (or\n * 'set'/'get' etc).\n */\nDUK_LOCAL void duk__parse_func_like_raw(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_token *tok;\n\tduk_bool_t no_advance;\n\n\tDUK_ASSERT(comp_ctx->curr_func.num_formals == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_function == 1);\n\tDUK_ASSERT(comp_ctx->curr_func.is_eval == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_global == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_setget == ((flags & DUK__FUNC_FLAG_GETSET) != 0));\n\n\tduk__update_lineinfo_currtoken(comp_ctx);\n\n\t/*\n\t *  Function name (if any)\n\t *\n\t *  We don't check for prohibited names here, because we don't\n\t *  yet know whether the function will be strict.  Function body\n\t *  parsing handles this retroactively.\n\t *\n\t *  For function expressions and declarations function name must\n\t *  be an Identifer (excludes reserved words).  For setter/getter\n\t *  it is a PropertyName which allows reserved words and also\n\t *  strings and numbers (e.g. \"{ get 1() { ... } }\").\n\t *\n\t *  Function parsing may start either from prev_token or curr_token\n\t *  (object literal method definition uses prev_token for example).\n\t *  This is dealt with for the initial token.\n\t */\n\n\tno_advance = (flags & DUK__FUNC_FLAG_USE_PREVTOKEN);\n\tif (no_advance) {\n\t\ttok = &comp_ctx->prev_token;\n\t} else {\n\t\ttok = &comp_ctx->curr_token;\n\t}\n\n\tif (flags & DUK__FUNC_FLAG_GETSET) {\n\t\t/* PropertyName -> IdentifierName | StringLiteral | NumericLiteral */\n\t\tif (tok->t_nores == DUK_TOK_IDENTIFIER || tok->t == DUK_TOK_STRING) {\n\t\t\tduk_push_hstring(thr, tok->str1);       /* keep in valstack */\n\t\t} else if (tok->t == DUK_TOK_NUMBER) {\n\t\t\tduk_push_number(thr, tok->num);\n\t\t\tduk_to_string(thr, -1);\n\t\t} else {\n\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_GETSET_NAME);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\tcomp_ctx->curr_func.h_name = duk_known_hstring(thr, -1);  /* borrowed reference */\n\t} else {\n\t\t/* Function name is an Identifier (not IdentifierName), but we get\n\t\t * the raw name (not recognizing keywords) here and perform the name\n\t\t * checks only after pass 1.\n\t\t */\n\t\tif (tok->t_nores == DUK_TOK_IDENTIFIER) {\n\t\t\tduk_push_hstring(thr, tok->str1);       /* keep in valstack */\n\t\t\tcomp_ctx->curr_func.h_name = duk_known_hstring(thr, -1);  /* borrowed reference */\n\t\t} else {\n\t\t\t/* valstack will be unbalanced, which is OK */\n\t\t\tDUK_ASSERT((flags & DUK__FUNC_FLAG_GETSET) == 0);\n\t\t\tDUK_ASSERT(comp_ctx->curr_func.h_name == NULL);\n\t\t\tno_advance = 1;\n\t\t\tif (flags & DUK__FUNC_FLAG_DECL) {\n\t\t\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_FUNC_NAME_REQUIRED);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t}\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"function name: %!O\",\n\t                   (duk_heaphdr *) comp_ctx->curr_func.h_name));\n\n\tif (!no_advance) {\n\t\tduk__advance(comp_ctx);\n\t}\n\n\t/*\n\t *  Formal argument list\n\t *\n\t *  We don't check for prohibited names or for duplicate argument\n\t *  names here, becase we don't yet know whether the function will\n\t *  be strict.  Function body parsing handles this retroactively.\n\t */\n\n\tduk__advance_expect(comp_ctx, DUK_TOK_LPAREN);\n\n\tduk__parse_func_formals(comp_ctx);\n\n\tDUK_ASSERT(comp_ctx->curr_token.t == DUK_TOK_RPAREN);\n\tduk__advance(comp_ctx);\n\n\t/*\n\t *  Parse function body\n\t */\n\n\tduk__parse_func_body(comp_ctx,\n\t                     0,   /* expect_eof */\n\t                     0,   /* implicit_return_value */\n\t                     flags & DUK__FUNC_FLAG_DECL, /* regexp_after */\n\t                     DUK_TOK_LCURLY);  /* expect_token */\n\n\t/*\n\t *  Convert duk_compiler_func to a function template and add it\n\t *  to the parent function table.\n\t */\n\n\tduk__convert_to_func_template(comp_ctx);  /* -> [ ... func ] */\n}\n\n/* Parse an inner function, adding the function template to the current function's\n * function table.  Return a function number to be used by the outer function.\n *\n * Avoiding O(depth^2) inner function parsing is handled here.  On the first pass,\n * compile and register the function normally into the 'funcs' array, also recording\n * a lexer point (offset/line) to the closing brace of the function.  On the second\n * pass, skip the function and return the same 'fnum' as on the first pass by using\n * a running counter.\n *\n * An unfortunate side effect of this is that when parsing the inner function, almost\n * nothing is known of the outer function, i.e. the inner function's scope.  We don't\n * need that information at the moment, but it would allow some optimizations if it\n * were used.\n */\nDUK_LOCAL duk_int_t duk__parse_func_like_fnum(duk_compiler_ctx *comp_ctx, duk_small_uint_t flags) {\n\tduk_hthread *thr = comp_ctx->thr;\n\tduk_compiler_func old_func;\n\tduk_idx_t entry_top;\n\tduk_int_t fnum;\n\n\t/*\n\t *  On second pass, skip the function.\n\t */\n\n\tif (!comp_ctx->curr_func.in_scanning) {\n\t\tduk_lexer_point lex_pt;\n\n\t\tfnum = comp_ctx->curr_func.fnum_next++;\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 1));\n\t\tlex_pt.offset = (duk_size_t) duk_to_uint(thr, -1);\n\t\tduk_pop(thr);\n\t\tduk_get_prop_index(thr, comp_ctx->curr_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 2));\n\t\tlex_pt.line = duk_to_int(thr, -1);\n\t\tduk_pop(thr);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"second pass of an inner func, skip the function, reparse closing brace; lex offset=%ld, line=%ld\",\n\t\t                     (long) lex_pt.offset, (long) lex_pt.line));\n\n\t\tDUK_LEXER_SETPOINT(&comp_ctx->lex, &lex_pt);\n\t\tcomp_ctx->curr_token.t = 0;  /* this is needed for regexp mode */\n\t\tcomp_ctx->curr_token.start_line = 0;  /* needed for line number tracking (becomes prev_token.start_line) */\n\t\tduk__advance(comp_ctx);\n\n\t\t/* RegExp is not allowed after a function expression, e.g. in\n\t\t * (function () {} / 123).  A RegExp *is* allowed after a\n\t\t * function declaration!\n\t\t */\n\t\tif (flags & DUK__FUNC_FLAG_DECL) {\n\t\t\tcomp_ctx->curr_func.allow_regexp_in_adv = 1;\n\t\t}\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_RCURLY);\n\n\t\treturn fnum;\n\t}\n\n\t/*\n\t *  On first pass, perform actual parsing.  Remember valstack top on entry\n\t *  to restore it later, and switch to using a new function in comp_ctx.\n\t */\n\n\tentry_top = duk_get_top(thr);\n\tDUK_DDD(DUK_DDDPRINT(\"before func: entry_top=%ld, curr_tok.start_offset=%ld\",\n\t                     (long) entry_top, (long) comp_ctx->curr_token.start_offset));\n\n\tduk_memcpy(&old_func, &comp_ctx->curr_func, sizeof(duk_compiler_func));\n\n\tduk_memzero(&comp_ctx->curr_func, sizeof(duk_compiler_func));\n\tduk__init_func_valstack_slots(comp_ctx);\n\tDUK_ASSERT(comp_ctx->curr_func.num_formals == 0);\n\n\t/* inherit initial strictness from parent */\n\tcomp_ctx->curr_func.is_strict = old_func.is_strict;\n\n\t/* XXX: It might be better to just store the flags into the curr_func\n\t * struct and use them as is without this flag interpretation step\n\t * here.\n\t */\n\tDUK_ASSERT(comp_ctx->curr_func.is_notail == 0);\n\tcomp_ctx->curr_func.is_function = 1;\n\tDUK_ASSERT(comp_ctx->curr_func.is_eval == 0);\n\tDUK_ASSERT(comp_ctx->curr_func.is_global == 0);\n\tcomp_ctx->curr_func.is_setget = ((flags & DUK__FUNC_FLAG_GETSET) != 0);\n\tcomp_ctx->curr_func.is_namebinding = !(flags & (DUK__FUNC_FLAG_GETSET |\n\t                                                DUK__FUNC_FLAG_METDEF |\n\t                                                DUK__FUNC_FLAG_DECL));  /* no name binding for: declarations, objlit getset, objlit method def */\n\tcomp_ctx->curr_func.is_constructable = !(flags & (DUK__FUNC_FLAG_GETSET |\n\t                                                  DUK__FUNC_FLAG_METDEF));  /* not constructable: objlit getset, objlit method def */\n\n\t/*\n\t *  Parse inner function\n\t */\n\n\tduk__parse_func_like_raw(comp_ctx, flags);  /* pushes function template */\n\n\t/* prev_token.start_offset points to the closing brace here; when skipping\n\t * we're going to reparse the closing brace to ensure semicolon insertion\n\t * etc work as expected.\n\t */\n\tDUK_DDD(DUK_DDDPRINT(\"after func: prev_tok.start_offset=%ld, curr_tok.start_offset=%ld\",\n\t                     (long) comp_ctx->prev_token.start_offset, (long) comp_ctx->curr_token.start_offset));\n\tDUK_ASSERT(comp_ctx->lex.input[comp_ctx->prev_token.start_offset] == (duk_uint8_t) DUK_ASC_RCURLY);\n\n\t/* XXX: append primitive */\n\tDUK_ASSERT(duk_get_length(thr, old_func.funcs_idx) == (duk_size_t) (old_func.fnum_next * 3));\n\tfnum = old_func.fnum_next++;\n\n\tif (fnum > DUK__MAX_FUNCS) {\n\t\tDUK_ERROR_RANGE(comp_ctx->thr, DUK_STR_FUNC_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\n\t/* array writes autoincrement length */\n\t(void) duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3));\n\tduk_push_size_t(thr, comp_ctx->prev_token.start_offset);\n\t(void) duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 1));\n\tduk_push_int(thr, comp_ctx->prev_token.start_line);\n\t(void) duk_put_prop_index(thr, old_func.funcs_idx, (duk_uarridx_t) (fnum * 3 + 2));\n\n\t/*\n\t *  Cleanup: restore original function, restore valstack state.\n\t *\n\t *  Function declaration handling needs the function name to be pushed\n\t *  on the value stack.\n\t */\n\n\tif (flags & DUK__FUNC_FLAG_PUSHNAME_PASS1) {\n\t\tDUK_ASSERT(comp_ctx->curr_func.h_name != NULL);\n\t\tduk_push_hstring(thr, comp_ctx->curr_func.h_name);\n\t\tduk_replace(thr, entry_top);\n\t\tduk_set_top(thr, entry_top + 1);\n\t} else {\n\t\tduk_set_top(thr, entry_top);\n\t}\n\tduk_memcpy((void *) &comp_ctx->curr_func, (void *) &old_func, sizeof(duk_compiler_func));\n\n\treturn fnum;\n}\n\n/*\n *  Compile input string into an executable function template without\n *  arguments.\n *\n *  The string is parsed as the \"Program\" production of ECMAScript E5.\n *  Compilation context can be either global code or eval code (see E5\n *  Sections 14 and 15.1.2.1).\n *\n *  Input stack:  [ ... filename ]\n *  Output stack: [ ... func_template ]\n */\n\n/* XXX: source code property */\n\nDUK_LOCAL duk_ret_t duk__js_compile_raw(duk_hthread *thr, void *udata) {\n\tduk_hstring *h_filename;\n\tduk__compiler_stkstate *comp_stk;\n\tduk_compiler_ctx *comp_ctx;\n\tduk_lexer_point *lex_pt;\n\tduk_compiler_func *func;\n\tduk_idx_t entry_top;\n\tduk_bool_t is_strict;\n\tduk_bool_t is_eval;\n\tduk_bool_t is_funcexpr;\n\tduk_small_uint_t flags;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(udata != NULL);\n\n\t/*\n\t *  Arguments check\n\t */\n\n\tentry_top = duk_get_top(thr);\n\tDUK_ASSERT(entry_top >= 1);\n\n\tcomp_stk = (duk__compiler_stkstate *) udata;\n\tcomp_ctx = &comp_stk->comp_ctx_alloc;\n\tlex_pt = &comp_stk->lex_pt_alloc;\n\tDUK_ASSERT(comp_ctx != NULL);\n\tDUK_ASSERT(lex_pt != NULL);\n\n\tflags = comp_stk->flags;\n\tis_eval = (flags & DUK_COMPILE_EVAL ? 1 : 0);\n\tis_strict = (flags & DUK_COMPILE_STRICT ? 1 : 0);\n\tis_funcexpr = (flags & DUK_COMPILE_FUNCEXPR ? 1 : 0);\n\n\th_filename = duk_get_hstring(thr, -1);  /* may be undefined */\n\n\t/*\n\t *  Init compiler and lexer contexts\n\t */\n\n\tfunc = &comp_ctx->curr_func;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tcomp_ctx->thr = NULL;\n\tcomp_ctx->h_filename = NULL;\n\tcomp_ctx->prev_token.str1 = NULL;\n\tcomp_ctx->prev_token.str2 = NULL;\n\tcomp_ctx->curr_token.str1 = NULL;\n\tcomp_ctx->curr_token.str2 = NULL;\n#endif\n\n\tduk_require_stack(thr, DUK__COMPILE_ENTRY_SLOTS);\n\n\tduk_push_dynamic_buffer(thr, 0);       /* entry_top + 0 */\n\tduk_push_undefined(thr);               /* entry_top + 1 */\n\tduk_push_undefined(thr);               /* entry_top + 2 */\n\tduk_push_undefined(thr);               /* entry_top + 3 */\n\tduk_push_undefined(thr);               /* entry_top + 4 */\n\n\tcomp_ctx->thr = thr;\n\tcomp_ctx->h_filename = h_filename;\n\tcomp_ctx->tok11_idx = entry_top + 1;\n\tcomp_ctx->tok12_idx = entry_top + 2;\n\tcomp_ctx->tok21_idx = entry_top + 3;\n\tcomp_ctx->tok22_idx = entry_top + 4;\n\tcomp_ctx->recursion_limit = DUK_USE_COMPILER_RECLIMIT;\n\n\t/* comp_ctx->lex has been pre-initialized by caller: it has been\n\t * zeroed and input/input_length has been set.\n\t */\n\tcomp_ctx->lex.thr = thr;\n\t/* comp_ctx->lex.input and comp_ctx->lex.input_length filled by caller */\n\tcomp_ctx->lex.slot1_idx = comp_ctx->tok11_idx;\n\tcomp_ctx->lex.slot2_idx = comp_ctx->tok12_idx;\n\tcomp_ctx->lex.buf_idx = entry_top + 0;\n\tcomp_ctx->lex.buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, entry_top + 0);\n\tDUK_ASSERT(DUK_HBUFFER_HAS_DYNAMIC(comp_ctx->lex.buf) && !DUK_HBUFFER_HAS_EXTERNAL(comp_ctx->lex.buf));\n\tcomp_ctx->lex.token_limit = DUK_COMPILER_TOKEN_LIMIT;\n\n\tlex_pt->offset = 0;\n\tlex_pt->line = 1;\n\tDUK_LEXER_SETPOINT(&comp_ctx->lex, lex_pt);    /* fills window */\n\tcomp_ctx->curr_token.start_line = 0;  /* needed for line number tracking (becomes prev_token.start_line) */\n\n\t/*\n\t *  Initialize function state for a zero-argument function\n\t */\n\n\tduk__init_func_valstack_slots(comp_ctx);\n\tDUK_ASSERT(func->num_formals == 0);\n\n\tif (is_funcexpr) {\n\t\t/* Name will be filled from function expression, not by caller.\n\t\t * This case is used by Function constructor and duk_compile()\n\t\t * API with the DUK_COMPILE_FUNCTION option.\n\t\t */\n\t\tDUK_ASSERT(func->h_name == NULL);\n\t} else {\n\t\tduk_push_hstring_stridx(thr, (is_eval ? DUK_STRIDX_EVAL :\n\t\t                                        DUK_STRIDX_GLOBAL));\n\t\tfunc->h_name = duk_get_hstring(thr, -1);\n\t}\n\n\t/*\n\t *  Parse a function body or a function-like expression, depending\n\t *  on flags.\n\t */\n\n\tDUK_ASSERT(func->is_setget == 0);\n\tfunc->is_strict = (duk_uint8_t) is_strict;\n\tDUK_ASSERT(func->is_notail == 0);\n\n\tif (is_funcexpr) {\n\t\tfunc->is_function = 1;\n\t\tDUK_ASSERT(func->is_eval == 0);\n\t\tDUK_ASSERT(func->is_global == 0);\n\t\tfunc->is_namebinding = 1;\n\t\tfunc->is_constructable = 1;\n\n\t\tduk__advance(comp_ctx);  /* init 'curr_token' */\n\t\tduk__advance_expect(comp_ctx, DUK_TOK_FUNCTION);\n\t\t(void) duk__parse_func_like_raw(comp_ctx, 0 /*flags*/);\n\t} else {\n\t\tDUK_ASSERT(func->is_function == 0);\n\t\tDUK_ASSERT(is_eval == 0 || is_eval == 1);\n\t\tfunc->is_eval = (duk_uint8_t) is_eval;\n\t\tfunc->is_global = (duk_uint8_t) !is_eval;\n\t\tDUK_ASSERT(func->is_namebinding == 0);\n\t\tDUK_ASSERT(func->is_constructable == 0);\n\n\t\tduk__parse_func_body(comp_ctx,\n\t\t                     1,             /* expect_eof */\n\t\t                     1,             /* implicit_return_value */\n\t\t                     1,             /* regexp_after (does not matter) */\n\t\t                     -1);           /* expect_token */\n\t}\n\n\t/*\n\t *  Convert duk_compiler_func to a function template\n\t */\n\n\tduk__convert_to_func_template(comp_ctx);\n\n\t/*\n\t *  Wrapping duk_safe_call() will mangle the stack, just return stack top\n\t */\n\n\t/* [ ... filename (temps) func ] */\n\n\treturn 1;\n}\n\nDUK_INTERNAL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer, duk_size_t src_length, duk_small_uint_t flags) {\n\tduk__compiler_stkstate comp_stk;\n\tduk_compiler_ctx *prev_ctx;\n\tduk_ret_t safe_rc;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(src_buffer != NULL);\n\n\t/* preinitialize lexer state partially */\n\tduk_memzero(&comp_stk, sizeof(comp_stk));\n\tcomp_stk.flags = flags;\n\tDUK_LEXER_INITCTX(&comp_stk.comp_ctx_alloc.lex);\n\tcomp_stk.comp_ctx_alloc.lex.input = src_buffer;\n\tcomp_stk.comp_ctx_alloc.lex.input_length = src_length;\n\tcomp_stk.comp_ctx_alloc.lex.flags = flags;  /* Forward flags directly for now. */\n\n\t/* [ ... filename ] */\n\n\tprev_ctx = thr->compile_ctx;\n\tthr->compile_ctx = &comp_stk.comp_ctx_alloc;  /* for duk_error_augment.c */\n\tsafe_rc = duk_safe_call(thr, duk__js_compile_raw, (void *) &comp_stk /*udata*/, 1 /*nargs*/, 1 /*nrets*/);\n\tthr->compile_ctx = prev_ctx;  /* must restore reliably before returning */\n\n\tif (safe_rc != DUK_EXEC_SUCCESS) {\n\t\tDUK_D(DUK_DPRINT(\"compilation failed: %!T\", duk_get_tval(thr, -1)));\n\t\t(void) duk_throw(thr);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/* [ ... template ] */\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_js_compiler.h",
    "content": "/*\n *  ECMAScript compiler.\n */\n\n#if !defined(DUK_JS_COMPILER_H_INCLUDED)\n#define DUK_JS_COMPILER_H_INCLUDED\n\n/* ECMAScript compiler limits */\n#define DUK_COMPILER_TOKEN_LIMIT           100000000L  /* 1e8: protects against deeply nested inner functions */\n\n/* maximum loopcount for peephole optimization */\n#define DUK_COMPILER_PEEPHOLE_MAXITER      3\n\n/* maximum bytecode length in instructions */\n#define DUK_COMPILER_MAX_BYTECODE_LENGTH   (256L * 1024L * 1024L)  /* 1 GB */\n\n/*\n *  Compiler intermediate values\n *\n *  Intermediate values describe either plain values (e.g. strings or\n *  numbers) or binary operations which have not yet been coerced into\n *  either a left-hand-side or right-hand-side role (e.g. object property).\n */\n\n#define DUK_IVAL_NONE          0   /* no value */\n#define DUK_IVAL_PLAIN         1   /* register, constant, or value */\n#define DUK_IVAL_ARITH         2   /* binary arithmetic; DUK_OP_ADD, DUK_OP_EQ, other binary ops */\n#define DUK_IVAL_PROP          3   /* property access */\n#define DUK_IVAL_VAR           4   /* variable access */\n\n#define DUK_ISPEC_NONE         0   /* no value */\n#define DUK_ISPEC_VALUE        1   /* value resides in 'valstack_idx' */\n#define DUK_ISPEC_REGCONST     2   /* value resides in a register or constant */\n\n/* Bit mask which indicates that a regconst is a constant instead of a register.\n * Chosen so that when a regconst is cast to duk_int32_t, all consts are\n * negative values.\n */\n#define DUK_REGCONST_CONST_MARKER    DUK_INT32_MIN  /* = -0x80000000 */\n\n/* Type to represent a reg/const reference during compilation, with <0\n * indicating a constant.  Some call sites also use -1 to indicate 'none'.\n */\ntypedef duk_int32_t duk_regconst_t;\n\ntypedef struct {\n\tduk_small_uint_t t;          /* DUK_ISPEC_XXX */\n\tduk_regconst_t regconst;\n\tduk_idx_t valstack_idx;      /* always set; points to a reserved valstack slot */\n} duk_ispec;\n\ntypedef struct {\n\t/*\n\t *  PLAIN: x1\n\t *  ARITH: x1 <op> x2\n\t *  PROP: x1.x2\n\t *  VAR: x1 (name)\n\t */\n\n\t/* XXX: can be optimized for smaller footprint esp. on 32-bit environments */\n\tduk_small_uint_t t;          /* DUK_IVAL_XXX */\n\tduk_small_uint_t op;         /* bytecode opcode for binary ops */\n\tduk_ispec x1;\n\tduk_ispec x2;\n} duk_ivalue;\n\n/*\n *  Bytecode instruction representation during compilation\n *\n *  Contains the actual instruction and (optionally) debug info.\n */\n\nstruct duk_compiler_instr {\n\tduk_instr_t ins;\n#if defined(DUK_USE_PC2LINE)\n\tduk_uint32_t line;\n#endif\n};\n\n/*\n *  Compiler state\n */\n\n#define DUK_LABEL_FLAG_ALLOW_BREAK       (1U << 0)\n#define DUK_LABEL_FLAG_ALLOW_CONTINUE    (1U << 1)\n\n#define DUK_DECL_TYPE_VAR                0\n#define DUK_DECL_TYPE_FUNC               1\n\n/* XXX: optimize to 16 bytes */\ntypedef struct {\n\tduk_small_uint_t flags;\n\tduk_int_t label_id;          /* numeric label_id (-1 reserved as marker) */\n\tduk_hstring *h_label;        /* borrowed label name */\n\tduk_int_t catch_depth;       /* catch depth at point of definition */\n\tduk_int_t pc_label;          /* pc of label statement:\n\t                              * pc+1: break jump site\n\t                              * pc+2: continue jump site\n\t                              */\n\n\t/* Fast jumps (which avoid longjmp) jump directly to the jump sites\n\t * which are always known even while the iteration/switch statement\n\t * is still being parsed.  A final peephole pass \"straightens out\"\n\t * the jumps.\n\t */\n} duk_labelinfo;\n\n/* Compiling state of one function, eventually converted to duk_hcompfunc */\nstruct duk_compiler_func {\n\t/* These pointers are at the start of the struct so that they pack\n\t * nicely.  Mixing pointers and integer values is bad on some\n\t * platforms (e.g. if int is 32 bits and pointers are 64 bits).\n\t */\n\n\tduk_bufwriter_ctx bw_code;          /* bufwriter for code */\n\n\tduk_hstring *h_name;                /* function name (borrowed reference), ends up in _name */\n\t/* h_code: held in bw_code */\n\tduk_hobject *h_consts;              /* array */\n\tduk_hobject *h_funcs;               /* array of function templates: [func1, offset1, line1, func2, offset2, line2]\n\t                                     * offset/line points to closing brace to allow skipping on pass 2\n\t                                     */\n\tduk_hobject *h_decls;               /* array of declarations: [ name1, val1, name2, val2, ... ]\n\t                                     * valN = (typeN) | (fnum << 8), where fnum is inner func number (0 for vars)\n\t                                     * record function and variable declarations in pass 1\n\t                                     */\n\tduk_hobject *h_labelnames;          /* array of active label names */\n\tduk_hbuffer_dynamic *h_labelinfos;  /* C array of duk_labelinfo */\n\tduk_hobject *h_argnames;            /* array of formal argument names (-> _Formals) */\n\tduk_hobject *h_varmap;              /* variable map for pass 2 (identifier -> register number or null (unmapped)) */\n\n\t/* Value stack indices for tracking objects. */\n\t/* code_idx: not needed */\n\tduk_idx_t consts_idx;\n\tduk_idx_t funcs_idx;\n\tduk_idx_t decls_idx;\n\tduk_idx_t labelnames_idx;\n\tduk_idx_t labelinfos_idx;\n\tduk_idx_t argnames_idx;\n\tduk_idx_t varmap_idx;\n\n\t/* Temp reg handling. */\n\tduk_regconst_t temp_first;           /* first register that is a temporary (below: variables) */\n\tduk_regconst_t temp_next;            /* next temporary register to allocate */\n\tduk_regconst_t temp_max;             /* highest value of temp_reg (temp_max - 1 is highest used reg) */\n\n\t/* Shuffle registers if large number of regs/consts. */\n\tduk_regconst_t shuffle1;\n\tduk_regconst_t shuffle2;\n\tduk_regconst_t shuffle3;\n\n\t/* Stats for current expression being parsed. */\n\tduk_int_t nud_count;\n\tduk_int_t led_count;\n\tduk_int_t paren_level;              /* parenthesis count, 0 = top level */\n\tduk_bool_t expr_lhs;                /* expression is left-hand-side compatible */\n\tduk_bool_t allow_in;                /* current paren level allows 'in' token */\n\n\t/* Misc. */\n\tduk_int_t stmt_next;                /* statement id allocation (running counter) */\n\tduk_int_t label_next;               /* label id allocation (running counter) */\n\tduk_int_t catch_depth;              /* catch stack depth */\n\tduk_int_t with_depth;               /* with stack depth (affects identifier lookups) */\n\tduk_int_t fnum_next;                /* inner function numbering */\n\tduk_int_t num_formals;              /* number of formal arguments */\n\tduk_regconst_t reg_stmt_value;      /* register for writing value of 'non-empty' statements (global or eval code), -1 is marker */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tduk_int_t min_line;                 /* XXX: typing (duk_hcompfunc has duk_uint32_t) */\n\tduk_int_t max_line;\n#endif\n\n\t/* Status booleans. */\n\tduk_uint8_t is_function;             /* is an actual function (not global/eval code) */\n\tduk_uint8_t is_eval;                 /* is eval code */\n\tduk_uint8_t is_global;               /* is global code */\n\tduk_uint8_t is_namebinding;          /* needs a name binding */\n\tduk_uint8_t is_constructable;        /* result is constructable */\n\tduk_uint8_t is_setget;               /* is a setter/getter */\n\tduk_uint8_t is_strict;               /* function is strict */\n\tduk_uint8_t is_notail;               /* function must not be tail called */\n\tduk_uint8_t in_directive_prologue;   /* parsing in \"directive prologue\", recognize directives */\n\tduk_uint8_t in_scanning;             /* parsing in \"scanning\" phase (first pass) */\n\tduk_uint8_t may_direct_eval;         /* function may call direct eval */\n\tduk_uint8_t id_access_arguments;     /* function refers to 'arguments' identifier */\n\tduk_uint8_t id_access_slow;          /* function makes one or more slow path accesses that won't match own static variables */\n\tduk_uint8_t id_access_slow_own;      /* function makes one or more slow path accesses that may match own static variables */\n\tduk_uint8_t is_arguments_shadowed;   /* argument/function declaration shadows 'arguments' */\n\tduk_uint8_t needs_shuffle;           /* function needs shuffle registers */\n\tduk_uint8_t reject_regexp_in_adv;    /* reject RegExp literal on next advance() call; needed for handling IdentifierName productions */\n\tduk_uint8_t allow_regexp_in_adv;     /* allow RegExp literal on next advance() call */\n};\n\nstruct duk_compiler_ctx {\n\tduk_hthread *thr;\n\n\t/* filename being compiled (ends up in functions' '_filename' property) */\n\tduk_hstring *h_filename;            /* borrowed reference */\n\n\t/* lexing (tokenization) state (contains two valstack slot indices) */\n\tduk_lexer_ctx lex;\n\n\t/* current and previous token for parsing */\n\tduk_token prev_token;\n\tduk_token curr_token;\n\tduk_idx_t tok11_idx;                /* curr_token slot1 (matches 'lex' slot1_idx) */\n\tduk_idx_t tok12_idx;                /* curr_token slot2 (matches 'lex' slot2_idx) */\n\tduk_idx_t tok21_idx;                /* prev_token slot1 */\n\tduk_idx_t tok22_idx;                /* prev_token slot2 */\n\n\t/* recursion limit */\n\tduk_int_t recursion_depth;\n\tduk_int_t recursion_limit;\n\n\t/* code emission temporary */\n\tduk_int_t emit_jumpslot_pc;\n\n\t/* current function being compiled (embedded instead of pointer for more compact access) */\n\tduk_compiler_func curr_func;\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_js_compile(duk_hthread *thr, const duk_uint8_t *src_buffer, duk_size_t src_length, duk_small_uint_t flags);\n\n#endif  /* DUK_JS_COMPILER_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_js_executor.c",
    "content": "/*\n *  ECMAScript bytecode executor.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Local declarations.\n */\n\nDUK_LOCAL_DECL void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, duk_activation *entry_act);\n\n/*\n *  Misc helpers.\n */\n\n/* Forced inline declaration, only applied for performance oriented build. */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n#define DUK__INLINE_PERF\n#define DUK__NOINLINE_PERF\n#else\n#define DUK__INLINE_PERF DUK_ALWAYS_INLINE\n#define DUK__NOINLINE_PERF DUK_NOINLINE\n#endif\n\n/* Replace value stack top to value at 'tv_ptr'.  Optimize for\n * performance by only applying the net refcount change.\n */\n#define DUK__REPLACE_TO_TVPTR(thr,tv_ptr) do { \\\n\t\tduk_hthread *duk__thr; \\\n\t\tduk_tval *duk__tvsrc; \\\n\t\tduk_tval *duk__tvdst; \\\n\t\tduk_tval duk__tvtmp; \\\n\t\tduk__thr = (thr); \\\n\t\tduk__tvsrc = DUK_GET_TVAL_NEGIDX(duk__thr, -1); \\\n\t\tduk__tvdst = (tv_ptr); \\\n\t\tDUK_TVAL_SET_TVAL(&duk__tvtmp, duk__tvdst); \\\n\t\tDUK_TVAL_SET_TVAL(duk__tvdst, duk__tvsrc); \\\n\t\tDUK_TVAL_SET_UNDEFINED(duk__tvsrc);  /* value stack init policy */ \\\n\t\tduk__thr->valstack_top = duk__tvsrc; \\\n\t\tDUK_TVAL_DECREF(duk__thr, &duk__tvtmp); \\\n\t} while (0)\n\n/* XXX: candidate of being an internal shared API call */\n#if 0  /* unused */\nDUK_LOCAL void duk__push_tvals_incref_only(duk_hthread *thr, duk_tval *tv_src, duk_small_uint_fast_t count) {\n\tduk_tval *tv_dst;\n\tduk_size_t copy_size;\n\tduk_size_t i;\n\n\ttv_dst = thr->valstack_top;\n\tcopy_size = sizeof(duk_tval) * count;\n\tduk_memcpy((void *) tv_dst, (const void *) tv_src, copy_size);\n\tfor (i = 0; i < count; i++) {\n\t\tDUK_TVAL_INCREF(thr, tv_dst);\n\t\ttv_dst++;\n\t}\n\tthr->valstack_top = tv_dst;\n}\n#endif\n\n/*\n *  Arithmetic, binary, and logical helpers.\n *\n *  Note: there is no opcode for logical AND or logical OR; this is on\n *  purpose, because the evalution order semantics for them make such\n *  opcodes pretty pointless: short circuiting means they are most\n *  comfortably implemented as jumps.  However, a logical NOT opcode\n *  is useful.\n *\n *  Note: careful with duk_tval pointers here: they are potentially\n *  invalidated by any DECREF and almost any API call.  It's still\n *  preferable to work without making a copy but that's not always\n *  possible.\n */\n\nDUK_LOCAL DUK__INLINE_PERF duk_double_t duk__compute_mod(duk_double_t d1, duk_double_t d2) {\n\treturn (duk_double_t) duk_js_arith_mod((double) d1, (double) d2);\n}\n\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\nDUK_LOCAL DUK__INLINE_PERF duk_double_t duk__compute_exp(duk_double_t d1, duk_double_t d2) {\n\treturn (duk_double_t) duk_js_arith_pow((double) d1, (double) d2);\n}\n#endif\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_add(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_fast_t idx_z) {\n\t/*\n\t *  Addition operator is different from other arithmetic\n\t *  operations in that it also provides string concatenation.\n\t *  Hence it is implemented separately.\n\t *\n\t *  There is a fast path for number addition.  Other cases go\n\t *  through potentially multiple coercions as described in the\n\t *  E5 specification.  It may be possible to reduce the number\n\t *  of coercions, but this must be done carefully to preserve\n\t *  the exact semantics.\n\t *\n\t *  E5 Section 11.6.1.\n\t *\n\t *  Custom types also have special behavior implemented here.\n\t */\n\n\tduk_double_union du;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_x != NULL);  /* may be reg or const */\n\tDUK_ASSERT(tv_y != NULL);  /* may be reg or const */\n\tDUK_ASSERT_DISABLE(idx_z >= 0);  /* unsigned */\n\tDUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr));\n\n\t/*\n\t *  Fast paths\n\t */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\tduk_int64_t v1, v2, v3;\n\t\tduk_int32_t v3_hi;\n\t\tduk_tval *tv_z;\n\n\t\t/* Input values are signed 48-bit so we can detect overflow\n\t\t * reliably from high bits or just a comparison.\n\t\t */\n\n\t\tv1 = DUK_TVAL_GET_FASTINT(tv_x);\n\t\tv2 = DUK_TVAL_GET_FASTINT(tv_y);\n\t\tv3 = v1 + v2;\n\t\tv3_hi = (duk_int32_t) (v3 >> 32);\n\t\tif (DUK_LIKELY(v3_hi >= DUK_I64_CONSTANT(-0x8000) && v3_hi <= DUK_I64_CONSTANT(0x7fff))) {\n\t\t\ttv_z = thr->valstack_bottom + idx_z;\n\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, v3);  /* side effects */\n\t\t\treturn;\n\t\t} else {\n\t\t\t/* overflow, fall through */\n\t\t\t;\n\t\t}\n\t}\n#endif  /* DUK_USE_FASTINT */\n\n\tif (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) {\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tduk_tval *tv_z;\n#endif\n\n\t\tdu.d = DUK_TVAL_GET_NUMBER(tv_x) + DUK_TVAL_GET_NUMBER(tv_y);\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tduk_push_number(thr, du.d);  /* will NaN normalize result */\n\t\tduk_replace(thr, (duk_idx_t) idx_z);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\t\ttv_z = thr->valstack_bottom + idx_z;\n\t\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, du.d);  /* side effects */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\treturn;\n\t}\n\n\t/*\n\t *  Slow path: potentially requires function calls for coercion\n\t */\n\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\tduk_to_primitive(thr, -2, DUK_HINT_NONE);  /* side effects -> don't use tv_x, tv_y after */\n\tduk_to_primitive(thr, -1, DUK_HINT_NONE);\n\n\t/* Since Duktape 2.x plain buffers are treated like ArrayBuffer. */\n\tif (duk_is_string(thr, -2) || duk_is_string(thr, -1)) {\n\t\t/* Symbols shouldn't technically be handled here, but should\n\t\t * go into the default ToNumber() coercion path instead and\n\t\t * fail there with a TypeError.  However, there's a ToString()\n\t\t * in duk_concat_2() which also fails with TypeError so no\n\t\t * explicit check is needed.\n\t\t */\n\t\tduk_concat_2(thr);  /* [... s1 s2] -> [... s1+s2] */\n\t} else {\n\t\tduk_double_t d1, d2;\n\n\t\td1 = duk_to_number_m2(thr);\n\t\td2 = duk_to_number_m1(thr);\n\t\tDUK_ASSERT(duk_is_number(thr, -2));\n\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d1);\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d2);\n\n\t\tdu.d = d1 + d2;\n\t\tduk_pop_2_unsafe(thr);\n\t\tduk_push_number(thr, du.d);  /* will NaN normalize result */\n\t}\n\tduk_replace(thr, (duk_idx_t) idx_z);  /* side effects */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_binary_op(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_uint_fast_t idx_z, duk_small_uint_fast_t opcode) {\n\t/*\n\t *  Arithmetic operations other than '+' have number-only semantics\n\t *  and are implemented here.  The separate switch-case here means a\n\t *  \"double dispatch\" of the arithmetic opcode, but saves code space.\n\t *\n\t *  E5 Sections 11.5, 11.5.1, 11.5.2, 11.5.3, 11.6, 11.6.1, 11.6.2, 11.6.3.\n\t */\n\n\tduk_double_t d1, d2;\n\tduk_double_union du;\n\tduk_small_uint_fast_t opcode_shifted;\n#if defined(DUK_USE_FASTINT) || !defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_tval *tv_z;\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_x != NULL);  /* may be reg or const */\n\tDUK_ASSERT(tv_y != NULL);  /* may be reg or const */\n\tDUK_ASSERT_DISABLE(idx_z >= 0);  /* unsigned */\n\tDUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr));\n\n\topcode_shifted = opcode >> 2;  /* Get base opcode without reg/const modifiers. */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\tduk_int64_t v1, v2, v3;\n\t\tduk_int32_t v3_hi;\n\n\t\tv1 = DUK_TVAL_GET_FASTINT(tv_x);\n\t\tv2 = DUK_TVAL_GET_FASTINT(tv_y);\n\n\t\tswitch (opcode_shifted) {\n\t\tcase DUK_OP_SUB >> 2: {\n\t\t\tv3 = v1 - v2;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL >> 2: {\n\t\t\t/* Must ensure result is 64-bit (no overflow); a\n\t\t\t * simple and sufficient fast path is to allow only\n\t\t\t * 32-bit inputs.  Avoid zero inputs to avoid\n\t\t\t * negative zero issues (-1 * 0 = -0, for instance).\n\t\t\t */\n\t\t\tif (v1 >= DUK_I64_CONSTANT(-0x80000000) && v1 <= DUK_I64_CONSTANT(0x7fffffff) && v1 != 0 &&\n\t\t\t    v2 >= DUK_I64_CONSTANT(-0x80000000) && v2 <= DUK_I64_CONSTANT(0x7fffffff) && v2 != 0) {\n\t\t\t\tv3 = v1 * v2;\n\t\t\t} else {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV >> 2: {\n\t\t\t/* Don't allow a zero divisor.  Fast path check by\n\t\t\t * \"verifying\" with multiplication.  Also avoid zero\n\t\t\t * dividend to avoid negative zero issues (0 / -1 = -0\n\t\t\t * for instance).\n\t\t\t */\n\t\t\tif (v1 == 0 || v2 == 0) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tv3 = v1 / v2;\n\t\t\tif (v3 * v2 != v1) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD >> 2: {\n\t\t\t/* Don't allow a zero divisor.  Restrict both v1 and\n\t\t\t * v2 to positive values to avoid compiler specific\n\t\t\t * behavior.\n\t\t\t */\n\t\t\tif (v1 < 1 || v2 < 1) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\tv3 = v1 % v2;\n\t\t\tDUK_ASSERT(v3 >= 0);\n\t\t\tDUK_ASSERT(v3 < v2);\n\t\t\tDUK_ASSERT(v1 - (v1 / v2) * v2 == v3);\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\t/* Possible with DUK_OP_EXP. */\n\t\t\tgoto skip_fastint;\n\t\t}\n\t\t}\n\n\t\tv3_hi = (duk_int32_t) (v3 >> 32);\n\t\tif (DUK_LIKELY(v3_hi >= DUK_I64_CONSTANT(-0x8000) && v3_hi <= DUK_I64_CONSTANT(0x7fff))) {\n\t\t\ttv_z = thr->valstack_bottom + idx_z;\n\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, v3);  /* side effects */\n\t\t\treturn;\n\t\t}\n\t\t/* fall through if overflow etc */\n\t}\n skip_fastint:\n#endif  /* DUK_USE_FASTINT */\n\n\tif (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) {\n\t\t/* fast path */\n\t\td1 = DUK_TVAL_GET_NUMBER(tv_x);\n\t\td2 = DUK_TVAL_GET_NUMBER(tv_y);\n\t} else {\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\td1 = duk_to_number_m2(thr);  /* side effects */\n\t\td2 = duk_to_number_m1(thr);\n\t\tDUK_ASSERT(duk_is_number(thr, -2));\n\t\tDUK_ASSERT(duk_is_number(thr, -1));\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d1);\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d2);\n\t\tduk_pop_2_unsafe(thr);\n\t}\n\n\tswitch (opcode_shifted) {\n\tcase DUK_OP_SUB >> 2: {\n\t\tdu.d = d1 - d2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_MUL >> 2: {\n\t\tdu.d = d1 * d2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_DIV >> 2: {\n\t\t/* Division-by-zero is undefined behavior, so\n\t\t * rely on a helper.\n\t\t */\n\t\tdu.d = duk_double_div(d1, d2);\n\t\tbreak;\n\t}\n\tcase DUK_OP_MOD >> 2: {\n\t\tdu.d = duk__compute_mod(d1, d2);\n\t\tbreak;\n\t}\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\tcase DUK_OP_EXP >> 2: {\n\t\tdu.d = duk__compute_exp(d1, d2);\n\t\tbreak;\n\t}\n#endif\n\tdefault: {\n\t\tDUK_UNREACHABLE();\n\t\tdu.d = DUK_DOUBLE_NAN;  /* should not happen */\n\t\tbreak;\n\t}\n\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_push_number(thr, du.d);  /* will NaN normalize result */\n\tduk_replace(thr, (duk_idx_t) idx_z);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t/* important to use normalized NaN with 8-byte tagged types */\n\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\ttv_z = thr->valstack_bottom + idx_z;\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, du.d);  /* side effects */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_bitwise_binary_op(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_fast_t idx_z, duk_small_uint_fast_t opcode) {\n\t/*\n\t *  Binary bitwise operations use different coercions (ToInt32, ToUint32)\n\t *  depending on the operation.  We coerce the arguments first using\n\t *  ToInt32(), and then cast to an 32-bit value if necessary.  Note that\n\t *  such casts must be correct even if there is no native 32-bit type\n\t *  (e.g., duk_int32_t and duk_uint32_t are 64-bit).\n\t *\n\t *  E5 Sections 11.10, 11.7.1, 11.7.2, 11.7.3\n\t */\n\n\tduk_int32_t i1, i2, i3;\n\tduk_uint32_t u1, u2, u3;\n#if defined(DUK_USE_FASTINT)\n\tduk_int64_t fi3;\n#else\n\tduk_double_t d3;\n#endif\n\tduk_small_uint_fast_t opcode_shifted;\n#if defined(DUK_USE_FASTINT) || !defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_tval *tv_z;\n#endif\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_x != NULL);  /* may be reg or const */\n\tDUK_ASSERT(tv_y != NULL);  /* may be reg or const */\n\tDUK_ASSERT_DISABLE(idx_z >= 0);  /* unsigned */\n\tDUK_ASSERT((duk_uint_t) idx_z < (duk_uint_t) duk_get_top(thr));\n\n\topcode_shifted = opcode >> 2;  /* Get base opcode without reg/const modifiers. */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\ti1 = (duk_int32_t) DUK_TVAL_GET_FASTINT_I32(tv_x);\n\t\ti2 = (duk_int32_t) DUK_TVAL_GET_FASTINT_I32(tv_y);\n\t}\n\telse\n#endif  /* DUK_USE_FASTINT */\n\t{\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\ti1 = duk_to_int32(thr, -2);\n\t\ti2 = duk_to_int32(thr, -1);\n\t\tduk_pop_2_unsafe(thr);\n\t}\n\n\tswitch (opcode_shifted) {\n\tcase DUK_OP_BAND >> 2: {\n\t\ti3 = i1 & i2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_BOR >> 2: {\n\t\ti3 = i1 | i2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_BXOR >> 2: {\n\t\ti3 = i1 ^ i2;\n\t\tbreak;\n\t}\n\tcase DUK_OP_BASL >> 2: {\n\t\t/* Signed shift, named \"arithmetic\" (asl) because the result\n\t\t * is signed, e.g. 4294967295 << 1 -> -2.  Note that result\n\t\t * must be masked.\n\t\t */\n\n\t\tu2 = ((duk_uint32_t) i2) & 0xffffffffUL;\n\t\ti3 = (duk_int32_t) (((duk_uint32_t) i1) << (u2 & 0x1fUL));  /* E5 Section 11.7.1, steps 7 and 8 */\n\t\ti3 = i3 & ((duk_int32_t) 0xffffffffUL);                     /* Note: left shift, should mask */\n\t\tbreak;\n\t}\n\tcase DUK_OP_BASR >> 2: {\n\t\t/* signed shift */\n\n\t\tu2 = ((duk_uint32_t) i2) & 0xffffffffUL;\n\t\ti3 = i1 >> (u2 & 0x1fUL);                      /* E5 Section 11.7.2, steps 7 and 8 */\n\t\tbreak;\n\t}\n\tcase DUK_OP_BLSR >> 2: {\n\t\t/* unsigned shift */\n\n\t\tu1 = ((duk_uint32_t) i1) & 0xffffffffUL;\n\t\tu2 = ((duk_uint32_t) i2) & 0xffffffffUL;\n\n\t\t/* special result value handling */\n\t\tu3 = u1 >> (u2 & 0x1fUL);     /* E5 Section 11.7.2, steps 7 and 8 */\n#if defined(DUK_USE_FASTINT)\n\t\tfi3 = (duk_int64_t) u3;\n\t\tgoto fastint_result_set;\n#else\n\t\td3 = (duk_double_t) u3;\n\t\tgoto result_set;\n#endif\n\t}\n\tdefault: {\n\t\tDUK_UNREACHABLE();\n\t\ti3 = 0;  /* should not happen */\n\t\tbreak;\n\t}\n\t}\n\n#if defined(DUK_USE_FASTINT)\n\t/* Result is always fastint compatible. */\n\t/* XXX: Set 32-bit result (but must then handle signed and\n\t * unsigned results separately).\n\t */\n\tfi3 = (duk_int64_t) i3;\n\n fastint_result_set:\n\ttv_z = thr->valstack_bottom + idx_z;\n\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_z, fi3);  /* side effects */\n#else  /* DUK_USE_FASTINT */\n\td3 = (duk_double_t) i3;\n\n result_set:\n\tDUK_ASSERT(!DUK_ISNAN(d3));            /* 'd3' is never NaN, so no need to normalize */\n\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(d3);   /* always normalized */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_push_number(thr, d3);  /* would NaN normalize result, but unnecessary */\n\tduk_replace(thr, (duk_idx_t) idx_z);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\ttv_z = thr->valstack_bottom + idx_z;\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_z, d3);  /* side effects */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n#endif  /* DUK_USE_FASTINT */\n}\n\n/* In-place unary operation. */\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_arith_unary_op(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst, duk_small_uint_fast_t opcode) {\n\t/*\n\t *  Arithmetic operations other than '+' have number-only semantics\n\t *  and are implemented here.  The separate switch-case here means a\n\t *  \"double dispatch\" of the arithmetic opcode, but saves code space.\n\t *\n\t *  E5 Sections 11.5, 11.5.1, 11.5.2, 11.5.3, 11.6, 11.6.1, 11.6.2, 11.6.3.\n\t */\n\n\tduk_tval *tv;\n\tduk_double_t d1;\n\tduk_double_union du;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(opcode == DUK_OP_UNM || opcode == DUK_OP_UNP);\n\tDUK_ASSERT_DISABLE(idx_src >= 0);\n\tDUK_ASSERT_DISABLE(idx_dst >= 0);\n\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\tduk_int64_t v1, v2;\n\n\t\tv1 = DUK_TVAL_GET_FASTINT(tv);\n\t\tif (opcode == DUK_OP_UNM) {\n\t\t\t/* The smallest fastint is no longer 48-bit when\n\t\t\t * negated.  Positive zero becames negative zero\n\t\t\t * (cannot be represented) when negated.\n\t\t\t */\n\t\t\tif (DUK_LIKELY(v1 != DUK_FASTINT_MIN && v1 != 0)) {\n\t\t\t\tv2 = -v1;\n\t\t\t\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv, v2);\n\t\t\t\treturn;\n\t\t\t}\n\t\t} else {\n\t\t\t/* ToNumber() for a fastint is a no-op. */\n\t\t\tDUK_ASSERT(opcode == DUK_OP_UNP);\n\t\t\tv2 = v1;\n\t\t\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv, v2);\n\t\t\treturn;\n\t\t}\n\t\t/* fall through if overflow etc */\n\t}\n#endif  /* DUK_USE_FASTINT */\n\n\tif (DUK_TVAL_IS_NUMBER(tv)) {\n\t\td1 = DUK_TVAL_GET_NUMBER(tv);\n\t} else {\n\t\td1 = duk_to_number_tval(thr, tv);  /* side effects */\n\t}\n\n\tif (opcode == DUK_OP_UNP) {\n\t\t/* ToNumber() for a double is a no-op, but unary plus is\n\t\t * used to force a fastint check so do that here.\n\t\t */\n\t\tdu.d = d1;\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n#if defined(DUK_USE_FASTINT)\n\t\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t\tDUK_TVAL_SET_NUMBER_CHKFAST_UPDREF(thr, tv, du.d);  /* always 'fast', i.e. inlined */\n\t\treturn;\n#endif\n\t} else {\n\t\tDUK_ASSERT(opcode == DUK_OP_UNM);\n\t\tdu.d = -d1;\n\t\tDUK_DBLUNION_NORMALIZE_NAN_CHECK(&du);  /* mandatory if du.d is a NaN */\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\t}\n\n\t/* XXX: size optimize: push+replace? */\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv, du.d);\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_bitwise_not(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst) {\n\t/*\n\t *  E5 Section 11.4.8\n\t */\n\n\tduk_tval *tv;\n\tduk_int32_t i1, i2;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT_DISABLE(idx_src >= 0);\n\tDUK_ASSERT_DISABLE(idx_dst >= 0);\n\tDUK_ASSERT((duk_uint_t) idx_src < (duk_uint_t) duk_get_top(thr));\n\tDUK_ASSERT((duk_uint_t) idx_dst < (duk_uint_t) duk_get_top(thr));\n\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\ti1 = (duk_int32_t) DUK_TVAL_GET_FASTINT_I32(tv);\n\t}\n\telse\n#endif  /* DUK_USE_FASTINT */\n\t{\n\t\tduk_push_tval(thr, tv);\n\t\ti1 = duk_to_int32(thr, -1);  /* side effects */\n\t\tduk_pop_unsafe(thr);\n\t}\n\n\t/* Result is always fastint compatible. */\n\ti2 = ~i1;\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\tDUK_TVAL_SET_I32_UPDREF(thr, tv, i2);  /* side effects */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__vm_logical_not(duk_hthread *thr, duk_uint_fast_t idx_src, duk_uint_fast_t idx_dst) {\n\t/*\n\t *  E5 Section 11.4.9\n\t */\n\n\tduk_tval *tv;\n\tduk_bool_t res;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT_DISABLE(idx_src >= 0);\n\tDUK_ASSERT_DISABLE(idx_dst >= 0);\n\tDUK_ASSERT((duk_uint_t) idx_src < (duk_uint_t) duk_get_top(thr));\n\tDUK_ASSERT((duk_uint_t) idx_dst < (duk_uint_t) duk_get_top(thr));\n\n\t/* ToBoolean() does not require any operations with side effects so\n\t * we can do it efficiently.  For footprint it would be better to use\n\t * duk_js_toboolean() and then push+replace to the result slot.\n\t */\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_src);\n\tres = duk_js_toboolean(tv);  /* does not modify 'tv' */\n\tDUK_ASSERT(res == 0 || res == 1);\n\tres ^= 1;\n\ttv = DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst);\n\t/* XXX: size optimize: push+replace? */\n\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv, res);  /* side effects */\n}\n\n/* XXX: size optimized variant */\nDUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_reg_helper(duk_hthread *thr, duk_tval *tv_dst, duk_tval *tv_src, duk_small_uint_t op) {\n\tduk_double_t x, y, z;\n\n\t/* Two lowest bits of opcode are used to distinguish\n\t * variants.  Bit 0 = inc(0)/dec(1), bit 1 = pre(0)/post(1).\n\t */\n\tDUK_ASSERT((DUK_OP_PREINCR & 0x03) == 0x00);\n\tDUK_ASSERT((DUK_OP_PREDECR & 0x03) == 0x01);\n\tDUK_ASSERT((DUK_OP_POSTINCR & 0x03) == 0x02);\n\tDUK_ASSERT((DUK_OP_POSTDECR & 0x03) == 0x03);\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_src)) {\n\t\tduk_int64_t x_fi, y_fi, z_fi;\n\t\tx_fi = DUK_TVAL_GET_FASTINT(tv_src);\n\t\tif (op & 0x01) {\n\t\t\tif (DUK_UNLIKELY(x_fi == DUK_FASTINT_MIN)) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\ty_fi = x_fi - 1;\n\t\t} else {\n\t\t\tif (DUK_UNLIKELY(x_fi == DUK_FASTINT_MAX)) {\n\t\t\t\tgoto skip_fastint;\n\t\t\t}\n\t\t\ty_fi = x_fi + 1;\n\t\t}\n\n\t\tDUK_TVAL_SET_FASTINT(tv_src, y_fi);  /* no need for refcount update */\n\n\t\tz_fi = (op & 0x02) ? x_fi : y_fi;\n\t\tDUK_TVAL_SET_FASTINT_UPDREF(thr, tv_dst, z_fi);  /* side effects */\n\t\treturn;\n\t}\n skip_fastint:\n#endif\n\tif (DUK_TVAL_IS_NUMBER(tv_src)) {\n\t\t/* Fast path for the case where the register\n\t\t * is a number (e.g. loop counter).\n\t\t */\n\n\t\tx = DUK_TVAL_GET_NUMBER(tv_src);\n\t\tif (op & 0x01) {\n\t\t\ty = x - 1.0;\n\t\t} else {\n\t\t\ty = x + 1.0;\n\t\t}\n\n\t\tDUK_TVAL_SET_NUMBER(tv_src, y);  /* no need for refcount update */\n\t} else {\n\t\t/* Preserve duk_tval pointer(s) across a potential valstack\n\t\t * resize by converting them into offsets temporarily.\n\t\t */\n\t\tduk_idx_t bc;\n\t\tduk_size_t off_dst;\n\n\t\toff_dst = (duk_size_t) ((duk_uint8_t *) tv_dst - (duk_uint8_t *) thr->valstack_bottom);\n\t\tbc = (duk_idx_t) (tv_src - thr->valstack_bottom);  /* XXX: pass index explicitly? */\n\t\ttv_src = NULL;  /* no longer referenced */\n\n\t\tx = duk_to_number(thr, bc);\n\t\tif (op & 0x01) {\n\t\t\ty = x - 1.0;\n\t\t} else {\n\t\t\ty = x + 1.0;\n\t\t}\n\n\t\tduk_push_number(thr, y);\n\t\tduk_replace(thr, bc);\n\n\t\ttv_dst = (duk_tval *) (void *) (((duk_uint8_t *) thr->valstack_bottom) + off_dst);\n\t}\n\n\tz = (op & 0x02) ? x : y;\n\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_dst, z);  /* side effects */\n}\n\nDUK_LOCAL DUK__INLINE_PERF void duk__prepost_incdec_var_helper(duk_hthread *thr, duk_small_uint_t idx_dst, duk_tval *tv_id, duk_small_uint_t op, duk_small_uint_t is_strict) {\n\tduk_activation *act;\n\tduk_double_t x, y;\n\tduk_hstring *name;\n\n\t/* XXX: The pre/post inc/dec for an identifier lookup is\n\t * missing the important fast path where the identifier\n\t * has a storage location e.g. in a scope object so that\n\t * it can be updated in-place.  In particular, the case\n\t * where the identifier has a storage location AND the\n\t * previous value is a number should be optimized because\n\t * it's side effect free.\n\t */\n\n\t/* Two lowest bits of opcode are used to distinguish\n\t * variants.  Bit 0 = inc(0)/dec(1), bit 1 = pre(0)/post(1).\n\t */\n\tDUK_ASSERT((DUK_OP_PREINCV & 0x03) == 0x00);\n\tDUK_ASSERT((DUK_OP_PREDECV & 0x03) == 0x01);\n\tDUK_ASSERT((DUK_OP_POSTINCV & 0x03) == 0x02);\n\tDUK_ASSERT((DUK_OP_POSTDECV & 0x03) == 0x03);\n\n\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv_id));\n\tname = DUK_TVAL_GET_STRING(tv_id);\n\tDUK_ASSERT(name != NULL);\n\tact = thr->callstack_curr;\n\t(void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/);  /* -> [ ... val this ] */\n\n\t/* XXX: Fastint fast path would be useful here.  Also fastints\n\t * now lose their fastint status in current handling which is\n\t * not intuitive.\n\t */\n\n\tx = duk_to_number_m2(thr);\n\tif (op & 0x01) {\n\t\ty = x - 1.0;\n\t} else {\n\t\ty = x + 1.0;\n\t}\n\n\t/* [... x this] */\n\n\tif (op & 0x02) {\n\t\tduk_push_number(thr, y);  /* -> [ ... x this y ] */\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tduk_js_putvar_activation(thr, act, name, DUK_GET_TVAL_NEGIDX(thr, -1), is_strict);\n\t\tduk_pop_2_unsafe(thr);  /* -> [ ... x ] */\n\t} else {\n\t\tduk_pop_2_unsafe(thr);  /* -> [ ... ] */\n\t\tduk_push_number(thr, y);  /* -> [ ... y ] */\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tduk_js_putvar_activation(thr, act, name, DUK_GET_TVAL_NEGIDX(thr, -1), is_strict);\n\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\tduk_replace(thr, (duk_idx_t) idx_dst);\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\tDUK__REPLACE_TO_TVPTR(thr, DUK_GET_TVAL_POSIDX(thr, (duk_idx_t) idx_dst));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n}\n\n/*\n *  Longjmp and other control flow transfer for the bytecode executor.\n *\n *  The longjmp handler can handle all longjmp types: error, yield, and\n *  resume (pseudotypes are never actually thrown).\n *\n *  Error policy for longjmp: should not ordinarily throw errors; if errors\n *  occur (e.g. due to out-of-memory) they bubble outwards rather than being\n *  handled recursively.\n */\n\n#define DUK__LONGJMP_RESTART   0  /* state updated, restart bytecode execution */\n#define DUK__LONGJMP_RETHROW   1  /* exit bytecode executor by rethrowing an error to caller */\n\n#define DUK__RETHAND_RESTART   0  /* state updated, restart bytecode execution */\n#define DUK__RETHAND_FINISHED  1  /* exit bytecode execution with return value */\n\n/* XXX: optimize reconfig valstack operations so that resize, clamp, and setting\n * top are combined into one pass.\n */\n\n/* Reconfigure value stack for return to an ECMAScript function at\n * callstack top (caller unwinds).\n */\nDUK_LOCAL void duk__reconfig_valstack_ecma_return(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_hcompfunc *h_func;\n\tduk_idx_t clamp_top;\n\n\tDUK_ASSERT(thr != NULL);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act)));\n\n\t/* Clamp so that values at 'clamp_top' and above are wiped and won't\n\t * retain reachable garbage.  Then extend to 'nregs' because we're\n\t * returning to an ECMAScript function.\n\t */\n\n\th_func = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff);\n\tDUK_ASSERT(act->retval_byteoff >= act->bottom_byteoff);\n\tclamp_top = (duk_idx_t) ((act->retval_byteoff - act->bottom_byteoff + sizeof(duk_tval)) / sizeof(duk_tval));  /* +1 = one retval */\n\tduk_set_top_and_wipe(thr, h_func->nregs, clamp_top);\n\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack_end >= (duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\n\t/* XXX: a best effort shrink check would be OK here */\n}\n\n/* Reconfigure value stack for an ECMAScript catcher.  Use topmost catcher\n * in 'act'.\n */\nDUK_LOCAL void duk__reconfig_valstack_ecma_catcher(duk_hthread *thr, duk_activation *act) {\n\tduk_catcher *cat;\n\tduk_hcompfunc *h_func;\n\tduk_size_t idx_bottom;\n\tduk_idx_t clamp_top;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act)));\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\th_func = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\n\tthr->valstack_bottom = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff);\n\tidx_bottom = (duk_size_t) (thr->valstack_bottom - thr->valstack);\n\tDUK_ASSERT(cat->idx_base >= idx_bottom);\n\tclamp_top = (duk_idx_t) (cat->idx_base - idx_bottom + 2);  /* +2 = catcher value, catcher lj_type */\n\tduk_set_top_and_wipe(thr, h_func->nregs, clamp_top);\n\n\tDUK_ASSERT((duk_uint8_t *) thr->valstack_end >= (duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\tthr->valstack_end = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->reserve_byteoff);\n\n\t/* XXX: a best effort shrink check would be OK here */\n}\n\n/* Set catcher regs: idx_base+0 = value, idx_base+1 = lj_type.\n * No side effects.\n */\nDUK_LOCAL void duk__set_catcher_regs_norz(duk_hthread *thr, duk_catcher *cat, duk_tval *tv_val_unstable, duk_small_uint_t lj_type) {\n\tduk_tval *tv1;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\n\ttv1 = thr->valstack + cat->idx_base;\n\tDUK_ASSERT(tv1 < thr->valstack_top);\n\tDUK_TVAL_SET_TVAL_UPDREF_NORZ(thr, tv1, tv_val_unstable);\n\n\ttv1++;\n\tDUK_ASSERT(tv1 == thr->valstack + cat->idx_base + 1);\n\tDUK_ASSERT(tv1 < thr->valstack_top);\n\tDUK_TVAL_SET_U32_UPDREF_NORZ(thr, tv1, (duk_uint32_t) lj_type);\n}\n\nDUK_LOCAL void duk__handle_catch_part1(duk_hthread *thr, duk_tval *tv_val_unstable, duk_small_uint_t lj_type, volatile duk_bool_t *out_delayed_catch_setup) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_DD(DUK_DDPRINT(\"handle catch, part 1; act=%!A, cat=%!C\", act, act->cat));\n\n\tDUK_ASSERT(act->cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);\n\n\t/* The part1/part2 split could also be made here at the very top\n\t * of catch handling.  Value stack would be reconfigured inside\n\t * part2's protection.  Value stack reconfiguration should be free\n\t * of allocs, however.\n\t */\n\n\tduk__set_catcher_regs_norz(thr, act->cat, tv_val_unstable, lj_type);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tduk__reconfig_valstack_ecma_catcher(thr, act);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tact->curr_pc = cat->pc_base + 0;  /* +0 = catch */\n\n\t/*\n\t *  If the catch block has an automatic catch variable binding,\n\t *  we need to create a lexical environment for it which requires\n\t *  allocations.  Move out of \"error handling state\" before the\n\t *  allocations to avoid e.g. out-of-memory errors (leading to\n\t *  GH-2022 or similar).\n\t */\n\n\tif (DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"catcher has an automatic catch binding, handle in part 2\"));\n\t\t*out_delayed_catch_setup = 1;\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"catcher has no catch binding\"));\n\t}\n\n\tDUK_CAT_CLEAR_CATCH_ENABLED(cat);\n}\n\nDUK_LOCAL void duk__handle_catch_part2(duk_hthread *thr) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_hdecenv *new_env;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_DD(DUK_DDPRINT(\"handle catch, part 2; act=%!A, cat=%!C\", act, act->cat));\n\n\tDUK_ASSERT(act->cat != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);\n\tDUK_ASSERT(DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat));\n\tDUK_ASSERT(thr->valstack + cat->idx_base < thr->valstack_top);\n\n\t/*\n\t *  Create lexical environment for the catch clause, containing\n\t *  a binding for the caught value.\n\t *\n\t *  The binding is mutable (= writable) but not deletable.\n\t *  Step 4 for the catch production in E5 Section 12.14;\n\t *  no value is given for CreateMutableBinding 'D' argument,\n\t *  which implies the binding is not deletable.\n\t */\n\n\tif (act->lex_env == NULL) {\n\t\tDUK_ASSERT(act->var_env == NULL);\n\t\tDUK_DDD(DUK_DDDPRINT(\"delayed environment initialization\"));\n\n\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t}\n\tDUK_ASSERT(act->lex_env != NULL);\n\tDUK_ASSERT(act->var_env != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\n\tnew_env = duk_hdecenv_alloc(thr,\n\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\tDUK_ASSERT(new_env != NULL);\n\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\tDUK_DDD(DUK_DDDPRINT(\"new_env allocated: %!iO\", (duk_heaphdr *) new_env));\n\n\t/* Note: currently the catch binding is handled without a register\n\t * binding because we don't support dynamic register bindings (they\n\t * must be fixed for an entire function).  So, there is no need to\n\t * record regbases etc.\n\t */\n\n\t/* [ ...env ] */\n\n\tDUK_ASSERT(cat->h_varname != NULL);\n\tduk_push_hstring(thr, cat->h_varname);\n\tDUK_ASSERT(thr->valstack + cat->idx_base < thr->valstack_top);\n\tduk_push_tval(thr, thr->valstack + cat->idx_base);\n\tduk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_W);  /* writable, not configurable */\n\n\t/* [ ... env ] */\n\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, act->lex_env);\n\tact->lex_env = (duk_hobject *) new_env;\n\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env);  /* reachable through activation */\n\t/* Net refcount change to act->lex_env is 0: incref for new_env's\n\t * prototype, decref for act->lex_env overwrite.\n\t */\n\n\tDUK_CAT_SET_LEXENV_ACTIVE(cat);\n\n\tduk_pop_unsafe(thr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"new_env finished: %!iO\", (duk_heaphdr *) new_env));\n}\n\nDUK_LOCAL void duk__handle_finally(duk_hthread *thr, duk_tval *tv_val_unstable, duk_small_uint_t lj_type) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(act->cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);\n\n\tduk__set_catcher_regs_norz(thr, act->cat, tv_val_unstable, lj_type);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tduk__reconfig_valstack_ecma_catcher(thr, act);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\n\tact->curr_pc = cat->pc_base + 1;  /* +1 = finally */\n\n\tDUK_CAT_CLEAR_FINALLY_ENABLED(cat);\n}\n\nDUK_LOCAL void duk__handle_label(duk_hthread *thr, duk_small_uint_t lj_type) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(DUK_ACT_GET_FUNC(act)));\n\n\t/* +0 = break, +1 = continue */\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_LABEL);\n\n\tact->curr_pc = cat->pc_base + (lj_type == DUK_LJ_TYPE_CONTINUE ? 1 : 0);\n\n\t/* valstack should not need changes */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(act == thr->callstack_curr);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack_bottom) ==\n\t           (duk_size_t) ((duk_hcompfunc *) DUK_ACT_GET_FUNC(act))->nregs);\n#endif\n}\n\n/* Called for handling both a longjmp() with type DUK_LJ_TYPE_YIELD and\n * when a RETURN opcode terminates a thread and yields to the resumer.\n * Caller unwinds so that top of callstack is the activation we return to.\n */\n#if defined(DUK_USE_COROUTINE_SUPPORT)\nDUK_LOCAL void duk__handle_yield(duk_hthread *thr, duk_hthread *resumer, duk_tval *tv_val_unstable) {\n\tduk_activation *act_resumer;\n\tduk_tval *tv1;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(resumer != NULL);\n\tDUK_ASSERT(tv_val_unstable != NULL);\n\tact_resumer = resumer->callstack_curr;\n\tDUK_ASSERT(act_resumer != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(act_resumer) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(act_resumer)));  /* resume caller must be an ECMAScript func */\n\n\ttv1 = (duk_tval *) (void *) ((duk_uint8_t *) resumer->valstack + act_resumer->retval_byteoff);  /* return value from Duktape.Thread.resume() */\n\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv_val_unstable);  /* side effects */  /* XXX: avoid side effects */\n\n\tduk__reconfig_valstack_ecma_return(resumer);\n\n\t/* caller must change active thread, and set thr->resumer to NULL */\n}\n#endif  /* DUK_USE_COROUTINE_SUPPORT */\n\nDUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation *entry_act, volatile duk_bool_t *out_delayed_catch_setup) {\n\tduk_small_uint_t retval = DUK__LONGJMP_RESTART;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(entry_act != NULL);\n\n\t/* 'thr' is the current thread, as no-one resumes except us and we\n\t * switch 'thr' in that case.\n\t */\n\tDUK_ASSERT(thr == thr->heap->curr_thread);\n\n\t/*\n\t *  (Re)try handling the longjmp.\n\t *\n\t *  A longjmp handler may convert the longjmp to a different type and\n\t *  \"virtually\" rethrow by goto'ing to 'check_longjmp'.  Before the goto,\n\t *  the following must be updated:\n\t *    - the heap 'lj' state\n\t *    - 'thr' must reflect the \"throwing\" thread\n\t */\n\n check_longjmp:\n\n\tDUK_DD(DUK_DDPRINT(\"handling longjmp: type=%ld, value1=%!T, value2=%!T, iserror=%ld, top=%ld\",\n\t                   (long) thr->heap->lj.type,\n\t                   (duk_tval *) &thr->heap->lj.value1,\n\t                   (duk_tval *) &thr->heap->lj.value2,\n\t                   (long) thr->heap->lj.iserror,\n\t\t\t   (long) duk_get_top(thr)));\n\n\tswitch (thr->heap->lj.type) {\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\tcase DUK_LJ_TYPE_RESUME: {\n\t\t/*\n\t\t *  Note: lj.value1 is 'value', lj.value2 is 'resumee'.\n\t\t *  This differs from YIELD.\n\t\t */\n\n\t\tduk_tval *tv;\n\t\tduk_tval *tv2;\n\t\tduk_hthread *resumee;\n\n\t\t/* duk_bi_duk_object_yield() and duk_bi_duk_object_resume() ensure all of these are met */\n\n\t\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);                                                         /* unchanged by Duktape.Thread.resume() */\n\t\tDUK_ASSERT(thr->callstack_top >= 2);                                                                         /* ECMAScript activation + Duktape.Thread.resume() activation */\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL &&\n\t\t           DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)) &&\n\t\t           ((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->callstack_curr))->func == duk_bi_thread_resume);\n\n\t\ttv = &thr->heap->lj.value2;  /* resumee */\n\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv));\n\t\tDUK_ASSERT(DUK_TVAL_GET_OBJECT(tv) != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_THREAD(DUK_TVAL_GET_OBJECT(tv)));\n\t\tresumee = (duk_hthread *) DUK_TVAL_GET_OBJECT(tv);\n\n\t\tDUK_ASSERT(resumee != NULL);\n\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\tDUK_ASSERT(resumee->state == DUK_HTHREAD_STATE_INACTIVE ||\n\t\t           resumee->state == DUK_HTHREAD_STATE_YIELDED);                                                     /* checked by Duktape.Thread.resume() */\n\t\tDUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_YIELDED ||\n\t\t           resumee->callstack_top >= 2);                                                                     /* YIELDED: ECMAScript activation + Duktape.Thread.yield() activation */\n\t\tDUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_YIELDED ||\n\t\t           (DUK_ACT_GET_FUNC(resumee->callstack_curr) != NULL &&\n\t\t            DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(resumee->callstack_curr)) &&\n\t\t            ((duk_hnatfunc *) DUK_ACT_GET_FUNC(resumee->callstack_curr))->func == duk_bi_thread_yield));\n\t\tDUK_ASSERT(resumee->state != DUK_HTHREAD_STATE_INACTIVE ||\n\t\t           resumee->callstack_top == 0);                                                                     /* INACTIVE: no activation, single function value on valstack */\n\n\t\tif (thr->heap->lj.iserror) {\n\t\t\t/*\n\t\t\t *  Throw the error in the resumed thread's context; the\n\t\t\t *  error value is pushed onto the resumee valstack.\n\t\t\t *\n\t\t\t *  Note: the callstack of the target may empty in this case\n\t\t\t *  too (i.e. the target thread has never been resumed).  The\n\t\t\t *  value stack will contain the initial function in that case,\n\t\t\t *  which we simply ignore.\n\t\t\t */\n\n\t\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\t\tresumee->resumer = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tresumee->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tthr->state = DUK_HTHREAD_STATE_RESUMED;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumee);\n\t\t\tthr = resumee;\n\n\t\t\tthr->heap->lj.type = DUK_LJ_TYPE_THROW;\n\n\t\t\t/* thr->heap->lj.value1 is already the value to throw */\n\t\t\t/* thr->heap->lj.value2 is 'thread', will be wiped out at the end */\n\n\t\t\tDUK_ASSERT(thr->heap->lj.iserror);  /* already set */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> resume with an error, converted to a throw in the resumee, propagate\"));\n\t\t\tgoto check_longjmp;\n\t\t} else if (resumee->state == DUK_HTHREAD_STATE_YIELDED) {\n\t\t\t/* Unwind previous Duktape.Thread.yield() call.  The\n\t\t\t * activation remaining must always be an ECMAScript\n\t\t\t * call now (yield() accepts calls from ECMAScript\n\t\t\t * only).\n\t\t\t */\n\t\t\tduk_activation *act_resumee;\n\n\t\t\tDUK_ASSERT(resumee->callstack_top >= 2);\n\t\t\tact_resumee = resumee->callstack_curr;  /* Duktape.Thread.yield() */\n\t\t\tDUK_ASSERT(act_resumee != NULL);\n\t\t\tact_resumee = act_resumee->parent;      /* ECMAScript call site for yield() */\n\t\t\tDUK_ASSERT(act_resumee != NULL);\n\n\t\t\ttv = (duk_tval *) (void *) ((duk_uint8_t *) resumee->valstack + act_resumee->retval_byteoff);  /* return value from Duktape.Thread.yield() */\n\t\t\tDUK_ASSERT(tv >= resumee->valstack && tv < resumee->valstack_top);\n\t\t\ttv2 = &thr->heap->lj.value1;\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv, tv2);  /* side effects */  /* XXX: avoid side effects */\n\n\t\t\tduk_hthread_activation_unwind_norz(resumee);  /* unwind to 'yield' caller */\n\t\t\t/* no need to unwind catch stack */\n\n\t\t\tduk__reconfig_valstack_ecma_return(resumee);\n\n\t\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\t\tresumee->resumer = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tresumee->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tthr->state = DUK_HTHREAD_STATE_RESUMED;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumee);\n#if 0\n\t\t\tthr = resumee;  /* not needed, as we exit right away */\n#endif\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> resume with a value, restart execution in resumee\"));\n\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\tgoto wipe_and_return;\n\t\t} else {\n\t\t\t/* Initial resume call. */\n\t\t\tduk_small_uint_t call_flags;\n\t\t\tduk_int_t setup_rc;\n\n\t\t\t/* resumee: [... initial_func]  (currently actually: [initial_func]) */\n\n\t\t\tduk_push_undefined(resumee);\n\t\t\ttv = &thr->heap->lj.value1;\n\t\t\tduk_push_tval(resumee, tv);\n\n\t\t\t/* resumee: [... initial_func undefined(= this) resume_value ] */\n\n\t\t\tcall_flags = DUK_CALL_FLAG_ALLOW_ECMATOECMA;  /* not tailcall, ecma-to-ecma (assumed to succeed) */\n\n\t\t\tsetup_rc = duk_handle_call_unprotected_nargs(resumee, 1 /*nargs*/, call_flags);\n\t\t\tif (setup_rc == 0) {\n\t\t\t\t/* This shouldn't happen; Duktape.Thread.resume()\n\t\t\t\t * should make sure of that.  If it does happen\n\t\t\t\t * this internal error will propagate out of the\n\t\t\t\t * executor which can be quite misleading.\n\t\t\t\t */\n\t\t\t\tDUK_ERROR_INTERNAL(thr);\n\t\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t\t}\n\n\t\t\tDUK_ASSERT(resumee->resumer == NULL);\n\t\t\tresumee->resumer = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tresumee->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tthr->state = DUK_HTHREAD_STATE_RESUMED;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumee);\n#if 0\n\t\t\tthr = resumee;  /* not needed, as we exit right away */\n#endif\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> resume with a value, restart execution in resumee\"));\n\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\tgoto wipe_and_return;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\t\tbreak;  /* never here */\n\t}\n\n\tcase DUK_LJ_TYPE_YIELD: {\n\t\t/*\n\t\t *  Currently only allowed only if yielding thread has only\n\t\t *  ECMAScript activations (except for the Duktape.Thread.yield()\n\t\t *  call at the callstack top) and none of them constructor\n\t\t *  calls.\n\t\t *\n\t\t *  This excludes the 'entry' thread which will always have\n\t\t *  a preventcount > 0.\n\t\t */\n\n\t\tduk_hthread *resumer;\n\n\t\t/* duk_bi_duk_object_yield() and duk_bi_duk_object_resume() ensure all of these are met */\n\n#if 0  /* entry_thread not available for assert */\n\t\tDUK_ASSERT(thr != entry_thread);                                                                             /* Duktape.Thread.yield() should prevent */\n#endif\n\t\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);                                                         /* unchanged from Duktape.Thread.yield() */\n\t\tDUK_ASSERT(thr->callstack_top >= 2);                                                                         /* ECMAScript activation + Duktape.Thread.yield() activation */\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL &&\n\t\t           DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)) &&\n\t\t           ((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->callstack_curr))->func == duk_bi_thread_yield);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr->parent) != NULL &&\n\t\t           DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent)));                              /* an ECMAScript function */\n\n\t\tresumer = thr->resumer;\n\n\t\tDUK_ASSERT(resumer != NULL);\n\t\tDUK_ASSERT(resumer->state == DUK_HTHREAD_STATE_RESUMED);                                                     /* written by a previous RESUME handling */\n\t\tDUK_ASSERT(resumer->callstack_top >= 2);                                                                     /* ECMAScript activation + Duktape.Thread.resume() activation */\n\t\tDUK_ASSERT(resumer->callstack_curr != NULL);\n\t\tDUK_ASSERT(resumer->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack_curr) != NULL &&\n\t\t           DUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr)) &&\n\t\t           ((duk_hnatfunc *) DUK_ACT_GET_FUNC(resumer->callstack_curr))->func == duk_bi_thread_resume);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(resumer->callstack_curr->parent) != NULL &&\n\t\t           DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(resumer->callstack_curr->parent)));                            /* an ECMAScript function */\n\n\t\tif (thr->heap->lj.iserror) {\n\t\t\tthr->state = DUK_HTHREAD_STATE_YIELDED;\n\t\t\tthr->resumer = NULL;\n\t\t\tDUK_HTHREAD_DECREF_NORZ(thr, resumer);\n\t\t\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n\t\t\tthr = resumer;\n\n\t\t\tthr->heap->lj.type = DUK_LJ_TYPE_THROW;\n\t\t\t/* lj.value1 is already set */\n\t\t\tDUK_ASSERT(thr->heap->lj.iserror);  /* already set */\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> yield an error, converted to a throw in the resumer, propagate\"));\n\t\t\tgoto check_longjmp;\n\t\t} else {\n\t\t\tduk_hthread_activation_unwind_norz(resumer);\n\t\t\tduk__handle_yield(thr, resumer, &thr->heap->lj.value1);\n\n\t\t\tthr->state = DUK_HTHREAD_STATE_YIELDED;\n\t\t\tthr->resumer = NULL;\n\t\t\tDUK_HTHREAD_DECREF_NORZ(thr, resumer);\n\t\t\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\t\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n#if 0\n\t\t\tthr = resumer;  /* not needed, as we exit right away */\n#endif\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> yield a value, restart execution in resumer\"));\n\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\tgoto wipe_and_return;\n\t\t}\n\t\tDUK_UNREACHABLE();\n\t\tbreak;  /* never here */\n\t}\n#endif  /* DUK_USE_COROUTINE_SUPPORT */\n\n\tcase DUK_LJ_TYPE_THROW: {\n\t\t/*\n\t\t *  Three possible outcomes:\n\t\t *    * A try or finally catcher is found => resume there.\n\t\t *      (or)\n\t\t *    * The error propagates to the bytecode executor entry\n\t\t *      level (and we're in the entry thread) => rethrow\n\t\t *      with a new longjmp(), after restoring the previous\n\t\t *      catchpoint.\n\t\t *    * The error is not caught in the current thread, so\n\t\t *      the thread finishes with an error.  This works like\n\t\t *      a yielded error, except that the thread is finished\n\t\t *      and can no longer be resumed.  (There is always a\n\t\t *      resumer in this case.)\n\t\t *\n\t\t *  Note: until we hit the entry level, there can only be\n\t\t *  ECMAScript activations.\n\t\t */\n\n\t\tduk_activation *act;\n\t\tduk_catcher *cat;\n\t\tduk_hthread *resumer;\n\n\t\tfor (;;) {\n\t\t\tact = thr->callstack_curr;\n\t\t\tif (act == NULL) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tfor (;;) {\n\t\t\t\tcat = act->cat;\n\t\t\t\tif (cat == NULL) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif (DUK_CAT_HAS_CATCH_ENABLED(cat)) {\n\t\t\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);\n\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"before catch part 1: thr=%p, act=%p, cat=%p\",\n\t\t\t\t\t                     (void *) thr, (void *) act, (void *) act->cat));\n\t\t\t\t\tduk__handle_catch_part1(thr,\n\t\t\t\t\t                        &thr->heap->lj.value1,\n\t\t\t\t\t                        DUK_LJ_TYPE_THROW,\n\t\t\t\t\t\t\t        out_delayed_catch_setup);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"-> throw caught by a 'catch' clause, restart execution\"));\n\t\t\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\t\t\tgoto wipe_and_return;\n\t\t\t\t}\n\n\t\t\t\tif (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\t\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF);\n\t\t\t\t\tDUK_ASSERT(!DUK_CAT_HAS_CATCH_ENABLED(cat));\n\n\t\t\t\t\tduk__handle_finally(thr,\n\t\t\t\t\t                    &thr->heap->lj.value1,\n\t\t\t\t\t                    DUK_LJ_TYPE_THROW);\n\n\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"-> throw caught by a 'finally' clause, restart execution\"));\n\t\t\t\t\tretval = DUK__LONGJMP_RESTART;\n\t\t\t\t\tgoto wipe_and_return;\n\t\t\t\t}\n\n\t\t\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t\t\t}\n\n\t\t\tif (act == entry_act) {\n\t\t\t\t/* Not caught by anything before entry level; rethrow and let the\n\t\t\t\t * final catcher finish unwinding (esp. value stack).\n\t\t\t\t */\n\t\t\t\tDUK_D(DUK_DPRINT(\"-> throw propagated up to entry level, rethrow and exit bytecode executor\"));\n\t\t\t\tretval = DUK__LONGJMP_RETHROW;\n\t\t\t\tgoto just_return;\n\t\t\t}\n\n\t\t\tduk_hthread_activation_unwind_norz(thr);\n\t\t}\n\n\t\tDUK_DD(DUK_DDPRINT(\"-> throw not caught by current thread, yield error to resumer and recheck longjmp\"));\n\n\t\t/* Not caught by current thread, thread terminates (yield error to resumer);\n\t\t * note that this may cause a cascade if the resumer terminates with an uncaught\n\t\t * exception etc (this is OK, but needs careful testing).\n\t\t */\n\n\t\tDUK_ASSERT(thr->resumer != NULL);\n\t\tDUK_ASSERT(thr->resumer->callstack_top >= 2);  /* ECMAScript activation + Duktape.Thread.resume() activation */\n\t\tDUK_ASSERT(thr->resumer->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->resumer->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent) != NULL &&\n\t\t           DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent)));  /* an ECMAScript function */\n\n\t\tresumer = thr->resumer;\n\n\t\t/* reset longjmp */\n\n\t\tDUK_ASSERT(thr->heap->lj.type == DUK_LJ_TYPE_THROW);  /* already set */\n\t\t/* lj.value1 already set */\n\n\t\tduk_hthread_terminate(thr);  /* updates thread state, minimizes its allocations */\n\t\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_TERMINATED);\n\n\t\tthr->resumer = NULL;\n\t\tDUK_HTHREAD_DECREF_NORZ(thr, resumer);\n\t\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\t\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n\t\tthr = resumer;\n\t\tgoto check_longjmp;\n\t}\n\n\tcase DUK_LJ_TYPE_BREAK:  /* pseudotypes, not used in actual longjmps */\n\tcase DUK_LJ_TYPE_CONTINUE:\n\tcase DUK_LJ_TYPE_RETURN:\n\tcase DUK_LJ_TYPE_NORMAL:\n\tdefault: {\n\t\t/* should never happen, but be robust */\n\t\tDUK_D(DUK_DPRINT(\"caught unknown longjmp type %ld, treat as internal error\", (long) thr->heap->lj.type));\n\t\tgoto convert_to_internal_error;\n\t}\n\n\t}  /* end switch */\n\n\tDUK_UNREACHABLE();\n\n wipe_and_return:\n\tDUK_DD(DUK_DDPRINT(\"handling longjmp done, wipe-and-return, top=%ld\",\n\t                   (long) duk_get_top(thr)));\n\tthr->heap->lj.type = DUK_LJ_TYPE_UNKNOWN;\n\tthr->heap->lj.iserror = 0;\n\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value1);  /* side effects */\n\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, &thr->heap->lj.value2);  /* side effects */\n\n\tDUK_GC_TORTURE(thr->heap);\n\n just_return:\n\treturn retval;\n\n convert_to_internal_error:\n\t/* This could also be thrown internally (set the error, goto check_longjmp),\n\t * but it's better for internal errors to bubble outwards so that we won't\n\t * infinite loop in this catchpoint.\n\t */\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Handle a BREAK/CONTINUE opcode.  Avoid using longjmp() for BREAK/CONTINUE\n * handling because it has a measurable performance impact in ordinary\n * environments and an extreme impact in Emscripten (GH-342).\n */\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_break_or_continue(duk_hthread *thr,\n                                                                duk_uint_t label_id,\n                                                                duk_small_uint_t lj_type) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/* Find a matching label catcher or 'finally' catcher in\n\t * the same function, unwinding catchers as we go.\n\t *\n\t * A label catcher must always exist and will match unless\n\t * a 'finally' captures the break/continue first.  It is the\n\t * compiler's responsibility to ensure that labels are used\n\t * correctly.\n\t */\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\tfor (;;) {\n\t\tcat = act->cat;\n\t\tif (cat == NULL) {\n\t\t\tbreak;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"considering catcher %p: type=%ld label=%ld\",\n\t\t                     (void *) cat,\n\t\t                     (long) DUK_CAT_GET_TYPE(cat),\n\t\t                     (long) DUK_CAT_GET_LABEL(cat)));\n\n\t\t/* XXX: bit mask test; FINALLY <-> TCF, single bit mask would suffice? */\n\n\t\tif (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF &&\n\t\t    DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\t\tduk_tval tv_tmp;\n\n\t\t\tDUK_TVAL_SET_U32(&tv_tmp, (duk_uint32_t) label_id);\n\t\t\tduk__handle_finally(thr, &tv_tmp, lj_type);\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> break/continue caught by 'finally', restart execution\"));\n\t\t\treturn;\n\t\t}\n\t\tif (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_LABEL &&\n\t\t    (duk_uint_t) DUK_CAT_GET_LABEL(cat) == label_id) {\n\t\t\tduk__handle_label(thr, lj_type);\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> break/continue caught by a label catcher (in the same function), restart execution\"));\n\t\t\treturn;\n\t\t}\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t}\n\n\t/* Should never happen, but be robust. */\n\tDUK_D(DUK_DPRINT(\"-> break/continue not caught by anything in the current function (should never happen), throw internal error\"));\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Handle a RETURN opcode.  Avoid using longjmp() for return handling because\n * it has a measurable performance impact in ordinary environments and an extreme\n * impact in Emscripten (GH-342).  Return value is on value stack top.\n */\nDUK_LOCAL duk_small_uint_t duk__handle_return(duk_hthread *thr, duk_activation *entry_act) {\n\tduk_tval *tv1;\n\tduk_tval *tv2;\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\tduk_hthread *resumer;\n#endif\n\tduk_activation *act;\n\tduk_catcher *cat;\n\n\t/* We can directly access value stack here. */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(entry_act != NULL);\n\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\ttv1 = thr->valstack_top - 1;\n\tDUK_TVAL_CHKFAST_INPLACE_FAST(tv1);  /* fastint downgrade check for return values */\n\n\t/*\n\t *  Four possible outcomes:\n\t *\n\t *    1. A 'finally' in the same function catches the 'return'.\n\t *       It may continue to propagate when 'finally' is finished,\n\t *       or it may be neutralized by 'finally' (both handled by\n\t *       ENDFIN).\n\t *\n\t *    2. The return happens at the entry level of the bytecode\n\t *       executor, so return from the executor (in C stack).\n\t *\n\t *    3. There is a calling (ECMAScript) activation in the call\n\t *       stack => return to it, in the same executor instance.\n\t *\n\t *    4. There is no calling activation, and the thread is\n\t *       terminated.  There is always a resumer in this case,\n\t *       which gets the return value similarly to a 'yield'\n\t *       (except that the current thread can no longer be\n\t *       resumed).\n\t */\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\tfor (;;) {\n\t\tcat = act->cat;\n\t\tif (cat == NULL) {\n\t\t\tbreak;\n\t\t}\n\n\t\tif (DUK_CAT_GET_TYPE(cat) == DUK_CAT_TYPE_TCF &&\n\t\t    DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\t\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\t\t\tduk__handle_finally(thr, thr->valstack_top - 1, DUK_LJ_TYPE_RETURN);\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"-> return caught by 'finally', restart execution\"));\n\t\t\treturn DUK__RETHAND_RESTART;\n\t\t}\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t}\n\n\tif (act == entry_act) {\n\t\t/* Return to the bytecode executor caller who will unwind stacks\n\t\t * and handle constructor post-processing.\n\t\t * Return value is already on the stack top: [ ... retval ].\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> return propagated up to entry level, exit bytecode executor\"));\n\t\treturn DUK__RETHAND_FINISHED;\n\t}\n\n\tif (thr->callstack_top >= 2) {\n\t\t/* There is a caller; it MUST be an ECMAScript caller (otherwise it would\n\t\t * match entry_act check).\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"return to ECMAScript caller, retval_byteoff=%ld, lj_value1=%!T\",\n\t\t                     (long) (thr->callstack_curr->parent->retval_byteoff),\n\t\t                     (duk_tval *) &thr->heap->lj.value1));\n\n\t\tDUK_ASSERT(thr->callstack_curr != NULL);\n\t\tDUK_ASSERT(thr->callstack_curr->parent != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr->parent)));   /* must be ECMAScript */\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\tif (thr->callstack_curr->flags & (DUK_ACT_FLAG_CONSTRUCT | DUK_ACT_FLAG_CONSTRUCT_PROXY)) {\n\t\t\tduk_call_construct_postprocess(thr, thr->callstack_curr->flags & DUK_ACT_FLAG_CONSTRUCT_PROXY);  /* side effects */\n\t\t}\n#else\n\t\tif (thr->callstack_curr->flags & DUK_ACT_FLAG_CONSTRUCT) {\n\t\t\tduk_call_construct_postprocess(thr, 0);  /* side effects */\n\t\t}\n#endif\n\n\t\ttv1 = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + thr->callstack_curr->parent->retval_byteoff);\n\t\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\t\ttv2 = thr->valstack_top - 1;\n\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv1, tv2);  /* side effects */\n\n\t\t/* Catch stack unwind happens inline in callstack unwind. */\n\t\tduk_hthread_activation_unwind_norz(thr);\n\n\t\tduk__reconfig_valstack_ecma_return(thr);\n\n\t\tDUK_DD(DUK_DDPRINT(\"-> return not intercepted, restart execution in caller\"));\n\t\treturn DUK__RETHAND_RESTART;\n\t}\n\n#if defined(DUK_USE_COROUTINE_SUPPORT)\n\tDUK_DD(DUK_DDPRINT(\"no calling activation, thread finishes (similar to yield)\"));\n\n\tDUK_ASSERT(thr->resumer != NULL);\n\tDUK_ASSERT(thr->resumer->callstack_top >= 2);  /* ECMAScript activation + Duktape.Thread.resume() activation */\n\tDUK_ASSERT(thr->resumer->callstack_curr != NULL);\n\tDUK_ASSERT(thr->resumer->callstack_curr->parent != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr) != NULL &&\n\t\t\tDUK_HOBJECT_IS_NATFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr)) &&\n\t\t\t((duk_hnatfunc *) DUK_ACT_GET_FUNC(thr->resumer->callstack_curr))->func == duk_bi_thread_resume);  /* Duktape.Thread.resume() */\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent) != NULL &&\n\t\t\tDUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->resumer->callstack_curr->parent)));  /* an ECMAScript function */\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_RUNNING);\n\tDUK_ASSERT(thr->resumer->state == DUK_HTHREAD_STATE_RESUMED);\n\n\tresumer = thr->resumer;\n\n\t/* Share yield longjmp handler.\n\t *\n\t * This sequence of steps is a bit fragile (see GH-1845):\n\t * - We need the return value from 'thr' (resumed thread) value stack.\n\t *   The termination unwinds its value stack, losing the value.\n\t * - We need a refcounted reference for 'thr', which may only exist\n\t *   in the caller value stack.  We can't unwind or reconfigure the\n\t *   caller's value stack without potentially freeing 'thr'.\n\t *\n\t * Current approach is to capture the 'thr' return value and store\n\t * a reference to 'thr' in the caller value stack temporarily.  This\n\t * keeps 'thr' reachable until final yield/return handling which\n\t * removes the references atomatically.\n\t */\n\n\tDUK_ASSERT(thr->valstack_top - 1 >= thr->valstack_bottom);\n\tduk_hthread_activation_unwind_norz(resumer);  /* May remove last reference to 'thr', but is NORZ. */\n\tduk_push_tval(resumer, thr->valstack_top - 1);  /* Capture return value, side effect free. */\n\tduk_push_hthread(resumer, thr);  /* Make 'thr' reachable again, before side effects. */\n\n\tduk_hthread_terminate(thr);  /* Updates thread state, minimizes its allocations. */\n\tthr->resumer = NULL;\n\tDUK_HTHREAD_DECREF(thr, resumer);\n\tDUK_ASSERT(thr->state == DUK_HTHREAD_STATE_TERMINATED);\n\n\tresumer->state = DUK_HTHREAD_STATE_RUNNING;\n\tDUK_HEAP_SWITCH_THREAD(thr->heap, resumer);\n\n\tDUK_ASSERT(resumer->valstack_top - 2 >= resumer->valstack_bottom);\n\tduk__handle_yield(thr, resumer, resumer->valstack_top - 2);\n\tthr = NULL;  /* 'thr' invalidated by call */\n\n#if 0\n\tthr = resumer;  /* not needed */\n#endif\n\n\tDUK_DD(DUK_DDPRINT(\"-> return not caught, thread terminated; handle like yield, restart execution in resumer\"));\n\treturn DUK__RETHAND_RESTART;\n#else\n\t/* Without coroutine support this case should never happen. */\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n#endif\n}\n\n/*\n *  Executor interrupt handling\n *\n *  The handler is called whenever the interrupt countdown reaches zero\n *  (or below).  The handler must perform whatever checks are activated,\n *  e.g. check for cumulative step count to impose an execution step\n *  limit or check for breakpoints or other debugger interaction.\n *\n *  When the actions are done, the handler must reinit the interrupt\n *  init and counter values.  The 'init' value must indicate how many\n *  bytecode instructions are executed before the next interrupt.  The\n *  counter must interface with the bytecode executor loop.  Concretely,\n *  the new init value is normally one higher than the new counter value.\n *  For instance, to execute exactly one bytecode instruction the init\n *  value is set to 1 and the counter to 0.  If an error is thrown by the\n *  interrupt handler, the counters are set to the same value (e.g. both\n *  to 0 to cause an interrupt when the next bytecode instruction is about\n *  to be executed after error handling).\n *\n *  Maintaining the init/counter value properly is important for accurate\n *  behavior.  For instance, executor step limit needs a cumulative step\n *  count which is simply computed as a sum of 'init' values.  This must\n *  work accurately even when single stepping.\n */\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\n#define DUK__INT_NOACTION    0    /* no specific action, resume normal execution */\n#define DUK__INT_RESTART     1    /* must \"goto restart_execution\", e.g. breakpoints changed */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_LOCAL void duk__interrupt_handle_debugger(duk_hthread *thr, duk_bool_t *out_immediate, duk_small_uint_t *out_interrupt_retval) {\n\tduk_activation *act;\n\tduk_breakpoint *bp;\n\tduk_breakpoint **bp_active;\n\tduk_uint_fast32_t line = 0;\n\tduk_bool_t process_messages;\n\tduk_bool_t processed_messages = 0;\n\n\tDUK_ASSERT(thr->heap->dbg_processing == 0);  /* don't re-enter e.g. during Eval */\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\t/* It might seem that replacing 'thr->heap' with just 'heap' below\n\t * might be a good idea, but it increases code size slightly\n\t * (probably due to unnecessary spilling) at least on x64.\n\t */\n\n\t/*\n\t *  Single opcode step check\n\t */\n\n\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE) {\n\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by one opcode step\"));\n\t\tduk_debug_set_paused(thr->heap);\n\t}\n\n\t/*\n\t *  Breakpoint and step state checks\n\t */\n\n\tif (act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE ||\n\t    (thr->heap->dbg_pause_act == thr->callstack_curr)) {\n\t\tline = duk_debug_curr_line(thr);\n\n\t\tif (act->prev_line != line) {\n\t\t\t/* Stepped?  Step out is handled by callstack unwind. */\n\t\t\tif ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) &&\n\t\t\t    (thr->heap->dbg_pause_act == thr->callstack_curr) &&\n\t\t\t    (line != thr->heap->dbg_pause_startline)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by line change, at line %ld\",\n\t\t\t\t                 (long) line));\n\t\t\t\tduk_debug_set_paused(thr->heap);\n\t\t\t}\n\n\t\t\t/* Check for breakpoints only on line transition.\n\t\t\t * Breakpoint is triggered when we enter the target\n\t\t\t * line from a different line, and the previous line\n\t\t\t * was within the same function.\n\t\t\t *\n\t\t\t * This condition is tricky: the condition used to be\n\t\t\t * that transition to -or across- the breakpoint line\n\t\t\t * triggered the breakpoint.  This seems intuitively\n\t\t\t * better because it handles breakpoints on lines with\n\t\t\t * no emitted opcodes; but this leads to the issue\n\t\t\t * described in: https://github.com/svaarala/duktape/issues/263.\n\t\t\t */\n\t\t\tbp_active = thr->heap->dbg_breakpoints_active;\n\t\t\tfor (;;) {\n\t\t\t\tbp = *bp_active++;\n\t\t\t\tif (bp == NULL) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tDUK_ASSERT(bp->filename != NULL);\n\t\t\t\tif (act->prev_line != bp->line && line == bp->line) {\n\t\t\t\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by breakpoint at %!O:%ld\",\n\t\t\t\t\t                 (duk_heaphdr *) bp->filename, (long) bp->line));\n\t\t\t\t\tduk_debug_set_paused(thr->heap);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t;\n\t\t}\n\n\t\tact->prev_line = (duk_uint32_t) line;\n\t}\n\n\t/*\n\t *  Rate limit check for sending status update or peeking into\n\t *  the debug transport.  Both can be expensive operations that\n\t *  we don't want to do on every opcode.\n\t *\n\t *  Making sure the interval remains reasonable on a wide variety\n\t *  of targets and bytecode is difficult without a timestamp, so\n\t *  we use a Date-provided timestamp for the rate limit check.\n\t *  But since it's also expensive to get a timestamp, a bytecode\n\t *  counter is used to rate limit getting timestamps.\n\t */\n\n\tprocess_messages = 0;\n\tif (thr->heap->dbg_state_dirty || DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) || thr->heap->dbg_detaching) {\n\t\t/* Enter message processing loop for sending Status notifys and\n\t\t * to finish a pending detach.\n\t\t */\n\t\tprocess_messages = 1;\n\t}\n\n\t/* XXX: remove heap->dbg_exec_counter, use heap->inst_count_interrupt instead? */\n\tDUK_ASSERT(thr->interrupt_init >= 0);\n\tthr->heap->dbg_exec_counter += (duk_uint_t) thr->interrupt_init;\n\tif (thr->heap->dbg_exec_counter - thr->heap->dbg_last_counter >= DUK_HEAP_DBG_RATELIMIT_OPCODES) {\n\t\t/* Overflow of the execution counter is fine and doesn't break\n\t\t * anything here.\n\t\t */\n\n\t\tduk_double_t now, diff_last;\n\n\t\tthr->heap->dbg_last_counter = thr->heap->dbg_exec_counter;\n\t\tnow = duk_time_get_monotonic_time(thr);\n\n\t\tdiff_last = now - thr->heap->dbg_last_time;\n\t\tif (diff_last < 0.0 || diff_last >= (duk_double_t) DUK_HEAP_DBG_RATELIMIT_MILLISECS) {\n\t\t\t/* Monotonic time should not experience time jumps,\n\t\t\t * but the provider may be missing and we're actually\n\t\t\t * using ECMAScript time.  So, tolerate negative values\n\t\t\t * so that a time jump works reasonably.\n\t\t\t *\n\t\t\t * Same interval is now used for status sending and\n\t\t\t * peeking.\n\t\t\t */\n\n\t\t\tthr->heap->dbg_last_time = now;\n\t\t\tthr->heap->dbg_state_dirty = 1;\n\t\t\tprocess_messages = 1;\n\t\t}\n\t}\n\n\t/*\n\t *  Process messages and send status if necessary.\n\t *\n\t *  If we're paused, we'll block for new messages.  If we're not\n\t *  paused, we'll process anything we can peek but won't block\n\t *  for more.  Detach (and re-attach) handling is all localized\n\t *  to duk_debug_process_messages() too.\n\t *\n\t *  Debugger writes outside the message loop may cause debugger\n\t *  detach1 phase to run, after which dbg_read_cb == NULL and\n\t *  dbg_detaching != 0.  The message loop will finish the detach\n\t *  by running detach2 phase, so enter the message loop also when\n\t *  detaching.\n\t */\n\n\tif (process_messages) {\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\t\tprocessed_messages = duk_debug_process_messages(thr, 0 /*no_block*/);\n\t\tDUK_ASSERT(thr->heap->dbg_processing == 0);\n\t}\n\n\t/* Continue checked execution if there are breakpoints or we're stepping.\n\t * Also use checked execution if paused flag is active - it shouldn't be\n\t * because the debug message loop shouldn't terminate if it was.  Step out\n\t * is handled by callstack unwind and doesn't need checked execution.\n\t * Note that debugger may have detached due to error or explicit request\n\t * above, so we must recheck attach status.\n\t */\n\n\tif (duk_debug_is_attached(thr->heap)) {\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t\tif (act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE ||\n\t\t    (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE) ||\n\t\t    ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) &&\n\t\t     thr->heap->dbg_pause_act == thr->callstack_curr) ||\n\t\t     DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap)) {\n\t\t\t*out_immediate = 1;\n\t\t}\n\n\t\t/* If we processed any debug messages breakpoints may have\n\t\t * changed; restart execution to re-check active breakpoints.\n\t\t */\n\t\tif (processed_messages) {\n\t\t\tDUK_D(DUK_DPRINT(\"processed debug messages, restart execution to recheck possibly changed breakpoints\"));\n\t\t\t*out_interrupt_retval = DUK__INT_RESTART;\n\t\t} else {\n\t\t\tif (thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_ONE_OPCODE) {\n\t\t\t\t/* Set 'pause after one opcode' active only when we're\n\t\t\t\t * actually just about to execute code.\n\t\t\t\t */\n\t\t\t\tthr->heap->dbg_pause_flags |= DUK_PAUSE_FLAG_ONE_OPCODE_ACTIVE;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tDUK_D(DUK_DPRINT(\"debugger became detached, resume normal execution\"));\n\t}\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\nDUK_LOCAL DUK__NOINLINE_PERF DUK_COLD duk_small_uint_t duk__executor_interrupt(duk_hthread *thr) {\n\tduk_int_t ctr;\n\tduk_activation *act;\n\tduk_hcompfunc *fun;\n\tduk_bool_t immediate = 0;\n\tduk_small_uint_t retval;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->heap != NULL);\n\tDUK_ASSERT(thr->callstack_top > 0);\n\n#if defined(DUK_USE_DEBUG)\n\tthr->heap->inst_count_interrupt += thr->interrupt_init;\n\tDUK_DD(DUK_DDPRINT(\"execution interrupt, counter=%ld, init=%ld, \"\n\t                   \"instruction counts: executor=%ld, interrupt=%ld\",\n\t                   (long) thr->interrupt_counter, (long) thr->interrupt_init,\n\t                   (long) thr->heap->inst_count_exec, (long) thr->heap->inst_count_interrupt));\n#endif\n\n\tretval = DUK__INT_NOACTION;\n\tctr = DUK_HTHREAD_INTCTR_DEFAULT;\n\n\t/*\n\t *  Avoid nested calls.  Concretely this happens during debugging, e.g.\n\t *  when we eval() an expression.\n\t *\n\t *  Also don't interrupt if we're currently doing debug processing\n\t *  (which can be initiated outside the bytecode executor) as this\n\t *  may cause the debugger to be called recursively.  Check required\n\t *  for correct operation of throw intercept and other \"exotic\" halting\n\t * scenarios.\n\t */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (DUK_HEAP_HAS_INTERRUPT_RUNNING(thr->heap) || thr->heap->dbg_processing) {\n#else\n\tif (DUK_HEAP_HAS_INTERRUPT_RUNNING(thr->heap)) {\n#endif\n\t\tDUK_DD(DUK_DDPRINT(\"nested executor interrupt, ignoring\"));\n\n\t\t/* Set a high interrupt counter; the original executor\n\t\t * interrupt invocation will rewrite before exiting.\n\t\t */\n\t\tthr->interrupt_init = ctr;\n\t\tthr->interrupt_counter = ctr - 1;\n\t\treturn DUK__INT_NOACTION;\n\t}\n\tDUK_HEAP_SET_INTERRUPT_RUNNING(thr->heap);\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\n\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC((duk_hobject *) fun));\n\n\tDUK_UNREF(fun);\n\n#if defined(DUK_USE_EXEC_TIMEOUT_CHECK)\n\t/*\n\t *  Execution timeout check\n\t */\n\n\tif (DUK_USE_EXEC_TIMEOUT_CHECK(thr->heap->heap_udata)) {\n\t\t/* Keep throwing an error whenever we get here.  The unusual values\n\t\t * are set this way because no instruction is ever executed, we just\n\t\t * throw an error until all try/catch/finally and other catchpoints\n\t\t * have been exhausted.  Duktape/C code gets control at each protected\n\t\t * call but whenever it enters back into Duktape the RangeError gets\n\t\t * raised.  User exec timeout check must consistently indicate a timeout\n\t\t * until we've fully bubbled out of Duktape.\n\t\t */\n\t\tDUK_D(DUK_DPRINT(\"execution timeout, throwing a RangeError\"));\n\t\tthr->interrupt_init = 0;\n\t\tthr->interrupt_counter = 0;\n\t\tDUK_HEAP_CLEAR_INTERRUPT_RUNNING(thr->heap);\n\t\tDUK_ERROR_RANGE(thr, \"execution timeout\");\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n#endif  /* DUK_USE_EXEC_TIMEOUT_CHECK */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tif (!thr->heap->dbg_processing &&\n\t    (thr->heap->dbg_read_cb != NULL || thr->heap->dbg_detaching)) {\n\t\t/* Avoid recursive re-entry; enter when we're attached or\n\t\t * detaching (to finish off the pending detach).\n\t\t */\n\t\tduk__interrupt_handle_debugger(thr, &immediate, &retval);\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n\t/*\n\t *  Update the interrupt counter\n\t */\n\n\tif (immediate) {\n\t\t/* Cause an interrupt after executing one instruction. */\n\t\tctr = 1;\n\t}\n\n\t/* The counter value is one less than the init value: init value should\n\t * indicate how many instructions are executed before interrupt.  To\n\t * execute 1 instruction (after interrupt handler return), counter must\n\t * be 0.\n\t */\n\tDUK_ASSERT(ctr >= 1);\n\tthr->interrupt_init = ctr;\n\tthr->interrupt_counter = ctr - 1;\n\tDUK_HEAP_CLEAR_INTERRUPT_RUNNING(thr->heap);\n\n\treturn retval;\n}\n#endif  /* DUK_USE_INTERRUPT_COUNTER */\n\n/*\n *  Debugger handling for executor restart\n *\n *  Check for breakpoints, stepping, etc, and figure out if we should execute\n *  in checked or normal mode.  Note that we can't do this when an activation\n *  is created, because breakpoint status (and stepping status) may change\n *  later, so we must recheck every time we're executing an activation.\n *  This primitive should be side effect free to avoid changes during check.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\nDUK_LOCAL void duk__executor_recheck_debugger(duk_hthread *thr, duk_activation *act, duk_hcompfunc *fun) {\n\tduk_heap *heap;\n\tduk_tval *tv_tmp;\n\tduk_hstring *filename;\n\tduk_small_uint_t bp_idx;\n\tduk_breakpoint **bp_active;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(fun != NULL);\n\n\theap = thr->heap;\n\tbp_active = heap->dbg_breakpoints_active;\n\tact->flags &= ~DUK_ACT_FLAG_BREAKPOINT_ACTIVE;\n\n\ttv_tmp = duk_hobject_find_entry_tval_ptr_stridx(thr->heap, (duk_hobject *) fun, DUK_STRIDX_FILE_NAME);\n\tif (tv_tmp && DUK_TVAL_IS_STRING(tv_tmp)) {\n\t\tfilename = DUK_TVAL_GET_STRING(tv_tmp);\n\n\t\t/* Figure out all active breakpoints.  A breakpoint is\n\t\t * considered active if the current function's fileName\n\t\t * matches the breakpoint's fileName, AND there is no\n\t\t * inner function that has matching line numbers\n\t\t * (otherwise a breakpoint would be triggered both\n\t\t * inside and outside of the inner function which would\n\t\t * be confusing).  Example:\n\t\t *\n\t\t *     function foo() {\n\t\t *         print('foo');\n\t\t *         function bar() {    <-.  breakpoints in these\n\t\t *             print('bar');     |  lines should not affect\n\t\t *         }                   <-'  foo() execution\n\t\t *         bar();\n\t\t *     }\n\t\t *\n\t\t * We need a few things that are only available when\n\t\t * debugger support is enabled: (1) a line range for\n\t\t * each function, and (2) access to the function\n\t\t * template to access the inner functions (and their\n\t\t * line ranges).\n\t\t *\n\t\t * It's important to have a narrow match for active\n\t\t * breakpoints so that we don't enter checked execution\n\t\t * when that's not necessary.  For instance, if we're\n\t\t * running inside a certain function and there's\n\t\t * breakpoint outside in (after the call site), we\n\t\t * don't want to slow down execution of the function.\n\t\t */\n\n\t\tfor (bp_idx = 0; bp_idx < heap->dbg_breakpoint_count; bp_idx++) {\n\t\t\tduk_breakpoint *bp = heap->dbg_breakpoints + bp_idx;\n\t\t\tduk_hobject **funcs, **funcs_end;\n\t\t\tduk_hcompfunc *inner_fun;\n\t\t\tduk_bool_t bp_match;\n\n\t\t\tif (bp->filename == filename &&\n\t\t\t    bp->line >= fun->start_line && bp->line <= fun->end_line) {\n\t\t\t\tbp_match = 1;\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"breakpoint filename and line match: \"\n\t\t\t\t                   \"%s:%ld vs. %s (line %ld vs. %ld-%ld)\",\n\t\t\t\t                   DUK_HSTRING_GET_DATA(bp->filename),\n\t\t\t\t                   (long) bp->line,\n\t\t\t\t                   DUK_HSTRING_GET_DATA(filename),\n\t\t\t\t                   (long) bp->line,\n\t\t\t\t                   (long) fun->start_line,\n\t\t\t\t                   (long) fun->end_line));\n\n\t\t\t\tfuncs = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, fun);\n\t\t\t\tfuncs_end = DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, fun);\n\t\t\t\twhile (funcs != funcs_end) {\n\t\t\t\t\tinner_fun = (duk_hcompfunc *) *funcs;\n\t\t\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) inner_fun));\n\t\t\t\t\tif (bp->line >= inner_fun->start_line && bp->line <= inner_fun->end_line) {\n\t\t\t\t\t\tDUK_DD(DUK_DDPRINT(\"inner function masks ('captures') breakpoint\"));\n\t\t\t\t\t\tbp_match = 0;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tfuncs++;\n\t\t\t\t}\n\n\t\t\t\tif (bp_match) {\n\t\t\t\t\t/* No need to check for size of bp_active list,\n\t\t\t\t\t * it's always larger than maximum number of\n\t\t\t\t\t * breakpoints.\n\t\t\t\t\t */\n\t\t\t\t\tact->flags |= DUK_ACT_FLAG_BREAKPOINT_ACTIVE;\n\t\t\t\t\t*bp_active = heap->dbg_breakpoints + bp_idx;\n\t\t\t\t\tbp_active++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t*bp_active = NULL;  /* terminate */\n\n\tDUK_DD(DUK_DDPRINT(\"ACTIVE BREAKPOINTS: %ld\", (long) (bp_active - thr->heap->dbg_breakpoints_active)));\n\n\t/* Force pause if we were doing \"step into\" in another activation. */\n\tif ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_FUNC_ENTRY) &&\n\t    thr->heap->dbg_pause_act != thr->callstack_curr) {\n\t\tDUK_D(DUK_DPRINT(\"PAUSE TRIGGERED by function entry\"));\n\t\tduk_debug_set_paused(thr->heap);\n\t}\n\n\t/* Force interrupt right away if we're paused or in \"checked mode\".\n\t * Step out is handled by callstack unwind.\n\t */\n\tif ((act->flags & DUK_ACT_FLAG_BREAKPOINT_ACTIVE) ||\n\t    DUK_HEAP_HAS_DEBUGGER_PAUSED(thr->heap) ||\n\t    ((thr->heap->dbg_pause_flags & DUK_PAUSE_FLAG_LINE_CHANGE) &&\n\t     thr->heap->dbg_pause_act == thr->callstack_curr)) {\n\t\t/* We'll need to interrupt early so recompute the init\n\t\t * counter to reflect the number of bytecode instructions\n\t\t * executed so that step counts for e.g. debugger rate\n\t\t * limiting are accurate.\n\t\t */\n\t\tDUK_ASSERT(thr->interrupt_counter <= thr->interrupt_init);\n\t\tthr->interrupt_init = thr->interrupt_init - thr->interrupt_counter;\n\t\tthr->interrupt_counter = 0;\n\t}\n}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n/*\n *  Opcode handlers for opcodes with a lot of code and which are relatively\n *  rare; NOINLINE to reduce amount of code in main bytecode dispatcher.\n */\n\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_initset_initget(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_bool_t is_set = (DUK_DEC_OP(ins) == DUK_OP_INITSET);\n\tduk_uint_fast_t idx;\n\tduk_uint_t defprop_flags;\n\n\t/* A -> object register (acts as a source)\n\t * BC -> BC+0 contains key, BC+1 closure (value)\n\t */\n\n\t/* INITSET/INITGET are only used to initialize object literal keys.\n\t * There may be a previous propery in ES2015 because duplicate property\n\t * names are allowed.\n\t */\n\n\t/* This could be made more optimal by accessing internals directly. */\n\n\tidx = (duk_uint_fast_t) DUK_DEC_BC(ins);\n\tduk_dup(thr, (duk_idx_t) (idx + 0));  /* key */\n\tduk_dup(thr, (duk_idx_t) (idx + 1));  /* getter/setter */\n\tif (is_set) {\n\t        defprop_flags = DUK_DEFPROP_HAVE_SETTER |\n\t                        DUK_DEFPROP_FORCE |\n\t                        DUK_DEFPROP_SET_ENUMERABLE |\n\t                        DUK_DEFPROP_SET_CONFIGURABLE;\n\t} else {\n\t        defprop_flags = DUK_DEFPROP_HAVE_GETTER |\n\t                        DUK_DEFPROP_FORCE |\n\t                        DUK_DEFPROP_SET_ENUMERABLE |\n\t                        DUK_DEFPROP_SET_CONFIGURABLE;\n\t}\n\tduk_def_prop(thr, (duk_idx_t) DUK_DEC_A(ins), defprop_flags);\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_trycatch(duk_hthread *thr, duk_uint_fast32_t ins, duk_instr_t *curr_pc) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_tval *tv1;\n\tduk_small_uint_fast_t a;\n\tduk_small_uint_fast_t bc;\n\n\t/* A -> flags\n\t * BC -> reg_catch; base register for two registers used both during\n\t *       trycatch setup and when catch is triggered\n\t *\n\t *      If DUK_BC_TRYCATCH_FLAG_CATCH_BINDING set:\n\t *          reg_catch + 0: catch binding variable name (string).\n\t *          Automatic declarative environment is established for\n\t *          the duration of the 'catch' clause.\n\t *\n\t *      If DUK_BC_TRYCATCH_FLAG_WITH_BINDING set:\n\t *          reg_catch + 0: with 'target value', which is coerced to\n\t *          an object and then used as a bindind object for an\n\t *          environment record.  The binding is initialized here, for\n\t *          the 'try' clause.\n\t *\n\t * Note that a TRYCATCH generated for a 'with' statement has no\n\t * catch or finally parts.\n\t */\n\n\t/* XXX: TRYCATCH handling should be reworked to avoid creating\n\t * an explicit scope unless it is actually needed (e.g. function\n\t * instances or eval is executed inside the catch block).  This\n\t * rework is not trivial because the compiler doesn't have an\n\t * intermediate representation.  When the rework is done, the\n\t * opcode format can also be made more straightforward.\n\t */\n\n\t/* XXX: side effect handling is quite awkward here */\n\n\tDUK_DDD(DUK_DDDPRINT(\"TRYCATCH: reg_catch=%ld, have_catch=%ld, \"\n\t                     \"have_finally=%ld, catch_binding=%ld, with_binding=%ld (flags=0x%02lx)\",\n\t                     (long) DUK_DEC_BC(ins),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH ? 1 : 0),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY ? 1 : 0),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_CATCH_BINDING ? 1 : 0),\n\t                     (long) (DUK_DEC_A(ins) & DUK_BC_TRYCATCH_FLAG_WITH_BINDING ? 1 : 0),\n\t                     (unsigned long) DUK_DEC_A(ins)));\n\n\ta = DUK_DEC_A(ins);\n\tbc = DUK_DEC_BC(ins);\n\n\t/* Registers 'bc' and 'bc + 1' are written in longjmp handling\n\t * and if their previous values (which are temporaries) become\n\t * unreachable -and- have a finalizer, there'll be a function\n\t * call during error handling which is not supported now (GH-287).\n\t * Ensure that both 'bc' and 'bc + 1' have primitive values to\n\t * guarantee no finalizer calls in error handling.  Scrubbing also\n\t * ensures finalizers for the previous values run here rather than\n\t * later.  Error handling related values are also written to 'bc'\n\t * and 'bc + 1' but those values never become unreachable during\n\t * error handling, so there's no side effect problem even if the\n\t * error value has a finalizer.\n\t */\n\tduk_dup(thr, (duk_idx_t) bc);  /* Stabilize value. */\n\tduk_to_undefined(thr, (duk_idx_t) bc);\n\tduk_to_undefined(thr, (duk_idx_t) (bc + 1));\n\n\t/* Allocate catcher and populate it.  Doesn't have to\n\t * be fully atomic, but the catcher must be in a\n\t * consistent state if side effects (such as finalizer\n\t * calls) occur.\n\t */\n\n\tcat = duk_hthread_catcher_alloc(thr);\n\tDUK_ASSERT(cat != NULL);\n\n\tcat->flags = DUK_CAT_TYPE_TCF;\n\tcat->h_varname = NULL;\n\tcat->pc_base = (duk_instr_t *) curr_pc;  /* pre-incremented, points to first jump slot */\n\tcat->idx_base = (duk_size_t) (thr->valstack_bottom - thr->valstack) + bc;\n\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tcat->parent = act->cat;\n\tact->cat = cat;\n\n\tif (a & DUK_BC_TRYCATCH_FLAG_HAVE_CATCH) {\n\t\tcat->flags |= DUK_CAT_FLAG_CATCH_ENABLED;\n\t}\n\tif (a & DUK_BC_TRYCATCH_FLAG_HAVE_FINALLY) {\n\t\tcat->flags |= DUK_CAT_FLAG_FINALLY_ENABLED;\n\t}\n\tif (a & DUK_BC_TRYCATCH_FLAG_CATCH_BINDING) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"catch binding flag set to catcher\"));\n\t\tcat->flags |= DUK_CAT_FLAG_CATCH_BINDING_ENABLED;\n\t\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\n\t\t/* borrowed reference; although 'tv1' comes from a register,\n\t\t * its value was loaded using LDCONST so the constant will\n\t\t * also exist and be reachable.\n\t\t */\n\t\tcat->h_varname = DUK_TVAL_GET_STRING(tv1);\n\t} else if (a & DUK_BC_TRYCATCH_FLAG_WITH_BINDING) {\n\t\tduk_hobjenv *env;\n\t\tduk_hobject *target;\n\n\t\t/* Delayed env initialization for activation (if needed). */\n\t\tDUK_ASSERT(thr->callstack_top >= 1);\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t\tif (act->lex_env == NULL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"delayed environment initialization\"));\n\t\t\tDUK_ASSERT(act->var_env == NULL);\n\n\t\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\t\tDUK_UNREF(act);  /* 'act' is no longer accessed, scanbuild fix */\n\t\t}\n\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\tDUK_ASSERT(act->var_env != NULL);\n\n\t\t/* Coerce 'with' target. */\n\t\ttarget = duk_to_hobject(thr, -1);\n\t\tDUK_ASSERT(target != NULL);\n\n\t\t/* Create an object environment; it is not pushed\n\t\t * so avoid side effects very carefully until it is\n\t\t * referenced.\n\t\t */\n\t\tenv = duk_hobjenv_alloc(thr,\n\t\t                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_OBJENV));\n\t\tDUK_ASSERT(env != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);\n\t\tenv->target = target;  /* always provideThis=true */\n\t\tDUK_HOBJECT_INCREF(thr, target);\n\t\tenv->has_this = 1;\n\t\tDUK_HOBJENV_ASSERT_VALID(env);\n\t\tDUK_DDD(DUK_DDDPRINT(\"environment for with binding: %!iO\", env));\n\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);\n\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) env, act->lex_env);\n\t\tact->lex_env = (duk_hobject *) env;  /* Now reachable. */\n\t\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) env);\n\t\t/* Net refcount change to act->lex_env is 0: incref for env's\n\t\t * prototype, decref for act->lex_env overwrite.\n\t\t */\n\n\t\t/* Set catcher lex_env active (affects unwind)\n\t\t * only when the whole setup is complete.\n\t\t */\n\t\tcat = act->cat;  /* XXX: better to relookup? not mandatory because 'cat' is stable */\n\t\tcat->flags |= DUK_CAT_FLAG_LEXENV_ACTIVE;\n\t} else {\n\t\t;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"TRYCATCH catcher: flags=0x%08lx, pc_base=%ld, \"\n\t                     \"idx_base=%ld, h_varname=%!O\",\n\t                     (unsigned long) cat->flags,\n\t                     (long) cat->pc_base, (long) cat->idx_base, (duk_heaphdr *) cat->h_varname));\n\n\tduk_pop_unsafe(thr);\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_instr_t *duk__handle_op_endtry(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_tval *tv1;\n\tduk_instr_t *pc_base;\n\n\tDUK_UNREF(ins);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_TCF);\n\n\tDUK_DDD(DUK_DDDPRINT(\"ENDTRY: clearing catch active flag (regardless of whether it was set or not)\"));\n\tDUK_CAT_CLEAR_CATCH_ENABLED(cat);\n\n\tpc_base = cat->pc_base;\n\n\tif (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDTRY: finally part is active, jump through 2nd jump slot with 'normal continuation'\"));\n\n\t\ttv1 = thr->valstack + cat->idx_base;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\ttv1 = thr->valstack + cat->idx_base + 1;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_U32_UPDREF(thr, tv1, (duk_uint32_t) DUK_LJ_TYPE_NORMAL);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\tDUK_CAT_CLEAR_FINALLY_ENABLED(cat);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDTRY: no finally part, dismantle catcher, jump through 2nd jump slot (to end of statement)\"));\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);  /* lexenv may be set for 'with' binding */\n\t\t/* no need to unwind callstack */\n\t}\n\n\treturn pc_base + 1;  /* new curr_pc value */\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_instr_t *duk__handle_op_endcatch(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_activation *act;\n\tduk_catcher *cat;\n\tduk_tval *tv1;\n\tduk_instr_t *pc_base;\n\n\tDUK_UNREF(ins);\n\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\tcat = act->cat;\n\tDUK_ASSERT(cat != NULL);\n\tDUK_ASSERT(!DUK_CAT_HAS_CATCH_ENABLED(cat));  /* cleared before entering catch part */\n\n\tif (DUK_CAT_HAS_LEXENV_ACTIVE(cat)) {\n\t\tduk_hobject *prev_env;\n\n\t\t/* 'with' binding has no catch clause, so can't be here unless a normal try-catch */\n\t\tDUK_ASSERT(DUK_CAT_HAS_CATCH_BINDING_ENABLED(cat));\n\t\tDUK_ASSERT(act->lex_env != NULL);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDCATCH: popping catcher part lexical environment\"));\n\n\t\tprev_env = act->lex_env;\n\t\tDUK_ASSERT(prev_env != NULL);\n\t\tact->lex_env = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, prev_env);\n\t\tDUK_CAT_CLEAR_LEXENV_ACTIVE(cat);\n\t\tDUK_HOBJECT_INCREF(thr, act->lex_env);\n\t\tDUK_HOBJECT_DECREF(thr, prev_env);  /* side effects */\n\n\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\tDUK_ASSERT(act != NULL);\n\t}\n\n\tpc_base = cat->pc_base;\n\n\tif (DUK_CAT_HAS_FINALLY_ENABLED(cat)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDCATCH: finally part is active, jump through 2nd jump slot with 'normal continuation'\"));\n\n\t\ttv1 = thr->valstack + cat->idx_base;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\ttv1 = thr->valstack + cat->idx_base + 1;\n\t\tDUK_ASSERT(tv1 >= thr->valstack && tv1 < thr->valstack_top);\n\t\tDUK_TVAL_SET_U32_UPDREF(thr, tv1, (duk_uint32_t) DUK_LJ_TYPE_NORMAL);  /* side effects */\n\t\ttv1 = NULL;\n\n\t\tDUK_CAT_CLEAR_FINALLY_ENABLED(cat);\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDCATCH: no finally part, dismantle catcher, jump through 2nd jump slot (to end of statement)\"));\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t\t/* no need to unwind callstack */\n\t}\n\n\treturn pc_base + 1;  /* new curr_pc value */\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_small_uint_t duk__handle_op_endfin(duk_hthread *thr, duk_uint_fast32_t ins, duk_activation *entry_act) {\n\tduk_activation *act;\n\tduk_tval *tv1;\n\tduk_uint_t reg_catch;\n\tduk_small_uint_t cont_type;\n\tduk_small_uint_t ret_result;\n\n\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tact = thr->callstack_curr;\n\tDUK_ASSERT(act != NULL);\n\treg_catch = DUK_DEC_ABC(ins);\n\n\t/* CATCH flag may be enabled or disabled here; it may be enabled if\n\t * the statement has a catch block but the try block does not throw\n\t * an error.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: completion value=%!T, type=%!T\",\n\t                     (duk_tval *) (thr->valstack_bottom + reg_catch + 0),\n\t                     (duk_tval *) (thr->valstack_bottom + reg_catch + 1)));\n\n\ttv1 = thr->valstack_bottom + reg_catch + 1;  /* type */\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\tcont_type = (duk_small_uint_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\tcont_type = (duk_small_uint_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\n\ttv1--;  /* value */\n\n\tswitch (cont_type) {\n\tcase DUK_LJ_TYPE_NORMAL: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: finally part finishing with 'normal' (non-abrupt) completion -> \"\n\t\t                     \"dismantle catcher, resume execution after ENDFIN\"));\n\n\t\tduk_hthread_catcher_unwind_norz(thr, act);\n\t\t/* no need to unwind callstack */\n\t\treturn 0;  /* restart execution */\n\t}\n\tcase DUK_LJ_TYPE_RETURN: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: finally part finishing with 'return' complation -> dismantle \"\n\t\t                     \"catcher, handle return, lj.value1=%!T\", tv1));\n\n\t\t/* Not necessary to unwind catch stack: return handling will\n\t\t * do it.  The finally flag of 'cat' is no longer set.  The\n\t\t * catch flag may be set, but it's not checked by return handling.\n\t\t */\n\n\t\tduk_push_tval(thr, tv1);\n\t\tret_result = duk__handle_return(thr, entry_act);\n\t\tif (ret_result == DUK__RETHAND_RESTART) {\n\t\t\treturn 0;  /* restart execution */\n\t\t}\n\t\tDUK_ASSERT(ret_result == DUK__RETHAND_FINISHED);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"exiting executor after ENDFIN and RETURN (pseudo) longjmp type\"));\n\t\treturn 1;  /* exit executor */\n\t}\n\tcase DUK_LJ_TYPE_BREAK:\n\tcase DUK_LJ_TYPE_CONTINUE: {\n\t\tduk_uint_t label_id;\n\t\tduk_small_uint_t lj_type;\n\n\t\t/* Not necessary to unwind catch stack: break/continue\n\t\t * handling will do it.  The finally flag of 'cat' is\n\t\t * no longer set.  The catch flag may be set, but it's\n\t\t * not checked by break/continue handling.\n\t\t */\n\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\tlabel_id = (duk_small_uint_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\t\tlabel_id = (duk_small_uint_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\tlj_type = cont_type;\n\t\tduk__handle_break_or_continue(thr, label_id, lj_type);\n\t\treturn 0;  /* restart execution */\n\t}\n\tdefault: {\n\t\tDUK_DDD(DUK_DDDPRINT(\"ENDFIN: finally part finishing with abrupt completion, lj_type=%ld -> \"\n\t\t                     \"dismantle catcher, re-throw error\",\n\t\t                     (long) cont_type));\n\n\t\tduk_err_setup_ljstate1(thr, (duk_small_uint_t) cont_type, tv1);\n\t\t/* No debugger Throw notify check on purpose (rethrow). */\n\n\t\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* always in executor */\n\t\tduk_err_longjmp(thr);\n\t\tDUK_UNREACHABLE();\n\t}\n\t}\n\n\tDUK_UNREACHABLE();\n\treturn 0;\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF void duk__handle_op_initenum(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_small_uint_t b;\n\tduk_small_uint_t c;\n\n\t/*\n\t *  Enumeration semantics come from for-in statement, E5 Section 12.6.4.\n\t *  If called with 'null' or 'undefined', this opcode returns 'null' as\n\t *  the enumerator, which is special cased in NEXTENUM.  This simplifies\n\t *  the compiler part\n\t */\n\n\t/* B -> register for writing enumerator object\n\t * C -> value to be enumerated (register)\n\t */\n\tb = DUK_DEC_B(ins);\n\tc = DUK_DEC_C(ins);\n\n\tif (duk_is_null_or_undefined(thr, (duk_idx_t) c)) {\n\t\tduk_push_null(thr);\n\t\tduk_replace(thr, (duk_idx_t) b);\n\t} else {\n\t\tduk_dup(thr, (duk_idx_t) c);\n\t\tduk_to_object(thr, -1);\n\t\tduk_hobject_enumerator_create(thr, 0 /*enum_flags*/);  /* [ ... val ] --> [ ... enum ] */\n\t\tduk_replace(thr, (duk_idx_t) b);\n\t}\n}\n\nDUK_LOCAL DUK__NOINLINE_PERF duk_small_uint_t duk__handle_op_nextenum(duk_hthread *thr, duk_uint_fast32_t ins) {\n\tduk_small_uint_t b;\n\tduk_small_uint_t c;\n\tduk_small_uint_t pc_skip = 0;\n\n\t/*\n\t *  NEXTENUM checks whether the enumerator still has unenumerated\n\t *  keys.  If so, the next key is loaded to the target register\n\t *  and the next instruction is skipped.  Otherwise the next instruction\n\t *  will be executed, jumping out of the enumeration loop.\n\t */\n\n\t/* B -> target register for next key\n\t * C -> enum register\n\t */\n\tb = DUK_DEC_B(ins);\n\tc = DUK_DEC_C(ins);\n\n\tDUK_DDD(DUK_DDDPRINT(\"NEXTENUM: b->%!T, c->%!T\",\n\t                     (duk_tval *) duk_get_tval(thr, (duk_idx_t) b),\n\t                     (duk_tval *) duk_get_tval(thr, (duk_idx_t) c)));\n\n\tif (duk_is_object(thr, (duk_idx_t) c)) {\n\t\t/* XXX: assert 'c' is an enumerator */\n\t\tduk_dup(thr, (duk_idx_t) c);\n\t\tif (duk_hobject_enumerator_next(thr, 0 /*get_value*/)) {\n\t\t\t/* [ ... enum ] -> [ ... next_key ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"enum active, next key is %!T, skip jump slot \",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\t\tpc_skip = 1;\n\t\t} else {\n\t\t\t/* [ ... enum ] -> [ ... ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"enum finished, execute jump slot\"));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* valstack policy */\n\t\t\tthr->valstack_top++;\n\t\t}\n\t\tduk_replace(thr, (duk_idx_t) b);\n\t} else {\n\t\t/* 'null' enumerator case -> behave as with an empty enumerator */\n\t\tDUK_ASSERT(duk_is_null(thr, (duk_idx_t) c));\n\t\tDUK_DDD(DUK_DDDPRINT(\"enum is null, execute jump slot\"));\n\t}\n\n\treturn pc_skip;\n}\n\n/*\n *  Call handling helpers.\n */\n\nDUK_LOCAL duk_bool_t duk__executor_handle_call(duk_hthread *thr, duk_idx_t idx, duk_idx_t nargs, duk_small_uint_t call_flags) {\n\tduk_bool_t rc;\n\n\tduk_set_top_unsafe(thr, (duk_idx_t) (idx + nargs + 2));   /* [ ... func this arg1 ... argN ] */\n\n\t/* Attempt an Ecma-to-Ecma call setup.  If the call\n\t * target is (directly or indirectly) Reflect.construct(),\n\t * the call may change into a constructor call on the fly.\n\t */\n\trc = (duk_bool_t) duk_handle_call_unprotected(thr, idx, call_flags);\n\tif (rc != 0) {\n\t\t/* Ecma-to-ecma call possible, may or may not\n\t\t * be a tail call.  Avoid C recursion by\n\t\t * reusing current executor instance.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"ecma-to-ecma call setup possible, restart execution\"));\n\t\t/* curr_pc synced by duk_handle_call_unprotected() */\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\treturn rc;\n\t} else {\n\t\t/* Call was handled inline. */\n\t}\n\tDUK_ASSERT(thr->ptr_curr_pc != NULL);\n\treturn rc;\n}\n\n/*\n *  ECMAScript bytecode executor.\n *\n *  Resume execution for the current thread from its current activation.\n *  Returns when execution would return from the entry level activation,\n *  leaving a single return value on top of the stack.  Function calls\n *  and thread resumptions are handled internally.  If an error occurs,\n *  a longjmp() with type DUK_LJ_TYPE_THROW is called on the entry level\n *  setjmp() jmpbuf.\n *\n *  ECMAScript function calls and coroutine resumptions are handled\n *  internally (by the outer executor function) without recursive C calls.\n *  Other function calls are handled using duk_handle_call(), increasing\n *  C recursion depth.\n *\n *  Abrupt completions (= long control tranfers) are handled either\n *  directly by reconfiguring relevant stacks and restarting execution,\n *  or via a longjmp.  Longjmp-free handling is preferable for performance\n *  (especially Emscripten performance), and is used for: break, continue,\n *  and return.\n *\n *  For more detailed notes, see doc/execution.rst.\n *\n *  Also see doc/code-issues.rst for discussion of setjmp(), longjmp(),\n *  and volatile.\n */\n\n/* Presence of 'fun' is config based, there's a marginal performance\n * difference and the best option is architecture dependent.\n */\n#if defined(DUK_USE_EXEC_FUN_LOCAL)\n#define DUK__FUN()          fun\n#else\n#define DUK__FUN()          ((duk_hcompfunc *) DUK_ACT_GET_FUNC((thr)->callstack_curr))\n#endif\n\n/* Strict flag. */\n#define DUK__STRICT()       ((duk_small_uint_t) DUK_HOBJECT_HAS_STRICT((duk_hobject *) DUK__FUN()))\n\n/* Reg/const access macros: these are very footprint and performance sensitive\n * so modify with care.  Arguments are sometimes evaluated multiple times which\n * is not ideal.\n */\n#define DUK__REG(x)         (*(thr->valstack_bottom + (x)))\n#define DUK__REGP(x)        (thr->valstack_bottom + (x))\n#define DUK__CONST(x)       (*(consts + (x)))\n#define DUK__CONSTP(x)      (consts + (x))\n\n/* Reg/const access macros which take the 32-bit instruction and avoid an\n * explicit field decoding step by using shifts and masks.  These must be\n * kept in sync with duk_js_bytecode.h.  The shift/mask values are chosen\n * so that 'ins' can be shifted and masked and used as a -byte- offset\n * instead of a duk_tval offset which needs further shifting (which is an\n * issue on some, but not all, CPUs).\n */\n#define DUK__RCBIT_B           DUK_BC_REGCONST_B\n#define DUK__RCBIT_C           DUK_BC_REGCONST_C\n#if defined(DUK_USE_EXEC_REGCONST_OPTIMIZE)\n#if defined(DUK_USE_PACKED_TVAL)\n#define DUK__TVAL_SHIFT        3  /* sizeof(duk_tval) == 8 */\n#else\n#define DUK__TVAL_SHIFT        4  /* sizeof(duk_tval) == 16; not always the case so also asserted for */\n#endif\n#define DUK__SHIFT_A           (DUK_BC_SHIFT_A - DUK__TVAL_SHIFT)\n#define DUK__SHIFT_B           (DUK_BC_SHIFT_B - DUK__TVAL_SHIFT)\n#define DUK__SHIFT_C           (DUK_BC_SHIFT_C - DUK__TVAL_SHIFT)\n#define DUK__SHIFT_BC          (DUK_BC_SHIFT_BC - DUK__TVAL_SHIFT)\n#define DUK__MASK_A            (DUK_BC_UNSHIFTED_MASK_A << DUK__TVAL_SHIFT)\n#define DUK__MASK_B            (DUK_BC_UNSHIFTED_MASK_B << DUK__TVAL_SHIFT)\n#define DUK__MASK_C            (DUK_BC_UNSHIFTED_MASK_C << DUK__TVAL_SHIFT)\n#define DUK__MASK_BC           (DUK_BC_UNSHIFTED_MASK_BC << DUK__TVAL_SHIFT)\n#define DUK__BYTEOFF_A(ins)    (((ins) >> DUK__SHIFT_A) & DUK__MASK_A)\n#define DUK__BYTEOFF_B(ins)    (((ins) >> DUK__SHIFT_B) & DUK__MASK_B)\n#define DUK__BYTEOFF_C(ins)    (((ins) >> DUK__SHIFT_C) & DUK__MASK_C)\n#define DUK__BYTEOFF_BC(ins)   (((ins) >> DUK__SHIFT_BC) & DUK__MASK_BC)\n\n#define DUK__REGP_A(ins)       ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_A((ins))))\n#define DUK__REGP_B(ins)       ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_B((ins))))\n#define DUK__REGP_C(ins)       ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_C((ins))))\n#define DUK__REGP_BC(ins)      ((duk_tval *) (void *) ((duk_uint8_t *) thr->valstack_bottom + DUK__BYTEOFF_BC((ins))))\n#define DUK__CONSTP_A(ins)     ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_A((ins))))\n#define DUK__CONSTP_B(ins)     ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_B((ins))))\n#define DUK__CONSTP_C(ins)     ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_C((ins))))\n#define DUK__CONSTP_BC(ins)    ((duk_tval *) (void *) ((duk_uint8_t *) consts + DUK__BYTEOFF_BC((ins))))\n#define DUK__REGCONSTP_B(ins)  ((duk_tval *) (void *) ((duk_uint8_t *) (((ins) & DUK__RCBIT_B) ? consts : thr->valstack_bottom) + DUK__BYTEOFF_B((ins))))\n#define DUK__REGCONSTP_C(ins)  ((duk_tval *) (void *) ((duk_uint8_t *) (((ins) & DUK__RCBIT_C) ? consts : thr->valstack_bottom) + DUK__BYTEOFF_C((ins))))\n#else  /* DUK_USE_EXEC_REGCONST_OPTIMIZE */\n/* Safe alternatives, no assumption about duk_tval size. */\n#define DUK__REGP_A(ins)       DUK__REGP(DUK_DEC_A((ins)))\n#define DUK__REGP_B(ins)       DUK__REGP(DUK_DEC_B((ins)))\n#define DUK__REGP_C(ins)       DUK__REGP(DUK_DEC_C((ins)))\n#define DUK__REGP_BC(ins)      DUK__REGP(DUK_DEC_BC((ins)))\n#define DUK__CONSTP_A(ins)     DUK__CONSTP(DUK_DEC_A((ins)))\n#define DUK__CONSTP_B(ins)     DUK__CONSTP(DUK_DEC_B((ins)))\n#define DUK__CONSTP_C(ins)     DUK__CONSTP(DUK_DEC_C((ins)))\n#define DUK__CONSTP_BC(ins)    DUK__CONSTP(DUK_DEC_BC((ins)))\n#define DUK__REGCONSTP_B(ins)  ((((ins) & DUK__RCBIT_B) ? consts : thr->valstack_bottom) + DUK_DEC_B((ins)))\n#define DUK__REGCONSTP_C(ins)  ((((ins) & DUK__RCBIT_C) ? consts : thr->valstack_bottom) + DUK_DEC_C((ins)))\n#endif  /* DUK_USE_EXEC_REGCONST_OPTIMIZE */\n\n#if defined(DUK_USE_VERBOSE_EXECUTOR_ERRORS)\n#define DUK__INTERNAL_ERROR(msg)  do { \\\n\t\tDUK_ERROR_ERROR(thr, (msg)); \\\n\t\tDUK_WO_NORETURN(return;); \\\n\t} while (0)\n#else\n#define DUK__INTERNAL_ERROR(msg)  do { \\\n\t\tgoto internal_error; \\\n\t} while (0)\n#endif\n\n#define DUK__SYNC_CURR_PC()  do { \\\n\t\tduk_activation *duk__act; \\\n\t\tduk__act = thr->callstack_curr; \\\n\t\tduk__act->curr_pc = curr_pc; \\\n\t} while (0)\n#define DUK__SYNC_AND_NULL_CURR_PC()  do { \\\n\t\tduk_activation *duk__act; \\\n\t\tduk__act = thr->callstack_curr; \\\n\t\tduk__act->curr_pc = curr_pc; \\\n\t\tthr->ptr_curr_pc = NULL; \\\n\t} while (0)\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n#define DUK__LOOKUP_INDIRECT(idx) do { \\\n\t\t(idx) = (duk_uint_fast_t) duk_get_uint(thr, (duk_idx_t) (idx)); \\\n\t} while (0)\n#elif defined(DUK_USE_FASTINT)\n#define DUK__LOOKUP_INDIRECT(idx) do { \\\n\t\tduk_tval *tv_ind; \\\n\t\ttv_ind = DUK__REGP((idx)); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_ind)); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv_ind));  /* compiler guarantees */ \\\n\t\t(idx) = (duk_uint_fast_t) DUK_TVAL_GET_FASTINT_U32(tv_ind); \\\n\t} while (0)\n#else\n#define DUK__LOOKUP_INDIRECT(idx) do { \\\n\t\tduk_tval *tv_ind; \\\n\t\ttv_ind = DUK__REGP(idx); \\\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_ind)); \\\n\t\tidx = (duk_uint_fast_t) DUK_TVAL_GET_NUMBER(tv_ind); \\\n\t} while (0)\n#endif\n\nDUK_LOCAL void duk__handle_executor_error(duk_heap *heap,\n                                          duk_activation *entry_act,\n                                          duk_int_t entry_call_recursion_depth,\n                                          duk_jmpbuf *entry_jmpbuf_ptr,\n                                          volatile duk_bool_t *out_delayed_catch_setup) {\n\tduk_small_uint_t lj_ret;\n\n\t/* Longjmp callers are required to sync-and-null thr->ptr_curr_pc\n\t * before longjmp.\n\t */\n\tDUK_ASSERT(heap->curr_thread != NULL);\n\tDUK_ASSERT(heap->curr_thread->ptr_curr_pc == NULL);\n\n\t/* XXX: signalling the need to shrink check (only if unwound) */\n\n\t/* Must be restored here to handle e.g. yields properly. */\n\theap->call_recursion_depth = entry_call_recursion_depth;\n\n\t/* Switch to caller's setjmp() catcher so that if an error occurs\n\t * during error handling, it is always propagated outwards instead\n\t * of causing an infinite loop in our own handler.\n\t */\n\theap->lj.jmpbuf_ptr = (duk_jmpbuf *) entry_jmpbuf_ptr;\n\n\tlj_ret = duk__handle_longjmp(heap->curr_thread, entry_act, out_delayed_catch_setup);\n\n\t/* Error handling complete, remove side effect protections.\n\t */\n#if defined(DUK_USE_ASSERTIONS)\n\tDUK_ASSERT(heap->error_not_allowed == 1);\n\theap->error_not_allowed = 0;\n#endif\n\tDUK_ASSERT(heap->pf_prevent_count > 0);\n\theap->pf_prevent_count--;\n\tDUK_DD(DUK_DDPRINT(\"executor error handled, pf_prevent_count updated to %ld\", (long) heap->pf_prevent_count));\n\n\tif (lj_ret == DUK__LONGJMP_RESTART) {\n\t\t/* Restart bytecode execution, possibly with a changed thread. */\n\t\tDUK_REFZERO_CHECK_SLOW(heap->curr_thread);\n\t} else {\n\t\t/* If an error is propagated, don't run refzero checks here.\n\t\t * The next catcher will deal with that.  Pf_prevent_count\n\t\t * will be re-bumped by the longjmp.\n\t\t */\n\n\t\tDUK_ASSERT(lj_ret == DUK__LONGJMP_RETHROW);  /* Rethrow error to calling state. */\n\t\tDUK_ASSERT(heap->lj.jmpbuf_ptr == entry_jmpbuf_ptr);  /* Longjmp handling has restored jmpbuf_ptr. */\n\n\t\t/* Thread may have changed, e.g. YIELD converted to THROW. */\n\t\tduk_err_longjmp(heap->curr_thread);\n\t\tDUK_UNREACHABLE();\n\t}\n}\n\n/* Outer executor with setjmp/longjmp handling. */\nDUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) {\n\t/* Entry level info. */\n\tduk_hthread *entry_thread;\n\tduk_activation *entry_act;\n\tduk_int_t entry_call_recursion_depth;\n\tduk_jmpbuf *entry_jmpbuf_ptr;\n\tduk_jmpbuf our_jmpbuf;\n\tduk_heap *heap;\n\tvolatile duk_bool_t delayed_catch_setup = 0;\n\n\tDUK_ASSERT(exec_thr != NULL);\n\tDUK_ASSERT(exec_thr->heap != NULL);\n\tDUK_ASSERT(exec_thr->heap->curr_thread != NULL);\n\tDUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR((duk_heaphdr *) exec_thr);\n\tDUK_ASSERT(exec_thr->callstack_top >= 1);  /* at least one activation, ours */\n\tDUK_ASSERT(exec_thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(exec_thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(exec_thr->callstack_curr)));\n\n\tDUK_GC_TORTURE(exec_thr->heap);\n\n\tentry_thread = exec_thr;\n\theap = entry_thread->heap;\n\tentry_act = entry_thread->callstack_curr;\n\tDUK_ASSERT(entry_act != NULL);\n\tentry_call_recursion_depth = entry_thread->heap->call_recursion_depth;\n\tentry_jmpbuf_ptr = entry_thread->heap->lj.jmpbuf_ptr;\n\n\t/*\n\t *  Note: we currently assume that the setjmp() catchpoint is\n\t *  not re-entrant (longjmp() cannot be called more than once\n\t *  for a single setjmp()).\n\t *\n\t *  See doc/code-issues.rst for notes on variable assignment\n\t *  before and after setjmp().\n\t */\n\n\tfor (;;) {\n\t\theap->lj.jmpbuf_ptr = &our_jmpbuf;\n\t\tDUK_ASSERT(heap->lj.jmpbuf_ptr != NULL);\n\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\ttry {\n#else\n\t\tDUK_ASSERT(heap->lj.jmpbuf_ptr == &our_jmpbuf);\n\t\tif (DUK_SETJMP(our_jmpbuf.jb) == 0) {\n#endif\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"after setjmp, delayed catch setup: %ld\\n\", (long) delayed_catch_setup));\n\n\t\t\tif (DUK_UNLIKELY(delayed_catch_setup != 0)) {\n\t\t\t\tduk_hthread *thr = entry_thread->heap->curr_thread;\n\n\t\t\t\tdelayed_catch_setup = 0;\n\t\t\t\tduk__handle_catch_part2(thr);\n\t\t\t\tDUK_ASSERT(delayed_catch_setup == 0);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"top after delayed catch setup: %ld\", (long) duk_get_top(entry_thread)));\n\t\t\t}\n\n\t\t\t/* Execute bytecode until returned or longjmp(). */\n\t\t\tduk__js_execute_bytecode_inner(entry_thread, entry_act);\n\n\t\t\t/* Successful return: restore jmpbuf and return to caller. */\n\t\t\theap->lj.jmpbuf_ptr = entry_jmpbuf_ptr;\n\n\t\t\treturn;\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\t} catch (duk_internal_exception &exc) {\n#else\n\t\t} else {\n#endif\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\t\tDUK_UNREF(exc);\n#endif\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"longjmp caught by bytecode executor\"));\n\t\t\tDUK_STATS_INC(exec_thr->heap, stats_exec_throw);\n\n\t\t\tduk__handle_executor_error(heap,\n\t\t\t                           entry_act,\n\t\t\t                           entry_call_recursion_depth,\n\t\t\t                           entry_jmpbuf_ptr,\n\t\t\t\t\t\t   &delayed_catch_setup);\n\t\t}\n#if defined(DUK_USE_CPP_EXCEPTIONS)\n\t\tcatch (duk_fatal_exception &exc) {\n\t\t\tDUK_D(DUK_DPRINT(\"rethrow duk_fatal_exception\"));\n\t\t\tthrow;\n\t\t} catch (std::exception &exc) {\n\t\t\tconst char *what = exc.what();\n\t\t\tif (!what) {\n\t\t\t\twhat = \"unknown\";\n\t\t\t}\n\t\t\tDUK_D(DUK_DPRINT(\"unexpected c++ std::exception (perhaps thrown by user code)\"));\n\t\t\tDUK_STATS_INC(exec_thr->heap, stats_exec_throw);\n\t\t\ttry {\n\t\t\t\tDUK_ASSERT(heap->curr_thread != NULL);\n\t\t\t\tDUK_ERROR_FMT1(heap->curr_thread, DUK_ERR_TYPE_ERROR, \"caught invalid c++ std::exception '%s' (perhaps thrown by user code)\", what);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t} catch (duk_internal_exception exc) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ std::exception\"));\n\t\t\t\tDUK_UNREF(exc);\n\t\t\t\tduk__handle_executor_error(heap,\n\t\t\t\t                           entry_act,\n\t\t\t\t                           entry_call_recursion_depth,\n\t\t\t\t                           entry_jmpbuf_ptr,\n\t\t\t\t\t\t\t   &delayed_catch_setup);\n\t\t\t}\n\t\t} catch (...) {\n\t\t\tDUK_D(DUK_DPRINT(\"unexpected c++ exception (perhaps thrown by user code)\"));\n\t\t\tDUK_STATS_INC(exec_thr->heap, stats_exec_throw);\n\t\t\ttry {\n\t\t\t\tDUK_ASSERT(heap->curr_thread != NULL);\n\t\t\t\tDUK_ERROR_TYPE(heap->curr_thread, \"caught invalid c++ exception (perhaps thrown by user code)\");\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t} catch (duk_internal_exception exc) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"caught api error thrown from unexpected c++ exception\"));\n\t\t\t\tDUK_UNREF(exc);\n\t\t\t\tduk__handle_executor_error(heap,\n\t\t\t\t                           entry_act,\n\t\t\t\t                           entry_call_recursion_depth,\n\t\t\t\t                           entry_jmpbuf_ptr,\n\t\t\t\t\t\t\t   &delayed_catch_setup);\n\t\t\t}\n\t\t}\n#endif\n\t}\n\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Inner executor, performance critical. */\nDUK_LOCAL DUK_NOINLINE DUK_HOT void duk__js_execute_bytecode_inner(duk_hthread *entry_thread, duk_activation *entry_act) {\n\t/* Current PC, accessed by other functions through thr->ptr_to_curr_pc.\n\t * Critical for performance.  It would be safest to make this volatile,\n\t * but that eliminates performance benefits; aliasing guarantees\n\t * should be enough though.\n\t */\n\tduk_instr_t *curr_pc;         /* bytecode has a stable pointer */\n\n\t/* Hot variables for interpretation.  Critical for performance,\n\t * but must add sparingly to minimize register shuffling.\n\t */\n\tduk_hthread *thr;             /* stable */\n\tduk_tval *consts;             /* stable */\n\tduk_uint_fast32_t ins;\n\t/* 'funcs' is quite rarely used, so no local for it */\n#if defined(DUK_USE_EXEC_FUN_LOCAL)\n\tduk_hcompfunc *fun;\n#else\n\t/* 'fun' is quite rarely used, so no local for it */\n#endif\n\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\tduk_int_t int_ctr;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\tduk_size_t valstack_top_base;    /* valstack top, should match before interpreting each op (no leftovers) */\n#endif\n\n\t/* Optimized reg/const access macros assume sizeof(duk_tval) to be\n\t * either 8 or 16.  Heap allocation checks this even without asserts\n\t * enabled now because it can't be autodetected in duk_config.h.\n\t */\n#if 1\n#if defined(DUK_USE_PACKED_TVAL)\n\tDUK_ASSERT(sizeof(duk_tval) == 8);\n#else\n\tDUK_ASSERT(sizeof(duk_tval) == 16);\n#endif\n#endif\n\n\tDUK_GC_TORTURE(entry_thread->heap);\n\n\t/*\n\t *  Restart execution by reloading thread state.\n\t *\n\t *  Note that 'thr' and any thread configuration may have changed,\n\t *  so all local variables are suspect and we need to reinitialize.\n\t *\n\t *  The number of local variables should be kept to a minimum: if\n\t *  the variables are spilled, they will need to be loaded from\n\t *  memory anyway.\n\t *\n\t *  Any 'goto restart_execution;' code path in opcode dispatch must\n\t *  ensure 'curr_pc' is synced back to act->curr_pc before the goto\n\t *  takes place.\n\t *\n\t *  The interpreter must be very careful with memory pointers, as\n\t *  many pointers are not guaranteed to be 'stable' and may be\n\t *  reallocated and relocated on-the-fly quite easily (e.g. by a\n\t *  memory allocation or a property access).\n\t *\n\t *  The following are assumed to have stable pointers:\n\t *    - the current thread\n\t *    - the current function\n\t *    - the bytecode, constant table, inner function table of the\n\t *      current function (as they are a part of the function allocation)\n\t *\n\t *  The following are assumed to have semi-stable pointers:\n\t *    - the current activation entry: stable as long as callstack\n\t *      is not changed (reallocated by growing or shrinking), or\n\t *      by any garbage collection invocation (through finalizers)\n\t *    - Note in particular that ANY DECREF can invalidate the\n\t *      activation pointer, so for the most part a fresh lookup\n\t *      is required\n\t *\n\t *  The following are not assumed to have stable pointers at all:\n\t *    - the value stack (registers) of the current thread\n\t *\n\t *  See execution.rst for discussion.\n\t */\n\n restart_execution:\n\n\t/* Lookup current thread; use the stable 'entry_thread' for this to\n\t * avoid clobber warnings.  Any valid, reachable 'thr' value would be\n\t * fine for this, so using 'entry_thread' is just to silence warnings.\n\t */\n\tthr = entry_thread->heap->curr_thread;\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(thr->callstack_top >= 1);\n\tDUK_ASSERT(thr->callstack_curr != NULL);\n\tDUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack_curr) != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(DUK_ACT_GET_FUNC(thr->callstack_curr)));\n\n\tDUK_GC_TORTURE(thr->heap);\n\n\tthr->ptr_curr_pc = &curr_pc;\n\n\t/* Relookup and initialize dispatch loop variables.  Debugger check. */\n\t{\n\t\tduk_activation *act;\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\tduk_hcompfunc *fun;\n#endif\n\n\t\t/* Assume interrupt init/counter are properly initialized here. */\n\t\t/* Assume that thr->valstack_bottom has been set-up before getting here. */\n\n\t\tact = thr->callstack_curr;\n\t\tDUK_ASSERT(act != NULL);\n\t\tfun = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\t\tDUK_ASSERT(fun != NULL);\n\t\tDUK_ASSERT(thr->valstack_top - thr->valstack_bottom == fun->nregs);\n\t\tconsts = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, fun);\n\t\tDUK_ASSERT(consts != NULL);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\tif (DUK_UNLIKELY(duk_debug_is_attached(thr->heap) && !thr->heap->dbg_processing)) {\n\t\t\tduk__executor_recheck_debugger(thr, act, fun);\n\t\t\tDUK_ASSERT(act == thr->callstack_curr);\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t}\n#endif  /* DUK_USE_DEBUGGER_SUPPORT */\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\tvalstack_top_base = (duk_size_t) (thr->valstack_top - thr->valstack);\n#endif\n\n\t\t/* Set up curr_pc for opcode dispatch. */\n\t\tcurr_pc = act->curr_pc;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"restarting execution, thr %p, act idx %ld, fun %p,\"\n\t                   \"consts %p, funcs %p, lev %ld, regbot %ld, regtop %ld, \"\n\t                   \"preventcount=%ld\",\n\t                   (void *) thr,\n\t                   (long) (thr->callstack_top - 1),\n\t                   (void *) DUK__FUN(),\n\t                   (void *) DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, DUK__FUN()),\n\t                   (void *) DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, DUK__FUN()),\n\t                   (long) (thr->callstack_top - 1),\n\t                   (long) (thr->valstack_bottom - thr->valstack),\n\t                   (long) (thr->valstack_top - thr->valstack),\n\t                   (long) thr->callstack_preventcount));\n\n\t/* Dispatch loop. */\n\n\tfor (;;) {\n\t\tduk_uint8_t op;\n\n\t\tDUK_ASSERT(thr->callstack_top >= 1);\n\t\tDUK_ASSERT(thr->valstack_top - thr->valstack_bottom == DUK__FUN()->nregs);\n\t\tDUK_ASSERT((duk_size_t) (thr->valstack_top - thr->valstack) == valstack_top_base);\n\n\t\t/* Executor interrupt counter check, used to implement breakpoints,\n\t\t * debugging interface, execution timeouts, etc.  The counter is heap\n\t\t * specific but is maintained in the current thread to make the check\n\t\t * as fast as possible.  The counter is copied back to the heap struct\n\t\t * whenever a thread switch occurs by the DUK_HEAP_SWITCH_THREAD() macro.\n\t\t */\n#if defined(DUK_USE_INTERRUPT_COUNTER)\n\t\tint_ctr = thr->interrupt_counter;\n\t\tif (DUK_LIKELY(int_ctr > 0)) {\n\t\t\tthr->interrupt_counter = int_ctr - 1;\n\t\t} else {\n\t\t\t/* Trigger at zero or below */\n\t\t\tduk_small_uint_t exec_int_ret;\n\n\t\t\tDUK_STATS_INC(thr->heap, stats_exec_interrupt);\n\n\t\t\t/* Write curr_pc back for the debugger. */\n\t\t\t{\n\t\t\t\tduk_activation *act;\n\t\t\t\tDUK_ASSERT(thr->callstack_top > 0);\n\t\t\t\tact = thr->callstack_curr;\n\t\t\t\tDUK_ASSERT(act != NULL);\n\t\t\t\tact->curr_pc = (duk_instr_t *) curr_pc;\n\t\t\t}\n\n\t\t\t/* Forced restart caused by a function return; must recheck\n\t\t\t * debugger breakpoints before checking line transitions,\n\t\t\t * see GH-303.  Restart and then handle interrupt_counter\n\t\t\t * zero again.\n\t\t\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\t\tif (thr->heap->dbg_force_restart) {\n\t\t\t\tDUK_DD(DUK_DDPRINT(\"dbg_force_restart flag forced restart execution\"));  /* GH-303 */\n\t\t\t\tthr->heap->dbg_force_restart = 0;\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n#endif\n\n\t\t\texec_int_ret = duk__executor_interrupt(thr);\n\t\t\tif (exec_int_ret == DUK__INT_RESTART) {\n\t\t\t\t/* curr_pc synced back above */\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n\t\t}\n#endif  /* DUK_USE_INTERRUPT_COUNTER */\n#if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)\n\t\t/* For cross-checking during development: ensure dispatch count\n\t\t * matches cumulative interrupt counter init value sums.\n\t\t */\n\t\tthr->heap->inst_count_exec++;\n#endif\n\n#if defined(DUK_USE_ASSERTIONS) || defined(DUK_USE_DEBUG)\n\t\t{\n\t\t\tduk_activation *act;\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(curr_pc >= DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, DUK__FUN()));\n\t\t\tDUK_ASSERT(curr_pc < DUK_HCOMPFUNC_GET_CODE_END(thr->heap, DUK__FUN()));\n\t\t\tDUK_UNREF(act);  /* if debugging disabled */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"executing bytecode: pc=%ld, ins=0x%08lx, op=%ld, valstack_top=%ld/%ld, nregs=%ld  -->  %!I\",\n\t\t\t                     (long) (curr_pc - DUK_HCOMPFUNC_GET_CODE_BASE(thr->heap, DUK__FUN())),\n\t\t\t                     (unsigned long) *curr_pc,\n\t\t\t                     (long) DUK_DEC_OP(*curr_pc),\n\t\t\t                     (long) (thr->valstack_top - thr->valstack),\n\t\t\t                     (long) (thr->valstack_end - thr->valstack),\n\t\t\t                     (long) (DUK__FUN() ? DUK__FUN()->nregs : -1),\n\t\t\t                     (duk_instr_t) *curr_pc));\n\t\t}\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\t/* Quite heavy assert: check valstack policy.  Improper\n\t\t * shuffle instructions can write beyond valstack_top/end\n\t\t * so this check catches them in the act.\n\t\t */\n\t\t{\n\t\t\tduk_tval *tv;\n\t\t\ttv = thr->valstack_top;\n\t\t\twhile (tv != thr->valstack_end) {\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(tv));\n\t\t\t\ttv++;\n\t\t\t}\n\t\t}\n#endif\n\n\t\tins = *curr_pc++;\n\t\tDUK_STATS_INC(thr->heap, stats_exec_opcodes);\n\n\t\t/* Typing: use duk_small_(u)int_fast_t when decoding small\n\t\t * opcode fields (op, A, B, C, BC) which fit into 16 bits\n\t\t * and duk_(u)int_fast_t when decoding larger fields (e.g.\n\t\t * ABC).  Use unsigned variant by default, signed when the\n\t\t * value is used in signed arithmetic.  Using variable names\n\t\t * such as 'a', 'b', 'c', 'bc', etc makes it easier to spot\n\t\t * typing mismatches.\n\t\t */\n\n\t\t/* Switch based on opcode.  Cast to 8-bit unsigned value and\n\t\t * use a fully populated case clauses so that the compiler\n\t\t * will (at least usually) omit a bounds check.\n\t\t */\n\t\top = (duk_uint8_t) DUK_DEC_OP(ins);\n\t\tswitch (op) {\n\n\t\t/* Some useful macros.  These access inner executor variables\n\t\t * directly so they only apply within the executor.\n\t\t */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n#define DUK__REPLACE_TOP_A_BREAK() { goto replace_top_a; }\n#define DUK__REPLACE_TOP_BC_BREAK() { goto replace_top_bc; }\n#define DUK__REPLACE_BOOL_A_BREAK(bval) { \\\n\t\tduk_bool_t duk__bval; \\\n\t\tduk__bval = (bval); \\\n\t\tDUK_ASSERT(duk__bval == 0 || duk__bval == 1); \\\n\t\tduk_push_boolean(thr, duk__bval); \\\n\t\tDUK__REPLACE_TOP_A_BREAK(); \\\n\t}\n#else\n#define DUK__REPLACE_TOP_A_BREAK() { DUK__REPLACE_TO_TVPTR(thr, DUK__REGP_A(ins)); break; }\n#define DUK__REPLACE_TOP_BC_BREAK() { DUK__REPLACE_TO_TVPTR(thr, DUK__REGP_BC(ins)); break; }\n#define DUK__REPLACE_BOOL_A_BREAK(bval) { \\\n\t\tduk_bool_t duk__bval; \\\n\t\tduk_tval *duk__tvdst; \\\n\t\tduk__bval = (bval); \\\n\t\tDUK_ASSERT(duk__bval == 0 || duk__bval == 1); \\\n\t\tduk__tvdst = DUK__REGP_A(ins); \\\n\t\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, duk__tvdst, duk__bval); \\\n\t\tbreak; \\\n\t}\n#endif\n\n\t\t/* XXX: 12 + 12 bit variant might make sense too, for both reg and\n\t\t * const loads.\n\t\t */\n\n\t\t/* For LDREG, STREG, LDCONST footprint optimized variants would just\n\t\t * duk_dup() + duk_replace(), but because they're used quite a lot\n\t\t * they're currently intentionally not size optimized.\n\t\t */\n\t\tcase DUK_OP_LDREG: {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\ttv2 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv1, tv2);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_STREG: {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\ttv2 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv2, tv1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_LDCONST: {\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\ttv2 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv1, tv2);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\n\t\t/* LDINT and LDINTX are intended to load an arbitrary signed\n\t\t * 32-bit value.  Only an LDINT+LDINTX sequence is supported.\n\t\t * This also guarantees all values remain fastints.\n\t\t */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_LDINT: {\n\t\t\tduk_int32_t val;\n\n\t\t\tval = (duk_int32_t) DUK_DEC_BC(ins) - (duk_int32_t) DUK_BC_LDINT_BIAS;\n\t\t\tduk_push_int(thr, val);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n\t\tcase DUK_OP_LDINTX: {\n\t\t\tduk_int32_t val;\n\n\t\t\tval = (duk_int32_t) duk_get_int(thr, DUK_DEC_A(ins));\n\t\t\tval = (val << DUK_BC_LDINTX_SHIFT) + (duk_int32_t) DUK_DEC_BC(ins);  /* no bias */\n\t\t\tduk_push_int(thr, val);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_LDINT: {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_int32_t val;\n\n\t\t\tval = (duk_int32_t) DUK_DEC_BC(ins) - (duk_int32_t) DUK_BC_LDINT_BIAS;\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_I32_UPDREF(thr, tv1, val);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDINTX: {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_int32_t val;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\t\tval = DUK_TVAL_GET_FASTINT_I32(tv1);\n#else\n\t\t\t/* XXX: fast double-to-int conversion, we know number is integer in [-0x80000000,0xffffffff]. */\n\t\t\tval = (duk_int32_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\t\tval = (duk_int32_t) ((duk_uint32_t) val << DUK_BC_LDINTX_SHIFT) + (duk_int32_t) DUK_DEC_BC(ins);  /* no bias */\n\t\t\tDUK_TVAL_SET_I32_UPDREF(thr, tv1, val);  /* side effects */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_LDTHIS: {\n\t\t\tduk_push_this(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\t\tcase DUK_OP_LDUNDEF: {\n\t\t\tduk_to_undefined(thr, (duk_idx_t) DUK_DEC_BC(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDNULL: {\n\t\t\tduk_to_null(thr, (duk_idx_t) DUK_DEC_BC(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDTRUE: {\n\t\t\tduk_push_true(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\t\tcase DUK_OP_LDFALSE: {\n\t\t\tduk_push_false(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_LDTHIS: {\n\t\t\t/* Note: 'this' may be bound to any value, not just an object */\n\t\t\tduk_tval *tv1, *tv2;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\ttv2 = thr->valstack_bottom - 1;  /* 'this binding' is just under bottom */\n\t\t\tDUK_ASSERT(tv2 >= thr->valstack);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF_FAST(thr, tv1, tv2);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDUNDEF: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDNULL: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_NULL_UPDREF(thr, tv1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDTRUE: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv1, 1);  /* side effects */\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_LDFALSE: {\n\t\t\tduk_tval *tv1;\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_BOOLEAN_UPDREF(thr, tv1, 0);  /* side effects */\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\tcase DUK_OP_BNOT: {\n\t\t\tduk__vm_bitwise_not(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_LNOT: {\n\t\t\tduk__vm_logical_not(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_UNM:\n\t\tcase DUK_OP_UNP: {\n\t\t\tduk__vm_arith_unary_op(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins), op);\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_UNM: {\n\t\t\tduk__vm_arith_unary_op(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins), DUK_OP_UNM);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_UNP: {\n\t\t\tduk__vm_arith_unary_op(thr, DUK_DEC_BC(ins), DUK_DEC_A(ins), DUK_OP_UNP);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_TYPEOF: {\n\t\t\tduk_small_uint_t stridx;\n\n\t\t\tstridx = duk_js_typeof_stridx(DUK__REGP_BC(ins));\n\t\t\tDUK_ASSERT_STRIDX_VALID(stridx);\n\t\t\tduk_push_hstring_stridx(thr, stridx);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_TYPEOF: {\n\t\t\tduk_tval *tv;\n\t\t\tduk_small_uint_t stridx;\n\t\t\tduk_hstring *h_str;\n\n\t\t\ttv = DUK__REGP_BC(ins);\n\t\t\tstridx = duk_js_typeof_stridx(tv);\n\t\t\tDUK_ASSERT_STRIDX_VALID(stridx);\n\t\t\th_str = DUK_HTHREAD_GET_STRING(thr, stridx);\n\t\t\ttv = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_STRING_UPDREF(thr, tv, h_str);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\tcase DUK_OP_TYPEOFID: {\n\t\t\tduk_small_uint_t stridx;\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_hstring *h_str;\n#endif\n\t\t\tduk_activation *act;\n\t\t\tduk_hstring *name;\n\t\t\tduk_tval *tv;\n\n\t\t\t/* A -> target register\n\t\t\t * BC -> constant index of identifier name\n\t\t\t */\n\n\t\t\ttv = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv));\n\t\t\tname = DUK_TVAL_GET_STRING(tv);\n\t\t\ttv = NULL;  /* lookup has side effects */\n\t\t\tact = thr->callstack_curr;\n\t\t\tif (duk_js_getvar_activation(thr, act, name, 0 /*throw*/)) {\n\t\t\t\t/* -> [... val this] */\n\t\t\t\ttv = DUK_GET_TVAL_NEGIDX(thr, -2);\n\t\t\t\tstridx = duk_js_typeof_stridx(tv);\n\t\t\t\ttv = NULL;  /* no longer needed */\n\t\t\t\tduk_pop_2_unsafe(thr);\n\t\t\t} else {\n\t\t\t\t/* unresolvable, no stack changes */\n\t\t\t\tstridx = DUK_STRIDX_LC_UNDEFINED;\n\t\t\t}\n\t\t\tDUK_ASSERT_STRIDX_VALID(stridx);\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_push_hstring_stridx(thr, stridx);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\t\th_str = DUK_HTHREAD_GET_STRING(thr, stridx);\n\t\t\ttv = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_STRING_UPDREF(thr, tv, h_str);\n\t\t\tbreak;\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\t}\n\n\t\t/* Equality: E5 Sections 11.9.1, 11.9.3 */\n\n#define DUK__EQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_equals(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__NEQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_equals(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\ttmp ^= 1; \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__SEQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_strict_equals((barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__SNEQ_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_strict_equals((barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\ttmp ^= 1; \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_EQ_RR:\n\t\tcase DUK_OP_EQ_CR:\n\t\tcase DUK_OP_EQ_RC:\n\t\tcase DUK_OP_EQ_CC:\n\t\t\tDUK__EQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_NEQ_RR:\n\t\tcase DUK_OP_NEQ_CR:\n\t\tcase DUK_OP_NEQ_RC:\n\t\tcase DUK_OP_NEQ_CC:\n\t\t\tDUK__NEQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_SEQ_RR:\n\t\tcase DUK_OP_SEQ_CR:\n\t\tcase DUK_OP_SEQ_RC:\n\t\tcase DUK_OP_SEQ_CC:\n\t\t\tDUK__SEQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_SNEQ_RR:\n\t\tcase DUK_OP_SNEQ_CR:\n\t\tcase DUK_OP_SNEQ_RC:\n\t\tcase DUK_OP_SNEQ_CC:\n\t\t\tDUK__SNEQ_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_EQ_RR:\n\t\t\tDUK__EQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_EQ_CR:\n\t\t\tDUK__EQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_EQ_RC:\n\t\t\tDUK__EQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_EQ_CC:\n\t\t\tDUK__EQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_NEQ_RR:\n\t\t\tDUK__NEQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_NEQ_CR:\n\t\t\tDUK__NEQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_NEQ_RC:\n\t\t\tDUK__NEQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_NEQ_CC:\n\t\t\tDUK__NEQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SEQ_RR:\n\t\t\tDUK__SEQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SEQ_CR:\n\t\t\tDUK__SEQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SEQ_RC:\n\t\t\tDUK__SEQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SEQ_CC:\n\t\t\tDUK__SEQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SNEQ_RR:\n\t\t\tDUK__SNEQ_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SNEQ_CR:\n\t\t\tDUK__SNEQ_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_SNEQ_RC:\n\t\t\tDUK__SNEQ_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_SNEQ_CC:\n\t\t\tDUK__SNEQ_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#define DUK__COMPARE_BODY(arg1,arg2,flags) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_compare_helper(thr, (arg1), (arg2), (flags)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__GT_BODY(barg,carg) DUK__COMPARE_BODY((carg), (barg), 0)\n#define DUK__GE_BODY(barg,carg) DUK__COMPARE_BODY((barg), (carg), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST | DUK_COMPARE_FLAG_NEGATE)\n#define DUK__LT_BODY(barg,carg) DUK__COMPARE_BODY((barg), (carg), DUK_COMPARE_FLAG_EVAL_LEFT_FIRST)\n#define DUK__LE_BODY(barg,carg) DUK__COMPARE_BODY((carg), (barg), DUK_COMPARE_FLAG_NEGATE)\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_GT_RR:\n\t\tcase DUK_OP_GT_CR:\n\t\tcase DUK_OP_GT_RC:\n\t\tcase DUK_OP_GT_CC:\n\t\t\tDUK__GT_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_GE_RR:\n\t\tcase DUK_OP_GE_CR:\n\t\tcase DUK_OP_GE_RC:\n\t\tcase DUK_OP_GE_CC:\n\t\t\tDUK__GE_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_LT_RR:\n\t\tcase DUK_OP_LT_CR:\n\t\tcase DUK_OP_LT_RC:\n\t\tcase DUK_OP_LT_CC:\n\t\t\tDUK__LT_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_LE_RR:\n\t\tcase DUK_OP_LE_CR:\n\t\tcase DUK_OP_LE_RC:\n\t\tcase DUK_OP_LE_CC:\n\t\t\tDUK__LE_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_GT_RR:\n\t\t\tDUK__GT_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GT_CR:\n\t\t\tDUK__GT_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GT_RC:\n\t\t\tDUK__GT_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GT_CC:\n\t\t\tDUK__GT_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GE_RR:\n\t\t\tDUK__GE_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GE_CR:\n\t\t\tDUK__GE_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GE_RC:\n\t\t\tDUK__GE_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GE_CC:\n\t\t\tDUK__GE_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LT_RR:\n\t\t\tDUK__LT_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LT_CR:\n\t\t\tDUK__LT_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LT_RC:\n\t\t\tDUK__LT_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LT_CC:\n\t\t\tDUK__LT_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LE_RR:\n\t\t\tDUK__LE_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LE_CR:\n\t\t\tDUK__LE_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_LE_RC:\n\t\t\tDUK__LE_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_LE_CC:\n\t\t\tDUK__LE_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* No size optimized variant at present for IF. */\n\t\tcase DUK_OP_IFTRUE_R: {\n\t\t\tif (duk_js_toboolean(DUK__REGP_BC(ins)) != 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_IFTRUE_C: {\n\t\t\tif (duk_js_toboolean(DUK__CONSTP_BC(ins)) != 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_IFFALSE_R: {\n\t\t\tif (duk_js_toboolean(DUK__REGP_BC(ins)) == 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_IFFALSE_C: {\n\t\t\tif (duk_js_toboolean(DUK__CONSTP_BC(ins)) == 0) {\n\t\t\t\tcurr_pc++;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_ADD_RR:\n\t\tcase DUK_OP_ADD_CR:\n\t\tcase DUK_OP_ADD_RC:\n\t\tcase DUK_OP_ADD_CC: {\n\t\t\t/* XXX: could leave value on stack top and goto replace_top_a; */\n\t\t\tduk__vm_arith_add(thr, DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_ADD_RR: {\n\t\t\tduk__vm_arith_add(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_ADD_CR: {\n\t\t\tduk__vm_arith_add(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_ADD_RC: {\n\t\t\tduk__vm_arith_add(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_ADD_CC: {\n\t\t\tduk__vm_arith_add(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins));\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_SUB_RR:\n\t\tcase DUK_OP_SUB_CR:\n\t\tcase DUK_OP_SUB_RC:\n\t\tcase DUK_OP_SUB_CC:\n\t\tcase DUK_OP_MUL_RR:\n\t\tcase DUK_OP_MUL_CR:\n\t\tcase DUK_OP_MUL_RC:\n\t\tcase DUK_OP_MUL_CC:\n\t\tcase DUK_OP_DIV_RR:\n\t\tcase DUK_OP_DIV_CR:\n\t\tcase DUK_OP_DIV_RC:\n\t\tcase DUK_OP_DIV_CC:\n\t\tcase DUK_OP_MOD_RR:\n\t\tcase DUK_OP_MOD_CR:\n\t\tcase DUK_OP_MOD_RC:\n\t\tcase DUK_OP_MOD_CC:\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tcase DUK_OP_EXP_RR:\n\t\tcase DUK_OP_EXP_CR:\n\t\tcase DUK_OP_EXP_RC:\n\t\tcase DUK_OP_EXP_CC:\n#endif  /* DUK_USE_ES7_EXP_OPERATOR */\n\t\t{\n\t\t\t/* XXX: could leave value on stack top and goto replace_top_a; */\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins), DUK_DEC_A(ins), op);\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_SUB_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_SUB_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_SUB_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_SUB_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_SUB);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MUL_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MUL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_DIV_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_DIV);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_MOD_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_MOD);\n\t\t\tbreak;\n\t\t}\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tcase DUK_OP_EXP_RR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_EXP_CR: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_EXP_RC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_EXP_CC: {\n\t\t\tduk__vm_arith_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_EXP);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_ES7_EXP_OPERATOR */\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_BAND_RR:\n\t\tcase DUK_OP_BAND_CR:\n\t\tcase DUK_OP_BAND_RC:\n\t\tcase DUK_OP_BAND_CC:\n\t\tcase DUK_OP_BOR_RR:\n\t\tcase DUK_OP_BOR_CR:\n\t\tcase DUK_OP_BOR_RC:\n\t\tcase DUK_OP_BOR_CC:\n\t\tcase DUK_OP_BXOR_RR:\n\t\tcase DUK_OP_BXOR_CR:\n\t\tcase DUK_OP_BXOR_RC:\n\t\tcase DUK_OP_BXOR_CC:\n\t\tcase DUK_OP_BASL_RR:\n\t\tcase DUK_OP_BASL_CR:\n\t\tcase DUK_OP_BASL_RC:\n\t\tcase DUK_OP_BASL_CC:\n\t\tcase DUK_OP_BLSR_RR:\n\t\tcase DUK_OP_BLSR_CR:\n\t\tcase DUK_OP_BLSR_RC:\n\t\tcase DUK_OP_BLSR_CC:\n\t\tcase DUK_OP_BASR_RR:\n\t\tcase DUK_OP_BASR_CR:\n\t\tcase DUK_OP_BASR_RC:\n\t\tcase DUK_OP_BASR_CC: {\n\t\t\t/* XXX: could leave value on stack top and goto replace_top_a; */\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins), DUK_DEC_A(ins), op);\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_BAND_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BAND_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BAND_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BAND_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BAND);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BOR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BXOR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BXOR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASL_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASL);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BLSR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BLSR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_RR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_CR: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__REGP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_RC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__REGP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_BASR_CC: {\n\t\t\tduk__vm_bitwise_binary_op(thr, DUK__CONSTP_B(ins), DUK__CONSTP_C(ins), DUK_DEC_A(ins), DUK_OP_BASR);\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* For INSTOF and IN, B is always a register. */\n#define DUK__INSTOF_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_instanceof(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#define DUK__IN_BODY(barg,carg) { \\\n\t\tduk_bool_t tmp; \\\n\t\ttmp = duk_js_in(thr, (barg), (carg)); \\\n\t\tDUK_ASSERT(tmp == 0 || tmp == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(tmp); \\\n\t}\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_INSTOF_RR:\n\t\tcase DUK_OP_INSTOF_CR:\n\t\tcase DUK_OP_INSTOF_RC:\n\t\tcase DUK_OP_INSTOF_CC:\n\t\t\tDUK__INSTOF_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_IN_RR:\n\t\tcase DUK_OP_IN_CR:\n\t\tcase DUK_OP_IN_RC:\n\t\tcase DUK_OP_IN_CC:\n\t\t\tDUK__IN_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_INSTOF_RR:\n\t\t\tDUK__INSTOF_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_INSTOF_CR:\n\t\t\tDUK__INSTOF_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_INSTOF_RC:\n\t\t\tDUK__INSTOF_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_INSTOF_CC:\n\t\t\tDUK__INSTOF_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_IN_RR:\n\t\t\tDUK__IN_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_IN_CR:\n\t\t\tDUK__IN_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_IN_RC:\n\t\t\tDUK__IN_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_IN_CC:\n\t\t\tDUK__IN_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* Pre/post inc/dec for register variables, important for loops. */\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_PREINCR:\n\t\tcase DUK_OP_PREDECR:\n\t\tcase DUK_OP_POSTINCR:\n\t\tcase DUK_OP_POSTDECR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), op);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREINCV:\n\t\tcase DUK_OP_PREDECV:\n\t\tcase DUK_OP_POSTINCV:\n\t\tcase DUK_OP_POSTDECV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), op, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_PREINCR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_PREINCR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREDECR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_PREDECR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTINCR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_POSTINCR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTDECR: {\n\t\t\tduk__prepost_incdec_reg_helper(thr, DUK__REGP_A(ins), DUK__REGP_BC(ins), DUK_OP_POSTDECR);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREINCV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_PREINCV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_PREDECV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_PREDECV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTINCV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_POSTINCV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_OP_POSTDECV: {\n\t\t\tduk__prepost_incdec_var_helper(thr, DUK_DEC_A(ins), DUK__CONSTP_BC(ins), DUK_OP_POSTDECV, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* XXX: Move to separate helper, optimize for perf/size separately. */\n\t\t/* Preinc/predec for object properties. */\n\t\tcase DUK_OP_PREINCP_RR:\n\t\tcase DUK_OP_PREINCP_CR:\n\t\tcase DUK_OP_PREINCP_RC:\n\t\tcase DUK_OP_PREINCP_CC:\n\t\tcase DUK_OP_PREDECP_RR:\n\t\tcase DUK_OP_PREDECP_CR:\n\t\tcase DUK_OP_PREDECP_RC:\n\t\tcase DUK_OP_PREDECP_CC:\n\t\tcase DUK_OP_POSTINCP_RR:\n\t\tcase DUK_OP_POSTINCP_CR:\n\t\tcase DUK_OP_POSTINCP_RC:\n\t\tcase DUK_OP_POSTINCP_CC:\n\t\tcase DUK_OP_POSTDECP_RR:\n\t\tcase DUK_OP_POSTDECP_CR:\n\t\tcase DUK_OP_POSTDECP_RC:\n\t\tcase DUK_OP_POSTDECP_CC: {\n\t\t\tduk_tval *tv_obj;\n\t\t\tduk_tval *tv_key;\n\t\t\tduk_tval *tv_val;\n\t\t\tduk_bool_t rc;\n\t\t\tduk_double_t x, y, z;\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_tval *tv_dst;\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t\t/* A -> target reg\n\t\t\t * B -> object reg/const (may be const e.g. in \"'foo'[1]\")\n\t\t\t * C -> key reg/const\n\t\t\t */\n\n\t\t\t/* Opcode bits 0-1 are used to distinguish reg/const variants.\n\t\t\t * Opcode bits 2-3 are used to distinguish inc/dec variants:\n\t\t\t * Bit 2 = inc(0)/dec(1), bit 3 = pre(0)/post(1).\n\t\t\t */\n\t\t\tDUK_ASSERT((DUK_OP_PREINCP_RR & 0x0c) == 0x00);\n\t\t\tDUK_ASSERT((DUK_OP_PREDECP_RR & 0x0c) == 0x04);\n\t\t\tDUK_ASSERT((DUK_OP_POSTINCP_RR & 0x0c) == 0x08);\n\t\t\tDUK_ASSERT((DUK_OP_POSTDECP_RR & 0x0c) == 0x0c);\n\n\t\t\ttv_obj = DUK__REGCONSTP_B(ins);\n\t\t\ttv_key = DUK__REGCONSTP_C(ins);\n\t\t\trc = duk_hobject_getprop(thr, tv_obj, tv_key);  /* -> [val] */\n\t\t\tDUK_UNREF(rc);  /* ignore */\n\t\t\ttv_obj = NULL;  /* invalidated */\n\t\t\ttv_key = NULL;  /* invalidated */\n\n\t\t\t/* XXX: Fastint fast path would be useful here.  Also fastints\n\t\t\t * now lose their fastint status in current handling which is\n\t\t\t * not intuitive.\n\t\t\t */\n\n\t\t\tx = duk_to_number_m1(thr);\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tif (ins & DUK_BC_INCDECP_FLAG_DEC) {\n\t\t\t\ty = x - 1.0;\n\t\t\t} else {\n\t\t\t\ty = x + 1.0;\n\t\t\t}\n\n\t\t\tduk_push_number(thr, y);\n\t\t\ttv_val = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\ttv_obj = DUK__REGCONSTP_B(ins);\n\t\t\ttv_key = DUK__REGCONSTP_C(ins);\n\t\t\trc = duk_hobject_putprop(thr, tv_obj, tv_key, tv_val, DUK__STRICT());\n\t\t\tDUK_UNREF(rc);  /* ignore */\n\t\t\ttv_obj = NULL;  /* invalidated */\n\t\t\ttv_key = NULL;  /* invalidated */\n\t\t\tduk_pop_unsafe(thr);\n\n\t\t\tz = (ins & DUK_BC_INCDECP_FLAG_POST) ? x : y;\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\t\tduk_push_number(thr, z);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n#else\n\t\t\ttv_dst = DUK__REGP_A(ins);\n\t\t\tDUK_TVAL_SET_NUMBER_UPDREF(thr, tv_dst, z);\n\t\t\tbreak;\n#endif\n\t\t}\n\n\t\t/* XXX: GETPROP where object is 'this', GETPROPT?\n\t\t * Occurs relatively often in object oriented code.\n\t\t */\n\n#define DUK__GETPROP_BODY(barg,carg) { \\\n\t\t/* A -> target reg \\\n\t\t * B -> object reg/const (may be const e.g. in \"'foo'[1]\") \\\n\t\t * C -> key reg/const \\\n\t\t */ \\\n\t\t(void) duk_hobject_getprop(thr, (barg), (carg)); \\\n\t\tDUK__REPLACE_TOP_A_BREAK(); \\\n\t}\n#define DUK__GETPROPC_BODY(barg,carg) { \\\n\t\t/* Same as GETPROP but callability check for property-based calls. */ \\\n\t\tduk_tval *tv__targ; \\\n\t\t(void) duk_hobject_getprop(thr, (barg), (carg)); \\\n\t\tDUK_GC_TORTURE(thr->heap); \\\n\t\ttv__targ = DUK_GET_TVAL_NEGIDX(thr, -1); \\\n\t\tif (DUK_UNLIKELY(!duk_is_callable_tval(thr, tv__targ))) { \\\n\t\t\t/* Here we intentionally re-evaluate the macro \\\n\t\t\t * arguments to deal with potentially changed \\\n\t\t\t * valstack base pointer! \\\n\t\t\t */ \\\n\t\t\tduk_call_setup_propcall_error(thr, (barg), (carg)); \\\n\t\t} \\\n\t\tDUK__REPLACE_TOP_A_BREAK(); \\\n\t}\n#define DUK__PUTPROP_BODY(aarg,barg,carg) { \\\n\t\t/* A -> object reg \\\n\t\t * B -> key reg/const \\\n\t\t * C -> value reg/const \\\n\t\t * \\\n\t\t * Note: intentional difference to register arrangement \\\n\t\t * of e.g. GETPROP; 'A' must contain a register-only value. \\\n\t\t */ \\\n\t\t(void) duk_hobject_putprop(thr, (aarg), (barg), (carg), DUK__STRICT()); \\\n\t\tbreak; \\\n\t}\n#define DUK__DELPROP_BODY(barg,carg) { \\\n\t\t/* A -> result reg \\\n\t\t * B -> object reg \\\n\t\t * C -> key reg/const \\\n\t\t */ \\\n\t\tduk_bool_t rc; \\\n\t\trc = duk_hobject_delprop(thr, (barg), (carg), DUK__STRICT()); \\\n\t\tDUK_ASSERT(rc == 0 || rc == 1); \\\n\t\tDUK__REPLACE_BOOL_A_BREAK(rc); \\\n\t}\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_GETPROP_RR:\n\t\tcase DUK_OP_GETPROP_CR:\n\t\tcase DUK_OP_GETPROP_RC:\n\t\tcase DUK_OP_GETPROP_CC:\n\t\t\tDUK__GETPROP_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\tcase DUK_OP_GETPROPC_RR:\n\t\tcase DUK_OP_GETPROPC_CR:\n\t\tcase DUK_OP_GETPROPC_RC:\n\t\tcase DUK_OP_GETPROPC_CC:\n\t\t\tDUK__GETPROPC_BODY(DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n#endif\n\t\tcase DUK_OP_PUTPROP_RR:\n\t\tcase DUK_OP_PUTPROP_CR:\n\t\tcase DUK_OP_PUTPROP_RC:\n\t\tcase DUK_OP_PUTPROP_CC:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGCONSTP_B(ins), DUK__REGCONSTP_C(ins));\n\t\tcase DUK_OP_DELPROP_RR:\n\t\tcase DUK_OP_DELPROP_RC:  /* B is always reg */\n\t\t\tDUK__DELPROP_BODY(DUK__REGP_B(ins), DUK__REGCONSTP_C(ins));\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_GETPROP_RR:\n\t\t\tDUK__GETPROP_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROP_CR:\n\t\t\tDUK__GETPROP_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROP_RC:\n\t\t\tDUK__GETPROP_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GETPROP_CC:\n\t\t\tDUK__GETPROP_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\t\tcase DUK_OP_GETPROPC_RR:\n\t\t\tDUK__GETPROPC_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROPC_CR:\n\t\t\tDUK__GETPROPC_BODY(DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_GETPROPC_RC:\n\t\t\tDUK__GETPROPC_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_GETPROPC_CC:\n\t\t\tDUK__GETPROPC_BODY(DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n#endif\n\t\tcase DUK_OP_PUTPROP_RR:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_PUTPROP_CR:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__CONSTP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_PUTPROP_RC:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_PUTPROP_CC:\n\t\t\tDUK__PUTPROP_BODY(DUK__REGP_A(ins), DUK__CONSTP_B(ins), DUK__CONSTP_C(ins));\n\t\tcase DUK_OP_DELPROP_RR:  /* B is always reg */\n\t\t\tDUK__DELPROP_BODY(DUK__REGP_B(ins), DUK__REGP_C(ins));\n\t\tcase DUK_OP_DELPROP_RC:\n\t\t\tDUK__DELPROP_BODY(DUK__REGP_B(ins), DUK__CONSTP_C(ins));\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\t/* No fast path for DECLVAR now, it's quite a rare instruction. */\n\t\tcase DUK_OP_DECLVAR_RR:\n\t\tcase DUK_OP_DECLVAR_CR:\n\t\tcase DUK_OP_DECLVAR_RC:\n\t\tcase DUK_OP_DECLVAR_CC: {\n\t\t\tduk_activation *act;\n\t\t\tduk_small_uint_fast_t a = DUK_DEC_A(ins);\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\t\t\tduk_small_uint_t prop_flags;\n\t\t\tduk_bool_t is_func_decl;\n\n\t\t\ttv1 = DUK__REGCONSTP_B(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\n\t\t\tis_func_decl = ((a & DUK_BC_DECLVAR_FLAG_FUNC_DECL) != 0);\n\n\t\t\t/* XXX: declvar takes an duk_tval pointer, which is awkward and\n\t\t\t * should be reworked.\n\t\t\t */\n\n\t\t\t/* Compiler is responsible for selecting property flags (configurability,\n\t\t\t * writability, etc).\n\t\t\t */\n\t\t\tprop_flags = a & DUK_PROPDESC_FLAGS_MASK;\n\n\t\t\tif (is_func_decl) {\n\t\t\t\tduk_push_tval(thr, DUK__REGCONSTP_C(ins));\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* valstack policy */\n\t\t\t\tthr->valstack_top++;\n\t\t\t}\n\t\t\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tif (duk_js_declvar_activation(thr, act, name, tv1, prop_flags, is_func_decl)) {\n\t\t\t\tif (is_func_decl) {\n\t\t\t\t\t/* Already declared, update value. */\n\t\t\t\t\ttv1 = DUK_GET_TVAL_NEGIDX(thr, -1);\n\t\t\t\t\tduk_js_putvar_activation(thr, act, name, tv1, DUK__STRICT());\n\t\t\t\t} else {\n\t\t\t\t\t/* Already declared but no initializer value\n\t\t\t\t\t * (e.g. 'var xyz;'), no-op.\n\t\t\t\t\t */\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tduk_pop_unsafe(thr);\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t/* The compiler should never emit DUK_OP_REGEXP if there is no\n\t\t * regexp support.\n\t\t */\n\t\tcase DUK_OP_REGEXP_RR:\n\t\tcase DUK_OP_REGEXP_CR:\n\t\tcase DUK_OP_REGEXP_RC:\n\t\tcase DUK_OP_REGEXP_CC: {\n\t\t\t/* A -> target register\n\t\t\t * B -> bytecode (also contains flags)\n\t\t\t * C -> escaped source\n\t\t\t */\n\n\t\t\tduk_push_tval(thr, DUK__REGCONSTP_C(ins));\n\t\t\tduk_push_tval(thr, DUK__REGCONSTP_B(ins));  /* -> [ ... escaped_source bytecode ] */\n\t\t\tduk_regexp_create_instance(thr);   /* -> [ ... regexp_instance ] */\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n\t\t/* XXX: 'c' is unused, use whole BC, etc. */\n\t\tcase DUK_OP_CSVAR_RR:\n\t\tcase DUK_OP_CSVAR_CR:\n\t\tcase DUK_OP_CSVAR_RC:\n\t\tcase DUK_OP_CSVAR_CC: {\n\t\t\t/* The speciality of calling through a variable binding is that the\n\t\t\t * 'this' value may be provided by the variable lookup: E5 Section 6.b.i.\n\t\t\t *\n\t\t\t * The only (standard) case where the 'this' binding is non-null is when\n\t\t\t *   (1) the variable is found in an object environment record, and\n\t\t\t *   (2) that object environment record is a 'with' block.\n\t\t\t */\n\n\t\t\tduk_activation *act;\n\t\t\tduk_uint_fast_t idx;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\n\t\t\t/* A -> target registers (A, A + 1) for call setup\n\t\t\t * B -> identifier name, usually constant but can be a register due to shuffling\n\t\t\t */\n\n\t\t\ttv1 = DUK__REGCONSTP_B(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\t\t\tact = thr->callstack_curr;\n\t\t\t(void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/);  /* -> [... val this] */\n\n\t\t\tidx = (duk_uint_fast_t) DUK_DEC_A(ins);\n\n\t\t\t/* Could add direct value stack handling. */\n\t\t\tduk_replace(thr, (duk_idx_t) (idx + 1));  /* 'this' binding */\n\t\t\tduk_replace(thr, (duk_idx_t) idx);        /* variable value (function, we hope, not checked here) */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_CLOSURE: {\n\t\t\tduk_activation *act;\n\t\t\tduk_hcompfunc *fun_act;\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\t\t\tduk_hobject *fun_temp;\n\n\t\t\t/* A -> target reg\n\t\t\t * BC -> inner function index\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"CLOSURE to target register %ld, fnum %ld (count %ld)\",\n\t\t\t                     (long) DUK_DEC_A(ins), (long) DUK_DEC_BC(ins), (long) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, DUK__FUN())));\n\n\t\t\tDUK_ASSERT_DISABLE(bc >= 0); /* unsigned */\n\t\t\tDUK_ASSERT((duk_uint_t) bc < (duk_uint_t) DUK_HCOMPFUNC_GET_FUNCS_COUNT(thr->heap, DUK__FUN()));\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tfun_act = (duk_hcompfunc *) DUK_ACT_GET_FUNC(act);\n\t\t\tfun_temp = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, fun_act)[bc];\n\t\t\tDUK_ASSERT(fun_temp != NULL);\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC(fun_temp));\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"CLOSURE: function template is: %p -> %!O\",\n\t\t\t                     (void *) fun_temp, (duk_heaphdr *) fun_temp));\n\n\t\t\tif (act->lex_env == NULL) {\n\t\t\t\tDUK_ASSERT(act->var_env == NULL);\n\t\t\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\t\t\tact = thr->callstack_curr;\n\t\t\t}\n\t\t\tDUK_ASSERT(act->lex_env != NULL);\n\t\t\tDUK_ASSERT(act->var_env != NULL);\n\n\t\t\t/* functions always have a NEWENV flag, i.e. they get a\n\t\t\t * new variable declaration environment, so only lex_env\n\t\t\t * matters here.\n\t\t\t */\n\t\t\tduk_js_push_closure(thr,\n\t\t\t                    (duk_hcompfunc *) fun_temp,\n\t\t\t                    act->var_env,\n\t\t\t                    act->lex_env,\n\t\t\t                    1 /*add_auto_proto*/);\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_GETVAR: {\n\t\t\tduk_activation *act;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\n\t\t\ttv1 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\t(void) duk_js_getvar_activation(thr, act, name, 1 /*throw*/);  /* -> [... val this] */\n\t\t\tduk_pop_unsafe(thr);  /* 'this' binding is not needed here */\n\t\t\tDUK__REPLACE_TOP_A_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_PUTVAR: {\n\t\t\tduk_activation *act;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\n\t\t\ttv1 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\n\t\t\t/* XXX: putvar takes a duk_tval pointer, which is awkward and\n\t\t\t * should be reworked.\n\t\t\t */\n\n\t\t\ttv1 = DUK__REGP_A(ins);  /* val */\n\t\t\tact = thr->callstack_curr;\n\t\t\tduk_js_putvar_activation(thr, act, name, tv1, DUK__STRICT());\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_DELVAR: {\n\t\t\tduk_activation *act;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hstring *name;\n\t\t\tduk_bool_t rc;\n\n\t\t\ttv1 = DUK__CONSTP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_STRING(tv1));\n\t\t\tname = DUK_TVAL_GET_STRING(tv1);\n\t\t\tDUK_ASSERT(name != NULL);\n\t\t\tact = thr->callstack_curr;\n\t\t\trc = duk_js_delvar_activation(thr, act, name);\n\t\t\tDUK__REPLACE_BOOL_A_BREAK(rc);\n\t\t}\n\n\t\tcase DUK_OP_JUMP: {\n\t\t\t/* Note: without explicit cast to signed, MSVC will\n\t\t\t * apparently generate a large positive jump when the\n\t\t\t * bias-corrected value would normally be negative.\n\t\t\t */\n\t\t\tcurr_pc += (duk_int_fast_t) DUK_DEC_ABC(ins) - (duk_int_fast_t) DUK_BC_JUMP_BIAS;\n\t\t\tbreak;\n\t\t}\n\n#define DUK__RETURN_SHARED() do { \\\n\t\tduk_small_uint_t ret_result; \\\n\t\t/* duk__handle_return() is guaranteed never to throw, except \\\n\t\t * for potential out-of-memory situations which will then \\\n\t\t * propagate out of the executor longjmp handler. \\\n\t\t */ \\\n\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL); \\\n\t\tret_result = duk__handle_return(thr, entry_act); \\\n\t\tif (ret_result == DUK__RETHAND_RESTART) { \\\n\t\t\tgoto restart_execution; \\\n\t\t} \\\n\t\tDUK_ASSERT(ret_result == DUK__RETHAND_FINISHED); \\\n\t\treturn; \\\n\t} while (0)\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t\tcase DUK_OP_RETREG:\n\t\tcase DUK_OP_RETCONST:\n\t\tcase DUK_OP_RETCONSTN:\n\t\tcase DUK_OP_RETUNDEF: {\n\t\t\t /* BC -> return value reg/const */\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\n\t\t\tif (op == DUK_OP_RETREG) {\n\t\t\t\tduk_push_tval(thr, DUK__REGP_BC(ins));\n\t\t\t} else if (op == DUK_OP_RETUNDEF) {\n\t\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));  /* valstack policy */\n\t\t\t\tthr->valstack_top++;\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(op == DUK_OP_RETCONST || op == DUK_OP_RETCONSTN);\n\t\t\t\tduk_push_tval(thr, DUK__CONSTP_BC(ins));\n\t\t\t}\n\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tcase DUK_OP_RETREG: {\n\t\t\tduk_tval *tv;\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\ttv = DUK__REGP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tthr->valstack_top++;\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n\t\t/* This will be unused without refcounting. */\n\t\tcase DUK_OP_RETCONST: {\n\t\t\tduk_tval *tv;\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\ttv = DUK__CONSTP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tthr->valstack_top++;\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n\t\tcase DUK_OP_RETCONSTN: {\n\t\t\tduk_tval *tv;\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\ttv = DUK__CONSTP_BC(ins);\n\t\t\tDUK_TVAL_SET_TVAL(thr->valstack_top, tv);\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\t\t\t/* Without refcounting only RETCONSTN is used. */\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_HEAP_ALLOCATED(tv));  /* no INCREF for this constant */\n#endif\n\t\t\tthr->valstack_top++;\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n\t\tcase DUK_OP_RETUNDEF: {\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\tthr->valstack_top++;  /* value at valstack top is already undefined by valstack policy */\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_UNDEFINED(thr->valstack_top));\n\t\t\tDUK__RETURN_SHARED();\n\t\t}\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\n\t\tcase DUK_OP_LABEL: {\n\t\t\tduk_activation *act;\n\t\t\tduk_catcher *cat;\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\t/* Allocate catcher and populate it (must be atomic). */\n\n\t\t\tcat = duk_hthread_catcher_alloc(thr);\n\t\t\tDUK_ASSERT(cat != NULL);\n\n\t\t\tcat->flags = (duk_uint32_t) (DUK_CAT_TYPE_LABEL | (bc << DUK_CAT_LABEL_SHIFT));\n\t\t\tcat->pc_base = (duk_instr_t *) curr_pc;  /* pre-incremented, points to first jump slot */\n\t\t\tcat->idx_base = 0;  /* unused for label */\n\t\t\tcat->h_varname = NULL;\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(act != NULL);\n\t\t\tcat->parent = act->cat;\n\t\t\tact->cat = cat;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"LABEL catcher: flags=0x%08lx, pc_base=%ld, \"\n\t\t\t                     \"idx_base=%ld, h_varname=%!O, label_id=%ld\",\n\t\t\t                     (long) cat->flags, (long) cat->pc_base,\n\t\t\t                     (long) cat->idx_base, (duk_heaphdr *) cat->h_varname, (long) DUK_CAT_GET_LABEL(cat)));\n\n\t\t\tcurr_pc += 2;  /* skip jump slots */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDLABEL: {\n\t\t\tduk_activation *act;\n#if (defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)) || defined(DUK_USE_ASSERTIONS)\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n#endif\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"ENDLABEL %ld\", (long) bc));\n#endif\n\n\t\t\tact = thr->callstack_curr;\n\t\t\tDUK_ASSERT(act->cat != NULL);\n\t\t\tDUK_ASSERT(DUK_CAT_GET_TYPE(act->cat) == DUK_CAT_TYPE_LABEL);\n\t\t\tDUK_ASSERT((duk_uint_fast_t) DUK_CAT_GET_LABEL(act->cat) == bc);\n\t\t\tduk_hthread_catcher_unwind_nolexenv_norz(thr, act);\n\n\t\t\t/* no need to unwind callstack */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_BREAK: {\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\tduk__handle_break_or_continue(thr, (duk_uint_t) bc, DUK_LJ_TYPE_BREAK);\n\t\t\tgoto restart_execution;\n\t\t}\n\n\t\tcase DUK_OP_CONTINUE: {\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\tduk__handle_break_or_continue(thr, (duk_uint_t) bc, DUK_LJ_TYPE_CONTINUE);\n\t\t\tgoto restart_execution;\n\t\t}\n\n\t\t/* XXX: move to helper, too large to be inline here */\n\t\tcase DUK_OP_TRYCATCH: {\n\t\t\tduk__handle_op_trycatch(thr, ins, curr_pc);\n\t\t\tcurr_pc += 2;  /* skip jump slots */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDTRY: {\n\t\t\tcurr_pc = duk__handle_op_endtry(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDCATCH: {\n\t\t\tduk__handle_op_endcatch(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_ENDFIN: {\n\t\t\t/* Sync and NULL early. */\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\n\t\t\tif (duk__handle_op_endfin(thr, ins, entry_act) != 0) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t/* Must restart because we NULLed out curr_pc. */\n\t\t\tgoto restart_execution;\n\t\t}\n\n\t\tcase DUK_OP_THROW: {\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\t/* Note: errors are augmented when they are created, not\n\t\t\t * when they are thrown.  So, don't augment here, it would\n\t\t\t * break re-throwing for instance.\n\t\t\t */\n\n\t\t\t/* Sync so that augmentation sees up-to-date activations, NULL\n\t\t\t * thr->ptr_curr_pc so that it's not used if side effects occur\n\t\t\t * in augmentation or longjmp handling.\n\t\t\t */\n\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\n\t\t\tduk_dup(thr, (duk_idx_t) bc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (BYTECODE): %!dT (before throw augment)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n#if defined(DUK_USE_AUGMENT_ERROR_THROW)\n\t\t\tduk_err_augment_error_throw(thr);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"THROW ERROR (BYTECODE): %!dT (after throw augment)\",\n\t\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n#endif\n\n\t\t\tduk_err_setup_ljstate1(thr, DUK_LJ_TYPE_THROW, DUK_GET_TVAL_NEGIDX(thr, -1));\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\t\tduk_err_check_debugger_integration(thr);\n#endif\n\n\t\t\tDUK_ASSERT(thr->heap->lj.jmpbuf_ptr != NULL);  /* always in executor */\n\t\t\tduk_err_longjmp(thr);\n\t\t\tDUK_UNREACHABLE();\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_CSREG: {\n\t\t\t/*\n\t\t\t *  Assuming a register binds to a variable declared within this\n\t\t\t *  function (a declarative binding), the 'this' for the call\n\t\t\t *  setup is always 'undefined'.  E5 Section 10.2.1.1.6.\n\t\t\t */\n\n\t\t\tduk_small_uint_fast_t a = DUK_DEC_A(ins);\n\t\t\tduk_small_uint_fast_t bc = DUK_DEC_BC(ins);\n\n\t\t\t/* A -> register containing target function (not type checked here)\n\t\t\t * BC -> target registers (BC, BC + 1) for call setup\n\t\t\t */\n\n#if defined(DUK_USE_PREFER_SIZE)\n\t\t\tduk_dup(thr, (duk_idx_t) a);\n\t\t\tduk_replace(thr, (duk_idx_t) bc);\n\t\t\tduk_to_undefined(thr, (duk_idx_t) (bc + 1));\n#else\n\t\t\tduk_tval *tv1;\n\t\t\tduk_tval *tv2;\n\t\t\tduk_tval *tv3;\n\t\t\tduk_tval tv_tmp1;\n\t\t\tduk_tval tv_tmp2;\n\n\t\t\ttv1 = DUK__REGP(bc);\n\t\t\ttv2 = tv1 + 1;\n\t\t\tDUK_TVAL_SET_TVAL(&tv_tmp1, tv1);\n\t\t\tDUK_TVAL_SET_TVAL(&tv_tmp2, tv2);\n\t\t\ttv3 = DUK__REGP(a);\n\t\t\tDUK_TVAL_SET_TVAL(tv1, tv3);\n\t\t\tDUK_TVAL_INCREF(thr, tv1);  /* no side effects */\n\t\t\tDUK_TVAL_SET_UNDEFINED(tv2);  /* no need for incref */\n\t\t\tDUK_TVAL_DECREF(thr, &tv_tmp1);\n\t\t\tDUK_TVAL_DECREF(thr, &tv_tmp2);\n#endif\n\t\t\tbreak;\n\t\t}\n\n\n\t\t/* XXX: in some cases it's faster NOT to reuse the value\n\t\t * stack but rather copy the arguments on top of the stack\n\t\t * (mainly when the calling value stack is large and the value\n\t\t * stack resize would be large).\n\t\t */\n\n\t\tcase DUK_OP_CALL0:\n\t\tcase DUK_OP_CALL1:\n\t\tcase DUK_OP_CALL2:\n\t\tcase DUK_OP_CALL3:\n\t\tcase DUK_OP_CALL4:\n\t\tcase DUK_OP_CALL5:\n\t\tcase DUK_OP_CALL6:\n\t\tcase DUK_OP_CALL7: {\n\t\t\t/* Opcode packs 4 flag bits: 1 for indirect, 3 map\n\t\t\t * 1:1 to three lowest call handling flags.\n\t\t\t *\n\t\t\t * A -> nargs or register with nargs (indirect)\n\t\t\t * BC -> base register for call (base -> func, base+1 -> this, base+2 -> arg1 ... base+2+N-1 -> argN)\n\t\t\t */\n\n\t\t\tduk_idx_t nargs;\n\t\t\tduk_idx_t idx;\n\t\t\tduk_small_uint_t call_flags;\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tduk_hcompfunc *fun;\n#endif\n\n\t\t\tDUK_ASSERT((DUK_OP_CALL0 & 0x0fU) == 0);\n\t\t\tDUK_ASSERT((ins & DUK_BC_CALL_FLAG_INDIRECT) == 0);\n\n\t\t\tnargs = (duk_idx_t) DUK_DEC_A(ins);\n\t\t\tcall_flags = (ins & 0x07U) | DUK_CALL_FLAG_ALLOW_ECMATOECMA;\n\t\t\tidx = (duk_idx_t) DUK_DEC_BC(ins);\n\n\t\t\tif (duk__executor_handle_call(thr, idx, nargs, call_flags)) {\n\t\t\t\t/* curr_pc synced by duk_handle_call_unprotected() */\n\t\t\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n\t\t\tDUK_ASSERT(thr->ptr_curr_pc != NULL);\n\n\t\t\t/* duk_js_call.c is required to restore the stack reserve\n\t\t\t * so we only need to reset the top.\n\t\t\t */\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tfun = DUK__FUN();\n#endif\n\t\t\tduk_set_top_unsafe(thr, (duk_idx_t) fun->nregs);\n\n\t\t\t/* No need to reinit setjmp() catchpoint, as call handling\n\t\t\t * will store and restore our state.\n\t\t\t *\n\t\t\t * When debugger is enabled, we need to recheck the activation\n\t\t\t * status after returning.  This is now handled by call handling\n\t\t\t * and heap->dbg_force_restart.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_CALL8:\n\t\tcase DUK_OP_CALL9:\n\t\tcase DUK_OP_CALL10:\n\t\tcase DUK_OP_CALL11:\n\t\tcase DUK_OP_CALL12:\n\t\tcase DUK_OP_CALL13:\n\t\tcase DUK_OP_CALL14:\n\t\tcase DUK_OP_CALL15: {\n\t\t\t/* Indirect variant. */\n\t\t\tduk_uint_fast_t nargs;\n\t\t\tduk_idx_t idx;\n\t\t\tduk_small_uint_t call_flags;\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tduk_hcompfunc *fun;\n#endif\n\n\t\t\tDUK_ASSERT((DUK_OP_CALL0 & 0x0fU) == 0);\n\t\t\tDUK_ASSERT((ins & DUK_BC_CALL_FLAG_INDIRECT) != 0);\n\n\t\t\tnargs = (duk_uint_fast_t) DUK_DEC_A(ins);\n\t\t\tDUK__LOOKUP_INDIRECT(nargs);\n\t\t\tcall_flags = (ins & 0x07U) | DUK_CALL_FLAG_ALLOW_ECMATOECMA;\n\t\t\tidx = (duk_idx_t) DUK_DEC_BC(ins);\n\n\t\t\tif (duk__executor_handle_call(thr, idx, (duk_idx_t) nargs, call_flags)) {\n\t\t\t\tDUK_ASSERT(thr->ptr_curr_pc == NULL);\n\t\t\t\tgoto restart_execution;\n\t\t\t}\n\t\t\tDUK_ASSERT(thr->ptr_curr_pc != NULL);\n\n#if !defined(DUK_USE_EXEC_FUN_LOCAL)\n\t\t\tfun = DUK__FUN();\n#endif\n\t\t\tduk_set_top_unsafe(thr, (duk_idx_t) fun->nregs);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_NEWOBJ: {\n\t\t\tduk_push_object(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t{\n\t\t\t\tduk_hobject *h;\n\t\t\t\th = duk_require_hobject(thr, -1);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ESIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(h) == 0);\n\t\t\t}\n#endif\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\t/* XXX: could do a direct props realloc, but need hash size */\n\t\t\tduk_hobject_resize_entrypart(thr, duk_known_hobject(thr, -1), DUK_DEC_A(ins));\n#endif\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_NEWARR: {\n\t\t\tduk_push_array(thr);\n#if defined(DUK_USE_ASSERTIONS)\n\t\t\t{\n\t\t\t\tduk_hobject *h;\n\t\t\t\th = duk_require_hobject(thr, -1);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ESIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ENEXT(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_ASIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_HSIZE(h) == 0);\n\t\t\t\tDUK_ASSERT(DUK_HOBJECT_HAS_ARRAY_PART(h));\n\t\t\t}\n#endif\n#if !defined(DUK_USE_PREFER_SIZE)\n\t\t\tduk_hobject_realloc_props(thr,\n\t\t\t                          duk_known_hobject(thr, -1),\n\t\t\t                          0 /*new_e_size*/,\n\t\t\t                          DUK_DEC_A(ins) /*new_a_size*/,\n\t\t\t                          0 /*new_h_size*/,\n\t\t\t                          0 /*abandon_array*/);\n#if 0\n\t\t\tduk_hobject_resize_arraypart(thr, duk_known_hobject(thr, -1), DUK_DEC_A(ins));\n#endif\n#endif\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n\n\t\tcase DUK_OP_MPUTOBJ:\n\t\tcase DUK_OP_MPUTOBJI: {\n\t\t\tduk_idx_t obj_idx;\n\t\t\tduk_uint_fast_t idx, idx_end;\n\t\t\tduk_small_uint_fast_t count;\n\n\t\t\t/* A -> register of target object\n\t\t\t * B -> first register of key/value pair list\n\t\t\t *      or register containing first register number if indirect\n\t\t\t * C -> number of key/value pairs * 2\n\t\t\t *      (= number of value stack indices used starting from 'B')\n\t\t\t */\n\n\t\t\tobj_idx = DUK_DEC_A(ins);\n\t\t\tDUK_ASSERT(duk_is_object(thr, obj_idx));\n\n\t\t\tidx = (duk_uint_fast_t) DUK_DEC_B(ins);\n\t\t\tif (DUK_DEC_OP(ins) == DUK_OP_MPUTOBJI) {\n\t\t\t\tDUK__LOOKUP_INDIRECT(idx);\n\t\t\t}\n\n\t\t\tcount = (duk_small_uint_fast_t) DUK_DEC_C(ins);\n\t\t\tDUK_ASSERT(count > 0);  /* compiler guarantees */\n\t\t\tidx_end = idx + count;\n\n#if defined(DUK_USE_EXEC_INDIRECT_BOUND_CHECK)\n\t\t\tif (DUK_UNLIKELY(idx_end > (duk_uint_fast_t) duk_get_top(thr))) {\n\t\t\t\t/* XXX: use duk_is_valid_index() instead? */\n\t\t\t\t/* XXX: improve check; check against nregs, not against top */\n\t\t\t\tDUK__INTERNAL_ERROR(\"MPUTOBJ out of bounds\");\n\t\t\t}\n#endif\n\n\t\t\t/* Use 'force' flag to duk_def_prop() to ensure that any\n\t\t\t * inherited properties don't prevent the operation.\n\t\t\t * With ES2015 duplicate properties are allowed, so that we\n\t\t\t * must overwrite any previous data or accessor property.\n\t\t\t *\n\t\t\t * With ES2015 computed property names the literal keys\n\t\t\t * may be arbitrary values and need to be ToPropertyKey()\n\t\t\t * coerced at runtime.\n\t\t\t */\n\t\t\tdo {\n\t\t\t\t/* XXX: faster initialization (direct access or better primitives) */\n\t\t\t\tduk_dup(thr, (duk_idx_t) idx);\n\t\t\t\tduk_dup(thr, (duk_idx_t) (idx + 1));\n\t\t\t\tduk_def_prop(thr, obj_idx, DUK_DEFPROP_HAVE_VALUE |\n\t\t\t\t                           DUK_DEFPROP_FORCE |\n\t\t\t\t                           DUK_DEFPROP_SET_WRITABLE |\n\t\t\t\t                           DUK_DEFPROP_SET_ENUMERABLE |\n\t\t\t\t                           DUK_DEFPROP_SET_CONFIGURABLE);\n\t\t\t\tidx += 2;\n\t\t\t} while (idx < idx_end);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INITSET:\n\t\tcase DUK_OP_INITGET: {\n\t\t\tduk__handle_op_initset_initget(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_MPUTARR:\n\t\tcase DUK_OP_MPUTARRI: {\n\t\t\tduk_idx_t obj_idx;\n\t\t\tduk_uint_fast_t idx, idx_end;\n\t\t\tduk_small_uint_fast_t count;\n\t\t\tduk_tval *tv1;\n\t\t\tduk_uint32_t arr_idx;\n\n\t\t\t/* A -> register of target object\n\t\t\t * B -> first register of value data (start_index, value1, value2, ..., valueN)\n\t\t\t *      or register containing first register number if indirect\n\t\t\t * C -> number of key/value pairs (N)\n\t\t\t */\n\n\t\t\tobj_idx = DUK_DEC_A(ins);\n\t\t\tDUK_ASSERT(duk_is_object(thr, obj_idx));\n\n\t\t\tidx = (duk_uint_fast_t) DUK_DEC_B(ins);\n\t\t\tif (DUK_DEC_OP(ins) == DUK_OP_MPUTARRI) {\n\t\t\t\tDUK__LOOKUP_INDIRECT(idx);\n\t\t\t}\n\n\t\t\tcount = (duk_small_uint_fast_t) DUK_DEC_C(ins);\n\t\t\tDUK_ASSERT(count > 0 + 1);  /* compiler guarantees */\n\t\t\tidx_end = idx + count;\n\n#if defined(DUK_USE_EXEC_INDIRECT_BOUND_CHECK)\n\t\t\tif (idx_end > (duk_uint_fast_t) duk_get_top(thr)) {\n\t\t\t\t/* XXX: use duk_is_valid_index() instead? */\n\t\t\t\t/* XXX: improve check; check against nregs, not against top */\n\t\t\t\tDUK__INTERNAL_ERROR(\"MPUTARR out of bounds\");\n\t\t\t}\n#endif\n\n\t\t\ttv1 = DUK__REGP(idx);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\t\tarr_idx = (duk_uint32_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\t\t\tarr_idx = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\t\tidx++;\n\n\t\t\tdo {\n\t\t\t\t/* duk_xdef_prop() will define an own property without any array\n\t\t\t\t * special behaviors.  We'll need to set the array length explicitly\n\t\t\t\t * in the end.  For arrays with elisions, the compiler will emit an\n\t\t\t\t * explicit SETALEN which will update the length.\n\t\t\t\t */\n\n\t\t\t\t/* XXX: because we're dealing with 'own' properties of a fresh array,\n\t\t\t\t * the array initializer should just ensure that the array has a large\n\t\t\t\t * enough array part and write the values directly into array part,\n\t\t\t\t * and finally set 'length' manually in the end (as already happens now).\n\t\t\t\t */\n\n\t\t\t\tduk_dup(thr, (duk_idx_t) idx);\n\t\t\t\tduk_xdef_prop_index_wec(thr, obj_idx, arr_idx);\n\n\t\t\t\tidx++;\n\t\t\t\tarr_idx++;\n\t\t\t} while (idx < idx_end);\n\n\t\t\t/* XXX: E5.1 Section 11.1.4 coerces the final length through\n\t\t\t * ToUint32() which is odd but happens now as a side effect of\n\t\t\t * 'arr_idx' type.\n\t\t\t */\n\t\t\tduk_set_length(thr, obj_idx, (duk_size_t) (duk_uarridx_t) arr_idx);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_SETALEN: {\n\t\t\tduk_tval *tv1;\n\t\t\tduk_hobject *h;\n\t\t\tduk_uint32_t len;\n\n\t\t\ttv1 = DUK__REGP_A(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_OBJECT(tv1));\n\t\t\th = DUK_TVAL_GET_OBJECT(tv1);\n\t\t\tDUK_ASSERT(DUK_HOBJECT_IS_ARRAY(h));\n\n\t\t\ttv1 = DUK__REGP_BC(ins);\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv1));\n#if defined(DUK_USE_FASTINT)\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv1));\n\t\t\tlen = (duk_uint32_t) DUK_TVAL_GET_FASTINT_U32(tv1);\n#else\n\t\t\tlen = (duk_uint32_t) DUK_TVAL_GET_NUMBER(tv1);\n#endif\n\t\t\t((duk_harray *) h)->length = len;\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INITENUM: {\n\t\t\tduk__handle_op_initenum(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_NEXTENUM: {\n\t\t\tcurr_pc += duk__handle_op_nextenum(thr, ins);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INVLHS: {\n\t\t\tDUK_ERROR_REFERENCE(thr, DUK_STR_INVALID_LVALUE);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_DEBUGGER: {\n\t\t\t/* Opcode only emitted by compiler when debugger\n\t\t\t * support is enabled.  Ignore it silently without\n\t\t\t * debugger support, in case it has been loaded\n\t\t\t * from precompiled bytecode.\n\t\t\t */\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\t\t\tif (duk_debug_is_attached(thr->heap)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement encountered, halt execution\"));\n\t\t\t\tDUK__SYNC_AND_NULL_CURR_PC();\n\t\t\t\tduk_debug_halt_execution(thr, 1 /*use_prev_pc*/);\n\t\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement finished, resume execution\"));\n\t\t\t\tgoto restart_execution;\n\t\t\t} else {\n\t\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement ignored, debugger not attached\"));\n\t\t\t}\n#else\n\t\t\tDUK_D(DUK_DPRINT(\"DEBUGGER statement ignored, no debugger support\"));\n#endif\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_NOP: {\n\t\t\t/* Nop, ignored, but ABC fields may carry a value e.g.\n\t\t\t * for indirect opcode handling.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\n\t\tcase DUK_OP_INVALID: {\n\t\t\tDUK_ERROR_FMT1(thr, DUK_ERR_ERROR, \"INVALID opcode (%ld)\", (long) DUK_DEC_ABC(ins));\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t\tbreak;\n\t\t}\n\n#if defined(DUK_USE_ES6)\n\t\tcase DUK_OP_NEWTARGET: {\n\t\t\tduk_push_new_target(thr);\n\t\t\tDUK__REPLACE_TOP_BC_BREAK();\n\t\t}\n#endif  /* DUK_USE_ES6 */\n\n#if !defined(DUK_USE_EXEC_PREFER_SIZE)\n#if !defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tcase DUK_OP_EXP_RR:\n\t\tcase DUK_OP_EXP_CR:\n\t\tcase DUK_OP_EXP_RC:\n\t\tcase DUK_OP_EXP_CC:\n#endif\n#if !defined(DUK_USE_ES6)\n\t\tcase DUK_OP_NEWTARGET:\n#endif\n#if !defined(DUK_USE_VERBOSE_ERRORS)\n\t\tcase DUK_OP_GETPROPC_RR:\n\t\tcase DUK_OP_GETPROPC_CR:\n\t\tcase DUK_OP_GETPROPC_RC:\n\t\tcase DUK_OP_GETPROPC_CC:\n#endif\n\t\tcase DUK_OP_UNUSED207:\n\t\tcase DUK_OP_UNUSED212:\n\t\tcase DUK_OP_UNUSED213:\n\t\tcase DUK_OP_UNUSED214:\n\t\tcase DUK_OP_UNUSED215:\n\t\tcase DUK_OP_UNUSED216:\n\t\tcase DUK_OP_UNUSED217:\n\t\tcase DUK_OP_UNUSED218:\n\t\tcase DUK_OP_UNUSED219:\n\t\tcase DUK_OP_UNUSED220:\n\t\tcase DUK_OP_UNUSED221:\n\t\tcase DUK_OP_UNUSED222:\n\t\tcase DUK_OP_UNUSED223:\n\t\tcase DUK_OP_UNUSED224:\n\t\tcase DUK_OP_UNUSED225:\n\t\tcase DUK_OP_UNUSED226:\n\t\tcase DUK_OP_UNUSED227:\n\t\tcase DUK_OP_UNUSED228:\n\t\tcase DUK_OP_UNUSED229:\n\t\tcase DUK_OP_UNUSED230:\n\t\tcase DUK_OP_UNUSED231:\n\t\tcase DUK_OP_UNUSED232:\n\t\tcase DUK_OP_UNUSED233:\n\t\tcase DUK_OP_UNUSED234:\n\t\tcase DUK_OP_UNUSED235:\n\t\tcase DUK_OP_UNUSED236:\n\t\tcase DUK_OP_UNUSED237:\n\t\tcase DUK_OP_UNUSED238:\n\t\tcase DUK_OP_UNUSED239:\n\t\tcase DUK_OP_UNUSED240:\n\t\tcase DUK_OP_UNUSED241:\n\t\tcase DUK_OP_UNUSED242:\n\t\tcase DUK_OP_UNUSED243:\n\t\tcase DUK_OP_UNUSED244:\n\t\tcase DUK_OP_UNUSED245:\n\t\tcase DUK_OP_UNUSED246:\n\t\tcase DUK_OP_UNUSED247:\n\t\tcase DUK_OP_UNUSED248:\n\t\tcase DUK_OP_UNUSED249:\n\t\tcase DUK_OP_UNUSED250:\n\t\tcase DUK_OP_UNUSED251:\n\t\tcase DUK_OP_UNUSED252:\n\t\tcase DUK_OP_UNUSED253:\n\t\tcase DUK_OP_UNUSED254:\n\t\tcase DUK_OP_UNUSED255:\n\t\t/* Force all case clauses to map to an actual handler\n\t\t * so that the compiler can emit a jump without a bounds\n\t\t * check: the switch argument is a duk_uint8_t so that\n\t\t * the compiler may be able to figure it out.  This is\n\t\t * a small detail and obviously compiler dependent.\n\t\t */\n\t\t/* default: clause omitted on purpose */\n#else  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\tdefault:\n#endif  /* DUK_USE_EXEC_PREFER_SIZE */\n\t\t{\n\t\t\t/* Default case catches invalid/unsupported opcodes. */\n\t\t\tDUK_D(DUK_DPRINT(\"invalid opcode: %ld - %!I\", (long) op, ins));\n\t\t\tDUK__INTERNAL_ERROR(\"invalid opcode\");\n\t\t\tbreak;\n\t\t}\n\n\t\t}  /* end switch */\n\n\t\tcontinue;\n\n\t\t/* Some shared exit paths for opcode handling below.  These\n\t\t * are mostly useful to reduce code footprint when multiple\n\t\t * opcodes have a similar epilogue (like replacing stack top\n\t\t * with index 'a').\n\t\t */\n\n#if defined(DUK_USE_EXEC_PREFER_SIZE)\n\t replace_top_a:\n\t\tDUK__REPLACE_TO_TVPTR(thr, DUK__REGP_A(ins));\n\t\tcontinue;\n\t replace_top_bc:\n\t\tDUK__REPLACE_TO_TVPTR(thr, DUK__REGP_BC(ins));\n\t\tcontinue;\n#endif\n\t}\n\tDUK_WO_NORETURN(return;);\n\n#if !defined(DUK_USE_VERBOSE_EXECUTOR_ERRORS)\n internal_error:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return;);\n#endif\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_js_ops.c",
    "content": "/*\n *  ECMAScript specification algorithm and conversion helpers.\n *\n *  These helpers encapsulate the primitive ECMAScript operation semantics,\n *  and are used by the bytecode executor and the API (among other places).\n *  Some primitives are only implemented as part of the API and have no\n *  \"internal\" helper.  This is the case when an internal helper would not\n *  really be useful; e.g. the operation is rare, uses value stack heavily,\n *  etc.\n *\n *  The operation arguments depend on what is required to implement\n *  the operation:\n *\n *    - If an operation is simple and stateless, and has no side\n *      effects, it won't take an duk_hthread argument and its\n *      arguments may be duk_tval pointers (which are safe as long\n *      as no side effects take place).\n *\n *    - If complex coercions are required (e.g. a \"ToNumber\" coercion)\n *      or errors may be thrown, the operation takes an duk_hthread\n *      argument.  This also implies that the operation may have\n *      arbitrary side effects, invalidating any duk_tval pointers.\n *\n *    - For operations with potential side effects, arguments can be\n *      taken in several ways:\n *\n *      a) as duk_tval pointers, which makes sense if the \"common case\"\n *         can be resolved without side effects (e.g. coercion); the\n *         arguments are pushed to the valstack for coercion if\n *         necessary\n *\n *      b) as duk_tval values\n *\n *      c) implicitly on value stack top\n *\n *      d) as indices to the value stack\n *\n *  Future work:\n *\n *     - Argument styles may not be the most sensible in every case now.\n *\n *     - In-place coercions might be useful for several operations, if\n *       in-place coercion is OK for the bytecode executor and the API.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  ToPrimitive()  (E5 Section 9.1)\n *\n *  ==> implemented in the API.\n */\n\n/*\n *  ToBoolean()  (E5 Section 9.2)\n */\n\nDUK_INTERNAL duk_bool_t duk_js_toboolean(duk_tval *tv) {\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED:\n\tcase DUK_TAG_NULL:\n\t\treturn 0;\n\tcase DUK_TAG_BOOLEAN:\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv) == 0 || DUK_TVAL_GET_BOOLEAN(tv) == 1);\n\t\treturn DUK_TVAL_GET_BOOLEAN(tv);\n\tcase DUK_TAG_STRING: {\n\t\t/* Symbols ToBoolean() coerce to true, regardless of their\n\t\t * description.  This happens with no explicit check because\n\t\t * of the symbol representation byte prefix.\n\t\t */\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tDUK_ASSERT(h != NULL);\n\t\treturn (DUK_HSTRING_GET_BYTELEN(h) > 0 ? 1 : 0);\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\treturn 1;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\t/* Mimic Uint8Array semantics: objects coerce true, regardless\n\t\t * of buffer length (zero or not) or context.\n\t\t */\n\t\treturn 1;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\tvoid *p = DUK_TVAL_GET_POINTER(tv);\n\t\treturn (p != NULL ? 1 : 0);\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\treturn 1;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\tif (DUK_TVAL_GET_FASTINT(tv) != 0) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tduk_double_t d;\n#if defined(DUK_USE_PREFER_SIZE)\n\t\tint c;\n#endif\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\t\td = DUK_TVAL_GET_DOUBLE(tv);\n#if defined(DUK_USE_PREFER_SIZE)\n\t\tc = DUK_FPCLASSIFY((double) d);\n\t\tif (c == DUK_FP_ZERO || c == DUK_FP_NAN) {\n\t\t\treturn 0;\n\t\t} else {\n\t\t\treturn 1;\n\t\t}\n#else\n\t\tDUK_ASSERT(duk_double_is_nan_or_zero(d) == 0 || duk_double_is_nan_or_zero(d) == 1);\n\t\treturn duk_double_is_nan_or_zero(d) ^ 1;\n#endif\n\t}\n\t}\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  ToNumber()  (E5 Section 9.3)\n *\n *  Value to convert must be on stack top, and is popped before exit.\n *\n *  See: http://www.cs.indiana.edu/~burger/FP-Printing-PLDI96.pdf\n *       http://www.cs.indiana.edu/~burger/fp/index.html\n *\n *  Notes on the conversion:\n *\n *    - There are specific requirements on the accuracy of the conversion\n *      through a \"Mathematical Value\" (MV), so this conversion is not\n *      trivial.\n *\n *    - Quick rejects (e.g. based on first char) are difficult because\n *      the grammar allows leading and trailing white space.\n *\n *    - Quick reject based on string length is difficult even after\n *      accounting for white space; there may be arbitrarily many\n *      decimal digits.\n *\n *    - Standard grammar allows decimal values (\"123\"), hex values\n *      (\"0x123\") and infinities\n *\n *    - Unlike source code literals, ToNumber() coerces empty strings\n *      and strings with only whitespace to zero (not NaN).  However,\n *      while '' coerces to 0, '+' and '-' coerce to NaN.\n */\n\n/* E5 Section 9.3.1 */\nDUK_LOCAL duk_double_t duk__tonumber_string_raw(duk_hthread *thr) {\n\tduk_small_uint_t s2n_flags;\n\tduk_double_t d;\n\n\tDUK_ASSERT(duk_is_string(thr, -1));\n\n\t/* Quite lenient, e.g. allow empty as zero, but don't allow trailing\n\t * garbage.\n\t */\n\ts2n_flags = DUK_S2N_FLAG_TRIM_WHITE |\n\t            DUK_S2N_FLAG_ALLOW_EXP |\n\t            DUK_S2N_FLAG_ALLOW_PLUS |\n\t            DUK_S2N_FLAG_ALLOW_MINUS |\n\t            DUK_S2N_FLAG_ALLOW_INF |\n\t            DUK_S2N_FLAG_ALLOW_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t            DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO |\n\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT |\n\t            DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT;\n\n\tduk_numconv_parse(thr, 10 /*radix*/, s2n_flags);\n\n#if defined(DUK_USE_PREFER_SIZE)\n\td = duk_get_number(thr, -1);\n\tduk_pop_unsafe(thr);\n#else\n\tthr->valstack_top--;\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(thr->valstack_top));\n\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(thr->valstack_top));  /* no fastint conversion in numconv now */\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(thr->valstack_top));\n\td = DUK_TVAL_GET_DOUBLE(thr->valstack_top);  /* assumes not a fastint */\n\tDUK_TVAL_SET_UNDEFINED(thr->valstack_top);\n#endif\n\n\treturn d;\n}\n\nDUK_INTERNAL duk_double_t duk_js_tonumber(duk_hthread *thr, duk_tval *tv) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(tv != NULL);\n\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\t/* return a specific NaN (although not strictly necessary) */\n\t\tduk_double_union du;\n\t\tDUK_DBLUNION_SET_NAN(&du);\n\t\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\t\treturn du.d;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\t/* +0.0 */\n\t\treturn 0.0;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tif (DUK_TVAL_IS_BOOLEAN_TRUE(tv)) {\n\t\t\treturn 1.0;\n\t\t}\n\t\treturn 0.0;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\t/* For Symbols ToNumber() is always a TypeError. */\n\t\tduk_hstring *h = DUK_TVAL_GET_STRING(tv);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) {\n\t\t\tDUK_ERROR_TYPE(thr, DUK_STR_CANNOT_NUMBER_COERCE_SYMBOL);\n\t\t\tDUK_WO_NORETURN(return 0.0;);\n\t\t}\n\t\tduk_push_hstring(thr, h);\n\t\treturn duk__tonumber_string_raw(thr);\n\t}\n\tcase DUK_TAG_BUFFER:  /* plain buffer treated like object */\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_double_t d;\n\t\tduk_push_tval(thr, tv);\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);  /* 'tv' becomes invalid */\n\n\t\t/* recursive call for a primitive value (guaranteed not to cause second\n\t\t * recursion).\n\t\t */\n\t\tDUK_ASSERT(duk_get_tval(thr, -1) != NULL);\n\t\td = duk_js_tonumber(thr, duk_get_tval(thr, -1));\n\n\t\tduk_pop_unsafe(thr);\n\t\treturn d;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\t/* Coerce like boolean */\n\t\tvoid *p = DUK_TVAL_GET_POINTER(tv);\n\t\treturn (p != NULL ? 1.0 : 0.0);\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\t/* +(function(){}) -> NaN */\n\t\treturn DUK_DOUBLE_NAN;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n\t\treturn (duk_double_t) DUK_TVAL_GET_FASTINT(tv);\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv));\n\t\tDUK_ASSERT(DUK_TVAL_IS_DOUBLE(tv));\n\t\treturn DUK_TVAL_GET_DOUBLE(tv);\n\t}\n\t}\n\n\tDUK_UNREACHABLE();\n}\n\n/*\n *  ToInteger()  (E5 Section 9.4)\n */\n\n/* exposed, used by e.g. duk_bi_date.c */\nDUK_INTERNAL duk_double_t duk_js_tointeger_number(duk_double_t x) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_small_int_t c = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\n\tif (DUK_UNLIKELY(c == DUK_FP_NAN)) {\n\t\treturn 0.0;\n\t} else if (DUK_UNLIKELY(c == DUK_FP_INFINITE)) {\n\t\treturn x;\n\t} else {\n\t\t/* Finite, including neg/pos zero.  Neg zero sign must be\n\t\t * preserved.\n\t\t */\n\t\treturn duk_double_trunc_towards_zero(x);\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\t/* NaN and Infinity have the same exponent so it's a cheap\n\t * initial check for the rare path.\n\t */\n\tif (DUK_UNLIKELY(duk_double_is_nan_or_inf(x) != 0U)) {\n\t\tif (duk_double_is_nan(x)) {\n\t\t\treturn 0.0;\n\t\t} else {\n\t\t\treturn x;\n\t\t}\n\t} else {\n\t\treturn duk_double_trunc_towards_zero(x);\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n}\n\nDUK_INTERNAL duk_double_t duk_js_tointeger(duk_hthread *thr, duk_tval *tv) {\n\t/* XXX: fastint */\n\tduk_double_t d = duk_js_tonumber(thr, tv);  /* invalidates tv */\n\treturn duk_js_tointeger_number(d);\n}\n\n/*\n *  ToInt32(), ToUint32(), ToUint16()  (E5 Sections 9.5, 9.6, 9.7)\n */\n\n/* combined algorithm matching E5 Sections 9.5 and 9.6 */\nDUK_LOCAL duk_double_t duk__toint32_touint32_helper(duk_double_t x, duk_bool_t is_toint32) {\n#if defined (DUK_USE_PREFER_SIZE)\n\tduk_small_int_t c;\n#endif\n\n#if defined (DUK_USE_PREFER_SIZE)\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (c == DUK_FP_NAN || c == DUK_FP_ZERO || c == DUK_FP_INFINITE) {\n\t\treturn 0.0;\n\t}\n#else\n\tif (duk_double_is_nan_zero_inf(x)) {\n\t\treturn 0.0;\n\t}\n#endif\n\n\t/* x = sign(x) * floor(abs(x)), i.e. truncate towards zero, keep sign */\n\tx = duk_double_trunc_towards_zero(x);\n\n\t/* NOTE: fmod(x) result sign is same as sign of x, which\n\t * differs from what Javascript wants (see Section 9.6).\n\t */\n\n\tx = DUK_FMOD(x, DUK_DOUBLE_2TO32);    /* -> x in ]-2**32, 2**32[ */\n\n\tif (x < 0.0) {\n\t\tx += DUK_DOUBLE_2TO32;\n\t}\n\tDUK_ASSERT(x >= 0 && x < DUK_DOUBLE_2TO32);  /* -> x in [0, 2**32[ */\n\n\tif (is_toint32) {\n\t\tif (x >= DUK_DOUBLE_2TO31) {\n\t\t\t/* x in [2**31, 2**32[ */\n\n\t\t\tx -= DUK_DOUBLE_2TO32;  /* -> x in [-2**31,2**31[ */\n\t\t}\n\t}\n\n\treturn x;\n}\n\nDUK_INTERNAL duk_int32_t duk_js_toint32(duk_hthread *thr, duk_tval *tv) {\n\tduk_double_t d;\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\treturn DUK_TVAL_GET_FASTINT_I32(tv);\n\t}\n#endif\n\n\td = duk_js_tonumber(thr, tv);  /* invalidates tv */\n\td = duk__toint32_touint32_helper(d, 1);\n\tDUK_ASSERT(DUK_FPCLASSIFY(d) == DUK_FP_ZERO || DUK_FPCLASSIFY(d) == DUK_FP_NORMAL);\n\tDUK_ASSERT(d >= -2147483648.0 && d <= 2147483647.0);  /* [-0x80000000,0x7fffffff] */\n\tDUK_ASSERT(d == ((duk_double_t) ((duk_int32_t) d)));  /* whole, won't clip */\n\treturn (duk_int32_t) d;\n}\n\n\nDUK_INTERNAL duk_uint32_t duk_js_touint32(duk_hthread *thr, duk_tval *tv) {\n\tduk_double_t d;\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv)) {\n\t\treturn DUK_TVAL_GET_FASTINT_U32(tv);\n\t}\n#endif\n\n\td = duk_js_tonumber(thr, tv);  /* invalidates tv */\n\td = duk__toint32_touint32_helper(d, 0);\n\tDUK_ASSERT(DUK_FPCLASSIFY(d) == DUK_FP_ZERO || DUK_FPCLASSIFY(d) == DUK_FP_NORMAL);\n\tDUK_ASSERT(d >= 0.0 && d <= 4294967295.0);  /* [0x00000000, 0xffffffff] */\n\tDUK_ASSERT(d == ((duk_double_t) ((duk_uint32_t) d)));  /* whole, won't clip */\n\treturn (duk_uint32_t) d;\n\n}\n\nDUK_INTERNAL duk_uint16_t duk_js_touint16(duk_hthread *thr, duk_tval *tv) {\n\t/* should be a safe way to compute this */\n\treturn (duk_uint16_t) (duk_js_touint32(thr, tv) & 0x0000ffffU);\n}\n\n/*\n *  ToString()  (E5 Section 9.8)\n *  ToObject()  (E5 Section 9.9)\n *  CheckObjectCoercible()  (E5 Section 9.10)\n *  IsCallable()  (E5 Section 9.11)\n *\n *  ==> implemented in the API.\n */\n\n/*\n *  Loose equality, strict equality, and SameValue (E5 Sections 11.9.1, 11.9.4,\n *  9.12).  These have much in common so they can share some helpers.\n *\n *  Future work notes:\n *\n *    - Current implementation (and spec definition) has recursion; this should\n *      be fixed if possible.\n *\n *    - String-to-number coercion should be possible without going through the\n *      value stack (and be more compact) if a shared helper is invoked.\n */\n\n/* Note that this is the same operation for strict and loose equality:\n *  - E5 Section 11.9.3, step 1.c (loose)\n *  - E5 Section 11.9.6, step 4 (strict)\n */\n\nDUK_LOCAL duk_bool_t duk__js_equals_number(duk_double_t x, duk_double_t y) {\n#if defined(DUK_USE_PARANOID_MATH)\n\t/* Straightforward algorithm, makes fewer compiler assumptions. */\n\tduk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tduk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\tif (cx == DUK_FP_NAN || cy == DUK_FP_NAN) {\n\t\treturn 0;\n\t}\n\tif (cx == DUK_FP_ZERO && cy == DUK_FP_ZERO) {\n\t\treturn 1;\n\t}\n\tif (x == y) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else  /* DUK_USE_PARANOID_MATH */\n\t/* Better equivalent algorithm.  If the compiler is compliant, C and\n\t * ECMAScript semantics are identical for this particular comparison.\n\t * In particular, NaNs must never compare equal and zeroes must compare\n\t * equal regardless of sign.  Could also use a macro, but this inlines\n\t * already nicely (no difference on gcc, for instance).\n\t */\n\tif (x == y) {\n\t\t/* IEEE requires that NaNs compare false */\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(x) != DUK_FP_NAN);\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(y) != DUK_FP_NAN);\n\t\treturn 1;\n\t} else {\n\t\t/* IEEE requires that zeros compare the same regardless\n\t\t * of their signed, so if both x and y are zeroes, they\n\t\t * are caught above.\n\t\t */\n\t\tDUK_ASSERT(!(DUK_FPCLASSIFY(x) == DUK_FP_ZERO && DUK_FPCLASSIFY(y) == DUK_FP_ZERO));\n\t\treturn 0;\n\t}\n#endif  /* DUK_USE_PARANOID_MATH */\n}\n\nDUK_LOCAL duk_bool_t duk__js_samevalue_number(duk_double_t x, duk_double_t y) {\n#if defined(DUK_USE_PARANOID_MATH)\n\tduk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tduk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\n\tif (cx == DUK_FP_NAN && cy == DUK_FP_NAN) {\n\t\t/* SameValue(NaN, NaN) = true, regardless of NaN sign or extra bits */\n\t\treturn 1;\n\t}\n\tif (cx == DUK_FP_ZERO && cy == DUK_FP_ZERO) {\n\t\t/* Note: cannot assume that a non-zero return value of signbit() would\n\t\t * always be the same -- hence cannot (portably) use something like:\n\t\t *\n\t\t *     signbit(x) == signbit(y)\n\t\t */\n\t\tduk_small_int_t sx = DUK_SIGNBIT(x) ? 1 : 0;\n\t\tduk_small_int_t sy = DUK_SIGNBIT(y) ? 1 : 0;\n\t\treturn (sx == sy);\n\t}\n\n\t/* normal comparison; known:\n\t *   - both x and y are not NaNs (but one of them can be)\n\t *   - both x and y are not zero (but one of them can be)\n\t *   - x and y may be denormal or infinite\n\t */\n\n\treturn (x == y);\n#else  /* DUK_USE_PARANOID_MATH */\n\tduk_small_int_t cx = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tduk_small_int_t cy = (duk_small_int_t) DUK_FPCLASSIFY(y);\n\n\tif (x == y) {\n\t\t/* IEEE requires that NaNs compare false */\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(x) != DUK_FP_NAN);\n\t\tDUK_ASSERT(DUK_FPCLASSIFY(y) != DUK_FP_NAN);\n\n\t\t/* Using classification has smaller footprint than direct comparison. */\n\t\tif (DUK_UNLIKELY(cx == DUK_FP_ZERO && cy == DUK_FP_ZERO)) {\n\t\t\t/* Note: cannot assume that a non-zero return value of signbit() would\n\t\t\t * always be the same -- hence cannot (portably) use something like:\n\t\t\t *\n\t\t\t *     signbit(x) == signbit(y)\n\t\t\t */\n\t\t\treturn duk_double_same_sign(x, y);\n\t\t}\n\t\treturn 1;\n\t} else {\n\t\t/* IEEE requires that zeros compare the same regardless\n\t\t * of their sign, so if both x and y are zeroes, they\n\t\t * are caught above.\n\t\t */\n\t\tDUK_ASSERT(!(DUK_FPCLASSIFY(x) == DUK_FP_ZERO && DUK_FPCLASSIFY(y) == DUK_FP_ZERO));\n\n\t\t/* Difference to non-strict/strict comparison is that NaNs compare\n\t\t * equal and signed zero signs matter.\n\t\t */\n\t\tif (DUK_UNLIKELY(cx == DUK_FP_NAN && cy == DUK_FP_NAN)) {\n\t\t\t/* SameValue(NaN, NaN) = true, regardless of NaN sign or extra bits */\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t}\n#endif  /* DUK_USE_PARANOID_MATH */\n}\n\nDUK_INTERNAL duk_bool_t duk_js_equals_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags) {\n\tduk_uint_t type_mask_x;\n\tduk_uint_t type_mask_y;\n\n\t/* If flags != 0 (strict or SameValue), thr can be NULL.  For loose\n\t * equals comparison it must be != NULL.\n\t */\n\tDUK_ASSERT(flags != 0 || thr != NULL);\n\n\t/*\n\t *  Same type?\n\t *\n\t *  Note: since number values have no explicit tag in the 8-byte\n\t *  representation, need the awkward if + switch.\n\t */\n\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y)) {\n\t\tif (DUK_TVAL_GET_FASTINT(tv_x) == DUK_TVAL_GET_FASTINT(tv_y)) {\n\t\t\treturn 1;\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}\n\telse\n#endif\n\tif (DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y)) {\n\t\tduk_double_t d1, d2;\n\n\t\t/* Catches both doubles and cases where only one argument is\n\t\t * a fastint so can't assume a double.\n\t\t */\n\t\td1 = DUK_TVAL_GET_NUMBER(tv_x);\n\t\td2 = DUK_TVAL_GET_NUMBER(tv_y);\n\t\tif (DUK_UNLIKELY((flags & DUK_EQUALS_FLAG_SAMEVALUE) != 0)) {\n\t\t\t/* SameValue */\n\t\t\treturn duk__js_samevalue_number(d1, d2);\n\t\t} else {\n\t\t\t/* equals and strict equals */\n\t\t\treturn duk__js_equals_number(d1, d2);\n\t\t}\n\t} else if (DUK_TVAL_GET_TAG(tv_x) == DUK_TVAL_GET_TAG(tv_y)) {\n\t\tswitch (DUK_TVAL_GET_TAG(tv_x)) {\n\t\tcase DUK_TAG_UNDEFINED:\n\t\tcase DUK_TAG_NULL: {\n\t\t\treturn 1;\n\t\t}\n\t\tcase DUK_TAG_BOOLEAN: {\n\t\t\treturn DUK_TVAL_GET_BOOLEAN(tv_x) == DUK_TVAL_GET_BOOLEAN(tv_y);\n\t\t}\n\t\tcase DUK_TAG_POINTER: {\n\t\t\treturn DUK_TVAL_GET_POINTER(tv_x) == DUK_TVAL_GET_POINTER(tv_y);\n\t\t}\n\t\tcase DUK_TAG_STRING:\n\t\tcase DUK_TAG_OBJECT: {\n\t\t\t/* Heap pointer comparison suffices for strings and objects.\n\t\t\t * Symbols compare equal if they have the same internal\n\t\t\t * representation; again heap pointer comparison suffices.\n\t\t\t */\n\t\t\treturn DUK_TVAL_GET_HEAPHDR(tv_x) == DUK_TVAL_GET_HEAPHDR(tv_y);\n\t\t}\n\t\tcase DUK_TAG_BUFFER: {\n\t\t\t/* In Duktape 2.x plain buffers mimic Uint8Array objects\n\t\t\t * so always compare by heap pointer.  In Duktape 1.x\n\t\t\t * strict comparison would compare heap pointers and\n\t\t\t * non-strict would compare contents.\n\t\t\t */\n\t\t\treturn DUK_TVAL_GET_HEAPHDR(tv_x) == DUK_TVAL_GET_HEAPHDR(tv_y);\n\t\t}\n\t\tcase DUK_TAG_LIGHTFUNC: {\n\t\t\t/* At least 'magic' has a significant impact on function\n\t\t\t * identity.\n\t\t\t */\n\t\t\tduk_small_uint_t lf_flags_x;\n\t\t\tduk_small_uint_t lf_flags_y;\n\t\t\tduk_c_function func_x;\n\t\t\tduk_c_function func_y;\n\n\t\t\tDUK_TVAL_GET_LIGHTFUNC(tv_x, func_x, lf_flags_x);\n\t\t\tDUK_TVAL_GET_LIGHTFUNC(tv_y, func_y, lf_flags_y);\n\t\t\treturn ((func_x == func_y) && (lf_flags_x == lf_flags_y)) ? 1 : 0;\n\t\t}\n#if defined(DUK_USE_FASTINT)\n\t\tcase DUK_TAG_FASTINT:\n#endif\n\t\tdefault: {\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_x));\n\t\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_y));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_x));\n\t\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_y));\n\t\t\tDUK_UNREACHABLE();\n\t\t\treturn 0;\n\t\t}\n\t\t}\n\t}\n\n\tif ((flags & (DUK_EQUALS_FLAG_STRICT | DUK_EQUALS_FLAG_SAMEVALUE)) != 0) {\n\t\treturn 0;\n\t}\n\n\tDUK_ASSERT(flags == 0);  /* non-strict equality from here on */\n\n\t/*\n\t *  Types are different; various cases for non-strict comparison\n\t *\n\t *  Since comparison is symmetric, we use a \"swap trick\" to reduce\n\t *  code size.\n\t */\n\n\ttype_mask_x = duk_get_type_mask_tval(tv_x);\n\ttype_mask_y = duk_get_type_mask_tval(tv_y);\n\n\t/* Undefined/null are considered equal (e.g. \"null == undefined\" -> true). */\n\tif ((type_mask_x & (DUK_TYPE_MASK_UNDEFINED | DUK_TYPE_MASK_NULL)) &&\n\t    (type_mask_y & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED))) {\n\t\treturn 1;\n\t}\n\n\t/* Number/string -> coerce string to number (e.g. \"'1.5' == 1.5\" -> true). */\n\tif ((type_mask_x & DUK_TYPE_MASK_NUMBER) && (type_mask_y & DUK_TYPE_MASK_STRING)) {\n\t\tif (!DUK_TVAL_STRING_IS_SYMBOL(tv_y)) {\n\t\t\tduk_double_t d1, d2;\n\t\t\td1 = DUK_TVAL_GET_NUMBER(tv_x);\n\t\t\td2 = duk_to_number_tval(thr, tv_y);\n\t\t\treturn duk__js_equals_number(d1, d2);\n\t\t}\n\t}\n\tif ((type_mask_x & DUK_TYPE_MASK_STRING) && (type_mask_y & DUK_TYPE_MASK_NUMBER)) {\n\t\tif (!DUK_TVAL_STRING_IS_SYMBOL(tv_x)) {\n\t\t\tduk_double_t d1, d2;\n\t\t\td1 = DUK_TVAL_GET_NUMBER(tv_y);\n\t\t\td2 = duk_to_number_tval(thr, tv_x);\n\t\t\treturn duk__js_equals_number(d1, d2);\n\t\t}\n\t}\n\n\t/* Boolean/any -> coerce boolean to number and try again.  If boolean is\n\t * compared to a pointer, the final comparison after coercion now always\n\t * yields false (as pointer vs. number compares to false), but this is\n\t * not special cased.\n\t *\n\t * ToNumber(bool) is +1.0 or 0.0.  Tagged boolean value is always 0 or 1.\n\t */\n\tif (type_mask_x & DUK_TYPE_MASK_BOOLEAN) {\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv_x) == 0 || DUK_TVAL_GET_BOOLEAN(tv_x) == 1);\n\t\tduk_push_uint(thr, DUK_TVAL_GET_BOOLEAN(tv_x));\n\t\tduk_push_tval(thr, tv_y);\n\t\tgoto recursive_call;\n\t}\n\tif (type_mask_y & DUK_TYPE_MASK_BOOLEAN) {\n\t\tDUK_ASSERT(DUK_TVAL_GET_BOOLEAN(tv_y) == 0 || DUK_TVAL_GET_BOOLEAN(tv_y) == 1);\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_uint(thr, DUK_TVAL_GET_BOOLEAN(tv_y));\n\t\tgoto recursive_call;\n\t}\n\n\t/* String-number-symbol/object -> coerce object to primitive (apparently without hint), then try again. */\n\tif ((type_mask_x & (DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_NUMBER)) &&\n\t    (type_mask_y & DUK_TYPE_MASK_OBJECT)) {\n\t\t/* No symbol check needed because symbols and strings are accepted. */\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NONE);  /* apparently no hint? */\n\t\tgoto recursive_call;\n\t}\n\tif ((type_mask_x & DUK_TYPE_MASK_OBJECT) &&\n\t    (type_mask_y & (DUK_TYPE_MASK_STRING | DUK_TYPE_MASK_NUMBER))) {\n\t\t/* No symbol check needed because symbols and strings are accepted. */\n\t\tduk_push_tval(thr, tv_x);\n\t\tduk_push_tval(thr, tv_y);\n\t\tduk_to_primitive(thr, -2, DUK_HINT_NONE);  /* apparently no hint? */\n\t\tgoto recursive_call;\n\t}\n\n\t/* Nothing worked -> not equal. */\n\treturn 0;\n\n recursive_call:\n\t/* Shared code path to call the helper again with arguments on stack top. */\n\t{\n\t\tduk_bool_t rc;\n\t\trc = duk_js_equals_helper(thr,\n\t\t                          DUK_GET_TVAL_NEGIDX(thr, -2),\n\t\t                          DUK_GET_TVAL_NEGIDX(thr, -1),\n\t\t                          0 /*flags:nonstrict*/);\n\t\tduk_pop_2_unsafe(thr);\n\t\treturn rc;\n\t}\n}\n\n/*\n *  Comparisons (x >= y, x > y, x <= y, x < y)\n *\n *  E5 Section 11.8.5: implement 'x < y' and then use negate and eval_left_first\n *  flags to get the rest.\n */\n\n/* XXX: this should probably just operate on the stack top, because it\n * needs to push stuff on the stack anyway...\n */\n\nDUK_INTERNAL duk_small_int_t duk_js_data_compare(const duk_uint8_t *buf1, const duk_uint8_t *buf2, duk_size_t len1, duk_size_t len2) {\n\tduk_size_t prefix_len;\n\tduk_small_int_t rc;\n\n\tprefix_len = (len1 <= len2 ? len1 : len2);\n\n\t/* duk_memcmp() is guaranteed to return zero (equal) for zero length\n\t * inputs.\n\t */\n\trc = duk_memcmp_unsafe((const void *) buf1,\n\t                       (const void *) buf2,\n\t                       (size_t) prefix_len);\n\n\tif (rc < 0) {\n\t\treturn -1;\n\t} else if (rc > 0) {\n\t\treturn 1;\n\t}\n\n\t/* prefix matches, lengths matter now */\n\tif (len1 < len2) {\n\t\t/* e.g. \"x\" < \"xx\" */\n\t\treturn -1;\n\t} else if (len1 > len2) {\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\nDUK_INTERNAL duk_small_int_t duk_js_string_compare(duk_hstring *h1, duk_hstring *h2) {\n\t/*\n\t *  String comparison (E5 Section 11.8.5, step 4), which\n\t *  needs to compare codepoint by codepoint.\n\t *\n\t *  However, UTF-8 allows us to use strcmp directly: the shared\n\t *  prefix will be encoded identically (UTF-8 has unique encoding)\n\t *  and the first differing character can be compared with a simple\n\t *  unsigned byte comparison (which strcmp does).\n\t *\n\t *  This will not work properly for non-xutf-8 strings, but this\n\t *  is not an issue for compliance.\n\t */\n\n\tDUK_ASSERT(h1 != NULL);\n\tDUK_ASSERT(h2 != NULL);\n\n\treturn duk_js_data_compare((const duk_uint8_t *) DUK_HSTRING_GET_DATA(h1),\n\t                           (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h2),\n\t                           (duk_size_t) DUK_HSTRING_GET_BYTELEN(h1),\n\t                           (duk_size_t) DUK_HSTRING_GET_BYTELEN(h2));\n}\n\n#if 0  /* unused */\nDUK_INTERNAL duk_small_int_t duk_js_buffer_compare(duk_heap *heap, duk_hbuffer *h1, duk_hbuffer *h2) {\n\t/* Similar to String comparison. */\n\n\tDUK_ASSERT(h1 != NULL);\n\tDUK_ASSERT(h2 != NULL);\n\tDUK_UNREF(heap);\n\n\treturn duk_js_data_compare((const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(heap, h1),\n\t                           (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(heap, h2),\n\t                           (duk_size_t) DUK_HBUFFER_GET_SIZE(h1),\n\t                           (duk_size_t) DUK_HBUFFER_GET_SIZE(h2));\n}\n#endif\n\n#if defined(DUK_USE_FASTINT)\nDUK_LOCAL duk_bool_t duk__compare_fastint(duk_bool_t retval, duk_int64_t v1, duk_int64_t v2) {\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\tif (v1 < v2) {\n\t\treturn retval ^ 1;\n\t} else {\n\t\treturn retval;\n\t}\n}\n#endif\n\n#if defined(DUK_USE_PARANOID_MATH)\nDUK_LOCAL duk_bool_t duk__compare_number(duk_bool_t retval, duk_double_t d1, duk_double_t d2) {\n\tduk_small_int_t c1, s1, c2, s2;\n\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\tc1 = (duk_small_int_t) DUK_FPCLASSIFY(d1);\n\ts1 = (duk_small_int_t) DUK_SIGNBIT(d1);\n\tc2 = (duk_small_int_t) DUK_FPCLASSIFY(d2);\n\ts2 = (duk_small_int_t) DUK_SIGNBIT(d2);\n\n\tif (c1 == DUK_FP_NAN || c2 == DUK_FP_NAN) {\n\t\treturn 0;  /* Always false, regardless of negation. */\n\t}\n\n\tif (c1 == DUK_FP_ZERO && c2 == DUK_FP_ZERO) {\n\t\t/* For all combinations: +0 < +0, +0 < -0, -0 < +0, -0 < -0,\n\t\t * steps e, f, and g.\n\t\t */\n\t\treturn retval;  /* false */\n\t}\n\n\tif (d1 == d2) {\n\t\treturn retval;  /* false */\n\t}\n\n\tif (c1 == DUK_FP_INFINITE && s1 == 0) {\n\t\t/* x == +Infinity */\n\t\treturn retval;  /* false */\n\t}\n\n\tif (c2 == DUK_FP_INFINITE && s2 == 0) {\n\t\t/* y == +Infinity */\n\t\treturn retval ^ 1;  /* true */\n\t}\n\n\tif (c2 == DUK_FP_INFINITE && s2 != 0) {\n\t\t/* y == -Infinity */\n\t\treturn retval;  /* false */\n\t}\n\n\tif (c1 == DUK_FP_INFINITE && s1 != 0) {\n\t\t/* x == -Infinity */\n\t\treturn retval ^ 1;  /* true */\n\t}\n\n\tif (d1 < d2) {\n\t\treturn retval ^ 1;  /* true */\n\t}\n\n\treturn retval;  /* false */\n}\n#else  /* DUK_USE_PARANOID_MATH */\nDUK_LOCAL duk_bool_t duk__compare_number(duk_bool_t retval, duk_double_t d1, duk_double_t d2) {\n\t/* This comparison tree relies doesn't match the exact steps in\n\t * E5 Section 11.8.5 but should produce the same results.  The\n\t * steps rely on exact IEEE semantics for NaNs, etc.\n\t */\n\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\tif (d1 < d2) {\n\t\t/* In no case should both (d1 < d2) and (d2 < d1) be true.\n\t\t * It's possible that neither is true though, and that's\n\t\t * handled below.\n\t\t */\n\t\tDUK_ASSERT(!(d2 < d1));\n\n\t\t/* - d1 < d2, both d1/d2 are normals (not Infinity, not NaN)\n\t\t * - d2 is +Infinity, d1 != +Infinity and NaN\n\t\t * - d1 is -Infinity, d2 != -Infinity and NaN\n\t\t */\n\t\treturn retval ^ 1;\n\t} else {\n\t\tif (d2 < d1) {\n\t\t\t/* - !(d1 < d2), both d1/d2 are normals (not Infinity, not NaN)\n\t\t\t * - d1 is +Infinity, d2 != +Infinity and NaN\n\t\t\t * - d2 is -Infinity, d1 != -Infinity and NaN\n\t\t\t */\n\t\t\treturn retval;\n\t\t} else {\n\t\t\t/* - d1 and/or d2 is NaN\n\t\t\t * - d1 and d2 are both +/- 0\n\t\t\t * - d1 == d2 (including infinities)\n\t\t\t */\n\t\t\tif (duk_double_is_nan(d1) || duk_double_is_nan(d2)) {\n\t\t\t\t/* Note: undefined from Section 11.8.5 always\n\t\t\t\t * results in false return (see e.g. Section\n\t\t\t\t * 11.8.3) - hence special treatment here.\n\t\t\t\t */\n\t\t\t\treturn 0;  /* zero regardless of negation */\n\t\t\t} else {\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\t}\n}\n#endif  /* DUK_USE_PARANOID_MATH */\n\nDUK_INTERNAL duk_bool_t duk_js_compare_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_small_uint_t flags) {\n\tduk_double_t d1, d2;\n\tduk_small_int_t rc;\n\tduk_bool_t retval;\n\n\tDUK_ASSERT(DUK_COMPARE_FLAG_NEGATE == 1);  /* Rely on this flag being lowest. */\n\tretval = flags & DUK_COMPARE_FLAG_NEGATE;\n\tDUK_ASSERT(retval == 0 || retval == 1);\n\n\t/* Fast path for fastints */\n#if defined(DUK_USE_FASTINT)\n\tif (DUK_LIKELY(DUK_TVAL_IS_FASTINT(tv_x) && DUK_TVAL_IS_FASTINT(tv_y))) {\n\t\treturn duk__compare_fastint(retval,\n\t\t                            DUK_TVAL_GET_FASTINT(tv_x),\n\t\t                            DUK_TVAL_GET_FASTINT(tv_y));\n\t}\n#endif  /* DUK_USE_FASTINT */\n\n\t/* Fast path for numbers (one of which may be a fastint) */\n#if !defined(DUK_USE_PREFER_SIZE)\n\tif (DUK_LIKELY(DUK_TVAL_IS_NUMBER(tv_x) && DUK_TVAL_IS_NUMBER(tv_y))) {\n\t\treturn duk__compare_number(retval,\n\t\t                           DUK_TVAL_GET_NUMBER(tv_x),\n\t\t                           DUK_TVAL_GET_NUMBER(tv_y));\n\t}\n#endif\n\n\t/* Slow path */\n\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\n\tif (flags & DUK_COMPARE_FLAG_EVAL_LEFT_FIRST) {\n\t\tduk_to_primitive(thr, -2, DUK_HINT_NUMBER);\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);\n\t} else {\n\t\tduk_to_primitive(thr, -1, DUK_HINT_NUMBER);\n\t\tduk_to_primitive(thr, -2, DUK_HINT_NUMBER);\n\t}\n\n\t/* Note: reuse variables */\n\ttv_x = DUK_GET_TVAL_NEGIDX(thr, -2);\n\ttv_y = DUK_GET_TVAL_NEGIDX(thr, -1);\n\n\tif (DUK_TVAL_IS_STRING(tv_x) && DUK_TVAL_IS_STRING(tv_y)) {\n\t\tduk_hstring *h1 = DUK_TVAL_GET_STRING(tv_x);\n\t\tduk_hstring *h2 = DUK_TVAL_GET_STRING(tv_y);\n\t\tDUK_ASSERT(h1 != NULL);\n\t\tDUK_ASSERT(h2 != NULL);\n\n\t\tif (DUK_LIKELY(!DUK_HSTRING_HAS_SYMBOL(h1) && !DUK_HSTRING_HAS_SYMBOL(h2))) {\n\t\t\trc = duk_js_string_compare(h1, h2);\n\t\t\tduk_pop_2_unsafe(thr);\n\t\t\tif (rc < 0) {\n\t\t\t\treturn retval ^ 1;\n\t\t\t} else {\n\t\t\t\treturn retval;\n\t\t\t}\n\t\t}\n\n\t\t/* One or both are Symbols: fall through to handle in the\n\t\t * generic path.  Concretely, ToNumber() will fail.\n\t\t */\n\t}\n\n\t/* Ordering should not matter (E5 Section 11.8.5, step 3.a). */\n#if 0\n\tif (flags & DUK_COMPARE_FLAG_EVAL_LEFT_FIRST) {\n\t\td1 = duk_to_number_m2(thr);\n\t\td2 = duk_to_number_m1(thr);\n\t} else {\n\t\td2 = duk_to_number_m1(thr);\n\t\td1 = duk_to_number_m2(thr);\n\t}\n#endif\n\td1 = duk_to_number_m2(thr);\n\td2 = duk_to_number_m1(thr);\n\n\t/* We want to duk_pop_2_unsafe(thr); because the values are numbers\n\t * no decref check is needed.\n\t */\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk_pop_2_nodecref_unsafe(thr);\n#else\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk_get_tval(thr, -2)));\n\tDUK_ASSERT(!DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk_get_tval(thr, -1)));\n\tDUK_ASSERT(duk_get_top(thr) >= 2);\n\tthr->valstack_top -= 2;\n\ttv_x = thr->valstack_top;\n\ttv_y = tv_x + 1;\n\tDUK_TVAL_SET_UNDEFINED(tv_x);  /* Value stack policy */\n\tDUK_TVAL_SET_UNDEFINED(tv_y);\n#endif\n\n\treturn duk__compare_number(retval, d1, d2);\n}\n\n/*\n *  instanceof\n */\n\n/*\n *  ES2015 Section 7.3.19 describes the OrdinaryHasInstance() algorithm\n *  which covers both bound and non-bound functions; in effect the algorithm\n *  includes E5 Sections 11.8.6, 15.3.5.3, and 15.3.4.5.3.\n *\n *  ES2015 Section 12.9.4 describes the instanceof operator which first\n *  checks @@hasInstance well-known symbol and falls back to\n *  OrdinaryHasInstance().\n *\n *  Limited Proxy support: don't support 'getPrototypeOf' trap but\n *  continue lookup in Proxy target if the value is a Proxy.\n */\n\nDUK_LOCAL duk_bool_t duk__js_instanceof_helper(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y, duk_bool_t skip_sym_check) {\n\tduk_hobject *func;\n\tduk_hobject *val;\n\tduk_hobject *proto;\n\tduk_tval *tv;\n\tduk_bool_t skip_first;\n\tduk_uint_t sanity;\n\n\t/*\n\t *  Get the values onto the stack first.  It would be possible to cover\n\t *  some normal cases without resorting to the value stack.\n\t *\n\t *  The right hand side could be a light function (as they generally\n\t *  behave like objects).  Light functions never have a 'prototype'\n\t *  property so E5.1 Section 15.3.5.3 step 3 always throws a TypeError.\n\t *  Using duk_require_hobject() is thus correct (except for error msg).\n\t */\n\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\tfunc = duk_require_hobject(thr, -1);\n\tDUK_ASSERT(func != NULL);\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\n\t/*\n\t *  @@hasInstance check, ES2015 Section 12.9.4, Steps 2-4.\n\t */\n\tif (!skip_sym_check) {\n\t\tif (duk_get_method_stridx(thr, -1, DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE)) {\n\t\t\t/* [ ... lhs rhs func ] */\n\t\t\tduk_insert(thr, -3);    /* -> [ ... func lhs rhs ] */\n\t\t\tduk_swap_top(thr, -2);  /* -> [ ... func rhs(this) lhs ] */\n\t\t\tduk_call_method(thr, 1);\n\t\t\treturn duk_to_boolean_top_pop(thr);\n\t\t}\n\t}\n#else\n\tDUK_UNREF(skip_sym_check);\n#endif\n\n\t/*\n\t *  For bound objects, [[HasInstance]] just calls the target function\n\t *  [[HasInstance]].  If that is again a bound object, repeat until\n\t *  we find a non-bound Function object.\n\t *\n\t *  The bound function chain is now \"collapsed\" so there can be only\n\t *  one bound function in the chain.\n\t */\n\n\tif (!DUK_HOBJECT_IS_CALLABLE(func)) {\n\t\t/*\n\t\t *  Note: of native ECMAScript objects, only Function instances\n\t\t *  have a [[HasInstance]] internal property.  Custom objects might\n\t\t *  also have it, but not in current implementation.\n\t\t *\n\t\t *  XXX: add a separate flag, DUK_HOBJECT_FLAG_ALLOW_INSTANCEOF?\n\t\t */\n\t\tgoto error_invalid_rval;\n\t}\n\n\tif (DUK_HOBJECT_HAS_BOUNDFUNC(func)) {\n\t\tduk_push_tval(thr, &((duk_hboundfunc *) (void *) func)->target);\n\t\tduk_replace(thr, -2);\n\t\tfunc = duk_require_hobject(thr, -1);  /* lightfunc throws */\n\n\t\t/* Rely on Function.prototype.bind() never creating bound\n\t\t * functions whose target is not proper.\n\t\t */\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(func));\n\t}\n\n\t/*\n\t *  'func' is now a non-bound object which supports [[HasInstance]]\n\t *  (which here just means DUK_HOBJECT_FLAG_CALLABLE).  Move on\n\t *  to execute E5 Section 15.3.5.3.\n\t */\n\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));\n\tDUK_ASSERT(DUK_HOBJECT_IS_CALLABLE(func));\n\n\t/* [ ... lval rval(func) ] */\n\n\t/* For lightfuncs, buffers, and pointers start the comparison directly\n\t * from the virtual prototype object.\n\t */\n\tskip_first = 0;\n\ttv = DUK_GET_TVAL_NEGIDX(thr, -2);\n\tswitch (DUK_TVAL_GET_TAG(tv)) {\n\tcase DUK_TAG_LIGHTFUNC:\n\t\tval = thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE];\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tcase DUK_TAG_BUFFER:\n\t\tval = thr->builtins[DUK_BIDX_UINT8ARRAY_PROTOTYPE];\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tcase DUK_TAG_POINTER:\n\t\tval = thr->builtins[DUK_BIDX_POINTER_PROTOTYPE];\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tcase DUK_TAG_OBJECT:\n\t\tskip_first = 1;  /* Ignore object itself on first round. */\n\t\tval = DUK_TVAL_GET_OBJECT(tv);\n\t\tDUK_ASSERT(val != NULL);\n\t\tbreak;\n\tdefault:\n\t\tgoto pop2_and_false;\n\t}\n\tDUK_ASSERT(val != NULL);  /* Loop doesn't actually rely on this. */\n\n\t/* Look up .prototype of rval.  Leave it on the value stack in case it\n\t * has been virtualized (e.g. getter, Proxy trap).\n\t */\n\tduk_get_prop_stridx_short(thr, -1, DUK_STRIDX_PROTOTYPE);  /* -> [ ... lval rval rval.prototype ] */\n#if defined(DUK_USE_VERBOSE_ERRORS)\n\tproto = duk_get_hobject(thr, -1);\n\tif (proto == NULL) {\n\t\tgoto error_invalid_rval_noproto;\n\t}\n#else\n\tproto = duk_require_hobject(thr, -1);\n#endif\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\tdo {\n\t\t/*\n\t\t *  Note: prototype chain is followed BEFORE first comparison.  This\n\t\t *  means that the instanceof lval is never itself compared to the\n\t\t *  rval.prototype property.  This is apparently intentional, see E5\n\t\t *  Section 15.3.5.3, step 4.a.\n\t\t *\n\t\t *  Also note:\n\t\t *\n\t\t *      js> (function() {}) instanceof Function\n\t\t *      true\n\t\t *      js> Function instanceof Function\n\t\t *      true\n\t\t *\n\t\t *  For the latter, h_proto will be Function.prototype, which is the\n\t\t *  built-in Function prototype.  Because Function.[[Prototype]] is\n\t\t *  also the built-in Function prototype, the result is true.\n\t\t */\n\n\t\tif (!val) {\n\t\t\tgoto pop3_and_false;\n\t\t}\n\n\t\tDUK_ASSERT(val != NULL);\n#if defined(DUK_USE_ES6_PROXY)\n\t\tval = duk_hobject_resolve_proxy_target(val);\n#endif\n\n\t\tif (skip_first) {\n\t\t\tskip_first = 0;\n\t\t} else if (val == proto) {\n\t\t\tgoto pop3_and_true;\n\t\t}\n\n\t\tDUK_ASSERT(val != NULL);\n\t\tval = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, val);\n\t} while (--sanity > 0);\n\n\tif (DUK_UNLIKELY(sanity == 0)) {\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\tDUK_WO_NORETURN(return 0;);\n\t}\n\tDUK_UNREACHABLE();\n\n pop2_and_false:\n\tduk_pop_2_unsafe(thr);\n\treturn 0;\n\n pop3_and_false:\n\tduk_pop_3_unsafe(thr);\n\treturn 0;\n\n pop3_and_true:\n\tduk_pop_3_unsafe(thr);\n\treturn 1;\n\n error_invalid_rval:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_INSTANCEOF_RVAL);\n\tDUK_WO_NORETURN(return 0;);\n\n#if defined(DUK_USE_VERBOSE_ERRORS)\n error_invalid_rval_noproto:\n\tDUK_ERROR_TYPE(thr, DUK_STR_INVALID_INSTANCEOF_RVAL_NOPROTO);\n\tDUK_WO_NORETURN(return 0;);\n#endif\n}\n\n#if defined(DUK_USE_SYMBOL_BUILTIN)\nDUK_INTERNAL duk_bool_t duk_js_instanceof_ordinary(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {\n\treturn duk__js_instanceof_helper(thr, tv_x, tv_y, 1 /*skip_sym_check*/);\n}\n#endif\n\nDUK_INTERNAL duk_bool_t duk_js_instanceof(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {\n\treturn duk__js_instanceof_helper(thr, tv_x, tv_y, 0 /*skip_sym_check*/);\n}\n\n/*\n *  in\n */\n\n/*\n *  E5 Sections 11.8.7, 8.12.6.\n *\n *  Basically just a property existence check using [[HasProperty]].\n */\n\nDUK_INTERNAL duk_bool_t duk_js_in(duk_hthread *thr, duk_tval *tv_x, duk_tval *tv_y) {\n\tduk_bool_t retval;\n\n\t/*\n\t *  Get the values onto the stack first.  It would be possible to cover\n\t *  some normal cases without resorting to the value stack (e.g. if\n\t *  lval is already a string).\n\t */\n\n\t/* XXX: The ES5/5.1/6 specifications require that the key in 'key in obj'\n\t * must be string coerced before the internal HasProperty() algorithm is\n\t * invoked.  A fast path skipping coercion could be safely implemented for\n\t * numbers (as number-to-string coercion has no side effects).  For ES2015\n\t * proxy behavior, the trap 'key' argument must be in a string coerced\n\t * form (which is a shame).\n\t */\n\n\t/* TypeError if rval is not an object or object like (e.g. lightfunc\n\t * or plain buffer).\n\t */\n\tduk_push_tval(thr, tv_x);\n\tduk_push_tval(thr, tv_y);\n\tduk_require_type_mask(thr, -1, DUK_TYPE_MASK_OBJECT | DUK_TYPE_MASK_LIGHTFUNC | DUK_TYPE_MASK_BUFFER);\n\n\t(void) duk_to_property_key_hstring(thr, -2);\n\n\tretval = duk_hobject_hasprop(thr,\n\t                             DUK_GET_TVAL_NEGIDX(thr, -1),\n\t                             DUK_GET_TVAL_NEGIDX(thr, -2));\n\n\tduk_pop_2_unsafe(thr);\n\treturn retval;\n}\n\n/*\n *  typeof\n *\n *  E5 Section 11.4.3.\n *\n *  Very straightforward.  The only question is what to return for our\n *  non-standard tag / object types.\n *\n *  There is an unfortunate string constant define naming problem with\n *  typeof return values for e.g. \"Object\" and \"object\"; careful with\n *  the built-in string defines.  The LC_XXX defines are used for the\n *  lowercase variants now.\n */\n\nDUK_INTERNAL duk_small_uint_t duk_js_typeof_stridx(duk_tval *tv_x) {\n\tduk_small_uint_t stridx = 0;\n\n\tswitch (DUK_TVAL_GET_TAG(tv_x)) {\n\tcase DUK_TAG_UNDEFINED: {\n\t\tstridx = DUK_STRIDX_LC_UNDEFINED;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_NULL: {\n\t\t/* Note: not a typo, \"object\" is returned for a null value. */\n\t\tstridx = DUK_STRIDX_LC_OBJECT;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BOOLEAN: {\n\t\tstridx = DUK_STRIDX_LC_BOOLEAN;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_POINTER: {\n\t\t/* Implementation specific. */\n\t\tstridx = DUK_STRIDX_LC_POINTER;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_STRING: {\n\t\tduk_hstring *str;\n\n\t\t/* All internal keys are identified as Symbols. */\n\t\tstr = DUK_TVAL_GET_STRING(tv_x);\n\t\tDUK_ASSERT(str != NULL);\n\t\tif (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(str))) {\n\t\t\tstridx = DUK_STRIDX_LC_SYMBOL;\n\t\t} else {\n\t\t\tstridx = DUK_STRIDX_LC_STRING;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_OBJECT: {\n\t\tduk_hobject *obj = DUK_TVAL_GET_OBJECT(tv_x);\n\t\tDUK_ASSERT(obj != NULL);\n\t\tif (DUK_HOBJECT_IS_CALLABLE(obj)) {\n\t\t\tstridx = DUK_STRIDX_LC_FUNCTION;\n\t\t} else {\n\t\t\tstridx = DUK_STRIDX_LC_OBJECT;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_TAG_BUFFER: {\n\t\t/* Implementation specific.  In Duktape 1.x this would be\n\t\t * 'buffer', in Duktape 2.x changed to 'object' because plain\n\t\t * buffers now mimic Uint8Array objects.\n\t\t */\n\t\tstridx = DUK_STRIDX_LC_OBJECT;\n\t\tbreak;\n\t}\n\tcase DUK_TAG_LIGHTFUNC: {\n\t\tstridx = DUK_STRIDX_LC_FUNCTION;\n\t\tbreak;\n\t}\n#if defined(DUK_USE_FASTINT)\n\tcase DUK_TAG_FASTINT:\n#endif\n\tdefault: {\n\t\t/* number */\n\t\tDUK_ASSERT(!DUK_TVAL_IS_UNUSED(tv_x));\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv_x));\n\t\tstridx = DUK_STRIDX_LC_NUMBER;\n\t\tbreak;\n\t}\n\t}\n\n\tDUK_ASSERT_STRIDX_VALID(stridx);\n\treturn stridx;\n}\n\n/*\n *  Array index and length\n *\n *  Array index: E5 Section 15.4\n *  Array length: E5 Section 15.4.5.1 steps 3.c - 3.d (array length write)\n */\n\n/* Compure array index from string context, or return a \"not array index\"\n * indicator.\n */\nDUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_string(const duk_uint8_t *str, duk_uint32_t blen) {\n\tduk_uarridx_t res;\n\n\t/* Only strings with byte length 1-10 can be 32-bit array indices.\n\t * Leading zeroes (except '0' alone), plus/minus signs are not allowed.\n\t * We could do a lot of prechecks here, but since most strings won't\n\t * start with any digits, it's simpler to just parse the number and\n\t * fail quickly.\n\t */\n\n\tres = 0;\n\tif (blen == 0) {\n\t\tgoto parse_fail;\n\t}\n\tdo {\n\t\tduk_uarridx_t dig;\n\t\tdig = (duk_uarridx_t) (*str++) - DUK_ASC_0;\n\n\t\tif (dig <= 9U) {\n\t\t\t/* Careful overflow handling.  When multiplying by 10:\n\t\t\t * - 0x19999998 x 10 = 0xfffffff0: no overflow, and adding\n\t\t\t *   0...9 is safe.\n\t\t\t * - 0x19999999 x 10 = 0xfffffffa: no overflow, adding\n\t\t\t *   0...5 is safe, 6...9 overflows.\n\t\t\t * - 0x1999999a x 10 = 0x100000004: always overflow.\n\t\t\t */\n\t\t\tif (DUK_UNLIKELY(res >= 0x19999999UL)) {\n\t\t\t\tif (res >= 0x1999999aUL) {\n\t\t\t\t\t/* Always overflow. */\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(res == 0x19999999UL);\n\t\t\t\tif (dig >= 6U) {\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t\tres = 0xfffffffaUL + dig;\n\t\t\t\tDUK_ASSERT(res >= 0xfffffffaUL);\n\t\t\t\tDUK_ASSERT_DISABLE(res <= 0xffffffffUL);  /* range */\n\t\t\t} else {\n\t\t\t\tres = res * 10U + dig;\n\t\t\t\tif (DUK_UNLIKELY(res == 0)) {\n\t\t\t\t\t/* If 'res' is 0, previous 'res' must\n\t\t\t\t\t * have been 0 and we scanned in a zero.\n\t\t\t\t\t * This is only allowed if blen == 1,\n\t\t\t\t\t * i.e. the exact string '0'.\n\t\t\t\t\t */\n\t\t\t\t\tif (blen == (duk_uint32_t) 1) {\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\t}\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t/* Because 'dig' is unsigned, catches both values\n\t\t\t * above '9' and below '0'.\n\t\t\t */\n\t\t\tgoto parse_fail;\n\t\t}\n\t} while (--blen > 0);\n\n\treturn res;\n\n parse_fail:\n\treturn DUK_HSTRING_NO_ARRAY_INDEX;\n}\n\n#if !defined(DUK_USE_HSTRING_ARRIDX)\n/* Get array index for a string which is known to be an array index.  This helper\n * is needed when duk_hstring doesn't concretely store the array index, but strings\n * are flagged as array indices at intern time.\n */\nDUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_hstring_fast_known(duk_hstring *h) {\n\tconst duk_uint8_t *p;\n\tduk_uarridx_t res;\n\tduk_uint8_t t;\n\n\tDUK_ASSERT(h != NULL);\n\tDUK_ASSERT(DUK_HSTRING_HAS_ARRIDX(h));\n\n\tp = DUK_HSTRING_GET_DATA(h);\n\tres = 0;\n\tfor (;;) {\n\t\tt = *p++;\n\t\tif (DUK_UNLIKELY(t == 0)) {\n\t\t\t/* Scanning to NUL is always safe for interned strings. */\n\t\t\tbreak;\n\t\t}\n\t\tDUK_ASSERT(t >= (duk_uint8_t) DUK_ASC_0 && t <= (duk_uint8_t) DUK_ASC_9);\n\t\tres = res * 10U + (duk_uarridx_t) t - (duk_uarridx_t) DUK_ASC_0;\n\t}\n\treturn res;\n}\n\nDUK_INTERNAL duk_uarridx_t duk_js_to_arrayindex_hstring_fast(duk_hstring *h) {\n\tDUK_ASSERT(h != NULL);\n\tif (!DUK_HSTRING_HAS_ARRIDX(h)) {\n\t\treturn DUK_HSTRING_NO_ARRAY_INDEX;\n\t}\n\treturn duk_js_to_arrayindex_hstring_fast_known(h);\n}\n#endif  /* DUK_USE_HSTRING_ARRIDX */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_js_var.c",
    "content": "/*\n *  Identifier access and function closure handling.\n *\n *  Provides the primitives for slow path identifier accesses: GETVAR,\n *  PUTVAR, DELVAR, etc.  The fast path, direct register accesses, should\n *  be used for most identifier accesses.  Consequently, these slow path\n *  primitives should be optimized for maximum compactness.\n *\n *  ECMAScript environment records (declarative and object) are represented\n *  as internal objects with control keys.  Environment records have a\n *  parent record (\"outer environment reference\") which is represented by\n *  the implicit prototype for technical reasons (in other words, it is a\n *  convenient field).  The prototype chain is not followed in the ordinary\n *  sense for variable lookups.\n *\n *  See identifier-handling.rst for more details on the identifier algorithms\n *  and the internal representation.  See function-objects.rst for details on\n *  what function templates and instances are expected to look like.\n *\n *  Care must be taken to avoid duk_tval pointer invalidation caused by\n *  e.g. value stack or object resizing.\n *\n *  TODO: properties for function instances could be initialized much more\n *  efficiently by creating a property allocation for a certain size and\n *  filling in keys and values directly (and INCREFing both with \"bulk incref\"\n *  primitives.\n *\n *  XXX: duk_hobject_getprop() and duk_hobject_putprop() calls are a bit\n *  awkward (especially because they follow the prototype chain); rework\n *  if \"raw\" own property helpers are added.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Local result type for duk__get_identifier_reference() lookup.\n */\n\ntypedef struct {\n\tduk_hobject *env;\n\tduk_hobject *holder;      /* for object-bound identifiers */\n\tduk_tval *value;          /* for register-bound and declarative env identifiers */\n\tduk_uint_t attrs;         /* property attributes for identifier (relevant if value != NULL) */\n\tduk_bool_t has_this;      /* for object-bound identifiers: provide 'this' binding */\n} duk__id_lookup_result;\n\n/*\n *  Create a new function object based on a \"template function\" which contains\n *  compiled bytecode, constants, etc, but lacks a lexical environment.\n *\n *  ECMAScript requires that each created closure is a separate object, with\n *  its own set of editable properties.  However, structured property values\n *  (such as the formal arguments list and the variable map) are shared.\n *  Also the bytecode, constants, and inner functions are shared.\n *\n *  See E5 Section 13.2 for detailed requirements on the function objects;\n *  there are no similar requirements for function \"templates\" which are an\n *  implementation dependent internal feature.  Also see function-objects.rst\n *  for a discussion on the function instance properties provided by this\n *  implementation.\n *\n *  Notes:\n *\n *   * Order of internal properties should match frequency of use, since the\n *     properties will be linearly scanned on lookup (functions usually don't\n *     have enough properties to warrant a hash part).\n *\n *   * The created closure is independent of its template; they do share the\n *     same 'data' buffer object, but the template object itself can be freed\n *     even if the closure object remains reachable.\n */\n\nDUK_LOCAL void duk__inc_data_inner_refcounts(duk_hthread *thr, duk_hcompfunc *f) {\n\tduk_tval *tv, *tv_end;\n\tduk_hobject **funcs, **funcs_end;\n\n\tDUK_UNREF(thr);\n\n\t/* If function creation fails due to out-of-memory, the data buffer\n\t * pointer may be NULL in some cases.  That's actually possible for\n\t * GC code, but shouldn't be possible here because the incomplete\n\t * function will be unwound from the value stack and never instantiated.\n\t */\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, f) != NULL);\n\n\ttv = DUK_HCOMPFUNC_GET_CONSTS_BASE(thr->heap, f);\n\ttv_end = DUK_HCOMPFUNC_GET_CONSTS_END(thr->heap, f);\n\twhile (tv < tv_end) {\n\t\tDUK_TVAL_INCREF(thr, tv);\n\t\ttv++;\n\t}\n\n\tfuncs = DUK_HCOMPFUNC_GET_FUNCS_BASE(thr->heap, f);\n\tfuncs_end = DUK_HCOMPFUNC_GET_FUNCS_END(thr->heap, f);\n\twhile (funcs < funcs_end) {\n\t\tDUK_HEAPHDR_INCREF(thr, (duk_heaphdr *) *funcs);\n\t\tfuncs++;\n\t}\n}\n\n/* Push a new closure on the stack.\n *\n * Note: if fun_temp has NEWENV, i.e. a new lexical and variable declaration\n * is created when the function is called, only outer_lex_env matters\n * (outer_var_env is ignored and may or may not be same as outer_lex_env).\n */\n\nDUK_LOCAL const duk_uint16_t duk__closure_copy_proplist[] = {\n\t/* order: most frequent to least frequent */\n\tDUK_STRIDX_INT_VARMAP,\n\tDUK_STRIDX_INT_FORMALS,\n#if defined(DUK_USE_PC2LINE)\n\tDUK_STRIDX_INT_PC2LINE,\n#endif\n#if defined(DUK_USE_FUNC_FILENAME_PROPERTY)\n\tDUK_STRIDX_FILE_NAME,\n#endif\n#if defined(DUK_USE_NONSTD_FUNC_SOURCE_PROPERTY)\n\tDUK_STRIDX_INT_SOURCE\n#endif\n};\n\nDUK_INTERNAL\nvoid duk_js_push_closure(duk_hthread *thr,\n                         duk_hcompfunc *fun_temp,\n                         duk_hobject *outer_var_env,\n                         duk_hobject *outer_lex_env,\n                         duk_bool_t add_auto_proto) {\n\tduk_hcompfunc *fun_clos;\n\tduk_harray *formals;\n\tduk_small_uint_t i;\n\tduk_uint_t len_value;\n\n\tDUK_ASSERT(fun_temp != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_temp) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_temp) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_temp) != NULL);\n\tDUK_ASSERT(outer_var_env != NULL);\n\tDUK_ASSERT(outer_lex_env != NULL);\n\tDUK_UNREF(len_value);\n\n\tDUK_STATS_INC(thr->heap, stats_envrec_pushclosure);\n\n\tfun_clos = duk_push_hcompfunc(thr);\n\tDUK_ASSERT(fun_clos != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) fun_clos) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\n\tduk_push_hobject(thr, &fun_temp->obj);  /* -> [ ... closure template ] */\n\n\tDUK_ASSERT(DUK_HOBJECT_IS_COMPFUNC((duk_hobject *) fun_clos));\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_clos) == NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_clos) == NULL);\n\n\tDUK_HCOMPFUNC_SET_DATA(thr->heap, fun_clos, DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_temp));\n\tDUK_HCOMPFUNC_SET_FUNCS(thr->heap, fun_clos, DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_temp));\n\tDUK_HCOMPFUNC_SET_BYTECODE(thr->heap, fun_clos, DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_temp));\n\n\t/* Note: all references inside 'data' need to get their refcounts\n\t * upped too.  This is the case because refcounts are decreased\n\t * through every function referencing 'data' independently.\n\t */\n\n\tDUK_HBUFFER_INCREF(thr, DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos));\n\tduk__inc_data_inner_refcounts(thr, fun_temp);\n\n\tfun_clos->nregs = fun_temp->nregs;\n\tfun_clos->nargs = fun_temp->nargs;\n#if defined(DUK_USE_DEBUGGER_SUPPORT)\n\tfun_clos->start_line = fun_temp->start_line;\n\tfun_clos->end_line = fun_temp->end_line;\n#endif\n\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_DATA(thr->heap, fun_clos) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_FUNCS(thr->heap, fun_clos) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_BYTECODE(thr->heap, fun_clos) != NULL);\n\n\t/* XXX: Could also copy from template, but there's no way to have any\n\t * other value here now (used code has no access to the template).\n\t * Prototype is set by duk_push_hcompfunc().\n\t */\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, &fun_clos->obj) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#if 0\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, &fun_clos->obj, thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n#endif\n\n\t/* Copy duk_hobject flags as is from the template using a mask.\n\t * Leave out duk_heaphdr owned flags just in case (e.g. if there's\n\t * some GC flag or similar).  Some flags can then be adjusted\n\t * separately if necessary.\n\t */\n\n\t/* DUK_HEAPHDR_SET_FLAGS() masks changes to non-duk_heaphdr flags only. */\n\tDUK_HEAPHDR_SET_FLAGS((duk_heaphdr *) fun_clos, DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) fun_temp));\n\tDUK_DD(DUK_DDPRINT(\"fun_temp heaphdr flags: 0x%08lx, fun_clos heaphdr flags: 0x%08lx\",\n\t                   (unsigned long) DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) fun_temp),\n\t                   (unsigned long) DUK_HEAPHDR_GET_FLAGS_RAW((duk_heaphdr *) fun_clos)));\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(&fun_clos->obj));\n\tDUK_ASSERT(DUK_HOBJECT_HAS_COMPFUNC(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_NATFUNC(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_IS_THREAD(&fun_clos->obj));\n\t/* DUK_HOBJECT_FLAG_ARRAY_PART: don't care */\n\t/* DUK_HOBJECT_FLAG_NEWENV: handled below */\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_STRINGOBJ(&fun_clos->obj));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARGUMENTS(&fun_clos->obj));\n\n\tif (!DUK_HOBJECT_HAS_CONSTRUCTABLE(&fun_clos->obj)) {\n\t\t/* If the template is not constructable don't add an automatic\n\t\t * .prototype property.  This is the case for e.g. ES2015 object\n\t\t * literal getters/setters and method definitions.\n\t\t */\n\t\tadd_auto_proto = 0;\n\t}\n\n\t/*\n\t *  Setup environment record properties based on the template and\n\t *  its flags.\n\t *\n\t *  If DUK_HOBJECT_HAS_NEWENV(fun_temp) is true, the environment\n\t *  records represent identifiers \"outside\" the function; the\n\t *  \"inner\" environment records are created on demand.  Otherwise,\n\t *  the environment records are those that will be directly used\n\t *  (e.g. for declarations).\n\t *\n\t *  _Lexenv is always set; _Varenv defaults to _Lexenv if missing,\n\t *  so _Varenv is only set if _Lexenv != _Varenv.\n\t *\n\t *  This is relatively complex, see doc/identifier-handling.rst.\n\t */\n\n\tif (DUK_HOBJECT_HAS_NEWENV(&fun_clos->obj)) {\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\t\tif (DUK_HOBJECT_HAS_NAMEBINDING(&fun_clos->obj)) {\n\t\t\tduk_hobject *proto;\n\t\t\tduk_hdecenv *new_env;\n\n\t\t\t/*\n\t\t\t *  Named function expression, name needs to be bound\n\t\t\t *  in an intermediate environment record.  The \"outer\"\n\t\t\t *  lexical/variable environment will thus be:\n\t\t\t *\n\t\t\t *  a) { funcname: <func>, __prototype: outer_lex_env }\n\t\t\t *  b) { funcname: <func>, __prototype:  <globalenv> }  (if outer_lex_env missing)\n\t\t\t */\n\n\t\t\tif (outer_lex_env) {\n\t\t\t\tproto = outer_lex_env;\n\t\t\t} else {\n\t\t\t\tproto = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t\t\t}\n\n\t\t\t/* -> [ ... closure template env ] */\n\t\t\tnew_env = duk_hdecenv_alloc(thr,\n\t\t\t                            DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t\t\t                            DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\t\t\tDUK_ASSERT(new_env != NULL);\n\t\t\tduk_push_hobject(thr, (duk_hobject *) new_env);\n\n\t\t\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) new_env) == NULL);\n\t\t\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) new_env, proto);\n\t\t\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, proto);\n\n\t\t\tDUK_ASSERT(new_env->thread == NULL);  /* Closed. */\n\t\t\tDUK_ASSERT(new_env->varmap == NULL);\n\n\t\t\t/* It's important that duk_xdef_prop() is a 'raw define' so that any\n\t\t\t * properties in an ancestor are never an issue (they should never be\n\t\t\t * e.g. non-writable, but just in case).\n\t\t\t *\n\t\t\t * Because template objects are not visible to user code, the case\n\t\t\t * where .name is missing shouldn't happen in practice.  It it does,\n\t\t\t * the name 'undefined' gets bound and maps to the closure (which is\n\t\t\t * a bit odd, but safe).\n\t\t\t */\n\t\t\t(void) duk_get_prop_stridx_short(thr, -2, DUK_STRIDX_NAME);\n\t\t\t/* -> [ ... closure template env funcname ] */\n\t\t\tduk_dup_m4(thr);                                           /* -> [ ... closure template env funcname closure ] */\n\t\t\tduk_xdef_prop(thr, -3, DUK_PROPDESC_FLAGS_NONE);           /* -> [ ... closure template env ] */\n\t\t\t/* env[funcname] = closure */\n\n\t\t\t/* [ ... closure template env ] */\n\n\t\t\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, fun_clos, (duk_hobject *) new_env);\n\t\t\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, (duk_hobject *) new_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, (duk_hobject *) new_env);\n\t\t\tduk_pop_unsafe(thr);\n\n\t\t\t/* [ ... closure template ] */\n\t\t}\n\t\telse\n#endif  /* DUK_USE_FUNC_NAME_PROPERTY */\n\t\t{\n\t\t\t/*\n\t\t\t *  Other cases (function declaration, anonymous function expression,\n\t\t\t *  strict direct eval code).  The \"outer\" environment will be whatever\n\t\t\t *  the caller gave us.\n\t\t\t */\n\n\t\t\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, fun_clos, outer_lex_env);\n\t\t\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, outer_lex_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, outer_lex_env);\n\t\t\tDUK_HOBJECT_INCREF(thr, outer_lex_env);\n\n\t\t\t/* [ ... closure template ] */\n\t\t}\n\t} else {\n\t\t/*\n\t\t *  Function gets no new environment when called.  This is the\n\t\t *  case for global code, indirect eval code, and non-strict\n\t\t *  direct eval code.  There is no direct correspondence to the\n\t\t *  E5 specification, as global/eval code is not exposed as a\n\t\t *  function.\n\t\t */\n\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_NAMEBINDING(&fun_temp->obj));\n\n\t\tDUK_HCOMPFUNC_SET_LEXENV(thr->heap, fun_clos, outer_lex_env);\n\t\tDUK_HCOMPFUNC_SET_VARENV(thr->heap, fun_clos, outer_var_env);\n\t\tDUK_HOBJECT_INCREF(thr, outer_lex_env);  /* NULLs not allowed; asserted on entry */\n\t\tDUK_HOBJECT_INCREF(thr, outer_var_env);\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"closure varenv -> %!ipO, lexenv -> %!ipO\",\n\t                     (duk_heaphdr *) fun_clos->var_env,\n\t                     (duk_heaphdr *) fun_clos->lex_env));\n\n\t/* Call handling assumes this for all callable closures. */\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_LEXENV(thr->heap, fun_clos) != NULL);\n\tDUK_ASSERT(DUK_HCOMPFUNC_GET_VARENV(thr->heap, fun_clos) != NULL);\n\n\t/*\n\t *  Copy some internal properties directly\n\t *\n\t *  The properties will be non-writable and non-enumerable, but\n\t *  configurable.\n\t *\n\t *  Function templates are bare objects, so inheritance of internal\n\t *  Symbols is not an issue here even when using ordinary property\n\t *  reads.  The function instance created is not bare, so internal\n\t *  Symbols must be defined without inheritance checks.\n\t */\n\n\t/* [ ... closure template ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"copying properties: closure=%!iT, template=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, -2),\n\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\n\tfor (i = 0; i < (duk_small_uint_t) (sizeof(duk__closure_copy_proplist) / sizeof(duk_uint16_t)); i++) {\n\t\tduk_small_int_t stridx = (duk_small_int_t) duk__closure_copy_proplist[i];\n\t\tif (duk_xget_owndataprop_stridx_short(thr, -1, stridx)) {\n\t\t\t/* [ ... closure template val ] */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copying property, stridx=%ld -> found\", (long) stridx));\n\t\t\tduk_xdef_prop_stridx_short(thr, -3, stridx, DUK_PROPDESC_FLAGS_C);\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"copying property, stridx=%ld -> not found\", (long) stridx));\n\t\t\tduk_pop_unsafe(thr);\n\t\t}\n\t}\n\n\t/*\n\t *  \"length\" maps to number of formals (E5 Section 13.2) for function\n\t *  declarations/expressions (non-bound functions).  Note that 'nargs'\n\t *  is NOT necessarily equal to the number of arguments.  Use length\n\t *  of _Formals; if missing, assume nargs matches .length.\n\t */\n\n\t/* [ ... closure template ] */\n\n\tformals = duk_hobject_get_formals(thr, (duk_hobject *) fun_temp);\n\tif (formals) {\n\t\tlen_value = (duk_uint_t) formals->length;\n\t\tDUK_DD(DUK_DDPRINT(\"closure length from _Formals -> %ld\", (long) len_value));\n\t} else {\n\t\tlen_value = fun_temp->nargs;\n\t\tDUK_DD(DUK_DDPRINT(\"closure length defaulted from nargs -> %ld\", (long) len_value));\n\t}\n\n\tduk_push_uint(thr, len_value);  /* [ ... closure template len_value ] */\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_LENGTH, DUK_PROPDESC_FLAGS_C);\n\n\t/*\n\t *  \"prototype\" is, by default, a fresh object with the \"constructor\"\n\t *  property.\n\t *\n\t *  Note that this creates a circular reference for every function\n\t *  instance (closure) which prevents refcount-based collection of\n\t *  function instances.\n\t *\n\t *  XXX: Try to avoid creating the default prototype object, because\n\t *  many functions are not used as constructors and the default\n\t *  prototype is unnecessary.  Perhaps it could be created on-demand\n\t *  when it is first accessed?\n\t */\n\n\t/* [ ... closure template ] */\n\n\tif (add_auto_proto) {\n\t\tduk_push_object(thr);  /* -> [ ... closure template newobj ] */\n\t\tduk_dup_m3(thr);       /* -> [ ... closure template newobj closure ] */\n\t\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_CONSTRUCTOR, DUK_PROPDESC_FLAGS_WC);  /* -> [ ... closure template newobj ] */\n\t\tduk_compact(thr, -1);  /* compact the prototype */\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_PROTOTYPE, DUK_PROPDESC_FLAGS_W);     /* -> [ ... closure template ] */\n\t}\n\n\t/*\n\t *  \"arguments\" and \"caller\" must be mapped to throwers for strict\n\t *  mode and bound functions (E5 Section 15.3.5).\n\t *\n\t *  XXX: This is expensive to have for every strict function instance.\n\t *  Try to implement as virtual properties or on-demand created properties.\n\t */\n\n\t/* [ ... closure template ] */\n\n\tif (DUK_HOBJECT_HAS_STRICT(&fun_clos->obj)) {\n\t\tduk_xdef_prop_stridx_thrower(thr, -2, DUK_STRIDX_CALLER);\n\t\tduk_xdef_prop_stridx_thrower(thr, -2, DUK_STRIDX_LC_ARGUMENTS);\n\t} else {\n#if defined(DUK_USE_NONSTD_FUNC_CALLER_PROPERTY)\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is non-strict and non-standard 'caller' property in use, add initial 'null' value\"));\n\t\tduk_push_null(thr);\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_CALLER, DUK_PROPDESC_FLAGS_NONE);\n#else\n\t\tDUK_DDD(DUK_DDDPRINT(\"function is non-strict and non-standard 'caller' property not used\"));\n#endif\n\t}\n\n\t/*\n\t *  \"name\" used to be non-standard but is now defined by ES2015.\n\t *  In ES2015/ES2016 the .name property is configurable.\n\t */\n\n\t/* [ ... closure template ] */\n\n#if defined(DUK_USE_FUNC_NAME_PROPERTY)\n\t/* XXX: Look for own property only; doesn't matter much because\n\t * templates are bare objects.\n\t */\n\tif (duk_get_prop_stridx_short(thr, -1, DUK_STRIDX_NAME)) {\n\t\t/* [ ... closure template name ] */\n\t\tDUK_ASSERT(duk_is_string(thr, -1));\n\t\tDUK_DD(DUK_DDPRINT(\"setting function instance name to %!T\", duk_get_tval(thr, -1)));\n\t\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_NAME, DUK_PROPDESC_FLAGS_C);  /* -> [ ... closure template ] */\n\t} else {\n\t\t/* Anonymous functions don't have a .name in ES2015, so don't set\n\t\t * it on the instance either.  The instance will then inherit\n\t\t * it from Function.prototype.name.\n\t\t */\n\t\tDUK_DD(DUK_DDPRINT(\"not setting function instance .name\"));\n\t\tduk_pop_unsafe(thr);\n\t}\n#endif\n\n\t/*\n\t *  Compact the closure, in most cases no properties will be added later.\n\t *  Also, without this the closures end up having unused property slots\n\t *  (e.g. in Duktape 0.9.0, 8 slots would be allocated and only 7 used).\n\t *  A better future solution would be to allocate the closure directly\n\t *  to correct size (and setup the properties directly without going\n\t *  through the API).\n\t */\n\n\tduk_compact(thr, -2);\n\n\t/*\n\t *  Some assertions (E5 Section 13.2).\n\t */\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(&fun_clos->obj) == DUK_HOBJECT_CLASS_FUNCTION);\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, &fun_clos->obj) == thr->builtins[DUK_BIDX_FUNCTION_PROTOTYPE]);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(&fun_clos->obj));\n\tDUK_ASSERT(duk_has_prop_stridx(thr, -2, DUK_STRIDX_LENGTH) != 0);\n\tDUK_ASSERT(add_auto_proto == 0 || duk_has_prop_stridx(thr, -2, DUK_STRIDX_PROTOTYPE) != 0);\n\t/* May be missing .name */\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(&fun_clos->obj) ||\n\t           duk_has_prop_stridx(thr, -2, DUK_STRIDX_CALLER) != 0);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_STRICT(&fun_clos->obj) ||\n\t           duk_has_prop_stridx(thr, -2, DUK_STRIDX_LC_ARGUMENTS) != 0);\n\n\t/*\n\t *  Finish\n\t */\n\n\t/* [ ... closure template ] */\n\n\tDUK_DDD(DUK_DDDPRINT(\"created function instance: template=%!iT -> closure=%!iT\",\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (duk_tval *) duk_get_tval(thr, -2)));\n\n\tduk_pop_unsafe(thr);\n\n\t/* [ ... closure ] */\n}\n\n/*\n *  Delayed activation environment record initialization (for functions\n *  with NEWENV).\n *\n *  The non-delayed initialization is handled by duk_handle_call().\n */\n\nDUK_LOCAL void duk__preallocate_env_entries(duk_hthread *thr, duk_hobject *varmap, duk_hobject *env) {\n\tduk_uint_fast32_t i;\n\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(varmap); i++) {\n\t\tduk_hstring *key;\n\n\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, varmap, i);\n\t\tDUK_ASSERT(key != NULL);   /* assume keys are compact in _Varmap */\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, varmap, i));  /* assume plain values */\n\n\t\t/* Predefine as 'undefined' to reserve a property slot.\n\t\t * This makes the unwind process (where register values\n\t\t * are copied to the env object) safe against throwing.\n\t\t *\n\t\t * XXX: This could be made much faster by creating the\n\t\t * property table directly.\n\t\t */\n\t\tduk_push_undefined(thr);\n\t\tDUK_DDD(DUK_DDDPRINT(\"preallocate env entry for key %!O\", key));\n\t\tduk_hobject_define_property_internal(thr, env, key, DUK_PROPDESC_FLAGS_WE);\n\t}\n}\n\n/* shared helper */\nDUK_INTERNAL\nduk_hobject *duk_create_activation_environment_record(duk_hthread *thr,\n                                                      duk_hobject *func,\n                                                      duk_size_t bottom_byteoff) {\n\tduk_hdecenv *env;\n\tduk_hobject *parent;\n\tduk_hcompfunc *f;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(func != NULL);\n\n\tDUK_STATS_INC(thr->heap, stats_envrec_create);\n\n\tf = (duk_hcompfunc *) func;\n\tparent = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f);\n\tif (!parent) {\n\t\tparent = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t}\n\n\tenv = duk_hdecenv_alloc(thr,\n\t                        DUK_HOBJECT_FLAG_EXTENSIBLE |\n\t                        DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_DECENV));\n\tDUK_ASSERT(env != NULL);\n\tduk_push_hobject(thr, (duk_hobject *) env);\n\n\tDUK_ASSERT(DUK_HOBJECT_GET_PROTOTYPE(thr->heap, (duk_hobject *) env) == NULL);\n\tDUK_HOBJECT_SET_PROTOTYPE(thr->heap, (duk_hobject *) env, parent);\n\tDUK_HOBJECT_INCREF_ALLOWNULL(thr, parent);  /* parent env is the prototype */\n\n\t/* open scope information, for compiled functions only */\n\n\tDUK_ASSERT(env->thread == NULL);\n\tDUK_ASSERT(env->varmap == NULL);\n\tDUK_ASSERT(env->regbase_byteoff == 0);\n\tif (DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\tduk_hobject *varmap;\n\n\t\tvarmap = duk_hobject_get_varmap(thr, func);\n\t\tif (varmap != NULL) {\n\t\t\tenv->varmap = varmap;\n\t\t\tDUK_HOBJECT_INCREF(thr, varmap);\n\t\t\tenv->thread = thr;\n\t\t\tDUK_HTHREAD_INCREF(thr, thr);\n\t\t\tenv->regbase_byteoff = bottom_byteoff;\n\n\t\t\t/* Preallocate env property table to avoid potential\n\t\t\t * for out-of-memory on unwind when the env is closed.\n\t\t\t */\n\t\t\tduk__preallocate_env_entries(thr, varmap, (duk_hobject *) env);\n\t\t} else {\n\t\t\t/* If function has no _Varmap, leave the environment closed. */\n\t\t\tDUK_ASSERT(env->thread == NULL);\n\t\t\tDUK_ASSERT(env->varmap == NULL);\n\t\t\tDUK_ASSERT(env->regbase_byteoff == 0);\n\t\t}\n\t}\n\n\treturn (duk_hobject *) env;\n}\n\nDUK_INTERNAL\nvoid duk_js_init_activation_environment_records_delayed(duk_hthread *thr,\n                                                        duk_activation *act) {\n\tduk_hobject *func;\n\tduk_hobject *env;\n\n\tDUK_ASSERT(thr != NULL);\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_BOUNDFUNC(func));  /* bound functions are never in act 'func' */\n\n\t/*\n\t *  Delayed initialization only occurs for 'NEWENV' functions.\n\t */\n\n\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func));\n\tDUK_ASSERT(act->lex_env == NULL);\n\tDUK_ASSERT(act->var_env == NULL);\n\n\tDUK_STATS_INC(thr->heap, stats_envrec_delayedcreate);\n\n\tenv = duk_create_activation_environment_record(thr, func, act->bottom_byteoff);\n\tDUK_ASSERT(env != NULL);\n\t/* 'act' is a stable pointer, so still OK. */\n\n\tDUK_DDD(DUK_DDDPRINT(\"created delayed fresh env: %!ipO\", (duk_heaphdr *) env));\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t{\n\t\tduk_hobject *p = env;\n\t\twhile (p) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"  -> %!ipO\", (duk_heaphdr *) p));\n\t\t\tp = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, p);\n\t\t}\n\t}\n#endif\n\n\tact->lex_env = env;\n\tact->var_env = env;\n\tDUK_HOBJECT_INCREF(thr, env);  /* XXX: incref by count (here 2 times) */\n\tDUK_HOBJECT_INCREF(thr, env);\n\n\tduk_pop_unsafe(thr);\n}\n\n/*\n *  Closing environment records.\n *\n *  The environment record MUST be closed with the thread where its activation\n *  is; i.e. if 'env' is open, 'thr' must match env->thread, and the regbase\n *  and varmap must still be valid.  On entry, 'env' must be reachable.\n */\n\nDUK_INTERNAL void duk_js_close_environment_record(duk_hthread *thr, duk_hobject *env) {\n\tduk_uint_fast32_t i;\n\tduk_hobject *varmap;\n\tduk_hstring *key;\n\tduk_tval *tv;\n\tduk_uint_t regnum;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL);\n\n\tif (DUK_UNLIKELY(!DUK_HOBJECT_IS_DECENV(env))) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"env not a declarative record: %!iO\", (duk_heaphdr *) env));\n\t\treturn;\n\t}\n\n\tvarmap = ((duk_hdecenv *) env)->varmap;\n\tif (varmap == NULL) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"env already closed: %!iO\", (duk_heaphdr *) env));\n\n\t\treturn;\n\t}\n\tDUK_ASSERT(((duk_hdecenv *) env)->thread != NULL);\n\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env);\n\n\tDUK_DDD(DUK_DDDPRINT(\"closing env: %!iO\", (duk_heaphdr *) env));\n\tDUK_DDD(DUK_DDDPRINT(\"varmap: %!O\", (duk_heaphdr *) varmap));\n\n\t/* Env must be closed in the same thread as where it runs. */\n\tDUK_ASSERT(((duk_hdecenv *) env)->thread == thr);\n\n\t/* XXX: additional conditions when to close variables? we don't want to do it\n\t * unless the environment may have \"escaped\" (referenced in a function closure).\n\t * With delayed environments, the existence is probably good enough of a check.\n\t */\n\n\t/* Note: we rely on the _Varmap having a bunch of nice properties, like:\n\t *  - being compacted and unmodified during this process\n\t *  - not containing an array part\n\t *  - having correct value types\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"copying bound register values, %ld bound regs\", (long) DUK_HOBJECT_GET_ENEXT(varmap)));\n\n\t/* Copy over current variable values from value stack to the\n\t * environment record.  The scope object is empty but may\n\t * inherit from another scope which has conflicting names.\n\t */\n\n\t/* XXX: Do this using a once allocated entry area, no side effects.\n\t * Hash part would need special treatment however (maybe copy, and\n\t * then realloc with hash part if large enough).\n\t */\n\tfor (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(varmap); i++) {\n\t\tduk_size_t regbase_byteoff;\n\n\t\tkey = DUK_HOBJECT_E_GET_KEY(thr->heap, varmap, i);\n\t\tDUK_ASSERT(key != NULL);   /* assume keys are compact in _Varmap */\n\t\tDUK_ASSERT(!DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, varmap, i));  /* assume plain values */\n\n\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, varmap, i);\n\t\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\t\tDUK_ASSERT(DUK_TVAL_GET_NUMBER(tv) <= (duk_double_t) DUK_UINT32_MAX);  /* limits */\n#if defined(DUK_USE_FASTINT)\n\t\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\t\tregnum = (duk_uint_t) DUK_TVAL_GET_FASTINT_U32(tv);\n#else\n\t\tregnum = (duk_uint_t) DUK_TVAL_GET_NUMBER(tv);\n#endif\n\n\t\tregbase_byteoff = ((duk_hdecenv *) env)->regbase_byteoff;\n\t\tDUK_ASSERT((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum >= (duk_uint8_t *) thr->valstack);\n\t\tDUK_ASSERT((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum < (duk_uint8_t *) thr->valstack_top);\n\n\t\t/* Write register value into env as named properties.\n\t\t * If property already exists, overwrites silently.\n\t\t * Property is writable, but not deletable (not configurable\n\t\t * in terms of property attributes).\n\t\t *\n\t\t * This property write must not throw because we're unwinding\n\t\t * and unwind code is not allowed to throw at present.  The\n\t\t * call itself has no such guarantees, but we've preallocated\n\t\t * entries for each property when the env was created, so no\n\t\t * out-of-memory error should be possible.  If this guarantee\n\t\t * is not provided, problems like GH-476 may happen.\n\t\t */\n\t\tduk_push_tval(thr, (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + regbase_byteoff + sizeof(duk_tval) * regnum));\n\t\tDUK_DDD(DUK_DDDPRINT(\"closing identifier %!O -> reg %ld, value %!T\",\n\t\t                     (duk_heaphdr *) key,\n\t\t                     (long) regnum,\n\t\t                     (duk_tval *) duk_get_tval(thr, -1)));\n\t\tduk_hobject_define_property_internal(thr, env, key, DUK_PROPDESC_FLAGS_WE);\n\t}\n\n\t/* NULL atomically to avoid inconsistent state + side effects. */\n\tDUK_HOBJECT_DECREF_NORZ(thr, ((duk_hdecenv *) env)->thread);\n\tDUK_HOBJECT_DECREF_NORZ(thr, ((duk_hdecenv *) env)->varmap);\n\t((duk_hdecenv *) env)->thread = NULL;\n\t((duk_hdecenv *) env)->varmap = NULL;\n\n\tDUK_DDD(DUK_DDDPRINT(\"env after closing: %!O\", (duk_heaphdr *) env));\n}\n\n/*\n *  GETIDREF: a GetIdentifierReference-like helper.\n *\n *  Provides a parent traversing lookup and a single level lookup\n *  (for HasBinding).\n *\n *  Instead of returning the value, returns a bunch of values allowing\n *  the caller to read, write, or delete the binding.  Value pointers\n *  are duk_tval pointers which can be mutated directly as long as\n *  refcounts are properly updated.  Note that any operation which may\n *  reallocate valstacks or compact objects may invalidate the returned\n *  duk_tval (but not object) pointers, so caller must be very careful.\n *\n *  If starting environment record 'env' is given, 'act' is ignored.\n *  However, if 'env' is NULL, the caller may identify, in 'act', an\n *  activation which hasn't had its declarative environment initialized\n *  yet.  The activation registers are then looked up, and its parent\n *  traversed normally.\n *\n *  The 'out' structure values are only valid if the function returns\n *  success (non-zero).\n */\n\n/* lookup name from an open declarative record's registers */\nDUK_LOCAL\nduk_bool_t duk__getid_open_decl_env_regs(duk_hthread *thr,\n                                         duk_hstring *name,\n                                         duk_hdecenv *env,\n                                         duk__id_lookup_result *out) {\n\tduk_tval *tv;\n\tduk_size_t reg_rel;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(out != NULL);\n\n\tDUK_ASSERT(DUK_HOBJECT_IS_DECENV((duk_hobject *) env));\n\tDUK_HDECENV_ASSERT_VALID(env);\n\n\tif (env->thread == NULL) {\n\t\t/* already closed */\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(env->varmap != NULL);\n\n\ttv = duk_hobject_find_entry_tval_ptr(thr->heap, env->varmap, name);\n\tif (DUK_UNLIKELY(tv == NULL)) {\n\t\treturn 0;\n\t}\n\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\tDUK_ASSERT(DUK_TVAL_GET_NUMBER(tv) <= (duk_double_t) DUK_UINT32_MAX);  /* limits */\n#if defined(DUK_USE_FASTINT)\n\tDUK_ASSERT(DUK_TVAL_IS_FASTINT(tv));\n\treg_rel = (duk_size_t) DUK_TVAL_GET_FASTINT_U32(tv);\n#else\n\treg_rel = (duk_size_t) DUK_TVAL_GET_NUMBER(tv);\n#endif\n\tDUK_ASSERT_DISABLE(reg_rel >= 0);  /* unsigned */\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) env->thread->valstack + env->regbase_byteoff + sizeof(duk_tval) * reg_rel);\n\tDUK_ASSERT(tv >= env->thread->valstack && tv < env->thread->valstack_end);  /* XXX: more accurate? */\n\n\tout->value = tv;\n\tout->attrs = DUK_PROPDESC_FLAGS_W;  /* registers are mutable, non-deletable */\n\tout->env = (duk_hobject *) env;\n\tout->holder = NULL;\n\tout->has_this = 0;\n\treturn 1;\n}\n\n/* lookup name from current activation record's functions' registers */\nDUK_LOCAL\nduk_bool_t duk__getid_activation_regs(duk_hthread *thr,\n                                      duk_hstring *name,\n                                      duk_activation *act,\n                                      duk__id_lookup_result *out) {\n\tduk_tval *tv;\n\tduk_hobject *func;\n\tduk_hobject *varmap;\n\tduk_size_t reg_rel;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(act != NULL);\n\tDUK_ASSERT(out != NULL);\n\n\tfunc = DUK_ACT_GET_FUNC(act);\n\tDUK_ASSERT(func != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func));\n\n\tif (!DUK_HOBJECT_IS_COMPFUNC(func)) {\n\t\treturn 0;\n\t}\n\n\t/* XXX: move varmap to duk_hcompfunc struct field? */\n\tvarmap = duk_hobject_get_varmap(thr, func);\n\tif (!varmap) {\n\t\treturn 0;\n\t}\n\n\ttv = duk_hobject_find_entry_tval_ptr(thr->heap, varmap, name);\n\tif (!tv) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(DUK_TVAL_IS_NUMBER(tv));\n\treg_rel = (duk_size_t) DUK_TVAL_GET_NUMBER(tv);\n\tDUK_ASSERT_DISABLE(reg_rel >= 0);\n\tDUK_ASSERT(reg_rel < ((duk_hcompfunc *) func)->nregs);\n\n\ttv = (duk_tval *) (void *) ((duk_uint8_t *) thr->valstack + act->bottom_byteoff);\n\ttv += reg_rel;\n\n\tout->value = tv;\n\tout->attrs = DUK_PROPDESC_FLAGS_W;  /* registers are mutable, non-deletable */\n\tout->env = NULL;\n\tout->holder = NULL;\n\tout->has_this = 0;\n\treturn 1;\n}\n\nDUK_LOCAL\nduk_bool_t duk__get_identifier_reference(duk_hthread *thr,\n                                         duk_hobject *env,\n                                         duk_hstring *name,\n                                         duk_activation *act,\n                                         duk_bool_t parents,\n                                         duk__id_lookup_result *out) {\n\tduk_tval *tv;\n\tduk_uint_t sanity;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL || act != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(out != NULL);\n\n\tDUK_ASSERT(!env || DUK_HOBJECT_IS_ENV(env));\n\tDUK_ASSERT(!env || !DUK_HOBJECT_HAS_ARRAY_PART(env));\n\n\t/*\n\t *  Conceptually, we look for the identifier binding by starting from\n\t *  'env' and following to chain of environment records (represented\n\t *  by the prototype chain).\n\t *\n\t *  If 'env' is NULL, the current activation does not yet have an\n\t *  allocated declarative environment record; this should be treated\n\t *  exactly as if the environment record existed but had no bindings\n\t *  other than register bindings.\n\t *\n\t *  Note: we assume that with the DUK_HOBJECT_FLAG_NEWENV cleared\n\t *  the environment will always be initialized immediately; hence\n\t *  a NULL 'env' should only happen with the flag set.  This is the\n\t *  case for: (1) function calls, and (2) strict, direct eval calls.\n\t */\n\n\tif (env == NULL && act != NULL) {\n\t\tduk_hobject *func;\n\t\tduk_hcompfunc *f;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference: env is NULL, activation is non-NULL -> \"\n\t\t                     \"delayed env case, look up activation regs first\"));\n\n\t\t/*\n\t\t *  Try registers\n\t\t */\n\n\t\tif (duk__getid_activation_regs(thr, name, act, out)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t                     \"(found from register bindings when env=NULL)\",\n\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\treturn 1;\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"not found in current activation regs\"));\n\n\t\t/*\n\t\t *  Not found in registers, proceed to the parent record.\n\t\t *  Here we need to determine what the parent would be,\n\t\t *  if 'env' was not NULL (i.e. same logic as when initializing\n\t\t *  the record).\n\t\t *\n\t\t *  Note that environment initialization is only deferred when\n\t\t *  DUK_HOBJECT_HAS_NEWENV is set, and this only happens for:\n\t\t *    - Function code\n\t\t *    - Strict eval code\n\t\t *\n\t\t *  We only need to check _Lexenv here; _Varenv exists only if it\n\t\t *  differs from _Lexenv (and thus _Lexenv will also be present).\n\t\t */\n\n\t\tif (!parents) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference failed, no parent traversal \"\n\t\t\t                     \"(not found from register bindings when env=NULL)\"));\n\t\t\tgoto fail_not_found;\n\t\t}\n\n\t\tfunc = DUK_ACT_GET_FUNC(act);\n\t\tDUK_ASSERT(func != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_NEWENV(func));\n\t\tf = (duk_hcompfunc *) func;\n\n\t\tenv = DUK_HCOMPFUNC_GET_LEXENV(thr->heap, f);\n\t\tif (!env) {\n\t\t\tenv = thr->builtins[DUK_BIDX_GLOBAL_ENV];\n\t\t}\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"continue lookup from env: %!iO\",\n\t\t                     (duk_heaphdr *) env));\n\t}\n\n\t/*\n\t *  Prototype walking starting from 'env'.\n\t *\n\t *  ('act' is not needed anywhere here.)\n\t */\n\n\tsanity = DUK_HOBJECT_PROTOTYPE_CHAIN_SANITY;\n\twhile (env != NULL) {\n\t\tduk_small_uint_t cl;\n\t\tduk_uint_t attrs;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference, name=%!O, considering env=%p -> %!iO\",\n\t\t                     (duk_heaphdr *) name,\n\t\t                     (void *) env,\n\t\t                     (duk_heaphdr *) env));\n\n\t\tDUK_ASSERT(env != NULL);\n\t\tDUK_ASSERT(DUK_HOBJECT_IS_ENV(env));\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(env));\n\n\t\tcl = DUK_HOBJECT_GET_CLASS_NUMBER(env);\n\t\tDUK_ASSERT(cl == DUK_HOBJECT_CLASS_OBJENV || cl == DUK_HOBJECT_CLASS_DECENV);\n\t\tif (cl == DUK_HOBJECT_CLASS_DECENV) {\n\t\t\t/*\n\t\t\t *  Declarative environment record.\n\t\t\t *\n\t\t\t *  Identifiers can never be stored in ancestors and are\n\t\t\t *  always plain values, so we can use an internal helper\n\t\t\t *  and access the value directly with an duk_tval ptr.\n\t\t\t *\n\t\t\t *  A closed environment is only indicated by it missing\n\t\t\t *  the \"book-keeping\" properties required for accessing\n\t\t\t *  register-bound variables.\n\t\t\t */\n\n\t\t\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env);\n\t\t\tif (duk__getid_open_decl_env_regs(thr, name, (duk_hdecenv *) env, out)) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t\t                     \"(declarative environment record, scope open, found in regs)\",\n\t\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\ttv = duk_hobject_find_entry_tval_ptr_and_attrs(thr->heap, env, name, &attrs);\n\t\t\tif (tv) {\n\t\t\t\tout->value = tv;\n\t\t\t\tout->attrs = attrs;\n\t\t\t\tout->env = env;\n\t\t\t\tout->holder = env;\n\t\t\t\tout->has_this = 0;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t\t                     \"(declarative environment record, found in properties)\",\n\t\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t} else {\n\t\t\t/*\n\t\t\t *  Object environment record.\n\t\t\t *\n\t\t\t *  Binding (target) object is an external, uncontrolled object.\n\t\t\t *  Identifier may be bound in an ancestor property, and may be\n\t\t\t *  an accessor.  Target can also be a Proxy which we must support\n\t\t\t *  here.\n\t\t\t */\n\n\t\t\t/* XXX: we could save space by using _Target OR _This.  If _Target, assume\n\t\t\t * this binding is undefined.  If _This, assumes this binding is _This, and\n\t\t\t * target is also _This.  One property would then be enough.\n\t\t\t */\n\n\t\t\tduk_hobject *target;\n\t\t\tduk_bool_t found;\n\n\t\t\tDUK_ASSERT(cl == DUK_HOBJECT_CLASS_OBJENV);\n\t\t\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) env);\n\n\t\t\ttarget = ((duk_hobjenv *) env)->target;\n\t\t\tDUK_ASSERT(target != NULL);\n\n\t\t\t/* Target may be a Proxy or property may be an accessor, so we must\n\t\t\t * use an actual, Proxy-aware hasprop check here.\n\t\t\t *\n\t\t\t * out->holder is NOT set to the actual duk_hobject where the\n\t\t\t * property is found, but rather the object binding target object.\n\t\t\t */\n\n#if defined(DUK_USE_ES6_PROXY)\n\t\t\tif (DUK_UNLIKELY(DUK_HOBJECT_IS_PROXY(target))) {\n\t\t\t\tduk_tval tv_name;\n\t\t\t\tduk_tval tv_target_tmp;\n\n\t\t\t\tDUK_ASSERT(name != NULL);\n\t\t\t\tDUK_TVAL_SET_STRING(&tv_name, name);\n\t\t\t\tDUK_TVAL_SET_OBJECT(&tv_target_tmp, target);\n\n\t\t\t\tfound = duk_hobject_hasprop(thr, &tv_target_tmp, &tv_name);\n\t\t\t} else\n#endif  /* DUK_USE_ES6_PROXY */\n\t\t\t{\n\t\t\t\t/* XXX: duk_hobject_hasprop() would be correct for\n\t\t\t\t * non-Proxy objects too, but it is about ~20-25%\n\t\t\t\t * slower at present so separate code paths for\n\t\t\t\t * Proxy and non-Proxy now.\n\t\t\t\t */\n\t\t\t\tfound = duk_hobject_hasprop_raw(thr, target, name);\n\t\t\t}\n\n\t\t\tif (found) {\n\t\t\t\tout->value = NULL;  /* can't get value, may be accessor */\n\t\t\t\tout->attrs = 0;     /* irrelevant when out->value == NULL */\n\t\t\t\tout->env = env;\n\t\t\t\tout->holder = target;\n\t\t\t\tout->has_this = ((duk_hobjenv *) env)->has_this;\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference successful: \"\n\t\t\t\t                     \"name=%!O -> value=%!T, attrs=%ld, has_this=%ld, env=%!O, holder=%!O \"\n\t\t\t\t                     \"(object environment record)\",\n\t\t\t\t                     (duk_heaphdr *) name, (duk_tval *) out->value,\n\t\t\t\t                     (long) out->attrs, (long) out->has_this,\n\t\t\t\t                     (duk_heaphdr *) out->env, (duk_heaphdr *) out->holder));\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\n\t\tif (!parents) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"duk__get_identifier_reference failed, no parent traversal \"\n\t\t\t                     \"(not found from first traversed env)\"));\n\t\t\tgoto fail_not_found;\n\t\t}\n\n                if (DUK_UNLIKELY(sanity-- == 0)) {\n                        DUK_ERROR_RANGE(thr, DUK_STR_PROTOTYPE_CHAIN_LIMIT);\n\t\t\tDUK_WO_NORETURN(return 0;);\n                }\n\t\tenv = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, env);\n\t}\n\n\t/*\n\t *  Not found (even in global object)\n\t */\n\n fail_not_found:\n\treturn 0;\n}\n\n/*\n *  HASVAR: check identifier binding from a given environment record\n *  without traversing its parents.\n *\n *  This primitive is not exposed to user code as such, but is used\n *  internally for e.g. declaration binding instantiation.\n *\n *  See E5 Sections:\n *    10.2.1.1.1 HasBinding(N)\n *    10.2.1.2.1 HasBinding(N)\n *\n *  Note: strictness has no bearing on this check.  Hence we don't take\n *  a 'strict' parameter.\n */\n\n#if 0  /*unused*/\nDUK_INTERNAL\nduk_bool_t duk_js_hasvar_envrec(duk_hthread *thr,\n                                duk_hobject *env,\n                                duk_hstring *name) {\n\tduk__id_lookup_result ref;\n\tduk_bool_t parents;\n\n\tDUK_DDD(DUK_DDDPRINT(\"hasvar: thr=%p, env=%p, name=%!O \"\n\t                     \"(env -> %!dO)\",\n\t                     (void *) thr, (void *) env, (duk_heaphdr *) name,\n\t                     (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(name != NULL);\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\n\tDUK_ASSERT(DUK_HOBJECT_IS_ENV(env));\n\tDUK_ASSERT(!DUK_HOBJECT_HAS_ARRAY_PART(env));\n\n\t/* lookup results is ignored */\n\tparents = 0;\n\treturn duk__get_identifier_reference(thr, env, name, NULL, parents, &ref);\n}\n#endif\n\n/*\n *  GETVAR\n *\n *  See E5 Sections:\n *    11.1.2 Identifier Reference\n *    10.3.1 Identifier Resolution\n *    11.13.1 Simple Assignment  [example of where the Reference is GetValue'd]\n *    8.7.1 GetValue (V)\n *    8.12.1 [[GetOwnProperty]] (P)\n *    8.12.2 [[GetProperty]] (P)\n *    8.12.3 [[Get]] (P)\n *\n *  If 'throw' is true, always leaves two values on top of stack: [val this].\n *\n *  If 'throw' is false, returns 0 if identifier cannot be resolved, and the\n *  stack will be unaffected in this case.  If identifier is resolved, returns\n *  1 and leaves [val this] on top of stack.\n *\n *  Note: the 'strict' flag of a reference returned by GetIdentifierReference\n *  is ignored by GetValue.  Hence we don't take a 'strict' parameter.\n *\n *  The 'throw' flag is needed for implementing 'typeof' for an unreferenced\n *  identifier.  An unreference identifier in other contexts generates a\n *  ReferenceError.\n */\n\nDUK_LOCAL\nduk_bool_t duk__getvar_helper(duk_hthread *thr,\n                              duk_hobject *env,\n                              duk_activation *act,\n                              duk_hstring *name,\n                              duk_bool_t throw_flag) {\n\tduk__id_lookup_result ref;\n\tduk_tval tv_tmp_obj;\n\tduk_tval tv_tmp_key;\n\tduk_bool_t parents;\n\n\tDUK_DDD(DUK_DDDPRINT(\"getvar: thr=%p, env=%p, act=%p, name=%!O \"\n\t                     \"(env -> %!dO)\",\n\t                     (void *) thr, (void *) env, (void *) act,\n\t                     (duk_heaphdr *) name, (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\t/* env and act may be NULL */\n\n\tDUK_STATS_INC(thr->heap, stats_getvar_all);\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\n\tparents = 1;     /* follow parent chain */\n\tif (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) {\n\t\tif (ref.value) {\n\t\t\tduk_push_tval(thr, ref.value);\n\t\t\tduk_push_undefined(thr);\n\t\t} else {\n\t\t\tDUK_ASSERT(ref.holder != NULL);\n\n\t\t\t/* ref.holder is safe across the getprop call (even\n\t\t\t * with side effects) because 'env' is reachable and\n\t\t\t * ref.holder is a direct heap pointer.\n\t\t\t */\n\n\t\t\tDUK_TVAL_SET_OBJECT(&tv_tmp_obj, ref.holder);\n\t\t\tDUK_TVAL_SET_STRING(&tv_tmp_key, name);\n\t\t\t(void) duk_hobject_getprop(thr, &tv_tmp_obj, &tv_tmp_key);  /* [value] */\n\n\t\t\tif (ref.has_this) {\n\t\t\t\tduk_push_hobject(thr, ref.holder);\n\t\t\t} else {\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t}\n\n\t\t\t/* [value this] */\n\t\t}\n\n\t\treturn 1;\n\t} else {\n\t\tif (throw_flag) {\n\t\t\tDUK_ERROR_FMT1(thr, DUK_ERR_REFERENCE_ERROR,\n\t\t\t               \"identifier '%s' undefined\",\n\t\t\t               (const char *) DUK_HSTRING_GET_DATA(name));\n\t\t\tDUK_WO_NORETURN(return 0;);\n\t\t}\n\n\t\treturn 0;\n\t}\n}\n\nDUK_INTERNAL\nduk_bool_t duk_js_getvar_envrec(duk_hthread *thr,\n                                duk_hobject *env,\n                                duk_hstring *name,\n                                duk_bool_t throw_flag) {\n\treturn duk__getvar_helper(thr, env, NULL, name, throw_flag);\n}\n\nDUK_INTERNAL\nduk_bool_t duk_js_getvar_activation(duk_hthread *thr,\n                                    duk_activation *act,\n                                    duk_hstring *name,\n                                    duk_bool_t throw_flag) {\n\tDUK_ASSERT(act != NULL);\n\treturn duk__getvar_helper(thr, act->lex_env, act, name, throw_flag);\n}\n\n/*\n *  PUTVAR\n *\n *  See E5 Sections:\n *    11.1.2 Identifier Reference\n *    10.3.1 Identifier Resolution\n *    11.13.1 Simple Assignment  [example of where the Reference is PutValue'd]\n *    8.7.2 PutValue (V,W)  [see especially step 3.b, undefined -> automatic global in non-strict mode]\n *    8.12.4 [[CanPut]] (P)\n *    8.12.5 [[Put]] (P)\n *\n *  Note: may invalidate any valstack (or object) duk_tval pointers because\n *  putting a value may reallocate any object or any valstack.  Caller beware.\n */\n\nDUK_LOCAL\nvoid duk__putvar_helper(duk_hthread *thr,\n                        duk_hobject *env,\n                        duk_activation *act,\n                        duk_hstring *name,\n                        duk_tval *val,\n                        duk_bool_t strict) {\n\tduk__id_lookup_result ref;\n\tduk_tval tv_tmp_obj;\n\tduk_tval tv_tmp_key;\n\tduk_bool_t parents;\n\n\tDUK_STATS_INC(thr->heap, stats_putvar_all);\n\n\tDUK_DDD(DUK_DDDPRINT(\"putvar: thr=%p, env=%p, act=%p, name=%!O, val=%p, strict=%ld \"\n\t                     \"(env -> %!dO, val -> %!T)\",\n\t                     (void *) thr, (void *) env, (void *) act,\n\t                     (duk_heaphdr *) name, (void *) val, (long) strict,\n\t                     (duk_heaphdr *) env, (duk_tval *) val));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(val != NULL);\n\t/* env and act may be NULL */\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env);\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\tDUK_ASSERT_REFCOUNT_NONZERO_TVAL(val);\n\n\t/*\n\t *  In strict mode E5 protects 'eval' and 'arguments' from being\n\t *  assigned to (or even declared anywhere).  Attempt to do so\n\t *  should result in a compile time SyntaxError.  See the internal\n\t *  design documentation for details.\n\t *\n\t *  Thus, we should never come here, run-time, for strict code,\n\t *  and name 'eval' or 'arguments'.\n\t */\n\n\tDUK_ASSERT(!strict ||\n\t           (name != DUK_HTHREAD_STRING_EVAL(thr) &&\n\t            name != DUK_HTHREAD_STRING_LC_ARGUMENTS(thr)));\n\n\t/*\n\t *  Lookup variable and update in-place if found.\n\t */\n\n\tparents = 1;     /* follow parent chain */\n\n\tif (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) {\n\t\tif (ref.value && (ref.attrs & DUK_PROPDESC_FLAG_WRITABLE)) {\n\t\t\t/* Update duk_tval in-place if pointer provided and the\n\t\t\t * property is writable.  If the property is not writable\n\t\t\t * (immutable binding), use duk_hobject_putprop() which\n\t\t\t * will respect mutability.\n\t\t\t */\n\t\t\tduk_tval *tv_val;\n\n\t\t\ttv_val = ref.value;\n\t\t\tDUK_ASSERT(tv_val != NULL);\n\t\t\tDUK_TVAL_SET_TVAL_UPDREF(thr, tv_val, val);  /* side effects */\n\n\t\t\t/* ref.value invalidated here */\n\t\t} else {\n\t\t\tDUK_ASSERT(ref.holder != NULL);\n\n\t\t\tDUK_TVAL_SET_OBJECT(&tv_tmp_obj, ref.holder);\n\t\t\tDUK_TVAL_SET_STRING(&tv_tmp_key, name);\n\t\t\t(void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, strict);\n\n\t\t\t/* ref.value invalidated here */\n\t\t}\n\n\t\treturn;\n\t}\n\n\t/*\n\t *  Not found: write to global object (non-strict) or ReferenceError\n\t *  (strict); see E5 Section 8.7.2, step 3.\n\t */\n\n\tif (strict) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"identifier binding not found, strict => reference error\"));\n\t\tDUK_ERROR_FMT1(thr, DUK_ERR_REFERENCE_ERROR,\n\t\t               \"identifier '%s' undefined\",\n\t\t               (const char *) DUK_HSTRING_GET_DATA(name));\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"identifier binding not found, not strict => set to global\"));\n\n\tDUK_TVAL_SET_OBJECT(&tv_tmp_obj, thr->builtins[DUK_BIDX_GLOBAL]);\n\tDUK_TVAL_SET_STRING(&tv_tmp_key, name);\n\t(void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, 0);  /* 0 = no throw */\n\n\t/* NB: 'val' may be invalidated here because put_value may realloc valstack,\n\t * caller beware.\n\t */\n}\n\nDUK_INTERNAL\nvoid duk_js_putvar_envrec(duk_hthread *thr,\n                          duk_hobject *env,\n                          duk_hstring *name,\n                          duk_tval *val,\n                          duk_bool_t strict) {\n\tduk__putvar_helper(thr, env, NULL, name, val, strict);\n}\n\nDUK_INTERNAL\nvoid duk_js_putvar_activation(duk_hthread *thr,\n                              duk_activation *act,\n                              duk_hstring *name,\n                              duk_tval *val,\n                              duk_bool_t strict) {\n\tDUK_ASSERT(act != NULL);\n\tduk__putvar_helper(thr, act->lex_env, act, name, val, strict);\n}\n\n/*\n *  DELVAR\n *\n *  See E5 Sections:\n *    11.4.1 The delete operator\n *    10.2.1.1.5 DeleteBinding (N)  [declarative environment record]\n *    10.2.1.2.5 DeleteBinding (N)  [object environment record]\n *\n *  Variable bindings established inside eval() are deletable (configurable),\n *  other bindings are not, including variables declared in global level.\n *  Registers are always non-deletable, and the deletion of other bindings\n *  is controlled by the configurable flag.\n *\n *  For strict mode code, the 'delete' operator should fail with a compile\n *  time SyntaxError if applied to identifiers.  Hence, no strict mode\n *  run-time deletion of identifiers should ever happen.  This function\n *  should never be called from strict mode code!\n */\n\nDUK_LOCAL\nduk_bool_t duk__delvar_helper(duk_hthread *thr,\n                              duk_hobject *env,\n                              duk_activation *act,\n                              duk_hstring *name) {\n\tduk__id_lookup_result ref;\n\tduk_bool_t parents;\n\n\tDUK_DDD(DUK_DDDPRINT(\"delvar: thr=%p, env=%p, act=%p, name=%!O \"\n\t                     \"(env -> %!dO)\",\n\t                     (void *) thr, (void *) env, (void *) act,\n\t                     (duk_heaphdr *) name, (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(name != NULL);\n\t/* env and act may be NULL */\n\n        DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name);\n\n\tparents = 1;     /* follow parent chain */\n\n\tif (duk__get_identifier_reference(thr, env, name, act, parents, &ref)) {\n\t\tif (ref.value && !(ref.attrs & DUK_PROPDESC_FLAG_CONFIGURABLE)) {\n\t\t\t/* Identifier found in registers (always non-deletable)\n\t\t\t * or declarative environment record and non-configurable.\n\t\t\t */\n\t\t\treturn 0;\n\t\t}\n\t\tDUK_ASSERT(ref.holder != NULL);\n\n\t\treturn duk_hobject_delprop_raw(thr, ref.holder, name, 0);\n\t}\n\n\t/*\n\t *  Not found (even in global object).\n\t *\n\t *  In non-strict mode this is a silent SUCCESS (!), see E5 Section 11.4.1,\n\t *  step 3.b.  In strict mode this case is a compile time SyntaxError so\n\t *  we should not come here.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"identifier to be deleted not found: name=%!O \"\n\t                     \"(treated as silent success)\",\n\t                     (duk_heaphdr *) name));\n\treturn 1;\n}\n\n#if 0  /*unused*/\nDUK_INTERNAL\nduk_bool_t duk_js_delvar_envrec(duk_hthread *thr,\n                                duk_hobject *env,\n                                duk_hstring *name) {\n\treturn duk__delvar_helper(thr, env, NULL, name);\n}\n#endif\n\nDUK_INTERNAL\nduk_bool_t duk_js_delvar_activation(duk_hthread *thr,\n                                    duk_activation *act,\n                                    duk_hstring *name) {\n\tDUK_ASSERT(act != NULL);\n\treturn duk__delvar_helper(thr, act->lex_env, act, name);\n}\n\n/*\n *  DECLVAR\n *\n *  See E5 Sections:\n *    10.4.3 Entering Function Code\n *    10.5 Declaration Binding Instantion\n *    12.2 Variable Statement\n *    11.1.2 Identifier Reference\n *    10.3.1 Identifier Resolution\n *\n *  Variable declaration behavior is mainly discussed in Section 10.5,\n *  and is not discussed in the execution semantics (Sections 11-13).\n *\n *  Conceptually declarations happen when code (global, eval, function)\n *  is entered, before any user code is executed.  In practice, register-\n *  bound identifiers are 'declared' automatically (by virtue of being\n *  allocated to registers with the initial value 'undefined').  Other\n *  identifiers are declared in the function prologue with this primitive.\n *\n *  Since non-register bindings eventually back to an internal object's\n *  properties, the 'prop_flags' argument is used to specify binding\n *  type:\n *\n *    - Immutable binding: set DUK_PROPDESC_FLAG_WRITABLE to false\n *    - Non-deletable binding: set DUK_PROPDESC_FLAG_CONFIGURABLE to false\n *    - The flag DUK_PROPDESC_FLAG_ENUMERABLE should be set, although it\n *      doesn't really matter for internal objects\n *\n *  All bindings are non-deletable mutable bindings except:\n *\n *    - Declarations in eval code (mutable, deletable)\n *    - 'arguments' binding in strict function code (immutable)\n *    - Function name binding of a function expression (immutable)\n *\n *  Declarations may go to declarative environment records (always\n *  so for functions), but may also go to object environment records\n *  (e.g. global code).  The global object environment has special\n *  behavior when re-declaring a function (but not a variable); see\n *  E5.1 specification, Section 10.5, step 5.e.\n *\n *  Declarations always go to the 'top-most' environment record, i.e.\n *  we never check the record chain.  It's not an error even if a\n *  property (even an immutable or non-deletable one) of the same name\n *  already exists.\n *\n *  If a declared variable already exists, its value needs to be updated\n *  (if possible).  Returns 1 if a PUTVAR needs to be done by the caller;\n *  otherwise returns 0.\n */\n\nDUK_LOCAL\nduk_bool_t duk__declvar_helper(duk_hthread *thr,\n                               duk_hobject *env,\n                               duk_hstring *name,\n                               duk_tval *val,\n                               duk_small_uint_t prop_flags,\n                               duk_bool_t is_func_decl) {\n\tduk_hobject *holder;\n\tduk_bool_t parents;\n\tduk__id_lookup_result ref;\n\tduk_tval *tv;\n\n\tDUK_DDD(DUK_DDDPRINT(\"declvar: thr=%p, env=%p, name=%!O, val=%!T, prop_flags=0x%08lx, is_func_decl=%ld \"\n\t                     \"(env -> %!iO)\",\n\t                     (void *) thr, (void *) env, (duk_heaphdr *) name,\n\t                     (duk_tval *) val, (unsigned long) prop_flags,\n\t                     (unsigned int) is_func_decl, (duk_heaphdr *) env));\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(name != NULL);\n\tDUK_ASSERT(val != NULL);\n\n\t/* Note: in strict mode the compiler should reject explicit\n\t * declaration of 'eval' or 'arguments'.  However, internal\n\t * bytecode may declare 'arguments' in the function prologue.\n\t * We don't bother checking (or asserting) for these now.\n\t */\n\n\t/* Note: val is a stable duk_tval pointer.  The caller makes\n\t * a value copy into its stack frame, so 'tv_val' is not subject\n\t * to side effects here.\n\t */\n\n\t/*\n\t *  Check whether already declared.\n\t *\n\t *  We need to check whether the binding exists in the environment\n\t *  without walking its parents.  However, we still need to check\n\t *  register-bound identifiers and the prototype chain of an object\n\t *  environment target object.\n\t */\n\n\tparents = 0;  /* just check 'env' */\n\tif (duk__get_identifier_reference(thr, env, name, NULL, parents, &ref)) {\n\t\tduk_int_t e_idx;\n\t\tduk_int_t h_idx;\n\t\tduk_small_uint_t flags;\n\n\t\t/*\n\t\t *  Variable already declared, ignore re-declaration.\n\t\t *  The only exception is the updated behavior of E5.1 for\n\t\t *  global function declarations, E5.1 Section 10.5, step 5.e.\n\t\t *  This behavior does not apply to global variable declarations.\n\t\t */\n\n\t\tif (!(is_func_decl && env == thr->builtins[DUK_BIDX_GLOBAL_ENV])) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"re-declare a binding, ignoring\"));\n\t\t\treturn 1;  /* 1 -> needs a PUTVAR */\n\t\t}\n\n\t\t/*\n\t\t *  Special behavior in E5.1.\n\t\t *\n\t\t *  Note that even though parents == 0, the conflicting property\n\t\t *  may be an inherited property (currently our global object's\n\t\t *  prototype is Object.prototype).  Step 5.e first operates on\n\t\t *  the existing property (which is potentially in an ancestor)\n\t\t *  and then defines a new property in the global object (and\n\t\t *  never modifies the ancestor).\n\t\t *\n\t\t *  Also note that this logic would become even more complicated\n\t\t *  if the conflicting property might be a virtual one.  Object\n\t\t *  prototype has no virtual properties, though.\n\t\t *\n\t\t *  XXX: this is now very awkward, rework.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"re-declare a function binding in global object, \"\n\t\t                     \"updated E5.1 processing\"));\n\n\t\tDUK_ASSERT(ref.holder != NULL);\n\t\tholder = ref.holder;\n\n\t\t/* holder will be set to the target object, not the actual object\n\t\t * where the property was found (see duk__get_identifier_reference()).\n\t\t */\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(holder) == DUK_HOBJECT_CLASS_GLOBAL);\n\t\tDUK_ASSERT(!DUK_HOBJECT_HAS_EXOTIC_ARRAY(holder));  /* global object doesn't have array part */\n\n\t\t/* XXX: use a helper for prototype traversal; no loop check here */\n\t\t/* must be found: was found earlier, and cannot be inherited */\n\t\tfor (;;) {\n\t\t\tDUK_ASSERT(holder != NULL);\n\t\t\tif (duk_hobject_find_entry(thr->heap, holder, name, &e_idx, &h_idx)) {\n\t\t\t\tDUK_ASSERT(e_idx >= 0);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t/* SCANBUILD: NULL pointer dereference, doesn't actually trigger,\n\t\t\t * asserted above.\n\t\t\t */\n\t\t\tholder = DUK_HOBJECT_GET_PROTOTYPE(thr->heap, holder);\n\t\t}\n\t\tDUK_ASSERT(holder != NULL);\n\t\tDUK_ASSERT(e_idx >= 0);\n\t\t/* SCANBUILD: scan-build produces a NULL pointer dereference warning\n\t\t * below; it never actually triggers because holder is actually never\n\t\t * NULL.\n\t\t */\n\n\t\t/* ref.holder is global object, holder is the object with the\n\t\t * conflicting property.\n\t\t */\n\n\t\tflags = DUK_HOBJECT_E_GET_FLAGS(thr->heap, holder, e_idx);\n\t\tif (!(flags & DUK_PROPDESC_FLAG_CONFIGURABLE)) {\n\t\t\tif (flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"existing property is a non-configurable \"\n\t\t\t\t                     \"accessor -> reject\"));\n\t\t\t\tgoto fail_existing_attributes;\n\t\t\t}\n\t\t\tif (!((flags & DUK_PROPDESC_FLAG_WRITABLE) &&\n\t\t\t      (flags & DUK_PROPDESC_FLAG_ENUMERABLE))) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"existing property is a non-configurable \"\n\t\t\t\t                     \"plain property which is not writable and \"\n\t\t\t\t                     \"enumerable -> reject\"));\n\t\t\t\tgoto fail_existing_attributes;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"existing property is not configurable but \"\n\t\t\t                     \"is plain, enumerable, and writable -> \"\n\t\t\t                     \"allow redeclaration\"));\n\t\t}\n\n\t\tif (holder == ref.holder) {\n\t\t\t/* XXX: if duk_hobject_define_property_internal() was updated\n\t\t\t * to handle a pre-existing accessor property, this would be\n\t\t\t * a simple call (like for the ancestor case).\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"redefine, offending property in global object itself\"));\n\n\t\t\tif (flags & DUK_PROPDESC_FLAG_ACCESSOR) {\n\t\t\t\tduk_hobject *tmp;\n\n\t\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_GETTER(thr->heap, holder, e_idx);\n\t\t\t\tDUK_HOBJECT_E_SET_VALUE_GETTER(thr->heap, holder, e_idx, NULL);\n\t\t\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);\n\t\t\t\tDUK_UNREF(tmp);\n\t\t\t\ttmp = DUK_HOBJECT_E_GET_VALUE_SETTER(thr->heap, holder, e_idx);\n\t\t\t\tDUK_HOBJECT_E_SET_VALUE_SETTER(thr->heap, holder, e_idx, NULL);\n\t\t\t\tDUK_HOBJECT_DECREF_ALLOWNULL(thr, tmp);\n\t\t\t\tDUK_UNREF(tmp);\n\t\t\t} else {\n\t\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx);\n\t\t\t\tDUK_TVAL_SET_UNDEFINED_UPDREF(thr, tv);\n\t\t\t}\n\n\t\t\t/* Here val would be potentially invalid if we didn't make\n\t\t\t * a value copy at the caller.\n\t\t\t */\n\n\t\t\ttv = DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx);\n\t\t\tDUK_TVAL_SET_TVAL(tv, val);\n\t\t\tDUK_TVAL_INCREF(thr, tv);\n\t\t\tDUK_HOBJECT_E_SET_FLAGS(thr->heap, holder, e_idx, prop_flags);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"updated global binding, final result: \"\n\t\t\t                     \"value -> %!T, prop_flags=0x%08lx\",\n\t\t\t                     (duk_tval *) DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(thr->heap, holder, e_idx),\n\t\t\t                     (unsigned long) prop_flags));\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"redefine, offending property in ancestor\"));\n\n\t\t\tDUK_ASSERT(ref.holder == thr->builtins[DUK_BIDX_GLOBAL]);\n\t\t\tduk_push_tval(thr, val);\n\t\t\tduk_hobject_define_property_internal(thr, ref.holder, name, prop_flags);\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  Not found (in registers or record objects).  Declare\n\t *  to current variable environment.\n\t */\n\n\t/*\n\t *  Get holder object\n\t */\n\n\tif (DUK_HOBJECT_IS_DECENV(env)) {\n\t\tDUK_HDECENV_ASSERT_VALID((duk_hdecenv *) env);\n\t\tholder = env;\n\t} else {\n\t\tDUK_HOBJENV_ASSERT_VALID((duk_hobjenv *) env);\n\t\tholder = ((duk_hobjenv *) env)->target;\n\t\tDUK_ASSERT(holder != NULL);\n\t}\n\n\t/*\n\t *  Define new property\n\t *\n\t *  Note: this may fail if the holder is not extensible.\n\t */\n\n\t/* XXX: this is awkward as we use an internal method which doesn't handle\n\t * extensibility etc correctly.  Basically we'd want to do a [[DefineOwnProperty]]\n\t * or Object.defineProperty() here.\n\t */\n\n\tif (!DUK_HOBJECT_HAS_EXTENSIBLE(holder)) {\n\t\tgoto fail_not_extensible;\n\t}\n\n\tduk_push_hobject(thr, holder);\n\tduk_push_hstring(thr, name);\n\tduk_push_tval(thr, val);\n\tduk_xdef_prop(thr, -3, prop_flags);  /* [holder name val] -> [holder] */\n\tduk_pop_unsafe(thr);\n\n\treturn 0;\n\n fail_existing_attributes:\n fail_not_extensible:\n\tDUK_ERROR_TYPE(thr, \"declaration failed\");\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_INTERNAL\nduk_bool_t duk_js_declvar_activation(duk_hthread *thr,\n                                     duk_activation *act,\n                                     duk_hstring *name,\n                                     duk_tval *val,\n                                     duk_small_uint_t prop_flags,\n                                     duk_bool_t is_func_decl) {\n\tduk_hobject *env;\n\tduk_tval tv_val_copy;\n\n\tDUK_ASSERT(act != NULL);\n\n\t/*\n\t *  Make a value copy of the input val.  This ensures that\n\t *  side effects cannot invalidate the pointer.\n\t */\n\n\tDUK_TVAL_SET_TVAL(&tv_val_copy, val);\n\tval = &tv_val_copy;\n\n\t/*\n\t *  Delayed env creation check\n\t */\n\n\tif (!act->var_env) {\n\t\tDUK_ASSERT(act->lex_env == NULL);\n\t\tduk_js_init_activation_environment_records_delayed(thr, act);\n\t\t/* 'act' is a stable pointer, so still OK. */\n\t}\n\tDUK_ASSERT(act->lex_env != NULL);\n\tDUK_ASSERT(act->var_env != NULL);\n\n\tenv = act->var_env;\n\tDUK_ASSERT(env != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_IS_ENV(env));\n\n\treturn duk__declvar_helper(thr, env, name, val, prop_flags, is_func_decl);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_json.h",
    "content": "/*\n *  Defines for JSON, especially duk_bi_json.c.\n */\n\n#if !defined(DUK_JSON_H_INCLUDED)\n#define DUK_JSON_H_INCLUDED\n\n/* Encoding/decoding flags */\n#define DUK_JSON_FLAG_ASCII_ONLY              (1U << 0)  /* escape any non-ASCII characters */\n#define DUK_JSON_FLAG_AVOID_KEY_QUOTES        (1U << 1)  /* avoid key quotes when key is an ASCII Identifier */\n#define DUK_JSON_FLAG_EXT_CUSTOM              (1U << 2)  /* extended types: custom encoding */\n#define DUK_JSON_FLAG_EXT_COMPATIBLE          (1U << 3)  /* extended types: compatible encoding */\n\n/* How much stack to require on entry to object/array encode */\n#define DUK_JSON_ENC_REQSTACK                 32\n\n/* How much stack to require on entry to object/array decode */\n#define DUK_JSON_DEC_REQSTACK                 32\n\n/* How large a loop detection stack to use */\n#define DUK_JSON_ENC_LOOPARRAY                64\n\n/* Encoding state.  Heap object references are all borrowed. */\ntypedef struct {\n\tduk_hthread *thr;\n\tduk_bufwriter_ctx bw;        /* output bufwriter */\n\tduk_hobject *h_replacer;     /* replacer function */\n\tduk_hstring *h_gap;          /* gap (if empty string, NULL) */\n\tduk_idx_t idx_proplist;      /* explicit PropertyList */\n\tduk_idx_t idx_loop;          /* valstack index of loop detection object */\n\tduk_small_uint_t flags;\n\tduk_small_uint_t flag_ascii_only;\n\tduk_small_uint_t flag_avoid_key_quotes;\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tduk_small_uint_t flag_ext_custom;\n\tduk_small_uint_t flag_ext_compatible;\n\tduk_small_uint_t flag_ext_custom_or_compatible;\n#endif\n\tduk_uint_t recursion_depth;\n\tduk_uint_t recursion_limit;\n\tduk_uint_t mask_for_undefined;      /* type bit mask: types which certainly produce 'undefined' */\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tduk_small_uint_t stridx_custom_undefined;\n\tduk_small_uint_t stridx_custom_nan;\n\tduk_small_uint_t stridx_custom_neginf;\n\tduk_small_uint_t stridx_custom_posinf;\n\tduk_small_uint_t stridx_custom_function;\n#endif\n\tduk_hobject *visiting[DUK_JSON_ENC_LOOPARRAY];  /* indexed by recursion_depth */\n} duk_json_enc_ctx;\n\ntypedef struct {\n\tduk_hthread *thr;\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_start;\n\tconst duk_uint8_t *p_end;\n\tduk_idx_t idx_reviver;\n\tduk_small_uint_t flags;\n#if defined(DUK_USE_JX) || defined(DUK_USE_JC)\n\tduk_small_uint_t flag_ext_custom;\n\tduk_small_uint_t flag_ext_compatible;\n\tduk_small_uint_t flag_ext_custom_or_compatible;\n#endif\n\tduk_int_t recursion_depth;\n\tduk_int_t recursion_limit;\n} duk_json_dec_ctx;\n\n#endif  /* DUK_JSON_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_lexer.c",
    "content": "/*\n *  Lexer for source files, ToNumber() string conversions, RegExp expressions,\n *  and JSON.\n *\n *  Provides a stream of ECMAScript tokens from an UTF-8/CESU-8 buffer.  The\n *  caller can also rewind the token stream into a certain position which is\n *  needed by the compiler part for multi-pass scanning.  Tokens are\n *  represented as duk_token structures, and contain line number information.\n *  Token types are identified with DUK_TOK_* defines.\n *\n *  Characters are decoded into a fixed size lookup window consisting of\n *  decoded Unicode code points, with window positions past the end of the\n *  input filled with an invalid codepoint (-1).  The tokenizer can thus\n *  perform multiple character lookups efficiently and with few sanity\n *  checks (such as access outside the end of the input), which keeps the\n *  tokenization code small at the cost of performance.\n *\n *  Character data in tokens, such as identifier names and string literals,\n *  is encoded into CESU-8 format on-the-fly while parsing the token in\n *  question.  The string data is made reachable to garbage collection by\n *  placing the token-related values in value stack entries allocated for\n *  this purpose by the caller.  The characters exist in Unicode code point\n *  form only in the fixed size lookup window, which keeps character data\n *  expansion (of especially ASCII data) low.\n *\n *  Token parsing supports the full range of Unicode characters as described\n *  in the E5 specification.  Parsing has been optimized for ASCII characters\n *  because ordinary ECMAScript code consists almost entirely of ASCII\n *  characters.  Matching of complex Unicode codepoint sets (such as in the\n *  IdentifierStart and IdentifierPart productions) is optimized for size,\n *  and is done using a linear scan of a bit-packed list of ranges.  This is\n *  very slow, but should never be entered unless the source code actually\n *  contains Unicode characters.\n *\n *  ECMAScript tokenization is partially context sensitive.  First,\n *  additional future reserved words are recognized in strict mode (see E5\n *  Section 7.6.1.2).  Second, a forward slash character ('/') can be\n *  recognized either as starting a RegExp literal or as a division operator,\n *  depending on context.  The caller must provide necessary context flags\n *  when requesting a new token.\n *\n *  Future work:\n *\n *    * Make line number tracking optional, as it consumes space.\n *\n *    * Add a feature flag for disabling UTF-8 decoding of input, as most\n *      source code is ASCII.  Because of Unicode escapes written in ASCII,\n *      this does not allow Unicode support to be removed from e.g.\n *      duk_unicode_is_identifier_start() nor does it allow removal of CESU-8\n *      encoding of e.g. string literals.\n *\n *    * Add a feature flag for disabling Unicode compliance of e.g. identifier\n *      names.  This allows for a build more than a kilobyte smaller, because\n *      Unicode ranges needed by duk_unicode_is_identifier_start() and\n *      duk_unicode_is_identifier_part() can be dropped.  String literals\n *      should still be allowed to contain escaped Unicode, so this still does\n *      not allow removal of CESU-8 encoding of e.g. string literals.\n *\n *    * Character lookup tables for codepoints above BMP could be stripped.\n *\n *    * Strictly speaking, E5 specification requires that source code consists\n *      of 16-bit code units, and if not, must be conceptually converted to\n *      that format first.  The current lexer processes Unicode code points\n *      and allows characters outside the BMP.  These should be converted to\n *      surrogate pairs while reading the source characters into the window,\n *      not after tokens have been formed (as is done now).  However, the fix\n *      is not trivial because two characters are decoded from one codepoint.\n *\n *    * Optimize for speed as well as size.  Large if-else ladders are (at\n *      least potentially) slow.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Various defines and file specific helper macros\n */\n\n#define DUK__MAX_RE_DECESC_DIGITS     9\n#define DUK__MAX_RE_QUANT_DIGITS      9   /* Does not allow e.g. 2**31-1, but one more would allow overflows of u32. */\n\n/* whether to use macros or helper function depends on call count */\n#define DUK__ISDIGIT(x)          ((x) >= DUK_ASC_0 && (x) <= DUK_ASC_9)\n#define DUK__ISHEXDIGIT(x)       duk__is_hex_digit((x))\n#define DUK__ISOCTDIGIT(x)       ((x) >= DUK_ASC_0 && (x) <= DUK_ASC_7)\n#define DUK__ISDIGIT03(x)        ((x) >= DUK_ASC_0 && (x) <= DUK_ASC_3)\n#define DUK__ISDIGIT47(x)        ((x) >= DUK_ASC_4 && (x) <= DUK_ASC_7)\n\n/* lexer character window helpers */\n#define DUK__LOOKUP(lex_ctx,idx)            ((lex_ctx)->window[(idx)].codepoint)\n#define DUK__ADVANCECHARS(lex_ctx,count)    duk__advance_chars((lex_ctx), (count))\n#define DUK__ADVANCEBYTES(lex_ctx,count)    duk__advance_bytes((lex_ctx), (count))\n#define DUK__INITBUFFER(lex_ctx)            duk__initbuffer((lex_ctx))\n#define DUK__APPENDBUFFER(lex_ctx,x)        duk__appendbuffer((lex_ctx), (duk_codepoint_t) (x))\n#define DUK__APPENDBUFFER_ASCII(lex_ctx,x)  duk__appendbuffer_ascii((lex_ctx), (duk_codepoint_t) (x))\n\n/* lookup shorthands (note: assume context variable is named 'lex_ctx') */\n#define DUK__L0()  DUK__LOOKUP(lex_ctx, 0)\n#define DUK__L1()  DUK__LOOKUP(lex_ctx, 1)\n#define DUK__L2()  DUK__LOOKUP(lex_ctx, 2)\n#define DUK__L3()  DUK__LOOKUP(lex_ctx, 3)\n#define DUK__L4()  DUK__LOOKUP(lex_ctx, 4)\n#define DUK__L5()  DUK__LOOKUP(lex_ctx, 5)\n\n/* packed advance/token number macro used by multiple functions */\n#define DUK__ADVTOK(advbytes,tok)  ((((advbytes) * sizeof(duk_lexer_codepoint)) << 8) + (tok))\n\n/*\n *  Advance lookup window by N characters, filling in new characters as\n *  necessary.  After returning caller is guaranteed a character window of\n *  at least DUK_LEXER_WINDOW_SIZE characters.\n *\n *  The main function duk__advance_bytes() is called at least once per every\n *  token so it has a major lexer/compiler performance impact.  There are two\n *  variants for the main duk__advance_bytes() algorithm: a sliding window\n *  approach which is slightly faster at the cost of larger code footprint,\n *  and a simple copying one.\n *\n *  Decoding directly from the source string would be another lexing option.\n *  But the lookup window based approach has the advantage of hiding the\n *  source string and its encoding effectively which gives more flexibility\n *  going forward to e.g. support chunked streaming of source from flash.\n *\n *  Decodes UTF-8/CESU-8 leniently with support for code points from U+0000 to\n *  U+10FFFF, causing an error if the input is unparseable.  Leniency means:\n *\n *    * Unicode code point validation is intentionally not performed,\n *      except to check that the codepoint does not exceed 0x10ffff.\n *\n *    * In particular, surrogate pairs are allowed and not combined, which\n *      allows source files to represent all SourceCharacters with CESU-8.\n *      Broken surrogate pairs are allowed, as ECMAScript does not mandate\n *      their validation.\n *\n *    * Allow non-shortest UTF-8 encodings.\n *\n *  Leniency here causes few security concerns because all character data is\n *  decoded into Unicode codepoints before lexer processing, and is then\n *  re-encoded into CESU-8.  The source can be parsed as strict UTF-8 with\n *  a compiler option.  However, ECMAScript source characters include -all-\n *  16-bit unsigned integer codepoints, so leniency seems to be appropriate.\n *\n *  Note that codepoints above the BMP are not strictly SourceCharacters,\n *  but the lexer still accepts them as such.  Before ending up in a string\n *  or an identifier name, codepoints above BMP are converted into surrogate\n *  pairs and then CESU-8 encoded, resulting in 16-bit Unicode data as\n *  expected by ECMAScript.\n *\n *  An alternative approach to dealing with invalid or partial sequences\n *  would be to skip them and replace them with e.g. the Unicode replacement\n *  character U+FFFD.  This has limited utility because a replacement character\n *  will most likely cause a parse error, unless it occurs inside a string.\n *  Further, ECMAScript source is typically pure ASCII.\n *\n *  See:\n *\n *     http://en.wikipedia.org/wiki/UTF-8\n *     http://en.wikipedia.org/wiki/CESU-8\n *     http://tools.ietf.org/html/rfc3629\n *     http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences\n *\n *  Future work:\n *\n *    * Reject other invalid Unicode sequences (see Wikipedia entry for examples)\n *      in strict UTF-8 mode.\n *\n *    * Size optimize.  An attempt to use a 16-byte lookup table for the first\n *      byte resulted in a code increase though.\n *\n *    * Is checking against maximum 0x10ffff really useful?  4-byte encoding\n *      imposes a certain limit anyway.\n *\n *    * Support chunked streaming of source code.  Can be implemented either\n *      by streaming chunks of bytes or chunks of codepoints.\n */\n\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\nDUK_LOCAL void duk__fill_lexer_buffer(duk_lexer_ctx *lex_ctx, duk_small_uint_t start_offset_bytes) {\n\tduk_lexer_codepoint *cp, *cp_end;\n\tduk_ucodepoint_t x;\n\tduk_small_uint_t contlen;\n\tconst duk_uint8_t *p, *p_end;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\tduk_ucodepoint_t mincp;\n#endif\n\tduk_int_t input_line;\n\n\t/* Use temporaries and update lex_ctx only when finished. */\n\tinput_line = lex_ctx->input_line;\n\tp = lex_ctx->input + lex_ctx->input_offset;\n\tp_end = lex_ctx->input + lex_ctx->input_length;\n\n\tcp = (duk_lexer_codepoint *) (void *) ((duk_uint8_t *) lex_ctx->buffer + start_offset_bytes);\n\tcp_end = lex_ctx->buffer + DUK_LEXER_BUFFER_SIZE;\n\n\tfor (; cp != cp_end; cp++) {\n\t\tcp->offset = (duk_size_t) (p - lex_ctx->input);\n\t\tcp->line = input_line;\n\n\t\t/* XXX: potential issue with signed pointers, p_end < p. */\n\t\tif (DUK_UNLIKELY(p >= p_end)) {\n\t\t\t/* If input_offset were assigned a negative value, it would\n\t\t\t * result in a large positive value.  Most likely it would be\n\t\t\t * larger than input_length and be caught here.  In any case\n\t\t\t * no memory unsafe behavior would happen.\n\t\t\t */\n\t\t\tcp->codepoint = -1;\n\t\t\tcontinue;\n\t\t}\n\n\t\tx = (duk_ucodepoint_t) (*p++);\n\n\t\t/* Fast path. */\n\n\t\tif (DUK_LIKELY(x < 0x80UL)) {\n\t\t\tDUK_ASSERT(x != 0x2028UL && x != 0x2029UL);  /* not LS/PS */\n\t\t\tif (DUK_UNLIKELY(x <= 0x000dUL)) {\n\t\t\t\tif ((x == 0x000aUL) ||\n\t\t\t\t    ((x == 0x000dUL) && (p >= p_end || *p != 0x000aUL))) {\n\t\t\t\t\t/* lookup for 0x000a above assumes shortest encoding now */\n\n\t\t\t\t\t/* E5 Section 7.3, treat the following as newlines:\n\t\t\t\t\t *   LF\n\t\t\t\t\t *   CR [not followed by LF]\n\t\t\t\t\t *   LS\n\t\t\t\t\t *   PS\n\t\t\t\t\t *\n\t\t\t\t\t * For CR LF, CR is ignored if it is followed by LF, and the LF will bump\n\t\t\t\t\t * the line number.\n\t\t\t\t\t */\n\t\t\t\t\tinput_line++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcp->codepoint = (duk_codepoint_t) x;\n\t\t\tcontinue;\n\t\t}\n\n\t\t/* Slow path. */\n\n\t\tif (x < 0xc0UL) {\n\t\t\t/* 10xx xxxx -> invalid */\n\t\t\tgoto error_encoding;\n\t\t} else if (x < 0xe0UL) {\n\t\t\t/* 110x xxxx   10xx xxxx  */\n\t\t\tcontlen = 1;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\t\tmincp = 0x80UL;\n#endif\n\t\t\tx = x & 0x1fUL;\n\t\t} else if (x < 0xf0UL) {\n\t\t\t/* 1110 xxxx   10xx xxxx   10xx xxxx */\n\t\t\tcontlen = 2;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\t\tmincp = 0x800UL;\n#endif\n\t\t\tx = x & 0x0fUL;\n\t\t} else if (x < 0xf8UL) {\n\t\t\t/* 1111 0xxx   10xx xxxx   10xx xxxx   10xx xxxx */\n\t\t\tcontlen = 3;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\t\tmincp = 0x10000UL;\n#endif\n\t\t\tx = x & 0x07UL;\n\t\t} else {\n\t\t\t/* no point in supporting encodings of 5 or more bytes */\n\t\t\tgoto error_encoding;\n\t\t}\n\n\t\tDUK_ASSERT(p_end >= p);\n\t\tif ((duk_size_t) contlen > (duk_size_t) (p_end - p)) {\n\t\t\tgoto error_clipped;\n\t\t}\n\n\t\twhile (contlen > 0) {\n\t\t\tduk_small_uint_t y;\n\t\t\ty = *p++;\n\t\t\tif ((y & 0xc0U) != 0x80U) {\n\t\t\t\t/* check that byte has the form 10xx xxxx */\n\t\t\t\tgoto error_encoding;\n\t\t\t}\n\t\t\tx = x << 6;\n\t\t\tx += y & 0x3fUL;\n\t\t\tcontlen--;\n\t\t}\n\n\t\t/* check final character validity */\n\n\t\tif (x > 0x10ffffUL) {\n\t\t\tgoto error_encoding;\n\t\t}\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tif (x < mincp || (x >= 0xd800UL && x <= 0xdfffUL) || x == 0xfffeUL) {\n\t\t\tgoto error_encoding;\n\t\t}\n#endif\n\n\t\tDUK_ASSERT(x != 0x000aUL && x != 0x000dUL);\n\t\tif ((x == 0x2028UL) || (x == 0x2029UL)) {\n\t\t\tinput_line++;\n\t\t}\n\n\t\tcp->codepoint = (duk_codepoint_t) x;\n\t}\n\n\tlex_ctx->input_offset = (duk_size_t) (p - lex_ctx->input);\n\tlex_ctx->input_line = input_line;\n\treturn;\n\n error_clipped:   /* clipped codepoint */\n error_encoding:  /* invalid codepoint encoding or codepoint */\n\tlex_ctx->input_offset = (duk_size_t) (p - lex_ctx->input);\n\tlex_ctx->input_line = input_line;\n\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_SOURCE_DECODE_FAILED);\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_LOCAL void duk__advance_bytes(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_bytes) {\n\tduk_small_uint_t used_bytes, avail_bytes;\n\n\tDUK_ASSERT_DISABLE(count_bytes >= 0);  /* unsigned */\n\tDUK_ASSERT(count_bytes <= (duk_small_uint_t) (DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint)));\n\tDUK_ASSERT(lex_ctx->window >= lex_ctx->buffer);\n\tDUK_ASSERT(lex_ctx->window < lex_ctx->buffer + DUK_LEXER_BUFFER_SIZE);\n\tDUK_ASSERT((duk_uint8_t *) lex_ctx->window + count_bytes <= (duk_uint8_t *) lex_ctx->buffer + DUK_LEXER_BUFFER_SIZE * sizeof(duk_lexer_codepoint));\n\n\t/* Zero 'count' is also allowed to make call sites easier.\n\t * Arithmetic in bytes generates better code in GCC.\n\t */\n\n\tlex_ctx->window = (duk_lexer_codepoint *) (void *) ((duk_uint8_t *) lex_ctx->window + count_bytes);  /* avoid multiply */\n\tused_bytes = (duk_small_uint_t) ((duk_uint8_t *) lex_ctx->window - (duk_uint8_t *) lex_ctx->buffer);\n\tavail_bytes = DUK_LEXER_BUFFER_SIZE * sizeof(duk_lexer_codepoint) - used_bytes;\n\tif (avail_bytes < (duk_small_uint_t) (DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint))) {\n\t\t/* Not enough data to provide a full window, so \"scroll\" window to\n\t\t * start of buffer and fill up the rest.\n\t\t */\n\t\tduk_memmove((void *) lex_ctx->buffer,\n\t\t            (const void *) lex_ctx->window,\n\t\t            (size_t) avail_bytes);\n\t\tlex_ctx->window = lex_ctx->buffer;\n\t\tduk__fill_lexer_buffer(lex_ctx, avail_bytes);\n\t}\n}\n\nDUK_LOCAL void duk__init_lexer_window(duk_lexer_ctx *lex_ctx) {\n\tlex_ctx->window = lex_ctx->buffer;\n\tduk__fill_lexer_buffer(lex_ctx, 0);\n}\n#else  /* DUK_USE_LEXER_SLIDING_WINDOW */\nDUK_LOCAL duk_codepoint_t duk__read_char(duk_lexer_ctx *lex_ctx) {\n\tduk_ucodepoint_t x;\n\tduk_small_uint_t len;\n\tduk_small_uint_t i;\n\tconst duk_uint8_t *p;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\tduk_ucodepoint_t mincp;\n#endif\n\tduk_size_t input_offset;\n\n\tinput_offset = lex_ctx->input_offset;\n\tif (DUK_UNLIKELY(input_offset >= lex_ctx->input_length)) {\n\t\t/* If input_offset were assigned a negative value, it would\n\t\t * result in a large positive value.  Most likely it would be\n\t\t * larger than input_length and be caught here.  In any case\n\t\t * no memory unsafe behavior would happen.\n\t\t */\n\t\treturn -1;\n\t}\n\n\tp = lex_ctx->input + input_offset;\n\tx = (duk_ucodepoint_t) (*p);\n\n\tif (DUK_LIKELY(x < 0x80UL)) {\n\t\t/* 0xxx xxxx -> fast path */\n\n\t\t/* input offset tracking */\n\t\tlex_ctx->input_offset++;\n\n\t\tDUK_ASSERT(x != 0x2028UL && x != 0x2029UL);  /* not LS/PS */\n\t\tif (DUK_UNLIKELY(x <= 0x000dUL)) {\n\t\t\tif ((x == 0x000aUL) ||\n\t\t\t    ((x == 0x000dUL) && (lex_ctx->input_offset >= lex_ctx->input_length ||\n\t\t\t                         lex_ctx->input[lex_ctx->input_offset] != 0x000aUL))) {\n\t\t\t\t/* lookup for 0x000a above assumes shortest encoding now */\n\n\t\t\t\t/* E5 Section 7.3, treat the following as newlines:\n\t\t\t\t *   LF\n\t\t\t\t *   CR [not followed by LF]\n\t\t\t\t *   LS\n\t\t\t\t *   PS\n\t\t\t\t *\n\t\t\t\t * For CR LF, CR is ignored if it is followed by LF, and the LF will bump\n\t\t\t\t * the line number.\n\t\t\t\t */\n\t\t\t\tlex_ctx->input_line++;\n\t\t\t}\n\t\t}\n\n\t\treturn (duk_codepoint_t) x;\n\t}\n\n\t/* Slow path. */\n\n\tif (x < 0xc0UL) {\n\t\t/* 10xx xxxx -> invalid */\n\t\tgoto error_encoding;\n\t} else if (x < 0xe0UL) {\n\t\t/* 110x xxxx   10xx xxxx  */\n\t\tlen = 2;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tmincp = 0x80UL;\n#endif\n\t\tx = x & 0x1fUL;\n\t} else if (x < 0xf0UL) {\n\t\t/* 1110 xxxx   10xx xxxx   10xx xxxx */\n\t\tlen = 3;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tmincp = 0x800UL;\n#endif\n\t\tx = x & 0x0fUL;\n\t} else if (x < 0xf8UL) {\n\t\t/* 1111 0xxx   10xx xxxx   10xx xxxx   10xx xxxx */\n\t\tlen = 4;\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\t\tmincp = 0x10000UL;\n#endif\n\t\tx = x & 0x07UL;\n\t} else {\n\t\t/* no point in supporting encodings of 5 or more bytes */\n\t\tgoto error_encoding;\n\t}\n\n\tDUK_ASSERT(lex_ctx->input_length >= lex_ctx->input_offset);\n\tif ((duk_size_t) len > (duk_size_t) (lex_ctx->input_length - lex_ctx->input_offset)) {\n\t\tgoto error_clipped;\n\t}\n\n\tp++;\n\tfor (i = 1; i < len; i++) {\n\t\tduk_small_uint_t y;\n\t\ty = *p++;\n\t\tif ((y & 0xc0U) != 0x80U) {\n\t\t\t/* check that byte has the form 10xx xxxx */\n\t\t\tgoto error_encoding;\n\t\t}\n\t\tx = x << 6;\n\t\tx += y & 0x3fUL;\n\t}\n\n\t/* check final character validity */\n\n\tif (x > 0x10ffffUL) {\n\t\tgoto error_encoding;\n\t}\n#if defined(DUK_USE_STRICT_UTF8_SOURCE)\n\tif (x < mincp || (x >= 0xd800UL && x <= 0xdfffUL) || x == 0xfffeUL) {\n\t\tgoto error_encoding;\n\t}\n#endif\n\n\t/* input offset tracking */\n\tlex_ctx->input_offset += len;\n\n\t/* line tracking */\n\tDUK_ASSERT(x != 0x000aUL && x != 0x000dUL);\n\tif ((x == 0x2028UL) || (x == 0x2029UL)) {\n\t\tlex_ctx->input_line++;\n\t}\n\n\treturn (duk_codepoint_t) x;\n\n error_clipped:   /* clipped codepoint */\n error_encoding:  /* invalid codepoint encoding or codepoint */\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_SOURCE_DECODE_FAILED);\n\tDUK_WO_NORETURN(return 0;);\n}\n\nDUK_LOCAL void duk__advance_bytes(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_bytes) {\n\tduk_small_uint_t keep_bytes;\n\tduk_lexer_codepoint *cp, *cp_end;\n\n\tDUK_ASSERT_DISABLE(count_bytes >= 0);  /* unsigned */\n\tDUK_ASSERT(count_bytes <= (duk_small_uint_t) (DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint)));\n\n\t/* Zero 'count' is also allowed to make call sites easier. */\n\n\tkeep_bytes = DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint) - count_bytes;\n\tduk_memmove((void *) lex_ctx->window,\n\t            (const void *) ((duk_uint8_t *) lex_ctx->window + count_bytes),\n\t            (size_t) keep_bytes);\n\n\tcp = (duk_lexer_codepoint *) ((duk_uint8_t *) lex_ctx->window + keep_bytes);\n\tcp_end = lex_ctx->window + DUK_LEXER_WINDOW_SIZE;\n\tfor (; cp != cp_end; cp++) {\n\t\tcp->offset = lex_ctx->input_offset;\n\t\tcp->line = lex_ctx->input_line;\n\t\tcp->codepoint = duk__read_char(lex_ctx);\n\t}\n}\n\nDUK_LOCAL void duk__init_lexer_window(duk_lexer_ctx *lex_ctx) {\n\t/* Call with count == DUK_LEXER_WINDOW_SIZE to fill buffer initially. */\n\tduk__advance_bytes(lex_ctx, DUK_LEXER_WINDOW_SIZE * sizeof(duk_lexer_codepoint));  /* fill window */\n}\n#endif  /* DUK_USE_LEXER_SLIDING_WINDOW */\n\nDUK_LOCAL void duk__advance_chars(duk_lexer_ctx *lex_ctx, duk_small_uint_t count_chars) {\n\tduk__advance_bytes(lex_ctx, count_chars * sizeof(duk_lexer_codepoint));\n}\n\n/*\n *  (Re)initialize the temporary byte buffer.  May be called extra times\n *  with little impact.\n */\n\nDUK_LOCAL void duk__initbuffer(duk_lexer_ctx *lex_ctx) {\n\t/* Reuse buffer as is unless buffer has grown large. */\n\tif (DUK_HBUFFER_DYNAMIC_GET_SIZE(lex_ctx->buf) < DUK_LEXER_TEMP_BUF_LIMIT) {\n\t\t/* Keep current size */\n\t} else {\n\t\tduk_hbuffer_resize(lex_ctx->thr, lex_ctx->buf, DUK_LEXER_TEMP_BUF_LIMIT);\n\t}\n\n\tDUK_BW_INIT_WITHBUF(lex_ctx->thr, &lex_ctx->bw, lex_ctx->buf);\n}\n\n/*\n *  Append a Unicode codepoint to the temporary byte buffer.  Performs\n *  CESU-8 surrogate pair encoding for codepoints above the BMP.\n *  Existing surrogate pairs are allowed and also encoded into CESU-8.\n */\n\nDUK_LOCAL void duk__appendbuffer(duk_lexer_ctx *lex_ctx, duk_codepoint_t x) {\n\t/*\n\t *  Since character data is only generated by decoding the source or by\n\t *  the compiler itself, we rely on the input codepoints being correct\n\t *  and avoid a check here.\n\t *\n\t *  Character data can also come here through decoding of Unicode\n\t *  escapes (\"\\udead\\ubeef\") so all 16-but unsigned values can be\n\t *  present, even when the source file itself is strict UTF-8.\n\t */\n\tDUK_ASSERT(x >= 0 && x <= 0x10ffffL);\n\n\tDUK_BW_WRITE_ENSURE_CESU8(lex_ctx->thr, &lex_ctx->bw, (duk_ucodepoint_t) x);\n}\n\nDUK_LOCAL void duk__appendbuffer_ascii(duk_lexer_ctx *lex_ctx, duk_codepoint_t x) {\n\t/* ASCII characters can be emitted as a single byte without encoding\n\t * which matters for some fast paths.\n\t */\n\tDUK_ASSERT(x >= 0 && x <= 0x7f);\n\n\tDUK_BW_WRITE_ENSURE_U8(lex_ctx->thr, &lex_ctx->bw, (duk_uint8_t) x);\n}\n\n/*\n *  Intern the temporary byte buffer into a valstack slot\n *  (in practice, slot1 or slot2).\n */\n\nDUK_LOCAL duk_hstring *duk__internbuffer(duk_lexer_ctx *lex_ctx, duk_idx_t valstack_idx) {\n\tDUK_ASSERT(valstack_idx == lex_ctx->slot1_idx || valstack_idx == lex_ctx->slot2_idx);\n\n\tDUK_BW_PUSH_AS_STRING(lex_ctx->thr, &lex_ctx->bw);\n\tduk_replace(lex_ctx->thr, valstack_idx);\n\treturn duk_known_hstring(lex_ctx->thr, valstack_idx);\n}\n\n/*\n *  Init lexer context\n */\n\nDUK_INTERNAL void duk_lexer_initctx(duk_lexer_ctx *lex_ctx) {\n\tDUK_ASSERT(lex_ctx != NULL);\n\n\tduk_memzero(lex_ctx, sizeof(*lex_ctx));\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\n\tlex_ctx->window = NULL;\n#endif\n\tlex_ctx->thr = NULL;\n\tlex_ctx->input = NULL;\n\tlex_ctx->buf = NULL;\n#endif\n}\n\n/*\n *  Set lexer input position and reinitialize lookup window.\n */\n\nDUK_INTERNAL void duk_lexer_getpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt) {\n\tpt->offset = lex_ctx->window[0].offset;\n\tpt->line = lex_ctx->window[0].line;\n}\n\nDUK_INTERNAL void duk_lexer_setpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt) {\n\tDUK_ASSERT_DISABLE(pt->offset >= 0);  /* unsigned */\n\tDUK_ASSERT(pt->line >= 1);\n\tlex_ctx->input_offset = pt->offset;\n\tlex_ctx->input_line = pt->line;\n\tduk__init_lexer_window(lex_ctx);\n}\n\n/*\n *  Lexing helpers\n */\n\n/* Numeric value of a hex digit (also covers octal and decimal digits) or\n * -1 if not a valid hex digit.\n */\nDUK_LOCAL duk_codepoint_t duk__hexval_validate(duk_codepoint_t x) {\n\tduk_small_int_t t;\n\n\t/* Here 'x' is a Unicode codepoint */\n\tif (DUK_LIKELY(x >= 0 && x <= 0xff)) {\n\t\tt = duk_hex_dectab[x];\n\t\tif (DUK_LIKELY(t >= 0)) {\n\t\t\treturn t;\n\t\t}\n\t}\n\n\treturn -1;\n}\n\n/* Just a wrapper for call sites where 'x' is known to be valid so\n * we assert for it before decoding.\n */\nDUK_LOCAL duk_codepoint_t duk__hexval(duk_codepoint_t x) {\n\tduk_codepoint_t ret;\n\n\tDUK_ASSERT((x >= DUK_ASC_0 && x <= DUK_ASC_9) ||\n\t           (x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_F) ||\n\t           (x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_F));\n\tret = duk__hexval_validate(x);\n\tDUK_ASSERT(ret >= 0 && ret <= 15);\n\treturn ret;\n}\n\n/* having this as a separate function provided a size benefit */\nDUK_LOCAL duk_bool_t duk__is_hex_digit(duk_codepoint_t x) {\n\tif (DUK_LIKELY(x >= 0 && x <= 0xff)) {\n\t\treturn (duk_hex_dectab[x] >= 0);\n\t}\n\treturn 0;\n}\n\n/* Parse a Unicode escape of the form \\xHH, \\uHHHH, or \\u{H+}.  Shared by\n * source and RegExp parsing.\n */\nDUK_LOCAL duk_codepoint_t duk__lexer_parse_escape(duk_lexer_ctx *lex_ctx, duk_bool_t allow_es6) {\n\tduk_small_int_t digits;  /* Initial value 2 or 4 for fixed length escapes, 0 for ES2015 \\u{H+}. */\n\tduk_codepoint_t escval;\n\tduk_codepoint_t x;\n\tduk_small_uint_t adv;\n\n\tDUK_ASSERT(DUK__L0() == DUK_ASC_BACKSLASH);  /* caller responsibilities */\n\tDUK_ASSERT(DUK__L1() == DUK_ASC_LC_X || DUK__L1() == DUK_ASC_LC_U);\n\tDUK_UNREF(allow_es6);\n\n\tadv = 2;\n\tdigits = 2;\n\tif (DUK__L1() == DUK_ASC_LC_U) {\n\t\tdigits = 4;\n#if defined(DUK_USE_ES6_UNICODE_ESCAPE)\n\t\tif (DUK__L2() == DUK_ASC_LCURLY && allow_es6) {\n\t\t\tdigits = 0;\n\t\t\tadv = 3;\n\t\t}\n#endif\n\t}\n\tDUK__ADVANCECHARS(lex_ctx, adv);\n\n\tescval = 0;\n\tfor (;;) {\n\t\t/* One of the escape forms: \\xHH, \\uHHHH, \\u{H+}.\n\t\t * The 'digits' variable tracks parsing state and is\n\t\t * initialized to:\n\t\t *\n\t\t *   \\xHH     2\n\t\t *   \\uHH     4\n\t\t *   \\u{H+}   0 first time, updated to -1 to indicate\n\t\t *            at least one digit has been parsed\n\t\t *\n\t\t * Octal parsing is handled separately because it can be\n\t\t * done with fixed lookahead and also has validation\n\t\t * rules which depend on the escape length (which is\n\t\t * variable).\n\t\t *\n\t\t * We don't need a specific check for x < 0 (end of\n\t\t * input) or duk_unicode_is_line_terminator(x)\n\t\t * because the 'dig' decode will fail and lead to a\n\t\t * SyntaxError.\n\t\t */\n\t\tduk_codepoint_t dig;\n\n\t\tx = DUK__L0();\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\n\t\tdig = duk__hexval_validate(x);\n\t\tif (digits > 0) {\n\t\t\tdigits--;\n\t\t\tif (dig < 0) {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t\tDUK_ASSERT(dig >= 0x00 && dig <= 0x0f);\n\t\t\tescval = (escval << 4) + dig;\n\t\t\tif (digits == 0) {\n\t\t\t\tDUK_ASSERT(escval >= 0 && escval <= 0xffffL);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n#if defined(DUK_USE_ES6_UNICODE_ESCAPE)\n\t\t\tDUK_ASSERT(digits == 0 /* first time */ || digits == -1 /* others */);\n\t\t\tif (dig >= 0) {\n\t\t\t\tDUK_ASSERT(dig >= 0x00 && dig <= 0x0f);\n\t\t\t\tescval = (escval << 4) + dig;\n\t\t\t\tif (escval > 0x10ffffL) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_RCURLY) {\n\t\t\t\tif (digits == 0) {\n\t\t\t\t\t/* Empty escape, \\u{}. */\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(escval >= 0 && escval <= 0x10ffffL);\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t\tdigits = -1;  /* Indicate we have at least one digit. */\n#else  /* DUK_USE_ES6_UNICODE_ESCAPE */\n\t\t\tDUK_ASSERT(0);  /* Never happens if \\u{H+} support disabled. */\n#endif  /* DUK_USE_ES6_UNICODE_ESCAPE */\n\t\t}\n\t}\n\n\treturn escval;\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Parse legacy octal escape of the form \\N{1,3}, e.g. \\0, \\5, \\0377.  Maximum\n * allowed value is \\0377 (U+00FF), longest match is used.  Used for both string\n * RegExp octal escape parsing.  Window[0] must be the slash '\\' and the first\n * digit must already be validated to be in [0-9] by the caller.\n */\nDUK_LOCAL duk_codepoint_t duk__lexer_parse_legacy_octal(duk_lexer_ctx *lex_ctx, duk_small_uint_t *out_adv, duk_bool_t reject_annex_b) {\n\tduk_codepoint_t cp;\n\tduk_small_uint_t lookup_idx;\n\tduk_small_uint_t adv;\n\tduk_codepoint_t tmp;\n\n\tDUK_ASSERT(out_adv != NULL);\n\tDUK_ASSERT(DUK__LOOKUP(lex_ctx, 0) == DUK_ASC_BACKSLASH);\n\tDUK_ASSERT(DUK__LOOKUP(lex_ctx, 1) >= DUK_ASC_0 && DUK__LOOKUP(lex_ctx, 1) <= DUK_ASC_9);\n\n\tcp = 0;\n\ttmp = 0;\n\tfor (lookup_idx = 1; lookup_idx <= 3; lookup_idx++) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"lookup_idx=%ld, cp=%ld\", (long) lookup_idx, (long) cp));\n\t\ttmp = DUK__LOOKUP(lex_ctx, lookup_idx);\n\t\tif (tmp < DUK_ASC_0 || tmp > DUK_ASC_7) {\n\t\t\t/* No more valid digits. */\n\t\t\tbreak;\n\t\t}\n\t\ttmp = (cp << 3) + (tmp - DUK_ASC_0);\n\t\tif (tmp > 0xff) {\n\t\t\t/* Three digit octal escapes above \\377 (= 0xff)\n\t\t\t * are not allowed.\n\t\t\t */\n\t\t\tbreak;\n\t\t}\n\t\tcp = tmp;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"final lookup_idx=%ld, cp=%ld\", (long) lookup_idx, (long) cp));\n\n\tadv = lookup_idx;\n\tif (lookup_idx == 1) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"\\\\8 or \\\\9 -> treat as literal, accept in strict mode too\"));\n\t\tDUK_ASSERT(tmp == DUK_ASC_8 || tmp == DUK_ASC_9);\n\t\tcp = tmp;\n\t\tadv++;  /* correction to above, eat offending character */\n\t} else if (lookup_idx == 2 && cp == 0) {\n\t\t/* Note: 'foo\\0bar' is OK in strict mode, but 'foo\\00bar' is not.\n\t\t * It won't be interpreted as 'foo\\u{0}0bar' but as a SyntaxError.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"\\\\0 -> accept in strict mode too\"));\n\t} else {\n\t\t/* This clause also handles non-shortest zero, e.g. \\00. */\n\t\tif (reject_annex_b) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-zero octal literal %ld -> reject in strict-mode\", (long) cp));\n\t\t\tcp = -1;\n\t\t} else {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-zero octal literal %ld -> accepted\", (long) cp));\n\t\t\tDUK_ASSERT(cp >= 0 && cp <= 0xff);\n\t\t}\n\t}\n\n\t*out_adv = adv;\n\n\tDUK_ASSERT((cp >= 0 && cp <= 0xff) || (cp == -1 && reject_annex_b));\n\treturn cp;\n}\n\n/* XXX: move strict mode to lex_ctx? */\nDUK_LOCAL void duk__lexer_parse_string_literal(duk_lexer_ctx *lex_ctx, duk_token *out_token, duk_small_int_t quote, duk_bool_t strict_mode) {\n\tduk_small_uint_t adv;\n\n\tfor (adv = 1 /* initial quote */ ;;) {\n\t\tduk_codepoint_t x;\n\n\t\tDUK__ADVANCECHARS(lex_ctx, adv);  /* eat opening quote on first loop */\n\t\tx = DUK__L0();\n\n\t\tadv = 1;\n\t\tif (x == quote) {\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat closing quote */\n\t\t\tbreak;\n\t\t} else if (x == '\\\\') {\n\t\t\t/* DUK__L0        -> '\\' char\n\t\t\t * DUK__L1 ... DUK__L5 -> more lookup\n\t\t\t */\n\t\t\tduk_small_int_t emitcp = -1;\n\n\t\t\tx = DUK__L1();\n\n\t\t\t/* How much to advance before next loop. */\n\t\t\tadv = 2;  /* note: long live range */\n\n\t\t\tswitch (x) {\n\t\t\tcase '\\'':\n\t\t\t\temitcp = 0x0027;\n\t\t\t\tbreak;\n\t\t\tcase '\"':\n\t\t\t\temitcp = 0x0022;\n\t\t\t\tbreak;\n\t\t\tcase '\\\\':\n\t\t\t\temitcp = 0x005c;\n\t\t\t\tbreak;\n\t\t\tcase 'b':\n\t\t\t\temitcp = 0x0008;\n\t\t\t\tbreak;\n\t\t\tcase 'f':\n\t\t\t\temitcp = 0x000c;\n\t\t\t\tbreak;\n\t\t\tcase 'n':\n\t\t\t\temitcp = 0x000a;\n\t\t\t\tbreak;\n\t\t\tcase 'r':\n\t\t\t\temitcp = 0x000d;\n\t\t\t\tbreak;\n\t\t\tcase 't':\n\t\t\t\temitcp = 0x0009;\n\t\t\t\tbreak;\n\t\t\tcase 'v':\n\t\t\t\temitcp = 0x000b;\n\t\t\t\tbreak;\n\t\t\tcase 'x':\n\t\t\tcase 'u': {\n\t\t\t\tduk_codepoint_t esc_cp;\n\t\t\t\tesc_cp = duk__lexer_parse_escape(lex_ctx, 1 /*allow_es6*/);\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, esc_cp);\n\t\t\t\tadv = 0;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tif (duk_unicode_is_line_terminator(x)) {\n\t\t\t\t\t/* line continuation */\n\t\t\t\t\tif (x == 0x000d && DUK__L2() == 0x000a) {\n\t\t\t\t\t\t/* CR LF again a special case */\n\t\t\t\t\t\tadv = 3;  /* line terminator, CR, LF */\n\t\t\t\t\t}\n\t\t\t\t} else if (DUK__ISDIGIT(x)) {\n\t\t\t\t\t/*\n\t\t\t\t\t *  Octal escape or zero escape:\n\t\t\t\t\t *    \\0                                     (lookahead not OctalDigit)\n\t\t\t\t\t *    \\1 ... \\7                              (lookahead not OctalDigit)\n\t\t\t\t\t *    \\ZeroToThree OctalDigit                (lookahead not OctalDigit)\n\t\t\t\t\t *    \\FourToSeven OctalDigit                (no lookahead restrictions)\n\t\t\t\t\t *    \\ZeroToThree OctalDigit OctalDigit     (no lookahead restrictions)\n\t\t\t\t\t *\n\t\t\t\t\t *  Zero escape is part of the standard syntax.  Octal escapes are\n\t\t\t\t\t *  defined in E5 Section B.1.2, and are only allowed in non-strict mode.\n\t\t\t\t\t *  Any other productions starting with a decimal digit are invalid\n\t\t\t\t\t *  but are in practice treated like identity escapes.\n\t\t\t\t\t *\n\t\t\t\t\t *  Parse octal (up to 3 digits) from the lookup window.\n\t\t\t\t\t */\n\n\t\t\t\t\temitcp = duk__lexer_parse_legacy_octal(lex_ctx, &adv, strict_mode /*reject_annex_b*/);\n\t\t\t\t\tif (emitcp < 0) {\n\t\t\t\t\t\tgoto fail_escape;\n\t\t\t\t\t}\n\t\t\t\t} else if (x < 0) {\n\t\t\t\t\tgoto fail_unterminated;\n\t\t\t\t} else {\n\t\t\t\t\t/* escaped NonEscapeCharacter */\n\t\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t\t}\n\t\t\t}  /* end default clause */\n\t\t\t}  /* end switch */\n\n\t\t\t/* Shared handling for single codepoint escapes. */\n\t\t\tif (emitcp >= 0) {\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, emitcp);\n\t\t\t}\n\n\t\t\t/* Track number of escapes; count not really needed but directive\n\t\t\t * prologues need to detect whether there were any escapes or line\n\t\t\t * continuations or not.\n\t\t\t */\n\t\t\tout_token->num_escapes++;\n\t\t} else if (x >= 0x20 && x <= 0x7f) {\n\t\t\t/* Fast path for ASCII case, avoids line terminator\n\t\t\t * check and CESU-8 encoding.\n\t\t\t */\n\t\t\tDUK_ASSERT(x >= 0);\n\t\t\tDUK_ASSERT(!duk_unicode_is_line_terminator(x));\n\t\t\tDUK_ASSERT(x != quote);\n\t\t\tDUK_ASSERT(x != DUK_ASC_BACKSLASH);\n\t\t\tDUK__APPENDBUFFER_ASCII(lex_ctx, x);\n\t\t} else if (x < 0 || duk_unicode_is_line_terminator(x)) {\n\t\t\tgoto fail_unterminated;\n\t\t} else {\n\t\t\t/* Character which is part of the string but wasn't handled\n\t\t\t * by the fast path.\n\t\t\t */\n\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t}\n\t} /* string parse loop */\n\n\treturn;\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterminated:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_STRING);\n\tDUK_WO_NORETURN(return;);\n}\n\n/* Skip to end-of-line (or end-of-file), used for single line comments. */\nDUK_LOCAL void duk__lexer_skip_to_endofline(duk_lexer_ctx *lex_ctx) {\n\tfor (;;) {\n\t\tduk_codepoint_t x;\n\n\t\tx = DUK__L0();\n\t\tif (x < 0 || duk_unicode_is_line_terminator(x)) {\n\t\t\tbreak;\n\t\t}\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t}\n}\n\n/*\n *  Parse ECMAScript source InputElementDiv or InputElementRegExp\n *  (E5 Section 7), skipping whitespace, comments, and line terminators.\n *\n *  Possible results are:\n *    (1) a token\n *    (2) a line terminator (skipped)\n *    (3) a comment (skipped)\n *    (4) EOF\n *\n *  White space is automatically skipped from the current position (but\n *  not after the input element).  If input has already ended, returns\n *  DUK_TOK_EOF indefinitely.  If a parse error occurs, uses an DUK_ERROR()\n *  macro call (and hence a longjmp through current heap longjmp context).\n *  Comments and line terminator tokens are automatically skipped.\n *\n *  The input element being matched is determined by regexp_mode; if set,\n *  parses a InputElementRegExp, otherwise a InputElementDiv.  The\n *  difference between these are handling of productions starting with a\n *  forward slash.\n *\n *  If strict_mode is set, recognizes additional future reserved words\n *  specific to strict mode, and refuses to parse octal literals.\n *\n *  The matching strategy below is to (currently) use a six character\n *  lookup window to quickly determine which production is the -longest-\n *  matching one, and then parse that.  The top-level if-else clauses\n *  match the first character, and the code blocks for each clause\n *  handle -all- alternatives for that first character.  ECMAScript\n *  specification uses the \"longest match wins\" semantics, so the order\n *  of the if-clauses matters.\n *\n *  Misc notes:\n *\n *    * ECMAScript numeric literals do not accept a sign character.\n *      Consequently e.g. \"-1.0\" is parsed as two tokens: a negative\n *      sign and a positive numeric literal.  The compiler performs\n *      the negation during compilation, so this has no adverse impact.\n *\n *    * There is no token for \"undefined\": it is just a value available\n *      from the global object (or simply established by doing a reference\n *      to an undefined value).\n *\n *    * Some contexts want Identifier tokens, which are IdentifierNames\n *      excluding reserved words, while some contexts want IdentifierNames\n *      directly.  In the latter case e.g. \"while\" is interpreted as an\n *      identifier name, not a DUK_TOK_WHILE token.  The solution here is\n *      to provide both token types: DUK_TOK_WHILE goes to 't' while\n *      DUK_TOK_IDENTIFIER goes to 't_nores', and 'slot1' always contains\n *      the identifier / keyword name.\n *\n *    * Directive prologue needs to identify string literals such as\n *      \"use strict\" and 'use strict', which are sensitive to line\n *      continuations and escape sequences.  For instance, \"use\\u0020strict\"\n *      is a valid directive but is distinct from \"use strict\".  The solution\n *      here is to decode escapes while tokenizing, but to keep track of the\n *      number of escapes.  Directive detection can then check that the\n *      number of escapes is zero.\n *\n *    * Multi-line comments with one or more internal LineTerminator are\n *      treated like a line terminator to comply with automatic semicolon\n *      insertion.\n */\n\nDUK_INTERNAL\nvoid duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,\n                                      duk_token *out_token,\n                                      duk_bool_t strict_mode,\n                                      duk_bool_t regexp_mode) {\n\tduk_codepoint_t x;           /* temporary, must be signed and 32-bit to hold Unicode code points */\n\tduk_small_uint_t advtok = 0; /* (advance << 8) + token_type, updated at function end,\n\t                              * init is unnecessary but suppresses \"may be used uninitialized\" warnings.\n\t                              */\n\tduk_bool_t got_lineterm = 0;  /* got lineterm preceding non-whitespace, non-lineterm token */\n\n\tif (++lex_ctx->token_count >= lex_ctx->token_limit) {\n\t\tgoto fail_token_limit;\n\t}\n\n\tout_token->t = DUK_TOK_EOF;\n\tout_token->t_nores = DUK_TOK_INVALID;  /* marker: copy t if not changed */\n#if 0  /* not necessary to init, disabled for faster parsing */\n\tout_token->num = DUK_DOUBLE_NAN;\n\tout_token->str1 = NULL;\n\tout_token->str2 = NULL;\n#endif\n\tout_token->num_escapes = 0;\n\t/* out_token->lineterm set by caller */\n\n\t/* This would be nice, but parsing is faster without resetting the\n\t * value slots.  The only side effect is that references to temporary\n\t * string values may linger until lexing is finished; they're then\n\t * freed normally.\n\t */\n#if 0\n\tduk_to_undefined(lex_ctx->thr, lex_ctx->slot1_idx);\n\tduk_to_undefined(lex_ctx->thr, lex_ctx->slot2_idx);\n#endif\n\n\t/* 'advtok' indicates how much to advance and which token id to assign\n\t * at the end.  This shared functionality minimizes code size.  All\n\t * code paths are required to set 'advtok' to some value, so no default\n\t * init value is used.  Code paths calling DUK_ERROR() never return so\n\t * they don't need to set advtok.\n\t */\n\n\t/*\n\t *  Matching order:\n\t *\n\t *    Punctuator first chars, also covers comments, regexps\n\t *    LineTerminator\n\t *    Identifier or reserved word, also covers null/true/false literals\n\t *    NumericLiteral\n\t *    StringLiteral\n\t *    EOF\n\t *\n\t *  The order does not matter as long as the longest match is\n\t *  always correctly identified.  There are order dependencies\n\t *  in the clauses, so it's not trivial to convert to a switch.\n\t */\n\n restart_lineupdate:\n\tout_token->start_line = lex_ctx->window[0].line;\n\n restart:\n\tout_token->start_offset = lex_ctx->window[0].offset;\n\n\tx = DUK__L0();\n\n\tswitch (x) {\n\tcase DUK_ASC_SPACE:\n\tcase DUK_ASC_HT:  /* fast paths for space and tab */\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\tgoto restart;\n\tcase DUK_ASC_LF:  /* LF line terminator; CR LF and Unicode lineterms are handled in slow path */\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\tgot_lineterm = 1;\n\t\tgoto restart_lineupdate;\n#if defined(DUK_USE_SHEBANG_COMMENTS)\n\tcase DUK_ASC_HASH:  /* '#' */\n\t\tif (DUK__L1() == DUK_ASC_EXCLAMATION && lex_ctx->window[0].offset == 0 &&\n\t\t    (lex_ctx->flags & DUK_COMPILE_SHEBANG)) {\n\t\t\t/* \"Shebang\" comment ('#! ...') on first line. */\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 2) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t}\n\t\tgoto fail_token;\n#endif  /* DUK_USE_SHEBANG_COMMENTS */\n\tcase DUK_ASC_SLASH:  /* '/' */\n\t\tif (DUK__L1() == DUK_ASC_SLASH) {\n\t\t\t/*\n\t\t\t *  E5 Section 7.4, allow SourceCharacter (which is any 16-bit\n\t\t\t *  code point).\n\t\t\t */\n\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 2) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t} else if (DUK__L1() == DUK_ASC_STAR) {\n\t\t\t/*\n\t\t\t *  E5 Section 7.4.  If the multi-line comment contains a newline,\n\t\t\t *  it is treated like a single line terminator for automatic\n\t\t\t *  semicolon insertion.\n\t\t\t */\n\n\t\t\tduk_bool_t last_asterisk = 0;\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 2);\n\t\t\tfor (;;) {\n\t\t\t\tx = DUK__L0();\n\t\t\t\tif (x < 0) {\n\t\t\t\t\tgoto fail_unterm_comment;\n\t\t\t\t}\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t\tif (last_asterisk && x == DUK_ASC_SLASH) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (duk_unicode_is_line_terminator(x)) {\n\t\t\t\t\tgot_lineterm = 1;\n\t\t\t\t}\n\t\t\t\tlast_asterisk = (x == DUK_ASC_STAR);\n\t\t\t}\n\t\t\tgoto restart_lineupdate;\n\t\t} else if (regexp_mode) {\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\t\t\t/*\n\t\t\t *  \"/\" followed by something in regexp mode.  See E5 Section 7.8.5.\n\t\t\t *\n\t\t\t *  RegExp parsing is a bit complex.  First, the regexp body is delimited\n\t\t\t *  by forward slashes, but the body may also contain forward slashes as\n\t\t\t *  part of an escape sequence or inside a character class (delimited by\n\t\t\t *  square brackets).  A mini state machine is used to implement these.\n\t\t\t *\n\t\t\t *  Further, an early (parse time) error must be thrown if the regexp\n\t\t\t *  would cause a run-time error when used in the expression new RegExp(...).\n\t\t\t *  Parsing here simply extracts the (candidate) regexp, and also accepts\n\t\t\t *  invalid regular expressions (which are delimited properly).  The caller\n\t\t\t *  (compiler) must perform final validation and regexp compilation.\n\t\t\t *\n\t\t\t *  RegExp first char may not be '/' (single line comment) or '*' (multi-\n\t\t\t *  line comment).  These have already been checked above, so there is no\n\t\t\t *  need below for special handling of the first regexp character as in\n\t\t\t *  the E5 productions.\n\t\t\t *\n\t\t\t *  About unicode escapes within regexp literals:\n\t\t\t *\n\t\t\t *      E5 Section 7.8.5 grammar does NOT accept \\uHHHH escapes.\n\t\t\t *      However, Section 6 states that regexps accept the escapes,\n\t\t\t *      see paragraph starting with \"In string literals...\".\n\t\t\t *      The regexp grammar, which sees the decoded regexp literal\n\t\t\t *      (after lexical parsing) DOES have a \\uHHHH unicode escape.\n\t\t\t *      So, for instance:\n\t\t\t *\n\t\t\t *          /\\u1234/\n\t\t\t *\n\t\t\t *      should first be parsed by the lexical grammar as:\n\t\t\t *\n\t\t\t *          '\\' 'u'      RegularExpressionBackslashSequence\n\t\t\t *          '1'          RegularExpressionNonTerminator\n\t\t\t *          '2'          RegularExpressionNonTerminator\n\t\t\t *          '3'          RegularExpressionNonTerminator\n\t\t\t *          '4'          RegularExpressionNonTerminator\n\t\t\t *\n\t\t\t *      and the escape itself is then parsed by the regexp engine.\n\t\t\t *      This is the current implementation.\n\t\t\t *\n\t\t\t *  Minor spec inconsistency:\n\t\t\t *\n\t\t\t *      E5 Section 7.8.5 RegularExpressionBackslashSequence is:\n\t\t\t *\n\t\t\t *         \\ RegularExpressionNonTerminator\n\t\t\t *\n\t\t\t *      while Section A.1 RegularExpressionBackslashSequence is:\n\t\t\t *\n\t\t\t *         \\ NonTerminator\n\t\t\t *\n\t\t\t *      The latter is not normative and a typo.\n\t\t\t *\n\t\t\t */\n\n\t\t\t/* first, parse regexp body roughly */\n\n\t\t\tduk_small_int_t state = 0;  /* 0=base, 1=esc, 2=class, 3=class+esc */\n\n\t\t\tDUK__INITBUFFER(lex_ctx);\n\t\t\tfor (;;) {\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* skip opening slash on first loop */\n\t\t\t\tx = DUK__L0();\n\t\t\t\tif (x < 0 || duk_unicode_is_line_terminator(x)) {\n\t\t\t\t\tgoto fail_unterm_regexp;\n\t\t\t\t}\n\t\t\t\tx = DUK__L0();  /* re-read to avoid spill / fetch */\n\t\t\t\tif (state == 0) {\n\t\t\t\t\tif (x == DUK_ASC_SLASH) {\n\t\t\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat closing slash */\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\t\t\t\tstate = 1;\n\t\t\t\t\t} else if (x == DUK_ASC_LBRACKET) {\n\t\t\t\t\t\tstate = 2;\n\t\t\t\t\t}\n\t\t\t\t} else if (state == 1) {\n\t\t\t\t\tstate = 0;\n\t\t\t\t} else if (state == 2) {\n\t\t\t\t\tif (x == DUK_ASC_RBRACKET) {\n\t\t\t\t\t\tstate = 0;\n\t\t\t\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\t\t\t\tstate = 3;\n\t\t\t\t\t}\n\t\t\t\t} else { /* state == 3 */\n\t\t\t\t\tstate = 2;\n\t\t\t\t}\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t}\n\t\t\tout_token->str1 = duk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\n\t\t\t/* second, parse flags */\n\n\t\t\tDUK__INITBUFFER(lex_ctx);\n\t\t\tfor (;;) {\n\t\t\t\tx = DUK__L0();\n\t\t\t\tif (!duk_unicode_is_identifier_part(x)) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tx = DUK__L0();  /* re-read to avoid spill / fetch */\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t}\n\t\t\tout_token->str2 = duk__internbuffer(lex_ctx, lex_ctx->slot2_idx);\n\n\t\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\t\t/* validation of the regexp is caller's responsibility */\n\n\t\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_REGEXP);\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\t\t\tgoto fail_regexp_support;\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\t/* \"/=\" and not in regexp mode */\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_DIV_EQ);\n\t\t} else {\n\t\t\t/* \"/\" and not in regexp mode */\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_DIV);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_LCURLY:  /* '{' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LCURLY);\n\t\tbreak;\n\tcase DUK_ASC_RCURLY:  /* '}' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_RCURLY);\n\t\tbreak;\n\tcase DUK_ASC_LPAREN:  /* '(' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LPAREN);\n\t\tbreak;\n\tcase DUK_ASC_RPAREN:  /* ')' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_RPAREN);\n\t\tbreak;\n\tcase DUK_ASC_LBRACKET:  /* '[' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LBRACKET);\n\t\tbreak;\n\tcase DUK_ASC_RBRACKET:  /* ']' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_RBRACKET);\n\t\tbreak;\n\tcase DUK_ASC_PERIOD:  /* '.' */\n\t\tif (DUK__ISDIGIT(DUK__L1())) {\n\t\t\t/* Period followed by a digit can only start DecimalLiteral\n\t\t\t * (handled in slow path).  We could jump straight into the\n\t\t\t * DecimalLiteral handling but should avoid goto to inside\n\t\t\t * a block.\n\t\t\t */\n\t\t\tgoto slow_path;\n\t\t}\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_PERIOD);\n\t\tbreak;\n\tcase DUK_ASC_SEMICOLON:  /* ';' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_SEMICOLON);\n\t\tbreak;\n\tcase DUK_ASC_COMMA:  /* ',' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_COMMA);\n\t\tbreak;\n\tcase DUK_ASC_LANGLE:  /* '<' */\n#if defined(DUK_USE_HTML_COMMENTS)\n\t\tif (DUK__L1() == DUK_ASC_EXCLAMATION && DUK__L2() == DUK_ASC_MINUS && DUK__L3() == DUK_ASC_MINUS) {\n\t\t\t/*\n\t\t\t *  ES2015: B.1.3, handle \"<!--\" SingleLineHTMLOpenComment\n\t\t\t */\n\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 4) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t}\n\t\telse\n#endif  /* DUK_USE_HTML_COMMENTS */\n\t\tif (DUK__L1() == DUK_ASC_LANGLE && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_ALSHIFT_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_LE);\n\t\t} else if (DUK__L1() == DUK_ASC_LANGLE) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_ALSHIFT);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LT);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_RANGLE:  /* '>' */\n\t\tif (DUK__L1() == DUK_ASC_RANGLE && DUK__L2() == DUK_ASC_RANGLE && DUK__L3() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(4, DUK_TOK_RSHIFT_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_RANGLE && DUK__L2() == DUK_ASC_RANGLE) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_RSHIFT);\n\t\t} else if (DUK__L1() == DUK_ASC_RANGLE && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_ARSHIFT_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_GE);\n\t\t} else if (DUK__L1() == DUK_ASC_RANGLE) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_ARSHIFT);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_GT);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_EQUALS:  /* '=' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_SEQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_EQUALSIGN);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_EXCLAMATION:  /* '!' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_SNEQ);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_NEQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_LNOT);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_PLUS:  /* '+' */\n\t\tif (DUK__L1() == DUK_ASC_PLUS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_INCREMENT);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_ADD_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_ADD);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_MINUS:  /* '-' */\n#if defined(DUK_USE_HTML_COMMENTS)\n\t\tif (got_lineterm && DUK__L1() == DUK_ASC_MINUS && DUK__L2() == DUK_ASC_RANGLE) {\n\t\t\t/*\n\t\t\t *  ES2015: B.1.3, handle \"-->\" SingleLineHTMLCloseComment\n\t\t\t *  Only allowed:\n\t\t\t *  - on new line\n\t\t\t *  - preceded only by whitespace\n\t\t\t *  - preceded by end of multiline comment and optional whitespace\n\t\t\t *\n\t\t\t * Since whitespace generates no tokens, and multiline comments\n\t\t\t * are treated as a line ending, consulting `got_lineterm` is\n\t\t\t * sufficient to test for these three options.\n\t\t\t */\n\n\t\t\t/* DUK__ADVANCECHARS(lex_ctx, 3) would be correct here, but not necessary */\n\t\t\tduk__lexer_skip_to_endofline(lex_ctx);\n\t\t\tgoto restart;  /* line terminator will be handled on next round */\n\t\t} else\n#endif  /* DUK_USE_HTML_COMMENTS */\n\t\tif (DUK__L1() == DUK_ASC_MINUS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_DECREMENT);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_SUB_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_SUB);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_STAR:  /* '*' */\n#if defined(DUK_USE_ES7_EXP_OPERATOR)\n\t\tif (DUK__L1() == DUK_ASC_STAR && DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(3, DUK_TOK_EXP_EQ);\n\t\t} else if (DUK__L1() == DUK_ASC_STAR) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_EXP);\n\t\t} else\n#endif\n\t\tif (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_MUL_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_MUL);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_PERCENT:  /* '%' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_MOD_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_MOD);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_AMP:  /* '&' */\n\t\tif (DUK__L1() == DUK_ASC_AMP) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_LAND);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_BAND_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BAND);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_PIPE:  /* '|' */\n\t\tif (DUK__L1() == DUK_ASC_PIPE) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_LOR);\n\t\t} else if (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_BOR_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BOR);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_CARET:  /* '^' */\n\t\tif (DUK__L1() == DUK_ASC_EQUALS) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_TOK_BXOR_EQ);\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BXOR);\n\t\t}\n\t\tbreak;\n\tcase DUK_ASC_TILDE:  /* '~' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_BNOT);\n\t\tbreak;\n\tcase DUK_ASC_QUESTION:  /* '?' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_QUESTION);\n\t\tbreak;\n\tcase DUK_ASC_COLON:  /* ':' */\n\t\tadvtok = DUK__ADVTOK(1, DUK_TOK_COLON);\n\t\tbreak;\n\tcase DUK_ASC_DOUBLEQUOTE:    /* '\"' */\n\tcase DUK_ASC_SINGLEQUOTE: {  /* '\\'' */\n\t\tDUK__INITBUFFER(lex_ctx);\n\t\tduk__lexer_parse_string_literal(lex_ctx, out_token, x /*quote*/, strict_mode);\n\t\tduk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\t\tout_token->str1 = duk_known_hstring(lex_ctx->thr, lex_ctx->slot1_idx);\n\n\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_STRING);\n\t\tbreak;\n\t}\n\tdefault:\n\t\tgoto slow_path;\n\t}  /* switch */\n\n\tgoto skip_slow_path;\n\n slow_path:\n\tif (duk_unicode_is_line_terminator(x)) {\n\t\tif (x == 0x000d && DUK__L1() == 0x000a) {\n\t\t\t/*\n\t\t\t *  E5 Section 7.3: CR LF is detected as a single line terminator for\n\t\t\t *  line numbers.  Here we also detect it as a single line terminator\n\t\t\t *  token.\n\t\t\t */\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 2);\n\t\t} else {\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t}\n\t\tgot_lineterm = 1;\n\t\tgoto restart_lineupdate;\n\t} else if (duk_unicode_is_identifier_start(x) || x == DUK_ASC_BACKSLASH) {\n\t\t/*\n\t\t *  Parse an identifier and then check whether it is:\n\t\t *    - reserved word (keyword or other reserved word)\n\t\t *    - \"null\"  (NullLiteral)\n\t\t *    - \"true\"  (BooleanLiteral)\n\t\t *    - \"false\" (BooleanLiteral)\n\t\t *    - anything else => identifier\n\t\t *\n\t\t *  This does not follow the E5 productions cleanly, but is\n\t\t *  useful and compact.\n\t\t *\n\t\t *  Note that identifiers may contain Unicode escapes,\n\t\t *  see E5 Sections 6 and 7.6.  They must be decoded first,\n\t\t *  and the result checked against allowed characters.\n\t\t *  The above if-clause accepts an identifier start and an\n\t\t *  '\\' character -- no other token can begin with a '\\'.\n\t\t *\n\t\t *  Note that \"get\" and \"set\" are not reserved words in E5\n\t\t *  specification so they are recognized as plain identifiers\n\t\t *  (the tokens DUK_TOK_GET and DUK_TOK_SET are actually not\n\t\t *  used now).  The compiler needs to work around this.\n\t\t *\n\t\t *  Strictly speaking, following ECMAScript longest match\n\t\t *  specification, an invalid escape for the first character\n\t\t *  should cause a syntax error.  However, an invalid escape\n\t\t *  for IdentifierParts should just terminate the identifier\n\t\t *  early (longest match), and let the next tokenization\n\t\t *  fail.  For instance Rhino croaks with 'foo\\z' when\n\t\t *  parsing the identifier.  This has little practical impact.\n\t\t */\n\n\t\tduk_small_uint_t i, i_end;\n\t\tduk_bool_t first = 1;\n\t\tduk_hstring *str;\n\n\t\tDUK__INITBUFFER(lex_ctx);\n\t\tfor (;;) {\n\t\t\t/* re-lookup first char on first loop */\n\t\t\tif (DUK__L0() == DUK_ASC_BACKSLASH) {\n\t\t\t\tduk_codepoint_t esc_cp;\n\t\t\t\tif (DUK__L1() != DUK_ASC_LC_U) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t\tesc_cp = duk__lexer_parse_escape(lex_ctx, 1 /*allow_es6*/);\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, esc_cp);\n\n\t\t\t\t/* IdentifierStart is stricter than IdentifierPart, so if the first\n\t\t\t\t * character is escaped, must have a stricter check here.\n\t\t\t\t */\n\t\t\t\tif (!(first ? duk_unicode_is_identifier_start(esc_cp) : duk_unicode_is_identifier_part(esc_cp))) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\n\t\t\t\t/* Track number of escapes: necessary for proper keyword\n\t\t\t\t * detection.\n\t\t\t\t */\n\t\t\t\tout_token->num_escapes++;\n\t\t\t} else {\n\t\t\t\t/* Note: first character is checked against this.  But because\n\t\t\t\t * IdentifierPart includes all IdentifierStart characters, and\n\t\t\t\t * the first character (if unescaped) has already been checked\n\t\t\t\t * in the if condition, this is OK.\n\t\t\t\t */\n\t\t\t\tif (!duk_unicode_is_identifier_part(DUK__L0())) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tDUK__APPENDBUFFER(lex_ctx, DUK__L0());\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t}\n\t\t\tfirst = 0;\n\t\t}\n\n\t\tout_token->str1 = duk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\t\tstr = out_token->str1;\n\t\tout_token->t_nores = DUK_TOK_IDENTIFIER;\n\n\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\t/*\n\t\t *  Interned identifier is compared against reserved words, which are\n\t\t *  currently interned into the heap context.  See genbuiltins.py.\n\t\t *\n\t\t *  Note that an escape in the identifier disables recognition of\n\t\t *  keywords; e.g. \"\\u0069f = 1;\" is a valid statement (assigns to\n\t\t *  identifier named \"if\").  This is not necessarily compliant,\n\t\t *  see test-dec-escaped-char-in-keyword.js.\n\t\t *\n\t\t *  Note: \"get\" and \"set\" are awkward.  They are not officially\n\t\t *  ReservedWords (and indeed e.g. \"var set = 1;\" is valid), and\n\t\t *  must come out as DUK_TOK_IDENTIFIER.  The compiler needs to\n\t\t *  work around this a bit.\n\t\t */\n\n\t\t/* XXX: optimize by adding the token numbers directly into the\n\t\t * always interned duk_hstring objects (there should be enough\n\t\t * flag bits free for that)?\n\t\t */\n\n\t\ti_end = (strict_mode ? DUK_STRIDX_END_RESERVED : DUK_STRIDX_START_STRICT_RESERVED);\n\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_IDENTIFIER);\n\t\tif (out_token->num_escapes == 0) {\n\t\t\tfor (i = DUK_STRIDX_START_RESERVED; i < i_end; i++) {\n\t\t\t\tDUK_ASSERT_DISABLE(i >= 0);  /* unsigned */\n\t\t\t\tDUK_ASSERT(i < DUK_HEAP_NUM_STRINGS);\n\t\t\t\tif (DUK_HTHREAD_GET_STRING(lex_ctx->thr, i) == str) {\n\t\t\t\t\tadvtok = DUK__ADVTOK(0, DUK_STRIDX_TO_TOK(i));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if (DUK__ISDIGIT(x) || (x == DUK_ASC_PERIOD)) {\n\t\t/* Note: decimal number may start with a period, but must be followed by a digit */\n\n\t\t/*\n\t\t *  Pre-parsing for decimal, hex, octal (both legacy and ES2015),\n\t\t *  and binary literals, followed by an actual parser step\n\t\t *  provided by numconv.\n\t\t *\n\t\t *  Note: the leading sign character ('+' or '-') is -not- part of\n\t\t *  the production in E5 grammar, and that the a DecimalLiteral\n\t\t *  starting with a '0' must be followed by a non-digit.\n\t\t *\n\t\t *  XXX: the two step parsing process is quite awkward, it would\n\t\t *  be more straightforward to allow numconv to parse the longest\n\t\t *  valid prefix (it already does that, it only needs to indicate\n\t\t *  where the input ended).  However, the lexer decodes characters\n\t\t *  using a limited lookup window, so this is not a trivial change.\n\t\t */\n\n\t\t/* XXX: because of the final check below (that the literal is not\n\t\t * followed by a digit), this could maybe be simplified, if we bail\n\t\t * out early from a leading zero (and if there are no periods etc).\n\t\t * Maybe too complex.\n\t\t */\n\n\t\tduk_double_t val;\n\t\tduk_bool_t legacy_oct = 0;\n\t\tduk_small_int_t state;  /* 0=before period/exp,\n\t\t                         * 1=after period, before exp\n\t\t                         * 2=after exp, allow '+' or '-'\n\t\t                         * 3=after exp and exp sign\n\t\t                         */\n\t\tduk_small_uint_t s2n_flags;\n\t\tduk_codepoint_t y, z;\n\t\tduk_small_int_t s2n_radix = 10;\n\t\tduk_small_uint_t pre_adv = 0;\n\n\t\tDUK__INITBUFFER(lex_ctx);\n\t\ty = DUK__L1();\n\n\t\tif (x == DUK_ASC_0) {\n\t\t\tz = DUK_LOWERCASE_CHAR_ASCII(y);\n\n\t\t\tpre_adv = 2;  /* default for 0xNNN, 0oNNN, 0bNNN. */\n\t\t\tif (z == DUK_ASC_LC_X) {\n\t\t\t\ts2n_radix = 16;\n\t\t\t} else if (z == DUK_ASC_LC_O) {\n\t\t\t\ts2n_radix = 8;\n\t\t\t} else if (z == DUK_ASC_LC_B) {\n\t\t\t\ts2n_radix = 2;\n\t\t\t} else {\n\t\t\t\tpre_adv = 0;\n\t\t\t\tif (DUK__ISDIGIT(y)) {\n\t\t\t\t\tif (strict_mode) {\n\t\t\t\t\t\t/* Reject octal like \\07 but also octal-lookalike\n\t\t\t\t\t\t * decimal like \\08 in strict mode.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tgoto fail_number_literal;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t/* Legacy OctalIntegerLiteral or octal-lookalice\n\t\t\t\t\t\t * decimal.  Deciding between the two happens below\n\t\t\t\t\t\t * in digit scanning.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\t\t\t\tpre_adv = 1;\n\t\t\t\t\t\tlegacy_oct = 1;\n\t\t\t\t\t\ts2n_radix = 8;  /* tentative unless conflicting digits found */\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tDUK__ADVANCECHARS(lex_ctx, pre_adv);\n\n\t\t/* XXX: we could parse integers here directly, and fall back\n\t\t * to numconv only when encountering a fractional expression\n\t\t * or when an octal literal turned out to be decimal (0778 etc).\n\t\t */\n\t\tstate = 0;\n\t\tfor (;;) {\n\t\t\tx = DUK__L0();  /* re-lookup curr char on first round */\n\t\t\tif (DUK__ISDIGIT(x)) {\n\t\t\t\t/* Note: intentionally allow leading zeroes here, as the\n\t\t\t\t * actual parser will check for them.\n\t\t\t\t */\n\t\t\t\tif (state == 0 && legacy_oct && (x == DUK_ASC_8 || x == DUK_ASC_9)) {\n\t\t\t\t\t/* Started out as an octal-lookalike\n\t\t\t\t\t * but interpreted as decimal, e.g.\n\t\t\t\t\t * '0779' -> 779.  This also means\n\t\t\t\t\t * that fractions are allowed, e.g.\n\t\t\t\t\t * '0779.123' is allowed but '0777.123'\n\t\t\t\t\t * is not!\n\t\t\t\t\t */\n\t\t\t\t\ts2n_radix = 10;\n\t\t\t\t}\n\t\t\t\tif (state == 2) {\n\t\t\t\t\tstate = 3;\n\t\t\t\t}\n\t\t\t} else if (s2n_radix == 16 && DUK__ISHEXDIGIT(x)) {\n\t\t\t\t/* Note: 'e' and 'E' are also accepted here. */\n\t\t\t\t;\n\t\t\t} else if (x == DUK_ASC_PERIOD) {\n\t\t\t\tif (state >= 1 || s2n_radix != 10) {\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tstate = 1;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_LC_E || x == DUK_ASC_UC_E) {\n\t\t\t\tif (state >= 2 || s2n_radix != 10) {\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tstate = 2;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_MINUS || x == DUK_ASC_PLUS) {\n\t\t\t\tif (state != 2) {\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tstate = 3;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK__APPENDBUFFER(lex_ctx, x);\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t}\n\n\t\t/* XXX: better coercion */\n\t\t(void) duk__internbuffer(lex_ctx, lex_ctx->slot1_idx);\n\n\t\tif (s2n_radix != 10) {\n\t\t\t/* For bases other than 10, integer only. */\n\t\t\ts2n_flags = DUK_S2N_FLAG_ALLOW_LEADING_ZERO;\n\t\t} else {\n\t\t\ts2n_flags = DUK_S2N_FLAG_ALLOW_EXP |\n\t\t\t            DUK_S2N_FLAG_ALLOW_FRAC |\n\t\t\t            DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t\t\t            DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t\t\t            DUK_S2N_FLAG_ALLOW_LEADING_ZERO;\n\t\t}\n\n\t\tduk_dup(lex_ctx->thr, lex_ctx->slot1_idx);\n\t\tduk_numconv_parse(lex_ctx->thr, s2n_radix, s2n_flags);\n\t\tval = duk_to_number_m1(lex_ctx->thr);\n\t\tif (DUK_ISNAN(val)) {\n\t\t\tgoto fail_number_literal;\n\t\t}\n\t\tduk_replace(lex_ctx->thr, lex_ctx->slot1_idx);  /* could also just pop? */\n\n\t\tDUK__INITBUFFER(lex_ctx);  /* free some memory */\n\n\t\t/* Section 7.8.3 (note): NumericLiteral must be followed by something other than\n\t\t * IdentifierStart or DecimalDigit.\n\t\t */\n\n\t\tif (DUK__ISDIGIT(DUK__L0()) || duk_unicode_is_identifier_start(DUK__L0())) {\n\t\t\tgoto fail_number_literal;\n\t\t}\n\n\t\tout_token->num = val;\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_NUMBER);\n\t} else if (duk_unicode_is_whitespace(DUK__LOOKUP(lex_ctx, 0))) {\n\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\tgoto restart;\n\t} else if (x < 0) {\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_EOF);\n\t} else {\n\t\tgoto fail_token;\n\t}\n skip_slow_path:\n\n\t/*\n\t *  Shared exit path\n\t */\n\n\tDUK__ADVANCEBYTES(lex_ctx, advtok >> 8);\n\tout_token->t = advtok & 0xff;\n\tif (out_token->t_nores == DUK_TOK_INVALID) {\n\t\tout_token->t_nores = out_token->t;\n\t}\n\tout_token->lineterm = got_lineterm;\n\n\t/* Automatic semicolon insertion is allowed if a token is preceded\n\t * by line terminator(s), or terminates a statement list (right curly\n\t * or EOF).\n\t */\n\tif (got_lineterm || out_token->t == DUK_TOK_RCURLY || out_token->t == DUK_TOK_EOF) {\n\t\tout_token->allow_auto_semi = 1;\n\t} else {\n\t\tout_token->allow_auto_semi = 0;\n\t}\n\n\treturn;\n\n fail_token_limit:\n\tDUK_ERROR_RANGE(lex_ctx->thr, DUK_STR_TOKEN_LIMIT);\n\tDUK_WO_NORETURN(return;);\n\n fail_token:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_TOKEN);\n\tDUK_WO_NORETURN(return;);\n\n fail_number_literal:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_NUMBER_LITERAL);\n\tDUK_WO_NORETURN(return;);\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterm_regexp:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_REGEXP);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterm_comment:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_COMMENT);\n\tDUK_WO_NORETURN(return;);\n\n#if !defined(DUK_USE_REGEXP_SUPPORT)\n fail_regexp_support:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_REGEXP_SUPPORT_DISABLED);\n\tDUK_WO_NORETURN(return;);\n#endif\n}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Parse a RegExp token.  The grammar is described in E5 Section 15.10.\n *  Terminal constructions (such as quantifiers) are parsed directly here.\n *\n *  0xffffffffU is used as a marker for \"infinity\" in quantifiers.  Further,\n *  DUK__MAX_RE_QUANT_DIGITS limits the maximum number of digits that\n *  will be accepted for a quantifier.\n */\n\nDUK_INTERNAL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token *out_token) {\n\tduk_small_uint_t advtok = 0;  /* init is unnecessary but suppresses \"may be used uninitialized\" warnings */\n\tduk_codepoint_t x, y;\n\n\tif (++lex_ctx->token_count >= lex_ctx->token_limit) {\n\t\tgoto fail_token_limit;\n\t}\n\n\tduk_memzero(out_token, sizeof(*out_token));\n\n\tx = DUK__L0();\n\ty = DUK__L1();\n\n\tDUK_DDD(DUK_DDDPRINT(\"parsing regexp token, L0=%ld, L1=%ld\", (long) x, (long) y));\n\n\tswitch (x) {\n\tcase DUK_ASC_PIPE: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_DISJUNCTION);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_CARET: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ASSERT_START);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_DOLLAR: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ASSERT_END);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_QUESTION: {\n\t\tout_token->qmin = 0;\n\t\tout_token->qmax = 1;\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 0;\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_STAR: {\n\t\tout_token->qmin = 0;\n\t\tout_token->qmax = DUK_RE_QUANTIFIER_INFINITE;\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 0;\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_PLUS: {\n\t\tout_token->qmin = 1;\n\t\tout_token->qmax = DUK_RE_QUANTIFIER_INFINITE;\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 0;\n\t\t} else {\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_QUANTIFIER);\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LCURLY: {\n\t\t/* Production allows 'DecimalDigits', including leading zeroes */\n\t\tduk_uint32_t val1 = 0;\n\t\tduk_uint32_t val2 = DUK_RE_QUANTIFIER_INFINITE;\n\t\tduk_small_int_t digits = 0;\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\tduk_lexer_point lex_pt;\n#endif\n\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t/* Store lexer position, restoring if quantifier is invalid. */\n\t\tDUK_LEXER_GETPOINT(lex_ctx, &lex_pt);\n#endif\n\n\t\tfor (;;) {\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat '{' on entry */\n\t\t\tx = DUK__L0();\n\t\t\tif (DUK__ISDIGIT(x)) {\n\t\t\t\tdigits++;\n\t\t\t\tval1 = val1 * 10 + (duk_uint32_t) duk__hexval(x);\n\t\t\t} else if (x == DUK_ASC_COMMA) {\n\t\t\t\tif (digits > DUK__MAX_RE_QUANT_DIGITS) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (val2 != DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (DUK__L1() == DUK_ASC_RCURLY) {\n\t\t\t\t\t/* form: { DecimalDigits , }, val1 = min count */\n\t\t\t\t\tif (digits == 0) {\n\t\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t\t}\n\t\t\t\t\tout_token->qmin = val1;\n\t\t\t\t\tout_token->qmax = DUK_RE_QUANTIFIER_INFINITE;\n\t\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 2);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tval2 = val1;\n\t\t\t\tval1 = 0;\n\t\t\t\tdigits = 0;  /* not strictly necessary because of lookahead '}' above */\n\t\t\t} else if (x == DUK_ASC_RCURLY) {\n\t\t\t\tif (digits > DUK__MAX_RE_QUANT_DIGITS) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (digits == 0) {\n\t\t\t\t\tgoto invalid_quantifier;\n\t\t\t\t}\n\t\t\t\tif (val2 != DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\t/* val2 = min count, val1 = max count */\n\t\t\t\t\tout_token->qmin = val2;\n\t\t\t\t\tout_token->qmax = val1;\n\t\t\t\t} else {\n\t\t\t\t\t/* val1 = count */\n\t\t\t\t\tout_token->qmin = val1;\n\t\t\t\t\tout_token->qmax = val1;\n\t\t\t\t}\n\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tgoto invalid_quantifier;\n\t\t\t}\n\t\t}\n\t\tif (DUK__L0() == DUK_ASC_QUESTION) {\n\t\t\tout_token->greedy = 0;\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);\n\t\t} else {\n\t\t\tout_token->greedy = 1;\n\t\t}\n\t\tadvtok = DUK__ADVTOK(0, DUK_RETOK_QUANTIFIER);\n\t\tbreak;\n invalid_quantifier:\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t/* Failed to match the quantifier, restore lexer and parse\n\t\t * opening brace as a literal.\n\t\t */\n\t\tDUK_LEXER_SETPOINT(lex_ctx, &lex_pt);\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_CHAR);\n\t\tout_token->num = DUK_ASC_LCURLY;\n#else\n\t\tgoto fail_quantifier;\n#endif\n\t\tbreak;\n\t}\n\tcase DUK_ASC_PERIOD: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_PERIOD);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_BACKSLASH: {\n\t\t/* The E5.1 specification does not seem to allow IdentifierPart characters\n\t\t * to be used as identity escapes.  Unfortunately this includes '$', which\n\t\t * cannot be escaped as '\\$'; it needs to be escaped e.g. as '\\u0024'.\n\t\t * Many other implementations (including V8 and Rhino, for instance) do\n\t\t * accept '\\$' as a valid identity escape, which is quite pragmatic, and\n\t\t * ES2015 Annex B relaxes the rules to allow these (and other) real world forms.\n\t\t */\n\n\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_CHAR);  /* default: char escape (two chars) */\n\t\tif (y == DUK_ASC_LC_B) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ASSERT_WORD_BOUNDARY);\n\t\t} else if (y == DUK_ASC_UC_B) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY);\n\t\t} else if (y == DUK_ASC_LC_F) {\n\t\t\tout_token->num = 0x000c;\n\t\t} else if (y == DUK_ASC_LC_N) {\n\t\t\tout_token->num = 0x000a;\n\t\t} else if (y == DUK_ASC_LC_T) {\n\t\t\tout_token->num = 0x0009;\n\t\t} else if (y == DUK_ASC_LC_R) {\n\t\t\tout_token->num = 0x000d;\n\t\t} else if (y == DUK_ASC_LC_V) {\n\t\t\tout_token->num = 0x000b;\n\t\t} else if (y == DUK_ASC_LC_C) {\n\t\t\tx = DUK__L2();\n\t\t\tif ((x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_Z) ||\n\t\t\t    (x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_Z)) {\n\t\t\t\tout_token->num = (duk_uint32_t) (x % 32);\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ATOM_CHAR);\n\t\t\t} else {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t} else if (y == DUK_ASC_LC_X || y == DUK_ASC_LC_U) {\n\t\t\t/* The token value is the Unicode codepoint without\n\t\t\t * it being decode into surrogate pair characters\n\t\t\t * here.  The \\u{H+} is only allowed in Unicode mode\n\t\t\t * which we don't support yet.\n\t\t\t */\n\t\t\tout_token->num = (duk_uint32_t) duk__lexer_parse_escape(lex_ctx, 0 /*allow_es6*/);\n\t\t\tadvtok = DUK__ADVTOK(0, DUK_RETOK_ATOM_CHAR);\n\t\t} else if (y == DUK_ASC_LC_D) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_DIGIT);\n\t\t} else if (y == DUK_ASC_UC_D) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_NOT_DIGIT);\n\t\t} else if (y == DUK_ASC_LC_S) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_WHITE);\n\t\t} else if (y == DUK_ASC_UC_S) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_NOT_WHITE);\n\t\t} else if (y == DUK_ASC_LC_W) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_WORD_CHAR);\n\t\t} else if (y == DUK_ASC_UC_W) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_NOT_WORD_CHAR);\n\t\t} else if (DUK__ISDIGIT(y)) {\n\t\t\t/* E5 Section 15.10.2.11 */\n\t\t\tif (y == DUK_ASC_0) {\n\t\t\t\tif (DUK__ISDIGIT(DUK__L2())) {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t\tout_token->num = 0x0000;\n\t\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_CHAR);\n\t\t\t} else {\n\t\t\t\t/* XXX: shared parsing? */\n\t\t\t\tduk_uint32_t val = 0;\n\t\t\t\tduk_small_int_t i;\n\t\t\t\tfor (i = 0; ; i++) {\n\t\t\t\t\tif (i >= DUK__MAX_RE_DECESC_DIGITS) {\n\t\t\t\t\t\tgoto fail_escape;\n\t\t\t\t\t}\n\t\t\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat backslash on entry */\n\t\t\t\t\tx = DUK__L0();\n\t\t\t\t\tif (!DUK__ISDIGIT(x)) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tval = val * 10 + (duk_uint32_t) duk__hexval(x);\n\t\t\t\t}\n\t\t\t\t/* DUK__L0() cannot be a digit, because the loop doesn't terminate if it is */\n\t\t\t\tadvtok = DUK__ADVTOK(0, DUK_RETOK_ATOM_BACKREFERENCE);\n\t\t\t\tout_token->num = val;\n\t\t\t}\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t} else if (y >= 0) {\n\t\t\t/* For ES2015 Annex B, accept any source character as identity\n\t\t\t * escape except 'c' which is used for control characters.\n\t\t\t * http://www.ecma-international.org/ecma-262/6.0/#sec-regular-expressions-patterns\n\t\t\t * Careful not to match end-of-buffer (<0) here.\n\t\t\t * This is not yet full ES2015 Annex B because cases above\n\t\t\t * (like hex escape) won't backtrack.\n\t\t\t */\n\t\t\tDUK_ASSERT(y != DUK_ASC_LC_C);  /* covered above */\n#else  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t} else if ((y >= 0 && !duk_unicode_is_identifier_part(y)) ||\n\t\t           y == DUK_UNICODE_CP_ZWNJ ||\n\t\t           y == DUK_UNICODE_CP_ZWJ) {\n\t\t\t/* For ES5.1 identity escapes are not allowed for identifier\n\t\t\t * parts.  This conflicts with a lot of real world code as this\n\t\t\t * doesn't e.g. allow escaping a dollar sign as /\\$/, see\n\t\t\t * test-regexp-identity-escape-dollar.js.\n\t\t\t */\n#endif  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t\tout_token->num = (duk_uint32_t) y;\n\t\t} else {\n\t\t\tgoto fail_escape;\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LPAREN: {\n\t\t/* XXX: naming is inconsistent: ATOM_END_GROUP ends an ASSERT_START_LOOKAHEAD */\n\n\t\tif (y == DUK_ASC_QUESTION) {\n\t\t\tif (DUK__L2() == DUK_ASC_EQUALS) {\n\t\t\t\t/* (?= */\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ASSERT_START_POS_LOOKAHEAD);\n\t\t\t} else if (DUK__L2() == DUK_ASC_EXCLAMATION) {\n\t\t\t\t/* (?! */\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD);\n\t\t\t} else if (DUK__L2() == DUK_ASC_COLON) {\n\t\t\t\t/* (?: */\n\t\t\t\tadvtok = DUK__ADVTOK(3, DUK_RETOK_ATOM_START_NONCAPTURE_GROUP);\n\t\t\t} else {\n\t\t\t\tgoto fail_group;\n\t\t\t}\n\t\t} else {\n\t\t\t/* ( */\n\t\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_START_CAPTURE_GROUP);\n\t\t}\n\t\tbreak;\n\t}\n\tcase DUK_ASC_RPAREN: {\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_END_GROUP);\n\t\tbreak;\n\t}\n\tcase DUK_ASC_LBRACKET: {\n\t\t/*\n\t\t *  To avoid creating a heavy intermediate value for the list of ranges,\n\t\t *  only the start token ('[' or '[^') is parsed here.  The regexp\n\t\t *  compiler parses the ranges itself.\n\t\t */\n\n\t\t/* XXX: with DUK_USE_ES6_REGEXP_SYNTAX we should allow left bracket\n\t\t * literal too, but it's not easy to parse without backtracking.\n\t\t */\n\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_START_CHARCLASS);\n\t\tif (y == DUK_ASC_CARET) {\n\t\t\tadvtok = DUK__ADVTOK(2, DUK_RETOK_ATOM_START_CHARCLASS_INVERTED);\n\t\t}\n\t\tbreak;\n\t}\n#if !defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\tcase DUK_ASC_RCURLY:\n\tcase DUK_ASC_RBRACKET: {\n\t\t/* Although these could be parsed as PatternCharacters unambiguously (here),\n\t\t * E5 Section 15.10.1 grammar explicitly forbids these as PatternCharacters.\n\t\t */\n\t\tgoto fail_invalid_char;\n\t\tbreak;\n\t}\n#endif\n\tcase -1: {\n\t\t/* EOF */\n\t\tadvtok = DUK__ADVTOK(0, DUK_TOK_EOF);\n\t\tbreak;\n\t}\n\tdefault: {\n\t\t/* PatternCharacter, all excluded characters are matched by cases above */\n\t\tadvtok = DUK__ADVTOK(1, DUK_RETOK_ATOM_CHAR);\n\t\tout_token->num = (duk_uint32_t) x;\n\t\tbreak;\n\t}\n\t}\n\n\t/*\n\t *  Shared exit path\n\t */\n\n\tDUK__ADVANCEBYTES(lex_ctx, advtok >> 8);\n\tout_token->t = advtok & 0xff;\n\treturn;\n\n fail_token_limit:\n\tDUK_ERROR_RANGE(lex_ctx->thr, DUK_STR_TOKEN_LIMIT);\n\tDUK_WO_NORETURN(return;);\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_group:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_GROUP);\n\tDUK_WO_NORETURN(return;);\n\n#if !defined(DUK_USE_ES6_REGEXP_SYNTAX)\n fail_invalid_char:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_CHARACTER);\n\tDUK_WO_NORETURN(return;);\n\n fail_quantifier:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_QUANTIFIER);\n\tDUK_WO_NORETURN(return;);\n#endif\n}\n\n/*\n *  Special parser for character classes; calls callback for every\n *  range parsed and returns the number of ranges present.\n */\n\n/* XXX: this duplicates functionality in duk_regexp.c where a similar loop is\n * required anyway.  We could use that BUT we need to update the regexp compiler\n * 'nranges' too.  Work this out a bit more cleanly to save space.\n */\n\n/* XXX: the handling of character range detection is a bit convoluted.\n * Try to simplify and make smaller.\n */\n\n/* XXX: logic for handling character ranges is now incorrect, it will accept\n * e.g. [\\d-z] whereas it should croak from it?  SMJS accepts this too, though.\n *\n * Needs a read through and a lot of additional tests.\n */\n\nDUK_LOCAL\nvoid duk__emit_u16_direct_ranges(duk_lexer_ctx *lex_ctx,\n                                 duk_re_range_callback gen_range,\n                                 void *userdata,\n                                 const duk_uint16_t *ranges,\n                                 duk_small_int_t num) {\n\tconst duk_uint16_t *ranges_end;\n\n\tDUK_UNREF(lex_ctx);\n\n\tranges_end = ranges + num;\n\twhile (ranges < ranges_end) {\n\t\t/* mark range 'direct', bypass canonicalization (see Wiki) */\n\t\tgen_range(userdata, (duk_codepoint_t) ranges[0], (duk_codepoint_t) ranges[1], 1);\n\t\tranges += 2;\n\t}\n}\n\nDUK_INTERNAL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_range_callback gen_range, void *userdata) {\n\tduk_codepoint_t start = -1;\n\tduk_codepoint_t ch;\n\tduk_codepoint_t x;\n\tduk_bool_t dash = 0;\n\tduk_small_uint_t adv = 0;\n\n\tDUK_DD(DUK_DDPRINT(\"parsing regexp ranges\"));\n\n\tfor (;;) {\n\t\tDUK__ADVANCECHARS(lex_ctx, adv);\n\t\tadv = 1;\n\n\t\tx = DUK__L0();\n\n\t\tch = -1;  /* not strictly necessary, but avoids \"uninitialized variable\" warnings */\n\t\tDUK_UNREF(ch);\n\n\t\tif (x < 0) {\n\t\t\tgoto fail_unterm_charclass;\n\t\t} else if (x == DUK_ASC_RBRACKET) {\n\t\t\tif (start >= 0) {\n\t\t\t\tgen_range(userdata, start, start, 0);\n\t\t\t}\n\t\t\tDUK__ADVANCECHARS(lex_ctx, 1);  /* eat ']' before finishing */\n\t\t\tbreak;\n\t\t} else if (x == DUK_ASC_MINUS) {\n\t\t\tif (start >= 0 && !dash && DUK__L1() != DUK_ASC_RBRACKET) {\n\t\t\t\t/* '-' as a range indicator */\n\t\t\t\tdash = 1;\n\t\t\t\tcontinue;\n\t\t\t} else {\n\t\t\t\t/* '-' verbatim */\n\t\t\t\tch = x;\n\t\t\t}\n\t\t} else if (x == DUK_ASC_BACKSLASH) {\n\t\t\t/*\n\t\t\t *  The escapes are same as outside a character class, except that \\b has a\n\t\t\t *  different meaning, and \\B and backreferences are prohibited (see E5\n\t\t\t *  Section 15.10.2.19).  However, it's difficult to share code because we\n\t\t\t *  handle e.g. \"\\n\" very differently: here we generate a single character\n\t\t\t *  range for it.\n\t\t\t */\n\n\t\t\t/* XXX: ES2015 surrogate pair handling. */\n\n\t\t\tx = DUK__L1();\n\n\t\t\tadv = 2;\n\n\t\t\tif (x == DUK_ASC_LC_B) {\n\t\t\t\t/* Note: '\\b' in char class is different than outside (assertion),\n\t\t\t\t * '\\B' is not allowed and is caught by the duk_unicode_is_identifier_part()\n\t\t\t\t * check below.\n\t\t\t\t */\n\t\t\t\tch = 0x0008;\n\t\t\t} else if (x == DUK_ASC_LC_F) {\n\t\t\t\tch = 0x000c;\n\t\t\t} else if (x == DUK_ASC_LC_N) {\n\t\t\t\tch = 0x000a;\n\t\t\t} else if (x == DUK_ASC_LC_T) {\n\t\t\t\tch = 0x0009;\n\t\t\t} else if (x == DUK_ASC_LC_R) {\n\t\t\t\tch = 0x000d;\n\t\t\t} else if (x == DUK_ASC_LC_V) {\n\t\t\t\tch = 0x000b;\n\t\t\t} else if (x == DUK_ASC_LC_C) {\n\t\t\t\tx = DUK__L2();\n\t\t\t\tadv = 3;\n\t\t\t\tif ((x >= DUK_ASC_LC_A && x <= DUK_ASC_LC_Z) ||\n\t\t\t\t    (x >= DUK_ASC_UC_A && x <= DUK_ASC_UC_Z)) {\n\t\t\t\t\tch = (x % 32);\n\t\t\t\t} else {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n\t\t\t} else if (x == DUK_ASC_LC_X || x == DUK_ASC_LC_U) {\n\t\t\t\t/* The \\u{H+} form is only allowed in Unicode mode which\n\t\t\t\t * we don't support yet.\n\t\t\t\t */\n\t\t\t\tch = duk__lexer_parse_escape(lex_ctx, 0 /*allow_es6*/);\n\t\t\t\tadv = 0;\n\t\t\t} else if (x == DUK_ASC_LC_D) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_digit,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_digit) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_UC_D) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_not_digit,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_not_digit) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_LC_S) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_white,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_white) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_UC_S) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_not_white,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_not_white) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_LC_W) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_wordchar,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_wordchar) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (x == DUK_ASC_UC_W) {\n\t\t\t\tduk__emit_u16_direct_ranges(lex_ctx,\n\t\t\t\t                            gen_range,\n\t\t\t\t                            userdata,\n\t\t\t\t                            duk_unicode_re_ranges_not_wordchar,\n\t\t\t\t                            sizeof(duk_unicode_re_ranges_not_wordchar) / sizeof(duk_uint16_t));\n\t\t\t\tch = -1;\n\t\t\t} else if (DUK__ISDIGIT(x)) {\n\t\t\t\t/* DecimalEscape, only \\0 is allowed, no leading\n\t\t\t\t * zeroes are allowed.\n\t\t\t\t *\n\t\t\t\t * ES2015 Annex B also allows (maximal match) legacy\n\t\t\t\t * octal escapes up to \\377 and \\8 and \\9 are\n\t\t\t\t * accepted as literal '8' and '9', also in strict mode.\n\t\t\t\t */\n\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t\t\tch = duk__lexer_parse_legacy_octal(lex_ctx, &adv, 0 /*reject_annex_b*/);\n\t\t\t\tDUK_ASSERT(ch >= 0);  /* no rejections */\n#else\n\t\t\t\tif (x == DUK_ASC_0 && !DUK__ISDIGIT(DUK__L2())) {\n\t\t\t\t\tch = 0x0000;\n\t\t\t\t} else {\n\t\t\t\t\tgoto fail_escape;\n\t\t\t\t}\n#endif\n#if defined(DUK_USE_ES6_REGEXP_SYNTAX)\n\t\t\t} else if (x >= 0) {\n\t\t\t\t/* IdentityEscape: ES2015 Annex B allows almost all\n\t\t\t\t * source characters here.  Match anything except\n\t\t\t\t * EOF here.\n\t\t\t\t */\n\t\t\t\tch = x;\n#else  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t\t} else if (!duk_unicode_is_identifier_part(x)) {\n\t\t\t\t/* IdentityEscape: ES5.1 doesn't allow identity escape\n\t\t\t\t * for identifier part characters, which conflicts with\n\t\t\t\t * some real world code.  For example, it doesn't allow\n\t\t\t\t * /[\\$]/ which is awkward.\n\t\t\t\t */\n\t\t\t\tch = x;\n#endif  /* DUK_USE_ES6_REGEXP_SYNTAX */\n\t\t\t} else {\n\t\t\t\tgoto fail_escape;\n\t\t\t}\n\t\t} else {\n\t\t\t/* character represents itself */\n\t\t\tch = x;\n\t\t}\n\n\t\t/* ch is a literal character here or -1 if parsed entity was\n\t\t * an escape such as \"\\s\".\n\t\t */\n\n\t\tif (ch < 0) {\n\t\t\t/* multi-character sets not allowed as part of ranges, see\n\t\t\t * E5 Section 15.10.2.15, abstract operation CharacterRange.\n\t\t\t */\n\t\t\tif (start >= 0) {\n\t\t\t\tif (dash) {\n\t\t\t\t\tgoto fail_range;\n\t\t\t\t} else {\n\t\t\t\t\tgen_range(userdata, start, start, 0);\n\t\t\t\t\tstart = -1;\n\t\t\t\t\t/* dash is already 0 */\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (start >= 0) {\n\t\t\t\tif (dash) {\n\t\t\t\t\tif (start > ch) {\n\t\t\t\t\t\tgoto fail_range;\n\t\t\t\t\t}\n\t\t\t\t\tgen_range(userdata, start, ch, 0);\n\t\t\t\t\tstart = -1;\n\t\t\t\t\tdash = 0;\n\t\t\t\t} else {\n\t\t\t\t\tgen_range(userdata, start, start, 0);\n\t\t\t\t\tstart = ch;\n\t\t\t\t\t/* dash is already 0 */\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstart = ch;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn;\n\n fail_escape:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_REGEXP_ESCAPE);\n\tDUK_WO_NORETURN(return;);\n\n fail_range:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_INVALID_RANGE);\n\tDUK_WO_NORETURN(return;);\n\n fail_unterm_charclass:\n\tDUK_ERROR_SYNTAX(lex_ctx->thr, DUK_STR_UNTERMINATED_CHARCLASS);\n\tDUK_WO_NORETURN(return;);\n}\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_lexer.h",
    "content": "/*\n *  Lexer defines.\n */\n\n#if !defined(DUK_LEXER_H_INCLUDED)\n#define DUK_LEXER_H_INCLUDED\n\ntypedef void (*duk_re_range_callback)(void *user, duk_codepoint_t r1, duk_codepoint_t r2, duk_bool_t direct);\n\n/*\n *  A token is interpreted as any possible production of InputElementDiv\n *  and InputElementRegExp, see E5 Section 7 in its entirety.  Note that\n *  the E5 \"Token\" production does not cover all actual tokens of the\n *  language (which is explicitly stated in the specification, Section 7.5).\n *  Null and boolean literals are defined as part of both ReservedWord\n *  (E5 Section 7.6.1) and Literal (E5 Section 7.8) productions.  Here,\n *  null and boolean values have literal tokens, and are not reserved\n *  words.\n *\n *  Decimal literal negative/positive sign is -not- part of DUK_TOK_NUMBER.\n *  The number tokens always have a non-negative value.  The unary minus\n *  operator in \"-1.0\" is optimized during compilation to yield a single\n *  negative constant.\n *\n *  Token numbering is free except that reserved words are required to be\n *  in a continuous range and in a particular order.  See genstrings.py.\n */\n\n#define DUK_LEXER_INITCTX(ctx)        duk_lexer_initctx((ctx))\n\n#define DUK_LEXER_SETPOINT(ctx,pt)    duk_lexer_setpoint((ctx), (pt))\n\n#define DUK_LEXER_GETPOINT(ctx,pt)    duk_lexer_getpoint((ctx), (pt))\n\n/* Currently 6 characters of lookup are actually needed (duk_lexer.c). */\n#define DUK_LEXER_WINDOW_SIZE                     6\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\n#define DUK_LEXER_BUFFER_SIZE                     64\n#endif\n\n#define DUK_TOK_MINVAL                            0\n\n/* returned after EOF (infinite amount) */\n#define DUK_TOK_EOF                               0\n\n/* identifier names (E5 Section 7.6) */\n#define DUK_TOK_IDENTIFIER                        1\n\n/* reserved words: keywords */\n#define DUK_TOK_START_RESERVED                    2\n#define DUK_TOK_BREAK                             2\n#define DUK_TOK_CASE                              3\n#define DUK_TOK_CATCH                             4\n#define DUK_TOK_CONTINUE                          5\n#define DUK_TOK_DEBUGGER                          6\n#define DUK_TOK_DEFAULT                           7\n#define DUK_TOK_DELETE                            8\n#define DUK_TOK_DO                                9\n#define DUK_TOK_ELSE                              10\n#define DUK_TOK_FINALLY                           11\n#define DUK_TOK_FOR                               12\n#define DUK_TOK_FUNCTION                          13\n#define DUK_TOK_IF                                14\n#define DUK_TOK_IN                                15\n#define DUK_TOK_INSTANCEOF                        16\n#define DUK_TOK_NEW                               17\n#define DUK_TOK_RETURN                            18\n#define DUK_TOK_SWITCH                            19\n#define DUK_TOK_THIS                              20\n#define DUK_TOK_THROW                             21\n#define DUK_TOK_TRY                               22\n#define DUK_TOK_TYPEOF                            23\n#define DUK_TOK_VAR                               24\n#define DUK_TOK_CONST                             25\n#define DUK_TOK_VOID                              26\n#define DUK_TOK_WHILE                             27\n#define DUK_TOK_WITH                              28\n\n/* reserved words: future reserved words */\n#define DUK_TOK_CLASS                             29\n#define DUK_TOK_ENUM                              30\n#define DUK_TOK_EXPORT                            31\n#define DUK_TOK_EXTENDS                           32\n#define DUK_TOK_IMPORT                            33\n#define DUK_TOK_SUPER                             34\n\n/* \"null\", \"true\", and \"false\" are always reserved words.\n * Note that \"get\" and \"set\" are not!\n */\n#define DUK_TOK_NULL                              35\n#define DUK_TOK_TRUE                              36\n#define DUK_TOK_FALSE                             37\n\n/* reserved words: additional future reserved words in strict mode */\n#define DUK_TOK_START_STRICT_RESERVED             38  /* inclusive */\n#define DUK_TOK_IMPLEMENTS                        38\n#define DUK_TOK_INTERFACE                         39\n#define DUK_TOK_LET                               40\n#define DUK_TOK_PACKAGE                           41\n#define DUK_TOK_PRIVATE                           42\n#define DUK_TOK_PROTECTED                         43\n#define DUK_TOK_PUBLIC                            44\n#define DUK_TOK_STATIC                            45\n#define DUK_TOK_YIELD                             46\n\n#define DUK_TOK_END_RESERVED                      47  /* exclusive */\n\n/* \"get\" and \"set\" are tokens but NOT ReservedWords.  They are currently\n * parsed and identifiers and these defines are actually now unused.\n */\n#define DUK_TOK_GET                               47\n#define DUK_TOK_SET                               48\n\n/* punctuators (unlike the spec, also includes \"/\" and \"/=\") */\n#define DUK_TOK_LCURLY                            49\n#define DUK_TOK_RCURLY                            50\n#define DUK_TOK_LBRACKET                          51\n#define DUK_TOK_RBRACKET                          52\n#define DUK_TOK_LPAREN                            53\n#define DUK_TOK_RPAREN                            54\n#define DUK_TOK_PERIOD                            55\n#define DUK_TOK_SEMICOLON                         56\n#define DUK_TOK_COMMA                             57\n#define DUK_TOK_LT                                58\n#define DUK_TOK_GT                                59\n#define DUK_TOK_LE                                60\n#define DUK_TOK_GE                                61\n#define DUK_TOK_EQ                                62\n#define DUK_TOK_NEQ                               63\n#define DUK_TOK_SEQ                               64\n#define DUK_TOK_SNEQ                              65\n#define DUK_TOK_ADD                               66\n#define DUK_TOK_SUB                               67\n#define DUK_TOK_MUL                               68\n#define DUK_TOK_DIV                               69\n#define DUK_TOK_MOD                               70\n#define DUK_TOK_EXP                               71\n#define DUK_TOK_INCREMENT                         72\n#define DUK_TOK_DECREMENT                         73\n#define DUK_TOK_ALSHIFT                           74   /* named \"arithmetic\" because result is signed */\n#define DUK_TOK_ARSHIFT                           75\n#define DUK_TOK_RSHIFT                            76\n#define DUK_TOK_BAND                              77\n#define DUK_TOK_BOR                               78\n#define DUK_TOK_BXOR                              79\n#define DUK_TOK_LNOT                              80\n#define DUK_TOK_BNOT                              81\n#define DUK_TOK_LAND                              82\n#define DUK_TOK_LOR                               83\n#define DUK_TOK_QUESTION                          84\n#define DUK_TOK_COLON                             85\n#define DUK_TOK_EQUALSIGN                         86\n#define DUK_TOK_ADD_EQ                            87\n#define DUK_TOK_SUB_EQ                            88\n#define DUK_TOK_MUL_EQ                            89\n#define DUK_TOK_DIV_EQ                            90\n#define DUK_TOK_MOD_EQ                            91\n#define DUK_TOK_EXP_EQ                            92\n#define DUK_TOK_ALSHIFT_EQ                        93\n#define DUK_TOK_ARSHIFT_EQ                        94\n#define DUK_TOK_RSHIFT_EQ                         95\n#define DUK_TOK_BAND_EQ                           96\n#define DUK_TOK_BOR_EQ                            97\n#define DUK_TOK_BXOR_EQ                           98\n\n/* literals (E5 Section 7.8), except null, true, false, which are treated\n * like reserved words (above).\n */\n#define DUK_TOK_NUMBER                            99\n#define DUK_TOK_STRING                            100\n#define DUK_TOK_REGEXP                            101\n\n#define DUK_TOK_MAXVAL                            101  /* inclusive */\n\n#define DUK_TOK_INVALID                           DUK_SMALL_UINT_MAX\n\n/* Convert heap string index to a token (reserved words) */\n#define DUK_STRIDX_TO_TOK(x)                        ((x) - DUK_STRIDX_START_RESERVED + DUK_TOK_START_RESERVED)\n\n/* Sanity check */\n#if (DUK_TOK_MAXVAL > 255)\n#error DUK_TOK_MAXVAL too large, code assumes it fits into 8 bits\n#endif\n\n/* Sanity checks for string and token defines */\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_BREAK) != DUK_TOK_BREAK)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CASE) != DUK_TOK_CASE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CATCH) != DUK_TOK_CATCH)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CONTINUE) != DUK_TOK_CONTINUE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DEBUGGER) != DUK_TOK_DEBUGGER)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DEFAULT) != DUK_TOK_DEFAULT)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DELETE) != DUK_TOK_DELETE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_DO) != DUK_TOK_DO)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_ELSE) != DUK_TOK_ELSE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_FINALLY) != DUK_TOK_FINALLY)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_FOR) != DUK_TOK_FOR)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_LC_FUNCTION) != DUK_TOK_FUNCTION)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IF) != DUK_TOK_IF)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IN) != DUK_TOK_IN)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_INSTANCEOF) != DUK_TOK_INSTANCEOF)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_NEW) != DUK_TOK_NEW)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_RETURN) != DUK_TOK_RETURN)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_SWITCH) != DUK_TOK_SWITCH)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_THIS) != DUK_TOK_THIS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_THROW) != DUK_TOK_THROW)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_TRY) != DUK_TOK_TRY)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_TYPEOF) != DUK_TOK_TYPEOF)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_VAR) != DUK_TOK_VAR)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_VOID) != DUK_TOK_VOID)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_WHILE) != DUK_TOK_WHILE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_WITH) != DUK_TOK_WITH)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CLASS) != DUK_TOK_CLASS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_CONST) != DUK_TOK_CONST)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_ENUM) != DUK_TOK_ENUM)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_EXPORT) != DUK_TOK_EXPORT)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_EXTENDS) != DUK_TOK_EXTENDS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IMPORT) != DUK_TOK_IMPORT)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_SUPER) != DUK_TOK_SUPER)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_LC_NULL) != DUK_TOK_NULL)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_TRUE) != DUK_TOK_TRUE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_FALSE) != DUK_TOK_FALSE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_IMPLEMENTS) != DUK_TOK_IMPLEMENTS)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_INTERFACE) != DUK_TOK_INTERFACE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_LET) != DUK_TOK_LET)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PACKAGE) != DUK_TOK_PACKAGE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PRIVATE) != DUK_TOK_PRIVATE)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PROTECTED) != DUK_TOK_PROTECTED)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_PUBLIC) != DUK_TOK_PUBLIC)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_STATIC) != DUK_TOK_STATIC)\n#error mismatch in token defines\n#endif\n#if (DUK_STRIDX_TO_TOK(DUK_STRIDX_YIELD) != DUK_TOK_YIELD)\n#error mismatch in token defines\n#endif\n\n/* Regexp tokens */\n#define DUK_RETOK_EOF                              0\n#define DUK_RETOK_DISJUNCTION                      1\n#define DUK_RETOK_QUANTIFIER                       2\n#define DUK_RETOK_ASSERT_START                     3\n#define DUK_RETOK_ASSERT_END                       4\n#define DUK_RETOK_ASSERT_WORD_BOUNDARY             5\n#define DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY         6\n#define DUK_RETOK_ASSERT_START_POS_LOOKAHEAD       7\n#define DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD       8\n#define DUK_RETOK_ATOM_PERIOD                      9\n#define DUK_RETOK_ATOM_CHAR                        10\n#define DUK_RETOK_ATOM_DIGIT                       11  /* assumptions in regexp compiler */\n#define DUK_RETOK_ATOM_NOT_DIGIT                   12  /* -\"\"- */\n#define DUK_RETOK_ATOM_WHITE                       13  /* -\"\"- */\n#define DUK_RETOK_ATOM_NOT_WHITE                   14  /* -\"\"- */\n#define DUK_RETOK_ATOM_WORD_CHAR                   15  /* -\"\"- */\n#define DUK_RETOK_ATOM_NOT_WORD_CHAR               16  /* -\"\"- */\n#define DUK_RETOK_ATOM_BACKREFERENCE               17\n#define DUK_RETOK_ATOM_START_CAPTURE_GROUP         18\n#define DUK_RETOK_ATOM_START_NONCAPTURE_GROUP      19\n#define DUK_RETOK_ATOM_START_CHARCLASS             20\n#define DUK_RETOK_ATOM_START_CHARCLASS_INVERTED    21\n#define DUK_RETOK_ATOM_END_GROUP                   22\n\n/* Constants for duk_lexer_ctx.buf. */\n#define DUK_LEXER_TEMP_BUF_LIMIT                   256\n\n/* A token value.  Can be memcpy()'d, but note that slot1/slot2 values are on the valstack.\n * Some fields (like num, str1, str2) are only valid for specific token types and may have\n * stale values otherwise.\n */\nstruct duk_token {\n\tduk_small_uint_t t;           /* token type (with reserved word identification) */\n\tduk_small_uint_t t_nores;     /* token type (with reserved words as DUK_TOK_IDENTIFER) */\n\tduk_double_t num;             /* numeric value of token */\n\tduk_hstring *str1;            /* string 1 of token (borrowed, stored to ctx->slot1_idx) */\n\tduk_hstring *str2;            /* string 2 of token (borrowed, stored to ctx->slot2_idx) */\n\tduk_size_t start_offset;      /* start byte offset of token in lexer input */\n\tduk_int_t start_line;         /* start line of token (first char) */\n\tduk_int_t num_escapes;        /* number of escapes and line continuations (for directive prologue) */\n\tduk_bool_t lineterm;          /* token was preceded by a lineterm */\n\tduk_bool_t allow_auto_semi;   /* token allows automatic semicolon insertion (eof or preceded by newline) */\n};\n\n#define DUK_RE_QUANTIFIER_INFINITE         ((duk_uint32_t) 0xffffffffUL)\n\n/* A regexp token value. */\nstruct duk_re_token {\n\tduk_small_uint_t t;          /* token type */\n\tduk_small_uint_t greedy;\n\tduk_uint32_t num;            /* numeric value (character, count) */\n\tduk_uint32_t qmin;\n\tduk_uint32_t qmax;\n};\n\n/* A structure for 'snapshotting' a point for rewinding */\nstruct duk_lexer_point {\n\tduk_size_t offset;\n\tduk_int_t line;\n};\n\n/* Lexer codepoint with additional info like offset/line number */\nstruct duk_lexer_codepoint {\n\tduk_codepoint_t codepoint;\n\tduk_size_t offset;\n\tduk_int_t line;\n};\n\n/* Lexer context.  Same context is used for ECMAScript and Regexp parsing. */\nstruct duk_lexer_ctx {\n#if defined(DUK_USE_LEXER_SLIDING_WINDOW)\n\tduk_lexer_codepoint *window; /* unicode code points, window[0] is always next, points to 'buffer' */\n\tduk_lexer_codepoint buffer[DUK_LEXER_BUFFER_SIZE];\n#else\n\tduk_lexer_codepoint window[DUK_LEXER_WINDOW_SIZE]; /* unicode code points, window[0] is always next */\n#endif\n\n\tduk_hthread *thr;                              /* thread; minimizes argument passing */\n\n\tconst duk_uint8_t *input;                      /* input string (may be a user pointer) */\n\tduk_size_t input_length;                       /* input byte length */\n\tduk_size_t input_offset;                       /* input offset for window leading edge (not window[0]) */\n\tduk_int_t input_line;                          /* input linenumber at input_offset (not window[0]), init to 1 */\n\n\tduk_idx_t slot1_idx;                           /* valstack slot for 1st token value */\n\tduk_idx_t slot2_idx;                           /* valstack slot for 2nd token value */\n\tduk_idx_t buf_idx;                             /* valstack slot for temp buffer */\n\tduk_hbuffer_dynamic *buf;                      /* temp accumulation buffer */\n\tduk_bufwriter_ctx bw;                          /* bufwriter for temp accumulation */\n\n\tduk_int_t token_count;                         /* number of tokens parsed */\n\tduk_int_t token_limit;                         /* maximum token count before error (sanity backstop) */\n\n\tduk_small_uint_t flags;                        /* lexer flags, use compiler flag defines for now */\n};\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_lexer_initctx(duk_lexer_ctx *lex_ctx);\n\nDUK_INTERNAL_DECL void duk_lexer_getpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt);\nDUK_INTERNAL_DECL void duk_lexer_setpoint(duk_lexer_ctx *lex_ctx, duk_lexer_point *pt);\n\nDUK_INTERNAL_DECL\nvoid duk_lexer_parse_js_input_element(duk_lexer_ctx *lex_ctx,\n                                      duk_token *out_token,\n                                      duk_bool_t strict_mode,\n                                      duk_bool_t regexp_mode);\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL_DECL void duk_lexer_parse_re_token(duk_lexer_ctx *lex_ctx, duk_re_token *out_token);\nDUK_INTERNAL_DECL void duk_lexer_parse_re_ranges(duk_lexer_ctx *lex_ctx, duk_re_range_callback gen_range, void *userdata);\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n\n#endif  /* DUK_LEXER_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_numconv.c",
    "content": "/*\n *  Number-to-string and string-to-number conversions.\n *\n *  Slow path number-to-string and string-to-number conversion is based on\n *  a Dragon4 variant, with fast paths for small integers.  Big integer\n *  arithmetic is needed for guaranteeing that the conversion is correct\n *  and uses a minimum number of digits.  The big number arithmetic has a\n *  fixed maximum size and does not require dynamic allocations.\n *\n *  See: doc/number-conversion.rst.\n */\n\n#include \"duk_internal.h\"\n\n#define DUK__IEEE_DOUBLE_EXP_BIAS  1023\n#define DUK__IEEE_DOUBLE_EXP_MIN   (-1022)   /* biased exp == 0 -> denormal, exp -1022 */\n\n#define DUK__DIGITCHAR(x)  duk_lc_digits[(x)]\n\n/*\n *  Tables generated with util/gennumdigits.py.\n *\n *  duk__str2num_digits_for_radix indicates, for each radix, how many input\n *  digits should be considered significant for string-to-number conversion.\n *  The input is also padded to this many digits to give the Dragon4\n *  conversion enough (apparent) precision to work with.\n *\n *  duk__str2num_exp_limits indicates, for each radix, the radix-specific\n *  minimum/maximum exponent values (for a Dragon4 integer mantissa)\n *  below and above which the number is guaranteed to underflow to zero\n *  or overflow to Infinity.  This allows parsing to keep bigint values\n *  bounded.\n */\n\nDUK_LOCAL const duk_uint8_t duk__str2num_digits_for_radix[] = {\n\t69, 44, 35, 30, 27, 25, 23, 22, 20, 20,    /* 2 to 11 */\n\t20, 19, 19, 18, 18, 17, 17, 17, 16, 16,    /* 12 to 21 */\n\t16, 16, 16, 15, 15, 15, 15, 15, 15, 14,    /* 22 to 31 */\n\t14, 14, 14, 14, 14                         /* 31 to 36 */\n};\n\ntypedef struct {\n\tduk_int16_t upper;\n\tduk_int16_t lower;\n} duk__exp_limits;\n\nDUK_LOCAL const duk__exp_limits duk__str2num_exp_limits[] = {\n\t{ 957, -1147 }, { 605, -725 },  { 479, -575 },  { 414, -496 },\n\t{ 372, -446 },  { 342, -411 },  { 321, -384 },  { 304, -364 },\n\t{ 291, -346 },  { 279, -334 },  { 268, -323 },  { 260, -312 },\n\t{ 252, -304 },  { 247, -296 },  { 240, -289 },  { 236, -283 },\n\t{ 231, -278 },  { 227, -273 },  { 223, -267 },  { 220, -263 },\n\t{ 216, -260 },  { 213, -256 },  { 210, -253 },  { 208, -249 },\n\t{ 205, -246 },  { 203, -244 },  { 201, -241 },  { 198, -239 },\n\t{ 196, -237 },  { 195, -234 },  { 193, -232 },  { 191, -230 },\n\t{ 190, -228 },  { 188, -226 },  { 187, -225 },\n};\n\n/*\n *  Limited functionality bigint implementation.\n *\n *  Restricted to non-negative numbers with less than 32 * DUK__BI_MAX_PARTS bits,\n *  with the caller responsible for ensuring this is never exceeded.  No memory\n *  allocation (except stack) is needed for bigint computation.  Operations\n *  have been tailored for number conversion needs.\n *\n *  Argument order is \"assignment order\", i.e. target first, then arguments:\n *  x <- y * z  -->  duk__bi_mul(x, y, z);\n */\n\n/* This upper value has been experimentally determined; debug build will check\n * bigint size with assertions.\n */\n#define DUK__BI_MAX_PARTS  37  /* 37x32 = 1184 bits */\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n#define DUK__BI_PRINT(name,x)  duk__bi_print((name),(x))\n#else\n#define DUK__BI_PRINT(name,x)\n#endif\n\n/* Current size is about 152 bytes. */\ntypedef struct {\n\tduk_small_int_t n;\n\tduk_uint32_t v[DUK__BI_MAX_PARTS];  /* low to high */\n} duk__bigint;\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\nDUK_LOCAL void duk__bi_print(const char *name, duk__bigint *x) {\n\t/* Overestimate required size; debug code so not critical to be tight. */\n\tchar buf[DUK__BI_MAX_PARTS * 9 + 64];\n\tchar *p = buf;\n\tduk_small_int_t i;\n\n\t/* No NUL term checks in this debug code. */\n\tp += DUK_SPRINTF(p, \"%p n=%ld\", (void *) x, (long) x->n);\n\tif (x->n == 0) {\n\t\tp += DUK_SPRINTF(p, \" 0\");\n\t}\n\tfor (i = x->n - 1; i >= 0; i--) {\n\t\tp += DUK_SPRINTF(p, \" %08lx\", (unsigned long) x->v[i]);\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"%s: %s\", (const char *) name, (const char *) buf));\n}\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_LOCAL duk_small_int_t duk__bi_is_valid(duk__bigint *x) {\n\treturn (duk_small_int_t)\n\t       ( ((x->n >= 0) && (x->n <= DUK__BI_MAX_PARTS)) /* is valid size */ &&\n\t         ((x->n == 0) || (x->v[x->n - 1] != 0)) /* is normalized */ );\n}\n#endif\n\nDUK_LOCAL void duk__bi_normalize(duk__bigint *x) {\n\tduk_small_int_t i;\n\n\tfor (i = x->n - 1; i >= 0; i--) {\n\t\tif (x->v[i] != 0) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* Note: if 'x' is zero, x->n becomes 0 here */\n\tx->n = i + 1;\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* x <- y */\nDUK_LOCAL void duk__bi_copy(duk__bigint *x, duk__bigint *y) {\n\tduk_small_int_t n;\n\n\tn = y->n;\n\tx->n = n;\n\t/* No need to special case n == 0. */\n\tduk_memcpy((void *) x->v, (const void *) y->v, (size_t) (sizeof(duk_uint32_t) * (size_t) n));\n}\n\nDUK_LOCAL void duk__bi_set_small(duk__bigint *x, duk_uint32_t v) {\n\tif (v == 0U) {\n\t\tx->n = 0;\n\t} else {\n\t\tx->n = 1;\n\t\tx->v[0] = v;\n\t}\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* Return value: <0  <=>  x < y\n *                0  <=>  x == y\n *               >0  <=>  x > y\n */\nDUK_LOCAL int duk__bi_compare(duk__bigint *x, duk__bigint *y) {\n\tduk_small_int_t i, nx, ny;\n\tduk_uint32_t tx, ty;\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\tnx = x->n;\n\tny = y->n;\n\tif (nx > ny) {\n\t\tgoto ret_gt;\n\t}\n\tif (nx < ny) {\n\t\tgoto ret_lt;\n\t}\n\tfor (i = nx - 1; i >= 0; i--) {\n\t\ttx = x->v[i];\n\t\tty = y->v[i];\n\n\t\tif (tx > ty) {\n\t\t\tgoto ret_gt;\n\t\t}\n\t\tif (tx < ty) {\n\t\t\tgoto ret_lt;\n\t\t}\n\t}\n\n\treturn 0;\n\n ret_gt:\n\treturn 1;\n\n ret_lt:\n\treturn -1;\n}\n\n/* x <- y + z */\n#if defined(DUK_USE_64BIT_OPS)\nDUK_LOCAL void duk__bi_add(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_uint64_t tmp;\n\tduk_small_int_t i, ny, nz;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\n\tif (z->n > y->n) {\n\t\tduk__bigint *t;\n\t\tt = y; y = z; z = t;\n\t}\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\ttmp = 0U;\n\tfor (i = 0; i < ny; i++) {\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\ttmp += y->v[i];\n\t\tif (i < nz) {\n\t\t\ttmp += z->v[i];\n\t\t}\n\t\tx->v[i] = (duk_uint32_t) (tmp & 0xffffffffUL);\n\t\ttmp = tmp >> 32;\n\t}\n\tif (tmp != 0U) {\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\tx->v[i++] = (duk_uint32_t) tmp;\n\t}\n\tx->n = i;\n\tDUK_ASSERT(x->n <= DUK__BI_MAX_PARTS);\n\n\t/* no need to normalize */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#else  /* DUK_USE_64BIT_OPS */\nDUK_LOCAL void duk__bi_add(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_uint32_t carry, tmp1, tmp2;\n\tduk_small_int_t i, ny, nz;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\n\tif (z->n > y->n) {\n\t\tduk__bigint *t;\n\t\tt = y; y = z; z = t;\n\t}\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\tcarry = 0U;\n\tfor (i = 0; i < ny; i++) {\n\t\t/* Carry is detected based on wrapping which relies on exact 32-bit\n\t\t * types.\n\t\t */\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\ttmp1 = y->v[i];\n\t\ttmp2 = tmp1;\n\t\tif (i < nz) {\n\t\t\ttmp2 += z->v[i];\n\t\t}\n\n\t\t/* Careful with carry condition:\n\t\t *  - If carry not added: 0x12345678 + 0 + 0xffffffff = 0x12345677 (< 0x12345678)\n\t\t *  - If carry added:     0x12345678 + 1 + 0xffffffff = 0x12345678 (== 0x12345678)\n\t\t */\n\t\tif (carry) {\n\t\t\ttmp2++;\n\t\t\tcarry = (tmp2 <= tmp1 ? 1U : 0U);\n\t\t} else {\n\t\t\tcarry = (tmp2 < tmp1 ? 1U : 0U);\n\t\t}\n\n\t\tx->v[i] = tmp2;\n\t}\n\tif (carry) {\n\t\tDUK_ASSERT(i < DUK__BI_MAX_PARTS);\n\t\tDUK_ASSERT(carry == 1U);\n\t\tx->v[i++] = carry;\n\t}\n\tx->n = i;\n\tDUK_ASSERT(x->n <= DUK__BI_MAX_PARTS);\n\n\t/* no need to normalize */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#endif  /* DUK_USE_64BIT_OPS */\n\n/* x <- y + z */\nDUK_LOCAL void duk__bi_add_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) {\n\tduk__bigint tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\t/* XXX: this could be optimized; there is only one call site now though */\n\tduk__bi_set_small(&tmp, z);\n\tduk__bi_add(x, y, &tmp);\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n#if 0  /* unused */\n/* x <- x + y, use t as temp */\nDUK_LOCAL void duk__bi_add_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) {\n\tduk__bi_add(t, x, y);\n\tduk__bi_copy(x, t);\n}\n#endif\n\n/* x <- y - z, require x >= y => z >= 0, i.e. y >= z */\n#if defined(DUK_USE_64BIT_OPS)\nDUK_LOCAL void duk__bi_sub(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_small_int_t i, ny, nz;\n\tduk_uint32_t ty, tz;\n\tduk_int64_t tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\tDUK_ASSERT(duk__bi_compare(y, z) >= 0);\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\ttmp = 0;\n\tfor (i = 0; i < ny; i++) {\n\t\tty = y->v[i];\n\t\tif (i < nz) {\n\t\t\ttz = z->v[i];\n\t\t} else {\n\t\t\ttz = 0;\n\t\t}\n\t\ttmp = (duk_int64_t) ty - (duk_int64_t) tz + tmp;\n\t\tx->v[i] = (duk_uint32_t) ((duk_uint64_t) tmp & 0xffffffffUL);\n\t\ttmp = tmp >> 32;  /* 0 or -1 */\n\t}\n\tDUK_ASSERT(tmp == 0);\n\n\tx->n = i;\n\tduk__bi_normalize(x);  /* need to normalize, may even cancel to 0 */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#else\nDUK_LOCAL void duk__bi_sub(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_small_int_t i, ny, nz;\n\tduk_uint32_t tmp1, tmp2, borrow;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\tDUK_ASSERT(duk__bi_compare(y, z) >= 0);\n\tDUK_ASSERT(y->n >= z->n);\n\n\tny = y->n; nz = z->n;\n\tborrow = 0U;\n\tfor (i = 0; i < ny; i++) {\n\t\t/* Borrow is detected based on wrapping which relies on exact 32-bit\n\t\t * types.\n\t\t */\n\t\ttmp1 = y->v[i];\n\t\ttmp2 = tmp1;\n\t\tif (i < nz) {\n\t\t\ttmp2 -= z->v[i];\n\t\t}\n\n\t\t/* Careful with borrow condition:\n\t\t *  - If borrow not subtracted: 0x12345678 - 0 - 0xffffffff = 0x12345679 (> 0x12345678)\n\t\t *  - If borrow subtracted:     0x12345678 - 1 - 0xffffffff = 0x12345678 (== 0x12345678)\n\t\t */\n\t\tif (borrow) {\n\t\t\ttmp2--;\n\t\t\tborrow = (tmp2 >= tmp1 ? 1U : 0U);\n\t\t} else {\n\t\t\tborrow = (tmp2 > tmp1 ? 1U : 0U);\n\t\t}\n\n\t\tx->v[i] = tmp2;\n\t}\n\tDUK_ASSERT(borrow == 0U);\n\n\tx->n = i;\n\tduk__bi_normalize(x);  /* need to normalize, may even cancel to 0 */\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#endif\n\n#if 0  /* unused */\n/* x <- y - z */\nDUK_LOCAL void duk__bi_sub_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) {\n\tduk__bigint tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\t/* XXX: this could be optimized */\n\tduk__bi_set_small(&tmp, z);\n\tduk__bi_sub(x, y, &tmp);\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n#endif\n\n/* x <- x - y, use t as temp */\nDUK_LOCAL void duk__bi_sub_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) {\n\tduk__bi_sub(t, x, y);\n\tduk__bi_copy(x, t);\n}\n\n/* x <- y * z */\nDUK_LOCAL void duk__bi_mul(duk__bigint *x, duk__bigint *y, duk__bigint *z) {\n\tduk_small_int_t i, j, nx, nz;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\tDUK_ASSERT(duk__bi_is_valid(z));\n\n\tnx = y->n + z->n;  /* max possible */\n\tDUK_ASSERT(nx <= DUK__BI_MAX_PARTS);\n\n\tif (nx == 0) {\n\t\t/* Both inputs are zero; cases where only one is zero can go\n\t\t * through main algorithm.\n\t\t */\n\t\tx->n = 0;\n\t\treturn;\n\t}\n\n\tduk_memzero((void *) x->v, (size_t) (sizeof(duk_uint32_t) * (size_t) nx));\n\tx->n = nx;\n\n\tnz = z->n;\n\tfor (i = 0; i < y->n; i++) {\n#if defined(DUK_USE_64BIT_OPS)\n\t\tduk_uint64_t tmp = 0U;\n\t\tfor (j = 0; j < nz; j++) {\n\t\t\ttmp += (duk_uint64_t) y->v[i] * (duk_uint64_t) z->v[j] + x->v[i+j];\n\t\t\tx->v[i+j] = (duk_uint32_t) (tmp & 0xffffffffUL);\n\t\t\ttmp = tmp >> 32;\n\t\t}\n\t\tif (tmp > 0) {\n\t\t\tDUK_ASSERT(i + j < nx);\n\t\t\tDUK_ASSERT(i + j < DUK__BI_MAX_PARTS);\n\t\t\tDUK_ASSERT(x->v[i+j] == 0U);\n\t\t\tx->v[i+j] = (duk_uint32_t) tmp;\n\t\t}\n#else\n\t\t/*\n\t\t *  Multiply + add + carry for 32-bit components using only 16x16->32\n\t\t *  multiplies and carry detection based on unsigned overflow.\n\t\t *\n\t\t *    1st mult, 32-bit: (A*2^16 + B)\n\t\t *    2nd mult, 32-bit: (C*2^16 + D)\n\t\t *    3rd add, 32-bit: E\n\t\t *    4th add, 32-bit: F\n\t\t *\n\t\t *      (AC*2^16 + B) * (C*2^16 + D) + E + F\n\t\t *    = AC*2^32 + AD*2^16 + BC*2^16 + BD + E + F\n\t\t *    = AC*2^32 + (AD + BC)*2^16 + (BD + E + F)\n\t\t *    = AC*2^32 + AD*2^16 + BC*2^16 + (BD + E + F)\n\t\t */\n\t\tduk_uint32_t a, b, c, d, e, f;\n\t\tduk_uint32_t r, s, t;\n\n\t\ta = y->v[i]; b = a & 0xffffUL; a = a >> 16;\n\n\t\tf = 0;\n\t\tfor (j = 0; j < nz; j++) {\n\t\t\tc = z->v[j]; d = c & 0xffffUL; c = c >> 16;\n\t\t\te = x->v[i+j];\n\n\t\t\t/* build result as: (r << 32) + s: start with (BD + E + F) */\n\t\t\tr = 0;\n\t\t\ts = b * d;\n\n\t\t\t/* add E */\n\t\t\tt = s + e;\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add F */\n\t\t\tt = s + f;\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add BC*2^16 */\n\t\t\tt = b * c;\n\t\t\tr += (t >> 16);\n\t\t\tt = s + ((t & 0xffffUL) << 16);\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add AD*2^16 */\n\t\t\tt = a * d;\n\t\t\tr += (t >> 16);\n\t\t\tt = s + ((t & 0xffffUL) << 16);\n\t\t\tif (t < s) { r++; }  /* carry */\n\t\t\ts = t;\n\n\t\t\t/* add AC*2^32 */\n\t\t\tt = a * c;\n\t\t\tr += t;\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"ab=%08lx cd=%08lx ef=%08lx -> rs=%08lx %08lx\",\n\t\t\t                     (unsigned long) y->v[i], (unsigned long) z->v[j],\n\t\t\t                     (unsigned long) x->v[i+j], (unsigned long) r,\n\t\t\t                     (unsigned long) s));\n\n\t\t\tx->v[i+j] = s;\n\t\t\tf = r;\n\t\t}\n\t\tif (f > 0U) {\n\t\t\tDUK_ASSERT(i + j < nx);\n\t\t\tDUK_ASSERT(i + j < DUK__BI_MAX_PARTS);\n\t\t\tDUK_ASSERT(x->v[i+j] == 0U);\n\t\t\tx->v[i+j] = (duk_uint32_t) f;\n\t\t}\n#endif  /* DUK_USE_64BIT_OPS */\n\t}\n\n\tduk__bi_normalize(x);\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* x <- y * z */\nDUK_LOCAL void duk__bi_mul_small(duk__bigint *x, duk__bigint *y, duk_uint32_t z) {\n\tduk__bigint tmp;\n\n\tDUK_ASSERT(duk__bi_is_valid(y));\n\n\t/* XXX: this could be optimized */\n\tduk__bi_set_small(&tmp, z);\n\tduk__bi_mul(x, y, &tmp);\n\n\tDUK_ASSERT(duk__bi_is_valid(x));\n}\n\n/* x <- x * y, use t as temp */\nDUK_LOCAL void duk__bi_mul_copy(duk__bigint *x, duk__bigint *y, duk__bigint *t) {\n\tduk__bi_mul(t, x, y);\n\tduk__bi_copy(x, t);\n}\n\n/* x <- x * y, use t as temp */\nDUK_LOCAL void duk__bi_mul_small_copy(duk__bigint *x, duk_uint32_t y, duk__bigint *t) {\n\tduk__bi_mul_small(t, x, y);\n\tduk__bi_copy(x, t);\n}\n\nDUK_LOCAL int duk__bi_is_even(duk__bigint *x) {\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\treturn (x->n == 0) || ((x->v[0] & 0x01) == 0);\n}\n\nDUK_LOCAL int duk__bi_is_zero(duk__bigint *x) {\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\treturn (x->n == 0);  /* this is the case for normalized numbers */\n}\n\n/* Bigint is 2^52.  Used to detect normalized IEEE double mantissa values\n * which are at the lowest edge (next floating point value downwards has\n * a different exponent).  The lowest mantissa has the form:\n *\n *     1000........000    (52 zeroes; only \"hidden bit\" is set)\n */\nDUK_LOCAL duk_small_int_t duk__bi_is_2to52(duk__bigint *x) {\n\tDUK_ASSERT(duk__bi_is_valid(x));\n\treturn (duk_small_int_t)\n\t        (x->n == 2) && (x->v[0] == 0U) && (x->v[1] == (1U << (52-32)));\n}\n\n/* x <- (1<<y) */\nDUK_LOCAL void duk__bi_twoexp(duk__bigint *x, duk_small_int_t y) {\n\tduk_small_int_t n, r;\n\n\tn = (y / 32) + 1;\n\tDUK_ASSERT(n > 0);\n\tr = y % 32;\n\tduk_memzero((void *) x->v, sizeof(duk_uint32_t) * (size_t) n);\n\tx->n = n;\n\tx->v[n - 1] = (((duk_uint32_t) 1) << r);\n}\n\n/* x <- b^y; use t1 and t2 as temps */\nDUK_LOCAL void duk__bi_exp_small(duk__bigint *x, duk_small_int_t b, duk_small_int_t y, duk__bigint *t1, duk__bigint *t2) {\n\t/* Fast path the binary case */\n\n\tDUK_ASSERT(x != t1 && x != t2 && t1 != t2);  /* distinct bignums, easy mistake to make */\n\tDUK_ASSERT(b >= 0);\n\tDUK_ASSERT(y >= 0);\n\n\tif (b == 2) {\n\t\tduk__bi_twoexp(x, y);\n\t\treturn;\n\t}\n\n\t/* http://en.wikipedia.org/wiki/Exponentiation_by_squaring */\n\n\tDUK_DDD(DUK_DDDPRINT(\"exp_small: b=%ld, y=%ld\", (long) b, (long) y));\n\n\tduk__bi_set_small(x, 1);\n\tduk__bi_set_small(t1, (duk_uint32_t) b);\n\tfor (;;) {\n\t\t/* Loop structure ensures that we don't compute t1^2 unnecessarily\n\t\t * on the final round, as that might create a bignum exceeding the\n\t\t * current DUK__BI_MAX_PARTS limit.\n\t\t */\n\t\tif (y & 0x01) {\n\t\t\tduk__bi_mul_copy(x, t1, t2);\n\t\t}\n\t\ty = y >> 1;\n\t\tif (y == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tduk__bi_mul_copy(t1, t1, t2);\n\t}\n\n\tDUK__BI_PRINT(\"exp_small result\", x);\n}\n\n/*\n *  A Dragon4 number-to-string variant, based on:\n *\n *    Guy L. Steele Jr., Jon L. White: \"How to Print Floating-Point Numbers\n *    Accurately\"\n *\n *    Robert G. Burger, R. Kent Dybvig: \"Printing Floating-Point Numbers\n *    Quickly and Accurately\"\n *\n *  The current algorithm is based on Figure 1 of the Burger-Dybvig paper,\n *  i.e. the base implementation without logarithm estimation speedups\n *  (these would increase code footprint considerably).  Fixed-format output\n *  does not follow the suggestions in the paper; instead, we generate an\n *  extra digit and round-with-carry.\n *\n *  The same algorithm is used for number parsing (with b=10 and B=2)\n *  by generating one extra digit and doing rounding manually.\n *\n *  See doc/number-conversion.rst for limitations.\n */\n\n/* Maximum number of digits generated. */\n#define DUK__MAX_OUTPUT_DIGITS          1040  /* (Number.MAX_VALUE).toString(2).length == 1024, + slack */\n\n/* Maximum number of characters in formatted value. */\n#define DUK__MAX_FORMATTED_LENGTH       1040  /* (-Number.MAX_VALUE).toString(2).length == 1025, + slack */\n\n/* Number and (minimum) size of bigints in the nc_ctx structure. */\n#define DUK__NUMCONV_CTX_NUM_BIGINTS    7\n#define DUK__NUMCONV_CTX_BIGINTS_SIZE   (sizeof(duk__bigint) * DUK__NUMCONV_CTX_NUM_BIGINTS)\n\ntypedef struct {\n\t/* Currently about 7*152 = 1064 bytes.  The space for these\n\t * duk__bigints is used also as a temporary buffer for generating\n\t * the final string.  This is a bit awkard; a union would be\n\t * more correct.\n\t */\n\tduk__bigint f, r, s, mp, mm, t1, t2;\n\n\tduk_small_int_t is_s2n;        /* if 1, doing a string-to-number; else doing a number-to-string */\n\tduk_small_int_t is_fixed;      /* if 1, doing a fixed format output (not free format) */\n\tduk_small_int_t req_digits;    /* requested number of output digits; 0 = free-format */\n\tduk_small_int_t abs_pos;       /* digit position is absolute, not relative */\n\tduk_small_int_t e;             /* exponent for 'f' */\n\tduk_small_int_t b;             /* input radix */\n\tduk_small_int_t B;             /* output radix */\n\tduk_small_int_t k;             /* see algorithm */\n\tduk_small_int_t low_ok;        /* see algorithm */\n\tduk_small_int_t high_ok;       /* see algorithm */\n\tduk_small_int_t unequal_gaps;  /* m+ != m- (very rarely) */\n\n\t/* Buffer used for generated digits, values are in the range [0,B-1]. */\n\tduk_uint8_t digits[DUK__MAX_OUTPUT_DIGITS];\n\tduk_small_int_t count;  /* digit count */\n} duk__numconv_stringify_ctx;\n\n/* Note: computes with 'idx' in assertions, so caller beware.\n * 'idx' is preincremented, i.e. '1' on first call, because it\n * is more convenient for the caller.\n */\n#define DUK__DRAGON4_OUTPUT_PREINC(nc_ctx,preinc_idx,x)  do { \\\n\t\tDUK_ASSERT((preinc_idx) - 1 >= 0); \\\n\t\tDUK_ASSERT((preinc_idx) - 1 < DUK__MAX_OUTPUT_DIGITS); \\\n\t\t((nc_ctx)->digits[(preinc_idx) - 1]) = (duk_uint8_t) (x); \\\n\t} while (0)\n\nDUK_LOCAL duk_size_t duk__dragon4_format_uint32(duk_uint8_t *buf, duk_uint32_t x, duk_small_int_t radix) {\n\tduk_uint8_t *p;\n\tduk_size_t len;\n\tduk_small_int_t dig;\n\tduk_uint32_t t;\n\n\tDUK_ASSERT(buf != NULL);\n\tDUK_ASSERT(radix >= 2 && radix <= 36);\n\n\t/* A 32-bit unsigned integer formats to at most 32 digits (the\n\t * worst case happens with radix == 2).  Output the digits backwards,\n\t * and use a memmove() to get them in the right place.\n\t */\n\n\tp = buf + 32;\n\tfor (;;) {\n\t\tt = x / (duk_uint32_t) radix;\n\t\tdig = (duk_small_int_t) (x - t * (duk_uint32_t) radix);\n\t\tx = t;\n\n\t\tDUK_ASSERT(dig >= 0 && dig < 36);\n\t\t*(--p) = DUK__DIGITCHAR(dig);\n\n\t\tif (x == 0) {\n\t\t\tbreak;\n\t\t}\n\t}\n\tlen = (duk_size_t) ((buf + 32) - p);\n\n\tduk_memmove((void *) buf, (const void *) p, (size_t) len);\n\n\treturn len;\n}\n\nDUK_LOCAL void duk__dragon4_prepare(duk__numconv_stringify_ctx *nc_ctx) {\n\tduk_small_int_t lowest_mantissa;\n\n#if 1\n\t/* Assume IEEE round-to-even, so that shorter encoding can be used\n\t * when round-to-even would produce correct result.  By removing\n\t * this check (and having low_ok == high_ok == 0) the results would\n\t * still be accurate but in some cases longer than necessary.\n\t */\n\tif (duk__bi_is_even(&nc_ctx->f)) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"f is even\"));\n\t\tnc_ctx->low_ok = 1;\n\t\tnc_ctx->high_ok = 1;\n\t} else {\n\t\tDUK_DDD(DUK_DDDPRINT(\"f is odd\"));\n\t\tnc_ctx->low_ok = 0;\n\t\tnc_ctx->high_ok = 0;\n\t}\n#else\n\t/* Note: not honoring round-to-even should work but now generates incorrect\n\t * results.  For instance, 1e23 serializes to \"a000...\", i.e. the first digit\n\t * equals the radix (10).  Scaling stops one step too early in this case.\n\t * Don't know why this is the case, but since this code path is unused, it\n\t * doesn't matter.\n\t */\n\tnc_ctx->low_ok = 0;\n\tnc_ctx->high_ok = 0;\n#endif\n\n\t/* For string-to-number, pretend we never have the lowest mantissa as there\n\t * is no natural \"precision\" for inputs.  Having lowest_mantissa == 0, we'll\n\t * fall into the base cases for both e >= 0 and e < 0.\n\t */\n\tif (nc_ctx->is_s2n) {\n\t\tlowest_mantissa = 0;\n\t} else {\n\t\tlowest_mantissa = duk__bi_is_2to52(&nc_ctx->f);\n\t}\n\n\tnc_ctx->unequal_gaps = 0;\n\tif (nc_ctx->e >= 0) {\n\t\t/* exponent non-negative (and thus not minimum exponent) */\n\n\t\tif (lowest_mantissa) {\n\t\t\t/* (>= e 0) AND (= f (expt b (- p 1)))\n\t\t\t *\n\t\t\t * be <- (expt b e) == b^e\n\t\t\t * be1 <- (* be b) == (expt b (+ e 1)) == b^(e+1)\n\t\t\t * r <- (* f be1 2) == 2 * f * b^(e+1)    [if b==2 -> f * b^(e+2)]\n\t\t\t * s <- (* b 2)                           [if b==2 -> 4]\n\t\t\t * m+ <- be1 == b^(e+1)\n\t\t\t * m- <- be == b^e\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-negative exponent (not smallest exponent); \"\n\t\t\t                     \"lowest mantissa value for this exponent -> \"\n\t\t\t                     \"unequal gaps\"));\n\n\t\t\tduk__bi_exp_small(&nc_ctx->mm, nc_ctx->b, nc_ctx->e, &nc_ctx->t1, &nc_ctx->t2);  /* mm <- b^e */\n\t\t\tduk__bi_mul_small(&nc_ctx->mp, &nc_ctx->mm, (duk_uint32_t) nc_ctx->b);           /* mp <- b^(e+1) */\n\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, 2);\n\t\t\tduk__bi_mul(&nc_ctx->r, &nc_ctx->t1, &nc_ctx->mp);              /* r <- (2 * f) * b^(e+1) */\n\t\t\tduk__bi_set_small(&nc_ctx->s, (duk_uint32_t) (nc_ctx->b * 2));  /* s <- 2 * b */\n\t\t\tnc_ctx->unequal_gaps = 1;\n\t\t} else {\n\t\t\t/* (>= e 0) AND (not (= f (expt b (- p 1))))\n\t\t\t *\n\t\t\t * be <- (expt b e) == b^e\n\t\t\t * r <- (* f be 2) == 2 * f * b^e    [if b==2 -> f * b^(e+1)]\n\t\t\t * s <- 2\n\t\t\t * m+ <- be == b^e\n\t\t\t * m- <- be == b^e\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"non-negative exponent (not smallest exponent); \"\n\t\t\t                     \"not lowest mantissa for this exponent -> \"\n\t\t\t                     \"equal gaps\"));\n\n\t\t\tduk__bi_exp_small(&nc_ctx->mm, nc_ctx->b, nc_ctx->e, &nc_ctx->t1, &nc_ctx->t2);  /* mm <- b^e */\n\t\t\tduk__bi_copy(&nc_ctx->mp, &nc_ctx->mm);                /* mp <- b^e */\n\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, 2);\n\t\t\tduk__bi_mul(&nc_ctx->r, &nc_ctx->t1, &nc_ctx->mp);     /* r <- (2 * f) * b^e */\n\t\t\tduk__bi_set_small(&nc_ctx->s, 2);                      /* s <- 2 */\n\t\t}\n\t} else {\n\t\t/* When doing string-to-number, lowest_mantissa is always 0 so\n\t\t * the exponent check, while incorrect, won't matter.\n\t\t */\n\t\tif (nc_ctx->e > DUK__IEEE_DOUBLE_EXP_MIN /*not minimum exponent*/ &&\n\t\t    lowest_mantissa /* lowest mantissa for this exponent*/) {\n\t\t\t/* r <- (* f b 2)                                [if b==2 -> (* f 4)]\n\t\t\t * s <- (* (expt b (- 1 e)) 2) == b^(1-e) * 2    [if b==2 -> b^(2-e)]\n\t\t\t * m+ <- b == 2\n\t\t\t * m- <- 1\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"negative exponent; not minimum exponent and \"\n\t\t\t                     \"lowest mantissa for this exponent -> \"\n\t\t\t                     \"unequal gaps\"));\n\n\t\t\tduk__bi_mul_small(&nc_ctx->r, &nc_ctx->f, (duk_uint32_t) (nc_ctx->b * 2));  /* r <- (2 * b) * f */\n\t\t\tduk__bi_exp_small(&nc_ctx->t1, nc_ctx->b, 1 - nc_ctx->e, &nc_ctx->s, &nc_ctx->t2);  /* NB: use 's' as temp on purpose */\n\t\t\tduk__bi_mul_small(&nc_ctx->s, &nc_ctx->t1, 2);             /* s <- b^(1-e) * 2 */\n\t\t\tduk__bi_set_small(&nc_ctx->mp, 2);\n\t\t\tduk__bi_set_small(&nc_ctx->mm, 1);\n\t\t\tnc_ctx->unequal_gaps = 1;\n\t\t} else {\n\t\t\t/* r <- (* f 2)\n\t\t\t * s <- (* (expt b (- e)) 2) == b^(-e) * 2    [if b==2 -> b^(1-e)]\n\t\t\t * m+ <- 1\n\t\t\t * m- <- 1\n\t\t\t * k <- 0\n\t\t\t * B <- B\n\t\t\t * low_ok <- round\n\t\t\t * high_ok <- round\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"negative exponent; minimum exponent or not \"\n\t\t\t                     \"lowest mantissa for this exponent -> \"\n\t\t\t                     \"equal gaps\"));\n\n\t\t\tduk__bi_mul_small(&nc_ctx->r, &nc_ctx->f, 2);            /* r <- 2 * f */\n\t\t\tduk__bi_exp_small(&nc_ctx->t1, nc_ctx->b, -nc_ctx->e, &nc_ctx->s, &nc_ctx->t2);  /* NB: use 's' as temp on purpose */\n\t\t\tduk__bi_mul_small(&nc_ctx->s, &nc_ctx->t1, 2);           /* s <- b^(-e) * 2 */\n\t\t\tduk__bi_set_small(&nc_ctx->mp, 1);\n\t\t\tduk__bi_set_small(&nc_ctx->mm, 1);\n\t\t}\n\t}\n}\n\nDUK_LOCAL void duk__dragon4_scale(duk__numconv_stringify_ctx *nc_ctx) {\n\tduk_small_int_t k = 0;\n\n\t/* This is essentially the 'scale' algorithm, with recursion removed.\n\t * Note that 'k' is either correct immediately, or will move in one\n\t * direction in the loop.  There's no need to do the low/high checks\n\t * on every round (like the Scheme algorithm does).\n\t *\n\t * The scheme algorithm finds 'k' and updates 's' simultaneously,\n\t * while the logical algorithm finds 'k' with 's' having its initial\n\t * value, after which 's' is updated separately (see the Burger-Dybvig\n\t * paper, Section 3.1, steps 2 and 3).\n\t *\n\t * The case where m+ == m- (almost always) is optimized for, because\n\t * it reduces the bigint operations considerably and almost always\n\t * applies.  The scale loop only needs to work with m+, so this works.\n\t */\n\n\t/* XXX: this algorithm could be optimized quite a lot by using e.g.\n\t * a logarithm based estimator for 'k' and performing B^n multiplication\n\t * using a lookup table or using some bit-representation based exp\n\t * algorithm.  Currently we just loop, with significant performance\n\t * impact for very large and very small numbers.\n\t */\n\n\tDUK_DDD(DUK_DDDPRINT(\"scale: B=%ld, low_ok=%ld, high_ok=%ld\",\n\t                     (long) nc_ctx->B, (long) nc_ctx->low_ok, (long) nc_ctx->high_ok));\n\tDUK__BI_PRINT(\"r(init)\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s(init)\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp(init)\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm(init)\", &nc_ctx->mm);\n\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"scale loop (inc k), k=%ld\", (long) k));\n\t\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\t\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\t\tDUK__BI_PRINT(\"m+\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"m-\", &nc_ctx->mm);\n\n\t\tduk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp);  /* t1 = (+ r m+) */\n\t\tif (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) >= (nc_ctx->high_ok ? 0 : 1)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"k is too low\"));\n\t\t\t/* r <- r\n\t\t\t * s <- (* s B)\n\t\t\t * m+ <- m+\n\t\t\t * m- <- m-\n\t\t\t * k <- (+ k 1)\n\t\t\t */\n\n\t\t\tduk__bi_mul_small_copy(&nc_ctx->s, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\tk++;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t/* k > 0 -> k was too low, and cannot be too high */\n\tif (k > 0) {\n\t\tgoto skip_dec_k;\n\t}\n\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"scale loop (dec k), k=%ld\", (long) k));\n\t\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\t\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\t\tDUK__BI_PRINT(\"m+\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"m-\", &nc_ctx->mm);\n\n\t\tduk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp);  /* t1 = (+ r m+) */\n\t\tduk__bi_mul_small(&nc_ctx->t2, &nc_ctx->t1, (duk_uint32_t) nc_ctx->B);   /* t2 = (* (+ r m+) B) */\n\t\tif (duk__bi_compare(&nc_ctx->t2, &nc_ctx->s) <= (nc_ctx->high_ok ? -1 : 0)) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"k is too high\"));\n\t\t\t/* r <- (* r B)\n\t\t\t * s <- s\n\t\t\t * m+ <- (* m+ B)\n\t\t\t * m- <- (* m- B)\n\t\t\t * k <- (- k 1)\n\t\t\t */\n\t\t\tduk__bi_mul_small_copy(&nc_ctx->r, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\tduk__bi_mul_small_copy(&nc_ctx->mp, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\tif (nc_ctx->unequal_gaps) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"m+ != m- -> need to update m- too\"));\n\t\t\t\tduk__bi_mul_small_copy(&nc_ctx->mm, (duk_uint32_t) nc_ctx->B, &nc_ctx->t1);\n\t\t\t}\n\t\t\tk--;\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\n skip_dec_k:\n\n\tif (!nc_ctx->unequal_gaps) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"equal gaps, copy m- from m+\"));\n\t\tduk__bi_copy(&nc_ctx->mm, &nc_ctx->mp);  /* mm <- mp */\n\t}\n\tnc_ctx->k = k;\n\n\tDUK_DDD(DUK_DDDPRINT(\"final k: %ld\", (long) k));\n\tDUK__BI_PRINT(\"r(final)\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s(final)\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp(final)\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm(final)\", &nc_ctx->mm);\n}\n\nDUK_LOCAL void duk__dragon4_generate(duk__numconv_stringify_ctx *nc_ctx) {\n\tduk_small_int_t tc1, tc2;    /* terminating conditions */\n\tduk_small_int_t d;           /* current digit */\n\tduk_small_int_t count = 0;   /* digit count */\n\n\t/*\n\t *  Digit generation loop.\n\t *\n\t *  Different termination conditions:\n\t *\n\t *    1. Free format output.  Terminate when shortest accurate\n\t *       representation found.\n\t *\n\t *    2. Fixed format output, with specific number of digits.\n\t *       Ignore termination conditions, terminate when digits\n\t *       generated.  Caller requests an extra digit and rounds.\n\t *\n\t *    3. Fixed format output, with a specific absolute cut-off\n\t *       position (e.g. 10 digits after decimal point).  Note\n\t *       that we always generate at least one digit, even if\n\t *       the digit is below the cut-off point already.\n\t */\n\n\tfor (;;) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"generate loop, count=%ld, k=%ld, B=%ld, low_ok=%ld, high_ok=%ld\",\n\t\t                     (long) count, (long) nc_ctx->k, (long) nc_ctx->B,\n\t\t                     (long) nc_ctx->low_ok, (long) nc_ctx->high_ok));\n\t\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\t\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\t\tDUK__BI_PRINT(\"m+\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"m-\", &nc_ctx->mm);\n\n\t\t/* (quotient-remainder (* r B) s) using a dummy subtraction loop */\n\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->r, (duk_uint32_t) nc_ctx->B);       /* t1 <- (* r B) */\n\t\td = 0;\n\t\tfor (;;) {\n\t\t\tif (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) < 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tduk__bi_sub_copy(&nc_ctx->t1, &nc_ctx->s, &nc_ctx->t2);  /* t1 <- t1 - s */\n\t\t\td++;\n\t\t}\n\t\tduk__bi_copy(&nc_ctx->r, &nc_ctx->t1);  /* r <- (remainder (* r B) s) */\n\t\t                                        /* d <- (quotient (* r B) s)   (in range 0...B-1) */\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> d(quot)=%ld\", (long) d));\n\t\tDUK__BI_PRINT(\"r(rem)\", &nc_ctx->r);\n\n\t\tduk__bi_mul_small_copy(&nc_ctx->mp, (duk_uint32_t) nc_ctx->B, &nc_ctx->t2); /* m+ <- (* m+ B) */\n\t\tduk__bi_mul_small_copy(&nc_ctx->mm, (duk_uint32_t) nc_ctx->B, &nc_ctx->t2); /* m- <- (* m- B) */\n\t\tDUK__BI_PRINT(\"mp(upd)\", &nc_ctx->mp);\n\t\tDUK__BI_PRINT(\"mm(upd)\", &nc_ctx->mm);\n\n\t\t/* Terminating conditions.  For fixed width output, we just ignore the\n\t\t * terminating conditions (and pretend that tc1 == tc2 == false).  The\n\t\t * the current shortcut for fixed-format output is to generate a few\n\t\t * extra digits and use rounding (with carry) to finish the output.\n\t\t */\n\n\t\tif (nc_ctx->is_fixed == 0) {\n\t\t\t/* free-form */\n\t\t\ttc1 = (duk__bi_compare(&nc_ctx->r, &nc_ctx->mm) <= (nc_ctx->low_ok ? 0 : -1));\n\n\t\t\tduk__bi_add(&nc_ctx->t1, &nc_ctx->r, &nc_ctx->mp);  /* t1 <- (+ r m+) */\n\t\t\ttc2 = (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) >= (nc_ctx->high_ok ? 0 : 1));\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=%ld, tc2=%ld\", (long) tc1, (long) tc2));\n\t\t} else {\n\t\t\t/* fixed-format */\n\t\t\ttc1 = 0;\n\t\t\ttc2 = 0;\n\t\t}\n\n\t\t/* Count is incremented before DUK__DRAGON4_OUTPUT_PREINC() call\n\t\t * on purpose, which is taken into account by the macro.\n\t\t */\n\t\tcount++;\n\n\t\tif (tc1) {\n\t\t\tif (tc2) {\n\t\t\t\t/* tc1 = true, tc2 = true */\n\t\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->r, 2);\n\t\t\t\tif (duk__bi_compare(&nc_ctx->t1, &nc_ctx->s) < 0) {  /* (< (* r 2) s) */\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=true, tc2=true, 2r > s: output d --> %ld (k=%ld)\",\n\t\t\t\t\t                     (long) d, (long) nc_ctx->k));\n\t\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=true, tc2=true, 2r <= s: output d+1 --> %ld (k=%ld)\",\n\t\t\t\t\t                     (long) (d + 1), (long) nc_ctx->k));\n\t\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d + 1);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t/* tc1 = true, tc2 = false */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=true, tc2=false: output d --> %ld (k=%ld)\",\n\t\t\t\t                     (long) d, (long) nc_ctx->k));\n\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (tc2) {\n\t\t\t\t/* tc1 = false, tc2 = true */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=false, tc2=true: output d+1 --> %ld (k=%ld)\",\n\t\t\t\t                     (long) (d + 1), (long) nc_ctx->k));\n\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d + 1);\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\t/* tc1 = false, tc2 = false */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"tc1=false, tc2=false: output d --> %ld (k=%ld)\",\n\t\t\t\t                     (long) d, (long) nc_ctx->k));\n\t\t\t\tDUK__DRAGON4_OUTPUT_PREINC(nc_ctx, count, d);\n\n\t\t\t\t/* r <- r    (updated above: r <- (remainder (* r B) s)\n\t\t\t\t * s <- s\n\t\t\t\t * m+ <- m+  (updated above: m+ <- (* m+ B)\n\t\t\t\t * m- <- m-  (updated above: m- <- (* m- B)\n\t\t\t\t * B, low_ok, high_ok are fixed\n\t\t\t\t */\n\n\t\t\t\t/* fall through and continue for-loop */\n\t\t\t}\n\t\t}\n\n\t\t/* fixed-format termination conditions */\n\t\tif (nc_ctx->is_fixed) {\n\t\t\tif (nc_ctx->abs_pos) {\n\t\t\t\tint pos = nc_ctx->k - count + 1;  /* count is already incremented, take into account */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fixed format, absolute: abs pos=%ld, k=%ld, count=%ld, req=%ld\",\n\t\t\t\t                     (long) pos, (long) nc_ctx->k, (long) count, (long) nc_ctx->req_digits));\n\t\t\t\tif (pos <= nc_ctx->req_digits) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"digit position reached req_digits, end generate loop\"));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"fixed format, relative: k=%ld, count=%ld, req=%ld\",\n\t\t\t\t                     (long) nc_ctx->k, (long) count, (long) nc_ctx->req_digits));\n\t\t\t\tif (count >= nc_ctx->req_digits) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"digit count reached req_digits, end generate loop\"));\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}  /* for */\n\n\tnc_ctx->count = count;\n\n\tDUK_DDD(DUK_DDDPRINT(\"generate finished\"));\n\n#if defined(DUK_USE_DEBUG_LEVEL) && (DUK_USE_DEBUG_LEVEL >= 2)\n\t{\n\t\tduk_uint8_t buf[2048];\n\t\tduk_small_int_t i, t;\n\t\tduk_memzero(buf, sizeof(buf));\n\t\tfor (i = 0; i < nc_ctx->count; i++) {\n\t\t\tt = nc_ctx->digits[i];\n\t\t\tif (t < 0 || t > 36) {\n\t\t\t\tbuf[i] = (duk_uint8_t) '?';\n\t\t\t} else {\n\t\t\t\tbuf[i] = (duk_uint8_t) DUK__DIGITCHAR(t);\n\t\t\t}\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"-> generated digits; k=%ld, digits='%s'\",\n\t\t                     (long) nc_ctx->k, (const char *) buf));\n\t}\n#endif\n}\n\n/* Round up digits to a given position.  If position is out-of-bounds,\n * does nothing.  If carry propagates over the first digit, a '1' is\n * prepended to digits and 'k' will be updated.  Return value indicates\n * whether carry propagated over the first digit.\n *\n * Note that nc_ctx->count is NOT updated based on the rounding position\n * (it is updated only if carry overflows over the first digit and an\n * extra digit is prepended).\n */\nDUK_LOCAL duk_small_int_t duk__dragon4_fixed_format_round(duk__numconv_stringify_ctx *nc_ctx, duk_small_int_t round_idx) {\n\tduk_small_int_t t;\n\tduk_uint8_t *p;\n\tduk_uint8_t roundup_limit;\n\tduk_small_int_t ret = 0;\n\n\t/*\n\t *  round_idx points to the digit which is considered for rounding; the\n\t *  digit to its left is the final digit of the rounded value.  If round_idx\n\t *  is zero, rounding will be performed; the result will either be an empty\n\t *  rounded value or if carry happens a '1' digit is generated.\n\t */\n\n\tif (round_idx >= nc_ctx->count) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"round_idx out of bounds (%ld >= %ld (count)) -> no rounding\",\n\t\t                     (long) round_idx, (long) nc_ctx->count));\n\t\treturn 0;\n\t} else if (round_idx < 0) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"round_idx out of bounds (%ld < 0) -> no rounding\",\n\t\t                     (long) round_idx));\n\t\treturn 0;\n\t}\n\n\t/*\n\t *  Round-up limit.\n\t *\n\t *  For even values, divides evenly, e.g. 10 -> roundup_limit=5.\n\t *\n\t *  For odd values, rounds up, e.g. 3 -> roundup_limit=2.\n\t *  If radix is 3, 0/3 -> down, 1/3 -> down, 2/3 -> up.\n\t */\n\troundup_limit = (duk_uint8_t) ((nc_ctx->B + 1) / 2);\n\n\tp = &nc_ctx->digits[round_idx];\n\tif (*p >= roundup_limit) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"fixed-format rounding carry required\"));\n\t\t/* carry */\n\t\tfor (;;) {\n\t\t\t*p = 0;\n\t\t\tif (p == &nc_ctx->digits[0]) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"carry propagated to first digit -> special case handling\"));\n\t\t\t\tduk_memmove((void *) (&nc_ctx->digits[1]),\n\t\t\t\t            (const void *) (&nc_ctx->digits[0]),\n\t\t\t\t            (size_t) (sizeof(char) * (size_t) nc_ctx->count));\n\t\t\t\tnc_ctx->digits[0] = 1;  /* don't increase 'count' */\n\t\t\t\tnc_ctx->k++;  /* position of highest digit changed */\n\t\t\t\tnc_ctx->count++;  /* number of digits changed */\n\t\t\t\tret = 1;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fixed-format rounding carry: B=%ld, roundup_limit=%ld, p=%p, digits=%p\",\n\t\t\t                     (long) nc_ctx->B, (long) roundup_limit, (void *) p, (void *) nc_ctx->digits));\n\t\t\tp--;\n\t\t\tt = *p;\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"digit before carry: %ld\", (long) t));\n\t\t\tif (++t < nc_ctx->B) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"rounding carry terminated\"));\n\t\t\t\t*p = (duk_uint8_t) t;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"wraps, carry to next digit\"));\n\t\t}\n\t}\n\n\treturn ret;\n}\n\n#define DUK__NO_EXP  (65536)  /* arbitrary marker, outside valid exp range */\n\nDUK_LOCAL void duk__dragon4_convert_and_push(duk__numconv_stringify_ctx *nc_ctx,\n                                             duk_hthread *thr,\n                                             duk_small_int_t radix,\n                                             duk_small_int_t digits,\n                                             duk_small_uint_t flags,\n                                             duk_small_int_t neg) {\n\tduk_small_int_t k;\n\tduk_small_int_t pos, pos_end;\n\tduk_small_int_t expt;\n\tduk_small_int_t dig;\n\tduk_uint8_t *q;\n\tduk_uint8_t *buf;\n\n\t/*\n\t *  The string conversion here incorporates all the necessary ECMAScript\n\t *  semantics without attempting to be generic.  nc_ctx->digits contains\n\t *  nc_ctx->count digits (>= 1), with the topmost digit's 'position'\n\t *  indicated by nc_ctx->k as follows:\n\t *\n\t *    digits=\"123\" count=3 k=0   -->   0.123\n\t *    digits=\"123\" count=3 k=1   -->   1.23\n\t *    digits=\"123\" count=3 k=5   -->   12300\n\t *    digits=\"123\" count=3 k=-1  -->   0.0123\n\t *\n\t *  Note that the identifier names used for format selection are different\n\t *  in Burger-Dybvig paper and ECMAScript specification (quite confusingly\n\t *  so, because e.g. 'k' has a totally different meaning in each).  See\n\t *  documentation for discussion.\n\t *\n\t *  ECMAScript doesn't specify any specific behavior for format selection\n\t *  (e.g. when to use exponent notation) for non-base-10 numbers.\n\t *\n\t *  The bigint space in the context is reused for string output, as there\n\t *  is more than enough space for that (>1kB at the moment), and we avoid\n\t *  allocating even more stack.\n\t */\n\n\tDUK_ASSERT(DUK__NUMCONV_CTX_BIGINTS_SIZE >= DUK__MAX_FORMATTED_LENGTH);\n\tDUK_ASSERT(nc_ctx->count >= 1);\n\n\tk = nc_ctx->k;\n\tbuf = (duk_uint8_t *) &nc_ctx->f;  /* XXX: union would be more correct */\n\tq = buf;\n\n\t/* Exponent handling: if exponent format is used, record exponent value and\n\t * fake k such that one leading digit is generated (e.g. digits=123 -> \"1.23\").\n\t *\n\t * toFixed() prevents exponent use; otherwise apply a set of criteria to\n\t * match the other API calls (toString(), toPrecision, etc).\n\t */\n\n\texpt = DUK__NO_EXP;\n\tif (!nc_ctx->abs_pos /* toFixed() */) {\n\t\tif ((flags & DUK_N2S_FLAG_FORCE_EXP) ||             /* exponential notation forced */\n\t\t    ((flags & DUK_N2S_FLAG_NO_ZERO_PAD) &&          /* fixed precision and zero padding would be required */\n\t             (k - digits >= 1)) ||                          /* (e.g. k=3, digits=2 -> \"12X\") */\n\t\t    ((k > 21 || k <= -6) && (radix == 10))) {       /* toString() conditions */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"use exponential notation: k=%ld -> expt=%ld\",\n\t\t\t                     (long) k, (long) (k - 1)));\n\t\t\texpt = k - 1;  /* e.g. 12.3 -> digits=\"123\" k=2 -> 1.23e1 */\n\t\t\tk = 1;  /* generate mantissa with a single leading whole number digit */\n\t\t}\n\t}\n\n\tif (neg) {\n\t\t*q++ = '-';\n\t}\n\n\t/* Start position (inclusive) and end position (exclusive) */\n\tpos = (k >= 1 ? k : 1);\n\tif (nc_ctx->is_fixed) {\n\t\tif (nc_ctx->abs_pos) {\n\t\t\t/* toFixed() */\n\t\t\tpos_end = -digits;\n\t\t} else {\n\t\t\tpos_end = k - digits;\n\t\t}\n\t} else {\n\t\tpos_end = k - nc_ctx->count;\n\t}\n\tif (pos_end > 0) {\n\t\tpos_end = 0;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"expt=%ld, k=%ld, count=%ld, pos=%ld, pos_end=%ld, is_fixed=%ld, \"\n\t                     \"digits=%ld, abs_pos=%ld\",\n\t                     (long) expt, (long) k, (long) nc_ctx->count, (long) pos, (long) pos_end,\n\t                     (long) nc_ctx->is_fixed, (long) digits, (long) nc_ctx->abs_pos));\n\n\t/* Digit generation */\n\twhile (pos > pos_end) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"digit generation: pos=%ld, pos_end=%ld\",\n\t\t                     (long) pos, (long) pos_end));\n\t\tif (pos == 0) {\n\t\t\t*q++ = (duk_uint8_t) '.';\n\t\t}\n\t\tif (pos > k) {\n\t\t\t*q++ = (duk_uint8_t) '0';\n\t\t} else if (pos <= k - nc_ctx->count) {\n\t\t\t*q++ = (duk_uint8_t) '0';\n\t\t} else {\n\t\t\tdig = nc_ctx->digits[k - pos];\n\t\t\tDUK_ASSERT(dig >= 0 && dig < nc_ctx->B);\n\t\t\t*q++ = (duk_uint8_t) DUK__DIGITCHAR(dig);\n\t\t}\n\n\t\tpos--;\n\t}\n\tDUK_ASSERT(pos <= 1);\n\n\t/* Exponent */\n\tif (expt != DUK__NO_EXP) {\n\t\t/*\n\t\t *  Exponent notation for non-base-10 numbers isn't specified in ECMAScript\n\t\t *  specification, as it never explicitly turns up: non-decimal numbers can\n\t\t *  only be formatted with Number.prototype.toString([radix]) and for that,\n\t\t *  behavior is not explicitly specified.\n\t\t *\n\t\t *  Logical choices include formatting the exponent as decimal (e.g. binary\n\t\t *  100000 as 1e+5) or in current radix (e.g. binary 100000 as 1e+101).\n\t\t *  The Dragon4 algorithm (in the original paper) prints the exponent value\n\t\t *  in the target radix B.  However, for radix values 15 and above, the\n\t\t *  exponent separator 'e' is no longer easily parseable.  Consider, for\n\t\t *  instance, the number \"1.faecee+1c\".\n\t\t */\n\n\t\tduk_size_t len;\n\t\tchar expt_sign;\n\n\t\t*q++ = 'e';\n\t\tif (expt >= 0) {\n\t\t\texpt_sign = '+';\n\t\t} else {\n\t\t\texpt_sign = '-';\n\t\t\texpt = -expt;\n\t\t}\n\t\t*q++ = (duk_uint8_t) expt_sign;\n\t\tlen = duk__dragon4_format_uint32(q, (duk_uint32_t) expt, radix);\n\t\tq += len;\n\t}\n\n\tduk_push_lstring(thr, (const char *) buf, (size_t) (q - buf));\n}\n\n/*\n *  Conversion helpers\n */\n\nDUK_LOCAL void duk__dragon4_double_to_ctx(duk__numconv_stringify_ctx *nc_ctx, duk_double_t x) {\n\tduk_double_union u;\n\tduk_uint32_t tmp;\n\tduk_small_int_t expt;\n\n\t/*\n\t *    seeeeeee eeeeffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff\n\t *       A        B        C        D        E        F        G        H\n\t *\n\t *    s       sign bit\n\t *    eee...  exponent field\n\t *    fff...  fraction\n\t *\n\t *    ieee value = 1.ffff... * 2^(e - 1023)  (normal)\n\t *               = 0.ffff... * 2^(-1022)     (denormal)\n\t *\n\t *    algorithm v = f * b^e\n\t */\n\n\tDUK_DBLUNION_SET_DOUBLE(&u, x);\n\n\tnc_ctx->f.n = 2;\n\n\ttmp = DUK_DBLUNION_GET_LOW32(&u);\n\tnc_ctx->f.v[0] = tmp;\n\ttmp = DUK_DBLUNION_GET_HIGH32(&u);\n\tnc_ctx->f.v[1] = tmp & 0x000fffffUL;\n\texpt = (duk_small_int_t) ((tmp >> 20) & 0x07ffUL);\n\n\tif (expt == 0) {\n\t\t/* denormal */\n\t\texpt = DUK__IEEE_DOUBLE_EXP_MIN - 52;\n\t\tduk__bi_normalize(&nc_ctx->f);\n\t} else {\n\t\t/* normal: implicit leading 1-bit */\n\t\tnc_ctx->f.v[1] |= 0x00100000UL;\n\t\texpt = expt - DUK__IEEE_DOUBLE_EXP_BIAS - 52;\n\t\tDUK_ASSERT(duk__bi_is_valid(&nc_ctx->f));  /* true, because v[1] has at least one bit set */\n\t}\n\n\tDUK_ASSERT(duk__bi_is_valid(&nc_ctx->f));\n\n\tnc_ctx->e = expt;\n}\n\nDUK_LOCAL void duk__dragon4_ctx_to_double(duk__numconv_stringify_ctx *nc_ctx, duk_double_t *x) {\n\tduk_double_union u;\n\tduk_small_int_t expt;\n\tduk_small_int_t i;\n\tduk_small_int_t bitstart;\n\tduk_small_int_t bitround;\n\tduk_small_int_t bitidx;\n\tduk_small_int_t skip_round;\n\tduk_uint32_t t, v;\n\n\tDUK_ASSERT(nc_ctx->count == 53 + 1);\n\n\t/* Sometimes this assert is not true right now; it will be true after\n\t * rounding.  See: test-bug-numconv-mantissa-assert.js.\n\t */\n\tDUK_ASSERT_DISABLE(nc_ctx->digits[0] == 1);  /* zero handled by caller */\n\n\t/* Should not be required because the code below always sets both high\n\t * and low parts, but at least gcc-4.4.5 fails to deduce this correctly\n\t * (perhaps because the low part is set (seemingly) conditionally in a\n\t * loop), so this is here to avoid the bogus warning.\n\t */\n\tduk_memzero((void *) &u, sizeof(u));\n\n\t/*\n\t *  Figure out how generated digits match up with the mantissa,\n\t *  and then perform rounding.  If mantissa overflows, need to\n\t *  recompute the exponent (it is bumped and may overflow to\n\t *  infinity).\n\t *\n\t *  For normal numbers the leading '1' is hidden and ignored,\n\t *  and the last bit is used for rounding:\n\t *\n\t *                          rounding pt\n\t *       <--------52------->|\n\t *     1 x x x x ... x x x x|y  ==>  x x x x ... x x x x\n\t *\n\t *  For denormals, the leading '1' is included in the number,\n\t *  and the rounding point is different:\n\t *\n\t *                      rounding pt\n\t *     <--52 or less--->|\n\t *     1 x x x x ... x x|x x y  ==>  0 0 ... 1 x x ... x x\n\t *\n\t *  The largest denormals will have a mantissa beginning with\n\t *  a '1' (the explicit leading bit); smaller denormals will\n\t *  have leading zero bits.\n\t *\n\t *  If the exponent would become too high, the result becomes\n\t *  Infinity.  If the exponent is so small that the entire\n\t *  mantissa becomes zero, the result becomes zero.\n\t *\n\t *  Note: the Dragon4 'k' is off-by-one with respect to the IEEE\n\t *  exponent.  For instance, k==0 indicates that the leading '1'\n\t *  digit is at the first binary fraction position (0.1xxx...);\n\t *  the corresponding IEEE exponent would be -1.\n\t */\n\n\tskip_round = 0;\n\n recheck_exp:\n\n\texpt = nc_ctx->k - 1;   /* IEEE exp without bias */\n\tif (expt > 1023) {\n\t\t/* Infinity */\n\t\tbitstart = -255;  /* needed for inf: causes mantissa to become zero,\n\t\t                   * and rounding to be skipped.\n\t\t                   */\n\t\texpt = 2047;\n\t} else if (expt >= -1022) {\n\t\t/* normal */\n\t\tbitstart = 1;  /* skip leading digit */\n\t\texpt += DUK__IEEE_DOUBLE_EXP_BIAS;\n\t\tDUK_ASSERT(expt >= 1 && expt <= 2046);\n\t} else {\n\t\t/* denormal or zero */\n\t\tbitstart = 1023 + expt;  /* expt==-1023 -> bitstart=0 (leading 1);\n\t\t                          * expt==-1024 -> bitstart=-1 (one left of leading 1), etc\n\t\t                          */\n\t\texpt = 0;\n\t}\n\tbitround = bitstart + 52;\n\n\tDUK_DDD(DUK_DDDPRINT(\"ieee expt=%ld, bitstart=%ld, bitround=%ld\",\n\t                     (long) expt, (long) bitstart, (long) bitround));\n\n\tif (!skip_round) {\n\t\tif (duk__dragon4_fixed_format_round(nc_ctx, bitround)) {\n\t\t\t/* Corner case: see test-numconv-parse-mant-carry.js.  We could\n\t\t\t * just bump the exponent and update bitstart, but it's more robust\n\t\t\t * to recompute (but avoid rounding twice).\n\t\t\t */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"rounding caused exponent to be bumped, recheck exponent\"));\n\t\t\tskip_round = 1;\n\t\t\tgoto recheck_exp;\n\t\t}\n\t}\n\n\t/*\n\t *  Create mantissa\n\t */\n\n\tt = 0;\n\tfor (i = 0; i < 52; i++) {\n\t\tbitidx = bitstart + 52 - 1 - i;\n\t\tif (bitidx >= nc_ctx->count) {\n\t\t\tv = 0;\n\t\t} else if (bitidx < 0) {\n\t\t\tv = 0;\n\t\t} else {\n\t\t\tv = nc_ctx->digits[bitidx];\n\t\t}\n\t\tDUK_ASSERT(v == 0 || v == 1);\n\t\tt += v << (i % 32);\n\t\tif (i == 31) {\n\t\t\t/* low 32 bits is complete */\n\t\t\tDUK_DBLUNION_SET_LOW32(&u, t);\n\t\t\tt = 0;\n\t\t}\n\t}\n\t/* t has high mantissa */\n\n\tDUK_DDD(DUK_DDDPRINT(\"mantissa is complete: %08lx %08lx\",\n\t                     (unsigned long) t,\n\t                     (unsigned long) DUK_DBLUNION_GET_LOW32(&u)));\n\n\tDUK_ASSERT(expt >= 0 && expt <= 0x7ffL);\n\tt += ((duk_uint32_t) expt) << 20;\n#if 0  /* caller handles sign change */\n\tif (negative) {\n\t\tt |= 0x80000000U;\n\t}\n#endif\n\tDUK_DBLUNION_SET_HIGH32(&u, t);\n\n\tDUK_DDD(DUK_DDDPRINT(\"number is complete: %08lx %08lx\",\n\t                     (unsigned long) DUK_DBLUNION_GET_HIGH32(&u),\n\t                     (unsigned long) DUK_DBLUNION_GET_LOW32(&u)));\n\n\t*x = DUK_DBLUNION_GET_DOUBLE(&u);\n}\n\n/*\n *  Exposed number-to-string API\n *\n *  Input: [ number ]\n *  Output: [ string ]\n */\n\nDUK_LOCAL DUK_NOINLINE void duk__numconv_stringify_raw(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) {\n\tduk_double_t x;\n\tduk_small_int_t c;\n\tduk_small_int_t neg;\n\tduk_uint32_t uval;\n\tduk__numconv_stringify_ctx nc_ctx_alloc;  /* large context; around 2kB now */\n\tduk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;\n\n\tx = (duk_double_t) duk_require_number(thr, -1);\n\tduk_pop(thr);\n\n\t/*\n\t *  Handle special cases (NaN, infinity, zero).\n\t */\n\n\tc = (duk_small_int_t) DUK_FPCLASSIFY(x);\n\tif (DUK_SIGNBIT((double) x)) {\n\t\tx = -x;\n\t\tneg = 1;\n\t} else {\n\t\tneg = 0;\n\t}\n\n\t/* NaN sign bit is platform specific with unpacked, un-normalized NaNs */\n\tDUK_ASSERT(c == DUK_FP_NAN || DUK_SIGNBIT((double) x) == 0);\n\n\tif (c == DUK_FP_NAN) {\n\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_NAN);\n\t\treturn;\n\t} else if (c == DUK_FP_INFINITE) {\n\t\tif (neg) {\n\t\t\t/* -Infinity */\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_MINUS_INFINITY);\n\t\t} else {\n\t\t\t/* Infinity */\n\t\t\tduk_push_hstring_stridx(thr, DUK_STRIDX_INFINITY);\n\t\t}\n\t\treturn;\n\t} else if (c == DUK_FP_ZERO) {\n\t\t/* We can't shortcut zero here if it goes through special formatting\n\t\t * (such as forced exponential notation).\n\t\t */\n\t\t;\n\t}\n\n\t/*\n\t *  Handle integers in 32-bit range (that is, [-(2**32-1),2**32-1])\n\t *  specially, as they're very likely for embedded programs.  This\n\t *  is now done for all radix values.  We must be careful not to use\n\t *  the fast path when special formatting (e.g. forced exponential)\n\t *  is in force.\n\t *\n\t *  XXX: could save space by supporting radix 10 only and using\n\t *  sprintf \"%lu\" for the fast path and for exponent formatting.\n\t */\n\n\tuval = duk_double_to_uint32_t(x);\n\tif (((double) uval) == x &&  /* integer number in range */\n\t    flags == 0) {            /* no special formatting */\n\t\t/* use bigint area as a temp */\n\t\tduk_uint8_t *buf = (duk_uint8_t *) (&nc_ctx->f);\n\t\tduk_uint8_t *p = buf;\n\n\t\tDUK_ASSERT(DUK__NUMCONV_CTX_BIGINTS_SIZE >= 32 + 1);  /* max size: radix=2 + sign */\n\t\tif (neg && uval != 0) {\n\t\t\t/* no negative sign for zero */\n\t\t\t*p++ = (duk_uint8_t) '-';\n\t\t}\n\t\tp += duk__dragon4_format_uint32(p, uval, radix);\n\t\tduk_push_lstring(thr, (const char *) buf, (duk_size_t) (p - buf));\n\t\treturn;\n\t}\n\n\t/*\n\t *  Dragon4 setup.\n\t *\n\t *  Convert double from IEEE representation for conversion;\n\t *  normal finite values have an implicit leading 1-bit.  The\n\t *  slow path algorithm doesn't handle zero, so zero is special\n\t *  cased here but still creates a valid nc_ctx, and goes\n\t *  through normal formatting in case special formatting has\n\t *  been requested (e.g. forced exponential format: 0 -> \"0e+0\").\n\t */\n\n\t/* Would be nice to bulk clear the allocation, but the context\n\t * is 1-2 kilobytes and nothing should rely on it being zeroed.\n\t */\n#if 0\n\tduk_memzero((void *) nc_ctx, sizeof(*nc_ctx));  /* slow init, do only for slow path cases */\n#endif\n\n\tnc_ctx->is_s2n = 0;\n\tnc_ctx->b = 2;\n\tnc_ctx->B = radix;\n\tnc_ctx->abs_pos = 0;\n\tif (flags & DUK_N2S_FLAG_FIXED_FORMAT) {\n\t\tnc_ctx->is_fixed = 1;\n\t\tif (flags & DUK_N2S_FLAG_FRACTION_DIGITS) {\n\t\t\t/* absolute req_digits; e.g. digits = 1 -> last digit is 0,\n\t\t\t * but add an extra digit for rounding.\n\t\t\t */\n\t\t\tnc_ctx->abs_pos = 1;\n\t\t\tnc_ctx->req_digits = (-digits + 1) - 1;\n\t\t} else {\n\t\t\tnc_ctx->req_digits = digits + 1;\n\t\t}\n\t} else {\n\t\tnc_ctx->is_fixed = 0;\n\t\tnc_ctx->req_digits = 0;\n\t}\n\n\tif (c == DUK_FP_ZERO) {\n\t\t/* Zero special case: fake requested number of zero digits; ensure\n\t\t * no sign bit is printed.  Relative and absolute fixed format\n\t\t * require separate handling.\n\t\t */\n\t\tduk_small_int_t count;\n\t\tif (nc_ctx->is_fixed) {\n\t\t\tif (nc_ctx->abs_pos) {\n\t\t\t\tcount = digits + 2;  /* lead zero + 'digits' fractions + 1 for rounding */\n\t\t\t} else {\n\t\t\t\tcount = digits + 1;  /* + 1 for rounding */\n\t\t\t}\n\t\t} else {\n\t\t\tcount = 1;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"count=%ld\", (long) count));\n\t\tDUK_ASSERT(count >= 1);\n\t\tduk_memzero((void *) nc_ctx->digits, (size_t) count);\n\t\tnc_ctx->count = count;\n\t\tnc_ctx->k = 1;  /* 0.000... */\n\t\tneg = 0;\n\t\tgoto zero_skip;\n\t}\n\n\tduk__dragon4_double_to_ctx(nc_ctx, x);   /* -> sets 'f' and 'e' */\n\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\tDUK_DDD(DUK_DDDPRINT(\"e=%ld\", (long) nc_ctx->e));\n\n\t/*\n\t *  Dragon4 slow path digit generation.\n\t */\n\n\tduk__dragon4_prepare(nc_ctx);  /* setup many variables in nc_ctx */\n\n\tDUK_DDD(DUK_DDDPRINT(\"after prepare:\"));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_scale(nc_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"after scale; k=%ld\", (long) nc_ctx->k));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_generate(nc_ctx);\n\n\t/*\n\t *  Convert and push final string.\n\t */\n\n zero_skip:\n\n\tif (flags & DUK_N2S_FLAG_FIXED_FORMAT) {\n\t\t/* Perform fixed-format rounding. */\n\t\tduk_small_int_t roundpos;\n\t\tif (flags & DUK_N2S_FLAG_FRACTION_DIGITS) {\n\t\t\t/* 'roundpos' is relative to nc_ctx->k and increases to the right\n\t\t\t * (opposite of how 'k' changes).\n\t\t\t */\n\t\t\troundpos = -digits;  /* absolute position for digit considered for rounding */\n\t\t\troundpos = nc_ctx->k - roundpos;\n\t\t} else {\n\t\t\troundpos = digits;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"rounding: k=%ld, count=%ld, digits=%ld, roundpos=%ld\",\n\t\t                     (long) nc_ctx->k, (long) nc_ctx->count, (long) digits, (long) roundpos));\n\t\t(void) duk__dragon4_fixed_format_round(nc_ctx, roundpos);\n\n\t\t/* Note: 'count' is currently not adjusted by rounding (i.e. the\n\t\t * digits are not \"chopped off\".  That shouldn't matter because\n\t\t * the digit position (absolute or relative) is passed on to the\n\t\t * convert-and-push function.\n\t\t */\n\t}\n\n\tduk__dragon4_convert_and_push(nc_ctx, thr, radix, digits, flags, neg);\n}\n\nDUK_INTERNAL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags) {\n\tduk_native_stack_check(thr);\n\tduk__numconv_stringify_raw(thr, radix, digits, flags);\n}\n\n/*\n *  Exposed string-to-number API\n *\n *  Input: [ string ]\n *  Output: [ number ]\n *\n *  If number parsing fails, a NaN is pushed as the result.  If number parsing\n *  fails due to an internal error, an InternalError is thrown.\n */\n\nDUK_LOCAL DUK_NOINLINE void duk__numconv_parse_raw(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags) {\n\tduk__numconv_stringify_ctx nc_ctx_alloc;  /* large context; around 2kB now */\n\tduk__numconv_stringify_ctx *nc_ctx = &nc_ctx_alloc;\n\tduk_double_t res;\n\tduk_hstring *h_str;\n\tduk_int_t expt;\n\tduk_bool_t expt_neg;\n\tduk_small_int_t expt_adj;\n\tduk_small_int_t neg;\n\tduk_small_int_t dig;\n\tduk_small_int_t dig_whole;\n\tduk_small_int_t dig_lzero;\n\tduk_small_int_t dig_frac;\n\tduk_small_int_t dig_expt;\n\tduk_small_int_t dig_prec;\n\tconst duk__exp_limits *explim;\n\tconst duk_uint8_t *p;\n\tduk_small_int_t ch;\n\n\tDUK_DDD(DUK_DDDPRINT(\"parse number: %!T, radix=%ld, flags=0x%08lx\",\n\t                     (duk_tval *) duk_get_tval(thr, -1),\n\t                     (long) radix, (unsigned long) flags));\n\n\tDUK_ASSERT(radix >= 2 && radix <= 36);\n\tDUK_ASSERT(radix - 2 < (duk_small_int_t) sizeof(duk__str2num_digits_for_radix));\n\n\t/*\n\t *  Preliminaries: trim, sign, Infinity check\n\t *\n\t *  We rely on the interned string having a NUL terminator, which will\n\t *  cause a parse failure wherever it is encountered.  As a result, we\n\t *  don't need separate pointer checks.\n\t *\n\t *  There is no special parsing for 'NaN' in the specification although\n\t *  'Infinity' (with an optional sign) is allowed in some contexts.\n\t *  Some contexts allow plus/minus sign, while others only allow the\n\t *  minus sign (like JSON.parse()).\n\t *\n\t *  Automatic hex number detection (leading '0x' or '0X') and octal\n\t *  number detection (leading '0' followed by at least one octal digit)\n\t *  is done here too.\n\t *\n\t *  Symbols are not explicitly rejected here (that's up to the caller).\n\t *  If a symbol were passed here, it should ultimately safely fail\n\t *  parsing due to a syntax error.\n\t */\n\n\tif (flags & DUK_S2N_FLAG_TRIM_WHITE) {\n\t\t/* Leading / trailing whitespace is sometimes accepted and\n\t\t * sometimes not.  After white space trimming, all valid input\n\t\t * characters are pure ASCII.\n\t\t */\n\t\tduk_trim(thr, -1);\n\t}\n\th_str = duk_require_hstring(thr, -1);\n\tDUK_ASSERT(h_str != NULL);\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_str);\n\n\tneg = 0;\n\tch = *p;\n\tif (ch == (duk_small_int_t) '+') {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_PLUS) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: leading plus sign not allowed\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t\tp++;\n\t} else if (ch == (duk_small_int_t) '-') {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_MINUS) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: leading minus sign not allowed\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t\tp++;\n\t\tneg = 1;\n\t}\n\n\tif ((flags & DUK_S2N_FLAG_ALLOW_INF) && DUK_STRNCMP((const char *) p, \"Infinity\", 8) == 0) {\n\t\t/* Don't check for Infinity unless the context allows it.\n\t\t * 'Infinity' is a valid integer literal in e.g. base-36:\n\t\t *\n\t\t *   parseInt('Infinity', 36)\n\t\t *   1461559270678\n\t\t */\n\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_GARBAGE) == 0 && p[8] != DUK_ASC_NUL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: trailing garbage after matching 'Infinity' not allowed\"));\n\t\t\tgoto parse_fail;\n\t\t} else {\n\t\t\tres = DUK_DOUBLE_INFINITY;\n\t\t\tgoto negcheck_and_ret;\n\t\t}\n\t}\n\tch = *p;\n\tif (ch == (duk_small_int_t) '0') {\n\t\tduk_small_int_t detect_radix = 0;\n\t\tch = DUK_LOWERCASE_CHAR_ASCII(p[1]);  /* 'x' or 'X' -> 'x' */\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT) && ch == DUK_ASC_LC_X) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0x/0X hex prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 16;\n#if 0\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_LEGACY_OCT_INT) &&\n\t\t           (ch >= (duk_small_int_t) '0' && ch <= (duk_small_int_t) '9')) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0n oct prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 8;\n\n\t\t\t/* NOTE: if this legacy octal case is added back, it has\n\t\t\t * different flags and 'p' advance so this needs to be\n\t\t\t * reworked.\n\t\t\t */\n\t\t\tflags |= DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO;  /* interpret e.g. '09' as '0', not NaN */\n\t\t\tp += 1;\n#endif\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT) && ch == DUK_ASC_LC_O) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0o oct prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 8;\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT) && ch == DUK_ASC_LC_B) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"detected 0b bin prefix, changing radix and preventing fractions and exponent\"));\n\t\t\tdetect_radix = 2;\n\t\t}\n\t\tif (detect_radix > 0) {\n\t\t\tradix = detect_radix;\n\t\t\t/* Clear empty as zero flag: interpret e.g. '0x' and '0xg' as a NaN (= parse error) */\n\t\t\tflags &= ~(DUK_S2N_FLAG_ALLOW_EXP | DUK_S2N_FLAG_ALLOW_EMPTY_FRAC |\n\t\t\t           DUK_S2N_FLAG_ALLOW_FRAC | DUK_S2N_FLAG_ALLOW_NAKED_FRAC |\n\t\t\t           DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO);\n\t\t\tflags |= DUK_S2N_FLAG_ALLOW_LEADING_ZERO;  /* allow e.g. '0x0009' and '0b00010001' */\n\t\t\tp += 2;\n\t\t}\n\t}\n\n\t/*\n\t *  Scan number and setup for Dragon4.\n\t *\n\t *  The fast path case is detected during setup: an integer which\n\t *  can be converted without rounding, no net exponent.  The fast\n\t *  path could be implemented as a separate scan, but may not really\n\t *  be worth it: the multiplications for building 'f' are not\n\t *  expensive when 'f' is small.\n\t *\n\t *  The significand ('f') must contain enough bits of (apparent)\n\t *  accuracy, so that Dragon4 will generate enough binary output digits.\n\t *  For decimal numbers, this means generating a 20-digit significand,\n\t *  which should yield enough practical accuracy to parse IEEE doubles.\n\t *  In fact, the ECMAScript specification explicitly allows an\n\t *  implementation to treat digits beyond 20 as zeroes (and even\n\t *  to round the 20th digit upwards).  For non-decimal numbers, the\n\t *  appropriate number of digits has been precomputed for comparable\n\t *  accuracy.\n\t *\n\t *  Digit counts:\n\t *\n\t *    [ dig_lzero ]\n\t *      |\n\t *     .+-..---[ dig_prec ]----.\n\t *     |  ||                   |\n\t *     0000123.456789012345678901234567890e+123456\n\t *     |     | |                         |  |    |\n\t *     `--+--' `------[ dig_frac ]-------'  `-+--'\n\t *        |                                   |\n\t *    [ dig_whole ]                       [ dig_expt ]\n\t *\n\t *    dig_frac and dig_expt are -1 if not present\n\t *    dig_lzero is only computed for whole number part\n\t *\n\t *  Parsing state\n\t *\n\t *     Parsing whole part      dig_frac < 0 AND dig_expt < 0\n\t *     Parsing fraction part   dig_frac >= 0 AND dig_expt < 0\n\t *     Parsing exponent part   dig_expt >= 0   (dig_frac may be < 0 or >= 0)\n\t *\n\t *  Note: in case we hit an implementation limit (like exponent range),\n\t *  we should throw an error, NOT return NaN or Infinity.  Even with\n\t *  very large exponent (or significand) values the final result may be\n\t *  finite, so NaN/Infinity would be incorrect.\n\t */\n\n\tduk__bi_set_small(&nc_ctx->f, 0);\n\tdig_prec = 0;\n\tdig_lzero = 0;\n\tdig_whole = 0;\n\tdig_frac = -1;\n\tdig_expt = -1;\n\texpt = 0;\n\texpt_adj = 0;  /* essentially tracks digit position of lowest 'f' digit */\n\texpt_neg = 0;\n\tfor (;;) {\n\t\tch = *p++;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"parse digits: p=%p, ch='%c' (%ld), expt=%ld, expt_adj=%ld, \"\n\t\t                     \"dig_whole=%ld, dig_frac=%ld, dig_expt=%ld, dig_lzero=%ld, dig_prec=%ld\",\n\t\t                     (const void *) p, (int) ((ch >= 0x20 && ch <= 0x7e) ? ch : '?'), (long) ch,\n\t\t                     (long) expt, (long) expt_adj, (long) dig_whole, (long) dig_frac,\n\t\t                     (long) dig_expt, (long) dig_lzero, (long) dig_prec));\n\t\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\n\t\t/* Most common cases first. */\n\t\tif (ch >= (duk_small_int_t) '0' && ch <= (duk_small_int_t) '9') {\n\t\t\tdig = (duk_small_int_t) ch - '0' + 0;\n\t\t} else if (ch == (duk_small_int_t) '.') {\n\t\t\t/* A leading digit is not required in some cases, e.g. accept \".123\".\n\t\t\t * In other cases (JSON.parse()) a leading digit is required.  This\n\t\t\t * is checked for after the loop.\n\t\t\t */\n\t\t\tif (dig_frac >= 0 || dig_expt >= 0) {\n\t\t\t\tif (flags & DUK_S2N_FLAG_ALLOW_GARBAGE) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"garbage termination (invalid period)\"));\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: period not allowed\"));\n\t\t\t\t\tgoto parse_fail;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_FRAC) == 0) {\n\t\t\t\t/* Some contexts don't allow fractions at all; this can't be a\n\t\t\t\t * post-check because the state ('f' and expt) would be incorrect.\n\t\t\t\t */\n\t\t\t\tif (flags & DUK_S2N_FLAG_ALLOW_GARBAGE) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"garbage termination (invalid first period)\"));\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: fraction part not allowed\"));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"start fraction part\"));\n\t\t\tdig_frac = 0;\n\t\t\tcontinue;\n\t\t} else if (ch == (duk_small_int_t) 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"NUL termination\"));\n\t\t\tbreak;\n\t\t} else if ((flags & DUK_S2N_FLAG_ALLOW_EXP) &&\n\t\t           dig_expt < 0 && (ch == (duk_small_int_t) 'e' || ch == (duk_small_int_t) 'E')) {\n\t\t\t/* Note: we don't parse back exponent notation for anything else\n\t\t\t * than radix 10, so this is not an ambiguous check (e.g. hex\n\t\t\t * exponent values may have 'e' either as a significand digit\n\t\t\t * or as an exponent separator).\n\t\t\t *\n\t\t\t * If the exponent separator occurs twice, 'e' will be interpreted\n\t\t\t * as a digit (= 14) and will be rejected as an invalid decimal\n\t\t\t * digit.\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"start exponent part\"));\n\n\t\t\t/* Exponent without a sign or with a +/- sign is accepted\n\t\t\t * by all call sites (even JSON.parse()).\n\t\t\t */\n\t\t\tch = *p;\n\t\t\tif (ch == (duk_small_int_t) '-') {\n\t\t\t\texpt_neg = 1;\n\t\t\t\tp++;\n\t\t\t} else if (ch == (duk_small_int_t) '+') {\n\t\t\t\tp++;\n\t\t\t}\n\t\t\tdig_expt = 0;\n\t\t\tcontinue;\n\t\t} else if (ch >= (duk_small_int_t) 'a' && ch <= (duk_small_int_t) 'z') {\n\t\t\tdig = (duk_small_int_t) (ch - (duk_small_int_t) 'a' + 0x0a);\n\t\t} else if (ch >= (duk_small_int_t) 'A' && ch <= (duk_small_int_t) 'Z') {\n\t\t\tdig = (duk_small_int_t) (ch - (duk_small_int_t) 'A' + 0x0a);\n\t\t} else {\n\t\t\tdig = 255;  /* triggers garbage digit check below */\n\t\t}\n\t\tDUK_ASSERT((dig >= 0 && dig <= 35) || dig == 255);\n\n\t\tif (dig >= radix) {\n\t\t\tif (flags & DUK_S2N_FLAG_ALLOW_GARBAGE) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"garbage termination\"));\n\t\t\t\tbreak;\n\t\t\t} else {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: trailing garbage or invalid digit\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t}\n\n\t\tif (dig_expt < 0) {\n\t\t\t/* whole or fraction digit */\n\n\t\t\tif (dig_prec < duk__str2num_digits_for_radix[radix - 2]) {\n\t\t\t\t/* significant from precision perspective */\n\n\t\t\t\tduk_small_int_t f_zero = duk__bi_is_zero(&nc_ctx->f);\n\t\t\t\tif (f_zero && dig == 0) {\n\t\t\t\t\t/* Leading zero is not counted towards precision digits; not\n\t\t\t\t\t * in the integer part, nor in the fraction part.\n\t\t\t\t\t */\n\t\t\t\t\tif (dig_frac < 0) {\n\t\t\t\t\t\tdig_lzero++;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t/* XXX: join these ops (multiply-accumulate), but only if\n\t\t\t\t\t * code footprint decreases.\n\t\t\t\t\t */\n\t\t\t\t\tduk__bi_mul_small(&nc_ctx->t1, &nc_ctx->f, (duk_uint32_t) radix);\n\t\t\t\t\tduk__bi_add_small(&nc_ctx->f, &nc_ctx->t1, (duk_uint32_t) dig);\n\t\t\t\t\tdig_prec++;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t/* Ignore digits beyond a radix-specific limit, but note them\n\t\t\t\t * in expt_adj.\n\t\t\t\t */\n\t\t\t\texpt_adj++;\n\t\t\t}\n\n\t\t\tif (dig_frac >= 0) {\n\t\t\t\tdig_frac++;\n\t\t\t\texpt_adj--;\n\t\t\t} else {\n\t\t\t\tdig_whole++;\n\t\t\t}\n\t\t} else {\n\t\t\t/* exponent digit */\n\n\t\t\tDUK_ASSERT(radix == 10);\n\t\t\texpt = expt * radix + dig;\n\t\t\tif (expt > DUK_S2N_MAX_EXPONENT) {\n\t\t\t\t/* Impose a reasonable exponent limit, so that exp\n\t\t\t\t * doesn't need to get tracked using a bigint.\n\t\t\t\t */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: exponent too large\"));\n\t\t\t\tgoto parse_explimit_error;\n\t\t\t}\n\t\t\tdig_expt++;\n\t\t}\n\t}\n\n\t/* Leading zero. */\n\n\tif (dig_lzero > 0 && dig_whole > 1) {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_LEADING_ZERO) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: leading zeroes not allowed in integer part\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t}\n\n\t/* Validity checks for various fraction formats (\"0.1\", \".1\", \"1.\", \".\"). */\n\n\tif (dig_whole == 0) {\n\t\tif (dig_frac == 0) {\n\t\t\t/* \".\" is not accepted in any format */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: plain period without leading or trailing digits\"));\n\t\t\tgoto parse_fail;\n\t\t} else if (dig_frac > 0) {\n\t\t\t/* \".123\" */\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_NAKED_FRAC) == 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: fraction part not allowed without \"\n\t\t\t\t                     \"leading integer digit(s)\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t} else {\n\t\t\t/* Empty (\"\") is allowed in some formats (e.g. Number(''), as zero,\n\t\t\t * but it must not have a leading +/- sign (GH-2019).  Note that\n\t\t\t * for Number(), h_str is already trimmed so we can check for zero\n\t\t\t * length and still get Number('  +  ') == NaN.\n\t\t\t */\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO) == 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: empty string not allowed (as zero)\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t} else if (DUK_HSTRING_GET_BYTELEN(h_str) != 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: no digits, but not empty (had a +/- sign)\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t}\n\t} else {\n\t\tif (dig_frac == 0) {\n\t\t\t/* \"123.\" is allowed in some formats */\n\t\t\tif ((flags & DUK_S2N_FLAG_ALLOW_EMPTY_FRAC) == 0) {\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: empty fractions\"));\n\t\t\t\tgoto parse_fail;\n\t\t\t}\n\t\t} else if (dig_frac > 0) {\n\t\t\t/* \"123.456\" */\n\t\t\t;\n\t\t} else {\n\t\t\t/* \"123\" */\n\t\t\t;\n\t\t}\n\t}\n\n\t/* Exponent without digits (e.g. \"1e\" or \"1e+\").  If trailing garbage is\n\t * allowed, ignore exponent part as garbage (= parse as \"1\", i.e. exp 0).\n\t */\n\n\tif (dig_expt == 0) {\n\t\tif ((flags & DUK_S2N_FLAG_ALLOW_GARBAGE) == 0) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"parse failed: empty exponent\"));\n\t\t\tgoto parse_fail;\n\t\t}\n\t\tDUK_ASSERT(expt == 0);\n\t}\n\n\tif (expt_neg) {\n\t\texpt = -expt;\n\t}\n\tDUK_DDD(DUK_DDDPRINT(\"expt=%ld, expt_adj=%ld, net exponent -> %ld\",\n\t                     (long) expt, (long) expt_adj, (long) (expt + expt_adj)));\n\texpt += expt_adj;\n\n\t/* Fast path check. */\n\n\tif (nc_ctx->f.n <= 1 &&   /* 32-bit value */\n\t    expt == 0    /* no net exponent */) {\n\t\t/* Fast path is triggered for no exponent and also for balanced exponent\n\t\t * and fraction parts, e.g. for \"1.23e2\" == \"123\".  Remember to respect\n\t\t * zero sign.\n\t\t */\n\n\t\t/* XXX: could accept numbers larger than 32 bits, e.g. up to 53 bits? */\n\t\tDUK_DDD(DUK_DDDPRINT(\"fast path number parse\"));\n\t\tif (nc_ctx->f.n == 1) {\n\t\t\tres = (double) nc_ctx->f.v[0];\n\t\t} else {\n\t\t\tres = 0.0;\n\t\t}\n\t\tgoto negcheck_and_ret;\n\t}\n\n\t/* Significand ('f') padding. */\n\n\twhile (dig_prec < duk__str2num_digits_for_radix[radix - 2]) {\n\t\t/* Pad significand with \"virtual\" zero digits so that Dragon4 will\n\t\t * have enough (apparent) precision to work with.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"dig_prec=%ld, pad significand with zero\", (long) dig_prec));\n\t\tduk__bi_mul_small_copy(&nc_ctx->f, (duk_uint32_t) radix, &nc_ctx->t1);\n\t\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\t\texpt--;\n\t\tdig_prec++;\n\t}\n\n\tDUK_DDD(DUK_DDDPRINT(\"final exponent: %ld\", (long) expt));\n\n\t/* Detect zero special case. */\n\n\tif (nc_ctx->f.n == 0) {\n\t\t/* This may happen even after the fast path check, if exponent is\n\t\t * not balanced (e.g. \"0e1\").  Remember to respect zero sign.\n\t\t */\n\t\tDUK_DDD(DUK_DDDPRINT(\"significand is zero\"));\n\t\tres = 0.0;\n\t\tgoto negcheck_and_ret;\n\t}\n\n\n\t/* Quick reject of too large or too small exponents.  This check\n\t * would be incorrect for zero (e.g. \"0e1000\" is zero, not Infinity)\n\t * so zero check must be above.\n\t */\n\n\texplim = &duk__str2num_exp_limits[radix - 2];\n\tif (expt > explim->upper) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"exponent too large -> infinite\"));\n\t\tres = (duk_double_t) DUK_DOUBLE_INFINITY;\n\t\tgoto negcheck_and_ret;\n\t} else if (expt < explim->lower) {\n\t\tDUK_DDD(DUK_DDDPRINT(\"exponent too small -> zero\"));\n\t\tres = (duk_double_t) 0.0;\n\t\tgoto negcheck_and_ret;\n\t}\n\n\tnc_ctx->is_s2n = 1;\n\tnc_ctx->e = expt;\n\tnc_ctx->b = radix;\n\tnc_ctx->B = 2;\n\tnc_ctx->is_fixed = 1;\n\tnc_ctx->abs_pos = 0;\n\tnc_ctx->req_digits = 53 + 1;\n\n\tDUK__BI_PRINT(\"f\", &nc_ctx->f);\n\tDUK_DDD(DUK_DDDPRINT(\"e=%ld\", (long) nc_ctx->e));\n\n\t/*\n\t *  Dragon4 slow path (binary) digit generation.\n\t *  An extra digit is generated for rounding.\n\t */\n\n\tduk__dragon4_prepare(nc_ctx);  /* setup many variables in nc_ctx */\n\n\tDUK_DDD(DUK_DDDPRINT(\"after prepare:\"));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_scale(nc_ctx);\n\n\tDUK_DDD(DUK_DDDPRINT(\"after scale; k=%ld\", (long) nc_ctx->k));\n\tDUK__BI_PRINT(\"r\", &nc_ctx->r);\n\tDUK__BI_PRINT(\"s\", &nc_ctx->s);\n\tDUK__BI_PRINT(\"mp\", &nc_ctx->mp);\n\tDUK__BI_PRINT(\"mm\", &nc_ctx->mm);\n\n\tduk__dragon4_generate(nc_ctx);\n\n\tDUK_ASSERT(nc_ctx->count == 53 + 1);\n\n\t/*\n\t *  Convert binary digits into an IEEE double.  Need to handle\n\t *  denormals and rounding correctly.\n\t *\n\t *  Some call sites currently assume the result is always a\n\t *  non-fastint double.  If this is changed, check all call\n\t *  sites.\n\t */\n\n\tduk__dragon4_ctx_to_double(nc_ctx, &res);\n\tgoto negcheck_and_ret;\n\n negcheck_and_ret:\n\tif (neg) {\n\t\tres = -res;\n\t}\n\tduk_pop(thr);\n\tduk_push_number(thr, (double) res);\n\tDUK_DDD(DUK_DDDPRINT(\"result: %!T\", (duk_tval *) duk_get_tval(thr, -1)));\n\treturn;\n\n parse_fail:\n\tDUK_DDD(DUK_DDDPRINT(\"parse failed\"));\n\tduk_pop(thr);\n\tduk_push_nan(thr);\n\treturn;\n\n parse_explimit_error:\n\tDUK_DDD(DUK_DDDPRINT(\"parse failed, internal error, can't return a value\"));\n\tDUK_ERROR_RANGE(thr, \"exponent too large\");\n\tDUK_WO_NORETURN(return;);\n}\n\nDUK_INTERNAL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags) {\n\tduk_native_stack_check(thr);\n\tduk__numconv_parse_raw(thr, radix, flags);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_numconv.h",
    "content": "/*\n *  Number-to-string conversion.  The semantics of these is very tightly\n *  bound with the ECMAScript semantics required for call sites.\n */\n\n#if !defined(DUK_NUMCONV_H_INCLUDED)\n#define DUK_NUMCONV_H_INCLUDED\n\n/* Output a specified number of digits instead of using the shortest\n * form.  Used for toPrecision() and toFixed().\n */\n#define DUK_N2S_FLAG_FIXED_FORMAT         (1U << 0)\n\n/* Force exponential format.  Used for toExponential(). */\n#define DUK_N2S_FLAG_FORCE_EXP            (1U << 1)\n\n/* If number would need zero padding (for whole number part), use\n * exponential format instead.  E.g. if input number is 12300, 3\n * digits are generated (\"123\"), output \"1.23e+4\" instead of \"12300\".\n * Used for toPrecision().\n */\n#define DUK_N2S_FLAG_NO_ZERO_PAD          (1U << 2)\n\n/* Digit count indicates number of fractions (i.e. an absolute\n * digit index instead of a relative one).  Used together with\n * DUK_N2S_FLAG_FIXED_FORMAT for toFixed().\n */\n#define DUK_N2S_FLAG_FRACTION_DIGITS      (1U << 3)\n\n/*\n *  String-to-number conversion\n */\n\n/* Maximum exponent value when parsing numbers.  This is not strictly\n * compliant as there should be no upper limit, but as we parse the\n * exponent without a bigint, impose some limit.  The limit should be\n * small enough that multiplying it (or limit-1 to be precise) won't\n * overflow signed 32-bit integer range.  Exponent is only parsed with\n * radix 10, but with maximum radix (36) a safe limit is:\n * (10000000*36).toString(16) -> '15752a00'\n */\n#define DUK_S2N_MAX_EXPONENT              10000000L\n\n/* Trim white space (= allow leading and trailing whitespace) */\n#define DUK_S2N_FLAG_TRIM_WHITE           (1U << 0)\n\n/* Allow exponent */\n#define DUK_S2N_FLAG_ALLOW_EXP            (1U << 1)\n\n/* Allow trailing garbage (e.g. treat \"123foo\" as \"123) */\n#define DUK_S2N_FLAG_ALLOW_GARBAGE        (1U << 2)\n\n/* Allow leading plus sign */\n#define DUK_S2N_FLAG_ALLOW_PLUS           (1U << 3)\n\n/* Allow leading minus sign */\n#define DUK_S2N_FLAG_ALLOW_MINUS          (1U << 4)\n\n/* Allow 'Infinity' */\n#define DUK_S2N_FLAG_ALLOW_INF            (1U << 5)\n\n/* Allow fraction part */\n#define DUK_S2N_FLAG_ALLOW_FRAC           (1U << 6)\n\n/* Allow naked fraction (e.g. \".123\") */\n#define DUK_S2N_FLAG_ALLOW_NAKED_FRAC     (1U << 7)\n\n/* Allow empty fraction (e.g. \"123.\") */\n#define DUK_S2N_FLAG_ALLOW_EMPTY_FRAC     (1U << 8)\n\n/* Allow empty string to be interpreted as 0 */\n#define DUK_S2N_FLAG_ALLOW_EMPTY_AS_ZERO  (1U << 9)\n\n/* Allow leading zeroes (e.g. \"0123\" -> \"123\") */\n#define DUK_S2N_FLAG_ALLOW_LEADING_ZERO   (1U << 10)\n\n/* Allow automatic detection of hex base (\"0x\" or \"0X\" prefix),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_HEX_INT   (1U << 11)\n\n/* Allow automatic detection of legacy octal base (\"0n\"),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_LEGACY_OCT_INT   (1U << 12)\n\n/* Allow automatic detection of ES2015 octal base (\"0o123\"),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_OCT_INT   (1U << 13)\n\n/* Allow automatic detection of ES2015 binary base (\"0b10001\"),\n * overrides radix argument and forces integer mode.\n */\n#define DUK_S2N_FLAG_ALLOW_AUTO_BIN_INT   (1U << 14)\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL void duk_numconv_stringify(duk_hthread *thr, duk_small_int_t radix, duk_small_int_t digits, duk_small_uint_t flags);\nDUK_INTERNAL_DECL void duk_numconv_parse(duk_hthread *thr, duk_small_int_t radix, duk_small_uint_t flags);\n\n#endif  /* DUK_NUMCONV_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_refcount.h",
    "content": "/*\n *  Reference counting helper macros.  The macros take a thread argument\n *  and must thus always be executed in a specific thread context.  The\n *  thread argument is not really needed anymore: DECREF can operate with\n *  a heap pointer only, and INCREF needs neither.\n */\n\n#if !defined(DUK_REFCOUNT_H_INCLUDED)\n#define DUK_REFCOUNT_H_INCLUDED\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n\n#if defined(DUK_USE_ROM_OBJECTS)\n/* With ROM objects \"needs refcount update\" is true when the value is\n * heap allocated and is not a ROM object.\n */\n/* XXX: double evaluation for 'tv' argument. */\n#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv) \\\n\t(DUK_TVAL_IS_HEAP_ALLOCATED((tv)) && !DUK_HEAPHDR_HAS_READONLY(DUK_TVAL_GET_HEAPHDR((tv))))\n#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h)  (!DUK_HEAPHDR_HAS_READONLY((h)))\n#else  /* DUK_USE_ROM_OBJECTS */\n/* Without ROM objects \"needs refcount update\" == is heap allocated. */\n#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)    DUK_TVAL_IS_HEAP_ALLOCATED((tv))\n#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h)  1\n#endif  /* DUK_USE_ROM_OBJECTS */\n\n/* Fast variants, inline refcount operations except for refzero handling.\n * Can be used explicitly when speed is always more important than size.\n * For a good compiler and a single file build, these are basically the\n * same as a forced inline.\n */\n#define DUK_TVAL_INCREF_FAST(thr,tv) do { \\\n\t\tduk_tval *duk__tv = (tv); \\\n\t\tDUK_ASSERT(duk__tv != NULL); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \\\n\t\t\tduk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \\\n\t\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(duk__h); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) != 0);  /* No wrapping. */ \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_DECREF_FAST(thr,tv) do { \\\n\t\tduk_tval *duk__tv = (tv); \\\n\t\tDUK_ASSERT(duk__tv != NULL); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \\\n\t\t\tduk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \\\n\t\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \\\n\t\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \\\n\t\t\t\tduk_heaphdr_refzero((thr), duk__h); \\\n\t\t\t} \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_DECREF_NORZ_FAST(thr,tv) do { \\\n\t\tduk_tval *duk__tv = (tv); \\\n\t\tDUK_ASSERT(duk__tv != NULL); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(duk__tv)) { \\\n\t\t\tduk_heaphdr *duk__h = DUK_TVAL_GET_HEAPHDR(duk__tv); \\\n\t\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \\\n\t\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \\\n\t\t\t\tduk_heaphdr_refzero_norz((thr), duk__h); \\\n\t\t\t} \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_INCREF_FAST(thr,h) do { \\\n\t\tduk_heaphdr *duk__h = (duk_heaphdr *) (h); \\\n\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\tif (DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(duk__h)) { \\\n\t\t\tDUK_HEAPHDR_PREINC_REFCOUNT(duk__h); \\\n\t\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) != 0);  /* No wrapping. */ \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_FAST_RAW(thr,h,rzcall,rzcast) do { \\\n\t\tduk_heaphdr *duk__h = (duk_heaphdr *) (h); \\\n\t\tDUK_ASSERT(duk__h != NULL); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_HTYPE_VALID(duk__h)); \\\n\t\tDUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(duk__h) > 0); \\\n\t\tif (DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(duk__h)) { \\\n\t\t\tif (DUK_HEAPHDR_PREDEC_REFCOUNT(duk__h) == 0) { \\\n\t\t\t\t(rzcall)((thr), (rzcast) duk__h); \\\n\t\t\t} \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_FAST(thr,h) \\\n\tDUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero,duk_heaphdr *)\n#define DUK_HEAPHDR_DECREF_NORZ_FAST(thr,h) \\\n\tDUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero_norz,duk_heaphdr *)\n\n/* Slow variants, call to a helper to reduce code size.\n * Can be used explicitly when size is always more important than speed.\n */\n#define DUK_TVAL_INCREF_SLOW(thr,tv)         do { duk_tval_incref((tv)); } while (0)\n#define DUK_TVAL_DECREF_SLOW(thr,tv)         do { duk_tval_decref((thr), (tv)); } while (0)\n#define DUK_TVAL_DECREF_NORZ_SLOW(thr,tv)    do { duk_tval_decref_norz((thr), (tv)); } while (0)\n#define DUK_HEAPHDR_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HEAPHDR_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HSTRING_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HSTRING_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HSTRING_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HBUFFER_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HBUFFER_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HBUFFER_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HOBJECT_INCREF_SLOW(thr,h)       do { duk_heaphdr_incref((duk_heaphdr *) (h)); } while (0)\n#define DUK_HOBJECT_DECREF_SLOW(thr,h)       do { duk_heaphdr_decref((thr), (duk_heaphdr *) (h)); } while (0)\n#define DUK_HOBJECT_DECREF_NORZ_SLOW(thr,h)  do { duk_heaphdr_decref_norz((thr), (duk_heaphdr *) (h)); } while (0)\n\n/* Default variants.  Selection depends on speed/size preference.\n * Concretely: with gcc 4.8.1 -Os x64 the difference in final binary\n * is about +1kB for _FAST variants.\n */\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n/* XXX: It would be nice to specialize for specific duk_hobject subtypes\n * but current refzero queue handling prevents that.\n */\n#define DUK_TVAL_INCREF(thr,tv)                DUK_TVAL_INCREF_FAST((thr),(tv))\n#define DUK_TVAL_DECREF(thr,tv)                DUK_TVAL_DECREF_FAST((thr),(tv))\n#define DUK_TVAL_DECREF_NORZ(thr,tv)           DUK_TVAL_DECREF_NORZ_FAST((thr),(tv))\n#define DUK_HEAPHDR_INCREF(thr,h)              DUK_HEAPHDR_INCREF_FAST((thr),(h))\n#define DUK_HEAPHDR_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero,duk_heaphdr *)\n#define DUK_HEAPHDR_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_heaphdr_refzero_norz,duk_heaphdr *)\n#define DUK_HSTRING_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HSTRING_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hstring_refzero,duk_hstring *)\n#define DUK_HSTRING_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hstring_refzero,duk_hstring *)  /* no 'norz' variant */\n#define DUK_HOBJECT_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HOBJECT_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HOBJECT_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HBUFFER_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HBUFFER_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hbuffer_refzero,duk_hbuffer *)\n#define DUK_HBUFFER_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hbuffer_refzero,duk_hbuffer *)  /* no 'norz' variant */\n#define DUK_HCOMPFUNC_INCREF(thr,h)            DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HCOMPFUNC_DECREF(thr,h)            DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h)       DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HNATFUNC_INCREF(thr,h)             DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HNATFUNC_DECREF(thr,h)             DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HNATFUNC_DECREF_NORZ(thr,h)        DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HBUFOBJ_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HBUFOBJ_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HBUFOBJ_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#define DUK_HTHREAD_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HTHREAD_DECREF(thr,h)              DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero,duk_hobject *)\n#define DUK_HTHREAD_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_FAST_RAW((thr),(h),duk_hobject_refzero_norz,duk_hobject *)\n#else\n#define DUK_TVAL_INCREF(thr,tv)                DUK_TVAL_INCREF_SLOW((thr),(tv))\n#define DUK_TVAL_DECREF(thr,tv)                DUK_TVAL_DECREF_SLOW((thr),(tv))\n#define DUK_TVAL_DECREF_NORZ(thr,tv)           DUK_TVAL_DECREF_NORZ_SLOW((thr),(tv))\n#define DUK_HEAPHDR_INCREF(thr,h)              DUK_HEAPHDR_INCREF_SLOW((thr),(h))\n#define DUK_HEAPHDR_DECREF(thr,h)              DUK_HEAPHDR_DECREF_SLOW((thr),(h))\n#define DUK_HEAPHDR_DECREF_NORZ(thr,h)         DUK_HEAPHDR_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HSTRING_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HSTRING_DECREF(thr,h)              DUK_HSTRING_DECREF_SLOW((thr),(h))\n#define DUK_HSTRING_DECREF_NORZ(thr,h)         DUK_HSTRING_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HOBJECT_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HOBJECT_DECREF(thr,h)              DUK_HOBJECT_DECREF_SLOW((thr),(h))\n#define DUK_HOBJECT_DECREF_NORZ(thr,h)         DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HBUFFER_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) (h))\n#define DUK_HBUFFER_DECREF(thr,h)              DUK_HBUFFER_DECREF_SLOW((thr),(h))\n#define DUK_HBUFFER_DECREF_NORZ(thr,h)         DUK_HBUFFER_DECREF_NORZ_SLOW((thr),(h))\n#define DUK_HCOMPFUNC_INCREF(thr,h)            DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HCOMPFUNC_DECREF(thr,h)            DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h)       DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HNATFUNC_INCREF(thr,h)             DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HNATFUNC_DECREF(thr,h)             DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HNATFUNC_DECREF_NORZ(thr,h)        DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HBUFOBJ_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HBUFOBJ_DECREF(thr,h)              DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HBUFOB_DECREF_NORZ(thr,h)          DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HTHREAD_INCREF(thr,h)              DUK_HEAPHDR_INCREF((thr),(duk_heaphdr *) &(h)->obj)\n#define DUK_HTHREAD_DECREF(thr,h)              DUK_HOBJECT_DECREF_SLOW((thr),(duk_hobject *) &(h)->obj)\n#define DUK_HTHREAD_DECREF_NORZ(thr,h)         DUK_HOBJECT_DECREF_NORZ_SLOW((thr),(duk_hobject *) &(h)->obj)\n#endif\n\n/* Convenience for some situations; the above macros don't allow NULLs\n * for performance reasons.  Macros cover only actually needed cases.\n */\n#define DUK_HEAPHDR_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HEAPHDR_INCREF((thr), (duk_heaphdr *) (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HEAPHDR_DECREF((thr), (duk_heaphdr *) (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HEAPHDR_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HEAPHDR_DECREF_NORZ((thr), (duk_heaphdr *) (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HOBJECT_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HOBJECT_INCREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HOBJECT_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HOBJECT_DECREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HOBJECT_DECREF_NORZ((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HBUFFER_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HBUFFER_INCREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HBUFFER_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HBUFFER_DECREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HBUFFER_DECREF_NORZ((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HTHREAD_INCREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HTHREAD_INCREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HTHREAD_DECREF_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HTHREAD_DECREF((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n#define DUK_HTHREAD_DECREF_NORZ_ALLOWNULL(thr,h) do { \\\n\t\tif ((h) != NULL) { \\\n\t\t\tDUK_HTHREAD_DECREF_NORZ((thr), (h)); \\\n\t\t} \\\n\t} while (0)\n\n/* Called after one or more DECREF NORZ calls to handle pending side effects.\n * At present DECREF NORZ does freeing inline but doesn't execute finalizers,\n * so these macros check for pending finalizers and execute them.  The FAST\n * variant is performance critical.\n */\n#if defined(DUK_USE_FINALIZER_SUPPORT)\n#define DUK_REFZERO_CHECK_FAST(thr) do { \\\n\t\tduk_refzero_check_fast((thr)); \\\n\t} while (0)\n#define DUK_REFZERO_CHECK_SLOW(thr) do { \\\n\t\tduk_refzero_check_slow((thr)); \\\n\t} while (0)\n#else  /* DUK_USE_FINALIZER_SUPPORT */\n#define DUK_REFZERO_CHECK_FAST(thr) do { } while (0)\n#define DUK_REFZERO_CHECK_SLOW(thr) do { } while (0)\n#endif  /* DUK_USE_FINALIZER_SUPPORT */\n\n/*\n *  Macros to set a duk_tval and update refcount of the target (decref the\n *  old value and incref the new value if necessary).  This is both performance\n *  and footprint critical; any changes made should be measured for size/speed.\n */\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_UNDEFINED(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_UNDEFINED(tv__dst); \\\n\t\tDUK_TVAL_DECREF_NORZ((thr), &tv__tmp); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_UNUSED(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NULL_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NULL(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_BOOLEAN(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NUMBER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NUMBER(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_DOUBLE(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_NAN_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_NAN(tv__dst); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_I48(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_I32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_I32(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#define DUK_TVAL_SET_U32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_U32(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n#else\n#define DUK_TVAL_SET_DOUBLE_CAST_UPDREF(thr,tvptr_dst,newval) \\\n\tDUK_TVAL_SET_DOUBLE_UPDREF((thr), (tvptr_dst), (duk_double_t) (newval))\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0(thr,tvptr_dst,lf_v,lf_fp,lf_flags) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_LIGHTFUNC(tv__dst, (lf_v), (lf_fp), (lf_flags)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_STRING_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_STRING(tv__dst, (newval)); \\\n\t\tDUK_HSTRING_INCREF((thr), (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_OBJECT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_OBJECT(tv__dst, (newval)); \\\n\t\tDUK_HOBJECT_INCREF((thr), (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BUFFER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_BUFFER(tv__dst, (newval)); \\\n\t\tDUK_HBUFFER_INCREF((thr), (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n#define DUK_TVAL_SET_POINTER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; duk_tval tv__tmp; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_POINTER(tv__dst, (newval)); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n/* DUK_TVAL_SET_TVAL_UPDREF() is used a lot in executor, property lookups,\n * etc, so it's very important for performance.  Measure when changing.\n *\n * NOTE: the source and destination duk_tval pointers may be the same, and\n * the macros MUST deal with that correctly.\n */\n\n/* Original idiom used, minimal code size. */\n#define DUK_TVAL_SET_TVAL_UPDREF_ALT0(thr,tvptr_dst,tvptr_src) do { \\\n\t\tduk_tval *tv__dst, *tv__src; duk_tval tv__tmp; \\\n\t\ttv__dst = (tvptr_dst); tv__src = (tvptr_src); \\\n\t\tDUK_TVAL_SET_TVAL(&tv__tmp, tv__dst); \\\n\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\tDUK_TVAL_INCREF((thr), tv__src); \\\n\t\tDUK_TVAL_DECREF((thr), &tv__tmp);  /* side effects */ \\\n\t} while (0)\n\n/* Faster alternative: avoid making a temporary copy of tvptr_dst and use\n * fast incref/decref macros.\n */\n#define DUK_TVAL_SET_TVAL_UPDREF_ALT1(thr,tvptr_dst,tvptr_src) do { \\\n\t\tduk_tval *tv__dst, *tv__src; duk_heaphdr *h__obj; \\\n\t\ttv__dst = (tvptr_dst); tv__src = (tvptr_src); \\\n\t\tDUK_TVAL_INCREF_FAST((thr), tv__src); \\\n\t\tif (DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv__dst)) { \\\n\t\t\th__obj = DUK_TVAL_GET_HEAPHDR(tv__dst); \\\n\t\t\tDUK_ASSERT(h__obj != NULL); \\\n\t\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\t\tDUK_HEAPHDR_DECREF_FAST((thr), h__obj);  /* side effects */ \\\n\t\t} else { \\\n\t\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\t} \\\n\t} while (0)\n\n/* XXX: no optimized variants yet */\n#define DUK_TVAL_SET_UNDEFINED_UPDREF         DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ    DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ_ALT0\n#define DUK_TVAL_SET_UNUSED_UPDREF            DUK_TVAL_SET_UNUSED_UPDREF_ALT0\n#define DUK_TVAL_SET_NULL_UPDREF              DUK_TVAL_SET_NULL_UPDREF_ALT0\n#define DUK_TVAL_SET_BOOLEAN_UPDREF           DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_UPDREF            DUK_TVAL_SET_NUMBER_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF    DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0\n#define DUK_TVAL_SET_DOUBLE_UPDREF            DUK_TVAL_SET_DOUBLE_UPDREF_ALT0\n#define DUK_TVAL_SET_NAN_UPDREF               DUK_TVAL_SET_NAN_UPDREF_ALT0\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_I48_UPDREF_ALT0\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_I32_UPDREF_ALT0\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_U32_UPDREF_ALT0\n#else\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF  /* XXX: fast int-to-double */\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_FASTINT_UPDREF           DUK_TVAL_SET_I48_UPDREF  /* convenience */\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF         DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0\n#define DUK_TVAL_SET_STRING_UPDREF            DUK_TVAL_SET_STRING_UPDREF_ALT0\n#define DUK_TVAL_SET_OBJECT_UPDREF            DUK_TVAL_SET_OBJECT_UPDREF_ALT0\n#define DUK_TVAL_SET_BUFFER_UPDREF            DUK_TVAL_SET_BUFFER_UPDREF_ALT0\n#define DUK_TVAL_SET_POINTER_UPDREF           DUK_TVAL_SET_POINTER_UPDREF_ALT0\n\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\n/* Optimized for speed. */\n#define DUK_TVAL_SET_TVAL_UPDREF              DUK_TVAL_SET_TVAL_UPDREF_ALT1\n#define DUK_TVAL_SET_TVAL_UPDREF_FAST         DUK_TVAL_SET_TVAL_UPDREF_ALT1\n#define DUK_TVAL_SET_TVAL_UPDREF_SLOW         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#else\n/* Optimized for size. */\n#define DUK_TVAL_SET_TVAL_UPDREF              DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_FAST         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_SLOW         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#endif\n\n#else  /* DUK_USE_REFERENCE_COUNTING */\n\n#define DUK_TVAL_NEEDS_REFCOUNT_UPDATE(tv)     0\n#define DUK_HEAPHDR_NEEDS_REFCOUNT_UPDATE(h)   0\n\n#define DUK_TVAL_INCREF_FAST(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_FAST(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_NORZ_FAST(thr,v)       do {} while (0) /* nop */\n#define DUK_TVAL_INCREF_SLOW(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_SLOW(thr,v)            do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_NORZ_SLOW(thr,v)       do {} while (0) /* nop */\n#define DUK_TVAL_INCREF(thr,v)                 do {} while (0) /* nop */\n#define DUK_TVAL_DECREF(thr,v)                 do {} while (0) /* nop */\n#define DUK_TVAL_DECREF_NORZ(thr,v)            do {} while (0) /* nop */\n#define DUK_HEAPHDR_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HEAPHDR_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HEAPHDR_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HEAPHDR_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HSTRING_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HSTRING_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HSTRING_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_FAST(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ_FAST(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_SLOW(thr,h)         do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ_SLOW(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n\n#define DUK_HCOMPFUNC_INCREF(thr,h)            do {} while (0) /* nop */\n#define DUK_HCOMPFUNC_DECREF(thr,h)            do {} while (0) /* nop */\n#define DUK_HCOMPFUNC_DECREF_NORZ(thr,h)       do {} while (0) /* nop */\n#define DUK_HNATFUNC_INCREF(thr,h)             do {} while (0) /* nop */\n#define DUK_HNATFUNC_DECREF(thr,h)             do {} while (0) /* nop */\n#define DUK_HNATFUNC_DECREF_NORZ(thr,h)        do {} while (0) /* nop */\n#define DUK_HBUFOBJ_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFOBJ_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HBUFOBJ_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HTHREAD_INCREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HTHREAD_DECREF(thr,h)              do {} while (0) /* nop */\n#define DUK_HTHREAD_DECREF_NORZ(thr,h)         do {} while (0) /* nop */\n#define DUK_HOBJECT_INCREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HOBJECT_DECREF_NORZ_ALLOWNULL(thr,h)  do {} while (0) /* nop */\n#define DUK_HBUFFER_INCREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_ALLOWNULL(thr,h)    do {} while (0) /* nop */\n#define DUK_HBUFFER_DECREF_NORZ_ALLOWNULL(thr,h)  do {} while (0) /* nop */\n\n#define DUK_REFZERO_CHECK_FAST(thr)            do {} while (0) /* nop */\n#define DUK_REFZERO_CHECK_SLOW(thr)            do {} while (0) /* nop */\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_UNDEFINED(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNUSED_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_UNUSED(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NULL_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NULL(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_BOOLEAN(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NUMBER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NUMBER(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_DOUBLE_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_DOUBLE(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_NAN_UPDREF_ALT0(thr,tvptr_dst) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_NAN(tv__dst); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_I48(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_I32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_I32(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#define DUK_TVAL_SET_U32_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_U32(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n#else\n#define DUK_TVAL_SET_DOUBLE_CAST_UPDREF(thr,tvptr_dst,newval) \\\n\tDUK_TVAL_SET_DOUBLE_UPDREF((thr), (tvptr_dst), (duk_double_t) (newval))\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0(thr,tvptr_dst,lf_v,lf_fp,lf_flags) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_LIGHTFUNC(tv__dst, (lf_v), (lf_fp), (lf_flags)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_STRING_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_STRING(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_OBJECT_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_OBJECT(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BUFFER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_BUFFER(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_POINTER_UPDREF_ALT0(thr,tvptr_dst,newval) do { \\\n\t\tduk_tval *tv__dst; tv__dst = (tvptr_dst); \\\n\t\tDUK_TVAL_SET_POINTER(tv__dst, (newval)); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_TVAL_UPDREF_ALT0(thr,tvptr_dst,tvptr_src) do { \\\n\t\tduk_tval *tv__dst, *tv__src; \\\n\t\ttv__dst = (tvptr_dst); tv__src = (tvptr_src); \\\n\t\tDUK_TVAL_SET_TVAL(tv__dst, tv__src); \\\n\t\tDUK_UNREF((thr)); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNDEFINED_UPDREF         DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0\n#define DUK_TVAL_SET_UNDEFINED_UPDREF_NORZ    DUK_TVAL_SET_UNDEFINED_UPDREF_ALT0\n#define DUK_TVAL_SET_UNUSED_UPDREF            DUK_TVAL_SET_UNUSED_UPDREF_ALT0\n#define DUK_TVAL_SET_NULL_UPDREF              DUK_TVAL_SET_NULL_UPDREF_ALT0\n#define DUK_TVAL_SET_BOOLEAN_UPDREF           DUK_TVAL_SET_BOOLEAN_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_UPDREF            DUK_TVAL_SET_NUMBER_UPDREF_ALT0\n#define DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF    DUK_TVAL_SET_NUMBER_CHKFAST_UPDREF_ALT0\n#define DUK_TVAL_SET_DOUBLE_UPDREF            DUK_TVAL_SET_DOUBLE_UPDREF_ALT0\n#define DUK_TVAL_SET_NAN_UPDREF               DUK_TVAL_SET_NAN_UPDREF_ALT0\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_I48_UPDREF_ALT0\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_I32_UPDREF_ALT0\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_U32_UPDREF_ALT0\n#else\n#define DUK_TVAL_SET_I48_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF  /* XXX: fast-int-to-double */\n#define DUK_TVAL_SET_I32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#define DUK_TVAL_SET_U32_UPDREF               DUK_TVAL_SET_DOUBLE_CAST_UPDREF\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_FASTINT_UPDREF           DUK_TVAL_SET_I48_UPDREF  /* convenience */\n#define DUK_TVAL_SET_LIGHTFUNC_UPDREF         DUK_TVAL_SET_LIGHTFUNC_UPDREF_ALT0\n#define DUK_TVAL_SET_STRING_UPDREF            DUK_TVAL_SET_STRING_UPDREF_ALT0\n#define DUK_TVAL_SET_OBJECT_UPDREF            DUK_TVAL_SET_OBJECT_UPDREF_ALT0\n#define DUK_TVAL_SET_BUFFER_UPDREF            DUK_TVAL_SET_BUFFER_UPDREF_ALT0\n#define DUK_TVAL_SET_POINTER_UPDREF           DUK_TVAL_SET_POINTER_UPDREF_ALT0\n\n#define DUK_TVAL_SET_TVAL_UPDREF              DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_FAST         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n#define DUK_TVAL_SET_TVAL_UPDREF_SLOW         DUK_TVAL_SET_TVAL_UPDREF_ALT0\n\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n/*\n *  Some convenience macros that don't have optimized implementations now.\n */\n\n#define DUK_TVAL_SET_TVAL_UPDREF_NORZ(thr,tv_dst,tv_src) do { \\\n\t\tduk_hthread *duk__thr = (thr); \\\n\t\tduk_tval *duk__dst = (tv_dst); \\\n\t\tduk_tval *duk__src = (tv_src); \\\n\t\tDUK_UNREF(duk__thr); \\\n\t\tDUK_TVAL_DECREF_NORZ(thr, duk__dst); \\\n\t\tDUK_TVAL_SET_TVAL(duk__dst, duk__src); \\\n\t\tDUK_TVAL_INCREF(thr, duk__dst); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_U32_UPDREF_NORZ(thr,tv_dst,val) do { \\\n\t\tduk_hthread *duk__thr = (thr); \\\n\t\tduk_tval *duk__dst = (tv_dst); \\\n\t\tduk_uint32_t duk__val = (duk_uint32_t) (val); \\\n\t\tDUK_UNREF(duk__thr); \\\n\t\tDUK_TVAL_DECREF_NORZ(thr, duk__dst); \\\n\t\tDUK_TVAL_SET_U32(duk__dst, duk__val); \\\n\t} while (0)\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_REFERENCE_COUNTING)\n#if defined(DUK_USE_FINALIZER_SUPPORT)\nDUK_INTERNAL_DECL void duk_refzero_check_slow(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_refzero_check_fast(duk_hthread *thr);\n#endif\nDUK_INTERNAL_DECL void duk_heaphdr_refcount_finalize_norz(duk_heap *heap, duk_heaphdr *hdr);\nDUK_INTERNAL_DECL void duk_hobject_refcount_finalize_norz(duk_heap *heap, duk_hobject *h);\n#if 0  /* Not needed: fast path handles inline; slow path uses duk_heaphdr_decref() which is needed anyway. */\nDUK_INTERNAL_DECL void duk_hstring_decref(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_hstring_decref_norz(duk_hthread *thr, duk_hstring *h);\nDUK_INTERNAL_DECL void duk_hbuffer_decref(duk_hthread *thr, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_hbuffer_decref_norz(duk_hthread *thr, duk_hbuffer *h);\nDUK_INTERNAL_DECL void duk_hobject_decref(duk_hthread *thr, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_hobject_decref_norz(duk_hthread *thr, duk_hobject *h);\n#endif\nDUK_INTERNAL_DECL void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_refzero_norz(duk_hthread *thr, duk_heaphdr *h);\n#if defined(DUK_USE_FAST_REFCOUNT_DEFAULT)\nDUK_INTERNAL_DECL void duk_hstring_refzero(duk_hthread *thr, duk_hstring *h);  /* no 'norz' variant */\nDUK_INTERNAL_DECL void duk_hbuffer_refzero(duk_hthread *thr, duk_hbuffer *h);  /* no 'norz' variant */\nDUK_INTERNAL_DECL void duk_hobject_refzero(duk_hthread *thr, duk_hobject *h);\nDUK_INTERNAL_DECL void duk_hobject_refzero_norz(duk_hthread *thr, duk_hobject *h);\n#else\nDUK_INTERNAL_DECL void duk_tval_incref(duk_tval *tv);\nDUK_INTERNAL_DECL void duk_tval_decref(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL void duk_tval_decref_norz(duk_hthread *thr, duk_tval *tv);\nDUK_INTERNAL_DECL void duk_heaphdr_incref(duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h);\nDUK_INTERNAL_DECL void duk_heaphdr_decref_norz(duk_hthread *thr, duk_heaphdr *h);\n#endif\n#else  /* DUK_USE_REFERENCE_COUNTING */\n/* no refcounting */\n#endif  /* DUK_USE_REFERENCE_COUNTING */\n\n#endif  /* DUK_REFCOUNT_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_regexp.h",
    "content": "/*\n *  Regular expression structs, constants, and bytecode defines.\n */\n\n#if !defined(DUK_REGEXP_H_INCLUDED)\n#define DUK_REGEXP_H_INCLUDED\n\n/* maximum bytecode copies for {n,m} quantifiers */\n#define DUK_RE_MAX_ATOM_COPIES             1000\n\n/* regexp compilation limits */\n#define DUK_RE_COMPILE_TOKEN_LIMIT         100000000L   /* 1e8 */\n\n/* regexp execution limits */\n#define DUK_RE_EXECUTE_STEPS_LIMIT         1000000000L  /* 1e9 */\n\n/* regexp opcodes */\n#define DUK_REOP_MATCH                     1\n#define DUK_REOP_CHAR                      2\n#define DUK_REOP_PERIOD                    3\n#define DUK_REOP_RANGES                    4\n#define DUK_REOP_INVRANGES                 5\n#define DUK_REOP_JUMP                      6\n#define DUK_REOP_SPLIT1                    7\n#define DUK_REOP_SPLIT2                    8\n#define DUK_REOP_SQMINIMAL                 9\n#define DUK_REOP_SQGREEDY                  10\n#define DUK_REOP_SAVE                      11\n#define DUK_REOP_WIPERANGE                 12\n#define DUK_REOP_LOOKPOS                   13\n#define DUK_REOP_LOOKNEG                   14\n#define DUK_REOP_BACKREFERENCE             15\n#define DUK_REOP_ASSERT_START              16\n#define DUK_REOP_ASSERT_END                17\n#define DUK_REOP_ASSERT_WORD_BOUNDARY      18\n#define DUK_REOP_ASSERT_NOT_WORD_BOUNDARY  19\n\n/* flags */\n#define DUK_RE_FLAG_GLOBAL                 (1U << 0)\n#define DUK_RE_FLAG_IGNORE_CASE            (1U << 1)\n#define DUK_RE_FLAG_MULTILINE              (1U << 2)\n\nstruct duk_re_matcher_ctx {\n\tduk_hthread *thr;\n\n\tduk_uint32_t re_flags;\n\tconst duk_uint8_t *input;\n\tconst duk_uint8_t *input_end;\n\tconst duk_uint8_t *bytecode;\n\tconst duk_uint8_t *bytecode_end;\n\tconst duk_uint8_t **saved;  /* allocated from valstack (fixed buffer) */\n\tduk_uint32_t nsaved;\n\tduk_uint32_t recursion_depth;\n\tduk_uint32_t recursion_limit;\n\tduk_uint32_t steps_count;\n\tduk_uint32_t steps_limit;\n};\n\nstruct duk_re_compiler_ctx {\n\tduk_hthread *thr;\n\n\tduk_uint32_t re_flags;\n\tduk_lexer_ctx lex;\n\tduk_re_token curr_token;\n\tduk_bufwriter_ctx bw;\n\tduk_uint32_t captures;  /* highest capture number emitted so far (used as: ++captures) */\n\tduk_uint32_t highest_backref;\n\tduk_uint32_t recursion_depth;\n\tduk_uint32_t recursion_limit;\n\tduk_uint32_t nranges;  /* internal temporary value, used for char classes */\n};\n\n/*\n *  Prototypes\n */\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL_DECL void duk_regexp_compile(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_regexp_create_instance(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_regexp_match(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_regexp_match_force_global(duk_hthread *thr);  /* hacky helper for String.prototype.split() */\n#endif\n\n#endif  /* DUK_REGEXP_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_regexp_compiler.c",
    "content": "/*\n *  Regexp compilation.\n *\n *  See doc/regexp.rst for a discussion of the compilation approach and\n *  current limitations.\n *\n *  Regexp bytecode assumes jumps can be expressed with signed 32-bit\n *  integers.  Consequently the bytecode size must not exceed 0x7fffffffL.\n *  The implementation casts duk_size_t (buffer size) to duk_(u)int32_t\n *  in many places.  Although this could be changed, the bytecode format\n *  limit would still prevent regexps exceeding the signed 32-bit limit\n *  from working.\n *\n *  XXX: The implementation does not prevent bytecode from exceeding the\n *  maximum supported size.  This could be done by limiting the maximum\n *  input string size (assuming an upper bound can be computed for number\n *  of bytecode bytes emitted per input byte) or checking buffer maximum\n *  size when emitting bytecode (slower).\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Helper macros\n */\n\n#define DUK__RE_INITIAL_BUFSIZE 64\n\n#define DUK__RE_BUFLEN(re_ctx) \\\n\tDUK_BW_GET_SIZE(re_ctx->thr, &re_ctx->bw)\n\n/*\n *  Disjunction struct: result of parsing a disjunction\n */\n\ntypedef struct {\n\t/* Number of characters that the atom matches (e.g. 3 for 'abc'),\n\t * -1 if atom is complex and number of matched characters either\n\t * varies or is not known.\n\t */\n\tduk_int32_t charlen;\n\n#if 0\n\t/* These are not needed to implement quantifier capture handling,\n\t * but might be needed at some point.\n\t */\n\n\t/* re_ctx->captures at start and end of atom parsing.\n\t * Since 'captures' indicates highest capture number emitted\n\t * so far in a DUK_REOP_SAVE, the captures numbers saved by\n\t * the atom are: ]start_captures,end_captures].\n\t */\n\tduk_uint32_t start_captures;\n\tduk_uint32_t end_captures;\n#endif\n} duk__re_disjunction_info;\n\n/*\n *  Encoding helpers\n *\n *  Some of the typing is bytecode based, e.g. slice sizes are unsigned 32-bit\n *  even though the buffer operations will use duk_size_t.\n */\n\n/* XXX: the insert helpers should ensure that the bytecode result is not\n * larger than expected (or at least assert for it).  Many things in the\n * bytecode, like skip offsets, won't work correctly if the bytecode is\n * larger than say 2G.\n */\n\nDUK_LOCAL duk_uint32_t duk__encode_i32(duk_int32_t x) {\n\tif (x < 0) {\n\t\treturn ((duk_uint32_t) (-x)) * 2 + 1;\n\t} else {\n\t\treturn ((duk_uint32_t) x) * 2;\n\t}\n}\n\n/* XXX: return type should probably be duk_size_t, or explicit checks are needed for\n * maximum size.\n */\nDUK_LOCAL duk_uint32_t duk__insert_u32(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_uint32_t x) {\n\tduk_uint8_t buf[DUK_UNICODE_MAX_XUTF8_LENGTH];\n\tduk_small_int_t len;\n\n\tlen = duk_unicode_encode_xutf8((duk_ucodepoint_t) x, buf);\n\tDUK_ASSERT(len >= 0);\n\tDUK_BW_INSERT_ENSURE_BYTES(re_ctx->thr, &re_ctx->bw, offset, buf, (duk_size_t) len);\n\treturn (duk_uint32_t) len;\n}\n\nDUK_LOCAL void duk__append_u32(duk_re_compiler_ctx *re_ctx, duk_uint32_t x) {\n\tDUK_BW_WRITE_ENSURE_XUTF8(re_ctx->thr, &re_ctx->bw, x);\n}\n\nDUK_LOCAL void duk__append_7bit(duk_re_compiler_ctx *re_ctx, duk_uint32_t x) {\n#if defined(DUK_USE_PREFER_SIZE)\n\tduk__append_u32(re_ctx, x);\n#else\n\tDUK_ASSERT(x <= 0x7fU);\n\tDUK_BW_WRITE_ENSURE_U8(re_ctx->thr, &re_ctx->bw, (duk_uint8_t) x);\n#endif\n}\n\n#if 0\nDUK_LOCAL void duk__append_2bytes(duk_re_compiler_ctx *re_ctx, duk_uint8_t x, duk_uint8_t y) {\n\tDUK_BW_WRITE_ENSURE_U8_2(re_ctx->thr, &re_ctx->bw, x, y);\n}\n#endif\n\nDUK_LOCAL duk_uint32_t duk__insert_i32(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_int32_t x) {\n\treturn duk__insert_u32(re_ctx, offset, duk__encode_i32(x));\n}\n\nDUK_LOCAL void duk__append_reop(duk_re_compiler_ctx *re_ctx, duk_uint32_t reop) {\n\tDUK_ASSERT(reop <= 0x7fU);\n\t(void) duk__append_7bit(re_ctx, reop);\n}\n\n#if 0  /* unused */\nDUK_LOCAL void duk__append_i32(duk_re_compiler_ctx *re_ctx, duk_int32_t x) {\n\tduk__append_u32(re_ctx, duk__encode_i32(x));\n}\n#endif\n\n/* special helper for emitting u16 lists (used for character ranges for built-in char classes) */\nDUK_LOCAL void duk__append_u16_list(duk_re_compiler_ctx *re_ctx, const duk_uint16_t *values, duk_uint32_t count) {\n\t/* Call sites don't need the result length so it's not accumulated. */\n\twhile (count-- > 0) {\n\t\tduk__append_u32(re_ctx, (duk_uint32_t) (*values++));\n\t}\n}\n\nDUK_LOCAL void duk__insert_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_uint32_t data_offset, duk_uint32_t data_length) {\n\tDUK_BW_INSERT_ENSURE_SLICE(re_ctx->thr, &re_ctx->bw, offset, data_offset, data_length);\n}\n\nDUK_LOCAL void duk__append_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t data_offset, duk_uint32_t data_length) {\n\tDUK_BW_WRITE_ENSURE_SLICE(re_ctx->thr, &re_ctx->bw, data_offset, data_length);\n}\n\nDUK_LOCAL void duk__remove_slice(duk_re_compiler_ctx *re_ctx, duk_uint32_t data_offset, duk_uint32_t data_length) {\n\tDUK_BW_REMOVE_ENSURE_SLICE(re_ctx->thr, &re_ctx->bw, data_offset, data_length);\n}\n\n/*\n *  Insert a jump offset at 'offset' to complete an instruction\n *  (the jump offset is always the last component of an instruction).\n *  The 'skip' argument must be computed relative to 'offset',\n *  -without- taking into account the skip field being inserted.\n *\n *       ... A B C ins X Y Z ...   (ins may be a JUMP, SPLIT1/SPLIT2, etc)\n *   =>  ... A B C ins SKIP X Y Z\n *\n *  Computing the final (adjusted) skip value, which is relative to the\n *  first byte of the next instruction, is a bit tricky because of the\n *  variable length UTF-8 encoding.  See doc/regexp.rst for discussion.\n */\nDUK_LOCAL duk_uint32_t duk__insert_jump_offset(duk_re_compiler_ctx *re_ctx, duk_uint32_t offset, duk_int32_t skip) {\n#if 0\n\t/* Iterative solution. */\n\tif (skip < 0) {\n\t\tduk_small_int_t len;\n\t\t/* two encoding attempts suffices */\n\t\tlen = duk_unicode_get_xutf8_length((duk_codepoint_t) duk__encode_i32(skip));\n\t\tlen = duk_unicode_get_xutf8_length((duk_codepoint_t) duk__encode_i32(skip - (duk_int32_t) len));\n\t\tDUK_ASSERT(duk_unicode_get_xutf8_length(duk__encode_i32(skip - (duk_int32_t) len)) == len);  /* no change */\n\t\tskip -= (duk_int32_t) len;\n\t}\n#endif\n\n#if defined(DUK_USE_PREFER_SIZE)\n\t/* Closed form solution, this produces smallest code.\n\t * See re_neg_jump_offset (closed2).\n\t */\n\tif (skip < 0) {\n\t\tskip--;\n\t\tif (skip < -0x3fL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x3ffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x7fffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0xfffffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x1ffffffL) {\n\t\t\tskip--;\n\t\t}\n\t\tif (skip < -0x3fffffffL) {\n\t\t\tskip--;\n\t\t}\n\t}\n#else  /* DUK_USE_PREFER_SIZE */\n\t/* Closed form solution, this produces fastest code.\n\t * See re_neg_jump_offset (closed1).\n\t */\n\tif (skip < 0) {\n\t\tif (skip >= -0x3eL) {\n\t\t\tskip -= 1;\n\t\t} else if (skip >= -0x3fdL) {\n\t\t\tskip -= 2;\n\t\t} else if (skip >= -0x7ffcL) {\n\t\t\tskip -= 3;\n\t\t} else if (skip >= -0xffffbL) {\n\t\t\tskip -= 4;\n\t\t} else if (skip >= -0x1fffffaL) {\n\t\t\tskip -= 5;\n\t\t} else if (skip >= -0x3ffffff9L) {\n\t\t\tskip -= 6;\n\t\t} else {\n\t\t\tskip -= 7;\n\t\t}\n\t}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n\treturn duk__insert_i32(re_ctx, offset, skip);\n}\n\nDUK_LOCAL duk_uint32_t duk__append_jump_offset(duk_re_compiler_ctx *re_ctx, duk_int32_t skip) {\n\treturn (duk_uint32_t) duk__insert_jump_offset(re_ctx, (duk_uint32_t) DUK__RE_BUFLEN(re_ctx), skip);\n}\n\n/*\n *  duk_re_range_callback for generating character class ranges.\n *\n *  When ignoreCase is false, the range is simply emitted as is.  We don't,\n *  for instance, eliminate duplicates or overlapping ranges in a character\n *  class.\n *\n *  When ignoreCase is true but the 'direct' flag is set, the caller knows\n *  that the range canonicalizes to itself for case insensitive matching,\n *  so the range is emitted as is.  This is mainly useful for built-in ranges\n *  like \\W.\n *\n *  Otherwise, when ignoreCase is true, the range needs to be normalized\n *  through canonicalization.  Unfortunately a canonicalized version of a\n *  continuous range is not necessarily continuous (e.g. [x-{] is continuous\n *  but [X-{] is not).  As a result, a single input range may expand to a lot\n *  of output ranges.  The current algorithm creates the canonicalized ranges\n *  footprint efficiently at the cost of compile time execution time; see\n *  doc/regexp.rst for discussion, and some more details below.\n *\n *  Note that the ctx->nranges is a context-wide temporary value.  This is OK\n *  because there cannot be multiple character classes being parsed\n *  simultaneously.\n *\n *  More detail on canonicalization:\n *\n *  Conceptually, a range is canonicalized by scanning the entire range,\n *  normalizing each codepoint by converting it to uppercase, and generating\n *  a set of result ranges.\n *\n *  Ideally a minimal set of output ranges would be emitted by merging all\n *  possible ranges even if they're emitted out of sequence.  Because the\n *  input string is also case normalized during matching, some codepoints\n *  never occur at runtime; these \"don't care\" codepoints can be included or\n *  excluded from ranges when merging/optimizing ranges.\n *\n *  The current algorithm does not do optimal range merging.  Rather, output\n *  codepoints are generated in sequence, and when the output codepoints are\n *  continuous (CP, CP+1, CP+2, ...), they are merged locally into as large a\n *  range as possible.  A small canonicalization bitmap is used to reduce\n *  actual codepoint canonicalizations which are quite slow at present.  The\n *  bitmap provides a \"codepoint block is continuous with respect to\n *  canonicalization\" for N-codepoint blocks.  This allows blocks to be\n *  skipped quickly.\n *\n *  There are a number of shortcomings and future work here:\n *\n *    - Individual codepoint normalizations are slow because they involve\n *      walking bit-packed rules without a lookup index.\n *\n *    - The conceptual algorithm needs to canonicalize every codepoint in the\n *      input range to figure out the output range(s).  Even with the small\n *      canonicalization bitmap the algorithm runs quite slowly for worst case\n *      inputs.  There are many data structure alternatives to improve this.\n *\n *    - While the current algorithm generates maximal output ranges when the\n *      output codepoints are emitted linearly, output ranges are not sorted or\n *      merged otherwise.  In the worst case a lot of ranges are emitted when\n *      most of the ranges could be merged.  In this process one could take\n *      advantage of \"don't care\" codepoints, which are never matched against at\n *      runtime due to canonicalization of input codepoints before comparison,\n *      to merge otherwise discontinuous output ranges.\n *\n *    - The runtime data structure is just a linear list of ranges to match\n *      against.  This can be quite slow if there are a lot of output ranges.\n *      There are various ways to make matching against the ranges faster,\n *      e.g. sorting the ranges and using a binary search; skip lists; tree\n *      based representations; full or approximate codepoint bitmaps, etc.\n *\n *    - Only BMP is supported, codepoints above BMP are assumed to canonicalize\n *      to themselves.  For now this is one place where we don't want to\n *      support chars outside the BMP, because the exhaustive search would be\n *      massively larger.  It would be possible to support non-BMP with a\n *      different algorithm, or perhaps doing case normalization only at match\n *      time.\n */\n\nDUK_LOCAL void duk__regexp_emit_range(duk_re_compiler_ctx *re_ctx, duk_codepoint_t r1, duk_codepoint_t r2) {\n\tDUK_ASSERT(r2 >= r1);\n\tduk__append_u32(re_ctx, (duk_uint32_t) r1);\n\tduk__append_u32(re_ctx, (duk_uint32_t) r2);\n\tre_ctx->nranges++;\n}\n\n#if defined(DUK_USE_REGEXP_CANON_BITMAP)\n/* Find next canonicalization discontinuity (conservative estimate) starting\n * from 'start', not exceeding 'end'.  If continuity is fine up to 'end'\n * inclusive, returns end.  Minimum possible return value is start.\n */\nDUK_LOCAL duk_codepoint_t duk__re_canon_next_discontinuity(duk_codepoint_t start, duk_codepoint_t end) {\n\tduk_uint_t start_blk;\n\tduk_uint_t end_blk;\n\tduk_uint_t blk;\n\tduk_uint_t offset;\n\tduk_uint8_t mask;\n\n\t/* Inclusive block range. */\n\tDUK_ASSERT(start >= 0);\n\tDUK_ASSERT(end >= 0);\n\tDUK_ASSERT(end >= start);\n\tstart_blk = (duk_uint_t) (start >> DUK_CANON_BITMAP_BLKSHIFT);\n\tend_blk = (duk_uint_t) (end >> DUK_CANON_BITMAP_BLKSHIFT);\n\n\tfor (blk = start_blk; blk <= end_blk; blk++) {\n\t\toffset = blk >> 3;\n\t\tmask = 1U << (blk & 0x07);\n\t\tif (offset >= sizeof(duk_unicode_re_canon_bitmap)) {\n\t\t\t/* Reached non-BMP range which is assumed continuous. */\n\t\t\treturn end;\n\t\t}\n\t\tDUK_ASSERT(offset < sizeof(duk_unicode_re_canon_bitmap));\n\t\tif ((duk_unicode_re_canon_bitmap[offset] & mask) == 0) {\n\t\t\t/* Block is discontinuous, continuity is guaranteed\n\t\t\t * only up to end of previous block (+1 for exclusive\n\t\t\t * return value => start of current block).  Start\n\t\t\t * block requires special handling.\n\t\t\t */\n\t\t\tif (blk > start_blk) {\n\t\t\t\treturn (duk_codepoint_t) (blk << DUK_CANON_BITMAP_BLKSHIFT);\n\t\t\t} else {\n\t\t\t\treturn start;\n\t\t\t}\n\t\t}\n\t}\n\tDUK_ASSERT(blk == end_blk + 1);  /* Reached end block which is continuous. */\n\treturn end;\n}\n#else  /* DUK_USE_REGEXP_CANON_BITMAP */\nDUK_LOCAL duk_codepoint_t duk__re_canon_next_discontinuity(duk_codepoint_t start, duk_codepoint_t end) {\n\tDUK_ASSERT(start >= 0);\n\tDUK_ASSERT(end >= 0);\n\tDUK_ASSERT(end >= start);\n\tif (start >= 0x10000) {\n\t\t/* Even without the bitmap, treat non-BMP as continuous. */\n\t\treturn end;\n\t}\n\treturn start;\n}\n#endif  /* DUK_USE_REGEXP_CANON_BITMAP */\n\nDUK_LOCAL void duk__regexp_generate_ranges(void *userdata, duk_codepoint_t r1, duk_codepoint_t r2, duk_bool_t direct) {\n\tduk_re_compiler_ctx *re_ctx = (duk_re_compiler_ctx *) userdata;\n\tduk_codepoint_t r_start;\n\tduk_codepoint_t r_end;\n\tduk_codepoint_t i;\n\tduk_codepoint_t t;\n\tduk_codepoint_t r_disc;\n\n\tDUK_DD(DUK_DDPRINT(\"duk__regexp_generate_ranges(): re_ctx=%p, range=[%ld,%ld] direct=%ld\",\n\t                   (void *) re_ctx, (long) r1, (long) r2, (long) direct));\n\n\tDUK_ASSERT(r2 >= r1);  /* SyntaxError for out of order range. */\n\n\tif (direct || (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) == 0) {\n\t\tDUK_DD(DUK_DDPRINT(\"direct or not case sensitive, emit range: [%ld,%ld]\", (long) r1, (long) r2));\n\t\tduk__regexp_emit_range(re_ctx, r1, r2);\n\t\treturn;\n\t}\n\n\tDUK_DD(DUK_DDPRINT(\"case sensitive, process range: [%ld,%ld]\", (long) r1, (long) r2));\n\n\tr_start = duk_unicode_re_canonicalize_char(re_ctx->thr, r1);\n\tr_end = r_start;\n\n\tfor (i = r1 + 1; i <= r2;) {\n\t\t/* Input codepoint space processed up to i-1, and\n\t\t * current range in r_{start,end} is up-to-date\n\t\t * (inclusive) and may either break or continue.\n\t\t */\n\t\tr_disc = duk__re_canon_next_discontinuity(i, r2);\n\t\tDUK_ASSERT(r_disc >= i);\n\t\tDUK_ASSERT(r_disc <= r2);\n\n\t\tr_end += r_disc - i;  /* May be zero. */\n\t\tt = duk_unicode_re_canonicalize_char(re_ctx->thr, r_disc);\n\t\tif (t == r_end + 1) {\n\t\t\t/* Not actually a discontinuity, continue range\n\t\t\t * to r_disc and recheck.\n\t\t\t */\n\t\t\tr_end = t;\n\t\t} else {\n\t\t\tduk__regexp_emit_range(re_ctx, r_start, r_end);\n\t\t\tr_start = t;\n\t\t\tr_end = t;\n\t\t}\n\t\ti = r_disc + 1;  /* Guarantees progress. */\n\t}\n\tduk__regexp_emit_range(re_ctx, r_start, r_end);\n\n#if 0  /* Exhaustive search, very slow. */\n\tr_start = duk_unicode_re_canonicalize_char(re_ctx->thr, r1);\n\tr_end = r_start;\n\tfor (i = r1 + 1; i <= r2; i++) {\n\t\tt = duk_unicode_re_canonicalize_char(re_ctx->thr, i);\n\t\tif (t == r_end + 1) {\n\t\t\tr_end = t;\n\t\t} else {\n\t\t\tDUK_DD(DUK_DDPRINT(\"canonicalized, emit range: [%ld,%ld]\", (long) r_start, (long) r_end));\n\t\t\tduk__append_u32(re_ctx, (duk_uint32_t) r_start);\n\t\t\tduk__append_u32(re_ctx, (duk_uint32_t) r_end);\n\t\t\tre_ctx->nranges++;\n\t\t\tr_start = t;\n\t\t\tr_end = t;\n\t\t}\n\t}\n\tDUK_DD(DUK_DDPRINT(\"canonicalized, emit range: [%ld,%ld]\", (long) r_start, (long) r_end));\n\tduk__append_u32(re_ctx, (duk_uint32_t) r_start);\n\tduk__append_u32(re_ctx, (duk_uint32_t) r_end);\n\tre_ctx->nranges++;\n#endif\n}\n\n/*\n *  Parse regexp Disjunction.  Most of regexp compilation happens here.\n *\n *  Handles Disjunction, Alternative, and Term productions directly without\n *  recursion.  The only constructs requiring recursion are positive/negative\n *  lookaheads, capturing parentheses, and non-capturing parentheses.\n *\n *  The function determines whether the entire disjunction is a 'simple atom'\n *  (see doc/regexp.rst discussion on 'simple quantifiers') and if so,\n *  returns the atom character length which is needed by the caller to keep\n *  track of its own atom character length.  A disjunction with more than one\n *  alternative is never considered a simple atom (although in some cases\n *  that might be the case).\n *\n *  Return value: simple atom character length or < 0 if not a simple atom.\n *  Appends the bytecode for the disjunction matcher to the end of the temp\n *  buffer.\n *\n *  Regexp top level structure is:\n *\n *    Disjunction = Term*\n *                | Term* | Disjunction\n *\n *    Term = Assertion\n *         | Atom\n *         | Atom Quantifier\n *\n *  An empty Term sequence is a valid disjunction alternative (e.g. /|||c||/).\n *\n *  Notes:\n *\n *    * Tracking of the 'simple-ness' of the current atom vs. the entire\n *      disjunction are separate matters.  For instance, the disjunction\n *      may be complex, but individual atoms may be simple.  Furthermore,\n *      simple quantifiers are used whenever possible, even if the\n *      disjunction as a whole is complex.\n *\n *    * The estimate of whether an atom is simple is conservative now,\n *      and it would be possible to expand it.  For instance, captures\n *      cause the disjunction to be marked complex, even though captures\n *      -can- be handled by simple quantifiers with some minor modifications.\n *\n *    * Disjunction 'tainting' as 'complex' is handled at the end of the\n *      main for loop collectively for atoms.  Assertions, quantifiers,\n *      and '|' tokens need to taint the result manually if necessary.\n *      Assertions cannot add to result char length, only atoms (and\n *      quantifiers) can; currently quantifiers will taint the result\n *      as complex though.\n */\n\nDUK_LOCAL const duk_uint16_t * const duk__re_range_lookup1[3] = {\n\tduk_unicode_re_ranges_digit,\n\tduk_unicode_re_ranges_white,\n\tduk_unicode_re_ranges_wordchar\n};\nDUK_LOCAL const duk_uint8_t duk__re_range_lookup2[3] = {\n\tsizeof(duk_unicode_re_ranges_digit) / (2 * sizeof(duk_uint16_t)),\n\tsizeof(duk_unicode_re_ranges_white) / (2 * sizeof(duk_uint16_t)),\n\tsizeof(duk_unicode_re_ranges_wordchar) / (2 * sizeof(duk_uint16_t))\n};\n\nDUK_LOCAL void duk__append_range_atom_matcher(duk_re_compiler_ctx *re_ctx, duk_small_uint_t re_op, const duk_uint16_t *ranges, duk_small_uint_t count) {\n#if 0\n\tDUK_ASSERT(re_op <= 0x7fUL);\n\tDUK_ASSERT(count <= 0x7fUL);\n\tduk__append_2bytes(re_ctx, (duk_uint8_t) re_op, (duk_uint8_t) count);\n#endif\n\tduk__append_reop(re_ctx, re_op);\n\tduk__append_7bit(re_ctx, count);\n\tduk__append_u16_list(re_ctx, ranges, count * 2);\n}\n\nDUK_LOCAL void duk__parse_disjunction(duk_re_compiler_ctx *re_ctx, duk_bool_t expect_eof, duk__re_disjunction_info *out_atom_info) {\n\tduk_int32_t atom_start_offset = -1;                   /* negative -> no atom matched on previous round */\n\tduk_int32_t atom_char_length = 0;                     /* negative -> complex atom */\n\tduk_uint32_t atom_start_captures = re_ctx->captures;  /* value of re_ctx->captures at start of atom */\n\tduk_int32_t unpatched_disjunction_split = -1;\n\tduk_int32_t unpatched_disjunction_jump = -1;\n\tduk_uint32_t entry_offset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);\n\tduk_int32_t res_charlen = 0;  /* -1 if disjunction is complex, char length if simple */\n\tduk__re_disjunction_info tmp_disj;\n\n\tDUK_ASSERT(out_atom_info != NULL);\n\n\tduk_native_stack_check(re_ctx->thr);\n\tif (re_ctx->recursion_depth >= re_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_COMPILER_RECURSION_LIMIT);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\tre_ctx->recursion_depth++;\n\n#if 0\n\tout_atom_info->start_captures = re_ctx->captures;\n#endif\n\n\tfor (;;) {\n\t\t/* atom_char_length, atom_start_offset, atom_start_offset reflect the\n\t\t * atom matched on the previous loop.  If a quantifier is encountered\n\t\t * on this loop, these are needed to handle the quantifier correctly.\n\t\t * new_atom_char_length etc are for the atom parsed on this round;\n\t\t * they're written to atom_char_length etc at the end of the round.\n\t\t */\n\t\tduk_int32_t new_atom_char_length;   /* char length of the atom parsed in this loop */\n\t\tduk_int32_t new_atom_start_offset;  /* bytecode start offset of the atom parsed in this loop\n\t\t                                     * (allows quantifiers to copy the atom bytecode)\n\t\t                                     */\n\t\tduk_uint32_t new_atom_start_captures;  /* re_ctx->captures at the start of the atom parsed in this loop */\n\n\t\tduk_lexer_parse_re_token(&re_ctx->lex, &re_ctx->curr_token);\n\n\t\tDUK_DD(DUK_DDPRINT(\"re token: %ld (num=%ld, char=%c)\",\n\t\t                   (long) re_ctx->curr_token.t,\n\t\t                   (long) re_ctx->curr_token.num,\n\t\t                   (re_ctx->curr_token.num >= 0x20 && re_ctx->curr_token.num <= 0x7e) ?\n\t\t                   (int) re_ctx->curr_token.num : (int) '?'));\n\n\t\t/* set by atom case clauses */\n\t\tnew_atom_start_offset = -1;\n\t\tnew_atom_char_length = -1;\n\t\tnew_atom_start_captures = re_ctx->captures;\n\n\t\tswitch (re_ctx->curr_token.t) {\n\t\tcase DUK_RETOK_DISJUNCTION: {\n\t\t\t/*\n\t\t\t *  The handling here is a bit tricky.  If a previous '|' has been processed,\n\t\t\t *  we have a pending split1 and a pending jump (for a previous match).  These\n\t\t\t *  need to be back-patched carefully.  See docs for a detailed example.\n\t\t\t */\n\n\t\t\t/* patch pending jump and split */\n\t\t\tif (unpatched_disjunction_jump >= 0) {\n\t\t\t\tduk_uint32_t offset;\n\n\t\t\t\tDUK_ASSERT(unpatched_disjunction_split >= 0);\n\t\t\t\toffset = (duk_uint32_t) unpatched_disjunction_jump;\n\t\t\t\toffset += duk__insert_jump_offset(re_ctx,\n\t\t\t\t                                  offset,\n\t\t\t\t                                  (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - offset));\n\t\t\t\t/* offset is now target of the pending split (right after jump) */\n\t\t\t\tduk__insert_jump_offset(re_ctx,\n\t\t\t\t                        (duk_uint32_t) unpatched_disjunction_split,\n\t\t\t\t                        (duk_int32_t) offset - unpatched_disjunction_split);\n\t\t\t}\n\n\t\t\t/* add a new pending split to the beginning of the entire disjunction */\n\t\t\t(void) duk__insert_u32(re_ctx,\n\t\t\t                       entry_offset,\n\t\t\t                       DUK_REOP_SPLIT1);   /* prefer direct execution */\n\t\t\tunpatched_disjunction_split = (duk_int32_t) (entry_offset + 1);   /* +1 for opcode */\n\n\t\t\t/* add a new pending match jump for latest finished alternative */\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_JUMP);\n\t\t\tunpatched_disjunction_jump = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\n\t\t\t/* 'taint' result as complex */\n\t\t\tres_charlen = -1;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_QUANTIFIER: {\n\t\t\tif (atom_start_offset < 0) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_INVALID_QUANTIFIER_NO_ATOM);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tif (re_ctx->curr_token.qmin > re_ctx->curr_token.qmax) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_INVALID_QUANTIFIER_VALUES);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tif (atom_char_length >= 0) {\n\t\t\t\t/*\n\t\t\t\t *  Simple atom\n\t\t\t\t *\n\t\t\t\t *  If atom_char_length is zero, we'll have unbounded execution time for e.g.\n\t\t\t\t *  /()*x/.exec('x').  We can't just skip the match because it might have some\n\t\t\t\t *  side effects (for instance, if we allowed captures in simple atoms, the\n\t\t\t\t *  capture needs to happen).  The simple solution below is to force the\n\t\t\t\t *  quantifier to match at most once, since the additional matches have no effect.\n\t\t\t\t *\n\t\t\t\t *  With a simple atom there can be no capture groups, so no captures need\n\t\t\t\t *  to be reset.\n\t\t\t\t */\n\t\t\t\tduk_int32_t atom_code_length;\n\t\t\t\tduk_uint32_t offset;\n\t\t\t\tduk_uint32_t qmin, qmax;\n\n\t\t\t\tqmin = re_ctx->curr_token.qmin;\n\t\t\t\tqmax = re_ctx->curr_token.qmax;\n\t\t\t\tif (atom_char_length == 0) {\n\t\t\t\t\t/* qmin and qmax will be 0 or 1 */\n\t\t\t\t\tif (qmin > 1) {\n\t\t\t\t\t\tqmin = 1;\n\t\t\t\t\t}\n\t\t\t\t\tif (qmax > 1) {\n\t\t\t\t\t\tqmax = 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_MATCH);   /* complete 'sub atom' */\n\t\t\t\tatom_code_length = (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (duk_size_t) atom_start_offset);\n\n\t\t\t\toffset = (duk_uint32_t) atom_start_offset;\n\t\t\t\tif (re_ctx->curr_token.greedy) {\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, DUK_REOP_SQGREEDY);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmin);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmax);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, (duk_uint32_t) atom_char_length);\n\t\t\t\t\toffset += duk__insert_jump_offset(re_ctx, offset, atom_code_length);\n\t\t\t\t} else {\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, DUK_REOP_SQMINIMAL);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmin);\n\t\t\t\t\toffset += duk__insert_u32(re_ctx, offset, qmax);\n\t\t\t\t\toffset += duk__insert_jump_offset(re_ctx, offset, atom_code_length);\n\t\t\t\t}\n\t\t\t\tDUK_UNREF(offset);  /* silence scan-build warning */\n\t\t\t} else {\n\t\t\t\t/*\n\t\t\t\t *  Complex atom\n\t\t\t\t *\n\t\t\t\t *  The original code is used as a template, and removed at the end\n\t\t\t\t *  (this differs from the handling of simple quantifiers).\n\t\t\t\t *\n\t\t\t\t *  NOTE: there is no current solution for empty atoms in complex\n\t\t\t\t *  quantifiers.  This would need some sort of a 'progress' instruction.\n\t\t\t\t *\n\t\t\t\t *  XXX: impose limit on maximum result size, i.e. atom_code_len * atom_copies?\n\t\t\t\t */\n\t\t\t\tduk_int32_t atom_code_length;\n\t\t\t\tduk_uint32_t atom_copies;\n\t\t\t\tduk_uint32_t tmp_qmin, tmp_qmax;\n\n\t\t\t\t/* pre-check how many atom copies we're willing to make (atom_copies not needed below) */\n\t\t\t\tatom_copies = (re_ctx->curr_token.qmax == DUK_RE_QUANTIFIER_INFINITE) ?\n\t\t\t\t              re_ctx->curr_token.qmin : re_ctx->curr_token.qmax;\n\t\t\t\tif (atom_copies > DUK_RE_MAX_ATOM_COPIES) {\n\t\t\t\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_QUANTIFIER_TOO_MANY_COPIES);\n\t\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t\t}\n\n\t\t\t\t/* wipe the capture range made by the atom (if any) */\n\t\t\t\tDUK_ASSERT(atom_start_captures <= re_ctx->captures);\n\t\t\t\tif (atom_start_captures != re_ctx->captures) {\n\t\t\t\t\tDUK_ASSERT(atom_start_captures < re_ctx->captures);\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"must wipe ]atom_start_captures,re_ctx->captures]: ]%ld,%ld]\",\n\t\t\t\t\t                     (long) atom_start_captures, (long) re_ctx->captures));\n\n\t\t\t\t\t/* insert (DUK_REOP_WIPERANGE, start, count) in reverse order so the order ends up right */\n\t\t\t\t\tduk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, (re_ctx->captures - atom_start_captures) * 2U);\n\t\t\t\t\tduk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, (atom_start_captures + 1) * 2);\n\t\t\t\t\tduk__insert_u32(re_ctx, (duk_uint32_t) atom_start_offset, DUK_REOP_WIPERANGE);\n\t\t\t\t} else {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"no need to wipe captures: atom_start_captures == re_ctx->captures == %ld\",\n\t\t\t\t\t                     (long) atom_start_captures));\n\t\t\t\t}\n\n\t\t\t\tatom_code_length = (duk_int32_t) DUK__RE_BUFLEN(re_ctx) - atom_start_offset;\n\n\t\t\t\t/* insert the required matches (qmin) by copying the atom */\n\t\t\t\ttmp_qmin = re_ctx->curr_token.qmin;\n\t\t\t\ttmp_qmax = re_ctx->curr_token.qmax;\n\t\t\t\twhile (tmp_qmin > 0) {\n\t\t\t\t\tduk__append_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t\t\ttmp_qmin--;\n\t\t\t\t\tif (tmp_qmax != DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\t\ttmp_qmax--;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tDUK_ASSERT(tmp_qmin == 0);\n\n\t\t\t\t/* insert code for matching the remainder - infinite or finite */\n\t\t\t\tif (tmp_qmax == DUK_RE_QUANTIFIER_INFINITE) {\n\t\t\t\t\t/* reuse last emitted atom for remaining 'infinite' quantifier */\n\n\t\t\t\t\tif (re_ctx->curr_token.qmin == 0) {\n\t\t\t\t\t\t/* Special case: original qmin was zero so there is nothing\n\t\t\t\t\t\t * to repeat.  Emit an atom copy but jump over it here.\n\t\t\t\t\t\t */\n\t\t\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_JUMP);\n\t\t\t\t\t\tduk__append_jump_offset(re_ctx, atom_code_length);\n\t\t\t\t\t\tduk__append_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t\t\t}\n\t\t\t\t\tif (re_ctx->curr_token.greedy) {\n\t\t\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_SPLIT2);   /* prefer jump */\n\t\t\t\t\t} else {\n\t\t\t\t\t\tduk__append_reop(re_ctx, DUK_REOP_SPLIT1);   /* prefer direct */\n\t\t\t\t\t}\n\t\t\t\t\tduk__append_jump_offset(re_ctx, -atom_code_length - 1);  /* -1 for opcode */\n\t\t\t\t} else {\n\t\t\t\t\t/*\n\t\t\t\t\t *  The remaining matches are emitted as sequence of SPLITs and atom\n\t\t\t\t\t *  copies; the SPLITs skip the remaining copies and match the sequel.\n\t\t\t\t\t *  This sequence needs to be emitted starting from the last copy\n\t\t\t\t\t *  because the SPLITs are variable length due to the variable length\n\t\t\t\t\t *  skip offset.  This causes a lot of memory copying now.\n\t\t\t\t\t *\n\t\t\t\t\t *  Example structure (greedy, match maximum # atoms):\n\t\t\t\t\t *\n\t\t\t\t\t *      SPLIT1 LSEQ\n\t\t\t\t\t *      (atom)\n\t\t\t\t\t *      SPLIT1 LSEQ    ; <- the byte length of this instruction is needed\n\t\t\t\t\t *      (atom)         ; to encode the above SPLIT1 correctly\n\t\t\t\t\t *      ...\n\t\t\t\t\t *   LSEQ:\n\t\t\t\t\t */\n\t\t\t\t\tduk_uint32_t offset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\t\t\twhile (tmp_qmax > 0) {\n\t\t\t\t\t\tduk__insert_slice(re_ctx, offset, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t\t\t\tif (re_ctx->curr_token.greedy) {\n\t\t\t\t\t\t\tduk__insert_u32(re_ctx, offset, DUK_REOP_SPLIT1);   /* prefer direct */\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tduk__insert_u32(re_ctx, offset, DUK_REOP_SPLIT2);   /* prefer jump */\n\t\t\t\t\t\t}\n\t\t\t\t\t\tduk__insert_jump_offset(re_ctx,\n\t\t\t\t\t\t                        offset + 1,   /* +1 for opcode */\n\t\t\t\t\t\t                        (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (offset + 1)));\n\t\t\t\t\t\ttmp_qmax--;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* remove the original 'template' atom */\n\t\t\t\tduk__remove_slice(re_ctx, (duk_uint32_t) atom_start_offset, (duk_uint32_t) atom_code_length);\n\t\t\t}\n\n\t\t\t/* 'taint' result as complex */\n\t\t\tres_charlen = -1;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_START: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_START);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_END: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_END);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_WORD_BOUNDARY: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_WORD_BOUNDARY);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_NOT_WORD_BOUNDARY: {\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_ASSERT_NOT_WORD_BOUNDARY);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ASSERT_START_POS_LOOKAHEAD:\n\t\tcase DUK_RETOK_ASSERT_START_NEG_LOOKAHEAD: {\n\t\t\tduk_uint32_t offset;\n\t\t\tduk_uint32_t opcode = (re_ctx->curr_token.t == DUK_RETOK_ASSERT_START_POS_LOOKAHEAD) ?\n\t\t\t                      DUK_REOP_LOOKPOS : DUK_REOP_LOOKNEG;\n\n\t\t\toffset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__parse_disjunction(re_ctx, 0, &tmp_disj);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_MATCH);\n\n\t\t\t(void) duk__insert_u32(re_ctx, offset, opcode);\n\t\t\t(void) duk__insert_jump_offset(re_ctx,\n\t\t\t                               offset + 1,   /* +1 for opcode */\n\t\t\t                               (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - (offset + 1)));\n\n\t\t\t/* 'taint' result as complex -- this is conservative,\n\t\t\t * as lookaheads do not backtrack.\n\t\t\t */\n\t\t\tres_charlen = -1;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_PERIOD: {\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_PERIOD);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_CHAR: {\n\t\t\t/* Note: successive characters could be joined into string matches\n\t\t\t * but this is not trivial (consider e.g. '/xyz+/); see docs for\n\t\t\t * more discussion.\n\t\t\t *\n\t\t\t * No support for \\u{H+} yet.  While only BMP Unicode escapes are\n\t\t\t * supported for RegExps at present, 'ch' may still be a non-BMP\n\t\t\t * codepoint if it is decoded straight from source text UTF-8.\n\t\t\t * There's no non-BMP support yet so this is handled simply by\n\t\t\t * matching the non-BMP character (which is custom behavior).\n\t\t\t */\n\t\t\tduk_uint32_t ch;\n\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_CHAR);\n\t\t\tch = re_ctx->curr_token.num;\n\t\t\tif (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) {\n\t\t\t\tch = (duk_uint32_t) duk_unicode_re_canonicalize_char(re_ctx->thr, (duk_codepoint_t) ch);\n\t\t\t}\n\t\t\tduk__append_u32(re_ctx, ch);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_DIGIT:\n\t\tcase DUK_RETOK_ATOM_NOT_DIGIT:\n\t\tcase DUK_RETOK_ATOM_WHITE:\n\t\tcase DUK_RETOK_ATOM_NOT_WHITE:\n\t\tcase DUK_RETOK_ATOM_WORD_CHAR:\n\t\tcase DUK_RETOK_ATOM_NOT_WORD_CHAR: {\n\t\t\tduk_small_uint_t re_op;\n\t\t\tduk_small_uint_t idx;\n\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_DIGIT & 0x01) != 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_WHITE & 0x01) != 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_WORD_CHAR & 0x01) != 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_NOT_DIGIT & 0x01) == 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_NOT_WHITE & 0x01) == 0);\n\t\t\tDUK_ASSERT((DUK_RETOK_ATOM_NOT_WORD_CHAR & 0x01) == 0);\n\t\t\tre_op = (re_ctx->curr_token.t & 0x01) ? DUK_REOP_RANGES : DUK_REOP_INVRANGES;\n\n\t\t\tDUK_ASSERT(DUK_RETOK_ATOM_WHITE == DUK_RETOK_ATOM_DIGIT + 2);\n\t\t\tDUK_ASSERT(DUK_RETOK_ATOM_WORD_CHAR == DUK_RETOK_ATOM_DIGIT + 4);\n\t\t\tidx = (duk_small_uint_t) ((re_ctx->curr_token.t - DUK_RETOK_ATOM_DIGIT) >> 1U);\n\t\t\tDUK_ASSERT(idx <= 2U);  /* Assume continuous token numbers; also checks negative underflow. */\n\n\t\t\tduk__append_range_atom_matcher(re_ctx, re_op, duk__re_range_lookup1[idx], duk__re_range_lookup2[idx]);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_BACKREFERENCE: {\n\t\t\tduk_uint32_t backref = (duk_uint32_t) re_ctx->curr_token.num;\n\t\t\tif (backref > re_ctx->highest_backref) {\n\t\t\t\tre_ctx->highest_backref = backref;\n\t\t\t}\n\t\t\tnew_atom_char_length = -1;   /* mark as complex */\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_BACKREFERENCE);\n\t\t\tduk__append_u32(re_ctx, backref);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_START_CAPTURE_GROUP: {\n\t\t\tduk_uint32_t cap;\n\n\t\t\tnew_atom_char_length = -1;   /* mark as complex (capture handling) */\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tcap = ++re_ctx->captures;\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_SAVE);\n\t\t\tduk__append_u32(re_ctx, cap * 2);\n\t\t\tduk__parse_disjunction(re_ctx, 0, &tmp_disj);  /* retval (sub-atom char length) unused, tainted as complex above */\n\t\t\tduk__append_reop(re_ctx, DUK_REOP_SAVE);\n\t\t\tduk__append_u32(re_ctx, cap * 2 + 1);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_START_NONCAPTURE_GROUP: {\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__parse_disjunction(re_ctx, 0, &tmp_disj);\n\t\t\tnew_atom_char_length = tmp_disj.charlen;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_START_CHARCLASS:\n\t\tcase DUK_RETOK_ATOM_START_CHARCLASS_INVERTED: {\n\t\t\t/*\n\t\t\t *  Range parsing is done with a special lexer function which calls\n\t\t\t *  us for every range parsed.  This is different from how rest of\n\t\t\t *  the parsing works, but avoids a heavy, arbitrary size intermediate\n\t\t\t *  value type to hold the ranges.\n\t\t\t *\n\t\t\t *  Another complication is the handling of character ranges when\n\t\t\t *  case insensitive matching is used (see docs for discussion).\n\t\t\t *  The range handler callback given to the lexer takes care of this\n\t\t\t *  as well.\n\t\t\t *\n\t\t\t *  Note that duplicate ranges are not eliminated when parsing character\n\t\t\t *  classes, so that canonicalization of\n\t\t\t *\n\t\t\t *    [0-9a-fA-Fx-{]\n\t\t\t *\n\t\t\t *  creates the result (note the duplicate ranges):\n\t\t\t *\n\t\t\t *    [0-9A-FA-FX-Z{-{]\n\t\t\t *\n\t\t\t *  where [x-{] is split as a result of canonicalization.  The duplicate\n\t\t\t *  ranges are not a semantics issue: they work correctly.\n\t\t\t */\n\n\t\t\tduk_uint32_t offset;\n\n\t\t\tDUK_DD(DUK_DDPRINT(\"character class\"));\n\n\t\t\t/* insert ranges instruction, range count patched in later */\n\t\t\tnew_atom_char_length = 1;\n\t\t\tnew_atom_start_offset = (duk_int32_t) DUK__RE_BUFLEN(re_ctx);\n\t\t\tduk__append_reop(re_ctx,\n\t\t\t                 (re_ctx->curr_token.t == DUK_RETOK_ATOM_START_CHARCLASS) ?\n\t\t\t                 DUK_REOP_RANGES : DUK_REOP_INVRANGES);\n\t\t\toffset = (duk_uint32_t) DUK__RE_BUFLEN(re_ctx);    /* patch in range count later */\n\n\t\t\t/* parse ranges until character class ends */\n\t\t\tre_ctx->nranges = 0;    /* note: ctx-wide temporary */\n\t\t\tduk_lexer_parse_re_ranges(&re_ctx->lex, duk__regexp_generate_ranges, (void *) re_ctx);\n\n\t\t\t/* insert range count */\n\t\t\tduk__insert_u32(re_ctx, offset, re_ctx->nranges);\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_RETOK_ATOM_END_GROUP: {\n\t\t\tif (expect_eof) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_CLOSING_PAREN);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tgoto done;\n\t\t}\n\t\tcase DUK_RETOK_EOF: {\n\t\t\tif (!expect_eof) {\n\t\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_END_OF_PATTERN);\n\t\t\t\tDUK_WO_NORETURN(return;);\n\t\t\t}\n\t\t\tgoto done;\n\t\t}\n\t\tdefault: {\n\t\t\tDUK_ERROR_SYNTAX(re_ctx->thr, DUK_STR_UNEXPECTED_REGEXP_TOKEN);\n\t\t\tDUK_WO_NORETURN(return;);\n\t\t}\n\t\t}\n\n\t\t/* a complex (new) atom taints the result */\n\t\tif (new_atom_start_offset >= 0) {\n\t\t\tif (new_atom_char_length < 0) {\n\t\t\t\tres_charlen = -1;\n\t\t\t} else if (res_charlen >= 0) {\n\t\t\t\t/* only advance if not tainted */\n\t\t\t\tres_charlen += new_atom_char_length;\n\t\t\t}\n\t\t}\n\n\t\t/* record previous atom info in case next token is a quantifier */\n\t\tatom_start_offset = new_atom_start_offset;\n\t\tatom_char_length = new_atom_char_length;\n\t\tatom_start_captures = new_atom_start_captures;\n\t}\n\n done:\n\n\t/* finish up pending jump and split for last alternative */\n\tif (unpatched_disjunction_jump >= 0) {\n\t\tduk_uint32_t offset;\n\n\t\tDUK_ASSERT(unpatched_disjunction_split >= 0);\n\t\toffset = (duk_uint32_t) unpatched_disjunction_jump;\n\t\toffset += duk__insert_jump_offset(re_ctx,\n\t\t                                  offset,\n\t\t                                  (duk_int32_t) (DUK__RE_BUFLEN(re_ctx) - offset));\n\t\t/* offset is now target of the pending split (right after jump) */\n\t\tduk__insert_jump_offset(re_ctx,\n\t\t                        (duk_uint32_t) unpatched_disjunction_split,\n\t\t                        (duk_int32_t) offset - unpatched_disjunction_split);\n\t}\n\n#if 0\n\tout_atom_info->end_captures = re_ctx->captures;\n#endif\n\tout_atom_info->charlen = res_charlen;\n\tDUK_DDD(DUK_DDDPRINT(\"parse disjunction finished: charlen=%ld\",\n\t                     (long) out_atom_info->charlen));\n\n\tre_ctx->recursion_depth--;\n}\n\n/*\n *  Flags parsing (see E5 Section 15.10.4.1).\n */\n\nDUK_LOCAL duk_uint32_t duk__parse_regexp_flags(duk_hthread *thr, duk_hstring *h) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_uint32_t flags = 0;\n\n\tp = DUK_HSTRING_GET_DATA(h);\n\tp_end = p + DUK_HSTRING_GET_BYTELEN(h);\n\n\t/* Note: can be safely scanned as bytes (undecoded) */\n\n\twhile (p < p_end) {\n\t\tduk_uint8_t c = *p++;\n\t\tswitch (c) {\n\t\tcase (duk_uint8_t) 'g': {\n\t\t\tif (flags & DUK_RE_FLAG_GLOBAL) {\n\t\t\t\tgoto flags_error;\n\t\t\t}\n\t\t\tflags |= DUK_RE_FLAG_GLOBAL;\n\t\t\tbreak;\n\t\t}\n\t\tcase (duk_uint8_t) 'i': {\n\t\t\tif (flags & DUK_RE_FLAG_IGNORE_CASE) {\n\t\t\t\tgoto flags_error;\n\t\t\t}\n\t\t\tflags |= DUK_RE_FLAG_IGNORE_CASE;\n\t\t\tbreak;\n\t\t}\n\t\tcase (duk_uint8_t) 'm': {\n\t\t\tif (flags & DUK_RE_FLAG_MULTILINE) {\n\t\t\t\tgoto flags_error;\n\t\t\t}\n\t\t\tflags |= DUK_RE_FLAG_MULTILINE;\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tgoto flags_error;\n\t\t}\n\t\t}\n\t}\n\n\treturn flags;\n\n flags_error:\n\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_REGEXP_FLAGS);\n\tDUK_WO_NORETURN(return 0U;);\n}\n\n/*\n *  Create escaped RegExp source (E5 Section 15.10.3).\n *\n *  The current approach is to special case the empty RegExp\n *  ('' -> '(?:)') and otherwise replace unescaped '/' characters\n *  with '\\/' regardless of where they occur in the regexp.\n *\n *  Note that normalization does not seem to be necessary for\n *  RegExp literals (e.g. '/foo/') because to be acceptable as\n *  a RegExp literal, the text between forward slashes must\n *  already match the escaping requirements (e.g. must not contain\n *  unescaped forward slashes or be empty).  Escaping IS needed\n *  for expressions like 'new Regexp(\"...\", \"\")' however.\n *  Currently, we re-escape in either case.\n *\n *  Also note that we process the source here in UTF-8 encoded\n *  form.  This is correct, because any non-ASCII characters are\n *  passed through without change.\n */\n\nDUK_LOCAL void duk__create_escaped_source(duk_hthread *thr, int idx_pattern) {\n\tduk_hstring *h;\n\tconst duk_uint8_t *p;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tduk_uint8_t *q;\n\tduk_size_t i, n;\n\tduk_uint_fast8_t c_prev, c;\n\n\th = duk_known_hstring(thr, idx_pattern);\n\tp = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h);\n\tn = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h);\n\n\tif (n == 0) {\n\t\tduk_push_literal(thr, \"(?:)\");\n\t\treturn;\n\t}\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, n);\n\tq = DUK_BW_GET_PTR(thr, bw);\n\n\tc_prev = (duk_uint_fast8_t) 0;\n\n\tfor (i = 0; i < n; i++) {\n\t\tc = p[i];\n\n\t\tq = DUK_BW_ENSURE_RAW(thr, bw, 2, q);\n\n\t\tif (c == (duk_uint_fast8_t) '/' && c_prev != (duk_uint_fast8_t) '\\\\') {\n\t\t\t/* Unescaped '/' ANYWHERE in the regexp (in disjunction,\n\t\t\t * inside a character class, ...) => same escape works.\n\t\t\t */\n\t\t\t*q++ = DUK_ASC_BACKSLASH;\n\t\t}\n\t\t*q++ = (duk_uint8_t) c;\n\n\t\tc_prev = c;\n\t}\n\n\tDUK_BW_SETPTR_AND_COMPACT(thr, bw, q);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe if input is safe. */\n\n\t/* [ ... escaped_source ] */\n}\n\n/*\n *  Exposed regexp compilation primitive.\n *\n *  Sets up a regexp compilation context, and calls duk__parse_disjunction() to do the\n *  actual parsing.  Handles generation of the compiled regexp header and the\n *  \"boilerplate\" capture of the matching substring (save 0 and 1).  Also does some\n *  global level regexp checks after recursive compilation has finished.\n *\n *  An escaped version of the regexp source, suitable for use as a RegExp instance\n *  'source' property (see E5 Section 15.10.3), is also left on the stack.\n *\n *  Input stack:  [ pattern flags ]\n *  Output stack: [ bytecode escaped_source ]  (both as strings)\n */\n\nDUK_INTERNAL void duk_regexp_compile(duk_hthread *thr) {\n\tduk_re_compiler_ctx re_ctx;\n\tduk_lexer_point lex_point;\n\tduk_hstring *h_pattern;\n\tduk_hstring *h_flags;\n\tduk__re_disjunction_info ign_disj;\n\n\tDUK_ASSERT(thr != NULL);\n\n\t/*\n\t *  Args validation\n\t */\n\n\t/* TypeError if fails */\n\th_pattern = duk_require_hstring_notsymbol(thr, -2);\n\th_flags = duk_require_hstring_notsymbol(thr, -1);\n\n\t/*\n\t *  Create normalized 'source' property (E5 Section 15.10.3).\n\t */\n\n\t/* [ ... pattern flags ] */\n\n\tduk__create_escaped_source(thr, -2);\n\n\t/* [ ... pattern flags escaped_source ] */\n\n\t/*\n\t *  Init compilation context\n\t */\n\n\t/* [ ... pattern flags escaped_source buffer ] */\n\n\tduk_memzero(&re_ctx, sizeof(re_ctx));\n\tDUK_LEXER_INITCTX(&re_ctx.lex);  /* duplicate zeroing, expect for (possible) NULL inits */\n\tre_ctx.thr = thr;\n\tre_ctx.lex.thr = thr;\n\tre_ctx.lex.input = DUK_HSTRING_GET_DATA(h_pattern);\n\tre_ctx.lex.input_length = DUK_HSTRING_GET_BYTELEN(h_pattern);\n\tre_ctx.lex.token_limit = DUK_RE_COMPILE_TOKEN_LIMIT;\n\tre_ctx.recursion_limit = DUK_USE_REGEXP_COMPILER_RECLIMIT;\n\tre_ctx.re_flags = duk__parse_regexp_flags(thr, h_flags);\n\n\tDUK_BW_INIT_PUSHBUF(thr, &re_ctx.bw, DUK__RE_INITIAL_BUFSIZE);\n\n\tDUK_DD(DUK_DDPRINT(\"regexp compiler ctx initialized, flags=0x%08lx, recursion_limit=%ld\",\n\t                   (unsigned long) re_ctx.re_flags, (long) re_ctx.recursion_limit));\n\n\t/*\n\t *  Init lexer\n\t */\n\n\tlex_point.offset = 0;  /* expensive init, just want to fill window */\n\tlex_point.line = 1;\n\tDUK_LEXER_SETPOINT(&re_ctx.lex, &lex_point);\n\n\t/*\n\t *  Compilation\n\t */\n\n\tDUK_DD(DUK_DDPRINT(\"starting regexp compilation\"));\n\n\tduk__append_reop(&re_ctx, DUK_REOP_SAVE);\n\tduk__append_7bit(&re_ctx, 0);\n\tduk__parse_disjunction(&re_ctx, 1 /*expect_eof*/, &ign_disj);\n\tduk__append_reop(&re_ctx, DUK_REOP_SAVE);\n\tduk__append_7bit(&re_ctx, 1);\n\tduk__append_reop(&re_ctx, DUK_REOP_MATCH);\n\n\t/*\n\t *  Check for invalid backreferences; note that it is NOT an error\n\t *  to back-reference a capture group which has not yet been introduced\n\t *  in the pattern (as in /\\1(foo)/); in fact, the backreference will\n\t *  always match!  It IS an error to back-reference a capture group\n\t *  which will never be introduced in the pattern.  Thus, we can check\n\t *  for such references only after parsing is complete.\n\t */\n\n\tif (re_ctx.highest_backref > re_ctx.captures) {\n\t\tDUK_ERROR_SYNTAX(thr, DUK_STR_INVALID_BACKREFS);\n\t\tDUK_WO_NORETURN(return;);\n\t}\n\n\t/*\n\t *  Emit compiled regexp header: flags, ncaptures\n\t *  (insertion order inverted on purpose)\n\t */\n\n\tduk__insert_u32(&re_ctx, 0, (re_ctx.captures + 1) * 2);\n\tduk__insert_u32(&re_ctx, 0, re_ctx.re_flags);\n\n\t/* [ ... pattern flags escaped_source buffer ] */\n\n\tDUK_BW_COMPACT(thr, &re_ctx.bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe because flags is at most 7 bit. */\n\n\t/* [ ... pattern flags escaped_source bytecode ] */\n\n\t/*\n\t *  Finalize stack\n\t */\n\n\tduk_remove(thr, -4);     /* -> [ ... flags escaped_source bytecode ] */\n\tduk_remove(thr, -3);     /* -> [ ... escaped_source bytecode ] */\n\n\tDUK_DD(DUK_DDPRINT(\"regexp compilation successful, bytecode: %!T, escaped source: %!T\",\n\t                   (duk_tval *) duk_get_tval(thr, -1), (duk_tval *) duk_get_tval(thr, -2)));\n}\n\n/*\n *  Create a RegExp instance (E5 Section 15.10.7).\n *\n *  Note: the output stack left by duk_regexp_compile() is directly compatible\n *  with the input here.\n *\n *  Input stack:  [ escaped_source bytecode ]  (both as strings)\n *  Output stack: [ RegExp ]\n */\n\nDUK_INTERNAL void duk_regexp_create_instance(duk_hthread *thr) {\n\tduk_hobject *h;\n\n\t/* [ ... escaped_source bytecode ] */\n\n\tduk_push_object(thr);\n\th = duk_known_hobject(thr, -1);\n\tduk_insert(thr, -3);\n\n\t/* [ ... regexp_object escaped_source bytecode ] */\n\n\tDUK_HOBJECT_SET_CLASS_NUMBER(h, DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, h, thr->builtins[DUK_BIDX_REGEXP_PROTOTYPE]);\n\n\tduk_xdef_prop_stridx_short(thr, -3, DUK_STRIDX_INT_BYTECODE, DUK_PROPDESC_FLAGS_NONE);\n\n\t/* [ ... regexp_object escaped_source ] */\n\n\t/* In ES2015 .source, and the .global, .multiline, etc flags are\n\t * inherited getters.  Store the escaped source as an internal\n\t * property for the getter.\n\t */\n\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_INT_SOURCE, DUK_PROPDESC_FLAGS_NONE);\n\n\t/* [ ... regexp_object ] */\n\n\tduk_push_int(thr, 0);\n\tduk_xdef_prop_stridx_short(thr, -2, DUK_STRIDX_LAST_INDEX, DUK_PROPDESC_FLAGS_W);\n\n\t/* [ ... regexp_object ] */\n}\n\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\n/* regexp support disabled */\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_regexp_executor.c",
    "content": "/*\n *  Regexp executor.\n *\n *  Safety: the ECMAScript executor should prevent user from reading and\n *  replacing regexp bytecode.  Even so, the executor must validate all\n *  memory accesses etc.  When an invalid access is detected (e.g. a 'save'\n *  opcode to invalid, unallocated index) it should fail with an internal\n *  error but not cause a segmentation fault.\n *\n *  Notes:\n *\n *    - Backtrack counts are limited to unsigned 32 bits but should\n *      technically be duk_size_t for strings longer than 4G chars.\n *      This also requires a regexp bytecode change.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Helpers for UTF-8 handling\n *\n *  For bytecode readers the duk_uint32_t and duk_int32_t types are correct\n *  because they're used for more than just codepoints.\n */\n\nDUK_LOCAL duk_uint32_t duk__bc_get_u32(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **pc) {\n\treturn (duk_uint32_t) duk_unicode_decode_xutf8_checked(re_ctx->thr, pc, re_ctx->bytecode, re_ctx->bytecode_end);\n}\n\nDUK_LOCAL duk_int32_t duk__bc_get_i32(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **pc) {\n\tduk_uint32_t t;\n\n\t/* signed integer encoding needed to work with UTF-8 */\n\tt = (duk_uint32_t) duk_unicode_decode_xutf8_checked(re_ctx->thr, pc, re_ctx->bytecode, re_ctx->bytecode_end);\n\tif (t & 1) {\n\t\treturn -((duk_int32_t) (t >> 1));\n\t} else {\n\t\treturn (duk_int32_t) (t >> 1);\n\t}\n}\n\nDUK_LOCAL const duk_uint8_t *duk__utf8_backtrack(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_uint_fast32_t count) {\n\tconst duk_uint8_t *p;\n\n\t/* Note: allow backtracking from p == ptr_end */\n\tp = *ptr;\n\tif (p < ptr_start || p > ptr_end) {\n\t\tgoto fail;\n\t}\n\n\twhile (count > 0) {\n\t\tfor (;;) {\n\t\t\tp--;\n\t\t\tif (p < ptr_start) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tif ((*p & 0xc0) != 0x80) {\n\t\t\t\t/* utf-8 continuation bytes have the form 10xx xxxx */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcount--;\n\t}\n\t*ptr = p;\n\treturn p;\n\n fail:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\nDUK_LOCAL const duk_uint8_t *duk__utf8_advance(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_uint_fast32_t count) {\n\tconst duk_uint8_t *p;\n\n\tp = *ptr;\n\tif (p < ptr_start || p >= ptr_end) {\n\t\tgoto fail;\n\t}\n\n\twhile (count > 0) {\n\t\tfor (;;) {\n\t\t\tp++;\n\n\t\t\t/* Note: if encoding ends by hitting end of input, we don't check that\n\t\t\t * the encoding is valid, we just assume it is.\n\t\t\t */\n\t\t\tif (p >= ptr_end || ((*p & 0xc0) != 0x80)) {\n\t\t\t\t/* utf-8 continuation bytes have the form 10xx xxxx */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tcount--;\n\t}\n\n\t*ptr = p;\n\treturn p;\n\n fail:\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Helpers for dealing with the input string\n */\n\n/* Get a (possibly canonicalized) input character from current sp.  The input\n * itself is never modified, and captures always record non-canonicalized\n * characters even in case-insensitive matching.  Return <0 if out of input.\n */\nDUK_LOCAL duk_codepoint_t duk__inp_get_cp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **sp) {\n\tduk_codepoint_t res;\n\n\tif (*sp >= re_ctx->input_end) {\n\t\treturn -1;\n\t}\n\tres = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(re_ctx->thr, sp, re_ctx->input, re_ctx->input_end);\n\tif (re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) {\n\t\tres = duk_unicode_re_canonicalize_char(re_ctx->thr, res);\n\t}\n\treturn res;\n}\n\nDUK_LOCAL const duk_uint8_t *duk__inp_backtrack(duk_re_matcher_ctx *re_ctx, const duk_uint8_t **sp, duk_uint_fast32_t count) {\n\treturn duk__utf8_backtrack(re_ctx->thr, sp, re_ctx->input, re_ctx->input_end, count);\n}\n\n/* Backtrack utf-8 input and return a (possibly canonicalized) input character. */\nDUK_LOCAL duk_codepoint_t duk__inp_get_prev_cp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t *sp) {\n\t/* note: caller 'sp' is intentionally not updated here */\n\t(void) duk__inp_backtrack(re_ctx, &sp, (duk_uint_fast32_t) 1);\n\treturn duk__inp_get_cp(re_ctx, &sp);\n}\n\n/*\n *  Regexp recursive matching function.\n *\n *  Returns 'sp' on successful match (points to character after last matched one),\n *  NULL otherwise.\n *\n *  The C recursion depth limit check is only performed in this function, this\n *  suffices because the function is present in all true recursion required by\n *  regexp execution.\n */\n\nDUK_LOCAL const duk_uint8_t *duk__match_regexp(duk_re_matcher_ctx *re_ctx, const duk_uint8_t *pc, const duk_uint8_t *sp) {\n\tduk_native_stack_check(re_ctx->thr);\n\tif (re_ctx->recursion_depth >= re_ctx->recursion_limit) {\n\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_EXECUTOR_RECURSION_LIMIT);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n\tre_ctx->recursion_depth++;\n\n\tfor (;;) {\n\t\tduk_small_int_t op;\n\n\t\tif (re_ctx->steps_count >= re_ctx->steps_limit) {\n\t\t\tDUK_ERROR_RANGE(re_ctx->thr, DUK_STR_REGEXP_EXECUTOR_STEP_LIMIT);\n\t\t\tDUK_WO_NORETURN(return NULL;);\n\t\t}\n\t\tre_ctx->steps_count++;\n\n\t\t/* Opcodes are at most 7 bits now so they encode to one byte.  If this\n\t\t * were not the case or 'pc' is invalid here (due to a bug etc) we'll\n\t\t * still fail safely through the switch default case.\n\t\t */\n\t\tDUK_ASSERT(pc[0] <= 0x7fU);\n#if 0\n\t\top = (duk_small_int_t) duk__bc_get_u32(re_ctx, &pc);\n#endif\n\t\top = *pc++;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"match: rec=%ld, steps=%ld, pc (after op)=%ld, sp=%ld, op=%ld\",\n\t\t                     (long) re_ctx->recursion_depth,\n\t\t                     (long) re_ctx->steps_count,\n\t\t                     (long) (pc - re_ctx->bytecode),\n\t\t                     (long) (sp - re_ctx->input),\n\t\t                     (long) op));\n\n\t\tswitch (op) {\n\t\tcase DUK_REOP_MATCH: {\n\t\t\tgoto match;\n\t\t}\n\t\tcase DUK_REOP_CHAR: {\n\t\t\t/*\n\t\t\t *  Byte-based matching would be possible for case-sensitive\n\t\t\t *  matching but not for case-insensitive matching.  So, we\n\t\t\t *  match by decoding the input and bytecode character normally.\n\t\t\t *\n\t\t\t *  Bytecode characters are assumed to be already canonicalized.\n\t\t\t *  Input characters are canonicalized automatically by\n\t\t\t *  duk__inp_get_cp() if necessary.\n\t\t\t *\n\t\t\t *  There is no opcode for matching multiple characters.  The\n\t\t\t *  regexp compiler has trouble joining strings efficiently\n\t\t\t *  during compilation.  See doc/regexp.rst for more discussion.\n\t\t\t */\n\t\t\tduk_codepoint_t c1, c2;\n\n\t\t\tc1 = (duk_codepoint_t) duk__bc_get_u32(re_ctx, &pc);\n\t\t\tDUK_ASSERT(!(re_ctx->re_flags & DUK_RE_FLAG_IGNORE_CASE) ||\n\t\t\t           c1 == duk_unicode_re_canonicalize_char(re_ctx->thr, c1));  /* canonicalized by compiler */\n\t\t\tc2 = duk__inp_get_cp(re_ctx, &sp);\n\t\t\t/* No need to check for c2 < 0 (end of input): because c1 >= 0, it\n\t\t\t * will fail the match below automatically and cause goto fail.\n\t\t\t */\n#if 0\n\t\t\tif (c2 < 0) {\n\t\t\t\tgoto fail;\n\t\t\t}\n#endif\n\t\t\tDUK_ASSERT(c1 >= 0);\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"char match, c1=%ld, c2=%ld\", (long) c1, (long) c2));\n\t\t\tif (c1 != c2) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_PERIOD: {\n\t\t\tduk_codepoint_t c;\n\n\t\t\tc = duk__inp_get_cp(re_ctx, &sp);\n\t\t\tif (c < 0 || duk_unicode_is_line_terminator(c)) {\n\t\t\t\t/* E5 Sections 15.10.2.8, 7.3 */\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_RANGES:\n\t\tcase DUK_REOP_INVRANGES: {\n\t\t\tduk_uint32_t n;\n\t\t\tduk_codepoint_t c;\n\t\t\tduk_small_int_t match;\n\n\t\t\tn = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tc = duk__inp_get_cp(re_ctx, &sp);\n\t\t\tif (c < 0) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\n\t\t\tmatch = 0;\n\t\t\twhile (n) {\n\t\t\t\tduk_codepoint_t r1, r2;\n\t\t\t\tr1 = (duk_codepoint_t) duk__bc_get_u32(re_ctx, &pc);\n\t\t\t\tr2 = (duk_codepoint_t) duk__bc_get_u32(re_ctx, &pc);\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"matching ranges/invranges, n=%ld, r1=%ld, r2=%ld, c=%ld\",\n\t\t\t\t                     (long) n, (long) r1, (long) r2, (long) c));\n\t\t\t\tif (c >= r1 && c <= r2) {\n\t\t\t\t\t/* Note: don't bail out early, we must read all the ranges from\n\t\t\t\t\t * bytecode.  Another option is to skip them efficiently after\n\t\t\t\t\t * breaking out of here.  Prefer smallest code.\n\t\t\t\t\t */\n\t\t\t\t\tmatch = 1;\n\t\t\t\t}\n\t\t\t\tn--;\n\t\t\t}\n\n\t\t\tif (op == DUK_REOP_RANGES) {\n\t\t\t\tif (!match) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(op == DUK_REOP_INVRANGES);\n\t\t\t\tif (match) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_ASSERT_START: {\n\t\t\tduk_codepoint_t c;\n\n\t\t\tif (sp <= re_ctx->input) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!(re_ctx->re_flags & DUK_RE_FLAG_MULTILINE)) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tc = duk__inp_get_prev_cp(re_ctx, sp);\n\t\t\tif (duk_unicode_is_line_terminator(c)) {\n\t\t\t\t/* E5 Sections 15.10.2.8, 7.3 */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_ASSERT_END: {\n\t\t\tduk_codepoint_t c;\n\t\t\tconst duk_uint8_t *tmp_sp;\n\n\t\t\ttmp_sp = sp;\n\t\t\tc = duk__inp_get_cp(re_ctx, &tmp_sp);\n\t\t\tif (c < 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (!(re_ctx->re_flags & DUK_RE_FLAG_MULTILINE)) {\n\t\t\t\tgoto fail;\n\t\t\t}\n\t\t\tif (duk_unicode_is_line_terminator(c)) {\n\t\t\t\t/* E5 Sections 15.10.2.8, 7.3 */\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_ASSERT_WORD_BOUNDARY:\n\t\tcase DUK_REOP_ASSERT_NOT_WORD_BOUNDARY: {\n\t\t\t/*\n\t\t\t *  E5 Section 15.10.2.6.  The previous and current character\n\t\t\t *  should -not- be canonicalized as they are now.  However,\n\t\t\t *  canonicalization does not affect the result of IsWordChar()\n\t\t\t *  (which depends on Unicode characters never canonicalizing\n\t\t\t *  into ASCII characters) so this does not matter.\n\t\t\t */\n\t\t\tduk_small_int_t w1, w2;\n\n\t\t\tif (sp <= re_ctx->input) {\n\t\t\t\tw1 = 0;  /* not a wordchar */\n\t\t\t} else {\n\t\t\t\tduk_codepoint_t c;\n\t\t\t\tc = duk__inp_get_prev_cp(re_ctx, sp);\n\t\t\t\tw1 = duk_unicode_re_is_wordchar(c);\n\t\t\t}\n\t\t\tif (sp >= re_ctx->input_end) {\n\t\t\t\tw2 = 0;  /* not a wordchar */\n\t\t\t} else {\n\t\t\t\tconst duk_uint8_t *tmp_sp = sp;  /* dummy so sp won't get updated */\n\t\t\t\tduk_codepoint_t c;\n\t\t\t\tc = duk__inp_get_cp(re_ctx, &tmp_sp);\n\t\t\t\tw2 = duk_unicode_re_is_wordchar(c);\n\t\t\t}\n\n\t\t\tif (op == DUK_REOP_ASSERT_WORD_BOUNDARY) {\n\t\t\t\tif (w1 == w2) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tDUK_ASSERT(op == DUK_REOP_ASSERT_NOT_WORD_BOUNDARY);\n\t\t\t\tif (w1 != w2) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_JUMP: {\n\t\t\tduk_int32_t skip;\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tpc += skip;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_SPLIT1: {\n\t\t\t/* split1: prefer direct execution (no jump) */\n\t\t\tconst duk_uint8_t *sub_sp;\n\t\t\tduk_int32_t skip;\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\t\t\tpc += skip;\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_SPLIT2: {\n\t\t\t/* split2: prefer jump execution (not direct) */\n\t\t\tconst duk_uint8_t *sub_sp;\n\t\t\tduk_int32_t skip;\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tcase DUK_REOP_SQMINIMAL: {\n\t\t\tduk_uint32_t q, qmin, qmax;\n\t\t\tduk_int32_t skip;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tqmin = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tqmax = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"minimal quantifier, qmin=%lu, qmax=%lu, skip=%ld\",\n\t\t\t                     (unsigned long) qmin, (unsigned long) qmax, (long) skip));\n\n\t\t\tq = 0;\n\t\t\twhile (q <= qmax) {\n\t\t\t\tif (q >= qmin) {\n\t\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\t\t\tif (sub_sp) {\n\t\t\t\t\t\tsp = sub_sp;\n\t\t\t\t\t\tgoto match;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\t\tif (!sub_sp) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tsp = sub_sp;\n\t\t\t\tq++;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_SQGREEDY: {\n\t\t\tduk_uint32_t q, qmin, qmax, atomlen;\n\t\t\tduk_int32_t skip;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tqmin = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tqmax = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tatomlen = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"greedy quantifier, qmin=%lu, qmax=%lu, atomlen=%lu, skip=%ld\",\n\t\t\t                     (unsigned long) qmin, (unsigned long) qmax, (unsigned long) atomlen, (long) skip));\n\n\t\t\tq = 0;\n\t\t\twhile (q < qmax) {\n\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\t\tif (!sub_sp) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tsp = sub_sp;\n\t\t\t\tq++;\n\t\t\t}\n\t\t\twhile (q >= qmin) {\n\t\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\t\tif (sub_sp) {\n\t\t\t\t\tsp = sub_sp;\n\t\t\t\t\tgoto match;\n\t\t\t\t}\n\t\t\t\tif (q == qmin) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t/* Note: if atom were to contain e.g. captures, we would need to\n\t\t\t\t * re-match the atom to get correct captures.  Simply quantifiers\n\t\t\t\t * do not allow captures in their atom now, so this is not an issue.\n\t\t\t\t */\n\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"greedy quantifier, backtrack %ld characters (atomlen)\",\n\t\t\t\t                     (long) atomlen));\n\t\t\t\tsp = duk__inp_backtrack(re_ctx, &sp, (duk_uint_fast32_t) atomlen);\n\t\t\t\tq--;\n\t\t\t}\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_SAVE: {\n\t\t\tduk_uint32_t idx;\n\t\t\tconst duk_uint8_t *old;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tidx = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tif (idx >= re_ctx->nsaved) {\n\t\t\t\t/* idx is unsigned, < 0 check is not necessary */\n\t\t\t\tDUK_D(DUK_DPRINT(\"internal error, regexp save index insane: idx=%ld\", (long) idx));\n\t\t\t\tgoto internal_error;\n\t\t\t}\n\t\t\told = re_ctx->saved[idx];\n\t\t\tre_ctx->saved[idx] = sp;\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\t\t\tre_ctx->saved[idx] = old;\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_WIPERANGE: {\n\t\t\t/* Wipe capture range and save old values for backtracking.\n\t\t\t *\n\t\t\t * XXX: this typically happens with a relatively small idx_count.\n\t\t\t * It might be useful to handle cases where the count is small\n\t\t\t * (say <= 8) by saving the values in stack instead.  This would\n\t\t\t * reduce memory churn and improve performance, at the cost of a\n\t\t\t * slightly higher code footprint.\n\t\t\t */\n\t\t\tduk_uint32_t idx_start, idx_count;\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\t\tduk_uint32_t idx_end, idx;\n#endif\n\t\t\tduk_uint8_t **range_save;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tidx_start = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tidx_count = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"wipe saved range: start=%ld, count=%ld -> [%ld,%ld] (captures [%ld,%ld])\",\n\t\t\t                     (long) idx_start, (long) idx_count,\n\t\t\t                     (long) idx_start, (long) (idx_start + idx_count - 1),\n\t\t\t                     (long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2)));\n\t\t\tif (idx_start + idx_count > re_ctx->nsaved || idx_count == 0) {\n\t\t\t\t/* idx is unsigned, < 0 check is not necessary */\n\t\t\t\tDUK_D(DUK_DPRINT(\"internal error, regexp wipe indices insane: idx_start=%ld, idx_count=%ld\",\n\t\t\t\t                 (long) idx_start, (long) idx_count));\n\t\t\t\tgoto internal_error;\n\t\t\t}\n\t\t\tDUK_ASSERT(idx_count > 0);\n\n\t\t\tduk_require_stack(re_ctx->thr, 1);\n\t\t\trange_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero(re_ctx->thr,\n\t\t\t                                                           sizeof(duk_uint8_t *) * idx_count);\n\t\t\tDUK_ASSERT(range_save != NULL);\n\t\t\tduk_memcpy(range_save, re_ctx->saved + idx_start, sizeof(duk_uint8_t *) * idx_count);\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\t\t\tidx_end = idx_start + idx_count;\n\t\t\tfor (idx = idx_start; idx < idx_end; idx++) {\n\t\t\t\tre_ctx->saved[idx] = NULL;\n\t\t\t}\n#else\n\t\t\tduk_memzero((void *) (re_ctx->saved + idx_start), sizeof(duk_uint8_t *) * idx_count);\n#endif\n\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\t/* match: keep wiped/resaved values */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"match: keep wiped/resaved values [%ld,%ld] (captures [%ld,%ld])\",\n\t\t\t\t                     (long) idx_start, (long) (idx_start + idx_count - 1),\n\t\t\t                             (long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2)));\n\t\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\n\t\t\t/* fail: restore saves */\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"fail: restore wiped/resaved values [%ld,%ld] (captures [%ld,%ld])\",\n\t\t\t                     (long) idx_start, (long) (idx_start + idx_count - 1),\n\t\t\t                     (long) (idx_start / 2), (long) ((idx_start + idx_count - 1) / 2)));\n\t\t\tduk_memcpy((void *) (re_ctx->saved + idx_start),\n\t\t\t           (const void *) range_save,\n\t\t\t           sizeof(duk_uint8_t *) * idx_count);\n\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_LOOKPOS:\n\t\tcase DUK_REOP_LOOKNEG: {\n\t\t\t/*\n\t\t\t *  Needs a save of multiple saved[] entries depending on what range\n\t\t\t *  may be overwritten.  Because the regexp parser does no such analysis,\n\t\t\t *  we currently save the entire saved array here.  Lookaheads are thus\n\t\t\t *  a bit expensive.  Note that the saved array is not needed for just\n\t\t\t *  the lookahead sub-match, but for the matching of the entire sequel.\n\t\t\t *\n\t\t\t *  The temporary save buffer is pushed on to the valstack to handle\n\t\t\t *  errors correctly.  Each lookahead causes a C recursion and pushes\n\t\t\t *  more stuff on the value stack.  If the C recursion limit is less\n\t\t\t *  than the value stack slack, there is no need to check the stack.\n\t\t\t *  We do so regardless, just in case.\n\t\t\t */\n\n\t\t\tduk_int32_t skip;\n\t\t\tduk_uint8_t **full_save;\n\t\t\tconst duk_uint8_t *sub_sp;\n\n\t\t\tDUK_ASSERT(re_ctx->nsaved > 0);\n\n\t\t\tduk_require_stack(re_ctx->thr, 1);\n\t\t\tfull_save = (duk_uint8_t **) duk_push_fixed_buffer_nozero(re_ctx->thr,\n\t\t\t                                                          sizeof(duk_uint8_t *) * re_ctx->nsaved);\n\t\t\tDUK_ASSERT(full_save != NULL);\n\t\t\tduk_memcpy(full_save, re_ctx->saved, sizeof(duk_uint8_t *) * re_ctx->nsaved);\n\n\t\t\tskip = duk__bc_get_i32(re_ctx, &pc);\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc, sp);\n\t\t\tif (op == DUK_REOP_LOOKPOS) {\n\t\t\t\tif (!sub_sp) {\n\t\t\t\t\tgoto lookahead_fail;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (sub_sp) {\n\t\t\t\t\tgoto lookahead_fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tsub_sp = duk__match_regexp(re_ctx, pc + skip, sp);\n\t\t\tif (sub_sp) {\n\t\t\t\t/* match: keep saves */\n\t\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\t\tsp = sub_sp;\n\t\t\t\tgoto match;\n\t\t\t}\n\n\t\t\t/* fall through */\n\n\t\t lookahead_fail:\n\t\t\t/* fail: restore saves */\n\t\t\tduk_memcpy((void *) re_ctx->saved,\n\t\t\t           (const void *) full_save,\n\t\t\t           sizeof(duk_uint8_t *) * re_ctx->nsaved);\n\t\t\tduk_pop_unsafe(re_ctx->thr);\n\t\t\tgoto fail;\n\t\t}\n\t\tcase DUK_REOP_BACKREFERENCE: {\n\t\t\t/*\n\t\t\t *  Byte matching for back-references would be OK in case-\n\t\t\t *  sensitive matching.  In case-insensitive matching we need\n\t\t\t *  to canonicalize characters, so back-reference matching needs\n\t\t\t *  to be done with codepoints instead.  So, we just decode\n\t\t\t *  everything normally here, too.\n\t\t\t *\n\t\t\t *  Note: back-reference index which is 0 or higher than\n\t\t\t *  NCapturingParens (= number of capturing parens in the\n\t\t\t *  -entire- regexp) is a compile time error.  However, a\n\t\t\t *  backreference referring to a valid capture which has\n\t\t\t *  not matched anything always succeeds!  See E5 Section\n\t\t\t *  15.10.2.9, step 5, sub-step 3.\n\t\t\t */\n\t\t\tduk_uint32_t idx;\n\t\t\tconst duk_uint8_t *p;\n\n\t\t\tidx = duk__bc_get_u32(re_ctx, &pc);\n\t\t\tidx = idx << 1;  /* backref n -> saved indices [n*2, n*2+1] */\n\t\t\tif (idx < 2 || idx + 1 >= re_ctx->nsaved) {\n\t\t\t\t/* regexp compiler should catch these */\n\t\t\t\tDUK_D(DUK_DPRINT(\"internal error, backreference index insane\"));\n\t\t\t\tgoto internal_error;\n\t\t\t}\n\t\t\tif (!re_ctx->saved[idx] || !re_ctx->saved[idx+1]) {\n\t\t\t\t/* capture is 'undefined', always matches! */\n\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"backreference: saved[%ld,%ld] not complete, always match\",\n\t\t\t\t                     (long) idx, (long) (idx + 1)));\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"backreference: match saved[%ld,%ld]\", (long) idx, (long) (idx + 1)));\n\n\t\t\tp = re_ctx->saved[idx];\n\t\t\twhile (p < re_ctx->saved[idx+1]) {\n\t\t\t\tduk_codepoint_t c1, c2;\n\n\t\t\t\t/* Note: not necessary to check p against re_ctx->input_end:\n\t\t\t\t * the memory access is checked by duk__inp_get_cp(), while\n\t\t\t\t * valid compiled regexps cannot write a saved[] entry\n\t\t\t\t * which points to outside the string.\n\t\t\t\t */\n\t\t\t\tc1 = duk__inp_get_cp(re_ctx, &p);\n\t\t\t\tDUK_ASSERT(c1 >= 0);\n\t\t\t\tc2 = duk__inp_get_cp(re_ctx, &sp);\n\t\t\t\t/* No need for an explicit c2 < 0 check: because c1 >= 0,\n\t\t\t\t * the comparison will always fail if c2 < 0.\n\t\t\t\t */\n#if 0\n\t\t\t\tif (c2 < 0) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n#endif\n\t\t\t\tif (c1 != c2) {\n\t\t\t\t\tgoto fail;\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tDUK_D(DUK_DPRINT(\"internal error, regexp opcode error: %ld\", (long) op));\n\t\t\tgoto internal_error;\n\t\t}\n\t\t}\n\t}\n\n match:\n\tre_ctx->recursion_depth--;\n\treturn sp;\n\n fail:\n\tre_ctx->recursion_depth--;\n\treturn NULL;\n\n internal_error:\n\tDUK_ERROR_INTERNAL(re_ctx->thr);\n\tDUK_WO_NORETURN(return NULL;);\n}\n\n/*\n *  Exposed matcher function which provides the semantics of RegExp.prototype.exec().\n *\n *  RegExp.prototype.test() has the same semantics as exec() but does not return the\n *  result object (which contains the matching string and capture groups).  Currently\n *  there is no separate test() helper, so a temporary result object is created and\n *  discarded if test() is needed.  This is intentional, to save code space.\n *\n *  Input stack:  [ ... re_obj input ]\n *  Output stack: [ ... result ]\n */\n\nDUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_global) {\n\tduk_re_matcher_ctx re_ctx;\n\tduk_hobject *h_regexp;\n\tduk_hstring *h_bytecode;\n\tduk_hstring *h_input;\n\tduk_uint8_t *p_buf;\n\tconst duk_uint8_t *pc;\n\tconst duk_uint8_t *sp;\n\tduk_small_int_t match = 0;\n\tduk_small_int_t global;\n\tduk_uint_fast32_t i;\n\tdouble d;\n\tduk_uint32_t char_offset;\n\n\tDUK_ASSERT(thr != NULL);\n\n\tDUK_DD(DUK_DDPRINT(\"regexp match: regexp=%!T, input=%!T\",\n\t                   (duk_tval *) duk_get_tval(thr, -2),\n\t                   (duk_tval *) duk_get_tval(thr, -1)));\n\n\t/*\n\t *  Regexp instance check, bytecode check, input coercion.\n\t *\n\t *  See E5 Section 15.10.6.\n\t */\n\n\t/* TypeError if wrong; class check, see E5 Section 15.10.6 */\n\th_regexp = duk_require_hobject_with_class(thr, -2, DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_ASSERT(h_regexp != NULL);\n\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_regexp) == DUK_HOBJECT_CLASS_REGEXP);\n\tDUK_UNREF(h_regexp);\n\n\th_input = duk_to_hstring(thr, -1);\n\tDUK_ASSERT(h_input != NULL);\n\n\tduk_xget_owndataprop_stridx_short(thr, -2, DUK_STRIDX_INT_BYTECODE);  /* [ ... re_obj input ] -> [ ... re_obj input bc ] */\n\th_bytecode = duk_require_hstring(thr, -1);  /* no regexp instance should exist without a non-configurable bytecode property */\n\tDUK_ASSERT(h_bytecode != NULL);\n\n\t/*\n\t *  Basic context initialization.\n\t *\n\t *  Some init values are read from the bytecode header\n\t *  whose format is (UTF-8 codepoints):\n\t *\n\t *    uint   flags\n\t *    uint   nsaved (even, 2n+2 where n = num captures)\n\t */\n\n\t/* [ ... re_obj input bc ] */\n\n\tduk_memzero(&re_ctx, sizeof(re_ctx));\n\n\tre_ctx.thr = thr;\n\tre_ctx.input = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tre_ctx.input_end = re_ctx.input + DUK_HSTRING_GET_BYTELEN(h_input);\n\tre_ctx.bytecode = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_bytecode);\n\tre_ctx.bytecode_end = re_ctx.bytecode + DUK_HSTRING_GET_BYTELEN(h_bytecode);\n\tre_ctx.saved = NULL;\n\tre_ctx.recursion_limit = DUK_USE_REGEXP_EXECUTOR_RECLIMIT;\n\tre_ctx.steps_limit = DUK_RE_EXECUTE_STEPS_LIMIT;\n\n\t/* read header */\n\tpc = re_ctx.bytecode;\n\tre_ctx.re_flags = duk__bc_get_u32(&re_ctx, &pc);\n\tre_ctx.nsaved = duk__bc_get_u32(&re_ctx, &pc);\n\tre_ctx.bytecode = pc;\n\n\tDUK_ASSERT(DUK_RE_FLAG_GLOBAL < 0x10000UL);  /* must fit into duk_small_int_t */\n\tglobal = (duk_small_int_t) (force_global | (duk_small_int_t) (re_ctx.re_flags & DUK_RE_FLAG_GLOBAL));\n\n\tDUK_ASSERT(re_ctx.nsaved >= 2);\n\tDUK_ASSERT((re_ctx.nsaved % 2) == 0);\n\n\tp_buf = (duk_uint8_t *) duk_push_fixed_buffer(thr, sizeof(duk_uint8_t *) * re_ctx.nsaved);  /* rely on zeroing */\n\tDUK_UNREF(p_buf);\n\tre_ctx.saved = (const duk_uint8_t **) duk_get_buffer(thr, -1, NULL);\n\tDUK_ASSERT(re_ctx.saved != NULL);\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n#if defined(DUK_USE_EXPLICIT_NULL_INIT)\n\tfor (i = 0; i < re_ctx.nsaved; i++) {\n\t\tre_ctx.saved[i] = (duk_uint8_t *) NULL;\n\t}\n#elif defined(DUK_USE_ZERO_BUFFER_DATA)\n\t/* buffer is automatically zeroed */\n#else\n\tduk_memzero((void *) p_buf, sizeof(duk_uint8_t *) * re_ctx.nsaved);\n#endif\n\n\tDUK_DDD(DUK_DDDPRINT(\"regexp ctx initialized, flags=0x%08lx, nsaved=%ld, recursion_limit=%ld, steps_limit=%ld\",\n\t                     (unsigned long) re_ctx.re_flags, (long) re_ctx.nsaved, (long) re_ctx.recursion_limit,\n\t                     (long) re_ctx.steps_limit));\n\n\t/*\n\t *  Get starting character offset for match, and initialize 'sp' based on it.\n\t *\n\t *  Note: lastIndex is non-configurable so it must be present (we check the\n\t *  internal class of the object above, so we know it is).  User code can set\n\t *  its value to an arbitrary (garbage) value though; E5 requires that lastIndex\n\t *  be coerced to a number before using.  The code below works even if the\n\t *  property is missing: the value will then be coerced to zero.\n\t *\n\t *  Note: lastIndex may be outside Uint32 range even after ToInteger() coercion.\n\t *  For instance, ToInteger(+Infinity) = +Infinity.  We track the match offset\n\t *  as an integer, but pre-check it to be inside the 32-bit range before the loop.\n\t *  If not, the check in E5 Section 15.10.6.2, step 9.a applies.\n\t */\n\n\t/* XXX: lastIndex handling produces a lot of asm */\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n\tduk_get_prop_stridx_short(thr, -4, DUK_STRIDX_LAST_INDEX);  /* -> [ ... re_obj input bc saved_buf lastIndex ] */\n\t(void) duk_to_int(thr, -1);  /* ToInteger(lastIndex) */\n\td = duk_get_number(thr, -1);  /* integer, but may be +/- Infinite, +/- zero (not NaN, though) */\n\tduk_pop_nodecref_unsafe(thr);\n\n\tif (global) {\n\t\tif (d < 0.0 || d > (double) DUK_HSTRING_GET_CHARLEN(h_input)) {\n\t\t\t/* match fail */\n\t\t\tchar_offset = 0;   /* not really necessary */\n\t\t\tDUK_ASSERT(match == 0);\n\t\t\tgoto match_over;\n\t\t}\n\t\tchar_offset = (duk_uint32_t) d;\n\t} else {\n\t\t/* lastIndex must be ignored for non-global regexps, but get the\n\t\t * value for (theoretical) side effects.  No side effects can\n\t\t * really occur, because lastIndex is a normal property and is\n\t\t * always non-configurable for RegExp instances.\n\t\t */\n\t\tchar_offset = (duk_uint32_t) 0;\n\t}\n\n\tDUK_ASSERT(char_offset <= DUK_HSTRING_GET_CHARLEN(h_input));\n\tsp = re_ctx.input + duk_heap_strcache_offset_char2byte(thr, h_input, char_offset);\n\n\t/*\n\t *  Match loop.\n\t *\n\t *  Try matching at different offsets until match found or input exhausted.\n\t */\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n\tDUK_ASSERT(match == 0);\n\n\tfor (;;) {\n\t\t/* char offset in [0, h_input->clen] (both ends inclusive), checked before entry */\n\t\tDUK_ASSERT_DISABLE(char_offset >= 0);\n\t\tDUK_ASSERT(char_offset <= DUK_HSTRING_GET_CHARLEN(h_input));\n\n\t\t/* Note: re_ctx.steps is intentionally not reset, it applies to the entire unanchored match */\n\t\tDUK_ASSERT(re_ctx.recursion_depth == 0);\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"attempt match at char offset %ld; %p [%p,%p]\",\n\t\t                     (long) char_offset, (const void *) sp,\n\t\t                     (const void *) re_ctx.input, (const void *) re_ctx.input_end));\n\n\t\t/*\n\t\t *  Note:\n\t\t *\n\t\t *    - duk__match_regexp() is required not to longjmp() in ordinary \"non-match\"\n\t\t *      conditions; a longjmp() will terminate the entire matching process.\n\t\t *\n\t\t *    - Clearing saved[] is not necessary because backtracking does it\n\t\t *\n\t\t *    - Backtracking also rewinds re_ctx.recursion back to zero, unless an\n\t\t *      internal/limit error occurs (which causes a longjmp())\n\t\t *\n\t\t *    - If we supported anchored matches, we would break out here\n\t\t *      unconditionally; however, ECMAScript regexps don't have anchored\n\t\t *      matches.  It might make sense to implement a fast bail-out if\n\t\t *      the regexp begins with '^' and sp is not 0: currently we'll just\n\t\t *      run through the entire input string, trivially failing the match\n\t\t *      at every non-zero offset.\n\t\t */\n\n\t\tif (duk__match_regexp(&re_ctx, re_ctx.bytecode, sp) != NULL) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"match at offset %ld\", (long) char_offset));\n\t\t\tmatch = 1;\n\t\t\tbreak;\n\t\t}\n\n\t\t/* advance by one character (code point) and one char_offset */\n\t\tchar_offset++;\n\t\tif (char_offset > DUK_HSTRING_GET_CHARLEN(h_input)) {\n\t\t\t/*\n\t\t\t *  Note:\n\t\t\t *\n\t\t\t *    - Intentionally attempt (empty) match at char_offset == k_input->clen\n\t\t\t *\n\t\t\t *    - Negative char_offsets have been eliminated and char_offset is duk_uint32_t\n\t\t\t *      -> no need or use for a negative check\n\t\t\t */\n\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"no match after trying all sp offsets\"));\n\t\t\tbreak;\n\t\t}\n\n\t\t/* avoid calling at end of input, will DUK_ERROR (above check suffices to avoid this) */\n\t\t(void) duk__utf8_advance(thr, &sp, re_ctx.input, re_ctx.input_end, (duk_uint_fast32_t) 1);\n\t}\n\n match_over:\n\n\t/*\n\t *  Matching complete, create result array or return a 'null'.  Update lastIndex\n\t *  if necessary.  See E5 Section 15.10.6.2.\n\t *\n\t *  Because lastIndex is a character (not byte) offset, we need the character\n\t *  length of the match which we conveniently get as a side effect of interning\n\t *  the matching substring (0th index of result array).\n\t *\n\t *  saved[0]         start pointer (~ byte offset) of current match\n\t *  saved[1]         end pointer (~ byte offset) of current match (exclusive)\n\t *  char_offset      start character offset of current match (-> .index of result)\n\t *  char_end_offset  end character offset (computed below)\n\t */\n\n\t/* [ ... re_obj input bc saved_buf ] */\n\n\tif (match) {\n#if defined(DUK_USE_ASSERTIONS)\n\t\tduk_hobject *h_res;\n#endif\n\t\tduk_uint32_t char_end_offset = 0;\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"regexp matches at char_offset %ld\", (long) char_offset));\n\n\t\tDUK_ASSERT(re_ctx.nsaved >= 2);        /* must have start and end */\n\t\tDUK_ASSERT((re_ctx.nsaved % 2) == 0);  /* and even number */\n\n\t\t/* XXX: Array size is known before and (2 * re_ctx.nsaved) but not taken\n\t\t * advantage of now.  The array is not compacted either, as regexp match\n\t\t * objects are usually short lived.\n\t\t */\n\n\t\tduk_push_array(thr);\n\n#if defined(DUK_USE_ASSERTIONS)\n\t\th_res = duk_require_hobject(thr, -1);\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXTENSIBLE(h_res));\n\t\tDUK_ASSERT(DUK_HOBJECT_HAS_EXOTIC_ARRAY(h_res));\n\t\tDUK_ASSERT(DUK_HOBJECT_GET_CLASS_NUMBER(h_res) == DUK_HOBJECT_CLASS_ARRAY);\n#endif\n\n\t\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\t\tduk_push_u32(thr, char_offset);\n\t\tduk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INDEX);\n\n\t\tduk_dup_m4(thr);\n\t\tduk_xdef_prop_stridx_short_wec(thr, -2, DUK_STRIDX_INPUT);\n\n\t\tfor (i = 0; i < re_ctx.nsaved; i += 2) {\n\t\t\t/* Captures which are undefined have NULL pointers and are returned\n\t\t\t * as 'undefined'.  The same is done when saved[] pointers are insane\n\t\t\t * (this should, of course, never happen in practice).\n\t\t\t */\n\t\t\tif (re_ctx.saved[i] && re_ctx.saved[i + 1] && re_ctx.saved[i + 1] >= re_ctx.saved[i]) {\n\t\t\t\tduk_push_lstring(thr,\n\t\t\t\t                 (const char *) re_ctx.saved[i],\n\t\t\t\t                 (duk_size_t) (re_ctx.saved[i+1] - re_ctx.saved[i]));\n\t\t\t\tif (i == 0) {\n\t\t\t\t\t/* Assumes that saved[0] and saved[1] are always\n\t\t\t\t\t * set by regexp bytecode (if not, char_end_offset\n\t\t\t\t\t * will be zero).  Also assumes clen reflects the\n\t\t\t\t\t * correct char length.\n\t\t\t\t\t */\n\t\t\t\t\tchar_end_offset = char_offset + (duk_uint32_t) duk_get_length(thr, -1);  /* add charlen */\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tduk_push_undefined(thr);\n\t\t\t}\n\n\t\t\t/* [ ... re_obj input bc saved_buf res_obj val ] */\n\t\t\tduk_put_prop_index(thr, -2, (duk_uarridx_t) (i / 2));\n\t\t}\n\n\t\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\t\t/* NB: 'length' property is automatically updated by the array setup loop */\n\n\t\tif (global) {\n\t\t\t/* global regexp: lastIndex updated on match */\n\t\t\tduk_push_u32(thr, char_end_offset);\n\t\t\tduk_put_prop_stridx_short(thr, -6, DUK_STRIDX_LAST_INDEX);\n\t\t} else {\n\t\t\t/* non-global regexp: lastIndex never updated on match */\n\t\t\t;\n\t\t}\n\t} else {\n\t\t/*\n\t\t *  No match, E5 Section 15.10.6.2, step 9.a.i - 9.a.ii apply, regardless\n\t\t *  of 'global' flag of the RegExp.  In particular, if lastIndex is invalid\n\t\t *  initially, it is reset to zero.\n\t\t */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"regexp does not match\"));\n\n\t\tduk_push_null(thr);\n\n\t\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\t\tduk_push_int(thr, 0);\n\t\tduk_put_prop_stridx_short(thr, -6, DUK_STRIDX_LAST_INDEX);\n\t}\n\n\t/* [ ... re_obj input bc saved_buf res_obj ] */\n\n\tduk_insert(thr, -5);\n\n\t/* [ ... res_obj re_obj input bc saved_buf ] */\n\n\tduk_pop_n_unsafe(thr, 4);\n\n\t/* [ ... res_obj ] */\n\n\t/* XXX: these last tricks are unnecessary if the function is made\n\t * a genuine native function.\n\t */\n}\n\nDUK_INTERNAL void duk_regexp_match(duk_hthread *thr) {\n\tduk__regexp_match_helper(thr, 0 /*force_global*/);\n}\n\n/* This variant is needed by String.prototype.split(); it needs to perform\n * global-style matching on a cloned RegExp which is potentially non-global.\n */\nDUK_INTERNAL void duk_regexp_match_force_global(duk_hthread *thr) {\n\tduk__regexp_match_helper(thr, 1 /*force_global*/);\n}\n\n#else  /* DUK_USE_REGEXP_SUPPORT */\n\n/* regexp support disabled */\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_replacements.c",
    "content": "/*\n *  Replacements for missing platform functions.\n *\n *  Unlike the originals, fpclassify() and signbit() replacements don't\n *  work on any floating point types, only doubles.  The C typing here\n *  mimics the standard prototypes.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_COMPUTED_NAN)\nDUK_INTERNAL double duk_computed_nan;\n#endif\n\n#if defined(DUK_USE_COMPUTED_INFINITY)\nDUK_INTERNAL double duk_computed_infinity;\n#endif\n\n#if defined(DUK_USE_REPL_FPCLASSIFY)\nDUK_INTERNAL int duk_repl_fpclassify(double x) {\n\tduk_double_union u;\n\tduk_uint_fast16_t expt;\n\tduk_small_int_t mzero;\n\n\tu.d = x;\n\texpt = (duk_uint_fast16_t) (u.us[DUK_DBL_IDX_US0] & 0x7ff0UL);\n\tif (expt > 0x0000UL && expt < 0x7ff0UL) {\n\t\t/* expt values [0x001,0x7fe] = normal */\n\t\treturn DUK_FP_NORMAL;\n\t}\n\n\tmzero = (u.ui[DUK_DBL_IDX_UI1] == 0 && (u.ui[DUK_DBL_IDX_UI0] & 0x000fffffUL) == 0);\n\tif (expt == 0x0000UL) {\n\t\t/* expt 0x000 is zero/subnormal */\n\t\tif (mzero) {\n\t\t\treturn DUK_FP_ZERO;\n\t\t} else {\n\t\t\treturn DUK_FP_SUBNORMAL;\n\t\t}\n\t} else {\n\t\t/* expt 0xfff is infinite/nan */\n\t\tif (mzero) {\n\t\t\treturn DUK_FP_INFINITE;\n\t\t} else {\n\t\t\treturn DUK_FP_NAN;\n\t\t}\n\t}\n}\n#endif\n\n#if defined(DUK_USE_REPL_SIGNBIT)\nDUK_INTERNAL int duk_repl_signbit(double x) {\n\tduk_double_union u;\n\tu.d = x;\n\treturn (int) (u.uc[DUK_DBL_IDX_UC0] & 0x80UL);\n}\n#endif\n\n#if defined(DUK_USE_REPL_ISFINITE)\nDUK_INTERNAL int duk_repl_isfinite(double x) {\n\tint c = DUK_FPCLASSIFY(x);\n\tif (c == DUK_FP_NAN || c == DUK_FP_INFINITE) {\n\t\treturn 0;\n\t} else {\n\t\treturn 1;\n\t}\n}\n#endif\n\n#if defined(DUK_USE_REPL_ISNAN)\nDUK_INTERNAL int duk_repl_isnan(double x) {\n\tint c = DUK_FPCLASSIFY(x);\n\treturn (c == DUK_FP_NAN);\n}\n#endif\n\n#if defined(DUK_USE_REPL_ISINF)\nDUK_INTERNAL int duk_repl_isinf(double x) {\n\tint c = DUK_FPCLASSIFY(x);\n\treturn (c == DUK_FP_INFINITE);\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_replacements.h",
    "content": "#if !defined(DUK_REPLACEMENTS_H_INCLUDED)\n#define DUK_REPLACEMENTS_H_INCLUDED\n\n#if !defined(DUK_SINGLE_FILE)\n#if defined(DUK_USE_COMPUTED_INFINITY)\nDUK_INTERNAL_DECL double duk_computed_infinity;\n#endif\n#if defined(DUK_USE_COMPUTED_NAN)\nDUK_INTERNAL_DECL double duk_computed_nan;\n#endif\n#endif  /* !DUK_SINGLE_FILE */\n\n#if defined(DUK_USE_REPL_FPCLASSIFY)\nDUK_INTERNAL_DECL int duk_repl_fpclassify(double x);\n#endif\n#if defined(DUK_USE_REPL_SIGNBIT)\nDUK_INTERNAL_DECL int duk_repl_signbit(double x);\n#endif\n#if defined(DUK_USE_REPL_ISFINITE)\nDUK_INTERNAL_DECL int duk_repl_isfinite(double x);\n#endif\n#if defined(DUK_USE_REPL_ISNAN)\nDUK_INTERNAL_DECL int duk_repl_isnan(double x);\n#endif\n#if defined(DUK_USE_REPL_ISINF)\nDUK_INTERNAL_DECL int duk_repl_isinf(double x);\n#endif\n\n#endif  /* DUK_REPLACEMENTS_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_selftest.c",
    "content": "/*\n *  Self tests to ensure execution environment is sane.  Intended to catch\n *  compiler/platform problems which cannot be detected at compile time.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_SELF_TESTS)\n\n/*\n *  Unions and structs for self tests\n */\n\ntypedef union {\n\tdouble d;\n\tduk_uint8_t x[8];\n} duk__test_double_union;\n\n/* Self test failed.  Expects a local variable 'error_count' to exist. */\n#define DUK__FAILED(msg)  do { \\\n\t\tDUK_D(DUK_DPRINT(\"self test failed: \" #msg \" at \" DUK_FILE_MACRO \":\" DUK_MACRO_STRINGIFY(DUK_LINE_MACRO))); \\\n\t\terror_count++; \\\n\t} while (0)\n\n#define DUK__DBLUNION_CMP_TRUE(a,b)  do { \\\n\t\tif (duk_memcmp((const void *) (a), (const void *) (b), sizeof(duk__test_double_union)) != 0) { \\\n\t\t\tDUK__FAILED(\"double union compares false (expected true)\"); \\\n\t\t} \\\n\t} while (0)\n\n#define DUK__DBLUNION_CMP_FALSE(a,b)  do { \\\n\t\tif (duk_memcmp((const void *) (a), (const void *) (b), sizeof(duk__test_double_union)) == 0) { \\\n\t\t\tDUK__FAILED(\"double union compares true (expected false)\"); \\\n\t\t} \\\n\t} while (0)\n\ntypedef union {\n\tduk_uint32_t i;\n\tduk_uint8_t x[8];\n} duk__test_u32_union;\n\n#if defined(DUK_USE_INTEGER_LE)\n#define DUK__U32_INIT(u, a, b, c, d) do { \\\n\t\t(u)->x[0] = (d); (u)->x[1] = (c); (u)->x[2] = (b); (u)->x[3] = (a); \\\n\t} while (0)\n#elif defined(DUK_USE_INTEGER_ME)\n#error integer mixed endian not supported now\n#elif defined(DUK_USE_INTEGER_BE)\n#define DUK__U32_INIT(u, a, b, c, d) do { \\\n\t\t(u)->x[0] = (a); (u)->x[1] = (b); (u)->x[2] = (c); (u)->x[3] = (d); \\\n\t} while (0)\n#else\n#error unknown integer endianness\n#endif\n\n#if defined(DUK_USE_DOUBLE_LE)\n#define DUK__DOUBLE_INIT(u, a, b, c, d, e, f, g, h) do { \\\n\t\t(u)->x[0] = (h); (u)->x[1] = (g); (u)->x[2] = (f); (u)->x[3] = (e); \\\n\t\t(u)->x[4] = (d); (u)->x[5] = (c); (u)->x[6] = (b); (u)->x[7] = (a); \\\n\t} while (0)\n#define DUK__DOUBLE_COMPARE(u, a, b, c, d, e, f, g, h) \\\n\t((u)->x[0] == (h) && (u)->x[1] == (g) && (u)->x[2] == (f) && (u)->x[3] == (e) && \\\n\t (u)->x[4] == (d) && (u)->x[5] == (c) && (u)->x[6] == (b) && (u)->x[7] == (a))\n#elif defined(DUK_USE_DOUBLE_ME)\n#define DUK__DOUBLE_INIT(u, a, b, c, d, e, f, g, h) do { \\\n\t\t(u)->x[0] = (d); (u)->x[1] = (c); (u)->x[2] = (b); (u)->x[3] = (a); \\\n\t\t(u)->x[4] = (h); (u)->x[5] = (g); (u)->x[6] = (f); (u)->x[7] = (e); \\\n\t} while (0)\n#define DUK__DOUBLE_COMPARE(u, a, b, c, d, e, f, g, h) \\\n\t((u)->x[0] == (d) && (u)->x[1] == (c) && (u)->x[2] == (b) && (u)->x[3] == (a) && \\\n\t (u)->x[4] == (h) && (u)->x[5] == (g) && (u)->x[6] == (f) && (u)->x[7] == (e))\n#elif defined(DUK_USE_DOUBLE_BE)\n#define DUK__DOUBLE_INIT(u, a, b, c, d, e, f, g, h) do { \\\n\t\t(u)->x[0] = (a); (u)->x[1] = (b); (u)->x[2] = (c); (u)->x[3] = (d); \\\n\t\t(u)->x[4] = (e); (u)->x[5] = (f); (u)->x[6] = (g); (u)->x[7] = (h); \\\n\t} while (0)\n#define DUK__DOUBLE_COMPARE(u, a, b, c, d, e, f, g, h) \\\n\t((u)->x[0] == (a) && (u)->x[1] == (b) && (u)->x[2] == (c) && (u)->x[3] == (d) && \\\n\t (u)->x[4] == (e) && (u)->x[5] == (f) && (u)->x[6] == (g) && (u)->x[7] == (h))\n#else\n#error unknown double endianness\n#endif\n\n/*\n *  Various sanity checks for typing\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_types(void) {\n\tduk_uint_t error_count = 0;\n\n\tif (!(sizeof(duk_int8_t) == 1 &&\n\t      sizeof(duk_uint8_t) == 1 &&\n\t      sizeof(duk_int16_t) == 2 &&\n\t      sizeof(duk_uint16_t) == 2 &&\n\t      sizeof(duk_int32_t) == 4 &&\n\t      sizeof(duk_uint32_t) == 4)) {\n\t\tDUK__FAILED(\"duk_(u)int{8,16,32}_t size\");\n\t}\n#if defined(DUK_USE_64BIT_OPS)\n\tif (!(sizeof(duk_int64_t) == 8 &&\n\t      sizeof(duk_uint64_t) == 8)) {\n\t\tDUK__FAILED(\"duk_(u)int64_t size\");\n\t}\n#endif\n\n\tif (!(sizeof(duk_size_t) >= sizeof(duk_uint_t))) {\n\t\t/* Some internal code now assumes that all duk_uint_t values\n\t\t * can be expressed with a duk_size_t.\n\t\t */\n\t\tDUK__FAILED(\"duk_size_t is smaller than duk_uint_t\");\n\t}\n\tif (!(sizeof(duk_int_t) >= 4)) {\n\t\tDUK__FAILED(\"duk_int_t is not 32 bits\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Packed tval sanity\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_packed_tval(void) {\n\tduk_uint_t error_count = 0;\n\n#if defined(DUK_USE_PACKED_TVAL)\n\tif (sizeof(void *) > 4) {\n\t\tDUK__FAILED(\"packed duk_tval in use but sizeof(void *) > 4\");\n\t}\n#endif\n\n\treturn error_count;\n}\n\n/*\n *  Two's complement arithmetic.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_twos_complement(void) {\n\tduk_uint_t error_count = 0;\n\tvolatile int test;\n\ttest = -1;\n\n\t/* Note that byte order doesn't affect this test: all bytes in\n\t * 'test' will be 0xFF for two's complement.\n\t */\n\tif (((volatile duk_uint8_t *) &test)[0] != (duk_uint8_t) 0xff) {\n\t\tDUK__FAILED(\"two's complement arithmetic\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Byte order.  Important to self check, because on some exotic platforms\n *  there is no actual detection but rather assumption based on platform\n *  defines.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_byte_order(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_u32_union u1;\n\tduk__test_double_union u2;\n\n\t/*\n\t *  >>> struct.pack('>d', 102030405060).encode('hex')\n\t *  '4237c17c6dc40000'\n\t */\n\n\tDUK__U32_INIT(&u1, 0xde, 0xad, 0xbe, 0xef);\n\tDUK__DOUBLE_INIT(&u2, 0x42, 0x37, 0xc1, 0x7c, 0x6d, 0xc4, 0x00, 0x00);\n\n\tif (u1.i != (duk_uint32_t) 0xdeadbeefUL) {\n\t\tDUK__FAILED(\"duk_uint32_t byte order\");\n\t}\n\n\tif (u2.d != (double) 102030405060.0) {\n\t\tDUK__FAILED(\"double byte order\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  DUK_BSWAP macros\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_bswap_macros(void) {\n\tduk_uint_t error_count = 0;\n\tvolatile duk_uint32_t x32_input, x32_output;\n\tduk_uint32_t x32;\n\tvolatile duk_uint16_t x16_input, x16_output;\n\tduk_uint16_t x16;\n\tduk_double_union du;\n\tduk_double_t du_diff;\n#if defined(DUK_BSWAP64)\n\tvolatile duk_uint64_t x64_input, x64_output;\n\tduk_uint64_t x64;\n#endif\n\n\t/* Cover both compile time and runtime bswap operations, as these\n\t * may have different bugs.\n\t */\n\n\tx16_input = 0xbeefUL;\n\tx16 = x16_input;\n\tx16 = DUK_BSWAP16(x16);\n\tx16_output = x16;\n\tif (x16_output != (duk_uint16_t) 0xefbeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP16\");\n\t}\n\n\tx16 = 0xbeefUL;\n\tx16 = DUK_BSWAP16(x16);\n\tif (x16 != (duk_uint16_t) 0xefbeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP16\");\n\t}\n\n\tx32_input = 0xdeadbeefUL;\n\tx32 = x32_input;\n\tx32 = DUK_BSWAP32(x32);\n\tx32_output = x32;\n\tif (x32_output != (duk_uint32_t) 0xefbeaddeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP32\");\n\t}\n\n\tx32 = 0xdeadbeefUL;\n\tx32 = DUK_BSWAP32(x32);\n\tif (x32 != (duk_uint32_t) 0xefbeaddeUL) {\n\t\tDUK__FAILED(\"DUK_BSWAP32\");\n\t}\n\n#if defined(DUK_BSWAP64)\n\tx64_input = DUK_U64_CONSTANT(0x8899aabbccddeeff);\n\tx64 = x64_input;\n\tx64 = DUK_BSWAP64(x64);\n\tx64_output = x64;\n\tif (x64_output != (duk_uint64_t) DUK_U64_CONSTANT(0xffeeddccbbaa9988)) {\n\t\tDUK__FAILED(\"DUK_BSWAP64\");\n\t}\n\n\tx64 = DUK_U64_CONSTANT(0x8899aabbccddeeff);\n\tx64 = DUK_BSWAP64(x64);\n\tif (x64 != (duk_uint64_t) DUK_U64_CONSTANT(0xffeeddccbbaa9988)) {\n\t\tDUK__FAILED(\"DUK_BSWAP64\");\n\t}\n#endif\n\n\t/* >>> struct.unpack('>d', '4000112233445566'.decode('hex'))\n\t * (2.008366013071895,)\n\t */\n\n\tdu.uc[0] = 0x40; du.uc[1] = 0x00; du.uc[2] = 0x11; du.uc[3] = 0x22;\n\tdu.uc[4] = 0x33; du.uc[5] = 0x44; du.uc[6] = 0x55; du.uc[7] = 0x66;\n\tDUK_DBLUNION_DOUBLE_NTOH(&du);\n\tdu_diff = du.d - 2.008366013071895;\n#if 0\n\tDUK_D(DUK_DPRINT(\"du_diff: %lg\\n\", (double) du_diff));\n#endif\n\tif (du_diff > 1e-15) {\n\t\t/* Allow very small lenience because some compilers won't parse\n\t\t * exact IEEE double constants (happened in matrix testing with\n\t\t * Linux gcc-4.8 -m32 at least).\n\t\t */\n#if 0\n\t\tDUK_D(DUK_DPRINT(\"Result of DUK_DBLUNION_DOUBLE_NTOH: %02x %02x %02x %02x %02x %02x %02x %02x\\n\",\n\t\t            (unsigned int) du.uc[0], (unsigned int) du.uc[1],\n\t\t            (unsigned int) du.uc[2], (unsigned int) du.uc[3],\n\t\t            (unsigned int) du.uc[4], (unsigned int) du.uc[5],\n\t\t            (unsigned int) du.uc[6], (unsigned int) du.uc[7]));\n#endif\n\t\tDUK__FAILED(\"DUK_DBLUNION_DOUBLE_NTOH\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Basic double / byte union memory layout.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_union_size(void) {\n\tduk_uint_t error_count = 0;\n\n\tif (sizeof(duk__test_double_union) != 8) {\n\t\tDUK__FAILED(\"invalid union size\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Union aliasing, see misc/clang_aliasing.c.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_aliasing(void) {\n\t/* This testcase fails when Emscripten-generated code runs on Firefox.\n\t * It's not an issue because the failure should only affect packed\n\t * duk_tval representation, which is not used with Emscripten.\n\t */\n#if defined(DUK_USE_PACKED_TVAL)\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union a, b;\n\n\t/* Test signaling NaN and alias assignment in all endianness combinations.\n\t */\n\n\t/* little endian */\n\ta.x[0] = 0x11; a.x[1] = 0x22; a.x[2] = 0x33; a.x[3] = 0x44;\n\ta.x[4] = 0x00; a.x[5] = 0x00; a.x[6] = 0xf1; a.x[7] = 0xff;\n\tb = a;\n\tDUK__DBLUNION_CMP_TRUE(&a, &b);\n\n\t/* big endian */\n\ta.x[0] = 0xff; a.x[1] = 0xf1; a.x[2] = 0x00; a.x[3] = 0x00;\n\ta.x[4] = 0x44; a.x[5] = 0x33; a.x[6] = 0x22; a.x[7] = 0x11;\n\tb = a;\n\tDUK__DBLUNION_CMP_TRUE(&a, &b);\n\n\t/* mixed endian */\n\ta.x[0] = 0x00; a.x[1] = 0x00; a.x[2] = 0xf1; a.x[3] = 0xff;\n\ta.x[4] = 0x11; a.x[5] = 0x22; a.x[6] = 0x33; a.x[7] = 0x44;\n\tb = a;\n\tDUK__DBLUNION_CMP_TRUE(&a, &b);\n\n\treturn error_count;\n#else\n\tDUK_D(DUK_DPRINT(\"skip double aliasing self test when duk_tval is not packed\"));\n\treturn 0;\n#endif\n}\n\n/*\n *  Zero sign, see misc/tcc_zerosign2.c.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_zero_sign(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union a, b;\n\n\ta.d = 0.0;\n\tb.d = -a.d;\n\tDUK__DBLUNION_CMP_FALSE(&a, &b);\n\n\treturn error_count;\n}\n\n/*\n *  Rounding mode: Duktape assumes round-to-nearest, check that this is true.\n *  If we had C99 fenv.h we could check that fegetround() == FE_TONEAREST,\n *  but we don't want to rely on that header; and even if we did, it's good\n *  to ensure the rounding actually works.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_double_rounding(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union a, b, c;\n\n#if 0\n\t/* Include <fenv.h> and test manually; these trigger failures: */\n\tfesetround(FE_UPWARD);\n\tfesetround(FE_DOWNWARD);\n\tfesetround(FE_TOWARDZERO);\n\n\t/* This is the default and passes. */\n\tfesetround(FE_TONEAREST);\n#endif\n\n\t/* Rounding tests check that none of the other modes (round to\n\t * +Inf, round to -Inf, round to zero) can be active:\n\t * http://www.gnu.org/software/libc/manual/html_node/Rounding.html\n\t */\n\n\t/* 1.0 + 2^(-53): result is midway between 1.0 and 1.0 + ulp.\n\t * Round to nearest: 1.0\n\t * Round to +Inf:    1.0 + ulp\n\t * Round to -Inf:    1.0\n\t * Round to zero:    1.0\n\t * => Correct result eliminates round to +Inf.\n\t */\n\tDUK__DOUBLE_INIT(&a, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);\n\tDUK__DOUBLE_INIT(&b, 0x3c, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);\n\tduk_memset((void *) &c, 0, sizeof(c));\n\tc.d = a.d + b.d;\n\tif (!DUK__DOUBLE_COMPARE(&c, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)) {\n\t\tDUK_D(DUK_DPRINT(\"broken result (native endiannesss): %02x %02x %02x %02x %02x %02x %02x %02x\",\n\t\t                 (unsigned int) c.x[0], (unsigned int) c.x[1],\n\t\t                 (unsigned int) c.x[2], (unsigned int) c.x[3],\n\t\t                 (unsigned int) c.x[4], (unsigned int) c.x[5],\n\t\t                 (unsigned int) c.x[6], (unsigned int) c.x[7]));\n\t\tDUK__FAILED(\"invalid result from 1.0 + 0.5ulp\");\n\t}\n\n\t/* (1.0 + ulp) + 2^(-53): result is midway between 1.0 + ulp and 1.0 + 2*ulp.\n\t * Round to nearest: 1.0 + 2*ulp (round to even mantissa)\n\t * Round to +Inf:    1.0 + 2*ulp\n\t * Round to -Inf:    1.0 + ulp\n\t * Round to zero:    1.0 + ulp\n\t * => Correct result eliminates round to -Inf and round to zero.\n\t */\n\tDUK__DOUBLE_INIT(&a, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01);\n\tDUK__DOUBLE_INIT(&b, 0x3c, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);\n\tduk_memset((void *) &c, 0, sizeof(c));\n\tc.d = a.d + b.d;\n\tif (!DUK__DOUBLE_COMPARE(&c, 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02)) {\n\t\tDUK_D(DUK_DPRINT(\"broken result (native endiannesss): %02x %02x %02x %02x %02x %02x %02x %02x\",\n\t\t                 (unsigned int) c.x[0], (unsigned int) c.x[1],\n\t\t                 (unsigned int) c.x[2], (unsigned int) c.x[3],\n\t\t                 (unsigned int) c.x[4], (unsigned int) c.x[5],\n\t\t                 (unsigned int) c.x[6], (unsigned int) c.x[7]));\n\t\tDUK__FAILED(\"invalid result from (1.0 + ulp) + 0.5ulp\");\n\t}\n\n\t/* Could do negative number testing too, but the tests above should\n\t * differentiate between IEEE 754 rounding modes.\n\t */\n\treturn error_count;\n}\n\n/*\n *  fmod(): often a portability issue in embedded or bare platform targets.\n *  Check for at least minimally correct behavior.  Unlike some other math\n *  functions (like cos()) Duktape relies on fmod() internally too.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_fmod(void) {\n\tduk_uint_t error_count = 0;\n\tduk__test_double_union u1, u2;\n\tvolatile duk_double_t t1, t2, t3;\n\n\t/* fmod() with integer argument and exponent 2^32 is used by e.g.\n\t * ToUint32() and some Duktape internals.\n\t */\n\tu1.d = DUK_FMOD(10.0, 4294967296.0);\n\tu2.d = 10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(4294967306.0, 4294967296.0);\n\tu2.d = 10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(73014444042.0, 4294967296.0);\n\tu2.d = 10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\t/* 52-bit integer split into two parts:\n\t * >>> 0x1fedcba9876543\n\t * 8987183256397123\n\t * >>> float(0x1fedcba9876543) / float(2**53)\n\t * 0.9977777777777778\n\t */\n\tu1.d = DUK_FMOD(8987183256397123.0, 4294967296.0);\n\tu2.d = (duk_double_t) 0xa9876543UL;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\tt1 = 8987183256397123.0;\n\tt2 = 4294967296.0;\n\tt3 = t1 / t2;\n\tu1.d = DUK_FLOOR(t3);\n\tu2.d = (duk_double_t) 0x1fedcbUL;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\t/* C99 behavior is for fmod() result sign to mathc argument sign. */\n\tu1.d = DUK_FMOD(-10.0, 4294967296.0);\n\tu2.d = -10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(-4294967306.0, 4294967296.0);\n\tu2.d = -10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\tu1.d = DUK_FMOD(-73014444042.0, 4294967296.0);\n\tu2.d = -10.0;\n\tDUK__DBLUNION_CMP_TRUE(&u1, &u2);\n\n\treturn error_count;\n}\n\n/*\n *  Struct size/alignment if platform requires it\n *\n *  There are some compiler specific struct padding pragmas etc in use, this\n *  selftest ensures they're correctly detected and used.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_struct_align(void) {\n\tduk_uint_t error_count = 0;\n\n#if (DUK_USE_ALIGN_BY == 4)\n\tif ((sizeof(duk_hbuffer_fixed) % 4) != 0) {\n\t\tDUK__FAILED(\"sizeof(duk_hbuffer_fixed) not aligned to 4\");\n\t}\n#elif (DUK_USE_ALIGN_BY == 8)\n\tif ((sizeof(duk_hbuffer_fixed) % 8) != 0) {\n\t\tDUK__FAILED(\"sizeof(duk_hbuffer_fixed) not aligned to 8\");\n\t}\n#elif (DUK_USE_ALIGN_BY == 1)\n\t/* no check */\n#else\n#error invalid DUK_USE_ALIGN_BY\n#endif\n\treturn error_count;\n}\n\n/*\n *  64-bit arithmetic\n *\n *  There are some platforms/compilers where 64-bit types are available\n *  but don't work correctly.  Test for known cases.\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_64bit_arithmetic(void) {\n\tduk_uint_t error_count = 0;\n#if defined(DUK_USE_64BIT_OPS)\n\tvolatile duk_int64_t i;\n\tvolatile duk_double_t d;\n\n\t/* Catch a double-to-int64 cast issue encountered in practice. */\n\td = 2147483648.0;\n\ti = (duk_int64_t) d;\n\tif (i != DUK_I64_CONSTANT(0x80000000)) {\n\t\tDUK__FAILED(\"casting 2147483648.0 to duk_int64_t failed\");\n\t}\n#else\n\t/* nop */\n#endif\n\treturn error_count;\n}\n\n/*\n *  Casting\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_cast_double_to_small_uint(void) {\n\t/*\n\t *  https://github.com/svaarala/duktape/issues/127#issuecomment-77863473\n\t */\n\n\tduk_uint_t error_count = 0;\n\n\tduk_double_t d1, d2;\n\tduk_small_uint_t u;\n\n\tduk_double_t d1v, d2v;\n\tduk_small_uint_t uv;\n\n\t/* Test without volatiles */\n\n\td1 = 1.0;\n\tu = (duk_small_uint_t) d1;\n\td2 = (duk_double_t) u;\n\n\tif (!(d1 == 1.0 && u == 1 && d2 == 1.0 && d1 == d2)) {\n\t\tDUK__FAILED(\"double to duk_small_uint_t cast failed\");\n\t}\n\n\t/* Same test with volatiles */\n\n\td1v = 1.0;\n\tuv = (duk_small_uint_t) d1v;\n\td2v = (duk_double_t) uv;\n\n\tif (!(d1v == 1.0 && uv == 1 && d2v == 1.0 && d1v == d2v)) {\n\t\tDUK__FAILED(\"double to duk_small_uint_t cast failed\");\n\t}\n\n\treturn error_count;\n}\n\nDUK_LOCAL duk_uint_t duk__selftest_cast_double_to_uint32(void) {\n\t/*\n\t *  This test fails on an exotic ARM target; double-to-uint\n\t *  cast is incorrectly clamped to -signed- int highest value.\n\t *\n\t *  https://github.com/svaarala/duktape/issues/336\n\t */\n\n\tduk_uint_t error_count = 0;\n\tduk_double_t dv;\n\tduk_uint32_t uv;\n\n\tdv = 3735928559.0;  /* 0xdeadbeef in decimal */\n\tuv = (duk_uint32_t) dv;\n\n\tif (uv != 0xdeadbeefUL) {\n\t\tDUK__FAILED(\"double to duk_uint32_t cast failed\");\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Minimal test of user supplied allocation functions\n *\n *    - Basic alloc + realloc + free cycle\n *\n *    - Realloc to significantly larger size to (hopefully) trigger a\n *      relocation and check that relocation copying works\n */\n\nDUK_LOCAL duk_uint_t duk__selftest_alloc_funcs(duk_alloc_function alloc_func,\n                                               duk_realloc_function realloc_func,\n                                               duk_free_function free_func,\n                                               void *udata) {\n\tduk_uint_t error_count = 0;\n\tvoid *ptr;\n\tvoid *new_ptr;\n\tduk_small_int_t i, j;\n\tunsigned char x;\n\n\tif (alloc_func == NULL || realloc_func == NULL || free_func == NULL) {\n\t\treturn 0;\n\t}\n\n\tfor (i = 1; i <= 256; i++) {\n\t\tptr = alloc_func(udata, (duk_size_t) i);\n\t\tif (ptr == NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"alloc failed, ignore\"));\n\t\t\tcontinue;  /* alloc failed, ignore */\n\t\t}\n\t\tfor (j = 0; j < i; j++) {\n\t\t\t((unsigned char *) ptr)[j] = (unsigned char) (0x80 + j);\n\t\t}\n\t\tnew_ptr = realloc_func(udata, ptr, 1024);\n\t\tif (new_ptr == NULL) {\n\t\t\tDUK_D(DUK_DPRINT(\"realloc failed, ignore\"));\n\t\t\tfree_func(udata, ptr);\n\t\t\tcontinue;  /* realloc failed, ignore */\n\t\t}\n\t\tptr = new_ptr;\n\t\tfor (j = 0; j < i; j++) {\n\t\t\tx = ((unsigned char *) ptr)[j];\n\t\t\tif (x != (unsigned char) (0x80 + j)) {\n\t\t\t\tDUK_D(DUK_DPRINT(\"byte at index %ld doesn't match after realloc: %02lx\",\n\t\t\t\t                 (long) j, (unsigned long) x));\n\t\t\t\tDUK__FAILED(\"byte compare after realloc\");\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tfree_func(udata, ptr);\n\t}\n\n\treturn error_count;\n}\n\n/*\n *  Self test main\n */\n\nDUK_INTERNAL duk_uint_t duk_selftest_run_tests(duk_alloc_function alloc_func,\n                                               duk_realloc_function realloc_func,\n                                               duk_free_function free_func,\n                                               void *udata) {\n\tduk_uint_t error_count = 0;\n\n\tDUK_D(DUK_DPRINT(\"self test starting\"));\n\n\terror_count += duk__selftest_types();\n\terror_count += duk__selftest_packed_tval();\n\terror_count += duk__selftest_twos_complement();\n\terror_count += duk__selftest_byte_order();\n\terror_count += duk__selftest_bswap_macros();\n\terror_count += duk__selftest_double_union_size();\n\terror_count += duk__selftest_double_aliasing();\n\terror_count += duk__selftest_double_zero_sign();\n\terror_count += duk__selftest_double_rounding();\n\terror_count += duk__selftest_fmod();\n\terror_count += duk__selftest_struct_align();\n\terror_count += duk__selftest_64bit_arithmetic();\n\terror_count += duk__selftest_cast_double_to_small_uint();\n\terror_count += duk__selftest_cast_double_to_uint32();\n\terror_count += duk__selftest_alloc_funcs(alloc_func, realloc_func, free_func, udata);\n\n\tDUK_D(DUK_DPRINT(\"self test complete, total error count: %ld\", (long) error_count));\n\n\treturn error_count;\n}\n\n#endif  /* DUK_USE_SELF_TESTS */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_selftest.h",
    "content": "/*\n *  Selftest code\n */\n\n#if !defined(DUK_SELFTEST_H_INCLUDED)\n#define DUK_SELFTEST_H_INCLUDED\n\n#if defined(DUK_USE_SELF_TESTS)\nDUK_INTERNAL_DECL duk_uint_t duk_selftest_run_tests(duk_alloc_function alloc_func,\n                                                    duk_realloc_function realloc_func,\n                                                    duk_free_function free_func,\n                                                    void *udata);\n#endif\n\n#endif  /* DUK_SELFTEST_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_source_meta.json",
    "content": "{\n    \"comment\": \"Metadata for Duktape sources\", \n    \"duk_version_string\": \"2.4.0\", \n    \"type\": \"duk_source_meta\", \n    \"duk_version\": 20400, \n    \"git_branch\": \"master\", \n    \"git_commit\": \"d4f2cff1c592d70f58bab8e1bd85705174c02a58\", \n    \"builtin_strings_info\": [\n        {\n            \"plain\": \"Undefined\", \n            \"base64\": \"VW5kZWZpbmVk\", \n            \"define\": \"DUK_STRIDX_UC_UNDEFINED\"\n        }, \n        {\n            \"plain\": \"Null\", \n            \"base64\": \"TnVsbA==\", \n            \"define\": \"DUK_STRIDX_UC_NULL\"\n        }, \n        {\n            \"plain\": \"Symbol\", \n            \"base64\": \"U3ltYm9s\", \n            \"define\": \"DUK_STRIDX_UC_SYMBOL\"\n        }, \n        {\n            \"plain\": \"Arguments\", \n            \"base64\": \"QXJndW1lbnRz\", \n            \"define\": \"DUK_STRIDX_UC_ARGUMENTS\"\n        }, \n        {\n            \"plain\": \"Object\", \n            \"base64\": \"T2JqZWN0\", \n            \"define\": \"DUK_STRIDX_UC_OBJECT\"\n        }, \n        {\n            \"plain\": \"Function\", \n            \"base64\": \"RnVuY3Rpb24=\", \n            \"define\": \"DUK_STRIDX_UC_FUNCTION\"\n        }, \n        {\n            \"plain\": \"Array\", \n            \"base64\": \"QXJyYXk=\", \n            \"define\": \"DUK_STRIDX_ARRAY\"\n        }, \n        {\n            \"plain\": \"String\", \n            \"base64\": \"U3RyaW5n\", \n            \"define\": \"DUK_STRIDX_UC_STRING\"\n        }, \n        {\n            \"plain\": \"Boolean\", \n            \"base64\": \"Qm9vbGVhbg==\", \n            \"define\": \"DUK_STRIDX_UC_BOOLEAN\"\n        }, \n        {\n            \"plain\": \"Number\", \n            \"base64\": \"TnVtYmVy\", \n            \"define\": \"DUK_STRIDX_UC_NUMBER\"\n        }, \n        {\n            \"plain\": \"Date\", \n            \"base64\": \"RGF0ZQ==\", \n            \"define\": \"DUK_STRIDX_DATE\"\n        }, \n        {\n            \"plain\": \"RegExp\", \n            \"base64\": \"UmVnRXhw\", \n            \"define\": \"DUK_STRIDX_REG_EXP\"\n        }, \n        {\n            \"plain\": \"Error\", \n            \"base64\": \"RXJyb3I=\", \n            \"define\": \"DUK_STRIDX_UC_ERROR\"\n        }, \n        {\n            \"plain\": \"Math\", \n            \"base64\": \"TWF0aA==\", \n            \"define\": \"DUK_STRIDX_MATH\"\n        }, \n        {\n            \"plain\": \"JSON\", \n            \"base64\": \"SlNPTg==\", \n            \"define\": \"DUK_STRIDX_JSON\"\n        }, \n        {\n            \"plain\": \"\", \n            \"base64\": \"\", \n            \"define\": \"DUK_STRIDX_EMPTY_STRING\"\n        }, \n        {\n            \"plain\": \"ArrayBuffer\", \n            \"base64\": \"QXJyYXlCdWZmZXI=\", \n            \"define\": \"DUK_STRIDX_ARRAY_BUFFER\"\n        }, \n        {\n            \"plain\": \"DataView\", \n            \"base64\": \"RGF0YVZpZXc=\", \n            \"define\": \"DUK_STRIDX_DATA_VIEW\"\n        }, \n        {\n            \"plain\": \"Int8Array\", \n            \"base64\": \"SW50OEFycmF5\", \n            \"define\": \"DUK_STRIDX_INT8_ARRAY\"\n        }, \n        {\n            \"plain\": \"Uint8Array\", \n            \"base64\": \"VWludDhBcnJheQ==\", \n            \"define\": \"DUK_STRIDX_UINT8_ARRAY\"\n        }, \n        {\n            \"plain\": \"Uint8ClampedArray\", \n            \"base64\": \"VWludDhDbGFtcGVkQXJyYXk=\", \n            \"define\": \"DUK_STRIDX_UINT8_CLAMPED_ARRAY\"\n        }, \n        {\n            \"plain\": \"Int16Array\", \n            \"base64\": \"SW50MTZBcnJheQ==\", \n            \"define\": \"DUK_STRIDX_INT16_ARRAY\"\n        }, \n        {\n            \"plain\": \"Uint16Array\", \n            \"base64\": \"VWludDE2QXJyYXk=\", \n            \"define\": \"DUK_STRIDX_UINT16_ARRAY\"\n        }, \n        {\n            \"plain\": \"Int32Array\", \n            \"base64\": \"SW50MzJBcnJheQ==\", \n            \"define\": \"DUK_STRIDX_INT32_ARRAY\"\n        }, \n        {\n            \"plain\": \"Uint32Array\", \n            \"base64\": \"VWludDMyQXJyYXk=\", \n            \"define\": \"DUK_STRIDX_UINT32_ARRAY\"\n        }, \n        {\n            \"plain\": \"Float32Array\", \n            \"base64\": \"RmxvYXQzMkFycmF5\", \n            \"define\": \"DUK_STRIDX_FLOAT32_ARRAY\"\n        }, \n        {\n            \"plain\": \"Float64Array\", \n            \"base64\": \"RmxvYXQ2NEFycmF5\", \n            \"define\": \"DUK_STRIDX_FLOAT64_ARRAY\"\n        }, \n        {\n            \"plain\": \"global\", \n            \"base64\": \"Z2xvYmFs\", \n            \"define\": \"DUK_STRIDX_GLOBAL\"\n        }, \n        {\n            \"plain\": \"ObjEnv\", \n            \"base64\": \"T2JqRW52\", \n            \"define\": \"DUK_STRIDX_OBJ_ENV\"\n        }, \n        {\n            \"plain\": \"DecEnv\", \n            \"base64\": \"RGVjRW52\", \n            \"define\": \"DUK_STRIDX_DEC_ENV\"\n        }, \n        {\n            \"plain\": \"Buffer\", \n            \"base64\": \"QnVmZmVy\", \n            \"define\": \"DUK_STRIDX_UC_BUFFER\"\n        }, \n        {\n            \"plain\": \"Pointer\", \n            \"base64\": \"UG9pbnRlcg==\", \n            \"define\": \"DUK_STRIDX_UC_POINTER\"\n        }, \n        {\n            \"plain\": \"Thread\", \n            \"base64\": \"VGhyZWFk\", \n            \"define\": \"DUK_STRIDX_UC_THREAD\"\n        }, \n        {\n            \"plain\": \"eval\", \n            \"base64\": \"ZXZhbA==\", \n            \"define\": \"DUK_STRIDX_EVAL\"\n        }, \n        {\n            \"plain\": \"value\", \n            \"base64\": \"dmFsdWU=\", \n            \"define\": \"DUK_STRIDX_VALUE\"\n        }, \n        {\n            \"plain\": \"writable\", \n            \"base64\": \"d3JpdGFibGU=\", \n            \"define\": \"DUK_STRIDX_WRITABLE\"\n        }, \n        {\n            \"plain\": \"configurable\", \n            \"base64\": \"Y29uZmlndXJhYmxl\", \n            \"define\": \"DUK_STRIDX_CONFIGURABLE\"\n        }, \n        {\n            \"plain\": \"enumerable\", \n            \"base64\": \"ZW51bWVyYWJsZQ==\", \n            \"define\": \"DUK_STRIDX_ENUMERABLE\"\n        }, \n        {\n            \"plain\": \"join\", \n            \"base64\": \"am9pbg==\", \n            \"define\": \"DUK_STRIDX_JOIN\"\n        }, \n        {\n            \"plain\": \"toLocaleString\", \n            \"base64\": \"dG9Mb2NhbGVTdHJpbmc=\", \n            \"define\": \"DUK_STRIDX_TO_LOCALE_STRING\"\n        }, \n        {\n            \"plain\": \"valueOf\", \n            \"base64\": \"dmFsdWVPZg==\", \n            \"define\": \"DUK_STRIDX_VALUE_OF\"\n        }, \n        {\n            \"plain\": \"toUTCString\", \n            \"base64\": \"dG9VVENTdHJpbmc=\", \n            \"define\": \"DUK_STRIDX_TO_UTC_STRING\"\n        }, \n        {\n            \"plain\": \"toISOString\", \n            \"base64\": \"dG9JU09TdHJpbmc=\", \n            \"define\": \"DUK_STRIDX_TO_ISO_STRING\"\n        }, \n        {\n            \"plain\": \"toGMTString\", \n            \"base64\": \"dG9HTVRTdHJpbmc=\", \n            \"define\": \"DUK_STRIDX_TO_GMT_STRING\"\n        }, \n        {\n            \"plain\": \"source\", \n            \"base64\": \"c291cmNl\", \n            \"define\": \"DUK_STRIDX_SOURCE\"\n        }, \n        {\n            \"plain\": \"ignoreCase\", \n            \"base64\": \"aWdub3JlQ2FzZQ==\", \n            \"define\": \"DUK_STRIDX_IGNORE_CASE\"\n        }, \n        {\n            \"plain\": \"multiline\", \n            \"base64\": \"bXVsdGlsaW5l\", \n            \"define\": \"DUK_STRIDX_MULTILINE\"\n        }, \n        {\n            \"plain\": \"lastIndex\", \n            \"base64\": \"bGFzdEluZGV4\", \n            \"define\": \"DUK_STRIDX_LAST_INDEX\"\n        }, \n        {\n            \"plain\": \"flags\", \n            \"base64\": \"ZmxhZ3M=\", \n            \"define\": \"DUK_STRIDX_FLAGS\"\n        }, \n        {\n            \"plain\": \"index\", \n            \"base64\": \"aW5kZXg=\", \n            \"define\": \"DUK_STRIDX_INDEX\"\n        }, \n        {\n            \"plain\": \"prototype\", \n            \"base64\": \"cHJvdG90eXBl\", \n            \"define\": \"DUK_STRIDX_PROTOTYPE\"\n        }, \n        {\n            \"plain\": \"constructor\", \n            \"base64\": \"Y29uc3RydWN0b3I=\", \n            \"define\": \"DUK_STRIDX_CONSTRUCTOR\"\n        }, \n        {\n            \"plain\": \"message\", \n            \"base64\": \"bWVzc2FnZQ==\", \n            \"define\": \"DUK_STRIDX_MESSAGE\"\n        }, \n        {\n            \"plain\": \"boolean\", \n            \"base64\": \"Ym9vbGVhbg==\", \n            \"define\": \"DUK_STRIDX_LC_BOOLEAN\"\n        }, \n        {\n            \"plain\": \"number\", \n            \"base64\": \"bnVtYmVy\", \n            \"define\": \"DUK_STRIDX_LC_NUMBER\"\n        }, \n        {\n            \"plain\": \"string\", \n            \"base64\": \"c3RyaW5n\", \n            \"define\": \"DUK_STRIDX_LC_STRING\"\n        }, \n        {\n            \"plain\": \"symbol\", \n            \"base64\": \"c3ltYm9s\", \n            \"define\": \"DUK_STRIDX_LC_SYMBOL\"\n        }, \n        {\n            \"plain\": \"object\", \n            \"base64\": \"b2JqZWN0\", \n            \"define\": \"DUK_STRIDX_LC_OBJECT\"\n        }, \n        {\n            \"plain\": \"undefined\", \n            \"base64\": \"dW5kZWZpbmVk\", \n            \"define\": \"DUK_STRIDX_LC_UNDEFINED\"\n        }, \n        {\n            \"plain\": \"NaN\", \n            \"base64\": \"TmFO\", \n            \"define\": \"DUK_STRIDX_NAN\"\n        }, \n        {\n            \"plain\": \"Infinity\", \n            \"base64\": \"SW5maW5pdHk=\", \n            \"define\": \"DUK_STRIDX_INFINITY\"\n        }, \n        {\n            \"plain\": \"-Infinity\", \n            \"base64\": \"LUluZmluaXR5\", \n            \"define\": \"DUK_STRIDX_MINUS_INFINITY\"\n        }, \n        {\n            \"plain\": \"-0\", \n            \"base64\": \"LTA=\", \n            \"define\": \"DUK_STRIDX_MINUS_ZERO\"\n        }, \n        {\n            \"plain\": \",\", \n            \"base64\": \"LA==\", \n            \"define\": \"DUK_STRIDX_COMMA\"\n        }, \n        {\n            \"plain\": \"\\n    \", \n            \"base64\": \"CiAgICA=\", \n            \"define\": \"DUK_STRIDX_NEWLINE_4SPACE\"\n        }, \n        {\n            \"plain\": \"[...]\", \n            \"base64\": \"Wy4uLl0=\", \n            \"define\": \"DUK_STRIDX_BRACKETED_ELLIPSIS\"\n        }, \n        {\n            \"plain\": \"Invalid Date\", \n            \"base64\": \"SW52YWxpZCBEYXRl\", \n            \"define\": \"DUK_STRIDX_INVALID_DATE\"\n        }, \n        {\n            \"plain\": \"arguments\", \n            \"base64\": \"YXJndW1lbnRz\", \n            \"define\": \"DUK_STRIDX_LC_ARGUMENTS\"\n        }, \n        {\n            \"plain\": \"callee\", \n            \"base64\": \"Y2FsbGVl\", \n            \"define\": \"DUK_STRIDX_CALLEE\"\n        }, \n        {\n            \"plain\": \"caller\", \n            \"base64\": \"Y2FsbGVy\", \n            \"define\": \"DUK_STRIDX_CALLER\"\n        }, \n        {\n            \"plain\": \"apply\", \n            \"base64\": \"YXBwbHk=\", \n            \"define\": \"DUK_STRIDX_APPLY\"\n        }, \n        {\n            \"plain\": \"construct\", \n            \"base64\": \"Y29uc3RydWN0\", \n            \"define\": \"DUK_STRIDX_CONSTRUCT\"\n        }, \n        {\n            \"plain\": \"deleteProperty\", \n            \"base64\": \"ZGVsZXRlUHJvcGVydHk=\", \n            \"define\": \"DUK_STRIDX_DELETE_PROPERTY\"\n        }, \n        {\n            \"plain\": \"get\", \n            \"base64\": \"Z2V0\", \n            \"define\": \"DUK_STRIDX_GET\"\n        }, \n        {\n            \"plain\": \"has\", \n            \"base64\": \"aGFz\", \n            \"define\": \"DUK_STRIDX_HAS\"\n        }, \n        {\n            \"plain\": \"ownKeys\", \n            \"base64\": \"b3duS2V5cw==\", \n            \"define\": \"DUK_STRIDX_OWN_KEYS\"\n        }, \n        {\n            \"plain\": \"\\u0081Symbol.toPrimitive\\u00ff\", \n            \"base64\": \"gVN5bWJvbC50b1ByaW1pdGl2Zf8=\", \n            \"define\": \"DUK_STRIDX_WELLKNOWN_SYMBOL_TO_PRIMITIVE\"\n        }, \n        {\n            \"plain\": \"\\u0081Symbol.hasInstance\\u00ff\", \n            \"base64\": \"gVN5bWJvbC5oYXNJbnN0YW5jZf8=\", \n            \"define\": \"DUK_STRIDX_WELLKNOWN_SYMBOL_HAS_INSTANCE\"\n        }, \n        {\n            \"plain\": \"\\u0081Symbol.toStringTag\\u00ff\", \n            \"base64\": \"gVN5bWJvbC50b1N0cmluZ1RhZ/8=\", \n            \"define\": \"DUK_STRIDX_WELLKNOWN_SYMBOL_TO_STRING_TAG\"\n        }, \n        {\n            \"plain\": \"\\u0081Symbol.isConcatSpreadable\\u00ff\", \n            \"base64\": \"gVN5bWJvbC5pc0NvbmNhdFNwcmVhZGFibGX/\", \n            \"define\": \"DUK_STRIDX_WELLKNOWN_SYMBOL_IS_CONCAT_SPREADABLE\"\n        }, \n        {\n            \"plain\": \"setPrototypeOf\", \n            \"base64\": \"c2V0UHJvdG90eXBlT2Y=\", \n            \"define\": \"DUK_STRIDX_SET_PROTOTYPE_OF\"\n        }, \n        {\n            \"plain\": \"__proto__\", \n            \"base64\": \"X19wcm90b19f\", \n            \"define\": \"DUK_STRIDX___PROTO__\"\n        }, \n        {\n            \"plain\": \"toString\", \n            \"base64\": \"dG9TdHJpbmc=\", \n            \"define\": \"DUK_STRIDX_TO_STRING\"\n        }, \n        {\n            \"plain\": \"toJSON\", \n            \"base64\": \"dG9KU09O\", \n            \"define\": \"DUK_STRIDX_TO_JSON\"\n        }, \n        {\n            \"plain\": \"type\", \n            \"base64\": \"dHlwZQ==\", \n            \"define\": \"DUK_STRIDX_TYPE\"\n        }, \n        {\n            \"plain\": \"data\", \n            \"base64\": \"ZGF0YQ==\", \n            \"define\": \"DUK_STRIDX_DATA\"\n        }, \n        {\n            \"plain\": \"length\", \n            \"base64\": \"bGVuZ3Ro\", \n            \"define\": \"DUK_STRIDX_LENGTH\"\n        }, \n        {\n            \"plain\": \"set\", \n            \"base64\": \"c2V0\", \n            \"define\": \"DUK_STRIDX_SET\"\n        }, \n        {\n            \"plain\": \"stack\", \n            \"base64\": \"c3RhY2s=\", \n            \"define\": \"DUK_STRIDX_STACK\"\n        }, \n        {\n            \"plain\": \"pc\", \n            \"base64\": \"cGM=\", \n            \"define\": \"DUK_STRIDX_PC\"\n        }, \n        {\n            \"plain\": \"lineNumber\", \n            \"base64\": \"bGluZU51bWJlcg==\", \n            \"define\": \"DUK_STRIDX_LINE_NUMBER\"\n        }, \n        {\n            \"plain\": \"\\u0082Tracedata\", \n            \"base64\": \"glRyYWNlZGF0YQ==\", \n            \"define\": \"DUK_STRIDX_INT_TRACEDATA\"\n        }, \n        {\n            \"plain\": \"name\", \n            \"base64\": \"bmFtZQ==\", \n            \"define\": \"DUK_STRIDX_NAME\"\n        }, \n        {\n            \"plain\": \"fileName\", \n            \"base64\": \"ZmlsZU5hbWU=\", \n            \"define\": \"DUK_STRIDX_FILE_NAME\"\n        }, \n        {\n            \"plain\": \"pointer\", \n            \"base64\": \"cG9pbnRlcg==\", \n            \"define\": \"DUK_STRIDX_LC_POINTER\"\n        }, \n        {\n            \"plain\": \"\\u0082Target\", \n            \"base64\": \"glRhcmdldA==\", \n            \"define\": \"DUK_STRIDX_INT_TARGET\"\n        }, \n        {\n            \"plain\": \"\\u0082Next\", \n            \"base64\": \"gk5leHQ=\", \n            \"define\": \"DUK_STRIDX_INT_NEXT\"\n        }, \n        {\n            \"plain\": \"\\u0082Bytecode\", \n            \"base64\": \"gkJ5dGVjb2Rl\", \n            \"define\": \"DUK_STRIDX_INT_BYTECODE\"\n        }, \n        {\n            \"plain\": \"\\u0082Formals\", \n            \"base64\": \"gkZvcm1hbHM=\", \n            \"define\": \"DUK_STRIDX_INT_FORMALS\"\n        }, \n        {\n            \"plain\": \"\\u0082Varmap\", \n            \"base64\": \"glZhcm1hcA==\", \n            \"define\": \"DUK_STRIDX_INT_VARMAP\"\n        }, \n        {\n            \"plain\": \"\\u0082Source\", \n            \"base64\": \"glNvdXJjZQ==\", \n            \"define\": \"DUK_STRIDX_INT_SOURCE\"\n        }, \n        {\n            \"plain\": \"\\u0082Pc2line\", \n            \"base64\": \"glBjMmxpbmU=\", \n            \"define\": \"DUK_STRIDX_INT_PC2LINE\"\n        }, \n        {\n            \"plain\": \"\\u0082Map\", \n            \"base64\": \"gk1hcA==\", \n            \"define\": \"DUK_STRIDX_INT_MAP\"\n        }, \n        {\n            \"plain\": \"\\u0082Varenv\", \n            \"base64\": \"glZhcmVudg==\", \n            \"define\": \"DUK_STRIDX_INT_VARENV\"\n        }, \n        {\n            \"plain\": \"\\u0082Finalizer\", \n            \"base64\": \"gkZpbmFsaXplcg==\", \n            \"define\": \"DUK_STRIDX_INT_FINALIZER\"\n        }, \n        {\n            \"plain\": \"\\u0082Value\", \n            \"base64\": \"glZhbHVl\", \n            \"define\": \"DUK_STRIDX_INT_VALUE\"\n        }, \n        {\n            \"plain\": \"compile\", \n            \"base64\": \"Y29tcGlsZQ==\", \n            \"define\": \"DUK_STRIDX_COMPILE\"\n        }, \n        {\n            \"plain\": \"input\", \n            \"base64\": \"aW5wdXQ=\", \n            \"define\": \"DUK_STRIDX_INPUT\"\n        }, \n        {\n            \"plain\": \"errCreate\", \n            \"base64\": \"ZXJyQ3JlYXRl\", \n            \"define\": \"DUK_STRIDX_ERR_CREATE\"\n        }, \n        {\n            \"plain\": \"errThrow\", \n            \"base64\": \"ZXJyVGhyb3c=\", \n            \"define\": \"DUK_STRIDX_ERR_THROW\"\n        }, \n        {\n            \"plain\": \"env\", \n            \"base64\": \"ZW52\", \n            \"define\": \"DUK_STRIDX_ENV\"\n        }, \n        {\n            \"plain\": \"hex\", \n            \"base64\": \"aGV4\", \n            \"define\": \"DUK_STRIDX_HEX\"\n        }, \n        {\n            \"plain\": \"base64\", \n            \"base64\": \"YmFzZTY0\", \n            \"define\": \"DUK_STRIDX_BASE64\"\n        }, \n        {\n            \"plain\": \"jx\", \n            \"base64\": \"ang=\", \n            \"define\": \"DUK_STRIDX_JX\"\n        }, \n        {\n            \"plain\": \"jc\", \n            \"base64\": \"amM=\", \n            \"define\": \"DUK_STRIDX_JC\"\n        }, \n        {\n            \"plain\": \"{\\\"_undef\\\":true}\", \n            \"base64\": \"eyJfdW5kZWYiOnRydWV9\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_UNDEFINED\"\n        }, \n        {\n            \"plain\": \"{\\\"_nan\\\":true}\", \n            \"base64\": \"eyJfbmFuIjp0cnVlfQ==\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_NAN\"\n        }, \n        {\n            \"plain\": \"{\\\"_inf\\\":true}\", \n            \"base64\": \"eyJfaW5mIjp0cnVlfQ==\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_POSINF\"\n        }, \n        {\n            \"plain\": \"{\\\"_ninf\\\":true}\", \n            \"base64\": \"eyJfbmluZiI6dHJ1ZX0=\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_NEGINF\"\n        }, \n        {\n            \"plain\": \"{\\\"_func\\\":true}\", \n            \"base64\": \"eyJfZnVuYyI6dHJ1ZX0=\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_FUNCTION1\"\n        }, \n        {\n            \"plain\": \"{_func:true}\", \n            \"base64\": \"e19mdW5jOnRydWV9\", \n            \"define\": \"DUK_STRIDX_JSON_EXT_FUNCTION2\"\n        }, \n        {\n            \"plain\": \"break\", \n            \"base64\": \"YnJlYWs=\", \n            \"define\": \"DUK_STRIDX_BREAK\"\n        }, \n        {\n            \"plain\": \"case\", \n            \"base64\": \"Y2FzZQ==\", \n            \"define\": \"DUK_STRIDX_CASE\"\n        }, \n        {\n            \"plain\": \"catch\", \n            \"base64\": \"Y2F0Y2g=\", \n            \"define\": \"DUK_STRIDX_CATCH\"\n        }, \n        {\n            \"plain\": \"continue\", \n            \"base64\": \"Y29udGludWU=\", \n            \"define\": \"DUK_STRIDX_CONTINUE\"\n        }, \n        {\n            \"plain\": \"debugger\", \n            \"base64\": \"ZGVidWdnZXI=\", \n            \"define\": \"DUK_STRIDX_DEBUGGER\"\n        }, \n        {\n            \"plain\": \"default\", \n            \"base64\": \"ZGVmYXVsdA==\", \n            \"define\": \"DUK_STRIDX_DEFAULT\"\n        }, \n        {\n            \"plain\": \"delete\", \n            \"base64\": \"ZGVsZXRl\", \n            \"define\": \"DUK_STRIDX_DELETE\"\n        }, \n        {\n            \"plain\": \"do\", \n            \"base64\": \"ZG8=\", \n            \"define\": \"DUK_STRIDX_DO\"\n        }, \n        {\n            \"plain\": \"else\", \n            \"base64\": \"ZWxzZQ==\", \n            \"define\": \"DUK_STRIDX_ELSE\"\n        }, \n        {\n            \"plain\": \"finally\", \n            \"base64\": \"ZmluYWxseQ==\", \n            \"define\": \"DUK_STRIDX_FINALLY\"\n        }, \n        {\n            \"plain\": \"for\", \n            \"base64\": \"Zm9y\", \n            \"define\": \"DUK_STRIDX_FOR\"\n        }, \n        {\n            \"plain\": \"function\", \n            \"base64\": \"ZnVuY3Rpb24=\", \n            \"define\": \"DUK_STRIDX_LC_FUNCTION\"\n        }, \n        {\n            \"plain\": \"if\", \n            \"base64\": \"aWY=\", \n            \"define\": \"DUK_STRIDX_IF\"\n        }, \n        {\n            \"plain\": \"in\", \n            \"base64\": \"aW4=\", \n            \"define\": \"DUK_STRIDX_IN\"\n        }, \n        {\n            \"plain\": \"instanceof\", \n            \"base64\": \"aW5zdGFuY2VvZg==\", \n            \"define\": \"DUK_STRIDX_INSTANCEOF\"\n        }, \n        {\n            \"plain\": \"new\", \n            \"base64\": \"bmV3\", \n            \"define\": \"DUK_STRIDX_NEW\"\n        }, \n        {\n            \"plain\": \"return\", \n            \"base64\": \"cmV0dXJu\", \n            \"define\": \"DUK_STRIDX_RETURN\"\n        }, \n        {\n            \"plain\": \"switch\", \n            \"base64\": \"c3dpdGNo\", \n            \"define\": \"DUK_STRIDX_SWITCH\"\n        }, \n        {\n            \"plain\": \"this\", \n            \"base64\": \"dGhpcw==\", \n            \"define\": \"DUK_STRIDX_THIS\"\n        }, \n        {\n            \"plain\": \"throw\", \n            \"base64\": \"dGhyb3c=\", \n            \"define\": \"DUK_STRIDX_THROW\"\n        }, \n        {\n            \"plain\": \"try\", \n            \"base64\": \"dHJ5\", \n            \"define\": \"DUK_STRIDX_TRY\"\n        }, \n        {\n            \"plain\": \"typeof\", \n            \"base64\": \"dHlwZW9m\", \n            \"define\": \"DUK_STRIDX_TYPEOF\"\n        }, \n        {\n            \"plain\": \"var\", \n            \"base64\": \"dmFy\", \n            \"define\": \"DUK_STRIDX_VAR\"\n        }, \n        {\n            \"plain\": \"const\", \n            \"base64\": \"Y29uc3Q=\", \n            \"define\": \"DUK_STRIDX_CONST\"\n        }, \n        {\n            \"plain\": \"void\", \n            \"base64\": \"dm9pZA==\", \n            \"define\": \"DUK_STRIDX_VOID\"\n        }, \n        {\n            \"plain\": \"while\", \n            \"base64\": \"d2hpbGU=\", \n            \"define\": \"DUK_STRIDX_WHILE\"\n        }, \n        {\n            \"plain\": \"with\", \n            \"base64\": \"d2l0aA==\", \n            \"define\": \"DUK_STRIDX_WITH\"\n        }, \n        {\n            \"plain\": \"class\", \n            \"base64\": \"Y2xhc3M=\", \n            \"define\": \"DUK_STRIDX_CLASS\"\n        }, \n        {\n            \"plain\": \"enum\", \n            \"base64\": \"ZW51bQ==\", \n            \"define\": \"DUK_STRIDX_ENUM\"\n        }, \n        {\n            \"plain\": \"export\", \n            \"base64\": \"ZXhwb3J0\", \n            \"define\": \"DUK_STRIDX_EXPORT\"\n        }, \n        {\n            \"plain\": \"extends\", \n            \"base64\": \"ZXh0ZW5kcw==\", \n            \"define\": \"DUK_STRIDX_EXTENDS\"\n        }, \n        {\n            \"plain\": \"import\", \n            \"base64\": \"aW1wb3J0\", \n            \"define\": \"DUK_STRIDX_IMPORT\"\n        }, \n        {\n            \"plain\": \"super\", \n            \"base64\": \"c3VwZXI=\", \n            \"define\": \"DUK_STRIDX_SUPER\"\n        }, \n        {\n            \"plain\": \"null\", \n            \"base64\": \"bnVsbA==\", \n            \"define\": \"DUK_STRIDX_LC_NULL\"\n        }, \n        {\n            \"plain\": \"true\", \n            \"base64\": \"dHJ1ZQ==\", \n            \"define\": \"DUK_STRIDX_TRUE\"\n        }, \n        {\n            \"plain\": \"false\", \n            \"base64\": \"ZmFsc2U=\", \n            \"define\": \"DUK_STRIDX_FALSE\"\n        }, \n        {\n            \"plain\": \"implements\", \n            \"base64\": \"aW1wbGVtZW50cw==\", \n            \"define\": \"DUK_STRIDX_IMPLEMENTS\"\n        }, \n        {\n            \"plain\": \"interface\", \n            \"base64\": \"aW50ZXJmYWNl\", \n            \"define\": \"DUK_STRIDX_INTERFACE\"\n        }, \n        {\n            \"plain\": \"let\", \n            \"base64\": \"bGV0\", \n            \"define\": \"DUK_STRIDX_LET\"\n        }, \n        {\n            \"plain\": \"package\", \n            \"base64\": \"cGFja2FnZQ==\", \n            \"define\": \"DUK_STRIDX_PACKAGE\"\n        }, \n        {\n            \"plain\": \"private\", \n            \"base64\": \"cHJpdmF0ZQ==\", \n            \"define\": \"DUK_STRIDX_PRIVATE\"\n        }, \n        {\n            \"plain\": \"protected\", \n            \"base64\": \"cHJvdGVjdGVk\", \n            \"define\": \"DUK_STRIDX_PROTECTED\"\n        }, \n        {\n            \"plain\": \"public\", \n            \"base64\": \"cHVibGlj\", \n            \"define\": \"DUK_STRIDX_PUBLIC\"\n        }, \n        {\n            \"plain\": \"static\", \n            \"base64\": \"c3RhdGlj\", \n            \"define\": \"DUK_STRIDX_STATIC\"\n        }, \n        {\n            \"plain\": \"yield\", \n            \"base64\": \"eWllbGQ=\", \n            \"define\": \"DUK_STRIDX_YIELD\"\n        }\n    ], \n    \"builtin_strings_base64\": [\n        \"VW5kZWZpbmVk\", \n        \"TnVsbA==\", \n        \"U3ltYm9s\", \n        \"QXJndW1lbnRz\", \n        \"T2JqZWN0\", \n        \"RnVuY3Rpb24=\", \n        \"QXJyYXk=\", \n        \"U3RyaW5n\", \n        \"Qm9vbGVhbg==\", \n        \"TnVtYmVy\", \n        \"RGF0ZQ==\", \n        \"UmVnRXhw\", \n        \"RXJyb3I=\", \n        \"TWF0aA==\", \n        \"SlNPTg==\", \n        \"\", \n        \"QXJyYXlCdWZmZXI=\", \n        \"RGF0YVZpZXc=\", \n        \"SW50OEFycmF5\", \n        \"VWludDhBcnJheQ==\", \n        \"VWludDhDbGFtcGVkQXJyYXk=\", \n        \"SW50MTZBcnJheQ==\", \n        \"VWludDE2QXJyYXk=\", \n        \"SW50MzJBcnJheQ==\", \n        \"VWludDMyQXJyYXk=\", \n        \"RmxvYXQzMkFycmF5\", \n        \"RmxvYXQ2NEFycmF5\", \n        \"Z2xvYmFs\", \n        \"T2JqRW52\", \n        \"RGVjRW52\", \n        \"QnVmZmVy\", \n        \"UG9pbnRlcg==\", \n        \"VGhyZWFk\", \n        \"ZXZhbA==\", \n        \"dmFsdWU=\", \n        \"d3JpdGFibGU=\", \n        \"Y29uZmlndXJhYmxl\", \n        \"ZW51bWVyYWJsZQ==\", \n        \"am9pbg==\", \n        \"dG9Mb2NhbGVTdHJpbmc=\", \n        \"dmFsdWVPZg==\", \n        \"dG9VVENTdHJpbmc=\", \n        \"dG9JU09TdHJpbmc=\", \n        \"dG9HTVRTdHJpbmc=\", \n        \"c291cmNl\", \n        \"aWdub3JlQ2FzZQ==\", \n        \"bXVsdGlsaW5l\", \n        \"bGFzdEluZGV4\", \n        \"ZmxhZ3M=\", \n        \"aW5kZXg=\", \n        \"cHJvdG90eXBl\", \n        \"Y29uc3RydWN0b3I=\", \n        \"bWVzc2FnZQ==\", \n        \"Ym9vbGVhbg==\", \n        \"bnVtYmVy\", \n        \"c3RyaW5n\", \n        \"c3ltYm9s\", \n        \"b2JqZWN0\", \n        \"dW5kZWZpbmVk\", \n        \"TmFO\", \n        \"SW5maW5pdHk=\", \n        \"LUluZmluaXR5\", \n        \"LTA=\", \n        \"LA==\", \n        \"CiAgICA=\", \n        \"Wy4uLl0=\", \n        \"SW52YWxpZCBEYXRl\", \n        \"YXJndW1lbnRz\", \n        \"Y2FsbGVl\", \n        \"Y2FsbGVy\", \n        \"YXBwbHk=\", \n        \"Y29uc3RydWN0\", \n        \"ZGVsZXRlUHJvcGVydHk=\", \n        \"Z2V0\", \n        \"aGFz\", \n        \"b3duS2V5cw==\", \n        \"gVN5bWJvbC50b1ByaW1pdGl2Zf8=\", \n        \"gVN5bWJvbC5oYXNJbnN0YW5jZf8=\", \n        \"gVN5bWJvbC50b1N0cmluZ1RhZ/8=\", \n        \"gVN5bWJvbC5pc0NvbmNhdFNwcmVhZGFibGX/\", \n        \"c2V0UHJvdG90eXBlT2Y=\", \n        \"X19wcm90b19f\", \n        \"dG9TdHJpbmc=\", \n        \"dG9KU09O\", \n        \"dHlwZQ==\", \n        \"ZGF0YQ==\", \n        \"bGVuZ3Ro\", \n        \"c2V0\", \n        \"c3RhY2s=\", \n        \"cGM=\", \n        \"bGluZU51bWJlcg==\", \n        \"glRyYWNlZGF0YQ==\", \n        \"bmFtZQ==\", \n        \"ZmlsZU5hbWU=\", \n        \"cG9pbnRlcg==\", \n        \"glRhcmdldA==\", \n        \"gk5leHQ=\", \n        \"gkJ5dGVjb2Rl\", \n        \"gkZvcm1hbHM=\", \n        \"glZhcm1hcA==\", \n        \"glNvdXJjZQ==\", \n        \"glBjMmxpbmU=\", \n        \"gk1hcA==\", \n        \"glZhcmVudg==\", \n        \"gkZpbmFsaXplcg==\", \n        \"glZhbHVl\", \n        \"Y29tcGlsZQ==\", \n        \"aW5wdXQ=\", \n        \"ZXJyQ3JlYXRl\", \n        \"ZXJyVGhyb3c=\", \n        \"ZW52\", \n        \"aGV4\", \n        \"YmFzZTY0\", \n        \"ang=\", \n        \"amM=\", \n        \"eyJfdW5kZWYiOnRydWV9\", \n        \"eyJfbmFuIjp0cnVlfQ==\", \n        \"eyJfaW5mIjp0cnVlfQ==\", \n        \"eyJfbmluZiI6dHJ1ZX0=\", \n        \"eyJfZnVuYyI6dHJ1ZX0=\", \n        \"e19mdW5jOnRydWV9\", \n        \"YnJlYWs=\", \n        \"Y2FzZQ==\", \n        \"Y2F0Y2g=\", \n        \"Y29udGludWU=\", \n        \"ZGVidWdnZXI=\", \n        \"ZGVmYXVsdA==\", \n        \"ZGVsZXRl\", \n        \"ZG8=\", \n        \"ZWxzZQ==\", \n        \"ZmluYWxseQ==\", \n        \"Zm9y\", \n        \"ZnVuY3Rpb24=\", \n        \"aWY=\", \n        \"aW4=\", \n        \"aW5zdGFuY2VvZg==\", \n        \"bmV3\", \n        \"cmV0dXJu\", \n        \"c3dpdGNo\", \n        \"dGhpcw==\", \n        \"dGhyb3c=\", \n        \"dHJ5\", \n        \"dHlwZW9m\", \n        \"dmFy\", \n        \"Y29uc3Q=\", \n        \"dm9pZA==\", \n        \"d2hpbGU=\", \n        \"d2l0aA==\", \n        \"Y2xhc3M=\", \n        \"ZW51bQ==\", \n        \"ZXhwb3J0\", \n        \"ZXh0ZW5kcw==\", \n        \"aW1wb3J0\", \n        \"c3VwZXI=\", \n        \"bnVsbA==\", \n        \"dHJ1ZQ==\", \n        \"ZmFsc2U=\", \n        \"aW1wbGVtZW50cw==\", \n        \"aW50ZXJmYWNl\", \n        \"bGV0\", \n        \"cGFja2FnZQ==\", \n        \"cHJpdmF0ZQ==\", \n        \"cHJvdGVjdGVk\", \n        \"cHVibGlj\", \n        \"c3RhdGlj\", \n        \"eWllbGQ=\"\n    ], \n    \"git_describe\": \"v2.4.0\", \n    \"builtin_strings\": [\n        \"Undefined\", \n        \"Null\", \n        \"Symbol\", \n        \"Arguments\", \n        \"Object\", \n        \"Function\", \n        \"Array\", \n        \"String\", \n        \"Boolean\", \n        \"Number\", \n        \"Date\", \n        \"RegExp\", \n        \"Error\", \n        \"Math\", \n        \"JSON\", \n        \"\", \n        \"ArrayBuffer\", \n        \"DataView\", \n        \"Int8Array\", \n        \"Uint8Array\", \n        \"Uint8ClampedArray\", \n        \"Int16Array\", \n        \"Uint16Array\", \n        \"Int32Array\", \n        \"Uint32Array\", \n        \"Float32Array\", \n        \"Float64Array\", \n        \"global\", \n        \"ObjEnv\", \n        \"DecEnv\", \n        \"Buffer\", \n        \"Pointer\", \n        \"Thread\", \n        \"eval\", \n        \"value\", \n        \"writable\", \n        \"configurable\", \n        \"enumerable\", \n        \"join\", \n        \"toLocaleString\", \n        \"valueOf\", \n        \"toUTCString\", \n        \"toISOString\", \n        \"toGMTString\", \n        \"source\", \n        \"ignoreCase\", \n        \"multiline\", \n        \"lastIndex\", \n        \"flags\", \n        \"index\", \n        \"prototype\", \n        \"constructor\", \n        \"message\", \n        \"boolean\", \n        \"number\", \n        \"string\", \n        \"symbol\", \n        \"object\", \n        \"undefined\", \n        \"NaN\", \n        \"Infinity\", \n        \"-Infinity\", \n        \"-0\", \n        \",\", \n        \"\\n    \", \n        \"[...]\", \n        \"Invalid Date\", \n        \"arguments\", \n        \"callee\", \n        \"caller\", \n        \"apply\", \n        \"construct\", \n        \"deleteProperty\", \n        \"get\", \n        \"has\", \n        \"ownKeys\", \n        \"\\u0081Symbol.toPrimitive\\u00ff\", \n        \"\\u0081Symbol.hasInstance\\u00ff\", \n        \"\\u0081Symbol.toStringTag\\u00ff\", \n        \"\\u0081Symbol.isConcatSpreadable\\u00ff\", \n        \"setPrototypeOf\", \n        \"__proto__\", \n        \"toString\", \n        \"toJSON\", \n        \"type\", \n        \"data\", \n        \"length\", \n        \"set\", \n        \"stack\", \n        \"pc\", \n        \"lineNumber\", \n        \"\\u0082Tracedata\", \n        \"name\", \n        \"fileName\", \n        \"pointer\", \n        \"\\u0082Target\", \n        \"\\u0082Next\", \n        \"\\u0082Bytecode\", \n        \"\\u0082Formals\", \n        \"\\u0082Varmap\", \n        \"\\u0082Source\", \n        \"\\u0082Pc2line\", \n        \"\\u0082Map\", \n        \"\\u0082Varenv\", \n        \"\\u0082Finalizer\", \n        \"\\u0082Value\", \n        \"compile\", \n        \"input\", \n        \"errCreate\", \n        \"errThrow\", \n        \"env\", \n        \"hex\", \n        \"base64\", \n        \"jx\", \n        \"jc\", \n        \"{\\\"_undef\\\":true}\", \n        \"{\\\"_nan\\\":true}\", \n        \"{\\\"_inf\\\":true}\", \n        \"{\\\"_ninf\\\":true}\", \n        \"{\\\"_func\\\":true}\", \n        \"{_func:true}\", \n        \"break\", \n        \"case\", \n        \"catch\", \n        \"continue\", \n        \"debugger\", \n        \"default\", \n        \"delete\", \n        \"do\", \n        \"else\", \n        \"finally\", \n        \"for\", \n        \"function\", \n        \"if\", \n        \"in\", \n        \"instanceof\", \n        \"new\", \n        \"return\", \n        \"switch\", \n        \"this\", \n        \"throw\", \n        \"try\", \n        \"typeof\", \n        \"var\", \n        \"const\", \n        \"void\", \n        \"while\", \n        \"with\", \n        \"class\", \n        \"enum\", \n        \"export\", \n        \"extends\", \n        \"import\", \n        \"super\", \n        \"null\", \n        \"true\", \n        \"false\", \n        \"implements\", \n        \"interface\", \n        \"let\", \n        \"package\", \n        \"private\", \n        \"protected\", \n        \"public\", \n        \"static\", \n        \"yield\"\n    ]\n}"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_strings.h",
    "content": "/*\n *  Shared string macros.\n *\n *  Using shared macros helps minimize strings data size because it's easy\n *  to check if an existing string could be used.  String constants don't\n *  need to be all defined here; defining a string here makes sense if there's\n *  a high chance the string could be reused.  Also, using macros allows\n *  a call site express the exact string needed, but the macro may map to an\n *  approximate string to reduce unique string count.  Macros can also be\n *  more easily tuned for low memory targets than #if defined()s throughout\n *  the code base.\n *\n *  Because format strings behave differently in the call site (they need to\n *  be followed by format arguments), they use a special prefix DUK_STR_FMT_.\n *\n *  On some compilers using explicit shared strings is preferable; on others\n *  it may be better to use straight literals because the compiler will combine\n *  them anyway, and such strings won't end up unnecessarily in a symbol table.\n */\n\n#if !defined(DUK_ERRMSG_H_INCLUDED)\n#define DUK_ERRMSG_H_INCLUDED\n\n/* Mostly API and built-in method related */\n#define DUK_STR_INTERNAL_ERROR                   \"internal error\"\n#define DUK_STR_UNSUPPORTED                      \"unsupported\"\n#define DUK_STR_INVALID_COUNT                    \"invalid count\"\n#define DUK_STR_INVALID_ARGS                     \"invalid args\"\n#define DUK_STR_INVALID_STATE                    \"invalid state\"\n#define DUK_STR_INVALID_INPUT                    \"invalid input\"\n#define DUK_STR_INVALID_LENGTH                   \"invalid length\"\n#define DUK_STR_NOT_CONSTRUCTABLE                \"not constructable\"\n#define DUK_STR_CONSTRUCT_ONLY                   \"constructor requires 'new'\"\n#define DUK_STR_NOT_CALLABLE                     \"not callable\"\n#define DUK_STR_NOT_EXTENSIBLE                   \"not extensible\"\n#define DUK_STR_NOT_WRITABLE                     \"not writable\"\n#define DUK_STR_NOT_CONFIGURABLE                 \"not configurable\"\n#define DUK_STR_INVALID_CONTEXT                  \"invalid context\"\n#define DUK_STR_INVALID_INDEX                    \"invalid args\"\n#define DUK_STR_PUSH_BEYOND_ALLOC_STACK          \"cannot push beyond allocated stack\"\n#define DUK_STR_NOT_UNDEFINED                    \"unexpected type\"\n#define DUK_STR_NOT_NULL                         \"unexpected type\"\n#define DUK_STR_NOT_BOOLEAN                      \"unexpected type\"\n#define DUK_STR_NOT_NUMBER                       \"unexpected type\"\n#define DUK_STR_NOT_STRING                       \"unexpected type\"\n#define DUK_STR_NOT_OBJECT                       \"unexpected type\"\n#define DUK_STR_NOT_POINTER                      \"unexpected type\"\n#define DUK_STR_NOT_BUFFER                       \"not buffer\"  /* still in use with verbose messages */\n#define DUK_STR_UNEXPECTED_TYPE                  \"unexpected type\"\n#define DUK_STR_NOT_THREAD                       \"unexpected type\"\n#define DUK_STR_NOT_COMPFUNC                     \"unexpected type\"\n#define DUK_STR_NOT_NATFUNC                      \"unexpected type\"\n#define DUK_STR_NOT_C_FUNCTION                   \"unexpected type\"\n#define DUK_STR_NOT_FUNCTION                     \"unexpected type\"\n#define DUK_STR_NOT_REGEXP                       \"unexpected type\"\n#define DUK_STR_TOPRIMITIVE_FAILED               \"coercion to primitive failed\"\n#define DUK_STR_NUMBER_OUTSIDE_RANGE             \"number outside range\"\n#define DUK_STR_NOT_OBJECT_COERCIBLE             \"not object coercible\"\n#define DUK_STR_CANNOT_NUMBER_COERCE_SYMBOL      \"cannot number coerce Symbol\"\n#define DUK_STR_CANNOT_STRING_COERCE_SYMBOL      \"cannot string coerce Symbol\"\n#define DUK_STR_STRING_TOO_LONG                  \"string too long\"\n#define DUK_STR_BUFFER_TOO_LONG                  \"buffer too long\"\n#define DUK_STR_ALLOC_FAILED                     \"alloc failed\"\n#define DUK_STR_WRONG_BUFFER_TYPE                \"wrong buffer type\"\n#define DUK_STR_BASE64_ENCODE_FAILED             \"base64 encode failed\"\n#define DUK_STR_SOURCE_DECODE_FAILED             \"source decode failed\"\n#define DUK_STR_UTF8_DECODE_FAILED               \"utf-8 decode failed\"\n#define DUK_STR_BASE64_DECODE_FAILED             \"base64 decode failed\"\n#define DUK_STR_HEX_DECODE_FAILED                \"hex decode failed\"\n#define DUK_STR_INVALID_BYTECODE                 \"invalid bytecode\"\n#define DUK_STR_NO_SOURCECODE                    \"no sourcecode\"\n#define DUK_STR_RESULT_TOO_LONG                  \"result too long\"\n#define DUK_STR_INVALID_CFUNC_RC                 \"invalid C function rc\"\n#define DUK_STR_INVALID_INSTANCEOF_RVAL          \"invalid instanceof rval\"\n#define DUK_STR_INVALID_INSTANCEOF_RVAL_NOPROTO  \"instanceof rval has no .prototype\"\n\n/* JSON */\n#define DUK_STR_FMT_PTR                          \"%p\"\n#define DUK_STR_FMT_INVALID_JSON                 \"invalid json (at offset %ld)\"\n#define DUK_STR_JSONDEC_RECLIMIT                 \"json decode recursion limit\"\n#define DUK_STR_JSONENC_RECLIMIT                 \"json encode recursion limit\"\n#define DUK_STR_CYCLIC_INPUT                     \"cyclic input\"\n\n/* Object property access */\n#define DUK_STR_INVALID_BASE                     \"invalid base value\"\n#define DUK_STR_STRICT_CALLER_READ               \"cannot read strict 'caller'\"\n#define DUK_STR_PROXY_REJECTED                   \"proxy rejected\"\n#define DUK_STR_INVALID_ARRAY_LENGTH             \"invalid array length\"\n#define DUK_STR_SETTER_UNDEFINED                 \"setter undefined\"\n#define DUK_STR_INVALID_DESCRIPTOR               \"invalid descriptor\"\n\n/* Proxy */\n#define DUK_STR_PROXY_REVOKED                    \"proxy revoked\"\n#define DUK_STR_INVALID_TRAP_RESULT              \"invalid trap result\"\n\n/* Variables */\n\n/* Lexer */\n#define DUK_STR_INVALID_ESCAPE                   \"invalid escape\"\n#define DUK_STR_UNTERMINATED_STRING              \"unterminated string\"\n#define DUK_STR_UNTERMINATED_COMMENT             \"unterminated comment\"\n#define DUK_STR_UNTERMINATED_REGEXP              \"unterminated regexp\"\n#define DUK_STR_TOKEN_LIMIT                      \"token limit\"\n#define DUK_STR_REGEXP_SUPPORT_DISABLED          \"regexp support disabled\"\n#define DUK_STR_INVALID_NUMBER_LITERAL           \"invalid number literal\"\n#define DUK_STR_INVALID_TOKEN                    \"invalid token\"\n\n/* Compiler */\n#define DUK_STR_PARSE_ERROR                      \"parse error\"\n#define DUK_STR_DUPLICATE_LABEL                  \"duplicate label\"\n#define DUK_STR_INVALID_LABEL                    \"invalid label\"\n#define DUK_STR_INVALID_ARRAY_LITERAL            \"invalid array literal\"\n#define DUK_STR_INVALID_OBJECT_LITERAL           \"invalid object literal\"\n#define DUK_STR_INVALID_VAR_DECLARATION          \"invalid variable declaration\"\n#define DUK_STR_CANNOT_DELETE_IDENTIFIER         \"cannot delete identifier\"\n#define DUK_STR_INVALID_EXPRESSION               \"invalid expression\"\n#define DUK_STR_INVALID_LVALUE                   \"invalid lvalue\"\n#define DUK_STR_INVALID_NEWTARGET                \"invalid new.target\"\n#define DUK_STR_EXPECTED_IDENTIFIER              \"expected identifier\"\n#define DUK_STR_EMPTY_EXPR_NOT_ALLOWED           \"empty expression not allowed\"\n#define DUK_STR_INVALID_FOR                      \"invalid for statement\"\n#define DUK_STR_INVALID_SWITCH                   \"invalid switch statement\"\n#define DUK_STR_INVALID_BREAK_CONT_LABEL         \"invalid break/continue label\"\n#define DUK_STR_INVALID_RETURN                   \"invalid return\"\n#define DUK_STR_INVALID_TRY                      \"invalid try\"\n#define DUK_STR_INVALID_THROW                    \"invalid throw\"\n#define DUK_STR_WITH_IN_STRICT_MODE              \"with in strict mode\"\n#define DUK_STR_FUNC_STMT_NOT_ALLOWED            \"function statement not allowed\"\n#define DUK_STR_UNTERMINATED_STMT                \"unterminated statement\"\n#define DUK_STR_INVALID_ARG_NAME                 \"invalid argument name\"\n#define DUK_STR_INVALID_FUNC_NAME                \"invalid function name\"\n#define DUK_STR_INVALID_GETSET_NAME              \"invalid getter/setter name\"\n#define DUK_STR_FUNC_NAME_REQUIRED               \"function name required\"\n\n/* RegExp */\n#define DUK_STR_INVALID_QUANTIFIER               \"invalid regexp quantifier\"\n#define DUK_STR_INVALID_QUANTIFIER_NO_ATOM       \"quantifier without preceding atom\"\n#define DUK_STR_INVALID_QUANTIFIER_VALUES        \"quantifier values invalid (qmin > qmax)\"\n#define DUK_STR_QUANTIFIER_TOO_MANY_COPIES       \"quantifier requires too many atom copies\"\n#define DUK_STR_UNEXPECTED_CLOSING_PAREN         \"unexpected closing parenthesis\"\n#define DUK_STR_UNEXPECTED_END_OF_PATTERN        \"unexpected end of pattern\"\n#define DUK_STR_UNEXPECTED_REGEXP_TOKEN          \"unexpected token in regexp\"\n#define DUK_STR_INVALID_REGEXP_FLAGS             \"invalid regexp flags\"\n#define DUK_STR_INVALID_REGEXP_ESCAPE            \"invalid regexp escape\"\n#define DUK_STR_INVALID_BACKREFS                 \"invalid backreference(s)\"\n#define DUK_STR_INVALID_REGEXP_CHARACTER         \"invalid regexp character\"\n#define DUK_STR_INVALID_REGEXP_GROUP             \"invalid regexp group\"\n#define DUK_STR_UNTERMINATED_CHARCLASS           \"unterminated character class\"\n#define DUK_STR_INVALID_RANGE                    \"invalid range\"\n\n/* Limits */\n#define DUK_STR_VALSTACK_LIMIT                   \"valstack limit\"\n#define DUK_STR_CALLSTACK_LIMIT                  \"callstack limit\"\n#define DUK_STR_PROTOTYPE_CHAIN_LIMIT            \"prototype chain limit\"\n#define DUK_STR_BOUND_CHAIN_LIMIT                \"function call bound chain limit\"\n#define DUK_STR_NATIVE_STACK_LIMIT               \"C stack depth limit\"\n#define DUK_STR_COMPILER_RECURSION_LIMIT         \"compiler recursion limit\"\n#define DUK_STR_BYTECODE_LIMIT                   \"bytecode limit\"\n#define DUK_STR_REG_LIMIT                        \"register limit\"\n#define DUK_STR_TEMP_LIMIT                       \"temp limit\"\n#define DUK_STR_CONST_LIMIT                      \"const limit\"\n#define DUK_STR_FUNC_LIMIT                       \"function limit\"\n#define DUK_STR_REGEXP_COMPILER_RECURSION_LIMIT  \"regexp compiler recursion limit\"\n#define DUK_STR_REGEXP_EXECUTOR_RECURSION_LIMIT  \"regexp executor recursion limit\"\n#define DUK_STR_REGEXP_EXECUTOR_STEP_LIMIT       \"regexp step limit\"\n\n#endif  /* DUK_ERRMSG_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_tval.c",
    "content": "#include \"duk_internal.h\"\n\n#if defined(DUK_USE_FASTINT)\n\n/*\n *  Manually optimized double-to-fastint downgrade check.\n *\n *  This check has a large impact on performance, especially for fastint\n *  slow paths, so must be changed carefully.  The code should probably be\n *  optimized for the case where the result does not fit into a fastint,\n *  to minimize the penalty for \"slow path code\" dealing with fractions etc.\n *\n *  At least on one tested soft float ARM platform double-to-int64 coercion\n *  is very slow (and sometimes produces incorrect results, see self tests).\n *  This algorithm combines a fastint compatibility check and extracting the\n *  integer value from an IEEE double for setting the tagged fastint.  For\n *  other platforms a more naive approach might be better.\n *\n *  See doc/fastint.rst for details.\n */\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_tval_set_number_chkfast_fast(duk_tval *tv, duk_double_t x) {\n\tduk_double_union du;\n\tduk_int64_t i;\n\tduk_small_int_t expt;\n\tduk_small_int_t shift;\n\n\t/* XXX: optimize for packed duk_tval directly? */\n\n\tdu.d = x;\n\ti = (duk_int64_t) DUK_DBLUNION_GET_INT64(&du);\n\texpt = (duk_small_int_t) ((i >> 52) & 0x07ff);\n\tshift = expt - 1023;\n\n\tif (shift >= 0 && shift <= 46) {  /* exponents 1023 to 1069 */\n\t\tduk_int64_t t;\n\n\t\tif (((DUK_I64_CONSTANT(0x000fffffffffffff) >> shift) & i) == 0) {\n\t\t\tt = i | DUK_I64_CONSTANT(0x0010000000000000);  /* implicit leading one */\n\t\t\tt = t & DUK_I64_CONSTANT(0x001fffffffffffff);\n\t\t\tt = t >> (52 - shift);\n\t\t\tif (i < 0) {\n\t\t\t\tt = -t;\n\t\t\t}\n\t\t\tDUK_TVAL_SET_FASTINT(tv, t);\n\t\t\treturn;\n\t\t}\n\t} else if (shift == -1023) {  /* exponent 0 */\n\t\tif (i >= 0 && (i & DUK_I64_CONSTANT(0x000fffffffffffff)) == 0) {\n\t\t\t/* Note: reject negative zero. */\n\t\t\tDUK_TVAL_SET_FASTINT(tv, (duk_int64_t) 0);\n\t\t\treturn;\n\t\t}\n\t} else if (shift == 47) {  /* exponent 1070 */\n\t\tif (i < 0 && (i & DUK_I64_CONSTANT(0x000fffffffffffff)) == 0) {\n\t\t\tDUK_TVAL_SET_FASTINT(tv, (duk_int64_t) DUK_FASTINT_MIN);\n\t\t\treturn;\n\t\t}\n\t}\n\n\tDUK_TVAL_SET_DOUBLE(tv, x);\n\treturn;\n}\n\nDUK_INTERNAL DUK_NOINLINE void duk_tval_set_number_chkfast_slow(duk_tval *tv, duk_double_t x) {\n\tduk_tval_set_number_chkfast_fast(tv, x);\n}\n\n/*\n *  Manually optimized number-to-double conversion\n */\n\n#if defined(DUK_USE_FASTINT) && defined(DUK_USE_PACKED_TVAL)\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_packed(duk_tval *tv) {\n\tduk_double_union du;\n\tduk_uint64_t t;\n\n\tt = (duk_uint64_t) DUK_DBLUNION_GET_UINT64(tv);\n\tif ((t >> 48) != DUK_TAG_FASTINT) {\n\t\treturn tv->d;\n\t} else if (t & DUK_U64_CONSTANT(0x0000800000000000)) {\n\t\tt = (duk_uint64_t) (-((duk_int64_t) t));  /* avoid unary minus on unsigned */\n\t\tt = t & DUK_U64_CONSTANT(0x0000ffffffffffff);  /* negative */\n\t\tt |= DUK_U64_CONSTANT(0xc330000000000000);\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d + 4503599627370496.0;  /* 1 << 52 */\n\t} else if (t != 0) {\n\t\tt &= DUK_U64_CONSTANT(0x0000ffffffffffff);  /* positive */\n\t\tt |= DUK_U64_CONSTANT(0x4330000000000000);\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d - 4503599627370496.0;  /* 1 << 52 */\n\t} else {\n\t\treturn 0.0;  /* zero */\n\t}\n}\n#endif  /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */\n\n#if 0  /* unused */\n#if defined(DUK_USE_FASTINT) && !defined(DUK_USE_PACKED_TVAL)\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked(duk_tval *tv) {\n\tduk_double_union du;\n\tduk_uint64_t t;\n\n\tDUK_ASSERT(tv->t == DUK_TAG_NUMBER || tv->t == DUK_TAG_FASTINT);\n\n\tif (tv->t == DUK_TAG_FASTINT) {\n\t\tif (tv->v.fi >= 0) {\n\t\t\tt = DUK_U64_CONSTANT(0x4330000000000000) | (duk_uint64_t) tv->v.fi;\n\t\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\t\treturn du.d - 4503599627370496.0;  /* 1 << 52 */\n\t\t} else {\n\t\t\tt = DUK_U64_CONSTANT(0xc330000000000000) | (duk_uint64_t) (-tv->v.fi);\n\t\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\t\treturn du.d + 4503599627370496.0;  /* 1 << 52 */\n\t\t}\n\t} else {\n\t\treturn tv->v.d;\n\t}\n}\n#endif  /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */\n#endif  /* 0 */\n\n#if defined(DUK_USE_FASTINT) && !defined(DUK_USE_PACKED_TVAL)\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_tval_get_number_unpacked_fastint(duk_tval *tv) {\n\tduk_double_union du;\n\tduk_uint64_t t;\n\n\tDUK_ASSERT(tv->t == DUK_TAG_FASTINT);\n\n\tif (tv->v.fi >= 0) {\n\t\tt = DUK_U64_CONSTANT(0x4330000000000000) | (duk_uint64_t) tv->v.fi;\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d - 4503599627370496.0;  /* 1 << 52 */\n\t} else {\n\t\tt = DUK_U64_CONSTANT(0xc330000000000000) | (duk_uint64_t) (-tv->v.fi);\n\t\tDUK_DBLUNION_SET_UINT64(&du, t);\n\t\treturn du.d + 4503599627370496.0;  /* 1 << 52 */\n\t}\n}\n#endif  /* DUK_USE_FASTINT && DUK_USE_PACKED_TVAL */\n\n#endif  /* DUK_USE_FASTINT */\n\n/*\n *  Assertion helpers.\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL void duk_tval_assert_valid(duk_tval *tv) {\n\tDUK_ASSERT(tv != NULL);\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_tval.h",
    "content": "/*\n *  Tagged type definition (duk_tval) and accessor macros.\n *\n *  Access all fields through the accessor macros, as the representation\n *  is quite tricky.\n *\n *  There are two packed type alternatives: an 8-byte representation\n *  based on an IEEE double (preferred for compactness), and a 12-byte\n *  representation (portability).  The latter is needed also in e.g.\n *  64-bit environments (it usually pads to 16 bytes per value).\n *\n *  Selecting the tagged type format involves many trade-offs (memory\n *  use, size and performance of generated code, portability, etc).\n *\n *  NB: because macro arguments are often expressions, macros should\n *  avoid evaluating their argument more than once.\n */\n\n#if !defined(DUK_TVAL_H_INCLUDED)\n#define DUK_TVAL_H_INCLUDED\n\n/* sanity */\n#if !defined(DUK_USE_DOUBLE_LE) && !defined(DUK_USE_DOUBLE_ME) && !defined(DUK_USE_DOUBLE_BE)\n#error unsupported: cannot determine byte order variant\n#endif\n\n#if defined(DUK_USE_PACKED_TVAL)\n/* ======================================================================== */\n\n/*\n *  Packed 8-byte representation\n */\n\n/* use duk_double_union as duk_tval directly */\ntypedef union duk_double_union duk_tval;\ntypedef struct {\n\tduk_uint16_t a;\n\tduk_uint16_t b;\n\tduk_uint16_t c;\n\tduk_uint16_t d;\n} duk_tval_unused;\n\n/* tags */\n#define DUK_TAG_NORMALIZED_NAN    0x7ff8UL   /* the NaN variant we use */\n/* avoid tag 0xfff0, no risk of confusion with negative infinity */\n#define DUK_TAG_MIN               0xfff1UL\n#if defined(DUK_USE_FASTINT)\n#define DUK_TAG_FASTINT           0xfff1UL   /* embed: integer value */\n#endif\n#define DUK_TAG_UNUSED            0xfff2UL   /* marker; not actual tagged value */\n#define DUK_TAG_UNDEFINED         0xfff3UL   /* embed: nothing */\n#define DUK_TAG_NULL              0xfff4UL   /* embed: nothing */\n#define DUK_TAG_BOOLEAN           0xfff5UL   /* embed: 0 or 1 (false or true) */\n/* DUK_TAG_NUMBER would logically go here, but it has multiple 'tags' */\n#define DUK_TAG_POINTER           0xfff6UL   /* embed: void ptr */\n#define DUK_TAG_LIGHTFUNC         0xfff7UL   /* embed: func ptr */\n#define DUK_TAG_STRING            0xfff8UL   /* embed: duk_hstring ptr */\n#define DUK_TAG_OBJECT            0xfff9UL   /* embed: duk_hobject ptr */\n#define DUK_TAG_BUFFER            0xfffaUL   /* embed: duk_hbuffer ptr */\n#define DUK_TAG_MAX               0xfffaUL\n\n/* for convenience */\n#define DUK_XTAG_BOOLEAN_FALSE    0xfff50000UL\n#define DUK_XTAG_BOOLEAN_TRUE     0xfff50001UL\n\n#define DUK_TVAL_IS_VALID_TAG(tv) \\\n\t(DUK_TVAL_GET_TAG((tv)) - DUK_TAG_MIN <= DUK_TAG_MAX - DUK_TAG_MIN)\n\n/* DUK_TVAL_UNUSED initializer for duk_tval_unused, works for any endianness. */\n#define DUK_TVAL_UNUSED_INITIALIZER() \\\n\t{ DUK_TAG_UNUSED, DUK_TAG_UNUSED, DUK_TAG_UNUSED, DUK_TAG_UNUSED }\n\n/* two casts to avoid gcc warning: \"warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]\" */\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) (tag)) << 16) | (((duk_uint64_t) (duk_uint32_t) (h)) << 32); \\\n\t} while (0)\n#else\n#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) (tag)) << 48) | ((duk_uint64_t) (duk_uint32_t) (h)); \\\n\t} while (0)\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n#define DUK__TVAL_SET_TAGGEDPOINTER(tv,h,tag)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) (tag)) << 16; \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (h); \\\n\t} while (0)\n#endif  /* DUK_USE_64BIT_OPS */\n\n#if defined(DUK_USE_64BIT_OPS)\n/* Double casting for pointer to avoid gcc warning (cast from pointer to integer of different size) */\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_LIGHTFUNC) << 16) | \\\n\t\t                              ((duk_uint64_t) (flags)) | \\\n\t\t                              (((duk_uint64_t) (duk_uint32_t) (fp)) << 32); \\\n\t} while (0)\n#else\n#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_LIGHTFUNC) << 48) | \\\n\t\t                              (((duk_uint64_t) (flags)) << 32) | \\\n\t\t                              ((duk_uint64_t) (duk_uint32_t) (fp)); \\\n\t} while (0)\n#endif\n#else  /* DUK_USE_64BIT_OPS */\n#define DUK__TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = (((duk_uint32_t) DUK_TAG_LIGHTFUNC) << 16) | ((duk_uint32_t) (flags)); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (fp); \\\n\t} while (0)\n#endif  /* DUK_USE_64BIT_OPS */\n\n#if defined(DUK_USE_FASTINT)\n/* Note: masking is done for 'i' to deal with negative numbers correctly */\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_SET_I48(tv,i)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) DUK_TAG_FASTINT) << 16 | (((duk_uint32_t) ((i) >> 32)) & 0x0000ffffUL); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (i); \\\n\t} while (0)\n#define DUK__TVAL_SET_U32(tv,i)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI0] = ((duk_uint32_t) DUK_TAG_FASTINT) << 16; \\\n\t\tduk__tv->ui[DUK_DBL_IDX_UI1] = (duk_uint32_t) (i); \\\n\t} while (0)\n#else\n#define DUK__TVAL_SET_I48(tv,i)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (((duk_uint64_t) (i)) & DUK_U64_CONSTANT(0x0000ffffffffffff)); \\\n\t} while (0)\n#define DUK__TVAL_SET_U32(tv,i)  do { \\\n\t\t(tv)->ull[DUK_DBL_IDX_ULL0] = (((duk_uint64_t) DUK_TAG_FASTINT) << 48) | (duk_uint64_t) (i); \\\n\t} while (0)\n#endif\n\n/* This needs to go through a cast because sign extension is needed. */\n#define DUK__TVAL_SET_I32(tv,i)  do { \\\n\t\tduk_int64_t duk__tmp = (duk_int64_t) (i); \\\n\t\tDUK_TVAL_SET_I48((tv), duk__tmp); \\\n\t} while (0)\n\n/* XXX: Clumsy sign extend and masking of 16 topmost bits. */\n#if defined(DUK_USE_DOUBLE_ME)\n#define DUK__TVAL_GET_FASTINT(tv)      (((duk_int64_t) ((((duk_uint64_t) (tv)->ui[DUK_DBL_IDX_UI0]) << 32) | ((duk_uint64_t) (tv)->ui[DUK_DBL_IDX_UI1]))) << 16 >> 16)\n#else\n#define DUK__TVAL_GET_FASTINT(tv)      ((((duk_int64_t) (tv)->ull[DUK_DBL_IDX_ULL0]) << 16) >> 16)\n#endif\n#define DUK__TVAL_GET_FASTINT_U32(tv)  ((tv)->ui[DUK_DBL_IDX_UI1])\n#define DUK__TVAL_GET_FASTINT_I32(tv)  ((duk_int32_t) (tv)->ui[DUK_DBL_IDX_UI1])\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_UNDEFINED(tv)  do { \\\n\t\t(tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNDEFINED; \\\n\t} while (0)\n#define DUK_TVAL_SET_UNUSED(tv)  do { \\\n\t\t(tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_UNUSED; \\\n\t} while (0)\n#define DUK_TVAL_SET_NULL(tv)  do { \\\n\t\t(tv)->us[DUK_DBL_IDX_US0] = (duk_uint16_t) DUK_TAG_NULL; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN(tv,val)         DUK_DBLUNION_SET_HIGH32((tv), (((duk_uint32_t) DUK_TAG_BOOLEAN) << 16) | ((duk_uint32_t) (val)))\n\n#define DUK_TVAL_SET_NAN(tv)                 DUK_DBLUNION_SET_NAN_FULL((tv))\n\n/* Assumes that caller has normalized NaNs, otherwise trouble ahead. */\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_DOUBLE(tv,d)  do { \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (d); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); \\\n\t\tDUK_DBLUNION_SET_DOUBLE((tv), duk__dblval); \\\n\t} while (0)\n#define DUK_TVAL_SET_I48(tv,i)               DUK__TVAL_SET_I48((tv), (i))\n#define DUK_TVAL_SET_I32(tv,i)               DUK__TVAL_SET_I32((tv), (i))\n#define DUK_TVAL_SET_U32(tv,i)               DUK__TVAL_SET_U32((tv), (i))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d)  duk_tval_set_number_chkfast_fast((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d)  duk_tval_set_number_chkfast_slow((tv), (d))\n#define DUK_TVAL_SET_NUMBER(tv,d)            DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#else  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_DOUBLE(tv,d)  do { \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (d); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); \\\n\t\tDUK_DBLUNION_SET_DOUBLE((tv), duk__dblval); \\\n\t} while (0)\n#define DUK_TVAL_SET_I48(tv,i)               DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i))  /* XXX: fast int-to-double */\n#define DUK_TVAL_SET_I32(tv,i)               DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i))\n#define DUK_TVAL_SET_U32(tv,i)               DUK_TVAL_SET_DOUBLE((tv), (duk_double_t) (i))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d)    DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d)    DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_SET_NUMBER(tv,d)            DUK_TVAL_SET_DOUBLE((tv), (d))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { } while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { } while (0)\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_FASTINT(tv,i)           DUK_TVAL_SET_I48((tv), (i))  /* alias */\n\n#define DUK_TVAL_SET_LIGHTFUNC(tv,fp,flags)  DUK__TVAL_SET_LIGHTFUNC((tv), (fp), (flags))\n#define DUK_TVAL_SET_STRING(tv,h)            DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_STRING)\n#define DUK_TVAL_SET_OBJECT(tv,h)            DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_OBJECT)\n#define DUK_TVAL_SET_BUFFER(tv,h)            DUK__TVAL_SET_TAGGEDPOINTER((tv), (h), DUK_TAG_BUFFER)\n#define DUK_TVAL_SET_POINTER(tv,p)           DUK__TVAL_SET_TAGGEDPOINTER((tv), (p), DUK_TAG_POINTER)\n\n#define DUK_TVAL_SET_TVAL(tv,x)              do { *(tv) = *(x); } while (0)\n\n/* getters */\n#define DUK_TVAL_GET_BOOLEAN(tv)             ((duk_small_uint_t) (tv)->us[DUK_DBL_IDX_US1])\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_GET_DOUBLE(tv)              ((tv)->d)\n#define DUK_TVAL_GET_FASTINT(tv)             DUK__TVAL_GET_FASTINT((tv))\n#define DUK_TVAL_GET_FASTINT_U32(tv)         DUK__TVAL_GET_FASTINT_U32((tv))\n#define DUK_TVAL_GET_FASTINT_I32(tv)         DUK__TVAL_GET_FASTINT_I32((tv))\n#define DUK_TVAL_GET_NUMBER(tv)              duk_tval_get_number_packed((tv))\n#else\n#define DUK_TVAL_GET_NUMBER(tv)              ((tv)->d)\n#define DUK_TVAL_GET_DOUBLE(tv)              ((tv)->d)\n#endif\n#define DUK_TVAL_GET_LIGHTFUNC(tv,out_fp,out_flags)  do { \\\n\t\t(out_flags) = (tv)->ui[DUK_DBL_IDX_UI0] & 0xffffUL; \\\n\t\t(out_fp) = (duk_c_function) (tv)->ui[DUK_DBL_IDX_UI1]; \\\n\t} while (0)\n#define DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv)   ((duk_c_function) ((tv)->ui[DUK_DBL_IDX_UI1]))\n#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv)     (((duk_small_uint_t) (tv)->ui[DUK_DBL_IDX_UI0]) & 0xffffUL)\n#define DUK_TVAL_GET_STRING(tv)              ((duk_hstring *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_OBJECT(tv)              ((duk_hobject *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_BUFFER(tv)              ((duk_hbuffer *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_POINTER(tv)             ((void *) (tv)->vp[DUK_DBL_IDX_VP1])\n#define DUK_TVAL_GET_HEAPHDR(tv)             ((duk_heaphdr *) (tv)->vp[DUK_DBL_IDX_VP1])\n\n/* decoding */\n#define DUK_TVAL_GET_TAG(tv)                 ((duk_small_uint_t) (tv)->us[DUK_DBL_IDX_US0])\n\n#define DUK_TVAL_IS_UNDEFINED(tv)            (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_UNDEFINED)\n#define DUK_TVAL_IS_UNUSED(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_UNUSED)\n#define DUK_TVAL_IS_NULL(tv)                 (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_NULL)\n#define DUK_TVAL_IS_BOOLEAN(tv)              (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_BOOLEAN)\n#define DUK_TVAL_IS_BOOLEAN_TRUE(tv)         ((tv)->ui[DUK_DBL_IDX_UI0] == DUK_XTAG_BOOLEAN_TRUE)\n#define DUK_TVAL_IS_BOOLEAN_FALSE(tv)        ((tv)->ui[DUK_DBL_IDX_UI0] == DUK_XTAG_BOOLEAN_FALSE)\n#define DUK_TVAL_IS_LIGHTFUNC(tv)            (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_LIGHTFUNC)\n#define DUK_TVAL_IS_STRING(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_STRING)\n#define DUK_TVAL_IS_OBJECT(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_OBJECT)\n#define DUK_TVAL_IS_BUFFER(tv)               (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_BUFFER)\n#define DUK_TVAL_IS_POINTER(tv)              (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_POINTER)\n#if defined(DUK_USE_FASTINT)\n/* 0xfff0 is -Infinity */\n#define DUK_TVAL_IS_DOUBLE(tv)               (DUK_TVAL_GET_TAG((tv)) <= 0xfff0UL)\n#define DUK_TVAL_IS_FASTINT(tv)              (DUK_TVAL_GET_TAG((tv)) == DUK_TAG_FASTINT)\n#define DUK_TVAL_IS_NUMBER(tv)               (DUK_TVAL_GET_TAG((tv)) <= 0xfff1UL)\n#else\n#define DUK_TVAL_IS_NUMBER(tv)               (DUK_TVAL_GET_TAG((tv)) <= 0xfff0UL)\n#define DUK_TVAL_IS_DOUBLE(tv)               DUK_TVAL_IS_NUMBER((tv))\n#endif\n\n/* This is performance critical because it appears in every DECREF. */\n#define DUK_TVAL_IS_HEAP_ALLOCATED(tv)       (DUK_TVAL_GET_TAG((tv)) >= DUK_TAG_STRING)\n\n#if defined(DUK_USE_FASTINT)\nDUK_INTERNAL_DECL duk_double_t duk_tval_get_number_packed(duk_tval *tv);\n#endif\n\n#else  /* DUK_USE_PACKED_TVAL */\n/* ======================================================================== */\n\n/*\n *  Portable 12-byte representation\n */\n\n/* Note: not initializing all bytes is normally not an issue: Duktape won't\n * read or use the uninitialized bytes so valgrind won't issue warnings.\n * In some special cases a harmless valgrind warning may be issued though.\n * For example, the DumpHeap debugger command writes out a compiled function's\n * 'data' area as is, including any uninitialized bytes, which causes a\n * valgrind warning.\n */\n\ntypedef struct duk_tval_struct duk_tval;\n\nstruct duk_tval_struct {\n\tduk_small_uint_t t;\n\tduk_small_uint_t v_extra;\n\tunion {\n\t\tduk_double_t d;\n\t\tduk_small_int_t i;\n#if defined(DUK_USE_FASTINT)\n\t\tduk_int64_t fi;  /* if present, forces 16-byte duk_tval */\n#endif\n\t\tvoid *voidptr;\n\t\tduk_hstring *hstring;\n\t\tduk_hobject *hobject;\n\t\tduk_hcompfunc *hcompfunc;\n\t\tduk_hnatfunc *hnatfunc;\n\t\tduk_hthread *hthread;\n\t\tduk_hbuffer *hbuffer;\n\t\tduk_heaphdr *heaphdr;\n\t\tduk_c_function lightfunc;\n\t} v;\n};\n\ntypedef struct {\n\tduk_small_uint_t t;\n\tduk_small_uint_t v_extra;\n\t/* The rest of the fields don't matter except for debug dumps and such\n\t * for which a partial initializer may trigger out-ot-bounds memory\n\t * reads.  Include a double field which is usually as large or larger\n\t * than pointers (not always however).\n\t */\n\tduk_double_t d;\n} duk_tval_unused;\n\n#define DUK_TVAL_UNUSED_INITIALIZER() \\\n\t{ DUK_TAG_UNUSED, 0, 0.0 }\n\n#define DUK_TAG_MIN                   0\n#define DUK_TAG_NUMBER                0  /* DUK_TAG_NUMBER only defined for non-packed duk_tval */\n#if defined(DUK_USE_FASTINT)\n#define DUK_TAG_FASTINT               1\n#endif\n#define DUK_TAG_UNDEFINED             2\n#define DUK_TAG_NULL                  3\n#define DUK_TAG_BOOLEAN               4\n#define DUK_TAG_POINTER               5\n#define DUK_TAG_LIGHTFUNC             6\n#define DUK_TAG_UNUSED                7  /* marker; not actual tagged type */\n#define DUK_TAG_STRING                8  /* first heap allocated, match bit boundary */\n#define DUK_TAG_OBJECT                9\n#define DUK_TAG_BUFFER                10\n#define DUK_TAG_MAX                   10\n\n#define DUK_TVAL_IS_VALID_TAG(tv) \\\n\t(DUK_TVAL_GET_TAG((tv)) - DUK_TAG_MIN <= DUK_TAG_MAX - DUK_TAG_MIN)\n\n/* DUK_TAG_NUMBER is intentionally first, as it is the default clause in code\n * to support the 8-byte representation.  Further, it is a non-heap-allocated\n * type so it should come before DUK_TAG_STRING.  Finally, it should not break\n * the tag value ranges covered by case-clauses in a switch-case.\n */\n\n/* setters */\n#define DUK_TVAL_SET_UNDEFINED(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_UNDEFINED; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_UNUSED(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_UNUSED; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NULL(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NULL; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BOOLEAN(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_BOOLEAN; \\\n\t\tduk__tv->v.i = (duk_small_int_t) (val); \\\n\t} while (0)\n\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_SET_DOUBLE(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (val); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); /* nop for unpacked duk_tval */ \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NUMBER; \\\n\t\tduk__tv->v.d = duk__dblval; \\\n\t} while (0)\n#define DUK_TVAL_SET_I48(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_FASTINT; \\\n\t\tduk__tv->v.fi = (val); \\\n\t} while (0)\n#define DUK_TVAL_SET_U32(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_FASTINT; \\\n\t\tduk__tv->v.fi = (duk_int64_t) (val); \\\n\t} while (0)\n#define DUK_TVAL_SET_I32(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_FASTINT; \\\n\t\tduk__tv->v.fi = (duk_int64_t) (val); \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) \\\n\tduk_tval_set_number_chkfast_fast((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) \\\n\tduk_tval_set_number_chkfast_slow((tv), (d))\n#define DUK_TVAL_SET_NUMBER(tv,val) \\\n\tDUK_TVAL_SET_DOUBLE((tv), (val))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_FAST(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__d; \\\n\t\tduk__tv = (tv); \\\n\t\tif (DUK_TVAL_IS_DOUBLE(duk__tv)) { \\\n\t\t\tduk__d = DUK_TVAL_GET_DOUBLE(duk__tv); \\\n\t\t\tDUK_TVAL_SET_NUMBER_CHKFAST_SLOW(duk__tv, duk__d); \\\n\t\t} \\\n\t} while (0)\n#else  /* DUK_USE_FASTINT */\n#define DUK_TVAL_SET_DOUBLE(tv,d) \\\n\tDUK_TVAL_SET_NUMBER((tv), (d))\n#define DUK_TVAL_SET_I48(tv,val) \\\n\tDUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val))  /* XXX: fast int-to-double */\n#define DUK_TVAL_SET_U32(tv,val) \\\n\tDUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val))\n#define DUK_TVAL_SET_I32(tv,val) \\\n\tDUK_TVAL_SET_NUMBER((tv), (duk_double_t) (val))\n#define DUK_TVAL_SET_NUMBER(tv,val)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk_double_t duk__dblval; \\\n\t\tduk__dblval = (val); \\\n\t\tDUK_ASSERT_DOUBLE_IS_NORMALIZED(duk__dblval); /* nop for unpacked duk_tval */ \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NUMBER; \\\n\t\tduk__tv->v.d = duk__dblval; \\\n\t} while (0)\n#define DUK_TVAL_SET_NUMBER_CHKFAST_FAST(tv,d) \\\n\tDUK_TVAL_SET_NUMBER((tv), (d))\n#define DUK_TVAL_SET_NUMBER_CHKFAST_SLOW(tv,d) \\\n\tDUK_TVAL_SET_NUMBER((tv), (d))\n#define DUK_TVAL_CHKFAST_INPLACE_FAST(tv)  do { } while (0)\n#define DUK_TVAL_CHKFAST_INPLACE_SLOW(tv)  do { } while (0)\n#endif  /* DUK_USE_FASTINT */\n\n#define DUK_TVAL_SET_FASTINT(tv,i) \\\n\tDUK_TVAL_SET_I48((tv), (i))  /* alias */\n\n#define DUK_TVAL_SET_POINTER(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_POINTER; \\\n\t\tduk__tv->v.voidptr = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_LIGHTFUNC(tv,fp,flags)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_LIGHTFUNC; \\\n\t\tduk__tv->v_extra = (flags); \\\n\t\tduk__tv->v.lightfunc = (duk_c_function) (fp); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_STRING(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_STRING; \\\n\t\tduk__tv->v.hstring = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_OBJECT(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_OBJECT; \\\n\t\tduk__tv->v.hobject = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_BUFFER(tv,hptr)  do { \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_BUFFER; \\\n\t\tduk__tv->v.hbuffer = (hptr); \\\n\t} while (0)\n\n#define DUK_TVAL_SET_NAN(tv)  do { \\\n\t\t/* in non-packed representation we don't care about which NaN is used */ \\\n\t\tduk_tval *duk__tv; \\\n\t\tduk__tv = (tv); \\\n\t\tduk__tv->t = DUK_TAG_NUMBER; \\\n\t\tduk__tv->v.d = DUK_DOUBLE_NAN; \\\n\t} while (0)\n\n#define DUK_TVAL_SET_TVAL(tv,x)            do { *(tv) = *(x); } while (0)\n\n/* getters */\n#define DUK_TVAL_GET_BOOLEAN(tv)           ((duk_small_uint_t) (tv)->v.i)\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_GET_DOUBLE(tv)            ((tv)->v.d)\n#define DUK_TVAL_GET_FASTINT(tv)           ((tv)->v.fi)\n#define DUK_TVAL_GET_FASTINT_U32(tv)       ((duk_uint32_t) ((tv)->v.fi))\n#define DUK_TVAL_GET_FASTINT_I32(tv)       ((duk_int32_t) ((tv)->v.fi))\n#if 0\n#define DUK_TVAL_GET_NUMBER(tv)            (DUK_TVAL_IS_FASTINT((tv)) ? \\\n                                               (duk_double_t) DUK_TVAL_GET_FASTINT((tv)) : \\\n                                               DUK_TVAL_GET_DOUBLE((tv)))\n#define DUK_TVAL_GET_NUMBER(tv)            duk_tval_get_number_unpacked((tv))\n#else\n/* This seems reasonable overall. */\n#define DUK_TVAL_GET_NUMBER(tv)            (DUK_TVAL_IS_FASTINT((tv)) ? \\\n                                               duk_tval_get_number_unpacked_fastint((tv)) : \\\n                                               DUK_TVAL_GET_DOUBLE((tv)))\n#endif\n#else\n#define DUK_TVAL_GET_NUMBER(tv)            ((tv)->v.d)\n#define DUK_TVAL_GET_DOUBLE(tv)            ((tv)->v.d)\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_GET_POINTER(tv)           ((tv)->v.voidptr)\n#define DUK_TVAL_GET_LIGHTFUNC(tv,out_fp,out_flags)  do { \\\n\t\t(out_flags) = (duk_uint32_t) (tv)->v_extra; \\\n\t\t(out_fp) = (tv)->v.lightfunc; \\\n\t} while (0)\n#define DUK_TVAL_GET_LIGHTFUNC_FUNCPTR(tv) ((tv)->v.lightfunc)\n#define DUK_TVAL_GET_LIGHTFUNC_FLAGS(tv)   ((duk_small_uint_t) ((tv)->v_extra))\n#define DUK_TVAL_GET_STRING(tv)            ((tv)->v.hstring)\n#define DUK_TVAL_GET_OBJECT(tv)            ((tv)->v.hobject)\n#define DUK_TVAL_GET_BUFFER(tv)            ((tv)->v.hbuffer)\n#define DUK_TVAL_GET_HEAPHDR(tv)           ((tv)->v.heaphdr)\n\n/* decoding */\n#define DUK_TVAL_GET_TAG(tv)               ((tv)->t)\n#define DUK_TVAL_IS_UNDEFINED(tv)          ((tv)->t == DUK_TAG_UNDEFINED)\n#define DUK_TVAL_IS_UNUSED(tv)             ((tv)->t == DUK_TAG_UNUSED)\n#define DUK_TVAL_IS_NULL(tv)               ((tv)->t == DUK_TAG_NULL)\n#define DUK_TVAL_IS_BOOLEAN(tv)            ((tv)->t == DUK_TAG_BOOLEAN)\n#define DUK_TVAL_IS_BOOLEAN_TRUE(tv)       (((tv)->t == DUK_TAG_BOOLEAN) && ((tv)->v.i != 0))\n#define DUK_TVAL_IS_BOOLEAN_FALSE(tv)      (((tv)->t == DUK_TAG_BOOLEAN) && ((tv)->v.i == 0))\n#if defined(DUK_USE_FASTINT)\n#define DUK_TVAL_IS_DOUBLE(tv)             ((tv)->t == DUK_TAG_NUMBER)\n#define DUK_TVAL_IS_FASTINT(tv)            ((tv)->t == DUK_TAG_FASTINT)\n#define DUK_TVAL_IS_NUMBER(tv)             ((tv)->t == DUK_TAG_NUMBER || \\\n                                            (tv)->t == DUK_TAG_FASTINT)\n#else\n#define DUK_TVAL_IS_NUMBER(tv)             ((tv)->t == DUK_TAG_NUMBER)\n#define DUK_TVAL_IS_DOUBLE(tv)             DUK_TVAL_IS_NUMBER((tv))\n#endif  /* DUK_USE_FASTINT */\n#define DUK_TVAL_IS_POINTER(tv)            ((tv)->t == DUK_TAG_POINTER)\n#define DUK_TVAL_IS_LIGHTFUNC(tv)          ((tv)->t == DUK_TAG_LIGHTFUNC)\n#define DUK_TVAL_IS_STRING(tv)             ((tv)->t == DUK_TAG_STRING)\n#define DUK_TVAL_IS_OBJECT(tv)             ((tv)->t == DUK_TAG_OBJECT)\n#define DUK_TVAL_IS_BUFFER(tv)             ((tv)->t == DUK_TAG_BUFFER)\n\n/* This is performance critical because it's needed for every DECREF.\n * Take advantage of the fact that the first heap allocated tag is 8,\n * so that bit 3 is set for all heap allocated tags (and never set for\n * non-heap-allocated tags).\n */\n#if 0\n#define DUK_TVAL_IS_HEAP_ALLOCATED(tv)     ((tv)->t >= DUK_TAG_STRING)\n#endif\n#define DUK_TVAL_IS_HEAP_ALLOCATED(tv)     ((tv)->t & 0x08)\n\n#if defined(DUK_USE_FASTINT)\n#if 0\nDUK_INTERNAL_DECL duk_double_t duk_tval_get_number_unpacked(duk_tval *tv);\n#endif\nDUK_INTERNAL_DECL duk_double_t duk_tval_get_number_unpacked_fastint(duk_tval *tv);\n#endif\n\n#endif  /* DUK_USE_PACKED_TVAL */\n\n/*\n *  Convenience (independent of representation)\n */\n\n#define DUK_TVAL_SET_BOOLEAN_TRUE(tv)        DUK_TVAL_SET_BOOLEAN((tv), 1)\n#define DUK_TVAL_SET_BOOLEAN_FALSE(tv)       DUK_TVAL_SET_BOOLEAN((tv), 0)\n\n#define DUK_TVAL_STRING_IS_SYMBOL(tv) \\\n\tDUK_HSTRING_HAS_SYMBOL(DUK_TVAL_GET_STRING((tv)))\n\n/* Lightfunc flags packing and unpacking. */\n/* Sign extend: 0x0000##00 -> 0x##000000 -> sign extend to 0xssssss##.\n * Avoid signed shifts due to portability limitations.\n */\n#define DUK_LFUNC_FLAGS_GET_MAGIC(lf_flags) \\\n\t((duk_int32_t) (duk_int8_t) (((duk_uint16_t) (lf_flags)) >> 8))\n#define DUK_LFUNC_FLAGS_GET_LENGTH(lf_flags) \\\n\t(((lf_flags) >> 4) & 0x0fU)\n#define DUK_LFUNC_FLAGS_GET_NARGS(lf_flags) \\\n\t((lf_flags) & 0x0fU)\n#define DUK_LFUNC_FLAGS_PACK(magic,length,nargs) \\\n\t((((duk_small_uint_t) (magic)) & 0xffU) << 8) | ((length) << 4) | (nargs)\n\n#define DUK_LFUNC_NARGS_VARARGS             0x0f   /* varargs marker */\n#define DUK_LFUNC_NARGS_MIN                 0x00\n#define DUK_LFUNC_NARGS_MAX                 0x0e   /* max, excl. varargs marker */\n#define DUK_LFUNC_LENGTH_MIN                0x00\n#define DUK_LFUNC_LENGTH_MAX                0x0f\n#define DUK_LFUNC_MAGIC_MIN                 (-0x80)\n#define DUK_LFUNC_MAGIC_MAX                 0x7f\n\n/* fastint constants etc */\n#if defined(DUK_USE_FASTINT)\n#define DUK_FASTINT_MIN           (DUK_I64_CONSTANT(-0x800000000000))\n#define DUK_FASTINT_MAX           (DUK_I64_CONSTANT(0x7fffffffffff))\n#define DUK_FASTINT_BITS          48\n\nDUK_INTERNAL_DECL void duk_tval_set_number_chkfast_fast(duk_tval *tv, duk_double_t x);\nDUK_INTERNAL_DECL void duk_tval_set_number_chkfast_slow(duk_tval *tv, duk_double_t x);\n#endif\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_tval_assert_valid(duk_tval *tv);\n#define DUK_TVAL_ASSERT_VALID(tv)  do { duk_tval_assert_valid((tv)); } while (0)\n#else\n#define DUK_TVAL_ASSERT_VALID(tv)  do {} while (0)\n#endif\n\n#endif  /* DUK_TVAL_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_unicode.h",
    "content": "/*\n *  Unicode helpers\n */\n\n#if !defined(DUK_UNICODE_H_INCLUDED)\n#define DUK_UNICODE_H_INCLUDED\n\n/*\n *  UTF-8 / XUTF-8 / CESU-8 constants\n */\n\n#define DUK_UNICODE_MAX_XUTF8_LENGTH      7   /* up to 36 bit codepoints */\n#define DUK_UNICODE_MAX_XUTF8_BMP_LENGTH  3   /* all codepoints up to U+FFFF */\n#define DUK_UNICODE_MAX_CESU8_LENGTH      6   /* all codepoints up to U+10FFFF */\n#define DUK_UNICODE_MAX_CESU8_BMP_LENGTH  3   /* all codepoints up to U+FFFF */\n\n/*\n *  Useful Unicode codepoints\n *\n *  Integer constants must be signed to avoid unexpected coercions\n *  in comparisons.\n */\n\n#define DUK_UNICODE_CP_ZWNJ                   0x200cL  /* zero-width non-joiner */\n#define DUK_UNICODE_CP_ZWJ                    0x200dL  /* zero-width joiner */\n#define DUK_UNICODE_CP_REPLACEMENT_CHARACTER  0xfffdL  /* http://en.wikipedia.org/wiki/Replacement_character#Replacement_character */\n\n/*\n *  ASCII character constants\n *\n *  C character literals like 'x' have a platform specific value and do\n *  not match ASCII (UTF-8) values on e.g. EBCDIC platforms.  So, use\n *  these (admittedly awkward) constants instead.  These constants must\n *  also have signed values to avoid unexpected coercions in comparisons.\n *\n *  http://en.wikipedia.org/wiki/ASCII\n */\n\n#define DUK_ASC_NUL              0x00\n#define DUK_ASC_SOH              0x01\n#define DUK_ASC_STX              0x02\n#define DUK_ASC_ETX              0x03\n#define DUK_ASC_EOT              0x04\n#define DUK_ASC_ENQ              0x05\n#define DUK_ASC_ACK              0x06\n#define DUK_ASC_BEL              0x07\n#define DUK_ASC_BS               0x08\n#define DUK_ASC_HT               0x09\n#define DUK_ASC_LF               0x0a\n#define DUK_ASC_VT               0x0b\n#define DUK_ASC_FF               0x0c\n#define DUK_ASC_CR               0x0d\n#define DUK_ASC_SO               0x0e\n#define DUK_ASC_SI               0x0f\n#define DUK_ASC_DLE              0x10\n#define DUK_ASC_DC1              0x11\n#define DUK_ASC_DC2              0x12\n#define DUK_ASC_DC3              0x13\n#define DUK_ASC_DC4              0x14\n#define DUK_ASC_NAK              0x15\n#define DUK_ASC_SYN              0x16\n#define DUK_ASC_ETB              0x17\n#define DUK_ASC_CAN              0x18\n#define DUK_ASC_EM               0x19\n#define DUK_ASC_SUB              0x1a\n#define DUK_ASC_ESC              0x1b\n#define DUK_ASC_FS               0x1c\n#define DUK_ASC_GS               0x1d\n#define DUK_ASC_RS               0x1e\n#define DUK_ASC_US               0x1f\n#define DUK_ASC_SPACE            0x20\n#define DUK_ASC_EXCLAMATION      0x21\n#define DUK_ASC_DOUBLEQUOTE      0x22\n#define DUK_ASC_HASH             0x23\n#define DUK_ASC_DOLLAR           0x24\n#define DUK_ASC_PERCENT          0x25\n#define DUK_ASC_AMP              0x26\n#define DUK_ASC_SINGLEQUOTE      0x27\n#define DUK_ASC_LPAREN           0x28\n#define DUK_ASC_RPAREN           0x29\n#define DUK_ASC_STAR             0x2a\n#define DUK_ASC_PLUS             0x2b\n#define DUK_ASC_COMMA            0x2c\n#define DUK_ASC_MINUS            0x2d\n#define DUK_ASC_PERIOD           0x2e\n#define DUK_ASC_SLASH            0x2f\n#define DUK_ASC_0                0x30\n#define DUK_ASC_1                0x31\n#define DUK_ASC_2                0x32\n#define DUK_ASC_3                0x33\n#define DUK_ASC_4                0x34\n#define DUK_ASC_5                0x35\n#define DUK_ASC_6                0x36\n#define DUK_ASC_7                0x37\n#define DUK_ASC_8                0x38\n#define DUK_ASC_9                0x39\n#define DUK_ASC_COLON            0x3a\n#define DUK_ASC_SEMICOLON        0x3b\n#define DUK_ASC_LANGLE           0x3c\n#define DUK_ASC_EQUALS           0x3d\n#define DUK_ASC_RANGLE           0x3e\n#define DUK_ASC_QUESTION         0x3f\n#define DUK_ASC_ATSIGN           0x40\n#define DUK_ASC_UC_A             0x41\n#define DUK_ASC_UC_B             0x42\n#define DUK_ASC_UC_C             0x43\n#define DUK_ASC_UC_D             0x44\n#define DUK_ASC_UC_E             0x45\n#define DUK_ASC_UC_F             0x46\n#define DUK_ASC_UC_G             0x47\n#define DUK_ASC_UC_H             0x48\n#define DUK_ASC_UC_I             0x49\n#define DUK_ASC_UC_J             0x4a\n#define DUK_ASC_UC_K             0x4b\n#define DUK_ASC_UC_L             0x4c\n#define DUK_ASC_UC_M             0x4d\n#define DUK_ASC_UC_N             0x4e\n#define DUK_ASC_UC_O             0x4f\n#define DUK_ASC_UC_P             0x50\n#define DUK_ASC_UC_Q             0x51\n#define DUK_ASC_UC_R             0x52\n#define DUK_ASC_UC_S             0x53\n#define DUK_ASC_UC_T             0x54\n#define DUK_ASC_UC_U             0x55\n#define DUK_ASC_UC_V             0x56\n#define DUK_ASC_UC_W             0x57\n#define DUK_ASC_UC_X             0x58\n#define DUK_ASC_UC_Y             0x59\n#define DUK_ASC_UC_Z             0x5a\n#define DUK_ASC_LBRACKET         0x5b\n#define DUK_ASC_BACKSLASH        0x5c\n#define DUK_ASC_RBRACKET         0x5d\n#define DUK_ASC_CARET            0x5e\n#define DUK_ASC_UNDERSCORE       0x5f\n#define DUK_ASC_GRAVE            0x60\n#define DUK_ASC_LC_A             0x61\n#define DUK_ASC_LC_B             0x62\n#define DUK_ASC_LC_C             0x63\n#define DUK_ASC_LC_D             0x64\n#define DUK_ASC_LC_E             0x65\n#define DUK_ASC_LC_F             0x66\n#define DUK_ASC_LC_G             0x67\n#define DUK_ASC_LC_H             0x68\n#define DUK_ASC_LC_I             0x69\n#define DUK_ASC_LC_J             0x6a\n#define DUK_ASC_LC_K             0x6b\n#define DUK_ASC_LC_L             0x6c\n#define DUK_ASC_LC_M             0x6d\n#define DUK_ASC_LC_N             0x6e\n#define DUK_ASC_LC_O             0x6f\n#define DUK_ASC_LC_P             0x70\n#define DUK_ASC_LC_Q             0x71\n#define DUK_ASC_LC_R             0x72\n#define DUK_ASC_LC_S             0x73\n#define DUK_ASC_LC_T             0x74\n#define DUK_ASC_LC_U             0x75\n#define DUK_ASC_LC_V             0x76\n#define DUK_ASC_LC_W             0x77\n#define DUK_ASC_LC_X             0x78\n#define DUK_ASC_LC_Y             0x79\n#define DUK_ASC_LC_Z             0x7a\n#define DUK_ASC_LCURLY           0x7b\n#define DUK_ASC_PIPE             0x7c\n#define DUK_ASC_RCURLY           0x7d\n#define DUK_ASC_TILDE            0x7e\n#define DUK_ASC_DEL              0x7f\n\n/*\n *  Miscellaneous\n */\n\n/* Uppercase A is 0x41, lowercase a is 0x61; OR 0x20 to convert uppercase\n * to lowercase.\n */\n#define DUK_LOWERCASE_CHAR_ASCII(x)  ((x) | 0x20)\n\n/*\n *  Unicode tables\n */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_ids_noa[1116];\n#else\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_ids_noabmp[625];\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_ids_m_let_noa[42];\n#else\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_ids_m_let_noabmp[24];\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_idp_m_ids_noa[576];\n#else\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_idp_m_ids_noabmp[358];\n#endif\n\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\nextern const duk_uint8_t duk_unicode_caseconv_uc[1411];\nextern const duk_uint8_t duk_unicode_caseconv_lc[706];\n\n#if defined(DUK_USE_REGEXP_CANON_WORKAROUND)\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\nextern const duk_uint16_t duk_unicode_re_canon_lookup[65536];\n#endif\n\n#if defined(DUK_USE_REGEXP_CANON_BITMAP)\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\n#define DUK_CANON_BITMAP_BLKSIZE                                      32\n#define DUK_CANON_BITMAP_BLKSHIFT                                     5\n#define DUK_CANON_BITMAP_BLKMASK                                      31\nextern const duk_uint8_t duk_unicode_re_canon_bitmap[256];\n#endif\n\n/*\n *  Extern\n */\n\n/* duk_unicode_support.c */\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_unicode_xutf8_markers[7];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_digit[2];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_white[22];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_wordchar[8];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_not_digit[4];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_not_white[24];\nDUK_INTERNAL_DECL const duk_uint16_t duk_unicode_re_ranges_not_wordchar[10];\nDUK_INTERNAL_DECL const duk_int8_t duk_is_idchar_tab[128];\n#endif  /* !DUK_SINGLE_FILE */\n\n/*\n *  Prototypes\n */\n\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_get_xutf8_length(duk_ucodepoint_t cp);\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_get_cesu8_length(duk_ucodepoint_t cp);\n#endif\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_encode_xutf8(duk_ucodepoint_t cp, duk_uint8_t *out);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_encode_cesu8(duk_ucodepoint_t cp, duk_uint8_t *out);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_decode_xutf8(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_ucodepoint_t *out_cp);\nDUK_INTERNAL_DECL duk_ucodepoint_t duk_unicode_decode_xutf8_checked(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end);\nDUK_INTERNAL_DECL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_whitespace(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_line_terminator(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_identifier_start(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_identifier_part(duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_is_letter(duk_codepoint_t cp);\nDUK_INTERNAL_DECL void duk_unicode_case_convert_string(duk_hthread *thr, duk_bool_t uppercase);\n#if defined(DUK_USE_REGEXP_SUPPORT)\nDUK_INTERNAL_DECL duk_codepoint_t duk_unicode_re_canonicalize_char(duk_hthread *thr, duk_codepoint_t cp);\nDUK_INTERNAL_DECL duk_small_int_t duk_unicode_re_is_wordchar(duk_codepoint_t cp);\n#endif\n\n#endif  /* DUK_UNICODE_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_unicode_support.c",
    "content": "/*\n *  Various Unicode help functions for character classification predicates,\n *  case conversion, decoding, etc.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Fast path tables\n */\n\n#if defined(DUK_USE_IDCHAR_FASTPATH)\nDUK_INTERNAL const duk_int8_t duk_is_idchar_tab[128] = {\n\t/* 0: not IdentifierStart or IdentifierPart\n\t * 1: IdentifierStart and IdentifierPart\n\t * -1: IdentifierPart only\n\t */\n\t0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   /* 0x00...0x0f */\n\t0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   /* 0x10...0x1f */\n\t0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,   /* 0x20...0x2f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0,  0,  0,  0,  0,  0,   /* 0x30...0x3f */\n\t0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,   /* 0x40...0x4f */\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  1,   /* 0x50...0x5f */\n\t0,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,   /* 0x60...0x6f */\n\t1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0    /* 0x70...0x7f */\n};\n#endif\n\n/*\n *  XUTF-8 and CESU-8 encoding/decoding\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_get_xutf8_length(duk_ucodepoint_t cp) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tif (x < 0x80UL) {\n\t\t/* 7 bits */\n\t\treturn 1;\n\t} else if (x < 0x800UL) {\n\t\t/* 11 bits */\n\t\treturn 2;\n\t} else if (x < 0x10000UL) {\n\t\t/* 16 bits */\n\t\treturn 3;\n\t} else if (x < 0x200000UL) {\n\t\t/* 21 bits */\n\t\treturn 4;\n\t} else if (x < 0x4000000UL) {\n\t\t/* 26 bits */\n\t\treturn 5;\n\t} else if (x < (duk_ucodepoint_t) 0x80000000UL) {\n\t\t/* 31 bits */\n\t\treturn 6;\n\t} else {\n\t\t/* 36 bits */\n\t\treturn 7;\n\t}\n}\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL duk_small_int_t duk_unicode_get_cesu8_length(duk_ucodepoint_t cp) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tif (x < 0x80UL) {\n\t\t/* 7 bits */\n\t\treturn 1;\n\t} else if (x < 0x800UL) {\n\t\t/* 11 bits */\n\t\treturn 2;\n\t} else if (x < 0x10000UL) {\n\t\t/* 16 bits */\n\t\treturn 3;\n\t} else {\n\t\t/* Encoded as surrogate pair, each encoding to 3 bytes for\n\t\t * 6 bytes total.  Codepoints above U+10FFFF encode as 6 bytes\n\t\t * too, see duk_unicode_encode_cesu8().\n\t\t  */\n\t\treturn 3 + 3;\n\t}\n}\n#endif  /* DUK_USE_ASSERTIONS */\n\nDUK_INTERNAL const duk_uint8_t duk_unicode_xutf8_markers[7] = {\n\t0x00, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe\n};\n\n/* Encode to extended UTF-8; 'out' must have space for at least\n * DUK_UNICODE_MAX_XUTF8_LENGTH bytes.  Allows encoding of any\n * 32-bit (unsigned) codepoint.\n */\nDUK_INTERNAL duk_small_int_t duk_unicode_encode_xutf8(duk_ucodepoint_t cp, duk_uint8_t *out) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tduk_small_int_t len;\n\tduk_uint8_t marker;\n\tduk_small_int_t i;\n\n\tlen = duk_unicode_get_xutf8_length(cp);\n\tDUK_ASSERT(len > 0);\n\n\tmarker = duk_unicode_xutf8_markers[len - 1];  /* 64-bit OK because always >= 0 */\n\n\ti = len;\n\tDUK_ASSERT(i > 0);\n\tdo {\n\t\ti--;\n\t\tif (i > 0) {\n\t\t\tout[i] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\t\tx >>= 6;\n\t\t} else {\n\t\t\t/* Note: masking of 'x' is not necessary because of\n\t\t\t * range check and shifting -> no bits overlapping\n\t\t\t * the marker should be set.\n\t\t\t */\n\t\t\tout[0] = (duk_uint8_t) (marker + x);\n\t\t}\n\t} while (i > 0);\n\n\treturn len;\n}\n\n/* Encode to CESU-8; 'out' must have space for at least\n * DUK_UNICODE_MAX_CESU8_LENGTH bytes; codepoints above U+10FFFF\n * will encode to garbage but won't overwrite the output buffer.\n */\nDUK_INTERNAL duk_small_int_t duk_unicode_encode_cesu8(duk_ucodepoint_t cp, duk_uint8_t *out) {\n\tduk_uint_fast32_t x = (duk_uint_fast32_t) cp;\n\tduk_small_int_t len;\n\n\tif (x < 0x80UL) {\n\t\tout[0] = (duk_uint8_t) x;\n\t\tlen = 1;\n\t} else if (x < 0x800UL) {\n\t\tout[0] = (duk_uint8_t) (0xc0 + ((x >> 6) & 0x1f));\n\t\tout[1] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\tlen = 2;\n\t} else if (x < 0x10000UL) {\n\t\t/* surrogate pairs get encoded here */\n\t\tout[0] = (duk_uint8_t) (0xe0 + ((x >> 12) & 0x0f));\n\t\tout[1] = (duk_uint8_t) (0x80 + ((x >> 6) & 0x3f));\n\t\tout[2] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\tlen = 3;\n\t} else {\n\t\t/*\n\t\t *  Unicode codepoints above U+FFFF are encoded as surrogate\n\t\t *  pairs here.  This ensures that all CESU-8 codepoints are\n\t\t *  16-bit values as expected in ECMAScript.  The surrogate\n\t\t *  pairs always get a 3-byte encoding (each) in CESU-8.\n\t\t *  See: http://en.wikipedia.org/wiki/Surrogate_pair\n\t\t *\n\t\t *  20-bit codepoint, 10 bits (A and B) per surrogate pair:\n\t\t *\n\t\t *    x = 0b00000000 0000AAAA AAAAAABB BBBBBBBB\n\t\t *  sp1 = 0b110110AA AAAAAAAA  (0xd800 + ((x >> 10) & 0x3ff))\n\t\t *  sp2 = 0b110111BB BBBBBBBB  (0xdc00 + (x & 0x3ff))\n\t\t *\n\t\t *  Encoded into CESU-8:\n\t\t *\n\t\t *  sp1 -> 0b11101101  (0xe0 + ((sp1 >> 12) & 0x0f))\n\t\t *      -> 0b1010AAAA  (0x80 + ((sp1 >> 6) & 0x3f))\n\t\t *      -> 0b10AAAAAA  (0x80 + (sp1 & 0x3f))\n\t\t *  sp2 -> 0b11101101  (0xe0 + ((sp2 >> 12) & 0x0f))\n\t\t *      -> 0b1011BBBB  (0x80 + ((sp2 >> 6) & 0x3f))\n\t\t *      -> 0b10BBBBBB  (0x80 + (sp2 & 0x3f))\n\t\t *\n\t\t *  Note that 0x10000 must be subtracted first.  The code below\n\t\t *  avoids the sp1, sp2 temporaries which saves around 20 bytes\n\t\t *  of code.\n\t\t */\n\n\t\tx -= 0x10000UL;\n\n\t\tout[0] = (duk_uint8_t) (0xed);\n\t\tout[1] = (duk_uint8_t) (0xa0 + ((x >> 16) & 0x0f));\n\t\tout[2] = (duk_uint8_t) (0x80 + ((x >> 10) & 0x3f));\n\t\tout[3] = (duk_uint8_t) (0xed);\n\t\tout[4] = (duk_uint8_t) (0xb0 + ((x >> 6) & 0x0f));\n\t\tout[5] = (duk_uint8_t) (0x80 + (x & 0x3f));\n\t\tlen = 6;\n\t}\n\n\treturn len;\n}\n\n/* Decode helper.  Return zero on error. */\nDUK_INTERNAL duk_small_int_t duk_unicode_decode_xutf8(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end, duk_ucodepoint_t *out_cp) {\n\tconst duk_uint8_t *p;\n\tduk_uint32_t res;\n\tduk_uint_fast8_t ch;\n\tduk_small_int_t n;\n\n\tDUK_UNREF(thr);\n\n\tp = *ptr;\n\tif (p < ptr_start || p >= ptr_end) {\n\t\tgoto fail;\n\t}\n\n\t/*\n\t *  UTF-8 decoder which accepts longer than standard byte sequences.\n\t *  This allows full 32-bit code points to be used.\n\t */\n\n\tch = (duk_uint_fast8_t) (*p++);\n\tif (ch < 0x80) {\n\t\t/* 0xxx xxxx   [7 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x7f);\n\t\tn = 0;\n\t} else if (ch < 0xc0) {\n\t\t/* 10xx xxxx -> invalid */\n\t\tgoto fail;\n\t} else if (ch < 0xe0) {\n\t\t/* 110x xxxx   10xx xxxx   [11 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x1f);\n\t\tn = 1;\n\t} else if (ch < 0xf0) {\n\t\t/* 1110 xxxx   10xx xxxx   10xx xxxx   [16 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x0f);\n\t\tn = 2;\n\t} else if (ch < 0xf8) {\n\t\t/* 1111 0xxx   10xx xxxx   10xx xxxx   10xx xxxx   [21 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x07);\n\t\tn = 3;\n\t} else if (ch < 0xfc) {\n\t\t/* 1111 10xx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [26 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x03);\n\t\tn = 4;\n\t} else if (ch < 0xfe) {\n\t\t/* 1111 110x   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [31 bits] */\n\t\tres = (duk_uint32_t) (ch & 0x01);\n\t\tn = 5;\n\t} else if (ch < 0xff) {\n\t\t/* 1111 1110   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [36 bits] */\n\t\tres = (duk_uint32_t) (0);\n\t\tn = 6;\n\t} else {\n\t\t/* 8-byte format could be:\n\t\t * 1111 1111   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   10xx xxxx   [41 bits]\n\t\t *\n\t\t * However, this format would not have a zero bit following the\n\t\t * leading one bits and would not allow 0xFF to be used as an\n\t\t * \"invalid xutf-8\" marker for internal keys.  Further, 8-byte\n\t\t * encodings (up to 41 bit code points) are not currently needed.\n\t\t */\n\t\tgoto fail;\n\t}\n\n\tDUK_ASSERT(p >= ptr_start);  /* verified at beginning */\n\tif (p + n > ptr_end) {\n\t\t/* check pointer at end */\n\t\tgoto fail;\n\t}\n\n\twhile (n > 0) {\n\t\tDUK_ASSERT(p >= ptr_start && p < ptr_end);\n\t\tch = (duk_uint_fast8_t) (*p++);\n#if 0\n\t\tif (ch & 0xc0 != 0x80) {\n\t\t\t/* not a continuation byte */\n\t\t\tp--;\n\t\t\t*ptr = p;\n\t\t\t*out_cp = DUK_UNICODE_CP_REPLACEMENT_CHARACTER;\n\t\t\treturn 1;\n\t\t}\n#endif\n\t\tres = (res << 6) + (duk_uint32_t) (ch & 0x3f);\n\t\tn--;\n\t}\n\n\t*ptr = p;\n\t*out_cp = res;\n\treturn 1;\n\n fail:\n\treturn 0;\n}\n\n/* used by e.g. duk_regexp_executor.c, string built-ins */\nDUK_INTERNAL duk_ucodepoint_t duk_unicode_decode_xutf8_checked(duk_hthread *thr, const duk_uint8_t **ptr, const duk_uint8_t *ptr_start, const duk_uint8_t *ptr_end) {\n\tduk_ucodepoint_t cp;\n\n\tif (duk_unicode_decode_xutf8(thr, ptr, ptr_start, ptr_end, &cp)) {\n\t\treturn cp;\n\t}\n\tDUK_ERROR_INTERNAL(thr);\n\tDUK_WO_NORETURN(return 0;);\n}\n\n/* Compute (extended) utf-8 length without codepoint encoding validation,\n * used for string interning.\n *\n * NOTE: This algorithm is performance critical, more so than string hashing\n * in some cases.  It is needed when interning a string and needs to scan\n * every byte of the string with no skipping.  Having an ASCII fast path\n * is useful if possible in the algorithm.  The current algorithms were\n * chosen from several variants, based on x64 gcc -O2 testing.  See:\n * https://github.com/svaarala/duktape/pull/422\n *\n * NOTE: must match tools/dukutil.py:duk_unicode_unvalidated_utf8_length().\n */\n\n#if defined(DUK_USE_PREFER_SIZE)\n/* Small variant; roughly 150 bytes smaller than the fast variant. */\nDUK_INTERNAL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tduk_size_t ncont;\n\tduk_size_t clen;\n\n\tp = data;\n\tp_end = data + blen;\n\tncont = 0;\n\twhile (p != p_end) {\n\t\tduk_uint8_t x;\n\t\tx = *p++;\n\t\tif (DUK_UNLIKELY(x >= 0x80 && x <= 0xbf)) {\n\t\t\tncont++;\n\t\t}\n\t}\n\n\tDUK_ASSERT(ncont <= blen);\n\tclen = blen - ncont;\n\tDUK_ASSERT(clen <= blen);\n\treturn clen;\n}\n#else  /* DUK_USE_PREFER_SIZE */\n/* This seems like a good overall approach.  Fast path for ASCII in 4 byte\n * blocks.\n */\nDUK_INTERNAL duk_size_t duk_unicode_unvalidated_utf8_length(const duk_uint8_t *data, duk_size_t blen) {\n\tconst duk_uint8_t *p;\n\tconst duk_uint8_t *p_end;\n\tconst duk_uint32_t *p32_end;\n\tconst duk_uint32_t *p32;\n\tduk_size_t ncont;\n\tduk_size_t clen;\n\n\tncont = 0;  /* number of continuation (non-initial) bytes in [0x80,0xbf] */\n\tp = data;\n\tp_end = data + blen;\n\tif (blen < 16) {\n\t\tgoto skip_fastpath;\n\t}\n\n\t/* Align 'p' to 4; the input data may have arbitrary alignment.\n\t * End of string check not needed because blen >= 16.\n\t */\n\twhile (((duk_size_t) (const void *) p) & 0x03U) {\n\t\tduk_uint8_t x;\n\t\tx = *p++;\n\t\tif (DUK_UNLIKELY(x >= 0x80 && x <= 0xbf)) {\n\t\t\tncont++;\n\t\t}\n\t}\n\n\t/* Full, aligned 4-byte reads. */\n\tp32_end = (const duk_uint32_t *) (const void *) (p + ((duk_size_t) (p_end - p) & (duk_size_t) (~0x03)));\n\tp32 = (const duk_uint32_t *) (const void *) p;\n\twhile (p32 != (const duk_uint32_t *) p32_end) {\n\t\tduk_uint32_t x;\n\t\tx = *p32++;\n\t\tif (DUK_LIKELY((x & 0x80808080UL) == 0)) {\n\t\t\t;  /* ASCII fast path */\n\t\t} else {\n\t\t\t/* Flip highest bit of each byte which changes\n\t\t\t * the bit pattern 10xxxxxx into 00xxxxxx which\n\t\t\t * allows an easy bit mask test.\n\t\t\t */\n\t\t\tx ^= 0x80808080UL;\n\t\t\tif (DUK_UNLIKELY(!(x & 0xc0000000UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(!(x & 0x00c00000UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(!(x & 0x0000c000UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t\tif (DUK_UNLIKELY(!(x & 0x000000c0UL))) {\n\t\t\t\tncont++;\n\t\t\t}\n\t\t}\n\t}\n\tp = (const duk_uint8_t *) p32;\n\t/* Fall through to handle the rest. */\n\n skip_fastpath:\n\twhile (p != p_end) {\n\t\tduk_uint8_t x;\n\t\tx = *p++;\n\t\tif (DUK_UNLIKELY(x >= 0x80 && x <= 0xbf)) {\n\t\t\tncont++;\n\t\t}\n\t}\n\n\tDUK_ASSERT(ncont <= blen);\n\tclen = blen - ncont;\n\tDUK_ASSERT(clen <= blen);\n\treturn clen;\n}\n#endif  /* DUK_USE_PREFER_SIZE */\n\n/*\n *  Unicode range matcher\n *\n *  Matches a codepoint against a packed bitstream of character ranges.\n *  Used for slow path Unicode matching.\n */\n\n/* Must match tools/extract_chars.py, generate_match_table3(). */\nDUK_LOCAL duk_uint32_t duk__uni_decode_value(duk_bitdecoder_ctx *bd_ctx) {\n\tduk_uint32_t t;\n\n\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 4);\n\tif (t <= 0x0eU) {\n\t\treturn t;\n\t}\n\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 8);\n\tif (t <= 0xfdU) {\n\t\treturn t + 0x0f;\n\t}\n\tif (t == 0xfeU) {\n\t\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 12);\n\t\treturn t + 0x0fU + 0xfeU;\n\t} else {\n\t\tt = (duk_uint32_t) duk_bd_decode(bd_ctx, 24);\n\t\treturn t + 0x0fU + 0xfeU + 0x1000UL;\n\t}\n}\n\nDUK_LOCAL duk_small_int_t duk__uni_range_match(const duk_uint8_t *unitab, duk_size_t unilen, duk_codepoint_t cp) {\n\tduk_bitdecoder_ctx bd_ctx;\n\tduk_codepoint_t prev_re;\n\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tbd_ctx.data = (const duk_uint8_t *) unitab;\n\tbd_ctx.length = (duk_size_t) unilen;\n\n\tprev_re = 0;\n\tfor (;;) {\n\t\tduk_codepoint_t r1, r2;\n\t\tr1 = (duk_codepoint_t) duk__uni_decode_value(&bd_ctx);\n\t\tif (r1 == 0) {\n\t\t\tbreak;\n\t\t}\n\t\tr2 = (duk_codepoint_t) duk__uni_decode_value(&bd_ctx);\n\n\t\tr1 = prev_re + r1;\n\t\tr2 = r1 + r2;\n\t\tprev_re = r2;\n\n\t\t/* [r1,r2] is the range */\n\n\t\tDUK_DDD(DUK_DDDPRINT(\"duk__uni_range_match: cp=%06lx range=[0x%06lx,0x%06lx]\",\n\t\t                     (unsigned long) cp, (unsigned long) r1, (unsigned long) r2));\n\t\tif (cp >= r1 && cp <= r2) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n/*\n *  \"WhiteSpace\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_whitespace(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.2 specifies six characters specifically as\n\t *  white space:\n\t *\n\t *    0009;<control>;Cc;0;S;;;;;N;CHARACTER TABULATION;;;;\n\t *    000B;<control>;Cc;0;S;;;;;N;LINE TABULATION;;;;\n\t *    000C;<control>;Cc;0;WS;;;;;N;FORM FEED (FF);;;;\n\t *    0020;SPACE;Zs;0;WS;;;;;N;;;;;\n\t *    00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;\n\t *    FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;;\n\t *\n\t *  It also specifies any Unicode category 'Zs' characters as white\n\t *  space.  These can be extracted with the \"tools/extract_chars.py\" script.\n\t *  Current result:\n\t *\n\t *    RAW OUTPUT:\n\t *    ===========\n\t *    0020;SPACE;Zs;0;WS;;;;;N;;;;;\n\t *    00A0;NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;NON-BREAKING SPACE;;;;\n\t *    1680;OGHAM SPACE MARK;Zs;0;WS;;;;;N;;;;;\n\t *    180E;MONGOLIAN VOWEL SEPARATOR;Zs;0;WS;;;;;N;;;;;\n\t *    2000;EN QUAD;Zs;0;WS;2002;;;;N;;;;;\n\t *    2001;EM QUAD;Zs;0;WS;2003;;;;N;;;;;\n\t *    2002;EN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2003;EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2004;THREE-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2005;FOUR-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2006;SIX-PER-EM SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2007;FIGURE SPACE;Zs;0;WS;<noBreak> 0020;;;;N;;;;;\n\t *    2008;PUNCTUATION SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    2009;THIN SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    200A;HAIR SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    202F;NARROW NO-BREAK SPACE;Zs;0;CS;<noBreak> 0020;;;;N;;;;;\n\t *    205F;MEDIUM MATHEMATICAL SPACE;Zs;0;WS;<compat> 0020;;;;N;;;;;\n\t *    3000;IDEOGRAPHIC SPACE;Zs;0;WS;<wide> 0020;;;;N;;;;;\n\t *\n\t *    RANGES:\n\t *    =======\n\t *    0x0020\n\t *    0x00a0\n\t *    0x1680\n\t *    0x180e\n\t *    0x2000 ... 0x200a\n\t *    0x202f\n\t *    0x205f\n\t *    0x3000\n\t *\n\t *  A manual decoder (below) is probably most compact for this.\n\t */\n\n\tduk_uint_fast8_t lo;\n\tduk_uint_fast32_t hi;\n\n\t/* cp == -1 (EOF) never matches and causes return value 0 */\n\n\tlo = (duk_uint_fast8_t) (cp & 0xff);\n\thi = (duk_uint_fast32_t) (cp >> 8);  /* does not fit into an uchar */\n\n\tif (hi == 0x0000UL) {\n\t\tif (lo == 0x09U || lo == 0x0bU || lo == 0x0cU ||\n\t\t    lo == 0x20U || lo == 0xa0U) {\n\t\t\treturn 1;\n\t\t}\n\t} else if (hi == 0x0020UL) {\n\t\tif (lo <= 0x0aU || lo == 0x2fU || lo == 0x5fU) {\n\t\t\treturn 1;\n\t\t}\n\t} else if (cp == 0x1680L || cp == 0x180eL || cp == 0x3000L ||\n\t           cp == 0xfeffL) {\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n/*\n *  \"LineTerminator\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_line_terminator(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.3\n\t *\n\t *  A LineTerminatorSequence essentially merges <CR> <LF> sequences\n\t *  into a single line terminator.  This must be handled by the caller.\n\t */\n\n\tif (cp == 0x000aL || cp == 0x000dL || cp == 0x2028L ||\n\t    cp == 0x2029L) {\n\t\treturn 1;\n\t}\n\n\treturn 0;\n}\n\n/*\n *  \"IdentifierStart\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_identifier_start(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.6:\n\t *\n\t *    IdentifierStart:\n\t *      UnicodeLetter\n\t *      $\n\t *      _\n\t *      \\ UnicodeEscapeSequence\n\t *\n\t *  IdentifierStart production has one multi-character production:\n\t *\n\t *    \\ UnicodeEscapeSequence\n\t *\n\t *  The '\\' character is -not- matched by this function.  Rather, the caller\n\t *  should decode the escape and then call this function to check whether the\n\t *  decoded character is acceptable (see discussion in E5 Section 7.6).\n\t *\n\t *  The \"UnicodeLetter\" alternative of the production allows letters\n\t *  from various Unicode categories.  These can be extracted with the\n\t *  \"tools/extract_chars.py\" script.\n\t *\n\t *  Because the result has hundreds of Unicode codepoint ranges, matching\n\t *  for any values >= 0x80 are done using a very slow range-by-range scan\n\t *  and a packed range format.\n\t *\n\t *  The ASCII portion (codepoints 0x00 ... 0x7f) is fast-pathed below because\n\t *  it matters the most.  The ASCII related ranges of IdentifierStart are:\n\t *\n\t *    0x0041 ... 0x005a     ['A' ... 'Z']\n\t *    0x0061 ... 0x007a     ['a' ... 'z']\n\t *    0x0024                ['$']\n\t *    0x005f                ['_']\n\t */\n\n\t/* ASCII (and EOF) fast path -- quick accept and reject */\n\tif (cp <= 0x7fL) {\n#if defined(DUK_USE_IDCHAR_FASTPATH)\n\t\treturn (cp >= 0) && (duk_is_idchar_tab[cp] > 0);\n#else\n\t\tif ((cp >= 'a' && cp <= 'z') ||\n\t\t    (cp >= 'A' && cp <= 'Z') ||\n\t\t    cp == '_' || cp == '$') {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n#endif\n\t}\n\n\t/* Non-ASCII slow path (range-by-range linear comparison), very slow */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n\tif (duk__uni_range_match(duk_unicode_ids_noa,\n\t                         (duk_size_t) sizeof(duk_unicode_ids_noa),\n\t                         (duk_codepoint_t) cp)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else\n\tif (cp < 0x10000L) {\n\t\tif (duk__uni_range_match(duk_unicode_ids_noabmp,\n\t\t                         sizeof(duk_unicode_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp)) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t} else {\n\t\t/* without explicit non-BMP support, assume non-BMP characters\n\t\t * are always accepted as identifier characters.\n\t\t */\n\t\treturn 1;\n\t}\n#endif\n}\n\n/*\n *  \"IdentifierPart\" production check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_identifier_part(duk_codepoint_t cp) {\n\t/*\n\t *  E5 Section 7.6:\n\t *\n\t *    IdentifierPart:\n\t *      IdentifierStart\n\t *      UnicodeCombiningMark\n\t *      UnicodeDigit\n\t *      UnicodeConnectorPunctuation\n\t *      <ZWNJ>  [U+200C]\n\t *      <ZWJ>   [U+200D]\n\t *\n\t *  IdentifierPart production has one multi-character production\n\t *  as part of its IdentifierStart alternative.  The '\\' character\n\t *  of an escape sequence is not matched here, see discussion in\n\t *  duk_unicode_is_identifier_start().\n\t *\n\t *  To match non-ASCII characters (codepoints >= 0x80), a very slow\n\t *  linear range-by-range scan is used.  The codepoint is first compared\n\t *  to the IdentifierStart ranges, and if it doesn't match, then to a\n\t *  set consisting of code points in IdentifierPart but not in\n\t *  IdentifierStart.  This is done to keep the unicode range data small,\n\t *  at the expense of speed.\n\t *\n\t *  The ASCII fast path consists of:\n\t *\n\t *    0x0030 ... 0x0039     ['0' ... '9', UnicodeDigit]\n\t *    0x0041 ... 0x005a     ['A' ... 'Z', IdentifierStart]\n\t *    0x0061 ... 0x007a     ['a' ... 'z', IdentifierStart]\n\t *    0x0024                ['$', IdentifierStart]\n\t *    0x005f                ['_', IdentifierStart and\n\t *                                UnicodeConnectorPunctuation]\n\t *\n\t *  UnicodeCombiningMark has no code points <= 0x7f.\n\t *\n\t *  The matching code reuses the \"identifier start\" tables, and then\n\t *  consults a separate range set for characters in \"identifier part\"\n\t *  but not in \"identifier start\".  These can be extracted with the\n\t *  \"tools/extract_chars.py\" script.\n\t *\n\t *  UnicodeCombiningMark -> categories Mn, Mc\n\t *  UnicodeDigit -> categories Nd\n\t *  UnicodeConnectorPunctuation -> categories Pc\n\t */\n\n\t/* ASCII (and EOF) fast path -- quick accept and reject */\n\tif (cp <= 0x7fL) {\n#if defined(DUK_USE_IDCHAR_FASTPATH)\n\t\treturn (cp >= 0) && (duk_is_idchar_tab[cp] != 0);\n#else\n\t\tif ((cp >= 'a' && cp <= 'z') ||\n\t\t    (cp >= 'A' && cp <= 'Z') ||\n\t\t    (cp >= '0' && cp <= '9') ||\n\t\t    cp == '_' || cp == '$') {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n#endif\n\t}\n\n\t/* Non-ASCII slow path (range-by-range linear comparison), very slow */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n\tif (duk__uni_range_match(duk_unicode_ids_noa,\n\t                         sizeof(duk_unicode_ids_noa),\n\t                         (duk_codepoint_t) cp) ||\n\t    duk__uni_range_match(duk_unicode_idp_m_ids_noa,\n\t                         sizeof(duk_unicode_idp_m_ids_noa),\n\t                         (duk_codepoint_t) cp)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else\n\tif (cp < 0x10000L) {\n\t\tif (duk__uni_range_match(duk_unicode_ids_noabmp,\n\t\t                         sizeof(duk_unicode_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp) ||\n\t\t    duk__uni_range_match(duk_unicode_idp_m_ids_noabmp,\n\t\t                         sizeof(duk_unicode_idp_m_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp)) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t} else {\n\t\t/* without explicit non-BMP support, assume non-BMP characters\n\t\t * are always accepted as identifier characters.\n\t\t */\n\t\treturn 1;\n\t}\n#endif\n}\n\n/*\n *  Unicode letter check.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_is_letter(duk_codepoint_t cp) {\n\t/*\n\t *  Unicode letter is now taken to be the categories:\n\t *\n\t *    Lu, Ll, Lt, Lm, Lo\n\t *\n\t *  (Not sure if this is exactly correct.)\n\t *\n\t *  The ASCII fast path consists of:\n\t *\n\t *    0x0041 ... 0x005a     ['A' ... 'Z']\n\t *    0x0061 ... 0x007a     ['a' ... 'z']\n\t */\n\n\t/* ASCII (and EOF) fast path -- quick accept and reject */\n\tif (cp <= 0x7fL) {\n\t\tif ((cp >= 'a' && cp <= 'z') ||\n\t\t    (cp >= 'A' && cp <= 'Z')) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t}\n\n\t/* Non-ASCII slow path (range-by-range linear comparison), very slow */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n\tif (duk__uni_range_match(duk_unicode_ids_noa,\n\t                         sizeof(duk_unicode_ids_noa),\n\t                         (duk_codepoint_t) cp) &&\n\t    !duk__uni_range_match(duk_unicode_ids_m_let_noa,\n\t                          sizeof(duk_unicode_ids_m_let_noa),\n\t                          (duk_codepoint_t) cp)) {\n\t\treturn 1;\n\t}\n\treturn 0;\n#else\n\tif (cp < 0x10000L) {\n\t\tif (duk__uni_range_match(duk_unicode_ids_noabmp,\n\t\t                         sizeof(duk_unicode_ids_noabmp),\n\t\t                         (duk_codepoint_t) cp) &&\n\t\t    !duk__uni_range_match(duk_unicode_ids_m_let_noabmp,\n\t\t                          sizeof(duk_unicode_ids_m_let_noabmp),\n\t\t                          (duk_codepoint_t) cp)) {\n\t\t\treturn 1;\n\t\t}\n\t\treturn 0;\n\t} else {\n\t\t/* without explicit non-BMP support, assume non-BMP characters\n\t\t * are always accepted as letters.\n\t\t */\n\t\treturn 1;\n\t}\n#endif\n}\n\n/*\n *  Complex case conversion helper which decodes a bit-packed conversion\n *  control stream generated by tools/extract_caseconv.py.  The conversion\n *  is very slow because it runs through the conversion data in a linear\n *  fashion to save space (which is why ASCII characters have a special\n *  fast path before arriving here).\n *\n *  The particular bit counts etc have been determined experimentally to\n *  be small but still sufficient, and must match the Python script\n *  (tools/extract_caseconv.py).\n *\n *  The return value is the case converted codepoint or -1 if the conversion\n *  results in multiple characters (this is useful for regexp Canonicalization\n *  operation).  If 'buf' is not NULL, the result codepoint(s) are also\n *  appended to the hbuffer.\n *\n *  Context and locale specific rules must be checked before consulting\n *  this function.\n */\n\nDUK_LOCAL\nduk_codepoint_t duk__slow_case_conversion(duk_hthread *thr,\n                                          duk_bufwriter_ctx *bw,\n                                          duk_codepoint_t cp,\n                                          duk_bitdecoder_ctx *bd_ctx) {\n\tduk_small_int_t skip = 0;\n\tduk_small_int_t n;\n\tduk_small_int_t t;\n\tduk_small_int_t count;\n\tduk_codepoint_t tmp_cp;\n\tduk_codepoint_t start_i;\n\tduk_codepoint_t start_o;\n\n\tDUK_ASSERT(bd_ctx != NULL);\n\tDUK_UNREF(thr);\n\n\tDUK_DDD(DUK_DDDPRINT(\"slow case conversion for codepoint: %ld\", (long) cp));\n\n\t/* range conversion with a \"skip\" */\n\tDUK_DDD(DUK_DDDPRINT(\"checking ranges\"));\n\tfor (;;) {\n\t\tskip++;\n\t\tn = (duk_small_int_t) duk_bd_decode(bd_ctx, 6);\n\t\tif (n == 0x3f) {\n\t\t\t/* end marker */\n\t\t\tbreak;\n\t\t}\n\t\tDUK_DDD(DUK_DDDPRINT(\"skip=%ld, n=%ld\", (long) skip, (long) n));\n\n\t\twhile (n--) {\n\t\t\tstart_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\t\tstart_o = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\t\tcount = (duk_small_int_t) duk_bd_decode(bd_ctx, 7);\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"range: start_i=%ld, start_o=%ld, count=%ld, skip=%ld\",\n\t\t\t                     (long) start_i, (long) start_o, (long) count, (long) skip));\n\n\t\t\tif (cp >= start_i) {\n\t\t\t\ttmp_cp = cp - start_i;  /* always >= 0 */\n\t\t\t\tif (tmp_cp < (duk_codepoint_t) count * (duk_codepoint_t) skip &&\n\t\t\t\t    (tmp_cp % (duk_codepoint_t) skip) == 0) {\n\t\t\t\t\tDUK_DDD(DUK_DDDPRINT(\"range matches input codepoint\"));\n\t\t\t\t\tcp = start_o + tmp_cp;\n\t\t\t\t\tgoto single;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/* 1:1 conversion */\n\tn = (duk_small_int_t) duk_bd_decode(bd_ctx, 7);\n\tDUK_DDD(DUK_DDDPRINT(\"checking 1:1 conversions (count %ld)\", (long) n));\n\twhile (n--) {\n\t\tstart_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\tstart_o = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\tDUK_DDD(DUK_DDDPRINT(\"1:1 conversion %ld -> %ld\", (long) start_i, (long) start_o));\n\t\tif (cp == start_i) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"1:1 matches input codepoint\"));\n\t\t\tcp = start_o;\n\t\t\tgoto single;\n\t\t}\n\t}\n\n\t/* complex, multicharacter conversion */\n\tn = (duk_small_int_t) duk_bd_decode(bd_ctx, 7);\n\tDUK_DDD(DUK_DDDPRINT(\"checking 1:n conversions (count %ld)\", (long) n));\n\twhile (n--) {\n\t\tstart_i = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\tt = (duk_small_int_t) duk_bd_decode(bd_ctx, 2);\n\t\tDUK_DDD(DUK_DDDPRINT(\"1:n conversion %ld -> %ld chars\", (long) start_i, (long) t));\n\t\tif (cp == start_i) {\n\t\t\tDUK_DDD(DUK_DDDPRINT(\"1:n matches input codepoint\"));\n\t\t\tif (bw != NULL) {\n\t\t\t\twhile (t--) {\n\t\t\t\t\ttmp_cp = (duk_codepoint_t) duk_bd_decode(bd_ctx, 16);\n\t\t\t\t\tDUK_BW_WRITE_RAW_XUTF8(thr, bw, (duk_ucodepoint_t) tmp_cp);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t} else {\n\t\t\twhile (t--) {\n\t\t\t\t(void) duk_bd_decode(bd_ctx, 16);\n\t\t\t}\n\t\t}\n\t}\n\n\t/* default: no change */\n\tDUK_DDD(DUK_DDDPRINT(\"no rule matches, output is same as input\"));\n\t/* fall through */\n\n single:\n\tif (bw != NULL) {\n\t\tDUK_BW_WRITE_RAW_XUTF8(thr, bw, (duk_ucodepoint_t) cp);\n\t}\n\treturn cp;\n}\n\n/*\n *  Case conversion helper, with context/local sensitivity.\n *  For proper case conversion, one needs to know the character\n *  and the preceding and following characters, as well as\n *  locale/language.\n */\n\n/* XXX: add 'language' argument when locale/language sensitive rule\n * support added.\n */\nDUK_LOCAL\nduk_codepoint_t duk__case_transform_helper(duk_hthread *thr,\n                                           duk_bufwriter_ctx *bw,\n                                           duk_codepoint_t cp,\n                                           duk_codepoint_t prev,\n                                           duk_codepoint_t next,\n                                           duk_bool_t uppercase) {\n\tduk_bitdecoder_ctx bd_ctx;\n\n\t/* fast path for ASCII */\n\tif (cp < 0x80L) {\n\t\t/* XXX: there are language sensitive rules for the ASCII range.\n\t\t * If/when language/locale support is implemented, they need to\n\t\t * be implemented here for the fast path.  There are no context\n\t\t * sensitive rules for ASCII range.\n\t\t */\n\n\t\tif (uppercase) {\n\t\t\tif (cp >= 'a' && cp <= 'z') {\n\t\t\t\tcp = cp - 'a' + 'A';\n\t\t\t}\n\t\t} else {\n\t\t\tif (cp >= 'A' && cp <= 'Z') {\n\t\t\t\tcp = cp - 'A' + 'a';\n\t\t\t}\n\t\t}\n\n\t\tif (bw != NULL) {\n\t\t\tDUK_BW_WRITE_RAW_U8(thr, bw, (duk_uint8_t) cp);\n\t\t}\n\t\treturn cp;\n\t}\n\n\t/* context and locale specific rules which cannot currently be represented\n\t * in the caseconv bitstream: hardcoded rules in C\n\t */\n\tif (uppercase) {\n\t\t/* XXX: turkish / azeri */\n\t} else {\n\t\t/*\n\t\t *  Final sigma context specific rule.  This is a rather tricky\n\t\t *  rule and this handling is probably not 100% correct now.\n\t\t *  The rule is not locale/language specific so it is supported.\n\t\t */\n\n\t\tif (cp == 0x03a3L &&    /* U+03A3 = GREEK CAPITAL LETTER SIGMA */\n\t\t    duk_unicode_is_letter(prev) &&        /* prev exists and is not a letter */\n\t\t    !duk_unicode_is_letter(next)) {       /* next does not exist or next is not a letter */\n\t\t\t/* Capital sigma occurred at \"end of word\", lowercase to\n\t\t\t * U+03C2 = GREEK SMALL LETTER FINAL SIGMA.  Otherwise\n\t\t\t * fall through and let the normal rules lowercase it to\n\t\t\t * U+03C3 = GREEK SMALL LETTER SIGMA.\n\t\t\t */\n\t\t\tcp = 0x03c2L;\n\t\t\tgoto singlechar;\n\t\t}\n\n\t\t/* XXX: lithuanian not implemented */\n\t\t/* XXX: lithuanian, explicit dot rules */\n\t\t/* XXX: turkish / azeri, lowercase rules */\n\t}\n\n\t/* 1:1 or special conversions, but not locale/context specific: script generated rules */\n\tduk_memzero(&bd_ctx, sizeof(bd_ctx));\n\tif (uppercase) {\n\t\tbd_ctx.data = (const duk_uint8_t *) duk_unicode_caseconv_uc;\n\t\tbd_ctx.length = (duk_size_t) sizeof(duk_unicode_caseconv_uc);\n\t} else {\n\t\tbd_ctx.data = (const duk_uint8_t *) duk_unicode_caseconv_lc;\n\t\tbd_ctx.length = (duk_size_t) sizeof(duk_unicode_caseconv_lc);\n\t}\n\treturn duk__slow_case_conversion(thr, bw, cp, &bd_ctx);\n\n singlechar:\n\tif (bw != NULL) {\n\t\tDUK_BW_WRITE_RAW_XUTF8(thr, bw, (duk_ucodepoint_t) cp);\n\t}\n\treturn cp;\n\n /* unused now, not needed until Turkish/Azeri */\n#if 0\n nochar:\n\treturn -1;\n#endif\n}\n\n/*\n *  Replace valstack top with case converted version.\n */\n\nDUK_INTERNAL void duk_unicode_case_convert_string(duk_hthread *thr, duk_bool_t uppercase) {\n\tduk_hstring *h_input;\n\tduk_bufwriter_ctx bw_alloc;\n\tduk_bufwriter_ctx *bw;\n\tconst duk_uint8_t *p, *p_start, *p_end;\n\tduk_codepoint_t prev, curr, next;\n\n\th_input = duk_require_hstring(thr, -1);  /* Accept symbols. */\n\tDUK_ASSERT(h_input != NULL);\n\n\tbw = &bw_alloc;\n\tDUK_BW_INIT_PUSHBUF(thr, bw, DUK_HSTRING_GET_BYTELEN(h_input));\n\n\t/* [ ... input buffer ] */\n\n\tp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_input);\n\tp_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input);\n\tp = p_start;\n\n\tprev = -1; DUK_UNREF(prev);\n\tcurr = -1;\n\tnext = -1;\n\tfor (;;) {\n\t\tprev = curr;\n\t\tcurr = next;\n\t\tnext = -1;\n\t\tif (p < p_end) {\n\t\t\tnext = (duk_codepoint_t) duk_unicode_decode_xutf8_checked(thr, &p, p_start, p_end);\n\t\t} else {\n\t\t\t/* end of input and last char has been processed */\n\t\t\tif (curr < 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t/* on first round, skip */\n\t\tif (curr >= 0) {\n\t\t\t/* XXX: could add a fast path to process chunks of input codepoints,\n\t\t\t * but relative benefit would be quite small.\n\t\t\t */\n\n\t\t\t/* Ensure space for maximum multi-character result; estimate is overkill. */\n\t\t\tDUK_BW_ENSURE(thr, bw, 8 * DUK_UNICODE_MAX_XUTF8_LENGTH);\n\n\t\t\tduk__case_transform_helper(thr,\n\t\t\t                           bw,\n\t\t\t                           (duk_codepoint_t) curr,\n\t\t\t                           prev,\n\t\t\t                           next,\n\t\t\t                           uppercase);\n\t\t}\n\t}\n\n\tDUK_BW_COMPACT(thr, bw);\n\t(void) duk_buffer_to_string(thr, -1);  /* Safe, output is encoded. */\n\t/* invalidates h_buf pointer */\n\tduk_remove_m2(thr);\n}\n\n#if defined(DUK_USE_REGEXP_SUPPORT)\n\n/*\n *  Canonicalize() abstract operation needed for canonicalization of individual\n *  codepoints during regexp compilation and execution, see E5 Section 15.10.2.8.\n *  Note that codepoints are canonicalized one character at a time, so no context\n *  specific rules can apply.  Locale specific rules can apply, though.\n */\n\nDUK_INTERNAL duk_codepoint_t duk_unicode_re_canonicalize_char(duk_hthread *thr, duk_codepoint_t cp) {\n#if defined(DUK_USE_REGEXP_CANON_WORKAROUND)\n\t/* Fast canonicalization lookup at the cost of 128kB footprint. */\n\tDUK_ASSERT(cp >= 0);\n\tDUK_UNREF(thr);\n\tif (DUK_LIKELY(cp < 0x10000L)) {\n\t\treturn (duk_codepoint_t) duk_unicode_re_canon_lookup[cp];\n\t}\n\treturn cp;\n#else  /* DUK_USE_REGEXP_CANON_WORKAROUND */\n\tduk_codepoint_t y;\n\n\ty = duk__case_transform_helper(thr,\n\t                               NULL,    /* NULL is allowed, no output */\n\t                               cp,      /* curr char */\n\t                               -1,      /* prev char */\n\t                               -1,      /* next char */\n\t                               1);      /* uppercase */\n\n\tif ((y < 0) || (cp >= 0x80 && y < 0x80)) {\n\t\t/* multiple codepoint conversion or non-ASCII mapped to ASCII\n\t\t * --> leave as is.\n\t\t */\n\t\treturn cp;\n\t}\n\n\treturn y;\n#endif  /* DUK_USE_REGEXP_CANON_WORKAROUND */\n}\n\n/*\n *  E5 Section 15.10.2.6 \"IsWordChar\" abstract operation.  Assume\n *  x < 0 for characters read outside the string.\n */\n\nDUK_INTERNAL duk_small_int_t duk_unicode_re_is_wordchar(duk_codepoint_t x) {\n\t/*\n\t *  Note: the description in E5 Section 15.10.2.6 has a typo, it\n\t *  contains 'A' twice and lacks 'a'; the intent is [0-9a-zA-Z_].\n\t */\n\tif ((x >= '0' && x <= '9') ||\n\t    (x >= 'a' && x <= 'z') ||\n\t    (x >= 'A' && x <= 'Z') ||\n\t    (x == '_')) {\n\t\treturn 1;\n\t}\n\treturn 0;\n}\n\n/*\n *  Regexp range tables\n */\n\n/* exposed because lexer needs these too */\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_digit[2] = {\n\t(duk_uint16_t) 0x0030UL, (duk_uint16_t) 0x0039UL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_white[22] = {\n\t(duk_uint16_t) 0x0009UL, (duk_uint16_t) 0x000DUL,\n\t(duk_uint16_t) 0x0020UL, (duk_uint16_t) 0x0020UL,\n\t(duk_uint16_t) 0x00A0UL, (duk_uint16_t) 0x00A0UL,\n\t(duk_uint16_t) 0x1680UL, (duk_uint16_t) 0x1680UL,\n\t(duk_uint16_t) 0x180EUL, (duk_uint16_t) 0x180EUL,\n\t(duk_uint16_t) 0x2000UL, (duk_uint16_t) 0x200AUL,\n\t(duk_uint16_t) 0x2028UL, (duk_uint16_t) 0x2029UL,\n\t(duk_uint16_t) 0x202FUL, (duk_uint16_t) 0x202FUL,\n\t(duk_uint16_t) 0x205FUL, (duk_uint16_t) 0x205FUL,\n\t(duk_uint16_t) 0x3000UL, (duk_uint16_t) 0x3000UL,\n\t(duk_uint16_t) 0xFEFFUL, (duk_uint16_t) 0xFEFFUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_wordchar[8] = {\n\t(duk_uint16_t) 0x0030UL, (duk_uint16_t) 0x0039UL,\n\t(duk_uint16_t) 0x0041UL, (duk_uint16_t) 0x005AUL,\n\t(duk_uint16_t) 0x005FUL, (duk_uint16_t) 0x005FUL,\n\t(duk_uint16_t) 0x0061UL, (duk_uint16_t) 0x007AUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_digit[4] = {\n\t(duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x002FUL,\n\t(duk_uint16_t) 0x003AUL, (duk_uint16_t) 0xFFFFUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_white[24] = {\n\t(duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x0008UL,\n\t(duk_uint16_t) 0x000EUL, (duk_uint16_t) 0x001FUL,\n\t(duk_uint16_t) 0x0021UL, (duk_uint16_t) 0x009FUL,\n\t(duk_uint16_t) 0x00A1UL, (duk_uint16_t) 0x167FUL,\n\t(duk_uint16_t) 0x1681UL, (duk_uint16_t) 0x180DUL,\n\t(duk_uint16_t) 0x180FUL, (duk_uint16_t) 0x1FFFUL,\n\t(duk_uint16_t) 0x200BUL, (duk_uint16_t) 0x2027UL,\n\t(duk_uint16_t) 0x202AUL, (duk_uint16_t) 0x202EUL,\n\t(duk_uint16_t) 0x2030UL, (duk_uint16_t) 0x205EUL,\n\t(duk_uint16_t) 0x2060UL, (duk_uint16_t) 0x2FFFUL,\n\t(duk_uint16_t) 0x3001UL, (duk_uint16_t) 0xFEFEUL,\n\t(duk_uint16_t) 0xFF00UL, (duk_uint16_t) 0xFFFFUL,\n};\nDUK_INTERNAL const duk_uint16_t duk_unicode_re_ranges_not_wordchar[10] = {\n\t(duk_uint16_t) 0x0000UL, (duk_uint16_t) 0x002FUL,\n\t(duk_uint16_t) 0x003AUL, (duk_uint16_t) 0x0040UL,\n\t(duk_uint16_t) 0x005BUL, (duk_uint16_t) 0x005EUL,\n\t(duk_uint16_t) 0x0060UL, (duk_uint16_t) 0x0060UL,\n\t(duk_uint16_t) 0x007BUL, (duk_uint16_t) 0xFFFFUL,\n};\n\n#endif  /* DUK_USE_REGEXP_SUPPORT */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_unicode_tables.c",
    "content": "/*\n *  Unicode support tables automatically generated during build.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Unicode tables containing ranges of Unicode characters in a\n *  packed format.  These tables are used to match non-ASCII\n *  characters of complex productions by resorting to a linear\n *  range-by-range comparison.  This is very slow, but is expected\n *  to be very rare in practical ECMAScript source code, and thus\n *  compactness is most important.\n *\n *  The tables are matched using uni_range_match() and the format\n *  is described in tools/extract_chars.py.\n */\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/* IdentifierStart production with ASCII excluded */\n/* duk_unicode_ids_noa[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_ids_noa[1116] = {\n249,176,176,80,111,7,47,15,47,254,11,197,191,0,72,2,15,115,66,19,50,7,2,34,\n2,240,66,244,50,247,185,249,98,241,99,7,241,159,57,240,181,63,31,241,191,\n21,18,245,50,15,1,24,27,35,15,2,2,240,239,15,244,156,15,10,241,26,21,6,240,\n101,10,4,15,9,240,152,175,39,240,82,127,56,242,100,15,4,8,159,1,240,5,115,\n19,240,98,98,4,52,15,2,14,18,47,0,27,9,85,19,240,98,98,18,18,31,17,50,15,5,\n47,2,130,34,240,98,98,18,68,15,4,15,1,31,9,12,115,19,240,98,98,18,68,15,16,\n18,47,1,15,3,2,84,34,52,18,2,20,20,36,191,8,15,38,114,34,240,114,240,4,15,\n12,38,31,16,5,114,34,240,114,146,68,15,18,2,31,1,31,4,114,34,241,147,15,2,\n6,41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,2,66,240,130,\n2,146,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,2,85,52,4,\n24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,35,63,17,35,\n54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,227,240,18,240,\n166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,21,5,15,53,244,\n152,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,175,40,240,122,\n242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,79,27,43,241,67,\n136,241,179,47,27,50,82,20,6,251,15,50,255,224,8,53,63,22,53,55,32,32,32,\n47,15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,32,\n68,112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,87,\n52,29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,254,\n12,146,240,184,132,52,95,70,114,47,74,35,111,27,47,78,240,63,11,242,127,0,\n255,224,244,255,240,0,138,143,60,255,240,4,14,47,2,255,227,127,243,95,30,\n63,253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,37,52,242,42,\n34,35,47,7,240,255,36,240,15,34,243,5,64,33,207,12,191,7,240,191,13,143,31,\n240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,48,32,\n240,162,58,130,213,53,53,166,38,47,27,43,159,99,240,255,255,0,26,150,223,7,\n95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,18,245,\n207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,127,10,\n207,73,69,53,53,50,241,91,47,10,47,3,33,46,61,241,79,107,243,127,37,255,\n223,13,79,33,242,31,16,239,14,111,22,191,14,63,20,87,36,241,207,142,240,79,\n20,95,20,95,24,159,36,248,239,254,2,154,240,107,127,138,83,2,241,194,20,3,\n240,123,240,122,240,255,51,240,50,27,240,107,240,175,56,242,135,31,50,15,1,\n50,34,240,223,28,240,212,240,223,21,114,240,207,13,242,107,240,107,240,62,\n240,47,96,243,159,41,242,62,242,62,241,79,254,13,15,13,176,159,6,248,207,7,\n223,37,243,223,29,241,47,9,240,207,20,240,240,207,19,64,223,32,240,3,240,\n112,32,241,95,2,47,9,244,102,32,35,46,41,143,31,241,135,49,63,6,38,33,36,\n64,240,64,212,249,15,37,240,67,240,96,241,47,32,240,97,32,250,175,31,241,\n179,241,111,32,240,96,242,223,27,224,243,159,11,253,127,28,246,111,48,241,\n16,249,39,63,23,240,32,32,240,224,191,24,128,240,112,207,30,240,80,241,79,\n41,255,152,47,21,240,48,242,63,14,246,38,33,47,22,240,112,240,181,33,47,16,\n240,0,255,224,59,240,63,254,0,31,254,40,207,88,245,255,3,251,79,254,155,15,\n254,50,31,254,236,95,254,19,159,255,0,16,173,255,225,43,143,15,246,63,14,\n240,79,32,240,35,241,31,5,111,3,255,225,164,243,15,114,243,182,15,52,207,\n50,18,15,14,255,240,0,110,169,255,225,229,255,240,1,64,31,254,1,31,35,47,3,\n57,255,224,126,255,231,248,245,182,196,136,159,255,0,6,90,244,82,243,114,\n19,3,19,50,178,2,98,243,18,51,114,98,240,194,50,66,4,98,255,224,70,63,9,47,\n9,47,15,47,9,47,15,47,9,47,15,47,9,47,15,47,9,39,255,232,40,241,219,111,2,\n15,254,6,95,28,255,228,8,251,95,45,243,72,15,254,58,131,47,11,33,32,48,41,\n35,32,32,112,80,32,32,34,33,32,48,32,32,32,32,33,32,51,38,35,35,32,41,47,1,\n98,36,47,1,255,240,0,3,143,255,0,149,201,241,191,254,242,124,252,227,255,\n240,0,87,79,0,255,240,0,194,63,254,177,63,254,17,0,\n};\n#else\n/* IdentifierStart production with ASCII and non-BMP excluded */\n/* duk_unicode_ids_noabmp[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_ids_noabmp[625] = {\n249,176,176,80,111,7,47,15,47,254,11,197,191,0,72,2,15,115,66,19,50,7,2,34,\n2,240,66,244,50,247,185,249,98,241,99,7,241,159,57,240,181,63,31,241,191,\n21,18,245,50,15,1,24,27,35,15,2,2,240,239,15,244,156,15,10,241,26,21,6,240,\n101,10,4,15,9,240,152,175,39,240,82,127,56,242,100,15,4,8,159,1,240,5,115,\n19,240,98,98,4,52,15,2,14,18,47,0,27,9,85,19,240,98,98,18,18,31,17,50,15,5,\n47,2,130,34,240,98,98,18,68,15,4,15,1,31,9,12,115,19,240,98,98,18,68,15,16,\n18,47,1,15,3,2,84,34,52,18,2,20,20,36,191,8,15,38,114,34,240,114,240,4,15,\n12,38,31,16,5,114,34,240,114,146,68,15,18,2,31,1,31,4,114,34,241,147,15,2,\n6,41,47,10,86,240,36,240,130,130,3,111,44,242,2,29,111,44,18,2,66,240,130,\n2,146,26,3,66,15,7,63,18,15,49,114,241,79,13,79,101,241,191,6,15,2,85,52,4,\n24,37,205,15,3,241,98,6,3,241,178,255,224,63,35,54,32,35,63,25,35,63,17,35,\n54,32,35,62,47,41,35,63,51,241,127,0,240,47,70,53,79,254,21,227,240,18,240,\n166,243,180,168,194,63,0,240,47,0,240,47,0,194,47,1,242,79,21,5,15,53,244,\n152,67,241,34,6,243,107,240,255,35,240,227,76,241,197,240,175,40,240,122,\n242,95,68,15,79,241,255,3,111,41,240,238,27,241,207,12,241,79,27,43,241,67,\n136,241,179,47,27,50,82,20,6,251,15,50,255,224,8,53,63,22,53,55,32,32,32,\n47,15,63,37,38,32,66,38,67,53,92,98,38,246,96,224,240,44,245,112,80,57,32,\n68,112,32,32,35,42,51,100,80,240,63,25,255,233,107,241,242,241,242,247,87,\n52,29,241,98,6,3,242,136,15,2,240,122,98,98,98,98,98,98,98,111,66,15,254,\n12,146,240,184,132,52,95,70,114,47,74,35,111,27,47,78,240,63,11,242,127,0,\n255,224,244,255,240,0,138,143,60,255,240,4,14,47,2,255,227,127,243,95,30,\n63,253,79,0,177,240,111,31,240,47,15,63,64,241,152,63,87,63,37,52,242,42,\n34,35,47,7,240,255,36,240,15,34,243,5,64,33,207,12,191,7,240,191,13,143,31,\n240,224,240,36,41,180,47,25,240,146,39,240,111,7,64,79,34,32,65,52,48,32,\n240,162,58,130,213,53,53,166,38,47,27,43,159,99,240,255,255,0,26,150,223,7,\n95,33,255,240,0,255,143,254,6,3,245,175,24,109,70,2,146,194,66,2,18,18,245,\n207,19,255,224,93,240,79,48,63,38,241,171,246,100,47,119,241,111,10,127,10,\n207,73,69,53,53,50,0,\n};\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/* IdentifierStart production with Letter and ASCII excluded */\n/* duk_unicode_ids_m_let_noa[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_ids_m_let_noa[42] = {\n255,240,0,94,18,255,233,99,241,51,63,254,215,32,240,184,240,2,255,240,6,89,\n249,255,240,4,148,79,37,255,224,192,9,15,120,79,255,0,15,30,245,240,\n};\n#else\n/* IdentifierStart production with Letter, ASCII, and non-BMP excluded */\n/* duk_unicode_ids_m_let_noabmp[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_ids_m_let_noabmp[24] = {\n255,240,0,94,18,255,233,99,241,51,63,254,215,32,240,184,240,2,255,240,6,89,\n249,0,\n};\n#endif\n\n#if defined(DUK_USE_SOURCE_NONBMP)\n/* IdentifierPart production with IdentifierStart and ASCII excluded */\n/* duk_unicode_idp_m_ids_noa[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_idp_m_ids_noa[576] = {\n255,225,243,246,15,254,0,116,255,191,29,32,33,33,32,243,170,242,47,15,112,\n245,118,53,49,35,57,240,144,241,15,11,244,218,240,25,241,56,160,240,163,40,\n34,36,241,210,246,158,47,17,242,130,47,2,38,177,57,240,50,242,160,38,49,50,\n160,177,57,240,0,50,242,160,36,81,50,64,240,107,64,194,242,160,39,34,34,\n240,97,57,181,34,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240,\n9,240,36,242,182,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240,\n35,242,145,38,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54,\n215,41,244,144,56,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160,\n245,111,4,41,211,82,34,54,67,235,46,255,225,179,47,254,42,98,240,242,240,\n241,241,1,243,47,16,160,57,241,50,57,245,209,241,64,246,139,91,185,247,41,\n242,244,242,185,47,13,58,121,240,141,243,68,242,31,1,201,240,56,210,241,12,\n57,241,237,242,47,4,153,121,246,130,47,5,80,112,50,251,143,42,36,255,225,0,\n31,35,31,5,15,109,197,4,191,254,175,34,247,240,245,47,16,255,225,30,95,91,\n31,255,0,100,121,159,55,5,159,18,31,66,31,254,0,64,64,80,240,148,244,161,\n242,79,2,185,127,2,234,240,231,240,188,241,227,242,29,240,25,192,185,242,\n29,208,145,57,241,50,242,64,34,49,97,32,241,180,97,253,231,33,57,255,240,3,\n225,128,255,225,213,240,15,2,240,4,31,10,47,178,159,23,15,254,27,16,253,64,\n248,116,255,224,25,159,254,68,178,33,99,241,162,80,249,113,255,225,49,57,\n159,254,16,10,250,18,242,126,241,25,240,19,241,250,242,121,114,241,109,41,\n97,241,224,210,242,45,147,73,244,75,112,249,43,105,115,242,145,38,49,50,\n160,177,54,68,251,47,2,169,80,244,63,4,217,252,118,56,240,209,244,79,1,240,\n25,244,60,153,244,94,89,254,78,249,121,253,150,54,64,240,233,241,166,35,\n144,170,242,15,0,255,224,137,114,127,2,159,42,240,98,223,108,84,2,18,98,9,\n159,34,66,18,73,159,254,3,211,255,240,3,165,217,247,132,242,214,240,185,\n255,226,233,2,242,120,63,255,0,59,254,31,255,0,3,186,68,89,115,111,16,63,\n134,47,254,71,223,34,255,224,244,242,117,242,41,15,0,15,8,66,239,254,68,70,\n47,1,54,33,36,255,118,169,255,224,150,223,254,76,166,245,246,105,255,240,\n192,105,175,224,0,\n};\n#else\n/* IdentifierPart production with IdentifierStart, ASCII, and non-BMP excluded */\n/* duk_unicode_idp_m_ids_noabmp[] */\n/*\n *  Automatically generated by extract_chars.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_idp_m_ids_noabmp[358] = {\n255,225,243,246,15,254,0,116,255,191,29,32,33,33,32,243,170,242,47,15,112,\n245,118,53,49,35,57,240,144,241,15,11,244,218,240,25,241,56,160,240,163,40,\n34,36,241,210,246,158,47,17,242,130,47,2,38,177,57,240,50,242,160,38,49,50,\n160,177,57,240,0,50,242,160,36,81,50,64,240,107,64,194,242,160,39,34,34,\n240,97,57,181,34,242,160,38,49,50,145,177,57,240,64,242,212,66,35,160,240,\n9,240,36,242,182,34,35,129,193,57,240,50,242,160,38,34,35,129,193,57,240,\n35,242,145,38,34,35,160,177,57,240,65,243,128,85,32,39,121,49,242,240,54,\n215,41,244,144,56,197,57,243,1,121,192,32,32,81,242,63,4,33,106,47,20,160,\n245,111,4,41,211,82,34,54,67,235,46,255,225,179,47,254,42,98,240,242,240,\n241,241,1,243,47,16,160,57,241,50,57,245,209,241,64,246,139,91,185,247,41,\n242,244,242,185,47,13,58,121,240,141,243,68,242,31,1,201,240,56,210,241,12,\n57,241,237,242,47,4,153,121,246,130,47,5,80,112,50,251,143,42,36,255,225,0,\n31,35,31,5,15,109,197,4,191,254,175,34,247,240,245,47,16,255,225,30,95,91,\n31,255,0,100,121,159,55,5,159,18,31,66,31,254,0,64,64,80,240,148,244,161,\n242,79,2,185,127,2,234,240,231,240,188,241,227,242,29,240,25,192,185,242,\n29,208,145,57,241,50,242,64,34,49,97,32,241,180,97,253,231,33,57,255,240,3,\n225,128,255,225,213,240,15,2,240,4,31,10,47,178,159,23,0,\n};\n#endif\n\n/*\n *  Case conversion tables generated using tools/extract_caseconv.py.\n */\n\n/* duk_unicode_caseconv_uc[] */\n/* duk_unicode_caseconv_lc[] */\n\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_caseconv_uc[1411] = {\n152,3,128,3,0,184,7,192,6,192,112,35,242,199,224,64,74,192,49,32,128,162,\n128,108,65,1,189,129,254,131,3,173,3,136,6,7,98,7,34,68,15,12,14,140,72,30,\n104,28,112,32,67,0,65,4,0,138,0,128,4,1,88,65,76,83,8,104,14,72,43,16,253,\n28,189,6,39,240,39,224,24,114,12,16,132,16,248,0,248,64,129,241,1,241,128,\n195,228,3,229,2,7,204,7,206,4,15,160,15,164,6,31,96,31,104,16,62,224,63,\n116,8,125,200,127,32,32,251,176,254,208,33,247,129,255,128,67,239,67,253,\n64,135,223,7,254,129,15,216,15,220,2,31,208,31,216,4,63,192,63,208,8,133,\n192,133,128,129,38,129,37,177,162,195,2,192,5,229,160,2,20,9,170,220,4,232,\n40,127,160,255,144,154,136,4,4,4,0,192,9,152,9,144,48,19,160,19,145,0,41,\n96,41,69,192,94,128,94,65,128,193,128,193,2,1,161,1,160,6,3,104,3,102,8,7,\n56,7,52,64,14,248,14,240,144,31,144,31,130,128,68,96,68,66,64,145,192,145,\n130,129,184,129,184,2,3,217,3,216,24,8,194,8,192,68,18,44,18,40,216,38,16,\n38,8,112,77,16,77,6,3,192,35,192,18,199,168,71,168,24,15,168,143,172,132,\n44,104,44,103,6,89,2,89,0,200,179,176,179,172,21,50,13,50,1,122,104,26,104,\n1,212,228,116,228,65,233,204,233,204,143,211,189,83,188,130,167,127,167,\n126,11,79,35,79,32,10,158,94,158,88,85,61,173,61,160,97,192,107,64,107,1,0,\n226,128,226,3,1,198,1,196,6,3,228,3,226,8,10,0,6,152,16,31,192,31,184,34,\n199,50,199,32,65,128,196,0,195,130,1,185,1,184,4,4,205,79,84,8,0,192,143,0,\n142,193,1,52,128,203,2,45,39,16,199,5,253,0,11,80,57,192,15,240,23,128,19,\n16,4,144,23,240,5,48,24,0,36,48,25,32,25,16,25,80,31,96,25,144,25,128,25,\n160,35,208,25,224,34,0,26,128,26,112,27,240,31,112,29,208,24,224,31,48,31,\n16,37,2,198,240,37,18,198,208,37,34,199,0,37,48,24,16,37,64,24,96,37,144,\n24,240,37,176,25,0,37,202,122,176,38,0,25,48,38,26,122,192,38,48,25,64,38,\n90,120,208,38,128,25,112,38,178,198,32,38,202,122,208,39,18,198,224,39,32,\n25,208,39,80,25,240,39,210,198,64,40,42,124,80,40,122,123,16,40,128,26,224,\n40,144,36,64,40,192,36,80,41,32,27,112,41,218,123,32,41,234,123,0,52,80,57,\n144,55,112,55,96,58,192,56,96,60,32,58,48,60,192,56,192,61,0,57,32,61,16,\n57,128,61,80,58,96,61,96,58,0,61,112,60,240,63,0,57,160,63,16,58,16,63,32,\n63,144,63,48,55,240,63,80,57,80,76,240,76,1,200,0,65,33,200,16,65,65,200,\n32,65,225,200,80,66,33,200,96,66,161,200,112,70,33,200,138,100,161,215,154,\n119,209,215,210,198,49,216,234,124,97,233,177,230,1,251,224,57,145,254,81,\n254,194,20,226,19,34,24,66,24,50,198,18,198,2,198,80,35,162,198,96,35,226,\n207,50,207,42,120,202,120,186,121,74,124,74,124,58,124,42,181,58,123,60,\n192,27,240,2,152,2,152,10,76,5,120,0,156,3,225,0,37,1,134,1,200,96,115,32,\n97,0,96,32,118,24,29,40,24,64,24,8,44,60,10,106,10,164,61,45,0,36,1,152,\n143,75,192,10,128,97,3,211,16,2,184,24,80,244,204,0,178,6,20,61,53,0,32,\n129,95,15,168,64,116,160,98,99,234,88,29,40,24,152,24,0,250,166,7,74,6,38,\n6,2,62,173,129,210,129,137,129,161,15,192,67,225,0,115,35,240,48,248,72,28,\n200,252,20,62,20,7,50,63,7,15,133,129,204,143,194,67,225,128,115,35,240,\n176,248,104,28,200,252,52,62,28,7,50,63,15,15,135,129,204,143,196,67,225,0,\n115,35,241,48,248,72,28,200,252,84,62,20,7,50,63,23,15,133,129,204,143,198,\n67,225,128,115,35,241,176,248,104,28,200,252,116,62,28,7,50,63,31,15,135,\n129,204,143,200,67,229,0,115,35,242,48,249,72,28,200,252,148,62,84,7,50,63,\n39,15,149,129,204,143,202,67,229,128,115,35,242,176,249,104,28,200,252,180,\n62,92,7,50,63,47,15,151,129,204,143,204,67,229,0,115,35,243,48,249,72,28,\n200,252,212,62,84,7,50,63,55,15,149,129,204,143,206,67,229,128,115,35,243,\n176,249,104,28,200,252,244,62,92,7,50,63,63,15,151,129,204,143,208,67,237,\n0,115,35,244,48,251,72,28,200,253,20,62,212,7,50,63,71,15,181,129,204,143,\n210,67,237,128,115,35,244,176,251,104,28,200,253,52,62,220,7,50,63,79,15,\n183,129,204,143,212,67,237,0,115,35,245,48,251,72,28,200,253,84,62,212,7,\n50,63,87,15,181,129,204,143,214,67,237,128,115,35,245,176,251,104,28,200,\n253,116,62,220,7,50,63,95,15,183,129,204,143,217,67,247,64,115,35,246,112,\n28,136,28,200,253,164,7,12,7,50,63,109,1,200,129,161,15,219,224,114,32,104,\n64,115,35,247,144,28,136,28,200,254,20,63,148,7,50,63,135,1,203,129,204,\n143,226,64,113,32,115,35,248,208,28,184,26,16,254,62,7,46,6,132,7,50,63,\n153,1,203,129,204,143,233,96,115,32,97,0,96,3,250,120,28,200,24,64,24,8,\n254,180,7,50,6,132,63,175,129,204,129,132,1,161,15,241,96,116,160,97,0,96,\n3,252,120,29,40,24,64,24,8,255,36,7,66,6,38,63,205,1,210,129,161,15,243,\n224,116,160,97,0,104,67,254,80,255,208,28,200,255,156,7,82,7,50,63,233,1,\n199,129,204,143,251,64,117,32,104,67,254,248,29,72,26,16,28,200,255,228,7,\n82,7,51,246,1,0,35,0,35,125,128,192,8,192,9,63,96,80,2,48,2,103,216,30,0,\n140,0,140,0,147,246,9,128,35,0,35,0,38,125,130,192,10,96,10,159,96,208,2,\n152,2,167,216,156,10,136,10,141,246,41,2,162,2,154,253,138,192,168,128,167,\n127,98,208,42,112,42,55,216,188,10,136,10,122,\n};\nconst duk_uint8_t duk_unicode_caseconv_lc[706] = {\n160,3,0,3,128,184,6,192,7,192,112,24,144,37,96,64,54,32,81,64,128,226,0,\n235,65,129,199,1,230,130,3,145,3,177,34,7,70,7,134,36,15,244,13,236,24,32,\n0,34,129,0,65,0,67,4,0,166,32,172,41,132,40,11,64,19,9,208,85,184,80,19,\n240,19,248,12,57,32,33,160,172,114,244,67,244,24,248,64,248,0,129,241,129,\n241,0,195,229,3,228,2,7,206,7,204,4,15,164,15,160,6,31,104,31,96,16,63,16,\n63,0,32,126,96,126,64,64,253,64,253,0,129,251,129,251,0,67,247,67,238,0,\n135,242,7,220,130,15,236,15,232,2,31,218,31,118,4,63,208,63,192,8,127,168,\n125,232,16,255,192,251,192,33,255,161,247,192,68,44,4,46,4,9,45,137,52,13,\n22,0,22,24,47,44,126,2,63,5,254,67,254,130,106,48,16,0,16,19,0,38,64,38,96,\n192,78,64,78,132,0,165,0,165,151,1,121,1,122,6,3,4,3,6,8,6,128,6,132,24,13,\n152,13,160,32,28,176,28,193,32,59,192,59,226,64,124,128,124,193,0,252,0,\n252,148,2,34,2,35,18,4,140,4,142,20,13,192,13,196,16,30,192,30,200,192,70,\n0,70,18,32,145,64,145,102,193,48,65,48,131,130,104,2,104,176,30,0,30,1,150,\n61,64,61,66,192,125,100,125,68,33,99,57,99,64,50,200,2,200,22,69,157,101,\n157,128,169,144,41,144,75,211,64,83,64,142,167,34,167,35,15,78,101,78,102,\n126,157,230,157,232,21,59,245,59,248,90,121,10,121,16,84,242,212,242,226,\n169,237,41,237,67,12,3,76,5,0,8,6,176,6,180,16,14,32,14,48,48,28,80,28,96,\n64,126,224,127,0,139,28,139,28,193,6,3,14,3,16,8,6,224,6,228,21,61,80,19,\n48,32,3,1,150,2,105,4,4,118,4,120,8,67,28,180,156,23,240,192,94,0,63,192,\n96,64,148,192,97,128,149,0,99,128,119,64,99,192,150,64,100,0,150,192,100,\n64,100,128,100,192,152,0,101,0,152,192,101,192,154,0,102,0,102,64,103,64,\n156,128,103,192,157,64,105,192,106,0,107,128,162,0,109,192,164,128,124,64,\n124,192,125,128,101,64,125,192,111,192,136,0,103,128,142,139,25,64,143,64,\n102,128,143,139,25,128,144,192,96,0,145,0,162,64,145,64,163,0,221,128,221,\n192,223,192,252,192,225,128,235,0,227,0,243,0,243,192,245,192,253,0,238,0,\n254,64,252,129,48,1,51,199,167,128,55,199,239,7,236,199,243,7,240,199,251,\n7,249,71,255,7,252,200,73,128,242,72,74,128,26,200,74,192,57,72,76,136,83,\n136,96,200,97,11,24,11,24,75,24,128,154,203,24,199,95,75,25,0,159,75,27,64,\n148,75,27,128,156,75,27,192,148,11,28,0,148,139,60,139,60,233,223,71,94,\n105,226,233,227,41,227,64,153,105,234,192,151,41,235,0,152,105,235,64,155,\n41,236,0,167,169,236,64,161,233,236,128,167,105,236,234,212,233,240,169,\n240,233,241,41,229,41,241,64,160,169,241,135,99,128,128,152,64,13,32,96,\n224,\n};\n\n#if defined(DUK_USE_REGEXP_CANON_WORKAROUND)\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\nconst duk_uint16_t duk_unicode_re_canon_lookup[65536] = {\n0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,\n28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,\n53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,\n78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,65,66,67,68,69,70,\n71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,123,124,125,\n126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,\n144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,\n162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,\n180,924,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,\n198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,\n216,217,218,219,220,221,222,223,192,193,194,195,196,197,198,199,200,201,\n202,203,204,205,206,207,208,209,210,211,212,213,214,247,216,217,218,219,\n220,221,222,376,256,256,258,258,260,260,262,262,264,264,266,266,268,268,\n270,270,272,272,274,274,276,276,278,278,280,280,282,282,284,284,286,286,\n288,288,290,290,292,292,294,294,296,296,298,298,300,300,302,302,304,305,\n306,306,308,308,310,310,312,313,313,315,315,317,317,319,319,321,321,323,\n323,325,325,327,327,329,330,330,332,332,334,334,336,336,338,338,340,340,\n342,342,344,344,346,346,348,348,350,350,352,352,354,354,356,356,358,358,\n360,360,362,362,364,364,366,366,368,368,370,370,372,372,374,374,376,377,\n377,379,379,381,381,383,579,385,386,386,388,388,390,391,391,393,394,395,\n395,397,398,399,400,401,401,403,404,502,406,407,408,408,573,411,412,413,\n544,415,416,416,418,418,420,420,422,423,423,425,426,427,428,428,430,431,\n431,433,434,435,435,437,437,439,440,440,442,443,444,444,446,503,448,449,\n450,451,452,452,452,455,455,455,458,458,458,461,461,463,463,465,465,467,\n467,469,469,471,471,473,473,475,475,398,478,478,480,480,482,482,484,484,\n486,486,488,488,490,490,492,492,494,494,496,497,497,497,500,500,502,503,\n504,504,506,506,508,508,510,510,512,512,514,514,516,516,518,518,520,520,\n522,522,524,524,526,526,528,528,530,530,532,532,534,534,536,536,538,538,\n540,540,542,542,544,545,546,546,548,548,550,550,552,552,554,554,556,556,\n558,558,560,560,562,562,564,565,566,567,568,569,570,571,571,573,574,11390,\n11391,577,577,579,580,581,582,582,584,584,586,586,588,588,590,590,11375,\n11373,11376,385,390,597,393,394,600,399,602,400,42923L,605,606,607,403,\n42924L,610,404,612,42893L,42922L,615,407,406,42926L,11362,42925L,621,622,\n412,624,11374,413,627,628,415,630,631,632,633,634,635,636,11364,638,639,\n422,641,42949L,425,644,645,646,42929L,430,580,433,434,581,653,654,655,656,\n657,439,659,660,661,662,663,664,665,666,667,668,42930L,42928L,671,672,673,\n674,675,676,677,678,679,680,681,682,683,684,685,686,687,688,689,690,691,\n692,693,694,695,696,697,698,699,700,701,702,703,704,705,706,707,708,709,\n710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,\n728,729,730,731,732,733,734,735,736,737,738,739,740,741,742,743,744,745,\n746,747,748,749,750,751,752,753,754,755,756,757,758,759,760,761,762,763,\n764,765,766,767,768,769,770,771,772,773,774,775,776,777,778,779,780,781,\n782,783,784,785,786,787,788,789,790,791,792,793,794,795,796,797,798,799,\n800,801,802,803,804,805,806,807,808,809,810,811,812,813,814,815,816,817,\n818,819,820,821,822,823,824,825,826,827,828,829,830,831,832,833,834,835,\n836,921,838,839,840,841,842,843,844,845,846,847,848,849,850,851,852,853,\n854,855,856,857,858,859,860,861,862,863,864,865,866,867,868,869,870,871,\n872,873,874,875,876,877,878,879,880,880,882,882,884,885,886,886,888,889,\n890,1021,1022,1023,894,895,896,897,898,899,900,901,902,903,904,905,906,907,\n908,909,910,911,912,913,914,915,916,917,918,919,920,921,922,923,924,925,\n926,927,928,929,930,931,932,933,934,935,936,937,938,939,902,904,905,906,\n944,913,914,915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,\n931,931,932,933,934,935,936,937,938,939,908,910,911,975,914,920,978,979,\n980,934,928,975,984,984,986,986,988,988,990,990,992,992,994,994,996,996,\n998,998,1000,1000,1002,1002,1004,1004,1006,1006,922,929,1017,895,1012,917,\n1014,1015,1015,1017,1018,1018,1020,1021,1022,1023,1024,1025,1026,1027,1028,\n1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,\n1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,\n1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1040,1041,\n1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,\n1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,\n1024,1025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1037,1038,\n1039,1120,1120,1122,1122,1124,1124,1126,1126,1128,1128,1130,1130,1132,1132,\n1134,1134,1136,1136,1138,1138,1140,1140,1142,1142,1144,1144,1146,1146,1148,\n1148,1150,1150,1152,1152,1154,1155,1156,1157,1158,1159,1160,1161,1162,1162,\n1164,1164,1166,1166,1168,1168,1170,1170,1172,1172,1174,1174,1176,1176,1178,\n1178,1180,1180,1182,1182,1184,1184,1186,1186,1188,1188,1190,1190,1192,1192,\n1194,1194,1196,1196,1198,1198,1200,1200,1202,1202,1204,1204,1206,1206,1208,\n1208,1210,1210,1212,1212,1214,1214,1216,1217,1217,1219,1219,1221,1221,1223,\n1223,1225,1225,1227,1227,1229,1229,1216,1232,1232,1234,1234,1236,1236,1238,\n1238,1240,1240,1242,1242,1244,1244,1246,1246,1248,1248,1250,1250,1252,1252,\n1254,1254,1256,1256,1258,1258,1260,1260,1262,1262,1264,1264,1266,1266,1268,\n1268,1270,1270,1272,1272,1274,1274,1276,1276,1278,1278,1280,1280,1282,1282,\n1284,1284,1286,1286,1288,1288,1290,1290,1292,1292,1294,1294,1296,1296,1298,\n1298,1300,1300,1302,1302,1304,1304,1306,1306,1308,1308,1310,1310,1312,1312,\n1314,1314,1316,1316,1318,1318,1320,1320,1322,1322,1324,1324,1326,1326,1328,\n1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,1341,1342,1343,\n1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,\n1359,1360,1361,1362,1363,1364,1365,1366,1367,1368,1369,1370,1371,1372,1373,\n1374,1375,1376,1329,1330,1331,1332,1333,1334,1335,1336,1337,1338,1339,1340,\n1341,1342,1343,1344,1345,1346,1347,1348,1349,1350,1351,1352,1353,1354,1355,\n1356,1357,1358,1359,1360,1361,1362,1363,1364,1365,1366,1415,1416,1417,1418,\n1419,1420,1421,1422,1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,\n1434,1435,1436,1437,1438,1439,1440,1441,1442,1443,1444,1445,1446,1447,1448,\n1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1463,\n1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477,1478,\n1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493,\n1494,1495,1496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,\n1509,1510,1511,1512,1513,1514,1515,1516,1517,1518,1519,1520,1521,1522,1523,\n1524,1525,1526,1527,1528,1529,1530,1531,1532,1533,1534,1535,1536,1537,1538,\n1539,1540,1541,1542,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,\n1554,1555,1556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,\n1569,1570,1571,1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,\n1584,1585,1586,1587,1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,\n1599,1600,1601,1602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,\n1614,1615,1616,1617,1618,1619,1620,1621,1622,1623,1624,1625,1626,1627,1628,\n1629,1630,1631,1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,\n1644,1645,1646,1647,1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,\n1659,1660,1661,1662,1663,1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,\n1674,1675,1676,1677,1678,1679,1680,1681,1682,1683,1684,1685,1686,1687,1688,\n1689,1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,\n1704,1705,1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,\n1719,1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,\n1734,1735,1736,1737,1738,1739,1740,1741,1742,1743,1744,1745,1746,1747,1748,\n1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763,\n1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,\n1779,1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,\n1794,1795,1796,1797,1798,1799,1800,1801,1802,1803,1804,1805,1806,1807,1808,\n1809,1810,1811,1812,1813,1814,1815,1816,1817,1818,1819,1820,1821,1822,1823,\n1824,1825,1826,1827,1828,1829,1830,1831,1832,1833,1834,1835,1836,1837,1838,\n1839,1840,1841,1842,1843,1844,1845,1846,1847,1848,1849,1850,1851,1852,1853,\n1854,1855,1856,1857,1858,1859,1860,1861,1862,1863,1864,1865,1866,1867,1868,\n1869,1870,1871,1872,1873,1874,1875,1876,1877,1878,1879,1880,1881,1882,1883,\n1884,1885,1886,1887,1888,1889,1890,1891,1892,1893,1894,1895,1896,1897,1898,\n1899,1900,1901,1902,1903,1904,1905,1906,1907,1908,1909,1910,1911,1912,1913,\n1914,1915,1916,1917,1918,1919,1920,1921,1922,1923,1924,1925,1926,1927,1928,\n1929,1930,1931,1932,1933,1934,1935,1936,1937,1938,1939,1940,1941,1942,1943,\n1944,1945,1946,1947,1948,1949,1950,1951,1952,1953,1954,1955,1956,1957,1958,\n1959,1960,1961,1962,1963,1964,1965,1966,1967,1968,1969,1970,1971,1972,1973,\n1974,1975,1976,1977,1978,1979,1980,1981,1982,1983,1984,1985,1986,1987,1988,\n1989,1990,1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,\n2004,2005,2006,2007,2008,2009,2010,2011,2012,2013,2014,2015,2016,2017,2018,\n2019,2020,2021,2022,2023,2024,2025,2026,2027,2028,2029,2030,2031,2032,2033,\n2034,2035,2036,2037,2038,2039,2040,2041,2042,2043,2044,2045,2046,2047,2048,\n2049,2050,2051,2052,2053,2054,2055,2056,2057,2058,2059,2060,2061,2062,2063,\n2064,2065,2066,2067,2068,2069,2070,2071,2072,2073,2074,2075,2076,2077,2078,\n2079,2080,2081,2082,2083,2084,2085,2086,2087,2088,2089,2090,2091,2092,2093,\n2094,2095,2096,2097,2098,2099,2100,2101,2102,2103,2104,2105,2106,2107,2108,\n2109,2110,2111,2112,2113,2114,2115,2116,2117,2118,2119,2120,2121,2122,2123,\n2124,2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2137,2138,\n2139,2140,2141,2142,2143,2144,2145,2146,2147,2148,2149,2150,2151,2152,2153,\n2154,2155,2156,2157,2158,2159,2160,2161,2162,2163,2164,2165,2166,2167,2168,\n2169,2170,2171,2172,2173,2174,2175,2176,2177,2178,2179,2180,2181,2182,2183,\n2184,2185,2186,2187,2188,2189,2190,2191,2192,2193,2194,2195,2196,2197,2198,\n2199,2200,2201,2202,2203,2204,2205,2206,2207,2208,2209,2210,2211,2212,2213,\n2214,2215,2216,2217,2218,2219,2220,2221,2222,2223,2224,2225,2226,2227,2228,\n2229,2230,2231,2232,2233,2234,2235,2236,2237,2238,2239,2240,2241,2242,2243,\n2244,2245,2246,2247,2248,2249,2250,2251,2252,2253,2254,2255,2256,2257,2258,\n2259,2260,2261,2262,2263,2264,2265,2266,2267,2268,2269,2270,2271,2272,2273,\n2274,2275,2276,2277,2278,2279,2280,2281,2282,2283,2284,2285,2286,2287,2288,\n2289,2290,2291,2292,2293,2294,2295,2296,2297,2298,2299,2300,2301,2302,2303,\n2304,2305,2306,2307,2308,2309,2310,2311,2312,2313,2314,2315,2316,2317,2318,\n2319,2320,2321,2322,2323,2324,2325,2326,2327,2328,2329,2330,2331,2332,2333,\n2334,2335,2336,2337,2338,2339,2340,2341,2342,2343,2344,2345,2346,2347,2348,\n2349,2350,2351,2352,2353,2354,2355,2356,2357,2358,2359,2360,2361,2362,2363,\n2364,2365,2366,2367,2368,2369,2370,2371,2372,2373,2374,2375,2376,2377,2378,\n2379,2380,2381,2382,2383,2384,2385,2386,2387,2388,2389,2390,2391,2392,2393,\n2394,2395,2396,2397,2398,2399,2400,2401,2402,2403,2404,2405,2406,2407,2408,\n2409,2410,2411,2412,2413,2414,2415,2416,2417,2418,2419,2420,2421,2422,2423,\n2424,2425,2426,2427,2428,2429,2430,2431,2432,2433,2434,2435,2436,2437,2438,\n2439,2440,2441,2442,2443,2444,2445,2446,2447,2448,2449,2450,2451,2452,2453,\n2454,2455,2456,2457,2458,2459,2460,2461,2462,2463,2464,2465,2466,2467,2468,\n2469,2470,2471,2472,2473,2474,2475,2476,2477,2478,2479,2480,2481,2482,2483,\n2484,2485,2486,2487,2488,2489,2490,2491,2492,2493,2494,2495,2496,2497,2498,\n2499,2500,2501,2502,2503,2504,2505,2506,2507,2508,2509,2510,2511,2512,2513,\n2514,2515,2516,2517,2518,2519,2520,2521,2522,2523,2524,2525,2526,2527,2528,\n2529,2530,2531,2532,2533,2534,2535,2536,2537,2538,2539,2540,2541,2542,2543,\n2544,2545,2546,2547,2548,2549,2550,2551,2552,2553,2554,2555,2556,2557,2558,\n2559,2560,2561,2562,2563,2564,2565,2566,2567,2568,2569,2570,2571,2572,2573,\n2574,2575,2576,2577,2578,2579,2580,2581,2582,2583,2584,2585,2586,2587,2588,\n2589,2590,2591,2592,2593,2594,2595,2596,2597,2598,2599,2600,2601,2602,2603,\n2604,2605,2606,2607,2608,2609,2610,2611,2612,2613,2614,2615,2616,2617,2618,\n2619,2620,2621,2622,2623,2624,2625,2626,2627,2628,2629,2630,2631,2632,2633,\n2634,2635,2636,2637,2638,2639,2640,2641,2642,2643,2644,2645,2646,2647,2648,\n2649,2650,2651,2652,2653,2654,2655,2656,2657,2658,2659,2660,2661,2662,2663,\n2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2674,2675,2676,2677,2678,\n2679,2680,2681,2682,2683,2684,2685,2686,2687,2688,2689,2690,2691,2692,2693,\n2694,2695,2696,2697,2698,2699,2700,2701,2702,2703,2704,2705,2706,2707,2708,\n2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720,2721,2722,2723,\n2724,2725,2726,2727,2728,2729,2730,2731,2732,2733,2734,2735,2736,2737,2738,\n2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750,2751,2752,2753,\n2754,2755,2756,2757,2758,2759,2760,2761,2762,2763,2764,2765,2766,2767,2768,\n2769,2770,2771,2772,2773,2774,2775,2776,2777,2778,2779,2780,2781,2782,2783,\n2784,2785,2786,2787,2788,2789,2790,2791,2792,2793,2794,2795,2796,2797,2798,\n2799,2800,2801,2802,2803,2804,2805,2806,2807,2808,2809,2810,2811,2812,2813,\n2814,2815,2816,2817,2818,2819,2820,2821,2822,2823,2824,2825,2826,2827,2828,\n2829,2830,2831,2832,2833,2834,2835,2836,2837,2838,2839,2840,2841,2842,2843,\n2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856,2857,2858,\n2859,2860,2861,2862,2863,2864,2865,2866,2867,2868,2869,2870,2871,2872,2873,\n2874,2875,2876,2877,2878,2879,2880,2881,2882,2883,2884,2885,2886,2887,2888,\n2889,2890,2891,2892,2893,2894,2895,2896,2897,2898,2899,2900,2901,2902,2903,\n2904,2905,2906,2907,2908,2909,2910,2911,2912,2913,2914,2915,2916,2917,2918,\n2919,2920,2921,2922,2923,2924,2925,2926,2927,2928,2929,2930,2931,2932,2933,\n2934,2935,2936,2937,2938,2939,2940,2941,2942,2943,2944,2945,2946,2947,2948,\n2949,2950,2951,2952,2953,2954,2955,2956,2957,2958,2959,2960,2961,2962,2963,\n2964,2965,2966,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976,2977,2978,\n2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2989,2990,2991,2992,2993,\n2994,2995,2996,2997,2998,2999,3000,3001,3002,3003,3004,3005,3006,3007,3008,\n3009,3010,3011,3012,3013,3014,3015,3016,3017,3018,3019,3020,3021,3022,3023,\n3024,3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037,3038,\n3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,3051,3052,3053,\n3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066,3067,3068,\n3069,3070,3071,3072,3073,3074,3075,3076,3077,3078,3079,3080,3081,3082,3083,\n3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095,3096,3097,3098,\n3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,3109,3110,3111,3112,3113,\n3114,3115,3116,3117,3118,3119,3120,3121,3122,3123,3124,3125,3126,3127,3128,\n3129,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140,3141,3142,3143,\n3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156,3157,3158,\n3159,3160,3161,3162,3163,3164,3165,3166,3167,3168,3169,3170,3171,3172,3173,\n3174,3175,3176,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186,3187,3188,\n3189,3190,3191,3192,3193,3194,3195,3196,3197,3198,3199,3200,3201,3202,3203,\n3204,3205,3206,3207,3208,3209,3210,3211,3212,3213,3214,3215,3216,3217,3218,\n3219,3220,3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3232,3233,\n3234,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248,\n3249,3250,3251,3252,3253,3254,3255,3256,3257,3258,3259,3260,3261,3262,3263,\n3264,3265,3266,3267,3268,3269,3270,3271,3272,3273,3274,3275,3276,3277,3278,\n3279,3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293,\n3294,3295,3296,3297,3298,3299,3300,3301,3302,3303,3304,3305,3306,3307,3308,\n3309,3310,3311,3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323,\n3324,3325,3326,3327,3328,3329,3330,3331,3332,3333,3334,3335,3336,3337,3338,\n3339,3340,3341,3342,3343,3344,3345,3346,3347,3348,3349,3350,3351,3352,3353,\n3354,3355,3356,3357,3358,3359,3360,3361,3362,3363,3364,3365,3366,3367,3368,\n3369,3370,3371,3372,3373,3374,3375,3376,3377,3378,3379,3380,3381,3382,3383,\n3384,3385,3386,3387,3388,3389,3390,3391,3392,3393,3394,3395,3396,3397,3398,\n3399,3400,3401,3402,3403,3404,3405,3406,3407,3408,3409,3410,3411,3412,3413,\n3414,3415,3416,3417,3418,3419,3420,3421,3422,3423,3424,3425,3426,3427,3428,\n3429,3430,3431,3432,3433,3434,3435,3436,3437,3438,3439,3440,3441,3442,3443,\n3444,3445,3446,3447,3448,3449,3450,3451,3452,3453,3454,3455,3456,3457,3458,\n3459,3460,3461,3462,3463,3464,3465,3466,3467,3468,3469,3470,3471,3472,3473,\n3474,3475,3476,3477,3478,3479,3480,3481,3482,3483,3484,3485,3486,3487,3488,\n3489,3490,3491,3492,3493,3494,3495,3496,3497,3498,3499,3500,3501,3502,3503,\n3504,3505,3506,3507,3508,3509,3510,3511,3512,3513,3514,3515,3516,3517,3518,\n3519,3520,3521,3522,3523,3524,3525,3526,3527,3528,3529,3530,3531,3532,3533,\n3534,3535,3536,3537,3538,3539,3540,3541,3542,3543,3544,3545,3546,3547,3548,\n3549,3550,3551,3552,3553,3554,3555,3556,3557,3558,3559,3560,3561,3562,3563,\n3564,3565,3566,3567,3568,3569,3570,3571,3572,3573,3574,3575,3576,3577,3578,\n3579,3580,3581,3582,3583,3584,3585,3586,3587,3588,3589,3590,3591,3592,3593,\n3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,3606,3607,3608,\n3609,3610,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,3621,3622,3623,\n3624,3625,3626,3627,3628,3629,3630,3631,3632,3633,3634,3635,3636,3637,3638,\n3639,3640,3641,3642,3643,3644,3645,3646,3647,3648,3649,3650,3651,3652,3653,\n3654,3655,3656,3657,3658,3659,3660,3661,3662,3663,3664,3665,3666,3667,3668,\n3669,3670,3671,3672,3673,3674,3675,3676,3677,3678,3679,3680,3681,3682,3683,\n3684,3685,3686,3687,3688,3689,3690,3691,3692,3693,3694,3695,3696,3697,3698,\n3699,3700,3701,3702,3703,3704,3705,3706,3707,3708,3709,3710,3711,3712,3713,\n3714,3715,3716,3717,3718,3719,3720,3721,3722,3723,3724,3725,3726,3727,3728,\n3729,3730,3731,3732,3733,3734,3735,3736,3737,3738,3739,3740,3741,3742,3743,\n3744,3745,3746,3747,3748,3749,3750,3751,3752,3753,3754,3755,3756,3757,3758,\n3759,3760,3761,3762,3763,3764,3765,3766,3767,3768,3769,3770,3771,3772,3773,\n3774,3775,3776,3777,3778,3779,3780,3781,3782,3783,3784,3785,3786,3787,3788,\n3789,3790,3791,3792,3793,3794,3795,3796,3797,3798,3799,3800,3801,3802,3803,\n3804,3805,3806,3807,3808,3809,3810,3811,3812,3813,3814,3815,3816,3817,3818,\n3819,3820,3821,3822,3823,3824,3825,3826,3827,3828,3829,3830,3831,3832,3833,\n3834,3835,3836,3837,3838,3839,3840,3841,3842,3843,3844,3845,3846,3847,3848,\n3849,3850,3851,3852,3853,3854,3855,3856,3857,3858,3859,3860,3861,3862,3863,\n3864,3865,3866,3867,3868,3869,3870,3871,3872,3873,3874,3875,3876,3877,3878,\n3879,3880,3881,3882,3883,3884,3885,3886,3887,3888,3889,3890,3891,3892,3893,\n3894,3895,3896,3897,3898,3899,3900,3901,3902,3903,3904,3905,3906,3907,3908,\n3909,3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,3920,3921,3922,3923,\n3924,3925,3926,3927,3928,3929,3930,3931,3932,3933,3934,3935,3936,3937,3938,\n3939,3940,3941,3942,3943,3944,3945,3946,3947,3948,3949,3950,3951,3952,3953,\n3954,3955,3956,3957,3958,3959,3960,3961,3962,3963,3964,3965,3966,3967,3968,\n3969,3970,3971,3972,3973,3974,3975,3976,3977,3978,3979,3980,3981,3982,3983,\n3984,3985,3986,3987,3988,3989,3990,3991,3992,3993,3994,3995,3996,3997,3998,\n3999,4000,4001,4002,4003,4004,4005,4006,4007,4008,4009,4010,4011,4012,4013,\n4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,4024,4025,4026,4027,4028,\n4029,4030,4031,4032,4033,4034,4035,4036,4037,4038,4039,4040,4041,4042,4043,\n4044,4045,4046,4047,4048,4049,4050,4051,4052,4053,4054,4055,4056,4057,4058,\n4059,4060,4061,4062,4063,4064,4065,4066,4067,4068,4069,4070,4071,4072,4073,\n4074,4075,4076,4077,4078,4079,4080,4081,4082,4083,4084,4085,4086,4087,4088,\n4089,4090,4091,4092,4093,4094,4095,4096,4097,4098,4099,4100,4101,4102,4103,\n4104,4105,4106,4107,4108,4109,4110,4111,4112,4113,4114,4115,4116,4117,4118,\n4119,4120,4121,4122,4123,4124,4125,4126,4127,4128,4129,4130,4131,4132,4133,\n4134,4135,4136,4137,4138,4139,4140,4141,4142,4143,4144,4145,4146,4147,4148,\n4149,4150,4151,4152,4153,4154,4155,4156,4157,4158,4159,4160,4161,4162,4163,\n4164,4165,4166,4167,4168,4169,4170,4171,4172,4173,4174,4175,4176,4177,4178,\n4179,4180,4181,4182,4183,4184,4185,4186,4187,4188,4189,4190,4191,4192,4193,\n4194,4195,4196,4197,4198,4199,4200,4201,4202,4203,4204,4205,4206,4207,4208,\n4209,4210,4211,4212,4213,4214,4215,4216,4217,4218,4219,4220,4221,4222,4223,\n4224,4225,4226,4227,4228,4229,4230,4231,4232,4233,4234,4235,4236,4237,4238,\n4239,4240,4241,4242,4243,4244,4245,4246,4247,4248,4249,4250,4251,4252,4253,\n4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265,4266,4267,4268,\n4269,4270,4271,4272,4273,4274,4275,4276,4277,4278,4279,4280,4281,4282,4283,\n4284,4285,4286,4287,4288,4289,4290,4291,4292,4293,4294,4295,4296,4297,4298,\n4299,4300,4301,4302,4303,7312,7313,7314,7315,7316,7317,7318,7319,7320,7321,\n7322,7323,7324,7325,7326,7327,7328,7329,7330,7331,7332,7333,7334,7335,7336,\n7337,7338,7339,7340,7341,7342,7343,7344,7345,7346,7347,7348,7349,7350,7351,\n7352,7353,7354,4347,4348,7357,7358,7359,4352,4353,4354,4355,4356,4357,4358,\n4359,4360,4361,4362,4363,4364,4365,4366,4367,4368,4369,4370,4371,4372,4373,\n4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,4387,4388,\n4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403,\n4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,4417,4418,\n4419,4420,4421,4422,4423,4424,4425,4426,4427,4428,4429,4430,4431,4432,4433,\n4434,4435,4436,4437,4438,4439,4440,4441,4442,4443,4444,4445,4446,4447,4448,\n4449,4450,4451,4452,4453,4454,4455,4456,4457,4458,4459,4460,4461,4462,4463,\n4464,4465,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475,4476,4477,4478,\n4479,4480,4481,4482,4483,4484,4485,4486,4487,4488,4489,4490,4491,4492,4493,\n4494,4495,4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507,4508,\n4509,4510,4511,4512,4513,4514,4515,4516,4517,4518,4519,4520,4521,4522,4523,\n4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,4536,4537,4538,\n4539,4540,4541,4542,4543,4544,4545,4546,4547,4548,4549,4550,4551,4552,4553,\n4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567,4568,\n4569,4570,4571,4572,4573,4574,4575,4576,4577,4578,4579,4580,4581,4582,4583,\n4584,4585,4586,4587,4588,4589,4590,4591,4592,4593,4594,4595,4596,4597,4598,\n4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609,4610,4611,4612,4613,\n4614,4615,4616,4617,4618,4619,4620,4621,4622,4623,4624,4625,4626,4627,4628,\n4629,4630,4631,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642,4643,\n4644,4645,4646,4647,4648,4649,4650,4651,4652,4653,4654,4655,4656,4657,4658,\n4659,4660,4661,4662,4663,4664,4665,4666,4667,4668,4669,4670,4671,4672,4673,\n4674,4675,4676,4677,4678,4679,4680,4681,4682,4683,4684,4685,4686,4687,4688,\n4689,4690,4691,4692,4693,4694,4695,4696,4697,4698,4699,4700,4701,4702,4703,\n4704,4705,4706,4707,4708,4709,4710,4711,4712,4713,4714,4715,4716,4717,4718,\n4719,4720,4721,4722,4723,4724,4725,4726,4727,4728,4729,4730,4731,4732,4733,\n4734,4735,4736,4737,4738,4739,4740,4741,4742,4743,4744,4745,4746,4747,4748,\n4749,4750,4751,4752,4753,4754,4755,4756,4757,4758,4759,4760,4761,4762,4763,\n4764,4765,4766,4767,4768,4769,4770,4771,4772,4773,4774,4775,4776,4777,4778,\n4779,4780,4781,4782,4783,4784,4785,4786,4787,4788,4789,4790,4791,4792,4793,\n4794,4795,4796,4797,4798,4799,4800,4801,4802,4803,4804,4805,4806,4807,4808,\n4809,4810,4811,4812,4813,4814,4815,4816,4817,4818,4819,4820,4821,4822,4823,\n4824,4825,4826,4827,4828,4829,4830,4831,4832,4833,4834,4835,4836,4837,4838,\n4839,4840,4841,4842,4843,4844,4845,4846,4847,4848,4849,4850,4851,4852,4853,\n4854,4855,4856,4857,4858,4859,4860,4861,4862,4863,4864,4865,4866,4867,4868,\n4869,4870,4871,4872,4873,4874,4875,4876,4877,4878,4879,4880,4881,4882,4883,\n4884,4885,4886,4887,4888,4889,4890,4891,4892,4893,4894,4895,4896,4897,4898,\n4899,4900,4901,4902,4903,4904,4905,4906,4907,4908,4909,4910,4911,4912,4913,\n4914,4915,4916,4917,4918,4919,4920,4921,4922,4923,4924,4925,4926,4927,4928,\n4929,4930,4931,4932,4933,4934,4935,4936,4937,4938,4939,4940,4941,4942,4943,\n4944,4945,4946,4947,4948,4949,4950,4951,4952,4953,4954,4955,4956,4957,4958,\n4959,4960,4961,4962,4963,4964,4965,4966,4967,4968,4969,4970,4971,4972,4973,\n4974,4975,4976,4977,4978,4979,4980,4981,4982,4983,4984,4985,4986,4987,4988,\n4989,4990,4991,4992,4993,4994,4995,4996,4997,4998,4999,5000,5001,5002,5003,\n5004,5005,5006,5007,5008,5009,5010,5011,5012,5013,5014,5015,5016,5017,5018,\n5019,5020,5021,5022,5023,5024,5025,5026,5027,5028,5029,5030,5031,5032,5033,\n5034,5035,5036,5037,5038,5039,5040,5041,5042,5043,5044,5045,5046,5047,5048,\n5049,5050,5051,5052,5053,5054,5055,5056,5057,5058,5059,5060,5061,5062,5063,\n5064,5065,5066,5067,5068,5069,5070,5071,5072,5073,5074,5075,5076,5077,5078,\n5079,5080,5081,5082,5083,5084,5085,5086,5087,5088,5089,5090,5091,5092,5093,\n5094,5095,5096,5097,5098,5099,5100,5101,5102,5103,5104,5105,5106,5107,5108,\n5109,5110,5111,5104,5105,5106,5107,5108,5109,5118,5119,5120,5121,5122,5123,\n5124,5125,5126,5127,5128,5129,5130,5131,5132,5133,5134,5135,5136,5137,5138,\n5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149,5150,5151,5152,5153,\n5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164,5165,5166,5167,5168,\n5169,5170,5171,5172,5173,5174,5175,5176,5177,5178,5179,5180,5181,5182,5183,\n5184,5185,5186,5187,5188,5189,5190,5191,5192,5193,5194,5195,5196,5197,5198,\n5199,5200,5201,5202,5203,5204,5205,5206,5207,5208,5209,5210,5211,5212,5213,\n5214,5215,5216,5217,5218,5219,5220,5221,5222,5223,5224,5225,5226,5227,5228,\n5229,5230,5231,5232,5233,5234,5235,5236,5237,5238,5239,5240,5241,5242,5243,\n5244,5245,5246,5247,5248,5249,5250,5251,5252,5253,5254,5255,5256,5257,5258,\n5259,5260,5261,5262,5263,5264,5265,5266,5267,5268,5269,5270,5271,5272,5273,\n5274,5275,5276,5277,5278,5279,5280,5281,5282,5283,5284,5285,5286,5287,5288,\n5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299,5300,5301,5302,5303,\n5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,\n5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331,5332,5333,\n5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347,5348,\n5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363,\n5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,\n5379,5380,5381,5382,5383,5384,5385,5386,5387,5388,5389,5390,5391,5392,5393,\n5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408,\n5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,\n5424,5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,\n5439,5440,5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,\n5454,5455,5456,5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,\n5469,5470,5471,5472,5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,\n5484,5485,5486,5487,5488,5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,\n5499,5500,5501,5502,5503,5504,5505,5506,5507,5508,5509,5510,5511,5512,5513,\n5514,5515,5516,5517,5518,5519,5520,5521,5522,5523,5524,5525,5526,5527,5528,\n5529,5530,5531,5532,5533,5534,5535,5536,5537,5538,5539,5540,5541,5542,5543,\n5544,5545,5546,5547,5548,5549,5550,5551,5552,5553,5554,5555,5556,5557,5558,\n5559,5560,5561,5562,5563,5564,5565,5566,5567,5568,5569,5570,5571,5572,5573,\n5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584,5585,5586,5587,5588,\n5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600,5601,5602,5603,\n5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616,5617,5618,\n5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632,5633,\n5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648,\n5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,\n5664,5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,\n5679,5680,5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,\n5694,5695,5696,5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,\n5709,5710,5711,5712,5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,\n5724,5725,5726,5727,5728,5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,\n5739,5740,5741,5742,5743,5744,5745,5746,5747,5748,5749,5750,5751,5752,5753,\n5754,5755,5756,5757,5758,5759,5760,5761,5762,5763,5764,5765,5766,5767,5768,\n5769,5770,5771,5772,5773,5774,5775,5776,5777,5778,5779,5780,5781,5782,5783,\n5784,5785,5786,5787,5788,5789,5790,5791,5792,5793,5794,5795,5796,5797,5798,\n5799,5800,5801,5802,5803,5804,5805,5806,5807,5808,5809,5810,5811,5812,5813,\n5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828,\n5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,\n5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856,5857,5858,\n5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872,5873,\n5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888,\n5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,\n5904,5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,\n5919,5920,5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,\n5934,5935,5936,5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,\n5949,5950,5951,5952,5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,\n5964,5965,5966,5967,5968,5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,\n5979,5980,5981,5982,5983,5984,5985,5986,5987,5988,5989,5990,5991,5992,5993,\n5994,5995,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008,\n6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,\n6024,6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036,6037,6038,\n6039,6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052,6053,\n6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068,\n6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,\n6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,\n6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,\n6114,6115,6116,6117,6118,6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,\n6129,6130,6131,6132,6133,6134,6135,6136,6137,6138,6139,6140,6141,6142,6143,\n6144,6145,6146,6147,6148,6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,\n6159,6160,6161,6162,6163,6164,6165,6166,6167,6168,6169,6170,6171,6172,6173,\n6174,6175,6176,6177,6178,6179,6180,6181,6182,6183,6184,6185,6186,6187,6188,\n6189,6190,6191,6192,6193,6194,6195,6196,6197,6198,6199,6200,6201,6202,6203,\n6204,6205,6206,6207,6208,6209,6210,6211,6212,6213,6214,6215,6216,6217,6218,\n6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229,6230,6231,6232,6233,\n6234,6235,6236,6237,6238,6239,6240,6241,6242,6243,6244,6245,6246,6247,6248,\n6249,6250,6251,6252,6253,6254,6255,6256,6257,6258,6259,6260,6261,6262,6263,\n6264,6265,6266,6267,6268,6269,6270,6271,6272,6273,6274,6275,6276,6277,6278,\n6279,6280,6281,6282,6283,6284,6285,6286,6287,6288,6289,6290,6291,6292,6293,\n6294,6295,6296,6297,6298,6299,6300,6301,6302,6303,6304,6305,6306,6307,6308,\n6309,6310,6311,6312,6313,6314,6315,6316,6317,6318,6319,6320,6321,6322,6323,\n6324,6325,6326,6327,6328,6329,6330,6331,6332,6333,6334,6335,6336,6337,6338,\n6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349,6350,6351,6352,6353,\n6354,6355,6356,6357,6358,6359,6360,6361,6362,6363,6364,6365,6366,6367,6368,\n6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380,6381,6382,6383,\n6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,6396,6397,6398,\n6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411,6412,6413,\n6414,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,6426,6427,6428,\n6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443,\n6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,6455,6456,6457,6458,\n6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472,6473,\n6474,6475,6476,6477,6478,6479,6480,6481,6482,6483,6484,6485,6486,6487,6488,\n6489,6490,6491,6492,6493,6494,6495,6496,6497,6498,6499,6500,6501,6502,6503,\n6504,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516,6517,6518,\n6519,6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532,6533,\n6534,6535,6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548,\n6549,6550,6551,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563,\n6564,6565,6566,6567,6568,6569,6570,6571,6572,6573,6574,6575,6576,6577,6578,\n6579,6580,6581,6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593,\n6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604,6605,6606,6607,6608,\n6609,6610,6611,6612,6613,6614,6615,6616,6617,6618,6619,6620,6621,6622,6623,\n6624,6625,6626,6627,6628,6629,6630,6631,6632,6633,6634,6635,6636,6637,6638,\n6639,6640,6641,6642,6643,6644,6645,6646,6647,6648,6649,6650,6651,6652,6653,\n6654,6655,6656,6657,6658,6659,6660,6661,6662,6663,6664,6665,6666,6667,6668,\n6669,6670,6671,6672,6673,6674,6675,6676,6677,6678,6679,6680,6681,6682,6683,\n6684,6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,6698,\n6699,6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711,6712,6713,\n6714,6715,6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,\n6729,6730,6731,6732,6733,6734,6735,6736,6737,6738,6739,6740,6741,6742,6743,\n6744,6745,6746,6747,6748,6749,6750,6751,6752,6753,6754,6755,6756,6757,6758,\n6759,6760,6761,6762,6763,6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,\n6774,6775,6776,6777,6778,6779,6780,6781,6782,6783,6784,6785,6786,6787,6788,\n6789,6790,6791,6792,6793,6794,6795,6796,6797,6798,6799,6800,6801,6802,6803,\n6804,6805,6806,6807,6808,6809,6810,6811,6812,6813,6814,6815,6816,6817,6818,\n6819,6820,6821,6822,6823,6824,6825,6826,6827,6828,6829,6830,6831,6832,6833,\n6834,6835,6836,6837,6838,6839,6840,6841,6842,6843,6844,6845,6846,6847,6848,\n6849,6850,6851,6852,6853,6854,6855,6856,6857,6858,6859,6860,6861,6862,6863,\n6864,6865,6866,6867,6868,6869,6870,6871,6872,6873,6874,6875,6876,6877,6878,\n6879,6880,6881,6882,6883,6884,6885,6886,6887,6888,6889,6890,6891,6892,6893,\n6894,6895,6896,6897,6898,6899,6900,6901,6902,6903,6904,6905,6906,6907,6908,\n6909,6910,6911,6912,6913,6914,6915,6916,6917,6918,6919,6920,6921,6922,6923,\n6924,6925,6926,6927,6928,6929,6930,6931,6932,6933,6934,6935,6936,6937,6938,\n6939,6940,6941,6942,6943,6944,6945,6946,6947,6948,6949,6950,6951,6952,6953,\n6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966,6967,6968,\n6969,6970,6971,6972,6973,6974,6975,6976,6977,6978,6979,6980,6981,6982,6983,\n6984,6985,6986,6987,6988,6989,6990,6991,6992,6993,6994,6995,6996,6997,6998,\n6999,7000,7001,7002,7003,7004,7005,7006,7007,7008,7009,7010,7011,7012,7013,\n7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027,7028,\n7029,7030,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042,7043,\n7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058,\n7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7073,\n7074,7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7086,7087,7088,\n7089,7090,7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,\n7104,7105,7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,\n7119,7120,7121,7122,7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,\n7134,7135,7136,7137,7138,7139,7140,7141,7142,7143,7144,7145,7146,7147,7148,\n7149,7150,7151,7152,7153,7154,7155,7156,7157,7158,7159,7160,7161,7162,7163,\n7164,7165,7166,7167,7168,7169,7170,7171,7172,7173,7174,7175,7176,7177,7178,\n7179,7180,7181,7182,7183,7184,7185,7186,7187,7188,7189,7190,7191,7192,7193,\n7194,7195,7196,7197,7198,7199,7200,7201,7202,7203,7204,7205,7206,7207,7208,\n7209,7210,7211,7212,7213,7214,7215,7216,7217,7218,7219,7220,7221,7222,7223,\n7224,7225,7226,7227,7228,7229,7230,7231,7232,7233,7234,7235,7236,7237,7238,\n7239,7240,7241,7242,7243,7244,7245,7246,7247,7248,7249,7250,7251,7252,7253,\n7254,7255,7256,7257,7258,7259,7260,7261,7262,7263,7264,7265,7266,7267,7268,\n7269,7270,7271,7272,7273,7274,7275,7276,7277,7278,7279,7280,7281,7282,7283,\n7284,7285,7286,7287,7288,7289,7290,7291,7292,7293,7294,7295,1042,1044,1054,\n1057,1058,1058,1066,1122,42570L,7305,7306,7307,7308,7309,7310,7311,7312,\n7313,7314,7315,7316,7317,7318,7319,7320,7321,7322,7323,7324,7325,7326,7327,\n7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339,7340,7341,7342,\n7343,7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,7354,7355,7356,7357,\n7358,7359,7360,7361,7362,7363,7364,7365,7366,7367,7368,7369,7370,7371,7372,\n7373,7374,7375,7376,7377,7378,7379,7380,7381,7382,7383,7384,7385,7386,7387,\n7388,7389,7390,7391,7392,7393,7394,7395,7396,7397,7398,7399,7400,7401,7402,\n7403,7404,7405,7406,7407,7408,7409,7410,7411,7412,7413,7414,7415,7416,7417,\n7418,7419,7420,7421,7422,7423,7424,7425,7426,7427,7428,7429,7430,7431,7432,\n7433,7434,7435,7436,7437,7438,7439,7440,7441,7442,7443,7444,7445,7446,7447,\n7448,7449,7450,7451,7452,7453,7454,7455,7456,7457,7458,7459,7460,7461,7462,\n7463,7464,7465,7466,7467,7468,7469,7470,7471,7472,7473,7474,7475,7476,7477,\n7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491,7492,\n7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,7503,7504,7505,7506,7507,\n7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,7520,7521,7522,\n7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537,\n7538,7539,7540,7541,7542,7543,7544,42877L,7546,7547,7548,11363,7550,7551,\n7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,\n42950L,7567,7568,7569,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,\n7580,7581,7582,7583,7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,\n7595,7596,7597,7598,7599,7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,\n7610,7611,7612,7613,7614,7615,7616,7617,7618,7619,7620,7621,7622,7623,7624,\n7625,7626,7627,7628,7629,7630,7631,7632,7633,7634,7635,7636,7637,7638,7639,\n7640,7641,7642,7643,7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654,\n7655,7656,7657,7658,7659,7660,7661,7662,7663,7664,7665,7666,7667,7668,7669,\n7670,7671,7672,7673,7674,7675,7676,7677,7678,7679,7680,7680,7682,7682,7684,\n7684,7686,7686,7688,7688,7690,7690,7692,7692,7694,7694,7696,7696,7698,7698,\n7700,7700,7702,7702,7704,7704,7706,7706,7708,7708,7710,7710,7712,7712,7714,\n7714,7716,7716,7718,7718,7720,7720,7722,7722,7724,7724,7726,7726,7728,7728,\n7730,7730,7732,7732,7734,7734,7736,7736,7738,7738,7740,7740,7742,7742,7744,\n7744,7746,7746,7748,7748,7750,7750,7752,7752,7754,7754,7756,7756,7758,7758,\n7760,7760,7762,7762,7764,7764,7766,7766,7768,7768,7770,7770,7772,7772,7774,\n7774,7776,7776,7778,7778,7780,7780,7782,7782,7784,7784,7786,7786,7788,7788,\n7790,7790,7792,7792,7794,7794,7796,7796,7798,7798,7800,7800,7802,7802,7804,\n7804,7806,7806,7808,7808,7810,7810,7812,7812,7814,7814,7816,7816,7818,7818,\n7820,7820,7822,7822,7824,7824,7826,7826,7828,7828,7830,7831,7832,7833,7834,\n7776,7836,7837,7838,7839,7840,7840,7842,7842,7844,7844,7846,7846,7848,7848,\n7850,7850,7852,7852,7854,7854,7856,7856,7858,7858,7860,7860,7862,7862,7864,\n7864,7866,7866,7868,7868,7870,7870,7872,7872,7874,7874,7876,7876,7878,7878,\n7880,7880,7882,7882,7884,7884,7886,7886,7888,7888,7890,7890,7892,7892,7894,\n7894,7896,7896,7898,7898,7900,7900,7902,7902,7904,7904,7906,7906,7908,7908,\n7910,7910,7912,7912,7914,7914,7916,7916,7918,7918,7920,7920,7922,7922,7924,\n7924,7926,7926,7928,7928,7930,7930,7932,7932,7934,7934,7944,7945,7946,7947,\n7948,7949,7950,7951,7944,7945,7946,7947,7948,7949,7950,7951,7960,7961,7962,\n7963,7964,7965,7958,7959,7960,7961,7962,7963,7964,7965,7966,7967,7976,7977,\n7978,7979,7980,7981,7982,7983,7976,7977,7978,7979,7980,7981,7982,7983,7992,\n7993,7994,7995,7996,7997,7998,7999,7992,7993,7994,7995,7996,7997,7998,7999,\n8008,8009,8010,8011,8012,8013,8006,8007,8008,8009,8010,8011,8012,8013,8014,\n8015,8016,8025,8018,8027,8020,8029,8022,8031,8024,8025,8026,8027,8028,8029,\n8030,8031,8040,8041,8042,8043,8044,8045,8046,8047,8040,8041,8042,8043,8044,\n8045,8046,8047,8122,8123,8136,8137,8138,8139,8154,8155,8184,8185,8170,8171,\n8186,8187,8062,8063,8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,\n8075,8076,8077,8078,8079,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,\n8090,8091,8092,8093,8094,8095,8096,8097,8098,8099,8100,8101,8102,8103,8104,\n8105,8106,8107,8108,8109,8110,8111,8120,8121,8114,8115,8116,8117,8118,8119,\n8120,8121,8122,8123,8124,8125,921,8127,8128,8129,8130,8131,8132,8133,8134,\n8135,8136,8137,8138,8139,8140,8141,8142,8143,8152,8153,8146,8147,8148,8149,\n8150,8151,8152,8153,8154,8155,8156,8157,8158,8159,8168,8169,8162,8163,8164,\n8172,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175,8176,8177,8178,8179,\n8180,8181,8182,8183,8184,8185,8186,8187,8188,8189,8190,8191,8192,8193,8194,\n8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207,8208,8209,\n8210,8211,8212,8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223,8224,\n8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239,\n8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,\n8255,8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,\n8270,8271,8272,8273,8274,8275,8276,8277,8278,8279,8280,8281,8282,8283,8284,\n8285,8286,8287,8288,8289,8290,8291,8292,8293,8294,8295,8296,8297,8298,8299,\n8300,8301,8302,8303,8304,8305,8306,8307,8308,8309,8310,8311,8312,8313,8314,\n8315,8316,8317,8318,8319,8320,8321,8322,8323,8324,8325,8326,8327,8328,8329,\n8330,8331,8332,8333,8334,8335,8336,8337,8338,8339,8340,8341,8342,8343,8344,\n8345,8346,8347,8348,8349,8350,8351,8352,8353,8354,8355,8356,8357,8358,8359,\n8360,8361,8362,8363,8364,8365,8366,8367,8368,8369,8370,8371,8372,8373,8374,\n8375,8376,8377,8378,8379,8380,8381,8382,8383,8384,8385,8386,8387,8388,8389,\n8390,8391,8392,8393,8394,8395,8396,8397,8398,8399,8400,8401,8402,8403,8404,\n8405,8406,8407,8408,8409,8410,8411,8412,8413,8414,8415,8416,8417,8418,8419,\n8420,8421,8422,8423,8424,8425,8426,8427,8428,8429,8430,8431,8432,8433,8434,\n8435,8436,8437,8438,8439,8440,8441,8442,8443,8444,8445,8446,8447,8448,8449,\n8450,8451,8452,8453,8454,8455,8456,8457,8458,8459,8460,8461,8462,8463,8464,\n8465,8466,8467,8468,8469,8470,8471,8472,8473,8474,8475,8476,8477,8478,8479,\n8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490,8491,8492,8493,8494,\n8495,8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8506,8507,8508,8509,\n8510,8511,8512,8513,8514,8515,8516,8517,8518,8519,8520,8521,8522,8523,8524,\n8525,8498,8527,8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538,8539,\n8540,8541,8542,8543,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,\n8555,8556,8557,8558,8559,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,\n8554,8555,8556,8557,8558,8559,8576,8577,8578,8579,8579,8581,8582,8583,8584,\n8585,8586,8587,8588,8589,8590,8591,8592,8593,8594,8595,8596,8597,8598,8599,\n8600,8601,8602,8603,8604,8605,8606,8607,8608,8609,8610,8611,8612,8613,8614,\n8615,8616,8617,8618,8619,8620,8621,8622,8623,8624,8625,8626,8627,8628,8629,\n8630,8631,8632,8633,8634,8635,8636,8637,8638,8639,8640,8641,8642,8643,8644,\n8645,8646,8647,8648,8649,8650,8651,8652,8653,8654,8655,8656,8657,8658,8659,\n8660,8661,8662,8663,8664,8665,8666,8667,8668,8669,8670,8671,8672,8673,8674,\n8675,8676,8677,8678,8679,8680,8681,8682,8683,8684,8685,8686,8687,8688,8689,\n8690,8691,8692,8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703,8704,\n8705,8706,8707,8708,8709,8710,8711,8712,8713,8714,8715,8716,8717,8718,8719,\n8720,8721,8722,8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,8734,\n8735,8736,8737,8738,8739,8740,8741,8742,8743,8744,8745,8746,8747,8748,8749,\n8750,8751,8752,8753,8754,8755,8756,8757,8758,8759,8760,8761,8762,8763,8764,\n8765,8766,8767,8768,8769,8770,8771,8772,8773,8774,8775,8776,8777,8778,8779,\n8780,8781,8782,8783,8784,8785,8786,8787,8788,8789,8790,8791,8792,8793,8794,\n8795,8796,8797,8798,8799,8800,8801,8802,8803,8804,8805,8806,8807,8808,8809,\n8810,8811,8812,8813,8814,8815,8816,8817,8818,8819,8820,8821,8822,8823,8824,\n8825,8826,8827,8828,8829,8830,8831,8832,8833,8834,8835,8836,8837,8838,8839,\n8840,8841,8842,8843,8844,8845,8846,8847,8848,8849,8850,8851,8852,8853,8854,\n8855,8856,8857,8858,8859,8860,8861,8862,8863,8864,8865,8866,8867,8868,8869,\n8870,8871,8872,8873,8874,8875,8876,8877,8878,8879,8880,8881,8882,8883,8884,\n8885,8886,8887,8888,8889,8890,8891,8892,8893,8894,8895,8896,8897,8898,8899,\n8900,8901,8902,8903,8904,8905,8906,8907,8908,8909,8910,8911,8912,8913,8914,\n8915,8916,8917,8918,8919,8920,8921,8922,8923,8924,8925,8926,8927,8928,8929,\n8930,8931,8932,8933,8934,8935,8936,8937,8938,8939,8940,8941,8942,8943,8944,\n8945,8946,8947,8948,8949,8950,8951,8952,8953,8954,8955,8956,8957,8958,8959,\n8960,8961,8962,8963,8964,8965,8966,8967,8968,8969,8970,8971,8972,8973,8974,\n8975,8976,8977,8978,8979,8980,8981,8982,8983,8984,8985,8986,8987,8988,8989,\n8990,8991,8992,8993,8994,8995,8996,8997,8998,8999,9000,9001,9002,9003,9004,\n9005,9006,9007,9008,9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019,\n9020,9021,9022,9023,9024,9025,9026,9027,9028,9029,9030,9031,9032,9033,9034,\n9035,9036,9037,9038,9039,9040,9041,9042,9043,9044,9045,9046,9047,9048,9049,\n9050,9051,9052,9053,9054,9055,9056,9057,9058,9059,9060,9061,9062,9063,9064,\n9065,9066,9067,9068,9069,9070,9071,9072,9073,9074,9075,9076,9077,9078,9079,\n9080,9081,9082,9083,9084,9085,9086,9087,9088,9089,9090,9091,9092,9093,9094,\n9095,9096,9097,9098,9099,9100,9101,9102,9103,9104,9105,9106,9107,9108,9109,\n9110,9111,9112,9113,9114,9115,9116,9117,9118,9119,9120,9121,9122,9123,9124,\n9125,9126,9127,9128,9129,9130,9131,9132,9133,9134,9135,9136,9137,9138,9139,\n9140,9141,9142,9143,9144,9145,9146,9147,9148,9149,9150,9151,9152,9153,9154,\n9155,9156,9157,9158,9159,9160,9161,9162,9163,9164,9165,9166,9167,9168,9169,\n9170,9171,9172,9173,9174,9175,9176,9177,9178,9179,9180,9181,9182,9183,9184,\n9185,9186,9187,9188,9189,9190,9191,9192,9193,9194,9195,9196,9197,9198,9199,\n9200,9201,9202,9203,9204,9205,9206,9207,9208,9209,9210,9211,9212,9213,9214,\n9215,9216,9217,9218,9219,9220,9221,9222,9223,9224,9225,9226,9227,9228,9229,\n9230,9231,9232,9233,9234,9235,9236,9237,9238,9239,9240,9241,9242,9243,9244,\n9245,9246,9247,9248,9249,9250,9251,9252,9253,9254,9255,9256,9257,9258,9259,\n9260,9261,9262,9263,9264,9265,9266,9267,9268,9269,9270,9271,9272,9273,9274,\n9275,9276,9277,9278,9279,9280,9281,9282,9283,9284,9285,9286,9287,9288,9289,\n9290,9291,9292,9293,9294,9295,9296,9297,9298,9299,9300,9301,9302,9303,9304,\n9305,9306,9307,9308,9309,9310,9311,9312,9313,9314,9315,9316,9317,9318,9319,\n9320,9321,9322,9323,9324,9325,9326,9327,9328,9329,9330,9331,9332,9333,9334,\n9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,9346,9347,9348,9349,\n9350,9351,9352,9353,9354,9355,9356,9357,9358,9359,9360,9361,9362,9363,9364,\n9365,9366,9367,9368,9369,9370,9371,9372,9373,9374,9375,9376,9377,9378,9379,\n9380,9381,9382,9383,9384,9385,9386,9387,9388,9389,9390,9391,9392,9393,9394,\n9395,9396,9397,9398,9399,9400,9401,9402,9403,9404,9405,9406,9407,9408,9409,\n9410,9411,9412,9413,9414,9415,9416,9417,9418,9419,9420,9421,9422,9423,9398,\n9399,9400,9401,9402,9403,9404,9405,9406,9407,9408,9409,9410,9411,9412,9413,\n9414,9415,9416,9417,9418,9419,9420,9421,9422,9423,9450,9451,9452,9453,9454,\n9455,9456,9457,9458,9459,9460,9461,9462,9463,9464,9465,9466,9467,9468,9469,\n9470,9471,9472,9473,9474,9475,9476,9477,9478,9479,9480,9481,9482,9483,9484,\n9485,9486,9487,9488,9489,9490,9491,9492,9493,9494,9495,9496,9497,9498,9499,\n9500,9501,9502,9503,9504,9505,9506,9507,9508,9509,9510,9511,9512,9513,9514,\n9515,9516,9517,9518,9519,9520,9521,9522,9523,9524,9525,9526,9527,9528,9529,\n9530,9531,9532,9533,9534,9535,9536,9537,9538,9539,9540,9541,9542,9543,9544,\n9545,9546,9547,9548,9549,9550,9551,9552,9553,9554,9555,9556,9557,9558,9559,\n9560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,\n9575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9588,9589,\n9590,9591,9592,9593,9594,9595,9596,9597,9598,9599,9600,9601,9602,9603,9604,\n9605,9606,9607,9608,9609,9610,9611,9612,9613,9614,9615,9616,9617,9618,9619,\n9620,9621,9622,9623,9624,9625,9626,9627,9628,9629,9630,9631,9632,9633,9634,\n9635,9636,9637,9638,9639,9640,9641,9642,9643,9644,9645,9646,9647,9648,9649,\n9650,9651,9652,9653,9654,9655,9656,9657,9658,9659,9660,9661,9662,9663,9664,\n9665,9666,9667,9668,9669,9670,9671,9672,9673,9674,9675,9676,9677,9678,9679,\n9680,9681,9682,9683,9684,9685,9686,9687,9688,9689,9690,9691,9692,9693,9694,\n9695,9696,9697,9698,9699,9700,9701,9702,9703,9704,9705,9706,9707,9708,9709,\n9710,9711,9712,9713,9714,9715,9716,9717,9718,9719,9720,9721,9722,9723,9724,\n9725,9726,9727,9728,9729,9730,9731,9732,9733,9734,9735,9736,9737,9738,9739,\n9740,9741,9742,9743,9744,9745,9746,9747,9748,9749,9750,9751,9752,9753,9754,\n9755,9756,9757,9758,9759,9760,9761,9762,9763,9764,9765,9766,9767,9768,9769,\n9770,9771,9772,9773,9774,9775,9776,9777,9778,9779,9780,9781,9782,9783,9784,\n9785,9786,9787,9788,9789,9790,9791,9792,9793,9794,9795,9796,9797,9798,9799,\n9800,9801,9802,9803,9804,9805,9806,9807,9808,9809,9810,9811,9812,9813,9814,\n9815,9816,9817,9818,9819,9820,9821,9822,9823,9824,9825,9826,9827,9828,9829,\n9830,9831,9832,9833,9834,9835,9836,9837,9838,9839,9840,9841,9842,9843,9844,\n9845,9846,9847,9848,9849,9850,9851,9852,9853,9854,9855,9856,9857,9858,9859,\n9860,9861,9862,9863,9864,9865,9866,9867,9868,9869,9870,9871,9872,9873,9874,\n9875,9876,9877,9878,9879,9880,9881,9882,9883,9884,9885,9886,9887,9888,9889,\n9890,9891,9892,9893,9894,9895,9896,9897,9898,9899,9900,9901,9902,9903,9904,\n9905,9906,9907,9908,9909,9910,9911,9912,9913,9914,9915,9916,9917,9918,9919,\n9920,9921,9922,9923,9924,9925,9926,9927,9928,9929,9930,9931,9932,9933,9934,\n9935,9936,9937,9938,9939,9940,9941,9942,9943,9944,9945,9946,9947,9948,9949,\n9950,9951,9952,9953,9954,9955,9956,9957,9958,9959,9960,9961,9962,9963,9964,\n9965,9966,9967,9968,9969,9970,9971,9972,9973,9974,9975,9976,9977,9978,9979,\n9980,9981,9982,9983,9984,9985,9986,9987,9988,9989,9990,9991,9992,9993,9994,\n9995,9996,9997,9998,9999,10000,10001,10002,10003,10004,10005,10006,10007,\n10008,10009,10010,10011,10012,10013,10014,10015,10016,10017,10018,10019,\n10020,10021,10022,10023,10024,10025,10026,10027,10028,10029,10030,10031,\n10032,10033,10034,10035,10036,10037,10038,10039,10040,10041,10042,10043,\n10044,10045,10046,10047,10048,10049,10050,10051,10052,10053,10054,10055,\n10056,10057,10058,10059,10060,10061,10062,10063,10064,10065,10066,10067,\n10068,10069,10070,10071,10072,10073,10074,10075,10076,10077,10078,10079,\n10080,10081,10082,10083,10084,10085,10086,10087,10088,10089,10090,10091,\n10092,10093,10094,10095,10096,10097,10098,10099,10100,10101,10102,10103,\n10104,10105,10106,10107,10108,10109,10110,10111,10112,10113,10114,10115,\n10116,10117,10118,10119,10120,10121,10122,10123,10124,10125,10126,10127,\n10128,10129,10130,10131,10132,10133,10134,10135,10136,10137,10138,10139,\n10140,10141,10142,10143,10144,10145,10146,10147,10148,10149,10150,10151,\n10152,10153,10154,10155,10156,10157,10158,10159,10160,10161,10162,10163,\n10164,10165,10166,10167,10168,10169,10170,10171,10172,10173,10174,10175,\n10176,10177,10178,10179,10180,10181,10182,10183,10184,10185,10186,10187,\n10188,10189,10190,10191,10192,10193,10194,10195,10196,10197,10198,10199,\n10200,10201,10202,10203,10204,10205,10206,10207,10208,10209,10210,10211,\n10212,10213,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,\n10224,10225,10226,10227,10228,10229,10230,10231,10232,10233,10234,10235,\n10236,10237,10238,10239,10240,10241,10242,10243,10244,10245,10246,10247,\n10248,10249,10250,10251,10252,10253,10254,10255,10256,10257,10258,10259,\n10260,10261,10262,10263,10264,10265,10266,10267,10268,10269,10270,10271,\n10272,10273,10274,10275,10276,10277,10278,10279,10280,10281,10282,10283,\n10284,10285,10286,10287,10288,10289,10290,10291,10292,10293,10294,10295,\n10296,10297,10298,10299,10300,10301,10302,10303,10304,10305,10306,10307,\n10308,10309,10310,10311,10312,10313,10314,10315,10316,10317,10318,10319,\n10320,10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,10331,\n10332,10333,10334,10335,10336,10337,10338,10339,10340,10341,10342,10343,\n10344,10345,10346,10347,10348,10349,10350,10351,10352,10353,10354,10355,\n10356,10357,10358,10359,10360,10361,10362,10363,10364,10365,10366,10367,\n10368,10369,10370,10371,10372,10373,10374,10375,10376,10377,10378,10379,\n10380,10381,10382,10383,10384,10385,10386,10387,10388,10389,10390,10391,\n10392,10393,10394,10395,10396,10397,10398,10399,10400,10401,10402,10403,\n10404,10405,10406,10407,10408,10409,10410,10411,10412,10413,10414,10415,\n10416,10417,10418,10419,10420,10421,10422,10423,10424,10425,10426,10427,\n10428,10429,10430,10431,10432,10433,10434,10435,10436,10437,10438,10439,\n10440,10441,10442,10443,10444,10445,10446,10447,10448,10449,10450,10451,\n10452,10453,10454,10455,10456,10457,10458,10459,10460,10461,10462,10463,\n10464,10465,10466,10467,10468,10469,10470,10471,10472,10473,10474,10475,\n10476,10477,10478,10479,10480,10481,10482,10483,10484,10485,10486,10487,\n10488,10489,10490,10491,10492,10493,10494,10495,10496,10497,10498,10499,\n10500,10501,10502,10503,10504,10505,10506,10507,10508,10509,10510,10511,\n10512,10513,10514,10515,10516,10517,10518,10519,10520,10521,10522,10523,\n10524,10525,10526,10527,10528,10529,10530,10531,10532,10533,10534,10535,\n10536,10537,10538,10539,10540,10541,10542,10543,10544,10545,10546,10547,\n10548,10549,10550,10551,10552,10553,10554,10555,10556,10557,10558,10559,\n10560,10561,10562,10563,10564,10565,10566,10567,10568,10569,10570,10571,\n10572,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,10583,\n10584,10585,10586,10587,10588,10589,10590,10591,10592,10593,10594,10595,\n10596,10597,10598,10599,10600,10601,10602,10603,10604,10605,10606,10607,\n10608,10609,10610,10611,10612,10613,10614,10615,10616,10617,10618,10619,\n10620,10621,10622,10623,10624,10625,10626,10627,10628,10629,10630,10631,\n10632,10633,10634,10635,10636,10637,10638,10639,10640,10641,10642,10643,\n10644,10645,10646,10647,10648,10649,10650,10651,10652,10653,10654,10655,\n10656,10657,10658,10659,10660,10661,10662,10663,10664,10665,10666,10667,\n10668,10669,10670,10671,10672,10673,10674,10675,10676,10677,10678,10679,\n10680,10681,10682,10683,10684,10685,10686,10687,10688,10689,10690,10691,\n10692,10693,10694,10695,10696,10697,10698,10699,10700,10701,10702,10703,\n10704,10705,10706,10707,10708,10709,10710,10711,10712,10713,10714,10715,\n10716,10717,10718,10719,10720,10721,10722,10723,10724,10725,10726,10727,\n10728,10729,10730,10731,10732,10733,10734,10735,10736,10737,10738,10739,\n10740,10741,10742,10743,10744,10745,10746,10747,10748,10749,10750,10751,\n10752,10753,10754,10755,10756,10757,10758,10759,10760,10761,10762,10763,\n10764,10765,10766,10767,10768,10769,10770,10771,10772,10773,10774,10775,\n10776,10777,10778,10779,10780,10781,10782,10783,10784,10785,10786,10787,\n10788,10789,10790,10791,10792,10793,10794,10795,10796,10797,10798,10799,\n10800,10801,10802,10803,10804,10805,10806,10807,10808,10809,10810,10811,\n10812,10813,10814,10815,10816,10817,10818,10819,10820,10821,10822,10823,\n10824,10825,10826,10827,10828,10829,10830,10831,10832,10833,10834,10835,\n10836,10837,10838,10839,10840,10841,10842,10843,10844,10845,10846,10847,\n10848,10849,10850,10851,10852,10853,10854,10855,10856,10857,10858,10859,\n10860,10861,10862,10863,10864,10865,10866,10867,10868,10869,10870,10871,\n10872,10873,10874,10875,10876,10877,10878,10879,10880,10881,10882,10883,\n10884,10885,10886,10887,10888,10889,10890,10891,10892,10893,10894,10895,\n10896,10897,10898,10899,10900,10901,10902,10903,10904,10905,10906,10907,\n10908,10909,10910,10911,10912,10913,10914,10915,10916,10917,10918,10919,\n10920,10921,10922,10923,10924,10925,10926,10927,10928,10929,10930,10931,\n10932,10933,10934,10935,10936,10937,10938,10939,10940,10941,10942,10943,\n10944,10945,10946,10947,10948,10949,10950,10951,10952,10953,10954,10955,\n10956,10957,10958,10959,10960,10961,10962,10963,10964,10965,10966,10967,\n10968,10969,10970,10971,10972,10973,10974,10975,10976,10977,10978,10979,\n10980,10981,10982,10983,10984,10985,10986,10987,10988,10989,10990,10991,\n10992,10993,10994,10995,10996,10997,10998,10999,11000,11001,11002,11003,\n11004,11005,11006,11007,11008,11009,11010,11011,11012,11013,11014,11015,\n11016,11017,11018,11019,11020,11021,11022,11023,11024,11025,11026,11027,\n11028,11029,11030,11031,11032,11033,11034,11035,11036,11037,11038,11039,\n11040,11041,11042,11043,11044,11045,11046,11047,11048,11049,11050,11051,\n11052,11053,11054,11055,11056,11057,11058,11059,11060,11061,11062,11063,\n11064,11065,11066,11067,11068,11069,11070,11071,11072,11073,11074,11075,\n11076,11077,11078,11079,11080,11081,11082,11083,11084,11085,11086,11087,\n11088,11089,11090,11091,11092,11093,11094,11095,11096,11097,11098,11099,\n11100,11101,11102,11103,11104,11105,11106,11107,11108,11109,11110,11111,\n11112,11113,11114,11115,11116,11117,11118,11119,11120,11121,11122,11123,\n11124,11125,11126,11127,11128,11129,11130,11131,11132,11133,11134,11135,\n11136,11137,11138,11139,11140,11141,11142,11143,11144,11145,11146,11147,\n11148,11149,11150,11151,11152,11153,11154,11155,11156,11157,11158,11159,\n11160,11161,11162,11163,11164,11165,11166,11167,11168,11169,11170,11171,\n11172,11173,11174,11175,11176,11177,11178,11179,11180,11181,11182,11183,\n11184,11185,11186,11187,11188,11189,11190,11191,11192,11193,11194,11195,\n11196,11197,11198,11199,11200,11201,11202,11203,11204,11205,11206,11207,\n11208,11209,11210,11211,11212,11213,11214,11215,11216,11217,11218,11219,\n11220,11221,11222,11223,11224,11225,11226,11227,11228,11229,11230,11231,\n11232,11233,11234,11235,11236,11237,11238,11239,11240,11241,11242,11243,\n11244,11245,11246,11247,11248,11249,11250,11251,11252,11253,11254,11255,\n11256,11257,11258,11259,11260,11261,11262,11263,11264,11265,11266,11267,\n11268,11269,11270,11271,11272,11273,11274,11275,11276,11277,11278,11279,\n11280,11281,11282,11283,11284,11285,11286,11287,11288,11289,11290,11291,\n11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,\n11304,11305,11306,11307,11308,11309,11310,11311,11264,11265,11266,11267,\n11268,11269,11270,11271,11272,11273,11274,11275,11276,11277,11278,11279,\n11280,11281,11282,11283,11284,11285,11286,11287,11288,11289,11290,11291,\n11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,\n11304,11305,11306,11307,11308,11309,11310,11359,11360,11360,11362,11363,\n11364,570,574,11367,11367,11369,11369,11371,11371,11373,11374,11375,11376,\n11377,11378,11378,11380,11381,11381,11383,11384,11385,11386,11387,11388,\n11389,11390,11391,11392,11392,11394,11394,11396,11396,11398,11398,11400,\n11400,11402,11402,11404,11404,11406,11406,11408,11408,11410,11410,11412,\n11412,11414,11414,11416,11416,11418,11418,11420,11420,11422,11422,11424,\n11424,11426,11426,11428,11428,11430,11430,11432,11432,11434,11434,11436,\n11436,11438,11438,11440,11440,11442,11442,11444,11444,11446,11446,11448,\n11448,11450,11450,11452,11452,11454,11454,11456,11456,11458,11458,11460,\n11460,11462,11462,11464,11464,11466,11466,11468,11468,11470,11470,11472,\n11472,11474,11474,11476,11476,11478,11478,11480,11480,11482,11482,11484,\n11484,11486,11486,11488,11488,11490,11490,11492,11493,11494,11495,11496,\n11497,11498,11499,11499,11501,11501,11503,11504,11505,11506,11506,11508,\n11509,11510,11511,11512,11513,11514,11515,11516,11517,11518,11519,4256,\n4257,4258,4259,4260,4261,4262,4263,4264,4265,4266,4267,4268,4269,4270,4271,\n4272,4273,4274,4275,4276,4277,4278,4279,4280,4281,4282,4283,4284,4285,4286,\n4287,4288,4289,4290,4291,4292,4293,11558,4295,11560,11561,11562,11563,\n11564,4301,11566,11567,11568,11569,11570,11571,11572,11573,11574,11575,\n11576,11577,11578,11579,11580,11581,11582,11583,11584,11585,11586,11587,\n11588,11589,11590,11591,11592,11593,11594,11595,11596,11597,11598,11599,\n11600,11601,11602,11603,11604,11605,11606,11607,11608,11609,11610,11611,\n11612,11613,11614,11615,11616,11617,11618,11619,11620,11621,11622,11623,\n11624,11625,11626,11627,11628,11629,11630,11631,11632,11633,11634,11635,\n11636,11637,11638,11639,11640,11641,11642,11643,11644,11645,11646,11647,\n11648,11649,11650,11651,11652,11653,11654,11655,11656,11657,11658,11659,\n11660,11661,11662,11663,11664,11665,11666,11667,11668,11669,11670,11671,\n11672,11673,11674,11675,11676,11677,11678,11679,11680,11681,11682,11683,\n11684,11685,11686,11687,11688,11689,11690,11691,11692,11693,11694,11695,\n11696,11697,11698,11699,11700,11701,11702,11703,11704,11705,11706,11707,\n11708,11709,11710,11711,11712,11713,11714,11715,11716,11717,11718,11719,\n11720,11721,11722,11723,11724,11725,11726,11727,11728,11729,11730,11731,\n11732,11733,11734,11735,11736,11737,11738,11739,11740,11741,11742,11743,\n11744,11745,11746,11747,11748,11749,11750,11751,11752,11753,11754,11755,\n11756,11757,11758,11759,11760,11761,11762,11763,11764,11765,11766,11767,\n11768,11769,11770,11771,11772,11773,11774,11775,11776,11777,11778,11779,\n11780,11781,11782,11783,11784,11785,11786,11787,11788,11789,11790,11791,\n11792,11793,11794,11795,11796,11797,11798,11799,11800,11801,11802,11803,\n11804,11805,11806,11807,11808,11809,11810,11811,11812,11813,11814,11815,\n11816,11817,11818,11819,11820,11821,11822,11823,11824,11825,11826,11827,\n11828,11829,11830,11831,11832,11833,11834,11835,11836,11837,11838,11839,\n11840,11841,11842,11843,11844,11845,11846,11847,11848,11849,11850,11851,\n11852,11853,11854,11855,11856,11857,11858,11859,11860,11861,11862,11863,\n11864,11865,11866,11867,11868,11869,11870,11871,11872,11873,11874,11875,\n11876,11877,11878,11879,11880,11881,11882,11883,11884,11885,11886,11887,\n11888,11889,11890,11891,11892,11893,11894,11895,11896,11897,11898,11899,\n11900,11901,11902,11903,11904,11905,11906,11907,11908,11909,11910,11911,\n11912,11913,11914,11915,11916,11917,11918,11919,11920,11921,11922,11923,\n11924,11925,11926,11927,11928,11929,11930,11931,11932,11933,11934,11935,\n11936,11937,11938,11939,11940,11941,11942,11943,11944,11945,11946,11947,\n11948,11949,11950,11951,11952,11953,11954,11955,11956,11957,11958,11959,\n11960,11961,11962,11963,11964,11965,11966,11967,11968,11969,11970,11971,\n11972,11973,11974,11975,11976,11977,11978,11979,11980,11981,11982,11983,\n11984,11985,11986,11987,11988,11989,11990,11991,11992,11993,11994,11995,\n11996,11997,11998,11999,12000,12001,12002,12003,12004,12005,12006,12007,\n12008,12009,12010,12011,12012,12013,12014,12015,12016,12017,12018,12019,\n12020,12021,12022,12023,12024,12025,12026,12027,12028,12029,12030,12031,\n12032,12033,12034,12035,12036,12037,12038,12039,12040,12041,12042,12043,\n12044,12045,12046,12047,12048,12049,12050,12051,12052,12053,12054,12055,\n12056,12057,12058,12059,12060,12061,12062,12063,12064,12065,12066,12067,\n12068,12069,12070,12071,12072,12073,12074,12075,12076,12077,12078,12079,\n12080,12081,12082,12083,12084,12085,12086,12087,12088,12089,12090,12091,\n12092,12093,12094,12095,12096,12097,12098,12099,12100,12101,12102,12103,\n12104,12105,12106,12107,12108,12109,12110,12111,12112,12113,12114,12115,\n12116,12117,12118,12119,12120,12121,12122,12123,12124,12125,12126,12127,\n12128,12129,12130,12131,12132,12133,12134,12135,12136,12137,12138,12139,\n12140,12141,12142,12143,12144,12145,12146,12147,12148,12149,12150,12151,\n12152,12153,12154,12155,12156,12157,12158,12159,12160,12161,12162,12163,\n12164,12165,12166,12167,12168,12169,12170,12171,12172,12173,12174,12175,\n12176,12177,12178,12179,12180,12181,12182,12183,12184,12185,12186,12187,\n12188,12189,12190,12191,12192,12193,12194,12195,12196,12197,12198,12199,\n12200,12201,12202,12203,12204,12205,12206,12207,12208,12209,12210,12211,\n12212,12213,12214,12215,12216,12217,12218,12219,12220,12221,12222,12223,\n12224,12225,12226,12227,12228,12229,12230,12231,12232,12233,12234,12235,\n12236,12237,12238,12239,12240,12241,12242,12243,12244,12245,12246,12247,\n12248,12249,12250,12251,12252,12253,12254,12255,12256,12257,12258,12259,\n12260,12261,12262,12263,12264,12265,12266,12267,12268,12269,12270,12271,\n12272,12273,12274,12275,12276,12277,12278,12279,12280,12281,12282,12283,\n12284,12285,12286,12287,12288,12289,12290,12291,12292,12293,12294,12295,\n12296,12297,12298,12299,12300,12301,12302,12303,12304,12305,12306,12307,\n12308,12309,12310,12311,12312,12313,12314,12315,12316,12317,12318,12319,\n12320,12321,12322,12323,12324,12325,12326,12327,12328,12329,12330,12331,\n12332,12333,12334,12335,12336,12337,12338,12339,12340,12341,12342,12343,\n12344,12345,12346,12347,12348,12349,12350,12351,12352,12353,12354,12355,\n12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,12367,\n12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,\n12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,\n12392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,\n12404,12405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,\n12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,\n12428,12429,12430,12431,12432,12433,12434,12435,12436,12437,12438,12439,\n12440,12441,12442,12443,12444,12445,12446,12447,12448,12449,12450,12451,\n12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,12463,\n12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,\n12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,\n12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,\n12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,\n12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,\n12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,12535,\n12536,12537,12538,12539,12540,12541,12542,12543,12544,12545,12546,12547,\n12548,12549,12550,12551,12552,12553,12554,12555,12556,12557,12558,12559,\n12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570,12571,\n12572,12573,12574,12575,12576,12577,12578,12579,12580,12581,12582,12583,\n12584,12585,12586,12587,12588,12589,12590,12591,12592,12593,12594,12595,\n12596,12597,12598,12599,12600,12601,12602,12603,12604,12605,12606,12607,\n12608,12609,12610,12611,12612,12613,12614,12615,12616,12617,12618,12619,\n12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,12631,\n12632,12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643,\n12644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654,12655,\n12656,12657,12658,12659,12660,12661,12662,12663,12664,12665,12666,12667,\n12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679,\n12680,12681,12682,12683,12684,12685,12686,12687,12688,12689,12690,12691,\n12692,12693,12694,12695,12696,12697,12698,12699,12700,12701,12702,12703,\n12704,12705,12706,12707,12708,12709,12710,12711,12712,12713,12714,12715,\n12716,12717,12718,12719,12720,12721,12722,12723,12724,12725,12726,12727,\n12728,12729,12730,12731,12732,12733,12734,12735,12736,12737,12738,12739,\n12740,12741,12742,12743,12744,12745,12746,12747,12748,12749,12750,12751,\n12752,12753,12754,12755,12756,12757,12758,12759,12760,12761,12762,12763,\n12764,12765,12766,12767,12768,12769,12770,12771,12772,12773,12774,12775,\n12776,12777,12778,12779,12780,12781,12782,12783,12784,12785,12786,12787,\n12788,12789,12790,12791,12792,12793,12794,12795,12796,12797,12798,12799,\n12800,12801,12802,12803,12804,12805,12806,12807,12808,12809,12810,12811,\n12812,12813,12814,12815,12816,12817,12818,12819,12820,12821,12822,12823,\n12824,12825,12826,12827,12828,12829,12830,12831,12832,12833,12834,12835,\n12836,12837,12838,12839,12840,12841,12842,12843,12844,12845,12846,12847,\n12848,12849,12850,12851,12852,12853,12854,12855,12856,12857,12858,12859,\n12860,12861,12862,12863,12864,12865,12866,12867,12868,12869,12870,12871,\n12872,12873,12874,12875,12876,12877,12878,12879,12880,12881,12882,12883,\n12884,12885,12886,12887,12888,12889,12890,12891,12892,12893,12894,12895,\n12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906,12907,\n12908,12909,12910,12911,12912,12913,12914,12915,12916,12917,12918,12919,\n12920,12921,12922,12923,12924,12925,12926,12927,12928,12929,12930,12931,\n12932,12933,12934,12935,12936,12937,12938,12939,12940,12941,12942,12943,\n12944,12945,12946,12947,12948,12949,12950,12951,12952,12953,12954,12955,\n12956,12957,12958,12959,12960,12961,12962,12963,12964,12965,12966,12967,\n12968,12969,12970,12971,12972,12973,12974,12975,12976,12977,12978,12979,\n12980,12981,12982,12983,12984,12985,12986,12987,12988,12989,12990,12991,\n12992,12993,12994,12995,12996,12997,12998,12999,13000,13001,13002,13003,\n13004,13005,13006,13007,13008,13009,13010,13011,13012,13013,13014,13015,\n13016,13017,13018,13019,13020,13021,13022,13023,13024,13025,13026,13027,\n13028,13029,13030,13031,13032,13033,13034,13035,13036,13037,13038,13039,\n13040,13041,13042,13043,13044,13045,13046,13047,13048,13049,13050,13051,\n13052,13053,13054,13055,13056,13057,13058,13059,13060,13061,13062,13063,\n13064,13065,13066,13067,13068,13069,13070,13071,13072,13073,13074,13075,\n13076,13077,13078,13079,13080,13081,13082,13083,13084,13085,13086,13087,\n13088,13089,13090,13091,13092,13093,13094,13095,13096,13097,13098,13099,\n13100,13101,13102,13103,13104,13105,13106,13107,13108,13109,13110,13111,\n13112,13113,13114,13115,13116,13117,13118,13119,13120,13121,13122,13123,\n13124,13125,13126,13127,13128,13129,13130,13131,13132,13133,13134,13135,\n13136,13137,13138,13139,13140,13141,13142,13143,13144,13145,13146,13147,\n13148,13149,13150,13151,13152,13153,13154,13155,13156,13157,13158,13159,\n13160,13161,13162,13163,13164,13165,13166,13167,13168,13169,13170,13171,\n13172,13173,13174,13175,13176,13177,13178,13179,13180,13181,13182,13183,\n13184,13185,13186,13187,13188,13189,13190,13191,13192,13193,13194,13195,\n13196,13197,13198,13199,13200,13201,13202,13203,13204,13205,13206,13207,\n13208,13209,13210,13211,13212,13213,13214,13215,13216,13217,13218,13219,\n13220,13221,13222,13223,13224,13225,13226,13227,13228,13229,13230,13231,\n13232,13233,13234,13235,13236,13237,13238,13239,13240,13241,13242,13243,\n13244,13245,13246,13247,13248,13249,13250,13251,13252,13253,13254,13255,\n13256,13257,13258,13259,13260,13261,13262,13263,13264,13265,13266,13267,\n13268,13269,13270,13271,13272,13273,13274,13275,13276,13277,13278,13279,\n13280,13281,13282,13283,13284,13285,13286,13287,13288,13289,13290,13291,\n13292,13293,13294,13295,13296,13297,13298,13299,13300,13301,13302,13303,\n13304,13305,13306,13307,13308,13309,13310,13311,13312,13313,13314,13315,\n13316,13317,13318,13319,13320,13321,13322,13323,13324,13325,13326,13327,\n13328,13329,13330,13331,13332,13333,13334,13335,13336,13337,13338,13339,\n13340,13341,13342,13343,13344,13345,13346,13347,13348,13349,13350,13351,\n13352,13353,13354,13355,13356,13357,13358,13359,13360,13361,13362,13363,\n13364,13365,13366,13367,13368,13369,13370,13371,13372,13373,13374,13375,\n13376,13377,13378,13379,13380,13381,13382,13383,13384,13385,13386,13387,\n13388,13389,13390,13391,13392,13393,13394,13395,13396,13397,13398,13399,\n13400,13401,13402,13403,13404,13405,13406,13407,13408,13409,13410,13411,\n13412,13413,13414,13415,13416,13417,13418,13419,13420,13421,13422,13423,\n13424,13425,13426,13427,13428,13429,13430,13431,13432,13433,13434,13435,\n13436,13437,13438,13439,13440,13441,13442,13443,13444,13445,13446,13447,\n13448,13449,13450,13451,13452,13453,13454,13455,13456,13457,13458,13459,\n13460,13461,13462,13463,13464,13465,13466,13467,13468,13469,13470,13471,\n13472,13473,13474,13475,13476,13477,13478,13479,13480,13481,13482,13483,\n13484,13485,13486,13487,13488,13489,13490,13491,13492,13493,13494,13495,\n13496,13497,13498,13499,13500,13501,13502,13503,13504,13505,13506,13507,\n13508,13509,13510,13511,13512,13513,13514,13515,13516,13517,13518,13519,\n13520,13521,13522,13523,13524,13525,13526,13527,13528,13529,13530,13531,\n13532,13533,13534,13535,13536,13537,13538,13539,13540,13541,13542,13543,\n13544,13545,13546,13547,13548,13549,13550,13551,13552,13553,13554,13555,\n13556,13557,13558,13559,13560,13561,13562,13563,13564,13565,13566,13567,\n13568,13569,13570,13571,13572,13573,13574,13575,13576,13577,13578,13579,\n13580,13581,13582,13583,13584,13585,13586,13587,13588,13589,13590,13591,\n13592,13593,13594,13595,13596,13597,13598,13599,13600,13601,13602,13603,\n13604,13605,13606,13607,13608,13609,13610,13611,13612,13613,13614,13615,\n13616,13617,13618,13619,13620,13621,13622,13623,13624,13625,13626,13627,\n13628,13629,13630,13631,13632,13633,13634,13635,13636,13637,13638,13639,\n13640,13641,13642,13643,13644,13645,13646,13647,13648,13649,13650,13651,\n13652,13653,13654,13655,13656,13657,13658,13659,13660,13661,13662,13663,\n13664,13665,13666,13667,13668,13669,13670,13671,13672,13673,13674,13675,\n13676,13677,13678,13679,13680,13681,13682,13683,13684,13685,13686,13687,\n13688,13689,13690,13691,13692,13693,13694,13695,13696,13697,13698,13699,\n13700,13701,13702,13703,13704,13705,13706,13707,13708,13709,13710,13711,\n13712,13713,13714,13715,13716,13717,13718,13719,13720,13721,13722,13723,\n13724,13725,13726,13727,13728,13729,13730,13731,13732,13733,13734,13735,\n13736,13737,13738,13739,13740,13741,13742,13743,13744,13745,13746,13747,\n13748,13749,13750,13751,13752,13753,13754,13755,13756,13757,13758,13759,\n13760,13761,13762,13763,13764,13765,13766,13767,13768,13769,13770,13771,\n13772,13773,13774,13775,13776,13777,13778,13779,13780,13781,13782,13783,\n13784,13785,13786,13787,13788,13789,13790,13791,13792,13793,13794,13795,\n13796,13797,13798,13799,13800,13801,13802,13803,13804,13805,13806,13807,\n13808,13809,13810,13811,13812,13813,13814,13815,13816,13817,13818,13819,\n13820,13821,13822,13823,13824,13825,13826,13827,13828,13829,13830,13831,\n13832,13833,13834,13835,13836,13837,13838,13839,13840,13841,13842,13843,\n13844,13845,13846,13847,13848,13849,13850,13851,13852,13853,13854,13855,\n13856,13857,13858,13859,13860,13861,13862,13863,13864,13865,13866,13867,\n13868,13869,13870,13871,13872,13873,13874,13875,13876,13877,13878,13879,\n13880,13881,13882,13883,13884,13885,13886,13887,13888,13889,13890,13891,\n13892,13893,13894,13895,13896,13897,13898,13899,13900,13901,13902,13903,\n13904,13905,13906,13907,13908,13909,13910,13911,13912,13913,13914,13915,\n13916,13917,13918,13919,13920,13921,13922,13923,13924,13925,13926,13927,\n13928,13929,13930,13931,13932,13933,13934,13935,13936,13937,13938,13939,\n13940,13941,13942,13943,13944,13945,13946,13947,13948,13949,13950,13951,\n13952,13953,13954,13955,13956,13957,13958,13959,13960,13961,13962,13963,\n13964,13965,13966,13967,13968,13969,13970,13971,13972,13973,13974,13975,\n13976,13977,13978,13979,13980,13981,13982,13983,13984,13985,13986,13987,\n13988,13989,13990,13991,13992,13993,13994,13995,13996,13997,13998,13999,\n14000,14001,14002,14003,14004,14005,14006,14007,14008,14009,14010,14011,\n14012,14013,14014,14015,14016,14017,14018,14019,14020,14021,14022,14023,\n14024,14025,14026,14027,14028,14029,14030,14031,14032,14033,14034,14035,\n14036,14037,14038,14039,14040,14041,14042,14043,14044,14045,14046,14047,\n14048,14049,14050,14051,14052,14053,14054,14055,14056,14057,14058,14059,\n14060,14061,14062,14063,14064,14065,14066,14067,14068,14069,14070,14071,\n14072,14073,14074,14075,14076,14077,14078,14079,14080,14081,14082,14083,\n14084,14085,14086,14087,14088,14089,14090,14091,14092,14093,14094,14095,\n14096,14097,14098,14099,14100,14101,14102,14103,14104,14105,14106,14107,\n14108,14109,14110,14111,14112,14113,14114,14115,14116,14117,14118,14119,\n14120,14121,14122,14123,14124,14125,14126,14127,14128,14129,14130,14131,\n14132,14133,14134,14135,14136,14137,14138,14139,14140,14141,14142,14143,\n14144,14145,14146,14147,14148,14149,14150,14151,14152,14153,14154,14155,\n14156,14157,14158,14159,14160,14161,14162,14163,14164,14165,14166,14167,\n14168,14169,14170,14171,14172,14173,14174,14175,14176,14177,14178,14179,\n14180,14181,14182,14183,14184,14185,14186,14187,14188,14189,14190,14191,\n14192,14193,14194,14195,14196,14197,14198,14199,14200,14201,14202,14203,\n14204,14205,14206,14207,14208,14209,14210,14211,14212,14213,14214,14215,\n14216,14217,14218,14219,14220,14221,14222,14223,14224,14225,14226,14227,\n14228,14229,14230,14231,14232,14233,14234,14235,14236,14237,14238,14239,\n14240,14241,14242,14243,14244,14245,14246,14247,14248,14249,14250,14251,\n14252,14253,14254,14255,14256,14257,14258,14259,14260,14261,14262,14263,\n14264,14265,14266,14267,14268,14269,14270,14271,14272,14273,14274,14275,\n14276,14277,14278,14279,14280,14281,14282,14283,14284,14285,14286,14287,\n14288,14289,14290,14291,14292,14293,14294,14295,14296,14297,14298,14299,\n14300,14301,14302,14303,14304,14305,14306,14307,14308,14309,14310,14311,\n14312,14313,14314,14315,14316,14317,14318,14319,14320,14321,14322,14323,\n14324,14325,14326,14327,14328,14329,14330,14331,14332,14333,14334,14335,\n14336,14337,14338,14339,14340,14341,14342,14343,14344,14345,14346,14347,\n14348,14349,14350,14351,14352,14353,14354,14355,14356,14357,14358,14359,\n14360,14361,14362,14363,14364,14365,14366,14367,14368,14369,14370,14371,\n14372,14373,14374,14375,14376,14377,14378,14379,14380,14381,14382,14383,\n14384,14385,14386,14387,14388,14389,14390,14391,14392,14393,14394,14395,\n14396,14397,14398,14399,14400,14401,14402,14403,14404,14405,14406,14407,\n14408,14409,14410,14411,14412,14413,14414,14415,14416,14417,14418,14419,\n14420,14421,14422,14423,14424,14425,14426,14427,14428,14429,14430,14431,\n14432,14433,14434,14435,14436,14437,14438,14439,14440,14441,14442,14443,\n14444,14445,14446,14447,14448,14449,14450,14451,14452,14453,14454,14455,\n14456,14457,14458,14459,14460,14461,14462,14463,14464,14465,14466,14467,\n14468,14469,14470,14471,14472,14473,14474,14475,14476,14477,14478,14479,\n14480,14481,14482,14483,14484,14485,14486,14487,14488,14489,14490,14491,\n14492,14493,14494,14495,14496,14497,14498,14499,14500,14501,14502,14503,\n14504,14505,14506,14507,14508,14509,14510,14511,14512,14513,14514,14515,\n14516,14517,14518,14519,14520,14521,14522,14523,14524,14525,14526,14527,\n14528,14529,14530,14531,14532,14533,14534,14535,14536,14537,14538,14539,\n14540,14541,14542,14543,14544,14545,14546,14547,14548,14549,14550,14551,\n14552,14553,14554,14555,14556,14557,14558,14559,14560,14561,14562,14563,\n14564,14565,14566,14567,14568,14569,14570,14571,14572,14573,14574,14575,\n14576,14577,14578,14579,14580,14581,14582,14583,14584,14585,14586,14587,\n14588,14589,14590,14591,14592,14593,14594,14595,14596,14597,14598,14599,\n14600,14601,14602,14603,14604,14605,14606,14607,14608,14609,14610,14611,\n14612,14613,14614,14615,14616,14617,14618,14619,14620,14621,14622,14623,\n14624,14625,14626,14627,14628,14629,14630,14631,14632,14633,14634,14635,\n14636,14637,14638,14639,14640,14641,14642,14643,14644,14645,14646,14647,\n14648,14649,14650,14651,14652,14653,14654,14655,14656,14657,14658,14659,\n14660,14661,14662,14663,14664,14665,14666,14667,14668,14669,14670,14671,\n14672,14673,14674,14675,14676,14677,14678,14679,14680,14681,14682,14683,\n14684,14685,14686,14687,14688,14689,14690,14691,14692,14693,14694,14695,\n14696,14697,14698,14699,14700,14701,14702,14703,14704,14705,14706,14707,\n14708,14709,14710,14711,14712,14713,14714,14715,14716,14717,14718,14719,\n14720,14721,14722,14723,14724,14725,14726,14727,14728,14729,14730,14731,\n14732,14733,14734,14735,14736,14737,14738,14739,14740,14741,14742,14743,\n14744,14745,14746,14747,14748,14749,14750,14751,14752,14753,14754,14755,\n14756,14757,14758,14759,14760,14761,14762,14763,14764,14765,14766,14767,\n14768,14769,14770,14771,14772,14773,14774,14775,14776,14777,14778,14779,\n14780,14781,14782,14783,14784,14785,14786,14787,14788,14789,14790,14791,\n14792,14793,14794,14795,14796,14797,14798,14799,14800,14801,14802,14803,\n14804,14805,14806,14807,14808,14809,14810,14811,14812,14813,14814,14815,\n14816,14817,14818,14819,14820,14821,14822,14823,14824,14825,14826,14827,\n14828,14829,14830,14831,14832,14833,14834,14835,14836,14837,14838,14839,\n14840,14841,14842,14843,14844,14845,14846,14847,14848,14849,14850,14851,\n14852,14853,14854,14855,14856,14857,14858,14859,14860,14861,14862,14863,\n14864,14865,14866,14867,14868,14869,14870,14871,14872,14873,14874,14875,\n14876,14877,14878,14879,14880,14881,14882,14883,14884,14885,14886,14887,\n14888,14889,14890,14891,14892,14893,14894,14895,14896,14897,14898,14899,\n14900,14901,14902,14903,14904,14905,14906,14907,14908,14909,14910,14911,\n14912,14913,14914,14915,14916,14917,14918,14919,14920,14921,14922,14923,\n14924,14925,14926,14927,14928,14929,14930,14931,14932,14933,14934,14935,\n14936,14937,14938,14939,14940,14941,14942,14943,14944,14945,14946,14947,\n14948,14949,14950,14951,14952,14953,14954,14955,14956,14957,14958,14959,\n14960,14961,14962,14963,14964,14965,14966,14967,14968,14969,14970,14971,\n14972,14973,14974,14975,14976,14977,14978,14979,14980,14981,14982,14983,\n14984,14985,14986,14987,14988,14989,14990,14991,14992,14993,14994,14995,\n14996,14997,14998,14999,15000,15001,15002,15003,15004,15005,15006,15007,\n15008,15009,15010,15011,15012,15013,15014,15015,15016,15017,15018,15019,\n15020,15021,15022,15023,15024,15025,15026,15027,15028,15029,15030,15031,\n15032,15033,15034,15035,15036,15037,15038,15039,15040,15041,15042,15043,\n15044,15045,15046,15047,15048,15049,15050,15051,15052,15053,15054,15055,\n15056,15057,15058,15059,15060,15061,15062,15063,15064,15065,15066,15067,\n15068,15069,15070,15071,15072,15073,15074,15075,15076,15077,15078,15079,\n15080,15081,15082,15083,15084,15085,15086,15087,15088,15089,15090,15091,\n15092,15093,15094,15095,15096,15097,15098,15099,15100,15101,15102,15103,\n15104,15105,15106,15107,15108,15109,15110,15111,15112,15113,15114,15115,\n15116,15117,15118,15119,15120,15121,15122,15123,15124,15125,15126,15127,\n15128,15129,15130,15131,15132,15133,15134,15135,15136,15137,15138,15139,\n15140,15141,15142,15143,15144,15145,15146,15147,15148,15149,15150,15151,\n15152,15153,15154,15155,15156,15157,15158,15159,15160,15161,15162,15163,\n15164,15165,15166,15167,15168,15169,15170,15171,15172,15173,15174,15175,\n15176,15177,15178,15179,15180,15181,15182,15183,15184,15185,15186,15187,\n15188,15189,15190,15191,15192,15193,15194,15195,15196,15197,15198,15199,\n15200,15201,15202,15203,15204,15205,15206,15207,15208,15209,15210,15211,\n15212,15213,15214,15215,15216,15217,15218,15219,15220,15221,15222,15223,\n15224,15225,15226,15227,15228,15229,15230,15231,15232,15233,15234,15235,\n15236,15237,15238,15239,15240,15241,15242,15243,15244,15245,15246,15247,\n15248,15249,15250,15251,15252,15253,15254,15255,15256,15257,15258,15259,\n15260,15261,15262,15263,15264,15265,15266,15267,15268,15269,15270,15271,\n15272,15273,15274,15275,15276,15277,15278,15279,15280,15281,15282,15283,\n15284,15285,15286,15287,15288,15289,15290,15291,15292,15293,15294,15295,\n15296,15297,15298,15299,15300,15301,15302,15303,15304,15305,15306,15307,\n15308,15309,15310,15311,15312,15313,15314,15315,15316,15317,15318,15319,\n15320,15321,15322,15323,15324,15325,15326,15327,15328,15329,15330,15331,\n15332,15333,15334,15335,15336,15337,15338,15339,15340,15341,15342,15343,\n15344,15345,15346,15347,15348,15349,15350,15351,15352,15353,15354,15355,\n15356,15357,15358,15359,15360,15361,15362,15363,15364,15365,15366,15367,\n15368,15369,15370,15371,15372,15373,15374,15375,15376,15377,15378,15379,\n15380,15381,15382,15383,15384,15385,15386,15387,15388,15389,15390,15391,\n15392,15393,15394,15395,15396,15397,15398,15399,15400,15401,15402,15403,\n15404,15405,15406,15407,15408,15409,15410,15411,15412,15413,15414,15415,\n15416,15417,15418,15419,15420,15421,15422,15423,15424,15425,15426,15427,\n15428,15429,15430,15431,15432,15433,15434,15435,15436,15437,15438,15439,\n15440,15441,15442,15443,15444,15445,15446,15447,15448,15449,15450,15451,\n15452,15453,15454,15455,15456,15457,15458,15459,15460,15461,15462,15463,\n15464,15465,15466,15467,15468,15469,15470,15471,15472,15473,15474,15475,\n15476,15477,15478,15479,15480,15481,15482,15483,15484,15485,15486,15487,\n15488,15489,15490,15491,15492,15493,15494,15495,15496,15497,15498,15499,\n15500,15501,15502,15503,15504,15505,15506,15507,15508,15509,15510,15511,\n15512,15513,15514,15515,15516,15517,15518,15519,15520,15521,15522,15523,\n15524,15525,15526,15527,15528,15529,15530,15531,15532,15533,15534,15535,\n15536,15537,15538,15539,15540,15541,15542,15543,15544,15545,15546,15547,\n15548,15549,15550,15551,15552,15553,15554,15555,15556,15557,15558,15559,\n15560,15561,15562,15563,15564,15565,15566,15567,15568,15569,15570,15571,\n15572,15573,15574,15575,15576,15577,15578,15579,15580,15581,15582,15583,\n15584,15585,15586,15587,15588,15589,15590,15591,15592,15593,15594,15595,\n15596,15597,15598,15599,15600,15601,15602,15603,15604,15605,15606,15607,\n15608,15609,15610,15611,15612,15613,15614,15615,15616,15617,15618,15619,\n15620,15621,15622,15623,15624,15625,15626,15627,15628,15629,15630,15631,\n15632,15633,15634,15635,15636,15637,15638,15639,15640,15641,15642,15643,\n15644,15645,15646,15647,15648,15649,15650,15651,15652,15653,15654,15655,\n15656,15657,15658,15659,15660,15661,15662,15663,15664,15665,15666,15667,\n15668,15669,15670,15671,15672,15673,15674,15675,15676,15677,15678,15679,\n15680,15681,15682,15683,15684,15685,15686,15687,15688,15689,15690,15691,\n15692,15693,15694,15695,15696,15697,15698,15699,15700,15701,15702,15703,\n15704,15705,15706,15707,15708,15709,15710,15711,15712,15713,15714,15715,\n15716,15717,15718,15719,15720,15721,15722,15723,15724,15725,15726,15727,\n15728,15729,15730,15731,15732,15733,15734,15735,15736,15737,15738,15739,\n15740,15741,15742,15743,15744,15745,15746,15747,15748,15749,15750,15751,\n15752,15753,15754,15755,15756,15757,15758,15759,15760,15761,15762,15763,\n15764,15765,15766,15767,15768,15769,15770,15771,15772,15773,15774,15775,\n15776,15777,15778,15779,15780,15781,15782,15783,15784,15785,15786,15787,\n15788,15789,15790,15791,15792,15793,15794,15795,15796,15797,15798,15799,\n15800,15801,15802,15803,15804,15805,15806,15807,15808,15809,15810,15811,\n15812,15813,15814,15815,15816,15817,15818,15819,15820,15821,15822,15823,\n15824,15825,15826,15827,15828,15829,15830,15831,15832,15833,15834,15835,\n15836,15837,15838,15839,15840,15841,15842,15843,15844,15845,15846,15847,\n15848,15849,15850,15851,15852,15853,15854,15855,15856,15857,15858,15859,\n15860,15861,15862,15863,15864,15865,15866,15867,15868,15869,15870,15871,\n15872,15873,15874,15875,15876,15877,15878,15879,15880,15881,15882,15883,\n15884,15885,15886,15887,15888,15889,15890,15891,15892,15893,15894,15895,\n15896,15897,15898,15899,15900,15901,15902,15903,15904,15905,15906,15907,\n15908,15909,15910,15911,15912,15913,15914,15915,15916,15917,15918,15919,\n15920,15921,15922,15923,15924,15925,15926,15927,15928,15929,15930,15931,\n15932,15933,15934,15935,15936,15937,15938,15939,15940,15941,15942,15943,\n15944,15945,15946,15947,15948,15949,15950,15951,15952,15953,15954,15955,\n15956,15957,15958,15959,15960,15961,15962,15963,15964,15965,15966,15967,\n15968,15969,15970,15971,15972,15973,15974,15975,15976,15977,15978,15979,\n15980,15981,15982,15983,15984,15985,15986,15987,15988,15989,15990,15991,\n15992,15993,15994,15995,15996,15997,15998,15999,16000,16001,16002,16003,\n16004,16005,16006,16007,16008,16009,16010,16011,16012,16013,16014,16015,\n16016,16017,16018,16019,16020,16021,16022,16023,16024,16025,16026,16027,\n16028,16029,16030,16031,16032,16033,16034,16035,16036,16037,16038,16039,\n16040,16041,16042,16043,16044,16045,16046,16047,16048,16049,16050,16051,\n16052,16053,16054,16055,16056,16057,16058,16059,16060,16061,16062,16063,\n16064,16065,16066,16067,16068,16069,16070,16071,16072,16073,16074,16075,\n16076,16077,16078,16079,16080,16081,16082,16083,16084,16085,16086,16087,\n16088,16089,16090,16091,16092,16093,16094,16095,16096,16097,16098,16099,\n16100,16101,16102,16103,16104,16105,16106,16107,16108,16109,16110,16111,\n16112,16113,16114,16115,16116,16117,16118,16119,16120,16121,16122,16123,\n16124,16125,16126,16127,16128,16129,16130,16131,16132,16133,16134,16135,\n16136,16137,16138,16139,16140,16141,16142,16143,16144,16145,16146,16147,\n16148,16149,16150,16151,16152,16153,16154,16155,16156,16157,16158,16159,\n16160,16161,16162,16163,16164,16165,16166,16167,16168,16169,16170,16171,\n16172,16173,16174,16175,16176,16177,16178,16179,16180,16181,16182,16183,\n16184,16185,16186,16187,16188,16189,16190,16191,16192,16193,16194,16195,\n16196,16197,16198,16199,16200,16201,16202,16203,16204,16205,16206,16207,\n16208,16209,16210,16211,16212,16213,16214,16215,16216,16217,16218,16219,\n16220,16221,16222,16223,16224,16225,16226,16227,16228,16229,16230,16231,\n16232,16233,16234,16235,16236,16237,16238,16239,16240,16241,16242,16243,\n16244,16245,16246,16247,16248,16249,16250,16251,16252,16253,16254,16255,\n16256,16257,16258,16259,16260,16261,16262,16263,16264,16265,16266,16267,\n16268,16269,16270,16271,16272,16273,16274,16275,16276,16277,16278,16279,\n16280,16281,16282,16283,16284,16285,16286,16287,16288,16289,16290,16291,\n16292,16293,16294,16295,16296,16297,16298,16299,16300,16301,16302,16303,\n16304,16305,16306,16307,16308,16309,16310,16311,16312,16313,16314,16315,\n16316,16317,16318,16319,16320,16321,16322,16323,16324,16325,16326,16327,\n16328,16329,16330,16331,16332,16333,16334,16335,16336,16337,16338,16339,\n16340,16341,16342,16343,16344,16345,16346,16347,16348,16349,16350,16351,\n16352,16353,16354,16355,16356,16357,16358,16359,16360,16361,16362,16363,\n16364,16365,16366,16367,16368,16369,16370,16371,16372,16373,16374,16375,\n16376,16377,16378,16379,16380,16381,16382,16383,16384,16385,16386,16387,\n16388,16389,16390,16391,16392,16393,16394,16395,16396,16397,16398,16399,\n16400,16401,16402,16403,16404,16405,16406,16407,16408,16409,16410,16411,\n16412,16413,16414,16415,16416,16417,16418,16419,16420,16421,16422,16423,\n16424,16425,16426,16427,16428,16429,16430,16431,16432,16433,16434,16435,\n16436,16437,16438,16439,16440,16441,16442,16443,16444,16445,16446,16447,\n16448,16449,16450,16451,16452,16453,16454,16455,16456,16457,16458,16459,\n16460,16461,16462,16463,16464,16465,16466,16467,16468,16469,16470,16471,\n16472,16473,16474,16475,16476,16477,16478,16479,16480,16481,16482,16483,\n16484,16485,16486,16487,16488,16489,16490,16491,16492,16493,16494,16495,\n16496,16497,16498,16499,16500,16501,16502,16503,16504,16505,16506,16507,\n16508,16509,16510,16511,16512,16513,16514,16515,16516,16517,16518,16519,\n16520,16521,16522,16523,16524,16525,16526,16527,16528,16529,16530,16531,\n16532,16533,16534,16535,16536,16537,16538,16539,16540,16541,16542,16543,\n16544,16545,16546,16547,16548,16549,16550,16551,16552,16553,16554,16555,\n16556,16557,16558,16559,16560,16561,16562,16563,16564,16565,16566,16567,\n16568,16569,16570,16571,16572,16573,16574,16575,16576,16577,16578,16579,\n16580,16581,16582,16583,16584,16585,16586,16587,16588,16589,16590,16591,\n16592,16593,16594,16595,16596,16597,16598,16599,16600,16601,16602,16603,\n16604,16605,16606,16607,16608,16609,16610,16611,16612,16613,16614,16615,\n16616,16617,16618,16619,16620,16621,16622,16623,16624,16625,16626,16627,\n16628,16629,16630,16631,16632,16633,16634,16635,16636,16637,16638,16639,\n16640,16641,16642,16643,16644,16645,16646,16647,16648,16649,16650,16651,\n16652,16653,16654,16655,16656,16657,16658,16659,16660,16661,16662,16663,\n16664,16665,16666,16667,16668,16669,16670,16671,16672,16673,16674,16675,\n16676,16677,16678,16679,16680,16681,16682,16683,16684,16685,16686,16687,\n16688,16689,16690,16691,16692,16693,16694,16695,16696,16697,16698,16699,\n16700,16701,16702,16703,16704,16705,16706,16707,16708,16709,16710,16711,\n16712,16713,16714,16715,16716,16717,16718,16719,16720,16721,16722,16723,\n16724,16725,16726,16727,16728,16729,16730,16731,16732,16733,16734,16735,\n16736,16737,16738,16739,16740,16741,16742,16743,16744,16745,16746,16747,\n16748,16749,16750,16751,16752,16753,16754,16755,16756,16757,16758,16759,\n16760,16761,16762,16763,16764,16765,16766,16767,16768,16769,16770,16771,\n16772,16773,16774,16775,16776,16777,16778,16779,16780,16781,16782,16783,\n16784,16785,16786,16787,16788,16789,16790,16791,16792,16793,16794,16795,\n16796,16797,16798,16799,16800,16801,16802,16803,16804,16805,16806,16807,\n16808,16809,16810,16811,16812,16813,16814,16815,16816,16817,16818,16819,\n16820,16821,16822,16823,16824,16825,16826,16827,16828,16829,16830,16831,\n16832,16833,16834,16835,16836,16837,16838,16839,16840,16841,16842,16843,\n16844,16845,16846,16847,16848,16849,16850,16851,16852,16853,16854,16855,\n16856,16857,16858,16859,16860,16861,16862,16863,16864,16865,16866,16867,\n16868,16869,16870,16871,16872,16873,16874,16875,16876,16877,16878,16879,\n16880,16881,16882,16883,16884,16885,16886,16887,16888,16889,16890,16891,\n16892,16893,16894,16895,16896,16897,16898,16899,16900,16901,16902,16903,\n16904,16905,16906,16907,16908,16909,16910,16911,16912,16913,16914,16915,\n16916,16917,16918,16919,16920,16921,16922,16923,16924,16925,16926,16927,\n16928,16929,16930,16931,16932,16933,16934,16935,16936,16937,16938,16939,\n16940,16941,16942,16943,16944,16945,16946,16947,16948,16949,16950,16951,\n16952,16953,16954,16955,16956,16957,16958,16959,16960,16961,16962,16963,\n16964,16965,16966,16967,16968,16969,16970,16971,16972,16973,16974,16975,\n16976,16977,16978,16979,16980,16981,16982,16983,16984,16985,16986,16987,\n16988,16989,16990,16991,16992,16993,16994,16995,16996,16997,16998,16999,\n17000,17001,17002,17003,17004,17005,17006,17007,17008,17009,17010,17011,\n17012,17013,17014,17015,17016,17017,17018,17019,17020,17021,17022,17023,\n17024,17025,17026,17027,17028,17029,17030,17031,17032,17033,17034,17035,\n17036,17037,17038,17039,17040,17041,17042,17043,17044,17045,17046,17047,\n17048,17049,17050,17051,17052,17053,17054,17055,17056,17057,17058,17059,\n17060,17061,17062,17063,17064,17065,17066,17067,17068,17069,17070,17071,\n17072,17073,17074,17075,17076,17077,17078,17079,17080,17081,17082,17083,\n17084,17085,17086,17087,17088,17089,17090,17091,17092,17093,17094,17095,\n17096,17097,17098,17099,17100,17101,17102,17103,17104,17105,17106,17107,\n17108,17109,17110,17111,17112,17113,17114,17115,17116,17117,17118,17119,\n17120,17121,17122,17123,17124,17125,17126,17127,17128,17129,17130,17131,\n17132,17133,17134,17135,17136,17137,17138,17139,17140,17141,17142,17143,\n17144,17145,17146,17147,17148,17149,17150,17151,17152,17153,17154,17155,\n17156,17157,17158,17159,17160,17161,17162,17163,17164,17165,17166,17167,\n17168,17169,17170,17171,17172,17173,17174,17175,17176,17177,17178,17179,\n17180,17181,17182,17183,17184,17185,17186,17187,17188,17189,17190,17191,\n17192,17193,17194,17195,17196,17197,17198,17199,17200,17201,17202,17203,\n17204,17205,17206,17207,17208,17209,17210,17211,17212,17213,17214,17215,\n17216,17217,17218,17219,17220,17221,17222,17223,17224,17225,17226,17227,\n17228,17229,17230,17231,17232,17233,17234,17235,17236,17237,17238,17239,\n17240,17241,17242,17243,17244,17245,17246,17247,17248,17249,17250,17251,\n17252,17253,17254,17255,17256,17257,17258,17259,17260,17261,17262,17263,\n17264,17265,17266,17267,17268,17269,17270,17271,17272,17273,17274,17275,\n17276,17277,17278,17279,17280,17281,17282,17283,17284,17285,17286,17287,\n17288,17289,17290,17291,17292,17293,17294,17295,17296,17297,17298,17299,\n17300,17301,17302,17303,17304,17305,17306,17307,17308,17309,17310,17311,\n17312,17313,17314,17315,17316,17317,17318,17319,17320,17321,17322,17323,\n17324,17325,17326,17327,17328,17329,17330,17331,17332,17333,17334,17335,\n17336,17337,17338,17339,17340,17341,17342,17343,17344,17345,17346,17347,\n17348,17349,17350,17351,17352,17353,17354,17355,17356,17357,17358,17359,\n17360,17361,17362,17363,17364,17365,17366,17367,17368,17369,17370,17371,\n17372,17373,17374,17375,17376,17377,17378,17379,17380,17381,17382,17383,\n17384,17385,17386,17387,17388,17389,17390,17391,17392,17393,17394,17395,\n17396,17397,17398,17399,17400,17401,17402,17403,17404,17405,17406,17407,\n17408,17409,17410,17411,17412,17413,17414,17415,17416,17417,17418,17419,\n17420,17421,17422,17423,17424,17425,17426,17427,17428,17429,17430,17431,\n17432,17433,17434,17435,17436,17437,17438,17439,17440,17441,17442,17443,\n17444,17445,17446,17447,17448,17449,17450,17451,17452,17453,17454,17455,\n17456,17457,17458,17459,17460,17461,17462,17463,17464,17465,17466,17467,\n17468,17469,17470,17471,17472,17473,17474,17475,17476,17477,17478,17479,\n17480,17481,17482,17483,17484,17485,17486,17487,17488,17489,17490,17491,\n17492,17493,17494,17495,17496,17497,17498,17499,17500,17501,17502,17503,\n17504,17505,17506,17507,17508,17509,17510,17511,17512,17513,17514,17515,\n17516,17517,17518,17519,17520,17521,17522,17523,17524,17525,17526,17527,\n17528,17529,17530,17531,17532,17533,17534,17535,17536,17537,17538,17539,\n17540,17541,17542,17543,17544,17545,17546,17547,17548,17549,17550,17551,\n17552,17553,17554,17555,17556,17557,17558,17559,17560,17561,17562,17563,\n17564,17565,17566,17567,17568,17569,17570,17571,17572,17573,17574,17575,\n17576,17577,17578,17579,17580,17581,17582,17583,17584,17585,17586,17587,\n17588,17589,17590,17591,17592,17593,17594,17595,17596,17597,17598,17599,\n17600,17601,17602,17603,17604,17605,17606,17607,17608,17609,17610,17611,\n17612,17613,17614,17615,17616,17617,17618,17619,17620,17621,17622,17623,\n17624,17625,17626,17627,17628,17629,17630,17631,17632,17633,17634,17635,\n17636,17637,17638,17639,17640,17641,17642,17643,17644,17645,17646,17647,\n17648,17649,17650,17651,17652,17653,17654,17655,17656,17657,17658,17659,\n17660,17661,17662,17663,17664,17665,17666,17667,17668,17669,17670,17671,\n17672,17673,17674,17675,17676,17677,17678,17679,17680,17681,17682,17683,\n17684,17685,17686,17687,17688,17689,17690,17691,17692,17693,17694,17695,\n17696,17697,17698,17699,17700,17701,17702,17703,17704,17705,17706,17707,\n17708,17709,17710,17711,17712,17713,17714,17715,17716,17717,17718,17719,\n17720,17721,17722,17723,17724,17725,17726,17727,17728,17729,17730,17731,\n17732,17733,17734,17735,17736,17737,17738,17739,17740,17741,17742,17743,\n17744,17745,17746,17747,17748,17749,17750,17751,17752,17753,17754,17755,\n17756,17757,17758,17759,17760,17761,17762,17763,17764,17765,17766,17767,\n17768,17769,17770,17771,17772,17773,17774,17775,17776,17777,17778,17779,\n17780,17781,17782,17783,17784,17785,17786,17787,17788,17789,17790,17791,\n17792,17793,17794,17795,17796,17797,17798,17799,17800,17801,17802,17803,\n17804,17805,17806,17807,17808,17809,17810,17811,17812,17813,17814,17815,\n17816,17817,17818,17819,17820,17821,17822,17823,17824,17825,17826,17827,\n17828,17829,17830,17831,17832,17833,17834,17835,17836,17837,17838,17839,\n17840,17841,17842,17843,17844,17845,17846,17847,17848,17849,17850,17851,\n17852,17853,17854,17855,17856,17857,17858,17859,17860,17861,17862,17863,\n17864,17865,17866,17867,17868,17869,17870,17871,17872,17873,17874,17875,\n17876,17877,17878,17879,17880,17881,17882,17883,17884,17885,17886,17887,\n17888,17889,17890,17891,17892,17893,17894,17895,17896,17897,17898,17899,\n17900,17901,17902,17903,17904,17905,17906,17907,17908,17909,17910,17911,\n17912,17913,17914,17915,17916,17917,17918,17919,17920,17921,17922,17923,\n17924,17925,17926,17927,17928,17929,17930,17931,17932,17933,17934,17935,\n17936,17937,17938,17939,17940,17941,17942,17943,17944,17945,17946,17947,\n17948,17949,17950,17951,17952,17953,17954,17955,17956,17957,17958,17959,\n17960,17961,17962,17963,17964,17965,17966,17967,17968,17969,17970,17971,\n17972,17973,17974,17975,17976,17977,17978,17979,17980,17981,17982,17983,\n17984,17985,17986,17987,17988,17989,17990,17991,17992,17993,17994,17995,\n17996,17997,17998,17999,18000,18001,18002,18003,18004,18005,18006,18007,\n18008,18009,18010,18011,18012,18013,18014,18015,18016,18017,18018,18019,\n18020,18021,18022,18023,18024,18025,18026,18027,18028,18029,18030,18031,\n18032,18033,18034,18035,18036,18037,18038,18039,18040,18041,18042,18043,\n18044,18045,18046,18047,18048,18049,18050,18051,18052,18053,18054,18055,\n18056,18057,18058,18059,18060,18061,18062,18063,18064,18065,18066,18067,\n18068,18069,18070,18071,18072,18073,18074,18075,18076,18077,18078,18079,\n18080,18081,18082,18083,18084,18085,18086,18087,18088,18089,18090,18091,\n18092,18093,18094,18095,18096,18097,18098,18099,18100,18101,18102,18103,\n18104,18105,18106,18107,18108,18109,18110,18111,18112,18113,18114,18115,\n18116,18117,18118,18119,18120,18121,18122,18123,18124,18125,18126,18127,\n18128,18129,18130,18131,18132,18133,18134,18135,18136,18137,18138,18139,\n18140,18141,18142,18143,18144,18145,18146,18147,18148,18149,18150,18151,\n18152,18153,18154,18155,18156,18157,18158,18159,18160,18161,18162,18163,\n18164,18165,18166,18167,18168,18169,18170,18171,18172,18173,18174,18175,\n18176,18177,18178,18179,18180,18181,18182,18183,18184,18185,18186,18187,\n18188,18189,18190,18191,18192,18193,18194,18195,18196,18197,18198,18199,\n18200,18201,18202,18203,18204,18205,18206,18207,18208,18209,18210,18211,\n18212,18213,18214,18215,18216,18217,18218,18219,18220,18221,18222,18223,\n18224,18225,18226,18227,18228,18229,18230,18231,18232,18233,18234,18235,\n18236,18237,18238,18239,18240,18241,18242,18243,18244,18245,18246,18247,\n18248,18249,18250,18251,18252,18253,18254,18255,18256,18257,18258,18259,\n18260,18261,18262,18263,18264,18265,18266,18267,18268,18269,18270,18271,\n18272,18273,18274,18275,18276,18277,18278,18279,18280,18281,18282,18283,\n18284,18285,18286,18287,18288,18289,18290,18291,18292,18293,18294,18295,\n18296,18297,18298,18299,18300,18301,18302,18303,18304,18305,18306,18307,\n18308,18309,18310,18311,18312,18313,18314,18315,18316,18317,18318,18319,\n18320,18321,18322,18323,18324,18325,18326,18327,18328,18329,18330,18331,\n18332,18333,18334,18335,18336,18337,18338,18339,18340,18341,18342,18343,\n18344,18345,18346,18347,18348,18349,18350,18351,18352,18353,18354,18355,\n18356,18357,18358,18359,18360,18361,18362,18363,18364,18365,18366,18367,\n18368,18369,18370,18371,18372,18373,18374,18375,18376,18377,18378,18379,\n18380,18381,18382,18383,18384,18385,18386,18387,18388,18389,18390,18391,\n18392,18393,18394,18395,18396,18397,18398,18399,18400,18401,18402,18403,\n18404,18405,18406,18407,18408,18409,18410,18411,18412,18413,18414,18415,\n18416,18417,18418,18419,18420,18421,18422,18423,18424,18425,18426,18427,\n18428,18429,18430,18431,18432,18433,18434,18435,18436,18437,18438,18439,\n18440,18441,18442,18443,18444,18445,18446,18447,18448,18449,18450,18451,\n18452,18453,18454,18455,18456,18457,18458,18459,18460,18461,18462,18463,\n18464,18465,18466,18467,18468,18469,18470,18471,18472,18473,18474,18475,\n18476,18477,18478,18479,18480,18481,18482,18483,18484,18485,18486,18487,\n18488,18489,18490,18491,18492,18493,18494,18495,18496,18497,18498,18499,\n18500,18501,18502,18503,18504,18505,18506,18507,18508,18509,18510,18511,\n18512,18513,18514,18515,18516,18517,18518,18519,18520,18521,18522,18523,\n18524,18525,18526,18527,18528,18529,18530,18531,18532,18533,18534,18535,\n18536,18537,18538,18539,18540,18541,18542,18543,18544,18545,18546,18547,\n18548,18549,18550,18551,18552,18553,18554,18555,18556,18557,18558,18559,\n18560,18561,18562,18563,18564,18565,18566,18567,18568,18569,18570,18571,\n18572,18573,18574,18575,18576,18577,18578,18579,18580,18581,18582,18583,\n18584,18585,18586,18587,18588,18589,18590,18591,18592,18593,18594,18595,\n18596,18597,18598,18599,18600,18601,18602,18603,18604,18605,18606,18607,\n18608,18609,18610,18611,18612,18613,18614,18615,18616,18617,18618,18619,\n18620,18621,18622,18623,18624,18625,18626,18627,18628,18629,18630,18631,\n18632,18633,18634,18635,18636,18637,18638,18639,18640,18641,18642,18643,\n18644,18645,18646,18647,18648,18649,18650,18651,18652,18653,18654,18655,\n18656,18657,18658,18659,18660,18661,18662,18663,18664,18665,18666,18667,\n18668,18669,18670,18671,18672,18673,18674,18675,18676,18677,18678,18679,\n18680,18681,18682,18683,18684,18685,18686,18687,18688,18689,18690,18691,\n18692,18693,18694,18695,18696,18697,18698,18699,18700,18701,18702,18703,\n18704,18705,18706,18707,18708,18709,18710,18711,18712,18713,18714,18715,\n18716,18717,18718,18719,18720,18721,18722,18723,18724,18725,18726,18727,\n18728,18729,18730,18731,18732,18733,18734,18735,18736,18737,18738,18739,\n18740,18741,18742,18743,18744,18745,18746,18747,18748,18749,18750,18751,\n18752,18753,18754,18755,18756,18757,18758,18759,18760,18761,18762,18763,\n18764,18765,18766,18767,18768,18769,18770,18771,18772,18773,18774,18775,\n18776,18777,18778,18779,18780,18781,18782,18783,18784,18785,18786,18787,\n18788,18789,18790,18791,18792,18793,18794,18795,18796,18797,18798,18799,\n18800,18801,18802,18803,18804,18805,18806,18807,18808,18809,18810,18811,\n18812,18813,18814,18815,18816,18817,18818,18819,18820,18821,18822,18823,\n18824,18825,18826,18827,18828,18829,18830,18831,18832,18833,18834,18835,\n18836,18837,18838,18839,18840,18841,18842,18843,18844,18845,18846,18847,\n18848,18849,18850,18851,18852,18853,18854,18855,18856,18857,18858,18859,\n18860,18861,18862,18863,18864,18865,18866,18867,18868,18869,18870,18871,\n18872,18873,18874,18875,18876,18877,18878,18879,18880,18881,18882,18883,\n18884,18885,18886,18887,18888,18889,18890,18891,18892,18893,18894,18895,\n18896,18897,18898,18899,18900,18901,18902,18903,18904,18905,18906,18907,\n18908,18909,18910,18911,18912,18913,18914,18915,18916,18917,18918,18919,\n18920,18921,18922,18923,18924,18925,18926,18927,18928,18929,18930,18931,\n18932,18933,18934,18935,18936,18937,18938,18939,18940,18941,18942,18943,\n18944,18945,18946,18947,18948,18949,18950,18951,18952,18953,18954,18955,\n18956,18957,18958,18959,18960,18961,18962,18963,18964,18965,18966,18967,\n18968,18969,18970,18971,18972,18973,18974,18975,18976,18977,18978,18979,\n18980,18981,18982,18983,18984,18985,18986,18987,18988,18989,18990,18991,\n18992,18993,18994,18995,18996,18997,18998,18999,19000,19001,19002,19003,\n19004,19005,19006,19007,19008,19009,19010,19011,19012,19013,19014,19015,\n19016,19017,19018,19019,19020,19021,19022,19023,19024,19025,19026,19027,\n19028,19029,19030,19031,19032,19033,19034,19035,19036,19037,19038,19039,\n19040,19041,19042,19043,19044,19045,19046,19047,19048,19049,19050,19051,\n19052,19053,19054,19055,19056,19057,19058,19059,19060,19061,19062,19063,\n19064,19065,19066,19067,19068,19069,19070,19071,19072,19073,19074,19075,\n19076,19077,19078,19079,19080,19081,19082,19083,19084,19085,19086,19087,\n19088,19089,19090,19091,19092,19093,19094,19095,19096,19097,19098,19099,\n19100,19101,19102,19103,19104,19105,19106,19107,19108,19109,19110,19111,\n19112,19113,19114,19115,19116,19117,19118,19119,19120,19121,19122,19123,\n19124,19125,19126,19127,19128,19129,19130,19131,19132,19133,19134,19135,\n19136,19137,19138,19139,19140,19141,19142,19143,19144,19145,19146,19147,\n19148,19149,19150,19151,19152,19153,19154,19155,19156,19157,19158,19159,\n19160,19161,19162,19163,19164,19165,19166,19167,19168,19169,19170,19171,\n19172,19173,19174,19175,19176,19177,19178,19179,19180,19181,19182,19183,\n19184,19185,19186,19187,19188,19189,19190,19191,19192,19193,19194,19195,\n19196,19197,19198,19199,19200,19201,19202,19203,19204,19205,19206,19207,\n19208,19209,19210,19211,19212,19213,19214,19215,19216,19217,19218,19219,\n19220,19221,19222,19223,19224,19225,19226,19227,19228,19229,19230,19231,\n19232,19233,19234,19235,19236,19237,19238,19239,19240,19241,19242,19243,\n19244,19245,19246,19247,19248,19249,19250,19251,19252,19253,19254,19255,\n19256,19257,19258,19259,19260,19261,19262,19263,19264,19265,19266,19267,\n19268,19269,19270,19271,19272,19273,19274,19275,19276,19277,19278,19279,\n19280,19281,19282,19283,19284,19285,19286,19287,19288,19289,19290,19291,\n19292,19293,19294,19295,19296,19297,19298,19299,19300,19301,19302,19303,\n19304,19305,19306,19307,19308,19309,19310,19311,19312,19313,19314,19315,\n19316,19317,19318,19319,19320,19321,19322,19323,19324,19325,19326,19327,\n19328,19329,19330,19331,19332,19333,19334,19335,19336,19337,19338,19339,\n19340,19341,19342,19343,19344,19345,19346,19347,19348,19349,19350,19351,\n19352,19353,19354,19355,19356,19357,19358,19359,19360,19361,19362,19363,\n19364,19365,19366,19367,19368,19369,19370,19371,19372,19373,19374,19375,\n19376,19377,19378,19379,19380,19381,19382,19383,19384,19385,19386,19387,\n19388,19389,19390,19391,19392,19393,19394,19395,19396,19397,19398,19399,\n19400,19401,19402,19403,19404,19405,19406,19407,19408,19409,19410,19411,\n19412,19413,19414,19415,19416,19417,19418,19419,19420,19421,19422,19423,\n19424,19425,19426,19427,19428,19429,19430,19431,19432,19433,19434,19435,\n19436,19437,19438,19439,19440,19441,19442,19443,19444,19445,19446,19447,\n19448,19449,19450,19451,19452,19453,19454,19455,19456,19457,19458,19459,\n19460,19461,19462,19463,19464,19465,19466,19467,19468,19469,19470,19471,\n19472,19473,19474,19475,19476,19477,19478,19479,19480,19481,19482,19483,\n19484,19485,19486,19487,19488,19489,19490,19491,19492,19493,19494,19495,\n19496,19497,19498,19499,19500,19501,19502,19503,19504,19505,19506,19507,\n19508,19509,19510,19511,19512,19513,19514,19515,19516,19517,19518,19519,\n19520,19521,19522,19523,19524,19525,19526,19527,19528,19529,19530,19531,\n19532,19533,19534,19535,19536,19537,19538,19539,19540,19541,19542,19543,\n19544,19545,19546,19547,19548,19549,19550,19551,19552,19553,19554,19555,\n19556,19557,19558,19559,19560,19561,19562,19563,19564,19565,19566,19567,\n19568,19569,19570,19571,19572,19573,19574,19575,19576,19577,19578,19579,\n19580,19581,19582,19583,19584,19585,19586,19587,19588,19589,19590,19591,\n19592,19593,19594,19595,19596,19597,19598,19599,19600,19601,19602,19603,\n19604,19605,19606,19607,19608,19609,19610,19611,19612,19613,19614,19615,\n19616,19617,19618,19619,19620,19621,19622,19623,19624,19625,19626,19627,\n19628,19629,19630,19631,19632,19633,19634,19635,19636,19637,19638,19639,\n19640,19641,19642,19643,19644,19645,19646,19647,19648,19649,19650,19651,\n19652,19653,19654,19655,19656,19657,19658,19659,19660,19661,19662,19663,\n19664,19665,19666,19667,19668,19669,19670,19671,19672,19673,19674,19675,\n19676,19677,19678,19679,19680,19681,19682,19683,19684,19685,19686,19687,\n19688,19689,19690,19691,19692,19693,19694,19695,19696,19697,19698,19699,\n19700,19701,19702,19703,19704,19705,19706,19707,19708,19709,19710,19711,\n19712,19713,19714,19715,19716,19717,19718,19719,19720,19721,19722,19723,\n19724,19725,19726,19727,19728,19729,19730,19731,19732,19733,19734,19735,\n19736,19737,19738,19739,19740,19741,19742,19743,19744,19745,19746,19747,\n19748,19749,19750,19751,19752,19753,19754,19755,19756,19757,19758,19759,\n19760,19761,19762,19763,19764,19765,19766,19767,19768,19769,19770,19771,\n19772,19773,19774,19775,19776,19777,19778,19779,19780,19781,19782,19783,\n19784,19785,19786,19787,19788,19789,19790,19791,19792,19793,19794,19795,\n19796,19797,19798,19799,19800,19801,19802,19803,19804,19805,19806,19807,\n19808,19809,19810,19811,19812,19813,19814,19815,19816,19817,19818,19819,\n19820,19821,19822,19823,19824,19825,19826,19827,19828,19829,19830,19831,\n19832,19833,19834,19835,19836,19837,19838,19839,19840,19841,19842,19843,\n19844,19845,19846,19847,19848,19849,19850,19851,19852,19853,19854,19855,\n19856,19857,19858,19859,19860,19861,19862,19863,19864,19865,19866,19867,\n19868,19869,19870,19871,19872,19873,19874,19875,19876,19877,19878,19879,\n19880,19881,19882,19883,19884,19885,19886,19887,19888,19889,19890,19891,\n19892,19893,19894,19895,19896,19897,19898,19899,19900,19901,19902,19903,\n19904,19905,19906,19907,19908,19909,19910,19911,19912,19913,19914,19915,\n19916,19917,19918,19919,19920,19921,19922,19923,19924,19925,19926,19927,\n19928,19929,19930,19931,19932,19933,19934,19935,19936,19937,19938,19939,\n19940,19941,19942,19943,19944,19945,19946,19947,19948,19949,19950,19951,\n19952,19953,19954,19955,19956,19957,19958,19959,19960,19961,19962,19963,\n19964,19965,19966,19967,19968,19969,19970,19971,19972,19973,19974,19975,\n19976,19977,19978,19979,19980,19981,19982,19983,19984,19985,19986,19987,\n19988,19989,19990,19991,19992,19993,19994,19995,19996,19997,19998,19999,\n20000,20001,20002,20003,20004,20005,20006,20007,20008,20009,20010,20011,\n20012,20013,20014,20015,20016,20017,20018,20019,20020,20021,20022,20023,\n20024,20025,20026,20027,20028,20029,20030,20031,20032,20033,20034,20035,\n20036,20037,20038,20039,20040,20041,20042,20043,20044,20045,20046,20047,\n20048,20049,20050,20051,20052,20053,20054,20055,20056,20057,20058,20059,\n20060,20061,20062,20063,20064,20065,20066,20067,20068,20069,20070,20071,\n20072,20073,20074,20075,20076,20077,20078,20079,20080,20081,20082,20083,\n20084,20085,20086,20087,20088,20089,20090,20091,20092,20093,20094,20095,\n20096,20097,20098,20099,20100,20101,20102,20103,20104,20105,20106,20107,\n20108,20109,20110,20111,20112,20113,20114,20115,20116,20117,20118,20119,\n20120,20121,20122,20123,20124,20125,20126,20127,20128,20129,20130,20131,\n20132,20133,20134,20135,20136,20137,20138,20139,20140,20141,20142,20143,\n20144,20145,20146,20147,20148,20149,20150,20151,20152,20153,20154,20155,\n20156,20157,20158,20159,20160,20161,20162,20163,20164,20165,20166,20167,\n20168,20169,20170,20171,20172,20173,20174,20175,20176,20177,20178,20179,\n20180,20181,20182,20183,20184,20185,20186,20187,20188,20189,20190,20191,\n20192,20193,20194,20195,20196,20197,20198,20199,20200,20201,20202,20203,\n20204,20205,20206,20207,20208,20209,20210,20211,20212,20213,20214,20215,\n20216,20217,20218,20219,20220,20221,20222,20223,20224,20225,20226,20227,\n20228,20229,20230,20231,20232,20233,20234,20235,20236,20237,20238,20239,\n20240,20241,20242,20243,20244,20245,20246,20247,20248,20249,20250,20251,\n20252,20253,20254,20255,20256,20257,20258,20259,20260,20261,20262,20263,\n20264,20265,20266,20267,20268,20269,20270,20271,20272,20273,20274,20275,\n20276,20277,20278,20279,20280,20281,20282,20283,20284,20285,20286,20287,\n20288,20289,20290,20291,20292,20293,20294,20295,20296,20297,20298,20299,\n20300,20301,20302,20303,20304,20305,20306,20307,20308,20309,20310,20311,\n20312,20313,20314,20315,20316,20317,20318,20319,20320,20321,20322,20323,\n20324,20325,20326,20327,20328,20329,20330,20331,20332,20333,20334,20335,\n20336,20337,20338,20339,20340,20341,20342,20343,20344,20345,20346,20347,\n20348,20349,20350,20351,20352,20353,20354,20355,20356,20357,20358,20359,\n20360,20361,20362,20363,20364,20365,20366,20367,20368,20369,20370,20371,\n20372,20373,20374,20375,20376,20377,20378,20379,20380,20381,20382,20383,\n20384,20385,20386,20387,20388,20389,20390,20391,20392,20393,20394,20395,\n20396,20397,20398,20399,20400,20401,20402,20403,20404,20405,20406,20407,\n20408,20409,20410,20411,20412,20413,20414,20415,20416,20417,20418,20419,\n20420,20421,20422,20423,20424,20425,20426,20427,20428,20429,20430,20431,\n20432,20433,20434,20435,20436,20437,20438,20439,20440,20441,20442,20443,\n20444,20445,20446,20447,20448,20449,20450,20451,20452,20453,20454,20455,\n20456,20457,20458,20459,20460,20461,20462,20463,20464,20465,20466,20467,\n20468,20469,20470,20471,20472,20473,20474,20475,20476,20477,20478,20479,\n20480,20481,20482,20483,20484,20485,20486,20487,20488,20489,20490,20491,\n20492,20493,20494,20495,20496,20497,20498,20499,20500,20501,20502,20503,\n20504,20505,20506,20507,20508,20509,20510,20511,20512,20513,20514,20515,\n20516,20517,20518,20519,20520,20521,20522,20523,20524,20525,20526,20527,\n20528,20529,20530,20531,20532,20533,20534,20535,20536,20537,20538,20539,\n20540,20541,20542,20543,20544,20545,20546,20547,20548,20549,20550,20551,\n20552,20553,20554,20555,20556,20557,20558,20559,20560,20561,20562,20563,\n20564,20565,20566,20567,20568,20569,20570,20571,20572,20573,20574,20575,\n20576,20577,20578,20579,20580,20581,20582,20583,20584,20585,20586,20587,\n20588,20589,20590,20591,20592,20593,20594,20595,20596,20597,20598,20599,\n20600,20601,20602,20603,20604,20605,20606,20607,20608,20609,20610,20611,\n20612,20613,20614,20615,20616,20617,20618,20619,20620,20621,20622,20623,\n20624,20625,20626,20627,20628,20629,20630,20631,20632,20633,20634,20635,\n20636,20637,20638,20639,20640,20641,20642,20643,20644,20645,20646,20647,\n20648,20649,20650,20651,20652,20653,20654,20655,20656,20657,20658,20659,\n20660,20661,20662,20663,20664,20665,20666,20667,20668,20669,20670,20671,\n20672,20673,20674,20675,20676,20677,20678,20679,20680,20681,20682,20683,\n20684,20685,20686,20687,20688,20689,20690,20691,20692,20693,20694,20695,\n20696,20697,20698,20699,20700,20701,20702,20703,20704,20705,20706,20707,\n20708,20709,20710,20711,20712,20713,20714,20715,20716,20717,20718,20719,\n20720,20721,20722,20723,20724,20725,20726,20727,20728,20729,20730,20731,\n20732,20733,20734,20735,20736,20737,20738,20739,20740,20741,20742,20743,\n20744,20745,20746,20747,20748,20749,20750,20751,20752,20753,20754,20755,\n20756,20757,20758,20759,20760,20761,20762,20763,20764,20765,20766,20767,\n20768,20769,20770,20771,20772,20773,20774,20775,20776,20777,20778,20779,\n20780,20781,20782,20783,20784,20785,20786,20787,20788,20789,20790,20791,\n20792,20793,20794,20795,20796,20797,20798,20799,20800,20801,20802,20803,\n20804,20805,20806,20807,20808,20809,20810,20811,20812,20813,20814,20815,\n20816,20817,20818,20819,20820,20821,20822,20823,20824,20825,20826,20827,\n20828,20829,20830,20831,20832,20833,20834,20835,20836,20837,20838,20839,\n20840,20841,20842,20843,20844,20845,20846,20847,20848,20849,20850,20851,\n20852,20853,20854,20855,20856,20857,20858,20859,20860,20861,20862,20863,\n20864,20865,20866,20867,20868,20869,20870,20871,20872,20873,20874,20875,\n20876,20877,20878,20879,20880,20881,20882,20883,20884,20885,20886,20887,\n20888,20889,20890,20891,20892,20893,20894,20895,20896,20897,20898,20899,\n20900,20901,20902,20903,20904,20905,20906,20907,20908,20909,20910,20911,\n20912,20913,20914,20915,20916,20917,20918,20919,20920,20921,20922,20923,\n20924,20925,20926,20927,20928,20929,20930,20931,20932,20933,20934,20935,\n20936,20937,20938,20939,20940,20941,20942,20943,20944,20945,20946,20947,\n20948,20949,20950,20951,20952,20953,20954,20955,20956,20957,20958,20959,\n20960,20961,20962,20963,20964,20965,20966,20967,20968,20969,20970,20971,\n20972,20973,20974,20975,20976,20977,20978,20979,20980,20981,20982,20983,\n20984,20985,20986,20987,20988,20989,20990,20991,20992,20993,20994,20995,\n20996,20997,20998,20999,21000,21001,21002,21003,21004,21005,21006,21007,\n21008,21009,21010,21011,21012,21013,21014,21015,21016,21017,21018,21019,\n21020,21021,21022,21023,21024,21025,21026,21027,21028,21029,21030,21031,\n21032,21033,21034,21035,21036,21037,21038,21039,21040,21041,21042,21043,\n21044,21045,21046,21047,21048,21049,21050,21051,21052,21053,21054,21055,\n21056,21057,21058,21059,21060,21061,21062,21063,21064,21065,21066,21067,\n21068,21069,21070,21071,21072,21073,21074,21075,21076,21077,21078,21079,\n21080,21081,21082,21083,21084,21085,21086,21087,21088,21089,21090,21091,\n21092,21093,21094,21095,21096,21097,21098,21099,21100,21101,21102,21103,\n21104,21105,21106,21107,21108,21109,21110,21111,21112,21113,21114,21115,\n21116,21117,21118,21119,21120,21121,21122,21123,21124,21125,21126,21127,\n21128,21129,21130,21131,21132,21133,21134,21135,21136,21137,21138,21139,\n21140,21141,21142,21143,21144,21145,21146,21147,21148,21149,21150,21151,\n21152,21153,21154,21155,21156,21157,21158,21159,21160,21161,21162,21163,\n21164,21165,21166,21167,21168,21169,21170,21171,21172,21173,21174,21175,\n21176,21177,21178,21179,21180,21181,21182,21183,21184,21185,21186,21187,\n21188,21189,21190,21191,21192,21193,21194,21195,21196,21197,21198,21199,\n21200,21201,21202,21203,21204,21205,21206,21207,21208,21209,21210,21211,\n21212,21213,21214,21215,21216,21217,21218,21219,21220,21221,21222,21223,\n21224,21225,21226,21227,21228,21229,21230,21231,21232,21233,21234,21235,\n21236,21237,21238,21239,21240,21241,21242,21243,21244,21245,21246,21247,\n21248,21249,21250,21251,21252,21253,21254,21255,21256,21257,21258,21259,\n21260,21261,21262,21263,21264,21265,21266,21267,21268,21269,21270,21271,\n21272,21273,21274,21275,21276,21277,21278,21279,21280,21281,21282,21283,\n21284,21285,21286,21287,21288,21289,21290,21291,21292,21293,21294,21295,\n21296,21297,21298,21299,21300,21301,21302,21303,21304,21305,21306,21307,\n21308,21309,21310,21311,21312,21313,21314,21315,21316,21317,21318,21319,\n21320,21321,21322,21323,21324,21325,21326,21327,21328,21329,21330,21331,\n21332,21333,21334,21335,21336,21337,21338,21339,21340,21341,21342,21343,\n21344,21345,21346,21347,21348,21349,21350,21351,21352,21353,21354,21355,\n21356,21357,21358,21359,21360,21361,21362,21363,21364,21365,21366,21367,\n21368,21369,21370,21371,21372,21373,21374,21375,21376,21377,21378,21379,\n21380,21381,21382,21383,21384,21385,21386,21387,21388,21389,21390,21391,\n21392,21393,21394,21395,21396,21397,21398,21399,21400,21401,21402,21403,\n21404,21405,21406,21407,21408,21409,21410,21411,21412,21413,21414,21415,\n21416,21417,21418,21419,21420,21421,21422,21423,21424,21425,21426,21427,\n21428,21429,21430,21431,21432,21433,21434,21435,21436,21437,21438,21439,\n21440,21441,21442,21443,21444,21445,21446,21447,21448,21449,21450,21451,\n21452,21453,21454,21455,21456,21457,21458,21459,21460,21461,21462,21463,\n21464,21465,21466,21467,21468,21469,21470,21471,21472,21473,21474,21475,\n21476,21477,21478,21479,21480,21481,21482,21483,21484,21485,21486,21487,\n21488,21489,21490,21491,21492,21493,21494,21495,21496,21497,21498,21499,\n21500,21501,21502,21503,21504,21505,21506,21507,21508,21509,21510,21511,\n21512,21513,21514,21515,21516,21517,21518,21519,21520,21521,21522,21523,\n21524,21525,21526,21527,21528,21529,21530,21531,21532,21533,21534,21535,\n21536,21537,21538,21539,21540,21541,21542,21543,21544,21545,21546,21547,\n21548,21549,21550,21551,21552,21553,21554,21555,21556,21557,21558,21559,\n21560,21561,21562,21563,21564,21565,21566,21567,21568,21569,21570,21571,\n21572,21573,21574,21575,21576,21577,21578,21579,21580,21581,21582,21583,\n21584,21585,21586,21587,21588,21589,21590,21591,21592,21593,21594,21595,\n21596,21597,21598,21599,21600,21601,21602,21603,21604,21605,21606,21607,\n21608,21609,21610,21611,21612,21613,21614,21615,21616,21617,21618,21619,\n21620,21621,21622,21623,21624,21625,21626,21627,21628,21629,21630,21631,\n21632,21633,21634,21635,21636,21637,21638,21639,21640,21641,21642,21643,\n21644,21645,21646,21647,21648,21649,21650,21651,21652,21653,21654,21655,\n21656,21657,21658,21659,21660,21661,21662,21663,21664,21665,21666,21667,\n21668,21669,21670,21671,21672,21673,21674,21675,21676,21677,21678,21679,\n21680,21681,21682,21683,21684,21685,21686,21687,21688,21689,21690,21691,\n21692,21693,21694,21695,21696,21697,21698,21699,21700,21701,21702,21703,\n21704,21705,21706,21707,21708,21709,21710,21711,21712,21713,21714,21715,\n21716,21717,21718,21719,21720,21721,21722,21723,21724,21725,21726,21727,\n21728,21729,21730,21731,21732,21733,21734,21735,21736,21737,21738,21739,\n21740,21741,21742,21743,21744,21745,21746,21747,21748,21749,21750,21751,\n21752,21753,21754,21755,21756,21757,21758,21759,21760,21761,21762,21763,\n21764,21765,21766,21767,21768,21769,21770,21771,21772,21773,21774,21775,\n21776,21777,21778,21779,21780,21781,21782,21783,21784,21785,21786,21787,\n21788,21789,21790,21791,21792,21793,21794,21795,21796,21797,21798,21799,\n21800,21801,21802,21803,21804,21805,21806,21807,21808,21809,21810,21811,\n21812,21813,21814,21815,21816,21817,21818,21819,21820,21821,21822,21823,\n21824,21825,21826,21827,21828,21829,21830,21831,21832,21833,21834,21835,\n21836,21837,21838,21839,21840,21841,21842,21843,21844,21845,21846,21847,\n21848,21849,21850,21851,21852,21853,21854,21855,21856,21857,21858,21859,\n21860,21861,21862,21863,21864,21865,21866,21867,21868,21869,21870,21871,\n21872,21873,21874,21875,21876,21877,21878,21879,21880,21881,21882,21883,\n21884,21885,21886,21887,21888,21889,21890,21891,21892,21893,21894,21895,\n21896,21897,21898,21899,21900,21901,21902,21903,21904,21905,21906,21907,\n21908,21909,21910,21911,21912,21913,21914,21915,21916,21917,21918,21919,\n21920,21921,21922,21923,21924,21925,21926,21927,21928,21929,21930,21931,\n21932,21933,21934,21935,21936,21937,21938,21939,21940,21941,21942,21943,\n21944,21945,21946,21947,21948,21949,21950,21951,21952,21953,21954,21955,\n21956,21957,21958,21959,21960,21961,21962,21963,21964,21965,21966,21967,\n21968,21969,21970,21971,21972,21973,21974,21975,21976,21977,21978,21979,\n21980,21981,21982,21983,21984,21985,21986,21987,21988,21989,21990,21991,\n21992,21993,21994,21995,21996,21997,21998,21999,22000,22001,22002,22003,\n22004,22005,22006,22007,22008,22009,22010,22011,22012,22013,22014,22015,\n22016,22017,22018,22019,22020,22021,22022,22023,22024,22025,22026,22027,\n22028,22029,22030,22031,22032,22033,22034,22035,22036,22037,22038,22039,\n22040,22041,22042,22043,22044,22045,22046,22047,22048,22049,22050,22051,\n22052,22053,22054,22055,22056,22057,22058,22059,22060,22061,22062,22063,\n22064,22065,22066,22067,22068,22069,22070,22071,22072,22073,22074,22075,\n22076,22077,22078,22079,22080,22081,22082,22083,22084,22085,22086,22087,\n22088,22089,22090,22091,22092,22093,22094,22095,22096,22097,22098,22099,\n22100,22101,22102,22103,22104,22105,22106,22107,22108,22109,22110,22111,\n22112,22113,22114,22115,22116,22117,22118,22119,22120,22121,22122,22123,\n22124,22125,22126,22127,22128,22129,22130,22131,22132,22133,22134,22135,\n22136,22137,22138,22139,22140,22141,22142,22143,22144,22145,22146,22147,\n22148,22149,22150,22151,22152,22153,22154,22155,22156,22157,22158,22159,\n22160,22161,22162,22163,22164,22165,22166,22167,22168,22169,22170,22171,\n22172,22173,22174,22175,22176,22177,22178,22179,22180,22181,22182,22183,\n22184,22185,22186,22187,22188,22189,22190,22191,22192,22193,22194,22195,\n22196,22197,22198,22199,22200,22201,22202,22203,22204,22205,22206,22207,\n22208,22209,22210,22211,22212,22213,22214,22215,22216,22217,22218,22219,\n22220,22221,22222,22223,22224,22225,22226,22227,22228,22229,22230,22231,\n22232,22233,22234,22235,22236,22237,22238,22239,22240,22241,22242,22243,\n22244,22245,22246,22247,22248,22249,22250,22251,22252,22253,22254,22255,\n22256,22257,22258,22259,22260,22261,22262,22263,22264,22265,22266,22267,\n22268,22269,22270,22271,22272,22273,22274,22275,22276,22277,22278,22279,\n22280,22281,22282,22283,22284,22285,22286,22287,22288,22289,22290,22291,\n22292,22293,22294,22295,22296,22297,22298,22299,22300,22301,22302,22303,\n22304,22305,22306,22307,22308,22309,22310,22311,22312,22313,22314,22315,\n22316,22317,22318,22319,22320,22321,22322,22323,22324,22325,22326,22327,\n22328,22329,22330,22331,22332,22333,22334,22335,22336,22337,22338,22339,\n22340,22341,22342,22343,22344,22345,22346,22347,22348,22349,22350,22351,\n22352,22353,22354,22355,22356,22357,22358,22359,22360,22361,22362,22363,\n22364,22365,22366,22367,22368,22369,22370,22371,22372,22373,22374,22375,\n22376,22377,22378,22379,22380,22381,22382,22383,22384,22385,22386,22387,\n22388,22389,22390,22391,22392,22393,22394,22395,22396,22397,22398,22399,\n22400,22401,22402,22403,22404,22405,22406,22407,22408,22409,22410,22411,\n22412,22413,22414,22415,22416,22417,22418,22419,22420,22421,22422,22423,\n22424,22425,22426,22427,22428,22429,22430,22431,22432,22433,22434,22435,\n22436,22437,22438,22439,22440,22441,22442,22443,22444,22445,22446,22447,\n22448,22449,22450,22451,22452,22453,22454,22455,22456,22457,22458,22459,\n22460,22461,22462,22463,22464,22465,22466,22467,22468,22469,22470,22471,\n22472,22473,22474,22475,22476,22477,22478,22479,22480,22481,22482,22483,\n22484,22485,22486,22487,22488,22489,22490,22491,22492,22493,22494,22495,\n22496,22497,22498,22499,22500,22501,22502,22503,22504,22505,22506,22507,\n22508,22509,22510,22511,22512,22513,22514,22515,22516,22517,22518,22519,\n22520,22521,22522,22523,22524,22525,22526,22527,22528,22529,22530,22531,\n22532,22533,22534,22535,22536,22537,22538,22539,22540,22541,22542,22543,\n22544,22545,22546,22547,22548,22549,22550,22551,22552,22553,22554,22555,\n22556,22557,22558,22559,22560,22561,22562,22563,22564,22565,22566,22567,\n22568,22569,22570,22571,22572,22573,22574,22575,22576,22577,22578,22579,\n22580,22581,22582,22583,22584,22585,22586,22587,22588,22589,22590,22591,\n22592,22593,22594,22595,22596,22597,22598,22599,22600,22601,22602,22603,\n22604,22605,22606,22607,22608,22609,22610,22611,22612,22613,22614,22615,\n22616,22617,22618,22619,22620,22621,22622,22623,22624,22625,22626,22627,\n22628,22629,22630,22631,22632,22633,22634,22635,22636,22637,22638,22639,\n22640,22641,22642,22643,22644,22645,22646,22647,22648,22649,22650,22651,\n22652,22653,22654,22655,22656,22657,22658,22659,22660,22661,22662,22663,\n22664,22665,22666,22667,22668,22669,22670,22671,22672,22673,22674,22675,\n22676,22677,22678,22679,22680,22681,22682,22683,22684,22685,22686,22687,\n22688,22689,22690,22691,22692,22693,22694,22695,22696,22697,22698,22699,\n22700,22701,22702,22703,22704,22705,22706,22707,22708,22709,22710,22711,\n22712,22713,22714,22715,22716,22717,22718,22719,22720,22721,22722,22723,\n22724,22725,22726,22727,22728,22729,22730,22731,22732,22733,22734,22735,\n22736,22737,22738,22739,22740,22741,22742,22743,22744,22745,22746,22747,\n22748,22749,22750,22751,22752,22753,22754,22755,22756,22757,22758,22759,\n22760,22761,22762,22763,22764,22765,22766,22767,22768,22769,22770,22771,\n22772,22773,22774,22775,22776,22777,22778,22779,22780,22781,22782,22783,\n22784,22785,22786,22787,22788,22789,22790,22791,22792,22793,22794,22795,\n22796,22797,22798,22799,22800,22801,22802,22803,22804,22805,22806,22807,\n22808,22809,22810,22811,22812,22813,22814,22815,22816,22817,22818,22819,\n22820,22821,22822,22823,22824,22825,22826,22827,22828,22829,22830,22831,\n22832,22833,22834,22835,22836,22837,22838,22839,22840,22841,22842,22843,\n22844,22845,22846,22847,22848,22849,22850,22851,22852,22853,22854,22855,\n22856,22857,22858,22859,22860,22861,22862,22863,22864,22865,22866,22867,\n22868,22869,22870,22871,22872,22873,22874,22875,22876,22877,22878,22879,\n22880,22881,22882,22883,22884,22885,22886,22887,22888,22889,22890,22891,\n22892,22893,22894,22895,22896,22897,22898,22899,22900,22901,22902,22903,\n22904,22905,22906,22907,22908,22909,22910,22911,22912,22913,22914,22915,\n22916,22917,22918,22919,22920,22921,22922,22923,22924,22925,22926,22927,\n22928,22929,22930,22931,22932,22933,22934,22935,22936,22937,22938,22939,\n22940,22941,22942,22943,22944,22945,22946,22947,22948,22949,22950,22951,\n22952,22953,22954,22955,22956,22957,22958,22959,22960,22961,22962,22963,\n22964,22965,22966,22967,22968,22969,22970,22971,22972,22973,22974,22975,\n22976,22977,22978,22979,22980,22981,22982,22983,22984,22985,22986,22987,\n22988,22989,22990,22991,22992,22993,22994,22995,22996,22997,22998,22999,\n23000,23001,23002,23003,23004,23005,23006,23007,23008,23009,23010,23011,\n23012,23013,23014,23015,23016,23017,23018,23019,23020,23021,23022,23023,\n23024,23025,23026,23027,23028,23029,23030,23031,23032,23033,23034,23035,\n23036,23037,23038,23039,23040,23041,23042,23043,23044,23045,23046,23047,\n23048,23049,23050,23051,23052,23053,23054,23055,23056,23057,23058,23059,\n23060,23061,23062,23063,23064,23065,23066,23067,23068,23069,23070,23071,\n23072,23073,23074,23075,23076,23077,23078,23079,23080,23081,23082,23083,\n23084,23085,23086,23087,23088,23089,23090,23091,23092,23093,23094,23095,\n23096,23097,23098,23099,23100,23101,23102,23103,23104,23105,23106,23107,\n23108,23109,23110,23111,23112,23113,23114,23115,23116,23117,23118,23119,\n23120,23121,23122,23123,23124,23125,23126,23127,23128,23129,23130,23131,\n23132,23133,23134,23135,23136,23137,23138,23139,23140,23141,23142,23143,\n23144,23145,23146,23147,23148,23149,23150,23151,23152,23153,23154,23155,\n23156,23157,23158,23159,23160,23161,23162,23163,23164,23165,23166,23167,\n23168,23169,23170,23171,23172,23173,23174,23175,23176,23177,23178,23179,\n23180,23181,23182,23183,23184,23185,23186,23187,23188,23189,23190,23191,\n23192,23193,23194,23195,23196,23197,23198,23199,23200,23201,23202,23203,\n23204,23205,23206,23207,23208,23209,23210,23211,23212,23213,23214,23215,\n23216,23217,23218,23219,23220,23221,23222,23223,23224,23225,23226,23227,\n23228,23229,23230,23231,23232,23233,23234,23235,23236,23237,23238,23239,\n23240,23241,23242,23243,23244,23245,23246,23247,23248,23249,23250,23251,\n23252,23253,23254,23255,23256,23257,23258,23259,23260,23261,23262,23263,\n23264,23265,23266,23267,23268,23269,23270,23271,23272,23273,23274,23275,\n23276,23277,23278,23279,23280,23281,23282,23283,23284,23285,23286,23287,\n23288,23289,23290,23291,23292,23293,23294,23295,23296,23297,23298,23299,\n23300,23301,23302,23303,23304,23305,23306,23307,23308,23309,23310,23311,\n23312,23313,23314,23315,23316,23317,23318,23319,23320,23321,23322,23323,\n23324,23325,23326,23327,23328,23329,23330,23331,23332,23333,23334,23335,\n23336,23337,23338,23339,23340,23341,23342,23343,23344,23345,23346,23347,\n23348,23349,23350,23351,23352,23353,23354,23355,23356,23357,23358,23359,\n23360,23361,23362,23363,23364,23365,23366,23367,23368,23369,23370,23371,\n23372,23373,23374,23375,23376,23377,23378,23379,23380,23381,23382,23383,\n23384,23385,23386,23387,23388,23389,23390,23391,23392,23393,23394,23395,\n23396,23397,23398,23399,23400,23401,23402,23403,23404,23405,23406,23407,\n23408,23409,23410,23411,23412,23413,23414,23415,23416,23417,23418,23419,\n23420,23421,23422,23423,23424,23425,23426,23427,23428,23429,23430,23431,\n23432,23433,23434,23435,23436,23437,23438,23439,23440,23441,23442,23443,\n23444,23445,23446,23447,23448,23449,23450,23451,23452,23453,23454,23455,\n23456,23457,23458,23459,23460,23461,23462,23463,23464,23465,23466,23467,\n23468,23469,23470,23471,23472,23473,23474,23475,23476,23477,23478,23479,\n23480,23481,23482,23483,23484,23485,23486,23487,23488,23489,23490,23491,\n23492,23493,23494,23495,23496,23497,23498,23499,23500,23501,23502,23503,\n23504,23505,23506,23507,23508,23509,23510,23511,23512,23513,23514,23515,\n23516,23517,23518,23519,23520,23521,23522,23523,23524,23525,23526,23527,\n23528,23529,23530,23531,23532,23533,23534,23535,23536,23537,23538,23539,\n23540,23541,23542,23543,23544,23545,23546,23547,23548,23549,23550,23551,\n23552,23553,23554,23555,23556,23557,23558,23559,23560,23561,23562,23563,\n23564,23565,23566,23567,23568,23569,23570,23571,23572,23573,23574,23575,\n23576,23577,23578,23579,23580,23581,23582,23583,23584,23585,23586,23587,\n23588,23589,23590,23591,23592,23593,23594,23595,23596,23597,23598,23599,\n23600,23601,23602,23603,23604,23605,23606,23607,23608,23609,23610,23611,\n23612,23613,23614,23615,23616,23617,23618,23619,23620,23621,23622,23623,\n23624,23625,23626,23627,23628,23629,23630,23631,23632,23633,23634,23635,\n23636,23637,23638,23639,23640,23641,23642,23643,23644,23645,23646,23647,\n23648,23649,23650,23651,23652,23653,23654,23655,23656,23657,23658,23659,\n23660,23661,23662,23663,23664,23665,23666,23667,23668,23669,23670,23671,\n23672,23673,23674,23675,23676,23677,23678,23679,23680,23681,23682,23683,\n23684,23685,23686,23687,23688,23689,23690,23691,23692,23693,23694,23695,\n23696,23697,23698,23699,23700,23701,23702,23703,23704,23705,23706,23707,\n23708,23709,23710,23711,23712,23713,23714,23715,23716,23717,23718,23719,\n23720,23721,23722,23723,23724,23725,23726,23727,23728,23729,23730,23731,\n23732,23733,23734,23735,23736,23737,23738,23739,23740,23741,23742,23743,\n23744,23745,23746,23747,23748,23749,23750,23751,23752,23753,23754,23755,\n23756,23757,23758,23759,23760,23761,23762,23763,23764,23765,23766,23767,\n23768,23769,23770,23771,23772,23773,23774,23775,23776,23777,23778,23779,\n23780,23781,23782,23783,23784,23785,23786,23787,23788,23789,23790,23791,\n23792,23793,23794,23795,23796,23797,23798,23799,23800,23801,23802,23803,\n23804,23805,23806,23807,23808,23809,23810,23811,23812,23813,23814,23815,\n23816,23817,23818,23819,23820,23821,23822,23823,23824,23825,23826,23827,\n23828,23829,23830,23831,23832,23833,23834,23835,23836,23837,23838,23839,\n23840,23841,23842,23843,23844,23845,23846,23847,23848,23849,23850,23851,\n23852,23853,23854,23855,23856,23857,23858,23859,23860,23861,23862,23863,\n23864,23865,23866,23867,23868,23869,23870,23871,23872,23873,23874,23875,\n23876,23877,23878,23879,23880,23881,23882,23883,23884,23885,23886,23887,\n23888,23889,23890,23891,23892,23893,23894,23895,23896,23897,23898,23899,\n23900,23901,23902,23903,23904,23905,23906,23907,23908,23909,23910,23911,\n23912,23913,23914,23915,23916,23917,23918,23919,23920,23921,23922,23923,\n23924,23925,23926,23927,23928,23929,23930,23931,23932,23933,23934,23935,\n23936,23937,23938,23939,23940,23941,23942,23943,23944,23945,23946,23947,\n23948,23949,23950,23951,23952,23953,23954,23955,23956,23957,23958,23959,\n23960,23961,23962,23963,23964,23965,23966,23967,23968,23969,23970,23971,\n23972,23973,23974,23975,23976,23977,23978,23979,23980,23981,23982,23983,\n23984,23985,23986,23987,23988,23989,23990,23991,23992,23993,23994,23995,\n23996,23997,23998,23999,24000,24001,24002,24003,24004,24005,24006,24007,\n24008,24009,24010,24011,24012,24013,24014,24015,24016,24017,24018,24019,\n24020,24021,24022,24023,24024,24025,24026,24027,24028,24029,24030,24031,\n24032,24033,24034,24035,24036,24037,24038,24039,24040,24041,24042,24043,\n24044,24045,24046,24047,24048,24049,24050,24051,24052,24053,24054,24055,\n24056,24057,24058,24059,24060,24061,24062,24063,24064,24065,24066,24067,\n24068,24069,24070,24071,24072,24073,24074,24075,24076,24077,24078,24079,\n24080,24081,24082,24083,24084,24085,24086,24087,24088,24089,24090,24091,\n24092,24093,24094,24095,24096,24097,24098,24099,24100,24101,24102,24103,\n24104,24105,24106,24107,24108,24109,24110,24111,24112,24113,24114,24115,\n24116,24117,24118,24119,24120,24121,24122,24123,24124,24125,24126,24127,\n24128,24129,24130,24131,24132,24133,24134,24135,24136,24137,24138,24139,\n24140,24141,24142,24143,24144,24145,24146,24147,24148,24149,24150,24151,\n24152,24153,24154,24155,24156,24157,24158,24159,24160,24161,24162,24163,\n24164,24165,24166,24167,24168,24169,24170,24171,24172,24173,24174,24175,\n24176,24177,24178,24179,24180,24181,24182,24183,24184,24185,24186,24187,\n24188,24189,24190,24191,24192,24193,24194,24195,24196,24197,24198,24199,\n24200,24201,24202,24203,24204,24205,24206,24207,24208,24209,24210,24211,\n24212,24213,24214,24215,24216,24217,24218,24219,24220,24221,24222,24223,\n24224,24225,24226,24227,24228,24229,24230,24231,24232,24233,24234,24235,\n24236,24237,24238,24239,24240,24241,24242,24243,24244,24245,24246,24247,\n24248,24249,24250,24251,24252,24253,24254,24255,24256,24257,24258,24259,\n24260,24261,24262,24263,24264,24265,24266,24267,24268,24269,24270,24271,\n24272,24273,24274,24275,24276,24277,24278,24279,24280,24281,24282,24283,\n24284,24285,24286,24287,24288,24289,24290,24291,24292,24293,24294,24295,\n24296,24297,24298,24299,24300,24301,24302,24303,24304,24305,24306,24307,\n24308,24309,24310,24311,24312,24313,24314,24315,24316,24317,24318,24319,\n24320,24321,24322,24323,24324,24325,24326,24327,24328,24329,24330,24331,\n24332,24333,24334,24335,24336,24337,24338,24339,24340,24341,24342,24343,\n24344,24345,24346,24347,24348,24349,24350,24351,24352,24353,24354,24355,\n24356,24357,24358,24359,24360,24361,24362,24363,24364,24365,24366,24367,\n24368,24369,24370,24371,24372,24373,24374,24375,24376,24377,24378,24379,\n24380,24381,24382,24383,24384,24385,24386,24387,24388,24389,24390,24391,\n24392,24393,24394,24395,24396,24397,24398,24399,24400,24401,24402,24403,\n24404,24405,24406,24407,24408,24409,24410,24411,24412,24413,24414,24415,\n24416,24417,24418,24419,24420,24421,24422,24423,24424,24425,24426,24427,\n24428,24429,24430,24431,24432,24433,24434,24435,24436,24437,24438,24439,\n24440,24441,24442,24443,24444,24445,24446,24447,24448,24449,24450,24451,\n24452,24453,24454,24455,24456,24457,24458,24459,24460,24461,24462,24463,\n24464,24465,24466,24467,24468,24469,24470,24471,24472,24473,24474,24475,\n24476,24477,24478,24479,24480,24481,24482,24483,24484,24485,24486,24487,\n24488,24489,24490,24491,24492,24493,24494,24495,24496,24497,24498,24499,\n24500,24501,24502,24503,24504,24505,24506,24507,24508,24509,24510,24511,\n24512,24513,24514,24515,24516,24517,24518,24519,24520,24521,24522,24523,\n24524,24525,24526,24527,24528,24529,24530,24531,24532,24533,24534,24535,\n24536,24537,24538,24539,24540,24541,24542,24543,24544,24545,24546,24547,\n24548,24549,24550,24551,24552,24553,24554,24555,24556,24557,24558,24559,\n24560,24561,24562,24563,24564,24565,24566,24567,24568,24569,24570,24571,\n24572,24573,24574,24575,24576,24577,24578,24579,24580,24581,24582,24583,\n24584,24585,24586,24587,24588,24589,24590,24591,24592,24593,24594,24595,\n24596,24597,24598,24599,24600,24601,24602,24603,24604,24605,24606,24607,\n24608,24609,24610,24611,24612,24613,24614,24615,24616,24617,24618,24619,\n24620,24621,24622,24623,24624,24625,24626,24627,24628,24629,24630,24631,\n24632,24633,24634,24635,24636,24637,24638,24639,24640,24641,24642,24643,\n24644,24645,24646,24647,24648,24649,24650,24651,24652,24653,24654,24655,\n24656,24657,24658,24659,24660,24661,24662,24663,24664,24665,24666,24667,\n24668,24669,24670,24671,24672,24673,24674,24675,24676,24677,24678,24679,\n24680,24681,24682,24683,24684,24685,24686,24687,24688,24689,24690,24691,\n24692,24693,24694,24695,24696,24697,24698,24699,24700,24701,24702,24703,\n24704,24705,24706,24707,24708,24709,24710,24711,24712,24713,24714,24715,\n24716,24717,24718,24719,24720,24721,24722,24723,24724,24725,24726,24727,\n24728,24729,24730,24731,24732,24733,24734,24735,24736,24737,24738,24739,\n24740,24741,24742,24743,24744,24745,24746,24747,24748,24749,24750,24751,\n24752,24753,24754,24755,24756,24757,24758,24759,24760,24761,24762,24763,\n24764,24765,24766,24767,24768,24769,24770,24771,24772,24773,24774,24775,\n24776,24777,24778,24779,24780,24781,24782,24783,24784,24785,24786,24787,\n24788,24789,24790,24791,24792,24793,24794,24795,24796,24797,24798,24799,\n24800,24801,24802,24803,24804,24805,24806,24807,24808,24809,24810,24811,\n24812,24813,24814,24815,24816,24817,24818,24819,24820,24821,24822,24823,\n24824,24825,24826,24827,24828,24829,24830,24831,24832,24833,24834,24835,\n24836,24837,24838,24839,24840,24841,24842,24843,24844,24845,24846,24847,\n24848,24849,24850,24851,24852,24853,24854,24855,24856,24857,24858,24859,\n24860,24861,24862,24863,24864,24865,24866,24867,24868,24869,24870,24871,\n24872,24873,24874,24875,24876,24877,24878,24879,24880,24881,24882,24883,\n24884,24885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24895,\n24896,24897,24898,24899,24900,24901,24902,24903,24904,24905,24906,24907,\n24908,24909,24910,24911,24912,24913,24914,24915,24916,24917,24918,24919,\n24920,24921,24922,24923,24924,24925,24926,24927,24928,24929,24930,24931,\n24932,24933,24934,24935,24936,24937,24938,24939,24940,24941,24942,24943,\n24944,24945,24946,24947,24948,24949,24950,24951,24952,24953,24954,24955,\n24956,24957,24958,24959,24960,24961,24962,24963,24964,24965,24966,24967,\n24968,24969,24970,24971,24972,24973,24974,24975,24976,24977,24978,24979,\n24980,24981,24982,24983,24984,24985,24986,24987,24988,24989,24990,24991,\n24992,24993,24994,24995,24996,24997,24998,24999,25000,25001,25002,25003,\n25004,25005,25006,25007,25008,25009,25010,25011,25012,25013,25014,25015,\n25016,25017,25018,25019,25020,25021,25022,25023,25024,25025,25026,25027,\n25028,25029,25030,25031,25032,25033,25034,25035,25036,25037,25038,25039,\n25040,25041,25042,25043,25044,25045,25046,25047,25048,25049,25050,25051,\n25052,25053,25054,25055,25056,25057,25058,25059,25060,25061,25062,25063,\n25064,25065,25066,25067,25068,25069,25070,25071,25072,25073,25074,25075,\n25076,25077,25078,25079,25080,25081,25082,25083,25084,25085,25086,25087,\n25088,25089,25090,25091,25092,25093,25094,25095,25096,25097,25098,25099,\n25100,25101,25102,25103,25104,25105,25106,25107,25108,25109,25110,25111,\n25112,25113,25114,25115,25116,25117,25118,25119,25120,25121,25122,25123,\n25124,25125,25126,25127,25128,25129,25130,25131,25132,25133,25134,25135,\n25136,25137,25138,25139,25140,25141,25142,25143,25144,25145,25146,25147,\n25148,25149,25150,25151,25152,25153,25154,25155,25156,25157,25158,25159,\n25160,25161,25162,25163,25164,25165,25166,25167,25168,25169,25170,25171,\n25172,25173,25174,25175,25176,25177,25178,25179,25180,25181,25182,25183,\n25184,25185,25186,25187,25188,25189,25190,25191,25192,25193,25194,25195,\n25196,25197,25198,25199,25200,25201,25202,25203,25204,25205,25206,25207,\n25208,25209,25210,25211,25212,25213,25214,25215,25216,25217,25218,25219,\n25220,25221,25222,25223,25224,25225,25226,25227,25228,25229,25230,25231,\n25232,25233,25234,25235,25236,25237,25238,25239,25240,25241,25242,25243,\n25244,25245,25246,25247,25248,25249,25250,25251,25252,25253,25254,25255,\n25256,25257,25258,25259,25260,25261,25262,25263,25264,25265,25266,25267,\n25268,25269,25270,25271,25272,25273,25274,25275,25276,25277,25278,25279,\n25280,25281,25282,25283,25284,25285,25286,25287,25288,25289,25290,25291,\n25292,25293,25294,25295,25296,25297,25298,25299,25300,25301,25302,25303,\n25304,25305,25306,25307,25308,25309,25310,25311,25312,25313,25314,25315,\n25316,25317,25318,25319,25320,25321,25322,25323,25324,25325,25326,25327,\n25328,25329,25330,25331,25332,25333,25334,25335,25336,25337,25338,25339,\n25340,25341,25342,25343,25344,25345,25346,25347,25348,25349,25350,25351,\n25352,25353,25354,25355,25356,25357,25358,25359,25360,25361,25362,25363,\n25364,25365,25366,25367,25368,25369,25370,25371,25372,25373,25374,25375,\n25376,25377,25378,25379,25380,25381,25382,25383,25384,25385,25386,25387,\n25388,25389,25390,25391,25392,25393,25394,25395,25396,25397,25398,25399,\n25400,25401,25402,25403,25404,25405,25406,25407,25408,25409,25410,25411,\n25412,25413,25414,25415,25416,25417,25418,25419,25420,25421,25422,25423,\n25424,25425,25426,25427,25428,25429,25430,25431,25432,25433,25434,25435,\n25436,25437,25438,25439,25440,25441,25442,25443,25444,25445,25446,25447,\n25448,25449,25450,25451,25452,25453,25454,25455,25456,25457,25458,25459,\n25460,25461,25462,25463,25464,25465,25466,25467,25468,25469,25470,25471,\n25472,25473,25474,25475,25476,25477,25478,25479,25480,25481,25482,25483,\n25484,25485,25486,25487,25488,25489,25490,25491,25492,25493,25494,25495,\n25496,25497,25498,25499,25500,25501,25502,25503,25504,25505,25506,25507,\n25508,25509,25510,25511,25512,25513,25514,25515,25516,25517,25518,25519,\n25520,25521,25522,25523,25524,25525,25526,25527,25528,25529,25530,25531,\n25532,25533,25534,25535,25536,25537,25538,25539,25540,25541,25542,25543,\n25544,25545,25546,25547,25548,25549,25550,25551,25552,25553,25554,25555,\n25556,25557,25558,25559,25560,25561,25562,25563,25564,25565,25566,25567,\n25568,25569,25570,25571,25572,25573,25574,25575,25576,25577,25578,25579,\n25580,25581,25582,25583,25584,25585,25586,25587,25588,25589,25590,25591,\n25592,25593,25594,25595,25596,25597,25598,25599,25600,25601,25602,25603,\n25604,25605,25606,25607,25608,25609,25610,25611,25612,25613,25614,25615,\n25616,25617,25618,25619,25620,25621,25622,25623,25624,25625,25626,25627,\n25628,25629,25630,25631,25632,25633,25634,25635,25636,25637,25638,25639,\n25640,25641,25642,25643,25644,25645,25646,25647,25648,25649,25650,25651,\n25652,25653,25654,25655,25656,25657,25658,25659,25660,25661,25662,25663,\n25664,25665,25666,25667,25668,25669,25670,25671,25672,25673,25674,25675,\n25676,25677,25678,25679,25680,25681,25682,25683,25684,25685,25686,25687,\n25688,25689,25690,25691,25692,25693,25694,25695,25696,25697,25698,25699,\n25700,25701,25702,25703,25704,25705,25706,25707,25708,25709,25710,25711,\n25712,25713,25714,25715,25716,25717,25718,25719,25720,25721,25722,25723,\n25724,25725,25726,25727,25728,25729,25730,25731,25732,25733,25734,25735,\n25736,25737,25738,25739,25740,25741,25742,25743,25744,25745,25746,25747,\n25748,25749,25750,25751,25752,25753,25754,25755,25756,25757,25758,25759,\n25760,25761,25762,25763,25764,25765,25766,25767,25768,25769,25770,25771,\n25772,25773,25774,25775,25776,25777,25778,25779,25780,25781,25782,25783,\n25784,25785,25786,25787,25788,25789,25790,25791,25792,25793,25794,25795,\n25796,25797,25798,25799,25800,25801,25802,25803,25804,25805,25806,25807,\n25808,25809,25810,25811,25812,25813,25814,25815,25816,25817,25818,25819,\n25820,25821,25822,25823,25824,25825,25826,25827,25828,25829,25830,25831,\n25832,25833,25834,25835,25836,25837,25838,25839,25840,25841,25842,25843,\n25844,25845,25846,25847,25848,25849,25850,25851,25852,25853,25854,25855,\n25856,25857,25858,25859,25860,25861,25862,25863,25864,25865,25866,25867,\n25868,25869,25870,25871,25872,25873,25874,25875,25876,25877,25878,25879,\n25880,25881,25882,25883,25884,25885,25886,25887,25888,25889,25890,25891,\n25892,25893,25894,25895,25896,25897,25898,25899,25900,25901,25902,25903,\n25904,25905,25906,25907,25908,25909,25910,25911,25912,25913,25914,25915,\n25916,25917,25918,25919,25920,25921,25922,25923,25924,25925,25926,25927,\n25928,25929,25930,25931,25932,25933,25934,25935,25936,25937,25938,25939,\n25940,25941,25942,25943,25944,25945,25946,25947,25948,25949,25950,25951,\n25952,25953,25954,25955,25956,25957,25958,25959,25960,25961,25962,25963,\n25964,25965,25966,25967,25968,25969,25970,25971,25972,25973,25974,25975,\n25976,25977,25978,25979,25980,25981,25982,25983,25984,25985,25986,25987,\n25988,25989,25990,25991,25992,25993,25994,25995,25996,25997,25998,25999,\n26000,26001,26002,26003,26004,26005,26006,26007,26008,26009,26010,26011,\n26012,26013,26014,26015,26016,26017,26018,26019,26020,26021,26022,26023,\n26024,26025,26026,26027,26028,26029,26030,26031,26032,26033,26034,26035,\n26036,26037,26038,26039,26040,26041,26042,26043,26044,26045,26046,26047,\n26048,26049,26050,26051,26052,26053,26054,26055,26056,26057,26058,26059,\n26060,26061,26062,26063,26064,26065,26066,26067,26068,26069,26070,26071,\n26072,26073,26074,26075,26076,26077,26078,26079,26080,26081,26082,26083,\n26084,26085,26086,26087,26088,26089,26090,26091,26092,26093,26094,26095,\n26096,26097,26098,26099,26100,26101,26102,26103,26104,26105,26106,26107,\n26108,26109,26110,26111,26112,26113,26114,26115,26116,26117,26118,26119,\n26120,26121,26122,26123,26124,26125,26126,26127,26128,26129,26130,26131,\n26132,26133,26134,26135,26136,26137,26138,26139,26140,26141,26142,26143,\n26144,26145,26146,26147,26148,26149,26150,26151,26152,26153,26154,26155,\n26156,26157,26158,26159,26160,26161,26162,26163,26164,26165,26166,26167,\n26168,26169,26170,26171,26172,26173,26174,26175,26176,26177,26178,26179,\n26180,26181,26182,26183,26184,26185,26186,26187,26188,26189,26190,26191,\n26192,26193,26194,26195,26196,26197,26198,26199,26200,26201,26202,26203,\n26204,26205,26206,26207,26208,26209,26210,26211,26212,26213,26214,26215,\n26216,26217,26218,26219,26220,26221,26222,26223,26224,26225,26226,26227,\n26228,26229,26230,26231,26232,26233,26234,26235,26236,26237,26238,26239,\n26240,26241,26242,26243,26244,26245,26246,26247,26248,26249,26250,26251,\n26252,26253,26254,26255,26256,26257,26258,26259,26260,26261,26262,26263,\n26264,26265,26266,26267,26268,26269,26270,26271,26272,26273,26274,26275,\n26276,26277,26278,26279,26280,26281,26282,26283,26284,26285,26286,26287,\n26288,26289,26290,26291,26292,26293,26294,26295,26296,26297,26298,26299,\n26300,26301,26302,26303,26304,26305,26306,26307,26308,26309,26310,26311,\n26312,26313,26314,26315,26316,26317,26318,26319,26320,26321,26322,26323,\n26324,26325,26326,26327,26328,26329,26330,26331,26332,26333,26334,26335,\n26336,26337,26338,26339,26340,26341,26342,26343,26344,26345,26346,26347,\n26348,26349,26350,26351,26352,26353,26354,26355,26356,26357,26358,26359,\n26360,26361,26362,26363,26364,26365,26366,26367,26368,26369,26370,26371,\n26372,26373,26374,26375,26376,26377,26378,26379,26380,26381,26382,26383,\n26384,26385,26386,26387,26388,26389,26390,26391,26392,26393,26394,26395,\n26396,26397,26398,26399,26400,26401,26402,26403,26404,26405,26406,26407,\n26408,26409,26410,26411,26412,26413,26414,26415,26416,26417,26418,26419,\n26420,26421,26422,26423,26424,26425,26426,26427,26428,26429,26430,26431,\n26432,26433,26434,26435,26436,26437,26438,26439,26440,26441,26442,26443,\n26444,26445,26446,26447,26448,26449,26450,26451,26452,26453,26454,26455,\n26456,26457,26458,26459,26460,26461,26462,26463,26464,26465,26466,26467,\n26468,26469,26470,26471,26472,26473,26474,26475,26476,26477,26478,26479,\n26480,26481,26482,26483,26484,26485,26486,26487,26488,26489,26490,26491,\n26492,26493,26494,26495,26496,26497,26498,26499,26500,26501,26502,26503,\n26504,26505,26506,26507,26508,26509,26510,26511,26512,26513,26514,26515,\n26516,26517,26518,26519,26520,26521,26522,26523,26524,26525,26526,26527,\n26528,26529,26530,26531,26532,26533,26534,26535,26536,26537,26538,26539,\n26540,26541,26542,26543,26544,26545,26546,26547,26548,26549,26550,26551,\n26552,26553,26554,26555,26556,26557,26558,26559,26560,26561,26562,26563,\n26564,26565,26566,26567,26568,26569,26570,26571,26572,26573,26574,26575,\n26576,26577,26578,26579,26580,26581,26582,26583,26584,26585,26586,26587,\n26588,26589,26590,26591,26592,26593,26594,26595,26596,26597,26598,26599,\n26600,26601,26602,26603,26604,26605,26606,26607,26608,26609,26610,26611,\n26612,26613,26614,26615,26616,26617,26618,26619,26620,26621,26622,26623,\n26624,26625,26626,26627,26628,26629,26630,26631,26632,26633,26634,26635,\n26636,26637,26638,26639,26640,26641,26642,26643,26644,26645,26646,26647,\n26648,26649,26650,26651,26652,26653,26654,26655,26656,26657,26658,26659,\n26660,26661,26662,26663,26664,26665,26666,26667,26668,26669,26670,26671,\n26672,26673,26674,26675,26676,26677,26678,26679,26680,26681,26682,26683,\n26684,26685,26686,26687,26688,26689,26690,26691,26692,26693,26694,26695,\n26696,26697,26698,26699,26700,26701,26702,26703,26704,26705,26706,26707,\n26708,26709,26710,26711,26712,26713,26714,26715,26716,26717,26718,26719,\n26720,26721,26722,26723,26724,26725,26726,26727,26728,26729,26730,26731,\n26732,26733,26734,26735,26736,26737,26738,26739,26740,26741,26742,26743,\n26744,26745,26746,26747,26748,26749,26750,26751,26752,26753,26754,26755,\n26756,26757,26758,26759,26760,26761,26762,26763,26764,26765,26766,26767,\n26768,26769,26770,26771,26772,26773,26774,26775,26776,26777,26778,26779,\n26780,26781,26782,26783,26784,26785,26786,26787,26788,26789,26790,26791,\n26792,26793,26794,26795,26796,26797,26798,26799,26800,26801,26802,26803,\n26804,26805,26806,26807,26808,26809,26810,26811,26812,26813,26814,26815,\n26816,26817,26818,26819,26820,26821,26822,26823,26824,26825,26826,26827,\n26828,26829,26830,26831,26832,26833,26834,26835,26836,26837,26838,26839,\n26840,26841,26842,26843,26844,26845,26846,26847,26848,26849,26850,26851,\n26852,26853,26854,26855,26856,26857,26858,26859,26860,26861,26862,26863,\n26864,26865,26866,26867,26868,26869,26870,26871,26872,26873,26874,26875,\n26876,26877,26878,26879,26880,26881,26882,26883,26884,26885,26886,26887,\n26888,26889,26890,26891,26892,26893,26894,26895,26896,26897,26898,26899,\n26900,26901,26902,26903,26904,26905,26906,26907,26908,26909,26910,26911,\n26912,26913,26914,26915,26916,26917,26918,26919,26920,26921,26922,26923,\n26924,26925,26926,26927,26928,26929,26930,26931,26932,26933,26934,26935,\n26936,26937,26938,26939,26940,26941,26942,26943,26944,26945,26946,26947,\n26948,26949,26950,26951,26952,26953,26954,26955,26956,26957,26958,26959,\n26960,26961,26962,26963,26964,26965,26966,26967,26968,26969,26970,26971,\n26972,26973,26974,26975,26976,26977,26978,26979,26980,26981,26982,26983,\n26984,26985,26986,26987,26988,26989,26990,26991,26992,26993,26994,26995,\n26996,26997,26998,26999,27000,27001,27002,27003,27004,27005,27006,27007,\n27008,27009,27010,27011,27012,27013,27014,27015,27016,27017,27018,27019,\n27020,27021,27022,27023,27024,27025,27026,27027,27028,27029,27030,27031,\n27032,27033,27034,27035,27036,27037,27038,27039,27040,27041,27042,27043,\n27044,27045,27046,27047,27048,27049,27050,27051,27052,27053,27054,27055,\n27056,27057,27058,27059,27060,27061,27062,27063,27064,27065,27066,27067,\n27068,27069,27070,27071,27072,27073,27074,27075,27076,27077,27078,27079,\n27080,27081,27082,27083,27084,27085,27086,27087,27088,27089,27090,27091,\n27092,27093,27094,27095,27096,27097,27098,27099,27100,27101,27102,27103,\n27104,27105,27106,27107,27108,27109,27110,27111,27112,27113,27114,27115,\n27116,27117,27118,27119,27120,27121,27122,27123,27124,27125,27126,27127,\n27128,27129,27130,27131,27132,27133,27134,27135,27136,27137,27138,27139,\n27140,27141,27142,27143,27144,27145,27146,27147,27148,27149,27150,27151,\n27152,27153,27154,27155,27156,27157,27158,27159,27160,27161,27162,27163,\n27164,27165,27166,27167,27168,27169,27170,27171,27172,27173,27174,27175,\n27176,27177,27178,27179,27180,27181,27182,27183,27184,27185,27186,27187,\n27188,27189,27190,27191,27192,27193,27194,27195,27196,27197,27198,27199,\n27200,27201,27202,27203,27204,27205,27206,27207,27208,27209,27210,27211,\n27212,27213,27214,27215,27216,27217,27218,27219,27220,27221,27222,27223,\n27224,27225,27226,27227,27228,27229,27230,27231,27232,27233,27234,27235,\n27236,27237,27238,27239,27240,27241,27242,27243,27244,27245,27246,27247,\n27248,27249,27250,27251,27252,27253,27254,27255,27256,27257,27258,27259,\n27260,27261,27262,27263,27264,27265,27266,27267,27268,27269,27270,27271,\n27272,27273,27274,27275,27276,27277,27278,27279,27280,27281,27282,27283,\n27284,27285,27286,27287,27288,27289,27290,27291,27292,27293,27294,27295,\n27296,27297,27298,27299,27300,27301,27302,27303,27304,27305,27306,27307,\n27308,27309,27310,27311,27312,27313,27314,27315,27316,27317,27318,27319,\n27320,27321,27322,27323,27324,27325,27326,27327,27328,27329,27330,27331,\n27332,27333,27334,27335,27336,27337,27338,27339,27340,27341,27342,27343,\n27344,27345,27346,27347,27348,27349,27350,27351,27352,27353,27354,27355,\n27356,27357,27358,27359,27360,27361,27362,27363,27364,27365,27366,27367,\n27368,27369,27370,27371,27372,27373,27374,27375,27376,27377,27378,27379,\n27380,27381,27382,27383,27384,27385,27386,27387,27388,27389,27390,27391,\n27392,27393,27394,27395,27396,27397,27398,27399,27400,27401,27402,27403,\n27404,27405,27406,27407,27408,27409,27410,27411,27412,27413,27414,27415,\n27416,27417,27418,27419,27420,27421,27422,27423,27424,27425,27426,27427,\n27428,27429,27430,27431,27432,27433,27434,27435,27436,27437,27438,27439,\n27440,27441,27442,27443,27444,27445,27446,27447,27448,27449,27450,27451,\n27452,27453,27454,27455,27456,27457,27458,27459,27460,27461,27462,27463,\n27464,27465,27466,27467,27468,27469,27470,27471,27472,27473,27474,27475,\n27476,27477,27478,27479,27480,27481,27482,27483,27484,27485,27486,27487,\n27488,27489,27490,27491,27492,27493,27494,27495,27496,27497,27498,27499,\n27500,27501,27502,27503,27504,27505,27506,27507,27508,27509,27510,27511,\n27512,27513,27514,27515,27516,27517,27518,27519,27520,27521,27522,27523,\n27524,27525,27526,27527,27528,27529,27530,27531,27532,27533,27534,27535,\n27536,27537,27538,27539,27540,27541,27542,27543,27544,27545,27546,27547,\n27548,27549,27550,27551,27552,27553,27554,27555,27556,27557,27558,27559,\n27560,27561,27562,27563,27564,27565,27566,27567,27568,27569,27570,27571,\n27572,27573,27574,27575,27576,27577,27578,27579,27580,27581,27582,27583,\n27584,27585,27586,27587,27588,27589,27590,27591,27592,27593,27594,27595,\n27596,27597,27598,27599,27600,27601,27602,27603,27604,27605,27606,27607,\n27608,27609,27610,27611,27612,27613,27614,27615,27616,27617,27618,27619,\n27620,27621,27622,27623,27624,27625,27626,27627,27628,27629,27630,27631,\n27632,27633,27634,27635,27636,27637,27638,27639,27640,27641,27642,27643,\n27644,27645,27646,27647,27648,27649,27650,27651,27652,27653,27654,27655,\n27656,27657,27658,27659,27660,27661,27662,27663,27664,27665,27666,27667,\n27668,27669,27670,27671,27672,27673,27674,27675,27676,27677,27678,27679,\n27680,27681,27682,27683,27684,27685,27686,27687,27688,27689,27690,27691,\n27692,27693,27694,27695,27696,27697,27698,27699,27700,27701,27702,27703,\n27704,27705,27706,27707,27708,27709,27710,27711,27712,27713,27714,27715,\n27716,27717,27718,27719,27720,27721,27722,27723,27724,27725,27726,27727,\n27728,27729,27730,27731,27732,27733,27734,27735,27736,27737,27738,27739,\n27740,27741,27742,27743,27744,27745,27746,27747,27748,27749,27750,27751,\n27752,27753,27754,27755,27756,27757,27758,27759,27760,27761,27762,27763,\n27764,27765,27766,27767,27768,27769,27770,27771,27772,27773,27774,27775,\n27776,27777,27778,27779,27780,27781,27782,27783,27784,27785,27786,27787,\n27788,27789,27790,27791,27792,27793,27794,27795,27796,27797,27798,27799,\n27800,27801,27802,27803,27804,27805,27806,27807,27808,27809,27810,27811,\n27812,27813,27814,27815,27816,27817,27818,27819,27820,27821,27822,27823,\n27824,27825,27826,27827,27828,27829,27830,27831,27832,27833,27834,27835,\n27836,27837,27838,27839,27840,27841,27842,27843,27844,27845,27846,27847,\n27848,27849,27850,27851,27852,27853,27854,27855,27856,27857,27858,27859,\n27860,27861,27862,27863,27864,27865,27866,27867,27868,27869,27870,27871,\n27872,27873,27874,27875,27876,27877,27878,27879,27880,27881,27882,27883,\n27884,27885,27886,27887,27888,27889,27890,27891,27892,27893,27894,27895,\n27896,27897,27898,27899,27900,27901,27902,27903,27904,27905,27906,27907,\n27908,27909,27910,27911,27912,27913,27914,27915,27916,27917,27918,27919,\n27920,27921,27922,27923,27924,27925,27926,27927,27928,27929,27930,27931,\n27932,27933,27934,27935,27936,27937,27938,27939,27940,27941,27942,27943,\n27944,27945,27946,27947,27948,27949,27950,27951,27952,27953,27954,27955,\n27956,27957,27958,27959,27960,27961,27962,27963,27964,27965,27966,27967,\n27968,27969,27970,27971,27972,27973,27974,27975,27976,27977,27978,27979,\n27980,27981,27982,27983,27984,27985,27986,27987,27988,27989,27990,27991,\n27992,27993,27994,27995,27996,27997,27998,27999,28000,28001,28002,28003,\n28004,28005,28006,28007,28008,28009,28010,28011,28012,28013,28014,28015,\n28016,28017,28018,28019,28020,28021,28022,28023,28024,28025,28026,28027,\n28028,28029,28030,28031,28032,28033,28034,28035,28036,28037,28038,28039,\n28040,28041,28042,28043,28044,28045,28046,28047,28048,28049,28050,28051,\n28052,28053,28054,28055,28056,28057,28058,28059,28060,28061,28062,28063,\n28064,28065,28066,28067,28068,28069,28070,28071,28072,28073,28074,28075,\n28076,28077,28078,28079,28080,28081,28082,28083,28084,28085,28086,28087,\n28088,28089,28090,28091,28092,28093,28094,28095,28096,28097,28098,28099,\n28100,28101,28102,28103,28104,28105,28106,28107,28108,28109,28110,28111,\n28112,28113,28114,28115,28116,28117,28118,28119,28120,28121,28122,28123,\n28124,28125,28126,28127,28128,28129,28130,28131,28132,28133,28134,28135,\n28136,28137,28138,28139,28140,28141,28142,28143,28144,28145,28146,28147,\n28148,28149,28150,28151,28152,28153,28154,28155,28156,28157,28158,28159,\n28160,28161,28162,28163,28164,28165,28166,28167,28168,28169,28170,28171,\n28172,28173,28174,28175,28176,28177,28178,28179,28180,28181,28182,28183,\n28184,28185,28186,28187,28188,28189,28190,28191,28192,28193,28194,28195,\n28196,28197,28198,28199,28200,28201,28202,28203,28204,28205,28206,28207,\n28208,28209,28210,28211,28212,28213,28214,28215,28216,28217,28218,28219,\n28220,28221,28222,28223,28224,28225,28226,28227,28228,28229,28230,28231,\n28232,28233,28234,28235,28236,28237,28238,28239,28240,28241,28242,28243,\n28244,28245,28246,28247,28248,28249,28250,28251,28252,28253,28254,28255,\n28256,28257,28258,28259,28260,28261,28262,28263,28264,28265,28266,28267,\n28268,28269,28270,28271,28272,28273,28274,28275,28276,28277,28278,28279,\n28280,28281,28282,28283,28284,28285,28286,28287,28288,28289,28290,28291,\n28292,28293,28294,28295,28296,28297,28298,28299,28300,28301,28302,28303,\n28304,28305,28306,28307,28308,28309,28310,28311,28312,28313,28314,28315,\n28316,28317,28318,28319,28320,28321,28322,28323,28324,28325,28326,28327,\n28328,28329,28330,28331,28332,28333,28334,28335,28336,28337,28338,28339,\n28340,28341,28342,28343,28344,28345,28346,28347,28348,28349,28350,28351,\n28352,28353,28354,28355,28356,28357,28358,28359,28360,28361,28362,28363,\n28364,28365,28366,28367,28368,28369,28370,28371,28372,28373,28374,28375,\n28376,28377,28378,28379,28380,28381,28382,28383,28384,28385,28386,28387,\n28388,28389,28390,28391,28392,28393,28394,28395,28396,28397,28398,28399,\n28400,28401,28402,28403,28404,28405,28406,28407,28408,28409,28410,28411,\n28412,28413,28414,28415,28416,28417,28418,28419,28420,28421,28422,28423,\n28424,28425,28426,28427,28428,28429,28430,28431,28432,28433,28434,28435,\n28436,28437,28438,28439,28440,28441,28442,28443,28444,28445,28446,28447,\n28448,28449,28450,28451,28452,28453,28454,28455,28456,28457,28458,28459,\n28460,28461,28462,28463,28464,28465,28466,28467,28468,28469,28470,28471,\n28472,28473,28474,28475,28476,28477,28478,28479,28480,28481,28482,28483,\n28484,28485,28486,28487,28488,28489,28490,28491,28492,28493,28494,28495,\n28496,28497,28498,28499,28500,28501,28502,28503,28504,28505,28506,28507,\n28508,28509,28510,28511,28512,28513,28514,28515,28516,28517,28518,28519,\n28520,28521,28522,28523,28524,28525,28526,28527,28528,28529,28530,28531,\n28532,28533,28534,28535,28536,28537,28538,28539,28540,28541,28542,28543,\n28544,28545,28546,28547,28548,28549,28550,28551,28552,28553,28554,28555,\n28556,28557,28558,28559,28560,28561,28562,28563,28564,28565,28566,28567,\n28568,28569,28570,28571,28572,28573,28574,28575,28576,28577,28578,28579,\n28580,28581,28582,28583,28584,28585,28586,28587,28588,28589,28590,28591,\n28592,28593,28594,28595,28596,28597,28598,28599,28600,28601,28602,28603,\n28604,28605,28606,28607,28608,28609,28610,28611,28612,28613,28614,28615,\n28616,28617,28618,28619,28620,28621,28622,28623,28624,28625,28626,28627,\n28628,28629,28630,28631,28632,28633,28634,28635,28636,28637,28638,28639,\n28640,28641,28642,28643,28644,28645,28646,28647,28648,28649,28650,28651,\n28652,28653,28654,28655,28656,28657,28658,28659,28660,28661,28662,28663,\n28664,28665,28666,28667,28668,28669,28670,28671,28672,28673,28674,28675,\n28676,28677,28678,28679,28680,28681,28682,28683,28684,28685,28686,28687,\n28688,28689,28690,28691,28692,28693,28694,28695,28696,28697,28698,28699,\n28700,28701,28702,28703,28704,28705,28706,28707,28708,28709,28710,28711,\n28712,28713,28714,28715,28716,28717,28718,28719,28720,28721,28722,28723,\n28724,28725,28726,28727,28728,28729,28730,28731,28732,28733,28734,28735,\n28736,28737,28738,28739,28740,28741,28742,28743,28744,28745,28746,28747,\n28748,28749,28750,28751,28752,28753,28754,28755,28756,28757,28758,28759,\n28760,28761,28762,28763,28764,28765,28766,28767,28768,28769,28770,28771,\n28772,28773,28774,28775,28776,28777,28778,28779,28780,28781,28782,28783,\n28784,28785,28786,28787,28788,28789,28790,28791,28792,28793,28794,28795,\n28796,28797,28798,28799,28800,28801,28802,28803,28804,28805,28806,28807,\n28808,28809,28810,28811,28812,28813,28814,28815,28816,28817,28818,28819,\n28820,28821,28822,28823,28824,28825,28826,28827,28828,28829,28830,28831,\n28832,28833,28834,28835,28836,28837,28838,28839,28840,28841,28842,28843,\n28844,28845,28846,28847,28848,28849,28850,28851,28852,28853,28854,28855,\n28856,28857,28858,28859,28860,28861,28862,28863,28864,28865,28866,28867,\n28868,28869,28870,28871,28872,28873,28874,28875,28876,28877,28878,28879,\n28880,28881,28882,28883,28884,28885,28886,28887,28888,28889,28890,28891,\n28892,28893,28894,28895,28896,28897,28898,28899,28900,28901,28902,28903,\n28904,28905,28906,28907,28908,28909,28910,28911,28912,28913,28914,28915,\n28916,28917,28918,28919,28920,28921,28922,28923,28924,28925,28926,28927,\n28928,28929,28930,28931,28932,28933,28934,28935,28936,28937,28938,28939,\n28940,28941,28942,28943,28944,28945,28946,28947,28948,28949,28950,28951,\n28952,28953,28954,28955,28956,28957,28958,28959,28960,28961,28962,28963,\n28964,28965,28966,28967,28968,28969,28970,28971,28972,28973,28974,28975,\n28976,28977,28978,28979,28980,28981,28982,28983,28984,28985,28986,28987,\n28988,28989,28990,28991,28992,28993,28994,28995,28996,28997,28998,28999,\n29000,29001,29002,29003,29004,29005,29006,29007,29008,29009,29010,29011,\n29012,29013,29014,29015,29016,29017,29018,29019,29020,29021,29022,29023,\n29024,29025,29026,29027,29028,29029,29030,29031,29032,29033,29034,29035,\n29036,29037,29038,29039,29040,29041,29042,29043,29044,29045,29046,29047,\n29048,29049,29050,29051,29052,29053,29054,29055,29056,29057,29058,29059,\n29060,29061,29062,29063,29064,29065,29066,29067,29068,29069,29070,29071,\n29072,29073,29074,29075,29076,29077,29078,29079,29080,29081,29082,29083,\n29084,29085,29086,29087,29088,29089,29090,29091,29092,29093,29094,29095,\n29096,29097,29098,29099,29100,29101,29102,29103,29104,29105,29106,29107,\n29108,29109,29110,29111,29112,29113,29114,29115,29116,29117,29118,29119,\n29120,29121,29122,29123,29124,29125,29126,29127,29128,29129,29130,29131,\n29132,29133,29134,29135,29136,29137,29138,29139,29140,29141,29142,29143,\n29144,29145,29146,29147,29148,29149,29150,29151,29152,29153,29154,29155,\n29156,29157,29158,29159,29160,29161,29162,29163,29164,29165,29166,29167,\n29168,29169,29170,29171,29172,29173,29174,29175,29176,29177,29178,29179,\n29180,29181,29182,29183,29184,29185,29186,29187,29188,29189,29190,29191,\n29192,29193,29194,29195,29196,29197,29198,29199,29200,29201,29202,29203,\n29204,29205,29206,29207,29208,29209,29210,29211,29212,29213,29214,29215,\n29216,29217,29218,29219,29220,29221,29222,29223,29224,29225,29226,29227,\n29228,29229,29230,29231,29232,29233,29234,29235,29236,29237,29238,29239,\n29240,29241,29242,29243,29244,29245,29246,29247,29248,29249,29250,29251,\n29252,29253,29254,29255,29256,29257,29258,29259,29260,29261,29262,29263,\n29264,29265,29266,29267,29268,29269,29270,29271,29272,29273,29274,29275,\n29276,29277,29278,29279,29280,29281,29282,29283,29284,29285,29286,29287,\n29288,29289,29290,29291,29292,29293,29294,29295,29296,29297,29298,29299,\n29300,29301,29302,29303,29304,29305,29306,29307,29308,29309,29310,29311,\n29312,29313,29314,29315,29316,29317,29318,29319,29320,29321,29322,29323,\n29324,29325,29326,29327,29328,29329,29330,29331,29332,29333,29334,29335,\n29336,29337,29338,29339,29340,29341,29342,29343,29344,29345,29346,29347,\n29348,29349,29350,29351,29352,29353,29354,29355,29356,29357,29358,29359,\n29360,29361,29362,29363,29364,29365,29366,29367,29368,29369,29370,29371,\n29372,29373,29374,29375,29376,29377,29378,29379,29380,29381,29382,29383,\n29384,29385,29386,29387,29388,29389,29390,29391,29392,29393,29394,29395,\n29396,29397,29398,29399,29400,29401,29402,29403,29404,29405,29406,29407,\n29408,29409,29410,29411,29412,29413,29414,29415,29416,29417,29418,29419,\n29420,29421,29422,29423,29424,29425,29426,29427,29428,29429,29430,29431,\n29432,29433,29434,29435,29436,29437,29438,29439,29440,29441,29442,29443,\n29444,29445,29446,29447,29448,29449,29450,29451,29452,29453,29454,29455,\n29456,29457,29458,29459,29460,29461,29462,29463,29464,29465,29466,29467,\n29468,29469,29470,29471,29472,29473,29474,29475,29476,29477,29478,29479,\n29480,29481,29482,29483,29484,29485,29486,29487,29488,29489,29490,29491,\n29492,29493,29494,29495,29496,29497,29498,29499,29500,29501,29502,29503,\n29504,29505,29506,29507,29508,29509,29510,29511,29512,29513,29514,29515,\n29516,29517,29518,29519,29520,29521,29522,29523,29524,29525,29526,29527,\n29528,29529,29530,29531,29532,29533,29534,29535,29536,29537,29538,29539,\n29540,29541,29542,29543,29544,29545,29546,29547,29548,29549,29550,29551,\n29552,29553,29554,29555,29556,29557,29558,29559,29560,29561,29562,29563,\n29564,29565,29566,29567,29568,29569,29570,29571,29572,29573,29574,29575,\n29576,29577,29578,29579,29580,29581,29582,29583,29584,29585,29586,29587,\n29588,29589,29590,29591,29592,29593,29594,29595,29596,29597,29598,29599,\n29600,29601,29602,29603,29604,29605,29606,29607,29608,29609,29610,29611,\n29612,29613,29614,29615,29616,29617,29618,29619,29620,29621,29622,29623,\n29624,29625,29626,29627,29628,29629,29630,29631,29632,29633,29634,29635,\n29636,29637,29638,29639,29640,29641,29642,29643,29644,29645,29646,29647,\n29648,29649,29650,29651,29652,29653,29654,29655,29656,29657,29658,29659,\n29660,29661,29662,29663,29664,29665,29666,29667,29668,29669,29670,29671,\n29672,29673,29674,29675,29676,29677,29678,29679,29680,29681,29682,29683,\n29684,29685,29686,29687,29688,29689,29690,29691,29692,29693,29694,29695,\n29696,29697,29698,29699,29700,29701,29702,29703,29704,29705,29706,29707,\n29708,29709,29710,29711,29712,29713,29714,29715,29716,29717,29718,29719,\n29720,29721,29722,29723,29724,29725,29726,29727,29728,29729,29730,29731,\n29732,29733,29734,29735,29736,29737,29738,29739,29740,29741,29742,29743,\n29744,29745,29746,29747,29748,29749,29750,29751,29752,29753,29754,29755,\n29756,29757,29758,29759,29760,29761,29762,29763,29764,29765,29766,29767,\n29768,29769,29770,29771,29772,29773,29774,29775,29776,29777,29778,29779,\n29780,29781,29782,29783,29784,29785,29786,29787,29788,29789,29790,29791,\n29792,29793,29794,29795,29796,29797,29798,29799,29800,29801,29802,29803,\n29804,29805,29806,29807,29808,29809,29810,29811,29812,29813,29814,29815,\n29816,29817,29818,29819,29820,29821,29822,29823,29824,29825,29826,29827,\n29828,29829,29830,29831,29832,29833,29834,29835,29836,29837,29838,29839,\n29840,29841,29842,29843,29844,29845,29846,29847,29848,29849,29850,29851,\n29852,29853,29854,29855,29856,29857,29858,29859,29860,29861,29862,29863,\n29864,29865,29866,29867,29868,29869,29870,29871,29872,29873,29874,29875,\n29876,29877,29878,29879,29880,29881,29882,29883,29884,29885,29886,29887,\n29888,29889,29890,29891,29892,29893,29894,29895,29896,29897,29898,29899,\n29900,29901,29902,29903,29904,29905,29906,29907,29908,29909,29910,29911,\n29912,29913,29914,29915,29916,29917,29918,29919,29920,29921,29922,29923,\n29924,29925,29926,29927,29928,29929,29930,29931,29932,29933,29934,29935,\n29936,29937,29938,29939,29940,29941,29942,29943,29944,29945,29946,29947,\n29948,29949,29950,29951,29952,29953,29954,29955,29956,29957,29958,29959,\n29960,29961,29962,29963,29964,29965,29966,29967,29968,29969,29970,29971,\n29972,29973,29974,29975,29976,29977,29978,29979,29980,29981,29982,29983,\n29984,29985,29986,29987,29988,29989,29990,29991,29992,29993,29994,29995,\n29996,29997,29998,29999,30000,30001,30002,30003,30004,30005,30006,30007,\n30008,30009,30010,30011,30012,30013,30014,30015,30016,30017,30018,30019,\n30020,30021,30022,30023,30024,30025,30026,30027,30028,30029,30030,30031,\n30032,30033,30034,30035,30036,30037,30038,30039,30040,30041,30042,30043,\n30044,30045,30046,30047,30048,30049,30050,30051,30052,30053,30054,30055,\n30056,30057,30058,30059,30060,30061,30062,30063,30064,30065,30066,30067,\n30068,30069,30070,30071,30072,30073,30074,30075,30076,30077,30078,30079,\n30080,30081,30082,30083,30084,30085,30086,30087,30088,30089,30090,30091,\n30092,30093,30094,30095,30096,30097,30098,30099,30100,30101,30102,30103,\n30104,30105,30106,30107,30108,30109,30110,30111,30112,30113,30114,30115,\n30116,30117,30118,30119,30120,30121,30122,30123,30124,30125,30126,30127,\n30128,30129,30130,30131,30132,30133,30134,30135,30136,30137,30138,30139,\n30140,30141,30142,30143,30144,30145,30146,30147,30148,30149,30150,30151,\n30152,30153,30154,30155,30156,30157,30158,30159,30160,30161,30162,30163,\n30164,30165,30166,30167,30168,30169,30170,30171,30172,30173,30174,30175,\n30176,30177,30178,30179,30180,30181,30182,30183,30184,30185,30186,30187,\n30188,30189,30190,30191,30192,30193,30194,30195,30196,30197,30198,30199,\n30200,30201,30202,30203,30204,30205,30206,30207,30208,30209,30210,30211,\n30212,30213,30214,30215,30216,30217,30218,30219,30220,30221,30222,30223,\n30224,30225,30226,30227,30228,30229,30230,30231,30232,30233,30234,30235,\n30236,30237,30238,30239,30240,30241,30242,30243,30244,30245,30246,30247,\n30248,30249,30250,30251,30252,30253,30254,30255,30256,30257,30258,30259,\n30260,30261,30262,30263,30264,30265,30266,30267,30268,30269,30270,30271,\n30272,30273,30274,30275,30276,30277,30278,30279,30280,30281,30282,30283,\n30284,30285,30286,30287,30288,30289,30290,30291,30292,30293,30294,30295,\n30296,30297,30298,30299,30300,30301,30302,30303,30304,30305,30306,30307,\n30308,30309,30310,30311,30312,30313,30314,30315,30316,30317,30318,30319,\n30320,30321,30322,30323,30324,30325,30326,30327,30328,30329,30330,30331,\n30332,30333,30334,30335,30336,30337,30338,30339,30340,30341,30342,30343,\n30344,30345,30346,30347,30348,30349,30350,30351,30352,30353,30354,30355,\n30356,30357,30358,30359,30360,30361,30362,30363,30364,30365,30366,30367,\n30368,30369,30370,30371,30372,30373,30374,30375,30376,30377,30378,30379,\n30380,30381,30382,30383,30384,30385,30386,30387,30388,30389,30390,30391,\n30392,30393,30394,30395,30396,30397,30398,30399,30400,30401,30402,30403,\n30404,30405,30406,30407,30408,30409,30410,30411,30412,30413,30414,30415,\n30416,30417,30418,30419,30420,30421,30422,30423,30424,30425,30426,30427,\n30428,30429,30430,30431,30432,30433,30434,30435,30436,30437,30438,30439,\n30440,30441,30442,30443,30444,30445,30446,30447,30448,30449,30450,30451,\n30452,30453,30454,30455,30456,30457,30458,30459,30460,30461,30462,30463,\n30464,30465,30466,30467,30468,30469,30470,30471,30472,30473,30474,30475,\n30476,30477,30478,30479,30480,30481,30482,30483,30484,30485,30486,30487,\n30488,30489,30490,30491,30492,30493,30494,30495,30496,30497,30498,30499,\n30500,30501,30502,30503,30504,30505,30506,30507,30508,30509,30510,30511,\n30512,30513,30514,30515,30516,30517,30518,30519,30520,30521,30522,30523,\n30524,30525,30526,30527,30528,30529,30530,30531,30532,30533,30534,30535,\n30536,30537,30538,30539,30540,30541,30542,30543,30544,30545,30546,30547,\n30548,30549,30550,30551,30552,30553,30554,30555,30556,30557,30558,30559,\n30560,30561,30562,30563,30564,30565,30566,30567,30568,30569,30570,30571,\n30572,30573,30574,30575,30576,30577,30578,30579,30580,30581,30582,30583,\n30584,30585,30586,30587,30588,30589,30590,30591,30592,30593,30594,30595,\n30596,30597,30598,30599,30600,30601,30602,30603,30604,30605,30606,30607,\n30608,30609,30610,30611,30612,30613,30614,30615,30616,30617,30618,30619,\n30620,30621,30622,30623,30624,30625,30626,30627,30628,30629,30630,30631,\n30632,30633,30634,30635,30636,30637,30638,30639,30640,30641,30642,30643,\n30644,30645,30646,30647,30648,30649,30650,30651,30652,30653,30654,30655,\n30656,30657,30658,30659,30660,30661,30662,30663,30664,30665,30666,30667,\n30668,30669,30670,30671,30672,30673,30674,30675,30676,30677,30678,30679,\n30680,30681,30682,30683,30684,30685,30686,30687,30688,30689,30690,30691,\n30692,30693,30694,30695,30696,30697,30698,30699,30700,30701,30702,30703,\n30704,30705,30706,30707,30708,30709,30710,30711,30712,30713,30714,30715,\n30716,30717,30718,30719,30720,30721,30722,30723,30724,30725,30726,30727,\n30728,30729,30730,30731,30732,30733,30734,30735,30736,30737,30738,30739,\n30740,30741,30742,30743,30744,30745,30746,30747,30748,30749,30750,30751,\n30752,30753,30754,30755,30756,30757,30758,30759,30760,30761,30762,30763,\n30764,30765,30766,30767,30768,30769,30770,30771,30772,30773,30774,30775,\n30776,30777,30778,30779,30780,30781,30782,30783,30784,30785,30786,30787,\n30788,30789,30790,30791,30792,30793,30794,30795,30796,30797,30798,30799,\n30800,30801,30802,30803,30804,30805,30806,30807,30808,30809,30810,30811,\n30812,30813,30814,30815,30816,30817,30818,30819,30820,30821,30822,30823,\n30824,30825,30826,30827,30828,30829,30830,30831,30832,30833,30834,30835,\n30836,30837,30838,30839,30840,30841,30842,30843,30844,30845,30846,30847,\n30848,30849,30850,30851,30852,30853,30854,30855,30856,30857,30858,30859,\n30860,30861,30862,30863,30864,30865,30866,30867,30868,30869,30870,30871,\n30872,30873,30874,30875,30876,30877,30878,30879,30880,30881,30882,30883,\n30884,30885,30886,30887,30888,30889,30890,30891,30892,30893,30894,30895,\n30896,30897,30898,30899,30900,30901,30902,30903,30904,30905,30906,30907,\n30908,30909,30910,30911,30912,30913,30914,30915,30916,30917,30918,30919,\n30920,30921,30922,30923,30924,30925,30926,30927,30928,30929,30930,30931,\n30932,30933,30934,30935,30936,30937,30938,30939,30940,30941,30942,30943,\n30944,30945,30946,30947,30948,30949,30950,30951,30952,30953,30954,30955,\n30956,30957,30958,30959,30960,30961,30962,30963,30964,30965,30966,30967,\n30968,30969,30970,30971,30972,30973,30974,30975,30976,30977,30978,30979,\n30980,30981,30982,30983,30984,30985,30986,30987,30988,30989,30990,30991,\n30992,30993,30994,30995,30996,30997,30998,30999,31000,31001,31002,31003,\n31004,31005,31006,31007,31008,31009,31010,31011,31012,31013,31014,31015,\n31016,31017,31018,31019,31020,31021,31022,31023,31024,31025,31026,31027,\n31028,31029,31030,31031,31032,31033,31034,31035,31036,31037,31038,31039,\n31040,31041,31042,31043,31044,31045,31046,31047,31048,31049,31050,31051,\n31052,31053,31054,31055,31056,31057,31058,31059,31060,31061,31062,31063,\n31064,31065,31066,31067,31068,31069,31070,31071,31072,31073,31074,31075,\n31076,31077,31078,31079,31080,31081,31082,31083,31084,31085,31086,31087,\n31088,31089,31090,31091,31092,31093,31094,31095,31096,31097,31098,31099,\n31100,31101,31102,31103,31104,31105,31106,31107,31108,31109,31110,31111,\n31112,31113,31114,31115,31116,31117,31118,31119,31120,31121,31122,31123,\n31124,31125,31126,31127,31128,31129,31130,31131,31132,31133,31134,31135,\n31136,31137,31138,31139,31140,31141,31142,31143,31144,31145,31146,31147,\n31148,31149,31150,31151,31152,31153,31154,31155,31156,31157,31158,31159,\n31160,31161,31162,31163,31164,31165,31166,31167,31168,31169,31170,31171,\n31172,31173,31174,31175,31176,31177,31178,31179,31180,31181,31182,31183,\n31184,31185,31186,31187,31188,31189,31190,31191,31192,31193,31194,31195,\n31196,31197,31198,31199,31200,31201,31202,31203,31204,31205,31206,31207,\n31208,31209,31210,31211,31212,31213,31214,31215,31216,31217,31218,31219,\n31220,31221,31222,31223,31224,31225,31226,31227,31228,31229,31230,31231,\n31232,31233,31234,31235,31236,31237,31238,31239,31240,31241,31242,31243,\n31244,31245,31246,31247,31248,31249,31250,31251,31252,31253,31254,31255,\n31256,31257,31258,31259,31260,31261,31262,31263,31264,31265,31266,31267,\n31268,31269,31270,31271,31272,31273,31274,31275,31276,31277,31278,31279,\n31280,31281,31282,31283,31284,31285,31286,31287,31288,31289,31290,31291,\n31292,31293,31294,31295,31296,31297,31298,31299,31300,31301,31302,31303,\n31304,31305,31306,31307,31308,31309,31310,31311,31312,31313,31314,31315,\n31316,31317,31318,31319,31320,31321,31322,31323,31324,31325,31326,31327,\n31328,31329,31330,31331,31332,31333,31334,31335,31336,31337,31338,31339,\n31340,31341,31342,31343,31344,31345,31346,31347,31348,31349,31350,31351,\n31352,31353,31354,31355,31356,31357,31358,31359,31360,31361,31362,31363,\n31364,31365,31366,31367,31368,31369,31370,31371,31372,31373,31374,31375,\n31376,31377,31378,31379,31380,31381,31382,31383,31384,31385,31386,31387,\n31388,31389,31390,31391,31392,31393,31394,31395,31396,31397,31398,31399,\n31400,31401,31402,31403,31404,31405,31406,31407,31408,31409,31410,31411,\n31412,31413,31414,31415,31416,31417,31418,31419,31420,31421,31422,31423,\n31424,31425,31426,31427,31428,31429,31430,31431,31432,31433,31434,31435,\n31436,31437,31438,31439,31440,31441,31442,31443,31444,31445,31446,31447,\n31448,31449,31450,31451,31452,31453,31454,31455,31456,31457,31458,31459,\n31460,31461,31462,31463,31464,31465,31466,31467,31468,31469,31470,31471,\n31472,31473,31474,31475,31476,31477,31478,31479,31480,31481,31482,31483,\n31484,31485,31486,31487,31488,31489,31490,31491,31492,31493,31494,31495,\n31496,31497,31498,31499,31500,31501,31502,31503,31504,31505,31506,31507,\n31508,31509,31510,31511,31512,31513,31514,31515,31516,31517,31518,31519,\n31520,31521,31522,31523,31524,31525,31526,31527,31528,31529,31530,31531,\n31532,31533,31534,31535,31536,31537,31538,31539,31540,31541,31542,31543,\n31544,31545,31546,31547,31548,31549,31550,31551,31552,31553,31554,31555,\n31556,31557,31558,31559,31560,31561,31562,31563,31564,31565,31566,31567,\n31568,31569,31570,31571,31572,31573,31574,31575,31576,31577,31578,31579,\n31580,31581,31582,31583,31584,31585,31586,31587,31588,31589,31590,31591,\n31592,31593,31594,31595,31596,31597,31598,31599,31600,31601,31602,31603,\n31604,31605,31606,31607,31608,31609,31610,31611,31612,31613,31614,31615,\n31616,31617,31618,31619,31620,31621,31622,31623,31624,31625,31626,31627,\n31628,31629,31630,31631,31632,31633,31634,31635,31636,31637,31638,31639,\n31640,31641,31642,31643,31644,31645,31646,31647,31648,31649,31650,31651,\n31652,31653,31654,31655,31656,31657,31658,31659,31660,31661,31662,31663,\n31664,31665,31666,31667,31668,31669,31670,31671,31672,31673,31674,31675,\n31676,31677,31678,31679,31680,31681,31682,31683,31684,31685,31686,31687,\n31688,31689,31690,31691,31692,31693,31694,31695,31696,31697,31698,31699,\n31700,31701,31702,31703,31704,31705,31706,31707,31708,31709,31710,31711,\n31712,31713,31714,31715,31716,31717,31718,31719,31720,31721,31722,31723,\n31724,31725,31726,31727,31728,31729,31730,31731,31732,31733,31734,31735,\n31736,31737,31738,31739,31740,31741,31742,31743,31744,31745,31746,31747,\n31748,31749,31750,31751,31752,31753,31754,31755,31756,31757,31758,31759,\n31760,31761,31762,31763,31764,31765,31766,31767,31768,31769,31770,31771,\n31772,31773,31774,31775,31776,31777,31778,31779,31780,31781,31782,31783,\n31784,31785,31786,31787,31788,31789,31790,31791,31792,31793,31794,31795,\n31796,31797,31798,31799,31800,31801,31802,31803,31804,31805,31806,31807,\n31808,31809,31810,31811,31812,31813,31814,31815,31816,31817,31818,31819,\n31820,31821,31822,31823,31824,31825,31826,31827,31828,31829,31830,31831,\n31832,31833,31834,31835,31836,31837,31838,31839,31840,31841,31842,31843,\n31844,31845,31846,31847,31848,31849,31850,31851,31852,31853,31854,31855,\n31856,31857,31858,31859,31860,31861,31862,31863,31864,31865,31866,31867,\n31868,31869,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879,\n31880,31881,31882,31883,31884,31885,31886,31887,31888,31889,31890,31891,\n31892,31893,31894,31895,31896,31897,31898,31899,31900,31901,31902,31903,\n31904,31905,31906,31907,31908,31909,31910,31911,31912,31913,31914,31915,\n31916,31917,31918,31919,31920,31921,31922,31923,31924,31925,31926,31927,\n31928,31929,31930,31931,31932,31933,31934,31935,31936,31937,31938,31939,\n31940,31941,31942,31943,31944,31945,31946,31947,31948,31949,31950,31951,\n31952,31953,31954,31955,31956,31957,31958,31959,31960,31961,31962,31963,\n31964,31965,31966,31967,31968,31969,31970,31971,31972,31973,31974,31975,\n31976,31977,31978,31979,31980,31981,31982,31983,31984,31985,31986,31987,\n31988,31989,31990,31991,31992,31993,31994,31995,31996,31997,31998,31999,\n32000,32001,32002,32003,32004,32005,32006,32007,32008,32009,32010,32011,\n32012,32013,32014,32015,32016,32017,32018,32019,32020,32021,32022,32023,\n32024,32025,32026,32027,32028,32029,32030,32031,32032,32033,32034,32035,\n32036,32037,32038,32039,32040,32041,32042,32043,32044,32045,32046,32047,\n32048,32049,32050,32051,32052,32053,32054,32055,32056,32057,32058,32059,\n32060,32061,32062,32063,32064,32065,32066,32067,32068,32069,32070,32071,\n32072,32073,32074,32075,32076,32077,32078,32079,32080,32081,32082,32083,\n32084,32085,32086,32087,32088,32089,32090,32091,32092,32093,32094,32095,\n32096,32097,32098,32099,32100,32101,32102,32103,32104,32105,32106,32107,\n32108,32109,32110,32111,32112,32113,32114,32115,32116,32117,32118,32119,\n32120,32121,32122,32123,32124,32125,32126,32127,32128,32129,32130,32131,\n32132,32133,32134,32135,32136,32137,32138,32139,32140,32141,32142,32143,\n32144,32145,32146,32147,32148,32149,32150,32151,32152,32153,32154,32155,\n32156,32157,32158,32159,32160,32161,32162,32163,32164,32165,32166,32167,\n32168,32169,32170,32171,32172,32173,32174,32175,32176,32177,32178,32179,\n32180,32181,32182,32183,32184,32185,32186,32187,32188,32189,32190,32191,\n32192,32193,32194,32195,32196,32197,32198,32199,32200,32201,32202,32203,\n32204,32205,32206,32207,32208,32209,32210,32211,32212,32213,32214,32215,\n32216,32217,32218,32219,32220,32221,32222,32223,32224,32225,32226,32227,\n32228,32229,32230,32231,32232,32233,32234,32235,32236,32237,32238,32239,\n32240,32241,32242,32243,32244,32245,32246,32247,32248,32249,32250,32251,\n32252,32253,32254,32255,32256,32257,32258,32259,32260,32261,32262,32263,\n32264,32265,32266,32267,32268,32269,32270,32271,32272,32273,32274,32275,\n32276,32277,32278,32279,32280,32281,32282,32283,32284,32285,32286,32287,\n32288,32289,32290,32291,32292,32293,32294,32295,32296,32297,32298,32299,\n32300,32301,32302,32303,32304,32305,32306,32307,32308,32309,32310,32311,\n32312,32313,32314,32315,32316,32317,32318,32319,32320,32321,32322,32323,\n32324,32325,32326,32327,32328,32329,32330,32331,32332,32333,32334,32335,\n32336,32337,32338,32339,32340,32341,32342,32343,32344,32345,32346,32347,\n32348,32349,32350,32351,32352,32353,32354,32355,32356,32357,32358,32359,\n32360,32361,32362,32363,32364,32365,32366,32367,32368,32369,32370,32371,\n32372,32373,32374,32375,32376,32377,32378,32379,32380,32381,32382,32383,\n32384,32385,32386,32387,32388,32389,32390,32391,32392,32393,32394,32395,\n32396,32397,32398,32399,32400,32401,32402,32403,32404,32405,32406,32407,\n32408,32409,32410,32411,32412,32413,32414,32415,32416,32417,32418,32419,\n32420,32421,32422,32423,32424,32425,32426,32427,32428,32429,32430,32431,\n32432,32433,32434,32435,32436,32437,32438,32439,32440,32441,32442,32443,\n32444,32445,32446,32447,32448,32449,32450,32451,32452,32453,32454,32455,\n32456,32457,32458,32459,32460,32461,32462,32463,32464,32465,32466,32467,\n32468,32469,32470,32471,32472,32473,32474,32475,32476,32477,32478,32479,\n32480,32481,32482,32483,32484,32485,32486,32487,32488,32489,32490,32491,\n32492,32493,32494,32495,32496,32497,32498,32499,32500,32501,32502,32503,\n32504,32505,32506,32507,32508,32509,32510,32511,32512,32513,32514,32515,\n32516,32517,32518,32519,32520,32521,32522,32523,32524,32525,32526,32527,\n32528,32529,32530,32531,32532,32533,32534,32535,32536,32537,32538,32539,\n32540,32541,32542,32543,32544,32545,32546,32547,32548,32549,32550,32551,\n32552,32553,32554,32555,32556,32557,32558,32559,32560,32561,32562,32563,\n32564,32565,32566,32567,32568,32569,32570,32571,32572,32573,32574,32575,\n32576,32577,32578,32579,32580,32581,32582,32583,32584,32585,32586,32587,\n32588,32589,32590,32591,32592,32593,32594,32595,32596,32597,32598,32599,\n32600,32601,32602,32603,32604,32605,32606,32607,32608,32609,32610,32611,\n32612,32613,32614,32615,32616,32617,32618,32619,32620,32621,32622,32623,\n32624,32625,32626,32627,32628,32629,32630,32631,32632,32633,32634,32635,\n32636,32637,32638,32639,32640,32641,32642,32643,32644,32645,32646,32647,\n32648,32649,32650,32651,32652,32653,32654,32655,32656,32657,32658,32659,\n32660,32661,32662,32663,32664,32665,32666,32667,32668,32669,32670,32671,\n32672,32673,32674,32675,32676,32677,32678,32679,32680,32681,32682,32683,\n32684,32685,32686,32687,32688,32689,32690,32691,32692,32693,32694,32695,\n32696,32697,32698,32699,32700,32701,32702,32703,32704,32705,32706,32707,\n32708,32709,32710,32711,32712,32713,32714,32715,32716,32717,32718,32719,\n32720,32721,32722,32723,32724,32725,32726,32727,32728,32729,32730,32731,\n32732,32733,32734,32735,32736,32737,32738,32739,32740,32741,32742,32743,\n32744,32745,32746,32747,32748,32749,32750,32751,32752,32753,32754,32755,\n32756,32757,32758,32759,32760,32761,32762,32763,32764,32765,32766,32767,\n32768L,32769L,32770L,32771L,32772L,32773L,32774L,32775L,32776L,32777L,\n32778L,32779L,32780L,32781L,32782L,32783L,32784L,32785L,32786L,32787L,\n32788L,32789L,32790L,32791L,32792L,32793L,32794L,32795L,32796L,32797L,\n32798L,32799L,32800L,32801L,32802L,32803L,32804L,32805L,32806L,32807L,\n32808L,32809L,32810L,32811L,32812L,32813L,32814L,32815L,32816L,32817L,\n32818L,32819L,32820L,32821L,32822L,32823L,32824L,32825L,32826L,32827L,\n32828L,32829L,32830L,32831L,32832L,32833L,32834L,32835L,32836L,32837L,\n32838L,32839L,32840L,32841L,32842L,32843L,32844L,32845L,32846L,32847L,\n32848L,32849L,32850L,32851L,32852L,32853L,32854L,32855L,32856L,32857L,\n32858L,32859L,32860L,32861L,32862L,32863L,32864L,32865L,32866L,32867L,\n32868L,32869L,32870L,32871L,32872L,32873L,32874L,32875L,32876L,32877L,\n32878L,32879L,32880L,32881L,32882L,32883L,32884L,32885L,32886L,32887L,\n32888L,32889L,32890L,32891L,32892L,32893L,32894L,32895L,32896L,32897L,\n32898L,32899L,32900L,32901L,32902L,32903L,32904L,32905L,32906L,32907L,\n32908L,32909L,32910L,32911L,32912L,32913L,32914L,32915L,32916L,32917L,\n32918L,32919L,32920L,32921L,32922L,32923L,32924L,32925L,32926L,32927L,\n32928L,32929L,32930L,32931L,32932L,32933L,32934L,32935L,32936L,32937L,\n32938L,32939L,32940L,32941L,32942L,32943L,32944L,32945L,32946L,32947L,\n32948L,32949L,32950L,32951L,32952L,32953L,32954L,32955L,32956L,32957L,\n32958L,32959L,32960L,32961L,32962L,32963L,32964L,32965L,32966L,32967L,\n32968L,32969L,32970L,32971L,32972L,32973L,32974L,32975L,32976L,32977L,\n32978L,32979L,32980L,32981L,32982L,32983L,32984L,32985L,32986L,32987L,\n32988L,32989L,32990L,32991L,32992L,32993L,32994L,32995L,32996L,32997L,\n32998L,32999L,33000L,33001L,33002L,33003L,33004L,33005L,33006L,33007L,\n33008L,33009L,33010L,33011L,33012L,33013L,33014L,33015L,33016L,33017L,\n33018L,33019L,33020L,33021L,33022L,33023L,33024L,33025L,33026L,33027L,\n33028L,33029L,33030L,33031L,33032L,33033L,33034L,33035L,33036L,33037L,\n33038L,33039L,33040L,33041L,33042L,33043L,33044L,33045L,33046L,33047L,\n33048L,33049L,33050L,33051L,33052L,33053L,33054L,33055L,33056L,33057L,\n33058L,33059L,33060L,33061L,33062L,33063L,33064L,33065L,33066L,33067L,\n33068L,33069L,33070L,33071L,33072L,33073L,33074L,33075L,33076L,33077L,\n33078L,33079L,33080L,33081L,33082L,33083L,33084L,33085L,33086L,33087L,\n33088L,33089L,33090L,33091L,33092L,33093L,33094L,33095L,33096L,33097L,\n33098L,33099L,33100L,33101L,33102L,33103L,33104L,33105L,33106L,33107L,\n33108L,33109L,33110L,33111L,33112L,33113L,33114L,33115L,33116L,33117L,\n33118L,33119L,33120L,33121L,33122L,33123L,33124L,33125L,33126L,33127L,\n33128L,33129L,33130L,33131L,33132L,33133L,33134L,33135L,33136L,33137L,\n33138L,33139L,33140L,33141L,33142L,33143L,33144L,33145L,33146L,33147L,\n33148L,33149L,33150L,33151L,33152L,33153L,33154L,33155L,33156L,33157L,\n33158L,33159L,33160L,33161L,33162L,33163L,33164L,33165L,33166L,33167L,\n33168L,33169L,33170L,33171L,33172L,33173L,33174L,33175L,33176L,33177L,\n33178L,33179L,33180L,33181L,33182L,33183L,33184L,33185L,33186L,33187L,\n33188L,33189L,33190L,33191L,33192L,33193L,33194L,33195L,33196L,33197L,\n33198L,33199L,33200L,33201L,33202L,33203L,33204L,33205L,33206L,33207L,\n33208L,33209L,33210L,33211L,33212L,33213L,33214L,33215L,33216L,33217L,\n33218L,33219L,33220L,33221L,33222L,33223L,33224L,33225L,33226L,33227L,\n33228L,33229L,33230L,33231L,33232L,33233L,33234L,33235L,33236L,33237L,\n33238L,33239L,33240L,33241L,33242L,33243L,33244L,33245L,33246L,33247L,\n33248L,33249L,33250L,33251L,33252L,33253L,33254L,33255L,33256L,33257L,\n33258L,33259L,33260L,33261L,33262L,33263L,33264L,33265L,33266L,33267L,\n33268L,33269L,33270L,33271L,33272L,33273L,33274L,33275L,33276L,33277L,\n33278L,33279L,33280L,33281L,33282L,33283L,33284L,33285L,33286L,33287L,\n33288L,33289L,33290L,33291L,33292L,33293L,33294L,33295L,33296L,33297L,\n33298L,33299L,33300L,33301L,33302L,33303L,33304L,33305L,33306L,33307L,\n33308L,33309L,33310L,33311L,33312L,33313L,33314L,33315L,33316L,33317L,\n33318L,33319L,33320L,33321L,33322L,33323L,33324L,33325L,33326L,33327L,\n33328L,33329L,33330L,33331L,33332L,33333L,33334L,33335L,33336L,33337L,\n33338L,33339L,33340L,33341L,33342L,33343L,33344L,33345L,33346L,33347L,\n33348L,33349L,33350L,33351L,33352L,33353L,33354L,33355L,33356L,33357L,\n33358L,33359L,33360L,33361L,33362L,33363L,33364L,33365L,33366L,33367L,\n33368L,33369L,33370L,33371L,33372L,33373L,33374L,33375L,33376L,33377L,\n33378L,33379L,33380L,33381L,33382L,33383L,33384L,33385L,33386L,33387L,\n33388L,33389L,33390L,33391L,33392L,33393L,33394L,33395L,33396L,33397L,\n33398L,33399L,33400L,33401L,33402L,33403L,33404L,33405L,33406L,33407L,\n33408L,33409L,33410L,33411L,33412L,33413L,33414L,33415L,33416L,33417L,\n33418L,33419L,33420L,33421L,33422L,33423L,33424L,33425L,33426L,33427L,\n33428L,33429L,33430L,33431L,33432L,33433L,33434L,33435L,33436L,33437L,\n33438L,33439L,33440L,33441L,33442L,33443L,33444L,33445L,33446L,33447L,\n33448L,33449L,33450L,33451L,33452L,33453L,33454L,33455L,33456L,33457L,\n33458L,33459L,33460L,33461L,33462L,33463L,33464L,33465L,33466L,33467L,\n33468L,33469L,33470L,33471L,33472L,33473L,33474L,33475L,33476L,33477L,\n33478L,33479L,33480L,33481L,33482L,33483L,33484L,33485L,33486L,33487L,\n33488L,33489L,33490L,33491L,33492L,33493L,33494L,33495L,33496L,33497L,\n33498L,33499L,33500L,33501L,33502L,33503L,33504L,33505L,33506L,33507L,\n33508L,33509L,33510L,33511L,33512L,33513L,33514L,33515L,33516L,33517L,\n33518L,33519L,33520L,33521L,33522L,33523L,33524L,33525L,33526L,33527L,\n33528L,33529L,33530L,33531L,33532L,33533L,33534L,33535L,33536L,33537L,\n33538L,33539L,33540L,33541L,33542L,33543L,33544L,33545L,33546L,33547L,\n33548L,33549L,33550L,33551L,33552L,33553L,33554L,33555L,33556L,33557L,\n33558L,33559L,33560L,33561L,33562L,33563L,33564L,33565L,33566L,33567L,\n33568L,33569L,33570L,33571L,33572L,33573L,33574L,33575L,33576L,33577L,\n33578L,33579L,33580L,33581L,33582L,33583L,33584L,33585L,33586L,33587L,\n33588L,33589L,33590L,33591L,33592L,33593L,33594L,33595L,33596L,33597L,\n33598L,33599L,33600L,33601L,33602L,33603L,33604L,33605L,33606L,33607L,\n33608L,33609L,33610L,33611L,33612L,33613L,33614L,33615L,33616L,33617L,\n33618L,33619L,33620L,33621L,33622L,33623L,33624L,33625L,33626L,33627L,\n33628L,33629L,33630L,33631L,33632L,33633L,33634L,33635L,33636L,33637L,\n33638L,33639L,33640L,33641L,33642L,33643L,33644L,33645L,33646L,33647L,\n33648L,33649L,33650L,33651L,33652L,33653L,33654L,33655L,33656L,33657L,\n33658L,33659L,33660L,33661L,33662L,33663L,33664L,33665L,33666L,33667L,\n33668L,33669L,33670L,33671L,33672L,33673L,33674L,33675L,33676L,33677L,\n33678L,33679L,33680L,33681L,33682L,33683L,33684L,33685L,33686L,33687L,\n33688L,33689L,33690L,33691L,33692L,33693L,33694L,33695L,33696L,33697L,\n33698L,33699L,33700L,33701L,33702L,33703L,33704L,33705L,33706L,33707L,\n33708L,33709L,33710L,33711L,33712L,33713L,33714L,33715L,33716L,33717L,\n33718L,33719L,33720L,33721L,33722L,33723L,33724L,33725L,33726L,33727L,\n33728L,33729L,33730L,33731L,33732L,33733L,33734L,33735L,33736L,33737L,\n33738L,33739L,33740L,33741L,33742L,33743L,33744L,33745L,33746L,33747L,\n33748L,33749L,33750L,33751L,33752L,33753L,33754L,33755L,33756L,33757L,\n33758L,33759L,33760L,33761L,33762L,33763L,33764L,33765L,33766L,33767L,\n33768L,33769L,33770L,33771L,33772L,33773L,33774L,33775L,33776L,33777L,\n33778L,33779L,33780L,33781L,33782L,33783L,33784L,33785L,33786L,33787L,\n33788L,33789L,33790L,33791L,33792L,33793L,33794L,33795L,33796L,33797L,\n33798L,33799L,33800L,33801L,33802L,33803L,33804L,33805L,33806L,33807L,\n33808L,33809L,33810L,33811L,33812L,33813L,33814L,33815L,33816L,33817L,\n33818L,33819L,33820L,33821L,33822L,33823L,33824L,33825L,33826L,33827L,\n33828L,33829L,33830L,33831L,33832L,33833L,33834L,33835L,33836L,33837L,\n33838L,33839L,33840L,33841L,33842L,33843L,33844L,33845L,33846L,33847L,\n33848L,33849L,33850L,33851L,33852L,33853L,33854L,33855L,33856L,33857L,\n33858L,33859L,33860L,33861L,33862L,33863L,33864L,33865L,33866L,33867L,\n33868L,33869L,33870L,33871L,33872L,33873L,33874L,33875L,33876L,33877L,\n33878L,33879L,33880L,33881L,33882L,33883L,33884L,33885L,33886L,33887L,\n33888L,33889L,33890L,33891L,33892L,33893L,33894L,33895L,33896L,33897L,\n33898L,33899L,33900L,33901L,33902L,33903L,33904L,33905L,33906L,33907L,\n33908L,33909L,33910L,33911L,33912L,33913L,33914L,33915L,33916L,33917L,\n33918L,33919L,33920L,33921L,33922L,33923L,33924L,33925L,33926L,33927L,\n33928L,33929L,33930L,33931L,33932L,33933L,33934L,33935L,33936L,33937L,\n33938L,33939L,33940L,33941L,33942L,33943L,33944L,33945L,33946L,33947L,\n33948L,33949L,33950L,33951L,33952L,33953L,33954L,33955L,33956L,33957L,\n33958L,33959L,33960L,33961L,33962L,33963L,33964L,33965L,33966L,33967L,\n33968L,33969L,33970L,33971L,33972L,33973L,33974L,33975L,33976L,33977L,\n33978L,33979L,33980L,33981L,33982L,33983L,33984L,33985L,33986L,33987L,\n33988L,33989L,33990L,33991L,33992L,33993L,33994L,33995L,33996L,33997L,\n33998L,33999L,34000L,34001L,34002L,34003L,34004L,34005L,34006L,34007L,\n34008L,34009L,34010L,34011L,34012L,34013L,34014L,34015L,34016L,34017L,\n34018L,34019L,34020L,34021L,34022L,34023L,34024L,34025L,34026L,34027L,\n34028L,34029L,34030L,34031L,34032L,34033L,34034L,34035L,34036L,34037L,\n34038L,34039L,34040L,34041L,34042L,34043L,34044L,34045L,34046L,34047L,\n34048L,34049L,34050L,34051L,34052L,34053L,34054L,34055L,34056L,34057L,\n34058L,34059L,34060L,34061L,34062L,34063L,34064L,34065L,34066L,34067L,\n34068L,34069L,34070L,34071L,34072L,34073L,34074L,34075L,34076L,34077L,\n34078L,34079L,34080L,34081L,34082L,34083L,34084L,34085L,34086L,34087L,\n34088L,34089L,34090L,34091L,34092L,34093L,34094L,34095L,34096L,34097L,\n34098L,34099L,34100L,34101L,34102L,34103L,34104L,34105L,34106L,34107L,\n34108L,34109L,34110L,34111L,34112L,34113L,34114L,34115L,34116L,34117L,\n34118L,34119L,34120L,34121L,34122L,34123L,34124L,34125L,34126L,34127L,\n34128L,34129L,34130L,34131L,34132L,34133L,34134L,34135L,34136L,34137L,\n34138L,34139L,34140L,34141L,34142L,34143L,34144L,34145L,34146L,34147L,\n34148L,34149L,34150L,34151L,34152L,34153L,34154L,34155L,34156L,34157L,\n34158L,34159L,34160L,34161L,34162L,34163L,34164L,34165L,34166L,34167L,\n34168L,34169L,34170L,34171L,34172L,34173L,34174L,34175L,34176L,34177L,\n34178L,34179L,34180L,34181L,34182L,34183L,34184L,34185L,34186L,34187L,\n34188L,34189L,34190L,34191L,34192L,34193L,34194L,34195L,34196L,34197L,\n34198L,34199L,34200L,34201L,34202L,34203L,34204L,34205L,34206L,34207L,\n34208L,34209L,34210L,34211L,34212L,34213L,34214L,34215L,34216L,34217L,\n34218L,34219L,34220L,34221L,34222L,34223L,34224L,34225L,34226L,34227L,\n34228L,34229L,34230L,34231L,34232L,34233L,34234L,34235L,34236L,34237L,\n34238L,34239L,34240L,34241L,34242L,34243L,34244L,34245L,34246L,34247L,\n34248L,34249L,34250L,34251L,34252L,34253L,34254L,34255L,34256L,34257L,\n34258L,34259L,34260L,34261L,34262L,34263L,34264L,34265L,34266L,34267L,\n34268L,34269L,34270L,34271L,34272L,34273L,34274L,34275L,34276L,34277L,\n34278L,34279L,34280L,34281L,34282L,34283L,34284L,34285L,34286L,34287L,\n34288L,34289L,34290L,34291L,34292L,34293L,34294L,34295L,34296L,34297L,\n34298L,34299L,34300L,34301L,34302L,34303L,34304L,34305L,34306L,34307L,\n34308L,34309L,34310L,34311L,34312L,34313L,34314L,34315L,34316L,34317L,\n34318L,34319L,34320L,34321L,34322L,34323L,34324L,34325L,34326L,34327L,\n34328L,34329L,34330L,34331L,34332L,34333L,34334L,34335L,34336L,34337L,\n34338L,34339L,34340L,34341L,34342L,34343L,34344L,34345L,34346L,34347L,\n34348L,34349L,34350L,34351L,34352L,34353L,34354L,34355L,34356L,34357L,\n34358L,34359L,34360L,34361L,34362L,34363L,34364L,34365L,34366L,34367L,\n34368L,34369L,34370L,34371L,34372L,34373L,34374L,34375L,34376L,34377L,\n34378L,34379L,34380L,34381L,34382L,34383L,34384L,34385L,34386L,34387L,\n34388L,34389L,34390L,34391L,34392L,34393L,34394L,34395L,34396L,34397L,\n34398L,34399L,34400L,34401L,34402L,34403L,34404L,34405L,34406L,34407L,\n34408L,34409L,34410L,34411L,34412L,34413L,34414L,34415L,34416L,34417L,\n34418L,34419L,34420L,34421L,34422L,34423L,34424L,34425L,34426L,34427L,\n34428L,34429L,34430L,34431L,34432L,34433L,34434L,34435L,34436L,34437L,\n34438L,34439L,34440L,34441L,34442L,34443L,34444L,34445L,34446L,34447L,\n34448L,34449L,34450L,34451L,34452L,34453L,34454L,34455L,34456L,34457L,\n34458L,34459L,34460L,34461L,34462L,34463L,34464L,34465L,34466L,34467L,\n34468L,34469L,34470L,34471L,34472L,34473L,34474L,34475L,34476L,34477L,\n34478L,34479L,34480L,34481L,34482L,34483L,34484L,34485L,34486L,34487L,\n34488L,34489L,34490L,34491L,34492L,34493L,34494L,34495L,34496L,34497L,\n34498L,34499L,34500L,34501L,34502L,34503L,34504L,34505L,34506L,34507L,\n34508L,34509L,34510L,34511L,34512L,34513L,34514L,34515L,34516L,34517L,\n34518L,34519L,34520L,34521L,34522L,34523L,34524L,34525L,34526L,34527L,\n34528L,34529L,34530L,34531L,34532L,34533L,34534L,34535L,34536L,34537L,\n34538L,34539L,34540L,34541L,34542L,34543L,34544L,34545L,34546L,34547L,\n34548L,34549L,34550L,34551L,34552L,34553L,34554L,34555L,34556L,34557L,\n34558L,34559L,34560L,34561L,34562L,34563L,34564L,34565L,34566L,34567L,\n34568L,34569L,34570L,34571L,34572L,34573L,34574L,34575L,34576L,34577L,\n34578L,34579L,34580L,34581L,34582L,34583L,34584L,34585L,34586L,34587L,\n34588L,34589L,34590L,34591L,34592L,34593L,34594L,34595L,34596L,34597L,\n34598L,34599L,34600L,34601L,34602L,34603L,34604L,34605L,34606L,34607L,\n34608L,34609L,34610L,34611L,34612L,34613L,34614L,34615L,34616L,34617L,\n34618L,34619L,34620L,34621L,34622L,34623L,34624L,34625L,34626L,34627L,\n34628L,34629L,34630L,34631L,34632L,34633L,34634L,34635L,34636L,34637L,\n34638L,34639L,34640L,34641L,34642L,34643L,34644L,34645L,34646L,34647L,\n34648L,34649L,34650L,34651L,34652L,34653L,34654L,34655L,34656L,34657L,\n34658L,34659L,34660L,34661L,34662L,34663L,34664L,34665L,34666L,34667L,\n34668L,34669L,34670L,34671L,34672L,34673L,34674L,34675L,34676L,34677L,\n34678L,34679L,34680L,34681L,34682L,34683L,34684L,34685L,34686L,34687L,\n34688L,34689L,34690L,34691L,34692L,34693L,34694L,34695L,34696L,34697L,\n34698L,34699L,34700L,34701L,34702L,34703L,34704L,34705L,34706L,34707L,\n34708L,34709L,34710L,34711L,34712L,34713L,34714L,34715L,34716L,34717L,\n34718L,34719L,34720L,34721L,34722L,34723L,34724L,34725L,34726L,34727L,\n34728L,34729L,34730L,34731L,34732L,34733L,34734L,34735L,34736L,34737L,\n34738L,34739L,34740L,34741L,34742L,34743L,34744L,34745L,34746L,34747L,\n34748L,34749L,34750L,34751L,34752L,34753L,34754L,34755L,34756L,34757L,\n34758L,34759L,34760L,34761L,34762L,34763L,34764L,34765L,34766L,34767L,\n34768L,34769L,34770L,34771L,34772L,34773L,34774L,34775L,34776L,34777L,\n34778L,34779L,34780L,34781L,34782L,34783L,34784L,34785L,34786L,34787L,\n34788L,34789L,34790L,34791L,34792L,34793L,34794L,34795L,34796L,34797L,\n34798L,34799L,34800L,34801L,34802L,34803L,34804L,34805L,34806L,34807L,\n34808L,34809L,34810L,34811L,34812L,34813L,34814L,34815L,34816L,34817L,\n34818L,34819L,34820L,34821L,34822L,34823L,34824L,34825L,34826L,34827L,\n34828L,34829L,34830L,34831L,34832L,34833L,34834L,34835L,34836L,34837L,\n34838L,34839L,34840L,34841L,34842L,34843L,34844L,34845L,34846L,34847L,\n34848L,34849L,34850L,34851L,34852L,34853L,34854L,34855L,34856L,34857L,\n34858L,34859L,34860L,34861L,34862L,34863L,34864L,34865L,34866L,34867L,\n34868L,34869L,34870L,34871L,34872L,34873L,34874L,34875L,34876L,34877L,\n34878L,34879L,34880L,34881L,34882L,34883L,34884L,34885L,34886L,34887L,\n34888L,34889L,34890L,34891L,34892L,34893L,34894L,34895L,34896L,34897L,\n34898L,34899L,34900L,34901L,34902L,34903L,34904L,34905L,34906L,34907L,\n34908L,34909L,34910L,34911L,34912L,34913L,34914L,34915L,34916L,34917L,\n34918L,34919L,34920L,34921L,34922L,34923L,34924L,34925L,34926L,34927L,\n34928L,34929L,34930L,34931L,34932L,34933L,34934L,34935L,34936L,34937L,\n34938L,34939L,34940L,34941L,34942L,34943L,34944L,34945L,34946L,34947L,\n34948L,34949L,34950L,34951L,34952L,34953L,34954L,34955L,34956L,34957L,\n34958L,34959L,34960L,34961L,34962L,34963L,34964L,34965L,34966L,34967L,\n34968L,34969L,34970L,34971L,34972L,34973L,34974L,34975L,34976L,34977L,\n34978L,34979L,34980L,34981L,34982L,34983L,34984L,34985L,34986L,34987L,\n34988L,34989L,34990L,34991L,34992L,34993L,34994L,34995L,34996L,34997L,\n34998L,34999L,35000L,35001L,35002L,35003L,35004L,35005L,35006L,35007L,\n35008L,35009L,35010L,35011L,35012L,35013L,35014L,35015L,35016L,35017L,\n35018L,35019L,35020L,35021L,35022L,35023L,35024L,35025L,35026L,35027L,\n35028L,35029L,35030L,35031L,35032L,35033L,35034L,35035L,35036L,35037L,\n35038L,35039L,35040L,35041L,35042L,35043L,35044L,35045L,35046L,35047L,\n35048L,35049L,35050L,35051L,35052L,35053L,35054L,35055L,35056L,35057L,\n35058L,35059L,35060L,35061L,35062L,35063L,35064L,35065L,35066L,35067L,\n35068L,35069L,35070L,35071L,35072L,35073L,35074L,35075L,35076L,35077L,\n35078L,35079L,35080L,35081L,35082L,35083L,35084L,35085L,35086L,35087L,\n35088L,35089L,35090L,35091L,35092L,35093L,35094L,35095L,35096L,35097L,\n35098L,35099L,35100L,35101L,35102L,35103L,35104L,35105L,35106L,35107L,\n35108L,35109L,35110L,35111L,35112L,35113L,35114L,35115L,35116L,35117L,\n35118L,35119L,35120L,35121L,35122L,35123L,35124L,35125L,35126L,35127L,\n35128L,35129L,35130L,35131L,35132L,35133L,35134L,35135L,35136L,35137L,\n35138L,35139L,35140L,35141L,35142L,35143L,35144L,35145L,35146L,35147L,\n35148L,35149L,35150L,35151L,35152L,35153L,35154L,35155L,35156L,35157L,\n35158L,35159L,35160L,35161L,35162L,35163L,35164L,35165L,35166L,35167L,\n35168L,35169L,35170L,35171L,35172L,35173L,35174L,35175L,35176L,35177L,\n35178L,35179L,35180L,35181L,35182L,35183L,35184L,35185L,35186L,35187L,\n35188L,35189L,35190L,35191L,35192L,35193L,35194L,35195L,35196L,35197L,\n35198L,35199L,35200L,35201L,35202L,35203L,35204L,35205L,35206L,35207L,\n35208L,35209L,35210L,35211L,35212L,35213L,35214L,35215L,35216L,35217L,\n35218L,35219L,35220L,35221L,35222L,35223L,35224L,35225L,35226L,35227L,\n35228L,35229L,35230L,35231L,35232L,35233L,35234L,35235L,35236L,35237L,\n35238L,35239L,35240L,35241L,35242L,35243L,35244L,35245L,35246L,35247L,\n35248L,35249L,35250L,35251L,35252L,35253L,35254L,35255L,35256L,35257L,\n35258L,35259L,35260L,35261L,35262L,35263L,35264L,35265L,35266L,35267L,\n35268L,35269L,35270L,35271L,35272L,35273L,35274L,35275L,35276L,35277L,\n35278L,35279L,35280L,35281L,35282L,35283L,35284L,35285L,35286L,35287L,\n35288L,35289L,35290L,35291L,35292L,35293L,35294L,35295L,35296L,35297L,\n35298L,35299L,35300L,35301L,35302L,35303L,35304L,35305L,35306L,35307L,\n35308L,35309L,35310L,35311L,35312L,35313L,35314L,35315L,35316L,35317L,\n35318L,35319L,35320L,35321L,35322L,35323L,35324L,35325L,35326L,35327L,\n35328L,35329L,35330L,35331L,35332L,35333L,35334L,35335L,35336L,35337L,\n35338L,35339L,35340L,35341L,35342L,35343L,35344L,35345L,35346L,35347L,\n35348L,35349L,35350L,35351L,35352L,35353L,35354L,35355L,35356L,35357L,\n35358L,35359L,35360L,35361L,35362L,35363L,35364L,35365L,35366L,35367L,\n35368L,35369L,35370L,35371L,35372L,35373L,35374L,35375L,35376L,35377L,\n35378L,35379L,35380L,35381L,35382L,35383L,35384L,35385L,35386L,35387L,\n35388L,35389L,35390L,35391L,35392L,35393L,35394L,35395L,35396L,35397L,\n35398L,35399L,35400L,35401L,35402L,35403L,35404L,35405L,35406L,35407L,\n35408L,35409L,35410L,35411L,35412L,35413L,35414L,35415L,35416L,35417L,\n35418L,35419L,35420L,35421L,35422L,35423L,35424L,35425L,35426L,35427L,\n35428L,35429L,35430L,35431L,35432L,35433L,35434L,35435L,35436L,35437L,\n35438L,35439L,35440L,35441L,35442L,35443L,35444L,35445L,35446L,35447L,\n35448L,35449L,35450L,35451L,35452L,35453L,35454L,35455L,35456L,35457L,\n35458L,35459L,35460L,35461L,35462L,35463L,35464L,35465L,35466L,35467L,\n35468L,35469L,35470L,35471L,35472L,35473L,35474L,35475L,35476L,35477L,\n35478L,35479L,35480L,35481L,35482L,35483L,35484L,35485L,35486L,35487L,\n35488L,35489L,35490L,35491L,35492L,35493L,35494L,35495L,35496L,35497L,\n35498L,35499L,35500L,35501L,35502L,35503L,35504L,35505L,35506L,35507L,\n35508L,35509L,35510L,35511L,35512L,35513L,35514L,35515L,35516L,35517L,\n35518L,35519L,35520L,35521L,35522L,35523L,35524L,35525L,35526L,35527L,\n35528L,35529L,35530L,35531L,35532L,35533L,35534L,35535L,35536L,35537L,\n35538L,35539L,35540L,35541L,35542L,35543L,35544L,35545L,35546L,35547L,\n35548L,35549L,35550L,35551L,35552L,35553L,35554L,35555L,35556L,35557L,\n35558L,35559L,35560L,35561L,35562L,35563L,35564L,35565L,35566L,35567L,\n35568L,35569L,35570L,35571L,35572L,35573L,35574L,35575L,35576L,35577L,\n35578L,35579L,35580L,35581L,35582L,35583L,35584L,35585L,35586L,35587L,\n35588L,35589L,35590L,35591L,35592L,35593L,35594L,35595L,35596L,35597L,\n35598L,35599L,35600L,35601L,35602L,35603L,35604L,35605L,35606L,35607L,\n35608L,35609L,35610L,35611L,35612L,35613L,35614L,35615L,35616L,35617L,\n35618L,35619L,35620L,35621L,35622L,35623L,35624L,35625L,35626L,35627L,\n35628L,35629L,35630L,35631L,35632L,35633L,35634L,35635L,35636L,35637L,\n35638L,35639L,35640L,35641L,35642L,35643L,35644L,35645L,35646L,35647L,\n35648L,35649L,35650L,35651L,35652L,35653L,35654L,35655L,35656L,35657L,\n35658L,35659L,35660L,35661L,35662L,35663L,35664L,35665L,35666L,35667L,\n35668L,35669L,35670L,35671L,35672L,35673L,35674L,35675L,35676L,35677L,\n35678L,35679L,35680L,35681L,35682L,35683L,35684L,35685L,35686L,35687L,\n35688L,35689L,35690L,35691L,35692L,35693L,35694L,35695L,35696L,35697L,\n35698L,35699L,35700L,35701L,35702L,35703L,35704L,35705L,35706L,35707L,\n35708L,35709L,35710L,35711L,35712L,35713L,35714L,35715L,35716L,35717L,\n35718L,35719L,35720L,35721L,35722L,35723L,35724L,35725L,35726L,35727L,\n35728L,35729L,35730L,35731L,35732L,35733L,35734L,35735L,35736L,35737L,\n35738L,35739L,35740L,35741L,35742L,35743L,35744L,35745L,35746L,35747L,\n35748L,35749L,35750L,35751L,35752L,35753L,35754L,35755L,35756L,35757L,\n35758L,35759L,35760L,35761L,35762L,35763L,35764L,35765L,35766L,35767L,\n35768L,35769L,35770L,35771L,35772L,35773L,35774L,35775L,35776L,35777L,\n35778L,35779L,35780L,35781L,35782L,35783L,35784L,35785L,35786L,35787L,\n35788L,35789L,35790L,35791L,35792L,35793L,35794L,35795L,35796L,35797L,\n35798L,35799L,35800L,35801L,35802L,35803L,35804L,35805L,35806L,35807L,\n35808L,35809L,35810L,35811L,35812L,35813L,35814L,35815L,35816L,35817L,\n35818L,35819L,35820L,35821L,35822L,35823L,35824L,35825L,35826L,35827L,\n35828L,35829L,35830L,35831L,35832L,35833L,35834L,35835L,35836L,35837L,\n35838L,35839L,35840L,35841L,35842L,35843L,35844L,35845L,35846L,35847L,\n35848L,35849L,35850L,35851L,35852L,35853L,35854L,35855L,35856L,35857L,\n35858L,35859L,35860L,35861L,35862L,35863L,35864L,35865L,35866L,35867L,\n35868L,35869L,35870L,35871L,35872L,35873L,35874L,35875L,35876L,35877L,\n35878L,35879L,35880L,35881L,35882L,35883L,35884L,35885L,35886L,35887L,\n35888L,35889L,35890L,35891L,35892L,35893L,35894L,35895L,35896L,35897L,\n35898L,35899L,35900L,35901L,35902L,35903L,35904L,35905L,35906L,35907L,\n35908L,35909L,35910L,35911L,35912L,35913L,35914L,35915L,35916L,35917L,\n35918L,35919L,35920L,35921L,35922L,35923L,35924L,35925L,35926L,35927L,\n35928L,35929L,35930L,35931L,35932L,35933L,35934L,35935L,35936L,35937L,\n35938L,35939L,35940L,35941L,35942L,35943L,35944L,35945L,35946L,35947L,\n35948L,35949L,35950L,35951L,35952L,35953L,35954L,35955L,35956L,35957L,\n35958L,35959L,35960L,35961L,35962L,35963L,35964L,35965L,35966L,35967L,\n35968L,35969L,35970L,35971L,35972L,35973L,35974L,35975L,35976L,35977L,\n35978L,35979L,35980L,35981L,35982L,35983L,35984L,35985L,35986L,35987L,\n35988L,35989L,35990L,35991L,35992L,35993L,35994L,35995L,35996L,35997L,\n35998L,35999L,36000L,36001L,36002L,36003L,36004L,36005L,36006L,36007L,\n36008L,36009L,36010L,36011L,36012L,36013L,36014L,36015L,36016L,36017L,\n36018L,36019L,36020L,36021L,36022L,36023L,36024L,36025L,36026L,36027L,\n36028L,36029L,36030L,36031L,36032L,36033L,36034L,36035L,36036L,36037L,\n36038L,36039L,36040L,36041L,36042L,36043L,36044L,36045L,36046L,36047L,\n36048L,36049L,36050L,36051L,36052L,36053L,36054L,36055L,36056L,36057L,\n36058L,36059L,36060L,36061L,36062L,36063L,36064L,36065L,36066L,36067L,\n36068L,36069L,36070L,36071L,36072L,36073L,36074L,36075L,36076L,36077L,\n36078L,36079L,36080L,36081L,36082L,36083L,36084L,36085L,36086L,36087L,\n36088L,36089L,36090L,36091L,36092L,36093L,36094L,36095L,36096L,36097L,\n36098L,36099L,36100L,36101L,36102L,36103L,36104L,36105L,36106L,36107L,\n36108L,36109L,36110L,36111L,36112L,36113L,36114L,36115L,36116L,36117L,\n36118L,36119L,36120L,36121L,36122L,36123L,36124L,36125L,36126L,36127L,\n36128L,36129L,36130L,36131L,36132L,36133L,36134L,36135L,36136L,36137L,\n36138L,36139L,36140L,36141L,36142L,36143L,36144L,36145L,36146L,36147L,\n36148L,36149L,36150L,36151L,36152L,36153L,36154L,36155L,36156L,36157L,\n36158L,36159L,36160L,36161L,36162L,36163L,36164L,36165L,36166L,36167L,\n36168L,36169L,36170L,36171L,36172L,36173L,36174L,36175L,36176L,36177L,\n36178L,36179L,36180L,36181L,36182L,36183L,36184L,36185L,36186L,36187L,\n36188L,36189L,36190L,36191L,36192L,36193L,36194L,36195L,36196L,36197L,\n36198L,36199L,36200L,36201L,36202L,36203L,36204L,36205L,36206L,36207L,\n36208L,36209L,36210L,36211L,36212L,36213L,36214L,36215L,36216L,36217L,\n36218L,36219L,36220L,36221L,36222L,36223L,36224L,36225L,36226L,36227L,\n36228L,36229L,36230L,36231L,36232L,36233L,36234L,36235L,36236L,36237L,\n36238L,36239L,36240L,36241L,36242L,36243L,36244L,36245L,36246L,36247L,\n36248L,36249L,36250L,36251L,36252L,36253L,36254L,36255L,36256L,36257L,\n36258L,36259L,36260L,36261L,36262L,36263L,36264L,36265L,36266L,36267L,\n36268L,36269L,36270L,36271L,36272L,36273L,36274L,36275L,36276L,36277L,\n36278L,36279L,36280L,36281L,36282L,36283L,36284L,36285L,36286L,36287L,\n36288L,36289L,36290L,36291L,36292L,36293L,36294L,36295L,36296L,36297L,\n36298L,36299L,36300L,36301L,36302L,36303L,36304L,36305L,36306L,36307L,\n36308L,36309L,36310L,36311L,36312L,36313L,36314L,36315L,36316L,36317L,\n36318L,36319L,36320L,36321L,36322L,36323L,36324L,36325L,36326L,36327L,\n36328L,36329L,36330L,36331L,36332L,36333L,36334L,36335L,36336L,36337L,\n36338L,36339L,36340L,36341L,36342L,36343L,36344L,36345L,36346L,36347L,\n36348L,36349L,36350L,36351L,36352L,36353L,36354L,36355L,36356L,36357L,\n36358L,36359L,36360L,36361L,36362L,36363L,36364L,36365L,36366L,36367L,\n36368L,36369L,36370L,36371L,36372L,36373L,36374L,36375L,36376L,36377L,\n36378L,36379L,36380L,36381L,36382L,36383L,36384L,36385L,36386L,36387L,\n36388L,36389L,36390L,36391L,36392L,36393L,36394L,36395L,36396L,36397L,\n36398L,36399L,36400L,36401L,36402L,36403L,36404L,36405L,36406L,36407L,\n36408L,36409L,36410L,36411L,36412L,36413L,36414L,36415L,36416L,36417L,\n36418L,36419L,36420L,36421L,36422L,36423L,36424L,36425L,36426L,36427L,\n36428L,36429L,36430L,36431L,36432L,36433L,36434L,36435L,36436L,36437L,\n36438L,36439L,36440L,36441L,36442L,36443L,36444L,36445L,36446L,36447L,\n36448L,36449L,36450L,36451L,36452L,36453L,36454L,36455L,36456L,36457L,\n36458L,36459L,36460L,36461L,36462L,36463L,36464L,36465L,36466L,36467L,\n36468L,36469L,36470L,36471L,36472L,36473L,36474L,36475L,36476L,36477L,\n36478L,36479L,36480L,36481L,36482L,36483L,36484L,36485L,36486L,36487L,\n36488L,36489L,36490L,36491L,36492L,36493L,36494L,36495L,36496L,36497L,\n36498L,36499L,36500L,36501L,36502L,36503L,36504L,36505L,36506L,36507L,\n36508L,36509L,36510L,36511L,36512L,36513L,36514L,36515L,36516L,36517L,\n36518L,36519L,36520L,36521L,36522L,36523L,36524L,36525L,36526L,36527L,\n36528L,36529L,36530L,36531L,36532L,36533L,36534L,36535L,36536L,36537L,\n36538L,36539L,36540L,36541L,36542L,36543L,36544L,36545L,36546L,36547L,\n36548L,36549L,36550L,36551L,36552L,36553L,36554L,36555L,36556L,36557L,\n36558L,36559L,36560L,36561L,36562L,36563L,36564L,36565L,36566L,36567L,\n36568L,36569L,36570L,36571L,36572L,36573L,36574L,36575L,36576L,36577L,\n36578L,36579L,36580L,36581L,36582L,36583L,36584L,36585L,36586L,36587L,\n36588L,36589L,36590L,36591L,36592L,36593L,36594L,36595L,36596L,36597L,\n36598L,36599L,36600L,36601L,36602L,36603L,36604L,36605L,36606L,36607L,\n36608L,36609L,36610L,36611L,36612L,36613L,36614L,36615L,36616L,36617L,\n36618L,36619L,36620L,36621L,36622L,36623L,36624L,36625L,36626L,36627L,\n36628L,36629L,36630L,36631L,36632L,36633L,36634L,36635L,36636L,36637L,\n36638L,36639L,36640L,36641L,36642L,36643L,36644L,36645L,36646L,36647L,\n36648L,36649L,36650L,36651L,36652L,36653L,36654L,36655L,36656L,36657L,\n36658L,36659L,36660L,36661L,36662L,36663L,36664L,36665L,36666L,36667L,\n36668L,36669L,36670L,36671L,36672L,36673L,36674L,36675L,36676L,36677L,\n36678L,36679L,36680L,36681L,36682L,36683L,36684L,36685L,36686L,36687L,\n36688L,36689L,36690L,36691L,36692L,36693L,36694L,36695L,36696L,36697L,\n36698L,36699L,36700L,36701L,36702L,36703L,36704L,36705L,36706L,36707L,\n36708L,36709L,36710L,36711L,36712L,36713L,36714L,36715L,36716L,36717L,\n36718L,36719L,36720L,36721L,36722L,36723L,36724L,36725L,36726L,36727L,\n36728L,36729L,36730L,36731L,36732L,36733L,36734L,36735L,36736L,36737L,\n36738L,36739L,36740L,36741L,36742L,36743L,36744L,36745L,36746L,36747L,\n36748L,36749L,36750L,36751L,36752L,36753L,36754L,36755L,36756L,36757L,\n36758L,36759L,36760L,36761L,36762L,36763L,36764L,36765L,36766L,36767L,\n36768L,36769L,36770L,36771L,36772L,36773L,36774L,36775L,36776L,36777L,\n36778L,36779L,36780L,36781L,36782L,36783L,36784L,36785L,36786L,36787L,\n36788L,36789L,36790L,36791L,36792L,36793L,36794L,36795L,36796L,36797L,\n36798L,36799L,36800L,36801L,36802L,36803L,36804L,36805L,36806L,36807L,\n36808L,36809L,36810L,36811L,36812L,36813L,36814L,36815L,36816L,36817L,\n36818L,36819L,36820L,36821L,36822L,36823L,36824L,36825L,36826L,36827L,\n36828L,36829L,36830L,36831L,36832L,36833L,36834L,36835L,36836L,36837L,\n36838L,36839L,36840L,36841L,36842L,36843L,36844L,36845L,36846L,36847L,\n36848L,36849L,36850L,36851L,36852L,36853L,36854L,36855L,36856L,36857L,\n36858L,36859L,36860L,36861L,36862L,36863L,36864L,36865L,36866L,36867L,\n36868L,36869L,36870L,36871L,36872L,36873L,36874L,36875L,36876L,36877L,\n36878L,36879L,36880L,36881L,36882L,36883L,36884L,36885L,36886L,36887L,\n36888L,36889L,36890L,36891L,36892L,36893L,36894L,36895L,36896L,36897L,\n36898L,36899L,36900L,36901L,36902L,36903L,36904L,36905L,36906L,36907L,\n36908L,36909L,36910L,36911L,36912L,36913L,36914L,36915L,36916L,36917L,\n36918L,36919L,36920L,36921L,36922L,36923L,36924L,36925L,36926L,36927L,\n36928L,36929L,36930L,36931L,36932L,36933L,36934L,36935L,36936L,36937L,\n36938L,36939L,36940L,36941L,36942L,36943L,36944L,36945L,36946L,36947L,\n36948L,36949L,36950L,36951L,36952L,36953L,36954L,36955L,36956L,36957L,\n36958L,36959L,36960L,36961L,36962L,36963L,36964L,36965L,36966L,36967L,\n36968L,36969L,36970L,36971L,36972L,36973L,36974L,36975L,36976L,36977L,\n36978L,36979L,36980L,36981L,36982L,36983L,36984L,36985L,36986L,36987L,\n36988L,36989L,36990L,36991L,36992L,36993L,36994L,36995L,36996L,36997L,\n36998L,36999L,37000L,37001L,37002L,37003L,37004L,37005L,37006L,37007L,\n37008L,37009L,37010L,37011L,37012L,37013L,37014L,37015L,37016L,37017L,\n37018L,37019L,37020L,37021L,37022L,37023L,37024L,37025L,37026L,37027L,\n37028L,37029L,37030L,37031L,37032L,37033L,37034L,37035L,37036L,37037L,\n37038L,37039L,37040L,37041L,37042L,37043L,37044L,37045L,37046L,37047L,\n37048L,37049L,37050L,37051L,37052L,37053L,37054L,37055L,37056L,37057L,\n37058L,37059L,37060L,37061L,37062L,37063L,37064L,37065L,37066L,37067L,\n37068L,37069L,37070L,37071L,37072L,37073L,37074L,37075L,37076L,37077L,\n37078L,37079L,37080L,37081L,37082L,37083L,37084L,37085L,37086L,37087L,\n37088L,37089L,37090L,37091L,37092L,37093L,37094L,37095L,37096L,37097L,\n37098L,37099L,37100L,37101L,37102L,37103L,37104L,37105L,37106L,37107L,\n37108L,37109L,37110L,37111L,37112L,37113L,37114L,37115L,37116L,37117L,\n37118L,37119L,37120L,37121L,37122L,37123L,37124L,37125L,37126L,37127L,\n37128L,37129L,37130L,37131L,37132L,37133L,37134L,37135L,37136L,37137L,\n37138L,37139L,37140L,37141L,37142L,37143L,37144L,37145L,37146L,37147L,\n37148L,37149L,37150L,37151L,37152L,37153L,37154L,37155L,37156L,37157L,\n37158L,37159L,37160L,37161L,37162L,37163L,37164L,37165L,37166L,37167L,\n37168L,37169L,37170L,37171L,37172L,37173L,37174L,37175L,37176L,37177L,\n37178L,37179L,37180L,37181L,37182L,37183L,37184L,37185L,37186L,37187L,\n37188L,37189L,37190L,37191L,37192L,37193L,37194L,37195L,37196L,37197L,\n37198L,37199L,37200L,37201L,37202L,37203L,37204L,37205L,37206L,37207L,\n37208L,37209L,37210L,37211L,37212L,37213L,37214L,37215L,37216L,37217L,\n37218L,37219L,37220L,37221L,37222L,37223L,37224L,37225L,37226L,37227L,\n37228L,37229L,37230L,37231L,37232L,37233L,37234L,37235L,37236L,37237L,\n37238L,37239L,37240L,37241L,37242L,37243L,37244L,37245L,37246L,37247L,\n37248L,37249L,37250L,37251L,37252L,37253L,37254L,37255L,37256L,37257L,\n37258L,37259L,37260L,37261L,37262L,37263L,37264L,37265L,37266L,37267L,\n37268L,37269L,37270L,37271L,37272L,37273L,37274L,37275L,37276L,37277L,\n37278L,37279L,37280L,37281L,37282L,37283L,37284L,37285L,37286L,37287L,\n37288L,37289L,37290L,37291L,37292L,37293L,37294L,37295L,37296L,37297L,\n37298L,37299L,37300L,37301L,37302L,37303L,37304L,37305L,37306L,37307L,\n37308L,37309L,37310L,37311L,37312L,37313L,37314L,37315L,37316L,37317L,\n37318L,37319L,37320L,37321L,37322L,37323L,37324L,37325L,37326L,37327L,\n37328L,37329L,37330L,37331L,37332L,37333L,37334L,37335L,37336L,37337L,\n37338L,37339L,37340L,37341L,37342L,37343L,37344L,37345L,37346L,37347L,\n37348L,37349L,37350L,37351L,37352L,37353L,37354L,37355L,37356L,37357L,\n37358L,37359L,37360L,37361L,37362L,37363L,37364L,37365L,37366L,37367L,\n37368L,37369L,37370L,37371L,37372L,37373L,37374L,37375L,37376L,37377L,\n37378L,37379L,37380L,37381L,37382L,37383L,37384L,37385L,37386L,37387L,\n37388L,37389L,37390L,37391L,37392L,37393L,37394L,37395L,37396L,37397L,\n37398L,37399L,37400L,37401L,37402L,37403L,37404L,37405L,37406L,37407L,\n37408L,37409L,37410L,37411L,37412L,37413L,37414L,37415L,37416L,37417L,\n37418L,37419L,37420L,37421L,37422L,37423L,37424L,37425L,37426L,37427L,\n37428L,37429L,37430L,37431L,37432L,37433L,37434L,37435L,37436L,37437L,\n37438L,37439L,37440L,37441L,37442L,37443L,37444L,37445L,37446L,37447L,\n37448L,37449L,37450L,37451L,37452L,37453L,37454L,37455L,37456L,37457L,\n37458L,37459L,37460L,37461L,37462L,37463L,37464L,37465L,37466L,37467L,\n37468L,37469L,37470L,37471L,37472L,37473L,37474L,37475L,37476L,37477L,\n37478L,37479L,37480L,37481L,37482L,37483L,37484L,37485L,37486L,37487L,\n37488L,37489L,37490L,37491L,37492L,37493L,37494L,37495L,37496L,37497L,\n37498L,37499L,37500L,37501L,37502L,37503L,37504L,37505L,37506L,37507L,\n37508L,37509L,37510L,37511L,37512L,37513L,37514L,37515L,37516L,37517L,\n37518L,37519L,37520L,37521L,37522L,37523L,37524L,37525L,37526L,37527L,\n37528L,37529L,37530L,37531L,37532L,37533L,37534L,37535L,37536L,37537L,\n37538L,37539L,37540L,37541L,37542L,37543L,37544L,37545L,37546L,37547L,\n37548L,37549L,37550L,37551L,37552L,37553L,37554L,37555L,37556L,37557L,\n37558L,37559L,37560L,37561L,37562L,37563L,37564L,37565L,37566L,37567L,\n37568L,37569L,37570L,37571L,37572L,37573L,37574L,37575L,37576L,37577L,\n37578L,37579L,37580L,37581L,37582L,37583L,37584L,37585L,37586L,37587L,\n37588L,37589L,37590L,37591L,37592L,37593L,37594L,37595L,37596L,37597L,\n37598L,37599L,37600L,37601L,37602L,37603L,37604L,37605L,37606L,37607L,\n37608L,37609L,37610L,37611L,37612L,37613L,37614L,37615L,37616L,37617L,\n37618L,37619L,37620L,37621L,37622L,37623L,37624L,37625L,37626L,37627L,\n37628L,37629L,37630L,37631L,37632L,37633L,37634L,37635L,37636L,37637L,\n37638L,37639L,37640L,37641L,37642L,37643L,37644L,37645L,37646L,37647L,\n37648L,37649L,37650L,37651L,37652L,37653L,37654L,37655L,37656L,37657L,\n37658L,37659L,37660L,37661L,37662L,37663L,37664L,37665L,37666L,37667L,\n37668L,37669L,37670L,37671L,37672L,37673L,37674L,37675L,37676L,37677L,\n37678L,37679L,37680L,37681L,37682L,37683L,37684L,37685L,37686L,37687L,\n37688L,37689L,37690L,37691L,37692L,37693L,37694L,37695L,37696L,37697L,\n37698L,37699L,37700L,37701L,37702L,37703L,37704L,37705L,37706L,37707L,\n37708L,37709L,37710L,37711L,37712L,37713L,37714L,37715L,37716L,37717L,\n37718L,37719L,37720L,37721L,37722L,37723L,37724L,37725L,37726L,37727L,\n37728L,37729L,37730L,37731L,37732L,37733L,37734L,37735L,37736L,37737L,\n37738L,37739L,37740L,37741L,37742L,37743L,37744L,37745L,37746L,37747L,\n37748L,37749L,37750L,37751L,37752L,37753L,37754L,37755L,37756L,37757L,\n37758L,37759L,37760L,37761L,37762L,37763L,37764L,37765L,37766L,37767L,\n37768L,37769L,37770L,37771L,37772L,37773L,37774L,37775L,37776L,37777L,\n37778L,37779L,37780L,37781L,37782L,37783L,37784L,37785L,37786L,37787L,\n37788L,37789L,37790L,37791L,37792L,37793L,37794L,37795L,37796L,37797L,\n37798L,37799L,37800L,37801L,37802L,37803L,37804L,37805L,37806L,37807L,\n37808L,37809L,37810L,37811L,37812L,37813L,37814L,37815L,37816L,37817L,\n37818L,37819L,37820L,37821L,37822L,37823L,37824L,37825L,37826L,37827L,\n37828L,37829L,37830L,37831L,37832L,37833L,37834L,37835L,37836L,37837L,\n37838L,37839L,37840L,37841L,37842L,37843L,37844L,37845L,37846L,37847L,\n37848L,37849L,37850L,37851L,37852L,37853L,37854L,37855L,37856L,37857L,\n37858L,37859L,37860L,37861L,37862L,37863L,37864L,37865L,37866L,37867L,\n37868L,37869L,37870L,37871L,37872L,37873L,37874L,37875L,37876L,37877L,\n37878L,37879L,37880L,37881L,37882L,37883L,37884L,37885L,37886L,37887L,\n37888L,37889L,37890L,37891L,37892L,37893L,37894L,37895L,37896L,37897L,\n37898L,37899L,37900L,37901L,37902L,37903L,37904L,37905L,37906L,37907L,\n37908L,37909L,37910L,37911L,37912L,37913L,37914L,37915L,37916L,37917L,\n37918L,37919L,37920L,37921L,37922L,37923L,37924L,37925L,37926L,37927L,\n37928L,37929L,37930L,37931L,37932L,37933L,37934L,37935L,37936L,37937L,\n37938L,37939L,37940L,37941L,37942L,37943L,37944L,37945L,37946L,37947L,\n37948L,37949L,37950L,37951L,37952L,37953L,37954L,37955L,37956L,37957L,\n37958L,37959L,37960L,37961L,37962L,37963L,37964L,37965L,37966L,37967L,\n37968L,37969L,37970L,37971L,37972L,37973L,37974L,37975L,37976L,37977L,\n37978L,37979L,37980L,37981L,37982L,37983L,37984L,37985L,37986L,37987L,\n37988L,37989L,37990L,37991L,37992L,37993L,37994L,37995L,37996L,37997L,\n37998L,37999L,38000L,38001L,38002L,38003L,38004L,38005L,38006L,38007L,\n38008L,38009L,38010L,38011L,38012L,38013L,38014L,38015L,38016L,38017L,\n38018L,38019L,38020L,38021L,38022L,38023L,38024L,38025L,38026L,38027L,\n38028L,38029L,38030L,38031L,38032L,38033L,38034L,38035L,38036L,38037L,\n38038L,38039L,38040L,38041L,38042L,38043L,38044L,38045L,38046L,38047L,\n38048L,38049L,38050L,38051L,38052L,38053L,38054L,38055L,38056L,38057L,\n38058L,38059L,38060L,38061L,38062L,38063L,38064L,38065L,38066L,38067L,\n38068L,38069L,38070L,38071L,38072L,38073L,38074L,38075L,38076L,38077L,\n38078L,38079L,38080L,38081L,38082L,38083L,38084L,38085L,38086L,38087L,\n38088L,38089L,38090L,38091L,38092L,38093L,38094L,38095L,38096L,38097L,\n38098L,38099L,38100L,38101L,38102L,38103L,38104L,38105L,38106L,38107L,\n38108L,38109L,38110L,38111L,38112L,38113L,38114L,38115L,38116L,38117L,\n38118L,38119L,38120L,38121L,38122L,38123L,38124L,38125L,38126L,38127L,\n38128L,38129L,38130L,38131L,38132L,38133L,38134L,38135L,38136L,38137L,\n38138L,38139L,38140L,38141L,38142L,38143L,38144L,38145L,38146L,38147L,\n38148L,38149L,38150L,38151L,38152L,38153L,38154L,38155L,38156L,38157L,\n38158L,38159L,38160L,38161L,38162L,38163L,38164L,38165L,38166L,38167L,\n38168L,38169L,38170L,38171L,38172L,38173L,38174L,38175L,38176L,38177L,\n38178L,38179L,38180L,38181L,38182L,38183L,38184L,38185L,38186L,38187L,\n38188L,38189L,38190L,38191L,38192L,38193L,38194L,38195L,38196L,38197L,\n38198L,38199L,38200L,38201L,38202L,38203L,38204L,38205L,38206L,38207L,\n38208L,38209L,38210L,38211L,38212L,38213L,38214L,38215L,38216L,38217L,\n38218L,38219L,38220L,38221L,38222L,38223L,38224L,38225L,38226L,38227L,\n38228L,38229L,38230L,38231L,38232L,38233L,38234L,38235L,38236L,38237L,\n38238L,38239L,38240L,38241L,38242L,38243L,38244L,38245L,38246L,38247L,\n38248L,38249L,38250L,38251L,38252L,38253L,38254L,38255L,38256L,38257L,\n38258L,38259L,38260L,38261L,38262L,38263L,38264L,38265L,38266L,38267L,\n38268L,38269L,38270L,38271L,38272L,38273L,38274L,38275L,38276L,38277L,\n38278L,38279L,38280L,38281L,38282L,38283L,38284L,38285L,38286L,38287L,\n38288L,38289L,38290L,38291L,38292L,38293L,38294L,38295L,38296L,38297L,\n38298L,38299L,38300L,38301L,38302L,38303L,38304L,38305L,38306L,38307L,\n38308L,38309L,38310L,38311L,38312L,38313L,38314L,38315L,38316L,38317L,\n38318L,38319L,38320L,38321L,38322L,38323L,38324L,38325L,38326L,38327L,\n38328L,38329L,38330L,38331L,38332L,38333L,38334L,38335L,38336L,38337L,\n38338L,38339L,38340L,38341L,38342L,38343L,38344L,38345L,38346L,38347L,\n38348L,38349L,38350L,38351L,38352L,38353L,38354L,38355L,38356L,38357L,\n38358L,38359L,38360L,38361L,38362L,38363L,38364L,38365L,38366L,38367L,\n38368L,38369L,38370L,38371L,38372L,38373L,38374L,38375L,38376L,38377L,\n38378L,38379L,38380L,38381L,38382L,38383L,38384L,38385L,38386L,38387L,\n38388L,38389L,38390L,38391L,38392L,38393L,38394L,38395L,38396L,38397L,\n38398L,38399L,38400L,38401L,38402L,38403L,38404L,38405L,38406L,38407L,\n38408L,38409L,38410L,38411L,38412L,38413L,38414L,38415L,38416L,38417L,\n38418L,38419L,38420L,38421L,38422L,38423L,38424L,38425L,38426L,38427L,\n38428L,38429L,38430L,38431L,38432L,38433L,38434L,38435L,38436L,38437L,\n38438L,38439L,38440L,38441L,38442L,38443L,38444L,38445L,38446L,38447L,\n38448L,38449L,38450L,38451L,38452L,38453L,38454L,38455L,38456L,38457L,\n38458L,38459L,38460L,38461L,38462L,38463L,38464L,38465L,38466L,38467L,\n38468L,38469L,38470L,38471L,38472L,38473L,38474L,38475L,38476L,38477L,\n38478L,38479L,38480L,38481L,38482L,38483L,38484L,38485L,38486L,38487L,\n38488L,38489L,38490L,38491L,38492L,38493L,38494L,38495L,38496L,38497L,\n38498L,38499L,38500L,38501L,38502L,38503L,38504L,38505L,38506L,38507L,\n38508L,38509L,38510L,38511L,38512L,38513L,38514L,38515L,38516L,38517L,\n38518L,38519L,38520L,38521L,38522L,38523L,38524L,38525L,38526L,38527L,\n38528L,38529L,38530L,38531L,38532L,38533L,38534L,38535L,38536L,38537L,\n38538L,38539L,38540L,38541L,38542L,38543L,38544L,38545L,38546L,38547L,\n38548L,38549L,38550L,38551L,38552L,38553L,38554L,38555L,38556L,38557L,\n38558L,38559L,38560L,38561L,38562L,38563L,38564L,38565L,38566L,38567L,\n38568L,38569L,38570L,38571L,38572L,38573L,38574L,38575L,38576L,38577L,\n38578L,38579L,38580L,38581L,38582L,38583L,38584L,38585L,38586L,38587L,\n38588L,38589L,38590L,38591L,38592L,38593L,38594L,38595L,38596L,38597L,\n38598L,38599L,38600L,38601L,38602L,38603L,38604L,38605L,38606L,38607L,\n38608L,38609L,38610L,38611L,38612L,38613L,38614L,38615L,38616L,38617L,\n38618L,38619L,38620L,38621L,38622L,38623L,38624L,38625L,38626L,38627L,\n38628L,38629L,38630L,38631L,38632L,38633L,38634L,38635L,38636L,38637L,\n38638L,38639L,38640L,38641L,38642L,38643L,38644L,38645L,38646L,38647L,\n38648L,38649L,38650L,38651L,38652L,38653L,38654L,38655L,38656L,38657L,\n38658L,38659L,38660L,38661L,38662L,38663L,38664L,38665L,38666L,38667L,\n38668L,38669L,38670L,38671L,38672L,38673L,38674L,38675L,38676L,38677L,\n38678L,38679L,38680L,38681L,38682L,38683L,38684L,38685L,38686L,38687L,\n38688L,38689L,38690L,38691L,38692L,38693L,38694L,38695L,38696L,38697L,\n38698L,38699L,38700L,38701L,38702L,38703L,38704L,38705L,38706L,38707L,\n38708L,38709L,38710L,38711L,38712L,38713L,38714L,38715L,38716L,38717L,\n38718L,38719L,38720L,38721L,38722L,38723L,38724L,38725L,38726L,38727L,\n38728L,38729L,38730L,38731L,38732L,38733L,38734L,38735L,38736L,38737L,\n38738L,38739L,38740L,38741L,38742L,38743L,38744L,38745L,38746L,38747L,\n38748L,38749L,38750L,38751L,38752L,38753L,38754L,38755L,38756L,38757L,\n38758L,38759L,38760L,38761L,38762L,38763L,38764L,38765L,38766L,38767L,\n38768L,38769L,38770L,38771L,38772L,38773L,38774L,38775L,38776L,38777L,\n38778L,38779L,38780L,38781L,38782L,38783L,38784L,38785L,38786L,38787L,\n38788L,38789L,38790L,38791L,38792L,38793L,38794L,38795L,38796L,38797L,\n38798L,38799L,38800L,38801L,38802L,38803L,38804L,38805L,38806L,38807L,\n38808L,38809L,38810L,38811L,38812L,38813L,38814L,38815L,38816L,38817L,\n38818L,38819L,38820L,38821L,38822L,38823L,38824L,38825L,38826L,38827L,\n38828L,38829L,38830L,38831L,38832L,38833L,38834L,38835L,38836L,38837L,\n38838L,38839L,38840L,38841L,38842L,38843L,38844L,38845L,38846L,38847L,\n38848L,38849L,38850L,38851L,38852L,38853L,38854L,38855L,38856L,38857L,\n38858L,38859L,38860L,38861L,38862L,38863L,38864L,38865L,38866L,38867L,\n38868L,38869L,38870L,38871L,38872L,38873L,38874L,38875L,38876L,38877L,\n38878L,38879L,38880L,38881L,38882L,38883L,38884L,38885L,38886L,38887L,\n38888L,38889L,38890L,38891L,38892L,38893L,38894L,38895L,38896L,38897L,\n38898L,38899L,38900L,38901L,38902L,38903L,38904L,38905L,38906L,38907L,\n38908L,38909L,38910L,38911L,38912L,38913L,38914L,38915L,38916L,38917L,\n38918L,38919L,38920L,38921L,38922L,38923L,38924L,38925L,38926L,38927L,\n38928L,38929L,38930L,38931L,38932L,38933L,38934L,38935L,38936L,38937L,\n38938L,38939L,38940L,38941L,38942L,38943L,38944L,38945L,38946L,38947L,\n38948L,38949L,38950L,38951L,38952L,38953L,38954L,38955L,38956L,38957L,\n38958L,38959L,38960L,38961L,38962L,38963L,38964L,38965L,38966L,38967L,\n38968L,38969L,38970L,38971L,38972L,38973L,38974L,38975L,38976L,38977L,\n38978L,38979L,38980L,38981L,38982L,38983L,38984L,38985L,38986L,38987L,\n38988L,38989L,38990L,38991L,38992L,38993L,38994L,38995L,38996L,38997L,\n38998L,38999L,39000L,39001L,39002L,39003L,39004L,39005L,39006L,39007L,\n39008L,39009L,39010L,39011L,39012L,39013L,39014L,39015L,39016L,39017L,\n39018L,39019L,39020L,39021L,39022L,39023L,39024L,39025L,39026L,39027L,\n39028L,39029L,39030L,39031L,39032L,39033L,39034L,39035L,39036L,39037L,\n39038L,39039L,39040L,39041L,39042L,39043L,39044L,39045L,39046L,39047L,\n39048L,39049L,39050L,39051L,39052L,39053L,39054L,39055L,39056L,39057L,\n39058L,39059L,39060L,39061L,39062L,39063L,39064L,39065L,39066L,39067L,\n39068L,39069L,39070L,39071L,39072L,39073L,39074L,39075L,39076L,39077L,\n39078L,39079L,39080L,39081L,39082L,39083L,39084L,39085L,39086L,39087L,\n39088L,39089L,39090L,39091L,39092L,39093L,39094L,39095L,39096L,39097L,\n39098L,39099L,39100L,39101L,39102L,39103L,39104L,39105L,39106L,39107L,\n39108L,39109L,39110L,39111L,39112L,39113L,39114L,39115L,39116L,39117L,\n39118L,39119L,39120L,39121L,39122L,39123L,39124L,39125L,39126L,39127L,\n39128L,39129L,39130L,39131L,39132L,39133L,39134L,39135L,39136L,39137L,\n39138L,39139L,39140L,39141L,39142L,39143L,39144L,39145L,39146L,39147L,\n39148L,39149L,39150L,39151L,39152L,39153L,39154L,39155L,39156L,39157L,\n39158L,39159L,39160L,39161L,39162L,39163L,39164L,39165L,39166L,39167L,\n39168L,39169L,39170L,39171L,39172L,39173L,39174L,39175L,39176L,39177L,\n39178L,39179L,39180L,39181L,39182L,39183L,39184L,39185L,39186L,39187L,\n39188L,39189L,39190L,39191L,39192L,39193L,39194L,39195L,39196L,39197L,\n39198L,39199L,39200L,39201L,39202L,39203L,39204L,39205L,39206L,39207L,\n39208L,39209L,39210L,39211L,39212L,39213L,39214L,39215L,39216L,39217L,\n39218L,39219L,39220L,39221L,39222L,39223L,39224L,39225L,39226L,39227L,\n39228L,39229L,39230L,39231L,39232L,39233L,39234L,39235L,39236L,39237L,\n39238L,39239L,39240L,39241L,39242L,39243L,39244L,39245L,39246L,39247L,\n39248L,39249L,39250L,39251L,39252L,39253L,39254L,39255L,39256L,39257L,\n39258L,39259L,39260L,39261L,39262L,39263L,39264L,39265L,39266L,39267L,\n39268L,39269L,39270L,39271L,39272L,39273L,39274L,39275L,39276L,39277L,\n39278L,39279L,39280L,39281L,39282L,39283L,39284L,39285L,39286L,39287L,\n39288L,39289L,39290L,39291L,39292L,39293L,39294L,39295L,39296L,39297L,\n39298L,39299L,39300L,39301L,39302L,39303L,39304L,39305L,39306L,39307L,\n39308L,39309L,39310L,39311L,39312L,39313L,39314L,39315L,39316L,39317L,\n39318L,39319L,39320L,39321L,39322L,39323L,39324L,39325L,39326L,39327L,\n39328L,39329L,39330L,39331L,39332L,39333L,39334L,39335L,39336L,39337L,\n39338L,39339L,39340L,39341L,39342L,39343L,39344L,39345L,39346L,39347L,\n39348L,39349L,39350L,39351L,39352L,39353L,39354L,39355L,39356L,39357L,\n39358L,39359L,39360L,39361L,39362L,39363L,39364L,39365L,39366L,39367L,\n39368L,39369L,39370L,39371L,39372L,39373L,39374L,39375L,39376L,39377L,\n39378L,39379L,39380L,39381L,39382L,39383L,39384L,39385L,39386L,39387L,\n39388L,39389L,39390L,39391L,39392L,39393L,39394L,39395L,39396L,39397L,\n39398L,39399L,39400L,39401L,39402L,39403L,39404L,39405L,39406L,39407L,\n39408L,39409L,39410L,39411L,39412L,39413L,39414L,39415L,39416L,39417L,\n39418L,39419L,39420L,39421L,39422L,39423L,39424L,39425L,39426L,39427L,\n39428L,39429L,39430L,39431L,39432L,39433L,39434L,39435L,39436L,39437L,\n39438L,39439L,39440L,39441L,39442L,39443L,39444L,39445L,39446L,39447L,\n39448L,39449L,39450L,39451L,39452L,39453L,39454L,39455L,39456L,39457L,\n39458L,39459L,39460L,39461L,39462L,39463L,39464L,39465L,39466L,39467L,\n39468L,39469L,39470L,39471L,39472L,39473L,39474L,39475L,39476L,39477L,\n39478L,39479L,39480L,39481L,39482L,39483L,39484L,39485L,39486L,39487L,\n39488L,39489L,39490L,39491L,39492L,39493L,39494L,39495L,39496L,39497L,\n39498L,39499L,39500L,39501L,39502L,39503L,39504L,39505L,39506L,39507L,\n39508L,39509L,39510L,39511L,39512L,39513L,39514L,39515L,39516L,39517L,\n39518L,39519L,39520L,39521L,39522L,39523L,39524L,39525L,39526L,39527L,\n39528L,39529L,39530L,39531L,39532L,39533L,39534L,39535L,39536L,39537L,\n39538L,39539L,39540L,39541L,39542L,39543L,39544L,39545L,39546L,39547L,\n39548L,39549L,39550L,39551L,39552L,39553L,39554L,39555L,39556L,39557L,\n39558L,39559L,39560L,39561L,39562L,39563L,39564L,39565L,39566L,39567L,\n39568L,39569L,39570L,39571L,39572L,39573L,39574L,39575L,39576L,39577L,\n39578L,39579L,39580L,39581L,39582L,39583L,39584L,39585L,39586L,39587L,\n39588L,39589L,39590L,39591L,39592L,39593L,39594L,39595L,39596L,39597L,\n39598L,39599L,39600L,39601L,39602L,39603L,39604L,39605L,39606L,39607L,\n39608L,39609L,39610L,39611L,39612L,39613L,39614L,39615L,39616L,39617L,\n39618L,39619L,39620L,39621L,39622L,39623L,39624L,39625L,39626L,39627L,\n39628L,39629L,39630L,39631L,39632L,39633L,39634L,39635L,39636L,39637L,\n39638L,39639L,39640L,39641L,39642L,39643L,39644L,39645L,39646L,39647L,\n39648L,39649L,39650L,39651L,39652L,39653L,39654L,39655L,39656L,39657L,\n39658L,39659L,39660L,39661L,39662L,39663L,39664L,39665L,39666L,39667L,\n39668L,39669L,39670L,39671L,39672L,39673L,39674L,39675L,39676L,39677L,\n39678L,39679L,39680L,39681L,39682L,39683L,39684L,39685L,39686L,39687L,\n39688L,39689L,39690L,39691L,39692L,39693L,39694L,39695L,39696L,39697L,\n39698L,39699L,39700L,39701L,39702L,39703L,39704L,39705L,39706L,39707L,\n39708L,39709L,39710L,39711L,39712L,39713L,39714L,39715L,39716L,39717L,\n39718L,39719L,39720L,39721L,39722L,39723L,39724L,39725L,39726L,39727L,\n39728L,39729L,39730L,39731L,39732L,39733L,39734L,39735L,39736L,39737L,\n39738L,39739L,39740L,39741L,39742L,39743L,39744L,39745L,39746L,39747L,\n39748L,39749L,39750L,39751L,39752L,39753L,39754L,39755L,39756L,39757L,\n39758L,39759L,39760L,39761L,39762L,39763L,39764L,39765L,39766L,39767L,\n39768L,39769L,39770L,39771L,39772L,39773L,39774L,39775L,39776L,39777L,\n39778L,39779L,39780L,39781L,39782L,39783L,39784L,39785L,39786L,39787L,\n39788L,39789L,39790L,39791L,39792L,39793L,39794L,39795L,39796L,39797L,\n39798L,39799L,39800L,39801L,39802L,39803L,39804L,39805L,39806L,39807L,\n39808L,39809L,39810L,39811L,39812L,39813L,39814L,39815L,39816L,39817L,\n39818L,39819L,39820L,39821L,39822L,39823L,39824L,39825L,39826L,39827L,\n39828L,39829L,39830L,39831L,39832L,39833L,39834L,39835L,39836L,39837L,\n39838L,39839L,39840L,39841L,39842L,39843L,39844L,39845L,39846L,39847L,\n39848L,39849L,39850L,39851L,39852L,39853L,39854L,39855L,39856L,39857L,\n39858L,39859L,39860L,39861L,39862L,39863L,39864L,39865L,39866L,39867L,\n39868L,39869L,39870L,39871L,39872L,39873L,39874L,39875L,39876L,39877L,\n39878L,39879L,39880L,39881L,39882L,39883L,39884L,39885L,39886L,39887L,\n39888L,39889L,39890L,39891L,39892L,39893L,39894L,39895L,39896L,39897L,\n39898L,39899L,39900L,39901L,39902L,39903L,39904L,39905L,39906L,39907L,\n39908L,39909L,39910L,39911L,39912L,39913L,39914L,39915L,39916L,39917L,\n39918L,39919L,39920L,39921L,39922L,39923L,39924L,39925L,39926L,39927L,\n39928L,39929L,39930L,39931L,39932L,39933L,39934L,39935L,39936L,39937L,\n39938L,39939L,39940L,39941L,39942L,39943L,39944L,39945L,39946L,39947L,\n39948L,39949L,39950L,39951L,39952L,39953L,39954L,39955L,39956L,39957L,\n39958L,39959L,39960L,39961L,39962L,39963L,39964L,39965L,39966L,39967L,\n39968L,39969L,39970L,39971L,39972L,39973L,39974L,39975L,39976L,39977L,\n39978L,39979L,39980L,39981L,39982L,39983L,39984L,39985L,39986L,39987L,\n39988L,39989L,39990L,39991L,39992L,39993L,39994L,39995L,39996L,39997L,\n39998L,39999L,40000L,40001L,40002L,40003L,40004L,40005L,40006L,40007L,\n40008L,40009L,40010L,40011L,40012L,40013L,40014L,40015L,40016L,40017L,\n40018L,40019L,40020L,40021L,40022L,40023L,40024L,40025L,40026L,40027L,\n40028L,40029L,40030L,40031L,40032L,40033L,40034L,40035L,40036L,40037L,\n40038L,40039L,40040L,40041L,40042L,40043L,40044L,40045L,40046L,40047L,\n40048L,40049L,40050L,40051L,40052L,40053L,40054L,40055L,40056L,40057L,\n40058L,40059L,40060L,40061L,40062L,40063L,40064L,40065L,40066L,40067L,\n40068L,40069L,40070L,40071L,40072L,40073L,40074L,40075L,40076L,40077L,\n40078L,40079L,40080L,40081L,40082L,40083L,40084L,40085L,40086L,40087L,\n40088L,40089L,40090L,40091L,40092L,40093L,40094L,40095L,40096L,40097L,\n40098L,40099L,40100L,40101L,40102L,40103L,40104L,40105L,40106L,40107L,\n40108L,40109L,40110L,40111L,40112L,40113L,40114L,40115L,40116L,40117L,\n40118L,40119L,40120L,40121L,40122L,40123L,40124L,40125L,40126L,40127L,\n40128L,40129L,40130L,40131L,40132L,40133L,40134L,40135L,40136L,40137L,\n40138L,40139L,40140L,40141L,40142L,40143L,40144L,40145L,40146L,40147L,\n40148L,40149L,40150L,40151L,40152L,40153L,40154L,40155L,40156L,40157L,\n40158L,40159L,40160L,40161L,40162L,40163L,40164L,40165L,40166L,40167L,\n40168L,40169L,40170L,40171L,40172L,40173L,40174L,40175L,40176L,40177L,\n40178L,40179L,40180L,40181L,40182L,40183L,40184L,40185L,40186L,40187L,\n40188L,40189L,40190L,40191L,40192L,40193L,40194L,40195L,40196L,40197L,\n40198L,40199L,40200L,40201L,40202L,40203L,40204L,40205L,40206L,40207L,\n40208L,40209L,40210L,40211L,40212L,40213L,40214L,40215L,40216L,40217L,\n40218L,40219L,40220L,40221L,40222L,40223L,40224L,40225L,40226L,40227L,\n40228L,40229L,40230L,40231L,40232L,40233L,40234L,40235L,40236L,40237L,\n40238L,40239L,40240L,40241L,40242L,40243L,40244L,40245L,40246L,40247L,\n40248L,40249L,40250L,40251L,40252L,40253L,40254L,40255L,40256L,40257L,\n40258L,40259L,40260L,40261L,40262L,40263L,40264L,40265L,40266L,40267L,\n40268L,40269L,40270L,40271L,40272L,40273L,40274L,40275L,40276L,40277L,\n40278L,40279L,40280L,40281L,40282L,40283L,40284L,40285L,40286L,40287L,\n40288L,40289L,40290L,40291L,40292L,40293L,40294L,40295L,40296L,40297L,\n40298L,40299L,40300L,40301L,40302L,40303L,40304L,40305L,40306L,40307L,\n40308L,40309L,40310L,40311L,40312L,40313L,40314L,40315L,40316L,40317L,\n40318L,40319L,40320L,40321L,40322L,40323L,40324L,40325L,40326L,40327L,\n40328L,40329L,40330L,40331L,40332L,40333L,40334L,40335L,40336L,40337L,\n40338L,40339L,40340L,40341L,40342L,40343L,40344L,40345L,40346L,40347L,\n40348L,40349L,40350L,40351L,40352L,40353L,40354L,40355L,40356L,40357L,\n40358L,40359L,40360L,40361L,40362L,40363L,40364L,40365L,40366L,40367L,\n40368L,40369L,40370L,40371L,40372L,40373L,40374L,40375L,40376L,40377L,\n40378L,40379L,40380L,40381L,40382L,40383L,40384L,40385L,40386L,40387L,\n40388L,40389L,40390L,40391L,40392L,40393L,40394L,40395L,40396L,40397L,\n40398L,40399L,40400L,40401L,40402L,40403L,40404L,40405L,40406L,40407L,\n40408L,40409L,40410L,40411L,40412L,40413L,40414L,40415L,40416L,40417L,\n40418L,40419L,40420L,40421L,40422L,40423L,40424L,40425L,40426L,40427L,\n40428L,40429L,40430L,40431L,40432L,40433L,40434L,40435L,40436L,40437L,\n40438L,40439L,40440L,40441L,40442L,40443L,40444L,40445L,40446L,40447L,\n40448L,40449L,40450L,40451L,40452L,40453L,40454L,40455L,40456L,40457L,\n40458L,40459L,40460L,40461L,40462L,40463L,40464L,40465L,40466L,40467L,\n40468L,40469L,40470L,40471L,40472L,40473L,40474L,40475L,40476L,40477L,\n40478L,40479L,40480L,40481L,40482L,40483L,40484L,40485L,40486L,40487L,\n40488L,40489L,40490L,40491L,40492L,40493L,40494L,40495L,40496L,40497L,\n40498L,40499L,40500L,40501L,40502L,40503L,40504L,40505L,40506L,40507L,\n40508L,40509L,40510L,40511L,40512L,40513L,40514L,40515L,40516L,40517L,\n40518L,40519L,40520L,40521L,40522L,40523L,40524L,40525L,40526L,40527L,\n40528L,40529L,40530L,40531L,40532L,40533L,40534L,40535L,40536L,40537L,\n40538L,40539L,40540L,40541L,40542L,40543L,40544L,40545L,40546L,40547L,\n40548L,40549L,40550L,40551L,40552L,40553L,40554L,40555L,40556L,40557L,\n40558L,40559L,40560L,40561L,40562L,40563L,40564L,40565L,40566L,40567L,\n40568L,40569L,40570L,40571L,40572L,40573L,40574L,40575L,40576L,40577L,\n40578L,40579L,40580L,40581L,40582L,40583L,40584L,40585L,40586L,40587L,\n40588L,40589L,40590L,40591L,40592L,40593L,40594L,40595L,40596L,40597L,\n40598L,40599L,40600L,40601L,40602L,40603L,40604L,40605L,40606L,40607L,\n40608L,40609L,40610L,40611L,40612L,40613L,40614L,40615L,40616L,40617L,\n40618L,40619L,40620L,40621L,40622L,40623L,40624L,40625L,40626L,40627L,\n40628L,40629L,40630L,40631L,40632L,40633L,40634L,40635L,40636L,40637L,\n40638L,40639L,40640L,40641L,40642L,40643L,40644L,40645L,40646L,40647L,\n40648L,40649L,40650L,40651L,40652L,40653L,40654L,40655L,40656L,40657L,\n40658L,40659L,40660L,40661L,40662L,40663L,40664L,40665L,40666L,40667L,\n40668L,40669L,40670L,40671L,40672L,40673L,40674L,40675L,40676L,40677L,\n40678L,40679L,40680L,40681L,40682L,40683L,40684L,40685L,40686L,40687L,\n40688L,40689L,40690L,40691L,40692L,40693L,40694L,40695L,40696L,40697L,\n40698L,40699L,40700L,40701L,40702L,40703L,40704L,40705L,40706L,40707L,\n40708L,40709L,40710L,40711L,40712L,40713L,40714L,40715L,40716L,40717L,\n40718L,40719L,40720L,40721L,40722L,40723L,40724L,40725L,40726L,40727L,\n40728L,40729L,40730L,40731L,40732L,40733L,40734L,40735L,40736L,40737L,\n40738L,40739L,40740L,40741L,40742L,40743L,40744L,40745L,40746L,40747L,\n40748L,40749L,40750L,40751L,40752L,40753L,40754L,40755L,40756L,40757L,\n40758L,40759L,40760L,40761L,40762L,40763L,40764L,40765L,40766L,40767L,\n40768L,40769L,40770L,40771L,40772L,40773L,40774L,40775L,40776L,40777L,\n40778L,40779L,40780L,40781L,40782L,40783L,40784L,40785L,40786L,40787L,\n40788L,40789L,40790L,40791L,40792L,40793L,40794L,40795L,40796L,40797L,\n40798L,40799L,40800L,40801L,40802L,40803L,40804L,40805L,40806L,40807L,\n40808L,40809L,40810L,40811L,40812L,40813L,40814L,40815L,40816L,40817L,\n40818L,40819L,40820L,40821L,40822L,40823L,40824L,40825L,40826L,40827L,\n40828L,40829L,40830L,40831L,40832L,40833L,40834L,40835L,40836L,40837L,\n40838L,40839L,40840L,40841L,40842L,40843L,40844L,40845L,40846L,40847L,\n40848L,40849L,40850L,40851L,40852L,40853L,40854L,40855L,40856L,40857L,\n40858L,40859L,40860L,40861L,40862L,40863L,40864L,40865L,40866L,40867L,\n40868L,40869L,40870L,40871L,40872L,40873L,40874L,40875L,40876L,40877L,\n40878L,40879L,40880L,40881L,40882L,40883L,40884L,40885L,40886L,40887L,\n40888L,40889L,40890L,40891L,40892L,40893L,40894L,40895L,40896L,40897L,\n40898L,40899L,40900L,40901L,40902L,40903L,40904L,40905L,40906L,40907L,\n40908L,40909L,40910L,40911L,40912L,40913L,40914L,40915L,40916L,40917L,\n40918L,40919L,40920L,40921L,40922L,40923L,40924L,40925L,40926L,40927L,\n40928L,40929L,40930L,40931L,40932L,40933L,40934L,40935L,40936L,40937L,\n40938L,40939L,40940L,40941L,40942L,40943L,40944L,40945L,40946L,40947L,\n40948L,40949L,40950L,40951L,40952L,40953L,40954L,40955L,40956L,40957L,\n40958L,40959L,40960L,40961L,40962L,40963L,40964L,40965L,40966L,40967L,\n40968L,40969L,40970L,40971L,40972L,40973L,40974L,40975L,40976L,40977L,\n40978L,40979L,40980L,40981L,40982L,40983L,40984L,40985L,40986L,40987L,\n40988L,40989L,40990L,40991L,40992L,40993L,40994L,40995L,40996L,40997L,\n40998L,40999L,41000L,41001L,41002L,41003L,41004L,41005L,41006L,41007L,\n41008L,41009L,41010L,41011L,41012L,41013L,41014L,41015L,41016L,41017L,\n41018L,41019L,41020L,41021L,41022L,41023L,41024L,41025L,41026L,41027L,\n41028L,41029L,41030L,41031L,41032L,41033L,41034L,41035L,41036L,41037L,\n41038L,41039L,41040L,41041L,41042L,41043L,41044L,41045L,41046L,41047L,\n41048L,41049L,41050L,41051L,41052L,41053L,41054L,41055L,41056L,41057L,\n41058L,41059L,41060L,41061L,41062L,41063L,41064L,41065L,41066L,41067L,\n41068L,41069L,41070L,41071L,41072L,41073L,41074L,41075L,41076L,41077L,\n41078L,41079L,41080L,41081L,41082L,41083L,41084L,41085L,41086L,41087L,\n41088L,41089L,41090L,41091L,41092L,41093L,41094L,41095L,41096L,41097L,\n41098L,41099L,41100L,41101L,41102L,41103L,41104L,41105L,41106L,41107L,\n41108L,41109L,41110L,41111L,41112L,41113L,41114L,41115L,41116L,41117L,\n41118L,41119L,41120L,41121L,41122L,41123L,41124L,41125L,41126L,41127L,\n41128L,41129L,41130L,41131L,41132L,41133L,41134L,41135L,41136L,41137L,\n41138L,41139L,41140L,41141L,41142L,41143L,41144L,41145L,41146L,41147L,\n41148L,41149L,41150L,41151L,41152L,41153L,41154L,41155L,41156L,41157L,\n41158L,41159L,41160L,41161L,41162L,41163L,41164L,41165L,41166L,41167L,\n41168L,41169L,41170L,41171L,41172L,41173L,41174L,41175L,41176L,41177L,\n41178L,41179L,41180L,41181L,41182L,41183L,41184L,41185L,41186L,41187L,\n41188L,41189L,41190L,41191L,41192L,41193L,41194L,41195L,41196L,41197L,\n41198L,41199L,41200L,41201L,41202L,41203L,41204L,41205L,41206L,41207L,\n41208L,41209L,41210L,41211L,41212L,41213L,41214L,41215L,41216L,41217L,\n41218L,41219L,41220L,41221L,41222L,41223L,41224L,41225L,41226L,41227L,\n41228L,41229L,41230L,41231L,41232L,41233L,41234L,41235L,41236L,41237L,\n41238L,41239L,41240L,41241L,41242L,41243L,41244L,41245L,41246L,41247L,\n41248L,41249L,41250L,41251L,41252L,41253L,41254L,41255L,41256L,41257L,\n41258L,41259L,41260L,41261L,41262L,41263L,41264L,41265L,41266L,41267L,\n41268L,41269L,41270L,41271L,41272L,41273L,41274L,41275L,41276L,41277L,\n41278L,41279L,41280L,41281L,41282L,41283L,41284L,41285L,41286L,41287L,\n41288L,41289L,41290L,41291L,41292L,41293L,41294L,41295L,41296L,41297L,\n41298L,41299L,41300L,41301L,41302L,41303L,41304L,41305L,41306L,41307L,\n41308L,41309L,41310L,41311L,41312L,41313L,41314L,41315L,41316L,41317L,\n41318L,41319L,41320L,41321L,41322L,41323L,41324L,41325L,41326L,41327L,\n41328L,41329L,41330L,41331L,41332L,41333L,41334L,41335L,41336L,41337L,\n41338L,41339L,41340L,41341L,41342L,41343L,41344L,41345L,41346L,41347L,\n41348L,41349L,41350L,41351L,41352L,41353L,41354L,41355L,41356L,41357L,\n41358L,41359L,41360L,41361L,41362L,41363L,41364L,41365L,41366L,41367L,\n41368L,41369L,41370L,41371L,41372L,41373L,41374L,41375L,41376L,41377L,\n41378L,41379L,41380L,41381L,41382L,41383L,41384L,41385L,41386L,41387L,\n41388L,41389L,41390L,41391L,41392L,41393L,41394L,41395L,41396L,41397L,\n41398L,41399L,41400L,41401L,41402L,41403L,41404L,41405L,41406L,41407L,\n41408L,41409L,41410L,41411L,41412L,41413L,41414L,41415L,41416L,41417L,\n41418L,41419L,41420L,41421L,41422L,41423L,41424L,41425L,41426L,41427L,\n41428L,41429L,41430L,41431L,41432L,41433L,41434L,41435L,41436L,41437L,\n41438L,41439L,41440L,41441L,41442L,41443L,41444L,41445L,41446L,41447L,\n41448L,41449L,41450L,41451L,41452L,41453L,41454L,41455L,41456L,41457L,\n41458L,41459L,41460L,41461L,41462L,41463L,41464L,41465L,41466L,41467L,\n41468L,41469L,41470L,41471L,41472L,41473L,41474L,41475L,41476L,41477L,\n41478L,41479L,41480L,41481L,41482L,41483L,41484L,41485L,41486L,41487L,\n41488L,41489L,41490L,41491L,41492L,41493L,41494L,41495L,41496L,41497L,\n41498L,41499L,41500L,41501L,41502L,41503L,41504L,41505L,41506L,41507L,\n41508L,41509L,41510L,41511L,41512L,41513L,41514L,41515L,41516L,41517L,\n41518L,41519L,41520L,41521L,41522L,41523L,41524L,41525L,41526L,41527L,\n41528L,41529L,41530L,41531L,41532L,41533L,41534L,41535L,41536L,41537L,\n41538L,41539L,41540L,41541L,41542L,41543L,41544L,41545L,41546L,41547L,\n41548L,41549L,41550L,41551L,41552L,41553L,41554L,41555L,41556L,41557L,\n41558L,41559L,41560L,41561L,41562L,41563L,41564L,41565L,41566L,41567L,\n41568L,41569L,41570L,41571L,41572L,41573L,41574L,41575L,41576L,41577L,\n41578L,41579L,41580L,41581L,41582L,41583L,41584L,41585L,41586L,41587L,\n41588L,41589L,41590L,41591L,41592L,41593L,41594L,41595L,41596L,41597L,\n41598L,41599L,41600L,41601L,41602L,41603L,41604L,41605L,41606L,41607L,\n41608L,41609L,41610L,41611L,41612L,41613L,41614L,41615L,41616L,41617L,\n41618L,41619L,41620L,41621L,41622L,41623L,41624L,41625L,41626L,41627L,\n41628L,41629L,41630L,41631L,41632L,41633L,41634L,41635L,41636L,41637L,\n41638L,41639L,41640L,41641L,41642L,41643L,41644L,41645L,41646L,41647L,\n41648L,41649L,41650L,41651L,41652L,41653L,41654L,41655L,41656L,41657L,\n41658L,41659L,41660L,41661L,41662L,41663L,41664L,41665L,41666L,41667L,\n41668L,41669L,41670L,41671L,41672L,41673L,41674L,41675L,41676L,41677L,\n41678L,41679L,41680L,41681L,41682L,41683L,41684L,41685L,41686L,41687L,\n41688L,41689L,41690L,41691L,41692L,41693L,41694L,41695L,41696L,41697L,\n41698L,41699L,41700L,41701L,41702L,41703L,41704L,41705L,41706L,41707L,\n41708L,41709L,41710L,41711L,41712L,41713L,41714L,41715L,41716L,41717L,\n41718L,41719L,41720L,41721L,41722L,41723L,41724L,41725L,41726L,41727L,\n41728L,41729L,41730L,41731L,41732L,41733L,41734L,41735L,41736L,41737L,\n41738L,41739L,41740L,41741L,41742L,41743L,41744L,41745L,41746L,41747L,\n41748L,41749L,41750L,41751L,41752L,41753L,41754L,41755L,41756L,41757L,\n41758L,41759L,41760L,41761L,41762L,41763L,41764L,41765L,41766L,41767L,\n41768L,41769L,41770L,41771L,41772L,41773L,41774L,41775L,41776L,41777L,\n41778L,41779L,41780L,41781L,41782L,41783L,41784L,41785L,41786L,41787L,\n41788L,41789L,41790L,41791L,41792L,41793L,41794L,41795L,41796L,41797L,\n41798L,41799L,41800L,41801L,41802L,41803L,41804L,41805L,41806L,41807L,\n41808L,41809L,41810L,41811L,41812L,41813L,41814L,41815L,41816L,41817L,\n41818L,41819L,41820L,41821L,41822L,41823L,41824L,41825L,41826L,41827L,\n41828L,41829L,41830L,41831L,41832L,41833L,41834L,41835L,41836L,41837L,\n41838L,41839L,41840L,41841L,41842L,41843L,41844L,41845L,41846L,41847L,\n41848L,41849L,41850L,41851L,41852L,41853L,41854L,41855L,41856L,41857L,\n41858L,41859L,41860L,41861L,41862L,41863L,41864L,41865L,41866L,41867L,\n41868L,41869L,41870L,41871L,41872L,41873L,41874L,41875L,41876L,41877L,\n41878L,41879L,41880L,41881L,41882L,41883L,41884L,41885L,41886L,41887L,\n41888L,41889L,41890L,41891L,41892L,41893L,41894L,41895L,41896L,41897L,\n41898L,41899L,41900L,41901L,41902L,41903L,41904L,41905L,41906L,41907L,\n41908L,41909L,41910L,41911L,41912L,41913L,41914L,41915L,41916L,41917L,\n41918L,41919L,41920L,41921L,41922L,41923L,41924L,41925L,41926L,41927L,\n41928L,41929L,41930L,41931L,41932L,41933L,41934L,41935L,41936L,41937L,\n41938L,41939L,41940L,41941L,41942L,41943L,41944L,41945L,41946L,41947L,\n41948L,41949L,41950L,41951L,41952L,41953L,41954L,41955L,41956L,41957L,\n41958L,41959L,41960L,41961L,41962L,41963L,41964L,41965L,41966L,41967L,\n41968L,41969L,41970L,41971L,41972L,41973L,41974L,41975L,41976L,41977L,\n41978L,41979L,41980L,41981L,41982L,41983L,41984L,41985L,41986L,41987L,\n41988L,41989L,41990L,41991L,41992L,41993L,41994L,41995L,41996L,41997L,\n41998L,41999L,42000L,42001L,42002L,42003L,42004L,42005L,42006L,42007L,\n42008L,42009L,42010L,42011L,42012L,42013L,42014L,42015L,42016L,42017L,\n42018L,42019L,42020L,42021L,42022L,42023L,42024L,42025L,42026L,42027L,\n42028L,42029L,42030L,42031L,42032L,42033L,42034L,42035L,42036L,42037L,\n42038L,42039L,42040L,42041L,42042L,42043L,42044L,42045L,42046L,42047L,\n42048L,42049L,42050L,42051L,42052L,42053L,42054L,42055L,42056L,42057L,\n42058L,42059L,42060L,42061L,42062L,42063L,42064L,42065L,42066L,42067L,\n42068L,42069L,42070L,42071L,42072L,42073L,42074L,42075L,42076L,42077L,\n42078L,42079L,42080L,42081L,42082L,42083L,42084L,42085L,42086L,42087L,\n42088L,42089L,42090L,42091L,42092L,42093L,42094L,42095L,42096L,42097L,\n42098L,42099L,42100L,42101L,42102L,42103L,42104L,42105L,42106L,42107L,\n42108L,42109L,42110L,42111L,42112L,42113L,42114L,42115L,42116L,42117L,\n42118L,42119L,42120L,42121L,42122L,42123L,42124L,42125L,42126L,42127L,\n42128L,42129L,42130L,42131L,42132L,42133L,42134L,42135L,42136L,42137L,\n42138L,42139L,42140L,42141L,42142L,42143L,42144L,42145L,42146L,42147L,\n42148L,42149L,42150L,42151L,42152L,42153L,42154L,42155L,42156L,42157L,\n42158L,42159L,42160L,42161L,42162L,42163L,42164L,42165L,42166L,42167L,\n42168L,42169L,42170L,42171L,42172L,42173L,42174L,42175L,42176L,42177L,\n42178L,42179L,42180L,42181L,42182L,42183L,42184L,42185L,42186L,42187L,\n42188L,42189L,42190L,42191L,42192L,42193L,42194L,42195L,42196L,42197L,\n42198L,42199L,42200L,42201L,42202L,42203L,42204L,42205L,42206L,42207L,\n42208L,42209L,42210L,42211L,42212L,42213L,42214L,42215L,42216L,42217L,\n42218L,42219L,42220L,42221L,42222L,42223L,42224L,42225L,42226L,42227L,\n42228L,42229L,42230L,42231L,42232L,42233L,42234L,42235L,42236L,42237L,\n42238L,42239L,42240L,42241L,42242L,42243L,42244L,42245L,42246L,42247L,\n42248L,42249L,42250L,42251L,42252L,42253L,42254L,42255L,42256L,42257L,\n42258L,42259L,42260L,42261L,42262L,42263L,42264L,42265L,42266L,42267L,\n42268L,42269L,42270L,42271L,42272L,42273L,42274L,42275L,42276L,42277L,\n42278L,42279L,42280L,42281L,42282L,42283L,42284L,42285L,42286L,42287L,\n42288L,42289L,42290L,42291L,42292L,42293L,42294L,42295L,42296L,42297L,\n42298L,42299L,42300L,42301L,42302L,42303L,42304L,42305L,42306L,42307L,\n42308L,42309L,42310L,42311L,42312L,42313L,42314L,42315L,42316L,42317L,\n42318L,42319L,42320L,42321L,42322L,42323L,42324L,42325L,42326L,42327L,\n42328L,42329L,42330L,42331L,42332L,42333L,42334L,42335L,42336L,42337L,\n42338L,42339L,42340L,42341L,42342L,42343L,42344L,42345L,42346L,42347L,\n42348L,42349L,42350L,42351L,42352L,42353L,42354L,42355L,42356L,42357L,\n42358L,42359L,42360L,42361L,42362L,42363L,42364L,42365L,42366L,42367L,\n42368L,42369L,42370L,42371L,42372L,42373L,42374L,42375L,42376L,42377L,\n42378L,42379L,42380L,42381L,42382L,42383L,42384L,42385L,42386L,42387L,\n42388L,42389L,42390L,42391L,42392L,42393L,42394L,42395L,42396L,42397L,\n42398L,42399L,42400L,42401L,42402L,42403L,42404L,42405L,42406L,42407L,\n42408L,42409L,42410L,42411L,42412L,42413L,42414L,42415L,42416L,42417L,\n42418L,42419L,42420L,42421L,42422L,42423L,42424L,42425L,42426L,42427L,\n42428L,42429L,42430L,42431L,42432L,42433L,42434L,42435L,42436L,42437L,\n42438L,42439L,42440L,42441L,42442L,42443L,42444L,42445L,42446L,42447L,\n42448L,42449L,42450L,42451L,42452L,42453L,42454L,42455L,42456L,42457L,\n42458L,42459L,42460L,42461L,42462L,42463L,42464L,42465L,42466L,42467L,\n42468L,42469L,42470L,42471L,42472L,42473L,42474L,42475L,42476L,42477L,\n42478L,42479L,42480L,42481L,42482L,42483L,42484L,42485L,42486L,42487L,\n42488L,42489L,42490L,42491L,42492L,42493L,42494L,42495L,42496L,42497L,\n42498L,42499L,42500L,42501L,42502L,42503L,42504L,42505L,42506L,42507L,\n42508L,42509L,42510L,42511L,42512L,42513L,42514L,42515L,42516L,42517L,\n42518L,42519L,42520L,42521L,42522L,42523L,42524L,42525L,42526L,42527L,\n42528L,42529L,42530L,42531L,42532L,42533L,42534L,42535L,42536L,42537L,\n42538L,42539L,42540L,42541L,42542L,42543L,42544L,42545L,42546L,42547L,\n42548L,42549L,42550L,42551L,42552L,42553L,42554L,42555L,42556L,42557L,\n42558L,42559L,42560L,42560L,42562L,42562L,42564L,42564L,42566L,42566L,\n42568L,42568L,42570L,42570L,42572L,42572L,42574L,42574L,42576L,42576L,\n42578L,42578L,42580L,42580L,42582L,42582L,42584L,42584L,42586L,42586L,\n42588L,42588L,42590L,42590L,42592L,42592L,42594L,42594L,42596L,42596L,\n42598L,42598L,42600L,42600L,42602L,42602L,42604L,42604L,42606L,42607L,\n42608L,42609L,42610L,42611L,42612L,42613L,42614L,42615L,42616L,42617L,\n42618L,42619L,42620L,42621L,42622L,42623L,42624L,42624L,42626L,42626L,\n42628L,42628L,42630L,42630L,42632L,42632L,42634L,42634L,42636L,42636L,\n42638L,42638L,42640L,42640L,42642L,42642L,42644L,42644L,42646L,42646L,\n42648L,42648L,42650L,42650L,42652L,42653L,42654L,42655L,42656L,42657L,\n42658L,42659L,42660L,42661L,42662L,42663L,42664L,42665L,42666L,42667L,\n42668L,42669L,42670L,42671L,42672L,42673L,42674L,42675L,42676L,42677L,\n42678L,42679L,42680L,42681L,42682L,42683L,42684L,42685L,42686L,42687L,\n42688L,42689L,42690L,42691L,42692L,42693L,42694L,42695L,42696L,42697L,\n42698L,42699L,42700L,42701L,42702L,42703L,42704L,42705L,42706L,42707L,\n42708L,42709L,42710L,42711L,42712L,42713L,42714L,42715L,42716L,42717L,\n42718L,42719L,42720L,42721L,42722L,42723L,42724L,42725L,42726L,42727L,\n42728L,42729L,42730L,42731L,42732L,42733L,42734L,42735L,42736L,42737L,\n42738L,42739L,42740L,42741L,42742L,42743L,42744L,42745L,42746L,42747L,\n42748L,42749L,42750L,42751L,42752L,42753L,42754L,42755L,42756L,42757L,\n42758L,42759L,42760L,42761L,42762L,42763L,42764L,42765L,42766L,42767L,\n42768L,42769L,42770L,42771L,42772L,42773L,42774L,42775L,42776L,42777L,\n42778L,42779L,42780L,42781L,42782L,42783L,42784L,42785L,42786L,42786L,\n42788L,42788L,42790L,42790L,42792L,42792L,42794L,42794L,42796L,42796L,\n42798L,42798L,42800L,42801L,42802L,42802L,42804L,42804L,42806L,42806L,\n42808L,42808L,42810L,42810L,42812L,42812L,42814L,42814L,42816L,42816L,\n42818L,42818L,42820L,42820L,42822L,42822L,42824L,42824L,42826L,42826L,\n42828L,42828L,42830L,42830L,42832L,42832L,42834L,42834L,42836L,42836L,\n42838L,42838L,42840L,42840L,42842L,42842L,42844L,42844L,42846L,42846L,\n42848L,42848L,42850L,42850L,42852L,42852L,42854L,42854L,42856L,42856L,\n42858L,42858L,42860L,42860L,42862L,42862L,42864L,42865L,42866L,42867L,\n42868L,42869L,42870L,42871L,42872L,42873L,42873L,42875L,42875L,42877L,\n42878L,42878L,42880L,42880L,42882L,42882L,42884L,42884L,42886L,42886L,\n42888L,42889L,42890L,42891L,42891L,42893L,42894L,42895L,42896L,42896L,\n42898L,42898L,42948L,42901L,42902L,42902L,42904L,42904L,42906L,42906L,\n42908L,42908L,42910L,42910L,42912L,42912L,42914L,42914L,42916L,42916L,\n42918L,42918L,42920L,42920L,42922L,42923L,42924L,42925L,42926L,42927L,\n42928L,42929L,42930L,42931L,42932L,42932L,42934L,42934L,42936L,42936L,\n42938L,42938L,42940L,42940L,42942L,42942L,42944L,42945L,42946L,42946L,\n42948L,42949L,42950L,42951L,42952L,42953L,42954L,42955L,42956L,42957L,\n42958L,42959L,42960L,42961L,42962L,42963L,42964L,42965L,42966L,42967L,\n42968L,42969L,42970L,42971L,42972L,42973L,42974L,42975L,42976L,42977L,\n42978L,42979L,42980L,42981L,42982L,42983L,42984L,42985L,42986L,42987L,\n42988L,42989L,42990L,42991L,42992L,42993L,42994L,42995L,42996L,42997L,\n42998L,42999L,43000L,43001L,43002L,43003L,43004L,43005L,43006L,43007L,\n43008L,43009L,43010L,43011L,43012L,43013L,43014L,43015L,43016L,43017L,\n43018L,43019L,43020L,43021L,43022L,43023L,43024L,43025L,43026L,43027L,\n43028L,43029L,43030L,43031L,43032L,43033L,43034L,43035L,43036L,43037L,\n43038L,43039L,43040L,43041L,43042L,43043L,43044L,43045L,43046L,43047L,\n43048L,43049L,43050L,43051L,43052L,43053L,43054L,43055L,43056L,43057L,\n43058L,43059L,43060L,43061L,43062L,43063L,43064L,43065L,43066L,43067L,\n43068L,43069L,43070L,43071L,43072L,43073L,43074L,43075L,43076L,43077L,\n43078L,43079L,43080L,43081L,43082L,43083L,43084L,43085L,43086L,43087L,\n43088L,43089L,43090L,43091L,43092L,43093L,43094L,43095L,43096L,43097L,\n43098L,43099L,43100L,43101L,43102L,43103L,43104L,43105L,43106L,43107L,\n43108L,43109L,43110L,43111L,43112L,43113L,43114L,43115L,43116L,43117L,\n43118L,43119L,43120L,43121L,43122L,43123L,43124L,43125L,43126L,43127L,\n43128L,43129L,43130L,43131L,43132L,43133L,43134L,43135L,43136L,43137L,\n43138L,43139L,43140L,43141L,43142L,43143L,43144L,43145L,43146L,43147L,\n43148L,43149L,43150L,43151L,43152L,43153L,43154L,43155L,43156L,43157L,\n43158L,43159L,43160L,43161L,43162L,43163L,43164L,43165L,43166L,43167L,\n43168L,43169L,43170L,43171L,43172L,43173L,43174L,43175L,43176L,43177L,\n43178L,43179L,43180L,43181L,43182L,43183L,43184L,43185L,43186L,43187L,\n43188L,43189L,43190L,43191L,43192L,43193L,43194L,43195L,43196L,43197L,\n43198L,43199L,43200L,43201L,43202L,43203L,43204L,43205L,43206L,43207L,\n43208L,43209L,43210L,43211L,43212L,43213L,43214L,43215L,43216L,43217L,\n43218L,43219L,43220L,43221L,43222L,43223L,43224L,43225L,43226L,43227L,\n43228L,43229L,43230L,43231L,43232L,43233L,43234L,43235L,43236L,43237L,\n43238L,43239L,43240L,43241L,43242L,43243L,43244L,43245L,43246L,43247L,\n43248L,43249L,43250L,43251L,43252L,43253L,43254L,43255L,43256L,43257L,\n43258L,43259L,43260L,43261L,43262L,43263L,43264L,43265L,43266L,43267L,\n43268L,43269L,43270L,43271L,43272L,43273L,43274L,43275L,43276L,43277L,\n43278L,43279L,43280L,43281L,43282L,43283L,43284L,43285L,43286L,43287L,\n43288L,43289L,43290L,43291L,43292L,43293L,43294L,43295L,43296L,43297L,\n43298L,43299L,43300L,43301L,43302L,43303L,43304L,43305L,43306L,43307L,\n43308L,43309L,43310L,43311L,43312L,43313L,43314L,43315L,43316L,43317L,\n43318L,43319L,43320L,43321L,43322L,43323L,43324L,43325L,43326L,43327L,\n43328L,43329L,43330L,43331L,43332L,43333L,43334L,43335L,43336L,43337L,\n43338L,43339L,43340L,43341L,43342L,43343L,43344L,43345L,43346L,43347L,\n43348L,43349L,43350L,43351L,43352L,43353L,43354L,43355L,43356L,43357L,\n43358L,43359L,43360L,43361L,43362L,43363L,43364L,43365L,43366L,43367L,\n43368L,43369L,43370L,43371L,43372L,43373L,43374L,43375L,43376L,43377L,\n43378L,43379L,43380L,43381L,43382L,43383L,43384L,43385L,43386L,43387L,\n43388L,43389L,43390L,43391L,43392L,43393L,43394L,43395L,43396L,43397L,\n43398L,43399L,43400L,43401L,43402L,43403L,43404L,43405L,43406L,43407L,\n43408L,43409L,43410L,43411L,43412L,43413L,43414L,43415L,43416L,43417L,\n43418L,43419L,43420L,43421L,43422L,43423L,43424L,43425L,43426L,43427L,\n43428L,43429L,43430L,43431L,43432L,43433L,43434L,43435L,43436L,43437L,\n43438L,43439L,43440L,43441L,43442L,43443L,43444L,43445L,43446L,43447L,\n43448L,43449L,43450L,43451L,43452L,43453L,43454L,43455L,43456L,43457L,\n43458L,43459L,43460L,43461L,43462L,43463L,43464L,43465L,43466L,43467L,\n43468L,43469L,43470L,43471L,43472L,43473L,43474L,43475L,43476L,43477L,\n43478L,43479L,43480L,43481L,43482L,43483L,43484L,43485L,43486L,43487L,\n43488L,43489L,43490L,43491L,43492L,43493L,43494L,43495L,43496L,43497L,\n43498L,43499L,43500L,43501L,43502L,43503L,43504L,43505L,43506L,43507L,\n43508L,43509L,43510L,43511L,43512L,43513L,43514L,43515L,43516L,43517L,\n43518L,43519L,43520L,43521L,43522L,43523L,43524L,43525L,43526L,43527L,\n43528L,43529L,43530L,43531L,43532L,43533L,43534L,43535L,43536L,43537L,\n43538L,43539L,43540L,43541L,43542L,43543L,43544L,43545L,43546L,43547L,\n43548L,43549L,43550L,43551L,43552L,43553L,43554L,43555L,43556L,43557L,\n43558L,43559L,43560L,43561L,43562L,43563L,43564L,43565L,43566L,43567L,\n43568L,43569L,43570L,43571L,43572L,43573L,43574L,43575L,43576L,43577L,\n43578L,43579L,43580L,43581L,43582L,43583L,43584L,43585L,43586L,43587L,\n43588L,43589L,43590L,43591L,43592L,43593L,43594L,43595L,43596L,43597L,\n43598L,43599L,43600L,43601L,43602L,43603L,43604L,43605L,43606L,43607L,\n43608L,43609L,43610L,43611L,43612L,43613L,43614L,43615L,43616L,43617L,\n43618L,43619L,43620L,43621L,43622L,43623L,43624L,43625L,43626L,43627L,\n43628L,43629L,43630L,43631L,43632L,43633L,43634L,43635L,43636L,43637L,\n43638L,43639L,43640L,43641L,43642L,43643L,43644L,43645L,43646L,43647L,\n43648L,43649L,43650L,43651L,43652L,43653L,43654L,43655L,43656L,43657L,\n43658L,43659L,43660L,43661L,43662L,43663L,43664L,43665L,43666L,43667L,\n43668L,43669L,43670L,43671L,43672L,43673L,43674L,43675L,43676L,43677L,\n43678L,43679L,43680L,43681L,43682L,43683L,43684L,43685L,43686L,43687L,\n43688L,43689L,43690L,43691L,43692L,43693L,43694L,43695L,43696L,43697L,\n43698L,43699L,43700L,43701L,43702L,43703L,43704L,43705L,43706L,43707L,\n43708L,43709L,43710L,43711L,43712L,43713L,43714L,43715L,43716L,43717L,\n43718L,43719L,43720L,43721L,43722L,43723L,43724L,43725L,43726L,43727L,\n43728L,43729L,43730L,43731L,43732L,43733L,43734L,43735L,43736L,43737L,\n43738L,43739L,43740L,43741L,43742L,43743L,43744L,43745L,43746L,43747L,\n43748L,43749L,43750L,43751L,43752L,43753L,43754L,43755L,43756L,43757L,\n43758L,43759L,43760L,43761L,43762L,43763L,43764L,43765L,43766L,43767L,\n43768L,43769L,43770L,43771L,43772L,43773L,43774L,43775L,43776L,43777L,\n43778L,43779L,43780L,43781L,43782L,43783L,43784L,43785L,43786L,43787L,\n43788L,43789L,43790L,43791L,43792L,43793L,43794L,43795L,43796L,43797L,\n43798L,43799L,43800L,43801L,43802L,43803L,43804L,43805L,43806L,43807L,\n43808L,43809L,43810L,43811L,43812L,43813L,43814L,43815L,43816L,43817L,\n43818L,43819L,43820L,43821L,43822L,43823L,43824L,43825L,43826L,43827L,\n43828L,43829L,43830L,43831L,43832L,43833L,43834L,43835L,43836L,43837L,\n43838L,43839L,43840L,43841L,43842L,43843L,43844L,43845L,43846L,43847L,\n43848L,43849L,43850L,43851L,43852L,43853L,43854L,43855L,43856L,43857L,\n43858L,42931L,43860L,43861L,43862L,43863L,43864L,43865L,43866L,43867L,\n43868L,43869L,43870L,43871L,43872L,43873L,43874L,43875L,43876L,43877L,\n43878L,43879L,43880L,43881L,43882L,43883L,43884L,43885L,43886L,43887L,5024,\n5025,5026,5027,5028,5029,5030,5031,5032,5033,5034,5035,5036,5037,5038,5039,\n5040,5041,5042,5043,5044,5045,5046,5047,5048,5049,5050,5051,5052,5053,5054,\n5055,5056,5057,5058,5059,5060,5061,5062,5063,5064,5065,5066,5067,5068,5069,\n5070,5071,5072,5073,5074,5075,5076,5077,5078,5079,5080,5081,5082,5083,5084,\n5085,5086,5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,\n5100,5101,5102,5103,43968L,43969L,43970L,43971L,43972L,43973L,43974L,\n43975L,43976L,43977L,43978L,43979L,43980L,43981L,43982L,43983L,43984L,\n43985L,43986L,43987L,43988L,43989L,43990L,43991L,43992L,43993L,43994L,\n43995L,43996L,43997L,43998L,43999L,44000L,44001L,44002L,44003L,44004L,\n44005L,44006L,44007L,44008L,44009L,44010L,44011L,44012L,44013L,44014L,\n44015L,44016L,44017L,44018L,44019L,44020L,44021L,44022L,44023L,44024L,\n44025L,44026L,44027L,44028L,44029L,44030L,44031L,44032L,44033L,44034L,\n44035L,44036L,44037L,44038L,44039L,44040L,44041L,44042L,44043L,44044L,\n44045L,44046L,44047L,44048L,44049L,44050L,44051L,44052L,44053L,44054L,\n44055L,44056L,44057L,44058L,44059L,44060L,44061L,44062L,44063L,44064L,\n44065L,44066L,44067L,44068L,44069L,44070L,44071L,44072L,44073L,44074L,\n44075L,44076L,44077L,44078L,44079L,44080L,44081L,44082L,44083L,44084L,\n44085L,44086L,44087L,44088L,44089L,44090L,44091L,44092L,44093L,44094L,\n44095L,44096L,44097L,44098L,44099L,44100L,44101L,44102L,44103L,44104L,\n44105L,44106L,44107L,44108L,44109L,44110L,44111L,44112L,44113L,44114L,\n44115L,44116L,44117L,44118L,44119L,44120L,44121L,44122L,44123L,44124L,\n44125L,44126L,44127L,44128L,44129L,44130L,44131L,44132L,44133L,44134L,\n44135L,44136L,44137L,44138L,44139L,44140L,44141L,44142L,44143L,44144L,\n44145L,44146L,44147L,44148L,44149L,44150L,44151L,44152L,44153L,44154L,\n44155L,44156L,44157L,44158L,44159L,44160L,44161L,44162L,44163L,44164L,\n44165L,44166L,44167L,44168L,44169L,44170L,44171L,44172L,44173L,44174L,\n44175L,44176L,44177L,44178L,44179L,44180L,44181L,44182L,44183L,44184L,\n44185L,44186L,44187L,44188L,44189L,44190L,44191L,44192L,44193L,44194L,\n44195L,44196L,44197L,44198L,44199L,44200L,44201L,44202L,44203L,44204L,\n44205L,44206L,44207L,44208L,44209L,44210L,44211L,44212L,44213L,44214L,\n44215L,44216L,44217L,44218L,44219L,44220L,44221L,44222L,44223L,44224L,\n44225L,44226L,44227L,44228L,44229L,44230L,44231L,44232L,44233L,44234L,\n44235L,44236L,44237L,44238L,44239L,44240L,44241L,44242L,44243L,44244L,\n44245L,44246L,44247L,44248L,44249L,44250L,44251L,44252L,44253L,44254L,\n44255L,44256L,44257L,44258L,44259L,44260L,44261L,44262L,44263L,44264L,\n44265L,44266L,44267L,44268L,44269L,44270L,44271L,44272L,44273L,44274L,\n44275L,44276L,44277L,44278L,44279L,44280L,44281L,44282L,44283L,44284L,\n44285L,44286L,44287L,44288L,44289L,44290L,44291L,44292L,44293L,44294L,\n44295L,44296L,44297L,44298L,44299L,44300L,44301L,44302L,44303L,44304L,\n44305L,44306L,44307L,44308L,44309L,44310L,44311L,44312L,44313L,44314L,\n44315L,44316L,44317L,44318L,44319L,44320L,44321L,44322L,44323L,44324L,\n44325L,44326L,44327L,44328L,44329L,44330L,44331L,44332L,44333L,44334L,\n44335L,44336L,44337L,44338L,44339L,44340L,44341L,44342L,44343L,44344L,\n44345L,44346L,44347L,44348L,44349L,44350L,44351L,44352L,44353L,44354L,\n44355L,44356L,44357L,44358L,44359L,44360L,44361L,44362L,44363L,44364L,\n44365L,44366L,44367L,44368L,44369L,44370L,44371L,44372L,44373L,44374L,\n44375L,44376L,44377L,44378L,44379L,44380L,44381L,44382L,44383L,44384L,\n44385L,44386L,44387L,44388L,44389L,44390L,44391L,44392L,44393L,44394L,\n44395L,44396L,44397L,44398L,44399L,44400L,44401L,44402L,44403L,44404L,\n44405L,44406L,44407L,44408L,44409L,44410L,44411L,44412L,44413L,44414L,\n44415L,44416L,44417L,44418L,44419L,44420L,44421L,44422L,44423L,44424L,\n44425L,44426L,44427L,44428L,44429L,44430L,44431L,44432L,44433L,44434L,\n44435L,44436L,44437L,44438L,44439L,44440L,44441L,44442L,44443L,44444L,\n44445L,44446L,44447L,44448L,44449L,44450L,44451L,44452L,44453L,44454L,\n44455L,44456L,44457L,44458L,44459L,44460L,44461L,44462L,44463L,44464L,\n44465L,44466L,44467L,44468L,44469L,44470L,44471L,44472L,44473L,44474L,\n44475L,44476L,44477L,44478L,44479L,44480L,44481L,44482L,44483L,44484L,\n44485L,44486L,44487L,44488L,44489L,44490L,44491L,44492L,44493L,44494L,\n44495L,44496L,44497L,44498L,44499L,44500L,44501L,44502L,44503L,44504L,\n44505L,44506L,44507L,44508L,44509L,44510L,44511L,44512L,44513L,44514L,\n44515L,44516L,44517L,44518L,44519L,44520L,44521L,44522L,44523L,44524L,\n44525L,44526L,44527L,44528L,44529L,44530L,44531L,44532L,44533L,44534L,\n44535L,44536L,44537L,44538L,44539L,44540L,44541L,44542L,44543L,44544L,\n44545L,44546L,44547L,44548L,44549L,44550L,44551L,44552L,44553L,44554L,\n44555L,44556L,44557L,44558L,44559L,44560L,44561L,44562L,44563L,44564L,\n44565L,44566L,44567L,44568L,44569L,44570L,44571L,44572L,44573L,44574L,\n44575L,44576L,44577L,44578L,44579L,44580L,44581L,44582L,44583L,44584L,\n44585L,44586L,44587L,44588L,44589L,44590L,44591L,44592L,44593L,44594L,\n44595L,44596L,44597L,44598L,44599L,44600L,44601L,44602L,44603L,44604L,\n44605L,44606L,44607L,44608L,44609L,44610L,44611L,44612L,44613L,44614L,\n44615L,44616L,44617L,44618L,44619L,44620L,44621L,44622L,44623L,44624L,\n44625L,44626L,44627L,44628L,44629L,44630L,44631L,44632L,44633L,44634L,\n44635L,44636L,44637L,44638L,44639L,44640L,44641L,44642L,44643L,44644L,\n44645L,44646L,44647L,44648L,44649L,44650L,44651L,44652L,44653L,44654L,\n44655L,44656L,44657L,44658L,44659L,44660L,44661L,44662L,44663L,44664L,\n44665L,44666L,44667L,44668L,44669L,44670L,44671L,44672L,44673L,44674L,\n44675L,44676L,44677L,44678L,44679L,44680L,44681L,44682L,44683L,44684L,\n44685L,44686L,44687L,44688L,44689L,44690L,44691L,44692L,44693L,44694L,\n44695L,44696L,44697L,44698L,44699L,44700L,44701L,44702L,44703L,44704L,\n44705L,44706L,44707L,44708L,44709L,44710L,44711L,44712L,44713L,44714L,\n44715L,44716L,44717L,44718L,44719L,44720L,44721L,44722L,44723L,44724L,\n44725L,44726L,44727L,44728L,44729L,44730L,44731L,44732L,44733L,44734L,\n44735L,44736L,44737L,44738L,44739L,44740L,44741L,44742L,44743L,44744L,\n44745L,44746L,44747L,44748L,44749L,44750L,44751L,44752L,44753L,44754L,\n44755L,44756L,44757L,44758L,44759L,44760L,44761L,44762L,44763L,44764L,\n44765L,44766L,44767L,44768L,44769L,44770L,44771L,44772L,44773L,44774L,\n44775L,44776L,44777L,44778L,44779L,44780L,44781L,44782L,44783L,44784L,\n44785L,44786L,44787L,44788L,44789L,44790L,44791L,44792L,44793L,44794L,\n44795L,44796L,44797L,44798L,44799L,44800L,44801L,44802L,44803L,44804L,\n44805L,44806L,44807L,44808L,44809L,44810L,44811L,44812L,44813L,44814L,\n44815L,44816L,44817L,44818L,44819L,44820L,44821L,44822L,44823L,44824L,\n44825L,44826L,44827L,44828L,44829L,44830L,44831L,44832L,44833L,44834L,\n44835L,44836L,44837L,44838L,44839L,44840L,44841L,44842L,44843L,44844L,\n44845L,44846L,44847L,44848L,44849L,44850L,44851L,44852L,44853L,44854L,\n44855L,44856L,44857L,44858L,44859L,44860L,44861L,44862L,44863L,44864L,\n44865L,44866L,44867L,44868L,44869L,44870L,44871L,44872L,44873L,44874L,\n44875L,44876L,44877L,44878L,44879L,44880L,44881L,44882L,44883L,44884L,\n44885L,44886L,44887L,44888L,44889L,44890L,44891L,44892L,44893L,44894L,\n44895L,44896L,44897L,44898L,44899L,44900L,44901L,44902L,44903L,44904L,\n44905L,44906L,44907L,44908L,44909L,44910L,44911L,44912L,44913L,44914L,\n44915L,44916L,44917L,44918L,44919L,44920L,44921L,44922L,44923L,44924L,\n44925L,44926L,44927L,44928L,44929L,44930L,44931L,44932L,44933L,44934L,\n44935L,44936L,44937L,44938L,44939L,44940L,44941L,44942L,44943L,44944L,\n44945L,44946L,44947L,44948L,44949L,44950L,44951L,44952L,44953L,44954L,\n44955L,44956L,44957L,44958L,44959L,44960L,44961L,44962L,44963L,44964L,\n44965L,44966L,44967L,44968L,44969L,44970L,44971L,44972L,44973L,44974L,\n44975L,44976L,44977L,44978L,44979L,44980L,44981L,44982L,44983L,44984L,\n44985L,44986L,44987L,44988L,44989L,44990L,44991L,44992L,44993L,44994L,\n44995L,44996L,44997L,44998L,44999L,45000L,45001L,45002L,45003L,45004L,\n45005L,45006L,45007L,45008L,45009L,45010L,45011L,45012L,45013L,45014L,\n45015L,45016L,45017L,45018L,45019L,45020L,45021L,45022L,45023L,45024L,\n45025L,45026L,45027L,45028L,45029L,45030L,45031L,45032L,45033L,45034L,\n45035L,45036L,45037L,45038L,45039L,45040L,45041L,45042L,45043L,45044L,\n45045L,45046L,45047L,45048L,45049L,45050L,45051L,45052L,45053L,45054L,\n45055L,45056L,45057L,45058L,45059L,45060L,45061L,45062L,45063L,45064L,\n45065L,45066L,45067L,45068L,45069L,45070L,45071L,45072L,45073L,45074L,\n45075L,45076L,45077L,45078L,45079L,45080L,45081L,45082L,45083L,45084L,\n45085L,45086L,45087L,45088L,45089L,45090L,45091L,45092L,45093L,45094L,\n45095L,45096L,45097L,45098L,45099L,45100L,45101L,45102L,45103L,45104L,\n45105L,45106L,45107L,45108L,45109L,45110L,45111L,45112L,45113L,45114L,\n45115L,45116L,45117L,45118L,45119L,45120L,45121L,45122L,45123L,45124L,\n45125L,45126L,45127L,45128L,45129L,45130L,45131L,45132L,45133L,45134L,\n45135L,45136L,45137L,45138L,45139L,45140L,45141L,45142L,45143L,45144L,\n45145L,45146L,45147L,45148L,45149L,45150L,45151L,45152L,45153L,45154L,\n45155L,45156L,45157L,45158L,45159L,45160L,45161L,45162L,45163L,45164L,\n45165L,45166L,45167L,45168L,45169L,45170L,45171L,45172L,45173L,45174L,\n45175L,45176L,45177L,45178L,45179L,45180L,45181L,45182L,45183L,45184L,\n45185L,45186L,45187L,45188L,45189L,45190L,45191L,45192L,45193L,45194L,\n45195L,45196L,45197L,45198L,45199L,45200L,45201L,45202L,45203L,45204L,\n45205L,45206L,45207L,45208L,45209L,45210L,45211L,45212L,45213L,45214L,\n45215L,45216L,45217L,45218L,45219L,45220L,45221L,45222L,45223L,45224L,\n45225L,45226L,45227L,45228L,45229L,45230L,45231L,45232L,45233L,45234L,\n45235L,45236L,45237L,45238L,45239L,45240L,45241L,45242L,45243L,45244L,\n45245L,45246L,45247L,45248L,45249L,45250L,45251L,45252L,45253L,45254L,\n45255L,45256L,45257L,45258L,45259L,45260L,45261L,45262L,45263L,45264L,\n45265L,45266L,45267L,45268L,45269L,45270L,45271L,45272L,45273L,45274L,\n45275L,45276L,45277L,45278L,45279L,45280L,45281L,45282L,45283L,45284L,\n45285L,45286L,45287L,45288L,45289L,45290L,45291L,45292L,45293L,45294L,\n45295L,45296L,45297L,45298L,45299L,45300L,45301L,45302L,45303L,45304L,\n45305L,45306L,45307L,45308L,45309L,45310L,45311L,45312L,45313L,45314L,\n45315L,45316L,45317L,45318L,45319L,45320L,45321L,45322L,45323L,45324L,\n45325L,45326L,45327L,45328L,45329L,45330L,45331L,45332L,45333L,45334L,\n45335L,45336L,45337L,45338L,45339L,45340L,45341L,45342L,45343L,45344L,\n45345L,45346L,45347L,45348L,45349L,45350L,45351L,45352L,45353L,45354L,\n45355L,45356L,45357L,45358L,45359L,45360L,45361L,45362L,45363L,45364L,\n45365L,45366L,45367L,45368L,45369L,45370L,45371L,45372L,45373L,45374L,\n45375L,45376L,45377L,45378L,45379L,45380L,45381L,45382L,45383L,45384L,\n45385L,45386L,45387L,45388L,45389L,45390L,45391L,45392L,45393L,45394L,\n45395L,45396L,45397L,45398L,45399L,45400L,45401L,45402L,45403L,45404L,\n45405L,45406L,45407L,45408L,45409L,45410L,45411L,45412L,45413L,45414L,\n45415L,45416L,45417L,45418L,45419L,45420L,45421L,45422L,45423L,45424L,\n45425L,45426L,45427L,45428L,45429L,45430L,45431L,45432L,45433L,45434L,\n45435L,45436L,45437L,45438L,45439L,45440L,45441L,45442L,45443L,45444L,\n45445L,45446L,45447L,45448L,45449L,45450L,45451L,45452L,45453L,45454L,\n45455L,45456L,45457L,45458L,45459L,45460L,45461L,45462L,45463L,45464L,\n45465L,45466L,45467L,45468L,45469L,45470L,45471L,45472L,45473L,45474L,\n45475L,45476L,45477L,45478L,45479L,45480L,45481L,45482L,45483L,45484L,\n45485L,45486L,45487L,45488L,45489L,45490L,45491L,45492L,45493L,45494L,\n45495L,45496L,45497L,45498L,45499L,45500L,45501L,45502L,45503L,45504L,\n45505L,45506L,45507L,45508L,45509L,45510L,45511L,45512L,45513L,45514L,\n45515L,45516L,45517L,45518L,45519L,45520L,45521L,45522L,45523L,45524L,\n45525L,45526L,45527L,45528L,45529L,45530L,45531L,45532L,45533L,45534L,\n45535L,45536L,45537L,45538L,45539L,45540L,45541L,45542L,45543L,45544L,\n45545L,45546L,45547L,45548L,45549L,45550L,45551L,45552L,45553L,45554L,\n45555L,45556L,45557L,45558L,45559L,45560L,45561L,45562L,45563L,45564L,\n45565L,45566L,45567L,45568L,45569L,45570L,45571L,45572L,45573L,45574L,\n45575L,45576L,45577L,45578L,45579L,45580L,45581L,45582L,45583L,45584L,\n45585L,45586L,45587L,45588L,45589L,45590L,45591L,45592L,45593L,45594L,\n45595L,45596L,45597L,45598L,45599L,45600L,45601L,45602L,45603L,45604L,\n45605L,45606L,45607L,45608L,45609L,45610L,45611L,45612L,45613L,45614L,\n45615L,45616L,45617L,45618L,45619L,45620L,45621L,45622L,45623L,45624L,\n45625L,45626L,45627L,45628L,45629L,45630L,45631L,45632L,45633L,45634L,\n45635L,45636L,45637L,45638L,45639L,45640L,45641L,45642L,45643L,45644L,\n45645L,45646L,45647L,45648L,45649L,45650L,45651L,45652L,45653L,45654L,\n45655L,45656L,45657L,45658L,45659L,45660L,45661L,45662L,45663L,45664L,\n45665L,45666L,45667L,45668L,45669L,45670L,45671L,45672L,45673L,45674L,\n45675L,45676L,45677L,45678L,45679L,45680L,45681L,45682L,45683L,45684L,\n45685L,45686L,45687L,45688L,45689L,45690L,45691L,45692L,45693L,45694L,\n45695L,45696L,45697L,45698L,45699L,45700L,45701L,45702L,45703L,45704L,\n45705L,45706L,45707L,45708L,45709L,45710L,45711L,45712L,45713L,45714L,\n45715L,45716L,45717L,45718L,45719L,45720L,45721L,45722L,45723L,45724L,\n45725L,45726L,45727L,45728L,45729L,45730L,45731L,45732L,45733L,45734L,\n45735L,45736L,45737L,45738L,45739L,45740L,45741L,45742L,45743L,45744L,\n45745L,45746L,45747L,45748L,45749L,45750L,45751L,45752L,45753L,45754L,\n45755L,45756L,45757L,45758L,45759L,45760L,45761L,45762L,45763L,45764L,\n45765L,45766L,45767L,45768L,45769L,45770L,45771L,45772L,45773L,45774L,\n45775L,45776L,45777L,45778L,45779L,45780L,45781L,45782L,45783L,45784L,\n45785L,45786L,45787L,45788L,45789L,45790L,45791L,45792L,45793L,45794L,\n45795L,45796L,45797L,45798L,45799L,45800L,45801L,45802L,45803L,45804L,\n45805L,45806L,45807L,45808L,45809L,45810L,45811L,45812L,45813L,45814L,\n45815L,45816L,45817L,45818L,45819L,45820L,45821L,45822L,45823L,45824L,\n45825L,45826L,45827L,45828L,45829L,45830L,45831L,45832L,45833L,45834L,\n45835L,45836L,45837L,45838L,45839L,45840L,45841L,45842L,45843L,45844L,\n45845L,45846L,45847L,45848L,45849L,45850L,45851L,45852L,45853L,45854L,\n45855L,45856L,45857L,45858L,45859L,45860L,45861L,45862L,45863L,45864L,\n45865L,45866L,45867L,45868L,45869L,45870L,45871L,45872L,45873L,45874L,\n45875L,45876L,45877L,45878L,45879L,45880L,45881L,45882L,45883L,45884L,\n45885L,45886L,45887L,45888L,45889L,45890L,45891L,45892L,45893L,45894L,\n45895L,45896L,45897L,45898L,45899L,45900L,45901L,45902L,45903L,45904L,\n45905L,45906L,45907L,45908L,45909L,45910L,45911L,45912L,45913L,45914L,\n45915L,45916L,45917L,45918L,45919L,45920L,45921L,45922L,45923L,45924L,\n45925L,45926L,45927L,45928L,45929L,45930L,45931L,45932L,45933L,45934L,\n45935L,45936L,45937L,45938L,45939L,45940L,45941L,45942L,45943L,45944L,\n45945L,45946L,45947L,45948L,45949L,45950L,45951L,45952L,45953L,45954L,\n45955L,45956L,45957L,45958L,45959L,45960L,45961L,45962L,45963L,45964L,\n45965L,45966L,45967L,45968L,45969L,45970L,45971L,45972L,45973L,45974L,\n45975L,45976L,45977L,45978L,45979L,45980L,45981L,45982L,45983L,45984L,\n45985L,45986L,45987L,45988L,45989L,45990L,45991L,45992L,45993L,45994L,\n45995L,45996L,45997L,45998L,45999L,46000L,46001L,46002L,46003L,46004L,\n46005L,46006L,46007L,46008L,46009L,46010L,46011L,46012L,46013L,46014L,\n46015L,46016L,46017L,46018L,46019L,46020L,46021L,46022L,46023L,46024L,\n46025L,46026L,46027L,46028L,46029L,46030L,46031L,46032L,46033L,46034L,\n46035L,46036L,46037L,46038L,46039L,46040L,46041L,46042L,46043L,46044L,\n46045L,46046L,46047L,46048L,46049L,46050L,46051L,46052L,46053L,46054L,\n46055L,46056L,46057L,46058L,46059L,46060L,46061L,46062L,46063L,46064L,\n46065L,46066L,46067L,46068L,46069L,46070L,46071L,46072L,46073L,46074L,\n46075L,46076L,46077L,46078L,46079L,46080L,46081L,46082L,46083L,46084L,\n46085L,46086L,46087L,46088L,46089L,46090L,46091L,46092L,46093L,46094L,\n46095L,46096L,46097L,46098L,46099L,46100L,46101L,46102L,46103L,46104L,\n46105L,46106L,46107L,46108L,46109L,46110L,46111L,46112L,46113L,46114L,\n46115L,46116L,46117L,46118L,46119L,46120L,46121L,46122L,46123L,46124L,\n46125L,46126L,46127L,46128L,46129L,46130L,46131L,46132L,46133L,46134L,\n46135L,46136L,46137L,46138L,46139L,46140L,46141L,46142L,46143L,46144L,\n46145L,46146L,46147L,46148L,46149L,46150L,46151L,46152L,46153L,46154L,\n46155L,46156L,46157L,46158L,46159L,46160L,46161L,46162L,46163L,46164L,\n46165L,46166L,46167L,46168L,46169L,46170L,46171L,46172L,46173L,46174L,\n46175L,46176L,46177L,46178L,46179L,46180L,46181L,46182L,46183L,46184L,\n46185L,46186L,46187L,46188L,46189L,46190L,46191L,46192L,46193L,46194L,\n46195L,46196L,46197L,46198L,46199L,46200L,46201L,46202L,46203L,46204L,\n46205L,46206L,46207L,46208L,46209L,46210L,46211L,46212L,46213L,46214L,\n46215L,46216L,46217L,46218L,46219L,46220L,46221L,46222L,46223L,46224L,\n46225L,46226L,46227L,46228L,46229L,46230L,46231L,46232L,46233L,46234L,\n46235L,46236L,46237L,46238L,46239L,46240L,46241L,46242L,46243L,46244L,\n46245L,46246L,46247L,46248L,46249L,46250L,46251L,46252L,46253L,46254L,\n46255L,46256L,46257L,46258L,46259L,46260L,46261L,46262L,46263L,46264L,\n46265L,46266L,46267L,46268L,46269L,46270L,46271L,46272L,46273L,46274L,\n46275L,46276L,46277L,46278L,46279L,46280L,46281L,46282L,46283L,46284L,\n46285L,46286L,46287L,46288L,46289L,46290L,46291L,46292L,46293L,46294L,\n46295L,46296L,46297L,46298L,46299L,46300L,46301L,46302L,46303L,46304L,\n46305L,46306L,46307L,46308L,46309L,46310L,46311L,46312L,46313L,46314L,\n46315L,46316L,46317L,46318L,46319L,46320L,46321L,46322L,46323L,46324L,\n46325L,46326L,46327L,46328L,46329L,46330L,46331L,46332L,46333L,46334L,\n46335L,46336L,46337L,46338L,46339L,46340L,46341L,46342L,46343L,46344L,\n46345L,46346L,46347L,46348L,46349L,46350L,46351L,46352L,46353L,46354L,\n46355L,46356L,46357L,46358L,46359L,46360L,46361L,46362L,46363L,46364L,\n46365L,46366L,46367L,46368L,46369L,46370L,46371L,46372L,46373L,46374L,\n46375L,46376L,46377L,46378L,46379L,46380L,46381L,46382L,46383L,46384L,\n46385L,46386L,46387L,46388L,46389L,46390L,46391L,46392L,46393L,46394L,\n46395L,46396L,46397L,46398L,46399L,46400L,46401L,46402L,46403L,46404L,\n46405L,46406L,46407L,46408L,46409L,46410L,46411L,46412L,46413L,46414L,\n46415L,46416L,46417L,46418L,46419L,46420L,46421L,46422L,46423L,46424L,\n46425L,46426L,46427L,46428L,46429L,46430L,46431L,46432L,46433L,46434L,\n46435L,46436L,46437L,46438L,46439L,46440L,46441L,46442L,46443L,46444L,\n46445L,46446L,46447L,46448L,46449L,46450L,46451L,46452L,46453L,46454L,\n46455L,46456L,46457L,46458L,46459L,46460L,46461L,46462L,46463L,46464L,\n46465L,46466L,46467L,46468L,46469L,46470L,46471L,46472L,46473L,46474L,\n46475L,46476L,46477L,46478L,46479L,46480L,46481L,46482L,46483L,46484L,\n46485L,46486L,46487L,46488L,46489L,46490L,46491L,46492L,46493L,46494L,\n46495L,46496L,46497L,46498L,46499L,46500L,46501L,46502L,46503L,46504L,\n46505L,46506L,46507L,46508L,46509L,46510L,46511L,46512L,46513L,46514L,\n46515L,46516L,46517L,46518L,46519L,46520L,46521L,46522L,46523L,46524L,\n46525L,46526L,46527L,46528L,46529L,46530L,46531L,46532L,46533L,46534L,\n46535L,46536L,46537L,46538L,46539L,46540L,46541L,46542L,46543L,46544L,\n46545L,46546L,46547L,46548L,46549L,46550L,46551L,46552L,46553L,46554L,\n46555L,46556L,46557L,46558L,46559L,46560L,46561L,46562L,46563L,46564L,\n46565L,46566L,46567L,46568L,46569L,46570L,46571L,46572L,46573L,46574L,\n46575L,46576L,46577L,46578L,46579L,46580L,46581L,46582L,46583L,46584L,\n46585L,46586L,46587L,46588L,46589L,46590L,46591L,46592L,46593L,46594L,\n46595L,46596L,46597L,46598L,46599L,46600L,46601L,46602L,46603L,46604L,\n46605L,46606L,46607L,46608L,46609L,46610L,46611L,46612L,46613L,46614L,\n46615L,46616L,46617L,46618L,46619L,46620L,46621L,46622L,46623L,46624L,\n46625L,46626L,46627L,46628L,46629L,46630L,46631L,46632L,46633L,46634L,\n46635L,46636L,46637L,46638L,46639L,46640L,46641L,46642L,46643L,46644L,\n46645L,46646L,46647L,46648L,46649L,46650L,46651L,46652L,46653L,46654L,\n46655L,46656L,46657L,46658L,46659L,46660L,46661L,46662L,46663L,46664L,\n46665L,46666L,46667L,46668L,46669L,46670L,46671L,46672L,46673L,46674L,\n46675L,46676L,46677L,46678L,46679L,46680L,46681L,46682L,46683L,46684L,\n46685L,46686L,46687L,46688L,46689L,46690L,46691L,46692L,46693L,46694L,\n46695L,46696L,46697L,46698L,46699L,46700L,46701L,46702L,46703L,46704L,\n46705L,46706L,46707L,46708L,46709L,46710L,46711L,46712L,46713L,46714L,\n46715L,46716L,46717L,46718L,46719L,46720L,46721L,46722L,46723L,46724L,\n46725L,46726L,46727L,46728L,46729L,46730L,46731L,46732L,46733L,46734L,\n46735L,46736L,46737L,46738L,46739L,46740L,46741L,46742L,46743L,46744L,\n46745L,46746L,46747L,46748L,46749L,46750L,46751L,46752L,46753L,46754L,\n46755L,46756L,46757L,46758L,46759L,46760L,46761L,46762L,46763L,46764L,\n46765L,46766L,46767L,46768L,46769L,46770L,46771L,46772L,46773L,46774L,\n46775L,46776L,46777L,46778L,46779L,46780L,46781L,46782L,46783L,46784L,\n46785L,46786L,46787L,46788L,46789L,46790L,46791L,46792L,46793L,46794L,\n46795L,46796L,46797L,46798L,46799L,46800L,46801L,46802L,46803L,46804L,\n46805L,46806L,46807L,46808L,46809L,46810L,46811L,46812L,46813L,46814L,\n46815L,46816L,46817L,46818L,46819L,46820L,46821L,46822L,46823L,46824L,\n46825L,46826L,46827L,46828L,46829L,46830L,46831L,46832L,46833L,46834L,\n46835L,46836L,46837L,46838L,46839L,46840L,46841L,46842L,46843L,46844L,\n46845L,46846L,46847L,46848L,46849L,46850L,46851L,46852L,46853L,46854L,\n46855L,46856L,46857L,46858L,46859L,46860L,46861L,46862L,46863L,46864L,\n46865L,46866L,46867L,46868L,46869L,46870L,46871L,46872L,46873L,46874L,\n46875L,46876L,46877L,46878L,46879L,46880L,46881L,46882L,46883L,46884L,\n46885L,46886L,46887L,46888L,46889L,46890L,46891L,46892L,46893L,46894L,\n46895L,46896L,46897L,46898L,46899L,46900L,46901L,46902L,46903L,46904L,\n46905L,46906L,46907L,46908L,46909L,46910L,46911L,46912L,46913L,46914L,\n46915L,46916L,46917L,46918L,46919L,46920L,46921L,46922L,46923L,46924L,\n46925L,46926L,46927L,46928L,46929L,46930L,46931L,46932L,46933L,46934L,\n46935L,46936L,46937L,46938L,46939L,46940L,46941L,46942L,46943L,46944L,\n46945L,46946L,46947L,46948L,46949L,46950L,46951L,46952L,46953L,46954L,\n46955L,46956L,46957L,46958L,46959L,46960L,46961L,46962L,46963L,46964L,\n46965L,46966L,46967L,46968L,46969L,46970L,46971L,46972L,46973L,46974L,\n46975L,46976L,46977L,46978L,46979L,46980L,46981L,46982L,46983L,46984L,\n46985L,46986L,46987L,46988L,46989L,46990L,46991L,46992L,46993L,46994L,\n46995L,46996L,46997L,46998L,46999L,47000L,47001L,47002L,47003L,47004L,\n47005L,47006L,47007L,47008L,47009L,47010L,47011L,47012L,47013L,47014L,\n47015L,47016L,47017L,47018L,47019L,47020L,47021L,47022L,47023L,47024L,\n47025L,47026L,47027L,47028L,47029L,47030L,47031L,47032L,47033L,47034L,\n47035L,47036L,47037L,47038L,47039L,47040L,47041L,47042L,47043L,47044L,\n47045L,47046L,47047L,47048L,47049L,47050L,47051L,47052L,47053L,47054L,\n47055L,47056L,47057L,47058L,47059L,47060L,47061L,47062L,47063L,47064L,\n47065L,47066L,47067L,47068L,47069L,47070L,47071L,47072L,47073L,47074L,\n47075L,47076L,47077L,47078L,47079L,47080L,47081L,47082L,47083L,47084L,\n47085L,47086L,47087L,47088L,47089L,47090L,47091L,47092L,47093L,47094L,\n47095L,47096L,47097L,47098L,47099L,47100L,47101L,47102L,47103L,47104L,\n47105L,47106L,47107L,47108L,47109L,47110L,47111L,47112L,47113L,47114L,\n47115L,47116L,47117L,47118L,47119L,47120L,47121L,47122L,47123L,47124L,\n47125L,47126L,47127L,47128L,47129L,47130L,47131L,47132L,47133L,47134L,\n47135L,47136L,47137L,47138L,47139L,47140L,47141L,47142L,47143L,47144L,\n47145L,47146L,47147L,47148L,47149L,47150L,47151L,47152L,47153L,47154L,\n47155L,47156L,47157L,47158L,47159L,47160L,47161L,47162L,47163L,47164L,\n47165L,47166L,47167L,47168L,47169L,47170L,47171L,47172L,47173L,47174L,\n47175L,47176L,47177L,47178L,47179L,47180L,47181L,47182L,47183L,47184L,\n47185L,47186L,47187L,47188L,47189L,47190L,47191L,47192L,47193L,47194L,\n47195L,47196L,47197L,47198L,47199L,47200L,47201L,47202L,47203L,47204L,\n47205L,47206L,47207L,47208L,47209L,47210L,47211L,47212L,47213L,47214L,\n47215L,47216L,47217L,47218L,47219L,47220L,47221L,47222L,47223L,47224L,\n47225L,47226L,47227L,47228L,47229L,47230L,47231L,47232L,47233L,47234L,\n47235L,47236L,47237L,47238L,47239L,47240L,47241L,47242L,47243L,47244L,\n47245L,47246L,47247L,47248L,47249L,47250L,47251L,47252L,47253L,47254L,\n47255L,47256L,47257L,47258L,47259L,47260L,47261L,47262L,47263L,47264L,\n47265L,47266L,47267L,47268L,47269L,47270L,47271L,47272L,47273L,47274L,\n47275L,47276L,47277L,47278L,47279L,47280L,47281L,47282L,47283L,47284L,\n47285L,47286L,47287L,47288L,47289L,47290L,47291L,47292L,47293L,47294L,\n47295L,47296L,47297L,47298L,47299L,47300L,47301L,47302L,47303L,47304L,\n47305L,47306L,47307L,47308L,47309L,47310L,47311L,47312L,47313L,47314L,\n47315L,47316L,47317L,47318L,47319L,47320L,47321L,47322L,47323L,47324L,\n47325L,47326L,47327L,47328L,47329L,47330L,47331L,47332L,47333L,47334L,\n47335L,47336L,47337L,47338L,47339L,47340L,47341L,47342L,47343L,47344L,\n47345L,47346L,47347L,47348L,47349L,47350L,47351L,47352L,47353L,47354L,\n47355L,47356L,47357L,47358L,47359L,47360L,47361L,47362L,47363L,47364L,\n47365L,47366L,47367L,47368L,47369L,47370L,47371L,47372L,47373L,47374L,\n47375L,47376L,47377L,47378L,47379L,47380L,47381L,47382L,47383L,47384L,\n47385L,47386L,47387L,47388L,47389L,47390L,47391L,47392L,47393L,47394L,\n47395L,47396L,47397L,47398L,47399L,47400L,47401L,47402L,47403L,47404L,\n47405L,47406L,47407L,47408L,47409L,47410L,47411L,47412L,47413L,47414L,\n47415L,47416L,47417L,47418L,47419L,47420L,47421L,47422L,47423L,47424L,\n47425L,47426L,47427L,47428L,47429L,47430L,47431L,47432L,47433L,47434L,\n47435L,47436L,47437L,47438L,47439L,47440L,47441L,47442L,47443L,47444L,\n47445L,47446L,47447L,47448L,47449L,47450L,47451L,47452L,47453L,47454L,\n47455L,47456L,47457L,47458L,47459L,47460L,47461L,47462L,47463L,47464L,\n47465L,47466L,47467L,47468L,47469L,47470L,47471L,47472L,47473L,47474L,\n47475L,47476L,47477L,47478L,47479L,47480L,47481L,47482L,47483L,47484L,\n47485L,47486L,47487L,47488L,47489L,47490L,47491L,47492L,47493L,47494L,\n47495L,47496L,47497L,47498L,47499L,47500L,47501L,47502L,47503L,47504L,\n47505L,47506L,47507L,47508L,47509L,47510L,47511L,47512L,47513L,47514L,\n47515L,47516L,47517L,47518L,47519L,47520L,47521L,47522L,47523L,47524L,\n47525L,47526L,47527L,47528L,47529L,47530L,47531L,47532L,47533L,47534L,\n47535L,47536L,47537L,47538L,47539L,47540L,47541L,47542L,47543L,47544L,\n47545L,47546L,47547L,47548L,47549L,47550L,47551L,47552L,47553L,47554L,\n47555L,47556L,47557L,47558L,47559L,47560L,47561L,47562L,47563L,47564L,\n47565L,47566L,47567L,47568L,47569L,47570L,47571L,47572L,47573L,47574L,\n47575L,47576L,47577L,47578L,47579L,47580L,47581L,47582L,47583L,47584L,\n47585L,47586L,47587L,47588L,47589L,47590L,47591L,47592L,47593L,47594L,\n47595L,47596L,47597L,47598L,47599L,47600L,47601L,47602L,47603L,47604L,\n47605L,47606L,47607L,47608L,47609L,47610L,47611L,47612L,47613L,47614L,\n47615L,47616L,47617L,47618L,47619L,47620L,47621L,47622L,47623L,47624L,\n47625L,47626L,47627L,47628L,47629L,47630L,47631L,47632L,47633L,47634L,\n47635L,47636L,47637L,47638L,47639L,47640L,47641L,47642L,47643L,47644L,\n47645L,47646L,47647L,47648L,47649L,47650L,47651L,47652L,47653L,47654L,\n47655L,47656L,47657L,47658L,47659L,47660L,47661L,47662L,47663L,47664L,\n47665L,47666L,47667L,47668L,47669L,47670L,47671L,47672L,47673L,47674L,\n47675L,47676L,47677L,47678L,47679L,47680L,47681L,47682L,47683L,47684L,\n47685L,47686L,47687L,47688L,47689L,47690L,47691L,47692L,47693L,47694L,\n47695L,47696L,47697L,47698L,47699L,47700L,47701L,47702L,47703L,47704L,\n47705L,47706L,47707L,47708L,47709L,47710L,47711L,47712L,47713L,47714L,\n47715L,47716L,47717L,47718L,47719L,47720L,47721L,47722L,47723L,47724L,\n47725L,47726L,47727L,47728L,47729L,47730L,47731L,47732L,47733L,47734L,\n47735L,47736L,47737L,47738L,47739L,47740L,47741L,47742L,47743L,47744L,\n47745L,47746L,47747L,47748L,47749L,47750L,47751L,47752L,47753L,47754L,\n47755L,47756L,47757L,47758L,47759L,47760L,47761L,47762L,47763L,47764L,\n47765L,47766L,47767L,47768L,47769L,47770L,47771L,47772L,47773L,47774L,\n47775L,47776L,47777L,47778L,47779L,47780L,47781L,47782L,47783L,47784L,\n47785L,47786L,47787L,47788L,47789L,47790L,47791L,47792L,47793L,47794L,\n47795L,47796L,47797L,47798L,47799L,47800L,47801L,47802L,47803L,47804L,\n47805L,47806L,47807L,47808L,47809L,47810L,47811L,47812L,47813L,47814L,\n47815L,47816L,47817L,47818L,47819L,47820L,47821L,47822L,47823L,47824L,\n47825L,47826L,47827L,47828L,47829L,47830L,47831L,47832L,47833L,47834L,\n47835L,47836L,47837L,47838L,47839L,47840L,47841L,47842L,47843L,47844L,\n47845L,47846L,47847L,47848L,47849L,47850L,47851L,47852L,47853L,47854L,\n47855L,47856L,47857L,47858L,47859L,47860L,47861L,47862L,47863L,47864L,\n47865L,47866L,47867L,47868L,47869L,47870L,47871L,47872L,47873L,47874L,\n47875L,47876L,47877L,47878L,47879L,47880L,47881L,47882L,47883L,47884L,\n47885L,47886L,47887L,47888L,47889L,47890L,47891L,47892L,47893L,47894L,\n47895L,47896L,47897L,47898L,47899L,47900L,47901L,47902L,47903L,47904L,\n47905L,47906L,47907L,47908L,47909L,47910L,47911L,47912L,47913L,47914L,\n47915L,47916L,47917L,47918L,47919L,47920L,47921L,47922L,47923L,47924L,\n47925L,47926L,47927L,47928L,47929L,47930L,47931L,47932L,47933L,47934L,\n47935L,47936L,47937L,47938L,47939L,47940L,47941L,47942L,47943L,47944L,\n47945L,47946L,47947L,47948L,47949L,47950L,47951L,47952L,47953L,47954L,\n47955L,47956L,47957L,47958L,47959L,47960L,47961L,47962L,47963L,47964L,\n47965L,47966L,47967L,47968L,47969L,47970L,47971L,47972L,47973L,47974L,\n47975L,47976L,47977L,47978L,47979L,47980L,47981L,47982L,47983L,47984L,\n47985L,47986L,47987L,47988L,47989L,47990L,47991L,47992L,47993L,47994L,\n47995L,47996L,47997L,47998L,47999L,48000L,48001L,48002L,48003L,48004L,\n48005L,48006L,48007L,48008L,48009L,48010L,48011L,48012L,48013L,48014L,\n48015L,48016L,48017L,48018L,48019L,48020L,48021L,48022L,48023L,48024L,\n48025L,48026L,48027L,48028L,48029L,48030L,48031L,48032L,48033L,48034L,\n48035L,48036L,48037L,48038L,48039L,48040L,48041L,48042L,48043L,48044L,\n48045L,48046L,48047L,48048L,48049L,48050L,48051L,48052L,48053L,48054L,\n48055L,48056L,48057L,48058L,48059L,48060L,48061L,48062L,48063L,48064L,\n48065L,48066L,48067L,48068L,48069L,48070L,48071L,48072L,48073L,48074L,\n48075L,48076L,48077L,48078L,48079L,48080L,48081L,48082L,48083L,48084L,\n48085L,48086L,48087L,48088L,48089L,48090L,48091L,48092L,48093L,48094L,\n48095L,48096L,48097L,48098L,48099L,48100L,48101L,48102L,48103L,48104L,\n48105L,48106L,48107L,48108L,48109L,48110L,48111L,48112L,48113L,48114L,\n48115L,48116L,48117L,48118L,48119L,48120L,48121L,48122L,48123L,48124L,\n48125L,48126L,48127L,48128L,48129L,48130L,48131L,48132L,48133L,48134L,\n48135L,48136L,48137L,48138L,48139L,48140L,48141L,48142L,48143L,48144L,\n48145L,48146L,48147L,48148L,48149L,48150L,48151L,48152L,48153L,48154L,\n48155L,48156L,48157L,48158L,48159L,48160L,48161L,48162L,48163L,48164L,\n48165L,48166L,48167L,48168L,48169L,48170L,48171L,48172L,48173L,48174L,\n48175L,48176L,48177L,48178L,48179L,48180L,48181L,48182L,48183L,48184L,\n48185L,48186L,48187L,48188L,48189L,48190L,48191L,48192L,48193L,48194L,\n48195L,48196L,48197L,48198L,48199L,48200L,48201L,48202L,48203L,48204L,\n48205L,48206L,48207L,48208L,48209L,48210L,48211L,48212L,48213L,48214L,\n48215L,48216L,48217L,48218L,48219L,48220L,48221L,48222L,48223L,48224L,\n48225L,48226L,48227L,48228L,48229L,48230L,48231L,48232L,48233L,48234L,\n48235L,48236L,48237L,48238L,48239L,48240L,48241L,48242L,48243L,48244L,\n48245L,48246L,48247L,48248L,48249L,48250L,48251L,48252L,48253L,48254L,\n48255L,48256L,48257L,48258L,48259L,48260L,48261L,48262L,48263L,48264L,\n48265L,48266L,48267L,48268L,48269L,48270L,48271L,48272L,48273L,48274L,\n48275L,48276L,48277L,48278L,48279L,48280L,48281L,48282L,48283L,48284L,\n48285L,48286L,48287L,48288L,48289L,48290L,48291L,48292L,48293L,48294L,\n48295L,48296L,48297L,48298L,48299L,48300L,48301L,48302L,48303L,48304L,\n48305L,48306L,48307L,48308L,48309L,48310L,48311L,48312L,48313L,48314L,\n48315L,48316L,48317L,48318L,48319L,48320L,48321L,48322L,48323L,48324L,\n48325L,48326L,48327L,48328L,48329L,48330L,48331L,48332L,48333L,48334L,\n48335L,48336L,48337L,48338L,48339L,48340L,48341L,48342L,48343L,48344L,\n48345L,48346L,48347L,48348L,48349L,48350L,48351L,48352L,48353L,48354L,\n48355L,48356L,48357L,48358L,48359L,48360L,48361L,48362L,48363L,48364L,\n48365L,48366L,48367L,48368L,48369L,48370L,48371L,48372L,48373L,48374L,\n48375L,48376L,48377L,48378L,48379L,48380L,48381L,48382L,48383L,48384L,\n48385L,48386L,48387L,48388L,48389L,48390L,48391L,48392L,48393L,48394L,\n48395L,48396L,48397L,48398L,48399L,48400L,48401L,48402L,48403L,48404L,\n48405L,48406L,48407L,48408L,48409L,48410L,48411L,48412L,48413L,48414L,\n48415L,48416L,48417L,48418L,48419L,48420L,48421L,48422L,48423L,48424L,\n48425L,48426L,48427L,48428L,48429L,48430L,48431L,48432L,48433L,48434L,\n48435L,48436L,48437L,48438L,48439L,48440L,48441L,48442L,48443L,48444L,\n48445L,48446L,48447L,48448L,48449L,48450L,48451L,48452L,48453L,48454L,\n48455L,48456L,48457L,48458L,48459L,48460L,48461L,48462L,48463L,48464L,\n48465L,48466L,48467L,48468L,48469L,48470L,48471L,48472L,48473L,48474L,\n48475L,48476L,48477L,48478L,48479L,48480L,48481L,48482L,48483L,48484L,\n48485L,48486L,48487L,48488L,48489L,48490L,48491L,48492L,48493L,48494L,\n48495L,48496L,48497L,48498L,48499L,48500L,48501L,48502L,48503L,48504L,\n48505L,48506L,48507L,48508L,48509L,48510L,48511L,48512L,48513L,48514L,\n48515L,48516L,48517L,48518L,48519L,48520L,48521L,48522L,48523L,48524L,\n48525L,48526L,48527L,48528L,48529L,48530L,48531L,48532L,48533L,48534L,\n48535L,48536L,48537L,48538L,48539L,48540L,48541L,48542L,48543L,48544L,\n48545L,48546L,48547L,48548L,48549L,48550L,48551L,48552L,48553L,48554L,\n48555L,48556L,48557L,48558L,48559L,48560L,48561L,48562L,48563L,48564L,\n48565L,48566L,48567L,48568L,48569L,48570L,48571L,48572L,48573L,48574L,\n48575L,48576L,48577L,48578L,48579L,48580L,48581L,48582L,48583L,48584L,\n48585L,48586L,48587L,48588L,48589L,48590L,48591L,48592L,48593L,48594L,\n48595L,48596L,48597L,48598L,48599L,48600L,48601L,48602L,48603L,48604L,\n48605L,48606L,48607L,48608L,48609L,48610L,48611L,48612L,48613L,48614L,\n48615L,48616L,48617L,48618L,48619L,48620L,48621L,48622L,48623L,48624L,\n48625L,48626L,48627L,48628L,48629L,48630L,48631L,48632L,48633L,48634L,\n48635L,48636L,48637L,48638L,48639L,48640L,48641L,48642L,48643L,48644L,\n48645L,48646L,48647L,48648L,48649L,48650L,48651L,48652L,48653L,48654L,\n48655L,48656L,48657L,48658L,48659L,48660L,48661L,48662L,48663L,48664L,\n48665L,48666L,48667L,48668L,48669L,48670L,48671L,48672L,48673L,48674L,\n48675L,48676L,48677L,48678L,48679L,48680L,48681L,48682L,48683L,48684L,\n48685L,48686L,48687L,48688L,48689L,48690L,48691L,48692L,48693L,48694L,\n48695L,48696L,48697L,48698L,48699L,48700L,48701L,48702L,48703L,48704L,\n48705L,48706L,48707L,48708L,48709L,48710L,48711L,48712L,48713L,48714L,\n48715L,48716L,48717L,48718L,48719L,48720L,48721L,48722L,48723L,48724L,\n48725L,48726L,48727L,48728L,48729L,48730L,48731L,48732L,48733L,48734L,\n48735L,48736L,48737L,48738L,48739L,48740L,48741L,48742L,48743L,48744L,\n48745L,48746L,48747L,48748L,48749L,48750L,48751L,48752L,48753L,48754L,\n48755L,48756L,48757L,48758L,48759L,48760L,48761L,48762L,48763L,48764L,\n48765L,48766L,48767L,48768L,48769L,48770L,48771L,48772L,48773L,48774L,\n48775L,48776L,48777L,48778L,48779L,48780L,48781L,48782L,48783L,48784L,\n48785L,48786L,48787L,48788L,48789L,48790L,48791L,48792L,48793L,48794L,\n48795L,48796L,48797L,48798L,48799L,48800L,48801L,48802L,48803L,48804L,\n48805L,48806L,48807L,48808L,48809L,48810L,48811L,48812L,48813L,48814L,\n48815L,48816L,48817L,48818L,48819L,48820L,48821L,48822L,48823L,48824L,\n48825L,48826L,48827L,48828L,48829L,48830L,48831L,48832L,48833L,48834L,\n48835L,48836L,48837L,48838L,48839L,48840L,48841L,48842L,48843L,48844L,\n48845L,48846L,48847L,48848L,48849L,48850L,48851L,48852L,48853L,48854L,\n48855L,48856L,48857L,48858L,48859L,48860L,48861L,48862L,48863L,48864L,\n48865L,48866L,48867L,48868L,48869L,48870L,48871L,48872L,48873L,48874L,\n48875L,48876L,48877L,48878L,48879L,48880L,48881L,48882L,48883L,48884L,\n48885L,48886L,48887L,48888L,48889L,48890L,48891L,48892L,48893L,48894L,\n48895L,48896L,48897L,48898L,48899L,48900L,48901L,48902L,48903L,48904L,\n48905L,48906L,48907L,48908L,48909L,48910L,48911L,48912L,48913L,48914L,\n48915L,48916L,48917L,48918L,48919L,48920L,48921L,48922L,48923L,48924L,\n48925L,48926L,48927L,48928L,48929L,48930L,48931L,48932L,48933L,48934L,\n48935L,48936L,48937L,48938L,48939L,48940L,48941L,48942L,48943L,48944L,\n48945L,48946L,48947L,48948L,48949L,48950L,48951L,48952L,48953L,48954L,\n48955L,48956L,48957L,48958L,48959L,48960L,48961L,48962L,48963L,48964L,\n48965L,48966L,48967L,48968L,48969L,48970L,48971L,48972L,48973L,48974L,\n48975L,48976L,48977L,48978L,48979L,48980L,48981L,48982L,48983L,48984L,\n48985L,48986L,48987L,48988L,48989L,48990L,48991L,48992L,48993L,48994L,\n48995L,48996L,48997L,48998L,48999L,49000L,49001L,49002L,49003L,49004L,\n49005L,49006L,49007L,49008L,49009L,49010L,49011L,49012L,49013L,49014L,\n49015L,49016L,49017L,49018L,49019L,49020L,49021L,49022L,49023L,49024L,\n49025L,49026L,49027L,49028L,49029L,49030L,49031L,49032L,49033L,49034L,\n49035L,49036L,49037L,49038L,49039L,49040L,49041L,49042L,49043L,49044L,\n49045L,49046L,49047L,49048L,49049L,49050L,49051L,49052L,49053L,49054L,\n49055L,49056L,49057L,49058L,49059L,49060L,49061L,49062L,49063L,49064L,\n49065L,49066L,49067L,49068L,49069L,49070L,49071L,49072L,49073L,49074L,\n49075L,49076L,49077L,49078L,49079L,49080L,49081L,49082L,49083L,49084L,\n49085L,49086L,49087L,49088L,49089L,49090L,49091L,49092L,49093L,49094L,\n49095L,49096L,49097L,49098L,49099L,49100L,49101L,49102L,49103L,49104L,\n49105L,49106L,49107L,49108L,49109L,49110L,49111L,49112L,49113L,49114L,\n49115L,49116L,49117L,49118L,49119L,49120L,49121L,49122L,49123L,49124L,\n49125L,49126L,49127L,49128L,49129L,49130L,49131L,49132L,49133L,49134L,\n49135L,49136L,49137L,49138L,49139L,49140L,49141L,49142L,49143L,49144L,\n49145L,49146L,49147L,49148L,49149L,49150L,49151L,49152L,49153L,49154L,\n49155L,49156L,49157L,49158L,49159L,49160L,49161L,49162L,49163L,49164L,\n49165L,49166L,49167L,49168L,49169L,49170L,49171L,49172L,49173L,49174L,\n49175L,49176L,49177L,49178L,49179L,49180L,49181L,49182L,49183L,49184L,\n49185L,49186L,49187L,49188L,49189L,49190L,49191L,49192L,49193L,49194L,\n49195L,49196L,49197L,49198L,49199L,49200L,49201L,49202L,49203L,49204L,\n49205L,49206L,49207L,49208L,49209L,49210L,49211L,49212L,49213L,49214L,\n49215L,49216L,49217L,49218L,49219L,49220L,49221L,49222L,49223L,49224L,\n49225L,49226L,49227L,49228L,49229L,49230L,49231L,49232L,49233L,49234L,\n49235L,49236L,49237L,49238L,49239L,49240L,49241L,49242L,49243L,49244L,\n49245L,49246L,49247L,49248L,49249L,49250L,49251L,49252L,49253L,49254L,\n49255L,49256L,49257L,49258L,49259L,49260L,49261L,49262L,49263L,49264L,\n49265L,49266L,49267L,49268L,49269L,49270L,49271L,49272L,49273L,49274L,\n49275L,49276L,49277L,49278L,49279L,49280L,49281L,49282L,49283L,49284L,\n49285L,49286L,49287L,49288L,49289L,49290L,49291L,49292L,49293L,49294L,\n49295L,49296L,49297L,49298L,49299L,49300L,49301L,49302L,49303L,49304L,\n49305L,49306L,49307L,49308L,49309L,49310L,49311L,49312L,49313L,49314L,\n49315L,49316L,49317L,49318L,49319L,49320L,49321L,49322L,49323L,49324L,\n49325L,49326L,49327L,49328L,49329L,49330L,49331L,49332L,49333L,49334L,\n49335L,49336L,49337L,49338L,49339L,49340L,49341L,49342L,49343L,49344L,\n49345L,49346L,49347L,49348L,49349L,49350L,49351L,49352L,49353L,49354L,\n49355L,49356L,49357L,49358L,49359L,49360L,49361L,49362L,49363L,49364L,\n49365L,49366L,49367L,49368L,49369L,49370L,49371L,49372L,49373L,49374L,\n49375L,49376L,49377L,49378L,49379L,49380L,49381L,49382L,49383L,49384L,\n49385L,49386L,49387L,49388L,49389L,49390L,49391L,49392L,49393L,49394L,\n49395L,49396L,49397L,49398L,49399L,49400L,49401L,49402L,49403L,49404L,\n49405L,49406L,49407L,49408L,49409L,49410L,49411L,49412L,49413L,49414L,\n49415L,49416L,49417L,49418L,49419L,49420L,49421L,49422L,49423L,49424L,\n49425L,49426L,49427L,49428L,49429L,49430L,49431L,49432L,49433L,49434L,\n49435L,49436L,49437L,49438L,49439L,49440L,49441L,49442L,49443L,49444L,\n49445L,49446L,49447L,49448L,49449L,49450L,49451L,49452L,49453L,49454L,\n49455L,49456L,49457L,49458L,49459L,49460L,49461L,49462L,49463L,49464L,\n49465L,49466L,49467L,49468L,49469L,49470L,49471L,49472L,49473L,49474L,\n49475L,49476L,49477L,49478L,49479L,49480L,49481L,49482L,49483L,49484L,\n49485L,49486L,49487L,49488L,49489L,49490L,49491L,49492L,49493L,49494L,\n49495L,49496L,49497L,49498L,49499L,49500L,49501L,49502L,49503L,49504L,\n49505L,49506L,49507L,49508L,49509L,49510L,49511L,49512L,49513L,49514L,\n49515L,49516L,49517L,49518L,49519L,49520L,49521L,49522L,49523L,49524L,\n49525L,49526L,49527L,49528L,49529L,49530L,49531L,49532L,49533L,49534L,\n49535L,49536L,49537L,49538L,49539L,49540L,49541L,49542L,49543L,49544L,\n49545L,49546L,49547L,49548L,49549L,49550L,49551L,49552L,49553L,49554L,\n49555L,49556L,49557L,49558L,49559L,49560L,49561L,49562L,49563L,49564L,\n49565L,49566L,49567L,49568L,49569L,49570L,49571L,49572L,49573L,49574L,\n49575L,49576L,49577L,49578L,49579L,49580L,49581L,49582L,49583L,49584L,\n49585L,49586L,49587L,49588L,49589L,49590L,49591L,49592L,49593L,49594L,\n49595L,49596L,49597L,49598L,49599L,49600L,49601L,49602L,49603L,49604L,\n49605L,49606L,49607L,49608L,49609L,49610L,49611L,49612L,49613L,49614L,\n49615L,49616L,49617L,49618L,49619L,49620L,49621L,49622L,49623L,49624L,\n49625L,49626L,49627L,49628L,49629L,49630L,49631L,49632L,49633L,49634L,\n49635L,49636L,49637L,49638L,49639L,49640L,49641L,49642L,49643L,49644L,\n49645L,49646L,49647L,49648L,49649L,49650L,49651L,49652L,49653L,49654L,\n49655L,49656L,49657L,49658L,49659L,49660L,49661L,49662L,49663L,49664L,\n49665L,49666L,49667L,49668L,49669L,49670L,49671L,49672L,49673L,49674L,\n49675L,49676L,49677L,49678L,49679L,49680L,49681L,49682L,49683L,49684L,\n49685L,49686L,49687L,49688L,49689L,49690L,49691L,49692L,49693L,49694L,\n49695L,49696L,49697L,49698L,49699L,49700L,49701L,49702L,49703L,49704L,\n49705L,49706L,49707L,49708L,49709L,49710L,49711L,49712L,49713L,49714L,\n49715L,49716L,49717L,49718L,49719L,49720L,49721L,49722L,49723L,49724L,\n49725L,49726L,49727L,49728L,49729L,49730L,49731L,49732L,49733L,49734L,\n49735L,49736L,49737L,49738L,49739L,49740L,49741L,49742L,49743L,49744L,\n49745L,49746L,49747L,49748L,49749L,49750L,49751L,49752L,49753L,49754L,\n49755L,49756L,49757L,49758L,49759L,49760L,49761L,49762L,49763L,49764L,\n49765L,49766L,49767L,49768L,49769L,49770L,49771L,49772L,49773L,49774L,\n49775L,49776L,49777L,49778L,49779L,49780L,49781L,49782L,49783L,49784L,\n49785L,49786L,49787L,49788L,49789L,49790L,49791L,49792L,49793L,49794L,\n49795L,49796L,49797L,49798L,49799L,49800L,49801L,49802L,49803L,49804L,\n49805L,49806L,49807L,49808L,49809L,49810L,49811L,49812L,49813L,49814L,\n49815L,49816L,49817L,49818L,49819L,49820L,49821L,49822L,49823L,49824L,\n49825L,49826L,49827L,49828L,49829L,49830L,49831L,49832L,49833L,49834L,\n49835L,49836L,49837L,49838L,49839L,49840L,49841L,49842L,49843L,49844L,\n49845L,49846L,49847L,49848L,49849L,49850L,49851L,49852L,49853L,49854L,\n49855L,49856L,49857L,49858L,49859L,49860L,49861L,49862L,49863L,49864L,\n49865L,49866L,49867L,49868L,49869L,49870L,49871L,49872L,49873L,49874L,\n49875L,49876L,49877L,49878L,49879L,49880L,49881L,49882L,49883L,49884L,\n49885L,49886L,49887L,49888L,49889L,49890L,49891L,49892L,49893L,49894L,\n49895L,49896L,49897L,49898L,49899L,49900L,49901L,49902L,49903L,49904L,\n49905L,49906L,49907L,49908L,49909L,49910L,49911L,49912L,49913L,49914L,\n49915L,49916L,49917L,49918L,49919L,49920L,49921L,49922L,49923L,49924L,\n49925L,49926L,49927L,49928L,49929L,49930L,49931L,49932L,49933L,49934L,\n49935L,49936L,49937L,49938L,49939L,49940L,49941L,49942L,49943L,49944L,\n49945L,49946L,49947L,49948L,49949L,49950L,49951L,49952L,49953L,49954L,\n49955L,49956L,49957L,49958L,49959L,49960L,49961L,49962L,49963L,49964L,\n49965L,49966L,49967L,49968L,49969L,49970L,49971L,49972L,49973L,49974L,\n49975L,49976L,49977L,49978L,49979L,49980L,49981L,49982L,49983L,49984L,\n49985L,49986L,49987L,49988L,49989L,49990L,49991L,49992L,49993L,49994L,\n49995L,49996L,49997L,49998L,49999L,50000L,50001L,50002L,50003L,50004L,\n50005L,50006L,50007L,50008L,50009L,50010L,50011L,50012L,50013L,50014L,\n50015L,50016L,50017L,50018L,50019L,50020L,50021L,50022L,50023L,50024L,\n50025L,50026L,50027L,50028L,50029L,50030L,50031L,50032L,50033L,50034L,\n50035L,50036L,50037L,50038L,50039L,50040L,50041L,50042L,50043L,50044L,\n50045L,50046L,50047L,50048L,50049L,50050L,50051L,50052L,50053L,50054L,\n50055L,50056L,50057L,50058L,50059L,50060L,50061L,50062L,50063L,50064L,\n50065L,50066L,50067L,50068L,50069L,50070L,50071L,50072L,50073L,50074L,\n50075L,50076L,50077L,50078L,50079L,50080L,50081L,50082L,50083L,50084L,\n50085L,50086L,50087L,50088L,50089L,50090L,50091L,50092L,50093L,50094L,\n50095L,50096L,50097L,50098L,50099L,50100L,50101L,50102L,50103L,50104L,\n50105L,50106L,50107L,50108L,50109L,50110L,50111L,50112L,50113L,50114L,\n50115L,50116L,50117L,50118L,50119L,50120L,50121L,50122L,50123L,50124L,\n50125L,50126L,50127L,50128L,50129L,50130L,50131L,50132L,50133L,50134L,\n50135L,50136L,50137L,50138L,50139L,50140L,50141L,50142L,50143L,50144L,\n50145L,50146L,50147L,50148L,50149L,50150L,50151L,50152L,50153L,50154L,\n50155L,50156L,50157L,50158L,50159L,50160L,50161L,50162L,50163L,50164L,\n50165L,50166L,50167L,50168L,50169L,50170L,50171L,50172L,50173L,50174L,\n50175L,50176L,50177L,50178L,50179L,50180L,50181L,50182L,50183L,50184L,\n50185L,50186L,50187L,50188L,50189L,50190L,50191L,50192L,50193L,50194L,\n50195L,50196L,50197L,50198L,50199L,50200L,50201L,50202L,50203L,50204L,\n50205L,50206L,50207L,50208L,50209L,50210L,50211L,50212L,50213L,50214L,\n50215L,50216L,50217L,50218L,50219L,50220L,50221L,50222L,50223L,50224L,\n50225L,50226L,50227L,50228L,50229L,50230L,50231L,50232L,50233L,50234L,\n50235L,50236L,50237L,50238L,50239L,50240L,50241L,50242L,50243L,50244L,\n50245L,50246L,50247L,50248L,50249L,50250L,50251L,50252L,50253L,50254L,\n50255L,50256L,50257L,50258L,50259L,50260L,50261L,50262L,50263L,50264L,\n50265L,50266L,50267L,50268L,50269L,50270L,50271L,50272L,50273L,50274L,\n50275L,50276L,50277L,50278L,50279L,50280L,50281L,50282L,50283L,50284L,\n50285L,50286L,50287L,50288L,50289L,50290L,50291L,50292L,50293L,50294L,\n50295L,50296L,50297L,50298L,50299L,50300L,50301L,50302L,50303L,50304L,\n50305L,50306L,50307L,50308L,50309L,50310L,50311L,50312L,50313L,50314L,\n50315L,50316L,50317L,50318L,50319L,50320L,50321L,50322L,50323L,50324L,\n50325L,50326L,50327L,50328L,50329L,50330L,50331L,50332L,50333L,50334L,\n50335L,50336L,50337L,50338L,50339L,50340L,50341L,50342L,50343L,50344L,\n50345L,50346L,50347L,50348L,50349L,50350L,50351L,50352L,50353L,50354L,\n50355L,50356L,50357L,50358L,50359L,50360L,50361L,50362L,50363L,50364L,\n50365L,50366L,50367L,50368L,50369L,50370L,50371L,50372L,50373L,50374L,\n50375L,50376L,50377L,50378L,50379L,50380L,50381L,50382L,50383L,50384L,\n50385L,50386L,50387L,50388L,50389L,50390L,50391L,50392L,50393L,50394L,\n50395L,50396L,50397L,50398L,50399L,50400L,50401L,50402L,50403L,50404L,\n50405L,50406L,50407L,50408L,50409L,50410L,50411L,50412L,50413L,50414L,\n50415L,50416L,50417L,50418L,50419L,50420L,50421L,50422L,50423L,50424L,\n50425L,50426L,50427L,50428L,50429L,50430L,50431L,50432L,50433L,50434L,\n50435L,50436L,50437L,50438L,50439L,50440L,50441L,50442L,50443L,50444L,\n50445L,50446L,50447L,50448L,50449L,50450L,50451L,50452L,50453L,50454L,\n50455L,50456L,50457L,50458L,50459L,50460L,50461L,50462L,50463L,50464L,\n50465L,50466L,50467L,50468L,50469L,50470L,50471L,50472L,50473L,50474L,\n50475L,50476L,50477L,50478L,50479L,50480L,50481L,50482L,50483L,50484L,\n50485L,50486L,50487L,50488L,50489L,50490L,50491L,50492L,50493L,50494L,\n50495L,50496L,50497L,50498L,50499L,50500L,50501L,50502L,50503L,50504L,\n50505L,50506L,50507L,50508L,50509L,50510L,50511L,50512L,50513L,50514L,\n50515L,50516L,50517L,50518L,50519L,50520L,50521L,50522L,50523L,50524L,\n50525L,50526L,50527L,50528L,50529L,50530L,50531L,50532L,50533L,50534L,\n50535L,50536L,50537L,50538L,50539L,50540L,50541L,50542L,50543L,50544L,\n50545L,50546L,50547L,50548L,50549L,50550L,50551L,50552L,50553L,50554L,\n50555L,50556L,50557L,50558L,50559L,50560L,50561L,50562L,50563L,50564L,\n50565L,50566L,50567L,50568L,50569L,50570L,50571L,50572L,50573L,50574L,\n50575L,50576L,50577L,50578L,50579L,50580L,50581L,50582L,50583L,50584L,\n50585L,50586L,50587L,50588L,50589L,50590L,50591L,50592L,50593L,50594L,\n50595L,50596L,50597L,50598L,50599L,50600L,50601L,50602L,50603L,50604L,\n50605L,50606L,50607L,50608L,50609L,50610L,50611L,50612L,50613L,50614L,\n50615L,50616L,50617L,50618L,50619L,50620L,50621L,50622L,50623L,50624L,\n50625L,50626L,50627L,50628L,50629L,50630L,50631L,50632L,50633L,50634L,\n50635L,50636L,50637L,50638L,50639L,50640L,50641L,50642L,50643L,50644L,\n50645L,50646L,50647L,50648L,50649L,50650L,50651L,50652L,50653L,50654L,\n50655L,50656L,50657L,50658L,50659L,50660L,50661L,50662L,50663L,50664L,\n50665L,50666L,50667L,50668L,50669L,50670L,50671L,50672L,50673L,50674L,\n50675L,50676L,50677L,50678L,50679L,50680L,50681L,50682L,50683L,50684L,\n50685L,50686L,50687L,50688L,50689L,50690L,50691L,50692L,50693L,50694L,\n50695L,50696L,50697L,50698L,50699L,50700L,50701L,50702L,50703L,50704L,\n50705L,50706L,50707L,50708L,50709L,50710L,50711L,50712L,50713L,50714L,\n50715L,50716L,50717L,50718L,50719L,50720L,50721L,50722L,50723L,50724L,\n50725L,50726L,50727L,50728L,50729L,50730L,50731L,50732L,50733L,50734L,\n50735L,50736L,50737L,50738L,50739L,50740L,50741L,50742L,50743L,50744L,\n50745L,50746L,50747L,50748L,50749L,50750L,50751L,50752L,50753L,50754L,\n50755L,50756L,50757L,50758L,50759L,50760L,50761L,50762L,50763L,50764L,\n50765L,50766L,50767L,50768L,50769L,50770L,50771L,50772L,50773L,50774L,\n50775L,50776L,50777L,50778L,50779L,50780L,50781L,50782L,50783L,50784L,\n50785L,50786L,50787L,50788L,50789L,50790L,50791L,50792L,50793L,50794L,\n50795L,50796L,50797L,50798L,50799L,50800L,50801L,50802L,50803L,50804L,\n50805L,50806L,50807L,50808L,50809L,50810L,50811L,50812L,50813L,50814L,\n50815L,50816L,50817L,50818L,50819L,50820L,50821L,50822L,50823L,50824L,\n50825L,50826L,50827L,50828L,50829L,50830L,50831L,50832L,50833L,50834L,\n50835L,50836L,50837L,50838L,50839L,50840L,50841L,50842L,50843L,50844L,\n50845L,50846L,50847L,50848L,50849L,50850L,50851L,50852L,50853L,50854L,\n50855L,50856L,50857L,50858L,50859L,50860L,50861L,50862L,50863L,50864L,\n50865L,50866L,50867L,50868L,50869L,50870L,50871L,50872L,50873L,50874L,\n50875L,50876L,50877L,50878L,50879L,50880L,50881L,50882L,50883L,50884L,\n50885L,50886L,50887L,50888L,50889L,50890L,50891L,50892L,50893L,50894L,\n50895L,50896L,50897L,50898L,50899L,50900L,50901L,50902L,50903L,50904L,\n50905L,50906L,50907L,50908L,50909L,50910L,50911L,50912L,50913L,50914L,\n50915L,50916L,50917L,50918L,50919L,50920L,50921L,50922L,50923L,50924L,\n50925L,50926L,50927L,50928L,50929L,50930L,50931L,50932L,50933L,50934L,\n50935L,50936L,50937L,50938L,50939L,50940L,50941L,50942L,50943L,50944L,\n50945L,50946L,50947L,50948L,50949L,50950L,50951L,50952L,50953L,50954L,\n50955L,50956L,50957L,50958L,50959L,50960L,50961L,50962L,50963L,50964L,\n50965L,50966L,50967L,50968L,50969L,50970L,50971L,50972L,50973L,50974L,\n50975L,50976L,50977L,50978L,50979L,50980L,50981L,50982L,50983L,50984L,\n50985L,50986L,50987L,50988L,50989L,50990L,50991L,50992L,50993L,50994L,\n50995L,50996L,50997L,50998L,50999L,51000L,51001L,51002L,51003L,51004L,\n51005L,51006L,51007L,51008L,51009L,51010L,51011L,51012L,51013L,51014L,\n51015L,51016L,51017L,51018L,51019L,51020L,51021L,51022L,51023L,51024L,\n51025L,51026L,51027L,51028L,51029L,51030L,51031L,51032L,51033L,51034L,\n51035L,51036L,51037L,51038L,51039L,51040L,51041L,51042L,51043L,51044L,\n51045L,51046L,51047L,51048L,51049L,51050L,51051L,51052L,51053L,51054L,\n51055L,51056L,51057L,51058L,51059L,51060L,51061L,51062L,51063L,51064L,\n51065L,51066L,51067L,51068L,51069L,51070L,51071L,51072L,51073L,51074L,\n51075L,51076L,51077L,51078L,51079L,51080L,51081L,51082L,51083L,51084L,\n51085L,51086L,51087L,51088L,51089L,51090L,51091L,51092L,51093L,51094L,\n51095L,51096L,51097L,51098L,51099L,51100L,51101L,51102L,51103L,51104L,\n51105L,51106L,51107L,51108L,51109L,51110L,51111L,51112L,51113L,51114L,\n51115L,51116L,51117L,51118L,51119L,51120L,51121L,51122L,51123L,51124L,\n51125L,51126L,51127L,51128L,51129L,51130L,51131L,51132L,51133L,51134L,\n51135L,51136L,51137L,51138L,51139L,51140L,51141L,51142L,51143L,51144L,\n51145L,51146L,51147L,51148L,51149L,51150L,51151L,51152L,51153L,51154L,\n51155L,51156L,51157L,51158L,51159L,51160L,51161L,51162L,51163L,51164L,\n51165L,51166L,51167L,51168L,51169L,51170L,51171L,51172L,51173L,51174L,\n51175L,51176L,51177L,51178L,51179L,51180L,51181L,51182L,51183L,51184L,\n51185L,51186L,51187L,51188L,51189L,51190L,51191L,51192L,51193L,51194L,\n51195L,51196L,51197L,51198L,51199L,51200L,51201L,51202L,51203L,51204L,\n51205L,51206L,51207L,51208L,51209L,51210L,51211L,51212L,51213L,51214L,\n51215L,51216L,51217L,51218L,51219L,51220L,51221L,51222L,51223L,51224L,\n51225L,51226L,51227L,51228L,51229L,51230L,51231L,51232L,51233L,51234L,\n51235L,51236L,51237L,51238L,51239L,51240L,51241L,51242L,51243L,51244L,\n51245L,51246L,51247L,51248L,51249L,51250L,51251L,51252L,51253L,51254L,\n51255L,51256L,51257L,51258L,51259L,51260L,51261L,51262L,51263L,51264L,\n51265L,51266L,51267L,51268L,51269L,51270L,51271L,51272L,51273L,51274L,\n51275L,51276L,51277L,51278L,51279L,51280L,51281L,51282L,51283L,51284L,\n51285L,51286L,51287L,51288L,51289L,51290L,51291L,51292L,51293L,51294L,\n51295L,51296L,51297L,51298L,51299L,51300L,51301L,51302L,51303L,51304L,\n51305L,51306L,51307L,51308L,51309L,51310L,51311L,51312L,51313L,51314L,\n51315L,51316L,51317L,51318L,51319L,51320L,51321L,51322L,51323L,51324L,\n51325L,51326L,51327L,51328L,51329L,51330L,51331L,51332L,51333L,51334L,\n51335L,51336L,51337L,51338L,51339L,51340L,51341L,51342L,51343L,51344L,\n51345L,51346L,51347L,51348L,51349L,51350L,51351L,51352L,51353L,51354L,\n51355L,51356L,51357L,51358L,51359L,51360L,51361L,51362L,51363L,51364L,\n51365L,51366L,51367L,51368L,51369L,51370L,51371L,51372L,51373L,51374L,\n51375L,51376L,51377L,51378L,51379L,51380L,51381L,51382L,51383L,51384L,\n51385L,51386L,51387L,51388L,51389L,51390L,51391L,51392L,51393L,51394L,\n51395L,51396L,51397L,51398L,51399L,51400L,51401L,51402L,51403L,51404L,\n51405L,51406L,51407L,51408L,51409L,51410L,51411L,51412L,51413L,51414L,\n51415L,51416L,51417L,51418L,51419L,51420L,51421L,51422L,51423L,51424L,\n51425L,51426L,51427L,51428L,51429L,51430L,51431L,51432L,51433L,51434L,\n51435L,51436L,51437L,51438L,51439L,51440L,51441L,51442L,51443L,51444L,\n51445L,51446L,51447L,51448L,51449L,51450L,51451L,51452L,51453L,51454L,\n51455L,51456L,51457L,51458L,51459L,51460L,51461L,51462L,51463L,51464L,\n51465L,51466L,51467L,51468L,51469L,51470L,51471L,51472L,51473L,51474L,\n51475L,51476L,51477L,51478L,51479L,51480L,51481L,51482L,51483L,51484L,\n51485L,51486L,51487L,51488L,51489L,51490L,51491L,51492L,51493L,51494L,\n51495L,51496L,51497L,51498L,51499L,51500L,51501L,51502L,51503L,51504L,\n51505L,51506L,51507L,51508L,51509L,51510L,51511L,51512L,51513L,51514L,\n51515L,51516L,51517L,51518L,51519L,51520L,51521L,51522L,51523L,51524L,\n51525L,51526L,51527L,51528L,51529L,51530L,51531L,51532L,51533L,51534L,\n51535L,51536L,51537L,51538L,51539L,51540L,51541L,51542L,51543L,51544L,\n51545L,51546L,51547L,51548L,51549L,51550L,51551L,51552L,51553L,51554L,\n51555L,51556L,51557L,51558L,51559L,51560L,51561L,51562L,51563L,51564L,\n51565L,51566L,51567L,51568L,51569L,51570L,51571L,51572L,51573L,51574L,\n51575L,51576L,51577L,51578L,51579L,51580L,51581L,51582L,51583L,51584L,\n51585L,51586L,51587L,51588L,51589L,51590L,51591L,51592L,51593L,51594L,\n51595L,51596L,51597L,51598L,51599L,51600L,51601L,51602L,51603L,51604L,\n51605L,51606L,51607L,51608L,51609L,51610L,51611L,51612L,51613L,51614L,\n51615L,51616L,51617L,51618L,51619L,51620L,51621L,51622L,51623L,51624L,\n51625L,51626L,51627L,51628L,51629L,51630L,51631L,51632L,51633L,51634L,\n51635L,51636L,51637L,51638L,51639L,51640L,51641L,51642L,51643L,51644L,\n51645L,51646L,51647L,51648L,51649L,51650L,51651L,51652L,51653L,51654L,\n51655L,51656L,51657L,51658L,51659L,51660L,51661L,51662L,51663L,51664L,\n51665L,51666L,51667L,51668L,51669L,51670L,51671L,51672L,51673L,51674L,\n51675L,51676L,51677L,51678L,51679L,51680L,51681L,51682L,51683L,51684L,\n51685L,51686L,51687L,51688L,51689L,51690L,51691L,51692L,51693L,51694L,\n51695L,51696L,51697L,51698L,51699L,51700L,51701L,51702L,51703L,51704L,\n51705L,51706L,51707L,51708L,51709L,51710L,51711L,51712L,51713L,51714L,\n51715L,51716L,51717L,51718L,51719L,51720L,51721L,51722L,51723L,51724L,\n51725L,51726L,51727L,51728L,51729L,51730L,51731L,51732L,51733L,51734L,\n51735L,51736L,51737L,51738L,51739L,51740L,51741L,51742L,51743L,51744L,\n51745L,51746L,51747L,51748L,51749L,51750L,51751L,51752L,51753L,51754L,\n51755L,51756L,51757L,51758L,51759L,51760L,51761L,51762L,51763L,51764L,\n51765L,51766L,51767L,51768L,51769L,51770L,51771L,51772L,51773L,51774L,\n51775L,51776L,51777L,51778L,51779L,51780L,51781L,51782L,51783L,51784L,\n51785L,51786L,51787L,51788L,51789L,51790L,51791L,51792L,51793L,51794L,\n51795L,51796L,51797L,51798L,51799L,51800L,51801L,51802L,51803L,51804L,\n51805L,51806L,51807L,51808L,51809L,51810L,51811L,51812L,51813L,51814L,\n51815L,51816L,51817L,51818L,51819L,51820L,51821L,51822L,51823L,51824L,\n51825L,51826L,51827L,51828L,51829L,51830L,51831L,51832L,51833L,51834L,\n51835L,51836L,51837L,51838L,51839L,51840L,51841L,51842L,51843L,51844L,\n51845L,51846L,51847L,51848L,51849L,51850L,51851L,51852L,51853L,51854L,\n51855L,51856L,51857L,51858L,51859L,51860L,51861L,51862L,51863L,51864L,\n51865L,51866L,51867L,51868L,51869L,51870L,51871L,51872L,51873L,51874L,\n51875L,51876L,51877L,51878L,51879L,51880L,51881L,51882L,51883L,51884L,\n51885L,51886L,51887L,51888L,51889L,51890L,51891L,51892L,51893L,51894L,\n51895L,51896L,51897L,51898L,51899L,51900L,51901L,51902L,51903L,51904L,\n51905L,51906L,51907L,51908L,51909L,51910L,51911L,51912L,51913L,51914L,\n51915L,51916L,51917L,51918L,51919L,51920L,51921L,51922L,51923L,51924L,\n51925L,51926L,51927L,51928L,51929L,51930L,51931L,51932L,51933L,51934L,\n51935L,51936L,51937L,51938L,51939L,51940L,51941L,51942L,51943L,51944L,\n51945L,51946L,51947L,51948L,51949L,51950L,51951L,51952L,51953L,51954L,\n51955L,51956L,51957L,51958L,51959L,51960L,51961L,51962L,51963L,51964L,\n51965L,51966L,51967L,51968L,51969L,51970L,51971L,51972L,51973L,51974L,\n51975L,51976L,51977L,51978L,51979L,51980L,51981L,51982L,51983L,51984L,\n51985L,51986L,51987L,51988L,51989L,51990L,51991L,51992L,51993L,51994L,\n51995L,51996L,51997L,51998L,51999L,52000L,52001L,52002L,52003L,52004L,\n52005L,52006L,52007L,52008L,52009L,52010L,52011L,52012L,52013L,52014L,\n52015L,52016L,52017L,52018L,52019L,52020L,52021L,52022L,52023L,52024L,\n52025L,52026L,52027L,52028L,52029L,52030L,52031L,52032L,52033L,52034L,\n52035L,52036L,52037L,52038L,52039L,52040L,52041L,52042L,52043L,52044L,\n52045L,52046L,52047L,52048L,52049L,52050L,52051L,52052L,52053L,52054L,\n52055L,52056L,52057L,52058L,52059L,52060L,52061L,52062L,52063L,52064L,\n52065L,52066L,52067L,52068L,52069L,52070L,52071L,52072L,52073L,52074L,\n52075L,52076L,52077L,52078L,52079L,52080L,52081L,52082L,52083L,52084L,\n52085L,52086L,52087L,52088L,52089L,52090L,52091L,52092L,52093L,52094L,\n52095L,52096L,52097L,52098L,52099L,52100L,52101L,52102L,52103L,52104L,\n52105L,52106L,52107L,52108L,52109L,52110L,52111L,52112L,52113L,52114L,\n52115L,52116L,52117L,52118L,52119L,52120L,52121L,52122L,52123L,52124L,\n52125L,52126L,52127L,52128L,52129L,52130L,52131L,52132L,52133L,52134L,\n52135L,52136L,52137L,52138L,52139L,52140L,52141L,52142L,52143L,52144L,\n52145L,52146L,52147L,52148L,52149L,52150L,52151L,52152L,52153L,52154L,\n52155L,52156L,52157L,52158L,52159L,52160L,52161L,52162L,52163L,52164L,\n52165L,52166L,52167L,52168L,52169L,52170L,52171L,52172L,52173L,52174L,\n52175L,52176L,52177L,52178L,52179L,52180L,52181L,52182L,52183L,52184L,\n52185L,52186L,52187L,52188L,52189L,52190L,52191L,52192L,52193L,52194L,\n52195L,52196L,52197L,52198L,52199L,52200L,52201L,52202L,52203L,52204L,\n52205L,52206L,52207L,52208L,52209L,52210L,52211L,52212L,52213L,52214L,\n52215L,52216L,52217L,52218L,52219L,52220L,52221L,52222L,52223L,52224L,\n52225L,52226L,52227L,52228L,52229L,52230L,52231L,52232L,52233L,52234L,\n52235L,52236L,52237L,52238L,52239L,52240L,52241L,52242L,52243L,52244L,\n52245L,52246L,52247L,52248L,52249L,52250L,52251L,52252L,52253L,52254L,\n52255L,52256L,52257L,52258L,52259L,52260L,52261L,52262L,52263L,52264L,\n52265L,52266L,52267L,52268L,52269L,52270L,52271L,52272L,52273L,52274L,\n52275L,52276L,52277L,52278L,52279L,52280L,52281L,52282L,52283L,52284L,\n52285L,52286L,52287L,52288L,52289L,52290L,52291L,52292L,52293L,52294L,\n52295L,52296L,52297L,52298L,52299L,52300L,52301L,52302L,52303L,52304L,\n52305L,52306L,52307L,52308L,52309L,52310L,52311L,52312L,52313L,52314L,\n52315L,52316L,52317L,52318L,52319L,52320L,52321L,52322L,52323L,52324L,\n52325L,52326L,52327L,52328L,52329L,52330L,52331L,52332L,52333L,52334L,\n52335L,52336L,52337L,52338L,52339L,52340L,52341L,52342L,52343L,52344L,\n52345L,52346L,52347L,52348L,52349L,52350L,52351L,52352L,52353L,52354L,\n52355L,52356L,52357L,52358L,52359L,52360L,52361L,52362L,52363L,52364L,\n52365L,52366L,52367L,52368L,52369L,52370L,52371L,52372L,52373L,52374L,\n52375L,52376L,52377L,52378L,52379L,52380L,52381L,52382L,52383L,52384L,\n52385L,52386L,52387L,52388L,52389L,52390L,52391L,52392L,52393L,52394L,\n52395L,52396L,52397L,52398L,52399L,52400L,52401L,52402L,52403L,52404L,\n52405L,52406L,52407L,52408L,52409L,52410L,52411L,52412L,52413L,52414L,\n52415L,52416L,52417L,52418L,52419L,52420L,52421L,52422L,52423L,52424L,\n52425L,52426L,52427L,52428L,52429L,52430L,52431L,52432L,52433L,52434L,\n52435L,52436L,52437L,52438L,52439L,52440L,52441L,52442L,52443L,52444L,\n52445L,52446L,52447L,52448L,52449L,52450L,52451L,52452L,52453L,52454L,\n52455L,52456L,52457L,52458L,52459L,52460L,52461L,52462L,52463L,52464L,\n52465L,52466L,52467L,52468L,52469L,52470L,52471L,52472L,52473L,52474L,\n52475L,52476L,52477L,52478L,52479L,52480L,52481L,52482L,52483L,52484L,\n52485L,52486L,52487L,52488L,52489L,52490L,52491L,52492L,52493L,52494L,\n52495L,52496L,52497L,52498L,52499L,52500L,52501L,52502L,52503L,52504L,\n52505L,52506L,52507L,52508L,52509L,52510L,52511L,52512L,52513L,52514L,\n52515L,52516L,52517L,52518L,52519L,52520L,52521L,52522L,52523L,52524L,\n52525L,52526L,52527L,52528L,52529L,52530L,52531L,52532L,52533L,52534L,\n52535L,52536L,52537L,52538L,52539L,52540L,52541L,52542L,52543L,52544L,\n52545L,52546L,52547L,52548L,52549L,52550L,52551L,52552L,52553L,52554L,\n52555L,52556L,52557L,52558L,52559L,52560L,52561L,52562L,52563L,52564L,\n52565L,52566L,52567L,52568L,52569L,52570L,52571L,52572L,52573L,52574L,\n52575L,52576L,52577L,52578L,52579L,52580L,52581L,52582L,52583L,52584L,\n52585L,52586L,52587L,52588L,52589L,52590L,52591L,52592L,52593L,52594L,\n52595L,52596L,52597L,52598L,52599L,52600L,52601L,52602L,52603L,52604L,\n52605L,52606L,52607L,52608L,52609L,52610L,52611L,52612L,52613L,52614L,\n52615L,52616L,52617L,52618L,52619L,52620L,52621L,52622L,52623L,52624L,\n52625L,52626L,52627L,52628L,52629L,52630L,52631L,52632L,52633L,52634L,\n52635L,52636L,52637L,52638L,52639L,52640L,52641L,52642L,52643L,52644L,\n52645L,52646L,52647L,52648L,52649L,52650L,52651L,52652L,52653L,52654L,\n52655L,52656L,52657L,52658L,52659L,52660L,52661L,52662L,52663L,52664L,\n52665L,52666L,52667L,52668L,52669L,52670L,52671L,52672L,52673L,52674L,\n52675L,52676L,52677L,52678L,52679L,52680L,52681L,52682L,52683L,52684L,\n52685L,52686L,52687L,52688L,52689L,52690L,52691L,52692L,52693L,52694L,\n52695L,52696L,52697L,52698L,52699L,52700L,52701L,52702L,52703L,52704L,\n52705L,52706L,52707L,52708L,52709L,52710L,52711L,52712L,52713L,52714L,\n52715L,52716L,52717L,52718L,52719L,52720L,52721L,52722L,52723L,52724L,\n52725L,52726L,52727L,52728L,52729L,52730L,52731L,52732L,52733L,52734L,\n52735L,52736L,52737L,52738L,52739L,52740L,52741L,52742L,52743L,52744L,\n52745L,52746L,52747L,52748L,52749L,52750L,52751L,52752L,52753L,52754L,\n52755L,52756L,52757L,52758L,52759L,52760L,52761L,52762L,52763L,52764L,\n52765L,52766L,52767L,52768L,52769L,52770L,52771L,52772L,52773L,52774L,\n52775L,52776L,52777L,52778L,52779L,52780L,52781L,52782L,52783L,52784L,\n52785L,52786L,52787L,52788L,52789L,52790L,52791L,52792L,52793L,52794L,\n52795L,52796L,52797L,52798L,52799L,52800L,52801L,52802L,52803L,52804L,\n52805L,52806L,52807L,52808L,52809L,52810L,52811L,52812L,52813L,52814L,\n52815L,52816L,52817L,52818L,52819L,52820L,52821L,52822L,52823L,52824L,\n52825L,52826L,52827L,52828L,52829L,52830L,52831L,52832L,52833L,52834L,\n52835L,52836L,52837L,52838L,52839L,52840L,52841L,52842L,52843L,52844L,\n52845L,52846L,52847L,52848L,52849L,52850L,52851L,52852L,52853L,52854L,\n52855L,52856L,52857L,52858L,52859L,52860L,52861L,52862L,52863L,52864L,\n52865L,52866L,52867L,52868L,52869L,52870L,52871L,52872L,52873L,52874L,\n52875L,52876L,52877L,52878L,52879L,52880L,52881L,52882L,52883L,52884L,\n52885L,52886L,52887L,52888L,52889L,52890L,52891L,52892L,52893L,52894L,\n52895L,52896L,52897L,52898L,52899L,52900L,52901L,52902L,52903L,52904L,\n52905L,52906L,52907L,52908L,52909L,52910L,52911L,52912L,52913L,52914L,\n52915L,52916L,52917L,52918L,52919L,52920L,52921L,52922L,52923L,52924L,\n52925L,52926L,52927L,52928L,52929L,52930L,52931L,52932L,52933L,52934L,\n52935L,52936L,52937L,52938L,52939L,52940L,52941L,52942L,52943L,52944L,\n52945L,52946L,52947L,52948L,52949L,52950L,52951L,52952L,52953L,52954L,\n52955L,52956L,52957L,52958L,52959L,52960L,52961L,52962L,52963L,52964L,\n52965L,52966L,52967L,52968L,52969L,52970L,52971L,52972L,52973L,52974L,\n52975L,52976L,52977L,52978L,52979L,52980L,52981L,52982L,52983L,52984L,\n52985L,52986L,52987L,52988L,52989L,52990L,52991L,52992L,52993L,52994L,\n52995L,52996L,52997L,52998L,52999L,53000L,53001L,53002L,53003L,53004L,\n53005L,53006L,53007L,53008L,53009L,53010L,53011L,53012L,53013L,53014L,\n53015L,53016L,53017L,53018L,53019L,53020L,53021L,53022L,53023L,53024L,\n53025L,53026L,53027L,53028L,53029L,53030L,53031L,53032L,53033L,53034L,\n53035L,53036L,53037L,53038L,53039L,53040L,53041L,53042L,53043L,53044L,\n53045L,53046L,53047L,53048L,53049L,53050L,53051L,53052L,53053L,53054L,\n53055L,53056L,53057L,53058L,53059L,53060L,53061L,53062L,53063L,53064L,\n53065L,53066L,53067L,53068L,53069L,53070L,53071L,53072L,53073L,53074L,\n53075L,53076L,53077L,53078L,53079L,53080L,53081L,53082L,53083L,53084L,\n53085L,53086L,53087L,53088L,53089L,53090L,53091L,53092L,53093L,53094L,\n53095L,53096L,53097L,53098L,53099L,53100L,53101L,53102L,53103L,53104L,\n53105L,53106L,53107L,53108L,53109L,53110L,53111L,53112L,53113L,53114L,\n53115L,53116L,53117L,53118L,53119L,53120L,53121L,53122L,53123L,53124L,\n53125L,53126L,53127L,53128L,53129L,53130L,53131L,53132L,53133L,53134L,\n53135L,53136L,53137L,53138L,53139L,53140L,53141L,53142L,53143L,53144L,\n53145L,53146L,53147L,53148L,53149L,53150L,53151L,53152L,53153L,53154L,\n53155L,53156L,53157L,53158L,53159L,53160L,53161L,53162L,53163L,53164L,\n53165L,53166L,53167L,53168L,53169L,53170L,53171L,53172L,53173L,53174L,\n53175L,53176L,53177L,53178L,53179L,53180L,53181L,53182L,53183L,53184L,\n53185L,53186L,53187L,53188L,53189L,53190L,53191L,53192L,53193L,53194L,\n53195L,53196L,53197L,53198L,53199L,53200L,53201L,53202L,53203L,53204L,\n53205L,53206L,53207L,53208L,53209L,53210L,53211L,53212L,53213L,53214L,\n53215L,53216L,53217L,53218L,53219L,53220L,53221L,53222L,53223L,53224L,\n53225L,53226L,53227L,53228L,53229L,53230L,53231L,53232L,53233L,53234L,\n53235L,53236L,53237L,53238L,53239L,53240L,53241L,53242L,53243L,53244L,\n53245L,53246L,53247L,53248L,53249L,53250L,53251L,53252L,53253L,53254L,\n53255L,53256L,53257L,53258L,53259L,53260L,53261L,53262L,53263L,53264L,\n53265L,53266L,53267L,53268L,53269L,53270L,53271L,53272L,53273L,53274L,\n53275L,53276L,53277L,53278L,53279L,53280L,53281L,53282L,53283L,53284L,\n53285L,53286L,53287L,53288L,53289L,53290L,53291L,53292L,53293L,53294L,\n53295L,53296L,53297L,53298L,53299L,53300L,53301L,53302L,53303L,53304L,\n53305L,53306L,53307L,53308L,53309L,53310L,53311L,53312L,53313L,53314L,\n53315L,53316L,53317L,53318L,53319L,53320L,53321L,53322L,53323L,53324L,\n53325L,53326L,53327L,53328L,53329L,53330L,53331L,53332L,53333L,53334L,\n53335L,53336L,53337L,53338L,53339L,53340L,53341L,53342L,53343L,53344L,\n53345L,53346L,53347L,53348L,53349L,53350L,53351L,53352L,53353L,53354L,\n53355L,53356L,53357L,53358L,53359L,53360L,53361L,53362L,53363L,53364L,\n53365L,53366L,53367L,53368L,53369L,53370L,53371L,53372L,53373L,53374L,\n53375L,53376L,53377L,53378L,53379L,53380L,53381L,53382L,53383L,53384L,\n53385L,53386L,53387L,53388L,53389L,53390L,53391L,53392L,53393L,53394L,\n53395L,53396L,53397L,53398L,53399L,53400L,53401L,53402L,53403L,53404L,\n53405L,53406L,53407L,53408L,53409L,53410L,53411L,53412L,53413L,53414L,\n53415L,53416L,53417L,53418L,53419L,53420L,53421L,53422L,53423L,53424L,\n53425L,53426L,53427L,53428L,53429L,53430L,53431L,53432L,53433L,53434L,\n53435L,53436L,53437L,53438L,53439L,53440L,53441L,53442L,53443L,53444L,\n53445L,53446L,53447L,53448L,53449L,53450L,53451L,53452L,53453L,53454L,\n53455L,53456L,53457L,53458L,53459L,53460L,53461L,53462L,53463L,53464L,\n53465L,53466L,53467L,53468L,53469L,53470L,53471L,53472L,53473L,53474L,\n53475L,53476L,53477L,53478L,53479L,53480L,53481L,53482L,53483L,53484L,\n53485L,53486L,53487L,53488L,53489L,53490L,53491L,53492L,53493L,53494L,\n53495L,53496L,53497L,53498L,53499L,53500L,53501L,53502L,53503L,53504L,\n53505L,53506L,53507L,53508L,53509L,53510L,53511L,53512L,53513L,53514L,\n53515L,53516L,53517L,53518L,53519L,53520L,53521L,53522L,53523L,53524L,\n53525L,53526L,53527L,53528L,53529L,53530L,53531L,53532L,53533L,53534L,\n53535L,53536L,53537L,53538L,53539L,53540L,53541L,53542L,53543L,53544L,\n53545L,53546L,53547L,53548L,53549L,53550L,53551L,53552L,53553L,53554L,\n53555L,53556L,53557L,53558L,53559L,53560L,53561L,53562L,53563L,53564L,\n53565L,53566L,53567L,53568L,53569L,53570L,53571L,53572L,53573L,53574L,\n53575L,53576L,53577L,53578L,53579L,53580L,53581L,53582L,53583L,53584L,\n53585L,53586L,53587L,53588L,53589L,53590L,53591L,53592L,53593L,53594L,\n53595L,53596L,53597L,53598L,53599L,53600L,53601L,53602L,53603L,53604L,\n53605L,53606L,53607L,53608L,53609L,53610L,53611L,53612L,53613L,53614L,\n53615L,53616L,53617L,53618L,53619L,53620L,53621L,53622L,53623L,53624L,\n53625L,53626L,53627L,53628L,53629L,53630L,53631L,53632L,53633L,53634L,\n53635L,53636L,53637L,53638L,53639L,53640L,53641L,53642L,53643L,53644L,\n53645L,53646L,53647L,53648L,53649L,53650L,53651L,53652L,53653L,53654L,\n53655L,53656L,53657L,53658L,53659L,53660L,53661L,53662L,53663L,53664L,\n53665L,53666L,53667L,53668L,53669L,53670L,53671L,53672L,53673L,53674L,\n53675L,53676L,53677L,53678L,53679L,53680L,53681L,53682L,53683L,53684L,\n53685L,53686L,53687L,53688L,53689L,53690L,53691L,53692L,53693L,53694L,\n53695L,53696L,53697L,53698L,53699L,53700L,53701L,53702L,53703L,53704L,\n53705L,53706L,53707L,53708L,53709L,53710L,53711L,53712L,53713L,53714L,\n53715L,53716L,53717L,53718L,53719L,53720L,53721L,53722L,53723L,53724L,\n53725L,53726L,53727L,53728L,53729L,53730L,53731L,53732L,53733L,53734L,\n53735L,53736L,53737L,53738L,53739L,53740L,53741L,53742L,53743L,53744L,\n53745L,53746L,53747L,53748L,53749L,53750L,53751L,53752L,53753L,53754L,\n53755L,53756L,53757L,53758L,53759L,53760L,53761L,53762L,53763L,53764L,\n53765L,53766L,53767L,53768L,53769L,53770L,53771L,53772L,53773L,53774L,\n53775L,53776L,53777L,53778L,53779L,53780L,53781L,53782L,53783L,53784L,\n53785L,53786L,53787L,53788L,53789L,53790L,53791L,53792L,53793L,53794L,\n53795L,53796L,53797L,53798L,53799L,53800L,53801L,53802L,53803L,53804L,\n53805L,53806L,53807L,53808L,53809L,53810L,53811L,53812L,53813L,53814L,\n53815L,53816L,53817L,53818L,53819L,53820L,53821L,53822L,53823L,53824L,\n53825L,53826L,53827L,53828L,53829L,53830L,53831L,53832L,53833L,53834L,\n53835L,53836L,53837L,53838L,53839L,53840L,53841L,53842L,53843L,53844L,\n53845L,53846L,53847L,53848L,53849L,53850L,53851L,53852L,53853L,53854L,\n53855L,53856L,53857L,53858L,53859L,53860L,53861L,53862L,53863L,53864L,\n53865L,53866L,53867L,53868L,53869L,53870L,53871L,53872L,53873L,53874L,\n53875L,53876L,53877L,53878L,53879L,53880L,53881L,53882L,53883L,53884L,\n53885L,53886L,53887L,53888L,53889L,53890L,53891L,53892L,53893L,53894L,\n53895L,53896L,53897L,53898L,53899L,53900L,53901L,53902L,53903L,53904L,\n53905L,53906L,53907L,53908L,53909L,53910L,53911L,53912L,53913L,53914L,\n53915L,53916L,53917L,53918L,53919L,53920L,53921L,53922L,53923L,53924L,\n53925L,53926L,53927L,53928L,53929L,53930L,53931L,53932L,53933L,53934L,\n53935L,53936L,53937L,53938L,53939L,53940L,53941L,53942L,53943L,53944L,\n53945L,53946L,53947L,53948L,53949L,53950L,53951L,53952L,53953L,53954L,\n53955L,53956L,53957L,53958L,53959L,53960L,53961L,53962L,53963L,53964L,\n53965L,53966L,53967L,53968L,53969L,53970L,53971L,53972L,53973L,53974L,\n53975L,53976L,53977L,53978L,53979L,53980L,53981L,53982L,53983L,53984L,\n53985L,53986L,53987L,53988L,53989L,53990L,53991L,53992L,53993L,53994L,\n53995L,53996L,53997L,53998L,53999L,54000L,54001L,54002L,54003L,54004L,\n54005L,54006L,54007L,54008L,54009L,54010L,54011L,54012L,54013L,54014L,\n54015L,54016L,54017L,54018L,54019L,54020L,54021L,54022L,54023L,54024L,\n54025L,54026L,54027L,54028L,54029L,54030L,54031L,54032L,54033L,54034L,\n54035L,54036L,54037L,54038L,54039L,54040L,54041L,54042L,54043L,54044L,\n54045L,54046L,54047L,54048L,54049L,54050L,54051L,54052L,54053L,54054L,\n54055L,54056L,54057L,54058L,54059L,54060L,54061L,54062L,54063L,54064L,\n54065L,54066L,54067L,54068L,54069L,54070L,54071L,54072L,54073L,54074L,\n54075L,54076L,54077L,54078L,54079L,54080L,54081L,54082L,54083L,54084L,\n54085L,54086L,54087L,54088L,54089L,54090L,54091L,54092L,54093L,54094L,\n54095L,54096L,54097L,54098L,54099L,54100L,54101L,54102L,54103L,54104L,\n54105L,54106L,54107L,54108L,54109L,54110L,54111L,54112L,54113L,54114L,\n54115L,54116L,54117L,54118L,54119L,54120L,54121L,54122L,54123L,54124L,\n54125L,54126L,54127L,54128L,54129L,54130L,54131L,54132L,54133L,54134L,\n54135L,54136L,54137L,54138L,54139L,54140L,54141L,54142L,54143L,54144L,\n54145L,54146L,54147L,54148L,54149L,54150L,54151L,54152L,54153L,54154L,\n54155L,54156L,54157L,54158L,54159L,54160L,54161L,54162L,54163L,54164L,\n54165L,54166L,54167L,54168L,54169L,54170L,54171L,54172L,54173L,54174L,\n54175L,54176L,54177L,54178L,54179L,54180L,54181L,54182L,54183L,54184L,\n54185L,54186L,54187L,54188L,54189L,54190L,54191L,54192L,54193L,54194L,\n54195L,54196L,54197L,54198L,54199L,54200L,54201L,54202L,54203L,54204L,\n54205L,54206L,54207L,54208L,54209L,54210L,54211L,54212L,54213L,54214L,\n54215L,54216L,54217L,54218L,54219L,54220L,54221L,54222L,54223L,54224L,\n54225L,54226L,54227L,54228L,54229L,54230L,54231L,54232L,54233L,54234L,\n54235L,54236L,54237L,54238L,54239L,54240L,54241L,54242L,54243L,54244L,\n54245L,54246L,54247L,54248L,54249L,54250L,54251L,54252L,54253L,54254L,\n54255L,54256L,54257L,54258L,54259L,54260L,54261L,54262L,54263L,54264L,\n54265L,54266L,54267L,54268L,54269L,54270L,54271L,54272L,54273L,54274L,\n54275L,54276L,54277L,54278L,54279L,54280L,54281L,54282L,54283L,54284L,\n54285L,54286L,54287L,54288L,54289L,54290L,54291L,54292L,54293L,54294L,\n54295L,54296L,54297L,54298L,54299L,54300L,54301L,54302L,54303L,54304L,\n54305L,54306L,54307L,54308L,54309L,54310L,54311L,54312L,54313L,54314L,\n54315L,54316L,54317L,54318L,54319L,54320L,54321L,54322L,54323L,54324L,\n54325L,54326L,54327L,54328L,54329L,54330L,54331L,54332L,54333L,54334L,\n54335L,54336L,54337L,54338L,54339L,54340L,54341L,54342L,54343L,54344L,\n54345L,54346L,54347L,54348L,54349L,54350L,54351L,54352L,54353L,54354L,\n54355L,54356L,54357L,54358L,54359L,54360L,54361L,54362L,54363L,54364L,\n54365L,54366L,54367L,54368L,54369L,54370L,54371L,54372L,54373L,54374L,\n54375L,54376L,54377L,54378L,54379L,54380L,54381L,54382L,54383L,54384L,\n54385L,54386L,54387L,54388L,54389L,54390L,54391L,54392L,54393L,54394L,\n54395L,54396L,54397L,54398L,54399L,54400L,54401L,54402L,54403L,54404L,\n54405L,54406L,54407L,54408L,54409L,54410L,54411L,54412L,54413L,54414L,\n54415L,54416L,54417L,54418L,54419L,54420L,54421L,54422L,54423L,54424L,\n54425L,54426L,54427L,54428L,54429L,54430L,54431L,54432L,54433L,54434L,\n54435L,54436L,54437L,54438L,54439L,54440L,54441L,54442L,54443L,54444L,\n54445L,54446L,54447L,54448L,54449L,54450L,54451L,54452L,54453L,54454L,\n54455L,54456L,54457L,54458L,54459L,54460L,54461L,54462L,54463L,54464L,\n54465L,54466L,54467L,54468L,54469L,54470L,54471L,54472L,54473L,54474L,\n54475L,54476L,54477L,54478L,54479L,54480L,54481L,54482L,54483L,54484L,\n54485L,54486L,54487L,54488L,54489L,54490L,54491L,54492L,54493L,54494L,\n54495L,54496L,54497L,54498L,54499L,54500L,54501L,54502L,54503L,54504L,\n54505L,54506L,54507L,54508L,54509L,54510L,54511L,54512L,54513L,54514L,\n54515L,54516L,54517L,54518L,54519L,54520L,54521L,54522L,54523L,54524L,\n54525L,54526L,54527L,54528L,54529L,54530L,54531L,54532L,54533L,54534L,\n54535L,54536L,54537L,54538L,54539L,54540L,54541L,54542L,54543L,54544L,\n54545L,54546L,54547L,54548L,54549L,54550L,54551L,54552L,54553L,54554L,\n54555L,54556L,54557L,54558L,54559L,54560L,54561L,54562L,54563L,54564L,\n54565L,54566L,54567L,54568L,54569L,54570L,54571L,54572L,54573L,54574L,\n54575L,54576L,54577L,54578L,54579L,54580L,54581L,54582L,54583L,54584L,\n54585L,54586L,54587L,54588L,54589L,54590L,54591L,54592L,54593L,54594L,\n54595L,54596L,54597L,54598L,54599L,54600L,54601L,54602L,54603L,54604L,\n54605L,54606L,54607L,54608L,54609L,54610L,54611L,54612L,54613L,54614L,\n54615L,54616L,54617L,54618L,54619L,54620L,54621L,54622L,54623L,54624L,\n54625L,54626L,54627L,54628L,54629L,54630L,54631L,54632L,54633L,54634L,\n54635L,54636L,54637L,54638L,54639L,54640L,54641L,54642L,54643L,54644L,\n54645L,54646L,54647L,54648L,54649L,54650L,54651L,54652L,54653L,54654L,\n54655L,54656L,54657L,54658L,54659L,54660L,54661L,54662L,54663L,54664L,\n54665L,54666L,54667L,54668L,54669L,54670L,54671L,54672L,54673L,54674L,\n54675L,54676L,54677L,54678L,54679L,54680L,54681L,54682L,54683L,54684L,\n54685L,54686L,54687L,54688L,54689L,54690L,54691L,54692L,54693L,54694L,\n54695L,54696L,54697L,54698L,54699L,54700L,54701L,54702L,54703L,54704L,\n54705L,54706L,54707L,54708L,54709L,54710L,54711L,54712L,54713L,54714L,\n54715L,54716L,54717L,54718L,54719L,54720L,54721L,54722L,54723L,54724L,\n54725L,54726L,54727L,54728L,54729L,54730L,54731L,54732L,54733L,54734L,\n54735L,54736L,54737L,54738L,54739L,54740L,54741L,54742L,54743L,54744L,\n54745L,54746L,54747L,54748L,54749L,54750L,54751L,54752L,54753L,54754L,\n54755L,54756L,54757L,54758L,54759L,54760L,54761L,54762L,54763L,54764L,\n54765L,54766L,54767L,54768L,54769L,54770L,54771L,54772L,54773L,54774L,\n54775L,54776L,54777L,54778L,54779L,54780L,54781L,54782L,54783L,54784L,\n54785L,54786L,54787L,54788L,54789L,54790L,54791L,54792L,54793L,54794L,\n54795L,54796L,54797L,54798L,54799L,54800L,54801L,54802L,54803L,54804L,\n54805L,54806L,54807L,54808L,54809L,54810L,54811L,54812L,54813L,54814L,\n54815L,54816L,54817L,54818L,54819L,54820L,54821L,54822L,54823L,54824L,\n54825L,54826L,54827L,54828L,54829L,54830L,54831L,54832L,54833L,54834L,\n54835L,54836L,54837L,54838L,54839L,54840L,54841L,54842L,54843L,54844L,\n54845L,54846L,54847L,54848L,54849L,54850L,54851L,54852L,54853L,54854L,\n54855L,54856L,54857L,54858L,54859L,54860L,54861L,54862L,54863L,54864L,\n54865L,54866L,54867L,54868L,54869L,54870L,54871L,54872L,54873L,54874L,\n54875L,54876L,54877L,54878L,54879L,54880L,54881L,54882L,54883L,54884L,\n54885L,54886L,54887L,54888L,54889L,54890L,54891L,54892L,54893L,54894L,\n54895L,54896L,54897L,54898L,54899L,54900L,54901L,54902L,54903L,54904L,\n54905L,54906L,54907L,54908L,54909L,54910L,54911L,54912L,54913L,54914L,\n54915L,54916L,54917L,54918L,54919L,54920L,54921L,54922L,54923L,54924L,\n54925L,54926L,54927L,54928L,54929L,54930L,54931L,54932L,54933L,54934L,\n54935L,54936L,54937L,54938L,54939L,54940L,54941L,54942L,54943L,54944L,\n54945L,54946L,54947L,54948L,54949L,54950L,54951L,54952L,54953L,54954L,\n54955L,54956L,54957L,54958L,54959L,54960L,54961L,54962L,54963L,54964L,\n54965L,54966L,54967L,54968L,54969L,54970L,54971L,54972L,54973L,54974L,\n54975L,54976L,54977L,54978L,54979L,54980L,54981L,54982L,54983L,54984L,\n54985L,54986L,54987L,54988L,54989L,54990L,54991L,54992L,54993L,54994L,\n54995L,54996L,54997L,54998L,54999L,55000L,55001L,55002L,55003L,55004L,\n55005L,55006L,55007L,55008L,55009L,55010L,55011L,55012L,55013L,55014L,\n55015L,55016L,55017L,55018L,55019L,55020L,55021L,55022L,55023L,55024L,\n55025L,55026L,55027L,55028L,55029L,55030L,55031L,55032L,55033L,55034L,\n55035L,55036L,55037L,55038L,55039L,55040L,55041L,55042L,55043L,55044L,\n55045L,55046L,55047L,55048L,55049L,55050L,55051L,55052L,55053L,55054L,\n55055L,55056L,55057L,55058L,55059L,55060L,55061L,55062L,55063L,55064L,\n55065L,55066L,55067L,55068L,55069L,55070L,55071L,55072L,55073L,55074L,\n55075L,55076L,55077L,55078L,55079L,55080L,55081L,55082L,55083L,55084L,\n55085L,55086L,55087L,55088L,55089L,55090L,55091L,55092L,55093L,55094L,\n55095L,55096L,55097L,55098L,55099L,55100L,55101L,55102L,55103L,55104L,\n55105L,55106L,55107L,55108L,55109L,55110L,55111L,55112L,55113L,55114L,\n55115L,55116L,55117L,55118L,55119L,55120L,55121L,55122L,55123L,55124L,\n55125L,55126L,55127L,55128L,55129L,55130L,55131L,55132L,55133L,55134L,\n55135L,55136L,55137L,55138L,55139L,55140L,55141L,55142L,55143L,55144L,\n55145L,55146L,55147L,55148L,55149L,55150L,55151L,55152L,55153L,55154L,\n55155L,55156L,55157L,55158L,55159L,55160L,55161L,55162L,55163L,55164L,\n55165L,55166L,55167L,55168L,55169L,55170L,55171L,55172L,55173L,55174L,\n55175L,55176L,55177L,55178L,55179L,55180L,55181L,55182L,55183L,55184L,\n55185L,55186L,55187L,55188L,55189L,55190L,55191L,55192L,55193L,55194L,\n55195L,55196L,55197L,55198L,55199L,55200L,55201L,55202L,55203L,55204L,\n55205L,55206L,55207L,55208L,55209L,55210L,55211L,55212L,55213L,55214L,\n55215L,55216L,55217L,55218L,55219L,55220L,55221L,55222L,55223L,55224L,\n55225L,55226L,55227L,55228L,55229L,55230L,55231L,55232L,55233L,55234L,\n55235L,55236L,55237L,55238L,55239L,55240L,55241L,55242L,55243L,55244L,\n55245L,55246L,55247L,55248L,55249L,55250L,55251L,55252L,55253L,55254L,\n55255L,55256L,55257L,55258L,55259L,55260L,55261L,55262L,55263L,55264L,\n55265L,55266L,55267L,55268L,55269L,55270L,55271L,55272L,55273L,55274L,\n55275L,55276L,55277L,55278L,55279L,55280L,55281L,55282L,55283L,55284L,\n55285L,55286L,55287L,55288L,55289L,55290L,55291L,55292L,55293L,55294L,\n55295L,55296L,55297L,55298L,55299L,55300L,55301L,55302L,55303L,55304L,\n55305L,55306L,55307L,55308L,55309L,55310L,55311L,55312L,55313L,55314L,\n55315L,55316L,55317L,55318L,55319L,55320L,55321L,55322L,55323L,55324L,\n55325L,55326L,55327L,55328L,55329L,55330L,55331L,55332L,55333L,55334L,\n55335L,55336L,55337L,55338L,55339L,55340L,55341L,55342L,55343L,55344L,\n55345L,55346L,55347L,55348L,55349L,55350L,55351L,55352L,55353L,55354L,\n55355L,55356L,55357L,55358L,55359L,55360L,55361L,55362L,55363L,55364L,\n55365L,55366L,55367L,55368L,55369L,55370L,55371L,55372L,55373L,55374L,\n55375L,55376L,55377L,55378L,55379L,55380L,55381L,55382L,55383L,55384L,\n55385L,55386L,55387L,55388L,55389L,55390L,55391L,55392L,55393L,55394L,\n55395L,55396L,55397L,55398L,55399L,55400L,55401L,55402L,55403L,55404L,\n55405L,55406L,55407L,55408L,55409L,55410L,55411L,55412L,55413L,55414L,\n55415L,55416L,55417L,55418L,55419L,55420L,55421L,55422L,55423L,55424L,\n55425L,55426L,55427L,55428L,55429L,55430L,55431L,55432L,55433L,55434L,\n55435L,55436L,55437L,55438L,55439L,55440L,55441L,55442L,55443L,55444L,\n55445L,55446L,55447L,55448L,55449L,55450L,55451L,55452L,55453L,55454L,\n55455L,55456L,55457L,55458L,55459L,55460L,55461L,55462L,55463L,55464L,\n55465L,55466L,55467L,55468L,55469L,55470L,55471L,55472L,55473L,55474L,\n55475L,55476L,55477L,55478L,55479L,55480L,55481L,55482L,55483L,55484L,\n55485L,55486L,55487L,55488L,55489L,55490L,55491L,55492L,55493L,55494L,\n55495L,55496L,55497L,55498L,55499L,55500L,55501L,55502L,55503L,55504L,\n55505L,55506L,55507L,55508L,55509L,55510L,55511L,55512L,55513L,55514L,\n55515L,55516L,55517L,55518L,55519L,55520L,55521L,55522L,55523L,55524L,\n55525L,55526L,55527L,55528L,55529L,55530L,55531L,55532L,55533L,55534L,\n55535L,55536L,55537L,55538L,55539L,55540L,55541L,55542L,55543L,55544L,\n55545L,55546L,55547L,55548L,55549L,55550L,55551L,55552L,55553L,55554L,\n55555L,55556L,55557L,55558L,55559L,55560L,55561L,55562L,55563L,55564L,\n55565L,55566L,55567L,55568L,55569L,55570L,55571L,55572L,55573L,55574L,\n55575L,55576L,55577L,55578L,55579L,55580L,55581L,55582L,55583L,55584L,\n55585L,55586L,55587L,55588L,55589L,55590L,55591L,55592L,55593L,55594L,\n55595L,55596L,55597L,55598L,55599L,55600L,55601L,55602L,55603L,55604L,\n55605L,55606L,55607L,55608L,55609L,55610L,55611L,55612L,55613L,55614L,\n55615L,55616L,55617L,55618L,55619L,55620L,55621L,55622L,55623L,55624L,\n55625L,55626L,55627L,55628L,55629L,55630L,55631L,55632L,55633L,55634L,\n55635L,55636L,55637L,55638L,55639L,55640L,55641L,55642L,55643L,55644L,\n55645L,55646L,55647L,55648L,55649L,55650L,55651L,55652L,55653L,55654L,\n55655L,55656L,55657L,55658L,55659L,55660L,55661L,55662L,55663L,55664L,\n55665L,55666L,55667L,55668L,55669L,55670L,55671L,55672L,55673L,55674L,\n55675L,55676L,55677L,55678L,55679L,55680L,55681L,55682L,55683L,55684L,\n55685L,55686L,55687L,55688L,55689L,55690L,55691L,55692L,55693L,55694L,\n55695L,55696L,55697L,55698L,55699L,55700L,55701L,55702L,55703L,55704L,\n55705L,55706L,55707L,55708L,55709L,55710L,55711L,55712L,55713L,55714L,\n55715L,55716L,55717L,55718L,55719L,55720L,55721L,55722L,55723L,55724L,\n55725L,55726L,55727L,55728L,55729L,55730L,55731L,55732L,55733L,55734L,\n55735L,55736L,55737L,55738L,55739L,55740L,55741L,55742L,55743L,55744L,\n55745L,55746L,55747L,55748L,55749L,55750L,55751L,55752L,55753L,55754L,\n55755L,55756L,55757L,55758L,55759L,55760L,55761L,55762L,55763L,55764L,\n55765L,55766L,55767L,55768L,55769L,55770L,55771L,55772L,55773L,55774L,\n55775L,55776L,55777L,55778L,55779L,55780L,55781L,55782L,55783L,55784L,\n55785L,55786L,55787L,55788L,55789L,55790L,55791L,55792L,55793L,55794L,\n55795L,55796L,55797L,55798L,55799L,55800L,55801L,55802L,55803L,55804L,\n55805L,55806L,55807L,55808L,55809L,55810L,55811L,55812L,55813L,55814L,\n55815L,55816L,55817L,55818L,55819L,55820L,55821L,55822L,55823L,55824L,\n55825L,55826L,55827L,55828L,55829L,55830L,55831L,55832L,55833L,55834L,\n55835L,55836L,55837L,55838L,55839L,55840L,55841L,55842L,55843L,55844L,\n55845L,55846L,55847L,55848L,55849L,55850L,55851L,55852L,55853L,55854L,\n55855L,55856L,55857L,55858L,55859L,55860L,55861L,55862L,55863L,55864L,\n55865L,55866L,55867L,55868L,55869L,55870L,55871L,55872L,55873L,55874L,\n55875L,55876L,55877L,55878L,55879L,55880L,55881L,55882L,55883L,55884L,\n55885L,55886L,55887L,55888L,55889L,55890L,55891L,55892L,55893L,55894L,\n55895L,55896L,55897L,55898L,55899L,55900L,55901L,55902L,55903L,55904L,\n55905L,55906L,55907L,55908L,55909L,55910L,55911L,55912L,55913L,55914L,\n55915L,55916L,55917L,55918L,55919L,55920L,55921L,55922L,55923L,55924L,\n55925L,55926L,55927L,55928L,55929L,55930L,55931L,55932L,55933L,55934L,\n55935L,55936L,55937L,55938L,55939L,55940L,55941L,55942L,55943L,55944L,\n55945L,55946L,55947L,55948L,55949L,55950L,55951L,55952L,55953L,55954L,\n55955L,55956L,55957L,55958L,55959L,55960L,55961L,55962L,55963L,55964L,\n55965L,55966L,55967L,55968L,55969L,55970L,55971L,55972L,55973L,55974L,\n55975L,55976L,55977L,55978L,55979L,55980L,55981L,55982L,55983L,55984L,\n55985L,55986L,55987L,55988L,55989L,55990L,55991L,55992L,55993L,55994L,\n55995L,55996L,55997L,55998L,55999L,56000L,56001L,56002L,56003L,56004L,\n56005L,56006L,56007L,56008L,56009L,56010L,56011L,56012L,56013L,56014L,\n56015L,56016L,56017L,56018L,56019L,56020L,56021L,56022L,56023L,56024L,\n56025L,56026L,56027L,56028L,56029L,56030L,56031L,56032L,56033L,56034L,\n56035L,56036L,56037L,56038L,56039L,56040L,56041L,56042L,56043L,56044L,\n56045L,56046L,56047L,56048L,56049L,56050L,56051L,56052L,56053L,56054L,\n56055L,56056L,56057L,56058L,56059L,56060L,56061L,56062L,56063L,56064L,\n56065L,56066L,56067L,56068L,56069L,56070L,56071L,56072L,56073L,56074L,\n56075L,56076L,56077L,56078L,56079L,56080L,56081L,56082L,56083L,56084L,\n56085L,56086L,56087L,56088L,56089L,56090L,56091L,56092L,56093L,56094L,\n56095L,56096L,56097L,56098L,56099L,56100L,56101L,56102L,56103L,56104L,\n56105L,56106L,56107L,56108L,56109L,56110L,56111L,56112L,56113L,56114L,\n56115L,56116L,56117L,56118L,56119L,56120L,56121L,56122L,56123L,56124L,\n56125L,56126L,56127L,56128L,56129L,56130L,56131L,56132L,56133L,56134L,\n56135L,56136L,56137L,56138L,56139L,56140L,56141L,56142L,56143L,56144L,\n56145L,56146L,56147L,56148L,56149L,56150L,56151L,56152L,56153L,56154L,\n56155L,56156L,56157L,56158L,56159L,56160L,56161L,56162L,56163L,56164L,\n56165L,56166L,56167L,56168L,56169L,56170L,56171L,56172L,56173L,56174L,\n56175L,56176L,56177L,56178L,56179L,56180L,56181L,56182L,56183L,56184L,\n56185L,56186L,56187L,56188L,56189L,56190L,56191L,56192L,56193L,56194L,\n56195L,56196L,56197L,56198L,56199L,56200L,56201L,56202L,56203L,56204L,\n56205L,56206L,56207L,56208L,56209L,56210L,56211L,56212L,56213L,56214L,\n56215L,56216L,56217L,56218L,56219L,56220L,56221L,56222L,56223L,56224L,\n56225L,56226L,56227L,56228L,56229L,56230L,56231L,56232L,56233L,56234L,\n56235L,56236L,56237L,56238L,56239L,56240L,56241L,56242L,56243L,56244L,\n56245L,56246L,56247L,56248L,56249L,56250L,56251L,56252L,56253L,56254L,\n56255L,56256L,56257L,56258L,56259L,56260L,56261L,56262L,56263L,56264L,\n56265L,56266L,56267L,56268L,56269L,56270L,56271L,56272L,56273L,56274L,\n56275L,56276L,56277L,56278L,56279L,56280L,56281L,56282L,56283L,56284L,\n56285L,56286L,56287L,56288L,56289L,56290L,56291L,56292L,56293L,56294L,\n56295L,56296L,56297L,56298L,56299L,56300L,56301L,56302L,56303L,56304L,\n56305L,56306L,56307L,56308L,56309L,56310L,56311L,56312L,56313L,56314L,\n56315L,56316L,56317L,56318L,56319L,56320L,56321L,56322L,56323L,56324L,\n56325L,56326L,56327L,56328L,56329L,56330L,56331L,56332L,56333L,56334L,\n56335L,56336L,56337L,56338L,56339L,56340L,56341L,56342L,56343L,56344L,\n56345L,56346L,56347L,56348L,56349L,56350L,56351L,56352L,56353L,56354L,\n56355L,56356L,56357L,56358L,56359L,56360L,56361L,56362L,56363L,56364L,\n56365L,56366L,56367L,56368L,56369L,56370L,56371L,56372L,56373L,56374L,\n56375L,56376L,56377L,56378L,56379L,56380L,56381L,56382L,56383L,56384L,\n56385L,56386L,56387L,56388L,56389L,56390L,56391L,56392L,56393L,56394L,\n56395L,56396L,56397L,56398L,56399L,56400L,56401L,56402L,56403L,56404L,\n56405L,56406L,56407L,56408L,56409L,56410L,56411L,56412L,56413L,56414L,\n56415L,56416L,56417L,56418L,56419L,56420L,56421L,56422L,56423L,56424L,\n56425L,56426L,56427L,56428L,56429L,56430L,56431L,56432L,56433L,56434L,\n56435L,56436L,56437L,56438L,56439L,56440L,56441L,56442L,56443L,56444L,\n56445L,56446L,56447L,56448L,56449L,56450L,56451L,56452L,56453L,56454L,\n56455L,56456L,56457L,56458L,56459L,56460L,56461L,56462L,56463L,56464L,\n56465L,56466L,56467L,56468L,56469L,56470L,56471L,56472L,56473L,56474L,\n56475L,56476L,56477L,56478L,56479L,56480L,56481L,56482L,56483L,56484L,\n56485L,56486L,56487L,56488L,56489L,56490L,56491L,56492L,56493L,56494L,\n56495L,56496L,56497L,56498L,56499L,56500L,56501L,56502L,56503L,56504L,\n56505L,56506L,56507L,56508L,56509L,56510L,56511L,56512L,56513L,56514L,\n56515L,56516L,56517L,56518L,56519L,56520L,56521L,56522L,56523L,56524L,\n56525L,56526L,56527L,56528L,56529L,56530L,56531L,56532L,56533L,56534L,\n56535L,56536L,56537L,56538L,56539L,56540L,56541L,56542L,56543L,56544L,\n56545L,56546L,56547L,56548L,56549L,56550L,56551L,56552L,56553L,56554L,\n56555L,56556L,56557L,56558L,56559L,56560L,56561L,56562L,56563L,56564L,\n56565L,56566L,56567L,56568L,56569L,56570L,56571L,56572L,56573L,56574L,\n56575L,56576L,56577L,56578L,56579L,56580L,56581L,56582L,56583L,56584L,\n56585L,56586L,56587L,56588L,56589L,56590L,56591L,56592L,56593L,56594L,\n56595L,56596L,56597L,56598L,56599L,56600L,56601L,56602L,56603L,56604L,\n56605L,56606L,56607L,56608L,56609L,56610L,56611L,56612L,56613L,56614L,\n56615L,56616L,56617L,56618L,56619L,56620L,56621L,56622L,56623L,56624L,\n56625L,56626L,56627L,56628L,56629L,56630L,56631L,56632L,56633L,56634L,\n56635L,56636L,56637L,56638L,56639L,56640L,56641L,56642L,56643L,56644L,\n56645L,56646L,56647L,56648L,56649L,56650L,56651L,56652L,56653L,56654L,\n56655L,56656L,56657L,56658L,56659L,56660L,56661L,56662L,56663L,56664L,\n56665L,56666L,56667L,56668L,56669L,56670L,56671L,56672L,56673L,56674L,\n56675L,56676L,56677L,56678L,56679L,56680L,56681L,56682L,56683L,56684L,\n56685L,56686L,56687L,56688L,56689L,56690L,56691L,56692L,56693L,56694L,\n56695L,56696L,56697L,56698L,56699L,56700L,56701L,56702L,56703L,56704L,\n56705L,56706L,56707L,56708L,56709L,56710L,56711L,56712L,56713L,56714L,\n56715L,56716L,56717L,56718L,56719L,56720L,56721L,56722L,56723L,56724L,\n56725L,56726L,56727L,56728L,56729L,56730L,56731L,56732L,56733L,56734L,\n56735L,56736L,56737L,56738L,56739L,56740L,56741L,56742L,56743L,56744L,\n56745L,56746L,56747L,56748L,56749L,56750L,56751L,56752L,56753L,56754L,\n56755L,56756L,56757L,56758L,56759L,56760L,56761L,56762L,56763L,56764L,\n56765L,56766L,56767L,56768L,56769L,56770L,56771L,56772L,56773L,56774L,\n56775L,56776L,56777L,56778L,56779L,56780L,56781L,56782L,56783L,56784L,\n56785L,56786L,56787L,56788L,56789L,56790L,56791L,56792L,56793L,56794L,\n56795L,56796L,56797L,56798L,56799L,56800L,56801L,56802L,56803L,56804L,\n56805L,56806L,56807L,56808L,56809L,56810L,56811L,56812L,56813L,56814L,\n56815L,56816L,56817L,56818L,56819L,56820L,56821L,56822L,56823L,56824L,\n56825L,56826L,56827L,56828L,56829L,56830L,56831L,56832L,56833L,56834L,\n56835L,56836L,56837L,56838L,56839L,56840L,56841L,56842L,56843L,56844L,\n56845L,56846L,56847L,56848L,56849L,56850L,56851L,56852L,56853L,56854L,\n56855L,56856L,56857L,56858L,56859L,56860L,56861L,56862L,56863L,56864L,\n56865L,56866L,56867L,56868L,56869L,56870L,56871L,56872L,56873L,56874L,\n56875L,56876L,56877L,56878L,56879L,56880L,56881L,56882L,56883L,56884L,\n56885L,56886L,56887L,56888L,56889L,56890L,56891L,56892L,56893L,56894L,\n56895L,56896L,56897L,56898L,56899L,56900L,56901L,56902L,56903L,56904L,\n56905L,56906L,56907L,56908L,56909L,56910L,56911L,56912L,56913L,56914L,\n56915L,56916L,56917L,56918L,56919L,56920L,56921L,56922L,56923L,56924L,\n56925L,56926L,56927L,56928L,56929L,56930L,56931L,56932L,56933L,56934L,\n56935L,56936L,56937L,56938L,56939L,56940L,56941L,56942L,56943L,56944L,\n56945L,56946L,56947L,56948L,56949L,56950L,56951L,56952L,56953L,56954L,\n56955L,56956L,56957L,56958L,56959L,56960L,56961L,56962L,56963L,56964L,\n56965L,56966L,56967L,56968L,56969L,56970L,56971L,56972L,56973L,56974L,\n56975L,56976L,56977L,56978L,56979L,56980L,56981L,56982L,56983L,56984L,\n56985L,56986L,56987L,56988L,56989L,56990L,56991L,56992L,56993L,56994L,\n56995L,56996L,56997L,56998L,56999L,57000L,57001L,57002L,57003L,57004L,\n57005L,57006L,57007L,57008L,57009L,57010L,57011L,57012L,57013L,57014L,\n57015L,57016L,57017L,57018L,57019L,57020L,57021L,57022L,57023L,57024L,\n57025L,57026L,57027L,57028L,57029L,57030L,57031L,57032L,57033L,57034L,\n57035L,57036L,57037L,57038L,57039L,57040L,57041L,57042L,57043L,57044L,\n57045L,57046L,57047L,57048L,57049L,57050L,57051L,57052L,57053L,57054L,\n57055L,57056L,57057L,57058L,57059L,57060L,57061L,57062L,57063L,57064L,\n57065L,57066L,57067L,57068L,57069L,57070L,57071L,57072L,57073L,57074L,\n57075L,57076L,57077L,57078L,57079L,57080L,57081L,57082L,57083L,57084L,\n57085L,57086L,57087L,57088L,57089L,57090L,57091L,57092L,57093L,57094L,\n57095L,57096L,57097L,57098L,57099L,57100L,57101L,57102L,57103L,57104L,\n57105L,57106L,57107L,57108L,57109L,57110L,57111L,57112L,57113L,57114L,\n57115L,57116L,57117L,57118L,57119L,57120L,57121L,57122L,57123L,57124L,\n57125L,57126L,57127L,57128L,57129L,57130L,57131L,57132L,57133L,57134L,\n57135L,57136L,57137L,57138L,57139L,57140L,57141L,57142L,57143L,57144L,\n57145L,57146L,57147L,57148L,57149L,57150L,57151L,57152L,57153L,57154L,\n57155L,57156L,57157L,57158L,57159L,57160L,57161L,57162L,57163L,57164L,\n57165L,57166L,57167L,57168L,57169L,57170L,57171L,57172L,57173L,57174L,\n57175L,57176L,57177L,57178L,57179L,57180L,57181L,57182L,57183L,57184L,\n57185L,57186L,57187L,57188L,57189L,57190L,57191L,57192L,57193L,57194L,\n57195L,57196L,57197L,57198L,57199L,57200L,57201L,57202L,57203L,57204L,\n57205L,57206L,57207L,57208L,57209L,57210L,57211L,57212L,57213L,57214L,\n57215L,57216L,57217L,57218L,57219L,57220L,57221L,57222L,57223L,57224L,\n57225L,57226L,57227L,57228L,57229L,57230L,57231L,57232L,57233L,57234L,\n57235L,57236L,57237L,57238L,57239L,57240L,57241L,57242L,57243L,57244L,\n57245L,57246L,57247L,57248L,57249L,57250L,57251L,57252L,57253L,57254L,\n57255L,57256L,57257L,57258L,57259L,57260L,57261L,57262L,57263L,57264L,\n57265L,57266L,57267L,57268L,57269L,57270L,57271L,57272L,57273L,57274L,\n57275L,57276L,57277L,57278L,57279L,57280L,57281L,57282L,57283L,57284L,\n57285L,57286L,57287L,57288L,57289L,57290L,57291L,57292L,57293L,57294L,\n57295L,57296L,57297L,57298L,57299L,57300L,57301L,57302L,57303L,57304L,\n57305L,57306L,57307L,57308L,57309L,57310L,57311L,57312L,57313L,57314L,\n57315L,57316L,57317L,57318L,57319L,57320L,57321L,57322L,57323L,57324L,\n57325L,57326L,57327L,57328L,57329L,57330L,57331L,57332L,57333L,57334L,\n57335L,57336L,57337L,57338L,57339L,57340L,57341L,57342L,57343L,57344L,\n57345L,57346L,57347L,57348L,57349L,57350L,57351L,57352L,57353L,57354L,\n57355L,57356L,57357L,57358L,57359L,57360L,57361L,57362L,57363L,57364L,\n57365L,57366L,57367L,57368L,57369L,57370L,57371L,57372L,57373L,57374L,\n57375L,57376L,57377L,57378L,57379L,57380L,57381L,57382L,57383L,57384L,\n57385L,57386L,57387L,57388L,57389L,57390L,57391L,57392L,57393L,57394L,\n57395L,57396L,57397L,57398L,57399L,57400L,57401L,57402L,57403L,57404L,\n57405L,57406L,57407L,57408L,57409L,57410L,57411L,57412L,57413L,57414L,\n57415L,57416L,57417L,57418L,57419L,57420L,57421L,57422L,57423L,57424L,\n57425L,57426L,57427L,57428L,57429L,57430L,57431L,57432L,57433L,57434L,\n57435L,57436L,57437L,57438L,57439L,57440L,57441L,57442L,57443L,57444L,\n57445L,57446L,57447L,57448L,57449L,57450L,57451L,57452L,57453L,57454L,\n57455L,57456L,57457L,57458L,57459L,57460L,57461L,57462L,57463L,57464L,\n57465L,57466L,57467L,57468L,57469L,57470L,57471L,57472L,57473L,57474L,\n57475L,57476L,57477L,57478L,57479L,57480L,57481L,57482L,57483L,57484L,\n57485L,57486L,57487L,57488L,57489L,57490L,57491L,57492L,57493L,57494L,\n57495L,57496L,57497L,57498L,57499L,57500L,57501L,57502L,57503L,57504L,\n57505L,57506L,57507L,57508L,57509L,57510L,57511L,57512L,57513L,57514L,\n57515L,57516L,57517L,57518L,57519L,57520L,57521L,57522L,57523L,57524L,\n57525L,57526L,57527L,57528L,57529L,57530L,57531L,57532L,57533L,57534L,\n57535L,57536L,57537L,57538L,57539L,57540L,57541L,57542L,57543L,57544L,\n57545L,57546L,57547L,57548L,57549L,57550L,57551L,57552L,57553L,57554L,\n57555L,57556L,57557L,57558L,57559L,57560L,57561L,57562L,57563L,57564L,\n57565L,57566L,57567L,57568L,57569L,57570L,57571L,57572L,57573L,57574L,\n57575L,57576L,57577L,57578L,57579L,57580L,57581L,57582L,57583L,57584L,\n57585L,57586L,57587L,57588L,57589L,57590L,57591L,57592L,57593L,57594L,\n57595L,57596L,57597L,57598L,57599L,57600L,57601L,57602L,57603L,57604L,\n57605L,57606L,57607L,57608L,57609L,57610L,57611L,57612L,57613L,57614L,\n57615L,57616L,57617L,57618L,57619L,57620L,57621L,57622L,57623L,57624L,\n57625L,57626L,57627L,57628L,57629L,57630L,57631L,57632L,57633L,57634L,\n57635L,57636L,57637L,57638L,57639L,57640L,57641L,57642L,57643L,57644L,\n57645L,57646L,57647L,57648L,57649L,57650L,57651L,57652L,57653L,57654L,\n57655L,57656L,57657L,57658L,57659L,57660L,57661L,57662L,57663L,57664L,\n57665L,57666L,57667L,57668L,57669L,57670L,57671L,57672L,57673L,57674L,\n57675L,57676L,57677L,57678L,57679L,57680L,57681L,57682L,57683L,57684L,\n57685L,57686L,57687L,57688L,57689L,57690L,57691L,57692L,57693L,57694L,\n57695L,57696L,57697L,57698L,57699L,57700L,57701L,57702L,57703L,57704L,\n57705L,57706L,57707L,57708L,57709L,57710L,57711L,57712L,57713L,57714L,\n57715L,57716L,57717L,57718L,57719L,57720L,57721L,57722L,57723L,57724L,\n57725L,57726L,57727L,57728L,57729L,57730L,57731L,57732L,57733L,57734L,\n57735L,57736L,57737L,57738L,57739L,57740L,57741L,57742L,57743L,57744L,\n57745L,57746L,57747L,57748L,57749L,57750L,57751L,57752L,57753L,57754L,\n57755L,57756L,57757L,57758L,57759L,57760L,57761L,57762L,57763L,57764L,\n57765L,57766L,57767L,57768L,57769L,57770L,57771L,57772L,57773L,57774L,\n57775L,57776L,57777L,57778L,57779L,57780L,57781L,57782L,57783L,57784L,\n57785L,57786L,57787L,57788L,57789L,57790L,57791L,57792L,57793L,57794L,\n57795L,57796L,57797L,57798L,57799L,57800L,57801L,57802L,57803L,57804L,\n57805L,57806L,57807L,57808L,57809L,57810L,57811L,57812L,57813L,57814L,\n57815L,57816L,57817L,57818L,57819L,57820L,57821L,57822L,57823L,57824L,\n57825L,57826L,57827L,57828L,57829L,57830L,57831L,57832L,57833L,57834L,\n57835L,57836L,57837L,57838L,57839L,57840L,57841L,57842L,57843L,57844L,\n57845L,57846L,57847L,57848L,57849L,57850L,57851L,57852L,57853L,57854L,\n57855L,57856L,57857L,57858L,57859L,57860L,57861L,57862L,57863L,57864L,\n57865L,57866L,57867L,57868L,57869L,57870L,57871L,57872L,57873L,57874L,\n57875L,57876L,57877L,57878L,57879L,57880L,57881L,57882L,57883L,57884L,\n57885L,57886L,57887L,57888L,57889L,57890L,57891L,57892L,57893L,57894L,\n57895L,57896L,57897L,57898L,57899L,57900L,57901L,57902L,57903L,57904L,\n57905L,57906L,57907L,57908L,57909L,57910L,57911L,57912L,57913L,57914L,\n57915L,57916L,57917L,57918L,57919L,57920L,57921L,57922L,57923L,57924L,\n57925L,57926L,57927L,57928L,57929L,57930L,57931L,57932L,57933L,57934L,\n57935L,57936L,57937L,57938L,57939L,57940L,57941L,57942L,57943L,57944L,\n57945L,57946L,57947L,57948L,57949L,57950L,57951L,57952L,57953L,57954L,\n57955L,57956L,57957L,57958L,57959L,57960L,57961L,57962L,57963L,57964L,\n57965L,57966L,57967L,57968L,57969L,57970L,57971L,57972L,57973L,57974L,\n57975L,57976L,57977L,57978L,57979L,57980L,57981L,57982L,57983L,57984L,\n57985L,57986L,57987L,57988L,57989L,57990L,57991L,57992L,57993L,57994L,\n57995L,57996L,57997L,57998L,57999L,58000L,58001L,58002L,58003L,58004L,\n58005L,58006L,58007L,58008L,58009L,58010L,58011L,58012L,58013L,58014L,\n58015L,58016L,58017L,58018L,58019L,58020L,58021L,58022L,58023L,58024L,\n58025L,58026L,58027L,58028L,58029L,58030L,58031L,58032L,58033L,58034L,\n58035L,58036L,58037L,58038L,58039L,58040L,58041L,58042L,58043L,58044L,\n58045L,58046L,58047L,58048L,58049L,58050L,58051L,58052L,58053L,58054L,\n58055L,58056L,58057L,58058L,58059L,58060L,58061L,58062L,58063L,58064L,\n58065L,58066L,58067L,58068L,58069L,58070L,58071L,58072L,58073L,58074L,\n58075L,58076L,58077L,58078L,58079L,58080L,58081L,58082L,58083L,58084L,\n58085L,58086L,58087L,58088L,58089L,58090L,58091L,58092L,58093L,58094L,\n58095L,58096L,58097L,58098L,58099L,58100L,58101L,58102L,58103L,58104L,\n58105L,58106L,58107L,58108L,58109L,58110L,58111L,58112L,58113L,58114L,\n58115L,58116L,58117L,58118L,58119L,58120L,58121L,58122L,58123L,58124L,\n58125L,58126L,58127L,58128L,58129L,58130L,58131L,58132L,58133L,58134L,\n58135L,58136L,58137L,58138L,58139L,58140L,58141L,58142L,58143L,58144L,\n58145L,58146L,58147L,58148L,58149L,58150L,58151L,58152L,58153L,58154L,\n58155L,58156L,58157L,58158L,58159L,58160L,58161L,58162L,58163L,58164L,\n58165L,58166L,58167L,58168L,58169L,58170L,58171L,58172L,58173L,58174L,\n58175L,58176L,58177L,58178L,58179L,58180L,58181L,58182L,58183L,58184L,\n58185L,58186L,58187L,58188L,58189L,58190L,58191L,58192L,58193L,58194L,\n58195L,58196L,58197L,58198L,58199L,58200L,58201L,58202L,58203L,58204L,\n58205L,58206L,58207L,58208L,58209L,58210L,58211L,58212L,58213L,58214L,\n58215L,58216L,58217L,58218L,58219L,58220L,58221L,58222L,58223L,58224L,\n58225L,58226L,58227L,58228L,58229L,58230L,58231L,58232L,58233L,58234L,\n58235L,58236L,58237L,58238L,58239L,58240L,58241L,58242L,58243L,58244L,\n58245L,58246L,58247L,58248L,58249L,58250L,58251L,58252L,58253L,58254L,\n58255L,58256L,58257L,58258L,58259L,58260L,58261L,58262L,58263L,58264L,\n58265L,58266L,58267L,58268L,58269L,58270L,58271L,58272L,58273L,58274L,\n58275L,58276L,58277L,58278L,58279L,58280L,58281L,58282L,58283L,58284L,\n58285L,58286L,58287L,58288L,58289L,58290L,58291L,58292L,58293L,58294L,\n58295L,58296L,58297L,58298L,58299L,58300L,58301L,58302L,58303L,58304L,\n58305L,58306L,58307L,58308L,58309L,58310L,58311L,58312L,58313L,58314L,\n58315L,58316L,58317L,58318L,58319L,58320L,58321L,58322L,58323L,58324L,\n58325L,58326L,58327L,58328L,58329L,58330L,58331L,58332L,58333L,58334L,\n58335L,58336L,58337L,58338L,58339L,58340L,58341L,58342L,58343L,58344L,\n58345L,58346L,58347L,58348L,58349L,58350L,58351L,58352L,58353L,58354L,\n58355L,58356L,58357L,58358L,58359L,58360L,58361L,58362L,58363L,58364L,\n58365L,58366L,58367L,58368L,58369L,58370L,58371L,58372L,58373L,58374L,\n58375L,58376L,58377L,58378L,58379L,58380L,58381L,58382L,58383L,58384L,\n58385L,58386L,58387L,58388L,58389L,58390L,58391L,58392L,58393L,58394L,\n58395L,58396L,58397L,58398L,58399L,58400L,58401L,58402L,58403L,58404L,\n58405L,58406L,58407L,58408L,58409L,58410L,58411L,58412L,58413L,58414L,\n58415L,58416L,58417L,58418L,58419L,58420L,58421L,58422L,58423L,58424L,\n58425L,58426L,58427L,58428L,58429L,58430L,58431L,58432L,58433L,58434L,\n58435L,58436L,58437L,58438L,58439L,58440L,58441L,58442L,58443L,58444L,\n58445L,58446L,58447L,58448L,58449L,58450L,58451L,58452L,58453L,58454L,\n58455L,58456L,58457L,58458L,58459L,58460L,58461L,58462L,58463L,58464L,\n58465L,58466L,58467L,58468L,58469L,58470L,58471L,58472L,58473L,58474L,\n58475L,58476L,58477L,58478L,58479L,58480L,58481L,58482L,58483L,58484L,\n58485L,58486L,58487L,58488L,58489L,58490L,58491L,58492L,58493L,58494L,\n58495L,58496L,58497L,58498L,58499L,58500L,58501L,58502L,58503L,58504L,\n58505L,58506L,58507L,58508L,58509L,58510L,58511L,58512L,58513L,58514L,\n58515L,58516L,58517L,58518L,58519L,58520L,58521L,58522L,58523L,58524L,\n58525L,58526L,58527L,58528L,58529L,58530L,58531L,58532L,58533L,58534L,\n58535L,58536L,58537L,58538L,58539L,58540L,58541L,58542L,58543L,58544L,\n58545L,58546L,58547L,58548L,58549L,58550L,58551L,58552L,58553L,58554L,\n58555L,58556L,58557L,58558L,58559L,58560L,58561L,58562L,58563L,58564L,\n58565L,58566L,58567L,58568L,58569L,58570L,58571L,58572L,58573L,58574L,\n58575L,58576L,58577L,58578L,58579L,58580L,58581L,58582L,58583L,58584L,\n58585L,58586L,58587L,58588L,58589L,58590L,58591L,58592L,58593L,58594L,\n58595L,58596L,58597L,58598L,58599L,58600L,58601L,58602L,58603L,58604L,\n58605L,58606L,58607L,58608L,58609L,58610L,58611L,58612L,58613L,58614L,\n58615L,58616L,58617L,58618L,58619L,58620L,58621L,58622L,58623L,58624L,\n58625L,58626L,58627L,58628L,58629L,58630L,58631L,58632L,58633L,58634L,\n58635L,58636L,58637L,58638L,58639L,58640L,58641L,58642L,58643L,58644L,\n58645L,58646L,58647L,58648L,58649L,58650L,58651L,58652L,58653L,58654L,\n58655L,58656L,58657L,58658L,58659L,58660L,58661L,58662L,58663L,58664L,\n58665L,58666L,58667L,58668L,58669L,58670L,58671L,58672L,58673L,58674L,\n58675L,58676L,58677L,58678L,58679L,58680L,58681L,58682L,58683L,58684L,\n58685L,58686L,58687L,58688L,58689L,58690L,58691L,58692L,58693L,58694L,\n58695L,58696L,58697L,58698L,58699L,58700L,58701L,58702L,58703L,58704L,\n58705L,58706L,58707L,58708L,58709L,58710L,58711L,58712L,58713L,58714L,\n58715L,58716L,58717L,58718L,58719L,58720L,58721L,58722L,58723L,58724L,\n58725L,58726L,58727L,58728L,58729L,58730L,58731L,58732L,58733L,58734L,\n58735L,58736L,58737L,58738L,58739L,58740L,58741L,58742L,58743L,58744L,\n58745L,58746L,58747L,58748L,58749L,58750L,58751L,58752L,58753L,58754L,\n58755L,58756L,58757L,58758L,58759L,58760L,58761L,58762L,58763L,58764L,\n58765L,58766L,58767L,58768L,58769L,58770L,58771L,58772L,58773L,58774L,\n58775L,58776L,58777L,58778L,58779L,58780L,58781L,58782L,58783L,58784L,\n58785L,58786L,58787L,58788L,58789L,58790L,58791L,58792L,58793L,58794L,\n58795L,58796L,58797L,58798L,58799L,58800L,58801L,58802L,58803L,58804L,\n58805L,58806L,58807L,58808L,58809L,58810L,58811L,58812L,58813L,58814L,\n58815L,58816L,58817L,58818L,58819L,58820L,58821L,58822L,58823L,58824L,\n58825L,58826L,58827L,58828L,58829L,58830L,58831L,58832L,58833L,58834L,\n58835L,58836L,58837L,58838L,58839L,58840L,58841L,58842L,58843L,58844L,\n58845L,58846L,58847L,58848L,58849L,58850L,58851L,58852L,58853L,58854L,\n58855L,58856L,58857L,58858L,58859L,58860L,58861L,58862L,58863L,58864L,\n58865L,58866L,58867L,58868L,58869L,58870L,58871L,58872L,58873L,58874L,\n58875L,58876L,58877L,58878L,58879L,58880L,58881L,58882L,58883L,58884L,\n58885L,58886L,58887L,58888L,58889L,58890L,58891L,58892L,58893L,58894L,\n58895L,58896L,58897L,58898L,58899L,58900L,58901L,58902L,58903L,58904L,\n58905L,58906L,58907L,58908L,58909L,58910L,58911L,58912L,58913L,58914L,\n58915L,58916L,58917L,58918L,58919L,58920L,58921L,58922L,58923L,58924L,\n58925L,58926L,58927L,58928L,58929L,58930L,58931L,58932L,58933L,58934L,\n58935L,58936L,58937L,58938L,58939L,58940L,58941L,58942L,58943L,58944L,\n58945L,58946L,58947L,58948L,58949L,58950L,58951L,58952L,58953L,58954L,\n58955L,58956L,58957L,58958L,58959L,58960L,58961L,58962L,58963L,58964L,\n58965L,58966L,58967L,58968L,58969L,58970L,58971L,58972L,58973L,58974L,\n58975L,58976L,58977L,58978L,58979L,58980L,58981L,58982L,58983L,58984L,\n58985L,58986L,58987L,58988L,58989L,58990L,58991L,58992L,58993L,58994L,\n58995L,58996L,58997L,58998L,58999L,59000L,59001L,59002L,59003L,59004L,\n59005L,59006L,59007L,59008L,59009L,59010L,59011L,59012L,59013L,59014L,\n59015L,59016L,59017L,59018L,59019L,59020L,59021L,59022L,59023L,59024L,\n59025L,59026L,59027L,59028L,59029L,59030L,59031L,59032L,59033L,59034L,\n59035L,59036L,59037L,59038L,59039L,59040L,59041L,59042L,59043L,59044L,\n59045L,59046L,59047L,59048L,59049L,59050L,59051L,59052L,59053L,59054L,\n59055L,59056L,59057L,59058L,59059L,59060L,59061L,59062L,59063L,59064L,\n59065L,59066L,59067L,59068L,59069L,59070L,59071L,59072L,59073L,59074L,\n59075L,59076L,59077L,59078L,59079L,59080L,59081L,59082L,59083L,59084L,\n59085L,59086L,59087L,59088L,59089L,59090L,59091L,59092L,59093L,59094L,\n59095L,59096L,59097L,59098L,59099L,59100L,59101L,59102L,59103L,59104L,\n59105L,59106L,59107L,59108L,59109L,59110L,59111L,59112L,59113L,59114L,\n59115L,59116L,59117L,59118L,59119L,59120L,59121L,59122L,59123L,59124L,\n59125L,59126L,59127L,59128L,59129L,59130L,59131L,59132L,59133L,59134L,\n59135L,59136L,59137L,59138L,59139L,59140L,59141L,59142L,59143L,59144L,\n59145L,59146L,59147L,59148L,59149L,59150L,59151L,59152L,59153L,59154L,\n59155L,59156L,59157L,59158L,59159L,59160L,59161L,59162L,59163L,59164L,\n59165L,59166L,59167L,59168L,59169L,59170L,59171L,59172L,59173L,59174L,\n59175L,59176L,59177L,59178L,59179L,59180L,59181L,59182L,59183L,59184L,\n59185L,59186L,59187L,59188L,59189L,59190L,59191L,59192L,59193L,59194L,\n59195L,59196L,59197L,59198L,59199L,59200L,59201L,59202L,59203L,59204L,\n59205L,59206L,59207L,59208L,59209L,59210L,59211L,59212L,59213L,59214L,\n59215L,59216L,59217L,59218L,59219L,59220L,59221L,59222L,59223L,59224L,\n59225L,59226L,59227L,59228L,59229L,59230L,59231L,59232L,59233L,59234L,\n59235L,59236L,59237L,59238L,59239L,59240L,59241L,59242L,59243L,59244L,\n59245L,59246L,59247L,59248L,59249L,59250L,59251L,59252L,59253L,59254L,\n59255L,59256L,59257L,59258L,59259L,59260L,59261L,59262L,59263L,59264L,\n59265L,59266L,59267L,59268L,59269L,59270L,59271L,59272L,59273L,59274L,\n59275L,59276L,59277L,59278L,59279L,59280L,59281L,59282L,59283L,59284L,\n59285L,59286L,59287L,59288L,59289L,59290L,59291L,59292L,59293L,59294L,\n59295L,59296L,59297L,59298L,59299L,59300L,59301L,59302L,59303L,59304L,\n59305L,59306L,59307L,59308L,59309L,59310L,59311L,59312L,59313L,59314L,\n59315L,59316L,59317L,59318L,59319L,59320L,59321L,59322L,59323L,59324L,\n59325L,59326L,59327L,59328L,59329L,59330L,59331L,59332L,59333L,59334L,\n59335L,59336L,59337L,59338L,59339L,59340L,59341L,59342L,59343L,59344L,\n59345L,59346L,59347L,59348L,59349L,59350L,59351L,59352L,59353L,59354L,\n59355L,59356L,59357L,59358L,59359L,59360L,59361L,59362L,59363L,59364L,\n59365L,59366L,59367L,59368L,59369L,59370L,59371L,59372L,59373L,59374L,\n59375L,59376L,59377L,59378L,59379L,59380L,59381L,59382L,59383L,59384L,\n59385L,59386L,59387L,59388L,59389L,59390L,59391L,59392L,59393L,59394L,\n59395L,59396L,59397L,59398L,59399L,59400L,59401L,59402L,59403L,59404L,\n59405L,59406L,59407L,59408L,59409L,59410L,59411L,59412L,59413L,59414L,\n59415L,59416L,59417L,59418L,59419L,59420L,59421L,59422L,59423L,59424L,\n59425L,59426L,59427L,59428L,59429L,59430L,59431L,59432L,59433L,59434L,\n59435L,59436L,59437L,59438L,59439L,59440L,59441L,59442L,59443L,59444L,\n59445L,59446L,59447L,59448L,59449L,59450L,59451L,59452L,59453L,59454L,\n59455L,59456L,59457L,59458L,59459L,59460L,59461L,59462L,59463L,59464L,\n59465L,59466L,59467L,59468L,59469L,59470L,59471L,59472L,59473L,59474L,\n59475L,59476L,59477L,59478L,59479L,59480L,59481L,59482L,59483L,59484L,\n59485L,59486L,59487L,59488L,59489L,59490L,59491L,59492L,59493L,59494L,\n59495L,59496L,59497L,59498L,59499L,59500L,59501L,59502L,59503L,59504L,\n59505L,59506L,59507L,59508L,59509L,59510L,59511L,59512L,59513L,59514L,\n59515L,59516L,59517L,59518L,59519L,59520L,59521L,59522L,59523L,59524L,\n59525L,59526L,59527L,59528L,59529L,59530L,59531L,59532L,59533L,59534L,\n59535L,59536L,59537L,59538L,59539L,59540L,59541L,59542L,59543L,59544L,\n59545L,59546L,59547L,59548L,59549L,59550L,59551L,59552L,59553L,59554L,\n59555L,59556L,59557L,59558L,59559L,59560L,59561L,59562L,59563L,59564L,\n59565L,59566L,59567L,59568L,59569L,59570L,59571L,59572L,59573L,59574L,\n59575L,59576L,59577L,59578L,59579L,59580L,59581L,59582L,59583L,59584L,\n59585L,59586L,59587L,59588L,59589L,59590L,59591L,59592L,59593L,59594L,\n59595L,59596L,59597L,59598L,59599L,59600L,59601L,59602L,59603L,59604L,\n59605L,59606L,59607L,59608L,59609L,59610L,59611L,59612L,59613L,59614L,\n59615L,59616L,59617L,59618L,59619L,59620L,59621L,59622L,59623L,59624L,\n59625L,59626L,59627L,59628L,59629L,59630L,59631L,59632L,59633L,59634L,\n59635L,59636L,59637L,59638L,59639L,59640L,59641L,59642L,59643L,59644L,\n59645L,59646L,59647L,59648L,59649L,59650L,59651L,59652L,59653L,59654L,\n59655L,59656L,59657L,59658L,59659L,59660L,59661L,59662L,59663L,59664L,\n59665L,59666L,59667L,59668L,59669L,59670L,59671L,59672L,59673L,59674L,\n59675L,59676L,59677L,59678L,59679L,59680L,59681L,59682L,59683L,59684L,\n59685L,59686L,59687L,59688L,59689L,59690L,59691L,59692L,59693L,59694L,\n59695L,59696L,59697L,59698L,59699L,59700L,59701L,59702L,59703L,59704L,\n59705L,59706L,59707L,59708L,59709L,59710L,59711L,59712L,59713L,59714L,\n59715L,59716L,59717L,59718L,59719L,59720L,59721L,59722L,59723L,59724L,\n59725L,59726L,59727L,59728L,59729L,59730L,59731L,59732L,59733L,59734L,\n59735L,59736L,59737L,59738L,59739L,59740L,59741L,59742L,59743L,59744L,\n59745L,59746L,59747L,59748L,59749L,59750L,59751L,59752L,59753L,59754L,\n59755L,59756L,59757L,59758L,59759L,59760L,59761L,59762L,59763L,59764L,\n59765L,59766L,59767L,59768L,59769L,59770L,59771L,59772L,59773L,59774L,\n59775L,59776L,59777L,59778L,59779L,59780L,59781L,59782L,59783L,59784L,\n59785L,59786L,59787L,59788L,59789L,59790L,59791L,59792L,59793L,59794L,\n59795L,59796L,59797L,59798L,59799L,59800L,59801L,59802L,59803L,59804L,\n59805L,59806L,59807L,59808L,59809L,59810L,59811L,59812L,59813L,59814L,\n59815L,59816L,59817L,59818L,59819L,59820L,59821L,59822L,59823L,59824L,\n59825L,59826L,59827L,59828L,59829L,59830L,59831L,59832L,59833L,59834L,\n59835L,59836L,59837L,59838L,59839L,59840L,59841L,59842L,59843L,59844L,\n59845L,59846L,59847L,59848L,59849L,59850L,59851L,59852L,59853L,59854L,\n59855L,59856L,59857L,59858L,59859L,59860L,59861L,59862L,59863L,59864L,\n59865L,59866L,59867L,59868L,59869L,59870L,59871L,59872L,59873L,59874L,\n59875L,59876L,59877L,59878L,59879L,59880L,59881L,59882L,59883L,59884L,\n59885L,59886L,59887L,59888L,59889L,59890L,59891L,59892L,59893L,59894L,\n59895L,59896L,59897L,59898L,59899L,59900L,59901L,59902L,59903L,59904L,\n59905L,59906L,59907L,59908L,59909L,59910L,59911L,59912L,59913L,59914L,\n59915L,59916L,59917L,59918L,59919L,59920L,59921L,59922L,59923L,59924L,\n59925L,59926L,59927L,59928L,59929L,59930L,59931L,59932L,59933L,59934L,\n59935L,59936L,59937L,59938L,59939L,59940L,59941L,59942L,59943L,59944L,\n59945L,59946L,59947L,59948L,59949L,59950L,59951L,59952L,59953L,59954L,\n59955L,59956L,59957L,59958L,59959L,59960L,59961L,59962L,59963L,59964L,\n59965L,59966L,59967L,59968L,59969L,59970L,59971L,59972L,59973L,59974L,\n59975L,59976L,59977L,59978L,59979L,59980L,59981L,59982L,59983L,59984L,\n59985L,59986L,59987L,59988L,59989L,59990L,59991L,59992L,59993L,59994L,\n59995L,59996L,59997L,59998L,59999L,60000L,60001L,60002L,60003L,60004L,\n60005L,60006L,60007L,60008L,60009L,60010L,60011L,60012L,60013L,60014L,\n60015L,60016L,60017L,60018L,60019L,60020L,60021L,60022L,60023L,60024L,\n60025L,60026L,60027L,60028L,60029L,60030L,60031L,60032L,60033L,60034L,\n60035L,60036L,60037L,60038L,60039L,60040L,60041L,60042L,60043L,60044L,\n60045L,60046L,60047L,60048L,60049L,60050L,60051L,60052L,60053L,60054L,\n60055L,60056L,60057L,60058L,60059L,60060L,60061L,60062L,60063L,60064L,\n60065L,60066L,60067L,60068L,60069L,60070L,60071L,60072L,60073L,60074L,\n60075L,60076L,60077L,60078L,60079L,60080L,60081L,60082L,60083L,60084L,\n60085L,60086L,60087L,60088L,60089L,60090L,60091L,60092L,60093L,60094L,\n60095L,60096L,60097L,60098L,60099L,60100L,60101L,60102L,60103L,60104L,\n60105L,60106L,60107L,60108L,60109L,60110L,60111L,60112L,60113L,60114L,\n60115L,60116L,60117L,60118L,60119L,60120L,60121L,60122L,60123L,60124L,\n60125L,60126L,60127L,60128L,60129L,60130L,60131L,60132L,60133L,60134L,\n60135L,60136L,60137L,60138L,60139L,60140L,60141L,60142L,60143L,60144L,\n60145L,60146L,60147L,60148L,60149L,60150L,60151L,60152L,60153L,60154L,\n60155L,60156L,60157L,60158L,60159L,60160L,60161L,60162L,60163L,60164L,\n60165L,60166L,60167L,60168L,60169L,60170L,60171L,60172L,60173L,60174L,\n60175L,60176L,60177L,60178L,60179L,60180L,60181L,60182L,60183L,60184L,\n60185L,60186L,60187L,60188L,60189L,60190L,60191L,60192L,60193L,60194L,\n60195L,60196L,60197L,60198L,60199L,60200L,60201L,60202L,60203L,60204L,\n60205L,60206L,60207L,60208L,60209L,60210L,60211L,60212L,60213L,60214L,\n60215L,60216L,60217L,60218L,60219L,60220L,60221L,60222L,60223L,60224L,\n60225L,60226L,60227L,60228L,60229L,60230L,60231L,60232L,60233L,60234L,\n60235L,60236L,60237L,60238L,60239L,60240L,60241L,60242L,60243L,60244L,\n60245L,60246L,60247L,60248L,60249L,60250L,60251L,60252L,60253L,60254L,\n60255L,60256L,60257L,60258L,60259L,60260L,60261L,60262L,60263L,60264L,\n60265L,60266L,60267L,60268L,60269L,60270L,60271L,60272L,60273L,60274L,\n60275L,60276L,60277L,60278L,60279L,60280L,60281L,60282L,60283L,60284L,\n60285L,60286L,60287L,60288L,60289L,60290L,60291L,60292L,60293L,60294L,\n60295L,60296L,60297L,60298L,60299L,60300L,60301L,60302L,60303L,60304L,\n60305L,60306L,60307L,60308L,60309L,60310L,60311L,60312L,60313L,60314L,\n60315L,60316L,60317L,60318L,60319L,60320L,60321L,60322L,60323L,60324L,\n60325L,60326L,60327L,60328L,60329L,60330L,60331L,60332L,60333L,60334L,\n60335L,60336L,60337L,60338L,60339L,60340L,60341L,60342L,60343L,60344L,\n60345L,60346L,60347L,60348L,60349L,60350L,60351L,60352L,60353L,60354L,\n60355L,60356L,60357L,60358L,60359L,60360L,60361L,60362L,60363L,60364L,\n60365L,60366L,60367L,60368L,60369L,60370L,60371L,60372L,60373L,60374L,\n60375L,60376L,60377L,60378L,60379L,60380L,60381L,60382L,60383L,60384L,\n60385L,60386L,60387L,60388L,60389L,60390L,60391L,60392L,60393L,60394L,\n60395L,60396L,60397L,60398L,60399L,60400L,60401L,60402L,60403L,60404L,\n60405L,60406L,60407L,60408L,60409L,60410L,60411L,60412L,60413L,60414L,\n60415L,60416L,60417L,60418L,60419L,60420L,60421L,60422L,60423L,60424L,\n60425L,60426L,60427L,60428L,60429L,60430L,60431L,60432L,60433L,60434L,\n60435L,60436L,60437L,60438L,60439L,60440L,60441L,60442L,60443L,60444L,\n60445L,60446L,60447L,60448L,60449L,60450L,60451L,60452L,60453L,60454L,\n60455L,60456L,60457L,60458L,60459L,60460L,60461L,60462L,60463L,60464L,\n60465L,60466L,60467L,60468L,60469L,60470L,60471L,60472L,60473L,60474L,\n60475L,60476L,60477L,60478L,60479L,60480L,60481L,60482L,60483L,60484L,\n60485L,60486L,60487L,60488L,60489L,60490L,60491L,60492L,60493L,60494L,\n60495L,60496L,60497L,60498L,60499L,60500L,60501L,60502L,60503L,60504L,\n60505L,60506L,60507L,60508L,60509L,60510L,60511L,60512L,60513L,60514L,\n60515L,60516L,60517L,60518L,60519L,60520L,60521L,60522L,60523L,60524L,\n60525L,60526L,60527L,60528L,60529L,60530L,60531L,60532L,60533L,60534L,\n60535L,60536L,60537L,60538L,60539L,60540L,60541L,60542L,60543L,60544L,\n60545L,60546L,60547L,60548L,60549L,60550L,60551L,60552L,60553L,60554L,\n60555L,60556L,60557L,60558L,60559L,60560L,60561L,60562L,60563L,60564L,\n60565L,60566L,60567L,60568L,60569L,60570L,60571L,60572L,60573L,60574L,\n60575L,60576L,60577L,60578L,60579L,60580L,60581L,60582L,60583L,60584L,\n60585L,60586L,60587L,60588L,60589L,60590L,60591L,60592L,60593L,60594L,\n60595L,60596L,60597L,60598L,60599L,60600L,60601L,60602L,60603L,60604L,\n60605L,60606L,60607L,60608L,60609L,60610L,60611L,60612L,60613L,60614L,\n60615L,60616L,60617L,60618L,60619L,60620L,60621L,60622L,60623L,60624L,\n60625L,60626L,60627L,60628L,60629L,60630L,60631L,60632L,60633L,60634L,\n60635L,60636L,60637L,60638L,60639L,60640L,60641L,60642L,60643L,60644L,\n60645L,60646L,60647L,60648L,60649L,60650L,60651L,60652L,60653L,60654L,\n60655L,60656L,60657L,60658L,60659L,60660L,60661L,60662L,60663L,60664L,\n60665L,60666L,60667L,60668L,60669L,60670L,60671L,60672L,60673L,60674L,\n60675L,60676L,60677L,60678L,60679L,60680L,60681L,60682L,60683L,60684L,\n60685L,60686L,60687L,60688L,60689L,60690L,60691L,60692L,60693L,60694L,\n60695L,60696L,60697L,60698L,60699L,60700L,60701L,60702L,60703L,60704L,\n60705L,60706L,60707L,60708L,60709L,60710L,60711L,60712L,60713L,60714L,\n60715L,60716L,60717L,60718L,60719L,60720L,60721L,60722L,60723L,60724L,\n60725L,60726L,60727L,60728L,60729L,60730L,60731L,60732L,60733L,60734L,\n60735L,60736L,60737L,60738L,60739L,60740L,60741L,60742L,60743L,60744L,\n60745L,60746L,60747L,60748L,60749L,60750L,60751L,60752L,60753L,60754L,\n60755L,60756L,60757L,60758L,60759L,60760L,60761L,60762L,60763L,60764L,\n60765L,60766L,60767L,60768L,60769L,60770L,60771L,60772L,60773L,60774L,\n60775L,60776L,60777L,60778L,60779L,60780L,60781L,60782L,60783L,60784L,\n60785L,60786L,60787L,60788L,60789L,60790L,60791L,60792L,60793L,60794L,\n60795L,60796L,60797L,60798L,60799L,60800L,60801L,60802L,60803L,60804L,\n60805L,60806L,60807L,60808L,60809L,60810L,60811L,60812L,60813L,60814L,\n60815L,60816L,60817L,60818L,60819L,60820L,60821L,60822L,60823L,60824L,\n60825L,60826L,60827L,60828L,60829L,60830L,60831L,60832L,60833L,60834L,\n60835L,60836L,60837L,60838L,60839L,60840L,60841L,60842L,60843L,60844L,\n60845L,60846L,60847L,60848L,60849L,60850L,60851L,60852L,60853L,60854L,\n60855L,60856L,60857L,60858L,60859L,60860L,60861L,60862L,60863L,60864L,\n60865L,60866L,60867L,60868L,60869L,60870L,60871L,60872L,60873L,60874L,\n60875L,60876L,60877L,60878L,60879L,60880L,60881L,60882L,60883L,60884L,\n60885L,60886L,60887L,60888L,60889L,60890L,60891L,60892L,60893L,60894L,\n60895L,60896L,60897L,60898L,60899L,60900L,60901L,60902L,60903L,60904L,\n60905L,60906L,60907L,60908L,60909L,60910L,60911L,60912L,60913L,60914L,\n60915L,60916L,60917L,60918L,60919L,60920L,60921L,60922L,60923L,60924L,\n60925L,60926L,60927L,60928L,60929L,60930L,60931L,60932L,60933L,60934L,\n60935L,60936L,60937L,60938L,60939L,60940L,60941L,60942L,60943L,60944L,\n60945L,60946L,60947L,60948L,60949L,60950L,60951L,60952L,60953L,60954L,\n60955L,60956L,60957L,60958L,60959L,60960L,60961L,60962L,60963L,60964L,\n60965L,60966L,60967L,60968L,60969L,60970L,60971L,60972L,60973L,60974L,\n60975L,60976L,60977L,60978L,60979L,60980L,60981L,60982L,60983L,60984L,\n60985L,60986L,60987L,60988L,60989L,60990L,60991L,60992L,60993L,60994L,\n60995L,60996L,60997L,60998L,60999L,61000L,61001L,61002L,61003L,61004L,\n61005L,61006L,61007L,61008L,61009L,61010L,61011L,61012L,61013L,61014L,\n61015L,61016L,61017L,61018L,61019L,61020L,61021L,61022L,61023L,61024L,\n61025L,61026L,61027L,61028L,61029L,61030L,61031L,61032L,61033L,61034L,\n61035L,61036L,61037L,61038L,61039L,61040L,61041L,61042L,61043L,61044L,\n61045L,61046L,61047L,61048L,61049L,61050L,61051L,61052L,61053L,61054L,\n61055L,61056L,61057L,61058L,61059L,61060L,61061L,61062L,61063L,61064L,\n61065L,61066L,61067L,61068L,61069L,61070L,61071L,61072L,61073L,61074L,\n61075L,61076L,61077L,61078L,61079L,61080L,61081L,61082L,61083L,61084L,\n61085L,61086L,61087L,61088L,61089L,61090L,61091L,61092L,61093L,61094L,\n61095L,61096L,61097L,61098L,61099L,61100L,61101L,61102L,61103L,61104L,\n61105L,61106L,61107L,61108L,61109L,61110L,61111L,61112L,61113L,61114L,\n61115L,61116L,61117L,61118L,61119L,61120L,61121L,61122L,61123L,61124L,\n61125L,61126L,61127L,61128L,61129L,61130L,61131L,61132L,61133L,61134L,\n61135L,61136L,61137L,61138L,61139L,61140L,61141L,61142L,61143L,61144L,\n61145L,61146L,61147L,61148L,61149L,61150L,61151L,61152L,61153L,61154L,\n61155L,61156L,61157L,61158L,61159L,61160L,61161L,61162L,61163L,61164L,\n61165L,61166L,61167L,61168L,61169L,61170L,61171L,61172L,61173L,61174L,\n61175L,61176L,61177L,61178L,61179L,61180L,61181L,61182L,61183L,61184L,\n61185L,61186L,61187L,61188L,61189L,61190L,61191L,61192L,61193L,61194L,\n61195L,61196L,61197L,61198L,61199L,61200L,61201L,61202L,61203L,61204L,\n61205L,61206L,61207L,61208L,61209L,61210L,61211L,61212L,61213L,61214L,\n61215L,61216L,61217L,61218L,61219L,61220L,61221L,61222L,61223L,61224L,\n61225L,61226L,61227L,61228L,61229L,61230L,61231L,61232L,61233L,61234L,\n61235L,61236L,61237L,61238L,61239L,61240L,61241L,61242L,61243L,61244L,\n61245L,61246L,61247L,61248L,61249L,61250L,61251L,61252L,61253L,61254L,\n61255L,61256L,61257L,61258L,61259L,61260L,61261L,61262L,61263L,61264L,\n61265L,61266L,61267L,61268L,61269L,61270L,61271L,61272L,61273L,61274L,\n61275L,61276L,61277L,61278L,61279L,61280L,61281L,61282L,61283L,61284L,\n61285L,61286L,61287L,61288L,61289L,61290L,61291L,61292L,61293L,61294L,\n61295L,61296L,61297L,61298L,61299L,61300L,61301L,61302L,61303L,61304L,\n61305L,61306L,61307L,61308L,61309L,61310L,61311L,61312L,61313L,61314L,\n61315L,61316L,61317L,61318L,61319L,61320L,61321L,61322L,61323L,61324L,\n61325L,61326L,61327L,61328L,61329L,61330L,61331L,61332L,61333L,61334L,\n61335L,61336L,61337L,61338L,61339L,61340L,61341L,61342L,61343L,61344L,\n61345L,61346L,61347L,61348L,61349L,61350L,61351L,61352L,61353L,61354L,\n61355L,61356L,61357L,61358L,61359L,61360L,61361L,61362L,61363L,61364L,\n61365L,61366L,61367L,61368L,61369L,61370L,61371L,61372L,61373L,61374L,\n61375L,61376L,61377L,61378L,61379L,61380L,61381L,61382L,61383L,61384L,\n61385L,61386L,61387L,61388L,61389L,61390L,61391L,61392L,61393L,61394L,\n61395L,61396L,61397L,61398L,61399L,61400L,61401L,61402L,61403L,61404L,\n61405L,61406L,61407L,61408L,61409L,61410L,61411L,61412L,61413L,61414L,\n61415L,61416L,61417L,61418L,61419L,61420L,61421L,61422L,61423L,61424L,\n61425L,61426L,61427L,61428L,61429L,61430L,61431L,61432L,61433L,61434L,\n61435L,61436L,61437L,61438L,61439L,61440L,61441L,61442L,61443L,61444L,\n61445L,61446L,61447L,61448L,61449L,61450L,61451L,61452L,61453L,61454L,\n61455L,61456L,61457L,61458L,61459L,61460L,61461L,61462L,61463L,61464L,\n61465L,61466L,61467L,61468L,61469L,61470L,61471L,61472L,61473L,61474L,\n61475L,61476L,61477L,61478L,61479L,61480L,61481L,61482L,61483L,61484L,\n61485L,61486L,61487L,61488L,61489L,61490L,61491L,61492L,61493L,61494L,\n61495L,61496L,61497L,61498L,61499L,61500L,61501L,61502L,61503L,61504L,\n61505L,61506L,61507L,61508L,61509L,61510L,61511L,61512L,61513L,61514L,\n61515L,61516L,61517L,61518L,61519L,61520L,61521L,61522L,61523L,61524L,\n61525L,61526L,61527L,61528L,61529L,61530L,61531L,61532L,61533L,61534L,\n61535L,61536L,61537L,61538L,61539L,61540L,61541L,61542L,61543L,61544L,\n61545L,61546L,61547L,61548L,61549L,61550L,61551L,61552L,61553L,61554L,\n61555L,61556L,61557L,61558L,61559L,61560L,61561L,61562L,61563L,61564L,\n61565L,61566L,61567L,61568L,61569L,61570L,61571L,61572L,61573L,61574L,\n61575L,61576L,61577L,61578L,61579L,61580L,61581L,61582L,61583L,61584L,\n61585L,61586L,61587L,61588L,61589L,61590L,61591L,61592L,61593L,61594L,\n61595L,61596L,61597L,61598L,61599L,61600L,61601L,61602L,61603L,61604L,\n61605L,61606L,61607L,61608L,61609L,61610L,61611L,61612L,61613L,61614L,\n61615L,61616L,61617L,61618L,61619L,61620L,61621L,61622L,61623L,61624L,\n61625L,61626L,61627L,61628L,61629L,61630L,61631L,61632L,61633L,61634L,\n61635L,61636L,61637L,61638L,61639L,61640L,61641L,61642L,61643L,61644L,\n61645L,61646L,61647L,61648L,61649L,61650L,61651L,61652L,61653L,61654L,\n61655L,61656L,61657L,61658L,61659L,61660L,61661L,61662L,61663L,61664L,\n61665L,61666L,61667L,61668L,61669L,61670L,61671L,61672L,61673L,61674L,\n61675L,61676L,61677L,61678L,61679L,61680L,61681L,61682L,61683L,61684L,\n61685L,61686L,61687L,61688L,61689L,61690L,61691L,61692L,61693L,61694L,\n61695L,61696L,61697L,61698L,61699L,61700L,61701L,61702L,61703L,61704L,\n61705L,61706L,61707L,61708L,61709L,61710L,61711L,61712L,61713L,61714L,\n61715L,61716L,61717L,61718L,61719L,61720L,61721L,61722L,61723L,61724L,\n61725L,61726L,61727L,61728L,61729L,61730L,61731L,61732L,61733L,61734L,\n61735L,61736L,61737L,61738L,61739L,61740L,61741L,61742L,61743L,61744L,\n61745L,61746L,61747L,61748L,61749L,61750L,61751L,61752L,61753L,61754L,\n61755L,61756L,61757L,61758L,61759L,61760L,61761L,61762L,61763L,61764L,\n61765L,61766L,61767L,61768L,61769L,61770L,61771L,61772L,61773L,61774L,\n61775L,61776L,61777L,61778L,61779L,61780L,61781L,61782L,61783L,61784L,\n61785L,61786L,61787L,61788L,61789L,61790L,61791L,61792L,61793L,61794L,\n61795L,61796L,61797L,61798L,61799L,61800L,61801L,61802L,61803L,61804L,\n61805L,61806L,61807L,61808L,61809L,61810L,61811L,61812L,61813L,61814L,\n61815L,61816L,61817L,61818L,61819L,61820L,61821L,61822L,61823L,61824L,\n61825L,61826L,61827L,61828L,61829L,61830L,61831L,61832L,61833L,61834L,\n61835L,61836L,61837L,61838L,61839L,61840L,61841L,61842L,61843L,61844L,\n61845L,61846L,61847L,61848L,61849L,61850L,61851L,61852L,61853L,61854L,\n61855L,61856L,61857L,61858L,61859L,61860L,61861L,61862L,61863L,61864L,\n61865L,61866L,61867L,61868L,61869L,61870L,61871L,61872L,61873L,61874L,\n61875L,61876L,61877L,61878L,61879L,61880L,61881L,61882L,61883L,61884L,\n61885L,61886L,61887L,61888L,61889L,61890L,61891L,61892L,61893L,61894L,\n61895L,61896L,61897L,61898L,61899L,61900L,61901L,61902L,61903L,61904L,\n61905L,61906L,61907L,61908L,61909L,61910L,61911L,61912L,61913L,61914L,\n61915L,61916L,61917L,61918L,61919L,61920L,61921L,61922L,61923L,61924L,\n61925L,61926L,61927L,61928L,61929L,61930L,61931L,61932L,61933L,61934L,\n61935L,61936L,61937L,61938L,61939L,61940L,61941L,61942L,61943L,61944L,\n61945L,61946L,61947L,61948L,61949L,61950L,61951L,61952L,61953L,61954L,\n61955L,61956L,61957L,61958L,61959L,61960L,61961L,61962L,61963L,61964L,\n61965L,61966L,61967L,61968L,61969L,61970L,61971L,61972L,61973L,61974L,\n61975L,61976L,61977L,61978L,61979L,61980L,61981L,61982L,61983L,61984L,\n61985L,61986L,61987L,61988L,61989L,61990L,61991L,61992L,61993L,61994L,\n61995L,61996L,61997L,61998L,61999L,62000L,62001L,62002L,62003L,62004L,\n62005L,62006L,62007L,62008L,62009L,62010L,62011L,62012L,62013L,62014L,\n62015L,62016L,62017L,62018L,62019L,62020L,62021L,62022L,62023L,62024L,\n62025L,62026L,62027L,62028L,62029L,62030L,62031L,62032L,62033L,62034L,\n62035L,62036L,62037L,62038L,62039L,62040L,62041L,62042L,62043L,62044L,\n62045L,62046L,62047L,62048L,62049L,62050L,62051L,62052L,62053L,62054L,\n62055L,62056L,62057L,62058L,62059L,62060L,62061L,62062L,62063L,62064L,\n62065L,62066L,62067L,62068L,62069L,62070L,62071L,62072L,62073L,62074L,\n62075L,62076L,62077L,62078L,62079L,62080L,62081L,62082L,62083L,62084L,\n62085L,62086L,62087L,62088L,62089L,62090L,62091L,62092L,62093L,62094L,\n62095L,62096L,62097L,62098L,62099L,62100L,62101L,62102L,62103L,62104L,\n62105L,62106L,62107L,62108L,62109L,62110L,62111L,62112L,62113L,62114L,\n62115L,62116L,62117L,62118L,62119L,62120L,62121L,62122L,62123L,62124L,\n62125L,62126L,62127L,62128L,62129L,62130L,62131L,62132L,62133L,62134L,\n62135L,62136L,62137L,62138L,62139L,62140L,62141L,62142L,62143L,62144L,\n62145L,62146L,62147L,62148L,62149L,62150L,62151L,62152L,62153L,62154L,\n62155L,62156L,62157L,62158L,62159L,62160L,62161L,62162L,62163L,62164L,\n62165L,62166L,62167L,62168L,62169L,62170L,62171L,62172L,62173L,62174L,\n62175L,62176L,62177L,62178L,62179L,62180L,62181L,62182L,62183L,62184L,\n62185L,62186L,62187L,62188L,62189L,62190L,62191L,62192L,62193L,62194L,\n62195L,62196L,62197L,62198L,62199L,62200L,62201L,62202L,62203L,62204L,\n62205L,62206L,62207L,62208L,62209L,62210L,62211L,62212L,62213L,62214L,\n62215L,62216L,62217L,62218L,62219L,62220L,62221L,62222L,62223L,62224L,\n62225L,62226L,62227L,62228L,62229L,62230L,62231L,62232L,62233L,62234L,\n62235L,62236L,62237L,62238L,62239L,62240L,62241L,62242L,62243L,62244L,\n62245L,62246L,62247L,62248L,62249L,62250L,62251L,62252L,62253L,62254L,\n62255L,62256L,62257L,62258L,62259L,62260L,62261L,62262L,62263L,62264L,\n62265L,62266L,62267L,62268L,62269L,62270L,62271L,62272L,62273L,62274L,\n62275L,62276L,62277L,62278L,62279L,62280L,62281L,62282L,62283L,62284L,\n62285L,62286L,62287L,62288L,62289L,62290L,62291L,62292L,62293L,62294L,\n62295L,62296L,62297L,62298L,62299L,62300L,62301L,62302L,62303L,62304L,\n62305L,62306L,62307L,62308L,62309L,62310L,62311L,62312L,62313L,62314L,\n62315L,62316L,62317L,62318L,62319L,62320L,62321L,62322L,62323L,62324L,\n62325L,62326L,62327L,62328L,62329L,62330L,62331L,62332L,62333L,62334L,\n62335L,62336L,62337L,62338L,62339L,62340L,62341L,62342L,62343L,62344L,\n62345L,62346L,62347L,62348L,62349L,62350L,62351L,62352L,62353L,62354L,\n62355L,62356L,62357L,62358L,62359L,62360L,62361L,62362L,62363L,62364L,\n62365L,62366L,62367L,62368L,62369L,62370L,62371L,62372L,62373L,62374L,\n62375L,62376L,62377L,62378L,62379L,62380L,62381L,62382L,62383L,62384L,\n62385L,62386L,62387L,62388L,62389L,62390L,62391L,62392L,62393L,62394L,\n62395L,62396L,62397L,62398L,62399L,62400L,62401L,62402L,62403L,62404L,\n62405L,62406L,62407L,62408L,62409L,62410L,62411L,62412L,62413L,62414L,\n62415L,62416L,62417L,62418L,62419L,62420L,62421L,62422L,62423L,62424L,\n62425L,62426L,62427L,62428L,62429L,62430L,62431L,62432L,62433L,62434L,\n62435L,62436L,62437L,62438L,62439L,62440L,62441L,62442L,62443L,62444L,\n62445L,62446L,62447L,62448L,62449L,62450L,62451L,62452L,62453L,62454L,\n62455L,62456L,62457L,62458L,62459L,62460L,62461L,62462L,62463L,62464L,\n62465L,62466L,62467L,62468L,62469L,62470L,62471L,62472L,62473L,62474L,\n62475L,62476L,62477L,62478L,62479L,62480L,62481L,62482L,62483L,62484L,\n62485L,62486L,62487L,62488L,62489L,62490L,62491L,62492L,62493L,62494L,\n62495L,62496L,62497L,62498L,62499L,62500L,62501L,62502L,62503L,62504L,\n62505L,62506L,62507L,62508L,62509L,62510L,62511L,62512L,62513L,62514L,\n62515L,62516L,62517L,62518L,62519L,62520L,62521L,62522L,62523L,62524L,\n62525L,62526L,62527L,62528L,62529L,62530L,62531L,62532L,62533L,62534L,\n62535L,62536L,62537L,62538L,62539L,62540L,62541L,62542L,62543L,62544L,\n62545L,62546L,62547L,62548L,62549L,62550L,62551L,62552L,62553L,62554L,\n62555L,62556L,62557L,62558L,62559L,62560L,62561L,62562L,62563L,62564L,\n62565L,62566L,62567L,62568L,62569L,62570L,62571L,62572L,62573L,62574L,\n62575L,62576L,62577L,62578L,62579L,62580L,62581L,62582L,62583L,62584L,\n62585L,62586L,62587L,62588L,62589L,62590L,62591L,62592L,62593L,62594L,\n62595L,62596L,62597L,62598L,62599L,62600L,62601L,62602L,62603L,62604L,\n62605L,62606L,62607L,62608L,62609L,62610L,62611L,62612L,62613L,62614L,\n62615L,62616L,62617L,62618L,62619L,62620L,62621L,62622L,62623L,62624L,\n62625L,62626L,62627L,62628L,62629L,62630L,62631L,62632L,62633L,62634L,\n62635L,62636L,62637L,62638L,62639L,62640L,62641L,62642L,62643L,62644L,\n62645L,62646L,62647L,62648L,62649L,62650L,62651L,62652L,62653L,62654L,\n62655L,62656L,62657L,62658L,62659L,62660L,62661L,62662L,62663L,62664L,\n62665L,62666L,62667L,62668L,62669L,62670L,62671L,62672L,62673L,62674L,\n62675L,62676L,62677L,62678L,62679L,62680L,62681L,62682L,62683L,62684L,\n62685L,62686L,62687L,62688L,62689L,62690L,62691L,62692L,62693L,62694L,\n62695L,62696L,62697L,62698L,62699L,62700L,62701L,62702L,62703L,62704L,\n62705L,62706L,62707L,62708L,62709L,62710L,62711L,62712L,62713L,62714L,\n62715L,62716L,62717L,62718L,62719L,62720L,62721L,62722L,62723L,62724L,\n62725L,62726L,62727L,62728L,62729L,62730L,62731L,62732L,62733L,62734L,\n62735L,62736L,62737L,62738L,62739L,62740L,62741L,62742L,62743L,62744L,\n62745L,62746L,62747L,62748L,62749L,62750L,62751L,62752L,62753L,62754L,\n62755L,62756L,62757L,62758L,62759L,62760L,62761L,62762L,62763L,62764L,\n62765L,62766L,62767L,62768L,62769L,62770L,62771L,62772L,62773L,62774L,\n62775L,62776L,62777L,62778L,62779L,62780L,62781L,62782L,62783L,62784L,\n62785L,62786L,62787L,62788L,62789L,62790L,62791L,62792L,62793L,62794L,\n62795L,62796L,62797L,62798L,62799L,62800L,62801L,62802L,62803L,62804L,\n62805L,62806L,62807L,62808L,62809L,62810L,62811L,62812L,62813L,62814L,\n62815L,62816L,62817L,62818L,62819L,62820L,62821L,62822L,62823L,62824L,\n62825L,62826L,62827L,62828L,62829L,62830L,62831L,62832L,62833L,62834L,\n62835L,62836L,62837L,62838L,62839L,62840L,62841L,62842L,62843L,62844L,\n62845L,62846L,62847L,62848L,62849L,62850L,62851L,62852L,62853L,62854L,\n62855L,62856L,62857L,62858L,62859L,62860L,62861L,62862L,62863L,62864L,\n62865L,62866L,62867L,62868L,62869L,62870L,62871L,62872L,62873L,62874L,\n62875L,62876L,62877L,62878L,62879L,62880L,62881L,62882L,62883L,62884L,\n62885L,62886L,62887L,62888L,62889L,62890L,62891L,62892L,62893L,62894L,\n62895L,62896L,62897L,62898L,62899L,62900L,62901L,62902L,62903L,62904L,\n62905L,62906L,62907L,62908L,62909L,62910L,62911L,62912L,62913L,62914L,\n62915L,62916L,62917L,62918L,62919L,62920L,62921L,62922L,62923L,62924L,\n62925L,62926L,62927L,62928L,62929L,62930L,62931L,62932L,62933L,62934L,\n62935L,62936L,62937L,62938L,62939L,62940L,62941L,62942L,62943L,62944L,\n62945L,62946L,62947L,62948L,62949L,62950L,62951L,62952L,62953L,62954L,\n62955L,62956L,62957L,62958L,62959L,62960L,62961L,62962L,62963L,62964L,\n62965L,62966L,62967L,62968L,62969L,62970L,62971L,62972L,62973L,62974L,\n62975L,62976L,62977L,62978L,62979L,62980L,62981L,62982L,62983L,62984L,\n62985L,62986L,62987L,62988L,62989L,62990L,62991L,62992L,62993L,62994L,\n62995L,62996L,62997L,62998L,62999L,63000L,63001L,63002L,63003L,63004L,\n63005L,63006L,63007L,63008L,63009L,63010L,63011L,63012L,63013L,63014L,\n63015L,63016L,63017L,63018L,63019L,63020L,63021L,63022L,63023L,63024L,\n63025L,63026L,63027L,63028L,63029L,63030L,63031L,63032L,63033L,63034L,\n63035L,63036L,63037L,63038L,63039L,63040L,63041L,63042L,63043L,63044L,\n63045L,63046L,63047L,63048L,63049L,63050L,63051L,63052L,63053L,63054L,\n63055L,63056L,63057L,63058L,63059L,63060L,63061L,63062L,63063L,63064L,\n63065L,63066L,63067L,63068L,63069L,63070L,63071L,63072L,63073L,63074L,\n63075L,63076L,63077L,63078L,63079L,63080L,63081L,63082L,63083L,63084L,\n63085L,63086L,63087L,63088L,63089L,63090L,63091L,63092L,63093L,63094L,\n63095L,63096L,63097L,63098L,63099L,63100L,63101L,63102L,63103L,63104L,\n63105L,63106L,63107L,63108L,63109L,63110L,63111L,63112L,63113L,63114L,\n63115L,63116L,63117L,63118L,63119L,63120L,63121L,63122L,63123L,63124L,\n63125L,63126L,63127L,63128L,63129L,63130L,63131L,63132L,63133L,63134L,\n63135L,63136L,63137L,63138L,63139L,63140L,63141L,63142L,63143L,63144L,\n63145L,63146L,63147L,63148L,63149L,63150L,63151L,63152L,63153L,63154L,\n63155L,63156L,63157L,63158L,63159L,63160L,63161L,63162L,63163L,63164L,\n63165L,63166L,63167L,63168L,63169L,63170L,63171L,63172L,63173L,63174L,\n63175L,63176L,63177L,63178L,63179L,63180L,63181L,63182L,63183L,63184L,\n63185L,63186L,63187L,63188L,63189L,63190L,63191L,63192L,63193L,63194L,\n63195L,63196L,63197L,63198L,63199L,63200L,63201L,63202L,63203L,63204L,\n63205L,63206L,63207L,63208L,63209L,63210L,63211L,63212L,63213L,63214L,\n63215L,63216L,63217L,63218L,63219L,63220L,63221L,63222L,63223L,63224L,\n63225L,63226L,63227L,63228L,63229L,63230L,63231L,63232L,63233L,63234L,\n63235L,63236L,63237L,63238L,63239L,63240L,63241L,63242L,63243L,63244L,\n63245L,63246L,63247L,63248L,63249L,63250L,63251L,63252L,63253L,63254L,\n63255L,63256L,63257L,63258L,63259L,63260L,63261L,63262L,63263L,63264L,\n63265L,63266L,63267L,63268L,63269L,63270L,63271L,63272L,63273L,63274L,\n63275L,63276L,63277L,63278L,63279L,63280L,63281L,63282L,63283L,63284L,\n63285L,63286L,63287L,63288L,63289L,63290L,63291L,63292L,63293L,63294L,\n63295L,63296L,63297L,63298L,63299L,63300L,63301L,63302L,63303L,63304L,\n63305L,63306L,63307L,63308L,63309L,63310L,63311L,63312L,63313L,63314L,\n63315L,63316L,63317L,63318L,63319L,63320L,63321L,63322L,63323L,63324L,\n63325L,63326L,63327L,63328L,63329L,63330L,63331L,63332L,63333L,63334L,\n63335L,63336L,63337L,63338L,63339L,63340L,63341L,63342L,63343L,63344L,\n63345L,63346L,63347L,63348L,63349L,63350L,63351L,63352L,63353L,63354L,\n63355L,63356L,63357L,63358L,63359L,63360L,63361L,63362L,63363L,63364L,\n63365L,63366L,63367L,63368L,63369L,63370L,63371L,63372L,63373L,63374L,\n63375L,63376L,63377L,63378L,63379L,63380L,63381L,63382L,63383L,63384L,\n63385L,63386L,63387L,63388L,63389L,63390L,63391L,63392L,63393L,63394L,\n63395L,63396L,63397L,63398L,63399L,63400L,63401L,63402L,63403L,63404L,\n63405L,63406L,63407L,63408L,63409L,63410L,63411L,63412L,63413L,63414L,\n63415L,63416L,63417L,63418L,63419L,63420L,63421L,63422L,63423L,63424L,\n63425L,63426L,63427L,63428L,63429L,63430L,63431L,63432L,63433L,63434L,\n63435L,63436L,63437L,63438L,63439L,63440L,63441L,63442L,63443L,63444L,\n63445L,63446L,63447L,63448L,63449L,63450L,63451L,63452L,63453L,63454L,\n63455L,63456L,63457L,63458L,63459L,63460L,63461L,63462L,63463L,63464L,\n63465L,63466L,63467L,63468L,63469L,63470L,63471L,63472L,63473L,63474L,\n63475L,63476L,63477L,63478L,63479L,63480L,63481L,63482L,63483L,63484L,\n63485L,63486L,63487L,63488L,63489L,63490L,63491L,63492L,63493L,63494L,\n63495L,63496L,63497L,63498L,63499L,63500L,63501L,63502L,63503L,63504L,\n63505L,63506L,63507L,63508L,63509L,63510L,63511L,63512L,63513L,63514L,\n63515L,63516L,63517L,63518L,63519L,63520L,63521L,63522L,63523L,63524L,\n63525L,63526L,63527L,63528L,63529L,63530L,63531L,63532L,63533L,63534L,\n63535L,63536L,63537L,63538L,63539L,63540L,63541L,63542L,63543L,63544L,\n63545L,63546L,63547L,63548L,63549L,63550L,63551L,63552L,63553L,63554L,\n63555L,63556L,63557L,63558L,63559L,63560L,63561L,63562L,63563L,63564L,\n63565L,63566L,63567L,63568L,63569L,63570L,63571L,63572L,63573L,63574L,\n63575L,63576L,63577L,63578L,63579L,63580L,63581L,63582L,63583L,63584L,\n63585L,63586L,63587L,63588L,63589L,63590L,63591L,63592L,63593L,63594L,\n63595L,63596L,63597L,63598L,63599L,63600L,63601L,63602L,63603L,63604L,\n63605L,63606L,63607L,63608L,63609L,63610L,63611L,63612L,63613L,63614L,\n63615L,63616L,63617L,63618L,63619L,63620L,63621L,63622L,63623L,63624L,\n63625L,63626L,63627L,63628L,63629L,63630L,63631L,63632L,63633L,63634L,\n63635L,63636L,63637L,63638L,63639L,63640L,63641L,63642L,63643L,63644L,\n63645L,63646L,63647L,63648L,63649L,63650L,63651L,63652L,63653L,63654L,\n63655L,63656L,63657L,63658L,63659L,63660L,63661L,63662L,63663L,63664L,\n63665L,63666L,63667L,63668L,63669L,63670L,63671L,63672L,63673L,63674L,\n63675L,63676L,63677L,63678L,63679L,63680L,63681L,63682L,63683L,63684L,\n63685L,63686L,63687L,63688L,63689L,63690L,63691L,63692L,63693L,63694L,\n63695L,63696L,63697L,63698L,63699L,63700L,63701L,63702L,63703L,63704L,\n63705L,63706L,63707L,63708L,63709L,63710L,63711L,63712L,63713L,63714L,\n63715L,63716L,63717L,63718L,63719L,63720L,63721L,63722L,63723L,63724L,\n63725L,63726L,63727L,63728L,63729L,63730L,63731L,63732L,63733L,63734L,\n63735L,63736L,63737L,63738L,63739L,63740L,63741L,63742L,63743L,63744L,\n63745L,63746L,63747L,63748L,63749L,63750L,63751L,63752L,63753L,63754L,\n63755L,63756L,63757L,63758L,63759L,63760L,63761L,63762L,63763L,63764L,\n63765L,63766L,63767L,63768L,63769L,63770L,63771L,63772L,63773L,63774L,\n63775L,63776L,63777L,63778L,63779L,63780L,63781L,63782L,63783L,63784L,\n63785L,63786L,63787L,63788L,63789L,63790L,63791L,63792L,63793L,63794L,\n63795L,63796L,63797L,63798L,63799L,63800L,63801L,63802L,63803L,63804L,\n63805L,63806L,63807L,63808L,63809L,63810L,63811L,63812L,63813L,63814L,\n63815L,63816L,63817L,63818L,63819L,63820L,63821L,63822L,63823L,63824L,\n63825L,63826L,63827L,63828L,63829L,63830L,63831L,63832L,63833L,63834L,\n63835L,63836L,63837L,63838L,63839L,63840L,63841L,63842L,63843L,63844L,\n63845L,63846L,63847L,63848L,63849L,63850L,63851L,63852L,63853L,63854L,\n63855L,63856L,63857L,63858L,63859L,63860L,63861L,63862L,63863L,63864L,\n63865L,63866L,63867L,63868L,63869L,63870L,63871L,63872L,63873L,63874L,\n63875L,63876L,63877L,63878L,63879L,63880L,63881L,63882L,63883L,63884L,\n63885L,63886L,63887L,63888L,63889L,63890L,63891L,63892L,63893L,63894L,\n63895L,63896L,63897L,63898L,63899L,63900L,63901L,63902L,63903L,63904L,\n63905L,63906L,63907L,63908L,63909L,63910L,63911L,63912L,63913L,63914L,\n63915L,63916L,63917L,63918L,63919L,63920L,63921L,63922L,63923L,63924L,\n63925L,63926L,63927L,63928L,63929L,63930L,63931L,63932L,63933L,63934L,\n63935L,63936L,63937L,63938L,63939L,63940L,63941L,63942L,63943L,63944L,\n63945L,63946L,63947L,63948L,63949L,63950L,63951L,63952L,63953L,63954L,\n63955L,63956L,63957L,63958L,63959L,63960L,63961L,63962L,63963L,63964L,\n63965L,63966L,63967L,63968L,63969L,63970L,63971L,63972L,63973L,63974L,\n63975L,63976L,63977L,63978L,63979L,63980L,63981L,63982L,63983L,63984L,\n63985L,63986L,63987L,63988L,63989L,63990L,63991L,63992L,63993L,63994L,\n63995L,63996L,63997L,63998L,63999L,64000L,64001L,64002L,64003L,64004L,\n64005L,64006L,64007L,64008L,64009L,64010L,64011L,64012L,64013L,64014L,\n64015L,64016L,64017L,64018L,64019L,64020L,64021L,64022L,64023L,64024L,\n64025L,64026L,64027L,64028L,64029L,64030L,64031L,64032L,64033L,64034L,\n64035L,64036L,64037L,64038L,64039L,64040L,64041L,64042L,64043L,64044L,\n64045L,64046L,64047L,64048L,64049L,64050L,64051L,64052L,64053L,64054L,\n64055L,64056L,64057L,64058L,64059L,64060L,64061L,64062L,64063L,64064L,\n64065L,64066L,64067L,64068L,64069L,64070L,64071L,64072L,64073L,64074L,\n64075L,64076L,64077L,64078L,64079L,64080L,64081L,64082L,64083L,64084L,\n64085L,64086L,64087L,64088L,64089L,64090L,64091L,64092L,64093L,64094L,\n64095L,64096L,64097L,64098L,64099L,64100L,64101L,64102L,64103L,64104L,\n64105L,64106L,64107L,64108L,64109L,64110L,64111L,64112L,64113L,64114L,\n64115L,64116L,64117L,64118L,64119L,64120L,64121L,64122L,64123L,64124L,\n64125L,64126L,64127L,64128L,64129L,64130L,64131L,64132L,64133L,64134L,\n64135L,64136L,64137L,64138L,64139L,64140L,64141L,64142L,64143L,64144L,\n64145L,64146L,64147L,64148L,64149L,64150L,64151L,64152L,64153L,64154L,\n64155L,64156L,64157L,64158L,64159L,64160L,64161L,64162L,64163L,64164L,\n64165L,64166L,64167L,64168L,64169L,64170L,64171L,64172L,64173L,64174L,\n64175L,64176L,64177L,64178L,64179L,64180L,64181L,64182L,64183L,64184L,\n64185L,64186L,64187L,64188L,64189L,64190L,64191L,64192L,64193L,64194L,\n64195L,64196L,64197L,64198L,64199L,64200L,64201L,64202L,64203L,64204L,\n64205L,64206L,64207L,64208L,64209L,64210L,64211L,64212L,64213L,64214L,\n64215L,64216L,64217L,64218L,64219L,64220L,64221L,64222L,64223L,64224L,\n64225L,64226L,64227L,64228L,64229L,64230L,64231L,64232L,64233L,64234L,\n64235L,64236L,64237L,64238L,64239L,64240L,64241L,64242L,64243L,64244L,\n64245L,64246L,64247L,64248L,64249L,64250L,64251L,64252L,64253L,64254L,\n64255L,64256L,64257L,64258L,64259L,64260L,64261L,64262L,64263L,64264L,\n64265L,64266L,64267L,64268L,64269L,64270L,64271L,64272L,64273L,64274L,\n64275L,64276L,64277L,64278L,64279L,64280L,64281L,64282L,64283L,64284L,\n64285L,64286L,64287L,64288L,64289L,64290L,64291L,64292L,64293L,64294L,\n64295L,64296L,64297L,64298L,64299L,64300L,64301L,64302L,64303L,64304L,\n64305L,64306L,64307L,64308L,64309L,64310L,64311L,64312L,64313L,64314L,\n64315L,64316L,64317L,64318L,64319L,64320L,64321L,64322L,64323L,64324L,\n64325L,64326L,64327L,64328L,64329L,64330L,64331L,64332L,64333L,64334L,\n64335L,64336L,64337L,64338L,64339L,64340L,64341L,64342L,64343L,64344L,\n64345L,64346L,64347L,64348L,64349L,64350L,64351L,64352L,64353L,64354L,\n64355L,64356L,64357L,64358L,64359L,64360L,64361L,64362L,64363L,64364L,\n64365L,64366L,64367L,64368L,64369L,64370L,64371L,64372L,64373L,64374L,\n64375L,64376L,64377L,64378L,64379L,64380L,64381L,64382L,64383L,64384L,\n64385L,64386L,64387L,64388L,64389L,64390L,64391L,64392L,64393L,64394L,\n64395L,64396L,64397L,64398L,64399L,64400L,64401L,64402L,64403L,64404L,\n64405L,64406L,64407L,64408L,64409L,64410L,64411L,64412L,64413L,64414L,\n64415L,64416L,64417L,64418L,64419L,64420L,64421L,64422L,64423L,64424L,\n64425L,64426L,64427L,64428L,64429L,64430L,64431L,64432L,64433L,64434L,\n64435L,64436L,64437L,64438L,64439L,64440L,64441L,64442L,64443L,64444L,\n64445L,64446L,64447L,64448L,64449L,64450L,64451L,64452L,64453L,64454L,\n64455L,64456L,64457L,64458L,64459L,64460L,64461L,64462L,64463L,64464L,\n64465L,64466L,64467L,64468L,64469L,64470L,64471L,64472L,64473L,64474L,\n64475L,64476L,64477L,64478L,64479L,64480L,64481L,64482L,64483L,64484L,\n64485L,64486L,64487L,64488L,64489L,64490L,64491L,64492L,64493L,64494L,\n64495L,64496L,64497L,64498L,64499L,64500L,64501L,64502L,64503L,64504L,\n64505L,64506L,64507L,64508L,64509L,64510L,64511L,64512L,64513L,64514L,\n64515L,64516L,64517L,64518L,64519L,64520L,64521L,64522L,64523L,64524L,\n64525L,64526L,64527L,64528L,64529L,64530L,64531L,64532L,64533L,64534L,\n64535L,64536L,64537L,64538L,64539L,64540L,64541L,64542L,64543L,64544L,\n64545L,64546L,64547L,64548L,64549L,64550L,64551L,64552L,64553L,64554L,\n64555L,64556L,64557L,64558L,64559L,64560L,64561L,64562L,64563L,64564L,\n64565L,64566L,64567L,64568L,64569L,64570L,64571L,64572L,64573L,64574L,\n64575L,64576L,64577L,64578L,64579L,64580L,64581L,64582L,64583L,64584L,\n64585L,64586L,64587L,64588L,64589L,64590L,64591L,64592L,64593L,64594L,\n64595L,64596L,64597L,64598L,64599L,64600L,64601L,64602L,64603L,64604L,\n64605L,64606L,64607L,64608L,64609L,64610L,64611L,64612L,64613L,64614L,\n64615L,64616L,64617L,64618L,64619L,64620L,64621L,64622L,64623L,64624L,\n64625L,64626L,64627L,64628L,64629L,64630L,64631L,64632L,64633L,64634L,\n64635L,64636L,64637L,64638L,64639L,64640L,64641L,64642L,64643L,64644L,\n64645L,64646L,64647L,64648L,64649L,64650L,64651L,64652L,64653L,64654L,\n64655L,64656L,64657L,64658L,64659L,64660L,64661L,64662L,64663L,64664L,\n64665L,64666L,64667L,64668L,64669L,64670L,64671L,64672L,64673L,64674L,\n64675L,64676L,64677L,64678L,64679L,64680L,64681L,64682L,64683L,64684L,\n64685L,64686L,64687L,64688L,64689L,64690L,64691L,64692L,64693L,64694L,\n64695L,64696L,64697L,64698L,64699L,64700L,64701L,64702L,64703L,64704L,\n64705L,64706L,64707L,64708L,64709L,64710L,64711L,64712L,64713L,64714L,\n64715L,64716L,64717L,64718L,64719L,64720L,64721L,64722L,64723L,64724L,\n64725L,64726L,64727L,64728L,64729L,64730L,64731L,64732L,64733L,64734L,\n64735L,64736L,64737L,64738L,64739L,64740L,64741L,64742L,64743L,64744L,\n64745L,64746L,64747L,64748L,64749L,64750L,64751L,64752L,64753L,64754L,\n64755L,64756L,64757L,64758L,64759L,64760L,64761L,64762L,64763L,64764L,\n64765L,64766L,64767L,64768L,64769L,64770L,64771L,64772L,64773L,64774L,\n64775L,64776L,64777L,64778L,64779L,64780L,64781L,64782L,64783L,64784L,\n64785L,64786L,64787L,64788L,64789L,64790L,64791L,64792L,64793L,64794L,\n64795L,64796L,64797L,64798L,64799L,64800L,64801L,64802L,64803L,64804L,\n64805L,64806L,64807L,64808L,64809L,64810L,64811L,64812L,64813L,64814L,\n64815L,64816L,64817L,64818L,64819L,64820L,64821L,64822L,64823L,64824L,\n64825L,64826L,64827L,64828L,64829L,64830L,64831L,64832L,64833L,64834L,\n64835L,64836L,64837L,64838L,64839L,64840L,64841L,64842L,64843L,64844L,\n64845L,64846L,64847L,64848L,64849L,64850L,64851L,64852L,64853L,64854L,\n64855L,64856L,64857L,64858L,64859L,64860L,64861L,64862L,64863L,64864L,\n64865L,64866L,64867L,64868L,64869L,64870L,64871L,64872L,64873L,64874L,\n64875L,64876L,64877L,64878L,64879L,64880L,64881L,64882L,64883L,64884L,\n64885L,64886L,64887L,64888L,64889L,64890L,64891L,64892L,64893L,64894L,\n64895L,64896L,64897L,64898L,64899L,64900L,64901L,64902L,64903L,64904L,\n64905L,64906L,64907L,64908L,64909L,64910L,64911L,64912L,64913L,64914L,\n64915L,64916L,64917L,64918L,64919L,64920L,64921L,64922L,64923L,64924L,\n64925L,64926L,64927L,64928L,64929L,64930L,64931L,64932L,64933L,64934L,\n64935L,64936L,64937L,64938L,64939L,64940L,64941L,64942L,64943L,64944L,\n64945L,64946L,64947L,64948L,64949L,64950L,64951L,64952L,64953L,64954L,\n64955L,64956L,64957L,64958L,64959L,64960L,64961L,64962L,64963L,64964L,\n64965L,64966L,64967L,64968L,64969L,64970L,64971L,64972L,64973L,64974L,\n64975L,64976L,64977L,64978L,64979L,64980L,64981L,64982L,64983L,64984L,\n64985L,64986L,64987L,64988L,64989L,64990L,64991L,64992L,64993L,64994L,\n64995L,64996L,64997L,64998L,64999L,65000L,65001L,65002L,65003L,65004L,\n65005L,65006L,65007L,65008L,65009L,65010L,65011L,65012L,65013L,65014L,\n65015L,65016L,65017L,65018L,65019L,65020L,65021L,65022L,65023L,65024L,\n65025L,65026L,65027L,65028L,65029L,65030L,65031L,65032L,65033L,65034L,\n65035L,65036L,65037L,65038L,65039L,65040L,65041L,65042L,65043L,65044L,\n65045L,65046L,65047L,65048L,65049L,65050L,65051L,65052L,65053L,65054L,\n65055L,65056L,65057L,65058L,65059L,65060L,65061L,65062L,65063L,65064L,\n65065L,65066L,65067L,65068L,65069L,65070L,65071L,65072L,65073L,65074L,\n65075L,65076L,65077L,65078L,65079L,65080L,65081L,65082L,65083L,65084L,\n65085L,65086L,65087L,65088L,65089L,65090L,65091L,65092L,65093L,65094L,\n65095L,65096L,65097L,65098L,65099L,65100L,65101L,65102L,65103L,65104L,\n65105L,65106L,65107L,65108L,65109L,65110L,65111L,65112L,65113L,65114L,\n65115L,65116L,65117L,65118L,65119L,65120L,65121L,65122L,65123L,65124L,\n65125L,65126L,65127L,65128L,65129L,65130L,65131L,65132L,65133L,65134L,\n65135L,65136L,65137L,65138L,65139L,65140L,65141L,65142L,65143L,65144L,\n65145L,65146L,65147L,65148L,65149L,65150L,65151L,65152L,65153L,65154L,\n65155L,65156L,65157L,65158L,65159L,65160L,65161L,65162L,65163L,65164L,\n65165L,65166L,65167L,65168L,65169L,65170L,65171L,65172L,65173L,65174L,\n65175L,65176L,65177L,65178L,65179L,65180L,65181L,65182L,65183L,65184L,\n65185L,65186L,65187L,65188L,65189L,65190L,65191L,65192L,65193L,65194L,\n65195L,65196L,65197L,65198L,65199L,65200L,65201L,65202L,65203L,65204L,\n65205L,65206L,65207L,65208L,65209L,65210L,65211L,65212L,65213L,65214L,\n65215L,65216L,65217L,65218L,65219L,65220L,65221L,65222L,65223L,65224L,\n65225L,65226L,65227L,65228L,65229L,65230L,65231L,65232L,65233L,65234L,\n65235L,65236L,65237L,65238L,65239L,65240L,65241L,65242L,65243L,65244L,\n65245L,65246L,65247L,65248L,65249L,65250L,65251L,65252L,65253L,65254L,\n65255L,65256L,65257L,65258L,65259L,65260L,65261L,65262L,65263L,65264L,\n65265L,65266L,65267L,65268L,65269L,65270L,65271L,65272L,65273L,65274L,\n65275L,65276L,65277L,65278L,65279L,65280L,65281L,65282L,65283L,65284L,\n65285L,65286L,65287L,65288L,65289L,65290L,65291L,65292L,65293L,65294L,\n65295L,65296L,65297L,65298L,65299L,65300L,65301L,65302L,65303L,65304L,\n65305L,65306L,65307L,65308L,65309L,65310L,65311L,65312L,65313L,65314L,\n65315L,65316L,65317L,65318L,65319L,65320L,65321L,65322L,65323L,65324L,\n65325L,65326L,65327L,65328L,65329L,65330L,65331L,65332L,65333L,65334L,\n65335L,65336L,65337L,65338L,65339L,65340L,65341L,65342L,65343L,65344L,\n65313L,65314L,65315L,65316L,65317L,65318L,65319L,65320L,65321L,65322L,\n65323L,65324L,65325L,65326L,65327L,65328L,65329L,65330L,65331L,65332L,\n65333L,65334L,65335L,65336L,65337L,65338L,65371L,65372L,65373L,65374L,\n65375L,65376L,65377L,65378L,65379L,65380L,65381L,65382L,65383L,65384L,\n65385L,65386L,65387L,65388L,65389L,65390L,65391L,65392L,65393L,65394L,\n65395L,65396L,65397L,65398L,65399L,65400L,65401L,65402L,65403L,65404L,\n65405L,65406L,65407L,65408L,65409L,65410L,65411L,65412L,65413L,65414L,\n65415L,65416L,65417L,65418L,65419L,65420L,65421L,65422L,65423L,65424L,\n65425L,65426L,65427L,65428L,65429L,65430L,65431L,65432L,65433L,65434L,\n65435L,65436L,65437L,65438L,65439L,65440L,65441L,65442L,65443L,65444L,\n65445L,65446L,65447L,65448L,65449L,65450L,65451L,65452L,65453L,65454L,\n65455L,65456L,65457L,65458L,65459L,65460L,65461L,65462L,65463L,65464L,\n65465L,65466L,65467L,65468L,65469L,65470L,65471L,65472L,65473L,65474L,\n65475L,65476L,65477L,65478L,65479L,65480L,65481L,65482L,65483L,65484L,\n65485L,65486L,65487L,65488L,65489L,65490L,65491L,65492L,65493L,65494L,\n65495L,65496L,65497L,65498L,65499L,65500L,65501L,65502L,65503L,65504L,\n65505L,65506L,65507L,65508L,65509L,65510L,65511L,65512L,65513L,65514L,\n65515L,65516L,65517L,65518L,65519L,65520L,65521L,65522L,65523L,65524L,\n65525L,65526L,65527L,65528L,65529L,65530L,65531L,65532L,65533L,65534L,\n65535L,\n};\n#endif\n\n#if defined(DUK_USE_REGEXP_CANON_BITMAP)\n/*\n *  Automatically generated by extract_caseconv.py, do not edit!\n */\n\nconst duk_uint8_t duk_unicode_re_canon_bitmap[256] = {\n23,0,224,19,1,228,255,255,255,255,255,255,255,255,255,255,63,254,255,127,\n255,255,255,255,255,255,255,255,231,231,0,16,255,227,255,255,63,255,255,\n255,255,255,255,255,1,252,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n227,129,255,255,255,147,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,251,\n};\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_util.h",
    "content": "/*\n *  Utilities\n */\n\n#if !defined(DUK_UTIL_H_INCLUDED)\n#define DUK_UTIL_H_INCLUDED\n\n#if defined(DUK_USE_GET_RANDOM_DOUBLE)\n#define DUK_UTIL_GET_RANDOM_DOUBLE(thr) DUK_USE_GET_RANDOM_DOUBLE((thr)->heap_udata)\n#else\n#define DUK_UTIL_GET_RANDOM_DOUBLE(thr) duk_util_tinyrandom_get_double(thr)\n#endif\n\n/*\n *  Some useful constants\n */\n\n#define DUK_DOUBLE_2TO32     4294967296.0\n#define DUK_DOUBLE_2TO31     2147483648.0\n#define DUK_DOUBLE_LOG2E     1.4426950408889634\n#define DUK_DOUBLE_LOG10E    0.4342944819032518\n\n/*\n *  Endian conversion\n */\n\n#if defined(DUK_USE_INTEGER_LE)\n#define DUK_HTON32(x) DUK_BSWAP32((x))\n#define DUK_NTOH32(x) DUK_BSWAP32((x))\n#define DUK_HTON16(x) DUK_BSWAP16((x))\n#define DUK_NTOH16(x) DUK_BSWAP16((x))\n#elif defined(DUK_USE_INTEGER_BE)\n#define DUK_HTON32(x) (x)\n#define DUK_NTOH32(x) (x)\n#define DUK_HTON16(x) (x)\n#define DUK_NTOH16(x) (x)\n#else\n#error internal error, endianness defines broken\n#endif\n\n/*\n *  Bitstream decoder\n */\n\nstruct duk_bitdecoder_ctx {\n\tconst duk_uint8_t *data;\n\tduk_size_t offset;\n\tduk_size_t length;\n\tduk_uint32_t currval;\n\tduk_small_int_t currbits;\n};\n\n#define DUK_BD_BITPACKED_STRING_MAXLEN 256\n\n/*\n *  Bitstream encoder\n */\n\nstruct duk_bitencoder_ctx {\n\tduk_uint8_t *data;\n\tduk_size_t offset;\n\tduk_size_t length;\n\tduk_uint32_t currval;\n\tduk_small_int_t currbits;\n\tduk_small_int_t truncated;\n};\n\n/*\n *  Raw write/read macros for big endian, unaligned basic values.\n *  Caller ensures there's enough space.  The macros update the pointer\n *  argument automatically on resizes.  The idiom seems a bit odd, but\n *  leads to compact code.\n */\n\n#define DUK_RAW_WRITE_U8(ptr,val)  do { \\\n\t\t*(ptr)++ = (duk_uint8_t) (val); \\\n\t} while (0)\n#define DUK_RAW_WRITE_U16_BE(ptr,val) duk_raw_write_u16_be(&(ptr), (duk_uint16_t) (val))\n#define DUK_RAW_WRITE_U32_BE(ptr,val) duk_raw_write_u32_be(&(ptr), (duk_uint32_t) (val))\n#define DUK_RAW_WRITE_DOUBLE_BE(ptr,val) duk_raw_write_double_be(&(ptr), (duk_double_t) (val))\n#define DUK_RAW_WRITE_XUTF8(ptr,val)  do { \\\n\t\t/* 'ptr' is evaluated both as LHS and RHS. */ \\\n\t\tduk_uint8_t *duk__ptr; \\\n\t\tduk_small_int_t duk__len; \\\n\t\tduk__ptr = (duk_uint8_t *) (ptr); \\\n\t\tduk__len = duk_unicode_encode_xutf8((duk_ucodepoint_t) (val), duk__ptr); \\\n\t\tduk__ptr += duk__len; \\\n\t\t(ptr) = duk__ptr; \\\n\t} while (0)\n#define DUK_RAW_WRITE_CESU8(ptr,val)  do { \\\n\t\t/* 'ptr' is evaluated both as LHS and RHS. */ \\\n\t\tduk_uint8_t *duk__ptr; \\\n\t\tduk_small_int_t duk__len; \\\n\t\tduk__ptr = (duk_uint8_t *) (ptr); \\\n\t\tduk__len = duk_unicode_encode_cesu8((duk_ucodepoint_t) (val), duk__ptr); \\\n\t\tduk__ptr += duk__len; \\\n\t\t(ptr) = duk__ptr; \\\n\t} while (0)\n\n#define DUK_RAW_READ_U8(ptr) ((duk_uint8_t) (*(ptr)++))\n#define DUK_RAW_READ_U16_BE(ptr) duk_raw_read_u16_be(&(ptr));\n#define DUK_RAW_READ_U32_BE(ptr) duk_raw_read_u32_be(&(ptr));\n#define DUK_RAW_READ_DOUBLE_BE(ptr) duk_raw_read_double_be(&(ptr));\n\n/*\n *  Buffer writer (dynamic buffer only)\n *\n *  Helper for writing to a dynamic buffer with a concept of a \"slack\" area\n *  to reduce resizes.  You can ensure there is enough space beforehand and\n *  then write for a while without further checks, relying on a stable data\n *  pointer.  Slack handling is automatic so call sites only indicate how\n *  much data they need right now.\n *\n *  There are several ways to write using bufwriter.  The best approach\n *  depends mainly on how much performance matters over code footprint.\n *  The key issues are (1) ensuring there is space and (2) keeping the\n *  pointers consistent.  Fast code should ensure space for multiple writes\n *  with one ensure call.  Fastest inner loop code can temporarily borrow\n *  the 'p' pointer but must write it back eventually.\n *\n *  Be careful to ensure all macro arguments (other than static pointers like\n *  'thr' and 'bw_ctx') are evaluated exactly once, using temporaries if\n *  necessary (if that's not possible, there should be a note near the macro).\n *  Buffer write arguments often contain arithmetic etc so this is\n *  particularly important here.\n */\n\n/* XXX: Migrate bufwriter and other read/write helpers to its own header? */\n\nstruct duk_bufwriter_ctx {\n\tduk_uint8_t *p;\n\tduk_uint8_t *p_base;\n\tduk_uint8_t *p_limit;\n\tduk_hbuffer_dynamic *buf;\n};\n\n#if defined(DUK_USE_PREFER_SIZE)\n#define DUK_BW_SLACK_ADD           64\n#define DUK_BW_SLACK_SHIFT         4    /* 2^4 -> 1/16 = 6.25% slack */\n#else\n#define DUK_BW_SLACK_ADD           64\n#define DUK_BW_SLACK_SHIFT         2    /* 2^2 -> 1/4 = 25% slack */\n#endif\n\n/* Initialization and finalization (compaction), converting to other types. */\n\n#define DUK_BW_INIT_PUSHBUF(thr,bw_ctx,sz) do { \\\n\t\tduk_bw_init_pushbuf((thr), (bw_ctx), (sz)); \\\n\t} while (0)\n#define DUK_BW_INIT_WITHBUF(thr,bw_ctx,buf) do { \\\n\t\tduk_bw_init((thr), (bw_ctx), (buf)); \\\n\t} while (0)\n#define DUK_BW_COMPACT(thr,bw_ctx) do { \\\n\t\t/* Make underlying buffer compact to match DUK_BW_GET_SIZE(). */ \\\n\t\tduk_bw_compact((thr), (bw_ctx)); \\\n\t} while (0)\n#define DUK_BW_PUSH_AS_STRING(thr,bw_ctx) do { \\\n\t\tduk_push_lstring((thr), \\\n\t\t                 (const char *) (bw_ctx)->p_base, \\\n\t\t                 (duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base)); \\\n\t} while (0)\n\n/* Pointers may be NULL for a while when 'buf' size is zero and before any\n * ENSURE calls have been made.  Once an ENSURE has been made, the pointers\n * are required to be non-NULL so that it's always valid to use memcpy() and\n * memmove(), even for zero size.\n */\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL_DECL void duk_bw_assert_valid(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx);\n#define DUK_BW_ASSERT_VALID_EXPR(thr,bw_ctx)  (duk_bw_assert_valid((thr), (bw_ctx)))\n#define DUK_BW_ASSERT_VALID(thr,bw_ctx)  do { duk_bw_assert_valid((thr), (bw_ctx)); } while (0)\n#else\n#define DUK_BW_ASSERT_VALID_EXPR(thr,bw_ctx)  DUK_ASSERT_EXPR(1)\n#define DUK_BW_ASSERT_VALID(thr,bw_ctx)  do {} while (0)\n#endif\n\n/* Working with the pointer and current size. */\n\n#define DUK_BW_GET_PTR(thr,bw_ctx) \\\n\t((bw_ctx)->p)\n#define DUK_BW_SET_PTR(thr,bw_ctx,ptr) do { \\\n\t\t(bw_ctx)->p = (ptr); \\\n\t} while (0)\n#define DUK_BW_ADD_PTR(thr,bw_ctx,delta) do { \\\n\t\t(bw_ctx)->p += (delta); \\\n\t} while (0)\n#define DUK_BW_GET_BASEPTR(thr,bw_ctx) \\\n\t((bw_ctx)->p_base)\n#define DUK_BW_GET_LIMITPTR(thr,bw_ctx) \\\n\t((bw_ctx)->p_limit)\n#define DUK_BW_GET_SIZE(thr,bw_ctx) \\\n\t((duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base))\n#define DUK_BW_SET_SIZE(thr,bw_ctx,sz) do { \\\n\t\tDUK_ASSERT((duk_size_t) (sz) <= (duk_size_t) ((bw_ctx)->p - (bw_ctx)->p_base)); \\\n\t\t(bw_ctx)->p = (bw_ctx)->p_base + (sz); \\\n\t} while (0)\n#define DUK_BW_RESET_SIZE(thr,bw_ctx) do { \\\n\t\t/* Reset to zero size, keep current limit. */ \\\n\t\t(bw_ctx)->p = (bw_ctx)->p_base; \\\n\t} while (0)\n#define DUK_BW_GET_BUFFER(thr,bw_ctx) \\\n\t((bw_ctx)->buf)\n\n/* Ensuring (reserving) space. */\n\n#define DUK_BW_ENSURE(thr,bw_ctx,sz) do { \\\n\t\tduk_size_t duk__sz, duk__space; \\\n\t\tDUK_BW_ASSERT_VALID((thr), (bw_ctx)); \\\n\t\tduk__sz = (sz); \\\n\t\tduk__space = (duk_size_t) ((bw_ctx)->p_limit - (bw_ctx)->p); \\\n\t\tif (duk__space < duk__sz) { \\\n\t\t\t(void) duk_bw_resize((thr), (bw_ctx), duk__sz); \\\n\t\t} \\\n\t} while (0)\n/* NOTE: Multiple evaluation of 'ptr' in this macro. */\n/* XXX: Rework to use an always-inline function? */\n#define DUK_BW_ENSURE_RAW(thr,bw_ctx,sz,ptr) \\\n\t(((duk_size_t) ((bw_ctx)->p_limit - (ptr)) >= (sz)) ? \\\n\t (ptr) : \\\n\t ((bw_ctx)->p = (ptr), duk_bw_resize((thr),(bw_ctx),(sz))))\n#define DUK_BW_ENSURE_GETPTR(thr,bw_ctx,sz) \\\n\tDUK_BW_ENSURE_RAW((thr), (bw_ctx), (sz), (bw_ctx)->p)\n#define DUK_BW_ASSERT_SPACE_EXPR(thr,bw_ctx,sz) \\\n\t(DUK_BW_ASSERT_VALID_EXPR((thr), (bw_ctx)), \\\n\t DUK_ASSERT_EXPR((duk_size_t) ((bw_ctx)->p_limit - (bw_ctx)->p) >= (duk_size_t) (sz)))\n#define DUK_BW_ASSERT_SPACE(thr,bw_ctx,sz) do { \\\n\t\tDUK_BW_ASSERT_SPACE_EXPR((thr), (bw_ctx), (sz)); \\\n\t} while (0)\n\n/* Miscellaneous. */\n\n#define DUK_BW_SETPTR_AND_COMPACT(thr,bw_ctx,ptr) do { \\\n\t\t(bw_ctx)->p = (ptr); \\\n\t\tduk_bw_compact((thr), (bw_ctx)); \\\n\t} while (0)\n\n/* Fast write calls which assume you control the slack beforehand.\n * Multibyte write variants exist and use a temporary write pointer\n * because byte writes alias with anything: with a stored pointer\n * explicit pointer load/stores get generated (e.g. gcc -Os).\n */\n\n#define DUK_BW_WRITE_RAW_U8(thr,bw_ctx,val) do { \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 1); \\\n\t\t*(bw_ctx)->p++ = (duk_uint8_t) (val); \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_2(thr,bw_ctx,val1,val2) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 2); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_3(thr,bw_ctx,val1,val2,val3) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 3); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_4(thr,bw_ctx,val1,val2,val3,val4) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 4); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t*duk__p++ = (duk_uint8_t) (val4); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_5(thr,bw_ctx,val1,val2,val3,val4,val5) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 5); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t*duk__p++ = (duk_uint8_t) (val4); \\\n\t\t*duk__p++ = (duk_uint8_t) (val5); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_U8_6(thr,bw_ctx,val1,val2,val3,val4,val5,val6) do { \\\n\t\tduk_uint8_t *duk__p; \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), 6); \\\n\t\tduk__p = (bw_ctx)->p; \\\n\t\t*duk__p++ = (duk_uint8_t) (val1); \\\n\t\t*duk__p++ = (duk_uint8_t) (val2); \\\n\t\t*duk__p++ = (duk_uint8_t) (val3); \\\n\t\t*duk__p++ = (duk_uint8_t) (val4); \\\n\t\t*duk__p++ = (duk_uint8_t) (val5); \\\n\t\t*duk__p++ = (duk_uint8_t) (val6); \\\n\t\t(bw_ctx)->p = duk__p; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_XUTF8(thr,bw_ctx,cp) do { \\\n\t\tduk_ucodepoint_t duk__cp; \\\n\t\tduk_small_int_t duk__enc_len; \\\n\t\tduk__cp = (duk_ucodepoint_t) (cp); \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), duk_unicode_get_xutf8_length(duk__cp)); \\\n\t\tduk__enc_len = duk_unicode_encode_xutf8(duk__cp, (bw_ctx)->p); \\\n\t\t(bw_ctx)->p += duk__enc_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_CESU8(thr,bw_ctx,cp) do { \\\n\t\tduk_ucodepoint_t duk__cp; \\\n\t\tduk_small_int_t duk__enc_len; \\\n\t\tduk__cp = (duk_ucodepoint_t) (cp); \\\n\t\tDUK_BW_ASSERT_SPACE((thr), (bw_ctx), duk_unicode_get_cesu8_length(duk__cp)); \\\n\t\tduk__enc_len = duk_unicode_encode_cesu8(duk__cp, (bw_ctx)->p); \\\n\t\t(bw_ctx)->p += duk__enc_len; \\\n\t} while (0)\n/* XXX: add temporary duk__p pointer here too; sharing */\n/* XXX: avoid unsafe variants */\n#define DUK_BW_WRITE_RAW_BYTES(thr,bw_ctx,valptr,valsz) do { \\\n\t\tconst void *duk__valptr; \\\n\t\tduk_size_t duk__valsz; \\\n\t\tduk__valptr = (const void *) (valptr); \\\n\t\tduk__valsz = (duk_size_t) (valsz); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), duk__valptr, duk__valsz); \\\n\t\t(bw_ctx)->p += duk__valsz; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_CSTRING(thr,bw_ctx,val) do { \\\n\t\tconst duk_uint8_t *duk__val; \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val = (const duk_uint8_t *) (val); \\\n\t\tduk__val_len = DUK_STRLEN((const char *) duk__val); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) duk__val, duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HSTRING(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HSTRING_GET_BYTELEN((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HSTRING_GET_DATA((val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HBUFFER(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_GET_SIZE((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HBUFFER_FIXED(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_FIXED_GET_SIZE((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_FIXED_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_RAW_HBUFFER_DYNAMIC(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_DYNAMIC_GET_SIZE((val)); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n\n/* Append bytes from a slice already in the buffer. */\n#define DUK_BW_WRITE_RAW_SLICE(thr,bw,dst_off,dst_len) \\\n\tduk_bw_write_raw_slice((thr), (bw), (dst_off), (dst_len))\n\n/* Insert bytes in the middle of the buffer from an external buffer. */\n#define DUK_BW_INSERT_RAW_BYTES(thr,bw,dst_off,buf,len) \\\n\tduk_bw_insert_raw_bytes((thr), (bw), (dst_off), (buf), (len))\n\n/* Insert bytes in the middle of the buffer from a slice already\n * in the buffer.  Source offset is interpreted \"before\" the operation.\n */\n#define DUK_BW_INSERT_RAW_SLICE(thr,bw,dst_off,src_off,len) \\\n\tduk_bw_insert_raw_slice((thr), (bw), (dst_off), (src_off), (len))\n\n/* Insert a reserved area somewhere in the buffer; caller fills it.\n * Evaluates to a (duk_uint_t *) pointing to the start of the reserved\n * area for convenience.\n */\n#define DUK_BW_INSERT_RAW_AREA(thr,bw,off,len) \\\n\tduk_bw_insert_raw_area((thr), (bw), (off), (len))\n\n/* Remove a slice from inside buffer. */\n#define DUK_BW_REMOVE_RAW_SLICE(thr,bw,off,len) \\\n\tduk_bw_remove_raw_slice((thr), (bw), (off), (len))\n\n/* Safe write calls which will ensure space first. */\n\n#define DUK_BW_WRITE_ENSURE_U8(thr,bw_ctx,val) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 1); \\\n\t\tDUK_BW_WRITE_RAW_U8((thr), (bw_ctx), (val)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_2(thr,bw_ctx,val1,val2) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 2); \\\n\t\tDUK_BW_WRITE_RAW_U8_2((thr), (bw_ctx), (val1), (val2)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_3(thr,bw_ctx,val1,val2,val3) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 3); \\\n\t\tDUK_BW_WRITE_RAW_U8_3((thr), (bw_ctx), (val1), (val2), (val3)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_4(thr,bw_ctx,val1,val2,val3,val4) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 4); \\\n\t\tDUK_BW_WRITE_RAW_U8_4((thr), (bw_ctx), (val1), (val2), (val3), (val4)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_5(thr,bw_ctx,val1,val2,val3,val4,val5) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 5); \\\n\t\tDUK_BW_WRITE_RAW_U8_5((thr), (bw_ctx), (val1), (val2), (val3), (val4), (val5)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_U8_6(thr,bw_ctx,val1,val2,val3,val4,val5,val6) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), 6); \\\n\t\tDUK_BW_WRITE_RAW_U8_6((thr), (bw_ctx), (val1), (val2), (val3), (val4), (val5), (val6)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_XUTF8(thr,bw_ctx,cp) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), DUK_UNICODE_MAX_XUTF8_LENGTH); \\\n\t\tDUK_BW_WRITE_RAW_XUTF8((thr), (bw_ctx), (cp)); \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_CESU8(thr,bw_ctx,cp) do { \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), DUK_UNICODE_MAX_CESU8_LENGTH); \\\n\t\tDUK_BW_WRITE_RAW_CESU8((thr), (bw_ctx), (cp)); \\\n\t} while (0)\n/* XXX: add temporary duk__p pointer here too; sharing */\n/* XXX: avoid unsafe */\n#define DUK_BW_WRITE_ENSURE_BYTES(thr,bw_ctx,valptr,valsz) do { \\\n\t\tconst void *duk__valptr; \\\n\t\tduk_size_t duk__valsz; \\\n\t\tduk__valptr = (const void *) (valptr); \\\n\t\tduk__valsz = (duk_size_t) (valsz); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__valsz); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), duk__valptr, duk__valsz); \\\n\t\t(bw_ctx)->p += duk__valsz; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_CSTRING(thr,bw_ctx,val) do { \\\n\t\tconst duk_uint8_t *duk__val; \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val = (const duk_uint8_t *) (val); \\\n\t\tduk__val_len = DUK_STRLEN((const char *) duk__val); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) duk__val, duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HSTRING(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HSTRING_GET_BYTELEN((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HSTRING_GET_DATA((val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HBUFFER(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_GET_SIZE((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HBUFFER_FIXED(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_FIXED_GET_SIZE((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_FIXED_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n#define DUK_BW_WRITE_ENSURE_HBUFFER_DYNAMIC(thr,bw_ctx,val) do { \\\n\t\tduk_size_t duk__val_len; \\\n\t\tduk__val_len = DUK_HBUFFER_DYNAMIC_GET_SIZE((val)); \\\n\t\tDUK_BW_ENSURE((thr), (bw_ctx), duk__val_len); \\\n\t\tduk_memcpy_unsafe((void *) ((bw_ctx)->p), (const void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR((thr)->heap, (val)), duk__val_len); \\\n\t\t(bw_ctx)->p += duk__val_len; \\\n\t} while (0)\n\n#define DUK_BW_WRITE_ENSURE_SLICE(thr,bw,dst_off,dst_len) \\\n\tduk_bw_write_ensure_slice((thr), (bw), (dst_off), (dst_len))\n#define DUK_BW_INSERT_ENSURE_BYTES(thr,bw,dst_off,buf,len) \\\n\tduk_bw_insert_ensure_bytes((thr), (bw), (dst_off), (buf), (len))\n#define DUK_BW_INSERT_ENSURE_SLICE(thr,bw,dst_off,src_off,len) \\\n\tduk_bw_insert_ensure_slice((thr), (bw), (dst_off), (src_off), (len))\n#define DUK_BW_INSERT_ENSURE_AREA(thr,bw,off,len) \\\n\t/* Evaluates to (duk_uint8_t *) pointing to start of area. */ \\\n\tduk_bw_insert_ensure_area((thr), (bw), (off), (len))\n#define DUK_BW_REMOVE_ENSURE_SLICE(thr,bw,off,len) \\\n\t/* No difference between raw/ensure because the buffer shrinks. */ \\\n\tDUK_BW_REMOVE_RAW_SLICE((thr), (bw), (off), (len))\n\n/*\n *  Externs and prototypes\n */\n\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL const duk_uint8_t duk_lc_digits[36];\nDUK_INTERNAL_DECL const duk_uint8_t duk_uc_nybbles[16];\nDUK_INTERNAL_DECL const duk_int8_t duk_hex_dectab[256];\n#if defined(DUK_USE_HEX_FASTPATH)\nDUK_INTERNAL_DECL const duk_int16_t duk_hex_dectab_shift4[256];\nDUK_INTERNAL_DECL const duk_uint16_t duk_hex_enctab[256];\n#endif\n#endif  /* !DUK_SINGLE_FILE */\n\n/* Note: assumes that duk_util_probe_steps size is 32 */\n#if defined(DUK_USE_HOBJECT_HASH_PART)\n#if !defined(DUK_SINGLE_FILE)\nDUK_INTERNAL_DECL duk_uint8_t duk_util_probe_steps[32];\n#endif  /* !DUK_SINGLE_FILE */\n#endif\n\n#if defined(DUK_USE_STRHASH_DENSE)\nDUK_INTERNAL_DECL duk_uint32_t duk_util_hashbytes(const duk_uint8_t *data, duk_size_t len, duk_uint32_t seed);\n#endif\n\nDUK_INTERNAL_DECL duk_uint32_t duk_bd_decode(duk_bitdecoder_ctx *ctx, duk_small_int_t bits);\nDUK_INTERNAL_DECL duk_small_uint_t duk_bd_decode_flag(duk_bitdecoder_ctx *ctx);\nDUK_INTERNAL_DECL duk_uint32_t duk_bd_decode_flagged(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_uint32_t def_value);\nDUK_INTERNAL_DECL duk_int32_t duk_bd_decode_flagged_signed(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_int32_t def_value);\nDUK_INTERNAL_DECL duk_uint32_t duk_bd_decode_varuint(duk_bitdecoder_ctx *ctx);\nDUK_INTERNAL_DECL duk_small_uint_t duk_bd_decode_bitpacked_string(duk_bitdecoder_ctx *bd, duk_uint8_t *out);\n\nDUK_INTERNAL_DECL void duk_be_encode(duk_bitencoder_ctx *ctx, duk_uint32_t data, duk_small_int_t bits);\nDUK_INTERNAL_DECL void duk_be_finish(duk_bitencoder_ctx *ctx);\n\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\nDUK_INTERNAL_DECL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr);\nDUK_INTERNAL_DECL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr);\n#endif\n\nDUK_INTERNAL_DECL void duk_bw_init(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_hbuffer_dynamic *h_buf);\nDUK_INTERNAL_DECL void duk_bw_init_pushbuf(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t buf_size);\nDUK_INTERNAL_DECL duk_uint8_t *duk_bw_resize(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t sz);\nDUK_INTERNAL_DECL void duk_bw_compact(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx);\nDUK_INTERNAL_DECL void duk_bw_write_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_write_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_raw_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_ensure_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_insert_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len);\nDUK_INTERNAL_DECL duk_uint8_t *duk_bw_insert_raw_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len);\nDUK_INTERNAL_DECL duk_uint8_t *duk_bw_insert_ensure_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len);\nDUK_INTERNAL_DECL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len);\n/* No duk_bw_remove_ensure_slice(), functionality would be identical. */\n\nDUK_INTERNAL_DECL duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p);\nDUK_INTERNAL_DECL duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p);\nDUK_INTERNAL_DECL duk_double_t duk_raw_read_double_be(duk_uint8_t **p);\nDUK_INTERNAL_DECL void duk_raw_write_u16_be(duk_uint8_t **p, duk_uint16_t val);\nDUK_INTERNAL_DECL void duk_raw_write_u32_be(duk_uint8_t **p, duk_uint32_t val);\nDUK_INTERNAL_DECL void duk_raw_write_double_be(duk_uint8_t **p, duk_double_t val);\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* For now only needed by the debugger. */\nDUK_INTERNAL_DECL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len);\n#endif\n\n/* memcpy(), memmove() etc wrappers.  The plain variants like duk_memcpy()\n * assume C99+ and 'src' and 'dst' pointers must be non-NULL even when the\n * operation size is zero.  The unsafe variants like duk_memcpy_safe() deal\n * with the zero size case explicitly, and allow NULL pointers in that case\n * (which is undefined behavior in C99+).  For the majority of actual targets\n * a NULL pointer with a zero length is fine in practice.  These wrappers are\n * macros to force inlining; because there are hundreds of call sites, even a\n * few extra bytes per call site adds up to ~1kB footprint.\n */\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n#define duk_memcpy(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memcpy_unsafe(dst,src,len)  duk_memcpy((dst), (src), (len))\n#define duk_memmove(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memmove_unsafe(dst,src,len)  duk_memmove((dst), (src), (len))\n#define duk_memset(dst,val,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_small_int_t duk__val = (val); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memset_unsafe(dst,val,len)  duk_memset((dst), (val), (len))\n#define duk_memzero(dst,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\t(void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memzero_unsafe(dst,len)  duk_memzero((dst), (len))\n#else  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\n#define duk_memcpy(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t(void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memcpy_unsafe(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t\t(void) DUK_MEMCPY(duk__dst, duk__src, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#define duk_memmove(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t(void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memmove_unsafe(dst,src,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tconst void *duk__src = (src); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tDUK_ASSERT(duk__src != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\tDUK_ASSERT(duk__src != NULL); \\\n\t\t\t(void) DUK_MEMMOVE(duk__dst, duk__src, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#define duk_memset(dst,val,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_small_int_t duk__val = (val); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t(void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memset_unsafe(dst,val,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_small_int_t duk__val = (val); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\t(void) DUK_MEMSET(duk__dst, duk__val, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#define duk_memzero(dst,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t(void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \\\n\t} while (0)\n#define duk_memzero_unsafe(dst,len)  do { \\\n\t\tvoid *duk__dst = (dst); \\\n\t\tduk_size_t duk__len = (len); \\\n\t\tDUK_ASSERT(duk__dst != NULL || duk__len == 0U); \\\n\t\tif (DUK_LIKELY(duk__len > 0U)) { \\\n\t\t\tDUK_ASSERT(duk__dst != NULL); \\\n\t\t\t(void) DUK_MEMZERO(duk__dst, (size_t) duk__len); \\\n\t\t} \\\n\t} while (0)\n#endif  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\n\nDUK_INTERNAL_DECL duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len);\nDUK_INTERNAL_DECL duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len);\n\nDUK_INTERNAL_DECL duk_bool_t duk_is_whole_get_int32_nonegzero(duk_double_t x, duk_int32_t *ival);\nDUK_INTERNAL_DECL duk_bool_t duk_is_whole_get_int32(duk_double_t x, duk_int32_t *ival);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_anyinf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_posinf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_neginf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_or_zero(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_or_inf(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_nan_zero_inf(duk_double_t x);\nDUK_INTERNAL_DECL duk_small_uint_t duk_double_signbit(duk_double_t x);\nDUK_INTERNAL_DECL duk_double_t duk_double_trunc_towards_zero(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_same_sign(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_double_t duk_double_fmin(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_finite(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_integer(duk_double_t x);\nDUK_INTERNAL_DECL duk_bool_t duk_double_is_safe_integer(duk_double_t x);\n\nDUK_INTERNAL_DECL duk_double_t duk_double_div(duk_double_t x, duk_double_t y);\nDUK_INTERNAL_DECL duk_int_t duk_double_to_int_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_uint_t duk_double_to_uint_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_int32_t duk_double_to_int32_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_uint32_t duk_double_to_uint32_t(duk_double_t x);\nDUK_INTERNAL_DECL duk_float_t duk_double_to_float_t(duk_double_t x);\n\n/*\n *  Miscellaneous\n */\n\n/* Example: x     = 0x10 = 0b00010000\n *          x - 1 = 0x0f = 0b00001111\n *          x & (x - 1) == 0\n *\n *          x     = 0x07 = 0b00000111\n *          x - 1 = 0x06 = 0b00000110\n *          x & (x - 1) != 0\n *\n * However, incorrectly true for x == 0 so check for that explicitly.\n */\n#define DUK_IS_POWER_OF_TWO(x) \\\n\t((x) != 0U && ((x) & ((x) - 1U)) == 0U)\n\n#endif  /* DUK_UTIL_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_util_bitdecoder.c",
    "content": "/*\n *  Bitstream decoder.\n */\n\n#include \"duk_internal.h\"\n\n/* Decode 'bits' bits from the input stream (bits must be 1...24).\n * When reading past bitstream end, zeroes are shifted in.  The result\n * is signed to match duk_bd_decode_flagged.\n */\nDUK_INTERNAL duk_uint32_t duk_bd_decode(duk_bitdecoder_ctx *ctx, duk_small_int_t bits) {\n\tduk_small_int_t shift;\n\tduk_uint32_t mask;\n\tduk_uint32_t tmp;\n\n\t/* Note: cannot read more than 24 bits without possibly shifting top bits out.\n\t * Fixable, but adds complexity.\n\t */\n\tDUK_ASSERT(bits >= 1 && bits <= 24);\n\n\twhile (ctx->currbits < bits) {\n#if 0\n\t\tDUK_DDD(DUK_DDDPRINT(\"decode_bits: shift more data (bits=%ld, currbits=%ld)\",\n\t\t                     (long) bits, (long) ctx->currbits));\n#endif\n\t\tctx->currval <<= 8;\n\t\tif (ctx->offset < ctx->length) {\n\t\t\t/* If ctx->offset >= ctx->length, we \"shift zeroes in\"\n\t\t\t * instead of croaking.\n\t\t\t */\n\t\t\tctx->currval |= ctx->data[ctx->offset++];\n\t\t}\n\t\tctx->currbits += 8;\n\t}\n#if 0\n\tDUK_DDD(DUK_DDDPRINT(\"decode_bits: bits=%ld, currbits=%ld, currval=0x%08lx\",\n\t                     (long) bits, (long) ctx->currbits, (unsigned long) ctx->currval));\n#endif\n\n\t/* Extract 'top' bits of currval; note that the extracted bits do not need\n\t * to be cleared, we just ignore them on next round.\n\t */\n\tshift = ctx->currbits - bits;\n\tmask = (((duk_uint32_t) 1U) << bits) - 1U;\n\ttmp = (ctx->currval >> shift) & mask;\n\tctx->currbits = shift;  /* remaining */\n\n#if 0\n\tDUK_DDD(DUK_DDDPRINT(\"decode_bits: %ld bits -> 0x%08lx (%ld), currbits=%ld, currval=0x%08lx\",\n\t                     (long) bits, (unsigned long) tmp, (long) tmp, (long) ctx->currbits, (unsigned long) ctx->currval));\n#endif\n\n\treturn tmp;\n}\n\nDUK_INTERNAL duk_small_uint_t duk_bd_decode_flag(duk_bitdecoder_ctx *ctx) {\n\treturn (duk_small_uint_t) duk_bd_decode(ctx, 1);\n}\n\n/* Decode a one-bit flag, and if set, decode a value of 'bits', otherwise return\n * default value.\n */\nDUK_INTERNAL duk_uint32_t duk_bd_decode_flagged(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_uint32_t def_value) {\n\tif (duk_bd_decode_flag(ctx)) {\n\t\treturn duk_bd_decode(ctx, bits);\n\t} else {\n\t\treturn def_value;\n\t}\n}\n\n/* Signed variant, allows negative marker value. */\nDUK_INTERNAL duk_int32_t duk_bd_decode_flagged_signed(duk_bitdecoder_ctx *ctx, duk_small_int_t bits, duk_int32_t def_value) {\n\treturn (duk_int32_t) duk_bd_decode_flagged(ctx, bits, (duk_uint32_t) def_value);\n}\n\n/* Shared varint encoding.  Match dukutil.py BitEncode.varuint(). */\nDUK_INTERNAL duk_uint32_t duk_bd_decode_varuint(duk_bitdecoder_ctx *ctx) {\n\tduk_small_uint_t t;\n\n\t/* The bit encoding choices here are based on manual testing against\n\t * the actual varuints generated by genbuiltins.py.\n\t */\n\tswitch (duk_bd_decode(ctx, 2)) {\n\tcase 0:\n\t\treturn 0;  /* [0,0] */\n\tcase 1:\n\t\treturn duk_bd_decode(ctx, 2) + 1;  /* [1,4] */\n\tcase 2:\n\t\treturn duk_bd_decode(ctx, 5) + 5;  /* [5,36] */\n\tdefault:\n\t\tt = duk_bd_decode(ctx, 7);\n\t\tif (t == 0) {\n\t\t\treturn duk_bd_decode(ctx, 20);\n\t\t}\n\t\treturn (t - 1) + 37;  /* [37,163] */\n\t}\n}\n\n/* Decode a bit packed string from a custom format used by genbuiltins.py.\n * This function is here because it's used for both heap and thread inits.\n * Caller must supply the output buffer whose size is NOT checked!\n */\n\n#define DUK__BITPACK_LETTER_LIMIT  26\n#define DUK__BITPACK_LOOKUP1       26\n#define DUK__BITPACK_LOOKUP2       27\n#define DUK__BITPACK_SWITCH1       28\n#define DUK__BITPACK_SWITCH        29\n#define DUK__BITPACK_UNUSED1       30\n#define DUK__BITPACK_EIGHTBIT      31\n\nDUK_LOCAL const duk_uint8_t duk__bitpacked_lookup[16] = {\n\tDUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3,\n\tDUK_ASC_4, DUK_ASC_5, DUK_ASC_6, DUK_ASC_7,\n\tDUK_ASC_8, DUK_ASC_9, DUK_ASC_UNDERSCORE, DUK_ASC_SPACE,\n\t0x82, 0x80, DUK_ASC_DOUBLEQUOTE, DUK_ASC_LCURLY\n};\n\nDUK_INTERNAL duk_small_uint_t duk_bd_decode_bitpacked_string(duk_bitdecoder_ctx *bd, duk_uint8_t *out) {\n\tduk_small_uint_t len;\n\tduk_small_uint_t mode;\n\tduk_small_uint_t t;\n\tduk_small_uint_t i;\n\n\tlen = duk_bd_decode(bd, 5);\n\tif (len == 31) {\n\t\tlen = duk_bd_decode(bd, 8);  /* Support up to 256 bytes; rare. */\n\t}\n\n\tmode = 32;  /* 0 = uppercase, 32 = lowercase (= 'a' - 'A') */\n\tfor (i = 0; i < len; i++) {\n\t\tt = duk_bd_decode(bd, 5);\n\t\tif (t < DUK__BITPACK_LETTER_LIMIT) {\n\t\t\tt = t + DUK_ASC_UC_A + mode;\n\t\t} else if (t == DUK__BITPACK_LOOKUP1) {\n\t\t\tt = duk__bitpacked_lookup[duk_bd_decode(bd, 3)];\n\t\t} else if (t == DUK__BITPACK_LOOKUP2) {\n\t\t\tt = duk__bitpacked_lookup[8 + duk_bd_decode(bd, 3)];\n\t\t} else if (t == DUK__BITPACK_SWITCH1) {\n\t\t\tt = duk_bd_decode(bd, 5);\n\t\t\tDUK_ASSERT_DISABLE(t >= 0);  /* unsigned */\n\t\t\tDUK_ASSERT(t <= 25);\n\t\t\tt = t + DUK_ASC_UC_A + (mode ^ 32);\n\t\t} else if (t == DUK__BITPACK_SWITCH) {\n\t\t\tmode = mode ^ 32;\n\t\t\tt = duk_bd_decode(bd, 5);\n\t\t\tDUK_ASSERT_DISABLE(t >= 0);\n\t\t\tDUK_ASSERT(t <= 25);\n\t\t\tt = t + DUK_ASC_UC_A + mode;\n\t\t} else if (t == DUK__BITPACK_EIGHTBIT) {\n\t\t\tt = duk_bd_decode(bd, 8);\n\t\t}\n\t\tout[i] = (duk_uint8_t) t;\n\t}\n\n\treturn len;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_util_bitencoder.c",
    "content": "/*\n *  Bitstream encoder.\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL void duk_be_encode(duk_bitencoder_ctx *ctx, duk_uint32_t data, duk_small_int_t bits) {\n\tduk_uint8_t tmp;\n\n\tDUK_ASSERT(ctx != NULL);\n\tDUK_ASSERT(ctx->currbits < 8);\n\n\t/* This limitation would be fixable but adds unnecessary complexity. */\n\tDUK_ASSERT(bits >= 1 && bits <= 24);\n\n\tctx->currval = (ctx->currval << bits) | data;\n\tctx->currbits += bits;\n\n\twhile (ctx->currbits >= 8) {\n\t\tif (ctx->offset < ctx->length) {\n\t\t\ttmp = (duk_uint8_t) ((ctx->currval >> (ctx->currbits - 8)) & 0xff);\n\t\t\tctx->data[ctx->offset++] = tmp;\n\t\t} else {\n\t\t\t/* If buffer has been exhausted, truncate bitstream */\n\t\t\tctx->truncated = 1;\n\t\t}\n\n\t\tctx->currbits -= 8;\n\t}\n}\n\nDUK_INTERNAL void duk_be_finish(duk_bitencoder_ctx *ctx) {\n\tduk_small_int_t npad;\n\n\tDUK_ASSERT(ctx != NULL);\n\tDUK_ASSERT(ctx->currbits < 8);\n\n\tnpad = (duk_small_int_t) (8 - ctx->currbits);\n\tif (npad > 0) {\n\t\tduk_be_encode(ctx, 0, npad);\n\t}\n\tDUK_ASSERT(ctx->currbits == 0);\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_util_bufwriter.c",
    "content": "/*\n *  Fast buffer writer with slack management.\n */\n\n#include \"duk_internal.h\"\n\n/* XXX: Avoid duk_{memcmp,memmove}_unsafe() by imposing a minimum length of\n * >0 for the underlying dynamic buffer.\n */\n\n/*\n *  Macro support functions (use only macros in calling code)\n */\n\nDUK_LOCAL void duk__bw_update_ptrs(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t curr_offset, duk_size_t new_length) {\n\tduk_uint8_t *p;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_UNREF(thr);\n\n\t/* 'p' might be NULL when the underlying buffer is zero size.  If so,\n\t * the resulting pointers are not used unsafely.\n\t */\n\tp = (duk_uint8_t *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(thr->heap, bw_ctx->buf);\n\tDUK_ASSERT(p != NULL || (DUK_HBUFFER_DYNAMIC_GET_SIZE(bw_ctx->buf) == 0 && curr_offset == 0 && new_length == 0));\n\tbw_ctx->p = p + curr_offset;\n\tbw_ctx->p_base = p;\n\tbw_ctx->p_limit = p + new_length;\n}\n\nDUK_INTERNAL void duk_bw_init(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_hbuffer_dynamic *h_buf) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_ASSERT(h_buf != NULL);\n\n\tbw_ctx->buf = h_buf;\n\tduk__bw_update_ptrs(thr, bw_ctx, 0, DUK_HBUFFER_DYNAMIC_GET_SIZE(h_buf));\n}\n\nDUK_INTERNAL void duk_bw_init_pushbuf(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t buf_size) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\n\t(void) duk_push_dynamic_buffer(thr, buf_size);\n\tbw_ctx->buf = (duk_hbuffer_dynamic *) duk_known_hbuffer(thr, -1);\n\tDUK_ASSERT(bw_ctx->buf != NULL);\n\tduk__bw_update_ptrs(thr, bw_ctx, 0, buf_size);\n}\n\n/* Resize target buffer for requested size.  Called by the macro only when the\n * fast path test (= there is space) fails.\n */\nDUK_INTERNAL duk_uint8_t *duk_bw_resize(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx, duk_size_t sz) {\n\tduk_size_t curr_off;\n\tduk_size_t add_sz;\n\tduk_size_t new_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\n\t/* We could do this operation without caller updating bw_ctx->ptr,\n\t * but by writing it back here we can share code better.\n\t */\n\n\tcurr_off = (duk_size_t) (bw_ctx->p - bw_ctx->p_base);\n\tadd_sz = (curr_off >> DUK_BW_SLACK_SHIFT) + DUK_BW_SLACK_ADD;\n\tnew_sz = curr_off + sz + add_sz;\n\tif (DUK_UNLIKELY(new_sz < curr_off)) {\n\t\t/* overflow */\n\t\tDUK_ERROR_RANGE(thr, DUK_STR_BUFFER_TOO_LONG);\n\t\tDUK_WO_NORETURN(return NULL;);\n\t}\n#if 0  /* for manual torture testing: tight allocation, useful with valgrind */\n\tnew_sz = curr_off + sz;\n#endif\n\n\t/* This is important to ensure dynamic buffer data pointer is not\n\t * NULL (which is possible if buffer size is zero), which in turn\n\t * causes portability issues with e.g. memmove() and memcpy().\n\t */\n\tDUK_ASSERT(new_sz >= 1);\n\n\tDUK_DD(DUK_DDPRINT(\"resize bufferwriter from %ld to %ld (add_sz=%ld)\", (long) curr_off, (long) new_sz, (long) add_sz));\n\n\tduk_hbuffer_resize(thr, bw_ctx->buf, new_sz);\n\tduk__bw_update_ptrs(thr, bw_ctx, curr_off, new_sz);\n\treturn bw_ctx->p;\n}\n\n/* Make buffer compact, matching current written size. */\nDUK_INTERNAL void duk_bw_compact(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx) {\n\tduk_size_t len;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_UNREF(thr);\n\n\tlen = (duk_size_t) (bw_ctx->p - bw_ctx->p_base);\n\tduk_hbuffer_resize(thr, bw_ctx->buf, len);\n\tduk__bw_update_ptrs(thr, bw_ctx, len, len);\n}\n\nDUK_INTERNAL void duk_bw_write_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len) {\n\tduk_uint8_t *p_base;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tduk_memcpy_unsafe((void *) bw->p,\n\t                  (const void *) (p_base + src_off),\n\t                  (size_t) len);\n\tbw->p += len;\n}\n\nDUK_INTERNAL void duk_bw_write_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t src_off, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\tduk_bw_write_raw_slice(thr, bw, src_off, len);\n}\n\nDUK_INTERNAL void duk_bw_insert_raw_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len) {\n\tduk_uint8_t *p_base;\n\tduk_size_t buf_sz, move_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(buf != NULL);\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tbuf_sz = (duk_size_t) (bw->p - p_base);  /* constrained by maximum buffer size */\n\tmove_sz = buf_sz - dst_off;\n\n\tDUK_ASSERT(p_base != NULL);  /* buffer size is >= 1 */\n\tduk_memmove_unsafe((void *) (p_base + dst_off + len),\n\t                   (const void *) (p_base + dst_off),\n\t                   (size_t) move_sz);\n\tduk_memcpy_unsafe((void *) (p_base + dst_off),\n\t                  (const void *) buf,\n\t                  (size_t) len);\n\tbw->p += len;\n}\n\nDUK_INTERNAL void duk_bw_insert_ensure_bytes(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, const duk_uint8_t *buf, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(buf != NULL);\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\tduk_bw_insert_raw_bytes(thr, bw, dst_off, buf, len);\n}\n\nDUK_INTERNAL void duk_bw_insert_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len) {\n\tduk_uint8_t *p_base;\n\tduk_size_t buf_sz, move_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\n\t/* Don't support \"straddled\" source now. */\n\tDUK_ASSERT(dst_off <= src_off || dst_off >= src_off + len);\n\n\tif (dst_off <= src_off) {\n\t\t/* Target is before source.  Source offset is expressed as\n\t\t * a \"before change\" offset.  Account for the memmove.\n\t\t */\n\t\tsrc_off += len;\n\t}\n\n\tbuf_sz = (duk_size_t) (bw->p - p_base);\n\tmove_sz = buf_sz - dst_off;\n\n\tDUK_ASSERT(p_base != NULL);  /* buffer size is >= 1 */\n\tduk_memmove_unsafe((void *) (p_base + dst_off + len),\n\t                   (const void *) (p_base + dst_off),\n\t                   (size_t) move_sz);\n\tduk_memcpy_unsafe((void *) (p_base + dst_off),\n\t                  (const void *) (p_base + src_off),\n\t                  (size_t) len);\n\tbw->p += len;\n}\n\nDUK_INTERNAL void duk_bw_insert_ensure_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t dst_off, duk_size_t src_off, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(dst_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(src_off + len <= DUK_BW_GET_SIZE(thr, bw));\n\n\t/* Don't support \"straddled\" source now. */\n\tDUK_ASSERT(dst_off <= src_off || dst_off >= src_off + len);\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\tduk_bw_insert_raw_slice(thr, bw, dst_off, src_off, len);\n}\n\nDUK_INTERNAL duk_uint8_t *duk_bw_insert_raw_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len) {\n\tduk_uint8_t *p_base, *p_dst, *p_src;\n\tduk_size_t buf_sz, move_sz;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tbuf_sz = (duk_size_t) (bw->p - p_base);\n\tmove_sz = buf_sz - off;\n\tp_dst = p_base + off + len;\n\tp_src = p_base + off;\n\tduk_memmove_unsafe((void *) p_dst, (const void *) p_src, (size_t) move_sz);\n\treturn p_src;  /* point to start of 'reserved area' */\n}\n\nDUK_INTERNAL duk_uint8_t *duk_bw_insert_ensure_area(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len) {\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw));\n\n\tDUK_BW_ENSURE(thr, bw, len);\n\treturn duk_bw_insert_raw_area(thr, bw, off, len);\n}\n\nDUK_INTERNAL void duk_bw_remove_raw_slice(duk_hthread *thr, duk_bufwriter_ctx *bw, duk_size_t off, duk_size_t len) {\n\tduk_size_t move_sz;\n\n\tduk_uint8_t *p_base;\n\tduk_uint8_t *p_src;\n\tduk_uint8_t *p_dst;\n\n\tDUK_ASSERT(thr != NULL);\n\tDUK_ASSERT(bw != NULL);\n\tDUK_ASSERT(off <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_ASSERT(off + len <= DUK_BW_GET_SIZE(thr, bw));\n\tDUK_UNREF(thr);\n\n\tp_base = bw->p_base;\n\tp_dst = p_base + off;\n\tp_src = p_dst + len;\n\tmove_sz = (duk_size_t) (bw->p - p_src);\n\tduk_memmove_unsafe((void *) p_dst,\n\t                   (const void *) p_src,\n\t                   (size_t) move_sz);\n\tbw->p -= len;\n}\n\n/*\n *  Macro support functions for reading/writing raw data.\n *\n *  These are done using mempcy to ensure they're valid even for unaligned\n *  reads/writes on platforms where alignment counts.  On x86 at least gcc\n *  is able to compile these into a bswap+mov.  \"Always inline\" is used to\n *  ensure these macros compile to minimal code.\n *\n *  Not really bufwriter related, but currently used together.\n */\n\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_uint16_t duk_raw_read_u16_be(duk_uint8_t **p) {\n\tunion {\n\t\tduk_uint8_t b[2];\n\t\tduk_uint16_t x;\n\t} u;\n\n\tduk_memcpy((void *) u.b, (const void *) (*p), (size_t) 2);\n\tu.x = DUK_NTOH16(u.x);\n\t*p += 2;\n\treturn u.x;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_uint32_t duk_raw_read_u32_be(duk_uint8_t **p) {\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tduk_memcpy((void *) u.b, (const void *) (*p), (size_t) 4);\n\tu.x = DUK_NTOH32(u.x);\n\t*p += 4;\n\treturn u.x;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE duk_double_t duk_raw_read_double_be(duk_uint8_t **p) {\n\tduk_double_union du;\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tduk_memcpy((void *) u.b, (const void *) (*p), (size_t) 4);\n\tu.x = DUK_NTOH32(u.x);\n\tdu.ui[DUK_DBL_IDX_UI0] = u.x;\n\tduk_memcpy((void *) u.b, (const void *) (*p + 4), (size_t) 4);\n\tu.x = DUK_NTOH32(u.x);\n\tdu.ui[DUK_DBL_IDX_UI1] = u.x;\n\t*p += 8;\n\n\treturn du.d;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u16_be(duk_uint8_t **p, duk_uint16_t val) {\n\tunion {\n\t\tduk_uint8_t b[2];\n\t\tduk_uint16_t x;\n\t} u;\n\n\tu.x = DUK_HTON16(val);\n\tduk_memcpy((void *) (*p), (const void *) u.b, (size_t) 2);\n\t*p += 2;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_u32_be(duk_uint8_t **p, duk_uint32_t val) {\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tu.x = DUK_HTON32(val);\n\tduk_memcpy((void *) (*p), (const void *) u.b, (size_t) 4);\n\t*p += 4;\n}\n\nDUK_INTERNAL DUK_ALWAYS_INLINE void duk_raw_write_double_be(duk_uint8_t **p, duk_double_t val) {\n\tduk_double_union du;\n\tunion {\n\t\tduk_uint8_t b[4];\n\t\tduk_uint32_t x;\n\t} u;\n\n\tdu.d = val;\n\tu.x = du.ui[DUK_DBL_IDX_UI0];\n\tu.x = DUK_HTON32(u.x);\n\tduk_memcpy((void *) (*p), (const void *) u.b, (size_t) 4);\n\tu.x = du.ui[DUK_DBL_IDX_UI1];\n\tu.x = DUK_HTON32(u.x);\n\tduk_memcpy((void *) (*p + 4), (const void *) u.b, (size_t) 4);\n\t*p += 8;\n}\n\n/*\n *  Assertion helpers\n */\n\n#if defined(DUK_USE_ASSERTIONS)\nDUK_INTERNAL void duk_bw_assert_valid(duk_hthread *thr, duk_bufwriter_ctx *bw_ctx) {\n\tDUK_UNREF(thr);\n\tDUK_ASSERT(bw_ctx != NULL);\n\tDUK_ASSERT(bw_ctx->buf != NULL);\n\tDUK_ASSERT((DUK_HBUFFER_DYNAMIC_GET_SIZE(bw_ctx->buf) == 0) ||\n\t           (bw_ctx->p != NULL &&\n\t            bw_ctx->p_base != NULL &&\n\t            bw_ctx->p_limit != NULL &&\n\t            bw_ctx->p_limit >= bw_ctx->p_base &&\n\t            bw_ctx->p >= bw_ctx->p_base &&\n\t            bw_ctx->p <= bw_ctx->p_limit));\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_util_cast.c",
    "content": "/*\n *  Cast helpers.\n *\n *  C99+ coercion is challenging portability-wise because out-of-range casts\n *  may invoke implementation defined or even undefined behavior.  See e.g.\n *  http://blog.frama-c.com/index.php?post/2013/10/09/Overflow-float-integer.\n *\n *  Provide explicit cast helpers which try to avoid implementation defined\n *  or undefined behavior.  These helpers can then be simplified in the vast\n *  majority of cases where the implementation defined or undefined behavior\n *  is not problematic.\n */\n\n#include \"duk_internal.h\"\n\n/* Portable double-to-integer cast which avoids undefined behavior and avoids\n * relying on fmin(), fmax(), or other intrinsics.  Out-of-range results are\n * not assumed by caller, but here value is clamped, NaN converts to minval.\n */\n#define DUK__DOUBLE_INT_CAST1(tname,minval,maxval)  do { \\\n\t\tif (DUK_LIKELY(x >= (duk_double_t) (minval))) { \\\n\t\t\tDUK_ASSERT(!DUK_ISNAN(x)); \\\n\t\t\tif (DUK_LIKELY(x <= (duk_double_t) (maxval))) { \\\n\t\t\t\treturn (tname) x; \\\n\t\t\t} else { \\\n\t\t\t\treturn (tname) (maxval); \\\n\t\t\t} \\\n\t\t} else { \\\n\t\t\t/* NaN or below minval.  Since we don't care about the result \\\n\t\t\t * for out-of-range values, just return the minimum value for \\\n\t\t\t * both. \\\n\t\t\t */ \\\n\t\t\treturn (tname) (minval); \\\n\t\t} \\\n\t} while (0)\n\n/* Rely on specific NaN behavior for duk_double_{fmin,fmax}(): if either\n * argument is a NaN, return the second argument.  This avoids a\n * NaN-to-integer cast which is undefined behavior.\n */\n#define DUK__DOUBLE_INT_CAST2(tname,minval,maxval)  do { \\\n\t\treturn (tname) duk_double_fmin(duk_double_fmax(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \\\n\t} while (0)\n\n/* Another solution which doesn't need C99+ behavior for fmin() and fmax(). */\n#define DUK__DOUBLE_INT_CAST3(tname,minval,maxval)  do { \\\n\t\tif (DUK_ISNAN(x)) { \\\n\t\t\t/* 0 or any other value is fine. */ \\\n\t\t\treturn (tname) 0; \\\n\t\t} else \\\n\t\t\treturn (tname) DUK_FMIN(DUK_FMAX(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \\\n\t\t} \\\n\t} while (0)\n\n/* C99+ solution: relies on specific fmin() and fmax() behavior in C99: if\n * one argument is NaN but the other isn't, the non-NaN argument is returned.\n * Because the limits are non-NaN values, explicit NaN check is not needed.\n * This may not work on all legacy platforms, and also doesn't seem to inline\n * the fmin() and fmax() calls (unless one uses -ffast-math which we don't\n * support).\n */\n#define DUK__DOUBLE_INT_CAST4(tname,minval,maxval)  do { \\\n\t\treturn (tname) DUK_FMIN(DUK_FMAX(x, (duk_double_t) (minval)), (duk_double_t) (maxval)); \\\n\t} while (0)\n\nDUK_INTERNAL duk_int_t duk_double_to_int_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\t/* Real world solution: almost any practical platform will provide\n\t * an integer value without any guarantees what it is (which is fine).\n\t */\n\treturn (duk_int_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_int_t, DUK_INT_MIN, DUK_INT_MAX);\n#endif\n}\n\nDUK_INTERNAL duk_uint_t duk_double_to_uint_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_uint_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_uint_t, DUK_UINT_MIN, DUK_UINT_MAX);\n#endif\n}\n\nDUK_INTERNAL duk_int32_t duk_double_to_int32_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_int32_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_int32_t, DUK_INT32_MIN, DUK_INT32_MAX);\n#endif\n}\n\nDUK_INTERNAL duk_uint32_t duk_double_to_uint32_t(duk_double_t x) {\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_uint32_t) x;\n#else\n\tDUK__DOUBLE_INT_CAST1(duk_uint32_t, DUK_UINT32_MIN, DUK_UINT32_MAX);\n#endif\n}\n\n/* Largest IEEE double that doesn't round to infinity in the default rounding\n * mode.  The exact midpoint between (1 - 2^(-24)) * 2^128 and 2^128 rounds to\n * infinity, at least on x64.  This number is one double unit below that\n * midpoint.  See misc/float_cast.c.\n */\n#define DUK__FLOAT_ROUND_LIMIT      340282356779733623858607532500980858880.0\n\n/* Maximum IEEE float.  Double-to-float conversion above this would be out of\n * range and thus technically undefined behavior.\n */\n#define DUK__FLOAT_MAX              340282346638528859811704183484516925440.0\n\nDUK_INTERNAL duk_float_t duk_double_to_float_t(duk_double_t x) {\n\t/* Even a double-to-float cast is technically undefined behavior if\n\t * the double is out-of-range.  C99 Section 6.3.1.5:\n\t *\n\t *   If the value being converted is in the range of values that can\n\t *   be represented but cannot be represented exactly, the result is\n\t *   either the nearest higher or nearest lower representable value,\n\t *   chosen in an implementation-defined manner.  If the value being\n\t *   converted is outside the range of values that can be represented,\n\t *   the behavior is undefined.\n\t */\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\treturn (duk_float_t) x;\n#else\n\tduk_double_t t;\n\n\tt = DUK_FABS(x);\n\tDUK_ASSERT((DUK_ISNAN(x) && DUK_ISNAN(t)) ||\n\t           (!DUK_ISNAN(x) && !DUK_ISNAN(t)));\n\n\tif (DUK_LIKELY(t <= DUK__FLOAT_MAX)) {\n\t\t/* Standard in-range case, try to get here with a minimum\n\t\t * number of checks and branches.\n\t\t */\n\t\tDUK_ASSERT(!DUK_ISNAN(x));\n\t\treturn (duk_float_t) x;\n\t} else if (t <= DUK__FLOAT_ROUND_LIMIT) {\n\t\t/* Out-of-range, but rounds to min/max float. */\n\t\tDUK_ASSERT(!DUK_ISNAN(x));\n\t\tif (x < 0.0) {\n\t\t\treturn (duk_float_t) -DUK__FLOAT_MAX;\n\t\t} else {\n\t\t\treturn (duk_float_t) DUK__FLOAT_MAX;\n\t\t}\n\t} else if (DUK_ISNAN(x)) {\n\t\t/* Assumes double NaN -> float NaN considered \"in range\". */\n\t\tDUK_ASSERT(DUK_ISNAN(x));\n\t\treturn (duk_float_t) x;\n\t} else {\n\t\t/* Out-of-range, rounds to +/- Infinity. */\n\t\tif (x < 0.0) {\n\t\t\treturn (duk_float_t) -DUK_DOUBLE_INFINITY;\n\t\t} else {\n\t\t\treturn (duk_float_t) DUK_DOUBLE_INFINITY;\n\t\t}\n\t}\n#endif\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_util_double.c",
    "content": "/*\n *  IEEE double helpers.\n */\n\n#include \"duk_internal.h\"\n\nDUK_INTERNAL duk_bool_t duk_double_is_anyinf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn DUK_DBLUNION_IS_ANYINF(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_posinf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn DUK_DBLUNION_IS_POSINF(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_neginf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn DUK_DBLUNION_IS_NEGINF(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\t/* Assumes we're dealing with a Duktape internal NaN which is\n\t * NaN normalized if duk_tval requires it.\n\t */\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\treturn DUK_DBLUNION_IS_NAN(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan_or_zero(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\t/* Assumes we're dealing with a Duktape internal NaN which is\n\t * NaN normalized if duk_tval requires it.\n\t */\n\tDUK_ASSERT(DUK_DBLUNION_IS_NORMALIZED(&du));\n\treturn DUK_DBLUNION_IS_NAN(&du) || DUK_DBLUNION_IS_ANYZERO(&du);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan_or_inf(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\t/* If exponent is 0x7FF the argument is either a NaN or an\n\t * infinity.  We don't need to check any other fields.\n\t */\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n\treturn (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000)) == DUK_U64_CONSTANT(0x000000007ff00000);\n#else\n\treturn (du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000)) == DUK_U64_CONSTANT(0x7ff0000000000000);\n#endif\n#else\n\treturn (du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL) == 0x7ff00000UL;\n#endif\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_nan_zero_inf(duk_double_t x) {\n\tduk_double_union du;\n#if defined(DUK_USE_64BIT_OPS)\n\tduk_uint64_t t;\n#else\n\tduk_uint32_t t;\n#endif\n\tdu.d = x;\n#if defined(DUK_USE_64BIT_OPS)\n#if defined(DUK_USE_DOUBLE_ME)\n\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x000000007ff00000);\n\tif (t == DUK_U64_CONSTANT(0x0000000000000000)) {\n\t\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x0000000080000000);\n\t\treturn t == 0;\n\t}\n\tif (t == DUK_U64_CONSTANT(0x000000007ff00000)) {\n\t\treturn 1;\n\t}\n#else\n\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x7ff0000000000000);\n\tif (t == DUK_U64_CONSTANT(0x0000000000000000)) {\n\t\tt = du.ull[DUK_DBL_IDX_ULL0] & DUK_U64_CONSTANT(0x8000000000000000);\n\t\treturn t == 0;\n\t}\n\tif (t == DUK_U64_CONSTANT(0x7ff0000000000000)) {\n\t\treturn 1;\n\t}\n#endif\n#else\n\tt = du.ui[DUK_DBL_IDX_UI0] & 0x7ff00000UL;\n\tif (t == 0x00000000UL) {\n\t\treturn DUK_DBLUNION_IS_ANYZERO(&du);\n\t}\n\tif (t == 0x7ff00000UL) {\n\t\treturn 1;\n\t}\n#endif\n\treturn 0;\n}\n\nDUK_INTERNAL duk_small_uint_t duk_double_signbit(duk_double_t x) {\n\tduk_double_union du;\n\tdu.d = x;\n\treturn (duk_small_uint_t) DUK_DBLUNION_GET_SIGNBIT(&du);\n}\n\nDUK_INTERNAL duk_double_t duk_double_trunc_towards_zero(duk_double_t x) {\n\t/* XXX: optimize */\n\tduk_small_uint_t s = duk_double_signbit(x);\n\tx = DUK_FLOOR(DUK_FABS(x));  /* truncate towards zero */\n\tif (s) {\n\t\tx = -x;\n\t}\n\treturn x;\n}\n\nDUK_INTERNAL duk_bool_t duk_double_same_sign(duk_double_t x, duk_double_t y) {\n\tduk_double_union du1;\n\tduk_double_union du2;\n\tdu1.d = x;\n\tdu2.d = y;\n\n\treturn (((du1.ui[DUK_DBL_IDX_UI0] ^ du2.ui[DUK_DBL_IDX_UI0]) & 0x80000000UL) == 0);\n}\n\nDUK_INTERNAL duk_double_t duk_double_fmin(duk_double_t x, duk_double_t y) {\n\t/* Doesn't replicate fmin() behavior exactly: for fmin() if one\n\t * argument is a NaN, the other argument should be returned.\n\t * Duktape doesn't rely on this behavior so the replacement can\n\t * be simplified.\n\t */\n\treturn (x < y ? x : y);\n}\n\nDUK_INTERNAL duk_double_t duk_double_fmax(duk_double_t x, duk_double_t y) {\n\t/* Doesn't replicate fmax() behavior exactly: for fmax() if one\n\t * argument is a NaN, the other argument should be returned.\n\t * Duktape doesn't rely on this behavior so the replacement can\n\t * be simplified.\n\t */\n\treturn (x > y ? x : y);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_finite(duk_double_t x) {\n\treturn !duk_double_is_nan_or_inf(x);\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_integer(duk_double_t x) {\n\tif (duk_double_is_nan_or_inf(x)) {\n\t\treturn 0;\n\t} else {\n\t\treturn duk_js_tointeger_number(x) == x;\n\t}\n}\n\nDUK_INTERNAL duk_bool_t duk_double_is_safe_integer(duk_double_t x) {\n\t/* >>> 2**53-1\n\t * 9007199254740991\n\t */\n\treturn duk_double_is_integer(x) && DUK_FABS(x) <= 9007199254740991.0;\n}\n\n/* Check whether a duk_double_t is a whole number in the 32-bit range (reject\n * negative zero), and if so, return a duk_int32_t.\n * For compiler use: don't allow negative zero as it will cause trouble with\n * LDINT+LDINTX, positive zero is OK.\n */\nDUK_INTERNAL duk_bool_t duk_is_whole_get_int32_nonegzero(duk_double_t x, duk_int32_t *ival) {\n\tduk_int32_t t;\n\n\tt = duk_double_to_int32_t(x);\n\tif (!((duk_double_t) t == x)) {\n\t\treturn 0;\n\t}\n\tif (t == 0) {\n\t\tduk_double_union du;\n\t\tdu.d = x;\n\t\tif (DUK_DBLUNION_HAS_SIGNBIT(&du)) {\n\t\t\treturn 0;\n\t\t}\n\t}\n\t*ival = t;\n\treturn 1;\n}\n\n/* Check whether a duk_double_t is a whole number in the 32-bit range, and if\n * so, return a duk_int32_t.\n */\nDUK_INTERNAL duk_bool_t duk_is_whole_get_int32(duk_double_t x, duk_int32_t *ival) {\n\tduk_int32_t t;\n\n\tt = duk_double_to_int32_t(x);\n\tif (!((duk_double_t) t == x)) {\n\t\treturn 0;\n\t}\n\t*ival = t;\n\treturn 1;\n}\n\n/* Division: division by zero is undefined behavior (and may in fact trap)\n * so it needs special handling for portability.\n */\n\nDUK_INTERNAL DUK_INLINE duk_double_t duk_double_div(duk_double_t x, duk_double_t y) {\n#if !defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\n\tif (DUK_UNLIKELY(y == 0.0)) {\n\t\t/* In C99+ division by zero is undefined behavior so\n\t\t * avoid it entirely.  Hopefully the compiler is\n\t\t * smart enough to avoid emitting any actual code\n\t\t * because almost all practical platforms behave as\n\t\t * expected.\n\t\t */\n\t\tif (x > 0.0) {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn -DUK_DOUBLE_INFINITY;\n\t\t\t} else {\n\t\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t\t}\n\t\t} else if (x < 0.0) {\n\t\t\tif (DUK_SIGNBIT(y)) {\n\t\t\t\treturn DUK_DOUBLE_INFINITY;\n\t\t\t} else {\n\t\t\t\treturn -DUK_DOUBLE_INFINITY;\n\t\t\t}\n\t\t} else {\n\t\t\t/* +/- 0, NaN */\n\t\t\treturn DUK_DOUBLE_NAN;\n\t\t}\n\t}\n#endif\n\n\treturn x / y;\n}\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_util_hashbytes.c",
    "content": "/*\n *  Hash function duk_util_hashbytes().\n *\n *  Currently, 32-bit MurmurHash2.\n *\n *  Don't rely on specific hash values; hash function may be endianness\n *  dependent, for instance.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_STRHASH_DENSE)\n/* 'magic' constants for Murmurhash2 */\n#define DUK__MAGIC_M  ((duk_uint32_t) 0x5bd1e995UL)\n#define DUK__MAGIC_R  24\n\nDUK_INTERNAL duk_uint32_t duk_util_hashbytes(const duk_uint8_t *data, duk_size_t len, duk_uint32_t seed) {\n\tduk_uint32_t h = seed ^ ((duk_uint32_t) len);\n\n\twhile (len >= 4) {\n\t\t/* Portability workaround is required for platforms without\n\t\t * unaligned access.  The replacement code emulates little\n\t\t * endian access even on big endian architectures, which is\n\t\t * OK as long as it is consistent for a build.\n\t\t */\n#if defined(DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS)\n\t\tduk_uint32_t k = *((const duk_uint32_t *) (const void *) data);\n#else\n\t\tduk_uint32_t k = ((duk_uint32_t) data[0]) |\n\t\t                 (((duk_uint32_t) data[1]) << 8) |\n\t\t                 (((duk_uint32_t) data[2]) << 16) |\n\t\t                 (((duk_uint32_t) data[3]) << 24);\n#endif\n\n\t\tk *= DUK__MAGIC_M;\n\t\tk ^= k >> DUK__MAGIC_R;\n\t\tk *= DUK__MAGIC_M;\n\t\th *= DUK__MAGIC_M;\n\t\th ^= k;\n\t\tdata += 4;\n\t\tlen -= 4;\n\t}\n\n\tswitch (len) {\n\tcase 3: h ^= data[2] << 16;\n\tcase 2: h ^= data[1] << 8;\n\tcase 1: h ^= data[0];\n\t        h *= DUK__MAGIC_M;\n        }\n\n\th ^= h >> 13;\n\th *= DUK__MAGIC_M;\n\th ^= h >> 15;\n\n\treturn h;\n}\n#endif  /* DUK_USE_STRHASH_DENSE */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_util_memory.c",
    "content": "/*\n *  Memory utils.\n */\n\n#include \"duk_internal.h\"\n\n#if defined(DUK_USE_ALLOW_UNDEFINED_BEHAVIOR)\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL || len == 0U);\n\tDUK_ASSERT(s2 != NULL || len == 0U);\n\treturn DUK_MEMCMP(s1, s2, (size_t) len);\n}\n\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL);\n\tDUK_ASSERT(s2 != NULL);\n\treturn DUK_MEMCMP(s1, s2, (size_t) len);\n}\n#else  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp_unsafe(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL || len == 0U);\n\tDUK_ASSERT(s2 != NULL || len == 0U);\n\tif (DUK_UNLIKELY(len == 0U)) {\n\t\treturn 0;\n\t}\n\tDUK_ASSERT(s1 != NULL);\n\tDUK_ASSERT(s2 != NULL);\n\treturn duk_memcmp(s1, s2, len);\n}\n\nDUK_INTERNAL DUK_INLINE duk_small_int_t duk_memcmp(const void *s1, const void *s2, duk_size_t len) {\n\tDUK_ASSERT(s1 != NULL);\n\tDUK_ASSERT(s2 != NULL);\n\treturn DUK_MEMCMP(s1, s2, (size_t) len);\n}\n#endif  /* DUK_USE_ALLOW_UNDEFINED_BEHAVIOR */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_util_misc.c",
    "content": "/*\n *  Misc util stuff.\n */\n\n#include \"duk_internal.h\"\n\n/*\n *  Lowercase digits for radix values 2 to 36.  Also doubles as lowercase\n *  hex nybble table.\n */\n\nDUK_INTERNAL const duk_uint8_t duk_lc_digits[36] = {\n\tDUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3,\n\tDUK_ASC_4, DUK_ASC_5, DUK_ASC_6, DUK_ASC_7,\n\tDUK_ASC_8, DUK_ASC_9, DUK_ASC_LC_A, DUK_ASC_LC_B,\n\tDUK_ASC_LC_C, DUK_ASC_LC_D, DUK_ASC_LC_E, DUK_ASC_LC_F,\n\tDUK_ASC_LC_G, DUK_ASC_LC_H, DUK_ASC_LC_I, DUK_ASC_LC_J,\n\tDUK_ASC_LC_K, DUK_ASC_LC_L, DUK_ASC_LC_M, DUK_ASC_LC_N,\n\tDUK_ASC_LC_O, DUK_ASC_LC_P, DUK_ASC_LC_Q, DUK_ASC_LC_R,\n\tDUK_ASC_LC_S, DUK_ASC_LC_T, DUK_ASC_LC_U, DUK_ASC_LC_V,\n\tDUK_ASC_LC_W, DUK_ASC_LC_X, DUK_ASC_LC_Y, DUK_ASC_LC_Z\n};\n\nDUK_INTERNAL const duk_uint8_t duk_uc_nybbles[16] = {\n\tDUK_ASC_0, DUK_ASC_1, DUK_ASC_2, DUK_ASC_3,\n\tDUK_ASC_4, DUK_ASC_5, DUK_ASC_6, DUK_ASC_7,\n\tDUK_ASC_8, DUK_ASC_9, DUK_ASC_UC_A, DUK_ASC_UC_B,\n\tDUK_ASC_UC_C, DUK_ASC_UC_D, DUK_ASC_UC_E, DUK_ASC_UC_F\n};\n\n/*\n *  Table for hex decoding ASCII hex digits\n */\n\nDUK_INTERNAL const duk_int8_t duk_hex_dectab[256] = {\n\t/* -1 if invalid */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x00-0x0f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x10-0x1f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x20-0x2f */\n\t 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1,  /* 0x30-0x3f */\n\t-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x40-0x4f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x50-0x5f */\n\t-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x60-0x6f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x70-0x7f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x80-0x8f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x90-0x9f */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xa0-0xaf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xb0-0xbf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xc0-0xcf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xd0-0xdf */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0xe0-0xef */\n\t-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1   /* 0xf0-0xff */\n};\n\n#if defined(DUK_USE_HEX_FASTPATH)\n/* Preshifted << 4.  Must use 16-bit entry to allow negative value signaling. */\nDUK_INTERNAL const duk_int16_t duk_hex_dectab_shift4[256] = {\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x00-0x0f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x10-0x1f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x20-0x2f */\n\t0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, 0x90,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x30-0x3f */\n\t  -1, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x40-0x4f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x50-0x5f */\n\t  -1, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x60-0x6f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x70-0x7f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x80-0x8f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0x90-0x9f */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xa0-0xaf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xb0-0xbf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xc0-0xcf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xd0-0xdf */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  /* 0xe0-0xef */\n\t  -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1   /* 0xf0-0xff */\n};\n#endif\n\n/*\n *  Table for hex encoding bytes\n */\n\n#if defined(DUK_USE_HEX_FASTPATH)\n/* Lookup to encode one byte directly into 2 characters:\n *\n *   def genhextab(bswap):\n *       for i in xrange(256):\n *           t = chr(i).encode('hex')\n *           if bswap:\n *               t = t[1] + t[0]\n *           print('0x' + t.encode('hex') + 'U')\n *   print('big endian'); genhextab(False)\n *   print('little endian'); genhextab(True)\n*/\nDUK_INTERNAL const duk_uint16_t duk_hex_enctab[256] = {\n#if defined(DUK_USE_INTEGER_BE)\n\t0x3030U, 0x3031U, 0x3032U, 0x3033U, 0x3034U, 0x3035U, 0x3036U, 0x3037U,\n\t0x3038U, 0x3039U, 0x3061U, 0x3062U, 0x3063U, 0x3064U, 0x3065U, 0x3066U,\n\t0x3130U, 0x3131U, 0x3132U, 0x3133U, 0x3134U, 0x3135U, 0x3136U, 0x3137U,\n\t0x3138U, 0x3139U, 0x3161U, 0x3162U, 0x3163U, 0x3164U, 0x3165U, 0x3166U,\n\t0x3230U, 0x3231U, 0x3232U, 0x3233U, 0x3234U, 0x3235U, 0x3236U, 0x3237U,\n\t0x3238U, 0x3239U, 0x3261U, 0x3262U, 0x3263U, 0x3264U, 0x3265U, 0x3266U,\n\t0x3330U, 0x3331U, 0x3332U, 0x3333U, 0x3334U, 0x3335U, 0x3336U, 0x3337U,\n\t0x3338U, 0x3339U, 0x3361U, 0x3362U, 0x3363U, 0x3364U, 0x3365U, 0x3366U,\n\t0x3430U, 0x3431U, 0x3432U, 0x3433U, 0x3434U, 0x3435U, 0x3436U, 0x3437U,\n\t0x3438U, 0x3439U, 0x3461U, 0x3462U, 0x3463U, 0x3464U, 0x3465U, 0x3466U,\n\t0x3530U, 0x3531U, 0x3532U, 0x3533U, 0x3534U, 0x3535U, 0x3536U, 0x3537U,\n\t0x3538U, 0x3539U, 0x3561U, 0x3562U, 0x3563U, 0x3564U, 0x3565U, 0x3566U,\n\t0x3630U, 0x3631U, 0x3632U, 0x3633U, 0x3634U, 0x3635U, 0x3636U, 0x3637U,\n\t0x3638U, 0x3639U, 0x3661U, 0x3662U, 0x3663U, 0x3664U, 0x3665U, 0x3666U,\n\t0x3730U, 0x3731U, 0x3732U, 0x3733U, 0x3734U, 0x3735U, 0x3736U, 0x3737U,\n\t0x3738U, 0x3739U, 0x3761U, 0x3762U, 0x3763U, 0x3764U, 0x3765U, 0x3766U,\n\t0x3830U, 0x3831U, 0x3832U, 0x3833U, 0x3834U, 0x3835U, 0x3836U, 0x3837U,\n\t0x3838U, 0x3839U, 0x3861U, 0x3862U, 0x3863U, 0x3864U, 0x3865U, 0x3866U,\n\t0x3930U, 0x3931U, 0x3932U, 0x3933U, 0x3934U, 0x3935U, 0x3936U, 0x3937U,\n\t0x3938U, 0x3939U, 0x3961U, 0x3962U, 0x3963U, 0x3964U, 0x3965U, 0x3966U,\n\t0x6130U, 0x6131U, 0x6132U, 0x6133U, 0x6134U, 0x6135U, 0x6136U, 0x6137U,\n\t0x6138U, 0x6139U, 0x6161U, 0x6162U, 0x6163U, 0x6164U, 0x6165U, 0x6166U,\n\t0x6230U, 0x6231U, 0x6232U, 0x6233U, 0x6234U, 0x6235U, 0x6236U, 0x6237U,\n\t0x6238U, 0x6239U, 0x6261U, 0x6262U, 0x6263U, 0x6264U, 0x6265U, 0x6266U,\n\t0x6330U, 0x6331U, 0x6332U, 0x6333U, 0x6334U, 0x6335U, 0x6336U, 0x6337U,\n\t0x6338U, 0x6339U, 0x6361U, 0x6362U, 0x6363U, 0x6364U, 0x6365U, 0x6366U,\n\t0x6430U, 0x6431U, 0x6432U, 0x6433U, 0x6434U, 0x6435U, 0x6436U, 0x6437U,\n\t0x6438U, 0x6439U, 0x6461U, 0x6462U, 0x6463U, 0x6464U, 0x6465U, 0x6466U,\n\t0x6530U, 0x6531U, 0x6532U, 0x6533U, 0x6534U, 0x6535U, 0x6536U, 0x6537U,\n\t0x6538U, 0x6539U, 0x6561U, 0x6562U, 0x6563U, 0x6564U, 0x6565U, 0x6566U,\n\t0x6630U, 0x6631U, 0x6632U, 0x6633U, 0x6634U, 0x6635U, 0x6636U, 0x6637U,\n\t0x6638U, 0x6639U, 0x6661U, 0x6662U, 0x6663U, 0x6664U, 0x6665U, 0x6666U\n#else  /* DUK_USE_INTEGER_BE */\n\t0x3030U, 0x3130U, 0x3230U, 0x3330U, 0x3430U, 0x3530U, 0x3630U, 0x3730U,\n\t0x3830U, 0x3930U, 0x6130U, 0x6230U, 0x6330U, 0x6430U, 0x6530U, 0x6630U,\n\t0x3031U, 0x3131U, 0x3231U, 0x3331U, 0x3431U, 0x3531U, 0x3631U, 0x3731U,\n\t0x3831U, 0x3931U, 0x6131U, 0x6231U, 0x6331U, 0x6431U, 0x6531U, 0x6631U,\n\t0x3032U, 0x3132U, 0x3232U, 0x3332U, 0x3432U, 0x3532U, 0x3632U, 0x3732U,\n\t0x3832U, 0x3932U, 0x6132U, 0x6232U, 0x6332U, 0x6432U, 0x6532U, 0x6632U,\n\t0x3033U, 0x3133U, 0x3233U, 0x3333U, 0x3433U, 0x3533U, 0x3633U, 0x3733U,\n\t0x3833U, 0x3933U, 0x6133U, 0x6233U, 0x6333U, 0x6433U, 0x6533U, 0x6633U,\n\t0x3034U, 0x3134U, 0x3234U, 0x3334U, 0x3434U, 0x3534U, 0x3634U, 0x3734U,\n\t0x3834U, 0x3934U, 0x6134U, 0x6234U, 0x6334U, 0x6434U, 0x6534U, 0x6634U,\n\t0x3035U, 0x3135U, 0x3235U, 0x3335U, 0x3435U, 0x3535U, 0x3635U, 0x3735U,\n\t0x3835U, 0x3935U, 0x6135U, 0x6235U, 0x6335U, 0x6435U, 0x6535U, 0x6635U,\n\t0x3036U, 0x3136U, 0x3236U, 0x3336U, 0x3436U, 0x3536U, 0x3636U, 0x3736U,\n\t0x3836U, 0x3936U, 0x6136U, 0x6236U, 0x6336U, 0x6436U, 0x6536U, 0x6636U,\n\t0x3037U, 0x3137U, 0x3237U, 0x3337U, 0x3437U, 0x3537U, 0x3637U, 0x3737U,\n\t0x3837U, 0x3937U, 0x6137U, 0x6237U, 0x6337U, 0x6437U, 0x6537U, 0x6637U,\n\t0x3038U, 0x3138U, 0x3238U, 0x3338U, 0x3438U, 0x3538U, 0x3638U, 0x3738U,\n\t0x3838U, 0x3938U, 0x6138U, 0x6238U, 0x6338U, 0x6438U, 0x6538U, 0x6638U,\n\t0x3039U, 0x3139U, 0x3239U, 0x3339U, 0x3439U, 0x3539U, 0x3639U, 0x3739U,\n\t0x3839U, 0x3939U, 0x6139U, 0x6239U, 0x6339U, 0x6439U, 0x6539U, 0x6639U,\n\t0x3061U, 0x3161U, 0x3261U, 0x3361U, 0x3461U, 0x3561U, 0x3661U, 0x3761U,\n\t0x3861U, 0x3961U, 0x6161U, 0x6261U, 0x6361U, 0x6461U, 0x6561U, 0x6661U,\n\t0x3062U, 0x3162U, 0x3262U, 0x3362U, 0x3462U, 0x3562U, 0x3662U, 0x3762U,\n\t0x3862U, 0x3962U, 0x6162U, 0x6262U, 0x6362U, 0x6462U, 0x6562U, 0x6662U,\n\t0x3063U, 0x3163U, 0x3263U, 0x3363U, 0x3463U, 0x3563U, 0x3663U, 0x3763U,\n\t0x3863U, 0x3963U, 0x6163U, 0x6263U, 0x6363U, 0x6463U, 0x6563U, 0x6663U,\n\t0x3064U, 0x3164U, 0x3264U, 0x3364U, 0x3464U, 0x3564U, 0x3664U, 0x3764U,\n\t0x3864U, 0x3964U, 0x6164U, 0x6264U, 0x6364U, 0x6464U, 0x6564U, 0x6664U,\n\t0x3065U, 0x3165U, 0x3265U, 0x3365U, 0x3465U, 0x3565U, 0x3665U, 0x3765U,\n\t0x3865U, 0x3965U, 0x6165U, 0x6265U, 0x6365U, 0x6465U, 0x6565U, 0x6665U,\n\t0x3066U, 0x3166U, 0x3266U, 0x3366U, 0x3466U, 0x3566U, 0x3666U, 0x3766U,\n\t0x3866U, 0x3966U, 0x6166U, 0x6266U, 0x6366U, 0x6466U, 0x6566U, 0x6666U\n#endif  /* DUK_USE_INTEGER_BE */\n};\n#endif  /* DUK_USE_HEX_FASTPATH */\n\n/*\n *  Arbitrary byteswap for potentially unaligned values\n *\n *  Used to byteswap pointers e.g. in debugger code.\n */\n\n#if defined(DUK_USE_DEBUGGER_SUPPORT)  /* For now only needed by the debugger. */\nDUK_INTERNAL void duk_byteswap_bytes(duk_uint8_t *p, duk_small_uint_t len) {\n\tduk_uint8_t tmp;\n\tduk_uint8_t *q = p + len - 1;\n\n\twhile (p - q < 0) {\n\t\ttmp = *p;\n\t\t*p = *q;\n\t\t*q = tmp;\n\t\tp++;\n\t\tq--;\n\t}\n}\n#endif\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duk_util_tinyrandom.c",
    "content": "/*\n *  A tiny random number generator used for Math.random() and other internals.\n *\n *  Default algorithm is xoroshiro128+: http://xoroshiro.di.unimi.it/xoroshiro128plus.c\n *  with SplitMix64 seed preparation: http://xorshift.di.unimi.it/splitmix64.c.\n *\n *  Low memory targets and targets without 64-bit types use a slightly smaller\n *  (but slower) algorithm by Adi Shamir:\n *  http://www.woodmann.com/forum/archive/index.php/t-3100.html.\n *\n */\n\n#include \"duk_internal.h\"\n\n#if !defined(DUK_USE_GET_RANDOM_DOUBLE)\n\n#if defined(DUK_USE_PREFER_SIZE) || !defined(DUK_USE_64BIT_OPS)\n#define DUK__RANDOM_SHAMIR3OP\n#else\n#define DUK__RANDOM_XOROSHIRO128PLUS\n#endif\n\n#if defined(DUK__RANDOM_SHAMIR3OP)\n#define DUK__UPDATE_RND(rnd) do { \\\n\t\t(rnd) += ((rnd) * (rnd)) | 0x05UL; \\\n\t\t(rnd) = ((rnd) & 0xffffffffUL);       /* if duk_uint32_t is exactly 32 bits, this is a NOP */ \\\n\t} while (0)\n\n#define DUK__RND_BIT(rnd)  ((rnd) >> 31)  /* only use the highest bit */\n\nDUK_INTERNAL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr) {\n\tDUK_UNREF(thr);  /* Nothing now. */\n}\n\nDUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) {\n\tduk_double_t t;\n\tduk_small_int_t n;\n\tduk_uint32_t rnd;\n\n\trnd = thr->heap->rnd_state;\n\n\tn = 53;  /* enough to cover the whole mantissa */\n\tt = 0.0;\n\n\tdo {\n\t\tDUK__UPDATE_RND(rnd);\n\t\tt += DUK__RND_BIT(rnd);\n\t\tt /= 2.0;\n\t} while (--n);\n\n\tthr->heap->rnd_state = rnd;\n\n\tDUK_ASSERT(t >= (duk_double_t) 0.0);\n\tDUK_ASSERT(t < (duk_double_t) 1.0);\n\n\treturn t;\n}\n#endif  /* DUK__RANDOM_SHAMIR3OP */\n\n#if defined(DUK__RANDOM_XOROSHIRO128PLUS)\nDUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__rnd_splitmix64(duk_uint64_t *x) {\n\tduk_uint64_t z;\n\tz = (*x += DUK_U64_CONSTANT(0x9E3779B97F4A7C15));\n\tz = (z ^ (z >> 30U)) * DUK_U64_CONSTANT(0xBF58476D1CE4E5B9);\n\tz = (z ^ (z >> 27U)) * DUK_U64_CONSTANT(0x94D049BB133111EB);\n\treturn z ^ (z >> 31U);\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__rnd_rotl(const duk_uint64_t x, duk_small_uint_t k) {\n\treturn (x << k) | (x >> (64U - k));\n}\n\nDUK_LOCAL DUK_ALWAYS_INLINE duk_uint64_t duk__xoroshiro128plus(duk_uint64_t *s) {\n\tduk_uint64_t s0;\n\tduk_uint64_t s1;\n\tduk_uint64_t res;\n\n\ts0 = s[0];\n\ts1 = s[1];\n\tres = s0 + s1;\n\ts1 ^= s0;\n\ts[0] = duk__rnd_rotl(s0, 55) ^ s1 ^ (s1 << 14U);\n\ts[1] = duk__rnd_rotl(s1, 36);\n\n\treturn res;\n}\n\nDUK_INTERNAL void duk_util_tinyrandom_prepare_seed(duk_hthread *thr) {\n\tduk_small_uint_t i;\n\tduk_uint64_t x;\n\n\t/* Mix both halves of the initial seed with SplitMix64.  The intent\n\t * is to ensure that very similar raw seeds (which is usually the case\n\t * because current seed is Date.now()) result in different xoroshiro128+\n\t * seeds.\n\t */\n\tx = thr->heap->rnd_state[0];  /* Only [0] is used as input here. */\n\tfor (i = 0; i < 64; i++) {\n\t\tthr->heap->rnd_state[i & 0x01] = duk__rnd_splitmix64(&x);  /* Keep last 2 values. */\n\t}\n}\n\nDUK_INTERNAL duk_double_t duk_util_tinyrandom_get_double(duk_hthread *thr) {\n\tduk_uint64_t v;\n\tduk_double_union du;\n\n\t/* For big and little endian the integer and IEEE double byte order\n\t * is the same so a direct assignment works.  For mixed endian the\n\t * 32-bit parts must be swapped.\n\t */\n\tv = (DUK_U64_CONSTANT(0x3ff) << 52U) | (duk__xoroshiro128plus((duk_uint64_t *) thr->heap->rnd_state) >> 12U);\n\tdu.ull[0] = v;\n#if defined(DUK_USE_DOUBLE_ME)\n\tdo {\n\t\tduk_uint32_t tmp;\n\t\ttmp = du.ui[0];\n\t\tdu.ui[0] = du.ui[1];\n\t\tdu.ui[1] = tmp;\n\t} while (0);\n#endif\n\treturn du.d - 1.0;\n}\n#endif  /* DUK__RANDOM_XOROSHIRO128PLUS */\n\n#endif  /* !DUK_USE_GET_RANDOM_DOUBLE */\n"
  },
  {
    "path": "react_juce/duktape/src-separate/duktape.h",
    "content": "/*\n *  Duktape public API for Duktape 2.4.0.\n *\n *  See the API reference for documentation on call semantics.  The exposed,\n *  supported API is between the \"BEGIN PUBLIC API\" and \"END PUBLIC API\"\n *  comments.  Other parts of the header are Duktape internal and related to\n *  e.g. platform/compiler/feature detection.\n *\n *  Git commit d4f2cff1c592d70f58bab8e1bd85705174c02a58 (v2.4.0).\n *  Git branch master.\n *\n *  See Duktape AUTHORS.rst and LICENSE.txt for copyright and\n *  licensing information.\n */\n\n/* LICENSE.txt */\n/*\n *  ===============\n *  Duktape license\n *  ===============\n *  \n *  (http://opensource.org/licenses/MIT)\n *  \n *  Copyright (c) 2013-2019 by Duktape authors (see AUTHORS.rst)\n *  \n *  Permission is hereby granted, free of charge, to any person obtaining a copy\n *  of this software and associated documentation files (the \"Software\"), to deal\n *  in the Software without restriction, including without limitation the rights\n *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n *  copies of the Software, and to permit persons to whom the Software is\n *  furnished to do so, subject to the following conditions:\n *  \n *  The above copyright notice and this permission notice shall be included in\n *  all copies or substantial portions of the Software.\n *  \n *  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n *  THE SOFTWARE.\n */\n\n/* AUTHORS.rst */\n/*\n *  ===============\n *  Duktape authors\n *  ===============\n *  \n *  Copyright\n *  =========\n *  \n *  Duktape copyrights are held by its authors.  Each author has a copyright\n *  to their contribution, and agrees to irrevocably license the contribution\n *  under the Duktape ``LICENSE.txt``.\n *  \n *  Authors\n *  =======\n *  \n *  Please include an e-mail address, a link to your GitHub profile, or something\n *  similar to allow your contribution to be identified accurately.\n *  \n *  The following people have contributed code, website contents, or Wiki contents,\n *  and agreed to irrevocably license their contributions under the Duktape\n *  ``LICENSE.txt`` (in order of appearance):\n *  \n *  * Sami Vaarala <sami.vaarala@iki.fi>\n *  * Niki Dobrev\n *  * Andreas \\u00d6man <andreas@lonelycoder.com>\n *  * L\\u00e1szl\\u00f3 Lang\\u00f3 <llango.u-szeged@partner.samsung.com>\n *  * Legimet <legimet.calc@gmail.com>\n *  * Karl Skomski <karl@skomski.com>\n *  * Bruce Pascoe <fatcerberus1@gmail.com>\n *  * Ren\\u00e9 Hollander <rene@rene8888.at>\n *  * Julien Hamaide (https://github.com/crazyjul)\n *  * Sebastian G\\u00f6tte (https://github.com/jaseg)\n *  * Tomasz Magulski (https://github.com/magul)\n *  * \\D. Bohdan (https://github.com/dbohdan)\n *  * Ond\\u0159ej Jirman (https://github.com/megous)\n *  * Sa\\u00fal Ibarra Corretg\\u00e9 <saghul@gmail.com>\n *  * Jeremy HU <huxingyi@msn.com>\n *  * Ole Andr\\u00e9 Vadla Ravn\\u00e5s (https://github.com/oleavr)\n *  * Harold Brenes (https://github.com/harold-b)\n *  * Oliver Crow (https://github.com/ocrow)\n *  * Jakub Ch\\u0142api\\u0144ski (https://github.com/jchlapinski)\n *  * Brett Vickers (https://github.com/beevik)\n *  * Dominik Okwieka (https://github.com/okitec)\n *  * Remko Tron\\u00e7on (https://el-tramo.be)\n *  * Romero Malaquias (rbsm@ic.ufal.br)\n *  * Michael Drake <michael.drake@codethink.co.uk>\n *  * Steven Don (https://github.com/shdon)\n *  * Simon Stone (https://github.com/sstone1)\n *  * \\J. McC. (https://github.com/jmhmccr)\n *  * Jakub Nowakowski (https://github.com/jimvonmoon)\n *  * Tommy Nguyen (https://github.com/tn0502)\n *  * Fabrice Fontaine (https://github.com/ffontaine)\n *  * Christopher Hiller (https://github.com/boneskull)\n *  * Gonzalo Diethelm (https://github.com/gonzus)\n *  * Michal Kasperek (https://github.com/michalkas)\n *  * Andrew Janke (https://github.com/apjanke)\n *  * Steve Fan (https://github.com/stevefan1999)\n *  * Edward Betts (https://github.com/edwardbetts)\n *  * Ozhan Duz (https://github.com/webfolderio)\n *  * Akos Kiss (https://github.com/akosthekiss)\n *  * TheBrokenRail (https://github.com/TheBrokenRail)\n *  * Jesse Doyle (https://github.com/jessedoyle)\n *  * Gero Kuehn (https://github.com/dc6jgk)\n *  * James Swift (https://github.com/phraemer)\n *  * Luis de Bethencourt (https://github.com/luisbg)\n *  * Ian Whyman (https://github.com/v00d00)\n *  \n *  Other contributions\n *  ===================\n *  \n *  The following people have contributed something other than code (e.g. reported\n *  bugs, provided ideas, etc; roughly in order of appearance):\n *  \n *  * Greg Burns\n *  * Anthony Rabine\n *  * Carlos Costa\n *  * Aur\\u00e9lien Bouilland\n *  * Preet Desai (Pris Matic)\n *  * judofyr (http://www.reddit.com/user/judofyr)\n *  * Jason Woofenden\n *  * Micha\\u0142 Przyby\\u015b\n *  * Anthony Howe\n *  * Conrad Pankoff\n *  * Jim Schimpf\n *  * Rajaran Gaunker (https://github.com/zimbabao)\n *  * Andreas \\u00d6man\n *  * Doug Sanden\n *  * Josh Engebretson (https://github.com/JoshEngebretson)\n *  * Remo Eichenberger (https://github.com/remoe)\n *  * Mamod Mehyar (https://github.com/mamod)\n *  * David Demelier (https://github.com/markand)\n *  * Tim Caswell (https://github.com/creationix)\n *  * Mitchell Blank Jr (https://github.com/mitchblank)\n *  * https://github.com/yushli\n *  * Seo Sanghyeon (https://github.com/sanxiyn)\n *  * Han ChoongWoo (https://github.com/tunz)\n *  * Joshua Peek (https://github.com/josh)\n *  * Bruce E. Pascoe (https://github.com/fatcerberus)\n *  * https://github.com/Kelledin\n *  * https://github.com/sstruchtrup\n *  * Michael Drake (https://github.com/tlsa)\n *  * https://github.com/chris-y\n *  * Laurent Zubiaur (https://github.com/lzubiaur)\n *  * Neil Kolban (https://github.com/nkolban)\n *  * Wilhelm Wanecek (https://github.com/wanecek)\n *  * Andrew Janke (https://github.com/apjanke)\n *  * Unamer (https://github.com/unamer)\n *  * Karl Dahlke (eklhad@gmail.com)\n *  \n *  If you are accidentally missing from this list, send me an e-mail\n *  (``sami.vaarala@iki.fi``) and I'll fix the omission.\n */\n\n#if !defined(DUKTAPE_H_INCLUDED)\n#define DUKTAPE_H_INCLUDED\n\n#undef DUK_SINGLE_FILE\n\n/*\n *  BEGIN PUBLIC API\n */\n\n/*\n *  Version and Git commit identification\n */\n\n/* Duktape version, (major * 10000) + (minor * 100) + patch.  Allows C code\n * to #if (DUK_VERSION >= NNN) against Duktape API version.  The same value\n * is also available to ECMAScript code in Duktape.version.  Unofficial\n * development snapshots have 99 for patch level (e.g. 0.10.99 would be a\n * development version after 0.10.0 but before the next official release).\n */\n#define DUK_VERSION                       20400L\n\n/* Git commit, describe, and branch for Duktape build.  Useful for\n * non-official snapshot builds so that application code can easily log\n * which Duktape snapshot was used.  Not available in the ECMAScript\n * environment.\n */\n#define DUK_GIT_COMMIT                    \"d4f2cff1c592d70f58bab8e1bd85705174c02a58\"\n#define DUK_GIT_DESCRIBE                  \"v2.4.0\"\n#define DUK_GIT_BRANCH                    \"master\"\n\n/* External duk_config.h provides platform/compiler/OS dependent\n * typedefs and macros, and DUK_USE_xxx config options so that\n * the rest of Duktape doesn't need to do any feature detection.\n * DUK_VERSION is defined before including so that configuration\n * snippets can react to it.\n */\n#include \"duk_config.h\"\n\n/*\n *  Avoid C++ name mangling\n */\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\n/*\n *  Some defines forwarded from feature detection\n */\n\n#undef DUK_API_VARIADIC_MACROS\n#if defined(DUK_USE_VARIADIC_MACROS)\n#define DUK_API_VARIADIC_MACROS\n#endif\n\n#define DUK_API_NORETURN(decl) DUK_NORETURN(decl)\n\n/*\n *  Public API specific typedefs\n *\n *  Many types are wrapped by Duktape for portability to rare platforms\n *  where e.g. 'int' is a 16-bit type.  See practical typing discussion\n *  in Duktape web documentation.\n */\n\nstruct duk_thread_state;\nstruct duk_memory_functions;\nstruct duk_function_list_entry;\nstruct duk_number_list_entry;\nstruct duk_time_components;\n\n/* duk_context is now defined in duk_config.h because it may also be\n * referenced there by prototypes.\n */\ntypedef struct duk_thread_state duk_thread_state;\ntypedef struct duk_memory_functions duk_memory_functions;\ntypedef struct duk_function_list_entry duk_function_list_entry;\ntypedef struct duk_number_list_entry duk_number_list_entry;\ntypedef struct duk_time_components duk_time_components;\n\ntypedef duk_ret_t (*duk_c_function)(duk_context *ctx);\ntypedef void *(*duk_alloc_function) (void *udata, duk_size_t size);\ntypedef void *(*duk_realloc_function) (void *udata, void *ptr, duk_size_t size);\ntypedef void (*duk_free_function) (void *udata, void *ptr);\ntypedef void (*duk_fatal_function) (void *udata, const char *msg);\ntypedef void (*duk_decode_char_function) (void *udata, duk_codepoint_t codepoint);\ntypedef duk_codepoint_t (*duk_map_char_function) (void *udata, duk_codepoint_t codepoint);\ntypedef duk_ret_t (*duk_safe_call_function) (duk_context *ctx, void *udata);\ntypedef duk_size_t (*duk_debug_read_function) (void *udata, char *buffer, duk_size_t length);\ntypedef duk_size_t (*duk_debug_write_function) (void *udata, const char *buffer, duk_size_t length);\ntypedef duk_size_t (*duk_debug_peek_function) (void *udata);\ntypedef void (*duk_debug_read_flush_function) (void *udata);\ntypedef void (*duk_debug_write_flush_function) (void *udata);\ntypedef duk_idx_t (*duk_debug_request_function) (duk_context *ctx, void *udata, duk_idx_t nvalues);\ntypedef void (*duk_debug_detached_function) (duk_context *ctx, void *udata);\n\nstruct duk_thread_state {\n\t/* XXX: Enough space to hold internal suspend/resume structure.\n\t * This is rather awkward and to be fixed when the internal\n\t * structure is visible for the public API header.\n\t */\n\tchar data[128];\n};\n\nstruct duk_memory_functions {\n\tduk_alloc_function alloc_func;\n\tduk_realloc_function realloc_func;\n\tduk_free_function free_func;\n\tvoid *udata;\n};\n\nstruct duk_function_list_entry {\n\tconst char *key;\n\tduk_c_function value;\n\tduk_idx_t nargs;\n};\n\nstruct duk_number_list_entry {\n\tconst char *key;\n\tduk_double_t value;\n};\n\nstruct duk_time_components {\n\tduk_double_t year;          /* year, e.g. 2016, ECMAScript year range */\n\tduk_double_t month;         /* month: 1-12 */\n\tduk_double_t day;           /* day: 1-31 */\n\tduk_double_t hours;         /* hour: 0-59 */\n\tduk_double_t minutes;       /* minute: 0-59 */\n\tduk_double_t seconds;       /* second: 0-59 (in POSIX time no leap second) */\n\tduk_double_t milliseconds;  /* may contain sub-millisecond fractions */\n\tduk_double_t weekday;       /* weekday: 0-6, 0=Sunday, 1=Monday, ..., 6=Saturday */\n};\n\n/*\n *  Constants\n */\n\n/* Duktape debug protocol version used by this build. */\n#define DUK_DEBUG_PROTOCOL_VERSION        2\n\n/* Used to represent invalid index; if caller uses this without checking,\n * this index will map to a non-existent stack entry.  Also used in some\n * API calls as a marker to denote \"no value\".\n */\n#define DUK_INVALID_INDEX                 DUK_IDX_MIN\n\n/* Indicates that a native function does not have a fixed number of args,\n * and the argument stack should not be capped/extended at all.\n */\n#define DUK_VARARGS                       ((duk_int_t) (-1))\n\n/* Number of value stack entries (in addition to actual call arguments)\n * guaranteed to be allocated on entry to a Duktape/C function.\n */\n#define DUK_API_ENTRY_STACK               64U\n\n/* Value types, used by e.g. duk_get_type() */\n#define DUK_TYPE_MIN                      0U\n#define DUK_TYPE_NONE                     0U    /* no value, e.g. invalid index */\n#define DUK_TYPE_UNDEFINED                1U    /* ECMAScript undefined */\n#define DUK_TYPE_NULL                     2U    /* ECMAScript null */\n#define DUK_TYPE_BOOLEAN                  3U    /* ECMAScript boolean: 0 or 1 */\n#define DUK_TYPE_NUMBER                   4U    /* ECMAScript number: double */\n#define DUK_TYPE_STRING                   5U    /* ECMAScript string: CESU-8 / extended UTF-8 encoded */\n#define DUK_TYPE_OBJECT                   6U    /* ECMAScript object: includes objects, arrays, functions, threads */\n#define DUK_TYPE_BUFFER                   7U    /* fixed or dynamic, garbage collected byte buffer */\n#define DUK_TYPE_POINTER                  8U    /* raw void pointer */\n#define DUK_TYPE_LIGHTFUNC                9U    /* lightweight function pointer */\n#define DUK_TYPE_MAX                      9U\n\n/* Value mask types, used by e.g. duk_get_type_mask() */\n#define DUK_TYPE_MASK_NONE                (1U << DUK_TYPE_NONE)\n#define DUK_TYPE_MASK_UNDEFINED           (1U << DUK_TYPE_UNDEFINED)\n#define DUK_TYPE_MASK_NULL                (1U << DUK_TYPE_NULL)\n#define DUK_TYPE_MASK_BOOLEAN             (1U << DUK_TYPE_BOOLEAN)\n#define DUK_TYPE_MASK_NUMBER              (1U << DUK_TYPE_NUMBER)\n#define DUK_TYPE_MASK_STRING              (1U << DUK_TYPE_STRING)\n#define DUK_TYPE_MASK_OBJECT              (1U << DUK_TYPE_OBJECT)\n#define DUK_TYPE_MASK_BUFFER              (1U << DUK_TYPE_BUFFER)\n#define DUK_TYPE_MASK_POINTER             (1U << DUK_TYPE_POINTER)\n#define DUK_TYPE_MASK_LIGHTFUNC           (1U << DUK_TYPE_LIGHTFUNC)\n#define DUK_TYPE_MASK_THROW               (1U << 10)  /* internal flag value: throw if mask doesn't match */\n#define DUK_TYPE_MASK_PROMOTE             (1U << 11)  /* internal flag value: promote to object if mask matches */\n\n/* Coercion hints */\n#define DUK_HINT_NONE                     0    /* prefer number, unless input is a Date, in which\n                                                * case prefer string (E5 Section 8.12.8)\n                                                */\n#define DUK_HINT_STRING                   1    /* prefer string */\n#define DUK_HINT_NUMBER                   2    /* prefer number */\n\n/* Enumeration flags for duk_enum() */\n#define DUK_ENUM_INCLUDE_NONENUMERABLE    (1U << 0)    /* enumerate non-numerable properties in addition to enumerable */\n#define DUK_ENUM_INCLUDE_HIDDEN           (1U << 1)    /* enumerate hidden symbols too (in Duktape 1.x called internal properties) */\n#define DUK_ENUM_INCLUDE_SYMBOLS          (1U << 2)    /* enumerate symbols */\n#define DUK_ENUM_EXCLUDE_STRINGS          (1U << 3)    /* exclude strings */\n#define DUK_ENUM_OWN_PROPERTIES_ONLY      (1U << 4)    /* don't walk prototype chain, only check own properties */\n#define DUK_ENUM_ARRAY_INDICES_ONLY       (1U << 5)    /* only enumerate array indices */\n/* XXX: misleading name */\n#define DUK_ENUM_SORT_ARRAY_INDICES       (1U << 6)    /* sort array indices (applied to full enumeration result, including inherited array indices); XXX: misleading name */\n#define DUK_ENUM_NO_PROXY_BEHAVIOR        (1U << 7)    /* enumerate a proxy object itself without invoking proxy behavior */\n\n/* Compilation flags for duk_compile() and duk_eval() */\n/* DUK_COMPILE_xxx bits 0-2 are reserved for an internal 'nargs' argument.\n */\n#define DUK_COMPILE_EVAL                  (1U << 3)    /* compile eval code (instead of global code) */\n#define DUK_COMPILE_FUNCTION              (1U << 4)    /* compile function code (instead of global code) */\n#define DUK_COMPILE_STRICT                (1U << 5)    /* use strict (outer) context for global, eval, or function code */\n#define DUK_COMPILE_SHEBANG               (1U << 6)    /* allow shebang ('#! ...') comment on first line of source */\n#define DUK_COMPILE_SAFE                  (1U << 7)    /* (internal) catch compilation errors */\n#define DUK_COMPILE_NORESULT              (1U << 8)    /* (internal) omit eval result */\n#define DUK_COMPILE_NOSOURCE              (1U << 9)    /* (internal) no source string on stack */\n#define DUK_COMPILE_STRLEN                (1U << 10)   /* (internal) take strlen() of src_buffer (avoids double evaluation in macro) */\n#define DUK_COMPILE_NOFILENAME            (1U << 11)   /* (internal) no filename on stack */\n#define DUK_COMPILE_FUNCEXPR              (1U << 12)   /* (internal) source is a function expression (used for Function constructor) */\n\n/* Flags for duk_def_prop() and its variants; base flags + a lot of convenience shorthands */\n#define DUK_DEFPROP_WRITABLE              (1U << 0)    /* set writable (effective if DUK_DEFPROP_HAVE_WRITABLE set) */\n#define DUK_DEFPROP_ENUMERABLE            (1U << 1)    /* set enumerable (effective if DUK_DEFPROP_HAVE_ENUMERABLE set) */\n#define DUK_DEFPROP_CONFIGURABLE          (1U << 2)    /* set configurable (effective if DUK_DEFPROP_HAVE_CONFIGURABLE set) */\n#define DUK_DEFPROP_HAVE_WRITABLE         (1U << 3)    /* set/clear writable */\n#define DUK_DEFPROP_HAVE_ENUMERABLE       (1U << 4)    /* set/clear enumerable */\n#define DUK_DEFPROP_HAVE_CONFIGURABLE     (1U << 5)    /* set/clear configurable */\n#define DUK_DEFPROP_HAVE_VALUE            (1U << 6)    /* set value (given on value stack) */\n#define DUK_DEFPROP_HAVE_GETTER           (1U << 7)    /* set getter (given on value stack) */\n#define DUK_DEFPROP_HAVE_SETTER           (1U << 8)    /* set setter (given on value stack) */\n#define DUK_DEFPROP_FORCE                 (1U << 9)    /* force change if possible, may still fail for e.g. virtual properties */\n#define DUK_DEFPROP_SET_WRITABLE          (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_WRITABLE)\n#define DUK_DEFPROP_CLEAR_WRITABLE        DUK_DEFPROP_HAVE_WRITABLE\n#define DUK_DEFPROP_SET_ENUMERABLE        (DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE)\n#define DUK_DEFPROP_CLEAR_ENUMERABLE      DUK_DEFPROP_HAVE_ENUMERABLE\n#define DUK_DEFPROP_SET_CONFIGURABLE      (DUK_DEFPROP_HAVE_CONFIGURABLE | DUK_DEFPROP_CONFIGURABLE)\n#define DUK_DEFPROP_CLEAR_CONFIGURABLE    DUK_DEFPROP_HAVE_CONFIGURABLE\n#define DUK_DEFPROP_W                     DUK_DEFPROP_WRITABLE\n#define DUK_DEFPROP_E                     DUK_DEFPROP_ENUMERABLE\n#define DUK_DEFPROP_C                     DUK_DEFPROP_CONFIGURABLE\n#define DUK_DEFPROP_WE                    (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_ENUMERABLE)\n#define DUK_DEFPROP_WC                    (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_CONFIGURABLE)\n#define DUK_DEFPROP_WEC                   (DUK_DEFPROP_WRITABLE | DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_CONFIGURABLE)\n#define DUK_DEFPROP_HAVE_W                DUK_DEFPROP_HAVE_WRITABLE\n#define DUK_DEFPROP_HAVE_E                DUK_DEFPROP_HAVE_ENUMERABLE\n#define DUK_DEFPROP_HAVE_C                DUK_DEFPROP_HAVE_CONFIGURABLE\n#define DUK_DEFPROP_HAVE_WE               (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE)\n#define DUK_DEFPROP_HAVE_WC               (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_CONFIGURABLE)\n#define DUK_DEFPROP_HAVE_WEC              (DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE)\n#define DUK_DEFPROP_SET_W                 DUK_DEFPROP_SET_WRITABLE\n#define DUK_DEFPROP_SET_E                 DUK_DEFPROP_SET_ENUMERABLE\n#define DUK_DEFPROP_SET_C                 DUK_DEFPROP_SET_CONFIGURABLE\n#define DUK_DEFPROP_SET_WE                (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_ENUMERABLE)\n#define DUK_DEFPROP_SET_WC                (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_CONFIGURABLE)\n#define DUK_DEFPROP_SET_WEC               (DUK_DEFPROP_SET_WRITABLE | DUK_DEFPROP_SET_ENUMERABLE | DUK_DEFPROP_SET_CONFIGURABLE)\n#define DUK_DEFPROP_CLEAR_W               DUK_DEFPROP_CLEAR_WRITABLE\n#define DUK_DEFPROP_CLEAR_E               DUK_DEFPROP_CLEAR_ENUMERABLE\n#define DUK_DEFPROP_CLEAR_C               DUK_DEFPROP_CLEAR_CONFIGURABLE\n#define DUK_DEFPROP_CLEAR_WE              (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_ENUMERABLE)\n#define DUK_DEFPROP_CLEAR_WC              (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_CONFIGURABLE)\n#define DUK_DEFPROP_CLEAR_WEC             (DUK_DEFPROP_CLEAR_WRITABLE | DUK_DEFPROP_CLEAR_ENUMERABLE | DUK_DEFPROP_CLEAR_CONFIGURABLE)\n#define DUK_DEFPROP_ATTR_W                (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_W)\n#define DUK_DEFPROP_ATTR_E                (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_E)\n#define DUK_DEFPROP_ATTR_C                (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_C)\n#define DUK_DEFPROP_ATTR_WE               (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WE)\n#define DUK_DEFPROP_ATTR_WC               (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WC)\n#define DUK_DEFPROP_ATTR_WEC              (DUK_DEFPROP_HAVE_WEC | DUK_DEFPROP_WEC)\n\n/* Flags for duk_push_thread_raw() */\n#define DUK_THREAD_NEW_GLOBAL_ENV         (1U << 0)    /* create a new global environment */\n\n/* Flags for duk_gc() */\n#define DUK_GC_COMPACT                    (1U << 0)    /* compact heap objects */\n\n/* Error codes (must be 8 bits at most, see duk_error.h) */\n#define DUK_ERR_NONE                      0    /* no error (e.g. from duk_get_error_code()) */\n#define DUK_ERR_ERROR                     1    /* Error */\n#define DUK_ERR_EVAL_ERROR                2    /* EvalError */\n#define DUK_ERR_RANGE_ERROR               3    /* RangeError */\n#define DUK_ERR_REFERENCE_ERROR           4    /* ReferenceError */\n#define DUK_ERR_SYNTAX_ERROR              5    /* SyntaxError */\n#define DUK_ERR_TYPE_ERROR                6    /* TypeError */\n#define DUK_ERR_URI_ERROR                 7    /* URIError */\n\n/* Return codes for C functions (shortcut for throwing an error) */\n#define DUK_RET_ERROR                     (-DUK_ERR_ERROR)\n#define DUK_RET_EVAL_ERROR                (-DUK_ERR_EVAL_ERROR)\n#define DUK_RET_RANGE_ERROR               (-DUK_ERR_RANGE_ERROR)\n#define DUK_RET_REFERENCE_ERROR           (-DUK_ERR_REFERENCE_ERROR)\n#define DUK_RET_SYNTAX_ERROR              (-DUK_ERR_SYNTAX_ERROR)\n#define DUK_RET_TYPE_ERROR                (-DUK_ERR_TYPE_ERROR)\n#define DUK_RET_URI_ERROR                 (-DUK_ERR_URI_ERROR)\n\n/* Return codes for protected calls (duk_safe_call(), duk_pcall()) */\n#define DUK_EXEC_SUCCESS                  0\n#define DUK_EXEC_ERROR                    1\n\n/* Debug levels for DUK_USE_DEBUG_WRITE(). */\n#define DUK_LEVEL_DEBUG                   0\n#define DUK_LEVEL_DDEBUG                  1\n#define DUK_LEVEL_DDDEBUG                 2\n\n/*\n *  Macros to create Symbols as C statically constructed strings.\n *\n *  Call e.g. as DUK_HIDDEN_SYMBOL(\"myProperty\") <=> (\"\\xFF\" \"myProperty\").\n *\n *  Local symbols have a unique suffix, caller should take care to avoid\n *  conflicting with the Duktape internal representation by e.g. prepending\n *  a '!' character: DUK_LOCAL_SYMBOL(\"myLocal\", \"!123\").\n *\n *  Note that these can only be used for string constants, not dynamically\n *  created strings.\n *\n *  You shouldn't normally use DUK_INTERNAL_SYMBOL() at all.  It is reserved\n *  for Duktape internal symbols only.  There are no versioning guarantees\n *  for internal symbols.\n */\n\n#define DUK_HIDDEN_SYMBOL(x)     (\"\\xFF\" x)\n#define DUK_GLOBAL_SYMBOL(x)     (\"\\x80\" x)\n#define DUK_LOCAL_SYMBOL(x,uniq) (\"\\x81\" x \"\\xff\" uniq)\n#define DUK_WELLKNOWN_SYMBOL(x)  (\"\\x81\" x \"\\xff\")\n#define DUK_INTERNAL_SYMBOL(x)   (\"\\x82\" x)\n\n/*\n *  If no variadic macros, __FILE__ and __LINE__ are passed through globals\n *  which is ugly and not thread safe.\n */\n\n#if !defined(DUK_API_VARIADIC_MACROS)\nDUK_EXTERNAL_DECL const char *duk_api_global_filename;\nDUK_EXTERNAL_DECL duk_int_t duk_api_global_line;\n#endif\n\n/*\n *  Context management\n */\n\nDUK_EXTERNAL_DECL\nduk_context *duk_create_heap(duk_alloc_function alloc_func,\n                             duk_realloc_function realloc_func,\n                             duk_free_function free_func,\n                             void *heap_udata,\n                             duk_fatal_function fatal_handler);\nDUK_EXTERNAL_DECL void duk_destroy_heap(duk_context *ctx);\n\nDUK_EXTERNAL_DECL void duk_suspend(duk_context *ctx, duk_thread_state *state);\nDUK_EXTERNAL_DECL void duk_resume(duk_context *ctx, const duk_thread_state *state);\n\n#define duk_create_heap_default() \\\n\tduk_create_heap(NULL, NULL, NULL, NULL, NULL)\n\n/*\n *  Memory management\n *\n *  Raw functions have no side effects (cannot trigger GC).\n */\n\nDUK_EXTERNAL_DECL void *duk_alloc_raw(duk_context *ctx, duk_size_t size);\nDUK_EXTERNAL_DECL void duk_free_raw(duk_context *ctx, void *ptr);\nDUK_EXTERNAL_DECL void *duk_realloc_raw(duk_context *ctx, void *ptr, duk_size_t size);\nDUK_EXTERNAL_DECL void *duk_alloc(duk_context *ctx, duk_size_t size);\nDUK_EXTERNAL_DECL void duk_free(duk_context *ctx, void *ptr);\nDUK_EXTERNAL_DECL void *duk_realloc(duk_context *ctx, void *ptr, duk_size_t size);\nDUK_EXTERNAL_DECL void duk_get_memory_functions(duk_context *ctx, duk_memory_functions *out_funcs);\nDUK_EXTERNAL_DECL void duk_gc(duk_context *ctx, duk_uint_t flags);\n\n/*\n *  Error handling\n */\n\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_throw_raw(duk_context *ctx));\n#define duk_throw(ctx) \\\n\t(duk_throw_raw((ctx)), (duk_ret_t) 0)\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_fatal_raw(duk_context *ctx, const char *err_msg));\n#define duk_fatal(ctx,err_msg) \\\n\t(duk_fatal_raw((ctx), (err_msg)), (duk_ret_t) 0)\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...));\n\n#if defined(DUK_API_VARIADIC_MACROS)\n#define duk_error(ctx,err_code,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_generic_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_eval_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_EVAL_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_range_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_RANGE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_reference_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_REFERENCE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_syntax_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_SYNTAX_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_type_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_TYPE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#define duk_uri_error(ctx,...)  \\\n\t(duk_error_raw((ctx), (duk_errcode_t) DUK_ERR_URI_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__), (duk_ret_t) 0)\n#else  /* DUK_API_VARIADIC_MACROS */\n/* For legacy compilers without variadic macros a macro hack is used to allow\n * variable arguments.  While the macro allows \"return duk_error(...)\", it\n * will fail with e.g. \"(void) duk_error(...)\".  The calls are noreturn but\n * with a return value to allow the \"return duk_error(...)\" idiom.  This may\n * cause some compiler warnings, but without noreturn the generated code is\n * often worse.  The same approach as with variadic macros (using\n * \"(duk_error(...), 0)\") won't work due to the macro hack structure.\n */\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_error_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_generic_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_eval_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_range_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_reference_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_syntax_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_type_error_stash(duk_context *ctx, const char *fmt, ...));\nDUK_API_NORETURN(DUK_EXTERNAL_DECL duk_ret_t duk_uri_error_stash(duk_context *ctx, const char *fmt, ...));\n#define duk_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_error_stash)  /* last value is func pointer, arguments follow in parens */\n#define duk_generic_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_generic_error_stash)\n#define duk_eval_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_eval_error_stash)\n#define duk_range_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_range_error_stash)\n#define duk_reference_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_reference_error_stash)\n#define duk_syntax_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_syntax_error_stash)\n#define duk_type_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_type_error_stash)\n#define duk_uri_error  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_uri_error_stash)\n#endif  /* DUK_API_VARIADIC_MACROS */\n\nDUK_API_NORETURN(DUK_EXTERNAL_DECL void duk_error_va_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap));\n\n#define duk_error_va(ctx,err_code,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_generic_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_eval_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_EVAL_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_range_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_RANGE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_reference_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_REFERENCE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_syntax_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_SYNTAX_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_type_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_TYPE_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n#define duk_uri_error_va(ctx,fmt,ap)  \\\n\t(duk_error_va_raw((ctx), (duk_errcode_t) DUK_ERR_URI_ERROR, (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap)), (duk_ret_t) 0)\n\n/*\n *  Other state related functions\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_strict_call(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_constructor_call(duk_context *ctx);\n\n/*\n *  Stack management\n */\n\nDUK_EXTERNAL_DECL duk_idx_t duk_normalize_index(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_idx_t duk_require_normalize_index(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_valid_index(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_require_valid_index(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL duk_idx_t duk_get_top(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_set_top(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_idx_t duk_get_top_index(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_require_top_index(duk_context *ctx);\n\n/* Although extra/top could be an unsigned type here, using a signed type\n * makes the API more robust to calling code calculation errors or corner\n * cases (where caller might occasionally come up with negative values).\n * Negative values are treated as zero, which is better than casting them\n * to a large unsigned number.  (This principle is used elsewhere in the\n * API too.)\n */\nDUK_EXTERNAL_DECL duk_bool_t duk_check_stack(duk_context *ctx, duk_idx_t extra);\nDUK_EXTERNAL_DECL void duk_require_stack(duk_context *ctx, duk_idx_t extra);\nDUK_EXTERNAL_DECL duk_bool_t duk_check_stack_top(duk_context *ctx, duk_idx_t top);\nDUK_EXTERNAL_DECL void duk_require_stack_top(duk_context *ctx, duk_idx_t top);\n\n/*\n *  Stack manipulation (other than push/pop)\n */\n\nDUK_EXTERNAL_DECL void duk_swap(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL void duk_swap_top(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_dup(duk_context *ctx, duk_idx_t from_idx);\nDUK_EXTERNAL_DECL void duk_dup_top(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_insert(duk_context *ctx, duk_idx_t to_idx);\nDUK_EXTERNAL_DECL void duk_replace(duk_context *ctx, duk_idx_t to_idx);\nDUK_EXTERNAL_DECL void duk_copy(duk_context *ctx, duk_idx_t from_idx, duk_idx_t to_idx);\nDUK_EXTERNAL_DECL void duk_remove(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_xcopymove_raw(duk_context *to_ctx, duk_context *from_ctx, duk_idx_t count, duk_bool_t is_copy);\n\n#define duk_xmove_top(to_ctx,from_ctx,count) \\\n\tduk_xcopymove_raw((to_ctx), (from_ctx), (count), 0 /*is_copy*/)\n#define duk_xcopy_top(to_ctx,from_ctx,count) \\\n\tduk_xcopymove_raw((to_ctx), (from_ctx), (count), 1 /*is_copy*/)\n\n/*\n *  Push operations\n *\n *  Push functions return the absolute (relative to bottom of frame)\n *  position of the pushed value for convenience.\n *\n *  Note: duk_dup() is technically a push.\n */\n\nDUK_EXTERNAL_DECL void duk_push_undefined(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_null(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_boolean(duk_context *ctx, duk_bool_t val);\nDUK_EXTERNAL_DECL void duk_push_true(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_false(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_number(duk_context *ctx, duk_double_t val);\nDUK_EXTERNAL_DECL void duk_push_nan(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_int(duk_context *ctx, duk_int_t val);\nDUK_EXTERNAL_DECL void duk_push_uint(duk_context *ctx, duk_uint_t val);\nDUK_EXTERNAL_DECL const char *duk_push_string(duk_context *ctx, const char *str);\nDUK_EXTERNAL_DECL const char *duk_push_lstring(duk_context *ctx, const char *str, duk_size_t len);\nDUK_EXTERNAL_DECL void duk_push_pointer(duk_context *ctx, void *p);\nDUK_EXTERNAL_DECL const char *duk_push_sprintf(duk_context *ctx, const char *fmt, ...);\nDUK_EXTERNAL_DECL const char *duk_push_vsprintf(duk_context *ctx, const char *fmt, va_list ap);\n\n/* duk_push_literal() may evaluate its argument (a C string literal) more than\n * once on purpose.  When speed is preferred, sizeof() avoids an unnecessary\n * strlen() at runtime.  Sizeof(\"foo\") == 4, so subtract 1.  The argument\n * must be non-NULL and should not contain internal NUL characters as the\n * behavior will then depend on config options.\n */\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_push_literal(ctx,cstring)  duk_push_string((ctx), (cstring))\n#else\nDUK_EXTERNAL_DECL const char *duk_push_literal_raw(duk_context *ctx, const char *str, duk_size_t len);\n#define duk_push_literal(ctx,cstring)  duk_push_literal_raw((ctx), (cstring), sizeof((cstring)) - 1U)\n#endif\n\nDUK_EXTERNAL_DECL void duk_push_this(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_new_target(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_current_function(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_current_thread(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_global_object(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_heap_stash(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_global_stash(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_push_thread_stash(duk_context *ctx, duk_context *target_ctx);\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_object(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_bare_object(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_array(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_bare_array(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_c_function(duk_context *ctx, duk_c_function func, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_c_lightfunc(duk_context *ctx, duk_c_function func, duk_idx_t nargs, duk_idx_t length, duk_int_t magic);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_thread_raw(duk_context *ctx, duk_uint_t flags);\nDUK_EXTERNAL_DECL duk_idx_t duk_push_proxy(duk_context *ctx, duk_uint_t proxy_flags);\n\n#define duk_push_thread(ctx) \\\n\tduk_push_thread_raw((ctx), 0 /*flags*/)\n\n#define duk_push_thread_new_globalenv(ctx) \\\n\tduk_push_thread_raw((ctx), DUK_THREAD_NEW_GLOBAL_ENV /*flags*/)\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, ...);\n\n#if defined(DUK_API_VARIADIC_MACROS)\n#define duk_push_error_object(ctx,err_code,...)  \\\n\tduk_push_error_object_raw((ctx), (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), __VA_ARGS__)\n#else\nDUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_stash(duk_context *ctx, duk_errcode_t err_code, const char *fmt, ...);\n/* Note: parentheses are required so that the comma expression works in assignments. */\n#define duk_push_error_object  \\\n\t(duk_api_global_filename = (const char *) (DUK_FILE_MACRO), \\\n\t duk_api_global_line = (duk_int_t) (DUK_LINE_MACRO), \\\n\t duk_push_error_object_stash)  /* last value is func pointer, arguments follow in parens */\n#endif\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_error_object_va_raw(duk_context *ctx, duk_errcode_t err_code, const char *filename, duk_int_t line, const char *fmt, va_list ap);\n#define duk_push_error_object_va(ctx,err_code,fmt,ap)  \\\n\tduk_push_error_object_va_raw((ctx), (err_code), (const char *) (DUK_FILE_MACRO), (duk_int_t) (DUK_LINE_MACRO), (fmt), (ap))\n\n#define DUK_BUF_FLAG_DYNAMIC   (1 << 0)    /* internal flag: dynamic buffer */\n#define DUK_BUF_FLAG_EXTERNAL  (1 << 1)    /* internal flag: external buffer */\n#define DUK_BUF_FLAG_NOZERO    (1 << 2)    /* internal flag: don't zero allocated buffer */\n\nDUK_EXTERNAL_DECL void *duk_push_buffer_raw(duk_context *ctx, duk_size_t size, duk_small_uint_t flags);\n\n#define duk_push_buffer(ctx,size,dynamic) \\\n\tduk_push_buffer_raw((ctx), (size), (dynamic) ? DUK_BUF_FLAG_DYNAMIC : 0)\n#define duk_push_fixed_buffer(ctx,size) \\\n\tduk_push_buffer_raw((ctx), (size), 0 /*flags*/)\n#define duk_push_dynamic_buffer(ctx,size) \\\n\tduk_push_buffer_raw((ctx), (size), DUK_BUF_FLAG_DYNAMIC /*flags*/)\n#define duk_push_external_buffer(ctx) \\\n\t((void) duk_push_buffer_raw((ctx), 0, DUK_BUF_FLAG_DYNAMIC | DUK_BUF_FLAG_EXTERNAL))\n\n#define DUK_BUFOBJ_ARRAYBUFFER         0\n#define DUK_BUFOBJ_NODEJS_BUFFER       1\n#define DUK_BUFOBJ_DATAVIEW            2\n#define DUK_BUFOBJ_INT8ARRAY           3\n#define DUK_BUFOBJ_UINT8ARRAY          4\n#define DUK_BUFOBJ_UINT8CLAMPEDARRAY   5\n#define DUK_BUFOBJ_INT16ARRAY          6\n#define DUK_BUFOBJ_UINT16ARRAY         7\n#define DUK_BUFOBJ_INT32ARRAY          8\n#define DUK_BUFOBJ_UINT32ARRAY         9\n#define DUK_BUFOBJ_FLOAT32ARRAY        10\n#define DUK_BUFOBJ_FLOAT64ARRAY        11\n\nDUK_EXTERNAL_DECL void duk_push_buffer_object(duk_context *ctx, duk_idx_t idx_buffer, duk_size_t byte_offset, duk_size_t byte_length, duk_uint_t flags);\n\nDUK_EXTERNAL_DECL duk_idx_t duk_push_heapptr(duk_context *ctx, void *ptr);\n\n/*\n *  Pop operations\n */\n\nDUK_EXTERNAL_DECL void duk_pop(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_pop_n(duk_context *ctx, duk_idx_t count);\nDUK_EXTERNAL_DECL void duk_pop_2(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_pop_3(duk_context *ctx);\n\n/*\n *  Type checks\n *\n *  duk_is_none(), which would indicate whether index it outside of stack,\n *  is not needed; duk_is_valid_index() gives the same information.\n */\n\nDUK_EXTERNAL_DECL duk_int_t duk_get_type(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_check_type(duk_context *ctx, duk_idx_t idx, duk_int_t type);\nDUK_EXTERNAL_DECL duk_uint_t duk_get_type_mask(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_check_type_mask(duk_context *ctx, duk_idx_t idx, duk_uint_t mask);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_undefined(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_null(duk_context *ctx, duk_idx_t idx);\n#define duk_is_null_or_undefined(ctx, idx) \\\n\t((duk_get_type_mask((ctx), (idx)) & (DUK_TYPE_MASK_NULL | DUK_TYPE_MASK_UNDEFINED)) ? 1 : 0)\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_nan(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_object(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_buffer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_buffer_data(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_lightfunc(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_symbol(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_array(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_c_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_ecmascript_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_bound_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_thread(duk_context *ctx, duk_idx_t idx);\n\n#define duk_is_callable(ctx,idx) \\\n\tduk_is_function((ctx), (idx))\nDUK_EXTERNAL_DECL duk_bool_t duk_is_constructable(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_is_dynamic_buffer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_fixed_buffer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_is_external_buffer(duk_context *ctx, duk_idx_t idx);\n\n/* Buffers and lightfuncs are not considered primitive because they mimic\n * objects and e.g. duk_to_primitive() will coerce them instead of returning\n * them as is.  Symbols are represented as strings internally.\n */\n#define duk_is_primitive(ctx,idx) \\\n\tduk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_UNDEFINED | \\\n\t                                  DUK_TYPE_MASK_NULL | \\\n\t                                  DUK_TYPE_MASK_BOOLEAN | \\\n\t                                  DUK_TYPE_MASK_NUMBER | \\\n\t                                  DUK_TYPE_MASK_STRING | \\\n\t                                  DUK_TYPE_MASK_POINTER)\n\n/* Symbols are object coercible, covered by DUK_TYPE_MASK_STRING. */\n#define duk_is_object_coercible(ctx,idx) \\\n\tduk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_BOOLEAN | \\\n\t                                  DUK_TYPE_MASK_NUMBER | \\\n\t                                  DUK_TYPE_MASK_STRING | \\\n\t                                  DUK_TYPE_MASK_OBJECT | \\\n\t                                  DUK_TYPE_MASK_BUFFER | \\\n\t                                  DUK_TYPE_MASK_POINTER | \\\n\t                                  DUK_TYPE_MASK_LIGHTFUNC)\n\nDUK_EXTERNAL_DECL duk_errcode_t duk_get_error_code(duk_context *ctx, duk_idx_t idx);\n#define duk_is_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) != 0)\n#define duk_is_eval_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_EVAL_ERROR)\n#define duk_is_range_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_RANGE_ERROR)\n#define duk_is_reference_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_REFERENCE_ERROR)\n#define duk_is_syntax_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_SYNTAX_ERROR)\n#define duk_is_type_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_TYPE_ERROR)\n#define duk_is_uri_error(ctx,idx) \\\n\t(duk_get_error_code((ctx), (idx)) == DUK_ERR_URI_ERROR)\n\n/*\n *  Get operations: no coercion, returns default value for invalid\n *  indices and invalid value types.\n *\n *  duk_get_undefined() and duk_get_null() would be pointless and\n *  are not included.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_double_t duk_get_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int_t duk_get_int(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint_t duk_get_uint(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_get_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_get_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL void *duk_get_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_get_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_get_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_c_function duk_get_c_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_context *duk_get_context(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void *duk_get_heapptr(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Get-with-explicit default operations: like get operations but with an\n *  explicit default value.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_boolean_default(duk_context *ctx, duk_idx_t idx, duk_bool_t def_value);\nDUK_EXTERNAL_DECL duk_double_t duk_get_number_default(duk_context *ctx, duk_idx_t idx, duk_double_t def_value);\nDUK_EXTERNAL_DECL duk_int_t duk_get_int_default(duk_context *ctx, duk_idx_t idx, duk_int_t def_value);\nDUK_EXTERNAL_DECL duk_uint_t duk_get_uint_default(duk_context *ctx, duk_idx_t idx, duk_uint_t def_value);\nDUK_EXTERNAL_DECL const char *duk_get_string_default(duk_context *ctx, duk_idx_t idx, const char *def_value);\nDUK_EXTERNAL_DECL const char *duk_get_lstring_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_get_buffer_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_get_buffer_data_default(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_get_pointer_default(duk_context *ctx, duk_idx_t idx, void *def_value);\nDUK_EXTERNAL_DECL duk_c_function duk_get_c_function_default(duk_context *ctx, duk_idx_t idx, duk_c_function def_value);\nDUK_EXTERNAL_DECL duk_context *duk_get_context_default(duk_context *ctx, duk_idx_t idx, duk_context *def_value);\nDUK_EXTERNAL_DECL void *duk_get_heapptr_default(duk_context *ctx, duk_idx_t idx, void *def_value);\n\n/*\n *  Opt operations: like require operations but with an explicit default value\n *  when value is undefined or index is invalid, null and non-matching types\n *  cause a TypeError.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_opt_boolean(duk_context *ctx, duk_idx_t idx, duk_bool_t def_value);\nDUK_EXTERNAL_DECL duk_double_t duk_opt_number(duk_context *ctx, duk_idx_t idx, duk_double_t def_value);\nDUK_EXTERNAL_DECL duk_int_t duk_opt_int(duk_context *ctx, duk_idx_t idx, duk_int_t def_value);\nDUK_EXTERNAL_DECL duk_uint_t duk_opt_uint(duk_context *ctx, duk_idx_t idx, duk_uint_t def_value);\nDUK_EXTERNAL_DECL const char *duk_opt_string(duk_context *ctx, duk_idx_t idx, const char *def_ptr);\nDUK_EXTERNAL_DECL const char *duk_opt_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len, const char *def_ptr, duk_size_t def_len);\nDUK_EXTERNAL_DECL void *duk_opt_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size);\nDUK_EXTERNAL_DECL void *duk_opt_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, void *def_ptr, duk_size_t def_size);\nDUK_EXTERNAL_DECL void *duk_opt_pointer(duk_context *ctx, duk_idx_t idx, void *def_value);\nDUK_EXTERNAL_DECL duk_c_function duk_opt_c_function(duk_context *ctx, duk_idx_t idx, duk_c_function def_value);\nDUK_EXTERNAL_DECL duk_context *duk_opt_context(duk_context *ctx, duk_idx_t idx, duk_context *def_value);\nDUK_EXTERNAL_DECL void *duk_opt_heapptr(duk_context *ctx, duk_idx_t idx, void *def_value);\n\n/*\n *  Require operations: no coercion, throw error if index or type\n *  is incorrect.  No defaulting.\n */\n\n#define duk_require_type_mask(ctx,idx,mask) \\\n\t((void) duk_check_type_mask((ctx), (idx), (mask) | DUK_TYPE_MASK_THROW))\n\nDUK_EXTERNAL_DECL void duk_require_undefined(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_require_null(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_require_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_double_t duk_require_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int_t duk_require_int(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint_t duk_require_uint(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_require_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_require_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL void duk_require_object(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void *duk_require_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_require_buffer_data(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void *duk_require_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_c_function duk_require_c_function(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_context *duk_require_context(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_require_function(duk_context *ctx, duk_idx_t idx);\n#define duk_require_callable(ctx,idx) \\\n\tduk_require_function((ctx), (idx))\nDUK_EXTERNAL_DECL void duk_require_constructor_call(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_require_constructable(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void *duk_require_heapptr(duk_context *ctx, duk_idx_t idx);\n\n/* Symbols are object coercible and covered by DUK_TYPE_MASK_STRING. */\n#define duk_require_object_coercible(ctx,idx) \\\n\t((void) duk_check_type_mask((ctx), (idx), DUK_TYPE_MASK_BOOLEAN | \\\n\t                                            DUK_TYPE_MASK_NUMBER | \\\n\t                                            DUK_TYPE_MASK_STRING | \\\n\t                                            DUK_TYPE_MASK_OBJECT | \\\n\t                                            DUK_TYPE_MASK_BUFFER | \\\n\t                                            DUK_TYPE_MASK_POINTER | \\\n\t                                            DUK_TYPE_MASK_LIGHTFUNC | \\\n\t                                            DUK_TYPE_MASK_THROW))\n\n/*\n *  Coercion operations: in-place coercion, return coerced value where\n *  applicable.  If index is invalid, throw error.  Some coercions may\n *  throw an expected error (e.g. from a toString() or valueOf() call)\n *  or an internal error (e.g. from out of memory).\n */\n\nDUK_EXTERNAL_DECL void duk_to_undefined(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_to_null(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_to_boolean(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_double_t duk_to_number(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int_t duk_to_int(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint_t duk_to_uint(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_int32_t duk_to_int32(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint32_t duk_to_uint32(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_uint16_t duk_to_uint16(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_to_string(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL void *duk_to_buffer_raw(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size, duk_uint_t flags);\nDUK_EXTERNAL_DECL void *duk_to_pointer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_to_object(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_to_primitive(duk_context *ctx, duk_idx_t idx, duk_int_t hint);\n\n#define DUK_BUF_MODE_FIXED      0   /* internal: request fixed buffer result */\n#define DUK_BUF_MODE_DYNAMIC    1   /* internal: request dynamic buffer result */\n#define DUK_BUF_MODE_DONTCARE   2   /* internal: don't care about fixed/dynamic nature */\n\n#define duk_to_buffer(ctx,idx,out_size) \\\n\tduk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_DONTCARE)\n#define duk_to_fixed_buffer(ctx,idx,out_size) \\\n\tduk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_FIXED)\n#define duk_to_dynamic_buffer(ctx,idx,out_size) \\\n\tduk_to_buffer_raw((ctx), (idx), (out_size), DUK_BUF_MODE_DYNAMIC)\n\n/* safe variants of a few coercion operations */\nDUK_EXTERNAL_DECL const char *duk_safe_to_lstring(duk_context *ctx, duk_idx_t idx, duk_size_t *out_len);\nDUK_EXTERNAL_DECL const char *duk_to_stacktrace(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_safe_to_stacktrace(duk_context *ctx, duk_idx_t idx);\n#define duk_safe_to_string(ctx,idx) \\\n\tduk_safe_to_lstring((ctx), (idx), NULL)\n\n/*\n *  Value length\n */\n\nDUK_EXTERNAL_DECL duk_size_t duk_get_length(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_length(duk_context *ctx, duk_idx_t idx, duk_size_t len);\n#if 0\n/* duk_require_length()? */\n/* duk_opt_length()? */\n#endif\n\n/*\n *  Misc conversion\n */\n\nDUK_EXTERNAL_DECL const char *duk_base64_encode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_base64_decode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_hex_encode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_hex_decode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL const char *duk_json_encode(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_json_decode(duk_context *ctx, duk_idx_t idx);\n\nDUK_EXTERNAL_DECL const char *duk_buffer_to_string(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Buffer\n */\n\nDUK_EXTERNAL_DECL void *duk_resize_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t new_size);\nDUK_EXTERNAL_DECL void *duk_steal_buffer(duk_context *ctx, duk_idx_t idx, duk_size_t *out_size);\nDUK_EXTERNAL_DECL void duk_config_buffer(duk_context *ctx, duk_idx_t idx, void *ptr, duk_size_t len);\n\n/*\n *  Property access\n *\n *  The basic function assumes key is on stack.  The _(l)string variant takes\n *  a C string as a property name; the _literal variant takes a C literal.\n *  The _index variant takes an array index as a property name (e.g. 123 is\n *  equivalent to the key \"123\").  The _heapptr variant takes a raw, borrowed\n *  heap pointer.\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_get_prop_literal(ctx,obj_idx,key)  duk_get_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_get_prop_literal(ctx,obj_idx,key)  duk_get_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_put_prop_literal(ctx,obj_idx,key)  duk_put_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_put_prop_literal(ctx,obj_idx,key)  duk_put_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_del_prop_literal(ctx,obj_idx,key)  duk_del_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_del_prop_literal(ctx,obj_idx,key)  duk_del_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_del_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_string(duk_context *ctx, duk_idx_t obj_idx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_lstring(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_has_prop_literal(ctx,obj_idx,key)  duk_has_prop_string((ctx), (obj_idx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_literal_raw(duk_context *ctx, duk_idx_t obj_idx, const char *key, duk_size_t key_len);\n#define duk_has_prop_literal(ctx,obj_idx,key)  duk_has_prop_literal_raw((ctx), (obj_idx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_index(duk_context *ctx, duk_idx_t obj_idx, duk_uarridx_t arr_idx);\nDUK_EXTERNAL_DECL duk_bool_t duk_has_prop_heapptr(duk_context *ctx, duk_idx_t obj_idx, void *ptr);\n\nDUK_EXTERNAL_DECL void duk_get_prop_desc(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags);\nDUK_EXTERNAL_DECL void duk_def_prop(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t flags);\n\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_string(duk_context *ctx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_get_global_literal(ctx,key)  duk_get_global_string((ctx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_literal_raw(duk_context *ctx, const char *key, duk_size_t key_len);\n#define duk_get_global_literal(ctx,key)  duk_get_global_literal_raw((ctx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_get_global_heapptr(duk_context *ctx, void *ptr);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_string(duk_context *ctx, const char *key);\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_lstring(duk_context *ctx, const char *key, duk_size_t key_len);\n#if defined(DUK_USE_PREFER_SIZE)\n#define duk_put_global_literal(ctx,key)  duk_put_global_string((ctx), (key))\n#else\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_literal_raw(duk_context *ctx, const char *key, duk_size_t key_len);\n#define duk_put_global_literal(ctx,key)  duk_put_global_literal_raw((ctx), (key), sizeof((key)) - 1U)\n#endif\nDUK_EXTERNAL_DECL duk_bool_t duk_put_global_heapptr(duk_context *ctx, void *ptr);\n\n/*\n *  Inspection\n */\n\nDUK_EXTERNAL_DECL void duk_inspect_value(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_inspect_callstack_entry(duk_context *ctx, duk_int_t level);\n\n/*\n *  Object prototype\n */\n\nDUK_EXTERNAL_DECL void duk_get_prototype(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_prototype(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Object finalizer\n */\n\nDUK_EXTERNAL_DECL void duk_get_finalizer(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_finalizer(duk_context *ctx, duk_idx_t idx);\n\n/*\n *  Global object\n */\n\nDUK_EXTERNAL_DECL void duk_set_global_object(duk_context *ctx);\n\n/*\n *  Duktape/C function magic value\n */\n\nDUK_EXTERNAL_DECL duk_int_t duk_get_magic(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL void duk_set_magic(duk_context *ctx, duk_idx_t idx, duk_int_t magic);\nDUK_EXTERNAL_DECL duk_int_t duk_get_current_magic(duk_context *ctx);\n\n/*\n *  Module helpers: put multiple function or constant properties\n */\n\nDUK_EXTERNAL_DECL void duk_put_function_list(duk_context *ctx, duk_idx_t obj_idx, const duk_function_list_entry *funcs);\nDUK_EXTERNAL_DECL void duk_put_number_list(duk_context *ctx, duk_idx_t obj_idx, const duk_number_list_entry *numbers);\n\n/*\n *  Object operations\n */\n\nDUK_EXTERNAL_DECL void duk_compact(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL void duk_enum(duk_context *ctx, duk_idx_t obj_idx, duk_uint_t enum_flags);\nDUK_EXTERNAL_DECL duk_bool_t duk_next(duk_context *ctx, duk_idx_t enum_idx, duk_bool_t get_value);\nDUK_EXTERNAL_DECL void duk_seal(duk_context *ctx, duk_idx_t obj_idx);\nDUK_EXTERNAL_DECL void duk_freeze(duk_context *ctx, duk_idx_t obj_idx);\n\n/*\n *  String manipulation\n */\n\nDUK_EXTERNAL_DECL void duk_concat(duk_context *ctx, duk_idx_t count);\nDUK_EXTERNAL_DECL void duk_join(duk_context *ctx, duk_idx_t count);\nDUK_EXTERNAL_DECL void duk_decode_string(duk_context *ctx, duk_idx_t idx, duk_decode_char_function callback, void *udata);\nDUK_EXTERNAL_DECL void duk_map_string(duk_context *ctx, duk_idx_t idx, duk_map_char_function callback, void *udata);\nDUK_EXTERNAL_DECL void duk_substring(duk_context *ctx, duk_idx_t idx, duk_size_t start_char_offset, duk_size_t end_char_offset);\nDUK_EXTERNAL_DECL void duk_trim(duk_context *ctx, duk_idx_t idx);\nDUK_EXTERNAL_DECL duk_codepoint_t duk_char_code_at(duk_context *ctx, duk_idx_t idx, duk_size_t char_offset);\n\n/*\n *  ECMAScript operators\n */\n\nDUK_EXTERNAL_DECL duk_bool_t duk_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL duk_bool_t duk_strict_equals(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL duk_bool_t duk_samevalue(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\nDUK_EXTERNAL_DECL duk_bool_t duk_instanceof(duk_context *ctx, duk_idx_t idx1, duk_idx_t idx2);\n\n/*\n *  Random\n */\n\nDUK_EXTERNAL_DECL duk_double_t duk_random(duk_context *ctx);\n\n/*\n *  Function (method) calls\n */\n\nDUK_EXTERNAL_DECL void duk_call(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL void duk_call_method(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL void duk_call_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pcall(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pcall_method(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pcall_prop(duk_context *ctx, duk_idx_t obj_idx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL void duk_new(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_pnew(duk_context *ctx, duk_idx_t nargs);\nDUK_EXTERNAL_DECL duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, void *udata, duk_idx_t nargs, duk_idx_t nrets);\n\n/*\n *  Thread management\n */\n\n/* There are currently no native functions to yield/resume, due to the internal\n * limitations on coroutine handling.  These will be added later.\n */\n\n/*\n *  Compilation and evaluation\n */\n\nDUK_EXTERNAL_DECL duk_int_t duk_eval_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags);\nDUK_EXTERNAL_DECL duk_int_t duk_compile_raw(duk_context *ctx, const char *src_buffer, duk_size_t src_length, duk_uint_t flags);\n\n/* plain */\n#define duk_eval(ctx)  \\\n\t((void) duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOFILENAME))\n\n#define duk_eval_noresult(ctx)  \\\n\t((void) duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval(ctx)  \\\n\t(duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_noresult(ctx)  \\\n\t(duk_eval_raw((ctx), NULL, 0, 1 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile(ctx,flags)  \\\n\t((void) duk_compile_raw((ctx), NULL, 0, 2 /*args*/ | (flags)))\n\n#define duk_pcompile(ctx,flags)  \\\n\t(duk_compile_raw((ctx), NULL, 0, 2 /*args*/ | (flags) | DUK_COMPILE_SAFE))\n\n/* string */\n#define duk_eval_string(ctx,src)  \\\n\t((void) duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_eval_string_noresult(ctx,src)  \\\n\t((void) duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_string(ctx,src)  \\\n\t(duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_string_noresult(ctx,src)  \\\n\t(duk_eval_raw((ctx), (src), 0, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_string(ctx,flags,src)  \\\n\t((void) duk_compile_raw((ctx), (src), 0, 0 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_string_filename(ctx,flags,src)  \\\n\t((void) duk_compile_raw((ctx), (src), 0, 1 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN))\n\n#define duk_pcompile_string(ctx,flags,src)  \\\n\t(duk_compile_raw((ctx), (src), 0, 0 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN | DUK_COMPILE_NOFILENAME))\n\n#define duk_pcompile_string_filename(ctx,flags,src)  \\\n\t(duk_compile_raw((ctx), (src), 0, 1 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN))\n\n/* lstring */\n#define duk_eval_lstring(ctx,buf,len)  \\\n\t((void) duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME))\n\n#define duk_eval_lstring_noresult(ctx,buf,len)  \\\n\t((void) duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_lstring(ctx,buf,len)  \\\n\t(duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_NOSOURCE | DUK_COMPILE_SAFE | DUK_COMPILE_NOFILENAME))\n\n#define duk_peval_lstring_noresult(ctx,buf,len)  \\\n\t(duk_eval_raw((ctx), buf, len, 0 /*args*/ | DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NORESULT | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_lstring(ctx,flags,buf,len)  \\\n\t((void) duk_compile_raw((ctx), buf, len, 0 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME))\n\n#define duk_compile_lstring_filename(ctx,flags,buf,len)  \\\n\t((void) duk_compile_raw((ctx), buf, len, 1 /*args*/ | (flags) | DUK_COMPILE_NOSOURCE))\n\n#define duk_pcompile_lstring(ctx,flags,buf,len)  \\\n\t(duk_compile_raw((ctx), buf, len, 0 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_NOFILENAME))\n\n#define duk_pcompile_lstring_filename(ctx,flags,buf,len)  \\\n\t(duk_compile_raw((ctx), buf, len, 1 /*args*/ | (flags) | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE))\n\n/*\n *  Bytecode load/dump\n */\n\nDUK_EXTERNAL_DECL void duk_dump_function(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_load_function(duk_context *ctx);\n\n/*\n *  Debugging\n */\n\nDUK_EXTERNAL_DECL void duk_push_context_dump(duk_context *ctx);\n\n/*\n *  Debugger (debug protocol)\n */\n\nDUK_EXTERNAL_DECL void duk_debugger_attach(duk_context *ctx,\n                                           duk_debug_read_function read_cb,\n                                           duk_debug_write_function write_cb,\n                                           duk_debug_peek_function peek_cb,\n                                           duk_debug_read_flush_function read_flush_cb,\n                                           duk_debug_write_flush_function write_flush_cb,\n                                           duk_debug_request_function request_cb,\n                                           duk_debug_detached_function detached_cb,\n                                           void *udata);\nDUK_EXTERNAL_DECL void duk_debugger_detach(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_debugger_cooperate(duk_context *ctx);\nDUK_EXTERNAL_DECL duk_bool_t duk_debugger_notify(duk_context *ctx, duk_idx_t nvalues);\nDUK_EXTERNAL_DECL void duk_debugger_pause(duk_context *ctx);\n\n/*\n *  Time handling\n */\n\nDUK_EXTERNAL_DECL duk_double_t duk_get_now(duk_context *ctx);\nDUK_EXTERNAL_DECL void duk_time_to_components(duk_context *ctx, duk_double_t timeval, duk_time_components *comp);\nDUK_EXTERNAL_DECL duk_double_t duk_components_to_time(duk_context *ctx, duk_time_components *comp);\n\n/*\n *  Date provider related constants\n *\n *  NOTE: These are \"semi public\" - you should only use these if you write\n *  your own platform specific Date provider, see doc/datetime.rst.\n */\n\n/* Millisecond count constants. */\n#define DUK_DATE_MSEC_SECOND          1000L\n#define DUK_DATE_MSEC_MINUTE          (60L * 1000L)\n#define DUK_DATE_MSEC_HOUR            (60L * 60L * 1000L)\n#define DUK_DATE_MSEC_DAY             (24L * 60L * 60L * 1000L)\n\n/* ECMAScript date range is 100 million days from Epoch:\n * > 100e6 * 24 * 60 * 60 * 1000  // 100M days in millisecs\n * 8640000000000000\n * (= 8.64e15)\n */\n#define DUK_DATE_MSEC_100M_DAYS         (8.64e15)\n#define DUK_DATE_MSEC_100M_DAYS_LEEWAY  (8.64e15 + 24 * 3600e3)\n\n/* ECMAScript year range:\n * > new Date(100e6 * 24 * 3600e3).toISOString()\n * '+275760-09-13T00:00:00.000Z'\n * > new Date(-100e6 * 24 * 3600e3).toISOString()\n * '-271821-04-20T00:00:00.000Z'\n */\n#define DUK_DATE_MIN_ECMA_YEAR     (-271821L)\n#define DUK_DATE_MAX_ECMA_YEAR     275760L\n\n/* Part indices for internal breakdowns.  Part order from DUK_DATE_IDX_YEAR\n * to DUK_DATE_IDX_MILLISECOND matches argument ordering of ECMAScript API\n * calls (like Date constructor call).  Some functions in duk_bi_date.c\n * depend on the specific ordering, so change with care.  16 bits are not\n * enough for all parts (year, specifically).\n *\n * Must be in-sync with genbuiltins.py.\n */\n#define DUK_DATE_IDX_YEAR           0  /* year */\n#define DUK_DATE_IDX_MONTH          1  /* month: 0 to 11 */\n#define DUK_DATE_IDX_DAY            2  /* day within month: 0 to 30 */\n#define DUK_DATE_IDX_HOUR           3\n#define DUK_DATE_IDX_MINUTE         4\n#define DUK_DATE_IDX_SECOND         5\n#define DUK_DATE_IDX_MILLISECOND    6\n#define DUK_DATE_IDX_WEEKDAY        7  /* weekday: 0 to 6, 0=sunday, 1=monday, etc */\n#define DUK_DATE_IDX_NUM_PARTS      8\n\n/* Internal API call flags, used for various functions in duk_bi_date.c.\n * Certain flags are used by only certain functions, but since the flags\n * don't overlap, a single flags value can be passed around to multiple\n * functions.\n *\n * The unused top bits of the flags field are also used to pass values\n * to helpers (duk__get_part_helper() and duk__set_part_helper()).\n *\n * Must be in-sync with genbuiltins.py.\n */\n\n/* NOTE: when writing a Date provider you only need a few specific\n * flags from here, the rest are internal.  Avoid using anything you\n * don't need.\n */\n\n#define DUK_DATE_FLAG_NAN_TO_ZERO          (1 << 0)  /* timeval breakdown: internal time value NaN -> zero */\n#define DUK_DATE_FLAG_NAN_TO_RANGE_ERROR   (1 << 1)  /* timeval breakdown: internal time value NaN -> RangeError (toISOString) */\n#define DUK_DATE_FLAG_ONEBASED             (1 << 2)  /* timeval breakdown: convert month and day-of-month parts to one-based (default is zero-based) */\n#define DUK_DATE_FLAG_EQUIVYEAR            (1 << 3)  /* timeval breakdown: replace year with equivalent year in the [1971,2037] range for DST calculations */\n#define DUK_DATE_FLAG_LOCALTIME            (1 << 4)  /* convert time value to local time */\n#define DUK_DATE_FLAG_SUB1900              (1 << 5)  /* getter: subtract 1900 from year when getting year part */\n#define DUK_DATE_FLAG_TOSTRING_DATE        (1 << 6)  /* include date part in string conversion result */\n#define DUK_DATE_FLAG_TOSTRING_TIME        (1 << 7)  /* include time part in string conversion result */\n#define DUK_DATE_FLAG_TOSTRING_LOCALE      (1 << 8)  /* use locale specific formatting if available */\n#define DUK_DATE_FLAG_TIMESETTER           (1 << 9)  /* setter: call is a time setter (affects hour, min, sec, ms); otherwise date setter (affects year, month, day-in-month) */\n#define DUK_DATE_FLAG_YEAR_FIXUP           (1 << 10) /* setter: perform 2-digit year fixup (00...99 -> 1900...1999) */\n#define DUK_DATE_FLAG_SEP_T                (1 << 11) /* string conversion: use 'T' instead of ' ' as a separator */\n#define DUK_DATE_FLAG_VALUE_SHIFT          12        /* additional values begin at bit 12 */\n\n/*\n *  ROM pointer compression\n */\n\n/* Support array for ROM pointer compression.  Only declared when ROM\n * pointer compression is active.\n */\n#if defined(DUK_USE_ROM_OBJECTS) && defined(DUK_USE_HEAPPTR16)\nDUK_EXTERNAL_DECL const void * const duk_rom_compressed_pointers[];\n#endif\n\n/*\n *  C++ name mangling\n */\n\n#if defined(__cplusplus)\n/* end 'extern \"C\"' wrapper */\n}\n#endif\n\n/*\n *  END PUBLIC API\n */\n\n#endif  /* DUKTAPE_H_INCLUDED */\n"
  },
  {
    "path": "react_juce/duktape/tools/combine_src.py",
    "content": "#!/usr/bin/env python2\n#\n#  Combine a set of a source files into a single C file.\n#\n#  Overview of the process:\n#\n#    * Parse user supplied C files.  Add automatic #undefs at the end\n#      of each C file to avoid defines bleeding from one file to another.\n#\n#    * Combine the C files in specified order.  If sources have ordering\n#      dependencies (depends on application), order may matter.\n#\n#    * Process #include statements in the combined source, categorizing\n#      them either as \"internal\" (found in specified include path) or\n#      \"external\".  Internal includes, unless explicitly excluded, are\n#      inlined into the result while extenal includes are left as is.\n#      Duplicate internal #include statements are replaced with a comment.\n#\n#  At every step, source and header lines are represented with explicit\n#  line objects which keep track of original filename and line.  The\n#  output contains #line directives, if requested, to ensure error\n#  throwing and other diagnostic info will work in a useful manner when\n#  deployed.  It's also possible to generate a combined source with no\n#  #line directives.\n#\n#  Making the process deterministic is important, so that if users have\n#  diffs that they apply to the combined source, such diffs would apply\n#  for as long as possible.\n#\n#  Limitations and notes:\n#\n#    * While there are automatic #undef's for #define's introduced in each\n#      C file, it's not possible to \"undefine\" structs, unions, etc.  If\n#      there are structs/unions/typedefs with conflicting names, these\n#      have to be resolved in the source files first.\n#\n#    * Because duplicate #include statements are suppressed, currently\n#      assumes #include statements are not conditional.\n#\n#    * A system header might be #include'd in multiple source files with\n#      different feature defines (like _BSD_SOURCE).  Because the #include\n#      file will only appear once in the resulting source, the first\n#      occurrence wins.  The result may not work correctly if the feature\n#      defines must actually be different between two or more source files.\n#\n\nimport logging\nimport sys\nlogging.basicConfig(level=logging.INFO, stream=sys.stdout, format='%(name)-21s %(levelname)-7s %(message)s')\nlogger = logging.getLogger('combine_src.py')\nlogger.setLevel(logging.INFO)\n\nimport os\nimport re\nimport json\nimport optparse\nimport logging\n\n# Include path for finding include files which are amalgamated.\ninclude_paths = []\n\n# Include files specifically excluded from being inlined.\ninclude_excluded = []\n\nclass File:\n    filename_full = None\n    filename = None\n    lines = None\n\n    def __init__(self, filename, lines):\n        self.filename = os.path.basename(filename)\n        self.filename_full = filename\n        self.lines = lines\n\nclass Line:\n    filename_full = None\n    filename = None\n    lineno = None\n    data = None\n\n    def __init__(self, filename, lineno, data):\n        self.filename = os.path.basename(filename)\n        self.filename_full = filename\n        self.lineno = lineno\n        self.data = data\n\ndef readFile(filename):\n    lines = []\n\n    with open(filename, 'rb') as f:\n        lineno = 0\n        for line in f:\n            lineno += 1\n            if len(line) > 0 and line[-1] == '\\n':\n                line = line[:-1]\n            lines.append(Line(filename, lineno, line))\n\n    return File(filename, lines)\n\ndef lookupInclude(incfn):\n    re_sep = re.compile(r'/|\\\\')\n\n    inccomp = re.split(re_sep, incfn)  # split include path, support / and \\\n\n    for path in include_paths:\n        fn = apply(os.path.join, [ path ] + inccomp)\n        if os.path.exists(fn):\n            return fn  # Return full path to first match\n\n    return None\n\ndef addAutomaticUndefs(f):\n    defined = {}\n\n    re_def = re.compile(r'#define\\s+(\\w+).*$')\n    re_undef = re.compile(r'#undef\\s+(\\w+).*$')\n\n    for line in f.lines:\n        m = re_def.match(line.data)\n        if m is not None:\n            #logger.debug('DEFINED: %s' % repr(m.group(1)))\n            defined[m.group(1)] = True\n        m = re_undef.match(line.data)\n        if m is not None:\n            # Could just ignore #undef's here: we'd then emit\n            # reliable #undef's (though maybe duplicates) at\n            # the end.\n            #logger.debug('UNDEFINED: %s' % repr(m.group(1)))\n            if defined.has_key(m.group(1)):\n                del defined[m.group(1)]\n\n    # Undefine anything that seems to be left defined.  This not a 100%\n    # process because some #undef's might be conditional which we don't\n    # track at the moment.  Note that it's safe to #undef something that's\n    # not defined.\n\n    keys = sorted(defined.keys())  # deterministic order\n    if len(keys) > 0:\n        #logger.debug('STILL DEFINED: %r' % repr(defined.keys()))\n        f.lines.append(Line(f.filename, len(f.lines) + 1, ''))\n        f.lines.append(Line(f.filename, len(f.lines) + 1, '/* automatic undefs */'))\n        for k in keys:\n            logger.debug('automatic #undef for ' + k)\n            f.lines.append(Line(f.filename, len(f.lines) + 1, '#undef %s' % k))\n\ndef createCombined(files, prologue_filename, line_directives):\n    res = []\n    line_map = []   # indicate combined source lines where uncombined file/line would change\n    metadata = {\n        'line_map': line_map\n    }\n\n    emit_state = [ None, None ]  # curr_filename, curr_lineno\n\n    def emit(line):\n        if isinstance(line, (str, unicode)):\n            res.append(line)\n            emit_state[1] += 1\n        else:\n            if line.filename != emit_state[0] or line.lineno != emit_state[1]:\n                if line_directives:\n                    res.append('#line %d \"%s\"' % (line.lineno, line.filename))\n                line_map.append({ 'original_file': line.filename,\n                                  'original_line': line.lineno,\n                                  'combined_line': len(res) + 1 })\n            res.append(line.data)\n            emit_state[0] = line.filename\n            emit_state[1] = line.lineno + 1\n\n    included = {}  # headers already included\n\n    if prologue_filename is not None:\n        with open(prologue_filename, 'rb') as f:\n            for line in f.read().split('\\n'):\n                res.append(line)\n\n    re_inc = re.compile(r'^#include\\s+(<|\\\")(.*?)(>|\\\").*$')\n\n    # Process a file, appending it to the result; the input may be a\n    # source or an include file.  #include directives are handled\n    # recursively.\n    def processFile(f):\n        logger.debug('Process file: ' + f.filename)\n\n        for line in f.lines:\n            if not line.data.startswith('#include'):\n                emit(line)\n                continue\n\n            m = re_inc.match(line.data)\n            if m is None:\n                raise Exception('Couldn\\'t match #include line: %s' % repr(line.data))\n            incpath = m.group(2)\n            if incpath in include_excluded:\n                # Specific include files excluded from the\n                # inlining / duplicate suppression process.\n                emit(line)  # keep as is\n                continue\n\n            if included.has_key(incpath):\n                # We suppress duplicate includes, both internal and\n                # external, based on the assumption that includes are\n                # not behind #if defined() checks.  This is the case for\n                # Duktape (except for the include files excluded).\n                emit('/* #include %s -> already included */' % incpath)\n                continue\n            included[incpath] = True\n\n            # An include file is considered \"internal\" and is amalgamated\n            # if it is found in the include path provided by the user.\n\n            incfile = lookupInclude(incpath)\n            if incfile is not None:\n                logger.debug('Include considered internal: %s -> %s' % (repr(line.data), repr(incfile)))\n                emit('/* #include %s */' % incpath)\n                processFile(readFile(incfile))\n            else:\n                logger.debug('Include considered external: %s' % repr(line.data))\n                emit(line)  # keep as is\n\n    for f in files:\n        processFile(f)\n\n    return '\\n'.join(res) + '\\n', metadata\n\ndef main():\n    global include_paths, include_excluded\n\n    parser = optparse.OptionParser()\n    parser.add_option('--include-path', dest='include_paths', action='append', default=[], help='Include directory for \"internal\" includes, can be specified multiple times')\n    parser.add_option('--include-exclude', dest='include_excluded', action='append', default=[], help='Include file excluded from being considered internal (even if found in include dirs)')\n    parser.add_option('--prologue', dest='prologue', help='Prologue to prepend to start of file')\n    parser.add_option('--output-source', dest='output_source', help='Output source filename')\n    parser.add_option('--output-metadata', dest='output_metadata', help='Output metadata filename')\n    parser.add_option('--line-directives', dest='line_directives', action='store_true', default=False, help='Use #line directives in combined source')\n    parser.add_option('--quiet', dest='quiet', action='store_true', default=False, help='Suppress info messages (show warnings)')\n    parser.add_option('--verbose', dest='verbose', action='store_true', default=False, help='Show verbose debug messages')\n    (opts, args) = parser.parse_args()\n\n    assert(opts.include_paths is not None)\n    include_paths = opts.include_paths  # global for easy access\n    include_excluded = opts.include_excluded\n    assert(opts.output_source)\n    assert(opts.output_metadata)\n\n    # Log level.\n    if opts.quiet:\n        logger.setLevel(logging.WARNING)\n    elif opts.verbose:\n        logger.setLevel(logging.DEBUG)\n\n    # Read input files, add automatic #undefs\n    sources = args\n    files = []\n    for fn in sources:\n        res = readFile(fn)\n        logger.debug('Add automatic undefs for: ' + fn)\n        addAutomaticUndefs(res)\n        files.append(res)\n\n    combined_source, metadata = \\\n        createCombined(files, opts.prologue, opts.line_directives)\n    with open(opts.output_source, 'wb') as f:\n        f.write(combined_source)\n    with open(opts.output_metadata, 'wb') as f:\n        f.write(json.dumps(metadata, indent=4))\n\n    logger.info('Combined %d source files, %d bytes written to %s' % (len(files), len(combined_source), opts.output_source))\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/tools/configure.py",
    "content": "#!/usr/bin/env python2\n#\n#  Prepare a duk_config.h and combined/separate sources for compilation,\n#  given user supplied config options, built-in metadata, Unicode tables, etc.\n#\n#  This is intended to be the main tool application build scripts would use\n#  before their build step, so convenient, versions, Python compatibility,\n#  etc all matter.\n#\n#  When obsoleting options, leave the option definitions behind (with\n#  help=optparse.SUPPRESS_HELP) and give useful suggestions when obsolete\n#  options are used.  This makes it easier for users to fix their build\n#  scripts.\n#\n\nimport logging\nimport sys\nlogging.basicConfig(level=logging.INFO, stream=sys.stdout, format='%(name)-21s %(levelname)-7s %(message)s')\nlogger = logging.getLogger('configure.py')\nlogger.setLevel(logging.INFO)\n\nimport os\nimport re\nimport shutil\nimport glob\nimport optparse\nimport tarfile\nimport json\nimport yaml\nimport tempfile\nimport subprocess\nimport atexit\n\nimport genconfig\n\n# Helpers\n\ndef exec_get_stdout(cmd, input=None, default=None, print_stdout=False):\n    try:\n        proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n        ret = proc.communicate(input=input)\n        if print_stdout:\n            sys.stdout.write(ret[0])\n            sys.stdout.flush()\n        if proc.returncode != 0:\n            sys.stdout.write(ret[1])  # print stderr on error\n            sys.stdout.flush()\n            if default is not None:\n                logger.info('WARNING: command %r failed, return default' % cmd)\n                return default\n            raise Exception('command failed, return code %d: %r' % (proc.returncode, cmd))\n        return ret[0]\n    except:\n        if default is not None:\n            logger.info('WARNING: command %r failed, return default' % cmd)\n            return default\n        raise\n\ndef exec_print_stdout(cmd, input=None):\n    ret = exec_get_stdout(cmd, input=input, print_stdout=True)\n\ndef mkdir(path):\n    os.mkdir(path)\n\ndef copy_file(src, dst):\n    with open(src, 'rb') as f_in:\n        with open(dst, 'wb') as f_out:\n            f_out.write(f_in.read())\n\ndef copy_files(filelist, srcdir, dstdir):\n    for i in filelist:\n        copy_file(os.path.join(srcdir, i), os.path.join(dstdir, i))\n\ndef copy_and_replace(src, dst, rules):\n    # Read and write separately to allow in-place replacement\n    keys = sorted(rules.keys())\n    res = []\n    with open(src, 'rb') as f_in:\n        for line in f_in:\n            for k in keys:\n                line = line.replace(k, rules[k])\n            res.append(line)\n    with open(dst, 'wb') as f_out:\n        f_out.write(''.join(res))\n\ndef copy_and_cquote(src, dst):\n    with open(src, 'rb') as f_in:\n        with open(dst, 'wb') as f_out:\n            f_out.write('/*\\n')\n            for line in f_in:\n                line = line.decode('utf-8')\n                f_out.write(' *  ')\n                for c in line:\n                    if (ord(c) >= 0x20 and ord(c) <= 0x7e) or (c in '\\x0a'):\n                        f_out.write(c.encode('ascii'))\n                    else:\n                        f_out.write('\\\\u%04x' % ord(c))\n            f_out.write(' */\\n')\n\ndef read_file(src, strip_last_nl=False):\n    with open(src, 'rb') as f:\n        data = f.read()\n        if len(data) > 0 and data[-1] == '\\n':\n            data = data[:-1]\n        return data\n\ndef delete_matching_files(dirpath, cb):\n    for fn in os.listdir(dirpath):\n        if os.path.isfile(os.path.join(dirpath, fn)) and cb(fn):\n            logger.debug('Deleting %r' % os.path.join(dirpath, fn))\n            os.unlink(os.path.join(dirpath, fn))\n\ndef create_targz(dstfile, filelist):\n    # https://docs.python.org/2/library/tarfile.html#examples\n\n    def _add(tf, fn):  # recursive add\n        logger.debug('Adding to tar: ' + fn)\n        if os.path.isdir(fn):\n            for i in sorted(os.listdir(fn)):\n                _add(tf, os.path.join(fn, i))\n        elif os.path.isfile(fn):\n            tf.add(fn)\n        else:\n            raise Exception('invalid file: %r' % fn)\n\n    with tarfile.open(dstfile, 'w:gz') as tf:\n        for fn in filelist:\n            _add(tf, fn)\n\ndef cstring(x):\n    return '\"' + x + '\"'  # good enough for now\n\n# DUK_VERSION is grepped from duktape.h.in: it is needed for the\n# public API and we want to avoid defining it in two places.\ndef get_duk_version(apiheader_filename):\n    r = re.compile(r'^#define\\s+DUK_VERSION\\s+(.*?)L?\\s*$')\n    with open(apiheader_filename, 'rb') as f:\n        for line in f:\n            m = r.match(line)\n            if m is not None:\n                duk_version = int(m.group(1))\n                duk_major = duk_version / 10000\n                duk_minor = (duk_version % 10000) / 100\n                duk_patch = duk_version % 100\n                duk_version_formatted = '%d.%d.%d' % (duk_major, duk_minor, duk_patch)\n                return duk_version, duk_major, duk_minor, duk_patch, duk_version_formatted\n\n    raise Exception('cannot figure out duktape version')\n\n# Python module check and friendly errors\n\ndef check_python_modules():\n    # dist.py doesn't need yaml but other dist utils will; check for it and\n    # warn if it is missing.\n    failed = False\n\n    def _warning(module, aptPackage, pipPackage):\n        sys.stderr.write('\\n')\n        sys.stderr.write('*** NOTE: Could not \"import %s\" needed for dist.  Install it using e.g.:\\n' % module)\n        sys.stderr.write('\\n')\n        sys.stderr.write('    # Linux\\n')\n        sys.stderr.write('    $ sudo apt-get install %s\\n' % aptPackage)\n        sys.stderr.write('\\n')\n        sys.stderr.write('    # Windows\\n')\n        sys.stderr.write('    > pip install %s\\n' % pipPackage)\n\n    try:\n        import yaml\n    except ImportError:\n        _warning('yaml', 'python-yaml', 'PyYAML')\n        failed = True\n\n    if failed:\n        sys.stderr.write('\\n')\n        raise Exception('Missing some required Python modules')\n\ncheck_python_modules()\n\n# Option parsing\n\ndef main():\n    parser = optparse.OptionParser(\n        usage='Usage: %prog [options]',\n        description='Prepare Duktape source files and a duk_config.h configuration header for compilation. ' + \\\n                    'Source files can be combined (amalgamated) or kept separate. ' + \\\n                    'See http://wiki.duktape.org/Configuring.html for examples.'\n    )\n\n    # Forced options from multiple sources are gathered into a shared list\n    # so that the override order remains the same as on the command line.\n    force_options_yaml = []\n    def add_force_option_yaml(option, opt, value, parser):\n        # XXX: check that YAML parses\n        force_options_yaml.append(value)\n    def add_force_option_file(option, opt, value, parser):\n        # XXX: check that YAML parses\n        with open(value, 'rb') as f:\n            force_options_yaml.append(f.read())\n    def add_force_option_define(option, opt, value, parser):\n        tmp = value.split('=')\n        if len(tmp) == 1:\n            doc = { tmp[0]: True }\n        elif len(tmp) == 2:\n            doc = { tmp[0]: tmp[1] }\n        else:\n            raise Exception('invalid option value: %r' % value)\n        force_options_yaml.append(yaml.safe_dump(doc))\n    def add_force_option_undefine(option, opt, value, parser):\n        tmp = value.split('=')\n        if len(tmp) == 1:\n            doc = { tmp[0]: False }\n        else:\n            raise Exception('invalid option value: %r' % value)\n        force_options_yaml.append(yaml.safe_dump(doc))\n\n    fixup_header_lines = []\n    def add_fixup_header_line(option, opt, value, parser):\n        fixup_header_lines.append(value)\n    def add_fixup_header_file(option, opt, value, parser):\n        with open(value, 'rb') as f:\n            for line in f:\n                if line[-1] == '\\n':\n                    line = line[:-1]\n                fixup_header_lines.append(line)\n\n    # Options for configure.py tool itself.\n    parser.add_option('--source-directory', dest='source_directory', default=None, help='Directory with raw input sources (defaulted based on configure.py script path)')\n    parser.add_option('--output-directory', dest='output_directory', default=None, help='Directory for output files (created automatically if it doesn\\'t exist, reused if safe)')\n    parser.add_option('--license-file', dest='license_file', default=None, help='Source for LICENSE.txt (defaulted based on configure.py script path)')\n    parser.add_option('--authors-file', dest='authors_file', default=None, help='Source for AUTHORS.rst (defaulted based on configure.py script path)')\n    parser.add_option('--git-commit', dest='git_commit', default=None, help='Force git commit hash')\n    parser.add_option('--git-describe', dest='git_describe', default=None, help='Force git describe')\n    parser.add_option('--git-branch', dest='git_branch', default=None, help='Force git branch name')\n    parser.add_option('--duk-dist-meta', dest='duk_dist_meta', default=None, help='duk_dist_meta.json to read git commit etc info from')\n\n    # Options for combining sources.\n    parser.add_option('--separate-sources', dest='separate_sources', action='store_true', default=False, help='Output separate sources instead of combined source (default is combined)')\n    parser.add_option('--line-directives', dest='line_directives', action='store_true', default=False, help='Output #line directives in combined source (default is false)')\n\n    # Options forwarded to genbuiltins.py.\n    parser.add_option('--rom-support', dest='rom_support', action='store_true', help='Add support for ROM strings/objects (increases duktape.c size considerably)')\n    parser.add_option('--rom-auto-lightfunc', dest='rom_auto_lightfunc', action='store_true', default=False, help='Convert ROM built-in function properties into lightfuncs automatically whenever possible')\n    parser.add_option('--user-builtin-metadata', dest='obsolete_builtin_metadata', default=None, help=optparse.SUPPRESS_HELP)\n    parser.add_option('--builtin-file', dest='builtin_files', metavar='FILENAME', action='append', default=[], help='Built-in string/object YAML metadata to be applied over default built-ins (multiple files may be given, applied in sequence)')\n\n    # Options for Unicode.\n    parser.add_option('--unicode-data', dest='unicode_data', default=None, help='Provide custom UnicodeData.txt')\n    parser.add_option('--special-casing', dest='special_casing', default=None, help='Provide custom SpecialCasing.txt')\n\n    # Options forwarded to genconfig.py.\n    genconfig.add_genconfig_optparse_options(parser)\n\n    # Log level options.\n    parser.add_option('--quiet', dest='quiet', action='store_true', default=False, help='Suppress info messages (show warnings)')\n    parser.add_option('--verbose', dest='verbose', action='store_true', default=False, help='Show verbose debug messages')\n\n    (opts, args) = parser.parse_args()\n    if len(args) > 0:\n        raise Exception('unexpected arguments: %r' % args)\n\n    if opts.obsolete_builtin_metadata is not None:\n        raise Exception('--user-builtin-metadata has been removed, use --builtin-file instead')\n\n    # Log level.\n    forward_loglevel = []\n    if opts.quiet:\n        logger.setLevel(logging.WARNING)\n        forward_loglevel = [ '--quiet' ]\n    elif opts.verbose:\n        logger.setLevel(logging.DEBUG)\n        forward_loglevel = [ '--verbose' ]\n\n    # Figure out directories, git info, etc\n\n    entry_cwd = os.getcwd()\n    script_path = sys.path[0]  # http://stackoverflow.com/questions/4934806/how-can-i-find-scripts-directory-with-python\n\n    def default_from_script_path(optname, orig, alternatives):\n        if orig is not None:\n            orig = os.path.abspath(orig)\n            if os.path.exists(orig):\n                logger.debug(optname + ' ' + orig)\n                return orig\n            else:\n                raise Exception('invalid argument to ' + optname)\n        for alt in alternatives:\n            cand = os.path.abspath(os.path.join(script_path, '..', alt))\n            if os.path.exists(cand):\n                logger.debug('default ' + optname + ' to ' + cand)\n                return cand\n        raise Exception('no ' + optname + ' and cannot default based on script path')\n\n    if opts.output_directory is None:\n        raise Exception('missing --output-directory')\n    opts.output_directory = os.path.abspath(opts.output_directory)\n    outdir = opts.output_directory\n\n    opts.source_directory = default_from_script_path('--source-directory', opts.source_directory, [ 'src-input' ])\n    srcdir = opts.source_directory\n\n    opts.config_metadata = default_from_script_path('--config-metadata', opts.config_metadata, [ 'config' ])\n\n    opts.license_file = default_from_script_path('--license-file', opts.license_file, [ 'LICENSE.txt' ])\n    license_file = opts.license_file\n\n    opts.authors_file = default_from_script_path('--authors-file', opts.authors_file, [ 'AUTHORS.rst' ])\n    authors_file = opts.authors_file\n\n    duk_dist_meta = None\n    if opts.duk_dist_meta is not None:\n        with open(opts.duk_dist_meta, 'rb') as f:\n            duk_dist_meta = json.loads(f.read())\n\n    duk_version, duk_major, duk_minor, duk_patch, duk_version_formatted = \\\n        get_duk_version(os.path.join(srcdir, 'duktape.h.in'))\n\n    git_commit = None\n    git_branch = None\n    git_describe = None\n\n    if duk_dist_meta is not None:\n        git_commit = duk_dist_meta['git_commit']\n        git_branch = duk_dist_meta['git_branch']\n        git_describe = duk_dist_meta['git_describe']\n\n    if opts.git_commit is not None:\n        git_commit = opts.git_commit\n    if opts.git_describe is not None:\n        git_describe = opts.git_describe\n    if opts.git_branch is not None:\n        git_branch = opts.git_branch\n\n    if git_commit is None:\n        logger.debug('Git commit not specified, autodetect from current directory')\n        git_commit = exec_get_stdout([ 'git', 'rev-parse', 'HEAD' ], default='external').strip()\n    if git_describe is None:\n        logger.debug('Git describe not specified, autodetect from current directory')\n        git_describe = exec_get_stdout([ 'git', 'describe', '--always', '--dirty' ], default='external').strip()\n    if git_branch is None:\n        logger.debug('Git branch not specified, autodetect from current directory')\n        git_branch = exec_get_stdout([ 'git', 'rev-parse', '--abbrev-ref', 'HEAD' ], default='external').strip()\n\n    git_commit = str(git_commit)\n    git_describe = str(git_describe)\n    git_branch = str(git_branch)\n\n    git_commit_cstring = cstring(git_commit)\n    git_describe_cstring = cstring(git_describe)\n    git_branch_cstring = cstring(git_branch)\n\n    if opts.unicode_data is None:\n        unicode_data = os.path.join(srcdir, 'UnicodeData.txt')\n    else:\n        unicode_data = opts.unicode_data\n    if opts.special_casing is None:\n        special_casing = os.path.join(srcdir, 'SpecialCasing.txt')\n    else:\n        special_casing = opts.special_casing\n\n    logger.info('Configuring Duktape version %s, commit %s, describe %s, branch %s' % \\\n                (duk_version_formatted, git_commit, git_describe, git_branch))\n    logger.info('  - source input directory: ' + opts.source_directory)\n    logger.info('  - license file: ' + opts.license_file)\n    logger.info('  - authors file: ' + opts.authors_file)\n    logger.info('  - config metadata directory: ' + opts.config_metadata)\n    logger.info('  - output directory: ' + opts.output_directory)\n\n    # Create output directory.  If the directory already exists, reuse it but\n    # only when it's safe to do so, i.e. it contains only known output files.\n    allow_outdir_reuse = True\n    outdir_whitelist = [ 'duk_config.h', 'duktape.c', 'duktape.h', 'duk_source_meta.json' ]\n    if os.path.exists(outdir):\n        if not allow_outdir_reuse:\n            raise Exception('configure target directory %s already exists, please delete it first' % repr(outdir))\n        for fn in os.listdir(outdir):\n            if fn == '.' or fn == '..' or (fn in outdir_whitelist and os.path.isfile(os.path.join(outdir, fn))):\n                continue\n            else:\n                raise Exception('configure target directory %s already exists, cannot reuse because it contains unknown files such as %s' % (repr(outdir), repr(fn)))\n        logger.info('Reusing output directory (already exists but contains only safe, known files)')\n        for fn in outdir_whitelist:\n            if os.path.isfile(os.path.join(outdir, fn)):\n                os.unlink(os.path.join(outdir, fn))\n    else:\n        logger.debug('Output directory doesn\\'t exist, create it')\n        os.mkdir(outdir)\n\n    # Temporary directory.\n    tempdir = tempfile.mkdtemp(prefix='tmp-duk-prepare-')\n    atexit.register(shutil.rmtree, tempdir)\n    mkdir(os.path.join(tempdir, 'src'))\n    logger.debug('Using temporary directory %r' % tempdir)\n\n    # Separate sources are mostly copied as is at present.\n    copy_files([\n        'duk_alloc_default.c',\n        'duk_api_internal.h',\n        'duk_api_stack.c',\n        'duk_api_heap.c',\n        'duk_api_buffer.c',\n        'duk_api_call.c',\n        'duk_api_codec.c',\n        'duk_api_compile.c',\n        'duk_api_bytecode.c',\n        'duk_api_inspect.c',\n        'duk_api_memory.c',\n        'duk_api_object.c',\n        'duk_api_random.c',\n        'duk_api_string.c',\n        'duk_api_time.c',\n        'duk_api_debug.c',\n        'duk_bi_array.c',\n        'duk_bi_boolean.c',\n        'duk_bi_buffer.c',\n        'duk_bi_date.c',\n        'duk_bi_date_unix.c',\n        'duk_bi_date_windows.c',\n        'duk_bi_duktape.c',\n        'duk_bi_encoding.c',\n        'duk_bi_error.c',\n        'duk_bi_function.c',\n        'duk_bi_global.c',\n        'duk_bi_json.c',\n        'duk_bi_math.c',\n        'duk_bi_number.c',\n        'duk_bi_object.c',\n        'duk_bi_performance.c',\n        'duk_bi_pointer.c',\n        'duk_bi_protos.h',\n        'duk_bi_reflect.c',\n        'duk_bi_regexp.c',\n        'duk_bi_string.c',\n        'duk_bi_promise.c',\n        'duk_bi_proxy.c',\n        'duk_bi_symbol.c',\n        'duk_bi_thread.c',\n        'duk_bi_thrower.c',\n        'duk_dblunion.h',\n        'duk_debug_fixedbuffer.c',\n        'duk_debug.h',\n        'duk_debug_macros.c',\n        'duk_debug_vsnprintf.c',\n        'duk_debugger.c',\n        'duk_debugger.h',\n        'duk_error_augment.c',\n        'duk_error.h',\n        'duk_error_longjmp.c',\n        'duk_error_macros.c',\n        'duk_error_misc.c',\n        'duk_error_throw.c',\n        'duk_forwdecl.h',\n        'duk_harray.h',\n        'duk_hboundfunc.h',\n        'duk_hbuffer_alloc.c',\n        'duk_hbuffer_assert.c',\n        'duk_hbuffer.h',\n        'duk_hbuffer_ops.c',\n        'duk_hbufobj.h',\n        'duk_hbufobj_misc.c',\n        'duk_hcompfunc.h',\n        'duk_heap_alloc.c',\n        'duk_heap.h',\n        'duk_heap_hashstring.c',\n        'duk_heaphdr.h',\n        'duk_heaphdr_assert.c',\n        'duk_heap_finalize.c',\n        'duk_heap_markandsweep.c',\n        'duk_heap_memory.c',\n        'duk_heap_misc.c',\n        'duk_heap_refcount.c',\n        'duk_heap_stringcache.c',\n        'duk_heap_stringtable.c',\n        'duk_hnatfunc.h',\n        'duk_hobject_alloc.c',\n        'duk_hobject_assert.c',\n        'duk_hobject_class.c',\n        'duk_hobject_enum.c',\n        'duk_hobject.h',\n        'duk_hobject_misc.c',\n        'duk_hobject_pc2line.c',\n        'duk_hobject_props.c',\n        'duk_hproxy.h',\n        'duk_hstring.h',\n        'duk_hstring_assert.c',\n        'duk_hstring_misc.c',\n        'duk_hthread_alloc.c',\n        'duk_hthread_builtins.c',\n        'duk_hthread.h',\n        'duk_hthread_misc.c',\n        'duk_hthread_stacks.c',\n        'duk_henv.h',\n        'duk_internal.h',\n        'duk_jmpbuf.h',\n        'duk_exception.h',\n        'duk_js_arith.c',\n        'duk_js_bytecode.h',\n        'duk_js_call.c',\n        'duk_js_compiler.c',\n        'duk_js_compiler.h',\n        'duk_js_executor.c',\n        'duk_js.h',\n        'duk_json.h',\n        'duk_js_ops.c',\n        'duk_js_var.c',\n        'duk_lexer.c',\n        'duk_lexer.h',\n        'duk_numconv.c',\n        'duk_numconv.h',\n        'duk_refcount.h',\n        'duk_regexp_compiler.c',\n        'duk_regexp_executor.c',\n        'duk_regexp.h',\n        'duk_tval.c',\n        'duk_tval.h',\n        'duk_unicode.h',\n        'duk_unicode_support.c',\n        'duk_unicode_tables.c',\n        'duk_util.h',\n        'duk_util_bitdecoder.c',\n        'duk_util_bitencoder.c',\n        'duk_util_hashbytes.c',\n        'duk_util_tinyrandom.c',\n        'duk_util_bufwriter.c',\n        'duk_util_double.c',\n        'duk_util_cast.c',\n        'duk_util_memory.c',\n        'duk_util_misc.c',\n        'duk_selftest.c',\n        'duk_selftest.h',\n        'duk_strings.h',\n        'duk_replacements.c',\n        'duk_replacements.h'\n    ], srcdir, os.path.join(tempdir, 'src'))\n\n    # Build temp versions of LICENSE.txt and AUTHORS.rst for embedding into\n    # autogenerated C/H files.\n\n    copy_and_cquote(license_file, os.path.join(tempdir, 'LICENSE.txt.tmp'))\n    copy_and_cquote(authors_file, os.path.join(tempdir, 'AUTHORS.rst.tmp'))\n\n    # Scan used stridx, bidx, config options, etc.\n\n    res = exec_get_stdout([\n        sys.executable,\n        os.path.join(script_path, 'scan_used_stridx_bidx.py')\n    ] + glob.glob(os.path.join(srcdir, '*.c')) \\\n      + glob.glob(os.path.join(srcdir, '*.h')) \\\n      + glob.glob(os.path.join(srcdir, '*.h.in'))\n    )\n    with open(os.path.join(tempdir, 'duk_used_stridx_bidx_defs.json.tmp'), 'wb') as f:\n        f.write(res)\n\n    # Create a duk_config.h.\n    # XXX: might be easier to invoke genconfig directly, but there are a few\n    # options which currently conflict (output file, git commit info, etc).\n    def forward_genconfig_options():\n        res = []\n        res += [ '--metadata', os.path.abspath(opts.config_metadata) ]  # rename option, --config-metadata => --metadata\n        if opts.platform is not None:\n            res += [ '--platform', opts.platform ]\n        if opts.compiler is not None:\n            res += [ '--compiler', opts.compiler ]\n        if opts.architecture is not None:\n            res += [ '--architecture', opts.architecture ]\n        if opts.c99_types_only:\n            res += [ '--c99-types-only' ]\n        if opts.dll:\n            res += [ '--dll' ]\n        if opts.support_feature_options:\n            res += [ '--support-feature-options' ]\n        if opts.emit_legacy_feature_check:\n            res += [ '--emit-legacy-feature-check' ]\n        if opts.emit_config_sanity_check:\n            res += [ '--emit-config-sanity-check' ]\n        if opts.omit_removed_config_options:\n            res += [ '--omit-removed-config-options' ]\n        if opts.omit_deprecated_config_options:\n            res += [ '--omit-deprecated-config-options' ]\n        if opts.omit_unused_config_options:\n            res += [ '--omit-unused-config-options' ]\n        if opts.add_active_defines_macro:\n            res += [ '--add-active-defines-macro' ]\n        if len(opts.force_options_yaml) > 0:\n            # Use temporary files so that large option sets don't create\n            # excessively large commands.\n            for idx,i in enumerate(opts.force_options_yaml):\n                tmpfn = os.path.join(tempdir, 'genconfig%d.yaml' % idx)\n                with open(tmpfn, 'wb') as f:\n                    f.write(i)\n                with open(tmpfn, 'rb') as f:\n                    logger.debug(f.read())\n                res += [ '--option-file', tmpfn ]\n        for i in opts.fixup_header_lines:\n            res += [ '--fixup-line', i ]\n        if not opts.sanity_strict:\n            res += [ '--sanity-warning' ]\n        if opts.use_cpp_warning:\n            res += [ '--use-cpp-warning' ]\n        return res\n\n    cmd = [\n        sys.executable, os.path.join(script_path, 'genconfig.py'),\n        '--output', os.path.join(tempdir, 'duk_config.h.tmp'),\n        '--output-active-options', os.path.join(tempdir, 'duk_config_active_options.json'),\n        '--git-commit', git_commit, '--git-describe', git_describe, '--git-branch', git_branch,\n        '--used-stridx-metadata', os.path.join(tempdir, 'duk_used_stridx_bidx_defs.json.tmp')\n    ]\n    cmd += forward_genconfig_options()\n    cmd += [\n        'duk-config-header'\n    ] + forward_loglevel\n    logger.debug(repr(cmd))\n    exec_print_stdout(cmd)\n\n    copy_file(os.path.join(tempdir, 'duk_config.h.tmp'), os.path.join(outdir, 'duk_config.h'))\n\n    # Build duktape.h from parts, with some git-related replacements.\n    # The only difference between single and separate file duktape.h\n    # is the internal DUK_SINGLE_FILE define.\n    #\n    # Newline after 'i \\':\n    # http://stackoverflow.com/questions/25631989/sed-insert-line-command-osx\n    copy_and_replace(os.path.join(srcdir, 'duktape.h.in'), os.path.join(tempdir, 'duktape.h'), {\n        '@DUK_SINGLE_FILE@': '#define DUK_SINGLE_FILE',\n        '@LICENSE_TXT@': read_file(os.path.join(tempdir, 'LICENSE.txt.tmp'), strip_last_nl=True),\n        '@AUTHORS_RST@': read_file(os.path.join(tempdir, 'AUTHORS.rst.tmp'), strip_last_nl=True),\n        '@DUK_VERSION_FORMATTED@': duk_version_formatted,\n        '@GIT_COMMIT@': git_commit,\n        '@GIT_COMMIT_CSTRING@': git_commit_cstring,\n        '@GIT_DESCRIBE@': git_describe,\n        '@GIT_DESCRIBE_CSTRING@': git_describe_cstring,\n        '@GIT_BRANCH@': git_branch,\n        '@GIT_BRANCH_CSTRING@': git_branch_cstring\n    })\n\n    if opts.separate_sources:\n        # keep the line so line numbers match between the two variant headers\n        copy_and_replace(os.path.join(tempdir, 'duktape.h'), os.path.join(outdir, 'duktape.h'), {\n            '#define DUK_SINGLE_FILE': '#undef DUK_SINGLE_FILE'\n        })\n    else:\n        copy_file(os.path.join(tempdir, 'duktape.h'), os.path.join(outdir, 'duktape.h'))\n\n    # Autogenerated strings and built-in files\n    #\n    # There are currently no profile specific variants of strings/builtins, but\n    # this will probably change when functions are added/removed based on profile.\n\n    cmd = [\n        sys.executable,\n        os.path.join(script_path, 'genbuiltins.py'),\n    ]\n    cmd += [\n        '--git-commit', git_commit,\n        '--git-branch', git_branch,\n        '--git-describe', git_describe,\n        '--duk-version', str(duk_version)\n    ]\n    cmd += [\n        '--used-stridx-metadata', os.path.join(tempdir, 'duk_used_stridx_bidx_defs.json.tmp'),\n        '--strings-metadata', os.path.join(srcdir, 'strings.yaml'),\n        '--objects-metadata', os.path.join(srcdir, 'builtins.yaml'),\n        '--active-options', os.path.join(tempdir, 'duk_config_active_options.json'),\n        '--out-header', os.path.join(tempdir, 'src', 'duk_builtins.h'),\n        '--out-source', os.path.join(tempdir, 'src', 'duk_builtins.c'),\n        '--out-metadata-json', os.path.join(tempdir, 'genbuiltins_metadata.json')\n    ]\n    cmd.append('--ram-support')  # enable by default\n    if opts.rom_support:\n        # ROM string/object support is not enabled by default because\n        # it increases the generated duktape.c considerably.\n        logger.debug('Enabling --rom-support for genbuiltins.py')\n        cmd.append('--rom-support')\n    if opts.rom_auto_lightfunc:\n        logger.debug('Enabling --rom-auto-lightfunc for genbuiltins.py')\n        cmd.append('--rom-auto-lightfunc')\n    for fn in opts.builtin_files:\n        logger.debug('Forwarding --builtin-file %s' % fn)\n        cmd.append('--builtin-file')\n        cmd.append(fn)\n    cmd += forward_loglevel\n    logger.debug(repr(cmd))\n    exec_print_stdout(cmd)\n\n    # Autogenerated Unicode files\n    #\n    # Note: not all of the generated headers are used.  For instance, the\n    # match table for \"WhiteSpace-Z\" is not used, because a custom piece\n    # of code handles that particular match.\n    #\n    # UnicodeData.txt contains ranges expressed like this:\n    #\n    #   4E00;<CJK Ideograph, First>;Lo;0;L;;;;;N;;;;;\n    #   9FCB;<CJK Ideograph, Last>;Lo;0;L;;;;;N;;;;;\n    #\n    # These are currently decoded into individual characters as a prestep.\n    #\n    # For IDPART:\n    #   UnicodeCombiningMark -> categories Mn, Mc\n    #   UnicodeDigit -> categories Nd\n    #   UnicodeConnectorPunctuation -> categories Pc\n\n    # Whitespace (unused now)\n    WHITESPACE_INCL='Zs'  # USP = Any other Unicode space separator\n    WHITESPACE_EXCL='NONE'\n\n    # Unicode letter (unused now)\n    LETTER_INCL='Lu,Ll,Lt,Lm,Lo'\n    LETTER_EXCL='NONE'\n    LETTER_NOA_INCL='Lu,Ll,Lt,Lm,Lo'\n    LETTER_NOA_EXCL='ASCII'\n    LETTER_NOABMP_INCL=LETTER_NOA_INCL\n    LETTER_NOABMP_EXCL='ASCII,NONBMP'\n\n    # Identifier start\n    # E5 Section 7.6\n    IDSTART_INCL='Lu,Ll,Lt,Lm,Lo,Nl,0024,005F'\n    IDSTART_EXCL='NONE'\n    IDSTART_NOA_INCL='Lu,Ll,Lt,Lm,Lo,Nl,0024,005F'\n    IDSTART_NOA_EXCL='ASCII'\n    IDSTART_NOABMP_INCL=IDSTART_NOA_INCL\n    IDSTART_NOABMP_EXCL='ASCII,NONBMP'\n\n    # Identifier start - Letter: allows matching of (rarely needed) 'Letter'\n    # production space efficiently with the help of IdentifierStart.  The\n    # 'Letter' production is only needed in case conversion of Greek final\n    # sigma.\n    IDSTART_MINUS_LETTER_INCL=IDSTART_NOA_INCL\n    IDSTART_MINUS_LETTER_EXCL='Lu,Ll,Lt,Lm,Lo'\n    IDSTART_MINUS_LETTER_NOA_INCL=IDSTART_NOA_INCL\n    IDSTART_MINUS_LETTER_NOA_EXCL='Lu,Ll,Lt,Lm,Lo,ASCII'\n    IDSTART_MINUS_LETTER_NOABMP_INCL=IDSTART_NOA_INCL\n    IDSTART_MINUS_LETTER_NOABMP_EXCL='Lu,Ll,Lt,Lm,Lo,ASCII,NONBMP'\n\n    # Identifier start - Identifier part\n    # E5 Section 7.6: IdentifierPart, but remove IdentifierStart (already above)\n    IDPART_MINUS_IDSTART_INCL='Lu,Ll,Lt,Lm,Lo,Nl,0024,005F,Mn,Mc,Nd,Pc,200C,200D'\n    IDPART_MINUS_IDSTART_EXCL='Lu,Ll,Lt,Lm,Lo,Nl,0024,005F'\n    IDPART_MINUS_IDSTART_NOA_INCL='Lu,Ll,Lt,Lm,Lo,Nl,0024,005F,Mn,Mc,Nd,Pc,200C,200D'\n    IDPART_MINUS_IDSTART_NOA_EXCL='Lu,Ll,Lt,Lm,Lo,Nl,0024,005F,ASCII'\n    IDPART_MINUS_IDSTART_NOABMP_INCL=IDPART_MINUS_IDSTART_NOA_INCL\n    IDPART_MINUS_IDSTART_NOABMP_EXCL='Lu,Ll,Lt,Lm,Lo,Nl,0024,005F,ASCII,NONBMP'\n\n    logger.debug('Expand UnicodeData.txt ranges')\n\n    exec_print_stdout([\n        sys.executable,\n        os.path.join(script_path, 'prepare_unicode_data.py'),\n        '--unicode-data', unicode_data,\n        '--output', os.path.join(tempdir, 'UnicodeData-expanded.tmp')\n    ] + forward_loglevel)\n\n    def extract_chars(incl, excl, suffix):\n        logger.debug('- extract_chars: %s %s %s' % (incl, excl, suffix))\n        res = exec_get_stdout([\n            sys.executable,\n            os.path.join(script_path, 'extract_chars.py'),\n            '--unicode-data', os.path.join(tempdir, 'UnicodeData-expanded.tmp'),\n            '--include-categories', incl,\n            '--exclude-categories', excl,\n            '--out-source', os.path.join(tempdir, 'duk_unicode_%s.c.tmp' % suffix),\n            '--out-header', os.path.join(tempdir, 'duk_unicode_%s.h.tmp' % suffix),\n            '--table-name', 'duk_unicode_%s' % suffix\n        ])\n        with open(os.path.join(tempdir, suffix + '.txt'), 'wb') as f:\n            f.write(res)\n\n    def extract_caseconv():\n        logger.debug('- extract_caseconv case conversion')\n        res = exec_get_stdout([\n            sys.executable,\n            os.path.join(script_path, 'extract_caseconv.py'),\n            '--command=caseconv_bitpacked',\n            '--unicode-data', os.path.join(tempdir, 'UnicodeData-expanded.tmp'),\n            '--special-casing', special_casing,\n            '--out-source', os.path.join(tempdir, 'duk_unicode_caseconv.c.tmp'),\n            '--out-header', os.path.join(tempdir, 'duk_unicode_caseconv.h.tmp'),\n            '--table-name-lc', 'duk_unicode_caseconv_lc',\n            '--table-name-uc', 'duk_unicode_caseconv_uc'\n        ])\n        with open(os.path.join(tempdir, 'caseconv.txt'), 'wb') as f:\n            f.write(res)\n\n        logger.debug('- extract_caseconv canon lookup')\n        res = exec_get_stdout([\n            sys.executable,\n            os.path.join(script_path, 'extract_caseconv.py'),\n            '--command=re_canon_lookup',\n            '--unicode-data', os.path.join(tempdir, 'UnicodeData-expanded.tmp'),\n            '--special-casing', special_casing,\n            '--out-source', os.path.join(tempdir, 'duk_unicode_re_canon_lookup.c.tmp'),\n            '--out-header', os.path.join(tempdir, 'duk_unicode_re_canon_lookup.h.tmp'),\n            '--table-name-re-canon-lookup', 'duk_unicode_re_canon_lookup'\n        ])\n        with open(os.path.join(tempdir, 'caseconv_re_canon_lookup.txt'), 'wb') as f:\n            f.write(res)\n\n        logger.debug('- extract_caseconv canon bitmap')\n        res = exec_get_stdout([\n            sys.executable,\n            os.path.join(script_path, 'extract_caseconv.py'),\n            '--command=re_canon_bitmap',\n            '--unicode-data', os.path.join(tempdir, 'UnicodeData-expanded.tmp'),\n            '--special-casing', special_casing,\n            '--out-source', os.path.join(tempdir, 'duk_unicode_re_canon_bitmap.c.tmp'),\n            '--out-header', os.path.join(tempdir, 'duk_unicode_re_canon_bitmap.h.tmp'),\n            '--table-name-re-canon-bitmap', 'duk_unicode_re_canon_bitmap'\n        ])\n        with open(os.path.join(tempdir, 'caseconv_re_canon_bitmap.txt'), 'wb') as f:\n            f.write(res)\n\n    # XXX: Now with configure.py part of the distributable, could generate\n    # only those Unicode tables needed by desired configuration (e.g. BMP-only\n    # tables if BMP-only was enabled).\n    # XXX: Improve Unicode preparation performance; it consumes most of the\n    # source preparation time.\n\n    logger.debug('Create Unicode tables for codepoint classes')\n    extract_chars(WHITESPACE_INCL, WHITESPACE_EXCL, 'ws')\n    extract_chars(LETTER_INCL, LETTER_EXCL, 'let')\n    extract_chars(LETTER_NOA_INCL, LETTER_NOA_EXCL, 'let_noa')\n    extract_chars(LETTER_NOABMP_INCL, LETTER_NOABMP_EXCL, 'let_noabmp')\n    extract_chars(IDSTART_INCL, IDSTART_EXCL, 'ids')\n    extract_chars(IDSTART_NOA_INCL, IDSTART_NOA_EXCL, 'ids_noa')\n    extract_chars(IDSTART_NOABMP_INCL, IDSTART_NOABMP_EXCL, 'ids_noabmp')\n    extract_chars(IDSTART_MINUS_LETTER_INCL, IDSTART_MINUS_LETTER_EXCL, 'ids_m_let')\n    extract_chars(IDSTART_MINUS_LETTER_NOA_INCL, IDSTART_MINUS_LETTER_NOA_EXCL, 'ids_m_let_noa')\n    extract_chars(IDSTART_MINUS_LETTER_NOABMP_INCL, IDSTART_MINUS_LETTER_NOABMP_EXCL, 'ids_m_let_noabmp')\n    extract_chars(IDPART_MINUS_IDSTART_INCL, IDPART_MINUS_IDSTART_EXCL, 'idp_m_ids')\n    extract_chars(IDPART_MINUS_IDSTART_NOA_INCL, IDPART_MINUS_IDSTART_NOA_EXCL, 'idp_m_ids_noa')\n    extract_chars(IDPART_MINUS_IDSTART_NOABMP_INCL, IDPART_MINUS_IDSTART_NOABMP_EXCL, 'idp_m_ids_noabmp')\n\n    logger.debug('Create Unicode tables for case conversion')\n    extract_caseconv()\n\n    logger.debug('Combine sources and clean up')\n\n    # Inject autogenerated files into source and header files so that they are\n    # usable (for all profiles and define cases) directly.\n    #\n    # The injection points use a standard C preprocessor #include syntax\n    # (earlier these were actual includes).\n\n    copy_and_replace(os.path.join(tempdir, 'src', 'duk_unicode.h'), os.path.join(tempdir, 'src', 'duk_unicode.h'), {\n        '#include \"duk_unicode_ids_noa.h\"': read_file(os.path.join(tempdir, 'duk_unicode_ids_noa.h.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_ids_noabmp.h\"': read_file(os.path.join(tempdir, 'duk_unicode_ids_noabmp.h.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_ids_m_let_noa.h\"': read_file(os.path.join(tempdir, 'duk_unicode_ids_m_let_noa.h.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_ids_m_let_noabmp.h\"': read_file(os.path.join(tempdir, 'duk_unicode_ids_m_let_noabmp.h.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_idp_m_ids_noa.h\"': read_file(os.path.join(tempdir, 'duk_unicode_idp_m_ids_noa.h.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_idp_m_ids_noabmp.h\"': read_file(os.path.join(tempdir, 'duk_unicode_idp_m_ids_noabmp.h.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_caseconv.h\"': read_file(os.path.join(tempdir, 'duk_unicode_caseconv.h.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_re_canon_lookup.h\"': read_file(os.path.join(tempdir, 'duk_unicode_re_canon_lookup.h.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_re_canon_bitmap.h\"': read_file(os.path.join(tempdir, 'duk_unicode_re_canon_bitmap.h.tmp'), strip_last_nl=True)\n    })\n\n    copy_and_replace(os.path.join(tempdir, 'src', 'duk_unicode_tables.c'), os.path.join(tempdir, 'src', 'duk_unicode_tables.c'), {\n        '#include \"duk_unicode_ids_noa.c\"': read_file(os.path.join(tempdir, 'duk_unicode_ids_noa.c.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_ids_noabmp.c\"': read_file(os.path.join(tempdir, 'duk_unicode_ids_noabmp.c.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_ids_m_let_noa.c\"': read_file(os.path.join(tempdir, 'duk_unicode_ids_m_let_noa.c.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_ids_m_let_noabmp.c\"': read_file(os.path.join(tempdir, 'duk_unicode_ids_m_let_noabmp.c.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_idp_m_ids_noa.c\"': read_file(os.path.join(tempdir, 'duk_unicode_idp_m_ids_noa.c.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_idp_m_ids_noabmp.c\"': read_file(os.path.join(tempdir, 'duk_unicode_idp_m_ids_noabmp.c.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_caseconv.c\"': read_file(os.path.join(tempdir, 'duk_unicode_caseconv.c.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_re_canon_lookup.c\"': read_file(os.path.join(tempdir, 'duk_unicode_re_canon_lookup.c.tmp'), strip_last_nl=True),\n        '#include \"duk_unicode_re_canon_bitmap.c\"': read_file(os.path.join(tempdir, 'duk_unicode_re_canon_bitmap.c.tmp'), strip_last_nl=True)\n    })\n\n    # Create a combined source file, duktape.c, into a separate combined source\n    # directory.  This allows user to just include \"duktape.c\", \"duktape.h\", and\n    # \"duk_config.h\" into a project and maximizes inlining and size optimization\n    # opportunities even with older compilers.  Because some projects include\n    # these files into their repository, the result should be deterministic and\n    # diffable.  Also, it must retain __FILE__/__LINE__ behavior through\n    # preprocessor directives.  Whitespace and comments can be stripped as long\n    # as the other requirements are met.  For some users it's preferable *not*\n    # to use #line directives in the combined source, so a separate variant is\n    # created for that, see: https://github.com/svaarala/duktape/pull/363.\n\n    def create_source_prologue(license_file, authors_file):\n        res = []\n\n        # Because duktape.c/duktape.h/duk_config.h are often distributed or\n        # included in project sources as is, add a license reminder and\n        # Duktape version information to the duktape.c header (duktape.h\n        # already contains them).\n\n        duk_major = duk_version / 10000\n        duk_minor = duk_version / 100 % 100\n        duk_patch = duk_version % 100\n        res.append('/*')\n        res.append(' *  Single source autogenerated distributable for Duktape %d.%d.%d.' % (duk_major, duk_minor, duk_patch))\n        res.append(' *')\n        res.append(' *  Git commit %s (%s).' % (git_commit, git_describe))\n        res.append(' *  Git branch %s.' % git_branch)\n        res.append(' *')\n        res.append(' *  See Duktape AUTHORS.rst and LICENSE.txt for copyright and')\n        res.append(' *  licensing information.')\n        res.append(' */')\n        res.append('')\n\n        # Add LICENSE.txt and AUTHORS.rst to combined source so that they're automatically\n        # included and are up-to-date.\n\n        res.append('/* LICENSE.txt */')\n        with open(license_file, 'rb') as f:\n            for line in f:\n                res.append(line.strip())\n        res.append('')\n        res.append('/* AUTHORS.rst */')\n        with open(authors_file, 'rb') as f:\n            for line in f:\n                res.append(line.strip())\n\n        return '\\n'.join(res) + '\\n'\n\n    def select_combined_sources():\n        # These files must appear before the alphabetically sorted\n        # ones so that static variables get defined before they're\n        # used.  We can't forward declare them because that would\n        # cause C++ issues (see GH-63).  When changing, verify by\n        # compiling with g++.\n        handpick = [\n            'duk_replacements.c',\n            'duk_debug_macros.c',\n            'duk_builtins.c',\n            'duk_error_macros.c',\n            'duk_unicode_support.c',\n            'duk_util_misc.c',\n            'duk_hobject_class.c'\n        ]\n\n        files = []\n        for fn in handpick:\n            files.append(fn)\n\n        for fn in sorted(os.listdir(os.path.join(tempdir, 'src'))):\n            f_ext = os.path.splitext(fn)[1]\n            if f_ext not in [ '.c' ]:\n                continue\n            if fn in files:\n                continue\n            files.append(fn)\n\n        res = map(lambda x: os.path.join(tempdir, 'src', x), files)\n        logger.debug(repr(files))\n        logger.debug(repr(res))\n        return res\n\n    if opts.separate_sources:\n        for fn in os.listdir(os.path.join(tempdir, 'src')):\n            copy_file(os.path.join(tempdir, 'src', fn), os.path.join(outdir, fn))\n    else:\n        with open(os.path.join(tempdir, 'prologue.tmp'), 'wb') as f:\n            f.write(create_source_prologue(os.path.join(tempdir, 'LICENSE.txt.tmp'), os.path.join(tempdir, 'AUTHORS.rst.tmp')))\n\n        cmd = [\n            sys.executable,\n            os.path.join(script_path, 'combine_src.py'),\n            '--include-path', os.path.join(tempdir, 'src'),\n            '--include-exclude', 'duk_config.h',  # don't inline\n            '--include-exclude', 'duktape.h',     # don't inline\n            '--prologue', os.path.join(tempdir, 'prologue.tmp'),\n            '--output-source', os.path.join(outdir, 'duktape.c'),\n            '--output-metadata', os.path.join(tempdir, 'combine_src_metadata.json')\n        ]\n        if opts.line_directives:\n            cmd += [ '--line-directives' ]\n        cmd += select_combined_sources()\n        cmd += forward_loglevel\n        exec_print_stdout(cmd)\n\n    # Merge metadata files.\n\n    doc = {\n        'type': 'duk_source_meta',\n        'comment': 'Metadata for prepared Duktape sources and configuration',\n        'git_commit': git_commit,\n        'git_branch': git_branch,\n        'git_describe': git_describe,\n        'duk_version': duk_version,\n        'duk_version_string': duk_version_formatted\n    }\n    with open(os.path.join(tempdir, 'genbuiltins_metadata.json'), 'rb') as f:\n        tmp = json.loads(f.read())\n        for k in tmp.keys():\n            doc[k] = tmp[k]\n    if opts.separate_sources:\n        pass\n    else:\n        with open(os.path.join(tempdir, 'combine_src_metadata.json'), 'rb') as f:\n            tmp = json.loads(f.read())\n            for k in tmp.keys():\n                doc[k] = tmp[k]\n\n    with open(os.path.join(outdir, 'duk_source_meta.json'), 'wb') as f:\n        f.write(json.dumps(doc, indent=4))\n\n    logger.debug('Configure finished successfully')\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/tools/create_spdx_license.py",
    "content": "#!/usr/bin/env python2\n#\n#  Helper to create an SPDX license file (http://spdx.org)\n#\n#  This must be executed when the dist/ directory is otherwise complete,\n#  except for the SPDX license, so that the file lists and such contained\n#  in the SPDX license will be correct.\n#\n#  The utility outputs RDF/XML to specified file:\n#\n#    $ python create_spdx_license.py /tmp/license.spdx\n#\n#  Then, validate with SPDXViewer and SPDXTools:\n#\n#    $ java -jar SPDXViewer.jar /tmp/license.spdx\n#    $ java -jar java -jar spdx-tools-1.2.5-jar-with-dependencies.jar RdfToHtml /tmp/license.spdx /tmp/license.html\n#\n#  Finally, copy to dist:\n#\n#    $ cp /tmp/license.spdx dist/license.spdx\n#\n#  SPDX FAQ indicates there is no standard extension for an SPDX license file\n#  but '.spdx' is a common practice.\n#\n#  The algorithm to compute a \"verification code\", implemented in this file,\n#  can be verified as follows:\n#\n#    # build dist tar.xz, copy to /tmp/duktape-N.N.N.tar.xz\n#    $ cd /tmp\n#    $ tar xvfJ duktape-N.N.N.tar.xz\n#    $ rm duktape-N.N.N/license.spdx  # remove file excluded from verification code\n#    $ java -jar spdx-tools-1.2.5-jar-with-dependencies.jar GenerateVerificationCode /tmp/duktape-N.N.N/\n#\n#  Compare the resulting verification code manually with the one in license.spdx.\n#\n#  Resources:\n#\n#   - http://spdx.org/about-spdx/faqs\n#   - http://wiki.spdx.org/view/Technical_Team/Best_Practices\n#\n\nimport os\nimport sys\nimport re\nimport datetime\nimport sha\nimport rdflib\nfrom rdflib import URIRef, BNode, Literal, Namespace\n\nRDF = Namespace('http://www.w3.org/1999/02/22-rdf-syntax-ns#')\nRDFS = Namespace('http://www.w3.org/2000/01/rdf-schema#')\nXSD = Namespace('http://www.w3.org/2001/XMLSchema#')\nSPDX = Namespace('http://spdx.org/rdf/terms#')\nDOAP = Namespace('http://usefulinc.com/ns/doap#')\nDUKTAPE = Namespace('http://duktape.org/rdf/terms#')\n\ndef checksumFile(g, filename):\n    f = open(filename, 'rb')\n    d = f.read()\n    f.close()\n    shasum = sha.sha(d).digest().encode('hex').lower()\n\n    csum_node = BNode()\n    g.add((csum_node, RDF.type, SPDX.Checksum))\n    g.add((csum_node, SPDX.algorithm, SPDX.checksumAlgorithm_sha1))\n    g.add((csum_node, SPDX.checksumValue, Literal(shasum)))\n\n    return csum_node\n\ndef computePackageVerification(g, dirname, excluded):\n    # SPDX 1.2 Section 4.7\n    # The SPDXTools command \"GenerateVerificationCode\" can be used to\n    # check the verification codes created.  Note that you must manually\n    # remove \"license.spdx\" from the unpacked dist directory before\n    # computing the verification code.\n\n    verify_node = BNode()\n\n    hashes = []\n    for dirpath, dirnames, filenames in os.walk(dirname):\n        for fn in filenames:\n            full_fn = os.path.join(dirpath, fn)\n            f = open(full_fn, 'rb')\n            d = f.read()\n            f.close()\n\n            if full_fn in excluded:\n                #print('excluded in verification: ' + full_fn)\n                continue\n            #print('included in verification: ' + full_fn)\n\n            file_sha1 = sha.sha(d).digest().encode('hex').lower()\n            hashes.append(file_sha1)\n\n    #print(repr(hashes))\n    hashes.sort()\n    #print(repr(hashes))\n    verify_code = sha.sha(''.join(hashes)).digest().encode('hex').lower()\n\n    for fn in excluded:\n        g.add((verify_node, SPDX.packageVerificationCodeExcludedFile, Literal(fn)))\n    g.add((verify_node, SPDX.packageVerificationCodeValue, Literal(verify_code)))\n\n    return verify_node\n\ndef fileType(filename):\n    ign, ext = os.path.splitext(filename)\n    if ext in [ '.c', '.h', '.js' ]:\n        return SPDX.fileType_source\n    else:\n        return SPDX.fileType_other\n\ndef getDuktapeVersion():\n    f = open('./src/duktape.h')\n    re_ver = re.compile(r'^#define\\s+DUK_VERSION\\s+(\\d+)L$')\n    for line in f:\n        line = line.strip()\n        m = re_ver.match(line)\n        if m is None:\n            continue\n        ver = int(m.group(1))\n        return '%d.%d.%d' % ((ver / 10000) % 100,\n                             (ver / 100) % 100,\n                             ver % 100)\n\n    raise Exception('could not figure out Duktape version')\n\ndef main():\n    outfile = sys.argv[1]\n\n    if not os.path.exists('CONTRIBUTING.md') and os.path.exists('tests/ecmascript'):\n        sys.stderr.write('Invalid CWD, must be in Duktape root with dist/ built')\n        sys.exit(1)\n    os.chdir('dist')\n    if not os.path.exists('Makefile.cmdline'):\n        sys.stderr.write('Invalid CWD, must be in Duktape root with dist/ built')\n        sys.exit(1)\n\n    duktape_version = getDuktapeVersion()\n    duktape_pkgname = 'duktape-' + duktape_version + '.tar.xz'\n    now = datetime.datetime.utcnow()\n    now = datetime.datetime(now.year, now.month, now.day, now.hour, now.minute, now.second)\n    creation_date = Literal(now.isoformat() + 'Z', datatype=XSD.dateTime)\n    duktape_org = Literal('Organization: duktape.org')\n    mit_license = URIRef('http://spdx.org/licenses/MIT')\n    duktape_copyright = Literal('Copyright 2013-2017 Duktape authors (see AUTHORS.rst in the Duktape distributable)')\n\n    g = rdflib.Graph()\n\n    crea_node = BNode()\n    g.add((crea_node, RDF.type, SPDX.CreationInfo))\n    g.add((crea_node, RDFS.comment, Literal('')))\n    g.add((crea_node, SPDX.creator, duktape_org))\n    g.add((crea_node, SPDX.created, creation_date))\n    g.add((crea_node, SPDX.licenseListVersion, Literal('1.20')))  # http://spdx.org/licenses/\n\n    # 'name' should not include a version number (see best practices)\n    pkg_node = BNode()\n    g.add((pkg_node, RDF.type, SPDX.Package))\n    g.add((pkg_node, SPDX.name, Literal('Duktape')))\n    g.add((pkg_node, SPDX.versionInfo, Literal(duktape_version)))\n    g.add((pkg_node, SPDX.packageFileName, Literal(duktape_pkgname)))\n    g.add((pkg_node, SPDX.supplier, duktape_org))\n    g.add((pkg_node, SPDX.originator, duktape_org))\n    g.add((pkg_node, SPDX.downloadLocation, Literal('http://duktape.org/' + duktape_pkgname, datatype=XSD.anyURI)))\n    g.add((pkg_node, SPDX.homePage, Literal('http://duktape.org/', datatype=XSD.anyURI)))\n    verify_node = computePackageVerification(g, '.', [ './license.spdx' ])\n    g.add((pkg_node, SPDX.packageVerificationCode, verify_node))\n    # SPDX.checksum: omitted because license is inside the package\n    g.add((pkg_node, SPDX.sourceInfo, Literal('Official duktape.org release built from GitHub repo https://github.com/svaarala/duktape.')))\n\n    # NOTE: MIT license alone is sufficient for now, because Duktape, Lua,\n    # Murmurhash2, and CommonJS (though probably not even relevant for\n    # licensing) are all MIT.\n    g.add((pkg_node, SPDX.licenseConcluded, mit_license))\n    g.add((pkg_node, SPDX.licenseInfoFromFiles, mit_license))\n    g.add((pkg_node, SPDX.licenseDeclared, mit_license))\n    g.add((pkg_node, SPDX.licenseComments, Literal('Duktape is copyrighted by its authors and licensed under the MIT license.  MurmurHash2 is used internally, it is also under the MIT license. Duktape module loader is based on the CommonJS module loading specification (without sharing any code), CommonJS is under the MIT license.')))\n    g.add((pkg_node, SPDX.copyrightText, duktape_copyright))\n    g.add((pkg_node, SPDX.summary, Literal('Duktape ECMAScript interpreter')))\n    g.add((pkg_node, SPDX.description, Literal('Duktape is an embeddable Javascript engine, with a focus on portability and compact footprint')))\n    # hasFile properties added separately below\n\n    #reviewed_node = BNode()\n    #g.add((reviewed_node, RDF.type, SPDX.Review))\n    #g.add((reviewed_node, SPDX.reviewer, XXX))\n    #g.add((reviewed_node, SPDX.reviewDate, XXX))\n    #g.add((reviewed_node, RDFS.comment, ''))\n\n    spdx_doc = BNode()\n    g.add((spdx_doc, RDF.type, SPDX.SpdxDocument))\n    g.add((spdx_doc, SPDX.specVersion, Literal('SPDX-1.2')))\n    g.add((spdx_doc, SPDX.dataLicense, URIRef('http://spdx.org/licenses/CC0-1.0')))\n    g.add((spdx_doc, RDFS.comment, Literal('SPDX license for Duktape ' + duktape_version)))\n    g.add((spdx_doc, SPDX.creationInfo, crea_node))\n    g.add((spdx_doc, SPDX.describesPackage, pkg_node))\n    # SPDX.hasExtractedLicensingInfo\n    # SPDX.reviewed\n    # SPDX.referencesFile: added below\n\n    for dirpath, dirnames, filenames in os.walk('.'):\n        for fn in filenames:\n            full_fn = os.path.join(dirpath, fn)\n            #print('# file: ' + full_fn)\n\n            file_node = BNode()\n            g.add((file_node, RDF.type, SPDX.File))\n            g.add((file_node, SPDX.fileName, Literal(full_fn)))\n            g.add((file_node, SPDX.fileType, fileType(full_fn)))\n            g.add((file_node, SPDX.checksum, checksumFile(g, full_fn)))\n\n            # Here we assume that LICENSE.txt provides the actual \"in file\"\n            # licensing information, and everything else is implicitly under\n            # MIT license.\n            g.add((file_node, SPDX.licenseConcluded, mit_license))\n            if full_fn == './LICENSE.txt':\n                g.add((file_node, SPDX.licenseInfoInFile, mit_license))\n            else:\n                g.add((file_node, SPDX.licenseInfoInFile, URIRef(SPDX.none)))\n\n            # SPDX.licenseComments\n            g.add((file_node, SPDX.copyrightText, duktape_copyright))\n            # SPDX.noticeText\n            # SPDX.artifactOf\n            # SPDX.fileDependency\n            # SPDX.fileContributor\n\n            # XXX: should referencesFile include all files?\n            g.add((spdx_doc, SPDX.referencesFile, file_node))\n\n            g.add((pkg_node, SPDX.hasFile, file_node))\n\n    # Serialize into RDF/XML directly.  We could also serialize into\n    # N-Triples and use external tools (like 'rapper') to get cleaner,\n    # abbreviated output.\n\n    #print('# Duktape SPDX license file (autogenerated)')\n    #print(g.serialize(format='turtle'))\n    #print(g.serialize(format='nt'))\n    f = open(outfile, 'wb')\n    #f.write(g.serialize(format='rdf/xml'))\n    f.write(g.serialize(format='xml'))\n    f.close()\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/tools/duk_meta_to_strarray.py",
    "content": "#!/usr/bin/env python2\n#\n#  Create an array of C strings with Duktape built-in strings.\n#  Useful when using external strings.\n#\n\nimport os\nimport sys\nimport json\n\ndef to_c_string(x):\n    res = '\"'\n    term = False\n    for i, c in enumerate(x):\n        if term:\n            term = False\n            res += '\" \"'\n\n        o = ord(c)\n        if o < 0x20 or o > 0x7e or c in '\\'\"\\\\':\n            # Terminate C string so that escape doesn't become\n            # ambiguous\n            res += '\\\\x%02x' % o\n            term = True\n        else:\n            res += c\n    res += '\"'\n    return res\n\ndef main():\n    f = open(sys.argv[1], 'rb')\n    d = f.read()\n    f.close()\n    meta = json.loads(d)\n\n    print('const char *duk_builtin_strings[] = {')\n\n    strlist = meta['builtin_strings_base64']\n    for i in xrange(len(strlist)):\n        s = strlist[i]\n        if i == len(strlist) - 1:\n            print('    %s' % to_c_string(s.decode('base64')))\n        else:\n            print('    %s,' % to_c_string(s.decode('base64')))\n\n    print('};')\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/tools/dukutil.py",
    "content": "#!/usr/bin/env python2\n#\n#  Python utilities shared by the build scripts.\n#\n\nimport datetime\nimport json\n\nclass BitEncoder:\n    \"Bitstream encoder.\"\n\n    _bits = None\n    _varuint_dist = None\n    _varuint_cats = None\n    _varuint_count = None\n    _varuint_bits = None\n\n    def __init__(self):\n        self._bits = []\n        self._varuint_dist = [ 0 ] * 65536\n        self._varuint_cats = [0] * 5\n        self._varuint_count = 0\n        self._varuint_bits = 0\n\n    def bits(self, x, nbits):\n        if (x >> nbits) != 0:\n            raise Exception('input value has too many bits (value: %d, bits: %d)' % (x, nbits))\n        for shift in xrange(nbits - 1, -1, -1):  # nbits - 1, nbits - 2, ..., 0\n            self._bits.append((x >> shift) & 0x01)\n\n    def string(self, x):\n        for i in xrange(len(x)):\n            ch = ord(x[i])\n            for shift in xrange(7, -1, -1):  # 7, 6, ..., 0\n                self._bits.append((ch >> shift) & 0x01)\n\n    # Shared varint encoding.\n    def varuint(self, x):\n        assert(x >= 0)\n        if x <= 0xffff:\n            self._varuint_dist[x] += 1\n        self._varuint_count += 1\n\n        if x == 0:\n            self.bits(0, 2)\n            self._varuint_bits += 2\n            self._varuint_cats[0] += 1\n        elif x <= 4:\n            self.bits(1, 2)\n            self.bits(x - 1, 2)\n            self._varuint_bits += 2 + 2\n            self._varuint_cats[1] += 1\n        elif x <= 36:\n            self.bits(2, 2)\n            self.bits(x - 5, 5)\n            self._varuint_bits += 2 + 5\n            self._varuint_cats[2] += 1\n        elif x <= 163:\n            self.bits(3, 2)\n            self.bits(x - 37 + 1, 7)\n            self._varuint_bits += 2 + 7\n            self._varuint_cats[3] += 1\n        else:\n            self.bits(3, 2)\n            self.bits(0, 7)\n            self.bits(x, 20)\n            self._varuint_bits += 2 + 7 + 20\n            self._varuint_cats[4] += 1\n\n    def getNumBits(self):\n        \"Get current number of encoded bits.\"\n        return len(self._bits)\n\n    def getNumBytes(self):\n        \"Get current number of encoded bytes, rounded up.\"\n        nbits = len(self._bits)\n        while (nbits % 8) != 0:\n            nbits += 1\n        return nbits / 8\n\n    def getBytes(self):\n        \"Get current bitstream as a byte sequence, padded with zero bits.\"\n        bytes = []\n\n        for i in xrange(self.getNumBytes()):\n            t = 0\n            for j in xrange(8):\n                off = i*8 + j\n                if off >= len(self._bits):\n                    t = (t << 1)\n                else:\n                    t = (t << 1) + self._bits[off]\n            bytes.append(t)\n\n        return bytes\n\n    def getByteString(self):\n        \"Get current bitstream as a string.\"\n        return ''.join([chr(i) for i in self.getBytes()])\n\nclass GenerateC:\n    \"Helper for generating C source and header files.\"\n\n    _data = None\n    wrap_col = 76\n\n    def __init__(self):\n        self._data = []\n\n    def emitRaw(self, text):\n        \"Emit raw text (without automatic newline).\"\n        self._data.append(text)\n\n    def emitLine(self, text):\n        \"Emit a raw line (with automatic newline).\"\n        self._data.append(text + '\\n')\n\n    def emitHeader(self, autogen_by):\n        \"Emit file header comments.\"\n\n        # Note: a timestamp would be nice but it breaks incremental building\n        self.emitLine('/*')\n        self.emitLine(' *  Automatically generated by %s, do not edit!' % autogen_by)\n        self.emitLine(' */')\n        self.emitLine('')\n\n    def emitArray(self, data, tablename, visibility=None, typename='char', size=None, intvalues=False, const=True):\n        \"Emit an array as a C array.\"\n\n        # lenient input\n        if isinstance(data, unicode):\n            data = data.encode('utf-8')\n        if isinstance(data, str):\n            tmp = []\n            for i in xrange(len(data)):\n                tmp.append(ord(data[i]))\n            data = tmp\n\n        size_spec = ''\n        if size is not None:\n            size_spec = '%d' % size\n        visib_qual = ''\n        if visibility is not None:\n            visib_qual = visibility + ' '\n        const_qual = ''\n        if const:\n            const_qual = 'const '\n        self.emitLine('%s%s%s %s[%s] = {' % (visib_qual, const_qual, typename, tablename, size_spec))\n\n        line = ''\n        for i in xrange(len(data)):\n            if intvalues:\n                suffix = ''\n                if data[i] < -32768 or data[i] > 32767:\n                    suffix = 'L'\n                t = \"%d%s,\" % (data[i], suffix)\n            else:\n                t = \"(%s)'\\\\x%02x', \" % (typename, data[i])\n            if len(line) + len(t) >= self.wrap_col:\n                self.emitLine(line)\n                line = t\n            else:\n                line += t\n        if line != '':\n            self.emitLine(line)\n        self.emitLine('};')\n\n    def emitDefine(self, name, value, comment=None):\n        \"Emit a C define with an optional comment.\"\n\n        # XXX: there is no escaping right now (for comment or value)\n        if comment is not None:\n            self.emitLine('#define %-60s  %-30s /* %s */' % (name, value, comment))\n        else:\n            self.emitLine('#define %-60s  %s' % (name, value))\n\n    def getString(self):\n        \"Get the entire file as a string.\"\n        return ''.join(self._data)\n\ndef json_encode(x):\n    \"JSON encode a value.\"\n    try:\n        return json.dumps(x)\n    except AttributeError:\n        pass\n\n    # for older library versions\n    return json.write(x)\n\ndef json_decode(x):\n    \"JSON decode a value.\"\n    try:\n        return json.loads(x)\n    except AttributeError:\n        pass\n\n    # for older library versions\n    return json.read(x)\n\n# Compute a byte hash identical to duk_util_hashbytes().\nDUK__MAGIC_M = 0x5bd1e995\nDUK__MAGIC_R = 24\ndef duk_util_hashbytes(x, off, nbytes, str_seed, big_endian):\n    h = (str_seed ^ nbytes) & 0xffffffff\n\n    while nbytes >= 4:\n        # 4-byte fetch byte order:\n        #  - native (endian dependent) if unaligned accesses allowed\n        #  - little endian if unaligned accesses not allowed\n\n        if big_endian:\n            k = ord(x[off + 3]) + (ord(x[off + 2]) << 8) + \\\n                (ord(x[off + 1]) << 16) + (ord(x[off + 0]) << 24)\n        else:\n            k = ord(x[off]) + (ord(x[off + 1]) << 8) + \\\n                (ord(x[off + 2]) << 16) + (ord(x[off + 3]) << 24)\n\n        k = (k * DUK__MAGIC_M) & 0xffffffff\n        k = (k ^ (k >> DUK__MAGIC_R)) & 0xffffffff\n        k = (k * DUK__MAGIC_M) & 0xffffffff\n        h = (h * DUK__MAGIC_M) & 0xffffffff\n        h = (h ^ k) & 0xffffffff\n\n        off += 4\n        nbytes -= 4\n\n    if nbytes >= 3:\n        h = (h ^ (ord(x[off + 2]) << 16)) & 0xffffffff\n    if nbytes >= 2:\n        h = (h ^ (ord(x[off + 1]) << 8)) & 0xffffffff\n    if nbytes >= 1:\n        h = (h ^ ord(x[off])) & 0xffffffff\n        h = (h * DUK__MAGIC_M) & 0xffffffff\n\n    h = (h ^ (h >> 13)) & 0xffffffff\n    h = (h * DUK__MAGIC_M) & 0xffffffff\n    h = (h ^ (h >> 15)) & 0xffffffff\n\n    return h\n\n# Compute a string hash identical to duk_heap_hashstring() when dense\n# hashing is enabled.\nDUK__STRHASH_SHORTSTRING = 4096\nDUK__STRHASH_MEDIUMSTRING = 256 * 1024\nDUK__STRHASH_BLOCKSIZE = 256\ndef duk_heap_hashstring_dense(x, hash_seed, big_endian=False, strhash16=False):\n    str_seed = (hash_seed ^ len(x)) & 0xffffffff\n\n    if len(x) <= DUK__STRHASH_SHORTSTRING:\n        res = duk_util_hashbytes(x, 0, len(x), str_seed, big_endian)\n    else:\n        if len(x) <= DUK__STRHASH_MEDIUMSTRING:\n            skip = 16 * DUK__STRHASH_BLOCKSIZE + DUK__STRHASH_BLOCKSIZE\n        else:\n            skip = 256 * DUK__STRHASH_BLOCKSIZE + DUK__STRHASH_BLOCKSIZE\n\n        res = duk_util_hashbytes(x, 0, DUK__STRHASH_SHORTSTRING, str_seed, big_endian)\n        off = DUK__STRHASH_SHORTSTRING + (skip * (res % 256)) / 256\n\n        while off < len(x):\n            left = len(x) - off\n            now = left\n            if now > DUK__STRHASH_BLOCKSIZE:\n                now = DUK__STRHASH_BLOCKSIZE\n            res = (res ^ duk_util_hashbytes(str, off, now, str_seed, big_endian)) & 0xffffffff\n            off += skip\n\n    if strhash16:\n        res &= 0xffff\n\n    return res\n\n# Compute a string hash identical to duk_heap_hashstring() when sparse\n# hashing is enabled.\nDUK__STRHASH_SKIP_SHIFT = 5   # XXX: assumes default value\ndef duk_heap_hashstring_sparse(x, hash_seed, strhash16=False):\n    res = (hash_seed ^ len(x)) & 0xffffffff\n\n    step = (len(x) >> DUK__STRHASH_SKIP_SHIFT) + 1\n    off = len(x)\n    while off >= step:\n        assert(off >= 1)\n        res = ((res * 33) + ord(x[off - 1])) & 0xffffffff\n        off -= step\n\n    if strhash16:\n        res &= 0xffff\n\n    return res\n\n# Must match src-input/duk_unicode_support:duk_unicode_unvalidated_utf8_length().\ndef duk_unicode_unvalidated_utf8_length(x):\n    assert(isinstance(x, str))\n    clen = 0\n    for c in x:\n        t = ord(c)\n        if t < 0x80 or t >= 0xc0:  # 0x80...0xbf are continuation chars, not counted\n            clen += 1\n    return clen\n"
  },
  {
    "path": "react_juce/duktape/tools/dump_bytecode.py",
    "content": "#!/usr/bin/env python2\n#\n#  Utility to dump bytecode into a human readable form.\n#\n\nimport os\nimport sys\nimport optparse\nimport struct\nimport yaml\n\nscript_path = sys.path[0]  # http://stackoverflow.com/questions/4934806/how-can-i-find-scripts-directory-with-python\n\nops = None\n\ndef decode_string(buf, off):\n    strlen, = struct.unpack('>L', buf[off:off + 4])\n    off += 4\n    strdata = buf[off:off + strlen]\n    off += strlen\n\n    return off, strdata\n\ndef sanitize_string(val):\n    # Don't try to UTF-8 decode, just escape non-printable ASCII.\n    def f(c):\n        if ord(c) < 0x20 or ord(c) > 0x7e or c in '\\'\"':\n            return '\\\\x%02x' % ord(c)\n        else:\n            return c\n\n    return \"'\" + ''.join(map(f, val)) + \"'\"\n\ndef decode_sanitize_string(buf, off):\n    off, val = decode_string(buf, off)\n    return off, sanitize_string(val)\n\ndef dump_ins(ins, x):\n    global ops\n\n    if ops is None:\n        return ''\n\n    pc = x / 4\n    args = []\n\n    op = ops[ins & 0xff]\n    comments = []\n\n    if 'args' in op:\n        for j in xrange(len(op['args'])):\n            A = (ins >> 8) & 0xff\n            B = (ins >> 16) & 0xff\n            C = (ins >> 24) & 0xff\n            BC = (ins >> 16) & 0xffff\n            ABC = (ins >> 8) & 0xffffff\n\n            Bconst = ins & 0x1\n            Cconst = ins & 0x2\n\n            if op['args'][j] == 'A_R':\n                args.append('r' + str(A))\n\n            elif op['args'][j] == 'A_RI':\n                args.append('r' + str(A) + '(indirect)')\n\n            elif op['args'][j] == 'A_C':\n                args.append('c' + str(A))\n\n            elif op['args'][j] == 'A_H':\n                args.append(hex(A))\n\n            elif op['args'][j] == 'A_I':\n                args.append(str(A))\n\n            elif op['args'][j] == 'A_B':\n                args.append('true' if A else 'false')\n\n            elif op['args'][j] == 'B_RC':\n                args.append('c' if Bconst else 'r' + str(B))\n\n            elif op['args'][j] == 'B_R':\n                args.append('r' + str(B))\n\n            elif op['args'][j] == 'B_RI':\n                args.append('r' + str(B) + '(indirect)')\n\n            elif op['args'][j] == 'B_C':\n                args.append('c' + str(B))\n\n            elif op['args'][j] == 'B_H':\n                args.append(hex(B))\n\n            elif op['args'][j] == 'B_I':\n                args.append(str(B))\n\n            elif op['args'][j] == 'C_RC':\n                args.append('c' if Cconst else 'r' + str(C))\n\n            elif op['args'][j] == 'C_R':\n                args.append('r' + str(C))\n\n            elif op['args'][j] == 'C_RI':\n                args.append('r' + str(C) + '(indirect)')\n\n            elif op['args'][j] == 'C_C':\n                args.append('c' + str(C))\n\n            elif op['args'][j] == 'C_H':\n                args.append(hex(C))\n\n            elif op['args'][j] == 'C_I':\n                args.append(str(C))\n\n            elif op['args'][j] == 'BC_R':\n                args.append('r' + str(BC))\n\n            elif op['args'][j] == 'BC_C':\n                args.append('c' + str(BC))\n\n            elif op['args'][j] == 'BC_H':\n                args.append(hex(BC))\n\n            elif op['args'][j] == 'BC_I':\n                args.append(str(BC))\n\n            elif op['args'][j] == 'ABC_H':\n                args.append(hex(ABC))\n\n            elif op['args'][j] == 'ABC_I':\n                args.append(str(ABC))\n\n            elif op['args'][j] == 'BC_LDINT':\n                args.append(hex(BC - (1 << 15)))\n\n            elif op['args'][j] == 'BC_LDINTX':\n                args.append(hex(BC))\n            elif op['args'][j] == 'ABC_JUMP':\n                pc_add = ABC - (1 << 23) + 1\n                pc_dst = pc + pc_add\n                args.append(str(pc_dst) + ' (' + ('+' if pc_add >= 0 else '') + str(pc_add) + ')')\n            else:\n                args.append('?')\n\n    if 'flags' in op:\n        for f in op['flags']:\n            if ins & f['mask']:\n                comments.append(f['name'])\n\n    if len(args) > 0:\n        res = '%-12s %s' % (op['name'], ', '.join(args))\n    else:\n        res = op['name']\n    if len(comments) > 0:\n        res = '%-44s ; %s' % (res, ', '.join(comments))\n\n    return res\n\ndef dump_function(buf, off, ind):\n    count_inst, count_const, count_funcs = struct.unpack('>LLL', buf[off:off + 12])\n    off += 12\n    print('%sInstructions: %d' % (ind, count_inst))\n    print('%sConstants: %d' % (ind, count_const))\n    print('%sInner functions: %d' % (ind, count_funcs))\n\n    # Line numbers present, assuming debugger support; otherwise 0.\n    nregs, nargs, start_line, end_line = struct.unpack('>HHLL', buf[off:off + 12])\n    off += 12\n    print('%sNregs: %d' % (ind, nregs))\n    print('%sNargs: %d' % (ind, nargs))\n    print('%sStart line number: %d' % (ind, start_line))\n    print('%sEnd line number: %d' % (ind, end_line))\n\n    compfunc_flags, = struct.unpack('>L', buf[off:off + 4])\n    off += 4\n    print('%sduk_hcompiledfunction flags: 0x%08x' % (ind, compfunc_flags))\n\n    for i in xrange(count_inst):\n        ins, = struct.unpack('>L', buf[off:off + 4])\n        off += 4\n        code = dump_ins(ins, i)\n        print('%s  %06d: %08lx %s' % (ind, i, ins, code))\n\n    print('%sConstants:' % ind)\n    for i in xrange(count_const):\n        const_type, = struct.unpack('B', buf[off:off + 1])\n        off += 1\n\n        if const_type == 0x00:\n            off, strdata = decode_sanitize_string(buf, off)\n            print('%s  %06d: %s' % (ind, i, strdata))\n        elif const_type == 0x01:\n            num, = struct.unpack('>d', buf[off:off + 8])\n            off += 8\n            print('%s  %06d: %f' % (ind, i, num))\n        else:\n            raise Exception('invalid constant type: %d' % const_type)\n\n    for i in xrange(count_funcs):\n        print('%sInner function %d:' % (ind, i))\n        off = dump_function(buf, off, ind + '  ')\n\n    val, = struct.unpack('>L', buf[off:off + 4])\n    off += 4\n    print('%s.length: %d' % (ind, val))\n    off, val = decode_sanitize_string(buf, off)\n    print('%s.name: %s' % (ind, val))\n    off, val = decode_sanitize_string(buf, off)\n    print('%s.fileName: %s' % (ind, val))\n    off, val = decode_string(buf, off)  # actually a buffer\n    print('%s._Pc2line: %s' % (ind, val.encode('hex')))\n\n    while True:\n        off, name = decode_string(buf, off)\n        if name == '':\n            break\n        name = sanitize_string(name)\n        val, = struct.unpack('>L', buf[off:off + 4])\n        off += 4\n        print('%s_Varmap[%s] = %d' % (ind, name, val))\n\n    num_formals, = struct.unpack('>L', buf[off:off + 4])\n    off += 4\n    if num_formals != 0xffffffff:\n        print('%s_Formals: %d formal arguments' % (ind, num_formals))\n        for idx in xrange(num_formals):\n            off, name = decode_string(buf, off)\n            name = sanitize_string(name)\n            print('%s_Formals[%d] = %s' % (ind, idx, name))\n    else:\n        print('%s_Formals: absent' % ind)\n\n    return off\n\ndef dump_bytecode(buf, off, ind):\n    sig, = struct.unpack('B', buf[off:off + 1])\n    print('%sSignature byte: 0x%02x' % (ind, sig))\n    off += 1\n    if sig == 0xff:\n        raise Exception('pre-Duktape 2.2 0xFF signature byte (signature byte is 0xBF since Duktape 2.2)')\n    if sig != 0xbf:\n        raise Exception('invalid signature byte: %d' % sig)\n\n    off = dump_function(buf, off, ind + '  ')\n\n    return off\n\ndef main():\n    global ops\n\n    for ops_path in [ '.',\n                      os.path.join('..', 'debugger'),\n                      script_path,\n                      os.path.join(script_path, '..', 'debugger') ]:\n        fn = os.path.join(ops_path, 'duk_opcodes.yaml')\n        if os.path.isfile(fn):\n            with open(fn) as f:\n                ops = yaml.load(f)['opcodes']\n\n    if ops is None:\n        print('WARN: duk_opcodes.yaml not found, unable do dump opcodes!')\n\n    parser = optparse.OptionParser()\n    parser.add_option('--hex-decode', dest='hex_decode', default=False, action='store_true',\n                      help='Input file is ASCII hex encoded, decode before dump')\n    (opts, args) = parser.parse_args()\n\n    with open(args[0], 'rb') as f:\n        d = f.read()\n        if opts.hex_decode:\n            d = d.strip()\n            d = d.decode('hex')\n    dump_bytecode(d, 0, '')\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/tools/extract_caseconv.py",
    "content": "#!/usr/bin/env python2\n#\n#  Extract rules for Unicode case conversion, specifically the behavior\n#  required by ECMAScript E5 in Sections 15.5.4.16 to 15.5.4.19.  The\n#  bitstream encoded rules are used for the slow path at run time, so\n#  compactness is favored over speed.\n#\n#  There is no support for context or locale sensitive rules, as they\n#  are handled directly in C code before consulting tables generated\n#  here.  ECMAScript requires case conversion both with and without\n#  locale/language specific rules (e.g. String.prototype.toLowerCase()\n#  and String.prototype.toLocaleLowerCase()), so they are best handled\n#  in C anyway.\n#\n#  Case conversion rules for ASCII are also excluded as they are handled\n#  by the C fast path.  Rules for non-BMP characters (codepoints above\n#  U+FFFF) are omitted as they're not required for standard ECMAScript.\n#\n\nimport os\nimport sys\nimport re\nimport math\nimport optparse\n\nimport dukutil\n\nclass UnicodeData:\n    \"\"\"Read UnicodeData.txt into an internal representation.\"\"\"\n\n    def __init__(self, filename):\n        self.data = self.read_unicode_data(filename)\n        print('read %d unicode data entries' % len(self.data))\n\n    def read_unicode_data(self, filename):\n        res = []\n        f = open(filename, 'rb')\n        for line in f:\n            if line.startswith('#'):\n                continue\n            line = line.strip()\n            if line == '':\n                continue\n            parts = line.split(';')\n            if len(parts) != 15:\n                raise Exception('invalid unicode data line')\n            res.append(parts)\n        f.close()\n\n        # Sort based on Unicode codepoint.\n        def mycmp(a,b):\n            return cmp(long(a[0], 16), long(b[0], 16))\n\n        res.sort(cmp=mycmp)\n        return res\n\nclass SpecialCasing:\n    \"\"\"Read SpecialCasing.txt into an internal representation.\"\"\"\n\n    def __init__(self, filename):\n        self.data = self.read_special_casing_data(filename)\n        print('read %d special casing entries' % len(self.data))\n\n    def read_special_casing_data(self, filename):\n        res = []\n        f = open(filename, 'rb')\n        for line in f:\n            try:\n                idx = line.index('#')\n                line = line[:idx]\n            except ValueError:\n                pass\n            line = line.strip()\n            if line == '':\n                continue\n            parts = line.split(';')\n            parts = [i.strip() for i in parts]\n            while len(parts) < 6:\n                parts.append('')\n            res.append(parts)\n        f.close()\n        return res\n\ndef parse_unicode_sequence(x):\n    \"\"\"Parse a Unicode sequence like ABCD 1234 into a unicode string.\"\"\"\n    res = ''\n    for i in x.split(' '):\n        i = i.strip()\n        if i == '':\n            continue\n        res += unichr(long(i, 16))\n    return res\n\ndef get_base_conversion_maps(unicode_data):\n    \"\"\"Create case conversion tables without handling special casing yet.\"\"\"\n\n    uc = {}        # uppercase, codepoint (number) -> string\n    lc = {}        # lowercase\n    tc = {}        # titlecase\n\n    for x in unicode_data.data:\n        c1 = long(x[0], 16)\n\n        # just 16-bit support needed\n        if c1 >= 0x10000:\n            continue\n\n        if x[12] != '':\n            # field 12: simple uppercase mapping\n            c2 = parse_unicode_sequence(x[12])\n            uc[c1] = c2\n            tc[c1] = c2    # titlecase default == uppercase, overridden below if necessary\n        if x[13] != '':\n            # field 13: simple lowercase mapping\n            c2 = parse_unicode_sequence(x[13])\n            lc[c1] = c2\n        if x[14] != '':\n            # field 14: simple titlecase mapping\n            c2 = parse_unicode_sequence(x[14])\n            tc[c1] = c2\n\n    return uc, lc, tc\n\ndef update_special_casings(uc, lc, tc, special_casing):\n    \"\"\"Update case conversion tables with special case conversion rules.\"\"\"\n\n    for x in special_casing.data:\n        c1 = long(x[0], 16)\n\n        if x[4] != '':\n            # conditions\n            continue\n\n        lower = parse_unicode_sequence(x[1])\n        title = parse_unicode_sequence(x[2])\n        upper = parse_unicode_sequence(x[3])\n\n        if len(lower) > 1:\n            lc[c1] = lower\n        if len(upper) > 1:\n            uc[c1] = upper\n        if len(title) > 1:\n            tc[c1] = title\n\n        print('- special case: %d %d %d' % (len(lower), len(upper), len(title)))\n\ndef remove_ascii_part(convmap):\n    \"\"\"Remove ASCII case conversion parts (handled by C fast path).\"\"\"\n\n    for i in xrange(128):\n        if convmap.has_key(i):\n            del convmap[i]\n\ndef scan_range_with_skip(convmap, start_idx, skip):\n    \"\"\"Scan for a range of continuous case conversion with a certain 'skip'.\"\"\"\n\n    conv_i = start_idx\n    if not convmap.has_key(conv_i):\n        return None, None, None\n    elif len(convmap[conv_i]) > 1:\n        return None, None, None\n    else:\n        conv_o = ord(convmap[conv_i])\n\n    start_i = conv_i\n    start_o = conv_o\n\n    while True:\n        new_i = conv_i + skip\n        new_o = conv_o + skip\n\n        if not convmap.has_key(new_i):\n            break\n        if len(convmap[new_i]) > 1:\n            break\n        if ord(convmap[new_i]) != new_o:\n            break\n\n        conv_i = new_i\n        conv_o = new_o\n\n    # [start_i,conv_i] maps to [start_o,conv_o], ignore ranges of 1 char.\n    count = (conv_i - start_i) / skip + 1\n    if count <= 1:\n        return None, None, None\n\n    # We have an acceptable range, remove them from the convmap here.\n    for i in xrange(start_i, conv_i + skip, skip):\n        del convmap[i]\n\n    return start_i, start_o, count\n\ndef find_first_range_with_skip(convmap, skip):\n    \"\"\"Find first range with a certain 'skip' value.\"\"\"\n\n    for i in xrange(65536):\n        start_i, start_o, count = scan_range_with_skip(convmap, i, skip)\n        if start_i is None:\n            continue\n        return start_i, start_o, count\n\n    return None, None, None\n\ndef generate_caseconv_tables(convmap):\n    \"\"\"Generate bit-packed case conversion table for a given conversion map.\"\"\"\n\n    # The bitstream encoding is based on manual inspection for whatever\n    # regularity the Unicode case conversion rules have.\n    #\n    # Start with a full description of case conversions which does not\n    # cover all codepoints; unmapped codepoints convert to themselves.\n    # Scan for range-to-range mappings with a range of skips starting from 1.\n    # Whenever a valid range is found, remove it from the map.  Finally,\n    # output the remaining case conversions (1:1 and 1:n) on a per codepoint\n    # basis.\n    #\n    # This is very slow because we always scan from scratch, but its the\n    # most reliable and simple way to scan\n\n    print('generate caseconv tables')\n\n    ranges = []        # range mappings (2 or more consecutive mappings with a certain skip)\n    singles = []       # 1:1 character mappings\n    multis = []        # 1:n character mappings\n\n    # Ranges with skips\n\n    for skip in xrange(1,6+1):    # skips 1...6 are useful\n        while True:\n            start_i, start_o, count = find_first_range_with_skip(convmap, skip)\n            if start_i is None:\n                break\n            print('- skip %d: %d %d %d' % (skip, start_i, start_o, count))\n            ranges.append([start_i, start_o, count, skip])\n\n    # 1:1 conversions\n\n    k = convmap.keys()\n    k.sort()\n    for i in k:\n        if len(convmap[i]) > 1:\n            continue\n        singles.append([i, ord(convmap[i])])    # codepoint, codepoint\n        del convmap[i]\n\n    # There are many mappings to 2-char sequences with latter char being U+0399.\n    # These could be handled as a special case, but we don't do that right now.\n    #\n    # [8064L, u'\\u1f08\\u0399']\n    # [8065L, u'\\u1f09\\u0399']\n    # [8066L, u'\\u1f0a\\u0399']\n    # [8067L, u'\\u1f0b\\u0399']\n    # [8068L, u'\\u1f0c\\u0399']\n    # [8069L, u'\\u1f0d\\u0399']\n    # [8070L, u'\\u1f0e\\u0399']\n    # [8071L, u'\\u1f0f\\u0399']\n    # ...\n    #\n    # tmp = {}\n    # k = convmap.keys()\n    # k.sort()\n    # for i in k:\n    #    if len(convmap[i]) == 2 and convmap[i][1] == u'\\u0399':\n    #        tmp[i] = convmap[i][0]\n    #        del convmap[i]\n    # print(repr(tmp))\n    #\n    # skip = 1\n    # while True:\n    #    start_i, start_o, count = find_first_range_with_skip(tmp, skip)\n    #    if start_i is None:\n    #        break\n    #    print('- special399, skip %d: %d %d %d' % (skip, start_i, start_o, count))\n    # print(len(tmp.keys()))\n    # print(repr(tmp))\n    # XXX: need to put 12 remaining mappings back to convmap\n\n    # 1:n conversions\n\n    k = convmap.keys()\n    k.sort()\n    for i in k:\n        multis.append([i, convmap[i]])        # codepoint, string\n        del convmap[i]\n\n    for t in singles:\n        print '- singles: ' + repr(t)\n\n    for t in multis:\n        print '- multis: ' + repr(t)\n\n    print '- range mappings: %d' % len(ranges)\n    print '- single character mappings: %d' % len(singles)\n    print '- complex mappings (1:n): %d' % len(multis)\n    print '- remaining (should be zero): %d' % len(convmap.keys())\n\n    # XXX: opportunities for diff encoding skip=3 ranges?\n    prev = None\n    for t in ranges:\n        # range: [start_i, start_o, count, skip]\n        if t[3] != 3:\n            continue\n        if prev is not None:\n            print '- %d %d' % (t[0] - prev[0], t[1] - prev[1])\n        else:\n            print '- start: %d %d' % (t[0], t[1])\n        prev = t\n\n    # Bit packed encoding.\n\n    be = dukutil.BitEncoder()\n\n    for curr_skip in xrange(1, 7):    # 1...6\n        count = 0\n        for r in ranges:\n            start_i, start_o, r_count, skip = r[0], r[1], r[2], r[3]\n            if skip != curr_skip:\n                continue\n            count += 1\n        be.bits(count, 6)\n        print('- encode: skip=%d, count=%d' % (curr_skip, count))\n\n        for r in ranges:\n            start_i, start_o, r_count, skip = r[0], r[1], r[2], r[3]\n            if skip != curr_skip:\n                continue\n            be.bits(start_i, 16)\n            be.bits(start_o, 16)\n            be.bits(r_count, 7)\n    be.bits(0x3f, 6)    # maximum count value = end of skips\n\n    count = len(singles)\n    be.bits(count, 7)\n    for t in singles:\n        cp_i, cp_o = t[0], t[1]\n        be.bits(cp_i, 16)\n        be.bits(cp_o, 16)\n\n    count = len(multis)\n    be.bits(count, 7)\n    for t in multis:\n        cp_i, str_o = t[0], t[1]\n        be.bits(cp_i, 16)\n        be.bits(len(str_o), 2)\n        for i in xrange(len(str_o)):\n            be.bits(ord(str_o[i]), 16)\n\n    return be.getBytes(), be.getNumBits()\n\ndef generate_regexp_canonicalize_tables(convmap):\n    \"\"\"Generate tables for case insensitive RegExp normalization.\"\"\"\n\n    # Generate a direct codepoint lookup for canonicalizing BMP range.\n\n    def generate_canontab():\n        res = []\n        highest_nonid = -1\n\n        for cp in xrange(65536):\n            res_cp = cp  # default to as is\n            if convmap.has_key(cp):\n                tmp = convmap[cp]\n                if len(tmp) == 1:\n                    # If multiple codepoints from input, ignore.\n                    res_cp = ord(tmp[0])\n            if cp >= 0x80 and res_cp < 0x80:\n                res_cp = cp  # If non-ASCII mapped to ASCII, ignore.\n            if cp != res_cp:\n                highest_nonid = cp\n            res.append(res_cp)\n\n        # At the moment this is 65370, which means there's very little\n        # gain in assuming 1:1 mapping above a certain BMP codepoint\n        # (though we do assume 1:1 mapping for above BMP codepoints).\n        print('- highest non-identity mapping: %d' % highest_nonid)\n\n        return res\n\n    print('generate canontab')\n    canontab = generate_canontab()\n\n    # Figure out which BMP values are never the result of canonicalization.\n    # Such codepoints are \"don't care\" in the sense that they are never\n    # matched against at runtime: ranges are canonicalized at compile time,\n    # and codepoint being matched is also canonicalized at run time.\n    # (Currently unused.)\n\n    def generate_dontcare():\n        res = [ True ] * 65536\n        for cp in canontab:\n            res[cp] = False\n        res_count = 0\n        for x in res:\n            if x:\n                res_count += 1\n        print('- %d dontcare codepoints' % res_count)\n        return res\n\n    print('generate canon dontcare')\n    dontcare = generate_dontcare()\n\n    # Generate maximal continuous ranges for canonicalization.  A continuous\n    # range is a sequence with N codepoints where IN+i canonicalizes to OUT+i\n    # for fixed IN, OUT, and i in 0...N-1.  There are unfortunately >1000\n    # of these ranges, mostly because there are a lot of individual exceptions.\n    # (Currently unused.)\n\n    canon_ranges = []\n    for cp in xrange(65536):\n       canon_ranges.append([ cp, canontab[cp], 1 ])  # 1 codepoint ranges at first\n    def merge_compatible_nogap(rng1, rng2):\n        # Merge adjacent ranges if continuity allows.\n        if rng1[0] + rng1[2] == rng2[0] and \\\n           rng1[1] + rng1[2] == rng2[1]:\n            return [ rng1[0], rng1[1], rng1[2] + rng2[2] ]\n        return None\n    def merge_check_nogap():\n        len_start = len(canon_ranges)\n        for i in xrange(len(canon_ranges) - 1):\n            j = i + 1\n            rng1 = canon_ranges[i]\n            rng2 = canon_ranges[j]\n            if rng1 is None or rng2 is None: continue\n            merged = merge_compatible_nogap(rng1, rng2)\n            if merged is not None:\n                canon_ranges[j] = None\n                canon_ranges[i] = merged\n        filtered = []\n        for x in canon_ranges:\n            if x is not None:\n                filtered.append(x)\n        len_end = len(filtered)\n        if len_end < len_start:\n            return filtered\n        return None\n\n    print('generate canon_ranges')\n    while True:\n        # Starting from individual ranges of 1 codepoint, merge adjacent\n        # ranges until no more ranges can be merged.\n        t = merge_check_nogap()\n        if t is None:\n            break\n        canon_ranges = t\n    print('- %d ranges' % len(canon_ranges))\n    #for rng in canon_ranges:\n    #    print('canon_ranges:')\n    #    print(repr(rng))\n\n    # Generate true/false ranges for BMP codepoints where:\n    # - A codepoint is flagged true if continuity is broken at that point, so\n    #   an explicit codepoint canonicalization is needed at runtime.\n    # - A codepoint is flagged false if case conversion is continuous from the\n    #   previous codepoint, i.e. out_curr = out_prev + 1.\n    #\n    # The result is a lot of small ranges due to a lot of small 'false' ranges.\n    # Reduce the range set by checking if adjacent 'true' ranges have at most\n    # false_limit 'false' entries between them.  If so, force the 'false'\n    # entries to 'true' (safe but results in an unnecessary runtime codepoint\n    # lookup) and merge the three ranges into a larger 'true' range.\n    #\n    # (Currently unused.)\n\n    def generate_needcheck_straight():\n        res = [ True ] * 65536\n        assert(canontab[0] == 0)  # can start from in == out == 0\n        prev_in = -1\n        prev_out = -1\n        for i in xrange(65536):\n            # First create a straight true/false bitmap for BMP.\n            curr_in = i\n            curr_out = canontab[i]\n            if prev_in + 1 == curr_in and prev_out + 1 == curr_out:\n                res[i] = False\n            prev_in = curr_in\n            prev_out = curr_out\n        return res\n    def generate_needcheck_ranges(data):\n        # Generate maximal accurate ranges.\n        prev = None\n        count = 0\n        ranges = []\n        for i in data:\n            if prev is None or prev != i:\n                if prev is not None:\n                    ranges.append([ prev, count ])\n                prev = i\n                count = 1\n            else:\n                count += 1\n        if prev is not None:\n            ranges.append([ prev, count ])\n        return ranges\n    def fillin_needcheck_ranges(data, false_limit):\n        # Fill in TRUE-FALSE*N-TRUE gaps into TRUE-TRUE*N-TRUE which is\n        # safe (leads to an unnecessary runtime check) but reduces\n        # range data size considerably.\n        res = []\n        for r in data:\n            res.append([ r[0], r[1] ])\n        while True:\n            found = False\n            for i in xrange(len(res) - 2):\n                r1 = res[i]\n                r2 = res[i + 1]\n                r3 = res[i + 2]\n                if r1[0] == True and r2[0] == False and r3[0] == True and \\\n                   r2[1] <= false_limit:\n                    #print('fillin %d falses' % r2[1])\n                    res.pop(i + 2)\n                    res.pop(i + 1)\n                    res[i] = [ True, r1[1] + r2[1] + r3[1] ]\n                    found = True\n                    break\n            if not found:\n                break\n        return res\n\n    print('generate needcheck straight')\n    needcheck = generate_needcheck_straight()\n\n    print('generate needcheck without false fillins')\n    needcheck_ranges1 = generate_needcheck_ranges(needcheck)\n    print('- %d ranges' % len(needcheck_ranges1))\n    #print(needcheck_ranges1)\n\n    print('generate needcheck with false fillins')\n    needcheck_ranges2 = fillin_needcheck_ranges(needcheck_ranges1, 11)\n    print('- %d ranges' % len(needcheck_ranges2))\n    #print(needcheck_ranges2)\n\n    # Generate a bitmap for BMP, divided into N-codepoint blocks, with each\n    # bit indicating: \"entire codepoint block canonicalizes continuously, and\n    # the block is continuous with the previous and next block\".  A 'true'\n    # entry allows runtime code to just skip the block, advancing 'in' and\n    # 'out' by the block size, with no codepoint conversion.  The block size\n    # should be large enough to produce a relatively small lookup table, but\n    # small enough to reduce codepoint conversions to a manageable number\n    # because the conversions are (currently) quite slow.  This matters\n    # especially for case-insensitive RegExps; without any optimization,\n    # /[\\u0000-\\uffff]/i requires 65536 case conversions for runtime\n    # normalization.\n\n    block_shift = 5\n    block_size = 1 << block_shift\n    block_mask = block_size - 1\n    num_blocks = 65536 / block_size\n\n    def generate_block_bits(check_continuity):\n        res = [ True ] * num_blocks\n        for i in xrange(num_blocks):\n            base_in = i * block_size\n            base_out = canontab[base_in]\n            if check_continuity:\n                lower = -1   # [-1,block_size]\n                upper = block_size + 1\n            else:\n                lower = 0    # [0,block_size-1]\n                upper = block_size\n            for j in xrange(lower, upper):\n                cp = base_in + j\n                if cp >= 0x0000 and cp <= 0xffff and canontab[cp] != base_out + j:\n                   res[i] = False\n                   break\n        return res\n\n    def dump_block_bitmap(bits):\n        tmp = ''.join([ ({ True: 'x', False: '.' })[b] for b in bits])\n        tmp = re.sub(r'.{64}', lambda x: x.group(0) + '\\n', tmp)\n        blocks_true = tmp.count('x')\n        blocks_false = tmp.count('.')\n        print('%d codepoint blocks are continuous, %d blocks are not' % (blocks_true, blocks_false))\n        sys.stdout.write(tmp)\n        #print(bits)\n\n    def dump_test_lookup(bits):\n        sys.stdout.write('duk_uint8_t test = {');\n        for b in bits:\n            if b:\n                sys.stdout.write('1,')\n            else:\n                sys.stdout.write('0,')\n        sys.stdout.write('};\\n')\n\n    def convert_to_bitmap(bits):\n        # C code looks up bits as:\n        #   index = codepoint >> N\n        #   bitnum = codepoint & mask\n        #   bitmask = 1 << bitnum\n        # So block 0 is mask 0x01 of first byte, block 1 is mask 0x02 of\n        # first byte, etc.\n        res = []\n        curr = 0\n        mask = 0x01\n        for b in bits:\n            if b:\n                curr += mask\n            mask = mask * 2\n            if mask == 0x100:\n                res.append(curr)\n                curr = 0\n                mask = 0x01\n        assert(mask == 0x01)  # no leftover\n        return res\n\n    print('generate canon block bitmap without continuity')\n    block_bits1 = generate_block_bits(False)\n    dump_block_bitmap(block_bits1)\n    dump_test_lookup(block_bits1)\n\n    print('generate canon block bitmap with continuity')\n    block_bits2 = generate_block_bits(True)\n    dump_block_bitmap(block_bits2)\n    dump_test_lookup(block_bits2)\n\n    print('generate final canon bitmap')\n    block_bitmap = convert_to_bitmap(block_bits2)\n    print('- %d bytes' % len(block_bitmap))\n    print('- ' + repr(block_bitmap))\n    canon_bitmap = {\n        'data': block_bitmap,\n        'block_size': block_size,\n        'block_shift': block_shift,\n        'block_mask': block_mask\n    }\n\n    # This is useful to figure out corner case test cases.\n    print('canon blocks which are different with and without continuity check')\n    for i in xrange(num_blocks):\n        if block_bits1[i] != block_bits2[i]:\n            print('- block %d ([%d,%d]) differs' % (i, i * block_size, i * block_size + block_size - 1))\n\n    return canontab, canon_bitmap\n\ndef clonedict(x):\n    \"Shallow clone of input dict.\"\n    res = {}\n    for k in x.keys():\n        res[k] = x[k]\n    return res\n\ndef main():\n    parser = optparse.OptionParser()\n    parser.add_option('--command', dest='command', default='caseconv_bitpacked')\n    parser.add_option('--unicode-data', dest='unicode_data')\n    parser.add_option('--special-casing', dest='special_casing')\n    parser.add_option('--out-source', dest='out_source')\n    parser.add_option('--out-header', dest='out_header')\n    parser.add_option('--table-name-lc', dest='table_name_lc', default='caseconv_lc')\n    parser.add_option('--table-name-uc', dest='table_name_uc', default='caseconv_uc')\n    parser.add_option('--table-name-re-canon-lookup', dest='table_name_re_canon_lookup', default='caseconv_re_canon_lookup')\n    parser.add_option('--table-name-re-canon-bitmap', dest='table_name_re_canon_bitmap', default='caseconv_re_canon_bitmap')\n    (opts, args) = parser.parse_args()\n\n    unicode_data = UnicodeData(opts.unicode_data)\n    special_casing = SpecialCasing(opts.special_casing)\n\n    uc, lc, tc = get_base_conversion_maps(unicode_data)\n    update_special_casings(uc, lc, tc, special_casing)\n\n    if opts.command == 'caseconv_bitpacked':\n        # XXX: ASCII and non-BMP filtering could be an option but is now hardcoded\n\n        # ASCII is handled with 'fast path' so not needed here.\n        t = clonedict(uc)\n        remove_ascii_part(t)\n        uc_bytes, uc_nbits = generate_caseconv_tables(t)\n\n        t = clonedict(lc)\n        remove_ascii_part(t)\n        lc_bytes, lc_nbits = generate_caseconv_tables(t)\n\n        # Generate C source and header files.\n        genc = dukutil.GenerateC()\n        genc.emitHeader('extract_caseconv.py')\n        genc.emitArray(uc_bytes, opts.table_name_uc, size=len(uc_bytes), typename='duk_uint8_t', intvalues=True, const=True)\n        genc.emitArray(lc_bytes, opts.table_name_lc, size=len(lc_bytes), typename='duk_uint8_t', intvalues=True, const=True)\n        f = open(opts.out_source, 'wb')\n        f.write(genc.getString())\n        f.close()\n\n        genc = dukutil.GenerateC()\n        genc.emitHeader('extract_caseconv.py')\n        genc.emitLine('extern const duk_uint8_t %s[%d];' % (opts.table_name_uc, len(uc_bytes)))\n        genc.emitLine('extern const duk_uint8_t %s[%d];' % (opts.table_name_lc, len(lc_bytes)))\n        f = open(opts.out_header, 'wb')\n        f.write(genc.getString())\n        f.close()\n    elif opts.command == 're_canon_lookup':\n        # Direct canonicalization lookup for case insensitive regexps, includes ascii part.\n        t = clonedict(uc)\n        re_canon_lookup, re_canon_bitmap = generate_regexp_canonicalize_tables(t)\n\n        genc = dukutil.GenerateC()\n        genc.emitHeader('extract_caseconv.py')\n        genc.emitArray(re_canon_lookup, opts.table_name_re_canon_lookup, size=len(re_canon_lookup), typename='duk_uint16_t', intvalues=True, const=True)\n        f = open(opts.out_source, 'wb')\n        f.write(genc.getString())\n        f.close()\n\n        genc = dukutil.GenerateC()\n        genc.emitHeader('extract_caseconv.py')\n        genc.emitLine('extern const duk_uint16_t %s[%d];' % (opts.table_name_re_canon_lookup, len(re_canon_lookup)))\n        f = open(opts.out_header, 'wb')\n        f.write(genc.getString())\n        f.close()\n    elif opts.command == 're_canon_bitmap':\n        # N-codepoint block bitmap for skipping continuous codepoint blocks\n        # quickly.\n        t = clonedict(uc)\n        re_canon_lookup, re_canon_bitmap = generate_regexp_canonicalize_tables(t)\n\n        genc = dukutil.GenerateC()\n        genc.emitHeader('extract_caseconv.py')\n        genc.emitArray(re_canon_bitmap['data'], opts.table_name_re_canon_bitmap, size=len(re_canon_bitmap['data']), typename='duk_uint8_t', intvalues=True, const=True)\n        f = open(opts.out_source, 'wb')\n        f.write(genc.getString())\n        f.close()\n\n        genc = dukutil.GenerateC()\n        genc.emitHeader('extract_caseconv.py')\n        genc.emitDefine('DUK_CANON_BITMAP_BLKSIZE', re_canon_bitmap['block_size'])\n        genc.emitDefine('DUK_CANON_BITMAP_BLKSHIFT', re_canon_bitmap['block_shift'])\n        genc.emitDefine('DUK_CANON_BITMAP_BLKMASK', re_canon_bitmap['block_mask'])\n        genc.emitLine('extern const duk_uint8_t %s[%d];' % (opts.table_name_re_canon_bitmap, len(re_canon_bitmap['data'])))\n        f = open(opts.out_header, 'wb')\n        f.write(genc.getString())\n        f.close()\n    else:\n        raise Exception('invalid command: %r' % opts.command)\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/tools/extract_chars.py",
    "content": "#!/usr/bin/env python2\n#\n#  Select a set of Unicode characters (based on included/excluded categories\n#  etc) and write out a compact bitstream for matching a character against\n#  the set at runtime.  This is for the slow path, where we're especially\n#  concerned with compactness.  A C source file with the table is written,\n#  together with a matching C header.\n#\n#  Unicode categories (such as 'Z') can be used.  Two pseudo-categories\n#  are also available for exclusion only: ASCII and NONBMP.  \"ASCII\"\n#  category excludes ASCII codepoints which is useful because C code\n#  typically contains an ASCII fast path so ASCII characters don't need\n#  to be considered in the Unicode tables.  \"NONBMP\" excludes codepoints\n#  above U+FFFF which is useful because such codepoints don't need to be\n#  supported in standard ECMAScript.\n#\n\nimport os\nimport sys\nimport math\nimport optparse\n\nimport dukutil\n\ndef read_unicode_data(unidata, catsinc, catsexc, filterfunc):\n    \"Read UnicodeData.txt, including lines matching catsinc unless excluded by catsexc or filterfunc.\"\n    res = []\n    f = open(unidata, 'rb')\n\n    def filter_none(cp):\n        return True\n    if filterfunc is None:\n        filterfunc = filter_none\n\n    # The Unicode parsing is slow enough to warrant some speedups.\n    exclude_cat_exact = {}\n    for cat in catsexc:\n        exclude_cat_exact[cat] = True\n    include_cat_exact = {}\n    for cat in catsinc:\n        include_cat_exact[cat] = True\n\n    for line in f:\n        #line = line.strip()\n        parts = line.split(';')\n\n        codepoint = parts[0]\n        if not filterfunc(long(codepoint, 16)):\n            continue\n\n        category = parts[2]\n        if exclude_cat_exact.has_key(category):\n            continue  # quick reject\n\n        rejected = False\n        for cat in catsexc:\n            if category.startswith(cat) or codepoint == cat:\n                rejected = True\n                break\n        if rejected:\n            continue\n\n        if include_cat_exact.has_key(category):\n            res.append(line)\n            continue\n\n        accepted = False\n        for cat in catsinc:\n            if category.startswith(cat) or codepoint == cat:\n                accepted = True\n                break\n        if accepted:\n            res.append(line)\n\n    f.close()\n\n    # Sort based on Unicode codepoint\n    def mycmp(a,b):\n        t1 = a.split(';')\n        t2 = b.split(';')\n        n1 = long(t1[0], 16)\n        n2 = long(t2[0], 16)\n        return cmp(n1, n2)\n\n    res.sort(cmp=mycmp)\n\n    return res\n\ndef scan_ranges(lines):\n    \"Scan continuous ranges from (filtered) UnicodeData.txt lines.\"\n    ranges = []\n    range_start = None\n    prev = None\n\n    for line in lines:\n        t = line.split(';')\n        n = long(t[0], 16)\n        if range_start is None:\n            range_start = n\n        else:\n            if n == prev + 1:\n                # continue range\n                pass\n            else:\n                ranges.append((range_start, prev))\n                range_start = n\n        prev = n\n\n    if range_start is not None:\n        ranges.append((range_start, prev))\n\n    return ranges\n\ndef generate_png(lines, fname):\n    \"Generate an illustrative PNG of the character set.\"\n    from PIL import Image\n\n    m = {}\n    for line in lines:\n        t = line.split(';')\n        n = long(t[0], 16)\n        m[n] = 1\n\n    codepoints = 0x10ffff + 1\n    width = int(256)\n    height = int(math.ceil(float(codepoints) / float(width)))\n    im = Image.new('RGB', (width, height))\n    black = (0,0,0)\n    white = (255,255,255)\n    for cp in xrange(codepoints):\n        y = cp / width\n        x = cp % width\n\n        if m.has_key(long(cp)):\n            im.putpixel((x,y), black)\n        else:\n            im.putpixel((x,y), white)\n\n    im.save(fname)\n\ndef generate_match_table1(ranges):\n    \"Unused match table format.\"\n\n    # This is an earlier match table format which is no longer used.\n    # IdentifierStart-UnicodeLetter has 445 ranges and generates a\n    # match table of 2289 bytes.\n\n    data = []\n    prev_re = None\n\n    def genrange(rs, re):\n        if (rs > re):\n            raise Exception('assumption failed: rs=%d re=%d' % (rs, re))\n\n        while True:\n            now = re - rs + 1\n            if now > 255:\n                now = 255\n                data.append(now)    # range now\n                data.append(0)        # skip 0\n                rs = rs + now\n            else:\n                data.append(now)    # range now\n                break\n\n    def genskip(ss, se):\n        if (ss > se):\n            raise Exception('assumption failed: ss=%d se=%s' % (ss, se))\n\n        while True:\n            now = se - ss + 1\n            if now > 255:\n                now = 255\n                data.append(now)    # skip now\n                data.append(0)        # range 0\n                ss = ss + now\n            else:\n                data.append(now)    # skip now\n                break\n\n    for rs, re in ranges:\n        if prev_re is not None:\n            genskip(prev_re + 1, rs - 1)\n        genrange(rs, re)\n        prev_re = re\n\n    num_entries = len(data)\n\n    # header: start of first range\n    #         num entries\n    hdr = []\n    hdr.append(ranges[0][0] >> 8)    # XXX: check that not 0x10000 or over\n    hdr.append(ranges[0][1] & 0xff)\n    hdr.append(num_entries >> 8)\n    hdr.append(num_entries & 0xff)\n\n    return hdr + data\n\ndef generate_match_table2(ranges):\n    \"Unused match table format.\"\n\n    # Another attempt at a match table which is also unused.\n    # Total tables for all current classes is now 1472 bytes.\n\n    data = []\n\n    def enc(x):\n        while True:\n            if x < 0x80:\n                data.append(x)\n                break\n            data.append(0x80 + (x & 0x7f))\n            x = x >> 7\n\n    prev_re = 0\n\n    for rs, re in ranges:\n        r1 = rs - prev_re    # 1 or above (no unjoined ranges)\n        r2 = re - rs        # 0 or above\n        enc(r1)\n        enc(r2)\n        prev_re = re\n\n    enc(0)    # end marker\n\n    return data\n\ndef generate_match_table3(ranges):\n    \"Current match table format.\"\n\n    # Yet another attempt, similar to generate_match_table2 except\n    # in packing format.\n    #\n    # Total match size now (at time of writing): 1194 bytes.\n    #\n    # This is the current encoding format used in duk_lexer.c.\n\n    be = dukutil.BitEncoder()\n\n    freq = [0] * (0x10ffff + 1)  # informative\n\n    def enc(x):\n        freq[x] += 1\n\n        if x <= 0x0e:\n            # 4-bit encoding\n            be.bits(x, 4)\n            return\n        x -= 0x0e + 1\n        if x <= 0xfd:\n            # 12-bit encoding\n            be.bits(0x0f, 4)\n            be.bits(x, 8)\n            return\n        x -= 0xfd + 1\n        if x <= 0xfff:\n            # 24-bit encoding\n            be.bits(0x0f, 4)\n            be.bits(0xfe, 8)\n            be.bits(x, 12)\n            return\n        x -= 0xfff + 1\n        if True:\n            # 36-bit encoding\n            be.bits(0x0f, 4)\n            be.bits(0xff, 8)\n            be.bits(x, 24)\n            return\n\n        raise Exception('cannot encode')\n\n    prev_re = 0\n\n    for rs, re in ranges:\n        r1 = rs - prev_re    # 1 or above (no unjoined ranges)\n        r2 = re - rs        # 0 or above\n        enc(r1)\n        enc(r2)\n        prev_re = re\n\n    enc(0)    # end marker\n\n    data, nbits = be.getBytes(), be.getNumBits()\n    return data, freq\n\ndef main():\n    parser = optparse.OptionParser()\n    parser.add_option('--unicode-data', dest='unicode_data')      # UnicodeData.txt\n    parser.add_option('--special-casing', dest='special_casing')  # SpecialCasing.txt\n    parser.add_option('--include-categories', dest='include_categories')\n    parser.add_option('--exclude-categories', dest='exclude_categories', default='NONE')\n    parser.add_option('--out-source', dest='out_source')\n    parser.add_option('--out-header', dest='out_header')\n    parser.add_option('--out-png', dest='out_png')\n    parser.add_option('--table-name', dest='table_name', default='match_table')\n    (opts, args) = parser.parse_args()\n\n    unidata = opts.unicode_data\n    catsinc = []\n    if opts.include_categories != '':\n        catsinc = opts.include_categories.split(',')\n    catsexc = []\n    if opts.exclude_categories != 'NONE':\n        catsexc = opts.exclude_categories.split(',')\n\n    print 'CATSEXC: %s' % repr(catsexc)\n    print 'CATSINC: %s' % repr(catsinc)\n\n    # pseudocategories\n    filter_ascii = ('ASCII' in catsexc)\n    filter_nonbmp = ('NONBMP' in catsexc)\n\n    # Read raw result\n    def filter1(x):\n        if filter_ascii and x <= 0x7f:\n            # exclude ascii\n            return False\n        if filter_nonbmp and x >= 0x10000:\n            # exclude non-bmp\n            return False\n        return True\n\n    print('read unicode data')\n    uni_filtered = read_unicode_data(unidata, catsinc, catsexc, filter1)\n    print('done reading unicode data')\n\n    # Raw output\n    #print('RAW OUTPUT:')\n    #print('===========')\n    #print('\\n'.join(uni_filtered))\n\n    # Scan ranges\n    #print('')\n    #print('RANGES:')\n    #print('=======')\n    ranges = scan_ranges(uni_filtered)\n    #for i in ranges:\n    #    if i[0] == i[1]:\n    #        print('0x%04x' % i[0])\n    #    else:\n    #        print('0x%04x ... 0x%04x' % (i[0], i[1]))\n    #print('')\n    print('%d ranges total' % len(ranges))\n\n    # Generate match table\n    #print('')\n    #print('MATCH TABLE:')\n    #print('============')\n    #matchtable1 = generate_match_table1(ranges)\n    #matchtable2 = generate_match_table2(ranges)\n    matchtable3, freq = generate_match_table3(ranges)\n    #print 'match table: %s' % repr(matchtable3)\n    print 'match table length: %d bytes' % len(matchtable3)\n    print 'encoding freq:'\n    for i in xrange(len(freq)):\n        if freq[i] == 0:\n            continue\n        print '  %6d: %d' % (i, freq[i])\n\n    print('')\n    print('MATCH C TABLE -> file %s' % repr(opts.out_header))\n\n    # Create C source and header files\n    genc = dukutil.GenerateC()\n    genc.emitHeader('extract_chars.py')\n    genc.emitArray(matchtable3, opts.table_name, size=len(matchtable3), typename='duk_uint8_t', intvalues=True, const=True)\n    if opts.out_source is not None:\n        f = open(opts.out_source, 'wb')\n        f.write(genc.getString())\n        f.close()\n\n    genc = dukutil.GenerateC()\n    genc.emitHeader('extract_chars.py')\n    genc.emitLine('extern const duk_uint8_t %s[%d];' % (opts.table_name, len(matchtable3)))\n    if opts.out_header is not None:\n        f = open(opts.out_header, 'wb')\n        f.write(genc.getString())\n        f.close()\n\n    # Image (for illustrative purposes only)\n    if opts.out_png is not None:\n        generate_png(uni_filtered, opts.out_png)\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/tools/extract_unique_options.py",
    "content": "#!/usr/bin/env python2\n#\n#  Extract unique DUK_USE_xxx flags from current code base:\n#\n#    $ python extract_unique_options.py ../src-input/*.c ../src-input/*.h ../src-input/*.h.in\n#\n\nimport os, sys, re\n\n# DUK_USE_xxx/DUK_OPT_xxx are used as placeholders and not matched\n# (only uppercase allowed)\nre_use = re.compile(r'DUK_USE_[A-Z0-9_]+')\nre_opt = re.compile(r'DUK_OPT_[A-Z0-9_]+')  # removed in Duktape 2.x; match anyway just in case\n\ndef main():\n    uses = {}\n    opts = {}\n\n    for fn in sys.argv[1:]:\n        f = open(fn, 'rb')\n        for line in f:\n            for t in re.findall(re_use, line):\n                if t[-1] != '_':  # skip e.g. 'DUK_USE_'\n                    uses[t] = True\n            for t in re.findall(re_opt, line):\n                if t[-1] != '_':\n                    opts[t] = True\n        f.close()\n\n    k = opts.keys()\n    k.sort()\n    for i in k:\n        print(i)\n\n    k = uses.keys()\n    k.sort()\n    for i in k:\n        print(i)\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/tools/genbuiltins.py",
    "content": "#!/usr/bin/env python2\n#\n#  Generate initialization data for built-in strings and objects.\n#\n#  Supports two different initialization approaches:\n#\n#    1. Bit-packed format for unpacking strings and objects during\n#       heap or thread init into RAM-based structures.  This is the\n#       default behavior.\n#\n#    2. Embedding strings and/or objects into a read-only data section\n#       at compile time.  This is useful for low memory targets to reduce\n#       memory usage.  Objects in data section will be immutable.\n#\n#  Both of these have practical complications like endianness differences,\n#  pointer compression variants, object property table layout variants,\n#  and so on.  Multiple #if defined()'d initializer sections are emitted\n#  to cover all supported alternatives.\n#\n\nimport logging\nimport sys\nlogging.basicConfig(level=logging.INFO, stream=sys.stdout, format='%(name)-21s %(levelname)-7s %(message)s')\nlogger = logging.getLogger('genbuiltins.py')\nlogger.setLevel(logging.INFO)\n\nimport os\nimport re\nimport traceback\nimport json\nimport yaml\nimport math\nimport struct\nimport optparse\nimport copy\nimport logging\n\nimport dukutil\n\n# Fixed seed for ROM strings, must match src-input/duk_heap_alloc.c.\nDUK__FIXED_HASH_SEED = 0xabcd1234\n\n# Base value for compressed ROM pointers, used range is [ROMPTR_FIRST,0xffff].\n# Must match DUK_USE_ROM_PTRCOMP_FIRST (generated header checks).\nROMPTR_FIRST = 0xf800  # 2048 should be enough; now around ~1000 used\n\n# ROM string table size\nROMSTR_LOOKUP_SIZE = 256\n\n#\n#  Miscellaneous helpers\n#\n\n# Convert Unicode to bytes, identifying Unicode U+0000 to U+00FF as bytes.\n# This representation is used in YAML metadata and allows invalid UTF-8 to\n# be represented exactly (which is necessary).\ndef unicode_to_bytes(x):\n    if isinstance(x, str):\n        return x\n    tmp = ''\n    for c in x:\n        if ord(c) > 0xff:\n            raise Exception('invalid codepoint: %r' % x)\n        tmp += chr(ord(c))\n    assert(isinstance(tmp, str))\n    return tmp\n\n# Convert bytes to Unicode, identifying bytes as U+0000 to U+00FF.\ndef bytes_to_unicode(x):\n    if isinstance(x, unicode):\n        return x\n    tmp = u''\n    for c in x:\n        tmp += unichr(ord(c))\n    assert(isinstance(tmp, unicode))\n    return tmp\n\n# Convert all strings in an object to bytes recursively.  Useful for\n# normalizing all strings in a YAML document.\ndef recursive_strings_to_bytes(doc):\n    def f(x):\n        if isinstance(x, unicode):\n            return unicode_to_bytes(x)\n        if isinstance(x, dict):\n            res = {}\n            for k in x.keys():\n                res[f(k)] = f(x[k])\n            return res\n        if isinstance(x, list):\n            res = []\n            for e in x:\n                res.append(f(e))\n            return res\n        return x\n\n    return f(doc)\n\n# Convert all strings in an object to from bytes to Unicode recursively.\n# Useful for writing back JSON/YAML dumps.\ndef recursive_bytes_to_strings(doc):\n    def f(x):\n        if isinstance(x, str):\n            return bytes_to_unicode(x)\n        if isinstance(x, dict):\n            res = {}\n            for k in x.keys():\n                res[f(k)] = f(x[k])\n            return res\n        if isinstance(x, list):\n            res = []\n            for e in x:\n                res.append(f(e))\n            return res\n        return x\n\n    return f(doc)\n\n# Check if string is an \"array index\" in ECMAScript terms.\ndef string_is_arridx(v):\n    is_arridx = False\n    try:\n        ival = int(v)\n        if ival >= 0 and ival <= 0xfffffffe and ('%d' % ival == v):\n            is_arridx = True\n    except ValueError:\n        pass\n\n    return is_arridx\n\n#\n#  Metadata loading, merging, and other preprocessing\n#\n#  Final metadata object contains merged and normalized objects and strings.\n#  Keys added include (see more below):\n#\n#    strings_stridx: string objects which have a stridx, matches stridx index order\n#    objects_bidx: objects which have a bidx, matches bidx index order\n#    objects_ram_toplevel: objects which are top level for RAM init\n#\n#  Various helper keys are also added, containing auxiliary object/string\n#  lists, lookup maps, etc.  See code below for details of these.\n#\n\ndef metadata_lookup_object(meta, obj_id):\n    return meta['_objid_to_object'][obj_id]\n\ndef metadata_lookup_object_and_index(meta, obj_id):\n    for i,t in enumerate(meta['objects']):\n        if t['id'] == obj_id:\n            return t, i\n    return None, None\n\ndef metadata_lookup_property(obj, key):\n    for p in obj['properties']:\n        if p['key'] == key:\n            return p\n    return None\n\ndef metadata_lookup_property_and_index(obj, key):\n    for i,t in enumerate(obj['properties']):\n        if t['key'] == key:\n            return t, i\n    return None, None\n\n# Remove disabled objects and properties.\ndef metadata_remove_disabled(meta, active_opts):\n    objlist = []\n\n    count_disabled_object = 0\n    count_notneeded_object = 0\n    count_disabled_property = 0\n    count_notneeded_property = 0\n\n    def present_if_check(v):\n        pi = v.get('present_if', None)\n        if pi is None:\n            return True\n        if isinstance(pi, (str, unicode)):\n            pi = [ pi ]\n        if not isinstance(pi, list):\n            raise Exception('invalid present_if syntax: %r' % pi)\n        # Present if all listed options are true or unknown.\n        # Absent if any option is known to be false.\n        for opt in pi:\n            if active_opts.get(opt, None) == False:\n                return False\n        return True\n\n    for o in meta['objects']:\n        if o.get('disable', False):\n            logger.debug('Remove disabled object: %s' % o['id'])\n            count_disabled_object += 1\n        elif not present_if_check(o):\n            logger.debug('Removed object not needed in active configuration: %s' % o['id'])\n            count_notneeded_object += 1\n        else:\n            objlist.append(o)\n\n        props = []\n        for p in o['properties']:\n            if p.get('disable', False):\n                logger.debug('Remove disabled property: %s, object: %s' % (p['key'], o['id']))\n                count_disabled_property += 1\n            elif not present_if_check(p):\n                logger.debug('Removed property not needed in active configuration: %s, object: %s' % (p['key'], o['id']))\n                count_notneeded_property += 1\n            else:\n                props.append(p)\n\n        o['properties'] = props\n\n    meta['objects'] = objlist\n\n    if count_disabled_object + count_notneeded_object + count_disabled_property + count_notneeded_property > 0:\n        logger.info('Removed %d objects (%d disabled, %d not needed by config), %d properties (%d disabled, %d not needed by config)' % (count_disabled_object + count_notneeded_object, count_disabled_object, count_notneeded_object, count_disabled_property + count_notneeded_property, count_disabled_property, count_notneeded_property))\n\n# Delete dangling references to removed/missing objects.\ndef metadata_delete_dangling_references_to_object(meta, obj_id):\n    for o in meta['objects']:\n        new_p = []\n        for p in o['properties']:\n            v = p['value']\n            ptype = None\n            if isinstance(v, dict):\n                ptype = p['value']['type']\n            delprop = False\n            if ptype == 'object' and v['id'] == obj_id:\n                delprop = True\n            if ptype == 'accessor' and v.get('getter_id') == obj_id:\n                p['getter_id'] = None\n            if ptype == 'accessor' and v.get('setter_id') == obj_id:\n                p['setter_id'] = None\n            # XXX: Should empty accessor (= no getter, no setter) be deleted?\n            # If so, beware of shorthand.\n            if delprop:\n                logger.debug('Deleted property %s of object %s, points to deleted object %s' % \\\n                             (p['key'], o['id'], obj_id))\n            else:\n                new_p.append(p)\n        o['properties'] = new_p\n\n# Merge a user YAML file into current metadata.\ndef metadata_merge_user_objects(meta, user_meta):\n    if user_meta.has_key('add_objects'):\n        raise Exception('\"add_objects\" removed, use \"objects\" with \"add: True\"')\n    if user_meta.has_key('replace_objects'):\n        raise Exception('\"replace_objects\" removed, use \"objects\" with \"replace: True\"')\n    if user_meta.has_key('modify_objects'):\n        raise Exception('\"modify_objects\" removed, use \"objects\" with \"modify: True\"')\n\n    for o in user_meta.get('objects', []):\n        if o.get('disable', False):\n            logger.debug('Skip disabled object: %s' % o['id'])\n            continue\n        targ, targ_idx = metadata_lookup_object_and_index(meta, o['id'])\n\n        if o.get('delete', False):\n            logger.debug('Delete object: %s' % targ['id'])\n            if targ is None:\n                raise Exception('Cannot delete object %s which doesn\\'t exist' % o['id'])\n            meta['objects'].pop(targ_idx)\n            metadata_delete_dangling_references_to_object(meta, targ['id'])\n            continue\n\n        if o.get('replace', False):\n            logger.debug('Replace object %s' % o['id'])\n            if targ is None:\n                logger.warning('object to be replaced doesn\\'t exist, append new object')\n                meta['objects'].append(o)\n            else:\n                meta['objects'][targ_idx] = o\n            continue\n\n        if o.get('add', False) or not o.get('modify', False):  # 'add' is the default\n            logger.debug('Add object %s' % o['id'])\n            if targ is not None:\n                raise Exception('Cannot add object %s which already exists' % o['id'])\n            meta['objects'].append(o)\n            continue\n\n        assert(o.get('modify', False))  # modify handling\n        if targ is None:\n            raise Exception('Cannot modify object %s which doesn\\'t exist' % o['id'])\n\n        for k in sorted(o.keys()):\n            # Merge top level keys by copying over, except 'properties'\n            if k == 'properties':\n                continue\n            targ[k] = o[k]\n        for p in o.get('properties', []):\n            if p.get('disable', False):\n                logger.debug('Skip disabled property: %s' % p['key'])\n                continue\n            prop = None\n            prop_idx = None\n            prop, prop_idx = metadata_lookup_property_and_index(targ, p['key'])\n            if prop is not None:\n                if p.get('delete', False):\n                    logger.debug('Delete property %s of %s' % (p['key'], o['id']))\n                    targ['properties'].pop(prop_idx)\n                else:\n                    logger.debug('Replace property %s of %s' % (p['key'], o['id']))\n                    targ['properties'][prop_idx] = p\n            else:\n                if p.get('delete', False):\n                    logger.debug('Deleting property %s of %s: doesn\\'t exist, nop' % (p['key'], o['id']))\n                else:\n                    logger.debug('Add property %s of %s' % (p['key'], o['id']))\n                    targ['properties'].append(p)\n\n# Replace 'symbol' keys and values with encoded strings.\ndef format_symbol(sym):\n    #print(repr(sym))\n    assert(isinstance(sym, dict))\n    assert(sym.get('type', None) == 'symbol')\n    variant = sym['variant']\n    if variant == 'global':\n        return '\\x80' + sym['string']\n    elif variant == 'wellknown':\n        # Well known symbols use an empty suffix which never occurs for\n        # runtime local symbols.\n        return '\\x81' + sym['string'] + '\\xff'\n    elif variant == 'userhidden':\n        return '\\xff' + sym['string']\n    elif variant == 'hidden':  # hidden == Duktape hidden Symbol\n        return '\\x82' + sym['string']\n    raise Exception('invalid symbol variant %r' % variant)\n\ndef metadata_normalize_symbol_strings(meta):\n    for o in meta['strings']:\n        if isinstance(o['str'], dict) and o['str'].get('type') == 'symbol':\n            o['str'] = format_symbol(o['str'])\n            #print('normalized symbol as string list element: %r', o)\n\n    for o in meta['objects']:\n        for p in o['properties']:\n            if isinstance(p['key'], dict) and p['key'].get('type') == 'symbol':\n                p['key'] = format_symbol(p['key'])\n                #print('normalized symbol as property key: %r', p)\n            if isinstance(p['value'], dict) and p['value'].get('type') == 'symbol':\n                p['value'] = format_symbol(p['value'])\n                #print('normalized symbol as property value: %r', p)\n\n# Normalize nargs for top level functions by defaulting 'nargs' from 'length'.\ndef metadata_normalize_nargs_length(meta):\n    # Default 'nargs' from 'length' for top level function objects.\n    for o in meta['objects']:\n        if o.has_key('nargs'):\n            continue\n        if not o.get('callable', False):\n            continue\n        for p in o['properties']:\n            if p['key'] != 'length':\n                continue\n            logger.debug('Default nargs for top level: %r' % p)\n            assert(isinstance(p['value'], int))\n            o['nargs'] = p['value']\n            break\n        assert(o.has_key('nargs'))\n\n    # Default 'nargs' from 'length' for function property shorthand.\n    for o in meta['objects']:\n        for p in o['properties']:\n            if not (isinstance(p['value'], dict) and p['value']['type'] == 'function'):\n                continue\n            pval = p['value']\n            if not pval.has_key('length'):\n                logger.debug('Default length for function shorthand: %r' % p)\n                pval['length'] = 0\n            if not pval.has_key('nargs'):\n                logger.debug('Default nargs for function shorthand: %r' % p)\n                pval['nargs'] = pval['length']\n\n# Prepare a list of built-in objects which need a runtime 'bidx'.\ndef metadata_prepare_objects_bidx(meta):\n    objlist = meta['objects']\n    meta['objects'] = []\n    meta['objects_bidx'] = []\n\n    # Objects have a 'bidx: true' if they need a DUK_BIDX_xxx constant\n    # and need to be present in thr->builtins[].  The list is already\n    # stripped of built-in objects which are not needed based on config.\n    # Ideally we'd scan the actually needed indices from the source\n    # but since some usage is inside #if defined()s that's not trivial.\n    for obj in objlist:\n        if obj.get('bidx', False):\n            obj['bidx_used'] = True\n            meta['objects'].append(obj)\n            meta['objects_bidx'].append(obj)\n\n    # Append remaining objects.\n    for obj in objlist:\n        if obj.get('bidx_used', False):\n            # Already in meta['objects'].\n            pass\n        else:\n            meta['objects'].append(obj)\n\n# Normalize metadata property shorthand.  For example, if a property value\n# is a shorthand function, create a function object and change the property\n# to point to that function object.\ndef metadata_normalize_shorthand(meta):\n    # Gather objects through the top level built-ins list.\n    objs = []\n    subobjs = []\n\n    def getSubObject():\n        obj = {}\n        obj['id'] = 'subobj_%d' % len(subobjs)  # synthetic ID\n        obj['properties'] = []\n        obj['auto_generated'] = True  # mark as autogenerated (just FYI)\n        subobjs.append(obj)\n        return obj\n\n    def decodeFunctionShorthand(funprop):\n        # Convert the built-in function property \"shorthand\" into an actual\n        # object for ROM built-ins.\n        assert(funprop['value']['type'] == 'function')\n        val = funprop['value']\n        obj = getSubObject()\n        props = obj['properties']\n        obj['native'] = val['native']\n        obj['nargs'] = val.get('nargs', val['length'])\n        obj['varargs'] = val.get('varargs', False)\n        obj['magic'] = val.get('magic', 0)\n        obj['internal_prototype'] = 'bi_function_prototype'\n        obj['class'] = 'Function'\n        obj['callable'] = val.get('callable', True)\n        obj['constructable'] = val.get('constructable', False)\n        obj['special_call'] = val.get('special_call', False)\n        fun_name = val.get('name', funprop['key'])\n        props.append({ 'key': 'length', 'value': val['length'], 'attributes': 'c' })  # Configurable in ES2015\n        props.append({ 'key': 'name', 'value': fun_name, 'attributes': 'c' })   # Configurable in ES2015\n        return obj\n\n    def addAccessor(funprop, magic, nargs, length, name, native_func):\n        assert(funprop['value']['type'] == 'accessor')\n        obj = getSubObject()\n        props = obj['properties']\n        obj['native'] = native_func\n        obj['nargs'] = nargs\n        obj['varargs'] = False\n        obj['magic'] = magic\n        obj['internal_prototype'] = 'bi_function_prototype'\n        obj['class'] = 'Function'\n        obj['callable'] = val.get('callable', True)\n        obj['constructable'] = val.get('constructable', False)\n        assert(obj.get('special_call', False) == False)\n        # Shorthand accessors are minimal and have no .length or .name\n        # right now.  Use longhand if these matter.\n        #props.append({ 'key': 'length', 'value': length, 'attributes': 'c' })\n        #props.append({ 'key': 'name', 'value': name, 'attributes': 'c' })\n        return obj\n\n    def decodeGetterShorthand(key, funprop):\n        assert(funprop['value']['type'] == 'accessor')\n        val = funprop['value']\n        if not val.has_key('getter'):\n            return None\n        return addAccessor(funprop,\n                           val['getter_magic'],\n                           val['getter_nargs'],\n                           val.get('getter_length', 0),\n                           key,\n                           val['getter'])\n\n    def decodeSetterShorthand(key, funprop):\n        assert(funprop['value']['type'] == 'accessor')\n        val = funprop['value']\n        if not val.has_key('setter'):\n            return None\n        return addAccessor(funprop,\n                           val['setter_magic'],\n                           val['setter_nargs'],\n                           val.get('setter_length', 0),\n                           key,\n                           val['setter'])\n\n    def decodeStructuredValue(val):\n        logger.debug('Decode structured value: %r' % val)\n        if isinstance(val, (int, long, float, str)):\n            return val  # as is\n        elif isinstance(val, (dict)):\n            # Object: decode recursively\n            obj = decodeStructuredObject(val)\n            return { 'type': 'object', 'id': obj['id'] }\n        elif isinstance(val, (list)):\n            raise Exception('structured shorthand does not yet support array literals')\n        else:\n            raise Exception('unsupported value in structured shorthand: %r' % v)\n\n    def decodeStructuredObject(val):\n        # XXX: We'd like to preserve dict order from YAML source but\n        # Python doesn't do that.  Use sorted order to make the result\n        # deterministic.  User can always use longhand for exact\n        # property control.\n\n        logger.debug('Decode structured object: %r' % val)\n        obj = getSubObject()\n        obj['class'] = 'Object'\n        obj['internal_prototype'] = 'bi_object_prototype'\n\n        props = obj['properties']\n        keys = sorted(val.keys())\n        for k in keys:\n            logger.debug('Decode property %s' % k)\n            prop = { 'key': k, 'value': decodeStructuredValue(val[k]), 'attributes': 'wec' }\n            props.append(prop)\n\n        return obj\n\n    def decodeStructuredShorthand(structprop):\n        assert(structprop['value']['type'] == 'structured')\n        val = structprop['value']['value']\n        return decodeStructuredValue(val)\n\n    def clonePropShared(prop):\n        res = {}\n        for k in [ 'key', 'attributes', 'auto_lightfunc' ]:\n            if prop.has_key(k):\n                res[k] = prop[k]\n        return res\n\n    for idx,obj in enumerate(meta['objects']):\n        props = []\n        repl_props = []\n\n        for val in obj['properties']:\n            # Date.prototype.toGMTString must point to the same Function object\n            # as Date.prototype.toUTCString, so special case hack it here.\n            if obj['id'] == 'bi_date_prototype' and val['key'] == 'toGMTString':\n                logger.debug('Skip Date.prototype.toGMTString')\n                continue\n\n            if isinstance(val['value'], dict) and val['value']['type'] == 'function':\n                # Function shorthand.\n                subfun = decodeFunctionShorthand(val)\n                prop = clonePropShared(val)\n                prop['value'] = { 'type': 'object', 'id': subfun['id'] }\n                repl_props.append(prop)\n            elif isinstance(val['value'], dict) and val['value']['type'] == 'accessor' and \\\n                 (val['value'].has_key('getter') or val['value'].has_key('setter')):\n                # Accessor normal and shorthand forms both use the type 'accessor',\n                # but are differentiated by properties.\n                sub_getter = decodeGetterShorthand(val['key'], val)\n                sub_setter = decodeSetterShorthand(val['key'], val)\n                prop = clonePropShared(val)\n                prop['value'] = { 'type': 'accessor' }\n                if sub_getter is not None:\n                    prop['value']['getter_id'] = sub_getter['id']\n                if sub_setter is not None:\n                    prop['value']['setter_id'] = sub_setter['id']\n                assert('a' in prop['attributes'])  # If missing, weird things happen runtime\n                logger.debug('Expand accessor shorthand: %r -> %r' % (val, prop))\n                repl_props.append(prop)\n            elif isinstance(val['value'], dict) and val['value']['type'] == 'structured':\n                # Structured shorthand.\n                subval = decodeStructuredShorthand(val)\n                prop = clonePropShared(val)\n                prop['value'] = subval\n                repl_props.append(prop)\n                logger.debug('Decoded structured shorthand for object %s, property %s' % (obj['id'], val['key']))\n            elif isinstance(val['value'], dict) and val['value']['type'] == 'buffer':\n                # Duktape buffer type not yet supported.\n                raise Exception('Buffer type not yet supported for builtins: %r' % val)\n            elif isinstance(val['value'], dict) and val['value']['type'] == 'pointer':\n                # Duktape pointer type not yet supported.\n                raise Exception('Pointer type not yet supported for builtins: %r' % val)\n            else:\n                # Property already in normalized form.\n                repl_props.append(val)\n\n            if obj['id'] == 'bi_date_prototype' and val['key'] == 'toUTCString':\n                logger.debug('Clone Date.prototype.toUTCString to Date.prototype.toGMTString')\n                prop2 = copy.deepcopy(repl_props[-1])\n                prop2['key'] = 'toGMTString'\n                repl_props.append(prop2)\n\n        # Replace properties with a variant where function properties\n        # point to built-ins rather than using an inline syntax.\n        obj['properties'] = repl_props\n\n    len_before = len(meta['objects'])\n    meta['objects'] += subobjs\n    len_after = len(meta['objects'])\n\n    logger.debug('Normalized metadata shorthand, %d objects -> %d final objects' % (len_before, len_after))\n\n# Normalize property attribute order, default attributes, etc.\ndef metadata_normalize_property_attributes(meta):\n    for o in meta['objects']:\n        for p in o['properties']:\n            orig_attrs = p.get('attributes', None)\n            is_accessor = (isinstance(p['value'], dict) and p['value']['type'] == 'accessor')\n\n            # If missing, set default attributes.\n            attrs = orig_attrs\n            if attrs is None:\n                if is_accessor:\n                    attrs = 'ca'  # accessor default is configurable\n                else:\n                    attrs = 'wc'  # default is writable, configurable\n                logger.debug('Defaulted attributes of %s/%s to %s' % (o['id'], p['key'], attrs))\n\n            # Decode flags to normalize their order in the end.\n            writable = 'w' in attrs\n            enumerable = 'e' in attrs\n            configurable = 'c' in attrs\n            accessor = 'a' in attrs\n\n            # Force 'accessor' attribute for accessors.\n            if is_accessor and not accessor:\n                logger.debug('Property %s is accessor but has no \"a\" attribute, add attribute' % p['key'])\n                accessor = True\n\n            # Normalize order and write back.\n            attrs = ''\n            if writable:\n                attrs += 'w'\n            if enumerable:\n                attrs += 'e'\n            if configurable:\n                attrs += 'c'\n            if accessor:\n                attrs += 'a'\n            p['attributes'] = attrs\n\n            if orig_attrs != attrs:\n                logger.debug('Updated attributes of %s/%s from %r to %r' % (o['id'], p['key'], orig_attrs, attrs))\n                pass\n\n# Normalize ROM property attributes.\ndef metadata_normalize_rom_property_attributes(meta):\n    for o in meta['objects']:\n        for p in o['properties']:\n            # ROM properties must not be configurable (runtime code\n            # depends on this).  Writability is kept so that instance\n            # objects can override parent properties.\n            p['attributes'] = p['attributes'].replace('c', '')\n\n# Add a 'name' property for all top level functions; expected by RAM\n# initialization code.\ndef metadata_normalize_ram_function_names(meta):\n    num_added = 0\n    for o in meta['objects']:\n        if not o.get('callable', False):\n            continue\n        name_prop = None\n        for p in o['properties']:\n            if p['key'] == 'name':\n                name_prop = p\n                break\n        if name_prop is None:\n            num_added += 1\n            logger.debug('Adding missing \"name\" property for function %s' % o['id'])\n            o['properties'].append({ 'key': 'name', 'value': '', 'attributes': 'c' })\n\n    if num_added > 0:\n        logger.debug('Added missing \"name\" property for %d functions' % num_added)\n\n# Add a built-in objects list for RAM initialization.\ndef metadata_add_ram_filtered_object_list(meta):\n    # For RAM init data to support user objects, we need to prepare a\n    # filtered top level object list, containing only those objects which\n    # need a value stack index during duk_hthread_builtins.c init process.\n    #\n    # Objects in meta['objects'] which are covered by inline property\n    # notation in the init data (this includes e.g. member functions like\n    # Math.cos) must not be present.\n\n    objlist = []\n    for o in meta['objects']:\n        keep = o.get('bidx_used', False)\n        if o.has_key('native') and not o.has_key('bidx'):\n            # Handled inline by run-time init code\n            pass\n        else:\n            # Top level object\n            keep = True\n        if keep:\n            objlist.append(o)\n\n    logger.debug('Filtered RAM object list: %d objects with bidx, %d total top level objects' % \\\n          (len(meta['objects_bidx']), len(objlist)))\n\n    meta['objects_ram_toplevel'] = objlist\n\n# Add missing strings into strings metadata.  For example, if an object\n# property key is not part of the strings list, append it there.  This\n# is critical for ROM builtins because all property keys etc must also\n# be in ROM.\ndef metadata_normalize_missing_strings(meta, user_meta):\n    # We just need plain strings here.\n    strs_have = {}\n    for s in meta['strings']:\n        strs_have[s['str']] = True\n\n    # For ROM builtins all the strings must be in the strings list,\n    # so scan objects for any strings not explicitly listed in metadata.\n    for idx, obj in enumerate(meta['objects']):\n        for prop in obj['properties']:\n            key = prop['key']\n            if not strs_have.get(key):\n                logger.debug('Add missing string: %r' % key)\n                meta['strings'].append({ 'str': key, '_auto_add_ref': True })\n                strs_have[key] = True\n            if prop.has_key('value') and isinstance(prop['value'], (str, unicode)):\n                val = unicode_to_bytes(prop['value'])  # should already be, just in case\n                if not strs_have.get(val):\n                    logger.debug('Add missing string: %r' % val)\n                    meta['strings'].append({ 'str': val, '_auto_add_ref': True })\n                    strs_have[val] = True\n\n    # Force user strings to be in ROM data.\n    for s in user_meta.get('add_forced_strings', []):\n        if not strs_have.get(s['str']):\n            logger.debug('Add user string: %r' % s['str'])\n            s['_auto_add_user'] = True\n            meta['strings'].append(s)\n\n# Convert built-in function properties into lightfuncs where applicable.\ndef metadata_convert_lightfuncs(meta):\n    num_converted = 0\n    num_skipped = 0\n\n    for o in meta['objects']:\n        for p in o['properties']:\n            v = p['value']\n            ptype = None\n            if isinstance(v, dict):\n                ptype = p['value']['type']\n            if ptype != 'object':\n                continue\n            targ, targ_idx = metadata_lookup_object_and_index(meta, p['value']['id'])\n\n            reasons = []\n            if not targ.get('callable', False):\n                reasons.append('not-callable')\n            #if targ.get('constructable', False):\n            #    reasons.append('constructable')\n\n            lf_len = 0\n            for p2 in targ['properties']:\n                # Don't convert if function has more properties than\n                # we're willing to sacrifice.\n                logger.debug('   - Check %r . %s' % (o.get('id', None), p2['key']))\n                if p2['key'] == 'length' and isinstance(p2['value'], (int, long)):\n                    lf_len = p2['value']\n                if p2['key'] not in [ 'length', 'name' ]:\n                    reasons.append('nonallowed-property')\n\n            if not p.get('auto_lightfunc', True):\n                logger.debug('Automatic lightfunc conversion rejected for key %s, explicitly requested in metadata' % p['key'])\n                reasons.append('no-auto-lightfunc')\n\n            # lf_len comes from actual property table (after normalization)\n            if targ.has_key('magic'):\n                try:\n                    # Magic values which resolve to 'bidx' indices cannot\n                    # be resolved here yet, because the bidx map is not\n                    # yet ready.  If so, reject the lightfunc conversion\n                    # for now.  In practice this doesn't matter.\n                    lf_magic = resolve_magic(targ.get('magic'), {})  # empty map is a \"fake\" bidx map\n                    logger.debug('resolved magic ok -> %r' % lf_magic)\n                except Exception, e:\n                    logger.debug('Failed to resolve magic for %r: %r' % (p['key'], e))\n                    reasons.append('magic-resolve-failed')\n                    lf_magic = 0xffffffff  # dummy, will be out of bounds\n            else:\n                lf_magic = 0\n            if targ.get('varargs', True):\n                lf_nargs = None\n                lf_varargs = True\n            else:\n                lf_nargs = targ['nargs']\n                lf_varargs = False\n\n            if lf_len < 0 or lf_len > 15:\n                logger.debug('lf_len out of bounds: %r' % lf_len)\n                reasons.append('len-bounds')\n            if lf_magic < -0x80 or lf_magic > 0x7f:\n                logger.debug('lf_magic out of bounds: %r' % lf_magic)\n                reasons.append('magic-bounds')\n            if not lf_varargs and (lf_nargs < 0 or lf_nargs > 14):\n                logger.debug('lf_nargs out of bounds: %r' % lf_nargs)\n                reasons.append('nargs-bounds')\n\n            if len(reasons) > 0:\n                logger.debug('Don\\'t convert to lightfunc: %r %r (%r): %r' % (o.get('id', None), p.get('key', None), p['value']['id'], reasons))\n                num_skipped += 1\n                continue\n\n            p_id = p['value']['id']\n            p['value'] = {\n                'type': 'lightfunc',\n                'native': targ['native'],\n                'length': lf_len,\n                'magic': lf_magic,\n                'nargs': lf_nargs,\n                'varargs': lf_varargs\n            }\n            logger.debug(' - Convert to lightfunc: %r %r (%r) -> %r' % (o.get('id', None), p.get('key', None), p_id, p['value']))\n\n            num_converted += 1\n\n    logger.debug('Converted %d built-in function properties to lightfuncs, %d skipped as non-eligible' % (num_converted, num_skipped))\n\n# Detect objects not reachable from any object with a 'bidx'.  This is usually\n# a user error because such objects can't be reached at runtime so they're\n# useless in RAM or ROM init data.\ndef metadata_remove_orphan_objects(meta):\n    reachable = {}\n\n    for o in meta['objects']:\n        if o.get('bidx_used', False):\n            reachable[o['id']] = True\n\n    while True:\n        reachable_count = len(reachable.keys())\n\n        def _markId(obj_id):\n            if obj_id is None:\n                return\n            reachable[obj_id] = True\n\n        for o in meta['objects']:\n            if not reachable.has_key(o['id']):\n                continue\n            _markId(o.get('internal_prototype', None))\n            for p in o['properties']:\n                # Shorthand has been normalized so no need\n                # to support it here.\n                v = p['value']\n                ptype = None\n                if isinstance(v, dict):\n                    ptype = p['value']['type']\n                if ptype == 'object':\n                    _markId(v['id'])\n                if ptype == 'accessor':\n                    _markId(v.get('getter_id'))\n                    _markId(v.get('setter_id'))\n\n        logger.debug('Mark reachable: reachable count initially %d, now %d' % \\\n                     (reachable_count, len(reachable.keys())))\n        if reachable_count == len(reachable.keys()):\n            break\n\n    num_deleted = 0\n    deleted = True\n    while deleted:\n        deleted = False\n        for i,o in enumerate(meta['objects']):\n            if not reachable.has_key(o['id']):\n                logger.debug('object %s not reachable, dropping' % o['id'])\n                meta['objects'].pop(i)\n                deleted = True\n                num_deleted += 1\n                break\n\n    if num_deleted > 0:\n        logger.debug('Deleted %d unreachable objects' % num_deleted)\n\n# Add C define names for builtin strings.  These defines are added to all\n# strings, even when they won't get a stridx because the define names are\n# used to autodetect referenced strings.\ndef metadata_add_string_define_names(strlist, special_defs):\n    for s in strlist:\n        v = s['str']\n\n        if special_defs.has_key(v):\n            s['define'] = 'DUK_STRIDX_' + special_defs[v]\n            continue\n\n        if len(v) >= 1 and v[0] == '\\x82':\n            pfx = 'DUK_STRIDX_INT_'\n            v = v[1:]\n        elif len(v) >= 1 and v[0] == '\\x81' and v[-1] == '\\xff':\n            pfx = 'DUK_STRIDX_WELLKNOWN_'\n            v = v[1:-1]\n        else:\n            pfx = 'DUK_STRIDX_'\n\n        t = re.sub(r'([a-z0-9])([A-Z])', r'\\1_\\2', v)  # add underscores: aB -> a_B\n        t = re.sub(r'\\.', '_', t)  # replace . with _, e.g. Symbol.iterator\n        s['define'] = pfx + t.upper()\n        logger.debug('stridx define: ' + s['define'])\n\n# Add a 'stridx_used' flag for strings which need a stridx.\ndef metadata_add_string_used_stridx(strlist, used_stridx_meta):\n    defs_needed = {}\n    defs_found = {}\n    for s in used_stridx_meta['used_stridx_defines']:\n        defs_needed[s] = True\n\n    # strings whose define is referenced\n    for s in strlist:\n        if s.has_key('define') and defs_needed.has_key(s['define']):\n            s['stridx_used'] = True\n            defs_found[s['define']] = True\n\n    # duk_lexer.h needs all reserved words\n    for s in strlist:\n        if s.get('reserved_word', False):\n            s['stridx_used'] = True\n\n    # ensure all needed defines are provided\n    defs_found['DUK_STRIDX_START_RESERVED'] = True  # special defines provided automatically\n    defs_found['DUK_STRIDX_START_STRICT_RESERVED'] = True\n    defs_found['DUK_STRIDX_END_RESERVED'] = True\n    defs_found['DUK_STRIDX_TO_TOK'] = True\n    for k in sorted(defs_needed.keys()):\n        if not defs_found.has_key(k):\n            raise Exception('source code needs define %s not provided by strings' % repr(k))\n\n# Merge duplicate strings in string metadata.\ndef metadata_merge_string_entries(strlist):\n    # The raw string list may contain duplicates so merge entries.\n    # The list is processed in reverse because the last entry should\n    # \"win\" and keep its place (this matters for reserved words).\n\n    strs = []\n    str_map = {}   # plain string -> object in strs[]\n    tmp = copy.deepcopy(strlist)\n    tmp.reverse()\n    for s in tmp:\n        prev = str_map.get(s['str'])\n        if prev is not None:\n            for k in s.keys():\n                if prev.has_key(k) and prev[k] != s[k]:\n                    raise Exception('fail to merge string entry, conflicting keys: %r <-> %r' % (prev, s))\n                prev[k] = s[k]\n        else:\n            strs.append(s)\n            str_map[s['str']] = s\n    strs.reverse()\n    return strs\n\n# Order builtin strings (strings with a stridx) into an order satisfying\n# multiple constraints.\ndef metadata_order_builtin_strings(input_strlist, keyword_list, strip_unused_stridx=False):\n    # Strings are ordered in the result as follows:\n    #   1. Non-reserved words requiring 8-bit indices\n    #   2. Non-reserved words not requiring 8-bit indices\n    #   3. Reserved words in non-strict mode only\n    #   4. Reserved words in strict mode\n    #\n    # Reserved words must follow an exact order because they are\n    # translated to/from token numbers by addition/subtraction.\n    # Some strings require an 8-bit index and must be in the\n    # beginning.\n\n    tmp_strs = []\n    for s in copy.deepcopy(input_strlist):\n        if not s.get('stridx_used', False):\n            # Drop strings which are not actually needed by src-input/*.(c|h).\n            # Such strings won't be in heap->strs[] or ROM legacy list.\n            pass\n        else:\n            tmp_strs.append(s)\n\n    # The reserved word list must match token order in duk_lexer.h\n    # exactly, so pluck them out first.\n\n    str_index = {}\n    kw_index = {}\n    keywords = []\n    strs = []\n    for idx,s in enumerate(tmp_strs):\n        str_index[s['str']] = s\n    for idx,s in enumerate(keyword_list):\n        keywords.append(str_index[s])\n        kw_index[s] = True\n    for idx,s in enumerate(tmp_strs):\n        if not kw_index.has_key(s['str']):\n            strs.append(s)\n\n    # Sort the strings by category number; within category keep\n    # previous order.\n\n    for idx,s in enumerate(strs):\n        s['_idx'] = idx  # for ensuring stable sort\n\n    def req8Bit(s):\n        return s.get('class_name', False)   # currently just class names\n\n    def getCat(s):\n        req8 = req8Bit(s)\n        if s.get('reserved_word', False):\n            # XXX: unused path now, because keywords are \"plucked out\"\n            # explicitly.\n            assert(not req8)\n            if s.get('future_reserved_word_strict', False):\n                return 4\n            else:\n                return 3\n        elif req8:\n            return 1\n        else:\n            return 2\n\n    def sortCmp(a,b):\n        return cmp( (getCat(a),a['_idx']), (getCat(b),b['_idx']) )\n\n    strs.sort(cmp=sortCmp)\n\n    for idx,s in enumerate(strs):\n        # Remove temporary _idx properties\n        del s['_idx']\n\n    for idx,s in enumerate(strs):\n        if req8Bit(s) and i >= 256:\n            raise Exception('8-bit string index not satisfied: ' + repr(s))\n\n    return strs + keywords\n\n# Dump metadata into a JSON file.\ndef dump_metadata(meta, fn):\n    tmp = json.dumps(recursive_bytes_to_strings(meta), indent=4)\n    with open(fn, 'wb') as f:\n        f.write(tmp)\n    logger.debug('Wrote metadata dump to %s' % fn)\n\n# Main metadata loading function: load metadata from multiple sources,\n# merge and normalize, prepare various indexes etc.\ndef load_metadata(opts, rom=False, build_info=None, active_opts=None):\n    # Load built-in strings and objects.\n    with open(opts.strings_metadata, 'rb') as f:\n        strings_metadata = recursive_strings_to_bytes(yaml.load(f))\n    with open(opts.objects_metadata, 'rb') as f:\n        objects_metadata = recursive_strings_to_bytes(yaml.load(f))\n\n    # Merge strings and objects metadata as simple top level key merge.\n    meta = {}\n    for k in objects_metadata.keys():\n        meta[k] = objects_metadata[k]\n    for k in strings_metadata.keys():\n        meta[k] = strings_metadata[k]\n\n    # Add user objects.\n    user_meta = {}\n    for fn in opts.builtin_files:\n        logger.debug('Merging user builtin metadata file %s' % fn)\n        with open(fn, 'rb') as f:\n            user_meta = recursive_strings_to_bytes(yaml.load(f))\n        metadata_merge_user_objects(meta, user_meta)\n\n    # Remove disabled objects and properties.  Also remove objects and\n    # properties which are disabled in (known) active duk_config.h.\n    metadata_remove_disabled(meta, active_opts)\n\n    # Replace Symbol keys and property values with plain (encoded) strings.\n    metadata_normalize_symbol_strings(meta)\n\n    # Normalize 'nargs' and 'length' defaults.\n    metadata_normalize_nargs_length(meta)\n\n    # Normalize property attributes.\n    metadata_normalize_property_attributes(meta)\n\n    # Normalize property shorthand into full objects.\n    metadata_normalize_shorthand(meta)\n\n    # RAM top-level functions must have a 'name'.\n    if not rom:\n        metadata_normalize_ram_function_names(meta)\n\n    # Add Duktape.version and (Duktape.env for ROM case).\n    for o in meta['objects']:\n        if o['id'] == 'bi_duktape':\n            o['properties'].insert(0, { 'key': 'version', 'value': int(build_info['duk_version']), 'attributes': '' })\n            if rom:\n                # Use a fixed (quite dummy for now) Duktape.env\n                # when ROM builtins are in use.  In the RAM case\n                # this is added during global object initialization\n                # based on config options in use.\n                o['properties'].insert(0, { 'key': 'env', 'value': 'ROM', 'attributes': '' })\n\n    # Normalize property attributes (just in case shorthand handling\n    # didn't add attributes to all properties).\n    metadata_normalize_property_attributes(meta)\n\n    # For ROM objects, mark all properties non-configurable.\n    if rom:\n        metadata_normalize_rom_property_attributes(meta)\n\n    # Convert built-in function properties automatically into\n    # lightfuncs if requested and function is eligible.\n    if rom and opts.rom_auto_lightfunc:\n        metadata_convert_lightfuncs(meta)\n\n    # Create a list of objects needing a 'bidx'.  Ensure 'objects' and\n    # 'objects_bidx' match in order for shared length.\n    metadata_prepare_objects_bidx(meta)\n\n    # Merge duplicate strings.\n    meta['strings'] = metadata_merge_string_entries(meta['strings'])\n\n    # Prepare an ordered list of strings with 'stridx':\n    #   - Add a 'stridx_used' flag for strings which need an index in current code base\n    #   - Add a C define (DUK_STRIDX_xxx) for such strings\n    #   - Compute a stridx string order satisfying current runtime constraints\n    #\n    # The meta['strings_stridx'] result will be in proper order and stripped of\n    # any strings which don't need a stridx.\n    metadata_add_string_define_names(meta['strings'], meta['special_define_names'])\n    with open(opts.used_stridx_metadata, 'rb') as f:\n        metadata_add_string_used_stridx(meta['strings'], json.loads(f.read()))\n    meta['strings_stridx'] = metadata_order_builtin_strings(meta['strings'], meta['reserved_word_token_order'])\n\n    # For the ROM build: add any strings referenced by built-in objects\n    # into the string list (not the 'stridx' list though): all strings\n    # referenced by ROM objects must also be in ROM.\n    if rom:\n        for fn in opts.builtin_files:\n            # XXX: awkward second pass\n            with open(fn, 'rb') as f:\n                user_meta = recursive_strings_to_bytes(yaml.load(f))\n                metadata_normalize_missing_strings(meta, user_meta)\n        metadata_normalize_missing_strings(meta, {})  # in case no files\n\n    # Check for orphan objects and remove them.\n    metadata_remove_orphan_objects(meta)\n\n    # Add final stridx and bidx indices to metadata objects and strings.\n    idx = 0\n    for o in meta['objects']:\n        if o.get('bidx_used', False):\n            o['bidx'] = idx\n            idx += 1\n    idx = 0\n    for s in meta['strings']:\n        if s.get('stridx_used', False):\n            s['stridx'] = idx\n            idx += 1\n\n    # Prepare a filtered RAM top level object list, needed for technical\n    # reasons during RAM init handling.\n    if not rom:\n        metadata_add_ram_filtered_object_list(meta)\n\n    # Sanity check: object index must match 'bidx' for all objects\n    # which have a runtime 'bidx'.  This is assumed by e.g. RAM\n    # thread init.\n    for i,o in enumerate(meta['objects']):\n        if i < len(meta['objects_bidx']):\n            assert(meta['objects_bidx'][i] == meta['objects'][i])\n        if o.get('bidx', False):\n            assert(o['bidx'] == i)\n\n    # Create a set of helper lists and maps now that the metadata is\n    # in its final form.\n    meta['_strings_plain'] = []\n    meta['_strings_stridx_plain'] = []\n    meta['_stridx_to_string'] = {}\n    meta['_idx_to_string'] = {}\n    meta['_stridx_to_plain'] = {}\n    meta['_idx_to_plain'] = {}\n    meta['_string_to_stridx'] = {}\n    meta['_plain_to_stridx'] = {}\n    meta['_string_to_idx'] = {}\n    meta['_plain_to_idx'] = {}\n    meta['_define_to_stridx'] = {}\n    meta['_stridx_to_define'] = {}\n    meta['_is_plain_reserved_word'] = {}\n    meta['_is_plain_strict_reserved_word'] = {}\n    meta['_objid_to_object'] = {}\n    meta['_objid_to_bidx'] = {}\n    meta['_objid_to_idx'] = {}\n    meta['_objid_to_ramidx'] = {}\n    meta['_bidx_to_objid'] = {}\n    meta['_idx_to_objid'] = {}\n    meta['_bidx_to_object'] = {}\n    meta['_idx_to_object'] = {}\n\n    for i,s in enumerate(meta['strings']):\n        assert(s['str'] not in meta['_strings_plain'])\n        meta['_strings_plain'].append(s['str'])\n        if s.get('reserved_word', False):\n            meta['_is_plain_reserved_word'][s['str']] = True  # includes also strict reserved words\n        if s.get('future_reserved_word_strict', False):\n            meta['_is_plain_strict_reserved_word'][s['str']] = True\n        meta['_idx_to_string'][i] = s\n        meta['_idx_to_plain'][i] = s['str']\n        meta['_plain_to_idx'][s['str']] = i\n        #meta['_string_to_idx'][s] = i\n    for i,s in enumerate(meta['strings_stridx']):\n        assert(s.get('stridx_used', False) == True)\n        meta['_strings_stridx_plain'].append(s['str'])\n        meta['_stridx_to_string'][i] = s\n        meta['_stridx_to_plain'][i] = s['str']\n        #meta['_string_to_stridx'][s] = i\n        meta['_plain_to_stridx'][s['str']] = i\n        meta['_define_to_stridx'][s['define']] = i\n        meta['_stridx_to_define'][i] = s['define']\n    for i,o in enumerate(meta['objects']):\n        meta['_objid_to_object'][o['id']] = o\n        meta['_objid_to_idx'][o['id']] = i\n        meta['_idx_to_objid'][i] = o['id']\n        meta['_idx_to_object'][i] = o\n    for i,o in enumerate(meta['objects_bidx']):\n        assert(o.get('bidx_used', False) == True)\n        meta['_objid_to_bidx'][o['id']] = i\n        assert(meta['_objid_to_bidx'][o['id']] == meta['_objid_to_idx'][o['id']])\n        meta['_bidx_to_objid'][i] = o['id']\n        meta['_bidx_to_object'][i] = o\n    if meta.has_key('objects_ram_toplevel'):\n        for i,o in enumerate(meta['objects_ram_toplevel']):\n            meta['_objid_to_ramidx'][o['id']] = i\n\n    # Dump stats.\n\n    if rom:\n        meta_name = 'ROM'\n    else:\n        meta_name = 'RAM'\n\n    count_add_ref = 0\n    count_add_user = 0\n    for s in meta['strings']:\n        if s.get('_auto_add_ref', False):\n            count_add_ref += 1\n        if s.get('_auto_add_user', False):\n            count_add_user += 1\n    count_add = count_add_ref + count_add_user\n\n    logger.debug(('Prepared %s metadata: %d objects, %d objects with bidx, ' + \\\n                  '%d strings, %d strings with stridx, %d strings added ' + \\\n                  '(%d property key references, %d user strings)') % \\\n                 (meta_name, len(meta['objects']), len(meta['objects_bidx']), \\\n                  len(meta['strings']), len(meta['strings_stridx']), \\\n                  count_add, count_add_ref, count_add_user))\n\n    return meta\n\n#\n#  Metadata helpers\n#\n\n# Magic values for Math built-in.\nmath_onearg_magic = {\n    'fabs': 0,    # BI_MATH_FABS_IDX\n    'acos': 1,    # BI_MATH_ACOS_IDX\n    'asin': 2,    # BI_MATH_ASIN_IDX\n    'atan': 3,    # BI_MATH_ATAN_IDX\n    'ceil': 4,    # BI_MATH_CEIL_IDX\n    'cos': 5,     # BI_MATH_COS_IDX\n    'exp': 6,     # BI_MATH_EXP_IDX\n    'floor': 7,   # BI_MATH_FLOOR_IDX\n    'log': 8,     # BI_MATH_LOG_IDX\n    'round': 9,   # BI_MATH_ROUND_IDX\n    'sin': 10,    # BI_MATH_SIN_IDX\n    'sqrt': 11,   # BI_MATH_SQRT_IDX\n    'tan': 12,    # BI_MATH_TAN_IDX\n    'cbrt': 13,   # BI_MATH_CBRT_IDX\n    'log2': 14,   # BI_MATH_LOG2_IDX\n    'log10': 15,  # BI_MATH_LOG10_IDX\n    'trunc': 16,  # BI_MATH_TRUNC_IDX\n}\nmath_twoarg_magic = {\n    'atan2': 0,  # BI_MATH_ATAN2_IDX\n    'pow': 1     # BI_MATH_POW_IDX\n}\n\n# Magic values for Array built-in.\narray_iter_magic = {\n    'every': 0,    # BI_ARRAY_ITER_EVERY\n    'some': 1,     # BI_ARRAY_ITER_SOME\n    'forEach': 2,  # BI_ARRAY_ITER_FOREACH\n    'map': 3,      # BI_ARRAY_ITER_MAP\n    'filter': 4    # BI_ARRAY_ITER_FILTER\n}\n\n# Magic value for typedarray/node.js buffer read field operations.\ndef magic_readfield(elem, signed=None, bigendian=None, typedarray=None):\n    # Must match duk__FLD_xxx in duk_bi_buffer.c\n    elemnum = {\n        '8bit': 0,\n        '16bit': 1,\n        '32bit': 2,\n        'float': 3,\n        'double': 4,\n        'varint': 5\n    }[elem]\n    if signed == True:\n        signednum = 1\n    elif signed == False:\n        signednum = 0\n    else:\n        raise Exception('missing \"signed\"')\n    if bigendian == True:\n        bigendiannum = 1\n    elif bigendian == False:\n        bigendiannum = 0\n    else:\n        raise Exception('missing \"bigendian\"')\n    if typedarray == True:\n        typedarraynum = 1\n    elif typedarray == False:\n        typedarraynum = 0\n    else:\n        raise Exception('missing \"typedarray\"')\n    return elemnum + (signednum << 4) + (bigendiannum << 3) + (typedarraynum << 5)\n\n# Magic value for typedarray/node.js buffer write field operations.\ndef magic_writefield(elem, signed=None, bigendian=None, typedarray=None):\n    return magic_readfield(elem, signed=signed, bigendian=bigendian, typedarray=typedarray)\n\n# Magic value for typedarray constructors.\ndef magic_typedarray_constructor(elem, shift):\n    # Must match duk_hbufobj.h header\n    elemnum = {\n        'uint8': 0,\n        'uint8clamped': 1,\n        'int8': 2,\n        'uint16': 3,\n        'int16': 4,\n        'uint32': 5,\n        'int32': 6,\n        'float32': 7,\n        'float64': 8\n    }[elem]\n    return (elemnum << 2) + shift\n\n# Resolve a magic value from a YAML metadata element into an integer.\ndef resolve_magic(elem, objid_to_bidx):\n    if elem is None:\n        return 0\n    if isinstance(elem, (int, long)):\n        v = int(elem)\n        if not (v >= -0x8000 and v <= 0x7fff):\n            raise Exception('invalid plain value for magic: %s' % repr(v))\n        return v\n    if not isinstance(elem, dict):\n        raise Exception('invalid magic: %r' % elem)\n\n    assert(elem.has_key('type'))\n    if elem['type'] == 'bidx':\n        # Maps to thr->builtins[].\n        v = elem['id']\n        return objid_to_bidx[v]\n    elif elem['type'] == 'plain':\n        v = elem['value']\n        if not (v >= -0x8000 and v <= 0x7fff):\n            raise Exception('invalid plain value for magic: %s' % repr(v))\n        return v\n    elif elem['type'] == 'math_onearg':\n        return math_onearg_magic[elem['funcname']]\n    elif elem['type'] == 'math_twoarg':\n        return math_twoarg_magic[elem['funcname']]\n    elif elem['type'] == 'array_iter':\n        return array_iter_magic[elem['funcname']]\n    elif elem['type'] == 'typedarray_constructor':\n        return magic_typedarray_constructor(elem['elem'], elem['shift'])\n    elif elem['type'] == 'buffer_readfield':\n        return magic_readfield(elem['elem'], elem['signed'], elem['bigendian'], elem['typedarray'])\n    elif elem['type'] == 'buffer_writefield':\n        return magic_writefield(elem['elem'], elem['signed'], elem['bigendian'], elem['typedarray'])\n    else:\n        raise Exception('invalid magic type: %r' % elem)\n\n# Helper to find a property from a property list, remove it from the\n# property list, and return the removed property.\ndef steal_prop(props, key, allow_accessor=True):\n    for idx,prop in enumerate(props):\n        if prop['key'] == key:\n            if not (isinstance(prop['value'], dict) and prop['value']['type'] == 'accessor') or allow_accessor:\n                return props.pop(idx)\n    return None\n\n#\n#  RAM initialization data\n#\n#  Init data for built-in strings and objects.  The init data for both\n#  strings and objects is a bit-packed stream tailored to match the decoders\n#  in duk_heap_alloc.c (strings) and duk_hthread_builtins.c (objects).\n#  Various bitfield sizes are used to minimize the bitstream size without\n#  resorting to actual, expensive compression.  The goal is to minimize the\n#  overall size of the init code and the init data.\n#\n#  The built-in data created here is used to set up initial RAM versions\n#  of the strings and objects.  References to these objects are tracked in\n#  heap->strs[] and thr->builtins[] which allows Duktape internals to refer\n#  to built-ins e.g. as thr->builtins[DUK_BIDX_STRING_PROTOTYPE].\n#\n#  Not all strings and objects need to be reachable through heap->strs[]\n#  or thr->builtins[]: the strings/objects that need to be in these arrays\n#  is determined based on metadata and source code scanning.\n#\n\n# XXX: Reserved word stridxs could be made to match token numbers\n#      directly so that a duk_stridx2token[] would not be needed.\n\n# Default property attributes.\nLENGTH_PROPERTY_ATTRIBUTES = 'c'\nACCESSOR_PROPERTY_ATTRIBUTES = 'c'\nDEFAULT_DATA_PROPERTY_ATTRIBUTES = 'wc'\nDEFAULT_FUNC_PROPERTY_ATTRIBUTES = 'wc'\n\n# Encoding constants (must match duk_hthread_builtins.c).\nPROP_FLAGS_BITS = 3\nLENGTH_PROP_BITS = 3\nNARGS_BITS = 3\nPROP_TYPE_BITS = 3\n\nNARGS_VARARGS_MARKER = 0x07\n\nPROP_TYPE_DOUBLE = 0\nPROP_TYPE_STRING = 1\nPROP_TYPE_STRIDX = 2\nPROP_TYPE_BUILTIN = 3\nPROP_TYPE_UNDEFINED = 4\nPROP_TYPE_BOOLEAN_TRUE = 5\nPROP_TYPE_BOOLEAN_FALSE = 6\nPROP_TYPE_ACCESSOR = 7\n\n# must match duk_hobject.h\nPROPDESC_FLAG_WRITABLE =     (1 << 0)\nPROPDESC_FLAG_ENUMERABLE =   (1 << 1)\nPROPDESC_FLAG_CONFIGURABLE = (1 << 2)\nPROPDESC_FLAG_ACCESSOR =     (1 << 3)  # unused now\n\n# Class names, numeric indices must match duk_hobject.h class numbers.\nclass_names = [\n    'Unused',\n    'Object',\n    'Array',\n    'Function',\n    'Arguments',\n    'Boolean',\n    'Date',\n    'Error',\n    'JSON',\n    'Math',\n    'Number',\n    'RegExp',\n    'String',\n    'global',\n    'Symbol',\n    'ObjEnv',\n    'DecEnv',\n    'Pointer',\n    'Thread'\n    # Remaining class names are not currently needed.\n]\nclass2num = {}\nfor i,v in enumerate(class_names):\n    class2num[v] = i\n\n# Map class name to a class number.\ndef class_to_number(x):\n    return class2num[x]\n\n# Bitpack a string into a format shared by heap and thread init data.\ndef bitpack_string(be, s, stats=None):\n    # Strings are encoded as follows: a string begins in lowercase\n    # mode and recognizes the following 5-bit symbols:\n    #\n    #    0-25    'a' ... 'z' or 'A' ... 'Z' depending on uppercase mode\n    #    26-31   special controls, see code below\n\n    LOOKUP1 = 26\n    LOOKUP2 = 27\n    SWITCH1 = 28\n    SWITCH = 29\n    UNUSED1 = 30\n    EIGHTBIT = 31\n    LOOKUP = '0123456789_ \\x82\\x80\"{'  # special characters\n    assert(len(LOOKUP) == 16)\n\n    # support up to 256 byte strings now, cases above ~30 bytes are very\n    # rare, so favor short strings in encoding\n    if len(s) <= 30:\n        be.bits(len(s), 5)\n    else:\n        be.bits(31, 5)\n        be.bits(len(s), 8)\n\n    # 5-bit character, mode specific\n    mode = 'lowercase'\n\n    for idx, c in enumerate(s):\n        # This encoder is not that optimal, but good enough for now.\n\n        islower = (ord(c) >= ord('a') and ord(c) <= ord('z'))\n        isupper = (ord(c) >= ord('A') and ord(c) <= ord('Z'))\n        islast = (idx == len(s) - 1)\n        isnextlower = False\n        isnextupper = False\n        if not islast:\n            c2 = s[idx+1]\n            isnextlower = (ord(c2) >= ord('a') and ord(c2) <= ord('z'))\n            isnextupper = (ord(c2) >= ord('A') and ord(c2) <= ord('Z'))\n\n        # XXX: Add back special handling for hidden or other symbols?\n\n        if islower and mode == 'lowercase':\n            be.bits(ord(c) - ord('a'), 5)\n            if stats is not None: stats['n_optimal'] += 1\n        elif isupper and mode == 'uppercase':\n            be.bits(ord(c) - ord('A'), 5)\n            if stats is not None: stats['n_optimal'] += 1\n        elif islower and mode == 'uppercase':\n            if isnextlower:\n                be.bits(SWITCH, 5)\n                be.bits(ord(c) - ord('a'), 5)\n                mode = 'lowercase'\n                if stats is not None: stats['n_switch'] += 1\n            else:\n                be.bits(SWITCH1, 5)\n                be.bits(ord(c) - ord('a'), 5)\n                if stats is not None: stats['n_switch1'] += 1\n        elif isupper and mode == 'lowercase':\n            if isnextupper:\n                be.bits(SWITCH, 5)\n                be.bits(ord(c) - ord('A'), 5)\n                mode = 'uppercase'\n                if stats is not None: stats['n_switch'] += 1\n            else:\n                be.bits(SWITCH1, 5)\n                be.bits(ord(c) - ord('A'), 5)\n                if stats is not None: stats['n_switch1'] += 1\n        elif c in LOOKUP:\n            idx = LOOKUP.find(c)\n            if idx >= 8:\n                be.bits(LOOKUP2, 5)\n                be.bits(idx - 8, 3)\n                if stats is not None: stats['n_lookup2'] += 1\n            else:\n                be.bits(LOOKUP1, 5)\n                be.bits(idx, 3)\n                if stats is not None: stats['n_lookup1'] += 1\n        elif ord(c) >= 0 and ord(c) <= 255:\n            logger.debug('eightbit encoding for %d (%s)' % (ord(c), c))\n            be.bits(EIGHTBIT, 5)\n            be.bits(ord(c), 8)\n            if stats is not None: stats['n_eightbit'] += 1\n        else:\n            raise Exception('internal error in bitpacking a string')\n\n# Generate bit-packed RAM string init data.\ndef gen_ramstr_initdata_bitpacked(meta):\n    be = dukutil.BitEncoder()\n\n    maxlen = 0\n    stats = {\n        'n_optimal': 0,\n        'n_lookup1': 0,\n        'n_lookup2': 0,\n        'n_switch1': 0,\n        'n_switch': 0,\n        'n_eightbit': 0\n    }\n\n    for s_obj in meta['strings_stridx']:\n        s = s_obj['str']\n        if len(s) > maxlen:\n            maxlen = len(s)\n        bitpack_string(be, s, stats)\n\n    # end marker not necessary, C code knows length from define\n\n    if be._varuint_count > 0:\n        logger.debug('Varuint distribution:')\n        logger.debug(json.dumps(be._varuint_dist[0:1024]))\n        logger.debug('Varuint encoding categories: %r' % be._varuint_cats)\n        logger.debug('Varuint efficiency: %f bits/value' % (float(be._varuint_bits) / float(be._varuint_count)))\n    res = be.getByteString()\n\n    logger.debug(('%d ram strings, %d bytes of string init data, %d maximum string length, ' + \\\n                 'encoding: optimal=%d,lookup1=%d,lookup2=%d,switch1=%d,switch=%d,eightbit=%d') % \\\n                 (len(meta['strings_stridx']), len(res), maxlen, \\\n                 stats['n_optimal'],\n                 stats['n_lookup1'], stats['n_lookup2'],\n                 stats['n_switch1'], stats['n_switch'],\n                 stats['n_eightbit']))\n\n    return res, maxlen\n\n# Functions to emit string-related source/header parts.\n\ndef emit_ramstr_source_strinit_data(genc, strdata):\n    genc.emitArray(strdata, 'duk_strings_data', visibility='DUK_INTERNAL', typename='duk_uint8_t', intvalues=True, const=True, size=len(strdata))\n\ndef emit_ramstr_header_strinit_defines(genc, meta, strdata, strmaxlen):\n    genc.emitLine('#if !defined(DUK_SINGLE_FILE)')\n    genc.emitLine('DUK_INTERNAL_DECL const duk_uint8_t duk_strings_data[%d];' % len(strdata))\n    genc.emitLine('#endif  /* !DUK_SINGLE_FILE */')\n    genc.emitDefine('DUK_STRDATA_MAX_STRLEN', strmaxlen)\n    genc.emitDefine('DUK_STRDATA_DATA_LENGTH', len(strdata))\n\n# This is used for both RAM and ROM strings.\ndef emit_header_stridx_defines(genc, meta):\n    strlist = meta['strings_stridx']\n\n    for idx,s in enumerate(strlist):\n        genc.emitDefine(s['define'], idx, repr(s['str']))\n        defname = s['define'].replace('_STRIDX','_HEAP_STRING')\n        genc.emitDefine(defname + '(heap)', 'DUK_HEAP_GET_STRING((heap),%s)' % s['define'])\n        defname = s['define'].replace('_STRIDX', '_HTHREAD_STRING')\n        genc.emitDefine(defname + '(thr)', 'DUK_HTHREAD_GET_STRING((thr),%s)' % s['define'])\n\n    idx_start_reserved = None\n    idx_start_strict_reserved = None\n    for idx,s in enumerate(strlist):\n        if idx_start_reserved is None and s.get('reserved_word', False):\n            idx_start_reserved = idx\n        if idx_start_strict_reserved is None and s.get('future_reserved_word_strict', False):\n            idx_start_strict_reserved = idx\n    assert(idx_start_reserved is not None)\n    assert(idx_start_strict_reserved is not None)\n\n    genc.emitLine('')\n    genc.emitDefine('DUK_HEAP_NUM_STRINGS', len(strlist))\n    genc.emitDefine('DUK_STRIDX_START_RESERVED', idx_start_reserved)\n    genc.emitDefine('DUK_STRIDX_START_STRICT_RESERVED', idx_start_strict_reserved)\n    genc.emitDefine('DUK_STRIDX_END_RESERVED', len(strlist), comment='exclusive endpoint')\n    genc.emitLine('')\n    genc.emitLine('/* To convert a heap stridx to a token number, subtract')\n    genc.emitLine(' * DUK_STRIDX_START_RESERVED and add DUK_TOK_START_RESERVED.')\n    genc.emitLine(' */')\n\n# Encode property flags for RAM initializers.\ndef encode_property_flags(flags):\n    # Note: must match duk_hobject.h\n\n    res = 0\n    nflags = 0\n    if 'w' in flags:\n        nflags += 1\n        res = res | PROPDESC_FLAG_WRITABLE\n    if 'e' in flags:\n        nflags += 1\n        res = res | PROPDESC_FLAG_ENUMERABLE\n    if 'c' in flags:\n        nflags += 1\n        res = res | PROPDESC_FLAG_CONFIGURABLE\n    if 'a' in flags:\n        nflags += 1\n        res = res | PROPDESC_FLAG_ACCESSOR\n\n    if nflags != len(flags):\n        raise Exception('unsupported flags: %s' % repr(flags))\n\n    return res\n\n# Generate RAM object initdata for an object (but not its properties).\ndef gen_ramobj_initdata_for_object(meta, be, bi, string_to_stridx, natfunc_name_to_natidx, objid_to_bidx):\n    def _stridx(strval):\n        stridx = string_to_stridx[strval]\n        be.varuint(stridx)\n    def _stridx_or_string(strval):\n        stridx = string_to_stridx.get(strval)\n        if stridx is not None:\n            be.varuint(stridx + 1)\n        else:\n            be.varuint(0)\n            bitpack_string(be, strval)\n    def _natidx(native_name):\n        natidx = natfunc_name_to_natidx[native_name]\n        be.varuint(natidx)\n\n    class_num = class_to_number(bi['class'])\n    be.varuint(class_num)\n\n    props = [x for x in bi['properties']]  # clone\n\n    prop_proto = steal_prop(props, 'prototype')\n    prop_constr = steal_prop(props, 'constructor')\n    prop_name = steal_prop(props, 'name', allow_accessor=False)\n    prop_length = steal_prop(props, 'length', allow_accessor=False)\n\n    length = -1  # default value -1 signifies varargs\n    if prop_length is not None:\n        assert(isinstance(prop_length['value'], int))\n        length = prop_length['value']\n        be.bits(1, 1)  # flag: have length\n        be.bits(length, LENGTH_PROP_BITS)\n    else:\n        be.bits(0, 1)  # flag: no length\n\n    # The attributes for 'length' are standard (\"none\") except for\n    # Array.prototype.length which must be writable (this is handled\n    # separately in duk_hthread_builtins.c).\n\n    len_attrs = LENGTH_PROPERTY_ATTRIBUTES\n    if prop_length is not None:\n        len_attrs = prop_length['attributes']\n\n    if len_attrs != LENGTH_PROPERTY_ATTRIBUTES:\n        # Attributes are assumed to be the same, except for Array.prototype.\n        if bi['class'] != 'Array':  # Array.prototype is the only one with this class\n            raise Exception('non-default length attribute for unexpected object')\n\n    # For 'Function' classed objects, emit the native function stuff.\n    # Unfortunately this is more or less a copy of what we do for\n    # function properties now.  This should be addressed if a rework\n    # on the init format is done.\n\n    if bi['class'] == 'Function':\n        _natidx(bi['native'])\n\n        if bi.get('varargs', False):\n            be.bits(1, 1)  # flag: non-default nargs\n            be.bits(NARGS_VARARGS_MARKER, NARGS_BITS)\n        elif bi.has_key('nargs') and bi['nargs'] != length:\n            be.bits(1, 1)  # flag: non-default nargs\n            be.bits(bi['nargs'], NARGS_BITS)\n        else:\n            assert(length is not None)\n            be.bits(0, 1)  # flag: default nargs OK\n\n        # All Function-classed global level objects are callable\n        # (have [[Call]]) but not all are constructable (have\n        # [[Construct]]).  Flag that.\n\n        assert(bi.has_key('callable'))\n        assert(bi['callable'] == True)\n\n        assert(prop_name is not None)\n        assert(isinstance(prop_name['value'], str))\n        _stridx_or_string(prop_name['value'])\n\n        if bi.get('constructable', False):\n            be.bits(1, 1)    # flag: constructable\n        else:\n            be.bits(0, 1)    # flag: not constructable\n        # DUK_HOBJECT_FLAG_SPECIAL_CALL is handled at runtime without init data.\n\n        # Convert signed magic to 16-bit unsigned for encoding\n        magic = resolve_magic(bi.get('magic'), objid_to_bidx) & 0xffff\n        assert(magic >= 0)\n        assert(magic <= 0xffff)\n        be.varuint(magic)\n\n# Generate RAM object initdata for an object's properties.\ndef gen_ramobj_initdata_for_props(meta, be, bi, string_to_stridx, natfunc_name_to_natidx, objid_to_bidx, double_byte_order):\n    count_normal_props = 0\n    count_function_props = 0\n\n    def _bidx(bi_id):\n        be.varuint(objid_to_bidx[bi_id])\n    def _bidx_or_none(bi_id):\n        if bi_id is None:\n            be.varuint(0)\n        else:\n            be.varuint(objid_to_bidx[bi_id] + 1)\n    def _stridx(strval):\n        stridx = string_to_stridx[strval]\n        be.varuint(stridx)\n    def _stridx_or_string(strval):\n        stridx = string_to_stridx.get(strval)\n        if stridx is not None:\n            be.varuint(stridx + 1)\n        else:\n            be.varuint(0)\n            bitpack_string(be, strval)\n    def _natidx(native_name):\n        if native_name is None:\n            natidx = 0  # 0 is NULL in the native functions table, denotes missing function\n        else:\n            natidx = natfunc_name_to_natidx[native_name]\n        be.varuint(natidx)\n    props = [x for x in bi['properties']]  # clone\n\n    # internal prototype: not an actual property so not in property list\n    if bi.has_key('internal_prototype'):\n        _bidx_or_none(bi['internal_prototype'])\n    else:\n        _bidx_or_none(None)\n\n    # external prototype: encoded specially, steal from property list\n    prop_proto = steal_prop(props, 'prototype')\n    if prop_proto is not None:\n        assert(prop_proto['value']['type'] == 'object')\n        assert(prop_proto['attributes'] == '')\n        _bidx_or_none(prop_proto['value']['id'])\n    else:\n        _bidx_or_none(None)\n\n    # external constructor: encoded specially, steal from property list\n    prop_constr = steal_prop(props, 'constructor')\n    if prop_constr is not None:\n        assert(prop_constr['value']['type'] == 'object')\n        assert(prop_constr['attributes'] == 'wc')\n        _bidx_or_none(prop_constr['value']['id'])\n    else:\n        _bidx_or_none(None)\n\n    # name: encoded specially for function objects, so steal and ignore here\n    if bi['class'] == 'Function':\n        prop_name = steal_prop(props, 'name', allow_accessor=False)\n        assert(prop_name is not None)\n        assert(isinstance(prop_name['value'], str))\n        assert(prop_name['attributes'] == 'c')\n\n    # length: encoded specially, so steal and ignore\n    prop_proto = steal_prop(props, 'length', allow_accessor=False)\n\n    # Date.prototype.toGMTString needs special handling and is handled\n    # directly in duk_hthread_builtins.c; so steal and ignore here.\n    if bi['id'] == 'bi_date_prototype':\n        prop_togmtstring = steal_prop(props, 'toGMTString')\n        assert(prop_togmtstring is not None)\n        logger.debug('Stole Date.prototype.toGMTString')\n\n    # Split properties into non-builtin functions and other properties.\n    # This split is a bit arbitrary, but is used to reduce flag bits in\n    # the bit stream.\n    values = []\n    functions = []\n    for prop in props:\n        if isinstance(prop['value'], dict) and \\\n           prop['value']['type'] == 'object' and \\\n           metadata_lookup_object(meta, prop['value']['id']).has_key('native') and \\\n           not metadata_lookup_object(meta, prop['value']['id']).has_key('bidx'):\n            functions.append(prop)\n        else:\n            values.append(prop)\n\n    be.varuint(len(values))\n\n    for valspec in values:\n        count_normal_props += 1\n\n        val = valspec['value']\n\n        _stridx_or_string(valspec['key'])\n\n        # Attribute check doesn't check for accessor flag; that is now\n        # automatically set by C code when value is an accessor type.\n        # Accessors must not have 'writable', so they'll always have\n        # non-default attributes (less footprint than adding a different\n        # default).\n        default_attrs = DEFAULT_DATA_PROPERTY_ATTRIBUTES\n\n        attrs = valspec.get('attributes', default_attrs)\n        attrs = attrs.replace('a', '')  # ram bitstream doesn't encode 'accessor' attribute\n        if attrs != default_attrs:\n            logger.debug('non-default attributes: %s -> %r (default %r)' % (valspec['key'], attrs, default_attrs))\n            be.bits(1, 1)  # flag: have custom attributes\n            be.bits(encode_property_flags(attrs), PROP_FLAGS_BITS)\n        else:\n            be.bits(0, 1)  # flag: no custom attributes\n\n        if val is None:\n            logger.warning('RAM init data format doesn\\'t support \"null\" now, value replaced with \"undefined\": %r' % valspec)\n            #raise Exception('RAM init format doesn\\'t support a \"null\" value now')\n            be.bits(PROP_TYPE_UNDEFINED, PROP_TYPE_BITS)\n        elif isinstance(val, bool):\n            if val == True:\n                be.bits(PROP_TYPE_BOOLEAN_TRUE, PROP_TYPE_BITS)\n            else:\n                be.bits(PROP_TYPE_BOOLEAN_FALSE, PROP_TYPE_BITS)\n        elif isinstance(val, (float, int)) or isinstance(val, dict) and val['type'] == 'double':\n            # Avoid converting a manually specified NaN temporarily into\n            # a float to avoid risk of e.g. NaN being replaced by another.\n            if isinstance(val, dict):\n                val = val['bytes'].decode('hex')\n                assert(len(val) == 8)\n            else:\n                val = struct.pack('>d', float(val))\n\n            be.bits(PROP_TYPE_DOUBLE, PROP_TYPE_BITS)\n\n            # encoding of double must match target architecture byte order\n            indexlist = {\n                'big':    [ 0, 1, 2, 3, 4, 5, 6, 7 ],\n                'little': [ 7, 6, 5, 4, 3, 2, 1, 0 ],\n                'mixed':  [ 3, 2, 1, 0, 7, 6, 5, 4 ]    # some arm platforms\n            }[double_byte_order]\n\n            data = ''.join([ val[indexlist[idx]] for idx in xrange(8) ])\n\n            logger.debug('DOUBLE: %s -> %s' % (val.encode('hex'), data.encode('hex')))\n\n            if len(data) != 8:\n                raise Exception('internal error')\n            be.string(data)\n        elif isinstance(val, str) or isinstance(val, unicode):\n            if isinstance(val, unicode):\n                # Note: non-ASCII characters will not currently work,\n                # because bits/char is too low.\n                val = val.encode('utf-8')\n\n            if string_to_stridx.has_key(val):\n                # String value is in built-in string table -> encode\n                # using a string index.  This saves some space,\n                # especially for the 'name' property of errors\n                # ('EvalError' etc).\n\n                be.bits(PROP_TYPE_STRIDX, PROP_TYPE_BITS)\n                _stridx(val)\n            else:\n                # Not in string table, bitpack string value as is.\n                be.bits(PROP_TYPE_STRING, PROP_TYPE_BITS)\n                bitpack_string(be, val)\n        elif isinstance(val, dict):\n            if val['type'] == 'object':\n                be.bits(PROP_TYPE_BUILTIN, PROP_TYPE_BITS)\n                _bidx(val['id'])\n            elif val['type'] == 'undefined':\n                be.bits(PROP_TYPE_UNDEFINED, PROP_TYPE_BITS)\n            elif val['type'] == 'accessor':\n                be.bits(PROP_TYPE_ACCESSOR, PROP_TYPE_BITS)\n                getter_natfun = None\n                setter_natfun = None\n                getter_magic = 0\n                setter_magic = 0\n                if val.has_key('getter_id'):\n                    getter_fn = metadata_lookup_object(meta, val['getter_id'])\n                    getter_natfun = getter_fn['native']\n                    assert(getter_fn['nargs'] == 0)\n                    getter_magic = getter_fn['magic']\n                if val.has_key('setter_id'):\n                    setter_fn = metadata_lookup_object(meta, val['setter_id'])\n                    setter_natfun = setter_fn['native']\n                    assert(setter_fn['nargs'] == 1)\n                    setter_magic = setter_fn['magic']\n                if getter_natfun is not None and setter_natfun is not None:\n                    assert(getter_magic == setter_magic)\n                _natidx(getter_natfun)\n                _natidx(setter_natfun)\n                be.varuint(getter_magic)\n            elif val['type'] == 'lightfunc':\n                logger.warning('RAM init data format doesn\\'t support \"lightfunc\" now, value replaced with \"undefined\": %r' % valspec)\n                be.bits(PROP_TYPE_UNDEFINED, PROP_TYPE_BITS)\n            else:\n                raise Exception('unsupported value: %s' % repr(val))\n        else:\n            raise Exception('unsupported value: %s' % repr(val))\n\n    be.varuint(len(functions))\n\n    for funprop in functions:\n        count_function_props += 1\n\n        funobj = metadata_lookup_object(meta, funprop['value']['id'])\n        prop_len = metadata_lookup_property(funobj, 'length')\n        assert(prop_len is not None)\n        assert(isinstance(prop_len['value'], (int)))\n        length = prop_len['value']\n\n        # XXX: this doesn't currently handle a function .name != its key\n        # At least warn about it here.  Or maybe generate the correct name\n        # at run time (it's systematic at the moment, @@toPrimitive has the\n        # name \"[Symbol.toPrimitive]\" which can be computed from the symbol\n        # internal representation.\n\n        _stridx_or_string(funprop['key'])\n        _natidx(funobj['native'])\n        be.bits(length, LENGTH_PROP_BITS)\n\n        if funobj.get('varargs', False):\n            be.bits(1, 1)  # flag: non-default nargs\n            be.bits(NARGS_VARARGS_MARKER, NARGS_BITS)\n        elif funobj.has_key('nargs') and funobj['nargs'] != length:\n            be.bits(1, 1)  # flag: non-default nargs\n            be.bits(funobj['nargs'], NARGS_BITS)\n        else:\n            be.bits(0, 1)  # flag: default nargs OK\n\n        # XXX: make this check conditional to minimize bit count\n        # (there are quite a lot of function properties)\n        # Convert signed magic to 16-bit unsigned for encoding\n        magic = resolve_magic(funobj.get('magic'), objid_to_bidx) & 0xffff\n        assert(magic >= 0)\n        assert(magic <= 0xffff)\n        be.varuint(magic)\n\n        default_attrs = DEFAULT_FUNC_PROPERTY_ATTRIBUTES\n        attrs = funprop.get('attributes', default_attrs)\n        attrs = attrs.replace('a', '')  # ram bitstream doesn't encode 'accessor' attribute\n        if attrs != default_attrs:\n            logger.debug('non-default attributes: %s -> %r (default %r)' % (funprop['key'], attrs, default_attrs))\n            be.bits(1, 1)  # flag: have custom attributes\n            be.bits(encode_property_flags(attrs), PROP_FLAGS_BITS)\n        else:\n            be.bits(0, 1)  # flag: no custom attributes\n\n    return count_normal_props, count_function_props\n\n# Get helper maps for RAM objects.\ndef get_ramobj_native_func_maps(meta):\n    # Native function list and index\n    native_funcs_found = {}\n    native_funcs = []\n    natfunc_name_to_natidx = {}\n\n    native_funcs.append(None)  # natidx 0 is reserved for NULL\n\n    for o in meta['objects']:\n        if o.has_key('native'):\n            native_funcs_found[o['native']] = True\n        for v in o['properties']:\n            val = v['value']\n            if isinstance(val, dict):\n                if val['type'] == 'accessor':\n                    if val.has_key('getter_id'):\n                        getter = metadata_lookup_object(meta, val['getter_id'])\n                        native_funcs_found[getter['native']] = True\n                    if val.has_key('setter_id'):\n                        setter = metadata_lookup_object(meta, val['setter_id'])\n                        native_funcs_found[setter['native']] = True\n                if val['type'] == 'object':\n                    target = metadata_lookup_object(meta, val['id'])\n                    if target.has_key('native'):\n                        native_funcs_found[target['native']] = True\n                if val['type'] == 'lightfunc':\n                    # No lightfunc support for RAM initializer now.\n                    pass\n\n    for idx,k in enumerate(sorted(native_funcs_found.keys())):\n        natfunc_name_to_natidx[k] = len(native_funcs)\n        native_funcs.append(k)  # native func names\n\n    return native_funcs, natfunc_name_to_natidx\n\n# Generate bit-packed RAM object init data.\ndef gen_ramobj_initdata_bitpacked(meta, native_funcs, natfunc_name_to_natidx, double_byte_order):\n    # RAM initialization is based on a specially filtered list of top\n    # level objects which includes objects with 'bidx' and objects\n    # which aren't handled as inline values in the init bitstream.\n    objlist = meta['objects_ram_toplevel']\n    objid_to_idx = meta['_objid_to_ramidx']\n    objid_to_object = meta['_objid_to_object']  # This index is valid even for filtered object list\n    string_index = meta['_plain_to_stridx']\n\n    # Generate bitstream\n    be = dukutil.BitEncoder()\n    count_builtins = 0\n    count_normal_props = 0\n    count_function_props = 0\n    for o in objlist:\n        count_builtins += 1\n        gen_ramobj_initdata_for_object(meta, be, o, string_index, natfunc_name_to_natidx, objid_to_idx)\n    for o in objlist:\n        count_obj_normal, count_obj_func = gen_ramobj_initdata_for_props(meta, be, o, string_index, natfunc_name_to_natidx, objid_to_idx, double_byte_order)\n        count_normal_props += count_obj_normal\n        count_function_props += count_obj_func\n\n    if be._varuint_count > 0:\n        logger.debug('varuint distribution:')\n        logger.debug(json.dumps(be._varuint_dist[0:1024]))\n        logger.debug('Varuint encoding categories: %r' % be._varuint_cats)\n        logger.debug('Varuint efficiency: %f bits/value' % (float(be._varuint_bits) / float(be._varuint_count)))\n    romobj_init_data = be.getByteString()\n    #logger.debug(repr(romobj_init_data))\n    #logger.debug(len(romobj_init_data))\n\n    logger.debug('%d ram builtins, %d normal properties, %d function properties, %d bytes of object init data' % \\\n          (count_builtins, count_normal_props, count_function_props, len(romobj_init_data)))\n\n    return romobj_init_data\n\n# Functions to emit object-related source/header parts.\n\ndef emit_ramobj_source_nativefunc_array(genc, native_func_list):\n    genc.emitLine('/* native functions: %d */' % len(native_func_list))\n    genc.emitLine('DUK_INTERNAL const duk_c_function duk_bi_native_functions[%d] = {' % len(native_func_list))\n    for i in native_func_list:\n        # The function pointer cast here makes BCC complain about\n        # \"initializer too complicated\", so omit the cast.\n        #genc.emitLine('\\t(duk_c_function) %s,' % i)\n        if i is None:\n            genc.emitLine('\\tNULL,')\n        else:\n            genc.emitLine('\\t%s,' % i)\n    genc.emitLine('};')\n\ndef emit_ramobj_source_objinit_data(genc, init_data):\n    genc.emitArray(init_data, 'duk_builtins_data', visibility='DUK_INTERNAL', typename='duk_uint8_t', intvalues=True, const=True, size=len(init_data))\n\ndef emit_ramobj_header_nativefunc_array(genc, native_func_list):\n    genc.emitLine('#if !defined(DUK_SINGLE_FILE)')\n    genc.emitLine('DUK_INTERNAL_DECL const duk_c_function duk_bi_native_functions[%d];' % len(native_func_list))\n    genc.emitLine('#endif  /* !DUK_SINGLE_FILE */')\n\ndef emit_ramobj_header_objects(genc, meta):\n    objlist = meta['objects_bidx']\n    for idx,o in enumerate(objlist):\n        defname = 'DUK_BIDX_' + '_'.join(o['id'].upper().split('_')[1:])  # bi_foo_bar -> FOO_BAR\n        genc.emitDefine(defname, idx)\n    genc.emitDefine('DUK_NUM_BUILTINS', len(objlist))\n    genc.emitDefine('DUK_NUM_BIDX_BUILTINS', len(objlist))                      # Objects with 'bidx'\n    genc.emitDefine('DUK_NUM_ALL_BUILTINS', len(meta['objects_ram_toplevel']))  # Objects with 'bidx' + temps needed in init\n\ndef emit_ramobj_header_initdata(genc, init_data):\n    genc.emitLine('#if !defined(DUK_SINGLE_FILE)')\n    genc.emitLine('DUK_INTERNAL_DECL const duk_uint8_t duk_builtins_data[%d];' % len(init_data))\n    genc.emitLine('#endif  /* !DUK_SINGLE_FILE */')\n    genc.emitDefine('DUK_BUILTINS_DATA_LENGTH', len(init_data))\n\n#\n#  ROM init data\n#\n#  Compile-time initializers for ROM strings and ROM objects.  This involves\n#  a lot of small details:\n#\n#    - Several variants are needed for different options: unpacked vs.\n#      packed duk_tval, endianness, string hash in use, etc).\n#\n#    - Static initializers must represent objects of different size.  For\n#      example, separate structs are needed for property tables of different\n#      size or value typing.\n#\n#    - Union initializers cannot be used portable because they're only\n#      available in C99 and above.\n#\n#    - Initializers must use 'const' correctly to ensure that the entire\n#      initialization data will go into ROM (read-only data section).\n#      Const pointers etc will need to be cast into non-const pointers at\n#      some point to properly mix with non-const RAM pointers, so a portable\n#      const losing cast is needed.\n#\n#    - C++ doesn't allow forward declaration of \"static const\" structures\n#      which is problematic because there are cyclical const structures.\n#\n\n# Get string hash initializers; need to compute possible string hash variants\n# which will match runtime values.\ndef rom_get_strhash16_macro(val):\n    hash16le = dukutil.duk_heap_hashstring_dense(val, DUK__FIXED_HASH_SEED, big_endian=False, strhash16=True)\n    hash16be = dukutil.duk_heap_hashstring_dense(val, DUK__FIXED_HASH_SEED, big_endian=True, strhash16=True)\n    hash16sparse = dukutil.duk_heap_hashstring_sparse(val, DUK__FIXED_HASH_SEED, strhash16=True)\n    return 'DUK__STRHASH16(%dU,%dU,%dU)' % (hash16le, hash16be, hash16sparse)\ndef rom_get_strhash32_macro(val):\n    hash32le = dukutil.duk_heap_hashstring_dense(val, DUK__FIXED_HASH_SEED, big_endian=False, strhash16=False)\n    hash32be = dukutil.duk_heap_hashstring_dense(val, DUK__FIXED_HASH_SEED, big_endian=True, strhash16=False)\n    hash32sparse = dukutil.duk_heap_hashstring_sparse(val, DUK__FIXED_HASH_SEED, strhash16=False)\n    return 'DUK__STRHASH32(%dUL,%dUL,%dUL)' % (hash32le, hash32be, hash32sparse)\n\n# Get string character .length; must match runtime .length computation.\ndef rom_charlen(x):\n    return dukutil.duk_unicode_unvalidated_utf8_length(x)\n\n# Get an initializer type and initializer literal for a specified value\n# (expressed in YAML metadata format).  The types and initializers depend\n# on declarations emitted before the initializers, and in several cases\n# use a macro to hide the selection between several initializer variants.\ndef rom_get_value_initializer(meta, val, bi_str_map, bi_obj_map):\n    def double_bytes_initializer(val):\n        # Portable and exact float initializer.\n        assert(isinstance(val, str) and len(val) == 16)  # hex encoded bytes\n        val = val.decode('hex')\n        tmp = []\n        for i in xrange(8):\n            t = ord(val[i])\n            if t >= 128:\n                tmp.append('%dU' % t)\n            else:\n                tmp.append('%d' % t)\n        return 'DUK__DBLBYTES(' + ','.join(tmp) + ')'\n\n    def tval_number_initializer(val):\n        return 'DUK__TVAL_NUMBER(%s)' % double_bytes_initializer(val)\n\n    v = val['value']\n    if v is None:\n        init_type = 'duk_rom_tval_null'\n        init_lit = 'DUK__TVAL_NULL()'\n    elif isinstance(v, (bool)):\n        init_type = 'duk_rom_tval_boolean'\n        bval = 0\n        if v:\n            bval = 1\n        init_lit = 'DUK__TVAL_BOOLEAN(%d)' % bval\n    elif isinstance(v, (int, float)):\n        fval = struct.pack('>d', float(v)).encode('hex')\n        init_type = 'duk_rom_tval_number'\n        init_lit = tval_number_initializer(fval)\n    elif isinstance(v, (str, unicode)):\n        init_type = 'duk_rom_tval_string'\n        init_lit = 'DUK__TVAL_STRING(&%s)' % bi_str_map[v]\n    elif isinstance(v, (dict)):\n        if v['type'] == 'double':\n            init_type = 'duk_rom_tval_number'\n            init_lit = tval_number_initializer(v['bytes'])\n        elif v['type'] == 'undefined':\n            init_type = 'duk_rom_tval_undefined'\n            init_lit = 'DUK__TVAL_UNDEFINED()'\n        elif v['type'] == 'null':\n            init_type = 'duk_rom_tval_null'\n            init_lit = 'DUK__TVAL_UNDEFINED()'\n        elif v['type'] == 'object':\n            init_type = 'duk_rom_tval_object'\n            init_lit = 'DUK__TVAL_OBJECT(&%s)' % bi_obj_map[v['id']]\n        elif v['type'] == 'accessor':\n            getter_ref = 'NULL'\n            setter_ref = 'NULL'\n            if v.has_key('getter_id'):\n                getter_object = metadata_lookup_object(meta, v['getter_id'])\n                getter_ref = '&%s' % bi_obj_map[getter_object['id']]\n            if v.has_key('setter_id'):\n                setter_object = metadata_lookup_object(meta, v['setter_id'])\n                setter_ref = '&%s' % bi_obj_map[setter_object['id']]\n            init_type = 'duk_rom_tval_accessor'\n            init_lit = 'DUK__TVAL_ACCESSOR(%s, %s)' % (getter_ref, setter_ref)\n        elif v['type'] == 'lightfunc':\n            # Match DUK_LFUNC_FLAGS_PACK() in duk_tval.h.\n            if v.has_key('length'):\n                assert(v['length'] >= 0 and v['length'] <= 15)\n                lf_length = v['length']\n            else:\n                lf_length = 0\n            if v.get('varargs', True):\n                lf_nargs = 15  # varargs marker\n            else:\n                assert(v['nargs'] >= 0 and v['nargs'] <= 14)\n                lf_nargs = v['nargs']\n            if v.has_key('magic'):\n                assert(v['magic'] >= -0x80 and v['magic'] <= 0x7f)\n                lf_magic = v['magic'] & 0xff\n            else:\n                lf_magic = 0\n            lf_flags = (lf_magic << 8) + (lf_length << 4) + lf_nargs\n            init_type = 'duk_rom_tval_lightfunc'\n            init_lit = 'DUK__TVAL_LIGHTFUNC(%s, %dL)' % (v['native'], lf_flags)\n        else:\n            raise Exception('unhandled value: %r' % val)\n    else:\n        raise Exception('internal error: %r' % val)\n    return init_type, init_lit\n\n# Helpers to get either initializer type or value only (not both).\ndef rom_get_value_initializer_type(meta, val, bi_str_map, bi_obj_map):\n    init_type, init_lit = rom_get_value_initializer(meta, val, bi_str_map, bi_obj_map)\n    return init_type\ndef rom_get_value_initializer_literal(meta, val, bi_str_map, bi_obj_map):\n    init_type, init_lit = rom_get_value_initializer(meta, val, bi_str_map, bi_obj_map)\n    return init_lit\n\n# Emit ROM strings source: structs/typedefs and their initializers.\n# Separate initialization structs are needed for strings of different\n# length.\ndef rom_emit_strings_source(genc, meta):\n    # Write built-in strings as code section initializers.\n\n    strs = meta['_strings_plain']  # all strings, plain versions\n    reserved_words = meta['_is_plain_reserved_word']\n    strict_reserved_words = meta['_is_plain_strict_reserved_word']\n    strs_needing_stridx = meta['strings_stridx']\n\n    # Sort used lengths and declare per-length initializers.\n    lens = []\n    for v in strs:\n        strlen = len(v)\n        if strlen not in lens:\n            lens.append(strlen)\n    lens.sort()\n    for strlen in lens:\n        genc.emitLine('typedef struct duk_romstr_%d duk_romstr_%d; ' % (strlen, strlen) +\n                      'struct duk_romstr_%d { duk_hstring hdr; duk_uint8_t data[%d]; };' % (strlen, strlen + 1))\n    genc.emitLine('')\n\n    # String hash values depend on endianness and other factors,\n    # use an initializer macro to select the appropriate hash.\n    genc.emitLine('/* When unaligned access possible, 32-bit values are fetched using host order.')\n    genc.emitLine(' * When unaligned access not possible, always simulate little endian order.')\n    genc.emitLine(' * See: src-input/duk_util_hashbytes.c:duk_util_hashbytes().')\n    genc.emitLine(' */')\n    genc.emitLine('#if defined(DUK_USE_STRHASH_DENSE)')\n    genc.emitLine('#if defined(DUK_USE_HASHBYTES_UNALIGNED_U32_ACCESS)')  # XXX: config option to be reworked\n    genc.emitLine('#if defined(DUK_USE_INTEGER_BE)')\n    genc.emitLine('#define DUK__STRHASH16(hash16le,hash16be,hash16sparse) (hash16be)')\n    genc.emitLine('#define DUK__STRHASH32(hash32le,hash32be,hash32sparse) (hash32be)')\n    genc.emitLine('#else')\n    genc.emitLine('#define DUK__STRHASH16(hash16le,hash16be,hash16sparse) (hash16le)')\n    genc.emitLine('#define DUK__STRHASH32(hash32le,hash32be,hash32sparse) (hash32le)')\n    genc.emitLine('#endif')\n    genc.emitLine('#else')\n    genc.emitLine('#define DUK__STRHASH16(hash16le,hash16be,hash16sparse) (hash16le)')\n    genc.emitLine('#define DUK__STRHASH32(hash32le,hash32be,hash32sparse) (hash32le)')\n    genc.emitLine('#endif')\n    genc.emitLine('#else  /* DUK_USE_STRHASH_DENSE */')\n    genc.emitLine('#define DUK__STRHASH16(hash16le,hash16be,hash16sparse) (hash16sparse)')\n    genc.emitLine('#define DUK__STRHASH32(hash32le,hash32be,hash32sparse) (hash32sparse)')\n    genc.emitLine('#endif  /* DUK_USE_STRHASH_DENSE */')\n\n    # String header initializer macro, takes into account lowmem etc.\n    genc.emitLine('#if defined(DUK_USE_HEAPPTR16)')\n    genc.emitLine('#if !defined(DUK_USE_REFCOUNT16)')\n    genc.emitLine('#error currently assumes DUK_USE_HEAPPTR16 and DUK_USE_REFCOUNT16 are both defined')\n    genc.emitLine('#endif')\n    genc.emitLine('#if defined(DUK_USE_HSTRING_CLEN)')\n    genc.emitLine('#define DUK__STRINIT(heaphdr_flags,refcount,hash32,hash16,blen,clen,next) \\\\')\n    genc.emitLine('\\t{ { (heaphdr_flags) | ((hash16) << 16), DUK__REFCINIT((refcount)), (blen), (duk_hstring *) DUK_LOSE_CONST((next)) }, (clen) }')\n    genc.emitLine('#else  /* DUK_USE_HSTRING_CLEN */')\n    genc.emitLine('#define DUK__STRINIT(heaphdr_flags,refcount,hash32,hash16,blen,clen,next) \\\\')\n    genc.emitLine('\\t{ { (heaphdr_flags) | ((hash16) << 16), DUK__REFCINIT((refcount)), (blen), (duk_hstring *) DUK_LOSE_CONST((next)) } }')\n    genc.emitLine('#endif  /* DUK_USE_HSTRING_CLEN */')\n    genc.emitLine('#else  /* DUK_USE_HEAPPTR16 */')\n    genc.emitLine('#define DUK__STRINIT(heaphdr_flags,refcount,hash32,hash16,blen,clen,next) \\\\')\n    genc.emitLine('\\t{ { (heaphdr_flags), DUK__REFCINIT((refcount)), (duk_hstring *) DUK_LOSE_CONST((next)) }, (hash32), (blen), (clen) }')\n    genc.emitLine('#endif  /* DUK_USE_HEAPPTR16 */')\n\n    # Organize ROM strings into a chained ROM string table.  The ROM string\n    # h_next link pointer is used for chaining just like for RAM strings but\n    # in a separate string table.\n    #\n    # To avoid dealing with the different possible string hash algorithms,\n    # use a much more trivial lookup key for ROM strings for now.\n    romstr_hash = []\n    while len(romstr_hash) < ROMSTR_LOOKUP_SIZE:\n        romstr_hash.append([])\n    for str_index,v in enumerate(strs):\n        if len(v) > 0:\n            rom_lookup_hash = ord(v[0]) + (len(v) << 4)\n        else:\n            rom_lookup_hash = 0 + (len(v) << 4)\n        rom_lookup_hash = rom_lookup_hash & 0xff\n        romstr_hash[rom_lookup_hash].append(v)\n\n    romstr_next = {}   # string -> the string's 'next' link\n    for lst in romstr_hash:\n        prev = None\n        #print(repr(lst))\n        for v in lst:\n            if prev is not None:\n                romstr_next[prev] = v\n            prev = v\n\n    chain_lens = {}\n    for lst in romstr_hash:\n        chainlen = len(lst)\n        if not chain_lens.has_key(chainlen):\n            chain_lens[chainlen] = 0\n        chain_lens[chainlen] += 1\n    tmp = []\n    for k in sorted(chain_lens.keys()):\n        tmp.append('%d: %d' % (k, chain_lens[k]))\n    logger.info('ROM string table chain lengths: %s' % ', '.join(tmp))\n\n    bi_str_map = {}   # string -> initializer variable name\n    for str_index,v in enumerate(strs):\n        bi_str_map[v] = 'duk_str_%d' % str_index\n\n    # Emit string initializers.  Emit the strings in an order which avoids\n    # forward declarations for the h_next link pointers; const forward\n    # declarations are a problem in C++.\n    genc.emitLine('')\n    for lst in romstr_hash:\n        for v in reversed(lst):\n            tmp = 'DUK_INTERNAL const duk_romstr_%d %s = {' % (len(v), bi_str_map[v])\n            flags = [ 'DUK_HTYPE_STRING',\n                      'DUK_HEAPHDR_FLAG_READONLY',\n                      'DUK_HEAPHDR_FLAG_REACHABLE',\n                      'DUK_HSTRING_FLAG_PINNED_LITERAL' ]\n            is_arridx = string_is_arridx(v)\n\n            blen = len(v)\n            clen = rom_charlen(v)\n\n            if blen == clen:\n                flags.append('DUK_HSTRING_FLAG_ASCII')\n            if is_arridx:\n                flags.append('DUK_HSTRING_FLAG_ARRIDX')\n            if len(v) >= 1 and v[0] in [ '\\x80', '\\x81', '\\x82', '\\xff' ]:\n                flags.append('DUK_HSTRING_FLAG_SYMBOL')\n            if len(v) >= 1 and v[0] in [ '\\x82', '\\xff' ]:\n                flags.append('DUK_HSTRING_FLAG_HIDDEN')\n            if v in [ 'eval', 'arguments' ]:\n                flags.append('DUK_HSTRING_FLAG_EVAL_OR_ARGUMENTS')\n            if reserved_words.has_key(v):\n                flags.append('DUK_HSTRING_FLAG_RESERVED_WORD')\n            if strict_reserved_words.has_key(v):\n                flags.append('DUK_HSTRING_FLAG_STRICT_RESERVED_WORD')\n\n            h_next = 'NULL'\n            if romstr_next.has_key(v):\n                h_next = '&' + bi_str_map[romstr_next[v]]\n\n            tmp += 'DUK__STRINIT(%s,%d,%s,%s,%d,%d,%s),' % \\\n                ('|'.join(flags), 1, rom_get_strhash32_macro(v), \\\n                 rom_get_strhash16_macro(v), blen, clen, h_next)\n\n            tmpbytes = []\n            for c in v:\n                if ord(c) < 128:\n                    tmpbytes.append('%d' % ord(c))\n                else:\n                    tmpbytes.append('%dU' % ord(c))\n            tmpbytes.append('%d' % 0)  # NUL term\n            tmp += '{' + ','.join(tmpbytes) + '}'\n            tmp += '};'\n            genc.emitLine(tmp)\n\n    # Emit the ROM string lookup table used by string interning.\n    #\n    # cdecl> explain const int * const foo;\n    # declare foo as const pointer to const int\n    genc.emitLine('')\n    genc.emitLine('DUK_INTERNAL const duk_hstring * const duk_rom_strings_lookup[%d] = {'% len(romstr_hash))\n    tmp = []\n    linecount = 0\n    for lst in romstr_hash:\n        if len(lst) == 0:\n            genc.emitLine('\\tNULL,')\n        else:\n            genc.emitLine('\\t(const duk_hstring *) &%s,' % bi_str_map[lst[0]])\n    genc.emitLine('};')\n\n    # Emit an array of duk_hstring pointers indexed using DUK_STRIDX_xxx.\n    # This will back e.g. DUK_HTHREAD_STRING_XYZ(thr) directly, without\n    # needing an explicit array in thr/heap->strs[].\n    #\n    # cdecl > explain const int * const foo;\n    # declare foo as const pointer to const int\n    genc.emitLine('')\n    genc.emitLine('DUK_INTERNAL const duk_hstring * const duk_rom_strings_stridx[%d] = {' % len(strs_needing_stridx))\n    for s in strs_needing_stridx:\n        genc.emitLine('\\t(const duk_hstring *) &%s,' % bi_str_map[s['str']])  # strs_needing_stridx is a list of objects, not plain strings\n    genc.emitLine('};')\n\n    return bi_str_map\n\n# Emit ROM strings header.\ndef rom_emit_strings_header(genc, meta):\n    genc.emitLine('#if !defined(DUK_SINGLE_FILE)')  # C++ static const workaround\n    genc.emitLine('DUK_INTERNAL_DECL const duk_hstring * const duk_rom_strings_lookup[%d];' % ROMSTR_LOOKUP_SIZE)\n    genc.emitLine('DUK_INTERNAL_DECL const duk_hstring * const duk_rom_strings_stridx[%d];' % len(meta['strings_stridx']))\n    genc.emitLine('#endif')\n\n# Emit ROM objects initialized types and macros.\ndef rom_emit_object_initializer_types_and_macros(genc):\n    # Objects and functions are straightforward because they just use the\n    # RAM structure which has no dynamic or variable size parts.\n    genc.emitLine('typedef struct duk_romobj duk_romobj; ' + \\\n                  'struct duk_romobj { duk_hobject hdr; };')\n    genc.emitLine('typedef struct duk_romarr duk_romarr; ' + \\\n                  'struct duk_romarr { duk_harray hdr; };')\n    genc.emitLine('typedef struct duk_romfun duk_romfun; ' + \\\n                  'struct duk_romfun { duk_hnatfunc hdr; };')\n    genc.emitLine('typedef struct duk_romobjenv duk_romobjenv; ' + \\\n                  'struct duk_romobjenv { duk_hobjenv hdr; };')\n\n    # For ROM pointer compression we'd need a -compile time- variant.\n    # The current portable solution is to just assign running numbers\n    # to ROM compressed pointers, and provide the table for user pointer\n    # compression function.  Much better solutions would be possible,\n    # but such solutions are often compiler/platform specific.\n\n    # Emit object/function initializer which is aware of options affecting\n    # the header.  Heap next/prev pointers are always NULL.\n    genc.emitLine('#if defined(DUK_USE_HEAPPTR16)')\n    genc.emitLine('#if !defined(DUK_USE_REFCOUNT16) || defined(DUK_USE_HOBJECT_HASH_PART)')\n    genc.emitLine('#error currently assumes DUK_USE_HEAPPTR16 and DUK_USE_REFCOUNT16 are both defined and DUK_USE_HOBJECT_HASH_PART is undefined')\n    genc.emitLine('#endif')\n    #genc.emitLine('#if !defined(DUK_USE_HEAPPTR_ENC16_STATIC)')\n    #genc.emitLine('#error need DUK_USE_HEAPPTR_ENC16_STATIC which provides compile-time pointer compression')\n    #genc.emitLine('#endif')\n    genc.emitLine('#define DUK__ROMOBJ_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize) \\\\')\n    genc.emitLine('\\t{ { { (heaphdr_flags), DUK__REFCINIT((refcount)), 0, 0, (props_enc16) }, (iproto_enc16), (esize), (enext), (asize) } }')\n    genc.emitLine('#define DUK__ROMARR_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize,length) \\\\')\n    genc.emitLine('\\t{ { { { (heaphdr_flags), DUK__REFCINIT((refcount)), 0, 0, (props_enc16) }, (iproto_enc16), (esize), (enext), (asize) }, (length), 0 /*length_nonwritable*/ } }')\n    genc.emitLine('#define DUK__ROMFUN_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize,nativefunc,nargs,magic) \\\\')\n    genc.emitLine('\\t{ { { { (heaphdr_flags), DUK__REFCINIT((refcount)), 0, 0, (props_enc16) }, (iproto_enc16), (esize), (enext), (asize) }, (nativefunc), (duk_int16_t) (nargs), (duk_int16_t) (magic) } }')\n    genc.emitLine('#define DUK__ROMOBJENV_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize,target,has_this) \\\\')\n    genc.emitLine('\\t{ { { { (heaphdr_flags), DUK__REFCINIT((refcount)), 0, 0, (props_enc16) }, (iproto_enc16), (esize), (enext), (asize) }, (duk_hobject *) DUK_LOSE_CONST(target), (has_this) } }')\n    genc.emitLine('#else  /* DUK_USE_HEAPPTR16 */')\n    genc.emitLine('#define DUK__ROMOBJ_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize) \\\\')\n    genc.emitLine('\\t{ { { (heaphdr_flags), DUK__REFCINIT((refcount)), NULL, NULL }, (duk_uint8_t *) DUK_LOSE_CONST(props), (duk_hobject *) DUK_LOSE_CONST(iproto), (esize), (enext), (asize), (hsize) } }')\n    genc.emitLine('#define DUK__ROMARR_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize,length) \\\\')\n    genc.emitLine('\\t{ { { { (heaphdr_flags), DUK__REFCINIT((refcount)), NULL, NULL }, (duk_uint8_t *) DUK_LOSE_CONST(props), (duk_hobject *) DUK_LOSE_CONST(iproto), (esize), (enext), (asize), (hsize) }, (length), 0 /*length_nonwritable*/ } }')\n    genc.emitLine('#define DUK__ROMFUN_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize,nativefunc,nargs,magic) \\\\')\n    genc.emitLine('\\t{ { { { (heaphdr_flags), DUK__REFCINIT((refcount)), NULL, NULL }, (duk_uint8_t *) DUK_LOSE_CONST(props), (duk_hobject *) DUK_LOSE_CONST(iproto), (esize), (enext), (asize), (hsize) }, (nativefunc), (duk_int16_t) (nargs), (duk_int16_t) (magic) } }')\n    genc.emitLine('#define DUK__ROMOBJENV_INIT(heaphdr_flags,refcount,props,props_enc16,iproto,iproto_enc16,esize,enext,asize,hsize,target,has_this) \\\\')\n    genc.emitLine('\\t{ { { { (heaphdr_flags), DUK__REFCINIT((refcount)), NULL, NULL }, (duk_uint8_t *) DUK_LOSE_CONST(props), (duk_hobject *) DUK_LOSE_CONST(iproto), (esize), (enext), (asize), (hsize) }, (duk_hobject *) DUK_LOSE_CONST(target), (has_this) } }')\n    genc.emitLine('#endif  /* DUK_USE_HEAPPTR16 */')\n\n    # Initializer typedef for a dummy function pointer.  ROM support assumes\n    # function pointers are 32 bits.  Using a dummy function pointer type\n    # avoids function pointer to normal pointer cast which emits warnings.\n    genc.emitLine('typedef void (*duk_rom_funcptr)(void);')\n\n    # Emit duk_tval structs.  This gets a bit messier with packed/unpacked\n    # duk_tval, endianness variants, pointer sizes, etc.\n    genc.emitLine('#if defined(DUK_USE_PACKED_TVAL)')\n    genc.emitLine('typedef struct duk_rom_tval_undefined duk_rom_tval_undefined;')\n    genc.emitLine('typedef struct duk_rom_tval_null duk_rom_tval_null;')\n    genc.emitLine('typedef struct duk_rom_tval_lightfunc duk_rom_tval_lightfunc;')\n    genc.emitLine('typedef struct duk_rom_tval_boolean duk_rom_tval_boolean;')\n    genc.emitLine('typedef struct duk_rom_tval_number duk_rom_tval_number;')\n    genc.emitLine('typedef struct duk_rom_tval_object duk_rom_tval_object;')\n    genc.emitLine('typedef struct duk_rom_tval_string duk_rom_tval_string;')\n    genc.emitLine('typedef struct duk_rom_tval_accessor duk_rom_tval_accessor;')\n    genc.emitLine('struct duk_rom_tval_number { duk_uint8_t bytes[8]; };')\n    genc.emitLine('struct duk_rom_tval_accessor { const duk_hobject *get; const duk_hobject *set; };')\n    genc.emitLine('#if defined(DUK_USE_DOUBLE_LE)')\n    genc.emitLine('struct duk_rom_tval_object { const void *ptr; duk_uint32_t hiword; };')\n    genc.emitLine('struct duk_rom_tval_string { const void *ptr; duk_uint32_t hiword; };')\n    genc.emitLine('struct duk_rom_tval_undefined { const void *ptr; duk_uint32_t hiword; };')\n    genc.emitLine('struct duk_rom_tval_null { const void *ptr; duk_uint32_t hiword; };')\n    genc.emitLine('struct duk_rom_tval_lightfunc { duk_rom_funcptr ptr; duk_uint32_t hiword; };')\n    genc.emitLine('struct duk_rom_tval_boolean { duk_uint32_t dummy; duk_uint32_t hiword; };')\n    genc.emitLine('#elif defined(DUK_USE_DOUBLE_BE)')\n    genc.emitLine('struct duk_rom_tval_object { duk_uint32_t hiword; const void *ptr; };')\n    genc.emitLine('struct duk_rom_tval_string { duk_uint32_t hiword; const void *ptr; };')\n    genc.emitLine('struct duk_rom_tval_undefined { duk_uint32_t hiword; const void *ptr; };')\n    genc.emitLine('struct duk_rom_tval_null { duk_uint32_t hiword; const void *ptr; };')\n    genc.emitLine('struct duk_rom_tval_lightfunc { duk_uint32_t hiword; duk_rom_funcptr ptr; };')\n    genc.emitLine('struct duk_rom_tval_boolean { duk_uint32_t hiword; duk_uint32_t dummy; };')\n    genc.emitLine('#elif defined(DUK_USE_DOUBLE_ME)')\n    genc.emitLine('struct duk_rom_tval_object { duk_uint32_t hiword; const void *ptr; };')\n    genc.emitLine('struct duk_rom_tval_string { duk_uint32_t hiword; const void *ptr; };')\n    genc.emitLine('struct duk_rom_tval_undefined { duk_uint32_t hiword; const void *ptr; };')\n    genc.emitLine('struct duk_rom_tval_null { duk_uint32_t hiword; const void *ptr; };')\n    genc.emitLine('struct duk_rom_tval_lightfunc { duk_uint32_t hiword; duk_rom_funcptr ptr; };')\n    genc.emitLine('struct duk_rom_tval_boolean { duk_uint32_t hiword; duk_uint32_t dummy; };')\n    genc.emitLine('#else')\n    genc.emitLine('#error invalid endianness defines')\n    genc.emitLine('#endif')\n    genc.emitLine('#else  /* DUK_USE_PACKED_TVAL */')\n    # Unpacked initializers are written assuming normal struct alignment\n    # rules so that sizeof(duk_tval) == 16.  32-bit pointers need special\n    # handling to ensure the individual initializers pad to 16 bytes as\n    # necessary.\n    # XXX: 32-bit unpacked duk_tval is not yet supported.\n    genc.emitLine('#if defined(DUK_UINTPTR_MAX)')\n    genc.emitLine('#if (DUK_UINTPTR_MAX <= 0xffffffffUL)')\n    genc.emitLine('#error ROM initializer with unpacked duk_tval does not currently work on 32-bit targets')\n    genc.emitLine('#endif')\n    genc.emitLine('#endif')\n    genc.emitLine('typedef struct duk_rom_tval_undefined duk_rom_tval_undefined;')\n    genc.emitLine('struct duk_rom_tval_undefined { duk_small_uint_t tag; duk_small_uint_t extra; duk_uint8_t bytes[8]; };')\n    genc.emitLine('typedef struct duk_rom_tval_null duk_rom_tval_null;')\n    genc.emitLine('struct duk_rom_tval_null { duk_small_uint_t tag; duk_small_uint_t extra; duk_uint8_t bytes[8]; };')\n    genc.emitLine('typedef struct duk_rom_tval_boolean duk_rom_tval_boolean;')\n    genc.emitLine('struct duk_rom_tval_boolean { duk_small_uint_t tag; duk_small_uint_t extra; duk_uint32_t val; duk_uint32_t unused; };')\n    genc.emitLine('typedef struct duk_rom_tval_number duk_rom_tval_number;')\n    genc.emitLine('struct duk_rom_tval_number { duk_small_uint_t tag; duk_small_uint_t extra; duk_uint8_t bytes[8]; };')\n    genc.emitLine('typedef struct duk_rom_tval_object duk_rom_tval_object;')\n    genc.emitLine('struct duk_rom_tval_object { duk_small_uint_t tag; duk_small_uint_t extra; const duk_heaphdr *val; };')\n    genc.emitLine('typedef struct duk_rom_tval_string duk_rom_tval_string;')\n    genc.emitLine('struct duk_rom_tval_string { duk_small_uint_t tag; duk_small_uint_t extra; const duk_heaphdr *val; };')\n    genc.emitLine('typedef struct duk_rom_tval_lightfunc duk_rom_tval_lightfunc;')\n    genc.emitLine('struct duk_rom_tval_lightfunc { duk_small_uint_t tag; duk_small_uint_t extra; duk_rom_funcptr ptr; };')\n    genc.emitLine('typedef struct duk_rom_tval_accessor duk_rom_tval_accessor;')\n    genc.emitLine('struct duk_rom_tval_accessor { const duk_hobject *get; const duk_hobject *set; };')\n    genc.emitLine('#endif  /* DUK_USE_PACKED_TVAL */')\n    genc.emitLine('')\n\n    # Double initializer byte shuffle macro to handle byte orders\n    # without duplicating the entire initializers.\n    genc.emitLine('#if defined(DUK_USE_DOUBLE_LE)')\n    genc.emitLine('#define DUK__DBLBYTES(a,b,c,d,e,f,g,h) { (h), (g), (f), (e), (d), (c), (b), (a) }')\n    genc.emitLine('#elif defined(DUK_USE_DOUBLE_BE)')\n    genc.emitLine('#define DUK__DBLBYTES(a,b,c,d,e,f,g,h) { (a), (b), (c), (d), (e), (f), (g), (h) }')\n    genc.emitLine('#elif defined(DUK_USE_DOUBLE_ME)')\n    genc.emitLine('#define DUK__DBLBYTES(a,b,c,d,e,f,g,h) { (d), (c), (b), (a), (h), (g), (f), (e) }')\n    genc.emitLine('#else')\n    genc.emitLine('#error invalid endianness defines')\n    genc.emitLine('#endif')\n    genc.emitLine('')\n\n    # Emit duk_tval initializer literal macros.\n    genc.emitLine('#if defined(DUK_USE_PACKED_TVAL)')\n    genc.emitLine('#define DUK__TVAL_NUMBER(hostbytes) { hostbytes }')  # bytes already in host order\n    genc.emitLine('#if defined(DUK_USE_DOUBLE_LE)')\n    genc.emitLine('#define DUK__TVAL_UNDEFINED() { (const void *) NULL, (DUK_TAG_UNDEFINED << 16) }')\n    genc.emitLine('#define DUK__TVAL_NULL() { (const void *) NULL, (DUK_TAG_NULL << 16) }')\n    genc.emitLine('#define DUK__TVAL_LIGHTFUNC(func,flags) { (duk_rom_funcptr) (func), (DUK_TAG_LIGHTFUNC << 16) + (flags) }')\n    genc.emitLine('#define DUK__TVAL_BOOLEAN(bval) { 0, (DUK_TAG_BOOLEAN << 16) + (bval) }')\n    genc.emitLine('#define DUK__TVAL_OBJECT(ptr) { (const void *) (ptr), (DUK_TAG_OBJECT << 16) }')\n    genc.emitLine('#define DUK__TVAL_STRING(ptr) { (const void *) (ptr), (DUK_TAG_STRING << 16) }')\n    genc.emitLine('#elif defined(DUK_USE_DOUBLE_BE)')\n    genc.emitLine('#define DUK__TVAL_UNDEFINED() { (DUK_TAG_UNDEFINED << 16), (const void *) NULL }')\n    genc.emitLine('#define DUK__TVAL_NULL() { (DUK_TAG_NULL << 16), (const void *) NULL }')\n    genc.emitLine('#define DUK__TVAL_LIGHTFUNC(func,flags) { (DUK_TAG_LIGHTFUNC << 16) + (flags), (duk_rom_funcptr) (func) }')\n    genc.emitLine('#define DUK__TVAL_BOOLEAN(bval) { (DUK_TAG_BOOLEAN << 16) + (bval), 0 }')\n    genc.emitLine('#define DUK__TVAL_OBJECT(ptr) { (DUK_TAG_OBJECT << 16), (const void *) (ptr) }')\n    genc.emitLine('#define DUK__TVAL_STRING(ptr) { (DUK_TAG_STRING << 16), (const void *) (ptr) }')\n    genc.emitLine('#elif defined(DUK_USE_DOUBLE_ME)')\n    genc.emitLine('#define DUK__TVAL_UNDEFINED() { (DUK_TAG_UNDEFINED << 16), (const void *) NULL }')\n    genc.emitLine('#define DUK__TVAL_NULL() { (DUK_TAG_NULL << 16), (const void *) NULL }')\n    genc.emitLine('#define DUK__TVAL_LIGHTFUNC(func,flags) { (DUK_TAG_LIGHTFUNC << 16) + (flags), (duk_rom_funcptr) (func) }')\n    genc.emitLine('#define DUK__TVAL_BOOLEAN(bval) { (DUK_TAG_BOOLEAN << 16) + (bval), 0 }')\n    genc.emitLine('#define DUK__TVAL_OBJECT(ptr) { (DUK_TAG_OBJECT << 16), (const void *) (ptr) }')\n    genc.emitLine('#define DUK__TVAL_STRING(ptr) { (DUK_TAG_STRING << 16), (const void *) (ptr) }')\n    genc.emitLine('#else')\n    genc.emitLine('#error invalid endianness defines')\n    genc.emitLine('#endif')\n    genc.emitLine('#else  /* DUK_USE_PACKED_TVAL */')\n    genc.emitLine('#define DUK__TVAL_NUMBER(hostbytes) { DUK_TAG_NUMBER, 0, hostbytes }')  # bytes already in host order\n    genc.emitLine('#define DUK__TVAL_UNDEFINED() { DUK_TAG_UNDEFINED, 0, {0,0,0,0,0,0,0,0} }')\n    genc.emitLine('#define DUK__TVAL_NULL() { DUK_TAG_NULL, 0, {0,0,0,0,0,0,0,0} }')\n    genc.emitLine('#define DUK__TVAL_BOOLEAN(bval) { DUK_TAG_BOOLEAN, 0, (bval), 0 }')\n    genc.emitLine('#define DUK__TVAL_OBJECT(ptr) { DUK_TAG_OBJECT, 0, (const duk_heaphdr *) (ptr) }')\n    genc.emitLine('#define DUK__TVAL_STRING(ptr) { DUK_TAG_STRING, 0, (const duk_heaphdr *) (ptr) }')\n    genc.emitLine('#define DUK__TVAL_LIGHTFUNC(func,flags) { DUK_TAG_LIGHTFUNC, (flags), (duk_rom_funcptr) (func) }')\n    genc.emitLine('#endif  /* DUK_USE_PACKED_TVAL */')\n    genc.emitLine('#define DUK__TVAL_ACCESSOR(getter,setter) { (const duk_hobject *) (getter), (const duk_hobject *) (setter) }')\n\n# Emit ROM objects source: the object/function headers themselves, property\n# table structs for different property table sizes/types, and property table\n# initializers.\ndef rom_emit_objects(genc, meta, bi_str_map):\n    objs = meta['objects']\n    id_to_bidx = meta['_objid_to_bidx']\n\n    # Table for compressed ROM pointers; reserve high range of compressed pointer\n    # values for this purpose.  This must contain all ROM pointers that might be\n    # referenced (all objects, strings, and property tables at least).\n    romptr_compress_list = []\n    def compress_rom_ptr(x):\n        if x == 'NULL':\n            return 0\n        try:\n            idx = romptr_compress_list.index(x)\n            res = ROMPTR_FIRST + idx\n        except ValueError:\n            romptr_compress_list.append(x)\n            res = ROMPTR_FIRST + len(romptr_compress_list) - 1\n        assert(res <= 0xffff)\n        return res\n\n    # Need string and object maps (id -> C symbol name) early.\n    bi_obj_map = {}   # object id -> initializer variable name\n    for idx,obj in enumerate(objs):\n        bi_obj_map[obj['id']] = 'duk_obj_%d' % idx\n\n    # Add built-in strings and objects to compressed ROM pointers first.\n    for k in sorted(bi_str_map.keys()):\n        compress_rom_ptr('&%s' % bi_str_map[k])\n    for k in sorted(bi_obj_map.keys()):\n        compress_rom_ptr('&%s' % bi_obj_map[k])\n\n    # Property attributes lookup, map metadata attribute string into a\n    # C initializer.\n    attr_lookup = {\n        '':    'DUK_PROPDESC_FLAGS_NONE',\n        'w':    'DUK_PROPDESC_FLAGS_W',\n        'e':    'DUK_PROPDESC_FLAGS_E',\n        'c':    'DUK_PROPDESC_FLAGS_C',\n        'we':    'DUK_PROPDESC_FLAGS_WE',\n        'wc':    'DUK_PROPDESC_FLAGS_WC',\n        'ec':    'DUK_PROPDESC_FLAGS_EC',\n        'wec':    'DUK_PROPDESC_FLAGS_WEC',\n        'a':    'DUK_PROPDESC_FLAGS_NONE|DUK_PROPDESC_FLAG_ACCESSOR',\n        'ea':    'DUK_PROPDESC_FLAGS_E|DUK_PROPDESC_FLAG_ACCESSOR',\n        'ca':    'DUK_PROPDESC_FLAGS_C|DUK_PROPDESC_FLAG_ACCESSOR',\n        'eca':    'DUK_PROPDESC_FLAGS_EC|DUK_PROPDESC_FLAG_ACCESSOR',\n    }\n\n    # Emit property table structs.  These are very complex because\n    # property count *and* individual property type affect the fields\n    # in the initializer, properties can be data properties or accessor\n    # properties or different duk_tval types.  There are also several\n    # property table memory layouts, each with a different ordering of\n    # keys, values, etc.  Union initializers would make things a bit\n    # easier but they're not very portable (being C99).\n    #\n    # The easy solution is to use a separate initializer type for each\n    # property type.  Could also cache and reuse identical initializers\n    # but there'd be very few of them so it's more straightforward to\n    # not reuse the structs.\n    #\n    # NOTE: naming is a bit inconsistent here, duk_tval is used also\n    # to refer to property value initializers like a getter/setter pair.\n\n    genc.emitLine('#if defined(DUK_USE_HOBJECT_LAYOUT_1)')\n    for idx,obj in enumerate(objs):\n        numprops = len(obj['properties'])\n        if numprops == 0:\n            continue\n        tmp = 'typedef struct duk_romprops_%d duk_romprops_%d; ' % (idx, idx)\n        tmp += 'struct duk_romprops_%d { ' % idx\n        for idx,val in enumerate(obj['properties']):\n            tmp += 'const duk_hstring *key%d; ' % idx\n        for idx,val in enumerate(obj['properties']):\n            # XXX: fastint support\n            tmp += '%s val%d; ' % (rom_get_value_initializer_type(meta, val, bi_str_map, bi_obj_map), idx)\n        for idx,val in enumerate(obj['properties']):\n            tmp += 'duk_uint8_t flags%d; ' % idx\n        tmp += '};'\n        genc.emitLine(tmp)\n    genc.emitLine('#elif defined(DUK_USE_HOBJECT_LAYOUT_2)')\n    for idx,obj in enumerate(objs):\n        numprops = len(obj['properties'])\n        if numprops == 0:\n            continue\n        tmp = 'typedef struct duk_romprops_%d duk_romprops_%d; ' % (idx, idx)\n        tmp += 'struct duk_romprops_%d { ' % idx\n        for idx,val in enumerate(obj['properties']):\n            # XXX: fastint support\n            tmp += '%s val%d; ' % (rom_get_value_initializer_type(meta, val, bi_str_map, bi_obj_map), idx)\n        for idx,val in enumerate(obj['properties']):\n            tmp += 'const duk_hstring *key%d; ' % idx\n        for idx,val in enumerate(obj['properties']):\n            tmp += 'duk_uint8_t flags%d; ' % idx\n        # Padding follows for flags, but we don't need to emit it\n        # (at the moment there is never an array or hash part).\n        tmp += '};'\n        genc.emitLine(tmp)\n    genc.emitLine('#elif defined(DUK_USE_HOBJECT_LAYOUT_3)')\n    for idx,obj in enumerate(objs):\n        numprops = len(obj['properties'])\n        if numprops == 0:\n            continue\n        tmp = 'typedef struct duk_romprops_%d duk_romprops_%d; ' % (idx, idx)\n        tmp += 'struct duk_romprops_%d { ' % idx\n        for idx,val in enumerate(obj['properties']):\n            # XXX: fastint support\n            tmp += '%s val%d; ' % (rom_get_value_initializer_type(meta, val, bi_str_map, bi_obj_map), idx)\n        # No array values\n        for idx,val in enumerate(obj['properties']):\n            tmp += 'const duk_hstring *key%d; ' % idx\n        # No hash index\n        for idx,val in enumerate(obj['properties']):\n            tmp += 'duk_uint8_t flags%d; ' % idx\n        tmp += '};'\n        genc.emitLine(tmp)\n    genc.emitLine('#else')\n    genc.emitLine('#error invalid object layout')\n    genc.emitLine('#endif')\n    genc.emitLine('')\n\n    # Forward declare all property tables so that objects can reference them.\n    # Also pointer compress them.\n\n    for idx,obj in enumerate(objs):\n        numprops = len(obj['properties'])\n        if numprops == 0:\n            continue\n\n        # We would like to use DUK_INTERNAL_DECL here, but that maps\n        # to \"static const\" in a single file build which has C++\n        # portability issues: you can't forward declare a static const.\n        # We can't reorder the property tables to avoid this because\n        # there are cyclic references.  So, as the current workaround,\n        # declare as external.\n        genc.emitLine('DUK_EXTERNAL_DECL const duk_romprops_%d duk_prop_%d;' % (idx, idx))\n\n        # Add property tables to ROM compressed pointers too.\n        compress_rom_ptr('&duk_prop_%d' % idx)\n    genc.emitLine('')\n\n    # Forward declare all objects so that objects can reference them,\n    # e.g. internal prototype reference.\n\n    for idx,obj in enumerate(objs):\n        # Careful with C++: must avoid redefining a non-extern const.\n        # See commentary above for duk_prop_%d forward declarations.\n        if obj.get('callable', False):\n            genc.emitLine('DUK_EXTERNAL_DECL const duk_romfun duk_obj_%d;' % idx)\n        elif obj.get('class') == 'Array':\n            genc.emitLine('DUK_EXTERNAL_DECL const duk_romarr duk_obj_%d;' % idx)\n        elif obj.get('class') == 'ObjEnv':\n            genc.emitLine('DUK_EXTERNAL_DECL const duk_romobjenv duk_obj_%d;' % idx)\n        else:\n            genc.emitLine('DUK_EXTERNAL_DECL const duk_romobj duk_obj_%d;' % idx)\n    genc.emitLine('')\n\n    # Define objects, reference property tables.  Objects will be\n    # logically non-extensible so also leave their extensible flag\n    # cleared despite what metadata requests; the runtime code expects\n    # ROM objects to be non-extensible.\n    for idx,obj in enumerate(objs):\n        numprops = len(obj['properties'])\n\n        isfunc = obj.get('callable', False)\n\n        if isfunc:\n            tmp = 'DUK_EXTERNAL const duk_romfun duk_obj_%d = ' % idx\n        elif obj.get('class') == 'Array':\n            tmp = 'DUK_EXTERNAL const duk_romarr duk_obj_%d = ' % idx\n        elif obj.get('class') == 'ObjEnv':\n            tmp = 'DUK_EXTERNAL const duk_romobjenv duk_obj_%d = ' % idx\n        else:\n            tmp = 'DUK_EXTERNAL const duk_romobj duk_obj_%d = ' % idx\n\n        flags = [ 'DUK_HTYPE_OBJECT', 'DUK_HEAPHDR_FLAG_READONLY', 'DUK_HEAPHDR_FLAG_REACHABLE' ]\n        if isfunc:\n            flags.append('DUK_HOBJECT_FLAG_NATFUNC')\n            flags.append('DUK_HOBJECT_FLAG_STRICT')\n            flags.append('DUK_HOBJECT_FLAG_NEWENV')\n        if obj.get('callable', False):\n            flags.append('DUK_HOBJECT_FLAG_CALLABLE')\n        if obj.get('constructable', False):\n            flags.append('DUK_HOBJECT_FLAG_CONSTRUCTABLE')\n        if obj.get('class') == 'Array':\n            flags.append('DUK_HOBJECT_FLAG_EXOTIC_ARRAY')\n        if obj.get('special_call', False):\n            flags.append('DUK_HOBJECT_FLAG_SPECIAL_CALL')\n        flags.append('DUK_HOBJECT_CLASS_AS_FLAGS(%d)' % class_to_number(obj['class']))  # XXX: use constant, not number\n\n        refcount = 1  # refcount is faked to be always 1\n        if numprops == 0:\n            props = 'NULL'\n        else:\n            props = '&duk_prop_%d' % idx\n        props_enc16 = compress_rom_ptr(props)\n\n        if obj.has_key('internal_prototype'):\n            iproto = '&%s' % bi_obj_map[obj['internal_prototype']]\n        else:\n            iproto = 'NULL'\n        iproto_enc16 = compress_rom_ptr(iproto)\n\n        e_size = numprops\n        e_next = e_size\n        a_size = 0  # never an array part for now\n        h_size = 0  # never a hash for now; not appropriate for perf relevant builds\n\n        if isfunc:\n            nativefunc = obj['native']\n            if obj.get('varargs', False):\n                nargs = 'DUK_VARARGS'\n            elif obj.has_key('nargs'):\n                nargs = '%d' % obj['nargs']\n            else:\n                assert(False)  # 'nargs' should be defaulted from 'length' at metadata load\n            magic = '%d' % resolve_magic(obj.get('magic', None), id_to_bidx)\n        else:\n            nativefunc = 'dummy'\n            nargs = '0'\n            magic = '0'\n\n        assert(a_size == 0)\n        assert(h_size == 0)\n        if isfunc:\n            tmp += 'DUK__ROMFUN_INIT(%s,%d,%s,%d,%s,%d,%d,%d,%d,%d,%s,%s,%s);' % \\\n                ('|'.join(flags), refcount, props, props_enc16, \\\n                 iproto, iproto_enc16, e_size, e_next, a_size, h_size, \\\n                 nativefunc, nargs, magic)\n        elif obj.get('class') == 'Array':\n            arrlen = 0\n            tmp += 'DUK__ROMARR_INIT(%s,%d,%s,%d,%s,%d,%d,%d,%d,%d,%d);' % \\\n                ('|'.join(flags), refcount, props, props_enc16, \\\n                 iproto, iproto_enc16, e_size, e_next, a_size, h_size, arrlen)\n        elif obj.get('class') == 'ObjEnv':\n            objenv_target = '&%s' % bi_obj_map[obj['objenv_target']]\n            objenv_has_this = obj['objenv_has_this']\n            tmp += 'DUK__ROMOBJENV_INIT(%s,%d,%s,%d,%s,%d,%d,%d,%d,%d,%s,%d);' % \\\n                ('|'.join(flags), refcount, props, props_enc16, \\\n                 iproto, iproto_enc16, e_size, e_next, a_size, h_size, objenv_target, objenv_has_this)\n        else:\n            tmp += 'DUK__ROMOBJ_INIT(%s,%d,%s,%d,%s,%d,%d,%d,%d,%d);' % \\\n                ('|'.join(flags), refcount, props, props_enc16, \\\n                 iproto, iproto_enc16, e_size, e_next, a_size, h_size)\n\n        genc.emitLine(tmp)\n\n    # Property tables.  Can reference arbitrary strings and objects as\n    # they're defined before them.\n\n    # Properties will be non-configurable, but must be writable so that\n    # standard property semantics allow shadowing properties to be\n    # established in inherited objects (e.g. \"var obj={}; obj.toString\n    # = myToString\").  Enumerable can also be kept.\n\n    def _prepAttrs(val):\n        attrs = val['attributes']\n        assert('c' not in attrs)\n        return attr_lookup[attrs]\n\n    def _emitPropTableInitializer(idx, obj, layout):\n        init_vals = []\n        init_keys = []\n        init_flags = []\n\n        numprops = len(obj['properties'])\n        for val in obj['properties']:\n            init_keys.append('(const duk_hstring *)&%s' % bi_str_map[val['key']])\n        for val in obj['properties']:\n            # XXX: fastint support\n            init_vals.append('%s' % rom_get_value_initializer_literal(meta, val, bi_str_map, bi_obj_map))\n        for val in obj['properties']:\n            init_flags.append('%s' % _prepAttrs(val))\n\n        if layout == 1:\n            initlist = init_keys + init_vals + init_flags\n        elif layout == 2:\n            initlist = init_vals + init_keys + init_flags\n        elif layout == 3:\n            # Same as layout 2 now, no hash/array\n            initlist = init_vals + init_keys + init_flags\n\n        if len(initlist) > 0:\n            genc.emitLine('DUK_EXTERNAL const duk_romprops_%d duk_prop_%d = {%s};' % (idx, idx, ','.join(initlist)))\n\n    genc.emitLine('#if defined(DUK_USE_HOBJECT_LAYOUT_1)')\n    for idx,obj in enumerate(objs):\n        _emitPropTableInitializer(idx, obj, 1)\n    genc.emitLine('#elif defined(DUK_USE_HOBJECT_LAYOUT_2)')\n    for idx,obj in enumerate(objs):\n        _emitPropTableInitializer(idx, obj, 2)\n    genc.emitLine('#elif defined(DUK_USE_HOBJECT_LAYOUT_3)')\n    for idx,obj in enumerate(objs):\n        _emitPropTableInitializer(idx, obj, 3)\n    genc.emitLine('#else')\n    genc.emitLine('#error invalid object layout')\n    genc.emitLine('#endif')\n    genc.emitLine('')\n\n    # Emit a list of ROM builtins (those objects needing a bidx).\n    #\n    # cdecl > explain const int * const foo;\n    # declare foo as const pointer to const int\n\n    count_bidx = 0\n    for bi in objs:\n        if bi.get('bidx_used', False):\n            count_bidx += 1\n    genc.emitLine('DUK_INTERNAL const duk_hobject * const duk_rom_builtins_bidx[%d] = {' % count_bidx)\n    for bi in objs:\n        if not bi.get('bidx_used', False):\n            continue  # for this we want the toplevel objects only\n        genc.emitLine('\\t(const duk_hobject *) &%s,' % bi_obj_map[bi['id']])\n    genc.emitLine('};')\n\n    # Emit a table of compressed ROM pointers.  We must be able to\n    # compress ROM pointers at compile time so we assign running\n    # indices to them.  User pointer compression macros must use this\n    # array to encode/decode ROM pointers.\n\n    genc.emitLine('')\n    genc.emitLine('#if defined(DUK_USE_ROM_OBJECTS) && defined(DUK_USE_HEAPPTR16)')\n    genc.emitLine('DUK_EXTERNAL const void * const duk_rom_compressed_pointers[%d] = {' % (len(romptr_compress_list) + 1))\n    for idx,ptr in enumerate(romptr_compress_list):\n        genc.emitLine('\\t(const void *) %s,  /* 0x%04x */' % (ptr, ROMPTR_FIRST + idx))\n    romptr_highest = ROMPTR_FIRST + len(romptr_compress_list) - 1\n    genc.emitLine('\\tNULL')  # for convenience\n    genc.emitLine('};')\n    genc.emitLine('#endif')\n\n    logger.debug('%d compressed rom pointers (used range is [0x%04x,0x%04x], %d space left)' % \\\n                 (len(romptr_compress_list), ROMPTR_FIRST, romptr_highest, 0xffff - romptr_highest))\n\n    # Undefine helpers.\n    genc.emitLine('')\n    for i in [\n        'DUK__STRHASH16',\n        'DUK__STRHASH32',\n        'DUK__DBLBYTES',\n        'DUK__TVAL_NUMBER',\n        'DUK__TVAL_UNDEFINED',\n        'DUK__TVAL_NULL',\n        'DUK__TVAL_BOOLEAN',\n        'DUK__TVAL_OBJECT',\n        'DUK__TVAL_STRING',\n        'DUK__STRINIT',\n        'DUK__ROMOBJ_INIT',\n        'DUK__ROMFUN_INIT'\n    ]:\n        genc.emitLine('#undef ' + i)\n\n    return romptr_compress_list\n\n# Emit ROM objects header.\ndef rom_emit_objects_header(genc, meta):\n    bidx = 0\n    for bi in meta['objects']:\n        if not bi.get('bidx_used', False):\n            continue  # for this we want the toplevel objects only\n        genc.emitDefine('DUK_BIDX_' + '_'.join(bi['id'].upper().split('_')[1:]), bidx)  # bi_foo_bar -> FOO_BAR\n        bidx += 1\n    count_bidx = bidx\n    genc.emitDefine('DUK_NUM_BUILTINS', count_bidx)\n    genc.emitDefine('DUK_NUM_BIDX_BUILTINS', count_bidx)\n    genc.emitDefine('DUK_NUM_ALL_BUILTINS', len(meta['objects']))\n    genc.emitLine('')\n    genc.emitLine('#if !defined(DUK_SINGLE_FILE)')  # C++ static const workaround\n    genc.emitLine('DUK_INTERNAL_DECL const duk_hobject * const duk_rom_builtins_bidx[%d];' % count_bidx)\n    genc.emitLine('#endif')\n\n    # XXX: missing declarations here, not an issue for single source build.\n    # Add missing declarations.\n    # XXX: For example, 'DUK_EXTERNAL_DECL ... duk_rom_compressed_pointers[]' is missing.\n\n#\n#  Shared for both RAM and ROM\n#\n\ndef emit_header_native_function_declarations(genc, meta):\n    emitted = {}  # To suppress duplicates\n    funclist = []\n    def _emit(fname):\n        if not emitted.has_key(fname):\n            emitted[fname] = True\n            funclist.append(fname)\n\n    for o in meta['objects']:\n        if o.has_key('native'):\n            _emit(o['native'])\n\n        for p in o['properties']:\n            v = p['value']\n            if isinstance(v, dict) and v['type'] == 'lightfunc':\n                assert(v.has_key('native'))\n                _emit(v['native'])\n                logger.debug('Lightfunc function declaration: %r' % v['native'])\n\n    for fname in funclist:\n        # Visibility depends on whether the function is Duktape internal or user.\n        # Use a simple prefix for now.\n        if fname[:4] == 'duk_':\n            genc.emitLine('DUK_INTERNAL_DECL duk_ret_t %s(duk_context *ctx);' % fname)\n        else:\n            genc.emitLine('extern duk_ret_t %s(duk_context *ctx);' % fname)\n\n#\n#  Main\n#\n\ndef main():\n    parser = optparse.OptionParser()\n    parser.add_option('--git-commit', dest='git_commit', default=None, help='Git commit hash')\n    parser.add_option('--git-describe', dest='git_describe', default=None, help='Git describe')\n    parser.add_option('--git-branch', dest='git_branch', default=None, help='Git branch name')\n    parser.add_option('--duk-version', dest='duk_version', default=None, help='Duktape version (e.g. 10203)')\n    parser.add_option('--quiet', dest='quiet', action='store_true', default=False, help='Suppress info messages (show warnings)')\n    parser.add_option('--verbose', dest='verbose', action='store_true', default=False, help='Show verbose debug messages')\n    parser.add_option('--used-stridx-metadata', dest='used_stridx_metadata', help='DUK_STRIDX_xxx used by source/headers, JSON format')\n    parser.add_option('--strings-metadata', dest='strings_metadata', help='Default built-in strings metadata file, YAML format')\n    parser.add_option('--objects-metadata', dest='objects_metadata', help='Default built-in objects metadata file, YAML format')\n    parser.add_option('--active-options', dest='active_options', help='Active config options from genconfig.py, JSON format')\n    parser.add_option('--user-builtin-metadata', dest='obsolete_builtin_metadata', default=None, help=optparse.SUPPRESS_HELP)\n    parser.add_option('--builtin-file', dest='builtin_files', metavar='FILENAME', action='append', default=[], help='Built-in string/object YAML metadata to be applied over default built-ins (multiple files may be given, applied in sequence)')\n    parser.add_option('--ram-support', dest='ram_support', action='store_true', default=False, help='Support RAM strings/objects')\n    parser.add_option('--rom-support', dest='rom_support', action='store_true', default=False, help='Support ROM strings/objects (increases output size considerably)')\n    parser.add_option('--rom-auto-lightfunc', dest='rom_auto_lightfunc', action='store_true', default=False, help='Convert ROM built-in function properties into lightfuncs automatically whenever possible')\n    parser.add_option('--out-header', dest='out_header', help='Output header file')\n    parser.add_option('--out-source', dest='out_source', help='Output source file')\n    parser.add_option('--out-metadata-json', dest='out_metadata_json', help='Output metadata file')\n    parser.add_option('--dev-dump-final-ram-metadata', dest='dev_dump_final_ram_metadata', help='Development option')\n    parser.add_option('--dev-dump-final-rom-metadata', dest='dev_dump_final_rom_metadata', help='Development option')\n    (opts, args) = parser.parse_args()\n\n    if opts.obsolete_builtin_metadata is not None:\n        raise Exception('--user-builtin-metadata has been removed, use --builtin-file instead')\n\n    # Log level.\n    if opts.quiet:\n        logger.setLevel(logging.WARNING)\n    elif opts.verbose:\n        logger.setLevel(logging.DEBUG)\n\n    # Options processing.\n\n    build_info = {\n        'git_commit': opts.git_commit,\n        'git_branch': opts.git_branch,\n        'git_describe': opts.git_describe,\n        'duk_version': int(opts.duk_version),\n    }\n\n    desc = []\n    if opts.ram_support:\n        desc += [ 'ram built-in support' ]\n    if opts.rom_support:\n        desc += [ 'rom built-in support' ]\n    if opts.rom_auto_lightfunc:\n        desc += [ 'rom auto lightfunc' ]\n    logger.info('Creating built-in initialization data: ' + ', '.join(desc))\n\n    # Read in metadata files, normalizing and merging as necessary.\n\n    active_opts = {}\n    if opts.active_options is not None:\n        with open(opts.active_options, 'rb') as f:\n            active_opts = json.loads(f.read())\n\n    ram_meta = load_metadata(opts, rom=False, build_info=build_info, active_opts=active_opts)\n    rom_meta = load_metadata(opts, rom=True, build_info=build_info, active_opts=active_opts)\n    if opts.dev_dump_final_ram_metadata is not None:\n        dump_metadata(ram_meta, opts.dev_dump_final_ram_metadata)\n    if opts.dev_dump_final_rom_metadata is not None:\n        dump_metadata(rom_meta, opts.dev_dump_final_rom_metadata)\n\n    # Create RAM init data bitstreams.\n\n    ramstr_data, ramstr_maxlen = gen_ramstr_initdata_bitpacked(ram_meta)\n    ram_native_funcs, ram_natfunc_name_to_natidx = get_ramobj_native_func_maps(ram_meta)\n\n    if opts.ram_support:\n        ramobj_data_le = gen_ramobj_initdata_bitpacked(ram_meta, ram_native_funcs, ram_natfunc_name_to_natidx, 'little')\n        ramobj_data_be = gen_ramobj_initdata_bitpacked(ram_meta, ram_native_funcs, ram_natfunc_name_to_natidx, 'big')\n        ramobj_data_me = gen_ramobj_initdata_bitpacked(ram_meta, ram_native_funcs, ram_natfunc_name_to_natidx, 'mixed')\n\n    # Write source and header files.\n\n    gc_src = dukutil.GenerateC()\n    gc_src.emitHeader('genbuiltins.py')\n    gc_src.emitLine('#include \"duk_internal.h\"')\n    gc_src.emitLine('')\n    gc_src.emitLine('#if defined(DUK_USE_ASSERTIONS)')\n    gc_src.emitLine('#define DUK__REFCINIT(refc) 0 /*h_assert_refcount*/, (refc) /*actual*/')\n    gc_src.emitLine('#else')\n    gc_src.emitLine('#define DUK__REFCINIT(refc) (refc) /*actual*/')\n    gc_src.emitLine('#endif')\n    gc_src.emitLine('')\n    gc_src.emitLine('#if defined(DUK_USE_ROM_STRINGS)')\n    if opts.rom_support:\n        rom_bi_str_map = rom_emit_strings_source(gc_src, rom_meta)\n        rom_emit_object_initializer_types_and_macros(gc_src)\n        rom_emit_objects(gc_src, rom_meta, rom_bi_str_map)\n    else:\n        gc_src.emitLine('#error ROM support not enabled, rerun configure.py with --rom-support')\n    gc_src.emitLine('#else  /* DUK_USE_ROM_STRINGS */')\n    emit_ramstr_source_strinit_data(gc_src, ramstr_data)\n    gc_src.emitLine('#endif  /* DUK_USE_ROM_STRINGS */')\n    gc_src.emitLine('')\n    gc_src.emitLine('#if defined(DUK_USE_ROM_OBJECTS)')\n    if opts.rom_support:\n        gc_src.emitLine('#if !defined(DUK_USE_ROM_STRINGS)')\n        gc_src.emitLine('#error DUK_USE_ROM_OBJECTS requires DUK_USE_ROM_STRINGS')\n        gc_src.emitLine('#endif')\n        gc_src.emitLine('#if defined(DUK_USE_HSTRING_ARRIDX)')\n        gc_src.emitLine('#error DUK_USE_HSTRING_ARRIDX is currently incompatible with ROM built-ins')\n        gc_src.emitLine('#endif')\n    else:\n        gc_src.emitLine('#error ROM support not enabled, rerun configure.py with --rom-support')\n    gc_src.emitLine('#else  /* DUK_USE_ROM_OBJECTS */')\n    if opts.ram_support:\n        emit_ramobj_source_nativefunc_array(gc_src, ram_native_funcs)  # endian independent\n        gc_src.emitLine('#if defined(DUK_USE_DOUBLE_LE)')\n        emit_ramobj_source_objinit_data(gc_src, ramobj_data_le)\n        gc_src.emitLine('#elif defined(DUK_USE_DOUBLE_BE)')\n        emit_ramobj_source_objinit_data(gc_src, ramobj_data_be)\n        gc_src.emitLine('#elif defined(DUK_USE_DOUBLE_ME)')\n        emit_ramobj_source_objinit_data(gc_src, ramobj_data_me)\n        gc_src.emitLine('#else')\n        gc_src.emitLine('#error invalid endianness defines')\n        gc_src.emitLine('#endif')\n    else:\n        gc_src.emitLine('#error RAM support not enabled, rerun configure.py with --ram-support')\n    gc_src.emitLine('#endif  /* DUK_USE_ROM_OBJECTS */')\n\n    gc_hdr = dukutil.GenerateC()\n    gc_hdr.emitHeader('genbuiltins.py')\n    gc_hdr.emitLine('#if !defined(DUK_BUILTINS_H_INCLUDED)')\n    gc_hdr.emitLine('#define DUK_BUILTINS_H_INCLUDED')\n    gc_hdr.emitLine('')\n    gc_hdr.emitLine('#if defined(DUK_USE_ROM_STRINGS)')\n    if opts.rom_support:\n        emit_header_stridx_defines(gc_hdr, rom_meta)\n        rom_emit_strings_header(gc_hdr, rom_meta)\n    else:\n        gc_hdr.emitLine('#error ROM support not enabled, rerun configure.py with --rom-support')\n    gc_hdr.emitLine('#else  /* DUK_USE_ROM_STRINGS */')\n    if opts.ram_support:\n        emit_header_stridx_defines(gc_hdr, ram_meta)\n        emit_ramstr_header_strinit_defines(gc_hdr, ram_meta, ramstr_data, ramstr_maxlen)\n    else:\n        gc_hdr.emitLine('#error RAM support not enabled, rerun configure.py with --ram-support')\n    gc_hdr.emitLine('#endif  /* DUK_USE_ROM_STRINGS */')\n    gc_hdr.emitLine('')\n    gc_hdr.emitLine('#if defined(DUK_USE_ROM_OBJECTS)')\n    if opts.rom_support:\n        # Currently DUK_USE_ROM_PTRCOMP_FIRST must match our fixed\n        # define, and the two must be updated in sync.  Catch any\n        # mismatch to avoid difficult to diagnose errors.\n        gc_hdr.emitLine('#if !defined(DUK_USE_ROM_PTRCOMP_FIRST)')\n        gc_hdr.emitLine('#error missing DUK_USE_ROM_PTRCOMP_FIRST define')\n        gc_hdr.emitLine('#endif')\n        gc_hdr.emitLine('#if (DUK_USE_ROM_PTRCOMP_FIRST != %dL)' % ROMPTR_FIRST)\n        gc_hdr.emitLine('#error DUK_USE_ROM_PTRCOMP_FIRST must match ROMPTR_FIRST in genbuiltins.py (%d), update manually and re-dist' % ROMPTR_FIRST)\n        gc_hdr.emitLine('#endif')\n        emit_header_native_function_declarations(gc_hdr, rom_meta)\n        rom_emit_objects_header(gc_hdr, rom_meta)\n    else:\n        gc_hdr.emitLine('#error RAM support not enabled, rerun configure.py with --ram-support')\n    gc_hdr.emitLine('#else  /* DUK_USE_ROM_OBJECTS */')\n    if opts.ram_support:\n        emit_header_native_function_declarations(gc_hdr, ram_meta)\n        emit_ramobj_header_nativefunc_array(gc_hdr, ram_native_funcs)\n        emit_ramobj_header_objects(gc_hdr, ram_meta)\n        gc_hdr.emitLine('#if defined(DUK_USE_DOUBLE_LE)')\n        emit_ramobj_header_initdata(gc_hdr, ramobj_data_le)\n        gc_hdr.emitLine('#elif defined(DUK_USE_DOUBLE_BE)')\n        emit_ramobj_header_initdata(gc_hdr, ramobj_data_be)\n        gc_hdr.emitLine('#elif defined(DUK_USE_DOUBLE_ME)')\n        emit_ramobj_header_initdata(gc_hdr, ramobj_data_me)\n        gc_hdr.emitLine('#else')\n        gc_hdr.emitLine('#error invalid endianness defines')\n        gc_hdr.emitLine('#endif')\n    else:\n        gc_hdr.emitLine('#error RAM support not enabled, rerun configure.py with --ram-support')\n    gc_hdr.emitLine('#endif  /* DUK_USE_ROM_OBJECTS */')\n    gc_hdr.emitLine('#endif  /* DUK_BUILTINS_H_INCLUDED */')\n\n    with open(opts.out_source, 'wb') as f:\n        f.write(gc_src.getString())\n    logger.debug('Wrote built-ins source to ' + opts.out_source)\n\n    with open(opts.out_header, 'wb') as f:\n        f.write(gc_hdr.getString())\n    logger.debug('Wrote built-ins header to ' + opts.out_header)\n\n    # Write a JSON file with build metadata, e.g. built-in strings.\n\n    ver = long(build_info['duk_version'])\n    plain_strs = []\n    base64_strs = []\n    str_objs = []\n    for s in ram_meta['strings_stridx']:  # XXX: provide all lists?\n        t1 = bytes_to_unicode(s['str'])\n        t2 = unicode_to_bytes(s['str']).encode('base64').strip()\n        plain_strs.append(t1)\n        base64_strs.append(t2)\n        str_objs.append({\n            'plain': t1, 'base64': t2, 'define': s['define']\n        })\n    meta = {\n        'comment': 'Metadata for Duktape sources',\n        'duk_version': ver,\n        'duk_version_string': '%d.%d.%d' % (ver / 10000, (ver / 100) % 100, ver % 100),\n        'git_commit': build_info['git_commit'],\n        'git_branch': build_info['git_branch'],\n        'git_describe': build_info['git_describe'],\n        'builtin_strings': plain_strs,\n        'builtin_strings_base64': base64_strs,\n        'builtin_strings_info': str_objs\n    }\n\n    with open(opts.out_metadata_json, 'wb') as f:\n        f.write(json.dumps(meta, indent=4, sort_keys=True, ensure_ascii=True))\n    logger.debug('Wrote built-ins metadata to ' + opts.out_metadata_json)\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/tools/genconfig.py",
    "content": "#!/usr/bin/env python2\n#\n#  Process Duktape option metadata and produce various useful outputs:\n#\n#    - duk_config.h with specific or autodetected platform, compiler, and\n#      architecture, forced options, sanity checks, etc\n#    - option documentation for Duktape config options (DUK_USE_xxx)\n#\n#  Genconfig tries to build all outputs based on modular metadata, so that\n#  managing a large number of config options (which is hard to avoid given\n#  the wide range of targets Duktape supports) remains maintainable.\n#\n#  Genconfig does *not* try to support all exotic platforms out there.\n#  Instead, the goal is to allow the metadata to be extended, or to provide\n#  a reasonable starting point for manual duk_config.h tweaking.\n#\n\nimport logging\nimport sys\nlogging.basicConfig(level=logging.INFO, stream=sys.stdout, format='%(name)-21s %(levelname)-7s %(message)s')\nlogger = logging.getLogger('genconfig.py')\nlogger.setLevel(logging.INFO)\n\nimport os\nimport re\nimport json\nimport yaml\nimport optparse\nimport tarfile\nimport tempfile\nimport atexit\nimport shutil\nimport logging\ntry:\n    from StringIO import StringIO\nexcept ImportError:\n    from io import StringIO\n\n#\n#  Globals holding scanned metadata, helper snippets, etc\n#\n\n# Metadata to scan from config files.\nuse_defs = None\nuse_defs_list = None\nopt_defs = None\nopt_defs_list = None\nuse_tags = None\nuse_tags_list = None\ntags_meta = None\nrequired_use_meta_keys = [\n    'define',\n    'introduced',\n    'default',\n    'tags',\n    'description'\n]\nallowed_use_meta_keys = [\n    'define',\n    'introduced',\n    'deprecated',\n    'removed',\n    'unused',\n    'requires',\n    'conflicts',\n    'related',\n    'default',\n    'tags',\n    'description',\n    'warn_if_missing'\n]\nrequired_opt_meta_keys = [\n    'define',\n    'introduced',\n    'tags',\n    'description'\n]\nallowed_opt_meta_keys = [\n    'define',\n    'introduced',\n    'deprecated',\n    'removed',\n    'unused',\n    'requires',\n    'conflicts',\n    'related',\n    'tags',\n    'description'\n]\n\n# Preferred tag order for option documentation.\ndoc_tag_order = [\n    'portability',\n    'memory',\n    'lowmemory',\n    'ecmascript',\n    'execution',\n    'debugger',\n    'debug',\n    'development'\n]\n\n# Preferred tag order for generated C header files.\nheader_tag_order = doc_tag_order\n\n# Helper headers snippets.\nhelper_snippets = None\n\n# Assume these provides come from outside.\nassumed_provides = {\n    'DUK_SINGLE_FILE': True,         # compiling Duktape from a single source file (duktape.c) version\n    'DUK_COMPILING_DUKTAPE': True,   # compiling Duktape (not user application)\n    'DUK_CONFIG_H_INCLUDED': True,   # artifact, include guard\n}\n\n# Platform files must provide at least these (additional checks\n# in validate_platform_file()).  Fill-ins provide missing optionals.\nplatform_required_provides = [\n    'DUK_USE_OS_STRING'  # must be #define'd\n]\n\n# Architecture files must provide at least these (additional checks\n# in validate_architecture_file()).  Fill-ins provide missing optionals.\narchitecture_required_provides = [\n    'DUK_USE_ARCH_STRING'\n]\n\n# Compiler files must provide at least these (additional checks\n# in validate_compiler_file()).  Fill-ins provide missing optionals.\ncompiler_required_provides = [\n    # Compilers need a lot of defines; missing defines are automatically\n    # filled in with defaults (which are mostly compiler independent), so\n    # the requires define list is not very large.\n\n    'DUK_USE_COMPILER_STRING',    # must be #define'd\n    'DUK_USE_BRANCH_HINTS',       # may be #undef'd, as long as provided\n    'DUK_USE_VARIADIC_MACROS',    # may be #undef'd, as long as provided\n    'DUK_USE_UNION_INITIALIZERS'  # may be #undef'd, as long as provided\n]\n\n#\n#  Miscellaneous helpers\n#\n\ndef get_auto_delete_tempdir():\n    tmpdir = tempfile.mkdtemp(suffix='-genconfig')\n    def _f(dirname):\n        logger.debug('Deleting temporary directory: %r' % dirname)\n        if os.path.isdir(dirname) and '-genconfig' in dirname:\n            shutil.rmtree(dirname)\n    atexit.register(_f, tmpdir)\n    return tmpdir\n\ndef strip_comments_from_lines(lines):\n    # Not exact but close enough.  Doesn't handle string literals etc,\n    # but these are not a concrete issue for scanning preprocessor\n    # #define references.\n    #\n    # Comment contents are stripped of any DUK_ prefixed text to avoid\n    # incorrect requires/provides detection.  Other comment text is kept;\n    # in particular a \"/* redefine */\" comment must remain intact here.\n    # (The 'redefine' hack is not actively needed now.)\n    #\n    # Avoid Python 2.6 vs. Python 2.7 argument differences.\n\n    def censor(x):\n        return re.sub(re.compile('DUK_\\w+', re.MULTILINE), 'xxx', x.group(0))\n\n    tmp = '\\n'.join(lines)\n    tmp = re.sub(re.compile('/\\*.*?\\*/', re.MULTILINE | re.DOTALL), censor, tmp)\n    tmp = re.sub(re.compile('//.*?$', re.MULTILINE), censor, tmp)\n    return tmp.split('\\n')\n\n# Header snippet representation: lines, provides defines, requires defines.\nre_line_provides = re.compile(r'^#(?:define|undef)\\s+(\\w+).*$')\nre_line_requires = re.compile(r'(DUK_[A-Z0-9_]+)')  # uppercase only, don't match DUK_USE_xxx for example\nclass Snippet:\n    lines = None     # lines of text and/or snippets\n    provides = None  # map from define to 'True' for now\n    requires = None  # map from define to 'True' for now\n\n    def __init__(self, lines, provides=None, requires=None, autoscan_requires=True, autoscan_provides=True):\n        self.lines = []\n        if not isinstance(lines, list):\n            raise Exception('Snippet constructor must be a list (not e.g. a string): %s' % repr(lines))\n        for line in lines:\n            if isinstance(line, str):\n                self.lines.append(line)\n            elif isinstance(line, unicode):\n                self.lines.append(line.encode('utf-8'))\n            else:\n                raise Exception('invalid line: %r' % line)\n        self.provides = {}\n        if provides is not None:\n            for k in provides.keys():\n                self.provides[k] = True\n        self.requires = {}\n        if requires is not None:\n            for k in requires.keys():\n                self.requires[k] = True\n\n        stripped_lines = strip_comments_from_lines(lines)\n        #for line in stripped_lines:\n        #    logger.debug(line)\n\n        for line in stripped_lines:\n            # Careful with order, snippet may self-reference its own\n            # defines in which case there's no outward dependency.\n            # (This is not 100% because the order of require/provide\n            # matters and this is not handled now.)\n            #\n            # Also, some snippets may #undef/#define another define but\n            # they don't \"provide\" the define as such.  Such redefinitions\n            # are marked \"/* redefine */\" in the snippets.  They're best\n            # avoided (and not currently needed in Duktape 1.4.0).\n\n            if autoscan_provides:\n                m = re_line_provides.match(line)\n                if m is not None and '/* redefine */' not in line and \\\n                    len(m.group(1)) > 0 and m.group(1)[-1] != '_':\n                    # Don't allow e.g. DUK_USE_ which results from matching DUK_USE_xxx\n                    #logger.debug('PROVIDES: %r' % m.group(1))\n                    self.provides[m.group(1)] = True\n            if autoscan_requires:\n                matches = re.findall(re_line_requires, line)\n                for m in matches:\n                    if len(m) > 0 and m[-1] == '_':\n                        # Don't allow e.g. DUK_USE_ which results from matching DUK_USE_xxx\n                        pass\n                    elif m[:7] == 'DUK_OPT':\n                        #logger.warning('Encountered DUK_OPT_xxx in a header snippet: %s' % repr(line))\n                        # DUK_OPT_xxx always come from outside\n                        pass\n                    elif m[:7] == 'DUK_USE':\n                        # DUK_USE_xxx are internal and they should not be 'requirements'\n                        pass\n                    elif self.provides.has_key(m):\n                        # Snippet provides it's own require; omit\n                        pass\n                    else:\n                        #logger.debug('REQUIRES: %r' % m)\n                        self.requires[m] = True\n\n    def fromFile(cls, filename):\n        lines = []\n        with open(filename, 'rb') as f:\n            for line in f:\n                if line[-1] == '\\n':\n                    line = line[:-1]\n                if line[:8] == '#snippet':\n                    m = re.match(r'#snippet\\s+\"(.*?)\"', line)\n                    # XXX: better plumbing for lookup path\n                    sub_fn = os.path.normpath(os.path.join(filename, '..', '..', 'header-snippets', m.group(1)))\n                    logger.debug('#snippet ' + sub_fn)\n                    sn = Snippet.fromFile(sub_fn)\n                    lines += sn.lines\n                else:\n                    lines.append(line)\n        return Snippet(lines, autoscan_requires=True, autoscan_provides=True)\n    fromFile = classmethod(fromFile)\n\n    def merge(cls, snippets):\n        ret = Snippet([], [], [])\n        for s in snippets:\n            ret.lines += s.lines\n            for k in s.provides.keys():\n                ret.provides[k] = True\n            for k in s.requires.keys():\n                ret.requires[k] = True\n        return ret\n    merge = classmethod(merge)\n\n# Helper for building a text file from individual lines, injected files, etc.\n# Inserted values are converted to Snippets so that their provides/requires\n# information can be tracked.  When non-C outputs are created, these will be\n# bogus but ignored.\nclass FileBuilder:\n    vals = None  # snippet list\n    base_dir = None\n    use_cpp_warning = False\n\n    def __init__(self, base_dir=None, use_cpp_warning=False):\n        self.vals = []\n        self.base_dir = base_dir\n        self.use_cpp_warning = use_cpp_warning\n\n    def line(self, line):\n        self.vals.append(Snippet([ line ]))\n\n    def lines(self, lines):\n        if len(lines) > 0 and lines[-1] == '\\n':\n            lines = lines[:-1]  # strip last newline to avoid empty line\n        self.vals.append(Snippet(lines.split('\\n')))\n\n    def empty(self):\n        self.vals.append(Snippet([ '' ]))\n\n    def rst_heading(self, title, char, doubled=False):\n        tmp = []\n        if doubled:\n            tmp.append(char * len(title))\n        tmp.append(title)\n        tmp.append(char * len(title))\n        self.vals.append(Snippet(tmp))\n\n    def snippet_relative(self, fn):\n        sn = Snippet.fromFile(os.path.join(self.base_dir, fn))\n        self.vals.append(sn)\n        return sn\n\n    def snippet_absolute(self, fn):\n        sn = Snippet.fromFile(fn)\n        self.vals.append(sn)\n        return sn\n\n    def cpp_error(self, msg):\n        # XXX: assume no newlines etc\n        self.vals.append(Snippet([ '#error %s' % msg ]))\n\n    def cpp_warning(self, msg):\n        # XXX: assume no newlines etc\n        # XXX: support compiler specific warning mechanisms\n        if self.use_cpp_warning:\n            # C preprocessor '#warning' is often supported\n            self.vals.append(Snippet([ '#warning %s' % msg ]))\n        else:\n            self.vals.append(Snippet([ '/* WARNING: %s */' % msg ]))\n\n    def cpp_warning_or_error(self, msg, is_error=True):\n        if is_error:\n            self.cpp_error(msg)\n        else:\n            self.cpp_warning(msg)\n\n    def chdr_comment_line(self, msg):\n        self.vals.append(Snippet([ '/* %s */' % msg ]))\n\n    def chdr_block_heading(self, msg):\n        lines = []\n        lines.append('')\n        lines.append('/*')\n        lines.append(' *  ' + msg)\n        lines.append(' */')\n        lines.append('')\n        self.vals.append(Snippet(lines))\n\n    def join(self):\n        tmp = []\n        for line in self.vals:\n            if not isinstance(line, object):\n                raise Exception('self.vals must be all snippets')\n            for x in line.lines:  # x is a Snippet\n                tmp.append(x)\n        return '\\n'.join(tmp)\n\n    def fill_dependencies_for_snippets(self, idx_deps):\n        fill_dependencies_for_snippets(self.vals, idx_deps)\n\n# Insert missing define dependencies into index 'idx_deps' repeatedly\n# until no unsatisfied dependencies exist.  This is used to pull in\n# the required DUK_F_xxx helper defines without pulling them all in.\n# The resolution mechanism also ensures dependencies are pulled in the\n# correct order, i.e. DUK_F_xxx helpers may depend on each other (as\n# long as there are no circular dependencies).\n#\n# XXX: this can be simplified a lot\ndef fill_dependencies_for_snippets(snippets, idx_deps):\n    # graph[A] = [ B, ... ] <-> B, ... provide something A requires.\n    graph = {}\n    snlist = []\n    resolved = []   # for printing only\n\n    def add(sn):\n        if sn in snlist:\n            return  # already present\n        snlist.append(sn)\n\n        to_add = []\n\n        for k in sn.requires.keys():\n            if assumed_provides.has_key(k):\n                continue\n\n            found = False\n            for sn2 in snlist:\n                if sn2.provides.has_key(k):\n                    if not graph.has_key(sn):\n                        graph[sn] = []\n                    graph[sn].append(sn2)\n                    found = True  # at least one other node provides 'k'\n\n            if not found:\n                logger.debug('Resolving %r' % k)\n                resolved.append(k)\n\n                # Find a header snippet which provides the missing define.\n                # Some DUK_F_xxx files provide multiple defines, so we don't\n                # necessarily know the snippet filename here.\n\n                sn_req = None\n                for sn2 in helper_snippets:\n                    if sn2.provides.has_key(k):\n                        sn_req = sn2\n                        break\n                if sn_req is None:\n                    logger.debug(repr(sn.lines))\n                    raise Exception('cannot resolve missing require: %r' % k)\n\n                # Snippet may have further unresolved provides; add recursively\n                to_add.append(sn_req)\n\n                if not graph.has_key(sn):\n                    graph[sn] = []\n                graph[sn].append(sn_req)\n\n        for sn in to_add:\n            add(sn)\n\n    # Add original snippets.  This fills in the required nodes\n    # recursively.\n    for sn in snippets:\n        add(sn)\n\n    # Figure out fill-ins by looking for snippets not in original\n    # list and without any unserialized dependent nodes.\n    handled = {}\n    for sn in snippets:\n        handled[sn] = True\n    keepgoing = True\n    while keepgoing:\n        keepgoing = False\n        for sn in snlist:\n            if handled.has_key(sn):\n                continue\n\n            success = True\n            for dep in graph.get(sn, []):\n                if not handled.has_key(dep):\n                    success = False\n            if success:\n                snippets.insert(idx_deps, sn)\n                idx_deps += 1\n                snippets.insert(idx_deps, Snippet([ '' ]))\n                idx_deps += 1\n                handled[sn] = True\n                keepgoing = True\n                break\n\n    # XXX: detect and handle loops cleanly\n    for sn in snlist:\n        if handled.has_key(sn):\n            continue\n        logger.debug('UNHANDLED KEY')\n        logger.debug('PROVIDES: %r' % sn.provides)\n        logger.debug('REQUIRES: %r' % sn.requires)\n        logger.debug('\\n'.join(sn.lines))\n\n    #logger.debug(repr(graph))\n    #logger.debug(repr(snlist))\n    logger.debug('Resolved helper defines: %r' % resolved)\n    logger.debug('Resolved %d helper defines' % len(resolved))\n\ndef serialize_snippet_list(snippets):\n    ret = []\n\n    emitted_provides = {}\n    for k in assumed_provides.keys():\n        emitted_provides[k] = True\n\n    for sn in snippets:\n        ret += sn.lines\n        for k in sn.provides.keys():\n            emitted_provides[k] = True\n        for k in sn.requires.keys():\n            if not emitted_provides.has_key(k):\n                # XXX: conditional warning, happens in some normal cases\n                logger.warning('define %r required, not provided so far' % k)\n                pass\n\n    return '\\n'.join(ret)\n\ndef remove_duplicate_newlines(x):\n    ret = []\n    empty = False\n    for line in x.split('\\n'):\n        if line == '':\n            if empty:\n                pass\n            else:\n                ret.append(line)\n            empty = True\n        else:\n            empty = False\n            ret.append(line)\n    return '\\n'.join(ret)\n\ndef scan_use_defs(dirname):\n    global use_defs, use_defs_list\n    use_defs = {}\n    use_defs_list = []\n\n    for fn in os.listdir(dirname):\n        root, ext = os.path.splitext(fn)\n        if not root.startswith('DUK_USE_') or ext != '.yaml':\n            continue\n        with open(os.path.join(dirname, fn), 'rb') as f:\n            doc = yaml.load(f)\n            if doc.get('example', False):\n                continue\n            if doc.get('unimplemented', False):\n                logger.warning('unimplemented: %s' % fn)\n                continue\n            dockeys = doc.keys()\n            for k in dockeys:\n                if not k in allowed_use_meta_keys:\n                    logger.warning('unknown key %s in metadata file %s' % (k, fn))\n            for k in required_use_meta_keys:\n                if not k in dockeys:\n                    logger.warning('missing key %s in metadata file %s' % (k, fn))\n\n            use_defs[doc['define']] = doc\n\n    keys = use_defs.keys()\n    keys.sort()\n    for k in keys:\n        use_defs_list.append(use_defs[k])\n\ndef scan_opt_defs(dirname):\n    global opt_defs, opt_defs_list\n    opt_defs = {}\n    opt_defs_list = []\n\n    for fn in os.listdir(dirname):\n        root, ext = os.path.splitext(fn)\n        if not root.startswith('DUK_OPT_') or ext != '.yaml':\n            continue\n        with open(os.path.join(dirname, fn), 'rb') as f:\n            doc = yaml.load(f)\n            if doc.get('example', False):\n                continue\n            if doc.get('unimplemented', False):\n                logger.warning('unimplemented: %s' % fn)\n                continue\n            dockeys = doc.keys()\n            for k in dockeys:\n                if not k in allowed_opt_meta_keys:\n                    logger.warning('unknown key %s in metadata file %s' % (k, fn))\n            for k in required_opt_meta_keys:\n                if not k in dockeys:\n                    logger.warning('missing key %s in metadata file %s' % (k, fn))\n\n            opt_defs[doc['define']] = doc\n\n    keys = opt_defs.keys()\n    keys.sort()\n    for k in keys:\n        opt_defs_list.append(opt_defs[k])\n\ndef scan_use_tags():\n    global use_tags, use_tags_list\n    use_tags = {}\n\n    for doc in use_defs_list:\n        for tag in doc.get('tags', []):\n            use_tags[tag] = True\n\n    use_tags_list = use_tags.keys()\n    use_tags_list.sort()\n\ndef scan_tags_meta(filename):\n    global tags_meta\n\n    with open(filename, 'rb') as f:\n        tags_meta = yaml.load(f)\n\ndef scan_helper_snippets(dirname):  # DUK_F_xxx snippets\n    global helper_snippets\n    helper_snippets = []\n\n    for fn in os.listdir(dirname):\n        if (fn[0:6] != 'DUK_F_'):\n            continue\n        logger.debug('Autoscanning snippet: %s' % fn)\n        helper_snippets.append(Snippet.fromFile(os.path.join(dirname, fn)))\n\ndef get_opt_defs(removed=True, deprecated=True, unused=True):\n    ret = []\n    for doc in opt_defs_list:\n        # XXX: aware of target version\n        if removed == False and doc.get('removed', None) is not None:\n            continue\n        if deprecated == False and doc.get('deprecated', None) is not None:\n            continue\n        if unused == False and doc.get('unused', False) == True:\n            continue\n        ret.append(doc)\n    return ret\n\ndef get_use_defs(removed=True, deprecated=True, unused=True):\n    ret = []\n    for doc in use_defs_list:\n        # XXX: aware of target version\n        if removed == False and doc.get('removed', None) is not None:\n            continue\n        if deprecated == False and doc.get('deprecated', None) is not None:\n            continue\n        if unused == False and doc.get('unused', False) == True:\n            continue\n        ret.append(doc)\n    return ret\n\ndef validate_platform_file(filename):\n    sn = Snippet.fromFile(filename)\n\n    for req in platform_required_provides:\n        if req not in sn.provides:\n            raise Exception('Platform %s is missing %s' % (filename, req))\n\n    # DUK_SETJMP, DUK_LONGJMP, DUK_JMPBUF_TYPE are optional, fill-in\n    # provides if none defined.\n\ndef validate_architecture_file(filename):\n    sn = Snippet.fromFile(filename)\n\n    for req in architecture_required_provides:\n        if req not in sn.provides:\n            raise Exception('Architecture %s is missing %s' % (filename, req))\n\n    # Byte order and alignment defines are allowed to be missing,\n    # a fill-in will handle them.  This is necessary because for\n    # some architecture byte order and/or alignment may vary between\n    # targets and may be software configurable.\n\n    # XXX: require automatic detection to be signaled?\n    # e.g. define DUK_USE_ALIGN_BY -1\n    #      define DUK_USE_BYTE_ORDER -1\n\ndef validate_compiler_file(filename):\n    sn = Snippet.fromFile(filename)\n\n    for req in compiler_required_provides:\n        if req not in sn.provides:\n            raise Exception('Compiler %s is missing %s' % (filename, req))\n\ndef get_tag_title(tag):\n    meta = tags_meta.get(tag, None)\n    if meta is None:\n        return tag\n    else:\n        return meta.get('title', tag)\n\ndef get_tag_description(tag):\n    meta = tags_meta.get(tag, None)\n    if meta is None:\n        return None\n    else:\n        return meta.get('description', None)\n\ndef get_tag_list_with_preferred_order(preferred):\n    tags = []\n\n    # Preferred tags first\n    for tag in preferred:\n        if tag not in tags:\n            tags.append(tag)\n\n    # Remaining tags in alphabetic order\n    for tag in use_tags_list:\n        if tag not in tags:\n            tags.append(tag)\n\n    logger.debug('Effective tag order: %r' % tags)\n    return tags\n\ndef rst_format(text):\n    # XXX: placeholder, need to decide on markup conventions for YAML files\n    ret = []\n    for para in text.split('\\n'):\n        if para == '':\n            continue\n        ret.append(para)\n    return '\\n\\n'.join(ret)\n\ndef cint_encode(x):\n    if not isinstance(x, (int, long)):\n        raise Exception('invalid input: %r' % x)\n\n    # XXX: unsigned constants?\n    if x > 0x7fffffff or x < -0x80000000:\n        return '%dLL' % x\n    elif x > 0x7fff or x < -0x8000:\n        return '%dL' % x\n    else:\n        return '%d' % x\n\ndef cstr_encode(x):\n    if isinstance(x, unicode):\n        x = x.encode('utf-8')\n    if not isinstance(x, str):\n        raise Exception('invalid input: %r' % x)\n\n    res = '\"'\n    term = False\n    has_terms = False\n    for c in x:\n        if term:\n            # Avoid ambiguous hex escapes\n            res += '\" \"'\n            term = False\n            has_terms = True\n        o = ord(c)\n        if o < 0x20 or o > 0x7e or c in '\"\\\\':\n            res += '\\\\x%02x' % o\n            term = True\n        else:\n            res += c\n    res += '\"'\n\n    if has_terms:\n        res = '(' + res + ')'\n\n    return res\n\n#\n#  Autogeneration of option documentation\n#\n\n# Shared helper to generate DUK_USE_xxx documentation.\n# XXX: unfinished placeholder\ndef generate_option_documentation(opts, opt_list=None, rst_title=None, include_default=False):\n    ret = FileBuilder(use_cpp_warning=opts.use_cpp_warning)\n\n    tags = get_tag_list_with_preferred_order(doc_tag_order)\n\n    title = rst_title\n    ret.rst_heading(title, '=', doubled=True)\n\n    handled = {}\n\n    for tag in tags:\n        first = True\n\n        for doc in opt_list:\n            if tag != doc['tags'][0]:  # sort under primary tag\n                continue\n            dname = doc['define']\n            desc = doc.get('description', None)\n\n            if handled.has_key(dname):\n                raise Exception('define handled twice, should not happen: %r' % dname)\n            handled[dname] = True\n\n            if first:  # emit tag heading only if there are subsections\n                ret.empty()\n                ret.rst_heading(get_tag_title(tag), '=')\n\n                tag_desc = get_tag_description(tag)\n                if tag_desc is not None:\n                    ret.empty()\n                    ret.line(rst_format(tag_desc))\n                first = False\n\n            ret.empty()\n            ret.rst_heading(dname, '-')\n\n            if desc is not None:\n                ret.empty()\n                ret.line(rst_format(desc))\n\n            if include_default:\n                ret.empty()\n                ret.line('Default: ``' + str(doc['default']) + '``')  # XXX: rst or other format\n\n    for doc in opt_list:\n        dname = doc['define']\n        if not handled.has_key(dname):\n            raise Exception('unhandled define (maybe missing from tags list?): %r' % dname)\n\n    ret.empty()\n    return ret.join()\n\ndef generate_config_option_documentation(opts):\n    defs = get_use_defs()\n    return generate_option_documentation(opts, opt_list=defs, rst_title='Duktape config options', include_default=True)\n\n#\n#  Helpers for duk_config.h generation\n#\n\ndef get_forced_options(opts):\n    # Forced options, last occurrence wins (allows a base config file to be\n    # overridden by a more specific one).\n    forced_opts = {}\n    for val in opts.force_options_yaml:\n        doc = yaml.load(StringIO(val))\n        for k in doc.keys():\n            if use_defs.has_key(k):\n                pass  # key is known\n            else:\n                logger.warning('option override key %s not defined in metadata, ignoring' % k)\n            forced_opts[k] = doc[k]  # shallow copy\n\n    if len(forced_opts.keys()) > 0:\n        logger.debug('Overrides: %s' % json.dumps(forced_opts))\n\n    return forced_opts\n\n# Emit a default #define / #undef for an option based on\n# a config option metadata node (parsed YAML doc).\ndef emit_default_from_config_meta(ret, doc, forced_opts, undef_done, active_opts):\n    defname = doc['define']\n    defval = forced_opts.get(defname, doc['default'])\n\n    # NOTE: careful with Python equality, e.g. \"0 == False\" is true.\n    if isinstance(defval, bool) and defval == True:\n        ret.line('#define ' + defname)\n        active_opts[defname] = True\n    elif isinstance(defval, bool) and defval == False:\n        if not undef_done:\n            ret.line('#undef ' + defname)\n        else:\n            # Default value is false, and caller has emitted\n            # an unconditional #undef, so don't emit a duplicate\n            pass\n        active_opts[defname] = False\n    elif isinstance(defval, (int, long)):\n        # integer value\n        ret.line('#define ' + defname + ' ' + cint_encode(defval))\n        active_opts[defname] = True\n    elif isinstance(defval, (str, unicode)):\n        # verbatim value\n        ret.line('#define ' + defname + ' ' + defval)\n        active_opts[defname] = True\n    elif isinstance(defval, dict):\n        if defval.has_key('verbatim'):\n            # verbatim text for the entire line\n            ret.line(defval['verbatim'])\n        elif defval.has_key('string'):\n            # C string value\n            ret.line('#define ' + defname + ' ' + cstr_encode(defval['string']))\n        else:\n            raise Exception('unsupported value for option %s: %r' % (defname, defval))\n        active_opts[defname] = True\n    else:\n        raise Exception('unsupported value for option %s: %r' % (defname, defval))\n\n# Add a header snippet for detecting presence of DUK_OPT_xxx feature\n# options and warning/erroring if application defines them.  Useful for\n# Duktape 2.x migration.\ndef add_legacy_feature_option_checks(opts, ret):\n    ret.chdr_block_heading('Checks for legacy feature options (DUK_OPT_xxx)')\n    ret.empty()\n\n    defs = []\n    for doc in get_opt_defs():\n        if doc['define'] not in defs:\n            defs.append(doc['define'])\n    defs.sort()\n\n    for optname in defs:\n        ret.line('#if defined(%s)' % optname)\n        ret.cpp_warning_or_error('unsupported legacy feature option %s used' % optname, opts.sanity_strict)\n        ret.line('#endif')\n\n    ret.empty()\n\n# Add a header snippet for checking consistency of DUK_USE_xxx config\n# options, e.g. inconsistent options, invalid option values.\ndef add_config_option_checks(opts, ret):\n    ret.chdr_block_heading('Checks for config option consistency (DUK_USE_xxx)')\n    ret.empty()\n\n    defs = []\n    for doc in get_use_defs():\n        if doc['define'] not in defs:\n            defs.append(doc['define'])\n    defs.sort()\n\n    for optname in defs:\n        doc = use_defs[optname]\n        dname = doc['define']\n\n        # XXX: more checks\n\n        if doc.get('removed', None) is not None:\n            ret.line('#if defined(%s)' % dname)\n            ret.cpp_warning_or_error('unsupported config option used (option has been removed): %s' % dname, opts.sanity_strict)\n            ret.line('#endif')\n        elif doc.get('deprecated', None) is not None:\n            ret.line('#if defined(%s)' % dname)\n            ret.cpp_warning_or_error('unsupported config option used (option has been deprecated): %s' % dname, opts.sanity_strict)\n            ret.line('#endif')\n\n        for req in doc.get('requires', []):\n            ret.line('#if defined(%s) && !defined(%s)' % (dname, req))\n            ret.cpp_warning_or_error('config option %s requires option %s (which is missing)' % (dname, req), opts.sanity_strict)\n            ret.line('#endif')\n\n        for req in doc.get('conflicts', []):\n            ret.line('#if defined(%s) && defined(%s)' % (dname, req))\n            ret.cpp_warning_or_error('config option %s conflicts with option %s (which is also defined)' % (dname, req), opts.sanity_strict)\n            ret.line('#endif')\n\n    ret.empty()\n    ret.snippet_relative('cpp_exception_sanity.h.in')\n    ret.empty()\n\n# Add a header snippet for providing a __OVERRIDE_DEFINES__ section.\ndef add_override_defines_section(opts, ret):\n    ret.empty()\n    ret.line('/*')\n    ret.line(' *  You may add overriding #define/#undef directives below for')\n    ret.line(' *  customization.  You of course cannot un-#include or un-typedef')\n    ret.line(' *  anything; these require direct changes above.')\n    ret.line(' */')\n    ret.empty()\n    ret.line('/* __OVERRIDE_DEFINES__ */')\n    ret.empty()\n\n# Add a header snippet for conditional C/C++ include files.\ndef add_conditional_includes_section(opts, ret):\n    ret.empty()\n    ret.line('/*')\n    ret.line(' *  Conditional includes')\n    ret.line(' */')\n    ret.empty()\n    ret.snippet_relative('platform_conditionalincludes.h.in')\n    ret.empty()\n\n# Development time helper: add DUK_ACTIVE which provides a runtime C string\n# indicating what DUK_USE_xxx config options are active at run time.  This\n# is useful in genconfig development so that one can e.g. diff the active\n# run time options of two headers.  This is intended just for genconfig\n# development and is not available in normal headers.\ndef add_duk_active_defines_macro(ret):\n    ret.chdr_block_heading('DUK_ACTIVE_DEFINES macro (development only)')\n\n    idx = 0\n    for doc in get_use_defs():\n        defname = doc['define']\n\n        ret.line('#if defined(%s)' % defname)\n        ret.line('#define DUK_ACTIVE_DEF%d \" %s\"' % (idx, defname))\n        ret.line('#else')\n        ret.line('#define DUK_ACTIVE_DEF%d \"\"' % idx)\n        ret.line('#endif')\n\n        idx += 1\n\n    tmp = []\n    for i in xrange(idx):\n        tmp.append('DUK_ACTIVE_DEF%d' % i)\n\n    ret.line('#define DUK_ACTIVE_DEFINES (\"Active: [\"' + ' '.join(tmp) + ' \" ]\")')\n\n#\n#  duk_config.h generation\n#\n\n# Generate a duk_config.h where platform, architecture, and compiler are\n# all either autodetected or specified by user.\n#\n# Autodetection is based on a configured list of supported platforms,\n# architectures, and compilers.  For example, platforms.yaml defines the\n# supported platforms and provides a helper define (DUK_F_xxx) to use for\n# detecting that platform, and names the header snippet to provide the\n# platform-specific definitions.  Necessary dependencies (DUK_F_xxx) are\n# automatically pulled in.\n#\n# Automatic \"fill ins\" are used for mandatory platform, architecture, and\n# compiler defines which have a reasonable portable default.  This reduces\n# e.g. compiler-specific define count because there are a lot compiler\n# macros which have a good default.\ndef generate_duk_config_header(opts, meta_dir):\n    ret = FileBuilder(base_dir=os.path.join(meta_dir, 'header-snippets'), \\\n                      use_cpp_warning=opts.use_cpp_warning)\n\n    # Parse forced options.  Warn about missing forced options when it is\n    # strongly recommended that the option is provided.\n    forced_opts = get_forced_options(opts)\n    for doc in use_defs_list:\n        if doc.get('warn_if_missing', False) and not forced_opts.has_key(doc['define']):\n            # Awkward handling for DUK_USE_CPP_EXCEPTIONS + DUK_USE_FATAL_HANDLER.\n            if doc['define'] == 'DUK_USE_FATAL_HANDLER' and forced_opts.has_key('DUK_USE_CPP_EXCEPTIONS'):\n                pass  # DUK_USE_FATAL_HANDLER not critical with DUK_USE_CPP_EXCEPTIONS\n            else:\n                logger.warning('Recommended config option ' + doc['define'] + ' not provided')\n\n    # Gather a map of \"active options\" for genbuiltins.py.  This is used to\n    # implement proper optional built-ins, e.g. if a certain config option\n    # (like DUK_USE_ES6_PROXY) is disabled, the corresponding objects and\n    # properties are dropped entirely.  The mechanism is not perfect: it won't\n    # detect fixup changes for example.\n    active_opts = {}\n\n    platforms = None\n    with open(os.path.join(meta_dir, 'platforms.yaml'), 'rb') as f:\n        platforms = yaml.load(f)\n    architectures = None\n    with open(os.path.join(meta_dir, 'architectures.yaml'), 'rb') as f:\n        architectures = yaml.load(f)\n    compilers = None\n    with open(os.path.join(meta_dir, 'compilers.yaml'), 'rb') as f:\n        compilers = yaml.load(f)\n\n    # XXX: indicate feature option support, sanity checks enabled, etc\n    # in general summary of options, perhaps genconfig command line?\n\n    ret.line('/*')\n    ret.line(' *  duk_config.h configuration header generated by genconfig.py.')\n    ret.line(' *')\n    ret.line(' *  Git commit: %s' % opts.git_commit or 'n/a')\n    ret.line(' *  Git describe: %s' % opts.git_describe or 'n/a')\n    ret.line(' *  Git branch: %s' % opts.git_branch or 'n/a')\n    ret.line(' *')\n    if opts.platform is not None:\n        ret.line(' *  Platform: ' + opts.platform)\n    else:\n        ret.line(' *  Supported platforms:')\n        for platf in platforms['autodetect']:\n            ret.line(' *      - %s' % platf.get('name', platf.get('check')))\n    ret.line(' *')\n    if opts.architecture is not None:\n        ret.line(' *  Architecture: ' + opts.architecture)\n    else:\n        ret.line(' *  Supported architectures:')\n        for arch in architectures['autodetect']:\n            ret.line(' *      - %s' % arch.get('name', arch.get('check')))\n    ret.line(' *')\n    if opts.compiler is not None:\n        ret.line(' *  Compiler: ' + opts.compiler)\n    else:\n        ret.line(' *  Supported compilers:')\n        for comp in compilers['autodetect']:\n            ret.line(' *      - %s' % comp.get('name', comp.get('check')))\n    ret.line(' *')\n    ret.line(' */')\n    ret.empty()\n    ret.line('#if !defined(DUK_CONFIG_H_INCLUDED)')\n    ret.line('#define DUK_CONFIG_H_INCLUDED')\n    ret.empty()\n\n    ret.chdr_block_heading('Intermediate helper defines')\n\n    # DLL build affects visibility attributes on Windows but unfortunately\n    # cannot be detected automatically from preprocessor defines or such.\n    # DLL build status is hidden behind DUK_F_DLL_BUILD. and there are two\n    ret.chdr_comment_line('DLL build detection')\n    if opts.dll:\n        ret.line('/* configured for DLL build */')\n        ret.line('#define DUK_F_DLL_BUILD')\n    else:\n        ret.line('/* not configured for DLL build */')\n        ret.line('#undef DUK_F_DLL_BUILD')\n    ret.empty()\n\n    idx_deps = len(ret.vals)  # position where to emit DUK_F_xxx dependencies\n\n    # Feature selection, system include, Date provider\n    # Most #include statements are here\n\n    if opts.platform is not None:\n        ret.chdr_block_heading('Platform: ' + opts.platform)\n\n        ret.snippet_relative('platform_cppextras.h.in')\n        ret.empty()\n\n        # XXX: better to lookup platforms metadata\n        include = 'platform_%s.h.in' % opts.platform\n        abs_fn = os.path.join(meta_dir, 'platforms', include)\n        validate_platform_file(abs_fn)\n        ret.snippet_absolute(abs_fn)\n    else:\n        ret.chdr_block_heading('Platform autodetection')\n\n        ret.snippet_relative('platform_cppextras.h.in')\n        ret.empty()\n\n        for idx, platf in enumerate(platforms['autodetect']):\n            check = platf.get('check', None)\n            include = platf['include']\n            abs_fn = os.path.join(meta_dir, 'platforms', include)\n\n            validate_platform_file(abs_fn)\n\n            if idx == 0:\n                ret.line('#if defined(%s)' % check)\n            else:\n                if check is None:\n                    ret.line('#else')\n                else:\n                    ret.line('#elif defined(%s)' % check)\n            ret.line('/* --- %s --- */' % platf.get('name', '???'))\n            ret.snippet_absolute(abs_fn)\n        ret.line('#endif  /* autodetect platform */')\n\n    ret.empty()\n    ret.snippet_relative('platform_sharedincludes.h.in')\n    ret.empty()\n\n    byteorder_provided_by_all = True  # byteorder provided by all architecture files\n    alignment_provided_by_all = True  # alignment provided by all architecture files\n    packedtval_provided_by_all = True # packed tval provided by all architecture files\n\n    if opts.architecture is not None:\n        ret.chdr_block_heading('Architecture: ' + opts.architecture)\n\n        # XXX: better to lookup architectures metadata\n        include = 'architecture_%s.h.in' % opts.architecture\n        abs_fn = os.path.join(meta_dir, 'architectures', include)\n        validate_architecture_file(abs_fn)\n        sn = ret.snippet_absolute(abs_fn)\n        if not sn.provides.get('DUK_USE_BYTEORDER', False):\n            byteorder_provided_by_all = False\n        if not sn.provides.get('DUK_USE_ALIGN_BY', False):\n            alignment_provided_by_all = False\n        if sn.provides.get('DUK_USE_PACKED_TVAL', False):\n            ret.line('#define DUK_F_PACKED_TVAL_PROVIDED')  # signal to fillin\n        else:\n            packedtval_provided_by_all = False\n    else:\n        ret.chdr_block_heading('Architecture autodetection')\n\n        for idx, arch in enumerate(architectures['autodetect']):\n            check = arch.get('check', None)\n            include = arch['include']\n            abs_fn = os.path.join(meta_dir, 'architectures', include)\n\n            validate_architecture_file(abs_fn)\n\n            if idx == 0:\n                ret.line('#if defined(%s)' % check)\n            else:\n                if check is None:\n                    ret.line('#else')\n                else:\n                    ret.line('#elif defined(%s)' % check)\n            ret.line('/* --- %s --- */' % arch.get('name', '???'))\n            sn = ret.snippet_absolute(abs_fn)\n            if not sn.provides.get('DUK_USE_BYTEORDER', False):\n                byteorder_provided_by_all = False\n            if not sn.provides.get('DUK_USE_ALIGN_BY', False):\n                alignment_provided_by_all = False\n            if sn.provides.get('DUK_USE_PACKED_TVAL', False):\n                ret.line('#define DUK_F_PACKED_TVAL_PROVIDED')  # signal to fillin\n            else:\n                packedtval_provided_by_all = False\n        ret.line('#endif  /* autodetect architecture */')\n\n    ret.empty()\n\n    if opts.compiler is not None:\n        ret.chdr_block_heading('Compiler: ' + opts.compiler)\n\n        # XXX: better to lookup compilers metadata\n        include = 'compiler_%s.h.in' % opts.compiler\n        abs_fn = os.path.join(meta_dir, 'compilers', include)\n        validate_compiler_file(abs_fn)\n        sn = ret.snippet_absolute(abs_fn)\n    else:\n        ret.chdr_block_heading('Compiler autodetection')\n\n        for idx, comp in enumerate(compilers['autodetect']):\n            check = comp.get('check', None)\n            include = comp['include']\n            abs_fn = os.path.join(meta_dir, 'compilers', include)\n\n            validate_compiler_file(abs_fn)\n\n            if idx == 0:\n                ret.line('#if defined(%s)' % check)\n            else:\n                if check is None:\n                    ret.line('#else')\n                else:\n                    ret.line('#elif defined(%s)' % check)\n            ret.line('/* --- %s --- */' % comp.get('name', '???'))\n            sn = ret.snippet_absolute(abs_fn)\n        ret.line('#endif  /* autodetect compiler */')\n\n    ret.empty()\n\n    # DUK_F_UCLIBC is special because __UCLIBC__ is provided by an #include\n    # file, so the check must happen after platform includes.  It'd be nice\n    # for this to be automatic (e.g. DUK_F_UCLIBC.h.in could indicate the\n    # dependency somehow).\n\n    ret.snippet_absolute(os.path.join(meta_dir, 'helper-snippets', 'DUK_F_UCLIBC.h.in'))\n    ret.empty()\n\n    # XXX: platform/compiler could provide types; if so, need some signaling\n    # defines like DUK_F_TYPEDEFS_DEFINED\n\n    # Number types\n    if opts.c99_types_only:\n        ret.snippet_relative('types1.h.in')\n        ret.line('/* C99 types assumed */')\n        ret.snippet_relative('types_c99.h.in')\n        ret.empty()\n    else:\n        ret.snippet_relative('types1.h.in')\n        ret.line('#if defined(DUK_F_HAVE_INTTYPES)')\n        ret.line('/* C99 or compatible */')\n        ret.empty()\n        ret.snippet_relative('types_c99.h.in')\n        ret.empty()\n        ret.line('#else  /* C99 types */')\n        ret.empty()\n        ret.snippet_relative('types_legacy.h.in')\n        ret.empty()\n        ret.line('#endif  /* C99 types */')\n        ret.empty()\n    ret.snippet_relative('types2.h.in')\n    ret.empty()\n    ret.snippet_relative('64bitops.h.in')\n    ret.empty()\n\n    # Platform, architecture, compiler fillins.  These are after all\n    # detection so that e.g. DUK_SPRINTF() can be provided by platform\n    # or compiler before trying a fill-in.\n\n    ret.chdr_block_heading('Fill-ins for platform, architecture, and compiler')\n\n    ret.snippet_relative('platform_fillins.h.in')\n    ret.empty()\n    ret.snippet_relative('architecture_fillins.h.in')\n    if not byteorder_provided_by_all:\n        ret.empty()\n        ret.snippet_relative('byteorder_fillin.h.in')\n    if not alignment_provided_by_all:\n        ret.empty()\n        ret.snippet_relative('alignment_fillin.h.in')\n    ret.empty()\n    ret.snippet_relative('compiler_fillins.h.in')\n    ret.empty()\n    ret.snippet_relative('inline_workaround.h.in')\n    ret.empty()\n    if not packedtval_provided_by_all:\n        ret.empty()\n        ret.snippet_relative('packed_tval_fillin.h.in')\n\n    # Object layout\n    ret.snippet_relative('object_layout.h.in')\n    ret.empty()\n\n    # Detect and reject 'fast math'\n    ret.snippet_relative('reject_fast_math.h.in')\n    ret.empty()\n\n    # Emit forced options.  If a corresponding option is already defined\n    # by a snippet above, #undef it first.\n\n    tmp = Snippet(ret.join().split('\\n'))\n    first_forced = True\n    for doc in get_use_defs(removed=not opts.omit_removed_config_options,\n                            deprecated=not opts.omit_deprecated_config_options,\n                            unused=not opts.omit_unused_config_options):\n        defname = doc['define']\n\n        if not forced_opts.has_key(defname):\n            continue\n\n        if not doc.has_key('default'):\n            raise Exception('config option %s is missing default value' % defname)\n\n        if first_forced:\n            ret.chdr_block_heading('Forced options')\n            first_forced = False\n\n        undef_done = False\n        if tmp.provides.has_key(defname):\n            ret.line('#undef ' + defname)\n            undef_done = True\n\n        emit_default_from_config_meta(ret, doc, forced_opts, undef_done, active_opts)\n\n    ret.empty()\n\n    # If manually-edited snippets don't #define or #undef a certain\n    # config option, emit a default value here.  This is useful to\n    # fill-in for new config options not covered by manual snippets\n    # (which is intentional).\n\n    tmp = Snippet(ret.join().split('\\n'))\n    need = {}\n    for doc in get_use_defs(removed=False):\n        need[doc['define']] = True\n    for k in tmp.provides.keys():\n        if need.has_key(k):\n            del need[k]\n    need_keys = sorted(need.keys())\n\n    if len(need_keys) > 0:\n        ret.chdr_block_heading('Autogenerated defaults')\n\n        for k in need_keys:\n            logger.debug('config option %s not covered by manual snippets, emitting default automatically' % k)\n            emit_default_from_config_meta(ret, use_defs[k], {}, False, active_opts)\n\n        ret.empty()\n\n    if len(opts.fixup_header_lines) > 0:\n        ret.chdr_block_heading('Fixups')\n        for line in opts.fixup_header_lines:\n            ret.line(line)\n        ret.empty()\n\n    add_override_defines_section(opts, ret)\n\n    # Some headers are only included if final DUK_USE_xxx option settings\n    # indicate they're needed, for example C++ <exception>.\n    add_conditional_includes_section(opts, ret)\n\n    # Date provider snippet is after custom header and overrides, so that\n    # the user may define e.g. DUK_USE_DATE_NOW_GETTIMEOFDAY in their\n    # custom header.\n    ret.snippet_relative('date_provider.h.in')\n    ret.empty()\n\n    ret.fill_dependencies_for_snippets(idx_deps)\n\n    if opts.emit_legacy_feature_check:\n        add_legacy_feature_option_checks(opts, ret)\n    if opts.emit_config_sanity_check:\n        add_config_option_checks(opts, ret)\n    if opts.add_active_defines_macro:\n        add_duk_active_defines_macro(ret)\n\n    # Derived defines (DUK_USE_INTEGER_LE, etc) from DUK_USE_BYTEORDER.\n    # Duktape internals currently rely on the derived defines.  This is\n    # after sanity checks because the derived defines are marked removed.\n    ret.snippet_relative('byteorder_derived.h.in')\n    ret.empty()\n\n    ret.line('#endif  /* DUK_CONFIG_H_INCLUDED */')\n    ret.empty()  # for trailing newline\n    return remove_duplicate_newlines(ret.join()), active_opts\n\n#\n#  Misc\n#\n\n# Validate DUK_USE_xxx config options found in source code against known\n# config metadata.  Also warn about non-removed config options that are\n# not found in the source.\ndef validate_config_options_in_source(fn):\n    with open(fn, 'rb') as f:\n        doc = json.loads(f.read())\n\n    defs_used = {}\n\n    for opt in doc.get('used_duk_use_options'):\n        defs_used[opt] = True\n        if opt == 'DUK_USE_xxx' or opt == 'DUK_USE_XXX':\n            continue  # allow common placeholders\n        meta = use_defs.get(opt)\n        if meta is None:\n            raise Exception('unknown config option in source code: %r' % opt)\n        if meta.get('removed', None) is not None:\n            #logger.info('removed config option in source code: %r' % opt)\n            #raise Exception('removed config option in source code: %r' % opt)\n            pass\n\n    for meta in use_defs_list:\n        if not defs_used.has_key(meta['define']):\n            if not meta.has_key('removed'):\n                logger.debug('config option %r not found in source code' % meta['define'])\n\n#\n#  Main\n#\n\ndef add_genconfig_optparse_options(parser, direct=False):\n    # Forced options from multiple sources are gathered into a shared list\n    # so that the override order remains the same as on the command line.\n    force_options_yaml = []\n    def add_force_option_yaml(option, opt, value, parser):\n        # XXX: check that YAML parses\n        force_options_yaml.append(value)\n    def add_force_option_file(option, opt, value, parser):\n        # XXX: check that YAML parses\n        with open(value, 'rb') as f:\n            force_options_yaml.append(f.read())\n    def add_force_option_define(option, opt, value, parser):\n        defname, eq, defval = value.partition('=')\n        if not eq:\n            doc = { defname: True }\n        else:\n            defname, paren, defargs = defname.partition('(')\n            if not paren:\n                doc = { defname: defval }\n            else:\n                doc = { defname: { 'verbatim': '#define %s%s%s %s' % (defname, paren, defargs, defval) } }\n        force_options_yaml.append(yaml.safe_dump(doc))\n    def add_force_option_undefine(option, opt, value, parser):\n        tmp = value.split('=')\n        if len(tmp) == 1:\n            doc = { tmp[0]: False }\n        else:\n            raise Exception('invalid option value: %r' % value)\n        force_options_yaml.append(yaml.safe_dump(doc))\n\n    fixup_header_lines = []\n    def add_fixup_header_line(option, opt, value, parser):\n        fixup_header_lines.append(value)\n    def add_fixup_header_file(option, opt, value, parser):\n        with open(value, 'rb') as f:\n            for line in f:\n                if line[-1] == '\\n':\n                    line = line[:-1]\n                fixup_header_lines.append(line)\n\n    if direct:\n        parser.add_option('--metadata', dest='config_metadata', default=None, help='metadata directory')\n        parser.add_option('--output', dest='output', default=None, help='output filename for C header or RST documentation file')\n        parser.add_option('--output-active-options', dest='output_active_options', default=None, help='output JSON file with active config options information')\n    else:\n        # Different option name when called through configure.py,\n        # also no --output option.\n        parser.add_option('--config-metadata', dest='config_metadata', default=None, help='metadata directory (defaulted based on configure.py script path)')\n\n    parser.add_option('--platform', dest='platform', default=None, help='platform (default is autodetect)')\n    parser.add_option('--compiler', dest='compiler', default=None, help='compiler (default is autodetect)')\n    parser.add_option('--architecture', dest='architecture', default=None, help='architecture (default is autodetec)')\n    parser.add_option('--c99-types-only', dest='c99_types_only', action='store_true', default=False, help='assume C99 types, no legacy type detection')\n    parser.add_option('--dll', dest='dll', action='store_true', default=False, help='dll build of Duktape, affects symbol visibility macros especially on Windows')\n    parser.add_option('--support-feature-options', dest='support_feature_options', action='store_true', default=False, help=optparse.SUPPRESS_HELP)\n    parser.add_option('--emit-legacy-feature-check', dest='emit_legacy_feature_check', action='store_true', default=False, help='emit preprocessor checks to reject legacy feature options (DUK_OPT_xxx)')\n    parser.add_option('--emit-config-sanity-check', dest='emit_config_sanity_check', action='store_true', default=False, help='emit preprocessor checks for config option consistency (DUK_USE_xxx)')\n    parser.add_option('--omit-removed-config-options', dest='omit_removed_config_options', action='store_true', default=False, help='omit removed config options from generated headers')\n    parser.add_option('--omit-deprecated-config-options', dest='omit_deprecated_config_options', action='store_true', default=False, help='omit deprecated config options from generated headers')\n    parser.add_option('--omit-unused-config-options', dest='omit_unused_config_options', action='store_true', default=False, help='omit unused config options from generated headers')\n    parser.add_option('--add-active-defines-macro', dest='add_active_defines_macro', action='store_true', default=False, help='add DUK_ACTIVE_DEFINES macro, for development only')\n    parser.add_option('--define', type='string', metavar='OPTION', dest='force_options_yaml', action='callback', callback=add_force_option_define, default=force_options_yaml, help='force #define option using a C compiler like syntax, e.g. \"--define DUK_USE_DEEP_C_STACK\" or \"--define DUK_USE_TRACEBACK_DEPTH=10\"')\n    parser.add_option('-D', type='string', metavar='OPTION', dest='force_options_yaml', action='callback', callback=add_force_option_define, default=force_options_yaml, help='synonym for --define, e.g. \"-DDUK_USE_DEEP_C_STACK\" or \"-DDUK_USE_TRACEBACK_DEPTH=10\"')\n    parser.add_option('--undefine', type='string', metavar='OPTION', dest='force_options_yaml', action='callback', callback=add_force_option_undefine, default=force_options_yaml, help='force #undef option using a C compiler like syntax, e.g. \"--undefine DUK_USE_DEEP_C_STACK\"')\n    parser.add_option('-U', type='string', metavar='OPTION', dest='force_options_yaml', action='callback', callback=add_force_option_undefine, default=force_options_yaml, help='synonym for --undefine, e.g. \"-UDUK_USE_DEEP_C_STACK\"')\n    parser.add_option('--option-yaml', type='string', metavar='YAML', dest='force_options_yaml', action='callback', callback=add_force_option_yaml, default=force_options_yaml, help='force option(s) using inline YAML (e.g. --option-yaml \"DUK_USE_DEEP_C_STACK: true\")')\n    parser.add_option('--option-file', type='string', metavar='FILENAME', dest='force_options_yaml', action='callback', callback=add_force_option_file, default=force_options_yaml, help='YAML file(s) providing config option overrides')\n    parser.add_option('--fixup-file', type='string', metavar='FILENAME', dest='fixup_header_lines', action='callback', callback=add_fixup_header_file, default=fixup_header_lines, help='C header snippet file(s) to be appended to generated header, useful for manual option fixups')\n    parser.add_option('--fixup-line', type='string', metavar='LINE', dest='fixup_header_lines', action='callback', callback=add_fixup_header_line, default=fixup_header_lines, help='C header fixup line to be appended to generated header (e.g. --fixup-line \"#define DUK_USE_FASTINT\")')\n    parser.add_option('--sanity-warning', dest='sanity_strict', action='store_false', default=True, help='emit a warning instead of #error for option sanity check issues')\n    parser.add_option('--use-cpp-warning', dest='use_cpp_warning', action='store_true', default=False, help='emit a (non-portable) #warning when appropriate')\n\n    if direct:\n        parser.add_option('--used-stridx-metadata', dest='used_stridx_metadata', default=None, help='metadata for used stridx, bidx, DUK_USE_xxx')\n        parser.add_option('--git-commit', dest='git_commit', default=None, help='git commit hash to be included in header comments')\n        parser.add_option('--git-describe', dest='git_describe', default=None, help='git describe string to be included in header comments')\n        parser.add_option('--git-branch', dest='git_branch', default=None, help='git branch string to be included in header comments')\n        parser.add_option('--quiet', dest='quiet', action='store_true', default=False, help='Suppress info messages (show warnings)')\n        parser.add_option('--verbose', dest='verbose', action='store_true', default=False, help='Show verbose debug messages')\n\ndef parse_options():\n    commands = [\n        'duk-config-header',\n        'config-documentation'\n    ]\n\n    parser = optparse.OptionParser(\n        usage='Usage: %prog [options] COMMAND',\n        description='Generate a duk_config.h or config option documentation based on config metadata.',\n        epilog='COMMAND can be one of: ' + ', '.join(commands) + '.'\n    )\n\n    add_genconfig_optparse_options(parser, direct=True)\n    (opts, args) = parser.parse_args()\n\n    return opts, args\n\ndef genconfig(opts, args):\n    # Log level.\n    if opts.quiet:\n        logger.setLevel(logging.WARNING)\n    elif opts.verbose:\n        logger.setLevel(logging.DEBUG)\n\n    if opts.support_feature_options:\n        raise Exception('--support-feature-options and support for DUK_OPT_xxx feature options are obsolete, use DUK_USE_xxx config options instead')\n\n    meta_dir = opts.config_metadata\n    if opts.config_metadata is None:\n        if os.path.isdir(os.path.join('.', 'config-options')):\n            opts.config_metadata = '.'\n    if opts.config_metadata is not None and os.path.isdir(opts.config_metadata):\n        meta_dir = opts.config_metadata\n        metadata_src_text = 'Using metadata directory: %r' % meta_dir\n    else:\n        raise Exception('metadata argument must be a directory (tar.gz no longer supported)')\n\n    scan_helper_snippets(os.path.join(meta_dir, 'helper-snippets'))\n    scan_use_defs(os.path.join(meta_dir, 'config-options'))\n    scan_opt_defs(os.path.join(meta_dir, 'feature-options'))\n    scan_use_tags()\n    scan_tags_meta(os.path.join(meta_dir, 'tags.yaml'))\n    logger.debug('%s, scanned%d DUK_USE_XXX, %d helper snippets' % \\\n        (metadata_src_text, len(use_defs.keys()), len(helper_snippets)))\n    logger.debug('Tags: %r' % use_tags_list)\n\n    if opts.used_stridx_metadata is not None:\n        validate_config_options_in_source(opts.used_stridx_metadata)\n\n    if len(args) == 0:\n        raise Exception('missing command')\n    cmd = args[0]\n\n    if cmd == 'duk-config-header':\n        # Generate a duk_config.h header with platform, compiler, and\n        # architecture either autodetected (default) or specified by\n        # user.\n        desc = [\n            'platform=' + ('any', opts.platform)[opts.platform is not None],\n            'architecture=' + ('any', opts.architecture)[opts.architecture is not None],\n            'compiler=' + ('any', opts.compiler)[opts.compiler is not None]\n        ]\n        if opts.dll:\n            desc.append('dll mode')\n        logger.info('Creating duk_config.h: ' + ', '.join(desc))\n        result, active_opts = generate_duk_config_header(opts, meta_dir)\n        with open(opts.output, 'wb') as f:\n            f.write(result)\n        logger.debug('Wrote duk_config.h to ' + str(opts.output))\n        if opts.output_active_options is not None:\n            with open(opts.output_active_options, 'wb') as f:\n                f.write(json.dumps(active_opts, indent=4))\n            logger.debug('Wrote active options JSON metadata to ' + str(opts.output_active_options))\n    elif cmd == 'feature-documentation':\n        raise Exception('The feature-documentation command has been removed along with DUK_OPT_xxx feature option support')\n    elif cmd == 'config-documentation':\n        logger.info('Creating config option documentation')\n        result = generate_config_option_documentation(opts)\n        with open(opts.output, 'wb') as f:\n            f.write(result)\n        logger.debug('Wrote config option documentation to ' + str(opts.output))\n    else:\n        raise Exception('invalid command: %r' % cmd)\n\ndef main():\n    opts, args = parse_options()\n    genconfig(opts, args)\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/tools/json2yaml.py",
    "content": "import os, sys, json, yaml\n\nif __name__ == '__main__':\n    # Use safe_dump() instead of dump() to avoid tags like \"!!python/unicode\"\n    print(yaml.safe_dump(json.load(sys.stdin), default_flow_style=False))\n"
  },
  {
    "path": "react_juce/duktape/tools/merge_debug_meta.py",
    "content": "#!/usr/bin/env python2\n#\n#  Merge debugger YAML metadata files and output a merged JSON metadata file.\n#\n\nimport logging\nimport sys\nlogging.basicConfig(level=logging.INFO, stream=sys.stdout, format='%(name)-21s %(levelname)-7s %(message)s')\nlogger = logging.getLogger('merge_debug_meta.py')\nlogger.setLevel(logging.INFO)\n\nimport os\nimport json\nimport yaml\nimport optparse\n\nif __name__ == '__main__':\n    parser = optparse.OptionParser()\n    parser.add_option('--output', dest='output', default=None, help='output JSON filename')\n    parser.add_option('--class-names', dest='class_names', help='YAML metadata for class names')\n    parser.add_option('--debug-commands', dest='debug_commands', help='YAML metadata for debug commands')\n    parser.add_option('--debug-errors', dest='debug_errors', help='YAML metadata for debug protocol error codes')\n    parser.add_option('--opcodes', dest='opcodes', help='YAML metadata for opcodes')\n    parser.add_option('--quiet', dest='quiet', action='store_true', default=False, help='Suppress info messages (show warnings)')\n    parser.add_option('--verbose', dest='verbose', action='store_true', default=False, help='Show verbose debug messages')\n    (opts, args) = parser.parse_args()\n\n    # Log level.\n    if opts.quiet:\n        logger.setLevel(logging.WARNING)\n    elif opts.verbose:\n        logger.setLevel(logging.DEBUG)\n\n    res = {}\n    def merge(fn):\n        with open(fn, 'rb') as f:\n            doc = yaml.load(f)\n        for k in doc.keys():\n            res[k] = doc[k]\n\n    merge(opts.class_names)\n    merge(opts.debug_commands)\n    merge(opts.debug_errors)\n    merge(opts.opcodes)\n\n    with open(opts.output, 'wb') as f:\n        f.write(json.dumps(res, indent=4) + '\\n')\n    logger.debug('Wrote merged debugger metadata to ' + str(opts.output))\n"
  },
  {
    "path": "react_juce/duktape/tools/prepare_unicode_data.py",
    "content": "#!/usr/bin/env python2\n#\n#  UnicodeData.txt may contain ranges in addition to individual characters.\n#  Unpack the ranges into individual characters for the other scripts to use.\n#\n\nimport os\nimport sys\nimport optparse\n\ndef main():\n    parser = optparse.OptionParser()\n    parser.add_option('--unicode-data', dest='unicode_data')\n    parser.add_option('--output', dest='output')\n    parser.add_option('--quiet', dest='quiet', action='store_true', default=False, help='Suppress info messages (show warnings)')\n    parser.add_option('--verbose', dest='verbose', action='store_true', default=False, help='Show verbose debug messages')\n    (opts, args) = parser.parse_args()\n    assert(opts.unicode_data is not None)\n    assert(opts.output is not None)\n\n    f_in = open(opts.unicode_data, 'rb')\n    f_out = open(opts.output, 'wb')\n    while True:\n        line = f_in.readline()\n        if line == '' or line == '\\n':\n            break\n        parts = line.split(';')  # keep newline\n        if parts[1].endswith('First>'):\n            line2 = f_in.readline()\n            parts2 = line2.split(';')\n            if not parts2[1].endswith('Last>'):\n                raise Exception('cannot parse range')\n            cp1 = long(parts[0], 16)\n            cp2 = long(parts2[0], 16)\n\n            tmp = parts[1:]\n            tmp[0] = '-\"\"-'\n            suffix = ';'.join(tmp)\n            f_out.write(line)\n            for i in xrange(cp1 + 1, cp2):\n                f_out.write('%04X;%s' % (i, suffix))\n            f_out.write(line2)\n        else:\n            f_out.write(line)\n\n    f_in.close()\n    f_out.flush()\n    f_out.close()\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/tools/resolve_combined_lineno.py",
    "content": "#!/usr/bin/env python2\n#\n#  Resolve a line number in the combined source into an uncombined file/line\n#  using a dist/src/duk_source_meta.json file.\n#\n#  Usage: $ python resolve_combined_lineno.py dist/src/duk_source_meta.json 12345\n#\n\nimport os\nimport sys\nimport json\n\ndef main():\n    with open(sys.argv[1], 'rb') as f:\n        metadata = json.loads(f.read())\n    lineno = int(sys.argv[2])\n\n    for e in reversed(metadata['line_map']):\n        if lineno >= e['combined_line']:\n            orig_lineno = e['original_line'] + (lineno - e['combined_line'])\n            print('%s:%d -> %s:%d' % ('duktape.c', lineno,\n                                      e['original_file'], orig_lineno))\n            break\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/tools/scan_strings.py",
    "content": "#!/usr/bin/env python2\n#\n#  Scan potential external strings from ECMAScript and C files.\n#\n#  Very simplistic example with a lot of limitations:\n#\n#    - Doesn't handle multiple variables in a variable declaration\n#\n#    - Only extracts strings from C files, these may correspond to\n#      Duktape/C bindings (but in many cases don't)\n#\n\nimport os\nimport sys\nimport re\nimport json\n\nstrmap = {}\n\n# ECMAScript function declaration\nre_funcname = re.compile(r'function\\s+(\\w+)', re.UNICODE)\n\n# ECMAScript variable declaration\n# XXX: doesn't handle multiple variables\nre_vardecl = re.compile(r'var\\s+(\\w+)', re.UNICODE)\n\n# ECMAScript variable assignment\nre_varassign = re.compile(r'(\\w+)\\s*=\\s*', re.UNICODE)\n\n# ECMAScript dotted property reference (also matches numbers like\n# '4.0', which are separately rejected below)\nre_propref = re.compile(r'(\\w+(?:\\.\\w+)+)', re.UNICODE)\nre_digits = re.compile(r'^\\d+$', re.UNICODE)\n\n# ECMAScript or C string literal\nre_strlit_dquot = re.compile(r'(\"(?:\\\\\"|\\\\\\\\|[^\"])*\")', re.UNICODE)\nre_strlit_squot = re.compile(r'(\\'(?:\\\\\\'|\\\\\\\\|[^\\'])*\\')', re.UNICODE)\n\ndef strDecode(x):\n    # Need to decode hex, unicode, and other escapes.  Python syntax\n    # is close enough to C and ECMAScript so use eval for now.\n\n    try:\n        return eval('u' + x)  # interpret as unicode string\n    except:\n        sys.stderr.write('Failed to parse: ' + repr(x) + ', ignoring\\n')\n        return None\n\ndef scan(f, fn):\n    global strmap\n\n    # Scan rules depend on file type\n    if fn[-2:] == '.c':\n        use_funcname = False\n        use_vardecl = False\n        use_varassign = False\n        use_propref = False\n        use_strlit_dquot = True\n        use_strlit_squot = False\n    else:\n        use_funcname = True\n        use_vardecl = True\n        use_varassign = True\n        use_propref = True\n        use_strlit_dquot = True\n        use_strlit_squot = True\n\n    for line in f:\n        # Assume input data is UTF-8\n        line = line.decode('utf-8')\n\n        if use_funcname:\n            for m in re_funcname.finditer(line):\n                strmap[m.group(1)] = True\n\n        if use_vardecl:\n            for m in re_vardecl.finditer(line):\n                strmap[m.group(1)] = True\n\n        if use_varassign:\n            for m in re_varassign.finditer(line):\n                strmap[m.group(1)] = True\n\n        if use_propref:\n            for m in re_propref.finditer(line):\n                parts = m.group(1).split('.')\n                if re_digits.match(parts[0]) is not None:\n                    # Probably a number ('4.0' or such)\n                    pass\n                else:\n                    for part in parts:\n                        strmap[part] = True\n\n        if use_strlit_dquot:\n            for m in re_strlit_dquot.finditer(line):\n                s = strDecode(m.group(1))\n                if s is not None:\n                    strmap[s] = True\n\n        if use_strlit_squot:\n            for m in re_strlit_squot.finditer(line):\n                s = strDecode(m.group(1))\n                if s is not None:\n                    strmap[s] = True\n\ndef main():\n    for fn in sys.argv[1:]:\n        f = open(fn, 'rb')\n        scan(f, fn)\n        f.close()\n\n    strs = []\n    strs_base64 = []\n    doc = {\n        # Strings as Unicode strings\n        'scanned_strings': strs,\n\n        # Strings as base64-encoded UTF-8 data, which should be ready\n        # to be used in C code (Duktape internal string representation\n        # is UTF-8)\n        'scanned_strings_base64': strs_base64\n    }\n    k = strmap.keys()\n    k.sort()\n    for s in k:\n        strs.append(s)\n        t = s.encode('utf-8').encode('base64')\n        if len(t) > 0 and t[-1] == '\\n':\n            t = t[0:-1]\n        strs_base64.append(t)\n\n    print(json.dumps(doc, indent=4, ensure_ascii=True, sort_keys=True))\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/tools/scan_used_stridx_bidx.py",
    "content": "#!/usr/bin/env python2\n#\n#  Scan Duktape code base for references to built-in strings and built-in\n#  objects, i.e. for:\n#\n#  - Strings which will need DUK_STRIDX_xxx constants and a place in the\n#    thr->strs[] array.\n#\n#  - Objects which will need DUK_BIDX_xxx constants and a place in the\n#    thr->builtins[] array.\n#\n\nimport os\nimport sys\nimport re\nimport json\n\nre_str_stridx = re.compile(r'DUK_STRIDX_(\\w+)', re.MULTILINE)\nre_str_heap = re.compile(r'DUK_HEAP_STRING_(\\w+)', re.MULTILINE)\nre_str_hthread = re.compile(r'DUK_HTHREAD_STRING_(\\w+)', re.MULTILINE)\nre_obj_bidx = re.compile(r'DUK_BIDX_(\\w+)', re.MULTILINE)\nre_duk_use = re.compile(r'DUK_USE_(\\w+)', re.MULTILINE)\n\ndef main():\n    str_defs = {}\n    obj_defs = {}\n    opt_defs = {}\n\n    for fn in sys.argv[1:]:\n        with open(fn, 'rb') as f:\n            d = f.read()\n            for m in re.finditer(re_str_stridx, d):\n                str_defs[m.group(1)] = True\n            for m in re.finditer(re_str_heap, d):\n                str_defs[m.group(1)] = True\n            for m in re.finditer(re_str_hthread, d):\n                str_defs[m.group(1)] = True\n            for m in re.finditer(re_obj_bidx, d):\n                obj_defs[m.group(1)] = True\n            for m in re.finditer(re_duk_use, d):\n                opt_defs[m.group(1)] = True\n\n    str_used = ['DUK_STRIDX_' + x for x in sorted(str_defs.keys())]\n    obj_used = ['DUK_BIDX_' + x for x in sorted(obj_defs.keys())]\n    opt_used = ['DUK_USE_' + x for x in sorted(opt_defs.keys())]\n\n    doc = {\n        'used_stridx_defines': str_used,\n        'used_bidx_defines': obj_used,\n        'used_duk_use_options': opt_used,\n        'count_used_stridx_defines': len(str_used),\n        'count_used_bidx_defines': len(obj_used),\n        'count_duk_use_options': len(opt_used),\n    }\n    print(json.dumps(doc, indent=4))\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "react_juce/duktape/tools/yaml2json.py",
    "content": "import os, sys, json, yaml\n\nif __name__ == '__main__':\n    print(json.dumps(yaml.load(sys.stdin)))\n"
  },
  {
    "path": "react_juce/react_juce.cpp",
    "content": "/*\n  ==============================================================================\n\n    react_juce.cpp\n    Created: 26 Nov 2018 3:19:03pm\n\n  ==============================================================================\n*/\n\n#ifdef REACTJUCE_H_INCLUDED\n /* When you add this cpp file to your project, you mustn't include it in a file where you've\n    already included any other headers - just put it inside a file on its own, possibly with your config\n    flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix\n    header files that the compiler may be using.\n */\n #error \"Incorrect use of the React-JUCE cpp file\"\n#endif\n\n#include \"react_juce.h\"\n\n#include \"core/AppHarness.cpp\"\n#include \"core/EcmascriptEngine.cpp\"\n\n#if JUCE_MODULE_AVAILABLE_juce_audio_processors\n    #include \"core/GenericEditor.cpp\"\n#endif\n\n#include \"core/CanvasView.cpp\"\n#include \"core/ReactApplicationRoot.cpp\"\n#include \"core/ShadowView.cpp\"\n#include \"core/TextInputView.cpp\"\n#include \"core/TextShadowView.cpp\"\n#include \"core/View.cpp\"\n#include \"core/ViewManager.cpp\"\n#include \"core/ScrollView.cpp\"\n#include \"core/ImageView.cpp\"\n#include \"core/Utils.cpp\"\n"
  },
  {
    "path": "react_juce/react_juce.h",
    "content": "/*******************************************************************************\n * This file declares a JUCE module for the shared library code implemented in\n * this directory. The block below is read by the Projucer to automatically\n * generate project code that uses the module. For details, see the\n * JUCE Module Format.txt file in the JUCE directory.\n\n   BEGIN_JUCE_MODULE_DECLARATION\n    ID:                 react_juce\n    vendor:             Nick Thompson\n    version:            0.1.0\n    name:               React-JUCE\n    description:        Write cross-platform native apps with React.js and JUCE\n    minimumCppStandard: 17\n    dependencies:       juce_gui_basics\n    searchpaths:        ./ ./duktape/ ./duktape/src-noline/ ./yoga\n   END_JUCE_MODULE_DECLARATION\n*******************************************************************************/\n\n#pragma once\n\n#define REACTJUCE_H_INCLUDED\n\n#include <juce_gui_basics/juce_gui_basics.h>\n\n#if JUCE_MODULE_AVAILABLE_juce_audio_processors\n    #include <juce_audio_processors/juce_audio_processors.h>\n#endif\n\n//==============================================================================\n#if JUCE_EXCEPTIONS_DISABLED\n    #error \"React-JUCE module requires exceptions to be enabled!\"\n#endif\n\n#if ! JUCE_CXX17_IS_AVAILABLE\n    #error \"React-JUCE module requires a C++17 compatible toolchain!\"\n#endif\n\n//==============================================================================\n#include \"core/AppHarness.h\"\n#include \"core/EcmascriptEngine.h\"\n#include \"core/CanvasView.h\"\n\n#if JUCE_MODULE_AVAILABLE_juce_audio_processors\n    #include \"core/GenericEditor.h\"\n#endif\n\n#include \"core/ImageView.h\"\n#include \"core/FileWatcher.h\"\n#include \"core/RawTextView.h\"\n#include \"core/ReactApplicationRoot.h\"\n#include \"core/ScrollView.h\"\n#include \"core/ScrollViewContentShadowView.h\"\n#include \"core/ShadowView.h\"\n#include \"core/TextShadowView.h\"\n#include \"core/TextView.h\"\n#include \"core/TextInputView.h\"\n#include \"core/Utils.h\"\n#include \"core/View.h\"\n#include \"core/ViewManager.h\"\n"
  }
]